Update darwin-x86 Go 1.17 prebuilts from ab/7691198 am: cc753b703b

Original change: https://android-review.googlesource.com/c/platform/prebuilts/go/darwin-x86/+/1815396

Change-Id: Ifd18c52d42a949496ae0cbb1fc582a81b5b2d5d0
diff --git a/AUTHORS b/AUTHORS
index 4828ba3..95d3158 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -41,7 +41,7 @@
 Afanasev Stanislav <phpprogger@gmail.com>
 Agis Anastasopoulos <agis.anast@gmail.com>
 Agniva De Sarker <agnivade@yahoo.co.in>
-Ahmed Wahed <oneofone@gmail.com>
+Ahmed W. Mones <oneofone@gmail.com>
 Ahmet Soormally <ahmet@mangomm.co.uk>
 Ahmy Yulrizka <yulrizka@gmail.com>
 Aiden Scandella <ai@uber.com>
@@ -145,7 +145,7 @@
 Andy Finkenstadt <afinkenstadt@zynga.com>
 Andy Lindeman <andy@lindeman.io>
 Andy Maloney <asmaloney@gmail.com>
-Andy Pan <panjf2000@gmail.com>
+Andy Pan <panjf2000@gmail.com> <panjf2000@golangcn.org> <i@andypan.me>
 Andy Walker <walkeraj@gmail.com>
 Anfernee Yongkun Gui <anfernee.gui@gmail.com>
 Angelo Bulfone <mbulfone@gmail.com>
@@ -195,7 +195,7 @@
 Aymerick Jéhanne <aymerick@jehanne.org>
 Azat Kaumov <kaumov.a.r@gmail.com>
 Baiju Muthukadan <baiju.m.mail@gmail.com>
-Baokun Lee <nototon@gmail.com>
+Baokun Lee <nototon@gmail.com> <bk@golangcn.org>
 Bartosz Grzybowski <melkorm@gmail.com>
 Bastian Ike <bastian.ike@gmail.com>
 Ben Burkert <ben@benburkert.com>
@@ -1425,6 +1425,7 @@
 Wei Fu <fhfuwei@163.com>
 Wei Guangjing <vcc.163@gmail.com>
 Weichao Tang <tevic.tt@gmail.com>
+Weixie Cui <cuiweixie@gmail.com> <523516579@qq.com>
 Wembley G. Leach, Jr <wembley.gl@gmail.com>
 Will Faught <will.faught@gmail.com>
 Will Storey <will@summercat.com>
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index ccbe462..1984d44 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -33,6 +33,7 @@
 Aaron Jensen <jensen.aaro@gmail.com>
 Aaron Kemp <kemp.aaron@gmail.com>
 Aaron Patterson <tenderlove@ruby-lang.org>
+Aaron Sheah <aaronsheah@gmail.com>
 Aaron Stein <aaronstein12@gmail.com>
 Aaron Torres <tcboox@gmail.com>
 Aaron Zinman <aaron@azinman.com>
@@ -47,6 +48,7 @@
 Adam Kisala <adam.kisala@gmail.com>
 Adam Langley <agl@golang.org>
 Adam Medzinski <adam.medzinski@gmail.com>
+Adam Mitha <adam.mitha@gmail.com>
 Adam Shannon <adamkshannon@gmail.com>
 Adam Shelton <aashelt90@gmail.com>
 Adam Sindelar <adamsh@google.com>
@@ -54,6 +56,8 @@
 Adam Williams <pwnfactory@gmail.com>
 Adam Woodbeck <adam@woodbeck.net>
 Adarsh Ravichandran <adarshravichandran91@gmail.com>
+Adel Rodríguez <adel.rodriguez@leftfieldlabs.com>
+Adin Scannell <ascannell@google.com>
 Aditya Harindar <aditya.harindar@gmail.com>
 Aditya Mukerjee <dev@chimeracoder.net>
 Adrian Hesketh <adrianhesketh@hushmail.com>
@@ -67,7 +71,8 @@
 Afanasev Stanislav <phpprogger@gmail.com>
 Agis Anastasopoulos <agis.anast@gmail.com>
 Agniva De Sarker <agnivade@yahoo.co.in>
-Ahmed Wahed <oneofone@gmail.com>
+Ahmed W. Mones <oneofone@gmail.com>
+Ahmet Aktürk <aakturk000@gmail.com>
 Ahmet Alp Balkan <ahmetb@google.com>
 Ahmet Soormally <ahmet@mangomm.co.uk>
 Ahmy Yulrizka <yulrizka@gmail.com>
@@ -92,11 +97,13 @@
 Alberto Donizetti <alb.donizetti@gmail.com>
 Alberto García Hierro <alberto@garciahierro.com> <alberto.garcia.hierro@gmail.com>
 Alec Benzer <alec.benzer@gmail.com>
+Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
 Aleksa Sarai <cyphar@cyphar.com>
 Aleksandar Dezelin <dezelin@gmail.com>
 Aleksandr Lukinykh <a.lukinykh@xsolla.com>
 Aleksandr Razumov <ar@cydev.ru>
 Alekseev Artem <a.artem060@gmail.com>
+Aleksei Tirman <aleksei.tirman@jetbrains.com>
 Alessandro Arzilli <alessandro.arzilli@gmail.com>
 Alessandro Baffa <alessandro.baffa@gmail.com>
 Alex A Skinner <alex@lx.lc>
@@ -165,6 +172,7 @@
 Aliaksandr Valialkin <valyala@gmail.com>
 Alice Merrick <amerrick@google.com>
 Alif Rachmawadi <subosito@gmail.com>
+Allan Guwatudde <guwats10@gmail.com>
 Allan Simon <allan.simon@supinfo.com>
 Allen Li <ayatane@google.com>
 Alok Menghrajani <alok.menghrajani@gmail.com>
@@ -172,6 +180,7 @@
 Aman Gupta <aman@tmm1.net>
 Amarjeet Anand <amarjeetanandsingh@gmail.com>
 Amir Mohammad Saied <amir@gluegadget.com>
+Amit Kumar <mittalmailbox@gmail.com>
 Amr Mohammed <merodiro@gmail.com>
 Amrut Joshi <amrut.joshi@gmail.com>
 An Long <aisk1988@gmail.com>
@@ -185,6 +194,7 @@
 André Martins <aanm90@gmail.com>
 Andre Nathan <andrenth@gmail.com>
 Andrea Nodari <andrea.nodari91@gmail.com>
+Andrea Simonini <andrea.simonini@gmail.com>
 Andrea Spadaccini <spadaccio@google.com>
 Andreas Auernhammer <aead@mail.de>
 Andreas Jellinghaus <andreas@ionisiert.de> <anj@google.com>
@@ -240,10 +250,11 @@
 Andy Finkenstadt <afinkenstadt@zynga.com>
 Andy Lindeman <andy@lindeman.io>
 Andy Maloney <asmaloney@gmail.com>
-Andy Pan <panjf2000@gmail.com>
+Andy Pan <panjf2000@gmail.com> <panjf2000@golangcn.org> <i@andypan.me>
 Andy Walker <walkeraj@gmail.com>
 Andy Wang <cbeuw.andy@gmail.com>
 Andy Williams <andy@andy.xyz>
+Andy Zhao <andyzhao@google.com>
 Andzej Maciusovic <andzej.maciusovic@gmail.com>
 Anfernee Yongkun Gui <anfernee.gui@gmail.com>
 Angelo Bulfone <mbulfone@gmail.com>
@@ -269,6 +280,7 @@
 Antonin Amand <antonin.amand@gmail.com>
 Antonio Antelo <aantelov87@gmail.com>
 Antonio Bibiano <antbbn@gmail.com>
+Antonio Garcia <garcia.olais@gmail.com>
 Antonio Huete Jimenez <tuxillo@quantumachine.net>
 Antonio Murdaca <runcom@redhat.com>
 Antonio Troina <thoeni@gmail.com>
@@ -292,8 +304,10 @@
 Artem Kolin <artemkaxboy@gmail.com>
 Arthur Fabre <arthur@arthurfabre.com>
 Arthur Khashaev <arthur@khashaev.ru>
+Artur M. Wolff <artur.m.wolff@gmail.com>
 Artyom Pervukhin <artyom.pervukhin@gmail.com>
 Arvindh Rajesh Tamilmani <art@a-30.net>
+Ashish Bhate <ab.listsubs@gmail.com>
 Ashish Gandhi <ag@ashishgandhi.org>
 Asim Shankar <asimshankar@gmail.com>
 Assel Meher <asselmeher@gmail.com>
@@ -321,10 +335,11 @@
 Baiju Muthukadan <baiju.m.mail@gmail.com>
 Balaram Makam <bmakam.qdt@qualcommdatacenter.com>
 Balazs Lecz <leczb@google.com>
-Baokun Lee <nototon@gmail.com>
+Baokun Lee <nototon@gmail.com> <bk@golangcn.org>
 Barnaby Keene <accounts@southcla.ws>
 Bartosz Grzybowski <melkorm@gmail.com>
 Bartosz Oler <brtsz@google.com>
+Bassam Ojeil <bojeil@google.com>
 Bastian Ike <bastian.ike@gmail.com>
 Ben Burkert <ben@benburkert.com>
 Ben Cartwright-Cox <Ben@Benjojo.co.uk>
@@ -332,6 +347,7 @@
 Ben Fried <ben.fried@gmail.com>
 Ben Haines <bhainesva@gmail.com>
 Ben Hoyt <benhoyt@gmail.com>
+Ben Hutchings <ben.hutchings@essensium.com>
 Ben Kraft <benkraft@khanacademy.org>
 Ben Laurie <ben@links.org> <benl@google.com>
 Ben Lubar <ben.lubar@gmail.com>
@@ -430,6 +446,7 @@
 Carl Jackson <carl@stripe.com>
 Carl Johnson <me@carlmjohnson.net>
 Carl Mastrangelo <notcarl@google.com>
+Carl Menezes <carleeto@gmail.com>
 Carl Shapiro <cshapiro@google.com> <cshapiro@golang.org>
 Carlisia Campos <carlisia@grokkingtech.io>
 Carlo Alberto Ferraris <cafxx@strayorange.com>
@@ -443,6 +460,7 @@
 Carlos Souza <carloshrsouza@gmail.com>
 Carolyn Van Slyck <me@carolynvanslyck.com>
 Carrie Bynon <cbynon@gmail.com>
+Carson Hoffman <c@rsonhoffman.com>
 Cary Hull <chull@google.com>
 Case Nelson <case.nelson@gmail.com>
 Casey Callendrello <squeed@gmail.com>
@@ -462,11 +480,12 @@
 Charles L. Dorian <cldorian@gmail.com>
 Charles Lee <zombie.fml@gmail.com>
 Charles Weill <weill@google.com>
+Charlie Moog <moogcharlie@gmail.com>
 Charlotte Brandhorst-Satzkorn <catzkorn@gmail.com>
 Chauncy Cullitan <chauncyc@google.com>
 Chen Zhidong <njutczd@gmail.com>
 Chen Zhihan <energiehund@gmail.com>
-Cherry Zhang <cherryyz@google.com>
+Cherry Mui <cherryyz@google.com>
 Chew Choon Keat <choonkeat@gmail.com>
 Chiawen Chen <golopot@gmail.com>
 Chirag Sukhala <cchirag77@gmail.com>
@@ -516,6 +535,7 @@
 Christopher Nielsen <m4dh4tt3r@gmail.com>
 Christopher Redden <christopher.redden@gmail.com>
 Christopher Swenson <cswenson@google.com>
+Christopher Thomas <53317512+chrisssthomas@users.noreply.github.com>
 Christopher Wedgwood <cw@f00f.org>
 Christos Zoulas <christos@zoulas.com> <zoulasc@gmail.com>
 Christy Perez <christy@linux.vnet.ibm.com>
@@ -541,6 +561,8 @@
 Costin Chirvasuta <ctin@google.com>
 Craig Citro <craigcitro@google.com>
 Cristian Staretu <unclejacksons@gmail.com>
+Cristo García <cgg.code@gmail.com>
+cui fliter <imcusg@gmail.com>
 Cuihtlauac ALVARADO <cuihtlauac.alvarado@orange.com>
 Cuong Manh Le <cuong@orijtech.com>
 Curtis La Graff <curtis@lagraff.me>
@@ -560,6 +582,7 @@
 Dan Harrington <harringtond@google.com>
 Dan Jacques <dnj@google.com>
 Dan Johnson <computerdruid@google.com>
+Dan McArdle <dmcardle@google.com>
 Dan Peterson <dpiddy@gmail.com>
 Dan Pupius <dan@medium.com>
 Dan Scales <danscales@google.com>
@@ -611,6 +634,7 @@
 David Anderson <danderson@google.com>
 David Barnett <dbarnett@google.com>
 David Benjamin <davidben@google.com>
+David Black <dblack@atlassian.com>
 David Bond <davidsbond93@gmail.com>
 David Brophy <dave@brophy.uk>
 David Bürgin <676c7473@gmail.com>
@@ -654,6 +678,7 @@
 Dean Eigenmann <7621705+decanus@users.noreply.github.com>
 Dean Prichard <dean.prichard@gmail.com>
 Deepak Jois <deepak.jois@gmail.com>
+Deepak S <deepakspavoodath@gmail.com>
 Denis Bernard <db047h@gmail.com>
 Denis Brandolini <denis.brandolini@gmail.com>
 Denis Isaev <idenx@yandex.com>
@@ -676,8 +701,10 @@
 Dhruvdutt Jadhav <dhruvdutt.jadhav@gmail.com>
 Di Xiao <dixiao@google.com>
 Didier Spezia <didier.06@gmail.com>
+Diego Medina <fmpwizard@gmail.com>
 Diego Siqueira <diego9889@gmail.com>
 Dieter Plaetinck <dieter@raintank.io>
+Dilyn Corner <dilyn.corner@gmail.com>
 Dimitri Sokolyuk <sokolyuk@gmail.com>
 Dimitri Tcaciuc <dtcaciuc@gmail.com>
 Dina Garmash <dgrmsh@gmail.com>
@@ -714,6 +741,7 @@
 Douglas Danger Manley <doug.manley@gmail.com>
 Drew Flower <drewvanstone@gmail.com>
 Drew Hintz <adhintz@google.com>
+Drew Richardson <drewrichardson@gmail.com>
 Duco van Amstel <duco.vanamstel@gmail.com>
 Duncan Holm <mail@frou.org>
 Dustin Carlino <dcarlino@google.com>
@@ -735,6 +763,7 @@
 Ehren Kret <ehren.kret@gmail.com>
 Eitan Adler <lists@eitanadler.com>
 Eivind Uggedal <eivind@uggedal.com>
+El Mostafa Idrassi <el.mostafa.idrassi@gmail.com>
 Elbert Fliek <efliek@gmail.com>
 Eldar Rakhimberdin <ibeono@gmail.com>
 Elena Grahovac <elena@grahovac.me>
@@ -742,6 +771,7 @@
 Elias Naur <mail@eliasnaur.com> <elias.naur@gmail.com>
 Elliot Morrison-Reed <elliotmr@gmail.com>
 Ellison Leão <ellisonleao@gmail.com>
+Elvina Yakubova <elvinayakubova@gmail.com>
 Emerson Lin <linyintor@gmail.com>
 Emil Bektimirov <lefelys@gmail.com>
 Emil Hessman <emil@hessman.se>
@@ -767,6 +797,7 @@
 Eric Roshan-Eisner <eric.d.eisner@gmail.com>
 Eric Rutherford <erutherford@gmail.com>
 Eric Rykwalder <e.rykwalder@gmail.com>
+Eric Wang <wangchaogo1990@gmail.com>
 Erick Tryzelaar <etryzelaar@google.com>
 Erik Aigner <aigner.erik@gmail.com>
 Erik Dubbelboer <erik@dubbelboer.com>
@@ -778,6 +809,7 @@
 Erwin Oegema <blablaechthema@hotmail.com>
 Esko Luontola <esko.luontola@gmail.com>
 Ethan Burns <eaburns@google.com>
+Ethan Hur <ethan0311@gmail.com>
 Ethan Miller <eamiller@us.ibm.com>
 Euan Kemp <euank@euank.com>
 Eugene Formanenko <mo4islona@gmail.com>
@@ -818,6 +850,7 @@
 Felix Geisendörfer <haimuiba@gmail.com>
 Felix Kollmann <fk@konsorten.de>
 Ferenc Szabo <frncmx@gmail.com>
+Fernandez Ludovic <lfernandez.dev@gmail.com>
 Filip Gruszczyński <gruszczy@gmail.com>
 Filip Haglund <drathier@users.noreply.github.com>
 Filip Stanis <fstanis@google.com>
@@ -858,6 +891,7 @@
 Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com>
 Gabriel Rosenhouse <rosenhouse@gmail.com>
 Gabriel Russell <gabriel.russell@gmail.com>
+Gabriel Vasile <gabriel.vasile0793@gmail.com>
 Gareth Paul Jones <gpj@foursquare.com>
 Garret Kelly <gdk@google.com>
 Garrick Evans <garrick@google.com>
@@ -891,6 +925,8 @@
 Gideon Jan-Wessel Redelinghuys <gjredelinghuys@gmail.com>
 Giles Lean <giles.lean@pobox.com>
 Giovanni Bajo <rasky@develer.com>
+GitHub User @180909 (70465953) <734461790@qq.com>
+GitHub User @6543 (24977596) <6543@obermui.de>
 GitHub User @aca (50316549) <acadx0@gmail.com>
 GitHub User @ajnirp (1688456) <ajnirp@users.noreply.github.com>
 GitHub User @ajz01 (4744634) <ajzdenek@gmail.com>
@@ -904,10 +940,12 @@
 GitHub User @cch123 (384546) <buaa.cch@gmail.com>
 GitHub User @chainhelen (7046329) <chainhelen@gmail.com>
 GitHub User @chanxuehong (3416908) <chanxuehong@gmail.com>
+GitHub User @Cluas (10056928) <Cluas@live.cn>
 GitHub User @cncal (23520240) <flycalvin@qq.com>
 GitHub User @DQNEO (188741) <dqneoo@gmail.com>
 GitHub User @Dreamacro (8615343) <chuainian@gmail.com>
 GitHub User @dupoxy (1143957) <dupoxy@users.noreply.github.com>
+GitHub User @EndlessCheng (7086966) <loli.con@qq.com>
 GitHub User @erifan (31343225) <eric.fang@arm.com>
 GitHub User @esell (9735165) <eujon.sellers@gmail.com>
 GitHub User @fatedier (7346661) <fatedier@gmail.com>
@@ -916,12 +954,15 @@
 GitHub User @GrigoriyMikhalkin (3637857) <grigoriymikhalkin@gmail.com>
 GitHub User @hengwu0 (41297446) <41297446+hengwu0@users.noreply.github.com>
 GitHub User @hitzhangjie (3725760) <hit.zhangjie@gmail.com>
+GitHub User @hqpko (13887251) <whaibin01@hotmail.com>
 GitHub User @itchyny (375258) <itchyny@hatena.ne.jp>
 GitHub User @jinmiaoluo (39730824) <jinmiaoluo@icloud.com>
 GitHub User @jopbrown (6345470) <msshane2008@gmail.com>
 GitHub User @kazyshr (30496953) <kazyshr0301@gmail.com>
 GitHub User @kc1212 (1093806) <kc1212@users.noreply.github.com>
+GitHub User @komisan19 (18901496) <komiyama6219@gmail.com>
 GitHub User @Kropekk (13366453) <kamilkropiewnicki@gmail.com>
+GitHub User @lhl2617 (33488131) <l.h.lee2617@gmail.com>
 GitHub User @linguohua (3434367) <lghchinaidea@gmail.com>
 GitHub User @LotusFenn (13775899) <fenn.lotus@gmail.com>
 GitHub User @ly303550688 (11519839) <yang.liu636@gmail.com>
@@ -936,10 +977,14 @@
 GitHub User @pityonline (438222) <pityonline@gmail.com>
 GitHub User @po3rin (29445112) <abctail30@gmail.com>
 GitHub User @pokutuna (57545) <popopopopokutuna@gmail.com>
+GitHub User @povsister (11040951) <pov@mahou-shoujo.moe>
 GitHub User @pytimer (17105586) <lixin20101023@gmail.com>
+GitHub User @qcrao (7698088) <qcrao91@gmail.com>
 GitHub User @ramenjuniti (32011829) <ramenjuniti@gmail.com>
 GitHub User @saitarunreddy (21041941) <saitarunreddypalla@gmail.com>
+GitHub User @SataQiu (9354727) <shidaqiu2018@gmail.com>
 GitHub User @shogo-ma (9860598) <Choroma194@gmail.com>
+GitHub User @sivchari (55221074) <shibuuuu5@gmail.com>
 GitHub User @skanehira (7888591) <sho19921005@gmail.com>
 GitHub User @soolaugust (10558124) <soolaugust@gmail.com>
 GitHub User @surechen (7249331) <surechen17@gmail.com>
@@ -947,9 +992,12 @@
 GitHub User @tell-k (26263) <ffk2005@gmail.com>
 GitHub User @tennashi (10219626) <tennashio@gmail.com>
 GitHub User @uhei (2116845) <uhei@users.noreply.github.com>
+GitHub User @uji (49834542) <ujiprog@gmail.com>
+GitHub User @unbyte (5772358) <i@shangyes.net>
 GitHub User @uropek (39370426) <uropek@gmail.com>
 GitHub User @utkarsh-extc (53217283) <utkarsh.extc@gmail.com>
 GitHub User @witchard (4994659) <witchard@hotmail.co.uk>
+GitHub User @wolf1996 (5901874) <ksgiv37@gmail.com>
 GitHub User @yah01 (12216890) <kagaminehuan@gmail.com>
 GitHub User @yuanhh (1298735) <yuan415030@gmail.com>
 GitHub User @zikaeroh (48577114) <zikaeroh@gmail.com>
@@ -962,6 +1010,7 @@
 Glenn Lewis <gmlewis@google.com>
 Gordon Klaus <gordon.klaus@gmail.com>
 Gordon Tyler <gordon@doxxx.net>
+Grace Han <hgrace503@gmail.com>
 Graham King <graham4king@gmail.com>
 Graham Miller <graham.miller@gmail.com>
 Grant Griffiths <ggp493@gmail.com>
@@ -977,10 +1026,12 @@
 Guilherme Garnier <guilherme.garnier@gmail.com>
 Guilherme Goncalves <guilhermeaugustosg@gmail.com>
 Guilherme Rezende <guilhermebr@gmail.com>
+Guilherme Souza <32180229+gqgs@users.noreply.github.com>
 Guillaume J. Charmes <guillaume@charmes.net>
 Guillaume Sottas <guillaumesottas@gmail.com>
 Günther Noack <gnoack@google.com>
 Guobiao Mei <meiguobiao@gmail.com>
+Guodong Li <guodongli@google.com>
 Guoliang Wang <iamwgliang@gmail.com>
 Gustav Paul <gustav.paul@gmail.com>
 Gustav Westling <gustav@westling.xyz>
@@ -995,6 +1046,7 @@
 Han-Wen Nienhuys <hanwen@google.com>
 Hang Qian <hangqian90@gmail.com>
 Hanjun Kim <hallazzang@gmail.com>
+Hanlin He <hanling.he@gmail.com>
 Hanlin Shi <shihanlin9@gmail.com>
 Haoran Luo <haoran.luo@chaitin.com>
 Haosdent Huang <haosdent@gmail.com>
@@ -1026,18 +1078,19 @@
 Heschi Kreinick <heschi@google.com>
 Hidetatsu Yaginuma <ygnmhdtt@gmail.com>
 Hilko Bengen <bengen@hilluzination.de>
+Himanshu Kishna Srivastava <28himanshu@gmail.com>
 Hiroaki Nakamura <hnakamur@gmail.com>
 Hiromichi Ema <ema.hiro@gmail.com>
 Hironao OTSUBO <motemen@gmail.com>
 Hiroshi Ioka <hirochachacha@gmail.com>
 Hitoshi Mitake <mitake.hitoshi@gmail.com>
 Holden Huang <ttyh061@gmail.com>
-Songlin Jiang <hollowman@hollowman.ml>
 Hong Ruiqi <hongruiqi@gmail.com>
 Hongfei Tan <feilengcui008@gmail.com>
 Horacio Duran <horacio.duran@gmail.com>
 Horst Rutter <hhrutter@gmail.com>
 Hossein Sheikh Attar <hattar@google.com>
+Hossein Zolfi <hossein.zolfi@gmail.com>
 Howard Zhang <howard.zhang@arm.com>
 Hsin Tsao <tsao@google.com>
 Hsin-Ho Yeh <yhh92u@gmail.com>
@@ -1054,11 +1107,14 @@
 Ian Kent <iankent85@gmail.com>
 Ian Lance Taylor <iant@golang.org>
 Ian Leue <ian@appboy.com>
+Ian Mckay <iann0036@gmail.com>
 Ian Tay <iantay@google.com>
+Ian Woolf <btw515wolf2@gmail.com>
 Ian Zapolsky <ianzapolsky@gmail.com>
 Ibrahim AshShohail <ibra.sho@gmail.com>
 Icarus Sparry <golang@icarus.freeuk.com>
 Iccha Sethi <icchasethi@gmail.com>
+Ichinose Shogo <shogo82148@gmail.com>
 Idora Shinatose <idora.shinatose@gmail.com>
 Ignacio Hagopian <jsign.uy@gmail.com>
 Igor Bernstein <igorbernstein@google.com>
@@ -1068,6 +1124,7 @@
 Igor Zhilianin <igor.zhilianin@gmail.com>
 Ikko Ashimine <eltociear@gmail.com>
 Illya Yalovyy <yalovoy@gmail.com>
+Ilya Chukov <56119080+Elias506@users.noreply.github.com>
 Ilya Sinelnikov <sidhmangh@gmail.com>
 Ilya Tocar <ilya.tocar@intel.com>
 INADA Naoki <songofacandy@gmail.com>
@@ -1122,6 +1179,7 @@
 James Craig Burley <james-github@burleyarch.com>
 James David Chalfant <james.chalfant@gmail.com>
 James Eady <jmeady@google.com>
+James Fennell <jpfennell@google.com>
 James Fysh <james.fysh@gmail.com>
 James Gray <james@james4k.com>
 James Hartig <fastest963@gmail.com>
@@ -1178,6 +1236,7 @@
 Javier Kohen <jkohen@google.com>
 Javier Revillas <jrevillas@massivedynamic.io>
 Javier Segura <javism@gmail.com>
+Jay Chen <chenjie@chenjie.info>
 Jay Conrod <jayconrod@google.com>
 Jay Lee <BusyJayLee@gmail.com>
 Jay Taylor <outtatime@gmail.com>
@@ -1200,6 +1259,7 @@
 Jeff R. Allen <jra@nella.org> <jeff.allen@gmail.com>
 Jeff Sickel <jas@corpus-callosum.com>
 Jeff Wendling <jeff@spacemonkey.com>
+Jeff Widman <jeff@jeffwidman.com>
 Jeffrey H <jeffreyh192@gmail.com>
 Jelte Fennema <github-tech@jeltef.nl>
 Jens Frederich <jfrederich@gmail.com>
@@ -1210,6 +1270,7 @@
 Jeremy Jackins <jeremyjackins@gmail.com>
 Jeremy Jay <jeremy@pbnjay.com>
 Jeremy Schlatter <jeremy.schlatter@gmail.com>
+Jero Bado <tokidokitalkyou@gmail.com>
 Jeroen Bobbeldijk <jerbob92@gmail.com>
 Jeroen Simonetti <jeroen@simonetti.nl>
 Jérôme Doucet <jerdct@gmail.com>
@@ -1251,6 +1312,8 @@
 Joe Shaw <joe@joeshaw.org>
 Joe Sylve <joe.sylve@gmail.com>
 Joe Tsai <joetsai@digital-static.net>
+Joel Courtney <euphemize@gmail.com>
+Joel Ferrier <joelferrier@google.com>
 Joel Sing <joel@sing.id.au> <jsing@google.com>
 Joël Stemmer <jstemmer@google.com>
 Joel Stemmer <stemmertech@gmail.com>
@@ -1260,7 +1323,9 @@
 Johan Jansson <johan.jansson@iki.fi>
 Johan Knutzen <johan@senri.se>
 Johan Sageryd <j@1616.se>
+Johannes Huning <johannes.huning@gmail.com>
 John Asmuth <jasmuth@gmail.com>
+John Bampton <jbampton@gmail.com>
 John Beisley <huin@google.com>
 John C Barstow <jbowtie@amathaine.com>
 John DeNero <denero@google.com>
@@ -1269,6 +1334,7 @@
 John Gilik <john@jgilik.com>
 John Graham-Cumming <jgc@jgc.org> <jgrahamc@gmail.com>
 John Howard Palevich <jack.palevich@gmail.com>
+John Jago <johnjago@protonmail.com>
 John Jeffery <jjeffery@sp.com.au>
 John Jenkins <twodopeshaggy@gmail.com>
 John Leidegren <john.leidegren@gmail.com>
@@ -1320,6 +1386,7 @@
 Jose Luis Vázquez González <josvazg@gmail.com>
 Joseph Bonneau <jcb@google.com>
 Joseph Holsten <joseph@josephholsten.com>
+Joseph Morag <sefim96@gmail.com>
 Josh Baum <joshbaum@google.com>
 Josh Bleecher Snyder <josharian@gmail.com>
 Josh Chorlton <jchorlton@gmail.com>
@@ -1327,12 +1394,14 @@
 Josh Goebel <dreamer3@gmail.com>
 Josh Hoak <jhoak@google.com>
 Josh Holland <jrh@joshh.co.uk>
+Josh Rickmar <jrick@companyzero.com>
 Josh Roppo <joshroppo@gmail.com>
 Josh Varga <josh.varga@gmail.com>
 Joshua Bezaleel Abednego <joshua.bezaleel@gmail.com>
 Joshua Boelter <joshua.boelter@intel.com>
 Joshua Chase <jcjoshuachase@gmail.com>
 Joshua Crowgey <jcrowgey@uw.edu>
+Joshua Harshman <joshgreyhat@gmail.com>
 Joshua M. Clulow <josh.clulow@joyent.com>
 Joshua Rubin <joshua@rubixconsulting.com>
 Josselin Costanzi <josselin@costanzi.fr>
@@ -1353,6 +1422,7 @@
 Julien Kauffmann <julien.kauffmann@freelan.org>
 Julien Salleyron <julien.salleyron@gmail.com>
 Julien Schmidt <google@julienschmidt.com>
+Julien Tant <julien@craftyx.fr>
 Julio Montes <julio.montes@intel.com>
 Jun Zhang <jim.zoumo@gmail.com>
 Junchen Li <junchen.li@arm.com>
@@ -1419,10 +1489,12 @@
 Kerollos Magdy <kerolloz@yahoo.com>
 Ketan Parmar <ketanbparmar@gmail.com>
 Kevan Swanberg <kevswanberg@gmail.com>
+Kevin Albertson <kevin.albertson@mongodb.com>
 Kevin Ballard <kevin@sb.org>
 Kevin Burke <kev@inburke.com>
 Kévin Dunglas <dunglas@gmail.com>
 Kevin Gillette <extemporalgenome@gmail.com>
+Kevin Herro <kevin109104@gmail.com>
 Kevin Kirsche <kev.kirsche@gmail.com>
 Kevin Klues <klueska@gmail.com> <klueska@google.com>
 Kevin Malachowski <chowski@google.com>
@@ -1457,6 +1529,7 @@
 Kris Kwiatkowski <kris@cloudflare.com>
 Kris Nova <kris@nivenly.com>
 Kris Rousey <krousey@google.com>
+Krishna Birla <krishnabirla16@gmail.com>
 Kristopher Watts <traetox@gmail.com>
 Krzysztof Dąbrowski <krzysdabro@live.com>
 Kshitij Saraogi <kshitijsaraogi@gmail.com>
@@ -1480,6 +1553,7 @@
 Lakshay Garg <lakshay.garg.1996@gmail.com>
 Lann Martin <lannm@google.com>
 Lanre Adelowo <yo@lanre.wtf>
+Lapo Luchini <lapo@lapo.it>
 Larry Clapp <larry@theclapp.org>
 Larry Hosken <lahosken@golang.org>
 Lars Jeppesen <jeppesen.lars@gmail.com>
@@ -1496,6 +1570,7 @@
 Leo Antunes <leo@costela.net>
 Leo Rudberg <ljr@google.com>
 Leon Klingele <git@leonklingele.de>
+Leonard Wang <wangdeyu0907@gmail.com>
 Leonardo Comelli <leonardo.comelli@gmail.com>
 Leonel Quinteros <leonel.quinteros@gmail.com>
 Lev Shamardin <shamardin@gmail.com>
@@ -1506,7 +1581,9 @@
 Lingchao Xin <douglarek@gmail.com>
 Lion Yang <lion@aosc.xyz>
 Liz Rice <liz@lizrice.com>
+Lize Cai <lizzzcai1@gmail.com>
 Lloyd Dewolf <foolswisdom@gmail.com>
+Lluís Batlle i Rossell <viric@viric.name>
 Lorenz Bauer <lmb@cloudflare.com>
 Lorenz Brun <lorenz@brun.one>
 Lorenz Nickel <mail@lorenznickel.de>
@@ -1531,6 +1608,7 @@
 Luke Champine <luke.champine@gmail.com>
 Luke Curley <qpingu@gmail.com>
 Luke Granger-Brown <git@lukegb.com>
+Luke Shumaker <lukeshu@datawire.io>
 Luke Young <bored-engineer@users.noreply.github.com>
 Luna Duclos <luna.duclos@palmstonegames.com>
 Luuk van Dijk <lvd@golang.org> <lvd@google.com>
@@ -1550,6 +1628,7 @@
 Manfred Touron <m@42.am>
 Manigandan Dharmalingam <manigandan.jeff@gmail.com>
 Manish Goregaokar <manishsmail@gmail.com>
+Manlio Perillo <manlio.perillo@gmail.com>
 Manoj Dayaram <platform-dev@moovweb.com> <manoj.dayaram@moovweb.com>
 Mansour Rahimi <rahimi.mnr@gmail.com>
 Manu Garg <manugarg@google.com>
@@ -1646,6 +1725,8 @@
 Matt Jones <mrjones@google.com>
 Matt Juran <thepciet@gmail.com>
 Matt Layher <mdlayher@gmail.com>
+Matt Masurka <masurka@google.com>
+Matt Pearring <broskies@google.com>
 Matt Reiferson <mreiferson@gmail.com>
 Matt Robenolt <matt@ydekproductions.com>
 Matt Strong <mstrong1341@gmail.com>
@@ -1659,9 +1740,12 @@
 Matthew Holt <Matthew.Holt+git@gmail.com>
 Matthew Horsnell <matthew.horsnell@gmail.com>
 Matthew Waters <mwwaters@gmail.com>
+Matthias Frei <matthias.frei@inf.ethz.ch>
 Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
 Matthieu Olivier <olivier.matthieu@gmail.com>
 Matthijs Kooijman <matthijs@stdin.nl>
+Mattias Appelgren <mattias@ppelgren.se>
+Mauricio Alvarado <mauricio.alvarado@leftfieldlabs.com>
 Max Drosdo.www <g1ran1q@gmail.com>
 Max Riveiro <kavu13@gmail.com>
 Max Schmitt <max@schmitt.mx>
@@ -1677,9 +1761,11 @@
 Maxwell Krohn <themax@gmail.com>
 Maya Rashish <maya@NetBSD.org>
 Mayank Kumar <krmayankk@gmail.com>
+Mehrad Sadeghi <2012.linkinpark@gmail.com>
 Meir Fischer <meirfischer@gmail.com>
 Meng Zhuo <mengzhuo1203@gmail.com> <mzh@golangcn.org>
 Mhd Sulhan <m.shulhan@gmail.com>
+Mia Zhu <CrystalZhu1025getu@gmail.com>
 Micah Stetson <micah.stetson@gmail.com>
 Michael Anthony Knyszek <mknyszek@google.com>
 Michael Brandenburg <mbrandenburg@bolste.com>
@@ -1730,8 +1816,10 @@
 Michał Łowicki <mlowicki@gmail.com>
 Michal Pristas <michal.pristas@gmail.com>
 Michal Rostecki <mrostecki@suse.de>
+Michal Stokluska <mstoklus@redhat.com>
 Michalis Kargakis <michaliskargakis@gmail.com>
 Michel Lespinasse <walken@google.com>
+Michel Levieux <mlevieux42@gmail.com>
 Michele Di Pede <michele.di.pede@gmail.com>
 Mickael Kerjean <mickael.kerjean@gmail.com>
 Mickey Reiss <mickeyreiss@gmail.com>
@@ -1790,7 +1878,9 @@
 Mukesh Sharma <sharma.mukesh439@gmail.com>
 Mura Li <mura_li@castech.com.tw>
 Mykhailo Lesyk <mikhail@lesyk.org>
+Nahum Shalman <nahamu@gmail.com>
 Naman Aggarwal <aggarwal.nam@gmail.com>
+Naman Gera <namangera15@gmail.com>
 Nan Deng <monnand@gmail.com>
 Nao Yonashiro <owan.orisano@gmail.com>
 Naoki Kanatani <k12naoki@gmail.com>
@@ -1818,6 +1908,7 @@
 Nevins Bartolomeo <nevins.bartolomeo@gmail.com>
 Niall Sheridan <nsheridan@gmail.com>
 Nic Day <nic.day@me.com>
+Nicholas Asimov <nicholas@asimov.me>
 Nicholas Katsaros <nick@nickkatsaros.com>
 Nicholas Maniscalco <nicholas@maniscalco.com>
 Nicholas Ng <nickng@nickng.io>
@@ -1847,6 +1938,7 @@
 Nikhil Benesch <nikhil.benesch@gmail.com>
 Nikita Gillmann <nikita@n0.is> <ng0@n0.is>
 Nikita Kryuchkov <nkryuchkov10@gmail.com>
+Nikita Melekhin <nimelehin@gmail.com>
 Nikita Vanyasin <nikita.vanyasin@gmail.com>
 Niklas Schnelle <niklas.schnelle@gmail.com>
 Niko Dziemba <niko@dziemba.com>
@@ -1858,6 +1950,7 @@
 Nishanth Shanmugham <nishanth.gerrard@gmail.com>
 Noah Campbell <noahcampbell@gmail.com>
 Noah Goldman <noahg34@gmail.com>
+Noah Santschi-Cooney <noah@santschi-cooney.ch>
 Noble Johnson <noblepoly@gmail.com>
 Nodir Turakulov <nodir@google.com>
 Noel Georgi <git@frezbo.com>
@@ -1894,6 +1987,7 @@
 Pablo Santiago Blum de Aguiar <scorphus@gmail.com>
 Padraig Kitterick <padraigkitterick@gmail.com>
 Pallat Anchaleechamaikorn <yod.pallat@gmail.com>
+Pan Chenglong <1004907659@qq.com>
 Panos Georgiadis <pgeorgiadis@suse.de>
 Pantelis Sampaziotis <psampaz@gmail.com>
 Paolo Giarrusso <p.giarrusso@gmail.com>
@@ -1947,6 +2041,7 @@
 Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com>
 Paulo Gomes <paulo.gomes.uk@gmail.com>
 Pavel Paulau <pavel.paulau@gmail.com>
+Pavel Watson <watsonpavel@gmail.com>
 Pavel Zinovkin <pavel.zinovkin@gmail.com>
 Pavlo Sumkin <ymkins@gmail.com>
 Pawel Knap <pawelknap88@gmail.com>
@@ -1954,6 +2049,8 @@
 Paweł Szulik <pawel.szulik@intel.com>
 Pei Xian Chee <luciolas1991@gmail.com>
 Pei-Ming Wu <p408865@gmail.com>
+Pen Tree <appletree2479@outlook.com>
+Peng Gao <peng.gao.dut@gmail.com>
 Percy Wegmann <ox.to.a.cart@gmail.com>
 Perry Abbott <perry.j.abbott@gmail.com>
 Petar Dambovaliev <petar.atanasov.1987@gmail.com>
@@ -1992,6 +2089,7 @@
 Philip Hofer <phofer@umich.edu>
 Philip K. Warren <pkwarren@gmail.com>
 Philip Nelson <me@pnelson.ca>
+Philipp Sauter <sauterp@protonmail.com>
 Philipp Stephani <phst@google.com>
 Phillip Campbell <15082+phillc@users.noreply.github.com>
 Pierre Carru <pierre.carru@eshard.com>
@@ -2007,6 +2105,7 @@
 Polina Osadcha <polliosa@google.com>
 Pontus Leitzler <leitzler@gmail.com>
 Povilas Versockas <p.versockas@gmail.com>
+Prajwal Koirala <16564273+Prajwal-Koirala@users.noreply.github.com>
 Prasanga Siripala <pj@pjebs.com.au>
 Prasanna Swaminathan <prasanna@mediamath.com>
 Prashant Agrawal <prashant.a.vjti@gmail.com>
@@ -2027,11 +2126,13 @@
 Quinn Slack <sqs@sourcegraph.com>
 Quinten Yearsley <qyearsley@chromium.org>
 Quoc-Viet Nguyen <afelion@gmail.com>
+Rabin Gaire <rabingaire20@gmail.com>
 Radek Simko <radek.simko@gmail.com>
 Radek Sohlich <sohlich@gmail.com>
 Radu Berinde <radu@cockroachlabs.com>
 Rafal Jeczalik <rjeczalik@gmail.com>
 Raghavendra Nagaraj <jamdagni86@gmail.com>
+Rahul Bajaj <rahulrb0509@gmail.com>
 Rahul Chaudhry <rahulchaudhry@chromium.org>
 Rahul Wadhwani <rahulwadhwani21@gmail.com>
 Raif S. Naffah <go@naffah-raif.name>
@@ -2041,12 +2142,14 @@
 Ralph Corderoy <ralph@inputplus.co.uk>
 Ramazan AYYILDIZ <rayyildiz@gmail.com>
 Ramesh Dharan <dharan@google.com>
+Randy Reddig <randy@alta.software>
 Raph Levien <raph@google.com>
 Raphael Geronimi <raphael.geronimi@gmail.com>
 Raul Silvera <rsilvera@google.com>
 Ravil Bikbulatov <weeellz12@gmail.com>
 RaviTeja Pothana <ravi.tezu@gmail.com>
 Ray Tung <rtung@thoughtworks.com>
+Ray Wu <ray@liftoff.io>
 Raymond Kazlauskas <raima220@gmail.com>
 Rebecca Stambler <rstambler@golang.org>
 Reilly Watson <reillywatson@gmail.com>
@@ -2066,6 +2169,7 @@
 Richard Gibson <richard.gibson@gmail.com>
 Richard Miller <miller.research@gmail.com>
 Richard Musiol <mail@richard-musiol.de> <neelance@gmail.com>
+Richard Pickering <richard.pickering@hotmail.co.uk>
 Richard Ulmer <codesoap@mailbox.org>
 Richard Wilkes <wilkes@me.com>
 Rick Arnold <rickarnoldjr@gmail.com>
@@ -2124,6 +2228,7 @@
 Rudi Kramer <rudi.kramer@gmail.com>
 Rui Ueyama <ruiu@google.com>
 Ruixin Bao <ruixin.bao@ibm.com>
+Ruslan Andreev <ruslan.andreev@huawei.com>
 Ruslan Nigmatullin <elessar@dropbox.com>
 Russ Cox <rsc@golang.org>
 Russell Haering <russellhaering@gmail.com>
@@ -2141,6 +2246,7 @@
 Ryan Slade <ryanslade@gmail.com>
 Ryan Zhang <ryan.zhang@docker.com>
 Ryoichi KATO <ryo1kato@gmail.com>
+Ryoya Sekino <ryoyasekino1993@gmail.com>
 Ryuji Iwata <qt.luigi@gmail.com>
 Ryuma Yoshida <ryuma.y1117@gmail.com>
 Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com>
@@ -2176,8 +2282,10 @@
 Sascha Brawer <sascha@brawer.ch>
 Sasha Lionheart <lionhearts@google.com>
 Sasha Sobol <sasha@scaledinference.com>
+Satoru Kitaguchi <rule.the.fate.myfirststory@gmail.com>
 Scott Barron <scott.barron@github.com>
 Scott Bell <scott@sctsm.com>
+Scott Cotton <scott@mindowl.com>
 Scott Crunkleton <crunk1@gmail.com>
 Scott Ferguson <scottwferg@gmail.com>
 Scott Lawrence <bytbox@gmail.com>
@@ -2191,6 +2299,7 @@
 Sean Christopherson <sean.j.christopherson@intel.com>
 Sean Dolphin <Sean.Dolphin@kpcompass.com>
 Sean Harger <sharger@google.com>
+Sean Harrington <sean.harrington@leftfieldlabs.com>
 Sean Hildebrand <seanwhildebrand@gmail.com>
 Sean Liao <seankhliao@gmail.com>
 Sean Rees <sean@erifax.org>
@@ -2212,6 +2321,7 @@
 Sergey Frolov <sfrolov@google.com>
 Sergey Glushchenko <gsserge@gmail.com>
 Sergey Ivanov <ser1325@gmail.com>
+Sergey Kacheev <S.Kacheev@gmail.com>
 Sergey Lukjanov <me@slukjanov.name>
 Sergey Mishin <sergeymishine@gmail.com>
 Sergey Mudrik <sergey.mudrik@gmail.com>
@@ -2223,6 +2333,7 @@
 Serhii Aheienko <serhii.aheienko@gmail.com>
 Seth Hoenig <seth.a.hoenig@gmail.com>
 Seth Vargo <sethvargo@gmail.com>
+Shaba Abhiram <shabarivas.abhiram@gmail.com>
 Shahar Kohanim <skohanim@gmail.com>
 Shailesh Suryawanshi <ss.shailesh28@gmail.com>
 Shamil Garatuev <garatuev@gmail.com>
@@ -2250,9 +2361,13 @@
 Shivani Singhal <shivani.singhal2804@gmail.com>
 Shivansh Rai <shivansh@freebsd.org>
 Shivashis Padhi <shivashispadhi@gmail.com>
+Shoshin Nikita <shoshin_nikita@fastmail.com>
+Shota Sugiura <s.shota.710.3506@gmail.com>
 Shubham Sharma <shubham.sha12@gmail.com>
+Shuhei Takahashi <nya@chromium.org>
 Shun Fan <sfan@google.com>
 Silvan Jegen <s.jegen@gmail.com>
+Simão Gomes Viana <simaogmv@gmail.com>
 Simarpreet Singh <simar@linux.com>
 Simon Drake <simondrake1990@gmail.com>
 Simon Ferquel <simon.ferquel@docker.com>
@@ -2267,13 +2382,16 @@
 Sjoerd Siebinga <sjoerd.siebinga@gmail.com>
 Sokolov Yura <funny.falcon@gmail.com>
 Song Gao <song@gao.io>
+Song Lim <songlim327@gmail.com>
 Songjiayang <songjiayang1@gmail.com>
+Songlin Jiang <hollowman@hollowman.ml>
 Soojin Nam <jsunam@gmail.com>
 Søren L. Hansen <soren@linux2go.dk>
 Sparrow Li <liyuancylx@gmail.com>
 Spencer Kocot <spencerkocot@gmail.com>
 Spencer Nelson <s@spenczar.com>
 Spencer Tung <spencertung@google.com>
+Spenser Black <spenserblack01@gmail.com>
 Spring Mc <heresy.mc@gmail.com>
 Srdjan Petrovic <spetrovic@google.com>
 Sridhar Venkatakrishnan <sridhar@laddoo.net>
@@ -2324,6 +2442,7 @@
 Suzy Mueller <suzmue@golang.org>
 Sven Almgren <sven@tras.se>
 Sven Blumenstein <svbl@google.com>
+Sven Lee <lee1300394324@gmail.com>
 Sven Taute <sven.taute@gmail.com>
 Sylvain Zimmer <sylvain@sylvainzimmer.com>
 Syohei YOSHIDA <syohex@gmail.com>
@@ -2406,12 +2525,14 @@
 Tobias Assarsson <tobias.assarsson@gmail.com>
 Tobias Columbus <tobias.columbus@gmail.com> <tobias.columbus@googlemail.com>
 Tobias Klauser <tklauser@distanz.ch>
+Tobias Kohlbau <tobias@kohlbau.de>
 Toby Burress <kurin@google.com>
 Todd Kulesza <tkulesza@google.com>
 Todd Neal <todd@tneal.org>
 Todd Wang <toddwang@gmail.com>
 Tom Anthony <git@tomanthony.co.uk>
 Tom Bergan <tombergan@google.com>
+Tom Freudenberg <tom.freudenberg@4commerce.de>
 Tom Heng <zhm20070928@gmail.com>
 Tom Lanyon <tomlanyon@google.com>
 Tom Levy <tomlevy93@gmail.com>
@@ -2440,6 +2561,7 @@
 Totoro W <tw19881113@gmail.com>
 Travis Bischel <travis.bischel@gmail.com>
 Travis Cline <travis.cline@gmail.com>
+Trevor Dixon <trevordixon@gmail.com>
 Trevor Strohman <trevor.strohman@gmail.com>
 Trey Lawrence <lawrence.trey@gmail.com>
 Trey Roessig <trey.roessig@gmail.com>
@@ -2463,6 +2585,7 @@
 Tzu-Chiao Yeh <su3g4284zo6y7@gmail.com>
 Tzu-Jung Lee <roylee17@currant.com>
 Udalov Max <re.udalov@gmail.com>
+Uddeshya Singh <singhuddeshyaofficial@gmail.com>
 Ugorji Nwoke <ugorji@gmail.com>
 Ulf Holm Nielsen <doktor@dyregod.dk>
 Ulrich Kunitz <uli.kunitz@gmail.com>
@@ -2475,6 +2598,7 @@
 Vadim Vygonets <unixdj@gmail.com>
 Val Polouchkine <vpolouch@justin.tv>
 Valentin Vidic <vvidic@valentin-vidic.from.hr>
+Vaughn Iverson <vsivsi@yahoo.com>
 Vee Zhang <veezhang@126.com> <vveezhang@gmail.com>
 Vega Garcia Luis Alfonso <vegacom@gmail.com>
 Venil Noronha <veniln@vmware.com>
@@ -2491,6 +2615,7 @@
 Vincent Vanackere <vincent.vanackere@gmail.com>
 Vinu Rajashekhar <vinutheraj@gmail.com>
 Vish Subramanian <vish@google.com>
+Vishal Dalwadi <dalwadivishal26@gmail.com>
 Vishvananda Ishaya <vishvananda@gmail.com>
 Visweswara R <r.visweswara@gmail.com>
 Vitaly Zdanevich <zdanevich.vitaly@ya.ru>
@@ -2526,6 +2651,7 @@
 Wei Xiao <wei.xiao@arm.com>
 Wei Xikai <xykwei@gmail.com>
 Weichao Tang <tevic.tt@gmail.com>
+Weixie Cui <cuiweixie@gmail.com> <523516579@qq.com>
 Wembley G. Leach, Jr <wembley.gl@gmail.com>
 Wenlei (Frank) He <wlhe@google.com>
 Wenzel Lowe <lowewenzel@gmail.com>
@@ -2541,6 +2667,7 @@
 William Chan <willchan@chromium.org>
 William Chang <mr.williamchang@gmail.com>
 William Josephson <wjosephson@gmail.com>
+William Langford <wlangfor@gmail.com>
 William Orr <will@worrbase.com> <ay1244@gmail.com>
 William Poussier <william.poussier@gmail.com>
 Wisdom Omuya <deafgoat@gmail.com>
@@ -2549,6 +2676,7 @@
 Xia Bin <snyh@snyh.org>
 Xiangdong Ji <xiangdong.ji@arm.com>
 Xiaodong Liu <teaofmoli@gmail.com>
+Xing Gao <18340825824@163.com>
 Xing Xing <mikespook@gmail.com>
 Xingqang Bai <bxq2011hust@qq.com>
 Xu Fei <badgangkiller@gmail.com>
@@ -2570,6 +2698,7 @@
 Yasser Abdolmaleki <yasser@yasser.ca>
 Yasuharu Goto <matope.ono@gmail.com>
 Yasuhiro Matsumoto <mattn.jp@gmail.com>
+Yasutaka Shinzaki <shinzaki@yasu26.tech>
 Yasuyuki Oka <yasuyk@gmail.com>
 Yazen Shunnar <yazen.shunnar@gmail.com>
 Yestin Sun <ylh@pdx.edu>
@@ -2582,14 +2711,18 @@
 Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp>
 Yoshiyuki Mineo <yoshiyuki.mineo@gmail.com>
 Yosuke Akatsuka <yosuke.akatsuka@gmail.com>
+Youfu Zhang <zhangyoufu@gmail.com>
 Yu Heng Zhang <annita.zhang@cn.ibm.com>
 Yu Xuan Zhang <zyxsh@cn.ibm.com>
+Yu, Li-Yu <afg984@gmail.com>
 Yuichi Kishimoto <yk2220s@gmail.com>
 Yuichi Nishiwaki <yuichi.nishiwaki@gmail.com>
 Yuji Yaginuma <yuuji.yaginuma@gmail.com>
+Yuki Ito <mrno110y@gmail.com>
 Yuki OKUSHI <huyuumi.dev@gmail.com>
 Yuki Yugui Sonoda <yugui@google.com>
 Yukihiro Nishinaka <6elpinal@gmail.com>
+YunQiang Su <syq@debian.org>
 Yury Smolsky <yury@smolsky.by>
 Yusuke Kagiwada <block.rxckin.beats@gmail.com>
 Yuusei Kuwana <kuwana@kumama.org>
@@ -2598,6 +2731,7 @@
 Zac Bergquist <zbergquist99@gmail.com>
 Zach Bintliff <zbintliff@gmail.com>
 Zach Gershman <zachgersh@gmail.com>
+Zach Hoffman <zrhoffman@apache.org>
 Zach Jones <zachj1@gmail.com>
 Zachary Amsden <zach@thundertoken.com>
 Zachary Gershman <zgershman@pivotal.io>
@@ -2616,6 +2750,7 @@
 Ziad Hatahet <hatahet@gmail.com>
 Ziheng Liu <lzhfromustc@gmail.com>
 Zorion Arrizabalaga <zorionk@gmail.com>
+Zvonimir Pavlinovic <zpavlinovic@google.com>
 Zyad A. Ali <zyad.ali.me@gmail.com>
 Максадбек Ахмедов <a.maksadbek@gmail.com>
 Максим Федосеев <max.faceless.frei@gmail.com>
diff --git a/VERSION b/VERSION
index ea60ca0..dd23292 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-go1.16.3
\ No newline at end of file
+go1.17
\ No newline at end of file
diff --git a/api/except.txt b/api/except.txt
index 6f6f839..14fe778 100644
--- a/api/except.txt
+++ b/api/except.txt
@@ -1,4 +1,7 @@
 pkg encoding/json, method (*RawMessage) MarshalJSON() ([]uint8, error)
+pkg math, const MaxFloat64 = 1.79769e+308  // 179769313486231570814527423731704356798100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+pkg math, const SmallestNonzeroFloat32 = 1.4013e-45  // 17516230804060213386546619791123951641/12500000000000000000000000000000000000000000000000000000000000000000000000000000000
+pkg math, const SmallestNonzeroFloat64 = 4.94066e-324  // 4940656458412465441765687928682213723651/1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 pkg math/big, const MaxBase = 36
 pkg math/big, type Word uintptr
 pkg net, func ListenUnixgram(string, *UnixAddr) (*UDPConn, error)
diff --git a/api/go1.17.txt b/api/go1.17.txt
new file mode 100644
index 0000000..4850538
--- /dev/null
+++ b/api/go1.17.txt
@@ -0,0 +1,195 @@
+pkg archive/zip, method (*File) OpenRaw() (io.Reader, error)
+pkg archive/zip, method (*Writer) Copy(*File) error
+pkg archive/zip, method (*Writer) CreateRaw(*FileHeader) (io.Writer, error)
+pkg compress/lzw, method (*Reader) Close() error
+pkg compress/lzw, method (*Reader) Read([]uint8) (int, error)
+pkg compress/lzw, method (*Reader) Reset(io.Reader, Order, int)
+pkg compress/lzw, method (*Writer) Close() error
+pkg compress/lzw, method (*Writer) Reset(io.Writer, Order, int)
+pkg compress/lzw, method (*Writer) Write([]uint8) (int, error)
+pkg compress/lzw, type Reader struct
+pkg compress/lzw, type Writer struct
+pkg crypto/tls, method (*CertificateRequestInfo) Context() context.Context
+pkg crypto/tls, method (*ClientHelloInfo) Context() context.Context
+pkg crypto/tls, method (*Conn) HandshakeContext(context.Context) error
+pkg database/sql, method (*NullByte) Scan(interface{}) error
+pkg database/sql, method (*NullInt16) Scan(interface{}) error
+pkg database/sql, method (NullByte) Value() (driver.Value, error)
+pkg database/sql, method (NullInt16) Value() (driver.Value, error)
+pkg database/sql, type NullByte struct
+pkg database/sql, type NullByte struct, Byte uint8
+pkg database/sql, type NullByte struct, Valid bool
+pkg database/sql, type NullInt16 struct
+pkg database/sql, type NullInt16 struct, Int16 int16
+pkg database/sql, type NullInt16 struct, Valid bool
+pkg debug/elf, const SHT_MIPS_ABIFLAGS = 1879048234
+pkg debug/elf, const SHT_MIPS_ABIFLAGS SectionType
+pkg encoding/csv, method (*Reader) FieldPos(int) (int, int)
+pkg go/build, type Context struct, ToolTags []string
+pkg go/parser, const SkipObjectResolution = 64
+pkg go/parser, const SkipObjectResolution Mode
+pkg image, method (*Alpha) RGBA64At(int, int) color.RGBA64
+pkg image, method (*Alpha) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*Alpha16) RGBA64At(int, int) color.RGBA64
+pkg image, method (*Alpha16) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*CMYK) RGBA64At(int, int) color.RGBA64
+pkg image, method (*CMYK) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*Gray) RGBA64At(int, int) color.RGBA64
+pkg image, method (*Gray) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*Gray16) RGBA64At(int, int) color.RGBA64
+pkg image, method (*Gray16) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*NRGBA) RGBA64At(int, int) color.RGBA64
+pkg image, method (*NRGBA) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*NRGBA64) RGBA64At(int, int) color.RGBA64
+pkg image, method (*NRGBA64) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*NYCbCrA) RGBA64At(int, int) color.RGBA64
+pkg image, method (*Paletted) RGBA64At(int, int) color.RGBA64
+pkg image, method (*Paletted) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*RGBA) RGBA64At(int, int) color.RGBA64
+pkg image, method (*RGBA) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*Uniform) RGBA64At(int, int) color.RGBA64
+pkg image, method (*YCbCr) RGBA64At(int, int) color.RGBA64
+pkg image, method (Rectangle) RGBA64At(int, int) color.RGBA64
+pkg image, type RGBA64Image interface { At, Bounds, ColorModel, RGBA64At }
+pkg image, type RGBA64Image interface, At(int, int) color.Color
+pkg image, type RGBA64Image interface, Bounds() Rectangle
+pkg image, type RGBA64Image interface, ColorModel() color.Model
+pkg image, type RGBA64Image interface, RGBA64At(int, int) color.RGBA64
+pkg image/draw, type RGBA64Image interface { At, Bounds, ColorModel, RGBA64At, Set, SetRGBA64 }
+pkg image/draw, type RGBA64Image interface, At(int, int) color.Color
+pkg image/draw, type RGBA64Image interface, Bounds() image.Rectangle
+pkg image/draw, type RGBA64Image interface, ColorModel() color.Model
+pkg image/draw, type RGBA64Image interface, RGBA64At(int, int) color.RGBA64
+pkg image/draw, type RGBA64Image interface, Set(int, int, color.Color)
+pkg image/draw, type RGBA64Image interface, SetRGBA64(int, int, color.RGBA64)
+pkg io/fs, func FileInfoToDirEntry(FileInfo) DirEntry
+pkg math, const MaxFloat64 = 1.79769e+308  // 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
+pkg math, const MaxInt = 9223372036854775807
+pkg math, const MaxInt ideal-int
+pkg math, const MaxUint = 18446744073709551615
+pkg math, const MaxUint ideal-int
+pkg math, const MinInt = -9223372036854775808
+pkg math, const MinInt ideal-int
+pkg math, const SmallestNonzeroFloat32 = 1.4013e-45  // 1/713623846352979940529142984724747568191373312
+pkg math, const SmallestNonzeroFloat64 = 4.94066e-324  // 1/202402253307310618352495346718917307049556649764142118356901358027430339567995346891960383701437124495187077864316811911389808737385793476867013399940738509921517424276566361364466907742093216341239767678472745068562007483424692698618103355649159556340810056512358769552333414615230502532186327508646006263307707741093494784
+pkg net, method (*ParseError) Temporary() bool
+pkg net, method (*ParseError) Timeout() bool
+pkg net, method (IP) IsPrivate() bool
+pkg net/http, func AllowQuerySemicolons(Handler) Handler
+pkg net/url, method (Values) Has(string) bool
+pkg reflect, func VisibleFields(Type) []StructField
+pkg reflect, method (Method) IsExported() bool
+pkg reflect, method (StructField) IsExported() bool
+pkg reflect, method (Value) CanConvert(Type) bool
+pkg runtime/cgo (darwin-amd64-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (darwin-amd64-cgo), method (Handle) Delete()
+pkg runtime/cgo (darwin-amd64-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (darwin-amd64-cgo), type Handle uintptr
+pkg runtime/cgo (freebsd-386-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (freebsd-386-cgo), method (Handle) Delete()
+pkg runtime/cgo (freebsd-386-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (freebsd-386-cgo), type Handle uintptr
+pkg runtime/cgo (freebsd-amd64-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (freebsd-amd64-cgo), method (Handle) Delete()
+pkg runtime/cgo (freebsd-amd64-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (freebsd-amd64-cgo), type Handle uintptr
+pkg runtime/cgo (freebsd-arm-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (freebsd-arm-cgo), method (Handle) Delete()
+pkg runtime/cgo (freebsd-arm-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (freebsd-arm-cgo), type Handle uintptr
+pkg runtime/cgo (linux-386-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (linux-386-cgo), method (Handle) Delete()
+pkg runtime/cgo (linux-386-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (linux-386-cgo), type Handle uintptr
+pkg runtime/cgo (linux-amd64-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (linux-amd64-cgo), method (Handle) Delete()
+pkg runtime/cgo (linux-amd64-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (linux-amd64-cgo), type Handle uintptr
+pkg runtime/cgo (linux-arm-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (linux-arm-cgo), method (Handle) Delete()
+pkg runtime/cgo (linux-arm-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (linux-arm-cgo), type Handle uintptr
+pkg runtime/cgo (netbsd-386-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (netbsd-386-cgo), method (Handle) Delete()
+pkg runtime/cgo (netbsd-386-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (netbsd-386-cgo), type Handle uintptr
+pkg runtime/cgo (netbsd-amd64-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (netbsd-amd64-cgo), method (Handle) Delete()
+pkg runtime/cgo (netbsd-amd64-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (netbsd-amd64-cgo), type Handle uintptr
+pkg runtime/cgo (netbsd-arm-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (netbsd-arm-cgo), method (Handle) Delete()
+pkg runtime/cgo (netbsd-arm-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (netbsd-arm-cgo), type Handle uintptr
+pkg runtime/cgo (netbsd-arm64-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (netbsd-arm64-cgo), method (Handle) Delete()
+pkg runtime/cgo (netbsd-arm64-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (netbsd-arm64-cgo), type Handle uintptr
+pkg runtime/cgo (openbsd-386-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (openbsd-386-cgo), method (Handle) Delete()
+pkg runtime/cgo (openbsd-386-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (openbsd-386-cgo), type Handle uintptr
+pkg runtime/cgo (openbsd-amd64-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (openbsd-amd64-cgo), method (Handle) Delete()
+pkg runtime/cgo (openbsd-amd64-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (openbsd-amd64-cgo), type Handle uintptr
+pkg strconv, func QuotedPrefix(string) (string, error)
+pkg sync/atomic, method (*Value) CompareAndSwap(interface{}, interface{}) bool
+pkg sync/atomic, method (*Value) Swap(interface{}) interface{}
+pkg syscall (netbsd-386), const SYS_WAIT6 = 481
+pkg syscall (netbsd-386), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-386), const WEXITED = 32
+pkg syscall (netbsd-386), const WEXITED ideal-int
+pkg syscall (netbsd-386-cgo), const SYS_WAIT6 = 481
+pkg syscall (netbsd-386-cgo), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-386-cgo), const WEXITED = 32
+pkg syscall (netbsd-386-cgo), const WEXITED ideal-int
+pkg syscall (netbsd-amd64), const SYS_WAIT6 = 481
+pkg syscall (netbsd-amd64), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-amd64), const WEXITED = 32
+pkg syscall (netbsd-amd64), const WEXITED ideal-int
+pkg syscall (netbsd-amd64-cgo), const SYS_WAIT6 = 481
+pkg syscall (netbsd-amd64-cgo), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-amd64-cgo), const WEXITED = 32
+pkg syscall (netbsd-amd64-cgo), const WEXITED ideal-int
+pkg syscall (netbsd-arm), const SYS_WAIT6 = 481
+pkg syscall (netbsd-arm), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-arm), const WEXITED = 32
+pkg syscall (netbsd-arm), const WEXITED ideal-int
+pkg syscall (netbsd-arm-cgo), const SYS_WAIT6 = 481
+pkg syscall (netbsd-arm-cgo), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-arm-cgo), const WEXITED = 32
+pkg syscall (netbsd-arm-cgo), const WEXITED ideal-int
+pkg syscall (netbsd-arm64), const SYS_WAIT6 = 481
+pkg syscall (netbsd-arm64), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-arm64), const WEXITED = 32
+pkg syscall (netbsd-arm64), const WEXITED ideal-int
+pkg syscall (netbsd-arm64-cgo), const SYS_WAIT6 = 481
+pkg syscall (netbsd-arm64-cgo), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-arm64-cgo), const WEXITED = 32
+pkg syscall (netbsd-arm64-cgo), const WEXITED ideal-int
+pkg syscall (openbsd-386), const MSG_CMSG_CLOEXEC = 2048
+pkg syscall (openbsd-386), const MSG_CMSG_CLOEXEC ideal-int
+pkg syscall (openbsd-386-cgo), const MSG_CMSG_CLOEXEC = 2048
+pkg syscall (openbsd-386-cgo), const MSG_CMSG_CLOEXEC ideal-int
+pkg syscall (openbsd-amd64), const MSG_CMSG_CLOEXEC = 2048
+pkg syscall (openbsd-amd64), const MSG_CMSG_CLOEXEC ideal-int
+pkg syscall (openbsd-amd64-cgo), const MSG_CMSG_CLOEXEC = 2048
+pkg syscall (openbsd-amd64-cgo), const MSG_CMSG_CLOEXEC ideal-int
+pkg syscall (windows-386), type SysProcAttr struct, AdditionalInheritedHandles []Handle
+pkg syscall (windows-386), type SysProcAttr struct, ParentProcess Handle
+pkg syscall (windows-amd64), type SysProcAttr struct, AdditionalInheritedHandles []Handle
+pkg syscall (windows-amd64), type SysProcAttr struct, ParentProcess Handle
+pkg testing, method (*B) Setenv(string, string)
+pkg testing, method (*T) Setenv(string, string)
+pkg testing, type TB interface, Setenv(string, string)
+pkg text/template/parse, const SkipFuncCheck = 2
+pkg text/template/parse, const SkipFuncCheck Mode
+pkg time, const Layout = "01/02 03:04:05PM '06 -0700"
+pkg time, const Layout ideal-string
+pkg time, func UnixMicro(int64) Time
+pkg time, func UnixMilli(int64) Time
+pkg time, method (Time) GoString() string
+pkg time, method (Time) IsDST() bool
+pkg time, method (Time) UnixMicro() int64
+pkg time, method (Time) UnixMilli() int64
diff --git a/bin/go b/bin/go
index 7950339..3b54215 100755
--- a/bin/go
+++ b/bin/go
Binary files differ
diff --git a/bin/gofmt b/bin/gofmt
index f04f707..52e3bad 100755
--- a/bin/gofmt
+++ b/bin/gofmt
Binary files differ
diff --git a/codereview.cfg b/codereview.cfg
new file mode 100644
index 0000000..9d5ebe8
--- /dev/null
+++ b/codereview.cfg
@@ -0,0 +1,2 @@
+branch: release-branch.go1.17
+parent-branch: master
diff --git a/doc/asm.html b/doc/asm.html
index 7173d9b..51f85eb 100644
--- a/doc/asm.html
+++ b/doc/asm.html
@@ -166,7 +166,7 @@
 </li>
 
 <li>
-<code>SP</code>: Stack pointer: top of stack.
+<code>SP</code>: Stack pointer: the highest address within the local stack frame.
 </li>
 
 </ul>
@@ -216,7 +216,7 @@
 The <code>SP</code> pseudo-register is a virtual stack pointer
 used to refer to frame-local variables and the arguments being
 prepared for function calls.
-It points to the top of the local stack frame, so references should use negative offsets
+It points to the highest address within the local stack frame, so references should use negative offsets
 in the range [−framesize, 0):
 <code>x-8(SP)</code>, <code>y-4(SP)</code>, and so on.
 </p>
@@ -409,7 +409,7 @@
 (For <code>TEXT</code> items.)
 Don't insert the preamble to check if the stack must be split.
 The frame for the routine, plus anything it calls, must fit in the
-spare space at the top of the stack segment.
+spare space remaining in the current stack segment.
 Used to protect routines such as the stack splitting code itself.
 </li>
 <li>
@@ -460,7 +460,7 @@
 <code>TOPFRAME</code> = 2048
 <br>
 (For <code>TEXT</code> items.)
-Function is the top of the call stack. Traceback should stop at this function.
+Function is the outermost frame of the call stack. Traceback should stop at this function.
 </li>
 </ul>
 
@@ -828,10 +828,6 @@
 <h3 id="arm64">ARM64</h3>
 
 <p>
-The ARM64 port is in an experimental state.
-</p>
-
-<p>
 <code>R18</code> is the "platform register", reserved on the Apple platform.
 To prevent accidental misuse, the register is named <code>R18_PLATFORM</code>.
 <code>R27</code> and <code>R28</code> are reserved by the compiler and linker.
diff --git a/doc/go1.16.html b/doc/go1.16.html
deleted file mode 100644
index 0beb62d..0000000
--- a/doc/go1.16.html
+++ /dev/null
@@ -1,1220 +0,0 @@
-<!--{
-	"Title": "Go 1.16 Release Notes",
-	"Path":  "/doc/go1.16"
-}-->
-
-<!--
-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>
-  main ul li { margin: 0.5em 0; }
-</style>
-
-<h2 id="introduction">Introduction to Go 1.16</h2>
-
-<p>
-  The latest Go release, version 1.16, arrives six months after <a href="/doc/go1.15">Go 1.15</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>
-
-<h2 id="language">Changes to the language</h2>
-
-<p>
-  There are no changes to the language.
-</p>
-
-<h2 id="ports">Ports</h2>
-
-<h3 id="darwin">Darwin and iOS</h3>
-
-<p><!-- golang.org/issue/38485, golang.org/issue/41385, CL 266373, more CLs -->
-  Go 1.16 adds support of 64-bit ARM architecture on macOS (also known as
-  Apple Silicon) with <code>GOOS=darwin</code>, <code>GOARCH=arm64</code>.
-  Like the <code>darwin/amd64</code> port, the <code>darwin/arm64</code>
-  port supports cgo, internal and external linking, <code>c-archive</code>,
-  <code>c-shared</code>, and <code>pie</code> build modes, and the race
-  detector.
-</p>
-
-<p><!-- CL 254740 -->
-  The iOS port, which was previously <code>darwin/arm64</code>, has
-  been renamed to <code>ios/arm64</code>. <code>GOOS=ios</code>
-  implies the
-  <code>darwin</code> build tag, just as <code>GOOS=android</code>
-  implies the <code>linux</code> build tag. This change should be
-  transparent to anyone using gomobile to build iOS apps.
-</p>
-
-<p><!-- golang.org/issue/42100, CL 263798 -->
-  Go 1.16 adds an <code>ios/amd64</code> port, which targets the iOS
-  simulator running on AMD64-based macOS. Previously this was
-  unofficially supported through <code>darwin/amd64</code> with
-  the <code>ios</code> build tag set. See also
-  <a href="/misc/ios/README"><code>misc/ios/README</code></a> for
-  details about how to build programs for iOS and iOS simulator.
-</p>
-
-<p><!-- golang.org/issue/23011 -->
-  Go 1.16 is the last release that will run on macOS 10.12 Sierra.
-  Go 1.17 will require macOS 10.13 High Sierra or later.
-</p>
-
-<h3 id="netbsd">NetBSD</h3>
-
-<p><!-- golang.org/issue/30824 -->
-  Go now supports the 64-bit ARM architecture on NetBSD (the
-  <code>netbsd/arm64</code> port).
-</p>
-
-<h3 id="openbsd">OpenBSD</h3>
-
-<p><!-- golang.org/issue/40995 -->
-  Go now supports the MIPS64 architecture on OpenBSD
-  (the <code>openbsd/mips64</code> port). This port does not yet
-  support cgo.
-</p>
-
-<p><!-- golang.org/issue/36435, many CLs -->
-  On the 64-bit x86 and 64-bit ARM architectures on OpenBSD (the
-  <code>openbsd/amd64</code> and <code>openbsd/arm64</code> ports), system
-  calls are now made through <code>libc</code>, instead of directly using
-  the <code>SYSCALL</code>/<code>SVC</code> instruction. This ensures
-  forward-compatibility with future versions of OpenBSD. In particular,
-  OpenBSD 6.9 onwards will require system calls to be made through
-  <code>libc</code> for non-static Go binaries.
-</p>
-
-<h3 id="386">386</h3>
-
-<p><!-- golang.org/issue/40255, golang.org/issue/41848, CL 258957, and CL 260017 -->
-  As <a href="go1.15#386">announced</a> in the Go 1.15 release notes,
-  Go 1.16 drops support for x87 mode compilation (<code>GO386=387</code>).
-  Support for non-SSE2 processors is now available using soft float
-  mode (<code>GO386=softfloat</code>).
-  Users running on non-SSE2 processors should replace <code>GO386=387</code>
-  with <code>GO386=softfloat</code>.
-</p>
-
-<h3 id="riscv">RISC-V</h3>
-
-<p><!-- golang.org/issue/36641, CL 267317 -->
-  The <code>linux/riscv64</code> port now supports cgo and
-  <code>-buildmode=pie</code>. This release also includes performance
-  optimizations and code generation improvements for RISC-V.
-</p>
-
-<h2 id="tools">Tools</h2>
-
-<h3 id="go-command">Go command</h3>
-
-<h4 id="modules">Modules</h4>
-
-<p><!-- golang.org/issue/41330 -->
-  Module-aware mode is enabled by default, regardless of whether a
-  <code>go.mod</code> file is present in the current working directory or a
-  parent directory. More precisely, the <code>GO111MODULE</code> environment
-  variable now defaults to <code>on</code>. To switch to the previous behavior,
-  set <code>GO111MODULE</code> to <code>auto</code>.
-</p>
-
-<p><!-- golang.org/issue/40728 -->
-  Build commands like <code>go</code> <code>build</code> and <code>go</code>
-  <code>test</code> no longer modify <code>go.mod</code> and <code>go.sum</code>
-  by default. Instead, they report an error if a module requirement or checksum
-  needs to be added or updated (as if the <code>-mod=readonly</code> flag were
-  used). Module requirements and sums may be adjusted with <code>go</code>
-  <code>mod</code> <code>tidy</code> or <code>go</code> <code>get</code>.
-</p>
-
-<p><!-- golang.org/issue/40276 -->
-  <code>go</code> <code>install</code> now accepts arguments with
-  version suffixes (for example, <code>go</code> <code>install</code>
-  <code>example.com/cmd@v1.0.0</code>). This causes <code>go</code>
-  <code>install</code> to build and install packages in module-aware mode,
-  ignoring the <code>go.mod</code> file in the current directory or any parent
-  directory, if there is one. This is useful for installing executables without
-  affecting the dependencies of the main module.
-</p>
-
-<p><!-- golang.org/issue/40276 -->
-  <code>go</code> <code>install</code>, with or without a version suffix (as
-  described above), is now the recommended way to build and install packages in
-  module mode. <code>go</code> <code>get</code> should be used with the
-  <code>-d</code> flag to adjust the current module's dependencies without
-  building packages, and use of <code>go</code> <code>get</code> to build and
-  install packages is deprecated. In a future release, the <code>-d</code> flag
-  will always be enabled.
-</p>
-
-<p><!-- golang.org/issue/24031 -->
-  <code>retract</code> directives may now be used in a <code>go.mod</code> file
-  to indicate that certain published versions of the module should not be used
-  by other modules. A module author may retract a version after a severe problem
-  is discovered or if the version was published unintentionally.
-</p>
-
-<p><!-- golang.org/issue/26603 -->
-  The <code>go</code> <code>mod</code> <code>vendor</code>
-  and <code>go</code> <code>mod</code> <code>tidy</code> subcommands now accept
-  the <code>-e</code> flag, which instructs them to proceed despite errors in
-  resolving missing packages.
-</p>
-
-<p><!-- golang.org/issue/36465 -->
-  The <code>go</code> command now ignores requirements on module versions
-  excluded by <code>exclude</code> directives in the main module. Previously,
-  the <code>go</code> command used the next version higher than an excluded
-  version, but that version could change over time, resulting in
-  non-reproducible builds.
-</p>
-
-<p><!-- golang.org/issue/43052, golang.org/issue/43985 -->
-  In module mode, the <code>go</code> command now disallows import paths that
-  include non-ASCII characters or path elements with a leading dot character
-  (<code>.</code>). Module paths with these characters were already disallowed
-  (see <a href="/ref/mod#go-mod-file-ident">Module paths and versions</a>),
-  so this change affects only paths within module subdirectories.
-</p>
-
-<h4 id="embed">Embedding Files</h4>
-
-<p>
-  The <code>go</code> command now supports including
-  static files and file trees as part of the final executable,
-  using the new <code>//go:embed</code> directive.
-  See the documentation for the new
-  <a href="/pkg/embed/"><code>embed</code></a>
-  package for details.
-</p>
-
-<h4 id="go-test"><code>go</code> <code>test</code></h4>
-
-<p><!-- golang.org/issue/29062 -->
-  When using <code>go</code> <code>test</code>, a test that
-  calls <code>os.Exit(0)</code> during execution of a test function
-  will now be considered to fail.
-  This will help catch cases in which a test calls code that calls
-  <code>os.Exit(0)</code> and thereby stops running all future tests.
-  If a <code>TestMain</code> function calls <code>os.Exit(0)</code>
-  that is still considered to be a passing test.
-</p>
-
-<p><!-- golang.org/issue/39484 -->
-  <code>go</code> <code>test</code> reports an error when the <code>-c</code>
-  or <code>-i</code> flags are used together with unknown flags. Normally,
-  unknown flags are passed to tests, but when <code>-c</code> or <code>-i</code>
-  are used, tests are not run.
-</p>
-
-<h4 id="go-get"><code>go</code> <code>get</code></h4>
-
-<p><!-- golang.org/issue/37519 -->
-  The <code>go</code> <code>get</code> <code>-insecure</code> flag is
-  deprecated and will be removed in a future version. This flag permits
-  fetching from repositories and resolving custom domains using insecure
-  schemes such as HTTP, and also bypasses module sum validation using the
-  checksum database. To permit the use of insecure schemes, use the
-  <code>GOINSECURE</code> environment variable instead. To bypass module
-  sum validation, use <code>GOPRIVATE</code> or <code>GONOSUMDB</code>.
-  See <code>go</code> <code>help</code> <code>environment</code> for details.
-</p>
-
-<p><!-- golang.org/cl/263267 -->
-  <code>go</code> <code>get</code> <code>example.com/mod@patch</code> now
-  requires that some version of <code>example.com/mod</code> already be
-  required by the main module.
-  (However, <code>go</code> <code>get</code> <code>-u=patch</code> continues
-  to patch even newly-added dependencies.)
-</p>
-
-<h4 id="govcs"><code>GOVCS</code> environment variable</h4>
-
-<p><!-- golang.org/issue/266420 -->
-  <code>GOVCS</code> is a new environment variable that limits which version
-  control tools the <code>go</code> command may use to download source code.
-  This mitigates security issues with tools that are typically used in trusted,
-  authenticated environments. By default, <code>git</code> and <code>hg</code>
-  may be used to download code from any repository. <code>svn</code>,
-  <code>bzr</code>, and <code>fossil</code> may only be used to download code
-  from repositories with module paths or package paths matching patterns in
-  the <code>GOPRIVATE</code> environment variable. See
-  <a href="/cmd/go/#hdr-Controlling_version_control_with_GOVCS"><code>go</code>
-  <code>help</code> <code>vcs</code></a> for details.
-</p>
-
-<h4 id="all-pattern">The <code>all</code> pattern</h4>
-
-<p><!-- golang.org/cl/240623 -->
-  When the main module's <code>go.mod</code> file
-  declares <code>go</code> <code>1.16</code> or higher, the <code>all</code>
-  package pattern now matches only those packages that are transitively imported
-  by a package or test found in the main module. (Packages imported by <em>tests
-  of</em> packages imported by the main module are no longer included.) This is
-  the same set of packages retained
-  by <code>go</code> <code>mod</code> <code>vendor</code> since Go 1.11.
-</p>
-
-<h4 id="toolexec">The <code>-toolexec</code> build flag</h4>
-
-<p><!-- golang.org/cl/263357 -->
-  When the <code>-toolexec</code> build flag is specified to use a program when
-  invoking toolchain programs like compile or asm, the environment variable
-  <code>TOOLEXEC_IMPORTPATH</code> is now set to the import path of the package
-  being built.
-</p>
-
-<h4 id="i-flag">The <code>-i</code> build flag</h4>
-
-<p><!-- golang.org/issue/41696 -->
-  The <code>-i</code> flag accepted by <code>go</code> <code>build</code>,
-  <code>go</code> <code>install</code>, and <code>go</code> <code>test</code> is
-  now deprecated. The <code>-i</code> flag instructs the <code>go</code> command
-  to install packages imported by packages named on the command line. Since
-  the build cache was introduced in Go 1.10, the <code>-i</code> flag no longer
-  has a significant effect on build times, and it causes errors when the install
-  directory is not writable.
-</p>
-
-<h4 id="list-buildid">The <code>list</code> command</h4>
-
-<p><!-- golang.org/cl/263542 -->
-  When the <code>-export</code> flag is specified, the <code>BuildID</code>
-  field is now set to the build ID of the compiled package. This is equivalent
-  to running <code>go</code> <code>tool</code> <code>buildid</code> on
-  <code>go</code> <code>list</code> <code>-exported</code> <code>-f</code> <code>{{.Export}}</code>,
-  but without the extra step.
-</p>
-
-<h4 id="overlay-flag">The <code>-overlay</code> flag</h4>
-
-<p><!-- golang.org/issue/39958 -->
-  The <code>-overlay</code> flag specifies a JSON configuration file containing
-  a set of file path replacements. The <code>-overlay</code> flag may be used
-  with all build commands and <code>go</code> <code>mod</code> subcommands.
-  It is primarily intended to be used by editor tooling such as gopls to
-  understand the effects of unsaved changes to source files.  The config file
-  maps actual file paths to replacement file paths and the <code>go</code>
-  command and its builds will run as if the actual file paths exist with the
-  contents given by the replacement file paths, or don't exist if the replacement
-  file paths are empty.
-</p>
-
-<h3 id="cgo">Cgo</h3>
-
-<p><!-- CL 252378 -->
-  The <a href="/cmd/cgo">cgo</a> tool will no longer try to translate
-  C struct bitfields into Go struct fields, even if their size can be
-  represented in Go. The order in which C bitfields appear in memory
-  is implementation dependent, so in some cases the cgo tool produced
-  results that were silently incorrect.
-</p>
-
-<h3 id="vet">Vet</h3>
-
-<h4 id="vet-testing-T">New warning for invalid testing.T use in
-goroutines</h4>
-
-<p><!-- CL 235677 -->
-  The vet tool now warns about invalid calls to the <code>testing.T</code>
-  method <code>Fatal</code> from within a goroutine created during the test.
-  This also warns on calls to <code>Fatalf</code>, <code>FailNow</code>, and
-  <code>Skip{,f,Now}</code> methods on <code>testing.T</code> tests or
-  <code>testing.B</code> benchmarks.
-</p>
-
-<p>
-  Calls to these methods stop the execution of the created goroutine and not
-  the <code>Test*</code> or <code>Benchmark*</code> function. So these are
-  <a href="/pkg/testing/#T.FailNow">required</a> to be called by the goroutine
-  running the test or benchmark function. For example:
-</p>
-
-<pre>
-func TestFoo(t *testing.T) {
-    go func() {
-        if condition() {
-            t.Fatal("oops") // This exits the inner func instead of TestFoo.
-        }
-        ...
-    }()
-}
-</pre>
-
-<p>
-  Code calling <code>t.Fatal</code> (or a similar method) from a created
-  goroutine should be rewritten to signal the test failure using
-  <code>t.Error</code> and exit the goroutine early using an alternative
-  method, such as using a <code>return</code> statement. The previous example
-  could be rewritten as:
-</p>
-
-<pre>
-func TestFoo(t *testing.T) {
-    go func() {
-        if condition() {
-            t.Error("oops")
-            return
-        }
-        ...
-    }()
-}
-</pre>
-
-<h4 id="vet-frame-pointer">New warning for frame pointer</h4>
-
-<p><!-- CL 248686, CL 276372 -->
-  The vet tool now warns about amd64 assembly that clobbers the BP
-  register (the frame pointer) without saving and restoring it,
-  contrary to the calling convention. Code that doesn't preserve the
-  BP register must be modified to either not use BP at all or preserve
-  BP by saving and restoring it. An easy way to preserve BP is to set
-  the frame size to a nonzero value, which causes the generated
-  prologue and epilogue to preserve the BP register for you.
-  See <a href="https://golang.org/cl/248260">CL 248260</a> for example
-  fixes.
-</p>
-
-<h4 id="vet-asn1-unmarshal">New warning for asn1.Unmarshal</h4>
-
-<p><!-- CL 243397 -->
-  The vet tool now warns about incorrectly passing a non-pointer or nil argument to
-  <a href="/pkg/encoding/asn1/#Unmarshal"><code>asn1.Unmarshal</code></a>.
-  This is like the existing checks for
-  <a href="/pkg/encoding/json/#Unmarshal"><code>encoding/json.Unmarshal</code></a>
-  and <a href="/pkg/encoding/xml/#Unmarshal"><code>encoding/xml.Unmarshal</code></a>.
-</p>
-
-<h2 id="runtime">Runtime</h2>
-
-<p>
-  The new <a href="/pkg/runtime/metrics/"><code>runtime/metrics</code></a> package
-  introduces a stable interface for reading
-  implementation-defined metrics from the Go runtime.
-  It supersedes existing functions like
-  <a href="/pkg/runtime/#ReadMemStats"><code>runtime.ReadMemStats</code></a>
-  and
-  <a href="/pkg/runtime/debug/#GCStats"><code>debug.GCStats</code></a>
-  and is significantly more general and efficient.
-  See the package documentation for more details.
-</p>
-
-<p><!-- CL 254659 -->
-  Setting the <code>GODEBUG</code> environment variable
-  to <code>inittrace=1</code> now causes the runtime to emit a single
-  line to standard error for each package <code>init</code>,
-  summarizing its execution time and memory allocation. This trace can
-  be used to find bottlenecks or regressions in Go startup
-  performance.
-  The <a href="/pkg/runtime/#hdr-Environment_Variables"><code>GODEBUG</code>
-  documentation</a> describes the format.
-</p>
-
-<p><!-- CL 267100 -->
-  On Linux, the runtime now defaults to releasing memory to the
-  operating system promptly (using <code>MADV_DONTNEED</code>), rather
-  than lazily when the operating system is under memory pressure
-  (using <code>MADV_FREE</code>). This means process-level memory
-  statistics like RSS will more accurately reflect the amount of
-  physical memory being used by Go processes. Systems that are
-  currently using <code>GODEBUG=madvdontneed=1</code> to improve
-  memory monitoring behavior no longer need to set this environment
-  variable.
-</p>
-
-<p><!-- CL 220419, CL 271987 -->
-  Go 1.16 fixes a discrepancy between the race detector and
-  the <a href="/ref/mem">Go memory model</a>. The race detector now
-  more precisely follows the channel synchronization rules of the
-  memory model. As a result, the detector may now report races it
-  previously missed.
-</p>
-
-<h2 id="compiler">Compiler</h2>
-
-<p><!-- CL 256459, CL 264837, CL 266203, CL 256460 -->
-  The compiler can now inline functions with
-  non-labeled <code>for</code> loops, method values, and type
-  switches. The inliner can also detect more indirect calls where
-  inlining is possible.
-</p>
-
-<h2 id="linker">Linker</h2>
-
-<p><!-- CL 248197 -->
-  This release includes additional improvements to the Go linker,
-  reducing linker resource usage (both time and memory) and improving
-  code robustness/maintainability. These changes form the second half
-  of a two-release project to
-  <a href="https://golang.org/s/better-linker">modernize the Go
-  linker</a>.
-</p>
-
-<p>
-  The linker changes in 1.16 extend the 1.15 improvements to all
-  supported architecture/OS combinations (the 1.15 performance improvements
-  were primarily focused on <code>ELF</code>-based OSes and
-  <code>amd64</code> architectures).  For a representative set of
-  large Go programs, linking is 20-25% faster than 1.15 and requires
-  5-15% less memory on average for <code>linux/amd64</code>, with larger
-  improvements for other architectures and OSes. Most binaries are
-  also smaller as a result of more aggressive symbol pruning.
-</p>
-
-<p><!-- CL 255259 -->
-  On Windows, <code>go build -buildmode=c-shared</code> now generates Windows
-  ASLR DLLs by default. ASLR can be disabled with <code>--ldflags=-aslr=false</code>.
-</p>
-
-<h2 id="library">Core library</h2>
-
-<h3 id="library-embed">Embedded Files</h3>
-
-<p>
-  The new <a href="/pkg/embed/"><code>embed</code></a> package
-  provides access to files embedded in the program during compilation
-  using the new <a href="#embed"><code>//go:embed</code> directive</a>.
-</p>
-
-<h3 id="fs">File Systems</h3>
-
-<p>
-  The new <a href="/pkg/io/fs/"><code>io/fs</code></a> package
-  defines the <a href="/pkg/io/fs/#FS"><code>fs.FS</code></a> interface,
-  an abstraction for read-only trees of files.
-  The standard library packages have been adapted to make use
-  of the interface as appropriate.
-</p>
-
-<p>
-  On the producer side of the interface,
-  the new <a href="/pkg/embed/#FS"><code>embed.FS</code></a> type
-  implements <code>fs.FS</code>, as does
-  <a href="/pkg/archive/zip/#Reader"><code>zip.Reader</code></a>.
-  The new <a href="/pkg/os/#DirFS"><code>os.DirFS</code></a> function
-  provides an implementation of <code>fs.FS</code> backed by a tree
-  of operating system files.
-</p>
-
-<p>
-  On the consumer side,
-  the new <a href="/pkg/net/http/#FS"><code>http.FS</code></a>
-  function converts an <code>fs.FS</code> to an
-  <a href="/pkg/net/http/#FileSystem"><code>http.FileSystem</code></a>.
-  Also, the <a href="/pkg/html/template/"><code>html/template</code></a>
-  and <a href="/pkg/text/template/"><code>text/template</code></a>
-  packages’ <a href="/pkg/html/template/#ParseFS"><code>ParseFS</code></a>
-  functions and methods read templates from an <code>fs.FS</code>.
-</p>
-
-<p>
-  For testing code that implements <code>fs.FS</code>,
-  the new <a href="/pkg/testing/fstest/"><code>testing/fstest</code></a>
-  package provides a <a href="/pkg/testing/fstest/#TestFS"><code>TestFS</code></a>
-  function that checks for and reports common mistakes.
-  It also provides a simple in-memory file system implementation,
-  <a href="/pkg/testing/fstest/#MapFS"><code>MapFS</code></a>,
-  which can be useful for testing code that accepts <code>fs.FS</code>
-  implementations.
-</p>
-
-<h3 id="ioutil">Deprecation of io/ioutil</h3>
-
-<p>
-  The <a href="/pkg/io/ioutil/"><code>io/ioutil</code></a> package has
-  turned out to be a poorly defined and hard to understand collection
-  of things. All functionality provided by the package has been moved
-  to other packages. The <code>io/ioutil</code> package remains and
-  will continue to work as before, but we encourage new code to use
-  the new definitions in the <a href="/pkg/io/"><code>io</code></a> and
-  <a href="/pkg/os/"><code>os</code></a> packages.
-
-  Here is a list of the new locations of the names exported
-  by <code>io/ioutil</code>:
-  <ul>
-    <li><a href="/pkg/io/ioutil/#Discard"><code>Discard</code></a>
-      => <a href="/pkg/io/#Discard"><code>io.Discard</code></a></li>
-    <li><a href="/pkg/io/ioutil/#NopCloser"><code>NopCloser</code></a>
-      => <a href="/pkg/io/#NopCloser"><code>io.NopCloser</code></a></li>
-    <li><a href="/pkg/io/ioutil/#ReadAll"><code>ReadAll</code></a>
-      => <a href="/pkg/io/#ReadAll"><code>io.ReadAll</code></a></li>
-    <li><a href="/pkg/io/ioutil/#ReadDir"><code>ReadDir</code></a>
-      => <a href="/pkg/os/#ReadDir"><code>os.ReadDir</code></a>
-      (note: returns a slice of
-      <a href="/pkg/os/#DirEntry"><code>os.DirEntry</code></a>
-      rather than a slice of
-      <a href="/pkg/fs/#FileInfo"><code>fs.FileInfo</code></a>)
-    </li>
-    <li><a href="/pkg/io/ioutil/#ReadFile"><code>ReadFile</code></a>
-      => <a href="/pkg/os/#ReadFile"><code>os.ReadFile</code></a></li>
-    <li><a href="/pkg/io/ioutil/#TempDir"><code>TempDir</code></a>
-      => <a href="/pkg/os/#MkdirTemp"><code>os.MkdirTemp</code></a></li>
-    <li><a href="/pkg/io/ioutil/#TempFile"><code>TempFile</code></a>
-      => <a href="/pkg/os/#CreateTemp"><code>os.CreateTemp</code></a></li>
-    <li><a href="/pkg/io/ioutil/#WriteFile"><code>WriteFile</code></a>
-      => <a href="/pkg/os/#WriteFile"><code>os.WriteFile</code></a></li>
-  </ul>
-</p>
-
-<!-- okay-after-beta1
-  TODO: decide if any additional changes are worth factoring out from
-  "Minor changes to the library" and highlighting in "Core library"
--->
-
-<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/zip"><dt><a href="/pkg/archive/zip/">archive/zip</a></dt>
-  <dd>
-    <p><!-- CL 243937 -->
-      The new <a href="/pkg/archive/zip/#Reader.Open"><code>Reader.Open</code></a>
-      method implements the <a href="/pkg/io/fs/#FS"><code>fs.FS</code></a>
-      interface.
-    </p>
-  </dd>
-</dl>
-
-<dl id="crypto/dsa"><dt><a href="/pkg/crypto/dsa/">crypto/dsa</a></dt>
-  <dd>
-    <p><!-- CL 257939 -->
-      The <a href="/pkg/crypto/dsa/"><code>crypto/dsa</code></a> package is now deprecated.
-      See <a href="https://golang.org/issue/40337">issue #40337</a>.
-    </p>
-  </dd>
-</dl><!-- crypto/dsa -->
-
-<dl id="crypto/hmac"><dt><a href="/pkg/crypto/hmac/">crypto/hmac</a></dt>
-  <dd>
-    <p><!-- CL 261960 -->
-      <a href="/pkg/crypto/hmac/#New"><code>New</code></a> will now panic if
-      separate calls to the hash generation function fail to return new values.
-      Previously, the behavior was undefined and invalid outputs were sometimes
-      generated.
-    </p>
-  </dd>
-</dl><!-- crypto/hmac -->
-
-<dl id="crypto/tls"><dt><a href="/pkg/crypto/tls/">crypto/tls</a></dt>
-  <dd>
-    <p><!-- CL 256897 -->
-      I/O operations on closing or closed TLS connections can now be detected
-      using the new <a href="/pkg/net/#ErrClosed"><code>net.ErrClosed</code></a>
-      error. A typical use would be <code>errors.Is(err, net.ErrClosed)</code>.
-    </p>
-
-    <p><!-- CL 266037 -->
-      A default write deadline is now set in
-      <a href="/pkg/crypto/tls/#Conn.Close"><code>Conn.Close</code></a>
-      before sending the "close notify" alert, in order to prevent blocking
-      indefinitely.
-    </p>
-
-    <p><!-- CL 239748 -->
-      Clients now return a handshake error if the server selects
-      <a href="/pkg/crypto/tls/#ConnectionState.NegotiatedProtocol">
-      an ALPN protocol</a> that was not in
-      <a href="/pkg/crypto/tls/#Config.NextProtos">
-      the list advertised by the client</a>.
-    </p>
-
-    <p><!-- CL 262857 -->
-      Servers will now prefer other available AEAD cipher suites (such as ChaCha20Poly1305)
-      over AES-GCM cipher suites if either the client or server doesn't have AES hardware
-      support, unless both <a href="/pkg/crypto/tls/#Config.PreferServerCipherSuites">
-      <code>Config.PreferServerCipherSuites</code></a>
-      and <a href="/pkg/crypto/tls/#Config.CipherSuites"><code>Config.CipherSuites</code></a>
-      are set. The client is assumed not to have AES hardware support if it does
-      not signal a preference for AES-GCM cipher suites.
-    </p>
-
-    <p><!-- CL 246637 -->
-      <a href="/pkg/crypto/tls/#Config.Clone"><code>Config.Clone</code></a> now
-      returns nil if the receiver is nil, rather than panicking.
-    </p>
-  </dd>
-</dl><!-- crypto/tls -->
-
-<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
-  <dd>
-    <p>
-      The <code>GODEBUG=x509ignoreCN=0</code> flag will be removed in Go 1.17.
-      It enables the legacy behavior of treating the <code>CommonName</code>
-      field on X.509 certificates as a host name when no Subject Alternative
-      Names are present.
-    </p>
-
-    <p><!-- CL 235078 -->
-      <a href="/pkg/crypto/x509/#ParseCertificate"><code>ParseCertificate</code></a> and
-      <a href="/pkg/crypto/x509/#CreateCertificate"><code>CreateCertificate</code></a>
-      now enforce string encoding restrictions for the <code>DNSNames</code>,
-      <code>EmailAddresses</code>, and <code>URIs</code> fields. These fields
-      can only contain strings with characters within the ASCII range.
-    </p>
-
-    <p><!-- CL 259697 -->
-      <a href="/pkg/crypto/x509/#CreateCertificate"><code>CreateCertificate</code></a>
-      now verifies the generated certificate's signature using the signer's
-      public key. If the signature is invalid, an error is returned, instead of
-      a malformed certificate.
-    </p>
-
-    <p><!-- CL 257939 -->
-      DSA signature verification is no longer supported. Note that DSA signature
-      generation was never supported.
-      See <a href="https://golang.org/issue/40337">issue #40337</a>.
-    </p>
-
-    <p><!-- CL 257257 -->
-      On Windows, <a href="/pkg/crypto/x509/#Certificate.Verify"><code>Certificate.Verify</code></a>
-      will now return all certificate chains that are built by the platform
-      certificate verifier, instead of just the highest ranked chain.
-    </p>
-
-    <p><!-- CL 262343 -->
-      The new <a href="/pkg/crypto/x509/#SystemRootsError.Unwrap"><code>SystemRootsError.Unwrap</code></a>
-      method allows accessing the <a href="/pkg/crypto/x509/#SystemRootsError.Err"><code>Err</code></a>
-      field through the <a href="/pkg/errors"><code>errors</code></a> package functions.
-    </p>
-
-    <p><!-- CL 230025 -->
-      On Unix systems, the <code>crypto/x509</code> package is now more
-      efficient in how it stores its copy of the system cert pool.
-      Programs that use only a small number of roots will use around a
-      half megabyte less memory.
-    </p>
-
-  </dd>
-</dl><!-- crypto/x509 -->
-
-<dl id="debug/elf"><dt><a href="/pkg/debug/elf/">debug/elf</a></dt>
-  <dd>
-    <p><!-- CL 255138 -->
-      More <a href="/pkg/debug/elf/#DT_NULL"><code>DT</code></a>
-      and <a href="/pkg/debug/elf/#PT_NULL"><code>PT</code></a>
-      constants have been added.
-    </p>
-  </dd>
-</dl><!-- debug/elf -->
-
-<dl id="encoding/asn1"><dt><a href="/pkg/encoding/asn1">encoding/asn1</a></dt>
-  <dd>
-    <p><!-- CL 255881 -->
-      <a href="/pkg/encoding/asn1/#Unmarshal"><code>Unmarshal</code></a> and
-      <a href="/pkg/encoding/asn1/#UnmarshalWithParams"><code>UnmarshalWithParams</code></a>
-      now return an error instead of panicking when the argument is not
-      a pointer or is nil. This change matches the behavior of other
-      encoding packages such as <a href="/pkg/encoding/json"><code>encoding/json</code></a>.
-    </p>
-  </dd>
-</dl>
-
-<dl id="encoding/json"><dt><a href="/pkg/encoding/json/">encoding/json</a></dt>
-  <dd>
-    <p><!-- CL 234818 -->
-      The <code>json</code> struct field tags understood by
-      <a href="/pkg/encoding/json/#Marshal"><code>Marshal</code></a>,
-      <a href="/pkg/encoding/json/#Unmarshal"><code>Unmarshal</code></a>,
-      and related functionality now permit semicolon characters within
-      a JSON object name for a Go struct field.
-    </p>
-  </dd>
-</dl><!-- encoding/json -->
-
-<dl id="encoding/xml"><dt><a href="/pkg/encoding/xml/">encoding/xml</a></dt>
-  <dd>
-    <p><!-- CL 264024 -->
-      The encoder has always taken care to avoid using namespace prefixes
-      beginning with <code>xml</code>, which are reserved by the XML
-      specification.
-      Now, following the specification more closely, that check is
-      case-insensitive, so that prefixes beginning
-      with <code>XML</code>, <code>XmL</code>, and so on are also
-      avoided.
-    </p>
-  </dd>
-</dl><!-- encoding/xml -->
-
-<dl id="flag"><dt><a href="/pkg/flag/">flag</a></dt>
-  <dd>
-    <p><!-- CL 240014 -->
-      The new <a href="/pkg/flag/#Func"><code>Func</code></a> function
-      allows registering a flag implemented by calling a function,
-      as a lighter-weight alternative to implementing the
-      <a href="/pkg/flag/#Value"><code>Value</code></a> interface.
-    </p>
-  </dd>
-</dl><!-- flag -->
-
-<dl id="go/build"><dt><a href="/pkg/go/build/">go/build</a></dt>
-  <dd>
-    <p><!-- CL 243941, CL 283636 -->
-      The <a href="/pkg/go/build/#Package"><code>Package</code></a>
-      struct has new fields that report information
-      about <code>//go:embed</code> directives in the package:
-      <a href="/pkg/go/build/#Package.EmbedPatterns"><code>EmbedPatterns</code></a>,
-      <a href="/pkg/go/build/#Package.EmbedPatternPos"><code>EmbedPatternPos</code></a>,
-      <a href="/pkg/go/build/#Package.TestEmbedPatterns"><code>TestEmbedPatterns</code></a>,
-      <a href="/pkg/go/build/#Package.TestEmbedPatternPos"><code>TestEmbedPatternPos</code></a>,
-      <a href="/pkg/go/build/#Package.XTestEmbedPatterns"><code>XTestEmbedPatterns</code></a>,
-      <a href="/pkg/go/build/#Package.XTestEmbedPatternPos"><code>XTestEmbedPatternPos</code></a>.
-    </p>
-
-    <p><!-- CL 240551 -->
-      The <a href="/pkg/go/build/#Package"><code>Package</code></a> field
-      <a href="/pkg/go/build/#Package.IgnoredGoFiles"><code>IgnoredGoFiles</code></a>
-      will no longer include files that start with "_" or ".",
-      as those files are always ignored.
-      <code>IgnoredGoFiles</code> is for files ignored because of
-      build constraints.
-    </p>
-
-    <p><!-- CL 240551 -->
-      The new <a href="/pkg/go/build/#Package"><code>Package</code></a>
-      field <a href="/pkg/go/build/#Package.IgnoredOtherFiles"><code>IgnoredOtherFiles</code></a>
-      has a list of non-Go files ignored because of build constraints.
-    </p>
-  </dd>
-</dl><!-- go/build -->
-
-<dl id="go/build/constraint"><dt><a href="/pkg/go/build/constraint/">go/build/constraint</a></dt>
-  <dd>
-    <p><!-- CL 240604 -->
-      The new
-      <a href="/pkg/go/build/constraint/"><code>go/build/constraint</code></a>
-      package parses build constraint lines, both the original
-      <code>// +build</code> syntax and the <code>//go:build</code>
-      syntax that will be introduced in Go 1.17.
-      This package exists so that tools built with Go 1.16 will be able
-      to process Go 1.17 source code.
-      See <a href="https://golang.org/design/draft-gobuild">https://golang.org/design/draft-gobuild</a>
-      for details about the build constraint syntaxes and the planned
-      transition to the <code>//go:build</code> syntax.
-      Note that <code>//go:build</code> lines are <b>not</b> supported
-      in Go 1.16 and should not be introduced into Go programs yet.
-    </p>
-  </dd>
-</dl><!-- go/build/constraint -->
-
-<dl id="html/template"><dt><a href="/pkg/html/template/">html/template</a></dt>
-  <dd>
-    <p><!-- CL 243938 -->
-      The new <a href="/pkg/html/template/#ParseFS"><code>template.ParseFS</code></a>
-      function and <a href="/pkg/html/template/#Template.ParseFS"><code>template.Template.ParseFS</code></a>
-      method are like <a href="/pkg/html/template/#ParseGlob"><code>template.ParseGlob</code></a>
-      and <a href="/pkg/html/template/#Template.ParseGlob"><code>template.Template.ParseGlob</code></a>,
-      but read the templates from an <a href="/pkg/io/fs/#FS"><code>fs.FS</code></a>.
-    </p>
-  </dd>
-</dl><!-- html/template -->
-
-<dl id="io"><dt><a href="/pkg/io/">io</a></dt>
-  <dd>
-    <p><!-- CL 261577 -->
-      The package now defines a
-      <a href="/pkg/io/#ReadSeekCloser"><code>ReadSeekCloser</code></a> interface.
-    </p>
-
-    <p><!-- CL 263141 -->
-      The package now defines
-      <a href="/pkg/io/#Discard"><code>Discard</code></a>,
-      <a href="/pkg/io/#NopCloser"><code>NopCloser</code></a>, and
-      <a href="/pkg/io/#ReadAll"><code>ReadAll</code></a>,
-      to be used instead of the same names in the
-      <a href="/pkg/io/ioutil/"><code>io/ioutil</code></a> package.
-    </p>
-  </dd>
-</dl><!-- io -->
-
-<dl id="log"><dt><a href="/pkg/log/">log</a></dt>
-  <dd>
-    <p><!-- CL 264460 -->
-      The new <a href="/pkg/log/#Default"><code>Default</code></a> function
-      provides access to the default <a href="/pkg/log/#Logger"><code>Logger</code></a>.
-    </p>
-  </dd>
-</dl><!-- log -->
-
-<dl id="log/syslog"><dt><a href="/pkg/log/syslog/">log/syslog</a></dt>
-  <dd>
-    <p><!-- CL 264297 -->
-      The <a href="/pkg/log/syslog/#Writer"><code>Writer</code></a>
-      now uses the local message format
-      (omitting the host name and using a shorter time stamp)
-      when logging to custom Unix domain sockets,
-      matching the format already used for the default log socket.
-    </p>
-  </dd>
-</dl><!-- log/syslog -->
-
-<dl id="mime/multipart"><dt><a href="/pkg/mime/multipart/">mime/multipart</a></dt>
-  <dd>
-    <p><!-- CL 247477 -->
-      The <a href="/pkg/mime/multipart/#Reader"><code>Reader</code></a>'s
-      <a href="/pkg/mime/multipart/#Reader.ReadForm"><code>ReadForm</code></a>
-      method no longer rejects form data
-      when passed the maximum int64 value as a limit.
-    </p>
-  </dd>
-</dl><!-- mime/multipart -->
-
-<dl id="net"><dt><a href="/pkg/net/">net</a></dt>
-  <dd>
-    <p><!-- CL 250357 -->
-      The case of I/O on a closed network connection, or I/O on a network
-      connection that is closed before any of the I/O completes, can now
-      be detected using the new <a href="/pkg/net/#ErrClosed"><code>ErrClosed</code></a>
-      error. A typical use would be <code>errors.Is(err, net.ErrClosed)</code>.
-      In earlier releases the only way to reliably detect this case was to
-      match the string returned by the <code>Error</code> method
-      with <code>"use of closed network connection"</code>.
-    </p>
-
-    <p><!-- CL 255898 -->
-      In previous Go releases the default TCP listener backlog size on Linux systems,
-      set by <code>/proc/sys/net/core/somaxconn</code>, was limited to a maximum of <code>65535</code>.
-      On Linux kernel version 4.1 and above, the maximum is now <code>4294967295</code>.
-    </p>
-
-    <p><!-- CL 238629 -->
-      On Linux, host name lookups no longer use DNS before checking
-      <code>/etc/hosts</code> when <code>/etc/nsswitch.conf</code>
-      is missing; this is common on musl-based systems and makes
-      Go programs match the behavior of C programs on those systems.
-    </p>
-  </dd>
-</dl><!-- net -->
-
-<dl id="net/http"><dt><a href="/pkg/net/http/">net/http</a></dt>
-  <dd>
-    <p><!-- CL 233637 -->
-      In the <a href="/pkg/net/http/"><code>net/http</code></a> package, the
-      behavior of <a href="/pkg/net/http/#StripPrefix"><code>StripPrefix</code></a>
-      has been changed to strip the prefix from the request URL's
-      <code>RawPath</code> field in addition to its <code>Path</code> field.
-      In past releases, only the <code>Path</code> field was trimmed, and so if the
-      request URL contained any escaped characters the URL would be modified to
-      have mismatched <code>Path</code> and <code>RawPath</code> fields.
-      In Go 1.16, <code>StripPrefix</code> trims both fields.
-      If there are escaped characters in the prefix part of the request URL the
-      handler serves a 404 instead of its previous behavior of invoking the
-      underlying handler with a mismatched <code>Path</code>/<code>RawPath</code> pair.
-    </p>
-
-    <p><!-- CL 252497 -->
-      The <a href="/pkg/net/http/"><code>net/http</code></a> package now rejects HTTP range requests
-      of the form <code>"Range": "bytes=--N"</code> where <code>"-N"</code> is a negative suffix length, for
-      example <code>"Range": "bytes=--2"</code>. It now replies with a <code>416 "Range Not Satisfiable"</code> response.
-    </p>
-
-    <p><!-- CL 256498, golang.org/issue/36990 -->
-      Cookies set with <a href="/pkg/net/http/#SameSiteDefaultMode"><code>SameSiteDefaultMode</code></a>
-      now behave according to the current spec (no attribute is set) instead of
-      generating a SameSite key without a value.
-    </p>
-
-    <p><!-- CL 250039 -->
-      The <a href="/pkg/net/http/#Client"><code>Client</code></a> now sends
-      an explicit <code>Content-Length:</code> <code>0</code>
-      header in <code>PATCH</code> requests with empty bodies,
-      matching the existing behavior of <code>POST</code> and <code>PUT</code>.
-    </p>
-
-    <p><!-- CL 249440 -->
-      The <a href="/pkg/net/http/#ProxyFromEnvironment"><code>ProxyFromEnvironment</code></a>
-      function no longer returns the setting of the <code>HTTP_PROXY</code>
-      environment variable for <code>https://</code> URLs when
-      <code>HTTPS_PROXY</code> is unset.
-    </p>
-
-    <p><!-- 259917 -->
-      The <a href="/pkg/net/http/#Transport"><code>Transport</code></a>
-      type has a new field
-      <a href="/pkg/net/http/#Transport.GetProxyConnectHeader"><code>GetProxyConnectHeader</code></a>
-      which may be set to a function that returns headers to send to a
-      proxy during a <code>CONNECT</code> request.
-      In effect <code>GetProxyConnectHeader</code> is a dynamic
-      version of the existing field
-      <a href="/pkg/net/http/#Transport.ProxyConnectHeader"><code>ProxyConnectHeader</code></a>;
-      if <code>GetProxyConnectHeader</code> is not <code>nil</code>,
-      then <code>ProxyConnectHeader</code> is ignored.
-    </p>
-
-    <p><!-- CL 243939 -->
-      The new <a href="/pkg/net/http/#FS"><code>http.FS</code></a>
-      function converts an <a href="/pkg/io/fs/#FS"><code>fs.FS</code></a>
-      to an <a href="/pkg/net/http/#FileSystem"><code>http.FileSystem</code></a>.
-    </p>
-  </dd>
-</dl><!-- net/http -->
-
-<dl id="net/http/httputil"><dt><a href="/pkg/net/http/httputil/">net/http/httputil</a></dt>
-  <dd>
-    <p><!-- CL 260637 -->
-      <a href="/pkg/net/http/httputil/#ReverseProxy"><code>ReverseProxy</code></a>
-      now flushes buffered data more aggressively when proxying
-      streamed responses with unknown body lengths.
-    </p>
-  </dd>
-</dl><!-- net/http/httputil -->
-
-<dl id="net/smtp"><dt><a href="/pkg/net/smtp/">net/smtp</a></dt>
-  <dd>
-    <p><!-- CL 247257 -->
-      The <a href="/pkg/net/smtp/#Client"><code>Client</code></a>'s
-      <a href="/pkg/net/smtp/#Client.Mail"><code>Mail</code></a>
-      method now sends the <code>SMTPUTF8</code> directive to
-      servers that support it, signaling that addresses are encoded in UTF-8.
-    </p>
-  </dd>
-</dl><!-- net/smtp -->
-
-<dl id="os"><dt><a href="/pkg/os/">os</a></dt>
-  <dd>
-    <p><!-- CL 242998 -->
-      <a href="/pkg/os/#Process.Signal"><code>Process.Signal</code></a> now
-      returns <a href="/pkg/os/#ErrProcessDone"><code>ErrProcessDone</code></a>
-      instead of the unexported <code>errFinished</code> when the process has
-      already finished.
-    </p>
-
-    <p><!-- CL 261540 -->
-      The package defines a new type
-      <a href="/pkg/os/#DirEntry"><code>DirEntry</code></a>
-      as an alias for <a href="/pkg/io/fs/#DirEntry"><code>fs.DirEntry</code></a>.
-      The new <a href="/pkg/os/#ReadDir"><code>ReadDir</code></a>
-      function and the new
-      <a href="/pkg/os/#File.ReadDir"><code>File.ReadDir</code></a>
-      method can be used to read the contents of a directory into a
-      slice of <a href="/pkg/os/#DirEntry"><code>DirEntry</code></a>.
-      The <a href="/pkg/os/#File.Readdir"><code>File.Readdir</code></a>
-      method (note the lower case <code>d</code> in <code>dir</code>)
-      still exists, returning a slice of
-      <a href="/pkg/os/#FileInfo"><code>FileInfo</code></a>, but for
-      most programs it will be more efficient to switch to
-      <a href="/pkg/os/#File.ReadDir"><code>File.ReadDir</code></a>.
-    </p>
-
-    <p><!-- CL 263141 -->
-      The package now defines
-      <a href="/pkg/os/#CreateTemp"><code>CreateTemp</code></a>,
-      <a href="/pkg/os/#MkdirTemp"><code>MkdirTemp</code></a>,
-      <a href="/pkg/os/#ReadFile"><code>ReadFile</code></a>, and
-      <a href="/pkg/os/#WriteFile"><code>WriteFile</code></a>,
-      to be used instead of functions defined in the
-      <a href="/pkg/io/ioutil/"><code>io/ioutil</code></a> package.
-    </p>
-
-    <p><!-- CL 243906 -->
-      The types <a href="/pkg/os/#FileInfo"><code>FileInfo</code></a>,
-      <a href="/pkg/os/#FileMode"><code>FileMode</code></a>, and
-      <a href="/pkg/os/#PathError"><code>PathError</code></a>
-      are now aliases for types of the same name in the
-      <a href="/pkg/io/fs/"><code>io/fs</code></a> package.
-      Function signatures in the <a href="/pkg/os/"><code>os</code></a>
-      package have been updated to refer to the names in the
-      <a href="/pkg/io/fs/"><code>io/fs</code></a> package.
-      This should not affect any existing code.
-    </p>
-
-    <p><!-- CL 243911 -->
-      The new <a href="/pkg/os/#DirFS"><code>DirFS</code></a> function
-      provides an implementation of
-      <a href="/pkg/io/fs/#FS"><code>fs.FS</code></a> backed by a tree
-      of operating system files.
-    </p>
-  </dd>
-</dl><!-- os -->
-
-<dl id="os/signal"><dt><a href="/pkg/os/signal/">os/signal</a></dt>
-  <dd>
-    <p><!-- CL 219640 -->
-      The new
-      <a href="/pkg/os/signal/#NotifyContext"><code>NotifyContext</code></a>
-      function allows creating contexts that are canceled upon arrival of
-      specific signals.
-    </p>
-  </dd>
-</dl><!-- os/signal -->
-
-<dl id="path"><dt><a href="/pkg/path/">path</a></dt>
-  <dd>
-    <p><!-- CL 264397, golang.org/issues/28614 -->
-      The <a href="/pkg/path/#Match"><code>Match</code></a> function now
-      returns an error if the unmatched part of the pattern has a
-      syntax error. Previously, the function returned early on a failed
-      match, and thus did not report any later syntax error in the
-      pattern.
-    </p>
-  </dd>
-</dl><!-- path -->
-
-<dl id="path/filepath"><dt><a href="/pkg/path/filepath/">path/filepath</a></dt>
-  <dd>
-    <p><!-- CL 267887 -->
-      The new function
-      <a href="/pkg/path/filepath/#WalkDir"><code>WalkDir</code></a>
-      is similar to
-      <a href="/pkg/path/filepath/#Walk"><code>Walk</code></a>,
-      but is typically more efficient.
-      The function passed to <code>WalkDir</code> receives a
-      <a href="/pkg/io/fs/#DirEntry"><code>fs.DirEntry</code></a>
-      instead of a
-      <a href="/pkg/io/fs/#FileInfo"><code>fs.FileInfo</code></a>.
-      (To clarify for those who recall the <code>Walk</code> function
-      as taking an <a href="/pkg/os/#FileInfo"><code>os.FileInfo</code></a>,
-      <code>os.FileInfo</code> is now an alias for <code>fs.FileInfo</code>.)
-    </p>
-
-    <p><!-- CL 264397, golang.org/issues/28614 -->
-      The <a href="/pkg/path/filepath#Match"><code>Match</code></a> and
-      <a href="/pkg/path/filepath#Glob"><code>Glob</code></a> functions now
-      return an error if the unmatched part of the pattern has a
-      syntax error. Previously, the functions returned early on a failed
-      match, and thus did not report any later syntax error in the
-      pattern.
-    </p>
-  </dd>
-</dl><!-- path/filepath -->
-
-<dl id="runtime/debug"><dt><a href="/pkg/runtime/debug/">runtime/debug</a></dt>
-  <dd>
-    <p><!-- CL 249677 -->
-      The <a href="/pkg/runtime#Error"><code>runtime.Error</code></a> values
-      used when <code>SetPanicOnFault</code> is enabled may now have an
-      <code>Addr</code> method. If that method exists, it returns the memory
-      address that triggered the fault.
-    </p>
-  </dd>
-</dl><!-- runtime/debug -->
-
-<dl id="strconv"><dt><a href="/pkg/strconv/">strconv</a></dt>
-  <dd>
-    <p><!-- CL 260858 -->
-      <a href="/pkg/strconv/#ParseFloat"><code>ParseFloat</code></a> now uses
-      the <a
-      href="https://nigeltao.github.io/blog/2020/eisel-lemire.html">Eisel-Lemire
-      algorithm</a>, improving performance by up to a factor of 2. This can
-      also speed up decoding textual formats like <a
-      href="/pkg/encoding/json/"><code>encoding/json</code></a>.
-    </p>
-  </dd>
-</dl><!-- strconv -->
-
-<dl id="syscall"><dt><a href="/pkg/syscall/">syscall</a></dt>
-  <dd>
-    <p><!-- CL 263271 -->
-      <a href="/pkg/syscall/?GOOS=windows#NewCallback"><code>NewCallback</code></a>
-      and
-      <a href="/pkg/syscall/?GOOS=windows#NewCallbackCDecl"><code>NewCallbackCDecl</code></a>
-      now correctly support callback functions with multiple
-      sub-<code>uintptr</code>-sized arguments in a row. This may
-      require changing uses of these functions to eliminate manual
-      padding between small arguments.
-    </p>
-
-    <p><!-- CL 261917 -->
-      <a href="/pkg/syscall/?GOOS=windows#SysProcAttr"><code>SysProcAttr</code></a> on Windows has a new <code>NoInheritHandles</code> field that disables inheriting handles when creating a new process.
-    </p>
-
-    <p><!-- CL 269761, golang.org/issue/42584 -->
-      <a href="/pkg/syscall/?GOOS=windows#DLLError"><code>DLLError</code></a> on Windows now has an <code>Unwrap</code> method for unwrapping its underlying error.
-    </p>
-
-    <p><!-- CL 210639 -->
-      On Linux,
-      <a href="/pkg/syscall/#Setgid"><code>Setgid</code></a>,
-      <a href="/pkg/syscall/#Setuid"><code>Setuid</code></a>,
-      and related calls are now implemented.
-      Previously, they returned an <code>syscall.EOPNOTSUPP</code> error.
-    </p>
-
-    <p><!-- CL 210639 -->
-      On Linux, the new functions
-      <a href="/pkg/syscall/#AllThreadsSyscall"><code>AllThreadsSyscall</code></a>
-      and <a href="/pkg/syscall/#AllThreadsSyscall6"><code>AllThreadsSyscall6</code></a>
-      may be used to make a system call on all Go threads in the process.
-      These functions may only be used by programs that do not use cgo;
-      if a program uses cgo, they will always return
-      <a href="/pkg/syscall/#ENOTSUP"><code>syscall.ENOTSUP</code></a>.
-    </p>
-  </dd>
-</dl><!-- syscall -->
-
-<dl id="testing/iotest"><dt><a href="/pkg/testing/iotest/">testing/iotest</a></dt>
-  <dd>
-    <p><!-- CL 199501 -->
-      The new
-      <a href="/pkg/testing/iotest/#ErrReader"><code>ErrReader</code></a>
-      function returns an
-      <a href="/pkg/io/#Reader"><code>io.Reader</code></a> that always
-      returns an error.
-    </p>
-
-    <p><!-- CL 243909 -->
-      The new
-      <a href="/pkg/testing/iotest/#TestReader"><code>TestReader</code></a>
-      function tests that an <a href="/pkg/io/#Reader"><code>io.Reader</code></a>
-      behaves correctly.
-    </p>
-  </dd>
-</dl><!-- testing/iotest -->
-
-<dl id="text/template"><dt><a href="/pkg/text/template/">text/template</a></dt>
-  <dd>
-    <p><!-- CL 254257, golang.org/issue/29770 -->
-      Newlines characters are now allowed inside action delimiters,
-      permitting actions to span multiple lines.
-    </p>
-
-    <p><!-- CL 243938 -->
-      The new <a href="/pkg/text/template/#ParseFS"><code>template.ParseFS</code></a>
-      function and <a href="/pkg/text/template/#Template.ParseFS"><code>template.Template.ParseFS</code></a>
-      method are like <a href="/pkg/text/template/#ParseGlob"><code>template.ParseGlob</code></a>
-      and <a href="/pkg/text/template/#Template.ParseGlob"><code>template.Template.ParseGlob</code></a>,
-      but read the templates from an <a href="/pkg/io/fs/#FS"><code>fs.FS</code></a>.
-    </p>
-  </dd>
-</dl><!-- text/template -->
-
-<dl id="text/template/parse"><dt><a href="/pkg/text/template/parse/">text/template/parse</a></dt>
-  <dd>
-    <p><!-- CL 229398, golang.org/issue/34652 -->
-      A new <a href="/pkg/text/template/parse/#CommentNode"><code>CommentNode</code></a>
-      was added to the parse tree. The <a href="/pkg/text/template/parse/#Mode"><code>Mode</code></a>
-      field in the <code>parse.Tree</code> enables access to it.
-    </p>
-  </dd>
-</dl><!-- text/template/parse -->
-
-<dl id="time/tzdata"><dt><a href="/pkg/time/tzdata/">time/tzdata</a></dt>
-  <dd>
-    <p><!-- CL 261877 -->
-      The slim timezone data format is now used for the timezone database in
-      <code>$GOROOT/lib/time/zoneinfo.zip</code> and the embedded copy in this
-      package. This reduces the size of the timezone database by about 350 KB.
-    </p>
-  </dd>
-</dl><!-- time/tzdata -->
-
-<dl id="unicode"><dt><a href="/pkg/unicode/">unicode</a></dt>
-  <dd>
-    <p><!-- CL 248765 -->
-      The <a href="/pkg/unicode/"><code>unicode</code></a> package and associated
-      support throughout the system has been upgraded from Unicode 12.0.0 to
-      <a href="https://www.unicode.org/versions/Unicode13.0.0/">Unicode 13.0.0</a>,
-      which adds 5,930 new characters, including four new scripts, and 55 new emoji.
-      Unicode 13.0.0 also designates plane 3 (U+30000-U+3FFFF) as the tertiary
-      ideographic plane.
-    </p>
-  </dd>
-</dl><!-- unicode -->
diff --git a/doc/go1.17.html b/doc/go1.17.html
new file mode 100644
index 0000000..c1b5ab3
--- /dev/null
+++ b/doc/go1.17.html
@@ -0,0 +1,1240 @@
+<!--{
+	"Title": "Go 1.17 Release Notes",
+	"Path":  "/doc/go1.17"
+}-->
+
+<!--
+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>
+  main ul li { margin: 0.5em 0; }
+</style>
+
+<h2 id="introduction">Introduction to Go 1.17</h2>
+
+<p>
+  The latest Go release, version 1.17, arrives six months after <a href="/doc/go1.16">Go 1.16</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">promise of compatibility</a>.
+  We expect almost all Go programs to continue to compile and run as before.
+</p>
+
+<h2 id="language">Changes to the language</h2>
+
+<p>
+  Go 1.17 includes three small enhancements to the language.
+</p>
+
+<ul>
+  <li><!-- CL 216424; issue 395 -->
+    <a href="/ref/spec#Conversions_from_slice_to_array_pointer">Conversions
+    from slice to array pointer</a>: An expression <code>s</code> of
+    type <code>[]T</code> may now be converted to array pointer type
+    <code>*[N]T</code>. If <code>a</code> is the result of such a
+    conversion, then corresponding indices that are in range refer to
+    the same underlying elements: <code>&amp;a[i] == &amp;s[i]</code>
+    for <code>0 &lt;= i &lt; N</code>. The conversion panics if
+    <code>len(s)</code> is less than <code>N</code>.
+  </li>
+
+  <li><!-- CL 312212; issue 40481 -->
+    <a href="/pkg/unsafe#Add"><code>unsafe.Add</code></a>:
+    <code>unsafe.Add(ptr, len)</code> adds <code>len</code>
+    to <code>ptr</code> and returns the updated pointer
+    <code>unsafe.Pointer(uintptr(ptr) + uintptr(len))</code>.
+  </li>
+
+  <li><!-- CL 312212; issue 19367 -->
+    <a href="/pkg/unsafe#Slice"><code>unsafe.Slice</code></a>:
+    For expression <code>ptr</code> of type <code>*T</code>,
+    <code>unsafe.Slice(ptr, len)</code> returns a slice of
+    type <code>[]T</code> whose underlying array starts
+    at <code>ptr</code> and whose length and capacity
+    are <code>len</code>.
+  </li>
+</ul>
+
+<p>
+  The package unsafe enhancements were added to simplify writing code that conforms
+  to <code>unsafe.Pointer</code>'s <a href="/pkg/unsafe/#Pointer">safety
+  rules</a>, but the rules remain unchanged. In particular, existing
+  programs that correctly use <code>unsafe.Pointer</code> remain
+  valid, and new programs must still follow the rules when
+  using <code>unsafe.Add</code> or <code>unsafe.Slice</code>.
+</p>
+
+
+<p>
+  Note that the new conversion from slice to array pointer is the
+  first case in which a type conversion can panic at run time.
+  Analysis tools that assume type conversions can never panic
+  should be updated to consider this possibility.
+</p>
+
+<h2 id="ports">Ports</h2>
+
+<h3 id="darwin">Darwin</h3>
+
+<p><!-- golang.org/issue/23011 -->
+  As <a href="go1.16#darwin">announced</a> in the Go 1.16 release
+  notes, Go 1.17 requires macOS 10.13 High Sierra or later; support
+  for previous versions has been discontinued.
+</p>
+
+<h3 id="windows">Windows</h3>
+
+<p><!-- golang.org/issue/36439 -->
+  Go 1.17 adds support of 64-bit ARM architecture on Windows (the
+  <code>windows/arm64</code> port). This port supports cgo.
+</p>
+
+<h3 id="openbsd">OpenBSD</h3>
+
+<p><!-- golang.org/issue/43005 -->
+  The 64-bit MIPS architecture on OpenBSD (the <code>openbsd/mips64</code>
+  port) now supports cgo.
+</p>
+
+<p><!-- golang.org/issue/36435 -->
+  In Go 1.16, on the 64-bit x86 and 64-bit ARM architectures on
+  OpenBSD (the <code>openbsd/amd64</code> and <code>openbsd/arm64</code>
+  ports) system calls are made through <code>libc</code>, instead
+  of directly using machine instructions. In Go 1.17, this is also
+  done on the 32-bit x86 and 32-bit ARM architectures on OpenBSD
+  (the <code>openbsd/386</code> and <code>openbsd/arm</code> ports).
+  This ensures compatibility with OpenBSD 6.9 onwards, which require
+  system calls to be made through <code>libc</code> for non-static
+  Go binaries.
+</p>
+
+<h3 id="arm64">ARM64</h3>
+
+<p><!-- CL 288814 -->
+  Go programs now maintain stack frame pointers on the 64-bit ARM
+  architecture on all operating systems. Previously it maintained
+  stack frame pointers only on Linux, macOS, and iOS.
+</p>
+
+<h3 id="loong64">loong64 GOARCH value reserved</h3>
+
+<p><!-- CL 333909 -->
+  The main Go compiler does not yet support the LoongArch
+  architecture, but we've reserved the <code>GOARCH</code> value
+  "<code>loong64</code>".
+  This means that Go files named <code>*_loong64.go</code> will now
+  be <a href="/pkg/go/build/#hdr-Build_Constraints">ignored by Go
+  tools</a> except when that GOARCH value is being used.
+</p>
+
+<h2 id="tools">Tools</h2>
+
+<h3 id="go-command">Go command</h3>
+
+<a id="lazy-loading"><!-- for existing links only --></a>
+<h4 id="graph-pruning">Pruned module graphs in <code>go 1.17</code> modules</h4>
+
+<p><!-- golang.org/issue/36460 -->
+  If a module specifies <code>go</code> <code>1.17</code> or higher, the module
+  graph includes only the <em>immediate</em> dependencies of
+  other <code>go</code> <code>1.17</code> modules, not their full transitive
+  dependencies. (See <a href="/ref/mod#graph-pruning">Module graph pruning</a>
+  for more detail.)
+</p>
+
+<p>
+  For the <code>go</code> command to correctly resolve transitive imports using
+  the pruned module graph, the <code>go.mod</code> file for each module needs to
+  include more detail about the transitive dependencies relevant to that module.
+  If a module specifies <code>go</code> <code>1.17</code> or higher in its
+  <code>go.mod</code> file, its <code>go.mod</code> file now contains an
+  explicit <a href="/ref/mod#go-mod-file-require"><code>require</code>
+  directive</a> for every module that provides a transitively-imported package.
+  (In previous versions, the <code>go.mod</code> file typically only included
+  explicit requirements for <em>directly</em>-imported packages.)
+<p>
+
+<p>
+  Since the expanded <code>go.mod</code> file needed for module graph pruning
+  includes all of the dependencies needed to load the imports of any package in
+  the main module, if the main module specifies
+  <code>go</code> <code>1.17</code> or higher the <code>go</code> tool no longer
+  reads (or even downloads) <code>go.mod</code> files for dependencies if they
+  are not needed in order to complete the requested command.
+  (See <a href="/ref/mod#lazy-loading">Lazy loading</a>.)
+</p>
+
+<p><!-- golang.org/issue/45965 -->
+  Because the number of explicit requirements may be substantially larger in an
+  expanded Go 1.17 <code>go.mod</code> file, the newly-added requirements
+  on <em>indirect</em> dependencies in a <code>go</code> <code>1.17</code>
+  module are maintained in a separate <code>require</code> block from the block
+  containing direct dependencies.
+</p>
+
+<p><!-- golang.org/issue/45094 -->
+  To facilitate the upgrade to Go 1.17 pruned module graphs, the
+  <a href="/ref/mod#go-mod-tidy"><code>go</code> <code>mod</code> <code>tidy</code></a>
+  subcommand now supports a <code>-go</code> flag to set or change
+  the <code>go</code> version in the <code>go.mod</code> file. To convert
+  the <code>go.mod</code> file for an existing module to Go 1.17 without
+  changing the selected versions of its dependencies, run:
+</p>
+
+<pre>
+  go mod tidy -go=1.17
+</pre>
+
+<p><!-- golang.org/issue/46141 -->
+  By default, <code>go</code> <code>mod</code> <code>tidy</code> verifies that
+  the selected versions of dependencies relevant to the main module are the same
+  versions that would be used by the prior Go release (Go 1.16 for a module that
+  specifies <code>go</code> <code>1.17</code>), and preserves
+  the <code>go.sum</code> entries needed by that release even for dependencies
+  that are not normally needed by other commands.
+</p>
+
+<p>
+  The <code>-compat</code> flag allows that version to be overridden to support
+  older (or only newer) versions, up to the version specified by
+  the <code>go</code> directive in the <code>go.mod</code> file. To tidy
+  a <code>go</code> <code>1.17</code> module for Go 1.17 only, without saving
+  checksums for (or checking for consistency with) Go 1.16:
+</p>
+
+<pre>
+  go mod tidy -compat=1.17
+</pre>
+
+<p>
+  Note that even if the main module is tidied with <code>-compat=1.17</code>,
+  users who <code>require</code> the module from a
+  <code>go</code> <code>1.16</code> or earlier module will still be able to
+  use it, provided that the packages use only compatible language and library
+  features.
+</p>
+
+<p><!-- golang.org/issue/46366 -->
+  The <a href="/ref/mod#go-mod-graph"><code>go</code> <code>mod</code> <code>graph</code></a>
+  subcommand also supports the <code>-go</code> flag, which causes it to report
+  the graph as seen by the indicated Go version, showing dependencies that may
+  otherwise be pruned out.
+</p>
+
+<h4 id="module-deprecation-comments">Module deprecation comments</h4>
+
+<p><!-- golang.org/issue/40357 -->
+  Module authors may deprecate a module by adding a
+  <a href="/ref/mod#go-mod-file-module-deprecation"><code>// Deprecated:</code>
+  comment</a> to <code>go.mod</code>, then tagging a new version.
+  <code>go</code> <code>get</code> now prints a warning if a module needed to
+  build packages named on the command line is deprecated. <code>go</code>
+  <code>list</code> <code>-m</code> <code>-u</code> prints deprecations for all
+  dependencies (use <code>-f</code> or <code>-json</code> to show the full
+  message). The <code>go</code> command considers different major versions to
+  be distinct modules, so this mechanism may be used, for example, to provide
+  users with migration instructions for a new major version.
+</p>
+
+<h4 id="go-get"><code>go</code> <code>get</code></h4>
+
+<p><!-- golang.org/issue/37519 -->
+  The <code>go</code> <code>get</code> <code>-insecure</code> flag is
+  deprecated and has been removed. To permit the use of insecure schemes
+  when fetching dependencies, please use the <code>GOINSECURE</code>
+  environment variable. The <code>-insecure</code> flag also bypassed module
+  sum validation, use <code>GOPRIVATE</code> or <code>GONOSUMDB</code> if
+  you need that functionality. See <code>go</code> <code>help</code>
+  <code>environment</code> for details.
+</p>
+
+<p><!-- golang.org/issue/43684 -->
+  <code>go</code> <code>get</code> prints a deprecation warning when installing
+  commands outside the main module (without the <code>-d</code> flag).
+  <code>go</code> <code>install</code> <code>cmd@version</code> should be used
+  instead to install a command at a specific version, using a suffix like
+  <code>@latest</code> or <code>@v1.2.3</code>. In Go 1.18, the <code>-d</code>
+  flag will always be enabled, and <code>go</code> <code>get</code> will only
+  be used to change dependencies in <code>go.mod</code>.
+</p>
+
+<h4 id="missing-go-directive"><code>go.mod</code> files missing <code>go</code> directives</h4>
+
+<p><!-- golang.org/issue/44976 -->
+  If the main module's <code>go.mod</code> file does not contain
+  a <a href="/doc/modules/gomod-ref#go"><code>go</code> directive</a> and
+  the <code>go</code> command cannot update the <code>go.mod</code> file, the
+  <code>go</code> command now assumes <code>go 1.11</code> instead of the
+  current release. (<code>go</code> <code>mod</code> <code>init</code> has added
+  <code>go</code> directives automatically <a href="/doc/go1.12#modules">since
+  Go 1.12</a>.)
+</p>
+
+<p><!-- golang.org/issue/44976 -->
+  If a module dependency lacks an explicit <code>go.mod</code> file, or
+  its <code>go.mod</code> file does not contain
+  a <a href="/doc/modules/gomod-ref#go"><code>go</code> directive</a>,
+  the <code>go</code> command now assumes <code>go 1.16</code> for that
+  dependency instead of the current release. (Dependencies developed in GOPATH
+  mode may lack a <code>go.mod</code> file, and
+  the <code>vendor/modules.txt</code> has to date never recorded
+  the <code>go</code> versions indicated by dependencies' <code>go.mod</code>
+  files.)
+</p>
+
+<h4 id="vendor"><code>vendor</code> contents</h4>
+
+<p><!-- golang.org/issue/36876 -->
+  If the main module specifies <code>go</code> <code>1.17</code> or higher,
+  <a href="/ref/mod#go-mod-vendor"><code>go</code> <code>mod</code> <code>vendor</code></a>
+  now annotates
+  <code>vendor/modules.txt</code> with the <code>go</code> version indicated by
+  each vendored module in its own <code>go.mod</code> file. The annotated
+  version is used when building the module's packages from vendored source code.
+</p>
+
+<p><!-- golang.org/issue/42970 -->
+  If the main module specifies <code>go</code> <code>1.17</code> or higher,
+  <code>go</code> <code>mod</code> <code>vendor</code> now omits <code>go.mod</code>
+  and <code>go.sum</code> files for vendored dependencies, which can otherwise
+  interfere with the ability of the <code>go</code> command to identify the correct
+  module root when invoked within the <code>vendor</code> tree.
+</p>
+
+<h4 id="password-prompts">Password prompts</h4>
+
+<p><!-- golang.org/issue/44904 -->
+  The <code>go</code> command by default now suppresses SSH password prompts and
+  Git Credential Manager prompts when fetching Git repositories using SSH, as it
+  already did previously for other Git password prompts. Users authenticating to
+  private Git repos with password-protected SSH may configure
+  an <code>ssh-agent</code> to enable the <code>go</code> command to use
+  password-protected SSH keys.
+</p>
+
+<h4 id="go-mod-download"><code>go</code> <code>mod</code> <code>download</code></h4>
+
+<p><!-- golang.org/issue/45332 -->
+  When <code>go</code> <code>mod</code> <code>download</code> is invoked without
+  arguments, it will no longer save sums for downloaded module content to
+  <code>go.sum</code>. It may still make changes to <code>go.mod</code> and
+  <code>go.sum</code> needed to load the build list. This is the same as the
+  behavior in Go 1.15. To save sums for all modules, use <code>go</code>
+  <code>mod</code> <code>download</code> <code>all</code>.
+</p>
+
+<h4 id="build-lines"><code>//go:build</code> lines</h4>
+
+<p>
+  The <code>go</code> command now understands <code>//go:build</code> lines
+  and prefers them over <code>// +build</code> lines. The new syntax uses
+  boolean expressions, just like Go, and should be less error-prone.
+  As of this release, the new syntax is fully supported, and all Go files
+  should be updated to have both forms with the same meaning. To aid in
+  migration, <a href="#gofmt"><code>gofmt</code></a> now automatically
+  synchronizes the two forms. For more details on the syntax and migration plan,
+  see
+  <a href="https://golang.org/design/draft-gobuild">https://golang.org/design/draft-gobuild</a>.
+</p>
+
+<h4 id="go run"><code>go</code> <code>run</code></h4>
+
+<p><!-- golang.org/issue/42088 -->
+  <code>go</code> <code>run</code> now accepts arguments with version suffixes
+  (for example, <code>go</code> <code>run</code>
+  <code>example.com/cmd@v1.0.0</code>).  This causes <code>go</code>
+  <code>run</code> to build and run packages in module-aware mode, ignoring the
+  <code>go.mod</code> file in the current directory or any parent directory, if
+  there is one. This is useful for running executables without installing them or
+  without changing dependencies of the current module.
+</p>
+
+<h3 id="gofmt">Gofmt</h3>
+
+<p>
+  <code>gofmt</code> (and <code>go</code> <code>fmt</code>) now synchronizes
+  <code>//go:build</code> lines with <code>// +build</code> lines. If a file
+  only has <code>// +build</code> lines, they will be moved to the appropriate
+  location in the file, and matching <code>//go:build</code> lines will be
+  added. Otherwise, <code>// +build</code> lines will be overwritten based on
+  any existing <code>//go:build</code> lines. For more information, see
+  <a href="https://golang.org/design/draft-gobuild">https://golang.org/design/draft-gobuild</a>.
+</p>
+
+<h3 id="vet">Vet</h3>
+
+<h4 id="vet-buildtags">New warning for mismatched <code>//go:build</code> and <code>// +build</code> lines</h4>
+
+<p><!-- CL 240609 -->
+  The <code>vet</code> tool now verifies that <code>//go:build</code> and
+  <code>// +build</code> lines are in the correct part of the file and
+  synchronized with each other. If they aren't,
+  <a href="#gofmt"><code>gofmt</code></a> can be used to fix them. For more
+  information, see
+  <a href="https://golang.org/design/draft-gobuild">https://golang.org/design/draft-gobuild</a>.
+</p>
+
+<h4 id="vet-sigchanyzer">New warning for calling <code>signal.Notify</code> on unbuffered channels</h4>
+
+<p><!-- CL 299532 -->
+  The vet tool now warns about calls to <a href="/pkg/os/signal/#Notify">signal.Notify</a>
+  with incoming signals being sent to an unbuffered channel. Using an unbuffered channel
+  risks missing signals sent on them as <code>signal.Notify</code> does not block when
+  sending to a channel. For example:
+</p>
+
+<pre>
+c := make(chan os.Signal)
+// signals are sent on c before the channel is read from.
+// This signal may be dropped as c is unbuffered.
+signal.Notify(c, os.Interrupt)
+</pre>
+
+<p>
+  Users of <code>signal.Notify</code> should use channels with sufficient buffer space to keep up with the
+  expected signal rate.
+</p>
+
+<h4 id="vet-error-stdmethods">New warnings for Is, As and Unwrap methods</h4>
+
+<p><!-- CL 321389 -->
+  The vet tool now warns about methods named <code>As</code>, <code>Is</code> or <code>Unwrap</code>
+  on types implementing the <code>error</code> interface that have a different signature than the
+  one expected by the <code>errors</code> package. The <code>errors.{As,Is,Unwrap}</code> functions
+  expect such methods to implement either <code>Is(error)</code> <code>bool</code>,
+  <code>As(interface{})</code> <code>bool</code>, or <code>Unwrap()</code> <code>error</code>
+  respectively. The functions <code>errors.{As,Is,Unwrap}</code> will ignore methods with the same
+  names but a different signature. For example:
+</p>
+
+<pre>
+type MyError struct { hint string }
+func (m MyError) Error() string { ... } // MyError implements error.
+func (MyError) Is(target interface{}) bool { ... } // target is interface{} instead of error.
+func Foo() bool {
+	x, y := MyError{"A"}, MyError{"B"}
+	return errors.Is(x, y) // returns false as x != y and MyError does not have an `Is(error) bool` function.
+}
+</pre>
+
+<h3 id="cover">Cover</h3>
+
+<p><!-- CL 249759 -->
+  The <code>cover</code> tool now uses an optimized parser
+  from <code>golang.org/x/tools/cover</code>, which may be noticeably faster
+  when parsing large coverage profiles.
+</p>
+
+<h2 id="compiler">Compiler</h2>
+
+<p><!-- golang.org/issue/40724 -->
+  Go 1.17 implements a new way of passing function arguments and results using
+  registers instead of the stack.
+  Benchmarks for a representative set of Go packages and programs show
+  performance improvements of about 5%, and a typical reduction in
+  binary size of about 2%.
+  This is currently enabled for Linux, macOS, and Windows on the
+  64-bit x86 architecture (the <code>linux/amd64</code>,
+  <code>darwin/amd64</code>, and <code>windows/amd64</code> ports).
+</p>
+
+<p>
+  This change does not affect the functionality of any safe Go code
+  and is designed to have no impact on most assembly code.
+  It may affect code that violates
+  the <a href="/pkg/unsafe#Pointer"><code>unsafe.Pointer</code></a>
+  rules when accessing function arguments, or that depends on
+  undocumented behavior involving comparing function code pointers.
+  To maintain compatibility with existing assembly functions, the
+  compiler generates adapter functions that convert between the new
+  register-based calling convention and the previous stack-based
+  calling convention.
+  These adapters are typically invisible to users, except that taking
+  the address of a Go function in assembly code or taking the address
+  of an assembly function in Go code
+  using <code>reflect.ValueOf(fn).Pointer()</code>
+  or <code>unsafe.Pointer</code> will now return the address of the
+  adapter.
+  Code that depends on the value of these code pointers may no longer
+  behave as expected.
+  Adapters also may cause a very small performance overhead in two
+  cases: calling an assembly function indirectly from Go via
+  a <code>func</code> value, and calling Go functions from assembly.
+</p>
+
+<p><!-- CL 304470 -->
+  The format of stack traces from the runtime (printed when an uncaught panic
+  occurs, or when <code>runtime.Stack</code> is called) is improved. Previously,
+  the function arguments were printed as hexadecimal words based on the memory
+  layout. Now each argument in the source code is printed separately, separated
+  by commas. Aggregate-typed (struct, array, string, slice, interface, and complex)
+  arguments are delimited by curly braces. A caveat is that the value of an
+  argument that only lives in a register and is not stored to memory may be
+  inaccurate. Function return values (which were usually inaccurate) are no longer
+  printed.
+</p>
+
+<p><!-- CL 283112, golang.org/issue/28727 -->
+  Functions containing closures can now be inlined.
+  One effect of this change is that a function with a closure may
+  produce a distinct closure code pointer for each place that the
+  function is inlined.
+  Go function values are not directly comparable, but this change
+  could reveal bugs in code that uses <code>reflect</code>
+  or <code>unsafe.Pointer</code> to bypass this language restriction
+  and compare functions by code pointer.
+</p>
+
+<h3 id="link">Linker</h3>
+
+<p><!-- CL 310349 -->
+  When the linker uses external linking mode, which is the default
+  when linking a program that uses cgo, and the linker is invoked
+  with a <code>-I</code> option, the option will now be passed to the
+  external linker as a <code>-Wl,--dynamic-linker</code> option.
+</p>
+
+<h2 id="library">Core library</h2>
+
+<h3 id="runtime/cgo"><a href="/pkg/runtime/cgo">Cgo</a></h3>
+
+<p>
+  The <a href="/pkg/runtime/cgo">runtime/cgo</a> package now provides a
+  new facility that allows to turn any Go values to a safe representation
+  that can be used to pass values between C and Go safely. See
+  <a href="/pkg/runtime/cgo#Handle">runtime/cgo.Handle</a> for more information.
+</p>
+
+<h3 id="semicolons">URL query parsing</h3>
+<!-- CL 325697, CL 326309 -->
+
+<p>
+  The <code>net/url</code> and <code>net/http</code> packages used to accept
+  <code>";"</code> (semicolon) as a setting separator in URL queries, in
+  addition to <code>"&"</code> (ampersand). Now, settings with non-percent-encoded
+  semicolons are rejected and <code>net/http</code> servers will log a warning to
+  <a href="/pkg/net/http#Server.ErrorLog"><code>Server.ErrorLog</code></a>
+  when encountering one in a request URL.
+</p>
+
+<p>
+  For example, before Go 1.17 the <a href="/pkg/net/url#URL.Query"><code>Query</code></a>
+  method of the URL <code>example?a=1;b=2&c=3</code> would have returned
+  <code>map[a:[1] b:[2] c:[3]]</code>, while now it returns <code>map[c:[3]]</code>.
+</p>
+
+<p>
+  When encountering such a query string,
+  <a href="/pkg/net/url#URL.Query"><code>URL.Query</code></a>
+  and
+  <a href="/pkg/net/http#Request.FormValue"><code>Request.FormValue</code></a>
+  ignore any settings that contain a semicolon,
+  <a href="/pkg/net/url#ParseQuery"><code>ParseQuery</code></a>
+  returns the remaining settings and an error, and
+  <a href="/pkg/net/http#Request.ParseForm"><code>Request.ParseForm</code></a>
+  and
+  <a href="/pkg/net/http#Request.ParseMultipartForm"><code>Request.ParseMultipartForm</code></a>
+  return an error but still set <code>Request</code> fields based on the
+  remaining settings.
+</p>
+
+<p>
+  <code>net/http</code> users can restore the original behavior by using the new
+  <a href="/pkg/net/http#AllowQuerySemicolons"><code>AllowQuerySemicolons</code></a>
+  handler wrapper. This will also suppress the <code>ErrorLog</code> warning.
+  Note that accepting semicolons as query separators can lead to security issues
+  if different systems interpret cache keys differently.
+  See <a href="https://golang.org/issue/25192">issue 25192</a> for more information.
+</p>
+
+<h3 id="ALPN">TLS strict ALPN</h3>
+<!-- CL 289209, CL 325432 -->
+
+<p>
+  When <a href="/pkg/crypto/tls#Config.NextProtos"><code>Config.NextProtos</code></a>
+  is set, servers now enforce that there is an overlap between the configured
+  protocols and the ALPN protocols advertised by the client, if any. If there is
+  no mutually supported protocol, the connection is closed with the
+  <code>no_application_protocol</code> alert, as required by RFC 7301. This
+  helps mitigate <a href="https://alpaca-attack.com/">the ALPACA cross-protocol attack</a>.
+</p>
+
+<p>
+  As an exception, when the value <code>"h2"</code> is included in the server's
+  <code>Config.NextProtos</code>, HTTP/1.1 clients will be allowed to connect as
+  if they didn't support ALPN.
+  See <a href="https://golang.org/issue/46310">issue 46310</a> for more information.
+</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/zip"><dt><a href="/pkg/archive/zip/">archive/zip</a></dt>
+  <dd>
+    <p><!-- CL 312310 -->
+      The new methods <a href="/pkg/archive/zip#File.OpenRaw"><code>File.OpenRaw</code></a>, <a href="/pkg/archive/zip#Writer.CreateRaw"><code>Writer.CreateRaw</code></a>, <a href="/pkg/archive/zip#Writer.Copy"><code>Writer.Copy</code></a> provide support for cases where performance is a primary concern.
+    </p>
+  </dd>
+</dl><!-- archive/zip -->
+
+<dl id="bufio"><dt><a href="/pkg/bufio/">bufio</a></dt>
+  <dd>
+    <p><!-- CL 280492 -->
+      The <a href="/pkg/bufio/#Writer.WriteRune"><code>Writer.WriteRune</code></a> method
+      now writes the replacement character U+FFFD for negative rune values,
+      as it does for other invalid runes.
+    </p>
+  </dd>
+</dl><!-- bufio -->
+
+<dl id="bytes"><dt><a href="/pkg/bytes/">bytes</a></dt>
+  <dd>
+    <p><!-- CL 280492 -->
+      The <a href="/pkg/bytes/#Buffer.WriteRune"><code>Buffer.WriteRune</code></a> method
+      now writes the replacement character U+FFFD for negative rune values,
+      as it does for other invalid runes.
+    </p>
+  </dd>
+</dl><!-- bytes -->
+
+<dl id="compress/lzw"><dt><a href="/pkg/compress/lzw/">compress/lzw</a></dt>
+  <dd>
+    <p><!-- CL 273667 -->
+      The <a href="/pkg/compress/lzw/#NewReader"><code>NewReader</code></a>
+      function is guaranteed to return a value of the new
+      type <a href="/pkg/compress/lzw/#Reader"><code>Reader</code></a>,
+      and similarly <a href="/pkg/compress/lzw/#NewWriter"><code>NewWriter</code></a>
+      is guaranteed to return a value of the new
+      type <a href="/pkg/compress/lzw/#Writer"><code>Writer</code></a>.
+      These new types both implement a <code>Reset</code> method
+      (<a href="/pkg/compress/lzw/#Reader.Reset"><code>Reader.Reset</code></a>,
+      <a href="/pkg/compress/lzw/#Writer.Reset"><code>Writer.Reset</code></a>)
+      that allows reuse of the <code>Reader</code> or <code>Writer</code>.
+    </p>
+  </dd>
+</dl><!-- compress/lzw -->
+
+<dl id="crypto/ed25519"><dt><a href="/pkg/crypto/ed25519/">crypto/ed25519</a></dt>
+  <dd>
+    <p><!-- CL 276272 -->
+      The <code>crypto/ed25519</code> package has been rewritten, and all
+      operations are now approximately twice as fast on amd64 and arm64.
+      The observable behavior has not otherwise changed.
+    </p>
+  </dd>
+</dl><!-- crypto/ed25519 -->
+
+<dl id="crypto/elliptic"><dt><a href="/pkg/crypto/elliptic/">crypto/elliptic</a></dt>
+  <dd>
+    <p><!-- CL 233939 -->
+      <a href="/pkg/crypto/elliptic#CurveParams"><code>CurveParams</code></a>
+      methods now automatically invoke faster and safer dedicated
+      implementations for known curves (P-224, P-256, and P-521) when
+      available. Note that this is a best-effort approach and applications
+      should avoid using the generic, not constant-time <code>CurveParams</code>
+      methods and instead use dedicated
+      <a href="/pkg/crypto/elliptic#Curve"><code>Curve</code></a> implementations
+      such as <a href="/pkg/crypto/elliptic#P256"><code>P256</code></a>.
+    </p>
+
+    <p><!-- CL 315271, CL 315274 -->
+      The <a href="/pkg/crypto/elliptic#P521"><code>P521</code></a> curve
+      implementation has been rewritten using code generated by the
+      <a href="https://github.com/mit-plv/fiat-crypto">fiat-crypto project</a>,
+      which is based on a formally-verified model of the arithmetic
+      operations. It is now constant-time and three times faster on amd64 and
+      arm64. The observable behavior has not otherwise changed.
+    </p>
+  </dd>
+</dl><!-- crypto/elliptic -->
+
+<dl id="crypto/rand"><dt><a href="/pkg/crypto/rand/">crypto/rand</a></dt>
+  <dd>
+    <p><!-- CL 302489, CL 299134, CL 269999 -->
+      The <code>crypto/rand</code> package now uses the <code>getentropy</code>
+      syscall on macOS and the <code>getrandom</code> syscall on Solaris,
+      Illumos, and DragonFlyBSD.
+    </p>
+  </dd>
+</dl><!-- crypto/rand -->
+
+<dl id="crypto/tls"><dt><a href="/pkg/crypto/tls/">crypto/tls</a></dt>
+  <dd>
+    <p><!-- CL 295370 -->
+      The new <a href="/pkg/crypto/tls#Conn.HandshakeContext"><code>Conn.HandshakeContext</code></a>
+      method allows the user to control cancellation of an in-progress TLS
+      handshake. The provided context is accessible from various callbacks through the new
+      <a href="/pkg/crypto/tls#ClientHelloInfo.Context"><code>ClientHelloInfo.Context</code></a> and
+      <a href="/pkg/crypto/tls#CertificateRequestInfo.Context"><code>CertificateRequestInfo.Context</code></a>
+      methods. Canceling the context after the handshake has finished has no effect.
+    </p>
+
+    <p><!-- CL 314609 -->
+      Cipher suite ordering is now handled entirely by the
+      <code>crypto/tls</code> package. Currently, cipher suites are sorted based
+      on their security, performance, and hardware support taking into account
+      both the local and peer's hardware. The order of the
+      <a href="/pkg/crypto/tls#Config.CipherSuites"><code>Config.CipherSuites</code></a>
+      field is now ignored, as well as the
+      <a href="/pkg/crypto/tls#Config.PreferServerCipherSuites"><code>Config.PreferServerCipherSuites</code></a>
+      field. Note that <code>Config.CipherSuites</code> still allows
+      applications to choose what TLS 1.0–1.2 cipher suites to enable.
+    </p>
+
+    <p>
+      The 3DES cipher suites have been moved to
+      <a href="/pkg/crypto/tls#InsecureCipherSuites"><code>InsecureCipherSuites</code></a>
+      due to <a href="https://sweet32.info/">fundamental block size-related
+      weakness</a>. They are still enabled by default but only as a last resort,
+      thanks to the cipher suite ordering change above.
+    </p>
+
+    <p><!-- golang.org/issue/45428 -->
+      Beginning in the next release, Go 1.18, the
+      <a href="/pkg/crypto/tls/#Config.MinVersion"><code>Config.MinVersion</code></a>
+      for <code>crypto/tls</code> clients will default to TLS 1.2, disabling TLS 1.0
+      and TLS 1.1 by default. Applications will be able to override the change by
+      explicitly setting <code>Config.MinVersion</code>.
+      This will not affect <code>crypto/tls</code> servers.
+    </p>
+  </dd>
+</dl><!-- crypto/tls -->
+
+<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
+  <dd>
+    <p><!-- CL 224157 -->
+      <a href="/pkg/crypto/x509/#CreateCertificate"><code>CreateCertificate</code></a>
+      now returns an error if the provided private key doesn't match the
+      parent's public key, if any. The resulting certificate would have failed
+      to verify.
+    </p>
+
+    <p><!-- CL 315209 -->
+      The temporary <code>GODEBUG=x509ignoreCN=0</code> flag has been removed.
+    </p>
+
+    <p><!-- CL 274234 -->
+      <a href="/pkg/crypto/x509/#ParseCertificate"><code>ParseCertificate</code></a>
+      has been rewritten, and now consumes ~70% fewer resources. The observable
+      behavior has not otherwise changed, except for error messages.
+    </p>
+
+    <p><!-- CL 321190 -->
+      On BSD systems, <code>/etc/ssl/certs</code> is now searched for trusted
+      roots. This adds support for the new system trusted certificate store in
+      FreeBSD 12.2+.
+    </p>
+
+    <p><!-- golang.org/issue/41682 -->
+      Beginning in the next release, Go 1.18, <code>crypto/x509</code> will
+      reject certificates signed with the SHA-1 hash function. This doesn't
+      apply to self-signed root certificates. Practical attacks against SHA-1
+      <a href="https://shattered.io/">have been demonstrated in 2017</a> and publicly
+      trusted Certificate Authorities have not issued SHA-1 certificates since 2015.
+    </p>
+  </dd>
+</dl><!-- crypto/x509 -->
+
+<dl id="database/sql"><dt><a href="/pkg/database/sql/">database/sql</a></dt>
+  <dd>
+    <p><!-- CL 258360 -->
+      The <a href="/pkg/database/sql/#DB.Close"><code>DB.Close</code></a> method now closes
+      the <code>connector</code> field if the type in this field implements the
+      <a href="/pkg/io/#Closer"><code>io.Closer</code></a> interface.
+    </p>
+
+    <p><!-- CL 311572 -->
+      The new
+      <a href="/pkg/database/sql/#NullInt16"><code>NullInt16</code></a>
+      and
+      <a href="/pkg/database/sql/#NullByte"><code>NullByte</code></a>
+      structs represent the int16 and byte values that may be null. These can be used as
+      destinations of the <a href="/pkg/database/sql/#Scan"><code>Scan</code></a> method,
+      similar to NullString.
+    </p>
+  </dd>
+</dl><!-- database/sql -->
+
+<dl id="debug/elf"><dt><a href="/pkg/debug/elf/">debug/elf</a></dt>
+  <dd>
+    <p><!-- CL 239217 -->
+      The <a href="/pkg/debug/elf/#SHT_MIPS_ABIFLAGS"><code>SHT_MIPS_ABIFLAGS</code></a>
+      constant has been added.
+    </p>
+  </dd>
+</dl><!-- debug/elf -->
+
+<dl id="encoding/binary"><dt><a href="/pkg/encoding/binary/">encoding/binary</a></dt>
+  <dd>
+    <p><!-- CL 299531 -->
+      <code>binary.Uvarint</code> will stop reading after <code>10 bytes</code> to avoid
+      wasted computations. If more than <code>10 bytes</code> are needed, the byte count returned is <code>-11</code>.
+      <br />
+      Previous Go versions could return larger negative counts when reading incorrectly encoded varints.
+    </p>
+  </dd>
+</dl><!-- encoding/binary -->
+
+<dl id="encoding/csv"><dt><a href="/pkg/encoding/csv/">encoding/csv</a></dt>
+  <dd>
+    <p><!-- CL 291290 -->
+      The new
+      <a href="/pkg/encoding/csv/#Reader.FieldPos"><code>Reader.FieldPos</code></a>
+      method returns the line and column corresponding to the start of
+      a given field in the record most recently returned by
+      <a href="/pkg/encoding/csv/#Reader.Read"><code>Read</code></a>.
+    </p>
+  </dd>
+</dl><!-- encoding/csv -->
+
+<dl id="encoding/xml"><dt><a href="/pkg/encoding/xml/">encoding/xml</a></dt>
+  <dd>
+    <p><!-- CL 277893 -->
+      When a comment appears within a
+      <a href="/pkg/encoding/xml/#Directive"><code>Directive</code></a>, it is now replaced
+      with a single space instead of being completely elided.
+    </p>
+
+    <p>
+      Invalid element or attribute names with leading, trailing, or multiple
+      colons are now stored unmodified into the
+      <a href="/pkg/encoding/xml/#Name"><code>Name.Local</code></a> field.
+    </p>
+  </dd>
+</dl><!-- encoding/xml -->
+
+<dl id="flag"><dt><a href="/pkg/flag/">flag</a></dt>
+  <dd>
+    <p><!-- CL 271788 -->
+      Flag declarations now panic if an invalid name is specified.
+    </p>
+  </dd>
+</dl><!-- flag -->
+
+<dl id="go/build"><dt><a href="/pkg/go/build/">go/build</a></dt>
+  <dd>
+    <p><!-- CL 310732 -->
+      The new
+      <a href="/pkg/go/build/#Context.ToolTags"><code>Context.ToolTags</code></a>
+      field holds the build tags appropriate to the current Go
+      toolchain configuration.
+    </p>
+  </dd>
+</dl><!-- go/build -->
+
+<dl id="go/format"><dt><a href="/pkg/go/format/">go/format</a></dt>
+  <dd>
+    <p>
+      The <a href="/pkg/go/format/#Source"><code>Source</code></a> and
+      <a href="/pkg/go/format/#Node"><code>Node</code></a> functions now
+      synchronize <code>//go:build</code> lines with <code>// +build</code>
+      lines. If a file only has <code>// +build</code> lines, they will be
+      moved to the appropriate location in the file, and matching
+      <code>//go:build</code> lines will be added. Otherwise,
+      <code>// +build</code> lines will be overwritten based on any existing
+      <code>//go:build</code> lines. For more information, see
+      <a href="https://golang.org/design/draft-gobuild">https://golang.org/design/draft-gobuild</a>.
+    </p>
+  </dd>
+</dl><!-- go/format -->
+
+<dl id="go/parser"><dt><a href="/pkg/go/parser/">go/parser</a></dt>
+  <dd>
+    <p><!-- CL 306149 -->
+      The new <a href="/pkg/go/parser/#SkipObjectResolution"><code>SkipObjectResolution</code></a>
+      <code>Mode</code> value instructs the parser not to resolve identifiers to
+      their declaration. This may improve parsing speed.
+    </p>
+  </dd>
+</dl><!-- go/parser -->
+
+<dl id="image"><dt><a href="/pkg/image/">image</a></dt>
+  <dd>
+    <p><!-- CL 311129 -->
+      The concrete image types (<code>RGBA</code>, <code>Gray16</code> and so on)
+      now implement a new <a href="/pkg/image/#RGBA64Image"><code>RGBA64Image</code></a>
+      interface. The concrete types that previously implemented
+      <a href="/pkg/image/draw/#Image"><code>draw.Image</code></a> now also implement
+      <a href="/pkg/image/draw/#RGBA64Image"><code>draw.RGBA64Image</code></a>, a
+      new interface in the <code>image/draw</code> package.
+    </p>
+  </dd>
+</dl><!-- image -->
+
+<dl id="io/fs"><dt><a href="/pkg/io/fs/">io/fs</a></dt>
+  <dd>
+    <p><!-- CL 293649 -->
+      The new <a href="/pkg/io/fs/#FileInfoToDirEntry"><code>FileInfoToDirEntry</code></a> function converts a <code>FileInfo</code> to a <code>DirEntry</code>.
+    </p>
+  </dd>
+</dl><!-- io/fs -->
+
+<dl id="math"><dt><a href="/pkg/math/">math</a></dt>
+  <dd>
+    <p><!-- CL 247058 -->
+      The math package now defines three more constants: <code>MaxUint</code>, <code>MaxInt</code> and <code>MinInt</code>.
+      For 32-bit systems their values are <code>2^32 - 1</code>, <code>2^31 - 1</code> and <code>-2^31</code>, respectively.
+      For 64-bit systems their values are <code>2^64 - 1</code>, <code>2^63 - 1</code> and <code>-2^63</code>, respectively.
+    </p>
+  </dd>
+</dl><!-- math -->
+
+<dl id="mime"><dt><a href="/pkg/mime/">mime</a></dt>
+  <dd>
+    <p><!-- CL 305230 -->
+      On Unix systems, the table of MIME types is now read from the local system's
+      <a href="https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-0.21.html">Shared MIME-info Database</a>
+      when available.
+    </p>
+  </dd>
+</dl><!-- mime -->
+
+<dl id="mime/multipart"><dt><a href="/pkg/mime/multipart/">mime/multipart</a></dt>
+  <dd>
+    <p><!-- CL 313809 -->
+      <a href="/pkg/mime/multipart/#Part.FileName"><code>Part.FileName</code></a>
+      now applies
+      <a href="/pkg/path/filepath/#Base"><code>filepath.Base</code></a> to the
+      return value. This mitigates potential path traversal vulnerabilities in
+      applications that accept multipart messages, such as <code>net/http</code>
+      servers that call
+      <a href="/pkg/net/http/#Request.FormFile"><code>Request.FormFile</code></a>.
+    </p>
+  </dd>
+</dl><!-- mime/multipart -->
+
+<dl id="net"><dt><a href="/pkg/net/">net</a></dt>
+  <dd>
+    <p><!-- CL 272668 -->
+      The new method <a href="/pkg/net/#IP.IsPrivate"><code>IP.IsPrivate</code></a> reports whether an address is
+      a private IPv4 address according to <a href="https://datatracker.ietf.org/doc/rfc1918">RFC 1918</a>
+      or a local IPv6 address according <a href="https://datatracker.ietf.org/doc/rfc4193">RFC 4193</a>.
+    </p>
+
+    <p><!-- CL 301709 -->
+      The Go DNS resolver now only sends one DNS query when resolving an address for an IPv4-only or IPv6-only network,
+      rather than querying for both address families.
+    </p>
+
+    <p><!-- CL 307030 -->
+      The <a href="/pkg/net/#ErrClosed"><code>ErrClosed</code></a> sentinel error and
+      <a href="/pkg/net/#ParseError"><code>ParseError</code></a> error type now implement
+      the <a href="/pkg/net/#Error"><code>net.Error</code></a> interface.
+    </p>
+
+    <p><!-- CL 325829 -->
+      The <a href="/pkg/net/#ParseIP"><code>ParseIP</code></a> and <a href="/pkg/net/#ParseCIDR"><code>ParseCIDR</code></a>
+      functions now reject IPv4 addresses which contain decimal components with leading zeros.
+
+      These components were always interpreted as decimal, but some operating systems treat them as octal.
+      This mismatch could hypothetically lead to security issues if a Go application was used to validate IP addresses
+      which were then used in their original form with non-Go applications which interpreted components as octal. Generally,
+      it is advisable to always re-encode values after validation, which avoids this class of parser misalignment issues.
+    </p>
+  </dd>
+</dl><!-- net -->
+
+<dl id="net/http"><dt><a href="/pkg/net/http/">net/http</a></dt>
+  <dd>
+    <p><!-- CL 295370 -->
+      The <a href="/pkg/net/http/"><code>net/http</code></a> package now uses the new
+      <a href="/pkg/crypto/tls#Conn.HandshakeContext"><code>(*tls.Conn).HandshakeContext</code></a>
+      with the <a href="/pkg/net/http/#Request"><code>Request</code></a> context
+      when performing TLS handshakes in the client or server.
+    </p>
+
+    <p><!-- CL 235437 -->
+      Setting the <a href="/pkg/net/http/#Server"><code>Server</code></a>
+      <code>ReadTimeout</code> or <code>WriteTimeout</code> fields to a negative value now indicates no timeout
+      rather than an immediate timeout.
+    </p>
+
+    <p><!-- CL 308952 -->
+      The <a href="/pkg/net/http/#ReadRequest"><code>ReadRequest</code></a> function
+      now returns an error when the request has multiple Host headers.
+    </p>
+
+    <p><!-- CL 313950 -->
+      When producing a redirect to the cleaned version of a URL,
+      <a href="/pkg/net/http/#ServeMux"><code>ServeMux</code></a> now always
+      uses relative URLs in the <code>Location</code> header. Previously it
+      would echo the full URL of the request, which could lead to unintended
+      redirects if the client could be made to send an absolute request URL.
+    </p>
+
+    <p><!-- CL 308009, CL 313489 -->
+      When interpreting certain HTTP headers handled by <code>net/http</code>,
+      non-ASCII characters are now ignored or rejected.
+    </p>
+
+    <p><!-- CL 325697 -->
+      If
+      <a href="/pkg/net/http/#Request.ParseForm"><code>Request.ParseForm</code></a>
+      returns an error when called by
+      <a href="/pkg/net/http/#Request.ParseMultipartForm"><code>Request.ParseMultipartForm</code></a>,
+      the latter now continues populating
+      <a href="/pkg/net/http/#Request.MultipartForm"><code>Request.MultipartForm</code></a>
+      before returning it.
+    </p>
+  </dd>
+</dl><!-- net/http -->
+
+<dl id="net/http/httptest"><dt><a href="/pkg/net/http/httptest/">net/http/httptest</a></dt>
+  <dd>
+    <p><!-- CL 308950 -->
+      <a href="/pkg/net/http/httptest/#ResponseRecorder.WriteHeader"><code>ResponseRecorder.WriteHeader</code></a>
+      now panics when the provided code is not a valid three-digit HTTP status code.
+      This matches the behavior of <a href="/pkg/net/http/#ResponseWriter"><code>ResponseWriter</code></a>
+      implementations in the <a href="/pkg/net/http/"><code>net/http</code></a> package.
+    </p>
+  </dd>
+</dl><!-- net/http/httptest -->
+
+<dl id="net/url"><dt><a href="/pkg/net/url/">net/url</a></dt>
+  <dd>
+    <p><!-- CL 314850 -->
+      The new method <a href="/pkg/net/url/#Values.Has"><code>Values.Has</code></a>
+      reports whether a query parameter is set.
+    </p>
+  </dd>
+</dl><!-- net/url -->
+
+<dl id="os"><dt><a href="/pkg/os/">os</a></dt>
+  <dd>
+    <p><!-- CL 268020 -->
+      The <a href="/pkg/os/#File.WriteString"><code>File.WriteString</code></a> method
+      has been optimized to not make a copy of the input string.
+    </p>
+  </dd>
+</dl><!-- os -->
+
+<dl id="reflect"><dt><a href="/pkg/reflect/">reflect</a></dt>
+  <dd>
+    <p><!-- CL 334669 -->
+      The new
+      <a href="/pkg/reflect/#Value.CanConvert"><code>Value.CanConvert</code></a>
+      method reports whether a value can be converted to a type.
+      This may be used to avoid a panic when converting a slice to an
+      array pointer type if the slice is too short.
+      Previously it was sufficient to use
+      <a href="/pkg/reflect/#Type.ConvertibleTo"><code>Type.ConvertibleTo</code></a>
+      for this, but the newly permitted conversion from slice to array
+      pointer type can panic even if the types are convertible.
+    </p>
+
+    <p><!-- CL 266197 -->
+      The new
+      <a href="/pkg/reflect/#StructField.IsExported"><code>StructField.IsExported</code></a>
+      and
+      <a href="/pkg/reflect/#Method.IsExported"><code>Method.IsExported</code></a>
+      methods report whether a struct field or type method is exported.
+      They provide a more readable alternative to checking whether <code>PkgPath</code>
+      is empty.
+    </p>
+
+    <p><!-- CL 281233 -->
+      The new <a href="/pkg/reflect/#VisibleFields"><code>VisibleFields</code></a> function
+      returns all the visible fields in a struct type, including fields inside anonymous struct members.
+    </p>
+
+    <p><!-- CL 284136 -->
+      The <a href="/pkg/reflect/#ArrayOf"><code>ArrayOf</code></a> function now panics when
+      called with a negative length.
+    </p>
+
+    <p><!-- CL 301652 -->
+      Checking the <a href="/pkg/reflect/#Type"><code>Type.ConvertibleTo</code></a> method
+      is no longer sufficient to guarantee that a call to
+      <a href="/pkg/reflect/#Value.Convert"><code>Value.Convert</code></a> will not panic.
+      It may panic when converting `[]T` to `*[N]T` if the slice's length is less than N.
+      See the <a href="#language">language changes</a> section above.
+    </p>
+  </dd>
+</dl><!-- reflect -->
+
+<dl id="runtime/metrics"><dt><a href="/pkg/runtime/metrics">runtime/metrics</a></dt>
+  <dd>
+    <p><!-- CL 308933, CL 312431, CL 312909 -->
+      New metrics were added that track total bytes and objects allocated and freed.
+      A new metric tracking the distribution of goroutine scheduling latencies was
+      also added.
+    </p>
+  </dd>
+</dl><!-- runtime/metrics -->
+
+<dl id="runtime/pprof"><dt><a href="/pkg/runtime/pprof">runtime/pprof</a></dt>
+  <dd>
+    <p><!-- CL 299991 -->
+      Block profiles are no longer biased to favor infrequent long events over
+      frequent short events.
+    </p>
+  </dd>
+</dl><!-- runtime/pprof -->
+
+<dl id="strconv"><dt><a href="/pkg/strconv/">strconv</a></dt>
+  <dd>
+    <p><!-- CL 170079, CL 170080 -->
+      The <code>strconv</code> package now uses Ulf Adams's Ryū algorithm for formatting floating-point numbers.
+      This algorithm improves performance on most inputs and is more than 99% faster on worst-case inputs.
+    </p>
+
+    <p><!-- CL 314775 -->
+      The new <a href="/pkg/strconv/#QuotedPrefix"><code>QuotedPrefix</code></a> function
+      returns the quoted string (as understood by
+      <a href="/pkg/strconv/#Unquote"><code>Unquote</code></a>)
+      at the start of input.
+    </p>
+  </dd>
+</dl><!-- strconv -->
+
+<dl id="strings"><dt><a href="/pkg/strings/">strings</a></dt>
+  <dd>
+    <p><!-- CL 280492 -->
+      The <a href="/pkg/strings/#Builder.WriteRune"><code>Builder.WriteRune</code></a> method
+      now writes the replacement character U+FFFD for negative rune values,
+      as it does for other invalid runes.
+    </p>
+  </dd>
+</dl><!-- strings -->
+
+<dl id="sync/atomic"><dt><a href="/pkg/sync/atomic/">sync/atomic</a></dt>
+  <dd>
+    <p><!-- CL 241678 -->
+      <code>atomic.Value</code> now has <a href="/pkg/sync/atomic/#Value.Swap"><code>Swap</code></a> and
+      <a href="/pkg/sync/atomic/#Value.CompareAndSwap"><code>CompareAndSwap</code></a> methods that provide
+      additional atomic operations.
+    </p>
+  </dd>
+</dl><!-- sync/atomic -->
+
+<dl id="syscall"><dt><a href="/pkg/syscall/">syscall</a></dt>
+  <dd>
+    <p><!-- CL 295371 -->
+    <p>
+      The <a href="/pkg/syscall/#GetQueuedCompletionStatus"><code>GetQueuedCompletionStatus</code></a> and
+      <a href="/pkg/syscall/#PostQueuedCompletionStatus"><code>PostQueuedCompletionStatus</code></a>
+      functions are now deprecated. These functions have incorrect signatures and are superseded by
+      equivalents in the <a href="https://godoc.org/golang.org/x/sys/windows"><code>golang.org/x/sys/windows</code></a> package.
+    </p>
+
+    <p><!-- CL 313653 -->
+      On Unix-like systems, the process group of a child process is now set with signals blocked.
+      This avoids sending a <code>SIGTTOU</code> to the child when the parent is in a background process group.
+    </p>
+
+    <p><!-- CL 288298, CL 288300 -->
+      The Windows version of
+      <a href="/pkg/syscall/#SysProcAttr"><code>SysProcAttr</code></a>
+      has two new fields. <code>AdditionalInheritedHandles</code> is
+      a list of additional handles to be inherited by the new child
+      process. <code>ParentProcess</code> permits specifying the
+      parent process of the new process.
+
+    <p><!-- CL 311570 -->
+      The constant <code>MSG_CMSG_CLOEXEC</code> is now defined on
+      DragonFly and all OpenBSD systems (it was already defined on
+      some OpenBSD systems and all FreeBSD, NetBSD, and Linux systems).
+    </p>
+
+    <p><!-- CL 315281 -->
+      The constants <code>SYS_WAIT6</code> and <code>WEXITED</code>
+      are now defined on NetBSD systems (<code>SYS_WAIT6</code> was
+      already defined on DragonFly and FreeBSD systems;
+      <code>WEXITED</code> was already defined on Darwin, DragonFly,
+      FreeBSD, Linux, and Solaris systems).
+    </p>
+  </dd>
+</dl><!-- syscall -->
+
+<dl id="testing"><dt><a href="/pkg/testing/">testing</a></dt>
+  <dd>
+    <p><!-- CL 310033 -->
+      Added a new <a href="/cmd/go/#hdr-Testing_flags">testing flag</a> <code>-shuffle</code> which controls the execution order of tests and benchmarks.
+    </p>
+    <p><!-- CL 260577 -->
+      The new
+      <a href="/pkg/testing/#T.Setenv"><code>T.Setenv</code></a>
+      and <a href="/pkg/testing/#B.Setenv"><code>B.Setenv</code></a>
+      methods support setting an environment variable for the duration
+      of the test or benchmark.
+    </p>
+  </dd>
+</dl><!-- testing -->
+
+<dl id="text/template/parse"><dt><a href="/pkg/text/template/parse/">text/template/parse</a></dt>
+  <dd>
+    <p><!-- CL 301493 -->
+      The new <a href="/pkg/text/template/parse/#Mode"><code>SkipFuncCheck</code></a> <a href=><code>Mode</code></a>
+      value changes the template parser to not verify that functions are defined.
+    </p>
+  </dd>
+</dl><!-- text/template/parse -->
+
+<dl id="time"><dt><a href="/pkg/time/">time</a></dt>
+  <dd>
+    <p><!-- CL 260858 -->
+      The <a href="/pkg/time/#Time"><code>Time</code></a> type now has a
+      <a href="/pkg/time/#Time.GoString"><code>GoString</code></a> method that
+      will return a more useful value for times when printed with the
+      <code>%#v</code> format specifier in the <code>fmt</code> package.
+    </p>
+
+    <p><!-- CL 264077 -->
+      The new <a href="/pkg/time/#Time.IsDST"><code>Time.IsDST</code></a> method can be used to check whether the time
+      is in Daylight Savings Time in its configured location.
+    </p>
+
+    <p><!-- CL 293349 -->
+      The new <a href="/pkg/time/#Time.UnixMilli"><code>Time.UnixMilli</code></a> and
+      <a href="/pkg/time/#Time.UnixMicro"><code>Time.UnixMicro</code></a>
+      methods return the number of milliseconds and microseconds elapsed since
+      January 1, 1970 UTC respectively.
+      <br />
+      The new <a href="/pkg/time/#UnixMilli"><code>UnixMilli</code></a> and
+      <a href="/pkg/time/#UnixMicro"><code>UnixMicro</code></a> functions
+      return the local <code>Time</code> corresponding to the given Unix time.
+    </p>
+
+    <p><!-- CL 300996 -->
+      The package now accepts comma "," as a separator for fractional seconds when parsing and formatting time.
+      For example, the following time layouts are now accepted:
+      <ul>
+        <li>2006-01-02 15:04:05,999999999 -0700 MST</li>
+        <li>Mon Jan _2 15:04:05,000000 2006</li>
+        <li>Monday, January 2 15:04:05,000 2006</li>
+      </ul>
+    </p>
+
+    <p><!-- CL 320252 -->
+      The new constant <a href="/pkg/time/#Layout"><code>Layout</code></a>
+      defines the reference time.
+    </p>
+  </dd>
+</dl><!-- time -->
+
+<dl id="unicode"><dt><a href="/pkg/unicode/">unicode</a></dt>
+  <dd>
+    <p><!-- CL 280493 -->
+      The <a href="/pkg/unicode/#Is"><code>Is</code></a>,
+      <a href="/pkg/unicode/#IsGraphic"><code>IsGraphic</code></a>,
+      <a href="/pkg/unicode/#IsLetter"><code>IsLetter</code></a>,
+      <a href="/pkg/unicode/#IsLower"><code>IsLower</code></a>,
+      <a href="/pkg/unicode/#IsMark"><code>IsMark</code></a>,
+      <a href="/pkg/unicode/#IsNumber"><code>IsNumber</code></a>,
+      <a href="/pkg/unicode/#IsPrint"><code>IsPrint</code></a>,
+      <a href="/pkg/unicode/#IsPunct"><code>IsPunct</code></a>,
+      <a href="/pkg/unicode/#IsSpace"><code>IsSpace</code></a>,
+      <a href="/pkg/unicode/#IsSymbol"><code>IsSymbol</code></a>, and
+      <a href="/pkg/unicode/#IsUpper"><code>IsUpper</code></a> functions
+      now return <code>false</code> on negative rune values, as they do for other invalid runes.
+    </p>
+  </dd>
+</dl><!-- unicode -->
diff --git a/doc/go_spec.html b/doc/go_spec.html
index 59c9ce3..fd5fee4 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
 <!--{
 	"Title": "The Go Programming Language Specification",
-	"Subtitle": "Version of Feb 10, 2021",
+	"Subtitle": "Version of Jul 26, 2021",
 	"Path": "/ref/spec"
 }-->
 
@@ -490,8 +490,8 @@
 \n   U+000A line feed or newline
 \r   U+000D carriage return
 \t   U+0009 horizontal tab
-\v   U+000b vertical tab
-\\   U+005c backslash
+\v   U+000B vertical tab
+\\   U+005C backslash
 \'   U+0027 single quote  (valid escape only within rune literals)
 \"   U+0022 double quote  (valid escape only within string literals)
 </pre>
@@ -830,7 +830,7 @@
 
 <h3 id="Method_sets">Method sets</h3>
 <p>
-A type may have a <i>method set</i> associated with it.
+A type has a (possibly empty) <i>method set</i> associated with it.
 The method set of an <a href="#Interface_types">interface type</a> is its interface.
 The method set of any other type <code>T</code> consists of all
 <a href="#Method_declarations">methods</a> declared with receiver type <code>T</code>.
@@ -3532,9 +3532,9 @@
 </p>
 
 <p>
-If the final argument is assignable to a slice type <code>[]T</code>, it is
-passed unchanged as the value for a <code>...T</code> parameter if the argument
-is followed by <code>...</code>. In this case no new slice is created.
+If the final argument is assignable to a slice type <code>[]T</code> and
+is followed by <code>...</code>, it is passed unchanged as the value
+for a <code>...T</code> parameter. In this case no new slice is created.
 </p>
 
 <p>
@@ -3681,8 +3681,8 @@
 ^    bitwise XOR            integers
 &amp;^   bit clear (AND NOT)    integers
 
-&lt;&lt;   left shift             integer &lt;&lt; unsigned integer
-&gt;&gt;   right shift            integer &gt;&gt; unsigned integer
+&lt;&lt;   left shift             integer &lt;&lt; integer &gt;= 0
+&gt;&gt;   right shift            integer &gt;&gt; integer &gt;= 0
 </pre>
 
 
@@ -4164,6 +4164,10 @@
 	<li>
 	<code>x</code> is a string and <code>T</code> is a slice of bytes or runes.
 	</li>
+	<li>
+	<code>x</code> is a slice, <code>T</code> is a pointer to an array,
+	and the slice and array types have <a href="#Type_identity">identical</a> element types.
+	</li>
 </ul>
 
 <p>
@@ -4314,6 +4318,28 @@
 </li>
 </ol>
 
+<h4 id="Conversions_from_slice_to_array_pointer">Conversions from slice to array pointer</h4>
+
+<p>
+Converting a slice to an array pointer yields a pointer to the underlying array of the slice.
+If the <a href="#Length_and_capacity">length</a> of the slice is less than the length of the array,
+a <a href="#Run_time_panics">run-time panic</a> occurs.
+</p>
+
+<pre>
+s := make([]byte, 2, 4)
+s0 := (*[0]byte)(s)      // s0 != nil
+s1 := (*[1]byte)(s[1:])  // &amp;s1[0] == &amp;s[1]
+s2 := (*[2]byte)(s)      // &amp;s2[0] == &amp;s[0]
+s4 := (*[4]byte)(s)      // panics: len([4]byte) > len(s)
+
+var t []string
+t0 := (*[0]string)(t)    // t0 == nil
+t1 := (*[1]string)(t)    // panics: len([1]string) > len(t)
+
+u := make([]byte, 0)
+u0 = (*[0]byte)(u)       // u0 != nil
+</pre>
 
 <h3 id="Constant_expressions">Constant expressions</h3>
 
@@ -4648,7 +4674,7 @@
 
 <pre>
 append cap complex imag len make new real
-unsafe.Alignof unsafe.Offsetof unsafe.Sizeof
+unsafe.Add unsafe.Alignof unsafe.Offsetof unsafe.Sizeof unsafe.Slice
 </pre>
 
 <pre>
@@ -4887,7 +4913,7 @@
 
 <p>
 "Switch" statements provide multi-way execution.
-An expression or type specifier is compared to the "cases"
+An expression or type is compared to the "cases"
 inside the "switch" to determine which branch
 to execute.
 </p>
@@ -4931,9 +4957,9 @@
 
 <p>
 If the switch expression evaluates to an untyped constant, it is first implicitly
-<a href="#Conversions">converted</a> to its <a href="#Constants">default type</a>;
-if it is an untyped boolean value, it is first implicitly converted to type <code>bool</code>.
+<a href="#Conversions">converted</a> to its <a href="#Constants">default type</a>.
 The predeclared untyped value <code>nil</code> cannot be used as a switch expression.
+The switch expression type must be <a href="#Comparison_operators">comparable</a>.
 </p>
 
 <p>
@@ -4998,7 +5024,7 @@
 A type switch compares types rather than values. It is otherwise similar
 to an expression switch. It is marked by a special switch expression that
 has the form of a <a href="#Type_assertions">type assertion</a>
-using the reserved word <code>type</code> rather than an actual type:
+using the keyword <code>type</code> rather than an actual type:
 </p>
 
 <pre>
@@ -6689,6 +6715,10 @@
 func Alignof(variable ArbitraryType) uintptr
 func Offsetof(selector ArbitraryType) uintptr
 func Sizeof(variable ArbitraryType) uintptr
+
+type IntegerType int  // shorthand for an integer type; it is not a real type
+func Add(ptr Pointer, len IntegerType) Pointer
+func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
 </pre>
 
 <p>
@@ -6745,6 +6775,40 @@
 <code>Sizeof</code> are compile-time constant expressions of type <code>uintptr</code>.
 </p>
 
+<p>
+The function <code>Add</code> adds <code>len</code> to <code>ptr</code>
+and returns the updated pointer <code>unsafe.Pointer(uintptr(ptr) + uintptr(len))</code>.
+The <code>len</code> argument must be of integer type or an untyped <a href="#Constants">constant</a>.
+A constant <code>len</code> argument must be <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>.
+The rules for <a href="/pkg/unsafe#Pointer">valid uses</a> of <code>Pointer</code> still apply.
+</p>
+
+<p>
+The function <code>Slice</code> returns a slice whose underlying array starts at <code>ptr</code>
+and whose length and capacity are <code>len</code>.
+<code>Slice(ptr, len)</code> is equivalent to
+</p>
+
+<pre>
+(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:]
+</pre>
+
+<p>
+except that, as a special case, if <code>ptr</code>
+is <code>nil</code> and <code>len</code> is zero,
+<code>Slice</code> returns <code>nil</code>.
+</p>
+
+<p>
+The <code>len</code> argument must be of integer type or an untyped <a href="#Constants">constant</a>.
+A constant <code>len</code> 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>.
+At run time, if <code>len</code> is negative,
+or if <code>ptr</code> is <code>nil</code> and <code>len</code> is not zero,
+a <a href="#Run_time_panics">run-time panic</a> occurs.
+</p>
+
 <h3 id="Size_and_alignment_guarantees">Size and alignment guarantees</h3>
 
 <p>
diff --git a/favicon.ico b/favicon.ico
deleted file mode 100644
index 8d22584..0000000
--- a/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/misc/android/go_android_exec.go b/misc/android/go_android_exec.go
index 7aa7fe5..3af2bee 100644
--- a/misc/android/go_android_exec.go
+++ b/misc/android/go_android_exec.go
@@ -14,7 +14,6 @@
 	"fmt"
 	"go/build"
 	"io"
-	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
@@ -276,7 +275,7 @@
 	if err := syscall.Flock(int(stat.Fd()), syscall.LOCK_EX); err != nil {
 		return err
 	}
-	s, err := ioutil.ReadAll(stat)
+	s, err := io.ReadAll(stat)
 	if err != nil {
 		return err
 	}
@@ -294,7 +293,7 @@
 	goroot := runtime.GOROOT()
 	// Build go for android.
 	goCmd := filepath.Join(goroot, "bin", "go")
-	tmpGo, err := ioutil.TempFile("", "go_android_exec-cmd-go-*")
+	tmpGo, err := os.CreateTemp("", "go_android_exec-cmd-go-*")
 	if err != nil {
 		return err
 	}
diff --git a/misc/cgo/errors/argposition_test.go b/misc/cgo/errors/argposition_test.go
new file mode 100644
index 0000000..331095f
--- /dev/null
+++ b/misc/cgo/errors/argposition_test.go
@@ -0,0 +1,134 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 42580: cmd/cgo: shifting identifier position in ast
+
+package errorstest
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/token"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+type ShortPosition struct {
+	Line    int
+	Column  int
+	Visited bool
+}
+
+type IdentPositionInfo map[string][]ShortPosition
+
+type Visitor struct {
+	identPosInfo IdentPositionInfo
+	fset         *token.FileSet
+	t            *testing.T
+}
+
+func (v *Visitor) Visit(node ast.Node) ast.Visitor {
+	if ident, ok := node.(*ast.Ident); ok {
+		if expectedPositions, ok := v.identPosInfo[ident.Name]; ok {
+			gotMatch := false
+			var errorMessage strings.Builder
+			for caseIndex, expectedPos := range expectedPositions {
+				actualPosition := v.fset.PositionFor(ident.Pos(), true)
+				errorOccured := false
+				if expectedPos.Line != actualPosition.Line {
+					fmt.Fprintf(&errorMessage, "wrong line number for ident %s: expected: %d got: %d\n", ident.Name, expectedPos.Line, actualPosition.Line)
+					errorOccured = true
+				}
+				if expectedPos.Column != actualPosition.Column {
+					fmt.Fprintf(&errorMessage, "wrong column number for ident %s: expected: %d got: %d\n", ident.Name, expectedPos.Column, actualPosition.Column)
+					errorOccured = true
+				}
+				if errorOccured {
+					continue
+				}
+				gotMatch = true
+				expectedPositions[caseIndex].Visited = true
+			}
+
+			if !gotMatch {
+				v.t.Errorf(errorMessage.String())
+			}
+		}
+	}
+	return v
+}
+
+func TestArgumentsPositions(t *testing.T) {
+	testdata, err := filepath.Abs("testdata")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	tmpPath := t.TempDir()
+
+	dir := filepath.Join(tmpPath, "src", "testpositions")
+	if err := os.MkdirAll(dir, 0755); err != nil {
+		t.Fatal(err)
+	}
+
+	cmd := exec.Command("go", "tool", "cgo",
+		"-srcdir", testdata,
+		"-objdir", dir,
+		"issue42580.go")
+	cmd.Stderr = new(bytes.Buffer)
+
+	err = cmd.Run()
+	if err != nil {
+		t.Fatalf("%s: %v\n%s", cmd, err, cmd.Stderr)
+	}
+	mainProcessed, err := ioutil.ReadFile(filepath.Join(dir, "issue42580.cgo1.go"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	fset := token.NewFileSet()
+	f, err := parser.ParseFile(fset, "", mainProcessed, parser.AllErrors)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+
+	expectation := IdentPositionInfo{
+		"checkedPointer": []ShortPosition{
+			ShortPosition{
+				Line:   32,
+				Column: 56,
+			},
+		},
+		"singleInnerPointerChecked": []ShortPosition{
+			ShortPosition{
+				Line:   37,
+				Column: 91,
+			},
+		},
+		"doublePointerChecked": []ShortPosition{
+			ShortPosition{
+				Line:   42,
+				Column: 91,
+			},
+		},
+	}
+	for _, decl := range f.Decls {
+		if fdecl, ok := decl.(*ast.FuncDecl); ok {
+			ast.Walk(&Visitor{expectation, fset, t}, fdecl.Body)
+		}
+	}
+	for ident, positions := range expectation {
+		for _, position := range positions {
+			if !position.Visited {
+				t.Errorf("Position %d:%d missed for %s ident", position.Line, position.Column, ident)
+			}
+		}
+	}
+}
diff --git a/misc/cgo/errors/badsym_test.go b/misc/cgo/errors/badsym_test.go
index b2701bf..fc68756 100644
--- a/misc/cgo/errors/badsym_test.go
+++ b/misc/cgo/errors/badsym_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"bytes"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -55,7 +54,7 @@
 
 	makeFile := func(mdir, base, source string) string {
 		ret := filepath.Join(mdir, base)
-		if err := ioutil.WriteFile(ret, []byte(source), 0644); err != nil {
+		if err := os.WriteFile(ret, []byte(source), 0644); err != nil {
 			t.Fatal(err)
 		}
 		return ret
@@ -100,7 +99,7 @@
 	// _cgo_import.go.
 
 	rewrite := func(from, to string) {
-		obj, err := ioutil.ReadFile(from)
+		obj, err := os.ReadFile(from)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -115,7 +114,7 @@
 
 		obj = bytes.ReplaceAll(obj, []byte(magicInput), []byte(magicReplace))
 
-		if err := ioutil.WriteFile(to, obj, 0644); err != nil {
+		if err := os.WriteFile(to, obj, 0644); err != nil {
 			t.Fatal(err)
 		}
 	}
diff --git a/misc/cgo/errors/errors_test.go b/misc/cgo/errors/errors_test.go
index 1bdf843..68a30a4 100644
--- a/misc/cgo/errors/errors_test.go
+++ b/misc/cgo/errors/errors_test.go
@@ -7,7 +7,6 @@
 import (
 	"bytes"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -25,7 +24,7 @@
 	t.Run(file, func(t *testing.T) {
 		t.Parallel()
 
-		contents, err := ioutil.ReadFile(path(file))
+		contents, err := os.ReadFile(path(file))
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -41,7 +40,8 @@
 			if len(frags) == 1 {
 				continue
 			}
-			re, err := regexp.Compile(string(frags[1]))
+			frag := fmt.Sprintf(":%d:.*%s", i+1, frags[1])
+			re, err := regexp.Compile(frag)
 			if err != nil {
 				t.Errorf("Invalid regexp after `ERROR HERE: `: %#q", frags[1])
 				continue
@@ -56,7 +56,7 @@
 }
 
 func expect(t *testing.T, file string, errors []*regexp.Regexp) {
-	dir, err := ioutil.TempDir("", filepath.Base(t.Name()))
+	dir, err := os.MkdirTemp("", filepath.Base(t.Name()))
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/misc/cgo/errors/ptr_test.go b/misc/cgo/errors/ptr_test.go
index 4a46b60..0f39dc8 100644
--- a/misc/cgo/errors/ptr_test.go
+++ b/misc/cgo/errors/ptr_test.go
@@ -10,7 +10,6 @@
 	"bytes"
 	"flag"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -463,7 +462,7 @@
 		gopath = *tmp
 		dir = ""
 	} else {
-		d, err := ioutil.TempDir("", filepath.Base(t.Name()))
+		d, err := os.MkdirTemp("", filepath.Base(t.Name()))
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -475,7 +474,7 @@
 	if err := os.MkdirAll(src, 0777); err != nil {
 		t.Fatal(err)
 	}
-	if err := ioutil.WriteFile(filepath.Join(src, "go.mod"), []byte("module ptrtest"), 0666); err != nil {
+	if err := os.WriteFile(filepath.Join(src, "go.mod"), []byte("module ptrtest"), 0666); err != nil {
 		t.Fatal(err)
 	}
 
@@ -535,10 +534,10 @@
 	fmt.Fprintf(&cgo1, "}\n\n")
 	fmt.Fprintf(&cgo1, "%s\n", ptrTestMain)
 
-	if err := ioutil.WriteFile(filepath.Join(src, "cgo1.go"), cgo1.Bytes(), 0666); err != nil {
+	if err := os.WriteFile(filepath.Join(src, "cgo1.go"), cgo1.Bytes(), 0666); err != nil {
 		t.Fatal(err)
 	}
-	if err := ioutil.WriteFile(filepath.Join(src, "cgo2.go"), cgo2.Bytes(), 0666); err != nil {
+	if err := os.WriteFile(filepath.Join(src, "cgo2.go"), cgo2.Bytes(), 0666); err != nil {
 		t.Fatal(err)
 	}
 
diff --git a/misc/cgo/errors/testdata/err2.go b/misc/cgo/errors/testdata/err2.go
index 1d22401..a90598f 100644
--- a/misc/cgo/errors/testdata/err2.go
+++ b/misc/cgo/errors/testdata/err2.go
@@ -40,15 +40,15 @@
 	C.foop = x // ERROR HERE
 
 	// issue 13129: used to output error about C.unsignedshort with CC=clang
-	var x C.ushort
-	x = int(0) // ERROR HERE: C\.ushort
+	var x1 C.ushort
+	x1 = int(0) // ERROR HERE: C\.ushort
 
 	// issue 13423
 	_ = C.fopen() // ERROR HERE
 
 	// issue 13467
-	var x rune = '✈'
-	var _ rune = C.transform(x) // ERROR HERE: C\.int
+	var x2 rune = '✈'
+	var _ rune = C.transform(x2) // ERROR HERE: C\.int
 
 	// issue 13635: used to output error about C.unsignedchar.
 	// This test tests all such types.
@@ -91,10 +91,10 @@
 
 	// issue 26745
 	_ = func(i int) int {
-		return C.i + 1 // ERROR HERE: :13
+		return C.i + 1 // ERROR HERE: 14
 	}
 	_ = func(i int) {
-		C.fi(i) // ERROR HERE: :6
+		C.fi(i) // ERROR HERE: 7
 	}
 
 	C.fi = C.fi // ERROR HERE
diff --git a/misc/cgo/errors/testdata/issue42580.go b/misc/cgo/errors/testdata/issue42580.go
new file mode 100644
index 0000000..aba80df
--- /dev/null
+++ b/misc/cgo/errors/testdata/issue42580.go
@@ -0,0 +1,44 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 42580: cmd/cgo: shifting identifier position in ast
+
+package cgotest
+
+// typedef int (*intFunc) ();
+//
+// char* strarg = "";
+//
+// int func_with_char(char* arg, void* dummy)
+// {return 5;}
+//
+// int* get_arr(char* arg, void* dummy)
+// {return NULL;}
+import "C"
+import "unsafe"
+
+// Test variables
+var (
+	checkedPointer            = []byte{1}
+	doublePointerChecked      = []byte{1}
+	singleInnerPointerChecked = []byte{1}
+)
+
+// This test checks the positions of variable identifiers.
+// Changing the positions of the test variables idents after this point will break the test.
+
+func TestSingleArgumentCast() C.int {
+	retcode := C.func_with_char((*C.char)(unsafe.Pointer(&checkedPointer[0])), unsafe.Pointer(C.strarg))
+	return retcode
+}
+
+func TestSingleArgumentCastRecFuncAsSimpleArg() C.int {
+	retcode := C.func_with_char((*C.char)(unsafe.Pointer(C.get_arr((*C.char)(unsafe.Pointer(&singleInnerPointerChecked[0])), unsafe.Pointer(C.strarg)))), nil)
+	return retcode
+}
+
+func TestSingleArgumentCastRecFunc() C.int {
+	retcode := C.func_with_char((*C.char)(unsafe.Pointer(C.get_arr((*C.char)(unsafe.Pointer(&doublePointerChecked[0])), unsafe.Pointer(C.strarg)))), unsafe.Pointer(C.strarg))
+	return retcode
+}
diff --git a/misc/cgo/life/life_test.go b/misc/cgo/life/life_test.go
index 3c95d87..0becb26 100644
--- a/misc/cgo/life/life_test.go
+++ b/misc/cgo/life/life_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"bytes"
-	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
@@ -21,7 +20,7 @@
 }
 
 func testMain(m *testing.M) int {
-	GOPATH, err := ioutil.TempDir("", "cgolife")
+	GOPATH, err := os.MkdirTemp("", "cgolife")
 	if err != nil {
 		log.Panic(err)
 	}
@@ -38,7 +37,7 @@
 		log.Panic(err)
 	}
 	os.Setenv("PWD", modRoot)
-	if err := ioutil.WriteFile("go.mod", []byte("module cgolife\n"), 0666); err != nil {
+	if err := os.WriteFile("go.mod", []byte("module cgolife\n"), 0666); err != nil {
 		log.Panic(err)
 	}
 
diff --git a/misc/cgo/stdio/stdio_test.go b/misc/cgo/stdio/stdio_test.go
index ab5d328..675418f 100644
--- a/misc/cgo/stdio/stdio_test.go
+++ b/misc/cgo/stdio/stdio_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"bytes"
-	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
@@ -21,7 +20,7 @@
 }
 
 func testMain(m *testing.M) int {
-	GOPATH, err := ioutil.TempDir("", "cgostdio")
+	GOPATH, err := os.MkdirTemp("", "cgostdio")
 	if err != nil {
 		log.Panic(err)
 	}
@@ -38,7 +37,7 @@
 		log.Panic(err)
 	}
 	os.Setenv("PWD", modRoot)
-	if err := ioutil.WriteFile("go.mod", []byte("module cgostdio\n"), 0666); err != nil {
+	if err := os.WriteFile("go.mod", []byte("module cgostdio\n"), 0666); err != nil {
 		log.Panic(err)
 	}
 
diff --git a/misc/cgo/test/callback.go b/misc/cgo/test/callback.go
index 814888e..08dd9b3 100644
--- a/misc/cgo/test/callback.go
+++ b/misc/cgo/test/callback.go
@@ -182,7 +182,7 @@
 		"runtime.cgocallbackg1",
 		"runtime.cgocallbackg",
 		"runtime.cgocallback",
-		"runtime.asmcgocall",
+		"runtime.systemstack_switch",
 		"runtime.cgocall",
 		"test._Cfunc_callback",
 		"test.nestedCall.func1",
diff --git a/misc/cgo/test/cgo_test.go b/misc/cgo/test/cgo_test.go
index f7a76d0..143f23f 100644
--- a/misc/cgo/test/cgo_test.go
+++ b/misc/cgo/test/cgo_test.go
@@ -59,6 +59,7 @@
 func Test30065(t *testing.T)                 { test30065(t) }
 func Test32579(t *testing.T)                 { test32579(t) }
 func Test31891(t *testing.T)                 { test31891(t) }
+func Test45451(t *testing.T)                 { test45451(t) }
 func TestAlign(t *testing.T)                 { testAlign(t) }
 func TestAtol(t *testing.T)                  { testAtol(t) }
 func TestBlocking(t *testing.T)              { testBlocking(t) }
@@ -80,6 +81,7 @@
 func TestCastToEnum(t *testing.T)            { testCastToEnum(t) }
 func TestErrno(t *testing.T)                 { testErrno(t) }
 func TestFpVar(t *testing.T)                 { testFpVar(t) }
+func TestHandle(t *testing.T)                { testHandle(t) }
 func TestHelpers(t *testing.T)               { testHelpers(t) }
 func TestLibgcc(t *testing.T)                { testLibgcc(t) }
 func TestMultipleAssign(t *testing.T)        { testMultipleAssign(t) }
diff --git a/misc/cgo/test/issue1435.go b/misc/cgo/test/issue1435.go
index a1c7cac..92c6b99 100644
--- a/misc/cgo/test/issue1435.go
+++ b/misc/cgo/test/issue1435.go
@@ -8,7 +8,8 @@
 
 import (
 	"fmt"
-	"io/ioutil"
+	"os"
+	"sort"
 	"strings"
 	"syscall"
 	"testing"
@@ -64,7 +65,7 @@
 func compareStatus(filter, expect string) error {
 	expected := filter + expect
 	pid := syscall.Getpid()
-	fs, err := ioutil.ReadDir(fmt.Sprintf("/proc/%d/task", pid))
+	fs, err := os.ReadDir(fmt.Sprintf("/proc/%d/task", pid))
 	if err != nil {
 		return fmt.Errorf("unable to find %d tasks: %v", pid, err)
 	}
@@ -72,7 +73,7 @@
 	foundAThread := false
 	for _, f := range fs {
 		tf := fmt.Sprintf("/proc/%s/status", f.Name())
-		d, err := ioutil.ReadFile(tf)
+		d, err := os.ReadFile(tf)
 		if err != nil {
 			// There are a surprising number of ways this
 			// can error out on linux.  We've seen all of
@@ -105,11 +106,23 @@
 				// "Pid:\t".
 			}
 			if strings.HasPrefix(line, filter) {
-				if line != expected {
-					return fmt.Errorf("%q got:%q want:%q (bad) [pid=%d file:'%s' %v]\n", tf, line, expected, pid, string(d), expectedProc)
+				if line == expected {
+					foundAThread = true
+					break
 				}
-				foundAThread = true
-				break
+				if filter == "Groups:" && strings.HasPrefix(line, "Groups:\t") {
+					// https://github.com/golang/go/issues/46145
+					// Containers don't reliably output this line in sorted order so manually sort and compare that.
+					a := strings.Split(line[8:], " ")
+					sort.Strings(a)
+					got := strings.Join(a, " ")
+					if got == expected[8:] {
+						foundAThread = true
+						break
+					}
+
+				}
+				return fmt.Errorf("%q got:%q want:%q (bad) [pid=%d file:'%s' %v]\n", tf, line, expected, pid, string(d), expectedProc)
 			}
 		}
 	}
diff --git a/misc/cgo/test/issue6997_linux.go b/misc/cgo/test/issue6997_linux.go
index 0c98ea0..f19afb8 100644
--- a/misc/cgo/test/issue6997_linux.go
+++ b/misc/cgo/test/issue6997_linux.go
@@ -5,7 +5,7 @@
 // +build !android
 
 // Test that pthread_cancel works as expected
-// (NPTL uses SIGRTMIN to implement thread cancelation)
+// (NPTL uses SIGRTMIN to implement thread cancellation)
 // See https://golang.org/issue/6997
 package cgotest
 
@@ -17,8 +17,10 @@
 */
 import "C"
 
-import "testing"
-import "time"
+import (
+	"testing"
+	"time"
+)
 
 func test6997(t *testing.T) {
 	r := C.StartThread()
diff --git a/misc/cgo/test/issue8148.c b/misc/cgo/test/issue8148.c
new file mode 100644
index 0000000..927b434
--- /dev/null
+++ b/misc/cgo/test/issue8148.c
@@ -0,0 +1,11 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "_cgo_export.h"
+
+int get8148(void) {
+	T t;
+	t.i = 42;
+	return issue8148Callback(&t);
+}
diff --git a/misc/cgo/test/issue8148.go b/misc/cgo/test/issue8148.go
index f704788..aee9003 100644
--- a/misc/cgo/test/issue8148.go
+++ b/misc/cgo/test/issue8148.go
@@ -10,14 +10,7 @@
 
 /*
 typedef struct { int i; } T;
-
-int issue8148Callback(T*);
-
-static int get() {
-	T t;
-	t.i = 42;
-	return issue8148Callback(&t);
-}
+int get8148(void);
 */
 import "C"
 
@@ -27,5 +20,5 @@
 }
 
 func Issue8148() int {
-	return int(C.get())
+	return int(C.get8148())
 }
diff --git a/misc/cgo/test/pkg_test.go b/misc/cgo/test/pkg_test.go
index 94abaa0..14013a4 100644
--- a/misc/cgo/test/pkg_test.go
+++ b/misc/cgo/test/pkg_test.go
@@ -5,7 +5,6 @@
 package cgotest
 
 import (
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -37,7 +36,7 @@
 		}
 	}
 
-	GOPATH, err := ioutil.TempDir("", "cgotest")
+	GOPATH, err := os.MkdirTemp("", "cgotest")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -47,7 +46,7 @@
 	if err := overlayDir(modRoot, "testdata"); err != nil {
 		t.Fatal(err)
 	}
-	if err := ioutil.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module cgotest\n"), 0666); err != nil {
+	if err := os.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module cgotest\n"), 0666); err != nil {
 		t.Fatal(err)
 	}
 
diff --git a/misc/cgo/test/setgid_linux.go b/misc/cgo/test/setgid_linux.go
index 6773f94..7c64946 100644
--- a/misc/cgo/test/setgid_linux.go
+++ b/misc/cgo/test/setgid_linux.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.
 
-// Test that setgid does not hang on GNU/Linux.
+// Test that setgid does not hang on Linux.
 // See https://golang.org/issue/3871 for details.
 
 package cgotest
diff --git a/misc/cgo/test/test.go b/misc/cgo/test/test.go
index 65823b1..3b8f548 100644
--- a/misc/cgo/test/test.go
+++ b/misc/cgo/test/test.go
@@ -899,6 +899,10 @@
 // issue 32579
 typedef struct S32579 { unsigned char data[1]; } S32579;
 
+// issue 37033, cgo.Handle
+extern void GoFunc37033(uintptr_t handle);
+void cFunc37033(uintptr_t handle) { GoFunc37033(handle); }
+
 // issue 38649
 // Test that #define'd type aliases work.
 #define netbsd_gid unsigned int
@@ -908,6 +912,9 @@
 enum Enum40494 { X_40494 };
 union Union40494 { int x; };
 void issue40494(enum Enum40494 e, union Union40494* up) {}
+
+// Issue 45451, bad handling of go:notinheap types.
+typedef struct issue45451Undefined issue45451;
 */
 import "C"
 
@@ -920,6 +927,7 @@
 	"os/signal"
 	"reflect"
 	"runtime"
+	"runtime/cgo"
 	"sync"
 	"syscall"
 	"testing"
@@ -2230,6 +2238,23 @@
 	}
 }
 
+// issue 37033, check if cgo.Handle works properly
+
+func testHandle(t *testing.T) {
+	ch := make(chan int)
+
+	for i := 0; i < 42; i++ {
+		h := cgo.NewHandle(ch)
+		go func() {
+			C.cFunc37033(C.uintptr_t(h))
+		}()
+		if v := <-ch; issue37033 != v {
+			t.Fatalf("unexpected receiving value: got %d, want %d", v, issue37033)
+		}
+		h.Delete()
+	}
+}
+
 // issue 38649
 
 var issue38649 C.netbsd_gid = 42
@@ -2244,3 +2269,19 @@
 func Issue40494() {
 	C.issue40494(C.enum_Enum40494(C.X_40494), (*C.union_Union40494)(nil))
 }
+
+// Issue 45451.
+func test45451(t *testing.T) {
+	var u *C.issue45451
+	typ := reflect.ValueOf(u).Type().Elem()
+
+	// The type is undefined in C so allocating it should panic.
+	defer func() {
+		if r := recover(); r == nil {
+			t.Error("expected panic")
+		}
+	}()
+
+	_ = reflect.New(typ)
+	t.Errorf("reflect.New(%v) should have panicked", typ)
+}
diff --git a/misc/cgo/test/testdata/issue9400/asm_386.s b/misc/cgo/test/testdata/issue9400/asm_386.s
index 7f158b5..96b8b60 100644
--- a/misc/cgo/test/testdata/issue9400/asm_386.s
+++ b/misc/cgo/test/testdata/issue9400/asm_386.s
@@ -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 !gccgo
+// +build gc
 
 #include "textflag.h"
 
diff --git a/misc/cgo/test/testdata/issue9400/asm_amd64x.s b/misc/cgo/test/testdata/issue9400/asm_amd64x.s
index 48b8619..99509bc 100644
--- a/misc/cgo/test/testdata/issue9400/asm_amd64x.s
+++ b/misc/cgo/test/testdata/issue9400/asm_amd64x.s
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build amd64 amd64p32
-// +build !gccgo
+// +build gc
 
 #include "textflag.h"
 
diff --git a/misc/cgo/test/testdata/issue9400/asm_arm.s b/misc/cgo/test/testdata/issue9400/asm_arm.s
index 96c2785..cc92856 100644
--- a/misc/cgo/test/testdata/issue9400/asm_arm.s
+++ b/misc/cgo/test/testdata/issue9400/asm_arm.s
@@ -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 !gccgo
+// +build gc
 
 #include "textflag.h"
 
diff --git a/misc/cgo/test/testdata/issue9400/asm_arm64.s b/misc/cgo/test/testdata/issue9400/asm_arm64.s
index 2ebbfcc..2565793 100644
--- a/misc/cgo/test/testdata/issue9400/asm_arm64.s
+++ b/misc/cgo/test/testdata/issue9400/asm_arm64.s
@@ -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 !gccgo
+// +build gc
 
 #include "textflag.h"
 
diff --git a/misc/cgo/test/testdata/issue9400/asm_mips64x.s b/misc/cgo/test/testdata/issue9400/asm_mips64x.s
index 63dc906..693231d 100644
--- a/misc/cgo/test/testdata/issue9400/asm_mips64x.s
+++ b/misc/cgo/test/testdata/issue9400/asm_mips64x.s
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build mips64 mips64le
-// +build !gccgo
+// +build gc
 
 #include "textflag.h"
 
diff --git a/misc/cgo/test/testdata/issue9400/asm_mipsx.s b/misc/cgo/test/testdata/issue9400/asm_mipsx.s
index 7a92735..63261bb 100644
--- a/misc/cgo/test/testdata/issue9400/asm_mipsx.s
+++ b/misc/cgo/test/testdata/issue9400/asm_mipsx.s
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build mips mipsle
-// +build !gccgo
+// +build gc
 
 #include "textflag.h"
 
diff --git a/misc/cgo/test/testdata/issue9400/asm_ppc64x.s b/misc/cgo/test/testdata/issue9400/asm_ppc64x.s
index c88ec3b..b5613fb 100644
--- a/misc/cgo/test/testdata/issue9400/asm_ppc64x.s
+++ b/misc/cgo/test/testdata/issue9400/asm_ppc64x.s
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build ppc64 ppc64le
-// +build !gccgo
+// +build gc
 
 #include "textflag.h"
 
diff --git a/misc/cgo/test/testdata/issue9400/asm_riscv64.s b/misc/cgo/test/testdata/issue9400/asm_riscv64.s
index 20fcc00..244dada 100644
--- a/misc/cgo/test/testdata/issue9400/asm_riscv64.s
+++ b/misc/cgo/test/testdata/issue9400/asm_riscv64.s
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build riscv64
-// +build !gccgo
+// +build gc
 
 #include "textflag.h"
 
diff --git a/misc/cgo/test/testdata/issue9400/asm_s390x.s b/misc/cgo/test/testdata/issue9400/asm_s390x.s
index fc9ad72..4856492 100644
--- a/misc/cgo/test/testdata/issue9400/asm_s390x.s
+++ b/misc/cgo/test/testdata/issue9400/asm_s390x.s
@@ -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 !gccgo
+// +build gc
 
 #include "textflag.h"
 
diff --git a/misc/cgo/test/testx.c b/misc/cgo/test/testx.c
new file mode 100644
index 0000000..1258e32
--- /dev/null
+++ b/misc/cgo/test/testx.c
@@ -0,0 +1,24 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "_cgo_export.h"
+
+void lockOSThreadC(void) {
+	lockOSThreadCallback();
+}
+
+void issue7978c(uint32_t *sync) {
+	while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 0)
+		;
+	__atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
+	while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 2)
+		;
+	issue7978cb();
+	__atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
+	while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 6)
+		;
+}
+
+void f7665(void) {
+}
diff --git a/misc/cgo/test/testx.go b/misc/cgo/test/testx.go
index 2b2e69e..823c3e1 100644
--- a/misc/cgo/test/testx.go
+++ b/misc/cgo/test/testx.go
@@ -12,6 +12,7 @@
 
 import (
 	"runtime"
+	"runtime/cgo"
 	"runtime/debug"
 	"strings"
 	"sync"
@@ -26,7 +27,6 @@
 extern void doAdd(int, int);
 
 // issue 1328
-extern void BackIntoGo(void);
 void IntoC(void);
 
 // issue 1560
@@ -38,11 +38,7 @@
 long long twoSleep(int);
 
 // issue 3775
-void lockOSThreadCallback(void);
-inline static void lockOSThreadC(void)
-{
-        lockOSThreadCallback();
-}
+void lockOSThreadC(void);
 int usleep(unsigned usec);
 
 // issue 4054 part 2 - part 1 in test.go
@@ -81,21 +77,9 @@
 
 #include <stdint.h>
 
-void issue7978cb(void);
-
 // use ugly atomic variable sync since that doesn't require calling back into
 // Go code or OS dependencies
-static void issue7978c(uint32_t *sync) {
-	while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 0)
-		;
-	__atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
-	while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 2)
-		;
-	issue7978cb();
-	__atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
-	while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 6)
-		;
-}
+void issue7978c(uint32_t *sync);
 
 // issue 8331 part 2 - part 1 in test.go
 // A typedef of an unnamed struct is the same struct when
@@ -428,9 +412,6 @@
 
 // issue 7665
 
-//export f7665
-func f7665() {}
-
 var bad7665 unsafe.Pointer = C.f7665
 var good7665 uintptr = uintptr(C.f7665)
 
@@ -558,6 +539,17 @@
 	C.callIssue31891()
 }
 
+// issue 37033, check if cgo.Handle works properly
+
+var issue37033 = 42
+
+//export GoFunc37033
+func GoFunc37033(handle C.uintptr_t) {
+	h := cgo.Handle(handle)
+	ch := h.Value().(chan int)
+	ch <- issue37033
+}
+
 // issue 38408
 // A typedef pointer can be used as the element type.
 // No runtime test; just make sure it compiles.
diff --git a/misc/cgo/testcarchive/carchive_test.go b/misc/cgo/testcarchive/carchive_test.go
index 6a5adf7..55be3c5 100644
--- a/misc/cgo/testcarchive/carchive_test.go
+++ b/misc/cgo/testcarchive/carchive_test.go
@@ -10,7 +10,6 @@
 	"debug/elf"
 	"flag"
 	"fmt"
-	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
@@ -53,7 +52,7 @@
 	// We need a writable GOPATH in which to run the tests.
 	// Construct one in a temporary directory.
 	var err error
-	GOPATH, err = ioutil.TempDir("", "carchive_test")
+	GOPATH, err = os.MkdirTemp("", "carchive_test")
 	if err != nil {
 		log.Panic(err)
 	}
@@ -74,7 +73,7 @@
 		log.Panic(err)
 	}
 	os.Setenv("PWD", modRoot)
-	if err := ioutil.WriteFile("go.mod", []byte("module testcarchive\n"), 0666); err != nil {
+	if err := os.WriteFile("go.mod", []byte("module testcarchive\n"), 0666); err != nil {
 		log.Panic(err)
 	}
 
@@ -176,7 +175,7 @@
 	// The 'cgo' command generates a number of additional artifacts,
 	// but we're only interested in the header.
 	// Shunt the rest of the outputs to a temporary directory.
-	objDir, err := ioutil.TempDir(GOPATH, "_obj")
+	objDir, err := os.MkdirTemp(GOPATH, "_obj")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -252,7 +251,7 @@
 // the user and make the files change based on details of the location
 // of GOPATH.
 func checkLineComments(t *testing.T, hdrname string) {
-	hdr, err := ioutil.ReadFile(hdrname)
+	hdr, err := os.ReadFile(hdrname)
 	if err != nil {
 		if !os.IsNotExist(err) {
 			t.Error(err)
@@ -618,7 +617,7 @@
 		t.Fatal(err)
 	}
 	s := strings.Replace(testar, "PWD", dir, 1)
-	if err := ioutil.WriteFile("testar", []byte(s), 0777); err != nil {
+	if err := os.WriteFile("testar", []byte(s), 0777); err != nil {
 		t.Fatal(err)
 	}
 
@@ -776,7 +775,7 @@
 // tool with -buildmode=c-archive, it passes -shared to the compiler,
 // so we override that. The go tool doesn't work this way, but Bazel
 // will likely do it in the future. And it ought to work. This test
-// was added because at one time it did not work on PPC GNU/Linux.
+// was added because at one time it did not work on PPC Linux.
 func TestCompileWithoutShared(t *testing.T) {
 	// For simplicity, reuse the signal forwarding test.
 	checkSignalForwardingTest(t)
diff --git a/misc/cgo/testcarchive/testdata/libgo6/sigprof.go b/misc/cgo/testcarchive/testdata/libgo6/sigprof.go
index 4cb05dc..31527c5 100644
--- a/misc/cgo/testcarchive/testdata/libgo6/sigprof.go
+++ b/misc/cgo/testcarchive/testdata/libgo6/sigprof.go
@@ -5,7 +5,7 @@
 package main
 
 import (
-	"io/ioutil"
+	"io"
 	"runtime/pprof"
 )
 
@@ -13,7 +13,7 @@
 
 //export go_start_profile
 func go_start_profile() {
-	pprof.StartCPUProfile(ioutil.Discard)
+	pprof.StartCPUProfile(io.Discard)
 }
 
 //export go_stop_profile
diff --git a/misc/cgo/testcarchive/testdata/main_unix.c b/misc/cgo/testcarchive/testdata/main_unix.c
index b23ac1c..bd00f9d 100644
--- a/misc/cgo/testcarchive/testdata/main_unix.c
+++ b/misc/cgo/testcarchive/testdata/main_unix.c
@@ -36,7 +36,7 @@
 		return 2;
 	}
 	// gccgo does not set SA_ONSTACK for SIGSEGV.
-	if (getenv("GCCGO") == "" && (osa.sa_flags&SA_ONSTACK) == 0) {
+	if (getenv("GCCGO") == NULL && (osa.sa_flags&SA_ONSTACK) == 0) {
 		fprintf(stderr, "Go runtime did not install signal handler\n");
 		return 2;
 	}
diff --git a/misc/cgo/testcshared/cshared_test.go b/misc/cgo/testcshared/cshared_test.go
index 3a4886c..19ad8c7 100644
--- a/misc/cgo/testcshared/cshared_test.go
+++ b/misc/cgo/testcshared/cshared_test.go
@@ -11,7 +11,6 @@
 	"encoding/binary"
 	"flag"
 	"fmt"
-	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
@@ -125,7 +124,7 @@
 	// Copy testdata into GOPATH/src/testcshared, along with a go.mod file
 	// declaring the same path.
 
-	GOPATH, err := ioutil.TempDir("", "cshared_test")
+	GOPATH, err := os.MkdirTemp("", "cshared_test")
 	if err != nil {
 		log.Panic(err)
 	}
@@ -140,7 +139,7 @@
 		log.Panic(err)
 	}
 	os.Setenv("PWD", modRoot)
-	if err := ioutil.WriteFile("go.mod", []byte("module testcshared\n"), 0666); err != nil {
+	if err := os.WriteFile("go.mod", []byte("module testcshared\n"), 0666); err != nil {
 		log.Panic(err)
 	}
 
@@ -260,7 +259,7 @@
 	// The 'cgo' command generates a number of additional artifacts,
 	// but we're only interested in the header.
 	// Shunt the rest of the outputs to a temporary directory.
-	objDir, err := ioutil.TempDir("", "testcshared_obj")
+	objDir, err := os.MkdirTemp("", "testcshared_obj")
 	if err != nil {
 		return err
 	}
@@ -293,11 +292,60 @@
 		"-installsuffix", "testcshared",
 		"-o", libgoname,
 		filepath.Join(".", "libgo", "libgo.go")}
+	if GOOS == "windows" && strings.HasSuffix(args[6], ".a") {
+		args[6] = strings.TrimSuffix(args[6], ".a") + ".dll"
+	}
 	cmd = exec.Command(args[0], args[1:]...)
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		return fmt.Errorf("command failed: %v\n%v\n%s\n", args, err, out)
 	}
+	if GOOS == "windows" {
+		// We can't simply pass -Wl,--out-implib, because this relies on having imports from multiple packages,
+		// which results in the linkers output implib getting overwritten at each step. So instead build the
+		// import library the traditional way, using a def file.
+		err = os.WriteFile("libgo.def",
+			[]byte("LIBRARY libgo.dll\nEXPORTS\n\tDidInitRun\n\tDidMainRun\n\tDivu\n\tFromPkg\n\t_cgo_dummy_export\n"),
+			0644)
+		if err != nil {
+			return fmt.Errorf("unable to write def file: %v", err)
+		}
+		out, err = exec.Command(cc[0], append(cc[1:], "-print-prog-name=dlltool")...).CombinedOutput()
+		if err != nil {
+			return fmt.Errorf("unable to find dlltool path: %v\n%s\n", err, out)
+		}
+		args := []string{strings.TrimSpace(string(out)), "-D", args[6], "-l", libgoname, "-d", "libgo.def"}
+
+		// This is an unfortunate workaround for https://github.com/mstorsjo/llvm-mingw/issues/205 in which
+		// we basically reimplement the contents of the dlltool.sh wrapper: https://git.io/JZFlU
+		dlltoolContents, err := os.ReadFile(args[0])
+		if err != nil {
+			return fmt.Errorf("unable to read dlltool: %v\n", err)
+		}
+		if bytes.HasPrefix(dlltoolContents, []byte("#!/bin/sh")) && bytes.Contains(dlltoolContents, []byte("llvm-dlltool")) {
+			base, name := filepath.Split(args[0])
+			args[0] = filepath.Join(base, "llvm-dlltool")
+			var machine string
+			switch strings.SplitN(name, "-", 2)[0] {
+			case "i686":
+				machine = "i386"
+			case "x86_64":
+				machine = "i386:x86-64"
+			case "armv7":
+				machine = "arm"
+			case "aarch64":
+				machine = "arm64"
+			}
+			if len(machine) > 0 {
+				args = append(args, "-m", machine)
+			}
+		}
+
+		out, err = exec.Command(args[0], args[1:]...).CombinedOutput()
+		if err != nil {
+			return fmt.Errorf("unable to run dlltool to create import library: %v\n%s\n", err, out)
+		}
+	}
 
 	if runtime.GOOS != GOOS && GOOS == "android" {
 		args = append(adbCmd(), "push", libgoname, fmt.Sprintf("%s/%s", androiddir, libgoname))
@@ -381,7 +429,7 @@
 
 	srcfile := filepath.Join(tmpdir, "test.go")
 	objfile := filepath.Join(tmpdir, "test.dll")
-	if err := ioutil.WriteFile(srcfile, []byte(prog), 0666); err != nil {
+	if err := os.WriteFile(srcfile, []byte(prog), 0666); err != nil {
 		t.Fatal(err)
 	}
 	argv := []string{"build", "-buildmode=c-shared"}
@@ -401,7 +449,7 @@
 	defer f.Close()
 	section := f.Section(".edata")
 	if section == nil {
-		t.Fatalf(".edata section is not present")
+		t.Skip(".edata section is not present")
 	}
 
 	// TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
@@ -643,7 +691,7 @@
 
 // Test that installing a second time recreates the header file.
 func TestCachedInstall(t *testing.T) {
-	tmpdir, err := ioutil.TempDir("", "cshared")
+	tmpdir, err := os.MkdirTemp("", "cshared")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -719,14 +767,14 @@
 // copyFile copies src to dst.
 func copyFile(t *testing.T, dst, src string) {
 	t.Helper()
-	data, err := ioutil.ReadFile(src)
+	data, err := os.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 {
+	if err := os.WriteFile(dst, data, 0666); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -743,14 +791,19 @@
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "cshared-TestGo2C2Go")
+	tmpdir, err := os.MkdirTemp("", "cshared-TestGo2C2Go")
 	if err != nil {
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(tmpdir)
 
 	lib := filepath.Join(tmpdir, "libtestgo2c2go."+libSuffix)
-	run(t, nil, "go", "build", "-buildmode=c-shared", "-o", lib, "./go2c2go/go")
+	var env []string
+	if GOOS == "windows" && strings.HasSuffix(lib, ".a") {
+		env = append(env, "CGO_LDFLAGS=-Wl,--out-implib,"+lib, "CGO_LDFLAGS_ALLOW=.*")
+		lib = strings.TrimSuffix(lib, ".a") + ".dll"
+	}
+	run(t, env, "go", "build", "-buildmode=c-shared", "-o", lib, "./go2c2go/go")
 
 	cgoCflags := os.Getenv("CGO_CFLAGS")
 	if cgoCflags != "" {
diff --git a/misc/cgo/testgodefs/testgodefs_test.go b/misc/cgo/testgodefs/testgodefs_test.go
index 4c2312c..aae3404 100644
--- a/misc/cgo/testgodefs/testgodefs_test.go
+++ b/misc/cgo/testgodefs/testgodefs_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"bytes"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -34,7 +33,7 @@
 		t.Fatal(err)
 	}
 
-	gopath, err := ioutil.TempDir("", "testgodefs-gopath")
+	gopath, err := os.MkdirTemp("", "testgodefs-gopath")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -58,20 +57,20 @@
 			t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr)
 		}
 
-		if err := ioutil.WriteFile(filepath.Join(dir, fp+"_defs.go"), out, 0644); err != nil {
+		if err := os.WriteFile(filepath.Join(dir, fp+"_defs.go"), out, 0644); err != nil {
 			t.Fatal(err)
 		}
 	}
 
-	main, err := ioutil.ReadFile(filepath.Join("testdata", "main.go"))
+	main, err := os.ReadFile(filepath.Join("testdata", "main.go"))
 	if err != nil {
 		t.Fatal(err)
 	}
-	if err := ioutil.WriteFile(filepath.Join(dir, "main.go"), main, 0644); err != nil {
+	if err := os.WriteFile(filepath.Join(dir, "main.go"), main, 0644); err != nil {
 		t.Fatal(err)
 	}
 
-	if err := ioutil.WriteFile(filepath.Join(dir, "go.mod"), []byte("module testgodefs\ngo 1.14\n"), 0644); err != nil {
+	if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module testgodefs\ngo 1.14\n"), 0644); err != nil {
 		t.Fatal(err)
 	}
 
diff --git a/misc/cgo/testplugin/plugin_test.go b/misc/cgo/testplugin/plugin_test.go
index 8869528..9697dbf 100644
--- a/misc/cgo/testplugin/plugin_test.go
+++ b/misc/cgo/testplugin/plugin_test.go
@@ -9,7 +9,6 @@
 	"context"
 	"flag"
 	"fmt"
-	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
@@ -31,15 +30,28 @@
 	os.Exit(testMain(m))
 }
 
+// tmpDir is used to cleanup logged commands -- s/tmpDir/$TMPDIR/
+var tmpDir string
+
+// prettyPrintf prints lines with tmpDir sanitized.
+func prettyPrintf(format string, args ...interface{}) {
+	s := fmt.Sprintf(format, args...)
+	if tmpDir != "" {
+		s = strings.ReplaceAll(s, tmpDir, "$TMPDIR")
+	}
+	fmt.Print(s)
+}
+
 func testMain(m *testing.M) int {
 	// Copy testdata into GOPATH/src/testplugin, along with a go.mod file
 	// declaring the same path.
 
-	GOPATH, err := ioutil.TempDir("", "plugin_test")
+	GOPATH, err := os.MkdirTemp("", "plugin_test")
 	if err != nil {
 		log.Panic(err)
 	}
 	defer os.RemoveAll(GOPATH)
+	tmpDir = GOPATH
 
 	modRoot := filepath.Join(GOPATH, "src", "testplugin")
 	altRoot := filepath.Join(GOPATH, "alt", "src", "testplugin")
@@ -50,14 +62,20 @@
 		if err := overlayDir(dstRoot, srcRoot); err != nil {
 			log.Panic(err)
 		}
-		if err := ioutil.WriteFile(filepath.Join(dstRoot, "go.mod"), []byte("module testplugin\n"), 0666); err != nil {
+		prettyPrintf("mkdir -p %s\n", dstRoot)
+		prettyPrintf("rsync -a %s/ %s\n", srcRoot, dstRoot)
+
+		if err := os.WriteFile(filepath.Join(dstRoot, "go.mod"), []byte("module testplugin\n"), 0666); err != nil {
 			log.Panic(err)
 		}
+		prettyPrintf("echo 'module testplugin' > %s/go.mod\n", dstRoot)
 	}
 
 	os.Setenv("GOPATH", filepath.Join(GOPATH, "alt"))
 	if err := os.Chdir(altRoot); err != nil {
 		log.Panic(err)
+	} else {
+		prettyPrintf("cd %s\n", altRoot)
 	}
 	os.Setenv("PWD", altRoot)
 	goCmd(nil, "build", "-buildmode=plugin", "-o", filepath.Join(modRoot, "plugin-mismatch.so"), "./plugin-mismatch")
@@ -65,6 +83,8 @@
 	os.Setenv("GOPATH", GOPATH)
 	if err := os.Chdir(modRoot); err != nil {
 		log.Panic(err)
+	} else {
+		prettyPrintf("cd %s\n", modRoot)
 	}
 	os.Setenv("PWD", modRoot)
 
@@ -72,13 +92,14 @@
 
 	goCmd(nil, "build", "-buildmode=plugin", "./plugin1")
 	goCmd(nil, "build", "-buildmode=plugin", "./plugin2")
-	so, err := ioutil.ReadFile("plugin2.so")
+	so, err := os.ReadFile("plugin2.so")
 	if err != nil {
 		log.Panic(err)
 	}
-	if err := ioutil.WriteFile("plugin2-dup.so", so, 0444); err != nil {
+	if err := os.WriteFile("plugin2-dup.so", so, 0444); err != nil {
 		log.Panic(err)
 	}
+	prettyPrintf("cp plugin2.so plugin2-dup.so\n")
 
 	goCmd(nil, "build", "-buildmode=plugin", "-o=sub/plugin1.so", "./sub/plugin1")
 	goCmd(nil, "build", "-buildmode=plugin", "-o=unnamed1.so", "./unnamed1/main.go")
@@ -95,8 +116,53 @@
 	run(t, "go", append([]string{op, "-gcflags", gcflags}, args...)...)
 }
 
+// escape converts a string to something suitable for 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 s == "" || strings.ContainsAny(s, "\\ ;#*&$~?!|[]()<>{}`") {
+		s = "'" + s + "'"
+	}
+	return s
+}
+
+// asCommandLine renders cmd as something that could be copy-and-pasted into a command line
+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 += " "
+			s += escape(e)
+		}
+	}
+	// These EVs are relevant to this test.
+	for _, e := range os.Environ() {
+		if strings.HasPrefix(e, "PWD=") ||
+			strings.HasPrefix(e, "GOPATH=") ||
+			strings.HasPrefix(e, "LD_LIBRARY_PATH=") {
+			s += " "
+			s += escape(e)
+		}
+	}
+	for _, a := range cmd.Args {
+		s += " "
+		s += escape(a)
+	}
+	s += " )"
+	return s
+}
+
 func run(t *testing.T, bin string, args ...string) string {
 	cmd := exec.Command(bin, args...)
+	cmdLine := asCommandLine(".", cmd)
+	prettyPrintf("%s\n", cmdLine)
 	cmd.Stderr = new(strings.Builder)
 	out, err := cmd.Output()
 	if err != nil {
@@ -197,6 +263,17 @@
 	}
 }
 
+// Test with main using -buildmode=pie with plugin for issue #43228
+func TestIssue25756pie(t *testing.T) {
+	if os.Getenv("GO_BUILDER_NAME") == "darwin-arm64-11_0-toothrot" {
+		t.Skip("broken on darwin/arm64 builder in sharded mode; see issue 46239")
+	}
+
+	goCmd(t, "build", "-buildmode=plugin", "-o", "life.so", "./issue25756/plugin")
+	goCmd(t, "build", "-buildmode=pie", "-o", "issue25756pie.exe", "./issue25756/main.go")
+	run(t, "./issue25756pie.exe")
+}
+
 func TestMethod(t *testing.T) {
 	// Exported symbol's method must be live.
 	goCmd(t, "build", "-buildmode=plugin", "-o", "plugin.so", "./method/plugin.go")
diff --git a/misc/cgo/testplugin/testdata/method2/main.go b/misc/cgo/testplugin/testdata/method2/main.go
index 6a87e7b..89afbda 100644
--- a/misc/cgo/testplugin/testdata/method2/main.go
+++ b/misc/cgo/testplugin/testdata/method2/main.go
@@ -15,7 +15,7 @@
 
 var t p.T
 
-type I interface { M() }
+type I interface{ M() }
 
 func main() {
 	pl, err := plugin.Open("method2.so")
diff --git a/misc/cgo/testsanitizers/cc_test.go b/misc/cgo/testsanitizers/cc_test.go
index 0192a66..384b625 100644
--- a/misc/cgo/testsanitizers/cc_test.go
+++ b/misc/cgo/testsanitizers/cc_test.go
@@ -11,7 +11,6 @@
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -36,7 +35,7 @@
 
 	overcommit.Once.Do(func() {
 		var out []byte
-		out, overcommit.err = ioutil.ReadFile("/proc/sys/vm/overcommit_memory")
+		out, overcommit.err = os.ReadFile("/proc/sys/vm/overcommit_memory")
 		if overcommit.err != nil {
 			return
 		}
@@ -313,14 +312,14 @@
 `)
 
 func (c *config) checkCSanitizer() (skip bool, err error) {
-	dir, err := ioutil.TempDir("", c.sanitizer)
+	dir, err := os.MkdirTemp("", 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 {
+	if err := os.WriteFile(src, cMain, 0600); err != nil {
 		return false, fmt.Errorf("failed to write C source file: %v", err)
 	}
 
@@ -418,7 +417,7 @@
 
 func newTempDir(t *testing.T) *tempDir {
 	t.Helper()
-	dir, err := ioutil.TempDir("", filepath.Dir(t.Name()))
+	dir, err := os.MkdirTemp("", filepath.Dir(t.Name()))
 	if err != nil {
 		t.Fatalf("Failed to create temp dir: %v", err)
 	}
@@ -440,3 +439,14 @@
 	}
 	return cmd
 }
+
+// mSanSupported is a copy of the function cmd/internal/sys.MSanSupported,
+// because the internal pacakage can't be used here.
+func mSanSupported(goos, goarch string) bool {
+	switch goos {
+	case "linux":
+		return goarch == "amd64" || goarch == "arm64"
+	default:
+		return false
+	}
+}
diff --git a/misc/cgo/testsanitizers/cshared_test.go b/misc/cgo/testsanitizers/cshared_test.go
index 56063ea..8fd0371 100644
--- a/misc/cgo/testsanitizers/cshared_test.go
+++ b/misc/cgo/testsanitizers/cshared_test.go
@@ -6,7 +6,7 @@
 
 import (
 	"fmt"
-	"io/ioutil"
+	"os"
 	"strings"
 	"testing"
 )
@@ -19,6 +19,12 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+
+	GOARCH, err := goEnv("GOARCH")
+	if err != nil {
+		t.Fatal(err)
+	}
+
 	libExt := "so"
 	if GOOS == "darwin" {
 		libExt = "dylib"
@@ -41,6 +47,11 @@
 	for _, tc := range cases {
 		tc := tc
 		name := strings.TrimSuffix(tc.src, ".go")
+		//The memory sanitizer tests require support for the -msan option.
+		if tc.sanitizer == "memory" && !mSanSupported(GOOS, GOARCH) {
+			t.Logf("skipping %s test on %s/%s; -msan option is not supported.", name, GOOS, GOARCH)
+			continue
+		}
 		t.Run(name, func(t *testing.T) {
 			t.Parallel()
 			config := configure(tc.sanitizer)
@@ -53,7 +64,7 @@
 			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 {
+			if err := os.WriteFile(cSrc, cMain, 0600); err != nil {
 				t.Fatalf("failed to write C source file: %v", err)
 			}
 
diff --git a/misc/cgo/testsanitizers/msan_test.go b/misc/cgo/testsanitizers/msan_test.go
index 5e2f975..5ee9947 100644
--- a/misc/cgo/testsanitizers/msan_test.go
+++ b/misc/cgo/testsanitizers/msan_test.go
@@ -10,6 +10,19 @@
 )
 
 func TestMSAN(t *testing.T) {
+	goos, err := goEnv("GOOS")
+	if err != nil {
+		t.Fatal(err)
+	}
+	goarch, err := goEnv("GOARCH")
+	if err != nil {
+		t.Fatal(err)
+	}
+	// The msan tests require support for the -msan option.
+	if !mSanSupported(goos, goarch) {
+		t.Skipf("skipping on %s/%s; -msan option is not supported.", goos, goarch)
+	}
+
 	t.Parallel()
 	requireOvercommit(t)
 	config := configure("memory")
@@ -29,6 +42,7 @@
 		{src: "msan5.go"},
 		{src: "msan6.go"},
 		{src: "msan7.go"},
+		{src: "msan8.go"},
 		{src: "msan_fail.go", wantErr: true},
 	}
 	for _, tc := range cases {
diff --git a/misc/cgo/testsanitizers/testdata/msan8.go b/misc/cgo/testsanitizers/testdata/msan8.go
new file mode 100644
index 0000000..1cb5c56
--- /dev/null
+++ b/misc/cgo/testsanitizers/testdata/msan8.go
@@ -0,0 +1,109 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+/*
+#include <pthread.h>
+#include <signal.h>
+#include <stdint.h>
+
+#include <sanitizer/msan_interface.h>
+
+// cgoTracebackArg is the type of the argument passed to msanGoTraceback.
+struct cgoTracebackArg {
+	uintptr_t context;
+	uintptr_t sigContext;
+	uintptr_t* buf;
+	uintptr_t max;
+};
+
+// msanGoTraceback is registered as the cgo traceback function.
+// This will be called when a signal occurs.
+void msanGoTraceback(void* parg) {
+	struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
+        arg->buf[0] = 0;
+}
+
+// msanGoWait will be called with all registers undefined as far as
+// msan is concerned. It just waits for a signal.
+// Because the registers are msan-undefined, the signal handler will
+// be invoked with all registers msan-undefined.
+__attribute__((noinline))
+void msanGoWait(unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, unsigned long a6) {
+	sigset_t mask;
+
+	sigemptyset(&mask);
+        sigsuspend(&mask);
+}
+
+// msanGoSignalThread is the thread ID of the msanGoLoop thread.
+static pthread_t msanGoSignalThread;
+
+// msanGoSignalThreadSet is used to record that msanGoSignalThread
+// has been initialized. This is accessed atomically.
+static int32_t msanGoSignalThreadSet;
+
+// uninit is explicitly poisoned, so that we can make all registers
+// undefined by calling msanGoWait.
+static unsigned long uninit;
+
+// msanGoLoop loops calling msanGoWait, with the arguments passed
+// such that msan thinks that they are undefined. msan permits
+// undefined values to be used as long as they are not used to
+// for conditionals or for memory access.
+void msanGoLoop() {
+	int i;
+
+	msanGoSignalThread = pthread_self();
+        __atomic_store_n(&msanGoSignalThreadSet, 1, __ATOMIC_SEQ_CST);
+
+	// Force uninit to be undefined for msan.
+	__msan_poison(&uninit, sizeof uninit);
+	for (i = 0; i < 100; i++) {
+		msanGoWait(uninit, uninit, uninit, uninit, uninit, uninit);
+        }
+}
+
+// msanGoReady returns whether msanGoSignalThread is set.
+int msanGoReady() {
+	return __atomic_load_n(&msanGoSignalThreadSet, __ATOMIC_SEQ_CST) != 0;
+}
+
+// msanGoSendSignal sends a signal to the msanGoLoop thread.
+void msanGoSendSignal() {
+	pthread_kill(msanGoSignalThread, SIGWINCH);
+}
+*/
+import "C"
+
+import (
+	"runtime"
+	"time"
+)
+
+func main() {
+	runtime.SetCgoTraceback(0, C.msanGoTraceback, nil, nil)
+
+	c := make(chan bool)
+	go func() {
+		defer func() { c <- true }()
+		C.msanGoLoop()
+	}()
+
+	for C.msanGoReady() == 0 {
+		time.Sleep(time.Microsecond)
+	}
+
+loop:
+	for {
+		select {
+		case <-c:
+			break loop
+		default:
+			C.msanGoSendSignal()
+			time.Sleep(time.Microsecond)
+		}
+	}
+}
diff --git a/misc/cgo/testsanitizers/testdata/tsan9.go b/misc/cgo/testsanitizers/testdata/tsan9.go
index f166d8b..06304be 100644
--- a/misc/cgo/testsanitizers/testdata/tsan9.go
+++ b/misc/cgo/testsanitizers/testdata/tsan9.go
@@ -44,7 +44,7 @@
 import "C"
 
 import (
-	"io/ioutil"
+	"io"
 	"runtime/pprof"
 	"time"
 )
@@ -60,7 +60,7 @@
 }
 
 func main() {
-	pprof.StartCPUProfile(ioutil.Discard)
+	pprof.StartCPUProfile(io.Discard)
 	go C.spin()
 	goSpin()
 	pprof.StopCPUProfile()
diff --git a/misc/cgo/testshared/shared_test.go b/misc/cgo/testshared/shared_test.go
index f52391c..e77f848 100644
--- a/misc/cgo/testshared/shared_test.go
+++ b/misc/cgo/testshared/shared_test.go
@@ -13,7 +13,6 @@
 	"fmt"
 	"go/build"
 	"io"
-	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
@@ -90,7 +89,7 @@
 
 // TestMain calls testMain so that the latter can use defer (TestMain exits with os.Exit).
 func testMain(m *testing.M) (int, error) {
-	workDir, err := ioutil.TempDir("", "shared_test")
+	workDir, err := os.MkdirTemp("", "shared_test")
 	if err != nil {
 		return 0, err
 	}
@@ -177,7 +176,7 @@
 	if err := overlayDir(modRoot, "testdata"); err != nil {
 		return "", err
 	}
-	if err := ioutil.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module testshared\n"), 0644); err != nil {
+	if err := os.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module testshared\n"), 0644); err != nil {
 		return "", err
 	}
 	return modRoot, nil
@@ -318,7 +317,7 @@
 	}
 	for _, pkg := range pkgs {
 		shlibnamefile := filepath.Join(gorootInstallDir, pkg+".shlibname")
-		contentsb, err := ioutil.ReadFile(shlibnamefile)
+		contentsb, err := os.ReadFile(shlibnamefile)
 		if err != nil {
 			t.Errorf("error reading shlibnamefile for %s: %v", pkg, err)
 			continue
@@ -791,7 +790,7 @@
 // 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()) {
 	t.Helper()
-	data, err := ioutil.ReadFile(path)
+	data, err := os.ReadFile(path)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -837,14 +836,14 @@
 	// user-writable.
 	perm := fi.Mode().Perm() | 0200
 
-	if err := ioutil.WriteFile(path, data, perm); err != nil {
+	if err := os.WriteFile(path, data, perm); err != nil {
 		t.Fatal(err)
 	}
 	if err := os.Chtimes(path, nearlyNew, nearlyNew); err != nil {
 		t.Fatal(err)
 	}
 	return func() {
-		if err := ioutil.WriteFile(path, old, perm); err != nil {
+		if err := os.WriteFile(path, old, perm); err != nil {
 			t.Fatal(err)
 		}
 	}
diff --git a/misc/cgo/testshared/testdata/depBase/asm.s b/misc/cgo/testshared/testdata/depBase/asm.s
index a8acf77..0f1111f 100644
--- a/misc/cgo/testshared/testdata/depBase/asm.s
+++ b/misc/cgo/testshared/testdata/depBase/asm.s
@@ -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 !gccgo
+// +build gc
 
 #include "textflag.h"
 
diff --git a/misc/cgo/testshared/testdata/depBase/stubs.go b/misc/cgo/testshared/testdata/depBase/stubs.go
index 04534f3..c779538 100644
--- a/misc/cgo/testshared/testdata/depBase/stubs.go
+++ b/misc/cgo/testshared/testdata/depBase/stubs.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo
+// +build gc
 
 package depBase
 
diff --git a/misc/cgo/testso/so_test.go b/misc/cgo/testso/so_test.go
index 57f0fd3..2023c51 100644
--- a/misc/cgo/testso/so_test.go
+++ b/misc/cgo/testso/so_test.go
@@ -7,7 +7,6 @@
 package so_test
 
 import (
-	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
@@ -37,7 +36,7 @@
 func TestSO(t *testing.T) {
 	requireTestSOSupported(t)
 
-	GOPATH, err := ioutil.TempDir("", "cgosotest")
+	GOPATH, err := os.MkdirTemp("", "cgosotest")
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -47,7 +46,7 @@
 	if err := overlayDir(modRoot, "testdata"); err != nil {
 		log.Panic(err)
 	}
-	if err := ioutil.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module cgosotest\n"), 0666); err != nil {
+	if err := os.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module cgosotest\n"), 0666); err != nil {
 		log.Panic(err)
 	}
 
@@ -80,6 +79,10 @@
 	case "windows":
 		ext = "dll"
 		args = append(args, "-DEXPORT_DLL")
+		// At least in mingw-clang it is not permitted to just name a .dll
+		// on the command line. You must name the corresponding import
+		// library instead, even though the dll is used when the executable is run.
+		args = append(args, "-Wl,-out-implib,libcgosotest.a")
 	case "aix":
 		ext = "so.1"
 	}
diff --git a/misc/cgo/testso/testdata/cgoso.go b/misc/cgo/testso/testdata/cgoso.go
index bba5de3..b59b2a8 100644
--- a/misc/cgo/testso/testdata/cgoso.go
+++ b/misc/cgo/testso/testdata/cgoso.go
@@ -14,7 +14,7 @@
 #cgo solaris LDFLAGS: -L. -lcgosotest
 #cgo netbsd LDFLAGS: -L. libcgosotest.so
 #cgo darwin LDFLAGS: -L. libcgosotest.dylib
-#cgo windows LDFLAGS: -L. libcgosotest.dll
+#cgo windows LDFLAGS: -L. libcgosotest.a
 #cgo aix LDFLAGS: -L. -l cgosotest
 
 void init(void);
diff --git a/misc/cgo/testsovar/so_test.go b/misc/cgo/testsovar/so_test.go
index 57f0fd3..2023c51 100644
--- a/misc/cgo/testsovar/so_test.go
+++ b/misc/cgo/testsovar/so_test.go
@@ -7,7 +7,6 @@
 package so_test
 
 import (
-	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
@@ -37,7 +36,7 @@
 func TestSO(t *testing.T) {
 	requireTestSOSupported(t)
 
-	GOPATH, err := ioutil.TempDir("", "cgosotest")
+	GOPATH, err := os.MkdirTemp("", "cgosotest")
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -47,7 +46,7 @@
 	if err := overlayDir(modRoot, "testdata"); err != nil {
 		log.Panic(err)
 	}
-	if err := ioutil.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module cgosotest\n"), 0666); err != nil {
+	if err := os.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module cgosotest\n"), 0666); err != nil {
 		log.Panic(err)
 	}
 
@@ -80,6 +79,10 @@
 	case "windows":
 		ext = "dll"
 		args = append(args, "-DEXPORT_DLL")
+		// At least in mingw-clang it is not permitted to just name a .dll
+		// on the command line. You must name the corresponding import
+		// library instead, even though the dll is used when the executable is run.
+		args = append(args, "-Wl,-out-implib,libcgosotest.a")
 	case "aix":
 		ext = "so.1"
 	}
diff --git a/misc/cgo/testsovar/testdata/cgoso.go b/misc/cgo/testsovar/testdata/cgoso.go
index 9c7f95e..d9deb55 100644
--- a/misc/cgo/testsovar/testdata/cgoso.go
+++ b/misc/cgo/testsovar/testdata/cgoso.go
@@ -18,7 +18,7 @@
 #cgo solaris LDFLAGS: -L. -lcgosotest
 #cgo netbsd LDFLAGS: -L. libcgosotest.so
 #cgo darwin LDFLAGS: -L. libcgosotest.dylib
-#cgo windows LDFLAGS: -L. libcgosotest.dll
+#cgo windows LDFLAGS: -L. libcgosotest.a
 #cgo aix LDFLAGS: -L. -l cgosotest
 
 #include "cgoso_c.h"
diff --git a/misc/chrome/gophertool/popup.html b/misc/chrome/gophertool/popup.html
index 9740406..ad42a38 100644
--- a/misc/chrome/gophertool/popup.html
+++ b/misc/chrome/gophertool/popup.html
@@ -15,7 +15,7 @@
 <a href="#" url="https://golang.org/pkg/">pkg</a> id/name:</small>
 <form style='margin: 0' id='navform'><nobr><input id="inputbox" size=10 tabindex=1 /><input type="submit" value="go" /></nobr></form>
 <small>Also: <a href="#" url="https://build.golang.org">buildbots</a>
-<a href="#" url="https://github.com/golang/go">Github</a>
+<a href="#" url="https://github.com/golang/go">GitHub</a>
 </small>
 </body>
 </html>
diff --git a/misc/ios/detect.go b/misc/ios/detect.go
index d32bcc3..cde5723 100644
--- a/misc/ios/detect.go
+++ b/misc/ios/detect.go
@@ -16,7 +16,6 @@
 	"bytes"
 	"crypto/x509"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"strings"
@@ -38,7 +37,7 @@
 	fmt.Println("# will be overwritten when running Go programs.")
 	for _, mp := range mps {
 		fmt.Println()
-		f, err := ioutil.TempFile("", "go_ios_detect_")
+		f, err := os.CreateTemp("", "go_ios_detect_")
 		check(err)
 		fname := f.Name()
 		defer os.Remove(fname)
diff --git a/misc/ios/go_ios_exec.go b/misc/ios/go_ios_exec.go
index 0acf1b2..9e63717 100644
--- a/misc/ios/go_ios_exec.go
+++ b/misc/ios/go_ios_exec.go
@@ -26,7 +26,6 @@
 	"fmt"
 	"go/build"
 	"io"
-	"io/ioutil"
 	"log"
 	"net"
 	"os"
@@ -79,7 +78,7 @@
 
 func runMain() (int, error) {
 	var err error
-	tmpdir, err = ioutil.TempDir("", "go_ios_exec_")
+	tmpdir, err = os.MkdirTemp("", "go_ios_exec_")
 	if err != nil {
 		return 1, err
 	}
@@ -205,13 +204,13 @@
 	}
 
 	entitlementsPath := filepath.Join(tmpdir, "Entitlements.plist")
-	if err := ioutil.WriteFile(entitlementsPath, []byte(entitlementsPlist()), 0744); err != nil {
+	if err := os.WriteFile(entitlementsPath, []byte(entitlementsPlist()), 0744); err != nil {
 		return err
 	}
-	if err := ioutil.WriteFile(filepath.Join(appdir, "Info.plist"), []byte(infoPlist(pkgpath)), 0744); err != nil {
+	if err := os.WriteFile(filepath.Join(appdir, "Info.plist"), []byte(infoPlist(pkgpath)), 0744); err != nil {
 		return err
 	}
-	if err := ioutil.WriteFile(filepath.Join(appdir, "ResourceRules.plist"), []byte(resourceRules), 0744); err != nil {
+	if err := os.WriteFile(filepath.Join(appdir, "ResourceRules.plist"), []byte(resourceRules), 0744); err != nil {
 		return err
 	}
 	return nil
diff --git a/misc/linkcheck/linkcheck.go b/misc/linkcheck/linkcheck.go
index d9bfd2f..570b430 100644
--- a/misc/linkcheck/linkcheck.go
+++ b/misc/linkcheck/linkcheck.go
@@ -11,7 +11,7 @@
 	"errors"
 	"flag"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"log"
 	"net/http"
 	"os"
@@ -144,7 +144,7 @@
 	if res.StatusCode != 200 {
 		return errors.New(res.Status)
 	}
-	slurp, err := ioutil.ReadAll(res.Body)
+	slurp, err := io.ReadAll(res.Body)
 	res.Body.Close()
 	if err != nil {
 		log.Fatalf("Error reading %s body: %v", url, err)
diff --git a/misc/reboot/experiment_toolid_test.go b/misc/reboot/experiment_toolid_test.go
index eabf06b..4f40284 100644
--- a/misc/reboot/experiment_toolid_test.go
+++ b/misc/reboot/experiment_toolid_test.go
@@ -13,7 +13,6 @@
 
 import (
 	"bytes"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -23,7 +22,7 @@
 
 func TestExperimentToolID(t *testing.T) {
 	// Set up GOROOT
-	goroot, err := ioutil.TempDir("", "experiment-goroot")
+	goroot, err := os.MkdirTemp("", "experiment-goroot")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -34,13 +33,13 @@
 		t.Fatal(err)
 	}
 
-	if err := ioutil.WriteFile(filepath.Join(goroot, "VERSION"), []byte("go1.999"), 0666); err != nil {
+	if err := os.WriteFile(filepath.Join(goroot, "VERSION"), []byte("go1.999"), 0666); err != nil {
 		t.Fatal(err)
 	}
 	env := append(os.Environ(), "GOROOT=", "GOROOT_BOOTSTRAP="+runtime.GOROOT())
 
 	// Use a clean cache.
-	gocache, err := ioutil.TempDir("", "experiment-gocache")
+	gocache, err := os.MkdirTemp("", "experiment-gocache")
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/misc/reboot/reboot_test.go b/misc/reboot/reboot_test.go
index 717c0fb..6bafc60 100644
--- a/misc/reboot/reboot_test.go
+++ b/misc/reboot/reboot_test.go
@@ -7,7 +7,6 @@
 package reboot_test
 
 import (
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -16,7 +15,7 @@
 )
 
 func TestRepeatBootstrap(t *testing.T) {
-	goroot, err := ioutil.TempDir("", "reboot-goroot")
+	goroot, err := os.MkdirTemp("", "reboot-goroot")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -27,7 +26,7 @@
 		t.Fatal(err)
 	}
 
-	if err := ioutil.WriteFile(filepath.Join(goroot, "VERSION"), []byte(runtime.Version()), 0666); err != nil {
+	if err := os.WriteFile(filepath.Join(goroot, "VERSION"), []byte(runtime.Version()), 0666); err != nil {
 		t.Fatal(err)
 	}
 
diff --git a/misc/trace/trace_viewer_full.html b/misc/trace/trace_viewer_full.html
index ef2e0ea..ae6e35f 100644
--- a/misc/trace/trace_viewer_full.html
+++ b/misc/trace/trace_viewer_full.html
@@ -993,13 +993,13 @@
     </style>
     <div style="padding-right: 200px">
       <div style="float:right;  border-style: solid; border-width: 1px; padding:20px">
-        X no feedback<br/>
-        0 uninitialized<br/>
-        . premonomorphic<br/>
-        1 monomorphic<br/>
-        ^ recompute handler<br/>
-        P polymorphic<br/>
-        N megamorphic<br/>
+        X no feedback<br>
+        0 uninitialized<br>
+        . premonomorphic<br>
+        1 monomorphic<br>
+        ^ recompute handler<br>
+        P polymorphic<br>
+        N megamorphic<br>
         G generic
       </div>
     </div>
@@ -3596,7 +3596,7 @@
     <div id="pipeline_per_frame_container">
       <div class="subtitle">Graphics Pipeline and Raster Tasks</div>
       <div class="description">
-        When raster tasks are completed in comparison to the rest of the graphics pipeline.<br/>
+        When raster tasks are completed in comparison to the rest of the graphics pipeline.<br>
         Only pages where raster tasks are completed after beginFrame is issued are included.
       </div>
       <tr-v-ui-raster-visualization id="rasterVisualization">
diff --git a/misc/wasm/wasm_exec.js b/misc/wasm/wasm_exec.js
index 82041e6..231185a 100644
--- a/misc/wasm/wasm_exec.js
+++ b/misc/wasm/wasm_exec.js
@@ -296,8 +296,8 @@
 						setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);
 					},
 
-					// func walltime1() (sec int64, nsec int32)
-					"runtime.walltime1": (sp) => {
+					// func walltime() (sec int64, nsec int32)
+					"runtime.walltime": (sp) => {
 						sp >>>= 0;
 						const msec = (new Date).getTime();
 						setInt64(sp + 8, msec / 1000);
@@ -401,6 +401,7 @@
 							storeValue(sp + 56, result);
 							this.mem.setUint8(sp + 64, 1);
 						} catch (err) {
+							sp = this._inst.exports.getsp() >>> 0; // see comment above
 							storeValue(sp + 56, err);
 							this.mem.setUint8(sp + 64, 0);
 						}
@@ -417,6 +418,7 @@
 							storeValue(sp + 40, result);
 							this.mem.setUint8(sp + 48, 1);
 						} catch (err) {
+							sp = this._inst.exports.getsp() >>> 0; // see comment above
 							storeValue(sp + 40, err);
 							this.mem.setUint8(sp + 48, 0);
 						}
@@ -433,6 +435,7 @@
 							storeValue(sp + 40, result);
 							this.mem.setUint8(sp + 48, 1);
 						} catch (err) {
+							sp = this._inst.exports.getsp() >>> 0; // see comment above
 							storeValue(sp + 40, err);
 							this.mem.setUint8(sp + 48, 0);
 						}
diff --git a/pkg/darwin_amd64/archive/tar.a b/pkg/darwin_amd64/archive/tar.a
index 0d78087..fde4a5d 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 6c384ce..e77ac14 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 efcafb6..d4cae7f 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 7f1a435..ccdb831 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 6af34cb..d5433b4 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 6b0aa00..cf1c7e5 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 1bfe274..d751c29 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 fc23493..2c0c63e 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/abi.a b/pkg/darwin_amd64/cmd/compile/internal/abi.a
new file mode 100644
index 0000000..ff8747b
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/abi.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 d8daac7..36364bd 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 414c273..b4e0a23 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 fd5d443..efa0ee5 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/base.a b/pkg/darwin_amd64/cmd/compile/internal/base.a
new file mode 100644
index 0000000..1250e36
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/base.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/bitvec.a b/pkg/darwin_amd64/cmd/compile/internal/bitvec.a
new file mode 100644
index 0000000..1dc4206
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/bitvec.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/deadcode.a b/pkg/darwin_amd64/cmd/compile/internal/deadcode.a
new file mode 100644
index 0000000..518fde8
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/deadcode.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/devirtualize.a b/pkg/darwin_amd64/cmd/compile/internal/devirtualize.a
new file mode 100644
index 0000000..9017a8b
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/devirtualize.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/dwarfgen.a b/pkg/darwin_amd64/cmd/compile/internal/dwarfgen.a
new file mode 100644
index 0000000..e0301f7
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/dwarfgen.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/escape.a b/pkg/darwin_amd64/cmd/compile/internal/escape.a
new file mode 100644
index 0000000..301ebb8
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/escape.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 873799b..eef9c29 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/importer.a b/pkg/darwin_amd64/cmd/compile/internal/importer.a
new file mode 100644
index 0000000..7506a44
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/importer.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/inline.a b/pkg/darwin_amd64/cmd/compile/internal/inline.a
new file mode 100644
index 0000000..7e75a93
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/inline.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/ir.a b/pkg/darwin_amd64/cmd/compile/internal/ir.a
new file mode 100644
index 0000000..1901437
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/ir.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/liveness.a b/pkg/darwin_amd64/cmd/compile/internal/liveness.a
new file mode 100644
index 0000000..f882f58
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/liveness.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/logopt.a b/pkg/darwin_amd64/cmd/compile/internal/logopt.a
index 608a20a..d43e97e 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/logopt.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/logopt.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 bbde5f4..2211af9 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 cb33803..08be30b 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/noder.a b/pkg/darwin_amd64/cmd/compile/internal/noder.a
new file mode 100644
index 0000000..65a83a1
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/noder.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/objw.a b/pkg/darwin_amd64/cmd/compile/internal/objw.a
new file mode 100644
index 0000000..841c3af
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/objw.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/pkginit.a b/pkg/darwin_amd64/cmd/compile/internal/pkginit.a
new file mode 100644
index 0000000..6b961e5
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/pkginit.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 ffaeeaa..9e05655 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/reflectdata.a b/pkg/darwin_amd64/cmd/compile/internal/reflectdata.a
new file mode 100644
index 0000000..4320b11
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/reflectdata.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/riscv64.a b/pkg/darwin_amd64/cmd/compile/internal/riscv64.a
index e635883..34543b9 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/riscv64.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/riscv64.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 ac582c6..07083f4 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 88abe9a..19d6553 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/ssagen.a b/pkg/darwin_amd64/cmd/compile/internal/ssagen.a
new file mode 100644
index 0000000..73287a5
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/ssagen.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/staticdata.a b/pkg/darwin_amd64/cmd/compile/internal/staticdata.a
new file mode 100644
index 0000000..123f4b2
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/staticdata.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/staticinit.a b/pkg/darwin_amd64/cmd/compile/internal/staticinit.a
new file mode 100644
index 0000000..0fc8efb
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/staticinit.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 8141143..c677aa9 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 c297430..e1c50fa 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/typebits.a b/pkg/darwin_amd64/cmd/compile/internal/typebits.a
new file mode 100644
index 0000000..a2f3906
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/typebits.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/typecheck.a b/pkg/darwin_amd64/cmd/compile/internal/typecheck.a
new file mode 100644
index 0000000..67e43a3
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/typecheck.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 0fe5152..0c8b8c3 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/types2.a b/pkg/darwin_amd64/cmd/compile/internal/types2.a
new file mode 100644
index 0000000..e0b86bb
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/types2.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/walk.a b/pkg/darwin_amd64/cmd/compile/internal/walk.a
new file mode 100644
index 0000000..1de227c
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/compile/internal/walk.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/compile/internal/wasm.a b/pkg/darwin_amd64/cmd/compile/internal/wasm.a
index e6ccfe5..54b5bb5 100644
--- a/pkg/darwin_amd64/cmd/compile/internal/wasm.a
+++ b/pkg/darwin_amd64/cmd/compile/internal/wasm.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 e9fd227..6bb110c 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/auth.a b/pkg/darwin_amd64/cmd/go/internal/auth.a
index cb2fe82..8c33062 100644
--- a/pkg/darwin_amd64/cmd/go/internal/auth.a
+++ b/pkg/darwin_amd64/cmd/go/internal/auth.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 c6733d8..a5f357d 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 00141b5..c074002 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/cache.a b/pkg/darwin_amd64/cmd/go/internal/cache.a
index e2366e1..3fde796 100644
--- a/pkg/darwin_amd64/cmd/go/internal/cache.a
+++ 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 22e7826..e6c9ffb 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 4e42359..9294423 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 008f1d4..5232823 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 209b30b..ef8b15d 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 06dead3..fa9c3f5 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 dd8c73a..a4b26fc 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 5096cdb..e255f16 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/fsys.a b/pkg/darwin_amd64/cmd/go/internal/fsys.a
index c6be90d..c58b107 100644
--- a/pkg/darwin_amd64/cmd/go/internal/fsys.a
+++ b/pkg/darwin_amd64/cmd/go/internal/fsys.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 16c5ede..3aa702f 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 16a87e4..9efdc94 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 b38d575..cbcc23e 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/imports.a b/pkg/darwin_amd64/cmd/go/internal/imports.a
index 7641024..bf7dd3a 100644
--- a/pkg/darwin_amd64/cmd/go/internal/imports.a
+++ b/pkg/darwin_amd64/cmd/go/internal/imports.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 d8555f2..adb61b0 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 d5502b7..f3254eb 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/lockedfile.a b/pkg/darwin_amd64/cmd/go/internal/lockedfile.a
index 3c0e789..89a7aa1 100644
--- a/pkg/darwin_amd64/cmd/go/internal/lockedfile.a
+++ b/pkg/darwin_amd64/cmd/go/internal/lockedfile.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/lockedfile/internal/filelock.a b/pkg/darwin_amd64/cmd/go/internal/lockedfile/internal/filelock.a
index 9ea6fdf..e83ce0d 100644
--- a/pkg/darwin_amd64/cmd/go/internal/lockedfile/internal/filelock.a
+++ b/pkg/darwin_amd64/cmd/go/internal/lockedfile/internal/filelock.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/modcmd.a b/pkg/darwin_amd64/cmd/go/internal/modcmd.a
index 1b293b1..2a80e85 100644
--- a/pkg/darwin_amd64/cmd/go/internal/modcmd.a
+++ b/pkg/darwin_amd64/cmd/go/internal/modcmd.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/modconv.a b/pkg/darwin_amd64/cmd/go/internal/modconv.a
index 20787e2..9ff1fbf 100644
--- a/pkg/darwin_amd64/cmd/go/internal/modconv.a
+++ b/pkg/darwin_amd64/cmd/go/internal/modconv.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/modfetch.a b/pkg/darwin_amd64/cmd/go/internal/modfetch.a
index 9ff203c..10a71d4 100644
--- a/pkg/darwin_amd64/cmd/go/internal/modfetch.a
+++ b/pkg/darwin_amd64/cmd/go/internal/modfetch.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/modfetch/codehost.a b/pkg/darwin_amd64/cmd/go/internal/modfetch/codehost.a
index f8521b3..97e0138 100644
--- a/pkg/darwin_amd64/cmd/go/internal/modfetch/codehost.a
+++ b/pkg/darwin_amd64/cmd/go/internal/modfetch/codehost.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/modget.a b/pkg/darwin_amd64/cmd/go/internal/modget.a
index 87cb770..3497922 100644
--- a/pkg/darwin_amd64/cmd/go/internal/modget.a
+++ b/pkg/darwin_amd64/cmd/go/internal/modget.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/modinfo.a b/pkg/darwin_amd64/cmd/go/internal/modinfo.a
index 54a3032..c1f2645 100644
--- a/pkg/darwin_amd64/cmd/go/internal/modinfo.a
+++ b/pkg/darwin_amd64/cmd/go/internal/modinfo.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/modload.a b/pkg/darwin_amd64/cmd/go/internal/modload.a
index 3f8093f..7114692 100644
--- a/pkg/darwin_amd64/cmd/go/internal/modload.a
+++ b/pkg/darwin_amd64/cmd/go/internal/modload.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/mvs.a b/pkg/darwin_amd64/cmd/go/internal/mvs.a
index 9cac4de..0bed949 100644
--- a/pkg/darwin_amd64/cmd/go/internal/mvs.a
+++ b/pkg/darwin_amd64/cmd/go/internal/mvs.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/par.a b/pkg/darwin_amd64/cmd/go/internal/par.a
index ecc7ad9..819b69f 100644
--- a/pkg/darwin_amd64/cmd/go/internal/par.a
+++ b/pkg/darwin_amd64/cmd/go/internal/par.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/renameio.a b/pkg/darwin_amd64/cmd/go/internal/renameio.a
deleted file mode 100644
index 55ff5e6..0000000
--- a/pkg/darwin_amd64/cmd/go/internal/renameio.a
+++ /dev/null
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/robustio.a b/pkg/darwin_amd64/cmd/go/internal/robustio.a
index 592763e..1a40d38 100644
--- a/pkg/darwin_amd64/cmd/go/internal/robustio.a
+++ b/pkg/darwin_amd64/cmd/go/internal/robustio.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 7e68853..42dd518 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/search.a b/pkg/darwin_amd64/cmd/go/internal/search.a
index 780ff44..c4f699a 100644
--- a/pkg/darwin_amd64/cmd/go/internal/search.a
+++ b/pkg/darwin_amd64/cmd/go/internal/search.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 e36491e..fcce149 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 57fe70f..4f5cd3e 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 d1e70a8..66931bc 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/trace.a b/pkg/darwin_amd64/cmd/go/internal/trace.a
index c33db3f..0c001a9 100644
--- a/pkg/darwin_amd64/cmd/go/internal/trace.a
+++ b/pkg/darwin_amd64/cmd/go/internal/trace.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/txtar.a b/pkg/darwin_amd64/cmd/go/internal/txtar.a
index 407e543..3ed5ce7 100644
--- a/pkg/darwin_amd64/cmd/go/internal/txtar.a
+++ b/pkg/darwin_amd64/cmd/go/internal/txtar.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/go/internal/vcs.a b/pkg/darwin_amd64/cmd/go/internal/vcs.a
index 7a71f2a..f1db6c1 100644
--- a/pkg/darwin_amd64/cmd/go/internal/vcs.a
+++ b/pkg/darwin_amd64/cmd/go/internal/vcs.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 951f4fc..84908d3 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 d91831d..c73acf1 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 acd926e..8b0fe29 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 ea61234..2cf5621 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/archive.a b/pkg/darwin_amd64/cmd/internal/archive.a
index ff28128..6796195 100644
--- a/pkg/darwin_amd64/cmd/internal/archive.a
+++ b/pkg/darwin_amd64/cmd/internal/archive.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/bio.a b/pkg/darwin_amd64/cmd/internal/bio.a
index 19b5eff..55b53d8 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 35157c8..26902cb 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
index 943d9ed..6d27fe1 100644
--- a/pkg/darwin_amd64/cmd/internal/buildid.a
+++ b/pkg/darwin_amd64/cmd/internal/buildid.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/codesign.a b/pkg/darwin_amd64/cmd/internal/codesign.a
index 5370674..dd3a9f1 100644
--- a/pkg/darwin_amd64/cmd/internal/codesign.a
+++ b/pkg/darwin_amd64/cmd/internal/codesign.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/diff.a b/pkg/darwin_amd64/cmd/internal/diff.a
index 4742669..1ba990f 100644
--- a/pkg/darwin_amd64/cmd/internal/diff.a
+++ b/pkg/darwin_amd64/cmd/internal/diff.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/dwarf.a b/pkg/darwin_amd64/cmd/internal/dwarf.a
index 7f01c63..9bd58ff 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
index e26bbd0..1102d5b 100644
--- a/pkg/darwin_amd64/cmd/internal/edit.a
+++ 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 373784d..788ee09 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 f3d6c29..c4cab80 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 6cc66a0..9052ae3 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 ff2dff2..a0ab4d8 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 852e2dc..e5a6e5e 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 92b23e1..aa88487 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 2fd0577..380e073 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/riscv.a b/pkg/darwin_amd64/cmd/internal/obj/riscv.a
index 96644c7..d2bd266 100644
--- a/pkg/darwin_amd64/cmd/internal/obj/riscv.a
+++ b/pkg/darwin_amd64/cmd/internal/obj/riscv.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 39ac3a4..fab934f 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/wasm.a b/pkg/darwin_amd64/cmd/internal/obj/wasm.a
index 00a2692..539c4f1 100644
--- a/pkg/darwin_amd64/cmd/internal/obj/wasm.a
+++ b/pkg/darwin_amd64/cmd/internal/obj/wasm.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 7b13f9b..2213e95 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 c54b9a7..dafae25 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 7fe261d..a23c89d 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/pkgpath.a b/pkg/darwin_amd64/cmd/internal/pkgpath.a
index 7a8762b..711c4ce 100644
--- a/pkg/darwin_amd64/cmd/internal/pkgpath.a
+++ b/pkg/darwin_amd64/cmd/internal/pkgpath.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/src.a b/pkg/darwin_amd64/cmd/internal/src.a
index 1ff16ec..a1e4dc8 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 d8ee987..861827b 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
index aca3e43..bdcf22b 100644
--- a/pkg/darwin_amd64/cmd/internal/test2json.a
+++ b/pkg/darwin_amd64/cmd/internal/test2json.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/internal/traceviewer.a b/pkg/darwin_amd64/cmd/internal/traceviewer.a
index 7dcdd85..01aa3a6 100644
--- a/pkg/darwin_amd64/cmd/internal/traceviewer.a
+++ b/pkg/darwin_amd64/cmd/internal/traceviewer.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 b8c9c94..1c374c2 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 f1d715f..8d1238c 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 5f5355d..76ecbbe 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/benchmark.a b/pkg/darwin_amd64/cmd/link/internal/benchmark.a
index 8cd810e..f7cb4c1 100644
--- a/pkg/darwin_amd64/cmd/link/internal/benchmark.a
+++ b/pkg/darwin_amd64/cmd/link/internal/benchmark.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 098d7ba..85d3806 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
index 59df220..beabd67 100644
--- a/pkg/darwin_amd64/cmd/link/internal/loadelf.a
+++ b/pkg/darwin_amd64/cmd/link/internal/loadelf.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/loader.a b/pkg/darwin_amd64/cmd/link/internal/loader.a
index 2d9eecf..1bb1780 100644
--- a/pkg/darwin_amd64/cmd/link/internal/loader.a
+++ b/pkg/darwin_amd64/cmd/link/internal/loader.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/loadmacho.a b/pkg/darwin_amd64/cmd/link/internal/loadmacho.a
index 1042ef5..5ed72f8 100644
--- a/pkg/darwin_amd64/cmd/link/internal/loadmacho.a
+++ 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
index 396bbf5..1eb34d8 100644
--- a/pkg/darwin_amd64/cmd/link/internal/loadpe.a
+++ b/pkg/darwin_amd64/cmd/link/internal/loadpe.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/loadxcoff.a b/pkg/darwin_amd64/cmd/link/internal/loadxcoff.a
index f450b20..2f99fef 100644
--- a/pkg/darwin_amd64/cmd/link/internal/loadxcoff.a
+++ b/pkg/darwin_amd64/cmd/link/internal/loadxcoff.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 263017c..cb555fc 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 be3056b..64a21f5 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/ppc64.a b/pkg/darwin_amd64/cmd/link/internal/ppc64.a
index 4a8610c..55b91b0 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/riscv64.a b/pkg/darwin_amd64/cmd/link/internal/riscv64.a
index 7a54652..cbb5729 100644
--- a/pkg/darwin_amd64/cmd/link/internal/riscv64.a
+++ b/pkg/darwin_amd64/cmd/link/internal/riscv64.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 d19c764..ddebf2a 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
index dc59911..07b1ae4 100644
--- a/pkg/darwin_amd64/cmd/link/internal/sym.a
+++ b/pkg/darwin_amd64/cmd/link/internal/sym.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/link/internal/wasm.a b/pkg/darwin_amd64/cmd/link/internal/wasm.a
index 77b0c96..b80db40 100644
--- a/pkg/darwin_amd64/cmd/link/internal/wasm.a
+++ b/pkg/darwin_amd64/cmd/link/internal/wasm.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 cb2ce93..eee4009 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 e6437c5..d957a2d 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 72b4ca9..7a7d929 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 3bd2583..ece61f9 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 e5815af..374bd6e 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 eceabf3..9406465 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 52efa4b..4740e8a 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 f90c1b4..191138a 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/report.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/report.a
index 75ac5d9..6afcc70 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 8a4d679..5481e7e 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 ba7be5e..ebab6a2 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/internal/transport.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/transport.a
index e1aedc4..89a8561 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/transport.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/internal/transport.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 2703f99..3c2ecef 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/d3.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/d3.a
index 23295ee..3980f41 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/d3.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/d3.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph.a
index 7db7afc..3828068 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/svgpan.a b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/svgpan.a
index 7ec21c2..9f58f4f 100644
--- a/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/svgpan.a
+++ b/pkg/darwin_amd64/cmd/vendor/github.com/google/pprof/third_party/svgpan.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 b963968..703b4e0 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 1d82771..463f2ed 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
index a73ba2f..1f9e4a6 100644
--- 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
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 a6ab0b8..892752f 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 02bd4d1..ac8ee2e 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/vendor/golang.org/x/crypto/ed25519.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/crypto/ed25519.a
index 122c808..c2bf011 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/crypto/ed25519.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/crypto/ed25519.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/crypto/ed25519/internal/edwards25519.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/crypto/ed25519/internal/edwards25519.a
index f6794ab..c71f0f6 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/crypto/ed25519/internal/edwards25519.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/crypto/ed25519/internal/edwards25519.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/crypto/ssh/terminal.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/crypto/ssh/terminal.a
deleted file mode 100644
index 22d4a27..0000000
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/crypto/ssh/terminal.a
+++ /dev/null
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/internal/lazyregexp.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/internal/lazyregexp.a
index f06a9f2..b515723 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/internal/lazyregexp.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/internal/lazyregexp.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/modfile.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/modfile.a
index 0860902..5a8e66b 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/modfile.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/modfile.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/module.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/module.a
index 7625f2c..084444c 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/module.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/module.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/semver.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/semver.a
index 662746b..3d19fac 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/semver.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/semver.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb.a
index 7177a77..8438c13 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb/dirhash.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb/dirhash.a
index 75df729..57abe90 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb/dirhash.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb/dirhash.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb/note.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb/note.a
index 8025ead..0a51bba 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb/note.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb/note.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb/tlog.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb/tlog.a
index 3bf3f96..82a2288 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb/tlog.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/sumdb/tlog.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/zip.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/zip.a
index 13481c9..906b0ae 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/zip.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/mod/zip.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/sys/internal/unsafeheader.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/sys/internal/unsafeheader.a
index 3251039..4eeddc2 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/sys/internal/unsafeheader.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/sys/internal/unsafeheader.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/sys/unix.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/sys/unix.a
index f0e2caa..6d164e3 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/sys/unix.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/sys/unix.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/term.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/term.a
new file mode 100644
index 0000000..4980f12
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/term.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/cover.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/cover.a
new file mode 100644
index 0000000..327f99d
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/cover.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis.a
index 73d8c7a..cd0e412 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/internal/analysisflags.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/internal/analysisflags.a
index 7d04883..22c257f 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/internal/analysisflags.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/internal/analysisflags.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/internal/facts.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/internal/facts.a
index bf4756d..127586c 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/internal/facts.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/internal/facts.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl.a
index 80057e1..a49a367 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/assign.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/assign.a
index fa2bb5c..c977c99 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/assign.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/assign.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/atomic.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/atomic.a
index 4f2f0e5..8e7835f 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/atomic.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/atomic.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/bools.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/bools.a
index 5b78408..1abf52f 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/bools.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/bools.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag.a
index b319146..1d29beb 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/cgocall.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/cgocall.a
index a54264b..bc4e11c 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/cgocall.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/cgocall.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/composite.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/composite.a
index 055c9c5..806b6a5 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/composite.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/composite.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/copylock.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/copylock.a
index 9c591b8..4831b01 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/copylock.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/copylock.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/ctrlflow.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/ctrlflow.a
index f12f6d5..e0cb67d 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/ctrlflow.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/ctrlflow.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/errorsas.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/errorsas.a
index 14fc2f5..8c8c19c 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/errorsas.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/errorsas.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/framepointer.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/framepointer.a
index 148d696..eba2326 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/framepointer.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/framepointer.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/httpresponse.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/httpresponse.a
index 5edb3ba..6d2665f 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/httpresponse.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/httpresponse.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/ifaceassert.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/ifaceassert.a
index 330e9b9..0fdf8e8 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/ifaceassert.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/ifaceassert.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect.a
index 28e5189..b0fcf58 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/internal/analysisutil.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/internal/analysisutil.a
index aed46b5..3ab9deb 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/internal/analysisutil.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/internal/analysisutil.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure.a
index 1f59c7a..b466e91 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/lostcancel.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/lostcancel.a
index d1de2aa..7a87c5f 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/lostcancel.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/lostcancel.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/nilfunc.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/nilfunc.a
index 2215ff7..e2ab929 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/nilfunc.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/nilfunc.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf.a
index 5253e6f..15c0a8d 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/shift.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/shift.a
index 49038e3..afbc10e 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/shift.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/shift.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/sigchanyzer.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/sigchanyzer.a
new file mode 100644
index 0000000..9c4291f
--- /dev/null
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/sigchanyzer.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods.a
index 2a14769..1562422 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/stringintconv.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/stringintconv.a
index 757c45f..75b1ae5 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/stringintconv.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/stringintconv.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag.a
index a7e0ac9..72e3241 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine.a
index debc9ac..ac4699d 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/tests.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/tests.a
index d64fb31..7879fbb 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/tests.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/tests.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unmarshal.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unmarshal.a
index 05c5df3..8b72b89 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unmarshal.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unmarshal.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unreachable.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unreachable.a
index 279d2d3..c84441c 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unreachable.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unreachable.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unsafeptr.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unsafeptr.a
index f6029f7..5e3e23a 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unsafeptr.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unsafeptr.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unusedresult.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unusedresult.a
index 6b86d94..05f6864 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unusedresult.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/passes/unusedresult.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker.a
index c9fc116..7271b60 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/ast/astutil.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/ast/astutil.a
index 73f515f..33d160c 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/ast/astutil.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/ast/astutil.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/ast/inspector.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/ast/inspector.a
index d9501a7..1aa7efd 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/ast/inspector.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/ast/inspector.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/cfg.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/cfg.a
index 2501160..2e75b29 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/cfg.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/cfg.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/types/objectpath.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/types/objectpath.a
index a4f6c08..4b55aa8 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/types/objectpath.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/types/objectpath.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/types/typeutil.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/types/typeutil.a
index cf0a4a3..981a354 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/types/typeutil.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/go/types/typeutil.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/internal/analysisinternal.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/internal/analysisinternal.a
index 456a6a7..e1d30dd 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/internal/analysisinternal.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/internal/analysisinternal.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy.a
index e37999a..e986b37 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/xerrors.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/xerrors.a
index 0f7165f..6a312a2 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/xerrors.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/xerrors.a
Binary files differ
diff --git a/pkg/darwin_amd64/cmd/vendor/golang.org/x/xerrors/internal.a b/pkg/darwin_amd64/cmd/vendor/golang.org/x/xerrors/internal.a
index 40fae17..6056287 100644
--- a/pkg/darwin_amd64/cmd/vendor/golang.org/x/xerrors/internal.a
+++ b/pkg/darwin_amd64/cmd/vendor/golang.org/x/xerrors/internal.a
Binary files differ
diff --git a/pkg/darwin_amd64/compress/bzip2.a b/pkg/darwin_amd64/compress/bzip2.a
index 9eb6568..1c2b2a1 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 cba9a8b..765108f 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 9b40399..841b748 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 3f93f5f..03811dd 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 e35d709..16db51d 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 5afd8ef..2c0ad0f 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 ce46b86..99a43b2 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 33a7846..45c0f0c 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 f981859..64cd9d0 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 41ca0a9..b30dc27 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 d698370..90309cc 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 68a1a17..880623b 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 2181e5a..d83b32f 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 24b255b..1d66db6 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 0c82352..5f17246 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/ed25519.a b/pkg/darwin_amd64/crypto/ed25519.a
index c108291..560fc2e 100644
--- a/pkg/darwin_amd64/crypto/ed25519.a
+++ b/pkg/darwin_amd64/crypto/ed25519.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/ed25519/internal/edwards25519.a b/pkg/darwin_amd64/crypto/ed25519/internal/edwards25519.a
index 31ecf70..decfad4 100644
--- a/pkg/darwin_amd64/crypto/ed25519/internal/edwards25519.a
+++ b/pkg/darwin_amd64/crypto/ed25519/internal/edwards25519.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/ed25519/internal/edwards25519/field.a b/pkg/darwin_amd64/crypto/ed25519/internal/edwards25519/field.a
new file mode 100644
index 0000000..bd95fc7
--- /dev/null
+++ b/pkg/darwin_amd64/crypto/ed25519/internal/edwards25519/field.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/elliptic.a b/pkg/darwin_amd64/crypto/elliptic.a
index 48423b9..989b267 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/elliptic/internal/fiat.a b/pkg/darwin_amd64/crypto/elliptic/internal/fiat.a
new file mode 100644
index 0000000..16140e5
--- /dev/null
+++ b/pkg/darwin_amd64/crypto/elliptic/internal/fiat.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/hmac.a b/pkg/darwin_amd64/crypto/hmac.a
index 109fe39..37064e4 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/randutil.a b/pkg/darwin_amd64/crypto/internal/randutil.a
index b6bcadf..1aa2c40 100644
--- a/pkg/darwin_amd64/crypto/internal/randutil.a
+++ b/pkg/darwin_amd64/crypto/internal/randutil.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/internal/subtle.a b/pkg/darwin_amd64/crypto/internal/subtle.a
index 269bb9e..a064a77 100644
--- a/pkg/darwin_amd64/crypto/internal/subtle.a
+++ b/pkg/darwin_amd64/crypto/internal/subtle.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/md5.a b/pkg/darwin_amd64/crypto/md5.a
index af14f64..8e136ae 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 c3af19f..b0af047 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 0f7b988..9ef6185 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 68ff028..a1f8a3f 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 945fabd..177508f 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 043a6f3..b3b2f72 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 32c7ef1..0b9e0a5 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 4d717f3..224b30a 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 9e61e7e..f8f43b6 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 3bd6f07..78ee030 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/internal/macos.a b/pkg/darwin_amd64/crypto/x509/internal/macos.a
index c0062d6..15e1b08 100644
--- a/pkg/darwin_amd64/crypto/x509/internal/macos.a
+++ b/pkg/darwin_amd64/crypto/x509/internal/macos.a
Binary files differ
diff --git a/pkg/darwin_amd64/crypto/x509/pkix.a b/pkg/darwin_amd64/crypto/x509/pkix.a
index 44a0c88..ce6bae3 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 f453ac1..29f11a6 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 f2a2a6f..41d4bd8 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 6ff5445..3c521dd 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 3f9aae5..1a77142 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 c2ea11f..def0f13 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 1a5bc1b..94e4bb5 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 9f8e063..f82ac0e 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 b8bedd9..1f2e0c1 100644
--- a/pkg/darwin_amd64/debug/plan9obj.a
+++ b/pkg/darwin_amd64/debug/plan9obj.a
Binary files differ
diff --git a/pkg/darwin_amd64/embed.a b/pkg/darwin_amd64/embed.a
index 349c285..4251274 100644
--- a/pkg/darwin_amd64/embed.a
+++ b/pkg/darwin_amd64/embed.a
Binary files differ
diff --git a/pkg/darwin_amd64/encoding.a b/pkg/darwin_amd64/encoding.a
index 46f8844..0ca73bd 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 0558d7a..8bd4d46 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 5c10e6b..ffdebc2 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 a791323..35d8542 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 24d83e6..db306e4 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 6bb84a1..cf58339 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 b594d51..9562169 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 2f6d0f5..e2b7593 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 f04125b..c74e4eb 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 00ad067..445ad77 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 eca26e4..c7582a2 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 d0f6284..e9a178f 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 a56b6f6..03d4cd8 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 717a199..6b72155 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 d3efb50..fc11539 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 8abb2e4..12e798d 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 fc83ceb..fc450a6 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 bbc9255..86eb0a5 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/build/constraint.a b/pkg/darwin_amd64/go/build/constraint.a
index e1fe586..392f757 100644
--- a/pkg/darwin_amd64/go/build/constraint.a
+++ b/pkg/darwin_amd64/go/build/constraint.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/constant.a b/pkg/darwin_amd64/go/constant.a
index 5c3563e..aff8e90 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 ce5bf13..0ac0d4c 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 8b3874a..826c06e 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 dacae72..443d319 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 1a59fc0..c5e4555 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 58928ce..0564655 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 c9ccbb3..53a4c3e 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/internal/typeparams.a b/pkg/darwin_amd64/go/internal/typeparams.a
new file mode 100644
index 0000000..657c1d4
--- /dev/null
+++ b/pkg/darwin_amd64/go/internal/typeparams.a
Binary files differ
diff --git a/pkg/darwin_amd64/go/parser.a b/pkg/darwin_amd64/go/parser.a
index c47d97d..3bab75d 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 3dbd91a..c3f2378 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 fea28df..33dec72 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 a86fef7..b20736c 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 f1dfb92..bd28008 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 e8d1fa7..b9bbc50 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 4a3fad7..d3b118e 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 3016d56..7be8b2b 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 e5b781c..25bcc56 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 9e2cb9b..be15a8b 100644
--- a/pkg/darwin_amd64/hash/fnv.a
+++ b/pkg/darwin_amd64/hash/fnv.a
Binary files differ
diff --git a/pkg/darwin_amd64/hash/maphash.a b/pkg/darwin_amd64/hash/maphash.a
index de94b14..42e698f 100644
--- a/pkg/darwin_amd64/hash/maphash.a
+++ b/pkg/darwin_amd64/hash/maphash.a
Binary files differ
diff --git a/pkg/darwin_amd64/html.a b/pkg/darwin_amd64/html.a
index 47ac8c0..f4e874f 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 18436e8..72e2eb2 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 b789423..ac88c1d 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 00651c6..f9a60f6 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 4d7dc2a..c3fb5c6 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 a882a0c..fc8b00d 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 088d242..7dbc84f 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 813f566..68ddcc9 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 a9f9068..b8a9a6b 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 d59b3dc..989cbdd 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 b10d7c7..b298ca4 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/abi.a b/pkg/darwin_amd64/internal/abi.a
new file mode 100644
index 0000000..4f1ea3c
--- /dev/null
+++ b/pkg/darwin_amd64/internal/abi.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/buildcfg.a b/pkg/darwin_amd64/internal/buildcfg.a
new file mode 100644
index 0000000..a872555
--- /dev/null
+++ b/pkg/darwin_amd64/internal/buildcfg.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/bytealg.a b/pkg/darwin_amd64/internal/bytealg.a
index 03f646b..be66cdd 100644
--- a/pkg/darwin_amd64/internal/bytealg.a
+++ b/pkg/darwin_amd64/internal/bytealg.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/cfg.a b/pkg/darwin_amd64/internal/cfg.a
index 267d55a..124ea81 100644
--- a/pkg/darwin_amd64/internal/cfg.a
+++ b/pkg/darwin_amd64/internal/cfg.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/cpu.a b/pkg/darwin_amd64/internal/cpu.a
index f5a1491..2857a3b 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/execabs.a b/pkg/darwin_amd64/internal/execabs.a
index 936c13d..c188582 100644
--- a/pkg/darwin_amd64/internal/execabs.a
+++ b/pkg/darwin_amd64/internal/execabs.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/fmtsort.a b/pkg/darwin_amd64/internal/fmtsort.a
index 03936d5..eaed43f 100644
--- a/pkg/darwin_amd64/internal/fmtsort.a
+++ b/pkg/darwin_amd64/internal/fmtsort.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/goexperiment.a b/pkg/darwin_amd64/internal/goexperiment.a
new file mode 100644
index 0000000..2d87970
--- /dev/null
+++ b/pkg/darwin_amd64/internal/goexperiment.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/goroot.a b/pkg/darwin_amd64/internal/goroot.a
index 1dad77c..bab29ee 100644
--- a/pkg/darwin_amd64/internal/goroot.a
+++ b/pkg/darwin_amd64/internal/goroot.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/goversion.a b/pkg/darwin_amd64/internal/goversion.a
index 784d34d..372faa9 100644
--- a/pkg/darwin_amd64/internal/goversion.a
+++ b/pkg/darwin_amd64/internal/goversion.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/itoa.a b/pkg/darwin_amd64/internal/itoa.a
new file mode 100644
index 0000000..d1299ef
--- /dev/null
+++ b/pkg/darwin_amd64/internal/itoa.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/lazyregexp.a b/pkg/darwin_amd64/internal/lazyregexp.a
index 28a4795..8df4e54 100644
--- a/pkg/darwin_amd64/internal/lazyregexp.a
+++ b/pkg/darwin_amd64/internal/lazyregexp.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/lazytemplate.a b/pkg/darwin_amd64/internal/lazytemplate.a
index 22f1b6b..588005c 100644
--- a/pkg/darwin_amd64/internal/lazytemplate.a
+++ b/pkg/darwin_amd64/internal/lazytemplate.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/nettrace.a b/pkg/darwin_amd64/internal/nettrace.a
index 69122f5..c884b9f 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/obscuretestdata.a b/pkg/darwin_amd64/internal/obscuretestdata.a
index a398c57..5214ca5 100644
--- a/pkg/darwin_amd64/internal/obscuretestdata.a
+++ b/pkg/darwin_amd64/internal/obscuretestdata.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/oserror.a b/pkg/darwin_amd64/internal/oserror.a
index fa2b392..0d9fa9c 100644
--- a/pkg/darwin_amd64/internal/oserror.a
+++ b/pkg/darwin_amd64/internal/oserror.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/poll.a b/pkg/darwin_amd64/internal/poll.a
index abe68cd..479dafb 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/profile.a b/pkg/darwin_amd64/internal/profile.a
index ce891eb..2ad9adf 100644
--- a/pkg/darwin_amd64/internal/profile.a
+++ b/pkg/darwin_amd64/internal/profile.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/race.a b/pkg/darwin_amd64/internal/race.a
index 2eec4be..a35ccb2 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/reflectlite.a b/pkg/darwin_amd64/internal/reflectlite.a
index be1156c..f58e441 100644
--- a/pkg/darwin_amd64/internal/reflectlite.a
+++ b/pkg/darwin_amd64/internal/reflectlite.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/singleflight.a b/pkg/darwin_amd64/internal/singleflight.a
index 49dbebd..344fa0c 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/execenv.a b/pkg/darwin_amd64/internal/syscall/execenv.a
index 51e9436..c7c690d 100644
--- a/pkg/darwin_amd64/internal/syscall/execenv.a
+++ b/pkg/darwin_amd64/internal/syscall/execenv.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/syscall/unix.a b/pkg/darwin_amd64/internal/syscall/unix.a
index d594001..f6d096f 100644
--- a/pkg/darwin_amd64/internal/syscall/unix.a
+++ b/pkg/darwin_amd64/internal/syscall/unix.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/sysinfo.a b/pkg/darwin_amd64/internal/sysinfo.a
index de5a38c..ef520af 100644
--- a/pkg/darwin_amd64/internal/sysinfo.a
+++ b/pkg/darwin_amd64/internal/sysinfo.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/testenv.a b/pkg/darwin_amd64/internal/testenv.a
index f4661c1..0cb8475 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
index 1f74f51..38611f0 100644
--- a/pkg/darwin_amd64/internal/testlog.a
+++ 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 28b0f0d..9d37436 100644
--- a/pkg/darwin_amd64/internal/trace.a
+++ b/pkg/darwin_amd64/internal/trace.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/unsafeheader.a b/pkg/darwin_amd64/internal/unsafeheader.a
index 1c87c30..1dfdece 100644
--- a/pkg/darwin_amd64/internal/unsafeheader.a
+++ b/pkg/darwin_amd64/internal/unsafeheader.a
Binary files differ
diff --git a/pkg/darwin_amd64/internal/xcoff.a b/pkg/darwin_amd64/internal/xcoff.a
index c18d440..6d80617 100644
--- a/pkg/darwin_amd64/internal/xcoff.a
+++ b/pkg/darwin_amd64/internal/xcoff.a
Binary files differ
diff --git a/pkg/darwin_amd64/io.a b/pkg/darwin_amd64/io.a
index 507ce0c..dc935b0 100644
--- a/pkg/darwin_amd64/io.a
+++ b/pkg/darwin_amd64/io.a
Binary files differ
diff --git a/pkg/darwin_amd64/io/fs.a b/pkg/darwin_amd64/io/fs.a
index 69ddf4d..53c878b 100644
--- a/pkg/darwin_amd64/io/fs.a
+++ b/pkg/darwin_amd64/io/fs.a
Binary files differ
diff --git a/pkg/darwin_amd64/io/ioutil.a b/pkg/darwin_amd64/io/ioutil.a
index fd7df01..10a7ba5 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 0ba88ad..5a8d916 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 e660580..026d482 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 623fdf3..2b5221d 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 98b2a96..a824b43 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 e5ae75c..57d0868 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 aa84415..6a470fe 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 72d02cd..0c0bcec 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 92842b0..e282763 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 c309393..d3849ee 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 164a8e7c..d97d5c6 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 7df71c8..c33e852 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 84726a5..5c0a230 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 70f666d..2bf6b58 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 5b269ea..fcaf2cf 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 3c23ea5..9a20bd3 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 75e524e..e819ace 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 4d5e9d0..1379700 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 23320cb..9c7c935 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 0f0468f..514c3da 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/internal/ascii.a b/pkg/darwin_amd64/net/http/internal/ascii.a
new file mode 100644
index 0000000..fa25a30
--- /dev/null
+++ b/pkg/darwin_amd64/net/http/internal/ascii.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/http/internal/testcert.a b/pkg/darwin_amd64/net/http/internal/testcert.a
new file mode 100644
index 0000000..1af55fe
--- /dev/null
+++ b/pkg/darwin_amd64/net/http/internal/testcert.a
Binary files differ
diff --git a/pkg/darwin_amd64/net/http/pprof.a b/pkg/darwin_amd64/net/http/pprof.a
index f88dfa7..cf7d9b2 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 4671156..e466aea 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 4738cd1..0336f86 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 38315e5..6321d92 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 ad70220..911b77d 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 a1744fa..4ab1d00 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 c004f2e..94ffc5f 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 accd394..149738b 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 e9e747d..4937ba9 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 dbfff3c..8bf5a06 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 0f949e2..065ccb0 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
index b334695..6113494 100644
--- a/pkg/darwin_amd64/os/signal/internal/pty.a
+++ 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 2d46207..17c3d90 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 b1975a1..5a0d611 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 b7f7842..39d32d7 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 cfb298f..1ae9916 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 8dbaaef..fbe9ff8 100644
--- a/pkg/darwin_amd64/reflect.a
+++ b/pkg/darwin_amd64/reflect.a
Binary files differ
diff --git a/pkg/darwin_amd64/reflect/internal/example1.a b/pkg/darwin_amd64/reflect/internal/example1.a
new file mode 100644
index 0000000..c1a2742
--- /dev/null
+++ b/pkg/darwin_amd64/reflect/internal/example1.a
Binary files differ
diff --git a/pkg/darwin_amd64/reflect/internal/example2.a b/pkg/darwin_amd64/reflect/internal/example2.a
new file mode 100644
index 0000000..b3a1562
--- /dev/null
+++ b/pkg/darwin_amd64/reflect/internal/example2.a
Binary files differ
diff --git a/pkg/darwin_amd64/regexp.a b/pkg/darwin_amd64/regexp.a
index c3067d9..301386d 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 78df60f..60937ac 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 c665bef..9de21cd 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 a764bd7..7fc28eb 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 9c7fd33..6922d0c 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 6dffef2..45df108 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/math.a b/pkg/darwin_amd64/runtime/internal/math.a
index aca45a2..76fdab2 100644
--- a/pkg/darwin_amd64/runtime/internal/math.a
+++ b/pkg/darwin_amd64/runtime/internal/math.a
Binary files differ
diff --git a/pkg/darwin_amd64/runtime/internal/sys.a b/pkg/darwin_amd64/runtime/internal/sys.a
index 998f5b6..2961848 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/metrics.a b/pkg/darwin_amd64/runtime/metrics.a
index db2c7da..97c4fac 100644
--- a/pkg/darwin_amd64/runtime/metrics.a
+++ b/pkg/darwin_amd64/runtime/metrics.a
Binary files differ
diff --git a/pkg/darwin_amd64/runtime/pprof.a b/pkg/darwin_amd64/runtime/pprof.a
index 6a4348f..c3702f8 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/race.a b/pkg/darwin_amd64/runtime/race.a
index fb8039e..eebdba5 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 ac9cc13..6a41cad 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 8d31e2e..9b39ca3 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 6998dbe..bcc0bd4 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 f64af48..aee238f 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 211fb6a..3b8f635 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 0e4e207..15dea67 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 0e0061a..99574d1 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 d38a6d5..170572c 100644
--- a/pkg/darwin_amd64/testing.a
+++ b/pkg/darwin_amd64/testing.a
Binary files differ
diff --git a/pkg/darwin_amd64/testing/fstest.a b/pkg/darwin_amd64/testing/fstest.a
index 2e1b1b0..79c5992 100644
--- a/pkg/darwin_amd64/testing/fstest.a
+++ b/pkg/darwin_amd64/testing/fstest.a
Binary files differ
diff --git a/pkg/darwin_amd64/testing/internal/testdeps.a b/pkg/darwin_amd64/testing/internal/testdeps.a
index 8982dac..5850eb7 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 267b1d1..c1bba94 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 0e1368c..3d867da 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 4aa7eb1..599e657 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 640a8bb..5faa41c 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 6946ea6..eeaea4d 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 5c681ed..1d43b0d 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 f107c3b..4e601b5 100644
--- a/pkg/darwin_amd64/time.a
+++ b/pkg/darwin_amd64/time.a
Binary files differ
diff --git a/pkg/darwin_amd64/time/tzdata.a b/pkg/darwin_amd64/time/tzdata.a
index 44db976..441dfe2 100644
--- a/pkg/darwin_amd64/time/tzdata.a
+++ b/pkg/darwin_amd64/time/tzdata.a
Binary files differ
diff --git a/pkg/darwin_amd64/unicode.a b/pkg/darwin_amd64/unicode.a
index 2bbba48..06de8f7 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 db5f5d4..b2ea13f 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 47f6d8f..f9cf7e2 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/chacha20.a b/pkg/darwin_amd64/vendor/golang.org/x/crypto/chacha20.a
index 58c9b0c..bc29ab8 100644
--- a/pkg/darwin_amd64/vendor/golang.org/x/crypto/chacha20.a
+++ b/pkg/darwin_amd64/vendor/golang.org/x/crypto/chacha20.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 2f95ec5..900e166 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/cryptobyte.a b/pkg/darwin_amd64/vendor/golang.org/x/crypto/cryptobyte.a
index 1b40791..7f3a79e 100644
--- a/pkg/darwin_amd64/vendor/golang.org/x/crypto/cryptobyte.a
+++ 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
index e2d04ae..1294fae 100644
--- a/pkg/darwin_amd64/vendor/golang.org/x/crypto/cryptobyte/asn1.a
+++ 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 9bfedae..41ce0b3 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/hkdf.a b/pkg/darwin_amd64/vendor/golang.org/x/crypto/hkdf.a
index 41de042..61982db 100644
--- a/pkg/darwin_amd64/vendor/golang.org/x/crypto/hkdf.a
+++ b/pkg/darwin_amd64/vendor/golang.org/x/crypto/hkdf.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang.org/x/crypto/internal/subtle.a b/pkg/darwin_amd64/vendor/golang.org/x/crypto/internal/subtle.a
index a36dd28..879c968 100644
--- a/pkg/darwin_amd64/vendor/golang.org/x/crypto/internal/subtle.a
+++ b/pkg/darwin_amd64/vendor/golang.org/x/crypto/internal/subtle.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 06d5268..0b50c2d 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/dns/dnsmessage.a b/pkg/darwin_amd64/vendor/golang.org/x/net/dns/dnsmessage.a
index 3151039..049c090 100644
--- a/pkg/darwin_amd64/vendor/golang.org/x/net/dns/dnsmessage.a
+++ b/pkg/darwin_amd64/vendor/golang.org/x/net/dns/dnsmessage.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang.org/x/net/http/httpguts.a b/pkg/darwin_amd64/vendor/golang.org/x/net/http/httpguts.a
index 2ea2209..614d5b2 100644
--- a/pkg/darwin_amd64/vendor/golang.org/x/net/http/httpguts.a
+++ b/pkg/darwin_amd64/vendor/golang.org/x/net/http/httpguts.a
Binary files differ
diff --git a/pkg/darwin_amd64/vendor/golang.org/x/net/http/httpproxy.a b/pkg/darwin_amd64/vendor/golang.org/x/net/http/httpproxy.a
index 5aa8493..7fee57a 100644
--- a/pkg/darwin_amd64/vendor/golang.org/x/net/http/httpproxy.a
+++ b/pkg/darwin_amd64/vendor/golang.org/x/net/http/httpproxy.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 6dc5663..a9b1554 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 173f550..4f7ef18 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/nettest.a b/pkg/darwin_amd64/vendor/golang.org/x/net/nettest.a
index 3200801..e6ee583 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/route.a b/pkg/darwin_amd64/vendor/golang.org/x/net/route.a
index 29601b1..c2b4aa6 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/sys/cpu.a b/pkg/darwin_amd64/vendor/golang.org/x/sys/cpu.a
index abfa865..11ef92f 100644
--- a/pkg/darwin_amd64/vendor/golang.org/x/sys/cpu.a
+++ b/pkg/darwin_amd64/vendor/golang.org/x/sys/cpu.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 c720ce9..41c553b 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 8de2a70..47241ff 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/bidi.a b/pkg/darwin_amd64/vendor/golang.org/x/text/unicode/bidi.a
index 095e5b9..a00789f 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 eac59db..3a78502 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 e6ea27b..43a00c4 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 7ea686b..7f52568 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 79c359a..09be1f6 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 6d4ddc4..48d7cce 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 a4ef53c..824430f 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 d2a218c..f65136e 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 45fb46c..9d0d729 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 b1fc1df..91eaa81 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 63f5f36..a9da065 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 c24f83b..46e96dd 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 b4e6995..601efd5 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 dacc11f..bd05e88 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 6c80b8d..5b5bbbb 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 eb41544..4dc10d8 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 b5f411e..e8a9f0e 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 ed8bc94..6191ea8 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 09fe9ba..8b4fae8 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 a90c3b9..6f7a9ba 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 e9291f1..ca1c574 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/ed25519.a b/pkg/darwin_amd64_race/crypto/ed25519.a
index f8cdea5..5f2f78c 100644
--- a/pkg/darwin_amd64_race/crypto/ed25519.a
+++ b/pkg/darwin_amd64_race/crypto/ed25519.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/ed25519/internal/edwards25519.a b/pkg/darwin_amd64_race/crypto/ed25519/internal/edwards25519.a
index 3c4d535..f0f1c6a 100644
--- a/pkg/darwin_amd64_race/crypto/ed25519/internal/edwards25519.a
+++ b/pkg/darwin_amd64_race/crypto/ed25519/internal/edwards25519.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/ed25519/internal/edwards25519/field.a b/pkg/darwin_amd64_race/crypto/ed25519/internal/edwards25519/field.a
new file mode 100644
index 0000000..7b3cfb8
--- /dev/null
+++ b/pkg/darwin_amd64_race/crypto/ed25519/internal/edwards25519/field.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/elliptic.a b/pkg/darwin_amd64_race/crypto/elliptic.a
index 181d1df..06d417a 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/elliptic/internal/fiat.a b/pkg/darwin_amd64_race/crypto/elliptic/internal/fiat.a
new file mode 100644
index 0000000..68b1568
--- /dev/null
+++ b/pkg/darwin_amd64_race/crypto/elliptic/internal/fiat.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/hmac.a b/pkg/darwin_amd64_race/crypto/hmac.a
index 8bc8c31..97df31c 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/randutil.a b/pkg/darwin_amd64_race/crypto/internal/randutil.a
index 672fa82..37b7070 100644
--- a/pkg/darwin_amd64_race/crypto/internal/randutil.a
+++ b/pkg/darwin_amd64_race/crypto/internal/randutil.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/internal/subtle.a b/pkg/darwin_amd64_race/crypto/internal/subtle.a
index e942c66..c60b1cb 100644
--- a/pkg/darwin_amd64_race/crypto/internal/subtle.a
+++ b/pkg/darwin_amd64_race/crypto/internal/subtle.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/crypto/md5.a b/pkg/darwin_amd64_race/crypto/md5.a
index 47102ed..09f1af6 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 9ff8c57..ef38578 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 7f2ce19..1663ee3 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 12ce01d..aaf5070 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 da1dd28..0e60c2b 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 9165223..bf570e6 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 0db005c..bc05245 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 815e7ff..b0ec892 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 de6627f..0f2c953 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 b52f276..19158ed 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/internal/macos.a b/pkg/darwin_amd64_race/crypto/x509/internal/macos.a
index 3acd73f..22280ab 100644
--- a/pkg/darwin_amd64_race/crypto/x509/internal/macos.a
+++ b/pkg/darwin_amd64_race/crypto/x509/internal/macos.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 308cd0c..a83e20b 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 19cabb3..1c7de95 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 da52dfb..8c7e72b 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 2d6fc61..ca92bc8 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 ca024e2..93a78d0 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 cef1c7e..084e56f 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 e83527f..fc4094a 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 04ba4c0..d4a9bb2 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 17ad213..11e2620 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/embed.a b/pkg/darwin_amd64_race/embed.a
index f104bc7..618543a 100644
--- a/pkg/darwin_amd64_race/embed.a
+++ b/pkg/darwin_amd64_race/embed.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/encoding.a b/pkg/darwin_amd64_race/encoding.a
index 924bdb6..32265bd 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 0a928f0..d1efa07 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 806665c..1f50473 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 b296442..5ba0928 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 1ea0780..fd4011f 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 5343e4b..6c28332 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 a24cbb5..5a14990 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 e1e1935..0fffd2c 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 a9223f0..3da8d8e 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 5d08088..372a8a2 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 f3dae8c..532bc21 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 bb2f218..c76ba61 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 7dd99d1..c19cc01 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 f9de04a..2480d5f 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 8ff6954..b328efe 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 616336a..7be4003 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 e10dcf9..f295fce 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 b5691f2..3d19cda 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/build/constraint.a b/pkg/darwin_amd64_race/go/build/constraint.a
index 8991642..465e98d 100644
--- a/pkg/darwin_amd64_race/go/build/constraint.a
+++ b/pkg/darwin_amd64_race/go/build/constraint.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/constant.a b/pkg/darwin_amd64_race/go/constant.a
index ef7f402..b14efd3 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 a1c7f84..15c3c3c 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 8c7b9ca..575a1ac 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 9bef429..cdab6ad 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 275f885..2874a2b 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 c98b459..0691cf3 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 7cd9c83..192ba42 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/internal/typeparams.a b/pkg/darwin_amd64_race/go/internal/typeparams.a
new file mode 100644
index 0000000..b9e156c
--- /dev/null
+++ b/pkg/darwin_amd64_race/go/internal/typeparams.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/go/parser.a b/pkg/darwin_amd64_race/go/parser.a
index cd384ed..8a540e5 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 5bb90ad..f4de554 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 7d5ad75..7509475 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 5503bf2..1ce0193 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 b5478f4..8cbb6cc 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 37948b8..c26de7f 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 7b7dede..1981992 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 5afe8d6..6f86339 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 78a9418..2a85b15 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 1e86ffc..0f9ee14 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/hash/maphash.a b/pkg/darwin_amd64_race/hash/maphash.a
index a86aef6..1faf317 100644
--- a/pkg/darwin_amd64_race/hash/maphash.a
+++ b/pkg/darwin_amd64_race/hash/maphash.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/html.a b/pkg/darwin_amd64_race/html.a
index 243c375..138a526 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 9bf87da..e1bcb9a 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 c628a17..daed2b5 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 2c5db4c..7ab05ff 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 77cf897..dbb7de8 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 f5b3155..d4a2d1b 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 0e5e4ba..1ce7d8e 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 a4e2b77..8c2a416 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 1762b5e..a52aa23 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 6cc4452..dabedef 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 3f158e7..e411a13 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/abi.a b/pkg/darwin_amd64_race/internal/abi.a
new file mode 100644
index 0000000..1edc6be
--- /dev/null
+++ b/pkg/darwin_amd64_race/internal/abi.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/buildcfg.a b/pkg/darwin_amd64_race/internal/buildcfg.a
new file mode 100644
index 0000000..a83e6f2
--- /dev/null
+++ b/pkg/darwin_amd64_race/internal/buildcfg.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/bytealg.a b/pkg/darwin_amd64_race/internal/bytealg.a
index 3db38a6..5c49d1e 100644
--- a/pkg/darwin_amd64_race/internal/bytealg.a
+++ b/pkg/darwin_amd64_race/internal/bytealg.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/cfg.a b/pkg/darwin_amd64_race/internal/cfg.a
index 14175ea..7722454 100644
--- a/pkg/darwin_amd64_race/internal/cfg.a
+++ b/pkg/darwin_amd64_race/internal/cfg.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/cpu.a b/pkg/darwin_amd64_race/internal/cpu.a
index cd42c65..22c506a 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/execabs.a b/pkg/darwin_amd64_race/internal/execabs.a
index da3f2e6..6f5eaee 100644
--- a/pkg/darwin_amd64_race/internal/execabs.a
+++ b/pkg/darwin_amd64_race/internal/execabs.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/fmtsort.a b/pkg/darwin_amd64_race/internal/fmtsort.a
index d9fca51..e40be9a 100644
--- a/pkg/darwin_amd64_race/internal/fmtsort.a
+++ b/pkg/darwin_amd64_race/internal/fmtsort.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/goexperiment.a b/pkg/darwin_amd64_race/internal/goexperiment.a
new file mode 100644
index 0000000..9c65999
--- /dev/null
+++ b/pkg/darwin_amd64_race/internal/goexperiment.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/goroot.a b/pkg/darwin_amd64_race/internal/goroot.a
index 4843450..d274f43 100644
--- a/pkg/darwin_amd64_race/internal/goroot.a
+++ b/pkg/darwin_amd64_race/internal/goroot.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/goversion.a b/pkg/darwin_amd64_race/internal/goversion.a
index 2a84790..21a6eef 100644
--- a/pkg/darwin_amd64_race/internal/goversion.a
+++ b/pkg/darwin_amd64_race/internal/goversion.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/itoa.a b/pkg/darwin_amd64_race/internal/itoa.a
new file mode 100644
index 0000000..aaefbe0
--- /dev/null
+++ b/pkg/darwin_amd64_race/internal/itoa.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/lazyregexp.a b/pkg/darwin_amd64_race/internal/lazyregexp.a
index e453db9..b0a5aae 100644
--- a/pkg/darwin_amd64_race/internal/lazyregexp.a
+++ b/pkg/darwin_amd64_race/internal/lazyregexp.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/lazytemplate.a b/pkg/darwin_amd64_race/internal/lazytemplate.a
index 4851b4a..7476b8a 100644
--- a/pkg/darwin_amd64_race/internal/lazytemplate.a
+++ b/pkg/darwin_amd64_race/internal/lazytemplate.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/nettrace.a b/pkg/darwin_amd64_race/internal/nettrace.a
index 77de270..b86a76f 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/obscuretestdata.a b/pkg/darwin_amd64_race/internal/obscuretestdata.a
index 3e26a6d..eeee143 100644
--- a/pkg/darwin_amd64_race/internal/obscuretestdata.a
+++ b/pkg/darwin_amd64_race/internal/obscuretestdata.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/oserror.a b/pkg/darwin_amd64_race/internal/oserror.a
index 9b768ff..e1daa52 100644
--- a/pkg/darwin_amd64_race/internal/oserror.a
+++ b/pkg/darwin_amd64_race/internal/oserror.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/poll.a b/pkg/darwin_amd64_race/internal/poll.a
index ebc23c0..103e2e5 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/profile.a b/pkg/darwin_amd64_race/internal/profile.a
index c819f1d..733070a 100644
--- a/pkg/darwin_amd64_race/internal/profile.a
+++ b/pkg/darwin_amd64_race/internal/profile.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/race.a b/pkg/darwin_amd64_race/internal/race.a
index 1cfaa87..57d7587 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/reflectlite.a b/pkg/darwin_amd64_race/internal/reflectlite.a
index 7b40b7a..d3f2aea 100644
--- a/pkg/darwin_amd64_race/internal/reflectlite.a
+++ b/pkg/darwin_amd64_race/internal/reflectlite.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/singleflight.a b/pkg/darwin_amd64_race/internal/singleflight.a
index 96d28cf..927fe90 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/execenv.a b/pkg/darwin_amd64_race/internal/syscall/execenv.a
index c85b2d1..b69a851 100644
--- a/pkg/darwin_amd64_race/internal/syscall/execenv.a
+++ b/pkg/darwin_amd64_race/internal/syscall/execenv.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/syscall/unix.a b/pkg/darwin_amd64_race/internal/syscall/unix.a
index 46b1cac..957907c 100644
--- a/pkg/darwin_amd64_race/internal/syscall/unix.a
+++ b/pkg/darwin_amd64_race/internal/syscall/unix.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/sysinfo.a b/pkg/darwin_amd64_race/internal/sysinfo.a
index 69ce35d..5f1b53b 100644
--- a/pkg/darwin_amd64_race/internal/sysinfo.a
+++ b/pkg/darwin_amd64_race/internal/sysinfo.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/testenv.a b/pkg/darwin_amd64_race/internal/testenv.a
index f71e4ef..912e1ad 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
index 3bb44e9..7c2d2f3 100644
--- a/pkg/darwin_amd64_race/internal/testlog.a
+++ 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 607767c..9fe5bed 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/internal/unsafeheader.a b/pkg/darwin_amd64_race/internal/unsafeheader.a
index 0e18eeb..ea7cfe2 100644
--- a/pkg/darwin_amd64_race/internal/unsafeheader.a
+++ b/pkg/darwin_amd64_race/internal/unsafeheader.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/internal/xcoff.a b/pkg/darwin_amd64_race/internal/xcoff.a
index b6d1b2e..2ef2bc1 100644
--- a/pkg/darwin_amd64_race/internal/xcoff.a
+++ b/pkg/darwin_amd64_race/internal/xcoff.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/io.a b/pkg/darwin_amd64_race/io.a
index c2af217..da9831d 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/fs.a b/pkg/darwin_amd64_race/io/fs.a
index 39519b3..28feba3 100644
--- a/pkg/darwin_amd64_race/io/fs.a
+++ b/pkg/darwin_amd64_race/io/fs.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/io/ioutil.a b/pkg/darwin_amd64_race/io/ioutil.a
index ee22450..91bc9d8 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 c31488c..b04d6e2 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 f52df3a..b339ec2 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 f9b5c8e..97ca987 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 ce0bdf0..d1df25d 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 9dbe9a9..f78b2fa 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 2311b38..cb1b826 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 02c4be1..6b54038 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 9b0dd41..078777c 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 ec26318..9d8eedf 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 52d3498..a2a49c8 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 2efd53e..997e877 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 b367c0b..c724a1e 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 d5f6d73..6f1acbe 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 1494758..137d859 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 fcf7965..c439920 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 3820c25..4f4e56b 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 f673471..fb06bdc 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 568b45d..9b96fc8 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 3fb5d8d..874b893 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/internal/ascii.a b/pkg/darwin_amd64_race/net/http/internal/ascii.a
new file mode 100644
index 0000000..a8e5cf4
--- /dev/null
+++ b/pkg/darwin_amd64_race/net/http/internal/ascii.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/net/http/internal/testcert.a b/pkg/darwin_amd64_race/net/http/internal/testcert.a
new file mode 100644
index 0000000..c54d92a
--- /dev/null
+++ b/pkg/darwin_amd64_race/net/http/internal/testcert.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 066eaba..8993013 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 5111c4b..1f4ec60 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 bc69733..f81da58 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 ded786d..8d4512d 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 59d1e0c..6a5f924 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 1959155..1653a8f 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 baf9c86..e8530b7 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 b323c7f..f5b5211 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 f420180..4a6f9f8 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 a2aa046..3d1d806 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 dfbf23f..26d3092 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
index 08c8ce5..cc63c14 100644
--- a/pkg/darwin_amd64_race/os/signal/internal/pty.a
+++ 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 2c14646..b216c28 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 57798af..58f96ca 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 910a165..d4915fa 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 ed5d292..03cfc18 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 6e9062a..289357a 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/reflect/internal/example1.a b/pkg/darwin_amd64_race/reflect/internal/example1.a
new file mode 100644
index 0000000..43dc9d2
--- /dev/null
+++ b/pkg/darwin_amd64_race/reflect/internal/example1.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/reflect/internal/example2.a b/pkg/darwin_amd64_race/reflect/internal/example2.a
new file mode 100644
index 0000000..48898cf
--- /dev/null
+++ b/pkg/darwin_amd64_race/reflect/internal/example2.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/regexp.a b/pkg/darwin_amd64_race/regexp.a
index 1418856..4766acf 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 b79e172..fb572d4 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 489d876..5c36ea8 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 ad68af2..5a7b056 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 b5939fd..95fa9d6 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 89b8f41..4e5657b 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/math.a b/pkg/darwin_amd64_race/runtime/internal/math.a
index bbd48a7..b13e7de 100644
--- a/pkg/darwin_amd64_race/runtime/internal/math.a
+++ b/pkg/darwin_amd64_race/runtime/internal/math.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 4d808ef..6c5c1c8 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/metrics.a b/pkg/darwin_amd64_race/runtime/metrics.a
index d776cae..984416d 100644
--- a/pkg/darwin_amd64_race/runtime/metrics.a
+++ b/pkg/darwin_amd64_race/runtime/metrics.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/runtime/pprof.a b/pkg/darwin_amd64_race/runtime/pprof.a
index 8493f7a..4539832 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/race.a b/pkg/darwin_amd64_race/runtime/race.a
index dbd5dbc..37ceddc 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 0ddb016..be378fc 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 c15a504..c9df3f2 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 8974f22..981b8a1 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 723a36e..e8b1bdc 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 0d82c97..f214368 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 c3a00f8..7f84d73 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 8d26d50..7608b3e 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 72ca15d..b24090b 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/fstest.a b/pkg/darwin_amd64_race/testing/fstest.a
index 68fc57e..1fb7fbc 100644
--- a/pkg/darwin_amd64_race/testing/fstest.a
+++ b/pkg/darwin_amd64_race/testing/fstest.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 2c801c7..f2900b3 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 b10b394..3e2e2f1 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 d24e56e..58a3a43 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 adaa112..d562e2f 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 9f9627e..3a23508 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 06b2d08..dc2f119 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 1f88f2f..70e4291 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 4d05cec..9c927ca 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/time/tzdata.a b/pkg/darwin_amd64_race/time/tzdata.a
index 7e9d027..9d175f2 100644
--- a/pkg/darwin_amd64_race/time/tzdata.a
+++ b/pkg/darwin_amd64_race/time/tzdata.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/unicode.a b/pkg/darwin_amd64_race/unicode.a
index dc8bd5c..f4ceb53 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 0be3e59..5a5ef47 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 ca33a97..d9085e9 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/chacha20.a b/pkg/darwin_amd64_race/vendor/golang.org/x/crypto/chacha20.a
index ad2a23b..2ee527a 100644
--- a/pkg/darwin_amd64_race/vendor/golang.org/x/crypto/chacha20.a
+++ b/pkg/darwin_amd64_race/vendor/golang.org/x/crypto/chacha20.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 fbd1050..1cdcd32 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/cryptobyte.a b/pkg/darwin_amd64_race/vendor/golang.org/x/crypto/cryptobyte.a
index 534349c..7615a5b 100644
--- a/pkg/darwin_amd64_race/vendor/golang.org/x/crypto/cryptobyte.a
+++ 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
index d9dc00b..d13b07c 100644
--- 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
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 95e32cb..3f5c55e 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/hkdf.a b/pkg/darwin_amd64_race/vendor/golang.org/x/crypto/hkdf.a
index b74568c..d95c4a3 100644
--- a/pkg/darwin_amd64_race/vendor/golang.org/x/crypto/hkdf.a
+++ b/pkg/darwin_amd64_race/vendor/golang.org/x/crypto/hkdf.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang.org/x/crypto/internal/subtle.a b/pkg/darwin_amd64_race/vendor/golang.org/x/crypto/internal/subtle.a
index b8d3afe..3600847 100644
--- a/pkg/darwin_amd64_race/vendor/golang.org/x/crypto/internal/subtle.a
+++ b/pkg/darwin_amd64_race/vendor/golang.org/x/crypto/internal/subtle.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 0fe24b7..07d0d45 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/dns/dnsmessage.a b/pkg/darwin_amd64_race/vendor/golang.org/x/net/dns/dnsmessage.a
index 5a65065..ac67e5d 100644
--- a/pkg/darwin_amd64_race/vendor/golang.org/x/net/dns/dnsmessage.a
+++ b/pkg/darwin_amd64_race/vendor/golang.org/x/net/dns/dnsmessage.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang.org/x/net/http/httpguts.a b/pkg/darwin_amd64_race/vendor/golang.org/x/net/http/httpguts.a
index f5eaf16..d56b772 100644
--- a/pkg/darwin_amd64_race/vendor/golang.org/x/net/http/httpguts.a
+++ b/pkg/darwin_amd64_race/vendor/golang.org/x/net/http/httpguts.a
Binary files differ
diff --git a/pkg/darwin_amd64_race/vendor/golang.org/x/net/http/httpproxy.a b/pkg/darwin_amd64_race/vendor/golang.org/x/net/http/httpproxy.a
index 3549a8c..7c43a53 100644
--- a/pkg/darwin_amd64_race/vendor/golang.org/x/net/http/httpproxy.a
+++ b/pkg/darwin_amd64_race/vendor/golang.org/x/net/http/httpproxy.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 aa8eb57..0c19d88 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 905f7e6..10accd6 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/nettest.a b/pkg/darwin_amd64_race/vendor/golang.org/x/net/nettest.a
index 8231857..8ac8990 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/route.a b/pkg/darwin_amd64_race/vendor/golang.org/x/net/route.a
index 50d0517..461e53d 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/sys/cpu.a b/pkg/darwin_amd64_race/vendor/golang.org/x/sys/cpu.a
index c1e3f2a..ab07102 100644
--- a/pkg/darwin_amd64_race/vendor/golang.org/x/sys/cpu.a
+++ b/pkg/darwin_amd64_race/vendor/golang.org/x/sys/cpu.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 c8626a2..bce206c 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 fdbea8d..b28860a 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/bidi.a b/pkg/darwin_amd64_race/vendor/golang.org/x/text/unicode/bidi.a
index df15906..6ba571b 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 8e23a9c..6641068 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/include/funcdata.h b/pkg/include/funcdata.h
index 798dbac..1002b18 100644
--- a/pkg/include/funcdata.h
+++ b/pkg/include/funcdata.h
@@ -17,6 +17,7 @@
 #define FUNCDATA_StackObjects 2
 #define FUNCDATA_InlTree 3
 #define FUNCDATA_OpenCodedDeferInfo 4 /* info for func with open-coded defers */
+#define FUNCDATA_ArgInfo 5
 
 // Pseudo-assembly statements.
 
diff --git a/pkg/include/textflag.h b/pkg/include/textflag.h
index daca36d..214075e 100644
--- a/pkg/include/textflag.h
+++ b/pkg/include/textflag.h
@@ -32,6 +32,8 @@
 #define NOFRAME 512
 // Function can call reflect.Type.Method or reflect.Type.MethodByName.
 #define REFLECTMETHOD 1024
-// Function is the top of the call stack. Call stack unwinders should stop
-// at this function.
+// Function is the outermost frame of the call stack. Call stack unwinders
+// should stop at this function.
 #define TOPFRAME 2048
+// Function is an ABI wrapper.
+#define ABIWRAPPER 4096
diff --git a/pkg/tool/darwin_amd64/addr2line b/pkg/tool/darwin_amd64/addr2line
index a05a8ab..95c60de 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 0138f8f..0cbad10 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 e061056..09a6cf3 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
index f53fb9e..9409878 100755
--- a/pkg/tool/darwin_amd64/buildid
+++ b/pkg/tool/darwin_amd64/buildid
Binary files differ
diff --git a/pkg/tool/darwin_amd64/cgo b/pkg/tool/darwin_amd64/cgo
index 0ee6393..a6e3200 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 f08ca20..583571a 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 50c256b..6e5b3ef 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 aa29ef9..c891c08 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 0a8c3d8..d4e51c1 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 e85a40b..41149fb 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 e78ce5f..9040dc2 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 4e2601e..9d69090 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 a4c7384..a7fbac2 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 15af122..9587d76 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 6b2a8f3..a43f9e9 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
index 47fec85..ba87ebb 100755
--- a/pkg/tool/darwin_amd64/test2json
+++ b/pkg/tool/darwin_amd64/test2json
Binary files differ
diff --git a/pkg/tool/darwin_amd64/trace b/pkg/tool/darwin_amd64/trace
index ccce0a7..8f91b3d 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 a4b1ac1..99862a4 100755
--- a/pkg/tool/darwin_amd64/vet
+++ b/pkg/tool/darwin_amd64/vet
Binary files differ
diff --git a/robots.txt b/robots.txt
deleted file mode 100644
index 1f53798..0000000
--- a/robots.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-User-agent: *
-Disallow: /
diff --git a/src/archive/tar/stat_actime1.go b/src/archive/tar/stat_actime1.go
index 1bdd1c9..4fdf2a0 100644
--- a/src/archive/tar/stat_actime1.go
+++ b/src/archive/tar/stat_actime1.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || linux || dragonfly || openbsd || solaris
 // +build aix linux dragonfly openbsd solaris
 
 package tar
diff --git a/src/archive/tar/stat_actime2.go b/src/archive/tar/stat_actime2.go
index 6f17dbe..5a9a35c 100644
--- a/src/archive/tar/stat_actime2.go
+++ b/src/archive/tar/stat_actime2.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || freebsd || netbsd
 // +build darwin freebsd netbsd
 
 package tar
diff --git a/src/archive/tar/stat_unix.go b/src/archive/tar/stat_unix.go
index 581d87d..3957349 100644
--- a/src/archive/tar/stat_unix.go
+++ b/src/archive/tar/stat_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || linux || darwin || dragonfly || freebsd || openbsd || netbsd || solaris
 // +build aix linux darwin dragonfly freebsd openbsd netbsd solaris
 
 package tar
diff --git a/src/archive/tar/tar_test.go b/src/archive/tar/tar_test.go
index 91b3840..e9fafc7 100644
--- a/src/archive/tar/tar_test.go
+++ b/src/archive/tar/tar_test.go
@@ -262,16 +262,11 @@
 func TestFileInfoHeaderSymlink(t *testing.T) {
 	testenv.MustHaveSymlink(t)
 
-	tmpdir, err := os.MkdirTemp("", "TestFileInfoHeaderSymlink")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	link := filepath.Join(tmpdir, "link")
 	target := tmpdir
-	err = os.Symlink(target, link)
-	if err != nil {
+	if err := os.Symlink(target, link); err != nil {
 		t.Fatal(err)
 	}
 	fi, err := os.Lstat(link)
diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
index c288ad9..2d53f4c 100644
--- a/src/archive/zip/reader.go
+++ b/src/archive/zip/reader.go
@@ -52,12 +52,9 @@
 	FileHeader
 	zip          *Reader
 	zipr         io.ReaderAt
-	zipsize      int64
 	headerOffset int64
-}
-
-func (f *File) hasDataDescriptor() bool {
-	return f.Flags&0x8 != 0
+	zip64        bool  // zip64 extended information extra field presence
+	descErr      error // error reading the data descriptor during init
 }
 
 // OpenReader will open the Zip file specified by name and return a ReadCloser.
@@ -99,7 +96,15 @@
 		return err
 	}
 	z.r = r
-	z.File = make([]*File, 0, end.directoryRecords)
+	// Since the number of directory records is not validated, it is not
+	// safe to preallocate z.File without first checking that the specified
+	// number of files is reasonable, since a malformed archive may
+	// indicate it contains up to 1 << 128 - 1 files. Since each file has a
+	// header which will be _at least_ 30 bytes we can safely preallocate
+	// if (data size / 30) >= end.directoryRecords.
+	if (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
+		z.File = make([]*File, 0, end.directoryRecords)
+	}
 	z.Comment = end.comment
 	rs := io.NewSectionReader(r, 0, size)
 	if _, err = rs.Seek(int64(end.directoryOffset), io.SeekStart); err != nil {
@@ -112,7 +117,7 @@
 	// 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}
+		f := &File{zip: z, zipr: r}
 		err = readDirectoryHeader(f, buf)
 		if err == ErrFormat || err == io.ErrUnexpectedEOF {
 			break
@@ -120,6 +125,7 @@
 		if err != nil {
 			return err
 		}
+		f.readDataDescriptor()
 		z.File = append(z.File, f)
 	}
 	if uint16(len(z.File)) != uint16(end.directoryRecords) { // only compare 16 bits here
@@ -180,26 +186,68 @@
 		return nil, ErrAlgorithm
 	}
 	var rc io.ReadCloser = dcomp(r)
-	var desr io.Reader
-	if f.hasDataDescriptor() {
-		desr = io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+size, dataDescriptorLen)
-	}
 	rc = &checksumReader{
 		rc:   rc,
 		hash: crc32.NewIEEE(),
 		f:    f,
-		desr: desr,
 	}
 	return rc, nil
 }
 
+// OpenRaw returns a Reader that provides access to the File's contents without
+// decompression.
+func (f *File) OpenRaw() (io.Reader, error) {
+	bodyOffset, err := f.findBodyOffset()
+	if err != nil {
+		return nil, err
+	}
+	r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, int64(f.CompressedSize64))
+	return r, nil
+}
+
+func (f *File) readDataDescriptor() {
+	if !f.hasDataDescriptor() {
+		return
+	}
+
+	bodyOffset, err := f.findBodyOffset()
+	if err != nil {
+		f.descErr = err
+		return
+	}
+
+	// In section 4.3.9.2 of the spec: "However ZIP64 format MAY be used
+	// regardless of the size of a file.  When extracting, if the zip64
+	// extended information extra field is present for the file the
+	// compressed and uncompressed sizes will be 8 byte values."
+	//
+	// Historically, this package has used the compressed and uncompressed
+	// sizes from the central directory to determine if the package is
+	// zip64.
+	//
+	// For this case we allow either the extra field or sizes to determine
+	// the data descriptor length.
+	zip64 := f.zip64 || f.isZip64()
+	n := int64(dataDescriptorLen)
+	if zip64 {
+		n = dataDescriptor64Len
+	}
+	size := int64(f.CompressedSize64)
+	r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+size, n)
+	dd, err := readDataDescriptor(r, zip64)
+	if err != nil {
+		f.descErr = err
+		return
+	}
+	f.CRC32 = dd.crc32
+}
+
 type checksumReader struct {
 	rc    io.ReadCloser
 	hash  hash.Hash32
 	nread uint64 // number of bytes read so far
 	f     *File
-	desr  io.Reader // if non-nil, where to read the data descriptor
-	err   error     // sticky error
+	err   error // sticky error
 }
 
 func (r *checksumReader) Stat() (fs.FileInfo, error) {
@@ -220,12 +268,12 @@
 		if r.nread != r.f.UncompressedSize64 {
 			return 0, io.ErrUnexpectedEOF
 		}
-		if r.desr != nil {
-			if err1 := readDataDescriptor(r.desr, r.f); err1 != nil {
-				if err1 == io.EOF {
+		if r.f.hasDataDescriptor() {
+			if r.f.descErr != nil {
+				if r.f.descErr == io.EOF {
 					err = io.ErrUnexpectedEOF
 				} else {
-					err = err1
+					err = r.f.descErr
 				}
 			} else if r.hash.Sum32() != r.f.CRC32 {
 				err = ErrChecksum
@@ -336,6 +384,8 @@
 
 		switch fieldTag {
 		case zip64ExtraID:
+			f.zip64 = true
+
 			// update directory values from the zip64 extra block.
 			// They should only be consulted if the sizes read earlier
 			// are maxed out.
@@ -435,8 +485,9 @@
 	return nil
 }
 
-func readDataDescriptor(r io.Reader, f *File) error {
-	var buf [dataDescriptorLen]byte
+func readDataDescriptor(r io.Reader, zip64 bool) (*dataDescriptor, error) {
+	// Create enough space for the largest possible size
+	var buf [dataDescriptor64Len]byte
 
 	// The spec says: "Although not originally assigned a
 	// signature, the value 0x08074b50 has commonly been adopted
@@ -446,10 +497,9 @@
 	// descriptors and should account for either case when reading
 	// ZIP files to ensure compatibility."
 	//
-	// dataDescriptorLen includes the size of the signature but
-	// first read just those 4 bytes to see if it exists.
+	// First read just those 4 bytes to see if the signature exists.
 	if _, err := io.ReadFull(r, buf[:4]); err != nil {
-		return err
+		return nil, err
 	}
 	off := 0
 	maybeSig := readBuf(buf[:4])
@@ -458,21 +508,28 @@
 		// bytes.
 		off += 4
 	}
-	if _, err := io.ReadFull(r, buf[off:12]); err != nil {
-		return err
+
+	end := dataDescriptorLen - 4
+	if zip64 {
+		end = dataDescriptor64Len - 4
 	}
-	b := readBuf(buf[:12])
-	if b.uint32() != f.CRC32 {
-		return ErrChecksum
+	if _, err := io.ReadFull(r, buf[off:end]); err != nil {
+		return nil, err
+	}
+	b := readBuf(buf[:end])
+
+	out := &dataDescriptor{
+		crc32: b.uint32(),
 	}
 
-	// The two sizes that follow here can be either 32 bits or 64 bits
-	// but the spec is not very clear on this and different
-	// interpretations has been made causing incompatibilities. We
-	// already have the sizes from the central directory so we can
-	// just ignore these.
-
-	return nil
+	if zip64 {
+		out.compressedSize = b.uint64()
+		out.uncompressedSize = b.uint64()
+	} else {
+		out.compressedSize = uint64(b.uint32())
+		out.uncompressedSize = uint64(b.uint32())
+	}
+	return out, nil
 }
 
 func readDirectoryEnd(r io.ReaderAt, size int64) (dir *directoryEnd, err error) {
@@ -628,10 +685,11 @@
 }
 
 // A fileListEntry is a File and its ename.
-// If file == nil, the fileListEntry describes a directory, without metadata.
+// If file == nil, the fileListEntry describes a directory without metadata.
 type fileListEntry struct {
-	name string
-	file *File // nil for directories
+	name  string
+	file  *File
+	isDir bool
 }
 
 type fileInfoDirEntry interface {
@@ -640,20 +698,26 @@
 }
 
 func (e *fileListEntry) stat() fileInfoDirEntry {
-	if e.file != nil {
+	if !e.isDir {
 		return headerFileInfo{&e.file.FileHeader}
 	}
 	return e
 }
 
 // Only used for directories.
-func (f *fileListEntry) Name() string       { _, elem, _ := split(f.name); return elem }
-func (f *fileListEntry) Size() int64        { return 0 }
-func (f *fileListEntry) ModTime() time.Time { return time.Time{} }
-func (f *fileListEntry) Mode() fs.FileMode  { return fs.ModeDir | 0555 }
-func (f *fileListEntry) Type() fs.FileMode  { return fs.ModeDir }
-func (f *fileListEntry) IsDir() bool        { return true }
-func (f *fileListEntry) Sys() interface{}   { return nil }
+func (f *fileListEntry) Name() string      { _, elem, _ := split(f.name); return elem }
+func (f *fileListEntry) Size() int64       { return 0 }
+func (f *fileListEntry) Mode() fs.FileMode { return fs.ModeDir | 0555 }
+func (f *fileListEntry) Type() fs.FileMode { return fs.ModeDir }
+func (f *fileListEntry) IsDir() bool       { return true }
+func (f *fileListEntry) Sys() interface{}  { return nil }
+
+func (f *fileListEntry) ModTime() time.Time {
+	if f.file == nil {
+		return time.Time{}
+	}
+	return f.file.FileHeader.Modified.UTC()
+}
 
 func (f *fileListEntry) Info() (fs.FileInfo, error) { return f, nil }
 
@@ -673,15 +737,32 @@
 func (r *Reader) initFileList() {
 	r.fileListOnce.Do(func() {
 		dirs := make(map[string]bool)
+		knownDirs := make(map[string]bool)
 		for _, file := range r.File {
+			isDir := len(file.Name) > 0 && file.Name[len(file.Name)-1] == '/'
 			name := toValidName(file.Name)
 			for dir := path.Dir(name); dir != "."; dir = path.Dir(dir) {
 				dirs[dir] = true
 			}
-			r.fileList = append(r.fileList, fileListEntry{name, file})
+			entry := fileListEntry{
+				name:  name,
+				file:  file,
+				isDir: isDir,
+			}
+			r.fileList = append(r.fileList, entry)
+			if isDir {
+				knownDirs[name] = true
+			}
 		}
 		for dir := range dirs {
-			r.fileList = append(r.fileList, fileListEntry{dir + "/", nil})
+			if !knownDirs[dir] {
+				entry := fileListEntry{
+					name:  dir,
+					file:  nil,
+					isDir: true,
+				}
+				r.fileList = append(r.fileList, entry)
+			}
 		}
 
 		sort.Slice(r.fileList, func(i, j int) bool { return fileEntryLess(r.fileList[i].name, r.fileList[j].name) })
@@ -705,7 +786,7 @@
 	if e == nil || !fs.ValidPath(name) {
 		return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
 	}
-	if e.file == nil || strings.HasSuffix(e.file.Name, "/") {
+	if e.isDir {
 		return &openDir{e, r.openReadDir(name), 0}, nil
 	}
 	rc, err := e.file.Open()
@@ -730,7 +811,7 @@
 	return name[:i], name[i+1:], isDir
 }
 
-var dotFile = &fileListEntry{name: "./"}
+var dotFile = &fileListEntry{name: "./", isDir: true}
 
 func (r *Reader) openLookup(name string) *fileListEntry {
 	if name == "." {
diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go
index 5faf1f4..37dafe6 100644
--- a/src/archive/zip/reader_test.go
+++ b/src/archive/zip/reader_test.go
@@ -499,9 +499,15 @@
 func readTestZip(t *testing.T, zt ZipTest) {
 	var z *Reader
 	var err error
+	var raw []byte
 	if zt.Source != nil {
 		rat, size := zt.Source()
 		z, err = NewReader(rat, size)
+		raw = make([]byte, size)
+		if _, err := rat.ReadAt(raw, 0); err != nil {
+			t.Errorf("ReadAt error=%v", err)
+			return
+		}
 	} else {
 		path := filepath.Join("testdata", zt.Name)
 		if zt.Obscured {
@@ -519,6 +525,12 @@
 			defer rc.Close()
 			z = &rc.Reader
 		}
+		var err2 error
+		raw, err2 = os.ReadFile(path)
+		if err2 != nil {
+			t.Errorf("ReadFile(%s) error=%v", path, err2)
+			return
+		}
 	}
 	if err != zt.Error {
 		t.Errorf("error=%v, want %v", err, zt.Error)
@@ -545,7 +557,7 @@
 
 	// test read of each file
 	for i, ft := range zt.File {
-		readTestFile(t, zt, ft, z.File[i])
+		readTestFile(t, zt, ft, z.File[i], raw)
 	}
 	if t.Failed() {
 		return
@@ -557,7 +569,7 @@
 	for i := 0; i < 5; i++ {
 		for j, ft := range zt.File {
 			go func(j int, ft ZipTestFile) {
-				readTestFile(t, zt, ft, z.File[j])
+				readTestFile(t, zt, ft, z.File[j], raw)
 				done <- true
 			}(j, ft)
 			n++
@@ -574,7 +586,7 @@
 	return t1.Equal(t2) && name1 == name2 && offset1 == offset2
 }
 
-func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
+func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File, raw []byte) {
 	if f.Name != ft.Name {
 		t.Errorf("name=%q, want %q", f.Name, ft.Name)
 	}
@@ -594,6 +606,31 @@
 		t.Errorf("%v: UncompressedSize=%#x does not match UncompressedSize64=%#x", f.Name, size, f.UncompressedSize64)
 	}
 
+	// Check that OpenRaw returns the correct byte segment
+	rw, err := f.OpenRaw()
+	if err != nil {
+		t.Errorf("%v: OpenRaw error=%v", f.Name, err)
+		return
+	}
+	start, err := f.DataOffset()
+	if err != nil {
+		t.Errorf("%v: DataOffset error=%v", f.Name, err)
+		return
+	}
+	got, err := io.ReadAll(rw)
+	if err != nil {
+		t.Errorf("%v: OpenRaw ReadAll error=%v", f.Name, err)
+		return
+	}
+	end := uint64(start) + f.CompressedSize64
+	want := raw[start:end]
+	if !bytes.Equal(got, want) {
+		t.Logf("got %q", got)
+		t.Logf("want %q", want)
+		t.Errorf("%v: OpenRaw returned unexpected bytes", f.Name)
+		return
+	}
+
 	r, err := f.Open()
 	if err != nil {
 		t.Errorf("%v", err)
@@ -776,8 +813,8 @@
 //		"archive/zip"
 //		"bytes"
 //		"io"
-//		"io/ioutil"
 //		"log"
+//		"os"
 //	)
 //
 //	type zeros struct{}
@@ -1073,12 +1110,62 @@
 }
 
 func TestFS(t *testing.T) {
-	z, err := OpenReader("testdata/unix.zip")
+	for _, test := range []struct {
+		file string
+		want []string
+	}{
+		{
+			"testdata/unix.zip",
+			[]string{"hello", "dir/bar", "readonly"},
+		},
+		{
+			"testdata/subdir.zip",
+			[]string{"a/b/c"},
+		},
+	} {
+		t.Run(test.file, func(t *testing.T) {
+			t.Parallel()
+			z, err := OpenReader(test.file)
+			if err != nil {
+				t.Fatal(err)
+			}
+			defer z.Close()
+			if err := fstest.TestFS(z, test.want...); err != nil {
+				t.Error(err)
+			}
+		})
+	}
+}
+
+func TestFSModTime(t *testing.T) {
+	t.Parallel()
+	z, err := OpenReader("testdata/subdir.zip")
 	if err != nil {
 		t.Fatal(err)
 	}
-	if err := fstest.TestFS(z, "hello", "dir/bar", "dir/empty", "readonly"); err != nil {
-		t.Fatal(err)
+	defer z.Close()
+
+	for _, test := range []struct {
+		name string
+		want time.Time
+	}{
+		{
+			"a",
+			time.Date(2021, 4, 19, 12, 29, 56, 0, timeZone(-7*time.Hour)).UTC(),
+		},
+		{
+			"a/b/c",
+			time.Date(2021, 4, 19, 12, 29, 59, 0, timeZone(-7*time.Hour)).UTC(),
+		},
+	} {
+		fi, err := fs.Stat(z, test.name)
+		if err != nil {
+			t.Errorf("%s: %v", test.name, err)
+			continue
+		}
+		if got := fi.ModTime(); !got.Equal(test.want) {
+			t.Errorf("%s: got modtime %v, want %v", test.name, got, test.want)
+		}
 	}
 }
 
@@ -1116,3 +1203,184 @@
 		t.Errorf("Error reading file: %v", err)
 	}
 }
+
+func TestReadDataDescriptor(t *testing.T) {
+	tests := []struct {
+		desc    string
+		in      []byte
+		zip64   bool
+		want    *dataDescriptor
+		wantErr error
+	}{{
+		desc: "valid 32 bit with signature",
+		in: []byte{
+			0x50, 0x4b, 0x07, 0x08, // signature
+			0x00, 0x01, 0x02, 0x03, // crc32
+			0x04, 0x05, 0x06, 0x07, // compressed size
+			0x08, 0x09, 0x0a, 0x0b, // uncompressed size
+		},
+		want: &dataDescriptor{
+			crc32:            0x03020100,
+			compressedSize:   0x07060504,
+			uncompressedSize: 0x0b0a0908,
+		},
+	}, {
+		desc: "valid 32 bit without signature",
+		in: []byte{
+			0x00, 0x01, 0x02, 0x03, // crc32
+			0x04, 0x05, 0x06, 0x07, // compressed size
+			0x08, 0x09, 0x0a, 0x0b, // uncompressed size
+		},
+		want: &dataDescriptor{
+			crc32:            0x03020100,
+			compressedSize:   0x07060504,
+			uncompressedSize: 0x0b0a0908,
+		},
+	}, {
+		desc: "valid 64 bit with signature",
+		in: []byte{
+			0x50, 0x4b, 0x07, 0x08, // signature
+			0x00, 0x01, 0x02, 0x03, // crc32
+			0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, // compressed size
+			0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, // uncompressed size
+		},
+		zip64: true,
+		want: &dataDescriptor{
+			crc32:            0x03020100,
+			compressedSize:   0x0b0a090807060504,
+			uncompressedSize: 0x131211100f0e0d0c,
+		},
+	}, {
+		desc: "valid 64 bit without signature",
+		in: []byte{
+			0x00, 0x01, 0x02, 0x03, // crc32
+			0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, // compressed size
+			0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, // uncompressed size
+		},
+		zip64: true,
+		want: &dataDescriptor{
+			crc32:            0x03020100,
+			compressedSize:   0x0b0a090807060504,
+			uncompressedSize: 0x131211100f0e0d0c,
+		},
+	}, {
+		desc: "invalid 32 bit with signature",
+		in: []byte{
+			0x50, 0x4b, 0x07, 0x08, // signature
+			0x00, 0x01, 0x02, 0x03, // crc32
+			0x04, 0x05, // unexpected end
+		},
+		wantErr: io.ErrUnexpectedEOF,
+	}, {
+		desc: "invalid 32 bit without signature",
+		in: []byte{
+			0x00, 0x01, 0x02, 0x03, // crc32
+			0x04, 0x05, // unexpected end
+		},
+		wantErr: io.ErrUnexpectedEOF,
+	}, {
+		desc: "invalid 64 bit with signature",
+		in: []byte{
+			0x50, 0x4b, 0x07, 0x08, // signature
+			0x00, 0x01, 0x02, 0x03, // crc32
+			0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, // compressed size
+			0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, // unexpected end
+		},
+		zip64:   true,
+		wantErr: io.ErrUnexpectedEOF,
+	}, {
+		desc: "invalid 64 bit without signature",
+		in: []byte{
+			0x00, 0x01, 0x02, 0x03, // crc32
+			0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, // compressed size
+			0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, // unexpected end
+		},
+		zip64:   true,
+		wantErr: io.ErrUnexpectedEOF,
+	}}
+
+	for _, test := range tests {
+		t.Run(test.desc, func(t *testing.T) {
+			r := bytes.NewReader(test.in)
+
+			desc, err := readDataDescriptor(r, test.zip64)
+			if err != test.wantErr {
+				t.Fatalf("got err %v; want nil", err)
+			}
+			if test.want == nil {
+				return
+			}
+			if desc == nil {
+				t.Fatalf("got nil DataDescriptor; want non-nil")
+			}
+			if desc.crc32 != test.want.crc32 {
+				t.Errorf("got CRC32 %#x; want %#x", desc.crc32, test.want.crc32)
+			}
+			if desc.compressedSize != test.want.compressedSize {
+				t.Errorf("got CompressedSize %#x; want %#x", desc.compressedSize, test.want.compressedSize)
+			}
+			if desc.uncompressedSize != test.want.uncompressedSize {
+				t.Errorf("got UncompressedSize %#x; want %#x", desc.uncompressedSize, test.want.uncompressedSize)
+			}
+		})
+	}
+}
+
+func TestCVE202133196(t *testing.T) {
+	// Archive that indicates it has 1 << 128 -1 files,
+	// this would previously cause a panic due to attempting
+	// to allocate a slice with 1 << 128 -1 elements.
+	data := []byte{
+		0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x08,
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02,
+		0x03, 0x62, 0x61, 0x65, 0x03, 0x04, 0x00, 0x00,
+		0xff, 0xff, 0x50, 0x4b, 0x07, 0x08, 0xbe, 0x20,
+		0x5c, 0x6c, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00,
+		0x00, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00,
+		0x14, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0xbe, 0x20, 0x5c, 0x6c, 0x09, 0x00,
+		0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 0x02, 0x03, 0x50, 0x4b, 0x06, 0x06, 0x2c,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+		0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0x31, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x50, 0x4b, 0x06, 0x07, 0x00,
+		0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50,
+		0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0x00, 0x00,
+	}
+	_, err := NewReader(bytes.NewReader(data), int64(len(data)))
+	if err != ErrFormat {
+		t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat)
+	}
+
+	// Also check that an archive containing a handful of empty
+	// files doesn't cause an issue
+	b := bytes.NewBuffer(nil)
+	w := NewWriter(b)
+	for i := 0; i < 5; i++ {
+		_, err := w.Create("")
+		if err != nil {
+			t.Fatalf("Writer.Create failed: %s", err)
+		}
+	}
+	if err := w.Close(); err != nil {
+		t.Fatalf("Writer.Close failed: %s", err)
+	}
+	r, err := NewReader(bytes.NewReader(b.Bytes()), int64(b.Len()))
+	if err != nil {
+		t.Fatalf("NewReader failed: %s", err)
+	}
+	if len(r.File) != 5 {
+		t.Errorf("Archive has unexpected number of files, got %d, want 5", len(r.File))
+	}
+}
diff --git a/src/archive/zip/struct.go b/src/archive/zip/struct.go
index 4dd29f3..ff9f605 100644
--- a/src/archive/zip/struct.go
+++ b/src/archive/zip/struct.go
@@ -42,7 +42,7 @@
 	directoryHeaderLen       = 46         // + filename + extra + comment
 	directoryEndLen          = 22         // + comment
 	dataDescriptorLen        = 16         // four uint32: descriptor signature, crc32, compressed size, size
-	dataDescriptor64Len      = 24         // descriptor with 8 byte sizes
+	dataDescriptor64Len      = 24         // two uint32: signature, crc32 | two uint64: compressed size, size
 	directory64LocLen        = 20         //
 	directory64EndLen        = 56         // + extra
 
@@ -315,6 +315,10 @@
 	return h.CompressedSize64 >= uint32max || h.UncompressedSize64 >= uint32max
 }
 
+func (f *FileHeader) hasDataDescriptor() bool {
+	return f.Flags&0x8 != 0
+}
+
 func msdosModeToFileMode(m uint32) (mode fs.FileMode) {
 	if m&msdosDir != 0 {
 		mode = fs.ModeDir | 0777
@@ -341,11 +345,9 @@
 	case fs.ModeSocket:
 		m = s_IFSOCK
 	case fs.ModeDevice:
-		if mode&fs.ModeCharDevice != 0 {
-			m = s_IFCHR
-		} else {
-			m = s_IFBLK
-		}
+		m = s_IFBLK
+	case fs.ModeDevice | fs.ModeCharDevice:
+		m = s_IFCHR
 	}
 	if mode&fs.ModeSetuid != 0 {
 		m |= s_ISUID
@@ -388,3 +390,11 @@
 	}
 	return mode
 }
+
+// dataDescriptor holds the data descriptor that optionally follows the file
+// contents in the zip file.
+type dataDescriptor struct {
+	crc32            uint32
+	compressedSize   uint64
+	uncompressedSize uint64
+}
diff --git a/src/archive/zip/testdata/subdir.zip b/src/archive/zip/testdata/subdir.zip
new file mode 100644
index 0000000..324d06b
--- /dev/null
+++ b/src/archive/zip/testdata/subdir.zip
Binary files differ
diff --git a/src/archive/zip/writer.go b/src/archive/zip/writer.go
index cdc534e..3b23cc3 100644
--- a/src/archive/zip/writer.go
+++ b/src/archive/zip/writer.go
@@ -37,6 +37,7 @@
 type header struct {
 	*FileHeader
 	offset uint64
+	raw    bool
 }
 
 // NewWriter returns a new Writer writing a zip file to w.
@@ -245,22 +246,31 @@
 	return true, require
 }
 
+// prepare performs the bookkeeping operations required at the start of
+// CreateHeader and CreateRaw.
+func (w *Writer) prepare(fh *FileHeader) error {
+	if w.last != nil && !w.last.closed {
+		if err := w.last.close(); err != nil {
+			return err
+		}
+	}
+	if len(w.dir) > 0 && w.dir[len(w.dir)-1].FileHeader == fh {
+		// See https://golang.org/issue/11144 confusion.
+		return errors.New("archive/zip: invalid duplicate FileHeader")
+	}
+	return nil
+}
+
 // 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.
+// call to Create, CreateHeader, CreateRaw, or Close.
 func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
-	if w.last != nil && !w.last.closed {
-		if err := w.last.close(); err != nil {
-			return nil, err
-		}
-	}
-	if len(w.dir) > 0 && w.dir[len(w.dir)-1].FileHeader == fh {
-		// See https://golang.org/issue/11144 confusion.
-		return nil, errors.New("archive/zip: invalid duplicate FileHeader")
+	if err := w.prepare(fh); err != nil {
+		return nil, err
 	}
 
 	// The ZIP format has a sad state of affairs regarding character encoding.
@@ -365,7 +375,7 @@
 		ow = fw
 	}
 	w.dir = append(w.dir, h)
-	if err := writeHeader(w.cw, fh); err != nil {
+	if err := writeHeader(w.cw, h); err != nil {
 		return nil, err
 	}
 	// If we're creating a directory, fw is nil.
@@ -373,7 +383,7 @@
 	return ow, nil
 }
 
-func writeHeader(w io.Writer, h *FileHeader) error {
+func writeHeader(w io.Writer, h *header) error {
 	const maxUint16 = 1<<16 - 1
 	if len(h.Name) > maxUint16 {
 		return errLongName
@@ -390,9 +400,20 @@
 	b.uint16(h.Method)
 	b.uint16(h.ModifiedTime)
 	b.uint16(h.ModifiedDate)
-	b.uint32(0) // since we are writing a data descriptor crc32,
-	b.uint32(0) // compressed size,
-	b.uint32(0) // and uncompressed size should be zero
+	// In raw mode (caller does the compression), the values are either
+	// written here or in the trailing data descriptor based on the header
+	// flags.
+	if h.raw && !h.hasDataDescriptor() {
+		b.uint32(h.CRC32)
+		b.uint32(uint32(min64(h.CompressedSize64, uint32max)))
+		b.uint32(uint32(min64(h.UncompressedSize64, uint32max)))
+	} else {
+		// When this package handle the compression, these values are
+		// always written to the trailing data descriptor.
+		b.uint32(0) // crc32
+		b.uint32(0) // compressed size
+		b.uint32(0) // uncompressed size
+	}
 	b.uint16(uint16(len(h.Name)))
 	b.uint16(uint16(len(h.Extra)))
 	if _, err := w.Write(buf[:]); err != nil {
@@ -405,6 +426,65 @@
 	return err
 }
 
+func min64(x, y uint64) uint64 {
+	if x < y {
+		return x
+	}
+	return y
+}
+
+// CreateRaw adds a file to the zip archive using the provided FileHeader and
+// 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, CreateRaw, or Close.
+//
+// In contrast to CreateHeader, the bytes passed to Writer are not compressed.
+func (w *Writer) CreateRaw(fh *FileHeader) (io.Writer, error) {
+	if err := w.prepare(fh); err != nil {
+		return nil, err
+	}
+
+	fh.CompressedSize = uint32(min64(fh.CompressedSize64, uint32max))
+	fh.UncompressedSize = uint32(min64(fh.UncompressedSize64, uint32max))
+
+	h := &header{
+		FileHeader: fh,
+		offset:     uint64(w.cw.count),
+		raw:        true,
+	}
+	w.dir = append(w.dir, h)
+	if err := writeHeader(w.cw, h); err != nil {
+		return nil, err
+	}
+
+	if strings.HasSuffix(fh.Name, "/") {
+		w.last = nil
+		return dirWriter{}, nil
+	}
+
+	fw := &fileWriter{
+		header: h,
+		zipw:   w.cw,
+	}
+	w.last = fw
+	return fw, nil
+}
+
+// Copy copies the file f (obtained from a Reader) into w. It copies the raw
+// form directly bypassing decompression, compression, and validation.
+func (w *Writer) Copy(f *File) error {
+	r, err := f.OpenRaw()
+	if err != nil {
+		return err
+	}
+	fw, err := w.CreateRaw(&f.FileHeader)
+	if err != nil {
+		return err
+	}
+	_, err = io.Copy(fw, r)
+	return err
+}
+
 // RegisterCompressor registers or overrides a custom compressor for a specific
 // method ID. If a compressor for a given method is not found, Writer will
 // default to looking up the compressor at the package level.
@@ -446,6 +526,9 @@
 	if w.closed {
 		return 0, errors.New("zip: write to closed file")
 	}
+	if w.raw {
+		return w.zipw.Write(p)
+	}
 	w.crc32.Write(p)
 	return w.rawCount.Write(p)
 }
@@ -455,6 +538,9 @@
 		return errors.New("zip: file closed twice")
 	}
 	w.closed = true
+	if w.raw {
+		return w.writeDataDescriptor()
+	}
 	if err := w.comp.Close(); err != nil {
 		return err
 	}
@@ -474,26 +560,33 @@
 		fh.UncompressedSize = uint32(fh.UncompressedSize64)
 	}
 
+	return w.writeDataDescriptor()
+}
+
+func (w *fileWriter) writeDataDescriptor() error {
+	if !w.hasDataDescriptor() {
+		return nil
+	}
 	// Write data descriptor. This is more complicated than one would
 	// think, see e.g. comments in zipfile.c:putextended() and
 	// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7073588.
 	// The approach here is to write 8 byte sizes if needed without
 	// adding a zip64 extra in the local header (too late anyway).
 	var buf []byte
-	if fh.isZip64() {
+	if w.isZip64() {
 		buf = make([]byte, dataDescriptor64Len)
 	} else {
 		buf = make([]byte, dataDescriptorLen)
 	}
 	b := writeBuf(buf)
 	b.uint32(dataDescriptorSignature) // de-facto standard, required by OS X
-	b.uint32(fh.CRC32)
-	if fh.isZip64() {
-		b.uint64(fh.CompressedSize64)
-		b.uint64(fh.UncompressedSize64)
+	b.uint32(w.CRC32)
+	if w.isZip64() {
+		b.uint64(w.CompressedSize64)
+		b.uint64(w.UncompressedSize64)
 	} else {
-		b.uint32(fh.CompressedSize)
-		b.uint32(fh.UncompressedSize)
+		b.uint32(w.CompressedSize)
+		b.uint32(w.UncompressedSize)
 	}
 	_, err := w.zipw.Write(buf)
 	return err
diff --git a/src/archive/zip/writer_test.go b/src/archive/zip/writer_test.go
index 5985144..97c6c52 100644
--- a/src/archive/zip/writer_test.go
+++ b/src/archive/zip/writer_test.go
@@ -6,8 +6,10 @@
 
 import (
 	"bytes"
+	"compress/flate"
 	"encoding/binary"
 	"fmt"
+	"hash/crc32"
 	"io"
 	"io/fs"
 	"math/rand"
@@ -57,6 +59,18 @@
 		Method: Deflate,
 		Mode:   0755 | fs.ModeSymlink,
 	},
+	{
+		Name:   "device",
+		Data:   []byte("device file"),
+		Method: Deflate,
+		Mode:   0755 | fs.ModeDevice,
+	},
+	{
+		Name:   "chardevice",
+		Data:   []byte("char device file"),
+		Method: Deflate,
+		Mode:   0755 | fs.ModeDevice | fs.ModeCharDevice,
+	},
 }
 
 func TestWriter(t *testing.T) {
@@ -353,6 +367,171 @@
 	}
 }
 
+func TestWriterCopy(t *testing.T) {
+	// make a zip file
+	buf := new(bytes.Buffer)
+	w := NewWriter(buf)
+	for _, wt := range writeTests {
+		testCreate(t, w, &wt)
+	}
+	if err := w.Close(); err != nil {
+		t.Fatal(err)
+	}
+
+	// read it back
+	src, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
+	if err != nil {
+		t.Fatal(err)
+	}
+	for i, wt := range writeTests {
+		testReadFile(t, src.File[i], &wt)
+	}
+
+	// make a new zip file copying the old compressed data.
+	buf2 := new(bytes.Buffer)
+	dst := NewWriter(buf2)
+	for _, f := range src.File {
+		if err := dst.Copy(f); err != nil {
+			t.Fatal(err)
+		}
+	}
+	if err := dst.Close(); err != nil {
+		t.Fatal(err)
+	}
+
+	// read the new one back
+	r, err := NewReader(bytes.NewReader(buf2.Bytes()), int64(buf2.Len()))
+	if err != nil {
+		t.Fatal(err)
+	}
+	for i, wt := range writeTests {
+		testReadFile(t, r.File[i], &wt)
+	}
+}
+
+func TestWriterCreateRaw(t *testing.T) {
+	files := []struct {
+		name             string
+		content          []byte
+		method           uint16
+		flags            uint16
+		crc32            uint32
+		uncompressedSize uint64
+		compressedSize   uint64
+	}{
+		{
+			name:    "small store w desc",
+			content: []byte("gophers"),
+			method:  Store,
+			flags:   0x8,
+		},
+		{
+			name:    "small deflate wo desc",
+			content: bytes.Repeat([]byte("abcdefg"), 2048),
+			method:  Deflate,
+		},
+	}
+
+	// write a zip file
+	archive := new(bytes.Buffer)
+	w := NewWriter(archive)
+
+	for i := range files {
+		f := &files[i]
+		f.crc32 = crc32.ChecksumIEEE(f.content)
+		size := uint64(len(f.content))
+		f.uncompressedSize = size
+		f.compressedSize = size
+
+		var compressedContent []byte
+		if f.method == Deflate {
+			var buf bytes.Buffer
+			w, err := flate.NewWriter(&buf, flate.BestSpeed)
+			if err != nil {
+				t.Fatalf("flate.NewWriter err = %v", err)
+			}
+			_, err = w.Write(f.content)
+			if err != nil {
+				t.Fatalf("flate Write err = %v", err)
+			}
+			err = w.Close()
+			if err != nil {
+				t.Fatalf("flate Writer.Close err = %v", err)
+			}
+			compressedContent = buf.Bytes()
+			f.compressedSize = uint64(len(compressedContent))
+		}
+
+		h := &FileHeader{
+			Name:               f.name,
+			Method:             f.method,
+			Flags:              f.flags,
+			CRC32:              f.crc32,
+			CompressedSize64:   f.compressedSize,
+			UncompressedSize64: f.uncompressedSize,
+		}
+		w, err := w.CreateRaw(h)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if compressedContent != nil {
+			_, err = w.Write(compressedContent)
+		} else {
+			_, err = w.Write(f.content)
+		}
+		if err != nil {
+			t.Fatalf("%s Write got %v; want nil", f.name, err)
+		}
+	}
+
+	if err := w.Close(); err != nil {
+		t.Fatal(err)
+	}
+
+	// read it back
+	r, err := NewReader(bytes.NewReader(archive.Bytes()), int64(archive.Len()))
+	if err != nil {
+		t.Fatal(err)
+	}
+	for i, want := range files {
+		got := r.File[i]
+		if got.Name != want.name {
+			t.Errorf("got Name %s; want %s", got.Name, want.name)
+		}
+		if got.Method != want.method {
+			t.Errorf("%s: got Method %#x; want %#x", want.name, got.Method, want.method)
+		}
+		if got.Flags != want.flags {
+			t.Errorf("%s: got Flags %#x; want %#x", want.name, got.Flags, want.flags)
+		}
+		if got.CRC32 != want.crc32 {
+			t.Errorf("%s: got CRC32 %#x; want %#x", want.name, got.CRC32, want.crc32)
+		}
+		if got.CompressedSize64 != want.compressedSize {
+			t.Errorf("%s: got CompressedSize64 %d; want %d", want.name, got.CompressedSize64, want.compressedSize)
+		}
+		if got.UncompressedSize64 != want.uncompressedSize {
+			t.Errorf("%s: got UncompressedSize64 %d; want %d", want.name, got.UncompressedSize64, want.uncompressedSize)
+		}
+
+		r, err := got.Open()
+		if err != nil {
+			t.Errorf("%s: Open err = %v", got.Name, err)
+			continue
+		}
+
+		buf, err := io.ReadAll(r)
+		if err != nil {
+			t.Errorf("%s: ReadAll err = %v", got.Name, err)
+			continue
+		}
+
+		if !bytes.Equal(buf, want.content) {
+			t.Errorf("%v: ReadAll returned unexpected bytes", got.Name)
+		}
+	}
+}
+
 func testCreate(t *testing.T, w *Writer, wt *WriteTest) {
 	header := &FileHeader{
 		Name:   wt.Name,
@@ -378,15 +557,15 @@
 	testFileMode(t, f, wt.Mode)
 	rc, err := f.Open()
 	if err != nil {
-		t.Fatal("opening:", err)
+		t.Fatalf("opening %s: %v", f.Name, err)
 	}
 	b, err := io.ReadAll(rc)
 	if err != nil {
-		t.Fatal("reading:", err)
+		t.Fatalf("reading %s: %v", f.Name, err)
 	}
 	err = rc.Close()
 	if err != nil {
-		t.Fatal("closing:", err)
+		t.Fatalf("closing %s: %v", f.Name, err)
 	}
 	if !bytes.Equal(b, wt.Data) {
 		t.Errorf("File contents %q, want %q", b, wt.Data)
diff --git a/src/bufio/bufio.go b/src/bufio/bufio.go
index 6baf9b9..ec928e7 100644
--- a/src/bufio/bufio.go
+++ b/src/bufio/bufio.go
@@ -670,7 +670,8 @@
 // WriteRune writes a single Unicode code point, returning
 // the number of bytes written and any error.
 func (b *Writer) WriteRune(r rune) (size int, err error) {
-	if r < utf8.RuneSelf {
+	// Compare as uint32 to correctly handle negative runes.
+	if uint32(r) < utf8.RuneSelf {
 		err = b.WriteByte(byte(r))
 		if err != nil {
 			return 0, err
diff --git a/src/bufio/bufio_test.go b/src/bufio/bufio_test.go
index d7b34bd..ebcc711 100644
--- a/src/bufio/bufio_test.go
+++ b/src/bufio/bufio_test.go
@@ -534,6 +534,20 @@
 	}
 }
 
+func TestWriteInvalidRune(t *testing.T) {
+	// Invalid runes, including negative ones, should be written as the
+	// replacement character.
+	for _, r := range []rune{-1, utf8.MaxRune + 1} {
+		var buf bytes.Buffer
+		w := NewWriter(&buf)
+		w.WriteRune(r)
+		w.Flush()
+		if s := buf.String(); s != "\uFFFD" {
+			t.Errorf("WriteRune(%d) wrote %q, not replacement character", r, s)
+		}
+	}
+}
+
 func TestReadStringAllocs(t *testing.T) {
 	r := strings.NewReader("       foo       foo        42        42        42        42        42        42        42        42       4.2       4.2       4.2       4.2\n")
 	buf := NewReader(r)
diff --git a/src/bufio/scan.go b/src/bufio/scan.go
index af46a14..4846d4f 100644
--- a/src/bufio/scan.go
+++ b/src/bufio/scan.go
@@ -48,7 +48,8 @@
 // and the next token to return to the user, if any, plus an error, if any.
 //
 // Scanning stops if the function returns an error, in which case some of
-// the input may be discarded.
+// the input may be discarded. If that error is ErrFinalToken, scanning
+// stops with no error.
 //
 // Otherwise, the Scanner advances the input. If the token is not nil,
 // the Scanner returns it to the user. If the token is nil, the
diff --git a/src/bytes/boundary_test.go b/src/bytes/boundary_test.go
index ea84f1e..5a47526 100644
--- a/src/bytes/boundary_test.go
+++ b/src/bytes/boundary_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 //
+//go:build linux
 // +build linux
 
 package bytes_test
diff --git a/src/bytes/buffer.go b/src/bytes/buffer.go
index f19a4cf..549b077 100644
--- a/src/bytes/buffer.go
+++ b/src/bytes/buffer.go
@@ -275,7 +275,8 @@
 // included to match bufio.Writer's WriteRune. The buffer is grown as needed;
 // if it becomes too large, WriteRune will panic with ErrTooLarge.
 func (b *Buffer) WriteRune(r rune) (n int, err error) {
-	if r < utf8.RuneSelf {
+	// Compare as uint32 to correctly handle negative runes.
+	if uint32(r) < utf8.RuneSelf {
 		b.WriteByte(byte(r))
 		return 1, nil
 	}
diff --git a/src/bytes/buffer_test.go b/src/bytes/buffer_test.go
index fec5ef8..9c9b744 100644
--- a/src/bytes/buffer_test.go
+++ b/src/bytes/buffer_test.go
@@ -6,6 +6,7 @@
 
 import (
 	. "bytes"
+	"fmt"
 	"io"
 	"math/rand"
 	"testing"
@@ -387,6 +388,16 @@
 	}
 }
 
+func TestWriteInvalidRune(t *testing.T) {
+	// Invalid runes, including negative ones, should be written as
+	// utf8.RuneError.
+	for _, r := range []rune{-1, utf8.MaxRune + 1} {
+		var buf Buffer
+		buf.WriteRune(r)
+		check(t, fmt.Sprintf("TestWriteInvalidRune (%d)", r), &buf, "\uFFFD")
+	}
+}
+
 func TestNext(t *testing.T) {
 	b := []byte{0, 1, 2, 3, 4}
 	tmp := make([]byte, 5)
diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go
index efc2696..b07a238 100644
--- a/src/cmd/api/goapi.go
+++ b/src/cmd/api/goapi.go
@@ -215,8 +215,7 @@
 	}
 	optional := fileFeatures(*nextFile)
 	exception := fileFeatures(*exceptFile)
-	fail = !compareAPI(bw, features, required, optional, exception,
-		*allowNew && strings.Contains(runtime.Version(), "devel"))
+	fail = !compareAPI(bw, features, required, optional, exception, *allowNew)
 }
 
 // export emits the exported package features.
diff --git a/src/cmd/api/run.go b/src/cmd/api/run.go
index ecb1d0f..81979de 100644
--- a/src/cmd/api/run.go
+++ b/src/cmd/api/run.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // The run program is invoked via the dist tool.
@@ -9,8 +10,11 @@
 package main
 
 import (
+	"errors"
 	"fmt"
 	exec "internal/execabs"
+	"internal/goversion"
+	"io/fs"
 	"log"
 	"os"
 	"path/filepath"
@@ -42,6 +46,7 @@
 	apiDir := filepath.Join(goroot, "api")
 	out, err := exec.Command(goCmd(), "tool", "api",
 		"-c", findAPIDirFiles(apiDir),
+		allowNew(apiDir),
 		"-next", filepath.Join(apiDir, "next.txt"),
 		"-except", filepath.Join(apiDir, "except.txt")).CombinedOutput()
 	if err != nil {
@@ -70,3 +75,35 @@
 	}
 	return strings.Join(apiFiles, ",")
 }
+
+// allowNew returns the -allow_new flag to use for the 'go tool api' invocation.
+func allowNew(apiDir string) string {
+	// Verify that the api/go1.n.txt for previous Go version exists.
+	// It definitely should, otherwise it's a signal that the logic below may be outdated.
+	if _, err := os.Stat(filepath.Join(apiDir, fmt.Sprintf("go1.%d.txt", goversion.Version-1))); err != nil {
+		log.Fatalln("Problem with api file for previous release:", err)
+	}
+
+	// See whether the api/go1.n.txt for this Go version has been created.
+	// (As of April 2021, it gets created during the release of the first Beta.)
+	_, err := os.Stat(filepath.Join(apiDir, fmt.Sprintf("go1.%d.txt", goversion.Version)))
+	if errors.Is(err, fs.ErrNotExist) {
+		// It doesn't exist, so we're in development or before Beta 1.
+		// At this stage, unmentioned API additions are deemed okay.
+		// (They will be quietly shown in API check output, but the test won't fail).
+		return "-allow_new=true"
+	} else if err == nil {
+		// The api/go1.n.txt for this Go version has been created,
+		// so we're definitely past Beta 1 in the release cycle.
+		//
+		// From this point, enforce that api/go1.n.txt is an accurate and complete
+		// representation of what's going into the release by failing API check if
+		// there are API additions (a month into the freeze, there shouldn't be many).
+		//
+		// See golang.org/issue/43956.
+		return "-allow_new=false"
+	} else {
+		log.Fatal(err)
+	}
+	panic("unreachable")
+}
diff --git a/src/cmd/asm/internal/arch/arch.go b/src/cmd/asm/internal/arch/arch.go
index a62e551..026d8ab 100644
--- a/src/cmd/asm/internal/arch/arch.go
+++ b/src/cmd/asm/internal/arch/arch.go
@@ -109,6 +109,10 @@
 	register["SB"] = RSB
 	register["FP"] = RFP
 	register["PC"] = RPC
+	if linkArch == &x86.Linkamd64 {
+		// Alias g to R14
+		register["g"] = x86.REGG
+	}
 	// Register prefix not used on this architecture.
 
 	instructions := make(map[string]obj.As)
diff --git a/src/cmd/asm/internal/arch/arm64.go b/src/cmd/asm/internal/arch/arm64.go
index e557630..40d828a 100644
--- a/src/cmd/asm/internal/arch/arm64.go
+++ b/src/cmd/asm/internal/arch/arm64.go
@@ -147,7 +147,16 @@
 	return 0, false
 }
 
-// ARM64RegisterExtension parses an ARM64 register with extension or arrangement.
+// ARM64RegisterShift constructs an ARM64 register with shift operation.
+func ARM64RegisterShift(reg, op, count int16) (int64, error) {
+	// the base register of shift operations must be general register.
+	if reg > arm64.REG_R31 || reg < arm64.REG_R0 {
+		return 0, errors.New("invalid register for shift operation")
+	}
+	return int64(reg&31)<<16 | int64(op)<<22 | int64(uint16(count)), nil
+}
+
+// ARM64RegisterExtension constructs an ARM64 register with extension or arrangement.
 func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, isIndex bool) error {
 	Rnum := (reg & 31) + int16(num<<5)
 	if isAmount {
@@ -155,154 +164,163 @@
 			return errors.New("index shift amount is out of range")
 		}
 	}
-	switch ext {
-	case "UXTB":
-		if !isAmount {
-			return errors.New("invalid register extension")
-		}
-		if a.Type == obj.TYPE_MEM {
-			return errors.New("invalid shift for the register offset addressing mode")
-		}
-		a.Reg = arm64.REG_UXTB + Rnum
-	case "UXTH":
-		if !isAmount {
-			return errors.New("invalid register extension")
-		}
-		if a.Type == obj.TYPE_MEM {
-			return errors.New("invalid shift for the register offset addressing mode")
-		}
-		a.Reg = arm64.REG_UXTH + Rnum
-	case "UXTW":
-		if !isAmount {
-			return errors.New("invalid register extension")
-		}
-		// effective address of memory is a base register value and an offset register value.
-		if a.Type == obj.TYPE_MEM {
-			a.Index = arm64.REG_UXTW + Rnum
-		} else {
-			a.Reg = arm64.REG_UXTW + Rnum
-		}
-	case "UXTX":
-		if !isAmount {
-			return errors.New("invalid register extension")
-		}
-		if a.Type == obj.TYPE_MEM {
-			return errors.New("invalid shift for the register offset addressing mode")
-		}
-		a.Reg = arm64.REG_UXTX + Rnum
-	case "SXTB":
-		if !isAmount {
-			return errors.New("invalid register extension")
-		}
-		a.Reg = arm64.REG_SXTB + Rnum
-	case "SXTH":
-		if !isAmount {
-			return errors.New("invalid register extension")
-		}
-		if a.Type == obj.TYPE_MEM {
-			return errors.New("invalid shift for the register offset addressing mode")
-		}
-		a.Reg = arm64.REG_SXTH + Rnum
-	case "SXTW":
-		if !isAmount {
-			return errors.New("invalid register extension")
-		}
-		if a.Type == obj.TYPE_MEM {
-			a.Index = arm64.REG_SXTW + Rnum
-		} else {
-			a.Reg = arm64.REG_SXTW + Rnum
-		}
-	case "SXTX":
-		if !isAmount {
-			return errors.New("invalid register extension")
-		}
-		if a.Type == obj.TYPE_MEM {
-			a.Index = arm64.REG_SXTX + Rnum
-		} else {
-			a.Reg = arm64.REG_SXTX + Rnum
-		}
-	case "LSL":
-		if !isAmount {
-			return errors.New("invalid register extension")
-		}
-		a.Index = arm64.REG_LSL + Rnum
-	case "B8":
-		if isIndex {
-			return errors.New("invalid register extension")
-		}
-		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_8B & 15) << 5)
-	case "B16":
-		if isIndex {
-			return errors.New("invalid register extension")
-		}
-		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_16B & 15) << 5)
-	case "H4":
-		if isIndex {
-			return errors.New("invalid register extension")
-		}
-		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_4H & 15) << 5)
-	case "H8":
-		if isIndex {
-			return errors.New("invalid register extension")
-		}
-		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_8H & 15) << 5)
-	case "S2":
-		if isIndex {
-			return errors.New("invalid register extension")
-		}
-		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_2S & 15) << 5)
-	case "S4":
-		if isIndex {
-			return errors.New("invalid register extension")
-		}
-		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_4S & 15) << 5)
-	case "D1":
-		if isIndex {
-			return errors.New("invalid register extension")
-		}
-		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_1D & 15) << 5)
-	case "D2":
-		if isIndex {
-			return errors.New("invalid register extension")
-		}
-		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_2D & 15) << 5)
-	case "Q1":
-		if isIndex {
-			return errors.New("invalid register extension")
-		}
-		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_1Q & 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)
-	}
+	if reg <= arm64.REG_R31 && reg >= arm64.REG_R0 {
+		switch ext {
+		case "UXTB":
+			if !isAmount {
+				return errors.New("invalid register extension")
+			}
+			if a.Type == obj.TYPE_MEM {
+				return errors.New("invalid shift for the register offset addressing mode")
+			}
+			a.Reg = arm64.REG_UXTB + Rnum
+		case "UXTH":
+			if !isAmount {
+				return errors.New("invalid register extension")
+			}
+			if a.Type == obj.TYPE_MEM {
+				return errors.New("invalid shift for the register offset addressing mode")
+			}
+			a.Reg = arm64.REG_UXTH + Rnum
+		case "UXTW":
+			if !isAmount {
+				return errors.New("invalid register extension")
+			}
+			// effective address of memory is a base register value and an offset register value.
+			if a.Type == obj.TYPE_MEM {
+				a.Index = arm64.REG_UXTW + Rnum
+			} else {
+				a.Reg = arm64.REG_UXTW + Rnum
+			}
+		case "UXTX":
+			if !isAmount {
+				return errors.New("invalid register extension")
+			}
+			if a.Type == obj.TYPE_MEM {
+				return errors.New("invalid shift for the register offset addressing mode")
+			}
+			a.Reg = arm64.REG_UXTX + Rnum
+		case "SXTB":
+			if !isAmount {
+				return errors.New("invalid register extension")
+			}
+			a.Reg = arm64.REG_SXTB + Rnum
+		case "SXTH":
+			if !isAmount {
+				return errors.New("invalid register extension")
+			}
+			if a.Type == obj.TYPE_MEM {
+				return errors.New("invalid shift for the register offset addressing mode")
+			}
+			a.Reg = arm64.REG_SXTH + Rnum
+		case "SXTW":
+			if !isAmount {
+				return errors.New("invalid register extension")
+			}
+			if a.Type == obj.TYPE_MEM {
+				a.Index = arm64.REG_SXTW + Rnum
+			} else {
+				a.Reg = arm64.REG_SXTW + Rnum
+			}
+		case "SXTX":
+			if !isAmount {
+				return errors.New("invalid register extension")
+			}
+			if a.Type == obj.TYPE_MEM {
+				a.Index = arm64.REG_SXTX + Rnum
+			} else {
+				a.Reg = arm64.REG_SXTX + Rnum
+			}
+		case "LSL":
+			if !isAmount {
+				return errors.New("invalid register extension")
+			}
+			a.Index = arm64.REG_LSL + Rnum
+		default:
+			return errors.New("unsupported general register extension type: " + ext)
 
+		}
+	} else if reg <= arm64.REG_V31 && reg >= arm64.REG_V0 {
+		switch ext {
+		case "B8":
+			if isIndex {
+				return errors.New("invalid register extension")
+			}
+			a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_8B & 15) << 5)
+		case "B16":
+			if isIndex {
+				return errors.New("invalid register extension")
+			}
+			a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_16B & 15) << 5)
+		case "H4":
+			if isIndex {
+				return errors.New("invalid register extension")
+			}
+			a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_4H & 15) << 5)
+		case "H8":
+			if isIndex {
+				return errors.New("invalid register extension")
+			}
+			a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_8H & 15) << 5)
+		case "S2":
+			if isIndex {
+				return errors.New("invalid register extension")
+			}
+			a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_2S & 15) << 5)
+		case "S4":
+			if isIndex {
+				return errors.New("invalid register extension")
+			}
+			a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_4S & 15) << 5)
+		case "D1":
+			if isIndex {
+				return errors.New("invalid register extension")
+			}
+			a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_1D & 15) << 5)
+		case "D2":
+			if isIndex {
+				return errors.New("invalid register extension")
+			}
+			a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_2D & 15) << 5)
+		case "Q1":
+			if isIndex {
+				return errors.New("invalid register extension")
+			}
+			a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_1Q & 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 simd register extension type: " + ext)
+		}
+	} else {
+		return errors.New("invalid register and extension combination")
+	}
 	return nil
 }
 
-// ARM64RegisterArrangement parses an ARM64 vector register arrangement.
+// ARM64RegisterArrangement constructs an ARM64 vector register arrangement.
 func ARM64RegisterArrangement(reg int16, name, arng string) (int64, error) {
 	var curQ, curSize uint16
 	if name[0] != 'V' {
diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go
index c403275..cf0d155 100644
--- a/src/cmd/asm/internal/asm/asm.go
+++ b/src/cmd/asm/internal/asm/asm.go
@@ -134,6 +134,14 @@
 		next++
 	}
 
+	// Issue an error if we see a function defined as ABIInternal
+	// without NOSPLIT. In ABIInternal, obj needs to know the function
+	// signature in order to construct the morestack path, so this
+	// currently isn't supported for asm functions.
+	if nameAddr.Sym.ABI() == obj.ABIInternal && flag&obj.NOSPLIT == 0 {
+		p.errorf("TEXT %q: ABIInternal requires NOSPLIT", name)
+	}
+
 	// Next operand is the frame and arg size.
 	// Bizarre syntax: $frameSize-argSize is two words, not subtraction.
 	// Both frameSize and argSize must be simple integers; only frameSize
@@ -799,22 +807,11 @@
 		p.errorf("can't handle %s instruction with 4 operands", op)
 		return
 	case 5:
-		if p.arch.Family == sys.PPC64 && arch.IsPPC64RLD(op) {
-			// Always reg, reg, con, con, reg.  (con, con is a 'mask').
+		if p.arch.Family == sys.PPC64 {
 			prog.From = a[0]
+			// Second arg is always a register type on ppc64.
 			prog.Reg = p.getRegister(prog, op, &a[1])
-			mask1 := p.getConstant(prog, op, &a[2])
-			mask2 := p.getConstant(prog, op, &a[3])
-			var mask uint32
-			if mask1 < mask2 {
-				mask = (^uint32(0) >> uint(mask1)) & (^uint32(0) << uint(31-mask2))
-			} else {
-				mask = (^uint32(0) >> uint(mask2+1)) & (^uint32(0) << uint(31-(mask1-1)))
-			}
-			prog.SetFrom3(obj.Addr{
-				Type:   obj.TYPE_CONST,
-				Offset: int64(mask),
-			})
+			prog.SetRestArgs([]obj.Addr{a[2], a[3]})
 			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 7472507..ead8b27 100644
--- a/src/cmd/asm/internal/asm/endtoend_test.go
+++ b/src/cmd/asm/internal/asm/endtoend_test.go
@@ -8,6 +8,7 @@
 	"bufio"
 	"bytes"
 	"fmt"
+	"internal/buildcfg"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -19,7 +20,6 @@
 
 	"cmd/asm/internal/lex"
 	"cmd/internal/obj"
-	"cmd/internal/objabi"
 )
 
 // An end-to-end test for the assembler: Do we print what we parse?
@@ -36,6 +36,7 @@
 	var ok bool
 	testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
 	ctxt.Bso = bufio.NewWriter(os.Stdout)
+	ctxt.IsAsm = true
 	defer ctxt.Bso.Flush()
 	failed := false
 	ctxt.DiagFunc = func(format string, args ...interface{}) {
@@ -269,7 +270,7 @@
 	errQuotesRE = regexp.MustCompile(`"([^"]*)"`)
 )
 
-func testErrors(t *testing.T, goarch, file string) {
+func testErrors(t *testing.T, goarch, file string, flags ...string) {
 	input := filepath.Join("testdata", file+".s")
 	architecture, ctxt := setArch(goarch)
 	lexer := lex.NewLexer(input)
@@ -278,6 +279,7 @@
 	var ok bool
 	testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
 	ctxt.Bso = bufio.NewWriter(os.Stdout)
+	ctxt.IsAsm = true
 	defer ctxt.Bso.Flush()
 	failed := false
 	var errBuf bytes.Buffer
@@ -290,6 +292,14 @@
 		}
 		errBuf.WriteString(s)
 	}
+	for _, flag := range flags {
+		switch flag {
+		case "dynlink":
+			ctxt.Flag_dynlink = true
+		default:
+			t.Errorf("unknown flag %s", flag)
+		}
+	}
 	pList.Firstpc, ok = parser.Parse()
 	obj.Flushplist(ctxt, pList, nil, "")
 	if ok && !failed {
@@ -358,10 +368,10 @@
 }
 
 func TestARMEndToEnd(t *testing.T) {
-	defer func(old int) { objabi.GOARM = old }(objabi.GOARM)
+	defer func(old int) { buildcfg.GOARM = old }(buildcfg.GOARM)
 	for _, goarm := range []int{5, 6, 7} {
 		t.Logf("GOARM=%d", goarm)
-		objabi.GOARM = goarm
+		buildcfg.GOARM = goarm
 		testEndToEnd(t, "arm", "arm")
 		if goarm == 6 {
 			testEndToEnd(t, "arm", "armv6")
@@ -428,6 +438,10 @@
 	testErrors(t, "amd64", "amd64error")
 }
 
+func TestAMD64DynLinkErrors(t *testing.T) {
+	testErrors(t, "amd64", "amd64dynlinkerror", "dynlink")
+}
+
 func TestMIPSEndToEnd(t *testing.T) {
 	testEndToEnd(t, "mips", "mips")
 	testEndToEnd(t, "mips64", "mips64")
@@ -437,8 +451,12 @@
 	testEndToEnd(t, "ppc64", "ppc64")
 }
 
-func TestRISCVEncoder(t *testing.T) {
-	testEndToEnd(t, "riscv64", "riscvenc")
+func TestRISCVEndToEnd(t *testing.T) {
+	testEndToEnd(t, "riscv64", "riscv64")
+}
+
+func TestRISCVErrors(t *testing.T) {
+	testErrors(t, "riscv64", "riscv64error")
 }
 
 func TestS390XEndToEnd(t *testing.T) {
diff --git a/src/cmd/asm/internal/asm/operand_test.go b/src/cmd/asm/internal/asm/operand_test.go
index 2e83e17..8ef02b1 100644
--- a/src/cmd/asm/internal/asm/operand_test.go
+++ b/src/cmd/asm/internal/asm/operand_test.go
@@ -5,20 +5,20 @@
 package asm
 
 import (
+	"internal/buildcfg"
 	"strings"
 	"testing"
 
 	"cmd/asm/internal/arch"
 	"cmd/asm/internal/lex"
 	"cmd/internal/obj"
-	"cmd/internal/objabi"
 )
 
 // A simple in-out test: Do we print what we parse?
 
 func setArch(goarch string) (*arch.Arch, *obj.Link) {
-	objabi.GOOS = "linux" // obj can handle this OS for all architectures.
-	objabi.GOARCH = goarch
+	buildcfg.GOOS = "linux" // obj can handle this OS for all architectures.
+	buildcfg.GOARCH = goarch
 	architecture := arch.Set(goarch)
 	if architecture == nil {
 		panic("asm: unrecognized architecture " + goarch)
@@ -259,6 +259,7 @@
 	{"R15", "R15"},
 	{"R8", "R8"},
 	{"R9", "R9"},
+	{"g", "R14"},
 	{"SI", "SI"},
 	{"SP", "SP"},
 	{"X0", "X0"},
diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go
index 154cf9c..4cddcf4 100644
--- a/src/cmd/asm/internal/asm/parse.go
+++ b/src/cmd/asm/internal/asm/parse.go
@@ -305,7 +305,7 @@
 // references and writes symabis information to w.
 //
 // The symabis format is documented at
-// cmd/compile/internal/gc.readSymABIs.
+// cmd/compile/internal/ssagen.ReadSymABIs.
 func (p *Parser) symDefRef(w io.Writer, word string, operands [][]lex.Token) {
 	switch word {
 	case "TEXT":
@@ -689,7 +689,11 @@
 		p.errorf("unexpected %s in register shift", tok.String())
 	}
 	if p.arch.Family == sys.ARM64 {
-		return int64(r1&31)<<16 | int64(op)<<22 | int64(uint16(count))
+		off, err := arch.ARM64RegisterShift(r1, op, count)
+		if err != nil {
+			p.errorf(err.Error())
+		}
+		return off
 	} else {
 		return int64((r1 & 15) | op<<5 | count)
 	}
@@ -999,15 +1003,18 @@
 				p.errorf("unimplemented two-register form")
 			}
 			a.Index = r1
-			if scale == 0 && p.arch.Family == sys.ARM64 {
-				// scale is 1 by default for ARM64
-				a.Scale = 1
+			if scale != 0 && scale != 1 && p.arch.Family == sys.ARM64 {
+				// Support (R1)(R2) (no scaling) and (R1)(R2*1).
+				p.errorf("arm64 doesn't support scaled register format")
 			} else {
 				a.Scale = int16(scale)
 			}
 		}
 		p.get(')')
 	} else if scale != 0 {
+		if p.arch.Family == sys.ARM64 {
+			p.errorf("arm64 doesn't support scaled register format")
+		}
 		// First (R) was missing, all we have is (R*scale).
 		a.Reg = 0
 		a.Index = r1
diff --git a/src/cmd/asm/internal/asm/pseudo_test.go b/src/cmd/asm/internal/asm/pseudo_test.go
index 622ee25..fe6ffa6 100644
--- a/src/cmd/asm/internal/asm/pseudo_test.go
+++ b/src/cmd/asm/internal/asm/pseudo_test.go
@@ -25,11 +25,13 @@
 
 func TestErroneous(t *testing.T) {
 
-	tests := []struct {
+	type errtest struct {
 		pseudo   string
 		operands string
 		expected string
-	}{
+	}
+
+	nonRuntimeTests := []errtest{
 		{"TEXT", "", "expect two or three operands for TEXT"},
 		{"TEXT", "%", "expect two or three operands for TEXT"},
 		{"TEXT", "1, 1", "TEXT symbol \"<erroneous symbol>\" must be a symbol(SB)"},
@@ -58,23 +60,44 @@
 		{"PCDATA", "1", "expect two operands for PCDATA"},
 	}
 
+	runtimeTests := []errtest{
+		{"TEXT", "foo<ABIInternal>(SB),0", "TEXT \"foo\": ABIInternal requires NOSPLIT"},
+	}
+
+	testcats := []struct {
+		compilingRuntime bool
+		tests            []errtest
+	}{
+		{
+			compilingRuntime: false,
+			tests:            nonRuntimeTests,
+		},
+		{
+			compilingRuntime: true,
+			tests:            runtimeTests,
+		},
+	}
+
 	// Note these errors should be independent of the architecture.
 	// Just run the test with amd64.
 	parser := newParser("amd64")
 	var buf bytes.Buffer
 	parser.errorWriter = &buf
 
-	for _, test := range tests {
-		parser.errorCount = 0
-		parser.lineNum++
-		if !parser.pseudo(test.pseudo, tokenize(test.operands)) {
-			t.Fatalf("Wrong pseudo-instruction: %s", test.pseudo)
+	for _, cat := range testcats {
+		for _, test := range cat.tests {
+			parser.compilingRuntime = cat.compilingRuntime
+			parser.errorCount = 0
+			parser.lineNum++
+			if !parser.pseudo(test.pseudo, tokenize(test.operands)) {
+				t.Fatalf("Wrong pseudo-instruction: %s", test.pseudo)
+			}
+			errorLine := buf.String()
+			if test.expected != errorLine {
+				t.Errorf("Unexpected error %q; expected %q", errorLine, test.expected)
+			}
+			buf.Reset()
 		}
-		errorLine := buf.String()
-		if test.expected != errorLine {
-			t.Errorf("Unexpected error %q; expected %q", errorLine, test.expected)
-		}
-		buf.Reset()
 	}
 
 }
diff --git a/src/cmd/asm/internal/asm/testdata/amd64dynlinkerror.s b/src/cmd/asm/internal/asm/testdata/amd64dynlinkerror.s
new file mode 100644
index 0000000..1eee1a1
--- /dev/null
+++ b/src/cmd/asm/internal/asm/testdata/amd64dynlinkerror.s
@@ -0,0 +1,68 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test to make sure that if we use R15 after it is clobbered by
+// a global variable access while dynamic linking, we get an error.
+// See issue 43661.
+
+TEXT ·a1(SB), 0, $0-0
+	CMPL runtime·writeBarrier(SB), $0
+	MOVL $0, R15
+	RET
+TEXT ·a2(SB), 0, $0-0
+	CMPL runtime·writeBarrier(SB), $0
+	MOVQ $0, R15
+	RET
+TEXT ·a3(SB), 0, $0-0
+	CMPL runtime·writeBarrier(SB), $0
+	XORL R15, R15
+	RET
+TEXT ·a4(SB), 0, $0-0
+	CMPL runtime·writeBarrier(SB), $0
+	XORQ R15, R15
+	RET
+TEXT ·a5(SB), 0, $0-0
+	CMPL runtime·writeBarrier(SB), $0
+	XORL R15, R15
+	RET
+TEXT ·a6(SB), 0, $0-0
+	CMPL runtime·writeBarrier(SB), $0
+	POPQ R15
+	PUSHQ R15
+	RET
+TEXT ·a7(SB), 0, $0-0
+	CMPL runtime·writeBarrier(SB), $0
+	MOVQ R15, AX // ERROR "when dynamic linking, R15 is clobbered by a global variable access and is used here"
+	RET
+TEXT ·a8(SB), 0, $0-0
+	CMPL runtime·writeBarrier(SB), $0
+	ADDQ AX, R15 // ERROR "when dynamic linking, R15 is clobbered by a global variable access and is used here"
+	RET
+TEXT ·a9(SB), 0, $0-0
+	CMPL runtime·writeBarrier(SB), $0
+	ORQ R15, R15 // ERROR "when dynamic linking, R15 is clobbered by a global variable access and is used here"
+	RET
+TEXT ·a10(SB), 0, $0-0
+	CMPL runtime·writeBarrier(SB), $0
+	JEQ one
+	ORQ R15, R15 // ERROR "when dynamic linking, R15 is clobbered by a global variable access and is used here"
+one:
+	RET
+TEXT ·a11(SB), 0, $0-0
+	CMPL runtime·writeBarrier(SB), $0
+	JEQ one
+	JMP two
+one:
+	ORQ R15, R15 // ERROR "when dynamic linking, R15 is clobbered by a global variable access and is used here"
+two:
+	RET
+TEXT ·a12(SB), 0, $0-0
+	CMPL runtime·writeBarrier(SB), $0
+	JMP one
+two:
+	ORQ R15, R15
+	RET
+one:
+	MOVL $0, R15
+	JMP two
diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s
index 91e3a0c..d8a20ed 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64.s
@@ -64,6 +64,16 @@
 	CMN	R1.SXTX<<2, R10                 // 5fe921ab
 	CMPW	R2.UXTH<<3, R11                 // 7f2d226b
 	CMNW	R1.SXTB, R9                     // 3f81212b
+	ADD	R1<<1, RSP, R3                  // e367218b
+	ADDW	R1<<2, R3, RSP                  // 7f48210b
+	SUB	R1<<3, RSP                      // ff6f21cb
+	SUBS	R1<<4, RSP, R3                  // e37321eb
+	ADDS	R1<<1, RSP, R4                  // e46721ab
+	CMP	R1<<2, RSP                      // ff6b21eb
+	CMN	R1<<3, RSP                      // ff6f21ab
+	ADDS	R1<<1, ZR, R4                   // e40701ab
+	ADD	R3<<50, ZR, ZR                  // ffcb038b
+	CMP	R4<<24, ZR                      // ff6304eb
 	CMPW	$0x60060, R2                    // CMPW	$393312, R2                       // 1b0c8052db00a0725f001b6b
 	CMPW	$40960, R0                      // 1f284071
 	CMPW	$27745, R2                      // 3b8c8d525f001b6b
@@ -79,7 +89,7 @@
 	CMP	R1<<33, R2
 	CMP	R22.SXTX, RSP                    // ffe336eb
 	CMP	$0x22220000, RSP                 // CMP $572653568, RSP   // 5b44a4d2ff633beb
-	CMPW	$0x22220000, RSP                 // CMPW $572653568, RSP  // 5b44a452ff633b6b
+	CMPW	$0x22220000, RSP                 // CMPW $572653568, RSP  // 5b44a452ff433b6b
 	CCMN	MI, ZR, R1, $4	                 // e44341ba
 	// MADD Rn,Rm,Ra,Rd
 	MADD	R1, R2, R3, R4                   // 6408019b
@@ -207,6 +217,18 @@
 	VUADDW2	V9.B16, V12.H8, V14.H8          // 8e11296e
 	VUADDW2	V13.H8, V20.S4, V30.S4          // 9e126d6e
 	VUADDW2	V21.S4, V24.D2, V29.D2          // 1d13b56e
+	VUMAX	V3.B8, V2.B8, V1.B8             // 4164232e
+	VUMAX	V3.B16, V2.B16, V1.B16          // 4164236e
+	VUMAX	V3.H4, V2.H4, V1.H4             // 4164632e
+	VUMAX	V3.H8, V2.H8, V1.H8             // 4164636e
+	VUMAX	V3.S2, V2.S2, V1.S2             // 4164a32e
+	VUMAX	V3.S4, V2.S4, V1.S4             // 4164a36e
+	VUMIN	V3.B8, V2.B8, V1.B8             // 416c232e
+	VUMIN	V3.B16, V2.B16, V1.B16          // 416c236e
+	VUMIN	V3.H4, V2.H4, V1.H4             // 416c632e
+	VUMIN	V3.H8, V2.H8, V1.H8             // 416c636e
+	VUMIN	V3.S2, V2.S2, V1.S2             // 416ca32e
+	VUMIN	V3.S4, V2.S4, V1.S4             // 416ca36e
 	FCCMPS	LT, F1, F2, $1	                // 41b4211e
 	FMADDS	F1, F3, F2, F4                  // 440c011f
 	FMADDD	F4, F5, F4, F4                  // 8414441f
@@ -352,6 +374,10 @@
 	MOVD	$1, ZR
 	MOVD	$1, R1
 	MOVK	$1, R1
+	MOVD	$0x1000100010001000, RSP      // MOVD	$1152939097061330944, RSP   // ff8304b2
+	MOVW	$0x10001000, RSP              // MOVW	$268439552, RSP             // ff830432
+	ADDW	$0x10001000, R1               // ADDW	$268439552, R1              // fb83043221001b0b
+	ADDW	$0x22220000, RSP, R3          // ADDW	$572653568, RSP, R3         // 5b44a452e3433b0b
 
 // move a large constant to a Vd.
 	VMOVS	$0x80402010, V11                                      // VMOVS	$2151686160, V11
@@ -380,13 +406,13 @@
 // LD1/ST1
 	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	(R8)(R20), [V21.B16, V22.B16]                   // 15a1d44c
 	VLD1.P	64(R1), [V5.B16, V6.B16, V7.B16, V8.B16]        // 2520df4c
 	VLD1.P	1(R0), V4.B[15]                                 // 041cdf4d
 	VLD1.P	2(R0), V4.H[7]                                  // 0458df4d
 	VLD1.P	4(R0), V4.S[3]                                  // 0490df4d
 	VLD1.P	8(R0), V4.D[1]                                  // 0484df4d
-	VLD1.P	(R0)(R1), V4.D[1]                               // VLD1.P	(R0)(R1*1), V4.D[1] // 0484c14d
+	VLD1.P	(R0)(R1), V4.D[1]                               // 0484c14d
 	VLD1	(R0), V4.D[1]                                   // 0484404d
 	VST1.P	[V4.S4, V5.S4], 32(R1)                          // 24a89f4c
 	VST1	[V0.S4, V1.S4], (R0)                            // 00a8004c
@@ -394,29 +420,29 @@
 	VLD1.P	24(R30), [V3.S2,V4.S2,V5.S2]                    // c36bdf0c
 	VLD2	(R29), [V23.H8, V24.H8]                         // b787404c
 	VLD2.P	16(R0), [V18.B8, V19.B8]                        // 1280df0c
-	VLD2.P	(R1)(R2), [V15.S2, V16.S2]                      // VLD2.P	(R1)(R2*1), [V15.S2,V16.S2] // 2f88c20c
+	VLD2.P	(R1)(R2), [V15.S2, V16.S2]                      // 2f88c20c
 	VLD3	(R27), [V11.S4, V12.S4, V13.S4]                 // 6b4b404c
 	VLD3.P	48(RSP), [V11.S4, V12.S4, V13.S4]               // eb4bdf4c
-	VLD3.P	(R30)(R2), [V14.D2, V15.D2, V16.D2]             // VLD3.P	(R30)(R2*1), [V14.D2,V15.D2,V16.D2] // ce4fc24c
+	VLD3.P	(R30)(R2), [V14.D2, V15.D2, V16.D2]             // ce4fc24c
 	VLD4	(R15), [V10.H4, V11.H4, V12.H4, V13.H4]         // ea05400c
 	VLD4.P	32(R24), [V31.B8, V0.B8, V1.B8, V2.B8]          // 1f03df0c
-	VLD4.P	(R13)(R9), [V14.S2, V15.S2, V16.S2, V17.S2]     // VLD4.P	(R13)(R9*1), [V14.S2,V15.S2,V16.S2,V17.S2] // ae09c90c
+	VLD4.P	(R13)(R9), [V14.S2, V15.S2, V16.S2, V17.S2]     // ae09c90c
 	VLD1R	(R1), [V9.B8]                                   // 29c0400d
 	VLD1R.P	(R1), [V9.B8]                                   // 29c0df0d
 	VLD1R.P	1(R1), [V2.B8]                                  // 22c0df0d
 	VLD1R.P	2(R1), [V2.H4]                                  // 22c4df0d
 	VLD1R	(R0), [V0.B16]                                  // 00c0404d
 	VLD1R.P	(R0), [V0.B16]                                  // 00c0df4d
-	VLD1R.P	(R15)(R1), [V15.H4]                             // VLD1R.P	(R15)(R1*1), [V15.H4] // efc5c10d
+	VLD1R.P	(R15)(R1), [V15.H4]                             // efc5c10d
 	VLD2R	(R15), [V15.H4, V16.H4]                         // efc5600d
 	VLD2R.P	16(R0), [V0.D2, V1.D2]                          // 00ccff4d
-	VLD2R.P	(R0)(R5), [V31.D1, V0.D1]                       // VLD2R.P	(R0)(R5*1), [V31.D1, V0.D1] // 1fcce50d
+	VLD2R.P	(R0)(R5), [V31.D1, V0.D1]                       // 1fcce50d
 	VLD3R	(RSP), [V31.S2, V0.S2, V1.S2]                   // ffeb400d
 	VLD3R.P	6(R15), [V15.H4, V16.H4, V17.H4]                // efe5df0d
-	VLD3R.P	(R15)(R6), [V15.H8, V16.H8, V17.H8]             // VLD3R.P	(R15)(R6*1), [V15.H8, V16.H8, V17.H8] // efe5c64d
+	VLD3R.P	(R15)(R6), [V15.H8, V16.H8, V17.H8]             // efe5c64d
 	VLD4R	(R0), [V0.B8, V1.B8, V2.B8, V3.B8]              // 00e0600d
 	VLD4R.P	16(RSP), [V31.S4, V0.S4, V1.S4, V2.S4]          // ffebff4d
-	VLD4R.P	(R15)(R9), [V15.H4, V16.H4, V17.H4, V18.H4]     // VLD4R.P	(R15)(R9*1), [V15.H4, V16.H4, V17.H4, V18.H4] // efe5e90d
+	VLD4R.P	(R15)(R9), [V15.H4, V16.H4, V17.H4, V18.H4]     // efe5e90d
 	VST1.P	[V24.S2], 8(R2)                                 // 58789f0c
 	VST1	[V29.S2, V30.S2], (R29)                         // bdab000c
 	VST1	[V14.H4, V15.H4, V16.H4], (R27)                 // 6e67000c
@@ -424,17 +450,17 @@
 	VST1.P	V4.H[7], 2(R0)                                  // 04589f4d
 	VST1.P	V4.S[3], 4(R0)                                  // 04909f4d
 	VST1.P	V4.D[1], 8(R0)                                  // 04849f4d
-	VST1.P	V4.D[1], (R0)(R1)                               // VST1.P	V4.D[1], (R0)(R1*1) // 0484814d
+	VST1.P	V4.D[1], (R0)(R1)                               // 0484814d
 	VST1	V4.D[1], (R0)                                   // 0484004d
 	VST2	[V22.H8, V23.H8], (R23)                         // f686004c
 	VST2.P	[V14.H4, V15.H4], 16(R17)                       // 2e869f0c
-	VST2.P	[V14.H4, V15.H4], (R3)(R17)                     // VST2.P	[V14.H4,V15.H4], (R3)(R17*1) // 6e84910c
+	VST2.P	[V14.H4, V15.H4], (R3)(R17)                     // 6e84910c
 	VST3	[V1.D2, V2.D2, V3.D2], (R11)                    // 614d004c
 	VST3.P	[V18.S4, V19.S4, V20.S4], 48(R25)               // 324b9f4c
-	VST3.P	[V19.B8, V20.B8, V21.B8], (R3)(R7)              // VST3.P	[V19.B8, V20.B8, V21.B8], (R3)(R7*1) // 7340870c
+	VST3.P	[V19.B8, V20.B8, V21.B8], (R3)(R7)              // 7340870c
 	VST4	[V22.D2, V23.D2, V24.D2, V25.D2], (R3)          // 760c004c
 	VST4.P	[V14.D2, V15.D2, V16.D2, V17.D2], 64(R15)       // ee0d9f4c
-	VST4.P	[V24.B8, V25.B8, V26.B8, V27.B8], (R3)(R23)     // VST4.P	[V24.B8, V25.B8, V26.B8, V27.B8], (R3)(R23*1) // 7800970c
+	VST4.P	[V24.B8, V25.B8, V26.B8, V27.B8], (R3)(R23)     // 7800970c
 
 // pre/post-indexed
 	FMOVS.P	F20, 4(R0)                                      // 144400bc
@@ -521,29 +547,30 @@
 
 // shifted or extended register offset.
 	MOVD	(R2)(R6.SXTW), R4               // 44c866f8
-	MOVD	(R3)(R6), R5                    // MOVD	(R3)(R6*1), R5               // 656866f8
-	MOVD	(R2)(R6), R4                    // MOVD	(R2)(R6*1), R4               // 446866f8
+	MOVD	(R3)(R6), R5                    // 656866f8
+	MOVD	(R3)(R6*1), R5                  // 656866f8
+	MOVD	(R2)(R6), R4                    // 446866f8
 	MOVWU	(R19)(R20<<2), R20              // 747a74b8
 	MOVD	(R2)(R6<<3), R4                 // 447866f8
 	MOVD	(R3)(R7.SXTX<<3), R8            // 68f867f8
 	MOVWU	(R5)(R4.UXTW), R10              // aa4864b8
 	MOVBU	(R3)(R9.UXTW), R8               // 68486938
-	MOVBU	(R5)(R8), R10                   // MOVBU	(R5)(R8*1), R10      // aa686838
+	MOVBU	(R5)(R8), R10                   // aa686838
 	MOVHU	(R2)(R7.SXTW<<1), R11           // 4bd86778
 	MOVHU	(R1)(R2<<1), R5                 // 25786278
 	MOVB	(R9)(R3.UXTW), R6               // 2649a338
-	MOVB	(R10)(R6), R15                  // MOVB	(R10)(R6*1), R15             // 4f69a638
+	MOVB	(R10)(R6), R15                  // 4f69a638
 	MOVB	(R29)(R30<<0), R14              // ae7bbe38
-	MOVB	(R29)(R30), R14                 // MOVB	(R29)(R30*1), R14            // ae6bbe38
+	MOVB	(R29)(R30), R14                 // ae6bbe38
 	MOVH	(R5)(R7.SXTX<<1), R19           // b3f8a778
 	MOVH	(R8)(R4<<1), R10                // 0a79a478
 	MOVW	(R9)(R8.SXTW<<2), R19           // 33d9a8b8
 	MOVW	(R1)(R4.SXTX), R11              // 2be8a4b8
 	MOVW	(R1)(R4.SXTX), ZR               // 3fe8a4b8
-	MOVW	(R2)(R5), R12                   // MOVW	(R2)(R5*1), R12               // 4c68a5b8
-	FMOVS	(R2)(R6), F4                    // FMOVS	(R2)(R6*1), F4        // 446866bc
+	MOVW	(R2)(R5), R12                   // 4c68a5b8
+	FMOVS	(R2)(R6), F4                    // 446866bc
 	FMOVS	(R2)(R6<<2), F4                 // 447866bc
-	FMOVD	(R2)(R6), F4                    // FMOVD	(R2)(R6*1), F4        // 446866fc
+	FMOVD	(R2)(R6), F4                    // 446866fc
 	FMOVD	(R2)(R6<<3), F4                 // 447866fc
 
 	MOVD	R5, (R2)(R6<<3)                 // 457826f8
@@ -553,15 +580,16 @@
 	MOVW	R7, (R3)(R4.SXTW)               // 67c824b8
 	MOVB	R4, (R2)(R6.SXTX)               // 44e82638
 	MOVB	R8, (R3)(R9.UXTW)               // 68482938
-	MOVB	R10, (R5)(R8)                   // MOVB	R10, (R5)(R8*1)               // aa682838
+	MOVB	R10, (R5)(R8)                   // aa682838
+	MOVB	R10, (R5)(R8*1)                 // aa682838
 	MOVH	R11, (R2)(R7.SXTW<<1)           // 4bd82778
 	MOVH	R5, (R1)(R2<<1)                 // 25782278
 	MOVH	R7, (R2)(R5.SXTX<<1)            // 47f82578
 	MOVH	R8, (R3)(R6.UXTW)               // 68482678
 	MOVB	R4, (R2)(R6.SXTX)               // 44e82638
-	FMOVS	F4, (R2)(R6)                    // FMOVS	F4, (R2)(R6*1)        // 446826bc
+	FMOVS	F4, (R2)(R6)                    // 446826bc
 	FMOVS	F4, (R2)(R6<<2)                 // 447826bc
-	FMOVD	F4, (R2)(R6)                    // FMOVD	F4, (R2)(R6*1)        // 446826fc
+	FMOVD	F4, (R2)(R6)                    // 446826fc
 	FMOVD	F4, (R2)(R6<<3)                 // 447826fc
 
 // vmov
@@ -571,9 +599,12 @@
 	VMOV	R20, V1.S[0]          // 811e044e
 	VMOV	R20, V1.S[1]          // 811e0c4e
 	VMOV	R1, V9.H4             // 290c020e
+	VDUP	R1, V9.H4             // 290c020e
 	VMOV	R22, V11.D2           // cb0e084e
+	VDUP	R22, V11.D2           // cb0e084e
 	VMOV	V2.B16, V4.B16        // 441ca24e
 	VMOV	V20.S[0], V20         // 9406045e
+	VDUP	V20.S[0], V20         // 9406045e
 	VMOV	V12.D[0], V12.D[1]    // 8c05186e
 	VMOV	V10.S[0], V12.S[1]    // 4c050c6e
 	VMOV	V9.H[0], V12.H[1]     // 2c05066e
@@ -982,6 +1013,54 @@
 	FSTPS	(F3, F4), x(SB)
 	FSTPS	(F3, F4), x+8(SB)
 
+// FLDPQ/FSTPQ
+	FLDPQ   -4000(R0), (F1, F2)  // 1b803ed1610b40ad
+	FLDPQ	-1024(R0), (F1, F2)  // 010860ad
+	FLDPQ	(R0), (F1, F2)       // 010840ad
+	FLDPQ	16(R0), (F1, F2)     // 018840ad
+	FLDPQ	-16(R0), (F1, F2)    // 01887fad
+	FLDPQ.W	32(R0), (F1, F2)     // 0108c1ad
+	FLDPQ.P	32(R0), (F1, F2)     // 0108c1ac
+	FLDPQ	11(R0), (F1, F2)     // 1b2c0091610b40ad
+	FLDPQ	1024(R0), (F1, F2)   // 1b001091610b40ad
+	FLDPQ   4104(R0), (F1, F2)
+	FLDPQ   -4000(RSP), (F1, F2) // fb833ed1610b40ad
+	FLDPQ	-1024(RSP), (F1, F2) // e10b60ad
+	FLDPQ	(RSP), (F1, F2)      // e10b40ad
+	FLDPQ	16(RSP), (F1, F2)    // e18b40ad
+	FLDPQ	-16(RSP), (F1, F2)   // e18b7fad
+	FLDPQ.W	32(RSP), (F1, F2)    // e10bc1ad
+	FLDPQ.P	32(RSP), (F1, F2)    // e10bc1ac
+	FLDPQ	11(RSP), (F1, F2)    // fb2f0091610b40ad
+	FLDPQ	1024(RSP), (F1, F2)  // fb031091610b40ad
+	FLDPQ   4104(RSP), (F1, F2)
+	FLDPQ	-31(R0), (F1, F2)    // 1b7c00d1610b40ad
+	FLDPQ	-4(R0), (F1, F2)     // 1b1000d1610b40ad
+	FLDPQ	x(SB), (F1, F2)
+	FLDPQ	x+8(SB), (F1, F2)
+	FSTPQ	(F3, F4), -4000(R5)  // bb803ed1631300ad
+	FSTPQ	(F3, F4), -1024(R5)  // a31020ad
+	FSTPQ	(F3, F4), (R5)       // a31000ad
+	FSTPQ	(F3, F4), 16(R5)     // a39000ad
+	FSTPQ	(F3, F4), -16(R5)    // a3903fad
+	FSTPQ.W	(F3, F4), 32(R5)     // a31081ad
+	FSTPQ.P	(F3, F4), 32(R5)     // a31081ac
+	FSTPQ	(F3, F4), 11(R5)     // bb2c0091631300ad
+	FSTPQ	(F3, F4), 1024(R5)   // bb001091631300ad
+	FSTPQ	(F3, F4), 4104(R5)
+	FSTPQ	(F3, F4), -4000(RSP) // fb833ed1631300ad
+	FSTPQ	(F3, F4), -1024(RSP) // e31320ad
+	FSTPQ	(F3, F4), (RSP)      // e31300ad
+	FSTPQ	(F3, F4), 16(RSP)    // e39300ad
+	FSTPQ	(F3, F4), -16(RSP)   // e3933fad
+	FSTPQ.W	(F3, F4), 32(RSP)    // e31381ad
+	FSTPQ.P	(F3, F4), 32(RSP)    // e31381ac
+	FSTPQ	(F3, F4), 11(RSP)    // fb2f0091631300ad
+	FSTPQ	(F3, F4), 1024(RSP)  // fb031091631300ad
+	FSTPQ	(F3, F4), 4104(RSP)
+	FSTPQ	(F3, F4), x(SB)
+	FSTPQ	(F3, F4), x+8(SB)
+
 // System Register
 	MSR	$1, SPSel                          // bf4100d5
 	MSR	$9, DAIFSet                        // df4903d5
diff --git a/src/cmd/asm/internal/asm/testdata/arm64enc.s b/src/cmd/asm/internal/asm/testdata/arm64enc.s
index e802ee7..a298628 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64enc.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64enc.s
@@ -188,7 +188,7 @@
    MOVBU 2916(R24), R3                        // 03936d39
    MOVBU (R19)(R14<<0), R23                   // 777a6e38
    MOVBU (R2)(R8.SXTX), R19                   // 53e86838
-   MOVBU (R27)(R23), R14                      // MOVBU (R27)(R23*1), R14     // 6e6b7738
+   MOVBU (R27)(R23), R14                      // 6e6b7738
    MOVHU.P 107(R14), R13                      // cdb54678
    MOVHU.W 192(R3), R2                        // 620c4c78
    MOVHU 6844(R4), R19                        // 93787579
@@ -201,9 +201,9 @@
    MOVB 997(R9), R23                          // 37958f39
    //TODO MOVBW (R2<<1)(R21), R15             // af7ae238
    //TODO MOVBW (R26)(R0), R21                // 1568fa38
-   MOVB (R5)(R15), R16                        // MOVB (R5)(R15*1), R16         // b068af38
+   MOVB (R5)(R15), R16                        // b068af38
    MOVB (R19)(R26.SXTW), R19                  // 73caba38
-   MOVB (R29)(R30), R14                       // MOVB (R29)(R30*1), R14        // ae6bbe38
+   MOVB (R29)(R30), R14                       // ae6bbe38
    //TODO MOVHW.P 218(R22), R25               // d9a6cd78
    MOVH.P 179(R23), R5                        // e5368b78
    //TODO MOVHW.W 136(R2), R27                // 5b8cc878
@@ -357,12 +357,12 @@
    MOVD R25, -137(R17)                        // 397217f8
    MOVW R4, (R12)(R22.UXTW<<2)                // 845936b8
    MOVD R27, (R5)(R15.UXTW<<3)                // bb582ff8
-   MOVB R2, (R10)(R16)                        // MOVB R2, (R10)(R16*1)         // 42693038
-   MOVB R2, (R29)(R26)                        // MOVB R2, (R29)(R26*1)         // a26b3a38
+   MOVB R2, (R10)(R16)                        // 42693038
+   MOVB R2, (R29)(R26)                        // a26b3a38
    MOVH R11, -80(R23)                         // eb021b78
    MOVH R11, (R27)(R14.SXTW<<1)               // 6bdb2e78
-   MOVB R19, (R0)(R4)                         // MOVB R19, (R0)(R4*1)          // 13682438
-   MOVB R1, (R6)(R4)                          // MOVB R1, (R6)(R4*1)           // c1682438
+   MOVB R19, (R0)(R4)                         // 13682438
+   MOVB R1, (R6)(R4)                          // c1682438
    MOVH R3, (R11)(R13<<1)                     // 63792d78
    //TODO STTR 55(R4), R29                    // 9d7803b8
    //TODO STTR 124(R5), R25                   // b9c807f8
@@ -669,6 +669,7 @@
    VCMEQ V24.S4, V13.S4, V12.S4                                // ac8db86e
    VCNT V13.B8, V11.B8                                         // ab59200e
    VMOV V31.B[15], V18                                         // f2071f5e
+   VDUP V31.B[15], V18                                         // f2071f5e
    VDUP V31.B[13], V20.B16                                     // f4071b4e
    VEOR V4.B8, V18.B8, V7.B8                                   // 471e242e
    VEXT $4, V2.B8, V1.B8, V3.B8                                // 2320022e
@@ -679,27 +680,28 @@
    VLD1 (R24), [V18.D1, V19.D1, V20.D1]                        // 126f400c
    VLD1 (R29), [V14.D1, V15.D1, V16.D1, V17.D1]                // ae2f400c
    VLD1.P 16(R23), [V1.B16]                                    // e172df4c
-   VLD1.P (R6)(R11), [V31.D1]                                  // VLD1.P (R6)(R11*1), [V31.D1]                 // df7ccb0c
+   VLD1.P (R6)(R11), [V31.D1]                                  // df7ccb0c
    VLD1.P 16(R7), [V31.D1, V0.D1]                              // ffacdf0c
-   VLD1.P (R19)(R4), [V24.B8, V25.B8]                          // VLD1.P (R19)(R4*1), [V24.B8, V25.B8]         // 78a2c40c
-   VLD1.P (R20)(R8), [V7.H8, V8.H8, V9.H8]                     // VLD1.P (R20)(R8*1), [V7.H8, V8.H8, V9.H8]    // 8766c84c
+   VLD1.P (R19)(R4), [V24.B8, V25.B8]                          // 78a2c40c
+   VLD1.P (R20)(R8), [V7.H8, V8.H8, V9.H8]                     // 8766c84c
    VLD1.P 32(R30), [V5.B8, V6.B8, V7.B8, V8.B8]                // c523df0c
    VLD1 (R19), V14.B[15]                                       // 6e1e404d
    VLD1 (R29), V0.H[1]                                         // a04b400d
    VLD1 (R27), V2.S[0]                                         // 6283400d
    VLD1 (R21), V5.D[1]                                         // a586404d
    VLD1.P 1(R19), V10.B[14]                                    // 6a1adf4d
-   VLD1.P (R3)(R14), V16.B[11]                                 // VLD1.P (R3)(R14*1), V16.B[11]                // 700cce4d
+   VLD1.P (R3)(R14), V16.B[11]                                 // 700cce4d
    VLD1.P 2(R1), V28.H[2]                                      // 3c50df0d
-   VLD1.P (R13)(R20), V9.H[2]                                  // VLD1.P (R13)(R20*1), V9.H[2]                 // a951d40d
+   VLD1.P (R13)(R20), V9.H[2]                                  // a951d40d
    VLD1.P 4(R17), V1.S[3]                                      // 2192df4d
-   VLD1.P (R14)(R2), V17.S[2]                                  // VLD1.P (R14)(R2*1), V17.S[2]                 // d181c24d
+   VLD1.P (R14)(R2), V17.S[2]                                  // d181c24d
    VLD1.P 8(R5), V30.D[1]                                      // be84df4d
-   VLD1.P (R27)(R13), V27.D[0]                                 // VLD1.P (R27)(R13*1), V27.D[0]                // 7b87cd0d
+   VLD1.P (R27)(R13), V27.D[0]                                 // 7b87cd0d
    //TODO FMOVS.P -29(RSP), F8                                 // e8375ebc
    //TODO FMOVS.W 71(R29), F28                                 // bc7f44bc
    FMOVS 6160(R4), F23                                         // 971058bd
    VMOV V18.B[10], V27                                         // 5b06155e
+   VDUP V18.B[10], V27                                         // 5b06155e
    VMOV V12.B[2], V28.B[12]                                    // 9c15196e
    VMOV R30, V4.B[13]                                          // c41f1b4e
    VMOV V2.B16, V4.B16                                         // 441ca24e
@@ -732,25 +734,25 @@
    VSHL $7, V22.D2, V25.D2                                     // d956474f
    VST1 [V14.H4, V15.H4, V16.H4], (R27)                        // 6e67000c
    VST1 [V2.S4, V3.S4, V4.S4, V5.S4], (R14)                    // c229004c
-   VST1.P [V25.S4], (R7)(R29)                                  // VST1.P [V25.S4], (R7)(R29*1)                          // f9789d4c
+   VST1.P [V25.S4], (R7)(R29)                                  // f9789d4c
    VST1.P [V25.D2, V26.D2], 32(R7)                             // f9ac9f4c
-   VST1.P [V14.D1, V15.D1], (R7)(R23)                          // VST1.P [V14.D1, V15.D1], (R7)(R23*1)                  // eeac970c
+   VST1.P [V14.D1, V15.D1], (R7)(R23)                          // eeac970c
    VST1.P [V25.D2, V26.D2, V27.D2], 48(R27)                    // 796f9f4c
-   VST1.P [V13.H8, V14.H8, V15.H8], (R3)(R14)                  // VST1.P [V13.H8, V14.H8, V15.H8], (R3)(R14*1)          // 6d648e4c
+   VST1.P [V13.H8, V14.H8, V15.H8], (R3)(R14)                  // 6d648e4c
    VST1.P [V16.S4, V17.S4, V18.S4, V19.S4], 64(R6)             // d0289f4c
-   VST1.P [V19.H4, V20.H4, V21.H4, V22.H4], (R4)(R16)          // VST1.P [V19.H4, V20.H4, V21.H4, V22.H4], (R4)(R16*1)  // 9324900c
+   VST1.P [V19.H4, V20.H4, V21.H4, V22.H4], (R4)(R16)          // 9324900c
    VST1 V12.B[3], (R1)                                         // 2c0c000d
    VST1 V12.B[3], (R1)                                         // 2c0c000d
    VST1 V25.S[2], (R20)                                        // 9982004d
    VST1 V9.D[1], (RSP)                                         // e987004d
    VST1.P V30.B[6], 1(R3)                                      // 7e189f0d
-   VST1.P V8.B[0], (R3)(R21)                                   // VST1.P V8.B[0], (R3)(R21*1)                          // 6800950d
+   VST1.P V8.B[0], (R3)(R21)                                   // 6800950d
    VST1.P V15.H[5], 2(R10)                                     // 4f499f4d
-   VST1.P V1.H[7], (R23)(R11)                                  // VST1.P V1.H[7], (R23)(R11*1)                         // e15a8b4d
+   VST1.P V1.H[7], (R23)(R11)                                  // e15a8b4d
    VST1.P V26.S[0], 4(R11)                                     // 7a819f0d
-   VST1.P V9.S[1], (R16)(R21)                                  // VST1.P V9.S[1], (R16)(R21*1)                         // 0992950d
+   VST1.P V9.S[1], (R16)(R21)                                  // 0992950d
    VST1.P V16.D[0], 8(R9)                                      // 30859f0d
-   VST1.P V23.D[1], (R21)(R16)                                 // VST1.P V23.D[1], (R21)(R16*1)                        // b786904d
+   VST1.P V23.D[1], (R21)(R16)                                 // b786904d
    VSUB V1, V12, V23                                           // 9785e17e
    VUADDLV V31.S4, V11                                         // eb3bb06e
    UCVTFWS R11, F19                                            // 7301231e
diff --git a/src/cmd/asm/internal/asm/testdata/arm64error.s b/src/cmd/asm/internal/asm/testdata/arm64error.s
index e579f20..cf57179 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64error.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64error.s
@@ -8,12 +8,60 @@
 	ADDSW	R7->32, R14, R13                                 // ERROR "shift amount out of range 0 to 31"
 	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"
+	ADDS	R5, R6, RSP                                      // ERROR "illegal destination register"
+	SUBS	R5, R6, RSP                                      // ERROR "illegal destination register"
+	ADDSW	R5, R6, RSP                                      // ERROR "illegal destination register"
+	SUBSW	R5, R6, RSP                                      // ERROR "illegal destination register"
+	ADDS	$0xff, R6, RSP                                   // ERROR "illegal destination register"
+	ADDS	$0xffff0, R6, RSP                                // ERROR "illegal destination register"
+	ADDS	$0x1000100010001000, R6, RSP                     // ERROR "illegal destination register"
+	ADDS	$0x10001000100011, R6, RSP                       // ERROR "illegal destination register"
+	ADDSW	$0xff, R6, RSP                                   // ERROR "illegal destination register"
+	ADDSW	$0xffff0, R6, RSP                                // ERROR "illegal destination register"
+	ADDSW	$0x1000100010001000, R6, RSP                     // ERROR "illegal destination register"
+	ADDSW	$0x10001000100011, R6, RSP                       // ERROR "illegal destination register"
+	SUBS	$0xff, R6, RSP                                   // ERROR "illegal destination register"
+	SUBS	$0xffff0, R6, RSP                                // ERROR "illegal destination register"
+	SUBS	$0x1000100010001000, R6, RSP                     // ERROR "illegal destination register"
+	SUBS	$0x10001000100011, R6, RSP                       // ERROR "illegal destination register"
+	SUBSW	$0xff, R6, RSP                                   // ERROR "illegal destination register"
+	SUBSW	$0xffff0, R6, RSP                                // ERROR "illegal destination register"
+	SUBSW	$0x1000100010001000, R6, RSP                     // ERROR "illegal destination register"
+	SUBSW	$0x10001000100011, R6, RSP                       // ERROR "illegal destination register"
 	AND	$0x22220000, R2, RSP                             // ERROR "illegal combination"
 	ANDS	$0x22220000, R2, RSP                             // ERROR "illegal combination"
 	ADD	R1, R2, R3, R4                                   // ERROR "illegal combination"
 	BICW	R7@>33, R5, R16                                  // ERROR "shift amount out of range 0 to 31"
+	NEGW	R7<<33, R5                                       // ERROR "shift amount out of range 0 to 31"
+	NEGSW	R7<<33, R5                                       // ERROR "shift amount out of range 0 to 31"
+	ADD	R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+	ADDW	R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+	ADDS	R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+	ADDSW	R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+	SUB	R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+	SUBW	R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+	SUBS	R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+	SUBSW	R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+	CMP	R7@>2, R5                                        // ERROR "unsupported shift operator"
+	CMPW	R7@>2, R5                                        // ERROR "unsupported shift operator"
+	CMN	R7@>2, R5                                        // ERROR "unsupported shift operator"
+	CMNW	R7@>2, R5                                        // ERROR "unsupported shift operator"
+	NEG	R7@>2, R5                                        // ERROR "unsupported shift operator"
+	NEGW	R7@>2, R5                                        // ERROR "unsupported shift operator"
+	NEGS	R7@>2, R5                                        // ERROR "unsupported shift operator"
+	NEGSW	R7@>2, R5                                        // ERROR "unsupported shift operator"
 	CINC	CS, R2, R3, R4                                   // ERROR "illegal combination"
 	CSEL	LT, R1, R2                                       // ERROR "illegal combination"
+	CINC	AL, R2, R3                                       // ERROR "invalid condition"
+	CINC	NV, R2, R3                                       // ERROR "invalid condition"
+	CINVW	AL, R2, R3                                       // ERROR "invalid condition"
+	CINV	NV, R2, R3                                       // ERROR "invalid condition"
+	CNEG	AL, R2, R3                                       // ERROR "invalid condition"
+	CNEGW	NV, R2, R3                                       // ERROR "invalid condition"
+	CSET	AL, R2                                           // ERROR "invalid condition"
+	CSET	NV, R2                                           // ERROR "invalid condition"
+	CSETMW	AL, R2                                           // ERROR "invalid condition"
+	CSETM	NV, R2                                           // ERROR "invalid condition"
 	LDP.P	8(R2), (R2, R3)                                  // ERROR "constrained unpredictable behavior"
 	LDP.W	8(R3), (R2, R3)                                  // ERROR "constrained unpredictable behavior"
 	LDP	(R1), (R2, R2)                                   // ERROR "constrained unpredictable behavior"
@@ -21,8 +69,8 @@
 	LDP	(R0), (R3, ZR)                                   // ERROR "invalid register pair"
 	LDXPW	(RSP), (R2, R2)                                  // ERROR "constrained unpredictable behavior"
 	LDAXPW	(R5), (R2, R2)                                   // ERROR "constrained unpredictable behavior"
-	MOVD.P	300(R2), R3                                      // ERROR "offset out of range [-255,254]"
-	MOVD.P	R3, 344(R2)                                      // ERROR "offset out of range [-255,254]"
+	MOVD.P	300(R2), R3                                      // ERROR "offset out of range [-256,255]"
+	MOVD.P	R3, 344(R2)                                      // ERROR "offset out of range [-256,255]"
 	MOVD	(R3)(R7.SXTX<<2), R8                             // ERROR "invalid index shift amount"
 	MOVWU	(R5)(R4.UXTW<<3), R10                            // ERROR "invalid index shift amount"
 	MOVWU	(R5)(R4<<1), R10                                 // ERROR "invalid index shift amount"
@@ -58,13 +106,13 @@
 	VMOV	V8.H[9], R3                                      // ERROR "register element index out of range 0 to 7"
 	VMOV	V8.S[4], R3                                      // ERROR "register element index out of range 0 to 3"
 	VMOV	V8.D[2], R3                                      // ERROR "register element index out of range 0 to 1"
-	VDUP	V8.B[16], R3.B16                                 // ERROR "register element index out of range 0 to 15"
-	VDUP	V8.B[17], R3.B8                                  // ERROR "register element index out of range 0 to 15"
-	VDUP	V8.H[9], R3.H4                                   // ERROR "register element index out of range 0 to 7"
-	VDUP	V8.H[9], R3.H8                                   // ERROR "register element index out of range 0 to 7"
-	VDUP	V8.S[4], R3.S2                                   // ERROR "register element index out of range 0 to 3"
-	VDUP	V8.S[4], R3.S4                                   // ERROR "register element index out of range 0 to 3"
-	VDUP	V8.D[2], R3.D2                                   // ERROR "register element index out of range 0 to 1"
+	VDUP	V8.B[16], V3.B16                                 // ERROR "register element index out of range 0 to 15"
+	VDUP	V8.B[17], V3.B8                                  // ERROR "register element index out of range 0 to 15"
+	VDUP	V8.H[9], V3.H4                                   // ERROR "register element index out of range 0 to 7"
+	VDUP	V8.H[9], V3.H8                                   // ERROR "register element index out of range 0 to 7"
+	VDUP	V8.S[4], V3.S2                                   // ERROR "register element index out of range 0 to 3"
+	VDUP	V8.S[4], V3.S4                                   // ERROR "register element index out of range 0 to 3"
+	VDUP	V8.D[2], V3.D2                                   // ERROR "register element index out of range 0 to 1"
 	VFMLA	V1.D2, V12.D2, V3.S2                             // ERROR "operand mismatch"
 	VFMLA	V1.S2, V12.S2, V3.D2                             // ERROR "operand mismatch"
 	VFMLA	V1.S4, V12.S2, V3.D2                             // ERROR "operand mismatch"
@@ -109,6 +157,9 @@
 	VREV16	V1.D1, V2.D1                                     // ERROR "invalid arrangement"
 	VREV16	V1.B8, V2.B16                                    // ERROR "invalid arrangement"
 	VREV16	V1.H4, V2.H4                                     // ERROR "invalid arrangement"
+	FLDPQ	(R0), (R1, R2)                                   // ERROR "invalid register pair"
+	FLDPQ	(R1), (F2, F2)                                   // ERROR "constrained unpredictable behavior"
+	FSTPQ	(R1, R2), (R0)                                   // ERROR "invalid register pair"
 	FLDPD	(R0), (R1, R2)                                   // ERROR "invalid register pair"
 	FLDPD	(R1), (F2, F2)                                   // ERROR "constrained unpredictable behavior"
 	FLDPS	(R2), (F3, F3)                                   // ERROR "constrained unpredictable behavior"
@@ -355,10 +406,17 @@
 	VBIF	V0.D2, V1.D2, V2.D2                              // ERROR "invalid arrangement"
 	VUADDW	V9.B8, V12.H8, V14.B8                            // ERROR "invalid arrangement"
 	VUADDW2	V9.B8, V12.S4, V14.S4                            // ERROR "operand mismatch"
+	VUMAX   V1.D2, V2.D2, V3.D2                              // ERROR "invalid arrangement"
+	VUMIN   V1.D2, V2.D2, V3.D2                              // ERROR "invalid arrangement"
+	VUMAX	V1.B8, V2.B8, V3.B16                             // ERROR "operand mismatch"
+	VUMIN	V1.H4, V2.S4, V3.H4                              // ERROR "operand mismatch"
 	VSLI	$64, V7.D2, V8.D2                                // ERROR "shift out of range"
 	VUSRA   $0, V7.D2, V8.D2                                 // ERROR "shift out of range"
 	CASPD	(R3, R4), (R2), (R8, R9)                         // ERROR "source register pair must start from even register"
 	CASPD	(R2, R3), (R2), (R9, R10)                        // ERROR "destination register pair must start from even register"
 	CASPD	(R2, R4), (R2), (R8, R9)                         // ERROR "source register pair must be contiguous"
 	CASPD	(R2, R3), (R2), (R8, R10)                        // ERROR "destination register pair must be contiguous"
+	ADD	R1>>2, RSP, R3                                   // ERROR "illegal combination"
+	ADDS	R2<<3, R3, RSP                                   // ERROR "unexpected SP reference"
+	CMP	R1<<5, RSP                                       // ERROR "the left shift amount out of range 0 to 4"
 	RET
diff --git a/src/cmd/asm/internal/asm/testdata/mips64.s b/src/cmd/asm/internal/asm/testdata/mips64.s
index 21ab82f..99044d8 100644
--- a/src/cmd/asm/internal/asm/testdata/mips64.s
+++ b/src/cmd/asm/internal/asm/testdata/mips64.s
@@ -407,6 +407,8 @@
 	SRLV	R27, R6, R17	// 03668816
 	SRA	R11, R19, R20	// 0173a007
 	SRAV	R20, R19, R19	// 02939817
+	ROTR	R19, R18, R20	// 0272a046
+	ROTRV	R9, R13, R16	// 012d8056
 
 //	LSHW rreg ',' rreg
 //	{
@@ -418,6 +420,8 @@
 	SRLV	R27, R6   	// 03663016
 	SRA	R11, R19	// 01739807
 	SRAV	R20, R19	// 02939817
+	ROTR	R20, R19	// 02939846
+	ROTRV	R16, R9		// 02094856
 
 //	LSHW imm ',' sreg ',' rreg
 //	{
@@ -429,6 +433,8 @@
 	SRLV	$31, R6, R17	// 00068ffa
 	SRA	$8, R8, R19	// 00089a03
 	SRAV	$19, R8, R7	// 00083cfb
+	ROTR	$12, R8, R3	// 00281b02
+	ROTRV	$8, R22, R22	// 0036b23a
 
 //	LSHW imm ',' rreg
 //	{
@@ -440,6 +446,8 @@
 	SRLV	$31, R17	// 00118ffa
 	SRA	$3, R12		// 000c60c3
 	SRAV	$12, R3		// 00031b3b
+	ROTR	$12, R8		// 00284302
+	ROTRV	$63, R22	// 0036b7fe
 
 
 //	LAND/LXOR/LNOR/LOR rreg ',' rreg
diff --git a/src/cmd/asm/internal/asm/testdata/ppc64.s b/src/cmd/asm/internal/asm/testdata/ppc64.s
index 8f6eb14..b6c0aa5 100644
--- a/src/cmd/asm/internal/asm/testdata/ppc64.s
+++ b/src/cmd/asm/internal/asm/testdata/ppc64.s
@@ -41,6 +41,8 @@
 	MOVDBR (R3)(R4), R5             // 7ca41c28
 	MOVWBR (R3)(R4), R5             // 7ca41c2c
 	MOVHBR (R3)(R4), R5             // 7ca41e2c
+	MOVD $foo+4009806848(FP), R5    // 3ca1ef0138a5cc20
+	MOVD $foo(SB), R5               // 3ca0000038a50000
 
 	MOVDU 8(R3), R4                 // e8830009
 	MOVDU (R3)(R4), R5              // 7ca4186a
@@ -77,6 +79,15 @@
 	MOVBU R4, 1(R3)                 // 9c830001
 	MOVBU R5, (R3)(R4)              // 7ca419ee
 
+	MOVB $0, R4			// 38800000
+	MOVBZ $0, R4			// 38800000
+	MOVH $0, R4			// 38800000
+	MOVHZ $0, R4			// 38800000
+	MOVW $0, R4			// 38800000
+	MOVWZ $0, R4			// 38800000
+	MOVD $0, R4			// 38800000
+	MOVD $0, R0			// 38000000
+
 	ADD $1, R3                      // 38630001
 	ADD $1, R3, R4                  // 38830001
 	ADD $-1, R4                     // 3884ffff
@@ -280,11 +291,17 @@
 	ROTLW R3, R4, R5                // 5c85183e
 	EXTSWSLI $3, R4, R5             // 7c851ef4
 	RLWMI $7, R3, $65535, R6        // 50663c3e
+	RLWMI $7, R3, $16, $31, R6      // 50663c3e
 	RLWMICC $7, R3, $65535, R6      // 50663c3f
+	RLWMICC $7, R3, $16, $31, R6    // 50663c3f
 	RLWNM $3, R4, $7, R6            // 54861f7e
+	RLWNM $3, R4, $29, $31, R6      // 54861f7e
 	RLWNM R3, R4, $7, R6            // 5c861f7e
+	RLWNM R3, R4, $29, $31, R6      // 5c861f7e
 	RLWNMCC $3, R4, $7, R6          // 54861f7f
+	RLWNMCC $3, R4, $29, $31, R6    // 54861f7f
 	RLWNMCC R3, R4, $7, R6          // 5c861f7f
+	RLWNMCC R3, R4, $29, $31, R6    // 5c861f7f
 	RLDMI $0, R4, $7, R6            // 7886076c
 	RLDMICC $0, R4, $7, R6          // 7886076d
 	RLDIMI $0, R4, $7, R6           // 788601cc
@@ -303,6 +320,8 @@
 	RLDICCC $0, R4, $15, R6         // 788603c9
 	CLRLSLWI $16, R5, $8, R4        // 54a4422e
 	CLRLSLDI $24, R4, $2, R3        // 78831588
+	RLDCR	$1, R1, $-16, R1        // 78210ee4
+	RLDCRCC	$1, R1, $-16, R1        // 78210ee5
 
 	BEQ 0(PC)                       // 41820000
 	BEQ CR1,0(PC)                   // 41860000
diff --git a/src/cmd/asm/internal/asm/testdata/riscv64.s b/src/cmd/asm/internal/asm/testdata/riscv64.s
new file mode 100644
index 0000000..77c0764
--- /dev/null
+++ b/src/cmd/asm/internal/asm/testdata/riscv64.s
@@ -0,0 +1,368 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "../../../../../runtime/textflag.h"
+
+TEXT asmtest(SB),DUPOK|NOSPLIT,$0
+start:
+	// Unprivileged ISA
+
+	// 2.4: Integer Computational Instructions
+
+	ADDI	$2047, X5, X6				// 1383f27f
+	ADDI	$-2048, X5, X6				// 13830280
+	ADDI	$2047, X5				// 9382f27f
+	ADDI	$-2048, X5				// 93820280
+
+	SLTI	$55, X5, X7				// 93a37203
+	SLTIU	$55, X5, X7				// 93b37203
+
+	ANDI	$1, X5, X6				// 13f31200
+	ANDI	$1, X5					// 93f21200
+	ORI	$1, X5, X6				// 13e31200
+	ORI	$1, X5					// 93e21200
+	XORI	$1, X5, X6				// 13c31200
+	XORI	$1, X5					// 93c21200
+
+	SLLI	$1, X5, X6				// 13931200
+	SLLI	$1, X5					// 93921200
+	SRLI	$1, X5, X6				// 13d31200
+	SRLI	$1, X5					// 93d21200
+	SRAI	$1, X5, X6				// 13d31240
+	SRAI	$1, X5					// 93d21240
+
+	ADD	X6, X5, X7				// b3836200
+	ADD	X5, X6					// 33035300
+	ADD	$2047, X5, X6				// 1383f27f
+	ADD	$-2048, X5, X6				// 13830280
+	ADD	$2047, X5				// 9382f27f
+	ADD	$-2048, X5				// 93820280
+
+	SLT	X6, X5, X7				// b3a36200
+	SLT	$55, X5, X7				// 93a37203
+	SLTU	X6, X5, X7				// b3b36200
+	SLTU	$55, X5, X7				// 93b37203
+
+	AND	X6, X5, X7				// b3f36200
+	AND	X5, X6					// 33735300
+	AND	$1, X5, X6				// 13f31200
+	AND	$1, X5					// 93f21200
+	OR	X6, X5, X7				// b3e36200
+	OR	X5, X6					// 33635300
+	OR	$1, X5, X6				// 13e31200
+	OR	$1, X5					// 93e21200
+	XOR	X6, X5, X7				// b3c36200
+	XOR	X5, X6					// 33435300
+	XOR	$1, X5, X6				// 13c31200
+	XOR	$1, X5					// 93c21200
+
+	AUIPC	$0, X10					// 17050000
+	AUIPC	$0, X11					// 97050000
+	AUIPC	$1, X10					// 17150000
+	AUIPC	$-524288, X15				// 97070080
+	AUIPC	$524287, X10				// 17f5ff7f
+
+	LUI	$0, X15					// b7070000
+	LUI	$167, X15				// b7770a00
+	LUI	$-524288, X15				// b7070080
+	LUI	$524287, X15				// b7f7ff7f
+
+	SLL	X6, X5, X7				// b3936200
+	SLL	X5, X6					// 33135300
+	SLL	$1, X5, X6				// 13931200
+	SLL	$1, X5					// 93921200
+	SRL	X6, X5, X7				// b3d36200
+	SRL	X5, X6					// 33535300
+	SRL	$1, X5, X6				// 13d31200
+	SRL	$1, X5					// 93d21200
+
+	SUB	X6, X5, X7				// b3836240
+	SUB	X5, X6					// 33035340
+
+	SRA	X6, X5, X7				// b3d36240
+	SRA	X5, X6					// 33535340
+	SRA	$1, X5, X6				// 13d31240
+	SRA	$1, X5					// 93d21240
+
+	// 2.5: Control Transfer Instructions
+
+	// These jumps and branches get printed as a jump or branch
+	// to 2 because they transfer control to the second instruction
+	// in the function (the first instruction being an invisible
+	// stack pointer adjustment).
+	JAL	X5, start	// JAL	X5, 2		// eff25ff0
+	JALR	X6, (X5)				// 67830200
+	JALR	X6, 4(X5)				// 67834200
+	BEQ	X5, X6, start	// BEQ	X5, X6, 2	// e38c62ee
+	BNE	X5, X6, start	// BNE	X5, X6, 2	// e39a62ee
+	BLT	X5, X6, start	// BLT	X5, X6, 2	// e3c862ee
+	BLTU	X5, X6, start	// BLTU	X5, X6, 2	// e3e662ee
+	BGE	X5, X6, start	// BGE	X5, X6, 2	// e3d462ee
+	BGEU	X5, X6, start	// BGEU	X5, X6, 2	// e3f262ee
+
+	// 2.6: Load and Store Instructions
+	LW	(X5), X6				// 03a30200
+	LW	4(X5), X6				// 03a34200
+	LWU	(X5), X6				// 03e30200
+	LWU	4(X5), X6				// 03e34200
+	LH	(X5), X6				// 03930200
+	LH	4(X5), X6				// 03934200
+	LHU	(X5), X6				// 03d30200
+	LHU	4(X5), X6				// 03d34200
+	LB	(X5), X6				// 03830200
+	LB	4(X5), X6				// 03834200
+	LBU	(X5), X6				// 03c30200
+	LBU	4(X5), X6				// 03c34200
+
+	SW	X5, (X6)				// 23205300
+	SW	X5, 4(X6)				// 23225300
+	SH	X5, (X6)				// 23105300
+	SH	X5, 4(X6)				// 23125300
+	SB	X5, (X6)				// 23005300
+	SB	X5, 4(X6)				// 23025300
+
+	// 2.7: Memory Ordering Instructions
+	FENCE						// 0f00f00f
+
+	// 5.2: Integer Computational Instructions (RV64I)
+	ADDIW	$1, X5, X6				// 1b831200
+	SLLIW	$1, X5, X6				// 1b931200
+	SRLIW	$1, X5, X6				// 1bd31200
+	SRAIW	$1, X5, X6				// 1bd31240
+	ADDW	X5, X6, X7				// bb035300
+	SLLW	X5, X6, X7				// bb135300
+	SRLW	X5, X6, X7				// bb535300
+	SUBW	X5, X6, X7				// bb035340
+	SRAW	X5, X6, X7				// bb535340
+
+	// 5.3: Load and Store Instructions (RV64I)
+	LD	(X5), X6				// 03b30200
+	LD	4(X5), X6				// 03b34200
+	SD	X5, (X6)				// 23305300
+	SD	X5, 4(X6)				// 23325300
+
+	// 7.1: Multiplication Operations
+	MUL	X5, X6, X7				// b3035302
+	MULH	X5, X6, X7				// b3135302
+	MULHU	X5, X6, X7				// b3335302
+	MULHSU	X5, X6, X7				// b3235302
+	MULW	X5, X6, X7				// bb035302
+	DIV	X5, X6, X7				// b3435302
+	DIVU	X5, X6, X7				// b3535302
+	REM	X5, X6, X7				// b3635302
+	REMU	X5, X6, X7				// b3735302
+	DIVW	X5, X6, X7				// bb435302
+	DIVUW	X5, X6, X7				// bb535302
+	REMW	X5, X6, X7				// bb635302
+	REMUW	X5, X6, X7				// bb735302
+
+	// 8.2: Load-Reserved/Store-Conditional
+	LRW	(X5), X6				// 2fa30214
+	LRD	(X5), X6				// 2fb30214
+	SCW	X5, (X6), X7				// af23531c
+	SCD	X5, (X6), X7				// af33531c
+
+	// 8.3: Atomic Memory Operations
+	AMOSWAPW	X5, (X6), X7			// af23530c
+	AMOSWAPD	X5, (X6), X7			// af33530c
+	AMOADDW		X5, (X6), X7			// af235304
+	AMOADDD		X5, (X6), X7			// af335304
+	AMOANDW		X5, (X6), X7			// af235364
+	AMOANDD		X5, (X6), X7			// af335364
+	AMOORW		X5, (X6), X7			// af235344
+	AMOORD		X5, (X6), X7			// af335344
+	AMOXORW		X5, (X6), X7			// af235324
+	AMOXORD		X5, (X6), X7			// af335324
+	AMOMAXW		X5, (X6), X7			// af2353a4
+	AMOMAXD		X5, (X6), X7			// af3353a4
+	AMOMAXUW	X5, (X6), X7			// af2353e4
+	AMOMAXUD	X5, (X6), X7			// af3353e4
+	AMOMINW		X5, (X6), X7			// af235384
+	AMOMIND		X5, (X6), X7			// af335384
+	AMOMINUW	X5, (X6), X7			// af2353c4
+	AMOMINUD	X5, (X6), X7			// af3353c4
+
+	// 10.1: Base Counters and Timers
+	RDCYCLE		X5				// f32200c0
+	RDTIME		X5				// f32210c0
+	RDINSTRET	X5				// f32220c0
+
+	// 11.5: Single-Precision Load and Store Instructions
+	FLW	(X5), F0				// 07a00200
+	FLW	4(X5), F0				// 07a04200
+	FSW	F0, (X5)				// 27a00200
+	FSW	F0, 4(X5)				// 27a20200
+
+	// 11.6: Single-Precision Floating-Point Computational Instructions
+	FADDS	F1, F0, F2				// 53011000
+	FSUBS	F1, F0, F2				// 53011008
+	FMULS	F1, F0, F2				// 53011010
+	FDIVS	F1, F0, F2				// 53011018
+	FMINS	F1, F0, F2				// 53011028
+	FMAXS	F1, F0, F2				// 53111028
+	FSQRTS	F0, F1					// d3000058
+
+	// 11.7: Single-Precision Floating-Point Conversion and Move Instructions
+	FCVTWS	F0, X5					// d31200c0
+	FCVTLS	F0, X5					// d31220c0
+	FCVTSW	X5, F0					// 538002d0
+	FCVTSL	X5, F0					// 538022d0
+	FCVTWUS	F0, X5					// d31210c0
+	FCVTLUS	F0, X5					// d31230c0
+	FCVTSWU	X5, F0					// 538012d0
+	FCVTSLU	X5, F0					// 538032d0
+	FSGNJS	F1, F0, F2				// 53011020
+	FSGNJNS	F1, F0, F2				// 53111020
+	FSGNJXS	F1, F0, F2				// 53211020
+	FMVXS	F0, X5					// d30200e0
+	FMVSX	X5, F0					// 538002f0
+	FMVXW	F0, X5					// d30200e0
+	FMVWX	X5, F0					// 538002f0
+
+	// 11.8: Single-Precision Floating-Point Compare Instructions
+	FEQS	F0, F1, X7				// d3a300a0
+	FLTS	F0, F1, X7				// d39300a0
+	FLES	F0, F1, X7				// d38300a0
+
+	// 11.9: Single-Precision Floating-Point Classify Instruction
+	FCLASSS	F0, X5					// d31200e0
+
+	// 12.3: Double-Precision Load and Store Instructions
+	FLD	(X5), F0				// 07b00200
+	FLD	4(X5), F0				// 07b04200
+	FSD	F0, (X5)				// 27b00200
+	FSD	F0, 4(X5)				// 27b20200
+
+	// 12.4: Double-Precision Floating-Point Computational Instructions
+	FADDD	F1, F0, F2				// 53011002
+	FSUBD	F1, F0, F2				// 5301100a
+	FMULD	F1, F0, F2				// 53011012
+	FDIVD	F1, F0, F2				// 5301101a
+	FMIND	F1, F0, F2				// 5301102a
+	FMAXD	F1, F0, F2				// 5311102a
+	FSQRTD	F0, F1					// d300005a
+
+	// 12.5: Double-Precision Floating-Point Conversion and Move Instructions
+	FCVTWD	F0, X5					// d31200c2
+	FCVTLD	F0, X5					// d31220c2
+	FCVTDW	X5, F0					// 538002d2
+	FCVTDL	X5, F0					// 538022d2
+	FCVTWUD F0, X5					// d31210c2
+	FCVTLUD F0, X5					// d31230c2
+	FCVTDWU X5, F0					// 538012d2
+	FCVTDLU X5, F0					// 538032d2
+	FCVTSD	F0, F1					// d3001040
+	FCVTDS	F0, F1					// d3000042
+	FSGNJD	F1, F0, F2				// 53011022
+	FSGNJND	F1, F0, F2				// 53111022
+	FSGNJXD	F1, F0, F2				// 53211022
+	FMVXD	F0, X5					// d30200e2
+	FMVDX	X5, F0					// 538002f2
+
+	// 12.6: Double-Precision Floating-Point Classify Instruction
+	FCLASSD	F0, X5					// d31200e2
+
+	// Privileged ISA
+
+	// 3.2.1: Environment Call and Breakpoint
+	ECALL						// 73000000
+	SCALL						// 73000000
+	EBREAK						// 73001000
+	SBREAK						// 73001000
+
+	// Arbitrary bytes (entered in little-endian mode)
+	WORD	$0x12345678	// WORD $305419896	// 78563412
+	WORD	$0x9abcdef0	// WORD $2596069104	// f0debc9a
+
+	// MOV pseudo-instructions
+	MOV	X5, X6					// 13830200
+	MOV	$2047, X5				// 9b02f07f
+	MOV	$-2048, X5				// 9b020080
+
+	// Converted to load of symbol.
+	MOV	$4294967296, X5				// 97020000
+
+	MOV	(X5), X6				// 03b30200
+	MOV	4(X5), X6				// 03b34200
+	MOVB	(X5), X6				// 03830200
+	MOVB	4(X5), X6				// 03834200
+	MOVH	(X5), X6				// 03930200
+	MOVH	4(X5), X6				// 03934200
+	MOVW	(X5), X6				// 03a30200
+	MOVW	4(X5), X6				// 03a34200
+	MOV	X5, (X6)				// 23305300
+	MOV	X5, 4(X6)				// 23325300
+	MOVB	X5, (X6)				// 23005300
+	MOVB	X5, 4(X6)				// 23025300
+	MOVH	X5, (X6)				// 23105300
+	MOVH	X5, 4(X6)				// 23125300
+	MOVW	X5, (X6)				// 23205300
+	MOVW	X5, 4(X6)				// 23225300
+
+	MOVB	X5, X6					// 1393820313538343
+	MOVH	X5, X6					// 1393020313530343
+	MOVW	X5, X6					// 1b830200
+	MOVBU	X5, X6					// 13f3f20f
+	MOVHU	X5, X6					// 1393020313530303
+	MOVWU	X5, X6					// 1393020213530302
+
+	MOVF	4(X5), F0				// 07a04200
+	MOVF	F0, 4(X5)				// 27a20200
+	MOVF	F0, F1					// d3000020
+
+	MOVD	4(X5), F0				// 07b04200
+	MOVD	F0, 4(X5)				// 27b20200
+	MOVD	F0, F1					// d3000022
+
+	// NOT pseudo-instruction
+	NOT	X5					// 93c2f2ff
+	NOT	X5, X6					// 13c3f2ff
+
+	// NEG/NEGW pseudo-instructions
+	NEG	X5					// b3025040
+	NEG	X5, X6					// 33035040
+	NEGW	X5					// bb025040
+	NEGW	X5, X6					// 3b035040
+
+	// These jumps can get printed as jumps to 2 because they go to the
+	// second instruction in the function (the first instruction is an
+	// invisible stack pointer adjustment).
+	JMP	start		// JMP	2		// 6ff01fc2
+	JMP	(X5)					// 67800200
+	JMP	4(X5)					// 67804200
+
+	// JMP and CALL to symbol are encoded as:
+	//	AUIPC $0, TMP
+	//	JALR $0, TMP
+	// with a R_RISCV_PCREL_ITYPE relocation - the linker resolves the
+	// real address and updates the immediates for both instructions.
+	CALL	asmtest(SB)				// 970f0000
+	JMP	asmtest(SB)				// 970f0000
+
+	// Branch pseudo-instructions
+	BEQZ	X5, start	// BEQZ	X5, 2		// e38202c0
+	BGEZ	X5, start	// BGEZ	X5, 2		// e3d002c0
+	BGT	X5, X6, start	// BGT	X5, X6, 2	// e34e53be
+	BGTU	X5, X6, start	// BGTU	X5, X6, 2	// e36c53be
+	BGTZ	X5, start	// BGTZ	X5, 2		// e34a50be
+	BLE	X5, X6, start	// BLE	X5, X6, 2	// e35853be
+	BLEU	X5, X6, start	// BLEU	X5, X6, 2	// e37653be
+	BLEZ	X5, start	// BLEZ	X5, 2		// e35450be
+	BLTZ	X5, start	// BLTZ	X5, 2		// e3c202be
+	BNEZ	X5, start	// BNEZ	X5, 2		// e39002be
+
+	// Set pseudo-instructions
+	SEQZ	X15, X15				// 93b71700
+	SNEZ	X15, X15				// b337f000
+
+	// F extension
+	FNEGS	F0, F1					// d3100020
+	FNES	F0, F1, X7				// d3a300a093c31300
+
+	// D extension
+	FNEGD	F0, F1					// d3100022
+	FNED	F0, F1, X5				// d3a200a293c21200
+	FLTD	F0, F1, X5				// d39200a2
+	FLED	F0, F1, X5				// d38200a2
+	FEQD	F0, F1, X5				// d3a200a2
diff --git a/src/cmd/asm/internal/asm/testdata/riscv64error.s b/src/cmd/asm/internal/asm/testdata/riscv64error.s
new file mode 100644
index 0000000..fb43e68
--- /dev/null
+++ b/src/cmd/asm/internal/asm/testdata/riscv64error.s
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+TEXT errors(SB),$0
+	MOV	$0, 0(SP)			// ERROR "constant load must target register"
+	MOV	$0, 8(SP)			// ERROR "constant load must target register"
+	MOV	$1234, 0(SP)			// ERROR "constant load must target register"
+	MOV	$1234, 8(SP)			// ERROR "constant load must target register"
+	MOVB	$1, X5				// ERROR "unsupported constant load"
+	MOVH	$1, X5				// ERROR "unsupported constant load"
+	MOVW	$1, X5				// ERROR "unsupported constant load"
+	MOVF	$1, X5				// ERROR "unsupported constant load"
+	RET
diff --git a/src/cmd/asm/internal/asm/testdata/riscvenc.s b/src/cmd/asm/internal/asm/testdata/riscvenc.s
deleted file mode 100644
index 9a49d96..0000000
--- a/src/cmd/asm/internal/asm/testdata/riscvenc.s
+++ /dev/null
@@ -1,365 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../../../runtime/textflag.h"
-
-TEXT asmtest(SB),DUPOK|NOSPLIT,$0
-start:
-	// Unprivileged ISA
-
-	// 2.4: Integer Computational Instructions
-
-	ADDI	$2047, X5, X6				// 1383f27f
-	ADDI	$-2048, X5, X6				// 13830280
-	ADDI	$2047, X5				// 9382f27f
-	ADDI	$-2048, X5				// 93820280
-
-	SLTI	$55, X5, X7				// 93a37203
-	SLTIU	$55, X5, X7				// 93b37203
-
-	ANDI	$1, X5, X6				// 13f31200
-	ANDI	$1, X5					// 93f21200
-	ORI	$1, X5, X6				// 13e31200
-	ORI	$1, X5					// 93e21200
-	XORI	$1, X5, X6				// 13c31200
-	XORI	$1, X5					// 93c21200
-
-	SLLI	$1, X5, X6				// 13931200
-	SLLI	$1, X5					// 93921200
-	SRLI	$1, X5, X6				// 13d31200
-	SRLI	$1, X5					// 93d21200
-	SRAI	$1, X5, X6				// 13d31240
-	SRAI	$1, X5					// 93d21240
-
-	ADD	X6, X5, X7				// b3836200
-	ADD	X5, X6					// 33035300
-	ADD	$2047, X5, X6				// 1383f27f
-	ADD	$-2048, X5, X6				// 13830280
-	ADD	$2047, X5				// 9382f27f
-	ADD	$-2048, X5				// 93820280
-
-	SLT	X6, X5, X7				// b3a36200
-	SLT	$55, X5, X7				// 93a37203
-	SLTU	X6, X5, X7				// b3b36200
-	SLTU	$55, X5, X7				// 93b37203
-
-	AND	X6, X5, X7				// b3f36200
-	AND	X5, X6					// 33735300
-	AND	$1, X5, X6				// 13f31200
-	AND	$1, X5					// 93f21200
-	OR	X6, X5, X7				// b3e36200
-	OR	X5, X6					// 33635300
-	OR	$1, X5, X6				// 13e31200
-	OR	$1, X5					// 93e21200
-	XOR	X6, X5, X7				// b3c36200
-	XOR	X5, X6					// 33435300
-	XOR	$1, X5, X6				// 13c31200
-	XOR	$1, X5					// 93c21200
-
-	AUIPC	$0, X10					// 17050000
-	AUIPC	$0, X11					// 97050000
-	AUIPC	$1, X10					// 17150000
-	AUIPC	$-524288, X15				// 97070080
-	AUIPC	$524287, X10				// 17f5ff7f
-
-	LUI	$0, X15					// b7070000
-	LUI	$167, X15				// b7770a00
-	LUI	$-524288, X15				// b7070080
-	LUI	$524287, X15				// b7f7ff7f
-
-	SLL	X6, X5, X7				// b3936200
-	SLL	X5, X6					// 33135300
-	SLL	$1, X5, X6				// 13931200
-	SLL	$1, X5					// 93921200
-	SRL	X6, X5, X7				// b3d36200
-	SRL	X5, X6					// 33535300
-	SRL	$1, X5, X6				// 13d31200
-	SRL	$1, X5					// 93d21200
-
-	SUB	X6, X5, X7				// b3836240
-	SUB	X5, X6					// 33035340
-
-	SRA	X6, X5, X7				// b3d36240
-	SRA	X5, X6					// 33535340
-	SRA	$1, X5, X6				// 13d31240
-	SRA	$1, X5					// 93d21240
-
-	// 2.5: Control Transfer Instructions
-
-	// These jumps and branches get printed as a jump or branch
-	// to 2 because they transfer control to the second instruction
-	// in the function (the first instruction being an invisible
-	// stack pointer adjustment).
-	JAL	X5, start	// JAL	X5, 2		// eff25ff0
-	JALR	X6, (X5)				// 67830200
-	JALR	X6, 4(X5)				// 67834200
-	BEQ	X5, X6, start	// BEQ	X5, X6, 2	// e38c62ee
-	BNE	X5, X6, start	// BNE	X5, X6, 2	// e39a62ee
-	BLT	X5, X6, start	// BLT	X5, X6, 2	// e3c862ee
-	BLTU	X5, X6, start	// BLTU	X5, X6, 2	// e3e662ee
-	BGE	X5, X6, start	// BGE	X5, X6, 2	// e3d462ee
-	BGEU	X5, X6, start	// BGEU	X5, X6, 2	// e3f262ee
-
-	// 2.6: Load and Store Instructions
-	LW	(X5), X6				// 03a30200
-	LW	4(X5), X6				// 03a34200
-	LWU	(X5), X6				// 03e30200
-	LWU	4(X5), X6				// 03e34200
-	LH	(X5), X6				// 03930200
-	LH	4(X5), X6				// 03934200
-	LHU	(X5), X6				// 03d30200
-	LHU	4(X5), X6				// 03d34200
-	LB	(X5), X6				// 03830200
-	LB	4(X5), X6				// 03834200
-	LBU	(X5), X6				// 03c30200
-	LBU	4(X5), X6				// 03c34200
-
-	SW	X5, (X6)				// 23205300
-	SW	X5, 4(X6)				// 23225300
-	SH	X5, (X6)				// 23105300
-	SH	X5, 4(X6)				// 23125300
-	SB	X5, (X6)				// 23005300
-	SB	X5, 4(X6)				// 23025300
-
-	// 2.7: Memory Ordering Instructions
-	FENCE						// 0f00f00f
-
-	// 5.2: Integer Computational Instructions (RV64I)
-	ADDIW	$1, X5, X6				// 1b831200
-	SLLIW	$1, X5, X6				// 1b931200
-	SRLIW	$1, X5, X6				// 1bd31200
-	SRAIW	$1, X5, X6				// 1bd31240
-	ADDW	X5, X6, X7				// bb035300
-	SLLW	X5, X6, X7				// bb135300
-	SRLW	X5, X6, X7				// bb535300
-	SUBW	X5, X6, X7				// bb035340
-	SRAW	X5, X6, X7				// bb535340
-
-	// 5.3: Load and Store Instructions (RV64I)
-	LD	(X5), X6				// 03b30200
-	LD	4(X5), X6				// 03b34200
-	SD	X5, (X6)				// 23305300
-	SD	X5, 4(X6)				// 23325300
-
-	// 7.1: Multiplication Operations
-	MUL	X5, X6, X7				// b3035302
-	MULH	X5, X6, X7				// b3135302
-	MULHU	X5, X6, X7				// b3335302
-	MULHSU	X5, X6, X7				// b3235302
-	MULW	X5, X6, X7				// bb035302
-	DIV	X5, X6, X7				// b3435302
-	DIVU	X5, X6, X7				// b3535302
-	REM	X5, X6, X7				// b3635302
-	REMU	X5, X6, X7				// b3735302
-	DIVW	X5, X6, X7				// bb435302
-	DIVUW	X5, X6, X7				// bb535302
-	REMW	X5, X6, X7				// bb635302
-	REMUW	X5, X6, X7				// bb735302
-
-	// 8.2: Load-Reserved/Store-Conditional
-	LRW	(X5), X6				// 2fa30214
-	LRD	(X5), X6				// 2fb30214
-	SCW	X5, (X6), X7				// af23531c
-	SCD	X5, (X6), X7				// af33531c
-
-	// 8.3: Atomic Memory Operations
-	AMOSWAPW	X5, (X6), X7			// af23530c
-	AMOSWAPD	X5, (X6), X7			// af33530c
-	AMOADDW		X5, (X6), X7			// af235304
-	AMOADDD		X5, (X6), X7			// af335304
-	AMOANDW		X5, (X6), X7			// af235364
-	AMOANDD		X5, (X6), X7			// af335364
-	AMOORW		X5, (X6), X7			// af235344
-	AMOORD		X5, (X6), X7			// af335344
-	AMOXORW		X5, (X6), X7			// af235324
-	AMOXORD		X5, (X6), X7			// af335324
-	AMOMAXW		X5, (X6), X7			// af2353a4
-	AMOMAXD		X5, (X6), X7			// af3353a4
-	AMOMAXUW	X5, (X6), X7			// af2353e4
-	AMOMAXUD	X5, (X6), X7			// af3353e4
-	AMOMINW		X5, (X6), X7			// af235384
-	AMOMIND		X5, (X6), X7			// af335384
-	AMOMINUW	X5, (X6), X7			// af2353c4
-	AMOMINUD	X5, (X6), X7			// af3353c4
-
-	// 10.1: Base Counters and Timers
-	RDCYCLE		X5				// f32200c0
-	RDTIME		X5				// f32210c0
-	RDINSTRET	X5				// f32220c0
-
-	// 11.5: Single-Precision Load and Store Instructions
-	FLW	(X5), F0				// 07a00200
-	FLW	4(X5), F0				// 07a04200
-	FSW	F0, (X5)				// 27a00200
-	FSW	F0, 4(X5)				// 27a20200
-
-	// 11.6: Single-Precision Floating-Point Computational Instructions
-	FADDS	F1, F0, F2				// 53011000
-	FSUBS	F1, F0, F2				// 53011008
-	FMULS	F1, F0, F2				// 53011010
-	FDIVS	F1, F0, F2				// 53011018
-	FMINS	F1, F0, F2				// 53011028
-	FMAXS	F1, F0, F2				// 53111028
-	FSQRTS	F0, F1					// d3000058
-
-	// 11.7: Single-Precision Floating-Point Conversion and Move Instructions
-	FCVTWS	F0, X5					// d31200c0
-	FCVTLS	F0, X5					// d31220c0
-	FCVTSW	X5, F0					// 538002d0
-	FCVTSL	X5, F0					// 538022d0
-	FCVTWUS	F0, X5					// d31210c0
-	FCVTLUS	F0, X5					// d31230c0
-	FCVTSWU	X5, F0					// 538012d0
-	FCVTSLU	X5, F0					// 538032d0
-	FSGNJS	F1, F0, F2				// 53011020
-	FSGNJNS	F1, F0, F2				// 53111020
-	FSGNJXS	F1, F0, F2				// 53211020
-	FMVXS	F0, X5					// d30200e0
-	FMVSX	X5, F0					// 538002f0
-	FMVXW	F0, X5					// d30200e0
-	FMVWX	X5, F0					// 538002f0
-
-	// 11.8: Single-Precision Floating-Point Compare Instructions
-	FEQS	F0, F1, X7				// d3a300a0
-	FLTS	F0, F1, X7				// d39300a0
-	FLES	F0, F1, X7				// d38300a0
-
-	// 11.9: Single-Precision Floating-Point Classify Instruction
-	FCLASSS	F0, X5					// d31200e0
-
-	// 12.3: Double-Precision Load and Store Instructions
-	FLD	(X5), F0				// 07b00200
-	FLD	4(X5), F0				// 07b04200
-	FSD	F0, (X5)				// 27b00200
-	FSD	F0, 4(X5)				// 27b20200
-
-	// 12.4: Double-Precision Floating-Point Computational Instructions
-	FADDD	F1, F0, F2				// 53011002
-	FSUBD	F1, F0, F2				// 5301100a
-	FMULD	F1, F0, F2				// 53011012
-	FDIVD	F1, F0, F2				// 5301101a
-	FMIND	F1, F0, F2				// 5301102a
-	FMAXD	F1, F0, F2				// 5311102a
-	FSQRTD	F0, F1					// d300005a
-
-	// 12.5: Double-Precision Floating-Point Conversion and Move Instructions
-	FCVTWD	F0, X5					// d31200c2
-	FCVTLD	F0, X5					// d31220c2
-	FCVTDW	X5, F0					// 538002d2
-	FCVTDL	X5, F0					// 538022d2
-	FCVTWUD F0, X5					// d31210c2
-	FCVTLUD F0, X5					// d31230c2
-	FCVTDWU X5, F0					// 538012d2
-	FCVTDLU X5, F0					// 538032d2
-	FCVTSD	F0, F1					// d3001040
-	FCVTDS	F0, F1					// d3000042
-	FSGNJD	F1, F0, F2				// 53011022
-	FSGNJND	F1, F0, F2				// 53111022
-	FSGNJXD	F1, F0, F2				// 53211022
-	FMVXD	F0, X5					// d30200e2
-	FMVDX	X5, F0					// 538002f2
-
-	// 12.6: Double-Precision Floating-Point Classify Instruction
-	FCLASSD	F0, X5					// d31200e2
-
-	// Privileged ISA
-
-	// 3.2.1: Environment Call and Breakpoint
-	ECALL						// 73000000
-	SCALL						// 73000000
-	EBREAK						// 73001000
-	SBREAK						// 73001000
-
-	// Arbitrary bytes (entered in little-endian mode)
-	WORD	$0x12345678	// WORD $305419896	// 78563412
-	WORD	$0x9abcdef0	// WORD $2596069104	// f0debc9a
-
-	// MOV pseudo-instructions
-	MOV	X5, X6					// 13830200
-	MOV	$2047, X5				// 9b02f07f
-	MOV	$-2048, X5				// 9b020080
-
-	MOV	(X5), X6				// 03b30200
-	MOV	4(X5), X6				// 03b34200
-	MOVB	(X5), X6				// 03830200
-	MOVB	4(X5), X6				// 03834200
-	MOVH	(X5), X6				// 03930200
-	MOVH	4(X5), X6				// 03934200
-	MOVW	(X5), X6				// 03a30200
-	MOVW	4(X5), X6				// 03a34200
-	MOV	X5, (X6)				// 23305300
-	MOV	X5, 4(X6)				// 23325300
-	MOVB	X5, (X6)				// 23005300
-	MOVB	X5, 4(X6)				// 23025300
-	MOVH	X5, (X6)				// 23105300
-	MOVH	X5, 4(X6)				// 23125300
-	MOVW	X5, (X6)				// 23205300
-	MOVW	X5, 4(X6)				// 23225300
-
-	MOVB	X5, X6					// 1393820313538343
-	MOVH	X5, X6					// 1393020313530343
-	MOVW	X5, X6					// 1b830200
-	MOVBU	X5, X6					// 13f3f20f
-	MOVHU	X5, X6					// 1393020313530303
-	MOVWU	X5, X6					// 1393020213530302
-
-	MOVF	4(X5), F0				// 07a04200
-	MOVF	F0, 4(X5)				// 27a20200
-	MOVF	F0, F1					// d3000020
-
-	MOVD	4(X5), F0				// 07b04200
-	MOVD	F0, 4(X5)				// 27b20200
-	MOVD	F0, F1					// d3000022
-
-	// NOT pseudo-instruction
-	NOT	X5					// 93c2f2ff
-	NOT	X5, X6					// 13c3f2ff
-
-	// NEG/NEGW pseudo-instructions
-	NEG	X5					// b3025040
-	NEG	X5, X6					// 33035040
-	NEGW	X5					// bb025040
-	NEGW	X5, X6					// 3b035040
-
-	// These jumps can get printed as jumps to 2 because they go to the
-	// second instruction in the function (the first instruction is an
-	// invisible stack pointer adjustment).
-	JMP	start		// JMP	2		// 6ff09fc2
-	JMP	(X5)					// 67800200
-	JMP	4(X5)					// 67804200
-
-	// JMP and CALL to symbol are encoded as:
-	//	AUIPC $0, TMP
-	//	JALR $0, TMP
-	// with a R_RISCV_PCREL_ITYPE relocation - the linker resolves the
-	// real address and updates the immediates for both instructions.
-	CALL	asmtest(SB)				// 970f0000
-	JMP	asmtest(SB)				// 970f0000
-
-	// Branch pseudo-instructions
-	BEQZ	X5, start	// BEQZ	X5, 2		// e38602c0
-	BGEZ	X5, start	// BGEZ	X5, 2		// e3d402c0
-	BGT	X5, X6, start	// BGT	X5, X6, 2	// e34253c0
-	BGTU	X5, X6, start	// BGTU	X5, X6, 2	// e36053c0
-	BGTZ	X5, start	// BGTZ	X5, 2		// e34e50be
-	BLE	X5, X6, start	// BLE	X5, X6, 2	// e35c53be
-	BLEU	X5, X6, start	// BLEU	X5, X6, 2	// e37a53be
-	BLEZ	X5, start	// BLEZ	X5, 2		// e35850be
-	BLTZ	X5, start	// BLTZ	X5, 2		// e3c602be
-	BNEZ	X5, start	// BNEZ	X5, 2		// e39402be
-
-	// Set pseudo-instructions
-	SEQZ	X15, X15				// 93b71700
-	SNEZ	X15, X15				// b337f000
-
-	// F extension
-	FNEGS	F0, F1					// d3100020
-	FNES	F0, F1, X7				// d3a300a093c31300
-
-	// D extension
-	FNEGD	F0, F1					// d3100022
-	FNED	F0, F1, X5				// d3a200a293c21200
-	FLTD	F0, F1, X5				// d39200a2
-	FLED	F0, F1, X5				// d38200a2
-	FEQD	F0, F1, X5				// d3a200a2
diff --git a/src/cmd/asm/internal/flags/flags.go b/src/cmd/asm/internal/flags/flags.go
index 1335860..dd947c7 100644
--- a/src/cmd/asm/internal/flags/flags.go
+++ b/src/cmd/asm/internal/flags/flags.go
@@ -32,11 +32,13 @@
 	D        MultiFlag
 	I        MultiFlag
 	PrintOut int
+	DebugV   bool
 )
 
 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")
+	flag.BoolVar(&DebugV, "v", false, "print debug output")
 	objabi.AddVersionFlag() // -V
 	objabi.Flagcount("S", "print assembly and machine code", &PrintOut)
 }
diff --git a/src/cmd/asm/internal/lex/input.go b/src/cmd/asm/internal/lex/input.go
index da4ebe6..e373ae8 100644
--- a/src/cmd/asm/internal/lex/input.go
+++ b/src/cmd/asm/internal/lex/input.go
@@ -6,6 +6,7 @@
 
 import (
 	"fmt"
+	"internal/buildcfg"
 	"os"
 	"path/filepath"
 	"strconv"
@@ -45,6 +46,21 @@
 // predefine installs the macros set by the -D flag on the command line.
 func predefine(defines flags.MultiFlag) map[string]*Macro {
 	macros := make(map[string]*Macro)
+
+	// Set macros for GOEXPERIMENTs so we can easily switch
+	// runtime assembly code based on them.
+	if *flags.CompilingRuntime {
+		for _, exp := range buildcfg.EnabledExperiments() {
+			// Define macro.
+			name := "GOEXPERIMENT_" + exp
+			macros[name] = &Macro{
+				name:   name,
+				args:   nil,
+				tokens: Tokenize("1"),
+			}
+		}
+	}
+
 	for _, name := range defines {
 		value := "1"
 		i := strings.IndexRune(name, '=')
diff --git a/src/cmd/asm/main.go b/src/cmd/asm/main.go
index 31636e3..043bc69 100644
--- a/src/cmd/asm/main.go
+++ b/src/cmd/asm/main.go
@@ -8,6 +8,7 @@
 	"bufio"
 	"flag"
 	"fmt"
+	"internal/buildcfg"
 	"log"
 	"os"
 
@@ -25,7 +26,8 @@
 	log.SetFlags(0)
 	log.SetPrefix("asm: ")
 
-	GOARCH := objabi.GOARCH
+	buildcfg.Check()
+	GOARCH := buildcfg.GOARCH
 
 	architecture := arch.Set(GOARCH)
 	if architecture == nil {
@@ -36,6 +38,7 @@
 
 	ctxt := obj.Linknew(architecture.LinkArch)
 	ctxt.Debugasm = flags.PrintOut
+	ctxt.Debugvlog = flags.DebugV
 	ctxt.Flag_dynlink = *flags.Dynlink
 	ctxt.Flag_linkshared = *flags.Linkshared
 	ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
@@ -67,7 +70,7 @@
 	defer buf.Close()
 
 	if !*flags.SymABIs {
-		fmt.Fprintf(buf, "go object %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version)
+		buf.WriteString(objabi.HeaderString())
 		fmt.Fprintf(buf, "!\n")
 	}
 
diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
index e782c86..a6787f6 100644
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -387,6 +387,9 @@
 it likes. However, programs that break these rules are likely to fail
 in unexpected and unpredictable ways.
 
+The runtime/cgo.Handle type can be used to safely pass Go values
+between Go and C. See the runtime/cgo package documentation for details.
+
 Note: the current implementation has a bug. While Go code is permitted
 to write nil or a C pointer (but not a Go pointer) to C memory, the
 current implementation may sometimes cause a runtime error if the
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index b5e28e3..a73e998 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -909,7 +909,7 @@
 	var sbCheck bytes.Buffer
 	for i, param := range params {
 		origArg := args[i]
-		arg, nu := p.mangle(f, &args[i])
+		arg, nu := p.mangle(f, &args[i], true)
 		if nu {
 			needsUnsafe = true
 		}
@@ -952,7 +952,7 @@
 		sb.WriteString("return ")
 	}
 
-	m, nu := p.mangle(f, &call.Call.Fun)
+	m, nu := p.mangle(f, &call.Call.Fun, false)
 	if nu {
 		needsUnsafe = true
 	}
@@ -1086,7 +1086,8 @@
 // rewriting calls when it finds them.
 // It removes the corresponding references in f.Ref and f.Calls, so that we
 // don't try to do the replacement again in rewriteRef or rewriteCall.
-func (p *Package) mangle(f *File, arg *ast.Expr) (ast.Expr, bool) {
+// If addPosition is true, add position info to the idents of C names in arg.
+func (p *Package) mangle(f *File, arg *ast.Expr, addPosition bool) (ast.Expr, bool) {
 	needsUnsafe := false
 	f.walk(arg, ctxExpr, func(f *File, arg interface{}, context astContext) {
 		px, ok := arg.(*ast.Expr)
@@ -1101,7 +1102,7 @@
 
 			for _, r := range f.Ref {
 				if r.Expr == px {
-					*px = p.rewriteName(f, r)
+					*px = p.rewriteName(f, r, addPosition)
 					r.Done = true
 					break
 				}
@@ -1361,7 +1362,7 @@
 			}
 		}
 
-		expr := p.rewriteName(f, r)
+		expr := p.rewriteName(f, r, false)
 
 		if *godefs {
 			// Substitute definition for mangled type name.
@@ -1424,8 +1425,23 @@
 }
 
 // rewriteName returns the expression used to rewrite a reference.
-func (p *Package) rewriteName(f *File, r *Ref) ast.Expr {
-	var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default
+// If addPosition is true, add position info in the ident name.
+func (p *Package) rewriteName(f *File, r *Ref, addPosition bool) ast.Expr {
+	getNewIdent := ast.NewIdent
+	if addPosition {
+		getNewIdent = func(newName string) *ast.Ident {
+			mangledIdent := ast.NewIdent(newName)
+			if len(newName) == len(r.Name.Go) {
+				return mangledIdent
+			}
+			p := fset.Position((*r.Expr).End())
+			if p.Column == 0 {
+				return mangledIdent
+			}
+			return ast.NewIdent(fmt.Sprintf("%s /*line :%d:%d*/", newName, p.Line, p.Column))
+		}
+	}
+	var expr ast.Expr = getNewIdent(r.Name.Mangle) // default
 	switch r.Context {
 	case ctxCall, ctxCall2:
 		if r.Name.Kind != "func" {
@@ -1453,7 +1469,7 @@
 				n.Mangle = "_C2func_" + n.Go
 				f.Name["2"+r.Name.Go] = n
 			}
-			expr = ast.NewIdent(n.Mangle)
+			expr = getNewIdent(n.Mangle)
 			r.Name = n
 			break
 		}
@@ -1484,7 +1500,7 @@
 			// issue 7757.
 			expr = &ast.CallExpr{
 				Fun:  &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"},
-				Args: []ast.Expr{ast.NewIdent(name.Mangle)},
+				Args: []ast.Expr{getNewIdent(name.Mangle)},
 			}
 		case "type":
 			// Okay - might be new(T)
@@ -1566,9 +1582,17 @@
 	case "s390x":
 		return []string{"-m64"}
 	case "mips64", "mips64le":
-		return []string{"-mabi=64"}
+		if gomips64 == "hardfloat" {
+			return []string{"-mabi=64", "-mhard-float"}
+		} else if gomips64 == "softfloat" {
+			return []string{"-mabi=64", "-msoft-float"}
+		}
 	case "mips", "mipsle":
-		return []string{"-mabi=32"}
+		if gomips == "hardfloat" {
+			return []string{"-mabi=32", "-mfp32", "-mhard-float", "-mno-odd-spreg"}
+		} else if gomips == "softfloat" {
+			return []string{"-mabi=32", "-msoft-float"}
+		}
 	}
 	return nil
 }
@@ -1614,6 +1638,8 @@
 		c = append(c, "-maix64")
 		c = append(c, "-mcmodel=large")
 	}
+	// disable LTO so we get an object whose symbols we can read
+	c = append(c, "-fno-lto")
 	c = append(c, "-") //read input from standard input
 	return c
 }
diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go
index c1116e2..c6a0c52 100644
--- a/src/cmd/cgo/main.go
+++ b/src/cmd/cgo/main.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.
 
-// Cgo; see gmp.go for an overview.
+// Cgo; see doc.go for an overview.
 
 // TODO(rsc):
 //	Emit correct line number annotations.
@@ -17,9 +17,11 @@
 	"go/ast"
 	"go/printer"
 	"go/token"
+	"internal/buildcfg"
 	"io"
 	"io/ioutil"
 	"os"
+	"os/exec"
 	"path/filepath"
 	"reflect"
 	"runtime"
@@ -245,7 +247,7 @@
 var importSyscall = flag.Bool("import_syscall", true, "import syscall in generated code")
 var trimpath = flag.String("trimpath", "", "applies supplied rewrites or trims prefixes to recorded source file paths")
 
-var goarch, goos string
+var goarch, goos, gomips, gomips64 string
 
 func main() {
 	objabi.AddVersionFlag() // -V
@@ -302,6 +304,14 @@
 
 	p := newPackage(args[:i])
 
+	// We need a C compiler to be available. Check this.
+	gccName := p.gccBaseCmd()[0]
+	_, err := exec.LookPath(gccName)
+	if err != nil {
+		fatalf("C compiler %q not found: %v", gccName, err)
+		os.Exit(2)
+	}
+
 	// Record CGO_LDFLAGS from the environment for external linking.
 	if ldflags := os.Getenv("CGO_LDFLAGS"); ldflags != "" {
 		args, err := splitQuoted(ldflags)
@@ -405,6 +415,9 @@
 	if s := os.Getenv("GOOS"); s != "" {
 		goos = s
 	}
+	buildcfg.Check()
+	gomips = buildcfg.GOMIPS
+	gomips64 = buildcfg.GOMIPS64
 	ptrSize := ptrSizeMap[goarch]
 	if ptrSize == 0 {
 		fatalf("unknown ptrSize for $GOARCH %q", goarch)
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
index 8e83f02..94152f4 100644
--- a/src/cmd/cgo/out.go
+++ b/src/cmd/cgo/out.go
@@ -168,8 +168,18 @@
 			if *gccgo {
 				fmt.Fprintf(fc, "extern byte *%s;\n", n.C)
 			} else {
-				fmt.Fprintf(fm, "extern char %s[];\n", n.C)
-				fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C)
+				// Force a reference to all symbols so that
+				// the external linker will add DT_NEEDED
+				// entries as needed on ELF systems.
+				// Treat function variables differently
+				// to avoid type confict errors from LTO
+				// (Link Time Optimization).
+				if n.Kind == "fpvar" {
+					fmt.Fprintf(fm, "extern void %s();\n", n.C)
+				} else {
+					fmt.Fprintf(fm, "extern char %s[];\n", n.C)
+					fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C)
+				}
 				fmt.Fprintf(fgo2, "//go:linkname __cgo_%s %s\n", n.C, n.C)
 				fmt.Fprintf(fgo2, "//go:cgo_import_static %s\n", n.C)
 				fmt.Fprintf(fgo2, "var __cgo_%s byte\n", n.C)
@@ -1021,14 +1031,28 @@
 		}
 		fmt.Fprintf(fgcc, "}\n")
 
+		// In internal linking mode, the Go linker sees both
+		// the C wrapper written above and the Go wrapper it
+		// references. Hence, export the C wrapper (e.g., for
+		// if we're building a shared object). The Go linker
+		// will resolve the C wrapper's reference to the Go
+		// wrapper without a separate export.
+		fmt.Fprintf(fgo2, "//go:cgo_export_dynamic %s\n", exp.ExpName)
+		// cgo_export_static refers to a symbol by its linker
+		// name, so set the linker name of the Go wrapper.
+		fmt.Fprintf(fgo2, "//go:linkname _cgoexp%s_%s _cgoexp%s_%s\n", cPrefix, exp.ExpName, cPrefix, exp.ExpName)
+		// In external linking mode, the Go linker sees the Go
+		// wrapper, but not the C wrapper. For this case,
+		// export the Go wrapper so the host linker can
+		// resolve the reference from the C wrapper to the Go
+		// wrapper.
+		fmt.Fprintf(fgo2, "//go:cgo_export_static _cgoexp%s_%s\n", cPrefix, exp.ExpName)
+
 		// Build the wrapper function compiled by cmd/compile.
 		// This unpacks the argument struct above and calls the Go function.
-		fmt.Fprintf(fgo2, "//go:cgo_export_dynamic %s\n", exp.ExpName)
-		fmt.Fprintf(fgo2, "//go:linkname _cgoexp%s_%s _cgoexp%s_%s\n", cPrefix, exp.ExpName, cPrefix, exp.ExpName)
-		fmt.Fprintf(fgo2, "//go:cgo_export_static _cgoexp%s_%s\n", cPrefix, exp.ExpName)
 		fmt.Fprintf(fgo2, "func _cgoexp%s_%s(a *%s) {\n", cPrefix, exp.ExpName, gotype)
 
-		fmt.Fprintf(fm, "int _cgoexp%s_%s;\n", cPrefix, exp.ExpName)
+		fmt.Fprintf(fm, "void _cgoexp%s_%s(void* p){}\n", cPrefix, exp.ExpName)
 
 		if gccResult != "void" {
 			// Write results back to frame.
@@ -1717,8 +1741,12 @@
 struct __go_string __go_byte_array_to_string(const void* p, intgo len);
 struct __go_open_array __go_string_to_byte_array (struct __go_string str);
 
+extern void runtime_throw(const char *);
+
 const char *_cgoPREFIX_Cfunc_CString(struct __go_string s) {
 	char *p = malloc(s.__length+1);
+	if(p == NULL)
+		runtime_throw("runtime: C malloc failed");
 	memmove(p, s.__data, s.__length);
 	p[s.__length] = 0;
 	return p;
@@ -1726,6 +1754,8 @@
 
 void *_cgoPREFIX_Cfunc_CBytes(struct __go_open_array b) {
 	char *p = malloc(b.__count);
+	if(p == NULL)
+		runtime_throw("runtime: C malloc failed");
 	memmove(p, b.__values, b.__count);
 	return p;
 }
@@ -1744,14 +1774,13 @@
 	return __go_string_to_byte_array(s);
 }
 
-extern void runtime_throw(const char *);
 void *_cgoPREFIX_Cfunc__CMalloc(size_t n) {
-        void *p = malloc(n);
-        if(p == NULL && n == 0)
-                p = malloc(1);
-        if(p == NULL)
-                runtime_throw("runtime: C malloc failed");
-        return p;
+	void *p = malloc(n);
+	if(p == NULL && n == 0)
+		p = malloc(1);
+	if(p == NULL)
+		runtime_throw("runtime: C malloc failed");
+	return p;
 }
 
 struct __go_type_descriptor;
diff --git a/src/cmd/compile/abi-internal.md b/src/cmd/compile/abi-internal.md
new file mode 100644
index 0000000..2bb4055
--- /dev/null
+++ b/src/cmd/compile/abi-internal.md
@@ -0,0 +1,645 @@
+# Go internal ABI specification
+
+This document describes Go’s internal application binary interface
+(ABI), known as ABIInternal.
+Go's ABI defines the layout of data in memory and the conventions for
+calling between Go functions.
+This ABI is *unstable* and will change between Go versions.
+If you’re writing assembly code, please instead refer to Go’s
+[assembly documentation](/doc/asm.html), which describes Go’s stable
+ABI, known as ABI0.
+
+All functions defined in Go source follow ABIInternal.
+However, ABIInternal and ABI0 functions are able to call each other
+through transparent *ABI wrappers*, described in the [internal calling
+convention proposal](https://golang.org/design/27539-internal-abi).
+
+Go uses a common ABI design across all architectures.
+We first describe the common ABI, and then cover per-architecture
+specifics.
+
+*Rationale*: For the reasoning behind using a common ABI across
+architectures instead of the platform ABI, see the [register-based Go
+calling convention proposal](https://golang.org/design/40724-register-calling).
+
+## Memory layout
+
+Go's built-in types have the following sizes and alignments.
+Many, though not all, of these sizes are guaranteed by the [language
+specification](/doc/go_spec.html#Size_and_alignment_guarantees).
+Those that aren't guaranteed may change in future versions of Go (for
+example, we've considered changing the alignment of int64 on 32-bit).
+
+| Type | 64-bit |       | 32-bit |       |
+| ---  | ---    | ---   | ---    | ---   |
+|      | Size   | Align | Size   | Align |
+| bool, uint8, int8  | 1  | 1 | 1  | 1 |
+| uint16, int16      | 2  | 2 | 2  | 2 |
+| uint32, int32      | 4  | 4 | 4  | 4 |
+| uint64, int64      | 8  | 8 | 8  | 4 |
+| int, uint          | 8  | 8 | 4  | 4 |
+| float32            | 4  | 4 | 4  | 4 |
+| float64            | 8  | 8 | 8  | 4 |
+| complex64          | 8  | 4 | 8  | 4 |
+| complex128         | 16 | 8 | 16 | 4 |
+| uintptr, *T, unsafe.Pointer | 8 | 8 | 4 | 4 |
+
+The types `byte` and `rune` are aliases for `uint8` and `int32`,
+respectively, and hence have the same size and alignment as these
+types.
+
+The layout of `map`, `chan`, and `func` types is equivalent to *T.
+
+To describe the layout of the remaining composite types, we first
+define the layout of a *sequence* S of N fields with types
+t<sub>1</sub>, t<sub>2</sub>, ..., t<sub>N</sub>.
+We define the byte offset at which each field begins relative to a
+base address of 0, as well as the size and alignment of the sequence
+as follows:
+
+```
+offset(S, i) = 0  if i = 1
+             = align(offset(S, i-1) + sizeof(t_(i-1)), alignof(t_i))
+alignof(S)   = 1  if N = 0
+             = max(alignof(t_i) | 1 <= i <= N)
+sizeof(S)    = 0  if N = 0
+             = align(offset(S, N) + sizeof(t_N), alignof(S))
+```
+
+Where sizeof(T) and alignof(T) are the size and alignment of type T,
+respectively, and align(x, y) rounds x up to a multiple of y.
+
+The `interface{}` type is a sequence of 1. a pointer to the runtime type
+description for the interface's dynamic type and 2. an `unsafe.Pointer`
+data field.
+Any other interface type (besides the empty interface) is a sequence
+of 1. a pointer to the runtime "itab" that gives the method pointers and
+the type of the data field and 2. an `unsafe.Pointer` data field.
+An interface can be "direct" or "indirect" depending on the dynamic
+type: a direct interface stores the value directly in the data field,
+and an indirect interface stores a pointer to the value in the data
+field.
+An interface can only be direct if the value consists of a single
+pointer word.
+
+An array type `[N]T` is a sequence of N fields of type T.
+
+The slice type `[]T` is a sequence of a `*[cap]T` pointer to the slice
+backing store, an `int` giving the `len` of the slice, and an `int`
+giving the `cap` of the slice.
+
+The `string` type is a sequence of a `*[len]byte` pointer to the
+string backing store, and an `int` giving the `len` of the string.
+
+A struct type `struct { f1 t1; ...; fM tM }` is laid out as the
+sequence t1, ..., tM, tP, where tP is either:
+
+- Type `byte` if sizeof(tM) = 0 and any of sizeof(t*i*) ≠ 0.
+- Empty (size 0 and align 1) otherwise.
+
+The padding byte prevents creating a past-the-end pointer by taking
+the address of the final, empty fN field.
+
+Note that user-written assembly code should generally not depend on Go
+type layout and should instead use the constants defined in
+[`go_asm.h`](/doc/asm.html#data-offsets).
+
+## Function call argument and result passing
+
+Function calls pass arguments and results using a combination of the
+stack and machine registers.
+Each argument or result is passed either entirely in registers or
+entirely on the stack.
+Because access to registers is generally faster than access to the
+stack, arguments and results are preferentially passed in registers.
+However, any argument or result that contains a non-trivial array or
+does not fit entirely in the remaining available registers is passed
+on the stack.
+
+Each architecture defines a sequence of integer registers and a
+sequence of floating-point registers.
+At a high level, arguments and results are recursively broken down
+into values of base types and these base values are assigned to
+registers from these sequences.
+
+Arguments and results can share the same registers, but do not share
+the same stack space.
+Beyond the arguments and results passed on the stack, the caller also
+reserves spill space on the stack for all register-based arguments
+(but does not populate this space).
+
+The receiver, arguments, and results of function or method F are
+assigned to registers or the stack using the following algorithm:
+
+1. Let NI and NFP be the length of integer and floating-point register
+   sequences defined by the architecture.
+   Let I and FP be 0; these are the indexes of the next integer and
+   floating-pointer register.
+   Let S, the type sequence defining the stack frame, be empty.
+1. If F is a method, assign F’s receiver.
+1. For each argument A of F, assign A.
+1. Add a pointer-alignment field to S. This has size 0 and the same
+   alignment as `uintptr`.
+1. Reset I and FP to 0.
+1. For each result R of F, assign R.
+1. Add a pointer-alignment field to S.
+1. For each register-assigned receiver and argument of F, let T be its
+   type and add T to the stack sequence S.
+   This is the argument's (or receiver's) spill space and will be
+   uninitialized at the call.
+1. Add a pointer-alignment field to S.
+
+Assigning a receiver, argument, or result V of underlying type T works
+as follows:
+
+1. Remember I and FP.
+1. If T has zero size, add T to the stack sequence S and return.
+1. Try to register-assign V.
+1. If step 2 failed, reset I and FP to the values from step 1, add T
+   to the stack sequence S, and assign V to this field in S.
+
+Register-assignment of a value V of underlying type T works as follows:
+
+1. If T is a boolean or integral type that fits in an integer
+   register, assign V to register I and increment I.
+1. If T is an integral type that fits in two integer registers, assign
+   the least significant and most significant halves of V to registers
+   I and I+1, respectively, and increment I by 2
+1. If T is a floating-point type and can be represented without loss
+   of precision in a floating-point register, assign V to register FP
+   and increment FP.
+1. If T is a complex type, recursively register-assign its real and
+   imaginary parts.
+1. If T is a pointer type, map type, channel type, or function type,
+   assign V to register I and increment I.
+1. If T is a string type, interface type, or slice type, recursively
+   register-assign V’s components (2 for strings and interfaces, 3 for
+   slices).
+1. If T is a struct type, recursively register-assign each field of V.
+1. If T is an array type of length 0, do nothing.
+1. If T is an array type of length 1, recursively register-assign its
+   one element.
+1. If T is an array type of length > 1, fail.
+1. If I > NI or FP > NFP, fail.
+1. If any recursive assignment above fails, fail.
+
+The above algorithm produces an assignment of each receiver, argument,
+and result to registers or to a field in the stack sequence.
+The final stack sequence looks like: stack-assigned receiver,
+stack-assigned arguments, pointer-alignment, stack-assigned results,
+pointer-alignment, spill space for each register-assigned argument,
+pointer-alignment.
+The following diagram shows what this stack frame looks like on the
+stack, using the typical convention where address 0 is at the bottom:
+
+    +------------------------------+
+    |             . . .            |
+    | 2nd reg argument spill space |
+    | 1st reg argument spill space |
+    | <pointer-sized alignment>    |
+    |             . . .            |
+    | 2nd stack-assigned result    |
+    | 1st stack-assigned result    |
+    | <pointer-sized alignment>    |
+    |             . . .            |
+    | 2nd stack-assigned argument  |
+    | 1st stack-assigned argument  |
+    | stack-assigned receiver      |
+    +------------------------------+ ↓ lower addresses
+
+To perform a call, the caller reserves space starting at the lowest
+address in its stack frame for the call stack frame, stores arguments
+in the registers and argument stack fields determined by the above
+algorithm, and performs the call.
+At the time of a call, spill space, result stack fields, and result
+registers are left uninitialized.
+Upon return, the callee must have stored results to all result
+registers and result stack fields determined by the above algorithm.
+
+There are no callee-save registers, so a call may overwrite any
+register that doesn’t have a fixed meaning, including argument
+registers.
+
+### Example
+
+Consider the function `func f(a1 uint8, a2 [2]uintptr, a3 uint8) (r1
+struct { x uintptr; y [2]uintptr }, r2 string)` on a 64-bit
+architecture with hypothetical integer registers R0–R9.
+
+On entry, `a1` is assigned to `R0`, `a3` is assigned to `R1` and the
+stack frame is laid out in the following sequence:
+
+    a2      [2]uintptr
+    r1.x    uintptr
+    r1.y    [2]uintptr
+    a1Spill uint8
+    a3Spill uint8
+    _       [6]uint8  // alignment padding
+
+In the stack frame, only the `a2` field is initialized on entry; the
+rest of the frame is left uninitialized.
+
+On exit, `r2.base` is assigned to `R0`, `r2.len` is assigned to `R1`,
+and `r1.x` and `r1.y` are initialized in the stack frame.
+
+There are several things to note in this example.
+First, `a2` and `r1` are stack-assigned because they contain arrays.
+The other arguments and results are register-assigned.
+Result `r2` is decomposed into its components, which are individually
+register-assigned.
+On the stack, the stack-assigned arguments appear at lower addresses
+than the stack-assigned results, which appear at lower addresses than
+the argument spill area.
+Only arguments, not results, are assigned a spill area on the stack.
+
+### Rationale
+
+Each base value is assigned to its own register to optimize
+construction and access.
+An alternative would be to pack multiple sub-word values into
+registers, or to simply map an argument's in-memory layout to
+registers (this is common in C ABIs), but this typically adds cost to
+pack and unpack these values.
+Modern architectures have more than enough registers to pass all
+arguments and results this way for nearly all functions (see the
+appendix), so there’s little downside to spreading base values across
+registers.
+
+Arguments that can’t be fully assigned to registers are passed
+entirely on the stack in case the callee takes the address of that
+argument.
+If an argument could be split across the stack and registers and the
+callee took its address, it would need to be reconstructed in memory,
+a process that would be proportional to the size of the argument.
+
+Non-trivial arrays are always passed on the stack because indexing
+into an array typically requires a computed offset, which generally
+isn’t possible with registers.
+Arrays in general are rare in function signatures (only 0.7% of
+functions in the Go 1.15 standard library and 0.2% in kubelet).
+We considered allowing array fields to be passed on the stack while
+the rest of an argument’s fields are passed in registers, but this
+creates the same problems as other large structs if the callee takes
+the address of an argument, and would benefit <0.1% of functions in
+kubelet (and even these very little).
+
+We make exceptions for 0 and 1-element arrays because these don’t
+require computed offsets, and 1-element arrays are already decomposed
+in the compiler’s SSA representation.
+
+The ABI assignment algorithm above is equivalent to Go’s stack-based
+ABI0 calling convention if there are zero architecture registers.
+This is intended to ease the transition to the register-based internal
+ABI and make it easy for the compiler to generate either calling
+convention.
+An architecture may still define register meanings that aren’t
+compatible with ABI0, but these differences should be easy to account
+for in the compiler.
+
+The assignment algorithm assigns zero-sized values to the stack
+(assignment step 2) in order to support ABI0-equivalence.
+While these values take no space themselves, they do result in
+alignment padding on the stack in ABI0.
+Without this step, the internal ABI would register-assign zero-sized
+values even on architectures that provide no argument registers
+because they don't consume any registers, and hence not add alignment
+padding to the stack.
+
+The algorithm reserves spill space for arguments in the caller’s frame
+so that the compiler can generate a stack growth path that spills into
+this reserved space.
+If the callee has to grow the stack, it may not be able to reserve
+enough additional stack space in its own frame to spill these, which
+is why it’s important that the caller do so.
+These slots also act as the home location if these arguments need to
+be spilled for any other reason, which simplifies traceback printing.
+
+There are several options for how to lay out the argument spill space.
+We chose to lay out each argument according to its type's usual memory
+layout but to separate the spill space from the regular argument
+space.
+Using the usual memory layout simplifies the compiler because it
+already understands this layout.
+Also, if a function takes the address of a register-assigned argument,
+the compiler must spill that argument to memory in its usual memory
+layout and it's more convenient to use the argument spill space for
+this purpose.
+
+Alternatively, the spill space could be structured around argument
+registers.
+In this approach, the stack growth spill path would spill each
+argument register to a register-sized stack word.
+However, if the function takes the address of a register-assigned
+argument, the compiler would have to reconstruct it in memory layout
+elsewhere on the stack.
+
+The spill space could also be interleaved with the stack-assigned
+arguments so the arguments appear in order whether they are register-
+or stack-assigned.
+This would be close to ABI0, except that register-assigned arguments
+would be uninitialized on the stack and there's no need to reserve
+stack space for register-assigned results.
+We expect separating the spill space to perform better because of
+memory locality.
+Separating the space is also potentially simpler for `reflect` calls
+because this allows `reflect` to summarize the spill space as a single
+number.
+Finally, the long-term intent is to remove reserved spill slots
+entirely – allowing most functions to be called without any stack
+setup and easing the introduction of callee-save registers – and
+separating the spill space makes that transition easier.
+
+## Closures
+
+A func value (e.g., `var x func()`) is a pointer to a closure object.
+A closure object begins with a pointer-sized program counter
+representing the entry point of the function, followed by zero or more
+bytes containing the closed-over environment.
+
+Closure calls follow the same conventions as static function and
+method calls, with one addition. Each architecture specifies a
+*closure context pointer* register and calls to closures store the
+address of the closure object in the closure context pointer register
+prior to the call.
+
+## Software floating-point mode
+
+In "softfloat" mode, the ABI simply treats the hardware as having zero
+floating-point registers.
+As a result, any arguments containing floating-point values will be
+passed on the stack.
+
+*Rationale*: Softfloat mode is about compatibility over performance
+and is not commonly used.
+Hence, we keep the ABI as simple as possible in this case, rather than
+adding additional rules for passing floating-point values in integer
+registers.
+
+## Architecture specifics
+
+This section describes per-architecture register mappings, as well as
+other per-architecture special cases.
+
+### amd64 architecture
+
+The amd64 architecture uses the following sequence of 9 registers for
+integer arguments and results:
+
+    RAX, RBX, RCX, RDI, RSI, R8, R9, R10, R11
+
+It uses X0 – X14 for floating-point arguments and results.
+
+*Rationale*: These sequences are chosen from the available registers
+to be relatively easy to remember.
+
+Registers R12 and R13 are permanent scratch registers.
+R15 is a scratch register except in dynamically linked binaries.
+
+*Rationale*: Some operations such as stack growth and reflection calls
+need dedicated scratch registers in order to manipulate call frames
+without corrupting arguments or results.
+
+Special-purpose registers are as follows:
+
+| Register | Call meaning | Return meaning | Body meaning |
+| --- | --- | --- | --- |
+| RSP | Stack pointer | Same | Same |
+| RBP | Frame pointer | Same | Same |
+| RDX | Closure context pointer | Scratch | Scratch |
+| R12 | Scratch | Scratch | Scratch |
+| R13 | Scratch | Scratch | Scratch |
+| R14 | Current goroutine | Same | Same |
+| R15 | GOT reference temporary if dynlink | Same | Same |
+| X15 | Zero value | Same | Scratch |
+
+*Rationale*: These register meanings are compatible with Go’s
+stack-based calling convention except for R14 and X15, which will have
+to be restored on transitions from ABI0 code to ABIInternal code.
+In ABI0, these are undefined, so transitions from ABIInternal to ABI0
+can ignore these registers.
+
+*Rationale*: For the current goroutine pointer, we chose a register
+that requires an additional REX byte.
+While this adds one byte to every function prologue, it is hardly ever
+accessed outside the function prologue and we expect making more
+single-byte registers available to be a net win.
+
+*Rationale*: We could allow R14 (the current goroutine pointer) to be
+a scratch register in function bodies because it can always be
+restored from TLS on amd64.
+However, we designate it as a fixed register for simplicity and for
+consistency with other architectures that may not have a copy of the
+current goroutine pointer in TLS.
+
+*Rationale*: We designate X15 as a fixed zero register because
+functions often have to bulk zero their stack frames, and this is more
+efficient with a designated zero register.
+
+*Implementation note*: Registers with fixed meaning at calls but not
+in function bodies must be initialized by "injected" calls such as
+signal-based panics.
+
+#### Stack layout
+
+The stack pointer, RSP, grows down and is always aligned to 8 bytes.
+
+The amd64 architecture does not use a link register.
+
+A function's stack frame is laid out as follows:
+
+    +------------------------------+
+    | return PC                    |
+    | RBP on entry                 |
+    | ... locals ...               |
+    | ... outgoing arguments ...   |
+    +------------------------------+ ↓ lower addresses
+
+The "return PC" is pushed as part of the standard amd64 `CALL`
+operation.
+On entry, a function subtracts from RSP to open its stack frame and
+saves the value of RBP directly below the return PC.
+A leaf function that does not require any stack space may omit the
+saved RBP.
+
+The Go ABI's use of RBP as a frame pointer register is compatible with
+amd64 platform conventions so that Go can inter-operate with platform
+debuggers and profilers.
+
+#### Flags
+
+The direction flag (D) is always cleared (set to the “forward”
+direction) at a call.
+The arithmetic status flags are treated like scratch registers and not
+preserved across calls.
+All other bits in RFLAGS are system flags.
+
+At function calls and returns, the CPU is in x87 mode (not MMX
+technology mode).
+
+*Rationale*: Go on amd64 does not use either the x87 registers or MMX
+registers. Hence, we follow the SysV platform conventions in order to
+simplify transitions to and from the C ABI.
+
+At calls, the MXCSR control bits are always set as follows:
+
+| Flag | Bit | Value | Meaning |
+| --- | --- | --- | --- |
+| FZ | 15 | 0 | Do not flush to zero |
+| RC | 14/13 | 0 (RN) | Round to nearest |
+| PM | 12 | 1 | Precision masked |
+| UM | 11 | 1 | Underflow masked |
+| OM | 10 | 1 | Overflow masked |
+| ZM | 9 | 1 | Divide-by-zero masked |
+| DM | 8 | 1 | Denormal operations masked |
+| IM | 7 | 1 | Invalid operations masked |
+| DAZ | 6 | 0 | Do not zero de-normals |
+
+The MXCSR status bits are callee-save.
+
+*Rationale*: Having a fixed MXCSR control configuration allows Go
+functions to use SSE operations without modifying or saving the MXCSR.
+Functions are allowed to modify it between calls (as long as they
+restore it), but as of this writing Go code never does.
+The above fixed configuration matches the process initialization
+control bits specified by the ELF AMD64 ABI.
+
+The x87 floating-point control word is not used by Go on amd64.
+
+## Future directions
+
+### Spill path improvements
+
+The ABI currently reserves spill space for argument registers so the
+compiler can statically generate an argument spill path before calling
+into `runtime.morestack` to grow the stack.
+This ensures there will be sufficient spill space even when the stack
+is nearly exhausted and keeps stack growth and stack scanning
+essentially unchanged from ABI0.
+
+However, this wastes stack space (the median wastage is 16 bytes per
+call), resulting in larger stacks and increased cache footprint.
+A better approach would be to reserve stack space only when spilling.
+One way to ensure enough space is available to spill would be for
+every function to ensure there is enough space for the function's own
+frame *as well as* the spill space of all functions it calls.
+For most functions, this would change the threshold for the prologue
+stack growth check.
+For `nosplit` functions, this would change the threshold used in the
+linker's static stack size check.
+
+Allocating spill space in the callee rather than the caller may also
+allow for faster reflection calls in the common case where a function
+takes only register arguments, since it would allow reflection to make
+these calls directly without allocating any frame.
+
+The statically-generated spill path also increases code size.
+It is possible to instead have a generic spill path in the runtime, as
+part of `morestack`.
+However, this complicates reserving the spill space, since spilling
+all possible register arguments would, in most cases, take
+significantly more space than spilling only those used by a particular
+function.
+Some options are to spill to a temporary space and copy back only the
+registers used by the function, or to grow the stack if necessary
+before spilling to it (using a temporary space if necessary), or to
+use a heap-allocated space if insufficient stack space is available.
+These options all add enough complexity that we will have to make this
+decision based on the actual code size growth caused by the static
+spill paths.
+
+### Clobber sets
+
+As defined, the ABI does not use callee-save registers.
+This significantly simplifies the garbage collector and the compiler's
+register allocator, but at some performance cost.
+A potentially better balance for Go code would be to use *clobber
+sets*: for each function, the compiler records the set of registers it
+clobbers (including those clobbered by functions it calls) and any
+register not clobbered by function F can remain live across calls to
+F.
+
+This is generally a good fit for Go because Go's package DAG allows
+function metadata like the clobber set to flow up the call graph, even
+across package boundaries.
+Clobber sets would require relatively little change to the garbage
+collector, unlike general callee-save registers.
+One disadvantage of clobber sets over callee-save registers is that
+they don't help with indirect function calls or interface method
+calls, since static information isn't available in these cases.
+
+### Large aggregates
+
+Go encourages passing composite values by value, and this simplifies
+reasoning about mutation and races.
+However, this comes at a performance cost for large composite values.
+It may be possible to instead transparently pass large composite
+values by reference and delay copying until it is actually necessary.
+
+## Appendix: Register usage analysis
+
+In order to understand the impacts of the above design on register
+usage, we
+[analyzed](https://github.com/aclements/go-misc/tree/master/abi) the
+impact of the above ABI on a large code base: cmd/kubelet from
+[Kubernetes](https://github.com/kubernetes/kubernetes) at tag v1.18.8.
+
+The following table shows the impact of different numbers of available
+integer and floating-point registers on argument assignment:
+
+```
+|      |        |       |      stack args |          spills |     stack total |
+| ints | floats | % fit | p50 | p95 | p99 | p50 | p95 | p99 | p50 | p95 | p99 |
+|    0 |      0 |  6.3% |  32 | 152 | 256 |   0 |   0 |   0 |  32 | 152 | 256 |
+|    0 |      8 |  6.4% |  32 | 152 | 256 |   0 |   0 |   0 |  32 | 152 | 256 |
+|    1 |      8 | 21.3% |  24 | 144 | 248 |   8 |   8 |   8 |  32 | 152 | 256 |
+|    2 |      8 | 38.9% |  16 | 128 | 224 |   8 |  16 |  16 |  24 | 136 | 240 |
+|    3 |      8 | 57.0% |   0 | 120 | 224 |  16 |  24 |  24 |  24 | 136 | 240 |
+|    4 |      8 | 73.0% |   0 | 120 | 216 |  16 |  32 |  32 |  24 | 136 | 232 |
+|    5 |      8 | 83.3% |   0 | 112 | 216 |  16 |  40 |  40 |  24 | 136 | 232 |
+|    6 |      8 | 87.5% |   0 | 112 | 208 |  16 |  48 |  48 |  24 | 136 | 232 |
+|    7 |      8 | 89.8% |   0 | 112 | 208 |  16 |  48 |  56 |  24 | 136 | 232 |
+|    8 |      8 | 91.3% |   0 | 112 | 200 |  16 |  56 |  64 |  24 | 136 | 232 |
+|    9 |      8 | 92.1% |   0 | 112 | 192 |  16 |  56 |  72 |  24 | 136 | 232 |
+|   10 |      8 | 92.6% |   0 | 104 | 192 |  16 |  56 |  72 |  24 | 136 | 232 |
+|   11 |      8 | 93.1% |   0 | 104 | 184 |  16 |  56 |  80 |  24 | 128 | 232 |
+|   12 |      8 | 93.4% |   0 | 104 | 176 |  16 |  56 |  88 |  24 | 128 | 232 |
+|   13 |      8 | 94.0% |   0 |  88 | 176 |  16 |  56 |  96 |  24 | 128 | 232 |
+|   14 |      8 | 94.4% |   0 |  80 | 152 |  16 |  64 | 104 |  24 | 128 | 232 |
+|   15 |      8 | 94.6% |   0 |  80 | 152 |  16 |  64 | 112 |  24 | 128 | 232 |
+|   16 |      8 | 94.9% |   0 |  16 | 152 |  16 |  64 | 112 |  24 | 128 | 232 |
+|    ∞ |      8 | 99.8% |   0 |   0 |   0 |  24 | 112 | 216 |  24 | 120 | 216 |
+```
+
+The first two columns show the number of available integer and
+floating-point registers.
+The first row shows the results for 0 integer and 0 floating-point
+registers, which is equivalent to ABI0.
+We found that any reasonable number of floating-point registers has
+the same effect, so we fixed it at 8 for all other rows.
+
+The “% fit” column gives the fraction of functions where all arguments
+and results are register-assigned and no arguments are passed on the
+stack.
+The three “stack args” columns give the median, 95th and 99th
+percentile number of bytes of stack arguments.
+The “spills” columns likewise summarize the number of bytes in
+on-stack spill space.
+And “stack total” summarizes the sum of stack arguments and on-stack
+spill slots.
+Note that these are three different distributions; for example,
+there’s no single function that takes 0 stack argument bytes, 16 spill
+bytes, and 24 total stack bytes.
+
+From this, we can see that the fraction of functions that fit entirely
+in registers grows very slowly once it reaches about 90%, though
+curiously there is a small minority of functions that could benefit
+from a huge number of registers.
+Making 9 integer registers available on amd64 puts it in this realm.
+We also see that the stack space required for most functions is fairly
+small.
+While the increasing space required for spills largely balances out
+the decreasing space required for stack arguments as the number of
+available registers increases, there is a general reduction in the
+total stack space required with more available registers.
+This does, however, suggest that eliminating spill slots in the future
+would noticeably reduce stack requirements.
diff --git a/src/cmd/compile/doc.go b/src/cmd/compile/doc.go
index 46d4722..b68ef27 100644
--- a/src/cmd/compile/doc.go
+++ b/src/cmd/compile/doc.go
@@ -83,7 +83,8 @@
 		Without this flag, the -o output is a combination of both
 		linker and compiler input.
 	-m
-		Print optimization decisions.
+		Print optimization decisions. Higher values or repetition
+		produce more detail.
 	-memprofile file
 		Write memory profile for the compilation to file.
 	-memprofilerate rate
diff --git a/src/cmd/compile/fmt_test.go b/src/cmd/compile/fmt_test.go
deleted file mode 100644
index 6625ccf..0000000
--- a/src/cmd/compile/fmt_test.go
+++ /dev/null
@@ -1,599 +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 implements TestFormats; a test that verifies
-// format strings in the compiler (this directory and all
-// subdirectories, recursively).
-//
-// TestFormats finds potential (Printf, etc.) format strings.
-// If they are used in a call, the format verbs are verified
-// based on the matching argument type against a precomputed
-// map of valid formats (knownFormats). This map can be used to
-// automatically rewrite format strings across all compiler
-// files with the -r flag.
-//
-// The format map needs to be updated whenever a new (type,
-// format) combination is found and the format verb is not
-// 'v' or 'T' (as in "%v" or "%T"). To update the map auto-
-// matically from the compiler source's use of format strings,
-// use the -u flag. (Whether formats are valid for the values
-// to be formatted must be verified manually, of course.)
-//
-// The -v flag prints out the names of all functions called
-// with a format string, the names of files that were not
-// processed, and any format rewrites made (with -r).
-//
-// Run as: go test -run Formats [-r][-u][-v]
-//
-// Known shortcomings:
-// - indexed format strings ("%[2]s", etc.) are not supported
-//   (the test will fail)
-// - format strings that are not simple string literals cannot
-//   be updated automatically
-//   (the test will fail with respective warnings)
-// - format strings in _test packages outside the current
-//   package are not processed
-//   (the test will report those files)
-//
-package main_test
-
-import (
-	"bytes"
-	"flag"
-	"fmt"
-	"go/ast"
-	"go/build"
-	"go/constant"
-	"go/format"
-	"go/importer"
-	"go/parser"
-	"go/token"
-	"go/types"
-	"internal/testenv"
-	"io"
-	"io/fs"
-	"io/ioutil"
-	"log"
-	"os"
-	"path/filepath"
-	"sort"
-	"strconv"
-	"strings"
-	"testing"
-	"unicode/utf8"
-)
-
-var (
-	rewrite = flag.Bool("r", false, "rewrite format strings")
-	update  = flag.Bool("u", false, "update known formats")
-)
-
-// The following variables collect information across all processed files.
-var (
-	fset          = token.NewFileSet()
-	formatStrings = make(map[*ast.BasicLit]bool)      // set of all potential format strings found
-	foundFormats  = make(map[string]bool)             // set of all formats found
-	callSites     = make(map[*ast.CallExpr]*callSite) // map of all calls
-)
-
-// A File is a corresponding (filename, ast) pair.
-type File struct {
-	name string
-	ast  *ast.File
-}
-
-func TestFormats(t *testing.T) {
-	if testing.Short() && testenv.Builder() == "" {
-		t.Skip("Skipping in short mode")
-	}
-	testenv.MustHaveGoBuild(t) // more restrictive than necessary, but that's ok
-
-	// process all directories
-	filepath.WalkDir(".", func(path string, info fs.DirEntry, err error) error {
-		if info.IsDir() {
-			if info.Name() == "testdata" {
-				return filepath.SkipDir
-			}
-
-			importPath := filepath.Join("cmd/compile", path)
-			if ignoredPackages[filepath.ToSlash(importPath)] {
-				return filepath.SkipDir
-			}
-
-			pkg, err := build.Import(importPath, path, 0)
-			if err != nil {
-				if _, ok := err.(*build.NoGoError); ok {
-					return nil // nothing to do here
-				}
-				t.Fatal(err)
-			}
-			collectPkgFormats(t, pkg)
-		}
-		return nil
-	})
-
-	// test and rewrite formats
-	updatedFiles := make(map[string]File) // files that were rewritten
-	for _, p := range callSites {
-		// test current format literal and determine updated one
-		out := formatReplace(p.str, func(index int, in string) string {
-			if in == "*" {
-				return in // cannot rewrite '*' (as in "%*d")
-			}
-			// in != '*'
-			typ := p.types[index]
-			format := typ + " " + in // e.g., "*Node %n"
-
-			// check if format is known
-			out, known := knownFormats[format]
-
-			// record format if not yet found
-			_, found := foundFormats[format]
-			if !found {
-				foundFormats[format] = true
-			}
-
-			// report an error if the format is unknown and this is the first
-			// time we see it; ignore "%v" and "%T" which are always valid
-			if !known && !found && in != "%v" && in != "%T" {
-				t.Errorf("%s: unknown format %q for %s argument", posString(p.arg), in, typ)
-			}
-
-			if out == "" {
-				out = in
-			}
-			return out
-		})
-
-		// replace existing format literal if it changed
-		if out != p.str {
-			// we cannot replace the argument if it's not a string literal for now
-			// (e.g., it may be "foo" + "bar")
-			lit, ok := p.arg.(*ast.BasicLit)
-			if !ok {
-				delete(callSites, p.call) // treat as if we hadn't found this site
-				continue
-			}
-
-			if testing.Verbose() {
-				fmt.Printf("%s:\n\t- %q\n\t+ %q\n", posString(p.arg), p.str, out)
-			}
-
-			// find argument index of format argument
-			index := -1
-			for i, arg := range p.call.Args {
-				if p.arg == arg {
-					index = i
-					break
-				}
-			}
-			if index < 0 {
-				// we may have processed the same call site twice,
-				// but that shouldn't happen
-				panic("internal error: matching argument not found")
-			}
-
-			// replace literal
-			new := *lit                    // make a copy
-			new.Value = strconv.Quote(out) // this may introduce "-quotes where there were `-quotes
-			p.call.Args[index] = &new
-			updatedFiles[p.file.name] = p.file
-		}
-	}
-
-	// write dirty files back
-	var filesUpdated bool
-	if len(updatedFiles) > 0 && *rewrite {
-		for _, file := range updatedFiles {
-			var buf bytes.Buffer
-			if err := format.Node(&buf, fset, file.ast); err != nil {
-				t.Errorf("WARNING: gofmt %s failed: %v", file.name, err)
-				continue
-			}
-			if err := ioutil.WriteFile(file.name, buf.Bytes(), 0x666); err != nil {
-				t.Errorf("WARNING: writing %s failed: %v", file.name, err)
-				continue
-			}
-			fmt.Printf("updated %s\n", file.name)
-			filesUpdated = true
-		}
-	}
-
-	// report the names of all functions called with a format string
-	if len(callSites) > 0 && testing.Verbose() {
-		set := make(map[string]bool)
-		for _, p := range callSites {
-			set[nodeString(p.call.Fun)] = true
-		}
-		var list []string
-		for s := range set {
-			list = append(list, s)
-		}
-		fmt.Println("\nFunctions called with a format string")
-		writeList(os.Stdout, list)
-	}
-
-	// update formats
-	if len(foundFormats) > 0 && *update {
-		var list []string
-		for s := range foundFormats {
-			list = append(list, fmt.Sprintf("%q: \"\",", s))
-		}
-		var buf bytes.Buffer
-		buf.WriteString(knownFormatsHeader)
-		writeList(&buf, list)
-		buf.WriteString("}\n")
-		out, err := format.Source(buf.Bytes())
-		const outfile = "fmtmap_test.go"
-		if err != nil {
-			t.Errorf("WARNING: gofmt %s failed: %v", outfile, err)
-			out = buf.Bytes() // continue with unformatted source
-		}
-		if err = ioutil.WriteFile(outfile, out, 0644); err != nil {
-			t.Errorf("WARNING: updating format map failed: %v", err)
-		}
-	}
-
-	// check that knownFormats is up to date
-	if !*rewrite && !*update {
-		var mismatch bool
-		for s := range foundFormats {
-			if _, ok := knownFormats[s]; !ok {
-				mismatch = true
-				break
-			}
-		}
-		if !mismatch {
-			for s := range knownFormats {
-				if _, ok := foundFormats[s]; !ok {
-					mismatch = true
-					break
-				}
-			}
-		}
-		if mismatch {
-			t.Errorf("format map is out of date; run 'go test -u' to update and manually verify correctness of change'")
-		}
-	}
-
-	// all format strings of calls must be in the formatStrings set (self-verification)
-	for _, p := range callSites {
-		if lit, ok := p.arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
-			if formatStrings[lit] {
-				// ok
-				delete(formatStrings, lit)
-			} else {
-				// this should never happen
-				panic(fmt.Sprintf("internal error: format string not found (%s)", posString(lit)))
-			}
-		}
-	}
-
-	// if we have any strings left, we may need to update them manually
-	if len(formatStrings) > 0 && filesUpdated {
-		var list []string
-		for lit := range formatStrings {
-			list = append(list, fmt.Sprintf("%s: %s", posString(lit), nodeString(lit)))
-		}
-		fmt.Println("\nWARNING: Potentially missed format strings")
-		writeList(os.Stdout, list)
-		t.Fail()
-	}
-
-	fmt.Println()
-}
-
-// A callSite describes a function call that appears to contain
-// a format string.
-type callSite struct {
-	file  File
-	call  *ast.CallExpr // call containing the format string
-	arg   ast.Expr      // format argument (string literal or constant)
-	str   string        // unquoted format string
-	types []string      // argument types
-}
-
-func collectPkgFormats(t *testing.T, pkg *build.Package) {
-	// collect all files
-	var filenames []string
-	filenames = append(filenames, pkg.GoFiles...)
-	filenames = append(filenames, pkg.CgoFiles...)
-	filenames = append(filenames, pkg.TestGoFiles...)
-
-	// TODO(gri) verify _test files outside package
-	for _, name := range pkg.XTestGoFiles {
-		// don't process this test itself
-		if name != "fmt_test.go" && testing.Verbose() {
-			fmt.Printf("WARNING: %s not processed\n", filepath.Join(pkg.Dir, name))
-		}
-	}
-
-	// make filenames relative to .
-	for i, name := range filenames {
-		filenames[i] = filepath.Join(pkg.Dir, name)
-	}
-
-	// parse all files
-	files := make([]*ast.File, len(filenames))
-	for i, filename := range filenames {
-		f, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
-		if err != nil {
-			t.Fatal(err)
-		}
-		files[i] = f
-	}
-
-	// typecheck package
-	conf := types.Config{Importer: importer.Default()}
-	etypes := make(map[ast.Expr]types.TypeAndValue)
-	if _, err := conf.Check(pkg.ImportPath, fset, files, &types.Info{Types: etypes}); err != nil {
-		t.Fatal(err)
-	}
-
-	// collect all potential format strings (for extra verification later)
-	for _, file := range files {
-		ast.Inspect(file, func(n ast.Node) bool {
-			if s, ok := stringLit(n); ok && isFormat(s) {
-				formatStrings[n.(*ast.BasicLit)] = true
-			}
-			return true
-		})
-	}
-
-	// collect all formats/arguments of calls with format strings
-	for index, file := range files {
-		ast.Inspect(file, func(n ast.Node) bool {
-			if call, ok := n.(*ast.CallExpr); ok {
-				if ignoredFunctions[nodeString(call.Fun)] {
-					return true
-				}
-				// look for an arguments that might be a format string
-				for i, arg := range call.Args {
-					if s, ok := stringVal(etypes[arg]); ok && isFormat(s) {
-						// make sure we have enough arguments
-						n := numFormatArgs(s)
-						if i+1+n > len(call.Args) {
-							t.Errorf("%s: not enough format args (ignore %s?)", posString(call), nodeString(call.Fun))
-							break // ignore this call
-						}
-						// assume last n arguments are to be formatted;
-						// determine their types
-						argTypes := make([]string, n)
-						for i, arg := range call.Args[len(call.Args)-n:] {
-							if tv, ok := etypes[arg]; ok {
-								argTypes[i] = typeString(tv.Type)
-							}
-						}
-						// collect call site
-						if callSites[call] != nil {
-							panic("internal error: file processed twice?")
-						}
-						callSites[call] = &callSite{
-							file:  File{filenames[index], file},
-							call:  call,
-							arg:   arg,
-							str:   s,
-							types: argTypes,
-						}
-						break // at most one format per argument list
-					}
-				}
-			}
-			return true
-		})
-	}
-}
-
-// writeList writes list in sorted order to w.
-func writeList(w io.Writer, list []string) {
-	sort.Strings(list)
-	for _, s := range list {
-		fmt.Fprintln(w, "\t", s)
-	}
-}
-
-// posString returns a string representation of n's position
-// in the form filename:line:col: .
-func posString(n ast.Node) string {
-	if n == nil {
-		return ""
-	}
-	return fset.Position(n.Pos()).String()
-}
-
-// nodeString returns a string representation of n.
-func nodeString(n ast.Node) string {
-	var buf bytes.Buffer
-	if err := format.Node(&buf, fset, n); err != nil {
-		log.Fatal(err) // should always succeed
-	}
-	return buf.String()
-}
-
-// typeString returns a string representation of n.
-func typeString(typ types.Type) string {
-	return filepath.ToSlash(typ.String())
-}
-
-// stringLit returns the unquoted string value and true if
-// n represents a string literal; otherwise it returns ""
-// and false.
-func stringLit(n ast.Node) (string, bool) {
-	if lit, ok := n.(*ast.BasicLit); ok && lit.Kind == token.STRING {
-		s, err := strconv.Unquote(lit.Value)
-		if err != nil {
-			log.Fatal(err) // should not happen with correct ASTs
-		}
-		return s, true
-	}
-	return "", false
-}
-
-// stringVal returns the (unquoted) string value and true if
-// tv is a string constant; otherwise it returns "" and false.
-func stringVal(tv types.TypeAndValue) (string, bool) {
-	if tv.IsValue() && tv.Value != nil && tv.Value.Kind() == constant.String {
-		return constant.StringVal(tv.Value), true
-	}
-	return "", false
-}
-
-// 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
-// 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.
-func formatIter(s string, f func(i, j int) int) {
-	i := 0     // index after current rune
-	var r rune // current rune
-
-	next := func() {
-		r1, w := utf8.DecodeRuneInString(s[i:])
-		if w == 0 {
-			r1 = -1 // signal end-of-string
-		}
-		r = r1
-		i += w
-	}
-
-	flags := func() {
-		for r == ' ' || r == '#' || r == '+' || r == '-' || r == '0' {
-			next()
-		}
-	}
-
-	index := func() {
-		if r == '[' {
-			log.Fatalf("cannot handle indexed arguments: %s", s)
-		}
-	}
-
-	digits := func() {
-		index()
-		if r == '*' {
-			i = f(i-1, i)
-			next()
-			return
-		}
-		for '0' <= r && r <= '9' {
-			next()
-		}
-	}
-
-	for next(); r >= 0; next() {
-		if r == '%' {
-			i0 := i
-			next()
-			flags()
-			digits()
-			if r == '.' {
-				next()
-				digits()
-			}
-			index()
-			// accept any letter (a-z, A-Z) as format verb;
-			// ignore anything else
-			if 'a' <= r && r <= 'z' || 'A' <= r && r <= 'Z' {
-				i = f(i0-1, i)
-			}
-		}
-	}
-}
-
-// isFormat reports whether s contains format specifiers.
-func isFormat(s string) (yes bool) {
-	formatIter(s, func(i, j int) int {
-		yes = true
-		return len(s) // stop iteration
-	})
-	return
-}
-
-// oneFormat reports whether s is exactly one format specifier.
-func oneFormat(s string) (yes bool) {
-	formatIter(s, func(i, j int) int {
-		yes = i == 0 && j == len(s)
-		return j
-	})
-	return
-}
-
-// numFormatArgs returns the number of format specifiers in s.
-func numFormatArgs(s string) int {
-	count := 0
-	formatIter(s, func(i, j int) int {
-		count++
-		return j
-	})
-	return count
-}
-
-// formatReplace replaces the i'th format specifier s in the incoming
-// string in with the result of f(i, s) and returns the new string.
-func formatReplace(in string, f func(i int, s string) string) string {
-	var buf []byte
-	i0 := 0
-	index := 0
-	formatIter(in, func(i, j int) int {
-		if sub := in[i:j]; sub != "*" { // ignore calls for "*" width/length specifiers
-			buf = append(buf, in[i0:i]...)
-			buf = append(buf, f(index, sub)...)
-			i0 = j
-		}
-		index++
-		return j
-	})
-	return string(append(buf, in[i0:]...))
-}
-
-// ignoredPackages is the set of packages which can
-// be ignored.
-var ignoredPackages = map[string]bool{}
-
-// ignoredFunctions is the set of functions which may have
-// format-like arguments but which don't do any formatting and
-// thus may be ignored.
-var ignoredFunctions = map[string]bool{}
-
-func init() {
-	// verify that knownFormats entries are correctly formatted
-	for key, val := range knownFormats {
-		// key must be "typename format", and format starts with a '%'
-		// (formats containing '*' alone are not collected in this map)
-		i := strings.Index(key, "%")
-		if i < 0 || !oneFormat(key[i:]) {
-			log.Fatalf("incorrect knownFormats key: %q", key)
-		}
-		// val must be "format" or ""
-		if val != "" && !oneFormat(val) {
-			log.Fatalf("incorrect knownFormats value: %q (key = %q)", val, key)
-		}
-	}
-}
-
-const knownFormatsHeader = `// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements the knownFormats map which records the valid
-// formats for a given type. The valid formats must correspond to
-// supported compiler formats implemented in fmt.go, or whatever
-// other format verbs are implemented for the given type. The map may
-// also be used to change the use of a format verb across all compiler
-// sources automatically (for instance, if the implementation of fmt.go
-// changes), by using the -r option together with the new formats in the
-// map. To generate this file automatically from the existing source,
-// run: go test -run Formats -u.
-//
-// See the package comment in fmt_test.go for additional information.
-
-package main_test
-
-// knownFormats entries are of the form "typename format" -> "newformat".
-// An absent entry means that the format is not recognized as valid.
-// An empty new format means that the format should remain unchanged.
-var knownFormats = map[string]string{
-`
diff --git a/src/cmd/compile/fmtmap_test.go b/src/cmd/compile/fmtmap_test.go
deleted file mode 100644
index 0811df7..0000000
--- a/src/cmd/compile/fmtmap_test.go
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements the knownFormats map which records the valid
-// formats for a given type. The valid formats must correspond to
-// supported compiler formats implemented in fmt.go, or whatever
-// other format verbs are implemented for the given type. The map may
-// also be used to change the use of a format verb across all compiler
-// sources automatically (for instance, if the implementation of fmt.go
-// changes), by using the -r option together with the new formats in the
-// map. To generate this file automatically from the existing source,
-// run: go test -run Formats -u.
-//
-// See the package comment in fmt_test.go for additional information.
-
-package main_test
-
-// knownFormats entries are of the form "typename format" -> "newformat".
-// An absent entry means that the format is not recognized as valid.
-// An empty new format means that the format should remain unchanged.
-var knownFormats = map[string]string{
-	"*bytes.Buffer %s":                                "",
-	"*cmd/compile/internal/gc.EscLocation %v":         "",
-	"*cmd/compile/internal/gc.Mpflt %v":               "",
-	"*cmd/compile/internal/gc.Mpint %v":               "",
-	"*cmd/compile/internal/gc.Node %#v":               "",
-	"*cmd/compile/internal/gc.Node %+S":               "",
-	"*cmd/compile/internal/gc.Node %+v":               "",
-	"*cmd/compile/internal/gc.Node %L":                "",
-	"*cmd/compile/internal/gc.Node %S":                "",
-	"*cmd/compile/internal/gc.Node %j":                "",
-	"*cmd/compile/internal/gc.Node %p":                "",
-	"*cmd/compile/internal/gc.Node %v":                "",
-	"*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.Register %s":           "",
-	"*cmd/compile/internal/ssa.Register %v":           "",
-	"*cmd/compile/internal/ssa.SparseTreeNode %v":     "",
-	"*cmd/compile/internal/ssa.Value %s":              "",
-	"*cmd/compile/internal/ssa.Value %v":              "",
-	"*cmd/compile/internal/ssa.sparseTreeMapEntry %v": "",
-	"*cmd/compile/internal/types.Field %p":            "",
-	"*cmd/compile/internal/types.Field %v":            "",
-	"*cmd/compile/internal/types.Sym %0S":             "",
-	"*cmd/compile/internal/types.Sym %S":              "",
-	"*cmd/compile/internal/types.Sym %p":              "",
-	"*cmd/compile/internal/types.Sym %v":              "",
-	"*cmd/compile/internal/types.Type %#L":            "",
-	"*cmd/compile/internal/types.Type %#v":            "",
-	"*cmd/compile/internal/types.Type %+v":            "",
-	"*cmd/compile/internal/types.Type %-S":            "",
-	"*cmd/compile/internal/types.Type %0S":            "",
-	"*cmd/compile/internal/types.Type %L":             "",
-	"*cmd/compile/internal/types.Type %S":             "",
-	"*cmd/compile/internal/types.Type %p":             "",
-	"*cmd/compile/internal/types.Type %s":             "",
-	"*cmd/compile/internal/types.Type %v":             "",
-	"*cmd/internal/obj.Addr %v":                       "",
-	"*cmd/internal/obj.LSym %v":                       "",
-	"*math/big.Float %f":                              "",
-	"*math/big.Int %#x":                               "",
-	"*math/big.Int %s":                                "",
-	"*math/big.Int %v":                                "",
-	"[16]byte %x":                                     "",
-	"[]*cmd/compile/internal/ssa.Block %v":            "",
-	"[]*cmd/compile/internal/ssa.Value %v":            "",
-	"[][]string %q":                                   "",
-	"[]byte %s":                                       "",
-	"[]byte %x":                                       "",
-	"[]cmd/compile/internal/ssa.Edge %v":              "",
-	"[]cmd/compile/internal/ssa.ID %v":                "",
-	"[]cmd/compile/internal/ssa.posetNode %v":         "",
-	"[]cmd/compile/internal/ssa.posetUndo %v":         "",
-	"[]cmd/compile/internal/syntax.token %s":          "",
-	"[]string %v":                                     "",
-	"[]uint32 %v":                                     "",
-	"bool %v":                                         "",
-	"byte %08b":                                       "",
-	"byte %c":                                         "",
-	"byte %q":                                         "",
-	"byte %v":                                         "",
-	"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.Nodes %#v":               "",
-	"cmd/compile/internal/gc.Nodes %+v":               "",
-	"cmd/compile/internal/gc.Nodes %.v":               "",
-	"cmd/compile/internal/gc.Nodes %v":                "",
-	"cmd/compile/internal/gc.Op %#v":                  "",
-	"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.itag %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.ID %v":                  "",
-	"cmd/compile/internal/ssa.LocalSlot %s":           "",
-	"cmd/compile/internal/ssa.LocalSlot %v":           "",
-	"cmd/compile/internal/ssa.Location %s":            "",
-	"cmd/compile/internal/ssa.Op %s":                  "",
-	"cmd/compile/internal/ssa.Op %v":                  "",
-	"cmd/compile/internal/ssa.Sym %v":                 "",
-	"cmd/compile/internal/ssa.ValAndOff %s":           "",
-	"cmd/compile/internal/ssa.domain %v":              "",
-	"cmd/compile/internal/ssa.flagConstant %s":        "",
-	"cmd/compile/internal/ssa.posetNode %v":           "",
-	"cmd/compile/internal/ssa.posetTestOp %v":         "",
-	"cmd/compile/internal/ssa.rbrank %d":              "",
-	"cmd/compile/internal/ssa.regMask %d":             "",
-	"cmd/compile/internal/ssa.register %d":            "",
-	"cmd/compile/internal/ssa.relation %s":            "",
-	"cmd/compile/internal/syntax.Error %q":            "",
-	"cmd/compile/internal/syntax.Expr %#v":            "",
-	"cmd/compile/internal/syntax.LitKind %d":          "",
-	"cmd/compile/internal/syntax.Node %T":             "",
-	"cmd/compile/internal/syntax.Operator %s":         "",
-	"cmd/compile/internal/syntax.Pos %s":              "",
-	"cmd/compile/internal/syntax.Pos %v":              "",
-	"cmd/compile/internal/syntax.position %s":         "",
-	"cmd/compile/internal/syntax.token %q":            "",
-	"cmd/compile/internal/syntax.token %s":            "",
-	"cmd/compile/internal/types.EType %d":             "",
-	"cmd/compile/internal/types.EType %s":             "",
-	"cmd/compile/internal/types.EType %v":             "",
-	"cmd/internal/obj.ABI %v":                         "",
-	"error %v":                                        "",
-	"float64 %.2f":                                    "",
-	"float64 %.3f":                                    "",
-	"float64 %.6g":                                    "",
-	"float64 %g":                                      "",
-	"int %#x":                                         "",
-	"int %-12d":                                       "",
-	"int %-6d":                                        "",
-	"int %-8o":                                        "",
-	"int %02d":                                        "",
-	"int %6d":                                         "",
-	"int %c":                                          "",
-	"int %d":                                          "",
-	"int %v":                                          "",
-	"int %x":                                          "",
-	"int16 %d":                                        "",
-	"int16 %x":                                        "",
-	"int32 %#x":                                       "",
-	"int32 %d":                                        "",
-	"int32 %v":                                        "",
-	"int32 %x":                                        "",
-	"int64 %#x":                                       "",
-	"int64 %+d":                                       "",
-	"int64 %-10d":                                     "",
-	"int64 %.5d":                                      "",
-	"int64 %d":                                        "",
-	"int64 %v":                                        "",
-	"int64 %x":                                        "",
-	"int8 %d":                                         "",
-	"int8 %v":                                         "",
-	"int8 %x":                                         "",
-	"interface{} %#v":                                 "",
-	"interface{} %T":                                  "",
-	"interface{} %p":                                  "",
-	"interface{} %q":                                  "",
-	"interface{} %s":                                  "",
-	"interface{} %v":                                  "",
-	"map[*cmd/compile/internal/gc.Node]*cmd/compile/internal/ssa.Value %v": "",
-	"map[*cmd/compile/internal/gc.Node][]*cmd/compile/internal/gc.Node %v": "",
-	"map[cmd/compile/internal/ssa.ID]uint32 %v":                            "",
-	"map[int64]uint32 %v":  "",
-	"math/big.Accuracy %s": "",
-	"reflect.Type %s":      "",
-	"rune %#U":             "",
-	"rune %c":              "",
-	"rune %q":              "",
-	"string %-*s":          "",
-	"string %-16s":         "",
-	"string %-6s":          "",
-	"string %q":            "",
-	"string %s":            "",
-	"string %v":            "",
-	"time.Duration %d":     "",
-	"time.Duration %v":     "",
-	"uint %04x":            "",
-	"uint %5d":             "",
-	"uint %d":              "",
-	"uint %x":              "",
-	"uint16 %d":            "",
-	"uint16 %x":            "",
-	"uint32 %#U":           "",
-	"uint32 %#x":           "",
-	"uint32 %d":            "",
-	"uint32 %v":            "",
-	"uint32 %x":            "",
-	"uint64 %08x":          "",
-	"uint64 %b":            "",
-	"uint64 %d":            "",
-	"uint64 %x":            "",
-	"uint8 %#x":            "",
-	"uint8 %d":             "",
-	"uint8 %v":             "",
-	"uint8 %x":             "",
-	"uintptr %d":           "",
-}
diff --git a/src/cmd/compile/internal/abi/abiutils.go b/src/cmd/compile/internal/abi/abiutils.go
new file mode 100644
index 0000000..d657ddc
--- /dev/null
+++ b/src/cmd/compile/internal/abi/abiutils.go
@@ -0,0 +1,825 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package abi
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+	"fmt"
+	"sync"
+)
+
+//......................................................................
+//
+// Public/exported bits of the ABI utilities.
+//
+
+// ABIParamResultInfo stores the results of processing a given
+// function type to compute stack layout and register assignments. For
+// each input and output parameter we capture whether the param was
+// register-assigned (and to which register(s)) or the stack offset
+// for the param if is not going to be passed in registers according
+// to the rules in the Go internal ABI specification (1.17).
+type ABIParamResultInfo struct {
+	inparams          []ABIParamAssignment // Includes receiver for method calls.  Does NOT include hidden closure pointer.
+	outparams         []ABIParamAssignment
+	offsetToSpillArea int64
+	spillAreaSize     int64
+	inRegistersUsed   int
+	outRegistersUsed  int
+	config            *ABIConfig // to enable String() method
+}
+
+func (a *ABIParamResultInfo) Config() *ABIConfig {
+	return a.config
+}
+
+func (a *ABIParamResultInfo) InParams() []ABIParamAssignment {
+	return a.inparams
+}
+
+func (a *ABIParamResultInfo) OutParams() []ABIParamAssignment {
+	return a.outparams
+}
+
+func (a *ABIParamResultInfo) InRegistersUsed() int {
+	return a.inRegistersUsed
+}
+
+func (a *ABIParamResultInfo) OutRegistersUsed() int {
+	return a.outRegistersUsed
+}
+
+func (a *ABIParamResultInfo) InParam(i int) *ABIParamAssignment {
+	return &a.inparams[i]
+}
+
+func (a *ABIParamResultInfo) OutParam(i int) *ABIParamAssignment {
+	return &a.outparams[i]
+}
+
+func (a *ABIParamResultInfo) SpillAreaOffset() int64 {
+	return a.offsetToSpillArea
+}
+
+func (a *ABIParamResultInfo) SpillAreaSize() int64 {
+	return a.spillAreaSize
+}
+
+// ArgWidth returns the amount of stack needed for all the inputs
+// and outputs of a function or method, including ABI-defined parameter
+// slots and ABI-defined spill slots for register-resident parameters.
+// The name is inherited from (*Type).ArgWidth(), which it replaces.
+func (a *ABIParamResultInfo) ArgWidth() int64 {
+	return a.spillAreaSize + a.offsetToSpillArea - a.config.LocalsOffset()
+}
+
+// RegIndex stores the index into the set of machine registers used by
+// the ABI on a specific architecture for parameter passing.  RegIndex
+// values 0 through N-1 (where N is the number of integer registers
+// used for param passing according to the ABI rules) describe integer
+// registers; values N through M (where M is the number of floating
+// point registers used).  Thus if the ABI says there are 5 integer
+// registers and 7 floating point registers, then RegIndex value of 4
+// indicates the 5th integer register, and a RegIndex value of 11
+// indicates the 7th floating point register.
+type RegIndex uint8
+
+// ABIParamAssignment holds information about how a specific param or
+// result will be passed: in registers (in which case 'Registers' is
+// populated) or on the stack (in which case 'Offset' is set to a
+// non-negative stack offset. The values in 'Registers' are indices
+// (as described above), not architected registers.
+type ABIParamAssignment struct {
+	Type      *types.Type
+	Name      types.Object // should always be *ir.Name, used to match with a particular ssa.OpArg.
+	Registers []RegIndex
+	offset    int32
+}
+
+// Offset returns the stack offset for addressing the parameter that "a" describes.
+// This will panic if "a" describes a register-allocated parameter.
+func (a *ABIParamAssignment) Offset() int32 {
+	if len(a.Registers) > 0 {
+		base.Fatalf("register allocated parameters have no offset")
+	}
+	return a.offset
+}
+
+// RegisterTypes returns a slice of the types of the registers
+// corresponding to a slice of parameters.  The returned slice
+// has capacity for one more, likely a memory type.
+func RegisterTypes(apa []ABIParamAssignment) []*types.Type {
+	rcount := 0
+	for _, pa := range apa {
+		rcount += len(pa.Registers)
+	}
+	if rcount == 0 {
+		// Note that this catches top-level struct{} and [0]Foo, which are stack allocated.
+		return make([]*types.Type, 0, 1)
+	}
+	rts := make([]*types.Type, 0, rcount+1)
+	for _, pa := range apa {
+		if len(pa.Registers) == 0 {
+			continue
+		}
+		rts = appendParamTypes(rts, pa.Type)
+	}
+	return rts
+}
+
+func (pa *ABIParamAssignment) RegisterTypesAndOffsets() ([]*types.Type, []int64) {
+	l := len(pa.Registers)
+	if l == 0 {
+		return nil, nil
+	}
+	typs := make([]*types.Type, 0, l)
+	offs := make([]int64, 0, l)
+	offs, _ = appendParamOffsets(offs, 0, pa.Type)
+	return appendParamTypes(typs, pa.Type), offs
+}
+
+func appendParamTypes(rts []*types.Type, t *types.Type) []*types.Type {
+	w := t.Width
+	if w == 0 {
+		return rts
+	}
+	if t.IsScalar() || t.IsPtrShaped() {
+		if t.IsComplex() {
+			c := types.FloatForComplex(t)
+			return append(rts, c, c)
+		} else {
+			if int(t.Size()) <= types.RegSize {
+				return append(rts, t)
+			}
+			// assume 64bit int on 32-bit machine
+			// TODO endianness? Should high-order (sign bits) word come first?
+			if t.IsSigned() {
+				rts = append(rts, types.Types[types.TINT32])
+			} else {
+				rts = append(rts, types.Types[types.TUINT32])
+			}
+			return append(rts, types.Types[types.TUINT32])
+		}
+	} else {
+		typ := t.Kind()
+		switch typ {
+		case types.TARRAY:
+			for i := int64(0); i < t.NumElem(); i++ { // 0 gets no registers, plus future-proofing.
+				rts = appendParamTypes(rts, t.Elem())
+			}
+		case types.TSTRUCT:
+			for _, f := range t.FieldSlice() {
+				if f.Type.Size() > 0 { // embedded zero-width types receive no registers
+					rts = appendParamTypes(rts, f.Type)
+				}
+			}
+		case types.TSLICE:
+			return appendParamTypes(rts, synthSlice)
+		case types.TSTRING:
+			return appendParamTypes(rts, synthString)
+		case types.TINTER:
+			return appendParamTypes(rts, synthIface)
+		}
+	}
+	return rts
+}
+
+// appendParamOffsets appends the offset(s) of type t, starting from "at",
+// to input offsets, and returns the longer slice and the next unused offset.
+func appendParamOffsets(offsets []int64, at int64, t *types.Type) ([]int64, int64) {
+	at = align(at, t)
+	w := t.Width
+	if w == 0 {
+		return offsets, at
+	}
+	if t.IsScalar() || t.IsPtrShaped() {
+		if t.IsComplex() || int(t.Width) > types.RegSize { // complex and *int64 on 32-bit
+			s := w / 2
+			return append(offsets, at, at+s), at + w
+		} else {
+			return append(offsets, at), at + w
+		}
+	} else {
+		typ := t.Kind()
+		switch typ {
+		case types.TARRAY:
+			for i := int64(0); i < t.NumElem(); i++ {
+				offsets, at = appendParamOffsets(offsets, at, t.Elem())
+			}
+		case types.TSTRUCT:
+			for i, f := range t.FieldSlice() {
+				offsets, at = appendParamOffsets(offsets, at, f.Type)
+				if f.Type.Width == 0 && i == t.NumFields()-1 {
+					at++ // last field has zero width
+				}
+			}
+			at = align(at, t) // type size is rounded up to its alignment
+		case types.TSLICE:
+			return appendParamOffsets(offsets, at, synthSlice)
+		case types.TSTRING:
+			return appendParamOffsets(offsets, at, synthString)
+		case types.TINTER:
+			return appendParamOffsets(offsets, at, synthIface)
+		}
+	}
+	return offsets, at
+}
+
+// FrameOffset returns the frame-pointer-relative location that a function
+// would spill its input or output parameter to, if such a spill slot exists.
+// If there is none defined (e.g., register-allocated outputs) it panics.
+// For register-allocated inputs that is their spill offset reserved for morestack;
+// for stack-allocated inputs and outputs, that is their location on the stack.
+// (In a future version of the ABI, register-resident inputs may lose their defined
+// spill area to help reduce stack sizes.)
+func (a *ABIParamAssignment) FrameOffset(i *ABIParamResultInfo) int64 {
+	if a.offset == -1 {
+		base.Fatalf("function parameter has no ABI-defined frame-pointer offset")
+	}
+	if len(a.Registers) == 0 { // passed on stack
+		return int64(a.offset) - i.config.LocalsOffset()
+	}
+	// spill area for registers
+	return int64(a.offset) + i.SpillAreaOffset() - i.config.LocalsOffset()
+}
+
+// RegAmounts holds a specified number of integer/float registers.
+type RegAmounts struct {
+	intRegs   int
+	floatRegs int
+}
+
+// ABIConfig captures the number of registers made available
+// by the ABI rules for parameter passing and result returning.
+type ABIConfig struct {
+	// Do we need anything more than this?
+	offsetForLocals  int64 // e.g., obj.(*Link).FixedFrameSize() -- extra linkage information on some architectures.
+	regAmounts       RegAmounts
+	regsForTypeCache map[*types.Type]int
+}
+
+// NewABIConfig returns a new ABI configuration for an architecture with
+// iRegsCount integer/pointer registers and fRegsCount floating point registers.
+func NewABIConfig(iRegsCount, fRegsCount int, offsetForLocals int64) *ABIConfig {
+	return &ABIConfig{offsetForLocals: offsetForLocals, regAmounts: RegAmounts{iRegsCount, fRegsCount}, regsForTypeCache: make(map[*types.Type]int)}
+}
+
+// Copy returns a copy of an ABIConfig for use in a function's compilation so that access to the cache does not need to be protected with a mutex.
+func (a *ABIConfig) Copy() *ABIConfig {
+	b := *a
+	b.regsForTypeCache = make(map[*types.Type]int)
+	return &b
+}
+
+// LocalsOffset returns the architecture-dependent offset from SP for args and results.
+// In theory this is only used for debugging; it ought to already be incorporated into
+// results from the ABI-related methods
+func (a *ABIConfig) LocalsOffset() int64 {
+	return a.offsetForLocals
+}
+
+// FloatIndexFor translates r into an index in the floating point parameter
+// registers.  If the result is negative, the input index was actually for the
+// integer parameter registers.
+func (a *ABIConfig) FloatIndexFor(r RegIndex) int64 {
+	return int64(r) - int64(a.regAmounts.intRegs)
+}
+
+// NumParamRegs returns the number of parameter registers used for a given type,
+// without regard for the number available.
+func (a *ABIConfig) NumParamRegs(t *types.Type) int {
+	var n int
+	if n, ok := a.regsForTypeCache[t]; ok {
+		return n
+	}
+
+	if t.IsScalar() || t.IsPtrShaped() {
+		if t.IsComplex() {
+			n = 2
+		} else {
+			n = (int(t.Size()) + types.RegSize - 1) / types.RegSize
+		}
+	} else {
+		typ := t.Kind()
+		switch typ {
+		case types.TARRAY:
+			n = a.NumParamRegs(t.Elem()) * int(t.NumElem())
+		case types.TSTRUCT:
+			for _, f := range t.FieldSlice() {
+				n += a.NumParamRegs(f.Type)
+			}
+		case types.TSLICE:
+			n = a.NumParamRegs(synthSlice)
+		case types.TSTRING:
+			n = a.NumParamRegs(synthString)
+		case types.TINTER:
+			n = a.NumParamRegs(synthIface)
+		}
+	}
+	a.regsForTypeCache[t] = n
+
+	return n
+}
+
+// preAllocateParams gets the slice sizes right for inputs and outputs.
+func (a *ABIParamResultInfo) preAllocateParams(hasRcvr bool, nIns, nOuts int) {
+	if hasRcvr {
+		nIns++
+	}
+	a.inparams = make([]ABIParamAssignment, 0, nIns)
+	a.outparams = make([]ABIParamAssignment, 0, nOuts)
+}
+
+// ABIAnalyzeTypes takes an optional receiver type, arrays of ins and outs, and returns an ABIParamResultInfo,
+// based on the given configuration.  This is the same result computed by config.ABIAnalyze applied to the
+// corresponding method/function type, except that all the embedded parameter names are nil.
+// This is intended for use by ssagen/ssa.go:(*state).rtcall, for runtime functions that lack a parsed function type.
+func (config *ABIConfig) ABIAnalyzeTypes(rcvr *types.Type, ins, outs []*types.Type) *ABIParamResultInfo {
+	setup()
+	s := assignState{
+		stackOffset: config.offsetForLocals,
+		rTotal:      config.regAmounts,
+	}
+	result := &ABIParamResultInfo{config: config}
+	result.preAllocateParams(rcvr != nil, len(ins), len(outs))
+
+	// Receiver
+	if rcvr != nil {
+		result.inparams = append(result.inparams,
+			s.assignParamOrReturn(rcvr, nil, false))
+	}
+
+	// Inputs
+	for _, t := range ins {
+		result.inparams = append(result.inparams,
+			s.assignParamOrReturn(t, nil, false))
+	}
+	s.stackOffset = types.Rnd(s.stackOffset, int64(types.RegSize))
+	result.inRegistersUsed = s.rUsed.intRegs + s.rUsed.floatRegs
+
+	// Outputs
+	s.rUsed = RegAmounts{}
+	for _, t := range outs {
+		result.outparams = append(result.outparams, s.assignParamOrReturn(t, nil, true))
+	}
+	// The spill area is at a register-aligned offset and its size is rounded up to a register alignment.
+	// TODO in theory could align offset only to minimum required by spilled data types.
+	result.offsetToSpillArea = alignTo(s.stackOffset, types.RegSize)
+	result.spillAreaSize = alignTo(s.spillOffset, types.RegSize)
+	result.outRegistersUsed = s.rUsed.intRegs + s.rUsed.floatRegs
+
+	return result
+}
+
+// ABIAnalyzeFuncType takes a function type 'ft' and an ABI rules description
+// 'config' and analyzes the function to determine how its parameters
+// and results will be passed (in registers or on the stack), returning
+// an ABIParamResultInfo object that holds the results of the analysis.
+func (config *ABIConfig) ABIAnalyzeFuncType(ft *types.Func) *ABIParamResultInfo {
+	setup()
+	s := assignState{
+		stackOffset: config.offsetForLocals,
+		rTotal:      config.regAmounts,
+	}
+	result := &ABIParamResultInfo{config: config}
+	result.preAllocateParams(ft.Receiver != nil, ft.Params.NumFields(), ft.Results.NumFields())
+
+	// Receiver
+	// TODO(register args) ? seems like "struct" and "fields" is not right anymore for describing function parameters
+	if ft.Receiver != nil && ft.Receiver.NumFields() != 0 {
+		r := ft.Receiver.FieldSlice()[0]
+		result.inparams = append(result.inparams,
+			s.assignParamOrReturn(r.Type, r.Nname, false))
+	}
+
+	// Inputs
+	ifsl := ft.Params.FieldSlice()
+	for _, f := range ifsl {
+		result.inparams = append(result.inparams,
+			s.assignParamOrReturn(f.Type, f.Nname, false))
+	}
+	s.stackOffset = types.Rnd(s.stackOffset, int64(types.RegSize))
+	result.inRegistersUsed = s.rUsed.intRegs + s.rUsed.floatRegs
+
+	// Outputs
+	s.rUsed = RegAmounts{}
+	ofsl := ft.Results.FieldSlice()
+	for _, f := range ofsl {
+		result.outparams = append(result.outparams, s.assignParamOrReturn(f.Type, f.Nname, true))
+	}
+	// The spill area is at a register-aligned offset and its size is rounded up to a register alignment.
+	// TODO in theory could align offset only to minimum required by spilled data types.
+	result.offsetToSpillArea = alignTo(s.stackOffset, types.RegSize)
+	result.spillAreaSize = alignTo(s.spillOffset, types.RegSize)
+	result.outRegistersUsed = s.rUsed.intRegs + s.rUsed.floatRegs
+	return result
+}
+
+// ABIAnalyze returns the same result as ABIAnalyzeFuncType, but also
+// updates the offsets of all the receiver, input, and output fields.
+// If setNname is true, it also sets the FrameOffset of the Nname for
+// the field(s); this is for use when compiling a function and figuring out
+// spill locations.  Doing this for callers can cause races for register
+// outputs because their frame location transitions from BOGUS_FUNARG_OFFSET
+// to zero to an as-if-AUTO offset that has no use for callers.
+func (config *ABIConfig) ABIAnalyze(t *types.Type, setNname bool) *ABIParamResultInfo {
+	ft := t.FuncType()
+	result := config.ABIAnalyzeFuncType(ft)
+
+	// Fill in the frame offsets for receiver, inputs, results
+	k := 0
+	if t.NumRecvs() != 0 {
+		config.updateOffset(result, ft.Receiver.FieldSlice()[0], result.inparams[0], false, setNname)
+		k++
+	}
+	for i, f := range ft.Params.FieldSlice() {
+		config.updateOffset(result, f, result.inparams[k+i], false, setNname)
+	}
+	for i, f := range ft.Results.FieldSlice() {
+		config.updateOffset(result, f, result.outparams[i], true, setNname)
+	}
+	return result
+}
+
+func (config *ABIConfig) updateOffset(result *ABIParamResultInfo, f *types.Field, a ABIParamAssignment, isReturn, setNname bool) {
+	// Everything except return values in registers has either a frame home (if not in a register) or a frame spill location.
+	if !isReturn || len(a.Registers) == 0 {
+		// The type frame offset DOES NOT show effects of minimum frame size.
+		// Getting this wrong breaks stackmaps, see liveness/plive.go:WriteFuncMap and typebits/typebits.go:Set
+		off := a.FrameOffset(result)
+		fOffset := f.Offset
+		if fOffset == types.BOGUS_FUNARG_OFFSET {
+			if setNname && f.Nname != nil {
+				f.Nname.(*ir.Name).SetFrameOffset(off)
+				f.Nname.(*ir.Name).SetIsOutputParamInRegisters(false)
+			}
+		} else {
+			base.Fatalf("field offset for %s at %s has been set to %d", f.Sym.Name, base.FmtPos(f.Pos), fOffset)
+		}
+	} else {
+		if setNname && f.Nname != nil {
+			fname := f.Nname.(*ir.Name)
+			fname.SetIsOutputParamInRegisters(true)
+			fname.SetFrameOffset(0)
+		}
+	}
+}
+
+//......................................................................
+//
+// Non-public portions.
+
+// regString produces a human-readable version of a RegIndex.
+func (c *RegAmounts) regString(r RegIndex) string {
+	if int(r) < c.intRegs {
+		return fmt.Sprintf("I%d", int(r))
+	} else if int(r) < c.intRegs+c.floatRegs {
+		return fmt.Sprintf("F%d", int(r)-c.intRegs)
+	}
+	return fmt.Sprintf("<?>%d", r)
+}
+
+// ToString method renders an ABIParamAssignment in human-readable
+// form, suitable for debugging or unit testing.
+func (ri *ABIParamAssignment) ToString(config *ABIConfig, extra bool) string {
+	regs := "R{"
+	offname := "spilloffset" // offset is for spill for register(s)
+	if len(ri.Registers) == 0 {
+		offname = "offset" // offset is for memory arg
+	}
+	for _, r := range ri.Registers {
+		regs += " " + config.regAmounts.regString(r)
+		if extra {
+			regs += fmt.Sprintf("(%d)", r)
+		}
+	}
+	if extra {
+		regs += fmt.Sprintf(" | #I=%d, #F=%d", config.regAmounts.intRegs, config.regAmounts.floatRegs)
+	}
+	return fmt.Sprintf("%s } %s: %d typ: %v", regs, offname, ri.offset, ri.Type)
+}
+
+// String method renders an ABIParamResultInfo in human-readable
+// form, suitable for debugging or unit testing.
+func (ri *ABIParamResultInfo) String() string {
+	res := ""
+	for k, p := range ri.inparams {
+		res += fmt.Sprintf("IN %d: %s\n", k, p.ToString(ri.config, false))
+	}
+	for k, r := range ri.outparams {
+		res += fmt.Sprintf("OUT %d: %s\n", k, r.ToString(ri.config, false))
+	}
+	res += fmt.Sprintf("offsetToSpillArea: %d spillAreaSize: %d",
+		ri.offsetToSpillArea, ri.spillAreaSize)
+	return res
+}
+
+// assignState holds intermediate state during the register assigning process
+// for a given function signature.
+type assignState struct {
+	rTotal      RegAmounts // total reg amounts from ABI rules
+	rUsed       RegAmounts // regs used by params completely assigned so far
+	pUsed       RegAmounts // regs used by the current param (or pieces therein)
+	stackOffset int64      // current stack offset
+	spillOffset int64      // current spill offset
+}
+
+// align returns a rounded up to t's alignment
+func align(a int64, t *types.Type) int64 {
+	return alignTo(a, int(t.Align))
+}
+
+// alignTo returns a rounded up to t, where t must be 0 or a power of 2.
+func alignTo(a int64, t int) int64 {
+	if t == 0 {
+		return a
+	}
+	return types.Rnd(a, int64(t))
+}
+
+// stackSlot returns a stack offset for a param or result of the
+// specified type.
+func (state *assignState) stackSlot(t *types.Type) int64 {
+	rv := align(state.stackOffset, t)
+	state.stackOffset = rv + t.Width
+	return rv
+}
+
+// allocateRegs returns an ordered list of register indices for a parameter or result
+// that we've just determined to be register-assignable. The number of registers
+// needed is assumed to be stored in state.pUsed.
+func (state *assignState) allocateRegs(regs []RegIndex, t *types.Type) []RegIndex {
+	if t.Width == 0 {
+		return regs
+	}
+	ri := state.rUsed.intRegs
+	rf := state.rUsed.floatRegs
+	if t.IsScalar() || t.IsPtrShaped() {
+		if t.IsComplex() {
+			regs = append(regs, RegIndex(rf+state.rTotal.intRegs), RegIndex(rf+1+state.rTotal.intRegs))
+			rf += 2
+		} else if t.IsFloat() {
+			regs = append(regs, RegIndex(rf+state.rTotal.intRegs))
+			rf += 1
+		} else {
+			n := (int(t.Size()) + types.RegSize - 1) / types.RegSize
+			for i := 0; i < n; i++ { // looking ahead to really big integers
+				regs = append(regs, RegIndex(ri))
+				ri += 1
+			}
+		}
+		state.rUsed.intRegs = ri
+		state.rUsed.floatRegs = rf
+		return regs
+	} else {
+		typ := t.Kind()
+		switch typ {
+		case types.TARRAY:
+			for i := int64(0); i < t.NumElem(); i++ {
+				regs = state.allocateRegs(regs, t.Elem())
+			}
+			return regs
+		case types.TSTRUCT:
+			for _, f := range t.FieldSlice() {
+				regs = state.allocateRegs(regs, f.Type)
+			}
+			return regs
+		case types.TSLICE:
+			return state.allocateRegs(regs, synthSlice)
+		case types.TSTRING:
+			return state.allocateRegs(regs, synthString)
+		case types.TINTER:
+			return state.allocateRegs(regs, synthIface)
+		}
+	}
+	base.Fatalf("was not expecting type %s", t)
+	panic("unreachable")
+}
+
+// regAllocate creates a register ABIParamAssignment object for a param
+// or result with the specified type, as a final step (this assumes
+// that all of the safety/suitability analysis is complete).
+func (state *assignState) regAllocate(t *types.Type, name types.Object, isReturn bool) ABIParamAssignment {
+	spillLoc := int64(-1)
+	if !isReturn {
+		// Spill for register-resident t must be aligned for storage of a t.
+		spillLoc = align(state.spillOffset, t)
+		state.spillOffset = spillLoc + t.Size()
+	}
+	return ABIParamAssignment{
+		Type:      t,
+		Name:      name,
+		Registers: state.allocateRegs([]RegIndex{}, t),
+		offset:    int32(spillLoc),
+	}
+}
+
+// stackAllocate creates a stack memory ABIParamAssignment object for
+// a param or result with the specified type, as a final step (this
+// assumes that all of the safety/suitability analysis is complete).
+func (state *assignState) stackAllocate(t *types.Type, name types.Object) ABIParamAssignment {
+	return ABIParamAssignment{
+		Type:   t,
+		Name:   name,
+		offset: int32(state.stackSlot(t)),
+	}
+}
+
+// intUsed returns the number of integer registers consumed
+// at a given point within an assignment stage.
+func (state *assignState) intUsed() int {
+	return state.rUsed.intRegs + state.pUsed.intRegs
+}
+
+// floatUsed returns the number of floating point registers consumed at
+// a given point within an assignment stage.
+func (state *assignState) floatUsed() int {
+	return state.rUsed.floatRegs + state.pUsed.floatRegs
+}
+
+// regassignIntegral examines a param/result of integral type 't' to
+// determines whether it can be register-assigned. Returns TRUE if we
+// can register allocate, FALSE otherwise (and updates state
+// accordingly).
+func (state *assignState) regassignIntegral(t *types.Type) bool {
+	regsNeeded := int(types.Rnd(t.Width, int64(types.PtrSize)) / int64(types.PtrSize))
+	if t.IsComplex() {
+		regsNeeded = 2
+	}
+
+	// Floating point and complex.
+	if t.IsFloat() || t.IsComplex() {
+		if regsNeeded+state.floatUsed() > state.rTotal.floatRegs {
+			// not enough regs
+			return false
+		}
+		state.pUsed.floatRegs += regsNeeded
+		return true
+	}
+
+	// Non-floating point
+	if regsNeeded+state.intUsed() > state.rTotal.intRegs {
+		// not enough regs
+		return false
+	}
+	state.pUsed.intRegs += regsNeeded
+	return true
+}
+
+// regassignArray processes an array type (or array component within some
+// other enclosing type) to determine if it can be register assigned.
+// Returns TRUE if we can register allocate, FALSE otherwise.
+func (state *assignState) regassignArray(t *types.Type) bool {
+
+	nel := t.NumElem()
+	if nel == 0 {
+		return true
+	}
+	if nel > 1 {
+		// Not an array of length 1: stack assign
+		return false
+	}
+	// Visit element
+	return state.regassign(t.Elem())
+}
+
+// regassignStruct processes a struct type (or struct component within
+// some other enclosing type) to determine if it can be register
+// assigned. Returns TRUE if we can register allocate, FALSE otherwise.
+func (state *assignState) regassignStruct(t *types.Type) bool {
+	for _, field := range t.FieldSlice() {
+		if !state.regassign(field.Type) {
+			return false
+		}
+	}
+	return true
+}
+
+// synthOnce ensures that we only create the synth* fake types once.
+var synthOnce sync.Once
+
+// synthSlice, synthString, and syncIface are synthesized struct types
+// meant to capture the underlying implementations of string/slice/interface.
+var synthSlice *types.Type
+var synthString *types.Type
+var synthIface *types.Type
+
+// setup performs setup for the register assignment utilities, manufacturing
+// a small set of synthesized types that we'll need along the way.
+func setup() {
+	synthOnce.Do(func() {
+		fname := types.BuiltinPkg.Lookup
+		nxp := src.NoXPos
+		unsp := types.Types[types.TUNSAFEPTR]
+		ui := types.Types[types.TUINTPTR]
+		synthSlice = types.NewStruct(types.NoPkg, []*types.Field{
+			types.NewField(nxp, fname("ptr"), unsp),
+			types.NewField(nxp, fname("len"), ui),
+			types.NewField(nxp, fname("cap"), ui),
+		})
+		synthString = types.NewStruct(types.NoPkg, []*types.Field{
+			types.NewField(nxp, fname("data"), unsp),
+			types.NewField(nxp, fname("len"), ui),
+		})
+		synthIface = types.NewStruct(types.NoPkg, []*types.Field{
+			types.NewField(nxp, fname("f1"), unsp),
+			types.NewField(nxp, fname("f2"), unsp),
+		})
+	})
+}
+
+// regassign examines a given param type (or component within some
+// composite) to determine if it can be register assigned.  Returns
+// TRUE if we can register allocate, FALSE otherwise.
+func (state *assignState) regassign(pt *types.Type) bool {
+	typ := pt.Kind()
+	if pt.IsScalar() || pt.IsPtrShaped() {
+		return state.regassignIntegral(pt)
+	}
+	switch typ {
+	case types.TARRAY:
+		return state.regassignArray(pt)
+	case types.TSTRUCT:
+		return state.regassignStruct(pt)
+	case types.TSLICE:
+		return state.regassignStruct(synthSlice)
+	case types.TSTRING:
+		return state.regassignStruct(synthString)
+	case types.TINTER:
+		return state.regassignStruct(synthIface)
+	default:
+		base.Fatalf("not expected")
+		panic("unreachable")
+	}
+}
+
+// assignParamOrReturn processes a given receiver, param, or result
+// of field f to determine whether it can be register assigned.
+// The result of the analysis is recorded in the result
+// ABIParamResultInfo held in 'state'.
+func (state *assignState) assignParamOrReturn(pt *types.Type, n types.Object, isReturn bool) ABIParamAssignment {
+	state.pUsed = RegAmounts{}
+	if pt.Width == types.BADWIDTH {
+		base.Fatalf("should never happen")
+		panic("unreachable")
+	} else if pt.Width == 0 {
+		return state.stackAllocate(pt, n)
+	} else if state.regassign(pt) {
+		return state.regAllocate(pt, n, isReturn)
+	} else {
+		return state.stackAllocate(pt, n)
+	}
+}
+
+// ComputePadding returns a list of "post element" padding values in
+// the case where we have a structure being passed in registers. Give
+// a param assignment corresponding to a struct, it returns a list of
+// contaning padding values for each field, e.g. the Kth element in
+// the list is the amount of padding between field K and the following
+// field. For things that are not struct (or structs without padding)
+// it returns a list of zeros. Example:
+//
+// type small struct {
+//   x uint16
+//   y uint8
+//   z int32
+//   w int32
+// }
+//
+// For this struct we would return a list [0, 1, 0, 0], meaning that
+// we have one byte of padding after the second field, and no bytes of
+// padding after any of the other fields. Input parameter "storage"
+// is with enough capacity to accommodate padding elements for
+// the architected register set in question.
+func (pa *ABIParamAssignment) ComputePadding(storage []uint64) []uint64 {
+	nr := len(pa.Registers)
+	padding := storage[:nr]
+	for i := 0; i < nr; i++ {
+		padding[i] = 0
+	}
+	if pa.Type.Kind() != types.TSTRUCT || nr == 0 {
+		return padding
+	}
+	types := make([]*types.Type, 0, nr)
+	types = appendParamTypes(types, pa.Type)
+	if len(types) != nr {
+		panic("internal error")
+	}
+	off := int64(0)
+	for idx, t := range types {
+		ts := t.Size()
+		off += int64(ts)
+		if idx < len(types)-1 {
+			noff := align(off, types[idx+1])
+			if noff != off {
+				padding[idx] = uint64(noff - off)
+			}
+		}
+	}
+	return padding
+}
diff --git a/src/cmd/compile/internal/amd64/galign.go b/src/cmd/compile/internal/amd64/galign.go
index af58440..2785aa0 100644
--- a/src/cmd/compile/internal/amd64/galign.go
+++ b/src/cmd/compile/internal/amd64/galign.go
@@ -5,13 +5,13 @@
 package amd64
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/ssagen"
 	"cmd/internal/obj/x86"
 )
 
 var leaptr = x86.ALEAQ
 
-func Init(arch *gc.Arch) {
+func Init(arch *ssagen.ArchInfo) {
 	arch.LinkArch = &x86.Linkamd64
 	arch.REGSP = x86.REGSP
 	arch.MAXWIDTH = 1 << 50
@@ -23,4 +23,6 @@
 	arch.SSAMarkMoves = ssaMarkMoves
 	arch.SSAGenValue = ssaGenValue
 	arch.SSAGenBlock = ssaGenBlock
+	arch.LoadRegResults = loadRegResults
+	arch.SpillArgReg = spillArgReg
 }
diff --git a/src/cmd/compile/internal/amd64/ggen.go b/src/cmd/compile/internal/amd64/ggen.go
index 0c1456f..1484ad5 100644
--- a/src/cmd/compile/internal/amd64/ggen.go
+++ b/src/cmd/compile/internal/amd64/ggen.go
@@ -5,22 +5,25 @@
 package amd64
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/x86"
-	"cmd/internal/objabi"
+	"internal/buildcfg"
 )
 
 // no floating point in note handlers on Plan 9
-var isPlan9 = objabi.GOOS == "plan9"
+var isPlan9 = buildcfg.GOOS == "plan9"
 
 // 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
+	dzBlockSize = 23 // size of instructions in a single block
+	dzMovSize   = 5  // size of single MOV instruction w/ offset
 	dzLeaqSize  = 4  // size of single LEAQ instruction
 	dzClearStep = 16 // number of bytes cleared by each MOV instruction
 
@@ -51,77 +54,101 @@
 	return -dzClearStep * (dzBlockLen - tailSteps)
 }
 
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Prog {
 	const (
-		ax = 1 << iota
-		x0
+		r13 = 1 << iota // if R13 is already zeroed.
+		x15             // if X15 is already zeroed. Note: in new ABI, X15 is always zero.
 	)
 
 	if cnt == 0 {
 		return p
 	}
 
-	if cnt%int64(gc.Widthreg) != 0 {
+	if cnt%int64(types.RegSize) != 0 {
 		// should only happen with nacl
-		if cnt%int64(gc.Widthptr) != 0 {
-			gc.Fatalf("zerorange count not a multiple of widthptr %d", cnt)
+		if cnt%int64(types.PtrSize) != 0 {
+			base.Fatalf("zerorange count not a multiple of widthptr %d", cnt)
 		}
-		if *state&ax == 0 {
-			p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
-			*state |= ax
+		if *state&r13 == 0 {
+			p = pp.Append(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_R13, 0)
+			*state |= r13
 		}
-		p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off)
-		off += int64(gc.Widthptr)
-		cnt -= int64(gc.Widthptr)
+		p = pp.Append(p, x86.AMOVL, obj.TYPE_REG, x86.REG_R13, 0, obj.TYPE_MEM, x86.REG_SP, off)
+		off += int64(types.PtrSize)
+		cnt -= int64(types.PtrSize)
 	}
 
 	if cnt == 8 {
-		if *state&ax == 0 {
-			p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
-			*state |= ax
+		if *state&r13 == 0 {
+			p = pp.Append(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_R13, 0)
+			*state |= r13
 		}
-		p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off)
-	} else if !isPlan9 && cnt <= int64(8*gc.Widthreg) {
-		if *state&x0 == 0 {
-			p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
-			*state |= x0
+		p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_R13, 0, obj.TYPE_MEM, x86.REG_SP, off)
+	} else if !isPlan9 && cnt <= int64(8*types.RegSize) {
+		if !buildcfg.Experiment.RegabiG && *state&x15 == 0 {
+			p = pp.Append(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X15, 0, obj.TYPE_REG, x86.REG_X15, 0)
+			*state |= x15
 		}
 
 		for i := int64(0); i < cnt/16; i++ {
-			p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, off+i*16)
+			p = pp.Append(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X15, 0, obj.TYPE_MEM, x86.REG_SP, off+i*16)
 		}
 
 		if cnt%16 != 0 {
-			p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, off+cnt-int64(16))
+			p = pp.Append(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X15, 0, obj.TYPE_MEM, x86.REG_SP, off+cnt-int64(16))
 		}
-	} else if !isPlan9 && (cnt <= int64(128*gc.Widthreg)) {
-		if *state&x0 == 0 {
-			p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
-			*state |= x0
+	} else if !isPlan9 && (cnt <= int64(128*types.RegSize)) {
+		if !buildcfg.Experiment.RegabiG && *state&x15 == 0 {
+			p = pp.Append(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X15, 0, obj.TYPE_REG, x86.REG_X15, 0)
+			*state |= x15
 		}
-		p = pp.Appendpp(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off+dzDI(cnt), obj.TYPE_REG, x86.REG_DI, 0)
-		p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, dzOff(cnt))
-		p.To.Sym = gc.Duffzero
-
+		// Save DI to r12. With the amd64 Go register abi, DI can contain
+		// an incoming parameter, whereas R12 is always scratch.
+		p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_DI, 0, obj.TYPE_REG, x86.REG_R12, 0)
+		// Emit duffzero call
+		p = pp.Append(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off+dzDI(cnt), obj.TYPE_REG, x86.REG_DI, 0)
+		p = pp.Append(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, dzOff(cnt))
+		p.To.Sym = ir.Syms.Duffzero
 		if cnt%16 != 0 {
-			p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_DI, -int64(8))
+			p = pp.Append(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X15, 0, obj.TYPE_MEM, x86.REG_DI, -int64(8))
 		}
+		// Restore DI from r12
+		p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_R12, 0, obj.TYPE_REG, x86.REG_DI, 0)
+
 	} else {
-		if *state&ax == 0 {
-			p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
-			*state |= ax
-		}
+		// When the register ABI is in effect, at this point in the
+		// prolog we may have live values in all of RAX,RDI,RCX. Save
+		// them off to registers before the REPSTOSQ below, then
+		// restore. Note that R12 and R13 are always available as
+		// scratch regs; here we also use R15 (this is safe to do
+		// since there won't be any globals accessed in the prolog).
+		// See rewriteToUseGot() in obj6.go for more on r15 use.
 
-		p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, cnt/int64(gc.Widthreg), obj.TYPE_REG, x86.REG_CX, 0)
-		p = pp.Appendpp(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
-		p = pp.Appendpp(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
-		p = pp.Appendpp(p, x86.ASTOSQ, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
+		// Save rax/rdi/rcx
+		p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_DI, 0, obj.TYPE_REG, x86.REG_R12, 0)
+		p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_REG, x86.REG_R13, 0)
+		p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_CX, 0, obj.TYPE_REG, x86.REG_R15, 0)
+
+		// Set up the REPSTOSQ and kick it off.
+		p = pp.Append(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
+		p = pp.Append(p, x86.AMOVQ, obj.TYPE_CONST, 0, cnt/int64(types.RegSize), obj.TYPE_REG, x86.REG_CX, 0)
+		p = pp.Append(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
+		p = pp.Append(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
+		p = pp.Append(p, x86.ASTOSQ, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
+
+		// Restore rax/rdi/rcx
+		p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_R12, 0, obj.TYPE_REG, x86.REG_DI, 0)
+		p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_R13, 0, obj.TYPE_REG, x86.REG_AX, 0)
+		p = pp.Append(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_R15, 0, obj.TYPE_REG, x86.REG_CX, 0)
+
+		// Record the fact that r13 is no longer zero.
+		*state &= ^uint32(r13)
 	}
 
 	return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
 	// This is a hardware nop (1-byte 0x90) instruction,
 	// even though we describe it as an explicit XCHGL here.
 	// Particularly, this does not zero the high 32 bits
diff --git a/src/cmd/compile/internal/amd64/ssa.go b/src/cmd/compile/internal/amd64/ssa.go
index 5ff05a0..ca5f36e 100644
--- a/src/cmd/compile/internal/amd64/ssa.go
+++ b/src/cmd/compile/internal/amd64/ssa.go
@@ -6,18 +6,22 @@
 
 import (
 	"fmt"
+	"internal/buildcfg"
 	"math"
 
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/logopt"
+	"cmd/compile/internal/objw"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/x86"
 )
 
 // markMoves marks any MOVXconst ops that need to avoid clobbering flags.
-func ssaMarkMoves(s *gc.SSAGenState, b *ssa.Block) {
+func ssaMarkMoves(s *ssagen.State, b *ssa.Block) {
 	flive := b.FlagsLiveAtEnd
 	for _, c := range b.ControlValues() {
 		flive = c.Type.IsFlags() || flive
@@ -110,7 +114,7 @@
 //     dest := dest(To) op src(From)
 // and also returns the created obj.Prog so it
 // may be further adjusted (offset, scale, etc).
-func opregreg(s *gc.SSAGenState, op obj.As, dest, src int16) *obj.Prog {
+func opregreg(s *ssagen.State, op obj.As, dest, src int16) *obj.Prog {
 	p := s.Prog(op)
 	p.From.Type = obj.TYPE_REG
 	p.To.Type = obj.TYPE_REG
@@ -164,16 +168,41 @@
 	return off, adj
 }
 
-func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
+func getgFromTLS(s *ssagen.State, r int16) {
+	// See the comments in cmd/internal/obj/x86/obj6.go
+	// near CanUse1InsnTLS for a detailed explanation of these instructions.
+	if x86.CanUse1InsnTLS(base.Ctxt) {
+		// MOVQ (TLS), r
+		p := s.Prog(x86.AMOVQ)
+		p.From.Type = obj.TYPE_MEM
+		p.From.Reg = x86.REG_TLS
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = r
+	} else {
+		// MOVQ TLS, r
+		// MOVQ (r)(TLS*1), r
+		p := s.Prog(x86.AMOVQ)
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = x86.REG_TLS
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = r
+		q := s.Prog(x86.AMOVQ)
+		q.From.Type = obj.TYPE_MEM
+		q.From.Reg = r
+		q.From.Index = x86.REG_TLS
+		q.From.Scale = 1
+		q.To.Type = obj.TYPE_REG
+		q.To.Reg = r
+	}
+}
+
+func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 	switch v.Op {
 	case ssa.OpAMD64VFMADD231SD:
 		p := s.Prog(v.Op.Asm())
 		p.From = obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[2].Reg()}
 		p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[1].Reg()})
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
+		p.SetFrom3Reg(v.Args[1].Reg())
 	case ssa.OpAMD64ADDQ, ssa.OpAMD64ADDL:
 		r := v.Reg()
 		r1 := v.Args[0].Reg()
@@ -223,11 +252,16 @@
 		ssa.OpAMD64BTSL, ssa.OpAMD64BTSQ,
 		ssa.OpAMD64BTCL, ssa.OpAMD64BTCQ,
 		ssa.OpAMD64BTRL, ssa.OpAMD64BTRQ:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
-		opregreg(s, v.Op.Asm(), r, v.Args[1].Reg())
+		opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
+
+	case ssa.OpAMD64SHRDQ, ssa.OpAMD64SHLDQ:
+		p := s.Prog(v.Op.Asm())
+		lo, hi, bits := v.Args[0].Reg(), v.Args[1].Reg(), v.Args[2].Reg()
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = bits
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = lo
+		p.SetFrom3Reg(hi)
 
 	case ssa.OpAMD64DIVQU, ssa.OpAMD64DIVLU, ssa.OpAMD64DIVWU:
 		// Arg[0] (the dividend) is in AX.
@@ -370,20 +404,16 @@
 		// compute (x+y)/2 unsigned.
 		// Do a 64-bit add, the overflow goes into the carry.
 		// Shift right once and pull the carry back into the 63rd bit.
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		p := s.Prog(x86.AADDQ)
 		p.From.Type = obj.TYPE_REG
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
+		p.To.Reg = v.Reg()
 		p.From.Reg = v.Args[1].Reg()
 		p = s.Prog(x86.ARCRQ)
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = 1
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
+		p.To.Reg = v.Reg()
 
 	case ssa.OpAMD64ADDQcarry, ssa.OpAMD64ADCQ:
 		r := v.Reg0()
@@ -499,21 +529,13 @@
 		ssa.OpAMD64CMOVQCS, ssa.OpAMD64CMOVLCS, ssa.OpAMD64CMOVWCS,
 		ssa.OpAMD64CMOVQGTF, ssa.OpAMD64CMOVLGTF, ssa.OpAMD64CMOVWGTF,
 		ssa.OpAMD64CMOVQGEF, ssa.OpAMD64CMOVLGEF, ssa.OpAMD64CMOVWGEF:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
+		p.To.Reg = v.Reg()
 
 	case ssa.OpAMD64CMOVQNEF, ssa.OpAMD64CMOVLNEF, ssa.OpAMD64CMOVWNEF:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		// Flag condition: ^ZERO || PARITY
 		// Generate:
 		//   CMOV*NE  SRC,DST
@@ -522,7 +544,7 @@
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
+		p.To.Reg = v.Reg()
 		var q *obj.Prog
 		if v.Op == ssa.OpAMD64CMOVQNEF {
 			q = s.Prog(x86.ACMOVQPS)
@@ -534,14 +556,9 @@
 		q.From.Type = obj.TYPE_REG
 		q.From.Reg = v.Args[1].Reg()
 		q.To.Type = obj.TYPE_REG
-		q.To.Reg = r
+		q.To.Reg = v.Reg()
 
 	case ssa.OpAMD64CMOVQEQF, ssa.OpAMD64CMOVLEQF, ssa.OpAMD64CMOVWEQF:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
-
 		// Flag condition: ZERO && !PARITY
 		// Generate:
 		//   MOV      SRC,AX
@@ -558,7 +575,7 @@
 		}
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
-		p.From.Reg = r
+		p.From.Reg = v.Reg()
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = x86.REG_AX
 		var q *obj.Prog
@@ -572,7 +589,7 @@
 		q.From.Type = obj.TYPE_REG
 		q.From.Reg = x86.REG_AX
 		q.To.Type = obj.TYPE_REG
-		q.To.Reg = r
+		q.To.Reg = v.Reg()
 
 	case ssa.OpAMD64MULQconst, ssa.OpAMD64MULLconst:
 		r := v.Reg()
@@ -581,7 +598,7 @@
 		p.From.Offset = v.AuxInt
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[0].Reg()})
+		p.SetFrom3Reg(v.Args[0].Reg())
 
 	case ssa.OpAMD64SUBQconst, ssa.OpAMD64SUBLconst,
 		ssa.OpAMD64ANDQconst, ssa.OpAMD64ANDLconst,
@@ -591,15 +608,11 @@
 		ssa.OpAMD64SHRQconst, ssa.OpAMD64SHRLconst, ssa.OpAMD64SHRWconst, ssa.OpAMD64SHRBconst,
 		ssa.OpAMD64SARQconst, ssa.OpAMD64SARLconst, ssa.OpAMD64SARWconst, ssa.OpAMD64SARBconst,
 		ssa.OpAMD64ROLQconst, ssa.OpAMD64ROLLconst, ssa.OpAMD64ROLWconst, ssa.OpAMD64ROLBconst:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		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 = r
+		p.To.Reg = v.Reg()
 	case ssa.OpAMD64SBBQcarrymask, ssa.OpAMD64SBBLcarrymask:
 		r := v.Reg()
 		p := s.Prog(v.Op.Asm())
@@ -630,12 +643,12 @@
 			p.To.Type = obj.TYPE_REG
 			p.To.Reg = o
 		}
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 	case ssa.OpAMD64LEAQ, ssa.OpAMD64LEAL, ssa.OpAMD64LEAW:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpAMD64CMPQ, ssa.OpAMD64CMPL, ssa.OpAMD64CMPW, ssa.OpAMD64CMPB,
@@ -671,7 +684,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Args[1].Reg()
 	case ssa.OpAMD64CMPQconstload, ssa.OpAMD64CMPLconstload, ssa.OpAMD64CMPWconstload, ssa.OpAMD64CMPBconstload:
@@ -679,22 +692,22 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux2(&p.From, v, sc.Off())
+		ssagen.AddAux2(&p.From, v, sc.Off64())
 		p.To.Type = obj.TYPE_CONST
-		p.To.Offset = sc.Val()
+		p.To.Offset = sc.Val64()
 	case ssa.OpAMD64CMPQloadidx8, ssa.OpAMD64CMPQloadidx1, ssa.OpAMD64CMPLloadidx4, ssa.OpAMD64CMPLloadidx1, ssa.OpAMD64CMPWloadidx2, ssa.OpAMD64CMPWloadidx1, ssa.OpAMD64CMPBloadidx1:
 		p := s.Prog(v.Op.Asm())
 		memIdx(&p.From, v)
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Args[2].Reg()
 	case ssa.OpAMD64CMPQconstloadidx8, ssa.OpAMD64CMPQconstloadidx1, ssa.OpAMD64CMPLconstloadidx4, ssa.OpAMD64CMPLconstloadidx1, ssa.OpAMD64CMPWconstloadidx2, ssa.OpAMD64CMPWconstloadidx1, ssa.OpAMD64CMPBconstloadidx1:
 		sc := v.AuxValAndOff()
 		p := s.Prog(v.Op.Asm())
 		memIdx(&p.From, v)
-		gc.AddAux2(&p.From, v, sc.Off())
+		ssagen.AddAux2(&p.From, v, sc.Off64())
 		p.To.Type = obj.TYPE_CONST
-		p.To.Offset = sc.Val()
+		p.To.Offset = sc.Val64()
 	case ssa.OpAMD64MOVLconst, ssa.OpAMD64MOVQconst:
 		x := v.Reg()
 
@@ -732,18 +745,17 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpAMD64MOVBloadidx1, ssa.OpAMD64MOVWloadidx1, ssa.OpAMD64MOVLloadidx1, ssa.OpAMD64MOVQloadidx1, ssa.OpAMD64MOVSSloadidx1, ssa.OpAMD64MOVSDloadidx1,
 		ssa.OpAMD64MOVQloadidx8, ssa.OpAMD64MOVSDloadidx8, ssa.OpAMD64MOVLloadidx8, ssa.OpAMD64MOVLloadidx4, ssa.OpAMD64MOVSSloadidx4, ssa.OpAMD64MOVWloadidx2:
 		p := s.Prog(v.Op.Asm())
 		memIdx(&p.From, v)
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpAMD64MOVQstore, ssa.OpAMD64MOVSSstore, ssa.OpAMD64MOVSDstore, ssa.OpAMD64MOVLstore, ssa.OpAMD64MOVWstore, ssa.OpAMD64MOVBstore, ssa.OpAMD64MOVOstore,
-		ssa.OpAMD64BTCQmodify, ssa.OpAMD64BTCLmodify, ssa.OpAMD64BTRQmodify, ssa.OpAMD64BTRLmodify, ssa.OpAMD64BTSQmodify, ssa.OpAMD64BTSLmodify,
 		ssa.OpAMD64ADDQmodify, ssa.OpAMD64SUBQmodify, ssa.OpAMD64ANDQmodify, ssa.OpAMD64ORQmodify, ssa.OpAMD64XORQmodify,
 		ssa.OpAMD64ADDLmodify, ssa.OpAMD64SUBLmodify, ssa.OpAMD64ANDLmodify, ssa.OpAMD64ORLmodify, ssa.OpAMD64XORLmodify:
 		p := s.Prog(v.Op.Asm())
@@ -751,7 +763,7 @@
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpAMD64MOVBstoreidx1, ssa.OpAMD64MOVWstoreidx1, ssa.OpAMD64MOVLstoreidx1, ssa.OpAMD64MOVQstoreidx1, ssa.OpAMD64MOVSSstoreidx1, ssa.OpAMD64MOVSDstoreidx1,
 		ssa.OpAMD64MOVQstoreidx8, ssa.OpAMD64MOVSDstoreidx8, ssa.OpAMD64MOVLstoreidx8, ssa.OpAMD64MOVSSstoreidx4, ssa.OpAMD64MOVLstoreidx4, ssa.OpAMD64MOVWstoreidx2,
 		ssa.OpAMD64ADDLmodifyidx1, ssa.OpAMD64ADDLmodifyidx4, ssa.OpAMD64ADDLmodifyidx8, ssa.OpAMD64ADDQmodifyidx1, ssa.OpAMD64ADDQmodifyidx8,
@@ -763,10 +775,10 @@
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[2].Reg()
 		memIdx(&p.To, v)
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpAMD64ADDQconstmodify, ssa.OpAMD64ADDLconstmodify:
 		sc := v.AuxValAndOff()
-		off := sc.Off()
+		off := sc.Off64()
 		val := sc.Val()
 		if val == 1 || val == -1 {
 			var asm obj.As
@@ -786,31 +798,41 @@
 			p := s.Prog(asm)
 			p.To.Type = obj.TYPE_MEM
 			p.To.Reg = v.Args[0].Reg()
-			gc.AddAux2(&p.To, v, off)
+			ssagen.AddAux2(&p.To, v, off)
 			break
 		}
 		fallthrough
 	case ssa.OpAMD64ANDQconstmodify, ssa.OpAMD64ANDLconstmodify, ssa.OpAMD64ORQconstmodify, ssa.OpAMD64ORLconstmodify,
-		ssa.OpAMD64BTCQconstmodify, ssa.OpAMD64BTCLconstmodify, ssa.OpAMD64BTSQconstmodify, ssa.OpAMD64BTSLconstmodify,
-		ssa.OpAMD64BTRQconstmodify, ssa.OpAMD64BTRLconstmodify, ssa.OpAMD64XORQconstmodify, ssa.OpAMD64XORLconstmodify:
+		ssa.OpAMD64XORQconstmodify, ssa.OpAMD64XORLconstmodify:
 		sc := v.AuxValAndOff()
-		off := sc.Off()
-		val := sc.Val()
+		off := sc.Off64()
+		val := sc.Val64()
 		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)
+		ssagen.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
 		sc := v.AuxValAndOff()
-		p.From.Offset = sc.Val()
+		p.From.Offset = sc.Val64()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux2(&p.To, v, sc.Off())
+		ssagen.AddAux2(&p.To, v, sc.Off64())
+	case ssa.OpAMD64MOVOstorezero:
+		if !buildcfg.Experiment.RegabiG || s.ABI != obj.ABIInternal {
+			// zero X15 manually
+			opregreg(s, x86.AXORPS, x86.REG_X15, x86.REG_X15)
+		}
+		p := s.Prog(v.Op.Asm())
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = x86.REG_X15
+		p.To.Type = obj.TYPE_MEM
+		p.To.Reg = v.Args[0].Reg()
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpAMD64MOVQstoreconstidx1, ssa.OpAMD64MOVQstoreconstidx8, ssa.OpAMD64MOVLstoreconstidx1, ssa.OpAMD64MOVLstoreconstidx4, ssa.OpAMD64MOVWstoreconstidx1, ssa.OpAMD64MOVWstoreconstidx2, ssa.OpAMD64MOVBstoreconstidx1,
 		ssa.OpAMD64ADDLconstmodifyidx1, ssa.OpAMD64ADDLconstmodifyidx4, ssa.OpAMD64ADDLconstmodifyidx8, ssa.OpAMD64ADDQconstmodifyidx1, ssa.OpAMD64ADDQconstmodifyidx8,
 		ssa.OpAMD64ANDLconstmodifyidx1, ssa.OpAMD64ANDLconstmodifyidx4, ssa.OpAMD64ANDLconstmodifyidx8, ssa.OpAMD64ANDQconstmodifyidx1, ssa.OpAMD64ANDQconstmodifyidx8,
@@ -819,7 +841,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_CONST
 		sc := v.AuxValAndOff()
-		p.From.Offset = sc.Val()
+		p.From.Offset = sc.Val64()
 		switch {
 		case p.As == x86.AADDQ && p.From.Offset == 1:
 			p.As = x86.AINCQ
@@ -835,7 +857,7 @@
 			p.From.Type = obj.TYPE_NONE
 		}
 		memIdx(&p.To, v)
-		gc.AddAux2(&p.To, v, sc.Off())
+		ssagen.AddAux2(&p.To, v, sc.Off64())
 	case ssa.OpAMD64MOVLQSX, ssa.OpAMD64MOVWQSX, ssa.OpAMD64MOVBQSX, ssa.OpAMD64MOVLQZX, ssa.OpAMD64MOVWQZX, ssa.OpAMD64MOVBQZX,
 		ssa.OpAMD64CVTTSS2SL, ssa.OpAMD64CVTTSD2SL, ssa.OpAMD64CVTTSS2SQ, ssa.OpAMD64CVTTSD2SQ,
 		ssa.OpAMD64CVTSS2SD, ssa.OpAMD64CVTSD2SS:
@@ -865,12 +887,9 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[1].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 	case ssa.OpAMD64ADDLloadidx1, ssa.OpAMD64ADDLloadidx4, ssa.OpAMD64ADDLloadidx8, ssa.OpAMD64ADDQloadidx1, ssa.OpAMD64ADDQloadidx8,
 		ssa.OpAMD64SUBLloadidx1, ssa.OpAMD64SUBLloadidx4, ssa.OpAMD64SUBLloadidx8, ssa.OpAMD64SUBQloadidx1, ssa.OpAMD64SUBQloadidx8,
 		ssa.OpAMD64ANDLloadidx1, ssa.OpAMD64ANDLloadidx4, ssa.OpAMD64ANDLloadidx8, ssa.OpAMD64ANDQloadidx1, ssa.OpAMD64ANDQloadidx8,
@@ -891,13 +910,14 @@
 		p.From.Reg = r
 		p.From.Index = i
 
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 	case ssa.OpAMD64DUFFZERO:
+		if !buildcfg.Experiment.RegabiG || s.ABI != obj.ABIInternal {
+			// zero X15 manually
+			opregreg(s, x86.AXORPS, x86.REG_X15, x86.REG_X15)
+		}
 		off := duffStart(v.AuxInt)
 		adj := duffAdj(v.AuxInt)
 		var p *obj.Prog
@@ -911,18 +931,12 @@
 		}
 		p = s.Prog(obj.ADUFFZERO)
 		p.To.Type = obj.TYPE_ADDR
-		p.To.Sym = gc.Duffzero
+		p.To.Sym = ir.Syms.Duffzero
 		p.To.Offset = off
-	case ssa.OpAMD64MOVOconst:
-		if v.AuxInt != 0 {
-			v.Fatalf("MOVOconst can only do constant=0")
-		}
-		r := v.Reg()
-		opregreg(s, x86.AXORPS, r, r)
 	case ssa.OpAMD64DUFFCOPY:
 		p := s.Prog(obj.ADUFFCOPY)
 		p.To.Type = obj.TYPE_ADDR
-		p.To.Sym = gc.Duffcopy
+		p.To.Sym = ir.Syms.Duffcopy
 		if v.AuxInt%16 != 0 {
 			v.Fatalf("bad DUFFCOPY AuxInt %v", v.AuxInt)
 		}
@@ -949,7 +963,7 @@
 			return
 		}
 		p := s.Prog(loadByType(v.Type))
-		gc.AddrAuto(&p.From, v.Args[0])
+		ssagen.AddrAuto(&p.From, v.Args[0])
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 
@@ -961,44 +975,48 @@
 		p := s.Prog(storeByType(v.Type))
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddrAuto(&p.To, v)
+		ssagen.AddrAuto(&p.To, v)
 	case ssa.OpAMD64LoweredHasCPUFeature:
 		p := s.Prog(x86.AMOVBQZX)
 		p.From.Type = obj.TYPE_MEM
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
+	case ssa.OpArgIntReg, ssa.OpArgFloatReg:
+		// The assembler needs to wrap the entry safepoint/stack growth code with spill/unspill
+		// The loop only runs once.
+		for _, ap := range v.Block.Func.RegArgs {
+			// Pass the spill/unspill information along to the assembler, offset by size of return PC pushed on stack.
+			addr := ssagen.SpillSlotAddr(ap, x86.REG_SP, v.Block.Func.Config.PtrSize)
+			s.FuncInfo().AddSpill(
+				obj.RegSpill{Reg: ap.Reg, Addr: addr, Unspill: loadByType(ap.Type), Spill: storeByType(ap.Type)})
+		}
+		v.Block.Func.RegArgs = nil
+		ssagen.CheckArgReg(v)
 	case ssa.OpAMD64LoweredGetClosurePtr:
 		// Closure pointer is DX.
-		gc.CheckLoweredGetClosurePtr(v)
+		ssagen.CheckLoweredGetClosurePtr(v)
 	case ssa.OpAMD64LoweredGetG:
-		r := v.Reg()
-		// See the comments in cmd/internal/obj/x86/obj6.go
-		// near CanUse1InsnTLS for a detailed explanation of these instructions.
-		if x86.CanUse1InsnTLS(gc.Ctxt) {
-			// MOVQ (TLS), r
-			p := s.Prog(x86.AMOVQ)
-			p.From.Type = obj.TYPE_MEM
-			p.From.Reg = x86.REG_TLS
-			p.To.Type = obj.TYPE_REG
-			p.To.Reg = r
-		} else {
-			// MOVQ TLS, r
-			// MOVQ (r)(TLS*1), r
-			p := s.Prog(x86.AMOVQ)
-			p.From.Type = obj.TYPE_REG
-			p.From.Reg = x86.REG_TLS
-			p.To.Type = obj.TYPE_REG
-			p.To.Reg = r
-			q := s.Prog(x86.AMOVQ)
-			q.From.Type = obj.TYPE_MEM
-			q.From.Reg = r
-			q.From.Index = x86.REG_TLS
-			q.From.Scale = 1
-			q.To.Type = obj.TYPE_REG
-			q.To.Reg = r
+		if buildcfg.Experiment.RegabiG && s.ABI == obj.ABIInternal {
+			v.Fatalf("LoweredGetG should not appear in ABIInternal")
 		}
-	case ssa.OpAMD64CALLstatic, ssa.OpAMD64CALLclosure, ssa.OpAMD64CALLinter:
+		r := v.Reg()
+		getgFromTLS(s, r)
+	case ssa.OpAMD64CALLstatic:
+		if buildcfg.Experiment.RegabiG && s.ABI == obj.ABI0 && v.Aux.(*ssa.AuxCall).Fn.ABI() == obj.ABIInternal {
+			// zeroing X15 when entering ABIInternal from ABI0
+			opregreg(s, x86.AXORPS, x86.REG_X15, x86.REG_X15)
+			// set G register from TLS
+			getgFromTLS(s, x86.REG_R14)
+		}
+		s.Call(v)
+		if buildcfg.Experiment.RegabiG && s.ABI == obj.ABIInternal && v.Aux.(*ssa.AuxCall).Fn.ABI() == obj.ABI0 {
+			// zeroing X15 when entering ABIInternal from ABI0
+			opregreg(s, x86.AXORPS, x86.REG_X15, x86.REG_X15)
+			// set G register from TLS
+			getgFromTLS(s, x86.REG_R14)
+		}
+	case ssa.OpAMD64CALLclosure, ssa.OpAMD64CALLinter:
 		s.Call(v)
 
 	case ssa.OpAMD64LoweredGetCallerPC:
@@ -1012,12 +1030,12 @@
 	case ssa.OpAMD64LoweredGetCallerSP:
 		// caller's SP is the address of the first arg
 		mov := x86.AMOVQ
-		if gc.Widthptr == 4 {
+		if types.PtrSize == 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.Offset = -base.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()
@@ -1027,36 +1045,28 @@
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
 		// arg0 is in DI. Set sym to match where regalloc put arg1.
-		p.To.Sym = gc.GCWriteBarrierReg[v.Args[1].Reg()]
+		p.To.Sym = ssagen.GCWriteBarrierReg[v.Args[1].Reg()]
 
 	case ssa.OpAMD64LoweredPanicBoundsA, ssa.OpAMD64LoweredPanicBoundsB, ssa.OpAMD64LoweredPanicBoundsC:
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
-		s.UseArgs(int64(2 * gc.Widthptr)) // space used in callee args area by assembly stubs
+		p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
+		s.UseArgs(int64(2 * types.PtrSize)) // space used in callee args area by assembly stubs
 
 	case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL,
 		ssa.OpAMD64BSWAPQ, ssa.OpAMD64BSWAPL,
 		ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		p := s.Prog(v.Op.Asm())
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
+		p.To.Reg = v.Reg()
 
 	case ssa.OpAMD64NEGLflags:
-		r := v.Reg0()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		p := s.Prog(v.Op.Asm())
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
+		p.To.Reg = v.Reg0()
 
-	case ssa.OpAMD64BSFQ, ssa.OpAMD64BSRQ, ssa.OpAMD64BSFL, ssa.OpAMD64BSRL, ssa.OpAMD64SQRTSD:
+	case ssa.OpAMD64BSFQ, ssa.OpAMD64BSRQ, ssa.OpAMD64BSFL, ssa.OpAMD64BSRL, ssa.OpAMD64SQRTSD, ssa.OpAMD64SQRTSS:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
@@ -1064,7 +1074,7 @@
 		switch v.Op {
 		case ssa.OpAMD64BSFQ, ssa.OpAMD64BSRQ:
 			p.To.Reg = v.Reg0()
-		case ssa.OpAMD64BSFL, ssa.OpAMD64BSRL, ssa.OpAMD64SQRTSD:
+		case ssa.OpAMD64BSFL, ssa.OpAMD64BSRL, ssa.OpAMD64SQRTSD, ssa.OpAMD64SQRTSS:
 			p.To.Reg = v.Reg()
 		}
 	case ssa.OpAMD64ROUNDSD:
@@ -1076,7 +1086,7 @@
 		}
 		p.From.Offset = val
 		p.From.Type = obj.TYPE_CONST
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[0].Reg()})
+		p.SetFrom3Reg(v.Args[0].Reg())
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpAMD64POPCNTQ, ssa.OpAMD64POPCNTL:
@@ -1115,7 +1125,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 
 	case ssa.OpAMD64SETNEF:
 		p := s.Prog(v.Op.Asm())
@@ -1164,39 +1174,31 @@
 		if logopt.Enabled() {
 			logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
 		}
-		if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
-			gc.Warnl(v.Pos, "generated nil check")
+		if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
+			base.WarnfAt(v.Pos, "generated nil check")
 		}
 	case ssa.OpAMD64MOVBatomicload, ssa.OpAMD64MOVLatomicload, ssa.OpAMD64MOVQatomicload:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg0()
 	case ssa.OpAMD64XCHGB, ssa.OpAMD64XCHGL, ssa.OpAMD64XCHGQ:
-		r := v.Reg0()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output[0] not in same register %s", v.LongString())
-		}
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
-		p.From.Reg = r
+		p.From.Reg = v.Reg0()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[1].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpAMD64XADDLlock, ssa.OpAMD64XADDQlock:
-		r := v.Reg0()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output[0] not in same register %s", v.LongString())
-		}
 		s.Prog(x86.ALOCK)
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
-		p.From.Reg = r
+		p.From.Reg = v.Reg0()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[1].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpAMD64CMPXCHGLlock, ssa.OpAMD64CMPXCHGQlock:
 		if v.Args[1].Reg() != x86.REG_AX {
 			v.Fatalf("input[1] not in AX %s", v.LongString())
@@ -1207,7 +1209,7 @@
 		p.From.Reg = v.Args[2].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 		p = s.Prog(x86.ASETEQ)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg0()
@@ -1218,21 +1220,28 @@
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpClobber:
 		p := s.Prog(x86.AMOVL)
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = 0xdeaddead
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = x86.REG_SP
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 		p = s.Prog(x86.AMOVL)
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = 0xdeaddead
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = x86.REG_SP
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 		p.To.Offset += 4
+	case ssa.OpClobberReg:
+		x := uint64(0xdeaddeaddeaddead)
+		p := s.Prog(x86.AMOVQ)
+		p.From.Type = obj.TYPE_CONST
+		p.From.Offset = int64(x)
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
 	default:
 		v.Fatalf("genValue not implemented: %s", v.LongString())
 	}
@@ -1257,22 +1266,22 @@
 	ssa.BlockAMD64NAN: {x86.AJPS, x86.AJPC},
 }
 
-var eqfJumps = [2][2]gc.IndexJump{
+var eqfJumps = [2][2]ssagen.IndexJump{
 	{{Jump: x86.AJNE, Index: 1}, {Jump: x86.AJPS, Index: 1}}, // next == b.Succs[0]
 	{{Jump: x86.AJNE, Index: 1}, {Jump: x86.AJPC, Index: 0}}, // next == b.Succs[1]
 }
-var nefJumps = [2][2]gc.IndexJump{
+var nefJumps = [2][2]ssagen.IndexJump{
 	{{Jump: x86.AJNE, Index: 0}, {Jump: x86.AJPC, Index: 1}}, // next == b.Succs[0]
 	{{Jump: x86.AJNE, Index: 0}, {Jump: x86.AJPS, Index: 0}}, // next == b.Succs[1]
 }
 
-func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
+func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
 	switch b.Kind {
 	case ssa.BlockPlain:
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 	case ssa.BlockDefer:
 		// defer returns in rax:
@@ -1285,16 +1294,22 @@
 		p.To.Reg = x86.REG_AX
 		p = s.Prog(x86.AJNE)
 		p.To.Type = obj.TYPE_BRANCH
-		s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+		s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[1].Block()})
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 	case ssa.BlockExit:
 	case ssa.BlockRet:
 		s.Prog(obj.ARET)
 	case ssa.BlockRetJmp:
+		if buildcfg.Experiment.RegabiG && s.ABI == obj.ABI0 && b.Aux.(*obj.LSym).ABI() == obj.ABIInternal {
+			// zeroing X15 when entering ABIInternal from ABI0
+			opregreg(s, x86.AXORPS, x86.REG_X15, x86.REG_X15)
+			// set G register from TLS
+			getgFromTLS(s, x86.REG_R14)
+		}
 		p := s.Prog(obj.ARET)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
@@ -1332,3 +1347,27 @@
 		b.Fatalf("branch not implemented: %s", b.LongString())
 	}
 }
+
+func loadRegResults(s *ssagen.State, f *ssa.Func) {
+	for _, o := range f.OwnAux.ABIInfo().OutParams() {
+		n := o.Name.(*ir.Name)
+		rts, offs := o.RegisterTypesAndOffsets()
+		for i := range o.Registers {
+			p := s.Prog(loadByType(rts[i]))
+			p.From.Type = obj.TYPE_MEM
+			p.From.Name = obj.NAME_AUTO
+			p.From.Sym = n.Linksym()
+			p.From.Offset = n.FrameOffset() + offs[i]
+			p.To.Type = obj.TYPE_REG
+			p.To.Reg = ssa.ObjRegForAbiReg(o.Registers[i], f.Config)
+		}
+	}
+}
+
+func spillArgReg(pp *objw.Progs, p *obj.Prog, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog {
+	p = pp.Append(p, storeByType(t), obj.TYPE_REG, reg, 0, obj.TYPE_MEM, 0, n.FrameOffset()+off)
+	p.To.Name = obj.NAME_PARAM
+	p.To.Sym = n.Linksym()
+	p.Pos = p.Pos.WithNotStmt()
+	return p
+}
diff --git a/src/cmd/compile/internal/arm/galign.go b/src/cmd/compile/internal/arm/galign.go
index 20e2f43..d685002 100644
--- a/src/cmd/compile/internal/arm/galign.go
+++ b/src/cmd/compile/internal/arm/galign.go
@@ -5,22 +5,22 @@
 package arm
 
 import (
-	"cmd/compile/internal/gc"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/internal/obj/arm"
-	"cmd/internal/objabi"
+	"internal/buildcfg"
 )
 
-func Init(arch *gc.Arch) {
+func Init(arch *ssagen.ArchInfo) {
 	arch.LinkArch = &arm.Linkarm
 	arch.REGSP = arm.REGSP
 	arch.MAXWIDTH = (1 << 32) - 1
-	arch.SoftFloat = objabi.GOARM == 5
+	arch.SoftFloat = buildcfg.GOARM == 5
 	arch.ZeroRange = zerorange
 	arch.Ginsnop = ginsnop
 	arch.Ginsnopdefer = ginsnop
 
-	arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
+	arch.SSAMarkMoves = func(s *ssagen.State, b *ssa.Block) {}
 	arch.SSAGenValue = ssaGenValue
 	arch.SSAGenBlock = ssaGenBlock
 }
diff --git a/src/cmd/compile/internal/arm/ggen.go b/src/cmd/compile/internal/arm/ggen.go
index bd8d7ff..f2c6763 100644
--- a/src/cmd/compile/internal/arm/ggen.go
+++ b/src/cmd/compile/internal/arm/ggen.go
@@ -5,49 +5,51 @@
 package arm
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/arm"
 )
 
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, r0 *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, r0 *uint32) *obj.Prog {
 	if cnt == 0 {
 		return p
 	}
 	if *r0 == 0 {
-		p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, arm.REG_R0, 0)
+		p = pp.Append(p, arm.AMOVW, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, arm.REG_R0, 0)
 		*r0 = 1
 	}
 
-	if cnt < int64(4*gc.Widthptr) {
-		for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
-			p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REGSP, 4+off+i)
+	if cnt < int64(4*types.PtrSize) {
+		for i := int64(0); i < cnt; i += int64(types.PtrSize) {
+			p = pp.Append(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REGSP, 4+off+i)
 		}
-	} else if cnt <= int64(128*gc.Widthptr) {
-		p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, 4+off, obj.TYPE_REG, arm.REG_R1, 0)
+	} else if cnt <= int64(128*types.PtrSize) {
+		p = pp.Append(p, arm.AADD, obj.TYPE_CONST, 0, 4+off, obj.TYPE_REG, arm.REG_R1, 0)
 		p.Reg = arm.REGSP
-		p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
+		p = pp.Append(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.Sym = ir.Syms.Duffzero
+		p.To.Offset = 4 * (128 - cnt/int64(types.PtrSize))
 	} else {
-		p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, 4+off, obj.TYPE_REG, arm.REG_R1, 0)
+		p = pp.Append(p, arm.AADD, obj.TYPE_CONST, 0, 4+off, obj.TYPE_REG, arm.REG_R1, 0)
 		p.Reg = arm.REGSP
-		p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, arm.REG_R2, 0)
+		p = pp.Append(p, arm.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, arm.REG_R2, 0)
 		p.Reg = arm.REG_R1
-		p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REG_R1, 4)
+		p = pp.Append(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REG_R1, 4)
 		p1 := p
 		p.Scond |= arm.C_PBIT
-		p = pp.Appendpp(p, arm.ACMP, obj.TYPE_REG, arm.REG_R1, 0, obj.TYPE_NONE, 0, 0)
+		p = pp.Append(p, arm.ACMP, obj.TYPE_REG, arm.REG_R1, 0, obj.TYPE_NONE, 0, 0)
 		p.Reg = arm.REG_R2
-		p = pp.Appendpp(p, arm.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
-		gc.Patch(p, p1)
+		p = pp.Append(p, arm.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
+		p.To.SetTarget(p1)
 	}
 
 	return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
 	p := pp.Prog(arm.AAND)
 	p.From.Type = obj.TYPE_REG
 	p.From.Reg = arm.REG_R0
diff --git a/src/cmd/compile/internal/arm/ssa.go b/src/cmd/compile/internal/arm/ssa.go
index 765a771..4b083ce 100644
--- a/src/cmd/compile/internal/arm/ssa.go
+++ b/src/cmd/compile/internal/arm/ssa.go
@@ -6,16 +6,18 @@
 
 import (
 	"fmt"
+	"internal/buildcfg"
 	"math"
 	"math/bits"
 
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/logopt"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/arm"
-	"cmd/internal/objabi"
 )
 
 // loadByType returns the load instruction of the given type.
@@ -91,7 +93,7 @@
 }
 
 // genshift generates a Prog for r = r0 op (r1 shifted by n)
-func genshift(s *gc.SSAGenState, as obj.As, r0, r1, r int16, typ int64, n int64) *obj.Prog {
+func genshift(s *ssagen.State, as obj.As, r0, r1, r int16, typ int64, n int64) *obj.Prog {
 	p := s.Prog(as)
 	p.From.Type = obj.TYPE_SHIFT
 	p.From.Offset = int64(makeshift(r1, typ, n))
@@ -109,7 +111,7 @@
 }
 
 // genregshift generates a Prog for r = r0 op (r1 shifted by r2)
-func genregshift(s *gc.SSAGenState, as obj.As, r0, r1, r2, r int16, typ int64) *obj.Prog {
+func genregshift(s *ssagen.State, as obj.As, r0, r1, r2, r int16, typ int64) *obj.Prog {
 	p := s.Prog(as)
 	p.From.Type = obj.TYPE_SHIFT
 	p.From.Offset = int64(makeregshift(r1, typ, r2))
@@ -143,7 +145,7 @@
 	return 0xffffffff, 0
 }
 
-func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
+func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 	switch v.Op {
 	case ssa.OpCopy, ssa.OpARMMOVWreg:
 		if v.Type.IsMemory() {
@@ -171,9 +173,6 @@
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = y
 	case ssa.OpARMMOVWnop:
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		// nothing to do
 	case ssa.OpLoadReg:
 		if v.Type.IsFlags() {
@@ -181,7 +180,7 @@
 			return
 		}
 		p := s.Prog(loadByType(v.Type))
-		gc.AddrAuto(&p.From, v.Args[0])
+		ssagen.AddrAuto(&p.From, v.Args[0])
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpStoreReg:
@@ -192,7 +191,7 @@
 		p := s.Prog(storeByType(v.Type))
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddrAuto(&p.To, v)
+		ssagen.AddrAuto(&p.To, v)
 	case ssa.OpARMADD,
 		ssa.OpARMADC,
 		ssa.OpARMSUB,
@@ -280,14 +279,14 @@
 		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.SetFrom3Const(v.AuxInt & 0xff)
 		p.Reg = v.Args[0].Reg()
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpARMANDconst, ssa.OpARMBICconst:
 		// try to optimize ANDconst and BICconst to BFC, which saves bytes and ticks
 		// BFC is only available on ARMv7, and its result and source are in the same register
-		if objabi.GOARM == 7 && v.Reg() == v.Args[0].Reg() {
+		if buildcfg.GOARM == 7 && v.Reg() == v.Args[0].Reg() {
 			var val uint32
 			if v.Op == ssa.OpARMANDconst {
 				val = ^uint32(v.AuxInt)
@@ -300,7 +299,7 @@
 				p := s.Prog(arm.ABFC)
 				p.From.Type = obj.TYPE_CONST
 				p.From.Offset = int64(width)
-				p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: int64(lsb)})
+				p.SetFrom3Const(int64(lsb))
 				p.To.Type = obj.TYPE_REG
 				p.To.Reg = v.Reg()
 				break
@@ -543,10 +542,10 @@
 			v.Fatalf("aux is of unknown type %T", v.Aux)
 		case *obj.LSym:
 			wantreg = "SB"
-			gc.AddAux(&p.From, v)
-		case *gc.Node:
+			ssagen.AddAux(&p.From, v)
+		case *ir.Name:
 			wantreg = "SP"
-			gc.AddAux(&p.From, v)
+			ssagen.AddAux(&p.From, v)
 		case nil:
 			// No sym, just MOVW $off(SP), R
 			wantreg = "SP"
@@ -566,7 +565,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpARMMOVBstore,
@@ -579,7 +578,7 @@
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpARMMOVWloadidx, ssa.OpARMMOVBUloadidx, ssa.OpARMMOVBloadidx, ssa.OpARMMOVHUloadidx, ssa.OpARMMOVHloadidx:
 		// this is just shift 0 bits
 		fallthrough
@@ -644,7 +643,7 @@
 			default:
 			}
 		}
-		if objabi.GOARM >= 6 {
+		if buildcfg.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
@@ -655,6 +654,7 @@
 		ssa.OpARMREV,
 		ssa.OpARMREV16,
 		ssa.OpARMRBIT,
+		ssa.OpARMSQRTF,
 		ssa.OpARMSQRTD,
 		ssa.OpARMNEGF,
 		ssa.OpARMNEGD,
@@ -700,7 +700,7 @@
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.Udiv
+		p.To.Sym = ir.Syms.Udiv
 	case ssa.OpARMLoweredWB:
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
@@ -710,39 +710,39 @@
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+		p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
 		s.UseArgs(8) // space used in callee args area by assembly stubs
 	case ssa.OpARMLoweredPanicExtendA, ssa.OpARMLoweredPanicExtendB, ssa.OpARMLoweredPanicExtendC:
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.ExtendCheckFunc[v.AuxInt]
+		p.To.Sym = ssagen.ExtendCheckFunc[v.AuxInt]
 		s.UseArgs(12) // space used in callee args area by assembly stubs
 	case ssa.OpARMDUFFZERO:
 		p := s.Prog(obj.ADUFFZERO)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.Duffzero
+		p.To.Sym = ir.Syms.Duffzero
 		p.To.Offset = v.AuxInt
 	case ssa.OpARMDUFFCOPY:
 		p := s.Prog(obj.ADUFFCOPY)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.Duffcopy
+		p.To.Sym = ir.Syms.Duffcopy
 		p.To.Offset = v.AuxInt
 	case ssa.OpARMLoweredNilCheck:
 		// Issue a load which will fault if arg is nil.
 		p := s.Prog(arm.AMOVB)
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = arm.REGTMP
 		if logopt.Enabled() {
 			logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
 		}
-		if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
-			gc.Warnl(v.Pos, "generated nil check")
+		if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
+			base.WarnfAt(v.Pos, "generated nil check")
 		}
 	case ssa.OpARMLoweredZero:
 		// MOVW.P	Rarg2, 4(R1)
@@ -777,7 +777,7 @@
 		p2.Reg = arm.REG_R1
 		p3 := s.Prog(arm.ABLE)
 		p3.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 	case ssa.OpARMLoweredMove:
 		// MOVW.P	4(R1), Rtmp
 		// MOVW.P	Rtmp, 4(R2)
@@ -818,7 +818,7 @@
 		p3.Reg = arm.REG_R1
 		p4 := s.Prog(arm.ABLE)
 		p4.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p4, p)
+		p4.To.SetTarget(p)
 	case ssa.OpARMEqual,
 		ssa.OpARMNotEqual,
 		ssa.OpARMLessThan,
@@ -844,12 +844,12 @@
 		p.To.Reg = v.Reg()
 	case ssa.OpARMLoweredGetClosurePtr:
 		// Closure pointer is R7 (arm.REGCTXT).
-		gc.CheckLoweredGetClosurePtr(v)
+		ssagen.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.Offset = -base.Ctxt.FixedFrameSize()
 		p.From.Name = obj.NAME_PARAM
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
@@ -861,7 +861,7 @@
 		v.Fatalf("FlagConstant op should never make it to codegen %v", v.LongString())
 	case ssa.OpARMInvertFlags:
 		v.Fatalf("InvertFlags should never make it to codegen %v", v.LongString())
-	case ssa.OpClobber:
+	case ssa.OpClobber, ssa.OpClobberReg:
 		// TODO: implement for clobberdead experiment. Nop is ok for now.
 	default:
 		v.Fatalf("genValue not implemented: %s", v.LongString())
@@ -899,24 +899,24 @@
 }
 
 // To model a 'LEnoov' ('<=' without overflow checking) branching
-var leJumps = [2][2]gc.IndexJump{
+var leJumps = [2][2]ssagen.IndexJump{
 	{{Jump: arm.ABEQ, Index: 0}, {Jump: arm.ABPL, Index: 1}}, // next == b.Succs[0]
 	{{Jump: arm.ABMI, Index: 0}, {Jump: arm.ABEQ, Index: 0}}, // next == b.Succs[1]
 }
 
 // To model a 'GTnoov' ('>' without overflow checking) branching
-var gtJumps = [2][2]gc.IndexJump{
+var gtJumps = [2][2]ssagen.IndexJump{
 	{{Jump: arm.ABMI, Index: 1}, {Jump: arm.ABEQ, Index: 1}}, // next == b.Succs[0]
 	{{Jump: arm.ABEQ, Index: 1}, {Jump: arm.ABPL, Index: 0}}, // next == b.Succs[1]
 }
 
-func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
+func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
 	switch b.Kind {
 	case ssa.BlockPlain:
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 
 	case ssa.BlockDefer:
@@ -929,11 +929,11 @@
 		p.Reg = arm.REG_R0
 		p = s.Prog(arm.ABNE)
 		p.To.Type = obj.TYPE_BRANCH
-		s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+		s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[1].Block()})
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 
 	case ssa.BlockExit:
diff --git a/src/cmd/compile/internal/arm64/galign.go b/src/cmd/compile/internal/arm64/galign.go
index 40d6e17..d3db37e 100644
--- a/src/cmd/compile/internal/arm64/galign.go
+++ b/src/cmd/compile/internal/arm64/galign.go
@@ -5,12 +5,12 @@
 package arm64
 
 import (
-	"cmd/compile/internal/gc"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/internal/obj/arm64"
 )
 
-func Init(arch *gc.Arch) {
+func Init(arch *ssagen.ArchInfo) {
 	arch.LinkArch = &arm64.Linkarm64
 	arch.REGSP = arm64.REGSP
 	arch.MAXWIDTH = 1 << 50
@@ -20,7 +20,7 @@
 	arch.Ginsnop = ginsnop
 	arch.Ginsnopdefer = ginsnop
 
-	arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
+	arch.SSAMarkMoves = func(s *ssagen.State, b *ssa.Block) {}
 	arch.SSAGenValue = ssaGenValue
 	arch.SSAGenBlock = ssaGenBlock
 }
diff --git a/src/cmd/compile/internal/arm64/ggen.go b/src/cmd/compile/internal/arm64/ggen.go
index f3fec03..89be496 100644
--- a/src/cmd/compile/internal/arm64/ggen.go
+++ b/src/cmd/compile/internal/arm64/ggen.go
@@ -5,13 +5,15 @@
 package arm64
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/arm64"
-	"cmd/internal/objabi"
+	"internal/buildcfg"
 )
 
-var darwin = objabi.GOOS == "darwin" || objabi.GOOS == "ios"
+var darwin = buildcfg.GOOS == "darwin" || buildcfg.GOOS == "ios"
 
 func padframe(frame int64) int64 {
 	// arm64 requires that the frame size (not counting saved FP&LR)
@@ -22,52 +24,52 @@
 	return frame
 }
 
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
 	if cnt == 0 {
 		return p
 	}
-	if cnt < int64(4*gc.Widthptr) {
-		for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
-			p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off+i)
+	if cnt < int64(4*types.PtrSize) {
+		for i := int64(0); i < cnt; i += int64(types.PtrSize) {
+			p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off+i)
 		}
-	} else if cnt <= int64(128*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)
+	} else if cnt <= int64(128*types.PtrSize) && !darwin { // darwin ld64 cannot handle BR26 reloc with non-zero addend
+		if cnt%(2*int64(types.PtrSize)) != 0 {
+			p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off)
+			off += int64(types.PtrSize)
+			cnt -= int64(types.PtrSize)
 		}
-		p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REG_R20, 0)
-		p = pp.Appendpp(p, arm64.AADD, obj.TYPE_CONST, 0, 8+off, obj.TYPE_REG, arm64.REG_R20, 0)
+		p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REG_R20, 0)
+		p = pp.Append(p, arm64.AADD, obj.TYPE_CONST, 0, 8+off, obj.TYPE_REG, arm64.REG_R20, 0)
 		p.Reg = arm64.REG_R20
-		p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
+		p = pp.Append(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 * (64 - cnt/(2*int64(gc.Widthptr)))
+		p.To.Sym = ir.Syms.Duffzero
+		p.To.Offset = 4 * (64 - cnt/(2*int64(types.PtrSize)))
 	} else {
 		// Not using REGTMP, so this is async preemptible (async preemption clobbers REGTMP).
 		// We are at the function entry, where no register is live, so it is okay to clobber
 		// other registers
 		const rtmp = arm64.REG_R20
-		p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, rtmp, 0)
-		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_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT1, 0)
+		p = pp.Append(p, arm64.AMOVD, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, rtmp, 0)
+		p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
+		p = pp.Append(p, arm64.AADD, obj.TYPE_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT1, 0)
 		p.Reg = arm64.REGRT1
-		p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, rtmp, 0)
-		p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT2, 0)
+		p = pp.Append(p, arm64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, rtmp, 0)
+		p = pp.Append(p, arm64.AADD, obj.TYPE_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT2, 0)
 		p.Reg = arm64.REGRT1
-		p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGRT1, int64(gc.Widthptr))
+		p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGRT1, int64(types.PtrSize))
 		p.Scond = arm64.C_XPRE
 		p1 := p
-		p = pp.Appendpp(p, arm64.ACMP, obj.TYPE_REG, arm64.REGRT1, 0, obj.TYPE_NONE, 0, 0)
+		p = pp.Append(p, arm64.ACMP, obj.TYPE_REG, arm64.REGRT1, 0, obj.TYPE_NONE, 0, 0)
 		p.Reg = arm64.REGRT2
-		p = pp.Appendpp(p, arm64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
-		gc.Patch(p, p1)
+		p = pp.Append(p, arm64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
+		p.To.SetTarget(p1)
 	}
 
 	return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
 	p := pp.Prog(arm64.AHINT)
 	p.From.Type = obj.TYPE_CONST
 	return p
diff --git a/src/cmd/compile/internal/arm64/ssa.go b/src/cmd/compile/internal/arm64/ssa.go
index 4358851..0c997bc 100644
--- a/src/cmd/compile/internal/arm64/ssa.go
+++ b/src/cmd/compile/internal/arm64/ssa.go
@@ -7,9 +7,11 @@
 import (
 	"math"
 
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/logopt"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/arm64"
@@ -81,7 +83,7 @@
 }
 
 // genshift generates a Prog for r = r0 op (r1 shifted by n)
-func genshift(s *gc.SSAGenState, as obj.As, r0, r1, r int16, typ int64, n int64) *obj.Prog {
+func genshift(s *ssagen.State, as obj.As, r0, r1, r int16, typ int64, n int64) *obj.Prog {
 	p := s.Prog(as)
 	p.From.Type = obj.TYPE_SHIFT
 	p.From.Offset = makeshift(r1, typ, n)
@@ -98,9 +100,11 @@
 	// Reg: base register, Index: (shifted) index register
 	mop := obj.Addr{Type: obj.TYPE_MEM, Reg: v.Args[0].Reg()}
 	switch v.Op {
-	case ssa.OpARM64MOVDloadidx8, ssa.OpARM64MOVDstoreidx8, ssa.OpARM64MOVDstorezeroidx8:
+	case ssa.OpARM64MOVDloadidx8, ssa.OpARM64MOVDstoreidx8, ssa.OpARM64MOVDstorezeroidx8,
+		ssa.OpARM64FMOVDloadidx8, ssa.OpARM64FMOVDstoreidx8:
 		mop.Index = arm64.REG_LSL | 3<<5 | v.Args[1].Reg()&31
-	case ssa.OpARM64MOVWloadidx4, ssa.OpARM64MOVWUloadidx4, ssa.OpARM64MOVWstoreidx4, ssa.OpARM64MOVWstorezeroidx4:
+	case ssa.OpARM64MOVWloadidx4, ssa.OpARM64MOVWUloadidx4, ssa.OpARM64MOVWstoreidx4, ssa.OpARM64MOVWstorezeroidx4,
+		ssa.OpARM64FMOVSloadidx4, ssa.OpARM64FMOVSstoreidx4:
 		mop.Index = arm64.REG_LSL | 2<<5 | v.Args[1].Reg()&31
 	case ssa.OpARM64MOVHloadidx2, ssa.OpARM64MOVHUloadidx2, ssa.OpARM64MOVHstoreidx2, ssa.OpARM64MOVHstorezeroidx2:
 		mop.Index = arm64.REG_LSL | 1<<5 | v.Args[1].Reg()&31
@@ -110,7 +114,7 @@
 	return mop
 }
 
-func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
+func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 	switch v.Op {
 	case ssa.OpCopy, ssa.OpARM64MOVDreg:
 		if v.Type.IsMemory() {
@@ -138,9 +142,6 @@
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = y
 	case ssa.OpARM64MOVDnop:
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		// nothing to do
 	case ssa.OpLoadReg:
 		if v.Type.IsFlags() {
@@ -148,7 +149,7 @@
 			return
 		}
 		p := s.Prog(loadByType(v.Type))
-		gc.AddrAuto(&p.From, v.Args[0])
+		ssagen.AddrAuto(&p.From, v.Args[0])
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpStoreReg:
@@ -159,7 +160,7 @@
 		p := s.Prog(storeByType(v.Type))
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddrAuto(&p.To, v)
+		ssagen.AddrAuto(&p.To, v)
 	case ssa.OpARM64ADD,
 		ssa.OpARM64SUB,
 		ssa.OpARM64AND,
@@ -228,7 +229,7 @@
 		p.Reg = ra
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = rm
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: rn})
+		p.SetFrom3Reg(rn)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = rt
 	case ssa.OpARM64ADDconst,
@@ -291,7 +292,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = v.AuxInt
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[0].Reg()})
+		p.SetFrom3Reg(v.Args[0].Reg())
 		p.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
@@ -393,10 +394,10 @@
 			v.Fatalf("aux is of unknown type %T", v.Aux)
 		case *obj.LSym:
 			wantreg = "SB"
-			gc.AddAux(&p.From, v)
-		case *gc.Node:
+			ssagen.AddAux(&p.From, v)
+		case *ir.Name:
 			wantreg = "SP"
-			gc.AddAux(&p.From, v)
+			ssagen.AddAux(&p.From, v)
 		case nil:
 			// No sym, just MOVD $off(SP), R
 			wantreg = "SP"
@@ -417,7 +418,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpARM64MOVBloadidx,
@@ -433,7 +434,9 @@
 		ssa.OpARM64MOVHUloadidx2,
 		ssa.OpARM64MOVWloadidx4,
 		ssa.OpARM64MOVWUloadidx4,
-		ssa.OpARM64MOVDloadidx8:
+		ssa.OpARM64MOVDloadidx8,
+		ssa.OpARM64FMOVDloadidx8,
+		ssa.OpARM64FMOVSloadidx4:
 		p := s.Prog(v.Op.Asm())
 		p.From = genIndexedOperand(v)
 		p.To.Type = obj.TYPE_REG
@@ -444,7 +447,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg0()
 	case ssa.OpARM64MOVBstore,
@@ -461,7 +464,7 @@
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpARM64MOVBstoreidx,
 		ssa.OpARM64MOVHstoreidx,
 		ssa.OpARM64MOVWstoreidx,
@@ -470,7 +473,9 @@
 		ssa.OpARM64FMOVDstoreidx,
 		ssa.OpARM64MOVHstoreidx2,
 		ssa.OpARM64MOVWstoreidx4,
-		ssa.OpARM64MOVDstoreidx8:
+		ssa.OpARM64FMOVSstoreidx4,
+		ssa.OpARM64MOVDstoreidx8,
+		ssa.OpARM64FMOVDstoreidx8:
 		p := s.Prog(v.Op.Asm())
 		p.To = genIndexedOperand(v)
 		p.From.Type = obj.TYPE_REG
@@ -482,7 +487,7 @@
 		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)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpARM64MOVBstorezero,
 		ssa.OpARM64MOVHstorezero,
 		ssa.OpARM64MOVWstorezero,
@@ -492,7 +497,7 @@
 		p.From.Reg = arm64.REGZERO
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpARM64MOVBstorezeroidx,
 		ssa.OpARM64MOVHstorezeroidx,
 		ssa.OpARM64MOVWstorezeroidx,
@@ -511,20 +516,16 @@
 		p.From.Offset = int64(arm64.REGZERO)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpARM64BFI,
 		ssa.OpARM64BFXIL:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		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.SetFrom3Const(v.AuxInt & 0xff)
 		p.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
+		p.To.Reg = v.Reg()
 	case ssa.OpARM64SBFIZ,
 		ssa.OpARM64SBFX,
 		ssa.OpARM64UBFIZ,
@@ -532,7 +533,7 @@
 		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.SetFrom3Const(v.AuxInt & 0xff)
 		p.Reg = v.Args[0].Reg()
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
@@ -580,7 +581,7 @@
 		p2.From.Type = obj.TYPE_REG
 		p2.From.Reg = arm64.REGTMP
 		p2.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p2, p)
+		p2.To.SetTarget(p)
 	case ssa.OpARM64LoweredAtomicExchange64Variant,
 		ssa.OpARM64LoweredAtomicExchange32Variant:
 		swap := arm64.ASWPALD
@@ -634,7 +635,7 @@
 		p3.From.Type = obj.TYPE_REG
 		p3.From.Reg = arm64.REGTMP
 		p3.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 	case ssa.OpARM64LoweredAtomicAdd64Variant,
 		ssa.OpARM64LoweredAtomicAdd32Variant:
 		// LDADDAL	Rarg1, (Rarg0), Rout
@@ -698,13 +699,13 @@
 		p4.From.Type = obj.TYPE_REG
 		p4.From.Reg = arm64.REGTMP
 		p4.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p4, p)
+		p4.To.SetTarget(p)
 		p5 := s.Prog(arm64.ACSET)
 		p5.From.Type = obj.TYPE_REG // assembler encodes conditional bits in Reg
 		p5.From.Reg = arm64.COND_EQ
 		p5.To.Type = obj.TYPE_REG
 		p5.To.Reg = out
-		gc.Patch(p2, p5)
+		p2.To.SetTarget(p5)
 	case ssa.OpARM64LoweredAtomicCas64Variant,
 		ssa.OpARM64LoweredAtomicCas32Variant:
 		// Rarg0: ptr
@@ -792,7 +793,7 @@
 		p3.From.Type = obj.TYPE_REG
 		p3.From.Reg = arm64.REGTMP
 		p3.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 	case ssa.OpARM64LoweredAtomicAnd8Variant,
 		ssa.OpARM64LoweredAtomicAnd32Variant:
 		atomic_clear := arm64.ALDCLRALW
@@ -892,6 +893,7 @@
 		ssa.OpARM64FMOVSgpfp,
 		ssa.OpARM64FNEGS,
 		ssa.OpARM64FNEGD,
+		ssa.OpARM64FSQRTS,
 		ssa.OpARM64FSQRTD,
 		ssa.OpARM64FCVTZSSW,
 		ssa.OpARM64FCVTZSDW,
@@ -913,6 +915,7 @@
 		ssa.OpARM64FCVTDS,
 		ssa.OpARM64REV,
 		ssa.OpARM64REVW,
+		ssa.OpARM64REV16,
 		ssa.OpARM64REV16W,
 		ssa.OpARM64RBIT,
 		ssa.OpARM64RBITW,
@@ -951,7 +954,21 @@
 		p.From.Type = obj.TYPE_REG // assembler encodes conditional bits in Reg
 		p.From.Reg = condBits[ssa.Op(v.AuxInt)]
 		p.Reg = v.Args[0].Reg()
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: r1})
+		p.SetFrom3Reg(r1)
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
+	case ssa.OpARM64CSINC, ssa.OpARM64CSINV, ssa.OpARM64CSNEG:
+		p := s.Prog(v.Op.Asm())
+		p.From.Type = obj.TYPE_REG // assembler encodes conditional bits in Reg
+		p.From.Reg = condBits[ssa.Op(v.AuxInt)]
+		p.Reg = v.Args[0].Reg()
+		p.SetFrom3Reg(v.Args[1].Reg())
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
+	case ssa.OpARM64CSETM:
+		p := s.Prog(arm64.ACSETM)
+		p.From.Type = obj.TYPE_REG // assembler encodes conditional bits in Reg
+		p.From.Reg = condBits[ssa.Op(v.AuxInt)]
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpARM64DUFFZERO:
@@ -959,7 +976,7 @@
 		p := s.Prog(obj.ADUFFZERO)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.Duffzero
+		p.To.Sym = ir.Syms.Duffzero
 		p.To.Offset = v.AuxInt
 	case ssa.OpARM64LoweredZero:
 		// STP.P	(ZR,ZR), 16(R16)
@@ -980,12 +997,12 @@
 		p2.Reg = arm64.REG_R16
 		p3 := s.Prog(arm64.ABLE)
 		p3.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 	case ssa.OpARM64DUFFCOPY:
 		p := s.Prog(obj.ADUFFCOPY)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.Duffcopy
+		p.To.Sym = ir.Syms.Duffcopy
 		p.To.Offset = v.AuxInt
 	case ssa.OpARM64LoweredMove:
 		// MOVD.P	8(R16), Rtmp
@@ -1013,7 +1030,7 @@
 		p3.Reg = arm64.REG_R16
 		p4 := s.Prog(arm64.ABLE)
 		p4.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p4, p)
+		p4.To.SetTarget(p)
 	case ssa.OpARM64CALLstatic, ssa.OpARM64CALLclosure, ssa.OpARM64CALLinter:
 		s.Call(v)
 	case ssa.OpARM64LoweredWB:
@@ -1025,21 +1042,21 @@
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+		p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
 		s.UseArgs(16) // space used in callee args area by assembly stubs
 	case ssa.OpARM64LoweredNilCheck:
 		// Issue a load which will fault if arg is nil.
 		p := s.Prog(arm64.AMOVB)
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = arm64.REGTMP
 		if logopt.Enabled() {
 			logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
 		}
-		if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Line==1 in generated wrappers
-			gc.Warnl(v.Pos, "generated nil check")
+		if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Line==1 in generated wrappers
+			base.WarnfAt(v.Pos, "generated nil check")
 		}
 	case ssa.OpARM64Equal,
 		ssa.OpARM64NotEqual,
@@ -1067,12 +1084,12 @@
 		p.To.Reg = v.Reg()
 	case ssa.OpARM64LoweredGetClosurePtr:
 		// Closure pointer is R26 (arm64.REGCTXT).
-		gc.CheckLoweredGetClosurePtr(v)
+		ssagen.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.Offset = -base.Ctxt.FixedFrameSize()
 		p.From.Name = obj.NAME_PARAM
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
@@ -1084,7 +1101,7 @@
 		v.Fatalf("FlagConstant op should never make it to codegen %v", v.LongString())
 	case ssa.OpARM64InvertFlags:
 		v.Fatalf("InvertFlags should never make it to codegen %v", v.LongString())
-	case ssa.OpClobber:
+	case ssa.OpClobber, ssa.OpClobberReg:
 		// TODO: implement for clobberdead experiment. Nop is ok for now.
 	default:
 		v.Fatalf("genValue not implemented: %s", v.LongString())
@@ -1142,24 +1159,24 @@
 }
 
 // To model a 'LEnoov' ('<=' without overflow checking) branching
-var leJumps = [2][2]gc.IndexJump{
+var leJumps = [2][2]ssagen.IndexJump{
 	{{Jump: arm64.ABEQ, Index: 0}, {Jump: arm64.ABPL, Index: 1}}, // next == b.Succs[0]
 	{{Jump: arm64.ABMI, Index: 0}, {Jump: arm64.ABEQ, Index: 0}}, // next == b.Succs[1]
 }
 
 // To model a 'GTnoov' ('>' without overflow checking) branching
-var gtJumps = [2][2]gc.IndexJump{
+var gtJumps = [2][2]ssagen.IndexJump{
 	{{Jump: arm64.ABMI, Index: 1}, {Jump: arm64.ABEQ, Index: 1}}, // next == b.Succs[0]
 	{{Jump: arm64.ABEQ, Index: 1}, {Jump: arm64.ABPL, Index: 0}}, // next == b.Succs[1]
 }
 
-func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
+func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
 	switch b.Kind {
 	case ssa.BlockPlain:
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 
 	case ssa.BlockDefer:
@@ -1172,11 +1189,11 @@
 		p.Reg = arm64.REG_R0
 		p = s.Prog(arm64.ABNE)
 		p.To.Type = obj.TYPE_BRANCH
-		s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+		s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[1].Block()})
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 
 	case ssa.BlockExit:
diff --git a/src/cmd/compile/internal/base/base.go b/src/cmd/compile/internal/base/base.go
new file mode 100644
index 0000000..4c2516f
--- /dev/null
+++ b/src/cmd/compile/internal/base/base.go
@@ -0,0 +1,75 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package base
+
+import (
+	"os"
+)
+
+var atExitFuncs []func()
+
+func AtExit(f func()) {
+	atExitFuncs = append(atExitFuncs, f)
+}
+
+func Exit(code int) {
+	for i := len(atExitFuncs) - 1; i >= 0; i-- {
+		f := atExitFuncs[i]
+		atExitFuncs = atExitFuncs[:i]
+		f()
+	}
+	os.Exit(code)
+}
+
+// To enable tracing support (-t flag), set EnableTrace to true.
+const EnableTrace = false
+
+func Compiling(pkgs []string) bool {
+	if Ctxt.Pkgpath != "" {
+		for _, p := range pkgs {
+			if Ctxt.Pkgpath == p {
+				return true
+			}
+		}
+	}
+
+	return false
+}
+
+// The racewalk pass is currently handled in three parts.
+//
+// First, for flag_race, it inserts calls to racefuncenter and
+// racefuncexit at the start and end (respectively) of each
+// function. This is handled below.
+//
+// Second, during buildssa, it inserts appropriate instrumentation
+// calls immediately before each memory load or store. This is handled
+// by the (*state).instrument method in ssa.go, so here we just set
+// the Func.InstrumentBody flag as needed. For background on why this
+// is done during SSA construction rather than a separate SSA pass,
+// see issue #19054.
+//
+// Third we remove calls to racefuncenter and racefuncexit, for leaf
+// functions without instrumented operations. This is done as part of
+// ssa opt pass via special rule.
+
+// TODO(dvyukov): do not instrument initialization as writes:
+// a := make([]int, 10)
+
+// Do not instrument the following packages at all,
+// at best instrumentation would cause infinite recursion.
+var NoInstrumentPkgs = []string{
+	"runtime/internal/atomic",
+	"runtime/internal/sys",
+	"runtime/internal/math",
+	"runtime",
+	"runtime/race",
+	"runtime/msan",
+	"internal/cpu",
+}
+
+// Don't insert racefuncenter/racefuncexit into the following packages.
+// Memory accesses in the packages are either uninteresting or will cause false positives.
+var NoRacePkgs = []string{"sync", "sync/atomic"}
diff --git a/src/cmd/compile/internal/base/debug.go b/src/cmd/compile/internal/base/debug.go
new file mode 100644
index 0000000..71712ab
--- /dev/null
+++ b/src/cmd/compile/internal/base/debug.go
@@ -0,0 +1,189 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Debug arguments, set by -d flag.
+
+package base
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"reflect"
+	"strconv"
+	"strings"
+)
+
+// Debug holds the parsed debugging configuration values.
+var Debug DebugFlags
+
+// DebugFlags defines the debugging configuration values (see var Debug).
+// Each struct field is a different value, named for the lower-case of the field name.
+// Each field must be an int or string and must have a `help` struct tag.
+//
+// The -d option takes a comma-separated list of settings.
+// Each setting is name=value; for ints, name is short for name=1.
+type DebugFlags struct {
+	Append               int    `help:"print information about append compilation"`
+	Checkptr             int    `help:"instrument unsafe pointer conversions"`
+	Closure              int    `help:"print information about closure compilation"`
+	DclStack             int    `help:"run internal dclstack check"`
+	Defer                int    `help:"print information about defer compilation"`
+	DisableNil           int    `help:"disable nil checks"`
+	DumpPtrs             int    `help:"show Node pointers values in dump output"`
+	DwarfInl             int    `help:"print information about DWARF inlined function creation"`
+	Export               int    `help:"print export data"`
+	GCProg               int    `help:"print dump of GC programs"`
+	InlFuncsWithClosures int    `help:"allow functions with closures to be inlined"`
+	Libfuzzer            int    `help:"enable coverage instrumentation for libfuzzer"`
+	LocationLists        int    `help:"print information about DWARF location list creation"`
+	Nil                  int    `help:"print information about nil checks"`
+	NoOpenDefer          int    `help:"disable open-coded defers"`
+	PCTab                string `help:"print named pc-value table"`
+	Panic                int    `help:"show all compiler panics"`
+	Slice                int    `help:"print information about slice compilation"`
+	SoftFloat            int    `help:"force compiler to emit soft-float code"`
+	TypeAssert           int    `help:"print information about type assertion inlining"`
+	TypecheckInl         int    `help:"eager typechecking of inline function bodies"`
+	WB                   int    `help:"print information about write barriers"`
+	ABIWrap              int    `help:"print information about ABI wrapper generation"`
+
+	any bool // set when any of the values have been set
+}
+
+// Any reports whether any of the debug flags have been set.
+func (d *DebugFlags) Any() bool { return d.any }
+
+type debugField struct {
+	name string
+	help string
+	val  interface{} // *int or *string
+}
+
+var debugTab []debugField
+
+func init() {
+	v := reflect.ValueOf(&Debug).Elem()
+	t := v.Type()
+	for i := 0; i < t.NumField(); i++ {
+		f := t.Field(i)
+		if f.Name == "any" {
+			continue
+		}
+		name := strings.ToLower(f.Name)
+		help := f.Tag.Get("help")
+		if help == "" {
+			panic(fmt.Sprintf("base.Debug.%s is missing help text", f.Name))
+		}
+		ptr := v.Field(i).Addr().Interface()
+		switch ptr.(type) {
+		default:
+			panic(fmt.Sprintf("base.Debug.%s has invalid type %v (must be int or string)", f.Name, f.Type))
+		case *int, *string:
+			// ok
+		}
+		debugTab = append(debugTab, debugField{name, help, ptr})
+	}
+}
+
+// DebugSSA is called to set a -d ssa/... option.
+// If nil, those options are reported as invalid options.
+// If DebugSSA returns a non-empty string, that text is reported as a compiler error.
+var DebugSSA func(phase, flag string, val int, valString string) string
+
+// parseDebug parses the -d debug string argument.
+func parseDebug(debugstr string) {
+	// parse -d argument
+	if debugstr == "" {
+		return
+	}
+	Debug.any = true
+Split:
+	for _, name := range strings.Split(debugstr, ",") {
+		if name == "" {
+			continue
+		}
+		// display help about the -d option itself and quit
+		if name == "help" {
+			fmt.Print(debugHelpHeader)
+			maxLen := len("ssa/help")
+			for _, t := range debugTab {
+				if len(t.name) > maxLen {
+					maxLen = len(t.name)
+				}
+			}
+			for _, t := range debugTab {
+				fmt.Printf("\t%-*s\t%s\n", maxLen, t.name, t.help)
+			}
+			// ssa options have their own help
+			fmt.Printf("\t%-*s\t%s\n", maxLen, "ssa/help", "print help about SSA debugging")
+			fmt.Print(debugHelpFooter)
+			os.Exit(0)
+		}
+		val, valstring, haveInt := 1, "", true
+		if i := strings.IndexAny(name, "=:"); i >= 0 {
+			var err error
+			name, valstring = name[:i], name[i+1:]
+			val, err = strconv.Atoi(valstring)
+			if err != nil {
+				val, haveInt = 1, false
+			}
+		}
+		for _, t := range debugTab {
+			if t.name != name {
+				continue
+			}
+			switch vp := t.val.(type) {
+			case nil:
+				// Ignore
+			case *string:
+				*vp = valstring
+			case *int:
+				if !haveInt {
+					log.Fatalf("invalid debug value %v", name)
+				}
+				*vp = val
+			default:
+				panic("bad debugtab type")
+			}
+			continue Split
+		}
+		// special case for ssa for now
+		if DebugSSA != nil && strings.HasPrefix(name, "ssa/") {
+			// expect form ssa/phase/flag
+			// e.g. -d=ssa/generic_cse/time
+			// _ in phase name also matches space
+			phase := name[4:]
+			flag := "debug" // default flag is debug
+			if i := strings.Index(phase, "/"); i >= 0 {
+				flag = phase[i+1:]
+				phase = phase[:i]
+			}
+			err := DebugSSA(phase, flag, val, valstring)
+			if err != "" {
+				log.Fatalf(err)
+			}
+			continue Split
+		}
+		log.Fatalf("unknown debug key -d %s\n", name)
+	}
+}
+
+const debugHelpHeader = `usage: -d arg[,arg]* and arg is <key>[=<value>]
+
+<key> is one of:
+
+`
+
+const debugHelpFooter = `
+<value> is key-specific.
+
+Key "checkptr" supports values:
+	"0": instrumentation disabled
+	"1": conversions involving unsafe.Pointer are instrumented
+	"2": conversions to unsafe.Pointer force heap allocation
+
+Key "pctab" supports values:
+	"pctospadj", "pctofile", "pctoline", "pctoinline", "pctopcdata"
+`
diff --git a/src/cmd/compile/internal/base/flag.go b/src/cmd/compile/internal/base/flag.go
new file mode 100644
index 0000000..42c0c1b
--- /dev/null
+++ b/src/cmd/compile/internal/base/flag.go
@@ -0,0 +1,469 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package base
+
+import (
+	"encoding/json"
+	"flag"
+	"fmt"
+	"internal/buildcfg"
+	"io/ioutil"
+	"log"
+	"os"
+	"reflect"
+	"runtime"
+	"strings"
+
+	"cmd/internal/objabi"
+	"cmd/internal/sys"
+)
+
+func usage() {
+	fmt.Fprintf(os.Stderr, "usage: compile [options] file.go...\n")
+	objabi.Flagprint(os.Stderr)
+	Exit(2)
+}
+
+// Flag holds the parsed command-line flags.
+// See ParseFlag for non-zero defaults.
+var Flag CmdFlags
+
+// A CountFlag is a counting integer flag.
+// It accepts -name=value to set the value directly,
+// but it also accepts -name with no =value to increment the count.
+type CountFlag int
+
+// CmdFlags defines the command-line flags (see var Flag).
+// Each struct field is a different flag, by default named for the lower-case of the field name.
+// If the flag name is a single letter, the default flag name is left upper-case.
+// If the flag name is "Lower" followed by a single letter, the default flag name is the lower-case of the last letter.
+//
+// If this default flag name can't be made right, the `flag` struct tag can be used to replace it,
+// but this should be done only in exceptional circumstances: it helps everyone if the flag name
+// is obvious from the field name when the flag is used elsewhere in the compiler sources.
+// The `flag:"-"` struct tag makes a field invisible to the flag logic and should also be used sparingly.
+//
+// Each field must have a `help` struct tag giving the flag help message.
+//
+// The allowed field types are bool, int, string, pointers to those (for values stored elsewhere),
+// CountFlag (for a counting flag), and func(string) (for a flag that uses special code for parsing).
+type CmdFlags struct {
+	// Single letters
+	B CountFlag    "help:\"disable bounds checking\""
+	C CountFlag    "help:\"disable printing of columns in error messages\""
+	D string       "help:\"set relative `path` for local imports\""
+	E CountFlag    "help:\"debug symbol export\""
+	G CountFlag    "help:\"accept generic code\""
+	I func(string) "help:\"add `directory` to import search path\""
+	K CountFlag    "help:\"debug missing line numbers\""
+	L CountFlag    "help:\"show full file names in error messages\""
+	N CountFlag    "help:\"disable optimizations\""
+	S CountFlag    "help:\"print assembly listing\""
+	// V is added by objabi.AddVersionFlag
+	W CountFlag "help:\"debug parse tree after type checking\""
+
+	LowerC int          "help:\"concurrency during compilation (1 means no concurrency)\""
+	LowerD func(string) "help:\"enable debugging settings; try -d help\""
+	LowerE CountFlag    "help:\"no limit on number of errors reported\""
+	LowerH CountFlag    "help:\"halt on error\""
+	LowerJ CountFlag    "help:\"debug runtime-initialized variables\""
+	LowerL CountFlag    "help:\"disable inlining\""
+	LowerM CountFlag    "help:\"print optimization decisions\""
+	LowerO string       "help:\"write output to `file`\""
+	LowerP *string      "help:\"set expected package import `path`\"" // &Ctxt.Pkgpath, set below
+	LowerR CountFlag    "help:\"debug generated wrappers\""
+	LowerT bool         "help:\"enable tracing for debugging the compiler\""
+	LowerW CountFlag    "help:\"debug type checking\""
+	LowerV *bool        "help:\"increase debug verbosity\""
+
+	// Special characters
+	Percent          int  "flag:\"%\" help:\"debug non-static initializers\""
+	CompilingRuntime bool "flag:\"+\" help:\"compiling runtime\""
+
+	// Longer names
+	AsmHdr             string       "help:\"write assembly header to `file`\""
+	Bench              string       "help:\"append benchmark times to `file`\""
+	BlockProfile       string       "help:\"write block profile to `file`\""
+	BuildID            string       "help:\"record `id` as the build id in the export metadata\""
+	CPUProfile         string       "help:\"write cpu profile to `file`\""
+	Complete           bool         "help:\"compiling complete package (no C or assembly)\""
+	ClobberDead        bool         "help:\"clobber dead stack slots (for debugging)\""
+	ClobberDeadReg     bool         "help:\"clobber dead registers (for debugging)\""
+	Dwarf              bool         "help:\"generate DWARF symbols\""
+	DwarfBASEntries    *bool        "help:\"use base address selection entries in DWARF\""                        // &Ctxt.UseBASEntries, set below
+	DwarfLocationLists *bool        "help:\"add location lists to DWARF in optimized mode\""                      // &Ctxt.Flag_locationlists, set below
+	Dynlink            *bool        "help:\"support references to Go symbols defined in other shared libraries\"" // &Ctxt.Flag_dynlink, set below
+	EmbedCfg           func(string) "help:\"read go:embed configuration from `file`\""
+	GenDwarfInl        int          "help:\"generate DWARF inline info records\"" // 0=disabled, 1=funcs, 2=funcs+formals/locals
+	GoVersion          string       "help:\"required version of the runtime\""
+	ImportCfg          func(string) "help:\"read import configuration from `file`\""
+	ImportMap          func(string) "help:\"add `definition` of the form source=actual to import map\""
+	InstallSuffix      string       "help:\"set pkg directory `suffix`\""
+	JSON               string       "help:\"version,file for JSON compiler/optimizer detail output\""
+	Lang               string       "help:\"Go language version source code expects\""
+	LinkObj            string       "help:\"write linker-specific object to `file`\""
+	LinkShared         *bool        "help:\"generate code that will be linked against Go shared libraries\"" // &Ctxt.Flag_linkshared, set below
+	Live               CountFlag    "help:\"debug liveness analysis\""
+	MSan               bool         "help:\"build code compatible with C/C++ memory sanitizer\""
+	MemProfile         string       "help:\"write memory profile to `file`\""
+	MemProfileRate     int64        "help:\"set runtime.MemProfileRate to `rate`\""
+	MutexProfile       string       "help:\"write mutex profile to `file`\""
+	NoLocalImports     bool         "help:\"reject local (relative) imports\""
+	Pack               bool         "help:\"write to file.a instead of file.o\""
+	Race               bool         "help:\"enable race detector\""
+	Shared             *bool        "help:\"generate code that can be linked into a shared library\"" // &Ctxt.Flag_shared, set below
+	SmallFrames        bool         "help:\"reduce the size limit for stack allocated objects\""      // small stacks, to diagnose GC latency; see golang.org/issue/27732
+	Spectre            string       "help:\"enable spectre mitigations in `list` (all, index, ret)\""
+	Std                bool         "help:\"compiling standard library\""
+	SymABIs            string       "help:\"read symbol ABIs from `file`\""
+	TraceProfile       string       "help:\"write an execution trace to `file`\""
+	TrimPath           string       "help:\"remove `prefix` from recorded source file paths\""
+	WB                 bool         "help:\"enable write barrier\"" // TODO: remove
+
+	// Configuration derived from flags; not a flag itself.
+	Cfg struct {
+		Embed struct { // set by -embedcfg
+			Patterns map[string][]string
+			Files    map[string]string
+		}
+		ImportDirs   []string          // appended to by -I
+		ImportMap    map[string]string // set by -importmap OR -importcfg
+		PackageFile  map[string]string // set by -importcfg; nil means not in use
+		SpectreIndex bool              // set by -spectre=index or -spectre=all
+		// Whether we are adding any sort of code instrumentation, such as
+		// when the race detector is enabled.
+		Instrumenting bool
+	}
+}
+
+// ParseFlags parses the command-line flags into Flag.
+func ParseFlags() {
+	Flag.I = addImportDir
+
+	Flag.LowerC = 1
+	Flag.LowerD = parseDebug
+	Flag.LowerP = &Ctxt.Pkgpath
+	Flag.LowerV = &Ctxt.Debugvlog
+
+	Flag.Dwarf = buildcfg.GOARCH != "wasm"
+	Flag.DwarfBASEntries = &Ctxt.UseBASEntries
+	Flag.DwarfLocationLists = &Ctxt.Flag_locationlists
+	*Flag.DwarfLocationLists = true
+	Flag.Dynlink = &Ctxt.Flag_dynlink
+	Flag.EmbedCfg = readEmbedCfg
+	Flag.GenDwarfInl = 2
+	Flag.ImportCfg = readImportCfg
+	Flag.ImportMap = addImportMap
+	Flag.LinkShared = &Ctxt.Flag_linkshared
+	Flag.Shared = &Ctxt.Flag_shared
+	Flag.WB = true
+	Debug.InlFuncsWithClosures = 1
+
+	Debug.Checkptr = -1 // so we can tell whether it is set explicitly
+
+	Flag.Cfg.ImportMap = make(map[string]string)
+
+	objabi.AddVersionFlag() // -V
+	registerFlags()
+	objabi.Flagparse(usage)
+
+	if Flag.MSan && !sys.MSanSupported(buildcfg.GOOS, buildcfg.GOARCH) {
+		log.Fatalf("%s/%s does not support -msan", buildcfg.GOOS, buildcfg.GOARCH)
+	}
+	if Flag.Race && !sys.RaceDetectorSupported(buildcfg.GOOS, buildcfg.GOARCH) {
+		log.Fatalf("%s/%s does not support -race", buildcfg.GOOS, buildcfg.GOARCH)
+	}
+	if (*Flag.Shared || *Flag.Dynlink || *Flag.LinkShared) && !Ctxt.Arch.InFamily(sys.AMD64, sys.ARM, sys.ARM64, sys.I386, sys.PPC64, sys.RISCV64, sys.S390X) {
+		log.Fatalf("%s/%s does not support -shared", buildcfg.GOOS, buildcfg.GOARCH)
+	}
+	parseSpectre(Flag.Spectre) // left as string for RecordFlags
+
+	Ctxt.Flag_shared = Ctxt.Flag_dynlink || Ctxt.Flag_shared
+	Ctxt.Flag_optimize = Flag.N == 0
+	Ctxt.Debugasm = int(Flag.S)
+
+	if flag.NArg() < 1 {
+		usage()
+	}
+
+	if Flag.GoVersion != "" && Flag.GoVersion != runtime.Version() {
+		fmt.Printf("compile: version %q does not match go tool version %q\n", runtime.Version(), Flag.GoVersion)
+		Exit(2)
+	}
+
+	if Flag.LowerO == "" {
+		p := flag.Arg(0)
+		if i := strings.LastIndex(p, "/"); i >= 0 {
+			p = p[i+1:]
+		}
+		if runtime.GOOS == "windows" {
+			if i := strings.LastIndex(p, `\`); i >= 0 {
+				p = p[i+1:]
+			}
+		}
+		if i := strings.LastIndex(p, "."); i >= 0 {
+			p = p[:i]
+		}
+		suffix := ".o"
+		if Flag.Pack {
+			suffix = ".a"
+		}
+		Flag.LowerO = p + suffix
+	}
+
+	if Flag.Race && Flag.MSan {
+		log.Fatal("cannot use both -race and -msan")
+	}
+	if Flag.Race || Flag.MSan {
+		// -race and -msan imply -d=checkptr for now.
+		if Debug.Checkptr == -1 { // if not set explicitly
+			Debug.Checkptr = 1
+		}
+	}
+
+	if Flag.CompilingRuntime && Flag.N != 0 {
+		log.Fatal("cannot disable optimizations while compiling runtime")
+	}
+	if Flag.LowerC < 1 {
+		log.Fatalf("-c must be at least 1, got %d", Flag.LowerC)
+	}
+	if Flag.LowerC > 1 && !concurrentBackendAllowed() {
+		log.Fatalf("cannot use concurrent backend compilation with provided flags; invoked as %v", os.Args)
+	}
+
+	if Flag.CompilingRuntime {
+		// Runtime can't use -d=checkptr, at least not yet.
+		Debug.Checkptr = 0
+
+		// Fuzzing the runtime isn't interesting either.
+		Debug.Libfuzzer = 0
+	}
+
+	if Debug.Checkptr == -1 { // if not set explicitly
+		Debug.Checkptr = 0
+	}
+
+	// set via a -d flag
+	Ctxt.Debugpcln = Debug.PCTab
+}
+
+// registerFlags adds flag registrations for all the fields in Flag.
+// See the comment on type CmdFlags for the rules.
+func registerFlags() {
+	var (
+		boolType      = reflect.TypeOf(bool(false))
+		intType       = reflect.TypeOf(int(0))
+		stringType    = reflect.TypeOf(string(""))
+		ptrBoolType   = reflect.TypeOf(new(bool))
+		ptrIntType    = reflect.TypeOf(new(int))
+		ptrStringType = reflect.TypeOf(new(string))
+		countType     = reflect.TypeOf(CountFlag(0))
+		funcType      = reflect.TypeOf((func(string))(nil))
+	)
+
+	v := reflect.ValueOf(&Flag).Elem()
+	t := v.Type()
+	for i := 0; i < t.NumField(); i++ {
+		f := t.Field(i)
+		if f.Name == "Cfg" {
+			continue
+		}
+
+		var name string
+		if len(f.Name) == 1 {
+			name = f.Name
+		} else if len(f.Name) == 6 && f.Name[:5] == "Lower" && 'A' <= f.Name[5] && f.Name[5] <= 'Z' {
+			name = string(rune(f.Name[5] + 'a' - 'A'))
+		} else {
+			name = strings.ToLower(f.Name)
+		}
+		if tag := f.Tag.Get("flag"); tag != "" {
+			name = tag
+		}
+
+		help := f.Tag.Get("help")
+		if help == "" {
+			panic(fmt.Sprintf("base.Flag.%s is missing help text", f.Name))
+		}
+
+		if k := f.Type.Kind(); (k == reflect.Ptr || k == reflect.Func) && v.Field(i).IsNil() {
+			panic(fmt.Sprintf("base.Flag.%s is uninitialized %v", f.Name, f.Type))
+		}
+
+		switch f.Type {
+		case boolType:
+			p := v.Field(i).Addr().Interface().(*bool)
+			flag.BoolVar(p, name, *p, help)
+		case intType:
+			p := v.Field(i).Addr().Interface().(*int)
+			flag.IntVar(p, name, *p, help)
+		case stringType:
+			p := v.Field(i).Addr().Interface().(*string)
+			flag.StringVar(p, name, *p, help)
+		case ptrBoolType:
+			p := v.Field(i).Interface().(*bool)
+			flag.BoolVar(p, name, *p, help)
+		case ptrIntType:
+			p := v.Field(i).Interface().(*int)
+			flag.IntVar(p, name, *p, help)
+		case ptrStringType:
+			p := v.Field(i).Interface().(*string)
+			flag.StringVar(p, name, *p, help)
+		case countType:
+			p := (*int)(v.Field(i).Addr().Interface().(*CountFlag))
+			objabi.Flagcount(name, help, p)
+		case funcType:
+			f := v.Field(i).Interface().(func(string))
+			objabi.Flagfn1(name, help, f)
+		}
+	}
+}
+
+// concurrentFlagOk reports whether the current compiler flags
+// are compatible with concurrent compilation.
+func concurrentFlagOk() bool {
+	// TODO(rsc): Many of these are fine. Remove them.
+	return Flag.Percent == 0 &&
+		Flag.E == 0 &&
+		Flag.K == 0 &&
+		Flag.L == 0 &&
+		Flag.LowerH == 0 &&
+		Flag.LowerJ == 0 &&
+		Flag.LowerM == 0 &&
+		Flag.LowerR == 0
+}
+
+func concurrentBackendAllowed() bool {
+	if !concurrentFlagOk() {
+		return false
+	}
+
+	// Debug.S by itself is ok, because all printing occurs
+	// while writing the object file, and that is non-concurrent.
+	// Adding Debug_vlog, however, causes Debug.S to also print
+	// while flushing the plist, which happens concurrently.
+	if Ctxt.Debugvlog || Debug.Any() || Flag.Live > 0 {
+		return false
+	}
+	// TODO: Test and delete this condition.
+	if buildcfg.Experiment.FieldTrack {
+		return false
+	}
+	// TODO: fix races and enable the following flags
+	if Ctxt.Flag_shared || Ctxt.Flag_dynlink || Flag.Race {
+		return false
+	}
+	return true
+}
+
+func addImportDir(dir string) {
+	if dir != "" {
+		Flag.Cfg.ImportDirs = append(Flag.Cfg.ImportDirs, dir)
+	}
+}
+
+func addImportMap(s string) {
+	if Flag.Cfg.ImportMap == nil {
+		Flag.Cfg.ImportMap = make(map[string]string)
+	}
+	if strings.Count(s, "=") != 1 {
+		log.Fatal("-importmap argument must be of the form source=actual")
+	}
+	i := strings.Index(s, "=")
+	source, actual := s[:i], s[i+1:]
+	if source == "" || actual == "" {
+		log.Fatal("-importmap argument must be of the form source=actual; source and actual must be non-empty")
+	}
+	Flag.Cfg.ImportMap[source] = actual
+}
+
+func readImportCfg(file string) {
+	if Flag.Cfg.ImportMap == nil {
+		Flag.Cfg.ImportMap = make(map[string]string)
+	}
+	Flag.Cfg.PackageFile = map[string]string{}
+	data, err := ioutil.ReadFile(file)
+	if err != nil {
+		log.Fatalf("-importcfg: %v", err)
+	}
+
+	for lineNum, line := range strings.Split(string(data), "\n") {
+		lineNum++ // 1-based
+		line = strings.TrimSpace(line)
+		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:
+			log.Fatalf("%s:%d: unknown directive %q", file, lineNum, verb)
+		case "importmap":
+			if before == "" || after == "" {
+				log.Fatalf(`%s:%d: invalid importmap: syntax is "importmap old=new"`, file, lineNum)
+			}
+			Flag.Cfg.ImportMap[before] = after
+		case "packagefile":
+			if before == "" || after == "" {
+				log.Fatalf(`%s:%d: invalid packagefile: syntax is "packagefile path=filename"`, file, lineNum)
+			}
+			Flag.Cfg.PackageFile[before] = after
+		}
+	}
+}
+
+func readEmbedCfg(file string) {
+	data, err := ioutil.ReadFile(file)
+	if err != nil {
+		log.Fatalf("-embedcfg: %v", err)
+	}
+	if err := json.Unmarshal(data, &Flag.Cfg.Embed); err != nil {
+		log.Fatalf("%s: %v", file, err)
+	}
+	if Flag.Cfg.Embed.Patterns == nil {
+		log.Fatalf("%s: invalid embedcfg: missing Patterns", file)
+	}
+	if Flag.Cfg.Embed.Files == nil {
+		log.Fatalf("%s: invalid embedcfg: missing Files", file)
+	}
+}
+
+// parseSpectre parses the spectre configuration from the string s.
+func parseSpectre(s string) {
+	for _, f := range strings.Split(s, ",") {
+		f = strings.TrimSpace(f)
+		switch f {
+		default:
+			log.Fatalf("unknown setting -spectre=%s", f)
+		case "":
+			// nothing
+		case "all":
+			Flag.Cfg.SpectreIndex = true
+			Ctxt.Retpoline = true
+		case "index":
+			Flag.Cfg.SpectreIndex = true
+		case "ret":
+			Ctxt.Retpoline = true
+		}
+	}
+
+	if Flag.Cfg.SpectreIndex {
+		switch buildcfg.GOARCH {
+		case "amd64":
+			// ok
+		default:
+			log.Fatalf("GOARCH=%s does not support -spectre=index", buildcfg.GOARCH)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/base/link.go b/src/cmd/compile/internal/base/link.go
new file mode 100644
index 0000000..49fe435
--- /dev/null
+++ b/src/cmd/compile/internal/base/link.go
@@ -0,0 +1,36 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package base
+
+import (
+	"cmd/internal/obj"
+)
+
+var Ctxt *obj.Link
+
+// TODO(mdempsky): These should probably be obj.Link methods.
+
+// PkgLinksym returns the linker symbol for name within the given
+// package prefix. For user packages, prefix should be the package
+// path encoded with objabi.PathToPrefix.
+func PkgLinksym(prefix, name string, abi obj.ABI) *obj.LSym {
+	if name == "_" {
+		// TODO(mdempsky): Cleanup callers and Fatalf instead.
+		return linksym(prefix, "_", abi)
+	}
+	return linksym(prefix, prefix+"."+name, abi)
+}
+
+// Linkname returns the linker symbol for the given name as it might
+// appear within a //go:linkname directive.
+func Linkname(name string, abi obj.ABI) *obj.LSym {
+	return linksym("_", name, abi)
+}
+
+// linksym is an internal helper function for implementing the above
+// exported APIs.
+func linksym(pkg, name string, abi obj.ABI) *obj.LSym {
+	return Ctxt.LookupABIInit(name, abi, func(r *obj.LSym) { r.Pkg = pkg })
+}
diff --git a/src/cmd/compile/internal/base/print.go b/src/cmd/compile/internal/base/print.go
new file mode 100644
index 0000000..b095fd7
--- /dev/null
+++ b/src/cmd/compile/internal/base/print.go
@@ -0,0 +1,264 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package base
+
+import (
+	"fmt"
+	"internal/buildcfg"
+	"os"
+	"runtime/debug"
+	"sort"
+	"strings"
+
+	"cmd/internal/src"
+)
+
+// An errorMsg is a queued error message, waiting to be printed.
+type errorMsg struct {
+	pos src.XPos
+	msg string
+}
+
+// Pos is the current source position being processed,
+// printed by Errorf, ErrorfLang, Fatalf, and Warnf.
+var Pos src.XPos
+
+var (
+	errorMsgs       []errorMsg
+	numErrors       int // number of entries in errorMsgs that are errors (as opposed to warnings)
+	numSyntaxErrors int
+)
+
+// Errors returns the number of errors reported.
+func Errors() int {
+	return numErrors
+}
+
+// SyntaxErrors returns the number of syntax errors reported
+func SyntaxErrors() int {
+	return numSyntaxErrors
+}
+
+// addErrorMsg adds a new errorMsg (which may be a warning) to errorMsgs.
+func addErrorMsg(pos src.XPos, format string, args ...interface{}) {
+	msg := fmt.Sprintf(format, args...)
+	// Only add the position if know the position.
+	// See issue golang.org/issue/11361.
+	if pos.IsKnown() {
+		msg = fmt.Sprintf("%v: %s", FmtPos(pos), msg)
+	}
+	errorMsgs = append(errorMsgs, errorMsg{
+		pos: pos,
+		msg: msg + "\n",
+	})
+}
+
+// FmtPos formats pos as a file:line string.
+func FmtPos(pos src.XPos) string {
+	if Ctxt == nil {
+		return "???"
+	}
+	return Ctxt.OutermostPos(pos).Format(Flag.C == 0, Flag.L == 1)
+}
+
+// byPos sorts errors by source position.
+type byPos []errorMsg
+
+func (x byPos) Len() int           { return len(x) }
+func (x byPos) Less(i, j int) bool { return x[i].pos.Before(x[j].pos) }
+func (x byPos) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+
+// FlushErrors sorts errors seen so far by line number, prints them to stdout,
+// and empties the errors array.
+func FlushErrors() {
+	if Ctxt != nil && Ctxt.Bso != nil {
+		Ctxt.Bso.Flush()
+	}
+	if len(errorMsgs) == 0 {
+		return
+	}
+	sort.Stable(byPos(errorMsgs))
+	for i, err := range errorMsgs {
+		if i == 0 || err.msg != errorMsgs[i-1].msg {
+			fmt.Printf("%s", err.msg)
+		}
+	}
+	errorMsgs = errorMsgs[:0]
+}
+
+// lasterror keeps track of the most recently issued error,
+// to avoid printing multiple error messages on the same line.
+var lasterror struct {
+	syntax src.XPos // source position of last syntax error
+	other  src.XPos // source position of last non-syntax error
+	msg    string   // error message of last non-syntax error
+}
+
+// sameline reports whether two positions a, b are on the same line.
+func sameline(a, b src.XPos) bool {
+	p := Ctxt.PosTable.Pos(a)
+	q := Ctxt.PosTable.Pos(b)
+	return p.Base() == q.Base() && p.Line() == q.Line()
+}
+
+// Errorf reports a formatted error at the current line.
+func Errorf(format string, args ...interface{}) {
+	ErrorfAt(Pos, format, args...)
+}
+
+// ErrorfAt reports a formatted error message at pos.
+func ErrorfAt(pos src.XPos, format string, args ...interface{}) {
+	msg := fmt.Sprintf(format, args...)
+
+	if strings.HasPrefix(msg, "syntax error") {
+		numSyntaxErrors++
+		// only one syntax error per line, no matter what error
+		if sameline(lasterror.syntax, pos) {
+			return
+		}
+		lasterror.syntax = pos
+	} else {
+		// only one of multiple equal non-syntax errors per line
+		// (FlushErrors shows only one of them, so we filter them
+		// here as best as we can (they may not appear in order)
+		// so that we don't count them here and exit early, and
+		// then have nothing to show for.)
+		if sameline(lasterror.other, pos) && lasterror.msg == msg {
+			return
+		}
+		lasterror.other = pos
+		lasterror.msg = msg
+	}
+
+	addErrorMsg(pos, "%s", msg)
+	numErrors++
+
+	hcrash()
+	if numErrors >= 10 && Flag.LowerE == 0 {
+		FlushErrors()
+		fmt.Printf("%v: too many errors\n", FmtPos(pos))
+		ErrorExit()
+	}
+}
+
+// ErrorfVers reports that a language feature (format, args) requires a later version of Go.
+func ErrorfVers(lang string, format string, args ...interface{}) {
+	Errorf("%s requires %s or later (-lang was set to %s; check go.mod)", fmt.Sprintf(format, args...), lang, Flag.Lang)
+}
+
+// UpdateErrorDot is a clumsy hack that rewrites the last error,
+// if it was "LINE: undefined: NAME", to be "LINE: undefined: NAME in EXPR".
+// It is used to give better error messages for dot (selector) expressions.
+func UpdateErrorDot(line string, name, expr string) {
+	if len(errorMsgs) == 0 {
+		return
+	}
+	e := &errorMsgs[len(errorMsgs)-1]
+	if strings.HasPrefix(e.msg, line) && e.msg == fmt.Sprintf("%v: undefined: %v\n", line, name) {
+		e.msg = fmt.Sprintf("%v: undefined: %v in %v\n", line, name, expr)
+	}
+}
+
+// Warnf reports a formatted warning at the current line.
+// In general the Go compiler does NOT generate warnings,
+// so this should be used only when the user has opted in
+// to additional output by setting a particular flag.
+func Warn(format string, args ...interface{}) {
+	WarnfAt(Pos, format, args...)
+}
+
+// WarnfAt reports a formatted warning at pos.
+// In general the Go compiler does NOT generate warnings,
+// so this should be used only when the user has opted in
+// to additional output by setting a particular flag.
+func WarnfAt(pos src.XPos, format string, args ...interface{}) {
+	addErrorMsg(pos, format, args...)
+	if Flag.LowerM != 0 {
+		FlushErrors()
+	}
+}
+
+// Fatalf reports a fatal error - an internal problem - at the current line and exits.
+// If other errors have already been printed, then Fatalf just quietly exits.
+// (The internal problem may have been caused by incomplete information
+// after the already-reported errors, so best to let users fix those and
+// try again without being bothered about a spurious internal error.)
+//
+// But if no errors have been printed, or if -d panic has been specified,
+// Fatalf prints the error as an "internal compiler error". In a released build,
+// it prints an error asking to file a bug report. In development builds, it
+// prints a stack trace.
+//
+// If -h has been specified, Fatalf panics to force the usual runtime info dump.
+func Fatalf(format string, args ...interface{}) {
+	FatalfAt(Pos, format, args...)
+}
+
+// FatalfAt reports a fatal error - an internal problem - at pos and exits.
+// If other errors have already been printed, then FatalfAt just quietly exits.
+// (The internal problem may have been caused by incomplete information
+// after the already-reported errors, so best to let users fix those and
+// try again without being bothered about a spurious internal error.)
+//
+// But if no errors have been printed, or if -d panic has been specified,
+// FatalfAt prints the error as an "internal compiler error". In a released build,
+// it prints an error asking to file a bug report. In development builds, it
+// prints a stack trace.
+//
+// If -h has been specified, FatalfAt panics to force the usual runtime info dump.
+func FatalfAt(pos src.XPos, format string, args ...interface{}) {
+	FlushErrors()
+
+	if Debug.Panic != 0 || numErrors == 0 {
+		fmt.Printf("%v: internal compiler error: ", FmtPos(pos))
+		fmt.Printf(format, args...)
+		fmt.Printf("\n")
+
+		// If this is a released compiler version, ask for a bug report.
+		if strings.HasPrefix(buildcfg.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()
+	ErrorExit()
+}
+
+// hcrash crashes the compiler when -h is set, to find out where a message is generated.
+func hcrash() {
+	if Flag.LowerH != 0 {
+		FlushErrors()
+		if Flag.LowerO != "" {
+			os.Remove(Flag.LowerO)
+		}
+		panic("-h")
+	}
+}
+
+// ErrorExit handles an error-status exit.
+// It flushes any pending errors, removes the output file, and exits.
+func ErrorExit() {
+	FlushErrors()
+	if Flag.LowerO != "" {
+		os.Remove(Flag.LowerO)
+	}
+	os.Exit(2)
+}
+
+// ExitIfErrors calls ErrorExit if any errors have been reported.
+func ExitIfErrors() {
+	if Errors() > 0 {
+		ErrorExit()
+	}
+}
+
+var AutogeneratedPos src.XPos
diff --git a/src/cmd/compile/internal/base/timings.go b/src/cmd/compile/internal/base/timings.go
new file mode 100644
index 0000000..f599f4e
--- /dev/null
+++ b/src/cmd/compile/internal/base/timings.go
@@ -0,0 +1,237 @@
+// 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 base
+
+import (
+	"fmt"
+	"io"
+	"strings"
+	"time"
+)
+
+var Timer Timings
+
+// Timings collects the execution times of labeled phases
+// which are added trough a sequence of Start/Stop calls.
+// Events may be associated with each phase via AddEvent.
+type Timings struct {
+	list   []timestamp
+	events map[int][]*event // lazily allocated
+}
+
+type timestamp struct {
+	time  time.Time
+	label string
+	start bool
+}
+
+type event struct {
+	size int64  // count or amount of data processed (allocations, data size, lines, funcs, ...)
+	unit string // unit of size measure (count, MB, lines, funcs, ...)
+}
+
+func (t *Timings) append(labels []string, start bool) {
+	t.list = append(t.list, timestamp{time.Now(), strings.Join(labels, ":"), start})
+}
+
+// Start marks the beginning of a new phase and implicitly stops the previous phase.
+// The phase name is the colon-separated concatenation of the labels.
+func (t *Timings) Start(labels ...string) {
+	t.append(labels, true)
+}
+
+// Stop marks the end of a phase and implicitly starts a new phase.
+// The labels are added to the labels of the ended phase.
+func (t *Timings) Stop(labels ...string) {
+	t.append(labels, false)
+}
+
+// AddEvent associates an event, i.e., a count, or an amount of data,
+// with the most recently started or stopped phase; or the very first
+// phase if Start or Stop hasn't been called yet. The unit specifies
+// the unit of measurement (e.g., MB, lines, no. of funcs, etc.).
+func (t *Timings) AddEvent(size int64, unit string) {
+	m := t.events
+	if m == nil {
+		m = make(map[int][]*event)
+		t.events = m
+	}
+	i := len(t.list)
+	if i > 0 {
+		i--
+	}
+	m[i] = append(m[i], &event{size, unit})
+}
+
+// Write prints the phase times to w.
+// The prefix is printed at the start of each line.
+func (t *Timings) Write(w io.Writer, prefix string) {
+	if len(t.list) > 0 {
+		var lines lines
+
+		// group of phases with shared non-empty label prefix
+		var group struct {
+			label string        // label prefix
+			tot   time.Duration // accumulated phase time
+			size  int           // number of phases collected in group
+		}
+
+		// accumulated time between Stop/Start timestamps
+		var unaccounted time.Duration
+
+		// process Start/Stop timestamps
+		pt := &t.list[0] // previous timestamp
+		tot := t.list[len(t.list)-1].time.Sub(pt.time)
+		for i := 1; i < len(t.list); i++ {
+			qt := &t.list[i] // current timestamp
+			dt := qt.time.Sub(pt.time)
+
+			var label string
+			var events []*event
+			if pt.start {
+				// previous phase started
+				label = pt.label
+				events = t.events[i-1]
+				if qt.start {
+					// start implicitly ended previous phase; nothing to do
+				} else {
+					// stop ended previous phase; append stop labels, if any
+					if qt.label != "" {
+						label += ":" + qt.label
+					}
+					// events associated with stop replace prior events
+					if e := t.events[i]; e != nil {
+						events = e
+					}
+				}
+			} else {
+				// previous phase stopped
+				if qt.start {
+					// between a stopped and started phase; unaccounted time
+					unaccounted += dt
+				} else {
+					// previous stop implicitly started current phase
+					label = qt.label
+					events = t.events[i]
+				}
+			}
+			if label != "" {
+				// add phase to existing group, or start a new group
+				l := commonPrefix(group.label, label)
+				if group.size == 1 && l != "" || group.size > 1 && l == group.label {
+					// add to existing group
+					group.label = l
+					group.tot += dt
+					group.size++
+				} else {
+					// start a new group
+					if group.size > 1 {
+						lines.add(prefix+group.label+"subtotal", 1, group.tot, tot, nil)
+					}
+					group.label = label
+					group.tot = dt
+					group.size = 1
+				}
+
+				// write phase
+				lines.add(prefix+label, 1, dt, tot, events)
+			}
+
+			pt = qt
+		}
+
+		if group.size > 1 {
+			lines.add(prefix+group.label+"subtotal", 1, group.tot, tot, nil)
+		}
+
+		if unaccounted != 0 {
+			lines.add(prefix+"unaccounted", 1, unaccounted, tot, nil)
+		}
+
+		lines.add(prefix+"total", 1, tot, tot, nil)
+
+		lines.write(w)
+	}
+}
+
+func commonPrefix(a, b string) string {
+	i := 0
+	for i < len(a) && i < len(b) && a[i] == b[i] {
+		i++
+	}
+	return a[:i]
+}
+
+type lines [][]string
+
+func (lines *lines) add(label string, n int, dt, tot time.Duration, events []*event) {
+	var line []string
+	add := func(format string, args ...interface{}) {
+		line = append(line, fmt.Sprintf(format, args...))
+	}
+
+	add("%s", label)
+	add("    %d", n)
+	add("    %d ns/op", dt)
+	add("    %.2f %%", float64(dt)/float64(tot)*100)
+
+	for _, e := range events {
+		add("    %d", e.size)
+		add(" %s", e.unit)
+		add("    %d", int64(float64(e.size)/dt.Seconds()+0.5))
+		add(" %s/s", e.unit)
+	}
+
+	*lines = append(*lines, line)
+}
+
+func (lines lines) write(w io.Writer) {
+	// determine column widths and contents
+	var widths []int
+	var number []bool
+	for _, line := range lines {
+		for i, col := range line {
+			if i < len(widths) {
+				if len(col) > widths[i] {
+					widths[i] = len(col)
+				}
+			} else {
+				widths = append(widths, len(col))
+				number = append(number, isnumber(col)) // first line determines column contents
+			}
+		}
+	}
+
+	// make column widths a multiple of align for more stable output
+	const align = 1 // set to a value > 1 to enable
+	if align > 1 {
+		for i, w := range widths {
+			w += align - 1
+			widths[i] = w - w%align
+		}
+	}
+
+	// print lines taking column widths and contents into account
+	for _, line := range lines {
+		for i, col := range line {
+			format := "%-*s"
+			if number[i] {
+				format = "%*s" // numbers are right-aligned
+			}
+			fmt.Fprintf(w, format, widths[i], col)
+		}
+		fmt.Fprintln(w)
+	}
+}
+
+func isnumber(s string) bool {
+	for _, ch := range s {
+		if ch <= ' ' {
+			continue // ignore leading whitespace
+		}
+		return '0' <= ch && ch <= '9' || ch == '.' || ch == '-' || ch == '+'
+	}
+	return false
+}
diff --git a/src/cmd/compile/internal/bitvec/bv.go b/src/cmd/compile/internal/bitvec/bv.go
new file mode 100644
index 0000000..bcac1fe
--- /dev/null
+++ b/src/cmd/compile/internal/bitvec/bv.go
@@ -0,0 +1,190 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bitvec
+
+import (
+	"math/bits"
+
+	"cmd/compile/internal/base"
+)
+
+const (
+	wordBits  = 32
+	wordMask  = wordBits - 1
+	wordShift = 5
+)
+
+// A BitVec is a bit vector.
+type BitVec struct {
+	N int32    // number of bits in vector
+	B []uint32 // words holding bits
+}
+
+func New(n int32) BitVec {
+	nword := (n + wordBits - 1) / wordBits
+	return BitVec{n, make([]uint32, nword)}
+}
+
+type Bulk struct {
+	words []uint32
+	nbit  int32
+	nword int32
+}
+
+func NewBulk(nbit int32, count int32) Bulk {
+	nword := (nbit + wordBits - 1) / wordBits
+	size := int64(nword) * int64(count)
+	if int64(int32(size*4)) != size*4 {
+		base.Fatalf("NewBulk too big: nbit=%d count=%d nword=%d size=%d", nbit, count, nword, size)
+	}
+	return Bulk{
+		words: make([]uint32, size),
+		nbit:  nbit,
+		nword: nword,
+	}
+}
+
+func (b *Bulk) Next() BitVec {
+	out := BitVec{b.nbit, b.words[:b.nword]}
+	b.words = b.words[b.nword:]
+	return out
+}
+
+func (bv1 BitVec) Eq(bv2 BitVec) bool {
+	if bv1.N != bv2.N {
+		base.Fatalf("bvequal: lengths %d and %d are not equal", bv1.N, bv2.N)
+	}
+	for i, x := range bv1.B {
+		if x != bv2.B[i] {
+			return false
+		}
+	}
+	return true
+}
+
+func (dst BitVec) Copy(src BitVec) {
+	copy(dst.B, src.B)
+}
+
+func (bv BitVec) Get(i int32) bool {
+	if i < 0 || i >= bv.N {
+		base.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
+}
+
+func (bv BitVec) Set(i int32) {
+	if i < 0 || i >= bv.N {
+		base.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
+}
+
+func (bv BitVec) Unset(i int32) {
+	if i < 0 || i >= bv.N {
+		base.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
+}
+
+// bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
+// If there is no such index, bvnext returns -1.
+func (bv BitVec) Next(i int32) int32 {
+	if i >= bv.N {
+		return -1
+	}
+
+	// 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 i >= bv.N {
+		return -1
+	}
+
+	// Find 1 bit.
+	w := bv.B[i>>wordShift] >> uint(i&wordMask)
+	i += int32(bits.TrailingZeros32(w))
+
+	return i
+}
+
+func (bv BitVec) IsEmpty() bool {
+	for _, x := range bv.B {
+		if x != 0 {
+			return false
+		}
+	}
+	return true
+}
+
+func (bv BitVec) Not() {
+	for i, x := range bv.B {
+		bv.B[i] = ^x
+	}
+}
+
+// union
+func (dst BitVec) Or(src1, src2 BitVec) {
+	if len(src1.B) == 0 {
+		return
+	}
+	_, _ = dst.B[len(src1.B)-1], src2.B[len(src1.B)-1] // hoist bounds checks out of the loop
+
+	for i, x := range src1.B {
+		dst.B[i] = x | src2.B[i]
+	}
+}
+
+// intersection
+func (dst BitVec) And(src1, src2 BitVec) {
+	if len(src1.B) == 0 {
+		return
+	}
+	_, _ = dst.B[len(src1.B)-1], src2.B[len(src1.B)-1] // hoist bounds checks out of the loop
+
+	for i, x := range src1.B {
+		dst.B[i] = x & src2.B[i]
+	}
+}
+
+// difference
+func (dst BitVec) AndNot(src1, src2 BitVec) {
+	if len(src1.B) == 0 {
+		return
+	}
+	_, _ = dst.B[len(src1.B)-1], src2.B[len(src1.B)-1] // hoist bounds checks out of the loop
+
+	for i, x := range src1.B {
+		dst.B[i] = x &^ src2.B[i]
+	}
+}
+
+func (bv BitVec) String() string {
+	s := make([]byte, 2+bv.N)
+	copy(s, "#*")
+	for i := int32(0); i < bv.N; i++ {
+		ch := byte('0')
+		if bv.Get(i) {
+			ch = '1'
+		}
+		s[2+i] = ch
+	}
+	return string(s)
+}
+
+func (bv BitVec) Clear() {
+	for i := range bv.B {
+		bv.B[i] = 0
+	}
+}
diff --git a/src/cmd/compile/internal/deadcode/deadcode.go b/src/cmd/compile/internal/deadcode/deadcode.go
new file mode 100644
index 0000000..5202037
--- /dev/null
+++ b/src/cmd/compile/internal/deadcode/deadcode.go
@@ -0,0 +1,152 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package deadcode
+
+import (
+	"go/constant"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+)
+
+func Func(fn *ir.Func) {
+	stmts(&fn.Body)
+
+	if len(fn.Body) == 0 {
+		return
+	}
+
+	for _, n := range fn.Body {
+		if len(n.Init()) > 0 {
+			return
+		}
+		switch n.Op() {
+		case ir.OIF:
+			n := n.(*ir.IfStmt)
+			if !ir.IsConst(n.Cond, constant.Bool) || len(n.Body) > 0 || len(n.Else) > 0 {
+				return
+			}
+		case ir.OFOR:
+			n := n.(*ir.ForStmt)
+			if !ir.IsConst(n.Cond, constant.Bool) || ir.BoolVal(n.Cond) {
+				return
+			}
+		default:
+			return
+		}
+	}
+
+	fn.Body = []ir.Node{ir.NewBlockStmt(base.Pos, nil)}
+}
+
+func stmts(nn *ir.Nodes) {
+	var lastLabel = -1
+	for i, n := range *nn {
+		if n != nil && n.Op() == ir.OLABEL {
+			lastLabel = i
+		}
+	}
+	for i, n := range *nn {
+		// Cut is set to true when all nodes after i'th position
+		// should be removed.
+		// In other words, it marks whole slice "tail" as dead.
+		cut := false
+		if n == nil {
+			continue
+		}
+		if n.Op() == ir.OIF {
+			n := n.(*ir.IfStmt)
+			n.Cond = expr(n.Cond)
+			if ir.IsConst(n.Cond, constant.Bool) {
+				var body ir.Nodes
+				if ir.BoolVal(n.Cond) {
+					n.Else = ir.Nodes{}
+					body = n.Body
+				} else {
+					n.Body = ir.Nodes{}
+					body = n.Else
+				}
+				// If "then" or "else" branch ends with panic or return statement,
+				// it is safe to remove all statements after this node.
+				// isterminating is not used to avoid goto-related complications.
+				// We must be careful not to deadcode-remove labels, as they
+				// might be the target of a goto. See issue 28616.
+				if body := body; len(body) != 0 {
+					switch body[(len(body) - 1)].Op() {
+					case ir.ORETURN, ir.OTAILCALL, ir.OPANIC:
+						if i > lastLabel {
+							cut = true
+						}
+					}
+				}
+			}
+		}
+
+		if len(n.Init()) != 0 {
+			stmts(n.(ir.InitNode).PtrInit())
+		}
+		switch n.Op() {
+		case ir.OBLOCK:
+			n := n.(*ir.BlockStmt)
+			stmts(&n.List)
+		case ir.OFOR:
+			n := n.(*ir.ForStmt)
+			stmts(&n.Body)
+		case ir.OIF:
+			n := n.(*ir.IfStmt)
+			stmts(&n.Body)
+			stmts(&n.Else)
+		case ir.ORANGE:
+			n := n.(*ir.RangeStmt)
+			stmts(&n.Body)
+		case ir.OSELECT:
+			n := n.(*ir.SelectStmt)
+			for _, cas := range n.Cases {
+				stmts(&cas.Body)
+			}
+		case ir.OSWITCH:
+			n := n.(*ir.SwitchStmt)
+			for _, cas := range n.Cases {
+				stmts(&cas.Body)
+			}
+		}
+
+		if cut {
+			*nn = (*nn)[:i+1]
+			break
+		}
+	}
+}
+
+func expr(n ir.Node) ir.Node {
+	// Perform dead-code elimination on short-circuited boolean
+	// expressions involving constants with the intent of
+	// producing a constant 'if' condition.
+	switch n.Op() {
+	case ir.OANDAND:
+		n := n.(*ir.LogicalExpr)
+		n.X = expr(n.X)
+		n.Y = expr(n.Y)
+		if ir.IsConst(n.X, constant.Bool) {
+			if ir.BoolVal(n.X) {
+				return n.Y // true && x => x
+			} else {
+				return n.X // false && x => false
+			}
+		}
+	case ir.OOROR:
+		n := n.(*ir.LogicalExpr)
+		n.X = expr(n.X)
+		n.Y = expr(n.Y)
+		if ir.IsConst(n.X, constant.Bool) {
+			if ir.BoolVal(n.X) {
+				return n.X // true || x => true
+			} else {
+				return n.Y // false || x => x
+			}
+		}
+	}
+	return n
+}
diff --git a/src/cmd/compile/internal/devirtualize/devirtualize.go b/src/cmd/compile/internal/devirtualize/devirtualize.go
new file mode 100644
index 0000000..60ba208
--- /dev/null
+++ b/src/cmd/compile/internal/devirtualize/devirtualize.go
@@ -0,0 +1,85 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package devirtualize implements a simple "devirtualization"
+// optimization pass, which replaces interface method calls with
+// direct concrete-type method calls where possible.
+package devirtualize
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+)
+
+// Func devirtualizes calls within fn where possible.
+func Func(fn *ir.Func) {
+	ir.CurFunc = fn
+	ir.VisitList(fn.Body, func(n ir.Node) {
+		if call, ok := n.(*ir.CallExpr); ok {
+			Call(call)
+		}
+	})
+}
+
+// Call devirtualizes the given call if possible.
+func Call(call *ir.CallExpr) {
+	if call.Op() != ir.OCALLINTER {
+		return
+	}
+	sel := call.X.(*ir.SelectorExpr)
+	r := ir.StaticValue(sel.X)
+	if r.Op() != ir.OCONVIFACE {
+		return
+	}
+	recv := r.(*ir.ConvExpr)
+
+	typ := recv.X.Type()
+	if typ.IsInterface() {
+		return
+	}
+
+	dt := ir.NewTypeAssertExpr(sel.Pos(), sel.X, nil)
+	dt.SetType(typ)
+	x := typecheck.Callee(ir.NewSelectorExpr(sel.Pos(), ir.OXDOT, dt, sel.Sel))
+	switch x.Op() {
+	case ir.ODOTMETH:
+		x := x.(*ir.SelectorExpr)
+		if base.Flag.LowerM != 0 {
+			base.WarnfAt(call.Pos(), "devirtualizing %v to %v", sel, typ)
+		}
+		call.SetOp(ir.OCALLMETH)
+		call.X = x
+	case ir.ODOTINTER:
+		// Promoted method from embedded interface-typed field (#42279).
+		x := x.(*ir.SelectorExpr)
+		if base.Flag.LowerM != 0 {
+			base.WarnfAt(call.Pos(), "partially devirtualizing %v to %v", sel, typ)
+		}
+		call.SetOp(ir.OCALLINTER)
+		call.X = x
+	default:
+		// TODO(mdempsky): Turn back into Fatalf after more testing.
+		if base.Flag.LowerM != 0 {
+			base.WarnfAt(call.Pos(), "failed to devirtualize %v (%v)", x, x.Op())
+		}
+		return
+	}
+
+	// Duplicated logic from typecheck for function call return
+	// value types.
+	//
+	// Receiver parameter size may have changed; need to update
+	// call.Type to get correct stack offsets for result
+	// parameters.
+	types.CheckSize(x.Type())
+	switch ft := x.Type(); ft.NumResults() {
+	case 0:
+	case 1:
+		call.SetType(ft.Results().Field(0).Type)
+	default:
+		call.SetType(ft.Results())
+	}
+}
diff --git a/src/cmd/compile/internal/dwarfgen/dwarf.go b/src/cmd/compile/internal/dwarfgen/dwarf.go
new file mode 100644
index 0000000..0e22b61
--- /dev/null
+++ b/src/cmd/compile/internal/dwarfgen/dwarf.go
@@ -0,0 +1,564 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dwarfgen
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"internal/buildcfg"
+	"sort"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
+	"cmd/compile/internal/types"
+	"cmd/internal/dwarf"
+	"cmd/internal/obj"
+	"cmd/internal/objabi"
+	"cmd/internal/src"
+)
+
+func Info(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls) {
+	fn := curfn.(*ir.Func)
+
+	if fn.Nname != nil {
+		expect := fn.Linksym()
+		if fnsym.ABI() == obj.ABI0 {
+			expect = fn.LinksymABI(obj.ABI0)
+		}
+		if fnsym != expect {
+			base.Fatalf("unexpected fnsym: %v != %v", fnsym, expect)
+		}
+	}
+
+	// Back when there were two different *Funcs for a function, this code
+	// was not consistent about whether a particular *Node being processed
+	// was an ODCLFUNC or ONAME node. Partly this is because inlined function
+	// bodies have no ODCLFUNC node, which was it's own inconsistency.
+	// In any event, the handling of the two different nodes for DWARF purposes
+	// was subtly different, likely in unintended ways. CL 272253 merged the
+	// two nodes' Func fields, so that code sees the same *Func whether it is
+	// holding the ODCLFUNC or the ONAME. This resulted in changes in the
+	// DWARF output. To preserve the existing DWARF output and leave an
+	// intentional change for a future CL, this code does the following when
+	// fn.Op == ONAME:
+	//
+	// 1. Disallow use of createComplexVars in createDwarfVars.
+	//    It was not possible to reach that code for an ONAME before,
+	//    because the DebugInfo was set only on the ODCLFUNC Func.
+	//    Calling into it in the ONAME case causes an index out of bounds panic.
+	//
+	// 2. Do not populate apdecls. fn.Func.Dcl was in the ODCLFUNC Func,
+	//    not the ONAME Func. Populating apdecls for the ONAME case results
+	//    in selected being populated after createSimpleVars is called in
+	//    createDwarfVars, and then that causes the loop to skip all the entries
+	//    in dcl, meaning that the RecordAutoType calls don't happen.
+	//
+	// These two adjustments keep toolstash -cmp working for now.
+	// Deciding the right answer is, as they say, future work.
+	//
+	// We can tell the difference between the old ODCLFUNC and ONAME
+	// cases by looking at the infosym.Name. If it's empty, DebugInfo is
+	// being called from (*obj.Link).populateDWARF, which used to use
+	// the ODCLFUNC. If it's non-empty (the name will end in $abstract),
+	// DebugInfo is being called from (*obj.Link).DwarfAbstractFunc,
+	// which used to use the ONAME form.
+	isODCLFUNC := infosym.Name == ""
+
+	var apdecls []*ir.Name
+	// Populate decls for fn.
+	if isODCLFUNC {
+		for _, n := range fn.Dcl {
+			if n.Op() != ir.ONAME { // might be OTYPE or OLITERAL
+				continue
+			}
+			switch n.Class {
+			case ir.PAUTO:
+				if !n.Used() {
+					// Text == nil -> generating abstract function
+					if fnsym.Func().Text != nil {
+						base.Fatalf("debuginfo unused node (AllocFrame should truncate fn.Func.Dcl)")
+					}
+					continue
+				}
+			case ir.PPARAM, ir.PPARAMOUT:
+			default:
+				continue
+			}
+			apdecls = append(apdecls, n)
+			fnsym.Func().RecordAutoType(reflectdata.TypeLinksym(n.Type()))
+		}
+	}
+
+	decls, dwarfVars := createDwarfVars(fnsym, isODCLFUNC, fn, apdecls)
+
+	// For each type referenced by the functions auto vars but not
+	// already referenced by a dwarf var, attach an R_USETYPE relocation to
+	// the function symbol to insure that the type included in DWARF
+	// processing during linking.
+	typesyms := []*obj.LSym{}
+	for t, _ := range fnsym.Func().Autot {
+		typesyms = append(typesyms, t)
+	}
+	sort.Sort(obj.BySymName(typesyms))
+	for _, sym := range typesyms {
+		r := obj.Addrel(infosym)
+		r.Sym = sym
+		r.Type = objabi.R_USETYPE
+	}
+	fnsym.Func().Autot = nil
+
+	var varScopes []ir.ScopeID
+	for _, decl := range decls {
+		pos := declPos(decl)
+		varScopes = append(varScopes, findScope(fn.Marks, pos))
+	}
+
+	scopes := assembleScopes(fnsym, fn, dwarfVars, varScopes)
+	var inlcalls dwarf.InlCalls
+	if base.Flag.GenDwarfInl > 0 {
+		inlcalls = assembleInlines(fnsym, dwarfVars)
+	}
+	return scopes, inlcalls
+}
+
+func declPos(decl *ir.Name) src.XPos {
+	return decl.Canonical().Pos()
+}
+
+// createDwarfVars process fn, returning a list of DWARF variables and the
+// Nodes they represent.
+func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir.Name) ([]*ir.Name, []*dwarf.Var) {
+	// Collect a raw list of DWARF vars.
+	var vars []*dwarf.Var
+	var decls []*ir.Name
+	var selected ir.NameSet
+
+	if base.Ctxt.Flag_locationlists && base.Ctxt.Flag_optimize && fn.DebugInfo != nil && complexOK {
+		decls, vars, selected = createComplexVars(fnsym, fn)
+	} else if fn.ABI == obj.ABIInternal && base.Flag.N != 0 && complexOK {
+		decls, vars, selected = createABIVars(fnsym, fn, apDecls)
+	} else {
+		decls, vars, selected = createSimpleVars(fnsym, apDecls)
+	}
+
+	dcl := apDecls
+	if fnsym.WasInlined() {
+		dcl = preInliningDcls(fnsym)
+	}
+
+	// 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).  Input arguments not eligible
+	// for SSA optimization are also missing.  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 non-SSA-able arguments, however, the correct information
+	// is known -- they have a single home on the stack.
+	for _, n := range dcl {
+		if selected.Has(n) {
+			continue
+		}
+		c := n.Sym().Name[0]
+		if c == '.' || n.Type().IsUntyped() {
+			continue
+		}
+		if n.Class == ir.PPARAM && !ssagen.TypeOK(n.Type()) {
+			// SSA-able args get location lists, and may move in and
+			// out of registers, so those are handled elsewhere.
+			// Autos and named output params seem to get handled
+			// with VARDEF, which creates location lists.
+			// Args not of SSA-able type are treated here; they
+			// are homed on the stack in a single place for the
+			// entire call.
+			vars = append(vars, createSimpleVar(fnsym, n))
+			decls = append(decls, n)
+			continue
+		}
+		typename := dwarf.InfoPrefix + types.TypeSymName(n.Type())
+		decls = append(decls, n)
+		abbrev := dwarf.DW_ABRV_AUTO_LOCLIST
+		isReturnValue := (n.Class == ir.PPARAMOUT)
+		if n.Class == ir.PPARAM || n.Class == ir.PPARAMOUT {
+			abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
+		}
+		if n.Esc() == ir.EscHeap {
+			// The variable in question has been promoted to the heap.
+			// Its address is in n.Heapaddr.
+			// TODO(thanm): generate a better location expression
+		}
+		inlIndex := 0
+		if base.Flag.GenDwarfInl > 1 {
+			if n.InlFormal() || n.InlLocal() {
+				inlIndex = posInlIndex(n.Pos()) + 1
+				if n.InlFormal() {
+					abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
+				}
+			}
+		}
+		declpos := base.Ctxt.InnermostPos(n.Pos())
+		vars = append(vars, &dwarf.Var{
+			Name:          n.Sym().Name,
+			IsReturnValue: isReturnValue,
+			Abbrev:        abbrev,
+			StackOffset:   int32(n.FrameOffset()),
+			Type:          base.Ctxt.Lookup(typename),
+			DeclFile:      declpos.RelFilename(),
+			DeclLine:      declpos.RelLine(),
+			DeclCol:       declpos.Col(),
+			InlIndex:      int32(inlIndex),
+			ChildIndex:    -1,
+		})
+		// Record go type of to insure that it gets emitted by the linker.
+		fnsym.Func().RecordAutoType(reflectdata.TypeLinksym(n.Type()))
+	}
+
+	// Sort decls and vars.
+	sortDeclsAndVars(fn, decls, vars)
+
+	return decls, vars
+}
+
+// sortDeclsAndVars sorts the decl and dwarf var lists according to
+// parameter declaration order, so as to insure that when a subprogram
+// DIE is emitted, its parameter children appear in declaration order.
+// Prior to the advent of the register ABI, sorting by frame offset
+// would achieve this; with the register we now need to go back to the
+// original function signature.
+func sortDeclsAndVars(fn *ir.Func, decls []*ir.Name, vars []*dwarf.Var) {
+	paramOrder := make(map[*ir.Name]int)
+	idx := 1
+	for _, selfn := range types.RecvsParamsResults {
+		fsl := selfn(fn.Type()).FieldSlice()
+		for _, f := range fsl {
+			if n, ok := f.Nname.(*ir.Name); ok {
+				paramOrder[n] = idx
+				idx++
+			}
+		}
+	}
+	sort.Stable(varsAndDecls{decls, vars, paramOrder})
+}
+
+type varsAndDecls struct {
+	decls      []*ir.Name
+	vars       []*dwarf.Var
+	paramOrder map[*ir.Name]int
+}
+
+func (v varsAndDecls) Len() int {
+	return len(v.decls)
+}
+
+func (v varsAndDecls) Less(i, j int) bool {
+	nameLT := func(ni, nj *ir.Name) bool {
+		oi, foundi := v.paramOrder[ni]
+		oj, foundj := v.paramOrder[nj]
+		if foundi {
+			if foundj {
+				return oi < oj
+			} else {
+				return true
+			}
+		}
+		return false
+	}
+	return nameLT(v.decls[i], v.decls[j])
+}
+
+func (v varsAndDecls) Swap(i, j int) {
+	v.vars[i], v.vars[j] = v.vars[j], v.vars[i]
+	v.decls[i], v.decls[j] = v.decls[j], v.decls[i]
+}
+
+// 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) []*ir.Name {
+	fn := base.Ctxt.DwFixups.GetPrecursorFunc(fnsym).(*ir.Func)
+	var rdcl []*ir.Name
+	for _, n := range fn.Inl.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)
+	}
+	return rdcl
+}
+
+// createSimpleVars creates a DWARF entry for every variable declared in the
+// function, claiming that they are permanently on the stack.
+func createSimpleVars(fnsym *obj.LSym, apDecls []*ir.Name) ([]*ir.Name, []*dwarf.Var, ir.NameSet) {
+	var vars []*dwarf.Var
+	var decls []*ir.Name
+	var selected ir.NameSet
+	for _, n := range apDecls {
+		if ir.IsAutoTmp(n) {
+			continue
+		}
+
+		decls = append(decls, n)
+		vars = append(vars, createSimpleVar(fnsym, n))
+		selected.Add(n)
+	}
+	return decls, vars, selected
+}
+
+func createSimpleVar(fnsym *obj.LSym, n *ir.Name) *dwarf.Var {
+	var abbrev int
+	var offs int64
+
+	localAutoOffset := func() int64 {
+		offs = n.FrameOffset()
+		if base.Ctxt.FixedFrameSize() == 0 {
+			offs -= int64(types.PtrSize)
+		}
+		if buildcfg.FramePointerEnabled {
+			offs -= int64(types.PtrSize)
+		}
+		return offs
+	}
+
+	switch n.Class {
+	case ir.PAUTO:
+		offs = localAutoOffset()
+		abbrev = dwarf.DW_ABRV_AUTO
+	case ir.PPARAM, ir.PPARAMOUT:
+		abbrev = dwarf.DW_ABRV_PARAM
+		if n.IsOutputParamInRegisters() {
+			offs = localAutoOffset()
+		} else {
+			offs = n.FrameOffset() + base.Ctxt.FixedFrameSize()
+		}
+
+	default:
+		base.Fatalf("createSimpleVar unexpected class %v for node %v", n.Class, n)
+	}
+
+	typename := dwarf.InfoPrefix + types.TypeSymName(n.Type())
+	delete(fnsym.Func().Autot, reflectdata.TypeLinksym(n.Type()))
+	inlIndex := 0
+	if base.Flag.GenDwarfInl > 1 {
+		if n.InlFormal() || n.InlLocal() {
+			inlIndex = posInlIndex(n.Pos()) + 1
+			if n.InlFormal() {
+				abbrev = dwarf.DW_ABRV_PARAM
+			}
+		}
+	}
+	declpos := base.Ctxt.InnermostPos(declPos(n))
+	return &dwarf.Var{
+		Name:          n.Sym().Name,
+		IsReturnValue: n.Class == ir.PPARAMOUT,
+		IsInlFormal:   n.InlFormal(),
+		Abbrev:        abbrev,
+		StackOffset:   int32(offs),
+		Type:          base.Ctxt.Lookup(typename),
+		DeclFile:      declpos.RelFilename(),
+		DeclLine:      declpos.RelLine(),
+		DeclCol:       declpos.Col(),
+		InlIndex:      int32(inlIndex),
+		ChildIndex:    -1,
+	}
+}
+
+// createABIVars creates DWARF variables for functions in which the
+// register ABI is enabled but optimization is turned off. It uses a
+// hybrid approach in which register-resident input params are
+// captured with location lists, and all other vars use the "simple"
+// strategy.
+func createABIVars(fnsym *obj.LSym, fn *ir.Func, apDecls []*ir.Name) ([]*ir.Name, []*dwarf.Var, ir.NameSet) {
+
+	// Invoke createComplexVars to generate dwarf vars for input parameters
+	// that are register-allocated according to the ABI rules.
+	decls, vars, selected := createComplexVars(fnsym, fn)
+
+	// Now fill in the remainder of the variables: input parameters
+	// that are not register-resident, output parameters, and local
+	// variables.
+	for _, n := range apDecls {
+		if ir.IsAutoTmp(n) {
+			continue
+		}
+		if _, ok := selected[n]; ok {
+			// already handled
+			continue
+		}
+
+		decls = append(decls, n)
+		vars = append(vars, createSimpleVar(fnsym, n))
+		selected.Add(n)
+	}
+
+	return decls, vars, selected
+}
+
+// createComplexVars creates recomposed DWARF vars with location lists,
+// suitable for describing optimized code.
+func createComplexVars(fnsym *obj.LSym, fn *ir.Func) ([]*ir.Name, []*dwarf.Var, ir.NameSet) {
+	debugInfo := fn.DebugInfo.(*ssa.FuncDebug)
+
+	// Produce a DWARF variable entry for each user variable.
+	var decls []*ir.Name
+	var vars []*dwarf.Var
+	var ssaVars ir.NameSet
+
+	for varID, dvar := range debugInfo.Vars {
+		n := dvar
+		ssaVars.Add(n)
+		for _, slot := range debugInfo.VarSlots[varID] {
+			ssaVars.Add(debugInfo.Slots[slot].N)
+		}
+
+		if dvar := createComplexVar(fnsym, fn, ssa.VarID(varID)); dvar != nil {
+			decls = append(decls, n)
+			vars = append(vars, dvar)
+		}
+	}
+
+	return decls, vars, ssaVars
+}
+
+// createComplexVar builds a single DWARF variable entry and location list.
+func createComplexVar(fnsym *obj.LSym, fn *ir.Func, varID ssa.VarID) *dwarf.Var {
+	debug := fn.DebugInfo.(*ssa.FuncDebug)
+	n := debug.Vars[varID]
+
+	var abbrev int
+	switch n.Class {
+	case ir.PAUTO:
+		abbrev = dwarf.DW_ABRV_AUTO_LOCLIST
+	case ir.PPARAM, ir.PPARAMOUT:
+		abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
+	default:
+		return nil
+	}
+
+	gotype := reflectdata.TypeLinksym(n.Type())
+	delete(fnsym.Func().Autot, gotype)
+	typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
+	inlIndex := 0
+	if base.Flag.GenDwarfInl > 1 {
+		if n.InlFormal() || n.InlLocal() {
+			inlIndex = posInlIndex(n.Pos()) + 1
+			if n.InlFormal() {
+				abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
+			}
+		}
+	}
+	declpos := base.Ctxt.InnermostPos(n.Pos())
+	dvar := &dwarf.Var{
+		Name:          n.Sym().Name,
+		IsReturnValue: n.Class == ir.PPARAMOUT,
+		IsInlFormal:   n.InlFormal(),
+		Abbrev:        abbrev,
+		Type:          base.Ctxt.Lookup(typename),
+		// The stack offset is used as a sorting key, so for decomposed
+		// variables just give it the first 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: ssagen.StackOffset(debug.Slots[debug.VarSlots[varID][0]]),
+		DeclFile:    declpos.RelFilename(),
+		DeclLine:    declpos.RelLine(),
+		DeclCol:     declpos.Col(),
+		InlIndex:    int32(inlIndex),
+		ChildIndex:  -1,
+	}
+	list := debug.LocationLists[varID]
+	if len(list) != 0 {
+		dvar.PutLocationList = func(listSym, startPC dwarf.Sym) {
+			debug.PutLocationList(list, base.Ctxt, listSym.(*obj.LSym), startPC.(*obj.LSym))
+		}
+	}
+	return dvar
+}
+
+// RecordFlags records the specified command-line flags to be placed
+// in the DWARF info.
+func RecordFlags(flags ...string) {
+	if base.Ctxt.Pkgpath == "" {
+		// 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())
+	}
+
+	// Adds flag to producer string singalling whether regabi is turned on or
+	// off.
+	// Once regabi is turned on across the board and the relative GOEXPERIMENT
+	// knobs no longer exist this code should be removed.
+	if buildcfg.Experiment.RegabiArgs {
+		cmd.Write([]byte(" regabi"))
+	}
+
+	if cmd.Len() == 0 {
+		return
+	}
+	s := base.Ctxt.Lookup(dwarf.CUInfoPrefix + "producer." + base.Ctxt.Pkgpath)
+	s.Type = objabi.SDWARFCUINFO
+	// Sometimes (for example when building tests) we can link
+	// together two package main archives. So allow dups.
+	s.Set(obj.AttrDuplicateOK, true)
+	base.Ctxt.Data = append(base.Ctxt.Data, s)
+	s.P = cmd.Bytes()[1:]
+}
+
+// RecordPackageName records the name of the package being
+// compiled, so that the linker can save it in the compile unit's DIE.
+func RecordPackageName() {
+	s := base.Ctxt.Lookup(dwarf.CUInfoPrefix + "packagename." + base.Ctxt.Pkgpath)
+	s.Type = objabi.SDWARFCUINFO
+	// Sometimes (for example when building tests) we can link
+	// together two package main archives. So allow dups.
+	s.Set(obj.AttrDuplicateOK, true)
+	base.Ctxt.Data = append(base.Ctxt.Data, s)
+	s.P = []byte(types.LocalPkg.Name)
+}
diff --git a/src/cmd/compile/internal/dwarfgen/dwinl.go b/src/cmd/compile/internal/dwarfgen/dwinl.go
new file mode 100644
index 0000000..8adb36f
--- /dev/null
+++ b/src/cmd/compile/internal/dwarfgen/dwinl.go
@@ -0,0 +1,454 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dwarfgen
+
+import (
+	"fmt"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/internal/dwarf"
+	"cmd/internal/obj"
+	"cmd/internal/src"
+)
+
+// 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, dwVars []*dwarf.Var) dwarf.InlCalls {
+	var inlcalls dwarf.InlCalls
+
+	if base.Debug.DwarfInl != 0 {
+		base.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 {
+		var m map[varPos]int
+		if ii == 0 {
+			if !fnsym.WasInlined() {
+				for j, v := range sl {
+					v.ChildIndex = int32(j)
+				}
+				continue
+			}
+			m = makePreinlineDclMap(fnsym)
+		} else {
+			ifnlsym := base.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 _, v := range sl {
+			canonName := unversion(v.Name)
+			vp := varPos{
+				DeclName: canonName,
+				DeclFile: v.DeclFile,
+				DeclLine: v.DeclLine,
+				DeclCol:  v.DeclCol,
+			}
+			synthesized := strings.HasPrefix(v.Name, "~r") || canonName == "_" || strings.HasPrefix(v.Name, "~b")
+			if idx, found := m[vp]; found {
+				v.ChildIndex = int32(idx)
+				v.IsInAbstract = !synthesized
+				v.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 ("_").
+				v.ChildIndex = int32(synthCount)
+				synthCount++
+			}
+		}
+	}
+
+	// Make a second pass through the progs to compute PC ranges for
+	// the various inlined calls.
+	start := int64(-1)
+	curii := -1
+	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
+		}
+		// Close out the current range
+		if start != -1 {
+			addRange(inlcalls.Calls, start, p.Pc, curii, imap)
+		}
+		// Begin new range
+		start = p.Pc
+		curii = ii
+	}
+	if start != -1 {
+		addRange(inlcalls.Calls, start, fnsym.Size, curii, imap)
+	}
+
+	// Issue 33188: if II foo is a child of II bar, then ensure that
+	// bar's ranges include the ranges of foo (the loop above will produce
+	// disjoint ranges).
+	for k, c := range inlcalls.Calls {
+		if c.Root {
+			unifyCallRanges(inlcalls, k)
+		}
+	}
+
+	// Debugging
+	if base.Debug.DwarfInl != 0 {
+		dumpInlCalls(inlcalls)
+		dumpInlVars(dwVars)
+	}
+
+	// Perform a consistency check on inlined routine PC ranges
+	// produced by unifyCallRanges above. In particular, complain in
+	// cases where you have A -> B -> C (e.g. C is inlined into B, and
+	// B is inlined into A) and the ranges for B are not enclosed
+	// within the ranges for A, or C within B.
+	for k, c := range inlcalls.Calls {
+		if c.Root {
+			checkInlCall(fnsym.Name, inlcalls, fnsym.Size, k, -1)
+		}
+	}
+
+	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 AbstractFunc(fn *obj.LSym) {
+	ifn := base.Ctxt.DwFixups.GetPrecursorFunc(fn)
+	if ifn == nil {
+		base.Ctxt.Diag("failed to locate precursor fn for %v", fn)
+		return
+	}
+	_ = ifn.(*ir.Func)
+	if base.Debug.DwarfInl != 0 {
+		base.Ctxt.Logf("DwarfAbstractFunc(%v)\n", fn.Name)
+	}
+	base.Ctxt.DwarfAbstractFunc(ifn, fn, base.Ctxt.Pkgpath)
+}
+
+// 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. NB: the recipe for computing variable pos/file/line
+// needs to be kept in sync with the similar code in gc.createSimpleVars
+// and related functions.
+func makePreinlineDclMap(fnsym *obj.LSym) map[varPos]int {
+	dcl := preInliningDcls(fnsym)
+	m := make(map[varPos]int)
+	for i, n := range dcl {
+		pos := base.Ctxt.InnermostPos(n.Pos())
+		vp := varPos{
+			DeclName: unversion(n.Sym().Name),
+			DeclFile: pos.RelFilename(),
+			DeclLine: pos.RelLine(),
+			DeclCol:  pos.Col(),
+		}
+		if _, found := m[vp]; found {
+			// We can see collisions (variables with the same name/file/line/col) in obfuscated or machine-generated code -- see issue 44378 for an example. Skip duplicates in such cases, since it is unlikely that a human will be debugging such code.
+			continue
+		}
+		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 := base.Ctxt.InlTree.Parent(inlIdx)
+	if parInlIdx >= 0 {
+		parCallIdx = insertInlCall(dwcalls, parInlIdx, imap)
+	}
+
+	// Create new entry for this inline
+	inlinedFn := base.Ctxt.InlTree.InlinedFunction(inlIdx)
+	callXPos := base.Ctxt.InlTree.CallPos(inlIdx)
+	absFnSym := base.Ctxt.DwFixups.AbsFuncDwarfSym(inlinedFn)
+	pb := base.Ctxt.PosTable.Pos(callXPos).Base()
+	callFileSym := base.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 := base.Ctxt.PosTable.Pos(xpos)
+	if b := pos.Base(); b != nil {
+		ii := b.InliningIndex()
+		if ii >= 0 {
+			return ii
+		}
+	}
+	return -1
+}
+
+func addRange(calls []dwarf.InlCall, start, end int64, ii int, imap map[int]int) {
+	if start == -1 {
+		panic("bad range start")
+	}
+	if end == -1 {
+		panic("bad range end")
+	}
+	if ii == -1 {
+		return
+	}
+	if start == end {
+		return
+	}
+	// Append range to correct inlined call
+	callIdx, found := imap[ii]
+	if !found {
+		base.Fatalf("can't find inlIndex %d in imap for prog at %d\n", ii, start)
+	}
+	call := &calls[callIdx]
+	call.Ranges = append(call.Ranges, dwarf.Range{Start: start, End: end})
+}
+
+func dumpInlCall(inlcalls dwarf.InlCalls, idx, ilevel int) {
+	for i := 0; i < ilevel; i++ {
+		base.Ctxt.Logf("  ")
+	}
+	ic := inlcalls.Calls[idx]
+	callee := base.Ctxt.InlTree.InlinedFunction(ic.InlIndex)
+	base.Ctxt.Logf("  %d: II:%d (%s) V: (", idx, ic.InlIndex, callee.Name)
+	for _, f := range ic.InlVars {
+		base.Ctxt.Logf(" %v", f.Name)
+	}
+	base.Ctxt.Logf(" ) C: (")
+	for _, k := range ic.Children {
+		base.Ctxt.Logf(" %v", k)
+	}
+	base.Ctxt.Logf(" ) R:")
+	for _, r := range ic.Ranges {
+		base.Ctxt.Logf(" [%d,%d)", r.Start, r.End)
+	}
+	base.Ctxt.Logf("\n")
+	for _, k := range ic.Children {
+		dumpInlCall(inlcalls, k, ilevel+1)
+	}
+
+}
+
+func dumpInlCalls(inlcalls dwarf.InlCalls) {
+	for k, c := range inlcalls.Calls {
+		if c.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
+		}
+		base.Ctxt.Logf("V%d: %s CI:%d II:%d IA:%d %s\n", i, dwv.Name, dwv.ChildIndex, dwv.InlIndex-1, ia, typ)
+	}
+}
+
+func rangesContains(par []dwarf.Range, rng dwarf.Range) (bool, string) {
+	for _, r := range par {
+		if rng.Start >= r.Start && rng.End <= r.End {
+			return true, ""
+		}
+	}
+	msg := fmt.Sprintf("range [%d,%d) not contained in {", rng.Start, rng.End)
+	for _, r := range par {
+		msg += fmt.Sprintf(" [%d,%d)", r.Start, r.End)
+	}
+	msg += " }"
+	return false, msg
+}
+
+func rangesContainsAll(parent, child []dwarf.Range) (bool, string) {
+	for _, r := range child {
+		c, m := rangesContains(parent, r)
+		if !c {
+			return false, m
+		}
+	}
+	return true, ""
+}
+
+// checkInlCall verifies that the PC ranges for inline info 'idx' are
+// enclosed/contained within the ranges of its parent inline (or if
+// this is a root/toplevel inline, checks that the ranges fall within
+// the extent of the top level function). A panic is issued if a
+// malformed range is found.
+func checkInlCall(funcName string, inlCalls dwarf.InlCalls, funcSize int64, idx, parentIdx int) {
+
+	// Callee
+	ic := inlCalls.Calls[idx]
+	callee := base.Ctxt.InlTree.InlinedFunction(ic.InlIndex).Name
+	calleeRanges := ic.Ranges
+
+	// Caller
+	caller := funcName
+	parentRanges := []dwarf.Range{dwarf.Range{Start: int64(0), End: funcSize}}
+	if parentIdx != -1 {
+		pic := inlCalls.Calls[parentIdx]
+		caller = base.Ctxt.InlTree.InlinedFunction(pic.InlIndex).Name
+		parentRanges = pic.Ranges
+	}
+
+	// Callee ranges contained in caller ranges?
+	c, m := rangesContainsAll(parentRanges, calleeRanges)
+	if !c {
+		base.Fatalf("** malformed inlined routine range in %s: caller %s callee %s II=%d %s\n", funcName, caller, callee, idx, m)
+	}
+
+	// Now visit kids
+	for _, k := range ic.Children {
+		checkInlCall(funcName, inlCalls, funcSize, k, idx)
+	}
+}
+
+// unifyCallRanges ensures that the ranges for a given inline
+// transitively include all of the ranges for its child inlines.
+func unifyCallRanges(inlcalls dwarf.InlCalls, idx int) {
+	ic := &inlcalls.Calls[idx]
+	for _, childIdx := range ic.Children {
+		// First make sure child ranges are unified.
+		unifyCallRanges(inlcalls, childIdx)
+
+		// Then merge child ranges into ranges for this inline.
+		cic := inlcalls.Calls[childIdx]
+		ic.Ranges = dwarf.MergeRanges(ic.Ranges, cic.Ranges)
+	}
+}
diff --git a/src/cmd/compile/internal/dwarfgen/marker.go b/src/cmd/compile/internal/dwarfgen/marker.go
new file mode 100644
index 0000000..ec6ce45
--- /dev/null
+++ b/src/cmd/compile/internal/dwarfgen/marker.go
@@ -0,0 +1,94 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dwarfgen
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/internal/src"
+)
+
+// A ScopeMarker tracks scope nesting and boundaries for later use
+// during DWARF generation.
+type ScopeMarker struct {
+	parents []ir.ScopeID
+	marks   []ir.Mark
+}
+
+// checkPos validates the given position and returns the current scope.
+func (m *ScopeMarker) checkPos(pos src.XPos) ir.ScopeID {
+	if !pos.IsKnown() {
+		base.Fatalf("unknown scope position")
+	}
+
+	if len(m.marks) == 0 {
+		return 0
+	}
+
+	last := &m.marks[len(m.marks)-1]
+	if xposBefore(pos, last.Pos) {
+		base.FatalfAt(pos, "non-monotonic scope positions\n\t%v: previous scope position", base.FmtPos(last.Pos))
+	}
+	return last.Scope
+}
+
+// Push records a transition to a new child scope of the current scope.
+func (m *ScopeMarker) Push(pos src.XPos) {
+	current := m.checkPos(pos)
+
+	m.parents = append(m.parents, current)
+	child := ir.ScopeID(len(m.parents))
+
+	m.marks = append(m.marks, ir.Mark{Pos: pos, Scope: child})
+}
+
+// Pop records a transition back to the current scope's parent.
+func (m *ScopeMarker) Pop(pos src.XPos) {
+	current := m.checkPos(pos)
+
+	parent := m.parents[current-1]
+
+	m.marks = append(m.marks, ir.Mark{Pos: pos, Scope: parent})
+}
+
+// Unpush removes the current scope, which must be empty.
+func (m *ScopeMarker) Unpush() {
+	i := len(m.marks) - 1
+	current := m.marks[i].Scope
+
+	if current != ir.ScopeID(len(m.parents)) {
+		base.FatalfAt(m.marks[i].Pos, "current scope is not empty")
+	}
+
+	m.parents = m.parents[:current-1]
+	m.marks = m.marks[:i]
+}
+
+// WriteTo writes the recorded scope marks to the given function,
+// and resets the marker for reuse.
+func (m *ScopeMarker) WriteTo(fn *ir.Func) {
+	m.compactMarks()
+
+	fn.Parents = make([]ir.ScopeID, len(m.parents))
+	copy(fn.Parents, m.parents)
+	m.parents = m.parents[:0]
+
+	fn.Marks = make([]ir.Mark, len(m.marks))
+	copy(fn.Marks, m.marks)
+	m.marks = m.marks[:0]
+}
+
+func (m *ScopeMarker) compactMarks() {
+	n := 0
+	for _, next := range m.marks {
+		if n > 0 && next.Pos == m.marks[n-1].Pos {
+			m.marks[n-1].Scope = next.Scope
+			continue
+		}
+		m.marks[n] = next
+		n++
+	}
+	m.marks = m.marks[:n]
+}
diff --git a/src/cmd/compile/internal/dwarfgen/scope.go b/src/cmd/compile/internal/dwarfgen/scope.go
new file mode 100644
index 0000000..b4ae69e
--- /dev/null
+++ b/src/cmd/compile/internal/dwarfgen/scope.go
@@ -0,0 +1,136 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dwarfgen
+
+import (
+	"sort"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/internal/dwarf"
+	"cmd/internal/obj"
+	"cmd/internal/src"
+)
+
+// See golang.org/issue/20390.
+func xposBefore(p, q src.XPos) bool {
+	return base.Ctxt.PosTable.Pos(p).Before(base.Ctxt.PosTable.Pos(q))
+}
+
+func findScope(marks []ir.Mark, pos src.XPos) ir.ScopeID {
+	i := sort.Search(len(marks), func(i int) bool {
+		return xposBefore(pos, marks[i].Pos)
+	})
+	if i == 0 {
+		return 0
+	}
+	return marks[i-1].Scope
+}
+
+func assembleScopes(fnsym *obj.LSym, fn *ir.Func, dwarfVars []*dwarf.Var, varScopes []ir.ScopeID) []dwarf.Scope {
+	// Initialize the DWARF scope tree based on lexical scopes.
+	dwarfScopes := make([]dwarf.Scope, 1+len(fn.Parents))
+	for i, parent := range fn.Parents {
+		dwarfScopes[i+1].Parent = int32(parent)
+	}
+
+	scopeVariables(dwarfVars, varScopes, dwarfScopes, fnsym.ABI() != obj.ABI0)
+	if fnsym.Func().Text != nil {
+		scopePCs(fnsym, fn.Marks, dwarfScopes)
+	}
+	return compactScopes(dwarfScopes)
+}
+
+// scopeVariables assigns DWARF variable records to their scopes.
+func scopeVariables(dwarfVars []*dwarf.Var, varScopes []ir.ScopeID, dwarfScopes []dwarf.Scope, regabi bool) {
+	if regabi {
+		sort.Stable(varsByScope{dwarfVars, varScopes})
+	} else {
+		sort.Stable(varsByScopeAndOffset{dwarfVars, varScopes})
+	}
+
+	i0 := 0
+	for i := range dwarfVars {
+		if varScopes[i] == varScopes[i0] {
+			continue
+		}
+		dwarfScopes[varScopes[i0]].Vars = dwarfVars[i0:i]
+		i0 = i
+	}
+	if i0 < len(dwarfVars) {
+		dwarfScopes[varScopes[i0]].Vars = dwarfVars[i0:]
+	}
+}
+
+// scopePCs assigns PC ranges to their scopes.
+func scopePCs(fnsym *obj.LSym, marks []ir.Mark, dwarfScopes []dwarf.Scope) {
+	// If there aren't any child scopes (in particular, when scope
+	// tracking is disabled), we can skip a whole lot of work.
+	if len(marks) == 0 {
+		return
+	}
+	p0 := fnsym.Func().Text
+	scope := findScope(marks, p0.Pos)
+	for p := p0; p != nil; p = p.Link {
+		if p.Pos == p0.Pos {
+			continue
+		}
+		dwarfScopes[scope].AppendRange(dwarf.Range{Start: p0.Pc, End: p.Pc})
+		p0 = p
+		scope = findScope(marks, p0.Pos)
+	}
+	if p0.Pc < fnsym.Size {
+		dwarfScopes[scope].AppendRange(dwarf.Range{Start: p0.Pc, End: fnsym.Size})
+	}
+}
+
+func compactScopes(dwarfScopes []dwarf.Scope) []dwarf.Scope {
+	// Reverse pass to propagate PC ranges to parent scopes.
+	for i := len(dwarfScopes) - 1; i > 0; i-- {
+		s := &dwarfScopes[i]
+		dwarfScopes[s.Parent].UnifyRanges(s)
+	}
+
+	return dwarfScopes
+}
+
+type varsByScopeAndOffset struct {
+	vars   []*dwarf.Var
+	scopes []ir.ScopeID
+}
+
+func (v varsByScopeAndOffset) Len() int {
+	return len(v.vars)
+}
+
+func (v varsByScopeAndOffset) Less(i, j int) bool {
+	if v.scopes[i] != v.scopes[j] {
+		return v.scopes[i] < v.scopes[j]
+	}
+	return v.vars[i].StackOffset < v.vars[j].StackOffset
+}
+
+func (v varsByScopeAndOffset) Swap(i, j int) {
+	v.vars[i], v.vars[j] = v.vars[j], v.vars[i]
+	v.scopes[i], v.scopes[j] = v.scopes[j], v.scopes[i]
+}
+
+type varsByScope struct {
+	vars   []*dwarf.Var
+	scopes []ir.ScopeID
+}
+
+func (v varsByScope) Len() int {
+	return len(v.vars)
+}
+
+func (v varsByScope) Less(i, j int) bool {
+	return v.scopes[i] < v.scopes[j]
+}
+
+func (v varsByScope) Swap(i, j int) {
+	v.vars[i], v.vars[j] = v.vars[j], v.vars[i]
+	v.scopes[i], v.scopes[j] = v.scopes[j], v.scopes[i]
+}
diff --git a/src/cmd/compile/internal/dwarfgen/scope_test.go b/src/cmd/compile/internal/dwarfgen/scope_test.go
new file mode 100644
index 0000000..3df4c34
--- /dev/null
+++ b/src/cmd/compile/internal/dwarfgen/scope_test.go
@@ -0,0 +1,539 @@
+// 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 dwarfgen
+
+import (
+	"debug/dwarf"
+	"fmt"
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"sort"
+	"strconv"
+	"strings"
+	"testing"
+
+	"cmd/internal/objfile"
+)
+
+type testline struct {
+	// line is one line of go source
+	line string
+
+	// scopes is a list of scope IDs of all the lexical scopes that this line
+	// of code belongs to.
+	// Scope IDs are assigned by traversing the tree of lexical blocks of a
+	// function in pre-order
+	// Scope IDs are function specific, i.e. scope 0 is always the root scope
+	// of the function that this line belongs to. Empty scopes are not assigned
+	// an ID (because they are not saved in debug_info).
+	// Scope 0 is always omitted from this list since all lines always belong
+	// to it.
+	scopes []int
+
+	// vars is the list of variables that belong in scopes[len(scopes)-1].
+	// Local variables are prefixed with "var ", formal parameters with "arg ".
+	// Must be ordered alphabetically.
+	// Set to nil to skip the check.
+	vars []string
+
+	// decl is the list of variables declared at this line.
+	decl []string
+
+	// declBefore is the list of variables declared at or before this line.
+	declBefore []string
+}
+
+var testfile = []testline{
+	{line: "package main"},
+	{line: "func f1(x int) { }"},
+	{line: "func f2(x int) { }"},
+	{line: "func f3(x int) { }"},
+	{line: "func f4(x int) { }"},
+	{line: "func f5(x int) { }"},
+	{line: "func f6(x int) { }"},
+	{line: "func fi(x interface{}) { if a, ok := x.(error); ok { a.Error() } }"},
+	{line: "func gret1() int { return 2 }"},
+	{line: "func gretbool() bool { return true }"},
+	{line: "func gret3() (int, int, int) { return 0, 1, 2 }"},
+	{line: "var v = []int{ 0, 1, 2 }"},
+	{line: "var ch = make(chan int)"},
+	{line: "var floatch = make(chan float64)"},
+	{line: "var iface interface{}"},
+	{line: "func TestNestedFor() {", vars: []string{"var a int"}},
+	{line: "	a := 0", decl: []string{"a"}},
+	{line: "	f1(a)"},
+	{line: "	for i := 0; i < 5; i++ {", scopes: []int{1}, vars: []string{"var i int"}, decl: []string{"i"}},
+	{line: "		f2(i)", scopes: []int{1}},
+	{line: "		for i := 0; i < 5; i++ {", scopes: []int{1, 2}, vars: []string{"var i int"}, decl: []string{"i"}},
+	{line: "			f3(i)", scopes: []int{1, 2}},
+	{line: "		}"},
+	{line: "		f4(i)", scopes: []int{1}},
+	{line: "	}"},
+	{line: "	f5(a)"},
+	{line: "}"},
+	{line: "func TestOas2() {", vars: []string{}},
+	{line: "	if a, b, c := gret3(); a != 1 {", scopes: []int{1}, vars: []string{"var a int", "var b int", "var c int"}},
+	{line: "		f1(a)", scopes: []int{1}},
+	{line: "		f1(b)", scopes: []int{1}},
+	{line: "		f1(c)", scopes: []int{1}},
+	{line: "	}"},
+	{line: "	for i, x := range v {", scopes: []int{2}, vars: []string{"var i int", "var x int"}},
+	{line: "		f1(i)", scopes: []int{2}},
+	{line: "		f1(x)", scopes: []int{2}},
+	{line: "	}"},
+	{line: "	if a, ok := <- ch; ok {", scopes: []int{3}, vars: []string{"var a int", "var ok bool"}},
+	{line: "		f1(a)", scopes: []int{3}},
+	{line: "	}"},
+	{line: "	if a, ok := iface.(int); ok {", scopes: []int{4}, vars: []string{"var a int", "var ok bool"}},
+	{line: "		f1(a)", scopes: []int{4}},
+	{line: "	}"},
+	{line: "}"},
+	{line: "func TestIfElse() {"},
+	{line: "	if x := gret1(); x != 0 {", scopes: []int{1}, vars: []string{"var x int"}},
+	{line: "		a := 0", scopes: []int{1, 2}, vars: []string{"var a int"}},
+	{line: "		f1(a); f1(x)", scopes: []int{1, 2}},
+	{line: "	} else {"},
+	{line: "		b := 1", scopes: []int{1, 3}, vars: []string{"var b int"}},
+	{line: "		f1(b); f1(x+1)", scopes: []int{1, 3}},
+	{line: "	}"},
+	{line: "}"},
+	{line: "func TestSwitch() {", vars: []string{}},
+	{line: "	switch x := gret1(); x {", scopes: []int{1}, vars: []string{"var x int"}},
+	{line: "	case 0:", scopes: []int{1, 2}},
+	{line: "		i := x + 5", scopes: []int{1, 2}, vars: []string{"var i int"}},
+	{line: "		f1(x); f1(i)", scopes: []int{1, 2}},
+	{line: "	case 1:", scopes: []int{1, 3}},
+	{line: "		j := x + 10", scopes: []int{1, 3}, vars: []string{"var j int"}},
+	{line: "		f1(x); f1(j)", scopes: []int{1, 3}},
+	{line: "	case 2:", scopes: []int{1, 4}},
+	{line: "		k := x + 2", scopes: []int{1, 4}, vars: []string{"var k int"}},
+	{line: "		f1(x); f1(k)", scopes: []int{1, 4}},
+	{line: "	}"},
+	{line: "}"},
+	{line: "func TestTypeSwitch() {", vars: []string{}},
+	{line: "	switch x := iface.(type) {"},
+	{line: "	case int:", scopes: []int{1}},
+	{line: "		f1(x)", scopes: []int{1}, vars: []string{"var x int"}},
+	{line: "	case uint8:", scopes: []int{2}},
+	{line: "		f1(int(x))", scopes: []int{2}, vars: []string{"var x uint8"}},
+	{line: "	case float64:", scopes: []int{3}},
+	{line: "		f1(int(x)+1)", scopes: []int{3}, vars: []string{"var x float64"}},
+	{line: "	}"},
+	{line: "}"},
+	{line: "func TestSelectScope() {"},
+	{line: "	select {"},
+	{line: "	case i := <- ch:", scopes: []int{1}},
+	{line: "		f1(i)", scopes: []int{1}, vars: []string{"var i int"}},
+	{line: "	case f := <- floatch:", scopes: []int{2}},
+	{line: "		f1(int(f))", scopes: []int{2}, vars: []string{"var f float64"}},
+	{line: "	}"},
+	{line: "}"},
+	{line: "func TestBlock() {", vars: []string{"var a int"}},
+	{line: "	a := 1"},
+	{line: "	{"},
+	{line: "		b := 2", scopes: []int{1}, vars: []string{"var b int"}},
+	{line: "		f1(b)", scopes: []int{1}},
+	{line: "		f1(a)", scopes: []int{1}},
+	{line: "	}"},
+	{line: "}"},
+	{line: "func TestDiscontiguousRanges() {", vars: []string{"var a int"}},
+	{line: "	a := 0"},
+	{line: "	f1(a)"},
+	{line: "	{"},
+	{line: "		b := 0", scopes: []int{1}, vars: []string{"var b int"}},
+	{line: "		f2(b)", scopes: []int{1}},
+	{line: "		if gretbool() {", scopes: []int{1}},
+	{line: "			c := 0", scopes: []int{1, 2}, vars: []string{"var c int"}},
+	{line: "			f3(c)", scopes: []int{1, 2}},
+	{line: "		} else {"},
+	{line: "			c := 1.1", scopes: []int{1, 3}, vars: []string{"var c float64"}},
+	{line: "			f4(int(c))", scopes: []int{1, 3}},
+	{line: "		}"},
+	{line: "		f5(b)", scopes: []int{1}},
+	{line: "	}"},
+	{line: "	f6(a)"},
+	{line: "}"},
+	{line: "func TestClosureScope() {", vars: []string{"var a int", "var b int", "var f func(int)"}},
+	{line: "	a := 1; b := 1"},
+	{line: "	f := func(c int) {", scopes: []int{0}, vars: []string{"arg c int", "var &b *int", "var a int", "var d int"}, declBefore: []string{"&b", "a"}},
+	{line: "		d := 3"},
+	{line: "		f1(c); f1(d)"},
+	{line: "		if e := 3; e != 0 {", scopes: []int{1}, vars: []string{"var e int"}},
+	{line: "			f1(e)", scopes: []int{1}},
+	{line: "			f1(a)", scopes: []int{1}},
+	{line: "			b = 2", scopes: []int{1}},
+	{line: "		}"},
+	{line: "	}"},
+	{line: "	f(3); f1(b)"},
+	{line: "}"},
+	{line: "func TestEscape() {"},
+	{line: "	a := 1", vars: []string{"var a int"}},
+	{line: "	{"},
+	{line: "		b := 2", scopes: []int{1}, vars: []string{"var &b *int", "var p *int"}},
+	{line: "		p := &b", scopes: []int{1}},
+	{line: "		f1(a)", scopes: []int{1}},
+	{line: "		fi(p)", scopes: []int{1}},
+	{line: "	}"},
+	{line: "}"},
+	{line: "var fglob func() int"},
+	{line: "func TestCaptureVar(flag bool) {"},
+	{line: "	a := 1", vars: []string{"arg flag bool", "var a int"}}, // TODO(register args) restore "arg ~r1 func() 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: "		fglob = f", scopes: []int{1}},
+	{line: "	}"},
+	{line: "	f1(a)"},
+	{line: "}"},
+	{line: "func main() {"},
+	{line: "	TestNestedFor()"},
+	{line: "	TestOas2()"},
+	{line: "	TestIfElse()"},
+	{line: "	TestSwitch()"},
+	{line: "	TestTypeSwitch()"},
+	{line: "	TestSelectScope()"},
+	{line: "	TestBlock()"},
+	{line: "	TestDiscontiguousRanges()"},
+	{line: "	TestClosureScope()"},
+	{line: "	TestEscape()"},
+	{line: "	TestCaptureVar(true)"},
+	{line: "}"},
+}
+
+const detailOutput = false
+
+// Compiles testfile checks that the description of lexical blocks emitted
+// by the linker in debug_info, for each function in the main package,
+// corresponds to what we expect it to be.
+func TestScopeRanges(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+	t.Parallel()
+
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; no DWARF symbol table in executables")
+	}
+
+	dir, err := ioutil.TempDir("", "TestScopeRanges")
+	if err != nil {
+		t.Fatalf("could not create directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	src, f := gobuild(t, dir, false, testfile)
+	defer f.Close()
+
+	// the compiler uses forward slashes for paths even on windows
+	src = strings.Replace(src, "\\", "/", -1)
+
+	pcln, err := f.PCLineTable()
+	if err != nil {
+		t.Fatal(err)
+	}
+	dwarfData, err := f.DWARF()
+	if err != nil {
+		t.Fatal(err)
+	}
+	dwarfReader := dwarfData.Reader()
+
+	lines := make(map[line][]*lexblock)
+
+	for {
+		entry, err := dwarfReader.Next()
+		if err != nil {
+			t.Fatal(err)
+		}
+		if entry == nil {
+			break
+		}
+
+		if entry.Tag != dwarf.TagSubprogram {
+			continue
+		}
+
+		name, ok := entry.Val(dwarf.AttrName).(string)
+		if !ok || !strings.HasPrefix(name, "main.Test") {
+			continue
+		}
+
+		var scope lexblock
+		ctxt := scopexplainContext{
+			dwarfData:   dwarfData,
+			dwarfReader: dwarfReader,
+			scopegen:    1,
+		}
+
+		readScope(&ctxt, &scope, entry)
+
+		scope.markLines(pcln, lines)
+	}
+
+	anyerror := false
+	for i := range testfile {
+		tgt := testfile[i].scopes
+		out := lines[line{src, i + 1}]
+
+		if detailOutput {
+			t.Logf("%s // %v", testfile[i].line, out)
+		}
+
+		scopesok := checkScopes(tgt, out)
+		if !scopesok {
+			t.Logf("mismatch at line %d %q: expected: %v got: %v\n", i, testfile[i].line, tgt, scopesToString(out))
+		}
+
+		varsok := true
+		if testfile[i].vars != nil {
+			if len(out) > 0 {
+				varsok = checkVars(testfile[i].vars, out[len(out)-1].vars)
+				if !varsok {
+					t.Logf("variable mismatch at line %d %q for scope %d: expected: %v got: %v\n", i+1, testfile[i].line, out[len(out)-1].id, testfile[i].vars, out[len(out)-1].vars)
+				}
+				for j := range testfile[i].decl {
+					if line := declLineForVar(out[len(out)-1].vars, testfile[i].decl[j]); line != i+1 {
+						t.Errorf("wrong declaration line for variable %s, expected %d got: %d", testfile[i].decl[j], i+1, line)
+					}
+				}
+
+				for j := range testfile[i].declBefore {
+					if line := declLineForVar(out[len(out)-1].vars, testfile[i].declBefore[j]); line > i+1 {
+						t.Errorf("wrong declaration line for variable %s, expected %d (or less) got: %d", testfile[i].declBefore[j], i+1, line)
+					}
+				}
+			}
+		}
+
+		anyerror = anyerror || !scopesok || !varsok
+	}
+
+	if anyerror {
+		t.Fatalf("mismatched output")
+	}
+}
+
+func scopesToString(v []*lexblock) string {
+	r := make([]string, len(v))
+	for i, s := range v {
+		r[i] = strconv.Itoa(s.id)
+	}
+	return "[ " + strings.Join(r, ", ") + " ]"
+}
+
+func checkScopes(tgt []int, out []*lexblock) bool {
+	if len(out) > 0 {
+		// omit scope 0
+		out = out[1:]
+	}
+	if len(tgt) != len(out) {
+		return false
+	}
+	for i := range tgt {
+		if tgt[i] != out[i].id {
+			return false
+		}
+	}
+	return true
+}
+
+func checkVars(tgt []string, out []variable) bool {
+	if len(tgt) != len(out) {
+		return false
+	}
+	for i := range tgt {
+		if tgt[i] != out[i].expr {
+			return false
+		}
+	}
+	return true
+}
+
+func declLineForVar(scope []variable, name string) int {
+	for i := range scope {
+		if scope[i].name() == name {
+			return scope[i].declLine
+		}
+	}
+	return -1
+}
+
+type lexblock struct {
+	id     int
+	ranges [][2]uint64
+	vars   []variable
+	scopes []lexblock
+}
+
+type variable struct {
+	expr     string
+	declLine int
+}
+
+func (v *variable) name() string {
+	return strings.Split(v.expr, " ")[1]
+}
+
+type line struct {
+	file   string
+	lineno int
+}
+
+type scopexplainContext struct {
+	dwarfData   *dwarf.Data
+	dwarfReader *dwarf.Reader
+	scopegen    int
+}
+
+// readScope reads the DW_TAG_lexical_block or the DW_TAG_subprogram in
+// entry and writes a description in scope.
+// Nested DW_TAG_lexical_block entries are read recursively.
+func readScope(ctxt *scopexplainContext, scope *lexblock, entry *dwarf.Entry) {
+	var err error
+	scope.ranges, err = ctxt.dwarfData.Ranges(entry)
+	if err != nil {
+		panic(err)
+	}
+	for {
+		e, err := ctxt.dwarfReader.Next()
+		if err != nil {
+			panic(err)
+		}
+		switch e.Tag {
+		case 0:
+			sort.Slice(scope.vars, func(i, j int) bool {
+				return scope.vars[i].expr < scope.vars[j].expr
+			})
+			return
+		case dwarf.TagFormalParameter:
+			typ, err := ctxt.dwarfData.Type(e.Val(dwarf.AttrType).(dwarf.Offset))
+			if err != nil {
+				panic(err)
+			}
+			scope.vars = append(scope.vars, entryToVar(e, "arg", typ))
+		case dwarf.TagVariable:
+			typ, err := ctxt.dwarfData.Type(e.Val(dwarf.AttrType).(dwarf.Offset))
+			if err != nil {
+				panic(err)
+			}
+			scope.vars = append(scope.vars, entryToVar(e, "var", typ))
+		case dwarf.TagLexDwarfBlock:
+			scope.scopes = append(scope.scopes, lexblock{id: ctxt.scopegen})
+			ctxt.scopegen++
+			readScope(ctxt, &scope.scopes[len(scope.scopes)-1], e)
+		}
+	}
+}
+
+func entryToVar(e *dwarf.Entry, kind string, typ dwarf.Type) variable {
+	return variable{
+		fmt.Sprintf("%s %s %s", kind, e.Val(dwarf.AttrName).(string), typ.String()),
+		int(e.Val(dwarf.AttrDeclLine).(int64)),
+	}
+}
+
+// markLines marks all lines that belong to this scope with this scope
+// Recursively calls markLines for all children scopes.
+func (scope *lexblock) markLines(pcln objfile.Liner, lines map[line][]*lexblock) {
+	for _, r := range scope.ranges {
+		for pc := r[0]; pc < r[1]; pc++ {
+			file, lineno, _ := pcln.PCToLine(pc)
+			l := line{file, lineno}
+			if len(lines[l]) == 0 || lines[l][len(lines[l])-1] != scope {
+				lines[l] = append(lines[l], scope)
+			}
+		}
+	}
+
+	for i := range scope.scopes {
+		scope.scopes[i].markLines(pcln, lines)
+	}
+}
+
+func gobuild(t *testing.T, dir string, optimized bool, testfile []testline) (string, *objfile.File) {
+	src := filepath.Join(dir, "test.go")
+	dst := filepath.Join(dir, "out.o")
+
+	f, err := os.Create(src)
+	if err != nil {
+		t.Fatal(err)
+	}
+	for i := range testfile {
+		f.Write([]byte(testfile[i].line))
+		f.Write([]byte{'\n'})
+	}
+	f.Close()
+
+	args := []string{"build"}
+	if !optimized {
+		args = append(args, "-gcflags=-N -l")
+	}
+	args = append(args, "-o", dst, src)
+
+	cmd := exec.Command(testenv.GoToolPath(t), args...)
+	if b, err := cmd.CombinedOutput(); err != nil {
+		t.Logf("build: %s\n", string(b))
+		t.Fatal(err)
+	}
+
+	pkg, err := objfile.Open(dst)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return src, pkg
+}
+
+// TestEmptyDwarfRanges tests that no list entry in debug_ranges has start == end.
+// See issue #23928.
+func TestEmptyDwarfRanges(t *testing.T) {
+	testenv.MustHaveGoRun(t)
+	t.Parallel()
+
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; no DWARF symbol table in executables")
+	}
+
+	dir, err := ioutil.TempDir("", "TestEmptyDwarfRanges")
+	if err != nil {
+		t.Fatalf("could not create directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	_, f := gobuild(t, dir, true, []testline{{line: "package main"}, {line: "func main(){ println(\"hello\") }"}})
+	defer f.Close()
+
+	dwarfData, err := f.DWARF()
+	if err != nil {
+		t.Fatal(err)
+	}
+	dwarfReader := dwarfData.Reader()
+
+	for {
+		entry, err := dwarfReader.Next()
+		if err != nil {
+			t.Fatal(err)
+		}
+		if entry == nil {
+			break
+		}
+
+		ranges, err := dwarfData.Ranges(entry)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if ranges == nil {
+			continue
+		}
+
+		for _, rng := range ranges {
+			if rng[0] == rng[1] {
+				t.Errorf("range entry with start == end: %v", rng)
+			}
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/escape/escape.go b/src/cmd/compile/internal/escape/escape.go
new file mode 100644
index 0000000..cd56f07
--- /dev/null
+++ b/src/cmd/compile/internal/escape/escape.go
@@ -0,0 +1,2149 @@
+// 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 escape
+
+import (
+	"fmt"
+	"math"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/logopt"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// Escape analysis.
+//
+// Here we analyze functions to determine which Go variables
+// (including implicit allocations such as calls to "new" or "make",
+// composite literals, etc.) can be allocated on the stack. The two
+// key invariants we have to ensure are: (1) pointers to stack objects
+// cannot be stored in the heap, and (2) pointers to a stack object
+// cannot outlive that object (e.g., because the declaring function
+// returned and destroyed the object's stack frame, or its space is
+// reused across loop iterations for logically distinct variables).
+//
+// We implement this with a static data-flow analysis of the AST.
+// First, we construct a directed weighted graph where vertices
+// (termed "locations") represent variables allocated by statements
+// and expressions, and edges represent assignments between variables
+// (with weights representing addressing/dereference counts).
+//
+// Next we walk the graph looking for assignment paths that might
+// violate the invariants stated above. If a variable v's address is
+// stored in the heap or elsewhere that may outlive it, then v is
+// marked as requiring heap allocation.
+//
+// To support interprocedural analysis, we also record data-flow from
+// each function's parameters to the heap and to its result
+// parameters. This information is summarized as "parameter tags",
+// which are used at static call sites to improve escape analysis of
+// function arguments.
+
+// Constructing the location graph.
+//
+// Every allocating statement (e.g., variable declaration) or
+// expression (e.g., "new" or "make") is first mapped to a unique
+// "location."
+//
+// We also model every Go assignment as a directed edges between
+// locations. The number of dereference operations minus the number of
+// addressing operations is recorded as the edge's weight (termed
+// "derefs"). For example:
+//
+//     p = &q    // -1
+//     p = q     //  0
+//     p = *q    //  1
+//     p = **q   //  2
+//
+//     p = **&**&q  // 2
+//
+// Note that the & operator can only be applied to addressable
+// expressions, and the expression &x itself is not addressable, so
+// derefs cannot go below -1.
+//
+// Every Go language construct is lowered into this representation,
+// generally without sensitivity to flow, path, or context; and
+// without distinguishing elements within a compound variable. For
+// example:
+//
+//     var x struct { f, g *int }
+//     var u []*int
+//
+//     x.f = u[0]
+//
+// is modeled simply as
+//
+//     x = *u
+//
+// That is, we don't distinguish x.f from x.g, or u[0] from u[1],
+// u[2], etc. However, we do record the implicit dereference involved
+// in indexing a slice.
+
+// A batch holds escape analysis state that's shared across an entire
+// batch of functions being analyzed at once.
+type batch struct {
+	allLocs  []*location
+	closures []closure
+
+	heapLoc  location
+	blankLoc location
+}
+
+// A closure holds a closure expression and its spill hole (i.e.,
+// where the hole representing storing into its closure record).
+type closure struct {
+	k   hole
+	clo *ir.ClosureExpr
+}
+
+// An escape holds state specific to a single function being analyzed
+// within a batch.
+type escape struct {
+	*batch
+
+	curfn *ir.Func // function being analyzed
+
+	labels map[*types.Sym]labelState // known labels
+
+	// loopDepth counts the current loop nesting depth within
+	// curfn. It increments within each "for" loop and at each
+	// label with a corresponding backwards "goto" (i.e.,
+	// unstructured loop).
+	loopDepth int
+}
+
+// An location represents an abstract location that stores a Go
+// variable.
+type location struct {
+	n         ir.Node  // represented variable or expression, if any
+	curfn     *ir.Func // enclosing function
+	edges     []edge   // incoming edges
+	loopDepth int      // loopDepth at declaration
+
+	// resultIndex records the tuple index (starting at 1) for
+	// PPARAMOUT variables within their function's result type.
+	// For non-PPARAMOUT variables it's 0.
+	resultIndex int
+
+	// derefs and walkgen are used during walkOne to track the
+	// minimal dereferences from the walk root.
+	derefs  int // >= -1
+	walkgen uint32
+
+	// dst and dstEdgeindex track the next immediate assignment
+	// destination location during walkone, along with the index
+	// of the edge pointing back to this location.
+	dst        *location
+	dstEdgeIdx int
+
+	// queued is used by walkAll to track whether this location is
+	// in the walk queue.
+	queued bool
+
+	// escapes reports whether the represented variable's address
+	// escapes; that is, whether the variable must be heap
+	// allocated.
+	escapes bool
+
+	// transient reports whether the represented expression's
+	// address does not outlive the statement; that is, whether
+	// its storage can be immediately reused.
+	transient bool
+
+	// paramEsc records the represented parameter's leak set.
+	paramEsc leaks
+
+	captured   bool // has a closure captured this variable?
+	reassigned bool // has this variable been reassigned?
+	addrtaken  bool // has this variable's address been taken?
+}
+
+// An edge represents an assignment edge between two Go variables.
+type edge struct {
+	src    *location
+	derefs int // >= -1
+	notes  *note
+}
+
+// Fmt is called from node printing to print information about escape analysis results.
+func Fmt(n ir.Node) string {
+	text := ""
+	switch n.Esc() {
+	case ir.EscUnknown:
+		break
+
+	case ir.EscHeap:
+		text = "esc(h)"
+
+	case ir.EscNone:
+		text = "esc(no)"
+
+	case ir.EscNever:
+		text = "esc(N)"
+
+	default:
+		text = fmt.Sprintf("esc(%d)", n.Esc())
+	}
+
+	if n.Op() == ir.ONAME {
+		n := n.(*ir.Name)
+		if loc, ok := n.Opt.(*location); ok && loc.loopDepth != 0 {
+			if text != "" {
+				text += " "
+			}
+			text += fmt.Sprintf("ld(%d)", loc.loopDepth)
+		}
+	}
+
+	return text
+}
+
+// Batch performs escape analysis on a minimal batch of
+// functions.
+func Batch(fns []*ir.Func, recursive bool) {
+	for _, fn := range fns {
+		if fn.Op() != ir.ODCLFUNC {
+			base.Fatalf("unexpected node: %v", fn)
+		}
+	}
+
+	var b batch
+	b.heapLoc.escapes = true
+
+	// Construct data-flow graph from syntax trees.
+	for _, fn := range fns {
+		if base.Flag.W > 1 {
+			s := fmt.Sprintf("\nbefore escape %v", fn)
+			ir.Dump(s, fn)
+		}
+		b.initFunc(fn)
+	}
+	for _, fn := range fns {
+		if !fn.IsHiddenClosure() {
+			b.walkFunc(fn)
+		}
+	}
+
+	// We've walked the function bodies, so we've seen everywhere a
+	// variable might be reassigned or have it's address taken. Now we
+	// can decide whether closures should capture their free variables
+	// by value or reference.
+	for _, closure := range b.closures {
+		b.flowClosure(closure.k, closure.clo)
+	}
+	b.closures = nil
+
+	for _, loc := range b.allLocs {
+		if why := HeapAllocReason(loc.n); why != "" {
+			b.flow(b.heapHole().addr(loc.n, why), loc)
+		}
+	}
+
+	b.walkAll()
+	b.finish(fns)
+}
+
+func (b *batch) with(fn *ir.Func) *escape {
+	return &escape{
+		batch:     b,
+		curfn:     fn,
+		loopDepth: 1,
+	}
+}
+
+func (b *batch) initFunc(fn *ir.Func) {
+	e := b.with(fn)
+	if fn.Esc() != escFuncUnknown {
+		base.Fatalf("unexpected node: %v", fn)
+	}
+	fn.SetEsc(escFuncPlanned)
+	if base.Flag.LowerM > 3 {
+		ir.Dump("escAnalyze", fn)
+	}
+
+	// Allocate locations for local variables.
+	for _, n := range fn.Dcl {
+		if n.Op() == ir.ONAME {
+			e.newLoc(n, false)
+		}
+	}
+
+	// Initialize resultIndex for result parameters.
+	for i, f := range fn.Type().Results().FieldSlice() {
+		e.oldLoc(f.Nname.(*ir.Name)).resultIndex = 1 + i
+	}
+}
+
+func (b *batch) walkFunc(fn *ir.Func) {
+	e := b.with(fn)
+	fn.SetEsc(escFuncStarted)
+
+	// Identify labels that mark the head of an unstructured loop.
+	ir.Visit(fn, func(n ir.Node) {
+		switch n.Op() {
+		case ir.OLABEL:
+			n := n.(*ir.LabelStmt)
+			if e.labels == nil {
+				e.labels = make(map[*types.Sym]labelState)
+			}
+			e.labels[n.Label] = nonlooping
+
+		case ir.OGOTO:
+			// If we visited the label before the goto,
+			// then this is a looping label.
+			n := n.(*ir.BranchStmt)
+			if e.labels[n.Label] == nonlooping {
+				e.labels[n.Label] = looping
+			}
+		}
+	})
+
+	e.block(fn.Body)
+
+	if len(e.labels) != 0 {
+		base.FatalfAt(fn.Pos(), "leftover labels after walkFunc")
+	}
+}
+
+func (b *batch) flowClosure(k hole, clo *ir.ClosureExpr) {
+	for _, cv := range clo.Func.ClosureVars {
+		n := cv.Canonical()
+		loc := b.oldLoc(cv)
+		if !loc.captured {
+			base.FatalfAt(cv.Pos(), "closure variable never captured: %v", cv)
+		}
+
+		// Capture by value for variables <= 128 bytes that are never reassigned.
+		n.SetByval(!loc.addrtaken && !loc.reassigned && n.Type().Size() <= 128)
+		if !n.Byval() {
+			n.SetAddrtaken(true)
+		}
+
+		if base.Flag.LowerM > 1 {
+			how := "ref"
+			if n.Byval() {
+				how = "value"
+			}
+			base.WarnfAt(n.Pos(), "%v capturing by %s: %v (addr=%v assign=%v width=%d)", n.Curfn, how, n, loc.addrtaken, loc.reassigned, n.Type().Size())
+		}
+
+		// Flow captured variables to closure.
+		k := k
+		if !cv.Byval() {
+			k = k.addr(cv, "reference")
+		}
+		b.flow(k.note(cv, "captured by a closure"), loc)
+	}
+}
+
+// Below we implement the methods for walking the AST and recording
+// data flow edges. Note that because a sub-expression might have
+// side-effects, it's important to always visit the entire AST.
+//
+// For example, write either:
+//
+//     if x {
+//         e.discard(n.Left)
+//     } else {
+//         e.value(k, n.Left)
+//     }
+//
+// or
+//
+//     if x {
+//         k = e.discardHole()
+//     }
+//     e.value(k, n.Left)
+//
+// Do NOT write:
+//
+//    // BAD: possibly loses side-effects within n.Left
+//    if !x {
+//        e.value(k, n.Left)
+//    }
+
+// stmt evaluates a single Go statement.
+func (e *escape) stmt(n ir.Node) {
+	if n == nil {
+		return
+	}
+
+	lno := ir.SetPos(n)
+	defer func() {
+		base.Pos = lno
+	}()
+
+	if base.Flag.LowerM > 2 {
+		fmt.Printf("%v:[%d] %v stmt: %v\n", base.FmtPos(base.Pos), e.loopDepth, e.curfn, n)
+	}
+
+	e.stmts(n.Init())
+
+	switch n.Op() {
+	default:
+		base.Fatalf("unexpected stmt: %v", n)
+
+	case ir.ODCLCONST, ir.ODCLTYPE, ir.OFALL, ir.OINLMARK:
+		// nop
+
+	case ir.OBREAK, ir.OCONTINUE, ir.OGOTO:
+		// TODO(mdempsky): Handle dead code?
+
+	case ir.OBLOCK:
+		n := n.(*ir.BlockStmt)
+		e.stmts(n.List)
+
+	case ir.ODCL:
+		// Record loop depth at declaration.
+		n := n.(*ir.Decl)
+		if !ir.IsBlank(n.X) {
+			e.dcl(n.X)
+		}
+
+	case ir.OLABEL:
+		n := n.(*ir.LabelStmt)
+		switch e.labels[n.Label] {
+		case nonlooping:
+			if base.Flag.LowerM > 2 {
+				fmt.Printf("%v:%v non-looping label\n", base.FmtPos(base.Pos), n)
+			}
+		case looping:
+			if base.Flag.LowerM > 2 {
+				fmt.Printf("%v: %v looping label\n", base.FmtPos(base.Pos), n)
+			}
+			e.loopDepth++
+		default:
+			base.Fatalf("label missing tag")
+		}
+		delete(e.labels, n.Label)
+
+	case ir.OIF:
+		n := n.(*ir.IfStmt)
+		e.discard(n.Cond)
+		e.block(n.Body)
+		e.block(n.Else)
+
+	case ir.OFOR, ir.OFORUNTIL:
+		n := n.(*ir.ForStmt)
+		e.loopDepth++
+		e.discard(n.Cond)
+		e.stmt(n.Post)
+		e.block(n.Body)
+		e.loopDepth--
+
+	case ir.ORANGE:
+		// for Key, Value = range X { Body }
+		n := n.(*ir.RangeStmt)
+
+		// X is evaluated outside the loop.
+		tmp := e.newLoc(nil, false)
+		e.expr(tmp.asHole(), n.X)
+
+		e.loopDepth++
+		ks := e.addrs([]ir.Node{n.Key, n.Value})
+		if n.X.Type().IsArray() {
+			e.flow(ks[1].note(n, "range"), tmp)
+		} else {
+			e.flow(ks[1].deref(n, "range-deref"), tmp)
+		}
+		e.reassigned(ks, n)
+
+		e.block(n.Body)
+		e.loopDepth--
+
+	case ir.OSWITCH:
+		n := n.(*ir.SwitchStmt)
+
+		if guard, ok := n.Tag.(*ir.TypeSwitchGuard); ok {
+			var ks []hole
+			if guard.Tag != nil {
+				for _, cas := range n.Cases {
+					cv := cas.Var
+					k := e.dcl(cv) // type switch variables have no ODCL.
+					if cv.Type().HasPointers() {
+						ks = append(ks, k.dotType(cv.Type(), cas, "switch case"))
+					}
+				}
+			}
+			e.expr(e.teeHole(ks...), n.Tag.(*ir.TypeSwitchGuard).X)
+		} else {
+			e.discard(n.Tag)
+		}
+
+		for _, cas := range n.Cases {
+			e.discards(cas.List)
+			e.block(cas.Body)
+		}
+
+	case ir.OSELECT:
+		n := n.(*ir.SelectStmt)
+		for _, cas := range n.Cases {
+			e.stmt(cas.Comm)
+			e.block(cas.Body)
+		}
+	case ir.ORECV:
+		// TODO(mdempsky): Consider e.discard(n.Left).
+		n := n.(*ir.UnaryExpr)
+		e.exprSkipInit(e.discardHole(), n) // already visited n.Ninit
+	case ir.OSEND:
+		n := n.(*ir.SendStmt)
+		e.discard(n.Chan)
+		e.assignHeap(n.Value, "send", n)
+
+	case ir.OAS:
+		n := n.(*ir.AssignStmt)
+		e.assignList([]ir.Node{n.X}, []ir.Node{n.Y}, "assign", n)
+	case ir.OASOP:
+		n := n.(*ir.AssignOpStmt)
+		// TODO(mdempsky): Worry about OLSH/ORSH?
+		e.assignList([]ir.Node{n.X}, []ir.Node{n.Y}, "assign", n)
+	case ir.OAS2:
+		n := n.(*ir.AssignListStmt)
+		e.assignList(n.Lhs, n.Rhs, "assign-pair", n)
+
+	case ir.OAS2DOTTYPE: // v, ok = x.(type)
+		n := n.(*ir.AssignListStmt)
+		e.assignList(n.Lhs, n.Rhs, "assign-pair-dot-type", n)
+	case ir.OAS2MAPR: // v, ok = m[k]
+		n := n.(*ir.AssignListStmt)
+		e.assignList(n.Lhs, n.Rhs, "assign-pair-mapr", n)
+	case ir.OAS2RECV, ir.OSELRECV2: // v, ok = <-ch
+		n := n.(*ir.AssignListStmt)
+		e.assignList(n.Lhs, n.Rhs, "assign-pair-receive", n)
+
+	case ir.OAS2FUNC:
+		n := n.(*ir.AssignListStmt)
+		e.stmts(n.Rhs[0].Init())
+		ks := e.addrs(n.Lhs)
+		e.call(ks, n.Rhs[0], nil)
+		e.reassigned(ks, n)
+	case ir.ORETURN:
+		n := n.(*ir.ReturnStmt)
+		results := e.curfn.Type().Results().FieldSlice()
+		dsts := make([]ir.Node, len(results))
+		for i, res := range results {
+			dsts[i] = res.Nname.(*ir.Name)
+		}
+		e.assignList(dsts, n.Results, "return", n)
+	case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OCLOSE, ir.OCOPY, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
+		e.call(nil, n, nil)
+	case ir.OGO, ir.ODEFER:
+		n := n.(*ir.GoDeferStmt)
+		e.stmts(n.Call.Init())
+		e.call(nil, n.Call, n)
+
+	case ir.OTAILCALL:
+		// TODO(mdempsky): Treat like a normal call? esc.go used to just ignore it.
+	}
+}
+
+func (e *escape) stmts(l ir.Nodes) {
+	for _, n := range l {
+		e.stmt(n)
+	}
+}
+
+// block is like stmts, but preserves loopDepth.
+func (e *escape) block(l ir.Nodes) {
+	old := e.loopDepth
+	e.stmts(l)
+	e.loopDepth = old
+}
+
+// expr models evaluating an expression n and flowing the result into
+// hole k.
+func (e *escape) expr(k hole, n ir.Node) {
+	if n == nil {
+		return
+	}
+	e.stmts(n.Init())
+	e.exprSkipInit(k, n)
+}
+
+func (e *escape) exprSkipInit(k hole, n ir.Node) {
+	if n == nil {
+		return
+	}
+
+	lno := ir.SetPos(n)
+	defer func() {
+		base.Pos = lno
+	}()
+
+	uintptrEscapesHack := k.uintptrEscapesHack
+	k.uintptrEscapesHack = false
+
+	if uintptrEscapesHack && n.Op() == ir.OCONVNOP && n.(*ir.ConvExpr).X.Type().IsUnsafePtr() {
+		// nop
+	} else if k.derefs >= 0 && !n.Type().HasPointers() {
+		k.dst = &e.blankLoc
+	}
+
+	switch n.Op() {
+	default:
+		base.Fatalf("unexpected expr: %s %v", n.Op().String(), n)
+
+	case ir.OLITERAL, ir.ONIL, ir.OGETG, ir.OTYPE, ir.OMETHEXPR, ir.OLINKSYMOFFSET:
+		// nop
+
+	case ir.ONAME:
+		n := n.(*ir.Name)
+		if n.Class == ir.PFUNC || n.Class == ir.PEXTERN {
+			return
+		}
+		if n.IsClosureVar() && n.Defn == nil {
+			return // ".this" from method value wrapper
+		}
+		e.flow(k, e.oldLoc(n))
+
+	case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT:
+		n := n.(*ir.UnaryExpr)
+		e.discard(n.X)
+	case ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.ODIV, ir.OMOD, ir.OLSH, ir.ORSH, ir.OAND, ir.OANDNOT, ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
+		n := n.(*ir.BinaryExpr)
+		e.discard(n.X)
+		e.discard(n.Y)
+	case ir.OANDAND, ir.OOROR:
+		n := n.(*ir.LogicalExpr)
+		e.discard(n.X)
+		e.discard(n.Y)
+	case ir.OADDR:
+		n := n.(*ir.AddrExpr)
+		e.expr(k.addr(n, "address-of"), n.X) // "address-of"
+	case ir.ODEREF:
+		n := n.(*ir.StarExpr)
+		e.expr(k.deref(n, "indirection"), n.X) // "indirection"
+	case ir.ODOT, ir.ODOTMETH, ir.ODOTINTER:
+		n := n.(*ir.SelectorExpr)
+		e.expr(k.note(n, "dot"), n.X)
+	case ir.ODOTPTR:
+		n := n.(*ir.SelectorExpr)
+		e.expr(k.deref(n, "dot of pointer"), n.X) // "dot of pointer"
+	case ir.ODOTTYPE, ir.ODOTTYPE2:
+		n := n.(*ir.TypeAssertExpr)
+		e.expr(k.dotType(n.Type(), n, "dot"), n.X)
+	case ir.OINDEX:
+		n := n.(*ir.IndexExpr)
+		if n.X.Type().IsArray() {
+			e.expr(k.note(n, "fixed-array-index-of"), n.X)
+		} else {
+			// TODO(mdempsky): Fix why reason text.
+			e.expr(k.deref(n, "dot of pointer"), n.X)
+		}
+		e.discard(n.Index)
+	case ir.OINDEXMAP:
+		n := n.(*ir.IndexExpr)
+		e.discard(n.X)
+		e.discard(n.Index)
+	case ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR, ir.OSLICESTR:
+		n := n.(*ir.SliceExpr)
+		e.expr(k.note(n, "slice"), n.X)
+		e.discard(n.Low)
+		e.discard(n.High)
+		e.discard(n.Max)
+
+	case ir.OCONV, ir.OCONVNOP:
+		n := n.(*ir.ConvExpr)
+		if ir.ShouldCheckPtr(e.curfn, 2) && n.Type().IsUnsafePtr() && n.X.Type().IsPtr() {
+			// When -d=checkptr=2 is enabled, treat
+			// conversions to unsafe.Pointer as an
+			// escaping operation. This allows better
+			// runtime instrumentation, since we can more
+			// easily detect object boundaries on the heap
+			// than the stack.
+			e.assignHeap(n.X, "conversion to unsafe.Pointer", n)
+		} else if n.Type().IsUnsafePtr() && n.X.Type().IsUintptr() {
+			e.unsafeValue(k, n.X)
+		} else {
+			e.expr(k, n.X)
+		}
+	case ir.OCONVIFACE:
+		n := n.(*ir.ConvExpr)
+		if !n.X.Type().IsInterface() && !types.IsDirectIface(n.X.Type()) {
+			k = e.spill(k, n)
+		}
+		e.expr(k.note(n, "interface-converted"), n.X)
+	case ir.OSLICE2ARRPTR:
+		// the slice pointer flows directly to the result
+		n := n.(*ir.ConvExpr)
+		e.expr(k, n.X)
+	case ir.ORECV:
+		n := n.(*ir.UnaryExpr)
+		e.discard(n.X)
+
+	case ir.OCALLMETH, ir.OCALLFUNC, ir.OCALLINTER, ir.OLEN, ir.OCAP, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCOPY, ir.OUNSAFEADD, ir.OUNSAFESLICE:
+		e.call([]hole{k}, n, nil)
+
+	case ir.ONEW:
+		n := n.(*ir.UnaryExpr)
+		e.spill(k, n)
+
+	case ir.OMAKESLICE:
+		n := n.(*ir.MakeExpr)
+		e.spill(k, n)
+		e.discard(n.Len)
+		e.discard(n.Cap)
+	case ir.OMAKECHAN:
+		n := n.(*ir.MakeExpr)
+		e.discard(n.Len)
+	case ir.OMAKEMAP:
+		n := n.(*ir.MakeExpr)
+		e.spill(k, n)
+		e.discard(n.Len)
+
+	case ir.ORECOVER:
+		// nop
+
+	case ir.OCALLPART:
+		// Flow the receiver argument to both the closure and
+		// to the receiver parameter.
+
+		n := n.(*ir.SelectorExpr)
+		closureK := e.spill(k, n)
+
+		m := n.Selection
+
+		// We don't know how the method value will be called
+		// later, so conservatively assume the result
+		// parameters all flow to the heap.
+		//
+		// TODO(mdempsky): Change ks into a callback, so that
+		// we don't have to create this slice?
+		var ks []hole
+		for i := m.Type.NumResults(); i > 0; i-- {
+			ks = append(ks, e.heapHole())
+		}
+		name, _ := m.Nname.(*ir.Name)
+		paramK := e.tagHole(ks, name, m.Type.Recv())
+
+		e.expr(e.teeHole(paramK, closureK), n.X)
+
+	case ir.OPTRLIT:
+		n := n.(*ir.AddrExpr)
+		e.expr(e.spill(k, n), n.X)
+
+	case ir.OARRAYLIT:
+		n := n.(*ir.CompLitExpr)
+		for _, elt := range n.List {
+			if elt.Op() == ir.OKEY {
+				elt = elt.(*ir.KeyExpr).Value
+			}
+			e.expr(k.note(n, "array literal element"), elt)
+		}
+
+	case ir.OSLICELIT:
+		n := n.(*ir.CompLitExpr)
+		k = e.spill(k, n)
+		k.uintptrEscapesHack = uintptrEscapesHack // for ...uintptr parameters
+
+		for _, elt := range n.List {
+			if elt.Op() == ir.OKEY {
+				elt = elt.(*ir.KeyExpr).Value
+			}
+			e.expr(k.note(n, "slice-literal-element"), elt)
+		}
+
+	case ir.OSTRUCTLIT:
+		n := n.(*ir.CompLitExpr)
+		for _, elt := range n.List {
+			e.expr(k.note(n, "struct literal element"), elt.(*ir.StructKeyExpr).Value)
+		}
+
+	case ir.OMAPLIT:
+		n := n.(*ir.CompLitExpr)
+		e.spill(k, n)
+
+		// Map keys and values are always stored in the heap.
+		for _, elt := range n.List {
+			elt := elt.(*ir.KeyExpr)
+			e.assignHeap(elt.Key, "map literal key", n)
+			e.assignHeap(elt.Value, "map literal value", n)
+		}
+
+	case ir.OCLOSURE:
+		n := n.(*ir.ClosureExpr)
+		k = e.spill(k, n)
+		e.closures = append(e.closures, closure{k, n})
+
+		if fn := n.Func; fn.IsHiddenClosure() {
+			for _, cv := range fn.ClosureVars {
+				if loc := e.oldLoc(cv); !loc.captured {
+					loc.captured = true
+
+					// Ignore reassignments to the variable in straightline code
+					// preceding the first capture by a closure.
+					if loc.loopDepth == e.loopDepth {
+						loc.reassigned = false
+					}
+				}
+			}
+
+			for _, n := range fn.Dcl {
+				// Add locations for local variables of the
+				// closure, if needed, in case we're not including
+				// the closure func in the batch for escape
+				// analysis (happens for escape analysis called
+				// from reflectdata.methodWrapper)
+				if n.Op() == ir.ONAME && n.Opt == nil {
+					e.with(fn).newLoc(n, false)
+				}
+			}
+			e.walkFunc(fn)
+		}
+
+	case ir.ORUNES2STR, ir.OBYTES2STR, ir.OSTR2RUNES, ir.OSTR2BYTES, ir.ORUNESTR:
+		n := n.(*ir.ConvExpr)
+		e.spill(k, n)
+		e.discard(n.X)
+
+	case ir.OADDSTR:
+		n := n.(*ir.AddStringExpr)
+		e.spill(k, n)
+
+		// Arguments of OADDSTR never escape;
+		// runtime.concatstrings makes sure of that.
+		e.discards(n.List)
+	}
+}
+
+// unsafeValue evaluates a uintptr-typed arithmetic expression looking
+// for conversions from an unsafe.Pointer.
+func (e *escape) unsafeValue(k hole, n ir.Node) {
+	if n.Type().Kind() != types.TUINTPTR {
+		base.Fatalf("unexpected type %v for %v", n.Type(), n)
+	}
+	if k.addrtaken {
+		base.Fatalf("unexpected addrtaken")
+	}
+
+	e.stmts(n.Init())
+
+	switch n.Op() {
+	case ir.OCONV, ir.OCONVNOP:
+		n := n.(*ir.ConvExpr)
+		if n.X.Type().IsUnsafePtr() {
+			e.expr(k, n.X)
+		} else {
+			e.discard(n.X)
+		}
+	case ir.ODOTPTR:
+		n := n.(*ir.SelectorExpr)
+		if ir.IsReflectHeaderDataField(n) {
+			e.expr(k.deref(n, "reflect.Header.Data"), n.X)
+		} else {
+			e.discard(n.X)
+		}
+	case ir.OPLUS, ir.ONEG, ir.OBITNOT:
+		n := n.(*ir.UnaryExpr)
+		e.unsafeValue(k, n.X)
+	case ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.ODIV, ir.OMOD, ir.OAND, ir.OANDNOT:
+		n := n.(*ir.BinaryExpr)
+		e.unsafeValue(k, n.X)
+		e.unsafeValue(k, n.Y)
+	case ir.OLSH, ir.ORSH:
+		n := n.(*ir.BinaryExpr)
+		e.unsafeValue(k, n.X)
+		// RHS need not be uintptr-typed (#32959) and can't meaningfully
+		// flow pointers anyway.
+		e.discard(n.Y)
+	default:
+		e.exprSkipInit(e.discardHole(), n)
+	}
+}
+
+// discard evaluates an expression n for side-effects, but discards
+// its value.
+func (e *escape) discard(n ir.Node) {
+	e.expr(e.discardHole(), n)
+}
+
+func (e *escape) discards(l ir.Nodes) {
+	for _, n := range l {
+		e.discard(n)
+	}
+}
+
+// addr evaluates an addressable expression n and returns a hole
+// that represents storing into the represented location.
+func (e *escape) addr(n ir.Node) hole {
+	if n == nil || ir.IsBlank(n) {
+		// Can happen in select case, range, maybe others.
+		return e.discardHole()
+	}
+
+	k := e.heapHole()
+
+	switch n.Op() {
+	default:
+		base.Fatalf("unexpected addr: %v", n)
+	case ir.ONAME:
+		n := n.(*ir.Name)
+		if n.Class == ir.PEXTERN {
+			break
+		}
+		k = e.oldLoc(n).asHole()
+	case ir.OLINKSYMOFFSET:
+		break
+	case ir.ODOT:
+		n := n.(*ir.SelectorExpr)
+		k = e.addr(n.X)
+	case ir.OINDEX:
+		n := n.(*ir.IndexExpr)
+		e.discard(n.Index)
+		if n.X.Type().IsArray() {
+			k = e.addr(n.X)
+		} else {
+			e.discard(n.X)
+		}
+	case ir.ODEREF, ir.ODOTPTR:
+		e.discard(n)
+	case ir.OINDEXMAP:
+		n := n.(*ir.IndexExpr)
+		e.discard(n.X)
+		e.assignHeap(n.Index, "key of map put", n)
+	}
+
+	return k
+}
+
+func (e *escape) addrs(l ir.Nodes) []hole {
+	var ks []hole
+	for _, n := range l {
+		ks = append(ks, e.addr(n))
+	}
+	return ks
+}
+
+// reassigned marks the locations associated with the given holes as
+// reassigned, unless the location represents a variable declared and
+// assigned exactly once by where.
+func (e *escape) reassigned(ks []hole, where ir.Node) {
+	if as, ok := where.(*ir.AssignStmt); ok && as.Op() == ir.OAS && as.Y == nil {
+		if dst, ok := as.X.(*ir.Name); ok && dst.Op() == ir.ONAME && dst.Defn == nil {
+			// Zero-value assignment for variable declared without an
+			// explicit initial value. Assume this is its initialization
+			// statement.
+			return
+		}
+	}
+
+	for _, k := range ks {
+		loc := k.dst
+		// Variables declared by range statements are assigned on every iteration.
+		if n, ok := loc.n.(*ir.Name); ok && n.Defn == where && where.Op() != ir.ORANGE {
+			continue
+		}
+		loc.reassigned = true
+	}
+}
+
+// assignList evaluates the assignment dsts... = srcs....
+func (e *escape) assignList(dsts, srcs []ir.Node, why string, where ir.Node) {
+	ks := e.addrs(dsts)
+	for i, k := range ks {
+		var src ir.Node
+		if i < len(srcs) {
+			src = srcs[i]
+		}
+
+		if dst := dsts[i]; dst != nil {
+			// Detect implicit conversion of uintptr to unsafe.Pointer when
+			// storing into reflect.{Slice,String}Header.
+			if dst.Op() == ir.ODOTPTR && ir.IsReflectHeaderDataField(dst) {
+				e.unsafeValue(e.heapHole().note(where, why), src)
+				continue
+			}
+
+			// Filter out some no-op assignments for escape analysis.
+			if src != nil && isSelfAssign(dst, src) {
+				if base.Flag.LowerM != 0 {
+					base.WarnfAt(where.Pos(), "%v ignoring self-assignment in %v", e.curfn, where)
+				}
+				k = e.discardHole()
+			}
+		}
+
+		e.expr(k.note(where, why), src)
+	}
+
+	e.reassigned(ks, where)
+}
+
+func (e *escape) assignHeap(src ir.Node, why string, where ir.Node) {
+	e.expr(e.heapHole().note(where, why), src)
+}
+
+// call evaluates a call expressions, including builtin calls. ks
+// should contain the holes representing where the function callee's
+// results flows; where is the OGO/ODEFER context of the call, if any.
+func (e *escape) call(ks []hole, call, where ir.Node) {
+	topLevelDefer := where != nil && where.Op() == ir.ODEFER && e.loopDepth == 1
+	if topLevelDefer {
+		// force stack allocation of defer record, unless
+		// open-coded defers are used (see ssa.go)
+		where.SetEsc(ir.EscNever)
+	}
+
+	argument := func(k hole, arg ir.Node) {
+		if topLevelDefer {
+			// Top level defers arguments don't escape to
+			// heap, but they do need to last until end of
+			// function.
+			k = e.later(k)
+		} else if where != nil {
+			k = e.heapHole()
+		}
+
+		e.expr(k.note(call, "call parameter"), arg)
+	}
+
+	switch call.Op() {
+	default:
+		ir.Dump("esc", call)
+		base.Fatalf("unexpected call op: %v", call.Op())
+
+	case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
+		call := call.(*ir.CallExpr)
+		typecheck.FixVariadicCall(call)
+
+		// Pick out the function callee, if statically known.
+		var fn *ir.Name
+		switch call.Op() {
+		case ir.OCALLFUNC:
+			switch v := ir.StaticValue(call.X); {
+			case v.Op() == ir.ONAME && v.(*ir.Name).Class == ir.PFUNC:
+				fn = v.(*ir.Name)
+			case v.Op() == ir.OCLOSURE:
+				fn = v.(*ir.ClosureExpr).Func.Nname
+			}
+		case ir.OCALLMETH:
+			fn = ir.MethodExprName(call.X)
+		}
+
+		fntype := call.X.Type()
+		if fn != nil {
+			fntype = fn.Type()
+		}
+
+		if ks != nil && fn != nil && e.inMutualBatch(fn) {
+			for i, result := range fn.Type().Results().FieldSlice() {
+				e.expr(ks[i], ir.AsNode(result.Nname))
+			}
+		}
+
+		if r := fntype.Recv(); r != nil {
+			argument(e.tagHole(ks, fn, r), call.X.(*ir.SelectorExpr).X)
+		} else {
+			// Evaluate callee function expression.
+			argument(e.discardHole(), call.X)
+		}
+
+		args := call.Args
+		for i, param := range fntype.Params().FieldSlice() {
+			argument(e.tagHole(ks, fn, param), args[i])
+		}
+
+	case ir.OAPPEND:
+		call := call.(*ir.CallExpr)
+		args := call.Args
+
+		// Appendee slice may flow directly to the result, if
+		// it has enough capacity. Alternatively, a new heap
+		// slice might be allocated, and all slice elements
+		// might flow to heap.
+		appendeeK := ks[0]
+		if args[0].Type().Elem().HasPointers() {
+			appendeeK = e.teeHole(appendeeK, e.heapHole().deref(call, "appendee slice"))
+		}
+		argument(appendeeK, args[0])
+
+		if call.IsDDD {
+			appendedK := e.discardHole()
+			if args[1].Type().IsSlice() && args[1].Type().Elem().HasPointers() {
+				appendedK = e.heapHole().deref(call, "appended slice...")
+			}
+			argument(appendedK, args[1])
+		} else {
+			for _, arg := range args[1:] {
+				argument(e.heapHole(), arg)
+			}
+		}
+
+	case ir.OCOPY:
+		call := call.(*ir.BinaryExpr)
+		argument(e.discardHole(), call.X)
+
+		copiedK := e.discardHole()
+		if call.Y.Type().IsSlice() && call.Y.Type().Elem().HasPointers() {
+			copiedK = e.heapHole().deref(call, "copied slice")
+		}
+		argument(copiedK, call.Y)
+
+	case ir.OPANIC:
+		call := call.(*ir.UnaryExpr)
+		argument(e.heapHole(), call.X)
+
+	case ir.OCOMPLEX:
+		call := call.(*ir.BinaryExpr)
+		argument(e.discardHole(), call.X)
+		argument(e.discardHole(), call.Y)
+	case ir.ODELETE, ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
+		call := call.(*ir.CallExpr)
+		for _, arg := range call.Args {
+			argument(e.discardHole(), arg)
+		}
+	case ir.OLEN, ir.OCAP, ir.OREAL, ir.OIMAG, ir.OCLOSE:
+		call := call.(*ir.UnaryExpr)
+		argument(e.discardHole(), call.X)
+
+	case ir.OUNSAFEADD, ir.OUNSAFESLICE:
+		call := call.(*ir.BinaryExpr)
+		argument(ks[0], call.X)
+		argument(e.discardHole(), call.Y)
+	}
+}
+
+// tagHole returns a hole for evaluating an argument passed to param.
+// ks should contain the holes representing where the function
+// callee's results flows. fn is the statically-known callee function,
+// if any.
+func (e *escape) tagHole(ks []hole, fn *ir.Name, param *types.Field) hole {
+	// If this is a dynamic call, we can't rely on param.Note.
+	if fn == nil {
+		return e.heapHole()
+	}
+
+	if e.inMutualBatch(fn) {
+		return e.addr(ir.AsNode(param.Nname))
+	}
+
+	// Call to previously tagged function.
+
+	if param.Note == UintptrEscapesNote {
+		k := e.heapHole()
+		k.uintptrEscapesHack = true
+		return k
+	}
+
+	var tagKs []hole
+
+	esc := parseLeaks(param.Note)
+	if x := esc.Heap(); x >= 0 {
+		tagKs = append(tagKs, e.heapHole().shift(x))
+	}
+
+	if ks != nil {
+		for i := 0; i < numEscResults; i++ {
+			if x := esc.Result(i); x >= 0 {
+				tagKs = append(tagKs, ks[i].shift(x))
+			}
+		}
+	}
+
+	return e.teeHole(tagKs...)
+}
+
+// inMutualBatch reports whether function fn is in the batch of
+// mutually recursive functions being analyzed. When this is true,
+// fn has not yet been analyzed, so its parameters and results
+// should be incorporated directly into the flow graph instead of
+// relying on its escape analysis tagging.
+func (e *escape) inMutualBatch(fn *ir.Name) bool {
+	if fn.Defn != nil && fn.Defn.Esc() < escFuncTagged {
+		if fn.Defn.Esc() == escFuncUnknown {
+			base.Fatalf("graph inconsistency: %v", fn)
+		}
+		return true
+	}
+	return false
+}
+
+// An hole represents a context for evaluation a Go
+// expression. E.g., when evaluating p in "x = **p", we'd have a hole
+// with dst==x and derefs==2.
+type hole struct {
+	dst    *location
+	derefs int // >= -1
+	notes  *note
+
+	// addrtaken indicates whether this context is taking the address of
+	// the expression, independent of whether the address will actually
+	// be stored into a variable.
+	addrtaken bool
+
+	// uintptrEscapesHack indicates this context is evaluating an
+	// argument for a //go:uintptrescapes function.
+	uintptrEscapesHack bool
+}
+
+type note struct {
+	next  *note
+	where ir.Node
+	why   string
+}
+
+func (k hole) note(where ir.Node, why string) hole {
+	if where == nil || why == "" {
+		base.Fatalf("note: missing where/why")
+	}
+	if base.Flag.LowerM >= 2 || logopt.Enabled() {
+		k.notes = &note{
+			next:  k.notes,
+			where: where,
+			why:   why,
+		}
+	}
+	return k
+}
+
+func (k hole) shift(delta int) hole {
+	k.derefs += delta
+	if k.derefs < -1 {
+		base.Fatalf("derefs underflow: %v", k.derefs)
+	}
+	k.addrtaken = delta < 0
+	return k
+}
+
+func (k hole) deref(where ir.Node, why string) hole { return k.shift(1).note(where, why) }
+func (k hole) addr(where ir.Node, why string) hole  { return k.shift(-1).note(where, why) }
+
+func (k hole) dotType(t *types.Type, where ir.Node, why string) hole {
+	if !t.IsInterface() && !types.IsDirectIface(t) {
+		k = k.shift(1)
+	}
+	return k.note(where, why)
+}
+
+// teeHole returns a new hole that flows into each hole of ks,
+// similar to the Unix tee(1) command.
+func (e *escape) teeHole(ks ...hole) hole {
+	if len(ks) == 0 {
+		return e.discardHole()
+	}
+	if len(ks) == 1 {
+		return ks[0]
+	}
+	// TODO(mdempsky): Optimize if there's only one non-discard hole?
+
+	// Given holes "l1 = _", "l2 = **_", "l3 = *_", ..., create a
+	// new temporary location ltmp, wire it into place, and return
+	// a hole for "ltmp = _".
+	loc := e.newLoc(nil, true)
+	for _, k := range ks {
+		// N.B., "p = &q" and "p = &tmp; tmp = q" are not
+		// semantically equivalent. To combine holes like "l1
+		// = _" and "l2 = &_", we'd need to wire them as "l1 =
+		// *ltmp" and "l2 = ltmp" and return "ltmp = &_"
+		// instead.
+		if k.derefs < 0 {
+			base.Fatalf("teeHole: negative derefs")
+		}
+
+		e.flow(k, loc)
+	}
+	return loc.asHole()
+}
+
+func (e *escape) dcl(n *ir.Name) hole {
+	if n.Curfn != e.curfn || n.IsClosureVar() {
+		base.Fatalf("bad declaration of %v", n)
+	}
+	loc := e.oldLoc(n)
+	loc.loopDepth = e.loopDepth
+	return loc.asHole()
+}
+
+// spill allocates a new location associated with expression n, flows
+// its address to k, and returns a hole that flows values to it. It's
+// intended for use with most expressions that allocate storage.
+func (e *escape) spill(k hole, n ir.Node) hole {
+	loc := e.newLoc(n, true)
+	e.flow(k.addr(n, "spill"), loc)
+	return loc.asHole()
+}
+
+// later returns a new hole that flows into k, but some time later.
+// Its main effect is to prevent immediate reuse of temporary
+// variables introduced during Order.
+func (e *escape) later(k hole) hole {
+	loc := e.newLoc(nil, false)
+	e.flow(k, loc)
+	return loc.asHole()
+}
+
+func (e *escape) newLoc(n ir.Node, transient bool) *location {
+	if e.curfn == nil {
+		base.Fatalf("e.curfn isn't set")
+	}
+	if n != nil && n.Type() != nil && n.Type().NotInHeap() {
+		base.ErrorfAt(n.Pos(), "%v is incomplete (or unallocatable); stack allocation disallowed", n.Type())
+	}
+
+	if n != nil && n.Op() == ir.ONAME {
+		n = n.(*ir.Name).Canonical()
+	}
+	loc := &location{
+		n:         n,
+		curfn:     e.curfn,
+		loopDepth: e.loopDepth,
+		transient: transient,
+	}
+	e.allLocs = append(e.allLocs, loc)
+	if n != nil {
+		if n.Op() == ir.ONAME {
+			n := n.(*ir.Name)
+			if n.Curfn != e.curfn {
+				base.Fatalf("curfn mismatch: %v != %v for %v", n.Curfn, e.curfn, n)
+			}
+
+			if n.Opt != nil {
+				base.Fatalf("%v already has a location", n)
+			}
+			n.Opt = loc
+		}
+	}
+	return loc
+}
+
+func (b *batch) oldLoc(n *ir.Name) *location {
+	if n.Canonical().Opt == nil {
+		base.Fatalf("%v has no location", n)
+	}
+	return n.Canonical().Opt.(*location)
+}
+
+func (l *location) asHole() hole {
+	return hole{dst: l}
+}
+
+func (b *batch) flow(k hole, src *location) {
+	if k.addrtaken {
+		src.addrtaken = true
+	}
+
+	dst := k.dst
+	if dst == &b.blankLoc {
+		return
+	}
+	if dst == src && k.derefs >= 0 { // dst = dst, dst = *dst, ...
+		return
+	}
+	if dst.escapes && k.derefs < 0 { // dst = &src
+		if base.Flag.LowerM >= 2 || logopt.Enabled() {
+			pos := base.FmtPos(src.n.Pos())
+			if base.Flag.LowerM >= 2 {
+				fmt.Printf("%s: %v escapes to heap:\n", pos, src.n)
+			}
+			explanation := b.explainFlow(pos, dst, src, k.derefs, k.notes, []*logopt.LoggedOpt{})
+			if logopt.Enabled() {
+				var e_curfn *ir.Func // TODO(mdempsky): Fix.
+				logopt.LogOpt(src.n.Pos(), "escapes", "escape", ir.FuncName(e_curfn), fmt.Sprintf("%v escapes to heap", src.n), explanation)
+			}
+
+		}
+		src.escapes = true
+		return
+	}
+
+	// TODO(mdempsky): Deduplicate edges?
+	dst.edges = append(dst.edges, edge{src: src, derefs: k.derefs, notes: k.notes})
+}
+
+func (b *batch) heapHole() hole    { return b.heapLoc.asHole() }
+func (b *batch) discardHole() hole { return b.blankLoc.asHole() }
+
+// walkAll computes the minimal dereferences between all pairs of
+// locations.
+func (b *batch) walkAll() {
+	// We use a work queue to keep track of locations that we need
+	// to visit, and repeatedly walk until we reach a fixed point.
+	//
+	// We walk once from each location (including the heap), and
+	// then re-enqueue each location on its transition from
+	// transient->!transient and !escapes->escapes, which can each
+	// happen at most once. So we take Θ(len(e.allLocs)) walks.
+
+	// LIFO queue, has enough room for e.allLocs and e.heapLoc.
+	todo := make([]*location, 0, len(b.allLocs)+1)
+	enqueue := func(loc *location) {
+		if !loc.queued {
+			todo = append(todo, loc)
+			loc.queued = true
+		}
+	}
+
+	for _, loc := range b.allLocs {
+		enqueue(loc)
+	}
+	enqueue(&b.heapLoc)
+
+	var walkgen uint32
+	for len(todo) > 0 {
+		root := todo[len(todo)-1]
+		todo = todo[:len(todo)-1]
+		root.queued = false
+
+		walkgen++
+		b.walkOne(root, walkgen, enqueue)
+	}
+}
+
+// walkOne computes the minimal number of dereferences from root to
+// all other locations.
+func (b *batch) walkOne(root *location, walkgen uint32, enqueue func(*location)) {
+	// The data flow graph has negative edges (from addressing
+	// operations), so we use the Bellman-Ford algorithm. However,
+	// we don't have to worry about infinite negative cycles since
+	// we bound intermediate dereference counts to 0.
+
+	root.walkgen = walkgen
+	root.derefs = 0
+	root.dst = nil
+
+	todo := []*location{root} // LIFO queue
+	for len(todo) > 0 {
+		l := todo[len(todo)-1]
+		todo = todo[:len(todo)-1]
+
+		derefs := l.derefs
+
+		// If l.derefs < 0, then l's address flows to root.
+		addressOf := derefs < 0
+		if addressOf {
+			// For a flow path like "root = &l; l = x",
+			// l's address flows to root, but x's does
+			// not. We recognize this by lower bounding
+			// derefs at 0.
+			derefs = 0
+
+			// If l's address flows to a non-transient
+			// location, then l can't be transiently
+			// allocated.
+			if !root.transient && l.transient {
+				l.transient = false
+				enqueue(l)
+			}
+		}
+
+		if b.outlives(root, l) {
+			// l's value flows to root. If l is a function
+			// parameter and root is the heap or a
+			// corresponding result parameter, then record
+			// that value flow for tagging the function
+			// later.
+			if l.isName(ir.PPARAM) {
+				if (logopt.Enabled() || base.Flag.LowerM >= 2) && !l.escapes {
+					if base.Flag.LowerM >= 2 {
+						fmt.Printf("%s: parameter %v leaks to %s with derefs=%d:\n", base.FmtPos(l.n.Pos()), l.n, b.explainLoc(root), derefs)
+					}
+					explanation := b.explainPath(root, l)
+					if logopt.Enabled() {
+						var e_curfn *ir.Func // TODO(mdempsky): Fix.
+						logopt.LogOpt(l.n.Pos(), "leak", "escape", ir.FuncName(e_curfn),
+							fmt.Sprintf("parameter %v leaks to %s with derefs=%d", l.n, b.explainLoc(root), derefs), explanation)
+					}
+				}
+				l.leakTo(root, derefs)
+			}
+
+			// If l's address flows somewhere that
+			// outlives it, then l needs to be heap
+			// allocated.
+			if addressOf && !l.escapes {
+				if logopt.Enabled() || base.Flag.LowerM >= 2 {
+					if base.Flag.LowerM >= 2 {
+						fmt.Printf("%s: %v escapes to heap:\n", base.FmtPos(l.n.Pos()), l.n)
+					}
+					explanation := b.explainPath(root, l)
+					if logopt.Enabled() {
+						var e_curfn *ir.Func // TODO(mdempsky): Fix.
+						logopt.LogOpt(l.n.Pos(), "escape", "escape", ir.FuncName(e_curfn), fmt.Sprintf("%v escapes to heap", l.n), explanation)
+					}
+				}
+				l.escapes = true
+				enqueue(l)
+				continue
+			}
+		}
+
+		for i, edge := range l.edges {
+			if edge.src.escapes {
+				continue
+			}
+			d := derefs + edge.derefs
+			if edge.src.walkgen != walkgen || edge.src.derefs > d {
+				edge.src.walkgen = walkgen
+				edge.src.derefs = d
+				edge.src.dst = l
+				edge.src.dstEdgeIdx = i
+				todo = append(todo, edge.src)
+			}
+		}
+	}
+}
+
+// explainPath prints an explanation of how src flows to the walk root.
+func (b *batch) explainPath(root, src *location) []*logopt.LoggedOpt {
+	visited := make(map[*location]bool)
+	pos := base.FmtPos(src.n.Pos())
+	var explanation []*logopt.LoggedOpt
+	for {
+		// Prevent infinite loop.
+		if visited[src] {
+			if base.Flag.LowerM >= 2 {
+				fmt.Printf("%s:   warning: truncated explanation due to assignment cycle; see golang.org/issue/35518\n", pos)
+			}
+			break
+		}
+		visited[src] = true
+		dst := src.dst
+		edge := &dst.edges[src.dstEdgeIdx]
+		if edge.src != src {
+			base.Fatalf("path inconsistency: %v != %v", edge.src, src)
+		}
+
+		explanation = b.explainFlow(pos, dst, src, edge.derefs, edge.notes, explanation)
+
+		if dst == root {
+			break
+		}
+		src = dst
+	}
+
+	return explanation
+}
+
+func (b *batch) explainFlow(pos string, dst, srcloc *location, derefs int, notes *note, explanation []*logopt.LoggedOpt) []*logopt.LoggedOpt {
+	ops := "&"
+	if derefs >= 0 {
+		ops = strings.Repeat("*", derefs)
+	}
+	print := base.Flag.LowerM >= 2
+
+	flow := fmt.Sprintf("   flow: %s = %s%v:", b.explainLoc(dst), ops, b.explainLoc(srcloc))
+	if print {
+		fmt.Printf("%s:%s\n", pos, flow)
+	}
+	if logopt.Enabled() {
+		var epos src.XPos
+		if notes != nil {
+			epos = notes.where.Pos()
+		} else if srcloc != nil && srcloc.n != nil {
+			epos = srcloc.n.Pos()
+		}
+		var e_curfn *ir.Func // TODO(mdempsky): Fix.
+		explanation = append(explanation, logopt.NewLoggedOpt(epos, "escflow", "escape", ir.FuncName(e_curfn), flow))
+	}
+
+	for note := notes; note != nil; note = note.next {
+		if print {
+			fmt.Printf("%s:     from %v (%v) at %s\n", pos, note.where, note.why, base.FmtPos(note.where.Pos()))
+		}
+		if logopt.Enabled() {
+			var e_curfn *ir.Func // TODO(mdempsky): Fix.
+			explanation = append(explanation, logopt.NewLoggedOpt(note.where.Pos(), "escflow", "escape", ir.FuncName(e_curfn),
+				fmt.Sprintf("     from %v (%v)", note.where, note.why)))
+		}
+	}
+	return explanation
+}
+
+func (b *batch) explainLoc(l *location) string {
+	if l == &b.heapLoc {
+		return "{heap}"
+	}
+	if l.n == nil {
+		// TODO(mdempsky): Omit entirely.
+		return "{temp}"
+	}
+	if l.n.Op() == ir.ONAME {
+		return fmt.Sprintf("%v", l.n)
+	}
+	return fmt.Sprintf("{storage for %v}", l.n)
+}
+
+// outlives reports whether values stored in l may survive beyond
+// other's lifetime if stack allocated.
+func (b *batch) outlives(l, other *location) bool {
+	// The heap outlives everything.
+	if l.escapes {
+		return true
+	}
+
+	// We don't know what callers do with returned values, so
+	// pessimistically we need to assume they flow to the heap and
+	// outlive everything too.
+	if l.isName(ir.PPARAMOUT) {
+		// Exception: Directly called closures can return
+		// locations allocated outside of them without forcing
+		// them to the heap. For example:
+		//
+		//    var u int  // okay to stack allocate
+		//    *(func() *int { return &u }()) = 42
+		if containsClosure(other.curfn, l.curfn) && l.curfn.ClosureCalled() {
+			return false
+		}
+
+		return true
+	}
+
+	// If l and other are within the same function, then l
+	// outlives other if it was declared outside other's loop
+	// scope. For example:
+	//
+	//    var l *int
+	//    for {
+	//        l = new(int)
+	//    }
+	if l.curfn == other.curfn && l.loopDepth < other.loopDepth {
+		return true
+	}
+
+	// If other is declared within a child closure of where l is
+	// declared, then l outlives it. For example:
+	//
+	//    var l *int
+	//    func() {
+	//        l = new(int)
+	//    }
+	if containsClosure(l.curfn, other.curfn) {
+		return true
+	}
+
+	return false
+}
+
+// containsClosure reports whether c is a closure contained within f.
+func containsClosure(f, c *ir.Func) bool {
+	// Common case.
+	if f == c {
+		return false
+	}
+
+	// Closures within function Foo are named like "Foo.funcN..."
+	// TODO(mdempsky): Better way to recognize this.
+	fn := f.Sym().Name
+	cn := c.Sym().Name
+	return len(cn) > len(fn) && cn[:len(fn)] == fn && cn[len(fn)] == '.'
+}
+
+// leak records that parameter l leaks to sink.
+func (l *location) leakTo(sink *location, derefs int) {
+	// If sink is a result parameter that doesn't escape (#44614)
+	// and we can fit return bits into the escape analysis tag,
+	// then record as a result leak.
+	if !sink.escapes && sink.isName(ir.PPARAMOUT) && sink.curfn == l.curfn {
+		ri := sink.resultIndex - 1
+		if ri < numEscResults {
+			// Leak to result parameter.
+			l.paramEsc.AddResult(ri, derefs)
+			return
+		}
+	}
+
+	// Otherwise, record as heap leak.
+	l.paramEsc.AddHeap(derefs)
+}
+
+func (b *batch) finish(fns []*ir.Func) {
+	// Record parameter tags for package export data.
+	for _, fn := range fns {
+		fn.SetEsc(escFuncTagged)
+
+		narg := 0
+		for _, fs := range &types.RecvsParams {
+			for _, f := range fs(fn.Type()).Fields().Slice() {
+				narg++
+				f.Note = b.paramTag(fn, narg, f)
+			}
+		}
+	}
+
+	for _, loc := range b.allLocs {
+		n := loc.n
+		if n == nil {
+			continue
+		}
+		if n.Op() == ir.ONAME {
+			n := n.(*ir.Name)
+			n.Opt = nil
+		}
+
+		// Update n.Esc based on escape analysis results.
+
+		if loc.escapes {
+			if n.Op() == ir.ONAME {
+				if base.Flag.CompilingRuntime {
+					base.ErrorfAt(n.Pos(), "%v escapes to heap, not allowed in runtime", n)
+				}
+				if base.Flag.LowerM != 0 {
+					base.WarnfAt(n.Pos(), "moved to heap: %v", n)
+				}
+			} else {
+				if base.Flag.LowerM != 0 {
+					base.WarnfAt(n.Pos(), "%v escapes to heap", n)
+				}
+				if logopt.Enabled() {
+					var e_curfn *ir.Func // TODO(mdempsky): Fix.
+					logopt.LogOpt(n.Pos(), "escape", "escape", ir.FuncName(e_curfn))
+				}
+			}
+			n.SetEsc(ir.EscHeap)
+		} else {
+			if base.Flag.LowerM != 0 && n.Op() != ir.ONAME {
+				base.WarnfAt(n.Pos(), "%v does not escape", n)
+			}
+			n.SetEsc(ir.EscNone)
+			if loc.transient {
+				switch n.Op() {
+				case ir.OCLOSURE:
+					n := n.(*ir.ClosureExpr)
+					n.SetTransient(true)
+				case ir.OCALLPART:
+					n := n.(*ir.SelectorExpr)
+					n.SetTransient(true)
+				case ir.OSLICELIT:
+					n := n.(*ir.CompLitExpr)
+					n.SetTransient(true)
+				}
+			}
+		}
+	}
+}
+
+func (l *location) isName(c ir.Class) bool {
+	return l.n != nil && l.n.Op() == ir.ONAME && l.n.(*ir.Name).Class == c
+}
+
+const numEscResults = 7
+
+// An leaks represents a set of assignment flows from a parameter
+// to the heap or to any of its function's (first numEscResults)
+// result parameters.
+type leaks [1 + numEscResults]uint8
+
+// Empty reports whether l is an empty set (i.e., no assignment flows).
+func (l leaks) Empty() bool { return l == leaks{} }
+
+// Heap returns the minimum deref count of any assignment flow from l
+// to the heap. If no such flows exist, Heap returns -1.
+func (l leaks) Heap() int { return l.get(0) }
+
+// Result returns the minimum deref count of any assignment flow from
+// l to its function's i'th result parameter. If no such flows exist,
+// Result returns -1.
+func (l leaks) Result(i int) int { return l.get(1 + i) }
+
+// AddHeap adds an assignment flow from l to the heap.
+func (l *leaks) AddHeap(derefs int) { l.add(0, derefs) }
+
+// AddResult adds an assignment flow from l to its function's i'th
+// result parameter.
+func (l *leaks) AddResult(i, derefs int) { l.add(1+i, derefs) }
+
+func (l *leaks) setResult(i, derefs int) { l.set(1+i, derefs) }
+
+func (l leaks) get(i int) int { return int(l[i]) - 1 }
+
+func (l *leaks) add(i, derefs int) {
+	if old := l.get(i); old < 0 || derefs < old {
+		l.set(i, derefs)
+	}
+}
+
+func (l *leaks) set(i, derefs int) {
+	v := derefs + 1
+	if v < 0 {
+		base.Fatalf("invalid derefs count: %v", derefs)
+	}
+	if v > math.MaxUint8 {
+		v = math.MaxUint8
+	}
+
+	l[i] = uint8(v)
+}
+
+// Optimize removes result flow paths that are equal in length or
+// longer than the shortest heap flow path.
+func (l *leaks) Optimize() {
+	// If we have a path to the heap, then there's no use in
+	// keeping equal or longer paths elsewhere.
+	if x := l.Heap(); x >= 0 {
+		for i := 0; i < numEscResults; i++ {
+			if l.Result(i) >= x {
+				l.setResult(i, -1)
+			}
+		}
+	}
+}
+
+var leakTagCache = map[leaks]string{}
+
+// Encode converts l into a binary string for export data.
+func (l leaks) Encode() string {
+	if l.Heap() == 0 {
+		// Space optimization: empty string encodes more
+		// efficiently in export data.
+		return ""
+	}
+	if s, ok := leakTagCache[l]; ok {
+		return s
+	}
+
+	n := len(l)
+	for n > 0 && l[n-1] == 0 {
+		n--
+	}
+	s := "esc:" + string(l[:n])
+	leakTagCache[l] = s
+	return s
+}
+
+// parseLeaks parses a binary string representing a leaks
+func parseLeaks(s string) leaks {
+	var l leaks
+	if !strings.HasPrefix(s, "esc:") {
+		l.AddHeap(0)
+		return l
+	}
+	copy(l[:], s[4:])
+	return l
+}
+
+func Funcs(all []ir.Node) {
+	ir.VisitFuncsBottomUp(all, Batch)
+}
+
+const (
+	escFuncUnknown = 0 + iota
+	escFuncPlanned
+	escFuncStarted
+	escFuncTagged
+)
+
+// Mark labels that have no backjumps to them as not increasing e.loopdepth.
+type labelState int
+
+const (
+	looping labelState = 1 + iota
+	nonlooping
+)
+
+func isSliceSelfAssign(dst, src ir.Node) bool {
+	// Detect the following special case.
+	//
+	//	func (b *Buffer) Foo() {
+	//		n, m := ...
+	//		b.buf = b.buf[n:m]
+	//	}
+	//
+	// This assignment is a no-op for escape analysis,
+	// it does not store any new pointers into b that were not already there.
+	// However, without this special case b will escape, because we assign to OIND/ODOTPTR.
+	// Here we assume that the statement will not contain calls,
+	// that is, that order will move any calls to init.
+	// Otherwise base ONAME value could change between the moments
+	// when we evaluate it for dst and for src.
+
+	// dst is ONAME dereference.
+	var dstX ir.Node
+	switch dst.Op() {
+	default:
+		return false
+	case ir.ODEREF:
+		dst := dst.(*ir.StarExpr)
+		dstX = dst.X
+	case ir.ODOTPTR:
+		dst := dst.(*ir.SelectorExpr)
+		dstX = dst.X
+	}
+	if dstX.Op() != ir.ONAME {
+		return false
+	}
+	// src is a slice operation.
+	switch src.Op() {
+	case ir.OSLICE, ir.OSLICE3, ir.OSLICESTR:
+		// OK.
+	case ir.OSLICEARR, ir.OSLICE3ARR:
+		// Since arrays are embedded into containing object,
+		// slice of non-pointer array will introduce a new pointer into b that was not already there
+		// (pointer to b itself). After such assignment, if b contents escape,
+		// b escapes as well. If we ignore such OSLICEARR, we will conclude
+		// that b does not escape when b contents do.
+		//
+		// Pointer to an array is OK since it's not stored inside b directly.
+		// For slicing an array (not pointer to array), there is an implicit OADDR.
+		// We check that to determine non-pointer array slicing.
+		src := src.(*ir.SliceExpr)
+		if src.X.Op() == ir.OADDR {
+			return false
+		}
+	default:
+		return false
+	}
+	// slice is applied to ONAME dereference.
+	var baseX ir.Node
+	switch base := src.(*ir.SliceExpr).X; base.Op() {
+	default:
+		return false
+	case ir.ODEREF:
+		base := base.(*ir.StarExpr)
+		baseX = base.X
+	case ir.ODOTPTR:
+		base := base.(*ir.SelectorExpr)
+		baseX = base.X
+	}
+	if baseX.Op() != ir.ONAME {
+		return false
+	}
+	// dst and src reference the same base ONAME.
+	return dstX.(*ir.Name) == baseX.(*ir.Name)
+}
+
+// isSelfAssign reports whether assignment from src to dst can
+// be ignored by the escape analysis as it's effectively a self-assignment.
+func isSelfAssign(dst, src ir.Node) bool {
+	if isSliceSelfAssign(dst, src) {
+		return true
+	}
+
+	// Detect trivial assignments that assign back to the same object.
+	//
+	// It covers these cases:
+	//	val.x = val.y
+	//	val.x[i] = val.y[j]
+	//	val.x1.x2 = val.x1.y2
+	//	... etc
+	//
+	// These assignments do not change assigned object lifetime.
+
+	if dst == nil || src == nil || dst.Op() != src.Op() {
+		return false
+	}
+
+	// The expression prefix must be both "safe" and identical.
+	switch dst.Op() {
+	case ir.ODOT, ir.ODOTPTR:
+		// Safe trailing accessors that are permitted to differ.
+		dst := dst.(*ir.SelectorExpr)
+		src := src.(*ir.SelectorExpr)
+		return ir.SameSafeExpr(dst.X, src.X)
+	case ir.OINDEX:
+		dst := dst.(*ir.IndexExpr)
+		src := src.(*ir.IndexExpr)
+		if mayAffectMemory(dst.Index) || mayAffectMemory(src.Index) {
+			return false
+		}
+		return ir.SameSafeExpr(dst.X, src.X)
+	default:
+		return false
+	}
+}
+
+// mayAffectMemory reports whether evaluation of n may affect the program's
+// memory state. If the expression can't affect memory state, then it can be
+// safely ignored by the escape analysis.
+func mayAffectMemory(n ir.Node) bool {
+	// We may want to use a list of "memory safe" ops instead of generally
+	// "side-effect free", which would include all calls and other ops that can
+	// allocate or change global state. For now, it's safer to start with the latter.
+	//
+	// We're ignoring things like division by zero, index out of range,
+	// and nil pointer dereference here.
+
+	// TODO(rsc): It seems like it should be possible to replace this with
+	// an ir.Any looking for any op that's not the ones in the case statement.
+	// But that produces changes in the compiled output detected by buildall.
+	switch n.Op() {
+	case ir.ONAME, ir.OLITERAL, ir.ONIL:
+		return false
+
+	case ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.OLSH, ir.ORSH, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD:
+		n := n.(*ir.BinaryExpr)
+		return mayAffectMemory(n.X) || mayAffectMemory(n.Y)
+
+	case ir.OINDEX:
+		n := n.(*ir.IndexExpr)
+		return mayAffectMemory(n.X) || mayAffectMemory(n.Index)
+
+	case ir.OCONVNOP, ir.OCONV:
+		n := n.(*ir.ConvExpr)
+		return mayAffectMemory(n.X)
+
+	case ir.OLEN, ir.OCAP, ir.ONOT, ir.OBITNOT, ir.OPLUS, ir.ONEG, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
+		n := n.(*ir.UnaryExpr)
+		return mayAffectMemory(n.X)
+
+	case ir.ODOT, ir.ODOTPTR:
+		n := n.(*ir.SelectorExpr)
+		return mayAffectMemory(n.X)
+
+	case ir.ODEREF:
+		n := n.(*ir.StarExpr)
+		return mayAffectMemory(n.X)
+
+	default:
+		return true
+	}
+}
+
+// HeapAllocReason returns the reason the given Node must be heap
+// allocated, or the empty string if it doesn't.
+func HeapAllocReason(n ir.Node) string {
+	if n == nil || n.Type() == nil {
+		return ""
+	}
+
+	// Parameters are always passed via the stack.
+	if n.Op() == ir.ONAME {
+		n := n.(*ir.Name)
+		if n.Class == ir.PPARAM || n.Class == ir.PPARAMOUT {
+			return ""
+		}
+	}
+
+	if n.Type().Width > ir.MaxStackVarSize {
+		return "too large for stack"
+	}
+
+	if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Width > ir.MaxImplicitStackVarSize {
+		return "too large for stack"
+	}
+
+	if n.Op() == ir.OCLOSURE && typecheck.ClosureType(n.(*ir.ClosureExpr)).Size() > ir.MaxImplicitStackVarSize {
+		return "too large for stack"
+	}
+	if n.Op() == ir.OCALLPART && typecheck.PartialCallType(n.(*ir.SelectorExpr)).Size() > ir.MaxImplicitStackVarSize {
+		return "too large for stack"
+	}
+
+	if n.Op() == ir.OMAKESLICE {
+		n := n.(*ir.MakeExpr)
+		r := n.Cap
+		if r == nil {
+			r = n.Len
+		}
+		if !ir.IsSmallIntConst(r) {
+			return "non-constant size"
+		}
+		if t := n.Type(); t.Elem().Width != 0 && ir.Int64Val(r) > ir.MaxImplicitStackVarSize/t.Elem().Width {
+			return "too large for stack"
+		}
+	}
+
+	return ""
+}
+
+// This special tag is applied to uintptr variables
+// that we believe may hold unsafe.Pointers for
+// calls into assembly functions.
+const UnsafeUintptrNote = "unsafe-uintptr"
+
+// This special tag is applied to uintptr parameters of functions
+// marked go:uintptrescapes.
+const UintptrEscapesNote = "uintptr-escapes"
+
+func (b *batch) paramTag(fn *ir.Func, narg int, f *types.Field) string {
+	name := func() string {
+		if f.Sym != nil {
+			return f.Sym.Name
+		}
+		return fmt.Sprintf("arg#%d", narg)
+	}
+
+	if len(fn.Body) == 0 {
+		// Assume that uintptr arguments must be held live across the call.
+		// This is most important for syscall.Syscall.
+		// See golang.org/issue/13372.
+		// This really doesn't have much to do with escape analysis per se,
+		// but we are reusing the ability to annotate an individual function
+		// argument and pass those annotations along to importing code.
+		if f.Type.IsUintptr() {
+			if base.Flag.LowerM != 0 {
+				base.WarnfAt(f.Pos, "assuming %v is unsafe uintptr", name())
+			}
+			return UnsafeUintptrNote
+		}
+
+		if !f.Type.HasPointers() { // don't bother tagging for scalars
+			return ""
+		}
+
+		var esc leaks
+
+		// External functions are assumed unsafe, unless
+		// //go:noescape is given before the declaration.
+		if fn.Pragma&ir.Noescape != 0 {
+			if base.Flag.LowerM != 0 && f.Sym != nil {
+				base.WarnfAt(f.Pos, "%v does not escape", name())
+			}
+		} else {
+			if base.Flag.LowerM != 0 && f.Sym != nil {
+				base.WarnfAt(f.Pos, "leaking param: %v", name())
+			}
+			esc.AddHeap(0)
+		}
+
+		return esc.Encode()
+	}
+
+	if fn.Pragma&ir.UintptrEscapes != 0 {
+		if f.Type.IsUintptr() {
+			if base.Flag.LowerM != 0 {
+				base.WarnfAt(f.Pos, "marking %v as escaping uintptr", name())
+			}
+			return UintptrEscapesNote
+		}
+		if f.IsDDD() && f.Type.Elem().IsUintptr() {
+			// final argument is ...uintptr.
+			if base.Flag.LowerM != 0 {
+				base.WarnfAt(f.Pos, "marking %v as escaping ...uintptr", name())
+			}
+			return UintptrEscapesNote
+		}
+	}
+
+	if !f.Type.HasPointers() { // don't bother tagging for scalars
+		return ""
+	}
+
+	// Unnamed parameters are unused and therefore do not escape.
+	if f.Sym == nil || f.Sym.IsBlank() {
+		var esc leaks
+		return esc.Encode()
+	}
+
+	n := f.Nname.(*ir.Name)
+	loc := b.oldLoc(n)
+	esc := loc.paramEsc
+	esc.Optimize()
+
+	if base.Flag.LowerM != 0 && !loc.escapes {
+		if esc.Empty() {
+			base.WarnfAt(f.Pos, "%v does not escape", name())
+		}
+		if x := esc.Heap(); x >= 0 {
+			if x == 0 {
+				base.WarnfAt(f.Pos, "leaking param: %v", name())
+			} else {
+				// TODO(mdempsky): Mention level=x like below?
+				base.WarnfAt(f.Pos, "leaking param content: %v", name())
+			}
+		}
+		for i := 0; i < numEscResults; i++ {
+			if x := esc.Result(i); x >= 0 {
+				res := fn.Type().Results().Field(i).Sym
+				base.WarnfAt(f.Pos, "leaking param: %v to result %v level=%d", name(), res, x)
+			}
+		}
+	}
+
+	return esc.Encode()
+}
diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go
deleted file mode 100644
index 2f7fa27..0000000
--- a/src/cmd/compile/internal/gc/alg.go
+++ /dev/null
@@ -1,959 +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.
-
-package gc
-
-import (
-	"cmd/compile/internal/types"
-	"cmd/internal/obj"
-	"fmt"
-	"sort"
-)
-
-// AlgKind describes the kind of algorithms used for comparing and
-// hashing a Type.
-type AlgKind int
-
-//go:generate stringer -type AlgKind -trimprefix A
-
-const (
-	// These values are known by runtime.
-	ANOEQ AlgKind = iota
-	AMEM0
-	AMEM8
-	AMEM16
-	AMEM32
-	AMEM64
-	AMEM128
-	ASTRING
-	AINTER
-	ANILINTER
-	AFLOAT32
-	AFLOAT64
-	ACPLX64
-	ACPLX128
-
-	// Type can be compared/hashed as regular memory.
-	AMEM AlgKind = 100
-
-	// Type needs special comparison/hashing functions.
-	ASPECIAL AlgKind = -1
-)
-
-// IsComparable reports whether t is a comparable type.
-func IsComparable(t *types.Type) bool {
-	a, _ := algtype1(t)
-	return a != ANOEQ
-}
-
-// IsRegularMemory reports whether t can be compared/hashed as regular memory.
-func IsRegularMemory(t *types.Type) bool {
-	a, _ := algtype1(t)
-	return a == AMEM
-}
-
-// IncomparableField returns an incomparable Field of struct Type t, if any.
-func IncomparableField(t *types.Type) *types.Field {
-	for _, f := range t.FieldSlice() {
-		if !IsComparable(f.Type) {
-			return f
-		}
-	}
-	return nil
-}
-
-// EqCanPanic reports whether == on type t could panic (has an interface somewhere).
-// t must be comparable.
-func EqCanPanic(t *types.Type) bool {
-	switch t.Etype {
-	default:
-		return false
-	case TINTER:
-		return true
-	case TARRAY:
-		return EqCanPanic(t.Elem())
-	case TSTRUCT:
-		for _, f := range t.FieldSlice() {
-			if !f.Sym.IsBlank() && EqCanPanic(f.Type) {
-				return true
-			}
-		}
-		return false
-	}
-}
-
-// algtype is like algtype1, except it returns the fixed-width AMEMxx variants
-// instead of the general AMEM kind when possible.
-func algtype(t *types.Type) AlgKind {
-	a, _ := algtype1(t)
-	if a == AMEM {
-		switch t.Width {
-		case 0:
-			return AMEM0
-		case 1:
-			return AMEM8
-		case 2:
-			return AMEM16
-		case 4:
-			return AMEM32
-		case 8:
-			return AMEM64
-		case 16:
-			return AMEM128
-		}
-	}
-
-	return a
-}
-
-// algtype1 returns the AlgKind used for comparing and hashing Type t.
-// If it returns ANOEQ, it also returns the component type of t that
-// makes it incomparable.
-func algtype1(t *types.Type) (AlgKind, *types.Type) {
-	if t.Broke() {
-		return AMEM, nil
-	}
-	if t.Noalg() {
-		return ANOEQ, t
-	}
-
-	switch t.Etype {
-	case TANY, TFORW:
-		// will be defined later.
-		return ANOEQ, t
-
-	case TINT8, TUINT8, TINT16, TUINT16,
-		TINT32, TUINT32, TINT64, TUINT64,
-		TINT, TUINT, TUINTPTR,
-		TBOOL, TPTR,
-		TCHAN, TUNSAFEPTR:
-		return AMEM, nil
-
-	case TFUNC, TMAP:
-		return ANOEQ, t
-
-	case TFLOAT32:
-		return AFLOAT32, nil
-
-	case TFLOAT64:
-		return AFLOAT64, nil
-
-	case TCOMPLEX64:
-		return ACPLX64, nil
-
-	case TCOMPLEX128:
-		return ACPLX128, nil
-
-	case TSTRING:
-		return ASTRING, nil
-
-	case TINTER:
-		if t.IsEmptyInterface() {
-			return ANILINTER, nil
-		}
-		return AINTER, nil
-
-	case TSLICE:
-		return ANOEQ, t
-
-	case TARRAY:
-		a, bad := algtype1(t.Elem())
-		switch a {
-		case AMEM:
-			return AMEM, nil
-		case ANOEQ:
-			return ANOEQ, bad
-		}
-
-		switch t.NumElem() {
-		case 0:
-			// We checked above that the element type is comparable.
-			return AMEM, nil
-		case 1:
-			// Single-element array is same as its lone element.
-			return a, nil
-		}
-
-		return ASPECIAL, nil
-
-	case TSTRUCT:
-		fields := t.FieldSlice()
-
-		// One-field struct is same as that one field alone.
-		if len(fields) == 1 && !fields[0].Sym.IsBlank() {
-			return algtype1(fields[0].Type)
-		}
-
-		ret := AMEM
-		for i, f := range fields {
-			// All fields must be comparable.
-			a, bad := algtype1(f.Type)
-			if a == ANOEQ {
-				return ANOEQ, bad
-			}
-
-			// Blank fields, padded fields, fields with non-memory
-			// equality need special compare.
-			if a != AMEM || f.Sym.IsBlank() || ispaddedfield(t, i) {
-				ret = ASPECIAL
-			}
-		}
-
-		return ret, nil
-	}
-
-	Fatalf("algtype1: unexpected type %v", t)
-	return 0, nil
-}
-
-// genhash returns a symbol which is the closure used to compute
-// the hash of a value of type t.
-// Note: the generated function must match runtime.typehash exactly.
-func genhash(t *types.Type) *obj.LSym {
-	switch algtype(t) {
-	default:
-		// genhash is only called for types that have equality
-		Fatalf("genhash %v", t)
-	case AMEM0:
-		return sysClosure("memhash0")
-	case AMEM8:
-		return sysClosure("memhash8")
-	case AMEM16:
-		return sysClosure("memhash16")
-	case AMEM32:
-		return sysClosure("memhash32")
-	case AMEM64:
-		return sysClosure("memhash64")
-	case AMEM128:
-		return sysClosure("memhash128")
-	case ASTRING:
-		return sysClosure("strhash")
-	case AINTER:
-		return sysClosure("interhash")
-	case ANILINTER:
-		return sysClosure("nilinterhash")
-	case AFLOAT32:
-		return sysClosure("f32hash")
-	case AFLOAT64:
-		return sysClosure("f64hash")
-	case ACPLX64:
-		return sysClosure("c64hash")
-	case ACPLX128:
-		return sysClosure("c128hash")
-	case AMEM:
-		// For other sizes of plain memory, we build a closure
-		// that calls memhash_varlen. The size of the memory is
-		// encoded in the first slot of the closure.
-		closure := typeLookup(fmt.Sprintf(".hashfunc%d", t.Width)).Linksym()
-		if len(closure.P) > 0 { // already generated
-			return closure
-		}
-		if memhashvarlen == nil {
-			memhashvarlen = sysfunc("memhash_varlen")
-		}
-		ot := 0
-		ot = dsymptr(closure, ot, memhashvarlen, 0)
-		ot = duintptr(closure, ot, uint64(t.Width)) // size encoded in closure
-		ggloblsym(closure, int32(ot), obj.DUPOK|obj.RODATA)
-		return closure
-	case ASPECIAL:
-		break
-	}
-
-	closure := typesymprefix(".hashfunc", t).Linksym()
-	if len(closure.P) > 0 { // already generated
-		return closure
-	}
-
-	// Generate hash functions for subtypes.
-	// There are cases where we might not use these hashes,
-	// but in that case they will get dead-code eliminated.
-	// (And the closure generated by genhash will also get
-	// dead-code eliminated, as we call the subtype hashers
-	// directly.)
-	switch t.Etype {
-	case types.TARRAY:
-		genhash(t.Elem())
-	case types.TSTRUCT:
-		for _, f := range t.FieldSlice() {
-			genhash(f.Type)
-		}
-	}
-
-	sym := typesymprefix(".hash", t)
-	if Debug.r != 0 {
-		fmt.Printf("genhash %v %v %v\n", closure, sym, t)
-	}
-
-	lineno = autogeneratedPos // less confusing than end of input
-	dclcontext = PEXTERN
-
-	// func sym(p *T, h uintptr) uintptr
-	tfn := nod(OTFUNC, nil, nil)
-	tfn.List.Set2(
-		namedfield("p", types.NewPtr(t)),
-		namedfield("h", types.Types[TUINTPTR]),
-	)
-	tfn.Rlist.Set1(anonfield(types.Types[TUINTPTR]))
-
-	fn := dclfunc(sym, tfn)
-	np := asNode(tfn.Type.Params().Field(0).Nname)
-	nh := asNode(tfn.Type.Params().Field(1).Nname)
-
-	switch t.Etype {
-	case types.TARRAY:
-		// An array of pure memory would be handled by the
-		// standard algorithm, so the element type must not be
-		// pure memory.
-		hashel := hashfor(t.Elem())
-
-		n := nod(ORANGE, nil, nod(ODEREF, np, nil))
-		ni := newname(lookup("i"))
-		ni.Type = types.Types[TINT]
-		n.List.Set1(ni)
-		n.SetColas(true)
-		colasdefn(n.List.Slice(), n)
-		ni = n.List.First()
-
-		// h = hashel(&p[i], h)
-		call := nod(OCALL, hashel, nil)
-
-		nx := nod(OINDEX, np, ni)
-		nx.SetBounded(true)
-		na := nod(OADDR, nx, nil)
-		call.List.Append(na)
-		call.List.Append(nh)
-		n.Nbody.Append(nod(OAS, nh, call))
-
-		fn.Nbody.Append(n)
-
-	case types.TSTRUCT:
-		// Walk the struct using memhash for runs of AMEM
-		// and calling specific hash functions for the others.
-		for i, fields := 0, t.FieldSlice(); i < len(fields); {
-			f := fields[i]
-
-			// Skip blank fields.
-			if f.Sym.IsBlank() {
-				i++
-				continue
-			}
-
-			// Hash non-memory fields with appropriate hash function.
-			if !IsRegularMemory(f.Type) {
-				hashel := hashfor(f.Type)
-				call := nod(OCALL, hashel, nil)
-				nx := nodSym(OXDOT, np, f.Sym) // TODO: fields from other packages?
-				na := nod(OADDR, nx, nil)
-				call.List.Append(na)
-				call.List.Append(nh)
-				fn.Nbody.Append(nod(OAS, nh, call))
-				i++
-				continue
-			}
-
-			// Otherwise, hash a maximal length run of raw memory.
-			size, next := memrun(t, i)
-
-			// h = hashel(&p.first, size, h)
-			hashel := hashmem(f.Type)
-			call := nod(OCALL, hashel, nil)
-			nx := nodSym(OXDOT, np, f.Sym) // TODO: fields from other packages?
-			na := nod(OADDR, nx, nil)
-			call.List.Append(na)
-			call.List.Append(nh)
-			call.List.Append(nodintconst(size))
-			fn.Nbody.Append(nod(OAS, nh, call))
-
-			i = next
-		}
-	}
-
-	r := nod(ORETURN, nil, nil)
-	r.List.Append(nh)
-	fn.Nbody.Append(r)
-
-	if Debug.r != 0 {
-		dumplist("genhash body", fn.Nbody)
-	}
-
-	funcbody()
-
-	fn.Func.SetDupok(true)
-	fn = typecheck(fn, ctxStmt)
-
-	Curfn = fn
-	typecheckslice(fn.Nbody.Slice(), ctxStmt)
-	Curfn = nil
-
-	if debug_dclstack != 0 {
-		testdclstack()
-	}
-
-	fn.Func.SetNilCheckDisabled(true)
-	xtop = append(xtop, fn)
-
-	// Build closure. It doesn't close over any variables, so
-	// it contains just the function pointer.
-	dsymptr(closure, 0, sym.Linksym(), 0)
-	ggloblsym(closure, int32(Widthptr), obj.DUPOK|obj.RODATA)
-
-	return closure
-}
-
-func hashfor(t *types.Type) *Node {
-	var sym *types.Sym
-
-	switch a, _ := algtype1(t); a {
-	case AMEM:
-		Fatalf("hashfor with AMEM type")
-	case AINTER:
-		sym = Runtimepkg.Lookup("interhash")
-	case ANILINTER:
-		sym = Runtimepkg.Lookup("nilinterhash")
-	case ASTRING:
-		sym = Runtimepkg.Lookup("strhash")
-	case AFLOAT32:
-		sym = Runtimepkg.Lookup("f32hash")
-	case AFLOAT64:
-		sym = Runtimepkg.Lookup("f64hash")
-	case ACPLX64:
-		sym = Runtimepkg.Lookup("c64hash")
-	case ACPLX128:
-		sym = Runtimepkg.Lookup("c128hash")
-	default:
-		// Note: the caller of hashfor ensured that this symbol
-		// exists and has a body by calling genhash for t.
-		sym = typesymprefix(".hash", t)
-	}
-
-	n := newname(sym)
-	setNodeNameFunc(n)
-	n.Type = functype(nil, []*Node{
-		anonfield(types.NewPtr(t)),
-		anonfield(types.Types[TUINTPTR]),
-	}, []*Node{
-		anonfield(types.Types[TUINTPTR]),
-	})
-	return n
-}
-
-// sysClosure returns a closure which will call the
-// given runtime function (with no closed-over variables).
-func sysClosure(name string) *obj.LSym {
-	s := sysvar(name + "·f")
-	if len(s.P) == 0 {
-		f := sysfunc(name)
-		dsymptr(s, 0, f, 0)
-		ggloblsym(s, int32(Widthptr), obj.DUPOK|obj.RODATA)
-	}
-	return s
-}
-
-// geneq returns a symbol which is the closure used to compute
-// equality for two objects of type t.
-func geneq(t *types.Type) *obj.LSym {
-	switch algtype(t) {
-	case ANOEQ:
-		// The runtime will panic if it tries to compare
-		// a type with a nil equality function.
-		return nil
-	case AMEM0:
-		return sysClosure("memequal0")
-	case AMEM8:
-		return sysClosure("memequal8")
-	case AMEM16:
-		return sysClosure("memequal16")
-	case AMEM32:
-		return sysClosure("memequal32")
-	case AMEM64:
-		return sysClosure("memequal64")
-	case AMEM128:
-		return sysClosure("memequal128")
-	case ASTRING:
-		return sysClosure("strequal")
-	case AINTER:
-		return sysClosure("interequal")
-	case ANILINTER:
-		return sysClosure("nilinterequal")
-	case AFLOAT32:
-		return sysClosure("f32equal")
-	case AFLOAT64:
-		return sysClosure("f64equal")
-	case ACPLX64:
-		return sysClosure("c64equal")
-	case ACPLX128:
-		return sysClosure("c128equal")
-	case AMEM:
-		// make equality closure. The size of the type
-		// is encoded in the closure.
-		closure := typeLookup(fmt.Sprintf(".eqfunc%d", t.Width)).Linksym()
-		if len(closure.P) != 0 {
-			return closure
-		}
-		if memequalvarlen == nil {
-			memequalvarlen = sysvar("memequal_varlen") // asm func
-		}
-		ot := 0
-		ot = dsymptr(closure, ot, memequalvarlen, 0)
-		ot = duintptr(closure, ot, uint64(t.Width))
-		ggloblsym(closure, int32(ot), obj.DUPOK|obj.RODATA)
-		return closure
-	case ASPECIAL:
-		break
-	}
-
-	closure := typesymprefix(".eqfunc", t).Linksym()
-	if len(closure.P) > 0 { // already generated
-		return closure
-	}
-	sym := typesymprefix(".eq", t)
-	if Debug.r != 0 {
-		fmt.Printf("geneq %v\n", t)
-	}
-
-	// Autogenerate code for equality of structs and arrays.
-
-	lineno = autogeneratedPos // less confusing than end of input
-	dclcontext = PEXTERN
-
-	// func sym(p, q *T) bool
-	tfn := nod(OTFUNC, nil, nil)
-	tfn.List.Set2(
-		namedfield("p", types.NewPtr(t)),
-		namedfield("q", types.NewPtr(t)),
-	)
-	tfn.Rlist.Set1(namedfield("r", types.Types[TBOOL]))
-
-	fn := dclfunc(sym, tfn)
-	np := asNode(tfn.Type.Params().Field(0).Nname)
-	nq := asNode(tfn.Type.Params().Field(1).Nname)
-	nr := asNode(tfn.Type.Results().Field(0).Nname)
-
-	// Label to jump to if an equality test fails.
-	neq := autolabel(".neq")
-
-	// We reach here only for types that have equality but
-	// cannot be handled by the standard algorithms,
-	// so t must be either an array or a struct.
-	switch t.Etype {
-	default:
-		Fatalf("geneq %v", t)
-
-	case TARRAY:
-		nelem := t.NumElem()
-
-		// checkAll generates code to check the equality of all array elements.
-		// If unroll is greater than nelem, checkAll generates:
-		//
-		// if eq(p[0], q[0]) && eq(p[1], q[1]) && ... {
-		// } else {
-		//   return
-		// }
-		//
-		// And so on.
-		//
-		// Otherwise it generates:
-		//
-		// for i := 0; i < nelem; i++ {
-		//   if eq(p[i], q[i]) {
-		//   } else {
-		//     goto neq
-		//   }
-		// }
-		//
-		// TODO(josharian): consider doing some loop unrolling
-		// for larger nelem as well, processing a few elements at a time in a loop.
-		checkAll := func(unroll int64, last bool, eq func(pi, qi *Node) *Node) {
-			// checkIdx generates a node to check for equality at index i.
-			checkIdx := func(i *Node) *Node {
-				// pi := p[i]
-				pi := nod(OINDEX, np, i)
-				pi.SetBounded(true)
-				pi.Type = t.Elem()
-				// qi := q[i]
-				qi := nod(OINDEX, nq, i)
-				qi.SetBounded(true)
-				qi.Type = t.Elem()
-				return eq(pi, qi)
-			}
-
-			if nelem <= unroll {
-				if last {
-					// Do last comparison in a different manner.
-					nelem--
-				}
-				// Generate a series of checks.
-				for i := int64(0); i < nelem; i++ {
-					// if check {} else { goto neq }
-					nif := nod(OIF, checkIdx(nodintconst(i)), nil)
-					nif.Rlist.Append(nodSym(OGOTO, nil, neq))
-					fn.Nbody.Append(nif)
-				}
-				if last {
-					fn.Nbody.Append(nod(OAS, nr, checkIdx(nodintconst(nelem))))
-				}
-			} else {
-				// Generate a for loop.
-				// for i := 0; i < nelem; i++
-				i := temp(types.Types[TINT])
-				init := nod(OAS, i, nodintconst(0))
-				cond := nod(OLT, i, nodintconst(nelem))
-				post := nod(OAS, i, nod(OADD, i, nodintconst(1)))
-				loop := nod(OFOR, cond, post)
-				loop.Ninit.Append(init)
-				// if eq(pi, qi) {} else { goto neq }
-				nif := nod(OIF, checkIdx(i), nil)
-				nif.Rlist.Append(nodSym(OGOTO, nil, neq))
-				loop.Nbody.Append(nif)
-				fn.Nbody.Append(loop)
-				if last {
-					fn.Nbody.Append(nod(OAS, nr, nodbool(true)))
-				}
-			}
-		}
-
-		switch t.Elem().Etype {
-		case TSTRING:
-			// Do two loops. First, check that all the lengths match (cheap).
-			// Second, check that all the contents match (expensive).
-			// TODO: when the array size is small, unroll the length match checks.
-			checkAll(3, false, func(pi, qi *Node) *Node {
-				// Compare lengths.
-				eqlen, _ := eqstring(pi, qi)
-				return eqlen
-			})
-			checkAll(1, true, func(pi, qi *Node) *Node {
-				// Compare contents.
-				_, eqmem := eqstring(pi, qi)
-				return eqmem
-			})
-		case TFLOAT32, TFLOAT64:
-			checkAll(2, true, func(pi, qi *Node) *Node {
-				// p[i] == q[i]
-				return nod(OEQ, pi, qi)
-			})
-		// TODO: pick apart structs, do them piecemeal too
-		default:
-			checkAll(1, true, func(pi, qi *Node) *Node {
-				// p[i] == q[i]
-				return nod(OEQ, pi, qi)
-			})
-		}
-
-	case TSTRUCT:
-		// Build a list of conditions to satisfy.
-		// The conditions are a list-of-lists. Conditions are reorderable
-		// within each inner list. The outer lists must be evaluated in order.
-		var conds [][]*Node
-		conds = append(conds, []*Node{})
-		and := func(n *Node) {
-			i := len(conds) - 1
-			conds[i] = append(conds[i], n)
-		}
-
-		// Walk the struct using memequal for runs of AMEM
-		// and calling specific equality tests for the others.
-		for i, fields := 0, t.FieldSlice(); i < len(fields); {
-			f := fields[i]
-
-			// Skip blank-named fields.
-			if f.Sym.IsBlank() {
-				i++
-				continue
-			}
-
-			// Compare non-memory fields with field equality.
-			if !IsRegularMemory(f.Type) {
-				if EqCanPanic(f.Type) {
-					// Enforce ordering by starting a new set of reorderable conditions.
-					conds = append(conds, []*Node{})
-				}
-				p := nodSym(OXDOT, np, f.Sym)
-				q := nodSym(OXDOT, nq, f.Sym)
-				switch {
-				case f.Type.IsString():
-					eqlen, eqmem := eqstring(p, q)
-					and(eqlen)
-					and(eqmem)
-				default:
-					and(nod(OEQ, p, q))
-				}
-				if EqCanPanic(f.Type) {
-					// Also enforce ordering after something that can panic.
-					conds = append(conds, []*Node{})
-				}
-				i++
-				continue
-			}
-
-			// Find maximal length run of memory-only fields.
-			size, next := memrun(t, i)
-
-			// TODO(rsc): All the calls to newname are wrong for
-			// cross-package unexported fields.
-			if s := fields[i:next]; len(s) <= 2 {
-				// Two or fewer fields: use plain field equality.
-				for _, f := range s {
-					and(eqfield(np, nq, f.Sym))
-				}
-			} else {
-				// More than two fields: use memequal.
-				and(eqmem(np, nq, f.Sym, size))
-			}
-			i = next
-		}
-
-		// Sort conditions to put runtime calls last.
-		// Preserve the rest of the ordering.
-		var flatConds []*Node
-		for _, c := range conds {
-			isCall := func(n *Node) bool {
-				return n.Op == OCALL || n.Op == OCALLFUNC
-			}
-			sort.SliceStable(c, func(i, j int) bool {
-				return !isCall(c[i]) && isCall(c[j])
-			})
-			flatConds = append(flatConds, c...)
-		}
-
-		if len(flatConds) == 0 {
-			fn.Nbody.Append(nod(OAS, nr, nodbool(true)))
-		} else {
-			for _, c := range flatConds[:len(flatConds)-1] {
-				// if cond {} else { goto neq }
-				n := nod(OIF, c, nil)
-				n.Rlist.Append(nodSym(OGOTO, nil, neq))
-				fn.Nbody.Append(n)
-			}
-			fn.Nbody.Append(nod(OAS, nr, flatConds[len(flatConds)-1]))
-		}
-	}
-
-	// ret:
-	//   return
-	ret := autolabel(".ret")
-	fn.Nbody.Append(nodSym(OLABEL, nil, ret))
-	fn.Nbody.Append(nod(ORETURN, nil, nil))
-
-	// neq:
-	//   r = false
-	//   return (or goto ret)
-	fn.Nbody.Append(nodSym(OLABEL, nil, neq))
-	fn.Nbody.Append(nod(OAS, nr, nodbool(false)))
-	if EqCanPanic(t) || hasCall(fn) {
-		// Epilogue is large, so share it with the equal case.
-		fn.Nbody.Append(nodSym(OGOTO, nil, ret))
-	} else {
-		// Epilogue is small, so don't bother sharing.
-		fn.Nbody.Append(nod(ORETURN, nil, nil))
-	}
-	// TODO(khr): the epilogue size detection condition above isn't perfect.
-	// We should really do a generic CL that shares epilogues across
-	// the board. See #24936.
-
-	if Debug.r != 0 {
-		dumplist("geneq body", fn.Nbody)
-	}
-
-	funcbody()
-
-	fn.Func.SetDupok(true)
-	fn = typecheck(fn, ctxStmt)
-
-	Curfn = fn
-	typecheckslice(fn.Nbody.Slice(), ctxStmt)
-	Curfn = nil
-
-	if debug_dclstack != 0 {
-		testdclstack()
-	}
-
-	// Disable checknils while compiling this code.
-	// We are comparing a struct or an array,
-	// neither of which can be nil, and our comparisons
-	// are shallow.
-	fn.Func.SetNilCheckDisabled(true)
-	xtop = append(xtop, fn)
-
-	// Generate a closure which points at the function we just generated.
-	dsymptr(closure, 0, sym.Linksym(), 0)
-	ggloblsym(closure, int32(Widthptr), obj.DUPOK|obj.RODATA)
-	return closure
-}
-
-func hasCall(n *Node) bool {
-	if n.Op == OCALL || n.Op == OCALLFUNC {
-		return true
-	}
-	if n.Left != nil && hasCall(n.Left) {
-		return true
-	}
-	if n.Right != nil && hasCall(n.Right) {
-		return true
-	}
-	for _, x := range n.Ninit.Slice() {
-		if hasCall(x) {
-			return true
-		}
-	}
-	for _, x := range n.Nbody.Slice() {
-		if hasCall(x) {
-			return true
-		}
-	}
-	for _, x := range n.List.Slice() {
-		if hasCall(x) {
-			return true
-		}
-	}
-	for _, x := range n.Rlist.Slice() {
-		if hasCall(x) {
-			return true
-		}
-	}
-	return false
-}
-
-// eqfield returns the node
-// 	p.field == q.field
-func eqfield(p *Node, q *Node, field *types.Sym) *Node {
-	nx := nodSym(OXDOT, p, field)
-	ny := nodSym(OXDOT, q, field)
-	ne := nod(OEQ, nx, ny)
-	return ne
-}
-
-// eqstring returns the nodes
-//   len(s) == len(t)
-// and
-//   memequal(s.ptr, t.ptr, len(s))
-// which can be used to construct string equality comparison.
-// eqlen must be evaluated before eqmem, and shortcircuiting is required.
-func eqstring(s, t *Node) (eqlen, eqmem *Node) {
-	s = conv(s, types.Types[TSTRING])
-	t = conv(t, types.Types[TSTRING])
-	sptr := nod(OSPTR, s, nil)
-	tptr := nod(OSPTR, t, nil)
-	slen := conv(nod(OLEN, s, nil), types.Types[TUINTPTR])
-	tlen := conv(nod(OLEN, t, nil), types.Types[TUINTPTR])
-
-	fn := syslook("memequal")
-	fn = substArgTypes(fn, types.Types[TUINT8], types.Types[TUINT8])
-	call := nod(OCALL, fn, nil)
-	call.List.Append(sptr, tptr, slen.copy())
-	call = typecheck(call, ctxExpr|ctxMultiOK)
-
-	cmp := nod(OEQ, slen, tlen)
-	cmp = typecheck(cmp, ctxExpr)
-	cmp.Type = types.Types[TBOOL]
-	return cmp, call
-}
-
-// eqinterface returns the nodes
-//   s.tab == t.tab (or s.typ == t.typ, as appropriate)
-// and
-//   ifaceeq(s.tab, s.data, t.data) (or efaceeq(s.typ, s.data, t.data), as appropriate)
-// which can be used to construct interface equality comparison.
-// eqtab must be evaluated before eqdata, and shortcircuiting is required.
-func eqinterface(s, t *Node) (eqtab, eqdata *Node) {
-	if !types.Identical(s.Type, t.Type) {
-		Fatalf("eqinterface %v %v", s.Type, t.Type)
-	}
-	// func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
-	// func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
-	var fn *Node
-	if s.Type.IsEmptyInterface() {
-		fn = syslook("efaceeq")
-	} else {
-		fn = syslook("ifaceeq")
-	}
-
-	stab := nod(OITAB, s, nil)
-	ttab := nod(OITAB, t, nil)
-	sdata := nod(OIDATA, s, nil)
-	tdata := nod(OIDATA, t, nil)
-	sdata.Type = types.Types[TUNSAFEPTR]
-	tdata.Type = types.Types[TUNSAFEPTR]
-	sdata.SetTypecheck(1)
-	tdata.SetTypecheck(1)
-
-	call := nod(OCALL, fn, nil)
-	call.List.Append(stab, sdata, tdata)
-	call = typecheck(call, ctxExpr|ctxMultiOK)
-
-	cmp := nod(OEQ, stab, ttab)
-	cmp = typecheck(cmp, ctxExpr)
-	cmp.Type = types.Types[TBOOL]
-	return cmp, call
-}
-
-// eqmem returns the node
-// 	memequal(&p.field, &q.field [, size])
-func eqmem(p *Node, q *Node, field *types.Sym, size int64) *Node {
-	nx := nod(OADDR, nodSym(OXDOT, p, field), nil)
-	ny := nod(OADDR, nodSym(OXDOT, q, field), nil)
-	nx = typecheck(nx, ctxExpr)
-	ny = typecheck(ny, ctxExpr)
-
-	fn, needsize := eqmemfunc(size, nx.Type.Elem())
-	call := nod(OCALL, fn, nil)
-	call.List.Append(nx)
-	call.List.Append(ny)
-	if needsize {
-		call.List.Append(nodintconst(size))
-	}
-
-	return call
-}
-
-func eqmemfunc(size int64, t *types.Type) (fn *Node, needsize bool) {
-	switch size {
-	default:
-		fn = syslook("memequal")
-		needsize = true
-	case 1, 2, 4, 8, 16:
-		buf := fmt.Sprintf("memequal%d", int(size)*8)
-		fn = syslook(buf)
-	}
-
-	fn = substArgTypes(fn, t, t)
-	return fn, needsize
-}
-
-// memrun finds runs of struct fields for which memory-only algs are appropriate.
-// t is the parent struct type, and start is the field index at which to start the run.
-// size is the length in bytes of the memory included in the run.
-// next is the index just after the end of the memory run.
-func memrun(t *types.Type, start int) (size int64, next int) {
-	next = start
-	for {
-		next++
-		if next == t.NumFields() {
-			break
-		}
-		// Stop run after a padded field.
-		if ispaddedfield(t, next-1) {
-			break
-		}
-		// Also, stop before a blank or non-memory field.
-		if f := t.Field(next); f.Sym.IsBlank() || !IsRegularMemory(f.Type) {
-			break
-		}
-	}
-	return t.Field(next-1).End() - t.Field(start).Offset, next
-}
-
-// ispaddedfield reports whether the i'th field of struct type t is followed
-// by padding.
-func ispaddedfield(t *types.Type, i int) bool {
-	if !t.IsStruct() {
-		Fatalf("ispaddedfield called non-struct %v", t)
-	}
-	end := t.Width
-	if i+1 < t.NumFields() {
-		end = t.Field(i + 1).Offset
-	}
-	return t.Field(i).End() != end
-}
diff --git a/src/cmd/compile/internal/gc/algkind_string.go b/src/cmd/compile/internal/gc/algkind_string.go
deleted file mode 100644
index 52b5399..0000000
--- a/src/cmd/compile/internal/gc/algkind_string.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Code generated by "stringer -type AlgKind -trimprefix A"; DO NOT EDIT.
-
-package gc
-
-import "strconv"
-
-func _() {
-	// An "invalid array index" compiler error signifies that the constant values have changed.
-	// Re-run the stringer command to generate them again.
-	var x [1]struct{}
-	_ = x[ANOEQ-0]
-	_ = x[AMEM0-1]
-	_ = x[AMEM8-2]
-	_ = x[AMEM16-3]
-	_ = x[AMEM32-4]
-	_ = x[AMEM64-5]
-	_ = x[AMEM128-6]
-	_ = x[ASTRING-7]
-	_ = x[AINTER-8]
-	_ = x[ANILINTER-9]
-	_ = x[AFLOAT32-10]
-	_ = x[AFLOAT64-11]
-	_ = x[ACPLX64-12]
-	_ = x[ACPLX128-13]
-	_ = x[AMEM-100]
-	_ = x[ASPECIAL - -1]
-}
-
-const (
-	_AlgKind_name_0 = "SPECIALNOEQMEM0MEM8MEM16MEM32MEM64MEM128STRINGINTERNILINTERFLOAT32FLOAT64CPLX64CPLX128"
-	_AlgKind_name_1 = "MEM"
-)
-
-var (
-	_AlgKind_index_0 = [...]uint8{0, 7, 11, 15, 19, 24, 29, 34, 40, 46, 51, 59, 66, 73, 79, 86}
-)
-
-func (i AlgKind) String() string {
-	switch {
-	case -1 <= i && i <= 13:
-		i -= -1
-		return _AlgKind_name_0[_AlgKind_index_0[i]:_AlgKind_index_0[i+1]]
-	case i == 100:
-		return _AlgKind_name_1
-	default:
-		return "AlgKind(" + strconv.FormatInt(int64(i), 10) + ")"
-	}
-}
diff --git a/src/cmd/compile/internal/gc/align.go b/src/cmd/compile/internal/gc/align.go
deleted file mode 100644
index a3a0c8f..0000000
--- a/src/cmd/compile/internal/gc/align.go
+++ /dev/null
@@ -1,531 +0,0 @@
-// Copyright 2009 The Go Authors. 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 (
-	"bytes"
-	"cmd/compile/internal/types"
-	"fmt"
-	"sort"
-)
-
-// sizeCalculationDisabled indicates whether it is safe
-// to calculate Types' widths and alignments. See dowidth.
-var sizeCalculationDisabled bool
-
-// machine size and rounding alignment is dictated around
-// the size of a pointer, set in betypeinit (see ../amd64/galign.go).
-var defercalc int
-
-func Rnd(o int64, r int64) int64 {
-	if r < 1 || r > 8 || r&(r-1) != 0 {
-		Fatalf("rnd %d", r)
-	}
-	return (o + r - 1) &^ (r - 1)
-}
-
-// expandiface computes the method set for interface type t by
-// expanding embedded interfaces.
-func expandiface(t *types.Type) {
-	seen := make(map[*types.Sym]*types.Field)
-	var methods []*types.Field
-
-	addMethod := func(m *types.Field, explicit bool) {
-		switch prev := seen[m.Sym]; {
-		case prev == nil:
-			seen[m.Sym] = m
-		case langSupported(1, 14, t.Pkg()) && !explicit && types.Identical(m.Type, prev.Type):
-			return
-		default:
-			yyerrorl(m.Pos, "duplicate method %s", m.Sym.Name)
-		}
-		methods = append(methods, m)
-	}
-
-	for _, m := range t.Methods().Slice() {
-		if m.Sym == nil {
-			continue
-		}
-
-		checkwidth(m.Type)
-		addMethod(m, true)
-	}
-
-	for _, m := range t.Methods().Slice() {
-		if m.Sym != nil {
-			continue
-		}
-
-		if !m.Type.IsInterface() {
-			yyerrorl(m.Pos, "interface contains embedded non-interface %v", m.Type)
-			m.SetBroke(true)
-			t.SetBroke(true)
-			// Add to fields so that error messages
-			// include the broken embedded type when
-			// printing t.
-			// TODO(mdempsky): Revisit this.
-			methods = append(methods, m)
-			continue
-		}
-
-		// Embedded interface: duplicate all methods
-		// (including broken ones, if any) and add to t's
-		// method set.
-		for _, t1 := range m.Type.Fields().Slice() {
-			f := types.NewField()
-			f.Pos = m.Pos // preserve embedding position
-			f.Sym = t1.Sym
-			f.Type = t1.Type
-			f.SetBroke(t1.Broke())
-			addMethod(f, false)
-		}
-	}
-
-	sort.Sort(methcmp(methods))
-
-	if int64(len(methods)) >= thearch.MAXWIDTH/int64(Widthptr) {
-		yyerrorl(typePos(t), "interface too large")
-	}
-	for i, m := range methods {
-		m.Offset = int64(i) * int64(Widthptr)
-	}
-
-	// Access fields directly to avoid recursively calling dowidth
-	// within Type.Fields().
-	t.Extra.(*types.Interface).Fields.Set(methods)
-}
-
-func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 {
-	starto := o
-	maxalign := int32(flag)
-	if maxalign < 1 {
-		maxalign = 1
-	}
-	lastzero := int64(0)
-	for _, f := range t.Fields().Slice() {
-		if f.Type == nil {
-			// broken field, just skip it so that other valid fields
-			// get a width.
-			continue
-		}
-
-		dowidth(f.Type)
-		if int32(f.Type.Align) > maxalign {
-			maxalign = int32(f.Type.Align)
-		}
-		if f.Type.Align > 0 {
-			o = Rnd(o, int64(f.Type.Align))
-		}
-		f.Offset = o
-		if n := asNode(f.Nname); n != nil {
-			// addrescapes has similar code to update these offsets.
-			// Usually addrescapes runs after widstruct,
-			// in which case we could drop this,
-			// but function closure functions are the exception.
-			// NOTE(rsc): This comment may be stale.
-			// It's possible the ordering has changed and this is
-			// now the common case. I'm not sure.
-			if n.Name.Param.Stackcopy != nil {
-				n.Name.Param.Stackcopy.Xoffset = o
-				n.Xoffset = 0
-			} else {
-				n.Xoffset = o
-			}
-		}
-
-		w := f.Type.Width
-		if w < 0 {
-			Fatalf("invalid width %d", f.Type.Width)
-		}
-		if w == 0 {
-			lastzero = o
-		}
-		o += w
-		maxwidth := thearch.MAXWIDTH
-		// On 32-bit systems, reflect tables impose an additional constraint
-		// that each field start offset must fit in 31 bits.
-		if maxwidth < 1<<32 {
-			maxwidth = 1<<31 - 1
-		}
-		if o >= maxwidth {
-			yyerrorl(typePos(errtype), "type %L too large", errtype)
-			o = 8 // small but nonzero
-		}
-	}
-
-	// For nonzero-sized structs which end in a zero-sized thing, we add
-	// an extra byte of padding to the type. This padding ensures that
-	// taking the address of the zero-sized thing can't manufacture a
-	// pointer to the next object in the heap. See issue 9401.
-	if flag == 1 && o > starto && o == lastzero {
-		o++
-	}
-
-	// final width is rounded
-	if flag != 0 {
-		o = Rnd(o, int64(maxalign))
-	}
-	t.Align = uint8(maxalign)
-
-	// type width only includes back to first field's offset
-	t.Width = o - starto
-
-	return o
-}
-
-// findTypeLoop searches for an invalid type declaration loop involving
-// type t and reports whether one is found. If so, path contains the
-// loop.
-//
-// path points to a slice used for tracking the sequence of types
-// visited. Using a pointer to a slice allows the slice capacity to
-// grow and limit reallocations.
-func findTypeLoop(t *types.Type, path *[]*types.Type) bool {
-	// We implement a simple DFS loop-finding algorithm. This
-	// could be faster, but type cycles are rare.
-
-	if t.Sym != nil {
-		// Declared type. Check for loops and otherwise
-		// recurse on the type expression used in the type
-		// declaration.
-
-		for i, x := range *path {
-			if x == t {
-				*path = (*path)[i:]
-				return true
-			}
-		}
-
-		*path = append(*path, t)
-		if p := asNode(t.Nod).Name.Param; p != nil && findTypeLoop(p.Ntype.Type, path) {
-			return true
-		}
-		*path = (*path)[:len(*path)-1]
-	} else {
-		// Anonymous type. Recurse on contained types.
-
-		switch t.Etype {
-		case TARRAY:
-			if findTypeLoop(t.Elem(), path) {
-				return true
-			}
-		case TSTRUCT:
-			for _, f := range t.Fields().Slice() {
-				if findTypeLoop(f.Type, path) {
-					return true
-				}
-			}
-		case TINTER:
-			for _, m := range t.Methods().Slice() {
-				if m.Type.IsInterface() { // embedded interface
-					if findTypeLoop(m.Type, path) {
-						return true
-					}
-				}
-			}
-		}
-	}
-
-	return false
-}
-
-func reportTypeLoop(t *types.Type) {
-	if t.Broke() {
-		return
-	}
-
-	var l []*types.Type
-	if !findTypeLoop(t, &l) {
-		Fatalf("failed to find type loop for: %v", t)
-	}
-
-	// Rotate loop so that the earliest type declaration is first.
-	i := 0
-	for j, t := range l[1:] {
-		if typePos(t).Before(typePos(l[i])) {
-			i = j + 1
-		}
-	}
-	l = append(l[i:], l[:i]...)
-
-	var msg bytes.Buffer
-	fmt.Fprintf(&msg, "invalid recursive type %v\n", l[0])
-	for _, t := range l {
-		fmt.Fprintf(&msg, "\t%v: %v refers to\n", linestr(typePos(t)), t)
-		t.SetBroke(true)
-	}
-	fmt.Fprintf(&msg, "\t%v: %v", linestr(typePos(l[0])), l[0])
-	yyerrorl(typePos(l[0]), msg.String())
-}
-
-// dowidth calculates and stores the size and alignment for t.
-// If sizeCalculationDisabled is set, and the size/alignment
-// have not already been calculated, it calls Fatal.
-// This is used to prevent data races in the back end.
-func dowidth(t *types.Type) {
-	// Calling dowidth when typecheck tracing enabled is not safe.
-	// See issue #33658.
-	if enableTrace && skipDowidthForTracing {
-		return
-	}
-	if Widthptr == 0 {
-		Fatalf("dowidth without betypeinit")
-	}
-
-	if t == nil {
-		return
-	}
-
-	if t.Width == -2 {
-		reportTypeLoop(t)
-		t.Width = 0
-		t.Align = 1
-		return
-	}
-
-	if t.WidthCalculated() {
-		return
-	}
-
-	if sizeCalculationDisabled {
-		if t.Broke() {
-			// break infinite recursion from Fatal call below
-			return
-		}
-		t.SetBroke(true)
-		Fatalf("width not calculated: %v", t)
-	}
-
-	// break infinite recursion if the broken recursive type
-	// is referenced again
-	if t.Broke() && t.Width == 0 {
-		return
-	}
-
-	// defer checkwidth calls until after we're done
-	defercheckwidth()
-
-	lno := lineno
-	if asNode(t.Nod) != nil {
-		lineno = asNode(t.Nod).Pos
-	}
-
-	t.Width = -2
-	t.Align = 0 // 0 means use t.Width, below
-
-	et := t.Etype
-	switch et {
-	case TFUNC, TCHAN, TMAP, TSTRING:
-		break
-
-	// simtype == 0 during bootstrap
-	default:
-		if simtype[t.Etype] != 0 {
-			et = simtype[t.Etype]
-		}
-	}
-
-	var w int64
-	switch et {
-	default:
-		Fatalf("dowidth: unknown type: %v", t)
-
-	// compiler-specific stuff
-	case TINT8, TUINT8, TBOOL:
-		// bool is int8
-		w = 1
-
-	case TINT16, TUINT16:
-		w = 2
-
-	case TINT32, TUINT32, TFLOAT32:
-		w = 4
-
-	case TINT64, TUINT64, TFLOAT64:
-		w = 8
-		t.Align = uint8(Widthreg)
-
-	case TCOMPLEX64:
-		w = 8
-		t.Align = 4
-
-	case TCOMPLEX128:
-		w = 16
-		t.Align = uint8(Widthreg)
-
-	case TPTR:
-		w = int64(Widthptr)
-		checkwidth(t.Elem())
-
-	case TUNSAFEPTR:
-		w = int64(Widthptr)
-
-	case TINTER: // implemented as 2 pointers
-		w = 2 * int64(Widthptr)
-		t.Align = uint8(Widthptr)
-		expandiface(t)
-
-	case TCHAN: // implemented as pointer
-		w = int64(Widthptr)
-
-		checkwidth(t.Elem())
-
-		// make fake type to check later to
-		// trigger channel argument check.
-		t1 := types.NewChanArgs(t)
-		checkwidth(t1)
-
-	case TCHANARGS:
-		t1 := t.ChanArgs()
-		dowidth(t1) // just in case
-		if t1.Elem().Width >= 1<<16 {
-			yyerrorl(typePos(t1), "channel element type too large (>64kB)")
-		}
-		w = 1 // anything will do
-
-	case TMAP: // implemented as pointer
-		w = int64(Widthptr)
-		checkwidth(t.Elem())
-		checkwidth(t.Key())
-
-	case TFORW: // should have been filled in
-		reportTypeLoop(t)
-		w = 1 // anything will do
-
-	case TANY:
-		// dummy type; should be replaced before use.
-		Fatalf("dowidth any")
-
-	case TSTRING:
-		if sizeofString == 0 {
-			Fatalf("early dowidth string")
-		}
-		w = sizeofString
-		t.Align = uint8(Widthptr)
-
-	case TARRAY:
-		if t.Elem() == nil {
-			break
-		}
-
-		dowidth(t.Elem())
-		if t.Elem().Width != 0 {
-			cap := (uint64(thearch.MAXWIDTH) - 1) / uint64(t.Elem().Width)
-			if uint64(t.NumElem()) > cap {
-				yyerrorl(typePos(t), "type %L larger than address space", t)
-			}
-		}
-		w = t.NumElem() * t.Elem().Width
-		t.Align = t.Elem().Align
-
-	case TSLICE:
-		if t.Elem() == nil {
-			break
-		}
-		w = sizeofSlice
-		checkwidth(t.Elem())
-		t.Align = uint8(Widthptr)
-
-	case TSTRUCT:
-		if t.IsFuncArgStruct() {
-			Fatalf("dowidth fn struct %v", t)
-		}
-		w = widstruct(t, t, 0, 1)
-
-	// make fake type to check later to
-	// trigger function argument computation.
-	case TFUNC:
-		t1 := types.NewFuncArgs(t)
-		checkwidth(t1)
-		w = int64(Widthptr) // width of func type is pointer
-
-	// function is 3 cated structures;
-	// compute their widths as side-effect.
-	case TFUNCARGS:
-		t1 := t.FuncArgs()
-		w = widstruct(t1, t1.Recvs(), 0, 0)
-		w = widstruct(t1, t1.Params(), w, Widthreg)
-		w = widstruct(t1, t1.Results(), w, Widthreg)
-		t1.Extra.(*types.Func).Argwid = w
-		if w%int64(Widthreg) != 0 {
-			Warn("bad type %v %d\n", t1, w)
-		}
-		t.Align = 1
-	}
-
-	if Widthptr == 4 && w != int64(int32(w)) {
-		yyerrorl(typePos(t), "type %v too large", t)
-	}
-
-	t.Width = w
-	if t.Align == 0 {
-		if w == 0 || w > 8 || w&(w-1) != 0 {
-			Fatalf("invalid alignment for %v", t)
-		}
-		t.Align = uint8(w)
-	}
-
-	lineno = lno
-
-	resumecheckwidth()
-}
-
-// when a type's width should be known, we call checkwidth
-// to compute it.  during a declaration like
-//
-//	type T *struct { next T }
-//
-// it is necessary to defer the calculation of the struct width
-// until after T has been initialized to be a pointer to that struct.
-// similarly, during import processing structs may be used
-// before their definition.  in those situations, calling
-// defercheckwidth() stops width calculations until
-// resumecheckwidth() is called, at which point all the
-// checkwidths that were deferred are executed.
-// dowidth should only be called when the type's size
-// is needed immediately.  checkwidth makes sure the
-// size is evaluated eventually.
-
-var deferredTypeStack []*types.Type
-
-func checkwidth(t *types.Type) {
-	if t == nil {
-		return
-	}
-
-	// function arg structs should not be checked
-	// outside of the enclosing function.
-	if t.IsFuncArgStruct() {
-		Fatalf("checkwidth %v", t)
-	}
-
-	if defercalc == 0 {
-		dowidth(t)
-		return
-	}
-
-	// if type has not yet been pushed on deferredTypeStack yet, do it now
-	if !t.Deferwidth() {
-		t.SetDeferwidth(true)
-		deferredTypeStack = append(deferredTypeStack, t)
-	}
-}
-
-func defercheckwidth() {
-	defercalc++
-}
-
-func resumecheckwidth() {
-	if defercalc == 1 {
-		for len(deferredTypeStack) > 0 {
-			t := deferredTypeStack[len(deferredTypeStack)-1]
-			deferredTypeStack = deferredTypeStack[:len(deferredTypeStack)-1]
-			t.SetDeferwidth(false)
-			dowidth(t)
-		}
-	}
-
-	defercalc--
-}
diff --git a/src/cmd/compile/internal/gc/bench_test.go b/src/cmd/compile/internal/gc/bench_test.go
deleted file mode 100644
index 8c42881..0000000
--- a/src/cmd/compile/internal/gc/bench_test.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import "testing"
-
-var globl int64
-var globl32 int32
-
-func BenchmarkLoadAdd(b *testing.B) {
-	x := make([]int64, 1024)
-	y := make([]int64, 1024)
-	for i := 0; i < b.N; i++ {
-		var s int64
-		for i := range x {
-			s ^= x[i] + y[i]
-		}
-		globl = s
-	}
-}
-
-// Added for ppc64 extswsli on power9
-func BenchmarkExtShift(b *testing.B) {
-	x := make([]int32, 1024)
-	for i := 0; i < b.N; i++ {
-		var s int64
-		for i := range x {
-			s ^= int64(x[i]+32) * 8
-		}
-		globl = s
-	}
-}
-
-func BenchmarkModify(b *testing.B) {
-	a := make([]int64, 1024)
-	v := globl
-	for i := 0; i < b.N; i++ {
-		for j := range a {
-			a[j] += v
-		}
-	}
-}
-
-func BenchmarkMullImm(b *testing.B) {
-	x := make([]int32, 1024)
-	for i := 0; i < b.N; i++ {
-		var s int32
-		for i := range x {
-			s += x[i] * 100
-		}
-		globl32 = s
-	}
-}
-
-func BenchmarkConstModify(b *testing.B) {
-	a := make([]int64, 1024)
-	for i := 0; i < b.N; i++ {
-		for j := range a {
-			a[j] += 3
-		}
-	}
-}
diff --git a/src/cmd/compile/internal/gc/bexport.go b/src/cmd/compile/internal/gc/bexport.go
deleted file mode 100644
index 10f21f8..0000000
--- a/src/cmd/compile/internal/gc/bexport.go
+++ /dev/null
@@ -1,177 +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 gc
-
-import (
-	"cmd/compile/internal/types"
-)
-
-type exporter struct {
-	marked map[*types.Type]bool // types already seen by markType
-}
-
-// 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 types.IsExported(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 or
-	// iterating over 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 function parameter types, because
-	// the user already needs some way to construct values of
-	// those types.
-	switch t.Etype {
-	case TPTR, TARRAY, TSLICE:
-		p.markType(t.Elem())
-
-	case TCHAN:
-		if t.ChanDir().CanRecv() {
-			p.markType(t.Elem())
-		}
-
-	case TMAP:
-		p.markType(t.Key())
-		p.markType(t.Elem())
-
-	case TSTRUCT:
-		for _, f := range t.FieldSlice() {
-			if types.IsExported(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 types.IsExported(f.Sym.Name) {
-				p.markType(f.Type)
-			}
-		}
-	}
-}
-
-// ----------------------------------------------------------------------------
-// Export format
-
-// Tags. Must be < 0.
-const (
-	// Objects
-	packageTag = -(iota + 1)
-	constTag
-	typeTag
-	varTag
-	funcTag
-	endTag
-
-	// Types
-	namedTag
-	arrayTag
-	sliceTag
-	dddTag
-	structTag
-	pointerTag
-	signatureTag
-	interfaceTag
-	mapTag
-	chanTag
-
-	// Values
-	falseTag
-	trueTag
-	int64Tag
-	floatTag
-	fractionTag // not used by gc
-	complexTag
-	stringTag
-	nilTag
-	unknownTag // not used by gc (only appears in packages with errors)
-
-	// Type aliases
-	aliasTag
-)
-
-var predecl []*types.Type // initialized lazily
-
-func predeclared() []*types.Type {
-	if predecl == nil {
-		// initialize lazily to be sure that all
-		// elements have been initialized before
-		predecl = []*types.Type{
-			// basic types
-			types.Types[TBOOL],
-			types.Types[TINT],
-			types.Types[TINT8],
-			types.Types[TINT16],
-			types.Types[TINT32],
-			types.Types[TINT64],
-			types.Types[TUINT],
-			types.Types[TUINT8],
-			types.Types[TUINT16],
-			types.Types[TUINT32],
-			types.Types[TUINT64],
-			types.Types[TUINTPTR],
-			types.Types[TFLOAT32],
-			types.Types[TFLOAT64],
-			types.Types[TCOMPLEX64],
-			types.Types[TCOMPLEX128],
-			types.Types[TSTRING],
-
-			// basic type aliases
-			types.Bytetype,
-			types.Runetype,
-
-			// error
-			types.Errortype,
-
-			// untyped types
-			types.UntypedBool,
-			types.UntypedInt,
-			types.UntypedRune,
-			types.UntypedFloat,
-			types.UntypedComplex,
-			types.UntypedString,
-			types.Types[TNIL],
-
-			// package unsafe
-			types.Types[TUNSAFEPTR],
-
-			// invalid type (package contains errors)
-			types.Types[Txxx],
-
-			// any type, for builtin export data
-			types.Types[TANY],
-		}
-	}
-	return predecl
-}
diff --git a/src/cmd/compile/internal/gc/bimport.go b/src/cmd/compile/internal/gc/bimport.go
deleted file mode 100644
index 911ac4c..0000000
--- a/src/cmd/compile/internal/gc/bimport.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.
-
-package gc
-
-import (
-	"cmd/internal/src"
-)
-
-// numImport tracks how often a package with a given name is imported.
-// It is used to provide a better error message (by using the package
-// path to disambiguate) if a package that appears multiple times with
-// the same name appears in an error message.
-var numImport = make(map[string]int)
-
-func npos(pos src.XPos, n *Node) *Node {
-	n.Pos = pos
-	return n
-}
-
-func builtinCall(op Op) *Node {
-	return nod(OCALL, mkname(builtinpkg.Lookup(goopnames[op])), nil)
-}
diff --git a/src/cmd/compile/internal/gc/bitset.go b/src/cmd/compile/internal/gc/bitset.go
deleted file mode 100644
index ed5eea0..0000000
--- a/src/cmd/compile/internal/gc/bitset.go
+++ /dev/null
@@ -1,59 +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 gc
-
-type bitset8 uint8
-
-func (f *bitset8) set(mask uint8, b bool) {
-	if b {
-		*(*uint8)(f) |= mask
-	} else {
-		*(*uint8)(f) &^= mask
-	}
-}
-
-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) {
-	if b {
-		*(*uint32)(f) |= mask
-	} else {
-		*(*uint32)(f) &^= mask
-	}
-}
-
-func (f bitset32) get2(shift uint8) uint8 {
-	return uint8(f>>shift) & 3
-}
-
-// set2 sets two bits in f using the bottom two bits of b.
-func (f *bitset32) set2(shift uint8, b uint8) {
-	// Clear old bits.
-	*(*uint32)(f) &^= 3 << shift
-	// Set new bits.
-	*(*uint32)(f) |= uint32(b&3) << shift
-}
-
-func (f bitset32) get3(shift uint8) uint8 {
-	return uint8(f>>shift) & 7
-}
-
-// set3 sets three bits in f using the bottom three bits of b.
-func (f *bitset32) set3(shift uint8, b uint8) {
-	// Clear old bits.
-	*(*uint32)(f) &^= 7 << shift
-	// Set new bits.
-	*(*uint32)(f) |= uint32(b&7) << shift
-}
diff --git a/src/cmd/compile/internal/gc/bootstrap.go b/src/cmd/compile/internal/gc/bootstrap.go
index 967f75a..37b0d59 100644
--- a/src/cmd/compile/internal/gc/bootstrap.go
+++ b/src/cmd/compile/internal/gc/bootstrap.go
@@ -2,12 +2,16 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !go1.8
 // +build !go1.8
 
 package gc
 
-import "runtime"
+import (
+	"cmd/compile/internal/base"
+	"runtime"
+)
 
 func startMutexProfiling() {
-	Fatalf("mutex profiling unavailable in version %v", runtime.Version())
+	base.Fatalf("mutex profiling unavailable in version %v", runtime.Version())
 }
diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go
deleted file mode 100644
index e04f23e..0000000
--- a/src/cmd/compile/internal/gc/builtin.go
+++ /dev/null
@@ -1,340 +0,0 @@
-// Code generated by mkbuiltin.go. DO NOT EDIT.
-
-package gc
-
-import "cmd/compile/internal/types"
-
-var runtimeDecls = [...]struct {
-	name string
-	tag  int
-	typ  int
-}{
-	{"newobject", funcTag, 4},
-	{"mallocgc", funcTag, 8},
-	{"panicdivide", funcTag, 9},
-	{"panicshift", funcTag, 9},
-	{"panicmakeslicelen", funcTag, 9},
-	{"panicmakeslicecap", funcTag, 9},
-	{"throwinit", funcTag, 9},
-	{"panicwrap", funcTag, 9},
-	{"gopanic", funcTag, 11},
-	{"gorecover", funcTag, 14},
-	{"goschedguarded", funcTag, 9},
-	{"goPanicIndex", funcTag, 16},
-	{"goPanicIndexU", funcTag, 18},
-	{"goPanicSliceAlen", funcTag, 16},
-	{"goPanicSliceAlenU", funcTag, 18},
-	{"goPanicSliceAcap", funcTag, 16},
-	{"goPanicSliceAcapU", funcTag, 18},
-	{"goPanicSliceB", funcTag, 16},
-	{"goPanicSliceBU", funcTag, 18},
-	{"goPanicSlice3Alen", funcTag, 16},
-	{"goPanicSlice3AlenU", funcTag, 18},
-	{"goPanicSlice3Acap", funcTag, 16},
-	{"goPanicSlice3AcapU", funcTag, 18},
-	{"goPanicSlice3B", funcTag, 16},
-	{"goPanicSlice3BU", funcTag, 18},
-	{"goPanicSlice3C", funcTag, 16},
-	{"goPanicSlice3CU", funcTag, 18},
-	{"printbool", funcTag, 19},
-	{"printfloat", funcTag, 21},
-	{"printint", funcTag, 23},
-	{"printhex", funcTag, 25},
-	{"printuint", funcTag, 25},
-	{"printcomplex", funcTag, 27},
-	{"printstring", funcTag, 29},
-	{"printpointer", funcTag, 30},
-	{"printuintptr", funcTag, 31},
-	{"printiface", funcTag, 30},
-	{"printeface", funcTag, 30},
-	{"printslice", funcTag, 30},
-	{"printnl", funcTag, 9},
-	{"printsp", funcTag, 9},
-	{"printlock", funcTag, 9},
-	{"printunlock", funcTag, 9},
-	{"concatstring2", funcTag, 34},
-	{"concatstring3", funcTag, 35},
-	{"concatstring4", funcTag, 36},
-	{"concatstring5", funcTag, 37},
-	{"concatstrings", funcTag, 39},
-	{"cmpstring", funcTag, 40},
-	{"intstring", funcTag, 43},
-	{"slicebytetostring", funcTag, 44},
-	{"slicebytetostringtmp", funcTag, 45},
-	{"slicerunetostring", funcTag, 48},
-	{"stringtoslicebyte", funcTag, 50},
-	{"stringtoslicerune", funcTag, 53},
-	{"slicecopy", funcTag, 54},
-	{"decoderune", funcTag, 55},
-	{"countrunes", funcTag, 56},
-	{"convI2I", funcTag, 57},
-	{"convT16", funcTag, 58},
-	{"convT32", funcTag, 58},
-	{"convT64", funcTag, 58},
-	{"convTstring", funcTag, 58},
-	{"convTslice", funcTag, 58},
-	{"convT2E", funcTag, 59},
-	{"convT2Enoptr", funcTag, 59},
-	{"convT2I", funcTag, 59},
-	{"convT2Inoptr", funcTag, 59},
-	{"assertE2I", funcTag, 57},
-	{"assertE2I2", funcTag, 60},
-	{"assertI2I", funcTag, 57},
-	{"assertI2I2", funcTag, 60},
-	{"panicdottypeE", funcTag, 61},
-	{"panicdottypeI", funcTag, 61},
-	{"panicnildottype", funcTag, 62},
-	{"ifaceeq", funcTag, 64},
-	{"efaceeq", funcTag, 64},
-	{"fastrand", funcTag, 66},
-	{"makemap64", funcTag, 68},
-	{"makemap", funcTag, 69},
-	{"makemap_small", funcTag, 70},
-	{"mapaccess1", funcTag, 71},
-	{"mapaccess1_fast32", funcTag, 72},
-	{"mapaccess1_fast64", funcTag, 72},
-	{"mapaccess1_faststr", funcTag, 72},
-	{"mapaccess1_fat", funcTag, 73},
-	{"mapaccess2", funcTag, 74},
-	{"mapaccess2_fast32", funcTag, 75},
-	{"mapaccess2_fast64", funcTag, 75},
-	{"mapaccess2_faststr", funcTag, 75},
-	{"mapaccess2_fat", funcTag, 76},
-	{"mapassign", funcTag, 71},
-	{"mapassign_fast32", funcTag, 72},
-	{"mapassign_fast32ptr", funcTag, 72},
-	{"mapassign_fast64", funcTag, 72},
-	{"mapassign_fast64ptr", funcTag, 72},
-	{"mapassign_faststr", funcTag, 72},
-	{"mapiterinit", funcTag, 77},
-	{"mapdelete", funcTag, 77},
-	{"mapdelete_fast32", funcTag, 78},
-	{"mapdelete_fast64", funcTag, 78},
-	{"mapdelete_faststr", funcTag, 78},
-	{"mapiternext", funcTag, 79},
-	{"mapclear", funcTag, 80},
-	{"makechan64", funcTag, 82},
-	{"makechan", funcTag, 83},
-	{"chanrecv1", funcTag, 85},
-	{"chanrecv2", funcTag, 86},
-	{"chansend1", funcTag, 88},
-	{"closechan", funcTag, 30},
-	{"writeBarrier", varTag, 90},
-	{"typedmemmove", funcTag, 91},
-	{"typedmemclr", funcTag, 92},
-	{"typedslicecopy", funcTag, 93},
-	{"selectnbsend", funcTag, 94},
-	{"selectnbrecv", funcTag, 95},
-	{"selectnbrecv2", funcTag, 97},
-	{"selectsetpc", funcTag, 98},
-	{"selectgo", funcTag, 99},
-	{"block", funcTag, 9},
-	{"makeslice", funcTag, 100},
-	{"makeslice64", funcTag, 101},
-	{"makeslicecopy", funcTag, 102},
-	{"growslice", funcTag, 104},
-	{"memmove", funcTag, 105},
-	{"memclrNoHeapPointers", funcTag, 106},
-	{"memclrHasPointers", funcTag, 106},
-	{"memequal", funcTag, 107},
-	{"memequal0", funcTag, 108},
-	{"memequal8", funcTag, 108},
-	{"memequal16", funcTag, 108},
-	{"memequal32", funcTag, 108},
-	{"memequal64", funcTag, 108},
-	{"memequal128", funcTag, 108},
-	{"f32equal", funcTag, 109},
-	{"f64equal", funcTag, 109},
-	{"c64equal", funcTag, 109},
-	{"c128equal", funcTag, 109},
-	{"strequal", funcTag, 109},
-	{"interequal", funcTag, 109},
-	{"nilinterequal", funcTag, 109},
-	{"memhash", funcTag, 110},
-	{"memhash0", funcTag, 111},
-	{"memhash8", funcTag, 111},
-	{"memhash16", funcTag, 111},
-	{"memhash32", funcTag, 111},
-	{"memhash64", funcTag, 111},
-	{"memhash128", funcTag, 111},
-	{"f32hash", funcTag, 111},
-	{"f64hash", funcTag, 111},
-	{"c64hash", funcTag, 111},
-	{"c128hash", funcTag, 111},
-	{"strhash", funcTag, 111},
-	{"interhash", funcTag, 111},
-	{"nilinterhash", funcTag, 111},
-	{"int64div", funcTag, 112},
-	{"uint64div", funcTag, 113},
-	{"int64mod", funcTag, 112},
-	{"uint64mod", funcTag, 113},
-	{"float64toint64", funcTag, 114},
-	{"float64touint64", funcTag, 115},
-	{"float64touint32", funcTag, 116},
-	{"int64tofloat64", funcTag, 117},
-	{"uint64tofloat64", funcTag, 118},
-	{"uint32tofloat64", funcTag, 119},
-	{"complex128div", funcTag, 120},
-	{"racefuncenter", funcTag, 31},
-	{"racefuncenterfp", funcTag, 9},
-	{"racefuncexit", funcTag, 9},
-	{"raceread", funcTag, 31},
-	{"racewrite", funcTag, 31},
-	{"racereadrange", funcTag, 121},
-	{"racewriterange", funcTag, 121},
-	{"msanread", funcTag, 121},
-	{"msanwrite", funcTag, 121},
-	{"msanmove", funcTag, 122},
-	{"checkptrAlignment", funcTag, 123},
-	{"checkptrArithmetic", funcTag, 125},
-	{"libfuzzerTraceCmp1", funcTag, 127},
-	{"libfuzzerTraceCmp2", funcTag, 129},
-	{"libfuzzerTraceCmp4", funcTag, 130},
-	{"libfuzzerTraceCmp8", funcTag, 131},
-	{"libfuzzerTraceConstCmp1", funcTag, 127},
-	{"libfuzzerTraceConstCmp2", funcTag, 129},
-	{"libfuzzerTraceConstCmp4", funcTag, 130},
-	{"libfuzzerTraceConstCmp8", funcTag, 131},
-	{"x86HasPOPCNT", varTag, 6},
-	{"x86HasSSE41", varTag, 6},
-	{"x86HasFMA", varTag, 6},
-	{"armHasVFPv4", varTag, 6},
-	{"arm64HasATOMICS", varTag, 6},
-}
-
-func runtimeTypes() []*types.Type {
-	var typs [132]*types.Type
-	typs[0] = types.Bytetype
-	typs[1] = types.NewPtr(typs[0])
-	typs[2] = types.Types[TANY]
-	typs[3] = types.NewPtr(typs[2])
-	typs[4] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[3])})
-	typs[5] = types.Types[TUINTPTR]
-	typs[6] = types.Types[TBOOL]
-	typs[7] = types.Types[TUNSAFEPTR]
-	typs[8] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[1]), anonfield(typs[6])}, []*Node{anonfield(typs[7])})
-	typs[9] = functype(nil, nil, nil)
-	typs[10] = types.Types[TINTER]
-	typs[11] = functype(nil, []*Node{anonfield(typs[10])}, nil)
-	typs[12] = types.Types[TINT32]
-	typs[13] = types.NewPtr(typs[12])
-	typs[14] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[10])})
-	typs[15] = types.Types[TINT]
-	typs[16] = functype(nil, []*Node{anonfield(typs[15]), anonfield(typs[15])}, nil)
-	typs[17] = types.Types[TUINT]
-	typs[18] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[15])}, nil)
-	typs[19] = functype(nil, []*Node{anonfield(typs[6])}, nil)
-	typs[20] = types.Types[TFLOAT64]
-	typs[21] = functype(nil, []*Node{anonfield(typs[20])}, nil)
-	typs[22] = types.Types[TINT64]
-	typs[23] = functype(nil, []*Node{anonfield(typs[22])}, nil)
-	typs[24] = types.Types[TUINT64]
-	typs[25] = functype(nil, []*Node{anonfield(typs[24])}, nil)
-	typs[26] = types.Types[TCOMPLEX128]
-	typs[27] = functype(nil, []*Node{anonfield(typs[26])}, nil)
-	typs[28] = types.Types[TSTRING]
-	typs[29] = functype(nil, []*Node{anonfield(typs[28])}, nil)
-	typs[30] = functype(nil, []*Node{anonfield(typs[2])}, nil)
-	typs[31] = functype(nil, []*Node{anonfield(typs[5])}, nil)
-	typs[32] = types.NewArray(typs[0], 32)
-	typs[33] = types.NewPtr(typs[32])
-	typs[34] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
-	typs[35] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
-	typs[36] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
-	typs[37] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
-	typs[38] = types.NewSlice(typs[28])
-	typs[39] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[38])}, []*Node{anonfield(typs[28])})
-	typs[40] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[15])})
-	typs[41] = types.NewArray(typs[0], 4)
-	typs[42] = types.NewPtr(typs[41])
-	typs[43] = functype(nil, []*Node{anonfield(typs[42]), anonfield(typs[22])}, []*Node{anonfield(typs[28])})
-	typs[44] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])})
-	typs[45] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])})
-	typs[46] = types.Runetype
-	typs[47] = types.NewSlice(typs[46])
-	typs[48] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[47])}, []*Node{anonfield(typs[28])})
-	typs[49] = types.NewSlice(typs[0])
-	typs[50] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28])}, []*Node{anonfield(typs[49])})
-	typs[51] = types.NewArray(typs[46], 32)
-	typs[52] = types.NewPtr(typs[51])
-	typs[53] = functype(nil, []*Node{anonfield(typs[52]), anonfield(typs[28])}, []*Node{anonfield(typs[47])})
-	typs[54] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*Node{anonfield(typs[15])})
-	typs[55] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[15])}, []*Node{anonfield(typs[46]), anonfield(typs[15])})
-	typs[56] = functype(nil, []*Node{anonfield(typs[28])}, []*Node{anonfield(typs[15])})
-	typs[57] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
-	typs[58] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[7])})
-	typs[59] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
-	typs[60] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[6])})
-	typs[61] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
-	typs[62] = functype(nil, []*Node{anonfield(typs[1])}, nil)
-	typs[63] = types.NewPtr(typs[5])
-	typs[64] = functype(nil, []*Node{anonfield(typs[63]), anonfield(typs[7]), anonfield(typs[7])}, []*Node{anonfield(typs[6])})
-	typs[65] = types.Types[TUINT32]
-	typs[66] = functype(nil, nil, []*Node{anonfield(typs[65])})
-	typs[67] = types.NewMap(typs[2], typs[2])
-	typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[3])}, []*Node{anonfield(typs[67])})
-	typs[69] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*Node{anonfield(typs[67])})
-	typs[70] = functype(nil, nil, []*Node{anonfield(typs[67])})
-	typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
-	typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
-	typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
-	typs[74] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[6])})
-	typs[75] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[6])})
-	typs[76] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[6])})
-	typs[77] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, nil)
-	typs[78] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, nil)
-	typs[79] = functype(nil, []*Node{anonfield(typs[3])}, nil)
-	typs[80] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67])}, nil)
-	typs[81] = types.NewChan(typs[2], types.Cboth)
-	typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22])}, []*Node{anonfield(typs[81])})
-	typs[83] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[81])})
-	typs[84] = types.NewChan(typs[2], types.Crecv)
-	typs[85] = functype(nil, []*Node{anonfield(typs[84]), anonfield(typs[3])}, nil)
-	typs[86] = functype(nil, []*Node{anonfield(typs[84]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
-	typs[87] = types.NewChan(typs[2], types.Csend)
-	typs[88] = functype(nil, []*Node{anonfield(typs[87]), anonfield(typs[3])}, nil)
-	typs[89] = types.NewArray(typs[0], 3)
-	typs[90] = tostruct([]*Node{namedfield("enabled", typs[6]), namedfield("pad", typs[89]), namedfield("needed", typs[6]), namedfield("cgo", typs[6]), namedfield("alignme", typs[24])})
-	typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
-	typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
-	typs[93] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15])}, []*Node{anonfield(typs[15])})
-	typs[94] = functype(nil, []*Node{anonfield(typs[87]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
-	typs[95] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[84])}, []*Node{anonfield(typs[6])})
-	typs[96] = types.NewPtr(typs[6])
-	typs[97] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[96]), anonfield(typs[84])}, []*Node{anonfield(typs[6])})
-	typs[98] = functype(nil, []*Node{anonfield(typs[63])}, nil)
-	typs[99] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[6])}, []*Node{anonfield(typs[15]), anonfield(typs[6])})
-	typs[100] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[7])})
-	typs[101] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[7])})
-	typs[102] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []*Node{anonfield(typs[7])})
-	typs[103] = types.NewSlice(typs[2])
-	typs[104] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[103]), anonfield(typs[15])}, []*Node{anonfield(typs[103])})
-	typs[105] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
-	typs[106] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, nil)
-	typs[107] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []*Node{anonfield(typs[6])})
-	typs[108] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
-	typs[109] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[7])}, []*Node{anonfield(typs[6])})
-	typs[110] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []*Node{anonfield(typs[5])})
-	typs[111] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, []*Node{anonfield(typs[5])})
-	typs[112] = functype(nil, []*Node{anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[22])})
-	typs[113] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, []*Node{anonfield(typs[24])})
-	typs[114] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[22])})
-	typs[115] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[24])})
-	typs[116] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[65])})
-	typs[117] = functype(nil, []*Node{anonfield(typs[22])}, []*Node{anonfield(typs[20])})
-	typs[118] = functype(nil, []*Node{anonfield(typs[24])}, []*Node{anonfield(typs[20])})
-	typs[119] = functype(nil, []*Node{anonfield(typs[65])}, []*Node{anonfield(typs[20])})
-	typs[120] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[26])}, []*Node{anonfield(typs[26])})
-	typs[121] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5])}, nil)
-	typs[122] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5]), anonfield(typs[5])}, nil)
-	typs[123] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
-	typs[124] = types.NewSlice(typs[7])
-	typs[125] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[124])}, nil)
-	typs[126] = types.Types[TUINT8]
-	typs[127] = functype(nil, []*Node{anonfield(typs[126]), anonfield(typs[126])}, nil)
-	typs[128] = types.Types[TUINT16]
-	typs[129] = functype(nil, []*Node{anonfield(typs[128]), anonfield(typs[128])}, nil)
-	typs[130] = functype(nil, []*Node{anonfield(typs[65]), anonfield(typs[65])}, nil)
-	typs[131] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, nil)
-	return typs[:]
-}
diff --git a/src/cmd/compile/internal/gc/builtin/runtime.go b/src/cmd/compile/internal/gc/builtin/runtime.go
deleted file mode 100644
index acb69c7..0000000
--- a/src/cmd/compile/internal/gc/builtin/runtime.go
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// NOTE: If you change this file you must run "go generate"
-// to update builtin.go. This is not done automatically
-// to avoid depending on having a working compiler binary.
-
-// +build ignore
-
-package runtime
-
-// emitted by compiler, not referred to by go programs
-
-import "unsafe"
-
-func newobject(typ *byte) *any
-func mallocgc(size uintptr, typ *byte, needszero bool) unsafe.Pointer
-func panicdivide()
-func panicshift()
-func panicmakeslicelen()
-func panicmakeslicecap()
-func throwinit()
-func panicwrap()
-
-func gopanic(interface{})
-func gorecover(*int32) interface{}
-func goschedguarded()
-
-// Note: these declarations are just for wasm port.
-// Other ports call assembly stubs instead.
-func goPanicIndex(x int, y int)
-func goPanicIndexU(x uint, y int)
-func goPanicSliceAlen(x int, y int)
-func goPanicSliceAlenU(x uint, y int)
-func goPanicSliceAcap(x int, y int)
-func goPanicSliceAcapU(x uint, y int)
-func goPanicSliceB(x int, y int)
-func goPanicSliceBU(x uint, y int)
-func goPanicSlice3Alen(x int, y int)
-func goPanicSlice3AlenU(x uint, y int)
-func goPanicSlice3Acap(x int, y int)
-func goPanicSlice3AcapU(x uint, y int)
-func goPanicSlice3B(x int, y int)
-func goPanicSlice3BU(x uint, y int)
-func goPanicSlice3C(x int, y int)
-func goPanicSlice3CU(x uint, y int)
-
-func printbool(bool)
-func printfloat(float64)
-func printint(int64)
-func printhex(uint64)
-func printuint(uint64)
-func printcomplex(complex128)
-func printstring(string)
-func printpointer(any)
-func printuintptr(uintptr)
-func printiface(any)
-func printeface(any)
-func printslice(any)
-func printnl()
-func printsp()
-func printlock()
-func printunlock()
-
-func concatstring2(*[32]byte, string, string) string
-func concatstring3(*[32]byte, string, string, string) string
-func concatstring4(*[32]byte, string, string, string, string) string
-func concatstring5(*[32]byte, string, string, string, string, string) string
-func concatstrings(*[32]byte, []string) string
-
-func cmpstring(string, string) int
-func intstring(*[4]byte, int64) string
-func slicebytetostring(buf *[32]byte, ptr *byte, n int) string
-func slicebytetostringtmp(ptr *byte, n int) string
-func slicerunetostring(*[32]byte, []rune) string
-func stringtoslicebyte(*[32]byte, string) []byte
-func stringtoslicerune(*[32]rune, string) []rune
-func slicecopy(toPtr *any, toLen int, fromPtr *any, fromLen int, wid uintptr) int
-
-func decoderune(string, int) (retv rune, retk int)
-func countrunes(string) int
-
-// Non-empty-interface to non-empty-interface conversion.
-func convI2I(typ *byte, elem any) (ret any)
-
-// Specialized type-to-interface conversion.
-// These return only a data pointer.
-func convT16(val any) unsafe.Pointer     // val must be uint16-like (same size and alignment as a uint16)
-func convT32(val any) unsafe.Pointer     // val must be uint32-like (same size and alignment as a uint32)
-func convT64(val any) unsafe.Pointer     // val must be uint64-like (same size and alignment as a uint64 and contains no pointers)
-func convTstring(val any) unsafe.Pointer // val must be a string
-func convTslice(val any) unsafe.Pointer  // val must be a slice
-
-// Type to empty-interface conversion.
-func convT2E(typ *byte, elem *any) (ret any)
-func convT2Enoptr(typ *byte, elem *any) (ret any)
-
-// Type to non-empty-interface conversion.
-func convT2I(tab *byte, elem *any) (ret any)
-func convT2Inoptr(tab *byte, elem *any) (ret any)
-
-// 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)
-func assertI2I2(typ *byte, iface any) (ret any, b bool)
-func panicdottypeE(have, want, iface *byte)
-func panicdottypeI(have, want, iface *byte)
-func panicnildottype(want *byte)
-
-// interface equality. Type/itab pointers are already known to be equal, so
-// we only need to pass one.
-func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
-func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
-
-func fastrand() uint32
-
-// *byte is really *runtime.Type
-func makemap64(mapType *byte, hint int64, mapbuf *any) (hmap map[any]any)
-func makemap(mapType *byte, hint int, mapbuf *any) (hmap map[any]any)
-func makemap_small() (hmap map[any]any)
-func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
-func mapaccess1_fast32(mapType *byte, hmap map[any]any, key any) (val *any)
-func mapaccess1_fast64(mapType *byte, hmap map[any]any, key any) (val *any)
-func mapaccess1_faststr(mapType *byte, hmap map[any]any, key any) (val *any)
-func mapaccess1_fat(mapType *byte, hmap map[any]any, key *any, zero *byte) (val *any)
-func mapaccess2(mapType *byte, hmap map[any]any, key *any) (val *any, pres bool)
-func mapaccess2_fast32(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
-func mapaccess2_fast64(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
-func mapaccess2_faststr(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
-func mapaccess2_fat(mapType *byte, hmap map[any]any, key *any, zero *byte) (val *any, pres bool)
-func mapassign(mapType *byte, hmap map[any]any, key *any) (val *any)
-func mapassign_fast32(mapType *byte, hmap map[any]any, key 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)
-func mapdelete_fast32(mapType *byte, hmap map[any]any, key any)
-func mapdelete_fast64(mapType *byte, hmap map[any]any, key any)
-func mapdelete_faststr(mapType *byte, hmap map[any]any, key any)
-func mapiternext(hiter *any)
-func mapclear(mapType *byte, hmap map[any]any)
-
-// *byte is really *runtime.Type
-func makechan64(chanType *byte, size int64) (hchan chan any)
-func makechan(chanType *byte, size int) (hchan chan any)
-func chanrecv1(hchan <-chan any, elem *any)
-func chanrecv2(hchan <-chan any, elem *any) bool
-func chansend1(hchan chan<- any, elem *any)
-func closechan(hchan any)
-
-var writeBarrier struct {
-	enabled bool
-	pad     [3]byte
-	needed  bool
-	cgo     bool
-	alignme uint64
-}
-
-// *byte is really *runtime.Type
-func typedmemmove(typ *byte, dst *any, src *any)
-func typedmemclr(typ *byte, dst *any)
-func typedslicecopy(typ *byte, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int
-
-func selectnbsend(hchan chan<- any, elem *any) bool
-func selectnbrecv(elem *any, hchan <-chan any) bool
-func selectnbrecv2(elem *any, received *bool, hchan <-chan any) bool
-
-func selectsetpc(pc *uintptr)
-func selectgo(cas0 *byte, order0 *byte, pc0 *uintptr, nsends int, nrecvs int, block bool) (int, bool)
-func block()
-
-func makeslice(typ *byte, len int, cap int) unsafe.Pointer
-func makeslice64(typ *byte, len int64, cap int64) unsafe.Pointer
-func makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer
-func growslice(typ *byte, old []any, cap int) (ary []any)
-func memmove(to *any, frm *any, length uintptr)
-func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
-func memclrHasPointers(ptr unsafe.Pointer, n uintptr)
-
-func memequal(x, y *any, size uintptr) bool
-func memequal0(x, y *any) bool
-func memequal8(x, y *any) bool
-func memequal16(x, y *any) bool
-func memequal32(x, y *any) bool
-func memequal64(x, y *any) bool
-func memequal128(x, y *any) bool
-func f32equal(p, q unsafe.Pointer) bool
-func f64equal(p, q unsafe.Pointer) bool
-func c64equal(p, q unsafe.Pointer) bool
-func c128equal(p, q unsafe.Pointer) bool
-func strequal(p, q unsafe.Pointer) bool
-func interequal(p, q unsafe.Pointer) bool
-func nilinterequal(p, q unsafe.Pointer) bool
-
-func memhash(p unsafe.Pointer, h uintptr, size uintptr) uintptr
-func memhash0(p unsafe.Pointer, h uintptr) uintptr
-func memhash8(p unsafe.Pointer, h uintptr) uintptr
-func memhash16(p unsafe.Pointer, h uintptr) uintptr
-func memhash32(p unsafe.Pointer, h uintptr) uintptr
-func memhash64(p unsafe.Pointer, h uintptr) uintptr
-func memhash128(p unsafe.Pointer, h uintptr) uintptr
-func f32hash(p unsafe.Pointer, h uintptr) uintptr
-func f64hash(p unsafe.Pointer, h uintptr) uintptr
-func c64hash(p unsafe.Pointer, h uintptr) uintptr
-func c128hash(p unsafe.Pointer, h uintptr) uintptr
-func strhash(a unsafe.Pointer, h uintptr) uintptr
-func interhash(p unsafe.Pointer, h uintptr) uintptr
-func nilinterhash(p unsafe.Pointer, h uintptr) uintptr
-
-// only used on 32-bit
-func int64div(int64, int64) int64
-func uint64div(uint64, uint64) uint64
-func int64mod(int64, int64) int64
-func uint64mod(uint64, uint64) uint64
-func float64toint64(float64) int64
-func float64touint64(float64) uint64
-func float64touint32(float64) uint32
-func int64tofloat64(int64) float64
-func uint64tofloat64(uint64) float64
-func uint32tofloat64(uint32) float64
-
-func complex128div(num complex128, den complex128) (quo complex128)
-
-// race detection
-func racefuncenter(uintptr)
-func racefuncenterfp()
-func racefuncexit()
-func raceread(uintptr)
-func racewrite(uintptr)
-func racereadrange(addr, size uintptr)
-func racewriterange(addr, size uintptr)
-
-// memory sanitizer
-func msanread(addr, size uintptr)
-func msanwrite(addr, size uintptr)
-func msanmove(dst, src, size uintptr)
-
-func checkptrAlignment(unsafe.Pointer, *byte, uintptr)
-func checkptrArithmetic(unsafe.Pointer, []unsafe.Pointer)
-
-func libfuzzerTraceCmp1(uint8, uint8)
-func libfuzzerTraceCmp2(uint16, uint16)
-func libfuzzerTraceCmp4(uint32, uint32)
-func libfuzzerTraceCmp8(uint64, uint64)
-func libfuzzerTraceConstCmp1(uint8, uint8)
-func libfuzzerTraceConstCmp2(uint16, uint16)
-func libfuzzerTraceConstCmp4(uint32, uint32)
-func libfuzzerTraceConstCmp8(uint64, uint64)
-
-// architecture variants
-var x86HasPOPCNT bool
-var x86HasSSE41 bool
-var x86HasFMA bool
-var armHasVFPv4 bool
-var arm64HasATOMICS bool
diff --git a/src/cmd/compile/internal/gc/builtin_test.go b/src/cmd/compile/internal/gc/builtin_test.go
deleted file mode 100644
index 57f24b2..0000000
--- a/src/cmd/compile/internal/gc/builtin_test.go
+++ /dev/null
@@ -1,32 +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.
-
-package gc_test
-
-import (
-	"bytes"
-	"internal/testenv"
-	"io/ioutil"
-	"os/exec"
-	"testing"
-)
-
-func TestBuiltin(t *testing.T) {
-	testenv.MustHaveGoRun(t)
-	t.Parallel()
-
-	old, err := ioutil.ReadFile("builtin.go")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	new, err := exec.Command(testenv.GoToolPath(t), "run", "mkbuiltin.go", "-stdout").Output()
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if !bytes.Equal(old, new) {
-		t.Fatal("builtin.go out of date; run mkbuiltin.go")
-	}
-}
diff --git a/src/cmd/compile/internal/gc/bv.go b/src/cmd/compile/internal/gc/bv.go
deleted file mode 100644
index e32ab97..0000000
--- a/src/cmd/compile/internal/gc/bv.go
+++ /dev/null
@@ -1,278 +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 gc
-
-import (
-	"math/bits"
-)
-
-const (
-	wordBits  = 32
-	wordMask  = wordBits - 1
-	wordShift = 5
-)
-
-// A bvec is a bit vector.
-type bvec struct {
-	n int32    // number of bits in vector
-	b []uint32 // words holding bits
-}
-
-func bvalloc(n int32) bvec {
-	nword := (n + wordBits - 1) / wordBits
-	return bvec{n, make([]uint32, nword)}
-}
-
-type bulkBvec struct {
-	words []uint32
-	nbit  int32
-	nword int32
-}
-
-func bvbulkalloc(nbit int32, count int32) bulkBvec {
-	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)
-	}
-	return bulkBvec{
-		words: make([]uint32, size),
-		nbit:  nbit,
-		nword: nword,
-	}
-}
-
-func (b *bulkBvec) next() bvec {
-	out := bvec{b.nbit, b.words[:b.nword]}
-	b.words = b.words[b.nword:]
-	return out
-}
-
-func (bv1 bvec) Eq(bv2 bvec) bool {
-	if bv1.n != bv2.n {
-		Fatalf("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n)
-	}
-	for i, x := range bv1.b {
-		if x != bv2.b[i] {
-			return false
-		}
-	}
-	return true
-}
-
-func (dst bvec) Copy(src bvec) {
-	copy(dst.b, src.b)
-}
-
-func (bv bvec) Get(i int32) bool {
-	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
-}
-
-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
-}
-
-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
-}
-
-// bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
-// If there is no such index, bvnext returns -1.
-func (bv bvec) Next(i int32) int32 {
-	if i >= bv.n {
-		return -1
-	}
-
-	// 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 i >= bv.n {
-		return -1
-	}
-
-	// Find 1 bit.
-	w := bv.b[i>>wordShift] >> uint(i&wordMask)
-	i += int32(bits.TrailingZeros32(w))
-
-	return i
-}
-
-func (bv bvec) IsEmpty() bool {
-	for _, x := range bv.b {
-		if x != 0 {
-			return false
-		}
-	}
-	return true
-}
-
-func (bv bvec) Not() {
-	for i, x := range bv.b {
-		bv.b[i] = ^x
-	}
-}
-
-// union
-func (dst bvec) Or(src1, src2 bvec) {
-	if len(src1.b) == 0 {
-		return
-	}
-	_, _ = dst.b[len(src1.b)-1], src2.b[len(src1.b)-1] // hoist bounds checks out of the loop
-
-	for i, x := range src1.b {
-		dst.b[i] = x | src2.b[i]
-	}
-}
-
-// intersection
-func (dst bvec) And(src1, src2 bvec) {
-	if len(src1.b) == 0 {
-		return
-	}
-	_, _ = dst.b[len(src1.b)-1], src2.b[len(src1.b)-1] // hoist bounds checks out of the loop
-
-	for i, x := range src1.b {
-		dst.b[i] = x & src2.b[i]
-	}
-}
-
-// difference
-func (dst bvec) AndNot(src1, src2 bvec) {
-	if len(src1.b) == 0 {
-		return
-	}
-	_, _ = dst.b[len(src1.b)-1], src2.b[len(src1.b)-1] // hoist bounds checks out of the loop
-
-	for i, x := range src1.b {
-		dst.b[i] = x &^ src2.b[i]
-	}
-}
-
-func (bv bvec) String() string {
-	s := make([]byte, 2+bv.n)
-	copy(s, "#*")
-	for i := int32(0); i < bv.n; i++ {
-		ch := byte('0')
-		if bv.Get(i) {
-			ch = '1'
-		}
-		s[2+i] = ch
-	}
-	return string(s)
-}
-
-func (bv bvec) Clear() {
-	for i := range bv.b {
-		bv.b[i] = 0
-	}
-}
-
-// FNV-1 hash function constants.
-const (
-	H0 = 2166136261
-	Hp = 16777619
-)
-
-func hashbitmap(h uint32, bv bvec) uint32 {
-	n := int((bv.n + 31) / 32)
-	for i := 0; i < n; i++ {
-		w := bv.b[i]
-		h = (h * Hp) ^ (w & 0xff)
-		h = (h * Hp) ^ ((w >> 8) & 0xff)
-		h = (h * Hp) ^ ((w >> 16) & 0xff)
-		h = (h * Hp) ^ ((w >> 24) & 0xff)
-	}
-
-	return h
-}
-
-// bvecSet is a set of bvecs, in initial insertion order.
-type bvecSet struct {
-	index []int  // hash -> uniq index. -1 indicates empty slot.
-	uniq  []bvec // unique bvecs, in insertion order
-}
-
-func (m *bvecSet) grow() {
-	// Allocate new index.
-	n := len(m.index) * 2
-	if n == 0 {
-		n = 32
-	}
-	newIndex := make([]int, n)
-	for i := range newIndex {
-		newIndex[i] = -1
-	}
-
-	// Rehash into newIndex.
-	for i, bv := range m.uniq {
-		h := hashbitmap(H0, bv) % uint32(len(newIndex))
-		for {
-			j := newIndex[h]
-			if j < 0 {
-				newIndex[h] = i
-				break
-			}
-			h++
-			if h == uint32(len(newIndex)) {
-				h = 0
-			}
-		}
-	}
-	m.index = newIndex
-}
-
-// add adds bv to the set and returns its index in m.extractUniqe.
-// The caller must not modify bv after this.
-func (m *bvecSet) add(bv bvec) int {
-	if len(m.uniq)*4 >= len(m.index) {
-		m.grow()
-	}
-
-	index := m.index
-	h := hashbitmap(H0, bv) % uint32(len(index))
-	for {
-		j := index[h]
-		if j < 0 {
-			// New bvec.
-			index[h] = len(m.uniq)
-			m.uniq = append(m.uniq, bv)
-			return len(m.uniq) - 1
-		}
-		jlive := m.uniq[j]
-		if bv.Eq(jlive) {
-			// Existing bvec.
-			return j
-		}
-
-		h++
-		if h == uint32(len(index)) {
-			h = 0
-		}
-	}
-}
-
-// extractUniqe returns this slice of unique bit vectors in m, as
-// indexed by the result of bvecSet.add.
-func (m *bvecSet) extractUniqe() []bvec {
-	return m.uniq
-}
diff --git a/src/cmd/compile/internal/gc/class_string.go b/src/cmd/compile/internal/gc/class_string.go
deleted file mode 100644
index a4084a7..0000000
--- a/src/cmd/compile/internal/gc/class_string.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Code generated by "stringer -type=Class"; DO NOT EDIT.
-
-package gc
-
-import "strconv"
-
-func _() {
-	// An "invalid array index" compiler error signifies that the constant values have changed.
-	// Re-run the stringer command to generate them again.
-	var x [1]struct{}
-	_ = x[Pxxx-0]
-	_ = x[PEXTERN-1]
-	_ = x[PAUTO-2]
-	_ = x[PAUTOHEAP-3]
-	_ = x[PPARAM-4]
-	_ = x[PPARAMOUT-5]
-	_ = x[PFUNC-6]
-}
-
-const _Class_name = "PxxxPEXTERNPAUTOPAUTOHEAPPPARAMPPARAMOUTPFUNC"
-
-var _Class_index = [...]uint8{0, 4, 11, 16, 25, 31, 40, 45}
-
-func (i Class) String() string {
-	if i >= Class(len(_Class_index)-1) {
-		return "Class(" + strconv.FormatInt(int64(i), 10) + ")"
-	}
-	return _Class_name[_Class_index[i]:_Class_index[i+1]]
-}
diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go
deleted file mode 100644
index bd350f6..0000000
--- a/src/cmd/compile/internal/gc/closure.go
+++ /dev/null
@@ -1,594 +0,0 @@
-// Copyright 2009 The Go Authors. 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/compile/internal/syntax"
-	"cmd/compile/internal/types"
-	"fmt"
-)
-
-func (p *noder) funcLit(expr *syntax.FuncLit) *Node {
-	xtype := p.typeExpr(expr.Type)
-	ntype := p.typeExpr(expr.Type)
-
-	xfunc := p.nod(expr, ODCLFUNC, nil, nil)
-	xfunc.Func.SetIsHiddenClosure(Curfn != nil)
-	xfunc.Func.Nname = newfuncnamel(p.pos(expr), nblank.Sym) // filled in by typecheckclosure
-	xfunc.Func.Nname.Name.Param.Ntype = xtype
-	xfunc.Func.Nname.Name.Defn = xfunc
-
-	clo := p.nod(expr, OCLOSURE, nil, nil)
-	clo.Func.Ntype = ntype
-
-	xfunc.Func.Closure = clo
-	clo.Func.Closure = xfunc
-
-	p.funcBody(xfunc, expr.Body)
-
-	// closure-specific variables are hanging off the
-	// ordinary ones in the symbol table; see oldname.
-	// unhook them.
-	// make the list of pointers for the closure call.
-	for _, v := range xfunc.Func.Cvars.Slice() {
-		// Unlink from v1; see comment in syntax.go type Param for these fields.
-		v1 := v.Name.Defn
-		v1.Name.Param.Innermost = v.Name.Param.Outer
-
-		// If the closure usage of v is not dense,
-		// we need to make it dense; now that we're out
-		// of the function in which v appeared,
-		// look up v.Sym in the enclosing function
-		// and keep it around for use in the compiled code.
-		//
-		// That is, suppose we just finished parsing the innermost
-		// closure f4 in this code:
-		//
-		//	func f() {
-		//		v := 1
-		//		func() { // f2
-		//			use(v)
-		//			func() { // f3
-		//				func() { // f4
-		//					use(v)
-		//				}()
-		//			}()
-		//		}()
-		//	}
-		//
-		// At this point v.Outer is f2's v; there is no f3's v.
-		// To construct the closure f4 from within f3,
-		// we need to use f3's v and in this case we need to create f3's v.
-		// We are now in the context of f3, so calling oldname(v.Sym)
-		// obtains f3's v, creating it if necessary (as it is in the example).
-		//
-		// capturevars will decide whether to use v directly or &v.
-		v.Name.Param.Outer = oldname(v.Sym)
-	}
-
-	return clo
-}
-
-// typecheckclosure typechecks an OCLOSURE node. It also creates the named
-// function associated with the closure.
-// TODO: This creation of the named function should probably really be done in a
-// separate pass from type-checking.
-func typecheckclosure(clo *Node, top int) {
-	xfunc := clo.Func.Closure
-	// Set current associated iota value, so iota can be used inside
-	// function in ConstSpec, see issue #22344
-	if x := getIotaValue(); x >= 0 {
-		xfunc.SetIota(x)
-	}
-
-	clo.Func.Ntype = typecheck(clo.Func.Ntype, ctxType)
-	clo.Type = clo.Func.Ntype.Type
-	clo.Func.Top = top
-
-	// Do not typecheck xfunc twice, otherwise, we will end up pushing
-	// xfunc to xtop multiple times, causing initLSym called twice.
-	// See #30709
-	if xfunc.Typecheck() == 1 {
-		return
-	}
-
-	for _, ln := range xfunc.Func.Cvars.Slice() {
-		n := ln.Name.Defn
-		if !n.Name.Captured() {
-			n.Name.SetCaptured(true)
-			if n.Name.Decldepth == 0 {
-				Fatalf("typecheckclosure: var %S does not have decldepth assigned", n)
-			}
-
-			// Ignore assignments to the variable in straightline code
-			// preceding the first capturing by a closure.
-			if n.Name.Decldepth == decldepth {
-				n.Name.SetAssigned(false)
-			}
-		}
-	}
-
-	xfunc.Func.Nname.Sym = closurename(Curfn)
-	setNodeNameFunc(xfunc.Func.Nname)
-	xfunc = typecheck(xfunc, ctxStmt)
-
-	// Type check the body now, but only if we're inside a function.
-	// At top level (in a variable initialization: curfn==nil) we're not
-	// ready to type check code yet; we'll check it later, because the
-	// underlying closure function we create is added to xtop.
-	if Curfn != nil && clo.Type != nil {
-		oldfn := Curfn
-		Curfn = xfunc
-		olddd := decldepth
-		decldepth = 1
-		typecheckslice(xfunc.Nbody.Slice(), ctxStmt)
-		decldepth = olddd
-		Curfn = oldfn
-	}
-
-	xtop = append(xtop, xfunc)
-}
-
-// globClosgen is like Func.Closgen, but for the global scope.
-var globClosgen int
-
-// closurename generates a new unique name for a closure within
-// outerfunc.
-func closurename(outerfunc *Node) *types.Sym {
-	outer := "glob."
-	prefix := "func"
-	gen := &globClosgen
-
-	if outerfunc != nil {
-		if outerfunc.Func.Closure != nil {
-			prefix = ""
-		}
-
-		outer = outerfunc.funcname()
-
-		// There may be multiple functions named "_". In those
-		// cases, we can't use their individual Closgens as it
-		// would lead to name clashes.
-		if !outerfunc.Func.Nname.isBlank() {
-			gen = &outerfunc.Func.Closgen
-		}
-	}
-
-	*gen++
-	return lookup(fmt.Sprintf("%s.%s%d", outer, prefix, *gen))
-}
-
-// capturevarscomplete is set to true when the capturevars phase is done.
-var capturevarscomplete bool
-
-// capturevars is called in a separate phase after all typechecking is done.
-// It decides whether each variable captured by a closure should be captured
-// by value or by reference.
-// We use value capturing for values <= 128 bytes that are never reassigned
-// after capturing (effectively constant).
-func capturevars(xfunc *Node) {
-	lno := lineno
-	lineno = xfunc.Pos
-
-	clo := xfunc.Func.Closure
-	cvars := xfunc.Func.Cvars.Slice()
-	out := cvars[:0]
-	for _, v := range cvars {
-		if v.Type == nil {
-			// If v.Type is nil, it means v looked like it
-			// was going to be used in the closure, but
-			// isn't. This happens in struct literals like
-			// s{f: x} where we can't distinguish whether
-			// f is a field identifier or expression until
-			// resolving s.
-			continue
-		}
-		out = append(out, v)
-
-		// type check the & of closed variables outside the closure,
-		// so that the outer frame also grabs them and knows they escape.
-		dowidth(v.Type)
-
-		outer := v.Name.Param.Outer
-		outermost := v.Name.Defn
-
-		// out parameters will be assigned to implicitly upon return.
-		if outermost.Class() != PPARAMOUT && !outermost.Name.Addrtaken() && !outermost.Name.Assigned() && v.Type.Width <= 128 {
-			v.Name.SetByval(true)
-		} else {
-			outermost.Name.SetAddrtaken(true)
-			outer = nod(OADDR, outer, nil)
-		}
-
-		if Debug.m > 1 {
-			var name *types.Sym
-			if v.Name.Curfn != nil && v.Name.Curfn.Func.Nname != nil {
-				name = v.Name.Curfn.Func.Nname.Sym
-			}
-			how := "ref"
-			if v.Name.Byval() {
-				how = "value"
-			}
-			Warnl(v.Pos, "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym, outermost.Name.Addrtaken(), outermost.Name.Assigned(), int32(v.Type.Width))
-		}
-
-		outer = typecheck(outer, ctxExpr)
-		clo.Func.Enter.Append(outer)
-	}
-
-	xfunc.Func.Cvars.Set(out)
-	lineno = lno
-}
-
-// transformclosure is called in a separate phase after escape analysis.
-// It transform closure bodies to properly reference captured variables.
-func transformclosure(xfunc *Node) {
-	lno := lineno
-	lineno = xfunc.Pos
-	clo := xfunc.Func.Closure
-
-	if clo.Func.Top&ctxCallee != 0 {
-		// If the closure is directly called, we transform it to a plain function call
-		// with variables passed as args. This avoids allocation of a closure object.
-		// Here we do only a part of the transformation. Walk of OCALLFUNC(OCLOSURE)
-		// will complete the transformation later.
-		// For illustration, the following closure:
-		//	func(a int) {
-		//		println(byval)
-		//		byref++
-		//	}(42)
-		// becomes:
-		//	func(byval int, &byref *int, a int) {
-		//		println(byval)
-		//		(*&byref)++
-		//	}(byval, &byref, 42)
-
-		// f is ONAME of the actual function.
-		f := xfunc.Func.Nname
-
-		// We are going to insert captured variables before input args.
-		var params []*types.Field
-		var decls []*Node
-		for _, v := range xfunc.Func.Cvars.Slice() {
-			if !v.Name.Byval() {
-				// If v of type T is captured by reference,
-				// we introduce function param &v *T
-				// and v remains PAUTOHEAP with &v heapaddr
-				// (accesses will implicitly deref &v).
-				addr := newname(lookup("&" + v.Sym.Name))
-				addr.Type = types.NewPtr(v.Type)
-				v.Name.Param.Heapaddr = addr
-				v = addr
-			}
-
-			v.SetClass(PPARAM)
-			decls = append(decls, v)
-
-			fld := types.NewField()
-			fld.Nname = asTypesNode(v)
-			fld.Type = v.Type
-			fld.Sym = v.Sym
-			params = append(params, fld)
-		}
-
-		if len(params) > 0 {
-			// Prepend params and decls.
-			f.Type.Params().SetFields(append(params, f.Type.Params().FieldSlice()...))
-			xfunc.Func.Dcl = append(decls, xfunc.Func.Dcl...)
-		}
-
-		dowidth(f.Type)
-		xfunc.Type = f.Type // update type of ODCLFUNC
-	} else {
-		// The closure is not called, so it is going to stay as closure.
-		var body []*Node
-		offset := int64(Widthptr)
-		for _, v := range xfunc.Func.Cvars.Slice() {
-			// cv refers to the field inside of closure OSTRUCTLIT.
-			cv := nod(OCLOSUREVAR, nil, nil)
-
-			cv.Type = v.Type
-			if !v.Name.Byval() {
-				cv.Type = types.NewPtr(v.Type)
-			}
-			offset = Rnd(offset, int64(cv.Type.Align))
-			cv.Xoffset = offset
-			offset += cv.Type.Width
-
-			if v.Name.Byval() && v.Type.Width <= int64(2*Widthptr) {
-				// If it is a small variable captured by value, downgrade it to PAUTO.
-				v.SetClass(PAUTO)
-				xfunc.Func.Dcl = append(xfunc.Func.Dcl, v)
-				body = append(body, nod(OAS, v, cv))
-			} else {
-				// Declare variable holding addresses taken from closure
-				// and initialize in entry prologue.
-				addr := newname(lookup("&" + v.Sym.Name))
-				addr.Type = types.NewPtr(v.Type)
-				addr.SetClass(PAUTO)
-				addr.Name.SetUsed(true)
-				addr.Name.Curfn = xfunc
-				xfunc.Func.Dcl = append(xfunc.Func.Dcl, addr)
-				v.Name.Param.Heapaddr = addr
-				if v.Name.Byval() {
-					cv = nod(OADDR, cv, nil)
-				}
-				body = append(body, nod(OAS, addr, cv))
-			}
-		}
-
-		if len(body) > 0 {
-			typecheckslice(body, ctxStmt)
-			xfunc.Func.Enter.Set(body)
-			xfunc.Func.SetNeedctxt(true)
-		}
-	}
-
-	lineno = lno
-}
-
-// hasemptycvars reports whether closure clo has an
-// empty list of captured vars.
-func hasemptycvars(clo *Node) bool {
-	xfunc := clo.Func.Closure
-	return xfunc.Func.Cvars.Len() == 0
-}
-
-// closuredebugruntimecheck applies boilerplate checks for debug flags
-// and compiling runtime
-func closuredebugruntimecheck(clo *Node) {
-	if Debug_closure > 0 {
-		xfunc := clo.Func.Closure
-		if clo.Esc == EscHeap {
-			Warnl(clo.Pos, "heap closure, captured vars = %v", xfunc.Func.Cvars)
-		} else {
-			Warnl(clo.Pos, "stack closure, captured vars = %v", xfunc.Func.Cvars)
-		}
-	}
-	if compiling_runtime && clo.Esc == EscHeap {
-		yyerrorl(clo.Pos, "heap-allocated closure, not allowed in runtime")
-	}
-}
-
-// closureType returns the struct type used to hold all the information
-// needed in the closure for clo (clo must be a OCLOSURE node).
-// The address of a variable of the returned type can be cast to a func.
-func closureType(clo *Node) *types.Type {
-	// Create closure in the form of a composite literal.
-	// supposing the closure captures an int i and a string s
-	// and has one float64 argument and no results,
-	// the generated code looks like:
-	//
-	//	clos = &struct{.F uintptr; i *int; s *string}{func.1, &i, &s}
-	//
-	// The use of the struct provides type information to the garbage
-	// collector so that it can walk the closure. We could use (in this case)
-	// [3]unsafe.Pointer instead, but that would leave the gc in the dark.
-	// The information appears in the binary in the form of type descriptors;
-	// the struct is unnamed so that closures in multiple packages with the
-	// same struct type can share the descriptor.
-	fields := []*Node{
-		namedfield(".F", types.Types[TUINTPTR]),
-	}
-	for _, v := range clo.Func.Closure.Func.Cvars.Slice() {
-		typ := v.Type
-		if !v.Name.Byval() {
-			typ = types.NewPtr(typ)
-		}
-		fields = append(fields, symfield(v.Sym, typ))
-	}
-	typ := tostruct(fields)
-	typ.SetNoalg(true)
-	return typ
-}
-
-func walkclosure(clo *Node, init *Nodes) *Node {
-	xfunc := clo.Func.Closure
-
-	// If no closure vars, don't bother wrapping.
-	if hasemptycvars(clo) {
-		if Debug_closure > 0 {
-			Warnl(clo.Pos, "closure converted to global")
-		}
-		return xfunc.Func.Nname
-	}
-	closuredebugruntimecheck(clo)
-
-	typ := closureType(clo)
-
-	clos := nod(OCOMPLIT, nil, typenod(typ))
-	clos.Esc = clo.Esc
-	clos.List.Set(append([]*Node{nod(OCFUNC, xfunc.Func.Nname, nil)}, clo.Func.Enter.Slice()...))
-
-	clos = nod(OADDR, clos, nil)
-	clos.Esc = clo.Esc
-
-	// Force type conversion from *struct to the func type.
-	clos = convnop(clos, clo.Type)
-
-	// non-escaping temp to use, if any.
-	if x := prealloc[clo]; x != nil {
-		if !types.Identical(typ, x.Type) {
-			panic("closure type does not match order's assigned type")
-		}
-		clos.Left.Right = x
-		delete(prealloc, clo)
-	}
-
-	return walkexpr(clos, init)
-}
-
-func typecheckpartialcall(fn *Node, sym *types.Sym) {
-	switch fn.Op {
-	case ODOTINTER, ODOTMETH:
-		break
-
-	default:
-		Fatalf("invalid typecheckpartialcall")
-	}
-
-	// Create top-level function.
-	xfunc := makepartialcall(fn, fn.Type, sym)
-	fn.Func = xfunc.Func
-	fn.Func.SetWrapper(true)
-	fn.Right = newname(sym)
-	fn.Op = OCALLPART
-	fn.Type = xfunc.Type
-}
-
-// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
-// for partial calls.
-func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node {
-	rcvrtype := fn.Left.Type
-	sym := methodSymSuffix(rcvrtype, meth, "-fm")
-
-	if sym.Uniq() {
-		return asNode(sym.Def)
-	}
-	sym.SetUniq(true)
-
-	savecurfn := Curfn
-	saveLineNo := lineno
-	Curfn = nil
-
-	// Set line number equal to the line number where the method is declared.
-	var m *types.Field
-	if lookdot0(meth, rcvrtype, &m, false) == 1 && m.Pos.IsKnown() {
-		lineno = m.Pos
-	}
-	// Note: !m.Pos.IsKnown() happens for method expressions where
-	// the method is implicitly declared. The Error method of the
-	// built-in error type is one such method.  We leave the line
-	// number at the use of the method expression in this
-	// case. See issue 29389.
-
-	tfn := nod(OTFUNC, nil, nil)
-	tfn.List.Set(structargs(t0.Params(), true))
-	tfn.Rlist.Set(structargs(t0.Results(), false))
-
-	xfunc := dclfunc(sym, tfn)
-	xfunc.Func.SetDupok(true)
-	xfunc.Func.SetNeedctxt(true)
-
-	tfn.Type.SetPkg(t0.Pkg())
-
-	// Declare and initialize variable holding receiver.
-
-	cv := nod(OCLOSUREVAR, nil, nil)
-	cv.Type = rcvrtype
-	cv.Xoffset = Rnd(int64(Widthptr), int64(cv.Type.Align))
-
-	ptr := newname(lookup(".this"))
-	declare(ptr, PAUTO)
-	ptr.Name.SetUsed(true)
-	var body []*Node
-	if rcvrtype.IsPtr() || rcvrtype.IsInterface() {
-		ptr.Type = rcvrtype
-		body = append(body, nod(OAS, ptr, cv))
-	} else {
-		ptr.Type = types.NewPtr(rcvrtype)
-		body = append(body, nod(OAS, ptr, nod(OADDR, cv, nil)))
-	}
-
-	call := nod(OCALL, nodSym(OXDOT, ptr, meth), nil)
-	call.List.Set(paramNnames(tfn.Type))
-	call.SetIsDDD(tfn.Type.IsVariadic())
-	if t0.NumResults() != 0 {
-		n := nod(ORETURN, nil, nil)
-		n.List.Set1(call)
-		call = n
-	}
-	body = append(body, call)
-
-	xfunc.Nbody.Set(body)
-	funcbody()
-
-	xfunc = typecheck(xfunc, ctxStmt)
-	// Need to typecheck the body of the just-generated wrapper.
-	// typecheckslice() requires that Curfn is set when processing an ORETURN.
-	Curfn = xfunc
-	typecheckslice(xfunc.Nbody.Slice(), ctxStmt)
-	sym.Def = asTypesNode(xfunc)
-	xtop = append(xtop, xfunc)
-	Curfn = savecurfn
-	lineno = saveLineNo
-
-	return xfunc
-}
-
-// partialCallType returns the struct type used to hold all the information
-// needed in the closure for n (n must be a OCALLPART node).
-// The address of a variable of the returned type can be cast to a func.
-func partialCallType(n *Node) *types.Type {
-	t := tostruct([]*Node{
-		namedfield("F", types.Types[TUINTPTR]),
-		namedfield("R", n.Left.Type),
-	})
-	t.SetNoalg(true)
-	return t
-}
-
-func walkpartialcall(n *Node, init *Nodes) *Node {
-	// Create closure in the form of a composite literal.
-	// For x.M with receiver (x) type T, the generated code looks like:
-	//
-	//	clos = &struct{F uintptr; R T}{T.M·f, x}
-	//
-	// Like walkclosure above.
-
-	if n.Left.Type.IsInterface() {
-		// Trigger panic for method on nil interface now.
-		// Otherwise it happens in the wrapper and is confusing.
-		n.Left = cheapexpr(n.Left, init)
-		n.Left = walkexpr(n.Left, nil)
-
-		tab := nod(OITAB, n.Left, nil)
-		tab = typecheck(tab, ctxExpr)
-
-		c := nod(OCHECKNIL, tab, nil)
-		c.SetTypecheck(1)
-		init.Append(c)
-	}
-
-	typ := partialCallType(n)
-
-	clos := nod(OCOMPLIT, nil, typenod(typ))
-	clos.Esc = n.Esc
-	clos.List.Set2(nod(OCFUNC, n.Func.Nname, nil), n.Left)
-
-	clos = nod(OADDR, clos, nil)
-	clos.Esc = n.Esc
-
-	// Force type conversion from *struct to the func type.
-	clos = convnop(clos, n.Type)
-
-	// non-escaping temp to use, if any.
-	if x := prealloc[n]; x != nil {
-		if !types.Identical(typ, x.Type) {
-			panic("partial call type does not match order's assigned type")
-		}
-		clos.Left.Right = x
-		delete(prealloc, n)
-	}
-
-	return walkexpr(clos, init)
-}
-
-// callpartMethod returns the *types.Field representing the method
-// referenced by method value n.
-func callpartMethod(n *Node) *types.Field {
-	if n.Op != OCALLPART {
-		Fatalf("expected OCALLPART, got %v", n)
-	}
-
-	// TODO(mdempsky): Optimize this. If necessary,
-	// makepartialcall could save m for us somewhere.
-	var m *types.Field
-	if lookdot0(n.Right.Sym, n.Left.Type, &m, false) != 1 {
-		Fatalf("failed to find field for OCALLPART")
-	}
-
-	return m
-}
diff --git a/src/cmd/compile/internal/gc/compile.go b/src/cmd/compile/internal/gc/compile.go
new file mode 100644
index 0000000..0050445
--- /dev/null
+++ b/src/cmd/compile/internal/gc/compile.go
@@ -0,0 +1,169 @@
+// Copyright 2011 The Go Authors. 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 (
+	"internal/race"
+	"math/rand"
+	"sort"
+	"sync"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/liveness"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/ssagen"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/compile/internal/walk"
+	"cmd/internal/obj"
+)
+
+// "Portable" code generation.
+
+var (
+	compilequeue []*ir.Func // functions waiting to be compiled
+)
+
+func enqueueFunc(fn *ir.Func) {
+	if ir.CurFunc != nil {
+		base.FatalfAt(fn.Pos(), "enqueueFunc %v inside %v", fn, ir.CurFunc)
+	}
+
+	if ir.FuncName(fn) == "_" {
+		// Skip compiling blank functions.
+		// Frontend already reported any spec-mandated errors (#29870).
+		return
+	}
+
+	if clo := fn.OClosure; clo != nil && !ir.IsTrivialClosure(clo) {
+		return // we'll get this as part of its enclosing function
+	}
+
+	if len(fn.Body) == 0 {
+		// Initialize ABI wrappers if necessary.
+		ssagen.InitLSym(fn, false)
+		types.CalcSize(fn.Type())
+		a := ssagen.AbiForBodylessFuncStackMap(fn)
+		abiInfo := a.ABIAnalyzeFuncType(fn.Type().FuncType()) // abiInfo has spill/home locations for wrapper
+		liveness.WriteFuncMap(fn, abiInfo)
+		if fn.ABI == obj.ABI0 {
+			x := ssagen.EmitArgInfo(fn, abiInfo)
+			objw.Global(x, int32(len(x.P)), obj.RODATA|obj.LOCAL)
+		}
+		return
+	}
+
+	errorsBefore := base.Errors()
+
+	todo := []*ir.Func{fn}
+	for len(todo) > 0 {
+		next := todo[len(todo)-1]
+		todo = todo[:len(todo)-1]
+
+		prepareFunc(next)
+		todo = append(todo, next.Closures...)
+	}
+
+	if base.Errors() > errorsBefore {
+		return
+	}
+
+	// Enqueue just fn itself. compileFunctions will handle
+	// scheduling compilation of its closures after it's done.
+	compilequeue = append(compilequeue, fn)
+}
+
+// prepareFunc handles any remaining frontend compilation tasks that
+// aren't yet safe to perform concurrently.
+func prepareFunc(fn *ir.Func) {
+	// Set up the function's LSym early to avoid data races with the assemblers.
+	// Do this before walk, as walk needs the LSym to set attributes/relocations
+	// (e.g. in MarkTypeUsedInInterface).
+	ssagen.InitLSym(fn, true)
+
+	// Calculate parameter offsets.
+	types.CalcSize(fn.Type())
+
+	typecheck.DeclContext = ir.PAUTO
+	ir.CurFunc = fn
+	walk.Walk(fn)
+	ir.CurFunc = nil // enforce no further uses of CurFunc
+	typecheck.DeclContext = ir.PEXTERN
+}
+
+// compileFunctions compiles all functions in compilequeue.
+// It fans out nBackendWorkers to do the work
+// and waits for them to complete.
+func compileFunctions() {
+	if len(compilequeue) == 0 {
+		return
+	}
+
+	if race.Enabled {
+		// Randomize compilation order to try to shake out races.
+		tmp := make([]*ir.Func, len(compilequeue))
+		perm := rand.Perm(len(compilequeue))
+		for i, v := range perm {
+			tmp[v] = compilequeue[i]
+		}
+		copy(compilequeue, tmp)
+	} else {
+		// Compile the longest functions first,
+		// since they're most likely to be the slowest.
+		// This helps avoid stragglers.
+		sort.Slice(compilequeue, func(i, j int) bool {
+			return len(compilequeue[i].Body) > len(compilequeue[j].Body)
+		})
+	}
+
+	// By default, we perform work right away on the current goroutine
+	// as the solo worker.
+	queue := func(work func(int)) {
+		work(0)
+	}
+
+	if nWorkers := base.Flag.LowerC; nWorkers > 1 {
+		// For concurrent builds, we create a goroutine per task, but
+		// require them to hold a unique worker ID while performing work
+		// to limit parallelism.
+		workerIDs := make(chan int, nWorkers)
+		for i := 0; i < nWorkers; i++ {
+			workerIDs <- i
+		}
+
+		queue = func(work func(int)) {
+			go func() {
+				worker := <-workerIDs
+				work(worker)
+				workerIDs <- worker
+			}()
+		}
+	}
+
+	var wg sync.WaitGroup
+	var compile func([]*ir.Func)
+	compile = func(fns []*ir.Func) {
+		wg.Add(len(fns))
+		for _, fn := range fns {
+			fn := fn
+			queue(func(worker int) {
+				ssagen.Compile(fn, worker)
+				compile(fn.Closures)
+				wg.Done()
+			})
+		}
+	}
+
+	types.CalcSizeDisabled = true // not safe to calculate sizes concurrently
+	base.Ctxt.InParallel = true
+
+	compile(compilequeue)
+	compilequeue = nil
+	wg.Wait()
+
+	base.Ctxt.InParallel = false
+	types.CalcSizeDisabled = false
+}
diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go
deleted file mode 100644
index b92c8d6..0000000
--- a/src/cmd/compile/internal/gc/const.go
+++ /dev/null
@@ -1,1323 +0,0 @@
-// Copyright 2009 The Go Authors. 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/compile/internal/types"
-	"cmd/internal/src"
-	"fmt"
-	"math/big"
-	"strings"
-)
-
-// Ctype describes the constant kind of an "ideal" (untyped) constant.
-type Ctype uint8
-
-const (
-	CTxxx Ctype = iota
-
-	CTINT
-	CTRUNE
-	CTFLT
-	CTCPLX
-	CTSTR
-	CTBOOL
-	CTNIL
-)
-
-type Val struct {
-	// U contains one of:
-	// bool     bool when Ctype() == CTBOOL
-	// *Mpint   int when Ctype() == CTINT, rune when Ctype() == CTRUNE
-	// *Mpflt   float when Ctype() == CTFLT
-	// *Mpcplx  pair of floats when Ctype() == CTCPLX
-	// string   string when Ctype() == CTSTR
-	// *Nilval  when Ctype() == CTNIL
-	U interface{}
-}
-
-func (v Val) Ctype() Ctype {
-	switch x := v.U.(type) {
-	default:
-		Fatalf("unexpected Ctype for %T", v.U)
-		panic("unreachable")
-	case nil:
-		return CTxxx
-	case *NilVal:
-		return CTNIL
-	case bool:
-		return CTBOOL
-	case *Mpint:
-		if x.Rune {
-			return CTRUNE
-		}
-		return CTINT
-	case *Mpflt:
-		return CTFLT
-	case *Mpcplx:
-		return CTCPLX
-	case string:
-		return CTSTR
-	}
-}
-
-func eqval(a, b Val) bool {
-	if a.Ctype() != b.Ctype() {
-		return false
-	}
-	switch x := a.U.(type) {
-	default:
-		Fatalf("unexpected Ctype for %T", a.U)
-		panic("unreachable")
-	case *NilVal:
-		return true
-	case bool:
-		y := b.U.(bool)
-		return x == y
-	case *Mpint:
-		y := b.U.(*Mpint)
-		return x.Cmp(y) == 0
-	case *Mpflt:
-		y := b.U.(*Mpflt)
-		return x.Cmp(y) == 0
-	case *Mpcplx:
-		y := b.U.(*Mpcplx)
-		return x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0
-	case string:
-		y := b.U.(string)
-		return x == y
-	}
-}
-
-// Interface returns the constant value stored in v as an interface{}.
-// It returns int64s for ints and runes, float64s for floats,
-// complex128s for complex values, and nil for constant nils.
-func (v Val) Interface() interface{} {
-	switch x := v.U.(type) {
-	default:
-		Fatalf("unexpected Interface for %T", v.U)
-		panic("unreachable")
-	case *NilVal:
-		return nil
-	case bool, string:
-		return x
-	case *Mpint:
-		return x.Int64()
-	case *Mpflt:
-		return x.Float64()
-	case *Mpcplx:
-		return complex(x.Real.Float64(), x.Imag.Float64())
-	}
-}
-
-type NilVal struct{}
-
-// Int64Val returns n as an int64.
-// n must be an integer or rune constant.
-func (n *Node) Int64Val() int64 {
-	if !Isconst(n, CTINT) {
-		Fatalf("Int64Val(%v)", n)
-	}
-	return n.Val().U.(*Mpint).Int64()
-}
-
-// CanInt64 reports whether it is safe to call Int64Val() on n.
-func (n *Node) CanInt64() bool {
-	if !Isconst(n, CTINT) {
-		return false
-	}
-
-	// if the value inside n cannot be represented as an int64, the
-	// return value of Int64 is undefined
-	return n.Val().U.(*Mpint).CmpInt64(n.Int64Val()) == 0
-}
-
-// BoolVal returns n as a bool.
-// n must be a boolean constant.
-func (n *Node) BoolVal() bool {
-	if !Isconst(n, CTBOOL) {
-		Fatalf("BoolVal(%v)", n)
-	}
-	return n.Val().U.(bool)
-}
-
-// StringVal returns the value of a literal string Node as a string.
-// n must be a string constant.
-func (n *Node) StringVal() string {
-	if !Isconst(n, CTSTR) {
-		Fatalf("StringVal(%v)", n)
-	}
-	return n.Val().U.(string)
-}
-
-// truncate float literal fv to 32-bit or 64-bit precision
-// according to type; return truncated value.
-func truncfltlit(oldv *Mpflt, t *types.Type) *Mpflt {
-	if t == nil {
-		return oldv
-	}
-
-	if overflow(Val{oldv}, t) {
-		// If there was overflow, simply continuing would set the
-		// value to Inf which in turn would lead to spurious follow-on
-		// errors. Avoid this by returning the existing value.
-		return oldv
-	}
-
-	fv := newMpflt()
-
-	// convert large precision literal floating
-	// into limited precision (float64 or float32)
-	switch t.Etype {
-	case types.TFLOAT32:
-		fv.SetFloat64(oldv.Float32())
-	case types.TFLOAT64:
-		fv.SetFloat64(oldv.Float64())
-	default:
-		Fatalf("truncfltlit: unexpected Etype %v", t.Etype)
-	}
-
-	return fv
-}
-
-// truncate Real and Imag parts of Mpcplx to 32-bit or 64-bit
-// precision, according to type; return truncated value. In case of
-// overflow, calls yyerror but does not truncate the input value.
-func trunccmplxlit(oldv *Mpcplx, t *types.Type) *Mpcplx {
-	if t == nil {
-		return oldv
-	}
-
-	if overflow(Val{oldv}, t) {
-		// If there was overflow, simply continuing would set the
-		// value to Inf which in turn would lead to spurious follow-on
-		// errors. Avoid this by returning the existing value.
-		return oldv
-	}
-
-	cv := newMpcmplx()
-
-	switch t.Etype {
-	case types.TCOMPLEX64:
-		cv.Real.SetFloat64(oldv.Real.Float32())
-		cv.Imag.SetFloat64(oldv.Imag.Float32())
-	case types.TCOMPLEX128:
-		cv.Real.SetFloat64(oldv.Real.Float64())
-		cv.Imag.SetFloat64(oldv.Imag.Float64())
-	default:
-		Fatalf("trunccplxlit: unexpected Etype %v", t.Etype)
-	}
-
-	return cv
-}
-
-// TODO(mdempsky): Replace these with better APIs.
-func convlit(n *Node, t *types.Type) *Node    { return convlit1(n, t, false, nil) }
-func defaultlit(n *Node, t *types.Type) *Node { return convlit1(n, t, false, nil) }
-
-// convlit1 converts an untyped expression n to type t. If n already
-// has a type, convlit1 has no effect.
-//
-// For explicit conversions, t must be non-nil, and integer-to-string
-// conversions are allowed.
-//
-// For implicit conversions (e.g., assignments), t may be nil; if so,
-// n is converted to its default type.
-//
-// If there's an error converting n to t, context is used in the error
-// message.
-func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Node {
-	if explicit && t == nil {
-		Fatalf("explicit conversion missing type")
-	}
-	if t != nil && t.IsUntyped() {
-		Fatalf("bad conversion to untyped: %v", t)
-	}
-
-	if n == nil || n.Type == nil {
-		// Allow sloppy callers.
-		return n
-	}
-	if !n.Type.IsUntyped() {
-		// Already typed; nothing to do.
-		return n
-	}
-
-	if n.Op == OLITERAL {
-		// Can't always set n.Type directly on OLITERAL nodes.
-		// See discussion on CL 20813.
-		n = n.rawcopy()
-	}
-
-	// Nil is technically not a constant, so handle it specially.
-	if n.Type.Etype == TNIL {
-		if t == nil {
-			yyerror("use of untyped nil")
-			n.SetDiag(true)
-			n.Type = nil
-			return n
-		}
-
-		if !t.HasNil() {
-			// Leave for caller to handle.
-			return n
-		}
-
-		n.Type = t
-		return n
-	}
-
-	if t == nil || !okforconst[t.Etype] {
-		t = defaultType(n.Type)
-	}
-
-	switch n.Op {
-	default:
-		Fatalf("unexpected untyped expression: %v", n)
-
-	case OLITERAL:
-		v := convertVal(n.Val(), t, explicit)
-		if v.U == nil {
-			break
-		}
-		n.SetVal(v)
-		n.Type = t
-		return n
-
-	case OPLUS, ONEG, OBITNOT, ONOT, OREAL, OIMAG:
-		ot := operandType(n.Op, t)
-		if ot == nil {
-			n = defaultlit(n, nil)
-			break
-		}
-
-		n.Left = convlit(n.Left, ot)
-		if n.Left.Type == nil {
-			n.Type = nil
-			return n
-		}
-		n.Type = t
-		return n
-
-	case OADD, OSUB, OMUL, ODIV, OMOD, OOR, OXOR, OAND, OANDNOT, OOROR, OANDAND, OCOMPLEX:
-		ot := operandType(n.Op, t)
-		if ot == nil {
-			n = defaultlit(n, nil)
-			break
-		}
-
-		n.Left = convlit(n.Left, ot)
-		n.Right = convlit(n.Right, ot)
-		if n.Left.Type == nil || n.Right.Type == nil {
-			n.Type = nil
-			return n
-		}
-		if !types.Identical(n.Left.Type, n.Right.Type) {
-			yyerror("invalid operation: %v (mismatched types %v and %v)", n, n.Left.Type, n.Right.Type)
-			n.Type = nil
-			return n
-		}
-
-		n.Type = t
-		return n
-
-	case OEQ, ONE, OLT, OLE, OGT, OGE:
-		if !t.IsBoolean() {
-			break
-		}
-		n.Type = t
-		return n
-
-	case OLSH, ORSH:
-		n.Left = convlit1(n.Left, t, explicit, nil)
-		n.Type = n.Left.Type
-		if n.Type != nil && !n.Type.IsInteger() {
-			yyerror("invalid operation: %v (shift of type %v)", n, n.Type)
-			n.Type = nil
-		}
-		return n
-	}
-
-	if !n.Diag() {
-		if !t.Broke() {
-			if explicit {
-				yyerror("cannot convert %L to type %v", n, t)
-			} else if context != nil {
-				yyerror("cannot use %L as type %v in %s", n, t, context())
-			} else {
-				yyerror("cannot use %L as type %v", n, t)
-			}
-		}
-		n.SetDiag(true)
-	}
-	n.Type = nil
-	return n
-}
-
-func operandType(op Op, t *types.Type) *types.Type {
-	switch op {
-	case OCOMPLEX:
-		if t.IsComplex() {
-			return floatForComplex(t)
-		}
-	case OREAL, OIMAG:
-		if t.IsFloat() {
-			return complexForFloat(t)
-		}
-	default:
-		if okfor[op][t.Etype] {
-			return t
-		}
-	}
-	return nil
-}
-
-// convertVal converts v into a representation appropriate for t. If
-// no such representation exists, it returns Val{} instead.
-//
-// If explicit is true, then conversions from integer to string are
-// also allowed.
-func convertVal(v Val, t *types.Type, explicit bool) Val {
-	switch ct := v.Ctype(); ct {
-	case CTBOOL:
-		if t.IsBoolean() {
-			return v
-		}
-
-	case CTSTR:
-		if t.IsString() {
-			return v
-		}
-
-	case CTINT, CTRUNE:
-		if explicit && t.IsString() {
-			return tostr(v)
-		}
-		fallthrough
-	case CTFLT, CTCPLX:
-		switch {
-		case t.IsInteger():
-			v = toint(v)
-			overflow(v, t)
-			return v
-		case t.IsFloat():
-			v = toflt(v)
-			v = Val{truncfltlit(v.U.(*Mpflt), t)}
-			return v
-		case t.IsComplex():
-			v = tocplx(v)
-			v = Val{trunccmplxlit(v.U.(*Mpcplx), t)}
-			return v
-		}
-	}
-
-	return Val{}
-}
-
-func tocplx(v Val) Val {
-	switch u := v.U.(type) {
-	case *Mpint:
-		c := newMpcmplx()
-		c.Real.SetInt(u)
-		c.Imag.SetFloat64(0.0)
-		v.U = c
-
-	case *Mpflt:
-		c := newMpcmplx()
-		c.Real.Set(u)
-		c.Imag.SetFloat64(0.0)
-		v.U = c
-	}
-
-	return v
-}
-
-func toflt(v Val) Val {
-	switch u := v.U.(type) {
-	case *Mpint:
-		f := newMpflt()
-		f.SetInt(u)
-		v.U = f
-
-	case *Mpcplx:
-		f := newMpflt()
-		f.Set(&u.Real)
-		if u.Imag.CmpFloat64(0) != 0 {
-			yyerror("constant %v truncated to real", u.GoString())
-		}
-		v.U = f
-	}
-
-	return v
-}
-
-func toint(v Val) Val {
-	switch u := v.U.(type) {
-	case *Mpint:
-		if u.Rune {
-			i := new(Mpint)
-			i.Set(u)
-			v.U = i
-		}
-
-	case *Mpflt:
-		i := new(Mpint)
-		if !i.SetFloat(u) {
-			if i.checkOverflow(0) {
-				yyerror("integer too large")
-			} else {
-				// The value of u cannot be represented as an integer;
-				// so we need to print an error message.
-				// Unfortunately some float values cannot be
-				// reasonably formatted for inclusion in an error
-				// message (example: 1 + 1e-100), so first we try to
-				// format the float; if the truncation resulted in
-				// something that looks like an integer we omit the
-				// value from the error message.
-				// (See issue #11371).
-				var t big.Float
-				t.Parse(u.GoString(), 10)
-				if t.IsInt() {
-					yyerror("constant truncated to integer")
-				} else {
-					yyerror("constant %v truncated to integer", u.GoString())
-				}
-			}
-		}
-		v.U = i
-
-	case *Mpcplx:
-		i := new(Mpint)
-		if !i.SetFloat(&u.Real) || u.Imag.CmpFloat64(0) != 0 {
-			yyerror("constant %v truncated to integer", u.GoString())
-		}
-
-		v.U = i
-	}
-
-	return v
-}
-
-func doesoverflow(v Val, t *types.Type) bool {
-	switch u := v.U.(type) {
-	case *Mpint:
-		if !t.IsInteger() {
-			Fatalf("overflow: %v integer constant", t)
-		}
-		return u.Cmp(minintval[t.Etype]) < 0 || u.Cmp(maxintval[t.Etype]) > 0
-
-	case *Mpflt:
-		if !t.IsFloat() {
-			Fatalf("overflow: %v floating-point constant", t)
-		}
-		return u.Cmp(minfltval[t.Etype]) <= 0 || u.Cmp(maxfltval[t.Etype]) >= 0
-
-	case *Mpcplx:
-		if !t.IsComplex() {
-			Fatalf("overflow: %v complex constant", t)
-		}
-		return u.Real.Cmp(minfltval[t.Etype]) <= 0 || u.Real.Cmp(maxfltval[t.Etype]) >= 0 ||
-			u.Imag.Cmp(minfltval[t.Etype]) <= 0 || u.Imag.Cmp(maxfltval[t.Etype]) >= 0
-	}
-
-	return false
-}
-
-func overflow(v Val, t *types.Type) bool {
-	// v has already been converted
-	// to appropriate form for t.
-	if t == nil || t.Etype == TIDEAL {
-		return false
-	}
-
-	// Only uintptrs may be converted to pointers, which cannot overflow.
-	if t.IsPtr() || t.IsUnsafePtr() {
-		return false
-	}
-
-	if doesoverflow(v, t) {
-		yyerror("constant %v overflows %v", v, t)
-		return true
-	}
-
-	return false
-
-}
-
-func tostr(v Val) Val {
-	switch u := v.U.(type) {
-	case *Mpint:
-		var r rune = 0xFFFD
-		if u.Cmp(minintval[TINT32]) >= 0 && u.Cmp(maxintval[TINT32]) <= 0 {
-			r = rune(u.Int64())
-		}
-		v.U = string(r)
-	}
-
-	return v
-}
-
-func consttype(n *Node) Ctype {
-	if n == nil || n.Op != OLITERAL {
-		return CTxxx
-	}
-	return n.Val().Ctype()
-}
-
-func Isconst(n *Node, ct Ctype) bool {
-	t := consttype(n)
-
-	// If the caller is asking for CTINT, allow CTRUNE too.
-	// Makes life easier for back ends.
-	return t == ct || (ct == CTINT && t == CTRUNE)
-}
-
-// evconst rewrites constant expressions into OLITERAL nodes.
-func evconst(n *Node) {
-	nl, nr := n.Left, n.Right
-
-	// Pick off just the opcodes that can be constant evaluated.
-	switch op := n.Op; op {
-	case OPLUS, ONEG, OBITNOT, ONOT:
-		if nl.Op == OLITERAL {
-			setconst(n, unaryOp(op, nl.Val(), n.Type))
-		}
-
-	case OADD, OSUB, OMUL, ODIV, OMOD, OOR, OXOR, OAND, OANDNOT, OOROR, OANDAND:
-		if nl.Op == OLITERAL && nr.Op == OLITERAL {
-			setconst(n, binaryOp(nl.Val(), op, nr.Val()))
-		}
-
-	case OEQ, ONE, OLT, OLE, OGT, OGE:
-		if nl.Op == OLITERAL && nr.Op == OLITERAL {
-			setboolconst(n, compareOp(nl.Val(), op, nr.Val()))
-		}
-
-	case OLSH, ORSH:
-		if nl.Op == OLITERAL && nr.Op == OLITERAL {
-			setconst(n, shiftOp(nl.Val(), op, nr.Val()))
-		}
-
-	case OCONV, ORUNESTR:
-		if okforconst[n.Type.Etype] && nl.Op == OLITERAL {
-			setconst(n, convertVal(nl.Val(), n.Type, true))
-		}
-
-	case OCONVNOP:
-		if okforconst[n.Type.Etype] && nl.Op == OLITERAL {
-			// set so n.Orig gets OCONV instead of OCONVNOP
-			n.Op = OCONV
-			setconst(n, nl.Val())
-		}
-
-	case OADDSTR:
-		// Merge adjacent constants in the argument list.
-		s := n.List.Slice()
-		for i1 := 0; i1 < len(s); i1++ {
-			if Isconst(s[i1], CTSTR) && i1+1 < len(s) && Isconst(s[i1+1], CTSTR) {
-				// merge from i1 up to but not including i2
-				var strs []string
-				i2 := i1
-				for i2 < len(s) && Isconst(s[i2], CTSTR) {
-					strs = append(strs, s[i2].StringVal())
-					i2++
-				}
-
-				nl := *s[i1]
-				nl.Orig = &nl
-				nl.SetVal(Val{strings.Join(strs, "")})
-				s[i1] = &nl
-				s = append(s[:i1+1], s[i2:]...)
-			}
-		}
-
-		if len(s) == 1 && Isconst(s[0], CTSTR) {
-			n.Op = OLITERAL
-			n.SetVal(s[0].Val())
-		} else {
-			n.List.Set(s)
-		}
-
-	case OCAP, OLEN:
-		switch nl.Type.Etype {
-		case TSTRING:
-			if Isconst(nl, CTSTR) {
-				setintconst(n, int64(len(nl.StringVal())))
-			}
-		case TARRAY:
-			if !hascallchan(nl) {
-				setintconst(n, nl.Type.NumElem())
-			}
-		}
-
-	case OALIGNOF, OOFFSETOF, OSIZEOF:
-		setintconst(n, evalunsafe(n))
-
-	case OREAL, OIMAG:
-		if nl.Op == OLITERAL {
-			var re, im *Mpflt
-			switch u := nl.Val().U.(type) {
-			case *Mpint:
-				re = newMpflt()
-				re.SetInt(u)
-				// im = 0
-			case *Mpflt:
-				re = u
-				// im = 0
-			case *Mpcplx:
-				re = &u.Real
-				im = &u.Imag
-			default:
-				Fatalf("impossible")
-			}
-			if n.Op == OIMAG {
-				if im == nil {
-					im = newMpflt()
-				}
-				re = im
-			}
-			setconst(n, Val{re})
-		}
-
-	case OCOMPLEX:
-		if nl.Op == OLITERAL && nr.Op == OLITERAL {
-			// make it a complex literal
-			c := newMpcmplx()
-			c.Real.Set(toflt(nl.Val()).U.(*Mpflt))
-			c.Imag.Set(toflt(nr.Val()).U.(*Mpflt))
-			setconst(n, Val{c})
-		}
-	}
-}
-
-func match(x, y Val) (Val, Val) {
-	switch {
-	case x.Ctype() == CTCPLX || y.Ctype() == CTCPLX:
-		return tocplx(x), tocplx(y)
-	case x.Ctype() == CTFLT || y.Ctype() == CTFLT:
-		return toflt(x), toflt(y)
-	}
-
-	// Mixed int/rune are fine.
-	return x, y
-}
-
-func compareOp(x Val, op Op, y Val) bool {
-	x, y = match(x, y)
-
-	switch x.Ctype() {
-	case CTBOOL:
-		x, y := x.U.(bool), y.U.(bool)
-		switch op {
-		case OEQ:
-			return x == y
-		case ONE:
-			return x != y
-		}
-
-	case CTINT, CTRUNE:
-		x, y := x.U.(*Mpint), y.U.(*Mpint)
-		return cmpZero(x.Cmp(y), op)
-
-	case CTFLT:
-		x, y := x.U.(*Mpflt), y.U.(*Mpflt)
-		return cmpZero(x.Cmp(y), op)
-
-	case CTCPLX:
-		x, y := x.U.(*Mpcplx), y.U.(*Mpcplx)
-		eq := x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0
-		switch op {
-		case OEQ:
-			return eq
-		case ONE:
-			return !eq
-		}
-
-	case CTSTR:
-		x, y := x.U.(string), y.U.(string)
-		switch op {
-		case OEQ:
-			return x == y
-		case ONE:
-			return x != y
-		case OLT:
-			return x < y
-		case OLE:
-			return x <= y
-		case OGT:
-			return x > y
-		case OGE:
-			return x >= y
-		}
-	}
-
-	Fatalf("compareOp: bad comparison: %v %v %v", x, op, y)
-	panic("unreachable")
-}
-
-func cmpZero(x int, op Op) bool {
-	switch op {
-	case OEQ:
-		return x == 0
-	case ONE:
-		return x != 0
-	case OLT:
-		return x < 0
-	case OLE:
-		return x <= 0
-	case OGT:
-		return x > 0
-	case OGE:
-		return x >= 0
-	}
-
-	Fatalf("cmpZero: want comparison operator, got %v", op)
-	panic("unreachable")
-}
-
-func binaryOp(x Val, op Op, y Val) Val {
-	x, y = match(x, y)
-
-Outer:
-	switch x.Ctype() {
-	case CTBOOL:
-		x, y := x.U.(bool), y.U.(bool)
-		switch op {
-		case OANDAND:
-			return Val{U: x && y}
-		case OOROR:
-			return Val{U: x || y}
-		}
-
-	case CTINT, CTRUNE:
-		x, y := x.U.(*Mpint), y.U.(*Mpint)
-
-		u := new(Mpint)
-		u.Rune = x.Rune || y.Rune
-		u.Set(x)
-		switch op {
-		case OADD:
-			u.Add(y)
-		case OSUB:
-			u.Sub(y)
-		case OMUL:
-			u.Mul(y)
-		case ODIV:
-			if y.CmpInt64(0) == 0 {
-				yyerror("division by zero")
-				return Val{}
-			}
-			u.Quo(y)
-		case OMOD:
-			if y.CmpInt64(0) == 0 {
-				yyerror("division by zero")
-				return Val{}
-			}
-			u.Rem(y)
-		case OOR:
-			u.Or(y)
-		case OAND:
-			u.And(y)
-		case OANDNOT:
-			u.AndNot(y)
-		case OXOR:
-			u.Xor(y)
-		default:
-			break Outer
-		}
-		return Val{U: u}
-
-	case CTFLT:
-		x, y := x.U.(*Mpflt), y.U.(*Mpflt)
-
-		u := newMpflt()
-		u.Set(x)
-		switch op {
-		case OADD:
-			u.Add(y)
-		case OSUB:
-			u.Sub(y)
-		case OMUL:
-			u.Mul(y)
-		case ODIV:
-			if y.CmpFloat64(0) == 0 {
-				yyerror("division by zero")
-				return Val{}
-			}
-			u.Quo(y)
-		default:
-			break Outer
-		}
-		return Val{U: u}
-
-	case CTCPLX:
-		x, y := x.U.(*Mpcplx), y.U.(*Mpcplx)
-
-		u := newMpcmplx()
-		u.Real.Set(&x.Real)
-		u.Imag.Set(&x.Imag)
-		switch op {
-		case OADD:
-			u.Real.Add(&y.Real)
-			u.Imag.Add(&y.Imag)
-		case OSUB:
-			u.Real.Sub(&y.Real)
-			u.Imag.Sub(&y.Imag)
-		case OMUL:
-			u.Mul(y)
-		case ODIV:
-			if !u.Div(y) {
-				yyerror("complex division by zero")
-				return Val{}
-			}
-		default:
-			break Outer
-		}
-		return Val{U: u}
-	}
-
-	Fatalf("binaryOp: bad operation: %v %v %v", x, op, y)
-	panic("unreachable")
-}
-
-func unaryOp(op Op, x Val, t *types.Type) Val {
-	switch op {
-	case OPLUS:
-		switch x.Ctype() {
-		case CTINT, CTRUNE, CTFLT, CTCPLX:
-			return x
-		}
-
-	case ONEG:
-		switch x.Ctype() {
-		case CTINT, CTRUNE:
-			x := x.U.(*Mpint)
-			u := new(Mpint)
-			u.Rune = x.Rune
-			u.Set(x)
-			u.Neg()
-			return Val{U: u}
-
-		case CTFLT:
-			x := x.U.(*Mpflt)
-			u := newMpflt()
-			u.Set(x)
-			u.Neg()
-			return Val{U: u}
-
-		case CTCPLX:
-			x := x.U.(*Mpcplx)
-			u := newMpcmplx()
-			u.Real.Set(&x.Real)
-			u.Imag.Set(&x.Imag)
-			u.Real.Neg()
-			u.Imag.Neg()
-			return Val{U: u}
-		}
-
-	case OBITNOT:
-		switch x.Ctype() {
-		case CTINT, CTRUNE:
-			x := x.U.(*Mpint)
-
-			u := new(Mpint)
-			u.Rune = x.Rune
-			if t.IsSigned() || t.IsUntyped() {
-				// Signed values change sign.
-				u.SetInt64(-1)
-			} else {
-				// Unsigned values invert their bits.
-				u.Set(maxintval[t.Etype])
-			}
-			u.Xor(x)
-			return Val{U: u}
-		}
-
-	case ONOT:
-		return Val{U: !x.U.(bool)}
-	}
-
-	Fatalf("unaryOp: bad operation: %v %v", op, x)
-	panic("unreachable")
-}
-
-func shiftOp(x Val, op Op, y Val) Val {
-	if x.Ctype() != CTRUNE {
-		x = toint(x)
-	}
-	y = toint(y)
-
-	u := new(Mpint)
-	u.Set(x.U.(*Mpint))
-	u.Rune = x.U.(*Mpint).Rune
-	switch op {
-	case OLSH:
-		u.Lsh(y.U.(*Mpint))
-	case ORSH:
-		u.Rsh(y.U.(*Mpint))
-	default:
-		Fatalf("shiftOp: bad operator: %v", op)
-		panic("unreachable")
-	}
-	return Val{U: u}
-}
-
-// setconst rewrites n as an OLITERAL with value v.
-func setconst(n *Node, v Val) {
-	// If constant folding failed, mark n as broken and give up.
-	if v.U == nil {
-		n.Type = nil
-		return
-	}
-
-	// Ensure n.Orig still points to a semantically-equivalent
-	// expression after we rewrite n into a constant.
-	if n.Orig == n {
-		n.Orig = n.sepcopy()
-	}
-
-	*n = Node{
-		Op:      OLITERAL,
-		Pos:     n.Pos,
-		Orig:    n.Orig,
-		Type:    n.Type,
-		Xoffset: BADWIDTH,
-	}
-	n.SetVal(v)
-	if vt := idealType(v.Ctype()); n.Type.IsUntyped() && n.Type != vt {
-		Fatalf("untyped type mismatch, have: %v, want: %v", n.Type, vt)
-	}
-
-	// Check range.
-	lno := setlineno(n)
-	overflow(v, n.Type)
-	lineno = lno
-
-	if !n.Type.IsUntyped() {
-		switch v.Ctype() {
-		// Truncate precision for non-ideal float.
-		case CTFLT:
-			n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)})
-		// Truncate precision for non-ideal complex.
-		case CTCPLX:
-			n.SetVal(Val{trunccmplxlit(v.U.(*Mpcplx), n.Type)})
-		}
-	}
-}
-
-func setboolconst(n *Node, v bool) {
-	setconst(n, Val{U: v})
-}
-
-func setintconst(n *Node, v int64) {
-	u := new(Mpint)
-	u.SetInt64(v)
-	setconst(n, Val{u})
-}
-
-// nodlit returns a new untyped constant with value v.
-func nodlit(v Val) *Node {
-	n := nod(OLITERAL, nil, nil)
-	n.SetVal(v)
-	n.Type = idealType(v.Ctype())
-	return n
-}
-
-func idealType(ct Ctype) *types.Type {
-	switch ct {
-	case CTSTR:
-		return types.UntypedString
-	case CTBOOL:
-		return types.UntypedBool
-	case CTINT:
-		return types.UntypedInt
-	case CTRUNE:
-		return types.UntypedRune
-	case CTFLT:
-		return types.UntypedFloat
-	case CTCPLX:
-		return types.UntypedComplex
-	case CTNIL:
-		return types.Types[TNIL]
-	}
-	Fatalf("unexpected Ctype: %v", ct)
-	return nil
-}
-
-// defaultlit on both nodes simultaneously;
-// if they're both ideal going in they better
-// get the same type going out.
-// force means must assign concrete (non-ideal) type.
-// The results of defaultlit2 MUST be assigned back to l and r, e.g.
-// 	n.Left, n.Right = defaultlit2(n.Left, n.Right, force)
-func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) {
-	if l.Type == nil || r.Type == nil {
-		return l, r
-	}
-	if !l.Type.IsUntyped() {
-		r = convlit(r, l.Type)
-		return l, r
-	}
-
-	if !r.Type.IsUntyped() {
-		l = convlit(l, r.Type)
-		return l, r
-	}
-
-	if !force {
-		return l, r
-	}
-
-	// Can't mix bool with non-bool, string with non-string, or nil with anything (untyped).
-	if l.Type.IsBoolean() != r.Type.IsBoolean() {
-		return l, r
-	}
-	if l.Type.IsString() != r.Type.IsString() {
-		return l, r
-	}
-	if l.isNil() || r.isNil() {
-		return l, r
-	}
-
-	t := defaultType(mixUntyped(l.Type, r.Type))
-	l = convlit(l, t)
-	r = convlit(r, t)
-	return l, r
-}
-
-func ctype(t *types.Type) Ctype {
-	switch t {
-	case types.UntypedBool:
-		return CTBOOL
-	case types.UntypedString:
-		return CTSTR
-	case types.UntypedInt:
-		return CTINT
-	case types.UntypedRune:
-		return CTRUNE
-	case types.UntypedFloat:
-		return CTFLT
-	case types.UntypedComplex:
-		return CTCPLX
-	}
-	Fatalf("bad type %v", t)
-	panic("unreachable")
-}
-
-func mixUntyped(t1, t2 *types.Type) *types.Type {
-	t := t1
-	if ctype(t2) > ctype(t1) {
-		t = t2
-	}
-	return t
-}
-
-func defaultType(t *types.Type) *types.Type {
-	if !t.IsUntyped() || t.Etype == TNIL {
-		return t
-	}
-
-	switch t {
-	case types.UntypedBool:
-		return types.Types[TBOOL]
-	case types.UntypedString:
-		return types.Types[TSTRING]
-	case types.UntypedInt:
-		return types.Types[TINT]
-	case types.UntypedRune:
-		return types.Runetype
-	case types.UntypedFloat:
-		return types.Types[TFLOAT64]
-	case types.UntypedComplex:
-		return types.Types[TCOMPLEX128]
-	}
-
-	Fatalf("bad type %v", t)
-	return nil
-}
-
-func smallintconst(n *Node) bool {
-	if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil {
-		switch simtype[n.Type.Etype] {
-		case TINT8,
-			TUINT8,
-			TINT16,
-			TUINT16,
-			TINT32,
-			TUINT32,
-			TBOOL:
-			return true
-
-		case TIDEAL, TINT64, TUINT64, TPTR:
-			v, ok := n.Val().U.(*Mpint)
-			if ok && v.Cmp(minintval[TINT32]) >= 0 && v.Cmp(maxintval[TINT32]) <= 0 {
-				return true
-			}
-		}
-	}
-
-	return false
-}
-
-// indexconst checks if Node n contains a constant expression
-// representable as a non-negative int and returns its value.
-// If n is not a constant expression, not representable as an
-// integer, or negative, it returns -1. If n is too large, it
-// returns -2.
-func indexconst(n *Node) int64 {
-	if n.Op != OLITERAL {
-		return -1
-	}
-
-	v := toint(n.Val()) // toint returns argument unchanged if not representable as an *Mpint
-	vi, ok := v.U.(*Mpint)
-	if !ok || vi.CmpInt64(0) < 0 {
-		return -1
-	}
-	if vi.Cmp(maxintval[TINT]) > 0 {
-		return -2
-	}
-
-	return vi.Int64()
-}
-
-// isGoConst reports whether n is a Go language constant (as opposed to a
-// compile-time constant).
-//
-// Expressions derived from nil, like string([]byte(nil)), while they
-// may be known at compile time, are not Go language constants.
-func (n *Node) isGoConst() bool {
-	return n.Op == OLITERAL && n.Val().Ctype() != CTNIL
-}
-
-func hascallchan(n *Node) bool {
-	if n == nil {
-		return false
-	}
-	switch n.Op {
-	case OAPPEND,
-		OCALL,
-		OCALLFUNC,
-		OCALLINTER,
-		OCALLMETH,
-		OCAP,
-		OCLOSE,
-		OCOMPLEX,
-		OCOPY,
-		ODELETE,
-		OIMAG,
-		OLEN,
-		OMAKE,
-		ONEW,
-		OPANIC,
-		OPRINT,
-		OPRINTN,
-		OREAL,
-		ORECOVER,
-		ORECV:
-		return true
-	}
-
-	if hascallchan(n.Left) || hascallchan(n.Right) {
-		return true
-	}
-	for _, n1 := range n.List.Slice() {
-		if hascallchan(n1) {
-			return true
-		}
-	}
-	for _, n2 := range n.Rlist.Slice() {
-		if hascallchan(n2) {
-			return true
-		}
-	}
-
-	return false
-}
-
-// A constSet represents a set of Go constant expressions.
-type constSet struct {
-	m map[constSetKey]src.XPos
-}
-
-type constSetKey struct {
-	typ *types.Type
-	val interface{}
-}
-
-// add adds constant expression n to s. If a constant expression of
-// equal value and identical type has already been added, then add
-// reports an error about the duplicate value.
-//
-// pos provides position information for where expression n occurred
-// (in case n does not have its own position information). what and
-// where are used in the error message.
-//
-// n must not be an untyped constant.
-func (s *constSet) add(pos src.XPos, n *Node, what, where string) {
-	if n.Op == OCONVIFACE && n.Implicit() {
-		n = n.Left
-	}
-
-	if !n.isGoConst() {
-		return
-	}
-	if n.Type.IsUntyped() {
-		Fatalf("%v is untyped", n)
-	}
-
-	// Consts are only duplicates if they have the same value and
-	// identical types.
-	//
-	// In general, we have to use types.Identical to test type
-	// identity, because == gives false negatives for anonymous
-	// types and the byte/uint8 and rune/int32 builtin type
-	// aliases.  However, this is not a problem here, because
-	// constant expressions are always untyped or have a named
-	// type, and we explicitly handle the builtin type aliases
-	// below.
-	//
-	// This approach may need to be revisited though if we fix
-	// #21866 by treating all type aliases like byte/uint8 and
-	// rune/int32.
-
-	typ := n.Type
-	switch typ {
-	case types.Bytetype:
-		typ = types.Types[TUINT8]
-	case types.Runetype:
-		typ = types.Types[TINT32]
-	}
-	k := constSetKey{typ, n.Val().Interface()}
-
-	if hasUniquePos(n) {
-		pos = n.Pos
-	}
-
-	if s.m == nil {
-		s.m = make(map[constSetKey]src.XPos)
-	}
-
-	if prevPos, isDup := s.m[k]; isDup {
-		yyerrorl(pos, "duplicate %s %s in %s\n\tprevious %s at %v",
-			what, nodeAndVal(n), where,
-			what, linestr(prevPos))
-	} else {
-		s.m[k] = pos
-	}
-}
-
-// nodeAndVal reports both an expression and its constant value, if
-// the latter is non-obvious.
-//
-// TODO(mdempsky): This could probably be a fmt.go flag.
-func nodeAndVal(n *Node) string {
-	show := n.String()
-	val := n.Val().Interface()
-	if s := fmt.Sprintf("%#v", val); show != s {
-		show += " (value " + s + ")"
-	}
-	return show
-}
diff --git a/src/cmd/compile/internal/gc/constFold_test.go b/src/cmd/compile/internal/gc/constFold_test.go
deleted file mode 100644
index 59f905d..0000000
--- a/src/cmd/compile/internal/gc/constFold_test.go
+++ /dev/null
@@ -1,18111 +0,0 @@
-// run
-// Code generated by gen/constFoldGen.go. DO NOT EDIT.
-
-package gc
-
-import "testing"
-
-func TestConstFolduint64add(t *testing.T) {
-	var x, y, r uint64
-	x = 0
-	y = 0
-	r = x + y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 1 {
-		t.Errorf("0 %s 1 = %d, want 1", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != 4294967296 {
-		t.Errorf("0 %s 4294967296 = %d, want 4294967296", "+", r)
-	}
-	y = 18446744073709551615
-	r = x + y
-	if r != 18446744073709551615 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 18446744073709551615", "+", r)
-	}
-	x = 1
-	y = 0
-	r = x + y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != 4294967297 {
-		t.Errorf("1 %s 4294967296 = %d, want 4294967297", "+", r)
-	}
-	y = 18446744073709551615
-	r = x + y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "+", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x + y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 4294967297 {
-		t.Errorf("4294967296 %s 1 = %d, want 4294967297", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != 8589934592 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 8589934592", "+", r)
-	}
-	y = 18446744073709551615
-	r = x + y
-	if r != 4294967295 {
-		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 4294967295", "+", r)
-	}
-	x = 18446744073709551615
-	y = 0
-	r = x + y
-	if r != 18446744073709551615 {
-		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 0", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != 4294967295 {
-		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 4294967295", "+", r)
-	}
-	y = 18446744073709551615
-	r = x + y
-	if r != 18446744073709551614 {
-		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 18446744073709551614", "+", r)
-	}
-}
-func TestConstFolduint64sub(t *testing.T) {
-	var x, y, r uint64
-	x = 0
-	y = 0
-	r = x - y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 18446744073709551615 {
-		t.Errorf("0 %s 1 = %d, want 18446744073709551615", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != 18446744069414584320 {
-		t.Errorf("0 %s 4294967296 = %d, want 18446744069414584320", "-", r)
-	}
-	y = 18446744073709551615
-	r = x - y
-	if r != 1 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 1", "-", r)
-	}
-	x = 1
-	y = 0
-	r = x - y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != 18446744069414584321 {
-		t.Errorf("1 %s 4294967296 = %d, want 18446744069414584321", "-", r)
-	}
-	y = 18446744073709551615
-	r = x - y
-	if r != 2 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 2", "-", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x - y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 4294967295 {
-		t.Errorf("4294967296 %s 1 = %d, want 4294967295", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "-", r)
-	}
-	y = 18446744073709551615
-	r = x - y
-	if r != 4294967297 {
-		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 4294967297", "-", r)
-	}
-	x = 18446744073709551615
-	y = 0
-	r = x - y
-	if r != 18446744073709551615 {
-		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 18446744073709551614 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551614", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != 18446744069414584319 {
-		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 18446744069414584319", "-", r)
-	}
-	y = 18446744073709551615
-	r = x - y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 0", "-", r)
-	}
-}
-func TestConstFolduint64div(t *testing.T) {
-	var x, y, r uint64
-	x = 0
-	y = 1
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "/", r)
-	}
-	y = 18446744073709551615
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "/", r)
-	}
-	x = 1
-	y = 1
-	r = x / y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", "/", r)
-	}
-	y = 18446744073709551615
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "/", r)
-	}
-	x = 4294967296
-	y = 1
-	r = x / y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 1 = %d, want 4294967296", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != 1 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 1", "/", r)
-	}
-	y = 18446744073709551615
-	r = x / y
-	if r != 0 {
-		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 0", "/", r)
-	}
-	x = 18446744073709551615
-	y = 1
-	r = x / y
-	if r != 18446744073709551615 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551615", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != 4294967295 {
-		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 4294967295", "/", r)
-	}
-	y = 18446744073709551615
-	r = x / y
-	if r != 1 {
-		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 1", "/", r)
-	}
-}
-func TestConstFolduint64mul(t *testing.T) {
-	var x, y, r uint64
-	x = 0
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "*", r)
-	}
-	y = 18446744073709551615
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "*", r)
-	}
-	x = 1
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("1 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != 4294967296 {
-		t.Errorf("1 %s 4294967296 = %d, want 4294967296", "*", r)
-	}
-	y = 18446744073709551615
-	r = x * y
-	if r != 18446744073709551615 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 18446744073709551615", "*", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("4294967296 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 1 = %d, want 4294967296", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "*", r)
-	}
-	y = 18446744073709551615
-	r = x * y
-	if r != 18446744069414584320 {
-		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 18446744069414584320", "*", r)
-	}
-	x = 18446744073709551615
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 18446744073709551615 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551615", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != 18446744069414584320 {
-		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 18446744069414584320", "*", r)
-	}
-	y = 18446744073709551615
-	r = x * y
-	if r != 1 {
-		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 1", "*", r)
-	}
-}
-func TestConstFolduint64mod(t *testing.T) {
-	var x, y, r uint64
-	x = 0
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "%", r)
-	}
-	y = 18446744073709551615
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "%", r)
-	}
-	x = 1
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 4294967296 = %d, want 1", "%", r)
-	}
-	y = 18446744073709551615
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 1", "%", r)
-	}
-	x = 4294967296
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("4294967296 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "%", r)
-	}
-	y = 18446744073709551615
-	r = x % y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 4294967296", "%", r)
-	}
-	x = 18446744073709551615
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != 4294967295 {
-		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 4294967295", "%", r)
-	}
-	y = 18446744073709551615
-	r = x % y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 0", "%", r)
-	}
-}
-func TestConstFoldint64add(t *testing.T) {
-	var x, y, r int64
-	x = -9223372036854775808
-	y = -9223372036854775808
-	r = x + y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s -9223372036854775808 = %d, want 0", "+", r)
-	}
-	y = -9223372036854775807
-	r = x + y
-	if r != 1 {
-		t.Errorf("-9223372036854775808 %s -9223372036854775807 = %d, want 1", "+", r)
-	}
-	y = -4294967296
-	r = x + y
-	if r != 9223372032559808512 {
-		t.Errorf("-9223372036854775808 %s -4294967296 = %d, want 9223372032559808512", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 9223372036854775807 {
-		t.Errorf("-9223372036854775808 %s -1 = %d, want 9223372036854775807", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want -9223372036854775807", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != -9223372032559808512 {
-		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want -9223372032559808512", "+", r)
-	}
-	y = 9223372036854775806
-	r = x + y
-	if r != -2 {
-		t.Errorf("-9223372036854775808 %s 9223372036854775806 = %d, want -2", "+", r)
-	}
-	y = 9223372036854775807
-	r = x + y
-	if r != -1 {
-		t.Errorf("-9223372036854775808 %s 9223372036854775807 = %d, want -1", "+", r)
-	}
-	x = -9223372036854775807
-	y = -9223372036854775808
-	r = x + y
-	if r != 1 {
-		t.Errorf("-9223372036854775807 %s -9223372036854775808 = %d, want 1", "+", r)
-	}
-	y = -9223372036854775807
-	r = x + y
-	if r != 2 {
-		t.Errorf("-9223372036854775807 %s -9223372036854775807 = %d, want 2", "+", r)
-	}
-	y = -4294967296
-	r = x + y
-	if r != 9223372032559808513 {
-		t.Errorf("-9223372036854775807 %s -4294967296 = %d, want 9223372032559808513", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775807 %s -1 = %d, want -9223372036854775808", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -9223372036854775806 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want -9223372036854775806", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != -9223372032559808511 {
-		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want -9223372032559808511", "+", r)
-	}
-	y = 9223372036854775806
-	r = x + y
-	if r != -1 {
-		t.Errorf("-9223372036854775807 %s 9223372036854775806 = %d, want -1", "+", r)
-	}
-	y = 9223372036854775807
-	r = x + y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s 9223372036854775807 = %d, want 0", "+", r)
-	}
-	x = -4294967296
-	y = -9223372036854775808
-	r = x + y
-	if r != 9223372032559808512 {
-		t.Errorf("-4294967296 %s -9223372036854775808 = %d, want 9223372032559808512", "+", r)
-	}
-	y = -9223372036854775807
-	r = x + y
-	if r != 9223372032559808513 {
-		t.Errorf("-4294967296 %s -9223372036854775807 = %d, want 9223372032559808513", "+", r)
-	}
-	y = -4294967296
-	r = x + y
-	if r != -8589934592 {
-		t.Errorf("-4294967296 %s -4294967296 = %d, want -8589934592", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -4294967297 {
-		t.Errorf("-4294967296 %s -1 = %d, want -4294967297", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -4294967295 {
-		t.Errorf("-4294967296 %s 1 = %d, want -4294967295", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != 0 {
-		t.Errorf("-4294967296 %s 4294967296 = %d, want 0", "+", r)
-	}
-	y = 9223372036854775806
-	r = x + y
-	if r != 9223372032559808510 {
-		t.Errorf("-4294967296 %s 9223372036854775806 = %d, want 9223372032559808510", "+", r)
-	}
-	y = 9223372036854775807
-	r = x + y
-	if r != 9223372032559808511 {
-		t.Errorf("-4294967296 %s 9223372036854775807 = %d, want 9223372032559808511", "+", r)
-	}
-	x = -1
-	y = -9223372036854775808
-	r = x + y
-	if r != 9223372036854775807 {
-		t.Errorf("-1 %s -9223372036854775808 = %d, want 9223372036854775807", "+", r)
-	}
-	y = -9223372036854775807
-	r = x + y
-	if r != -9223372036854775808 {
-		t.Errorf("-1 %s -9223372036854775807 = %d, want -9223372036854775808", "+", r)
-	}
-	y = -4294967296
-	r = x + y
-	if r != -4294967297 {
-		t.Errorf("-1 %s -4294967296 = %d, want -4294967297", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -2 {
-		t.Errorf("-1 %s -1 = %d, want -2", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 0 {
-		t.Errorf("-1 %s 1 = %d, want 0", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != 4294967295 {
-		t.Errorf("-1 %s 4294967296 = %d, want 4294967295", "+", r)
-	}
-	y = 9223372036854775806
-	r = x + y
-	if r != 9223372036854775805 {
-		t.Errorf("-1 %s 9223372036854775806 = %d, want 9223372036854775805", "+", r)
-	}
-	y = 9223372036854775807
-	r = x + y
-	if r != 9223372036854775806 {
-		t.Errorf("-1 %s 9223372036854775807 = %d, want 9223372036854775806", "+", r)
-	}
-	x = 0
-	y = -9223372036854775808
-	r = x + y
-	if r != -9223372036854775808 {
-		t.Errorf("0 %s -9223372036854775808 = %d, want -9223372036854775808", "+", r)
-	}
-	y = -9223372036854775807
-	r = x + y
-	if r != -9223372036854775807 {
-		t.Errorf("0 %s -9223372036854775807 = %d, want -9223372036854775807", "+", r)
-	}
-	y = -4294967296
-	r = x + y
-	if r != -4294967296 {
-		t.Errorf("0 %s -4294967296 = %d, want -4294967296", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -1 {
-		t.Errorf("0 %s -1 = %d, want -1", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 1 {
-		t.Errorf("0 %s 1 = %d, want 1", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != 4294967296 {
-		t.Errorf("0 %s 4294967296 = %d, want 4294967296", "+", r)
-	}
-	y = 9223372036854775806
-	r = x + y
-	if r != 9223372036854775806 {
-		t.Errorf("0 %s 9223372036854775806 = %d, want 9223372036854775806", "+", r)
-	}
-	y = 9223372036854775807
-	r = x + y
-	if r != 9223372036854775807 {
-		t.Errorf("0 %s 9223372036854775807 = %d, want 9223372036854775807", "+", r)
-	}
-	x = 1
-	y = -9223372036854775808
-	r = x + y
-	if r != -9223372036854775807 {
-		t.Errorf("1 %s -9223372036854775808 = %d, want -9223372036854775807", "+", r)
-	}
-	y = -9223372036854775807
-	r = x + y
-	if r != -9223372036854775806 {
-		t.Errorf("1 %s -9223372036854775807 = %d, want -9223372036854775806", "+", r)
-	}
-	y = -4294967296
-	r = x + y
-	if r != -4294967295 {
-		t.Errorf("1 %s -4294967296 = %d, want -4294967295", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 0 {
-		t.Errorf("1 %s -1 = %d, want 0", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != 4294967297 {
-		t.Errorf("1 %s 4294967296 = %d, want 4294967297", "+", r)
-	}
-	y = 9223372036854775806
-	r = x + y
-	if r != 9223372036854775807 {
-		t.Errorf("1 %s 9223372036854775806 = %d, want 9223372036854775807", "+", r)
-	}
-	y = 9223372036854775807
-	r = x + y
-	if r != -9223372036854775808 {
-		t.Errorf("1 %s 9223372036854775807 = %d, want -9223372036854775808", "+", r)
-	}
-	x = 4294967296
-	y = -9223372036854775808
-	r = x + y
-	if r != -9223372032559808512 {
-		t.Errorf("4294967296 %s -9223372036854775808 = %d, want -9223372032559808512", "+", r)
-	}
-	y = -9223372036854775807
-	r = x + y
-	if r != -9223372032559808511 {
-		t.Errorf("4294967296 %s -9223372036854775807 = %d, want -9223372032559808511", "+", r)
-	}
-	y = -4294967296
-	r = x + y
-	if r != 0 {
-		t.Errorf("4294967296 %s -4294967296 = %d, want 0", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 4294967295 {
-		t.Errorf("4294967296 %s -1 = %d, want 4294967295", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 4294967297 {
-		t.Errorf("4294967296 %s 1 = %d, want 4294967297", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != 8589934592 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 8589934592", "+", r)
-	}
-	y = 9223372036854775806
-	r = x + y
-	if r != -9223372032559808514 {
-		t.Errorf("4294967296 %s 9223372036854775806 = %d, want -9223372032559808514", "+", r)
-	}
-	y = 9223372036854775807
-	r = x + y
-	if r != -9223372032559808513 {
-		t.Errorf("4294967296 %s 9223372036854775807 = %d, want -9223372032559808513", "+", r)
-	}
-	x = 9223372036854775806
-	y = -9223372036854775808
-	r = x + y
-	if r != -2 {
-		t.Errorf("9223372036854775806 %s -9223372036854775808 = %d, want -2", "+", r)
-	}
-	y = -9223372036854775807
-	r = x + y
-	if r != -1 {
-		t.Errorf("9223372036854775806 %s -9223372036854775807 = %d, want -1", "+", r)
-	}
-	y = -4294967296
-	r = x + y
-	if r != 9223372032559808510 {
-		t.Errorf("9223372036854775806 %s -4294967296 = %d, want 9223372032559808510", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 9223372036854775805 {
-		t.Errorf("9223372036854775806 %s -1 = %d, want 9223372036854775805", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want 9223372036854775807", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != -9223372032559808514 {
-		t.Errorf("9223372036854775806 %s 4294967296 = %d, want -9223372032559808514", "+", r)
-	}
-	y = 9223372036854775806
-	r = x + y
-	if r != -4 {
-		t.Errorf("9223372036854775806 %s 9223372036854775806 = %d, want -4", "+", r)
-	}
-	y = 9223372036854775807
-	r = x + y
-	if r != -3 {
-		t.Errorf("9223372036854775806 %s 9223372036854775807 = %d, want -3", "+", r)
-	}
-	x = 9223372036854775807
-	y = -9223372036854775808
-	r = x + y
-	if r != -1 {
-		t.Errorf("9223372036854775807 %s -9223372036854775808 = %d, want -1", "+", r)
-	}
-	y = -9223372036854775807
-	r = x + y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s -9223372036854775807 = %d, want 0", "+", r)
-	}
-	y = -4294967296
-	r = x + y
-	if r != 9223372032559808511 {
-		t.Errorf("9223372036854775807 %s -4294967296 = %d, want 9223372032559808511", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775807 %s -1 = %d, want 9223372036854775806", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -9223372036854775808 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want -9223372036854775808", "+", r)
-	}
-	y = 4294967296
-	r = x + y
-	if r != -9223372032559808513 {
-		t.Errorf("9223372036854775807 %s 4294967296 = %d, want -9223372032559808513", "+", r)
-	}
-	y = 9223372036854775806
-	r = x + y
-	if r != -3 {
-		t.Errorf("9223372036854775807 %s 9223372036854775806 = %d, want -3", "+", r)
-	}
-	y = 9223372036854775807
-	r = x + y
-	if r != -2 {
-		t.Errorf("9223372036854775807 %s 9223372036854775807 = %d, want -2", "+", r)
-	}
-}
-func TestConstFoldint64sub(t *testing.T) {
-	var x, y, r int64
-	x = -9223372036854775808
-	y = -9223372036854775808
-	r = x - y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s -9223372036854775808 = %d, want 0", "-", r)
-	}
-	y = -9223372036854775807
-	r = x - y
-	if r != -1 {
-		t.Errorf("-9223372036854775808 %s -9223372036854775807 = %d, want -1", "-", r)
-	}
-	y = -4294967296
-	r = x - y
-	if r != -9223372032559808512 {
-		t.Errorf("-9223372036854775808 %s -4294967296 = %d, want -9223372032559808512", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775808 %s -1 = %d, want -9223372036854775807", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 9223372036854775807 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want 9223372036854775807", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != 9223372032559808512 {
-		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want 9223372032559808512", "-", r)
-	}
-	y = 9223372036854775806
-	r = x - y
-	if r != 2 {
-		t.Errorf("-9223372036854775808 %s 9223372036854775806 = %d, want 2", "-", r)
-	}
-	y = 9223372036854775807
-	r = x - y
-	if r != 1 {
-		t.Errorf("-9223372036854775808 %s 9223372036854775807 = %d, want 1", "-", r)
-	}
-	x = -9223372036854775807
-	y = -9223372036854775808
-	r = x - y
-	if r != 1 {
-		t.Errorf("-9223372036854775807 %s -9223372036854775808 = %d, want 1", "-", r)
-	}
-	y = -9223372036854775807
-	r = x - y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s -9223372036854775807 = %d, want 0", "-", r)
-	}
-	y = -4294967296
-	r = x - y
-	if r != -9223372032559808511 {
-		t.Errorf("-9223372036854775807 %s -4294967296 = %d, want -9223372032559808511", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -9223372036854775806 {
-		t.Errorf("-9223372036854775807 %s -1 = %d, want -9223372036854775806", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want -9223372036854775808", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != 9223372032559808513 {
-		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want 9223372032559808513", "-", r)
-	}
-	y = 9223372036854775806
-	r = x - y
-	if r != 3 {
-		t.Errorf("-9223372036854775807 %s 9223372036854775806 = %d, want 3", "-", r)
-	}
-	y = 9223372036854775807
-	r = x - y
-	if r != 2 {
-		t.Errorf("-9223372036854775807 %s 9223372036854775807 = %d, want 2", "-", r)
-	}
-	x = -4294967296
-	y = -9223372036854775808
-	r = x - y
-	if r != 9223372032559808512 {
-		t.Errorf("-4294967296 %s -9223372036854775808 = %d, want 9223372032559808512", "-", r)
-	}
-	y = -9223372036854775807
-	r = x - y
-	if r != 9223372032559808511 {
-		t.Errorf("-4294967296 %s -9223372036854775807 = %d, want 9223372032559808511", "-", r)
-	}
-	y = -4294967296
-	r = x - y
-	if r != 0 {
-		t.Errorf("-4294967296 %s -4294967296 = %d, want 0", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -4294967295 {
-		t.Errorf("-4294967296 %s -1 = %d, want -4294967295", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -4294967297 {
-		t.Errorf("-4294967296 %s 1 = %d, want -4294967297", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != -8589934592 {
-		t.Errorf("-4294967296 %s 4294967296 = %d, want -8589934592", "-", r)
-	}
-	y = 9223372036854775806
-	r = x - y
-	if r != 9223372032559808514 {
-		t.Errorf("-4294967296 %s 9223372036854775806 = %d, want 9223372032559808514", "-", r)
-	}
-	y = 9223372036854775807
-	r = x - y
-	if r != 9223372032559808513 {
-		t.Errorf("-4294967296 %s 9223372036854775807 = %d, want 9223372032559808513", "-", r)
-	}
-	x = -1
-	y = -9223372036854775808
-	r = x - y
-	if r != 9223372036854775807 {
-		t.Errorf("-1 %s -9223372036854775808 = %d, want 9223372036854775807", "-", r)
-	}
-	y = -9223372036854775807
-	r = x - y
-	if r != 9223372036854775806 {
-		t.Errorf("-1 %s -9223372036854775807 = %d, want 9223372036854775806", "-", r)
-	}
-	y = -4294967296
-	r = x - y
-	if r != 4294967295 {
-		t.Errorf("-1 %s -4294967296 = %d, want 4294967295", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 0 {
-		t.Errorf("-1 %s -1 = %d, want 0", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != -4294967297 {
-		t.Errorf("-1 %s 4294967296 = %d, want -4294967297", "-", r)
-	}
-	y = 9223372036854775806
-	r = x - y
-	if r != -9223372036854775807 {
-		t.Errorf("-1 %s 9223372036854775806 = %d, want -9223372036854775807", "-", r)
-	}
-	y = 9223372036854775807
-	r = x - y
-	if r != -9223372036854775808 {
-		t.Errorf("-1 %s 9223372036854775807 = %d, want -9223372036854775808", "-", r)
-	}
-	x = 0
-	y = -9223372036854775808
-	r = x - y
-	if r != -9223372036854775808 {
-		t.Errorf("0 %s -9223372036854775808 = %d, want -9223372036854775808", "-", r)
-	}
-	y = -9223372036854775807
-	r = x - y
-	if r != 9223372036854775807 {
-		t.Errorf("0 %s -9223372036854775807 = %d, want 9223372036854775807", "-", r)
-	}
-	y = -4294967296
-	r = x - y
-	if r != 4294967296 {
-		t.Errorf("0 %s -4294967296 = %d, want 4294967296", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 1 {
-		t.Errorf("0 %s -1 = %d, want 1", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -1 {
-		t.Errorf("0 %s 1 = %d, want -1", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != -4294967296 {
-		t.Errorf("0 %s 4294967296 = %d, want -4294967296", "-", r)
-	}
-	y = 9223372036854775806
-	r = x - y
-	if r != -9223372036854775806 {
-		t.Errorf("0 %s 9223372036854775806 = %d, want -9223372036854775806", "-", r)
-	}
-	y = 9223372036854775807
-	r = x - y
-	if r != -9223372036854775807 {
-		t.Errorf("0 %s 9223372036854775807 = %d, want -9223372036854775807", "-", r)
-	}
-	x = 1
-	y = -9223372036854775808
-	r = x - y
-	if r != -9223372036854775807 {
-		t.Errorf("1 %s -9223372036854775808 = %d, want -9223372036854775807", "-", r)
-	}
-	y = -9223372036854775807
-	r = x - y
-	if r != -9223372036854775808 {
-		t.Errorf("1 %s -9223372036854775807 = %d, want -9223372036854775808", "-", r)
-	}
-	y = -4294967296
-	r = x - y
-	if r != 4294967297 {
-		t.Errorf("1 %s -4294967296 = %d, want 4294967297", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 2 {
-		t.Errorf("1 %s -1 = %d, want 2", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != -4294967295 {
-		t.Errorf("1 %s 4294967296 = %d, want -4294967295", "-", r)
-	}
-	y = 9223372036854775806
-	r = x - y
-	if r != -9223372036854775805 {
-		t.Errorf("1 %s 9223372036854775806 = %d, want -9223372036854775805", "-", r)
-	}
-	y = 9223372036854775807
-	r = x - y
-	if r != -9223372036854775806 {
-		t.Errorf("1 %s 9223372036854775807 = %d, want -9223372036854775806", "-", r)
-	}
-	x = 4294967296
-	y = -9223372036854775808
-	r = x - y
-	if r != -9223372032559808512 {
-		t.Errorf("4294967296 %s -9223372036854775808 = %d, want -9223372032559808512", "-", r)
-	}
-	y = -9223372036854775807
-	r = x - y
-	if r != -9223372032559808513 {
-		t.Errorf("4294967296 %s -9223372036854775807 = %d, want -9223372032559808513", "-", r)
-	}
-	y = -4294967296
-	r = x - y
-	if r != 8589934592 {
-		t.Errorf("4294967296 %s -4294967296 = %d, want 8589934592", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 4294967297 {
-		t.Errorf("4294967296 %s -1 = %d, want 4294967297", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 4294967295 {
-		t.Errorf("4294967296 %s 1 = %d, want 4294967295", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "-", r)
-	}
-	y = 9223372036854775806
-	r = x - y
-	if r != -9223372032559808510 {
-		t.Errorf("4294967296 %s 9223372036854775806 = %d, want -9223372032559808510", "-", r)
-	}
-	y = 9223372036854775807
-	r = x - y
-	if r != -9223372032559808511 {
-		t.Errorf("4294967296 %s 9223372036854775807 = %d, want -9223372032559808511", "-", r)
-	}
-	x = 9223372036854775806
-	y = -9223372036854775808
-	r = x - y
-	if r != -2 {
-		t.Errorf("9223372036854775806 %s -9223372036854775808 = %d, want -2", "-", r)
-	}
-	y = -9223372036854775807
-	r = x - y
-	if r != -3 {
-		t.Errorf("9223372036854775806 %s -9223372036854775807 = %d, want -3", "-", r)
-	}
-	y = -4294967296
-	r = x - y
-	if r != -9223372032559808514 {
-		t.Errorf("9223372036854775806 %s -4294967296 = %d, want -9223372032559808514", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775806 %s -1 = %d, want 9223372036854775807", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 9223372036854775805 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want 9223372036854775805", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != 9223372032559808510 {
-		t.Errorf("9223372036854775806 %s 4294967296 = %d, want 9223372032559808510", "-", r)
-	}
-	y = 9223372036854775806
-	r = x - y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 9223372036854775806 = %d, want 0", "-", r)
-	}
-	y = 9223372036854775807
-	r = x - y
-	if r != -1 {
-		t.Errorf("9223372036854775806 %s 9223372036854775807 = %d, want -1", "-", r)
-	}
-	x = 9223372036854775807
-	y = -9223372036854775808
-	r = x - y
-	if r != -1 {
-		t.Errorf("9223372036854775807 %s -9223372036854775808 = %d, want -1", "-", r)
-	}
-	y = -9223372036854775807
-	r = x - y
-	if r != -2 {
-		t.Errorf("9223372036854775807 %s -9223372036854775807 = %d, want -2", "-", r)
-	}
-	y = -4294967296
-	r = x - y
-	if r != -9223372032559808513 {
-		t.Errorf("9223372036854775807 %s -4294967296 = %d, want -9223372032559808513", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -9223372036854775808 {
-		t.Errorf("9223372036854775807 %s -1 = %d, want -9223372036854775808", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want 9223372036854775806", "-", r)
-	}
-	y = 4294967296
-	r = x - y
-	if r != 9223372032559808511 {
-		t.Errorf("9223372036854775807 %s 4294967296 = %d, want 9223372032559808511", "-", r)
-	}
-	y = 9223372036854775806
-	r = x - y
-	if r != 1 {
-		t.Errorf("9223372036854775807 %s 9223372036854775806 = %d, want 1", "-", r)
-	}
-	y = 9223372036854775807
-	r = x - y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 9223372036854775807 = %d, want 0", "-", r)
-	}
-}
-func TestConstFoldint64div(t *testing.T) {
-	var x, y, r int64
-	x = -9223372036854775808
-	y = -9223372036854775808
-	r = x / y
-	if r != 1 {
-		t.Errorf("-9223372036854775808 %s -9223372036854775808 = %d, want 1", "/", r)
-	}
-	y = -9223372036854775807
-	r = x / y
-	if r != 1 {
-		t.Errorf("-9223372036854775808 %s -9223372036854775807 = %d, want 1", "/", r)
-	}
-	y = -4294967296
-	r = x / y
-	if r != 2147483648 {
-		t.Errorf("-9223372036854775808 %s -4294967296 = %d, want 2147483648", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s -1 = %d, want -9223372036854775808", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want -9223372036854775808", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != -2147483648 {
-		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want -2147483648", "/", r)
-	}
-	y = 9223372036854775806
-	r = x / y
-	if r != -1 {
-		t.Errorf("-9223372036854775808 %s 9223372036854775806 = %d, want -1", "/", r)
-	}
-	y = 9223372036854775807
-	r = x / y
-	if r != -1 {
-		t.Errorf("-9223372036854775808 %s 9223372036854775807 = %d, want -1", "/", r)
-	}
-	x = -9223372036854775807
-	y = -9223372036854775808
-	r = x / y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s -9223372036854775808 = %d, want 0", "/", r)
-	}
-	y = -9223372036854775807
-	r = x / y
-	if r != 1 {
-		t.Errorf("-9223372036854775807 %s -9223372036854775807 = %d, want 1", "/", r)
-	}
-	y = -4294967296
-	r = x / y
-	if r != 2147483647 {
-		t.Errorf("-9223372036854775807 %s -4294967296 = %d, want 2147483647", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s -1 = %d, want 9223372036854775807", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want -9223372036854775807", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != -2147483647 {
-		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want -2147483647", "/", r)
-	}
-	y = 9223372036854775806
-	r = x / y
-	if r != -1 {
-		t.Errorf("-9223372036854775807 %s 9223372036854775806 = %d, want -1", "/", r)
-	}
-	y = 9223372036854775807
-	r = x / y
-	if r != -1 {
-		t.Errorf("-9223372036854775807 %s 9223372036854775807 = %d, want -1", "/", r)
-	}
-	x = -4294967296
-	y = -9223372036854775808
-	r = x / y
-	if r != 0 {
-		t.Errorf("-4294967296 %s -9223372036854775808 = %d, want 0", "/", r)
-	}
-	y = -9223372036854775807
-	r = x / y
-	if r != 0 {
-		t.Errorf("-4294967296 %s -9223372036854775807 = %d, want 0", "/", r)
-	}
-	y = -4294967296
-	r = x / y
-	if r != 1 {
-		t.Errorf("-4294967296 %s -4294967296 = %d, want 1", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 4294967296 {
-		t.Errorf("-4294967296 %s -1 = %d, want 4294967296", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 1 = %d, want -4294967296", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != -1 {
-		t.Errorf("-4294967296 %s 4294967296 = %d, want -1", "/", r)
-	}
-	y = 9223372036854775806
-	r = x / y
-	if r != 0 {
-		t.Errorf("-4294967296 %s 9223372036854775806 = %d, want 0", "/", r)
-	}
-	y = 9223372036854775807
-	r = x / y
-	if r != 0 {
-		t.Errorf("-4294967296 %s 9223372036854775807 = %d, want 0", "/", r)
-	}
-	x = -1
-	y = -9223372036854775808
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s -9223372036854775808 = %d, want 0", "/", r)
-	}
-	y = -9223372036854775807
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s -9223372036854775807 = %d, want 0", "/", r)
-	}
-	y = -4294967296
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s -4294967296 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 1 {
-		t.Errorf("-1 %s -1 = %d, want 1", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s 4294967296 = %d, want 0", "/", r)
-	}
-	y = 9223372036854775806
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s 9223372036854775806 = %d, want 0", "/", r)
-	}
-	y = 9223372036854775807
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s 9223372036854775807 = %d, want 0", "/", r)
-	}
-	x = 0
-	y = -9223372036854775808
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -9223372036854775808 = %d, want 0", "/", r)
-	}
-	y = -9223372036854775807
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -9223372036854775807 = %d, want 0", "/", r)
-	}
-	y = -4294967296
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -4294967296 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -1 = %d, want 0", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "/", r)
-	}
-	y = 9223372036854775806
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 9223372036854775806 = %d, want 0", "/", r)
-	}
-	y = 9223372036854775807
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 9223372036854775807 = %d, want 0", "/", r)
-	}
-	x = 1
-	y = -9223372036854775808
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s -9223372036854775808 = %d, want 0", "/", r)
-	}
-	y = -9223372036854775807
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s -9223372036854775807 = %d, want 0", "/", r)
-	}
-	y = -4294967296
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s -4294967296 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -1 {
-		t.Errorf("1 %s -1 = %d, want -1", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", "/", r)
-	}
-	y = 9223372036854775806
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 9223372036854775806 = %d, want 0", "/", r)
-	}
-	y = 9223372036854775807
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 9223372036854775807 = %d, want 0", "/", r)
-	}
-	x = 4294967296
-	y = -9223372036854775808
-	r = x / y
-	if r != 0 {
-		t.Errorf("4294967296 %s -9223372036854775808 = %d, want 0", "/", r)
-	}
-	y = -9223372036854775807
-	r = x / y
-	if r != 0 {
-		t.Errorf("4294967296 %s -9223372036854775807 = %d, want 0", "/", r)
-	}
-	y = -4294967296
-	r = x / y
-	if r != -1 {
-		t.Errorf("4294967296 %s -4294967296 = %d, want -1", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -4294967296 {
-		t.Errorf("4294967296 %s -1 = %d, want -4294967296", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 1 = %d, want 4294967296", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != 1 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 1", "/", r)
-	}
-	y = 9223372036854775806
-	r = x / y
-	if r != 0 {
-		t.Errorf("4294967296 %s 9223372036854775806 = %d, want 0", "/", r)
-	}
-	y = 9223372036854775807
-	r = x / y
-	if r != 0 {
-		t.Errorf("4294967296 %s 9223372036854775807 = %d, want 0", "/", r)
-	}
-	x = 9223372036854775806
-	y = -9223372036854775808
-	r = x / y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s -9223372036854775808 = %d, want 0", "/", r)
-	}
-	y = -9223372036854775807
-	r = x / y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s -9223372036854775807 = %d, want 0", "/", r)
-	}
-	y = -4294967296
-	r = x / y
-	if r != -2147483647 {
-		t.Errorf("9223372036854775806 %s -4294967296 = %d, want -2147483647", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -9223372036854775806 {
-		t.Errorf("9223372036854775806 %s -1 = %d, want -9223372036854775806", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want 9223372036854775806", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != 2147483647 {
-		t.Errorf("9223372036854775806 %s 4294967296 = %d, want 2147483647", "/", r)
-	}
-	y = 9223372036854775806
-	r = x / y
-	if r != 1 {
-		t.Errorf("9223372036854775806 %s 9223372036854775806 = %d, want 1", "/", r)
-	}
-	y = 9223372036854775807
-	r = x / y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 9223372036854775807 = %d, want 0", "/", r)
-	}
-	x = 9223372036854775807
-	y = -9223372036854775808
-	r = x / y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s -9223372036854775808 = %d, want 0", "/", r)
-	}
-	y = -9223372036854775807
-	r = x / y
-	if r != -1 {
-		t.Errorf("9223372036854775807 %s -9223372036854775807 = %d, want -1", "/", r)
-	}
-	y = -4294967296
-	r = x / y
-	if r != -2147483647 {
-		t.Errorf("9223372036854775807 %s -4294967296 = %d, want -2147483647", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -9223372036854775807 {
-		t.Errorf("9223372036854775807 %s -1 = %d, want -9223372036854775807", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want 9223372036854775807", "/", r)
-	}
-	y = 4294967296
-	r = x / y
-	if r != 2147483647 {
-		t.Errorf("9223372036854775807 %s 4294967296 = %d, want 2147483647", "/", r)
-	}
-	y = 9223372036854775806
-	r = x / y
-	if r != 1 {
-		t.Errorf("9223372036854775807 %s 9223372036854775806 = %d, want 1", "/", r)
-	}
-	y = 9223372036854775807
-	r = x / y
-	if r != 1 {
-		t.Errorf("9223372036854775807 %s 9223372036854775807 = %d, want 1", "/", r)
-	}
-}
-func TestConstFoldint64mul(t *testing.T) {
-	var x, y, r int64
-	x = -9223372036854775808
-	y = -9223372036854775808
-	r = x * y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s -9223372036854775808 = %d, want 0", "*", r)
-	}
-	y = -9223372036854775807
-	r = x * y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s -9223372036854775807 = %d, want -9223372036854775808", "*", r)
-	}
-	y = -4294967296
-	r = x * y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s -4294967296 = %d, want 0", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s -1 = %d, want -9223372036854775808", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want -9223372036854775808", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want 0", "*", r)
-	}
-	y = 9223372036854775806
-	r = x * y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 9223372036854775806 = %d, want 0", "*", r)
-	}
-	y = 9223372036854775807
-	r = x * y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 9223372036854775807 = %d, want -9223372036854775808", "*", r)
-	}
-	x = -9223372036854775807
-	y = -9223372036854775808
-	r = x * y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775807 %s -9223372036854775808 = %d, want -9223372036854775808", "*", r)
-	}
-	y = -9223372036854775807
-	r = x * y
-	if r != 1 {
-		t.Errorf("-9223372036854775807 %s -9223372036854775807 = %d, want 1", "*", r)
-	}
-	y = -4294967296
-	r = x * y
-	if r != -4294967296 {
-		t.Errorf("-9223372036854775807 %s -4294967296 = %d, want -4294967296", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s -1 = %d, want 9223372036854775807", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want -9223372036854775807", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != 4294967296 {
-		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want 4294967296", "*", r)
-	}
-	y = 9223372036854775806
-	r = x * y
-	if r != 9223372036854775806 {
-		t.Errorf("-9223372036854775807 %s 9223372036854775806 = %d, want 9223372036854775806", "*", r)
-	}
-	y = 9223372036854775807
-	r = x * y
-	if r != -1 {
-		t.Errorf("-9223372036854775807 %s 9223372036854775807 = %d, want -1", "*", r)
-	}
-	x = -4294967296
-	y = -9223372036854775808
-	r = x * y
-	if r != 0 {
-		t.Errorf("-4294967296 %s -9223372036854775808 = %d, want 0", "*", r)
-	}
-	y = -9223372036854775807
-	r = x * y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s -9223372036854775807 = %d, want -4294967296", "*", r)
-	}
-	y = -4294967296
-	r = x * y
-	if r != 0 {
-		t.Errorf("-4294967296 %s -4294967296 = %d, want 0", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 4294967296 {
-		t.Errorf("-4294967296 %s -1 = %d, want 4294967296", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-4294967296 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 1 = %d, want -4294967296", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != 0 {
-		t.Errorf("-4294967296 %s 4294967296 = %d, want 0", "*", r)
-	}
-	y = 9223372036854775806
-	r = x * y
-	if r != 8589934592 {
-		t.Errorf("-4294967296 %s 9223372036854775806 = %d, want 8589934592", "*", r)
-	}
-	y = 9223372036854775807
-	r = x * y
-	if r != 4294967296 {
-		t.Errorf("-4294967296 %s 9223372036854775807 = %d, want 4294967296", "*", r)
-	}
-	x = -1
-	y = -9223372036854775808
-	r = x * y
-	if r != -9223372036854775808 {
-		t.Errorf("-1 %s -9223372036854775808 = %d, want -9223372036854775808", "*", r)
-	}
-	y = -9223372036854775807
-	r = x * y
-	if r != 9223372036854775807 {
-		t.Errorf("-1 %s -9223372036854775807 = %d, want 9223372036854775807", "*", r)
-	}
-	y = -4294967296
-	r = x * y
-	if r != 4294967296 {
-		t.Errorf("-1 %s -4294967296 = %d, want 4294967296", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 1 {
-		t.Errorf("-1 %s -1 = %d, want 1", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-1 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != -4294967296 {
-		t.Errorf("-1 %s 4294967296 = %d, want -4294967296", "*", r)
-	}
-	y = 9223372036854775806
-	r = x * y
-	if r != -9223372036854775806 {
-		t.Errorf("-1 %s 9223372036854775806 = %d, want -9223372036854775806", "*", r)
-	}
-	y = 9223372036854775807
-	r = x * y
-	if r != -9223372036854775807 {
-		t.Errorf("-1 %s 9223372036854775807 = %d, want -9223372036854775807", "*", r)
-	}
-	x = 0
-	y = -9223372036854775808
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -9223372036854775808 = %d, want 0", "*", r)
-	}
-	y = -9223372036854775807
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -9223372036854775807 = %d, want 0", "*", r)
-	}
-	y = -4294967296
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -4294967296 = %d, want 0", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -1 = %d, want 0", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "*", r)
-	}
-	y = 9223372036854775806
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 9223372036854775806 = %d, want 0", "*", r)
-	}
-	y = 9223372036854775807
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 9223372036854775807 = %d, want 0", "*", r)
-	}
-	x = 1
-	y = -9223372036854775808
-	r = x * y
-	if r != -9223372036854775808 {
-		t.Errorf("1 %s -9223372036854775808 = %d, want -9223372036854775808", "*", r)
-	}
-	y = -9223372036854775807
-	r = x * y
-	if r != -9223372036854775807 {
-		t.Errorf("1 %s -9223372036854775807 = %d, want -9223372036854775807", "*", r)
-	}
-	y = -4294967296
-	r = x * y
-	if r != -4294967296 {
-		t.Errorf("1 %s -4294967296 = %d, want -4294967296", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -1 {
-		t.Errorf("1 %s -1 = %d, want -1", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("1 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != 4294967296 {
-		t.Errorf("1 %s 4294967296 = %d, want 4294967296", "*", r)
-	}
-	y = 9223372036854775806
-	r = x * y
-	if r != 9223372036854775806 {
-		t.Errorf("1 %s 9223372036854775806 = %d, want 9223372036854775806", "*", r)
-	}
-	y = 9223372036854775807
-	r = x * y
-	if r != 9223372036854775807 {
-		t.Errorf("1 %s 9223372036854775807 = %d, want 9223372036854775807", "*", r)
-	}
-	x = 4294967296
-	y = -9223372036854775808
-	r = x * y
-	if r != 0 {
-		t.Errorf("4294967296 %s -9223372036854775808 = %d, want 0", "*", r)
-	}
-	y = -9223372036854775807
-	r = x * y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s -9223372036854775807 = %d, want 4294967296", "*", r)
-	}
-	y = -4294967296
-	r = x * y
-	if r != 0 {
-		t.Errorf("4294967296 %s -4294967296 = %d, want 0", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -4294967296 {
-		t.Errorf("4294967296 %s -1 = %d, want -4294967296", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("4294967296 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 1 = %d, want 4294967296", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "*", r)
-	}
-	y = 9223372036854775806
-	r = x * y
-	if r != -8589934592 {
-		t.Errorf("4294967296 %s 9223372036854775806 = %d, want -8589934592", "*", r)
-	}
-	y = 9223372036854775807
-	r = x * y
-	if r != -4294967296 {
-		t.Errorf("4294967296 %s 9223372036854775807 = %d, want -4294967296", "*", r)
-	}
-	x = 9223372036854775806
-	y = -9223372036854775808
-	r = x * y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s -9223372036854775808 = %d, want 0", "*", r)
-	}
-	y = -9223372036854775807
-	r = x * y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s -9223372036854775807 = %d, want 9223372036854775806", "*", r)
-	}
-	y = -4294967296
-	r = x * y
-	if r != 8589934592 {
-		t.Errorf("9223372036854775806 %s -4294967296 = %d, want 8589934592", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -9223372036854775806 {
-		t.Errorf("9223372036854775806 %s -1 = %d, want -9223372036854775806", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want 9223372036854775806", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != -8589934592 {
-		t.Errorf("9223372036854775806 %s 4294967296 = %d, want -8589934592", "*", r)
-	}
-	y = 9223372036854775806
-	r = x * y
-	if r != 4 {
-		t.Errorf("9223372036854775806 %s 9223372036854775806 = %d, want 4", "*", r)
-	}
-	y = 9223372036854775807
-	r = x * y
-	if r != -9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 9223372036854775807 = %d, want -9223372036854775806", "*", r)
-	}
-	x = 9223372036854775807
-	y = -9223372036854775808
-	r = x * y
-	if r != -9223372036854775808 {
-		t.Errorf("9223372036854775807 %s -9223372036854775808 = %d, want -9223372036854775808", "*", r)
-	}
-	y = -9223372036854775807
-	r = x * y
-	if r != -1 {
-		t.Errorf("9223372036854775807 %s -9223372036854775807 = %d, want -1", "*", r)
-	}
-	y = -4294967296
-	r = x * y
-	if r != 4294967296 {
-		t.Errorf("9223372036854775807 %s -4294967296 = %d, want 4294967296", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -9223372036854775807 {
-		t.Errorf("9223372036854775807 %s -1 = %d, want -9223372036854775807", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want 9223372036854775807", "*", r)
-	}
-	y = 4294967296
-	r = x * y
-	if r != -4294967296 {
-		t.Errorf("9223372036854775807 %s 4294967296 = %d, want -4294967296", "*", r)
-	}
-	y = 9223372036854775806
-	r = x * y
-	if r != -9223372036854775806 {
-		t.Errorf("9223372036854775807 %s 9223372036854775806 = %d, want -9223372036854775806", "*", r)
-	}
-	y = 9223372036854775807
-	r = x * y
-	if r != 1 {
-		t.Errorf("9223372036854775807 %s 9223372036854775807 = %d, want 1", "*", r)
-	}
-}
-func TestConstFoldint64mod(t *testing.T) {
-	var x, y, r int64
-	x = -9223372036854775808
-	y = -9223372036854775808
-	r = x % y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s -9223372036854775808 = %d, want 0", "%", r)
-	}
-	y = -9223372036854775807
-	r = x % y
-	if r != -1 {
-		t.Errorf("-9223372036854775808 %s -9223372036854775807 = %d, want -1", "%", r)
-	}
-	y = -4294967296
-	r = x % y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s -4294967296 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want 0", "%", r)
-	}
-	y = 9223372036854775806
-	r = x % y
-	if r != -2 {
-		t.Errorf("-9223372036854775808 %s 9223372036854775806 = %d, want -2", "%", r)
-	}
-	y = 9223372036854775807
-	r = x % y
-	if r != -1 {
-		t.Errorf("-9223372036854775808 %s 9223372036854775807 = %d, want -1", "%", r)
-	}
-	x = -9223372036854775807
-	y = -9223372036854775808
-	r = x % y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s -9223372036854775808 = %d, want -9223372036854775807", "%", r)
-	}
-	y = -9223372036854775807
-	r = x % y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s -9223372036854775807 = %d, want 0", "%", r)
-	}
-	y = -4294967296
-	r = x % y
-	if r != -4294967295 {
-		t.Errorf("-9223372036854775807 %s -4294967296 = %d, want -4294967295", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != -4294967295 {
-		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want -4294967295", "%", r)
-	}
-	y = 9223372036854775806
-	r = x % y
-	if r != -1 {
-		t.Errorf("-9223372036854775807 %s 9223372036854775806 = %d, want -1", "%", r)
-	}
-	y = 9223372036854775807
-	r = x % y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s 9223372036854775807 = %d, want 0", "%", r)
-	}
-	x = -4294967296
-	y = -9223372036854775808
-	r = x % y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s -9223372036854775808 = %d, want -4294967296", "%", r)
-	}
-	y = -9223372036854775807
-	r = x % y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s -9223372036854775807 = %d, want -4294967296", "%", r)
-	}
-	y = -4294967296
-	r = x % y
-	if r != 0 {
-		t.Errorf("-4294967296 %s -4294967296 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-4294967296 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-4294967296 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != 0 {
-		t.Errorf("-4294967296 %s 4294967296 = %d, want 0", "%", r)
-	}
-	y = 9223372036854775806
-	r = x % y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 9223372036854775806 = %d, want -4294967296", "%", r)
-	}
-	y = 9223372036854775807
-	r = x % y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 9223372036854775807 = %d, want -4294967296", "%", r)
-	}
-	x = -1
-	y = -9223372036854775808
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s -9223372036854775808 = %d, want -1", "%", r)
-	}
-	y = -9223372036854775807
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s -9223372036854775807 = %d, want -1", "%", r)
-	}
-	y = -4294967296
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s -4294967296 = %d, want -1", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-1 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-1 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s 4294967296 = %d, want -1", "%", r)
-	}
-	y = 9223372036854775806
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s 9223372036854775806 = %d, want -1", "%", r)
-	}
-	y = 9223372036854775807
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s 9223372036854775807 = %d, want -1", "%", r)
-	}
-	x = 0
-	y = -9223372036854775808
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -9223372036854775808 = %d, want 0", "%", r)
-	}
-	y = -9223372036854775807
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -9223372036854775807 = %d, want 0", "%", r)
-	}
-	y = -4294967296
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -4294967296 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "%", r)
-	}
-	y = 9223372036854775806
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 9223372036854775806 = %d, want 0", "%", r)
-	}
-	y = 9223372036854775807
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 9223372036854775807 = %d, want 0", "%", r)
-	}
-	x = 1
-	y = -9223372036854775808
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s -9223372036854775808 = %d, want 1", "%", r)
-	}
-	y = -9223372036854775807
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s -9223372036854775807 = %d, want 1", "%", r)
-	}
-	y = -4294967296
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s -4294967296 = %d, want 1", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("1 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 4294967296 = %d, want 1", "%", r)
-	}
-	y = 9223372036854775806
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 9223372036854775806 = %d, want 1", "%", r)
-	}
-	y = 9223372036854775807
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 9223372036854775807 = %d, want 1", "%", r)
-	}
-	x = 4294967296
-	y = -9223372036854775808
-	r = x % y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s -9223372036854775808 = %d, want 4294967296", "%", r)
-	}
-	y = -9223372036854775807
-	r = x % y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s -9223372036854775807 = %d, want 4294967296", "%", r)
-	}
-	y = -4294967296
-	r = x % y
-	if r != 0 {
-		t.Errorf("4294967296 %s -4294967296 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("4294967296 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("4294967296 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "%", r)
-	}
-	y = 9223372036854775806
-	r = x % y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 9223372036854775806 = %d, want 4294967296", "%", r)
-	}
-	y = 9223372036854775807
-	r = x % y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 9223372036854775807 = %d, want 4294967296", "%", r)
-	}
-	x = 9223372036854775806
-	y = -9223372036854775808
-	r = x % y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s -9223372036854775808 = %d, want 9223372036854775806", "%", r)
-	}
-	y = -9223372036854775807
-	r = x % y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s -9223372036854775807 = %d, want 9223372036854775806", "%", r)
-	}
-	y = -4294967296
-	r = x % y
-	if r != 4294967294 {
-		t.Errorf("9223372036854775806 %s -4294967296 = %d, want 4294967294", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != 4294967294 {
-		t.Errorf("9223372036854775806 %s 4294967296 = %d, want 4294967294", "%", r)
-	}
-	y = 9223372036854775806
-	r = x % y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 9223372036854775806 = %d, want 0", "%", r)
-	}
-	y = 9223372036854775807
-	r = x % y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 9223372036854775807 = %d, want 9223372036854775806", "%", r)
-	}
-	x = 9223372036854775807
-	y = -9223372036854775808
-	r = x % y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s -9223372036854775808 = %d, want 9223372036854775807", "%", r)
-	}
-	y = -9223372036854775807
-	r = x % y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s -9223372036854775807 = %d, want 0", "%", r)
-	}
-	y = -4294967296
-	r = x % y
-	if r != 4294967295 {
-		t.Errorf("9223372036854775807 %s -4294967296 = %d, want 4294967295", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967296
-	r = x % y
-	if r != 4294967295 {
-		t.Errorf("9223372036854775807 %s 4294967296 = %d, want 4294967295", "%", r)
-	}
-	y = 9223372036854775806
-	r = x % y
-	if r != 1 {
-		t.Errorf("9223372036854775807 %s 9223372036854775806 = %d, want 1", "%", r)
-	}
-	y = 9223372036854775807
-	r = x % y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 9223372036854775807 = %d, want 0", "%", r)
-	}
-}
-func TestConstFolduint32add(t *testing.T) {
-	var x, y, r uint32
-	x = 0
-	y = 0
-	r = x + y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 1 {
-		t.Errorf("0 %s 1 = %d, want 1", "+", r)
-	}
-	y = 4294967295
-	r = x + y
-	if r != 4294967295 {
-		t.Errorf("0 %s 4294967295 = %d, want 4294967295", "+", r)
-	}
-	x = 1
-	y = 0
-	r = x + y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "+", r)
-	}
-	y = 4294967295
-	r = x + y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", "+", r)
-	}
-	x = 4294967295
-	y = 0
-	r = x + y
-	if r != 4294967295 {
-		t.Errorf("4294967295 %s 0 = %d, want 4294967295", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 0 {
-		t.Errorf("4294967295 %s 1 = %d, want 0", "+", r)
-	}
-	y = 4294967295
-	r = x + y
-	if r != 4294967294 {
-		t.Errorf("4294967295 %s 4294967295 = %d, want 4294967294", "+", r)
-	}
-}
-func TestConstFolduint32sub(t *testing.T) {
-	var x, y, r uint32
-	x = 0
-	y = 0
-	r = x - y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 4294967295 {
-		t.Errorf("0 %s 1 = %d, want 4294967295", "-", r)
-	}
-	y = 4294967295
-	r = x - y
-	if r != 1 {
-		t.Errorf("0 %s 4294967295 = %d, want 1", "-", r)
-	}
-	x = 1
-	y = 0
-	r = x - y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "-", r)
-	}
-	y = 4294967295
-	r = x - y
-	if r != 2 {
-		t.Errorf("1 %s 4294967295 = %d, want 2", "-", r)
-	}
-	x = 4294967295
-	y = 0
-	r = x - y
-	if r != 4294967295 {
-		t.Errorf("4294967295 %s 0 = %d, want 4294967295", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 4294967294 {
-		t.Errorf("4294967295 %s 1 = %d, want 4294967294", "-", r)
-	}
-	y = 4294967295
-	r = x - y
-	if r != 0 {
-		t.Errorf("4294967295 %s 4294967295 = %d, want 0", "-", r)
-	}
-}
-func TestConstFolduint32div(t *testing.T) {
-	var x, y, r uint32
-	x = 0
-	y = 1
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "/", r)
-	}
-	y = 4294967295
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", "/", r)
-	}
-	x = 1
-	y = 1
-	r = x / y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "/", r)
-	}
-	y = 4294967295
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", "/", r)
-	}
-	x = 4294967295
-	y = 1
-	r = x / y
-	if r != 4294967295 {
-		t.Errorf("4294967295 %s 1 = %d, want 4294967295", "/", r)
-	}
-	y = 4294967295
-	r = x / y
-	if r != 1 {
-		t.Errorf("4294967295 %s 4294967295 = %d, want 1", "/", r)
-	}
-}
-func TestConstFolduint32mul(t *testing.T) {
-	var x, y, r uint32
-	x = 0
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "*", r)
-	}
-	y = 4294967295
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", "*", r)
-	}
-	x = 1
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("1 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "*", r)
-	}
-	y = 4294967295
-	r = x * y
-	if r != 4294967295 {
-		t.Errorf("1 %s 4294967295 = %d, want 4294967295", "*", r)
-	}
-	x = 4294967295
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("4294967295 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 4294967295 {
-		t.Errorf("4294967295 %s 1 = %d, want 4294967295", "*", r)
-	}
-	y = 4294967295
-	r = x * y
-	if r != 1 {
-		t.Errorf("4294967295 %s 4294967295 = %d, want 1", "*", r)
-	}
-}
-func TestConstFolduint32mod(t *testing.T) {
-	var x, y, r uint32
-	x = 0
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967295
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", "%", r)
-	}
-	x = 1
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967295
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 4294967295 = %d, want 1", "%", r)
-	}
-	x = 4294967295
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("4294967295 %s 1 = %d, want 0", "%", r)
-	}
-	y = 4294967295
-	r = x % y
-	if r != 0 {
-		t.Errorf("4294967295 %s 4294967295 = %d, want 0", "%", r)
-	}
-}
-func TestConstFoldint32add(t *testing.T) {
-	var x, y, r int32
-	x = -2147483648
-	y = -2147483648
-	r = x + y
-	if r != 0 {
-		t.Errorf("-2147483648 %s -2147483648 = %d, want 0", "+", r)
-	}
-	y = -2147483647
-	r = x + y
-	if r != 1 {
-		t.Errorf("-2147483648 %s -2147483647 = %d, want 1", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 2147483647 {
-		t.Errorf("-2147483648 %s -1 = %d, want 2147483647", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -2147483647 {
-		t.Errorf("-2147483648 %s 1 = %d, want -2147483647", "+", r)
-	}
-	y = 2147483647
-	r = x + y
-	if r != -1 {
-		t.Errorf("-2147483648 %s 2147483647 = %d, want -1", "+", r)
-	}
-	x = -2147483647
-	y = -2147483648
-	r = x + y
-	if r != 1 {
-		t.Errorf("-2147483647 %s -2147483648 = %d, want 1", "+", r)
-	}
-	y = -2147483647
-	r = x + y
-	if r != 2 {
-		t.Errorf("-2147483647 %s -2147483647 = %d, want 2", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -2147483648 {
-		t.Errorf("-2147483647 %s -1 = %d, want -2147483648", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -2147483646 {
-		t.Errorf("-2147483647 %s 1 = %d, want -2147483646", "+", r)
-	}
-	y = 2147483647
-	r = x + y
-	if r != 0 {
-		t.Errorf("-2147483647 %s 2147483647 = %d, want 0", "+", r)
-	}
-	x = -1
-	y = -2147483648
-	r = x + y
-	if r != 2147483647 {
-		t.Errorf("-1 %s -2147483648 = %d, want 2147483647", "+", r)
-	}
-	y = -2147483647
-	r = x + y
-	if r != -2147483648 {
-		t.Errorf("-1 %s -2147483647 = %d, want -2147483648", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -2 {
-		t.Errorf("-1 %s -1 = %d, want -2", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 0 {
-		t.Errorf("-1 %s 1 = %d, want 0", "+", r)
-	}
-	y = 2147483647
-	r = x + y
-	if r != 2147483646 {
-		t.Errorf("-1 %s 2147483647 = %d, want 2147483646", "+", r)
-	}
-	x = 0
-	y = -2147483648
-	r = x + y
-	if r != -2147483648 {
-		t.Errorf("0 %s -2147483648 = %d, want -2147483648", "+", r)
-	}
-	y = -2147483647
-	r = x + y
-	if r != -2147483647 {
-		t.Errorf("0 %s -2147483647 = %d, want -2147483647", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -1 {
-		t.Errorf("0 %s -1 = %d, want -1", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 1 {
-		t.Errorf("0 %s 1 = %d, want 1", "+", r)
-	}
-	y = 2147483647
-	r = x + y
-	if r != 2147483647 {
-		t.Errorf("0 %s 2147483647 = %d, want 2147483647", "+", r)
-	}
-	x = 1
-	y = -2147483648
-	r = x + y
-	if r != -2147483647 {
-		t.Errorf("1 %s -2147483648 = %d, want -2147483647", "+", r)
-	}
-	y = -2147483647
-	r = x + y
-	if r != -2147483646 {
-		t.Errorf("1 %s -2147483647 = %d, want -2147483646", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 0 {
-		t.Errorf("1 %s -1 = %d, want 0", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "+", r)
-	}
-	y = 2147483647
-	r = x + y
-	if r != -2147483648 {
-		t.Errorf("1 %s 2147483647 = %d, want -2147483648", "+", r)
-	}
-	x = 2147483647
-	y = -2147483648
-	r = x + y
-	if r != -1 {
-		t.Errorf("2147483647 %s -2147483648 = %d, want -1", "+", r)
-	}
-	y = -2147483647
-	r = x + y
-	if r != 0 {
-		t.Errorf("2147483647 %s -2147483647 = %d, want 0", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 2147483646 {
-		t.Errorf("2147483647 %s -1 = %d, want 2147483646", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s 0 = %d, want 2147483647", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -2147483648 {
-		t.Errorf("2147483647 %s 1 = %d, want -2147483648", "+", r)
-	}
-	y = 2147483647
-	r = x + y
-	if r != -2 {
-		t.Errorf("2147483647 %s 2147483647 = %d, want -2", "+", r)
-	}
-}
-func TestConstFoldint32sub(t *testing.T) {
-	var x, y, r int32
-	x = -2147483648
-	y = -2147483648
-	r = x - y
-	if r != 0 {
-		t.Errorf("-2147483648 %s -2147483648 = %d, want 0", "-", r)
-	}
-	y = -2147483647
-	r = x - y
-	if r != -1 {
-		t.Errorf("-2147483648 %s -2147483647 = %d, want -1", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -2147483647 {
-		t.Errorf("-2147483648 %s -1 = %d, want -2147483647", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 2147483647 {
-		t.Errorf("-2147483648 %s 1 = %d, want 2147483647", "-", r)
-	}
-	y = 2147483647
-	r = x - y
-	if r != 1 {
-		t.Errorf("-2147483648 %s 2147483647 = %d, want 1", "-", r)
-	}
-	x = -2147483647
-	y = -2147483648
-	r = x - y
-	if r != 1 {
-		t.Errorf("-2147483647 %s -2147483648 = %d, want 1", "-", r)
-	}
-	y = -2147483647
-	r = x - y
-	if r != 0 {
-		t.Errorf("-2147483647 %s -2147483647 = %d, want 0", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -2147483646 {
-		t.Errorf("-2147483647 %s -1 = %d, want -2147483646", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -2147483648 {
-		t.Errorf("-2147483647 %s 1 = %d, want -2147483648", "-", r)
-	}
-	y = 2147483647
-	r = x - y
-	if r != 2 {
-		t.Errorf("-2147483647 %s 2147483647 = %d, want 2", "-", r)
-	}
-	x = -1
-	y = -2147483648
-	r = x - y
-	if r != 2147483647 {
-		t.Errorf("-1 %s -2147483648 = %d, want 2147483647", "-", r)
-	}
-	y = -2147483647
-	r = x - y
-	if r != 2147483646 {
-		t.Errorf("-1 %s -2147483647 = %d, want 2147483646", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 0 {
-		t.Errorf("-1 %s -1 = %d, want 0", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "-", r)
-	}
-	y = 2147483647
-	r = x - y
-	if r != -2147483648 {
-		t.Errorf("-1 %s 2147483647 = %d, want -2147483648", "-", r)
-	}
-	x = 0
-	y = -2147483648
-	r = x - y
-	if r != -2147483648 {
-		t.Errorf("0 %s -2147483648 = %d, want -2147483648", "-", r)
-	}
-	y = -2147483647
-	r = x - y
-	if r != 2147483647 {
-		t.Errorf("0 %s -2147483647 = %d, want 2147483647", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 1 {
-		t.Errorf("0 %s -1 = %d, want 1", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -1 {
-		t.Errorf("0 %s 1 = %d, want -1", "-", r)
-	}
-	y = 2147483647
-	r = x - y
-	if r != -2147483647 {
-		t.Errorf("0 %s 2147483647 = %d, want -2147483647", "-", r)
-	}
-	x = 1
-	y = -2147483648
-	r = x - y
-	if r != -2147483647 {
-		t.Errorf("1 %s -2147483648 = %d, want -2147483647", "-", r)
-	}
-	y = -2147483647
-	r = x - y
-	if r != -2147483648 {
-		t.Errorf("1 %s -2147483647 = %d, want -2147483648", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 2 {
-		t.Errorf("1 %s -1 = %d, want 2", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "-", r)
-	}
-	y = 2147483647
-	r = x - y
-	if r != -2147483646 {
-		t.Errorf("1 %s 2147483647 = %d, want -2147483646", "-", r)
-	}
-	x = 2147483647
-	y = -2147483648
-	r = x - y
-	if r != -1 {
-		t.Errorf("2147483647 %s -2147483648 = %d, want -1", "-", r)
-	}
-	y = -2147483647
-	r = x - y
-	if r != -2 {
-		t.Errorf("2147483647 %s -2147483647 = %d, want -2", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -2147483648 {
-		t.Errorf("2147483647 %s -1 = %d, want -2147483648", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s 0 = %d, want 2147483647", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 2147483646 {
-		t.Errorf("2147483647 %s 1 = %d, want 2147483646", "-", r)
-	}
-	y = 2147483647
-	r = x - y
-	if r != 0 {
-		t.Errorf("2147483647 %s 2147483647 = %d, want 0", "-", r)
-	}
-}
-func TestConstFoldint32div(t *testing.T) {
-	var x, y, r int32
-	x = -2147483648
-	y = -2147483648
-	r = x / y
-	if r != 1 {
-		t.Errorf("-2147483648 %s -2147483648 = %d, want 1", "/", r)
-	}
-	y = -2147483647
-	r = x / y
-	if r != 1 {
-		t.Errorf("-2147483648 %s -2147483647 = %d, want 1", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s -1 = %d, want -2147483648", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 1 = %d, want -2147483648", "/", r)
-	}
-	y = 2147483647
-	r = x / y
-	if r != -1 {
-		t.Errorf("-2147483648 %s 2147483647 = %d, want -1", "/", r)
-	}
-	x = -2147483647
-	y = -2147483648
-	r = x / y
-	if r != 0 {
-		t.Errorf("-2147483647 %s -2147483648 = %d, want 0", "/", r)
-	}
-	y = -2147483647
-	r = x / y
-	if r != 1 {
-		t.Errorf("-2147483647 %s -2147483647 = %d, want 1", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 2147483647 {
-		t.Errorf("-2147483647 %s -1 = %d, want 2147483647", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s 1 = %d, want -2147483647", "/", r)
-	}
-	y = 2147483647
-	r = x / y
-	if r != -1 {
-		t.Errorf("-2147483647 %s 2147483647 = %d, want -1", "/", r)
-	}
-	x = -1
-	y = -2147483648
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s -2147483648 = %d, want 0", "/", r)
-	}
-	y = -2147483647
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s -2147483647 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 1 {
-		t.Errorf("-1 %s -1 = %d, want 1", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", "/", r)
-	}
-	y = 2147483647
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s 2147483647 = %d, want 0", "/", r)
-	}
-	x = 0
-	y = -2147483648
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -2147483648 = %d, want 0", "/", r)
-	}
-	y = -2147483647
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -2147483647 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -1 = %d, want 0", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "/", r)
-	}
-	y = 2147483647
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 2147483647 = %d, want 0", "/", r)
-	}
-	x = 1
-	y = -2147483648
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s -2147483648 = %d, want 0", "/", r)
-	}
-	y = -2147483647
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s -2147483647 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -1 {
-		t.Errorf("1 %s -1 = %d, want -1", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "/", r)
-	}
-	y = 2147483647
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 2147483647 = %d, want 0", "/", r)
-	}
-	x = 2147483647
-	y = -2147483648
-	r = x / y
-	if r != 0 {
-		t.Errorf("2147483647 %s -2147483648 = %d, want 0", "/", r)
-	}
-	y = -2147483647
-	r = x / y
-	if r != -1 {
-		t.Errorf("2147483647 %s -2147483647 = %d, want -1", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -2147483647 {
-		t.Errorf("2147483647 %s -1 = %d, want -2147483647", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s 1 = %d, want 2147483647", "/", r)
-	}
-	y = 2147483647
-	r = x / y
-	if r != 1 {
-		t.Errorf("2147483647 %s 2147483647 = %d, want 1", "/", r)
-	}
-}
-func TestConstFoldint32mul(t *testing.T) {
-	var x, y, r int32
-	x = -2147483648
-	y = -2147483648
-	r = x * y
-	if r != 0 {
-		t.Errorf("-2147483648 %s -2147483648 = %d, want 0", "*", r)
-	}
-	y = -2147483647
-	r = x * y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s -2147483647 = %d, want -2147483648", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s -1 = %d, want -2147483648", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-2147483648 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 1 = %d, want -2147483648", "*", r)
-	}
-	y = 2147483647
-	r = x * y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 2147483647 = %d, want -2147483648", "*", r)
-	}
-	x = -2147483647
-	y = -2147483648
-	r = x * y
-	if r != -2147483648 {
-		t.Errorf("-2147483647 %s -2147483648 = %d, want -2147483648", "*", r)
-	}
-	y = -2147483647
-	r = x * y
-	if r != 1 {
-		t.Errorf("-2147483647 %s -2147483647 = %d, want 1", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 2147483647 {
-		t.Errorf("-2147483647 %s -1 = %d, want 2147483647", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-2147483647 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s 1 = %d, want -2147483647", "*", r)
-	}
-	y = 2147483647
-	r = x * y
-	if r != -1 {
-		t.Errorf("-2147483647 %s 2147483647 = %d, want -1", "*", r)
-	}
-	x = -1
-	y = -2147483648
-	r = x * y
-	if r != -2147483648 {
-		t.Errorf("-1 %s -2147483648 = %d, want -2147483648", "*", r)
-	}
-	y = -2147483647
-	r = x * y
-	if r != 2147483647 {
-		t.Errorf("-1 %s -2147483647 = %d, want 2147483647", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 1 {
-		t.Errorf("-1 %s -1 = %d, want 1", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-1 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", "*", r)
-	}
-	y = 2147483647
-	r = x * y
-	if r != -2147483647 {
-		t.Errorf("-1 %s 2147483647 = %d, want -2147483647", "*", r)
-	}
-	x = 0
-	y = -2147483648
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -2147483648 = %d, want 0", "*", r)
-	}
-	y = -2147483647
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -2147483647 = %d, want 0", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -1 = %d, want 0", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "*", r)
-	}
-	y = 2147483647
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 2147483647 = %d, want 0", "*", r)
-	}
-	x = 1
-	y = -2147483648
-	r = x * y
-	if r != -2147483648 {
-		t.Errorf("1 %s -2147483648 = %d, want -2147483648", "*", r)
-	}
-	y = -2147483647
-	r = x * y
-	if r != -2147483647 {
-		t.Errorf("1 %s -2147483647 = %d, want -2147483647", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -1 {
-		t.Errorf("1 %s -1 = %d, want -1", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("1 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "*", r)
-	}
-	y = 2147483647
-	r = x * y
-	if r != 2147483647 {
-		t.Errorf("1 %s 2147483647 = %d, want 2147483647", "*", r)
-	}
-	x = 2147483647
-	y = -2147483648
-	r = x * y
-	if r != -2147483648 {
-		t.Errorf("2147483647 %s -2147483648 = %d, want -2147483648", "*", r)
-	}
-	y = -2147483647
-	r = x * y
-	if r != -1 {
-		t.Errorf("2147483647 %s -2147483647 = %d, want -1", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -2147483647 {
-		t.Errorf("2147483647 %s -1 = %d, want -2147483647", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("2147483647 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s 1 = %d, want 2147483647", "*", r)
-	}
-	y = 2147483647
-	r = x * y
-	if r != 1 {
-		t.Errorf("2147483647 %s 2147483647 = %d, want 1", "*", r)
-	}
-}
-func TestConstFoldint32mod(t *testing.T) {
-	var x, y, r int32
-	x = -2147483648
-	y = -2147483648
-	r = x % y
-	if r != 0 {
-		t.Errorf("-2147483648 %s -2147483648 = %d, want 0", "%", r)
-	}
-	y = -2147483647
-	r = x % y
-	if r != -1 {
-		t.Errorf("-2147483648 %s -2147483647 = %d, want -1", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-2147483648 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-2147483648 %s 1 = %d, want 0", "%", r)
-	}
-	y = 2147483647
-	r = x % y
-	if r != -1 {
-		t.Errorf("-2147483648 %s 2147483647 = %d, want -1", "%", r)
-	}
-	x = -2147483647
-	y = -2147483648
-	r = x % y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s -2147483648 = %d, want -2147483647", "%", r)
-	}
-	y = -2147483647
-	r = x % y
-	if r != 0 {
-		t.Errorf("-2147483647 %s -2147483647 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-2147483647 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-2147483647 %s 1 = %d, want 0", "%", r)
-	}
-	y = 2147483647
-	r = x % y
-	if r != 0 {
-		t.Errorf("-2147483647 %s 2147483647 = %d, want 0", "%", r)
-	}
-	x = -1
-	y = -2147483648
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s -2147483648 = %d, want -1", "%", r)
-	}
-	y = -2147483647
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s -2147483647 = %d, want -1", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-1 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-1 %s 1 = %d, want 0", "%", r)
-	}
-	y = 2147483647
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s 2147483647 = %d, want -1", "%", r)
-	}
-	x = 0
-	y = -2147483648
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -2147483648 = %d, want 0", "%", r)
-	}
-	y = -2147483647
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -2147483647 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "%", r)
-	}
-	y = 2147483647
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 2147483647 = %d, want 0", "%", r)
-	}
-	x = 1
-	y = -2147483648
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s -2147483648 = %d, want 1", "%", r)
-	}
-	y = -2147483647
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s -2147483647 = %d, want 1", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("1 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "%", r)
-	}
-	y = 2147483647
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 2147483647 = %d, want 1", "%", r)
-	}
-	x = 2147483647
-	y = -2147483648
-	r = x % y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s -2147483648 = %d, want 2147483647", "%", r)
-	}
-	y = -2147483647
-	r = x % y
-	if r != 0 {
-		t.Errorf("2147483647 %s -2147483647 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("2147483647 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("2147483647 %s 1 = %d, want 0", "%", r)
-	}
-	y = 2147483647
-	r = x % y
-	if r != 0 {
-		t.Errorf("2147483647 %s 2147483647 = %d, want 0", "%", r)
-	}
-}
-func TestConstFolduint16add(t *testing.T) {
-	var x, y, r uint16
-	x = 0
-	y = 0
-	r = x + y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 1 {
-		t.Errorf("0 %s 1 = %d, want 1", "+", r)
-	}
-	y = 65535
-	r = x + y
-	if r != 65535 {
-		t.Errorf("0 %s 65535 = %d, want 65535", "+", r)
-	}
-	x = 1
-	y = 0
-	r = x + y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "+", r)
-	}
-	y = 65535
-	r = x + y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", "+", r)
-	}
-	x = 65535
-	y = 0
-	r = x + y
-	if r != 65535 {
-		t.Errorf("65535 %s 0 = %d, want 65535", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 0 {
-		t.Errorf("65535 %s 1 = %d, want 0", "+", r)
-	}
-	y = 65535
-	r = x + y
-	if r != 65534 {
-		t.Errorf("65535 %s 65535 = %d, want 65534", "+", r)
-	}
-}
-func TestConstFolduint16sub(t *testing.T) {
-	var x, y, r uint16
-	x = 0
-	y = 0
-	r = x - y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 65535 {
-		t.Errorf("0 %s 1 = %d, want 65535", "-", r)
-	}
-	y = 65535
-	r = x - y
-	if r != 1 {
-		t.Errorf("0 %s 65535 = %d, want 1", "-", r)
-	}
-	x = 1
-	y = 0
-	r = x - y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "-", r)
-	}
-	y = 65535
-	r = x - y
-	if r != 2 {
-		t.Errorf("1 %s 65535 = %d, want 2", "-", r)
-	}
-	x = 65535
-	y = 0
-	r = x - y
-	if r != 65535 {
-		t.Errorf("65535 %s 0 = %d, want 65535", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 65534 {
-		t.Errorf("65535 %s 1 = %d, want 65534", "-", r)
-	}
-	y = 65535
-	r = x - y
-	if r != 0 {
-		t.Errorf("65535 %s 65535 = %d, want 0", "-", r)
-	}
-}
-func TestConstFolduint16div(t *testing.T) {
-	var x, y, r uint16
-	x = 0
-	y = 1
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "/", r)
-	}
-	y = 65535
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", "/", r)
-	}
-	x = 1
-	y = 1
-	r = x / y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "/", r)
-	}
-	y = 65535
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", "/", r)
-	}
-	x = 65535
-	y = 1
-	r = x / y
-	if r != 65535 {
-		t.Errorf("65535 %s 1 = %d, want 65535", "/", r)
-	}
-	y = 65535
-	r = x / y
-	if r != 1 {
-		t.Errorf("65535 %s 65535 = %d, want 1", "/", r)
-	}
-}
-func TestConstFolduint16mul(t *testing.T) {
-	var x, y, r uint16
-	x = 0
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "*", r)
-	}
-	y = 65535
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", "*", r)
-	}
-	x = 1
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("1 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "*", r)
-	}
-	y = 65535
-	r = x * y
-	if r != 65535 {
-		t.Errorf("1 %s 65535 = %d, want 65535", "*", r)
-	}
-	x = 65535
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("65535 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 65535 {
-		t.Errorf("65535 %s 1 = %d, want 65535", "*", r)
-	}
-	y = 65535
-	r = x * y
-	if r != 1 {
-		t.Errorf("65535 %s 65535 = %d, want 1", "*", r)
-	}
-}
-func TestConstFolduint16mod(t *testing.T) {
-	var x, y, r uint16
-	x = 0
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "%", r)
-	}
-	y = 65535
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", "%", r)
-	}
-	x = 1
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "%", r)
-	}
-	y = 65535
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 65535 = %d, want 1", "%", r)
-	}
-	x = 65535
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("65535 %s 1 = %d, want 0", "%", r)
-	}
-	y = 65535
-	r = x % y
-	if r != 0 {
-		t.Errorf("65535 %s 65535 = %d, want 0", "%", r)
-	}
-}
-func TestConstFoldint16add(t *testing.T) {
-	var x, y, r int16
-	x = -32768
-	y = -32768
-	r = x + y
-	if r != 0 {
-		t.Errorf("-32768 %s -32768 = %d, want 0", "+", r)
-	}
-	y = -32767
-	r = x + y
-	if r != 1 {
-		t.Errorf("-32768 %s -32767 = %d, want 1", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 32767 {
-		t.Errorf("-32768 %s -1 = %d, want 32767", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -32768 {
-		t.Errorf("-32768 %s 0 = %d, want -32768", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -32767 {
-		t.Errorf("-32768 %s 1 = %d, want -32767", "+", r)
-	}
-	y = 32766
-	r = x + y
-	if r != -2 {
-		t.Errorf("-32768 %s 32766 = %d, want -2", "+", r)
-	}
-	y = 32767
-	r = x + y
-	if r != -1 {
-		t.Errorf("-32768 %s 32767 = %d, want -1", "+", r)
-	}
-	x = -32767
-	y = -32768
-	r = x + y
-	if r != 1 {
-		t.Errorf("-32767 %s -32768 = %d, want 1", "+", r)
-	}
-	y = -32767
-	r = x + y
-	if r != 2 {
-		t.Errorf("-32767 %s -32767 = %d, want 2", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -32768 {
-		t.Errorf("-32767 %s -1 = %d, want -32768", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -32767 {
-		t.Errorf("-32767 %s 0 = %d, want -32767", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -32766 {
-		t.Errorf("-32767 %s 1 = %d, want -32766", "+", r)
-	}
-	y = 32766
-	r = x + y
-	if r != -1 {
-		t.Errorf("-32767 %s 32766 = %d, want -1", "+", r)
-	}
-	y = 32767
-	r = x + y
-	if r != 0 {
-		t.Errorf("-32767 %s 32767 = %d, want 0", "+", r)
-	}
-	x = -1
-	y = -32768
-	r = x + y
-	if r != 32767 {
-		t.Errorf("-1 %s -32768 = %d, want 32767", "+", r)
-	}
-	y = -32767
-	r = x + y
-	if r != -32768 {
-		t.Errorf("-1 %s -32767 = %d, want -32768", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -2 {
-		t.Errorf("-1 %s -1 = %d, want -2", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 0 {
-		t.Errorf("-1 %s 1 = %d, want 0", "+", r)
-	}
-	y = 32766
-	r = x + y
-	if r != 32765 {
-		t.Errorf("-1 %s 32766 = %d, want 32765", "+", r)
-	}
-	y = 32767
-	r = x + y
-	if r != 32766 {
-		t.Errorf("-1 %s 32767 = %d, want 32766", "+", r)
-	}
-	x = 0
-	y = -32768
-	r = x + y
-	if r != -32768 {
-		t.Errorf("0 %s -32768 = %d, want -32768", "+", r)
-	}
-	y = -32767
-	r = x + y
-	if r != -32767 {
-		t.Errorf("0 %s -32767 = %d, want -32767", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -1 {
-		t.Errorf("0 %s -1 = %d, want -1", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 1 {
-		t.Errorf("0 %s 1 = %d, want 1", "+", r)
-	}
-	y = 32766
-	r = x + y
-	if r != 32766 {
-		t.Errorf("0 %s 32766 = %d, want 32766", "+", r)
-	}
-	y = 32767
-	r = x + y
-	if r != 32767 {
-		t.Errorf("0 %s 32767 = %d, want 32767", "+", r)
-	}
-	x = 1
-	y = -32768
-	r = x + y
-	if r != -32767 {
-		t.Errorf("1 %s -32768 = %d, want -32767", "+", r)
-	}
-	y = -32767
-	r = x + y
-	if r != -32766 {
-		t.Errorf("1 %s -32767 = %d, want -32766", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 0 {
-		t.Errorf("1 %s -1 = %d, want 0", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "+", r)
-	}
-	y = 32766
-	r = x + y
-	if r != 32767 {
-		t.Errorf("1 %s 32766 = %d, want 32767", "+", r)
-	}
-	y = 32767
-	r = x + y
-	if r != -32768 {
-		t.Errorf("1 %s 32767 = %d, want -32768", "+", r)
-	}
-	x = 32766
-	y = -32768
-	r = x + y
-	if r != -2 {
-		t.Errorf("32766 %s -32768 = %d, want -2", "+", r)
-	}
-	y = -32767
-	r = x + y
-	if r != -1 {
-		t.Errorf("32766 %s -32767 = %d, want -1", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 32765 {
-		t.Errorf("32766 %s -1 = %d, want 32765", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 32766 {
-		t.Errorf("32766 %s 0 = %d, want 32766", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 32767 {
-		t.Errorf("32766 %s 1 = %d, want 32767", "+", r)
-	}
-	y = 32766
-	r = x + y
-	if r != -4 {
-		t.Errorf("32766 %s 32766 = %d, want -4", "+", r)
-	}
-	y = 32767
-	r = x + y
-	if r != -3 {
-		t.Errorf("32766 %s 32767 = %d, want -3", "+", r)
-	}
-	x = 32767
-	y = -32768
-	r = x + y
-	if r != -1 {
-		t.Errorf("32767 %s -32768 = %d, want -1", "+", r)
-	}
-	y = -32767
-	r = x + y
-	if r != 0 {
-		t.Errorf("32767 %s -32767 = %d, want 0", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 32766 {
-		t.Errorf("32767 %s -1 = %d, want 32766", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 32767 {
-		t.Errorf("32767 %s 0 = %d, want 32767", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -32768 {
-		t.Errorf("32767 %s 1 = %d, want -32768", "+", r)
-	}
-	y = 32766
-	r = x + y
-	if r != -3 {
-		t.Errorf("32767 %s 32766 = %d, want -3", "+", r)
-	}
-	y = 32767
-	r = x + y
-	if r != -2 {
-		t.Errorf("32767 %s 32767 = %d, want -2", "+", r)
-	}
-}
-func TestConstFoldint16sub(t *testing.T) {
-	var x, y, r int16
-	x = -32768
-	y = -32768
-	r = x - y
-	if r != 0 {
-		t.Errorf("-32768 %s -32768 = %d, want 0", "-", r)
-	}
-	y = -32767
-	r = x - y
-	if r != -1 {
-		t.Errorf("-32768 %s -32767 = %d, want -1", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -32767 {
-		t.Errorf("-32768 %s -1 = %d, want -32767", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -32768 {
-		t.Errorf("-32768 %s 0 = %d, want -32768", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 32767 {
-		t.Errorf("-32768 %s 1 = %d, want 32767", "-", r)
-	}
-	y = 32766
-	r = x - y
-	if r != 2 {
-		t.Errorf("-32768 %s 32766 = %d, want 2", "-", r)
-	}
-	y = 32767
-	r = x - y
-	if r != 1 {
-		t.Errorf("-32768 %s 32767 = %d, want 1", "-", r)
-	}
-	x = -32767
-	y = -32768
-	r = x - y
-	if r != 1 {
-		t.Errorf("-32767 %s -32768 = %d, want 1", "-", r)
-	}
-	y = -32767
-	r = x - y
-	if r != 0 {
-		t.Errorf("-32767 %s -32767 = %d, want 0", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -32766 {
-		t.Errorf("-32767 %s -1 = %d, want -32766", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -32767 {
-		t.Errorf("-32767 %s 0 = %d, want -32767", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -32768 {
-		t.Errorf("-32767 %s 1 = %d, want -32768", "-", r)
-	}
-	y = 32766
-	r = x - y
-	if r != 3 {
-		t.Errorf("-32767 %s 32766 = %d, want 3", "-", r)
-	}
-	y = 32767
-	r = x - y
-	if r != 2 {
-		t.Errorf("-32767 %s 32767 = %d, want 2", "-", r)
-	}
-	x = -1
-	y = -32768
-	r = x - y
-	if r != 32767 {
-		t.Errorf("-1 %s -32768 = %d, want 32767", "-", r)
-	}
-	y = -32767
-	r = x - y
-	if r != 32766 {
-		t.Errorf("-1 %s -32767 = %d, want 32766", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 0 {
-		t.Errorf("-1 %s -1 = %d, want 0", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "-", r)
-	}
-	y = 32766
-	r = x - y
-	if r != -32767 {
-		t.Errorf("-1 %s 32766 = %d, want -32767", "-", r)
-	}
-	y = 32767
-	r = x - y
-	if r != -32768 {
-		t.Errorf("-1 %s 32767 = %d, want -32768", "-", r)
-	}
-	x = 0
-	y = -32768
-	r = x - y
-	if r != -32768 {
-		t.Errorf("0 %s -32768 = %d, want -32768", "-", r)
-	}
-	y = -32767
-	r = x - y
-	if r != 32767 {
-		t.Errorf("0 %s -32767 = %d, want 32767", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 1 {
-		t.Errorf("0 %s -1 = %d, want 1", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -1 {
-		t.Errorf("0 %s 1 = %d, want -1", "-", r)
-	}
-	y = 32766
-	r = x - y
-	if r != -32766 {
-		t.Errorf("0 %s 32766 = %d, want -32766", "-", r)
-	}
-	y = 32767
-	r = x - y
-	if r != -32767 {
-		t.Errorf("0 %s 32767 = %d, want -32767", "-", r)
-	}
-	x = 1
-	y = -32768
-	r = x - y
-	if r != -32767 {
-		t.Errorf("1 %s -32768 = %d, want -32767", "-", r)
-	}
-	y = -32767
-	r = x - y
-	if r != -32768 {
-		t.Errorf("1 %s -32767 = %d, want -32768", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 2 {
-		t.Errorf("1 %s -1 = %d, want 2", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "-", r)
-	}
-	y = 32766
-	r = x - y
-	if r != -32765 {
-		t.Errorf("1 %s 32766 = %d, want -32765", "-", r)
-	}
-	y = 32767
-	r = x - y
-	if r != -32766 {
-		t.Errorf("1 %s 32767 = %d, want -32766", "-", r)
-	}
-	x = 32766
-	y = -32768
-	r = x - y
-	if r != -2 {
-		t.Errorf("32766 %s -32768 = %d, want -2", "-", r)
-	}
-	y = -32767
-	r = x - y
-	if r != -3 {
-		t.Errorf("32766 %s -32767 = %d, want -3", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 32767 {
-		t.Errorf("32766 %s -1 = %d, want 32767", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 32766 {
-		t.Errorf("32766 %s 0 = %d, want 32766", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 32765 {
-		t.Errorf("32766 %s 1 = %d, want 32765", "-", r)
-	}
-	y = 32766
-	r = x - y
-	if r != 0 {
-		t.Errorf("32766 %s 32766 = %d, want 0", "-", r)
-	}
-	y = 32767
-	r = x - y
-	if r != -1 {
-		t.Errorf("32766 %s 32767 = %d, want -1", "-", r)
-	}
-	x = 32767
-	y = -32768
-	r = x - y
-	if r != -1 {
-		t.Errorf("32767 %s -32768 = %d, want -1", "-", r)
-	}
-	y = -32767
-	r = x - y
-	if r != -2 {
-		t.Errorf("32767 %s -32767 = %d, want -2", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -32768 {
-		t.Errorf("32767 %s -1 = %d, want -32768", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 32767 {
-		t.Errorf("32767 %s 0 = %d, want 32767", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 32766 {
-		t.Errorf("32767 %s 1 = %d, want 32766", "-", r)
-	}
-	y = 32766
-	r = x - y
-	if r != 1 {
-		t.Errorf("32767 %s 32766 = %d, want 1", "-", r)
-	}
-	y = 32767
-	r = x - y
-	if r != 0 {
-		t.Errorf("32767 %s 32767 = %d, want 0", "-", r)
-	}
-}
-func TestConstFoldint16div(t *testing.T) {
-	var x, y, r int16
-	x = -32768
-	y = -32768
-	r = x / y
-	if r != 1 {
-		t.Errorf("-32768 %s -32768 = %d, want 1", "/", r)
-	}
-	y = -32767
-	r = x / y
-	if r != 1 {
-		t.Errorf("-32768 %s -32767 = %d, want 1", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -32768 {
-		t.Errorf("-32768 %s -1 = %d, want -32768", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -32768 {
-		t.Errorf("-32768 %s 1 = %d, want -32768", "/", r)
-	}
-	y = 32766
-	r = x / y
-	if r != -1 {
-		t.Errorf("-32768 %s 32766 = %d, want -1", "/", r)
-	}
-	y = 32767
-	r = x / y
-	if r != -1 {
-		t.Errorf("-32768 %s 32767 = %d, want -1", "/", r)
-	}
-	x = -32767
-	y = -32768
-	r = x / y
-	if r != 0 {
-		t.Errorf("-32767 %s -32768 = %d, want 0", "/", r)
-	}
-	y = -32767
-	r = x / y
-	if r != 1 {
-		t.Errorf("-32767 %s -32767 = %d, want 1", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 32767 {
-		t.Errorf("-32767 %s -1 = %d, want 32767", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -32767 {
-		t.Errorf("-32767 %s 1 = %d, want -32767", "/", r)
-	}
-	y = 32766
-	r = x / y
-	if r != -1 {
-		t.Errorf("-32767 %s 32766 = %d, want -1", "/", r)
-	}
-	y = 32767
-	r = x / y
-	if r != -1 {
-		t.Errorf("-32767 %s 32767 = %d, want -1", "/", r)
-	}
-	x = -1
-	y = -32768
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s -32768 = %d, want 0", "/", r)
-	}
-	y = -32767
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s -32767 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 1 {
-		t.Errorf("-1 %s -1 = %d, want 1", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", "/", r)
-	}
-	y = 32766
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s 32766 = %d, want 0", "/", r)
-	}
-	y = 32767
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s 32767 = %d, want 0", "/", r)
-	}
-	x = 0
-	y = -32768
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -32768 = %d, want 0", "/", r)
-	}
-	y = -32767
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -32767 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -1 = %d, want 0", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "/", r)
-	}
-	y = 32766
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 32766 = %d, want 0", "/", r)
-	}
-	y = 32767
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 32767 = %d, want 0", "/", r)
-	}
-	x = 1
-	y = -32768
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s -32768 = %d, want 0", "/", r)
-	}
-	y = -32767
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s -32767 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -1 {
-		t.Errorf("1 %s -1 = %d, want -1", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "/", r)
-	}
-	y = 32766
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 32766 = %d, want 0", "/", r)
-	}
-	y = 32767
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 32767 = %d, want 0", "/", r)
-	}
-	x = 32766
-	y = -32768
-	r = x / y
-	if r != 0 {
-		t.Errorf("32766 %s -32768 = %d, want 0", "/", r)
-	}
-	y = -32767
-	r = x / y
-	if r != 0 {
-		t.Errorf("32766 %s -32767 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -32766 {
-		t.Errorf("32766 %s -1 = %d, want -32766", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 32766 {
-		t.Errorf("32766 %s 1 = %d, want 32766", "/", r)
-	}
-	y = 32766
-	r = x / y
-	if r != 1 {
-		t.Errorf("32766 %s 32766 = %d, want 1", "/", r)
-	}
-	y = 32767
-	r = x / y
-	if r != 0 {
-		t.Errorf("32766 %s 32767 = %d, want 0", "/", r)
-	}
-	x = 32767
-	y = -32768
-	r = x / y
-	if r != 0 {
-		t.Errorf("32767 %s -32768 = %d, want 0", "/", r)
-	}
-	y = -32767
-	r = x / y
-	if r != -1 {
-		t.Errorf("32767 %s -32767 = %d, want -1", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -32767 {
-		t.Errorf("32767 %s -1 = %d, want -32767", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 32767 {
-		t.Errorf("32767 %s 1 = %d, want 32767", "/", r)
-	}
-	y = 32766
-	r = x / y
-	if r != 1 {
-		t.Errorf("32767 %s 32766 = %d, want 1", "/", r)
-	}
-	y = 32767
-	r = x / y
-	if r != 1 {
-		t.Errorf("32767 %s 32767 = %d, want 1", "/", r)
-	}
-}
-func TestConstFoldint16mul(t *testing.T) {
-	var x, y, r int16
-	x = -32768
-	y = -32768
-	r = x * y
-	if r != 0 {
-		t.Errorf("-32768 %s -32768 = %d, want 0", "*", r)
-	}
-	y = -32767
-	r = x * y
-	if r != -32768 {
-		t.Errorf("-32768 %s -32767 = %d, want -32768", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -32768 {
-		t.Errorf("-32768 %s -1 = %d, want -32768", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-32768 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -32768 {
-		t.Errorf("-32768 %s 1 = %d, want -32768", "*", r)
-	}
-	y = 32766
-	r = x * y
-	if r != 0 {
-		t.Errorf("-32768 %s 32766 = %d, want 0", "*", r)
-	}
-	y = 32767
-	r = x * y
-	if r != -32768 {
-		t.Errorf("-32768 %s 32767 = %d, want -32768", "*", r)
-	}
-	x = -32767
-	y = -32768
-	r = x * y
-	if r != -32768 {
-		t.Errorf("-32767 %s -32768 = %d, want -32768", "*", r)
-	}
-	y = -32767
-	r = x * y
-	if r != 1 {
-		t.Errorf("-32767 %s -32767 = %d, want 1", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 32767 {
-		t.Errorf("-32767 %s -1 = %d, want 32767", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-32767 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -32767 {
-		t.Errorf("-32767 %s 1 = %d, want -32767", "*", r)
-	}
-	y = 32766
-	r = x * y
-	if r != 32766 {
-		t.Errorf("-32767 %s 32766 = %d, want 32766", "*", r)
-	}
-	y = 32767
-	r = x * y
-	if r != -1 {
-		t.Errorf("-32767 %s 32767 = %d, want -1", "*", r)
-	}
-	x = -1
-	y = -32768
-	r = x * y
-	if r != -32768 {
-		t.Errorf("-1 %s -32768 = %d, want -32768", "*", r)
-	}
-	y = -32767
-	r = x * y
-	if r != 32767 {
-		t.Errorf("-1 %s -32767 = %d, want 32767", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 1 {
-		t.Errorf("-1 %s -1 = %d, want 1", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-1 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", "*", r)
-	}
-	y = 32766
-	r = x * y
-	if r != -32766 {
-		t.Errorf("-1 %s 32766 = %d, want -32766", "*", r)
-	}
-	y = 32767
-	r = x * y
-	if r != -32767 {
-		t.Errorf("-1 %s 32767 = %d, want -32767", "*", r)
-	}
-	x = 0
-	y = -32768
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -32768 = %d, want 0", "*", r)
-	}
-	y = -32767
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -32767 = %d, want 0", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -1 = %d, want 0", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "*", r)
-	}
-	y = 32766
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 32766 = %d, want 0", "*", r)
-	}
-	y = 32767
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 32767 = %d, want 0", "*", r)
-	}
-	x = 1
-	y = -32768
-	r = x * y
-	if r != -32768 {
-		t.Errorf("1 %s -32768 = %d, want -32768", "*", r)
-	}
-	y = -32767
-	r = x * y
-	if r != -32767 {
-		t.Errorf("1 %s -32767 = %d, want -32767", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -1 {
-		t.Errorf("1 %s -1 = %d, want -1", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("1 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "*", r)
-	}
-	y = 32766
-	r = x * y
-	if r != 32766 {
-		t.Errorf("1 %s 32766 = %d, want 32766", "*", r)
-	}
-	y = 32767
-	r = x * y
-	if r != 32767 {
-		t.Errorf("1 %s 32767 = %d, want 32767", "*", r)
-	}
-	x = 32766
-	y = -32768
-	r = x * y
-	if r != 0 {
-		t.Errorf("32766 %s -32768 = %d, want 0", "*", r)
-	}
-	y = -32767
-	r = x * y
-	if r != 32766 {
-		t.Errorf("32766 %s -32767 = %d, want 32766", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -32766 {
-		t.Errorf("32766 %s -1 = %d, want -32766", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("32766 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 32766 {
-		t.Errorf("32766 %s 1 = %d, want 32766", "*", r)
-	}
-	y = 32766
-	r = x * y
-	if r != 4 {
-		t.Errorf("32766 %s 32766 = %d, want 4", "*", r)
-	}
-	y = 32767
-	r = x * y
-	if r != -32766 {
-		t.Errorf("32766 %s 32767 = %d, want -32766", "*", r)
-	}
-	x = 32767
-	y = -32768
-	r = x * y
-	if r != -32768 {
-		t.Errorf("32767 %s -32768 = %d, want -32768", "*", r)
-	}
-	y = -32767
-	r = x * y
-	if r != -1 {
-		t.Errorf("32767 %s -32767 = %d, want -1", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -32767 {
-		t.Errorf("32767 %s -1 = %d, want -32767", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("32767 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 32767 {
-		t.Errorf("32767 %s 1 = %d, want 32767", "*", r)
-	}
-	y = 32766
-	r = x * y
-	if r != -32766 {
-		t.Errorf("32767 %s 32766 = %d, want -32766", "*", r)
-	}
-	y = 32767
-	r = x * y
-	if r != 1 {
-		t.Errorf("32767 %s 32767 = %d, want 1", "*", r)
-	}
-}
-func TestConstFoldint16mod(t *testing.T) {
-	var x, y, r int16
-	x = -32768
-	y = -32768
-	r = x % y
-	if r != 0 {
-		t.Errorf("-32768 %s -32768 = %d, want 0", "%", r)
-	}
-	y = -32767
-	r = x % y
-	if r != -1 {
-		t.Errorf("-32768 %s -32767 = %d, want -1", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-32768 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-32768 %s 1 = %d, want 0", "%", r)
-	}
-	y = 32766
-	r = x % y
-	if r != -2 {
-		t.Errorf("-32768 %s 32766 = %d, want -2", "%", r)
-	}
-	y = 32767
-	r = x % y
-	if r != -1 {
-		t.Errorf("-32768 %s 32767 = %d, want -1", "%", r)
-	}
-	x = -32767
-	y = -32768
-	r = x % y
-	if r != -32767 {
-		t.Errorf("-32767 %s -32768 = %d, want -32767", "%", r)
-	}
-	y = -32767
-	r = x % y
-	if r != 0 {
-		t.Errorf("-32767 %s -32767 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-32767 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-32767 %s 1 = %d, want 0", "%", r)
-	}
-	y = 32766
-	r = x % y
-	if r != -1 {
-		t.Errorf("-32767 %s 32766 = %d, want -1", "%", r)
-	}
-	y = 32767
-	r = x % y
-	if r != 0 {
-		t.Errorf("-32767 %s 32767 = %d, want 0", "%", r)
-	}
-	x = -1
-	y = -32768
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s -32768 = %d, want -1", "%", r)
-	}
-	y = -32767
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s -32767 = %d, want -1", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-1 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-1 %s 1 = %d, want 0", "%", r)
-	}
-	y = 32766
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s 32766 = %d, want -1", "%", r)
-	}
-	y = 32767
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s 32767 = %d, want -1", "%", r)
-	}
-	x = 0
-	y = -32768
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -32768 = %d, want 0", "%", r)
-	}
-	y = -32767
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -32767 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "%", r)
-	}
-	y = 32766
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 32766 = %d, want 0", "%", r)
-	}
-	y = 32767
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 32767 = %d, want 0", "%", r)
-	}
-	x = 1
-	y = -32768
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s -32768 = %d, want 1", "%", r)
-	}
-	y = -32767
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s -32767 = %d, want 1", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("1 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "%", r)
-	}
-	y = 32766
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 32766 = %d, want 1", "%", r)
-	}
-	y = 32767
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 32767 = %d, want 1", "%", r)
-	}
-	x = 32766
-	y = -32768
-	r = x % y
-	if r != 32766 {
-		t.Errorf("32766 %s -32768 = %d, want 32766", "%", r)
-	}
-	y = -32767
-	r = x % y
-	if r != 32766 {
-		t.Errorf("32766 %s -32767 = %d, want 32766", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("32766 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("32766 %s 1 = %d, want 0", "%", r)
-	}
-	y = 32766
-	r = x % y
-	if r != 0 {
-		t.Errorf("32766 %s 32766 = %d, want 0", "%", r)
-	}
-	y = 32767
-	r = x % y
-	if r != 32766 {
-		t.Errorf("32766 %s 32767 = %d, want 32766", "%", r)
-	}
-	x = 32767
-	y = -32768
-	r = x % y
-	if r != 32767 {
-		t.Errorf("32767 %s -32768 = %d, want 32767", "%", r)
-	}
-	y = -32767
-	r = x % y
-	if r != 0 {
-		t.Errorf("32767 %s -32767 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("32767 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("32767 %s 1 = %d, want 0", "%", r)
-	}
-	y = 32766
-	r = x % y
-	if r != 1 {
-		t.Errorf("32767 %s 32766 = %d, want 1", "%", r)
-	}
-	y = 32767
-	r = x % y
-	if r != 0 {
-		t.Errorf("32767 %s 32767 = %d, want 0", "%", r)
-	}
-}
-func TestConstFolduint8add(t *testing.T) {
-	var x, y, r uint8
-	x = 0
-	y = 0
-	r = x + y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 1 {
-		t.Errorf("0 %s 1 = %d, want 1", "+", r)
-	}
-	y = 255
-	r = x + y
-	if r != 255 {
-		t.Errorf("0 %s 255 = %d, want 255", "+", r)
-	}
-	x = 1
-	y = 0
-	r = x + y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "+", r)
-	}
-	y = 255
-	r = x + y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", "+", r)
-	}
-	x = 255
-	y = 0
-	r = x + y
-	if r != 255 {
-		t.Errorf("255 %s 0 = %d, want 255", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 0 {
-		t.Errorf("255 %s 1 = %d, want 0", "+", r)
-	}
-	y = 255
-	r = x + y
-	if r != 254 {
-		t.Errorf("255 %s 255 = %d, want 254", "+", r)
-	}
-}
-func TestConstFolduint8sub(t *testing.T) {
-	var x, y, r uint8
-	x = 0
-	y = 0
-	r = x - y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 255 {
-		t.Errorf("0 %s 1 = %d, want 255", "-", r)
-	}
-	y = 255
-	r = x - y
-	if r != 1 {
-		t.Errorf("0 %s 255 = %d, want 1", "-", r)
-	}
-	x = 1
-	y = 0
-	r = x - y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "-", r)
-	}
-	y = 255
-	r = x - y
-	if r != 2 {
-		t.Errorf("1 %s 255 = %d, want 2", "-", r)
-	}
-	x = 255
-	y = 0
-	r = x - y
-	if r != 255 {
-		t.Errorf("255 %s 0 = %d, want 255", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 254 {
-		t.Errorf("255 %s 1 = %d, want 254", "-", r)
-	}
-	y = 255
-	r = x - y
-	if r != 0 {
-		t.Errorf("255 %s 255 = %d, want 0", "-", r)
-	}
-}
-func TestConstFolduint8div(t *testing.T) {
-	var x, y, r uint8
-	x = 0
-	y = 1
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "/", r)
-	}
-	y = 255
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", "/", r)
-	}
-	x = 1
-	y = 1
-	r = x / y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "/", r)
-	}
-	y = 255
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", "/", r)
-	}
-	x = 255
-	y = 1
-	r = x / y
-	if r != 255 {
-		t.Errorf("255 %s 1 = %d, want 255", "/", r)
-	}
-	y = 255
-	r = x / y
-	if r != 1 {
-		t.Errorf("255 %s 255 = %d, want 1", "/", r)
-	}
-}
-func TestConstFolduint8mul(t *testing.T) {
-	var x, y, r uint8
-	x = 0
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "*", r)
-	}
-	y = 255
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", "*", r)
-	}
-	x = 1
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("1 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "*", r)
-	}
-	y = 255
-	r = x * y
-	if r != 255 {
-		t.Errorf("1 %s 255 = %d, want 255", "*", r)
-	}
-	x = 255
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("255 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 255 {
-		t.Errorf("255 %s 1 = %d, want 255", "*", r)
-	}
-	y = 255
-	r = x * y
-	if r != 1 {
-		t.Errorf("255 %s 255 = %d, want 1", "*", r)
-	}
-}
-func TestConstFolduint8mod(t *testing.T) {
-	var x, y, r uint8
-	x = 0
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "%", r)
-	}
-	y = 255
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", "%", r)
-	}
-	x = 1
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "%", r)
-	}
-	y = 255
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 255 = %d, want 1", "%", r)
-	}
-	x = 255
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("255 %s 1 = %d, want 0", "%", r)
-	}
-	y = 255
-	r = x % y
-	if r != 0 {
-		t.Errorf("255 %s 255 = %d, want 0", "%", r)
-	}
-}
-func TestConstFoldint8add(t *testing.T) {
-	var x, y, r int8
-	x = -128
-	y = -128
-	r = x + y
-	if r != 0 {
-		t.Errorf("-128 %s -128 = %d, want 0", "+", r)
-	}
-	y = -127
-	r = x + y
-	if r != 1 {
-		t.Errorf("-128 %s -127 = %d, want 1", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 127 {
-		t.Errorf("-128 %s -1 = %d, want 127", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -128 {
-		t.Errorf("-128 %s 0 = %d, want -128", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -127 {
-		t.Errorf("-128 %s 1 = %d, want -127", "+", r)
-	}
-	y = 126
-	r = x + y
-	if r != -2 {
-		t.Errorf("-128 %s 126 = %d, want -2", "+", r)
-	}
-	y = 127
-	r = x + y
-	if r != -1 {
-		t.Errorf("-128 %s 127 = %d, want -1", "+", r)
-	}
-	x = -127
-	y = -128
-	r = x + y
-	if r != 1 {
-		t.Errorf("-127 %s -128 = %d, want 1", "+", r)
-	}
-	y = -127
-	r = x + y
-	if r != 2 {
-		t.Errorf("-127 %s -127 = %d, want 2", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -128 {
-		t.Errorf("-127 %s -1 = %d, want -128", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -127 {
-		t.Errorf("-127 %s 0 = %d, want -127", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -126 {
-		t.Errorf("-127 %s 1 = %d, want -126", "+", r)
-	}
-	y = 126
-	r = x + y
-	if r != -1 {
-		t.Errorf("-127 %s 126 = %d, want -1", "+", r)
-	}
-	y = 127
-	r = x + y
-	if r != 0 {
-		t.Errorf("-127 %s 127 = %d, want 0", "+", r)
-	}
-	x = -1
-	y = -128
-	r = x + y
-	if r != 127 {
-		t.Errorf("-1 %s -128 = %d, want 127", "+", r)
-	}
-	y = -127
-	r = x + y
-	if r != -128 {
-		t.Errorf("-1 %s -127 = %d, want -128", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -2 {
-		t.Errorf("-1 %s -1 = %d, want -2", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 0 {
-		t.Errorf("-1 %s 1 = %d, want 0", "+", r)
-	}
-	y = 126
-	r = x + y
-	if r != 125 {
-		t.Errorf("-1 %s 126 = %d, want 125", "+", r)
-	}
-	y = 127
-	r = x + y
-	if r != 126 {
-		t.Errorf("-1 %s 127 = %d, want 126", "+", r)
-	}
-	x = 0
-	y = -128
-	r = x + y
-	if r != -128 {
-		t.Errorf("0 %s -128 = %d, want -128", "+", r)
-	}
-	y = -127
-	r = x + y
-	if r != -127 {
-		t.Errorf("0 %s -127 = %d, want -127", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != -1 {
-		t.Errorf("0 %s -1 = %d, want -1", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 1 {
-		t.Errorf("0 %s 1 = %d, want 1", "+", r)
-	}
-	y = 126
-	r = x + y
-	if r != 126 {
-		t.Errorf("0 %s 126 = %d, want 126", "+", r)
-	}
-	y = 127
-	r = x + y
-	if r != 127 {
-		t.Errorf("0 %s 127 = %d, want 127", "+", r)
-	}
-	x = 1
-	y = -128
-	r = x + y
-	if r != -127 {
-		t.Errorf("1 %s -128 = %d, want -127", "+", r)
-	}
-	y = -127
-	r = x + y
-	if r != -126 {
-		t.Errorf("1 %s -127 = %d, want -126", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 0 {
-		t.Errorf("1 %s -1 = %d, want 0", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "+", r)
-	}
-	y = 126
-	r = x + y
-	if r != 127 {
-		t.Errorf("1 %s 126 = %d, want 127", "+", r)
-	}
-	y = 127
-	r = x + y
-	if r != -128 {
-		t.Errorf("1 %s 127 = %d, want -128", "+", r)
-	}
-	x = 126
-	y = -128
-	r = x + y
-	if r != -2 {
-		t.Errorf("126 %s -128 = %d, want -2", "+", r)
-	}
-	y = -127
-	r = x + y
-	if r != -1 {
-		t.Errorf("126 %s -127 = %d, want -1", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 125 {
-		t.Errorf("126 %s -1 = %d, want 125", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 126 {
-		t.Errorf("126 %s 0 = %d, want 126", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != 127 {
-		t.Errorf("126 %s 1 = %d, want 127", "+", r)
-	}
-	y = 126
-	r = x + y
-	if r != -4 {
-		t.Errorf("126 %s 126 = %d, want -4", "+", r)
-	}
-	y = 127
-	r = x + y
-	if r != -3 {
-		t.Errorf("126 %s 127 = %d, want -3", "+", r)
-	}
-	x = 127
-	y = -128
-	r = x + y
-	if r != -1 {
-		t.Errorf("127 %s -128 = %d, want -1", "+", r)
-	}
-	y = -127
-	r = x + y
-	if r != 0 {
-		t.Errorf("127 %s -127 = %d, want 0", "+", r)
-	}
-	y = -1
-	r = x + y
-	if r != 126 {
-		t.Errorf("127 %s -1 = %d, want 126", "+", r)
-	}
-	y = 0
-	r = x + y
-	if r != 127 {
-		t.Errorf("127 %s 0 = %d, want 127", "+", r)
-	}
-	y = 1
-	r = x + y
-	if r != -128 {
-		t.Errorf("127 %s 1 = %d, want -128", "+", r)
-	}
-	y = 126
-	r = x + y
-	if r != -3 {
-		t.Errorf("127 %s 126 = %d, want -3", "+", r)
-	}
-	y = 127
-	r = x + y
-	if r != -2 {
-		t.Errorf("127 %s 127 = %d, want -2", "+", r)
-	}
-}
-func TestConstFoldint8sub(t *testing.T) {
-	var x, y, r int8
-	x = -128
-	y = -128
-	r = x - y
-	if r != 0 {
-		t.Errorf("-128 %s -128 = %d, want 0", "-", r)
-	}
-	y = -127
-	r = x - y
-	if r != -1 {
-		t.Errorf("-128 %s -127 = %d, want -1", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -127 {
-		t.Errorf("-128 %s -1 = %d, want -127", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -128 {
-		t.Errorf("-128 %s 0 = %d, want -128", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 127 {
-		t.Errorf("-128 %s 1 = %d, want 127", "-", r)
-	}
-	y = 126
-	r = x - y
-	if r != 2 {
-		t.Errorf("-128 %s 126 = %d, want 2", "-", r)
-	}
-	y = 127
-	r = x - y
-	if r != 1 {
-		t.Errorf("-128 %s 127 = %d, want 1", "-", r)
-	}
-	x = -127
-	y = -128
-	r = x - y
-	if r != 1 {
-		t.Errorf("-127 %s -128 = %d, want 1", "-", r)
-	}
-	y = -127
-	r = x - y
-	if r != 0 {
-		t.Errorf("-127 %s -127 = %d, want 0", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -126 {
-		t.Errorf("-127 %s -1 = %d, want -126", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -127 {
-		t.Errorf("-127 %s 0 = %d, want -127", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -128 {
-		t.Errorf("-127 %s 1 = %d, want -128", "-", r)
-	}
-	y = 126
-	r = x - y
-	if r != 3 {
-		t.Errorf("-127 %s 126 = %d, want 3", "-", r)
-	}
-	y = 127
-	r = x - y
-	if r != 2 {
-		t.Errorf("-127 %s 127 = %d, want 2", "-", r)
-	}
-	x = -1
-	y = -128
-	r = x - y
-	if r != 127 {
-		t.Errorf("-1 %s -128 = %d, want 127", "-", r)
-	}
-	y = -127
-	r = x - y
-	if r != 126 {
-		t.Errorf("-1 %s -127 = %d, want 126", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 0 {
-		t.Errorf("-1 %s -1 = %d, want 0", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "-", r)
-	}
-	y = 126
-	r = x - y
-	if r != -127 {
-		t.Errorf("-1 %s 126 = %d, want -127", "-", r)
-	}
-	y = 127
-	r = x - y
-	if r != -128 {
-		t.Errorf("-1 %s 127 = %d, want -128", "-", r)
-	}
-	x = 0
-	y = -128
-	r = x - y
-	if r != -128 {
-		t.Errorf("0 %s -128 = %d, want -128", "-", r)
-	}
-	y = -127
-	r = x - y
-	if r != 127 {
-		t.Errorf("0 %s -127 = %d, want 127", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 1 {
-		t.Errorf("0 %s -1 = %d, want 1", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != -1 {
-		t.Errorf("0 %s 1 = %d, want -1", "-", r)
-	}
-	y = 126
-	r = x - y
-	if r != -126 {
-		t.Errorf("0 %s 126 = %d, want -126", "-", r)
-	}
-	y = 127
-	r = x - y
-	if r != -127 {
-		t.Errorf("0 %s 127 = %d, want -127", "-", r)
-	}
-	x = 1
-	y = -128
-	r = x - y
-	if r != -127 {
-		t.Errorf("1 %s -128 = %d, want -127", "-", r)
-	}
-	y = -127
-	r = x - y
-	if r != -128 {
-		t.Errorf("1 %s -127 = %d, want -128", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 2 {
-		t.Errorf("1 %s -1 = %d, want 2", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "-", r)
-	}
-	y = 126
-	r = x - y
-	if r != -125 {
-		t.Errorf("1 %s 126 = %d, want -125", "-", r)
-	}
-	y = 127
-	r = x - y
-	if r != -126 {
-		t.Errorf("1 %s 127 = %d, want -126", "-", r)
-	}
-	x = 126
-	y = -128
-	r = x - y
-	if r != -2 {
-		t.Errorf("126 %s -128 = %d, want -2", "-", r)
-	}
-	y = -127
-	r = x - y
-	if r != -3 {
-		t.Errorf("126 %s -127 = %d, want -3", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != 127 {
-		t.Errorf("126 %s -1 = %d, want 127", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 126 {
-		t.Errorf("126 %s 0 = %d, want 126", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 125 {
-		t.Errorf("126 %s 1 = %d, want 125", "-", r)
-	}
-	y = 126
-	r = x - y
-	if r != 0 {
-		t.Errorf("126 %s 126 = %d, want 0", "-", r)
-	}
-	y = 127
-	r = x - y
-	if r != -1 {
-		t.Errorf("126 %s 127 = %d, want -1", "-", r)
-	}
-	x = 127
-	y = -128
-	r = x - y
-	if r != -1 {
-		t.Errorf("127 %s -128 = %d, want -1", "-", r)
-	}
-	y = -127
-	r = x - y
-	if r != -2 {
-		t.Errorf("127 %s -127 = %d, want -2", "-", r)
-	}
-	y = -1
-	r = x - y
-	if r != -128 {
-		t.Errorf("127 %s -1 = %d, want -128", "-", r)
-	}
-	y = 0
-	r = x - y
-	if r != 127 {
-		t.Errorf("127 %s 0 = %d, want 127", "-", r)
-	}
-	y = 1
-	r = x - y
-	if r != 126 {
-		t.Errorf("127 %s 1 = %d, want 126", "-", r)
-	}
-	y = 126
-	r = x - y
-	if r != 1 {
-		t.Errorf("127 %s 126 = %d, want 1", "-", r)
-	}
-	y = 127
-	r = x - y
-	if r != 0 {
-		t.Errorf("127 %s 127 = %d, want 0", "-", r)
-	}
-}
-func TestConstFoldint8div(t *testing.T) {
-	var x, y, r int8
-	x = -128
-	y = -128
-	r = x / y
-	if r != 1 {
-		t.Errorf("-128 %s -128 = %d, want 1", "/", r)
-	}
-	y = -127
-	r = x / y
-	if r != 1 {
-		t.Errorf("-128 %s -127 = %d, want 1", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -128 {
-		t.Errorf("-128 %s -1 = %d, want -128", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -128 {
-		t.Errorf("-128 %s 1 = %d, want -128", "/", r)
-	}
-	y = 126
-	r = x / y
-	if r != -1 {
-		t.Errorf("-128 %s 126 = %d, want -1", "/", r)
-	}
-	y = 127
-	r = x / y
-	if r != -1 {
-		t.Errorf("-128 %s 127 = %d, want -1", "/", r)
-	}
-	x = -127
-	y = -128
-	r = x / y
-	if r != 0 {
-		t.Errorf("-127 %s -128 = %d, want 0", "/", r)
-	}
-	y = -127
-	r = x / y
-	if r != 1 {
-		t.Errorf("-127 %s -127 = %d, want 1", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 127 {
-		t.Errorf("-127 %s -1 = %d, want 127", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -127 {
-		t.Errorf("-127 %s 1 = %d, want -127", "/", r)
-	}
-	y = 126
-	r = x / y
-	if r != -1 {
-		t.Errorf("-127 %s 126 = %d, want -1", "/", r)
-	}
-	y = 127
-	r = x / y
-	if r != -1 {
-		t.Errorf("-127 %s 127 = %d, want -1", "/", r)
-	}
-	x = -1
-	y = -128
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s -128 = %d, want 0", "/", r)
-	}
-	y = -127
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s -127 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 1 {
-		t.Errorf("-1 %s -1 = %d, want 1", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", "/", r)
-	}
-	y = 126
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s 126 = %d, want 0", "/", r)
-	}
-	y = 127
-	r = x / y
-	if r != 0 {
-		t.Errorf("-1 %s 127 = %d, want 0", "/", r)
-	}
-	x = 0
-	y = -128
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -128 = %d, want 0", "/", r)
-	}
-	y = -127
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -127 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s -1 = %d, want 0", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "/", r)
-	}
-	y = 126
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 126 = %d, want 0", "/", r)
-	}
-	y = 127
-	r = x / y
-	if r != 0 {
-		t.Errorf("0 %s 127 = %d, want 0", "/", r)
-	}
-	x = 1
-	y = -128
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s -128 = %d, want 0", "/", r)
-	}
-	y = -127
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s -127 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -1 {
-		t.Errorf("1 %s -1 = %d, want -1", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "/", r)
-	}
-	y = 126
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 126 = %d, want 0", "/", r)
-	}
-	y = 127
-	r = x / y
-	if r != 0 {
-		t.Errorf("1 %s 127 = %d, want 0", "/", r)
-	}
-	x = 126
-	y = -128
-	r = x / y
-	if r != 0 {
-		t.Errorf("126 %s -128 = %d, want 0", "/", r)
-	}
-	y = -127
-	r = x / y
-	if r != 0 {
-		t.Errorf("126 %s -127 = %d, want 0", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -126 {
-		t.Errorf("126 %s -1 = %d, want -126", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 126 {
-		t.Errorf("126 %s 1 = %d, want 126", "/", r)
-	}
-	y = 126
-	r = x / y
-	if r != 1 {
-		t.Errorf("126 %s 126 = %d, want 1", "/", r)
-	}
-	y = 127
-	r = x / y
-	if r != 0 {
-		t.Errorf("126 %s 127 = %d, want 0", "/", r)
-	}
-	x = 127
-	y = -128
-	r = x / y
-	if r != 0 {
-		t.Errorf("127 %s -128 = %d, want 0", "/", r)
-	}
-	y = -127
-	r = x / y
-	if r != -1 {
-		t.Errorf("127 %s -127 = %d, want -1", "/", r)
-	}
-	y = -1
-	r = x / y
-	if r != -127 {
-		t.Errorf("127 %s -1 = %d, want -127", "/", r)
-	}
-	y = 1
-	r = x / y
-	if r != 127 {
-		t.Errorf("127 %s 1 = %d, want 127", "/", r)
-	}
-	y = 126
-	r = x / y
-	if r != 1 {
-		t.Errorf("127 %s 126 = %d, want 1", "/", r)
-	}
-	y = 127
-	r = x / y
-	if r != 1 {
-		t.Errorf("127 %s 127 = %d, want 1", "/", r)
-	}
-}
-func TestConstFoldint8mul(t *testing.T) {
-	var x, y, r int8
-	x = -128
-	y = -128
-	r = x * y
-	if r != 0 {
-		t.Errorf("-128 %s -128 = %d, want 0", "*", r)
-	}
-	y = -127
-	r = x * y
-	if r != -128 {
-		t.Errorf("-128 %s -127 = %d, want -128", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -128 {
-		t.Errorf("-128 %s -1 = %d, want -128", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-128 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -128 {
-		t.Errorf("-128 %s 1 = %d, want -128", "*", r)
-	}
-	y = 126
-	r = x * y
-	if r != 0 {
-		t.Errorf("-128 %s 126 = %d, want 0", "*", r)
-	}
-	y = 127
-	r = x * y
-	if r != -128 {
-		t.Errorf("-128 %s 127 = %d, want -128", "*", r)
-	}
-	x = -127
-	y = -128
-	r = x * y
-	if r != -128 {
-		t.Errorf("-127 %s -128 = %d, want -128", "*", r)
-	}
-	y = -127
-	r = x * y
-	if r != 1 {
-		t.Errorf("-127 %s -127 = %d, want 1", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 127 {
-		t.Errorf("-127 %s -1 = %d, want 127", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-127 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -127 {
-		t.Errorf("-127 %s 1 = %d, want -127", "*", r)
-	}
-	y = 126
-	r = x * y
-	if r != 126 {
-		t.Errorf("-127 %s 126 = %d, want 126", "*", r)
-	}
-	y = 127
-	r = x * y
-	if r != -1 {
-		t.Errorf("-127 %s 127 = %d, want -1", "*", r)
-	}
-	x = -1
-	y = -128
-	r = x * y
-	if r != -128 {
-		t.Errorf("-1 %s -128 = %d, want -128", "*", r)
-	}
-	y = -127
-	r = x * y
-	if r != 127 {
-		t.Errorf("-1 %s -127 = %d, want 127", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 1 {
-		t.Errorf("-1 %s -1 = %d, want 1", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("-1 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", "*", r)
-	}
-	y = 126
-	r = x * y
-	if r != -126 {
-		t.Errorf("-1 %s 126 = %d, want -126", "*", r)
-	}
-	y = 127
-	r = x * y
-	if r != -127 {
-		t.Errorf("-1 %s 127 = %d, want -127", "*", r)
-	}
-	x = 0
-	y = -128
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -128 = %d, want 0", "*", r)
-	}
-	y = -127
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -127 = %d, want 0", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s -1 = %d, want 0", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "*", r)
-	}
-	y = 126
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 126 = %d, want 0", "*", r)
-	}
-	y = 127
-	r = x * y
-	if r != 0 {
-		t.Errorf("0 %s 127 = %d, want 0", "*", r)
-	}
-	x = 1
-	y = -128
-	r = x * y
-	if r != -128 {
-		t.Errorf("1 %s -128 = %d, want -128", "*", r)
-	}
-	y = -127
-	r = x * y
-	if r != -127 {
-		t.Errorf("1 %s -127 = %d, want -127", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -1 {
-		t.Errorf("1 %s -1 = %d, want -1", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("1 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 1 {
-		t.Errorf("1 %s 1 = %d, want 1", "*", r)
-	}
-	y = 126
-	r = x * y
-	if r != 126 {
-		t.Errorf("1 %s 126 = %d, want 126", "*", r)
-	}
-	y = 127
-	r = x * y
-	if r != 127 {
-		t.Errorf("1 %s 127 = %d, want 127", "*", r)
-	}
-	x = 126
-	y = -128
-	r = x * y
-	if r != 0 {
-		t.Errorf("126 %s -128 = %d, want 0", "*", r)
-	}
-	y = -127
-	r = x * y
-	if r != 126 {
-		t.Errorf("126 %s -127 = %d, want 126", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -126 {
-		t.Errorf("126 %s -1 = %d, want -126", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("126 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 126 {
-		t.Errorf("126 %s 1 = %d, want 126", "*", r)
-	}
-	y = 126
-	r = x * y
-	if r != 4 {
-		t.Errorf("126 %s 126 = %d, want 4", "*", r)
-	}
-	y = 127
-	r = x * y
-	if r != -126 {
-		t.Errorf("126 %s 127 = %d, want -126", "*", r)
-	}
-	x = 127
-	y = -128
-	r = x * y
-	if r != -128 {
-		t.Errorf("127 %s -128 = %d, want -128", "*", r)
-	}
-	y = -127
-	r = x * y
-	if r != -1 {
-		t.Errorf("127 %s -127 = %d, want -1", "*", r)
-	}
-	y = -1
-	r = x * y
-	if r != -127 {
-		t.Errorf("127 %s -1 = %d, want -127", "*", r)
-	}
-	y = 0
-	r = x * y
-	if r != 0 {
-		t.Errorf("127 %s 0 = %d, want 0", "*", r)
-	}
-	y = 1
-	r = x * y
-	if r != 127 {
-		t.Errorf("127 %s 1 = %d, want 127", "*", r)
-	}
-	y = 126
-	r = x * y
-	if r != -126 {
-		t.Errorf("127 %s 126 = %d, want -126", "*", r)
-	}
-	y = 127
-	r = x * y
-	if r != 1 {
-		t.Errorf("127 %s 127 = %d, want 1", "*", r)
-	}
-}
-func TestConstFoldint8mod(t *testing.T) {
-	var x, y, r int8
-	x = -128
-	y = -128
-	r = x % y
-	if r != 0 {
-		t.Errorf("-128 %s -128 = %d, want 0", "%", r)
-	}
-	y = -127
-	r = x % y
-	if r != -1 {
-		t.Errorf("-128 %s -127 = %d, want -1", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-128 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-128 %s 1 = %d, want 0", "%", r)
-	}
-	y = 126
-	r = x % y
-	if r != -2 {
-		t.Errorf("-128 %s 126 = %d, want -2", "%", r)
-	}
-	y = 127
-	r = x % y
-	if r != -1 {
-		t.Errorf("-128 %s 127 = %d, want -1", "%", r)
-	}
-	x = -127
-	y = -128
-	r = x % y
-	if r != -127 {
-		t.Errorf("-127 %s -128 = %d, want -127", "%", r)
-	}
-	y = -127
-	r = x % y
-	if r != 0 {
-		t.Errorf("-127 %s -127 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-127 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-127 %s 1 = %d, want 0", "%", r)
-	}
-	y = 126
-	r = x % y
-	if r != -1 {
-		t.Errorf("-127 %s 126 = %d, want -1", "%", r)
-	}
-	y = 127
-	r = x % y
-	if r != 0 {
-		t.Errorf("-127 %s 127 = %d, want 0", "%", r)
-	}
-	x = -1
-	y = -128
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s -128 = %d, want -1", "%", r)
-	}
-	y = -127
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s -127 = %d, want -1", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-1 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("-1 %s 1 = %d, want 0", "%", r)
-	}
-	y = 126
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s 126 = %d, want -1", "%", r)
-	}
-	y = 127
-	r = x % y
-	if r != -1 {
-		t.Errorf("-1 %s 127 = %d, want -1", "%", r)
-	}
-	x = 0
-	y = -128
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -128 = %d, want 0", "%", r)
-	}
-	y = -127
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -127 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "%", r)
-	}
-	y = 126
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 126 = %d, want 0", "%", r)
-	}
-	y = 127
-	r = x % y
-	if r != 0 {
-		t.Errorf("0 %s 127 = %d, want 0", "%", r)
-	}
-	x = 1
-	y = -128
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s -128 = %d, want 1", "%", r)
-	}
-	y = -127
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s -127 = %d, want 1", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("1 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", "%", r)
-	}
-	y = 126
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 126 = %d, want 1", "%", r)
-	}
-	y = 127
-	r = x % y
-	if r != 1 {
-		t.Errorf("1 %s 127 = %d, want 1", "%", r)
-	}
-	x = 126
-	y = -128
-	r = x % y
-	if r != 126 {
-		t.Errorf("126 %s -128 = %d, want 126", "%", r)
-	}
-	y = -127
-	r = x % y
-	if r != 126 {
-		t.Errorf("126 %s -127 = %d, want 126", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("126 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("126 %s 1 = %d, want 0", "%", r)
-	}
-	y = 126
-	r = x % y
-	if r != 0 {
-		t.Errorf("126 %s 126 = %d, want 0", "%", r)
-	}
-	y = 127
-	r = x % y
-	if r != 126 {
-		t.Errorf("126 %s 127 = %d, want 126", "%", r)
-	}
-	x = 127
-	y = -128
-	r = x % y
-	if r != 127 {
-		t.Errorf("127 %s -128 = %d, want 127", "%", r)
-	}
-	y = -127
-	r = x % y
-	if r != 0 {
-		t.Errorf("127 %s -127 = %d, want 0", "%", r)
-	}
-	y = -1
-	r = x % y
-	if r != 0 {
-		t.Errorf("127 %s -1 = %d, want 0", "%", r)
-	}
-	y = 1
-	r = x % y
-	if r != 0 {
-		t.Errorf("127 %s 1 = %d, want 0", "%", r)
-	}
-	y = 126
-	r = x % y
-	if r != 1 {
-		t.Errorf("127 %s 126 = %d, want 1", "%", r)
-	}
-	y = 127
-	r = x % y
-	if r != 0 {
-		t.Errorf("127 %s 127 = %d, want 0", "%", r)
-	}
-}
-func TestConstFolduint64uint64lsh(t *testing.T) {
-	var x, r uint64
-	var y uint64
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x << y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 8589934592 {
-		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 18446744073709551615
-	y = 0
-	r = x << y
-	if r != 18446744073709551615 {
-		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 18446744073709551614 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551614", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint64uint64rsh(t *testing.T) {
-	var x, r uint64
-	var y uint64
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x >> y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 2147483648 {
-		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 18446744073709551615
-	y = 0
-	r = x >> y
-	if r != 18446744073709551615 {
-		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 9223372036854775807 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 9223372036854775807", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint64uint32lsh(t *testing.T) {
-	var x, r uint64
-	var y uint32
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x << y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 8589934592 {
-		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 18446744073709551615
-	y = 0
-	r = x << y
-	if r != 18446744073709551615 {
-		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 18446744073709551614 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551614", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 4294967295 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint64uint32rsh(t *testing.T) {
-	var x, r uint64
-	var y uint32
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x >> y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 2147483648 {
-		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 18446744073709551615
-	y = 0
-	r = x >> y
-	if r != 18446744073709551615 {
-		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 9223372036854775807 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 9223372036854775807", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 4294967295 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint64uint16lsh(t *testing.T) {
-	var x, r uint64
-	var y uint16
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x << y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 8589934592 {
-		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967296 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 18446744073709551615
-	y = 0
-	r = x << y
-	if r != 18446744073709551615 {
-		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 18446744073709551614 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551614", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 65535 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint64uint16rsh(t *testing.T) {
-	var x, r uint64
-	var y uint16
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x >> y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 2147483648 {
-		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967296 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 18446744073709551615
-	y = 0
-	r = x >> y
-	if r != 18446744073709551615 {
-		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 9223372036854775807 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 9223372036854775807", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 65535 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint64uint8lsh(t *testing.T) {
-	var x, r uint64
-	var y uint8
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x << y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 8589934592 {
-		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967296 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 18446744073709551615
-	y = 0
-	r = x << y
-	if r != 18446744073709551615 {
-		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 18446744073709551614 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551614", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 255 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint64uint8rsh(t *testing.T) {
-	var x, r uint64
-	var y uint8
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x >> y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 2147483648 {
-		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967296 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 18446744073709551615
-	y = 0
-	r = x >> y
-	if r != 18446744073709551615 {
-		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 9223372036854775807 {
-		t.Errorf("18446744073709551615 %s 1 = %d, want 9223372036854775807", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("18446744073709551615 %s 255 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint64uint64lsh(t *testing.T) {
-	var x, r int64
-	var y uint64
-	x = -9223372036854775808
-	y = 0
-	r = x << y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = -9223372036854775807
-	y = 0
-	r = x << y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = -4294967296
-	y = 0
-	r = x << y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -8589934592 {
-		t.Errorf("-4294967296 %s 1 = %d, want -8589934592", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-4294967296 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-4294967296 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x << y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 8589934592 {
-		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 9223372036854775806
-	y = 0
-	r = x << y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -4 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want -4", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 9223372036854775807
-	y = 0
-	r = x << y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint64uint64rsh(t *testing.T) {
-	var x, r int64
-	var y uint64
-	x = -9223372036854775808
-	y = 0
-	r = x >> y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -4611686018427387904 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want -4611686018427387904", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-9223372036854775808 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = -9223372036854775807
-	y = 0
-	r = x >> y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -4611686018427387904 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want -4611686018427387904", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-9223372036854775807 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = -4294967296
-	y = 0
-	r = x >> y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -2147483648 {
-		t.Errorf("-4294967296 %s 1 = %d, want -2147483648", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-4294967296 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-4294967296 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x >> y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 2147483648 {
-		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 9223372036854775806
-	y = 0
-	r = x >> y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 4611686018427387903 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want 4611686018427387903", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 9223372036854775807
-	y = 0
-	r = x >> y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 4611686018427387903 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want 4611686018427387903", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint64uint32lsh(t *testing.T) {
-	var x, r int64
-	var y uint32
-	x = -9223372036854775808
-	y = 0
-	r = x << y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = -9223372036854775807
-	y = 0
-	r = x << y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = -4294967296
-	y = 0
-	r = x << y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -8589934592 {
-		t.Errorf("-4294967296 %s 1 = %d, want -8589934592", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-4294967296 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x << y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 8589934592 {
-		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 9223372036854775806
-	y = 0
-	r = x << y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -4 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want -4", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 9223372036854775807
-	y = 0
-	r = x << y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 4294967295 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint64uint32rsh(t *testing.T) {
-	var x, r int64
-	var y uint32
-	x = -9223372036854775808
-	y = 0
-	r = x >> y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -4611686018427387904 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want -4611686018427387904", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-9223372036854775808 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = -9223372036854775807
-	y = 0
-	r = x >> y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -4611686018427387904 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want -4611686018427387904", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-9223372036854775807 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = -4294967296
-	y = 0
-	r = x >> y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -2147483648 {
-		t.Errorf("-4294967296 %s 1 = %d, want -2147483648", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-4294967296 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x >> y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 2147483648 {
-		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967296 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 9223372036854775806
-	y = 0
-	r = x >> y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 4611686018427387903 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want 4611686018427387903", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 9223372036854775807
-	y = 0
-	r = x >> y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 4611686018427387903 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want 4611686018427387903", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 4294967295 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint64uint16lsh(t *testing.T) {
-	var x, r int64
-	var y uint16
-	x = -9223372036854775808
-	y = 0
-	r = x << y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = -9223372036854775807
-	y = 0
-	r = x << y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = -4294967296
-	y = 0
-	r = x << y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -8589934592 {
-		t.Errorf("-4294967296 %s 1 = %d, want -8589934592", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-4294967296 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x << y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 8589934592 {
-		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967296 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 9223372036854775806
-	y = 0
-	r = x << y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -4 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want -4", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 9223372036854775807
-	y = 0
-	r = x << y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 65535 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint64uint16rsh(t *testing.T) {
-	var x, r int64
-	var y uint16
-	x = -9223372036854775808
-	y = 0
-	r = x >> y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -4611686018427387904 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want -4611686018427387904", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-9223372036854775808 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = -9223372036854775807
-	y = 0
-	r = x >> y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -4611686018427387904 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want -4611686018427387904", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-9223372036854775807 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = -4294967296
-	y = 0
-	r = x >> y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -2147483648 {
-		t.Errorf("-4294967296 %s 1 = %d, want -2147483648", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-4294967296 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x >> y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 2147483648 {
-		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967296 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 9223372036854775806
-	y = 0
-	r = x >> y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 4611686018427387903 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want 4611686018427387903", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 9223372036854775807
-	y = 0
-	r = x >> y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 4611686018427387903 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want 4611686018427387903", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 65535 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint64uint8lsh(t *testing.T) {
-	var x, r int64
-	var y uint8
-	x = -9223372036854775808
-	y = 0
-	r = x << y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775808 %s 255 = %d, want 0", "<<", r)
-	}
-	x = -9223372036854775807
-	y = 0
-	r = x << y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-9223372036854775807 %s 255 = %d, want 0", "<<", r)
-	}
-	x = -4294967296
-	y = 0
-	r = x << y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -8589934592 {
-		t.Errorf("-4294967296 %s 1 = %d, want -8589934592", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-4294967296 %s 255 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x << y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 8589934592 {
-		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967296 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 9223372036854775806
-	y = 0
-	r = x << y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -4 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want -4", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 9223372036854775807
-	y = 0
-	r = x << y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 255 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint64uint8rsh(t *testing.T) {
-	var x, r int64
-	var y uint8
-	x = -9223372036854775808
-	y = 0
-	r = x >> y
-	if r != -9223372036854775808 {
-		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -4611686018427387904 {
-		t.Errorf("-9223372036854775808 %s 1 = %d, want -4611686018427387904", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-9223372036854775808 %s 255 = %d, want -1", ">>", r)
-	}
-	x = -9223372036854775807
-	y = 0
-	r = x >> y
-	if r != -9223372036854775807 {
-		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -4611686018427387904 {
-		t.Errorf("-9223372036854775807 %s 1 = %d, want -4611686018427387904", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-9223372036854775807 %s 255 = %d, want -1", ">>", r)
-	}
-	x = -4294967296
-	y = 0
-	r = x >> y
-	if r != -4294967296 {
-		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -2147483648 {
-		t.Errorf("-4294967296 %s 1 = %d, want -2147483648", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-4294967296 %s 255 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 255 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 4294967296
-	y = 0
-	r = x >> y
-	if r != 4294967296 {
-		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 2147483648 {
-		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967296 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 9223372036854775806
-	y = 0
-	r = x >> y
-	if r != 9223372036854775806 {
-		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 4611686018427387903 {
-		t.Errorf("9223372036854775806 %s 1 = %d, want 4611686018427387903", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("9223372036854775806 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 9223372036854775807
-	y = 0
-	r = x >> y
-	if r != 9223372036854775807 {
-		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 4611686018427387903 {
-		t.Errorf("9223372036854775807 %s 1 = %d, want 4611686018427387903", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("9223372036854775807 %s 255 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint32uint64lsh(t *testing.T) {
-	var x, r uint32
-	var y uint64
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 4294967295
-	y = 0
-	r = x << y
-	if r != 4294967295 {
-		t.Errorf("4294967295 %s 0 = %d, want 4294967295", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 4294967294 {
-		t.Errorf("4294967295 %s 1 = %d, want 4294967294", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967295 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967295 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint32uint64rsh(t *testing.T) {
-	var x, r uint32
-	var y uint64
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 4294967295
-	y = 0
-	r = x >> y
-	if r != 4294967295 {
-		t.Errorf("4294967295 %s 0 = %d, want 4294967295", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 2147483647 {
-		t.Errorf("4294967295 %s 1 = %d, want 2147483647", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967295 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967295 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint32uint32lsh(t *testing.T) {
-	var x, r uint32
-	var y uint32
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 4294967295
-	y = 0
-	r = x << y
-	if r != 4294967295 {
-		t.Errorf("4294967295 %s 0 = %d, want 4294967295", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 4294967294 {
-		t.Errorf("4294967295 %s 1 = %d, want 4294967294", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967295 %s 4294967295 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint32uint32rsh(t *testing.T) {
-	var x, r uint32
-	var y uint32
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 4294967295
-	y = 0
-	r = x >> y
-	if r != 4294967295 {
-		t.Errorf("4294967295 %s 0 = %d, want 4294967295", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 2147483647 {
-		t.Errorf("4294967295 %s 1 = %d, want 2147483647", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967295 %s 4294967295 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint32uint16lsh(t *testing.T) {
-	var x, r uint32
-	var y uint16
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 4294967295
-	y = 0
-	r = x << y
-	if r != 4294967295 {
-		t.Errorf("4294967295 %s 0 = %d, want 4294967295", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 4294967294 {
-		t.Errorf("4294967295 %s 1 = %d, want 4294967294", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967295 %s 65535 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint32uint16rsh(t *testing.T) {
-	var x, r uint32
-	var y uint16
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 4294967295
-	y = 0
-	r = x >> y
-	if r != 4294967295 {
-		t.Errorf("4294967295 %s 0 = %d, want 4294967295", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 2147483647 {
-		t.Errorf("4294967295 %s 1 = %d, want 2147483647", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967295 %s 65535 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint32uint8lsh(t *testing.T) {
-	var x, r uint32
-	var y uint8
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 4294967295
-	y = 0
-	r = x << y
-	if r != 4294967295 {
-		t.Errorf("4294967295 %s 0 = %d, want 4294967295", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 4294967294 {
-		t.Errorf("4294967295 %s 1 = %d, want 4294967294", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("4294967295 %s 255 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint32uint8rsh(t *testing.T) {
-	var x, r uint32
-	var y uint8
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 4294967295
-	y = 0
-	r = x >> y
-	if r != 4294967295 {
-		t.Errorf("4294967295 %s 0 = %d, want 4294967295", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 2147483647 {
-		t.Errorf("4294967295 %s 1 = %d, want 2147483647", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("4294967295 %s 255 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint32uint64lsh(t *testing.T) {
-	var x, r int32
-	var y uint64
-	x = -2147483648
-	y = 0
-	r = x << y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483648 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483648 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483648 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = -2147483647
-	y = 0
-	r = x << y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-2147483647 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483647 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483647 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 2147483647
-	y = 0
-	r = x << y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s 0 = %d, want 2147483647", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("2147483647 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("2147483647 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("2147483647 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint32uint64rsh(t *testing.T) {
-	var x, r int32
-	var y uint64
-	x = -2147483648
-	y = 0
-	r = x >> y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1073741824 {
-		t.Errorf("-2147483648 %s 1 = %d, want -1073741824", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-2147483648 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-2147483648 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = -2147483647
-	y = 0
-	r = x >> y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1073741824 {
-		t.Errorf("-2147483647 %s 1 = %d, want -1073741824", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-2147483647 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-2147483647 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 2147483647
-	y = 0
-	r = x >> y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s 0 = %d, want 2147483647", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 1073741823 {
-		t.Errorf("2147483647 %s 1 = %d, want 1073741823", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("2147483647 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("2147483647 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint32uint32lsh(t *testing.T) {
-	var x, r int32
-	var y uint32
-	x = -2147483648
-	y = 0
-	r = x << y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483648 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483648 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = -2147483647
-	y = 0
-	r = x << y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-2147483647 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483647 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 2147483647
-	y = 0
-	r = x << y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s 0 = %d, want 2147483647", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("2147483647 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("2147483647 %s 4294967295 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint32uint32rsh(t *testing.T) {
-	var x, r int32
-	var y uint32
-	x = -2147483648
-	y = 0
-	r = x >> y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1073741824 {
-		t.Errorf("-2147483648 %s 1 = %d, want -1073741824", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-2147483648 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = -2147483647
-	y = 0
-	r = x >> y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1073741824 {
-		t.Errorf("-2147483647 %s 1 = %d, want -1073741824", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-2147483647 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 2147483647
-	y = 0
-	r = x >> y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s 0 = %d, want 2147483647", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 1073741823 {
-		t.Errorf("2147483647 %s 1 = %d, want 1073741823", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("2147483647 %s 4294967295 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint32uint16lsh(t *testing.T) {
-	var x, r int32
-	var y uint16
-	x = -2147483648
-	y = 0
-	r = x << y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483648 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483648 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = -2147483647
-	y = 0
-	r = x << y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-2147483647 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483647 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 2147483647
-	y = 0
-	r = x << y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s 0 = %d, want 2147483647", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("2147483647 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("2147483647 %s 65535 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint32uint16rsh(t *testing.T) {
-	var x, r int32
-	var y uint16
-	x = -2147483648
-	y = 0
-	r = x >> y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1073741824 {
-		t.Errorf("-2147483648 %s 1 = %d, want -1073741824", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-2147483648 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = -2147483647
-	y = 0
-	r = x >> y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1073741824 {
-		t.Errorf("-2147483647 %s 1 = %d, want -1073741824", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-2147483647 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 2147483647
-	y = 0
-	r = x >> y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s 0 = %d, want 2147483647", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 1073741823 {
-		t.Errorf("2147483647 %s 1 = %d, want 1073741823", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("2147483647 %s 65535 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint32uint8lsh(t *testing.T) {
-	var x, r int32
-	var y uint8
-	x = -2147483648
-	y = 0
-	r = x << y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483648 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483648 %s 255 = %d, want 0", "<<", r)
-	}
-	x = -2147483647
-	y = 0
-	r = x << y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-2147483647 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-2147483647 %s 255 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 2147483647
-	y = 0
-	r = x << y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s 0 = %d, want 2147483647", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("2147483647 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("2147483647 %s 255 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint32uint8rsh(t *testing.T) {
-	var x, r int32
-	var y uint8
-	x = -2147483648
-	y = 0
-	r = x >> y
-	if r != -2147483648 {
-		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1073741824 {
-		t.Errorf("-2147483648 %s 1 = %d, want -1073741824", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-2147483648 %s 255 = %d, want -1", ">>", r)
-	}
-	x = -2147483647
-	y = 0
-	r = x >> y
-	if r != -2147483647 {
-		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1073741824 {
-		t.Errorf("-2147483647 %s 1 = %d, want -1073741824", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-2147483647 %s 255 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 255 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 2147483647
-	y = 0
-	r = x >> y
-	if r != 2147483647 {
-		t.Errorf("2147483647 %s 0 = %d, want 2147483647", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 1073741823 {
-		t.Errorf("2147483647 %s 1 = %d, want 1073741823", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("2147483647 %s 255 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint16uint64lsh(t *testing.T) {
-	var x, r uint16
-	var y uint64
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 65535
-	y = 0
-	r = x << y
-	if r != 65535 {
-		t.Errorf("65535 %s 0 = %d, want 65535", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 65534 {
-		t.Errorf("65535 %s 1 = %d, want 65534", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("65535 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("65535 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint16uint64rsh(t *testing.T) {
-	var x, r uint16
-	var y uint64
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 65535
-	y = 0
-	r = x >> y
-	if r != 65535 {
-		t.Errorf("65535 %s 0 = %d, want 65535", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 32767 {
-		t.Errorf("65535 %s 1 = %d, want 32767", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("65535 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("65535 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint16uint32lsh(t *testing.T) {
-	var x, r uint16
-	var y uint32
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 65535
-	y = 0
-	r = x << y
-	if r != 65535 {
-		t.Errorf("65535 %s 0 = %d, want 65535", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 65534 {
-		t.Errorf("65535 %s 1 = %d, want 65534", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("65535 %s 4294967295 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint16uint32rsh(t *testing.T) {
-	var x, r uint16
-	var y uint32
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 65535
-	y = 0
-	r = x >> y
-	if r != 65535 {
-		t.Errorf("65535 %s 0 = %d, want 65535", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 32767 {
-		t.Errorf("65535 %s 1 = %d, want 32767", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("65535 %s 4294967295 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint16uint16lsh(t *testing.T) {
-	var x, r uint16
-	var y uint16
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 65535
-	y = 0
-	r = x << y
-	if r != 65535 {
-		t.Errorf("65535 %s 0 = %d, want 65535", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 65534 {
-		t.Errorf("65535 %s 1 = %d, want 65534", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("65535 %s 65535 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint16uint16rsh(t *testing.T) {
-	var x, r uint16
-	var y uint16
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 65535
-	y = 0
-	r = x >> y
-	if r != 65535 {
-		t.Errorf("65535 %s 0 = %d, want 65535", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 32767 {
-		t.Errorf("65535 %s 1 = %d, want 32767", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("65535 %s 65535 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint16uint8lsh(t *testing.T) {
-	var x, r uint16
-	var y uint8
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 65535
-	y = 0
-	r = x << y
-	if r != 65535 {
-		t.Errorf("65535 %s 0 = %d, want 65535", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 65534 {
-		t.Errorf("65535 %s 1 = %d, want 65534", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("65535 %s 255 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint16uint8rsh(t *testing.T) {
-	var x, r uint16
-	var y uint8
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 65535
-	y = 0
-	r = x >> y
-	if r != 65535 {
-		t.Errorf("65535 %s 0 = %d, want 65535", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 32767 {
-		t.Errorf("65535 %s 1 = %d, want 32767", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("65535 %s 255 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint16uint64lsh(t *testing.T) {
-	var x, r int16
-	var y uint64
-	x = -32768
-	y = 0
-	r = x << y
-	if r != -32768 {
-		t.Errorf("-32768 %s 0 = %d, want -32768", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32768 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32768 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32768 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = -32767
-	y = 0
-	r = x << y
-	if r != -32767 {
-		t.Errorf("-32767 %s 0 = %d, want -32767", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-32767 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32767 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32767 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 32766
-	y = 0
-	r = x << y
-	if r != 32766 {
-		t.Errorf("32766 %s 0 = %d, want 32766", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -4 {
-		t.Errorf("32766 %s 1 = %d, want -4", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("32766 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("32766 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 32767
-	y = 0
-	r = x << y
-	if r != 32767 {
-		t.Errorf("32767 %s 0 = %d, want 32767", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("32767 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("32767 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("32767 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint16uint64rsh(t *testing.T) {
-	var x, r int16
-	var y uint64
-	x = -32768
-	y = 0
-	r = x >> y
-	if r != -32768 {
-		t.Errorf("-32768 %s 0 = %d, want -32768", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -16384 {
-		t.Errorf("-32768 %s 1 = %d, want -16384", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-32768 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-32768 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = -32767
-	y = 0
-	r = x >> y
-	if r != -32767 {
-		t.Errorf("-32767 %s 0 = %d, want -32767", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -16384 {
-		t.Errorf("-32767 %s 1 = %d, want -16384", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-32767 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-32767 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 32766
-	y = 0
-	r = x >> y
-	if r != 32766 {
-		t.Errorf("32766 %s 0 = %d, want 32766", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 16383 {
-		t.Errorf("32766 %s 1 = %d, want 16383", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("32766 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("32766 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 32767
-	y = 0
-	r = x >> y
-	if r != 32767 {
-		t.Errorf("32767 %s 0 = %d, want 32767", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 16383 {
-		t.Errorf("32767 %s 1 = %d, want 16383", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("32767 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("32767 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint16uint32lsh(t *testing.T) {
-	var x, r int16
-	var y uint32
-	x = -32768
-	y = 0
-	r = x << y
-	if r != -32768 {
-		t.Errorf("-32768 %s 0 = %d, want -32768", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32768 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32768 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = -32767
-	y = 0
-	r = x << y
-	if r != -32767 {
-		t.Errorf("-32767 %s 0 = %d, want -32767", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-32767 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32767 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 32766
-	y = 0
-	r = x << y
-	if r != 32766 {
-		t.Errorf("32766 %s 0 = %d, want 32766", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -4 {
-		t.Errorf("32766 %s 1 = %d, want -4", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("32766 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 32767
-	y = 0
-	r = x << y
-	if r != 32767 {
-		t.Errorf("32767 %s 0 = %d, want 32767", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("32767 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("32767 %s 4294967295 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint16uint32rsh(t *testing.T) {
-	var x, r int16
-	var y uint32
-	x = -32768
-	y = 0
-	r = x >> y
-	if r != -32768 {
-		t.Errorf("-32768 %s 0 = %d, want -32768", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -16384 {
-		t.Errorf("-32768 %s 1 = %d, want -16384", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-32768 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = -32767
-	y = 0
-	r = x >> y
-	if r != -32767 {
-		t.Errorf("-32767 %s 0 = %d, want -32767", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -16384 {
-		t.Errorf("-32767 %s 1 = %d, want -16384", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-32767 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 32766
-	y = 0
-	r = x >> y
-	if r != 32766 {
-		t.Errorf("32766 %s 0 = %d, want 32766", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 16383 {
-		t.Errorf("32766 %s 1 = %d, want 16383", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("32766 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 32767
-	y = 0
-	r = x >> y
-	if r != 32767 {
-		t.Errorf("32767 %s 0 = %d, want 32767", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 16383 {
-		t.Errorf("32767 %s 1 = %d, want 16383", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("32767 %s 4294967295 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint16uint16lsh(t *testing.T) {
-	var x, r int16
-	var y uint16
-	x = -32768
-	y = 0
-	r = x << y
-	if r != -32768 {
-		t.Errorf("-32768 %s 0 = %d, want -32768", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32768 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32768 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = -32767
-	y = 0
-	r = x << y
-	if r != -32767 {
-		t.Errorf("-32767 %s 0 = %d, want -32767", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-32767 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32767 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 32766
-	y = 0
-	r = x << y
-	if r != 32766 {
-		t.Errorf("32766 %s 0 = %d, want 32766", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -4 {
-		t.Errorf("32766 %s 1 = %d, want -4", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("32766 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 32767
-	y = 0
-	r = x << y
-	if r != 32767 {
-		t.Errorf("32767 %s 0 = %d, want 32767", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("32767 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("32767 %s 65535 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint16uint16rsh(t *testing.T) {
-	var x, r int16
-	var y uint16
-	x = -32768
-	y = 0
-	r = x >> y
-	if r != -32768 {
-		t.Errorf("-32768 %s 0 = %d, want -32768", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -16384 {
-		t.Errorf("-32768 %s 1 = %d, want -16384", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-32768 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = -32767
-	y = 0
-	r = x >> y
-	if r != -32767 {
-		t.Errorf("-32767 %s 0 = %d, want -32767", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -16384 {
-		t.Errorf("-32767 %s 1 = %d, want -16384", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-32767 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 32766
-	y = 0
-	r = x >> y
-	if r != 32766 {
-		t.Errorf("32766 %s 0 = %d, want 32766", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 16383 {
-		t.Errorf("32766 %s 1 = %d, want 16383", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("32766 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 32767
-	y = 0
-	r = x >> y
-	if r != 32767 {
-		t.Errorf("32767 %s 0 = %d, want 32767", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 16383 {
-		t.Errorf("32767 %s 1 = %d, want 16383", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("32767 %s 65535 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint16uint8lsh(t *testing.T) {
-	var x, r int16
-	var y uint8
-	x = -32768
-	y = 0
-	r = x << y
-	if r != -32768 {
-		t.Errorf("-32768 %s 0 = %d, want -32768", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32768 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32768 %s 255 = %d, want 0", "<<", r)
-	}
-	x = -32767
-	y = 0
-	r = x << y
-	if r != -32767 {
-		t.Errorf("-32767 %s 0 = %d, want -32767", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-32767 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-32767 %s 255 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 32766
-	y = 0
-	r = x << y
-	if r != 32766 {
-		t.Errorf("32766 %s 0 = %d, want 32766", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -4 {
-		t.Errorf("32766 %s 1 = %d, want -4", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("32766 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 32767
-	y = 0
-	r = x << y
-	if r != 32767 {
-		t.Errorf("32767 %s 0 = %d, want 32767", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("32767 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("32767 %s 255 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint16uint8rsh(t *testing.T) {
-	var x, r int16
-	var y uint8
-	x = -32768
-	y = 0
-	r = x >> y
-	if r != -32768 {
-		t.Errorf("-32768 %s 0 = %d, want -32768", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -16384 {
-		t.Errorf("-32768 %s 1 = %d, want -16384", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-32768 %s 255 = %d, want -1", ">>", r)
-	}
-	x = -32767
-	y = 0
-	r = x >> y
-	if r != -32767 {
-		t.Errorf("-32767 %s 0 = %d, want -32767", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -16384 {
-		t.Errorf("-32767 %s 1 = %d, want -16384", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-32767 %s 255 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 255 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 32766
-	y = 0
-	r = x >> y
-	if r != 32766 {
-		t.Errorf("32766 %s 0 = %d, want 32766", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 16383 {
-		t.Errorf("32766 %s 1 = %d, want 16383", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("32766 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 32767
-	y = 0
-	r = x >> y
-	if r != 32767 {
-		t.Errorf("32767 %s 0 = %d, want 32767", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 16383 {
-		t.Errorf("32767 %s 1 = %d, want 16383", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("32767 %s 255 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint8uint64lsh(t *testing.T) {
-	var x, r uint8
-	var y uint64
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 255
-	y = 0
-	r = x << y
-	if r != 255 {
-		t.Errorf("255 %s 0 = %d, want 255", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 254 {
-		t.Errorf("255 %s 1 = %d, want 254", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("255 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("255 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint8uint64rsh(t *testing.T) {
-	var x, r uint8
-	var y uint64
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 255
-	y = 0
-	r = x >> y
-	if r != 255 {
-		t.Errorf("255 %s 0 = %d, want 255", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 127 {
-		t.Errorf("255 %s 1 = %d, want 127", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("255 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("255 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint8uint32lsh(t *testing.T) {
-	var x, r uint8
-	var y uint32
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 255
-	y = 0
-	r = x << y
-	if r != 255 {
-		t.Errorf("255 %s 0 = %d, want 255", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 254 {
-		t.Errorf("255 %s 1 = %d, want 254", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("255 %s 4294967295 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint8uint32rsh(t *testing.T) {
-	var x, r uint8
-	var y uint32
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 255
-	y = 0
-	r = x >> y
-	if r != 255 {
-		t.Errorf("255 %s 0 = %d, want 255", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 127 {
-		t.Errorf("255 %s 1 = %d, want 127", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("255 %s 4294967295 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint8uint16lsh(t *testing.T) {
-	var x, r uint8
-	var y uint16
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 255
-	y = 0
-	r = x << y
-	if r != 255 {
-		t.Errorf("255 %s 0 = %d, want 255", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 254 {
-		t.Errorf("255 %s 1 = %d, want 254", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("255 %s 65535 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint8uint16rsh(t *testing.T) {
-	var x, r uint8
-	var y uint16
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 255
-	y = 0
-	r = x >> y
-	if r != 255 {
-		t.Errorf("255 %s 0 = %d, want 255", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 127 {
-		t.Errorf("255 %s 1 = %d, want 127", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("255 %s 65535 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFolduint8uint8lsh(t *testing.T) {
-	var x, r uint8
-	var y uint8
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 255
-	y = 0
-	r = x << y
-	if r != 255 {
-		t.Errorf("255 %s 0 = %d, want 255", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 254 {
-		t.Errorf("255 %s 1 = %d, want 254", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("255 %s 255 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFolduint8uint8rsh(t *testing.T) {
-	var x, r uint8
-	var y uint8
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 255
-	y = 0
-	r = x >> y
-	if r != 255 {
-		t.Errorf("255 %s 0 = %d, want 255", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 127 {
-		t.Errorf("255 %s 1 = %d, want 127", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("255 %s 255 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint8uint64lsh(t *testing.T) {
-	var x, r int8
-	var y uint64
-	x = -128
-	y = 0
-	r = x << y
-	if r != -128 {
-		t.Errorf("-128 %s 0 = %d, want -128", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-128 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-128 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-128 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = -127
-	y = 0
-	r = x << y
-	if r != -127 {
-		t.Errorf("-127 %s 0 = %d, want -127", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-127 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-127 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-127 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 126
-	y = 0
-	r = x << y
-	if r != 126 {
-		t.Errorf("126 %s 0 = %d, want 126", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -4 {
-		t.Errorf("126 %s 1 = %d, want -4", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("126 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("126 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-	x = 127
-	y = 0
-	r = x << y
-	if r != 127 {
-		t.Errorf("127 %s 0 = %d, want 127", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("127 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967296
-	r = x << y
-	if r != 0 {
-		t.Errorf("127 %s 4294967296 = %d, want 0", "<<", r)
-	}
-	y = 18446744073709551615
-	r = x << y
-	if r != 0 {
-		t.Errorf("127 %s 18446744073709551615 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint8uint64rsh(t *testing.T) {
-	var x, r int8
-	var y uint64
-	x = -128
-	y = 0
-	r = x >> y
-	if r != -128 {
-		t.Errorf("-128 %s 0 = %d, want -128", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -64 {
-		t.Errorf("-128 %s 1 = %d, want -64", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-128 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-128 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = -127
-	y = 0
-	r = x >> y
-	if r != -127 {
-		t.Errorf("-127 %s 0 = %d, want -127", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -64 {
-		t.Errorf("-127 %s 1 = %d, want -64", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-127 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-127 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 4294967296 = %d, want -1", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 18446744073709551615 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 126
-	y = 0
-	r = x >> y
-	if r != 126 {
-		t.Errorf("126 %s 0 = %d, want 126", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 63 {
-		t.Errorf("126 %s 1 = %d, want 63", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("126 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("126 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-	x = 127
-	y = 0
-	r = x >> y
-	if r != 127 {
-		t.Errorf("127 %s 0 = %d, want 127", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 63 {
-		t.Errorf("127 %s 1 = %d, want 63", ">>", r)
-	}
-	y = 4294967296
-	r = x >> y
-	if r != 0 {
-		t.Errorf("127 %s 4294967296 = %d, want 0", ">>", r)
-	}
-	y = 18446744073709551615
-	r = x >> y
-	if r != 0 {
-		t.Errorf("127 %s 18446744073709551615 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint8uint32lsh(t *testing.T) {
-	var x, r int8
-	var y uint32
-	x = -128
-	y = 0
-	r = x << y
-	if r != -128 {
-		t.Errorf("-128 %s 0 = %d, want -128", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-128 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-128 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = -127
-	y = 0
-	r = x << y
-	if r != -127 {
-		t.Errorf("-127 %s 0 = %d, want -127", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-127 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-127 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 126
-	y = 0
-	r = x << y
-	if r != 126 {
-		t.Errorf("126 %s 0 = %d, want 126", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -4 {
-		t.Errorf("126 %s 1 = %d, want -4", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("126 %s 4294967295 = %d, want 0", "<<", r)
-	}
-	x = 127
-	y = 0
-	r = x << y
-	if r != 127 {
-		t.Errorf("127 %s 0 = %d, want 127", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("127 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 4294967295
-	r = x << y
-	if r != 0 {
-		t.Errorf("127 %s 4294967295 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint8uint32rsh(t *testing.T) {
-	var x, r int8
-	var y uint32
-	x = -128
-	y = 0
-	r = x >> y
-	if r != -128 {
-		t.Errorf("-128 %s 0 = %d, want -128", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -64 {
-		t.Errorf("-128 %s 1 = %d, want -64", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-128 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = -127
-	y = 0
-	r = x >> y
-	if r != -127 {
-		t.Errorf("-127 %s 0 = %d, want -127", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -64 {
-		t.Errorf("-127 %s 1 = %d, want -64", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-127 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 4294967295 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 126
-	y = 0
-	r = x >> y
-	if r != 126 {
-		t.Errorf("126 %s 0 = %d, want 126", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 63 {
-		t.Errorf("126 %s 1 = %d, want 63", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("126 %s 4294967295 = %d, want 0", ">>", r)
-	}
-	x = 127
-	y = 0
-	r = x >> y
-	if r != 127 {
-		t.Errorf("127 %s 0 = %d, want 127", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 63 {
-		t.Errorf("127 %s 1 = %d, want 63", ">>", r)
-	}
-	y = 4294967295
-	r = x >> y
-	if r != 0 {
-		t.Errorf("127 %s 4294967295 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint8uint16lsh(t *testing.T) {
-	var x, r int8
-	var y uint16
-	x = -128
-	y = 0
-	r = x << y
-	if r != -128 {
-		t.Errorf("-128 %s 0 = %d, want -128", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-128 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-128 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = -127
-	y = 0
-	r = x << y
-	if r != -127 {
-		t.Errorf("-127 %s 0 = %d, want -127", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-127 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-127 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 126
-	y = 0
-	r = x << y
-	if r != 126 {
-		t.Errorf("126 %s 0 = %d, want 126", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -4 {
-		t.Errorf("126 %s 1 = %d, want -4", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("126 %s 65535 = %d, want 0", "<<", r)
-	}
-	x = 127
-	y = 0
-	r = x << y
-	if r != 127 {
-		t.Errorf("127 %s 0 = %d, want 127", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("127 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 65535
-	r = x << y
-	if r != 0 {
-		t.Errorf("127 %s 65535 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint8uint16rsh(t *testing.T) {
-	var x, r int8
-	var y uint16
-	x = -128
-	y = 0
-	r = x >> y
-	if r != -128 {
-		t.Errorf("-128 %s 0 = %d, want -128", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -64 {
-		t.Errorf("-128 %s 1 = %d, want -64", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-128 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = -127
-	y = 0
-	r = x >> y
-	if r != -127 {
-		t.Errorf("-127 %s 0 = %d, want -127", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -64 {
-		t.Errorf("-127 %s 1 = %d, want -64", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-127 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 65535 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 126
-	y = 0
-	r = x >> y
-	if r != 126 {
-		t.Errorf("126 %s 0 = %d, want 126", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 63 {
-		t.Errorf("126 %s 1 = %d, want 63", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("126 %s 65535 = %d, want 0", ">>", r)
-	}
-	x = 127
-	y = 0
-	r = x >> y
-	if r != 127 {
-		t.Errorf("127 %s 0 = %d, want 127", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 63 {
-		t.Errorf("127 %s 1 = %d, want 63", ">>", r)
-	}
-	y = 65535
-	r = x >> y
-	if r != 0 {
-		t.Errorf("127 %s 65535 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldint8uint8lsh(t *testing.T) {
-	var x, r int8
-	var y uint8
-	x = -128
-	y = 0
-	r = x << y
-	if r != -128 {
-		t.Errorf("-128 %s 0 = %d, want -128", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("-128 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-128 %s 255 = %d, want 0", "<<", r)
-	}
-	x = -127
-	y = 0
-	r = x << y
-	if r != -127 {
-		t.Errorf("-127 %s 0 = %d, want -127", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("-127 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-127 %s 255 = %d, want 0", "<<", r)
-	}
-	x = -1
-	y = 0
-	r = x << y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("-1 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 0
-	y = 0
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 1
-	y = 0
-	r = x << y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != 2 {
-		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 126
-	y = 0
-	r = x << y
-	if r != 126 {
-		t.Errorf("126 %s 0 = %d, want 126", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -4 {
-		t.Errorf("126 %s 1 = %d, want -4", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("126 %s 255 = %d, want 0", "<<", r)
-	}
-	x = 127
-	y = 0
-	r = x << y
-	if r != 127 {
-		t.Errorf("127 %s 0 = %d, want 127", "<<", r)
-	}
-	y = 1
-	r = x << y
-	if r != -2 {
-		t.Errorf("127 %s 1 = %d, want -2", "<<", r)
-	}
-	y = 255
-	r = x << y
-	if r != 0 {
-		t.Errorf("127 %s 255 = %d, want 0", "<<", r)
-	}
-}
-func TestConstFoldint8uint8rsh(t *testing.T) {
-	var x, r int8
-	var y uint8
-	x = -128
-	y = 0
-	r = x >> y
-	if r != -128 {
-		t.Errorf("-128 %s 0 = %d, want -128", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -64 {
-		t.Errorf("-128 %s 1 = %d, want -64", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-128 %s 255 = %d, want -1", ">>", r)
-	}
-	x = -127
-	y = 0
-	r = x >> y
-	if r != -127 {
-		t.Errorf("-127 %s 0 = %d, want -127", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -64 {
-		t.Errorf("-127 %s 1 = %d, want -64", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-127 %s 255 = %d, want -1", ">>", r)
-	}
-	x = -1
-	y = 0
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != -1 {
-		t.Errorf("-1 %s 255 = %d, want -1", ">>", r)
-	}
-	x = 0
-	y = 0
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 1
-	y = 0
-	r = x >> y
-	if r != 1 {
-		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 126
-	y = 0
-	r = x >> y
-	if r != 126 {
-		t.Errorf("126 %s 0 = %d, want 126", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 63 {
-		t.Errorf("126 %s 1 = %d, want 63", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("126 %s 255 = %d, want 0", ">>", r)
-	}
-	x = 127
-	y = 0
-	r = x >> y
-	if r != 127 {
-		t.Errorf("127 %s 0 = %d, want 127", ">>", r)
-	}
-	y = 1
-	r = x >> y
-	if r != 63 {
-		t.Errorf("127 %s 1 = %d, want 63", ">>", r)
-	}
-	y = 255
-	r = x >> y
-	if r != 0 {
-		t.Errorf("127 %s 255 = %d, want 0", ">>", r)
-	}
-}
-func TestConstFoldCompareuint64(t *testing.T) {
-	{
-		var x uint64 = 0
-		var y uint64 = 0
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint64 = 0
-		var y uint64 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint64 = 0
-		var y uint64 = 4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint64 = 0
-		var y uint64 = 18446744073709551615
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint64 = 1
-		var y uint64 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint64 = 1
-		var y uint64 = 1
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint64 = 1
-		var y uint64 = 4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint64 = 1
-		var y uint64 = 18446744073709551615
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint64 = 4294967296
-		var y uint64 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint64 = 4294967296
-		var y uint64 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint64 = 4294967296
-		var y uint64 = 4294967296
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint64 = 4294967296
-		var y uint64 = 18446744073709551615
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint64 = 18446744073709551615
-		var y uint64 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint64 = 18446744073709551615
-		var y uint64 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint64 = 18446744073709551615
-		var y uint64 = 4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint64 = 18446744073709551615
-		var y uint64 = 18446744073709551615
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-}
-func TestConstFoldCompareint64(t *testing.T) {
-	{
-		var x int64 = -9223372036854775808
-		var y int64 = -9223372036854775808
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775808
-		var y int64 = -9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775808
-		var y int64 = -4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775808
-		var y int64 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775808
-		var y int64 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775808
-		var y int64 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775808
-		var y int64 = 4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775808
-		var y int64 = 9223372036854775806
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775808
-		var y int64 = 9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775807
-		var y int64 = -9223372036854775808
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775807
-		var y int64 = -9223372036854775807
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775807
-		var y int64 = -4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775807
-		var y int64 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775807
-		var y int64 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775807
-		var y int64 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775807
-		var y int64 = 4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775807
-		var y int64 = 9223372036854775806
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -9223372036854775807
-		var y int64 = 9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -4294967296
-		var y int64 = -9223372036854775808
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = -4294967296
-		var y int64 = -9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = -4294967296
-		var y int64 = -4294967296
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = -4294967296
-		var y int64 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -4294967296
-		var y int64 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -4294967296
-		var y int64 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -4294967296
-		var y int64 = 4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -4294967296
-		var y int64 = 9223372036854775806
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -4294967296
-		var y int64 = 9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -1
-		var y int64 = -9223372036854775808
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = -1
-		var y int64 = -9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = -1
-		var y int64 = -4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = -1
-		var y int64 = -1
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = -1
-		var y int64 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -1
-		var y int64 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -1
-		var y int64 = 4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -1
-		var y int64 = 9223372036854775806
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = -1
-		var y int64 = 9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = 0
-		var y int64 = -9223372036854775808
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 0
-		var y int64 = -9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 0
-		var y int64 = -4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 0
-		var y int64 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 0
-		var y int64 = 0
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 0
-		var y int64 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = 0
-		var y int64 = 4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = 0
-		var y int64 = 9223372036854775806
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = 0
-		var y int64 = 9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = 1
-		var y int64 = -9223372036854775808
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 1
-		var y int64 = -9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 1
-		var y int64 = -4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 1
-		var y int64 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 1
-		var y int64 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 1
-		var y int64 = 1
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 1
-		var y int64 = 4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = 1
-		var y int64 = 9223372036854775806
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = 1
-		var y int64 = 9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = 4294967296
-		var y int64 = -9223372036854775808
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 4294967296
-		var y int64 = -9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 4294967296
-		var y int64 = -4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 4294967296
-		var y int64 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 4294967296
-		var y int64 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 4294967296
-		var y int64 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 4294967296
-		var y int64 = 4294967296
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 4294967296
-		var y int64 = 9223372036854775806
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = 4294967296
-		var y int64 = 9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775806
-		var y int64 = -9223372036854775808
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775806
-		var y int64 = -9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775806
-		var y int64 = -4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775806
-		var y int64 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775806
-		var y int64 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775806
-		var y int64 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775806
-		var y int64 = 4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775806
-		var y int64 = 9223372036854775806
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775806
-		var y int64 = 9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775807
-		var y int64 = -9223372036854775808
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775807
-		var y int64 = -9223372036854775807
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775807
-		var y int64 = -4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775807
-		var y int64 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775807
-		var y int64 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775807
-		var y int64 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775807
-		var y int64 = 4294967296
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775807
-		var y int64 = 9223372036854775806
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int64 = 9223372036854775807
-		var y int64 = 9223372036854775807
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-}
-func TestConstFoldCompareuint32(t *testing.T) {
-	{
-		var x uint32 = 0
-		var y uint32 = 0
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint32 = 0
-		var y uint32 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint32 = 0
-		var y uint32 = 4294967295
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint32 = 1
-		var y uint32 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint32 = 1
-		var y uint32 = 1
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint32 = 1
-		var y uint32 = 4294967295
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint32 = 4294967295
-		var y uint32 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint32 = 4294967295
-		var y uint32 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint32 = 4294967295
-		var y uint32 = 4294967295
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-}
-func TestConstFoldCompareint32(t *testing.T) {
-	{
-		var x int32 = -2147483648
-		var y int32 = -2147483648
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = -2147483648
-		var y int32 = -2147483647
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = -2147483648
-		var y int32 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = -2147483648
-		var y int32 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = -2147483648
-		var y int32 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = -2147483648
-		var y int32 = 2147483647
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = -2147483647
-		var y int32 = -2147483648
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = -2147483647
-		var y int32 = -2147483647
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = -2147483647
-		var y int32 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = -2147483647
-		var y int32 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = -2147483647
-		var y int32 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = -2147483647
-		var y int32 = 2147483647
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = -1
-		var y int32 = -2147483648
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = -1
-		var y int32 = -2147483647
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = -1
-		var y int32 = -1
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = -1
-		var y int32 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = -1
-		var y int32 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = -1
-		var y int32 = 2147483647
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = 0
-		var y int32 = -2147483648
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 0
-		var y int32 = -2147483647
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 0
-		var y int32 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 0
-		var y int32 = 0
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 0
-		var y int32 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = 0
-		var y int32 = 2147483647
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = 1
-		var y int32 = -2147483648
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 1
-		var y int32 = -2147483647
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 1
-		var y int32 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 1
-		var y int32 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 1
-		var y int32 = 1
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 1
-		var y int32 = 2147483647
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int32 = 2147483647
-		var y int32 = -2147483648
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 2147483647
-		var y int32 = -2147483647
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 2147483647
-		var y int32 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 2147483647
-		var y int32 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 2147483647
-		var y int32 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int32 = 2147483647
-		var y int32 = 2147483647
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-}
-func TestConstFoldCompareuint16(t *testing.T) {
-	{
-		var x uint16 = 0
-		var y uint16 = 0
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint16 = 0
-		var y uint16 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint16 = 0
-		var y uint16 = 65535
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint16 = 1
-		var y uint16 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint16 = 1
-		var y uint16 = 1
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint16 = 1
-		var y uint16 = 65535
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint16 = 65535
-		var y uint16 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint16 = 65535
-		var y uint16 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint16 = 65535
-		var y uint16 = 65535
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-}
-func TestConstFoldCompareint16(t *testing.T) {
-	{
-		var x int16 = -32768
-		var y int16 = -32768
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = -32768
-		var y int16 = -32767
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -32768
-		var y int16 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -32768
-		var y int16 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -32768
-		var y int16 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -32768
-		var y int16 = 32766
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -32768
-		var y int16 = 32767
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -32767
-		var y int16 = -32768
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = -32767
-		var y int16 = -32767
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = -32767
-		var y int16 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -32767
-		var y int16 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -32767
-		var y int16 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -32767
-		var y int16 = 32766
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -32767
-		var y int16 = 32767
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -1
-		var y int16 = -32768
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = -1
-		var y int16 = -32767
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = -1
-		var y int16 = -1
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = -1
-		var y int16 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -1
-		var y int16 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -1
-		var y int16 = 32766
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = -1
-		var y int16 = 32767
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = 0
-		var y int16 = -32768
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 0
-		var y int16 = -32767
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 0
-		var y int16 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 0
-		var y int16 = 0
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 0
-		var y int16 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = 0
-		var y int16 = 32766
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = 0
-		var y int16 = 32767
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = 1
-		var y int16 = -32768
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 1
-		var y int16 = -32767
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 1
-		var y int16 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 1
-		var y int16 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 1
-		var y int16 = 1
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 1
-		var y int16 = 32766
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = 1
-		var y int16 = 32767
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = 32766
-		var y int16 = -32768
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 32766
-		var y int16 = -32767
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 32766
-		var y int16 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 32766
-		var y int16 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 32766
-		var y int16 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 32766
-		var y int16 = 32766
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 32766
-		var y int16 = 32767
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int16 = 32767
-		var y int16 = -32768
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 32767
-		var y int16 = -32767
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 32767
-		var y int16 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 32767
-		var y int16 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 32767
-		var y int16 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 32767
-		var y int16 = 32766
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int16 = 32767
-		var y int16 = 32767
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-}
-func TestConstFoldCompareuint8(t *testing.T) {
-	{
-		var x uint8 = 0
-		var y uint8 = 0
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint8 = 0
-		var y uint8 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint8 = 0
-		var y uint8 = 255
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint8 = 1
-		var y uint8 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint8 = 1
-		var y uint8 = 1
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint8 = 1
-		var y uint8 = 255
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x uint8 = 255
-		var y uint8 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint8 = 255
-		var y uint8 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x uint8 = 255
-		var y uint8 = 255
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-}
-func TestConstFoldCompareint8(t *testing.T) {
-	{
-		var x int8 = -128
-		var y int8 = -128
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = -128
-		var y int8 = -127
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -128
-		var y int8 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -128
-		var y int8 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -128
-		var y int8 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -128
-		var y int8 = 126
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -128
-		var y int8 = 127
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -127
-		var y int8 = -128
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = -127
-		var y int8 = -127
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = -127
-		var y int8 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -127
-		var y int8 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -127
-		var y int8 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -127
-		var y int8 = 126
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -127
-		var y int8 = 127
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -1
-		var y int8 = -128
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = -1
-		var y int8 = -127
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = -1
-		var y int8 = -1
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = -1
-		var y int8 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -1
-		var y int8 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -1
-		var y int8 = 126
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = -1
-		var y int8 = 127
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = 0
-		var y int8 = -128
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 0
-		var y int8 = -127
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 0
-		var y int8 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 0
-		var y int8 = 0
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 0
-		var y int8 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = 0
-		var y int8 = 126
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = 0
-		var y int8 = 127
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = 1
-		var y int8 = -128
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 1
-		var y int8 = -127
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 1
-		var y int8 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 1
-		var y int8 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 1
-		var y int8 = 1
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 1
-		var y int8 = 126
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = 1
-		var y int8 = 127
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = 126
-		var y int8 = -128
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 126
-		var y int8 = -127
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 126
-		var y int8 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 126
-		var y int8 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 126
-		var y int8 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 126
-		var y int8 = 126
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 126
-		var y int8 = 127
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if !(x < y) {
-			t.Errorf("!(%d < %d)", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if x >= y {
-			t.Errorf("%d >= %d", x, y)
-		}
-	}
-	{
-		var x int8 = 127
-		var y int8 = -128
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 127
-		var y int8 = -127
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 127
-		var y int8 = -1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 127
-		var y int8 = 0
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 127
-		var y int8 = 1
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 127
-		var y int8 = 126
-		if x == y {
-			t.Errorf("%d == %d", x, y)
-		}
-		if !(x != y) {
-			t.Errorf("!(%d != %d)", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if !(x > y) {
-			t.Errorf("!(%d > %d)", x, y)
-		}
-		if x <= y {
-			t.Errorf("%d <= %d", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-	{
-		var x int8 = 127
-		var y int8 = 127
-		if !(x == y) {
-			t.Errorf("!(%d == %d)", x, y)
-		}
-		if x != y {
-			t.Errorf("%d != %d", x, y)
-		}
-		if x < y {
-			t.Errorf("%d < %d", x, y)
-		}
-		if x > y {
-			t.Errorf("%d > %d", x, y)
-		}
-		if !(x <= y) {
-			t.Errorf("!(%d <= %d)", x, y)
-		}
-		if !(x >= y) {
-			t.Errorf("!(%d >= %d)", x, y)
-		}
-	}
-}
diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go
deleted file mode 100644
index 6e90eb4..0000000
--- a/src/cmd/compile/internal/gc/dcl.go
+++ /dev/null
@@ -1,1185 +0,0 @@
-// Copyright 2009 The Go Authors. 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 (
-	"bytes"
-	"cmd/compile/internal/types"
-	"cmd/internal/obj"
-	"cmd/internal/src"
-	"fmt"
-	"strings"
-)
-
-// Declaration stack & operations
-
-var externdcl []*Node
-
-func testdclstack() {
-	if !types.IsDclstackValid() {
-		if nerrors != 0 {
-			errorexit()
-		}
-		Fatalf("mark left on the dclstack")
-	}
-}
-
-// redeclare emits a diagnostic about symbol s being redeclared at pos.
-func redeclare(pos src.XPos, s *types.Sym, where string) {
-	if !s.Lastlineno.IsKnown() {
-		pkg := s.Origpkg
-		if pkg == nil {
-			pkg = s.Pkg
-		}
-		yyerrorl(pos, "%v redeclared %s\n"+
-			"\tprevious declaration during import %q", s, where, pkg.Path)
-	} else {
-		prevPos := s.Lastlineno
-
-		// When an import and a declaration collide in separate files,
-		// present the import as the "redeclared", because the declaration
-		// is visible where the import is, but not vice versa.
-		// See issue 4510.
-		if s.Def == nil {
-			pos, prevPos = prevPos, pos
-		}
-
-		yyerrorl(pos, "%v redeclared %s\n"+
-			"\tprevious declaration at %v", s, where, linestr(prevPos))
-	}
-}
-
-var vargen int
-
-// declare individual names - var, typ, const
-
-var declare_typegen int
-
-// declare records that Node n declares symbol n.Sym in the specified
-// declaration context.
-func declare(n *Node, ctxt Class) {
-	if n.isBlank() {
-		return
-	}
-
-	if n.Name == nil {
-		// named OLITERAL needs Name; most OLITERALs don't.
-		n.Name = new(Name)
-	}
-
-	s := n.Sym
-
-	// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
-	if !inimport && !typecheckok && s.Pkg != localpkg {
-		yyerrorl(n.Pos, "cannot declare name %v", s)
-	}
-
-	gen := 0
-	if ctxt == PEXTERN {
-		if s.Name == "init" {
-			yyerrorl(n.Pos, "cannot declare init - must be func")
-		}
-		if s.Name == "main" && s.Pkg.Name == "main" {
-			yyerrorl(n.Pos, "cannot declare main - must be func")
-		}
-		externdcl = append(externdcl, n)
-	} else {
-		if Curfn == nil && ctxt == PAUTO {
-			lineno = n.Pos
-			Fatalf("automatic outside function")
-		}
-		if Curfn != nil && ctxt != PFUNC {
-			Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
-		}
-		if n.Op == OTYPE {
-			declare_typegen++
-			gen = declare_typegen
-		} else if n.Op == ONAME && ctxt == PAUTO && !strings.Contains(s.Name, "·") {
-			vargen++
-			gen = vargen
-		}
-		types.Pushdcl(s)
-		n.Name.Curfn = Curfn
-	}
-
-	if ctxt == PAUTO {
-		n.Xoffset = 0
-	}
-
-	if s.Block == types.Block {
-		// functype will print errors about duplicate function arguments.
-		// Don't repeat the error here.
-		if ctxt != PPARAM && ctxt != PPARAMOUT {
-			redeclare(n.Pos, s, "in this block")
-		}
-	}
-
-	s.Block = types.Block
-	s.Lastlineno = lineno
-	s.Def = asTypesNode(n)
-	n.Name.Vargen = int32(gen)
-	n.SetClass(ctxt)
-	if ctxt == PFUNC {
-		n.Sym.SetFunc(true)
-	}
-
-	autoexport(n, ctxt)
-}
-
-func addvar(n *Node, t *types.Type, ctxt Class) {
-	if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil {
-		Fatalf("addvar: n=%v t=%v nil", n, t)
-	}
-
-	n.Op = ONAME
-	declare(n, ctxt)
-	n.Type = t
-}
-
-// declare variables from grammar
-// new_name_list (type | [type] = expr_list)
-func variter(vl []*Node, t *Node, el []*Node) []*Node {
-	var init []*Node
-	doexpr := len(el) > 0
-
-	if len(el) == 1 && len(vl) > 1 {
-		e := el[0]
-		as2 := nod(OAS2, nil, nil)
-		as2.List.Set(vl)
-		as2.Rlist.Set1(e)
-		for _, v := range vl {
-			v.Op = ONAME
-			declare(v, dclcontext)
-			v.Name.Param.Ntype = t
-			v.Name.Defn = as2
-			if Curfn != nil {
-				init = append(init, nod(ODCL, v, nil))
-			}
-		}
-
-		return append(init, as2)
-	}
-
-	nel := len(el)
-	for _, v := range vl {
-		var e *Node
-		if doexpr {
-			if len(el) == 0 {
-				yyerror("assignment mismatch: %d variables but %d values", len(vl), nel)
-				break
-			}
-			e = el[0]
-			el = el[1:]
-		}
-
-		v.Op = ONAME
-		declare(v, dclcontext)
-		v.Name.Param.Ntype = t
-
-		if e != nil || Curfn != nil || v.isBlank() {
-			if Curfn != nil {
-				init = append(init, nod(ODCL, v, nil))
-			}
-			e = nod(OAS, v, e)
-			init = append(init, e)
-			if e.Right != nil {
-				v.Name.Defn = e
-			}
-		}
-	}
-
-	if len(el) != 0 {
-		yyerror("assignment mismatch: %d variables but %d values", len(vl), nel)
-	}
-	return init
-}
-
-// newnoname returns a new ONONAME Node associated with symbol s.
-func newnoname(s *types.Sym) *Node {
-	if s == nil {
-		Fatalf("newnoname nil")
-	}
-	n := nod(ONONAME, nil, nil)
-	n.Sym = s
-	n.Xoffset = 0
-	return n
-}
-
-// 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
-}
-
-// this generates a new name node for a name
-// being declared.
-func dclname(s *types.Sym) *Node {
-	n := newname(s)
-	n.Op = ONONAME // caller will correct it
-	return n
-}
-
-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(nodl(pos, OTYPE, nil, nil))
-		asNode(t.Nod).Type = t
-		asNode(t.Nod).Sym = t.Sym
-	}
-
-	return asNode(t.Nod)
-}
-
-func anonfield(typ *types.Type) *Node {
-	return symfield(nil, typ)
-}
-
-func namedfield(s string, typ *types.Type) *Node {
-	return symfield(lookup(s), typ)
-}
-
-func symfield(s *types.Sym, typ *types.Type) *Node {
-	n := nodSym(ODCLFIELD, nil, s)
-	n.Type = typ
-	return n
-}
-
-// oldname returns the Node that declares symbol s in the current scope.
-// If no such Node currently exists, an ONONAME Node is returned instead.
-// Automatically creates a new closure variable if the referenced symbol was
-// declared in a different (containing) function.
-func oldname(s *types.Sym) *Node {
-	n := asNode(s.Def)
-	if n == nil {
-		// Maybe a top-level declaration will come along later to
-		// define s. resolve will check s.Def again once all input
-		// source has been processed.
-		return newnoname(s)
-	}
-
-	if Curfn != nil && n.Op == ONAME && n.Name.Curfn != nil && n.Name.Curfn != Curfn {
-		// Inner func is referring to var in outer func.
-		//
-		// TODO(rsc): If there is an outer variable x and we
-		// are parsing x := 5 inside the closure, until we get to
-		// the := it looks like a reference to the outer x so we'll
-		// make x a closure variable unnecessarily.
-		c := n.Name.Param.Innermost
-		if c == nil || c.Name.Curfn != Curfn {
-			// Do not have a closure var for the active closure yet; make one.
-			c = newname(s)
-			c.SetClass(PAUTOHEAP)
-			c.Name.SetIsClosureVar(true)
-			c.SetIsDDD(n.IsDDD())
-			c.Name.Defn = n
-
-			// Link into list of active closure variables.
-			// Popped from list in func funcLit.
-			c.Name.Param.Outer = n.Name.Param.Innermost
-			n.Name.Param.Innermost = c
-
-			Curfn.Func.Cvars.Append(c)
-		}
-
-		// return ref to closure var, not original
-		return c
-	}
-
-	return n
-}
-
-// importName is like oldname, but it reports an error if sym is from another package and not exported.
-func importName(sym *types.Sym) *Node {
-	n := oldname(sym)
-	if !types.IsExported(sym.Name) && sym.Pkg != localpkg {
-		n.SetDiag(true)
-		yyerror("cannot refer to unexported name %s.%s", sym.Pkg.Name, sym.Name)
-	}
-	return n
-}
-
-// := declarations
-func colasname(n *Node) bool {
-	switch n.Op {
-	case ONAME,
-		ONONAME,
-		OPACK,
-		OTYPE,
-		OLITERAL:
-		return n.Sym != nil
-	}
-
-	return false
-}
-
-func colasdefn(left []*Node, defn *Node) {
-	for _, n := range left {
-		if n.Sym != nil {
-			n.Sym.SetUniq(true)
-		}
-	}
-
-	var nnew, nerr int
-	for i, n := range left {
-		if n.isBlank() {
-			continue
-		}
-		if !colasname(n) {
-			yyerrorl(defn.Pos, "non-name %v on left side of :=", n)
-			nerr++
-			continue
-		}
-
-		if !n.Sym.Uniq() {
-			yyerrorl(defn.Pos, "%v repeated on left side of :=", n.Sym)
-			n.SetDiag(true)
-			nerr++
-			continue
-		}
-
-		n.Sym.SetUniq(false)
-		if n.Sym.Block == types.Block {
-			continue
-		}
-
-		nnew++
-		n = newname(n.Sym)
-		declare(n, dclcontext)
-		n.Name.Defn = defn
-		defn.Ninit.Append(nod(ODCL, n, nil))
-		left[i] = n
-	}
-
-	if nnew == 0 && nerr == 0 {
-		yyerrorl(defn.Pos, "no new variables on left side of :=")
-	}
-}
-
-// declare the arguments in an
-// interface field declaration.
-func ifacedcl(n *Node) {
-	if n.Op != ODCLFIELD || n.Left == nil {
-		Fatalf("ifacedcl")
-	}
-
-	if n.Sym.IsBlank() {
-		yyerror("methods must have a unique non-blank name")
-	}
-}
-
-// declare the function proper
-// and declare the arguments.
-// called in extern-declaration context
-// returns in auto-declaration context.
-func funchdr(n *Node) {
-	// change the declaration context from extern to auto
-	funcStack = append(funcStack, funcStackEnt{Curfn, dclcontext})
-	Curfn = n
-	dclcontext = PAUTO
-
-	types.Markdcl()
-
-	if n.Func.Nname != nil {
-		funcargs(n.Func.Nname.Name.Param.Ntype)
-	} else if n.Func.Ntype != nil {
-		funcargs(n.Func.Ntype)
-	} else {
-		funcargs2(n.Type)
-	}
-}
-
-func funcargs(nt *Node) {
-	if nt.Op != OTFUNC {
-		Fatalf("funcargs %v", nt.Op)
-	}
-
-	// re-start the variable generation number
-	// we want to use small numbers for the return variables,
-	// so let them have the chunk starting at 1.
-	//
-	// TODO(mdempsky): This is ugly, and only necessary because
-	// esc.go uses Vargen to figure out result parameters' index
-	// within the result tuple.
-	vargen = nt.Rlist.Len()
-
-	// declare the receiver and in arguments.
-	if nt.Left != nil {
-		funcarg(nt.Left, PPARAM)
-	}
-	for _, n := range nt.List.Slice() {
-		funcarg(n, PPARAM)
-	}
-
-	oldvargen := vargen
-	vargen = 0
-
-	// declare the out arguments.
-	gen := nt.List.Len()
-	for _, n := range nt.Rlist.Slice() {
-		if n.Sym == nil {
-			// Name so that escape analysis can track it. ~r stands for 'result'.
-			n.Sym = lookupN("~r", gen)
-			gen++
-		}
-		if n.Sym.IsBlank() {
-			// Give it a name so we can assign to it during return. ~b stands for 'blank'.
-			// The name must be different from ~r above because if you have
-			//	func f() (_ int)
-			//	func g() int
-			// f is allowed to use a plain 'return' with no arguments, while g is not.
-			// So the two cases must be distinguished.
-			n.Sym = lookupN("~b", gen)
-			gen++
-		}
-
-		funcarg(n, PPARAMOUT)
-	}
-
-	vargen = oldvargen
-}
-
-func funcarg(n *Node, ctxt Class) {
-	if n.Op != ODCLFIELD {
-		Fatalf("funcarg %v", n.Op)
-	}
-	if n.Sym == nil {
-		return
-	}
-
-	n.Right = newnamel(n.Pos, n.Sym)
-	n.Right.Name.Param.Ntype = n.Left
-	n.Right.SetIsDDD(n.IsDDD())
-	declare(n.Right, ctxt)
-
-	vargen++
-	n.Right.Name.Vargen = int32(vargen)
-}
-
-// Same as funcargs, except run over an already constructed TFUNC.
-// This happens during import, where the hidden_fndcl rule has
-// used functype directly to parse the function's type.
-func funcargs2(t *types.Type) {
-	if t.Etype != TFUNC {
-		Fatalf("funcargs2 %v", t)
-	}
-
-	for _, f := range t.Recvs().Fields().Slice() {
-		funcarg2(f, PPARAM)
-	}
-	for _, f := range t.Params().Fields().Slice() {
-		funcarg2(f, PPARAM)
-	}
-	for _, f := range t.Results().Fields().Slice() {
-		funcarg2(f, PPARAMOUT)
-	}
-}
-
-func funcarg2(f *types.Field, ctxt Class) {
-	if f.Sym == nil {
-		return
-	}
-	n := newnamel(f.Pos, f.Sym)
-	f.Nname = asTypesNode(n)
-	n.Type = f.Type
-	n.SetIsDDD(f.IsDDD())
-	declare(n, ctxt)
-}
-
-var funcStack []funcStackEnt // stack of previous values of Curfn/dclcontext
-
-type funcStackEnt struct {
-	curfn      *Node
-	dclcontext Class
-}
-
-// finish the body.
-// called in auto-declaration context.
-// returns in extern-declaration context.
-func funcbody() {
-	// change the declaration context from auto to previous context
-	types.Popdcl()
-	var e funcStackEnt
-	funcStack, e = funcStack[:len(funcStack)-1], funcStack[len(funcStack)-1]
-	Curfn, dclcontext = e.curfn, e.dclcontext
-}
-
-// structs, functions, and methods.
-// they don't belong here, but where do they belong?
-func checkembeddedtype(t *types.Type) {
-	if t == nil {
-		return
-	}
-
-	if t.Sym == nil && t.IsPtr() {
-		t = t.Elem()
-		if t.IsInterface() {
-			yyerror("embedded type cannot be a pointer to interface")
-		}
-	}
-
-	if t.IsPtr() || t.IsUnsafePtr() {
-		yyerror("embedded type cannot be a pointer")
-	} else if t.Etype == TFORW && !t.ForwardType().Embedlineno.IsKnown() {
-		t.ForwardType().Embedlineno = lineno
-	}
-}
-
-func structfield(n *Node) *types.Field {
-	lno := lineno
-	lineno = n.Pos
-
-	if n.Op != ODCLFIELD {
-		Fatalf("structfield: oops %v\n", n)
-	}
-
-	f := types.NewField()
-	f.Pos = n.Pos
-	f.Sym = n.Sym
-
-	if n.Left != nil {
-		n.Left = typecheck(n.Left, ctxType)
-		n.Type = n.Left.Type
-		n.Left = nil
-	}
-
-	f.Type = n.Type
-	if f.Type == nil {
-		f.SetBroke(true)
-	}
-
-	if n.Embedded() {
-		checkembeddedtype(n.Type)
-		f.Embedded = 1
-	} else {
-		f.Embedded = 0
-	}
-
-	switch u := n.Val().U.(type) {
-	case string:
-		f.Note = u
-	default:
-		yyerror("field tag must be a string")
-	case nil:
-		// no-op
-	}
-
-	lineno = lno
-	return f
-}
-
-// checkdupfields emits errors for duplicately named fields or methods in
-// a list of struct or interface types.
-func checkdupfields(what string, fss ...[]*types.Field) {
-	seen := make(map[*types.Sym]bool)
-	for _, fs := range fss {
-		for _, f := range fs {
-			if f.Sym == nil || f.Sym.IsBlank() {
-				continue
-			}
-			if seen[f.Sym] {
-				yyerrorl(f.Pos, "duplicate %s %s", what, f.Sym.Name)
-				continue
-			}
-			seen[f.Sym] = true
-		}
-	}
-}
-
-// convert a parsed id/type list into
-// a type for struct/interface/arglist
-func tostruct(l []*Node) *types.Type {
-	t := types.New(TSTRUCT)
-
-	fields := make([]*types.Field, len(l))
-	for i, n := range l {
-		f := structfield(n)
-		if f.Broke() {
-			t.SetBroke(true)
-		}
-		fields[i] = f
-	}
-	t.SetFields(fields)
-
-	checkdupfields("field", t.FieldSlice())
-
-	if !t.Broke() {
-		checkwidth(t)
-	}
-
-	return t
-}
-
-func tofunargs(l []*Node, funarg types.Funarg) *types.Type {
-	t := types.New(TSTRUCT)
-	t.StructType().Funarg = funarg
-
-	fields := make([]*types.Field, len(l))
-	for i, n := range l {
-		f := structfield(n)
-		f.SetIsDDD(n.IsDDD())
-		if n.Right != nil {
-			n.Right.Type = f.Type
-			f.Nname = asTypesNode(n.Right)
-		}
-		if f.Broke() {
-			t.SetBroke(true)
-		}
-		fields[i] = f
-	}
-	t.SetFields(fields)
-	return t
-}
-
-func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type {
-	t := types.New(TSTRUCT)
-	t.StructType().Funarg = funarg
-	t.SetFields(fields)
-	return t
-}
-
-func interfacefield(n *Node) *types.Field {
-	lno := lineno
-	lineno = n.Pos
-
-	if n.Op != ODCLFIELD {
-		Fatalf("interfacefield: oops %v\n", n)
-	}
-
-	if n.Val().Ctype() != CTxxx {
-		yyerror("interface method cannot have annotation")
-	}
-
-	// MethodSpec = MethodName Signature | InterfaceTypeName .
-	//
-	// If Sym != nil, then Sym is MethodName and Left is Signature.
-	// Otherwise, Left is InterfaceTypeName.
-
-	if n.Left != nil {
-		n.Left = typecheck(n.Left, ctxType)
-		n.Type = n.Left.Type
-		n.Left = nil
-	}
-
-	f := types.NewField()
-	f.Pos = n.Pos
-	f.Sym = n.Sym
-	f.Type = n.Type
-	if f.Type == nil {
-		f.SetBroke(true)
-	}
-
-	lineno = lno
-	return f
-}
-
-func tointerface(l []*Node) *types.Type {
-	if len(l) == 0 {
-		return types.Types[TINTER]
-	}
-	t := types.New(TINTER)
-	var fields []*types.Field
-	for _, n := range l {
-		f := interfacefield(n)
-		if f.Broke() {
-			t.SetBroke(true)
-		}
-		fields = append(fields, f)
-	}
-	t.SetInterface(fields)
-	return t
-}
-
-func fakeRecv() *Node {
-	return anonfield(types.FakeRecvType())
-}
-
-func fakeRecvField() *types.Field {
-	f := types.NewField()
-	f.Type = types.FakeRecvType()
-	return f
-}
-
-// isifacemethod reports whether (field) m is
-// an interface method. Such methods have the
-// special receiver type types.FakeRecvType().
-func isifacemethod(f *types.Type) bool {
-	return f.Recv().Type == types.FakeRecvType()
-}
-
-// turn a parsed function declaration into a type
-func functype(this *Node, in, out []*Node) *types.Type {
-	t := types.New(TFUNC)
-
-	var rcvr []*Node
-	if this != nil {
-		rcvr = []*Node{this}
-	}
-	t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr)
-	t.FuncType().Params = tofunargs(in, types.FunargParams)
-	t.FuncType().Results = tofunargs(out, types.FunargResults)
-
-	checkdupfields("argument", t.Recvs().FieldSlice(), t.Params().FieldSlice(), t.Results().FieldSlice())
-
-	if t.Recvs().Broke() || t.Results().Broke() || t.Params().Broke() {
-		t.SetBroke(true)
-	}
-
-	t.FuncType().Outnamed = t.NumResults() > 0 && origSym(t.Results().Field(0).Sym) != nil
-
-	return t
-}
-
-func functypefield(this *types.Field, in, out []*types.Field) *types.Type {
-	t := types.New(TFUNC)
-
-	var rcvr []*types.Field
-	if this != nil {
-		rcvr = []*types.Field{this}
-	}
-	t.FuncType().Receiver = tofunargsfield(rcvr, types.FunargRcvr)
-	t.FuncType().Params = tofunargsfield(in, types.FunargParams)
-	t.FuncType().Results = tofunargsfield(out, types.FunargResults)
-
-	t.FuncType().Outnamed = t.NumResults() > 0 && origSym(t.Results().Field(0).Sym) != nil
-
-	return t
-}
-
-// origSym returns the original symbol written by the user.
-func origSym(s *types.Sym) *types.Sym {
-	if s == nil {
-		return nil
-	}
-
-	if len(s.Name) > 1 && s.Name[0] == '~' {
-		switch s.Name[1] {
-		case 'r': // originally an unnamed result
-			return nil
-		case 'b': // originally the blank identifier _
-			// TODO(mdempsky): Does s.Pkg matter here?
-			return nblank.Sym
-		}
-		return s
-	}
-
-	if strings.HasPrefix(s.Name, ".anon") {
-		// originally an unnamed or _ name (see subr.go: structargs)
-		return nil
-	}
-
-	return s
-}
-
-// methodSym returns the method symbol representing a method name
-// associated with a specific receiver type.
-//
-// Method symbols can be used to distinguish the same method appearing
-// in different method sets. For example, T.M and (*T).M have distinct
-// method symbols.
-//
-// The returned symbol will be marked as a function.
-func methodSym(recv *types.Type, msym *types.Sym) *types.Sym {
-	sym := methodSymSuffix(recv, msym, "")
-	sym.SetFunc(true)
-	return sym
-}
-
-// methodSymSuffix is like methodsym, but allows attaching a
-// distinguisher suffix. To avoid collisions, the suffix must not
-// start with a letter, number, or period.
-func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
-	if msym.IsBlank() {
-		Fatalf("blank method name")
-	}
-
-	rsym := recv.Sym
-	if recv.IsPtr() {
-		if rsym != nil {
-			Fatalf("declared pointer receiver type: %v", recv)
-		}
-		rsym = recv.Elem().Sym
-	}
-
-	// Find the package the receiver type appeared in. For
-	// anonymous receiver types (i.e., anonymous structs with
-	// embedded fields), use the "go" pseudo-package instead.
-	rpkg := gopkg
-	if rsym != nil {
-		rpkg = rsym.Pkg
-	}
-
-	var b bytes.Buffer
-	if recv.IsPtr() {
-		// The parentheses aren't really necessary, but
-		// they're pretty traditional at this point.
-		fmt.Fprintf(&b, "(%-S)", recv)
-	} else {
-		fmt.Fprintf(&b, "%-S", recv)
-	}
-
-	// A particular receiver type may have multiple non-exported
-	// methods with the same name. To disambiguate them, include a
-	// package qualifier for names that came from a different
-	// package than the receiver type.
-	if !types.IsExported(msym.Name) && msym.Pkg != rpkg {
-		b.WriteString(".")
-		b.WriteString(msym.Pkg.Prefix)
-	}
-
-	b.WriteString(".")
-	b.WriteString(msym.Name)
-	b.WriteString(suffix)
-
-	return rpkg.LookupBytes(b.Bytes())
-}
-
-// Add a method, declared as a function.
-// - msym is the method symbol
-// - t is function type (with receiver)
-// Returns a pointer to the existing or added Field; or nil if there's an error.
-func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
-	if msym == nil {
-		Fatalf("no method symbol")
-	}
-
-	// get parent type sym
-	rf := t.Recv() // ptr to this structure
-	if rf == nil {
-		yyerror("missing receiver")
-		return nil
-	}
-
-	mt := methtype(rf.Type)
-	if mt == nil || mt.Sym == nil {
-		pa := rf.Type
-		t := pa
-		if t != nil && t.IsPtr() {
-			if t.Sym != nil {
-				yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
-				return nil
-			}
-			t = t.Elem()
-		}
-
-		switch {
-		case t == nil || t.Broke():
-			// rely on typecheck having complained before
-		case t.Sym == nil:
-			yyerror("invalid receiver type %v (%v is not a defined type)", pa, t)
-		case t.IsPtr():
-			yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
-		case t.IsInterface():
-			yyerror("invalid receiver type %v (%v is an interface type)", pa, t)
-		default:
-			// Should have picked off all the reasons above,
-			// but just in case, fall back to generic error.
-			yyerror("invalid receiver type %v (%L / %L)", pa, pa, t)
-		}
-		return nil
-	}
-
-	if local && mt.Sym.Pkg != localpkg {
-		yyerror("cannot define new methods on non-local type %v", mt)
-		return nil
-	}
-
-	if msym.IsBlank() {
-		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)
-				f.SetBroke(true)
-				return nil
-			}
-		}
-	}
-
-	for _, f := range mt.Methods().Slice() {
-		if msym.Name != f.Sym.Name {
-			continue
-		}
-		// types.Identical only checks that incoming and result parameters match,
-		// so explicitly check that the receiver parameters match too.
-		if !types.Identical(t, f.Type) || !types.Identical(t.Recv().Type, f.Type.Recv().Type) {
-			yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
-		}
-		return f
-	}
-
-	f := types.NewField()
-	f.Pos = lineno
-	f.Sym = msym
-	f.Type = t
-	f.SetNointerface(nointerface)
-
-	mt.Methods().Append(f)
-	return f
-}
-
-func funcsymname(s *types.Sym) string {
-	return s.Name + "·f"
-}
-
-// funcsym returns s·f.
-func funcsym(s *types.Sym) *types.Sym {
-	// funcsymsmu here serves to protect not just mutations of funcsyms (below),
-	// but also the package lookup of the func sym name,
-	// since this function gets called concurrently from the backend.
-	// There are no other concurrent package lookups in the backend,
-	// except for the types package, which is protected separately.
-	// Reusing funcsymsmu to also cover this package lookup
-	// avoids a general, broader, expensive package lookup mutex.
-	// Note makefuncsym also does package look-up of func sym names,
-	// but that it is only called serially, from the front end.
-	funcsymsmu.Lock()
-	sf, existed := s.Pkg.LookupOK(funcsymname(s))
-	// Don't export s·f when compiling for dynamic linking.
-	// When dynamically linking, the necessary function
-	// symbols will be created explicitly with makefuncsym.
-	// See the makefuncsym comment for details.
-	if !Ctxt.Flag_dynlink && !existed {
-		funcsyms = append(funcsyms, s)
-	}
-	funcsymsmu.Unlock()
-	return sf
-}
-
-// makefuncsym ensures that s·f is exported.
-// It is only used with -dynlink.
-// When not compiling for dynamic linking,
-// the funcsyms are created as needed by
-// the packages that use them.
-// Normally we emit the s·f stubs as DUPOK syms,
-// but DUPOK doesn't work across shared library boundaries.
-// So instead, when dynamic linking, we only create
-// the s·f stubs in s's package.
-func makefuncsym(s *types.Sym) {
-	if !Ctxt.Flag_dynlink {
-		Fatalf("makefuncsym dynlink")
-	}
-	if s.IsBlank() {
-		return
-	}
-	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 {
-		funcsyms = append(funcsyms, s)
-	}
-}
-
-// setNodeNameFunc marks a node as a function.
-func setNodeNameFunc(n *Node) {
-	if n.Op != ONAME || n.Class() != Pxxx {
-		Fatalf("expected ONAME/Pxxx node, got %v", n)
-	}
-
-	n.SetClass(PFUNC)
-	n.Sym.SetFunc(true)
-}
-
-func dclfunc(sym *types.Sym, tfn *Node) *Node {
-	if tfn.Op != OTFUNC {
-		Fatalf("expected OTFUNC node, got %v", tfn)
-	}
-
-	fn := nod(ODCLFUNC, nil, nil)
-	fn.Func.Nname = newfuncnamel(lineno, sym)
-	fn.Func.Nname.Name.Defn = fn
-	fn.Func.Nname.Name.Param.Ntype = tfn
-	setNodeNameFunc(fn.Func.Nname)
-	funchdr(fn)
-	fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, ctxType)
-	return fn
-}
-
-type nowritebarrierrecChecker struct {
-	// 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
-
-	// curfn is the current function during AST walks.
-	curfn *Node
-}
-
-type nowritebarrierrecCall struct {
-	target *Node    // ODCLFUNC of caller or callee
-	lineno src.XPos // line of call
-}
-
-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),
-	}
-
-	// 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
-		}
-		c.curfn = n
-		inspect(n, c.findExtraCalls)
-	}
-	c.curfn = nil
-	return c
-}
-
-func (c *nowritebarrierrecChecker) findExtraCalls(n *Node) bool {
-	if n.Op != OCALLFUNC {
-		return true
-	}
-	fn := n.Left
-	if fn == nil || fn.Op != ONAME || fn.Class() != PFUNC || fn.Name.Defn == nil {
-		return true
-	}
-	if !isRuntimePkg(fn.Sym.Pkg) || fn.Sym.Name != "systemstack" {
-		return true
-	}
-
-	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)
-	}
-	if callee.Op != ODCLFUNC {
-		Fatalf("expected ODCLFUNC node, got %+v", callee)
-	}
-	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/dep_test.go b/src/cmd/compile/internal/gc/dep_test.go
deleted file mode 100644
index c1dac93..0000000
--- a/src/cmd/compile/internal/gc/dep_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
-	"internal/testenv"
-	"os/exec"
-	"strings"
-	"testing"
-)
-
-func TestDeps(t *testing.T) {
-	out, err := exec.Command(testenv.GoToolPath(t), "list", "-f", "{{.Deps}}", "cmd/compile/internal/gc").Output()
-	if err != nil {
-		t.Fatal(err)
-	}
-	for _, dep := range strings.Fields(strings.Trim(string(out), "[]")) {
-		switch dep {
-		case "go/build", "go/token":
-			t.Errorf("undesired dependency on %q", dep)
-		}
-	}
-}
diff --git a/src/cmd/compile/internal/gc/dump.go b/src/cmd/compile/internal/gc/dump.go
deleted file mode 100644
index 29eb1c1..0000000
--- a/src/cmd/compile/internal/gc/dump.go
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements textual dumping of arbitrary data structures
-// for debugging purposes. The code is customized for Node graphs
-// and may be used for an alternative view of the node structure.
-
-package gc
-
-import (
-	"cmd/compile/internal/types"
-	"cmd/internal/src"
-	"fmt"
-	"io"
-	"os"
-	"reflect"
-	"regexp"
-)
-
-// dump is like fdump but prints to stderr.
-func dump(root interface{}, filter string, depth int) {
-	fdump(os.Stderr, root, filter, depth)
-}
-
-// fdump prints the structure of a rooted data structure
-// to w by depth-first traversal of the data structure.
-//
-// The filter parameter is a regular expression. If it is
-// non-empty, only struct fields whose names match filter
-// are printed.
-//
-// The depth parameter controls how deep traversal recurses
-// before it returns (higher value means greater depth).
-// If an empty field filter is given, a good depth default value
-// is 4. A negative depth means no depth limit, which may be fine
-// for small data structures or if there is a non-empty filter.
-//
-// In the output, Node structs are identified by their Op name
-// rather than their type; struct fields with zero values or
-// non-matching field names are omitted, and "…" means recursion
-// depth has been reached or struct fields have been omitted.
-func fdump(w io.Writer, root interface{}, filter string, depth int) {
-	if root == nil {
-		fmt.Fprintln(w, "nil")
-		return
-	}
-
-	if filter == "" {
-		filter = ".*" // default
-	}
-
-	p := dumper{
-		output:  w,
-		fieldrx: regexp.MustCompile(filter),
-		ptrmap:  make(map[uintptr]int),
-		last:    '\n', // force printing of line number on first line
-	}
-
-	p.dump(reflect.ValueOf(root), depth)
-	p.printf("\n")
-}
-
-type dumper struct {
-	output  io.Writer
-	fieldrx *regexp.Regexp  // field name filter
-	ptrmap  map[uintptr]int // ptr -> dump line number
-	lastadr string          // last address string printed (for shortening)
-
-	// output
-	indent int  // current indentation level
-	last   byte // last byte processed by Write
-	line   int  // current line number
-}
-
-var indentBytes = []byte(".  ")
-
-func (p *dumper) Write(data []byte) (n int, err error) {
-	var m int
-	for i, b := range data {
-		// invariant: data[0:n] has been written
-		if b == '\n' {
-			m, err = p.output.Write(data[n : i+1])
-			n += m
-			if err != nil {
-				return
-			}
-		} else if p.last == '\n' {
-			p.line++
-			_, err = fmt.Fprintf(p.output, "%6d  ", p.line)
-			if err != nil {
-				return
-			}
-			for j := p.indent; j > 0; j-- {
-				_, err = p.output.Write(indentBytes)
-				if err != nil {
-					return
-				}
-			}
-		}
-		p.last = b
-	}
-	if len(data) > n {
-		m, err = p.output.Write(data[n:])
-		n += m
-	}
-	return
-}
-
-// printf is a convenience wrapper.
-func (p *dumper) printf(format string, args ...interface{}) {
-	if _, err := fmt.Fprintf(p, format, args...); err != nil {
-		panic(err)
-	}
-}
-
-// addr returns the (hexadecimal) address string of the object
-// represented by x (or "?" if x is not addressable), with the
-// common prefix between this and the prior address replaced by
-// "0x…" to make it easier to visually match addresses.
-func (p *dumper) addr(x reflect.Value) string {
-	if !x.CanAddr() {
-		return "?"
-	}
-	adr := fmt.Sprintf("%p", x.Addr().Interface())
-	s := adr
-	if i := commonPrefixLen(p.lastadr, adr); i > 0 {
-		s = "0x…" + adr[i:]
-	}
-	p.lastadr = adr
-	return s
-}
-
-// dump prints the contents of x.
-func (p *dumper) dump(x reflect.Value, depth int) {
-	if depth == 0 {
-		p.printf("…")
-		return
-	}
-
-	// special cases
-	switch v := x.Interface().(type) {
-	case Nodes:
-		// unpack Nodes since reflect cannot look inside
-		// due to the unexported field in its struct
-		x = reflect.ValueOf(v.Slice())
-
-	case src.XPos:
-		p.printf("%s", linestr(v))
-		return
-
-	case *types.Node:
-		x = reflect.ValueOf(asNode(v))
-	}
-
-	switch x.Kind() {
-	case reflect.String:
-		p.printf("%q", x.Interface()) // print strings in quotes
-
-	case reflect.Interface:
-		if x.IsNil() {
-			p.printf("nil")
-			return
-		}
-		p.dump(x.Elem(), depth-1)
-
-	case reflect.Ptr:
-		if x.IsNil() {
-			p.printf("nil")
-			return
-		}
-
-		p.printf("*")
-		ptr := x.Pointer()
-		if line, exists := p.ptrmap[ptr]; exists {
-			p.printf("(@%d)", line)
-			return
-		}
-		p.ptrmap[ptr] = p.line
-		p.dump(x.Elem(), depth) // don't count pointer indirection towards depth
-
-	case reflect.Slice:
-		if x.IsNil() {
-			p.printf("nil")
-			return
-		}
-		p.printf("%s (%d entries) {", x.Type(), x.Len())
-		if x.Len() > 0 {
-			p.indent++
-			p.printf("\n")
-			for i, n := 0, x.Len(); i < n; i++ {
-				p.printf("%d: ", i)
-				p.dump(x.Index(i), depth-1)
-				p.printf("\n")
-			}
-			p.indent--
-		}
-		p.printf("}")
-
-	case reflect.Struct:
-		typ := x.Type()
-
-		isNode := false
-		if n, ok := x.Interface().(Node); ok {
-			isNode = true
-			p.printf("%s %s {", n.Op.String(), p.addr(x))
-		} else {
-			p.printf("%s {", typ)
-		}
-		p.indent++
-
-		first := true
-		omitted := false
-		for i, n := 0, typ.NumField(); i < n; i++ {
-			// Exclude non-exported fields because their
-			// values cannot be accessed via reflection.
-			if name := typ.Field(i).Name; types.IsExported(name) {
-				if !p.fieldrx.MatchString(name) {
-					omitted = true
-					continue // field name not selected by filter
-				}
-
-				// special cases
-				if isNode && name == "Op" {
-					omitted = true
-					continue // Op field already printed for Nodes
-				}
-				x := x.Field(i)
-				if isZeroVal(x) {
-					omitted = true
-					continue // exclude zero-valued fields
-				}
-				if n, ok := x.Interface().(Nodes); ok && n.Len() == 0 {
-					omitted = true
-					continue // exclude empty Nodes slices
-				}
-
-				if first {
-					p.printf("\n")
-					first = false
-				}
-				p.printf("%s: ", name)
-				p.dump(x, depth-1)
-				p.printf("\n")
-			}
-		}
-		if omitted {
-			p.printf("…\n")
-		}
-
-		p.indent--
-		p.printf("}")
-
-	default:
-		p.printf("%v", x.Interface())
-	}
-}
-
-func isZeroVal(x reflect.Value) bool {
-	switch x.Kind() {
-	case reflect.Bool:
-		return !x.Bool()
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return x.Int() == 0
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return x.Uint() == 0
-	case reflect.String:
-		return x.String() == ""
-	case reflect.Interface, reflect.Ptr, reflect.Slice:
-		return x.IsNil()
-	}
-	return false
-}
-
-func commonPrefixLen(a, b string) (i int) {
-	for i < len(a) && i < len(b) && a[i] == b[i] {
-		i++
-	}
-	return
-}
diff --git a/src/cmd/compile/internal/gc/dwinl.go b/src/cmd/compile/internal/gc/dwinl.go
deleted file mode 100644
index 31d0768..0000000
--- a/src/cmd/compile/internal/gc/dwinl.go
+++ /dev/null
@@ -1,450 +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 gc
-
-import (
-	"cmd/internal/dwarf"
-	"cmd/internal/obj"
-	"cmd/internal/src"
-	"fmt"
-	"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, 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 {
-		var m map[varPos]int
-		if ii == 0 {
-			if !fnsym.WasInlined() {
-				for j, v := range sl {
-					v.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 _, v := range sl {
-			canonName := unversion(v.Name)
-			vp := varPos{
-				DeclName: canonName,
-				DeclFile: v.DeclFile,
-				DeclLine: v.DeclLine,
-				DeclCol:  v.DeclCol,
-			}
-			synthesized := strings.HasPrefix(v.Name, "~r") || canonName == "_" || strings.HasPrefix(v.Name, "~b")
-			if idx, found := m[vp]; found {
-				v.ChildIndex = int32(idx)
-				v.IsInAbstract = !synthesized
-				v.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 ("_").
-				v.ChildIndex = int32(synthCount)
-				synthCount++
-			}
-		}
-	}
-
-	// Make a second pass through the progs to compute PC ranges for
-	// the various inlined calls.
-	start := int64(-1)
-	curii := -1
-	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
-		}
-		// Close out the current range
-		if start != -1 {
-			addRange(inlcalls.Calls, start, p.Pc, curii, imap)
-		}
-		// Begin new range
-		start = p.Pc
-		curii = ii
-	}
-	if start != -1 {
-		addRange(inlcalls.Calls, start, fnsym.Size, curii, imap)
-	}
-
-	// Issue 33188: if II foo is a child of II bar, then ensure that
-	// bar's ranges include the ranges of foo (the loop above will produce
-	// disjoint ranges).
-	for k, c := range inlcalls.Calls {
-		if c.Root {
-			unifyCallRanges(inlcalls, k)
-		}
-	}
-
-	// Debugging
-	if Debug_gendwarfinl != 0 {
-		dumpInlCalls(inlcalls)
-		dumpInlVars(dwVars)
-	}
-
-	// Perform a consistency check on inlined routine PC ranges
-	// produced by unifyCallRanges above. In particular, complain in
-	// cases where you have A -> B -> C (e.g. C is inlined into B, and
-	// B is inlined into A) and the ranges for B are not enclosed
-	// within the ranges for A, or C within B.
-	for k, c := range inlcalls.Calls {
-		if c.Root {
-			checkInlCall(fnsym.Name, inlcalls, fnsym.Size, k, -1)
-		}
-	}
-
-	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. NB: the recipe for computing variable pos/file/line
-// needs to be kept in sync with the similar code in gc.createSimpleVars
-// and related functions.
-func makePreinlineDclMap(fnsym *obj.LSym) map[varPos]int {
-	dcl := preInliningDcls(fnsym)
-	m := make(map[varPos]int)
-	for i, n := range dcl {
-		pos := Ctxt.InnermostPos(n.Pos)
-		vp := varPos{
-			DeclName: unversion(n.Sym.Name),
-			DeclFile: pos.RelFilename(),
-			DeclLine: pos.RelLine(),
-			DeclCol:  pos.Col(),
-		}
-		if _, found := m[vp]; found {
-			// We can see collisions (variables with the same name/file/line/col) in obfuscated or machine-generated code -- see issue 44378 for an example. Skip duplicates in such cases, since it is unlikely that a human will be debugging such code.
-			continue
-		}
-		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(inlIdx)
-	callXPos := Ctxt.InlTree.CallPos(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 addRange(calls []dwarf.InlCall, start, end int64, ii int, imap map[int]int) {
-	if start == -1 {
-		panic("bad range start")
-	}
-	if end == -1 {
-		panic("bad range end")
-	}
-	if ii == -1 {
-		return
-	}
-	if start == end {
-		return
-	}
-	// Append range to correct inlined call
-	callIdx, found := imap[ii]
-	if !found {
-		Fatalf("can't find inlIndex %d in imap for prog at %d\n", ii, start)
-	}
-	call := &calls[callIdx]
-	call.Ranges = append(call.Ranges, dwarf.Range{Start: start, End: end})
-}
-
-func dumpInlCall(inlcalls dwarf.InlCalls, idx, ilevel int) {
-	for i := 0; i < ilevel; i++ {
-		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) {
-	for k, c := range inlcalls.Calls {
-		if c.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)
-	}
-}
-
-func rangesContains(par []dwarf.Range, rng dwarf.Range) (bool, string) {
-	for _, r := range par {
-		if rng.Start >= r.Start && rng.End <= r.End {
-			return true, ""
-		}
-	}
-	msg := fmt.Sprintf("range [%d,%d) not contained in {", rng.Start, rng.End)
-	for _, r := range par {
-		msg += fmt.Sprintf(" [%d,%d)", r.Start, r.End)
-	}
-	msg += " }"
-	return false, msg
-}
-
-func rangesContainsAll(parent, child []dwarf.Range) (bool, string) {
-	for _, r := range child {
-		c, m := rangesContains(parent, r)
-		if !c {
-			return false, m
-		}
-	}
-	return true, ""
-}
-
-// checkInlCall verifies that the PC ranges for inline info 'idx' are
-// enclosed/contained within the ranges of its parent inline (or if
-// this is a root/toplevel inline, checks that the ranges fall within
-// the extent of the top level function). A panic is issued if a
-// malformed range is found.
-func checkInlCall(funcName string, inlCalls dwarf.InlCalls, funcSize int64, idx, parentIdx int) {
-
-	// Callee
-	ic := inlCalls.Calls[idx]
-	callee := Ctxt.InlTree.InlinedFunction(ic.InlIndex).Name
-	calleeRanges := ic.Ranges
-
-	// Caller
-	caller := funcName
-	parentRanges := []dwarf.Range{dwarf.Range{Start: int64(0), End: funcSize}}
-	if parentIdx != -1 {
-		pic := inlCalls.Calls[parentIdx]
-		caller = Ctxt.InlTree.InlinedFunction(pic.InlIndex).Name
-		parentRanges = pic.Ranges
-	}
-
-	// Callee ranges contained in caller ranges?
-	c, m := rangesContainsAll(parentRanges, calleeRanges)
-	if !c {
-		Fatalf("** malformed inlined routine range in %s: caller %s callee %s II=%d %s\n", funcName, caller, callee, idx, m)
-	}
-
-	// Now visit kids
-	for _, k := range ic.Children {
-		checkInlCall(funcName, inlCalls, funcSize, k, idx)
-	}
-}
-
-// unifyCallRanges ensures that the ranges for a given inline
-// transitively include all of the ranges for its child inlines.
-func unifyCallRanges(inlcalls dwarf.InlCalls, idx int) {
-	ic := &inlcalls.Calls[idx]
-	for _, childIdx := range ic.Children {
-		// First make sure child ranges are unified.
-		unifyCallRanges(inlcalls, childIdx)
-
-		// Then merge child ranges into ranges for this inline.
-		cic := inlcalls.Calls[childIdx]
-		ic.Ranges = dwarf.MergeRanges(ic.Ranges, cic.Ranges)
-	}
-}
diff --git a/src/cmd/compile/internal/gc/embed.go b/src/cmd/compile/internal/gc/embed.go
deleted file mode 100644
index f45796c..0000000
--- a/src/cmd/compile/internal/gc/embed.go
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
-	"cmd/compile/internal/syntax"
-	"cmd/compile/internal/types"
-	"cmd/internal/obj"
-	"encoding/json"
-	"io/ioutil"
-	"log"
-	"path"
-	"sort"
-	"strconv"
-	"strings"
-)
-
-var embedlist []*Node
-
-var embedCfg struct {
-	Patterns map[string][]string
-	Files    map[string]string
-}
-
-func readEmbedCfg(file string) {
-	data, err := ioutil.ReadFile(file)
-	if err != nil {
-		log.Fatalf("-embedcfg: %v", err)
-	}
-	if err := json.Unmarshal(data, &embedCfg); err != nil {
-		log.Fatalf("%s: %v", file, err)
-	}
-	if embedCfg.Patterns == nil {
-		log.Fatalf("%s: invalid embedcfg: missing Patterns", file)
-	}
-	if embedCfg.Files == nil {
-		log.Fatalf("%s: invalid embedcfg: missing Files", file)
-	}
-}
-
-const (
-	embedUnknown = iota
-	embedBytes
-	embedString
-	embedFiles
-)
-
-func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []PragmaEmbed) {
-	haveEmbed := false
-	for _, decl := range p.file.DeclList {
-		imp, ok := decl.(*syntax.ImportDecl)
-		if !ok {
-			// imports always come first
-			break
-		}
-		path, _ := strconv.Unquote(imp.Path.Value)
-		if path == "embed" {
-			haveEmbed = true
-			break
-		}
-	}
-
-	pos := embeds[0].Pos
-	if !haveEmbed {
-		p.yyerrorpos(pos, "invalid go:embed: missing import \"embed\"")
-		return
-	}
-	if len(names) > 1 {
-		p.yyerrorpos(pos, "go:embed cannot apply to multiple vars")
-		return
-	}
-	if len(exprs) > 0 {
-		p.yyerrorpos(pos, "go:embed cannot apply to var with initializer")
-		return
-	}
-	if typ == nil {
-		// Should not happen, since len(exprs) == 0 now.
-		p.yyerrorpos(pos, "go:embed cannot apply to var without type")
-		return
-	}
-	if dclcontext != PEXTERN {
-		p.yyerrorpos(pos, "go:embed cannot apply to var inside func")
-		return
-	}
-
-	var list []irEmbed
-	for _, e := range embeds {
-		list = append(list, irEmbed{Pos: p.makeXPos(e.Pos), Patterns: e.Patterns})
-	}
-	v := names[0]
-	v.Name.Param.SetEmbedList(list)
-	embedlist = append(embedlist, v)
-}
-
-func embedFileList(v *Node, kind int) []string {
-	// Build list of files to store.
-	have := make(map[string]bool)
-	var list []string
-	for _, e := range v.Name.Param.EmbedList() {
-		for _, pattern := range e.Patterns {
-			files, ok := embedCfg.Patterns[pattern]
-			if !ok {
-				yyerrorl(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern)
-			}
-			for _, file := range files {
-				if embedCfg.Files[file] == "" {
-					yyerrorl(e.Pos, "invalid go:embed: build system did not map file: %s", file)
-					continue
-				}
-				if !have[file] {
-					have[file] = true
-					list = append(list, file)
-				}
-				if kind == embedFiles {
-					for dir := path.Dir(file); dir != "." && !have[dir]; dir = path.Dir(dir) {
-						have[dir] = true
-						list = append(list, dir+"/")
-					}
-				}
-			}
-		}
-	}
-	sort.Slice(list, func(i, j int) bool {
-		return embedFileLess(list[i], list[j])
-	})
-
-	if kind == embedString || kind == embedBytes {
-		if len(list) > 1 {
-			yyerrorl(v.Pos, "invalid go:embed: multiple files for type %v", v.Type)
-			return nil
-		}
-	}
-
-	return list
-}
-
-// embedKind determines the kind of embedding variable.
-func embedKind(typ *types.Type) int {
-	if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && myimportpath == "embed")) {
-		return embedFiles
-	}
-	if typ.Etype == types.TSTRING {
-		return embedString
-	}
-	if typ.Etype == types.TSLICE && typ.Elem().Etype == types.TUINT8 {
-		return embedBytes
-	}
-	return embedUnknown
-}
-
-func embedFileNameSplit(name string) (dir, elem string, isDir bool) {
-	if name[len(name)-1] == '/' {
-		isDir = true
-		name = name[:len(name)-1]
-	}
-	i := len(name) - 1
-	for i >= 0 && name[i] != '/' {
-		i--
-	}
-	if i < 0 {
-		return ".", name, isDir
-	}
-	return name[:i], name[i+1:], isDir
-}
-
-// embedFileLess implements the sort order for a list of embedded files.
-// See the comment inside ../../../../embed/embed.go's Files struct for rationale.
-func embedFileLess(x, y string) bool {
-	xdir, xelem, _ := embedFileNameSplit(x)
-	ydir, yelem, _ := embedFileNameSplit(y)
-	return xdir < ydir || xdir == ydir && xelem < yelem
-}
-
-func dumpembeds() {
-	for _, v := range embedlist {
-		initEmbed(v)
-	}
-}
-
-// initEmbed emits the init data for a //go:embed variable,
-// which is either a string, a []byte, or an embed.FS.
-func initEmbed(v *Node) {
-	commentPos := v.Name.Param.EmbedList()[0].Pos
-	if !langSupported(1, 16, localpkg) {
-		lno := lineno
-		lineno = commentPos
-		yyerrorv("go1.16", "go:embed")
-		lineno = lno
-		return
-	}
-	if embedCfg.Patterns == nil {
-		yyerrorl(commentPos, "invalid go:embed: build system did not supply embed configuration")
-		return
-	}
-	kind := embedKind(v.Type)
-	if kind == embedUnknown {
-		yyerrorl(v.Pos, "go:embed cannot apply to var of type %v", v.Type)
-		return
-	}
-
-	files := embedFileList(v, kind)
-	switch kind {
-	case embedString, embedBytes:
-		file := files[0]
-		fsym, size, err := fileStringSym(v.Pos, embedCfg.Files[file], kind == embedString, nil)
-		if err != nil {
-			yyerrorl(v.Pos, "embed %s: %v", file, err)
-		}
-		sym := v.Sym.Linksym()
-		off := 0
-		off = dsymptr(sym, off, fsym, 0)       // data string
-		off = duintptr(sym, off, uint64(size)) // len
-		if kind == embedBytes {
-			duintptr(sym, off, uint64(size)) // cap for slice
-		}
-
-	case embedFiles:
-		slicedata := Ctxt.Lookup(`"".` + v.Sym.Name + `.files`)
-		off := 0
-		// []files pointed at by Files
-		off = dsymptr(slicedata, off, slicedata, 3*Widthptr) // []file, pointing just past slice
-		off = duintptr(slicedata, off, uint64(len(files)))
-		off = duintptr(slicedata, off, uint64(len(files)))
-
-		// embed/embed.go type file is:
-		//	name string
-		//	data string
-		//	hash [16]byte
-		// Emit one of these per file in the set.
-		const hashSize = 16
-		hash := make([]byte, hashSize)
-		for _, file := range files {
-			off = dsymptr(slicedata, off, stringsym(v.Pos, file), 0) // file string
-			off = duintptr(slicedata, off, uint64(len(file)))
-			if strings.HasSuffix(file, "/") {
-				// entry for directory - no data
-				off = duintptr(slicedata, off, 0)
-				off = duintptr(slicedata, off, 0)
-				off += hashSize
-			} else {
-				fsym, size, err := fileStringSym(v.Pos, embedCfg.Files[file], true, hash)
-				if err != nil {
-					yyerrorl(v.Pos, "embed %s: %v", file, err)
-				}
-				off = dsymptr(slicedata, off, fsym, 0) // data string
-				off = duintptr(slicedata, off, uint64(size))
-				off = int(slicedata.WriteBytes(Ctxt, int64(off), hash))
-			}
-		}
-		ggloblsym(slicedata, int32(off), obj.RODATA|obj.LOCAL)
-		sym := v.Sym.Linksym()
-		dsymptr(sym, 0, slicedata, 0)
-	}
-}
diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go
deleted file mode 100644
index 6f328ab..0000000
--- a/src/cmd/compile/internal/gc/esc.go
+++ /dev/null
@@ -1,472 +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
-
-import (
-	"cmd/compile/internal/types"
-	"fmt"
-)
-
-func escapes(all []*Node) {
-	visitBottomUp(all, escapeFuncs)
-}
-
-const (
-	EscFuncUnknown = 0 + iota
-	EscFuncPlanned
-	EscFuncStarted
-	EscFuncTagged
-)
-
-func min8(a, b int8) int8 {
-	if a < b {
-		return a
-	}
-	return b
-}
-
-func max8(a, b int8) int8 {
-	if a > b {
-		return a
-	}
-	return b
-}
-
-const (
-	EscUnknown = iota
-	EscNone    // Does not escape to heap, result, or parameters.
-	EscHeap    // Reachable from the heap
-	EscNever   // By construction will not escape.
-)
-
-// funcSym returns fn.Func.Nname.Sym if no nils are encountered along the way.
-func funcSym(fn *Node) *types.Sym {
-	if fn == nil || fn.Func.Nname == nil {
-		return nil
-	}
-	return fn.Func.Nname.Sym
-}
-
-// Mark labels that have no backjumps to them as not increasing e.loopdepth.
-// Walk hasn't generated (goto|label).Left.Sym.Label yet, so we'll cheat
-// and set it to one of the following two. Then in esc we'll clear it again.
-var (
-	looping    Node
-	nonlooping Node
-)
-
-func isSliceSelfAssign(dst, src *Node) bool {
-	// Detect the following special case.
-	//
-	//	func (b *Buffer) Foo() {
-	//		n, m := ...
-	//		b.buf = b.buf[n:m]
-	//	}
-	//
-	// This assignment is a no-op for escape analysis,
-	// it does not store any new pointers into b that were not already there.
-	// However, without this special case b will escape, because we assign to OIND/ODOTPTR.
-	// Here we assume that the statement will not contain calls,
-	// that is, that order will move any calls to init.
-	// Otherwise base ONAME value could change between the moments
-	// when we evaluate it for dst and for src.
-
-	// dst is ONAME dereference.
-	if dst.Op != ODEREF && dst.Op != ODOTPTR || dst.Left.Op != ONAME {
-		return false
-	}
-	// src is a slice operation.
-	switch src.Op {
-	case OSLICE, OSLICE3, OSLICESTR:
-		// OK.
-	case OSLICEARR, OSLICE3ARR:
-		// Since arrays are embedded into containing object,
-		// slice of non-pointer array will introduce a new pointer into b that was not already there
-		// (pointer to b itself). After such assignment, if b contents escape,
-		// b escapes as well. If we ignore such OSLICEARR, we will conclude
-		// that b does not escape when b contents do.
-		//
-		// Pointer to an array is OK since it's not stored inside b directly.
-		// For slicing an array (not pointer to array), there is an implicit OADDR.
-		// We check that to determine non-pointer array slicing.
-		if src.Left.Op == OADDR {
-			return false
-		}
-	default:
-		return false
-	}
-	// slice is applied to ONAME dereference.
-	if src.Left.Op != ODEREF && src.Left.Op != ODOTPTR || src.Left.Left.Op != ONAME {
-		return false
-	}
-	// dst and src reference the same base ONAME.
-	return dst.Left == src.Left.Left
-}
-
-// isSelfAssign reports whether assignment from src to dst can
-// be ignored by the escape analysis as it's effectively a self-assignment.
-func isSelfAssign(dst, src *Node) bool {
-	if isSliceSelfAssign(dst, src) {
-		return true
-	}
-
-	// Detect trivial assignments that assign back to the same object.
-	//
-	// It covers these cases:
-	//	val.x = val.y
-	//	val.x[i] = val.y[j]
-	//	val.x1.x2 = val.x1.y2
-	//	... etc
-	//
-	// These assignments do not change assigned object lifetime.
-
-	if dst == nil || src == nil || dst.Op != src.Op {
-		return false
-	}
-
-	switch dst.Op {
-	case ODOT, ODOTPTR:
-		// Safe trailing accessors that are permitted to differ.
-	case OINDEX:
-		if mayAffectMemory(dst.Right) || mayAffectMemory(src.Right) {
-			return false
-		}
-	default:
-		return false
-	}
-
-	// The expression prefix must be both "safe" and identical.
-	return samesafeexpr(dst.Left, src.Left)
-}
-
-// mayAffectMemory reports whether evaluation of n may affect the program's
-// memory state. If the expression can't affect memory state, then it can be
-// safely ignored by the escape analysis.
-func mayAffectMemory(n *Node) bool {
-	// We may want to use a list of "memory safe" ops instead of generally
-	// "side-effect free", which would include all calls and other ops that can
-	// allocate or change global state. For now, it's safer to start with the latter.
-	//
-	// We're ignoring things like division by zero, index out of range,
-	// and nil pointer dereference here.
-	switch n.Op {
-	case ONAME, OCLOSUREVAR, OLITERAL:
-		return false
-
-	// Left+Right group.
-	case OINDEX, OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
-		return mayAffectMemory(n.Left) || mayAffectMemory(n.Right)
-
-	// Left group.
-	case ODOT, ODOTPTR, ODEREF, OCONVNOP, OCONV, OLEN, OCAP,
-		ONOT, OBITNOT, OPLUS, ONEG, OALIGNOF, OOFFSETOF, OSIZEOF:
-		return mayAffectMemory(n.Left)
-
-	default:
-		return true
-	}
-}
-
-// heapAllocReason returns the reason the given Node must be heap
-// allocated, or the empty string if it doesn't.
-func heapAllocReason(n *Node) string {
-	if n.Type == nil {
-		return ""
-	}
-
-	// Parameters are always passed via the stack.
-	if n.Op == ONAME && (n.Class() == PPARAM || n.Class() == PPARAMOUT) {
-		return ""
-	}
-
-	if n.Type.Width > maxStackVarSize {
-		return "too large for stack"
-	}
-
-	if (n.Op == ONEW || n.Op == OPTRLIT) && n.Type.Elem().Width >= maxImplicitStackVarSize {
-		return "too large for stack"
-	}
-
-	if n.Op == OCLOSURE && closureType(n).Size() >= maxImplicitStackVarSize {
-		return "too large for stack"
-	}
-	if n.Op == OCALLPART && partialCallType(n).Size() >= maxImplicitStackVarSize {
-		return "too large for stack"
-	}
-
-	if n.Op == OMAKESLICE {
-		r := n.Right
-		if r == nil {
-			r = n.Left
-		}
-		if !smallintconst(r) {
-			return "non-constant size"
-		}
-		if t := n.Type; t.Elem().Width != 0 && r.Int64Val() >= maxImplicitStackVarSize/t.Elem().Width {
-			return "too large for stack"
-		}
-	}
-
-	return ""
-}
-
-// addrescapes tags node n as having had its address taken
-// by "increasing" the "value" of n.Esc to EscHeap.
-// Storage is allocated as necessary to allow the address
-// to be taken.
-func addrescapes(n *Node) {
-	switch n.Op {
-	default:
-		// Unexpected Op, probably due to a previous type error. Ignore.
-
-	case ODEREF, ODOTPTR:
-		// Nothing to do.
-
-	case ONAME:
-		if n == nodfp {
-			break
-		}
-
-		// if this is a tmpname (PAUTO), it was tagged by tmpname as not escaping.
-		// on PPARAM it means something different.
-		if n.Class() == PAUTO && n.Esc == EscNever {
-			break
-		}
-
-		// If a closure reference escapes, mark the outer variable as escaping.
-		if n.Name.IsClosureVar() {
-			addrescapes(n.Name.Defn)
-			break
-		}
-
-		if n.Class() != PPARAM && n.Class() != PPARAMOUT && n.Class() != PAUTO {
-			break
-		}
-
-		// This is a plain parameter or local variable that needs to move to the heap,
-		// but possibly for the function outside the one we're compiling.
-		// That is, if we have:
-		//
-		//	func f(x int) {
-		//		func() {
-		//			global = &x
-		//		}
-		//	}
-		//
-		// then we're analyzing the inner closure but we need to move x to the
-		// heap in f, not in the inner closure. Flip over to f before calling moveToHeap.
-		oldfn := Curfn
-		Curfn = n.Name.Curfn
-		if Curfn.Func.Closure != nil && Curfn.Op == OCLOSURE {
-			Curfn = Curfn.Func.Closure
-		}
-		ln := lineno
-		lineno = Curfn.Pos
-		moveToHeap(n)
-		Curfn = oldfn
-		lineno = ln
-
-	// ODOTPTR has already been introduced,
-	// so these are the non-pointer ODOT and OINDEX.
-	// In &x[0], if x is a slice, then x does not
-	// escape--the pointer inside x does, but that
-	// is always a heap pointer anyway.
-	case ODOT, OINDEX, OPAREN, OCONVNOP:
-		if !n.Left.Type.IsSlice() {
-			addrescapes(n.Left)
-		}
-	}
-}
-
-// moveToHeap records the parameter or local variable n as moved to the heap.
-func moveToHeap(n *Node) {
-	if Debug.r != 0 {
-		Dump("MOVE", n)
-	}
-	if compiling_runtime {
-		yyerror("%v escapes to heap, not allowed in runtime", n)
-	}
-	if n.Class() == PAUTOHEAP {
-		Dump("n", n)
-		Fatalf("double move to heap")
-	}
-
-	// Allocate a local stack variable to hold the pointer to the heap copy.
-	// temp will add it to the function declaration list automatically.
-	heapaddr := temp(types.NewPtr(n.Type))
-	heapaddr.Sym = lookup("&" + n.Sym.Name)
-	heapaddr.Orig.Sym = heapaddr.Sym
-	heapaddr.Pos = n.Pos
-
-	// Unset AutoTemp to persist the &foo variable name through SSA to
-	// liveness analysis.
-	// TODO(mdempsky/drchase): Cleaner solution?
-	heapaddr.Name.SetAutoTemp(false)
-
-	// Parameters have a local stack copy used at function start/end
-	// in addition to the copy in the heap that may live longer than
-	// the function.
-	if n.Class() == PPARAM || n.Class() == PPARAMOUT {
-		if n.Xoffset == BADWIDTH {
-			Fatalf("addrescapes before param assignment")
-		}
-
-		// We rewrite n below to be a heap variable (indirection of heapaddr).
-		// Preserve a copy so we can still write code referring to the original,
-		// and substitute that copy into the function declaration list
-		// so that analyses of the local (on-stack) variables use it.
-		stackcopy := newname(n.Sym)
-		stackcopy.Type = n.Type
-		stackcopy.Xoffset = n.Xoffset
-		stackcopy.SetClass(n.Class())
-		stackcopy.Name.Param.Heapaddr = heapaddr
-		if n.Class() == PPARAMOUT {
-			// Make sure the pointer to the heap copy is kept live throughout the function.
-			// The function could panic at any point, and then a defer could recover.
-			// Thus, we need the pointer to the heap copy always available so the
-			// post-deferreturn code can copy the return value back to the stack.
-			// See issue 16095.
-			heapaddr.Name.SetIsOutputParamHeapAddr(true)
-		}
-		n.Name.Param.Stackcopy = stackcopy
-
-		// Substitute the stackcopy into the function variable list so that
-		// liveness and other analyses use the underlying stack slot
-		// and not the now-pseudo-variable n.
-		found := false
-		for i, d := range Curfn.Func.Dcl {
-			if d == n {
-				Curfn.Func.Dcl[i] = stackcopy
-				found = true
-				break
-			}
-			// Parameters are before locals, so can stop early.
-			// This limits the search even in functions with many local variables.
-			if d.Class() == PAUTO {
-				break
-			}
-		}
-		if !found {
-			Fatalf("cannot find %v in local variable list", n)
-		}
-		Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
-	}
-
-	// Modify n in place so that uses of n now mean indirection of the heapaddr.
-	n.SetClass(PAUTOHEAP)
-	n.Xoffset = 0
-	n.Name.Param.Heapaddr = heapaddr
-	n.Esc = EscHeap
-	if Debug.m != 0 {
-		Warnl(n.Pos, "moved to heap: %v", n)
-	}
-}
-
-// This special tag is applied to uintptr variables
-// that we believe may hold unsafe.Pointers for
-// calls into assembly functions.
-const unsafeUintptrTag = "unsafe-uintptr"
-
-// This special tag is applied to uintptr parameters of functions
-// marked go:uintptrescapes.
-const uintptrEscapesTag = "uintptr-escapes"
-
-func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
-	name := func() string {
-		if f.Sym != nil {
-			return f.Sym.Name
-		}
-		return fmt.Sprintf("arg#%d", narg)
-	}
-
-	if fn.Nbody.Len() == 0 {
-		// Assume that uintptr arguments must be held live across the call.
-		// This is most important for syscall.Syscall.
-		// See golang.org/issue/13372.
-		// This really doesn't have much to do with escape analysis per se,
-		// but we are reusing the ability to annotate an individual function
-		// argument and pass those annotations along to importing code.
-		if f.Type.IsUintptr() {
-			if Debug.m != 0 {
-				Warnl(f.Pos, "assuming %v is unsafe uintptr", name())
-			}
-			return unsafeUintptrTag
-		}
-
-		if !f.Type.HasPointers() { // don't bother tagging for scalars
-			return ""
-		}
-
-		var esc EscLeaks
-
-		// External functions are assumed unsafe, unless
-		// //go:noescape is given before the declaration.
-		if fn.Func.Pragma&Noescape != 0 {
-			if Debug.m != 0 && f.Sym != nil {
-				Warnl(f.Pos, "%v does not escape", name())
-			}
-		} else {
-			if Debug.m != 0 && f.Sym != nil {
-				Warnl(f.Pos, "leaking param: %v", name())
-			}
-			esc.AddHeap(0)
-		}
-
-		return esc.Encode()
-	}
-
-	if fn.Func.Pragma&UintptrEscapes != 0 {
-		if f.Type.IsUintptr() {
-			if Debug.m != 0 {
-				Warnl(f.Pos, "marking %v as escaping uintptr", name())
-			}
-			return uintptrEscapesTag
-		}
-		if f.IsDDD() && f.Type.Elem().IsUintptr() {
-			// final argument is ...uintptr.
-			if Debug.m != 0 {
-				Warnl(f.Pos, "marking %v as escaping ...uintptr", name())
-			}
-			return uintptrEscapesTag
-		}
-	}
-
-	if !f.Type.HasPointers() { // don't bother tagging for scalars
-		return ""
-	}
-
-	// Unnamed parameters are unused and therefore do not escape.
-	if f.Sym == nil || f.Sym.IsBlank() {
-		var esc EscLeaks
-		return esc.Encode()
-	}
-
-	n := asNode(f.Nname)
-	loc := e.oldLoc(n)
-	esc := loc.paramEsc
-	esc.Optimize()
-
-	if Debug.m != 0 && !loc.escapes {
-		if esc.Empty() {
-			Warnl(f.Pos, "%v does not escape", name())
-		}
-		if x := esc.Heap(); x >= 0 {
-			if x == 0 {
-				Warnl(f.Pos, "leaking param: %v", name())
-			} else {
-				// TODO(mdempsky): Mention level=x like below?
-				Warnl(f.Pos, "leaking param content: %v", name())
-			}
-		}
-		for i := 0; i < numEscResults; i++ {
-			if x := esc.Result(i); x >= 0 {
-				res := fn.Type.Results().Field(i).Sym
-				Warnl(f.Pos, "leaking param: %v to result %v level=%d", name(), res, x)
-			}
-		}
-	}
-
-	return esc.Encode()
-}
diff --git a/src/cmd/compile/internal/gc/escape.go b/src/cmd/compile/internal/gc/escape.go
deleted file mode 100644
index f719892..0000000
--- a/src/cmd/compile/internal/gc/escape.go
+++ /dev/null
@@ -1,1539 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
-	"cmd/compile/internal/logopt"
-	"cmd/compile/internal/types"
-	"cmd/internal/src"
-	"fmt"
-	"math"
-	"strings"
-)
-
-// Escape analysis.
-//
-// Here we analyze functions to determine which Go variables
-// (including implicit allocations such as calls to "new" or "make",
-// composite literals, etc.) can be allocated on the stack. The two
-// key invariants we have to ensure are: (1) pointers to stack objects
-// cannot be stored in the heap, and (2) pointers to a stack object
-// cannot outlive that object (e.g., because the declaring function
-// returned and destroyed the object's stack frame, or its space is
-// reused across loop iterations for logically distinct variables).
-//
-// We implement this with a static data-flow analysis of the AST.
-// First, we construct a directed weighted graph where vertices
-// (termed "locations") represent variables allocated by statements
-// and expressions, and edges represent assignments between variables
-// (with weights representing addressing/dereference counts).
-//
-// Next we walk the graph looking for assignment paths that might
-// violate the invariants stated above. If a variable v's address is
-// stored in the heap or elsewhere that may outlive it, then v is
-// marked as requiring heap allocation.
-//
-// To support interprocedural analysis, we also record data-flow from
-// each function's parameters to the heap and to its result
-// parameters. This information is summarized as "parameter tags",
-// which are used at static call sites to improve escape analysis of
-// function arguments.
-
-// Constructing the location graph.
-//
-// Every allocating statement (e.g., variable declaration) or
-// expression (e.g., "new" or "make") is first mapped to a unique
-// "location."
-//
-// We also model every Go assignment as a directed edges between
-// locations. The number of dereference operations minus the number of
-// addressing operations is recorded as the edge's weight (termed
-// "derefs"). For example:
-//
-//     p = &q    // -1
-//     p = q     //  0
-//     p = *q    //  1
-//     p = **q   //  2
-//
-//     p = **&**&q  // 2
-//
-// Note that the & operator can only be applied to addressable
-// expressions, and the expression &x itself is not addressable, so
-// derefs cannot go below -1.
-//
-// Every Go language construct is lowered into this representation,
-// generally without sensitivity to flow, path, or context; and
-// without distinguishing elements within a compound variable. For
-// example:
-//
-//     var x struct { f, g *int }
-//     var u []*int
-//
-//     x.f = u[0]
-//
-// is modeled simply as
-//
-//     x = *u
-//
-// That is, we don't distinguish x.f from x.g, or u[0] from u[1],
-// u[2], etc. However, we do record the implicit dereference involved
-// in indexing a slice.
-
-type Escape struct {
-	allLocs []*EscLocation
-
-	curfn *Node
-
-	// loopDepth counts the current loop nesting depth within
-	// curfn. It increments within each "for" loop and at each
-	// label with a corresponding backwards "goto" (i.e.,
-	// unstructured loop).
-	loopDepth int
-
-	heapLoc  EscLocation
-	blankLoc EscLocation
-}
-
-// An EscLocation represents an abstract location that stores a Go
-// variable.
-type EscLocation struct {
-	n         *Node     // represented variable or expression, if any
-	curfn     *Node     // enclosing function
-	edges     []EscEdge // incoming edges
-	loopDepth int       // loopDepth at declaration
-
-	// derefs and walkgen are used during walkOne to track the
-	// minimal dereferences from the walk root.
-	derefs  int // >= -1
-	walkgen uint32
-
-	// dst and dstEdgeindex track the next immediate assignment
-	// destination location during walkone, along with the index
-	// of the edge pointing back to this location.
-	dst        *EscLocation
-	dstEdgeIdx int
-
-	// queued is used by walkAll to track whether this location is
-	// in the walk queue.
-	queued bool
-
-	// escapes reports whether the represented variable's address
-	// escapes; that is, whether the variable must be heap
-	// allocated.
-	escapes bool
-
-	// transient reports whether the represented expression's
-	// address does not outlive the statement; that is, whether
-	// its storage can be immediately reused.
-	transient bool
-
-	// paramEsc records the represented parameter's leak set.
-	paramEsc EscLeaks
-}
-
-// An EscEdge represents an assignment edge between two Go variables.
-type EscEdge struct {
-	src    *EscLocation
-	derefs int // >= -1
-	notes  *EscNote
-}
-
-// escapeFuncs performs escape analysis on a minimal batch of
-// functions.
-func escapeFuncs(fns []*Node, recursive bool) {
-	for _, fn := range fns {
-		if fn.Op != ODCLFUNC {
-			Fatalf("unexpected node: %v", fn)
-		}
-	}
-
-	var e Escape
-	e.heapLoc.escapes = true
-
-	// Construct data-flow graph from syntax trees.
-	for _, fn := range fns {
-		e.initFunc(fn)
-	}
-	for _, fn := range fns {
-		e.walkFunc(fn)
-	}
-	e.curfn = nil
-
-	e.walkAll()
-	e.finish(fns)
-}
-
-func (e *Escape) initFunc(fn *Node) {
-	if fn.Op != ODCLFUNC || fn.Esc != EscFuncUnknown {
-		Fatalf("unexpected node: %v", fn)
-	}
-	fn.Esc = EscFuncPlanned
-	if Debug.m > 3 {
-		Dump("escAnalyze", fn)
-	}
-
-	e.curfn = fn
-	e.loopDepth = 1
-
-	// Allocate locations for local variables.
-	for _, dcl := range fn.Func.Dcl {
-		if dcl.Op == ONAME {
-			e.newLoc(dcl, false)
-		}
-	}
-}
-
-func (e *Escape) walkFunc(fn *Node) {
-	fn.Esc = EscFuncStarted
-
-	// Identify labels that mark the head of an unstructured loop.
-	inspectList(fn.Nbody, func(n *Node) bool {
-		switch n.Op {
-		case OLABEL:
-			n.Sym.Label = asTypesNode(&nonlooping)
-
-		case OGOTO:
-			// If we visited the label before the goto,
-			// then this is a looping label.
-			if n.Sym.Label == asTypesNode(&nonlooping) {
-				n.Sym.Label = asTypesNode(&looping)
-			}
-		}
-
-		return true
-	})
-
-	e.curfn = fn
-	e.loopDepth = 1
-	e.block(fn.Nbody)
-}
-
-// Below we implement the methods for walking the AST and recording
-// data flow edges. Note that because a sub-expression might have
-// side-effects, it's important to always visit the entire AST.
-//
-// For example, write either:
-//
-//     if x {
-//         e.discard(n.Left)
-//     } else {
-//         e.value(k, n.Left)
-//     }
-//
-// or
-//
-//     if x {
-//         k = e.discardHole()
-//     }
-//     e.value(k, n.Left)
-//
-// Do NOT write:
-//
-//    // BAD: possibly loses side-effects within n.Left
-//    if !x {
-//        e.value(k, n.Left)
-//    }
-
-// stmt evaluates a single Go statement.
-func (e *Escape) stmt(n *Node) {
-	if n == nil {
-		return
-	}
-
-	lno := setlineno(n)
-	defer func() {
-		lineno = lno
-	}()
-
-	if Debug.m > 2 {
-		fmt.Printf("%v:[%d] %v stmt: %v\n", linestr(lineno), e.loopDepth, funcSym(e.curfn), n)
-	}
-
-	e.stmts(n.Ninit)
-
-	switch n.Op {
-	default:
-		Fatalf("unexpected stmt: %v", n)
-
-	case ODCLCONST, ODCLTYPE, OEMPTY, OFALL, OINLMARK:
-		// nop
-
-	case OBREAK, OCONTINUE, OGOTO:
-		// TODO(mdempsky): Handle dead code?
-
-	case OBLOCK:
-		e.stmts(n.List)
-
-	case ODCL:
-		// Record loop depth at declaration.
-		if !n.Left.isBlank() {
-			e.dcl(n.Left)
-		}
-
-	case OLABEL:
-		switch asNode(n.Sym.Label) {
-		case &nonlooping:
-			if Debug.m > 2 {
-				fmt.Printf("%v:%v non-looping label\n", linestr(lineno), n)
-			}
-		case &looping:
-			if Debug.m > 2 {
-				fmt.Printf("%v: %v looping label\n", linestr(lineno), n)
-			}
-			e.loopDepth++
-		default:
-			Fatalf("label missing tag")
-		}
-		n.Sym.Label = nil
-
-	case OIF:
-		e.discard(n.Left)
-		e.block(n.Nbody)
-		e.block(n.Rlist)
-
-	case OFOR, OFORUNTIL:
-		e.loopDepth++
-		e.discard(n.Left)
-		e.stmt(n.Right)
-		e.block(n.Nbody)
-		e.loopDepth--
-
-	case ORANGE:
-		// for List = range Right { Nbody }
-		e.loopDepth++
-		ks := e.addrs(n.List)
-		e.block(n.Nbody)
-		e.loopDepth--
-
-		// Right is evaluated outside the loop.
-		k := e.discardHole()
-		if len(ks) >= 2 {
-			if n.Right.Type.IsArray() {
-				k = ks[1].note(n, "range")
-			} else {
-				k = ks[1].deref(n, "range-deref")
-			}
-		}
-		e.expr(e.later(k), n.Right)
-
-	case OSWITCH:
-		typesw := n.Left != nil && n.Left.Op == OTYPESW
-
-		var ks []EscHole
-		for _, cas := range n.List.Slice() { // cases
-			if typesw && n.Left.Left != nil {
-				cv := cas.Rlist.First()
-				k := e.dcl(cv) // type switch variables have no ODCL.
-				if cv.Type.HasPointers() {
-					ks = append(ks, k.dotType(cv.Type, cas, "switch case"))
-				}
-			}
-
-			e.discards(cas.List)
-			e.block(cas.Nbody)
-		}
-
-		if typesw {
-			e.expr(e.teeHole(ks...), n.Left.Right)
-		} else {
-			e.discard(n.Left)
-		}
-
-	case OSELECT:
-		for _, cas := range n.List.Slice() {
-			e.stmt(cas.Left)
-			e.block(cas.Nbody)
-		}
-	case OSELRECV:
-		e.assign(n.Left, n.Right, "selrecv", n)
-	case OSELRECV2:
-		e.assign(n.Left, n.Right, "selrecv", n)
-		e.assign(n.List.First(), nil, "selrecv", n)
-	case ORECV:
-		// TODO(mdempsky): Consider e.discard(n.Left).
-		e.exprSkipInit(e.discardHole(), n) // already visited n.Ninit
-	case OSEND:
-		e.discard(n.Left)
-		e.assignHeap(n.Right, "send", n)
-
-	case OAS, OASOP:
-		e.assign(n.Left, n.Right, "assign", n)
-
-	case OAS2:
-		for i, nl := range n.List.Slice() {
-			e.assign(nl, n.Rlist.Index(i), "assign-pair", n)
-		}
-
-	case OAS2DOTTYPE: // v, ok = x.(type)
-		e.assign(n.List.First(), n.Right, "assign-pair-dot-type", n)
-		e.assign(n.List.Second(), nil, "assign-pair-dot-type", n)
-	case OAS2MAPR: // v, ok = m[k]
-		e.assign(n.List.First(), n.Right, "assign-pair-mapr", n)
-		e.assign(n.List.Second(), nil, "assign-pair-mapr", n)
-	case OAS2RECV: // v, ok = <-ch
-		e.assign(n.List.First(), n.Right, "assign-pair-receive", n)
-		e.assign(n.List.Second(), nil, "assign-pair-receive", n)
-
-	case OAS2FUNC:
-		e.stmts(n.Right.Ninit)
-		e.call(e.addrs(n.List), n.Right, nil)
-	case ORETURN:
-		results := e.curfn.Type.Results().FieldSlice()
-		for i, v := range n.List.Slice() {
-			e.assign(asNode(results[i].Nname), v, "return", n)
-		}
-	case OCALLFUNC, OCALLMETH, OCALLINTER, OCLOSE, OCOPY, ODELETE, OPANIC, OPRINT, OPRINTN, ORECOVER:
-		e.call(nil, n, nil)
-	case OGO, ODEFER:
-		e.stmts(n.Left.Ninit)
-		e.call(nil, n.Left, n)
-
-	case ORETJMP:
-		// TODO(mdempsky): What do? esc.go just ignores it.
-	}
-}
-
-func (e *Escape) stmts(l Nodes) {
-	for _, n := range l.Slice() {
-		e.stmt(n)
-	}
-}
-
-// block is like stmts, but preserves loopDepth.
-func (e *Escape) block(l Nodes) {
-	old := e.loopDepth
-	e.stmts(l)
-	e.loopDepth = old
-}
-
-// expr models evaluating an expression n and flowing the result into
-// hole k.
-func (e *Escape) expr(k EscHole, n *Node) {
-	if n == nil {
-		return
-	}
-	e.stmts(n.Ninit)
-	e.exprSkipInit(k, n)
-}
-
-func (e *Escape) exprSkipInit(k EscHole, n *Node) {
-	if n == nil {
-		return
-	}
-
-	lno := setlineno(n)
-	defer func() {
-		lineno = lno
-	}()
-
-	uintptrEscapesHack := k.uintptrEscapesHack
-	k.uintptrEscapesHack = false
-
-	if uintptrEscapesHack && n.Op == OCONVNOP && n.Left.Type.IsUnsafePtr() {
-		// nop
-	} else if k.derefs >= 0 && !n.Type.HasPointers() {
-		k = e.discardHole()
-	}
-
-	switch n.Op {
-	default:
-		Fatalf("unexpected expr: %v", n)
-
-	case OLITERAL, OGETG, OCLOSUREVAR, OTYPE:
-		// nop
-
-	case ONAME:
-		if n.Class() == PFUNC || n.Class() == PEXTERN {
-			return
-		}
-		e.flow(k, e.oldLoc(n))
-
-	case OPLUS, ONEG, OBITNOT, ONOT:
-		e.discard(n.Left)
-	case OADD, OSUB, OOR, OXOR, OMUL, ODIV, OMOD, OLSH, ORSH, OAND, OANDNOT, OEQ, ONE, OLT, OLE, OGT, OGE, OANDAND, OOROR:
-		e.discard(n.Left)
-		e.discard(n.Right)
-
-	case OADDR:
-		e.expr(k.addr(n, "address-of"), n.Left) // "address-of"
-	case ODEREF:
-		e.expr(k.deref(n, "indirection"), n.Left) // "indirection"
-	case ODOT, ODOTMETH, ODOTINTER:
-		e.expr(k.note(n, "dot"), n.Left)
-	case ODOTPTR:
-		e.expr(k.deref(n, "dot of pointer"), n.Left) // "dot of pointer"
-	case ODOTTYPE, ODOTTYPE2:
-		e.expr(k.dotType(n.Type, n, "dot"), n.Left)
-	case OINDEX:
-		if n.Left.Type.IsArray() {
-			e.expr(k.note(n, "fixed-array-index-of"), n.Left)
-		} else {
-			// TODO(mdempsky): Fix why reason text.
-			e.expr(k.deref(n, "dot of pointer"), n.Left)
-		}
-		e.discard(n.Right)
-	case OINDEXMAP:
-		e.discard(n.Left)
-		e.discard(n.Right)
-	case OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR:
-		e.expr(k.note(n, "slice"), n.Left)
-		low, high, max := n.SliceBounds()
-		e.discard(low)
-		e.discard(high)
-		e.discard(max)
-
-	case OCONV, OCONVNOP:
-		if checkPtr(e.curfn, 2) && n.Type.IsUnsafePtr() && n.Left.Type.IsPtr() {
-			// When -d=checkptr=2 is enabled, treat
-			// conversions to unsafe.Pointer as an
-			// escaping operation. This allows better
-			// runtime instrumentation, since we can more
-			// easily detect object boundaries on the heap
-			// than the stack.
-			e.assignHeap(n.Left, "conversion to unsafe.Pointer", n)
-		} else if n.Type.IsUnsafePtr() && n.Left.Type.IsUintptr() {
-			e.unsafeValue(k, n.Left)
-		} else {
-			e.expr(k, n.Left)
-		}
-	case OCONVIFACE:
-		if !n.Left.Type.IsInterface() && !isdirectiface(n.Left.Type) {
-			k = e.spill(k, n)
-		}
-		e.expr(k.note(n, "interface-converted"), n.Left)
-
-	case ORECV:
-		e.discard(n.Left)
-
-	case OCALLMETH, OCALLFUNC, OCALLINTER, OLEN, OCAP, OCOMPLEX, OREAL, OIMAG, OAPPEND, OCOPY:
-		e.call([]EscHole{k}, n, nil)
-
-	case ONEW:
-		e.spill(k, n)
-
-	case OMAKESLICE:
-		e.spill(k, n)
-		e.discard(n.Left)
-		e.discard(n.Right)
-	case OMAKECHAN:
-		e.discard(n.Left)
-	case OMAKEMAP:
-		e.spill(k, n)
-		e.discard(n.Left)
-
-	case ORECOVER:
-		// nop
-
-	case OCALLPART:
-		// Flow the receiver argument to both the closure and
-		// to the receiver parameter.
-
-		closureK := e.spill(k, n)
-
-		m := callpartMethod(n)
-
-		// We don't know how the method value will be called
-		// later, so conservatively assume the result
-		// parameters all flow to the heap.
-		//
-		// TODO(mdempsky): Change ks into a callback, so that
-		// we don't have to create this dummy slice?
-		var ks []EscHole
-		for i := m.Type.NumResults(); i > 0; i-- {
-			ks = append(ks, e.heapHole())
-		}
-		paramK := e.tagHole(ks, asNode(m.Type.Nname()), m.Type.Recv())
-
-		e.expr(e.teeHole(paramK, closureK), n.Left)
-
-	case OPTRLIT:
-		e.expr(e.spill(k, n), n.Left)
-
-	case OARRAYLIT:
-		for _, elt := range n.List.Slice() {
-			if elt.Op == OKEY {
-				elt = elt.Right
-			}
-			e.expr(k.note(n, "array literal element"), elt)
-		}
-
-	case OSLICELIT:
-		k = e.spill(k, n)
-		k.uintptrEscapesHack = uintptrEscapesHack // for ...uintptr parameters
-
-		for _, elt := range n.List.Slice() {
-			if elt.Op == OKEY {
-				elt = elt.Right
-			}
-			e.expr(k.note(n, "slice-literal-element"), elt)
-		}
-
-	case OSTRUCTLIT:
-		for _, elt := range n.List.Slice() {
-			e.expr(k.note(n, "struct literal element"), elt.Left)
-		}
-
-	case OMAPLIT:
-		e.spill(k, n)
-
-		// Map keys and values are always stored in the heap.
-		for _, elt := range n.List.Slice() {
-			e.assignHeap(elt.Left, "map literal key", n)
-			e.assignHeap(elt.Right, "map literal value", n)
-		}
-
-	case OCLOSURE:
-		k = e.spill(k, n)
-
-		// Link addresses of captured variables to closure.
-		for _, v := range n.Func.Closure.Func.Cvars.Slice() {
-			if v.Op == OXXX { // unnamed out argument; see dcl.go:/^funcargs
-				continue
-			}
-
-			k := k
-			if !v.Name.Byval() {
-				k = k.addr(v, "reference")
-			}
-
-			e.expr(k.note(n, "captured by a closure"), v.Name.Defn)
-		}
-
-	case ORUNES2STR, OBYTES2STR, OSTR2RUNES, OSTR2BYTES, ORUNESTR:
-		e.spill(k, n)
-		e.discard(n.Left)
-
-	case OADDSTR:
-		e.spill(k, n)
-
-		// Arguments of OADDSTR never escape;
-		// runtime.concatstrings makes sure of that.
-		e.discards(n.List)
-	}
-}
-
-// unsafeValue evaluates a uintptr-typed arithmetic expression looking
-// for conversions from an unsafe.Pointer.
-func (e *Escape) unsafeValue(k EscHole, n *Node) {
-	if n.Type.Etype != TUINTPTR {
-		Fatalf("unexpected type %v for %v", n.Type, n)
-	}
-
-	e.stmts(n.Ninit)
-
-	switch n.Op {
-	case OCONV, OCONVNOP:
-		if n.Left.Type.IsUnsafePtr() {
-			e.expr(k, n.Left)
-		} else {
-			e.discard(n.Left)
-		}
-	case ODOTPTR:
-		if isReflectHeaderDataField(n) {
-			e.expr(k.deref(n, "reflect.Header.Data"), n.Left)
-		} else {
-			e.discard(n.Left)
-		}
-	case OPLUS, ONEG, OBITNOT:
-		e.unsafeValue(k, n.Left)
-	case OADD, OSUB, OOR, OXOR, OMUL, ODIV, OMOD, OAND, OANDNOT:
-		e.unsafeValue(k, n.Left)
-		e.unsafeValue(k, n.Right)
-	case OLSH, ORSH:
-		e.unsafeValue(k, n.Left)
-		// RHS need not be uintptr-typed (#32959) and can't meaningfully
-		// flow pointers anyway.
-		e.discard(n.Right)
-	default:
-		e.exprSkipInit(e.discardHole(), n)
-	}
-}
-
-// discard evaluates an expression n for side-effects, but discards
-// its value.
-func (e *Escape) discard(n *Node) {
-	e.expr(e.discardHole(), n)
-}
-
-func (e *Escape) discards(l Nodes) {
-	for _, n := range l.Slice() {
-		e.discard(n)
-	}
-}
-
-// addr evaluates an addressable expression n and returns an EscHole
-// that represents storing into the represented location.
-func (e *Escape) addr(n *Node) EscHole {
-	if n == nil || n.isBlank() {
-		// Can happen at least in OSELRECV.
-		// TODO(mdempsky): Anywhere else?
-		return e.discardHole()
-	}
-
-	k := e.heapHole()
-
-	switch n.Op {
-	default:
-		Fatalf("unexpected addr: %v", n)
-	case ONAME:
-		if n.Class() == PEXTERN {
-			break
-		}
-		k = e.oldLoc(n).asHole()
-	case ODOT:
-		k = e.addr(n.Left)
-	case OINDEX:
-		e.discard(n.Right)
-		if n.Left.Type.IsArray() {
-			k = e.addr(n.Left)
-		} else {
-			e.discard(n.Left)
-		}
-	case ODEREF, ODOTPTR:
-		e.discard(n)
-	case OINDEXMAP:
-		e.discard(n.Left)
-		e.assignHeap(n.Right, "key of map put", n)
-	}
-
-	if !n.Type.HasPointers() {
-		k = e.discardHole()
-	}
-
-	return k
-}
-
-func (e *Escape) addrs(l Nodes) []EscHole {
-	var ks []EscHole
-	for _, n := range l.Slice() {
-		ks = append(ks, e.addr(n))
-	}
-	return ks
-}
-
-// assign evaluates the assignment dst = src.
-func (e *Escape) assign(dst, src *Node, why string, where *Node) {
-	// Filter out some no-op assignments for escape analysis.
-	ignore := dst != nil && src != nil && isSelfAssign(dst, src)
-	if ignore && Debug.m != 0 {
-		Warnl(where.Pos, "%v ignoring self-assignment in %S", funcSym(e.curfn), where)
-	}
-
-	k := e.addr(dst)
-	if dst != nil && dst.Op == ODOTPTR && isReflectHeaderDataField(dst) {
-		e.unsafeValue(e.heapHole().note(where, why), src)
-	} else {
-		if ignore {
-			k = e.discardHole()
-		}
-		e.expr(k.note(where, why), src)
-	}
-}
-
-func (e *Escape) assignHeap(src *Node, why string, where *Node) {
-	e.expr(e.heapHole().note(where, why), src)
-}
-
-// call evaluates a call expressions, including builtin calls. ks
-// should contain the holes representing where the function callee's
-// results flows; where is the OGO/ODEFER context of the call, if any.
-func (e *Escape) call(ks []EscHole, call, where *Node) {
-	topLevelDefer := where != nil && where.Op == ODEFER && e.loopDepth == 1
-	if topLevelDefer {
-		// force stack allocation of defer record, unless
-		// open-coded defers are used (see ssa.go)
-		where.Esc = EscNever
-	}
-
-	argument := func(k EscHole, arg *Node) {
-		if topLevelDefer {
-			// Top level defers arguments don't escape to
-			// heap, but they do need to last until end of
-			// function.
-			k = e.later(k)
-		} else if where != nil {
-			k = e.heapHole()
-		}
-
-		e.expr(k.note(call, "call parameter"), arg)
-	}
-
-	switch call.Op {
-	default:
-		Fatalf("unexpected call op: %v", call.Op)
-
-	case OCALLFUNC, OCALLMETH, OCALLINTER:
-		fixVariadicCall(call)
-
-		// Pick out the function callee, if statically known.
-		var fn *Node
-		switch call.Op {
-		case OCALLFUNC:
-			switch v := staticValue(call.Left); {
-			case v.Op == ONAME && v.Class() == PFUNC:
-				fn = v
-			case v.Op == OCLOSURE:
-				fn = v.Func.Closure.Func.Nname
-			}
-		case OCALLMETH:
-			fn = asNode(call.Left.Type.FuncType().Nname)
-		}
-
-		fntype := call.Left.Type
-		if fn != nil {
-			fntype = fn.Type
-		}
-
-		if ks != nil && fn != nil && e.inMutualBatch(fn) {
-			for i, result := range fn.Type.Results().FieldSlice() {
-				e.expr(ks[i], asNode(result.Nname))
-			}
-		}
-
-		if r := fntype.Recv(); r != nil {
-			argument(e.tagHole(ks, fn, r), call.Left.Left)
-		} else {
-			// Evaluate callee function expression.
-			argument(e.discardHole(), call.Left)
-		}
-
-		args := call.List.Slice()
-		for i, param := range fntype.Params().FieldSlice() {
-			argument(e.tagHole(ks, fn, param), args[i])
-		}
-
-	case OAPPEND:
-		args := call.List.Slice()
-
-		// Appendee slice may flow directly to the result, if
-		// it has enough capacity. Alternatively, a new heap
-		// slice might be allocated, and all slice elements
-		// might flow to heap.
-		appendeeK := ks[0]
-		if args[0].Type.Elem().HasPointers() {
-			appendeeK = e.teeHole(appendeeK, e.heapHole().deref(call, "appendee slice"))
-		}
-		argument(appendeeK, args[0])
-
-		if call.IsDDD() {
-			appendedK := e.discardHole()
-			if args[1].Type.IsSlice() && args[1].Type.Elem().HasPointers() {
-				appendedK = e.heapHole().deref(call, "appended slice...")
-			}
-			argument(appendedK, args[1])
-		} else {
-			for _, arg := range args[1:] {
-				argument(e.heapHole(), arg)
-			}
-		}
-
-	case OCOPY:
-		argument(e.discardHole(), call.Left)
-
-		copiedK := e.discardHole()
-		if call.Right.Type.IsSlice() && call.Right.Type.Elem().HasPointers() {
-			copiedK = e.heapHole().deref(call, "copied slice")
-		}
-		argument(copiedK, call.Right)
-
-	case OPANIC:
-		argument(e.heapHole(), call.Left)
-
-	case OCOMPLEX:
-		argument(e.discardHole(), call.Left)
-		argument(e.discardHole(), call.Right)
-	case ODELETE, OPRINT, OPRINTN, ORECOVER:
-		for _, arg := range call.List.Slice() {
-			argument(e.discardHole(), arg)
-		}
-	case OLEN, OCAP, OREAL, OIMAG, OCLOSE:
-		argument(e.discardHole(), call.Left)
-	}
-}
-
-// tagHole returns a hole for evaluating an argument passed to param.
-// ks should contain the holes representing where the function
-// callee's results flows. fn is the statically-known callee function,
-// if any.
-func (e *Escape) tagHole(ks []EscHole, fn *Node, param *types.Field) EscHole {
-	// If this is a dynamic call, we can't rely on param.Note.
-	if fn == nil {
-		return e.heapHole()
-	}
-
-	if e.inMutualBatch(fn) {
-		return e.addr(asNode(param.Nname))
-	}
-
-	// Call to previously tagged function.
-
-	if param.Note == uintptrEscapesTag {
-		k := e.heapHole()
-		k.uintptrEscapesHack = true
-		return k
-	}
-
-	var tagKs []EscHole
-
-	esc := ParseLeaks(param.Note)
-	if x := esc.Heap(); x >= 0 {
-		tagKs = append(tagKs, e.heapHole().shift(x))
-	}
-
-	if ks != nil {
-		for i := 0; i < numEscResults; i++ {
-			if x := esc.Result(i); x >= 0 {
-				tagKs = append(tagKs, ks[i].shift(x))
-			}
-		}
-	}
-
-	return e.teeHole(tagKs...)
-}
-
-// inMutualBatch reports whether function fn is in the batch of
-// mutually recursive functions being analyzed. When this is true,
-// fn has not yet been analyzed, so its parameters and results
-// should be incorporated directly into the flow graph instead of
-// relying on its escape analysis tagging.
-func (e *Escape) inMutualBatch(fn *Node) bool {
-	if fn.Name.Defn != nil && fn.Name.Defn.Esc < EscFuncTagged {
-		if fn.Name.Defn.Esc == EscFuncUnknown {
-			Fatalf("graph inconsistency")
-		}
-		return true
-	}
-	return false
-}
-
-// An EscHole represents a context for evaluation a Go
-// expression. E.g., when evaluating p in "x = **p", we'd have a hole
-// with dst==x and derefs==2.
-type EscHole struct {
-	dst    *EscLocation
-	derefs int // >= -1
-	notes  *EscNote
-
-	// uintptrEscapesHack indicates this context is evaluating an
-	// argument for a //go:uintptrescapes function.
-	uintptrEscapesHack bool
-}
-
-type EscNote struct {
-	next  *EscNote
-	where *Node
-	why   string
-}
-
-func (k EscHole) note(where *Node, why string) EscHole {
-	if where == nil || why == "" {
-		Fatalf("note: missing where/why")
-	}
-	if Debug.m >= 2 || logopt.Enabled() {
-		k.notes = &EscNote{
-			next:  k.notes,
-			where: where,
-			why:   why,
-		}
-	}
-	return k
-}
-
-func (k EscHole) shift(delta int) EscHole {
-	k.derefs += delta
-	if k.derefs < -1 {
-		Fatalf("derefs underflow: %v", k.derefs)
-	}
-	return k
-}
-
-func (k EscHole) deref(where *Node, why string) EscHole { return k.shift(1).note(where, why) }
-func (k EscHole) addr(where *Node, why string) EscHole  { return k.shift(-1).note(where, why) }
-
-func (k EscHole) dotType(t *types.Type, where *Node, why string) EscHole {
-	if !t.IsInterface() && !isdirectiface(t) {
-		k = k.shift(1)
-	}
-	return k.note(where, why)
-}
-
-// teeHole returns a new hole that flows into each hole of ks,
-// similar to the Unix tee(1) command.
-func (e *Escape) teeHole(ks ...EscHole) EscHole {
-	if len(ks) == 0 {
-		return e.discardHole()
-	}
-	if len(ks) == 1 {
-		return ks[0]
-	}
-	// TODO(mdempsky): Optimize if there's only one non-discard hole?
-
-	// Given holes "l1 = _", "l2 = **_", "l3 = *_", ..., create a
-	// new temporary location ltmp, wire it into place, and return
-	// a hole for "ltmp = _".
-	loc := e.newLoc(nil, true)
-	for _, k := range ks {
-		// N.B., "p = &q" and "p = &tmp; tmp = q" are not
-		// semantically equivalent. To combine holes like "l1
-		// = _" and "l2 = &_", we'd need to wire them as "l1 =
-		// *ltmp" and "l2 = ltmp" and return "ltmp = &_"
-		// instead.
-		if k.derefs < 0 {
-			Fatalf("teeHole: negative derefs")
-		}
-
-		e.flow(k, loc)
-	}
-	return loc.asHole()
-}
-
-func (e *Escape) dcl(n *Node) EscHole {
-	loc := e.oldLoc(n)
-	loc.loopDepth = e.loopDepth
-	return loc.asHole()
-}
-
-// spill allocates a new location associated with expression n, flows
-// its address to k, and returns a hole that flows values to it. It's
-// intended for use with most expressions that allocate storage.
-func (e *Escape) spill(k EscHole, n *Node) EscHole {
-	loc := e.newLoc(n, true)
-	e.flow(k.addr(n, "spill"), loc)
-	return loc.asHole()
-}
-
-// later returns a new hole that flows into k, but some time later.
-// Its main effect is to prevent immediate reuse of temporary
-// variables introduced during Order.
-func (e *Escape) later(k EscHole) EscHole {
-	loc := e.newLoc(nil, false)
-	e.flow(k, loc)
-	return loc.asHole()
-}
-
-// canonicalNode returns the canonical *Node that n logically
-// represents.
-func canonicalNode(n *Node) *Node {
-	if n != nil && n.Op == ONAME && n.Name.IsClosureVar() {
-		n = n.Name.Defn
-		if n.Name.IsClosureVar() {
-			Fatalf("still closure var")
-		}
-	}
-
-	return n
-}
-
-func (e *Escape) newLoc(n *Node, transient bool) *EscLocation {
-	if e.curfn == nil {
-		Fatalf("e.curfn isn't set")
-	}
-	if n != nil && n.Type != nil && n.Type.NotInHeap() {
-		yyerrorl(n.Pos, "%v is incomplete (or unallocatable); stack allocation disallowed", n.Type)
-	}
-
-	n = canonicalNode(n)
-	loc := &EscLocation{
-		n:         n,
-		curfn:     e.curfn,
-		loopDepth: e.loopDepth,
-		transient: transient,
-	}
-	e.allLocs = append(e.allLocs, loc)
-	if n != nil {
-		if n.Op == ONAME && n.Name.Curfn != e.curfn {
-			Fatalf("curfn mismatch: %v != %v", n.Name.Curfn, e.curfn)
-		}
-
-		if n.HasOpt() {
-			Fatalf("%v already has a location", n)
-		}
-		n.SetOpt(loc)
-
-		if why := heapAllocReason(n); why != "" {
-			e.flow(e.heapHole().addr(n, why), loc)
-		}
-	}
-	return loc
-}
-
-func (e *Escape) oldLoc(n *Node) *EscLocation {
-	n = canonicalNode(n)
-	return n.Opt().(*EscLocation)
-}
-
-func (l *EscLocation) asHole() EscHole {
-	return EscHole{dst: l}
-}
-
-func (e *Escape) flow(k EscHole, src *EscLocation) {
-	dst := k.dst
-	if dst == &e.blankLoc {
-		return
-	}
-	if dst == src && k.derefs >= 0 { // dst = dst, dst = *dst, ...
-		return
-	}
-	if dst.escapes && k.derefs < 0 { // dst = &src
-		if Debug.m >= 2 || logopt.Enabled() {
-			pos := linestr(src.n.Pos)
-			if Debug.m >= 2 {
-				fmt.Printf("%s: %v escapes to heap:\n", pos, src.n)
-			}
-			explanation := e.explainFlow(pos, dst, src, k.derefs, k.notes, []*logopt.LoggedOpt{})
-			if logopt.Enabled() {
-				logopt.LogOpt(src.n.Pos, "escapes", "escape", e.curfn.funcname(), fmt.Sprintf("%v escapes to heap", src.n), explanation)
-			}
-
-		}
-		src.escapes = true
-		return
-	}
-
-	// TODO(mdempsky): Deduplicate edges?
-	dst.edges = append(dst.edges, EscEdge{src: src, derefs: k.derefs, notes: k.notes})
-}
-
-func (e *Escape) heapHole() EscHole    { return e.heapLoc.asHole() }
-func (e *Escape) discardHole() EscHole { return e.blankLoc.asHole() }
-
-// walkAll computes the minimal dereferences between all pairs of
-// locations.
-func (e *Escape) walkAll() {
-	// We use a work queue to keep track of locations that we need
-	// to visit, and repeatedly walk until we reach a fixed point.
-	//
-	// We walk once from each location (including the heap), and
-	// then re-enqueue each location on its transition from
-	// transient->!transient and !escapes->escapes, which can each
-	// happen at most once. So we take Θ(len(e.allLocs)) walks.
-
-	// LIFO queue, has enough room for e.allLocs and e.heapLoc.
-	todo := make([]*EscLocation, 0, len(e.allLocs)+1)
-	enqueue := func(loc *EscLocation) {
-		if !loc.queued {
-			todo = append(todo, loc)
-			loc.queued = true
-		}
-	}
-
-	for _, loc := range e.allLocs {
-		enqueue(loc)
-	}
-	enqueue(&e.heapLoc)
-
-	var walkgen uint32
-	for len(todo) > 0 {
-		root := todo[len(todo)-1]
-		todo = todo[:len(todo)-1]
-		root.queued = false
-
-		walkgen++
-		e.walkOne(root, walkgen, enqueue)
-	}
-}
-
-// walkOne computes the minimal number of dereferences from root to
-// all other locations.
-func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLocation)) {
-	// The data flow graph has negative edges (from addressing
-	// operations), so we use the Bellman-Ford algorithm. However,
-	// we don't have to worry about infinite negative cycles since
-	// we bound intermediate dereference counts to 0.
-
-	root.walkgen = walkgen
-	root.derefs = 0
-	root.dst = nil
-
-	todo := []*EscLocation{root} // LIFO queue
-	for len(todo) > 0 {
-		l := todo[len(todo)-1]
-		todo = todo[:len(todo)-1]
-
-		base := l.derefs
-
-		// If l.derefs < 0, then l's address flows to root.
-		addressOf := base < 0
-		if addressOf {
-			// For a flow path like "root = &l; l = x",
-			// l's address flows to root, but x's does
-			// not. We recognize this by lower bounding
-			// base at 0.
-			base = 0
-
-			// If l's address flows to a non-transient
-			// location, then l can't be transiently
-			// allocated.
-			if !root.transient && l.transient {
-				l.transient = false
-				enqueue(l)
-			}
-		}
-
-		if e.outlives(root, l) {
-			// l's value flows to root. If l is a function
-			// parameter and root is the heap or a
-			// corresponding result parameter, then record
-			// that value flow for tagging the function
-			// later.
-			if l.isName(PPARAM) {
-				if (logopt.Enabled() || Debug.m >= 2) && !l.escapes {
-					if Debug.m >= 2 {
-						fmt.Printf("%s: parameter %v leaks to %s with derefs=%d:\n", linestr(l.n.Pos), l.n, e.explainLoc(root), base)
-					}
-					explanation := e.explainPath(root, l)
-					if logopt.Enabled() {
-						logopt.LogOpt(l.n.Pos, "leak", "escape", e.curfn.funcname(),
-							fmt.Sprintf("parameter %v leaks to %s with derefs=%d", l.n, e.explainLoc(root), base), explanation)
-					}
-				}
-				l.leakTo(root, base)
-			}
-
-			// If l's address flows somewhere that
-			// outlives it, then l needs to be heap
-			// allocated.
-			if addressOf && !l.escapes {
-				if logopt.Enabled() || Debug.m >= 2 {
-					if Debug.m >= 2 {
-						fmt.Printf("%s: %v escapes to heap:\n", linestr(l.n.Pos), l.n)
-					}
-					explanation := e.explainPath(root, l)
-					if logopt.Enabled() {
-						logopt.LogOpt(l.n.Pos, "escape", "escape", e.curfn.funcname(), fmt.Sprintf("%v escapes to heap", l.n), explanation)
-					}
-				}
-				l.escapes = true
-				enqueue(l)
-				continue
-			}
-		}
-
-		for i, edge := range l.edges {
-			if edge.src.escapes {
-				continue
-			}
-			derefs := base + edge.derefs
-			if edge.src.walkgen != walkgen || edge.src.derefs > derefs {
-				edge.src.walkgen = walkgen
-				edge.src.derefs = derefs
-				edge.src.dst = l
-				edge.src.dstEdgeIdx = i
-				todo = append(todo, edge.src)
-			}
-		}
-	}
-}
-
-// explainPath prints an explanation of how src flows to the walk root.
-func (e *Escape) explainPath(root, src *EscLocation) []*logopt.LoggedOpt {
-	visited := make(map[*EscLocation]bool)
-	pos := linestr(src.n.Pos)
-	var explanation []*logopt.LoggedOpt
-	for {
-		// Prevent infinite loop.
-		if visited[src] {
-			if Debug.m >= 2 {
-				fmt.Printf("%s:   warning: truncated explanation due to assignment cycle; see golang.org/issue/35518\n", pos)
-			}
-			break
-		}
-		visited[src] = true
-		dst := src.dst
-		edge := &dst.edges[src.dstEdgeIdx]
-		if edge.src != src {
-			Fatalf("path inconsistency: %v != %v", edge.src, src)
-		}
-
-		explanation = e.explainFlow(pos, dst, src, edge.derefs, edge.notes, explanation)
-
-		if dst == root {
-			break
-		}
-		src = dst
-	}
-
-	return explanation
-}
-
-func (e *Escape) explainFlow(pos string, dst, srcloc *EscLocation, derefs int, notes *EscNote, explanation []*logopt.LoggedOpt) []*logopt.LoggedOpt {
-	ops := "&"
-	if derefs >= 0 {
-		ops = strings.Repeat("*", derefs)
-	}
-	print := Debug.m >= 2
-
-	flow := fmt.Sprintf("   flow: %s = %s%v:", e.explainLoc(dst), ops, e.explainLoc(srcloc))
-	if print {
-		fmt.Printf("%s:%s\n", pos, flow)
-	}
-	if logopt.Enabled() {
-		var epos src.XPos
-		if notes != nil {
-			epos = notes.where.Pos
-		} else if srcloc != nil && srcloc.n != nil {
-			epos = srcloc.n.Pos
-		}
-		explanation = append(explanation, logopt.NewLoggedOpt(epos, "escflow", "escape", e.curfn.funcname(), flow))
-	}
-
-	for note := notes; note != nil; note = note.next {
-		if print {
-			fmt.Printf("%s:     from %v (%v) at %s\n", pos, note.where, note.why, linestr(note.where.Pos))
-		}
-		if logopt.Enabled() {
-			explanation = append(explanation, logopt.NewLoggedOpt(note.where.Pos, "escflow", "escape", e.curfn.funcname(),
-				fmt.Sprintf("     from %v (%v)", note.where, note.why)))
-		}
-	}
-	return explanation
-}
-
-func (e *Escape) explainLoc(l *EscLocation) string {
-	if l == &e.heapLoc {
-		return "{heap}"
-	}
-	if l.n == nil {
-		// TODO(mdempsky): Omit entirely.
-		return "{temp}"
-	}
-	if l.n.Op == ONAME {
-		return fmt.Sprintf("%v", l.n)
-	}
-	return fmt.Sprintf("{storage for %v}", l.n)
-}
-
-// outlives reports whether values stored in l may survive beyond
-// other's lifetime if stack allocated.
-func (e *Escape) outlives(l, other *EscLocation) bool {
-	// The heap outlives everything.
-	if l.escapes {
-		return true
-	}
-
-	// We don't know what callers do with returned values, so
-	// pessimistically we need to assume they flow to the heap and
-	// outlive everything too.
-	if l.isName(PPARAMOUT) {
-		// Exception: Directly called closures can return
-		// locations allocated outside of them without forcing
-		// them to the heap. For example:
-		//
-		//    var u int  // okay to stack allocate
-		//    *(func() *int { return &u }()) = 42
-		if containsClosure(other.curfn, l.curfn) && l.curfn.Func.Closure.Func.Top&ctxCallee != 0 {
-			return false
-		}
-
-		return true
-	}
-
-	// If l and other are within the same function, then l
-	// outlives other if it was declared outside other's loop
-	// scope. For example:
-	//
-	//    var l *int
-	//    for {
-	//        l = new(int)
-	//    }
-	if l.curfn == other.curfn && l.loopDepth < other.loopDepth {
-		return true
-	}
-
-	// If other is declared within a child closure of where l is
-	// declared, then l outlives it. For example:
-	//
-	//    var l *int
-	//    func() {
-	//        l = new(int)
-	//    }
-	if containsClosure(l.curfn, other.curfn) {
-		return true
-	}
-
-	return false
-}
-
-// containsClosure reports whether c is a closure contained within f.
-func containsClosure(f, c *Node) bool {
-	if f.Op != ODCLFUNC || c.Op != ODCLFUNC {
-		Fatalf("bad containsClosure: %v, %v", f, c)
-	}
-
-	// Common case.
-	if f == c {
-		return false
-	}
-
-	// Closures within function Foo are named like "Foo.funcN..."
-	// TODO(mdempsky): Better way to recognize this.
-	fn := f.Func.Nname.Sym.Name
-	cn := c.Func.Nname.Sym.Name
-	return len(cn) > len(fn) && cn[:len(fn)] == fn && cn[len(fn)] == '.'
-}
-
-// leak records that parameter l leaks to sink.
-func (l *EscLocation) leakTo(sink *EscLocation, derefs int) {
-	// If sink is a result parameter that doesn't escape (#44614)
-	// and we can fit return bits into the escape analysis tag,
-	// then record as a result leak.
-	if !sink.escapes && sink.isName(PPARAMOUT) && sink.curfn == l.curfn {
-		// TODO(mdempsky): Eliminate dependency on Vargen here.
-		ri := int(sink.n.Name.Vargen) - 1
-		if ri < numEscResults {
-			// Leak to result parameter.
-			l.paramEsc.AddResult(ri, derefs)
-			return
-		}
-	}
-
-	// Otherwise, record as heap leak.
-	l.paramEsc.AddHeap(derefs)
-}
-
-func (e *Escape) finish(fns []*Node) {
-	// Record parameter tags for package export data.
-	for _, fn := range fns {
-		fn.Esc = EscFuncTagged
-
-		narg := 0
-		for _, fs := range &types.RecvsParams {
-			for _, f := range fs(fn.Type).Fields().Slice() {
-				narg++
-				f.Note = e.paramTag(fn, narg, f)
-			}
-		}
-	}
-
-	for _, loc := range e.allLocs {
-		n := loc.n
-		if n == nil {
-			continue
-		}
-		n.SetOpt(nil)
-
-		// Update n.Esc based on escape analysis results.
-
-		if loc.escapes {
-			if n.Op != ONAME {
-				if Debug.m != 0 {
-					Warnl(n.Pos, "%S escapes to heap", n)
-				}
-				if logopt.Enabled() {
-					logopt.LogOpt(n.Pos, "escape", "escape", e.curfn.funcname())
-				}
-			}
-			n.Esc = EscHeap
-			addrescapes(n)
-		} else {
-			if Debug.m != 0 && n.Op != ONAME {
-				Warnl(n.Pos, "%S does not escape", n)
-			}
-			n.Esc = EscNone
-			if loc.transient {
-				n.SetTransient(true)
-			}
-		}
-	}
-}
-
-func (l *EscLocation) isName(c Class) bool {
-	return l.n != nil && l.n.Op == ONAME && l.n.Class() == c
-}
-
-const numEscResults = 7
-
-// An EscLeaks represents a set of assignment flows from a parameter
-// to the heap or to any of its function's (first numEscResults)
-// result parameters.
-type EscLeaks [1 + numEscResults]uint8
-
-// Empty reports whether l is an empty set (i.e., no assignment flows).
-func (l EscLeaks) Empty() bool { return l == EscLeaks{} }
-
-// Heap returns the minimum deref count of any assignment flow from l
-// to the heap. If no such flows exist, Heap returns -1.
-func (l EscLeaks) Heap() int { return l.get(0) }
-
-// Result returns the minimum deref count of any assignment flow from
-// l to its function's i'th result parameter. If no such flows exist,
-// Result returns -1.
-func (l EscLeaks) Result(i int) int { return l.get(1 + i) }
-
-// AddHeap adds an assignment flow from l to the heap.
-func (l *EscLeaks) AddHeap(derefs int) { l.add(0, derefs) }
-
-// AddResult adds an assignment flow from l to its function's i'th
-// result parameter.
-func (l *EscLeaks) AddResult(i, derefs int) { l.add(1+i, derefs) }
-
-func (l *EscLeaks) setResult(i, derefs int) { l.set(1+i, derefs) }
-
-func (l EscLeaks) get(i int) int { return int(l[i]) - 1 }
-
-func (l *EscLeaks) add(i, derefs int) {
-	if old := l.get(i); old < 0 || derefs < old {
-		l.set(i, derefs)
-	}
-}
-
-func (l *EscLeaks) set(i, derefs int) {
-	v := derefs + 1
-	if v < 0 {
-		Fatalf("invalid derefs count: %v", derefs)
-	}
-	if v > math.MaxUint8 {
-		v = math.MaxUint8
-	}
-
-	l[i] = uint8(v)
-}
-
-// Optimize removes result flow paths that are equal in length or
-// longer than the shortest heap flow path.
-func (l *EscLeaks) Optimize() {
-	// If we have a path to the heap, then there's no use in
-	// keeping equal or longer paths elsewhere.
-	if x := l.Heap(); x >= 0 {
-		for i := 0; i < numEscResults; i++ {
-			if l.Result(i) >= x {
-				l.setResult(i, -1)
-			}
-		}
-	}
-}
-
-var leakTagCache = map[EscLeaks]string{}
-
-// Encode converts l into a binary string for export data.
-func (l EscLeaks) Encode() string {
-	if l.Heap() == 0 {
-		// Space optimization: empty string encodes more
-		// efficiently in export data.
-		return ""
-	}
-	if s, ok := leakTagCache[l]; ok {
-		return s
-	}
-
-	n := len(l)
-	for n > 0 && l[n-1] == 0 {
-		n--
-	}
-	s := "esc:" + string(l[:n])
-	leakTagCache[l] = s
-	return s
-}
-
-// ParseLeaks parses a binary string representing an EscLeaks.
-func ParseLeaks(s string) EscLeaks {
-	var l EscLeaks
-	if !strings.HasPrefix(s, "esc:") {
-		l.AddHeap(0)
-		return l
-	}
-	copy(l[:], s[4:])
-	return l
-}
diff --git a/src/cmd/compile/internal/gc/export.go b/src/cmd/compile/internal/gc/export.go
index c6917e0..2137f1d 100644
--- a/src/cmd/compile/internal/gc/export.go
+++ b/src/cmd/compile/internal/gc/export.go
@@ -5,225 +5,73 @@
 package gc
 
 import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/inline"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
 	"cmd/compile/internal/types"
 	"cmd/internal/bio"
-	"cmd/internal/src"
 	"fmt"
-)
-
-var (
-	Debug_export int // if set, print debugging information about export data
+	"go/constant"
 )
 
 func exportf(bout *bio.Writer, format string, args ...interface{}) {
 	fmt.Fprintf(bout, format, args...)
-	if Debug_export != 0 {
+	if base.Debug.Export != 0 {
 		fmt.Printf(format, args...)
 	}
 }
 
-var asmlist []*Node
-
-// exportsym marks n for export (or reexport).
-func exportsym(n *Node) {
-	if n.Sym.OnExportList() {
-		return
-	}
-	n.Sym.SetOnExportList(true)
-
-	if Debug.E != 0 {
-		fmt.Printf("export symbol %v\n", n.Sym)
-	}
-
-	exportlist = append(exportlist, n)
-}
-
-func initname(s string) bool {
-	return s == "init"
-}
-
-func autoexport(n *Node, ctxt Class) {
-	if n.Sym.Pkg != localpkg {
-		return
-	}
-	if (ctxt != PEXTERN && ctxt != PFUNC) || dclcontext != PEXTERN {
-		return
-	}
-	if n.Type != nil && n.Type.IsKind(TFUNC) && n.IsMethod() {
-		return
-	}
-
-	if types.IsExported(n.Sym.Name) || initname(n.Sym.Name) {
-		exportsym(n)
-	}
-	if asmhdr != "" && !n.Sym.Asm() {
-		n.Sym.SetAsm(true)
-		asmlist = append(asmlist, n)
-	}
-}
-
 func dumpexport(bout *bio.Writer) {
+	p := &exporter{marked: make(map[*types.Type]bool)}
+	for _, n := range typecheck.Target.Exports {
+		// Must catch it here rather than Export(), because the type can be
+		// not fully set (still TFORW) when Export() is called.
+		if n.Type() != nil && n.Type().HasTParam() {
+			base.Fatalf("Cannot (yet) export a generic type: %v", n)
+		}
+		p.markObject(n)
+	}
+
 	// The linker also looks for the $$ marker - use char after $$ to distinguish format.
 	exportf(bout, "\n$$B\n") // indicate binary export format
 	off := bout.Offset()
-	iexport(bout.Writer)
+	typecheck.WriteExports(bout.Writer)
 	size := bout.Offset() - off
 	exportf(bout, "\n$$\n")
 
-	if Debug_export != 0 {
-		fmt.Printf("BenchmarkExportSize:%s 1 %d bytes\n", myimportpath, size)
-	}
-}
-
-func importsym(ipkg *types.Pkg, s *types.Sym, op Op) *Node {
-	n := asNode(s.PkgDef())
-	if n == nil {
-		// iimport should have created a stub ONONAME
-		// declaration for all imported symbols. The exception
-		// is declarations for Runtimepkg, which are populated
-		// by loadsys instead.
-		if s.Pkg != Runtimepkg {
-			Fatalf("missing ONONAME for %v\n", s)
-		}
-
-		n = dclname(s)
-		s.SetPkgDef(asTypesNode(n))
-		s.Importdef = ipkg
-	}
-	if n.Op != ONONAME && n.Op != op {
-		redeclare(lineno, s, fmt.Sprintf("during import %q", ipkg.Path))
-	}
-	return n
-}
-
-// importtype returns the named type declared by symbol s.
-// If no such type has been declared yet, a forward declaration is returned.
-// ipkg is the package being imported
-func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
-	n := importsym(ipkg, s, OTYPE)
-	if n.Op != OTYPE {
-		t := types.New(TFORW)
-		t.Sym = s
-		t.Nod = asTypesNode(n)
-
-		n.Op = OTYPE
-		n.Pos = pos
-		n.Type = t
-		n.SetClass(PEXTERN)
-	}
-
-	t := n.Type
-	if t == nil {
-		Fatalf("importtype %v", s)
-	}
-	return t
-}
-
-// importobj declares symbol s as an imported object representable by op.
-// ipkg is the package being imported
-func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t *types.Type) *Node {
-	n := importsym(ipkg, s, op)
-	if n.Op != ONONAME {
-		if n.Op == op && (n.Class() != ctxt || !types.Identical(n.Type, t)) {
-			redeclare(lineno, s, fmt.Sprintf("during import %q", ipkg.Path))
-		}
-		return nil
-	}
-
-	n.Op = op
-	n.Pos = pos
-	n.SetClass(ctxt)
-	if ctxt == PFUNC {
-		n.Sym.SetFunc(true)
-	}
-	n.Type = t
-	return n
-}
-
-// importconst declares symbol s as an imported constant with type t and value val.
-// ipkg is the package being imported
-func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val Val) {
-	n := importobj(ipkg, pos, s, OLITERAL, PEXTERN, t)
-	if n == nil { // TODO: Check that value matches.
-		return
-	}
-
-	n.SetVal(val)
-
-	if Debug.E != 0 {
-		fmt.Printf("import const %v %L = %v\n", s, t, val)
-	}
-}
-
-// importfunc declares symbol s as an imported function with type t.
-// ipkg is the package being imported
-func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
-	n := importobj(ipkg, pos, s, ONAME, PFUNC, t)
-	if n == nil {
-		return
-	}
-
-	n.Func = new(Func)
-	t.SetNname(asTypesNode(n))
-
-	if Debug.E != 0 {
-		fmt.Printf("import func %v%S\n", s, t)
-	}
-}
-
-// importvar declares symbol s as an imported variable with type t.
-// ipkg is the package being imported
-func importvar(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
-	n := importobj(ipkg, pos, s, ONAME, PEXTERN, t)
-	if n == nil {
-		return
-	}
-
-	if Debug.E != 0 {
-		fmt.Printf("import var %v %L\n", s, t)
-	}
-}
-
-// importalias declares symbol s as an imported type alias with type t.
-// ipkg is the package being imported
-func importalias(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
-	n := importobj(ipkg, pos, s, OTYPE, PEXTERN, t)
-	if n == nil {
-		return
-	}
-
-	if Debug.E != 0 {
-		fmt.Printf("import type %v = %L\n", s, t)
+	if base.Debug.Export != 0 {
+		fmt.Printf("BenchmarkExportSize:%s 1 %d bytes\n", base.Ctxt.Pkgpath, size)
 	}
 }
 
 func dumpasmhdr() {
-	b, err := bio.Create(asmhdr)
+	b, err := bio.Create(base.Flag.AsmHdr)
 	if err != nil {
-		Fatalf("%v", err)
+		base.Fatalf("%v", err)
 	}
-	fmt.Fprintf(b, "// generated by compile -asmhdr from package %s\n\n", localpkg.Name)
-	for _, n := range asmlist {
-		if n.Sym.IsBlank() {
+	fmt.Fprintf(b, "// generated by compile -asmhdr from package %s\n\n", types.LocalPkg.Name)
+	for _, n := range typecheck.Target.Asms {
+		if n.Sym().IsBlank() {
 			continue
 		}
-		switch n.Op {
-		case OLITERAL:
-			t := n.Val().Ctype()
-			if t == CTFLT || t == CTCPLX {
+		switch n.Op() {
+		case ir.OLITERAL:
+			t := n.Val().Kind()
+			if t == constant.Float || t == constant.Complex {
 				break
 			}
-			fmt.Fprintf(b, "#define const_%s %#v\n", n.Sym.Name, n.Val())
+			fmt.Fprintf(b, "#define const_%s %#v\n", n.Sym().Name, n.Val())
 
-		case OTYPE:
-			t := n.Type
+		case ir.OTYPE:
+			t := n.Type()
 			if !t.IsStruct() || t.StructType().Map != nil || t.IsFuncArgStruct() {
 				break
 			}
-			fmt.Fprintf(b, "#define %s__size %d\n", n.Sym.Name, int(t.Width))
+			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))
+					fmt.Fprintf(b, "#define %s_%s %d\n", n.Sym().Name, f.Sym.Name, int(f.Offset))
 				}
 			}
 		}
@@ -231,3 +79,83 @@
 
 	b.Close()
 }
+
+type exporter struct {
+	marked map[*types.Type]bool // types already seen by markType
+}
+
+// markObject visits a reachable object.
+func (p *exporter) markObject(n ir.Node) {
+	if n.Op() == ir.ONAME {
+		n := n.(*ir.Name)
+		if n.Class == ir.PFUNC {
+			inline.Inline_Flood(n, typecheck.Export)
+		}
+	}
+
+	p.markType(n.Type())
+}
+
+// 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.Kind() != types.TINTER {
+		for _, m := range t.Methods().Slice() {
+			if types.IsExported(m.Sym.Name) {
+				p.markObject(ir.AsNode(m.Nname))
+			}
+		}
+	}
+
+	// Recursively mark any types that can be produced given a
+	// value of type t: dereferencing a pointer; indexing or
+	// iterating over 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 function parameter types, because
+	// the user already needs some way to construct values of
+	// those types.
+	switch t.Kind() {
+	case types.TPTR, types.TARRAY, types.TSLICE:
+		p.markType(t.Elem())
+
+	case types.TCHAN:
+		if t.ChanDir().CanRecv() {
+			p.markType(t.Elem())
+		}
+
+	case types.TMAP:
+		p.markType(t.Key())
+		p.markType(t.Elem())
+
+	case types.TSTRUCT:
+		for _, f := range t.FieldSlice() {
+			if types.IsExported(f.Sym.Name) || f.Embedded != 0 {
+				p.markType(f.Type)
+			}
+		}
+
+	case types.TFUNC:
+		for _, f := range t.Results().FieldSlice() {
+			p.markType(f.Type)
+		}
+
+	case types.TINTER:
+		for _, f := range t.AllMethods().Slice() {
+			if types.IsExported(f.Sym.Name) {
+				p.markType(f.Type)
+			}
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/gc/fixedbugs_test.go b/src/cmd/compile/internal/gc/fixedbugs_test.go
deleted file mode 100644
index 8ac4436..0000000
--- a/src/cmd/compile/internal/gc/fixedbugs_test.go
+++ /dev/null
@@ -1,92 +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.
-
-package gc
-
-import (
-	"internal/testenv"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"strings"
-	"testing"
-)
-
-type T struct {
-	x [2]int64 // field that will be clobbered. Also makes type not SSAable.
-	p *byte    // has a pointer
-}
-
-//go:noinline
-func makeT() T {
-	return T{}
-}
-
-var g T
-
-var sink interface{}
-
-func TestIssue15854(t *testing.T) {
-	for i := 0; i < 10000; i++ {
-		if g.x[0] != 0 {
-			t.Fatalf("g.x[0] clobbered with %x\n", g.x[0])
-		}
-		// The bug was in the following assignment. The return
-		// value of makeT() is not copied out of the args area of
-		// stack frame in a timely fashion. So when write barriers
-		// are enabled, the marshaling of the args for the write
-		// barrier call clobbers the result of makeT() before it is
-		// read by the write barrier code.
-		g = makeT()
-		sink = make([]byte, 1000) // force write barriers to eventually happen
-	}
-}
-func TestIssue15854b(t *testing.T) {
-	const N = 10000
-	a := make([]T, N)
-	for i := 0; i < N; i++ {
-		a = append(a, makeT())
-		sink = make([]byte, 1000) // force write barriers to eventually happen
-	}
-	for i, v := range a {
-		if v.x[0] != 0 {
-			t.Fatalf("a[%d].x[0] clobbered with %x\n", i, v.x[0])
-		}
-	}
-}
-
-// Test that the generated assembly has line numbers (Issue #16214).
-func TestIssue16214(t *testing.T) {
-	testenv.MustHaveGoBuild(t)
-	dir, err := ioutil.TempDir("", "TestLineNumber")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
-
-	src := filepath.Join(dir, "x.go")
-	err = ioutil.WriteFile(src, []byte(issue16214src), 0644)
-	if err != nil {
-		t.Fatalf("could not write file: %v", err)
-	}
-
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-S", "-o", filepath.Join(dir, "out.o"), src)
-	out, err := cmd.CombinedOutput()
-	if err != nil {
-		t.Fatalf("fail to run go tool compile: %v", err)
-	}
-
-	if strings.Contains(string(out), "unknown line number") {
-		t.Errorf("line number missing in assembly:\n%s", out)
-	}
-}
-
-var issue16214src = `
-package main
-
-func Mod32(x uint32) uint32 {
-	return x % 3 // frontend rewrites it as HMUL with 2863311531, the LITERAL node has unknown Pos
-}
-`
diff --git a/src/cmd/compile/internal/gc/float_test.go b/src/cmd/compile/internal/gc/float_test.go
deleted file mode 100644
index c619d25..0000000
--- a/src/cmd/compile/internal/gc/float_test.go
+++ /dev/null
@@ -1,544 +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.
-
-package gc
-
-import (
-	"math"
-	"testing"
-)
-
-//go:noinline
-func compare1(a, b float64) bool {
-	return a < b
-}
-
-//go:noinline
-func compare2(a, b float32) bool {
-	return a < b
-}
-
-func TestFloatCompare(t *testing.T) {
-	if !compare1(3, 5) {
-		t.Errorf("compare1 returned false")
-	}
-	if !compare2(3, 5) {
-		t.Errorf("compare2 returned false")
-	}
-}
-
-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")
-	}
-}
-
-//go:noinline
-func cvt1(a float64) uint64 {
-	return uint64(a)
-}
-
-//go:noinline
-func cvt2(a float64) uint32 {
-	return uint32(a)
-}
-
-//go:noinline
-func cvt3(a float32) uint64 {
-	return uint64(a)
-}
-
-//go:noinline
-func cvt4(a float32) uint32 {
-	return uint32(a)
-}
-
-//go:noinline
-func cvt5(a float64) int64 {
-	return int64(a)
-}
-
-//go:noinline
-func cvt6(a float64) int32 {
-	return int32(a)
-}
-
-//go:noinline
-func cvt7(a float32) int64 {
-	return int64(a)
-}
-
-//go:noinline
-func cvt8(a float32) int32 {
-	return int32(a)
-}
-
-// make sure to cover int, uint cases (issue #16738)
-//go:noinline
-func cvt9(a float64) int {
-	return int(a)
-}
-
-//go:noinline
-func cvt10(a float64) uint {
-	return uint(a)
-}
-
-//go:noinline
-func cvt11(a float32) int {
-	return int(a)
-}
-
-//go:noinline
-func cvt12(a float32) uint {
-	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)
-	}
-	if got := cvt2(3.5); got != 3 {
-		t.Errorf("cvt2 got %d, wanted 3", got)
-	}
-	if got := cvt3(3.5); got != 3 {
-		t.Errorf("cvt3 got %d, wanted 3", got)
-	}
-	if got := cvt4(3.5); got != 3 {
-		t.Errorf("cvt4 got %d, wanted 3", got)
-	}
-	if got := cvt5(3.5); got != 3 {
-		t.Errorf("cvt5 got %d, wanted 3", got)
-	}
-	if got := cvt6(3.5); got != 3 {
-		t.Errorf("cvt6 got %d, wanted 3", got)
-	}
-	if got := cvt7(3.5); got != 3 {
-		t.Errorf("cvt7 got %d, wanted 3", got)
-	}
-	if got := cvt8(3.5); got != 3 {
-		t.Errorf("cvt8 got %d, wanted 3", got)
-	}
-	if got := cvt9(3.5); got != 3 {
-		t.Errorf("cvt9 got %d, wanted 3", got)
-	}
-	if got := cvt10(3.5); got != 3 {
-		t.Errorf("cvt10 got %d, wanted 3", got)
-	}
-	if got := cvt11(3.5); got != 3 {
-		t.Errorf("cvt11 got %d, wanted 3", got)
-	}
-	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")
-	}
-}
-
-func TestFloat32StoreToLoadConstantFold(t *testing.T) {
-	// Test that math.Float32{,from}bits constant fold correctly.
-	// In particular we need to be careful that signaling NaN (sNaN) values
-	// are not converted to quiet NaN (qNaN) values during compilation.
-	// See issue #27193 for more information.
-
-	// signaling NaNs
-	{
-		const nan = uint32(0x7f800001) // sNaN
-		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
-			t.Errorf("got %#x, want %#x", x, nan)
-		}
-	}
-	{
-		const nan = uint32(0x7fbfffff) // sNaN
-		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
-			t.Errorf("got %#x, want %#x", x, nan)
-		}
-	}
-	{
-		const nan = uint32(0xff800001) // sNaN
-		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
-			t.Errorf("got %#x, want %#x", x, nan)
-		}
-	}
-	{
-		const nan = uint32(0xffbfffff) // sNaN
-		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
-			t.Errorf("got %#x, want %#x", x, nan)
-		}
-	}
-
-	// quiet NaNs
-	{
-		const nan = uint32(0x7fc00000) // qNaN
-		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
-			t.Errorf("got %#x, want %#x", x, nan)
-		}
-	}
-	{
-		const nan = uint32(0x7fffffff) // qNaN
-		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
-			t.Errorf("got %#x, want %#x", x, nan)
-		}
-	}
-	{
-		const nan = uint32(0x8fc00000) // qNaN
-		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
-			t.Errorf("got %#x, want %#x", x, nan)
-		}
-	}
-	{
-		const nan = uint32(0x8fffffff) // qNaN
-		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
-			t.Errorf("got %#x, want %#x", x, nan)
-		}
-	}
-
-	// infinities
-	{
-		const inf = uint32(0x7f800000) // +∞
-		if x := math.Float32bits(math.Float32frombits(inf)); x != inf {
-			t.Errorf("got %#x, want %#x", x, inf)
-		}
-	}
-	{
-		const negInf = uint32(0xff800000) // -∞
-		if x := math.Float32bits(math.Float32frombits(negInf)); x != negInf {
-			t.Errorf("got %#x, want %#x", x, negInf)
-		}
-	}
-
-	// numbers
-	{
-		const zero = uint32(0) // +0.0
-		if x := math.Float32bits(math.Float32frombits(zero)); x != zero {
-			t.Errorf("got %#x, want %#x", x, zero)
-		}
-	}
-	{
-		const negZero = uint32(1 << 31) // -0.0
-		if x := math.Float32bits(math.Float32frombits(negZero)); x != negZero {
-			t.Errorf("got %#x, want %#x", x, negZero)
-		}
-	}
-	{
-		const one = uint32(0x3f800000) // 1.0
-		if x := math.Float32bits(math.Float32frombits(one)); x != one {
-			t.Errorf("got %#x, want %#x", x, one)
-		}
-	}
-	{
-		const negOne = uint32(0xbf800000) // -1.0
-		if x := math.Float32bits(math.Float32frombits(negOne)); x != negOne {
-			t.Errorf("got %#x, want %#x", x, negOne)
-		}
-	}
-	{
-		const frac = uint32(0x3fc00000) // +1.5
-		if x := math.Float32bits(math.Float32frombits(frac)); x != frac {
-			t.Errorf("got %#x, want %#x", x, frac)
-		}
-	}
-	{
-		const negFrac = uint32(0xbfc00000) // -1.5
-		if x := math.Float32bits(math.Float32frombits(negFrac)); x != negFrac {
-			t.Errorf("got %#x, want %#x", x, negFrac)
-		}
-	}
-}
-
-// Signaling NaN values as constants.
-const (
-	snan32bits uint32 = 0x7f800001
-	snan64bits uint64 = 0x7ff0000000000001
-)
-
-// Signaling NaNs as variables.
-var snan32bitsVar uint32 = snan32bits
-var snan64bitsVar uint64 = snan64bits
-
-func TestFloatSignalingNaN(t *testing.T) {
-	// Make sure we generate a signaling NaN from a constant properly.
-	// See issue 36400.
-	f32 := math.Float32frombits(snan32bits)
-	g32 := math.Float32frombits(snan32bitsVar)
-	x32 := math.Float32bits(f32)
-	y32 := math.Float32bits(g32)
-	if x32 != y32 {
-		t.Errorf("got %x, want %x (diff=%x)", x32, y32, x32^y32)
-	}
-
-	f64 := math.Float64frombits(snan64bits)
-	g64 := math.Float64frombits(snan64bitsVar)
-	x64 := math.Float64bits(f64)
-	y64 := math.Float64bits(g64)
-	if x64 != y64 {
-		t.Errorf("got %x, want %x (diff=%x)", x64, y64, x64^y64)
-	}
-}
-
-func TestFloatSignalingNaNConversion(t *testing.T) {
-	// Test to make sure when we convert a signaling NaN, we get a NaN.
-	// (Ideally we want a quiet NaN, but some platforms don't agree.)
-	// See issue 36399.
-	s32 := math.Float32frombits(snan32bitsVar)
-	if s32 == s32 {
-		t.Errorf("converting a NaN did not result in a NaN")
-	}
-	s64 := math.Float64frombits(snan64bitsVar)
-	if s64 == s64 {
-		t.Errorf("converting a NaN did not result in a NaN")
-	}
-}
-
-func TestFloatSignalingNaNConversionConst(t *testing.T) {
-	// Test to make sure when we convert a signaling NaN, it converts to a NaN.
-	// (Ideally we want a quiet NaN, but some platforms don't agree.)
-	// See issue 36399 and 36400.
-	s32 := math.Float32frombits(snan32bits)
-	if s32 == s32 {
-		t.Errorf("converting a NaN did not result in a NaN")
-	}
-	s64 := math.Float64frombits(snan64bits)
-	if s64 == s64 {
-		t.Errorf("converting a NaN did not result in a NaN")
-	}
-}
-
-var sinkFloat float64
-
-func BenchmarkMul2(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var m float64 = 1
-		for j := 0; j < 500; j++ {
-			m *= 2
-		}
-		sinkFloat = m
-	}
-}
-func BenchmarkMulNeg2(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var m float64 = 1
-		for j := 0; j < 500; j++ {
-			m *= -2
-		}
-		sinkFloat = m
-	}
-}
diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go
deleted file mode 100644
index f92f5d0..0000000
--- a/src/cmd/compile/internal/gc/fmt.go
+++ /dev/null
@@ -1,1986 +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
-
-import (
-	"bytes"
-	"cmd/compile/internal/types"
-	"cmd/internal/src"
-	"fmt"
-	"io"
-	"strconv"
-	"strings"
-	"sync"
-	"unicode/utf8"
-)
-
-// A FmtFlag value is a set of flags (or 0).
-// They control how the Xconv functions format their values.
-// See the respective function's documentation for details.
-type FmtFlag int
-
-const ( //                                 fmt.Format flag/prec or verb
-	FmtLeft     FmtFlag = 1 << iota // '-'
-	FmtSharp                        // '#'
-	FmtSign                         // '+'
-	FmtUnsigned                     // internal use only (historic: u flag)
-	FmtShort                        // verb == 'S'       (historic: h flag)
-	FmtLong                         // verb == 'L'       (historic: l flag)
-	FmtComma                        // '.' (== hasPrec)  (historic: , flag)
-	FmtByte                         // '0'               (historic: hh flag)
-)
-
-// fmtFlag computes the (internal) FmtFlag
-// value given the fmt.State and format verb.
-func fmtFlag(s fmt.State, verb rune) FmtFlag {
-	var flag FmtFlag
-	if s.Flag('-') {
-		flag |= FmtLeft
-	}
-	if s.Flag('#') {
-		flag |= FmtSharp
-	}
-	if s.Flag('+') {
-		flag |= FmtSign
-	}
-	if s.Flag(' ') {
-		Fatalf("FmtUnsigned in format string")
-	}
-	if _, ok := s.Precision(); ok {
-		flag |= FmtComma
-	}
-	if s.Flag('0') {
-		flag |= FmtByte
-	}
-	switch verb {
-	case 'S':
-		flag |= FmtShort
-	case 'L':
-		flag |= FmtLong
-	}
-	return flag
-}
-
-// Format conversions:
-// TODO(gri) verify these; eliminate those not used anymore
-//
-//	%v Op		Node opcodes
-//		Flags:  #: print Go syntax (automatic unless mode == FDbg)
-//
-//	%j *Node	Node details
-//		Flags:  0: suppresses things not relevant until walk
-//
-//	%v *Val		Constant values
-//
-//	%v *types.Sym		Symbols
-//	%S              unqualified identifier in any mode
-//		Flags:  +,- #: mode (see below)
-//			0: in export mode: unqualified identifier if exported, qualified if not
-//
-//	%v *types.Type	Types
-//	%S              omit "func" and receiver in function types
-//	%L              definition instead of name.
-//		Flags:  +,- #: mode (see below)
-//			' ' (only in -/Sym mode) print type identifiers wit package name instead of prefix.
-//
-//	%v *Node	Nodes
-//	%S              (only in +/debug mode) suppress recursion
-//	%L              (only in Error mode) print "foo (type Bar)"
-//		Flags:  +,- #: mode (see below)
-//
-//	%v Nodes	Node lists
-//		Flags:  those of *Node
-//			.: separate items with ',' instead of ';'
-
-// *types.Sym, *types.Type, and *Node types use the flags below to set the format mode
-const (
-	FErr fmtMode = iota
-	FDbg
-	FTypeId
-	FTypeIdName // same as FTypeId, but use package name instead of prefix
-)
-
-// The mode flags '+', '-', and '#' are sticky; they persist through
-// recursions of *Node, *types.Type, and *types.Sym values. The ' ' flag is
-// sticky only on *types.Type recursions and only used in %-/*types.Sym mode.
-//
-// Example: given a *types.Sym: %+v %#v %-v print an identifier properly qualified for debug/export/internal mode
-
-// Useful format combinations:
-// TODO(gri): verify these
-//
-// *Node, Nodes:
-//   %+v    multiline recursive debug dump of *Node/Nodes
-//   %+S    non-recursive debug dump
-//
-// *Node:
-//   %#v    Go format
-//   %L     "foo (type Bar)" for error messages
-//
-// *types.Type:
-//   %#v    Go format
-//   %#L    type definition instead of name
-//   %#S    omit "func" and receiver in function signature
-//
-//   %-v    type identifiers
-//   %-S    type identifiers without "func" and arg names in type signatures (methodsym)
-//   %- v   type identifiers with package name instead of prefix (typesym, dcommontype, typehash)
-
-// update returns the results of applying f to mode.
-func (f FmtFlag) update(mode fmtMode) (FmtFlag, fmtMode) {
-	switch {
-	case f&FmtSign != 0:
-		mode = FDbg
-	case f&FmtSharp != 0:
-		// ignore (textual export format no longer supported)
-	case f&FmtUnsigned != 0:
-		mode = FTypeIdName
-	case f&FmtLeft != 0:
-		mode = FTypeId
-	}
-
-	f &^= FmtSharp | FmtLeft | FmtSign
-	return f, mode
-}
-
-var goopnames = []string{
-	OADDR:     "&",
-	OADD:      "+",
-	OADDSTR:   "+",
-	OALIGNOF:  "unsafe.Alignof",
-	OANDAND:   "&&",
-	OANDNOT:   "&^",
-	OAND:      "&",
-	OAPPEND:   "append",
-	OAS:       "=",
-	OAS2:      "=",
-	OBREAK:    "break",
-	OCALL:     "function call", // not actual syntax
-	OCAP:      "cap",
-	OCASE:     "case",
-	OCLOSE:    "close",
-	OCOMPLEX:  "complex",
-	OBITNOT:   "^",
-	OCONTINUE: "continue",
-	OCOPY:     "copy",
-	ODELETE:   "delete",
-	ODEFER:    "defer",
-	ODIV:      "/",
-	OEQ:       "==",
-	OFALL:     "fallthrough",
-	OFOR:      "for",
-	OFORUNTIL: "foruntil", // not actual syntax; used to avoid off-end pointer live on backedge.892
-	OGE:       ">=",
-	OGOTO:     "goto",
-	OGT:       ">",
-	OIF:       "if",
-	OIMAG:     "imag",
-	OINLMARK:  "inlmark",
-	ODEREF:    "*",
-	OLEN:      "len",
-	OLE:       "<=",
-	OLSH:      "<<",
-	OLT:       "<",
-	OMAKE:     "make",
-	ONEG:      "-",
-	OMOD:      "%",
-	OMUL:      "*",
-	ONEW:      "new",
-	ONE:       "!=",
-	ONOT:      "!",
-	OOFFSETOF: "unsafe.Offsetof",
-	OOROR:     "||",
-	OOR:       "|",
-	OPANIC:    "panic",
-	OPLUS:     "+",
-	OPRINTN:   "println",
-	OPRINT:    "print",
-	ORANGE:    "range",
-	OREAL:     "real",
-	ORECV:     "<-",
-	ORECOVER:  "recover",
-	ORETURN:   "return",
-	ORSH:      ">>",
-	OSELECT:   "select",
-	OSEND:     "<-",
-	OSIZEOF:   "unsafe.Sizeof",
-	OSUB:      "-",
-	OSWITCH:   "switch",
-	OXOR:      "^",
-}
-
-func (o Op) GoString() string {
-	return fmt.Sprintf("%#v", o)
-}
-
-func (o Op) format(s fmt.State, verb rune, mode fmtMode) {
-	switch verb {
-	case 'v':
-		o.oconv(s, fmtFlag(s, verb), mode)
-
-	default:
-		fmt.Fprintf(s, "%%!%c(Op=%d)", verb, int(o))
-	}
-}
-
-func (o Op) oconv(s fmt.State, flag FmtFlag, mode fmtMode) {
-	if flag&FmtSharp != 0 || mode != FDbg {
-		if int(o) < len(goopnames) && goopnames[o] != "" {
-			fmt.Fprint(s, goopnames[o])
-			return
-		}
-	}
-
-	// 'o.String()' instead of just 'o' to avoid infinite recursion
-	fmt.Fprint(s, o.String())
-}
-
-type (
-	fmtMode int
-
-	fmtNodeErr        Node
-	fmtNodeDbg        Node
-	fmtNodeTypeId     Node
-	fmtNodeTypeIdName Node
-
-	fmtOpErr        Op
-	fmtOpDbg        Op
-	fmtOpTypeId     Op
-	fmtOpTypeIdName Op
-
-	fmtTypeErr        types.Type
-	fmtTypeDbg        types.Type
-	fmtTypeTypeId     types.Type
-	fmtTypeTypeIdName types.Type
-
-	fmtSymErr        types.Sym
-	fmtSymDbg        types.Sym
-	fmtSymTypeId     types.Sym
-	fmtSymTypeIdName types.Sym
-
-	fmtNodesErr        Nodes
-	fmtNodesDbg        Nodes
-	fmtNodesTypeId     Nodes
-	fmtNodesTypeIdName Nodes
-)
-
-func (n *fmtNodeErr) Format(s fmt.State, verb rune)        { (*Node)(n).format(s, verb, FErr) }
-func (n *fmtNodeDbg) Format(s fmt.State, verb rune)        { (*Node)(n).format(s, verb, FDbg) }
-func (n *fmtNodeTypeId) Format(s fmt.State, verb rune)     { (*Node)(n).format(s, verb, FTypeId) }
-func (n *fmtNodeTypeIdName) Format(s fmt.State, verb rune) { (*Node)(n).format(s, verb, FTypeIdName) }
-func (n *Node) Format(s fmt.State, verb rune)              { n.format(s, verb, FErr) }
-
-func (o fmtOpErr) Format(s fmt.State, verb rune)        { Op(o).format(s, verb, FErr) }
-func (o fmtOpDbg) Format(s fmt.State, verb rune)        { Op(o).format(s, verb, FDbg) }
-func (o fmtOpTypeId) Format(s fmt.State, verb rune)     { Op(o).format(s, verb, FTypeId) }
-func (o fmtOpTypeIdName) Format(s fmt.State, verb rune) { Op(o).format(s, verb, FTypeIdName) }
-func (o Op) Format(s fmt.State, verb rune)              { o.format(s, verb, FErr) }
-
-func (t *fmtTypeErr) Format(s fmt.State, verb rune) { typeFormat((*types.Type)(t), s, verb, FErr) }
-func (t *fmtTypeDbg) Format(s fmt.State, verb rune) { typeFormat((*types.Type)(t), s, verb, FDbg) }
-func (t *fmtTypeTypeId) Format(s fmt.State, verb rune) {
-	typeFormat((*types.Type)(t), s, verb, FTypeId)
-}
-func (t *fmtTypeTypeIdName) Format(s fmt.State, verb rune) {
-	typeFormat((*types.Type)(t), s, verb, FTypeIdName)
-}
-
-// func (t *types.Type) Format(s fmt.State, verb rune)     // in package types
-
-func (y *fmtSymErr) Format(s fmt.State, verb rune)    { symFormat((*types.Sym)(y), s, verb, FErr) }
-func (y *fmtSymDbg) Format(s fmt.State, verb rune)    { symFormat((*types.Sym)(y), s, verb, FDbg) }
-func (y *fmtSymTypeId) Format(s fmt.State, verb rune) { symFormat((*types.Sym)(y), s, verb, FTypeId) }
-func (y *fmtSymTypeIdName) Format(s fmt.State, verb rune) {
-	symFormat((*types.Sym)(y), s, verb, FTypeIdName)
-}
-
-// func (y *types.Sym) Format(s fmt.State, verb rune)            // in package types  { y.format(s, verb, FErr) }
-
-func (n fmtNodesErr) Format(s fmt.State, verb rune)        { (Nodes)(n).format(s, verb, FErr) }
-func (n fmtNodesDbg) Format(s fmt.State, verb rune)        { (Nodes)(n).format(s, verb, FDbg) }
-func (n fmtNodesTypeId) Format(s fmt.State, verb rune)     { (Nodes)(n).format(s, verb, FTypeId) }
-func (n fmtNodesTypeIdName) Format(s fmt.State, verb rune) { (Nodes)(n).format(s, verb, FTypeIdName) }
-func (n Nodes) Format(s fmt.State, verb rune)              { n.format(s, verb, FErr) }
-
-func (m fmtMode) Fprintf(s fmt.State, format string, args ...interface{}) {
-	m.prepareArgs(args)
-	fmt.Fprintf(s, format, args...)
-}
-
-func (m fmtMode) Sprintf(format string, args ...interface{}) string {
-	m.prepareArgs(args)
-	return fmt.Sprintf(format, args...)
-}
-
-func (m fmtMode) Sprint(args ...interface{}) string {
-	m.prepareArgs(args)
-	return fmt.Sprint(args...)
-}
-
-func (m fmtMode) prepareArgs(args []interface{}) {
-	switch m {
-	case FErr:
-		for i, arg := range args {
-			switch arg := arg.(type) {
-			case Op:
-				args[i] = fmtOpErr(arg)
-			case *Node:
-				args[i] = (*fmtNodeErr)(arg)
-			case *types.Type:
-				args[i] = (*fmtTypeErr)(arg)
-			case *types.Sym:
-				args[i] = (*fmtSymErr)(arg)
-			case Nodes:
-				args[i] = fmtNodesErr(arg)
-			case Val, int32, int64, string, types.EType:
-				// OK: printing these types doesn't depend on mode
-			default:
-				Fatalf("mode.prepareArgs type %T", arg)
-			}
-		}
-	case FDbg:
-		for i, arg := range args {
-			switch arg := arg.(type) {
-			case Op:
-				args[i] = fmtOpDbg(arg)
-			case *Node:
-				args[i] = (*fmtNodeDbg)(arg)
-			case *types.Type:
-				args[i] = (*fmtTypeDbg)(arg)
-			case *types.Sym:
-				args[i] = (*fmtSymDbg)(arg)
-			case Nodes:
-				args[i] = fmtNodesDbg(arg)
-			case Val, int32, int64, string, types.EType:
-				// OK: printing these types doesn't depend on mode
-			default:
-				Fatalf("mode.prepareArgs type %T", arg)
-			}
-		}
-	case FTypeId:
-		for i, arg := range args {
-			switch arg := arg.(type) {
-			case Op:
-				args[i] = fmtOpTypeId(arg)
-			case *Node:
-				args[i] = (*fmtNodeTypeId)(arg)
-			case *types.Type:
-				args[i] = (*fmtTypeTypeId)(arg)
-			case *types.Sym:
-				args[i] = (*fmtSymTypeId)(arg)
-			case Nodes:
-				args[i] = fmtNodesTypeId(arg)
-			case Val, int32, int64, string, types.EType:
-				// OK: printing these types doesn't depend on mode
-			default:
-				Fatalf("mode.prepareArgs type %T", arg)
-			}
-		}
-	case FTypeIdName:
-		for i, arg := range args {
-			switch arg := arg.(type) {
-			case Op:
-				args[i] = fmtOpTypeIdName(arg)
-			case *Node:
-				args[i] = (*fmtNodeTypeIdName)(arg)
-			case *types.Type:
-				args[i] = (*fmtTypeTypeIdName)(arg)
-			case *types.Sym:
-				args[i] = (*fmtSymTypeIdName)(arg)
-			case Nodes:
-				args[i] = fmtNodesTypeIdName(arg)
-			case Val, int32, int64, string, types.EType:
-				// OK: printing these types doesn't depend on mode
-			default:
-				Fatalf("mode.prepareArgs type %T", arg)
-			}
-		}
-	default:
-		Fatalf("mode.prepareArgs mode %d", m)
-	}
-}
-
-func (n *Node) format(s fmt.State, verb rune, mode fmtMode) {
-	switch verb {
-	case 'v', 'S', 'L':
-		n.nconv(s, fmtFlag(s, verb), mode)
-
-	case 'j':
-		n.jconv(s, fmtFlag(s, verb))
-
-	default:
-		fmt.Fprintf(s, "%%!%c(*Node=%p)", verb, n)
-	}
-}
-
-// *Node details
-func (n *Node) jconv(s fmt.State, flag FmtFlag) {
-	c := flag & FmtShort
-
-	// Useful to see which nodes in a Node Dump/dumplist are actually identical
-	if Debug_dumpptrs != 0 {
-		fmt.Fprintf(s, " p(%p)", n)
-	}
-	if c == 0 && n.Name != nil && n.Name.Vargen != 0 {
-		fmt.Fprintf(s, " g(%d)", n.Name.Vargen)
-	}
-
-	if Debug_dumpptrs != 0 && c == 0 && n.Name != nil && n.Name.Defn != nil {
-		// Useful to see where Defn is set and what node it points to
-		fmt.Fprintf(s, " defn(%p)", n.Name.Defn)
-	}
-
-	if n.Pos.IsKnown() {
-		pfx := ""
-		switch n.Pos.IsStmt() {
-		case src.PosNotStmt:
-			pfx = "_" // "-" would be confusing
-		case src.PosIsStmt:
-			pfx = "+"
-		}
-		fmt.Fprintf(s, " l(%s%d)", pfx, n.Pos.Line())
-	}
-
-	if c == 0 && n.Xoffset != BADWIDTH {
-		fmt.Fprintf(s, " x(%d)", n.Xoffset)
-	}
-
-	if n.Class() != 0 {
-		fmt.Fprintf(s, " class(%v)", n.Class())
-	}
-
-	if n.Colas() {
-		fmt.Fprintf(s, " colas(%v)", n.Colas())
-	}
-
-	switch n.Esc {
-	case EscUnknown:
-		break
-
-	case EscHeap:
-		fmt.Fprint(s, " esc(h)")
-
-	case EscNone:
-		fmt.Fprint(s, " esc(no)")
-
-	case EscNever:
-		if c == 0 {
-			fmt.Fprint(s, " esc(N)")
-		}
-
-	default:
-		fmt.Fprintf(s, " esc(%d)", n.Esc)
-	}
-
-	if e, ok := n.Opt().(*EscLocation); ok && e.loopDepth != 0 {
-		fmt.Fprintf(s, " ld(%d)", e.loopDepth)
-	}
-
-	if c == 0 && n.Typecheck() != 0 {
-		fmt.Fprintf(s, " tc(%d)", n.Typecheck())
-	}
-
-	if n.IsDDD() {
-		fmt.Fprintf(s, " isddd(%v)", n.IsDDD())
-	}
-
-	if n.Implicit() {
-		fmt.Fprintf(s, " implicit(%v)", n.Implicit())
-	}
-
-	if n.Embedded() {
-		fmt.Fprintf(s, " embedded")
-	}
-
-	if n.Op == ONAME {
-		if n.Name.Addrtaken() {
-			fmt.Fprint(s, " addrtaken")
-		}
-		if n.Name.Assigned() {
-			fmt.Fprint(s, " assigned")
-		}
-		if n.Name.IsClosureVar() {
-			fmt.Fprint(s, " closurevar")
-		}
-		if n.Name.Captured() {
-			fmt.Fprint(s, " captured")
-		}
-		if n.Name.IsOutputParamHeapAddr() {
-			fmt.Fprint(s, " outputparamheapaddr")
-		}
-	}
-	if n.Bounded() {
-		fmt.Fprint(s, " bounded")
-	}
-	if n.NonNil() {
-		fmt.Fprint(s, " nonnil")
-	}
-
-	if c == 0 && n.HasCall() {
-		fmt.Fprint(s, " hascall")
-	}
-
-	if c == 0 && n.Name != nil && n.Name.Used() {
-		fmt.Fprint(s, " used")
-	}
-}
-
-func (v Val) Format(s fmt.State, verb rune) {
-	switch verb {
-	case 'v':
-		v.vconv(s, fmtFlag(s, verb))
-
-	default:
-		fmt.Fprintf(s, "%%!%c(Val=%T)", verb, v)
-	}
-}
-
-func (v Val) vconv(s fmt.State, flag FmtFlag) {
-	switch u := v.U.(type) {
-	case *Mpint:
-		if !u.Rune {
-			if flag&FmtSharp != 0 {
-				fmt.Fprint(s, u.String())
-				return
-			}
-			fmt.Fprint(s, u.GoString())
-			return
-		}
-
-		switch x := u.Int64(); {
-		case ' ' <= x && x < utf8.RuneSelf && x != '\\' && x != '\'':
-			fmt.Fprintf(s, "'%c'", int(x))
-
-		case 0 <= x && x < 1<<16:
-			fmt.Fprintf(s, "'\\u%04x'", uint(int(x)))
-
-		case 0 <= x && x <= utf8.MaxRune:
-			fmt.Fprintf(s, "'\\U%08x'", uint64(x))
-
-		default:
-			fmt.Fprintf(s, "('\\x00' + %v)", u)
-		}
-
-	case *Mpflt:
-		if flag&FmtSharp != 0 {
-			fmt.Fprint(s, u.String())
-			return
-		}
-		fmt.Fprint(s, u.GoString())
-		return
-
-	case *Mpcplx:
-		if flag&FmtSharp != 0 {
-			fmt.Fprint(s, u.String())
-			return
-		}
-		fmt.Fprint(s, u.GoString())
-		return
-
-	case string:
-		fmt.Fprint(s, strconv.Quote(u))
-
-	case bool:
-		fmt.Fprint(s, u)
-
-	case *NilVal:
-		fmt.Fprint(s, "nil")
-
-	default:
-		fmt.Fprintf(s, "<ctype=%d>", v.Ctype())
-	}
-}
-
-/*
-s%,%,\n%g
-s%\n+%\n%g
-s%^[	]*T%%g
-s%,.*%%g
-s%.+%	[T&]		= "&",%g
-s%^	........*\]%&~%g
-s%~	%%g
-*/
-
-func symfmt(b *bytes.Buffer, s *types.Sym, flag FmtFlag, mode fmtMode) {
-	if flag&FmtShort == 0 {
-		switch mode {
-		case FErr: // This is for the user
-			if s.Pkg == builtinpkg || s.Pkg == localpkg {
-				b.WriteString(s.Name)
-				return
-			}
-
-			// If the name was used by multiple packages, display the full path,
-			if s.Pkg.Name != "" && numImport[s.Pkg.Name] > 1 {
-				fmt.Fprintf(b, "%q.%s", s.Pkg.Path, s.Name)
-				return
-			}
-			b.WriteString(s.Pkg.Name)
-			b.WriteByte('.')
-			b.WriteString(s.Name)
-			return
-
-		case FDbg:
-			b.WriteString(s.Pkg.Name)
-			b.WriteByte('.')
-			b.WriteString(s.Name)
-			return
-
-		case FTypeIdName:
-			// dcommontype, typehash
-			b.WriteString(s.Pkg.Name)
-			b.WriteByte('.')
-			b.WriteString(s.Name)
-			return
-
-		case FTypeId:
-			// (methodsym), typesym, weaksym
-			b.WriteString(s.Pkg.Prefix)
-			b.WriteByte('.')
-			b.WriteString(s.Name)
-			return
-		}
-	}
-
-	if flag&FmtByte != 0 {
-		// FmtByte (hh) implies FmtShort (h)
-		// skip leading "type." in method name
-		name := s.Name
-		if i := strings.LastIndex(name, "."); i >= 0 {
-			name = name[i+1:]
-		}
-
-		if mode == FDbg {
-			fmt.Fprintf(b, "@%q.%s", s.Pkg.Path, name)
-			return
-		}
-
-		b.WriteString(name)
-		return
-	}
-
-	b.WriteString(s.Name)
-}
-
-var basicnames = []string{
-	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",
-	TANY:        "any",
-	TSTRING:     "string",
-	TNIL:        "nil",
-	TIDEAL:      "untyped number",
-	TBLANK:      "blank",
-}
-
-var fmtBufferPool = sync.Pool{
-	New: func() interface{} {
-		return new(bytes.Buffer)
-	},
-}
-
-func tconv(t *types.Type, flag FmtFlag, mode fmtMode) string {
-	buf := fmtBufferPool.Get().(*bytes.Buffer)
-	buf.Reset()
-	defer fmtBufferPool.Put(buf)
-
-	tconv2(buf, t, flag, mode, nil)
-	return types.InternString(buf.Bytes())
-}
-
-// tconv2 writes a string representation of t to b.
-// flag and mode control exactly what is printed.
-// Any types x that are already in the visited map get printed as @%d where %d=visited[x].
-// See #16897 before changing the implementation of tconv.
-func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited map[*types.Type]int) {
-	if off, ok := visited[t]; ok {
-		// We've seen this type before, so we're trying to print it recursively.
-		// Print a reference to it instead.
-		fmt.Fprintf(b, "@%d", off)
-		return
-	}
-	if t == nil {
-		b.WriteString("<T>")
-		return
-	}
-	if t.Etype == types.TSSA {
-		b.WriteString(t.Extra.(string))
-		return
-	}
-	if t.Etype == types.TTUPLE {
-		b.WriteString(t.FieldType(0).String())
-		b.WriteByte(',')
-		b.WriteString(t.FieldType(1).String())
-		return
-	}
-
-	if t.Etype == types.TRESULTS {
-		tys := t.Extra.(*types.Results).Types
-		for i, et := range tys {
-			if i > 0 {
-				b.WriteByte(',')
-			}
-			b.WriteString(et.String())
-		}
-		return
-	}
-
-	flag, mode = flag.update(mode)
-	if mode == FTypeIdName {
-		flag |= FmtUnsigned
-	}
-	if t == types.Bytetype || t == types.Runetype {
-		// in %-T mode collapse rune and byte with their originals.
-		switch mode {
-		case FTypeIdName, FTypeId:
-			t = types.Types[t.Etype]
-		default:
-			sconv2(b, t.Sym, FmtShort, mode)
-			return
-		}
-	}
-	if t == types.Errortype {
-		b.WriteString("error")
-		return
-	}
-
-	// Unless the 'L' flag was specified, if the type has a name, just print that name.
-	if flag&FmtLong == 0 && t.Sym != nil && t != types.Types[t.Etype] {
-		switch mode {
-		case FTypeId, FTypeIdName:
-			if flag&FmtShort != 0 {
-				if t.Vargen != 0 {
-					sconv2(b, t.Sym, FmtShort, mode)
-					fmt.Fprintf(b, "·%d", t.Vargen)
-					return
-				}
-				sconv2(b, t.Sym, FmtShort, mode)
-				return
-			}
-
-			if mode == FTypeIdName {
-				sconv2(b, t.Sym, FmtUnsigned, mode)
-				return
-			}
-
-			if t.Sym.Pkg == localpkg && t.Vargen != 0 {
-				b.WriteString(mode.Sprintf("%v·%d", t.Sym, t.Vargen))
-				return
-			}
-		}
-
-		sconv2(b, t.Sym, 0, mode)
-		return
-	}
-
-	if int(t.Etype) < len(basicnames) && basicnames[t.Etype] != "" {
-		var name string
-		switch t {
-		case types.UntypedBool:
-			name = "untyped bool"
-		case types.UntypedString:
-			name = "untyped string"
-		case types.UntypedInt:
-			name = "untyped int"
-		case types.UntypedRune:
-			name = "untyped rune"
-		case types.UntypedFloat:
-			name = "untyped float"
-		case types.UntypedComplex:
-			name = "untyped complex"
-		default:
-			name = basicnames[t.Etype]
-		}
-		b.WriteString(name)
-		return
-	}
-
-	if mode == FDbg {
-		b.WriteString(t.Etype.String())
-		b.WriteByte('-')
-		tconv2(b, t, flag, FErr, visited)
-		return
-	}
-
-	// At this point, we might call tconv2 recursively. Add the current type to the visited list so we don't
-	// try to print it recursively.
-	// We record the offset in the result buffer where the type's text starts. This offset serves as a reference
-	// point for any later references to the same type.
-	// Note that we remove the type from the visited map as soon as the recursive call is done.
-	// This prevents encoding types like map[*int]*int as map[*int]@4. (That encoding would work,
-	// but I'd like to use the @ notation only when strictly necessary.)
-	if visited == nil {
-		visited = map[*types.Type]int{}
-	}
-	visited[t] = b.Len()
-	defer delete(visited, t)
-
-	switch t.Etype {
-	case TPTR:
-		b.WriteByte('*')
-		switch mode {
-		case FTypeId, FTypeIdName:
-			if flag&FmtShort != 0 {
-				tconv2(b, t.Elem(), FmtShort, mode, visited)
-				return
-			}
-		}
-		tconv2(b, t.Elem(), 0, mode, visited)
-
-	case TARRAY:
-		b.WriteByte('[')
-		b.WriteString(strconv.FormatInt(t.NumElem(), 10))
-		b.WriteByte(']')
-		tconv2(b, t.Elem(), 0, mode, visited)
-
-	case TSLICE:
-		b.WriteString("[]")
-		tconv2(b, t.Elem(), 0, mode, visited)
-
-	case TCHAN:
-		switch t.ChanDir() {
-		case types.Crecv:
-			b.WriteString("<-chan ")
-			tconv2(b, t.Elem(), 0, mode, visited)
-		case types.Csend:
-			b.WriteString("chan<- ")
-			tconv2(b, t.Elem(), 0, mode, visited)
-		default:
-			b.WriteString("chan ")
-			if t.Elem() != nil && t.Elem().IsChan() && t.Elem().Sym == nil && t.Elem().ChanDir() == types.Crecv {
-				b.WriteByte('(')
-				tconv2(b, t.Elem(), 0, mode, visited)
-				b.WriteByte(')')
-			} else {
-				tconv2(b, t.Elem(), 0, mode, visited)
-			}
-		}
-
-	case TMAP:
-		b.WriteString("map[")
-		tconv2(b, t.Key(), 0, mode, visited)
-		b.WriteByte(']')
-		tconv2(b, t.Elem(), 0, mode, visited)
-
-	case TINTER:
-		if t.IsEmptyInterface() {
-			b.WriteString("interface {}")
-			break
-		}
-		b.WriteString("interface {")
-		for i, f := range t.Fields().Slice() {
-			if i != 0 {
-				b.WriteByte(';')
-			}
-			b.WriteByte(' ')
-			switch {
-			case f.Sym == nil:
-				// Check first that a symbol is defined for this type.
-				// Wrong interface definitions may have types lacking a symbol.
-				break
-			case types.IsExported(f.Sym.Name):
-				sconv2(b, f.Sym, FmtShort, mode)
-			default:
-				flag1 := FmtLeft
-				if flag&FmtUnsigned != 0 {
-					flag1 = FmtUnsigned
-				}
-				sconv2(b, f.Sym, flag1, mode)
-			}
-			tconv2(b, f.Type, FmtShort, mode, visited)
-		}
-		if t.NumFields() != 0 {
-			b.WriteByte(' ')
-		}
-		b.WriteByte('}')
-
-	case TFUNC:
-		if flag&FmtShort != 0 {
-			// no leading func
-		} else {
-			if t.Recv() != nil {
-				b.WriteString("method")
-				tconv2(b, t.Recvs(), 0, mode, visited)
-				b.WriteByte(' ')
-			}
-			b.WriteString("func")
-		}
-		tconv2(b, t.Params(), 0, mode, visited)
-
-		switch t.NumResults() {
-		case 0:
-			// nothing to do
-
-		case 1:
-			b.WriteByte(' ')
-			tconv2(b, t.Results().Field(0).Type, 0, mode, visited) // struct->field->field's type
-
-		default:
-			b.WriteByte(' ')
-			tconv2(b, t.Results(), 0, mode, visited)
-		}
-
-	case TSTRUCT:
-		if m := t.StructType().Map; m != nil {
-			mt := m.MapType()
-			// Format the bucket struct for map[x]y as map.bucket[x]y.
-			// This avoids a recursive print that generates very long names.
-			switch t {
-			case mt.Bucket:
-				b.WriteString("map.bucket[")
-			case mt.Hmap:
-				b.WriteString("map.hdr[")
-			case mt.Hiter:
-				b.WriteString("map.iter[")
-			default:
-				Fatalf("unknown internal map type")
-			}
-			tconv2(b, m.Key(), 0, mode, visited)
-			b.WriteByte(']')
-			tconv2(b, m.Elem(), 0, mode, visited)
-			break
-		}
-
-		if funarg := t.StructType().Funarg; funarg != types.FunargNone {
-			b.WriteByte('(')
-			var flag1 FmtFlag
-			switch mode {
-			case FTypeId, FTypeIdName, FErr:
-				// no argument names on function signature, and no "noescape"/"nosplit" tags
-				flag1 = FmtShort
-			}
-			for i, f := range t.Fields().Slice() {
-				if i != 0 {
-					b.WriteString(", ")
-				}
-				fldconv(b, f, flag1, mode, visited, funarg)
-			}
-			b.WriteByte(')')
-		} else {
-			b.WriteString("struct {")
-			for i, f := range t.Fields().Slice() {
-				if i != 0 {
-					b.WriteByte(';')
-				}
-				b.WriteByte(' ')
-				fldconv(b, f, FmtLong, mode, visited, funarg)
-			}
-			if t.NumFields() != 0 {
-				b.WriteByte(' ')
-			}
-			b.WriteByte('}')
-		}
-
-	case TFORW:
-		b.WriteString("undefined")
-		if t.Sym != nil {
-			b.WriteByte(' ')
-			sconv2(b, t.Sym, 0, mode)
-		}
-
-	case TUNSAFEPTR:
-		b.WriteString("unsafe.Pointer")
-
-	case Txxx:
-		b.WriteString("Txxx")
-	default:
-		// Don't know how to handle - fall back to detailed prints.
-		b.WriteString(mode.Sprintf("%v <%v>", t.Etype, t.Sym))
-	}
-}
-
-// Statements which may be rendered with a simplestmt as init.
-func stmtwithinit(op Op) bool {
-	switch op {
-	case OIF, OFOR, OFORUNTIL, OSWITCH:
-		return true
-	}
-
-	return false
-}
-
-func (n *Node) stmtfmt(s fmt.State, mode fmtMode) {
-	// some statements allow for an init, but at most one,
-	// but we may have an arbitrary number added, eg by typecheck
-	// and inlining. If it doesn't fit the syntax, emit an enclosing
-	// block starting with the init statements.
-
-	// if we can just say "for" n->ninit; ... then do so
-	simpleinit := n.Ninit.Len() == 1 && n.Ninit.First().Ninit.Len() == 0 && stmtwithinit(n.Op)
-
-	// otherwise, print the inits as separate statements
-	complexinit := n.Ninit.Len() != 0 && !simpleinit && (mode != FErr)
-
-	// but if it was for if/for/switch, put in an extra surrounding block to limit the scope
-	extrablock := complexinit && stmtwithinit(n.Op)
-
-	if extrablock {
-		fmt.Fprint(s, "{")
-	}
-
-	if complexinit {
-		mode.Fprintf(s, " %v; ", n.Ninit)
-	}
-
-	switch n.Op {
-	case ODCL:
-		mode.Fprintf(s, "var %v %v", n.Left.Sym, n.Left.Type)
-
-	case ODCLFIELD:
-		if n.Sym != nil {
-			mode.Fprintf(s, "%v %v", n.Sym, n.Left)
-		} else {
-			mode.Fprintf(s, "%v", n.Left)
-		}
-
-	// Don't export "v = <N>" initializing statements, hope they're always
-	// preceded by the DCL which will be re-parsed and typechecked to reproduce
-	// the "v = <N>" again.
-	case OAS:
-		if n.Colas() && !complexinit {
-			mode.Fprintf(s, "%v := %v", n.Left, n.Right)
-		} else {
-			mode.Fprintf(s, "%v = %v", n.Left, n.Right)
-		}
-
-	case OASOP:
-		if n.Implicit() {
-			if n.SubOp() == OADD {
-				mode.Fprintf(s, "%v++", n.Left)
-			} else {
-				mode.Fprintf(s, "%v--", n.Left)
-			}
-			break
-		}
-
-		mode.Fprintf(s, "%v %#v= %v", n.Left, n.SubOp(), n.Right)
-
-	case OAS2:
-		if n.Colas() && !complexinit {
-			mode.Fprintf(s, "%.v := %.v", n.List, n.Rlist)
-			break
-		}
-		fallthrough
-
-	case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
-		mode.Fprintf(s, "%.v = %v", n.List, n.Right)
-
-	case ORETURN:
-		mode.Fprintf(s, "return %.v", n.List)
-
-	case ORETJMP:
-		mode.Fprintf(s, "retjmp %v", n.Sym)
-
-	case OINLMARK:
-		mode.Fprintf(s, "inlmark %d", n.Xoffset)
-
-	case OGO:
-		mode.Fprintf(s, "go %v", n.Left)
-
-	case ODEFER:
-		mode.Fprintf(s, "defer %v", n.Left)
-
-	case OIF:
-		if simpleinit {
-			mode.Fprintf(s, "if %v; %v { %v }", n.Ninit.First(), n.Left, n.Nbody)
-		} else {
-			mode.Fprintf(s, "if %v { %v }", n.Left, n.Nbody)
-		}
-		if n.Rlist.Len() != 0 {
-			mode.Fprintf(s, " else { %v }", n.Rlist)
-		}
-
-	case OFOR, OFORUNTIL:
-		opname := "for"
-		if n.Op == OFORUNTIL {
-			opname = "foruntil"
-		}
-		if mode == FErr { // TODO maybe only if FmtShort, same below
-			fmt.Fprintf(s, "%s loop", opname)
-			break
-		}
-
-		fmt.Fprint(s, opname)
-		if simpleinit {
-			mode.Fprintf(s, " %v;", n.Ninit.First())
-		} else if n.Right != nil {
-			fmt.Fprint(s, " ;")
-		}
-
-		if n.Left != nil {
-			mode.Fprintf(s, " %v", n.Left)
-		}
-
-		if n.Right != nil {
-			mode.Fprintf(s, "; %v", n.Right)
-		} else if simpleinit {
-			fmt.Fprint(s, ";")
-		}
-
-		if n.Op == OFORUNTIL && n.List.Len() != 0 {
-			mode.Fprintf(s, "; %v", n.List)
-		}
-
-		mode.Fprintf(s, " { %v }", n.Nbody)
-
-	case ORANGE:
-		if mode == FErr {
-			fmt.Fprint(s, "for loop")
-			break
-		}
-
-		if n.List.Len() == 0 {
-			mode.Fprintf(s, "for range %v { %v }", n.Right, n.Nbody)
-			break
-		}
-
-		mode.Fprintf(s, "for %.v = range %v { %v }", n.List, n.Right, n.Nbody)
-
-	case OSELECT, OSWITCH:
-		if mode == FErr {
-			mode.Fprintf(s, "%v statement", n.Op)
-			break
-		}
-
-		mode.Fprintf(s, "%#v", n.Op)
-		if simpleinit {
-			mode.Fprintf(s, " %v;", n.Ninit.First())
-		}
-		if n.Left != nil {
-			mode.Fprintf(s, " %v ", n.Left)
-		}
-
-		mode.Fprintf(s, " { %v }", n.List)
-
-	case OCASE:
-		if n.List.Len() != 0 {
-			mode.Fprintf(s, "case %.v", n.List)
-		} else {
-			fmt.Fprint(s, "default")
-		}
-		mode.Fprintf(s, ": %v", n.Nbody)
-
-	case OBREAK, OCONTINUE, OGOTO, OFALL:
-		if n.Sym != nil {
-			mode.Fprintf(s, "%#v %v", n.Op, n.Sym)
-		} else {
-			mode.Fprintf(s, "%#v", n.Op)
-		}
-
-	case OEMPTY:
-		break
-
-	case OLABEL:
-		mode.Fprintf(s, "%v: ", n.Sym)
-	}
-
-	if extrablock {
-		fmt.Fprint(s, "}")
-	}
-}
-
-var opprec = []int{
-	OALIGNOF:       8,
-	OAPPEND:        8,
-	OBYTES2STR:     8,
-	OARRAYLIT:      8,
-	OSLICELIT:      8,
-	ORUNES2STR:     8,
-	OCALLFUNC:      8,
-	OCALLINTER:     8,
-	OCALLMETH:      8,
-	OCALL:          8,
-	OCAP:           8,
-	OCLOSE:         8,
-	OCONVIFACE:     8,
-	OCONVNOP:       8,
-	OCONV:          8,
-	OCOPY:          8,
-	ODELETE:        8,
-	OGETG:          8,
-	OLEN:           8,
-	OLITERAL:       8,
-	OMAKESLICE:     8,
-	OMAKESLICECOPY: 8,
-	OMAKE:          8,
-	OMAPLIT:        8,
-	ONAME:          8,
-	ONEW:           8,
-	ONONAME:        8,
-	OOFFSETOF:      8,
-	OPACK:          8,
-	OPANIC:         8,
-	OPAREN:         8,
-	OPRINTN:        8,
-	OPRINT:         8,
-	ORUNESTR:       8,
-	OSIZEOF:        8,
-	OSTR2BYTES:     8,
-	OSTR2RUNES:     8,
-	OSTRUCTLIT:     8,
-	OTARRAY:        8,
-	OTCHAN:         8,
-	OTFUNC:         8,
-	OTINTER:        8,
-	OTMAP:          8,
-	OTSTRUCT:       8,
-	OINDEXMAP:      8,
-	OINDEX:         8,
-	OSLICE:         8,
-	OSLICESTR:      8,
-	OSLICEARR:      8,
-	OSLICE3:        8,
-	OSLICE3ARR:     8,
-	OSLICEHEADER:   8,
-	ODOTINTER:      8,
-	ODOTMETH:       8,
-	ODOTPTR:        8,
-	ODOTTYPE2:      8,
-	ODOTTYPE:       8,
-	ODOT:           8,
-	OXDOT:          8,
-	OCALLPART:      8,
-	OPLUS:          7,
-	ONOT:           7,
-	OBITNOT:        7,
-	ONEG:           7,
-	OADDR:          7,
-	ODEREF:         7,
-	ORECV:          7,
-	OMUL:           6,
-	ODIV:           6,
-	OMOD:           6,
-	OLSH:           6,
-	ORSH:           6,
-	OAND:           6,
-	OANDNOT:        6,
-	OADD:           5,
-	OSUB:           5,
-	OOR:            5,
-	OXOR:           5,
-	OEQ:            4,
-	OLT:            4,
-	OLE:            4,
-	OGE:            4,
-	OGT:            4,
-	ONE:            4,
-	OSEND:          3,
-	OANDAND:        2,
-	OOROR:          1,
-
-	// Statements handled by stmtfmt
-	OAS:         -1,
-	OAS2:        -1,
-	OAS2DOTTYPE: -1,
-	OAS2FUNC:    -1,
-	OAS2MAPR:    -1,
-	OAS2RECV:    -1,
-	OASOP:       -1,
-	OBREAK:      -1,
-	OCASE:       -1,
-	OCONTINUE:   -1,
-	ODCL:        -1,
-	ODCLFIELD:   -1,
-	ODEFER:      -1,
-	OEMPTY:      -1,
-	OFALL:       -1,
-	OFOR:        -1,
-	OFORUNTIL:   -1,
-	OGOTO:       -1,
-	OIF:         -1,
-	OLABEL:      -1,
-	OGO:         -1,
-	ORANGE:      -1,
-	ORETURN:     -1,
-	OSELECT:     -1,
-	OSWITCH:     -1,
-
-	OEND: 0,
-}
-
-func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
-	for n != nil && n.Implicit() && (n.Op == ODEREF || n.Op == OADDR) {
-		n = n.Left
-	}
-
-	if n == nil {
-		fmt.Fprint(s, "<N>")
-		return
-	}
-
-	nprec := opprec[n.Op]
-	if n.Op == OTYPE && n.Sym != nil {
-		nprec = 8
-	}
-
-	if prec > nprec {
-		mode.Fprintf(s, "(%v)", n)
-		return
-	}
-
-	switch n.Op {
-	case OPAREN:
-		mode.Fprintf(s, "(%v)", n.Left)
-
-	case OLITERAL: // this is a bit of a mess
-		if mode == FErr {
-			if n.Orig != nil && n.Orig != n {
-				n.Orig.exprfmt(s, prec, mode)
-				return
-			}
-			if n.Sym != nil {
-				fmt.Fprint(s, smodeString(n.Sym, mode))
-				return
-			}
-		}
-		if n.Val().Ctype() == CTNIL && n.Orig != nil && n.Orig != n {
-			n.Orig.exprfmt(s, prec, mode)
-			return
-		}
-		if n.Type != nil && !n.Type.IsUntyped() {
-			// Need parens when type begins with what might
-			// be misinterpreted as a unary operator: * or <-.
-			if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == types.Crecv) {
-				mode.Fprintf(s, "(%v)(%v)", n.Type, n.Val())
-				return
-			} else {
-				mode.Fprintf(s, "%v(%v)", n.Type, n.Val())
-				return
-			}
-		}
-
-		mode.Fprintf(s, "%v", n.Val())
-
-	// Special case: name used as local variable in export.
-	// _ becomes ~b%d internally; print as _ for export
-	case ONAME:
-		if mode == FErr && n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' {
-			fmt.Fprint(s, "_")
-			return
-		}
-		fallthrough
-	case OPACK, ONONAME:
-		fmt.Fprint(s, smodeString(n.Sym, mode))
-
-	case OTYPE:
-		if n.Type == nil && n.Sym != nil {
-			fmt.Fprint(s, smodeString(n.Sym, mode))
-			return
-		}
-		mode.Fprintf(s, "%v", n.Type)
-
-	case OTARRAY:
-		if n.Left != nil {
-			mode.Fprintf(s, "[%v]%v", n.Left, n.Right)
-			return
-		}
-		mode.Fprintf(s, "[]%v", n.Right) // happens before typecheck
-
-	case OTMAP:
-		mode.Fprintf(s, "map[%v]%v", n.Left, n.Right)
-
-	case OTCHAN:
-		switch n.TChanDir() {
-		case types.Crecv:
-			mode.Fprintf(s, "<-chan %v", n.Left)
-
-		case types.Csend:
-			mode.Fprintf(s, "chan<- %v", n.Left)
-
-		default:
-			if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && n.Left.TChanDir() == types.Crecv {
-				mode.Fprintf(s, "chan (%v)", n.Left)
-			} else {
-				mode.Fprintf(s, "chan %v", n.Left)
-			}
-		}
-
-	case OTSTRUCT:
-		fmt.Fprint(s, "<struct>")
-
-	case OTINTER:
-		fmt.Fprint(s, "<inter>")
-
-	case OTFUNC:
-		fmt.Fprint(s, "<func>")
-
-	case OCLOSURE:
-		if mode == FErr {
-			fmt.Fprint(s, "func literal")
-			return
-		}
-		if n.Nbody.Len() != 0 {
-			mode.Fprintf(s, "%v { %v }", n.Type, n.Nbody)
-			return
-		}
-		mode.Fprintf(s, "%v { %v }", n.Type, n.Func.Closure.Nbody)
-
-	case OCOMPLIT:
-		if mode == FErr {
-			if n.Implicit() {
-				mode.Fprintf(s, "... argument")
-				return
-			}
-			if n.Right != nil {
-				mode.Fprintf(s, "%v{%s}", n.Right, ellipsisIf(n.List.Len() != 0))
-				return
-			}
-
-			fmt.Fprint(s, "composite literal")
-			return
-		}
-		mode.Fprintf(s, "(%v{ %.v })", n.Right, n.List)
-
-	case OPTRLIT:
-		mode.Fprintf(s, "&%v", n.Left)
-
-	case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
-		if mode == FErr {
-			mode.Fprintf(s, "%v{%s}", n.Type, ellipsisIf(n.List.Len() != 0))
-			return
-		}
-		mode.Fprintf(s, "(%v{ %.v })", n.Type, n.List)
-
-	case OKEY:
-		if n.Left != nil && n.Right != nil {
-			mode.Fprintf(s, "%v:%v", n.Left, n.Right)
-			return
-		}
-
-		if n.Left == nil && n.Right != nil {
-			mode.Fprintf(s, ":%v", n.Right)
-			return
-		}
-		if n.Left != nil && n.Right == nil {
-			mode.Fprintf(s, "%v:", n.Left)
-			return
-		}
-		fmt.Fprint(s, ":")
-
-	case OSTRUCTKEY:
-		mode.Fprintf(s, "%v:%v", n.Sym, n.Left)
-
-	case OCALLPART:
-		n.Left.exprfmt(s, nprec, mode)
-		if n.Right == nil || n.Right.Sym == nil {
-			fmt.Fprint(s, ".<nil>")
-			return
-		}
-		mode.Fprintf(s, ".%0S", n.Right.Sym)
-
-	case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
-		n.Left.exprfmt(s, nprec, mode)
-		if n.Sym == nil {
-			fmt.Fprint(s, ".<nil>")
-			return
-		}
-		mode.Fprintf(s, ".%0S", n.Sym)
-
-	case ODOTTYPE, ODOTTYPE2:
-		n.Left.exprfmt(s, nprec, mode)
-		if n.Right != nil {
-			mode.Fprintf(s, ".(%v)", n.Right)
-			return
-		}
-		mode.Fprintf(s, ".(%v)", n.Type)
-
-	case OINDEX, OINDEXMAP:
-		n.Left.exprfmt(s, nprec, mode)
-		mode.Fprintf(s, "[%v]", n.Right)
-
-	case OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
-		n.Left.exprfmt(s, nprec, mode)
-		fmt.Fprint(s, "[")
-		low, high, max := n.SliceBounds()
-		if low != nil {
-			fmt.Fprint(s, low.modeString(mode))
-		}
-		fmt.Fprint(s, ":")
-		if high != nil {
-			fmt.Fprint(s, high.modeString(mode))
-		}
-		if n.Op.IsSlice3() {
-			fmt.Fprint(s, ":")
-			if max != nil {
-				fmt.Fprint(s, max.modeString(mode))
-			}
-		}
-		fmt.Fprint(s, "]")
-
-	case OSLICEHEADER:
-		if n.List.Len() != 2 {
-			Fatalf("bad OSLICEHEADER list length %d", n.List.Len())
-		}
-		mode.Fprintf(s, "sliceheader{%v,%v,%v}", n.Left, n.List.First(), n.List.Second())
-
-	case OCOMPLEX, OCOPY:
-		if n.Left != nil {
-			mode.Fprintf(s, "%#v(%v, %v)", n.Op, n.Left, n.Right)
-		} else {
-			mode.Fprintf(s, "%#v(%.v)", n.Op, n.List)
-		}
-
-	case OCONV,
-		OCONVIFACE,
-		OCONVNOP,
-		OBYTES2STR,
-		ORUNES2STR,
-		OSTR2BYTES,
-		OSTR2RUNES,
-		ORUNESTR:
-		if n.Type == nil || n.Type.Sym == nil {
-			mode.Fprintf(s, "(%v)", n.Type)
-		} else {
-			mode.Fprintf(s, "%v", n.Type)
-		}
-		if n.Left != nil {
-			mode.Fprintf(s, "(%v)", n.Left)
-		} else {
-			mode.Fprintf(s, "(%.v)", n.List)
-		}
-
-	case OREAL,
-		OIMAG,
-		OAPPEND,
-		OCAP,
-		OCLOSE,
-		ODELETE,
-		OLEN,
-		OMAKE,
-		ONEW,
-		OPANIC,
-		ORECOVER,
-		OALIGNOF,
-		OOFFSETOF,
-		OSIZEOF,
-		OPRINT,
-		OPRINTN:
-		if n.Left != nil {
-			mode.Fprintf(s, "%#v(%v)", n.Op, n.Left)
-			return
-		}
-		if n.IsDDD() {
-			mode.Fprintf(s, "%#v(%.v...)", n.Op, n.List)
-			return
-		}
-		mode.Fprintf(s, "%#v(%.v)", n.Op, n.List)
-
-	case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG:
-		n.Left.exprfmt(s, nprec, mode)
-		if n.IsDDD() {
-			mode.Fprintf(s, "(%.v...)", n.List)
-			return
-		}
-		mode.Fprintf(s, "(%.v)", n.List)
-
-	case OMAKEMAP, OMAKECHAN, OMAKESLICE:
-		if n.List.Len() != 0 { // pre-typecheck
-			mode.Fprintf(s, "make(%v, %.v)", n.Type, n.List)
-			return
-		}
-		if n.Right != nil {
-			mode.Fprintf(s, "make(%v, %v, %v)", n.Type, n.Left, n.Right)
-			return
-		}
-		if n.Left != nil && (n.Op == OMAKESLICE || !n.Left.Type.IsUntyped()) {
-			mode.Fprintf(s, "make(%v, %v)", n.Type, n.Left)
-			return
-		}
-		mode.Fprintf(s, "make(%v)", n.Type)
-
-	case OMAKESLICECOPY:
-		mode.Fprintf(s, "makeslicecopy(%v, %v, %v)", n.Type, n.Left, n.Right)
-
-	case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
-		// Unary
-		mode.Fprintf(s, "%#v", n.Op)
-		if n.Left != nil && n.Left.Op == n.Op {
-			fmt.Fprint(s, " ")
-		}
-		n.Left.exprfmt(s, nprec+1, mode)
-
-		// Binary
-	case OADD,
-		OAND,
-		OANDAND,
-		OANDNOT,
-		ODIV,
-		OEQ,
-		OGE,
-		OGT,
-		OLE,
-		OLT,
-		OLSH,
-		OMOD,
-		OMUL,
-		ONE,
-		OOR,
-		OOROR,
-		ORSH,
-		OSEND,
-		OSUB,
-		OXOR:
-		n.Left.exprfmt(s, nprec, mode)
-		mode.Fprintf(s, " %#v ", n.Op)
-		n.Right.exprfmt(s, nprec+1, mode)
-
-	case OADDSTR:
-		for i, n1 := range n.List.Slice() {
-			if i != 0 {
-				fmt.Fprint(s, " + ")
-			}
-			n1.exprfmt(s, nprec, mode)
-		}
-	case ODDD:
-		mode.Fprintf(s, "...")
-	default:
-		mode.Fprintf(s, "<node %v>", n.Op)
-	}
-}
-
-func (n *Node) nodefmt(s fmt.State, flag FmtFlag, mode fmtMode) {
-	t := n.Type
-
-	// We almost always want the original.
-	// TODO(gri) Why the special case for OLITERAL?
-	if n.Op != OLITERAL && n.Orig != nil {
-		n = n.Orig
-	}
-
-	if flag&FmtLong != 0 && t != nil {
-		if t.Etype == TNIL {
-			fmt.Fprint(s, "nil")
-		} else if n.Op == ONAME && n.Name.AutoTemp() {
-			mode.Fprintf(s, "%v value", t)
-		} else {
-			mode.Fprintf(s, "%v (type %v)", n, t)
-		}
-		return
-	}
-
-	// TODO inlining produces expressions with ninits. we can't print these yet.
-
-	if opprec[n.Op] < 0 {
-		n.stmtfmt(s, mode)
-		return
-	}
-
-	n.exprfmt(s, 0, mode)
-}
-
-func (n *Node) nodedump(s fmt.State, flag FmtFlag, mode fmtMode) {
-	recur := flag&FmtShort == 0
-
-	if recur {
-		indent(s)
-		if dumpdepth > 40 {
-			fmt.Fprint(s, "...")
-			return
-		}
-
-		if n.Ninit.Len() != 0 {
-			mode.Fprintf(s, "%v-init%v", n.Op, n.Ninit)
-			indent(s)
-		}
-	}
-
-	switch n.Op {
-	default:
-		mode.Fprintf(s, "%v%j", n.Op, n)
-
-	case OLITERAL:
-		mode.Fprintf(s, "%v-%v%j", n.Op, n.Val(), n)
-
-	case ONAME, ONONAME:
-		if n.Sym != nil {
-			mode.Fprintf(s, "%v-%v%j", n.Op, n.Sym, n)
-		} else {
-			mode.Fprintf(s, "%v%j", n.Op, n)
-		}
-		if recur && n.Type == nil && n.Name != nil && n.Name.Param != nil && n.Name.Param.Ntype != nil {
-			indent(s)
-			mode.Fprintf(s, "%v-ntype%v", n.Op, n.Name.Param.Ntype)
-		}
-
-	case OASOP:
-		mode.Fprintf(s, "%v-%v%j", n.Op, n.SubOp(), n)
-
-	case OTYPE:
-		mode.Fprintf(s, "%v %v%j type=%v", n.Op, n.Sym, n, n.Type)
-		if recur && n.Type == nil && n.Name != nil && n.Name.Param != nil && n.Name.Param.Ntype != nil {
-			indent(s)
-			mode.Fprintf(s, "%v-ntype%v", n.Op, n.Name.Param.Ntype)
-		}
-	}
-
-	if n.Op == OCLOSURE && n.Func.Closure != nil && n.Func.Closure.Func.Nname.Sym != nil {
-		mode.Fprintf(s, " fnName %v", n.Func.Closure.Func.Nname.Sym)
-	}
-	if n.Sym != nil && n.Op != ONAME {
-		mode.Fprintf(s, " %v", n.Sym)
-	}
-
-	if n.Type != nil {
-		mode.Fprintf(s, " %v", n.Type)
-	}
-
-	if recur {
-		if n.Left != nil {
-			mode.Fprintf(s, "%v", n.Left)
-		}
-		if n.Right != nil {
-			mode.Fprintf(s, "%v", n.Right)
-		}
-		if n.Func != nil && n.Func.Closure != nil && n.Func.Closure.Nbody.Len() != 0 {
-			indent(s)
-			// The function associated with a closure
-			mode.Fprintf(s, "%v-clofunc%v", n.Op, n.Func.Closure)
-		}
-		if n.Func != nil && n.Func.Dcl != nil && len(n.Func.Dcl) != 0 {
-			indent(s)
-			// The dcls for a func or closure
-			mode.Fprintf(s, "%v-dcl%v", n.Op, asNodes(n.Func.Dcl))
-		}
-		if n.List.Len() != 0 {
-			indent(s)
-			mode.Fprintf(s, "%v-list%v", n.Op, n.List)
-		}
-
-		if n.Rlist.Len() != 0 {
-			indent(s)
-			mode.Fprintf(s, "%v-rlist%v", n.Op, n.Rlist)
-		}
-
-		if n.Nbody.Len() != 0 {
-			indent(s)
-			mode.Fprintf(s, "%v-body%v", n.Op, n.Nbody)
-		}
-	}
-}
-
-// "%S" suppresses qualifying with package
-func symFormat(s *types.Sym, f fmt.State, verb rune, mode fmtMode) {
-	switch verb {
-	case 'v', 'S':
-		fmt.Fprint(f, sconv(s, fmtFlag(f, verb), mode))
-
-	default:
-		fmt.Fprintf(f, "%%!%c(*types.Sym=%p)", verb, s)
-	}
-}
-
-func smodeString(s *types.Sym, mode fmtMode) string { return sconv(s, 0, mode) }
-
-// See #16897 before changing the implementation of sconv.
-func sconv(s *types.Sym, flag FmtFlag, mode fmtMode) string {
-	if flag&FmtLong != 0 {
-		panic("linksymfmt")
-	}
-
-	if s == nil {
-		return "<S>"
-	}
-
-	if s.Name == "_" {
-		return "_"
-	}
-	buf := fmtBufferPool.Get().(*bytes.Buffer)
-	buf.Reset()
-	defer fmtBufferPool.Put(buf)
-
-	flag, mode = flag.update(mode)
-	symfmt(buf, s, flag, mode)
-	return types.InternString(buf.Bytes())
-}
-
-func sconv2(b *bytes.Buffer, s *types.Sym, flag FmtFlag, mode fmtMode) {
-	if flag&FmtLong != 0 {
-		panic("linksymfmt")
-	}
-	if s == nil {
-		b.WriteString("<S>")
-		return
-	}
-	if s.Name == "_" {
-		b.WriteString("_")
-		return
-	}
-
-	flag, mode = flag.update(mode)
-	symfmt(b, s, flag, mode)
-}
-
-func fldconv(b *bytes.Buffer, f *types.Field, flag FmtFlag, mode fmtMode, visited map[*types.Type]int, funarg types.Funarg) {
-	if f == nil {
-		b.WriteString("<T>")
-		return
-	}
-	flag, mode = flag.update(mode)
-	if mode == FTypeIdName {
-		flag |= FmtUnsigned
-	}
-
-	var name string
-	if flag&FmtShort == 0 {
-		s := f.Sym
-
-		// Take the name from the original.
-		if mode == FErr {
-			s = origSym(s)
-		}
-
-		if s != nil && f.Embedded == 0 {
-			if funarg != types.FunargNone {
-				name = asNode(f.Nname).modeString(mode)
-			} else if flag&FmtLong != 0 {
-				name = mode.Sprintf("%0S", s)
-				if !types.IsExported(name) && flag&FmtUnsigned == 0 {
-					name = smodeString(s, mode) // qualify non-exported names (used on structs, not on funarg)
-				}
-			} else {
-				name = smodeString(s, mode)
-			}
-		}
-	}
-
-	if name != "" {
-		b.WriteString(name)
-		b.WriteString(" ")
-	}
-
-	if f.IsDDD() {
-		var et *types.Type
-		if f.Type != nil {
-			et = f.Type.Elem()
-		}
-		b.WriteString("...")
-		tconv2(b, et, 0, mode, visited)
-	} else {
-		tconv2(b, f.Type, 0, mode, visited)
-	}
-
-	if flag&FmtShort == 0 && funarg == types.FunargNone && f.Note != "" {
-		b.WriteString(" ")
-		b.WriteString(strconv.Quote(f.Note))
-	}
-}
-
-// "%L"  print definition, not name
-// "%S"  omit 'func' and receiver from function types, short type names
-func typeFormat(t *types.Type, s fmt.State, verb rune, mode fmtMode) {
-	switch verb {
-	case 'v', 'S', 'L':
-		fmt.Fprint(s, tconv(t, fmtFlag(s, verb), mode))
-	default:
-		fmt.Fprintf(s, "%%!%c(*Type=%p)", verb, t)
-	}
-}
-
-func (n *Node) String() string                 { return fmt.Sprint(n) }
-func (n *Node) modeString(mode fmtMode) string { return mode.Sprint(n) }
-
-// "%L"  suffix with "(type %T)" where possible
-// "%+S" in debug mode, don't recurse, no multiline output
-func (n *Node) nconv(s fmt.State, flag FmtFlag, mode fmtMode) {
-	if n == nil {
-		fmt.Fprint(s, "<N>")
-		return
-	}
-
-	flag, mode = flag.update(mode)
-
-	switch mode {
-	case FErr:
-		n.nodefmt(s, flag, mode)
-
-	case FDbg:
-		dumpdepth++
-		n.nodedump(s, flag, mode)
-		dumpdepth--
-
-	default:
-		Fatalf("unhandled %%N mode: %d", mode)
-	}
-}
-
-func (l Nodes) format(s fmt.State, verb rune, mode fmtMode) {
-	switch verb {
-	case 'v':
-		l.hconv(s, fmtFlag(s, verb), mode)
-
-	default:
-		fmt.Fprintf(s, "%%!%c(Nodes)", verb)
-	}
-}
-
-func (n Nodes) String() string {
-	return fmt.Sprint(n)
-}
-
-// Flags: all those of %N plus '.': separate with comma's instead of semicolons.
-func (l Nodes) hconv(s fmt.State, flag FmtFlag, mode fmtMode) {
-	if l.Len() == 0 && mode == FDbg {
-		fmt.Fprint(s, "<nil>")
-		return
-	}
-
-	flag, mode = flag.update(mode)
-	sep := "; "
-	if mode == FDbg {
-		sep = "\n"
-	} else if flag&FmtComma != 0 {
-		sep = ", "
-	}
-
-	for i, n := range l.Slice() {
-		fmt.Fprint(s, n.modeString(mode))
-		if i+1 < l.Len() {
-			fmt.Fprint(s, sep)
-		}
-	}
-}
-
-func dumplist(s string, l Nodes) {
-	fmt.Printf("%s%+v\n", s, l)
-}
-
-func fdumplist(w io.Writer, s string, l Nodes) {
-	fmt.Fprintf(w, "%s%+v\n", s, l)
-}
-
-func Dump(s string, n *Node) {
-	fmt.Printf("%s [%p]%+v\n", s, n, n)
-}
-
-// TODO(gri) make variable local somehow
-var dumpdepth int
-
-// indent prints indentation to s.
-func indent(s fmt.State) {
-	fmt.Fprint(s, "\n")
-	for i := 0; i < dumpdepth; i++ {
-		fmt.Fprint(s, ".   ")
-	}
-}
-
-func ellipsisIf(b bool) string {
-	if b {
-		return "..."
-	}
-	return ""
-}
diff --git a/src/cmd/compile/internal/gc/gen.go b/src/cmd/compile/internal/gc/gen.go
deleted file mode 100644
index 929653e..0000000
--- a/src/cmd/compile/internal/gc/gen.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
-	"cmd/compile/internal/types"
-	"cmd/internal/obj"
-	"cmd/internal/src"
-	"strconv"
-)
-
-// sysfunc looks up Go function name in package runtime. This function
-// must follow the internal calling convention.
-func sysfunc(name string) *obj.LSym {
-	s := Runtimepkg.Lookup(name)
-	s.SetFunc(true)
-	return s.Linksym()
-}
-
-// sysvar looks up a variable (or assembly function) name in package
-// runtime. If this is a function, it may have a special calling
-// convention.
-func sysvar(name string) *obj.LSym {
-	return Runtimepkg.Lookup(name).Linksym()
-}
-
-// isParamStackCopy reports whether this is the on-stack copy of a
-// function parameter that moved to the heap.
-func (n *Node) isParamStackCopy() bool {
-	return n.Op == ONAME && (n.Class() == PPARAM || n.Class() == PPARAMOUT) && n.Name.Param.Heapaddr != nil
-}
-
-// isParamHeapCopy reports whether this is the on-heap copy of
-// a function parameter that moved to the heap.
-func (n *Node) isParamHeapCopy() bool {
-	return n.Op == ONAME && n.Class() == PAUTOHEAP && n.Name.Param.Stackcopy != nil
-}
-
-// autotmpname returns the name for an autotmp variable numbered n.
-func autotmpname(n int) string {
-	// Give each tmp a different name so that they can be registerized.
-	// Add a preceding . to avoid clashing with legal names.
-	const prefix = ".autotmp_"
-	// Start with a buffer big enough to hold a large n.
-	b := []byte(prefix + "      ")[:len(prefix)]
-	b = strconv.AppendInt(b, int64(n), 10)
-	return types.InternString(b)
-}
-
-// make a new Node off the books
-func tempAt(pos src.XPos, curfn *Node, t *types.Type) *Node {
-	if curfn == nil {
-		Fatalf("no curfn for tempAt")
-	}
-	if curfn.Func.Closure != nil && curfn.Op == OCLOSURE {
-		Dump("tempAt", curfn)
-		Fatalf("adding tempAt to wrong closure function")
-	}
-	if t == nil {
-		Fatalf("tempAt called with nil type")
-	}
-
-	s := &types.Sym{
-		Name: autotmpname(len(curfn.Func.Dcl)),
-		Pkg:  localpkg,
-	}
-	n := newnamel(pos, s)
-	s.Def = asTypesNode(n)
-	n.Type = t
-	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)
-
-	return n.Orig
-}
-
-func temp(t *types.Type) *Node {
-	return tempAt(lineno, Curfn, t)
-}
diff --git a/src/cmd/compile/internal/gc/global_test.go b/src/cmd/compile/internal/gc/global_test.go
deleted file mode 100644
index edad6d0..0000000
--- a/src/cmd/compile/internal/gc/global_test.go
+++ /dev/null
@@ -1,116 +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 gc
-
-import (
-	"bytes"
-	"internal/testenv"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"strings"
-	"testing"
-)
-
-// Make sure "hello world" does not link in all the
-// fmt.scanf routines. See issue 6853.
-func TestScanfRemoval(t *testing.T) {
-	testenv.MustHaveGoBuild(t)
-	t.Parallel()
-
-	// Make a directory to work in.
-	dir, err := ioutil.TempDir("", "issue6853a-")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
-
-	// Create source.
-	src := filepath.Join(dir, "test.go")
-	f, err := os.Create(src)
-	if err != nil {
-		t.Fatalf("could not create source file: %v", err)
-	}
-	f.Write([]byte(`
-package main
-import "fmt"
-func main() {
-	fmt.Println("hello world")
-}
-`))
-	f.Close()
-
-	// Name of destination.
-	dst := filepath.Join(dir, "test")
-
-	// Compile source.
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dst, src)
-	out, err := cmd.CombinedOutput()
-	if err != nil {
-		t.Fatalf("could not build target: %v", err)
-	}
-
-	// Check destination to see if scanf code was included.
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "nm", dst)
-	out, err = cmd.CombinedOutput()
-	if err != nil {
-		t.Fatalf("could not read target: %v", err)
-	}
-	if bytes.Contains(out, []byte("scanInt")) {
-		t.Fatalf("scanf code not removed from helloworld")
-	}
-}
-
-// Make sure -S prints assembly code. See issue 14515.
-func TestDashS(t *testing.T) {
-	testenv.MustHaveGoBuild(t)
-	t.Parallel()
-
-	// Make a directory to work in.
-	dir, err := ioutil.TempDir("", "issue14515-")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
-
-	// Create source.
-	src := filepath.Join(dir, "test.go")
-	f, err := os.Create(src)
-	if err != nil {
-		t.Fatalf("could not create source file: %v", err)
-	}
-	f.Write([]byte(`
-package main
-import "fmt"
-func main() {
-	fmt.Println("hello world")
-}
-`))
-	f.Close()
-
-	// Compile source.
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags", "-S", "-o", filepath.Join(dir, "test"), src)
-	out, err := cmd.CombinedOutput()
-	if err != nil {
-		t.Fatalf("could not build target: %v", err)
-	}
-
-	patterns := []string{
-		// It is hard to look for actual instructions in an
-		// arch-independent way. So we'll just look for
-		// pseudo-ops that are arch-independent.
-		"\tTEXT\t",
-		"\tFUNCDATA\t",
-		"\tPCDATA\t",
-	}
-	outstr := string(out)
-	for _, p := range patterns {
-		if !strings.Contains(outstr, p) {
-			println(outstr)
-			panic("can't find pattern " + p)
-		}
-	}
-}
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
deleted file mode 100644
index 274930b..0000000
--- a/src/cmd/compile/internal/gc/go.go
+++ /dev/null
@@ -1,349 +0,0 @@
-// Copyright 2009 The Go Authors. 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/compile/internal/ssa"
-	"cmd/compile/internal/types"
-	"cmd/internal/obj"
-	"cmd/internal/src"
-	"sync"
-)
-
-const (
-	BADWIDTH = types.BADWIDTH
-)
-
-var (
-	// maximum size variable which we will allocate on the stack.
-	// This limit is for explicit variable declarations like "var x T" or "x := ...".
-	// Note: the flag smallframes can update this value.
-	maxStackVarSize = int64(10 * 1024 * 1024)
-
-	// maximum size of implicit variables that we will allocate on the stack.
-	//   p := new(T)          allocating T on the stack
-	//   p := &T{}            allocating T on the stack
-	//   s := make([]T, n)    allocating [n]T on the stack
-	//   s := []byte("...")   allocating [n]byte on the stack
-	// Note: the flag smallframes can update this value.
-	maxImplicitStackVarSize = int64(64 * 1024)
-
-	// smallArrayBytes is the maximum size of an array which is considered small.
-	// Small arrays will be initialized directly with a sequence of constant stores.
-	// Large arrays will be initialized by copying from a static temp.
-	// 256 bytes was chosen to minimize generated code + statictmp size.
-	smallArrayBytes = int64(256)
-)
-
-// isRuntimePkg reports whether p is package runtime.
-func isRuntimePkg(p *types.Pkg) bool {
-	if compiling_runtime && p == localpkg {
-		return true
-	}
-	return p.Path == "runtime"
-}
-
-// isReflectPkg reports whether p is package reflect.
-func isReflectPkg(p *types.Pkg) bool {
-	if p == localpkg {
-		return myimportpath == "reflect"
-	}
-	return p.Path == "reflect"
-}
-
-// The Class of a variable/function describes the "storage class"
-// of a variable or function. During parsing, storage classes are
-// called declaration contexts.
-type Class uint8
-
-//go:generate stringer -type=Class
-const (
-	Pxxx      Class = iota // no class; used during ssa conversion to indicate pseudo-variables
-	PEXTERN                // global variables
-	PAUTO                  // local variables
-	PAUTOHEAP              // local variables or parameters moved to heap
-	PPARAM                 // input arguments
-	PPARAMOUT              // output results
-	PFUNC                  // global functions
-
-	// Careful: Class is stored in three bits in Node.flags.
-	_ = uint((1 << 3) - iota) // static assert for iota <= (1 << 3)
-)
-
-// Slices in the runtime are represented by three components:
-//
-// type slice struct {
-// 	ptr unsafe.Pointer
-// 	len int
-// 	cap int
-// }
-//
-// Strings in the runtime are represented by two components:
-//
-// type string struct {
-// 	ptr unsafe.Pointer
-// 	len int
-// }
-//
-// These variables are the offsets of fields and sizes of these structs.
-var (
-	slicePtrOffset int64
-	sliceLenOffset int64
-	sliceCapOffset int64
-
-	sizeofSlice  int64
-	sizeofString int64
-)
-
-var pragcgobuf [][]string
-
-var outfile string
-var linkobj string
-
-// nerrors is the number of compiler errors reported
-// since the last call to saveerrors.
-var nerrors int
-
-// nsavederrors is the total number of compiler errors
-// reported before the last call to saveerrors.
-var nsavederrors int
-
-var nsyntaxerrors int
-
-var decldepth int32
-
-var nolocalimports bool
-
-// gc debug flags
-type DebugFlags struct {
-	P, B, C, E,
-	K, L, N, S,
-	W, e, h, j,
-	l, m, r, w int
-}
-
-var Debug DebugFlags
-
-var debugstr string
-
-var Debug_checknil int
-var Debug_typeassert int
-
-var localpkg *types.Pkg // package being compiled
-
-var inimport bool // set during import
-
-var itabpkg *types.Pkg // fake pkg for itab entries
-
-var itablinkpkg *types.Pkg // fake package for runtime itab entries
-
-var Runtimepkg *types.Pkg // fake package runtime
-
-var racepkg *types.Pkg // package runtime/race
-
-var msanpkg *types.Pkg // package runtime/msan
-
-var unsafepkg *types.Pkg // package unsafe
-
-var trackpkg *types.Pkg // fake package for field tracking
-
-var mappkg *types.Pkg // fake package for map zero value
-
-var gopkg *types.Pkg // pseudo-package for method symbols on anonymous receiver types
-
-var zerosize int64
-
-var myimportpath string
-
-var localimport string
-
-var asmhdr string
-
-var simtype [NTYPE]types.EType
-
-var (
-	isInt     [NTYPE]bool
-	isFloat   [NTYPE]bool
-	isComplex [NTYPE]bool
-	issimple  [NTYPE]bool
-)
-
-var (
-	okforeq    [NTYPE]bool
-	okforadd   [NTYPE]bool
-	okforand   [NTYPE]bool
-	okfornone  [NTYPE]bool
-	okforcmp   [NTYPE]bool
-	okforbool  [NTYPE]bool
-	okforcap   [NTYPE]bool
-	okforlen   [NTYPE]bool
-	okforarith [NTYPE]bool
-	okforconst [NTYPE]bool
-)
-
-var (
-	okfor [OEND][]bool
-	iscmp [OEND]bool
-)
-
-var minintval [NTYPE]*Mpint
-
-var maxintval [NTYPE]*Mpint
-
-var minfltval [NTYPE]*Mpflt
-
-var maxfltval [NTYPE]*Mpflt
-
-var xtop []*Node
-
-var exportlist []*Node
-
-var importlist []*Node // imported functions and methods with inlinable bodies
-
-var (
-	funcsymsmu sync.Mutex // protects funcsyms and associated package lookups (see func funcsym)
-	funcsyms   []*types.Sym
-)
-
-var dclcontext Class // PEXTERN/PAUTO
-
-var Curfn *Node
-
-var Widthptr int
-
-var Widthreg int
-
-var nblank *Node
-
-var typecheckok bool
-
-var compiling_runtime bool
-
-// Compiling the standard library
-var compiling_std bool
-
-var use_writebarrier bool
-
-var pure_go bool
-
-var flag_installsuffix string
-
-var flag_race bool
-
-var flag_msan bool
-
-var flagDWARF bool
-
-// Whether we are adding any sort of code instrumentation, such as
-// when the race detector is enabled.
-var instrumenting bool
-
-// 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
-
-var writearchive bool
-
-var nodfp *Node
-
-var disable_checknil int
-
-var autogeneratedPos src.XPos
-
-// interface to back end
-
-type Arch struct {
-	LinkArch *obj.LinkArch
-
-	REGSP     int
-	MAXWIDTH  int64
-	SoftFloat bool
-
-	PadFrame func(int64) int64
-
-	// ZeroRange zeroes a range of memory on stack. It is only inserted
-	// at function entry, and it is ok to clobber registers.
-	ZeroRange func(*Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog
-
-	Ginsnop      func(*Progs) *obj.Prog
-	Ginsnopdefer func(*Progs) *obj.Prog // special ginsnop for deferreturn
-
-	// SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
-	SSAMarkMoves func(*SSAGenState, *ssa.Block)
-
-	// SSAGenValue emits Prog(s) for the Value.
-	SSAGenValue func(*SSAGenState, *ssa.Value)
-
-	// SSAGenBlock emits end-of-block Progs. SSAGenValue should be called
-	// for all values in the block before SSAGenBlock.
-	SSAGenBlock func(s *SSAGenState, b, next *ssa.Block)
-}
-
-var thearch Arch
-
-var (
-	staticuint64s,
-	zerobase *Node
-
-	assertE2I,
-	assertE2I2,
-	assertI2I,
-	assertI2I2,
-	deferproc,
-	deferprocStack,
-	Deferreturn,
-	Duffcopy,
-	Duffzero,
-	gcWriteBarrier,
-	goschedguarded,
-	growslice,
-	msanread,
-	msanwrite,
-	msanmove,
-	newobject,
-	newproc,
-	panicdivide,
-	panicshift,
-	panicdottypeE,
-	panicdottypeI,
-	panicnildottype,
-	panicoverflow,
-	raceread,
-	racereadrange,
-	racewrite,
-	racewriterange,
-	x86HasPOPCNT,
-	x86HasSSE41,
-	x86HasFMA,
-	armHasVFPv4,
-	arm64HasATOMICS,
-	typedmemclr,
-	typedmemmove,
-	Udiv,
-	writeBarrier,
-	zerobaseSym *obj.LSym
-
-	BoundsCheckFunc [ssa.BoundsKindCount]*obj.LSym
-	ExtendCheckFunc [ssa.BoundsKindCount]*obj.LSym
-
-	// Wasm
-	WasmMove,
-	WasmZero,
-	WasmDiv,
-	WasmTruncS,
-	WasmTruncU,
-	SigPanic *obj.LSym
-)
-
-// GCWriteBarrierReg maps from registers to gcWriteBarrier implementation LSyms.
-var GCWriteBarrierReg map[int16]*obj.LSym
diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go
deleted file mode 100644
index d599a38..0000000
--- a/src/cmd/compile/internal/gc/gsubr.go
+++ /dev/null
@@ -1,333 +0,0 @@
-// Derived from Inferno utils/6c/txt.c
-// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6c/txt.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 gc
-
-import (
-	"cmd/compile/internal/ssa"
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"cmd/internal/src"
-)
-
-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 {
-	Text      *obj.Prog  // ATEXT Prog for this function
-	next      *obj.Prog  // next Prog
-	pc        int64      // virtual PC; count of Progs
-	pos       src.XPos   // position to use for new Progs
-	curfn     *Node      // fn these Progs are for
-	progcache []obj.Prog // local progcache
-	cacheidx  int        // first free element of progcache
-
-	nextLive LivenessIndex // liveness index for the next Prog
-	prevLive LivenessIndex // last emitted liveness index
-}
-
-// newProgs returns a new Progs for fn.
-// worker indicates which of the backend workers will use the Progs.
-func newProgs(fn *Node, worker int) *Progs {
-	pp := new(Progs)
-	if Ctxt.CanReuseProgs() {
-		sz := len(sharedProgArray) / nBackendWorkers
-		pp.progcache = sharedProgArray[sz*worker : sz*(worker+1)]
-	}
-	pp.curfn = fn
-
-	// prime the pump
-	pp.next = pp.NewProg()
-	pp.clearp(pp.next)
-
-	pp.pos = fn.Pos
-	pp.settext(fn)
-	// PCDATA tables implicitly start with index -1.
-	pp.prevLive = LivenessIndex{-1, false}
-	pp.nextLive = pp.prevLive
-	return pp
-}
-
-func (pp *Progs) NewProg() *obj.Prog {
-	var p *obj.Prog
-	if pp.cacheidx < len(pp.progcache) {
-		p = &pp.progcache[pp.cacheidx]
-		pp.cacheidx++
-	} else {
-		p = new(obj.Prog)
-	}
-	p.Ctxt = Ctxt
-	return p
-}
-
-// 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, myimportpath)
-}
-
-// Free clears pp and any associated resources.
-func (pp *Progs) Free() {
-	if Ctxt.CanReuseProgs() {
-		// Clear progs to enable GC and avoid abuse.
-		s := pp.progcache[:pp.cacheidx]
-		for i := range s {
-			s[i] = obj.Prog{}
-		}
-	}
-	// Clear pp to avoid abuse.
-	*pp = Progs{}
-}
-
-// Prog adds a Prog with instruction As to pp.
-func (pp *Progs) Prog(as obj.As) *obj.Prog {
-	if pp.nextLive.StackMapValid() && pp.nextLive.stackMapIndex != pp.prevLive.stackMapIndex {
-		// Emit stack map index change.
-		idx := pp.nextLive.stackMapIndex
-		pp.prevLive.stackMapIndex = idx
-		p := pp.Prog(obj.APCDATA)
-		Addrconst(&p.From, objabi.PCDATA_StackMapIndex)
-		Addrconst(&p.To, int64(idx))
-	}
-	if pp.nextLive.isUnsafePoint != pp.prevLive.isUnsafePoint {
-		// Emit unsafe-point marker.
-		pp.prevLive.isUnsafePoint = pp.nextLive.isUnsafePoint
-		p := pp.Prog(obj.APCDATA)
-		Addrconst(&p.From, objabi.PCDATA_UnsafePoint)
-		if pp.nextLive.isUnsafePoint {
-			Addrconst(&p.To, objabi.PCDATA_UnsafePointUnsafe)
-		} else {
-			Addrconst(&p.To, objabi.PCDATA_UnsafePointSafe)
-		}
-	}
-
-	p := pp.next
-	pp.next = pp.NewProg()
-	pp.clearp(pp.next)
-	p.Link = pp.next
-
-	if !pp.pos.IsKnown() && Debug.K != 0 {
-		Warn("prog: unknown position (line 0)")
-	}
-
-	p.As = as
-	p.Pos = pp.pos
-	if pp.pos.IsStmt() == src.PosIsStmt {
-		// Clear IsStmt for later Progs at this pos provided that as can be marked as a stmt
-		if ssa.LosesStmtMark(as) {
-			return p
-		}
-		pp.pos = pp.pos.WithNotStmt()
-	}
-	return p
-}
-
-func (pp *Progs) clearp(p *obj.Prog) {
-	obj.Nopout(p)
-	p.As = obj.AEND
-	p.Pc = pp.pc
-	pp.pc++
-}
-
-func (pp *Progs) Appendpp(p *obj.Prog, as obj.As, ftype obj.AddrType, freg int16, foffset int64, ttype obj.AddrType, treg int16, toffset int64) *obj.Prog {
-	q := pp.NewProg()
-	pp.clearp(q)
-	q.As = as
-	q.Pos = p.Pos
-	q.From.Type = ftype
-	q.From.Reg = freg
-	q.From.Offset = foffset
-	q.To.Type = ttype
-	q.To.Reg = treg
-	q.To.Offset = toffset
-	q.Link = p.Link
-	p.Link = q
-	return q
-}
-
-func (pp *Progs) settext(fn *Node) {
-	if pp.Text != nil {
-		Fatalf("Progs.settext called twice")
-	}
-	ptxt := pp.Prog(obj.ATEXT)
-	pp.Text = ptxt
-
-	fn.Func.lsym.Func().Text = ptxt
-	ptxt.From.Type = obj.TYPE_MEM
-	ptxt.From.Name = obj.NAME_EXTERN
-	ptxt.From.Sym = fn.Func.lsym
-}
-
-// initLSym defines f's obj.LSym and initializes it based on the
-// properties of f. This includes setting the symbol flags and ABI and
-// creating and initializing related DWARF symbols.
-//
-// initLSym must be called exactly once per function and must be
-// called for both functions with bodies and functions without bodies.
-func (f *Func) initLSym(hasBody bool) {
-	if f.lsym != nil {
-		Fatalf("Func.initLSym called twice")
-	}
-
-	if nam := f.Nname; !nam.isBlank() {
-		f.lsym = nam.Sym.Linksym()
-		if f.Pragma&Systemstack != 0 {
-			f.lsym.Set(obj.AttrCFunc, true)
-		}
-
-		var aliasABI obj.ABI
-		needABIAlias := false
-		defABI, hasDefABI := symabiDefs[f.lsym.Name]
-		if hasDefABI && defABI == obj.ABI0 {
-			// Symbol is defined as ABI0. Create an
-			// Internal -> ABI0 wrapper.
-			f.lsym.SetABI(obj.ABI0)
-			needABIAlias, aliasABI = true, obj.ABIInternal
-		} else {
-			// No ABI override. Check that the symbol is
-			// using the expected ABI.
-			want := obj.ABIInternal
-			if f.lsym.ABI() != want {
-				Fatalf("function symbol %s has the wrong ABI %v, expected %v", f.lsym.Name, f.lsym.ABI(), want)
-			}
-		}
-
-		isLinknameExported := nam.Sym.Linkname != "" && (hasBody || hasDefABI)
-		if abi, ok := symabiRefs[f.lsym.Name]; (ok && abi == obj.ABI0) || isLinknameExported {
-			// Either 1) this symbol is definitely
-			// referenced as ABI0 from this package; or 2)
-			// this symbol is defined in this package but
-			// given a linkname, indicating that it may be
-			// referenced from another package. Create an
-			// ABI0 -> Internal wrapper so it can be
-			// called as ABI0. In case 2, it's important
-			// that we know it's defined in this package
-			// since other packages may "pull" symbols
-			// using linkname and we don't want to create
-			// duplicate ABI wrappers.
-			if f.lsym.ABI() != obj.ABI0 {
-				needABIAlias, aliasABI = true, obj.ABI0
-			}
-		}
-
-		if needABIAlias {
-			// These LSyms have the same name as the
-			// native function, so we create them directly
-			// rather than looking them up. The uniqueness
-			// of f.lsym ensures uniqueness of asym.
-			asym := &obj.LSym{
-				Name: f.lsym.Name,
-				Type: objabi.SABIALIAS,
-				R:    []obj.Reloc{{Sym: f.lsym}}, // 0 size, so "informational"
-			}
-			asym.SetABI(aliasABI)
-			asym.Set(obj.AttrDuplicateOK, true)
-			Ctxt.ABIAliases = append(Ctxt.ABIAliases, asym)
-		}
-	}
-
-	if !hasBody {
-		// For body-less functions, we only create the LSym.
-		return
-	}
-
-	var flag int
-	if f.Dupok() {
-		flag |= obj.DUPOK
-	}
-	if f.Wrapper() {
-		flag |= obj.WRAPPER
-	}
-	if f.Needctxt() {
-		flag |= obj.NEEDCTXT
-	}
-	if f.Pragma&Nosplit != 0 {
-		flag |= obj.NOSPLIT
-	}
-	if f.ReflectMethod() {
-		flag |= obj.REFLECTMETHOD
-	}
-
-	// Clumsy but important.
-	// See test/recover.go for test cases and src/reflect/value.go
-	// for the actual functions being considered.
-	if myimportpath == "reflect" {
-		switch f.Nname.Sym.Name {
-		case "callReflect", "callMethod":
-			flag |= obj.WRAPPER
-		}
-	}
-
-	Ctxt.InitTextSym(f.lsym, flag)
-}
-
-func ggloblnod(nam *Node) {
-	s := nam.Sym.Linksym()
-	s.Gotype = ngotype(nam).Linksym()
-	flags := 0
-	if nam.Name.Readonly() {
-		flags = obj.RODATA
-	}
-	if nam.Type != nil && !nam.Type.HasPointers() {
-		flags |= obj.NOPTR
-	}
-	Ctxt.Globl(s, nam.Type.Width, flags)
-	if nam.Name.LibfuzzerExtraCounter() {
-		s.Type = objabi.SLIBFUZZER_EXTRA_COUNTER
-	}
-	if nam.Sym.Linkname != "" {
-		// Make sure linkname'd symbol is non-package. When a symbol is
-		// both imported and linkname'd, s.Pkg may not set to "_" in
-		// types.Sym.Linksym because LSym already exists. Set it here.
-		s.Pkg = "_"
-	}
-}
-
-func ggloblsym(s *obj.LSym, width int32, flags int16) {
-	if flags&obj.LOCAL != 0 {
-		s.Set(obj.AttrLocal, true)
-		flags &^= obj.LOCAL
-	}
-	Ctxt.Globl(s, int64(width), int(flags))
-}
-
-func Addrconst(a *obj.Addr, v int64) {
-	a.Sym = nil
-	a.Type = obj.TYPE_CONST
-	a.Offset = v
-}
-
-func Patch(p *obj.Prog, to *obj.Prog) {
-	if p.To.Type != obj.TYPE_BRANCH {
-		Fatalf("patch: not a branch")
-	}
-	p.To.SetTarget(to)
-	p.To.Offset = to.Pc
-}
diff --git a/src/cmd/compile/internal/gc/iexport.go b/src/cmd/compile/internal/gc/iexport.go
deleted file mode 100644
index 1f53d8c..0000000
--- a/src/cmd/compile/internal/gc/iexport.go
+++ /dev/null
@@ -1,1515 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Indexed package export.
-//
-// The indexed export data format is an evolution of the previous
-// binary export data format. Its chief contribution is introducing an
-// index table, which allows efficient random access of individual
-// declarations and inline function bodies. In turn, this allows
-// avoiding unnecessary work for compilation units that import large
-// packages.
-//
-//
-// The top-level data format is structured as:
-//
-//     Header struct {
-//         Tag        byte   // 'i'
-//         Version    uvarint
-//         StringSize uvarint
-//         DataSize   uvarint
-//     }
-//
-//     Strings [StringSize]byte
-//     Data    [DataSize]byte
-//
-//     MainIndex []struct{
-//         PkgPath   stringOff
-//         PkgName   stringOff
-//         PkgHeight uvarint
-//
-//         Decls []struct{
-//             Name   stringOff
-//             Offset declOff
-//         }
-//     }
-//
-//     Fingerprint [8]byte
-//
-// uvarint means a uint64 written out using uvarint encoding.
-//
-// []T means a uvarint followed by that many T objects. In other
-// words:
-//
-//     Len   uvarint
-//     Elems [Len]T
-//
-// stringOff means a uvarint that indicates an offset within the
-// Strings section. At that offset is another uvarint, followed by
-// that many bytes, which form the string value.
-//
-// declOff means a uvarint that indicates an offset within the Data
-// section where the associated declaration can be found.
-//
-//
-// There are five kinds of declarations, distinguished by their first
-// byte:
-//
-//     type Var struct {
-//         Tag  byte // 'V'
-//         Pos  Pos
-//         Type typeOff
-//     }
-//
-//     type Func struct {
-//         Tag       byte // 'F'
-//         Pos       Pos
-//         Signature Signature
-//     }
-//
-//     type Const struct {
-//         Tag   byte // 'C'
-//         Pos   Pos
-//         Value Value
-//     }
-//
-//     type Type struct {
-//         Tag        byte // 'T'
-//         Pos        Pos
-//         Underlying typeOff
-//
-//         Methods []struct{  // omitted if Underlying is an interface type
-//             Pos       Pos
-//             Name      stringOff
-//             Recv      Param
-//             Signature Signature
-//         }
-//     }
-//
-//     type Alias struct {
-//         Tag  byte // 'A'
-//         Pos  Pos
-//         Type typeOff
-//     }
-//
-//
-// typeOff means a uvarint that either indicates a predeclared type,
-// or an offset into the Data section. If the uvarint is less than
-// predeclReserved, then it indicates the index into the predeclared
-// types list (see predeclared in bexport.go for order). Otherwise,
-// subtracting predeclReserved yields the offset of a type descriptor.
-//
-// Value means a type and type-specific value. See
-// (*exportWriter).value for details.
-//
-//
-// There are nine kinds of type descriptors, distinguished by an itag:
-//
-//     type DefinedType struct {
-//         Tag     itag // definedType
-//         Name    stringOff
-//         PkgPath stringOff
-//     }
-//
-//     type PointerType struct {
-//         Tag  itag // pointerType
-//         Elem typeOff
-//     }
-//
-//     type SliceType struct {
-//         Tag  itag // sliceType
-//         Elem typeOff
-//     }
-//
-//     type ArrayType struct {
-//         Tag  itag // arrayType
-//         Len  uint64
-//         Elem typeOff
-//     }
-//
-//     type ChanType struct {
-//         Tag  itag   // chanType
-//         Dir  uint64 // 1 RecvOnly; 2 SendOnly; 3 SendRecv
-//         Elem typeOff
-//     }
-//
-//     type MapType struct {
-//         Tag  itag // mapType
-//         Key  typeOff
-//         Elem typeOff
-//     }
-//
-//     type FuncType struct {
-//         Tag       itag // signatureType
-//         PkgPath   stringOff
-//         Signature Signature
-//     }
-//
-//     type StructType struct {
-//         Tag     itag // structType
-//         PkgPath stringOff
-//         Fields []struct {
-//             Pos      Pos
-//             Name     stringOff
-//             Type     typeOff
-//             Embedded bool
-//             Note     stringOff
-//         }
-//     }
-//
-//     type InterfaceType struct {
-//         Tag     itag // interfaceType
-//         PkgPath stringOff
-//         Embeddeds []struct {
-//             Pos  Pos
-//             Type typeOff
-//         }
-//         Methods []struct {
-//             Pos       Pos
-//             Name      stringOff
-//             Signature Signature
-//         }
-//     }
-//
-//
-//     type Signature struct {
-//         Params   []Param
-//         Results  []Param
-//         Variadic bool  // omitted if Results is empty
-//     }
-//
-//     type Param struct {
-//         Pos  Pos
-//         Name stringOff
-//         Type typOff
-//     }
-//
-//
-// Pos encodes a file:line:column triple, incorporating a simple delta
-// encoding scheme within a data object. See exportWriter.pos for
-// details.
-//
-//
-// Compiler-specific details.
-//
-// cmd/compile writes out a second index for inline bodies and also
-// appends additional compiler-specific details after declarations.
-// Third-party tools are not expected to depend on these details and
-// they're expected to change much more rapidly, so they're omitted
-// here. See exportWriter's varExt/funcExt/etc methods for details.
-
-package gc
-
-import (
-	"bufio"
-	"bytes"
-	"cmd/compile/internal/types"
-	"cmd/internal/goobj"
-	"cmd/internal/src"
-	"crypto/md5"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"math/big"
-	"sort"
-	"strings"
-)
-
-// Current indexed export format version. Increase with each format change.
-// 1: added column details to Pos
-// 0: Go1.11 encoding
-const iexportVersion = 1
-
-// predeclReserved is the number of type offsets reserved for types
-// implicitly declared in the universe block.
-const predeclReserved = 32
-
-// An itag distinguishes the kind of type that was written into the
-// indexed export format.
-type itag uint64
-
-const (
-	// Types
-	definedType itag = iota
-	pointerType
-	sliceType
-	arrayType
-	chanType
-	mapType
-	signatureType
-	structType
-	interfaceType
-)
-
-func iexport(out *bufio.Writer) {
-	// Mark inline bodies that are reachable through exported types.
-	// (Phase 0 of bexport.go.)
-	{
-		// TODO(mdempsky): Separate from bexport logic.
-		p := &exporter{marked: make(map[*types.Type]bool)}
-		for _, n := range exportlist {
-			sym := n.Sym
-			p.markType(asNode(sym.Def).Type)
-		}
-	}
-
-	p := iexporter{
-		allPkgs:     map[*types.Pkg]bool{},
-		stringIndex: map[string]uint64{},
-		declIndex:   map[*Node]uint64{},
-		inlineIndex: map[*Node]uint64{},
-		typIndex:    map[*types.Type]uint64{},
-	}
-
-	for i, pt := range predeclared() {
-		p.typIndex[pt] = uint64(i)
-	}
-	if len(p.typIndex) > predeclReserved {
-		Fatalf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)
-	}
-
-	// Initialize work queue with exported declarations.
-	for _, n := range exportlist {
-		p.pushDecl(n)
-	}
-
-	// Loop until no more work. We use a queue because while
-	// writing out inline bodies, we may discover additional
-	// declarations that are needed.
-	for !p.declTodo.empty() {
-		p.doDecl(p.declTodo.popLeft())
-	}
-
-	// Append indices to data0 section.
-	dataLen := uint64(p.data0.Len())
-	w := p.newWriter()
-	w.writeIndex(p.declIndex, true)
-	w.writeIndex(p.inlineIndex, false)
-	w.flush()
-
-	// Assemble header.
-	var hdr intWriter
-	hdr.WriteByte('i')
-	hdr.uint64(iexportVersion)
-	hdr.uint64(uint64(p.strings.Len()))
-	hdr.uint64(dataLen)
-
-	// Flush output.
-	h := md5.New()
-	wr := io.MultiWriter(out, h)
-	io.Copy(wr, &hdr)
-	io.Copy(wr, &p.strings)
-	io.Copy(wr, &p.data0)
-
-	// Add fingerprint (used by linker object file).
-	// Attach this to the end, so tools (e.g. gcimporter) don't care.
-	copy(Ctxt.Fingerprint[:], h.Sum(nil)[:])
-	out.Write(Ctxt.Fingerprint[:])
-}
-
-// writeIndex writes out an object index. mainIndex indicates whether
-// we're writing out the main index, which is also read by
-// non-compiler tools and includes a complete package description
-// (i.e., name and height).
-func (w *exportWriter) writeIndex(index map[*Node]uint64, mainIndex bool) {
-	// Build a map from packages to objects from that package.
-	pkgObjs := map[*types.Pkg][]*Node{}
-
-	// For the main index, make sure to include every package that
-	// we reference, even if we're not exporting (or reexporting)
-	// any symbols from it.
-	if mainIndex {
-		pkgObjs[localpkg] = nil
-		for pkg := range w.p.allPkgs {
-			pkgObjs[pkg] = nil
-		}
-	}
-
-	for n := range index {
-		pkgObjs[n.Sym.Pkg] = append(pkgObjs[n.Sym.Pkg], n)
-	}
-
-	var pkgs []*types.Pkg
-	for pkg, objs := range pkgObjs {
-		pkgs = append(pkgs, pkg)
-
-		sort.Slice(objs, func(i, j int) bool {
-			return objs[i].Sym.Name < objs[j].Sym.Name
-		})
-	}
-
-	sort.Slice(pkgs, func(i, j int) bool {
-		return pkgs[i].Path < pkgs[j].Path
-	})
-
-	w.uint64(uint64(len(pkgs)))
-	for _, pkg := range pkgs {
-		w.string(pkg.Path)
-		if mainIndex {
-			w.string(pkg.Name)
-			w.uint64(uint64(pkg.Height))
-		}
-
-		objs := pkgObjs[pkg]
-		w.uint64(uint64(len(objs)))
-		for _, n := range objs {
-			w.string(n.Sym.Name)
-			w.uint64(index[n])
-		}
-	}
-}
-
-type iexporter struct {
-	// allPkgs tracks all packages that have been referenced by
-	// the export data, so we can ensure to include them in the
-	// main index.
-	allPkgs map[*types.Pkg]bool
-
-	declTodo nodeQueue
-
-	strings     intWriter
-	stringIndex map[string]uint64
-
-	data0       intWriter
-	declIndex   map[*Node]uint64
-	inlineIndex map[*Node]uint64
-	typIndex    map[*types.Type]uint64
-}
-
-// stringOff returns the offset of s within the string section.
-// If not already present, it's added to the end.
-func (p *iexporter) stringOff(s string) uint64 {
-	off, ok := p.stringIndex[s]
-	if !ok {
-		off = uint64(p.strings.Len())
-		p.stringIndex[s] = off
-
-		p.strings.uint64(uint64(len(s)))
-		p.strings.WriteString(s)
-	}
-	return off
-}
-
-// pushDecl adds n to the declaration work queue, if not already present.
-func (p *iexporter) pushDecl(n *Node) {
-	if n.Sym == nil || asNode(n.Sym.Def) != n && n.Op != OTYPE {
-		Fatalf("weird Sym: %v, %v", n, n.Sym)
-	}
-
-	// Don't export predeclared declarations.
-	if n.Sym.Pkg == builtinpkg || n.Sym.Pkg == unsafepkg {
-		return
-	}
-
-	if _, ok := p.declIndex[n]; ok {
-		return
-	}
-
-	p.declIndex[n] = ^uint64(0) // mark n present in work queue
-	p.declTodo.pushRight(n)
-}
-
-// exportWriter handles writing out individual data section chunks.
-type exportWriter struct {
-	p *iexporter
-
-	data       intWriter
-	currPkg    *types.Pkg
-	prevFile   string
-	prevLine   int64
-	prevColumn int64
-}
-
-func (p *iexporter) doDecl(n *Node) {
-	w := p.newWriter()
-	w.setPkg(n.Sym.Pkg, false)
-
-	switch n.Op {
-	case ONAME:
-		switch n.Class() {
-		case PEXTERN:
-			// Variable.
-			w.tag('V')
-			w.pos(n.Pos)
-			w.typ(n.Type)
-			w.varExt(n)
-
-		case PFUNC:
-			if n.IsMethod() {
-				Fatalf("unexpected method: %v", n)
-			}
-
-			// Function.
-			w.tag('F')
-			w.pos(n.Pos)
-			w.signature(n.Type)
-			w.funcExt(n)
-
-		default:
-			Fatalf("unexpected class: %v, %v", n, n.Class())
-		}
-
-	case OLITERAL:
-		// Constant.
-		n = typecheck(n, ctxExpr)
-		w.tag('C')
-		w.pos(n.Pos)
-		w.value(n.Type, n.Val())
-
-	case OTYPE:
-		if IsAlias(n.Sym) {
-			// Alias.
-			w.tag('A')
-			w.pos(n.Pos)
-			w.typ(n.Type)
-			break
-		}
-
-		// Defined type.
-		w.tag('T')
-		w.pos(n.Pos)
-
-		underlying := n.Type.Orig
-		if underlying == types.Errortype.Orig {
-			// For "type T error", use error as the
-			// underlying type instead of error's own
-			// underlying anonymous interface. This
-			// ensures consistency with how importers may
-			// declare error (e.g., go/types uses nil Pkg
-			// for predeclared objects).
-			underlying = types.Errortype
-		}
-		w.typ(underlying)
-
-		t := n.Type
-		if t.IsInterface() {
-			w.typeExt(t)
-			break
-		}
-
-		ms := t.Methods()
-		w.uint64(uint64(ms.Len()))
-		for _, m := range ms.Slice() {
-			w.pos(m.Pos)
-			w.selector(m.Sym)
-			w.param(m.Type.Recv())
-			w.signature(m.Type)
-		}
-
-		w.typeExt(t)
-		for _, m := range ms.Slice() {
-			w.methExt(m)
-		}
-
-	default:
-		Fatalf("unexpected node: %v", n)
-	}
-
-	p.declIndex[n] = w.flush()
-}
-
-func (w *exportWriter) tag(tag byte) {
-	w.data.WriteByte(tag)
-}
-
-func (p *iexporter) doInline(f *Node) {
-	w := p.newWriter()
-	w.setPkg(fnpkg(f), false)
-
-	w.stmtList(asNodes(f.Func.Inl.Body))
-
-	p.inlineIndex[f] = w.flush()
-}
-
-func (w *exportWriter) pos(pos src.XPos) {
-	p := Ctxt.PosTable.Pos(pos)
-	file := p.Base().AbsFilename()
-	line := int64(p.RelLine())
-	column := int64(p.RelCol())
-
-	// Encode position relative to the last position: column
-	// delta, then line delta, then file name. We reserve the
-	// bottom bit of the column and line deltas to encode whether
-	// the remaining fields are present.
-	//
-	// Note: Because data objects may be read out of order (or not
-	// at all), we can only apply delta encoding within a single
-	// object. This is handled implicitly by tracking prevFile,
-	// prevLine, and prevColumn as fields of exportWriter.
-
-	deltaColumn := (column - w.prevColumn) << 1
-	deltaLine := (line - w.prevLine) << 1
-
-	if file != w.prevFile {
-		deltaLine |= 1
-	}
-	if deltaLine != 0 {
-		deltaColumn |= 1
-	}
-
-	w.int64(deltaColumn)
-	if deltaColumn&1 != 0 {
-		w.int64(deltaLine)
-		if deltaLine&1 != 0 {
-			w.string(file)
-		}
-	}
-
-	w.prevFile = file
-	w.prevLine = line
-	w.prevColumn = column
-}
-
-func (w *exportWriter) pkg(pkg *types.Pkg) {
-	// Ensure any referenced packages are declared in the main index.
-	w.p.allPkgs[pkg] = true
-
-	w.string(pkg.Path)
-}
-
-func (w *exportWriter) qualifiedIdent(n *Node) {
-	// Ensure any referenced declarations are written out too.
-	w.p.pushDecl(n)
-
-	s := n.Sym
-	w.string(s.Name)
-	w.pkg(s.Pkg)
-}
-
-func (w *exportWriter) selector(s *types.Sym) {
-	if w.currPkg == nil {
-		Fatalf("missing currPkg")
-	}
-
-	// Method selectors are rewritten into method symbols (of the
-	// form T.M) during typechecking, but we want to write out
-	// just the bare method name.
-	name := s.Name
-	if i := strings.LastIndex(name, "."); i >= 0 {
-		name = name[i+1:]
-	} else {
-		pkg := w.currPkg
-		if types.IsExported(name) {
-			pkg = localpkg
-		}
-		if s.Pkg != pkg {
-			Fatalf("package mismatch in selector: %v in package %q, but want %q", s, s.Pkg.Path, pkg.Path)
-		}
-	}
-
-	w.string(name)
-}
-
-func (w *exportWriter) typ(t *types.Type) {
-	w.data.uint64(w.p.typOff(t))
-}
-
-func (p *iexporter) newWriter() *exportWriter {
-	return &exportWriter{p: p}
-}
-
-func (w *exportWriter) flush() uint64 {
-	off := uint64(w.p.data0.Len())
-	io.Copy(&w.p.data0, &w.data)
-	return off
-}
-
-func (p *iexporter) typOff(t *types.Type) uint64 {
-	off, ok := p.typIndex[t]
-	if !ok {
-		w := p.newWriter()
-		w.doTyp(t)
-		off = predeclReserved + w.flush()
-		p.typIndex[t] = off
-	}
-	return off
-}
-
-func (w *exportWriter) startType(k itag) {
-	w.data.uint64(uint64(k))
-}
-
-func (w *exportWriter) doTyp(t *types.Type) {
-	if t.Sym != nil {
-		if t.Sym.Pkg == builtinpkg || t.Sym.Pkg == unsafepkg {
-			Fatalf("builtin type missing from typIndex: %v", t)
-		}
-
-		w.startType(definedType)
-		w.qualifiedIdent(typenod(t))
-		return
-	}
-
-	switch t.Etype {
-	case TPTR:
-		w.startType(pointerType)
-		w.typ(t.Elem())
-
-	case TSLICE:
-		w.startType(sliceType)
-		w.typ(t.Elem())
-
-	case TARRAY:
-		w.startType(arrayType)
-		w.uint64(uint64(t.NumElem()))
-		w.typ(t.Elem())
-
-	case TCHAN:
-		w.startType(chanType)
-		w.uint64(uint64(t.ChanDir()))
-		w.typ(t.Elem())
-
-	case TMAP:
-		w.startType(mapType)
-		w.typ(t.Key())
-		w.typ(t.Elem())
-
-	case TFUNC:
-		w.startType(signatureType)
-		w.setPkg(t.Pkg(), true)
-		w.signature(t)
-
-	case TSTRUCT:
-		w.startType(structType)
-		w.setPkg(t.Pkg(), true)
-
-		w.uint64(uint64(t.NumFields()))
-		for _, f := range t.FieldSlice() {
-			w.pos(f.Pos)
-			w.selector(f.Sym)
-			w.typ(f.Type)
-			w.bool(f.Embedded != 0)
-			w.string(f.Note)
-		}
-
-	case TINTER:
-		var embeddeds, methods []*types.Field
-		for _, m := range t.Methods().Slice() {
-			if m.Sym != nil {
-				methods = append(methods, m)
-			} else {
-				embeddeds = append(embeddeds, m)
-			}
-		}
-
-		w.startType(interfaceType)
-		w.setPkg(t.Pkg(), true)
-
-		w.uint64(uint64(len(embeddeds)))
-		for _, f := range embeddeds {
-			w.pos(f.Pos)
-			w.typ(f.Type)
-		}
-
-		w.uint64(uint64(len(methods)))
-		for _, f := range methods {
-			w.pos(f.Pos)
-			w.selector(f.Sym)
-			w.signature(f.Type)
-		}
-
-	default:
-		Fatalf("unexpected type: %v", t)
-	}
-}
-
-func (w *exportWriter) setPkg(pkg *types.Pkg, write bool) {
-	if pkg == nil {
-		// TODO(mdempsky): Proactively set Pkg for types and
-		// remove this fallback logic.
-		pkg = localpkg
-	}
-
-	if write {
-		w.pkg(pkg)
-	}
-
-	w.currPkg = pkg
-}
-
-func (w *exportWriter) signature(t *types.Type) {
-	w.paramList(t.Params().FieldSlice())
-	w.paramList(t.Results().FieldSlice())
-	if n := t.Params().NumFields(); n > 0 {
-		w.bool(t.Params().Field(n - 1).IsDDD())
-	}
-}
-
-func (w *exportWriter) paramList(fs []*types.Field) {
-	w.uint64(uint64(len(fs)))
-	for _, f := range fs {
-		w.param(f)
-	}
-}
-
-func (w *exportWriter) param(f *types.Field) {
-	w.pos(f.Pos)
-	w.localIdent(origSym(f.Sym), 0)
-	w.typ(f.Type)
-}
-
-func constTypeOf(typ *types.Type) Ctype {
-	switch typ {
-	case types.UntypedInt, types.UntypedRune:
-		return CTINT
-	case types.UntypedFloat:
-		return CTFLT
-	case types.UntypedComplex:
-		return CTCPLX
-	}
-
-	switch typ.Etype {
-	case TCHAN, TFUNC, TMAP, TNIL, TINTER, TPTR, TSLICE, TUNSAFEPTR:
-		return CTNIL
-	case TBOOL:
-		return CTBOOL
-	case TSTRING:
-		return CTSTR
-	case TINT, TINT8, TINT16, TINT32, TINT64,
-		TUINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINTPTR:
-		return CTINT
-	case TFLOAT32, TFLOAT64:
-		return CTFLT
-	case TCOMPLEX64, TCOMPLEX128:
-		return CTCPLX
-	}
-
-	Fatalf("unexpected constant type: %v", typ)
-	return 0
-}
-
-func (w *exportWriter) value(typ *types.Type, v Val) {
-	if vt := idealType(v.Ctype()); typ.IsUntyped() && typ != vt {
-		Fatalf("exporter: untyped type mismatch, have: %v, want: %v", typ, vt)
-	}
-	w.typ(typ)
-
-	// Each type has only one admissible constant representation,
-	// so we could type switch directly on v.U here. However,
-	// switching on the type increases symmetry with import logic
-	// and provides a useful consistency check.
-
-	switch constTypeOf(typ) {
-	case CTNIL:
-		// Only one value; nothing to encode.
-		_ = v.U.(*NilVal)
-	case CTBOOL:
-		w.bool(v.U.(bool))
-	case CTSTR:
-		w.string(v.U.(string))
-	case CTINT:
-		w.mpint(&v.U.(*Mpint).Val, typ)
-	case CTFLT:
-		w.mpfloat(&v.U.(*Mpflt).Val, typ)
-	case CTCPLX:
-		x := v.U.(*Mpcplx)
-		w.mpfloat(&x.Real.Val, typ)
-		w.mpfloat(&x.Imag.Val, typ)
-	}
-}
-
-func intSize(typ *types.Type) (signed bool, maxBytes uint) {
-	if typ.IsUntyped() {
-		return true, Mpprec / 8
-	}
-
-	switch typ.Etype {
-	case TFLOAT32, TCOMPLEX64:
-		return true, 3
-	case TFLOAT64, TCOMPLEX128:
-		return true, 7
-	}
-
-	signed = typ.IsSigned()
-	maxBytes = uint(typ.Size())
-
-	// The go/types API doesn't expose sizes to importers, so they
-	// don't know how big these types are.
-	switch typ.Etype {
-	case TINT, TUINT, TUINTPTR:
-		maxBytes = 8
-	}
-
-	return
-}
-
-// mpint exports a multi-precision integer.
-//
-// For unsigned types, small values are written out as a single
-// byte. Larger values are written out as a length-prefixed big-endian
-// byte string, where the length prefix is encoded as its complement.
-// For example, bytes 0, 1, and 2 directly represent the integer
-// values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-,
-// 2-, and 3-byte big-endian string follow.
-//
-// Encoding for signed types use the same general approach as for
-// unsigned types, except small values use zig-zag encoding and the
-// bottom bit of length prefix byte for large values is reserved as a
-// sign bit.
-//
-// The exact boundary between small and large encodings varies
-// according to the maximum number of bytes needed to encode a value
-// of type typ. As a special case, 8-bit types are always encoded as a
-// single byte.
-//
-// TODO(mdempsky): Is this level of complexity really worthwhile?
-func (w *exportWriter) mpint(x *big.Int, typ *types.Type) {
-	signed, maxBytes := intSize(typ)
-
-	negative := x.Sign() < 0
-	if !signed && negative {
-		Fatalf("negative unsigned integer; type %v, value %v", typ, x)
-	}
-
-	b := x.Bytes()
-	if len(b) > 0 && b[0] == 0 {
-		Fatalf("leading zeros")
-	}
-	if uint(len(b)) > maxBytes {
-		Fatalf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)
-	}
-
-	maxSmall := 256 - maxBytes
-	if signed {
-		maxSmall = 256 - 2*maxBytes
-	}
-	if maxBytes == 1 {
-		maxSmall = 256
-	}
-
-	// Check if x can use small value encoding.
-	if len(b) <= 1 {
-		var ux uint
-		if len(b) == 1 {
-			ux = uint(b[0])
-		}
-		if signed {
-			ux <<= 1
-			if negative {
-				ux--
-			}
-		}
-		if ux < maxSmall {
-			w.data.WriteByte(byte(ux))
-			return
-		}
-	}
-
-	n := 256 - uint(len(b))
-	if signed {
-		n = 256 - 2*uint(len(b))
-		if negative {
-			n |= 1
-		}
-	}
-	if n < maxSmall || n >= 256 {
-		Fatalf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)
-	}
-
-	w.data.WriteByte(byte(n))
-	w.data.Write(b)
-}
-
-// mpfloat exports a multi-precision floating point number.
-//
-// The number's value is decomposed into mantissa × 2**exponent, where
-// mantissa is an integer. The value is written out as mantissa (as a
-// multi-precision integer) and then the exponent, except exponent is
-// omitted if mantissa is zero.
-func (w *exportWriter) mpfloat(f *big.Float, typ *types.Type) {
-	if f.IsInf() {
-		Fatalf("infinite constant")
-	}
-
-	// Break into f = mant × 2**exp, with 0.5 <= mant < 1.
-	var mant big.Float
-	exp := int64(f.MantExp(&mant))
-
-	// Scale so that mant is an integer.
-	prec := mant.MinPrec()
-	mant.SetMantExp(&mant, int(prec))
-	exp -= int64(prec)
-
-	manti, acc := mant.Int(nil)
-	if acc != big.Exact {
-		Fatalf("mantissa scaling failed for %f (%s)", f, acc)
-	}
-	w.mpint(manti, typ)
-	if manti.Sign() != 0 {
-		w.int64(exp)
-	}
-}
-
-func (w *exportWriter) bool(b bool) bool {
-	var x uint64
-	if b {
-		x = 1
-	}
-	w.uint64(x)
-	return b
-}
-
-func (w *exportWriter) int64(x int64)   { w.data.int64(x) }
-func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) }
-func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) }
-
-// Compiler-specific extensions.
-
-func (w *exportWriter) varExt(n *Node) {
-	w.linkname(n.Sym)
-	w.symIdx(n.Sym)
-}
-
-func (w *exportWriter) funcExt(n *Node) {
-	w.linkname(n.Sym)
-	w.symIdx(n.Sym)
-
-	// Escape analysis.
-	for _, fs := range &types.RecvsParams {
-		for _, f := range fs(n.Type).FieldSlice() {
-			w.string(f.Note)
-		}
-	}
-
-	// Inline body.
-	if n.Func.Inl != nil {
-		w.uint64(1 + uint64(n.Func.Inl.Cost))
-		if n.Func.ExportInline() {
-			w.p.doInline(n)
-		}
-
-		// Endlineno for inlined function.
-		if n.Name.Defn != nil {
-			w.pos(n.Name.Defn.Func.Endlineno)
-		} else {
-			// When the exported node was defined externally,
-			// e.g. io exports atomic.(*Value).Load or bytes exports errors.New.
-			// Keep it as we don't distinguish this case in iimport.go.
-			w.pos(n.Func.Endlineno)
-		}
-	} else {
-		w.uint64(0)
-	}
-}
-
-func (w *exportWriter) methExt(m *types.Field) {
-	w.bool(m.Nointerface())
-	w.funcExt(asNode(m.Type.Nname()))
-}
-
-func (w *exportWriter) linkname(s *types.Sym) {
-	w.string(s.Linkname)
-}
-
-func (w *exportWriter) symIdx(s *types.Sym) {
-	lsym := s.Linksym()
-	if lsym.PkgIdx > goobj.PkgIdxSelf || (lsym.PkgIdx == goobj.PkgIdxInvalid && !lsym.Indexed()) || s.Linkname != "" {
-		// Don't export index for non-package symbols, linkname'd symbols,
-		// and symbols without an index. They can only be referenced by
-		// name.
-		w.int64(-1)
-	} else {
-		// For a defined symbol, export its index.
-		// For re-exporting an imported symbol, pass its index through.
-		w.int64(int64(lsym.SymIdx))
-	}
-}
-
-func (w *exportWriter) typeExt(t *types.Type) {
-	// Export whether this type is marked notinheap.
-	w.bool(t.NotInHeap())
-	// For type T, export the index of type descriptor symbols of T and *T.
-	if i, ok := typeSymIdx[t]; ok {
-		w.int64(i[0])
-		w.int64(i[1])
-		return
-	}
-	w.symIdx(typesym(t))
-	w.symIdx(typesym(t.PtrTo()))
-}
-
-// Inline bodies.
-
-func (w *exportWriter) stmtList(list Nodes) {
-	for _, n := range list.Slice() {
-		w.node(n)
-	}
-	w.op(OEND)
-}
-
-func (w *exportWriter) node(n *Node) {
-	if opprec[n.Op] < 0 {
-		w.stmt(n)
-	} else {
-		w.expr(n)
-	}
-}
-
-// Caution: stmt will emit more than one node for statement nodes n that have a non-empty
-// n.Ninit and where n cannot have a natural init section (such as in "if", "for", etc.).
-func (w *exportWriter) stmt(n *Node) {
-	if n.Ninit.Len() > 0 && !stmtwithinit(n.Op) {
-		// can't use stmtList here since we don't want the final OEND
-		for _, n := range n.Ninit.Slice() {
-			w.stmt(n)
-		}
-	}
-
-	switch op := n.Op; op {
-	case ODCL:
-		w.op(ODCL)
-		w.pos(n.Left.Pos)
-		w.localName(n.Left)
-		w.typ(n.Left.Type)
-
-	// case ODCLFIELD:
-	//	unimplemented - handled by default case
-
-	case OAS:
-		// Don't export "v = <N>" initializing statements, hope they're always
-		// preceded by the DCL which will be re-parsed and typecheck to reproduce
-		// the "v = <N>" again.
-		if n.Right != nil {
-			w.op(OAS)
-			w.pos(n.Pos)
-			w.expr(n.Left)
-			w.expr(n.Right)
-		}
-
-	case OASOP:
-		w.op(OASOP)
-		w.pos(n.Pos)
-		w.op(n.SubOp())
-		w.expr(n.Left)
-		if w.bool(!n.Implicit()) {
-			w.expr(n.Right)
-		}
-
-	case OAS2:
-		w.op(OAS2)
-		w.pos(n.Pos)
-		w.exprList(n.List)
-		w.exprList(n.Rlist)
-
-	case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
-		w.op(OAS2)
-		w.pos(n.Pos)
-		w.exprList(n.List)
-		w.exprList(asNodes([]*Node{n.Right}))
-
-	case ORETURN:
-		w.op(ORETURN)
-		w.pos(n.Pos)
-		w.exprList(n.List)
-
-	// case ORETJMP:
-	// 	unreachable - generated by compiler for trampolin routines
-
-	case OGO, ODEFER:
-		w.op(op)
-		w.pos(n.Pos)
-		w.expr(n.Left)
-
-	case OIF:
-		w.op(OIF)
-		w.pos(n.Pos)
-		w.stmtList(n.Ninit)
-		w.expr(n.Left)
-		w.stmtList(n.Nbody)
-		w.stmtList(n.Rlist)
-
-	case OFOR:
-		w.op(OFOR)
-		w.pos(n.Pos)
-		w.stmtList(n.Ninit)
-		w.exprsOrNil(n.Left, n.Right)
-		w.stmtList(n.Nbody)
-
-	case ORANGE:
-		w.op(ORANGE)
-		w.pos(n.Pos)
-		w.stmtList(n.List)
-		w.expr(n.Right)
-		w.stmtList(n.Nbody)
-
-	case OSELECT, OSWITCH:
-		w.op(op)
-		w.pos(n.Pos)
-		w.stmtList(n.Ninit)
-		w.exprsOrNil(n.Left, nil)
-		w.caseList(n)
-
-	// case OCASE:
-	//	handled by caseList
-
-	case OFALL:
-		w.op(OFALL)
-		w.pos(n.Pos)
-
-	case OBREAK, OCONTINUE:
-		w.op(op)
-		w.pos(n.Pos)
-		w.exprsOrNil(n.Left, nil)
-
-	case OEMPTY:
-		// nothing to emit
-
-	case OGOTO, OLABEL:
-		w.op(op)
-		w.pos(n.Pos)
-		w.string(n.Sym.Name)
-
-	default:
-		Fatalf("exporter: CANNOT EXPORT: %v\nPlease notify gri@\n", n.Op)
-	}
-}
-
-func (w *exportWriter) caseList(sw *Node) {
-	namedTypeSwitch := sw.Op == OSWITCH && sw.Left != nil && sw.Left.Op == OTYPESW && sw.Left.Left != nil
-
-	cases := sw.List.Slice()
-	w.uint64(uint64(len(cases)))
-	for _, cas := range cases {
-		if cas.Op != OCASE {
-			Fatalf("expected OCASE, got %v", cas)
-		}
-		w.pos(cas.Pos)
-		w.stmtList(cas.List)
-		if namedTypeSwitch {
-			w.localName(cas.Rlist.First())
-		}
-		w.stmtList(cas.Nbody)
-	}
-}
-
-func (w *exportWriter) exprList(list Nodes) {
-	for _, n := range list.Slice() {
-		w.expr(n)
-	}
-	w.op(OEND)
-}
-
-func (w *exportWriter) expr(n *Node) {
-	// from nodefmt (fmt.go)
-	//
-	// nodefmt reverts nodes back to their original - we don't need to do
-	// it because we are not bound to produce valid Go syntax when exporting
-	//
-	// if (fmtmode != FExp || n.Op != OLITERAL) && n.Orig != nil {
-	// 	n = n.Orig
-	// }
-
-	// from exprfmt (fmt.go)
-	for n.Op == OPAREN || n.Implicit() && (n.Op == ODEREF || n.Op == OADDR || n.Op == ODOT || n.Op == ODOTPTR) {
-		n = n.Left
-	}
-
-	switch op := n.Op; op {
-	// expressions
-	// (somewhat closely following the structure of exprfmt in fmt.go)
-	case OLITERAL:
-		if n.Val().Ctype() == CTNIL && n.Orig != nil && n.Orig != n {
-			w.expr(n.Orig)
-			break
-		}
-		w.op(OLITERAL)
-		w.pos(n.Pos)
-		w.value(n.Type, n.Val())
-
-	case ONAME:
-		// 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.isMethodExpression() {
-			w.op(OXDOT)
-			w.pos(n.Pos)
-			w.expr(n.Left) // n.Left.Op == OTYPE
-			w.selector(n.Right.Sym)
-			break
-		}
-
-		// Package scope name.
-		if (n.Class() == PEXTERN || n.Class() == PFUNC) && !n.isBlank() {
-			w.op(ONONAME)
-			w.qualifiedIdent(n)
-			break
-		}
-
-		// Function scope name.
-		w.op(ONAME)
-		w.localName(n)
-
-	// case OPACK, ONONAME:
-	// 	should have been resolved by typechecking - handled by default case
-
-	case OTYPE:
-		w.op(OTYPE)
-		w.typ(n.Type)
-
-	case OTYPESW:
-		w.op(OTYPESW)
-		w.pos(n.Pos)
-		var s *types.Sym
-		if n.Left != nil {
-			if n.Left.Op != ONONAME {
-				Fatalf("expected ONONAME, got %v", n.Left)
-			}
-			s = n.Left.Sym
-		}
-		w.localIdent(s, 0) // declared pseudo-variable, if any
-		w.exprsOrNil(n.Right, nil)
-
-	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
-	// 	should have been resolved by typechecking - handled by default case
-
-	// case OCLOSURE:
-	//	unimplemented - handled by default case
-
-	// case OCOMPLIT:
-	// 	should have been resolved by typechecking - handled by default case
-
-	case OPTRLIT:
-		w.op(OADDR)
-		w.pos(n.Pos)
-		w.expr(n.Left)
-
-	case OSTRUCTLIT:
-		w.op(OSTRUCTLIT)
-		w.pos(n.Pos)
-		w.typ(n.Type)
-		w.elemList(n.List) // special handling of field names
-
-	case OARRAYLIT, OSLICELIT, OMAPLIT:
-		w.op(OCOMPLIT)
-		w.pos(n.Pos)
-		w.typ(n.Type)
-		w.exprList(n.List)
-
-	case OKEY:
-		w.op(OKEY)
-		w.pos(n.Pos)
-		w.exprsOrNil(n.Left, n.Right)
-
-	// case OSTRUCTKEY:
-	//	unreachable - handled in case OSTRUCTLIT by elemList
-
-	case OCALLPART:
-		// An OCALLPART is an OXDOT before type checking.
-		w.op(OXDOT)
-		w.pos(n.Pos)
-		w.expr(n.Left)
-		// Right node should be ONAME
-		w.selector(n.Right.Sym)
-
-	case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
-		w.op(OXDOT)
-		w.pos(n.Pos)
-		w.expr(n.Left)
-		w.selector(n.Sym)
-
-	case ODOTTYPE, ODOTTYPE2:
-		w.op(ODOTTYPE)
-		w.pos(n.Pos)
-		w.expr(n.Left)
-		w.typ(n.Type)
-
-	case OINDEX, OINDEXMAP:
-		w.op(OINDEX)
-		w.pos(n.Pos)
-		w.expr(n.Left)
-		w.expr(n.Right)
-
-	case OSLICE, OSLICESTR, OSLICEARR:
-		w.op(OSLICE)
-		w.pos(n.Pos)
-		w.expr(n.Left)
-		low, high, _ := n.SliceBounds()
-		w.exprsOrNil(low, high)
-
-	case OSLICE3, OSLICE3ARR:
-		w.op(OSLICE3)
-		w.pos(n.Pos)
-		w.expr(n.Left)
-		low, high, max := n.SliceBounds()
-		w.exprsOrNil(low, high)
-		w.expr(max)
-
-	case OCOPY, OCOMPLEX:
-		// treated like other builtin calls (see e.g., OREAL)
-		w.op(op)
-		w.pos(n.Pos)
-		w.expr(n.Left)
-		w.expr(n.Right)
-		w.op(OEND)
-
-	case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, ORUNES2STR, OSTR2BYTES, OSTR2RUNES, ORUNESTR:
-		w.op(OCONV)
-		w.pos(n.Pos)
-		w.expr(n.Left)
-		w.typ(n.Type)
-
-	case OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
-		w.op(op)
-		w.pos(n.Pos)
-		if n.Left != nil {
-			w.expr(n.Left)
-			w.op(OEND)
-		} else {
-			w.exprList(n.List) // emits terminating OEND
-		}
-		// only append() calls may contain '...' arguments
-		if op == OAPPEND {
-			w.bool(n.IsDDD())
-		} else if n.IsDDD() {
-			Fatalf("exporter: unexpected '...' with %v call", op)
-		}
-
-	case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
-		w.op(OCALL)
-		w.pos(n.Pos)
-		w.stmtList(n.Ninit)
-		w.expr(n.Left)
-		w.exprList(n.List)
-		w.bool(n.IsDDD())
-
-	case OMAKEMAP, OMAKECHAN, OMAKESLICE:
-		w.op(op) // must keep separate from OMAKE for importer
-		w.pos(n.Pos)
-		w.typ(n.Type)
-		switch {
-		default:
-			// empty list
-			w.op(OEND)
-		case n.List.Len() != 0: // pre-typecheck
-			w.exprList(n.List) // emits terminating OEND
-		case n.Right != nil:
-			w.expr(n.Left)
-			w.expr(n.Right)
-			w.op(OEND)
-		case n.Left != nil && (n.Op == OMAKESLICE || !n.Left.Type.IsUntyped()):
-			w.expr(n.Left)
-			w.op(OEND)
-		}
-
-	// unary expressions
-	case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
-		w.op(op)
-		w.pos(n.Pos)
-		w.expr(n.Left)
-
-	// binary expressions
-	case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
-		OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
-		w.op(op)
-		w.pos(n.Pos)
-		w.expr(n.Left)
-		w.expr(n.Right)
-
-	case OADDSTR:
-		w.op(OADDSTR)
-		w.pos(n.Pos)
-		w.exprList(n.List)
-
-	case ODCLCONST:
-		// if exporting, DCLCONST should just be removed as its usage
-		// has already been replaced with literals
-
-	default:
-		Fatalf("cannot export %v (%d) node\n"+
-			"\t==> please file an issue and assign to gri@", n.Op, int(n.Op))
-	}
-}
-
-func (w *exportWriter) op(op Op) {
-	w.uint64(uint64(op))
-}
-
-func (w *exportWriter) exprsOrNil(a, b *Node) {
-	ab := 0
-	if a != nil {
-		ab |= 1
-	}
-	if b != nil {
-		ab |= 2
-	}
-	w.uint64(uint64(ab))
-	if ab&1 != 0 {
-		w.expr(a)
-	}
-	if ab&2 != 0 {
-		w.node(b)
-	}
-}
-
-func (w *exportWriter) elemList(list Nodes) {
-	w.uint64(uint64(list.Len()))
-	for _, n := range list.Slice() {
-		w.selector(n.Sym)
-		w.expr(n.Left)
-	}
-}
-
-func (w *exportWriter) localName(n *Node) {
-	// Escape analysis happens after inline bodies are saved, but
-	// we're using the same ONAME nodes, so we might still see
-	// PAUTOHEAP here.
-	//
-	// Check for Stackcopy to identify PAUTOHEAP that came from
-	// PPARAM/PPARAMOUT, because we only want to include vargen in
-	// non-param names.
-	var v int32
-	if n.Class() == PAUTO || (n.Class() == PAUTOHEAP && n.Name.Param.Stackcopy == nil) {
-		v = n.Name.Vargen
-	}
-
-	w.localIdent(n.Sym, v)
-}
-
-func (w *exportWriter) localIdent(s *types.Sym, v int32) {
-	// Anonymous parameters.
-	if s == nil {
-		w.string("")
-		return
-	}
-
-	name := s.Name
-	if name == "_" {
-		w.string("_")
-		return
-	}
-
-	// TODO(mdempsky): Fix autotmp hack.
-	if i := strings.LastIndex(name, "."); i >= 0 && !strings.HasPrefix(name, ".autotmp_") {
-		Fatalf("unexpected dot in identifier: %v", name)
-	}
-
-	if v > 0 {
-		if strings.Contains(name, "·") {
-			Fatalf("exporter: unexpected · in symbol name")
-		}
-		name = fmt.Sprintf("%s·%d", name, v)
-	}
-
-	if !types.IsExported(name) && s.Pkg != w.currPkg {
-		Fatalf("weird package in name: %v => %v, not %q", s, name, w.currPkg.Path)
-	}
-
-	w.string(name)
-}
-
-type intWriter struct {
-	bytes.Buffer
-}
-
-func (w *intWriter) int64(x int64) {
-	var buf [binary.MaxVarintLen64]byte
-	n := binary.PutVarint(buf[:], x)
-	w.Write(buf[:n])
-}
-
-func (w *intWriter) uint64(x uint64) {
-	var buf [binary.MaxVarintLen64]byte
-	n := binary.PutUvarint(buf[:], x)
-	w.Write(buf[:n])
-}
diff --git a/src/cmd/compile/internal/gc/iface_test.go b/src/cmd/compile/internal/gc/iface_test.go
deleted file mode 100644
index 21c6587..0000000
--- a/src/cmd/compile/internal/gc/iface_test.go
+++ /dev/null
@@ -1,128 +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.
-
-package gc
-
-// Test to make sure we make copies of the values we
-// put in interfaces.
-
-import (
-	"testing"
-)
-
-var x int
-
-func TestEfaceConv1(t *testing.T) {
-	a := 5
-	i := interface{}(a)
-	a += 2
-	if got := i.(int); got != 5 {
-		t.Errorf("wanted 5, got %d\n", got)
-	}
-}
-
-func TestEfaceConv2(t *testing.T) {
-	a := 5
-	sink = &a
-	i := interface{}(a)
-	a += 2
-	if got := i.(int); got != 5 {
-		t.Errorf("wanted 5, got %d\n", got)
-	}
-}
-
-func TestEfaceConv3(t *testing.T) {
-	x = 5
-	if got := e2int3(x); got != 5 {
-		t.Errorf("wanted 5, got %d\n", got)
-	}
-}
-
-//go:noinline
-func e2int3(i interface{}) int {
-	x = 7
-	return i.(int)
-}
-
-func TestEfaceConv4(t *testing.T) {
-	a := 5
-	if got := e2int4(a, &a); got != 5 {
-		t.Errorf("wanted 5, got %d\n", got)
-	}
-}
-
-//go:noinline
-func e2int4(i interface{}, p *int) int {
-	*p = 7
-	return i.(int)
-}
-
-type Int int
-
-var y Int
-
-type I interface {
-	foo()
-}
-
-func (i Int) foo() {
-}
-
-func TestIfaceConv1(t *testing.T) {
-	a := Int(5)
-	i := interface{}(a)
-	a += 2
-	if got := i.(Int); got != 5 {
-		t.Errorf("wanted 5, got %d\n", int(got))
-	}
-}
-
-func TestIfaceConv2(t *testing.T) {
-	a := Int(5)
-	sink = &a
-	i := interface{}(a)
-	a += 2
-	if got := i.(Int); got != 5 {
-		t.Errorf("wanted 5, got %d\n", int(got))
-	}
-}
-
-func TestIfaceConv3(t *testing.T) {
-	y = 5
-	if got := i2Int3(y); got != 5 {
-		t.Errorf("wanted 5, got %d\n", int(got))
-	}
-}
-
-//go:noinline
-func i2Int3(i I) Int {
-	y = 7
-	return i.(Int)
-}
-
-func TestIfaceConv4(t *testing.T) {
-	a := Int(5)
-	if got := i2Int4(a, &a); got != 5 {
-		t.Errorf("wanted 5, got %d\n", int(got))
-	}
-}
-
-//go:noinline
-func i2Int4(i I, p *Int) Int {
-	*p = 7
-	return i.(Int)
-}
-
-func BenchmarkEfaceInteger(b *testing.B) {
-	sum := 0
-	for i := 0; i < b.N; i++ {
-		sum += i2int(i)
-	}
-	sink = sum
-}
-
-//go:noinline
-func i2int(i interface{}) int {
-	return i.(int)
-}
diff --git a/src/cmd/compile/internal/gc/iimport.go b/src/cmd/compile/internal/gc/iimport.go
deleted file mode 100644
index c0114d0..0000000
--- a/src/cmd/compile/internal/gc/iimport.go
+++ /dev/null
@@ -1,1117 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Indexed package import.
-// See iexport.go for the export data format.
-
-package gc
-
-import (
-	"cmd/compile/internal/types"
-	"cmd/internal/bio"
-	"cmd/internal/goobj"
-	"cmd/internal/obj"
-	"cmd/internal/src"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"math/big"
-	"os"
-	"strings"
-)
-
-// An iimporterAndOffset identifies an importer and an offset within
-// its data section.
-type iimporterAndOffset struct {
-	p   *iimporter
-	off uint64
-}
-
-var (
-	// declImporter maps from imported identifiers to an importer
-	// and offset where that identifier's declaration can be read.
-	declImporter = map[*types.Sym]iimporterAndOffset{}
-
-	// inlineImporter is like declImporter, but for inline bodies
-	// for function and method symbols.
-	inlineImporter = map[*types.Sym]iimporterAndOffset{}
-)
-
-func expandDecl(n *Node) {
-	if n.Op != ONONAME {
-		return
-	}
-
-	r := importReaderFor(n, declImporter)
-	if r == nil {
-		// Can happen if user tries to reference an undeclared name.
-		return
-	}
-
-	r.doDecl(n)
-}
-
-func expandInline(fn *Node) {
-	if fn.Func.Inl.Body != nil {
-		return
-	}
-
-	r := importReaderFor(fn, inlineImporter)
-	if r == nil {
-		Fatalf("missing import reader for %v", fn)
-	}
-
-	r.doInline(fn)
-}
-
-func importReaderFor(n *Node, importers map[*types.Sym]iimporterAndOffset) *importReader {
-	x, ok := importers[n.Sym]
-	if !ok {
-		return nil
-	}
-
-	return x.p.newReader(x.off, n.Sym.Pkg)
-}
-
-type intReader struct {
-	*bio.Reader
-	pkg *types.Pkg
-}
-
-func (r *intReader) int64() int64 {
-	i, err := binary.ReadVarint(r.Reader)
-	if err != nil {
-		yyerror("import %q: read error: %v", r.pkg.Path, err)
-		errorexit()
-	}
-	return i
-}
-
-func (r *intReader) uint64() uint64 {
-	i, err := binary.ReadUvarint(r.Reader)
-	if err != nil {
-		yyerror("import %q: read error: %v", r.pkg.Path, err)
-		errorexit()
-	}
-	return i
-}
-
-func iimport(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintType) {
-	ir := &intReader{in, pkg}
-
-	version := ir.uint64()
-	if version != iexportVersion {
-		yyerror("import %q: unknown export format version %d", pkg.Path, version)
-		errorexit()
-	}
-
-	sLen := ir.uint64()
-	dLen := ir.uint64()
-
-	// Map string (and data) section into memory as a single large
-	// string. This reduces heap fragmentation and allows
-	// returning individual substrings very efficiently.
-	data, err := mapFile(in.File(), in.Offset(), int64(sLen+dLen))
-	if err != nil {
-		yyerror("import %q: mapping input: %v", pkg.Path, err)
-		errorexit()
-	}
-	stringData := data[:sLen]
-	declData := data[sLen:]
-
-	in.MustSeek(int64(sLen+dLen), os.SEEK_CUR)
-
-	p := &iimporter{
-		ipkg: pkg,
-
-		pkgCache:     map[uint64]*types.Pkg{},
-		posBaseCache: map[uint64]*src.PosBase{},
-		typCache:     map[uint64]*types.Type{},
-
-		stringData: stringData,
-		declData:   declData,
-	}
-
-	for i, pt := range predeclared() {
-		p.typCache[uint64(i)] = pt
-	}
-
-	// Declaration index.
-	for nPkgs := ir.uint64(); nPkgs > 0; nPkgs-- {
-		pkg := p.pkgAt(ir.uint64())
-		pkgName := p.stringAt(ir.uint64())
-		pkgHeight := int(ir.uint64())
-		if pkg.Name == "" {
-			pkg.Name = pkgName
-			pkg.Height = pkgHeight
-			numImport[pkgName]++
-
-			// TODO(mdempsky): This belongs somewhere else.
-			pkg.Lookup("_").Def = asTypesNode(nblank)
-		} else {
-			if pkg.Name != pkgName {
-				Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
-			}
-			if pkg.Height != pkgHeight {
-				Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path)
-			}
-		}
-
-		for nSyms := ir.uint64(); nSyms > 0; nSyms-- {
-			s := pkg.Lookup(p.stringAt(ir.uint64()))
-			off := ir.uint64()
-
-			if _, ok := declImporter[s]; ok {
-				continue
-			}
-			declImporter[s] = iimporterAndOffset{p, off}
-
-			// Create stub declaration. If used, this will
-			// be overwritten by expandDecl.
-			if s.Def != nil {
-				Fatalf("unexpected definition for %v: %v", s, asNode(s.Def))
-			}
-			s.Def = asTypesNode(npos(src.NoXPos, dclname(s)))
-		}
-	}
-
-	// Inline body index.
-	for nPkgs := ir.uint64(); nPkgs > 0; nPkgs-- {
-		pkg := p.pkgAt(ir.uint64())
-
-		for nSyms := ir.uint64(); nSyms > 0; nSyms-- {
-			s := pkg.Lookup(p.stringAt(ir.uint64()))
-			off := ir.uint64()
-
-			if _, ok := inlineImporter[s]; ok {
-				continue
-			}
-			inlineImporter[s] = iimporterAndOffset{p, off}
-		}
-	}
-
-	// Fingerprint.
-	_, err = io.ReadFull(in, fingerprint[:])
-	if err != nil {
-		yyerror("import %s: error reading fingerprint", pkg.Path)
-		errorexit()
-	}
-	return fingerprint
-}
-
-type iimporter struct {
-	ipkg *types.Pkg
-
-	pkgCache     map[uint64]*types.Pkg
-	posBaseCache map[uint64]*src.PosBase
-	typCache     map[uint64]*types.Type
-
-	stringData string
-	declData   string
-}
-
-func (p *iimporter) stringAt(off uint64) string {
-	var x [binary.MaxVarintLen64]byte
-	n := copy(x[:], p.stringData[off:])
-
-	slen, n := binary.Uvarint(x[:n])
-	if n <= 0 {
-		Fatalf("varint failed")
-	}
-	spos := off + uint64(n)
-	return p.stringData[spos : spos+slen]
-}
-
-func (p *iimporter) posBaseAt(off uint64) *src.PosBase {
-	if posBase, ok := p.posBaseCache[off]; ok {
-		return posBase
-	}
-
-	file := p.stringAt(off)
-	posBase := src.NewFileBase(file, file)
-	p.posBaseCache[off] = posBase
-	return posBase
-}
-
-func (p *iimporter) pkgAt(off uint64) *types.Pkg {
-	if pkg, ok := p.pkgCache[off]; ok {
-		return pkg
-	}
-
-	pkg := p.ipkg
-	if pkgPath := p.stringAt(off); pkgPath != "" {
-		pkg = types.NewPkg(pkgPath, "")
-	}
-	p.pkgCache[off] = pkg
-	return pkg
-}
-
-// An importReader keeps state for reading an individual imported
-// object (declaration or inline body).
-type importReader struct {
-	strings.Reader
-	p *iimporter
-
-	currPkg    *types.Pkg
-	prevBase   *src.PosBase
-	prevLine   int64
-	prevColumn int64
-}
-
-func (p *iimporter) newReader(off uint64, pkg *types.Pkg) *importReader {
-	r := &importReader{
-		p:       p,
-		currPkg: pkg,
-	}
-	// (*strings.Reader).Reset wasn't added until Go 1.7, and we
-	// need to build with Go 1.4.
-	r.Reader = *strings.NewReader(p.declData[off:])
-	return r
-}
-
-func (r *importReader) string() string        { return r.p.stringAt(r.uint64()) }
-func (r *importReader) posBase() *src.PosBase { return r.p.posBaseAt(r.uint64()) }
-func (r *importReader) pkg() *types.Pkg       { return r.p.pkgAt(r.uint64()) }
-
-func (r *importReader) setPkg() {
-	r.currPkg = r.pkg()
-}
-
-func (r *importReader) doDecl(n *Node) {
-	if n.Op != ONONAME {
-		Fatalf("doDecl: unexpected Op for %v: %v", n.Sym, n.Op)
-	}
-
-	tag := r.byte()
-	pos := r.pos()
-
-	switch tag {
-	case 'A':
-		typ := r.typ()
-
-		importalias(r.p.ipkg, pos, n.Sym, typ)
-
-	case 'C':
-		typ, val := r.value()
-
-		importconst(r.p.ipkg, pos, n.Sym, typ, val)
-
-	case 'F':
-		typ := r.signature(nil)
-
-		importfunc(r.p.ipkg, pos, n.Sym, typ)
-		r.funcExt(n)
-
-	case 'T':
-		// Types can be recursive. We need to setup a stub
-		// declaration before recursing.
-		t := importtype(r.p.ipkg, pos, n.Sym)
-
-		// We also need to defer width calculations until
-		// after the underlying type has been assigned.
-		defercheckwidth()
-		underlying := r.typ()
-		setUnderlying(t, underlying)
-		resumecheckwidth()
-
-		if underlying.IsInterface() {
-			r.typeExt(t)
-			break
-		}
-
-		ms := make([]*types.Field, r.uint64())
-		for i := range ms {
-			mpos := r.pos()
-			msym := r.ident()
-			recv := r.param()
-			mtyp := r.signature(recv)
-
-			f := types.NewField()
-			f.Pos = mpos
-			f.Sym = msym
-			f.Type = mtyp
-			ms[i] = f
-
-			m := newfuncnamel(mpos, methodSym(recv.Type, msym))
-			m.Type = mtyp
-			m.SetClass(PFUNC)
-			// methodSym already marked m.Sym as a function.
-
-			// (comment from parser.go)
-			// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
-			// (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.
-			mtyp.SetNname(asTypesNode(m))
-		}
-		t.Methods().Set(ms)
-
-		r.typeExt(t)
-		for _, m := range ms {
-			r.methExt(m)
-		}
-
-	case 'V':
-		typ := r.typ()
-
-		importvar(r.p.ipkg, pos, n.Sym, typ)
-		r.varExt(n)
-
-	default:
-		Fatalf("unexpected tag: %v", tag)
-	}
-}
-
-func (p *importReader) value() (typ *types.Type, v Val) {
-	typ = p.typ()
-
-	switch constTypeOf(typ) {
-	case CTNIL:
-		v.U = &NilVal{}
-	case CTBOOL:
-		v.U = p.bool()
-	case CTSTR:
-		v.U = p.string()
-	case CTINT:
-		x := new(Mpint)
-		x.Rune = typ == types.UntypedRune
-		p.mpint(&x.Val, typ)
-		v.U = x
-	case CTFLT:
-		x := newMpflt()
-		p.float(x, typ)
-		v.U = x
-	case CTCPLX:
-		x := newMpcmplx()
-		p.float(&x.Real, typ)
-		p.float(&x.Imag, typ)
-		v.U = x
-	}
-	return
-}
-
-func (p *importReader) mpint(x *big.Int, typ *types.Type) {
-	signed, maxBytes := intSize(typ)
-
-	maxSmall := 256 - maxBytes
-	if signed {
-		maxSmall = 256 - 2*maxBytes
-	}
-	if maxBytes == 1 {
-		maxSmall = 256
-	}
-
-	n, _ := p.ReadByte()
-	if uint(n) < maxSmall {
-		v := int64(n)
-		if signed {
-			v >>= 1
-			if n&1 != 0 {
-				v = ^v
-			}
-		}
-		x.SetInt64(v)
-		return
-	}
-
-	v := -n
-	if signed {
-		v = -(n &^ 1) >> 1
-	}
-	if v < 1 || uint(v) > maxBytes {
-		Fatalf("weird decoding: %v, %v => %v", n, signed, v)
-	}
-	b := make([]byte, v)
-	p.Read(b)
-	x.SetBytes(b)
-	if signed && n&1 != 0 {
-		x.Neg(x)
-	}
-}
-
-func (p *importReader) float(x *Mpflt, typ *types.Type) {
-	var mant big.Int
-	p.mpint(&mant, typ)
-	m := x.Val.SetInt(&mant)
-	if m.Sign() == 0 {
-		return
-	}
-	m.SetMantExp(m, int(p.int64()))
-}
-
-func (r *importReader) ident() *types.Sym {
-	name := r.string()
-	if name == "" {
-		return nil
-	}
-	pkg := r.currPkg
-	if types.IsExported(name) {
-		pkg = localpkg
-	}
-	return pkg.Lookup(name)
-}
-
-func (r *importReader) qualifiedIdent() *types.Sym {
-	name := r.string()
-	pkg := r.pkg()
-	return pkg.Lookup(name)
-}
-
-func (r *importReader) pos() src.XPos {
-	delta := r.int64()
-	r.prevColumn += delta >> 1
-	if delta&1 != 0 {
-		delta = r.int64()
-		r.prevLine += delta >> 1
-		if delta&1 != 0 {
-			r.prevBase = r.posBase()
-		}
-	}
-
-	if (r.prevBase == nil || r.prevBase.AbsFilename() == "") && r.prevLine == 0 && r.prevColumn == 0 {
-		// TODO(mdempsky): Remove once we reliably write
-		// position information for all nodes.
-		return src.NoXPos
-	}
-
-	if r.prevBase == nil {
-		Fatalf("missing posbase")
-	}
-	pos := src.MakePos(r.prevBase, uint(r.prevLine), uint(r.prevColumn))
-	return Ctxt.PosTable.XPos(pos)
-}
-
-func (r *importReader) typ() *types.Type {
-	return r.p.typAt(r.uint64())
-}
-
-func (p *iimporter) typAt(off uint64) *types.Type {
-	t, ok := p.typCache[off]
-	if !ok {
-		if off < predeclReserved {
-			Fatalf("predeclared type missing from cache: %d", off)
-		}
-		t = p.newReader(off-predeclReserved, nil).typ1()
-		p.typCache[off] = t
-	}
-	return t
-}
-
-func (r *importReader) typ1() *types.Type {
-	switch k := r.kind(); k {
-	default:
-		Fatalf("unexpected kind tag in %q: %v", r.p.ipkg.Path, k)
-		return nil
-
-	case definedType:
-		// We might be called from within doInline, in which
-		// case Sym.Def can point to declared parameters
-		// instead of the top-level types. Also, we don't
-		// support inlining functions with local defined
-		// types. Therefore, this must be a package-scope
-		// type.
-		n := asNode(r.qualifiedIdent().PkgDef())
-		if n.Op == ONONAME {
-			expandDecl(n)
-		}
-		if n.Op != OTYPE {
-			Fatalf("expected OTYPE, got %v: %v, %v", n.Op, n.Sym, n)
-		}
-		return n.Type
-	case pointerType:
-		return types.NewPtr(r.typ())
-	case sliceType:
-		return types.NewSlice(r.typ())
-	case arrayType:
-		n := r.uint64()
-		return types.NewArray(r.typ(), int64(n))
-	case chanType:
-		dir := types.ChanDir(r.uint64())
-		return types.NewChan(r.typ(), dir)
-	case mapType:
-		return types.NewMap(r.typ(), r.typ())
-
-	case signatureType:
-		r.setPkg()
-		return r.signature(nil)
-
-	case structType:
-		r.setPkg()
-
-		fs := make([]*types.Field, r.uint64())
-		for i := range fs {
-			pos := r.pos()
-			sym := r.ident()
-			typ := r.typ()
-			emb := r.bool()
-			note := r.string()
-
-			f := types.NewField()
-			f.Pos = pos
-			f.Sym = sym
-			f.Type = typ
-			if emb {
-				f.Embedded = 1
-			}
-			f.Note = note
-			fs[i] = f
-		}
-
-		t := types.New(TSTRUCT)
-		t.SetPkg(r.currPkg)
-		t.SetFields(fs)
-		return t
-
-	case interfaceType:
-		r.setPkg()
-
-		embeddeds := make([]*types.Field, r.uint64())
-		for i := range embeddeds {
-			pos := r.pos()
-			typ := r.typ()
-
-			f := types.NewField()
-			f.Pos = pos
-			f.Type = typ
-			embeddeds[i] = f
-		}
-
-		methods := make([]*types.Field, r.uint64())
-		for i := range methods {
-			pos := r.pos()
-			sym := r.ident()
-			typ := r.signature(fakeRecvField())
-
-			f := types.NewField()
-			f.Pos = pos
-			f.Sym = sym
-			f.Type = typ
-			methods[i] = f
-		}
-
-		t := types.New(TINTER)
-		t.SetPkg(r.currPkg)
-		t.SetInterface(append(embeddeds, methods...))
-
-		// Ensure we expand the interface in the frontend (#25055).
-		checkwidth(t)
-		return t
-	}
-}
-
-func (r *importReader) kind() itag {
-	return itag(r.uint64())
-}
-
-func (r *importReader) signature(recv *types.Field) *types.Type {
-	params := r.paramList()
-	results := r.paramList()
-	if n := len(params); n > 0 {
-		params[n-1].SetIsDDD(r.bool())
-	}
-	t := functypefield(recv, params, results)
-	t.SetPkg(r.currPkg)
-	return t
-}
-
-func (r *importReader) paramList() []*types.Field {
-	fs := make([]*types.Field, r.uint64())
-	for i := range fs {
-		fs[i] = r.param()
-	}
-	return fs
-}
-
-func (r *importReader) param() *types.Field {
-	f := types.NewField()
-	f.Pos = r.pos()
-	f.Sym = r.ident()
-	f.Type = r.typ()
-	return f
-}
-
-func (r *importReader) bool() bool {
-	return r.uint64() != 0
-}
-
-func (r *importReader) int64() int64 {
-	n, err := binary.ReadVarint(r)
-	if err != nil {
-		Fatalf("readVarint: %v", err)
-	}
-	return n
-}
-
-func (r *importReader) uint64() uint64 {
-	n, err := binary.ReadUvarint(r)
-	if err != nil {
-		Fatalf("readVarint: %v", err)
-	}
-	return n
-}
-
-func (r *importReader) byte() byte {
-	x, err := r.ReadByte()
-	if err != nil {
-		Fatalf("declReader.ReadByte: %v", err)
-	}
-	return x
-}
-
-// Compiler-specific extensions.
-
-func (r *importReader) varExt(n *Node) {
-	r.linkname(n.Sym)
-	r.symIdx(n.Sym)
-}
-
-func (r *importReader) funcExt(n *Node) {
-	r.linkname(n.Sym)
-	r.symIdx(n.Sym)
-
-	// Escape analysis.
-	for _, fs := range &types.RecvsParams {
-		for _, f := range fs(n.Type).FieldSlice() {
-			f.Note = r.string()
-		}
-	}
-
-	// Inline body.
-	if u := r.uint64(); u > 0 {
-		n.Func.Inl = &Inline{
-			Cost: int32(u - 1),
-		}
-		n.Func.Endlineno = r.pos()
-	}
-}
-
-func (r *importReader) methExt(m *types.Field) {
-	if r.bool() {
-		m.SetNointerface(true)
-	}
-	r.funcExt(asNode(m.Type.Nname()))
-}
-
-func (r *importReader) linkname(s *types.Sym) {
-	s.Linkname = r.string()
-}
-
-func (r *importReader) symIdx(s *types.Sym) {
-	lsym := s.Linksym()
-	idx := int32(r.int64())
-	if idx != -1 {
-		if s.Linkname != "" {
-			Fatalf("bad index for linknamed symbol: %v %d\n", lsym, idx)
-		}
-		lsym.SymIdx = idx
-		lsym.Set(obj.AttrIndexed, true)
-	}
-}
-
-func (r *importReader) typeExt(t *types.Type) {
-	t.SetNotInHeap(r.bool())
-	i, pi := r.int64(), r.int64()
-	if i != -1 && pi != -1 {
-		typeSymIdx[t] = [2]int64{i, pi}
-	}
-}
-
-// Map imported type T to the index of type descriptor symbols of T and *T,
-// so we can use index to reference the symbol.
-var typeSymIdx = make(map[*types.Type][2]int64)
-
-func (r *importReader) doInline(n *Node) {
-	if len(n.Func.Inl.Body) != 0 {
-		Fatalf("%v already has inline body", n)
-	}
-
-	funchdr(n)
-	body := r.stmtList()
-	funcbody()
-	if body == nil {
-		//
-		// Make sure empty body is not interpreted as
-		// no inlineable body (see also parser.fnbody)
-		// (not doing so can cause significant performance
-		// degradation due to unnecessary calls to empty
-		// functions).
-		body = []*Node{}
-	}
-	n.Func.Inl.Body = body
-
-	importlist = append(importlist, n)
-
-	if Debug.E > 0 && Debug.m > 2 {
-		if Debug.m > 3 {
-			fmt.Printf("inl body for %v %#v: %+v\n", n, n.Type, asNodes(n.Func.Inl.Body))
-		} else {
-			fmt.Printf("inl body for %v %#v: %v\n", n, n.Type, asNodes(n.Func.Inl.Body))
-		}
-	}
-}
-
-// ----------------------------------------------------------------------------
-// Inlined function bodies
-
-// Approach: Read nodes and use them to create/declare the same data structures
-// as done originally by the (hidden) parser by closely following the parser's
-// original code. In other words, "parsing" the import data (which happens to
-// be encoded in binary rather textual form) is the best way at the moment to
-// re-establish the syntax tree's invariants. At some future point we might be
-// able to avoid this round-about way and create the rewritten nodes directly,
-// possibly avoiding a lot of duplicate work (name resolution, type checking).
-//
-// Refined nodes (e.g., ODOTPTR as a refinement of OXDOT) are exported as their
-// unrefined nodes (since this is what the importer uses). The respective case
-// entries are unreachable in the importer.
-
-func (r *importReader) stmtList() []*Node {
-	var list []*Node
-	for {
-		n := r.node()
-		if n == nil {
-			break
-		}
-		// OBLOCK nodes may be created when importing ODCL nodes - unpack them
-		if n.Op == OBLOCK {
-			list = append(list, n.List.Slice()...)
-		} else {
-			list = append(list, n)
-		}
-
-	}
-	return list
-}
-
-func (r *importReader) caseList(sw *Node) []*Node {
-	namedTypeSwitch := sw.Op == OSWITCH && sw.Left != nil && sw.Left.Op == OTYPESW && sw.Left.Left != nil
-
-	cases := make([]*Node, r.uint64())
-	for i := range cases {
-		cas := nodl(r.pos(), OCASE, nil, nil)
-		cas.List.Set(r.stmtList())
-		if namedTypeSwitch {
-			// Note: per-case variables will have distinct, dotted
-			// names after import. That's okay: swt.go only needs
-			// Sym for diagnostics anyway.
-			caseVar := newnamel(cas.Pos, r.ident())
-			declare(caseVar, dclcontext)
-			cas.Rlist.Set1(caseVar)
-			caseVar.Name.Defn = sw.Left
-		}
-		cas.Nbody.Set(r.stmtList())
-		cases[i] = cas
-	}
-	return cases
-}
-
-func (r *importReader) exprList() []*Node {
-	var list []*Node
-	for {
-		n := r.expr()
-		if n == nil {
-			break
-		}
-		list = append(list, n)
-	}
-	return list
-}
-
-func (r *importReader) expr() *Node {
-	n := r.node()
-	if n != nil && n.Op == OBLOCK {
-		Fatalf("unexpected block node: %v", n)
-	}
-	return n
-}
-
-// TODO(gri) split into expr and stmt
-func (r *importReader) node() *Node {
-	switch op := r.op(); op {
-	// expressions
-	// case OPAREN:
-	// 	unreachable - unpacked by exporter
-
-	case OLITERAL:
-		pos := r.pos()
-		typ, val := r.value()
-
-		n := npos(pos, nodlit(val))
-		n.Type = typ
-		return n
-
-	case ONONAME:
-		return mkname(r.qualifiedIdent())
-
-	case ONAME:
-		return mkname(r.ident())
-
-	// case OPACK, ONONAME:
-	// 	unreachable - should have been resolved by typechecking
-
-	case OTYPE:
-		return typenod(r.typ())
-
-	case OTYPESW:
-		n := nodl(r.pos(), OTYPESW, nil, nil)
-		if s := r.ident(); s != nil {
-			n.Left = npos(n.Pos, newnoname(s))
-		}
-		n.Right, _ = r.exprsOrNil()
-		return n
-
-	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
-	//      unreachable - should have been resolved by typechecking
-
-	// case OCLOSURE:
-	//	unimplemented
-
-	// case OPTRLIT:
-	//	unreachable - mapped to case OADDR below by exporter
-
-	case OSTRUCTLIT:
-		// TODO(mdempsky): Export position information for OSTRUCTKEY nodes.
-		savedlineno := lineno
-		lineno = r.pos()
-		n := nodl(lineno, OCOMPLIT, nil, typenod(r.typ()))
-		n.List.Set(r.elemList()) // special handling of field names
-		lineno = savedlineno
-		return n
-
-	// case OARRAYLIT, OSLICELIT, OMAPLIT:
-	// 	unreachable - mapped to case OCOMPLIT below by exporter
-
-	case OCOMPLIT:
-		n := nodl(r.pos(), OCOMPLIT, nil, typenod(r.typ()))
-		n.List.Set(r.exprList())
-		return n
-
-	case OKEY:
-		pos := r.pos()
-		left, right := r.exprsOrNil()
-		return nodl(pos, OKEY, left, right)
-
-	// case OSTRUCTKEY:
-	//	unreachable - handled in case OSTRUCTLIT by elemList
-
-	// case OCALLPART:
-	//	unreachable - mapped to case OXDOT below by exporter
-
-	// case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
-	// 	unreachable - mapped to case OXDOT below by exporter
-
-	case OXDOT:
-		// see parser.new_dotname
-		return npos(r.pos(), nodSym(OXDOT, r.expr(), r.ident()))
-
-	// case ODOTTYPE, ODOTTYPE2:
-	// 	unreachable - mapped to case ODOTTYPE below by exporter
-
-	case ODOTTYPE:
-		n := nodl(r.pos(), ODOTTYPE, r.expr(), nil)
-		n.Type = r.typ()
-		return n
-
-	// case OINDEX, OINDEXMAP, OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
-	// 	unreachable - mapped to cases below by exporter
-
-	case OINDEX:
-		return nodl(r.pos(), op, r.expr(), r.expr())
-
-	case OSLICE, OSLICE3:
-		n := nodl(r.pos(), op, r.expr(), nil)
-		low, high := r.exprsOrNil()
-		var max *Node
-		if n.Op.IsSlice3() {
-			max = r.expr()
-		}
-		n.SetSliceBounds(low, high, max)
-		return n
-
-	// case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, ORUNES2STR, OSTR2BYTES, OSTR2RUNES, ORUNESTR:
-	// 	unreachable - mapped to OCONV case below by exporter
-
-	case OCONV:
-		n := nodl(r.pos(), OCONV, r.expr(), nil)
-		n.Type = r.typ()
-		return n
-
-	case OCOPY, OCOMPLEX, OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
-		n := npos(r.pos(), builtinCall(op))
-		n.List.Set(r.exprList())
-		if op == OAPPEND {
-			n.SetIsDDD(r.bool())
-		}
-		return n
-
-	// case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
-	// 	unreachable - mapped to OCALL case below by exporter
-
-	case OCALL:
-		n := nodl(r.pos(), OCALL, nil, nil)
-		n.Ninit.Set(r.stmtList())
-		n.Left = r.expr()
-		n.List.Set(r.exprList())
-		n.SetIsDDD(r.bool())
-		return n
-
-	case OMAKEMAP, OMAKECHAN, OMAKESLICE:
-		n := npos(r.pos(), builtinCall(OMAKE))
-		n.List.Append(typenod(r.typ()))
-		n.List.Append(r.exprList()...)
-		return n
-
-	// unary expressions
-	case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
-		return nodl(r.pos(), op, r.expr(), nil)
-
-	// binary expressions
-	case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
-		OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
-		return nodl(r.pos(), op, r.expr(), r.expr())
-
-	case OADDSTR:
-		pos := r.pos()
-		list := r.exprList()
-		x := npos(pos, list[0])
-		for _, y := range list[1:] {
-			x = nodl(pos, OADD, x, y)
-		}
-		return x
-
-	// --------------------------------------------------------------------
-	// statements
-	case ODCL:
-		pos := r.pos()
-		lhs := npos(pos, dclname(r.ident()))
-		typ := typenod(r.typ())
-		return npos(pos, liststmt(variter([]*Node{lhs}, typ, nil))) // TODO(gri) avoid list creation
-
-	// case ODCLFIELD:
-	//	unimplemented
-
-	// case OAS, OASWB:
-	// 	unreachable - mapped to OAS case below by exporter
-
-	case OAS:
-		return nodl(r.pos(), OAS, r.expr(), r.expr())
-
-	case OASOP:
-		n := nodl(r.pos(), OASOP, nil, nil)
-		n.SetSubOp(r.op())
-		n.Left = r.expr()
-		if !r.bool() {
-			n.Right = nodintconst(1)
-			n.SetImplicit(true)
-		} else {
-			n.Right = r.expr()
-		}
-		return n
-
-	// case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
-	// 	unreachable - mapped to OAS2 case below by exporter
-
-	case OAS2:
-		n := nodl(r.pos(), OAS2, nil, nil)
-		n.List.Set(r.exprList())
-		n.Rlist.Set(r.exprList())
-		return n
-
-	case ORETURN:
-		n := nodl(r.pos(), ORETURN, nil, nil)
-		n.List.Set(r.exprList())
-		return n
-
-	// case ORETJMP:
-	// 	unreachable - generated by compiler for trampolin routines (not exported)
-
-	case OGO, ODEFER:
-		return nodl(r.pos(), op, r.expr(), nil)
-
-	case OIF:
-		n := nodl(r.pos(), OIF, nil, nil)
-		n.Ninit.Set(r.stmtList())
-		n.Left = r.expr()
-		n.Nbody.Set(r.stmtList())
-		n.Rlist.Set(r.stmtList())
-		return n
-
-	case OFOR:
-		n := nodl(r.pos(), OFOR, nil, nil)
-		n.Ninit.Set(r.stmtList())
-		n.Left, n.Right = r.exprsOrNil()
-		n.Nbody.Set(r.stmtList())
-		return n
-
-	case ORANGE:
-		n := nodl(r.pos(), ORANGE, nil, nil)
-		n.List.Set(r.stmtList())
-		n.Right = r.expr()
-		n.Nbody.Set(r.stmtList())
-		return n
-
-	case OSELECT, OSWITCH:
-		n := nodl(r.pos(), op, nil, nil)
-		n.Ninit.Set(r.stmtList())
-		n.Left, _ = r.exprsOrNil()
-		n.List.Set(r.caseList(n))
-		return n
-
-	// case OCASE:
-	//	handled by caseList
-
-	case OFALL:
-		n := nodl(r.pos(), OFALL, nil, nil)
-		return n
-
-	case OBREAK, OCONTINUE:
-		pos := r.pos()
-		left, _ := r.exprsOrNil()
-		if left != nil {
-			left = newname(left.Sym)
-		}
-		return nodl(pos, op, left, nil)
-
-	// case OEMPTY:
-	// 	unreachable - not emitted by exporter
-
-	case OGOTO, OLABEL:
-		n := nodl(r.pos(), op, nil, nil)
-		n.Sym = lookup(r.string())
-		return n
-
-	case OEND:
-		return nil
-
-	default:
-		Fatalf("cannot import %v (%d) node\n"+
-			"\t==> please file an issue and assign to gri@", op, int(op))
-		panic("unreachable") // satisfy compiler
-	}
-}
-
-func (r *importReader) op() Op {
-	return Op(r.uint64())
-}
-
-func (r *importReader) elemList() []*Node {
-	c := r.uint64()
-	list := make([]*Node, c)
-	for i := range list {
-		s := r.ident()
-		list[i] = nodSym(OSTRUCTKEY, r.expr(), s)
-	}
-	return list
-}
-
-func (r *importReader) exprsOrNil() (a, b *Node) {
-	ab := r.uint64()
-	if ab&1 != 0 {
-		a = r.expr()
-	}
-	if ab&2 != 0 {
-		b = r.node()
-	}
-	return
-}
diff --git a/src/cmd/compile/internal/gc/init.go b/src/cmd/compile/internal/gc/init.go
deleted file mode 100644
index ec9cc4b..0000000
--- a/src/cmd/compile/internal/gc/init.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
-	"cmd/compile/internal/types"
-	"cmd/internal/obj"
-)
-
-// A function named init is a special case.
-// It is called by the initialization before main is run.
-// To make it unique within a package and also uncallable,
-// the name, normally "pkg.init", is altered to "pkg.init.0".
-var renameinitgen int
-
-// Dummy function for autotmps generated during typechecking.
-var dummyInitFn = nod(ODCLFUNC, nil, nil)
-
-func renameinit() *types.Sym {
-	s := lookupN("init.", renameinitgen)
-	renameinitgen++
-	return s
-}
-
-// fninit makes an initialization record for the package.
-// See runtime/proc.go:initTask for its layout.
-// The 3 tasks for initialization are:
-//   1) Initialize all of the packages the current package depends on.
-//   2) Initialize all the variables that have initializers.
-//   3) Run any init functions.
-func fninit(n []*Node) {
-	nf := initOrder(n)
-
-	var deps []*obj.LSym // initTask records for packages the current package depends on
-	var fns []*obj.LSym  // functions to call for package initialization
-
-	// Find imported packages with init tasks.
-	for _, s := range types.InitSyms {
-		deps = append(deps, s.Linksym())
-	}
-
-	// Make a function that contains all the initialization statements.
-	if len(nf) > 0 {
-		lineno = nf[0].Pos // prolog/epilog gets line number of first init stmt
-		initializers := lookup("init")
-		fn := dclfunc(initializers, nod(OTFUNC, nil, nil))
-		for _, dcl := range dummyInitFn.Func.Dcl {
-			dcl.Name.Curfn = fn
-		}
-		fn.Func.Dcl = append(fn.Func.Dcl, dummyInitFn.Func.Dcl...)
-		dummyInitFn.Func.Dcl = nil
-
-		fn.Nbody.Set(nf)
-		funcbody()
-
-		fn = typecheck(fn, ctxStmt)
-		Curfn = fn
-		typecheckslice(nf, ctxStmt)
-		Curfn = nil
-		xtop = append(xtop, fn)
-		fns = append(fns, initializers.Linksym())
-	}
-	if dummyInitFn.Func.Dcl != nil {
-		// We only generate temps using dummyInitFn if there
-		// are package-scope initialization statements, so
-		// something's weird if we get here.
-		Fatalf("dummyInitFn still has declarations")
-	}
-	dummyInitFn = nil
-
-	// Record user init functions.
-	for i := 0; i < renameinitgen; i++ {
-		s := lookupN("init.", i)
-		fn := asNode(s.Def).Name.Defn
-		// Skip init functions with empty bodies.
-		if fn.Nbody.Len() == 1 && fn.Nbody.First().Op == OEMPTY {
-			continue
-		}
-		fns = append(fns, s.Linksym())
-	}
-
-	if len(deps) == 0 && len(fns) == 0 && localpkg.Name != "main" && localpkg.Name != "runtime" {
-		return // nothing to initialize
-	}
-
-	// Make an .inittask structure.
-	sym := lookup(".inittask")
-	nn := newname(sym)
-	nn.Type = types.Types[TUINT8] // dummy type
-	nn.SetClass(PEXTERN)
-	sym.Def = asTypesNode(nn)
-	exportsym(nn)
-	lsym := sym.Linksym()
-	ot := 0
-	ot = duintptr(lsym, ot, 0) // state: not initialized yet
-	ot = duintptr(lsym, ot, uint64(len(deps)))
-	ot = duintptr(lsym, ot, uint64(len(fns)))
-	for _, d := range deps {
-		ot = dsymptr(lsym, ot, d, 0)
-	}
-	for _, f := range fns {
-		ot = dsymptr(lsym, ot, f, 0)
-	}
-	// An initTask has pointers, but none into the Go heap.
-	// It's not quite read only, the state field must be modifiable.
-	ggloblsym(lsym, int32(ot), obj.NOPTR)
-}
diff --git a/src/cmd/compile/internal/gc/initorder.go b/src/cmd/compile/internal/gc/initorder.go
deleted file mode 100644
index e2084fd..0000000
--- a/src/cmd/compile/internal/gc/initorder.go
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
-	"bytes"
-	"container/heap"
-	"fmt"
-)
-
-// Package initialization
-//
-// Here we implement the algorithm for ordering package-level variable
-// initialization. The spec is written in terms of variable
-// initialization, but multiple variables initialized by a single
-// assignment are handled together, so here we instead focus on
-// ordering initialization assignments. Conveniently, this maps well
-// to how we represent package-level initializations using the Node
-// AST.
-//
-// Assignments are in one of three phases: NotStarted, Pending, or
-// Done. For assignments in the Pending phase, we use Xoffset to
-// record the number of unique variable dependencies whose
-// initialization assignment is not yet Done. We also maintain a
-// "blocking" map that maps assignments back to all of the assignments
-// that depend on it.
-//
-// For example, for an initialization like:
-//
-//     var x = f(a, b, b)
-//     var a, b = g()
-//
-// the "x = f(a, b, b)" assignment depends on two variables (a and b),
-// so its Xoffset will be 2. Correspondingly, the "a, b = g()"
-// assignment's "blocking" entry will have two entries back to x's
-// assignment.
-//
-// Logically, initialization works by (1) taking all NotStarted
-// assignments, calculating their dependencies, and marking them
-// Pending; (2) adding all Pending assignments with Xoffset==0 to a
-// "ready" priority queue (ordered by variable declaration position);
-// and (3) iteratively processing the next Pending assignment from the
-// queue, decreasing the Xoffset of assignments it's blocking, and
-// adding them to the queue if decremented to 0.
-//
-// As an optimization, we actually apply each of these three steps for
-// each assignment. This yields the same order, but keeps queue size
-// down and thus also heap operation costs.
-
-// Static initialization phase.
-// These values are stored in two bits in Node.flags.
-const (
-	InitNotStarted = iota
-	InitDone
-	InitPending
-)
-
-type InitOrder struct {
-	// blocking maps initialization assignments to the assignments
-	// that depend on it.
-	blocking map[*Node][]*Node
-
-	// ready is the queue of Pending initialization assignments
-	// that are ready for initialization.
-	ready declOrder
-}
-
-// initOrder computes initialization order for a list l of
-// package-level declarations (in declaration order) and outputs the
-// corresponding list of statements to include in the init() function
-// body.
-func initOrder(l []*Node) []*Node {
-	s := InitSchedule{
-		initplans: make(map[*Node]*InitPlan),
-		inittemps: make(map[*Node]*Node),
-	}
-	o := InitOrder{
-		blocking: make(map[*Node][]*Node),
-	}
-
-	// Process all package-level assignment in declaration order.
-	for _, n := range l {
-		switch n.Op {
-		case OAS, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
-			o.processAssign(n)
-			o.flushReady(s.staticInit)
-		case ODCLCONST, ODCLFUNC, ODCLTYPE:
-			// nop
-		default:
-			Fatalf("unexpected package-level statement: %v", n)
-		}
-	}
-
-	// Check that all assignments are now Done; if not, there must
-	// have been a dependency cycle.
-	for _, n := range l {
-		switch n.Op {
-		case OAS, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
-			if n.Initorder() != InitDone {
-				// If there have already been errors
-				// printed, those errors may have
-				// confused us and there might not be
-				// a loop. Let the user fix those
-				// first.
-				if nerrors > 0 {
-					errorexit()
-				}
-
-				findInitLoopAndExit(firstLHS(n), new([]*Node), make(map[*Node]bool))
-				Fatalf("initialization unfinished, but failed to identify loop")
-			}
-		}
-	}
-
-	// Invariant consistency check. If this is non-zero, then we
-	// should have found a cycle above.
-	if len(o.blocking) != 0 {
-		Fatalf("expected empty map: %v", o.blocking)
-	}
-
-	return s.out
-}
-
-func (o *InitOrder) processAssign(n *Node) {
-	if n.Initorder() != InitNotStarted || n.Xoffset != BADWIDTH {
-		Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Xoffset)
-	}
-
-	n.SetInitorder(InitPending)
-	n.Xoffset = 0
-
-	// Compute number of variable dependencies and build the
-	// inverse dependency ("blocking") graph.
-	for dep := range collectDeps(n, true) {
-		defn := dep.Name.Defn
-		// Skip dependencies on functions (PFUNC) and
-		// variables already initialized (InitDone).
-		if dep.Class() != PEXTERN || defn.Initorder() == InitDone {
-			continue
-		}
-		n.Xoffset++
-		o.blocking[defn] = append(o.blocking[defn], n)
-	}
-
-	if n.Xoffset == 0 {
-		heap.Push(&o.ready, n)
-	}
-}
-
-// flushReady repeatedly applies initialize to the earliest (in
-// declaration order) assignment ready for initialization and updates
-// the inverse dependency ("blocking") graph.
-func (o *InitOrder) flushReady(initialize func(*Node)) {
-	for o.ready.Len() != 0 {
-		n := heap.Pop(&o.ready).(*Node)
-		if n.Initorder() != InitPending || n.Xoffset != 0 {
-			Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Xoffset)
-		}
-
-		initialize(n)
-		n.SetInitorder(InitDone)
-		n.Xoffset = BADWIDTH
-
-		blocked := o.blocking[n]
-		delete(o.blocking, n)
-
-		for _, m := range blocked {
-			m.Xoffset--
-			if m.Xoffset == 0 {
-				heap.Push(&o.ready, m)
-			}
-		}
-	}
-}
-
-// findInitLoopAndExit searches for an initialization loop involving variable
-// or function n. If one is found, it reports the loop as an error and exits.
-//
-// path points to a slice used for tracking the sequence of
-// variables/functions visited. Using a pointer to a slice allows the
-// slice capacity to grow and limit reallocations.
-func findInitLoopAndExit(n *Node, path *[]*Node, ok map[*Node]bool) {
-	for i, x := range *path {
-		if x == n {
-			reportInitLoopAndExit((*path)[i:])
-			return
-		}
-	}
-
-	// There might be multiple loops involving n; by sorting
-	// references, we deterministically pick the one reported.
-	refers := collectDeps(n.Name.Defn, false).Sorted(func(ni, nj *Node) bool {
-		return ni.Pos.Before(nj.Pos)
-	})
-
-	*path = append(*path, n)
-	for _, ref := range refers {
-		// Short-circuit variables that were initialized.
-		if ref.Class() == PEXTERN && ref.Name.Defn.Initorder() == InitDone || ok[ref] {
-			continue
-		}
-		findInitLoopAndExit(ref, path, ok)
-	}
-
-	// n is not involved in a cycle.
-	// Record that fact to avoid checking it again when reached another way,
-	// or else this traversal will take exponential time traversing all paths
-	// through the part of the package's call graph implicated in the cycle.
-	ok[n] = true
-
-	*path = (*path)[:len(*path)-1]
-}
-
-// reportInitLoopAndExit reports and initialization loop as an error
-// and exits. However, if l is not actually an initialization loop, it
-// simply returns instead.
-func reportInitLoopAndExit(l []*Node) {
-	// Rotate loop so that the earliest variable declaration is at
-	// the start.
-	i := -1
-	for j, n := range l {
-		if n.Class() == PEXTERN && (i == -1 || n.Pos.Before(l[i].Pos)) {
-			i = j
-		}
-	}
-	if i == -1 {
-		// False positive: loop only involves recursive
-		// functions. Return so that findInitLoop can continue
-		// searching.
-		return
-	}
-	l = append(l[i:], l[:i]...)
-
-	// TODO(mdempsky): Method values are printed as "T.m-fm"
-	// rather than "T.m". Figure out how to avoid that.
-
-	var msg bytes.Buffer
-	fmt.Fprintf(&msg, "initialization loop:\n")
-	for _, n := range l {
-		fmt.Fprintf(&msg, "\t%v: %v refers to\n", n.Line(), n)
-	}
-	fmt.Fprintf(&msg, "\t%v: %v", l[0].Line(), l[0])
-
-	yyerrorl(l[0].Pos, msg.String())
-	errorexit()
-}
-
-// collectDeps returns all of the package-level functions and
-// variables that declaration n depends on. If transitive is true,
-// then it also includes the transitive dependencies of any depended
-// upon functions (but not variables).
-func collectDeps(n *Node, transitive bool) NodeSet {
-	d := initDeps{transitive: transitive}
-	switch n.Op {
-	case OAS:
-		d.inspect(n.Right)
-	case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
-		d.inspect(n.Right)
-	case ODCLFUNC:
-		d.inspectList(n.Nbody)
-	default:
-		Fatalf("unexpected Op: %v", n.Op)
-	}
-	return d.seen
-}
-
-type initDeps struct {
-	transitive bool
-	seen       NodeSet
-}
-
-func (d *initDeps) inspect(n *Node)     { inspect(n, d.visit) }
-func (d *initDeps) inspectList(l Nodes) { inspectList(l, d.visit) }
-
-// visit calls foundDep on any package-level functions or variables
-// referenced by n, if any.
-func (d *initDeps) visit(n *Node) bool {
-	switch n.Op {
-	case ONAME:
-		if n.isMethodExpression() {
-			d.foundDep(asNode(n.Type.FuncType().Nname))
-			return false
-		}
-
-		switch n.Class() {
-		case PEXTERN, PFUNC:
-			d.foundDep(n)
-		}
-
-	case OCLOSURE:
-		d.inspectList(n.Func.Closure.Nbody)
-
-	case ODOTMETH, OCALLPART:
-		d.foundDep(asNode(n.Type.FuncType().Nname))
-	}
-
-	return true
-}
-
-// foundDep records that we've found a dependency on n by adding it to
-// seen.
-func (d *initDeps) foundDep(n *Node) {
-	// Can happen with method expressions involving interface
-	// types; e.g., fixedbugs/issue4495.go.
-	if n == nil {
-		return
-	}
-
-	// Names without definitions aren't interesting as far as
-	// initialization ordering goes.
-	if n.Name.Defn == nil {
-		return
-	}
-
-	if d.seen.Has(n) {
-		return
-	}
-	d.seen.Add(n)
-	if d.transitive && n.Class() == PFUNC {
-		d.inspectList(n.Name.Defn.Nbody)
-	}
-}
-
-// declOrder implements heap.Interface, ordering assignment statements
-// by the position of their first LHS expression.
-//
-// N.B., the Pos of the first LHS expression is used because because
-// an OAS node's Pos may not be unique. For example, given the
-// declaration "var a, b = f(), g()", "a" must be ordered before "b",
-// but both OAS nodes use the "=" token's position as their Pos.
-type declOrder []*Node
-
-func (s declOrder) Len() int           { return len(s) }
-func (s declOrder) Less(i, j int) bool { return firstLHS(s[i]).Pos.Before(firstLHS(s[j]).Pos) }
-func (s declOrder) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-
-func (s *declOrder) Push(x interface{}) { *s = append(*s, x.(*Node)) }
-func (s *declOrder) Pop() interface{} {
-	n := (*s)[len(*s)-1]
-	*s = (*s)[:len(*s)-1]
-	return n
-}
-
-// firstLHS returns the first expression on the left-hand side of
-// assignment n.
-func firstLHS(n *Node) *Node {
-	switch n.Op {
-	case OAS:
-		return n.Left
-	case OAS2DOTTYPE, OAS2FUNC, OAS2RECV, OAS2MAPR:
-		return n.List.First()
-	}
-
-	Fatalf("unexpected Op: %v", n.Op)
-	return nil
-}
diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go
deleted file mode 100644
index a8cc010..0000000
--- a/src/cmd/compile/internal/gc/inl.go
+++ /dev/null
@@ -1,1507 +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.
-//
-// The inlining facility makes 2 passes: first caninl determines which
-// functions are suitable for inlining, and for those that are it
-// saves a copy of the body. Then inlcalls walks each function body to
-// 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. Additional levels (beyond -l) may be buggy and
-// are not supported.
-//      0: disabled
-//      1: 80-nodes leaf functions, oneliners, panic, lazy typechecking (default)
-//      2: (unassigned)
-//      3: (unassigned)
-//      4: allow non-leaf functions
-//
-// At some point this may get another default and become switch-offable with -N.
-//
-// 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.
-
-package gc
-
-import (
-	"cmd/compile/internal/logopt"
-	"cmd/compile/internal/types"
-	"cmd/internal/obj"
-	"cmd/internal/src"
-	"fmt"
-	"strings"
-)
-
-// Inlining budget parameters, gathered in one place
-const (
-	inlineMaxBudget       = 80
-	inlineExtraAppendCost = 0
-	// default is to inline if there's at most one call. -l=4 overrides this by using 1 instead.
-	inlineExtraCallCost  = 57              // 57 was benchmarked to provided most benefit with no bad surprises; see https://github.com/golang/go/issues/19348#issuecomment-439370742
-	inlineExtraPanicCost = 1               // do not penalize inlining panics.
-	inlineExtraThrowCost = inlineMaxBudget // with current (2018-05/1.11) code, inlining runtime.throw does not help.
-
-	inlineBigFunctionNodes   = 5000 // Functions with this many nodes are considered "big".
-	inlineBigFunctionMaxCost = 20   // Max cost of inlinee when inlining into a "big" function.
-)
-
-// Get the function's package. For ordinary functions it's on the ->sym, but for imported methods
-// the ->sym can be re-used in the local package, so peel it off the receiver's type.
-func fnpkg(fn *Node) *types.Pkg {
-	if fn.IsMethod() {
-		// method
-		rcvr := fn.Type.Recv().Type
-
-		if rcvr.IsPtr() {
-			rcvr = rcvr.Elem()
-		}
-		if rcvr.Sym == nil {
-			Fatalf("receiver with no sym: [%v] %L  (%v)", fn.Sym, fn, rcvr)
-		}
-		return rcvr.Sym.Pkg
-	}
-
-	// non-method
-	return fn.Sym.Pkg
-}
-
-// Lazy typechecking of imported bodies. For local functions, caninl will set ->typecheck
-// because they're a copy of an already checked body.
-func typecheckinl(fn *Node) {
-	lno := setlineno(fn)
-
-	expandInline(fn)
-
-	// typecheckinl is only for imported functions;
-	// their bodies may refer to unsafe as long as the package
-	// was marked safe during import (which was checked then).
-	// the ->inl of a local function has been typechecked before caninl copied it.
-	pkg := fnpkg(fn)
-
-	if pkg == localpkg || pkg == nil {
-		return // typecheckinl on local function
-	}
-
-	if Debug.m > 2 || Debug_export != 0 {
-		fmt.Printf("typecheck import [%v] %L { %#v }\n", fn.Sym, fn, asNodes(fn.Func.Inl.Body))
-	}
-
-	savefn := Curfn
-	Curfn = fn
-	typecheckslice(fn.Func.Inl.Body, ctxStmt)
-	Curfn = savefn
-
-	// During expandInline (which imports fn.Func.Inl.Body),
-	// declarations are added to fn.Func.Dcl by funcHdr(). Move them
-	// to fn.Func.Inl.Dcl for consistency with how local functions
-	// behave. (Append because typecheckinl may be called multiple
-	// times.)
-	fn.Func.Inl.Dcl = append(fn.Func.Inl.Dcl, fn.Func.Dcl...)
-	fn.Func.Dcl = nil
-
-	lineno = lno
-}
-
-// Caninl determines whether fn is inlineable.
-// If so, caninl saves fn->nbody in fn->inl and substitutes it with a copy.
-// fn and ->nbody will already have been typechecked.
-func caninl(fn *Node) {
-	if fn.Op != ODCLFUNC {
-		Fatalf("caninl %v", fn)
-	}
-	if fn.Func.Nname == nil {
-		Fatalf("caninl no nname %+v", fn)
-	}
-
-	var reason string // reason, if any, that the function was not inlined
-	if Debug.m > 1 || logopt.Enabled() {
-		defer func() {
-			if reason != "" {
-				if Debug.m > 1 {
-					fmt.Printf("%v: cannot inline %v: %s\n", fn.Line(), fn.Func.Nname, reason)
-				}
-				if logopt.Enabled() {
-					logopt.LogOpt(fn.Pos, "cannotInlineFunction", "inline", fn.funcname(), reason)
-				}
-			}
-		}()
-	}
-
-	// If marked "go:noinline", don't inline
-	if fn.Func.Pragma&Noinline != 0 {
-		reason = "marked go:noinline"
-		return
-	}
-
-	// If marked "go:norace" and -race compilation, don't inline.
-	if flag_race && fn.Func.Pragma&Norace != 0 {
-		reason = "marked go:norace with -race compilation"
-		return
-	}
-
-	// If marked "go:nocheckptr" and -d checkptr compilation, don't inline.
-	if Debug_checkptr != 0 && fn.Func.Pragma&NoCheckPtr != 0 {
-		reason = "marked go:nocheckptr"
-		return
-	}
-
-	// If marked "go:cgo_unsafe_args", don't inline, since the
-	// function makes assumptions about its argument frame layout.
-	if fn.Func.Pragma&CgoUnsafeArgs != 0 {
-		reason = "marked go:cgo_unsafe_args"
-		return
-	}
-
-	// If marked as "go:uintptrescapes", don't inline, since the
-	// escape information is lost during inlining.
-	if fn.Func.Pragma&UintptrEscapes != 0 {
-		reason = "marked as having an escaping uintptr argument"
-		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"
-		return
-	}
-
-	if fn.Typecheck() == 0 {
-		Fatalf("caninl on non-typechecked function %v", fn)
-	}
-
-	n := fn.Func.Nname
-	if n.Func.InlinabilityChecked() {
-		return
-	}
-	defer n.Func.SetInlinabilityChecked(true)
-
-	cc := int32(inlineExtraCallCost)
-	if Debug.l == 4 {
-		cc = 1 // this appears to yield better performance than 0.
-	}
-
-	// At this point in the game the function we're looking at may
-	// have "stale" autos, vars that still appear in the Dcl list, but
-	// which no longer have any uses in the function body (due to
-	// elimination by deadcode). We'd like to exclude these dead vars
-	// when creating the "Inline.Dcl" field below; to accomplish this,
-	// the hairyVisitor below builds up a map of used/referenced
-	// locals, and we use this map to produce a pruned Inline.Dcl
-	// list. See issue 25249 for more context.
-
-	visitor := hairyVisitor{
-		budget:        inlineMaxBudget,
-		extraCallCost: cc,
-		usedLocals:    make(map[*Node]bool),
-	}
-	if visitor.visitList(fn.Nbody) {
-		reason = visitor.reason
-		return
-	}
-	if visitor.budget < 0 {
-		reason = fmt.Sprintf("function too complex: cost %d exceeds budget %d", inlineMaxBudget-visitor.budget, inlineMaxBudget)
-		return
-	}
-
-	n.Func.Inl = &Inline{
-		Cost: inlineMaxBudget - visitor.budget,
-		Dcl:  inlcopylist(pruneUnusedAutos(n.Name.Defn.Func.Dcl, &visitor)),
-		Body: inlcopylist(fn.Nbody.Slice()),
-	}
-
-	// hack, TODO, check for better way to link method nodes back to the thing with the ->inl
-	// this is so export can find the body of a method
-	fn.Type.FuncType().Nname = asTypesNode(n)
-
-	if Debug.m > 1 {
-		fmt.Printf("%v: can inline %#v with cost %d as: %#v { %#v }\n", fn.Line(), n, inlineMaxBudget-visitor.budget, fn.Type, asNodes(n.Func.Inl.Body))
-	} else if Debug.m != 0 {
-		fmt.Printf("%v: can inline %v\n", fn.Line(), n)
-	}
-	if logopt.Enabled() {
-		logopt.LogOpt(fn.Pos, "canInlineFunction", "inline", fn.funcname(), fmt.Sprintf("cost: %d", inlineMaxBudget-visitor.budget))
-	}
-}
-
-// 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 {
-		Fatalf("inlFlood: missing Func on %v", n)
-	}
-	if n.Func.Inl == nil {
-		return
-	}
-
-	if n.Func.ExportInline() {
-		return
-	}
-	n.Func.SetExportInline(true)
-
-	typecheckinl(n)
-
-	// Recursively identify all referenced functions for
-	// reexport. We want to include even non-called functions,
-	// because after inlining they might be callable.
-	inspectList(asNodes(n.Func.Inl.Body), func(n *Node) bool {
-		switch n.Op {
-		case ONAME:
-			switch n.Class() {
-			case PFUNC:
-				if n.isMethodExpression() {
-					inlFlood(asNode(n.Type.Nname()))
-				} else {
-					inlFlood(n)
-					exportsym(n)
-				}
-			case PEXTERN:
-				exportsym(n)
-			}
-
-		case ODOTMETH:
-			fn := asNode(n.Type.Nname())
-			inlFlood(fn)
-
-		case OCALLPART:
-			// Okay, because we don't yet inline indirect
-			// calls to method values.
-		case OCLOSURE:
-			// If the closure is inlinable, we'll need to
-			// flood it too. But today we don't support
-			// inlining functions that contain closures.
-			//
-			// When we do, we'll probably want:
-			//     inlFlood(n.Func.Closure.Func.Nname)
-			Fatalf("unexpected closure in inlinable function")
-		}
-		return true
-	})
-}
-
-// hairyVisitor visits a function body to determine its inlining
-// hairiness and whether or not it can be inlined.
-type hairyVisitor struct {
-	budget        int32
-	reason        string
-	extraCallCost int32
-	usedLocals    map[*Node]bool
-}
-
-// Look for anything we want to punt on.
-func (v *hairyVisitor) visitList(ll Nodes) bool {
-	for _, n := range ll.Slice() {
-		if v.visit(n) {
-			return true
-		}
-	}
-	return false
-}
-
-func (v *hairyVisitor) visit(n *Node) bool {
-	if n == nil {
-		return false
-	}
-
-	switch n.Op {
-	// Call is okay if inlinable and we have the budget for the body.
-	case OCALLFUNC:
-		// Functions that call runtime.getcaller{pc,sp} can not be inlined
-		// because getcaller{pc,sp} expect a pointer to the caller's first argument.
-		//
-		// runtime.throw is a "cheap call" like panic in normal code.
-		if n.Left.Op == ONAME && n.Left.Class() == PFUNC && isRuntimePkg(n.Left.Sym.Pkg) {
-			fn := n.Left.Sym.Name
-			if fn == "getcallerpc" || fn == "getcallersp" {
-				v.reason = "call to " + fn
-				return true
-			}
-			if fn == "throw" {
-				v.budget -= inlineExtraThrowCost
-				break
-			}
-		}
-
-		if isIntrinsicCall(n) {
-			// Treat like any other node.
-			break
-		}
-
-		if fn := inlCallee(n.Left); fn != nil && fn.Func.Inl != nil {
-			v.budget -= fn.Func.Inl.Cost
-			break
-		}
-
-		// Call cost for non-leaf inlining.
-		v.budget -= v.extraCallCost
-
-	// Call is okay if inlinable and we have the budget for the body.
-	case OCALLMETH:
-		t := n.Left.Type
-		if t == nil {
-			Fatalf("no function type for [%p] %+v\n", n.Left, n.Left)
-		}
-		if t.Nname() == nil {
-			Fatalf("no function definition for [%p] %+v\n", t, t)
-		}
-		if isRuntimePkg(n.Left.Sym.Pkg) {
-			fn := n.Left.Sym.Name
-			if fn == "heapBits.nextArena" {
-				// Special case: explicitly allow
-				// mid-stack inlining of
-				// runtime.heapBits.next even though
-				// it calls slow-path
-				// runtime.heapBits.nextArena.
-				break
-			}
-		}
-		if inlfn := asNode(t.FuncType().Nname).Func; inlfn.Inl != nil {
-			v.budget -= inlfn.Inl.Cost
-			break
-		}
-		// Call cost for non-leaf inlining.
-		v.budget -= v.extraCallCost
-
-	// Things that are too hairy, irrespective of the budget
-	case OCALL, OCALLINTER:
-		// Call cost for non-leaf inlining.
-		v.budget -= v.extraCallCost
-
-	case OPANIC:
-		v.budget -= inlineExtraPanicCost
-
-	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,
-		ORANGE,
-		OSELECT,
-		OGO,
-		ODEFER,
-		ODCLTYPE, // can't print yet
-		ORETJMP:
-		v.reason = "unhandled op " + n.Op.String()
-		return true
-
-	case OAPPEND:
-		v.budget -= inlineExtraAppendCost
-
-	case ODCLCONST, OEMPTY, OFALL:
-		// These nodes don't produce code; omit from inlining budget.
-		return false
-
-	case OLABEL:
-		// TODO(mdempsky): Add support for inlining labeled control statements.
-		if n.labeledControl() != nil {
-			v.reason = "labeled control"
-			return true
-		}
-
-	case OBREAK, OCONTINUE:
-		if n.Sym != nil {
-			// Should have short-circuited due to labeledControl above.
-			Fatalf("unexpected labeled break/continue: %v", n)
-		}
-
-	case OIF:
-		if Isconst(n.Left, CTBOOL) {
-			// This if and the condition cost nothing.
-			return v.visitList(n.Ninit) || v.visitList(n.Nbody) ||
-				v.visitList(n.Rlist)
-		}
-
-	case ONAME:
-		if n.Class() == PAUTO {
-			v.usedLocals[n] = true
-		}
-
-	}
-
-	v.budget--
-
-	// When debugging, don't stop early, to get full cost of inlining this function
-	if v.budget < 0 && Debug.m < 2 && !logopt.Enabled() {
-		return true
-	}
-
-	return v.visit(n.Left) || v.visit(n.Right) ||
-		v.visitList(n.List) || v.visitList(n.Rlist) ||
-		v.visitList(n.Ninit) || v.visitList(n.Nbody)
-}
-
-// inlcopylist (together with inlcopy) recursively copies a list of nodes, except
-// that it keeps the same ONAME, OTYPE, and OLITERAL nodes. It is used for copying
-// the body and dcls of an inlineable function.
-func inlcopylist(ll []*Node) []*Node {
-	s := make([]*Node, 0, len(ll))
-	for _, n := range ll {
-		s = append(s, inlcopy(n))
-	}
-	return s
-}
-
-func inlcopy(n *Node) *Node {
-	if n == nil {
-		return nil
-	}
-
-	switch n.Op {
-	case ONAME, OTYPE, OLITERAL:
-		return n
-	}
-
-	m := n.copy()
-	if n.Op != OCALLPART && m.Func != nil {
-		Fatalf("unexpected Func: %v", m)
-	}
-	m.Left = inlcopy(n.Left)
-	m.Right = inlcopy(n.Right)
-	m.List.Set(inlcopylist(n.List.Slice()))
-	m.Rlist.Set(inlcopylist(n.Rlist.Slice()))
-	m.Ninit.Set(inlcopylist(n.Ninit.Slice()))
-	m.Nbody.Set(inlcopylist(n.Nbody.Slice()))
-
-	return m
-}
-
-func countNodes(n *Node) int {
-	if n == nil {
-		return 0
-	}
-	cnt := 1
-	cnt += countNodes(n.Left)
-	cnt += countNodes(n.Right)
-	for _, n1 := range n.Ninit.Slice() {
-		cnt += countNodes(n1)
-	}
-	for _, n1 := range n.Nbody.Slice() {
-		cnt += countNodes(n1)
-	}
-	for _, n1 := range n.List.Slice() {
-		cnt += countNodes(n1)
-	}
-	for _, n1 := range n.Rlist.Slice() {
-		cnt += countNodes(n1)
-	}
-	return cnt
-}
-
-// Inlcalls/nodelist/node walks fn's statements and expressions and substitutes any
-// calls made to inlineable functions. This is the external entry point.
-func inlcalls(fn *Node) {
-	savefn := Curfn
-	Curfn = fn
-	maxCost := int32(inlineMaxBudget)
-	if countNodes(fn) >= inlineBigFunctionNodes {
-		maxCost = inlineBigFunctionMaxCost
-	}
-	// Map to keep track of functions that have been inlined at a particular
-	// call site, in order to stop inlining when we reach the beginning of a
-	// recursion cycle again. We don't inline immediately recursive functions,
-	// but allow inlining if there is a recursion cycle of many functions.
-	// Most likely, the inlining will stop before we even hit the beginning of
-	// the cycle again, but the map catches the unusual case.
-	inlMap := make(map[*Node]bool)
-	fn = inlnode(fn, maxCost, inlMap)
-	if fn != Curfn {
-		Fatalf("inlnode replaced curfn")
-	}
-	Curfn = savefn
-}
-
-// Turn an OINLCALL into a statement.
-func inlconv2stmt(n *Node) {
-	n.Op = OBLOCK
-
-	// n->ninit stays
-	n.List.Set(n.Nbody.Slice())
-
-	n.Nbody.Set(nil)
-	n.Rlist.Set(nil)
-}
-
-// Turn an OINLCALL into a single valued expression.
-// The result of inlconv2expr MUST be assigned back to n, e.g.
-// 	n.Left = inlconv2expr(n.Left)
-func inlconv2expr(n *Node) *Node {
-	r := n.Rlist.First()
-	return addinit(r, append(n.Ninit.Slice(), n.Nbody.Slice()...))
-}
-
-// Turn the rlist (with the return values) of the OINLCALL in
-// n into an expression list lumping the ninit and body
-// containing the inlined statements on the first list element so
-// order will be preserved Used in return, oas2func and call
-// statements.
-func inlconv2list(n *Node) []*Node {
-	if n.Op != OINLCALL || n.Rlist.Len() == 0 {
-		Fatalf("inlconv2list %+v\n", n)
-	}
-
-	s := n.Rlist.Slice()
-	s[0] = addinit(s[0], append(n.Ninit.Slice(), n.Nbody.Slice()...))
-	return s
-}
-
-func inlnodelist(l Nodes, maxCost int32, inlMap map[*Node]bool) {
-	s := l.Slice()
-	for i := range s {
-		s[i] = inlnode(s[i], maxCost, inlMap)
-	}
-}
-
-// inlnode recurses over the tree to find inlineable calls, which will
-// be turned into OINLCALLs by mkinlcall. When the recursion comes
-// back up will examine left, right, list, rlist, ninit, ntest, nincr,
-// nbody and nelse and use one of the 4 inlconv/glue functions above
-// to turn the OINLCALL into an expression, a statement, or patch it
-// in to this nodes list or rlist as appropriate.
-// NOTE it makes no sense to pass the glue functions down the
-// recursion to the level where the OINLCALL gets created because they
-// have to edit /this/ n, so you'd have to push that one down as well,
-// but then you may as well do it here.  so this is cleaner and
-// shorter and less complicated.
-// The result of inlnode MUST be assigned back to n, e.g.
-// 	n.Left = inlnode(n.Left)
-func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
-	if n == nil {
-		return n
-	}
-
-	switch n.Op {
-	case ODEFER, OGO:
-		switch n.Left.Op {
-		case OCALLFUNC, OCALLMETH:
-			n.Left.SetNoInline(true)
-		}
-
-	// TODO do them here (or earlier),
-	// so escape analysis can avoid more heapmoves.
-	case OCLOSURE:
-		return n
-	case OCALLMETH:
-		// Prevent inlining some reflect.Value methods when using checkptr,
-		// even when package reflect was compiled without it (#35073).
-		if s := n.Left.Sym; Debug_checkptr != 0 && isReflectPkg(s.Pkg) && (s.Name == "Value.UnsafeAddr" || s.Name == "Value.Pointer") {
-			return n
-		}
-	}
-
-	lno := setlineno(n)
-
-	inlnodelist(n.Ninit, maxCost, inlMap)
-	for _, n1 := range n.Ninit.Slice() {
-		if n1.Op == OINLCALL {
-			inlconv2stmt(n1)
-		}
-	}
-
-	n.Left = inlnode(n.Left, maxCost, inlMap)
-	if n.Left != nil && n.Left.Op == OINLCALL {
-		n.Left = inlconv2expr(n.Left)
-	}
-
-	n.Right = inlnode(n.Right, maxCost, inlMap)
-	if n.Right != nil && n.Right.Op == OINLCALL {
-		if n.Op == OFOR || n.Op == OFORUNTIL {
-			inlconv2stmt(n.Right)
-		} else if n.Op == OAS2FUNC {
-			n.Rlist.Set(inlconv2list(n.Right))
-			n.Right = nil
-			n.Op = OAS2
-			n.SetTypecheck(0)
-			n = typecheck(n, ctxStmt)
-		} else {
-			n.Right = inlconv2expr(n.Right)
-		}
-	}
-
-	inlnodelist(n.List, maxCost, inlMap)
-	if n.Op == OBLOCK {
-		for _, n2 := range n.List.Slice() {
-			if n2.Op == OINLCALL {
-				inlconv2stmt(n2)
-			}
-		}
-	} else {
-		s := n.List.Slice()
-		for i1, n1 := range s {
-			if n1 != nil && n1.Op == OINLCALL {
-				s[i1] = inlconv2expr(s[i1])
-			}
-		}
-	}
-
-	inlnodelist(n.Rlist, maxCost, inlMap)
-	s := n.Rlist.Slice()
-	for i1, n1 := range s {
-		if n1.Op == OINLCALL {
-			if n.Op == OIF {
-				inlconv2stmt(n1)
-			} else {
-				s[i1] = inlconv2expr(s[i1])
-			}
-		}
-	}
-
-	inlnodelist(n.Nbody, maxCost, inlMap)
-	for _, n := range n.Nbody.Slice() {
-		if n.Op == OINLCALL {
-			inlconv2stmt(n)
-		}
-	}
-
-	// with all the branches out of the way, it is now time to
-	// transmogrify this node itself unless inhibited by the
-	// switch at the top of this function.
-	switch n.Op {
-	case OCALLFUNC, OCALLMETH:
-		if n.NoInline() {
-			return n
-		}
-	}
-
-	switch n.Op {
-	case OCALLFUNC:
-		if Debug.m > 3 {
-			fmt.Printf("%v:call to func %+v\n", n.Line(), n.Left)
-		}
-		if isIntrinsicCall(n) {
-			break
-		}
-		if fn := inlCallee(n.Left); fn != nil && fn.Func.Inl != nil {
-			n = mkinlcall(n, fn, maxCost, inlMap)
-		}
-
-	case OCALLMETH:
-		if Debug.m > 3 {
-			fmt.Printf("%v:call to meth %L\n", n.Line(), n.Left.Right)
-		}
-
-		// typecheck should have resolved ODOTMETH->type, whose nname points to the actual function.
-		if n.Left.Type == nil {
-			Fatalf("no function type for [%p] %+v\n", n.Left, n.Left)
-		}
-
-		if n.Left.Type.Nname() == nil {
-			Fatalf("no function definition for [%p] %+v\n", n.Left.Type, n.Left.Type)
-		}
-
-		n = mkinlcall(n, asNode(n.Left.Type.FuncType().Nname), maxCost, inlMap)
-	}
-
-	lineno = lno
-	return n
-}
-
-// inlCallee takes a function-typed expression and returns the underlying function ONAME
-// that it refers to if statically known. Otherwise, it returns nil.
-func inlCallee(fn *Node) *Node {
-	fn = staticValue(fn)
-	switch {
-	case fn.Op == ONAME && fn.Class() == PFUNC:
-		if fn.isMethodExpression() {
-			n := asNode(fn.Type.Nname())
-			// Check that receiver type matches fn.Left.
-			// TODO(mdempsky): Handle implicit dereference
-			// of pointer receiver argument?
-			if n == nil || !types.Identical(n.Type.Recv().Type, fn.Left.Type) {
-				return nil
-			}
-			return n
-		}
-		return fn
-	case fn.Op == OCLOSURE:
-		c := fn.Func.Closure
-		caninl(c)
-		return c.Func.Nname
-	}
-	return nil
-}
-
-func staticValue(n *Node) *Node {
-	for {
-		if n.Op == OCONVNOP {
-			n = n.Left
-			continue
-		}
-
-		n1 := staticValue1(n)
-		if n1 == nil {
-			return n
-		}
-		n = n1
-	}
-}
-
-// staticValue1 implements a simple SSA-like optimization. If n is a local variable
-// that is initialized and never reassigned, staticValue1 returns the initializer
-// expression. Otherwise, it returns nil.
-func staticValue1(n *Node) *Node {
-	if n.Op != ONAME || n.Class() != PAUTO || n.Name.Addrtaken() {
-		return nil
-	}
-
-	defn := n.Name.Defn
-	if defn == nil {
-		return nil
-	}
-
-	var rhs *Node
-FindRHS:
-	switch defn.Op {
-	case OAS:
-		rhs = defn.Right
-	case OAS2:
-		for i, lhs := range defn.List.Slice() {
-			if lhs == n {
-				rhs = defn.Rlist.Index(i)
-				break FindRHS
-			}
-		}
-		Fatalf("%v missing from LHS of %v", n, defn)
-	default:
-		return nil
-	}
-	if rhs == nil {
-		Fatalf("RHS is nil: %v", defn)
-	}
-
-	unsafe, _ := reassigned(n)
-	if unsafe {
-		return nil
-	}
-
-	return rhs
-}
-
-// 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, OSELRECV:
-		if n.Left == v.name && n != v.name.Name.Defn {
-			return n
-		}
-	case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV:
-		for _, p := range n.List.Slice() {
-			if p == v.name && n != v.name.Name.Defn {
-				return n
-			}
-		}
-	case OSELRECV2:
-		if (n.Left == v.name || n.List.First() == v.name) && n != v.name.Name.Defn {
-			return n
-		}
-	}
-	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
-}
-
-func inlParam(t *types.Field, as *Node, inlvars map[*Node]*Node) *Node {
-	n := asNode(t.Nname)
-	if n == nil || n.isBlank() {
-		return nblank
-	}
-
-	inlvar := inlvars[n]
-	if inlvar == nil {
-		Fatalf("missing inlvar for %v", n)
-	}
-	as.Ninit.Append(nod(ODCL, inlvar, nil))
-	inlvar.Name.Defn = as
-	return inlvar
-}
-
-var inlgen int
-
-// If n is a call node (OCALLFUNC or OCALLMETH), and fn is an ONAME node for a
-// function with an inlinable body, return an OINLCALL node that can replace n.
-// The returned node's Ninit has the parameter assignments, the Nbody is the
-// inlined function body, and (List, Rlist) contain the (input, output)
-// parameters.
-// The result of mkinlcall MUST be assigned back to n, e.g.
-// 	n.Left = mkinlcall(n.Left, fn, isddd)
-func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
-	if fn.Func.Inl == nil {
-		if logopt.Enabled() {
-			logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", Curfn.funcname(),
-				fmt.Sprintf("%s cannot be inlined", fn.pkgFuncName()))
-		}
-		return n
-	}
-	if fn.Func.Inl.Cost > maxCost {
-		// The inlined function body is too big. Typically we use this check to restrict
-		// inlining into very big functions.  See issue 26546 and 17566.
-		if logopt.Enabled() {
-			logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", Curfn.funcname(),
-				fmt.Sprintf("cost %d of %s exceeds max large caller cost %d", fn.Func.Inl.Cost, fn.pkgFuncName(), maxCost))
-		}
-		return n
-	}
-
-	if fn == Curfn || fn.Name.Defn == Curfn {
-		// Can't recursively inline a function into itself.
-		if logopt.Enabled() {
-			logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", fmt.Sprintf("recursive call to %s", Curfn.funcname()))
-		}
-		return n
-	}
-
-	if instrumenting && isRuntimePkg(fn.Sym.Pkg) {
-		// Runtime package must not be instrumented.
-		// Instrument skips runtime package. However, some runtime code can be
-		// inlined into other packages and instrumented there. To avoid this,
-		// we disable inlining of runtime functions when instrumenting.
-		// The example that we observed is inlining of LockOSThread,
-		// which lead to false race reports on m contents.
-		return n
-	}
-
-	if inlMap[fn] {
-		if Debug.m > 1 {
-			fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", n.Line(), fn, Curfn.funcname())
-		}
-		return n
-	}
-	inlMap[fn] = true
-	defer func() {
-		inlMap[fn] = false
-	}()
-	if Debug_typecheckinl == 0 {
-		typecheckinl(fn)
-	}
-
-	// We have a function node, and it has an inlineable body.
-	if Debug.m > 1 {
-		fmt.Printf("%v: inlining call to %v %#v { %#v }\n", n.Line(), fn.Sym, fn.Type, asNodes(fn.Func.Inl.Body))
-	} else if Debug.m != 0 {
-		fmt.Printf("%v: inlining call to %v\n", n.Line(), fn)
-	}
-	if Debug.m > 2 {
-		fmt.Printf("%v: Before inlining: %+v\n", n.Line(), n)
-	}
-
-	if ssaDump != "" && ssaDump == Curfn.funcname() {
-		ssaDumpInlined = append(ssaDumpInlined, fn)
-	}
-
-	ninit := n.Ninit
-
-	// For normal function calls, the function callee expression
-	// may contain side effects (e.g., added by addinit during
-	// inlconv2expr or inlconv2list). Make sure to preserve these,
-	// if necessary (#42703).
-	if n.Op == OCALLFUNC {
-		callee := n.Left
-		for callee.Op == OCONVNOP {
-			ninit.AppendNodes(&callee.Ninit)
-			callee = callee.Left
-		}
-		if callee.Op != ONAME && callee.Op != OCLOSURE {
-			Fatalf("unexpected callee expression: %v", callee)
-		}
-	}
-
-	// Make temp names to use instead of the originals.
-	inlvars := make(map[*Node]*Node)
-
-	// record formals/locals for later post-processing
-	var inlfvars []*Node
-
-	// Handle captured variables when inlining closures.
-	if fn.Name.Defn != nil {
-		if c := fn.Name.Defn.Func.Closure; c != nil {
-			for _, v := range c.Func.Closure.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), ctxExpr)
-					ninit.Append(nod(ODCL, iv, nil))
-					ninit.Append(typecheck(nod(OAS, iv, o), ctxStmt))
-					inlvars[v] = iv
-				} else {
-					addr := newname(lookup("&" + v.Sym.Name))
-					addr.Type = types.NewPtr(v.Type)
-					ia := typecheck(inlvar(addr), ctxExpr)
-					ninit.Append(nod(ODCL, ia, nil))
-					ninit.Append(typecheck(nod(OAS, ia, nod(OADDR, o, nil)), ctxStmt))
-					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(ODEREF, ia, nil), ctxExpr)
-				}
-			}
-		}
-	}
-
-	for _, ln := range fn.Func.Inl.Dcl {
-		if ln.Op != ONAME {
-			continue
-		}
-		if ln.Class() == PPARAMOUT { // return values handled below.
-			continue
-		}
-		if ln.isParamStackCopy() { // ignore the on-stack copy of a parameter that moved to the heap
-			// TODO(mdempsky): Remove once I'm confident
-			// this never actually happens. We currently
-			// perform inlining before escape analysis, so
-			// nothing should have moved to the heap yet.
-			Fatalf("impossible: %v", ln)
-		}
-		inlf := typecheck(inlvar(ln), ctxExpr)
-		inlvars[ln] = inlf
-		if genDwarfInline > 0 {
-			if ln.Class() == PPARAM {
-				inlf.Name.SetInlFormal(true)
-			} else {
-				inlf.Name.SetInlLocal(true)
-			}
-			inlf.Pos = ln.Pos
-			inlfvars = append(inlfvars, inlf)
-		}
-	}
-
-	// We can delay declaring+initializing result parameters if:
-	// (1) there's exactly one "return" statement in the inlined function;
-	// (2) it's not an empty return statement (#44355); and
-	// (3) the result parameters aren't named.
-	delayretvars := true
-
-	nreturns := 0
-	inspectList(asNodes(fn.Func.Inl.Body), func(n *Node) bool {
-		if n != nil && n.Op == ORETURN {
-			nreturns++
-			if n.List.Len() == 0 {
-				delayretvars = false // empty return statement (case 2)
-			}
-		}
-		return true
-	})
-
-	if nreturns != 1 {
-		delayretvars = false // not exactly one return statement (case 1)
-	}
-
-	// temporaries for return values.
-	var retvars []*Node
-	for i, t := range fn.Type.Results().Fields().Slice() {
-		var m *Node
-		if n := asNode(t.Nname); n != nil && !n.isBlank() && !strings.HasPrefix(n.Sym.Name, "~r") {
-			m = inlvar(n)
-			m = typecheck(m, ctxExpr)
-			inlvars[n] = m
-			delayretvars = false // found a named result parameter (case 3)
-		} else {
-			// anonymous return values, synthesize names for use in assignment that replaces return
-			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.Name.SetInlFormal(true)
-				m.Pos = t.Pos
-				inlfvars = append(inlfvars, m)
-			}
-		}
-
-		retvars = append(retvars, m)
-	}
-
-	// Assign arguments to the parameters' temp names.
-	as := nod(OAS2, nil, nil)
-	as.SetColas(true)
-	if n.Op == OCALLMETH {
-		if n.Left.Left == nil {
-			Fatalf("method call without receiver: %+v", n)
-		}
-		as.Rlist.Append(n.Left.Left)
-	}
-	as.Rlist.Append(n.List.Slice()...)
-
-	// For non-dotted calls to variadic functions, we assign the
-	// variadic parameter's temp name separately.
-	var vas *Node
-
-	if recv := fn.Type.Recv(); recv != nil {
-		as.List.Append(inlParam(recv, as, inlvars))
-	}
-	for _, param := range fn.Type.Params().Fields().Slice() {
-		// For ordinary parameters or variadic parameters in
-		// dotted calls, just add the variable to the
-		// assignment list, and we're done.
-		if !param.IsDDD() || n.IsDDD() {
-			as.List.Append(inlParam(param, as, inlvars))
-			continue
-		}
-
-		// Otherwise, we need to collect the remaining values
-		// to pass as a slice.
-
-		x := as.List.Len()
-		for as.List.Len() < as.Rlist.Len() {
-			as.List.Append(argvar(param.Type, as.List.Len()))
-		}
-		varargs := as.List.Slice()[x:]
-
-		vas = nod(OAS, nil, nil)
-		vas.Left = inlParam(param, vas, inlvars)
-		if len(varargs) == 0 {
-			vas.Right = nodnil()
-			vas.Right.Type = param.Type
-		} else {
-			vas.Right = nod(OCOMPLIT, nil, typenod(param.Type))
-			vas.Right.List.Set(varargs)
-		}
-	}
-
-	if as.Rlist.Len() != 0 {
-		as = typecheck(as, ctxStmt)
-		ninit.Append(as)
-	}
-
-	if vas != nil {
-		vas = typecheck(vas, ctxStmt)
-		ninit.Append(vas)
-	}
-
-	if !delayretvars {
-		// Zero the return parameters.
-		for _, n := range retvars {
-			ninit.Append(nod(ODCL, n, nil))
-			ras := nod(OAS, n, nil)
-			ras = typecheck(ras, ctxStmt)
-			ninit.Append(ras)
-		}
-	}
-
-	retlabel := autolabel(".i")
-
-	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())
-
-	// Add an inline mark just before the inlined body.
-	// This mark is inline in the code so that it's a reasonable spot
-	// to put a breakpoint. Not sure if that's really necessary or not
-	// (in which case it could go at the end of the function instead).
-	// Note issue 28603.
-	inlMark := nod(OINLMARK, nil, nil)
-	inlMark.Pos = n.Pos.WithIsStmt()
-	inlMark.Xoffset = int64(newIndex)
-	ninit.Append(inlMark)
-
-	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,
-		delayretvars: delayretvars,
-		inlvars:      inlvars,
-		bases:        make(map[*src.PosBase]*src.PosBase),
-		newInlIndex:  newIndex,
-	}
-
-	body := subst.list(asNodes(fn.Func.Inl.Body))
-
-	lab := nodSym(OLABEL, nil, retlabel)
-	body = append(body, lab)
-
-	typecheckslice(body, ctxStmt)
-
-	if genDwarfInline > 0 {
-		for _, v := range inlfvars {
-			v.Pos = subst.updatedPos(v.Pos)
-		}
-	}
-
-	//dumplist("ninit post", ninit);
-
-	call := nod(OINLCALL, nil, nil)
-	call.Ninit.Set(ninit.Slice())
-	call.Nbody.Set(body)
-	call.Rlist.Set(retvars)
-	call.Type = n.Type
-	call.SetTypecheck(1)
-
-	// 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.
-	inlnodelist(call.Nbody, maxCost, inlMap)
-	for _, n := range call.Nbody.Slice() {
-		if n.Op == OINLCALL {
-			inlconv2stmt(n)
-		}
-	}
-
-	if Debug.m > 2 {
-		fmt.Printf("%v: After inlining %+v\n\n", call.Line(), call)
-	}
-
-	return call
-}
-
-// Every time we expand a function we generate a new set of tmpnames,
-// PAUTO's in the calling functions, and link them off of the
-// PPARAM's, PAUTOS and PPARAMOUTs of the called function.
-func inlvar(var_ *Node) *Node {
-	if Debug.m > 3 {
-		fmt.Printf("inlvar %+v\n", var_)
-	}
-
-	n := newname(var_.Sym)
-	n.Type = var_.Type
-	n.SetClass(PAUTO)
-	n.Name.SetUsed(true)
-	n.Name.Curfn = Curfn // the calling function, not the called one
-	n.Name.SetAddrtaken(var_.Name.Addrtaken())
-
-	Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
-	return n
-}
-
-// 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.Type = t.Type
-	n.SetClass(PAUTO)
-	n.Name.SetUsed(true)
-	n.Name.Curfn = Curfn // the calling function, not the called one
-	Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
-	return n
-}
-
-// Synthesize a variable to store the inlined function's arguments
-// when they come from a multiple return call.
-func argvar(t *types.Type, i int) *Node {
-	n := newname(lookupN("~arg", i))
-	n.Type = t.Elem()
-	n.SetClass(PAUTO)
-	n.Name.SetUsed(true)
-	n.Name.Curfn = Curfn // the calling function, not the called one
-	Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
-	return n
-}
-
-// The inlsubst type implements the actual inlining of a single
-// function call.
-type inlsubst struct {
-	// Target of the goto substituted in place of a return.
-	retlabel *types.Sym
-
-	// Temporary result variables.
-	retvars []*Node
-
-	// Whether result variables should be initialized at the
-	// "return" statement.
-	delayretvars bool
-
-	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.
-func (subst *inlsubst) list(ll Nodes) []*Node {
-	s := make([]*Node, 0, ll.Len())
-	for _, n := range ll.Slice() {
-		s = append(s, subst.node(n))
-	}
-	return s
-}
-
-// node recursively copies a node from the saved pristine body of the
-// inlined function, substituting references to input/output
-// parameters with ones to the tmpnames, and substituting returns with
-// assignments to the output.
-func (subst *inlsubst) node(n *Node) *Node {
-	if n == nil {
-		return nil
-	}
-
-	switch n.Op {
-	case ONAME:
-		if inlvar := subst.inlvars[n]; inlvar != nil { // These will be set during inlnode
-			if Debug.m > 2 {
-				fmt.Printf("substituting name %+v  ->  %+v\n", n, inlvar)
-			}
-			return inlvar
-		}
-
-		if Debug.m > 2 {
-			fmt.Printf("not substituting name %+v\n", n)
-		}
-		return n
-
-	case OLITERAL, OTYPE:
-		// If n is a named constant or type, we can continue
-		// using it in the inline copy. Otherwise, make a copy
-		// so we can update the line number.
-		if n.Sym != nil {
-			return n
-		}
-
-		// Since we don't handle bodies with closures, this return is guaranteed to belong to the current inlined function.
-
-	//		dump("Return before substitution", n);
-	case ORETURN:
-		m := nodSym(OGOTO, nil, subst.retlabel)
-		m.Ninit.Set(subst.list(n.Ninit))
-
-		if len(subst.retvars) != 0 && n.List.Len() != 0 {
-			as := nod(OAS2, nil, nil)
-
-			// Make a shallow copy of retvars.
-			// Otherwise OINLCALL.Rlist will be the same list,
-			// and later walk and typecheck may clobber it.
-			for _, n := range subst.retvars {
-				as.List.Append(n)
-			}
-			as.Rlist.Set(subst.list(n.List))
-
-			if subst.delayretvars {
-				for _, n := range as.List.Slice() {
-					as.Ninit.Append(nod(ODCL, n, nil))
-					n.Name.Defn = as
-				}
-			}
-
-			as = typecheck(as, ctxStmt)
-			m.Ninit.Append(as)
-		}
-
-		typecheckslice(m.Ninit.Slice(), ctxStmt)
-		m = typecheck(m, ctxStmt)
-
-		//		dump("Return after substitution", m);
-		return m
-
-	case OGOTO, OLABEL:
-		m := n.copy()
-		m.Pos = subst.updatedPos(m.Pos)
-		m.Ninit.Set(nil)
-		p := fmt.Sprintf("%s·%d", n.Sym.Name, inlgen)
-		m.Sym = lookup(p)
-
-		return m
-	}
-
-	m := n.copy()
-	m.Pos = subst.updatedPos(m.Pos)
-	m.Ninit.Set(nil)
-
-	if n.Op == OCLOSURE {
-		Fatalf("cannot inline function containing closure: %+v", n)
-	}
-
-	m.Left = subst.node(n.Left)
-	m.Right = subst.node(n.Right)
-	m.List.Set(subst.list(n.List))
-	m.Rlist.Set(subst.list(n.Rlist))
-	m.Ninit.Set(append(m.Ninit.Slice(), subst.list(n.Ninit)...))
-	m.Nbody.Set(subst.list(n.Nbody))
-
-	return m
-}
-
-func (subst *inlsubst) updatedPos(xpos src.XPos) src.XPos {
-	pos := Ctxt.PosTable.Pos(xpos)
-	oldbase := pos.Base() // can be nil
-	newbase := subst.bases[oldbase]
-	if newbase == nil {
-		newbase = src.NewInliningBase(oldbase, subst.newInlIndex)
-		subst.bases[oldbase] = newbase
-	}
-	pos.SetBase(newbase)
-	return Ctxt.PosTable.XPos(pos)
-}
-
-func pruneUnusedAutos(ll []*Node, vis *hairyVisitor) []*Node {
-	s := make([]*Node, 0, len(ll))
-	for _, n := range ll {
-		if n.Class() == PAUTO {
-			if _, found := vis.usedLocals[n]; !found {
-				continue
-			}
-		}
-		s = append(s, n)
-	}
-	return s
-}
-
-// devirtualize replaces interface method calls within fn with direct
-// concrete-type method calls where applicable.
-func devirtualize(fn *Node) {
-	Curfn = fn
-	inspectList(fn.Nbody, func(n *Node) bool {
-		if n.Op == OCALLINTER {
-			devirtualizeCall(n)
-		}
-		return true
-	})
-}
-
-func devirtualizeCall(call *Node) {
-	recv := staticValue(call.Left.Left)
-	if recv.Op != OCONVIFACE {
-		return
-	}
-
-	typ := recv.Left.Type
-	if typ.IsInterface() {
-		return
-	}
-
-	x := nodl(call.Left.Pos, ODOTTYPE, call.Left.Left, nil)
-	x.Type = typ
-	x = nodlSym(call.Left.Pos, OXDOT, x, call.Left.Sym)
-	x = typecheck(x, ctxExpr|ctxCallee)
-	switch x.Op {
-	case ODOTMETH:
-		if Debug.m != 0 {
-			Warnl(call.Pos, "devirtualizing %v to %v", call.Left, typ)
-		}
-		call.Op = OCALLMETH
-		call.Left = x
-	case ODOTINTER:
-		// Promoted method from embedded interface-typed field (#42279).
-		if Debug.m != 0 {
-			Warnl(call.Pos, "partially devirtualizing %v to %v", call.Left, typ)
-		}
-		call.Op = OCALLINTER
-		call.Left = x
-	default:
-		// TODO(mdempsky): Turn back into Fatalf after more testing.
-		if Debug.m != 0 {
-			Warnl(call.Pos, "failed to devirtualize %v (%v)", x, x.Op)
-		}
-		return
-	}
-
-	// Duplicated logic from typecheck for function call return
-	// value types.
-	//
-	// Receiver parameter size may have changed; need to update
-	// call.Type to get correct stack offsets for result
-	// parameters.
-	checkwidth(x.Type)
-	switch ft := x.Type; ft.NumResults() {
-	case 0:
-	case 1:
-		call.Type = ft.Results().Field(0).Type
-	default:
-		call.Type = ft.Results()
-	}
-}
diff --git a/src/cmd/compile/internal/gc/inl_test.go b/src/cmd/compile/internal/gc/inl_test.go
deleted file mode 100644
index 02735e5..0000000
--- a/src/cmd/compile/internal/gc/inl_test.go
+++ /dev/null
@@ -1,269 +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 gc
-
-import (
-	"bufio"
-	"internal/testenv"
-	"io"
-	"math/bits"
-	"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 inlinable. If they have no callers in their packages, they
-	// might not actually be inlined anywhere.
-	want := map[string][]string{
-		"runtime": {
-			"add",
-			"acquirem",
-			"add1",
-			"addb",
-			"adjustpanics",
-			"adjustpointer",
-			"alignDown",
-			"alignUp",
-			"bucketMask",
-			"bucketShift",
-			"chanbuf",
-			"deferArgs",
-			"deferclass",
-			"evacuated",
-			"fastlog2",
-			"fastrand",
-			"float64bits",
-			"funcPC",
-			"getArgInfoFast",
-			"getm",
-			"getMCache",
-			"isDirectIface",
-			"itabHashFunc",
-			"noescape",
-			"pcvalueCacheKey",
-			"readUnaligned32",
-			"readUnaligned64",
-			"releasem",
-			"roundupsize",
-			"stackmapdata",
-			"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",
-			"markBits.isMarked",
-			"muintptr.ptr",
-			"puintptr.ptr",
-			"spanOf",
-			"spanOfUnchecked",
-			"(*gcWork).putFast",
-			"(*gcWork).tryGetFast",
-			"(*guintptr).set",
-			"(*markBits).advance",
-			"(*mspan).allocBitsForIndex",
-			"(*mspan).base",
-			"(*mspan).markBitsForBase",
-			"(*mspan).markBitsForIndex",
-			"(*muintptr).set",
-			"(*puintptr).set",
-		},
-		"runtime/internal/sys": {},
-		"runtime/internal/math": {
-			"MulUintptr",
-		},
-		"bytes": {
-			"(*Buffer).Bytes",
-			"(*Buffer).Cap",
-			"(*Buffer).Len",
-			"(*Buffer).Grow",
-			"(*Buffer).Next",
-			"(*Buffer).Read",
-			"(*Buffer).ReadByte",
-			"(*Buffer).Reset",
-			"(*Buffer).String",
-			"(*Buffer).UnreadByte",
-			"(*Buffer).tryGrowByReslice",
-		},
-		"compress/flate": {
-			"byLiteral.Len",
-			"byLiteral.Less",
-			"byLiteral.Swap",
-			"(*dictDecoder).tryWriteCopy",
-		},
-		"encoding/base64": {
-			"assemble32",
-			"assemble64",
-		},
-		"unicode/utf8": {
-			"FullRune",
-			"FullRuneInString",
-			"RuneLen",
-			"ValidRune",
-		},
-		"reflect": {
-			"Value.CanAddr",
-			"Value.CanSet",
-			"Value.CanInterface",
-			"Value.IsValid",
-			"Value.pointer",
-			"add",
-			"align",
-			"flag.mustBe",
-			"flag.mustBeAssignable",
-			"flag.mustBeExported",
-			"flag.kind",
-			"flag.ro",
-		},
-		"regexp": {
-			"(*bitState).push",
-		},
-		"math/big": {
-			"bigEndianWord",
-			// The following functions require the math_big_pure_go build tag.
-			"addVW",
-			"subVW",
-		},
-		"math/rand": {
-			"(*rngSource).Int63",
-			"(*rngSource).Uint64",
-		},
-	}
-
-	if runtime.GOARCH != "386" && runtime.GOARCH != "mips64" && runtime.GOARCH != "mips64le" && runtime.GOARCH != "riscv64" {
-		// 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 and riscv64, 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")
-	}
-	if bits.UintSize == 64 {
-		// rotl_31 is only defined on 64-bit architectures
-		want["runtime"] = append(want["runtime"], "rotl_31")
-	}
-
-	switch runtime.GOARCH {
-	case "386", "wasm", "arm":
-	default:
-		// TODO(mvdan): As explained in /test/inline_sync.go, some
-		// architectures don't have atomic intrinsics, so these go over
-		// the inlining budget. Move back to the main table once that
-		// problem is solved.
-		want["sync"] = []string{
-			"(*Mutex).Lock",
-			"(*Mutex).Unlock",
-			"(*RWMutex).RLock",
-			"(*RWMutex).RUnlock",
-			"(*Once).Do",
-		}
-	}
-
-	// Functions that must actually be inlined; they must have actual callers.
-	must := map[string]bool{
-		"compress/flate.byLiteral.Len":  true,
-		"compress/flate.byLiteral.Less": true,
-		"compress/flate.byLiteral.Swap": true,
-	}
-
-	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", "-tags=math_big_pure_go"}, 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 ([^ ]*)`)
-	haveInlined := regexp.MustCompile(`: inlining call to ([^ ]*)`)
-	cannotInline := regexp.MustCompile(`: cannot inline ([^ ]*): (.*)`)
-	for scanner.Scan() {
-		line := scanner.Text()
-		if strings.HasPrefix(line, "# ") {
-			curPkg = line[2:]
-			continue
-		}
-		if m := haveInlined.FindStringSubmatch(line); m != nil {
-			fname := m[1]
-			delete(notInlinedReason, curPkg+"."+fname)
-			continue
-		}
-		if m := canInline.FindStringSubmatch(line); m != nil {
-			fname := m[1]
-			fullname := curPkg + "." + fname
-			// If function must be inlined somewhere, being inlinable is not enough
-			if _, ok := must[fullname]; !ok {
-				delete(notInlinedReason, fullname)
-				continue
-			}
-		}
-		if m := cannotInline.FindStringSubmatch(line); m != nil {
-			fname, reason := m[1], m[2]
-			fullName := curPkg + "." + fname
-			if _, ok := notInlinedReason[fullName]; ok {
-				// cmd/compile gave us a reason why
-				notInlinedReason[fullName] = reason
-			}
-			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/lang_test.go b/src/cmd/compile/internal/gc/lang_test.go
deleted file mode 100644
index 72e7f07..0000000
--- a/src/cmd/compile/internal/gc/lang_test.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
-	"internal/testenv"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"testing"
-)
-
-const aliasSrc = `
-package x
-
-type T = int
-`
-
-func TestInvalidLang(t *testing.T) {
-	t.Parallel()
-
-	testenv.MustHaveGoBuild(t)
-
-	dir, err := ioutil.TempDir("", "TestInvalidLang")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
-
-	src := filepath.Join(dir, "alias.go")
-	if err := ioutil.WriteFile(src, []byte(aliasSrc), 0644); err != nil {
-		t.Fatal(err)
-	}
-
-	outfile := filepath.Join(dir, "alias.o")
-
-	if testLang(t, "go9.99", src, outfile) == nil {
-		t.Error("compilation with -lang=go9.99 succeeded unexpectedly")
-	}
-
-	// This test will have to be adjusted if we ever reach 1.99 or 2.0.
-	if testLang(t, "go1.99", src, outfile) == nil {
-		t.Error("compilation with -lang=go1.99 succeeded unexpectedly")
-	}
-
-	if testLang(t, "go1.8", src, outfile) == nil {
-		t.Error("compilation with -lang=go1.8 succeeded unexpectedly")
-	}
-
-	if err := testLang(t, "go1.9", src, outfile); err != nil {
-		t.Errorf("compilation with -lang=go1.9 failed unexpectedly: %v", err)
-	}
-}
-
-func testLang(t *testing.T, lang, src, outfile string) error {
-	run := []string{testenv.GoToolPath(t), "tool", "compile", "-lang", lang, "-o", outfile, src}
-	t.Log(run)
-	out, err := exec.Command(run[0], run[1:]...).CombinedOutput()
-	t.Logf("%s", out)
-	return err
-}
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
deleted file mode 100644
index 7cce371..0000000
--- a/src/cmd/compile/internal/gc/lex.go
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2009 The Go Authors. 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/compile/internal/syntax"
-	"cmd/internal/objabi"
-	"cmd/internal/src"
-	"fmt"
-	"strings"
-)
-
-// lineno is the source position at the start of the most recently lexed token.
-// TODO(gri) rename and eventually remove
-var lineno src.XPos
-
-func makePos(base *src.PosBase, line, col uint) src.XPos {
-	return Ctxt.PosTable.XPos(src.MakePos(base, line, col))
-}
-
-func isSpace(c rune) bool {
-	return c == ' ' || c == '\t' || c == '\n' || c == '\r'
-}
-
-func isQuoted(s string) bool {
-	return len(s) >= 2 && s[0] == '"' && s[len(s)-1] == '"'
-}
-
-type PragmaFlag int16
-
-const (
-	// Func pragmas.
-	Nointerface    PragmaFlag = 1 << iota
-	Noescape                  // func parameters don't escape
-	Norace                    // func must not have race detector annotations
-	Nosplit                   // func should not execute on separate stack
-	Noinline                  // func should not be inlined
-	NoCheckPtr                // func should not be instrumented by checkptr
-	CgoUnsafeArgs             // treat a pointer to one arg as a pointer to them all
-	UintptrEscapes            // pointers converted to uintptr escape
-
-	// Runtime-only func pragmas.
-	// See ../../../../runtime/README.md for detailed descriptions.
-	Systemstack        // func must run on system stack
-	Nowritebarrier     // emit compiler error instead of write barrier
-	Nowritebarrierrec  // error on write barrier in this or recursive callees
-	Yeswritebarrierrec // cancels Nowritebarrierrec in this function and callees
-
-	// Runtime and cgo type pragmas
-	NotInHeap // values of this type must not be heap allocated
-
-	// Go command pragmas
-	GoBuildPragma
-)
-
-const (
-	FuncPragmas = Nointerface |
-		Noescape |
-		Norace |
-		Nosplit |
-		Noinline |
-		NoCheckPtr |
-		CgoUnsafeArgs |
-		UintptrEscapes |
-		Systemstack |
-		Nowritebarrier |
-		Nowritebarrierrec |
-		Yeswritebarrierrec
-
-	TypePragmas = NotInHeap
-)
-
-func pragmaFlag(verb string) PragmaFlag {
-	switch verb {
-	case "go:build":
-		return GoBuildPragma
-	case "go:nointerface":
-		if objabi.Fieldtrack_enabled != 0 {
-			return Nointerface
-		}
-	case "go:noescape":
-		return Noescape
-	case "go:norace":
-		return Norace
-	case "go:nosplit":
-		return Nosplit | NoCheckPtr // implies NoCheckPtr (see #34972)
-	case "go:noinline":
-		return Noinline
-	case "go:nocheckptr":
-		return NoCheckPtr
-	case "go:systemstack":
-		return Systemstack
-	case "go:nowritebarrier":
-		return Nowritebarrier
-	case "go:nowritebarrierrec":
-		return Nowritebarrierrec | Nowritebarrier // implies Nowritebarrier
-	case "go:yeswritebarrierrec":
-		return Yeswritebarrierrec
-	case "go:cgo_unsafe_args":
-		return CgoUnsafeArgs | NoCheckPtr // implies NoCheckPtr (see #34968)
-	case "go:uintptrescapes":
-		// For the next function declared in the file
-		// any uintptr arguments may be pointer values
-		// converted to uintptr. This directive
-		// ensures that the referenced allocated
-		// object, if any, is retained and not moved
-		// until the call completes, even though from
-		// the types alone it would appear that the
-		// object is no longer needed during the
-		// call. The conversion to uintptr must appear
-		// in the argument list.
-		// Used in syscall/dll_windows.go.
-		return UintptrEscapes
-	case "go:notinheap":
-		return NotInHeap
-	}
-	return 0
-}
-
-// pragcgo is called concurrently if files are parsed concurrently.
-func (p *noder) pragcgo(pos syntax.Pos, text string) {
-	f := pragmaFields(text)
-
-	verb := strings.TrimPrefix(f[0], "go:")
-	f[0] = verb
-
-	switch verb {
-	case "cgo_export_static", "cgo_export_dynamic":
-		switch {
-		case len(f) == 2 && !isQuoted(f[1]):
-		case len(f) == 3 && !isQuoted(f[1]) && !isQuoted(f[2]):
-		default:
-			p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf(`usage: //go:%s local [remote]`, verb)})
-			return
-		}
-	case "cgo_import_dynamic":
-		switch {
-		case len(f) == 2 && !isQuoted(f[1]):
-		case len(f) == 3 && !isQuoted(f[1]) && !isQuoted(f[2]):
-		case len(f) == 4 && !isQuoted(f[1]) && !isQuoted(f[2]) && isQuoted(f[3]):
-			f[3] = strings.Trim(f[3], `"`)
-			if objabi.GOOS == "aix" && f[3] != "" {
-				// On Aix, library pattern must be "lib.a/object.o"
-				// or "lib.a/libname.so.X"
-				n := strings.Split(f[3], "/")
-				if len(n) != 2 || !strings.HasSuffix(n[0], ".a") || (!strings.HasSuffix(n[1], ".o") && !strings.Contains(n[1], ".so.")) {
-					p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_dynamic local [remote ["lib.a/object.o"]]`})
-					return
-				}
-			}
-		default:
-			p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_dynamic local [remote ["library"]]`})
-			return
-		}
-	case "cgo_import_static":
-		switch {
-		case len(f) == 2 && !isQuoted(f[1]):
-		default:
-			p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_static local`})
-			return
-		}
-	case "cgo_dynamic_linker":
-		switch {
-		case len(f) == 2 && isQuoted(f[1]):
-			f[1] = strings.Trim(f[1], `"`)
-		default:
-			p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_dynamic_linker "path"`})
-			return
-		}
-	case "cgo_ldflag":
-		switch {
-		case len(f) == 2 && isQuoted(f[1]):
-			f[1] = strings.Trim(f[1], `"`)
-		default:
-			p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_ldflag "arg"`})
-			return
-		}
-	default:
-		return
-	}
-	p.pragcgobuf = append(p.pragcgobuf, f)
-}
-
-// pragmaFields is similar to strings.FieldsFunc(s, isSpace)
-// but does not split when inside double quoted regions and always
-// splits before the start and after the end of a double quoted region.
-// pragmaFields does not recognize escaped quotes. If a quote in s is not
-// closed the part after the opening quote will not be returned as a field.
-func pragmaFields(s string) []string {
-	var a []string
-	inQuote := false
-	fieldStart := -1 // Set to -1 when looking for start of field.
-	for i, c := range s {
-		switch {
-		case c == '"':
-			if inQuote {
-				inQuote = false
-				a = append(a, s[fieldStart:i+1])
-				fieldStart = -1
-			} else {
-				inQuote = true
-				if fieldStart >= 0 {
-					a = append(a, s[fieldStart:i])
-				}
-				fieldStart = i
-			}
-		case !inQuote && isSpace(c):
-			if fieldStart >= 0 {
-				a = append(a, s[fieldStart:i])
-				fieldStart = -1
-			}
-		default:
-			if fieldStart == -1 {
-				fieldStart = i
-			}
-		}
-	}
-	if !inQuote && fieldStart >= 0 { // Last field might end at the end of the string.
-		a = append(a, s[fieldStart:])
-	}
-	return a
-}
diff --git a/src/cmd/compile/internal/gc/lex_test.go b/src/cmd/compile/internal/gc/lex_test.go
deleted file mode 100644
index b2081a1..0000000
--- a/src/cmd/compile/internal/gc/lex_test.go
+++ /dev/null
@@ -1,121 +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.
-
-package gc
-
-import (
-	"cmd/compile/internal/syntax"
-	"reflect"
-	"runtime"
-	"testing"
-)
-
-func eq(a, b []string) bool {
-	if len(a) != len(b) {
-		return false
-	}
-	for i := 0; i < len(a); i++ {
-		if a[i] != b[i] {
-			return false
-		}
-	}
-	return true
-}
-
-func TestPragmaFields(t *testing.T) {
-	var tests = []struct {
-		in   string
-		want []string
-	}{
-		{"", []string{}},
-		{" \t ", []string{}},
-		{`""""`, []string{`""`, `""`}},
-		{"  a'b'c  ", []string{"a'b'c"}},
-		{"1 2 3 4", []string{"1", "2", "3", "4"}},
-		{"\n☺\t☹\n", []string{"☺", "☹"}},
-		{`"1 2 "  3  " 4 5"`, []string{`"1 2 "`, `3`, `" 4 5"`}},
-		{`"1""2 3""4"`, []string{`"1"`, `"2 3"`, `"4"`}},
-		{`12"34"`, []string{`12`, `"34"`}},
-		{`12"34 `, []string{`12`}},
-	}
-
-	for _, tt := range tests {
-		got := pragmaFields(tt.in)
-		if !eq(got, tt.want) {
-			t.Errorf("pragmaFields(%q) = %v; want %v", tt.in, got, tt.want)
-			continue
-		}
-	}
-}
-
-func TestPragcgo(t *testing.T) {
-	type testStruct struct {
-		in   string
-		want []string
-	}
-
-	var tests = []testStruct{
-		{`go:cgo_export_dynamic local`, []string{`cgo_export_dynamic`, `local`}},
-		{`go:cgo_export_dynamic local remote`, []string{`cgo_export_dynamic`, `local`, `remote`}},
-		{`go:cgo_export_dynamic local' remote'`, []string{`cgo_export_dynamic`, `local'`, `remote'`}},
-		{`go:cgo_export_static local`, []string{`cgo_export_static`, `local`}},
-		{`go:cgo_export_static local remote`, []string{`cgo_export_static`, `local`, `remote`}},
-		{`go:cgo_export_static local' remote'`, []string{`cgo_export_static`, `local'`, `remote'`}},
-		{`go:cgo_import_dynamic local`, []string{`cgo_import_dynamic`, `local`}},
-		{`go:cgo_import_dynamic local remote`, []string{`cgo_import_dynamic`, `local`, `remote`}},
-		{`go:cgo_import_static local`, []string{`cgo_import_static`, `local`}},
-		{`go:cgo_import_static local'`, []string{`cgo_import_static`, `local'`}},
-		{`go:cgo_dynamic_linker "/path/"`, []string{`cgo_dynamic_linker`, `/path/`}},
-		{`go:cgo_dynamic_linker "/p ath/"`, []string{`cgo_dynamic_linker`, `/p ath/`}},
-		{`go:cgo_ldflag "arg"`, []string{`cgo_ldflag`, `arg`}},
-		{`go:cgo_ldflag "a rg"`, []string{`cgo_ldflag`, `a rg`}},
-	}
-
-	if runtime.GOOS != "aix" {
-		tests = append(tests, []testStruct{
-			{`go:cgo_import_dynamic local remote "library"`, []string{`cgo_import_dynamic`, `local`, `remote`, `library`}},
-			{`go:cgo_import_dynamic local' remote' "lib rary"`, []string{`cgo_import_dynamic`, `local'`, `remote'`, `lib rary`}},
-		}...)
-	} else {
-		// cgo_import_dynamic with a library is slightly different on AIX
-		// as the library field must follow the pattern [libc.a/object.o].
-		tests = append(tests, []testStruct{
-			{`go:cgo_import_dynamic local remote "lib.a/obj.o"`, []string{`cgo_import_dynamic`, `local`, `remote`, `lib.a/obj.o`}},
-			// This test must fail.
-			{`go:cgo_import_dynamic local' remote' "library"`, []string{`<unknown position>: usage: //go:cgo_import_dynamic local [remote ["lib.a/object.o"]]`}},
-		}...)
-
-	}
-
-	var p noder
-	var nopos syntax.Pos
-	for _, tt := range tests {
-
-		p.err = make(chan syntax.Error)
-		gotch := make(chan [][]string, 1)
-		go func() {
-			p.pragcgobuf = nil
-			p.pragcgo(nopos, tt.in)
-			if p.pragcgobuf != nil {
-				gotch <- p.pragcgobuf
-			}
-		}()
-
-		select {
-		case e := <-p.err:
-			want := tt.want[0]
-			if e.Error() != want {
-				t.Errorf("pragcgo(%q) = %q; want %q", tt.in, e, want)
-				continue
-			}
-		case got := <-gotch:
-			want := [][]string{tt.want}
-			if !reflect.DeepEqual(got, want) {
-				t.Errorf("pragcgo(%q) = %q; want %q", tt.in, got, want)
-				continue
-			}
-		}
-
-	}
-}
diff --git a/src/cmd/compile/internal/gc/logic_test.go b/src/cmd/compile/internal/gc/logic_test.go
deleted file mode 100644
index 78d2dd2..0000000
--- a/src/cmd/compile/internal/gc/logic_test.go
+++ /dev/null
@@ -1,289 +0,0 @@
-package gc
-
-import "testing"
-
-// Tests to make sure logic simplification rules are correct.
-
-func TestLogic64(t *testing.T) {
-	// test values to determine function equality
-	values := [...]int64{-1 << 63, 1<<63 - 1, -4, -3, -2, -1, 0, 1, 2, 3, 4}
-
-	// golden functions we use repeatedly
-	zero := func(x int64) int64 { return 0 }
-	id := func(x int64) int64 { return x }
-	or := func(x, y int64) int64 { return x | y }
-	and := func(x, y int64) int64 { return x & y }
-	y := func(x, y int64) int64 { return y }
-
-	for _, test := range [...]struct {
-		name   string
-		f      func(int64) int64
-		golden func(int64) int64
-	}{
-		{"x|x", func(x int64) int64 { return x | x }, id},
-		{"x|0", func(x int64) int64 { return x | 0 }, id},
-		{"x|-1", func(x int64) int64 { return x | -1 }, func(x int64) int64 { return -1 }},
-		{"x&x", func(x int64) int64 { return x & x }, id},
-		{"x&0", func(x int64) int64 { return x & 0 }, zero},
-		{"x&-1", func(x int64) int64 { return x & -1 }, id},
-		{"x^x", func(x int64) int64 { return x ^ x }, zero},
-		{"x^0", func(x int64) int64 { return x ^ 0 }, id},
-		{"x^-1", func(x int64) int64 { return x ^ -1 }, func(x int64) int64 { return ^x }},
-		{"x+0", func(x int64) int64 { return x + 0 }, id},
-		{"x-x", func(x int64) int64 { return x - x }, zero},
-		{"x*0", func(x int64) int64 { return x * 0 }, zero},
-		{"^^x", func(x int64) int64 { return ^^x }, id},
-	} {
-		for _, v := range values {
-			got := test.f(v)
-			want := test.golden(v)
-			if want != got {
-				t.Errorf("[%s](%d)=%d, want %d", test.name, v, got, want)
-			}
-		}
-	}
-	for _, test := range [...]struct {
-		name   string
-		f      func(int64, int64) int64
-		golden func(int64, int64) int64
-	}{
-		{"x|(x|y)", func(x, y int64) int64 { return x | (x | y) }, or},
-		{"x|(y|x)", func(x, y int64) int64 { return x | (y | x) }, or},
-		{"(x|y)|x", func(x, y int64) int64 { return (x | y) | x }, or},
-		{"(y|x)|x", func(x, y int64) int64 { return (y | x) | x }, or},
-		{"x&(x&y)", func(x, y int64) int64 { return x & (x & y) }, and},
-		{"x&(y&x)", func(x, y int64) int64 { return x & (y & x) }, and},
-		{"(x&y)&x", func(x, y int64) int64 { return (x & y) & x }, and},
-		{"(y&x)&x", func(x, y int64) int64 { return (y & x) & x }, and},
-		{"x^(x^y)", func(x, y int64) int64 { return x ^ (x ^ y) }, y},
-		{"x^(y^x)", func(x, y int64) int64 { return x ^ (y ^ x) }, y},
-		{"(x^y)^x", func(x, y int64) int64 { return (x ^ y) ^ x }, y},
-		{"(y^x)^x", func(x, y int64) int64 { return (y ^ x) ^ x }, y},
-		{"-(y-x)", func(x, y int64) int64 { return -(y - x) }, func(x, y int64) int64 { return x - y }},
-		{"(x+y)-x", func(x, y int64) int64 { return (x + y) - x }, y},
-		{"(y+x)-x", func(x, y int64) int64 { return (y + x) - x }, y},
-	} {
-		for _, v := range values {
-			for _, w := range values {
-				got := test.f(v, w)
-				want := test.golden(v, w)
-				if want != got {
-					t.Errorf("[%s](%d,%d)=%d, want %d", test.name, v, w, got, want)
-				}
-			}
-		}
-	}
-}
-
-func TestLogic32(t *testing.T) {
-	// test values to determine function equality
-	values := [...]int32{-1 << 31, 1<<31 - 1, -4, -3, -2, -1, 0, 1, 2, 3, 4}
-
-	// golden functions we use repeatedly
-	zero := func(x int32) int32 { return 0 }
-	id := func(x int32) int32 { return x }
-	or := func(x, y int32) int32 { return x | y }
-	and := func(x, y int32) int32 { return x & y }
-	y := func(x, y int32) int32 { return y }
-
-	for _, test := range [...]struct {
-		name   string
-		f      func(int32) int32
-		golden func(int32) int32
-	}{
-		{"x|x", func(x int32) int32 { return x | x }, id},
-		{"x|0", func(x int32) int32 { return x | 0 }, id},
-		{"x|-1", func(x int32) int32 { return x | -1 }, func(x int32) int32 { return -1 }},
-		{"x&x", func(x int32) int32 { return x & x }, id},
-		{"x&0", func(x int32) int32 { return x & 0 }, zero},
-		{"x&-1", func(x int32) int32 { return x & -1 }, id},
-		{"x^x", func(x int32) int32 { return x ^ x }, zero},
-		{"x^0", func(x int32) int32 { return x ^ 0 }, id},
-		{"x^-1", func(x int32) int32 { return x ^ -1 }, func(x int32) int32 { return ^x }},
-		{"x+0", func(x int32) int32 { return x + 0 }, id},
-		{"x-x", func(x int32) int32 { return x - x }, zero},
-		{"x*0", func(x int32) int32 { return x * 0 }, zero},
-		{"^^x", func(x int32) int32 { return ^^x }, id},
-	} {
-		for _, v := range values {
-			got := test.f(v)
-			want := test.golden(v)
-			if want != got {
-				t.Errorf("[%s](%d)=%d, want %d", test.name, v, got, want)
-			}
-		}
-	}
-	for _, test := range [...]struct {
-		name   string
-		f      func(int32, int32) int32
-		golden func(int32, int32) int32
-	}{
-		{"x|(x|y)", func(x, y int32) int32 { return x | (x | y) }, or},
-		{"x|(y|x)", func(x, y int32) int32 { return x | (y | x) }, or},
-		{"(x|y)|x", func(x, y int32) int32 { return (x | y) | x }, or},
-		{"(y|x)|x", func(x, y int32) int32 { return (y | x) | x }, or},
-		{"x&(x&y)", func(x, y int32) int32 { return x & (x & y) }, and},
-		{"x&(y&x)", func(x, y int32) int32 { return x & (y & x) }, and},
-		{"(x&y)&x", func(x, y int32) int32 { return (x & y) & x }, and},
-		{"(y&x)&x", func(x, y int32) int32 { return (y & x) & x }, and},
-		{"x^(x^y)", func(x, y int32) int32 { return x ^ (x ^ y) }, y},
-		{"x^(y^x)", func(x, y int32) int32 { return x ^ (y ^ x) }, y},
-		{"(x^y)^x", func(x, y int32) int32 { return (x ^ y) ^ x }, y},
-		{"(y^x)^x", func(x, y int32) int32 { return (y ^ x) ^ x }, y},
-		{"-(y-x)", func(x, y int32) int32 { return -(y - x) }, func(x, y int32) int32 { return x - y }},
-		{"(x+y)-x", func(x, y int32) int32 { return (x + y) - x }, y},
-		{"(y+x)-x", func(x, y int32) int32 { return (y + x) - x }, y},
-	} {
-		for _, v := range values {
-			for _, w := range values {
-				got := test.f(v, w)
-				want := test.golden(v, w)
-				if want != got {
-					t.Errorf("[%s](%d,%d)=%d, want %d", test.name, v, w, got, want)
-				}
-			}
-		}
-	}
-}
-
-func TestLogic16(t *testing.T) {
-	// test values to determine function equality
-	values := [...]int16{-1 << 15, 1<<15 - 1, -4, -3, -2, -1, 0, 1, 2, 3, 4}
-
-	// golden functions we use repeatedly
-	zero := func(x int16) int16 { return 0 }
-	id := func(x int16) int16 { return x }
-	or := func(x, y int16) int16 { return x | y }
-	and := func(x, y int16) int16 { return x & y }
-	y := func(x, y int16) int16 { return y }
-
-	for _, test := range [...]struct {
-		name   string
-		f      func(int16) int16
-		golden func(int16) int16
-	}{
-		{"x|x", func(x int16) int16 { return x | x }, id},
-		{"x|0", func(x int16) int16 { return x | 0 }, id},
-		{"x|-1", func(x int16) int16 { return x | -1 }, func(x int16) int16 { return -1 }},
-		{"x&x", func(x int16) int16 { return x & x }, id},
-		{"x&0", func(x int16) int16 { return x & 0 }, zero},
-		{"x&-1", func(x int16) int16 { return x & -1 }, id},
-		{"x^x", func(x int16) int16 { return x ^ x }, zero},
-		{"x^0", func(x int16) int16 { return x ^ 0 }, id},
-		{"x^-1", func(x int16) int16 { return x ^ -1 }, func(x int16) int16 { return ^x }},
-		{"x+0", func(x int16) int16 { return x + 0 }, id},
-		{"x-x", func(x int16) int16 { return x - x }, zero},
-		{"x*0", func(x int16) int16 { return x * 0 }, zero},
-		{"^^x", func(x int16) int16 { return ^^x }, id},
-	} {
-		for _, v := range values {
-			got := test.f(v)
-			want := test.golden(v)
-			if want != got {
-				t.Errorf("[%s](%d)=%d, want %d", test.name, v, got, want)
-			}
-		}
-	}
-	for _, test := range [...]struct {
-		name   string
-		f      func(int16, int16) int16
-		golden func(int16, int16) int16
-	}{
-		{"x|(x|y)", func(x, y int16) int16 { return x | (x | y) }, or},
-		{"x|(y|x)", func(x, y int16) int16 { return x | (y | x) }, or},
-		{"(x|y)|x", func(x, y int16) int16 { return (x | y) | x }, or},
-		{"(y|x)|x", func(x, y int16) int16 { return (y | x) | x }, or},
-		{"x&(x&y)", func(x, y int16) int16 { return x & (x & y) }, and},
-		{"x&(y&x)", func(x, y int16) int16 { return x & (y & x) }, and},
-		{"(x&y)&x", func(x, y int16) int16 { return (x & y) & x }, and},
-		{"(y&x)&x", func(x, y int16) int16 { return (y & x) & x }, and},
-		{"x^(x^y)", func(x, y int16) int16 { return x ^ (x ^ y) }, y},
-		{"x^(y^x)", func(x, y int16) int16 { return x ^ (y ^ x) }, y},
-		{"(x^y)^x", func(x, y int16) int16 { return (x ^ y) ^ x }, y},
-		{"(y^x)^x", func(x, y int16) int16 { return (y ^ x) ^ x }, y},
-		{"-(y-x)", func(x, y int16) int16 { return -(y - x) }, func(x, y int16) int16 { return x - y }},
-		{"(x+y)-x", func(x, y int16) int16 { return (x + y) - x }, y},
-		{"(y+x)-x", func(x, y int16) int16 { return (y + x) - x }, y},
-	} {
-		for _, v := range values {
-			for _, w := range values {
-				got := test.f(v, w)
-				want := test.golden(v, w)
-				if want != got {
-					t.Errorf("[%s](%d,%d)=%d, want %d", test.name, v, w, got, want)
-				}
-			}
-		}
-	}
-}
-
-func TestLogic8(t *testing.T) {
-	// test values to determine function equality
-	values := [...]int8{-1 << 7, 1<<7 - 1, -4, -3, -2, -1, 0, 1, 2, 3, 4}
-
-	// golden functions we use repeatedly
-	zero := func(x int8) int8 { return 0 }
-	id := func(x int8) int8 { return x }
-	or := func(x, y int8) int8 { return x | y }
-	and := func(x, y int8) int8 { return x & y }
-	y := func(x, y int8) int8 { return y }
-
-	for _, test := range [...]struct {
-		name   string
-		f      func(int8) int8
-		golden func(int8) int8
-	}{
-		{"x|x", func(x int8) int8 { return x | x }, id},
-		{"x|0", func(x int8) int8 { return x | 0 }, id},
-		{"x|-1", func(x int8) int8 { return x | -1 }, func(x int8) int8 { return -1 }},
-		{"x&x", func(x int8) int8 { return x & x }, id},
-		{"x&0", func(x int8) int8 { return x & 0 }, zero},
-		{"x&-1", func(x int8) int8 { return x & -1 }, id},
-		{"x^x", func(x int8) int8 { return x ^ x }, zero},
-		{"x^0", func(x int8) int8 { return x ^ 0 }, id},
-		{"x^-1", func(x int8) int8 { return x ^ -1 }, func(x int8) int8 { return ^x }},
-		{"x+0", func(x int8) int8 { return x + 0 }, id},
-		{"x-x", func(x int8) int8 { return x - x }, zero},
-		{"x*0", func(x int8) int8 { return x * 0 }, zero},
-		{"^^x", func(x int8) int8 { return ^^x }, id},
-	} {
-		for _, v := range values {
-			got := test.f(v)
-			want := test.golden(v)
-			if want != got {
-				t.Errorf("[%s](%d)=%d, want %d", test.name, v, got, want)
-			}
-		}
-	}
-	for _, test := range [...]struct {
-		name   string
-		f      func(int8, int8) int8
-		golden func(int8, int8) int8
-	}{
-		{"x|(x|y)", func(x, y int8) int8 { return x | (x | y) }, or},
-		{"x|(y|x)", func(x, y int8) int8 { return x | (y | x) }, or},
-		{"(x|y)|x", func(x, y int8) int8 { return (x | y) | x }, or},
-		{"(y|x)|x", func(x, y int8) int8 { return (y | x) | x }, or},
-		{"x&(x&y)", func(x, y int8) int8 { return x & (x & y) }, and},
-		{"x&(y&x)", func(x, y int8) int8 { return x & (y & x) }, and},
-		{"(x&y)&x", func(x, y int8) int8 { return (x & y) & x }, and},
-		{"(y&x)&x", func(x, y int8) int8 { return (y & x) & x }, and},
-		{"x^(x^y)", func(x, y int8) int8 { return x ^ (x ^ y) }, y},
-		{"x^(y^x)", func(x, y int8) int8 { return x ^ (y ^ x) }, y},
-		{"(x^y)^x", func(x, y int8) int8 { return (x ^ y) ^ x }, y},
-		{"(y^x)^x", func(x, y int8) int8 { return (y ^ x) ^ x }, y},
-		{"-(y-x)", func(x, y int8) int8 { return -(y - x) }, func(x, y int8) int8 { return x - y }},
-		{"(x+y)-x", func(x, y int8) int8 { return (x + y) - x }, y},
-		{"(y+x)-x", func(x, y int8) int8 { return (y + x) - x }, y},
-	} {
-		for _, v := range values {
-			for _, w := range values {
-				got := test.f(v, w)
-				want := test.golden(v, w)
-				if want != got {
-					t.Errorf("[%s](%d,%d)=%d, want %d", test.name, v, w, got, want)
-				}
-			}
-		}
-	}
-}
diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go
index a6963a3..ce50cbb 100644
--- a/src/cmd/compile/internal/gc/main.go
+++ b/src/cmd/compile/internal/gc/main.go
@@ -2,716 +2,246 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:generate go run mkbuiltin.go
-
 package gc
 
 import (
 	"bufio"
 	"bytes"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/deadcode"
+	"cmd/compile/internal/devirtualize"
+	"cmd/compile/internal/dwarfgen"
+	"cmd/compile/internal/escape"
+	"cmd/compile/internal/inline"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/logopt"
+	"cmd/compile/internal/noder"
+	"cmd/compile/internal/pkginit"
+	"cmd/compile/internal/reflectdata"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
+	"cmd/compile/internal/typecheck"
 	"cmd/compile/internal/types"
-	"cmd/internal/bio"
 	"cmd/internal/dwarf"
-	"cmd/internal/goobj"
 	"cmd/internal/obj"
 	"cmd/internal/objabi"
 	"cmd/internal/src"
-	"cmd/internal/sys"
 	"flag"
 	"fmt"
-	"internal/goversion"
-	"io"
-	"io/ioutil"
+	"internal/buildcfg"
 	"log"
 	"os"
-	"path"
-	"regexp"
 	"runtime"
-	"sort"
-	"strconv"
-	"strings"
 )
 
-var (
-	buildid      string
-	spectre      string
-	spectreIndex bool
-)
-
-var (
-	Debug_append       int
-	Debug_checkptr     int
-	Debug_closure      int
-	Debug_compilelater int
-	debug_dclstack     int
-	Debug_dumpptrs     int
-	Debug_libfuzzer    int
-	Debug_panic        int
-	Debug_slice        int
-	Debug_vlog         bool
-	Debug_wb           int
-	Debug_pctab        string
-	Debug_locationlist int
-	Debug_typecheckinl int
-	Debug_gendwarfinl  int
-	Debug_softfloat    int
-	Debug_defer        int
-)
-
-// Debug arguments.
-// These can be specified with the -d flag, as in "-d nil"
-// to set the debug_checknil variable.
-// Multiple options can be comma-separated.
-// Each option accepts an optional argument, as in "gcprog=2"
-var debugtab = []struct {
-	name string
-	help string
-	val  interface{} // must be *int or *string
-}{
-	{"append", "print information about append compilation", &Debug_append},
-	{"checkptr", "instrument unsafe pointer conversions", &Debug_checkptr},
-	{"closure", "print information about closure compilation", &Debug_closure},
-	{"compilelater", "compile functions as late as possible", &Debug_compilelater},
-	{"disablenil", "disable nil checks", &disable_checknil},
-	{"dclstack", "run internal dclstack check", &debug_dclstack},
-	{"dumpptrs", "show Node pointer values in Dump/dumplist output", &Debug_dumpptrs},
-	{"gcprog", "print dump of GC programs", &Debug_gcprog},
-	{"libfuzzer", "coverage instrumentation for libfuzzer", &Debug_libfuzzer},
-	{"nil", "print information about nil checks", &Debug_checknil},
-	{"panic", "do not hide any compiler panic", &Debug_panic},
-	{"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},
-	{"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},
-	{"defer", "print information about defer compilation", &Debug_defer},
-	{"fieldtrack", "enable fieldtracking", &objabi.Fieldtrack_enabled},
-}
-
-const debugHelpHeader = `usage: -d arg[,arg]* and arg is <key>[=<value>]
-
-<key> is one of:
-
-`
-
-const debugHelpFooter = `
-<value> is key-specific.
-
-Key "checkptr" supports values:
-	"0": instrumentation disabled
-	"1": conversions involving unsafe.Pointer are instrumented
-	"2": conversions to unsafe.Pointer force heap allocation
-
-Key "pctab" supports values:
-	"pctospadj", "pctofile", "pctoline", "pctoinline", "pctopcdata"
-`
-
-func usage() {
-	fmt.Fprintf(os.Stderr, "usage: compile [options] file.go...\n")
-	objabi.Flagprint(os.Stderr)
-	Exit(2)
-}
-
 func hidePanic() {
-	if Debug_panic == 0 && nsavederrors+nerrors > 0 {
+	if base.Debug.Panic == 0 && base.Errors() > 0 {
 		// If we've already complained about things
 		// in the program, don't bother complaining
 		// about a panic too; let the user clean up
 		// the code and try again.
 		if err := recover(); err != nil {
-			errorexit()
+			if err == "-h" {
+				panic(err)
+			}
+			base.ErrorExit()
 		}
 	}
 }
 
-// supportsDynlink reports whether or not the code generator for the given
-// architecture supports the -shared and -dynlink flags.
-func supportsDynlink(arch *sys.Arch) bool {
-	return arch.InFamily(sys.AMD64, sys.ARM, sys.ARM64, sys.I386, sys.PPC64, sys.RISCV64, sys.S390X)
-}
-
-// timing data for compiler phases
-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.
-func Main(archInit func(*Arch)) {
-	timings.Start("fe", "init")
+func Main(archInit func(*ssagen.ArchInfo)) {
+	base.Timer.Start("fe", "init")
 
 	defer hidePanic()
 
-	archInit(&thearch)
+	archInit(&ssagen.Arch)
 
-	Ctxt = obj.Linknew(thearch.LinkArch)
-	Ctxt.DiagFunc = yyerror
-	Ctxt.DiagFlush = flusherrors
-	Ctxt.Bso = bufio.NewWriter(os.Stdout)
+	base.Ctxt = obj.Linknew(ssagen.Arch.LinkArch)
+	base.Ctxt.DiagFunc = base.Errorf
+	base.Ctxt.DiagFlush = base.FlushErrors
+	base.Ctxt.Bso = bufio.NewWriter(os.Stdout)
 
 	// UseBASEntries is preferred because it shaves about 2% off build time, but LLDB, dsymutil, and dwarfdump
 	// on Darwin don't support it properly, especially since macOS 10.14 (Mojave).  This is exposed as a flag
 	// to allow testing with LLVM tools on Linux, and to help with reporting this bug to the LLVM project.
 	// See bugs 31188 and 21945 (CLs 170638, 98075, 72371).
-	Ctxt.UseBASEntries = Ctxt.Headtype != objabi.Hdarwin
+	base.Ctxt.UseBASEntries = base.Ctxt.Headtype != objabi.Hdarwin
 
-	localpkg = types.NewPkg("", "")
-	localpkg.Prefix = "\"\""
+	types.LocalPkg = types.NewPkg("", "")
+	types.LocalPkg.Prefix = "\"\""
 
 	// We won't know localpkg's height until after import
 	// processing. In the mean time, set to MaxPkgHeight to ensure
 	// height comparisons at least work until then.
-	localpkg.Height = types.MaxPkgHeight
+	types.LocalPkg.Height = types.MaxPkgHeight
 
 	// pseudo-package, for scoping
-	builtinpkg = types.NewPkg("go.builtin", "") // TODO(gri) name this package go.builtin?
-	builtinpkg.Prefix = "go.builtin"            // not go%2ebuiltin
+	types.BuiltinPkg = types.NewPkg("go.builtin", "") // TODO(gri) name this package go.builtin?
+	types.BuiltinPkg.Prefix = "go.builtin"            // not go%2ebuiltin
 
 	// pseudo-package, accessed by import "unsafe"
-	unsafepkg = types.NewPkg("unsafe", "unsafe")
+	ir.Pkgs.Unsafe = types.NewPkg("unsafe", "unsafe")
 
 	// Pseudo-package that contains the compiler's builtin
 	// declarations for package runtime. These are declared in a
 	// separate package to avoid conflicts with package runtime's
 	// actual declarations, which may differ intentionally but
 	// insignificantly.
-	Runtimepkg = types.NewPkg("go.runtime", "runtime")
-	Runtimepkg.Prefix = "runtime"
+	ir.Pkgs.Runtime = types.NewPkg("go.runtime", "runtime")
+	ir.Pkgs.Runtime.Prefix = "runtime"
 
 	// pseudo-packages used in symbol tables
-	itabpkg = types.NewPkg("go.itab", "go.itab")
-	itabpkg.Prefix = "go.itab" // not go%2eitab
-
-	itablinkpkg = types.NewPkg("go.itablink", "go.itablink")
-	itablinkpkg.Prefix = "go.itablink" // not go%2eitablink
-
-	trackpkg = types.NewPkg("go.track", "go.track")
-	trackpkg.Prefix = "go.track" // not go%2etrack
-
-	// pseudo-package used for map zero values
-	mappkg = types.NewPkg("go.map", "go.map")
-	mappkg.Prefix = "go.map"
+	ir.Pkgs.Itab = types.NewPkg("go.itab", "go.itab")
+	ir.Pkgs.Itab.Prefix = "go.itab" // not go%2eitab
 
 	// pseudo-package used for methods with anonymous receivers
-	gopkg = types.NewPkg("go", "")
+	ir.Pkgs.Go = types.NewPkg("go", "")
 
-	Wasm := objabi.GOARCH == "wasm"
-
-	// Whether the limit for stack-allocated objects is much smaller than normal.
-	// This can be helpful for diagnosing certain causes of GC latency. See #27732.
-	smallFrames := false
-	jsonLogOpt := ""
-
-	flag.BoolVar(&compiling_runtime, "+", false, "compiling runtime")
-	flag.BoolVar(&compiling_std, "std", false, "compiling standard library")
-	flag.StringVar(&localimport, "D", "", "set relative `path` for local imports")
-
-	objabi.Flagcount("%", "debug non-static initializers", &Debug.P)
-	objabi.Flagcount("B", "disable bounds checking", &Debug.B)
-	objabi.Flagcount("C", "disable printing of columns in error messages", &Debug.C)
-	objabi.Flagcount("E", "debug symbol export", &Debug.E)
-	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)
-	objabi.Flagcount("S", "print assembly listing", &Debug.S)
-	objabi.Flagcount("W", "debug parse tree after type checking", &Debug.W)
-	objabi.Flagcount("e", "no limit on number of errors reported", &Debug.e)
-	objabi.Flagcount("h", "halt on error", &Debug.h)
-	objabi.Flagcount("j", "debug runtime-initialized variables", &Debug.j)
-	objabi.Flagcount("l", "disable inlining", &Debug.l)
-	objabi.Flagcount("m", "print optimization decisions", &Debug.m)
-	objabi.Flagcount("r", "debug generated wrappers", &Debug.r)
-	objabi.Flagcount("w", "debug type checking", &Debug.w)
-
-	objabi.Flagfn1("I", "add `directory` to import search path", addidir)
-	objabi.AddVersionFlag() // -V
-	flag.StringVar(&asmhdr, "asmhdr", "", "write assembly header to `file`")
-	flag.StringVar(&buildid, "buildid", "", "record `id` as the build id in the export metadata")
-	flag.IntVar(&nBackendWorkers, "c", 1, "concurrency during compilation, 1 means no concurrency")
-	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", !Wasm, "generate DWARF symbols")
-	flag.BoolVar(&Ctxt.Flag_locationlists, "dwarflocationlists", true, "add location lists to DWARF in optimized mode")
-	flag.IntVar(&genDwarfInline, "gendwarfinl", 2, "generate DWARF inline info records")
-	objabi.Flagfn1("embedcfg", "read go:embed configuration from `file`", readEmbedCfg)
-	objabi.Flagfn1("importmap", "add `definition` of the form source=actual to import map", addImportMap)
-	objabi.Flagfn1("importcfg", "read import configuration from `file`", readImportCfg)
-	flag.StringVar(&flag_installsuffix, "installsuffix", "", "set pkg directory `suffix`")
-	flag.StringVar(&flag_lang, "lang", "", "release to compile for")
-	flag.StringVar(&linkobj, "linkobj", "", "write linker-specific object to `file`")
-	objabi.Flagcount("live", "debug liveness analysis", &debuglive)
-	if sys.MSanSupported(objabi.GOOS, objabi.GOARCH) {
-		flag.BoolVar(&flag_msan, "msan", false, "build code compatible with C/C++ memory sanitizer")
-	}
-	flag.BoolVar(&nolocalimports, "nolocalimports", false, "reject local (relative) imports")
-	flag.StringVar(&outfile, "o", "", "write output to `file`")
-	flag.StringVar(&myimportpath, "p", "", "set expected package import `path`")
-	flag.BoolVar(&writearchive, "pack", false, "write to file.a instead of file.o")
-	if sys.RaceDetectorSupported(objabi.GOOS, objabi.GOARCH) {
-		flag.BoolVar(&flag_race, "race", false, "enable race detector")
-	}
-	flag.StringVar(&spectre, "spectre", spectre, "enable spectre mitigations in `list` (all, index, ret)")
-	if enableTrace {
-		flag.BoolVar(&trace, "t", false, "trace type-checking")
-	}
-	flag.StringVar(&pathPrefix, "trimpath", "", "remove `prefix` from recorded source file paths")
-	flag.BoolVar(&Debug_vlog, "v", false, "increase debug verbosity")
-	flag.BoolVar(&use_writebarrier, "wb", true, "enable write barrier")
-	var flag_shared bool
-	var flag_dynlink bool
-	if supportsDynlink(thearch.LinkArch.Arch) {
-		flag.BoolVar(&flag_shared, "shared", false, "generate code that can be linked into a shared library")
-		flag.BoolVar(&flag_dynlink, "dynlink", false, "support references to Go symbols defined in other shared libraries")
-		flag.BoolVar(&Ctxt.Flag_linkshared, "linkshared", false, "generate code that will be linked against Go shared libraries")
-	}
-	flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to `file`")
-	flag.StringVar(&memprofile, "memprofile", "", "write memory profile to `file`")
-	flag.Int64Var(&memprofilerate, "memprofilerate", 0, "set runtime.MemProfileRate to `rate`")
-	var goversion string
-	flag.StringVar(&goversion, "goversion", "", "required version of the runtime")
-	var symabisPath string
-	flag.StringVar(&symabisPath, "symabis", "", "read symbol ABIs from `file`")
-	flag.StringVar(&traceprofile, "traceprofile", "", "write an execution trace to `file`")
-	flag.StringVar(&blockprofile, "blockprofile", "", "write block profile to `file`")
-	flag.StringVar(&mutexprofile, "mutexprofile", "", "write mutex profile to `file`")
-	flag.StringVar(&benchfile, "bench", "", "append benchmark times to `file`")
-	flag.BoolVar(&smallFrames, "smallframes", false, "reduce the size limit for stack allocated objects")
-	flag.BoolVar(&Ctxt.UseBASEntries, "dwarfbasentries", Ctxt.UseBASEntries, "use base address selection entries in DWARF")
-	flag.StringVar(&jsonLogOpt, "json", "", "version,destination for JSON compiler/optimizer logging")
-
-	objabi.Flagparse(usage)
-
-	Ctxt.Pkgpath = myimportpath
-
-	for _, f := range strings.Split(spectre, ",") {
-		f = strings.TrimSpace(f)
-		switch f {
-		default:
-			log.Fatalf("unknown setting -spectre=%s", f)
-		case "":
-			// nothing
-		case "all":
-			spectreIndex = true
-			Ctxt.Retpoline = true
-		case "index":
-			spectreIndex = true
-		case "ret":
-			Ctxt.Retpoline = true
-		}
-	}
-
-	if spectreIndex {
-		switch objabi.GOARCH {
-		case "amd64":
-			// ok
-		default:
-			log.Fatalf("GOARCH=%s does not support -spectre=index", objabi.GOARCH)
-		}
-	}
+	base.DebugSSA = ssa.PhaseOption
+	base.ParseFlags()
 
 	// 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", "dwarfbasentries", "smallframes", "spectre")
+	dwarfgen.RecordFlags("B", "N", "l", "msan", "race", "shared", "dynlink", "dwarf", "dwarflocationlists", "dwarfbasentries", "smallframes", "spectre")
 
-	if smallFrames {
-		maxStackVarSize = 128 * 1024
-		maxImplicitStackVarSize = 16 * 1024
+	if !base.EnableTrace && base.Flag.LowerT {
+		log.Fatalf("compiler not built with support for -t")
 	}
 
-	Ctxt.Flag_shared = flag_dynlink || flag_shared
-	Ctxt.Flag_dynlink = flag_dynlink
-	Ctxt.Flag_optimize = Debug.N == 0
+	// Enable inlining (after RecordFlags, to avoid recording the rewritten -l).  For now:
+	//	default: inlining on.  (Flag.LowerL == 1)
+	//	-l: inlining off  (Flag.LowerL == 0)
+	//	-l=2, -l=3: inlining on again, with extra debugging (Flag.LowerL > 1)
+	if base.Flag.LowerL <= 1 {
+		base.Flag.LowerL = 1 - base.Flag.LowerL
+	}
 
-	Ctxt.Debugasm = Debug.S
-	Ctxt.Debugvlog = Debug_vlog
-	if flagDWARF {
-		Ctxt.DebugInfo = debuginfo
-		Ctxt.GenAbstractFunc = genAbstractFunc
-		Ctxt.DwFixups = obj.NewDwarfFixupTable(Ctxt)
+	if base.Flag.SmallFrames {
+		ir.MaxStackVarSize = 128 * 1024
+		ir.MaxImplicitStackVarSize = 16 * 1024
+	}
+
+	if base.Flag.Dwarf {
+		base.Ctxt.DebugInfo = dwarfgen.Info
+		base.Ctxt.GenAbstractFunc = dwarfgen.AbstractFunc
+		base.Ctxt.DwFixups = obj.NewDwarfFixupTable(base.Ctxt)
 	} else {
 		// turn off inline generation if no dwarf at all
-		genDwarfInline = 0
-		Ctxt.Flag_locationlists = false
+		base.Flag.GenDwarfInl = 0
+		base.Ctxt.Flag_locationlists = false
+	}
+	if base.Ctxt.Flag_locationlists && len(base.Ctxt.Arch.DWARFRegisters) == 0 {
+		log.Fatalf("location lists requested but register mapping not available on %v", base.Ctxt.Arch.Name)
 	}
 
-	if flag.NArg() < 1 && debugstr != "help" && debugstr != "ssa/help" {
-		usage()
+	types.ParseLangFlag()
+
+	symABIs := ssagen.NewSymABIs(base.Ctxt.Pkgpath)
+	if base.Flag.SymABIs != "" {
+		symABIs.ReadSymABIs(base.Flag.SymABIs)
 	}
 
-	if goversion != "" && goversion != runtime.Version() {
-		fmt.Printf("compile: version %q does not match go tool version %q\n", runtime.Version(), goversion)
-		Exit(2)
+	if base.Compiling(base.NoInstrumentPkgs) {
+		base.Flag.Race = false
+		base.Flag.MSan = false
 	}
 
-	checkLang()
-
-	if symabisPath != "" {
-		readSymABIs(symabisPath, myimportpath)
-	}
-
-	thearch.LinkArch.Init(Ctxt)
-
-	if outfile == "" {
-		p := flag.Arg(0)
-		if i := strings.LastIndex(p, "/"); i >= 0 {
-			p = p[i+1:]
-		}
-		if runtime.GOOS == "windows" {
-			if i := strings.LastIndex(p, `\`); i >= 0 {
-				p = p[i+1:]
-			}
-		}
-		if i := strings.LastIndex(p, "."); i >= 0 {
-			p = p[:i]
-		}
-		suffix := ".o"
-		if writearchive {
-			suffix = ".a"
-		}
-		outfile = p + suffix
-	}
-
+	ssagen.Arch.LinkArch.Init(base.Ctxt)
 	startProfile()
-
-	if flag_race && flag_msan {
-		log.Fatal("cannot use both -race and -msan")
+	if base.Flag.Race || base.Flag.MSan {
+		base.Flag.Cfg.Instrumenting = true
 	}
-	if flag_race || flag_msan {
-		// -race and -msan imply -d=checkptr for now.
-		Debug_checkptr = 1
+	if base.Flag.Dwarf {
+		dwarf.EnableLogging(base.Debug.DwarfInl != 0)
 	}
-	if ispkgin(omit_pkgs) {
-		flag_race = false
-		flag_msan = false
-	}
-	if flag_race {
-		racepkg = types.NewPkg("runtime/race", "")
-	}
-	if flag_msan {
-		msanpkg = types.NewPkg("runtime/msan", "")
-	}
-	if flag_race || flag_msan {
-		instrumenting = true
+	if base.Debug.SoftFloat != 0 {
+		if buildcfg.Experiment.RegabiArgs {
+			log.Fatalf("softfloat mode with GOEXPERIMENT=regabiargs not implemented ")
+		}
+		ssagen.Arch.SoftFloat = true
 	}
 
-	if compiling_runtime && Debug.N != 0 {
-		log.Fatal("cannot disable optimizations while compiling runtime")
-	}
-	if nBackendWorkers < 1 {
-		log.Fatalf("-c must be at least 1, got %d", nBackendWorkers)
-	}
-	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)
+	if base.Flag.JSON != "" { // parse version,destination from json logging optimization.
+		logopt.LogJsonOption(base.Flag.JSON)
 	}
 
-	// parse -d argument
-	if debugstr != "" {
-	Split:
-		for _, name := range strings.Split(debugstr, ",") {
-			if name == "" {
-				continue
-			}
-			// display help about the -d option itself and quit
-			if name == "help" {
-				fmt.Print(debugHelpHeader)
-				maxLen := len("ssa/help")
-				for _, t := range debugtab {
-					if len(t.name) > maxLen {
-						maxLen = len(t.name)
-					}
-				}
-				for _, t := range debugtab {
-					fmt.Printf("\t%-*s\t%s\n", maxLen, t.name, t.help)
-				}
-				// ssa options have their own help
-				fmt.Printf("\t%-*s\t%s\n", maxLen, "ssa/help", "print help about SSA debugging")
-				fmt.Print(debugHelpFooter)
-				os.Exit(0)
-			}
-			val, valstring, haveInt := 1, "", true
-			if i := strings.IndexAny(name, "=:"); i >= 0 {
-				var err error
-				name, valstring = name[:i], name[i+1:]
-				val, err = strconv.Atoi(valstring)
-				if err != nil {
-					val, haveInt = 1, false
-				}
-			}
-			for _, t := range debugtab {
-				if t.name != name {
-					continue
-				}
-				switch vp := t.val.(type) {
-				case nil:
-					// Ignore
-				case *string:
-					*vp = valstring
-				case *int:
-					if !haveInt {
-						log.Fatalf("invalid debug value %v", name)
-					}
-					*vp = val
-				default:
-					panic("bad debugtab type")
-				}
-				continue Split
-			}
-			// special case for ssa for now
-			if strings.HasPrefix(name, "ssa/") {
-				// expect form ssa/phase/flag
-				// e.g. -d=ssa/generic_cse/time
-				// _ in phase name also matches space
-				phase := name[4:]
-				flag := "debug" // default flag is debug
-				if i := strings.Index(phase, "/"); i >= 0 {
-					flag = phase[i+1:]
-					phase = phase[:i]
-				}
-				err := ssa.PhaseOption(phase, flag, val, valstring)
-				if err != "" {
-					log.Fatalf(err)
-				}
-				continue Split
-			}
-			log.Fatalf("unknown debug key -d %s\n", name)
+	ir.EscFmt = escape.Fmt
+	ir.IsIntrinsicCall = ssagen.IsIntrinsicCall
+	inline.SSADumpInline = ssagen.DumpInline
+	ssagen.InitEnv()
+	ssagen.InitTables()
+
+	types.PtrSize = ssagen.Arch.LinkArch.PtrSize
+	types.RegSize = ssagen.Arch.LinkArch.RegSize
+	types.MaxWidth = ssagen.Arch.MAXWIDTH
+
+	typecheck.Target = new(ir.Package)
+
+	typecheck.NeedITab = func(t, iface *types.Type) { reflectdata.ITabAddr(t, iface) }
+	typecheck.NeedRuntimeType = reflectdata.NeedRuntimeType // TODO(rsc): TypeSym for lock?
+
+	base.AutogeneratedPos = makePos(src.NewFileBase("<autogenerated>", "<autogenerated>"), 1, 0)
+
+	typecheck.InitUniverse()
+
+	// Parse and typecheck input.
+	noder.LoadPackage(flag.Args())
+
+	dwarfgen.RecordPackageName()
+
+	// Build init task.
+	if initTask := pkginit.Task(); initTask != nil {
+		typecheck.Export(initTask)
+	}
+
+	// Eliminate some obviously dead code.
+	// Must happen after typechecking.
+	for _, n := range typecheck.Target.Decls {
+		if n.Op() == ir.ODCLFUNC {
+			deadcode.Func(n.(*ir.Func))
 		}
 	}
 
-	if compiling_runtime {
-		// Runtime can't use -d=checkptr, at least not yet.
-		Debug_checkptr = 0
-
-		// Fuzzing the runtime isn't interesting either.
-		Debug_libfuzzer = 0
+	// Compute Addrtaken for names.
+	// We need to wait until typechecking is done so that when we see &x[i]
+	// we know that x has its address taken if x is an array, but not if x is a slice.
+	// We compute Addrtaken in bulk here.
+	// After this phase, we maintain Addrtaken incrementally.
+	if typecheck.DirtyAddrtaken {
+		typecheck.ComputeAddrtaken(typecheck.Target.Decls)
+		typecheck.DirtyAddrtaken = false
 	}
+	typecheck.IncrementalAddrtaken = true
 
-	// 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)
-	//	-l=2, -l=3: inlining on again, with extra debugging (Debug.l > 1)
-	if Debug.l <= 1 {
-		Debug.l = 1 - Debug.l
-	}
-
-	if jsonLogOpt != "" { // parse version,destination from json logging optimization.
-		logopt.LogJsonOption(jsonLogOpt)
-	}
-
-	ssaDump = os.Getenv("GOSSAFUNC")
-	ssaDir = os.Getenv("GOSSADIR")
-	if ssaDump != "" {
-		if strings.HasSuffix(ssaDump, "+") {
-			ssaDump = ssaDump[:len(ssaDump)-1]
-			ssaDumpStdout = true
-		}
-		spl := strings.Split(ssaDump, ":")
-		if len(spl) > 1 {
-			ssaDump = spl[0]
-			ssaDumpCFG = spl[1]
-		}
-	}
-
-	trackScopes = flagDWARF
-
-	Widthptr = thearch.LinkArch.PtrSize
-	Widthreg = thearch.LinkArch.RegSize
-
-	// initialize types package
-	// (we need to do this to break dependencies that otherwise
-	// would lead to import cycles)
-	types.Widthptr = Widthptr
-	types.Dowidth = dowidth
-	types.Fatalf = Fatalf
-	types.Sconv = func(s *types.Sym, flag, mode int) string {
-		return sconv(s, FmtFlag(flag), fmtMode(mode))
-	}
-	types.Tconv = func(t *types.Type, flag, mode int) string {
-		return tconv(t, FmtFlag(flag), fmtMode(mode))
-	}
-	types.FormatSym = func(sym *types.Sym, s fmt.State, verb rune, mode int) {
-		symFormat(sym, s, verb, fmtMode(mode))
-	}
-	types.FormatType = func(t *types.Type, s fmt.State, verb rune, mode int) {
-		typeFormat(t, s, verb, fmtMode(mode))
-	}
-	types.TypeLinkSym = func(t *types.Type) *obj.LSym {
-		return typenamesym(t).Linksym()
-	}
-	types.FmtLeft = int(FmtLeft)
-	types.FmtUnsigned = int(FmtUnsigned)
-	types.FErr = int(FErr)
-	types.Ctxt = Ctxt
-
-	initUniverse()
-
-	dclcontext = PEXTERN
-	nerrors = 0
-
-	autogeneratedPos = makePos(src.NewFileBase("<autogenerated>", "<autogenerated>"), 1, 0)
-
-	timings.Start("fe", "loadsys")
-	loadsys()
-
-	timings.Start("fe", "parse")
-	lines := parseFiles(flag.Args())
-	timings.Stop()
-	timings.AddEvent(int64(lines), "lines")
-
-	finishUniverse()
-
-	recordPackageName()
-
-	typecheckok = true
-
-	// Process top-level declarations in phases.
-
-	// Phase 1: const, type, and names and types of funcs.
-	//   This will gather all the information about types
-	//   and methods but doesn't depend on any of it.
-	//
-	//   We also defer type alias declarations until phase 2
-	//   to avoid cycles like #18640.
-	//   TODO(gri) Remove this again once we have a fix for #25838.
-
-	// Don't use range--typecheck can add closures to xtop.
-	timings.Start("fe", "typecheck", "top1")
-	for i := 0; i < len(xtop); i++ {
-		n := xtop[i]
-		if op := n.Op; op != ODCL && op != OAS && op != OAS2 && (op != ODCLTYPE || !n.Left.Name.Param.Alias()) {
-			xtop[i] = typecheck(n, ctxStmt)
-		}
-	}
-
-	// Phase 2: Variable assignments.
-	//   To check interface assignments, depends on phase 1.
-
-	// Don't use range--typecheck can add closures to xtop.
-	timings.Start("fe", "typecheck", "top2")
-	for i := 0; i < len(xtop); i++ {
-		n := xtop[i]
-		if op := n.Op; op == ODCL || op == OAS || op == OAS2 || op == ODCLTYPE && n.Left.Name.Param.Alias() {
-			xtop[i] = typecheck(n, ctxStmt)
-		}
-	}
-
-	// Phase 3: Type check function bodies.
-	// Don't use range--typecheck can add closures to xtop.
-	timings.Start("fe", "typecheck", "func")
-	var fcount int64
-	for i := 0; i < len(xtop); i++ {
-		n := xtop[i]
-		if n.Op == ODCLFUNC {
-			Curfn = n
-			decldepth = 1
-			saveerrors()
-			typecheckslice(Curfn.Nbody.Slice(), ctxStmt)
-			checkreturn(Curfn)
-			if nerrors != 0 {
-				Curfn.Nbody.Set(nil) // type errors; do not compile
-			}
-			// Now that we've checked whether n terminates,
-			// we can eliminate some obviously dead code.
-			deadcode(Curfn)
-			fcount++
-		}
-	}
-	// With all types checked, it's now safe to verify map keys. One single
-	// check past phase 9 isn't sufficient, as we may exit with other errors
-	// before then, thus skipping map key errors.
-	checkMapKeys()
-	timings.AddEvent(fcount, "funcs")
-
-	if nsavederrors+nerrors != 0 {
-		errorexit()
-	}
-
-	fninit(xtop)
-
-	// Phase 4: Decide how to capture closed variables.
-	// This needs to run before escape analysis,
-	// because variables captured by value do not escape.
-	timings.Start("fe", "capturevars")
-	for _, n := range xtop {
-		if n.Op == ODCLFUNC && n.Func.Closure != nil {
-			Curfn = n
-			capturevars(n)
-		}
-	}
-	capturevarscomplete = true
-
-	Curfn = nil
-
-	if nsavederrors+nerrors != 0 {
-		errorexit()
-	}
-
-	// Phase 5: Inlining
-	timings.Start("fe", "inlining")
-	if Debug_typecheckinl != 0 {
+	if base.Debug.TypecheckInl != 0 {
 		// Typecheck imported function bodies if Debug.l > 1,
 		// otherwise lazily when used or re-exported.
-		for _, n := range importlist {
-			if n.Func.Inl != nil {
-				saveerrors()
-				typecheckinl(n)
-			}
-		}
-
-		if nsavederrors+nerrors != 0 {
-			errorexit()
-		}
+		typecheck.AllImportedBodies()
 	}
 
-	if Debug.l != 0 {
-		// Find functions that can be inlined and clone them before walk expands them.
-		visitBottomUp(xtop, func(list []*Node, recursive bool) {
-			numfns := numNonClosures(list)
-			for _, n := range list {
-				if !recursive || numfns > 1 {
-					// We allow inlining if there is no
-					// recursion, or the recursion cycle is
-					// across more than one function.
-					caninl(n)
-				} else {
-					if Debug.m > 1 {
-						fmt.Printf("%v: cannot inline %v: recursive\n", n.Line(), n.Func.Nname)
-					}
-				}
-				inlcalls(n)
-			}
-		})
+	// Inlining
+	base.Timer.Start("fe", "inlining")
+	if base.Flag.LowerL != 0 {
+		inline.InlinePackage()
 	}
 
-	for _, n := range xtop {
-		if n.Op == ODCLFUNC {
-			devirtualize(n)
+	// Devirtualize.
+	for _, n := range typecheck.Target.Decls {
+		if n.Op() == ir.ODCLFUNC {
+			devirtualize.Func(n.(*ir.Func))
 		}
 	}
-	Curfn = nil
+	ir.CurFunc = nil
 
-	// Phase 6: Escape analysis.
+	// Generate ABI wrappers. Must happen before escape analysis
+	// and doesn't benefit from dead-coding or inlining.
+	symABIs.GenABIWrappers()
+
+	// Escape analysis.
 	// Required for moving heap allocations onto stack,
 	// which in turn is required by the closure implementation,
 	// which stores the addresses of stack variables into the closure.
@@ -719,140 +249,86 @@
 	// or else the stack copier will not update it.
 	// Large values are also moved off stack in escape analysis;
 	// because large values may contain pointers, it must happen early.
-	timings.Start("fe", "escapes")
-	escapes(xtop)
+	base.Timer.Start("fe", "escapes")
+	escape.Funcs(typecheck.Target.Decls)
 
 	// Collect information for go:nowritebarrierrec
-	// checking. This must happen before transformclosure.
+	// checking. This must happen before transforming closures during Walk
 	// 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.
-	timings.Start("fe", "xclosures")
-	for _, n := range xtop {
-		if n.Op == ODCLFUNC && n.Func.Closure != nil {
-			Curfn = n
-			transformclosure(n)
-		}
+	if base.Flag.CompilingRuntime {
+		ssagen.EnableNoWriteBarrierRecCheck()
 	}
 
 	// Prepare for SSA compilation.
-	// This must be before peekitabs, because peekitabs
+	// This must be before CompileITabs, because CompileITabs
 	// can trigger function compilation.
-	initssaconfig()
+	typecheck.InitRuntime()
+	ssagen.InitConfig()
 
 	// Just before compilation, compile itabs found on
 	// the right side of OCONVIFACE so that methods
 	// can be de-virtualized during compilation.
-	Curfn = nil
-	peekitabs()
+	ir.CurFunc = nil
+	reflectdata.CompileITabs()
 
-	// Phase 8: Compile top level functions.
-	// Don't use range--walk can add functions to xtop.
-	timings.Start("be", "compilefuncs")
-	fcount = 0
-	for i := 0; i < len(xtop); i++ {
-		n := xtop[i]
-		if n.Op == ODCLFUNC {
-			funccompile(n)
+	// Compile top level functions.
+	// Don't use range--walk can add functions to Target.Decls.
+	base.Timer.Start("be", "compilefuncs")
+	fcount := int64(0)
+	for i := 0; i < len(typecheck.Target.Decls); i++ {
+		if fn, ok := typecheck.Target.Decls[i].(*ir.Func); ok {
+			enqueueFunc(fn)
 			fcount++
 		}
 	}
-	timings.AddEvent(fcount, "funcs")
+	base.Timer.AddEvent(fcount, "funcs")
 
 	compileFunctions()
 
-	if nowritebarrierrecCheck != nil {
-		// Write barriers are now known. Check the
-		// call graph.
-		nowritebarrierrecCheck.check()
-		nowritebarrierrecCheck = nil
+	if base.Flag.CompilingRuntime {
+		// Write barriers are now known. Check the call graph.
+		ssagen.NoWriteBarrierRecCheck()
 	}
 
 	// 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
-	}
-
-	// Phase 9: Check external declarations.
-	timings.Start("be", "externaldcls")
-	for i, n := range externdcl {
-		if n.Op == ONAME {
-			externdcl[i] = typecheck(externdcl[i], ctxExpr)
-		}
-	}
-	// Check the map keys again, since we typechecked the external
-	// declarations.
-	checkMapKeys()
-
-	if nerrors+nsavederrors != 0 {
-		errorexit()
+	if base.Ctxt.DwFixups != nil {
+		base.Ctxt.DwFixups.Finalize(base.Ctxt.Pkgpath, base.Debug.DwarfInl != 0)
+		base.Ctxt.DwFixups = nil
+		base.Flag.GenDwarfInl = 0
 	}
 
 	// Write object data to disk.
-	timings.Start("be", "dumpobj")
+	base.Timer.Start("be", "dumpobj")
 	dumpdata()
-	Ctxt.NumberSyms()
+	base.Ctxt.NumberSyms()
 	dumpobj()
-	if asmhdr != "" {
+	if base.Flag.AsmHdr != "" {
 		dumpasmhdr()
 	}
 
-	// Check whether any of the functions we have compiled have gigantic stack frames.
-	sort.Slice(largeStackFrames, func(i, j int) bool {
-		return largeStackFrames[i].pos.Before(largeStackFrames[j].pos)
-	})
-	for _, large := range largeStackFrames {
-		if large.callee != 0 {
-			yyerrorl(large.pos, "stack frame too large (>1GB): %d MB locals + %d MB args + %d MB callee", large.locals>>20, large.args>>20, large.callee>>20)
-		} else {
-			yyerrorl(large.pos, "stack frame too large (>1GB): %d MB locals + %d MB args", large.locals>>20, large.args>>20)
-		}
-	}
+	ssagen.CheckLargeStacks()
+	typecheck.CheckFuncStack()
 
-	if len(funcStack) != 0 {
-		Fatalf("funcStack is non-empty: %v", len(funcStack))
-	}
 	if len(compilequeue) != 0 {
-		Fatalf("%d uncompiled functions", len(compilequeue))
+		base.Fatalf("%d uncompiled functions", len(compilequeue))
 	}
 
-	logopt.FlushLoggedOpts(Ctxt, myimportpath)
+	logopt.FlushLoggedOpts(base.Ctxt, base.Ctxt.Pkgpath)
+	base.ExitIfErrors()
 
-	if nerrors+nsavederrors != 0 {
-		errorexit()
-	}
+	base.FlushErrors()
+	base.Timer.Stop()
 
-	flusherrors()
-	timings.Stop()
-
-	if benchfile != "" {
-		if err := writebench(benchfile); err != nil {
+	if base.Flag.Bench != "" {
+		if err := writebench(base.Flag.Bench); err != nil {
 			log.Fatalf("cannot write benchmark data: %v", err)
 		}
 	}
 }
 
-// numNonClosures returns the number of functions in list which are not closures.
-func numNonClosures(list []*Node) int {
-	count := 0
-	for _, n := range list {
-		if n.Func.Closure == nil {
-			count++
-		}
-	}
-	return count
-}
-
 func writebench(filename string) error {
 	f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
 	if err != nil {
@@ -860,10 +336,10 @@
 	}
 
 	var buf bytes.Buffer
-	fmt.Fprintln(&buf, "commit:", objabi.Version)
+	fmt.Fprintln(&buf, "commit:", buildcfg.Version)
 	fmt.Fprintln(&buf, "goos:", runtime.GOOS)
 	fmt.Fprintln(&buf, "goarch:", runtime.GOARCH)
-	timings.Write(&buf, "BenchmarkCompile:"+myimportpath+":")
+	base.Timer.Write(&buf, "BenchmarkCompile:"+base.Ctxt.Pkgpath+":")
 
 	n, err := f.Write(buf.Bytes())
 	if err != nil {
@@ -876,735 +352,6 @@
 	return f.Close()
 }
 
-var (
-	importMap   = map[string]string{}
-	packageFile map[string]string // nil means not in use
-)
-
-func addImportMap(s string) {
-	if strings.Count(s, "=") != 1 {
-		log.Fatal("-importmap argument must be of the form source=actual")
-	}
-	i := strings.Index(s, "=")
-	source, actual := s[:i], s[i+1:]
-	if source == "" || actual == "" {
-		log.Fatal("-importmap argument must be of the form source=actual; source and actual must be non-empty")
-	}
-	importMap[source] = actual
-}
-
-func readImportCfg(file string) {
-	packageFile = map[string]string{}
-	data, err := ioutil.ReadFile(file)
-	if err != nil {
-		log.Fatalf("-importcfg: %v", err)
-	}
-
-	for lineNum, line := range strings.Split(string(data), "\n") {
-		lineNum++ // 1-based
-		line = strings.TrimSpace(line)
-		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:
-			log.Fatalf("%s:%d: unknown directive %q", file, lineNum, verb)
-		case "importmap":
-			if before == "" || after == "" {
-				log.Fatalf(`%s:%d: invalid importmap: syntax is "importmap old=new"`, file, lineNum)
-			}
-			importMap[before] = after
-		case "packagefile":
-			if before == "" || after == "" {
-				log.Fatalf(`%s:%d: invalid packagefile: syntax is "packagefile path=filename"`, file, lineNum)
-			}
-			packageFile[before] = after
-		}
-	}
-}
-
-// symabiDefs and symabiRefs record the defined and referenced ABIs of
-// symbols required by non-Go code. These are keyed by link symbol
-// name, where the local package prefix is always `"".`
-var symabiDefs, symabiRefs map[string]obj.ABI
-
-// readSymABIs reads a symabis file that specifies definitions and
-// references of text symbols by ABI.
-//
-// The symabis format is a set of lines, where each line is a sequence
-// of whitespace-separated fields. The first field is a verb and is
-// either "def" for defining a symbol ABI or "ref" for referencing a
-// symbol using an ABI. For both "def" and "ref", the second field is
-// the symbol name and the third field is the ABI name, as one of the
-// named cmd/internal/obj.ABI constants.
-func readSymABIs(file, myimportpath string) {
-	data, err := ioutil.ReadFile(file)
-	if err != nil {
-		log.Fatalf("-symabis: %v", err)
-	}
-
-	symabiDefs = make(map[string]obj.ABI)
-	symabiRefs = make(map[string]obj.ABI)
-
-	localPrefix := ""
-	if myimportpath != "" {
-		// Symbols in this package may be written either as
-		// "".X or with the package's import path already in
-		// the symbol.
-		localPrefix = objabi.PathToPrefix(myimportpath) + "."
-	}
-
-	for lineNum, line := range strings.Split(string(data), "\n") {
-		lineNum++ // 1-based
-		line = strings.TrimSpace(line)
-		if line == "" || strings.HasPrefix(line, "#") {
-			continue
-		}
-
-		parts := strings.Fields(line)
-		switch parts[0] {
-		case "def", "ref":
-			// Parse line.
-			if len(parts) != 3 {
-				log.Fatalf(`%s:%d: invalid symabi: syntax is "%s sym abi"`, file, lineNum, parts[0])
-			}
-			sym, abistr := parts[1], parts[2]
-			abi, valid := obj.ParseABI(abistr)
-			if !valid {
-				log.Fatalf(`%s:%d: invalid symabi: unknown abi "%s"`, file, lineNum, abistr)
-			}
-
-			// If the symbol is already prefixed with
-			// myimportpath, rewrite it to start with ""
-			// so it matches the compiler's internal
-			// symbol names.
-			if localPrefix != "" && strings.HasPrefix(sym, localPrefix) {
-				sym = `"".` + sym[len(localPrefix):]
-			}
-
-			// Record for later.
-			if parts[0] == "def" {
-				symabiDefs[sym] = abi
-			} else {
-				symabiRefs[sym] = abi
-			}
-		default:
-			log.Fatalf(`%s:%d: invalid symabi type "%s"`, file, lineNum, parts[0])
-		}
-	}
-}
-
-func saveerrors() {
-	nsavederrors += nerrors
-	nerrors = 0
-}
-
-func arsize(b *bufio.Reader, name string) int {
-	var buf [ArhdrSize]byte
-	if _, err := io.ReadFull(b, buf[:]); err != nil {
-		return -1
-	}
-	aname := strings.Trim(string(buf[0:16]), " ")
-	if !strings.HasPrefix(aname, name) {
-		return -1
-	}
-	asize := strings.Trim(string(buf[48:58]), " ")
-	i, _ := strconv.Atoi(asize)
-	return i
-}
-
-var idirs []string
-
-func addidir(dir string) {
-	if dir != "" {
-		idirs = append(idirs, dir)
-	}
-}
-
-func isDriveLetter(b byte) bool {
-	return 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z'
-}
-
-// 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] == '/' ||
-		strings.HasPrefix(name, "./") || name == "." ||
-		strings.HasPrefix(name, "../") || name == ".."
-}
-
-func findpkg(name string) (file string, ok bool) {
-	if islocalname(name) {
-		if nolocalimports {
-			return "", false
-		}
-
-		if packageFile != nil {
-			file, ok = packageFile[name]
-			return file, ok
-		}
-
-		// try .a before .6.  important for building libraries:
-		// if there is an array.6 in the array.a library,
-		// want to find all of array.a, not just array.6.
-		file = fmt.Sprintf("%s.a", name)
-		if _, err := os.Stat(file); err == nil {
-			return file, true
-		}
-		file = fmt.Sprintf("%s.o", name)
-		if _, err := os.Stat(file); err == nil {
-			return file, true
-		}
-		return "", false
-	}
-
-	// local imports should be canonicalized already.
-	// don't want to see "encoding/../encoding/base64"
-	// as different from "encoding/base64".
-	if q := path.Clean(name); q != name {
-		yyerror("non-canonical import path %q (should be %q)", name, q)
-		return "", false
-	}
-
-	if packageFile != nil {
-		file, ok = packageFile[name]
-		return file, ok
-	}
-
-	for _, dir := range idirs {
-		file = fmt.Sprintf("%s/%s.a", dir, name)
-		if _, err := os.Stat(file); err == nil {
-			return file, true
-		}
-		file = fmt.Sprintf("%s/%s.o", dir, name)
-		if _, err := os.Stat(file); err == nil {
-			return file, true
-		}
-	}
-
-	if objabi.GOROOT != "" {
-		suffix := ""
-		suffixsep := ""
-		if flag_installsuffix != "" {
-			suffixsep = "_"
-			suffix = flag_installsuffix
-		} else if flag_race {
-			suffixsep = "_"
-			suffix = "race"
-		} else if flag_msan {
-			suffixsep = "_"
-			suffix = "msan"
-		}
-
-		file = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.a", objabi.GOROOT, objabi.GOOS, objabi.GOARCH, suffixsep, suffix, name)
-		if _, err := os.Stat(file); err == nil {
-			return file, true
-		}
-		file = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.o", objabi.GOROOT, objabi.GOOS, objabi.GOARCH, suffixsep, suffix, name)
-		if _, err := os.Stat(file); err == nil {
-			return file, true
-		}
-	}
-
-	return "", false
-}
-
-// loadsys loads the definitions for the low-level runtime functions,
-// so that the compiler can generate calls to them,
-// but does not make them visible to user code.
-func loadsys() {
-	types.Block = 1
-
-	inimport = true
-	typecheckok = true
-
-	typs := runtimeTypes()
-	for _, d := range &runtimeDecls {
-		sym := Runtimepkg.Lookup(d.name)
-		typ := typs[d.typ]
-		switch d.tag {
-		case funcTag:
-			importfunc(Runtimepkg, src.NoXPos, sym, typ)
-		case varTag:
-			importvar(Runtimepkg, src.NoXPos, sym, typ)
-		default:
-			Fatalf("unhandled declaration tag %v", d.tag)
-		}
-	}
-
-	typecheckok = false
-	inimport = false
-}
-
-// myheight tracks the local package's height based on packages
-// imported so far.
-var myheight int
-
-func importfile(f *Val) *types.Pkg {
-	path_, ok := f.U.(string)
-	if !ok {
-		yyerror("import path must be a string")
-		return nil
-	}
-
-	if len(path_) == 0 {
-		yyerror("import path is empty")
-		return nil
-	}
-
-	if isbadimport(path_, false) {
-		return nil
-	}
-
-	// The package name main is no longer reserved,
-	// but we reserve the import path "main" to identify
-	// the main package, just as we reserve the import
-	// path "math" to identify the standard math package.
-	if path_ == "main" {
-		yyerror("cannot import \"main\"")
-		errorexit()
-	}
-
-	if myimportpath != "" && path_ == myimportpath {
-		yyerror("import %q while compiling that package (import cycle)", path_)
-		errorexit()
-	}
-
-	if mapped, ok := importMap[path_]; ok {
-		path_ = mapped
-	}
-
-	if path_ == "unsafe" {
-		return unsafepkg
-	}
-
-	if islocalname(path_) {
-		if path_[0] == '/' {
-			yyerror("import path cannot be absolute path")
-			return nil
-		}
-
-		prefix := Ctxt.Pathname
-		if localimport != "" {
-			prefix = localimport
-		}
-		path_ = path.Join(prefix, path_)
-
-		if isbadimport(path_, true) {
-			return nil
-		}
-	}
-
-	file, found := findpkg(path_)
-	if !found {
-		yyerror("can't find import: %q", path_)
-		errorexit()
-	}
-
-	importpkg := types.NewPkg(path_, "")
-	if importpkg.Imported {
-		return importpkg
-	}
-
-	importpkg.Imported = true
-
-	imp, err := bio.Open(file)
-	if err != nil {
-		yyerror("can't open import: %q: %v", path_, err)
-		errorexit()
-	}
-	defer imp.Close()
-
-	// check object header
-	p, err := imp.ReadString('\n')
-	if err != nil {
-		yyerror("import %s: reading input: %v", file, err)
-		errorexit()
-	}
-
-	if p == "!<arch>\n" { // package archive
-		// package export block should be first
-		sz := arsize(imp.Reader, "__.PKGDEF")
-		if sz <= 0 {
-			yyerror("import %s: not a package file", file)
-			errorexit()
-		}
-		p, err = imp.ReadString('\n')
-		if err != nil {
-			yyerror("import %s: reading input: %v", file, err)
-			errorexit()
-		}
-	}
-
-	if !strings.HasPrefix(p, "go object ") {
-		yyerror("import %s: not a go object file: %s", file, p)
-		errorexit()
-	}
-	q := fmt.Sprintf("%s %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version, objabi.Expstring())
-	if p[10:] != q {
-		yyerror("import %s: object is [%s] expected [%s]", file, p[10:], q)
-		errorexit()
-	}
-
-	// process header lines
-	for {
-		p, err = imp.ReadString('\n')
-		if err != nil {
-			yyerror("import %s: reading input: %v", file, err)
-			errorexit()
-		}
-		if p == "\n" {
-			break // header ends with blank line
-		}
-	}
-
-	// In the importfile, if we find:
-	// $$\n  (textual format): not supported anymore
-	// $$B\n (binary format) : import directly, then feed the lexer a dummy statement
-
-	// look for $$
-	var c byte
-	for {
-		c, err = imp.ReadByte()
-		if err != nil {
-			break
-		}
-		if c == '$' {
-			c, err = imp.ReadByte()
-			if c == '$' || err != nil {
-				break
-			}
-		}
-	}
-
-	// get character after $$
-	if err == nil {
-		c, _ = imp.ReadByte()
-	}
-
-	var fingerprint goobj.FingerprintType
-	switch c {
-	case '\n':
-		yyerror("cannot import %s: old export format no longer supported (recompile library)", path_)
-		return nil
-
-	case 'B':
-		if Debug_export != 0 {
-			fmt.Printf("importing %s (%s)\n", path_, file)
-		}
-		imp.ReadByte() // skip \n after $$B
-
-		c, err = imp.ReadByte()
-		if err != nil {
-			yyerror("import %s: reading input: %v", file, err)
-			errorexit()
-		}
-
-		// Indexed format is distinguished by an 'i' byte,
-		// whereas previous export formats started with 'c', 'd', or 'v'.
-		if c != 'i' {
-			yyerror("import %s: unexpected package format byte: %v", file, c)
-			errorexit()
-		}
-		fingerprint = iimport(importpkg, imp)
-
-	default:
-		yyerror("no import in %q", path_)
-		errorexit()
-	}
-
-	// assume files move (get installed) so don't record the full path
-	if packageFile != nil {
-		// If using a packageFile map, assume path_ can be recorded directly.
-		Ctxt.AddImport(path_, fingerprint)
-	} else {
-		// For file "/Users/foo/go/pkg/darwin_amd64/math.a" record "math.a".
-		Ctxt.AddImport(file[len(file)-len(path_)-len(".a"):], fingerprint)
-	}
-
-	if importpkg.Height >= myheight {
-		myheight = importpkg.Height + 1
-	}
-
-	return importpkg
-}
-
-func pkgnotused(lineno src.XPos, path string, name string) {
-	// If the package was imported with a name other than the final
-	// import path element, show it explicitly in the error message.
-	// Note that this handles both renamed imports and imports of
-	// packages containing unconventional package declarations.
-	// Note that this uses / always, even on Windows, because Go import
-	// paths always use forward slashes.
-	elem := path
-	if i := strings.LastIndex(elem, "/"); i >= 0 {
-		elem = elem[i+1:]
-	}
-	if name == "" || elem == name {
-		yyerrorl(lineno, "imported and not used: %q", path)
-	} else {
-		yyerrorl(lineno, "imported and not used: %q as %s", path, name)
-	}
-}
-
-func mkpackage(pkgname string) {
-	if localpkg.Name == "" {
-		if pkgname == "_" {
-			yyerror("invalid package name _")
-		}
-		localpkg.Name = pkgname
-	} else {
-		if pkgname != localpkg.Name {
-			yyerror("package %s; expected %s", pkgname, localpkg.Name)
-		}
-	}
-}
-
-func clearImports() {
-	type importedPkg struct {
-		pos  src.XPos
-		path string
-		name string
-	}
-	var unused []importedPkg
-
-	for _, s := range localpkg.Syms {
-		n := asNode(s.Def)
-		if n == nil {
-			continue
-		}
-		if n.Op == OPACK {
-			// throw away top-level package name left over
-			// from previous file.
-			// leave s->block set to cause redeclaration
-			// errors if a conflicting top-level name is
-			// introduced by a different file.
-			if !n.Name.Used() && nsyntaxerrors == 0 {
-				unused = append(unused, importedPkg{n.Pos, n.Name.Pkg.Path, s.Name})
-			}
-			s.Def = nil
-			continue
-		}
-		if IsAlias(s) {
-			// throw away top-level name left over
-			// from previous import . "x"
-			if n.Name != nil && n.Name.Pack != nil && !n.Name.Pack.Name.Used() && nsyntaxerrors == 0 {
-				unused = append(unused, importedPkg{n.Name.Pack.Pos, n.Name.Pack.Name.Pkg.Path, ""})
-				n.Name.Pack.Name.SetUsed(true)
-			}
-			s.Def = nil
-			continue
-		}
-	}
-
-	sort.Slice(unused, func(i, j int) bool { return unused[i].pos.Before(unused[j].pos) })
-	for _, pkg := range unused {
-		pkgnotused(pkg.pos, pkg.path, pkg.name)
-	}
-}
-
-func IsAlias(sym *types.Sym) bool {
-	return sym.Def != nil && asNode(sym.Def).Sym != sym
-}
-
-// By default, assume any debug flags are incompatible with concurrent
-// compilation. A few are safe and potentially in common use for
-// normal compiles, though; return true for those.
-func concurrentFlagOk() bool {
-	// Report whether any debug flag that would prevent concurrent
-	// compilation is set, by zeroing out the allowed ones and then
-	// checking if the resulting struct is zero.
-	d := Debug
-	d.B = 0 // disable bounds checking
-	d.C = 0 // disable printing of columns in error messages
-	d.e = 0 // no limit on errors; errors all come from non-concurrent code
-	d.N = 0 // disable optimizations
-	d.l = 0 // disable inlining
-	d.w = 0 // all printing happens before compilation
-	d.W = 0 // all printing happens before compilation
-	d.S = 0 // printing disassembly happens at the end (but see concurrentBackendAllowed below)
-
-	return d == DebugFlags{}
-}
-
-func concurrentBackendAllowed() bool {
-	if !concurrentFlagOk() {
-		return false
-	}
-
-	// Debug.S by itself is ok, because all printing occurs
-	// while writing the object file, and that is non-concurrent.
-	// Adding Debug_vlog, however, causes Debug.S to also print
-	// while flushing the plist, which happens concurrently.
-	if Debug_vlog || debugstr != "" || debuglive > 0 {
-		return false
-	}
-	// TODO: Test and delete this condition.
-	if objabi.Fieldtrack_enabled != 0 {
-		return false
-	}
-	// TODO: fix races and enable the following flags
-	if Ctxt.Flag_shared || Ctxt.Flag_dynlink || flag_race {
-		return false
-	}
-	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.SDWARFCUINFO
-	// 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:]
-}
-
-// recordPackageName records the name of the package being
-// compiled, so that the linker can save it in the compile unit's DIE.
-func recordPackageName() {
-	s := Ctxt.Lookup(dwarf.CUInfoPrefix + "packagename." + myimportpath)
-	s.Type = objabi.SDWARFCUINFO
-	// 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 = []byte(localpkg.Name)
-}
-
-// flag_lang is the language version we are compiling for, set by the -lang flag.
-var flag_lang string
-
-// currentLang returns the current language version.
-func currentLang() string {
-	return fmt.Sprintf("go1.%d", goversion.Version)
-}
-
-// goVersionRE is a regular expression that matches the valid
-// arguments to the -lang flag.
-var goVersionRE = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
-
-// A lang is a language version broken into major and minor numbers.
-type lang struct {
-	major, minor int
-}
-
-// langWant is the desired language version set by the -lang flag.
-// If the -lang flag is not set, this is the zero value, meaning that
-// any language version is supported.
-var langWant lang
-
-// langSupported reports whether language version major.minor is
-// supported in a particular package.
-func langSupported(major, minor int, pkg *types.Pkg) bool {
-	if pkg == nil {
-		// TODO(mdempsky): Set Pkg for local types earlier.
-		pkg = localpkg
-	}
-	if pkg != localpkg {
-		// Assume imported packages passed type-checking.
-		return true
-	}
-
-	if langWant.major == 0 && langWant.minor == 0 {
-		return true
-	}
-	return langWant.major > major || (langWant.major == major && langWant.minor >= minor)
-}
-
-// checkLang verifies that the -lang flag holds a valid value, and
-// exits if not. It initializes data used by langSupported.
-func checkLang() {
-	if flag_lang == "" {
-		return
-	}
-
-	var err error
-	langWant, err = parseLang(flag_lang)
-	if err != nil {
-		log.Fatalf("invalid value %q for -lang: %v", flag_lang, err)
-	}
-
-	if def := currentLang(); flag_lang != def {
-		defVers, err := parseLang(def)
-		if err != nil {
-			log.Fatalf("internal error parsing default lang %q: %v", def, err)
-		}
-		if langWant.major > defVers.major || (langWant.major == defVers.major && langWant.minor > defVers.minor) {
-			log.Fatalf("invalid value %q for -lang: max known version is %q", flag_lang, def)
-		}
-	}
-}
-
-// parseLang parses a -lang option into a langVer.
-func parseLang(s string) (lang, error) {
-	matches := goVersionRE.FindStringSubmatch(s)
-	if matches == nil {
-		return lang{}, fmt.Errorf(`should be something like "go1.12"`)
-	}
-	major, err := strconv.Atoi(matches[1])
-	if err != nil {
-		return lang{}, err
-	}
-	minor, err := strconv.Atoi(matches[2])
-	if err != nil {
-		return lang{}, err
-	}
-	return lang{major: major, minor: minor}, nil
+func makePos(b *src.PosBase, line, col uint) src.XPos {
+	return base.Ctxt.PosTable.XPos(src.MakePos(b, line, col))
 }
diff --git a/src/cmd/compile/internal/gc/mapfile_mmap.go b/src/cmd/compile/internal/gc/mapfile_mmap.go
deleted file mode 100644
index 9483688..0000000
--- a/src/cmd/compile/internal/gc/mapfile_mmap.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd
-
-package gc
-
-import (
-	"os"
-	"reflect"
-	"syscall"
-	"unsafe"
-)
-
-// TODO(mdempsky): Is there a higher-level abstraction that still
-// works well for iimport?
-
-// mapFile returns length bytes from the file starting at the
-// specified offset as a string.
-func mapFile(f *os.File, offset, length int64) (string, error) {
-	// POSIX mmap: "The implementation may require that off is a
-	// multiple of the page size."
-	x := offset & int64(os.Getpagesize()-1)
-	offset -= x
-	length += x
-
-	buf, err := syscall.Mmap(int(f.Fd()), offset, int(length), syscall.PROT_READ, syscall.MAP_SHARED)
-	keepAlive(f)
-	if err != nil {
-		return "", err
-	}
-
-	buf = buf[x:]
-	pSlice := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
-
-	var res string
-	pString := (*reflect.StringHeader)(unsafe.Pointer(&res))
-
-	pString.Data = pSlice.Data
-	pString.Len = pSlice.Len
-
-	return res, nil
-}
-
-// keepAlive is a reimplementation of runtime.KeepAlive, which wasn't
-// added until Go 1.7, whereas we need to compile with Go 1.4.
-var keepAlive = func(interface{}) {}
diff --git a/src/cmd/compile/internal/gc/mapfile_read.go b/src/cmd/compile/internal/gc/mapfile_read.go
deleted file mode 100644
index c6f68ed..0000000
--- a/src/cmd/compile/internal/gc/mapfile_read.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd
-
-package gc
-
-import (
-	"io"
-	"os"
-)
-
-func mapFile(f *os.File, offset, length int64) (string, error) {
-	buf := make([]byte, length)
-	_, err := io.ReadFull(io.NewSectionReader(f, offset, length), buf)
-	if err != nil {
-		return "", err
-	}
-	return string(buf), nil
-}
diff --git a/src/cmd/compile/internal/gc/mkbuiltin.go b/src/cmd/compile/internal/gc/mkbuiltin.go
deleted file mode 100644
index 63d2a12..0000000
--- a/src/cmd/compile/internal/gc/mkbuiltin.go
+++ /dev/null
@@ -1,225 +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.
-
-// +build ignore
-
-// Generate builtin.go from builtin/runtime.go.
-
-package main
-
-import (
-	"bytes"
-	"flag"
-	"fmt"
-	"go/ast"
-	"go/format"
-	"go/parser"
-	"go/token"
-	"io"
-	"io/ioutil"
-	"log"
-	"os"
-	"path/filepath"
-	"strconv"
-	"strings"
-)
-
-var stdout = flag.Bool("stdout", false, "write to stdout instead of builtin.go")
-
-func main() {
-	flag.Parse()
-
-	var b bytes.Buffer
-	fmt.Fprintln(&b, "// Code generated by mkbuiltin.go. DO NOT EDIT.")
-	fmt.Fprintln(&b)
-	fmt.Fprintln(&b, "package gc")
-	fmt.Fprintln(&b)
-	fmt.Fprintln(&b, `import "cmd/compile/internal/types"`)
-
-	mkbuiltin(&b, "runtime")
-
-	out, err := format.Source(b.Bytes())
-	if err != nil {
-		log.Fatal(err)
-	}
-	if *stdout {
-		_, err = os.Stdout.Write(out)
-	} else {
-		err = ioutil.WriteFile("builtin.go", out, 0666)
-	}
-	if err != nil {
-		log.Fatal(err)
-	}
-}
-
-func mkbuiltin(w io.Writer, name string) {
-	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, filepath.Join("builtin", name+".go"), nil, 0)
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	var interner typeInterner
-
-	fmt.Fprintf(w, "var %sDecls = [...]struct { name string; tag int; typ int }{\n", name)
-	for _, decl := range f.Decls {
-		switch decl := decl.(type) {
-		case *ast.FuncDecl:
-			if decl.Recv != nil {
-				log.Fatal("methods unsupported")
-			}
-			if decl.Body != nil {
-				log.Fatal("unexpected function body")
-			}
-			fmt.Fprintf(w, "{%q, funcTag, %d},\n", decl.Name.Name, interner.intern(decl.Type))
-		case *ast.GenDecl:
-			if decl.Tok == token.IMPORT {
-				if len(decl.Specs) != 1 || decl.Specs[0].(*ast.ImportSpec).Path.Value != "\"unsafe\"" {
-					log.Fatal("runtime cannot import other package")
-				}
-				continue
-			}
-			if decl.Tok != token.VAR {
-				log.Fatal("unhandled declaration kind", decl.Tok)
-			}
-			for _, spec := range decl.Specs {
-				spec := spec.(*ast.ValueSpec)
-				if len(spec.Values) != 0 {
-					log.Fatal("unexpected values")
-				}
-				typ := interner.intern(spec.Type)
-				for _, name := range spec.Names {
-					fmt.Fprintf(w, "{%q, varTag, %d},\n", name.Name, typ)
-				}
-			}
-		default:
-			log.Fatal("unhandled decl type", decl)
-		}
-	}
-	fmt.Fprintln(w, "}")
-
-	fmt.Fprintln(w)
-	fmt.Fprintf(w, "func %sTypes() []*types.Type {\n", name)
-	fmt.Fprintf(w, "var typs [%d]*types.Type\n", len(interner.typs))
-	for i, typ := range interner.typs {
-		fmt.Fprintf(w, "typs[%d] = %s\n", i, typ)
-	}
-	fmt.Fprintln(w, "return typs[:]")
-	fmt.Fprintln(w, "}")
-}
-
-// typeInterner maps Go type expressions to compiler code that
-// constructs the denoted type. It recognizes and reuses common
-// subtype expressions.
-type typeInterner struct {
-	typs []string
-	hash map[string]int
-}
-
-func (i *typeInterner) intern(t ast.Expr) int {
-	x := i.mktype(t)
-	v, ok := i.hash[x]
-	if !ok {
-		v = len(i.typs)
-		if i.hash == nil {
-			i.hash = make(map[string]int)
-		}
-		i.hash[x] = v
-		i.typs = append(i.typs, x)
-	}
-	return v
-}
-
-func (i *typeInterner) subtype(t ast.Expr) string {
-	return fmt.Sprintf("typs[%d]", i.intern(t))
-}
-
-func (i *typeInterner) mktype(t ast.Expr) string {
-	switch t := t.(type) {
-	case *ast.Ident:
-		switch t.Name {
-		case "byte":
-			return "types.Bytetype"
-		case "rune":
-			return "types.Runetype"
-		}
-		return fmt.Sprintf("types.Types[T%s]", strings.ToUpper(t.Name))
-	case *ast.SelectorExpr:
-		if t.X.(*ast.Ident).Name != "unsafe" || t.Sel.Name != "Pointer" {
-			log.Fatalf("unhandled type: %#v", t)
-		}
-		return "types.Types[TUNSAFEPTR]"
-
-	case *ast.ArrayType:
-		if t.Len == nil {
-			return fmt.Sprintf("types.NewSlice(%s)", i.subtype(t.Elt))
-		}
-		return fmt.Sprintf("types.NewArray(%s, %d)", i.subtype(t.Elt), intconst(t.Len))
-	case *ast.ChanType:
-		dir := "types.Cboth"
-		switch t.Dir {
-		case ast.SEND:
-			dir = "types.Csend"
-		case ast.RECV:
-			dir = "types.Crecv"
-		}
-		return fmt.Sprintf("types.NewChan(%s, %s)", i.subtype(t.Value), dir)
-	case *ast.FuncType:
-		return fmt.Sprintf("functype(nil, %s, %s)", i.fields(t.Params, false), i.fields(t.Results, false))
-	case *ast.InterfaceType:
-		if len(t.Methods.List) != 0 {
-			log.Fatal("non-empty interfaces unsupported")
-		}
-		return "types.Types[TINTER]"
-	case *ast.MapType:
-		return fmt.Sprintf("types.NewMap(%s, %s)", i.subtype(t.Key), i.subtype(t.Value))
-	case *ast.StarExpr:
-		return fmt.Sprintf("types.NewPtr(%s)", i.subtype(t.X))
-	case *ast.StructType:
-		return fmt.Sprintf("tostruct(%s)", i.fields(t.Fields, true))
-
-	default:
-		log.Fatalf("unhandled type: %#v", t)
-		panic("unreachable")
-	}
-}
-
-func (i *typeInterner) fields(fl *ast.FieldList, keepNames bool) string {
-	if fl == nil || len(fl.List) == 0 {
-		return "nil"
-	}
-	var res []string
-	for _, f := range fl.List {
-		typ := i.subtype(f.Type)
-		if len(f.Names) == 0 {
-			res = append(res, fmt.Sprintf("anonfield(%s)", typ))
-		} else {
-			for _, name := range f.Names {
-				if keepNames {
-					res = append(res, fmt.Sprintf("namedfield(%q, %s)", name.Name, typ))
-				} else {
-					res = append(res, fmt.Sprintf("anonfield(%s)", typ))
-				}
-			}
-		}
-	}
-	return fmt.Sprintf("[]*Node{%s}", strings.Join(res, ", "))
-}
-
-func intconst(e ast.Expr) int64 {
-	switch e := e.(type) {
-	case *ast.BasicLit:
-		if e.Kind != token.INT {
-			log.Fatalf("expected INT, got %v", e.Kind)
-		}
-		x, err := strconv.ParseInt(e.Value, 0, 64)
-		if err != nil {
-			log.Fatal(err)
-		}
-		return x
-	default:
-		log.Fatalf("unhandled expr: %#v", e)
-		panic("unreachable")
-	}
-}
diff --git a/src/cmd/compile/internal/gc/mpfloat.go b/src/cmd/compile/internal/gc/mpfloat.go
deleted file mode 100644
index 401aef3..0000000
--- a/src/cmd/compile/internal/gc/mpfloat.go
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
-	"fmt"
-	"math"
-	"math/big"
-)
-
-// implements float arithmetic
-
-const (
-	// Maximum size in bits for Mpints before signalling
-	// overflow and also mantissa precision for Mpflts.
-	Mpprec = 512
-	// Turn on for constant arithmetic debugging output.
-	Mpdebug = false
-)
-
-// Mpflt represents a floating-point constant.
-type Mpflt struct {
-	Val big.Float
-}
-
-// Mpcplx represents a complex constant.
-type Mpcplx struct {
-	Real Mpflt
-	Imag Mpflt
-}
-
-// Use newMpflt (not new(Mpflt)!) to get the correct default precision.
-func newMpflt() *Mpflt {
-	var a Mpflt
-	a.Val.SetPrec(Mpprec)
-	return &a
-}
-
-// Use newMpcmplx (not new(Mpcplx)!) to get the correct default precision.
-func newMpcmplx() *Mpcplx {
-	var a Mpcplx
-	a.Real = *newMpflt()
-	a.Imag = *newMpflt()
-	return &a
-}
-
-func (a *Mpflt) SetInt(b *Mpint) {
-	if b.checkOverflow(0) {
-		// sign doesn't really matter but copy anyway
-		a.Val.SetInf(b.Val.Sign() < 0)
-		return
-	}
-	a.Val.SetInt(&b.Val)
-}
-
-func (a *Mpflt) Set(b *Mpflt) {
-	a.Val.Set(&b.Val)
-}
-
-func (a *Mpflt) Add(b *Mpflt) {
-	if Mpdebug {
-		fmt.Printf("\n%v + %v", a, b)
-	}
-
-	a.Val.Add(&a.Val, &b.Val)
-
-	if Mpdebug {
-		fmt.Printf(" = %v\n\n", a)
-	}
-}
-
-func (a *Mpflt) AddFloat64(c float64) {
-	var b Mpflt
-
-	b.SetFloat64(c)
-	a.Add(&b)
-}
-
-func (a *Mpflt) Sub(b *Mpflt) {
-	if Mpdebug {
-		fmt.Printf("\n%v - %v", a, b)
-	}
-
-	a.Val.Sub(&a.Val, &b.Val)
-
-	if Mpdebug {
-		fmt.Printf(" = %v\n\n", a)
-	}
-}
-
-func (a *Mpflt) Mul(b *Mpflt) {
-	if Mpdebug {
-		fmt.Printf("%v\n * %v\n", a, b)
-	}
-
-	a.Val.Mul(&a.Val, &b.Val)
-
-	if Mpdebug {
-		fmt.Printf(" = %v\n\n", a)
-	}
-}
-
-func (a *Mpflt) MulFloat64(c float64) {
-	var b Mpflt
-
-	b.SetFloat64(c)
-	a.Mul(&b)
-}
-
-func (a *Mpflt) Quo(b *Mpflt) {
-	if Mpdebug {
-		fmt.Printf("%v\n / %v\n", a, b)
-	}
-
-	a.Val.Quo(&a.Val, &b.Val)
-
-	if Mpdebug {
-		fmt.Printf(" = %v\n\n", a)
-	}
-}
-
-func (a *Mpflt) Cmp(b *Mpflt) int {
-	return a.Val.Cmp(&b.Val)
-}
-
-func (a *Mpflt) CmpFloat64(c float64) int {
-	if c == 0 {
-		return a.Val.Sign() // common case shortcut
-	}
-	return a.Val.Cmp(big.NewFloat(c))
-}
-
-func (a *Mpflt) Float64() float64 {
-	x, _ := a.Val.Float64()
-
-	// check for overflow
-	if math.IsInf(x, 0) && nsavederrors+nerrors == 0 {
-		Fatalf("ovf in Mpflt Float64")
-	}
-
-	return x + 0 // avoid -0 (should not be needed, but be conservative)
-}
-
-func (a *Mpflt) Float32() float64 {
-	x32, _ := a.Val.Float32()
-	x := float64(x32)
-
-	// check for overflow
-	if math.IsInf(x, 0) && nsavederrors+nerrors == 0 {
-		Fatalf("ovf in Mpflt Float32")
-	}
-
-	return x + 0 // avoid -0 (should not be needed, but be conservative)
-}
-
-func (a *Mpflt) SetFloat64(c float64) {
-	if Mpdebug {
-		fmt.Printf("\nconst %g", c)
-	}
-
-	// convert -0 to 0
-	if c == 0 {
-		c = 0
-	}
-	a.Val.SetFloat64(c)
-
-	if Mpdebug {
-		fmt.Printf(" = %v\n", a)
-	}
-}
-
-func (a *Mpflt) Neg() {
-	// avoid -0
-	if a.Val.Sign() != 0 {
-		a.Val.Neg(&a.Val)
-	}
-}
-
-func (a *Mpflt) SetString(as string) {
-	f, _, err := a.Val.Parse(as, 0)
-	if err != nil {
-		yyerror("malformed constant: %s (%v)", as, err)
-		a.Val.SetFloat64(0)
-		return
-	}
-
-	if f.IsInf() {
-		yyerror("constant too large: %s", as)
-		a.Val.SetFloat64(0)
-		return
-	}
-
-	// -0 becomes 0
-	if f.Sign() == 0 && f.Signbit() {
-		a.Val.SetFloat64(0)
-	}
-}
-
-func (f *Mpflt) String() string {
-	return f.Val.Text('b', 0)
-}
-
-func (fvp *Mpflt) GoString() string {
-	// determine sign
-	sign := ""
-	f := &fvp.Val
-	if f.Sign() < 0 {
-		sign = "-"
-		f = new(big.Float).Abs(f)
-	}
-
-	// Don't try to convert infinities (will not terminate).
-	if f.IsInf() {
-		return sign + "Inf"
-	}
-
-	// Use exact fmt formatting if in float64 range (common case):
-	// proceed if f doesn't underflow to 0 or overflow to inf.
-	if x, _ := f.Float64(); f.Sign() == 0 == (x == 0) && !math.IsInf(x, 0) {
-		return fmt.Sprintf("%s%.6g", sign, x)
-	}
-
-	// Out of float64 range. Do approximate manual to decimal
-	// conversion to avoid precise but possibly slow Float
-	// formatting.
-	// f = mant * 2**exp
-	var mant big.Float
-	exp := f.MantExp(&mant) // 0.5 <= mant < 1.0
-
-	// approximate float64 mantissa m and decimal exponent d
-	// f ~ m * 10**d
-	m, _ := mant.Float64()                     // 0.5 <= m < 1.0
-	d := float64(exp) * (math.Ln2 / math.Ln10) // log_10(2)
-
-	// adjust m for truncated (integer) decimal exponent e
-	e := int64(d)
-	m *= math.Pow(10, d-float64(e))
-
-	// ensure 1 <= m < 10
-	switch {
-	case m < 1-0.5e-6:
-		// The %.6g format below rounds m to 5 digits after the
-		// decimal point. Make sure that m*10 < 10 even after
-		// rounding up: m*10 + 0.5e-5 < 10 => m < 1 - 0.5e6.
-		m *= 10
-		e--
-	case m >= 10:
-		m /= 10
-		e++
-	}
-
-	return fmt.Sprintf("%s%.6ge%+d", sign, m, e)
-}
-
-// complex multiply v *= rv
-//	(a, b) * (c, d) = (a*c - b*d, b*c + a*d)
-func (v *Mpcplx) Mul(rv *Mpcplx) {
-	var ac, ad, bc, bd Mpflt
-
-	ac.Set(&v.Real)
-	ac.Mul(&rv.Real) // ac
-
-	bd.Set(&v.Imag)
-	bd.Mul(&rv.Imag) // bd
-
-	bc.Set(&v.Imag)
-	bc.Mul(&rv.Real) // bc
-
-	ad.Set(&v.Real)
-	ad.Mul(&rv.Imag) // ad
-
-	v.Real.Set(&ac)
-	v.Real.Sub(&bd) // ac-bd
-
-	v.Imag.Set(&bc)
-	v.Imag.Add(&ad) // bc+ad
-}
-
-// complex divide v /= rv
-//	(a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d)
-func (v *Mpcplx) Div(rv *Mpcplx) bool {
-	if rv.Real.CmpFloat64(0) == 0 && rv.Imag.CmpFloat64(0) == 0 {
-		return false
-	}
-
-	var ac, ad, bc, bd, cc_plus_dd Mpflt
-
-	cc_plus_dd.Set(&rv.Real)
-	cc_plus_dd.Mul(&rv.Real) // cc
-
-	ac.Set(&rv.Imag)
-	ac.Mul(&rv.Imag)    // dd
-	cc_plus_dd.Add(&ac) // cc+dd
-
-	// We already checked that c and d are not both zero, but we can't
-	// assume that c²+d² != 0 follows, because for tiny values of c
-	// and/or d c²+d² can underflow to zero.  Check that c²+d² is
-	// nonzero, return if it's not.
-	if cc_plus_dd.CmpFloat64(0) == 0 {
-		return false
-	}
-
-	ac.Set(&v.Real)
-	ac.Mul(&rv.Real) // ac
-
-	bd.Set(&v.Imag)
-	bd.Mul(&rv.Imag) // bd
-
-	bc.Set(&v.Imag)
-	bc.Mul(&rv.Real) // bc
-
-	ad.Set(&v.Real)
-	ad.Mul(&rv.Imag) // ad
-
-	v.Real.Set(&ac)
-	v.Real.Add(&bd)         // ac+bd
-	v.Real.Quo(&cc_plus_dd) // (ac+bd)/(cc+dd)
-
-	v.Imag.Set(&bc)
-	v.Imag.Sub(&ad)         // bc-ad
-	v.Imag.Quo(&cc_plus_dd) // (bc+ad)/(cc+dd)
-
-	return true
-}
-
-func (v *Mpcplx) String() string {
-	return fmt.Sprintf("(%s+%si)", v.Real.String(), v.Imag.String())
-}
-
-func (v *Mpcplx) GoString() string {
-	var re string
-	sre := v.Real.CmpFloat64(0)
-	if sre != 0 {
-		re = v.Real.GoString()
-	}
-
-	var im string
-	sim := v.Imag.CmpFloat64(0)
-	if sim != 0 {
-		im = v.Imag.GoString()
-	}
-
-	switch {
-	case sre == 0 && sim == 0:
-		return "0"
-	case sre == 0:
-		return im + "i"
-	case sim == 0:
-		return re
-	case sim < 0:
-		return fmt.Sprintf("(%s%si)", re, im)
-	default:
-		return fmt.Sprintf("(%s+%si)", re, im)
-	}
-}
diff --git a/src/cmd/compile/internal/gc/mpint.go b/src/cmd/compile/internal/gc/mpint.go
deleted file mode 100644
index 340350b..0000000
--- a/src/cmd/compile/internal/gc/mpint.go
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright 2009 The Go Authors. 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 (
-	"fmt"
-	"math/big"
-)
-
-// implements integer arithmetic
-
-// Mpint represents an integer constant.
-type Mpint struct {
-	Val  big.Int
-	Ovf  bool // set if Val overflowed compiler limit (sticky)
-	Rune bool // set if syntax indicates default type rune
-}
-
-func (a *Mpint) SetOverflow() {
-	a.Val.SetUint64(1) // avoid spurious div-zero errors
-	a.Ovf = true
-}
-
-func (a *Mpint) checkOverflow(extra int) bool {
-	// We don't need to be precise here, any reasonable upper limit would do.
-	// For now, use existing limit so we pass all the tests unchanged.
-	if a.Val.BitLen()+extra > Mpprec {
-		a.SetOverflow()
-	}
-	return a.Ovf
-}
-
-func (a *Mpint) Set(b *Mpint) {
-	a.Val.Set(&b.Val)
-}
-
-func (a *Mpint) SetFloat(b *Mpflt) bool {
-	// avoid converting huge floating-point numbers to integers
-	// (2*Mpprec is large enough to permit all tests to pass)
-	if b.Val.MantExp(nil) > 2*Mpprec {
-		a.SetOverflow()
-		return false
-	}
-
-	if _, acc := b.Val.Int(&a.Val); acc == big.Exact {
-		return true
-	}
-
-	const delta = 16 // a reasonably small number of bits > 0
-	var t big.Float
-	t.SetPrec(Mpprec - delta)
-
-	// try rounding down a little
-	t.SetMode(big.ToZero)
-	t.Set(&b.Val)
-	if _, acc := t.Int(&a.Val); acc == big.Exact {
-		return true
-	}
-
-	// try rounding up a little
-	t.SetMode(big.AwayFromZero)
-	t.Set(&b.Val)
-	if _, acc := t.Int(&a.Val); acc == big.Exact {
-		return true
-	}
-
-	a.Ovf = false
-	return false
-}
-
-func (a *Mpint) Add(b *Mpint) {
-	if a.Ovf || b.Ovf {
-		if nsavederrors+nerrors == 0 {
-			Fatalf("ovf in Mpint Add")
-		}
-		a.SetOverflow()
-		return
-	}
-
-	a.Val.Add(&a.Val, &b.Val)
-
-	if a.checkOverflow(0) {
-		yyerror("constant addition overflow")
-	}
-}
-
-func (a *Mpint) Sub(b *Mpint) {
-	if a.Ovf || b.Ovf {
-		if nsavederrors+nerrors == 0 {
-			Fatalf("ovf in Mpint Sub")
-		}
-		a.SetOverflow()
-		return
-	}
-
-	a.Val.Sub(&a.Val, &b.Val)
-
-	if a.checkOverflow(0) {
-		yyerror("constant subtraction overflow")
-	}
-}
-
-func (a *Mpint) Mul(b *Mpint) {
-	if a.Ovf || b.Ovf {
-		if nsavederrors+nerrors == 0 {
-			Fatalf("ovf in Mpint Mul")
-		}
-		a.SetOverflow()
-		return
-	}
-
-	a.Val.Mul(&a.Val, &b.Val)
-
-	if a.checkOverflow(0) {
-		yyerror("constant multiplication overflow")
-	}
-}
-
-func (a *Mpint) Quo(b *Mpint) {
-	if a.Ovf || b.Ovf {
-		if nsavederrors+nerrors == 0 {
-			Fatalf("ovf in Mpint Quo")
-		}
-		a.SetOverflow()
-		return
-	}
-
-	a.Val.Quo(&a.Val, &b.Val)
-
-	if a.checkOverflow(0) {
-		// can only happen for div-0 which should be checked elsewhere
-		yyerror("constant division overflow")
-	}
-}
-
-func (a *Mpint) Rem(b *Mpint) {
-	if a.Ovf || b.Ovf {
-		if nsavederrors+nerrors == 0 {
-			Fatalf("ovf in Mpint Rem")
-		}
-		a.SetOverflow()
-		return
-	}
-
-	a.Val.Rem(&a.Val, &b.Val)
-
-	if a.checkOverflow(0) {
-		// should never happen
-		yyerror("constant modulo overflow")
-	}
-}
-
-func (a *Mpint) Or(b *Mpint) {
-	if a.Ovf || b.Ovf {
-		if nsavederrors+nerrors == 0 {
-			Fatalf("ovf in Mpint Or")
-		}
-		a.SetOverflow()
-		return
-	}
-
-	a.Val.Or(&a.Val, &b.Val)
-}
-
-func (a *Mpint) And(b *Mpint) {
-	if a.Ovf || b.Ovf {
-		if nsavederrors+nerrors == 0 {
-			Fatalf("ovf in Mpint And")
-		}
-		a.SetOverflow()
-		return
-	}
-
-	a.Val.And(&a.Val, &b.Val)
-}
-
-func (a *Mpint) AndNot(b *Mpint) {
-	if a.Ovf || b.Ovf {
-		if nsavederrors+nerrors == 0 {
-			Fatalf("ovf in Mpint AndNot")
-		}
-		a.SetOverflow()
-		return
-	}
-
-	a.Val.AndNot(&a.Val, &b.Val)
-}
-
-func (a *Mpint) Xor(b *Mpint) {
-	if a.Ovf || b.Ovf {
-		if nsavederrors+nerrors == 0 {
-			Fatalf("ovf in Mpint Xor")
-		}
-		a.SetOverflow()
-		return
-	}
-
-	a.Val.Xor(&a.Val, &b.Val)
-}
-
-func (a *Mpint) Lsh(b *Mpint) {
-	if a.Ovf || b.Ovf {
-		if nsavederrors+nerrors == 0 {
-			Fatalf("ovf in Mpint Lsh")
-		}
-		a.SetOverflow()
-		return
-	}
-
-	s := b.Int64()
-	if s < 0 || s >= Mpprec {
-		msg := "shift count too large"
-		if s < 0 {
-			msg = "invalid negative shift count"
-		}
-		yyerror("%s: %d", msg, s)
-		a.SetInt64(0)
-		return
-	}
-
-	if a.checkOverflow(int(s)) {
-		yyerror("constant shift overflow")
-		return
-	}
-	a.Val.Lsh(&a.Val, uint(s))
-}
-
-func (a *Mpint) Rsh(b *Mpint) {
-	if a.Ovf || b.Ovf {
-		if nsavederrors+nerrors == 0 {
-			Fatalf("ovf in Mpint Rsh")
-		}
-		a.SetOverflow()
-		return
-	}
-
-	s := b.Int64()
-	if s < 0 {
-		yyerror("invalid negative shift count: %d", s)
-		if a.Val.Sign() < 0 {
-			a.SetInt64(-1)
-		} else {
-			a.SetInt64(0)
-		}
-		return
-	}
-
-	a.Val.Rsh(&a.Val, uint(s))
-}
-
-func (a *Mpint) Cmp(b *Mpint) int {
-	return a.Val.Cmp(&b.Val)
-}
-
-func (a *Mpint) CmpInt64(c int64) int {
-	if c == 0 {
-		return a.Val.Sign() // common case shortcut
-	}
-	return a.Val.Cmp(big.NewInt(c))
-}
-
-func (a *Mpint) Neg() {
-	a.Val.Neg(&a.Val)
-}
-
-func (a *Mpint) Int64() int64 {
-	if a.Ovf {
-		if nsavederrors+nerrors == 0 {
-			Fatalf("constant overflow")
-		}
-		return 0
-	}
-
-	return a.Val.Int64()
-}
-
-func (a *Mpint) SetInt64(c int64) {
-	a.Val.SetInt64(c)
-}
-
-func (a *Mpint) SetString(as string) {
-	_, ok := a.Val.SetString(as, 0)
-	if !ok {
-		// The lexer checks for correct syntax of the literal
-		// and reports detailed errors. Thus SetString should
-		// never fail (in theory it might run out of memory,
-		// but that wouldn't be reported as an error here).
-		Fatalf("malformed integer constant: %s", as)
-		return
-	}
-	if a.checkOverflow(0) {
-		yyerror("constant too large: %s", as)
-	}
-}
-
-func (a *Mpint) GoString() string {
-	return a.Val.String()
-}
-
-func (a *Mpint) String() string {
-	return fmt.Sprintf("%#x", &a.Val)
-}
diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go
deleted file mode 100644
index 7494c3e..0000000
--- a/src/cmd/compile/internal/gc/noder.go
+++ /dev/null
@@ -1,1756 +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.
-
-package gc
-
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"runtime"
-	"strconv"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-
-	"cmd/compile/internal/syntax"
-	"cmd/compile/internal/types"
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"cmd/internal/src"
-)
-
-// parseFiles concurrently parses files into *syntax.File structures.
-// Each declaration in every *syntax.File is converted to a syntax tree
-// and its root represented by *Node is appended to xtop.
-// Returns the total count of parsed lines.
-func parseFiles(filenames []string) uint {
-	noders := make([]*noder, 0, len(filenames))
-	// Limit the number of simultaneously open files.
-	sem := make(chan struct{}, runtime.GOMAXPROCS(0)+10)
-
-	for _, filename := range filenames {
-		p := &noder{
-			basemap: make(map[*syntax.PosBase]*src.PosBase),
-			err:     make(chan syntax.Error),
-		}
-		noders = append(noders, p)
-
-		go func(filename string) {
-			sem <- struct{}{}
-			defer func() { <-sem }()
-			defer close(p.err)
-			base := syntax.NewFileBase(filename)
-
-			f, err := os.Open(filename)
-			if err != nil {
-				p.error(syntax.Error{Msg: err.Error()})
-				return
-			}
-			defer f.Close()
-
-			p.file, _ = syntax.Parse(base, f, p.error, p.pragma, syntax.CheckBranches) // errors are tracked via p.error
-		}(filename)
-	}
-
-	var lines uint
-	for _, p := range noders {
-		for e := range p.err {
-			p.yyerrorpos(e.Pos, "%s", e.Msg)
-		}
-
-		p.node()
-		lines += p.file.Lines
-		p.file = nil // release memory
-
-		if nsyntaxerrors != 0 {
-			errorexit()
-		}
-		// Always run testdclstack here, even when debug_dclstack is not set, as a sanity measure.
-		testdclstack()
-	}
-
-	localpkg.Height = myheight
-
-	return lines
-}
-
-// makeSrcPosBase translates from a *syntax.PosBase to a *src.PosBase.
-func (p *noder) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase {
-	// fast path: most likely PosBase hasn't changed
-	if p.basecache.last == b0 {
-		return p.basecache.base
-	}
-
-	b1, ok := p.basemap[b0]
-	if !ok {
-		fn := b0.Filename()
-		if b0.IsFileBase() {
-			b1 = src.NewFileBase(fn, absFilename(fn))
-		} else {
-			// line directive base
-			p0 := b0.Pos()
-			p0b := p0.Base()
-			if p0b == b0 {
-				panic("infinite recursion in makeSrcPosBase")
-			}
-			p1 := src.MakePos(p.makeSrcPosBase(p0b), p0.Line(), p0.Col())
-			b1 = src.NewLinePragmaBase(p1, fn, fileh(fn), b0.Line(), b0.Col())
-		}
-		p.basemap[b0] = b1
-	}
-
-	// update cache
-	p.basecache.last = b0
-	p.basecache.base = b1
-
-	return b1
-}
-
-func (p *noder) makeXPos(pos syntax.Pos) (_ src.XPos) {
-	return Ctxt.PosTable.XPos(src.MakePos(p.makeSrcPosBase(pos.Base()), pos.Line(), pos.Col()))
-}
-
-func (p *noder) yyerrorpos(pos syntax.Pos, format string, args ...interface{}) {
-	yyerrorl(p.makeXPos(pos), format, args...)
-}
-
-var pathPrefix string
-
-// TODO(gri) Can we eliminate fileh in favor of absFilename?
-func fileh(name string) string {
-	return objabi.AbsFile("", name, pathPrefix)
-}
-
-func absFilename(name string) string {
-	return objabi.AbsFile(Ctxt.Pathname, name, pathPrefix)
-}
-
-// noder transforms package syntax's AST into a Node tree.
-type noder struct {
-	basemap   map[*syntax.PosBase]*src.PosBase
-	basecache struct {
-		last *syntax.PosBase
-		base *src.PosBase
-	}
-
-	file           *syntax.File
-	linknames      []linkname
-	pragcgobuf     [][]string
-	err            chan syntax.Error
-	scope          ScopeID
-	importedUnsafe bool
-	importedEmbed  bool
-
-	// scopeVars is a stack tracking the number of variables declared in the
-	// current function at the moment each open scope was opened.
-	scopeVars []int
-
-	lastCloseScopePos syntax.Pos
-}
-
-func (p *noder) funcBody(fn *Node, block *syntax.BlockStmt) {
-	oldScope := p.scope
-	p.scope = 0
-	funchdr(fn)
-
-	if block != nil {
-		body := p.stmts(block.List)
-		if body == nil {
-			body = []*Node{nod(OEMPTY, nil, nil)}
-		}
-		fn.Nbody.Set(body)
-
-		lineno = p.makeXPos(block.Rbrace)
-		fn.Func.Endlineno = lineno
-	}
-
-	funcbody()
-	p.scope = oldScope
-}
-
-func (p *noder) openScope(pos syntax.Pos) {
-	types.Markdcl()
-
-	if trackScopes {
-		Curfn.Func.Parents = append(Curfn.Func.Parents, p.scope)
-		p.scopeVars = append(p.scopeVars, len(Curfn.Func.Dcl))
-		p.scope = ScopeID(len(Curfn.Func.Parents))
-
-		p.markScope(pos)
-	}
-}
-
-func (p *noder) closeScope(pos syntax.Pos) {
-	p.lastCloseScopePos = pos
-	types.Popdcl()
-
-	if trackScopes {
-		scopeVars := p.scopeVars[len(p.scopeVars)-1]
-		p.scopeVars = p.scopeVars[:len(p.scopeVars)-1]
-		if scopeVars == len(Curfn.Func.Dcl) {
-			// no variables were declared in this scope, so we can retract it.
-
-			if int(p.scope) != len(Curfn.Func.Parents) {
-				Fatalf("scope tracking inconsistency, no variables declared but scopes were not retracted")
-			}
-
-			p.scope = Curfn.Func.Parents[p.scope-1]
-			Curfn.Func.Parents = Curfn.Func.Parents[:len(Curfn.Func.Parents)-1]
-
-			nmarks := len(Curfn.Func.Marks)
-			Curfn.Func.Marks[nmarks-1].Scope = p.scope
-			prevScope := ScopeID(0)
-			if nmarks >= 2 {
-				prevScope = Curfn.Func.Marks[nmarks-2].Scope
-			}
-			if Curfn.Func.Marks[nmarks-1].Scope == prevScope {
-				Curfn.Func.Marks = Curfn.Func.Marks[:nmarks-1]
-			}
-			return
-		}
-
-		p.scope = Curfn.Func.Parents[p.scope-1]
-
-		p.markScope(pos)
-	}
-}
-
-func (p *noder) markScope(pos syntax.Pos) {
-	xpos := p.makeXPos(pos)
-	if i := len(Curfn.Func.Marks); i > 0 && Curfn.Func.Marks[i-1].Pos == xpos {
-		Curfn.Func.Marks[i-1].Scope = p.scope
-	} else {
-		Curfn.Func.Marks = append(Curfn.Func.Marks, Mark{xpos, p.scope})
-	}
-}
-
-// closeAnotherScope is like closeScope, but it reuses the same mark
-// position as the last closeScope call. This is useful for "for" and
-// "if" statements, as their implicit blocks always end at the same
-// position as an explicit block.
-func (p *noder) closeAnotherScope() {
-	p.closeScope(p.lastCloseScopePos)
-}
-
-// linkname records a //go:linkname directive.
-type linkname struct {
-	pos    syntax.Pos
-	local  string
-	remote string
-}
-
-func (p *noder) node() {
-	types.Block = 1
-	p.importedUnsafe = false
-	p.importedEmbed = false
-
-	p.setlineno(p.file.PkgName)
-	mkpackage(p.file.PkgName.Value)
-
-	if pragma, ok := p.file.Pragma.(*Pragma); ok {
-		pragma.Flag &^= GoBuildPragma
-		p.checkUnused(pragma)
-	}
-
-	xtop = append(xtop, p.decls(p.file.DeclList)...)
-
-	for _, n := range p.linknames {
-		if !p.importedUnsafe {
-			p.yyerrorpos(n.pos, "//go:linkname only allowed in Go files that import \"unsafe\"")
-			continue
-		}
-		s := lookup(n.local)
-		if n.remote != "" {
-			s.Linkname = n.remote
-		} else {
-			// Use the default object symbol name if the
-			// user didn't provide one.
-			if myimportpath == "" {
-				p.yyerrorpos(n.pos, "//go:linkname requires linkname argument or -p compiler flag")
-			} else {
-				s.Linkname = objabi.PathToPrefix(myimportpath) + "." + n.local
-			}
-		}
-	}
-
-	// The linker expects an ABI0 wrapper for all cgo-exported
-	// functions.
-	for _, prag := range p.pragcgobuf {
-		switch prag[0] {
-		case "cgo_export_static", "cgo_export_dynamic":
-			if symabiRefs == nil {
-				symabiRefs = make(map[string]obj.ABI)
-			}
-			symabiRefs[prag[1]] = obj.ABI0
-		}
-	}
-
-	pragcgobuf = append(pragcgobuf, p.pragcgobuf...)
-	lineno = src.NoXPos
-	clearImports()
-}
-
-func (p *noder) decls(decls []syntax.Decl) (l []*Node) {
-	var cs constState
-
-	for _, decl := range decls {
-		p.setlineno(decl)
-		switch decl := decl.(type) {
-		case *syntax.ImportDecl:
-			p.importDecl(decl)
-
-		case *syntax.VarDecl:
-			l = append(l, p.varDecl(decl)...)
-
-		case *syntax.ConstDecl:
-			l = append(l, p.constDecl(decl, &cs)...)
-
-		case *syntax.TypeDecl:
-			l = append(l, p.typeDecl(decl))
-
-		case *syntax.FuncDecl:
-			l = append(l, p.funcDecl(decl))
-
-		default:
-			panic("unhandled Decl")
-		}
-	}
-
-	return
-}
-
-func (p *noder) importDecl(imp *syntax.ImportDecl) {
-	if imp.Path.Bad {
-		return // avoid follow-on errors if there was a syntax error
-	}
-
-	if pragma, ok := imp.Pragma.(*Pragma); ok {
-		p.checkUnused(pragma)
-	}
-
-	val := p.basicLit(imp.Path)
-	ipkg := importfile(&val)
-	if ipkg == nil {
-		if nerrors == 0 {
-			Fatalf("phase error in import")
-		}
-		return
-	}
-
-	if ipkg == unsafepkg {
-		p.importedUnsafe = true
-	}
-	if ipkg.Path == "embed" {
-		p.importedEmbed = true
-	}
-
-	ipkg.Direct = true
-
-	var my *types.Sym
-	if imp.LocalPkgName != nil {
-		my = p.name(imp.LocalPkgName)
-	} else {
-		my = lookup(ipkg.Name)
-	}
-
-	pack := p.nod(imp, OPACK, nil, nil)
-	pack.Sym = my
-	pack.Name.Pkg = ipkg
-
-	switch my.Name {
-	case ".":
-		importdot(ipkg, pack)
-		return
-	case "init":
-		yyerrorl(pack.Pos, "cannot import package as init - init must be a func")
-		return
-	case "_":
-		return
-	}
-	if my.Def != nil {
-		redeclare(pack.Pos, my, "as imported package name")
-	}
-	my.Def = asTypesNode(pack)
-	my.Lastlineno = pack.Pos
-	my.Block = 1 // at top level
-}
-
-func (p *noder) varDecl(decl *syntax.VarDecl) []*Node {
-	names := p.declNames(decl.NameList)
-	typ := p.typeExprOrNil(decl.Type)
-
-	var exprs []*Node
-	if decl.Values != nil {
-		exprs = p.exprList(decl.Values)
-	}
-
-	if pragma, ok := decl.Pragma.(*Pragma); ok {
-		if len(pragma.Embeds) > 0 {
-			if !p.importedEmbed {
-				// This check can't be done when building the list pragma.Embeds
-				// because that list is created before the noder starts walking over the file,
-				// so at that point it hasn't seen the imports.
-				// We're left to check now, just before applying the //go:embed lines.
-				for _, e := range pragma.Embeds {
-					p.yyerrorpos(e.Pos, "//go:embed only allowed in Go files that import \"embed\"")
-				}
-			} else {
-				varEmbed(p, names, typ, exprs, pragma.Embeds)
-			}
-			pragma.Embeds = nil
-		}
-		p.checkUnused(pragma)
-	}
-
-	p.setlineno(decl)
-	return variter(names, typ, exprs)
-}
-
-// constState tracks state between constant specifiers within a
-// declaration group. This state is kept separate from noder so nested
-// constant declarations are handled correctly (e.g., issue 15550).
-type constState struct {
-	group  *syntax.Group
-	typ    *Node
-	values []*Node
-	iota   int64
-}
-
-func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*Node {
-	if decl.Group == nil || decl.Group != cs.group {
-		*cs = constState{
-			group: decl.Group,
-		}
-	}
-
-	if pragma, ok := decl.Pragma.(*Pragma); ok {
-		p.checkUnused(pragma)
-	}
-
-	names := p.declNames(decl.NameList)
-	typ := p.typeExprOrNil(decl.Type)
-
-	var values []*Node
-	if decl.Values != nil {
-		values = p.exprList(decl.Values)
-		cs.typ, cs.values = typ, values
-	} else {
-		if typ != nil {
-			yyerror("const declaration cannot have type without expression")
-		}
-		typ, values = cs.typ, cs.values
-	}
-
-	nn := make([]*Node, 0, len(names))
-	for i, n := range names {
-		if i >= len(values) {
-			yyerror("missing value in const declaration")
-			break
-		}
-		v := values[i]
-		if decl.Values == nil {
-			v = treecopy(v, n.Pos)
-		}
-
-		n.Op = OLITERAL
-		declare(n, dclcontext)
-
-		n.Name.Param.Ntype = typ
-		n.Name.Defn = v
-		n.SetIota(cs.iota)
-
-		nn = append(nn, p.nod(decl, ODCLCONST, n, nil))
-	}
-
-	if len(values) > len(names) {
-		yyerror("extra expression in const declaration")
-	}
-
-	cs.iota++
-
-	return nn
-}
-
-func (p *noder) typeDecl(decl *syntax.TypeDecl) *Node {
-	n := p.declName(decl.Name)
-	n.Op = OTYPE
-	declare(n, dclcontext)
-
-	// decl.Type may be nil but in that case we got a syntax error during parsing
-	typ := p.typeExprOrNil(decl.Type)
-
-	param := n.Name.Param
-	param.Ntype = typ
-	param.SetAlias(decl.Alias)
-	if pragma, ok := decl.Pragma.(*Pragma); ok {
-		if !decl.Alias {
-			param.SetPragma(pragma.Flag & TypePragmas)
-			pragma.Flag &^= TypePragmas
-		}
-		p.checkUnused(pragma)
-	}
-
-	nod := p.nod(decl, ODCLTYPE, n, nil)
-	if param.Alias() && !langSupported(1, 9, localpkg) {
-		yyerrorl(nod.Pos, "type aliases only supported as of -lang=go1.9")
-	}
-	return nod
-}
-
-func (p *noder) declNames(names []*syntax.Name) []*Node {
-	nodes := make([]*Node, 0, len(names))
-	for _, name := range names {
-		nodes = append(nodes, p.declName(name))
-	}
-	return nodes
-}
-
-func (p *noder) declName(name *syntax.Name) *Node {
-	n := dclname(p.name(name))
-	n.Pos = p.pos(name)
-	return n
-}
-
-func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
-	name := p.name(fun.Name)
-	t := p.signature(fun.Recv, fun.Type)
-	f := p.nod(fun, ODCLFUNC, nil, nil)
-
-	if fun.Recv == nil {
-		if name.Name == "init" {
-			name = renameinit()
-			if t.List.Len() > 0 || t.Rlist.Len() > 0 {
-				yyerrorl(f.Pos, "func init must have no arguments and no return values")
-			}
-		}
-
-		if localpkg.Name == "main" && name.Name == "main" {
-			if t.List.Len() > 0 || t.Rlist.Len() > 0 {
-				yyerrorl(f.Pos, "func main must have no arguments and no return values")
-			}
-		}
-	} else {
-		f.Func.Shortname = name
-		name = nblank.Sym // filled in by typecheckfunc
-	}
-
-	f.Func.Nname = newfuncnamel(p.pos(fun.Name), name)
-	f.Func.Nname.Name.Defn = f
-	f.Func.Nname.Name.Param.Ntype = t
-
-	if pragma, ok := fun.Pragma.(*Pragma); ok {
-		f.Func.Pragma = pragma.Flag & FuncPragmas
-		if pragma.Flag&Systemstack != 0 && pragma.Flag&Nosplit != 0 {
-			yyerrorl(f.Pos, "go:nosplit and go:systemstack cannot be combined")
-		}
-		pragma.Flag &^= FuncPragmas
-		p.checkUnused(pragma)
-	}
-
-	if fun.Recv == nil {
-		declare(f.Func.Nname, PFUNC)
-	}
-
-	p.funcBody(f, fun.Body)
-
-	if fun.Body != nil {
-		if f.Func.Pragma&Noescape != 0 {
-			yyerrorl(f.Pos, "can only use //go:noescape with external func implementations")
-		}
-	} else {
-		if pure_go || strings.HasPrefix(f.funcname(), "init.") {
-			// Linknamed functions are allowed to have no body. Hopefully
-			// the linkname target has a body. See issue 23311.
-			isLinknamed := false
-			for _, n := range p.linknames {
-				if f.funcname() == n.local {
-					isLinknamed = true
-					break
-				}
-			}
-			if !isLinknamed {
-				yyerrorl(f.Pos, "missing function body")
-			}
-		}
-	}
-
-	return f
-}
-
-func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *Node {
-	n := p.nod(typ, OTFUNC, nil, nil)
-	if recv != nil {
-		n.Left = p.param(recv, false, false)
-	}
-	n.List.Set(p.params(typ.ParamList, true))
-	n.Rlist.Set(p.params(typ.ResultList, false))
-	return n
-}
-
-func (p *noder) params(params []*syntax.Field, dddOk bool) []*Node {
-	nodes := make([]*Node, 0, len(params))
-	for i, param := range params {
-		p.setlineno(param)
-		nodes = append(nodes, p.param(param, dddOk, i+1 == len(params)))
-	}
-	return nodes
-}
-
-func (p *noder) param(param *syntax.Field, dddOk, final bool) *Node {
-	var name *types.Sym
-	if param.Name != nil {
-		name = p.name(param.Name)
-	}
-
-	typ := p.typeExpr(param.Type)
-	n := p.nodSym(param, ODCLFIELD, typ, name)
-
-	// rewrite ...T parameter
-	if typ.Op == ODDD {
-		if !dddOk {
-			// We mark these as syntax errors to get automatic elimination
-			// of multiple such errors per line (see yyerrorl in subr.go).
-			yyerror("syntax error: cannot use ... in receiver or result parameter list")
-		} else if !final {
-			if param.Name == nil {
-				yyerror("syntax error: cannot use ... with non-final parameter")
-			} else {
-				p.yyerrorpos(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value)
-			}
-		}
-		typ.Op = OTARRAY
-		typ.Right = typ.Left
-		typ.Left = nil
-		n.SetIsDDD(true)
-		if n.Left != nil {
-			n.Left.SetIsDDD(true)
-		}
-	}
-
-	return n
-}
-
-func (p *noder) exprList(expr syntax.Expr) []*Node {
-	if list, ok := expr.(*syntax.ListExpr); ok {
-		return p.exprs(list.ElemList)
-	}
-	return []*Node{p.expr(expr)}
-}
-
-func (p *noder) exprs(exprs []syntax.Expr) []*Node {
-	nodes := make([]*Node, 0, len(exprs))
-	for _, expr := range exprs {
-		nodes = append(nodes, p.expr(expr))
-	}
-	return nodes
-}
-
-func (p *noder) expr(expr syntax.Expr) *Node {
-	p.setlineno(expr)
-	switch expr := expr.(type) {
-	case nil, *syntax.BadExpr:
-		return nil
-	case *syntax.Name:
-		return p.mkname(expr)
-	case *syntax.BasicLit:
-		n := nodlit(p.basicLit(expr))
-		n.SetDiag(expr.Bad) // avoid follow-on errors if there was a syntax error
-		return n
-	case *syntax.CompositeLit:
-		n := p.nod(expr, OCOMPLIT, nil, nil)
-		if expr.Type != nil {
-			n.Right = p.expr(expr.Type)
-		}
-		l := p.exprs(expr.ElemList)
-		for i, e := range l {
-			l[i] = p.wrapname(expr.ElemList[i], e)
-		}
-		n.List.Set(l)
-		lineno = p.makeXPos(expr.Rbrace)
-		return n
-	case *syntax.KeyValueExpr:
-		// use position of expr.Key rather than of expr (which has position of ':')
-		return p.nod(expr.Key, OKEY, p.expr(expr.Key), p.wrapname(expr.Value, p.expr(expr.Value)))
-	case *syntax.FuncLit:
-		return p.funcLit(expr)
-	case *syntax.ParenExpr:
-		return p.nod(expr, OPAREN, p.expr(expr.X), nil)
-	case *syntax.SelectorExpr:
-		// parser.new_dotname
-		obj := p.expr(expr.X)
-		if obj.Op == OPACK {
-			obj.Name.SetUsed(true)
-			return importName(obj.Name.Pkg.Lookup(expr.Sel.Value))
-		}
-		n := nodSym(OXDOT, obj, p.name(expr.Sel))
-		n.Pos = p.pos(expr) // lineno may have been changed by p.expr(expr.X)
-		return n
-	case *syntax.IndexExpr:
-		return p.nod(expr, OINDEX, p.expr(expr.X), p.expr(expr.Index))
-	case *syntax.SliceExpr:
-		op := OSLICE
-		if expr.Full {
-			op = OSLICE3
-		}
-		n := p.nod(expr, op, p.expr(expr.X), nil)
-		var index [3]*Node
-		for i, x := range &expr.Index {
-			if x != nil {
-				index[i] = p.expr(x)
-			}
-		}
-		n.SetSliceBounds(index[0], index[1], index[2])
-		return n
-	case *syntax.AssertExpr:
-		return p.nod(expr, ODOTTYPE, p.expr(expr.X), p.typeExpr(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 {
-			return p.nod(expr, p.unOp(expr.Op), x, nil)
-		}
-		return p.nod(expr, p.binOp(expr.Op), x, p.expr(expr.Y))
-	case *syntax.CallExpr:
-		n := p.nod(expr, OCALL, p.expr(expr.Fun), nil)
-		n.List.Set(p.exprs(expr.ArgList))
-		n.SetIsDDD(expr.HasDots)
-		return n
-
-	case *syntax.ArrayType:
-		var len *Node
-		if expr.Len != nil {
-			len = p.expr(expr.Len)
-		} else {
-			len = p.nod(expr, ODDD, nil, nil)
-		}
-		return p.nod(expr, OTARRAY, len, p.typeExpr(expr.Elem))
-	case *syntax.SliceType:
-		return p.nod(expr, OTARRAY, nil, p.typeExpr(expr.Elem))
-	case *syntax.DotsType:
-		return p.nod(expr, ODDD, p.typeExpr(expr.Elem), nil)
-	case *syntax.StructType:
-		return p.structType(expr)
-	case *syntax.InterfaceType:
-		return p.interfaceType(expr)
-	case *syntax.FuncType:
-		return p.signature(nil, expr)
-	case *syntax.MapType:
-		return p.nod(expr, OTMAP, p.typeExpr(expr.Key), p.typeExpr(expr.Value))
-	case *syntax.ChanType:
-		n := p.nod(expr, OTCHAN, p.typeExpr(expr.Elem), nil)
-		n.SetTChanDir(p.chanDir(expr.Dir))
-		return n
-
-	case *syntax.TypeSwitchGuard:
-		n := p.nod(expr, OTYPESW, nil, p.expr(expr.X))
-		if expr.Lhs != nil {
-			n.Left = p.declName(expr.Lhs)
-			if n.Left.isBlank() {
-				yyerror("invalid variable name %v in type switch", n.Left)
-			}
-		}
-		return n
-	}
-	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.StringVal())
-	}
-
-	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.StringVal())
-				continue
-			}
-
-			nstr = r
-			chunks = append(chunks, nstr.StringVal())
-		} 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)
-}
-
-func (p *noder) typeExprOrNil(typ syntax.Expr) *Node {
-	if typ != nil {
-		return p.expr(typ)
-	}
-	return nil
-}
-
-func (p *noder) chanDir(dir syntax.ChanDir) types.ChanDir {
-	switch dir {
-	case 0:
-		return types.Cboth
-	case syntax.SendOnly:
-		return types.Csend
-	case syntax.RecvOnly:
-		return types.Crecv
-	}
-	panic("unhandled ChanDir")
-}
-
-func (p *noder) structType(expr *syntax.StructType) *Node {
-	l := make([]*Node, 0, len(expr.FieldList))
-	for i, field := range expr.FieldList {
-		p.setlineno(field)
-		var n *Node
-		if field.Name == nil {
-			n = p.embedded(field.Type)
-		} else {
-			n = p.nodSym(field, ODCLFIELD, p.typeExpr(field.Type), p.name(field.Name))
-		}
-		if i < len(expr.TagList) && expr.TagList[i] != nil {
-			n.SetVal(p.basicLit(expr.TagList[i]))
-		}
-		l = append(l, n)
-	}
-
-	p.setlineno(expr)
-	n := p.nod(expr, OTSTRUCT, nil, nil)
-	n.List.Set(l)
-	return n
-}
-
-func (p *noder) interfaceType(expr *syntax.InterfaceType) *Node {
-	l := make([]*Node, 0, len(expr.MethodList))
-	for _, method := range expr.MethodList {
-		p.setlineno(method)
-		var n *Node
-		if method.Name == nil {
-			n = p.nodSym(method, ODCLFIELD, importName(p.packname(method.Type)), nil)
-		} else {
-			mname := p.name(method.Name)
-			sig := p.typeExpr(method.Type)
-			sig.Left = fakeRecv()
-			n = p.nodSym(method, ODCLFIELD, sig, mname)
-			ifacedcl(n)
-		}
-		l = append(l, n)
-	}
-
-	n := p.nod(expr, OTINTER, nil, nil)
-	n.List.Set(l)
-	return n
-}
-
-func (p *noder) packname(expr syntax.Expr) *types.Sym {
-	switch expr := expr.(type) {
-	case *syntax.Name:
-		name := p.name(expr)
-		if n := oldname(name); n.Name != nil && n.Name.Pack != nil {
-			n.Name.Pack.Name.SetUsed(true)
-		}
-		return name
-	case *syntax.SelectorExpr:
-		name := p.name(expr.X.(*syntax.Name))
-		def := asNode(name.Def)
-		if def == nil {
-			yyerror("undefined: %v", name)
-			return name
-		}
-		var pkg *types.Pkg
-		if def.Op != OPACK {
-			yyerror("%v is not a package", name)
-			pkg = localpkg
-		} else {
-			def.Name.SetUsed(true)
-			pkg = def.Name.Pkg
-		}
-		return pkg.Lookup(expr.Sel.Value)
-	}
-	panic(fmt.Sprintf("unexpected packname: %#v", expr))
-}
-
-func (p *noder) embedded(typ syntax.Expr) *Node {
-	op, isStar := typ.(*syntax.Operation)
-	if isStar {
-		if op.Op != syntax.Mul || op.Y != nil {
-			panic("unexpected Operation")
-		}
-		typ = op.X
-	}
-
-	sym := p.packname(typ)
-	n := p.nodSym(typ, ODCLFIELD, importName(sym), lookup(sym.Name))
-	n.SetEmbedded(true)
-
-	if isStar {
-		n.Left = p.nod(op, ODEREF, n.Left, nil)
-	}
-	return n
-}
-
-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 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()...)
-		} else {
-			nodes = append(nodes, s)
-		}
-	}
-	return nodes
-}
-
-func (p *noder) stmt(stmt syntax.Stmt) *Node {
-	return p.stmtFall(stmt, false)
-}
-
-func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
-	p.setlineno(stmt)
-	switch stmt := stmt.(type) {
-	case *syntax.EmptyStmt:
-		return nil
-	case *syntax.LabeledStmt:
-		return p.labeledStmt(stmt, fallOK)
-	case *syntax.BlockStmt:
-		l := p.blockStmt(stmt)
-		if len(l) == 0 {
-			// TODO(mdempsky): Line number?
-			return nod(OEMPTY, nil, nil)
-		}
-		return liststmt(l)
-	case *syntax.ExprStmt:
-		return p.wrapname(stmt, p.expr(stmt.X))
-	case *syntax.SendStmt:
-		return p.nod(stmt, OSEND, p.expr(stmt.Chan), p.expr(stmt.Value))
-	case *syntax.DeclStmt:
-		return liststmt(p.decls(stmt.DeclList))
-	case *syntax.AssignStmt:
-		if stmt.Op != 0 && stmt.Op != syntax.Def {
-			n := p.nod(stmt, OASOP, p.expr(stmt.Lhs), p.expr(stmt.Rhs))
-			n.SetImplicit(stmt.Rhs == syntax.ImplicitOne)
-			n.SetSubOp(p.binOp(stmt.Op))
-			return n
-		}
-
-		n := p.nod(stmt, OAS, nil, nil) // assume 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
-			n.Left = lhs[0]
-			n.Right = rhs[0]
-		} else {
-			n.Op = OAS2
-			n.List.Set(lhs)
-			n.Rlist.Set(rhs)
-		}
-		return n
-
-	case *syntax.BranchStmt:
-		var op Op
-		switch stmt.Tok {
-		case syntax.Break:
-			op = OBREAK
-		case syntax.Continue:
-			op = OCONTINUE
-		case syntax.Fallthrough:
-			if !fallOK {
-				yyerror("fallthrough statement out of place")
-			}
-			op = OFALL
-		case syntax.Goto:
-			op = OGOTO
-		default:
-			panic("unhandled BranchStmt")
-		}
-		n := p.nod(stmt, op, nil, nil)
-		if stmt.Label != nil {
-			n.Sym = p.name(stmt.Label)
-		}
-		return n
-	case *syntax.CallStmt:
-		var op Op
-		switch stmt.Tok {
-		case syntax.Defer:
-			op = ODEFER
-		case syntax.Go:
-			op = OGO
-		default:
-			panic("unhandled CallStmt")
-		}
-		return p.nod(stmt, op, p.expr(stmt.Call), nil)
-	case *syntax.ReturnStmt:
-		var results []*Node
-		if stmt.Results != nil {
-			results = p.exprList(stmt.Results)
-		}
-		n := p.nod(stmt, ORETURN, nil, nil)
-		n.List.Set(results)
-		if n.List.Len() == 0 && Curfn != nil {
-			for _, ln := range Curfn.Func.Dcl {
-				if ln.Class() == PPARAM {
-					continue
-				}
-				if ln.Class() != PPARAMOUT {
-					break
-				}
-				if asNode(ln.Sym.Def) != ln {
-					yyerror("%s is shadowed during return", ln.Sym.Name)
-				}
-			}
-		}
-		return n
-	case *syntax.IfStmt:
-		return p.ifStmt(stmt)
-	case *syntax.ForStmt:
-		return p.forStmt(stmt)
-	case *syntax.SwitchStmt:
-		return p.switchStmt(stmt)
-	case *syntax.SelectStmt:
-		return p.selectStmt(stmt)
-	}
-	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.setlineno(expr)
-		res[i] = nblank
-
-		name, ok := expr.(*syntax.Name)
-		if !ok {
-			p.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] {
-			p.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)
-	p.closeScope(stmt.Rbrace)
-	return nodes
-}
-
-func (p *noder) ifStmt(stmt *syntax.IfStmt) *Node {
-	p.openScope(stmt.Pos())
-	n := p.nod(stmt, OIF, nil, nil)
-	if stmt.Init != nil {
-		n.Ninit.Set1(p.stmt(stmt.Init))
-	}
-	if stmt.Cond != nil {
-		n.Left = p.expr(stmt.Cond)
-	}
-	n.Nbody.Set(p.blockStmt(stmt.Then))
-	if stmt.Else != nil {
-		e := p.stmt(stmt.Else)
-		if e.Op == OBLOCK && e.Ninit.Len() == 0 {
-			n.Rlist.Set(e.List.Slice())
-		} else {
-			n.Rlist.Set1(e)
-		}
-	}
-	p.closeAnotherScope()
-	return n
-}
-
-func (p *noder) forStmt(stmt *syntax.ForStmt) *Node {
-	p.openScope(stmt.Pos())
-	var n *Node
-	if r, ok := stmt.Init.(*syntax.RangeClause); ok {
-		if stmt.Cond != nil || stmt.Post != nil {
-			panic("unexpected RangeClause")
-		}
-
-		n = p.nod(r, ORANGE, nil, p.expr(r.X))
-		if r.Lhs != nil {
-			n.List.Set(p.assignList(r.Lhs, n, r.Def))
-		}
-	} else {
-		n = p.nod(stmt, OFOR, nil, nil)
-		if stmt.Init != nil {
-			n.Ninit.Set1(p.stmt(stmt.Init))
-		}
-		if stmt.Cond != nil {
-			n.Left = p.expr(stmt.Cond)
-		}
-		if stmt.Post != nil {
-			n.Right = p.stmt(stmt.Post)
-		}
-	}
-	n.Nbody.Set(p.blockStmt(stmt.Body))
-	p.closeAnotherScope()
-	return n
-}
-
-func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *Node {
-	p.openScope(stmt.Pos())
-	n := p.nod(stmt, OSWITCH, nil, nil)
-	if stmt.Init != nil {
-		n.Ninit.Set1(p.stmt(stmt.Init))
-	}
-	if stmt.Tag != nil {
-		n.Left = p.expr(stmt.Tag)
-	}
-
-	tswitch := n.Left
-	if tswitch != nil && tswitch.Op != OTYPESW {
-		tswitch = nil
-	}
-	n.List.Set(p.caseClauses(stmt.Body, tswitch, stmt.Rbrace))
-
-	p.closeScope(stmt.Rbrace)
-	return n
-}
-
-func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node, rbrace syntax.Pos) []*Node {
-	nodes := make([]*Node, 0, len(clauses))
-	for i, clause := range clauses {
-		p.setlineno(clause)
-		if i > 0 {
-			p.closeScope(clause.Pos())
-		}
-		p.openScope(clause.Pos())
-
-		n := p.nod(clause, OCASE, nil, nil)
-		if clause.Cases != nil {
-			n.List.Set(p.exprList(clause.Cases))
-		}
-		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
-		}
-
-		// 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 {
-		p.closeScope(rbrace)
-	}
-	return nodes
-}
-
-func (p *noder) selectStmt(stmt *syntax.SelectStmt) *Node {
-	n := p.nod(stmt, OSELECT, nil, nil)
-	n.List.Set(p.commClauses(stmt.Body, stmt.Rbrace))
-	return n
-}
-
-func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*Node {
-	nodes := make([]*Node, 0, len(clauses))
-	for i, clause := range clauses {
-		p.setlineno(clause)
-		if i > 0 {
-			p.closeScope(clause.Pos())
-		}
-		p.openScope(clause.Pos())
-
-		n := p.nod(clause, OCASE, nil, nil)
-		if clause.Comm != nil {
-			n.List.Set1(p.stmt(clause.Comm))
-		}
-		n.Nbody.Set(p.stmts(clause.Body))
-		nodes = append(nodes, n)
-	}
-	if len(clauses) > 0 {
-		p.closeScope(rbrace)
-	}
-	return nodes
-}
-
-func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) *Node {
-	lhs := p.nodSym(label, OLABEL, nil, p.name(label.Label))
-
-	var ls *Node
-	if label.Stmt != nil { // TODO(mdempsky): Should always be present.
-		ls = p.stmtFall(label.Stmt, fallOK)
-	}
-
-	lhs.Name.Defn = ls
-	l := []*Node{lhs}
-	if ls != nil {
-		if ls.Op == OBLOCK && ls.Ninit.Len() == 0 {
-			l = append(l, ls.List.Slice()...)
-		} else {
-			l = append(l, ls)
-		}
-	}
-	return liststmt(l)
-}
-
-var unOps = [...]Op{
-	syntax.Recv: ORECV,
-	syntax.Mul:  ODEREF,
-	syntax.And:  OADDR,
-
-	syntax.Not: ONOT,
-	syntax.Xor: OBITNOT,
-	syntax.Add: OPLUS,
-	syntax.Sub: ONEG,
-}
-
-func (p *noder) unOp(op syntax.Operator) Op {
-	if uint64(op) >= uint64(len(unOps)) || unOps[op] == 0 {
-		panic("invalid Operator")
-	}
-	return unOps[op]
-}
-
-var binOps = [...]Op{
-	syntax.OrOr:   OOROR,
-	syntax.AndAnd: OANDAND,
-
-	syntax.Eql: OEQ,
-	syntax.Neq: ONE,
-	syntax.Lss: OLT,
-	syntax.Leq: OLE,
-	syntax.Gtr: OGT,
-	syntax.Geq: OGE,
-
-	syntax.Add: OADD,
-	syntax.Sub: OSUB,
-	syntax.Or:  OOR,
-	syntax.Xor: OXOR,
-
-	syntax.Mul:    OMUL,
-	syntax.Div:    ODIV,
-	syntax.Rem:    OMOD,
-	syntax.And:    OAND,
-	syntax.AndNot: OANDNOT,
-	syntax.Shl:    OLSH,
-	syntax.Shr:    ORSH,
-}
-
-func (p *noder) binOp(op syntax.Operator) Op {
-	if uint64(op) >= uint64(len(binOps)) || binOps[op] == 0 {
-		panic("invalid Operator")
-	}
-	return binOps[op]
-}
-
-// checkLangCompat reports an error if the representation of a numeric
-// literal is not compatible with the current language version.
-func checkLangCompat(lit *syntax.BasicLit) {
-	s := lit.Value
-	if len(s) <= 2 || langSupported(1, 13, localpkg) {
-		return
-	}
-	// len(s) > 2
-	if strings.Contains(s, "_") {
-		yyerrorv("go1.13", "underscores in numeric literals")
-		return
-	}
-	if s[0] != '0' {
-		return
-	}
-	base := s[1]
-	if base == 'b' || base == 'B' {
-		yyerrorv("go1.13", "binary literals")
-		return
-	}
-	if base == 'o' || base == 'O' {
-		yyerrorv("go1.13", "0o/0O-style octal literals")
-		return
-	}
-	if lit.Kind != syntax.IntLit && (base == 'x' || base == 'X') {
-		yyerrorv("go1.13", "hexadecimal floating-point literals")
-	}
-}
-
-func (p *noder) basicLit(lit *syntax.BasicLit) Val {
-	// We don't use the errors of the conversion routines to determine
-	// if a literal string is valid because the conversion routines may
-	// accept a wider syntax than the language permits. Rely on lit.Bad
-	// instead.
-	switch s := lit.Value; lit.Kind {
-	case syntax.IntLit:
-		checkLangCompat(lit)
-		x := new(Mpint)
-		if !lit.Bad {
-			x.SetString(s)
-		}
-		return Val{U: x}
-
-	case syntax.FloatLit:
-		checkLangCompat(lit)
-		x := newMpflt()
-		if !lit.Bad {
-			x.SetString(s)
-		}
-		return Val{U: x}
-
-	case syntax.ImagLit:
-		checkLangCompat(lit)
-		x := newMpcmplx()
-		if !lit.Bad {
-			x.Imag.SetString(strings.TrimSuffix(s, "i"))
-		}
-		return Val{U: x}
-
-	case syntax.RuneLit:
-		x := new(Mpint)
-		x.Rune = true
-		if !lit.Bad {
-			u, _ := strconv.Unquote(s)
-			var r rune
-			if len(u) == 1 {
-				r = rune(u[0])
-			} else {
-				r, _ = utf8.DecodeRuneInString(u)
-			}
-			x.SetInt64(int64(r))
-		}
-		return Val{U: x}
-
-	case syntax.StringLit:
-		var x string
-		if !lit.Bad {
-			if len(s) > 0 && s[0] == '`' {
-				// strip carriage returns from raw string
-				s = strings.Replace(s, "\r", "", -1)
-			}
-			x, _ = strconv.Unquote(s)
-		}
-		return Val{U: x}
-
-	default:
-		panic("unhandled BasicLit kind")
-	}
-}
-
-func (p *noder) name(name *syntax.Name) *types.Sym {
-	return lookup(name.Value)
-}
-
-func (p *noder) mkname(name *syntax.Name) *Node {
-	// TODO(mdempsky): Set line number?
-	return mkname(p.name(name))
-}
-
-func (p *noder) wrapname(n syntax.Node, x *Node) *Node {
-	// These nodes do not carry line numbers.
-	// Introduce a wrapper node to give them the correct line.
-	switch x.Op {
-	case OTYPE, OLITERAL:
-		if x.Sym == nil {
-			break
-		}
-		fallthrough
-	case ONAME, ONONAME, OPACK:
-		x = p.nod(n, OPAREN, x, nil)
-		x.SetImplicit(true)
-	}
-	return x
-}
-
-func (p *noder) nod(orig syntax.Node, op Op, left, right *Node) *Node {
-	return nodl(p.pos(orig), op, left, right)
-}
-
-func (p *noder) nodSym(orig syntax.Node, op Op, left *Node, sym *types.Sym) *Node {
-	n := nodSym(op, left, sym)
-	n.Pos = p.pos(orig)
-	return n
-}
-
-func (p *noder) pos(n syntax.Node) src.XPos {
-	// TODO(gri): orig.Pos() should always be known - fix package syntax
-	xpos := lineno
-	if pos := n.Pos(); pos.IsKnown() {
-		xpos = p.makeXPos(pos)
-	}
-	return xpos
-}
-
-func (p *noder) setlineno(n syntax.Node) {
-	if n != nil {
-		lineno = p.pos(n)
-	}
-}
-
-// error is called concurrently if files are parsed concurrently.
-func (p *noder) error(err error) {
-	p.err <- err.(syntax.Error)
-}
-
-// pragmas that are allowed in the std lib, but don't have
-// a syntax.Pragma value (see lex.go) associated with them.
-var allowedStdPragmas = map[string]bool{
-	"go:cgo_export_static":  true,
-	"go:cgo_export_dynamic": true,
-	"go:cgo_import_static":  true,
-	"go:cgo_import_dynamic": true,
-	"go:cgo_ldflag":         true,
-	"go:cgo_dynamic_linker": true,
-	"go:embed":              true,
-	"go:generate":           true,
-}
-
-// *Pragma is the value stored in a syntax.Pragma during parsing.
-type Pragma struct {
-	Flag   PragmaFlag  // collected bits
-	Pos    []PragmaPos // position of each individual flag
-	Embeds []PragmaEmbed
-}
-
-type PragmaPos struct {
-	Flag PragmaFlag
-	Pos  syntax.Pos
-}
-
-type PragmaEmbed struct {
-	Pos      syntax.Pos
-	Patterns []string
-}
-
-func (p *noder) checkUnused(pragma *Pragma) {
-	for _, pos := range pragma.Pos {
-		if pos.Flag&pragma.Flag != 0 {
-			p.yyerrorpos(pos.Pos, "misplaced compiler directive")
-		}
-	}
-	if len(pragma.Embeds) > 0 {
-		for _, e := range pragma.Embeds {
-			p.yyerrorpos(e.Pos, "misplaced go:embed directive")
-		}
-	}
-}
-
-func (p *noder) checkUnusedDuringParse(pragma *Pragma) {
-	for _, pos := range pragma.Pos {
-		if pos.Flag&pragma.Flag != 0 {
-			p.error(syntax.Error{Pos: pos.Pos, Msg: "misplaced compiler directive"})
-		}
-	}
-	if len(pragma.Embeds) > 0 {
-		for _, e := range pragma.Embeds {
-			p.error(syntax.Error{Pos: e.Pos, Msg: "misplaced go:embed directive"})
-		}
-	}
-}
-
-// pragma is called concurrently if files are parsed concurrently.
-func (p *noder) pragma(pos syntax.Pos, blankLine bool, text string, old syntax.Pragma) syntax.Pragma {
-	pragma, _ := old.(*Pragma)
-	if pragma == nil {
-		pragma = new(Pragma)
-	}
-
-	if text == "" {
-		// unused pragma; only called with old != nil.
-		p.checkUnusedDuringParse(pragma)
-		return nil
-	}
-
-	if strings.HasPrefix(text, "line ") {
-		// line directives are handled by syntax package
-		panic("unreachable")
-	}
-
-	if !blankLine {
-		// directive must be on line by itself
-		p.error(syntax.Error{Pos: pos, Msg: "misplaced compiler directive"})
-		return pragma
-	}
-
-	switch {
-	case strings.HasPrefix(text, "go:linkname "):
-		f := strings.Fields(text)
-		if !(2 <= len(f) && len(f) <= 3) {
-			p.error(syntax.Error{Pos: pos, Msg: "usage: //go:linkname localname [linkname]"})
-			break
-		}
-		// The second argument is optional. If omitted, we use
-		// the default object symbol name for this and
-		// linkname only serves to mark this symbol as
-		// something that may be referenced via the object
-		// symbol name from another package.
-		var target string
-		if len(f) == 3 {
-			target = f[2]
-		}
-		p.linknames = append(p.linknames, linkname{pos, f[1], target})
-
-	case text == "go:embed", strings.HasPrefix(text, "go:embed "):
-		args, err := parseGoEmbed(text[len("go:embed"):])
-		if err != nil {
-			p.error(syntax.Error{Pos: pos, Msg: err.Error()})
-		}
-		if len(args) == 0 {
-			p.error(syntax.Error{Pos: pos, Msg: "usage: //go:embed pattern..."})
-			break
-		}
-		pragma.Embeds = append(pragma.Embeds, PragmaEmbed{pos, args})
-
-	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.pragcgo(pos, text)
-			pragma.Flag |= pragmaFlag("go:cgo_import_dynamic")
-			break
-		}
-		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.pragcgo(pos, text)
-		fallthrough // because of //go:cgo_unsafe_args
-	default:
-		verb := text
-		if i := strings.Index(text, " "); i >= 0 {
-			verb = verb[:i]
-		}
-		flag := pragmaFlag(verb)
-		const runtimePragmas = Systemstack | Nowritebarrier | Nowritebarrierrec | Yeswritebarrierrec
-		if !compiling_runtime && flag&runtimePragmas != 0 {
-			p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in runtime", verb)})
-		}
-		if flag == 0 && !allowedStdPragmas[verb] && compiling_std {
-			p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s is not allowed in the standard library", verb)})
-		}
-		pragma.Flag |= flag
-		pragma.Pos = append(pragma.Pos, PragmaPos{flag, pos})
-	}
-
-	return pragma
-}
-
-// 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 syntax.Pos) bool {
-	return strings.HasPrefix(filepath.Base(filepath.Clean(fileh(pos.Base().Filename()))), "_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 {
-		n.Name.Pack.Name.SetUsed(true)
-	}
-	return n
-}
-
-// parseGoEmbed parses the text following "//go:embed" to extract the glob patterns.
-// It accepts unquoted space-separated patterns as well as double-quoted and back-quoted Go strings.
-// go/build/read.go also processes these strings and contains similar logic.
-func parseGoEmbed(args string) ([]string, error) {
-	var list []string
-	for args = strings.TrimSpace(args); args != ""; args = strings.TrimSpace(args) {
-		var path string
-	Switch:
-		switch args[0] {
-		default:
-			i := len(args)
-			for j, c := range args {
-				if unicode.IsSpace(c) {
-					i = j
-					break
-				}
-			}
-			path = args[:i]
-			args = args[i:]
-
-		case '`':
-			i := strings.Index(args[1:], "`")
-			if i < 0 {
-				return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
-			}
-			path = args[1 : 1+i]
-			args = args[1+i+1:]
-
-		case '"':
-			i := 1
-			for ; i < len(args); i++ {
-				if args[i] == '\\' {
-					i++
-					continue
-				}
-				if args[i] == '"' {
-					q, err := strconv.Unquote(args[:i+1])
-					if err != nil {
-						return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args[:i+1])
-					}
-					path = q
-					args = args[i+1:]
-					break Switch
-				}
-			}
-			if i >= len(args) {
-				return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
-			}
-		}
-
-		if args != "" {
-			r, _ := utf8.DecodeRuneInString(args)
-			if !unicode.IsSpace(r) {
-				return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
-			}
-		}
-		list = append(list, path)
-	}
-	return list, nil
-}
diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go
index 32aa7c5..474d718 100644
--- a/src/cmd/compile/internal/gc/obj.go
+++ b/src/cmd/compile/internal/gc/obj.go
@@ -5,28 +5,21 @@
 package gc
 
 import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/staticdata"
+	"cmd/compile/internal/typecheck"
 	"cmd/compile/internal/types"
+	"cmd/internal/archive"
 	"cmd/internal/bio"
 	"cmd/internal/obj"
 	"cmd/internal/objabi"
-	"cmd/internal/src"
-	"crypto/sha256"
 	"encoding/json"
 	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"sort"
-	"strconv"
 )
 
-// architecture-independent object file output
-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))
-}
-
 // These modes say which kind of object file to generate.
 // The default use of the toolchain is to set both bits,
 // generating a combined compiler+linker object, one that
@@ -46,20 +39,20 @@
 )
 
 func dumpobj() {
-	if linkobj == "" {
-		dumpobj1(outfile, modeCompilerObj|modeLinkerObj)
+	if base.Flag.LinkObj == "" {
+		dumpobj1(base.Flag.LowerO, modeCompilerObj|modeLinkerObj)
 		return
 	}
-	dumpobj1(outfile, modeCompilerObj)
-	dumpobj1(linkobj, modeLinkerObj)
+	dumpobj1(base.Flag.LowerO, modeCompilerObj)
+	dumpobj1(base.Flag.LinkObj, modeLinkerObj)
 }
 
 func dumpobj1(outfile string, mode int) {
 	bout, err := bio.Create(outfile)
 	if err != nil {
-		flusherrors()
+		base.FlushErrors()
 		fmt.Printf("can't create %s: %v\n", outfile, err)
-		errorexit()
+		base.ErrorExit()
 	}
 	defer bout.Close()
 	bout.WriteString("!<arch>\n")
@@ -77,18 +70,18 @@
 }
 
 func printObjHeader(bout *bio.Writer) {
-	fmt.Fprintf(bout, "go object %s %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version, objabi.Expstring())
-	if buildid != "" {
-		fmt.Fprintf(bout, "build id %q\n", buildid)
+	bout.WriteString(objabi.HeaderString())
+	if base.Flag.BuildID != "" {
+		fmt.Fprintf(bout, "build id %q\n", base.Flag.BuildID)
 	}
-	if localpkg.Name == "main" {
+	if types.LocalPkg.Name == "main" {
 		fmt.Fprintf(bout, "main\n")
 	}
 	fmt.Fprintf(bout, "\n") // header ends with blank line
 }
 
 func startArchiveEntry(bout *bio.Writer) int64 {
-	var arhdr [ArhdrSize]byte
+	var arhdr [archive.HeaderSize]byte
 	bout.Write(arhdr[:])
 	return bout.Offset()
 }
@@ -99,10 +92,10 @@
 	if size&1 != 0 {
 		bout.WriteByte(0)
 	}
-	bout.MustSeek(start-ArhdrSize, 0)
+	bout.MustSeek(start-archive.HeaderSize, 0)
 
-	var arhdr [ArhdrSize]byte
-	formathdr(arhdr[:], name, size)
+	var arhdr [archive.HeaderSize]byte
+	archive.FormatHeader(arhdr[:], name, size)
 	bout.Write(arhdr[:])
 	bout.Flush()
 	bout.MustSeek(start+size+(size&1), 0)
@@ -114,22 +107,21 @@
 }
 
 func dumpdata() {
-	externs := len(externdcl)
-	xtops := len(xtop)
+	numExterns := len(typecheck.Target.Externs)
+	numDecls := len(typecheck.Target.Decls)
 
-	dumpglobls()
-	addptabs()
-	exportlistLen := len(exportlist)
-	addsignats(externdcl)
-	dumpsignats()
-	dumptabs()
-	ptabsLen := len(ptabs)
-	itabsLen := len(itabs)
-	dumpimportstrings()
-	dumpbasictypes()
+	dumpglobls(typecheck.Target.Externs)
+	reflectdata.CollectPTabs()
+	numExports := len(typecheck.Target.Exports)
+	addsignats(typecheck.Target.Externs)
+	reflectdata.WriteRuntimeTypes()
+	reflectdata.WriteTabs()
+	numPTabs, numITabs := reflectdata.CountTabs()
+	reflectdata.WriteImportStrings()
+	reflectdata.WriteBasicTypes()
 	dumpembeds()
 
-	// Calls to dumpsignats can generate functions,
+	// Calls to WriteRuntimeTypes can generate functions,
 	// like method wrappers and hash and equality routines.
 	// Compile any generated functions, process any new resulting types, repeat.
 	// This can't loop forever, because there is no way to generate an infinite
@@ -137,169 +129,110 @@
 	// In the typical case, we loop 0 or 1 times.
 	// It was not until issue 24761 that we found any code that required a loop at all.
 	for {
-		for i := xtops; i < len(xtop); i++ {
-			n := xtop[i]
-			if n.Op == ODCLFUNC {
-				funccompile(n)
+		for i := numDecls; i < len(typecheck.Target.Decls); i++ {
+			if n, ok := typecheck.Target.Decls[i].(*ir.Func); ok {
+				enqueueFunc(n)
 			}
 		}
-		xtops = len(xtop)
+		numDecls = len(typecheck.Target.Decls)
 		compileFunctions()
-		dumpsignats()
-		if xtops == len(xtop) {
+		reflectdata.WriteRuntimeTypes()
+		if numDecls == len(typecheck.Target.Decls) {
 			break
 		}
 	}
 
 	// Dump extra globals.
-	tmp := externdcl
+	dumpglobls(typecheck.Target.Externs[numExterns:])
 
-	if externdcl != nil {
-		externdcl = externdcl[externs:]
-	}
-	dumpglobls()
-	externdcl = tmp
-
-	if zerosize > 0 {
-		zero := mappkg.Lookup("zero")
-		ggloblsym(zero.Linksym(), int32(zerosize), obj.DUPOK|obj.RODATA)
+	if reflectdata.ZeroSize > 0 {
+		zero := base.PkgLinksym("go.map", "zero", obj.ABI0)
+		objw.Global(zero, int32(reflectdata.ZeroSize), obj.DUPOK|obj.RODATA)
+		zero.Set(obj.AttrStatic, true)
 	}
 
+	staticdata.WriteFuncSyms()
 	addGCLocals()
 
-	if exportlistLen != len(exportlist) {
-		Fatalf("exportlist changed after compile functions loop")
+	if numExports != len(typecheck.Target.Exports) {
+		base.Fatalf("Target.Exports changed after compile functions loop")
 	}
-	if ptabsLen != len(ptabs) {
-		Fatalf("ptabs changed after compile functions loop")
+	newNumPTabs, newNumITabs := reflectdata.CountTabs()
+	if newNumPTabs != numPTabs {
+		base.Fatalf("ptabs changed after compile functions loop")
 	}
-	if itabsLen != len(itabs) {
-		Fatalf("itabs changed after compile functions loop")
+	if newNumITabs != numITabs {
+		base.Fatalf("itabs changed after compile functions loop")
 	}
 }
 
 func dumpLinkerObj(bout *bio.Writer) {
 	printObjHeader(bout)
 
-	if len(pragcgobuf) != 0 {
+	if len(typecheck.Target.CgoPragmas) != 0 {
 		// write empty export section; must be before cgo section
 		fmt.Fprintf(bout, "\n$$\n\n$$\n\n")
 		fmt.Fprintf(bout, "\n$$  // cgo\n")
-		if err := json.NewEncoder(bout).Encode(pragcgobuf); err != nil {
-			Fatalf("serializing pragcgobuf: %v", err)
+		if err := json.NewEncoder(bout).Encode(typecheck.Target.CgoPragmas); err != nil {
+			base.Fatalf("serializing pragcgobuf: %v", err)
 		}
 		fmt.Fprintf(bout, "\n$$\n\n")
 	}
 
 	fmt.Fprintf(bout, "\n!\n")
 
-	obj.WriteObjFile(Ctxt, bout)
+	obj.WriteObjFile(base.Ctxt, bout)
 }
 
-func addptabs() {
-	if !Ctxt.Flag_dynlink || localpkg.Name != "main" {
+func dumpGlobal(n *ir.Name) {
+	if n.Type() == nil {
+		base.Fatalf("external %v nil type\n", n)
+	}
+	if n.Class == ir.PFUNC {
 		return
 	}
-	for _, exportn := range exportlist {
-		s := exportn.Sym
-		n := asNode(s.Def)
-		if n == nil {
-			continue
-		}
-		if n.Op != ONAME {
-			continue
-		}
-		if !types.IsExported(s.Name) {
-			continue
-		}
-		if s.Pkg.Name != "main" {
-			continue
-		}
-		if n.Type.Etype == TFUNC && n.Class() == PFUNC {
-			// function
-			ptabs = append(ptabs, ptabEntry{s: s, t: asNode(s.Def).Type})
-		} else {
-			// variable
-			ptabs = append(ptabs, ptabEntry{s: s, t: types.NewPtr(asNode(s.Def).Type)})
-		}
-	}
-}
-
-func dumpGlobal(n *Node) {
-	if n.Type == nil {
-		Fatalf("external %v nil type\n", n)
-	}
-	if n.Class() == PFUNC {
+	if n.Sym().Pkg != types.LocalPkg {
 		return
 	}
-	if n.Sym.Pkg != localpkg {
-		return
-	}
-	dowidth(n.Type)
+	types.CalcSize(n.Type())
 	ggloblnod(n)
+	base.Ctxt.DwarfGlobal(base.Ctxt.Pkgpath, types.TypeSymName(n.Type()), n.Linksym())
 }
 
-func dumpGlobalConst(n *Node) {
+func dumpGlobalConst(n ir.Node) {
 	// only export typed constants
-	t := n.Type
+	t := n.Type()
 	if t == nil {
 		return
 	}
-	if n.Sym.Pkg != localpkg {
+	if n.Sym().Pkg != types.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:
+	if !t.IsInteger() {
 		return
 	}
-	Ctxt.DwarfIntConst(myimportpath, n.Sym.Name, typesymname(t), n.Int64Val())
+	v := n.Val()
+	if t.IsUntyped() {
+		// Export untyped integers as int (if they fit).
+		t = types.Types[types.TINT]
+		if ir.ConstOverflow(v, t) {
+			return
+		}
+	}
+	base.Ctxt.DwarfIntConst(base.Ctxt.Pkgpath, n.Sym().Name, types.TypeSymName(t), ir.IntVal(t, v))
 }
 
-func dumpglobls() {
+func dumpglobls(externs []ir.Node) {
 	// add globals
-	for _, n := range externdcl {
-		switch n.Op {
-		case ONAME:
-			dumpGlobal(n)
-		case OLITERAL:
+	for _, n := range externs {
+		switch n.Op() {
+		case ir.ONAME:
+			dumpGlobal(n.(*ir.Name))
+		case ir.OLITERAL:
 			dumpGlobalConst(n)
 		}
 	}
-
-	sort.Slice(funcsyms, func(i, j int) bool {
-		return funcsyms[i].LinksymName() < funcsyms[j].LinksymName()
-	})
-	for _, s := range funcsyms {
-		sf := s.Pkg.Lookup(funcsymname(s)).Linksym()
-		dsymptr(sf, 0, s.Linksym(), 0)
-		ggloblsym(sf, int32(Widthptr), obj.DUPOK|obj.RODATA)
-	}
-
-	// Do not reprocess funcsyms on next dumpglobls call.
-	funcsyms = nil
 }
 
 // addGCLocals adds gcargs, gclocals, gcregs, and stack object symbols to Ctxt.Data.
@@ -307,332 +240,65 @@
 // This is done during the sequential phase after compilation, since
 // global symbols can't be declared during parallel compilation.
 func addGCLocals() {
-	for _, s := range Ctxt.Text {
+	for _, s := range base.Ctxt.Text {
 		fn := s.Func()
 		if fn == nil {
 			continue
 		}
 		for _, gcsym := range []*obj.LSym{fn.GCArgs, fn.GCLocals} {
 			if gcsym != nil && !gcsym.OnList() {
-				ggloblsym(gcsym, int32(len(gcsym.P)), obj.RODATA|obj.DUPOK)
+				objw.Global(gcsym, int32(len(gcsym.P)), obj.RODATA|obj.DUPOK)
 			}
 		}
 		if x := fn.StackObjects; x != nil {
 			attr := int16(obj.RODATA)
-			ggloblsym(x, int32(len(x.P)), attr)
+			objw.Global(x, int32(len(x.P)), attr)
 			x.Set(obj.AttrStatic, true)
 		}
 		if x := fn.OpenCodedDeferInfo; x != nil {
-			ggloblsym(x, int32(len(x.P)), obj.RODATA|obj.DUPOK)
+			objw.Global(x, int32(len(x.P)), obj.RODATA|obj.DUPOK)
+		}
+		if x := fn.ArgInfo; x != nil {
+			objw.Global(x, int32(len(x.P)), obj.RODATA|obj.DUPOK)
+			x.Set(obj.AttrStatic, true)
+			x.Set(obj.AttrContentAddressable, true)
 		}
 	}
 }
 
-func duintxx(s *obj.LSym, off int, v uint64, wid int) int {
-	if off&(wid-1) != 0 {
-		Fatalf("duintxxLSym: misaligned: v=%d wid=%d off=%d", v, wid, off)
+func ggloblnod(nam *ir.Name) {
+	s := nam.Linksym()
+	s.Gotype = reflectdata.TypeLinksym(nam.Type())
+	flags := 0
+	if nam.Readonly() {
+		flags = obj.RODATA
 	}
-	s.WriteInt(Ctxt, int64(off), wid, int64(v))
-	return off + wid
+	if nam.Type() != nil && !nam.Type().HasPointers() {
+		flags |= obj.NOPTR
+	}
+	base.Ctxt.Globl(s, nam.Type().Width, flags)
+	if nam.LibfuzzerExtraCounter() {
+		s.Type = objabi.SLIBFUZZER_EXTRA_COUNTER
+	}
+	if nam.Sym().Linkname != "" {
+		// Make sure linkname'd symbol is non-package. When a symbol is
+		// both imported and linkname'd, s.Pkg may not set to "_" in
+		// types.Sym.Linksym because LSym already exists. Set it here.
+		s.Pkg = "_"
+	}
 }
 
-func duint8(s *obj.LSym, off int, v uint8) int {
-	return duintxx(s, off, uint64(v), 1)
+func dumpembeds() {
+	for _, v := range typecheck.Target.Embeds {
+		staticdata.WriteEmbed(v)
+	}
 }
 
-func duint16(s *obj.LSym, off int, v uint16) int {
-	return duintxx(s, off, uint64(v), 2)
-}
-
-func duint32(s *obj.LSym, off int, v uint32) int {
-	return duintxx(s, off, uint64(v), 4)
-}
-
-func duintptr(s *obj.LSym, off int, v uint64) int {
-	return duintxx(s, off, v, Widthptr)
-}
-
-func dbvec(s *obj.LSym, off int, bv bvec) int {
-	// Runtime reads the bitmaps as byte arrays. Oblige.
-	for j := 0; int32(j) < bv.n; j += 8 {
-		word := bv.b[j/32]
-		off = duint8(s, off, uint8(word>>(uint(j)%32)))
-	}
-	return off
-}
-
-const (
-	stringSymPrefix  = "go.string."
-	stringSymPattern = ".gostring.%d.%x"
-)
-
-// stringsym returns a symbol containing the string s.
-// The symbol contains the string data, not a string header.
-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.
-		// Indulge in some paranoia by writing the length of s, too,
-		// as protection against length extension attacks.
-		// Same pattern is known to fileStringSym below.
-		h := sha256.New()
-		io.WriteString(h, s)
-		symname = fmt.Sprintf(stringSymPattern, len(s), h.Sum(nil))
-	} else {
-		// Small strings get named directly by their contents.
-		symname = strconv.Quote(s)
-	}
-
-	symdata := Ctxt.Lookup(stringSymPrefix + symname)
-	if !symdata.OnList() {
-		off := dstringdata(symdata, 0, s, pos, "string")
-		ggloblsym(symdata, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL)
-		symdata.Set(obj.AttrContentAddressable, true)
-	}
-
-	return symdata
-}
-
-// fileStringSym returns a symbol for the contents and the size of file.
-// If readonly is true, the symbol shares storage with any literal string
-// or other file with the same content and is placed in a read-only section.
-// If readonly is false, the symbol is a read-write copy separate from any other,
-// for use as the backing store of a []byte.
-// The content hash of file is copied into hash. (If hash is nil, nothing is copied.)
-// The returned symbol contains the data itself, not a string header.
-func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj.LSym, int64, error) {
-	f, err := os.Open(file)
-	if err != nil {
-		return nil, 0, err
-	}
-	defer f.Close()
-	info, err := f.Stat()
-	if err != nil {
-		return nil, 0, err
-	}
-	if !info.Mode().IsRegular() {
-		return nil, 0, fmt.Errorf("not a regular file")
-	}
-	size := info.Size()
-	if size <= 1*1024 {
-		data, err := ioutil.ReadAll(f)
-		if err != nil {
-			return nil, 0, err
+func addsignats(dcls []ir.Node) {
+	// copy types from dcl list to signatset
+	for _, n := range dcls {
+		if n.Op() == ir.OTYPE {
+			reflectdata.NeedRuntimeType(n.Type())
 		}
-		if int64(len(data)) != size {
-			return nil, 0, fmt.Errorf("file changed between reads")
-		}
-		var sym *obj.LSym
-		if readonly {
-			sym = stringsym(pos, string(data))
-		} else {
-			sym = slicedata(pos, string(data)).Sym.Linksym()
-		}
-		if len(hash) > 0 {
-			sum := sha256.Sum256(data)
-			copy(hash, sum[:])
-		}
-		return sym, size, nil
-	}
-	if size > 2e9 {
-		// ggloblsym takes an int32,
-		// and probably the rest of the toolchain
-		// can't handle such big symbols either.
-		// See golang.org/issue/9862.
-		return nil, 0, fmt.Errorf("file too large")
-	}
-
-	// File is too big to read and keep in memory.
-	// Compute hash if needed for read-only content hashing or if the caller wants it.
-	var sum []byte
-	if readonly || len(hash) > 0 {
-		h := sha256.New()
-		n, err := io.Copy(h, f)
-		if err != nil {
-			return nil, 0, err
-		}
-		if n != size {
-			return nil, 0, fmt.Errorf("file changed between reads")
-		}
-		sum = h.Sum(nil)
-		copy(hash, sum)
-	}
-
-	var symdata *obj.LSym
-	if readonly {
-		symname := fmt.Sprintf(stringSymPattern, size, sum)
-		symdata = Ctxt.Lookup(stringSymPrefix + symname)
-		if !symdata.OnList() {
-			info := symdata.NewFileInfo()
-			info.Name = file
-			info.Size = size
-			ggloblsym(symdata, int32(size), obj.DUPOK|obj.RODATA|obj.LOCAL)
-			// Note: AttrContentAddressable cannot be set here,
-			// because the content-addressable-handling code
-			// does not know about file symbols.
-		}
-	} else {
-		// Emit a zero-length data symbol
-		// and then fix up length and content to use file.
-		symdata = slicedata(pos, "").Sym.Linksym()
-		symdata.Size = size
-		symdata.Type = objabi.SNOPTRDATA
-		info := symdata.NewFileInfo()
-		info.Name = file
-		info.Size = size
-	}
-
-	return symdata, size, nil
-}
-
-var slicedataGen int
-
-func slicedata(pos src.XPos, s string) *Node {
-	slicedataGen++
-	symname := fmt.Sprintf(".gobytes.%d", slicedataGen)
-	sym := localpkg.Lookup(symname)
-	symnode := newname(sym)
-	sym.Def = asTypesNode(symnode)
-
-	lsym := sym.Linksym()
-	off := dstringdata(lsym, 0, s, pos, "slice")
-	ggloblsym(lsym, int32(off), obj.NOPTR|obj.LOCAL)
-
-	return symnode
-}
-
-func slicebytes(nam *Node, s string) {
-	if nam.Op != ONAME {
-		Fatalf("slicebytes %v", nam)
-	}
-	slicesym(nam, slicedata(nam.Pos, s), int64(len(s)))
-}
-
-func dstringdata(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)
-}
-
-func dsymptr(s *obj.LSym, off int, x *obj.LSym, xoff int) int {
-	off = int(Rnd(int64(off), int64(Widthptr)))
-	s.WriteAddr(Ctxt, int64(off), Widthptr, x, int64(xoff))
-	off += Widthptr
-	return off
-}
-
-func dsymptrOff(s *obj.LSym, off int, x *obj.LSym) int {
-	s.WriteOff(Ctxt, int64(off), x, 0)
-	off += 4
-	return off
-}
-
-func dsymptrWeakOff(s *obj.LSym, off int, x *obj.LSym) int {
-	s.WriteWeakOff(Ctxt, int64(off), x, 0)
-	off += 4
-	return off
-}
-
-// slicesym writes a static slice symbol {&arr, lencap, lencap} to n.
-// arr must be an ONAME. slicesym does not modify n.
-func slicesym(n, arr *Node, lencap int64) {
-	s := n.Sym.Linksym()
-	base := n.Xoffset
-	if arr.Op != ONAME {
-		Fatalf("slicesym non-name arr %v", arr)
-	}
-	s.WriteAddr(Ctxt, base, Widthptr, arr.Sym.Linksym(), arr.Xoffset)
-	s.WriteInt(Ctxt, base+sliceLenOffset, Widthptr, lencap)
-	s.WriteInt(Ctxt, base+sliceCapOffset, Widthptr, lencap)
-}
-
-// addrsym writes the static address of a to n. a must be an ONAME.
-// Neither n nor a is modified.
-func addrsym(n, a *Node) {
-	if n.Op != ONAME {
-		Fatalf("addrsym n op %v", n.Op)
-	}
-	if n.Sym == nil {
-		Fatalf("addrsym nil n sym")
-	}
-	if a.Op != ONAME {
-		Fatalf("addrsym a op %v", a.Op)
-	}
-	s := n.Sym.Linksym()
-	s.WriteAddr(Ctxt, n.Xoffset, Widthptr, a.Sym.Linksym(), a.Xoffset)
-}
-
-// pfuncsym writes the static address of f to n. f must be a global function.
-// Neither n nor f is modified.
-func pfuncsym(n, f *Node) {
-	if n.Op != ONAME {
-		Fatalf("pfuncsym n op %v", n.Op)
-	}
-	if n.Sym == nil {
-		Fatalf("pfuncsym nil n sym")
-	}
-	if f.Class() != PFUNC {
-		Fatalf("pfuncsym class not PFUNC %d", f.Class())
-	}
-	s := n.Sym.Linksym()
-	s.WriteAddr(Ctxt, n.Xoffset, Widthptr, funcsym(f.Sym).Linksym(), f.Xoffset)
-}
-
-// litsym writes the static literal c to n.
-// Neither n nor c is modified.
-func litsym(n, c *Node, wid int) {
-	if n.Op != ONAME {
-		Fatalf("litsym n op %v", n.Op)
-	}
-	if c.Op != OLITERAL {
-		Fatalf("litsym c op %v", c.Op)
-	}
-	if n.Sym == nil {
-		Fatalf("litsym nil n sym")
-	}
-	s := n.Sym.Linksym()
-	switch u := c.Val().U.(type) {
-	case bool:
-		i := int64(obj.Bool2int(u))
-		s.WriteInt(Ctxt, n.Xoffset, wid, i)
-
-	case *Mpint:
-		s.WriteInt(Ctxt, n.Xoffset, wid, u.Int64())
-
-	case *Mpflt:
-		f := u.Float64()
-		switch n.Type.Etype {
-		case TFLOAT32:
-			s.WriteFloat32(Ctxt, n.Xoffset, float32(f))
-		case TFLOAT64:
-			s.WriteFloat64(Ctxt, n.Xoffset, f)
-		}
-
-	case *Mpcplx:
-		r := u.Real.Float64()
-		i := u.Imag.Float64()
-		switch n.Type.Etype {
-		case TCOMPLEX64:
-			s.WriteFloat32(Ctxt, n.Xoffset, float32(r))
-			s.WriteFloat32(Ctxt, n.Xoffset+4, float32(i))
-		case TCOMPLEX128:
-			s.WriteFloat64(Ctxt, n.Xoffset, r)
-			s.WriteFloat64(Ctxt, n.Xoffset+8, i)
-		}
-
-	case string:
-		symdata := stringsym(n.Pos, u)
-		s.WriteAddr(Ctxt, n.Xoffset, Widthptr, symdata, 0)
-		s.WriteInt(Ctxt, n.Xoffset+int64(Widthptr), Widthptr, int64(len(u)))
-
-	default:
-		Fatalf("litsym unhandled OLITERAL %v", c)
 	}
 }
diff --git a/src/cmd/compile/internal/gc/op_string.go b/src/cmd/compile/internal/gc/op_string.go
deleted file mode 100644
index 41d5883..0000000
--- a/src/cmd/compile/internal/gc/op_string.go
+++ /dev/null
@@ -1,175 +0,0 @@
-// Code generated by "stringer -type=Op -trimprefix=O"; DO NOT EDIT.
-
-package gc
-
-import "strconv"
-
-func _() {
-	// An "invalid array index" compiler error signifies that the constant values have changed.
-	// Re-run the stringer command to generate them again.
-	var x [1]struct{}
-	_ = x[OXXX-0]
-	_ = x[ONAME-1]
-	_ = x[ONONAME-2]
-	_ = x[OTYPE-3]
-	_ = x[OPACK-4]
-	_ = x[OLITERAL-5]
-	_ = x[OADD-6]
-	_ = x[OSUB-7]
-	_ = x[OOR-8]
-	_ = x[OXOR-9]
-	_ = x[OADDSTR-10]
-	_ = x[OADDR-11]
-	_ = x[OANDAND-12]
-	_ = x[OAPPEND-13]
-	_ = x[OBYTES2STR-14]
-	_ = x[OBYTES2STRTMP-15]
-	_ = x[ORUNES2STR-16]
-	_ = x[OSTR2BYTES-17]
-	_ = x[OSTR2BYTESTMP-18]
-	_ = x[OSTR2RUNES-19]
-	_ = x[OAS-20]
-	_ = x[OAS2-21]
-	_ = x[OAS2DOTTYPE-22]
-	_ = x[OAS2FUNC-23]
-	_ = x[OAS2MAPR-24]
-	_ = x[OAS2RECV-25]
-	_ = x[OASOP-26]
-	_ = x[OCALL-27]
-	_ = x[OCALLFUNC-28]
-	_ = x[OCALLMETH-29]
-	_ = x[OCALLINTER-30]
-	_ = x[OCALLPART-31]
-	_ = x[OCAP-32]
-	_ = x[OCLOSE-33]
-	_ = x[OCLOSURE-34]
-	_ = x[OCOMPLIT-35]
-	_ = x[OMAPLIT-36]
-	_ = x[OSTRUCTLIT-37]
-	_ = x[OARRAYLIT-38]
-	_ = x[OSLICELIT-39]
-	_ = x[OPTRLIT-40]
-	_ = x[OCONV-41]
-	_ = x[OCONVIFACE-42]
-	_ = x[OCONVNOP-43]
-	_ = x[OCOPY-44]
-	_ = x[ODCL-45]
-	_ = x[ODCLFUNC-46]
-	_ = x[ODCLFIELD-47]
-	_ = x[ODCLCONST-48]
-	_ = x[ODCLTYPE-49]
-	_ = x[ODELETE-50]
-	_ = x[ODOT-51]
-	_ = x[ODOTPTR-52]
-	_ = x[ODOTMETH-53]
-	_ = x[ODOTINTER-54]
-	_ = x[OXDOT-55]
-	_ = x[ODOTTYPE-56]
-	_ = x[ODOTTYPE2-57]
-	_ = x[OEQ-58]
-	_ = x[ONE-59]
-	_ = x[OLT-60]
-	_ = x[OLE-61]
-	_ = x[OGE-62]
-	_ = x[OGT-63]
-	_ = x[ODEREF-64]
-	_ = x[OINDEX-65]
-	_ = x[OINDEXMAP-66]
-	_ = x[OKEY-67]
-	_ = x[OSTRUCTKEY-68]
-	_ = x[OLEN-69]
-	_ = x[OMAKE-70]
-	_ = x[OMAKECHAN-71]
-	_ = x[OMAKEMAP-72]
-	_ = x[OMAKESLICE-73]
-	_ = x[OMAKESLICECOPY-74]
-	_ = x[OMUL-75]
-	_ = x[ODIV-76]
-	_ = x[OMOD-77]
-	_ = x[OLSH-78]
-	_ = x[ORSH-79]
-	_ = x[OAND-80]
-	_ = x[OANDNOT-81]
-	_ = x[ONEW-82]
-	_ = x[ONEWOBJ-83]
-	_ = x[ONOT-84]
-	_ = x[OBITNOT-85]
-	_ = x[OPLUS-86]
-	_ = x[ONEG-87]
-	_ = x[OOROR-88]
-	_ = x[OPANIC-89]
-	_ = x[OPRINT-90]
-	_ = x[OPRINTN-91]
-	_ = x[OPAREN-92]
-	_ = x[OSEND-93]
-	_ = x[OSLICE-94]
-	_ = x[OSLICEARR-95]
-	_ = x[OSLICESTR-96]
-	_ = x[OSLICE3-97]
-	_ = x[OSLICE3ARR-98]
-	_ = x[OSLICEHEADER-99]
-	_ = x[ORECOVER-100]
-	_ = x[ORECV-101]
-	_ = x[ORUNESTR-102]
-	_ = x[OSELRECV-103]
-	_ = x[OSELRECV2-104]
-	_ = x[OIOTA-105]
-	_ = x[OREAL-106]
-	_ = x[OIMAG-107]
-	_ = x[OCOMPLEX-108]
-	_ = x[OALIGNOF-109]
-	_ = x[OOFFSETOF-110]
-	_ = x[OSIZEOF-111]
-	_ = x[OBLOCK-112]
-	_ = x[OBREAK-113]
-	_ = x[OCASE-114]
-	_ = x[OCONTINUE-115]
-	_ = x[ODEFER-116]
-	_ = x[OEMPTY-117]
-	_ = x[OFALL-118]
-	_ = x[OFOR-119]
-	_ = x[OFORUNTIL-120]
-	_ = x[OGOTO-121]
-	_ = x[OIF-122]
-	_ = x[OLABEL-123]
-	_ = x[OGO-124]
-	_ = x[ORANGE-125]
-	_ = x[ORETURN-126]
-	_ = x[OSELECT-127]
-	_ = x[OSWITCH-128]
-	_ = x[OTYPESW-129]
-	_ = x[OTCHAN-130]
-	_ = x[OTMAP-131]
-	_ = x[OTSTRUCT-132]
-	_ = x[OTINTER-133]
-	_ = x[OTFUNC-134]
-	_ = x[OTARRAY-135]
-	_ = x[ODDD-136]
-	_ = x[OINLCALL-137]
-	_ = x[OEFACE-138]
-	_ = x[OITAB-139]
-	_ = x[OIDATA-140]
-	_ = x[OSPTR-141]
-	_ = x[OCLOSUREVAR-142]
-	_ = x[OCFUNC-143]
-	_ = x[OCHECKNIL-144]
-	_ = x[OVARDEF-145]
-	_ = x[OVARKILL-146]
-	_ = x[OVARLIVE-147]
-	_ = x[ORESULT-148]
-	_ = x[OINLMARK-149]
-	_ = x[ORETJMP-150]
-	_ = x[OGETG-151]
-	_ = x[OEND-152]
-}
-
-const _Op_name = "XXXNAMENONAMETYPEPACKLITERALADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLFIELDDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNEWOBJNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECVRUNESTRSELRECVSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFBLOCKBREAKCASECONTINUEDEFEREMPTYFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWTCHANTMAPTSTRUCTTINTERTFUNCTARRAYDDDINLCALLEFACEITABIDATASPTRCLOSUREVARCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKRETJMPGETGEND"
-
-var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 36, 39, 45, 49, 55, 61, 70, 82, 91, 100, 112, 121, 123, 126, 136, 143, 150, 157, 161, 165, 173, 181, 190, 198, 201, 206, 213, 220, 226, 235, 243, 251, 257, 261, 270, 277, 281, 284, 291, 299, 307, 314, 320, 323, 329, 336, 344, 348, 355, 363, 365, 367, 369, 371, 373, 375, 380, 385, 393, 396, 405, 408, 412, 420, 427, 436, 449, 452, 455, 458, 461, 464, 467, 473, 476, 482, 485, 491, 495, 498, 502, 507, 512, 518, 523, 527, 532, 540, 548, 554, 563, 574, 581, 585, 592, 599, 607, 611, 615, 619, 626, 633, 641, 647, 652, 657, 661, 669, 674, 679, 683, 686, 694, 698, 700, 705, 707, 712, 718, 724, 730, 736, 741, 745, 752, 758, 763, 769, 772, 779, 784, 788, 793, 797, 807, 812, 820, 826, 833, 840, 846, 853, 859, 863, 866}
-
-func (i Op) String() string {
-	if i >= Op(len(_Op_index)-1) {
-		return "Op(" + strconv.FormatInt(int64(i), 10) + ")"
-	}
-	return _Op_name[_Op_index[i]:_Op_index[i+1]]
-}
diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go
deleted file mode 100644
index 30e1535..0000000
--- a/src/cmd/compile/internal/gc/order.go
+++ /dev/null
@@ -1,1441 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
-	"cmd/compile/internal/types"
-	"cmd/internal/src"
-	"fmt"
-)
-
-// Rewrite tree to use separate statements to enforce
-// order of evaluation. Makes walk easier, because it
-// can (after this runs) reorder at will within an expression.
-//
-// Rewrite m[k] op= r into m[k] = m[k] op r if op is / or %.
-//
-// Introduce temporaries as needed by runtime routines.
-// For example, the map runtime routines take the map key
-// by reference, so make sure all map keys are addressable
-// by copying them to temporaries as needed.
-// The same is true for channel operations.
-//
-// Arrange that map index expressions only appear in direct
-// assignments x = m[k] or m[k] = x, never in larger expressions.
-//
-// Arrange that receive expressions only appear in direct assignments
-// x = <-c or as standalone statements <-c, never in larger expressions.
-
-// TODO(rsc): The temporary introduction during multiple assignments
-// should be moved into this file, so that the temporaries can be cleaned
-// and so that conversions implicit in the OAS2FUNC and OAS2RECV
-// nodes can be made explicit and then have their temporaries cleaned.
-
-// TODO(rsc): Goto and multilevel break/continue can jump over
-// inserted VARKILL annotations. Work out a way to handle these.
-// The current implementation is safe, in that it will execute correctly.
-// But it won't reuse temporaries as aggressively as it might, and
-// it can result in unnecessary zeroing of those variables in the function
-// prologue.
-
-// Order holds state during the ordering process.
-type Order struct {
-	out  []*Node            // list of generated statements
-	temp []*Node            // stack of temporary variables
-	free map[string][]*Node // free list of unused temporaries, by type.LongString().
-}
-
-// Order rewrites fn.Nbody to apply the ordering constraints
-// described in the comment at the top of the file.
-func order(fn *Node) {
-	if Debug.W > 1 {
-		s := fmt.Sprintf("\nbefore order %v", fn.Func.Nname.Sym)
-		dumplist(s, fn.Nbody)
-	}
-
-	orderBlock(&fn.Nbody, map[string][]*Node{})
-}
-
-// newTemp allocates a new temporary with the given type,
-// pushes it onto the temp stack, and returns it.
-// If clear is true, newTemp emits code to zero the temporary.
-func (o *Order) newTemp(t *types.Type, clear bool) *Node {
-	var v *Node
-	// Note: LongString is close to the type equality we want,
-	// but not exactly. We still need to double-check with types.Identical.
-	key := t.LongString()
-	a := o.free[key]
-	for i, n := range a {
-		if types.Identical(t, n.Type) {
-			v = a[i]
-			a[i] = a[len(a)-1]
-			a = a[:len(a)-1]
-			o.free[key] = a
-			break
-		}
-	}
-	if v == nil {
-		v = temp(t)
-	}
-	if clear {
-		a := nod(OAS, v, nil)
-		a = typecheck(a, ctxStmt)
-		o.out = append(o.out, a)
-	}
-
-	o.temp = append(o.temp, v)
-	return v
-}
-
-// copyExpr behaves like newTemp but also emits
-// code to initialize the temporary to the value n.
-//
-// The clear argument is provided for use when the evaluation
-// of tmp = n turns into a function call that is passed a pointer
-// to the temporary as the output space. If the call blocks before
-// tmp has been written, the garbage collector will still treat the
-// temporary as live, so we must zero it before entering that call.
-// Today, this only happens for channel receive operations.
-// (The other candidate would be map access, but map access
-// returns a pointer to the result data instead of taking a pointer
-// to be filled in.)
-func (o *Order) copyExpr(n *Node, t *types.Type, clear bool) *Node {
-	v := o.newTemp(t, clear)
-	a := nod(OAS, v, n)
-	a = typecheck(a, ctxStmt)
-	o.out = append(o.out, a)
-	return v
-}
-
-// cheapExpr returns a cheap version of n.
-// The definition of cheap is that n is a variable or constant.
-// If not, cheapExpr allocates a new tmp, emits tmp = n,
-// and then returns tmp.
-func (o *Order) cheapExpr(n *Node) *Node {
-	if n == nil {
-		return nil
-	}
-
-	switch n.Op {
-	case ONAME, OLITERAL:
-		return n
-	case OLEN, OCAP:
-		l := o.cheapExpr(n.Left)
-		if l == n.Left {
-			return n
-		}
-		a := n.sepcopy()
-		a.Left = l
-		return typecheck(a, ctxExpr)
-	}
-
-	return o.copyExpr(n, n.Type, false)
-}
-
-// safeExpr returns a safe version of n.
-// The definition of safe is that n can appear multiple times
-// without violating the semantics of the original program,
-// and that assigning to the safe version has the same effect
-// as assigning to the original n.
-//
-// The intended use is to apply to x when rewriting x += y into x = x + y.
-func (o *Order) safeExpr(n *Node) *Node {
-	switch n.Op {
-	case ONAME, OLITERAL:
-		return n
-
-	case ODOT, OLEN, OCAP:
-		l := o.safeExpr(n.Left)
-		if l == n.Left {
-			return n
-		}
-		a := n.sepcopy()
-		a.Left = l
-		return typecheck(a, ctxExpr)
-
-	case ODOTPTR, ODEREF:
-		l := o.cheapExpr(n.Left)
-		if l == n.Left {
-			return n
-		}
-		a := n.sepcopy()
-		a.Left = l
-		return typecheck(a, ctxExpr)
-
-	case OINDEX, OINDEXMAP:
-		var l *Node
-		if n.Left.Type.IsArray() {
-			l = o.safeExpr(n.Left)
-		} else {
-			l = o.cheapExpr(n.Left)
-		}
-		r := o.cheapExpr(n.Right)
-		if l == n.Left && r == n.Right {
-			return n
-		}
-		a := n.sepcopy()
-		a.Left = l
-		a.Right = r
-		return typecheck(a, ctxExpr)
-
-	default:
-		Fatalf("order.safeExpr %v", n.Op)
-		return nil // not reached
-	}
-}
-
-// isaddrokay reports whether it is okay to pass n's address to runtime routines.
-// Taking the address of a variable makes the liveness and optimization analyses
-// lose track of where the variable's lifetime ends. To avoid hurting the analyses
-// of ordinary stack variables, those are not 'isaddrokay'. Temporaries are okay,
-// because we emit explicit VARKILL instructions marking the end of those
-// temporaries' lifetimes.
-func isaddrokay(n *Node) bool {
-	return islvalue(n) && (n.Op != ONAME || n.Class() == PEXTERN || n.IsAutoTmp())
-}
-
-// addrTemp ensures that n is okay to pass by address to runtime routines.
-// If the original argument n is not okay, addrTemp creates a tmp, emits
-// tmp = n, and then returns tmp.
-// The result of addrTemp MUST be assigned back to n, e.g.
-// 	n.Left = o.addrTemp(n.Left)
-func (o *Order) addrTemp(n *Node) *Node {
-	if consttype(n) != CTxxx {
-		// TODO: expand this to all static composite literal nodes?
-		n = defaultlit(n, nil)
-		dowidth(n.Type)
-		vstat := readonlystaticname(n.Type)
-		var s InitSchedule
-		s.staticassign(vstat, n)
-		if s.out != nil {
-			Fatalf("staticassign of const generated code: %+v", n)
-		}
-		vstat = typecheck(vstat, ctxExpr)
-		return vstat
-	}
-	if isaddrokay(n) {
-		return n
-	}
-	return o.copyExpr(n, n.Type, false)
-}
-
-// mapKeyTemp prepares n to be a key in a map runtime call and returns n.
-// It should only be used for map runtime calls which have *_fast* versions.
-func (o *Order) mapKeyTemp(t *types.Type, n *Node) *Node {
-	// Most map calls need to take the address of the key.
-	// Exception: map*_fast* calls. See golang.org/issue/19015.
-	if mapfast(t) == mapslow {
-		return o.addrTemp(n)
-	}
-	return n
-}
-
-// mapKeyReplaceStrConv replaces OBYTES2STR by OBYTES2STRTMP
-// in n to avoid string allocations for keys in map lookups.
-// Returns a bool that signals if a modification was made.
-//
-// For:
-//  x = m[string(k)]
-//  x = m[T1{... Tn{..., string(k), ...}]
-// where k is []byte, T1 to Tn is a nesting of struct and array literals,
-// the allocation of backing bytes for the string can be avoided
-// by reusing the []byte backing array. These are special cases
-// for avoiding allocations when converting byte slices to strings.
-// It would be nice to handle these generally, but because
-// []byte keys are not allowed in maps, the use of string(k)
-// comes up in important cases in practice. See issue 3512.
-func mapKeyReplaceStrConv(n *Node) bool {
-	var replaced bool
-	switch n.Op {
-	case OBYTES2STR:
-		n.Op = OBYTES2STRTMP
-		replaced = true
-	case OSTRUCTLIT:
-		for _, elem := range n.List.Slice() {
-			if mapKeyReplaceStrConv(elem.Left) {
-				replaced = true
-			}
-		}
-	case OARRAYLIT:
-		for _, elem := range n.List.Slice() {
-			if elem.Op == OKEY {
-				elem = elem.Right
-			}
-			if mapKeyReplaceStrConv(elem) {
-				replaced = true
-			}
-		}
-	}
-	return replaced
-}
-
-type ordermarker int
-
-// markTemp returns the top of the temporary variable stack.
-func (o *Order) markTemp() ordermarker {
-	return ordermarker(len(o.temp))
-}
-
-// popTemp pops temporaries off the stack until reaching the mark,
-// which must have been returned by markTemp.
-func (o *Order) popTemp(mark ordermarker) {
-	for _, n := range o.temp[mark:] {
-		key := n.Type.LongString()
-		o.free[key] = append(o.free[key], n)
-	}
-	o.temp = o.temp[:mark]
-}
-
-// cleanTempNoPop emits VARKILL instructions to *out
-// for each temporary above the mark on the temporary stack.
-// It does not pop the temporaries from the stack.
-func (o *Order) cleanTempNoPop(mark ordermarker) []*Node {
-	var out []*Node
-	for i := len(o.temp) - 1; i >= int(mark); i-- {
-		n := o.temp[i]
-		kill := nod(OVARKILL, n, nil)
-		kill = typecheck(kill, ctxStmt)
-		out = append(out, kill)
-	}
-	return out
-}
-
-// cleanTemp emits VARKILL instructions for each temporary above the
-// mark on the temporary stack and removes them from the stack.
-func (o *Order) cleanTemp(top ordermarker) {
-	o.out = append(o.out, o.cleanTempNoPop(top)...)
-	o.popTemp(top)
-}
-
-// stmtList orders each of the statements in the list.
-func (o *Order) stmtList(l Nodes) {
-	s := l.Slice()
-	for i := range s {
-		orderMakeSliceCopy(s[i:])
-		o.stmt(s[i])
-	}
-}
-
-// orderMakeSliceCopy matches the pattern:
-//  m = OMAKESLICE([]T, x); OCOPY(m, s)
-// and rewrites it to:
-//  m = OMAKESLICECOPY([]T, x, s); nil
-func orderMakeSliceCopy(s []*Node) {
-	if Debug.N != 0 || instrumenting {
-		return
-	}
-
-	if len(s) < 2 {
-		return
-	}
-
-	asn := s[0]
-	copyn := s[1]
-
-	if asn == nil || asn.Op != OAS {
-		return
-	}
-	if asn.Left.Op != ONAME {
-		return
-	}
-	if asn.Left.isBlank() {
-		return
-	}
-	maken := asn.Right
-	if maken == nil || maken.Op != OMAKESLICE {
-		return
-	}
-	if maken.Esc == EscNone {
-		return
-	}
-	if maken.Left == nil || maken.Right != nil {
-		return
-	}
-	if copyn.Op != OCOPY {
-		return
-	}
-	if copyn.Left.Op != ONAME {
-		return
-	}
-	if asn.Left.Sym != copyn.Left.Sym {
-		return
-	}
-	if copyn.Right.Op != ONAME {
-		return
-	}
-
-	if copyn.Left.Sym == copyn.Right.Sym {
-		return
-	}
-
-	maken.Op = OMAKESLICECOPY
-	maken.Right = copyn.Right
-	// Set bounded when m = OMAKESLICE([]T, len(s)); OCOPY(m, s)
-	maken.SetBounded(maken.Left.Op == OLEN && samesafeexpr(maken.Left.Left, copyn.Right))
-
-	maken = typecheck(maken, ctxExpr)
-
-	s[1] = nil // remove separate copy call
-
-	return
-}
-
-// edge inserts coverage instrumentation for libfuzzer.
-func (o *Order) edge() {
-	if Debug_libfuzzer == 0 {
-		return
-	}
-
-	// Create a new uint8 counter to be allocated in section
-	// __libfuzzer_extra_counters.
-	counter := staticname(types.Types[TUINT8])
-	counter.Name.SetLibfuzzerExtraCounter(true)
-
-	// counter += 1
-	incr := nod(OASOP, counter, nodintconst(1))
-	incr.SetSubOp(OADD)
-	incr = typecheck(incr, ctxStmt)
-
-	o.out = append(o.out, incr)
-}
-
-// orderBlock orders the block of statements in n into a new slice,
-// and then replaces the old slice in n with the new slice.
-// free is a map that can be used to obtain temporary variables by type.
-func orderBlock(n *Nodes, free map[string][]*Node) {
-	var order Order
-	order.free = free
-	mark := order.markTemp()
-	order.edge()
-	order.stmtList(*n)
-	order.cleanTemp(mark)
-	n.Set(order.out)
-}
-
-// exprInPlace orders the side effects in *np and
-// leaves them as the init list of the final *np.
-// The result of exprInPlace MUST be assigned back to n, e.g.
-// 	n.Left = o.exprInPlace(n.Left)
-func (o *Order) exprInPlace(n *Node) *Node {
-	var order Order
-	order.free = o.free
-	n = order.expr(n, nil)
-	n = addinit(n, order.out)
-
-	// insert new temporaries from order
-	// at head of outer list.
-	o.temp = append(o.temp, order.temp...)
-	return n
-}
-
-// orderStmtInPlace orders the side effects of the single statement *np
-// and replaces it with the resulting statement list.
-// The result of orderStmtInPlace MUST be assigned back to n, e.g.
-// 	n.Left = orderStmtInPlace(n.Left)
-// free is a map that can be used to obtain temporary variables by type.
-func orderStmtInPlace(n *Node, free map[string][]*Node) *Node {
-	var order Order
-	order.free = free
-	mark := order.markTemp()
-	order.stmt(n)
-	order.cleanTemp(mark)
-	return liststmt(order.out)
-}
-
-// init moves n's init list to o.out.
-func (o *Order) init(n *Node) {
-	if n.mayBeShared() {
-		// For concurrency safety, don't mutate potentially shared nodes.
-		// First, ensure that no work is required here.
-		if n.Ninit.Len() > 0 {
-			Fatalf("order.init shared node with ninit")
-		}
-		return
-	}
-	o.stmtList(n.Ninit)
-	n.Ninit.Set(nil)
-}
-
-// call orders the call expression n.
-// n.Op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY.
-func (o *Order) call(n *Node) {
-	if n.Ninit.Len() > 0 {
-		// Caller should have already called o.init(n).
-		Fatalf("%v with unexpected ninit", n.Op)
-	}
-
-	// Builtin functions.
-	if n.Op != OCALLFUNC && n.Op != OCALLMETH && n.Op != OCALLINTER {
-		n.Left = o.expr(n.Left, nil)
-		n.Right = o.expr(n.Right, nil)
-		o.exprList(n.List)
-		return
-	}
-
-	fixVariadicCall(n)
-	n.Left = o.expr(n.Left, nil)
-	o.exprList(n.List)
-
-	if n.Op == OCALLINTER {
-		return
-	}
-	keepAlive := func(arg *Node) {
-		// If the argument is really a pointer being converted to uintptr,
-		// arrange for the pointer to be kept alive until the call returns,
-		// by copying it into a temp and marking that temp
-		// still alive when we pop the temp stack.
-		if arg.Op == OCONVNOP && arg.Left.Type.IsUnsafePtr() {
-			x := o.copyExpr(arg.Left, arg.Left.Type, false)
-			arg.Left = x
-			x.Name.SetAddrtaken(true) // ensure SSA keeps the x variable
-			n.Nbody.Append(typecheck(nod(OVARLIVE, x, nil), ctxStmt))
-		}
-	}
-
-	// Check for "unsafe-uintptr" tag provided by escape analysis.
-	for i, param := range n.Left.Type.Params().FieldSlice() {
-		if param.Note == unsafeUintptrTag || param.Note == uintptrEscapesTag {
-			if arg := n.List.Index(i); arg.Op == OSLICELIT {
-				for _, elt := range arg.List.Slice() {
-					keepAlive(elt)
-				}
-			} else {
-				keepAlive(arg)
-			}
-		}
-	}
-}
-
-// mapAssign appends n to o.out, introducing temporaries
-// to make sure that all map assignments have the form m[k] = x.
-// (Note: expr has already been called on n, so we know k is addressable.)
-//
-// If n is the multiple assignment form ..., m[k], ... = ..., x, ..., the rewrite is
-//	t1 = m
-//	t2 = k
-//	...., t3, ... = ..., x, ...
-//	t1[t2] = t3
-//
-// The temporaries t1, t2 are needed in case the ... being assigned
-// contain m or k. They are usually unnecessary, but in the unnecessary
-// cases they are also typically registerizable, so not much harm done.
-// And this only applies to the multiple-assignment form.
-// We could do a more precise analysis if needed, like in walk.go.
-func (o *Order) mapAssign(n *Node) {
-	switch n.Op {
-	default:
-		Fatalf("order.mapAssign %v", n.Op)
-
-	case OAS, OASOP:
-		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.
-			if n.Right.Op == OAPPEND {
-				s := n.Right.List.Slice()[1:]
-				for i, n := range s {
-					s[i] = o.cheapExpr(n)
-				}
-			} else {
-				n.Right = o.cheapExpr(n.Right)
-			}
-		}
-		o.out = append(o.out, n)
-
-	case OAS2, OAS2DOTTYPE, OAS2MAPR, OAS2FUNC:
-		var post []*Node
-		for i, m := range n.List.Slice() {
-			switch {
-			case m.Op == OINDEXMAP:
-				if !m.Left.IsAutoTmp() {
-					m.Left = o.copyExpr(m.Left, m.Left.Type, false)
-				}
-				if !m.Right.IsAutoTmp() {
-					m.Right = o.copyExpr(m.Right, m.Right.Type, false)
-				}
-				fallthrough
-			case instrumenting && n.Op == OAS2FUNC && !m.isBlank():
-				t := o.newTemp(m.Type, false)
-				n.List.SetIndex(i, t)
-				a := nod(OAS, m, t)
-				a = typecheck(a, ctxStmt)
-				post = append(post, a)
-			}
-		}
-
-		o.out = append(o.out, n)
-		o.out = append(o.out, post...)
-	}
-}
-
-// stmt orders the statement n, appending to o.out.
-// Temporaries created during the statement are cleaned
-// up using VARKILL instructions as possible.
-func (o *Order) stmt(n *Node) {
-	if n == nil {
-		return
-	}
-
-	lno := setlineno(n)
-	o.init(n)
-
-	switch n.Op {
-	default:
-		Fatalf("order.stmt %v", n.Op)
-
-	case OVARKILL, OVARLIVE, OINLMARK:
-		o.out = append(o.out, n)
-
-	case OAS:
-		t := o.markTemp()
-		n.Left = o.expr(n.Left, nil)
-		n.Right = o.expr(n.Right, n.Left)
-		o.mapAssign(n)
-		o.cleanTemp(t)
-
-	case OASOP:
-		t := o.markTemp()
-		n.Left = o.expr(n.Left, nil)
-		n.Right = o.expr(n.Right, nil)
-
-		if instrumenting || n.Left.Op == OINDEXMAP && (n.SubOp() == ODIV || n.SubOp() == OMOD) {
-			// Rewrite m[k] op= r into m[k] = m[k] op r so
-			// that we can ensure that if op panics
-			// because r is zero, the panic happens before
-			// the map assignment.
-
-			n.Left = o.safeExpr(n.Left)
-
-			l := treecopy(n.Left, src.NoXPos)
-			if l.Op == OINDEXMAP {
-				l.SetIndexMapLValue(false)
-			}
-			l = o.copyExpr(l, n.Left.Type, false)
-			n.Right = nod(n.SubOp(), l, n.Right)
-			n.Right = typecheck(n.Right, ctxExpr)
-			n.Right = o.expr(n.Right, nil)
-
-			n.Op = OAS
-			n.ResetAux()
-		}
-
-		o.mapAssign(n)
-		o.cleanTemp(t)
-
-	case OAS2:
-		t := o.markTemp()
-		o.exprList(n.List)
-		o.exprList(n.Rlist)
-		o.mapAssign(n)
-		o.cleanTemp(t)
-
-	// Special: avoid copy of func call n.Right
-	case OAS2FUNC:
-		t := o.markTemp()
-		o.exprList(n.List)
-		o.init(n.Right)
-		o.call(n.Right)
-		o.as2(n)
-		o.cleanTemp(t)
-
-	// Special: use temporary variables to hold result,
-	// so that runtime can take address of temporary.
-	// No temporary for blank assignment.
-	//
-	// OAS2MAPR: make sure key is addressable if needed,
-	//           and make sure OINDEXMAP is not copied out.
-	case OAS2DOTTYPE, OAS2RECV, OAS2MAPR:
-		t := o.markTemp()
-		o.exprList(n.List)
-
-		switch r := n.Right; r.Op {
-		case ODOTTYPE2, ORECV:
-			r.Left = o.expr(r.Left, nil)
-		case OINDEXMAP:
-			r.Left = o.expr(r.Left, nil)
-			r.Right = o.expr(r.Right, nil)
-			// See similar conversion for OINDEXMAP below.
-			_ = mapKeyReplaceStrConv(r.Right)
-			r.Right = o.mapKeyTemp(r.Left.Type, r.Right)
-		default:
-			Fatalf("order.stmt: %v", r.Op)
-		}
-
-		o.okAs2(n)
-		o.cleanTemp(t)
-
-	// Special: does not save n onto out.
-	case OBLOCK, OEMPTY:
-		o.stmtList(n.List)
-
-	// Special: n->left is not an expression; save as is.
-	case OBREAK,
-		OCONTINUE,
-		ODCL,
-		ODCLCONST,
-		ODCLTYPE,
-		OFALL,
-		OGOTO,
-		OLABEL,
-		ORETJMP:
-		o.out = append(o.out, n)
-
-	// Special: handle call arguments.
-	case OCALLFUNC, OCALLINTER, OCALLMETH:
-		t := o.markTemp()
-		o.call(n)
-		o.out = append(o.out, n)
-		o.cleanTemp(t)
-
-	case OCLOSE,
-		OCOPY,
-		OPRINT,
-		OPRINTN,
-		ORECOVER,
-		ORECV:
-		t := o.markTemp()
-		n.Left = o.expr(n.Left, nil)
-		n.Right = o.expr(n.Right, nil)
-		o.exprList(n.List)
-		o.exprList(n.Rlist)
-		o.out = append(o.out, n)
-		o.cleanTemp(t)
-
-	// Special: order arguments to inner call but not call itself.
-	case ODEFER, OGO:
-		t := o.markTemp()
-		o.init(n.Left)
-		o.call(n.Left)
-		o.out = append(o.out, n)
-		o.cleanTemp(t)
-
-	case ODELETE:
-		t := o.markTemp()
-		n.List.SetFirst(o.expr(n.List.First(), nil))
-		n.List.SetSecond(o.expr(n.List.Second(), nil))
-		n.List.SetSecond(o.mapKeyTemp(n.List.First().Type, n.List.Second()))
-		o.out = append(o.out, n)
-		o.cleanTemp(t)
-
-	// Clean temporaries from condition evaluation at
-	// beginning of loop body and after for statement.
-	case OFOR:
-		t := o.markTemp()
-		n.Left = o.exprInPlace(n.Left)
-		n.Nbody.Prepend(o.cleanTempNoPop(t)...)
-		orderBlock(&n.Nbody, o.free)
-		n.Right = orderStmtInPlace(n.Right, o.free)
-		o.out = append(o.out, n)
-		o.cleanTemp(t)
-
-	// Clean temporaries from condition at
-	// beginning of both branches.
-	case OIF:
-		t := o.markTemp()
-		n.Left = o.exprInPlace(n.Left)
-		n.Nbody.Prepend(o.cleanTempNoPop(t)...)
-		n.Rlist.Prepend(o.cleanTempNoPop(t)...)
-		o.popTemp(t)
-		orderBlock(&n.Nbody, o.free)
-		orderBlock(&n.Rlist, o.free)
-		o.out = append(o.out, n)
-
-	// Special: argument will be converted to interface using convT2E
-	// so make sure it is an addressable temporary.
-	case OPANIC:
-		t := o.markTemp()
-		n.Left = o.expr(n.Left, nil)
-		if !n.Left.Type.IsInterface() {
-			n.Left = o.addrTemp(n.Left)
-		}
-		o.out = append(o.out, n)
-		o.cleanTemp(t)
-
-	case ORANGE:
-		// n.Right is the expression being ranged over.
-		// order it, and then make a copy if we need one.
-		// We almost always do, to ensure that we don't
-		// see any value changes made during the loop.
-		// Usually the copy is cheap (e.g., array pointer,
-		// chan, slice, string are all tiny).
-		// The exception is ranging over an array value
-		// (not a slice, not a pointer to array),
-		// which must make a copy to avoid seeing updates made during
-		// the range body. Ranging over an array value is uncommon though.
-
-		// Mark []byte(str) range expression to reuse string backing storage.
-		// It is safe because the storage cannot be mutated.
-		if n.Right.Op == OSTR2BYTES {
-			n.Right.Op = OSTR2BYTESTMP
-		}
-
-		t := o.markTemp()
-		n.Right = o.expr(n.Right, nil)
-
-		orderBody := true
-		switch n.Type.Etype {
-		default:
-			Fatalf("order.stmt range %v", n.Type)
-
-		case TARRAY, TSLICE:
-			if n.List.Len() < 2 || n.List.Second().isBlank() {
-				// for i := range x will only use x once, to compute len(x).
-				// No need to copy it.
-				break
-			}
-			fallthrough
-
-		case TCHAN, TSTRING:
-			// chan, string, slice, array ranges use value multiple times.
-			// make copy.
-			r := n.Right
-
-			if r.Type.IsString() && r.Type != types.Types[TSTRING] {
-				r = nod(OCONV, r, nil)
-				r.Type = types.Types[TSTRING]
-				r = typecheck(r, ctxExpr)
-			}
-
-			n.Right = o.copyExpr(r, r.Type, false)
-
-		case TMAP:
-			if isMapClear(n) {
-				// Preserve the body of the map clear pattern so it can
-				// be detected during walk. The loop body will not be used
-				// when optimizing away the range loop to a runtime call.
-				orderBody = false
-				break
-			}
-
-			// copy the map value in case it is a map literal.
-			// TODO(rsc): Make tmp = literal expressions reuse tmp.
-			// For maps tmp is just one word so it hardly matters.
-			r := n.Right
-			n.Right = o.copyExpr(r, r.Type, false)
-
-			// prealloc[n] is the temp for the iterator.
-			// hiter contains pointers and needs to be zeroed.
-			prealloc[n] = o.newTemp(hiter(n.Type), true)
-		}
-		o.exprListInPlace(n.List)
-		if orderBody {
-			orderBlock(&n.Nbody, o.free)
-		}
-		o.out = append(o.out, n)
-		o.cleanTemp(t)
-
-	case ORETURN:
-		o.exprList(n.List)
-		o.out = append(o.out, n)
-
-	// Special: clean case temporaries in each block entry.
-	// Select must enter one of its blocks, so there is no
-	// need for a cleaning at the end.
-	// Doubly special: evaluation order for select is stricter
-	// than ordinary expressions. Even something like p.c
-	// has to be hoisted into a temporary, so that it cannot be
-	// reordered after the channel evaluation for a different
-	// case (if p were nil, then the timing of the fault would
-	// give this away).
-	case OSELECT:
-		t := o.markTemp()
-
-		for _, n2 := range n.List.Slice() {
-			if n2.Op != OCASE {
-				Fatalf("order select case %v", n2.Op)
-			}
-			r := n2.Left
-			setlineno(n2)
-
-			// Append any new body prologue to ninit.
-			// The next loop will insert ninit into nbody.
-			if n2.Ninit.Len() != 0 {
-				Fatalf("order select ninit")
-			}
-			if r == nil {
-				continue
-			}
-			switch r.Op {
-			default:
-				Dump("select case", r)
-				Fatalf("unknown op in select %v", r.Op)
-
-			// If this is case x := <-ch or case x, y := <-ch, the case has
-			// the ODCL nodes to declare x and y. We want to delay that
-			// declaration (and possible allocation) until inside the case body.
-			// Delete the ODCL nodes here and recreate them inside the body below.
-			case OSELRECV, OSELRECV2:
-				if r.Colas() {
-					i := 0
-					if r.Ninit.Len() != 0 && r.Ninit.First().Op == ODCL && r.Ninit.First().Left == r.Left {
-						i++
-					}
-					if i < r.Ninit.Len() && r.Ninit.Index(i).Op == ODCL && r.List.Len() != 0 && r.Ninit.Index(i).Left == r.List.First() {
-						i++
-					}
-					if i >= r.Ninit.Len() {
-						r.Ninit.Set(nil)
-					}
-				}
-
-				if r.Ninit.Len() != 0 {
-					dumplist("ninit", r.Ninit)
-					Fatalf("ninit on select recv")
-				}
-
-				// case x = <-c
-				// case x, ok = <-c
-				// r->left is x, r->ntest is ok, r->right is ORECV, r->right->left is c.
-				// r->left == N means 'case <-c'.
-				// c is always evaluated; x and ok are only evaluated when assigned.
-				r.Right.Left = o.expr(r.Right.Left, nil)
-
-				if !r.Right.Left.IsAutoTmp() {
-					r.Right.Left = o.copyExpr(r.Right.Left, r.Right.Left.Type, false)
-				}
-
-				// Introduce temporary for receive and move actual copy into case body.
-				// avoids problems with target being addressed, as usual.
-				// NOTE: If we wanted to be clever, we could arrange for just one
-				// temporary per distinct type, sharing the temp among all receives
-				// with that temp. Similarly one ok bool could be shared among all
-				// the x,ok receives. Not worth doing until there's a clear need.
-				if r.Left != nil && r.Left.isBlank() {
-					r.Left = nil
-				}
-				if r.Left != nil {
-					// 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
-
-					if r.Colas() {
-						tmp2 := nod(ODCL, tmp1, nil)
-						tmp2 = typecheck(tmp2, ctxStmt)
-						n2.Ninit.Append(tmp2)
-					}
-
-					r.Left = o.newTemp(r.Right.Left.Type.Elem(), r.Right.Left.Type.Elem().HasPointers())
-					tmp2 := nod(OAS, tmp1, r.Left)
-					tmp2 = typecheck(tmp2, ctxStmt)
-					n2.Ninit.Append(tmp2)
-				}
-
-				if r.List.Len() != 0 && r.List.First().isBlank() {
-					r.List.Set(nil)
-				}
-				if r.List.Len() != 0 {
-					tmp1 := r.List.First()
-					if r.Colas() {
-						tmp2 := nod(ODCL, tmp1, nil)
-						tmp2 = typecheck(tmp2, ctxStmt)
-						n2.Ninit.Append(tmp2)
-					}
-
-					r.List.Set1(o.newTemp(types.Types[TBOOL], false))
-					tmp2 := okas(tmp1, r.List.First())
-					tmp2 = typecheck(tmp2, ctxStmt)
-					n2.Ninit.Append(tmp2)
-				}
-				orderBlock(&n2.Ninit, o.free)
-
-			case OSEND:
-				if r.Ninit.Len() != 0 {
-					dumplist("ninit", r.Ninit)
-					Fatalf("ninit on select send")
-				}
-
-				// case c <- x
-				// r->left is c, r->right is x, both are always evaluated.
-				r.Left = o.expr(r.Left, nil)
-
-				if !r.Left.IsAutoTmp() {
-					r.Left = o.copyExpr(r.Left, r.Left.Type, false)
-				}
-				r.Right = o.expr(r.Right, nil)
-				if !r.Right.IsAutoTmp() {
-					r.Right = o.copyExpr(r.Right, r.Right.Type, false)
-				}
-			}
-		}
-		// Now that we have accumulated all the temporaries, clean them.
-		// Also insert any ninit queued during the previous loop.
-		// (The temporary cleaning must follow that ninit work.)
-		for _, n3 := range n.List.Slice() {
-			orderBlock(&n3.Nbody, o.free)
-			n3.Nbody.Prepend(o.cleanTempNoPop(t)...)
-
-			// TODO(mdempsky): Is this actually necessary?
-			// walkselect appears to walk Ninit.
-			n3.Nbody.Prepend(n3.Ninit.Slice()...)
-			n3.Ninit.Set(nil)
-		}
-
-		o.out = append(o.out, n)
-		o.popTemp(t)
-
-	// Special: value being sent is passed as a pointer; make it addressable.
-	case OSEND:
-		t := o.markTemp()
-		n.Left = o.expr(n.Left, nil)
-		n.Right = o.expr(n.Right, nil)
-		if instrumenting {
-			// Force copying to the stack so that (chan T)(nil) <- x
-			// is still instrumented as a read of x.
-			n.Right = o.copyExpr(n.Right, n.Right.Type, false)
-		} else {
-			n.Right = o.addrTemp(n.Right)
-		}
-		o.out = append(o.out, n)
-		o.cleanTemp(t)
-
-	// TODO(rsc): Clean temporaries more aggressively.
-	// Note that because walkswitch will rewrite some of the
-	// switch into a binary search, this is not as easy as it looks.
-	// (If we ran that code here we could invoke order.stmt on
-	// the if-else chain instead.)
-	// For now just clean all the temporaries at the end.
-	// In practice that's fine.
-	case OSWITCH:
-		if Debug_libfuzzer != 0 && !hasDefaultCase(n) {
-			// Add empty "default:" case for instrumentation.
-			n.List.Append(nod(OCASE, nil, nil))
-		}
-
-		t := o.markTemp()
-		n.Left = o.expr(n.Left, nil)
-		for _, ncas := range n.List.Slice() {
-			if ncas.Op != OCASE {
-				Fatalf("order switch case %v", ncas.Op)
-			}
-			o.exprListInPlace(ncas.List)
-			orderBlock(&ncas.Nbody, o.free)
-		}
-
-		o.out = append(o.out, n)
-		o.cleanTemp(t)
-	}
-
-	lineno = lno
-}
-
-func hasDefaultCase(n *Node) bool {
-	for _, ncas := range n.List.Slice() {
-		if ncas.Op != OCASE {
-			Fatalf("expected case, found %v", ncas.Op)
-		}
-		if ncas.List.Len() == 0 {
-			return true
-		}
-	}
-	return false
-}
-
-// exprList orders the expression list l into o.
-func (o *Order) exprList(l Nodes) {
-	s := l.Slice()
-	for i := range s {
-		s[i] = o.expr(s[i], nil)
-	}
-}
-
-// exprListInPlace orders the expression list l but saves
-// the side effects on the individual expression ninit lists.
-func (o *Order) exprListInPlace(l Nodes) {
-	s := l.Slice()
-	for i := range s {
-		s[i] = o.exprInPlace(s[i])
-	}
-}
-
-// prealloc[x] records the allocation to use for x.
-var prealloc = map[*Node]*Node{}
-
-// expr orders a single expression, appending side
-// effects to o.out as needed.
-// If this is part of an assignment lhs = *np, lhs is given.
-// Otherwise lhs == nil. (When lhs != nil it may be possible
-// to avoid copying the result of the expression to a temporary.)
-// The result of expr MUST be assigned back to n, e.g.
-// 	n.Left = o.expr(n.Left, lhs)
-func (o *Order) expr(n, lhs *Node) *Node {
-	if n == nil {
-		return n
-	}
-
-	lno := setlineno(n)
-	o.init(n)
-
-	switch n.Op {
-	default:
-		n.Left = o.expr(n.Left, nil)
-		n.Right = o.expr(n.Right, nil)
-		o.exprList(n.List)
-		o.exprList(n.Rlist)
-
-	// Addition of strings turns into a function call.
-	// Allocate a temporary to hold the strings.
-	// Fewer than 5 strings use direct runtime helpers.
-	case OADDSTR:
-		o.exprList(n.List)
-
-		if n.List.Len() > 5 {
-			t := types.NewArray(types.Types[TSTRING], int64(n.List.Len()))
-			prealloc[n] = o.newTemp(t, false)
-		}
-
-		// Mark string(byteSlice) arguments to reuse byteSlice backing
-		// buffer during conversion. String concatenation does not
-		// memorize the strings for later use, so it is safe.
-		// However, we can do it only if there is at least one non-empty string literal.
-		// Otherwise if all other arguments are empty strings,
-		// concatstrings will return the reference to the temp string
-		// to the caller.
-		hasbyte := false
-
-		haslit := false
-		for _, n1 := range n.List.Slice() {
-			hasbyte = hasbyte || n1.Op == OBYTES2STR
-			haslit = haslit || n1.Op == OLITERAL && len(n1.StringVal()) != 0
-		}
-
-		if haslit && hasbyte {
-			for _, n2 := range n.List.Slice() {
-				if n2.Op == OBYTES2STR {
-					n2.Op = OBYTES2STRTMP
-				}
-			}
-		}
-
-	case OINDEXMAP:
-		n.Left = o.expr(n.Left, nil)
-		n.Right = o.expr(n.Right, nil)
-		needCopy := false
-
-		if !n.IndexMapLValue() {
-			// Enforce that any []byte slices we are not copying
-			// can not be changed before the map index by forcing
-			// the map index to happen immediately following the
-			// conversions. See copyExpr a few lines below.
-			needCopy = mapKeyReplaceStrConv(n.Right)
-
-			if instrumenting {
-				// Race detector needs the copy so it can
-				// call treecopy on the result.
-				needCopy = true
-			}
-		}
-
-		// key must be addressable
-		n.Right = o.mapKeyTemp(n.Left.Type, n.Right)
-		if needCopy {
-			n = o.copyExpr(n, n.Type, false)
-		}
-
-	// concrete type (not interface) argument might need an addressable
-	// temporary to pass to the runtime conversion routine.
-	case OCONVIFACE:
-		n.Left = o.expr(n.Left, nil)
-		if n.Left.Type.IsInterface() {
-			break
-		}
-		if _, needsaddr := convFuncName(n.Left.Type, n.Type); needsaddr || isStaticCompositeLiteral(n.Left) {
-			// Need a temp if we need to pass the address to the conversion function.
-			// We also process static composite literal node here, making a named static global
-			// whose address we can put directly in an interface (see OCONVIFACE case in walk).
-			n.Left = o.addrTemp(n.Left)
-		}
-
-	case OCONVNOP:
-		if n.Type.IsKind(TUNSAFEPTR) && n.Left.Type.IsKind(TUINTPTR) && (n.Left.Op == OCALLFUNC || n.Left.Op == OCALLINTER || n.Left.Op == OCALLMETH) {
-			// When reordering unsafe.Pointer(f()) into a separate
-			// statement, the conversion and function call must stay
-			// together. See golang.org/issue/15329.
-			o.init(n.Left)
-			o.call(n.Left)
-			if lhs == nil || lhs.Op != ONAME || instrumenting {
-				n = o.copyExpr(n, n.Type, false)
-			}
-		} else {
-			n.Left = o.expr(n.Left, nil)
-		}
-
-	case OANDAND, OOROR:
-		// ... = LHS && RHS
-		//
-		// var r bool
-		// r = LHS
-		// if r {       // or !r, for OROR
-		//     r = RHS
-		// }
-		// ... = r
-
-		r := o.newTemp(n.Type, false)
-
-		// Evaluate left-hand side.
-		lhs := o.expr(n.Left, nil)
-		o.out = append(o.out, typecheck(nod(OAS, r, lhs), ctxStmt))
-
-		// Evaluate right-hand side, save generated code.
-		saveout := o.out
-		o.out = nil
-		t := o.markTemp()
-		o.edge()
-		rhs := o.expr(n.Right, nil)
-		o.out = append(o.out, typecheck(nod(OAS, r, rhs), ctxStmt))
-		o.cleanTemp(t)
-		gen := o.out
-		o.out = saveout
-
-		// If left-hand side doesn't cause a short-circuit, issue right-hand side.
-		nif := nod(OIF, r, nil)
-		if n.Op == OANDAND {
-			nif.Nbody.Set(gen)
-		} else {
-			nif.Rlist.Set(gen)
-		}
-		o.out = append(o.out, nif)
-		n = r
-
-	case OCALLFUNC,
-		OCALLINTER,
-		OCALLMETH,
-		OCAP,
-		OCOMPLEX,
-		OCOPY,
-		OIMAG,
-		OLEN,
-		OMAKECHAN,
-		OMAKEMAP,
-		OMAKESLICE,
-		OMAKESLICECOPY,
-		ONEW,
-		OREAL,
-		ORECOVER,
-		OSTR2BYTES,
-		OSTR2BYTESTMP,
-		OSTR2RUNES:
-
-		if isRuneCount(n) {
-			// len([]rune(s)) is rewritten to runtime.countrunes(s) later.
-			n.Left.Left = o.expr(n.Left.Left, nil)
-		} else {
-			o.call(n)
-		}
-
-		if lhs == nil || lhs.Op != ONAME || instrumenting {
-			n = o.copyExpr(n, n.Type, false)
-		}
-
-	case OAPPEND:
-		// Check for append(x, make([]T, y)...) .
-		if isAppendOfMake(n) {
-			n.List.SetFirst(o.expr(n.List.First(), nil))             // order x
-			n.List.Second().Left = o.expr(n.List.Second().Left, nil) // order y
-		} else {
-			o.exprList(n.List)
-		}
-
-		if lhs == nil || lhs.Op != ONAME && !samesafeexpr(lhs, n.List.First()) {
-			n = o.copyExpr(n, n.Type, false)
-		}
-
-	case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR:
-		n.Left = o.expr(n.Left, nil)
-		low, high, max := n.SliceBounds()
-		low = o.expr(low, nil)
-		low = o.cheapExpr(low)
-		high = o.expr(high, nil)
-		high = o.cheapExpr(high)
-		max = o.expr(max, nil)
-		max = o.cheapExpr(max)
-		n.SetSliceBounds(low, high, max)
-		if lhs == nil || lhs.Op != ONAME && !samesafeexpr(lhs, n.Left) {
-			n = o.copyExpr(n, n.Type, false)
-		}
-
-	case OCLOSURE:
-		if n.Transient() && n.Func.Closure.Func.Cvars.Len() > 0 {
-			prealloc[n] = o.newTemp(closureType(n), false)
-		}
-
-	case OSLICELIT, OCALLPART:
-		n.Left = o.expr(n.Left, nil)
-		n.Right = o.expr(n.Right, nil)
-		o.exprList(n.List)
-		o.exprList(n.Rlist)
-		if n.Transient() {
-			var t *types.Type
-			switch n.Op {
-			case OSLICELIT:
-				t = types.NewArray(n.Type.Elem(), n.Right.Int64Val())
-			case OCALLPART:
-				t = partialCallType(n)
-			}
-			prealloc[n] = o.newTemp(t, false)
-		}
-
-	case ODOTTYPE, ODOTTYPE2:
-		n.Left = o.expr(n.Left, nil)
-		if !isdirectiface(n.Type) || instrumenting {
-			n = o.copyExpr(n, n.Type, true)
-		}
-
-	case ORECV:
-		n.Left = o.expr(n.Left, nil)
-		n = o.copyExpr(n, n.Type, true)
-
-	case OEQ, ONE, OLT, OLE, OGT, OGE:
-		n.Left = o.expr(n.Left, nil)
-		n.Right = o.expr(n.Right, nil)
-
-		t := n.Left.Type
-		switch {
-		case t.IsString():
-			// Mark string(byteSlice) arguments to reuse byteSlice backing
-			// buffer during conversion. String comparison does not
-			// memorize the strings for later use, so it is safe.
-			if n.Left.Op == OBYTES2STR {
-				n.Left.Op = OBYTES2STRTMP
-			}
-			if n.Right.Op == OBYTES2STR {
-				n.Right.Op = OBYTES2STRTMP
-			}
-
-		case t.IsStruct() || t.IsArray():
-			// for complex comparisons, we need both args to be
-			// addressable so we can pass them to the runtime.
-			n.Left = o.addrTemp(n.Left)
-			n.Right = o.addrTemp(n.Right)
-		}
-	case OMAPLIT:
-		// Order map by converting:
-		//   map[int]int{
-		//     a(): b(),
-		//     c(): d(),
-		//     e(): f(),
-		//   }
-		// to
-		//   m := map[int]int{}
-		//   m[a()] = b()
-		//   m[c()] = d()
-		//   m[e()] = f()
-		// Then order the result.
-		// Without this special case, order would otherwise compute all
-		// the keys and values before storing any of them to the map.
-		// See issue 26552.
-		entries := n.List.Slice()
-		statics := entries[:0]
-		var dynamics []*Node
-		for _, r := range entries {
-			if r.Op != OKEY {
-				Fatalf("OMAPLIT entry not OKEY: %v\n", r)
-			}
-
-			if !isStaticCompositeLiteral(r.Left) || !isStaticCompositeLiteral(r.Right) {
-				dynamics = append(dynamics, r)
-				continue
-			}
-
-			// Recursively ordering some static entries can change them to dynamic;
-			// e.g., OCONVIFACE nodes. See #31777.
-			r = o.expr(r, nil)
-			if !isStaticCompositeLiteral(r.Left) || !isStaticCompositeLiteral(r.Right) {
-				dynamics = append(dynamics, r)
-				continue
-			}
-
-			statics = append(statics, r)
-		}
-		n.List.Set(statics)
-
-		if len(dynamics) == 0 {
-			break
-		}
-
-		// Emit the creation of the map (with all its static entries).
-		m := o.newTemp(n.Type, false)
-		as := nod(OAS, m, n)
-		typecheck(as, ctxStmt)
-		o.stmt(as)
-		n = m
-
-		// Emit eval+insert of dynamic entries, one at a time.
-		for _, r := range dynamics {
-			as := nod(OAS, nod(OINDEX, n, r.Left), r.Right)
-			typecheck(as, ctxStmt) // Note: this converts the OINDEX to an OINDEXMAP
-			o.stmt(as)
-		}
-	}
-
-	lineno = lno
-	return n
-}
-
-// okas creates and returns an assignment of val to ok,
-// including an explicit conversion if necessary.
-func okas(ok, val *Node) *Node {
-	if !ok.isBlank() {
-		val = conv(val, ok.Type)
-	}
-	return nod(OAS, ok, val)
-}
-
-// as2 orders OAS2XXXX nodes. It creates temporaries to ensure left-to-right assignment.
-// The caller should order the right-hand side of the assignment before calling order.as2.
-// It rewrites,
-// 	a, b, a = ...
-// as
-//	tmp1, tmp2, tmp3 = ...
-// 	a, b, a = tmp1, tmp2, tmp3
-// This is necessary to ensure left to right assignment order.
-func (o *Order) as2(n *Node) {
-	tmplist := []*Node{}
-	left := []*Node{}
-	for ni, l := range n.List.Slice() {
-		if !l.isBlank() {
-			tmp := o.newTemp(l.Type, l.Type.HasPointers())
-			n.List.SetIndex(ni, tmp)
-			tmplist = append(tmplist, tmp)
-			left = append(left, l)
-		}
-	}
-
-	o.out = append(o.out, n)
-
-	as := nod(OAS2, nil, nil)
-	as.List.Set(left)
-	as.Rlist.Set(tmplist)
-	as = typecheck(as, ctxStmt)
-	o.stmt(as)
-}
-
-// okAs2 orders OAS2XXX with ok.
-// Just like as2, this also adds temporaries to ensure left-to-right assignment.
-func (o *Order) okAs2(n *Node) {
-	var tmp1, tmp2 *Node
-	if !n.List.First().isBlank() {
-		typ := n.Right.Type
-		tmp1 = o.newTemp(typ, typ.HasPointers())
-	}
-
-	if !n.List.Second().isBlank() {
-		tmp2 = o.newTemp(types.Types[TBOOL], false)
-	}
-
-	o.out = append(o.out, n)
-
-	if tmp1 != nil {
-		r := nod(OAS, n.List.First(), tmp1)
-		r = typecheck(r, ctxStmt)
-		o.mapAssign(r)
-		n.List.SetFirst(tmp1)
-	}
-	if tmp2 != nil {
-		r := okas(n.List.Second(), tmp2)
-		r = typecheck(r, ctxStmt)
-		o.mapAssign(r)
-		n.List.SetSecond(tmp2)
-	}
-}
diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go
deleted file mode 100644
index 353f4b0..0000000
--- a/src/cmd/compile/internal/gc/pgen.go
+++ /dev/null
@@ -1,798 +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
-
-import (
-	"cmd/compile/internal/ssa"
-	"cmd/compile/internal/types"
-	"cmd/internal/dwarf"
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"cmd/internal/src"
-	"cmd/internal/sys"
-	"internal/race"
-	"math/rand"
-	"sort"
-	"sync"
-	"time"
-)
-
-// "Portable" code generation.
-
-var (
-	nBackendWorkers int     // number of concurrent backend workers, set by a compiler flag
-	compilequeue    []*Node // functions waiting to be compiled
-)
-
-func emitptrargsmap(fn *Node) {
-	if fn.funcname() == "_" || fn.Func.Nname.Sym.Linkname != "" {
-		return
-	}
-	lsym := Ctxt.Lookup(fn.Func.lsym.Name + ".args_stackmap")
-
-	nptr := int(fn.Type.ArgWidth() / int64(Widthptr))
-	bv := bvalloc(int32(nptr) * 2)
-	nbitmap := 1
-	if fn.Type.NumResults() > 0 {
-		nbitmap = 2
-	}
-	off := duint32(lsym, 0, uint32(nbitmap))
-	off = duint32(lsym, off, uint32(bv.n))
-
-	if fn.IsMethod() {
-		onebitwalktype1(fn.Type.Recvs(), 0, bv)
-	}
-	if fn.Type.NumParams() > 0 {
-		onebitwalktype1(fn.Type.Params(), 0, bv)
-	}
-	off = dbvec(lsym, off, bv)
-
-	if fn.Type.NumResults() > 0 {
-		onebitwalktype1(fn.Type.Results(), 0, bv)
-		off = dbvec(lsym, off, bv)
-	}
-
-	ggloblsym(lsym, int32(off), obj.RODATA|obj.LOCAL)
-}
-
-// cmpstackvarlt reports whether the stack variable a sorts before b.
-//
-// Sort the list of stack variables. Autos after anything else,
-// within autos, unused after used, within used, things with
-// pointers first, zeroed things first, and then decreasing size.
-// Because autos are laid out in decreasing addresses
-// on the stack, pointers first, zeroed things first and decreasing size
-// really means, in memory, things with pointers needing zeroing at
-// the top of the stack and increasing in size.
-// Non-autos sort on offset.
-func cmpstackvarlt(a, b *Node) bool {
-	if (a.Class() == PAUTO) != (b.Class() == PAUTO) {
-		return b.Class() == PAUTO
-	}
-
-	if a.Class() != PAUTO {
-		return a.Xoffset < b.Xoffset
-	}
-
-	if a.Name.Used() != b.Name.Used() {
-		return a.Name.Used()
-	}
-
-	ap := a.Type.HasPointers()
-	bp := b.Type.HasPointers()
-	if ap != bp {
-		return ap
-	}
-
-	ap = a.Name.Needzero()
-	bp = b.Name.Needzero()
-	if ap != bp {
-		return ap
-	}
-
-	if a.Type.Width != b.Type.Width {
-		return a.Type.Width > b.Type.Width
-	}
-
-	return a.Sym.Name < b.Sym.Name
-}
-
-// byStackvar implements sort.Interface for []*Node using cmpstackvarlt.
-type byStackVar []*Node
-
-func (s byStackVar) Len() int           { return len(s) }
-func (s byStackVar) Less(i, j int) bool { return cmpstackvarlt(s[i], s[j]) }
-func (s byStackVar) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-
-func (s *ssafn) AllocFrame(f *ssa.Func) {
-	s.stksize = 0
-	s.stkptrsize = 0
-	fn := s.curfn.Func
-
-	// Mark the PAUTO's unused.
-	for _, ln := range fn.Dcl {
-		if ln.Class() == PAUTO {
-			ln.Name.SetUsed(false)
-		}
-	}
-
-	for _, l := range f.RegAlloc {
-		if ls, ok := l.(ssa.LocalSlot); ok {
-			ls.N.(*Node).Name.SetUsed(true)
-		}
-	}
-
-	scratchUsed := false
-	for _, b := range f.Blocks {
-		for _, v := range b.Values {
-			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)
-				}
-			}
-			if !scratchUsed {
-				scratchUsed = v.Op.UsesScratch()
-			}
-
-		}
-	}
-
-	if f.Config.NeedsFpScratch && scratchUsed {
-		s.scratchFpMem = tempAt(src.NoXPos, s.curfn, types.Types[TUINT64])
-	}
-
-	sort.Sort(byStackVar(fn.Dcl))
-
-	// Reassign stack offsets of the locals that are used.
-	lastHasPtr := false
-	for i, n := range fn.Dcl {
-		if n.Op != ONAME || n.Class() != PAUTO {
-			continue
-		}
-		if !n.Name.Used() {
-			fn.Dcl = fn.Dcl[:i]
-			break
-		}
-
-		dowidth(n.Type)
-		w := n.Type.Width
-		if w >= thearch.MAXWIDTH || w < 0 {
-			Fatalf("bad width")
-		}
-		if w == 0 && lastHasPtr {
-			// Pad between a pointer-containing object and a zero-sized object.
-			// This prevents a pointer to the zero-sized object from being interpreted
-			// as a pointer to the pointer-containing object (and causing it
-			// to be scanned when it shouldn't be). See issue 24993.
-			w = 1
-		}
-		s.stksize += w
-		s.stksize = Rnd(s.stksize, int64(n.Type.Align))
-		if n.Type.HasPointers() {
-			s.stkptrsize = s.stksize
-			lastHasPtr = true
-		} else {
-			lastHasPtr = false
-		}
-		if thearch.LinkArch.InFamily(sys.MIPS, sys.MIPS64, sys.ARM, sys.ARM64, sys.PPC64, sys.S390X) {
-			s.stksize = Rnd(s.stksize, int64(Widthptr))
-		}
-		n.Xoffset = -s.stksize
-	}
-
-	s.stksize = Rnd(s.stksize, int64(Widthreg))
-	s.stkptrsize = Rnd(s.stkptrsize, int64(Widthreg))
-}
-
-func funccompile(fn *Node) {
-	if Curfn != nil {
-		Fatalf("funccompile %v inside %v", fn.Func.Nname.Sym, Curfn.Func.Nname.Sym)
-	}
-
-	if fn.Type == nil {
-		if nerrors == 0 {
-			Fatalf("funccompile missing type")
-		}
-		return
-	}
-
-	// assign parameter offsets
-	dowidth(fn.Type)
-
-	if fn.Nbody.Len() == 0 {
-		// Initialize ABI wrappers if necessary.
-		fn.Func.initLSym(false)
-		emitptrargsmap(fn)
-		return
-	}
-
-	dclcontext = PAUTO
-	Curfn = fn
-
-	compile(fn)
-
-	Curfn = nil
-	dclcontext = PEXTERN
-}
-
-func compile(fn *Node) {
-	saveerrors()
-
-	order(fn)
-	if nerrors != 0 {
-		return
-	}
-
-	// Set up the function's LSym early to avoid data races with the assemblers.
-	// Do this before walk, as walk needs the LSym to set attributes/relocations
-	// (e.g. in markTypeUsedInInterface).
-	fn.Func.initLSym(true)
-
-	walk(fn)
-	if nerrors != 0 {
-		return
-	}
-	if instrumenting {
-		instrument(fn)
-	}
-
-	// From this point, there should be no uses of Curfn. Enforce that.
-	Curfn = nil
-
-	if fn.funcname() == "_" {
-		// We don't need to generate code for this function, just report errors in its body.
-		// At this point we've generated any errors needed.
-		// (Beyond here we generate only non-spec errors, like "stack frame too large".)
-		// See issue 29870.
-		return
-	}
-
-	// Make sure type syms are declared for all types that might
-	// be types of stack objects. We need to do this here
-	// because symbols must be allocated before the parallel
-	// phase of the compiler.
-	for _, n := range fn.Func.Dcl {
-		switch n.Class() {
-		case PPARAM, PPARAMOUT, PAUTO:
-			if livenessShouldTrack(n) && n.Name.Addrtaken() {
-				dtypesym(n.Type)
-				// Also make sure we allocate a linker symbol
-				// for the stack object data, for the same reason.
-				if fn.Func.lsym.Func().StackObjects == nil {
-					fn.Func.lsym.Func().StackObjects = Ctxt.Lookup(fn.Func.lsym.Name + ".stkobj")
-				}
-			}
-		}
-	}
-
-	if compilenow(fn) {
-		compileSSA(fn, 0)
-	} else {
-		compilequeue = append(compilequeue, fn)
-	}
-}
-
-// compilenow reports whether to compile immediately.
-// If functions are not compiled immediately,
-// they are enqueued in compilequeue,
-// which is drained by compileFunctions.
-func compilenow(fn *Node) bool {
-	// Issue 38068: if this function is a method AND an inline
-	// candidate AND was not inlined (yet), put it onto the compile
-	// queue instead of compiling it immediately. This is in case we
-	// wind up inlining it into a method wrapper that is generated by
-	// compiling a function later on in the xtop list.
-	if fn.IsMethod() && isInlinableButNotInlined(fn) {
-		return false
-	}
-	return nBackendWorkers == 1 && Debug_compilelater == 0
-}
-
-// isInlinableButNotInlined returns true if 'fn' was marked as an
-// inline candidate but then never inlined (presumably because we
-// found no call sites).
-func isInlinableButNotInlined(fn *Node) bool {
-	if fn.Func.Nname.Func.Inl == nil {
-		return false
-	}
-	if fn.Sym == nil {
-		return true
-	}
-	return !fn.Sym.Linksym().WasInlined()
-}
-
-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) {
-	f := buildssa(fn, worker)
-	// Note: check arg size to fix issue 25507.
-	if f.Frontend().(*ssafn).stksize >= maxStackSize || fn.Type.ArgWidth() >= maxStackSize {
-		largeStackFramesMu.Lock()
-		largeStackFrames = append(largeStackFrames, largeStack{locals: f.Frontend().(*ssafn).stksize, args: fn.Type.ArgWidth(), pos: fn.Pos})
-		largeStackFramesMu.Unlock()
-		return
-	}
-	pp := newProgs(fn, worker)
-	defer pp.Free()
-	genssa(f, pp)
-	// Check frame size again.
-	// The check above included only the space needed for local variables.
-	// After genssa, the space needed includes local variables and the callee arg region.
-	// We must do this check prior to calling pp.Flush.
-	// If there are any oversized stack frames,
-	// the assembler may emit inscrutable complaints about invalid instructions.
-	if pp.Text.To.Offset >= maxStackSize {
-		largeStackFramesMu.Lock()
-		locals := f.Frontend().(*ssafn).stksize
-		largeStackFrames = append(largeStackFrames, largeStack{locals: locals, args: fn.Type.ArgWidth(), callee: pp.Text.To.Offset - locals, pos: fn.Pos})
-		largeStackFramesMu.Unlock()
-		return
-	}
-
-	pp.Flush() // assemble, fill in boilerplate, etc.
-	// fieldtrack must be called after pp.Flush. See issue 20014.
-	fieldtrack(pp.Text.From.Sym, fn.Func.FieldTrack)
-}
-
-func init() {
-	if race.Enabled {
-		rand.Seed(time.Now().UnixNano())
-	}
-}
-
-// compileFunctions compiles all functions in compilequeue.
-// It fans out nBackendWorkers to do the work
-// and waits for them to complete.
-func compileFunctions() {
-	if len(compilequeue) != 0 {
-		sizeCalculationDisabled = true // not safe to calculate sizes concurrently
-		if race.Enabled {
-			// Randomize compilation order to try to shake out races.
-			tmp := make([]*Node, len(compilequeue))
-			perm := rand.Perm(len(compilequeue))
-			for i, v := range perm {
-				tmp[v] = compilequeue[i]
-			}
-			copy(compilequeue, tmp)
-		} else {
-			// Compile the longest functions first,
-			// since they're most likely to be the slowest.
-			// This helps avoid stragglers.
-			sort.Slice(compilequeue, func(i, j int) bool {
-				return compilequeue[i].Nbody.Len() > compilequeue[j].Nbody.Len()
-			})
-		}
-		var wg sync.WaitGroup
-		Ctxt.InParallel = true
-		c := make(chan *Node, nBackendWorkers)
-		for i := 0; i < nBackendWorkers; i++ {
-			wg.Add(1)
-			go func(worker int) {
-				for fn := range c {
-					compileSSA(fn, worker)
-				}
-				wg.Done()
-			}(i)
-		}
-		for _, fn := range compilequeue {
-			c <- fn
-		}
-		close(c)
-		compilequeue = nil
-		wg.Wait()
-		Ctxt.InParallel = false
-		sizeCalculationDisabled = false
-	}
-}
-
-func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls) {
-	fn := curfn.(*Node)
-	if fn.Func.Nname != nil {
-		if expect := fn.Func.Nname.Sym.Linksym(); fnsym != expect {
-			Fatalf("unexpected fnsym: %v != %v", fnsym, expect)
-		}
-	}
-
-	var apdecls []*Node
-	// Populate decls for fn.
-	for _, n := range fn.Func.Dcl {
-		if n.Op != ONAME { // might be OTYPE or OLITERAL
-			continue
-		}
-		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
-			}
-		case PPARAM, PPARAMOUT:
-		default:
-			continue
-		}
-		apdecls = append(apdecls, n)
-		fnsym.Func().RecordAutoType(ngotype(n).Linksym())
-	}
-
-	decls, dwarfVars := createDwarfVars(fnsym, fn.Func, apdecls)
-
-	// For each type referenced by the functions auto vars but not
-	// already referenced by a dwarf var, attach a dummy relocation to
-	// the function symbol to insure that the type included in DWARF
-	// processing during linking.
-	typesyms := []*obj.LSym{}
-	for t, _ := range fnsym.Func().Autot {
-		typesyms = append(typesyms, t)
-	}
-	sort.Sort(obj.BySymName(typesyms))
-	for _, sym := range typesyms {
-		r := obj.Addrel(infosym)
-		r.Sym = sym
-		r.Type = objabi.R_USETYPE
-	}
-	fnsym.Func().Autot = nil
-
-	var varScopes []ScopeID
-	for _, decl := range decls {
-		pos := declPos(decl)
-		varScopes = append(varScopes, findScope(fn.Func.Marks, pos))
-	}
-
-	scopes := assembleScopes(fnsym, fn, dwarfVars, varScopes)
-	var inlcalls dwarf.InlCalls
-	if genDwarfInline > 0 {
-		inlcalls = assembleInlines(fnsym, dwarfVars)
-	}
-	return scopes, inlcalls
-}
-
-func declPos(decl *Node) src.XPos {
-	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.
-		return decl.Name.Defn.Pos
-	}
-	return decl.Pos
-}
-
-// createSimpleVars creates a DWARF entry for every variable declared in the
-// function, claiming that they are permanently on the stack.
-func createSimpleVars(fnsym *obj.LSym, apDecls []*Node) ([]*Node, []*dwarf.Var, map[*Node]bool) {
-	var vars []*dwarf.Var
-	var decls []*Node
-	selected := make(map[*Node]bool)
-	for _, n := range apDecls {
-		if n.IsAutoTmp() {
-			continue
-		}
-
-		decls = append(decls, n)
-		vars = append(vars, createSimpleVar(fnsym, n))
-		selected[n] = true
-	}
-	return decls, vars, selected
-}
-
-func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var {
-	var abbrev int
-	offs := n.Xoffset
-
-	switch n.Class() {
-	case PAUTO:
-		abbrev = dwarf.DW_ABRV_AUTO
-		if Ctxt.FixedFrameSize() == 0 {
-			offs -= int64(Widthptr)
-		}
-		if objabi.Framepointer_enabled || objabi.GOARCH == "arm64" {
-			// There is a word space for FP on ARM64 even if the frame pointer is disabled
-			offs -= int64(Widthptr)
-		}
-
-	case PPARAM, PPARAMOUT:
-		abbrev = dwarf.DW_ABRV_PARAM
-		offs += Ctxt.FixedFrameSize()
-	default:
-		Fatalf("createSimpleVar unexpected class %v for node %v", n.Class(), n)
-	}
-
-	typename := dwarf.InfoPrefix + typesymname(n.Type)
-	delete(fnsym.Func().Autot, ngotype(n).Linksym())
-	inlIndex := 0
-	if genDwarfInline > 1 {
-		if n.Name.InlFormal() || n.Name.InlLocal() {
-			inlIndex = posInlIndex(n.Pos) + 1
-			if n.Name.InlFormal() {
-				abbrev = dwarf.DW_ABRV_PARAM
-			}
-		}
-	}
-	declpos := Ctxt.InnermostPos(declPos(n))
-	return &dwarf.Var{
-		Name:          n.Sym.Name,
-		IsReturnValue: n.Class() == PPARAMOUT,
-		IsInlFormal:   n.Name.InlFormal(),
-		Abbrev:        abbrev,
-		StackOffset:   int32(offs),
-		Type:          Ctxt.Lookup(typename),
-		DeclFile:      declpos.RelFilename(),
-		DeclLine:      declpos.RelLine(),
-		DeclCol:       declpos.Col(),
-		InlIndex:      int32(inlIndex),
-		ChildIndex:    -1,
-	}
-}
-
-// createComplexVars creates recomposed DWARF vars with location lists,
-// suitable for describing optimized code.
-func createComplexVars(fnsym *obj.LSym, fn *Func) ([]*Node, []*dwarf.Var, map[*Node]bool) {
-	debugInfo := fn.DebugInfo
-
-	// Produce a DWARF variable entry for each user variable.
-	var decls []*Node
-	var vars []*dwarf.Var
-	ssaVars := make(map[*Node]bool)
-
-	for varID, dvar := range debugInfo.Vars {
-		n := dvar.(*Node)
-		ssaVars[n] = true
-		for _, slot := range debugInfo.VarSlots[varID] {
-			ssaVars[debugInfo.Slots[slot].N.(*Node)] = true
-		}
-
-		if dvar := createComplexVar(fnsym, fn, ssa.VarID(varID)); dvar != nil {
-			decls = append(decls, n)
-			vars = append(vars, dvar)
-		}
-	}
-
-	return decls, vars, ssaVars
-}
-
-// createDwarfVars process fn, returning a list of DWARF variables and the
-// Nodes they represent.
-func createDwarfVars(fnsym *obj.LSym, fn *Func, apDecls []*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 && fn.DebugInfo != nil {
-		decls, vars, selected = createComplexVars(fnsym, fn)
-	} else {
-		decls, vars, selected = createSimpleVars(fnsym, apDecls)
-	}
-
-	dcl := apDecls
-	if fnsym.WasInlined() {
-		dcl = preInliningDcls(fnsym)
-	}
-
-	// 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).  Input arguments not eligible
-	// for SSA optimization are also missing.  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 non-SSA-able arguments, however, the correct information
-	// is known -- they have a single home on the stack.
-	for _, n := range dcl {
-		if _, found := selected[n]; found {
-			continue
-		}
-		c := n.Sym.Name[0]
-		if c == '.' || n.Type.IsUntyped() {
-			continue
-		}
-		if n.Class() == PPARAM && !canSSAType(n.Type) {
-			// SSA-able args get location lists, and may move in and
-			// out of registers, so those are handled elsewhere.
-			// Autos and named output params seem to get handled
-			// with VARDEF, which creates location lists.
-			// Args not of SSA-able type are treated here; they
-			// are homed on the stack in a single place for the
-			// entire call.
-			vars = append(vars, createSimpleVar(fnsym, n))
-			decls = append(decls, n)
-			continue
-		}
-		typename := dwarf.InfoPrefix + typesymname(n.Type)
-		decls = append(decls, n)
-		abbrev := dwarf.DW_ABRV_AUTO_LOCLIST
-		isReturnValue := (n.Class() == PPARAMOUT)
-		if n.Class() == PPARAM || n.Class() == PPARAMOUT {
-			abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
-		} else if n.Class() == PAUTOHEAP {
-			// If dcl in question has been promoted to heap, do a bit
-			// of extra work to recover original class (auto or param);
-			// see issue 30908. This insures that we get the proper
-			// signature in the abstract function DIE, but leaves a
-			// misleading location for the param (we want pointer-to-heap
-			// and not stack).
-			// TODO(thanm): generate a better location expression
-			stackcopy := n.Name.Param.Stackcopy
-			if stackcopy != nil && (stackcopy.Class() == PPARAM || stackcopy.Class() == PPARAMOUT) {
-				abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
-				isReturnValue = (stackcopy.Class() == PPARAMOUT)
-			}
-		}
-		inlIndex := 0
-		if genDwarfInline > 1 {
-			if n.Name.InlFormal() || n.Name.InlLocal() {
-				inlIndex = posInlIndex(n.Pos) + 1
-				if n.Name.InlFormal() {
-					abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
-				}
-			}
-		}
-		declpos := Ctxt.InnermostPos(n.Pos)
-		vars = append(vars, &dwarf.Var{
-			Name:          n.Sym.Name,
-			IsReturnValue: isReturnValue,
-			Abbrev:        abbrev,
-			StackOffset:   int32(n.Xoffset),
-			Type:          Ctxt.Lookup(typename),
-			DeclFile:      declpos.RelFilename(),
-			DeclLine:      declpos.RelLine(),
-			DeclCol:       declpos.Col(),
-			InlIndex:      int32(inlIndex),
-			ChildIndex:    -1,
-		})
-		// Record go type of to insure that it gets emitted by the linker.
-		fnsym.Func().RecordAutoType(ngotype(n).Linksym())
-	}
-
-	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 rdcl []*Node
-	for _, n := range fn.Func.Inl.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)
-	}
-	return rdcl
-}
-
-// 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.GOARCH == "arm64" {
-			// There is a word space for FP on ARM64 even if the frame pointer is disabled
-			base -= int64(Widthptr)
-		}
-	case PPARAM, PPARAMOUT:
-		base += Ctxt.FixedFrameSize()
-	}
-	return int32(base + n.Xoffset + slot.Off)
-}
-
-// createComplexVar builds a single DWARF variable entry and location list.
-func createComplexVar(fnsym *obj.LSym, fn *Func, varID ssa.VarID) *dwarf.Var {
-	debug := fn.DebugInfo
-	n := debug.Vars[varID].(*Node)
-
-	var abbrev int
-	switch n.Class() {
-	case PAUTO:
-		abbrev = dwarf.DW_ABRV_AUTO_LOCLIST
-	case PPARAM, PPARAMOUT:
-		abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
-	default:
-		return nil
-	}
-
-	gotype := ngotype(n).Linksym()
-	delete(fnsym.Func().Autot, gotype)
-	typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
-	inlIndex := 0
-	if genDwarfInline > 1 {
-		if n.Name.InlFormal() || n.Name.InlLocal() {
-			inlIndex = posInlIndex(n.Pos) + 1
-			if n.Name.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.Name.InlFormal(),
-		Abbrev:        abbrev,
-		Type:          Ctxt.Lookup(typename),
-		// The stack offset is used as a sorting key, so for decomposed
-		// variables just give it the first 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: stackOffset(debug.Slots[debug.VarSlots[varID][0]]),
-		DeclFile:    declpos.RelFilename(),
-		DeclLine:    declpos.RelLine(),
-		DeclCol:     declpos.Col(),
-		InlIndex:    int32(inlIndex),
-		ChildIndex:  -1,
-	}
-	list := debug.LocationLists[varID]
-	if len(list) != 0 {
-		dvar.PutLocationList = func(listSym, startPC dwarf.Sym) {
-			debug.PutLocationList(list, Ctxt, listSym.(*obj.LSym), startPC.(*obj.LSym))
-		}
-	}
-	return dvar
-}
-
-// fieldtrack adds R_USEFIELD relocations to fnsym to record any
-// struct fields that it used.
-func fieldtrack(fnsym *obj.LSym, tracked map[*types.Sym]struct{}) {
-	if fnsym == nil {
-		return
-	}
-	if objabi.Fieldtrack_enabled == 0 || len(tracked) == 0 {
-		return
-	}
-
-	trackSyms := make([]*types.Sym, 0, len(tracked))
-	for sym := range tracked {
-		trackSyms = append(trackSyms, sym)
-	}
-	sort.Sort(symByName(trackSyms))
-	for _, sym := range trackSyms {
-		r := obj.Addrel(fnsym)
-		r.Sym = sym.Linksym()
-		r.Type = objabi.R_USEFIELD
-	}
-}
-
-type symByName []*types.Sym
-
-func (a symByName) Len() int           { return len(a) }
-func (a symByName) Less(i, j int) bool { return a[i].Name < a[j].Name }
-func (a symByName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
diff --git a/src/cmd/compile/internal/gc/pgen_test.go b/src/cmd/compile/internal/gc/pgen_test.go
deleted file mode 100644
index b1db298..0000000
--- a/src/cmd/compile/internal/gc/pgen_test.go
+++ /dev/null
@@ -1,196 +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 gc
-
-import (
-	"cmd/compile/internal/types"
-	"reflect"
-	"sort"
-	"testing"
-)
-
-func typeWithoutPointers() *types.Type {
-	t := types.New(TSTRUCT)
-	f := &types.Field{Type: types.New(TINT)}
-	t.SetFields([]*types.Field{f})
-	return t
-}
-
-func typeWithPointers() *types.Type {
-	t := types.New(TSTRUCT)
-	f := &types.Field{Type: types.NewPtr(types.New(TINT))}
-	t.SetFields([]*types.Field{f})
-	return t
-}
-
-func markUsed(n *Node) *Node {
-	n.Name.SetUsed(true)
-	return n
-}
-
-func markNeedZero(n *Node) *Node {
-	n.Name.SetNeedzero(true)
-	return n
-}
-
-func nodeWithClass(n Node, c Class) *Node {
-	n.SetClass(c)
-	n.Name = new(Name)
-	return &n
-}
-
-// Test all code paths for cmpstackvarlt.
-func TestCmpstackvar(t *testing.T) {
-	testdata := []struct {
-		a, b *Node
-		lt   bool
-	}{
-		{
-			nodeWithClass(Node{}, PAUTO),
-			nodeWithClass(Node{}, PFUNC),
-			false,
-		},
-		{
-			nodeWithClass(Node{}, PFUNC),
-			nodeWithClass(Node{}, PAUTO),
-			true,
-		},
-		{
-			nodeWithClass(Node{Xoffset: 0}, PFUNC),
-			nodeWithClass(Node{Xoffset: 10}, PFUNC),
-			true,
-		},
-		{
-			nodeWithClass(Node{Xoffset: 20}, PFUNC),
-			nodeWithClass(Node{Xoffset: 10}, PFUNC),
-			false,
-		},
-		{
-			nodeWithClass(Node{Xoffset: 10}, PFUNC),
-			nodeWithClass(Node{Xoffset: 10}, PFUNC),
-			false,
-		},
-		{
-			nodeWithClass(Node{Xoffset: 10}, PPARAM),
-			nodeWithClass(Node{Xoffset: 20}, PPARAMOUT),
-			true,
-		},
-		{
-			nodeWithClass(Node{Xoffset: 10}, PPARAMOUT),
-			nodeWithClass(Node{Xoffset: 20}, PPARAM),
-			true,
-		},
-		{
-			markUsed(nodeWithClass(Node{}, PAUTO)),
-			nodeWithClass(Node{}, PAUTO),
-			true,
-		},
-		{
-			nodeWithClass(Node{}, PAUTO),
-			markUsed(nodeWithClass(Node{}, PAUTO)),
-			false,
-		},
-		{
-			nodeWithClass(Node{Type: typeWithoutPointers()}, PAUTO),
-			nodeWithClass(Node{Type: typeWithPointers()}, PAUTO),
-			false,
-		},
-		{
-			nodeWithClass(Node{Type: typeWithPointers()}, PAUTO),
-			nodeWithClass(Node{Type: typeWithoutPointers()}, PAUTO),
-			true,
-		},
-		{
-			markNeedZero(nodeWithClass(Node{Type: &types.Type{}}, PAUTO)),
-			nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}}, PAUTO),
-			true,
-		},
-		{
-			nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}}, PAUTO),
-			markNeedZero(nodeWithClass(Node{Type: &types.Type{}}, PAUTO)),
-			false,
-		},
-		{
-			nodeWithClass(Node{Type: &types.Type{Width: 1}, Name: &Name{}}, PAUTO),
-			nodeWithClass(Node{Type: &types.Type{Width: 2}, Name: &Name{}}, PAUTO),
-			false,
-		},
-		{
-			nodeWithClass(Node{Type: &types.Type{Width: 2}, Name: &Name{}}, PAUTO),
-			nodeWithClass(Node{Type: &types.Type{Width: 1}, Name: &Name{}}, PAUTO),
-			true,
-		},
-		{
-			nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "abc"}}, PAUTO),
-			nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO),
-			true,
-		},
-		{
-			nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "abc"}}, PAUTO),
-			nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "abc"}}, PAUTO),
-			false,
-		},
-		{
-			nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO),
-			nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "abc"}}, PAUTO),
-			false,
-		},
-	}
-	for _, d := range testdata {
-		got := cmpstackvarlt(d.a, d.b)
-		if got != d.lt {
-			t.Errorf("want %#v < %#v", d.a, d.b)
-		}
-		// If we expect a < b to be true, check that b < a is false.
-		if d.lt && cmpstackvarlt(d.b, d.a) {
-			t.Errorf("unexpected %#v < %#v", d.b, d.a)
-		}
-	}
-}
-
-func TestStackvarSort(t *testing.T) {
-	inp := []*Node{
-		nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
-		nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO),
-		nodeWithClass(Node{Xoffset: 0, Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
-		nodeWithClass(Node{Xoffset: 10, Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
-		nodeWithClass(Node{Xoffset: 20, Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
-		markUsed(nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO)),
-		nodeWithClass(Node{Type: typeWithoutPointers(), Sym: &types.Sym{}}, PAUTO),
-		nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO),
-		markNeedZero(nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO)),
-		nodeWithClass(Node{Type: &types.Type{Width: 1}, Sym: &types.Sym{}}, PAUTO),
-		nodeWithClass(Node{Type: &types.Type{Width: 2}, Sym: &types.Sym{}}, PAUTO),
-		nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "abc"}}, PAUTO),
-		nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO),
-	}
-	want := []*Node{
-		nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
-		nodeWithClass(Node{Xoffset: 0, Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
-		nodeWithClass(Node{Xoffset: 10, Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
-		nodeWithClass(Node{Xoffset: 20, Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
-		markUsed(nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO)),
-		markNeedZero(nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO)),
-		nodeWithClass(Node{Type: &types.Type{Width: 2}, Sym: &types.Sym{}}, PAUTO),
-		nodeWithClass(Node{Type: &types.Type{Width: 1}, Sym: &types.Sym{}}, PAUTO),
-		nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO),
-		nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO),
-		nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "abc"}}, PAUTO),
-		nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO),
-		nodeWithClass(Node{Type: typeWithoutPointers(), Sym: &types.Sym{}}, PAUTO),
-	}
-	sort.Sort(byStackVar(inp))
-	if !reflect.DeepEqual(want, inp) {
-		t.Error("sort failed")
-		for i := range inp {
-			g := inp[i]
-			w := want[i]
-			eq := reflect.DeepEqual(w, g)
-			if !eq {
-				t.Log(i, w, g)
-			}
-		}
-	}
-}
diff --git a/src/cmd/compile/internal/gc/phi.go b/src/cmd/compile/internal/gc/phi.go
deleted file mode 100644
index 5218cd0..0000000
--- a/src/cmd/compile/internal/gc/phi.go
+++ /dev/null
@@ -1,538 +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.
-
-package gc
-
-import (
-	"cmd/compile/internal/ssa"
-	"cmd/compile/internal/types"
-	"cmd/internal/src"
-	"container/heap"
-	"fmt"
-)
-
-// This file contains the algorithm to place phi nodes in a function.
-// For small functions, we use Braun, Buchwald, Hack, Leißa, Mallon, and Zwinkau.
-// https://pp.info.uni-karlsruhe.de/uploads/publikationen/braun13cc.pdf
-// For large functions, we use Sreedhar & Gao: A Linear Time Algorithm for Placing Φ-Nodes.
-// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.8.1979&rep=rep1&type=pdf
-
-const smallBlocks = 500
-
-const debugPhi = false
-
-// insertPhis finds all the places in the function where a phi is
-// necessary and inserts them.
-// Uses FwdRef ops to find all uses of variables, and s.defvars to find
-// all definitions.
-// Phi values are inserted, and all FwdRefs are changed to a Copy
-// of the appropriate phi or definition.
-// TODO: make this part of cmd/compile/internal/ssa somehow?
-func (s *state) insertPhis() {
-	if len(s.f.Blocks) <= smallBlocks {
-		sps := simplePhiState{s: s, f: s.f, defvars: s.defvars}
-		sps.insertPhis()
-		return
-	}
-	ps := phiState{s: s, f: s.f, defvars: s.defvars}
-	ps.insertPhis()
-}
-
-type phiState struct {
-	s       *state                 // SSA state
-	f       *ssa.Func              // function to work on
-	defvars []map[*Node]*ssa.Value // defined variables at end of each block
-
-	varnum map[*Node]int32 // variable numbering
-
-	// properties of the dominator tree
-	idom  []*ssa.Block // dominator parents
-	tree  []domBlock   // dominator child+sibling
-	level []int32      // level in dominator tree (0 = root or unreachable, 1 = children of root, ...)
-
-	// scratch locations
-	priq   blockHeap    // priority queue of blocks, higher level (toward leaves) = higher priority
-	q      []*ssa.Block // inner loop queue
-	queued *sparseSet   // has been put in q
-	hasPhi *sparseSet   // has a phi
-	hasDef *sparseSet   // has a write of the variable we're processing
-
-	// miscellaneous
-	placeholder *ssa.Value // dummy value to use as a "not set yet" placeholder.
-}
-
-func (s *phiState) insertPhis() {
-	if debugPhi {
-		fmt.Println(s.f.String())
-	}
-
-	// Find all the variables for which we need to match up reads & writes.
-	// This step prunes any basic-block-only variables from consideration.
-	// Generate a numbering for these variables.
-	s.varnum = map[*Node]int32{}
-	var vars []*Node
-	var vartypes []*types.Type
-	for _, b := range s.f.Blocks {
-		for _, v := range b.Values {
-			if v.Op != ssa.OpFwdRef {
-				continue
-			}
-			var_ := v.Aux.(*Node)
-
-			// Optimization: look back 1 block for the definition.
-			if len(b.Preds) == 1 {
-				c := b.Preds[0].Block()
-				if w := s.defvars[c.ID][var_]; w != nil {
-					v.Op = ssa.OpCopy
-					v.Aux = nil
-					v.AddArg(w)
-					continue
-				}
-			}
-
-			if _, ok := s.varnum[var_]; ok {
-				continue
-			}
-			s.varnum[var_] = int32(len(vartypes))
-			if debugPhi {
-				fmt.Printf("var%d = %v\n", len(vartypes), var_)
-			}
-			vars = append(vars, var_)
-			vartypes = append(vartypes, v.Type)
-		}
-	}
-
-	if len(vartypes) == 0 {
-		return
-	}
-
-	// Find all definitions of the variables we need to process.
-	// defs[n] contains all the blocks in which variable number n is assigned.
-	defs := make([][]*ssa.Block, len(vartypes))
-	for _, b := range s.f.Blocks {
-		for var_ := range s.defvars[b.ID] { // TODO: encode defvars some other way (explicit ops)? make defvars[n] a slice instead of a map.
-			if n, ok := s.varnum[var_]; ok {
-				defs[n] = append(defs[n], b)
-			}
-		}
-	}
-
-	// Make dominator tree.
-	s.idom = s.f.Idom()
-	s.tree = make([]domBlock, s.f.NumBlocks())
-	for _, b := range s.f.Blocks {
-		p := s.idom[b.ID]
-		if p != nil {
-			s.tree[b.ID].sibling = s.tree[p.ID].firstChild
-			s.tree[p.ID].firstChild = b
-		}
-	}
-	// Compute levels in dominator tree.
-	// With parent pointers we can do a depth-first walk without
-	// any auxiliary storage.
-	s.level = make([]int32, s.f.NumBlocks())
-	b := s.f.Entry
-levels:
-	for {
-		if p := s.idom[b.ID]; p != nil {
-			s.level[b.ID] = s.level[p.ID] + 1
-			if debugPhi {
-				fmt.Printf("level %s = %d\n", b, s.level[b.ID])
-			}
-		}
-		if c := s.tree[b.ID].firstChild; c != nil {
-			b = c
-			continue
-		}
-		for {
-			if c := s.tree[b.ID].sibling; c != nil {
-				b = c
-				continue levels
-			}
-			b = s.idom[b.ID]
-			if b == nil {
-				break levels
-			}
-		}
-	}
-
-	// Allocate scratch locations.
-	s.priq.level = s.level
-	s.q = make([]*ssa.Block, 0, s.f.NumBlocks())
-	s.queued = newSparseSet(s.f.NumBlocks())
-	s.hasPhi = newSparseSet(s.f.NumBlocks())
-	s.hasDef = newSparseSet(s.f.NumBlocks())
-	s.placeholder = s.s.entryNewValue0(ssa.OpUnknown, types.TypeInvalid)
-
-	// Generate phi ops for each variable.
-	for n := range vartypes {
-		s.insertVarPhis(n, vars[n], defs[n], vartypes[n])
-	}
-
-	// Resolve FwdRefs to the correct write or phi.
-	s.resolveFwdRefs()
-
-	// Erase variable numbers stored in AuxInt fields of phi ops. They are no longer needed.
-	for _, b := range s.f.Blocks {
-		for _, v := range b.Values {
-			if v.Op == ssa.OpPhi {
-				v.AuxInt = 0
-			}
-		}
-	}
-}
-
-func (s *phiState) insertVarPhis(n int, var_ *Node, defs []*ssa.Block, typ *types.Type) {
-	priq := &s.priq
-	q := s.q
-	queued := s.queued
-	queued.clear()
-	hasPhi := s.hasPhi
-	hasPhi.clear()
-	hasDef := s.hasDef
-	hasDef.clear()
-
-	// Add defining blocks to priority queue.
-	for _, b := range defs {
-		priq.a = append(priq.a, b)
-		hasDef.add(b.ID)
-		if debugPhi {
-			fmt.Printf("def of var%d in %s\n", n, b)
-		}
-	}
-	heap.Init(priq)
-
-	// Visit blocks defining variable n, from deepest to shallowest.
-	for len(priq.a) > 0 {
-		currentRoot := heap.Pop(priq).(*ssa.Block)
-		if debugPhi {
-			fmt.Printf("currentRoot %s\n", currentRoot)
-		}
-		// Walk subtree below definition.
-		// Skip subtrees we've done in previous iterations.
-		// Find edges exiting tree dominated by definition (the dominance frontier).
-		// Insert phis at target blocks.
-		if queued.contains(currentRoot.ID) {
-			s.s.Fatalf("root already in queue")
-		}
-		q = append(q, currentRoot)
-		queued.add(currentRoot.ID)
-		for len(q) > 0 {
-			b := q[len(q)-1]
-			q = q[:len(q)-1]
-			if debugPhi {
-				fmt.Printf("  processing %s\n", b)
-			}
-
-			currentRootLevel := s.level[currentRoot.ID]
-			for _, e := range b.Succs {
-				c := e.Block()
-				// TODO: if the variable is dead at c, skip it.
-				if s.level[c.ID] > currentRootLevel {
-					// a D-edge, or an edge whose target is in currentRoot's subtree.
-					continue
-				}
-				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 range c.Preds {
-					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)
-				}
-			}
-
-			// Visit children if they have not been visited yet.
-			for c := s.tree[b.ID].firstChild; c != nil; c = s.tree[c.ID].sibling {
-				if !queued.contains(c.ID) {
-					q = append(q, c)
-					queued.add(c.ID)
-				}
-			}
-		}
-	}
-}
-
-// resolveFwdRefs links all FwdRef uses up to their nearest dominating definition.
-func (s *phiState) resolveFwdRefs() {
-	// Do a depth-first walk of the dominator tree, keeping track
-	// of the most-recently-seen value for each variable.
-
-	// Map from variable ID to SSA value at the current point of the walk.
-	values := make([]*ssa.Value, len(s.varnum))
-	for i := range values {
-		values[i] = s.placeholder
-	}
-
-	// Stack of work to do.
-	type stackEntry struct {
-		b *ssa.Block // block to explore
-
-		// variable/value pair to reinstate on exit
-		n int32 // variable ID
-		v *ssa.Value
-
-		// Note: only one of b or n,v will be set.
-	}
-	var stk []stackEntry
-
-	stk = append(stk, stackEntry{b: s.f.Entry})
-	for len(stk) > 0 {
-		work := stk[len(stk)-1]
-		stk = stk[:len(stk)-1]
-
-		b := work.b
-		if b == nil {
-			// On exit from a block, this case will undo any assignments done below.
-			values[work.n] = work.v
-			continue
-		}
-
-		// Process phis as new defs. They come before FwdRefs in this block.
-		for _, v := range b.Values {
-			if v.Op != ssa.OpPhi {
-				continue
-			}
-			n := int32(v.AuxInt)
-			// Remember the old assignment so we can undo it when we exit b.
-			stk = append(stk, stackEntry{n: n, v: values[n]})
-			// Record the new assignment.
-			values[n] = v
-		}
-
-		// Replace a FwdRef op with the current incoming value for its variable.
-		for _, v := range b.Values {
-			if v.Op != ssa.OpFwdRef {
-				continue
-			}
-			n := s.varnum[v.Aux.(*Node)]
-			v.Op = ssa.OpCopy
-			v.Aux = nil
-			v.AddArg(values[n])
-		}
-
-		// Establish values for variables defined in b.
-		for var_, v := range s.defvars[b.ID] {
-			n, ok := s.varnum[var_]
-			if !ok {
-				// some variable not live across a basic block boundary.
-				continue
-			}
-			// Remember the old assignment so we can undo it when we exit b.
-			stk = append(stk, stackEntry{n: n, v: values[n]})
-			// Record the new assignment.
-			values[n] = v
-		}
-
-		// Replace phi args in successors with the current incoming value.
-		for _, e := range b.Succs {
-			c, i := e.Block(), e.Index()
-			for j := len(c.Values) - 1; j >= 0; j-- {
-				v := c.Values[j]
-				if v.Op != ssa.OpPhi {
-					break // All phis will be at the end of the block during phi building.
-				}
-				// Only set arguments that have been resolved.
-				// For very wide CFGs, this significantly speeds up phi resolution.
-				// See golang.org/issue/8225.
-				if w := values[v.AuxInt]; w.Op != ssa.OpUnknown {
-					v.SetArg(i, w)
-				}
-			}
-		}
-
-		// Walk children in dominator tree.
-		for c := s.tree[b.ID].firstChild; c != nil; c = s.tree[c.ID].sibling {
-			stk = append(stk, stackEntry{b: c})
-		}
-	}
-}
-
-// domBlock contains extra per-block information to record the dominator tree.
-type domBlock struct {
-	firstChild *ssa.Block // first child of block in dominator tree
-	sibling    *ssa.Block // next child of parent in dominator tree
-}
-
-// A block heap is used as a priority queue to implement the PiggyBank
-// from Sreedhar and Gao.  That paper uses an array which is better
-// asymptotically but worse in the common case when the PiggyBank
-// holds a sparse set of blocks.
-type blockHeap struct {
-	a     []*ssa.Block // block IDs in heap
-	level []int32      // depth in dominator tree (static, used for determining priority)
-}
-
-func (h *blockHeap) Len() int      { return len(h.a) }
-func (h *blockHeap) Swap(i, j int) { a := h.a; a[i], a[j] = a[j], a[i] }
-
-func (h *blockHeap) Push(x interface{}) {
-	v := x.(*ssa.Block)
-	h.a = append(h.a, v)
-}
-func (h *blockHeap) Pop() interface{} {
-	old := h.a
-	n := len(old)
-	x := old[n-1]
-	h.a = old[:n-1]
-	return x
-}
-func (h *blockHeap) Less(i, j int) bool {
-	return h.level[h.a[i].ID] > h.level[h.a[j].ID]
-}
-
-// TODO: stop walking the iterated domininance frontier when
-// the variable is dead. Maybe detect that by checking if the
-// node we're on is reverse dominated by all the reads?
-// Reverse dominated by the highest common successor of all the reads?
-
-// copy of ../ssa/sparseset.go
-// TODO: move this file to ../ssa, then use sparseSet there.
-type sparseSet struct {
-	dense  []ssa.ID
-	sparse []int32
-}
-
-// newSparseSet returns a sparseSet that can represent
-// integers between 0 and n-1
-func newSparseSet(n int) *sparseSet {
-	return &sparseSet{dense: nil, sparse: make([]int32, n)}
-}
-
-func (s *sparseSet) contains(x ssa.ID) bool {
-	i := s.sparse[x]
-	return i < int32(len(s.dense)) && s.dense[i] == x
-}
-
-func (s *sparseSet) add(x ssa.ID) {
-	i := s.sparse[x]
-	if i < int32(len(s.dense)) && s.dense[i] == x {
-		return
-	}
-	s.dense = append(s.dense, x)
-	s.sparse[x] = int32(len(s.dense)) - 1
-}
-
-func (s *sparseSet) clear() {
-	s.dense = s.dense[:0]
-}
-
-// Variant to use for small functions.
-type simplePhiState struct {
-	s         *state                 // SSA state
-	f         *ssa.Func              // function to work on
-	fwdrefs   []*ssa.Value           // list of FwdRefs to be processed
-	defvars   []map[*Node]*ssa.Value // defined variables at end of each block
-	reachable []bool                 // which blocks are reachable
-}
-
-func (s *simplePhiState) insertPhis() {
-	s.reachable = ssa.ReachableBlocks(s.f)
-
-	// Find FwdRef ops.
-	for _, b := range s.f.Blocks {
-		for _, v := range b.Values {
-			if v.Op != ssa.OpFwdRef {
-				continue
-			}
-			s.fwdrefs = append(s.fwdrefs, v)
-			var_ := v.Aux.(*Node)
-			if _, ok := s.defvars[b.ID][var_]; !ok {
-				s.defvars[b.ID][var_] = v // treat FwdDefs as definitions.
-			}
-		}
-	}
-
-	var args []*ssa.Value
-
-loop:
-	for len(s.fwdrefs) > 0 {
-		v := s.fwdrefs[len(s.fwdrefs)-1]
-		s.fwdrefs = s.fwdrefs[:len(s.fwdrefs)-1]
-		b := v.Block
-		var_ := v.Aux.(*Node)
-		if b == s.f.Entry {
-			// No variable should be live at entry.
-			s.s.Fatalf("Value live at entry. It shouldn't be. func %s, node %v, value %v", s.f.Name, var_, v)
-		}
-		if !s.reachable[b.ID] {
-			// This block is dead.
-			// It doesn't matter what we use here as long as it is well-formed.
-			v.Op = ssa.OpUnknown
-			v.Aux = nil
-			continue
-		}
-		// Find variable value on each predecessor.
-		args = args[:0]
-		for _, e := range b.Preds {
-			args = append(args, s.lookupVarOutgoing(e.Block(), v.Type, var_, v.Pos))
-		}
-
-		// Decide if we need a phi or not. We need a phi if there
-		// are two different args (which are both not v).
-		var w *ssa.Value
-		for _, a := range args {
-			if a == v {
-				continue // self-reference
-			}
-			if a == w {
-				continue // already have this witness
-			}
-			if w != nil {
-				// two witnesses, need a phi value
-				v.Op = ssa.OpPhi
-				v.AddArgs(args...)
-				v.Aux = nil
-				continue loop
-			}
-			w = a // save witness
-		}
-		if w == nil {
-			s.s.Fatalf("no witness for reachable phi %s", v)
-		}
-		// One witness. Make v a copy of w.
-		v.Op = ssa.OpCopy
-		v.Aux = nil
-		v.AddArg(w)
-	}
-}
-
-// lookupVarOutgoing finds the variable's value at the end of block b.
-func (s *simplePhiState) lookupVarOutgoing(b *ssa.Block, t *types.Type, var_ *Node, line src.XPos) *ssa.Value {
-	for {
-		if v := s.defvars[b.ID][var_]; v != nil {
-			return v
-		}
-		// The variable is not defined by b and we haven't looked it up yet.
-		// If b has exactly one predecessor, loop to look it up there.
-		// Otherwise, give up and insert a new FwdRef and resolve it later.
-		if len(b.Preds) != 1 {
-			break
-		}
-		b = b.Preds[0].Block()
-		if !s.reachable[b.ID] {
-			// This is rare; it happens with oddly interleaved infinite loops in dead code.
-			// See issue 19783.
-			break
-		}
-	}
-	// Generate a FwdRef for the variable and return that.
-	v := b.NewValue0A(line, ssa.OpFwdRef, t, var_)
-	s.defvars[b.ID][var_] = v
-	s.s.addNamedValue(var_, v)
-	s.fwdrefs = append(s.fwdrefs, v)
-	return v
-}
diff --git a/src/cmd/compile/internal/gc/plive.go b/src/cmd/compile/internal/gc/plive.go
deleted file mode 100644
index a48173e..0000000
--- a/src/cmd/compile/internal/gc/plive.go
+++ /dev/null
@@ -1,1321 +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.
-
-// Garbage collector liveness bitmap generation.
-
-// The command line flag -live causes this code to print debug information.
-// The levels are:
-//
-//	-live (aka -live=1): print liveness lists as code warnings at safe points
-//	-live=2: print an assembly listing with liveness annotations
-//
-// Each level includes the earlier output as well.
-
-package gc
-
-import (
-	"cmd/compile/internal/ssa"
-	"cmd/compile/internal/types"
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"crypto/md5"
-	"fmt"
-	"strings"
-)
-
-// OpVarDef is an annotation for the liveness analysis, marking a place
-// where a complete initialization (definition) of a variable begins.
-// Since the liveness analysis can see initialization of single-word
-// variables quite easy, OpVarDef is only needed for multi-word
-// variables satisfying isfat(n.Type). For simplicity though, buildssa
-// emits OpVarDef regardless of variable width.
-//
-// An 'OpVarDef x' annotation in the instruction stream tells the liveness
-// analysis to behave as though the variable x is being initialized at that
-// point in the instruction stream. The OpVarDef must appear before the
-// actual (multi-instruction) initialization, and it must also appear after
-// any uses of the previous value, if any. For example, if compiling:
-//
-//	x = x[1:]
-//
-// it is important to generate code like:
-//
-//	base, len, cap = pieces of x[1:]
-//	OpVarDef x
-//	x = {base, len, cap}
-//
-// If instead the generated code looked like:
-//
-//	OpVarDef x
-//	base, len, cap = pieces of x[1:]
-//	x = {base, len, cap}
-//
-// then the liveness analysis would decide the previous value of x was
-// unnecessary even though it is about to be used by the x[1:] computation.
-// Similarly, if the generated code looked like:
-//
-//	base, len, cap = pieces of x[1:]
-//	x = {base, len, cap}
-//	OpVarDef x
-//
-// then the liveness analysis will not preserve the new value of x, because
-// the OpVarDef appears to have "overwritten" it.
-//
-// OpVarDef is a bit of a kludge to work around the fact that the instruction
-// stream is working on single-word values but the liveness analysis
-// wants to work on individual variables, which might be multi-word
-// aggregates. It might make sense at some point to look into letting
-// the liveness analysis work on single-word values as well, although
-// there are complications around interface values, slices, and strings,
-// all of which cannot be treated as individual words.
-//
-// OpVarKill is the opposite of OpVarDef: it marks a value as no longer needed,
-// even if its address has been taken. That is, an OpVarKill annotation asserts
-// that its argument is certainly dead, for use when the liveness analysis
-// would not otherwise be able to deduce that fact.
-
-// TODO: get rid of OpVarKill here. It's useful for stack frame allocation
-// so the compiler can allocate two temps to the same location. Here it's now
-// useless, since the implementation of stack objects.
-
-// BlockEffects summarizes the liveness effects on an SSA block.
-type BlockEffects struct {
-	// Computed during Liveness.prologue using only the content of
-	// individual blocks:
-	//
-	//	uevar: upward exposed variables (used before set in block)
-	//	varkill: killed variables (set in block)
-	uevar   bvec
-	varkill bvec
-
-	// Computed during Liveness.solve using control flow information:
-	//
-	//	livein: variables live at block entry
-	//	liveout: variables live at block exit
-	livein  bvec
-	liveout bvec
-}
-
-// A collection of global state used by liveness analysis.
-type Liveness struct {
-	fn         *Node
-	f          *ssa.Func
-	vars       []*Node
-	idx        map[*Node]int32
-	stkptrsize int64
-
-	be []BlockEffects
-
-	// allUnsafe indicates that all points in this function are
-	// unsafe-points.
-	allUnsafe bool
-	// unsafePoints bit i is set if Value ID i is an unsafe-point
-	// (preemption is not allowed). Only valid if !allUnsafe.
-	unsafePoints bvec
-
-	// An array with a bit vector for each safe point in the
-	// current Block during Liveness.epilogue. Indexed in Value
-	// order for that block. Additionally, for the entry block
-	// livevars[0] is the entry bitmap. Liveness.compact moves
-	// these to stackMaps.
-	livevars []bvec
-
-	// livenessMap maps from safe points (i.e., CALLs) to their
-	// liveness map indexes.
-	livenessMap LivenessMap
-	stackMapSet bvecSet
-	stackMaps   []bvec
-
-	cache progeffectscache
-}
-
-// LivenessMap maps from *ssa.Value to LivenessIndex.
-type LivenessMap struct {
-	vals map[ssa.ID]LivenessIndex
-	// The set of live, pointer-containing variables at the deferreturn
-	// call (only set when open-coded defers are used).
-	deferreturn LivenessIndex
-}
-
-func (m *LivenessMap) reset() {
-	if m.vals == nil {
-		m.vals = make(map[ssa.ID]LivenessIndex)
-	} else {
-		for k := range m.vals {
-			delete(m.vals, k)
-		}
-	}
-	m.deferreturn = LivenessDontCare
-}
-
-func (m *LivenessMap) set(v *ssa.Value, i LivenessIndex) {
-	m.vals[v.ID] = i
-}
-
-func (m LivenessMap) Get(v *ssa.Value) LivenessIndex {
-	// If v isn't in the map, then it's a "don't care" and not an
-	// unsafe-point.
-	if idx, ok := m.vals[v.ID]; ok {
-		return idx
-	}
-	return LivenessIndex{StackMapDontCare, false}
-}
-
-// LivenessIndex stores the liveness map information for a Value.
-type LivenessIndex struct {
-	stackMapIndex int
-
-	// isUnsafePoint indicates that this is an unsafe-point.
-	//
-	// Note that it's possible for a call Value to have a stack
-	// map while also being an unsafe-point. This means it cannot
-	// be preempted at this instruction, but that a preemption or
-	// stack growth may happen in the called function.
-	isUnsafePoint bool
-}
-
-// LivenessDontCare indicates that the liveness information doesn't
-// matter. Currently it is used in deferreturn liveness when we don't
-// actually need it. It should never be emitted to the PCDATA stream.
-var LivenessDontCare = LivenessIndex{StackMapDontCare, true}
-
-// StackMapDontCare indicates that the stack map index at a Value
-// doesn't matter.
-//
-// This is a sentinel value that should never be emitted to the PCDATA
-// stream. We use -1000 because that's obviously never a valid stack
-// index (but -1 is).
-const StackMapDontCare = -1000
-
-func (idx LivenessIndex) StackMapValid() bool {
-	return idx.stackMapIndex != StackMapDontCare
-}
-
-type progeffectscache struct {
-	retuevar    []int32
-	tailuevar   []int32
-	initialized bool
-}
-
-// livenessShouldTrack reports whether the liveness analysis
-// should track the variable n.
-// We don't care about variables that have no pointers,
-// nor do we care about non-local variables,
-// nor do we care about empty structs (handled by the pointer check),
-// nor do we care about the fake PAUTOHEAP variables.
-func livenessShouldTrack(n *Node) bool {
-	return n.Op == ONAME && (n.Class() == PAUTO || n.Class() == PPARAM || n.Class() == PPARAMOUT) && n.Type.HasPointers()
-}
-
-// getvariables returns the list of on-stack variables that we need to track
-// and a map for looking up indices by *Node.
-func getvariables(fn *Node) ([]*Node, map[*Node]int32) {
-	var vars []*Node
-	for _, n := range fn.Func.Dcl {
-		if livenessShouldTrack(n) {
-			vars = append(vars, n)
-		}
-	}
-	idx := make(map[*Node]int32, len(vars))
-	for i, n := range vars {
-		idx[n] = int32(i)
-	}
-	return vars, idx
-}
-
-func (lv *Liveness) initcache() {
-	if lv.cache.initialized {
-		Fatalf("liveness cache initialized twice")
-		return
-	}
-	lv.cache.initialized = true
-
-	for i, node := range lv.vars {
-		switch node.Class() {
-		case PPARAM:
-			// A return instruction with a p.to is a tail return, which brings
-			// the stack pointer back up (if it ever went down) and then jumps
-			// to a new function entirely. That form of instruction must read
-			// all the parameters for correctness, and similarly it must not
-			// read the out arguments - they won't be set until the new
-			// function runs.
-			lv.cache.tailuevar = append(lv.cache.tailuevar, int32(i))
-
-		case PPARAMOUT:
-			// All results are live at every return point.
-			// Note that this point is after escaping return values
-			// are copied back to the stack using their PAUTOHEAP references.
-			lv.cache.retuevar = append(lv.cache.retuevar, int32(i))
-		}
-	}
-}
-
-// A liveEffect is a set of flags that describe an instruction's
-// liveness effects on a variable.
-//
-// The possible flags are:
-//	uevar - used by the instruction
-//	varkill - killed by the instruction (set)
-// A kill happens after the use (for an instruction that updates a value, for example).
-type liveEffect int
-
-const (
-	uevar liveEffect = 1 << iota
-	varkill
-)
-
-// valueEffects returns the index of a variable in lv.vars and the
-// liveness effects v has on that variable.
-// If v does not affect any tracked variables, it returns -1, 0.
-func (lv *Liveness) valueEffects(v *ssa.Value) (int32, liveEffect) {
-	n, e := affectedNode(v)
-	if e == 0 || n == nil || n.Op != ONAME { // cheapest checks first
-		return -1, 0
-	}
-
-	// AllocFrame has dropped unused variables from
-	// lv.fn.Func.Dcl, but they might still be referenced by
-	// OpVarFoo pseudo-ops. Ignore them to prevent "lost track of
-	// variable" ICEs (issue 19632).
-	switch v.Op {
-	case ssa.OpVarDef, ssa.OpVarKill, ssa.OpVarLive, ssa.OpKeepAlive:
-		if !n.Name.Used() {
-			return -1, 0
-		}
-	}
-
-	var effect liveEffect
-	// Read is a read, obviously.
-	//
-	// Addr is a read also, as any subsequent holder of the pointer must be able
-	// to see all the values (including initialization) written so far.
-	// This also prevents a variable from "coming back from the dead" and presenting
-	// stale pointers to the garbage collector. See issue 28445.
-	if e&(ssa.SymRead|ssa.SymAddr) != 0 {
-		effect |= uevar
-	}
-	if e&ssa.SymWrite != 0 && (!isfat(n.Type) || v.Op == ssa.OpVarDef) {
-		effect |= varkill
-	}
-
-	if effect == 0 {
-		return -1, 0
-	}
-
-	if pos, ok := lv.idx[n]; ok {
-		return pos, effect
-	}
-	return -1, 0
-}
-
-// affectedNode returns the *Node affected by v
-func affectedNode(v *ssa.Value) (*Node, ssa.SymEffect) {
-	// Special cases.
-	switch v.Op {
-	case ssa.OpLoadReg:
-		n, _ := AutoVar(v.Args[0])
-		return n, ssa.SymRead
-	case ssa.OpStoreReg:
-		n, _ := AutoVar(v)
-		return n, ssa.SymWrite
-
-	case ssa.OpVarLive:
-		return v.Aux.(*Node), ssa.SymRead
-	case ssa.OpVarDef, ssa.OpVarKill:
-		return v.Aux.(*Node), ssa.SymWrite
-	case ssa.OpKeepAlive:
-		n, _ := AutoVar(v.Args[0])
-		return n, ssa.SymRead
-	}
-
-	e := v.Op.SymEffect()
-	if e == 0 {
-		return nil, 0
-	}
-
-	switch a := v.Aux.(type) {
-	case nil, *obj.LSym:
-		// ok, but no node
-		return nil, e
-	case *Node:
-		return a, e
-	default:
-		Fatalf("weird aux: %s", v.LongString())
-		return nil, e
-	}
-}
-
-type livenessFuncCache struct {
-	be          []BlockEffects
-	livenessMap LivenessMap
-}
-
-// Constructs a new liveness structure used to hold the global state of the
-// liveness computation. The cfg argument is a slice of *BasicBlocks and the
-// vars argument is a slice of *Nodes.
-func newliveness(fn *Node, f *ssa.Func, vars []*Node, idx map[*Node]int32, stkptrsize int64) *Liveness {
-	lv := &Liveness{
-		fn:         fn,
-		f:          f,
-		vars:       vars,
-		idx:        idx,
-		stkptrsize: stkptrsize,
-	}
-
-	// Significant sources of allocation are kept in the ssa.Cache
-	// and reused. Surprisingly, the bit vectors themselves aren't
-	// a major source of allocation, but the liveness maps are.
-	if lc, _ := f.Cache.Liveness.(*livenessFuncCache); lc == nil {
-		// Prep the cache so liveness can fill it later.
-		f.Cache.Liveness = new(livenessFuncCache)
-	} else {
-		if cap(lc.be) >= f.NumBlocks() {
-			lv.be = lc.be[:f.NumBlocks()]
-		}
-		lv.livenessMap = LivenessMap{vals: lc.livenessMap.vals, deferreturn: LivenessDontCare}
-		lc.livenessMap.vals = nil
-	}
-	if lv.be == nil {
-		lv.be = make([]BlockEffects, f.NumBlocks())
-	}
-
-	nblocks := int32(len(f.Blocks))
-	nvars := int32(len(vars))
-	bulk := bvbulkalloc(nvars, nblocks*7)
-	for _, b := range f.Blocks {
-		be := lv.blockEffects(b)
-
-		be.uevar = bulk.next()
-		be.varkill = bulk.next()
-		be.livein = bulk.next()
-		be.liveout = bulk.next()
-	}
-	lv.livenessMap.reset()
-
-	lv.markUnsafePoints()
-	return lv
-}
-
-func (lv *Liveness) blockEffects(b *ssa.Block) *BlockEffects {
-	return &lv.be[b.ID]
-}
-
-// 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: type %v has alignment %d, but offset is %v", t, t.Align, off)
-	}
-	if !t.HasPointers() {
-		// Note: this case ensures that pointers to go:notinheap types
-		// are not considered pointers by garbage collection and stack copying.
-		return
-	}
-
-	switch t.Etype {
-	case TPTR, TUNSAFEPTR, TFUNC, TCHAN, TMAP:
-		if off&int64(Widthptr-1) != 0 {
-			Fatalf("onebitwalktype1: invalid alignment, %v", t)
-		}
-		bv.Set(int32(off / int64(Widthptr))) // pointer
-
-	case TSTRING:
-		// struct { byte *str; intgo len; }
-		if off&int64(Widthptr-1) != 0 {
-			Fatalf("onebitwalktype1: invalid alignment, %v", t)
-		}
-		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 off&int64(Widthptr-1) != 0 {
-			Fatalf("onebitwalktype1: invalid alignment, %v", t)
-		}
-		// The first word of an interface is a pointer, but we don't
-		// treat it as such.
-		// 1. If it is a non-empty interface, the pointer points to an itab
-		//    which is always in persistentalloc space.
-		// 2. If it is an empty interface, the pointer points to a _type.
-		//   a. If it is a compile-time-allocated type, it points into
-		//      the read-only data section.
-		//   b. If it is a reflect-allocated type, it points into the Go heap.
-		//      Reflect is responsible for keeping a reference to
-		//      the underlying type so it won't be GCd.
-		// If we ever have a moving GC, we need to change this for 2b (as
-		// well as scan itabs to update their itab._type fields).
-		bv.Set(int32(off/int64(Widthptr) + 1)) // pointer in second slot
-
-	case TSLICE:
-		// struct { byte *array; uintgo len; uintgo cap; }
-		if off&int64(Widthptr-1) != 0 {
-			Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
-		}
-		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(elt, off, bv)
-			off += elt.Width
-		}
-
-	case TSTRUCT:
-		for _, f := range t.Fields().Slice() {
-			onebitwalktype1(f.Type, off+f.Offset, bv)
-		}
-
-	default:
-		Fatalf("onebitwalktype1: unexpected type, %v", t)
-	}
-}
-
-// 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 (lv *Liveness) pointerMap(liveout bvec, vars []*Node, args, locals bvec) {
-	for i := int32(0); ; i++ {
-		i = liveout.Next(i)
-		if i < 0 {
-			break
-		}
-		node := vars[i]
-		switch node.Class() {
-		case PAUTO:
-			onebitwalktype1(node.Type, node.Xoffset+lv.stkptrsize, locals)
-
-		case PPARAM, PPARAMOUT:
-			onebitwalktype1(node.Type, node.Xoffset, args)
-		}
-	}
-}
-
-// allUnsafe indicates that all points in this function are
-// unsafe-points.
-func allUnsafe(f *ssa.Func) bool {
-	// The runtime assumes the only safe-points are function
-	// prologues (because that's how it used to be). We could and
-	// should improve that, but for now keep consider all points
-	// in the runtime unsafe. obj will add prologues and their
-	// safe-points.
-	//
-	// go:nosplit functions are similar. Since safe points used to
-	// be coupled with stack checks, go:nosplit often actually
-	// means "no safe points in this function".
-	return compiling_runtime || f.NoSplit
-}
-
-// markUnsafePoints finds unsafe points and computes lv.unsafePoints.
-func (lv *Liveness) markUnsafePoints() {
-	if allUnsafe(lv.f) {
-		// No complex analysis necessary.
-		lv.allUnsafe = true
-		return
-	}
-
-	lv.unsafePoints = bvalloc(int32(lv.f.NumValues()))
-
-	// Mark architecture-specific unsafe points.
-	for _, b := range lv.f.Blocks {
-		for _, v := range b.Values {
-			if v.Op.UnsafePoint() {
-				lv.unsafePoints.Set(int32(v.ID))
-			}
-		}
-	}
-
-	// Mark write barrier unsafe points.
-	for _, wbBlock := range lv.f.WBLoads {
-		if wbBlock.Kind == ssa.BlockPlain && len(wbBlock.Values) == 0 {
-			// The write barrier block was optimized away
-			// but we haven't done dead block elimination.
-			// (This can happen in -N mode.)
-			continue
-		}
-		// Check that we have the expected diamond shape.
-		if len(wbBlock.Succs) != 2 {
-			lv.f.Fatalf("expected branch at write barrier block %v", wbBlock)
-		}
-		s0, s1 := wbBlock.Succs[0].Block(), wbBlock.Succs[1].Block()
-		if s0 == s1 {
-			// There's no difference between write barrier on and off.
-			// Thus there's no unsafe locations. See issue 26024.
-			continue
-		}
-		if s0.Kind != ssa.BlockPlain || s1.Kind != ssa.BlockPlain {
-			lv.f.Fatalf("expected successors of write barrier block %v to be plain", wbBlock)
-		}
-		if s0.Succs[0].Block() != s1.Succs[0].Block() {
-			lv.f.Fatalf("expected successors of write barrier block %v to converge", wbBlock)
-		}
-
-		// Flow backwards from the control value to find the
-		// flag load. We don't know what lowered ops we're
-		// looking for, but all current arches produce a
-		// single op that does the memory load from the flag
-		// address, so we look for that.
-		var load *ssa.Value
-		v := wbBlock.Controls[0]
-		for {
-			if sym, ok := v.Aux.(*obj.LSym); ok && sym == writeBarrier {
-				load = v
-				break
-			}
-			switch v.Op {
-			case ssa.Op386TESTL:
-				// 386 lowers Neq32 to (TESTL cond cond),
-				if v.Args[0] == v.Args[1] {
-					v = v.Args[0]
-					continue
-				}
-			case ssa.Op386MOVLload, ssa.OpARM64MOVWUload, ssa.OpPPC64MOVWZload, ssa.OpWasmI64Load32U:
-				// Args[0] is the address of the write
-				// barrier control. Ignore Args[1],
-				// which is the mem operand.
-				// TODO: Just ignore mem operands?
-				v = v.Args[0]
-				continue
-			}
-			// Common case: just flow backwards.
-			if len(v.Args) != 1 {
-				v.Fatalf("write barrier control value has more than one argument: %s", v.LongString())
-			}
-			v = v.Args[0]
-		}
-
-		// Mark everything after the load unsafe.
-		found := false
-		for _, v := range wbBlock.Values {
-			found = found || v == load
-			if found {
-				lv.unsafePoints.Set(int32(v.ID))
-			}
-		}
-
-		// Mark the two successor blocks unsafe. These come
-		// back together immediately after the direct write in
-		// one successor and the last write barrier call in
-		// the other, so there's no need to be more precise.
-		for _, succ := range wbBlock.Succs {
-			for _, v := range succ.Block().Values {
-				lv.unsafePoints.Set(int32(v.ID))
-			}
-		}
-	}
-
-	// Find uintptr -> unsafe.Pointer conversions and flood
-	// unsafeness back to a call (which is always a safe point).
-	//
-	// Looking for the uintptr -> unsafe.Pointer conversion has a
-	// few advantages over looking for unsafe.Pointer -> uintptr
-	// conversions:
-	//
-	// 1. We avoid needlessly blocking safe-points for
-	// unsafe.Pointer -> uintptr conversions that never go back to
-	// a Pointer.
-	//
-	// 2. We don't have to detect calls to reflect.Value.Pointer,
-	// reflect.Value.UnsafeAddr, and reflect.Value.InterfaceData,
-	// which are implicit unsafe.Pointer -> uintptr conversions.
-	// We can't even reliably detect this if there's an indirect
-	// call to one of these methods.
-	//
-	// TODO: For trivial unsafe.Pointer arithmetic, it would be
-	// nice to only flood as far as the unsafe.Pointer -> uintptr
-	// conversion, but it's hard to know which argument of an Add
-	// or Sub to follow.
-	var flooded bvec
-	var flood func(b *ssa.Block, vi int)
-	flood = func(b *ssa.Block, vi int) {
-		if flooded.n == 0 {
-			flooded = bvalloc(int32(lv.f.NumBlocks()))
-		}
-		if flooded.Get(int32(b.ID)) {
-			return
-		}
-		for i := vi - 1; i >= 0; i-- {
-			v := b.Values[i]
-			if v.Op.IsCall() {
-				// Uintptrs must not contain live
-				// pointers across calls, so stop
-				// flooding.
-				return
-			}
-			lv.unsafePoints.Set(int32(v.ID))
-		}
-		if vi == len(b.Values) {
-			// We marked all values in this block, so no
-			// need to flood this block again.
-			flooded.Set(int32(b.ID))
-		}
-		for _, pred := range b.Preds {
-			flood(pred.Block(), len(pred.Block().Values))
-		}
-	}
-	for _, b := range lv.f.Blocks {
-		for i, v := range b.Values {
-			if !(v.Op == ssa.OpConvert && v.Type.IsPtrShaped()) {
-				continue
-			}
-			// Flood the unsafe-ness of this backwards
-			// until we hit a call.
-			flood(b, i+1)
-		}
-	}
-}
-
-// Returns true for instructions that must have a stack map.
-//
-// This does not necessarily mean the instruction is a safe-point. In
-// particular, call Values can have a stack map in case the callee
-// grows the stack, but not themselves be a safe-point.
-func (lv *Liveness) hasStackMap(v *ssa.Value) bool {
-	if !v.Op.IsCall() {
-		return false
-	}
-	// typedmemclr and typedmemmove are write barriers and
-	// deeply non-preemptible. They are unsafe points and
-	// hence should not have liveness maps.
-	if sym, ok := v.Aux.(*ssa.AuxCall); ok && (sym.Fn == typedmemclr || sym.Fn == typedmemmove) {
-		return false
-	}
-	return true
-}
-
-// 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 (lv *Liveness) prologue() {
-	lv.initcache()
-
-	for _, b := range lv.f.Blocks {
-		be := lv.blockEffects(b)
-
-		// Walk the block instructions backward and update the block
-		// effects with the each prog effects.
-		for j := len(b.Values) - 1; j >= 0; j-- {
-			pos, e := lv.valueEffects(b.Values[j])
-			if e&varkill != 0 {
-				be.varkill.Set(pos)
-				be.uevar.Unset(pos)
-			}
-			if e&uevar != 0 {
-				be.uevar.Set(pos)
-			}
-		}
-	}
-}
-
-// Solve the liveness dataflow equations.
-func (lv *Liveness) solve() {
-	// These temporary bitvectors exist to avoid successive allocations and
-	// frees within the loop.
-	nvars := int32(len(lv.vars))
-	newlivein := bvalloc(nvars)
-	newliveout := bvalloc(nvars)
-
-	// Walk blocks in postorder ordering. This improves convergence.
-	po := lv.f.Postorder()
-
-	// Iterate through the blocks in reverse round-robin fashion. A work
-	// queue might be slightly faster. As is, the number of iterations is
-	// so low that it hardly seems to be worth the complexity.
-
-	for change := true; change; {
-		change = false
-		for _, b := range po {
-			be := lv.blockEffects(b)
-
-			newliveout.Clear()
-			switch b.Kind {
-			case ssa.BlockRet:
-				for _, pos := range lv.cache.retuevar {
-					newliveout.Set(pos)
-				}
-			case ssa.BlockRetJmp:
-				for _, pos := range lv.cache.tailuevar {
-					newliveout.Set(pos)
-				}
-			case ssa.BlockExit:
-				// panic exit - nothing to do
-			default:
-				// A variable is live on output from this block
-				// if it is live on input to some successor.
-				//
-				// out[b] = \bigcup_{s \in succ[b]} in[s]
-				newliveout.Copy(lv.blockEffects(b.Succs[0].Block()).livein)
-				for _, succ := range b.Succs[1:] {
-					newliveout.Or(newliveout, lv.blockEffects(succ.Block()).livein)
-				}
-			}
-
-			if !be.liveout.Eq(newliveout) {
-				change = true
-				be.liveout.Copy(newliveout)
-			}
-
-			// A variable is live on input to this block
-			// if it is used by this block, or live on output from this block and
-			// not set by the code in this block.
-			//
-			// in[b] = uevar[b] \cup (out[b] \setminus varkill[b])
-			newlivein.AndNot(be.liveout, be.varkill)
-			be.livein.Or(newlivein, be.uevar)
-		}
-	}
-}
-
-// Visits all instructions in a basic block and computes a bit vector of live
-// variables at each safe point locations.
-func (lv *Liveness) epilogue() {
-	nvars := int32(len(lv.vars))
-	liveout := bvalloc(nvars)
-	livedefer := bvalloc(nvars) // always-live variables
-
-	// If there is a defer (that could recover), then all output
-	// parameters are live all the time.  In addition, any locals
-	// that are pointers to heap-allocated output parameters are
-	// also always live (post-deferreturn code needs these
-	// pointers to copy values back to the stack).
-	// TODO: if the output parameter is heap-allocated, then we
-	// don't need to keep the stack copy live?
-	if lv.fn.Func.HasDefer() {
-		for i, n := range lv.vars {
-			if n.Class() == PPARAMOUT {
-				if n.Name.IsOutputParamHeapAddr() {
-					// Just to be paranoid.  Heap addresses are PAUTOs.
-					Fatalf("variable %v both output param and heap output param", n)
-				}
-				if n.Name.Param.Heapaddr != nil {
-					// If this variable moved to the heap, then
-					// its stack copy is not live.
-					continue
-				}
-				// Note: zeroing is handled by zeroResults in walk.go.
-				livedefer.Set(int32(i))
-			}
-			if n.Name.IsOutputParamHeapAddr() {
-				// This variable will be overwritten early in the function
-				// prologue (from the result of a mallocgc) but we need to
-				// zero it in case that malloc causes a stack scan.
-				n.Name.SetNeedzero(true)
-				livedefer.Set(int32(i))
-			}
-			if n.Name.OpenDeferSlot() {
-				// Open-coded defer args slots must be live
-				// everywhere in a function, since a panic can
-				// occur (almost) anywhere. Because it is live
-				// everywhere, it must be zeroed on entry.
-				livedefer.Set(int32(i))
-				// It was already marked as Needzero when created.
-				if !n.Name.Needzero() {
-					Fatalf("all pointer-containing defer arg slots should have Needzero set")
-				}
-			}
-		}
-	}
-
-	// We must analyze the entry block first. The runtime assumes
-	// the function entry map is index 0. Conveniently, layout
-	// already ensured that the entry block is first.
-	if lv.f.Entry != lv.f.Blocks[0] {
-		lv.f.Fatalf("entry block must be first")
-	}
-
-	{
-		// Reserve an entry for function entry.
-		live := bvalloc(nvars)
-		lv.livevars = append(lv.livevars, live)
-	}
-
-	for _, b := range lv.f.Blocks {
-		be := lv.blockEffects(b)
-
-		// Walk forward through the basic block instructions and
-		// allocate liveness maps for those instructions that need them.
-		for _, v := range b.Values {
-			if !lv.hasStackMap(v) {
-				continue
-			}
-
-			live := bvalloc(nvars)
-			lv.livevars = append(lv.livevars, live)
-		}
-
-		// walk backward, construct maps at each safe point
-		index := int32(len(lv.livevars) - 1)
-
-		liveout.Copy(be.liveout)
-		for i := len(b.Values) - 1; i >= 0; i-- {
-			v := b.Values[i]
-
-			if lv.hasStackMap(v) {
-				// Found an interesting instruction, record the
-				// corresponding liveness information.
-
-				live := &lv.livevars[index]
-				live.Or(*live, liveout)
-				live.Or(*live, livedefer) // only for non-entry safe points
-				index--
-			}
-
-			// Update liveness information.
-			pos, e := lv.valueEffects(v)
-			if e&varkill != 0 {
-				liveout.Unset(pos)
-			}
-			if e&uevar != 0 {
-				liveout.Set(pos)
-			}
-		}
-
-		if b == lv.f.Entry {
-			if index != 0 {
-				Fatalf("bad index for entry point: %v", index)
-			}
-
-			// Check to make sure only input variables are live.
-			for i, n := range lv.vars {
-				if !liveout.Get(int32(i)) {
-					continue
-				}
-				if n.Class() == PPARAM {
-					continue // ok
-				}
-				Fatalf("bad live variable at entry of %v: %L", lv.fn.Func.Nname, n)
-			}
-
-			// Record live variables.
-			live := &lv.livevars[index]
-			live.Or(*live, liveout)
-		}
-
-		// The liveness maps for this block are now complete. Compact them.
-		lv.compact(b)
-	}
-
-	// If we have an open-coded deferreturn call, make a liveness map for it.
-	if lv.fn.Func.OpenCodedDeferDisallowed() {
-		lv.livenessMap.deferreturn = LivenessDontCare
-	} else {
-		lv.livenessMap.deferreturn = LivenessIndex{
-			stackMapIndex: lv.stackMapSet.add(livedefer),
-			isUnsafePoint: false,
-		}
-	}
-
-	// Done compacting. Throw out the stack map set.
-	lv.stackMaps = lv.stackMapSet.extractUniqe()
-	lv.stackMapSet = bvecSet{}
-
-	// Useful sanity check: on entry to the function,
-	// the only things that can possibly be live are the
-	// input parameters.
-	for j, n := range lv.vars {
-		if n.Class() != PPARAM && lv.stackMaps[0].Get(int32(j)) {
-			lv.f.Fatalf("%v %L recorded as live on entry", lv.fn.Func.Nname, n)
-		}
-	}
-}
-
-// Compact coalesces identical bitmaps from lv.livevars into the sets
-// lv.stackMapSet.
-//
-// Compact clears lv.livevars.
-//
-// There are actually two lists of bitmaps, one list for the local variables and one
-// list for the function arguments. Both lists are indexed by the same PCDATA
-// index, so the corresponding pairs must be considered together when
-// merging duplicates. The argument bitmaps change much less often during
-// function execution than the local variable bitmaps, so it is possible that
-// we could introduce a separate PCDATA index for arguments vs locals and
-// then compact the set of argument bitmaps separately from the set of
-// local variable bitmaps. As of 2014-04-02, doing this to the godoc binary
-// 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 (lv *Liveness) compact(b *ssa.Block) {
-	pos := 0
-	if b == lv.f.Entry {
-		// Handle entry stack map.
-		lv.stackMapSet.add(lv.livevars[0])
-		pos++
-	}
-	for _, v := range b.Values {
-		hasStackMap := lv.hasStackMap(v)
-		isUnsafePoint := lv.allUnsafe || lv.unsafePoints.Get(int32(v.ID))
-		idx := LivenessIndex{StackMapDontCare, isUnsafePoint}
-		if hasStackMap {
-			idx.stackMapIndex = lv.stackMapSet.add(lv.livevars[pos])
-			pos++
-		}
-		if hasStackMap || isUnsafePoint {
-			lv.livenessMap.set(v, idx)
-		}
-	}
-
-	// Reset livevars.
-	lv.livevars = lv.livevars[:0]
-}
-
-func (lv *Liveness) showlive(v *ssa.Value, live bvec) {
-	if debuglive == 0 || lv.fn.funcname() == "init" || strings.HasPrefix(lv.fn.funcname(), ".") {
-		return
-	}
-	if !(v == nil || v.Op.IsCall()) {
-		// Historically we only printed this information at
-		// calls. Keep doing so.
-		return
-	}
-	if live.IsEmpty() {
-		return
-	}
-
-	pos := lv.fn.Func.Nname.Pos
-	if v != nil {
-		pos = v.Pos
-	}
-
-	s := "live at "
-	if v == nil {
-		s += fmt.Sprintf("entry to %s:", lv.fn.funcname())
-	} else if sym, ok := v.Aux.(*ssa.AuxCall); ok && sym.Fn != nil {
-		fn := sym.Fn.Name
-		if pos := strings.Index(fn, "."); pos >= 0 {
-			fn = fn[pos+1:]
-		}
-		s += fmt.Sprintf("call to %s:", fn)
-	} else {
-		s += "indirect call:"
-	}
-
-	for j, n := range lv.vars {
-		if live.Get(int32(j)) {
-			s += fmt.Sprintf(" %v", n)
-		}
-	}
-
-	Warnl(pos, s)
-}
-
-func (lv *Liveness) printbvec(printed bool, name string, live bvec) bool {
-	if live.IsEmpty() {
-		return printed
-	}
-
-	if !printed {
-		fmt.Printf("\t")
-	} else {
-		fmt.Printf(" ")
-	}
-	fmt.Printf("%s=", name)
-
-	comma := ""
-	for i, n := range lv.vars {
-		if !live.Get(int32(i)) {
-			continue
-		}
-		fmt.Printf("%s%s", comma, n.Sym.Name)
-		comma = ","
-	}
-	return true
-}
-
-// printeffect is like printbvec, but for valueEffects.
-func (lv *Liveness) printeffect(printed bool, name string, pos int32, x bool) bool {
-	if !x {
-		return printed
-	}
-	if !printed {
-		fmt.Printf("\t")
-	} else {
-		fmt.Printf(" ")
-	}
-	fmt.Printf("%s=", name)
-	if x {
-		fmt.Printf("%s", lv.vars[pos].Sym.Name)
-	}
-
-	return true
-}
-
-// Prints the computed liveness information and inputs, for debugging.
-// This format synthesizes the information used during the multiple passes
-// into a single presentation.
-func (lv *Liveness) printDebug() {
-	fmt.Printf("liveness: %s\n", lv.fn.funcname())
-
-	for i, b := range lv.f.Blocks {
-		if i > 0 {
-			fmt.Printf("\n")
-		}
-
-		// bb#0 pred=1,2 succ=3,4
-		fmt.Printf("bb#%d pred=", b.ID)
-		for j, pred := range b.Preds {
-			if j > 0 {
-				fmt.Printf(",")
-			}
-			fmt.Printf("%d", pred.Block().ID)
-		}
-		fmt.Printf(" succ=")
-		for j, succ := range b.Succs {
-			if j > 0 {
-				fmt.Printf(",")
-			}
-			fmt.Printf("%d", succ.Block().ID)
-		}
-		fmt.Printf("\n")
-
-		be := lv.blockEffects(b)
-
-		// initial settings
-		printed := false
-		printed = lv.printbvec(printed, "uevar", be.uevar)
-		printed = lv.printbvec(printed, "livein", be.livein)
-		if printed {
-			fmt.Printf("\n")
-		}
-
-		// program listing, with individual effects listed
-
-		if b == lv.f.Entry {
-			live := lv.stackMaps[0]
-			fmt.Printf("(%s) function entry\n", linestr(lv.fn.Func.Nname.Pos))
-			fmt.Printf("\tlive=")
-			printed = false
-			for j, n := range lv.vars {
-				if !live.Get(int32(j)) {
-					continue
-				}
-				if printed {
-					fmt.Printf(",")
-				}
-				fmt.Printf("%v", n)
-				printed = true
-			}
-			fmt.Printf("\n")
-		}
-
-		for _, v := range b.Values {
-			fmt.Printf("(%s) %v\n", linestr(v.Pos), v.LongString())
-
-			pcdata := lv.livenessMap.Get(v)
-
-			pos, effect := lv.valueEffects(v)
-			printed = false
-			printed = lv.printeffect(printed, "uevar", pos, effect&uevar != 0)
-			printed = lv.printeffect(printed, "varkill", pos, effect&varkill != 0)
-			if printed {
-				fmt.Printf("\n")
-			}
-
-			if pcdata.StackMapValid() {
-				fmt.Printf("\tlive=")
-				printed = false
-				if pcdata.StackMapValid() {
-					live := lv.stackMaps[pcdata.stackMapIndex]
-					for j, n := range lv.vars {
-						if !live.Get(int32(j)) {
-							continue
-						}
-						if printed {
-							fmt.Printf(",")
-						}
-						fmt.Printf("%v", n)
-						printed = true
-					}
-				}
-				fmt.Printf("\n")
-			}
-
-			if pcdata.isUnsafePoint {
-				fmt.Printf("\tunsafe-point\n")
-			}
-		}
-
-		// bb bitsets
-		fmt.Printf("end\n")
-		printed = false
-		printed = lv.printbvec(printed, "varkill", be.varkill)
-		printed = lv.printbvec(printed, "liveout", be.liveout)
-		if printed {
-			fmt.Printf("\n")
-		}
-	}
-
-	fmt.Printf("\n")
-}
-
-// Dumps a slice of bitmaps to a symbol as a sequence of uint32 values. The
-// 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 (lv *Liveness) emit() (argsSym, liveSym *obj.LSym) {
-	// Size args bitmaps to be just large enough to hold the largest pointer.
-	// First, find the largest Xoffset node we care about.
-	// (Nodes without pointers aren't in lv.vars; see livenessShouldTrack.)
-	var maxArgNode *Node
-	for _, n := range lv.vars {
-		switch n.Class() {
-		case PPARAM, PPARAMOUT:
-			if maxArgNode == nil || n.Xoffset > maxArgNode.Xoffset {
-				maxArgNode = n
-			}
-		}
-	}
-	// Next, find the offset of the largest pointer in the largest node.
-	var maxArgs int64
-	if maxArgNode != nil {
-		maxArgs = maxArgNode.Xoffset + typeptrdata(maxArgNode.Type)
-	}
-
-	// Size locals bitmaps to be stkptrsize sized.
-	// We cannot shrink them to only hold the largest pointer,
-	// because their size is used to calculate the beginning
-	// of the local variables frame.
-	// Further discussion in https://golang.org/cl/104175.
-	// TODO: consider trimming leading zeros.
-	// This would require shifting all bitmaps.
-	maxLocals := lv.stkptrsize
-
-	// Temporary symbols for encoding bitmaps.
-	var argsSymTmp, liveSymTmp obj.LSym
-
-	args := bvalloc(int32(maxArgs / int64(Widthptr)))
-	aoff := duint32(&argsSymTmp, 0, uint32(len(lv.stackMaps))) // number of bitmaps
-	aoff = duint32(&argsSymTmp, aoff, uint32(args.n))          // number of bits in each bitmap
-
-	locals := bvalloc(int32(maxLocals / int64(Widthptr)))
-	loff := duint32(&liveSymTmp, 0, uint32(len(lv.stackMaps))) // number of bitmaps
-	loff = duint32(&liveSymTmp, loff, uint32(locals.n))        // number of bits in each bitmap
-
-	for _, live := range lv.stackMaps {
-		args.Clear()
-		locals.Clear()
-
-		lv.pointerMap(live, lv.vars, args, locals)
-
-		aoff = dbvec(&argsSymTmp, aoff, args)
-		loff = dbvec(&liveSymTmp, loff, locals)
-	}
-
-	// Give these LSyms content-addressable names,
-	// so that they can be de-duplicated.
-	// This provides significant binary size savings.
-	//
-	// These symbols will be added to Ctxt.Data by addGCLocals
-	// after parallel compilation is done.
-	makeSym := func(tmpSym *obj.LSym) *obj.LSym {
-		return Ctxt.LookupInit(fmt.Sprintf("gclocals·%x", md5.Sum(tmpSym.P)), func(lsym *obj.LSym) {
-			lsym.P = tmpSym.P
-			lsym.Set(obj.AttrContentAddressable, true)
-		})
-	}
-	return makeSym(&argsSymTmp), makeSym(&liveSymTmp)
-}
-
-// Entry pointer for liveness analysis. Solves for the liveness of
-// pointer variables in the function and emits a runtime data
-// structure read by the garbage collector.
-// Returns a map from GC safe points to their corresponding stack map index.
-func liveness(e *ssafn, f *ssa.Func, pp *Progs) LivenessMap {
-	// Construct the global liveness state.
-	vars, idx := getvariables(e.curfn)
-	lv := newliveness(e.curfn, f, vars, idx, e.stkptrsize)
-
-	// Run the dataflow framework.
-	lv.prologue()
-	lv.solve()
-	lv.epilogue()
-	if debuglive > 0 {
-		lv.showlive(nil, lv.stackMaps[0])
-		for _, b := range f.Blocks {
-			for _, val := range b.Values {
-				if idx := lv.livenessMap.Get(val); idx.StackMapValid() {
-					lv.showlive(val, lv.stackMaps[idx.stackMapIndex])
-				}
-			}
-		}
-	}
-	if debuglive >= 2 {
-		lv.printDebug()
-	}
-
-	// Update the function cache.
-	{
-		cache := f.Cache.Liveness.(*livenessFuncCache)
-		if cap(lv.be) < 2000 { // Threshold from ssa.Cache slices.
-			for i := range lv.be {
-				lv.be[i] = BlockEffects{}
-			}
-			cache.be = lv.be
-		}
-		if len(lv.livenessMap.vals) < 2000 {
-			cache.livenessMap = lv.livenessMap
-		}
-	}
-
-	// Emit the live pointer map data structures
-	ls := e.curfn.Func.lsym
-	fninfo := ls.Func()
-	fninfo.GCArgs, fninfo.GCLocals = lv.emit()
-
-	p := pp.Prog(obj.AFUNCDATA)
-	Addrconst(&p.From, objabi.FUNCDATA_ArgsPointerMaps)
-	p.To.Type = obj.TYPE_MEM
-	p.To.Name = obj.NAME_EXTERN
-	p.To.Sym = fninfo.GCArgs
-
-	p = pp.Prog(obj.AFUNCDATA)
-	Addrconst(&p.From, objabi.FUNCDATA_LocalsPointerMaps)
-	p.To.Type = obj.TYPE_MEM
-	p.To.Name = obj.NAME_EXTERN
-	p.To.Sym = fninfo.GCLocals
-
-	return lv.livenessMap
-}
-
-// isfat reports whether a variable of type t needs multiple assignments to initialize.
-// For example:
-//
-// 	type T struct { x, y int }
-// 	x := T{x: 0, y: 1}
-//
-// Then we need:
-//
-// 	var t T
-// 	t.x = 0
-// 	t.y = 1
-//
-// to fully initialize t.
-func isfat(t *types.Type) bool {
-	if t != nil {
-		switch t.Etype {
-		case TSLICE, TSTRING,
-			TINTER: // maybe remove later
-			return true
-		case TARRAY:
-			// Array of 1 element, check if element is fat
-			if t.NumElem() == 1 {
-				return isfat(t.Elem())
-			}
-			return true
-		case TSTRUCT:
-			// Struct with 1 field, check if field is fat
-			if t.NumFields() == 1 {
-				return isfat(t.Field(0).Type)
-			}
-			return true
-		}
-	}
-
-	return false
-}
diff --git a/src/cmd/compile/internal/gc/pprof.go b/src/cmd/compile/internal/gc/pprof.go
index 256c659..5f9b030 100644
--- a/src/cmd/compile/internal/gc/pprof.go
+++ b/src/cmd/compile/internal/gc/pprof.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.8
 // +build go1.8
 
 package gc
diff --git a/src/cmd/compile/internal/gc/racewalk.go b/src/cmd/compile/internal/gc/racewalk.go
deleted file mode 100644
index 3552617..0000000
--- a/src/cmd/compile/internal/gc/racewalk.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
-	"cmd/compile/internal/types"
-	"cmd/internal/src"
-	"cmd/internal/sys"
-)
-
-// The racewalk pass is currently handled in three parts.
-//
-// First, for flag_race, it inserts calls to racefuncenter and
-// racefuncexit at the start and end (respectively) of each
-// function. This is handled below.
-//
-// Second, during buildssa, it inserts appropriate instrumentation
-// calls immediately before each memory load or store. This is handled
-// by the (*state).instrument method in ssa.go, so here we just set
-// the Func.InstrumentBody flag as needed. For background on why this
-// is done during SSA construction rather than a separate SSA pass,
-// see issue #19054.
-//
-// Third we remove calls to racefuncenter and racefuncexit, for leaf
-// functions without instrumented operations. This is done as part of
-// ssa opt pass via special rule.
-
-// TODO(dvyukov): do not instrument initialization as writes:
-// a := make([]int, 10)
-
-// Do not instrument the following packages at all,
-// at best instrumentation would cause infinite recursion.
-var omit_pkgs = []string{
-	"runtime/internal/atomic",
-	"runtime/internal/sys",
-	"runtime/internal/math",
-	"runtime",
-	"runtime/race",
-	"runtime/msan",
-	"internal/cpu",
-}
-
-// Don't insert racefuncenterfp/racefuncexit into the following packages.
-// Memory accesses in the packages are either uninteresting or will cause false positives.
-var norace_inst_pkgs = []string{"sync", "sync/atomic"}
-
-func ispkgin(pkgs []string) bool {
-	if myimportpath != "" {
-		for _, p := range pkgs {
-			if myimportpath == p {
-				return true
-			}
-		}
-	}
-
-	return false
-}
-
-func instrument(fn *Node) {
-	if fn.Func.Pragma&Norace != 0 {
-		return
-	}
-
-	if !flag_race || !ispkgin(norace_inst_pkgs) {
-		fn.Func.SetInstrumentBody(true)
-	}
-
-	if flag_race {
-		lno := lineno
-		lineno = src.NoXPos
-
-		if thearch.LinkArch.Arch.Family != sys.AMD64 {
-			fn.Func.Enter.Prepend(mkcall("racefuncenterfp", nil, nil))
-			fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil))
-		} else {
-
-			// nodpc is the PC of the caller as extracted by
-			// getcallerpc. We use -widthptr(FP) for x86.
-			// This only works for amd64. This will not
-			// work on arm or others that might support
-			// race in the future.
-			nodpc := nodfp.copy()
-			nodpc.Type = types.Types[TUINTPTR]
-			nodpc.Xoffset = int64(-Widthptr)
-			fn.Func.Dcl = append(fn.Func.Dcl, nodpc)
-			fn.Func.Enter.Prepend(mkcall("racefuncenter", nil, nil, nodpc))
-			fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil))
-		}
-		lineno = lno
-	}
-}
diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go
deleted file mode 100644
index 1b4d765..0000000
--- a/src/cmd/compile/internal/gc/range.go
+++ /dev/null
@@ -1,628 +0,0 @@
-// Copyright 2009 The Go Authors. 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/compile/internal/types"
-	"cmd/internal/sys"
-	"unicode/utf8"
-)
-
-// range
-func typecheckrange(n *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.
-	// 1. typecheck produced values,
-	//	this part can declare new vars and so it must be typechecked before body,
-	//	because body can contain a closure that captures the vars.
-	// 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], ctxExpr|ctxAssign)
-		}
-	}
-
-	decldepth++
-	typecheckslice(n.Nbody.Slice(), ctxStmt)
-	decldepth--
-}
-
-func typecheckrangeExpr(n *Node) {
-	n.Right = typecheck(n.Right, ctxExpr)
-
-	t := n.Right.Type
-	if t == nil {
-		return
-	}
-	// delicate little dance.  see typecheckas2
-	ls := n.List.Slice()
-	for i1, n1 := range ls {
-		if n1.Name == nil || n1.Name.Defn != n {
-			ls[i1] = typecheck(ls[i1], ctxExpr|ctxAssign)
-		}
-	}
-
-	if t.IsPtr() && t.Elem().IsArray() {
-		t = t.Elem()
-	}
-	n.Type = t
-
-	var t1, t2 *types.Type
-	toomany := false
-	switch t.Etype {
-	default:
-		yyerrorl(n.Pos, "cannot range over %L", n.Right)
-		return
-
-	case TARRAY, TSLICE:
-		t1 = types.Types[TINT]
-		t2 = t.Elem()
-
-	case TMAP:
-		t1 = t.Key()
-		t2 = t.Elem()
-
-	case TCHAN:
-		if !t.ChanDir().CanRecv() {
-			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 = true
-		}
-
-	case TSTRING:
-		t1 = types.Types[TINT]
-		t2 = types.Runetype
-	}
-
-	if n.List.Len() > 2 || toomany {
-		yyerrorl(n.Pos, "too many variables in range")
-	}
-
-	var v1, v2 *Node
-	if n.List.Len() != 0 {
-		v1 = n.List.First()
-	}
-	if n.List.Len() > 1 {
-		v2 = n.List.Second()
-	}
-
-	// this is not only an optimization but also a requirement in the spec.
-	// "if the second iteration variable is the blank identifier, the range
-	// clause is equivalent to the same clause with only the first variable
-	// present."
-	if v2.isBlank() {
-		if v1 != nil {
-			n.List.Set1(v1)
-		}
-		v2 = nil
-	}
-
-	if v1 != nil {
-		if v1.Name != nil && v1.Name.Defn == n {
-			v1.Type = t1
-		} else if v1.Type != nil {
-			if op, why := assignop(t1, v1.Type); op == OXXX {
-				yyerrorl(n.Pos, "cannot assign type %v to %L in range%s", t1, v1, why)
-			}
-		}
-		checkassign(n, v1)
-	}
-
-	if v2 != nil {
-		if v2.Name != nil && v2.Name.Defn == n {
-			v2.Type = t2
-		} else if v2.Type != nil {
-			if op, why := assignop(t2, v2.Type); op == OXXX {
-				yyerrorl(n.Pos, "cannot assign type %v to %L in range%s", t2, v2, why)
-			}
-		}
-		checkassign(n, v2)
-	}
-}
-
-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
-		}
-	}
-	return false
-}
-
-// walkrange transforms various forms of ORANGE into
-// simpler forms.  The result must be assigned back to n.
-// Node n may also be modified in place, and may also be
-// the returned node.
-func walkrange(n *Node) *Node {
-	if isMapClear(n) {
-		m := n.Right
-		lno := setlineno(m)
-		n = mapClear(m)
-		lineno = lno
-		return n
-	}
-
-	// variable name conventions:
-	//	ohv1, hv1, hv2: hidden (old) val 1, 2
-	//	ha, hit: hidden aggregate, iterator
-	//	hn, hp: hidden len, pointer
-	//	hb: hidden bool
-	//	a, v1, v2: not hidden aggregate, val 1, 2
-
-	t := n.Type
-
-	a := n.Right
-	lno := setlineno(a)
-	n.Right = nil
-
-	var v1, v2 *Node
-	l := n.List.Len()
-	if l > 0 {
-		v1 = n.List.First()
-	}
-
-	if l > 1 {
-		v2 = n.List.Second()
-	}
-
-	if v2.isBlank() {
-		v2 = nil
-	}
-
-	if v1.isBlank() && v2 == nil {
-		v1 = nil
-	}
-
-	if v1 == nil && v2 != nil {
-		Fatalf("walkrange: v2 != nil while v1 == nil")
-	}
-
-	// 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 {
-	default:
-		Fatalf("walkrange")
-
-	case TARRAY, TSLICE:
-		if arrayClear(n, v1, v2, a) {
-			lineno = lno
-			return n
-		}
-
-		// order.stmt arranged for a copy of the array/slice variable if needed.
-		ha := a
-
-		hv1 := temp(types.Types[TINT])
-		hn := temp(types.Types[TINT])
-
-		init = append(init, nod(OAS, hv1, nil))
-		init = append(init, nod(OAS, hn, nod(OLEN, ha, nil)))
-
-		n.Left = nod(OLT, hv1, hn)
-		n.Right = nod(OAS, hv1, nod(OADD, hv1, nodintconst(1)))
-
-		// 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, tmp)
-			body = []*Node{a}
-			break
-		}
-
-		// TODO(austin): OFORUNTIL is a strange beast, but is
-		// necessary for expressing the control flow we need
-		// while also making "break" and "continue" work. It
-		// would be nice to just lower ORANGE during SSA, but
-		// racewalk needs to see many of the operations
-		// involved in ORANGE's implementation. If racewalk
-		// moves into SSA, consider moving ORANGE into SSA and
-		// eliminating OFORUNTIL.
-
-		// TODO(austin): OFORUNTIL inhibits bounds-check
-		// elimination on the index variable (see #20711).
-		// Enhance the prove pass to understand this.
-		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(ODEREF, hp, nil))
-		body = append(body, a)
-
-		// Advance pointer as part of the late increment.
-		//
-		// This runs *after* the condition check, so we know
-		// advancing the pointer is safe and won't go past the
-		// end of the allocation.
-		a = nod(OAS, hp, addptr(hp, t.Elem().Width))
-		a = typecheck(a, ctxStmt)
-		n.List.Set1(a)
-
-	case TMAP:
-		// order.stmt allocated the iterator for us.
-		// we only use a once, so no copy needed.
-		ha := a
-
-		hit := prealloc[n]
-		th := hit.Type
-		n.Left = nil
-		keysym := th.Field(0).Sym  // depends on layout of iterator struct.  See reflect.go:hiter
-		elemsym := th.Field(1).Sym // ditto
-
-		fn := syslook("mapiterinit")
-
-		fn = substArgTypes(fn, t.Key(), t.Elem(), th)
-		init = append(init, mkcall1(fn, nil, nil, typename(t), ha, nod(OADDR, hit, nil)))
-		n.Left = nod(ONE, nodSym(ODOT, hit, keysym), nodnil())
-
-		fn = syslook("mapiternext")
-		fn = substArgTypes(fn, th)
-		n.Right = mkcall1(fn, nil, nil, nod(OADDR, hit, nil))
-
-		key := nodSym(ODOT, hit, keysym)
-		key = nod(ODEREF, key, nil)
-		if v1 == nil {
-			body = nil
-		} else if v2 == nil {
-			body = []*Node{nod(OAS, v1, key)}
-		} else {
-			elem := nodSym(ODOT, hit, elemsym)
-			elem = nod(ODEREF, elem, nil)
-			a := nod(OAS2, nil, nil)
-			a.List.Set2(v1, v2)
-			a.Rlist.Set2(key, elem)
-			body = []*Node{a}
-		}
-
-	case TCHAN:
-		// order.stmt arranged for a copy of the channel variable.
-		ha := a
-
-		n.Left = nil
-
-		hv1 := temp(t.Elem())
-		hv1.SetTypecheck(1)
-		if t.Elem().HasPointers() {
-			init = append(init, nod(OAS, hv1, nil))
-		}
-		hb := temp(types.Types[TBOOL])
-
-		n.Left = nod(ONE, hb, nodbool(false))
-		a := nod(OAS2RECV, nil, nil)
-		a.SetTypecheck(1)
-		a.List.Set2(hv1, hb)
-		a.Right = nod(ORECV, ha, nil)
-		n.Left.Ninit.Set1(a)
-		if v1 == nil {
-			body = nil
-		} else {
-			body = []*Node{nod(OAS, v1, hv1)}
-		}
-		// Zero hv1. This prevents hv1 from being the sole, inaccessible
-		// reference to an otherwise GC-able value during the next channel receive.
-		// See issue 15281.
-		body = append(body, nod(OAS, hv1, nil))
-
-	case TSTRING:
-		// Transform string range statements like "for v1, v2 = range a" into
-		//
-		// ha := a
-		// for hv1 := 0; hv1 < len(ha); {
-		//   hv1t := hv1
-		//   hv2 := rune(ha[hv1])
-		//   if hv2 < utf8.RuneSelf {
-		//      hv1++
-		//   } else {
-		//      hv2, hv1 = decoderune(ha, hv1)
-		//   }
-		//   v1, v2 = hv1t, hv2
-		//   // original body
-		// }
-
-		// order.stmt arranged for a copy of the string variable.
-		ha := a
-
-		hv1 := temp(types.Types[TINT])
-		hv1t := temp(types.Types[TINT])
-		hv2 := temp(types.Runetype)
-
-		// hv1 := 0
-		init = append(init, nod(OAS, hv1, nil))
-
-		// hv1 < len(ha)
-		n.Left = nod(OLT, hv1, nod(OLEN, ha, nil))
-
-		if v1 != nil {
-			// hv1t = hv1
-			body = append(body, nod(OAS, hv1t, hv1))
-		}
-
-		// hv2 := rune(ha[hv1])
-		nind := nod(OINDEX, ha, hv1)
-		nind.SetBounded(true)
-		body = append(body, nod(OAS, hv2, conv(nind, types.Runetype)))
-
-		// if hv2 < utf8.RuneSelf
-		nif := nod(OIF, nil, nil)
-		nif.Left = nod(OLT, hv2, nodintconst(utf8.RuneSelf))
-
-		// hv1++
-		nif.Nbody.Set1(nod(OAS, hv1, nod(OADD, hv1, nodintconst(1))))
-
-		// } else {
-		eif := nod(OAS2, nil, nil)
-		nif.Rlist.Set1(eif)
-
-		// hv2, hv1 = decoderune(ha, hv1)
-		eif.List.Set2(hv2, hv1)
-		fn := syslook("decoderune")
-		eif.Rlist.Set1(mkcall1(fn, fn.Type.Results(), nil, ha, hv1))
-
-		body = append(body, nif)
-
-		if v1 != nil {
-			if v2 != nil {
-				// v1, v2 = hv1t, hv2
-				a := nod(OAS2, nil, nil)
-				a.List.Set2(v1, v2)
-				a.Rlist.Set2(hv1t, hv2)
-				body = append(body, a)
-			} else {
-				// v1 = hv1t
-				body = append(body, nod(OAS, v1, hv1t))
-			}
-		}
-	}
-
-	n.Op = translatedLoopOp
-	typecheckslice(init, ctxStmt)
-
-	if ifGuard != nil {
-		ifGuard.Ninit.Append(init...)
-		ifGuard = typecheck(ifGuard, ctxStmt)
-	} else {
-		n.Ninit.Append(init...)
-	}
-
-	typecheckslice(n.Left.Ninit.Slice(), ctxStmt)
-
-	n.Left = typecheck(n.Left, ctxExpr)
-	n.Left = defaultlit(n.Left, nil)
-	n.Right = typecheck(n.Right, ctxStmt)
-	typecheckslice(body, ctxStmt)
-	n.Nbody.Prepend(body...)
-
-	if ifGuard != nil {
-		ifGuard.Nbody.Set1(n)
-		n = ifGuard
-	}
-
-	n = walkstmt(n)
-
-	lineno = lno
-	return n
-}
-
-// isMapClear checks if n is of the form:
-//
-// for k := range m {
-//   delete(m, k)
-// }
-//
-// where == for keys of map m is reflexive.
-func isMapClear(n *Node) bool {
-	if Debug.N != 0 || instrumenting {
-		return false
-	}
-
-	if n.Op != ORANGE || n.Type.Etype != TMAP || n.List.Len() != 1 {
-		return false
-	}
-
-	k := n.List.First()
-	if k == nil || k.isBlank() {
-		return false
-	}
-
-	// Require k to be a new variable name.
-	if k.Name == nil || k.Name.Defn != n {
-		return false
-	}
-
-	if n.Nbody.Len() != 1 {
-		return false
-	}
-
-	stmt := n.Nbody.First() // only stmt in body
-	if stmt == nil || stmt.Op != ODELETE {
-		return false
-	}
-
-	m := n.Right
-	if !samesafeexpr(stmt.List.First(), m) || !samesafeexpr(stmt.List.Second(), k) {
-		return false
-	}
-
-	// Keys where equality is not reflexive can not be deleted from maps.
-	if !isreflexive(m.Type.Key()) {
-		return false
-	}
-
-	return true
-}
-
-// mapClear constructs a call to runtime.mapclear for the map m.
-func mapClear(m *Node) *Node {
-	t := m.Type
-
-	// instantiate mapclear(typ *type, hmap map[any]any)
-	fn := syslook("mapclear")
-	fn = substArgTypes(fn, t.Key(), t.Elem())
-	n := mkcall1(fn, nil, nil, typename(t), m)
-
-	n = typecheck(n, ctxStmt)
-	n = walkstmt(n)
-
-	return n
-}
-
-// Lower n into runtime·memclr if possible, for
-// fast zeroing of slices and arrays (issue 5373).
-// Look for instances of
-//
-// for i := range a {
-// 	a[i] = zero
-// }
-//
-// in which the evaluation of a is side-effect-free.
-//
-// Parameters are as in walkrange: "for v1, v2 = range a".
-func arrayClear(n, v1, v2, a *Node) bool {
-	if Debug.N != 0 || instrumenting {
-		return false
-	}
-
-	if v1 == nil || v2 != nil {
-		return false
-	}
-
-	if n.Nbody.Len() != 1 || n.Nbody.First() == nil {
-		return false
-	}
-
-	stmt := n.Nbody.First() // only stmt in body
-	if stmt.Op != OAS || stmt.Left.Op != OINDEX {
-		return false
-	}
-
-	if !samesafeexpr(stmt.Left.Left, a) || !samesafeexpr(stmt.Left.Right, v1) {
-		return false
-	}
-
-	elemsize := n.Type.Elem().Width
-	if elemsize <= 0 || !isZero(stmt.Right) {
-		return false
-	}
-
-	// Convert to
-	// if len(a) != 0 {
-	// 	hp = &a[0]
-	// 	hn = len(a)*sizeof(elem(a))
-	// 	memclr{NoHeap,Has}Pointers(hp, hn)
-	// 	i = len(a) - 1
-	// }
-	n.Op = OIF
-
-	n.Nbody.Set(nil)
-	n.Left = nod(ONE, nod(OLEN, a, nil), nodintconst(0))
-
-	// hp = &a[0]
-	hp := temp(types.Types[TUNSAFEPTR])
-
-	tmp := nod(OINDEX, a, nodintconst(0))
-	tmp.SetBounded(true)
-	tmp = nod(OADDR, tmp, nil)
-	tmp = convnop(tmp, types.Types[TUNSAFEPTR])
-	n.Nbody.Append(nod(OAS, hp, tmp))
-
-	// hn = len(a) * sizeof(elem(a))
-	hn := temp(types.Types[TUINTPTR])
-
-	tmp = nod(OLEN, a, nil)
-	tmp = nod(OMUL, tmp, nodintconst(elemsize))
-	tmp = conv(tmp, types.Types[TUINTPTR])
-	n.Nbody.Append(nod(OAS, hn, tmp))
-
-	var fn *Node
-	if a.Type.Elem().HasPointers() {
-		// memclrHasPointers(hp, hn)
-		Curfn.Func.setWBPos(stmt.Pos)
-		fn = mkcall("memclrHasPointers", nil, nil, hp, hn)
-	} else {
-		// memclrNoHeapPointers(hp, hn)
-		fn = mkcall("memclrNoHeapPointers", nil, nil, hp, hn)
-	}
-
-	n.Nbody.Append(fn)
-
-	// i = len(a) - 1
-	v1 = nod(OAS, v1, nod(OSUB, nod(OLEN, a, nil), nodintconst(1)))
-
-	n.Nbody.Append(v1)
-
-	n.Left = typecheck(n.Left, ctxExpr)
-	n.Left = defaultlit(n.Left, nil)
-	typecheckslice(n.Nbody.Slice(), ctxStmt)
-	n = walkstmt(n)
-	return true
-}
-
-// addptr returns (*T)(uintptr(p) + n).
-func addptr(p *Node, n int64) *Node {
-	t := p.Type
-
-	p = nod(OCONVNOP, p, nil)
-	p.Type = types.Types[TUINTPTR]
-
-	p = nod(OADD, p, nodintconst(n))
-
-	p = nod(OCONVNOP, p, nil)
-	p.Type = t
-
-	return p
-}
diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go
deleted file mode 100644
index 9401eba..0000000
--- a/src/cmd/compile/internal/gc/reflect.go
+++ /dev/null
@@ -1,1901 +0,0 @@
-// Copyright 2009 The Go Authors. 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/compile/internal/types"
-	"cmd/internal/gcprog"
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"cmd/internal/src"
-	"fmt"
-	"os"
-	"sort"
-	"strings"
-	"sync"
-)
-
-type itabEntry struct {
-	t, itype *types.Type
-	lsym     *obj.LSym // symbol of the itab itself
-
-	// symbols of each method in
-	// the itab, sorted by byte offset;
-	// filled in by peekitabs
-	entries []*obj.LSym
-}
-
-type ptabEntry struct {
-	s *types.Sym
-	t *types.Type
-}
-
-// runtime interface and reflection data structures
-var (
-	signatmu    sync.Mutex // protects signatset and signatslice
-	signatset   = make(map[*types.Type]struct{})
-	signatslice []*types.Type
-
-	itabs []itabEntry
-	ptabs []ptabEntry
-)
-
-type Sig struct {
-	name  *types.Sym
-	isym  *types.Sym
-	tsym  *types.Sym
-	type_ *types.Type
-	mtype *types.Type
-}
-
-// Builds a type representing a Bucket structure for
-// the given map type. This type is not visible to users -
-// we include only enough information to generate a correct GC
-// program for it.
-// Make sure this stays in sync with runtime/map.go.
-const (
-	BUCKETSIZE  = 8
-	MAXKEYSIZE  = 128
-	MAXELEMSIZE = 128
-)
-
-func structfieldSize() int { return 3 * Widthptr }       // Sizeof(runtime.structfield{})
-func imethodSize() int     { return 4 + 4 }              // Sizeof(runtime.imethod{})
-func commonSize() int      { return 4*Widthptr + 8 + 8 } // Sizeof(runtime._type{})
-
-func uncommonSize(t *types.Type) int { // Sizeof(runtime.uncommontype{})
-	if t.Sym == nil && len(methods(t)) == 0 {
-		return 0
-	}
-	return 4 + 2 + 2 + 4 + 4
-}
-
-func makefield(name string, t *types.Type) *types.Field {
-	f := types.NewField()
-	f.Type = t
-	f.Sym = (*types.Pkg)(nil).Lookup(name)
-	return f
-}
-
-// 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
-	}
-
-	bucket := types.New(TSTRUCT)
-	keytype := t.Key()
-	elemtype := t.Elem()
-	dowidth(keytype)
-	dowidth(elemtype)
-	if keytype.Width > MAXKEYSIZE {
-		keytype = types.NewPtr(keytype)
-	}
-	if elemtype.Width > MAXELEMSIZE {
-		elemtype = types.NewPtr(elemtype)
-	}
-
-	field := make([]*types.Field, 0, 5)
-
-	// The first field is: uint8 topbits[BUCKETSIZE].
-	arr := types.NewArray(types.Types[TUINT8], BUCKETSIZE)
-	field = append(field, makefield("topbits", arr))
-
-	arr = types.NewArray(keytype, BUCKETSIZE)
-	arr.SetNoalg(true)
-	keys := makefield("keys", arr)
-	field = append(field, keys)
-
-	arr = types.NewArray(elemtype, BUCKETSIZE)
-	arr.SetNoalg(true)
-	elems := makefield("elems", arr)
-	field = append(field, elems)
-
-	// If keys and elems have no pointers, the map implementation
-	// can keep a list of overflow pointers on the side so that
-	// buckets can be marked as having no pointers.
-	// Arrange for the bucket to have no pointers by changing
-	// the type of the overflow field to uintptr in this case.
-	// See comment on hmap.overflow in runtime/map.go.
-	otyp := types.NewPtr(bucket)
-	if !elemtype.HasPointers() && !keytype.HasPointers() {
-		otyp = types.Types[TUINTPTR]
-	}
-	overflow := makefield("overflow", otyp)
-	field = append(field, overflow)
-
-	// link up fields
-	bucket.SetNoalg(true)
-	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 elemtype.Align > BUCKETSIZE {
-		Fatalf("elem align too big for %v", t)
-	}
-	if keytype.Width > MAXKEYSIZE {
-		Fatalf("key size to large for %v", t)
-	}
-	if elemtype.Width > MAXELEMSIZE {
-		Fatalf("elem size to large for %v", t)
-	}
-	if t.Key().Width > MAXKEYSIZE && !keytype.IsPtr() {
-		Fatalf("key indirect incorrect for %v", t)
-	}
-	if t.Elem().Width > MAXELEMSIZE && !elemtype.IsPtr() {
-		Fatalf("elem 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 elemtype.Width%int64(elemtype.Align) != 0 {
-		Fatalf("elem size not a multiple of elem align for %v", t)
-	}
-	if bucket.Align%keytype.Align != 0 {
-		Fatalf("bucket align not multiple of key align %v", t)
-	}
-	if bucket.Align%elemtype.Align != 0 {
-		Fatalf("bucket align not multiple of elem align %v", t)
-	}
-	if keys.Offset%int64(keytype.Align) != 0 {
-		Fatalf("bad alignment of keys in bmap for %v", t)
-	}
-	if elems.Offset%int64(elemtype.Align) != 0 {
-		Fatalf("bad alignment of elems in bmap for %v", t)
-	}
-
-	// Double-check that overflow field is final memory in struct,
-	// with no padding at end.
-	if overflow.Offset != bucket.Width-int64(Widthptr) {
-		Fatalf("bad offset of overflow in bmap for %v", t)
-	}
-
-	t.MapType().Bucket = bucket
-
-	bucket.StructType().Map = t
-	return bucket
-}
-
-// hmap builds a type representing a Hmap structure for the given map type.
-// Make sure this stays in sync with runtime/map.go.
-func hmap(t *types.Type) *types.Type {
-	if t.MapType().Hmap != nil {
-		return t.MapType().Hmap
-	}
-
-	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/map.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]), // 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("extra", types.Types[TUNSAFEPTR]),
-	}
-
-	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/map.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:
-	// type hiter struct {
-	//    key         *Key
-	//    elem        *Elem
-	//    t           unsafe.Pointer // *MapType
-	//    h           *hmap
-	//    buckets     *bmap
-	//    bptr        *bmap
-	//    overflow    unsafe.Pointer // *[]*bmap
-	//    oldoverflow unsafe.Pointer // *[]*bmap
-	//    startBucket uintptr
-	//    offset      uint8
-	//    wrapped     bool
-	//    B           uint8
-	//    i           uint8
-	//    bucket      uintptr
-	//    checkBucket uintptr
-	// }
-	// must match runtime/map.go:hiter.
-	fields := []*types.Field{
-		makefield("key", types.NewPtr(t.Key())),   // Used in range.go for TMAP.
-		makefield("elem", types.NewPtr(t.Elem())), // 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
-	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 = hiter
-	hiter.StructType().Map = t
-	return hiter
-}
-
-// deferstruct makes a runtime._defer structure, with additional space for
-// stksize bytes of args.
-func deferstruct(stksize int64) *types.Type {
-	makefield := func(name string, typ *types.Type) *types.Field {
-		f := types.NewField()
-		f.Type = typ
-		// Unlike the global makefield function, this one needs to set Pkg
-		// because these types might be compared (in SSA CSE sorting).
-		// TODO: unify this makefield and the global one above.
-		f.Sym = &types.Sym{Name: name, Pkg: localpkg}
-		return f
-	}
-	argtype := types.NewArray(types.Types[TUINT8], stksize)
-	argtype.Width = stksize
-	argtype.Align = 1
-	// These fields must match the ones in runtime/runtime2.go:_defer and
-	// cmd/compile/internal/gc/ssa.go:(*state).call.
-	fields := []*types.Field{
-		makefield("siz", types.Types[TUINT32]),
-		makefield("started", types.Types[TBOOL]),
-		makefield("heap", types.Types[TBOOL]),
-		makefield("openDefer", types.Types[TBOOL]),
-		makefield("sp", types.Types[TUINTPTR]),
-		makefield("pc", types.Types[TUINTPTR]),
-		// Note: the types here don't really matter. Defer structures
-		// are always scanned explicitly during stack copying and GC,
-		// so we make them uintptr type even though they are real pointers.
-		makefield("fn", types.Types[TUINTPTR]),
-		makefield("_panic", types.Types[TUINTPTR]),
-		makefield("link", types.Types[TUINTPTR]),
-		makefield("framepc", types.Types[TUINTPTR]),
-		makefield("varp", types.Types[TUINTPTR]),
-		makefield("fd", types.Types[TUINTPTR]),
-		makefield("args", argtype),
-	}
-
-	// build struct holding the above fields
-	s := types.New(TSTRUCT)
-	s.SetNoalg(true)
-	s.SetFields(fields)
-	s.Width = widstruct(s, s, 0, 1)
-	s.Align = uint8(Widthptr)
-	return s
-}
-
-// f is method type, with receiver.
-// return function type, receiver as first argument (or not).
-func methodfunc(f *types.Type, receiver *types.Type) *types.Type {
-	inLen := f.Params().Fields().Len()
-	if receiver != nil {
-		inLen++
-	}
-	in := make([]*Node, 0, inLen)
-
-	if receiver != nil {
-		d := anonfield(receiver)
-		in = append(in, d)
-	}
-
-	for _, t := range f.Params().Fields().Slice() {
-		d := anonfield(t.Type)
-		d.SetIsDDD(t.IsDDD())
-		in = append(in, d)
-	}
-
-	outLen := f.Results().Fields().Len()
-	out := make([]*Node, 0, outLen)
-	for _, t := range f.Results().Fields().Slice() {
-		d := anonfield(t.Type)
-		out = append(out, d)
-	}
-
-	t := functype(nil, in, out)
-	if f.Nname() != nil {
-		// Link to name of original method function.
-		t.SetNname(f.Nname())
-	}
-
-	return t
-}
-
-// methods returns the methods of the non-interface type t, sorted by name.
-// Generates stub functions as needed.
-func methods(t *types.Type) []*Sig {
-	// method type
-	mt := methtype(t)
-
-	if mt == nil {
-		return nil
-	}
-	expandmeth(mt)
-
-	// type stored in interface word
-	it := t
-
-	if !isdirectiface(it) {
-		it = types.NewPtr(t)
-	}
-
-	// make list of methods for t,
-	// generating code if necessary.
-	var ms []*Sig
-	for _, f := range mt.AllMethods().Slice() {
-		if !f.IsMethod() {
-			Fatalf("non-method on %v method %v %v\n", mt, f.Sym, f)
-		}
-		if f.Type.Recv() == nil {
-			Fatalf("receiver with no type on %v method %v %v\n", mt, f.Sym, f)
-		}
-		if f.Nointerface() {
-			continue
-		}
-
-		method := f.Sym
-		if method == nil {
-			break
-		}
-
-		// get receiver type for this particular method.
-		// if pointer receiver but non-pointer t and
-		// this is not an embedded pointer inside a struct,
-		// method does not apply.
-		if !isMethodApplicable(t, f) {
-			continue
-		}
-
-		sig := &Sig{
-			name:  method,
-			isym:  methodSym(it, method),
-			tsym:  methodSym(t, method),
-			type_: methodfunc(f.Type, t),
-			mtype: methodfunc(f.Type, nil),
-		}
-		ms = append(ms, sig)
-
-		this := f.Type.Recv().Type
-
-		if !sig.isym.Siggen() {
-			sig.isym.SetSiggen(true)
-			if !types.Identical(this, it) {
-				genwrapper(it, f, sig.isym)
-			}
-		}
-
-		if !sig.tsym.Siggen() {
-			sig.tsym.SetSiggen(true)
-			if !types.Identical(this, t) {
-				genwrapper(t, f, sig.tsym)
-			}
-		}
-	}
-
-	return ms
-}
-
-// imethods returns the methods of the interface type t, sorted by name.
-func imethods(t *types.Type) []*Sig {
-	var methods []*Sig
-	for _, f := range t.Fields().Slice() {
-		if f.Type.Etype != TFUNC || f.Sym == nil {
-			continue
-		}
-		if f.Sym.IsBlank() {
-			Fatalf("unexpected blank symbol in interface method set")
-		}
-		if n := len(methods); n > 0 {
-			last := methods[n-1]
-			if !last.name.Less(f.Sym) {
-				Fatalf("sigcmp vs sortinter %v %v", last.name, f.Sym)
-			}
-		}
-
-		sig := &Sig{
-			name:  f.Sym,
-			mtype: f.Type,
-			type_: methodfunc(f.Type, nil),
-		}
-		methods = append(methods, sig)
-
-		// NOTE(rsc): Perhaps an oversight that
-		// IfaceType.Method is not in the reflect data.
-		// Generate the method body, so that compiled
-		// code can refer to it.
-		isym := methodSym(t, f.Sym)
-		if !isym.Siggen() {
-			isym.SetSiggen(true)
-			genwrapper(t, f, isym)
-		}
-	}
-
-	return methods
-}
-
-func dimportpath(p *types.Pkg) {
-	if p.Pathsym != nil {
-		return
-	}
-
-	// If we are compiling the runtime package, there are two runtime packages around
-	// -- localpkg and Runtimepkg. We don't want to produce import path symbols for
-	// both of them, so just produce one for localpkg.
-	if myimportpath == "runtime" && p == Runtimepkg {
-		return
-	}
-
-	str := p.Path
-	if p == localpkg {
-		// Note: myimportpath != "", or else dgopkgpath won't call dimportpath.
-		str = myimportpath
-	}
-
-	s := Ctxt.Lookup("type..importpath." + p.Prefix + ".")
-	ot := dnameData(s, 0, str, "", nil, false)
-	ggloblsym(s, int32(ot), obj.DUPOK|obj.RODATA)
-	s.Set(obj.AttrContentAddressable, true)
-	p.Pathsym = s
-}
-
-func dgopkgpath(s *obj.LSym, ot int, pkg *types.Pkg) int {
-	if pkg == nil {
-		return duintptr(s, ot, 0)
-	}
-
-	if pkg == localpkg && myimportpath == "" {
-		// If we don't know the full import path of the package being compiled
-		// (i.e. -p was not passed on the compiler command line), emit a reference to
-		// type..importpath.""., which the linker will rewrite using the correct import path.
-		// Every package that imports this one directly defines the symbol.
-		// See also https://groups.google.com/forum/#!topic/golang-dev/myb9s53HxGQ.
-		ns := Ctxt.Lookup(`type..importpath."".`)
-		return dsymptr(s, ot, ns, 0)
-	}
-
-	dimportpath(pkg)
-	return dsymptr(s, ot, pkg.Pathsym, 0)
-}
-
-// dgopkgpathOff writes an offset relocation in s at offset ot to the pkg path symbol.
-func dgopkgpathOff(s *obj.LSym, ot int, pkg *types.Pkg) int {
-	if pkg == nil {
-		return duint32(s, ot, 0)
-	}
-	if pkg == localpkg && myimportpath == "" {
-		// If we don't know the full import path of the package being compiled
-		// (i.e. -p was not passed on the compiler command line), emit a reference to
-		// type..importpath.""., which the linker will rewrite using the correct import path.
-		// Every package that imports this one directly defines the symbol.
-		// See also https://groups.google.com/forum/#!topic/golang-dev/myb9s53HxGQ.
-		ns := Ctxt.Lookup(`type..importpath."".`)
-		return dsymptrOff(s, ot, ns)
-	}
-
-	dimportpath(pkg)
-	return dsymptrOff(s, ot, pkg.Pathsym)
-}
-
-// dnameField dumps a reflect.name for a struct field.
-func dnameField(lsym *obj.LSym, ot int, spkg *types.Pkg, ft *types.Field) int {
-	if !types.IsExported(ft.Sym.Name) && ft.Sym.Pkg != spkg {
-		Fatalf("package mismatch for %v", ft.Sym)
-	}
-	nsym := dname(ft.Sym.Name, ft.Note, nil, types.IsExported(ft.Sym.Name))
-	return dsymptr(lsym, ot, nsym, 0)
-}
-
-// dnameData writes the contents of a reflect.name into s at offset ot.
-func dnameData(s *obj.LSym, ot int, name, tag string, pkg *types.Pkg, exported bool) int {
-	if len(name) > 1<<16-1 {
-		Fatalf("name too long: %s", name)
-	}
-	if len(tag) > 1<<16-1 {
-		Fatalf("tag too long: %s", tag)
-	}
-
-	// Encode name and tag. See reflect/type.go for details.
-	var bits byte
-	l := 1 + 2 + len(name)
-	if exported {
-		bits |= 1 << 0
-	}
-	if len(tag) > 0 {
-		l += 2 + len(tag)
-		bits |= 1 << 1
-	}
-	if pkg != nil {
-		bits |= 1 << 2
-	}
-	b := make([]byte, l)
-	b[0] = bits
-	b[1] = uint8(len(name) >> 8)
-	b[2] = uint8(len(name))
-	copy(b[3:], name)
-	if len(tag) > 0 {
-		tb := b[3+len(name):]
-		tb[0] = uint8(len(tag) >> 8)
-		tb[1] = uint8(len(tag))
-		copy(tb[2:], tag)
-	}
-
-	ot = int(s.WriteBytes(Ctxt, int64(ot), b))
-
-	if pkg != nil {
-		ot = dgopkgpathOff(s, ot, pkg)
-	}
-
-	return ot
-}
-
-var dnameCount int
-
-// dname creates a reflect.name for a struct field or method.
-func dname(name, tag string, pkg *types.Pkg, exported bool) *obj.LSym {
-	// Write out data as "type.." to signal two things to the
-	// linker, first that when dynamically linking, the symbol
-	// should be moved to a relro section, and second that the
-	// contents should not be decoded as a type.
-	sname := "type..namedata."
-	if pkg == nil {
-		// In the common case, share data with other packages.
-		if name == "" {
-			if exported {
-				sname += "-noname-exported." + tag
-			} else {
-				sname += "-noname-unexported." + tag
-			}
-		} else {
-			if exported {
-				sname += name + "." + tag
-			} else {
-				sname += name + "-" + tag
-			}
-		}
-	} else {
-		sname = fmt.Sprintf(`%s"".%d`, sname, dnameCount)
-		dnameCount++
-	}
-	s := Ctxt.Lookup(sname)
-	if len(s.P) > 0 {
-		return s
-	}
-	ot := dnameData(s, 0, name, tag, pkg, exported)
-	ggloblsym(s, int32(ot), obj.DUPOK|obj.RODATA)
-	s.Set(obj.AttrContentAddressable, true)
-	return s
-}
-
-// dextratype dumps the fields of a runtime.uncommontype.
-// dataAdd is the offset in bytes after the header where the
-// backing array of the []method field is written (by dextratypeData).
-func dextratype(lsym *obj.LSym, ot int, t *types.Type, dataAdd int) int {
-	m := methods(t)
-	if t.Sym == nil && len(m) == 0 {
-		return ot
-	}
-	noff := int(Rnd(int64(ot), int64(Widthptr)))
-	if noff != ot {
-		Fatalf("unexpected alignment in dextratype for %v", t)
-	}
-
-	for _, a := range m {
-		dtypesym(a.type_)
-	}
-
-	ot = dgopkgpathOff(lsym, ot, typePkg(t))
-
-	dataAdd += uncommonSize(t)
-	mcount := len(m)
-	if mcount != int(uint16(mcount)) {
-		Fatalf("too many methods on %v: %d", t, mcount)
-	}
-	xcount := sort.Search(mcount, func(i int) bool { return !types.IsExported(m[i].name.Name) })
-	if dataAdd != int(uint32(dataAdd)) {
-		Fatalf("methods are too far away on %v: %d", t, dataAdd)
-	}
-
-	ot = duint16(lsym, ot, uint16(mcount))
-	ot = duint16(lsym, ot, uint16(xcount))
-	ot = duint32(lsym, ot, uint32(dataAdd))
-	ot = duint32(lsym, ot, 0)
-	return ot
-}
-
-func typePkg(t *types.Type) *types.Pkg {
-	tsym := t.Sym
-	if tsym == nil {
-		switch t.Etype {
-		case TARRAY, TSLICE, TPTR, TCHAN:
-			if t.Elem() != nil {
-				tsym = t.Elem().Sym
-			}
-		}
-	}
-	if tsym != nil && t != types.Types[t.Etype] && t != types.Errortype {
-		return tsym.Pkg
-	}
-	return nil
-}
-
-// dextratypeData dumps the backing array for the []method field of
-// runtime.uncommontype.
-func dextratypeData(lsym *obj.LSym, ot int, t *types.Type) int {
-	for _, a := range methods(t) {
-		// ../../../../runtime/type.go:/method
-		exported := types.IsExported(a.name.Name)
-		var pkg *types.Pkg
-		if !exported && a.name.Pkg != typePkg(t) {
-			pkg = a.name.Pkg
-		}
-		nsym := dname(a.name.Name, "", pkg, exported)
-
-		ot = dsymptrOff(lsym, ot, nsym)
-		ot = dmethodptrOff(lsym, ot, dtypesym(a.mtype))
-		ot = dmethodptrOff(lsym, ot, a.isym.Linksym())
-		ot = dmethodptrOff(lsym, ot, a.tsym.Linksym())
-	}
-	return ot
-}
-
-func dmethodptrOff(s *obj.LSym, ot int, x *obj.LSym) int {
-	duint32(s, ot, 0)
-	r := obj.Addrel(s)
-	r.Off = int32(ot)
-	r.Siz = 4
-	r.Sym = x
-	r.Type = objabi.R_METHODOFF
-	return ot + 4
-}
-
-var kinds = []int{
-	TINT:        objabi.KindInt,
-	TUINT:       objabi.KindUint,
-	TINT8:       objabi.KindInt8,
-	TUINT8:      objabi.KindUint8,
-	TINT16:      objabi.KindInt16,
-	TUINT16:     objabi.KindUint16,
-	TINT32:      objabi.KindInt32,
-	TUINT32:     objabi.KindUint32,
-	TINT64:      objabi.KindInt64,
-	TUINT64:     objabi.KindUint64,
-	TUINTPTR:    objabi.KindUintptr,
-	TFLOAT32:    objabi.KindFloat32,
-	TFLOAT64:    objabi.KindFloat64,
-	TBOOL:       objabi.KindBool,
-	TSTRING:     objabi.KindString,
-	TPTR:        objabi.KindPtr,
-	TSTRUCT:     objabi.KindStruct,
-	TINTER:      objabi.KindInterface,
-	TCHAN:       objabi.KindChan,
-	TMAP:        objabi.KindMap,
-	TARRAY:      objabi.KindArray,
-	TSLICE:      objabi.KindSlice,
-	TFUNC:       objabi.KindFunc,
-	TCOMPLEX64:  objabi.KindComplex64,
-	TCOMPLEX128: objabi.KindComplex128,
-	TUNSAFEPTR:  objabi.KindUnsafePointer,
-}
-
-// typeptrdata returns the length in bytes of the prefix of t
-// containing pointer data. Anything after this offset is scalar data.
-func typeptrdata(t *types.Type) int64 {
-	if !t.HasPointers() {
-		return 0
-	}
-
-	switch t.Etype {
-	case TPTR,
-		TUNSAFEPTR,
-		TFUNC,
-		TCHAN,
-		TMAP:
-		return int64(Widthptr)
-
-	case TSTRING:
-		// struct { byte *str; intgo len; }
-		return int64(Widthptr)
-
-	case TINTER:
-		// struct { Itab *tab;	void *data; } or
-		// struct { Type *type; void *data; }
-		// Note: see comment in plive.go:onebitwalktype1.
-		return 2 * int64(Widthptr)
-
-	case TSLICE:
-		// struct { byte *array; uintgo len; uintgo cap; }
-		return int64(Widthptr)
-
-	case TARRAY:
-		// haspointers already eliminated t.NumElem() == 0.
-		return (t.NumElem()-1)*t.Elem().Width + typeptrdata(t.Elem())
-
-	case TSTRUCT:
-		// Find the last field that has pointers.
-		var lastPtrField *types.Field
-		for _, t1 := range t.Fields().Slice() {
-			if t1.Type.HasPointers() {
-				lastPtrField = t1
-			}
-		}
-		return lastPtrField.Offset + typeptrdata(lastPtrField.Type)
-
-	default:
-		Fatalf("typeptrdata: unexpected type, %v", t)
-		return 0
-	}
-}
-
-// tflag is documented in reflect/type.go.
-//
-// tflag values must be kept in sync with copies in:
-//	cmd/compile/internal/gc/reflect.go
-//	cmd/link/internal/ld/decodesym.go
-//	reflect/type.go
-//	runtime/type.go
-const (
-	tflagUncommon      = 1 << 0
-	tflagExtraStar     = 1 << 1
-	tflagNamed         = 1 << 2
-	tflagRegularMemory = 1 << 3
-)
-
-var (
-	memhashvarlen  *obj.LSym
-	memequalvarlen *obj.LSym
-)
-
-// dcommontype dumps the contents of a reflect.rtype (runtime._type).
-func dcommontype(lsym *obj.LSym, t *types.Type) int {
-	dowidth(t)
-	eqfunc := geneq(t)
-
-	sptrWeak := true
-	var sptr *obj.LSym
-	if !t.IsPtr() || t.IsPtrElem() {
-		tptr := types.NewPtr(t)
-		if t.Sym != nil || methods(tptr) != nil {
-			sptrWeak = false
-		}
-		sptr = dtypesym(tptr)
-	}
-
-	gcsym, useGCProg, ptrdata := dgcsym(t)
-
-	// ../../../../reflect/type.go:/^type.rtype
-	// actual type structure
-	//	type rtype struct {
-	//		size          uintptr
-	//		ptrdata       uintptr
-	//		hash          uint32
-	//		tflag         tflag
-	//		align         uint8
-	//		fieldAlign    uint8
-	//		kind          uint8
-	//		equal         func(unsafe.Pointer, unsafe.Pointer) bool
-	//		gcdata        *byte
-	//		str           nameOff
-	//		ptrToThis     typeOff
-	//	}
-	ot := 0
-	ot = duintptr(lsym, ot, uint64(t.Width))
-	ot = duintptr(lsym, ot, uint64(ptrdata))
-	ot = duint32(lsym, ot, typehash(t))
-
-	var tflag uint8
-	if uncommonSize(t) != 0 {
-		tflag |= tflagUncommon
-	}
-	if t.Sym != nil && t.Sym.Name != "" {
-		tflag |= tflagNamed
-	}
-	if IsRegularMemory(t) {
-		tflag |= tflagRegularMemory
-	}
-
-	exported := false
-	p := t.LongString()
-	// If we're writing out type T,
-	// we are very likely to write out type *T as well.
-	// Use the string "*T"[1:] for "T", so that the two
-	// share storage. This is a cheap way to reduce the
-	// amount of space taken up by reflect strings.
-	if !strings.HasPrefix(p, "*") {
-		p = "*" + p
-		tflag |= tflagExtraStar
-		if t.Sym != nil {
-			exported = types.IsExported(t.Sym.Name)
-		}
-	} else {
-		if t.Elem() != nil && t.Elem().Sym != nil {
-			exported = types.IsExported(t.Elem().Sym.Name)
-		}
-	}
-
-	ot = duint8(lsym, ot, tflag)
-
-	// runtime (and common sense) expects alignment to be a power of two.
-	i := int(t.Align)
-
-	if i == 0 {
-		i = 1
-	}
-	if i&(i-1) != 0 {
-		Fatalf("invalid alignment %d for %v", t.Align, t)
-	}
-	ot = duint8(lsym, ot, t.Align) // align
-	ot = duint8(lsym, ot, t.Align) // fieldAlign
-
-	i = kinds[t.Etype]
-	if isdirectiface(t) {
-		i |= objabi.KindDirectIface
-	}
-	if useGCProg {
-		i |= objabi.KindGCProg
-	}
-	ot = duint8(lsym, ot, uint8(i)) // kind
-	if eqfunc != nil {
-		ot = dsymptr(lsym, ot, eqfunc, 0) // equality function
-	} else {
-		ot = duintptr(lsym, ot, 0) // type we can't do == with
-	}
-	ot = dsymptr(lsym, ot, gcsym, 0) // gcdata
-
-	nsym := dname(p, "", nil, exported)
-	ot = dsymptrOff(lsym, ot, nsym) // str
-	// ptrToThis
-	if sptr == nil {
-		ot = duint32(lsym, ot, 0)
-	} else if sptrWeak {
-		ot = dsymptrWeakOff(lsym, ot, sptr)
-	} else {
-		ot = dsymptrOff(lsym, ot, sptr)
-	}
-
-	return ot
-}
-
-// typeHasNoAlg reports 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 typeHasNoAlg(t) {
-		name = "noalg." + name
-	}
-	return name
-}
-
-// Fake package for runtime type info (headers)
-// Don't access directly, use typeLookup below.
-var (
-	typepkgmu sync.Mutex // protects typepkg lookups
-	typepkg   = types.NewPkg("type", "type")
-)
-
-func typeLookup(name string) *types.Sym {
-	typepkgmu.Lock()
-	s := typepkg.Lookup(name)
-	typepkgmu.Unlock()
-	return s
-}
-
-func typesym(t *types.Type) *types.Sym {
-	return typeLookup(typesymname(t))
-}
-
-// tracksym returns the symbol for tracking use of field/method f, assumed
-// to be a member of struct/interface type t.
-func tracksym(t *types.Type, f *types.Field) *types.Sym {
-	return trackpkg.Lookup(t.ShortString() + "." + f.Sym.Name)
-}
-
-func typesymprefix(prefix string, t *types.Type) *types.Sym {
-	p := prefix + "." + t.ShortString()
-	s := typeLookup(p)
-
-	// This function is for looking up type-related generated functions
-	// (e.g. eq and hash). Make sure they are indeed generated.
-	signatmu.Lock()
-	addsignat(t)
-	signatmu.Unlock()
-
-	//print("algsym: %s -> %+S\n", p, s);
-
-	return s
-}
-
-func typenamesym(t *types.Type) *types.Sym {
-	if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() {
-		Fatalf("typenamesym %v", t)
-	}
-	s := typesym(t)
-	signatmu.Lock()
-	addsignat(t)
-	signatmu.Unlock()
-	return s
-}
-
-func typename(t *types.Type) *Node {
-	s := typenamesym(t)
-	if s.Def == nil {
-		n := newnamel(src.NoXPos, s)
-		n.Type = types.Types[TUINT8]
-		n.SetClass(PEXTERN)
-		n.SetTypecheck(1)
-		s.Def = asTypesNode(n)
-	}
-
-	n := nod(OADDR, asNode(s.Def), nil)
-	n.Type = types.NewPtr(asNode(s.Def).Type)
-	n.SetTypecheck(1)
-	return n
-}
-
-func itabname(t, itype *types.Type) *Node {
-	if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() || !itype.IsInterface() || itype.IsEmptyInterface() {
-		Fatalf("itabname(%v, %v)", t, itype)
-	}
-	s := itabpkg.Lookup(t.ShortString() + "," + itype.ShortString())
-	if s.Def == nil {
-		n := newname(s)
-		n.Type = types.Types[TUINT8]
-		n.SetClass(PEXTERN)
-		n.SetTypecheck(1)
-		s.Def = asTypesNode(n)
-		itabs = append(itabs, itabEntry{t: t, itype: itype, lsym: s.Linksym()})
-	}
-
-	n := nod(OADDR, asNode(s.Def), nil)
-	n.Type = types.NewPtr(asNode(s.Def).Type)
-	n.SetTypecheck(1)
-	return n
-}
-
-// isreflexive reports whether t has a reflexive equality operator.
-// That is, if x==x for all x of type t.
-func isreflexive(t *types.Type) bool {
-	switch t.Etype {
-	case TBOOL,
-		TINT,
-		TUINT,
-		TINT8,
-		TUINT8,
-		TINT16,
-		TUINT16,
-		TINT32,
-		TUINT32,
-		TINT64,
-		TUINT64,
-		TUINTPTR,
-		TPTR,
-		TUNSAFEPTR,
-		TSTRING,
-		TCHAN:
-		return true
-
-	case TFLOAT32,
-		TFLOAT64,
-		TCOMPLEX64,
-		TCOMPLEX128,
-		TINTER:
-		return false
-
-	case TARRAY:
-		return isreflexive(t.Elem())
-
-	case TSTRUCT:
-		for _, t1 := range t.Fields().Slice() {
-			if !isreflexive(t1.Type) {
-				return false
-			}
-		}
-		return true
-
-	default:
-		Fatalf("bad type for map key: %v", t)
-		return false
-	}
-}
-
-// needkeyupdate reports whether map updates with t as a key
-// need the key to be updated.
-func needkeyupdate(t *types.Type) bool {
-	switch t.Etype {
-	case TBOOL, TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32,
-		TINT64, TUINT64, TUINTPTR, TPTR, TUNSAFEPTR, TCHAN:
-		return false
-
-	case TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, // floats and complex can be +0/-0
-		TINTER,
-		TSTRING: // strings might have smaller backing stores
-		return true
-
-	case TARRAY:
-		return needkeyupdate(t.Elem())
-
-	case TSTRUCT:
-		for _, t1 := range t.Fields().Slice() {
-			if needkeyupdate(t1.Type) {
-				return true
-			}
-		}
-		return false
-
-	default:
-		Fatalf("bad type for map key: %v", t)
-		return true
-	}
-}
-
-// hashMightPanic reports whether the hash of a map key of type t might panic.
-func hashMightPanic(t *types.Type) bool {
-	switch t.Etype {
-	case TINTER:
-		return true
-
-	case TARRAY:
-		return hashMightPanic(t.Elem())
-
-	case TSTRUCT:
-		for _, t1 := range t.Fields().Slice() {
-			if hashMightPanic(t1.Type) {
-				return true
-			}
-		}
-		return false
-
-	default:
-		return false
-	}
-}
-
-// formalType replaces byte and rune aliases with real types.
-// They've been separate internally to make error messages
-// better, but we have to merge them in the reflect tables.
-func formalType(t *types.Type) *types.Type {
-	if t == types.Bytetype || t == types.Runetype {
-		return types.Types[t.Etype]
-	}
-	return t
-}
-
-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 lsym
-	}
-	s.SetSiggen(true)
-
-	// special case (look for runtime below):
-	// when compiling package runtime,
-	// emit the type structures for int, float, etc.
-	tbase := t
-
-	if t.IsPtr() && t.Sym == nil && t.Elem().Sym != nil {
-		tbase = t.Elem()
-	}
-	dupok := 0
-	if tbase.Sym == nil {
-		dupok = obj.DUPOK
-	}
-
-	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 {
-			if i, ok := typeSymIdx[tbase]; ok {
-				lsym.Pkg = tbase.Sym.Pkg.Prefix
-				if t != tbase {
-					lsym.SymIdx = int32(i[1])
-				} else {
-					lsym.SymIdx = int32(i[0])
-				}
-				lsym.Set(obj.AttrIndexed, true)
-			}
-			return lsym
-		}
-		// TODO(mdempsky): Investigate whether this can happen.
-		if tbase.Etype == TFORW {
-			return lsym
-		}
-	}
-
-	ot := 0
-	switch t.Etype {
-	default:
-		ot = dcommontype(lsym, t)
-		ot = dextratype(lsym, ot, t, 0)
-
-	case TARRAY:
-		// ../../../../runtime/type.go:/arrayType
-		s1 := dtypesym(t.Elem())
-		t2 := types.NewSlice(t.Elem())
-		s2 := dtypesym(t2)
-		ot = dcommontype(lsym, t)
-		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)
-
-	case TSLICE:
-		// ../../../../runtime/type.go:/sliceType
-		s1 := dtypesym(t.Elem())
-		ot = dcommontype(lsym, t)
-		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, t)
-		ot = dsymptr(lsym, ot, s1, 0)
-		ot = duintptr(lsym, ot, uint64(t.ChanDir()))
-		ot = dextratype(lsym, ot, t, 0)
-
-	case TFUNC:
-		for _, t1 := range t.Recvs().Fields().Slice() {
-			dtypesym(t1.Type)
-		}
-		isddd := false
-		for _, t1 := range t.Params().Fields().Slice() {
-			isddd = t1.IsDDD()
-			dtypesym(t1.Type)
-		}
-		for _, t1 := range t.Results().Fields().Slice() {
-			dtypesym(t1.Type)
-		}
-
-		ot = dcommontype(lsym, t)
-		inCount := t.NumRecvs() + t.NumParams()
-		outCount := t.NumResults()
-		if isddd {
-			outCount |= 1 << 15
-		}
-		ot = duint16(lsym, ot, uint16(inCount))
-		ot = duint16(lsym, ot, uint16(outCount))
-		if Widthptr == 8 {
-			ot += 4 // align for *rtype
-		}
-
-		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), 0)
-		}
-		for _, t1 := range t.Params().Fields().Slice() {
-			ot = dsymptr(lsym, ot, dtypesym(t1.Type), 0)
-		}
-		for _, t1 := range t.Results().Fields().Slice() {
-			ot = dsymptr(lsym, ot, dtypesym(t1.Type), 0)
-		}
-
-	case TINTER:
-		m := imethods(t)
-		n := len(m)
-		for _, a := range m {
-			dtypesym(a.type_)
-		}
-
-		// ../../../../runtime/type.go:/interfaceType
-		ot = dcommontype(lsym, t)
-
-		var tpkg *types.Pkg
-		if t.Sym != nil && t != types.Types[t.Etype] && t != types.Errortype {
-			tpkg = t.Sym.Pkg
-		}
-		ot = dgopkgpath(lsym, ot, tpkg)
-
-		ot = dsymptr(lsym, ot, lsym, ot+3*Widthptr+uncommonSize(t))
-		ot = duintptr(lsym, ot, uint64(n))
-		ot = duintptr(lsym, ot, uint64(n))
-		dataAdd := imethodSize() * n
-		ot = dextratype(lsym, ot, t, dataAdd)
-
-		for _, a := range m {
-			// ../../../../runtime/type.go:/imethod
-			exported := types.IsExported(a.name.Name)
-			var pkg *types.Pkg
-			if !exported && a.name.Pkg != tpkg {
-				pkg = a.name.Pkg
-			}
-			nsym := dname(a.name.Name, "", pkg, exported)
-
-			ot = dsymptrOff(lsym, ot, nsym)
-			ot = dsymptrOff(lsym, ot, dtypesym(a.type_))
-		}
-
-	// ../../../../runtime/type.go:/mapType
-	case TMAP:
-		s1 := dtypesym(t.Key())
-		s2 := dtypesym(t.Elem())
-		s3 := dtypesym(bmap(t))
-		hasher := genhash(t.Key())
-
-		ot = dcommontype(lsym, t)
-		ot = dsymptr(lsym, ot, s1, 0)
-		ot = dsymptr(lsym, ot, s2, 0)
-		ot = dsymptr(lsym, ot, s3, 0)
-		ot = dsymptr(lsym, ot, hasher, 0)
-		var flags uint32
-		// Note: flags must match maptype accessors in ../../../../runtime/type.go
-		// and maptype builder in ../../../../reflect/type.go:MapOf.
-		if t.Key().Width > MAXKEYSIZE {
-			ot = duint8(lsym, ot, uint8(Widthptr))
-			flags |= 1 // indirect key
-		} else {
-			ot = duint8(lsym, ot, uint8(t.Key().Width))
-		}
-
-		if t.Elem().Width > MAXELEMSIZE {
-			ot = duint8(lsym, ot, uint8(Widthptr))
-			flags |= 2 // indirect value
-		} else {
-			ot = duint8(lsym, ot, uint8(t.Elem().Width))
-		}
-		ot = duint16(lsym, ot, uint16(bmap(t).Width))
-		if isreflexive(t.Key()) {
-			flags |= 4 // reflexive key
-		}
-		if needkeyupdate(t.Key()) {
-			flags |= 8 // need key update
-		}
-		if hashMightPanic(t.Key()) {
-			flags |= 16 // hash might panic
-		}
-		ot = duint32(lsym, ot, flags)
-		ot = dextratype(lsym, ot, t, 0)
-
-	case TPTR:
-		if t.Elem().Etype == TANY {
-			// ../../../../runtime/type.go:/UnsafePointerType
-			ot = dcommontype(lsym, t)
-			ot = dextratype(lsym, ot, t, 0)
-
-			break
-		}
-
-		// ../../../../runtime/type.go:/ptrType
-		s1 := dtypesym(t.Elem())
-
-		ot = dcommontype(lsym, t)
-		ot = dsymptr(lsym, ot, s1, 0)
-		ot = dextratype(lsym, ot, t, 0)
-
-	// ../../../../runtime/type.go:/structType
-	// for security, only the exported fields.
-	case TSTRUCT:
-		fields := t.Fields().Slice()
-		for _, t1 := range fields {
-			dtypesym(t1.Type)
-		}
-
-		// 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 !types.IsExported(f.Sym.Name) {
-				spkg = f.Sym.Pkg
-				break
-			}
-		}
-
-		ot = dcommontype(lsym, 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 fields {
-			// ../../../../runtime/type.go:/structField
-			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)
-			}
-			if f.Embedded != 0 {
-				offsetAnon |= 1
-			}
-			ot = duintptr(lsym, ot, offsetAnon)
-		}
-	}
-
-	ot = dextratypeData(lsym, ot, t)
-	ggloblsym(lsym, int32(ot), int16(dupok|obj.RODATA))
-
-	// The linker will leave a table of all the typelinks for
-	// types in the binary, so the runtime can find them.
-	//
-	// When buildmode=shared, all types are in typelinks so the
-	// runtime can deduplicate type pointers.
-	keep := Ctxt.Flag_dynlink
-	if !keep && t.Sym == nil {
-		// For an unnamed type, we only need the link if the type can
-		// be created at run time by reflect.PtrTo and similar
-		// functions. If the type exists in the program, those
-		// functions must return the existing type structure rather
-		// than creating a new one.
-		switch t.Etype {
-		case TPTR, TARRAY, TCHAN, TFUNC, TMAP, TSLICE, TSTRUCT:
-			keep = true
-		}
-	}
-	// Do not put Noalg types in typelinks.  See issue #22605.
-	if typeHasNoAlg(t) {
-		keep = false
-	}
-	lsym.Set(obj.AttrMakeTypelink, keep)
-
-	return lsym
-}
-
-// ifaceMethodOffset returns the offset of the i-th method in the interface
-// type descriptor, ityp.
-func ifaceMethodOffset(ityp *types.Type, i int64) int64 {
-	// interface type descriptor layout is struct {
-	//   _type        // commonSize
-	//   pkgpath      // 1 word
-	//   []imethod    // 3 words (pointing to [...]imethod below)
-	//   uncommontype // uncommonSize
-	//   [...]imethod
-	// }
-	// The size of imethod is 8.
-	return int64(commonSize()+4*Widthptr+uncommonSize(ityp)) + i*8
-}
-
-// for each itabEntry, gather the methods on
-// the concrete type that implement the interface
-func peekitabs() {
-	for i := range itabs {
-		tab := &itabs[i]
-		methods := genfun(tab.t, tab.itype)
-		if len(methods) == 0 {
-			continue
-		}
-		tab.entries = methods
-	}
-}
-
-// for the given concrete type and interface
-// type, return the (sorted) set of methods
-// on the concrete type that implement the interface
-func genfun(t, it *types.Type) []*obj.LSym {
-	if t == nil || it == nil {
-		return nil
-	}
-	sigs := imethods(it)
-	methods := methods(t)
-	out := make([]*obj.LSym, 0, len(sigs))
-	// TODO(mdempsky): Short circuit before calling methods(t)?
-	// See discussion on CL 105039.
-	if len(sigs) == 0 {
-		return nil
-	}
-
-	// both sigs and methods are sorted by name,
-	// so we can find the intersect in a single pass
-	for _, m := range methods {
-		if m.name == sigs[0].name {
-			out = append(out, m.isym.Linksym())
-			sigs = sigs[1:]
-			if len(sigs) == 0 {
-				break
-			}
-		}
-	}
-
-	if len(sigs) != 0 {
-		Fatalf("incomplete itab")
-	}
-
-	return out
-}
-
-// itabsym uses the information gathered in
-// peekitabs to de-virtualize interface methods.
-// Since this is called by the SSA backend, it shouldn't
-// generate additional Nodes, Syms, etc.
-func itabsym(it *obj.LSym, offset int64) *obj.LSym {
-	var syms []*obj.LSym
-	if it == nil {
-		return nil
-	}
-
-	for i := range itabs {
-		e := &itabs[i]
-		if e.lsym == it {
-			syms = e.entries
-			break
-		}
-	}
-	if syms == nil {
-		return nil
-	}
-
-	// keep this arithmetic in sync with *itab layout
-	methodnum := int((offset - 2*int64(Widthptr) - 8) / int64(Widthptr))
-	if methodnum >= len(syms) {
-		return nil
-	}
-	return syms[methodnum]
-}
-
-// addsignat ensures that a runtime type descriptor is emitted for t.
-func addsignat(t *types.Type) {
-	if _, ok := signatset[t]; !ok {
-		signatset[t] = struct{}{}
-		signatslice = append(signatslice, t)
-	}
-}
-
-func addsignats(dcls []*Node) {
-	// copy types from dcl list to signatset
-	for _, n := range dcls {
-		if n.Op == OTYPE {
-			addsignat(n.Type)
-		}
-	}
-}
-
-func dumpsignats() {
-	// Process signatset. Use a loop, as dtypesym adds
-	// entries to signatset while it is being processed.
-	signats := make([]typeAndStr, len(signatslice))
-	for len(signatslice) > 0 {
-		signats = signats[:0]
-		// Transfer entries to a slice and sort, for reproducible builds.
-		for _, t := range signatslice {
-			signats = append(signats, typeAndStr{t: t, short: typesymname(t), regular: t.String()})
-			delete(signatset, t)
-		}
-		signatslice = signatslice[:0]
-		sort.Sort(typesByString(signats))
-		for _, ts := range signats {
-			t := ts.t
-			dtypesym(t)
-			if t.Sym != nil {
-				dtypesym(types.NewPtr(t))
-			}
-		}
-	}
-}
-
-func dumptabs() {
-	// process itabs
-	for _, i := range itabs {
-		// dump empty itab symbol into i.sym
-		// type itab struct {
-		//   inter  *interfacetype
-		//   _type  *_type
-		//   hash   uint32
-		//   _      [4]byte
-		//   fun    [1]uintptr // variable sized
-		// }
-		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))
-		i.lsym.Set(obj.AttrContentAddressable, true)
-	}
-
-	// process ptabs
-	if localpkg.Name == "main" && len(ptabs) > 0 {
-		ot := 0
-		s := Ctxt.Lookup("go.plugin.tabs")
-		for _, p := range ptabs {
-			// Dump ptab symbol into go.pluginsym package.
-			//
-			// type ptab struct {
-			//	name nameOff
-			//	typ  typeOff // pointer to symbol
-			// }
-			nsym := dname(p.s.Name, "", nil, true)
-			tsym := dtypesym(p.t)
-			ot = dsymptrOff(s, ot, nsym)
-			ot = dsymptrOff(s, ot, tsym)
-			// Plugin exports symbols as interfaces. Mark their types
-			// as UsedInIface.
-			tsym.Set(obj.AttrUsedInIface, true)
-		}
-		ggloblsym(s, int32(ot), int16(obj.RODATA))
-
-		ot = 0
-		s = Ctxt.Lookup("go.plugin.exports")
-		for _, p := range ptabs {
-			ot = dsymptr(s, ot, p.s.Linksym(), 0)
-		}
-		ggloblsym(s, int32(ot), int16(obj.RODATA))
-	}
-}
-
-func dumpimportstrings() {
-	// generate import strings for imported packages
-	for _, p := range types.ImportedPkgList() {
-		dimportpath(p)
-	}
-}
-
-func dumpbasictypes() {
-	// do basic types if compiling package runtime.
-	// they have to be in at least one package,
-	// and runtime is always loaded implicitly,
-	// so this is as good as any.
-	// another possible choice would be package main,
-	// but using runtime means fewer copies in object files.
-	if myimportpath == "runtime" {
-		for i := types.EType(1); i <= TBOOL; i++ {
-			dtypesym(types.NewPtr(types.Types[i]))
-		}
-		dtypesym(types.NewPtr(types.Types[TSTRING]))
-		dtypesym(types.NewPtr(types.Types[TUNSAFEPTR]))
-
-		// emit type structs for error and func(error) string.
-		// The latter is the type of an auto-generated wrapper.
-		dtypesym(types.NewPtr(types.Errortype))
-
-		dtypesym(functype(nil, []*Node{anonfield(types.Errortype)}, []*Node{anonfield(types.Types[TSTRING])}))
-
-		// add paths for runtime and main, which 6l imports implicitly.
-		dimportpath(Runtimepkg)
-
-		if flag_race {
-			dimportpath(racepkg)
-		}
-		if flag_msan {
-			dimportpath(msanpkg)
-		}
-		dimportpath(types.NewPkg("main", ""))
-	}
-}
-
-type typeAndStr struct {
-	t       *types.Type
-	short   string
-	regular string
-}
-
-type typesByString []typeAndStr
-
-func (a typesByString) Len() int { return len(a) }
-func (a typesByString) Less(i, j int) bool {
-	if a[i].short != a[j].short {
-		return a[i].short < a[j].short
-	}
-	// When the only difference between the types is whether
-	// they refer to byte or uint8, such as **byte vs **uint8,
-	// the types' ShortStrings can be identical.
-	// To preserve deterministic sort ordering, sort these by String().
-	if a[i].regular != a[j].regular {
-		return a[i].regular < a[j].regular
-	}
-	// Identical anonymous interfaces defined in different locations
-	// will be equal for the above checks, but different in DWARF output.
-	// Sort by source position to ensure deterministic order.
-	// See issues 27013 and 30202.
-	if a[i].t.Etype == types.TINTER && a[i].t.Methods().Len() > 0 {
-		return a[i].t.Methods().Index(0).Pos.Before(a[j].t.Methods().Index(0).Pos)
-	}
-	return false
-}
-func (a typesByString) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-
-// maxPtrmaskBytes is the maximum length of a GC ptrmask bitmap,
-// which holds 1-bit entries describing where pointers are in a given type.
-// Above this length, the GC information is recorded as a GC program,
-// which can express repetition compactly. In either form, the
-// information is used by the runtime to initialize the heap bitmap,
-// and for large types (like 128 or more words), they are roughly the
-// same speed. GC programs are never much larger and often more
-// compact. (If large arrays are involved, they can be arbitrarily
-// more compact.)
-//
-// The cutoff must be large enough that any allocation large enough to
-// use a GC program is large enough that it does not share heap bitmap
-// bytes with any other objects, allowing the GC program execution to
-// assume an aligned start and not use atomic operations. In the current
-// runtime, this means all malloc size classes larger than the cutoff must
-// be multiples of four words. On 32-bit systems that's 16 bytes, and
-// all size classes >= 16 bytes are 16-byte aligned, so no real constraint.
-// On 64-bit systems, that's 32 bytes, and 32-byte alignment is guaranteed
-// for size classes >= 256 bytes. On a 64-bit system, 256 bytes allocated
-// is 32 pointers, the bits for which fit in 4 bytes. So maxPtrmaskBytes
-// must be >= 4.
-//
-// We used to use 16 because the GC programs do have some constant overhead
-// to get started, and processing 128 pointers seems to be enough to
-// amortize that overhead well.
-//
-// To make sure that the runtime's chansend can call typeBitsBulkBarrier,
-// we raised the limit to 2048, so that even 32-bit systems are guaranteed to
-// use bitmaps for objects up to 64 kB in size.
-//
-// Also known to reflect/type.go.
-//
-const maxPtrmaskBytes = 2048
-
-// dgcsym emits and returns a data symbol containing GC information for type t,
-// along with a boolean reporting whether the UseGCProg bit should be set in
-// the type kind, and the ptrdata field to record in the reflect type information.
-func dgcsym(t *types.Type) (lsym *obj.LSym, useGCProg bool, ptrdata int64) {
-	ptrdata = typeptrdata(t)
-	if ptrdata/int64(Widthptr) <= maxPtrmaskBytes*8 {
-		lsym = dgcptrmask(t)
-		return
-	}
-
-	useGCProg = true
-	lsym, ptrdata = dgcprog(t)
-	return
-}
-
-// dgcptrmask emits and returns the symbol containing a pointer mask for type t.
-func dgcptrmask(t *types.Type) *obj.LSym {
-	ptrmask := make([]byte, (typeptrdata(t)/int64(Widthptr)+7)/8)
-	fillptrmask(t, ptrmask)
-	p := fmt.Sprintf("gcbits.%x", ptrmask)
-
-	sym := Runtimepkg.Lookup(p)
-	lsym := sym.Linksym()
-	if !sym.Uniq() {
-		sym.SetUniq(true)
-		for i, x := range ptrmask {
-			duint8(lsym, i, x)
-		}
-		ggloblsym(lsym, int32(len(ptrmask)), obj.DUPOK|obj.RODATA|obj.LOCAL)
-		lsym.Set(obj.AttrContentAddressable, true)
-	}
-	return lsym
-}
-
-// fillptrmask fills in ptrmask with 1s corresponding to the
-// word offsets in t that hold pointers.
-// ptrmask is assumed to fit at least typeptrdata(t)/Widthptr bits.
-func fillptrmask(t *types.Type, ptrmask []byte) {
-	for i := range ptrmask {
-		ptrmask[i] = 0
-	}
-	if !t.HasPointers() {
-		return
-	}
-
-	vec := bvalloc(8 * int32(len(ptrmask)))
-	onebitwalktype1(t, 0, vec)
-
-	nptr := typeptrdata(t) / int64(Widthptr)
-	for i := int64(0); i < nptr; i++ {
-		if vec.Get(int32(i)) {
-			ptrmask[i/8] |= 1 << (uint(i) % 8)
-		}
-	}
-}
-
-// dgcprog emits and returns the symbol containing a GC program for type t
-// along with the size of the data described by the program (in the range [typeptrdata(t), t.Width]).
-// In practice, the size is typeptrdata(t) except for non-trivial arrays.
-// For non-trivial arrays, the program describes the full t.Width size.
-func dgcprog(t *types.Type) (*obj.LSym, int64) {
-	dowidth(t)
-	if t.Width == BADWIDTH {
-		Fatalf("dgcprog: %v badwidth", t)
-	}
-	lsym := typesymprefix(".gcprog", t).Linksym()
-	var p GCProg
-	p.init(lsym)
-	p.emit(t, 0)
-	offset := p.w.BitIndex() * int64(Widthptr)
-	p.end()
-	if ptrdata := typeptrdata(t); offset < ptrdata || offset > t.Width {
-		Fatalf("dgcprog: %v: offset=%d but ptrdata=%d size=%d", t, offset, ptrdata, t.Width)
-	}
-	return lsym, offset
-}
-
-type GCProg struct {
-	lsym   *obj.LSym
-	symoff int
-	w      gcprog.Writer
-}
-
-var Debug_gcprog int // set by -d gcprog
-
-func (p *GCProg) init(lsym *obj.LSym) {
-	p.lsym = lsym
-	p.symoff = 4 // first 4 bytes hold program length
-	p.w.Init(p.writeByte)
-	if Debug_gcprog > 0 {
-		fmt.Fprintf(os.Stderr, "compile: start GCProg for %v\n", lsym)
-		p.w.Debug(os.Stderr)
-	}
-}
-
-func (p *GCProg) writeByte(x byte) {
-	p.symoff = duint8(p.lsym, p.symoff, x)
-}
-
-func (p *GCProg) end() {
-	p.w.End()
-	duint32(p.lsym, 0, uint32(p.symoff-4))
-	ggloblsym(p.lsym, int32(p.symoff), obj.DUPOK|obj.RODATA|obj.LOCAL)
-	if Debug_gcprog > 0 {
-		fmt.Fprintf(os.Stderr, "compile: end GCProg for %v\n", p.lsym)
-	}
-}
-
-func (p *GCProg) emit(t *types.Type, offset int64) {
-	dowidth(t)
-	if !t.HasPointers() {
-		return
-	}
-	if t.Width == int64(Widthptr) {
-		p.w.Ptr(offset / int64(Widthptr))
-		return
-	}
-	switch t.Etype {
-	default:
-		Fatalf("GCProg.emit: unexpected type %v", t)
-
-	case TSTRING:
-		p.w.Ptr(offset / int64(Widthptr))
-
-	case TINTER:
-		// Note: the first word isn't a pointer. See comment in plive.go:onebitwalktype1.
-		p.w.Ptr(offset/int64(Widthptr) + 1)
-
-	case TSLICE:
-		p.w.Ptr(offset / int64(Widthptr))
-
-	case TARRAY:
-		if t.NumElem() == 0 {
-			// should have been handled by haspointers check above
-			Fatalf("GCProg.emit: empty array")
-		}
-
-		// Flatten array-of-array-of-array to just a big array by multiplying counts.
-		count := t.NumElem()
-		elem := t.Elem()
-		for elem.IsArray() {
-			count *= elem.NumElem()
-			elem = elem.Elem()
-		}
-
-		if !p.w.ShouldRepeat(elem.Width/int64(Widthptr), count) {
-			// Cheaper to just emit the bits.
-			for i := int64(0); i < count; i++ {
-				p.emit(elem, offset+i*elem.Width)
-			}
-			return
-		}
-		p.emit(elem, offset)
-		p.w.ZeroUntil((offset + elem.Width) / int64(Widthptr))
-		p.w.Repeat(elem.Width/int64(Widthptr), count-1)
-
-	case TSTRUCT:
-		for _, t1 := range t.Fields().Slice() {
-			p.emit(t1.Type, offset+t1.Offset)
-		}
-	}
-}
-
-// zeroaddr returns the address of a symbol with at least
-// size bytes of zeros.
-func zeroaddr(size int64) *Node {
-	if size >= 1<<31 {
-		Fatalf("map elem too big %d", size)
-	}
-	if zerosize < size {
-		zerosize = size
-	}
-	s := mappkg.Lookup("zero")
-	if s.Def == nil {
-		x := newname(s)
-		x.Type = types.Types[TUINT8]
-		x.SetClass(PEXTERN)
-		x.SetTypecheck(1)
-		s.Def = asTypesNode(x)
-	}
-	z := nod(OADDR, asNode(s.Def), nil)
-	z.Type = types.NewPtr(types.Types[TUINT8])
-	z.SetTypecheck(1)
-	return z
-}
diff --git a/src/cmd/compile/internal/gc/reproduciblebuilds_test.go b/src/cmd/compile/internal/gc/reproduciblebuilds_test.go
deleted file mode 100644
index 8101e44..0000000
--- a/src/cmd/compile/internal/gc/reproduciblebuilds_test.go
+++ /dev/null
@@ -1,112 +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 gc_test
-
-import (
-	"bytes"
-	"internal/testenv"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"testing"
-)
-
-func TestReproducibleBuilds(t *testing.T) {
-	tests := []string{
-		"issue20272.go",
-		"issue27013.go",
-		"issue30202.go",
-	}
-
-	testenv.MustHaveGoBuild(t)
-	iters := 10
-	if testing.Short() {
-		iters = 4
-	}
-	t.Parallel()
-	for _, test := range tests {
-		test := test
-		t.Run(test, func(t *testing.T) {
-			t.Parallel()
-			var want []byte
-			tmp, err := ioutil.TempFile("", "")
-			if err != nil {
-				t.Fatalf("temp file creation failed: %v", err)
-			}
-			defer os.Remove(tmp.Name())
-			defer tmp.Close()
-			for i := 0; i < iters; i++ {
-				// Note: use -c 2 to expose any nondeterminism which is the result
-				// of the runtime scheduler.
-				out, err := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-c", "2", "-o", tmp.Name(), filepath.Join("testdata", "reproducible", test)).CombinedOutput()
-				if err != nil {
-					t.Fatalf("failed to compile: %v\n%s", err, out)
-				}
-				obj, err := ioutil.ReadFile(tmp.Name())
-				if err != nil {
-					t.Fatalf("failed to read object file: %v", err)
-				}
-				if i == 0 {
-					want = obj
-				} else {
-					if !bytes.Equal(want, obj) {
-						t.Fatalf("builds produced different output after %d iters (%d bytes vs %d bytes)", i, len(want), len(obj))
-					}
-				}
-			}
-		})
-	}
-}
-
-func TestIssue38068(t *testing.T) {
-	testenv.MustHaveGoBuild(t)
-	t.Parallel()
-
-	// Compile a small package with and without the concurrent
-	// backend, then check to make sure that the resulting archives
-	// are identical.  Note: this uses "go tool compile" instead of
-	// "go build" since the latter will generate differnent build IDs
-	// if it sees different command line flags.
-	scenarios := []struct {
-		tag     string
-		args    string
-		libpath string
-	}{
-		{tag: "serial", args: "-c=1"},
-		{tag: "concurrent", args: "-c=2"}}
-
-	tmpdir, err := ioutil.TempDir("", "TestIssue38068")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
-
-	src := filepath.Join("testdata", "reproducible", "issue38068.go")
-	for i := range scenarios {
-		s := &scenarios[i]
-		s.libpath = filepath.Join(tmpdir, s.tag+".a")
-		// Note: use of "-p" required in order for DWARF to be generated.
-		cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-trimpath", "-p=issue38068", "-buildid=", s.args, "-o", s.libpath, src)
-		out, err := cmd.CombinedOutput()
-		if err != nil {
-			t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
-		}
-	}
-
-	readBytes := func(fn string) []byte {
-		payload, err := ioutil.ReadFile(fn)
-		if err != nil {
-			t.Fatalf("failed to read executable '%s': %v", fn, err)
-		}
-		return payload
-	}
-
-	b1 := readBytes(scenarios[0].libpath)
-	b2 := readBytes(scenarios[1].libpath)
-	if !bytes.Equal(b1, b2) {
-		t.Fatalf("concurrent and serial builds produced different output")
-	}
-}
diff --git a/src/cmd/compile/internal/gc/scc.go b/src/cmd/compile/internal/gc/scc.go
deleted file mode 100644
index 5c7935a..0000000
--- a/src/cmd/compile/internal/gc/scc.go
+++ /dev/null
@@ -1,140 +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
-
-// Strongly connected components.
-//
-// Run analysis on minimal sets of mutually recursive functions
-// or single non-recursive functions, bottom up.
-//
-// Finding these sets is finding strongly connected components
-// by reverse topological order in the static call graph.
-// The algorithm (known as Tarjan's algorithm) for doing that is taken from
-// Sedgewick, Algorithms, Second Edition, p. 482, with two adaptations.
-//
-// First, a hidden closure function (n.Func.IsHiddenClosure()) cannot be the
-// root of a connected component. Refusing to use it as a root
-// forces it into the component of the function in which it appears.
-// This is more convenient for escape analysis.
-//
-// Second, each function becomes two virtual nodes in the graph,
-// with numbers n and n+1. We record the function's node number as n
-// but search from node n+1. If the search tells us that the component
-// number (min) is n+1, we know that this is a trivial component: one function
-// plus its closures. If the search tells us that the component number is
-// n, then there was a path from node n+1 back to node n, meaning that
-// the function set is mutually recursive. The escape analysis can be
-// more precise when analyzing a single non-recursive function than
-// when analyzing a set of mutually recursive functions.
-
-type bottomUpVisitor struct {
-	analyze  func([]*Node, bool)
-	visitgen uint32
-	nodeID   map[*Node]uint32
-	stack    []*Node
-}
-
-// visitBottomUp invokes analyze on the ODCLFUNC nodes listed in list.
-// It calls analyze with successive groups of functions, working from
-// the bottom of the call graph upward. Each time analyze is called with
-// a list of functions, every function on that list only calls other functions
-// on the list or functions that have been passed in previous invocations of
-// analyze. Closures appear in the same list as their outer functions.
-// The lists are as short as possible while preserving those requirements.
-// (In a typical program, many invocations of analyze will be passed just
-// a single function.) The boolean argument 'recursive' passed to analyze
-// specifies whether the functions on the list are mutually recursive.
-// If recursive is false, the list consists of only a single function and its closures.
-// If recursive is true, the list may still contain only a single function,
-// if that function is itself recursive.
-func visitBottomUp(list []*Node, analyze func(list []*Node, recursive bool)) {
-	var v bottomUpVisitor
-	v.analyze = analyze
-	v.nodeID = make(map[*Node]uint32)
-	for _, n := range list {
-		if n.Op == ODCLFUNC && !n.Func.IsHiddenClosure() {
-			v.visit(n)
-		}
-	}
-}
-
-func (v *bottomUpVisitor) visit(n *Node) uint32 {
-	if id := v.nodeID[n]; id > 0 {
-		// already visited
-		return id
-	}
-
-	v.visitgen++
-	id := v.visitgen
-	v.nodeID[n] = id
-	v.visitgen++
-	min := v.visitgen
-	v.stack = append(v.stack, n)
-
-	inspectList(n.Nbody, func(n *Node) bool {
-		switch n.Op {
-		case ONAME:
-			if n.Class() == PFUNC {
-				if n.isMethodExpression() {
-					n = asNode(n.Type.Nname())
-				}
-				if n != nil && n.Name.Defn != nil {
-					if m := v.visit(n.Name.Defn); m < min {
-						min = m
-					}
-				}
-			}
-		case ODOTMETH:
-			fn := asNode(n.Type.Nname())
-			if fn != nil && fn.Op == ONAME && fn.Class() == PFUNC && fn.Name.Defn != nil {
-				if m := v.visit(fn.Name.Defn); m < min {
-					min = m
-				}
-			}
-		case OCALLPART:
-			fn := asNode(callpartMethod(n).Type.Nname())
-			if fn != nil && fn.Op == ONAME && fn.Class() == PFUNC && fn.Name.Defn != nil {
-				if m := v.visit(fn.Name.Defn); m < min {
-					min = m
-				}
-			}
-		case OCLOSURE:
-			if m := v.visit(n.Func.Closure); m < min {
-				min = m
-			}
-		}
-		return true
-	})
-
-	if (min == id || min == id+1) && !n.Func.IsHiddenClosure() {
-		// This node is the root of a strongly connected component.
-
-		// The original min passed to visitcodelist was v.nodeID[n]+1.
-		// If visitcodelist found its way back to v.nodeID[n], then this
-		// block is a set of mutually recursive functions.
-		// Otherwise it's just a lone function that does not recurse.
-		recursive := min == id
-
-		// Remove connected component from stack.
-		// Mark walkgen so that future visits return a large number
-		// so as not to affect the caller's min.
-
-		var i int
-		for i = len(v.stack) - 1; i >= 0; i-- {
-			x := v.stack[i]
-			if x == n {
-				break
-			}
-			v.nodeID[x] = ^uint32(0)
-		}
-		v.nodeID[n] = ^uint32(0)
-		block := v.stack[i:]
-		// Run escape analysis on this set of functions.
-		v.stack = v.stack[:i]
-		v.analyze(block, recursive)
-	}
-
-	return min
-}
diff --git a/src/cmd/compile/internal/gc/scope.go b/src/cmd/compile/internal/gc/scope.go
deleted file mode 100644
index e66b859..0000000
--- a/src/cmd/compile/internal/gc/scope.go
+++ /dev/null
@@ -1,109 +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 gc
-
-import (
-	"cmd/internal/dwarf"
-	"cmd/internal/obj"
-	"cmd/internal/src"
-	"sort"
-)
-
-// See golang.org/issue/20390.
-func xposBefore(p, q src.XPos) bool {
-	return Ctxt.PosTable.Pos(p).Before(Ctxt.PosTable.Pos(q))
-}
-
-func findScope(marks []Mark, pos src.XPos) ScopeID {
-	i := sort.Search(len(marks), func(i int) bool {
-		return xposBefore(pos, marks[i].Pos)
-	})
-	if i == 0 {
-		return 0
-	}
-	return marks[i-1].Scope
-}
-
-func assembleScopes(fnsym *obj.LSym, fn *Node, dwarfVars []*dwarf.Var, varScopes []ScopeID) []dwarf.Scope {
-	// Initialize the DWARF scope tree based on lexical scopes.
-	dwarfScopes := make([]dwarf.Scope, 1+len(fn.Func.Parents))
-	for i, parent := range fn.Func.Parents {
-		dwarfScopes[i+1].Parent = int32(parent)
-	}
-
-	scopeVariables(dwarfVars, varScopes, dwarfScopes)
-	scopePCs(fnsym, fn.Func.Marks, dwarfScopes)
-	return compactScopes(dwarfScopes)
-}
-
-// scopeVariables assigns DWARF variable records to their scopes.
-func scopeVariables(dwarfVars []*dwarf.Var, varScopes []ScopeID, dwarfScopes []dwarf.Scope) {
-	sort.Stable(varsByScopeAndOffset{dwarfVars, varScopes})
-
-	i0 := 0
-	for i := range dwarfVars {
-		if varScopes[i] == varScopes[i0] {
-			continue
-		}
-		dwarfScopes[varScopes[i0]].Vars = dwarfVars[i0:i]
-		i0 = i
-	}
-	if i0 < len(dwarfVars) {
-		dwarfScopes[varScopes[i0]].Vars = dwarfVars[i0:]
-	}
-}
-
-// scopePCs assigns PC ranges to their scopes.
-func scopePCs(fnsym *obj.LSym, marks []Mark, dwarfScopes []dwarf.Scope) {
-	// If there aren't any child scopes (in particular, when scope
-	// tracking is disabled), we can skip a whole lot of work.
-	if len(marks) == 0 {
-		return
-	}
-	p0 := fnsym.Func().Text
-	scope := findScope(marks, p0.Pos)
-	for p := p0; p != nil; p = p.Link {
-		if p.Pos == p0.Pos {
-			continue
-		}
-		dwarfScopes[scope].AppendRange(dwarf.Range{Start: p0.Pc, End: p.Pc})
-		p0 = p
-		scope = findScope(marks, p0.Pos)
-	}
-	if p0.Pc < fnsym.Size {
-		dwarfScopes[scope].AppendRange(dwarf.Range{Start: p0.Pc, End: fnsym.Size})
-	}
-}
-
-func compactScopes(dwarfScopes []dwarf.Scope) []dwarf.Scope {
-	// Reverse pass to propagate PC ranges to parent scopes.
-	for i := len(dwarfScopes) - 1; i > 0; i-- {
-		s := &dwarfScopes[i]
-		dwarfScopes[s.Parent].UnifyRanges(s)
-	}
-
-	return dwarfScopes
-}
-
-type varsByScopeAndOffset struct {
-	vars   []*dwarf.Var
-	scopes []ScopeID
-}
-
-func (v varsByScopeAndOffset) Len() int {
-	return len(v.vars)
-}
-
-func (v varsByScopeAndOffset) Less(i, j int) bool {
-	if v.scopes[i] != v.scopes[j] {
-		return v.scopes[i] < v.scopes[j]
-	}
-	return v.vars[i].StackOffset < v.vars[j].StackOffset
-}
-
-func (v varsByScopeAndOffset) Swap(i, j int) {
-	v.vars[i], v.vars[j] = v.vars[j], v.vars[i]
-	v.scopes[i], v.scopes[j] = v.scopes[j], v.scopes[i]
-}
diff --git a/src/cmd/compile/internal/gc/scope_test.go b/src/cmd/compile/internal/gc/scope_test.go
deleted file mode 100644
index b0e038d..0000000
--- a/src/cmd/compile/internal/gc/scope_test.go
+++ /dev/null
@@ -1,538 +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.
-
-package gc_test
-
-import (
-	"cmd/internal/objfile"
-	"debug/dwarf"
-	"fmt"
-	"internal/testenv"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"sort"
-	"strconv"
-	"strings"
-	"testing"
-)
-
-type testline struct {
-	// line is one line of go source
-	line string
-
-	// scopes is a list of scope IDs of all the lexical scopes that this line
-	// of code belongs to.
-	// Scope IDs are assigned by traversing the tree of lexical blocks of a
-	// function in pre-order
-	// Scope IDs are function specific, i.e. scope 0 is always the root scope
-	// of the function that this line belongs to. Empty scopes are not assigned
-	// an ID (because they are not saved in debug_info).
-	// Scope 0 is always omitted from this list since all lines always belong
-	// to it.
-	scopes []int
-
-	// vars is the list of variables that belong in scopes[len(scopes)-1].
-	// Local variables are prefixed with "var ", formal parameters with "arg ".
-	// Must be ordered alphabetically.
-	// Set to nil to skip the check.
-	vars []string
-
-	// decl is the list of variables declared at this line.
-	decl []string
-
-	// declBefore is the list of variables declared at or before this line.
-	declBefore []string
-}
-
-var testfile = []testline{
-	{line: "package main"},
-	{line: "func f1(x int) { }"},
-	{line: "func f2(x int) { }"},
-	{line: "func f3(x int) { }"},
-	{line: "func f4(x int) { }"},
-	{line: "func f5(x int) { }"},
-	{line: "func f6(x int) { }"},
-	{line: "func fi(x interface{}) { if a, ok := x.(error); ok { a.Error() } }"},
-	{line: "func gret1() int { return 2 }"},
-	{line: "func gretbool() bool { return true }"},
-	{line: "func gret3() (int, int, int) { return 0, 1, 2 }"},
-	{line: "var v = []int{ 0, 1, 2 }"},
-	{line: "var ch = make(chan int)"},
-	{line: "var floatch = make(chan float64)"},
-	{line: "var iface interface{}"},
-	{line: "func TestNestedFor() {", vars: []string{"var a int"}},
-	{line: "	a := 0", decl: []string{"a"}},
-	{line: "	f1(a)"},
-	{line: "	for i := 0; i < 5; i++ {", scopes: []int{1}, vars: []string{"var i int"}, decl: []string{"i"}},
-	{line: "		f2(i)", scopes: []int{1}},
-	{line: "		for i := 0; i < 5; i++ {", scopes: []int{1, 2}, vars: []string{"var i int"}, decl: []string{"i"}},
-	{line: "			f3(i)", scopes: []int{1, 2}},
-	{line: "		}"},
-	{line: "		f4(i)", scopes: []int{1}},
-	{line: "	}"},
-	{line: "	f5(a)"},
-	{line: "}"},
-	{line: "func TestOas2() {", vars: []string{}},
-	{line: "	if a, b, c := gret3(); a != 1 {", scopes: []int{1}, vars: []string{"var a int", "var b int", "var c int"}},
-	{line: "		f1(a)", scopes: []int{1}},
-	{line: "		f1(b)", scopes: []int{1}},
-	{line: "		f1(c)", scopes: []int{1}},
-	{line: "	}"},
-	{line: "	for i, x := range v {", scopes: []int{2}, vars: []string{"var i int", "var x int"}},
-	{line: "		f1(i)", scopes: []int{2}},
-	{line: "		f1(x)", scopes: []int{2}},
-	{line: "	}"},
-	{line: "	if a, ok := <- ch; ok {", scopes: []int{3}, vars: []string{"var a int", "var ok bool"}},
-	{line: "		f1(a)", scopes: []int{3}},
-	{line: "	}"},
-	{line: "	if a, ok := iface.(int); ok {", scopes: []int{4}, vars: []string{"var a int", "var ok bool"}},
-	{line: "		f1(a)", scopes: []int{4}},
-	{line: "	}"},
-	{line: "}"},
-	{line: "func TestIfElse() {"},
-	{line: "	if x := gret1(); x != 0 {", scopes: []int{1}, vars: []string{"var x int"}},
-	{line: "		a := 0", scopes: []int{1, 2}, vars: []string{"var a int"}},
-	{line: "		f1(a); f1(x)", scopes: []int{1, 2}},
-	{line: "	} else {"},
-	{line: "		b := 1", scopes: []int{1, 3}, vars: []string{"var b int"}},
-	{line: "		f1(b); f1(x+1)", scopes: []int{1, 3}},
-	{line: "	}"},
-	{line: "}"},
-	{line: "func TestSwitch() {", vars: []string{}},
-	{line: "	switch x := gret1(); x {", scopes: []int{1}, vars: []string{"var x int"}},
-	{line: "	case 0:", scopes: []int{1, 2}},
-	{line: "		i := x + 5", scopes: []int{1, 2}, vars: []string{"var i int"}},
-	{line: "		f1(x); f1(i)", scopes: []int{1, 2}},
-	{line: "	case 1:", scopes: []int{1, 3}},
-	{line: "		j := x + 10", scopes: []int{1, 3}, vars: []string{"var j int"}},
-	{line: "		f1(x); f1(j)", scopes: []int{1, 3}},
-	{line: "	case 2:", scopes: []int{1, 4}},
-	{line: "		k := x + 2", scopes: []int{1, 4}, vars: []string{"var k int"}},
-	{line: "		f1(x); f1(k)", scopes: []int{1, 4}},
-	{line: "	}"},
-	{line: "}"},
-	{line: "func TestTypeSwitch() {", vars: []string{}},
-	{line: "	switch x := iface.(type) {"},
-	{line: "	case int:", scopes: []int{1}},
-	{line: "		f1(x)", scopes: []int{1}, vars: []string{"var x int"}},
-	{line: "	case uint8:", scopes: []int{2}},
-	{line: "		f1(int(x))", scopes: []int{2}, vars: []string{"var x uint8"}},
-	{line: "	case float64:", scopes: []int{3}},
-	{line: "		f1(int(x)+1)", scopes: []int{3}, vars: []string{"var x float64"}},
-	{line: "	}"},
-	{line: "}"},
-	{line: "func TestSelectScope() {"},
-	{line: "	select {"},
-	{line: "	case i := <- ch:", scopes: []int{1}},
-	{line: "		f1(i)", scopes: []int{1}, vars: []string{"var i int"}},
-	{line: "	case f := <- floatch:", scopes: []int{2}},
-	{line: "		f1(int(f))", scopes: []int{2}, vars: []string{"var f float64"}},
-	{line: "	}"},
-	{line: "}"},
-	{line: "func TestBlock() {", vars: []string{"var a int"}},
-	{line: "	a := 1"},
-	{line: "	{"},
-	{line: "		b := 2", scopes: []int{1}, vars: []string{"var b int"}},
-	{line: "		f1(b)", scopes: []int{1}},
-	{line: "		f1(a)", scopes: []int{1}},
-	{line: "	}"},
-	{line: "}"},
-	{line: "func TestDiscontiguousRanges() {", vars: []string{"var a int"}},
-	{line: "	a := 0"},
-	{line: "	f1(a)"},
-	{line: "	{"},
-	{line: "		b := 0", scopes: []int{1}, vars: []string{"var b int"}},
-	{line: "		f2(b)", scopes: []int{1}},
-	{line: "		if gretbool() {", scopes: []int{1}},
-	{line: "			c := 0", scopes: []int{1, 2}, vars: []string{"var c int"}},
-	{line: "			f3(c)", scopes: []int{1, 2}},
-	{line: "		} else {"},
-	{line: "			c := 1.1", scopes: []int{1, 3}, vars: []string{"var c float64"}},
-	{line: "			f4(int(c))", scopes: []int{1, 3}},
-	{line: "		}"},
-	{line: "		f5(b)", scopes: []int{1}},
-	{line: "	}"},
-	{line: "	f6(a)"},
-	{line: "}"},
-	{line: "func TestClosureScope() {", vars: []string{"var a int", "var b int", "var f func(int)"}},
-	{line: "	a := 1; b := 1"},
-	{line: "	f := func(c int) {", scopes: []int{0}, vars: []string{"arg c int", "var &b *int", "var a int", "var d int"}, declBefore: []string{"&b", "a"}},
-	{line: "		d := 3"},
-	{line: "		f1(c); f1(d)"},
-	{line: "		if e := 3; e != 0 {", scopes: []int{1}, vars: []string{"var e int"}},
-	{line: "			f1(e)", scopes: []int{1}},
-	{line: "			f1(a)", scopes: []int{1}},
-	{line: "			b = 2", scopes: []int{1}},
-	{line: "		}"},
-	{line: "	}"},
-	{line: "	f(3); f1(b)"},
-	{line: "}"},
-	{line: "func TestEscape() {"},
-	{line: "	a := 1", vars: []string{"var a int"}},
-	{line: "	{"},
-	{line: "		b := 2", scopes: []int{1}, vars: []string{"var &b *int", "var p *int"}},
-	{line: "		p := &b", scopes: []int{1}},
-	{line: "		f1(a)", scopes: []int{1}},
-	{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()"},
-	{line: "	TestIfElse()"},
-	{line: "	TestSwitch()"},
-	{line: "	TestTypeSwitch()"},
-	{line: "	TestSelectScope()"},
-	{line: "	TestBlock()"},
-	{line: "	TestDiscontiguousRanges()"},
-	{line: "	TestClosureScope()"},
-	{line: "	TestEscape()"},
-	{line: "	TestCaptureVar(true)"},
-	{line: "}"},
-}
-
-const detailOutput = false
-
-// Compiles testfile checks that the description of lexical blocks emitted
-// by the linker in debug_info, for each function in the main package,
-// corresponds to what we expect it to be.
-func TestScopeRanges(t *testing.T) {
-	testenv.MustHaveGoBuild(t)
-	t.Parallel()
-
-	if runtime.GOOS == "plan9" {
-		t.Skip("skipping on plan9; no DWARF symbol table in executables")
-	}
-
-	dir, err := ioutil.TempDir("", "TestScopeRanges")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
-
-	src, f := gobuild(t, dir, false, testfile)
-	defer f.Close()
-
-	// the compiler uses forward slashes for paths even on windows
-	src = strings.Replace(src, "\\", "/", -1)
-
-	pcln, err := f.PCLineTable()
-	if err != nil {
-		t.Fatal(err)
-	}
-	dwarfData, err := f.DWARF()
-	if err != nil {
-		t.Fatal(err)
-	}
-	dwarfReader := dwarfData.Reader()
-
-	lines := make(map[line][]*lexblock)
-
-	for {
-		entry, err := dwarfReader.Next()
-		if err != nil {
-			t.Fatal(err)
-		}
-		if entry == nil {
-			break
-		}
-
-		if entry.Tag != dwarf.TagSubprogram {
-			continue
-		}
-
-		name, ok := entry.Val(dwarf.AttrName).(string)
-		if !ok || !strings.HasPrefix(name, "main.Test") {
-			continue
-		}
-
-		var scope lexblock
-		ctxt := scopexplainContext{
-			dwarfData:   dwarfData,
-			dwarfReader: dwarfReader,
-			scopegen:    1,
-		}
-
-		readScope(&ctxt, &scope, entry)
-
-		scope.markLines(pcln, lines)
-	}
-
-	anyerror := false
-	for i := range testfile {
-		tgt := testfile[i].scopes
-		out := lines[line{src, i + 1}]
-
-		if detailOutput {
-			t.Logf("%s // %v", testfile[i].line, out)
-		}
-
-		scopesok := checkScopes(tgt, out)
-		if !scopesok {
-			t.Logf("mismatch at line %d %q: expected: %v got: %v\n", i, testfile[i].line, tgt, scopesToString(out))
-		}
-
-		varsok := true
-		if testfile[i].vars != nil {
-			if len(out) > 0 {
-				varsok = checkVars(testfile[i].vars, out[len(out)-1].vars)
-				if !varsok {
-					t.Logf("variable mismatch at line %d %q for scope %d: expected: %v got: %v\n", i+1, testfile[i].line, out[len(out)-1].id, testfile[i].vars, out[len(out)-1].vars)
-				}
-				for j := range testfile[i].decl {
-					if line := declLineForVar(out[len(out)-1].vars, testfile[i].decl[j]); line != i+1 {
-						t.Errorf("wrong declaration line for variable %s, expected %d got: %d", testfile[i].decl[j], i+1, line)
-					}
-				}
-
-				for j := range testfile[i].declBefore {
-					if line := declLineForVar(out[len(out)-1].vars, testfile[i].declBefore[j]); line > i+1 {
-						t.Errorf("wrong declaration line for variable %s, expected %d (or less) got: %d", testfile[i].declBefore[j], i+1, line)
-					}
-				}
-			}
-		}
-
-		anyerror = anyerror || !scopesok || !varsok
-	}
-
-	if anyerror {
-		t.Fatalf("mismatched output")
-	}
-}
-
-func scopesToString(v []*lexblock) string {
-	r := make([]string, len(v))
-	for i, s := range v {
-		r[i] = strconv.Itoa(s.id)
-	}
-	return "[ " + strings.Join(r, ", ") + " ]"
-}
-
-func checkScopes(tgt []int, out []*lexblock) bool {
-	if len(out) > 0 {
-		// omit scope 0
-		out = out[1:]
-	}
-	if len(tgt) != len(out) {
-		return false
-	}
-	for i := range tgt {
-		if tgt[i] != out[i].id {
-			return false
-		}
-	}
-	return true
-}
-
-func checkVars(tgt []string, out []variable) bool {
-	if len(tgt) != len(out) {
-		return false
-	}
-	for i := range tgt {
-		if tgt[i] != out[i].expr {
-			return false
-		}
-	}
-	return true
-}
-
-func declLineForVar(scope []variable, name string) int {
-	for i := range scope {
-		if scope[i].name() == name {
-			return scope[i].declLine
-		}
-	}
-	return -1
-}
-
-type lexblock struct {
-	id     int
-	ranges [][2]uint64
-	vars   []variable
-	scopes []lexblock
-}
-
-type variable struct {
-	expr     string
-	declLine int
-}
-
-func (v *variable) name() string {
-	return strings.Split(v.expr, " ")[1]
-}
-
-type line struct {
-	file   string
-	lineno int
-}
-
-type scopexplainContext struct {
-	dwarfData   *dwarf.Data
-	dwarfReader *dwarf.Reader
-	scopegen    int
-}
-
-// readScope reads the DW_TAG_lexical_block or the DW_TAG_subprogram in
-// entry and writes a description in scope.
-// Nested DW_TAG_lexical_block entries are read recursively.
-func readScope(ctxt *scopexplainContext, scope *lexblock, entry *dwarf.Entry) {
-	var err error
-	scope.ranges, err = ctxt.dwarfData.Ranges(entry)
-	if err != nil {
-		panic(err)
-	}
-	for {
-		e, err := ctxt.dwarfReader.Next()
-		if err != nil {
-			panic(err)
-		}
-		switch e.Tag {
-		case 0:
-			sort.Slice(scope.vars, func(i, j int) bool {
-				return scope.vars[i].expr < scope.vars[j].expr
-			})
-			return
-		case dwarf.TagFormalParameter:
-			typ, err := ctxt.dwarfData.Type(e.Val(dwarf.AttrType).(dwarf.Offset))
-			if err != nil {
-				panic(err)
-			}
-			scope.vars = append(scope.vars, entryToVar(e, "arg", typ))
-		case dwarf.TagVariable:
-			typ, err := ctxt.dwarfData.Type(e.Val(dwarf.AttrType).(dwarf.Offset))
-			if err != nil {
-				panic(err)
-			}
-			scope.vars = append(scope.vars, entryToVar(e, "var", typ))
-		case dwarf.TagLexDwarfBlock:
-			scope.scopes = append(scope.scopes, lexblock{id: ctxt.scopegen})
-			ctxt.scopegen++
-			readScope(ctxt, &scope.scopes[len(scope.scopes)-1], e)
-		}
-	}
-}
-
-func entryToVar(e *dwarf.Entry, kind string, typ dwarf.Type) variable {
-	return variable{
-		fmt.Sprintf("%s %s %s", kind, e.Val(dwarf.AttrName).(string), typ.String()),
-		int(e.Val(dwarf.AttrDeclLine).(int64)),
-	}
-}
-
-// markLines marks all lines that belong to this scope with this scope
-// Recursively calls markLines for all children scopes.
-func (scope *lexblock) markLines(pcln objfile.Liner, lines map[line][]*lexblock) {
-	for _, r := range scope.ranges {
-		for pc := r[0]; pc < r[1]; pc++ {
-			file, lineno, _ := pcln.PCToLine(pc)
-			l := line{file, lineno}
-			if len(lines[l]) == 0 || lines[l][len(lines[l])-1] != scope {
-				lines[l] = append(lines[l], scope)
-			}
-		}
-	}
-
-	for i := range scope.scopes {
-		scope.scopes[i].markLines(pcln, lines)
-	}
-}
-
-func gobuild(t *testing.T, dir string, optimized bool, testfile []testline) (string, *objfile.File) {
-	src := filepath.Join(dir, "test.go")
-	dst := filepath.Join(dir, "out.o")
-
-	f, err := os.Create(src)
-	if err != nil {
-		t.Fatal(err)
-	}
-	for i := range testfile {
-		f.Write([]byte(testfile[i].line))
-		f.Write([]byte{'\n'})
-	}
-	f.Close()
-
-	args := []string{"build"}
-	if !optimized {
-		args = append(args, "-gcflags=-N -l")
-	}
-	args = append(args, "-o", dst, src)
-
-	cmd := exec.Command(testenv.GoToolPath(t), args...)
-	if b, err := cmd.CombinedOutput(); err != nil {
-		t.Logf("build: %s\n", string(b))
-		t.Fatal(err)
-	}
-
-	pkg, err := objfile.Open(dst)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return src, pkg
-}
-
-// TestEmptyDwarfRanges tests that no list entry in debug_ranges has start == end.
-// See issue #23928.
-func TestEmptyDwarfRanges(t *testing.T) {
-	testenv.MustHaveGoRun(t)
-	t.Parallel()
-
-	if runtime.GOOS == "plan9" {
-		t.Skip("skipping on plan9; no DWARF symbol table in executables")
-	}
-
-	dir, err := ioutil.TempDir("", "TestEmptyDwarfRanges")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
-
-	_, f := gobuild(t, dir, true, []testline{{line: "package main"}, {line: "func main(){ println(\"hello\") }"}})
-	defer f.Close()
-
-	dwarfData, err := f.DWARF()
-	if err != nil {
-		t.Fatal(err)
-	}
-	dwarfReader := dwarfData.Reader()
-
-	for {
-		entry, err := dwarfReader.Next()
-		if err != nil {
-			t.Fatal(err)
-		}
-		if entry == nil {
-			break
-		}
-
-		ranges, err := dwarfData.Ranges(entry)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if ranges == nil {
-			continue
-		}
-
-		for _, rng := range ranges {
-			if rng[0] == rng[1] {
-				t.Errorf("range entry with start == end: %v", rng)
-			}
-		}
-	}
-}
diff --git a/src/cmd/compile/internal/gc/select.go b/src/cmd/compile/internal/gc/select.go
deleted file mode 100644
index 97e0424..0000000
--- a/src/cmd/compile/internal/gc/select.go
+++ /dev/null
@@ -1,387 +0,0 @@
-// Copyright 2009 The Go Authors. 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/compile/internal/types"
-
-// select
-func typecheckselect(sel *Node) {
-	var def *Node
-	lno := setlineno(sel)
-	typecheckslice(sel.Ninit.Slice(), ctxStmt)
-	for _, ncase := range sel.List.Slice() {
-		if ncase.Op != OCASE {
-			setlineno(ncase)
-			Fatalf("typecheckselect %v", ncase.Op)
-		}
-
-		if ncase.List.Len() == 0 {
-			// default
-			if def != nil {
-				yyerrorl(ncase.Pos, "multiple defaults in select (first at %v)", def.Line())
-			} else {
-				def = ncase
-			}
-		} else if ncase.List.Len() > 1 {
-			yyerrorl(ncase.Pos, "select cases cannot be lists")
-		} else {
-			ncase.List.SetFirst(typecheck(ncase.List.First(), ctxStmt))
-			n := ncase.List.First()
-			ncase.Left = n
-			ncase.List.Set(nil)
-			switch n.Op {
-			default:
-				pos := n.Pos
-				if n.Op == ONAME {
-					// We don't have the right position for ONAME nodes (see #15459 and
-					// others). Using ncase.Pos for now as it will provide the correct
-					// line number (assuming the expression follows the "case" keyword
-					// on the same line). This matches the approach before 1.10.
-					pos = ncase.Pos
-				}
-				yyerrorl(pos, "select case must be receive, send or assign recv")
-
-			// convert x = <-c into OSELRECV(x, <-c).
-			// remove implicit conversions; the eventual assignment
-			// will reintroduce them.
-			case OAS:
-				if (n.Right.Op == OCONVNOP || n.Right.Op == OCONVIFACE) && n.Right.Implicit() {
-					n.Right = n.Right.Left
-				}
-
-				if n.Right.Op != ORECV {
-					yyerrorl(n.Pos, "select assignment must have receive on right hand side")
-					break
-				}
-
-				n.Op = OSELRECV
-
-				// convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok
-			case OAS2RECV:
-				if n.Right.Op != ORECV {
-					yyerrorl(n.Pos, "select assignment must have receive on right hand side")
-					break
-				}
-
-				n.Op = OSELRECV2
-				n.Left = n.List.First()
-				n.List.Set1(n.List.Second())
-
-				// convert <-c into OSELRECV(N, <-c)
-			case ORECV:
-				n = nodl(n.Pos, OSELRECV, nil, n)
-
-				n.SetTypecheck(1)
-				ncase.Left = n
-
-			case OSEND:
-				break
-			}
-		}
-
-		typecheckslice(ncase.Nbody.Slice(), ctxStmt)
-	}
-
-	lineno = lno
-}
-
-func walkselect(sel *Node) {
-	lno := setlineno(sel)
-	if sel.Nbody.Len() != 0 {
-		Fatalf("double walkselect")
-	}
-
-	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 {
-	ncas := cases.Len()
-	sellineno := lineno
-
-	// optimization: zero-case select
-	if ncas == 0 {
-		return []*Node{mkcall("block", nil, nil)}
-	}
-
-	// optimization: one-case select: single op.
-	if ncas == 1 {
-		cas := cases.First()
-		setlineno(cas)
-		l := cas.Ninit.Slice()
-		if cas.Left != nil { // not default:
-			n := cas.Left
-			l = append(l, n.Ninit.Slice()...)
-			n.Ninit.Set(nil)
-			switch n.Op {
-			default:
-				Fatalf("select %v", n.Op)
-
-			case OSEND:
-				// already ok
-
-			case OSELRECV, OSELRECV2:
-				if n.Op == OSELRECV || n.List.Len() == 0 {
-					if n.Left == nil {
-						n = n.Right
-					} else {
-						n.Op = OAS
-					}
-					break
-				}
-
-				if n.Left == nil {
-					nblank = typecheck(nblank, ctxExpr|ctxAssign)
-					n.Left = nblank
-				}
-
-				n.Op = OAS2
-				n.List.Prepend(n.Left)
-				n.Rlist.Set1(n.Right)
-				n.Right = nil
-				n.Left = nil
-				n.SetTypecheck(0)
-				n = typecheck(n, ctxStmt)
-			}
-
-			l = append(l, n)
-		}
-
-		l = append(l, cas.Nbody.Slice()...)
-		l = append(l, nod(OBREAK, nil, nil))
-		return l
-	}
-
-	// convert case value arguments to addresses.
-	// this rewrite is used by both the general code and the next optimization.
-	var dflt *Node
-	for _, cas := range cases.Slice() {
-		setlineno(cas)
-		n := cas.Left
-		if n == nil {
-			dflt = cas
-			continue
-		}
-		switch n.Op {
-		case OSEND:
-			n.Right = nod(OADDR, n.Right, nil)
-			n.Right = typecheck(n.Right, ctxExpr)
-
-		case OSELRECV, OSELRECV2:
-			if n.Op == OSELRECV2 && n.List.Len() == 0 {
-				n.Op = OSELRECV
-			}
-
-			if n.Left != nil {
-				n.Left = nod(OADDR, n.Left, nil)
-				n.Left = typecheck(n.Left, ctxExpr)
-			}
-		}
-	}
-
-	// optimization: two-case select but one is default: single non-blocking op.
-	if ncas == 2 && dflt != nil {
-		cas := cases.First()
-		if cas == dflt {
-			cas = cases.Second()
-		}
-
-		n := cas.Left
-		setlineno(n)
-		r := nod(OIF, nil, nil)
-		r.Ninit.Set(cas.Ninit.Slice())
-		switch n.Op {
-		default:
-			Fatalf("select %v", n.Op)
-
-		case OSEND:
-			// if selectnbsend(c, v) { body } else { default body }
-			ch := n.Left
-			r.Left = mkcall1(chanfn("selectnbsend", 2, ch.Type), types.Types[TBOOL], &r.Ninit, ch, n.Right)
-
-		case OSELRECV:
-			// if selectnbrecv(&v, c) { body } else { default body }
-			ch := n.Right.Left
-			elem := n.Left
-			if elem == nil {
-				elem = nodnil()
-			}
-			r.Left = mkcall1(chanfn("selectnbrecv", 2, ch.Type), types.Types[TBOOL], &r.Ninit, elem, ch)
-
-		case OSELRECV2:
-			// if selectnbrecv2(&v, &received, c) { body } else { default body }
-			ch := n.Right.Left
-			elem := n.Left
-			if elem == nil {
-				elem = nodnil()
-			}
-			receivedp := nod(OADDR, n.List.First(), nil)
-			receivedp = typecheck(receivedp, ctxExpr)
-			r.Left = mkcall1(chanfn("selectnbrecv2", 2, ch.Type), types.Types[TBOOL], &r.Ninit, elem, receivedp, ch)
-		}
-
-		r.Left = typecheck(r.Left, ctxExpr)
-		r.Nbody.Set(cas.Nbody.Slice())
-		r.Rlist.Set(append(dflt.Ninit.Slice(), dflt.Nbody.Slice()...))
-		return []*Node{r, nod(OBREAK, nil, nil)}
-	}
-
-	if dflt != nil {
-		ncas--
-	}
-	casorder := make([]*Node, ncas)
-	nsends, nrecvs := 0, 0
-
-	var init []*Node
-
-	// generate sel-struct
-	lineno = sellineno
-	selv := temp(types.NewArray(scasetype(), int64(ncas)))
-	r := nod(OAS, selv, nil)
-	r = typecheck(r, ctxStmt)
-	init = append(init, r)
-
-	// No initialization for order; runtime.selectgo is responsible for that.
-	order := temp(types.NewArray(types.Types[TUINT16], 2*int64(ncas)))
-
-	var pc0, pcs *Node
-	if flag_race {
-		pcs = temp(types.NewArray(types.Types[TUINTPTR], int64(ncas)))
-		pc0 = typecheck(nod(OADDR, nod(OINDEX, pcs, nodintconst(0)), nil), ctxExpr)
-	} else {
-		pc0 = nodnil()
-	}
-
-	// register cases
-	for _, cas := range cases.Slice() {
-		setlineno(cas)
-
-		init = append(init, cas.Ninit.Slice()...)
-		cas.Ninit.Set(nil)
-
-		n := cas.Left
-		if n == nil { // default:
-			continue
-		}
-
-		var i int
-		var c, elem *Node
-		switch n.Op {
-		default:
-			Fatalf("select %v", n.Op)
-		case OSEND:
-			i = nsends
-			nsends++
-			c = n.Left
-			elem = n.Right
-		case OSELRECV, OSELRECV2:
-			nrecvs++
-			i = ncas - nrecvs
-			c = n.Right.Left
-			elem = n.Left
-		}
-
-		casorder[i] = cas
-
-		setField := func(f string, val *Node) {
-			r := nod(OAS, nodSym(ODOT, nod(OINDEX, selv, nodintconst(int64(i))), lookup(f)), val)
-			r = typecheck(r, ctxStmt)
-			init = append(init, r)
-		}
-
-		c = convnop(c, types.Types[TUNSAFEPTR])
-		setField("c", c)
-		if elem != nil {
-			elem = convnop(elem, types.Types[TUNSAFEPTR])
-			setField("elem", elem)
-		}
-
-		// TODO(mdempsky): There should be a cleaner way to
-		// handle this.
-		if flag_race {
-			r = mkcall("selectsetpc", nil, nil, nod(OADDR, nod(OINDEX, pcs, nodintconst(int64(i))), nil))
-			init = append(init, r)
-		}
-	}
-	if nsends+nrecvs != ncas {
-		Fatalf("walkselectcases: miscount: %v + %v != %v", nsends, nrecvs, ncas)
-	}
-
-	// run the select
-	lineno = sellineno
-	chosen := temp(types.Types[TINT])
-	recvOK := temp(types.Types[TBOOL])
-	r = nod(OAS2, nil, nil)
-	r.List.Set2(chosen, recvOK)
-	fn := syslook("selectgo")
-	r.Rlist.Set1(mkcall1(fn, fn.Type.Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), pc0, nodintconst(int64(nsends)), nodintconst(int64(nrecvs)), nodbool(dflt == nil)))
-	r = typecheck(r, ctxStmt)
-	init = append(init, r)
-
-	// selv and order are no longer alive after selectgo.
-	init = append(init, nod(OVARKILL, selv, nil))
-	init = append(init, nod(OVARKILL, order, nil))
-	if flag_race {
-		init = append(init, nod(OVARKILL, pcs, nil))
-	}
-
-	// dispatch cases
-	dispatch := func(cond, cas *Node) {
-		cond = typecheck(cond, ctxExpr)
-		cond = defaultlit(cond, nil)
-
-		r := nod(OIF, cond, nil)
-
-		if n := cas.Left; n != nil && n.Op == OSELRECV2 {
-			x := nod(OAS, n.List.First(), recvOK)
-			x = typecheck(x, ctxStmt)
-			r.Nbody.Append(x)
-		}
-
-		r.Nbody.AppendNodes(&cas.Nbody)
-		r.Nbody.Append(nod(OBREAK, nil, nil))
-		init = append(init, r)
-	}
-
-	if dflt != nil {
-		setlineno(dflt)
-		dispatch(nod(OLT, chosen, nodintconst(0)), dflt)
-	}
-	for i, cas := range casorder {
-		setlineno(cas)
-		dispatch(nod(OEQ, chosen, nodintconst(int64(i))), cas)
-	}
-
-	return init
-}
-
-// bytePtrToIndex returns a Node representing "(*byte)(&n[i])".
-func bytePtrToIndex(n *Node, i int64) *Node {
-	s := nod(OADDR, nod(OINDEX, n, nodintconst(i)), nil)
-	t := types.NewPtr(types.Types[TUINT8])
-	return convnop(s, t)
-}
-
-var scase *types.Type
-
-// Keep in sync with src/runtime/select.go.
-func scasetype() *types.Type {
-	if scase == nil {
-		scase = tostruct([]*Node{
-			namedfield("c", types.Types[TUNSAFEPTR]),
-			namedfield("elem", types.Types[TUNSAFEPTR]),
-		})
-		scase.SetNoalg(true)
-	}
-	return scase
-}
diff --git a/src/cmd/compile/internal/gc/shift_test.go b/src/cmd/compile/internal/gc/shift_test.go
deleted file mode 100644
index ce2eedf..0000000
--- a/src/cmd/compile/internal/gc/shift_test.go
+++ /dev/null
@@ -1,1031 +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.
-
-package gc
-
-import (
-	"reflect"
-	"testing"
-)
-
-// Tests shifts of zero.
-
-//go:noinline
-func ofz64l64(n uint64) int64 {
-	var x int64
-	return x << n
-}
-
-//go:noinline
-func ofz64l32(n uint32) int64 {
-	var x int64
-	return x << n
-}
-
-//go:noinline
-func ofz64l16(n uint16) int64 {
-	var x int64
-	return x << n
-}
-
-//go:noinline
-func ofz64l8(n uint8) int64 {
-	var x int64
-	return x << n
-}
-
-//go:noinline
-func ofz64r64(n uint64) int64 {
-	var x int64
-	return x >> n
-}
-
-//go:noinline
-func ofz64r32(n uint32) int64 {
-	var x int64
-	return x >> n
-}
-
-//go:noinline
-func ofz64r16(n uint16) int64 {
-	var x int64
-	return x >> n
-}
-
-//go:noinline
-func ofz64r8(n uint8) int64 {
-	var x int64
-	return x >> n
-}
-
-//go:noinline
-func ofz64ur64(n uint64) uint64 {
-	var x uint64
-	return x >> n
-}
-
-//go:noinline
-func ofz64ur32(n uint32) uint64 {
-	var x uint64
-	return x >> n
-}
-
-//go:noinline
-func ofz64ur16(n uint16) uint64 {
-	var x uint64
-	return x >> n
-}
-
-//go:noinline
-func ofz64ur8(n uint8) uint64 {
-	var x uint64
-	return x >> n
-}
-
-//go:noinline
-func ofz32l64(n uint64) int32 {
-	var x int32
-	return x << n
-}
-
-//go:noinline
-func ofz32l32(n uint32) int32 {
-	var x int32
-	return x << n
-}
-
-//go:noinline
-func ofz32l16(n uint16) int32 {
-	var x int32
-	return x << n
-}
-
-//go:noinline
-func ofz32l8(n uint8) int32 {
-	var x int32
-	return x << n
-}
-
-//go:noinline
-func ofz32r64(n uint64) int32 {
-	var x int32
-	return x >> n
-}
-
-//go:noinline
-func ofz32r32(n uint32) int32 {
-	var x int32
-	return x >> n
-}
-
-//go:noinline
-func ofz32r16(n uint16) int32 {
-	var x int32
-	return x >> n
-}
-
-//go:noinline
-func ofz32r8(n uint8) int32 {
-	var x int32
-	return x >> n
-}
-
-//go:noinline
-func ofz32ur64(n uint64) uint32 {
-	var x uint32
-	return x >> n
-}
-
-//go:noinline
-func ofz32ur32(n uint32) uint32 {
-	var x uint32
-	return x >> n
-}
-
-//go:noinline
-func ofz32ur16(n uint16) uint32 {
-	var x uint32
-	return x >> n
-}
-
-//go:noinline
-func ofz32ur8(n uint8) uint32 {
-	var x uint32
-	return x >> n
-}
-
-//go:noinline
-func ofz16l64(n uint64) int16 {
-	var x int16
-	return x << n
-}
-
-//go:noinline
-func ofz16l32(n uint32) int16 {
-	var x int16
-	return x << n
-}
-
-//go:noinline
-func ofz16l16(n uint16) int16 {
-	var x int16
-	return x << n
-}
-
-//go:noinline
-func ofz16l8(n uint8) int16 {
-	var x int16
-	return x << n
-}
-
-//go:noinline
-func ofz16r64(n uint64) int16 {
-	var x int16
-	return x >> n
-}
-
-//go:noinline
-func ofz16r32(n uint32) int16 {
-	var x int16
-	return x >> n
-}
-
-//go:noinline
-func ofz16r16(n uint16) int16 {
-	var x int16
-	return x >> n
-}
-
-//go:noinline
-func ofz16r8(n uint8) int16 {
-	var x int16
-	return x >> n
-}
-
-//go:noinline
-func ofz16ur64(n uint64) uint16 {
-	var x uint16
-	return x >> n
-}
-
-//go:noinline
-func ofz16ur32(n uint32) uint16 {
-	var x uint16
-	return x >> n
-}
-
-//go:noinline
-func ofz16ur16(n uint16) uint16 {
-	var x uint16
-	return x >> n
-}
-
-//go:noinline
-func ofz16ur8(n uint8) uint16 {
-	var x uint16
-	return x >> n
-}
-
-//go:noinline
-func ofz8l64(n uint64) int8 {
-	var x int8
-	return x << n
-}
-
-//go:noinline
-func ofz8l32(n uint32) int8 {
-	var x int8
-	return x << n
-}
-
-//go:noinline
-func ofz8l16(n uint16) int8 {
-	var x int8
-	return x << n
-}
-
-//go:noinline
-func ofz8l8(n uint8) int8 {
-	var x int8
-	return x << n
-}
-
-//go:noinline
-func ofz8r64(n uint64) int8 {
-	var x int8
-	return x >> n
-}
-
-//go:noinline
-func ofz8r32(n uint32) int8 {
-	var x int8
-	return x >> n
-}
-
-//go:noinline
-func ofz8r16(n uint16) int8 {
-	var x int8
-	return x >> n
-}
-
-//go:noinline
-func ofz8r8(n uint8) int8 {
-	var x int8
-	return x >> n
-}
-
-//go:noinline
-func ofz8ur64(n uint64) uint8 {
-	var x uint8
-	return x >> n
-}
-
-//go:noinline
-func ofz8ur32(n uint32) uint8 {
-	var x uint8
-	return x >> n
-}
-
-//go:noinline
-func ofz8ur16(n uint16) uint8 {
-	var x uint8
-	return x >> n
-}
-
-//go:noinline
-func ofz8ur8(n uint8) uint8 {
-	var x uint8
-	return x >> n
-}
-
-func TestShiftOfZero(t *testing.T) {
-	if got := ofz64l64(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz64l32(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz64l16(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz64l8(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz64r64(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz64r32(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz64r16(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz64r8(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz64ur64(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-	if got := ofz64ur32(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-	if got := ofz64ur16(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-	if got := ofz64ur8(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-
-	if got := ofz32l64(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz32l32(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz32l16(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz32l8(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz32r64(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz32r32(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz32r16(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz32r8(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz32ur64(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-	if got := ofz32ur32(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-	if got := ofz32ur16(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-	if got := ofz32ur8(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-
-	if got := ofz16l64(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz16l32(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz16l16(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz16l8(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz16r64(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz16r32(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz16r16(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz16r8(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz16ur64(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-	if got := ofz16ur32(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-	if got := ofz16ur16(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-	if got := ofz16ur8(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-
-	if got := ofz8l64(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz8l32(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz8l16(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz8l8(5); got != 0 {
-		t.Errorf("0<<5 == %d, want 0", got)
-	}
-	if got := ofz8r64(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz8r32(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz8r16(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz8r8(5); got != 0 {
-		t.Errorf("0>>5 == %d, want 0", got)
-	}
-	if got := ofz8ur64(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-	if got := ofz8ur32(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-	if got := ofz8ur16(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-	if got := ofz8ur8(5); got != 0 {
-		t.Errorf("0>>>5 == %d, want 0", got)
-	}
-}
-
-//go:noinline
-func byz64l(n int64) int64 {
-	return n << 0
-}
-
-//go:noinline
-func byz64r(n int64) int64 {
-	return n >> 0
-}
-
-//go:noinline
-func byz64ur(n uint64) uint64 {
-	return n >> 0
-}
-
-//go:noinline
-func byz32l(n int32) int32 {
-	return n << 0
-}
-
-//go:noinline
-func byz32r(n int32) int32 {
-	return n >> 0
-}
-
-//go:noinline
-func byz32ur(n uint32) uint32 {
-	return n >> 0
-}
-
-//go:noinline
-func byz16l(n int16) int16 {
-	return n << 0
-}
-
-//go:noinline
-func byz16r(n int16) int16 {
-	return n >> 0
-}
-
-//go:noinline
-func byz16ur(n uint16) uint16 {
-	return n >> 0
-}
-
-//go:noinline
-func byz8l(n int8) int8 {
-	return n << 0
-}
-
-//go:noinline
-func byz8r(n int8) int8 {
-	return n >> 0
-}
-
-//go:noinline
-func byz8ur(n uint8) uint8 {
-	return n >> 0
-}
-
-func TestShiftByZero(t *testing.T) {
-	{
-		var n int64 = 0x5555555555555555
-		if got := byz64l(n); got != n {
-			t.Errorf("%x<<0 == %x, want %x", n, got, n)
-		}
-		if got := byz64r(n); got != n {
-			t.Errorf("%x>>0 == %x, want %x", n, got, n)
-		}
-	}
-	{
-		var n uint64 = 0xaaaaaaaaaaaaaaaa
-		if got := byz64ur(n); got != n {
-			t.Errorf("%x>>>0 == %x, want %x", n, got, n)
-		}
-	}
-
-	{
-		var n int32 = 0x55555555
-		if got := byz32l(n); got != n {
-			t.Errorf("%x<<0 == %x, want %x", n, got, n)
-		}
-		if got := byz32r(n); got != n {
-			t.Errorf("%x>>0 == %x, want %x", n, got, n)
-		}
-	}
-	{
-		var n uint32 = 0xaaaaaaaa
-		if got := byz32ur(n); got != n {
-			t.Errorf("%x>>>0 == %x, want %x", n, got, n)
-		}
-	}
-
-	{
-		var n int16 = 0x5555
-		if got := byz16l(n); got != n {
-			t.Errorf("%x<<0 == %x, want %x", n, got, n)
-		}
-		if got := byz16r(n); got != n {
-			t.Errorf("%x>>0 == %x, want %x", n, got, n)
-		}
-	}
-	{
-		var n uint16 = 0xaaaa
-		if got := byz16ur(n); got != n {
-			t.Errorf("%x>>>0 == %x, want %x", n, got, n)
-		}
-	}
-
-	{
-		var n int8 = 0x55
-		if got := byz8l(n); got != n {
-			t.Errorf("%x<<0 == %x, want %x", n, got, n)
-		}
-		if got := byz8r(n); got != n {
-			t.Errorf("%x>>0 == %x, want %x", n, got, n)
-		}
-	}
-	{
-		var n uint8 = 0x55
-		if got := byz8ur(n); got != n {
-			t.Errorf("%x>>>0 == %x, want %x", n, got, n)
-		}
-	}
-}
-
-//go:noinline
-func two64l(x int64) int64 {
-	return x << 1 << 1
-}
-
-//go:noinline
-func two64r(x int64) int64 {
-	return x >> 1 >> 1
-}
-
-//go:noinline
-func two64ur(x uint64) uint64 {
-	return x >> 1 >> 1
-}
-
-//go:noinline
-func two32l(x int32) int32 {
-	return x << 1 << 1
-}
-
-//go:noinline
-func two32r(x int32) int32 {
-	return x >> 1 >> 1
-}
-
-//go:noinline
-func two32ur(x uint32) uint32 {
-	return x >> 1 >> 1
-}
-
-//go:noinline
-func two16l(x int16) int16 {
-	return x << 1 << 1
-}
-
-//go:noinline
-func two16r(x int16) int16 {
-	return x >> 1 >> 1
-}
-
-//go:noinline
-func two16ur(x uint16) uint16 {
-	return x >> 1 >> 1
-}
-
-//go:noinline
-func two8l(x int8) int8 {
-	return x << 1 << 1
-}
-
-//go:noinline
-func two8r(x int8) int8 {
-	return x >> 1 >> 1
-}
-
-//go:noinline
-func two8ur(x uint8) uint8 {
-	return x >> 1 >> 1
-}
-
-func TestShiftCombine(t *testing.T) {
-	if got, want := two64l(4), int64(16); want != got {
-		t.Errorf("4<<1<<1 == %d, want %d", got, want)
-	}
-	if got, want := two64r(64), int64(16); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := two64ur(64), uint64(16); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := two32l(4), int32(16); want != got {
-		t.Errorf("4<<1<<1 == %d, want %d", got, want)
-	}
-	if got, want := two32r(64), int32(16); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := two32ur(64), uint32(16); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := two16l(4), int16(16); want != got {
-		t.Errorf("4<<1<<1 == %d, want %d", got, want)
-	}
-	if got, want := two16r(64), int16(16); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := two16ur(64), uint16(16); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := two8l(4), int8(16); want != got {
-		t.Errorf("4<<1<<1 == %d, want %d", got, want)
-	}
-	if got, want := two8r(64), int8(16); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := two8ur(64), uint8(16); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-
-}
-
-//go:noinline
-func three64l(x int64) int64 {
-	return x << 3 >> 1 << 2
-}
-
-//go:noinline
-func three64ul(x uint64) uint64 {
-	return x << 3 >> 1 << 2
-}
-
-//go:noinline
-func three64r(x int64) int64 {
-	return x >> 3 << 1 >> 2
-}
-
-//go:noinline
-func three64ur(x uint64) uint64 {
-	return x >> 3 << 1 >> 2
-}
-
-//go:noinline
-func three32l(x int32) int32 {
-	return x << 3 >> 1 << 2
-}
-
-//go:noinline
-func three32ul(x uint32) uint32 {
-	return x << 3 >> 1 << 2
-}
-
-//go:noinline
-func three32r(x int32) int32 {
-	return x >> 3 << 1 >> 2
-}
-
-//go:noinline
-func three32ur(x uint32) uint32 {
-	return x >> 3 << 1 >> 2
-}
-
-//go:noinline
-func three16l(x int16) int16 {
-	return x << 3 >> 1 << 2
-}
-
-//go:noinline
-func three16ul(x uint16) uint16 {
-	return x << 3 >> 1 << 2
-}
-
-//go:noinline
-func three16r(x int16) int16 {
-	return x >> 3 << 1 >> 2
-}
-
-//go:noinline
-func three16ur(x uint16) uint16 {
-	return x >> 3 << 1 >> 2
-}
-
-//go:noinline
-func three8l(x int8) int8 {
-	return x << 3 >> 1 << 2
-}
-
-//go:noinline
-func three8ul(x uint8) uint8 {
-	return x << 3 >> 1 << 2
-}
-
-//go:noinline
-func three8r(x int8) int8 {
-	return x >> 3 << 1 >> 2
-}
-
-//go:noinline
-func three8ur(x uint8) uint8 {
-	return x >> 3 << 1 >> 2
-}
-
-func TestShiftCombine3(t *testing.T) {
-	if got, want := three64l(4), int64(64); want != got {
-		t.Errorf("4<<1<<1 == %d, want %d", got, want)
-	}
-	if got, want := three64ul(4), uint64(64); want != got {
-		t.Errorf("4<<1<<1 == %d, want %d", got, want)
-	}
-	if got, want := three64r(64), int64(4); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := three64ur(64), uint64(4); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := three32l(4), int32(64); want != got {
-		t.Errorf("4<<1<<1 == %d, want %d", got, want)
-	}
-	if got, want := three32ul(4), uint32(64); want != got {
-		t.Errorf("4<<1<<1 == %d, want %d", got, want)
-	}
-	if got, want := three32r(64), int32(4); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := three32ur(64), uint32(4); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := three16l(4), int16(64); want != got {
-		t.Errorf("4<<1<<1 == %d, want %d", got, want)
-	}
-	if got, want := three16ul(4), uint16(64); want != got {
-		t.Errorf("4<<1<<1 == %d, want %d", got, want)
-	}
-	if got, want := three16r(64), int16(4); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := three16ur(64), uint16(4); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := three8l(4), int8(64); want != got {
-		t.Errorf("4<<1<<1 == %d, want %d", got, want)
-	}
-	if got, want := three8ul(4), uint8(64); want != got {
-		t.Errorf("4<<1<<1 == %d, want %d", got, want)
-	}
-	if got, want := three8r(64), int8(4); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-	if got, want := three8ur(64), uint8(4); want != got {
-		t.Errorf("64>>1>>1 == %d, want %d", got, want)
-	}
-}
-
-var (
-	one64  int64  = 1
-	one64u uint64 = 1
-	one32  int32  = 1
-	one32u uint32 = 1
-	one16  int16  = 1
-	one16u uint16 = 1
-	one8   int8   = 1
-	one8u  uint8  = 1
-)
-
-func TestShiftLargeCombine(t *testing.T) {
-	var N uint64 = 0x8000000000000000
-	if one64<<N<<N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one64>>N>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one64u>>N>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one32<<N<<N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one32>>N>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one32u>>N>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one16<<N<<N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one16>>N>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one16u>>N>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one8<<N<<N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one8>>N>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one8u>>N>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-}
-
-func TestShiftLargeCombine3(t *testing.T) {
-	var N uint64 = 0x8000000000000001
-	if one64<<N>>2<<N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one64u<<N>>2<<N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one64>>N<<2>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one64u>>N<<2>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one32<<N>>2<<N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one32u<<N>>2<<N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one32>>N<<2>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one32u>>N<<2>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one16<<N>>2<<N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one16u<<N>>2<<N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one16>>N<<2>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one16u>>N<<2>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one8<<N>>2<<N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one8u<<N>>2<<N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one8>>N<<2>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-	if one8u>>N<<2>>N == 1 {
-		t.Errorf("shift overflow mishandled")
-	}
-}
-
-func TestShiftGeneric(t *testing.T) {
-	for _, test := range [...]struct {
-		valueWidth int
-		signed     bool
-		shiftWidth int
-		left       bool
-		f          interface{}
-	}{
-		{64, true, 64, true, func(n int64, s uint64) int64 { return n << s }},
-		{64, true, 64, false, func(n int64, s uint64) int64 { return n >> s }},
-		{64, false, 64, false, func(n uint64, s uint64) uint64 { return n >> s }},
-		{64, true, 32, true, func(n int64, s uint32) int64 { return n << s }},
-		{64, true, 32, false, func(n int64, s uint32) int64 { return n >> s }},
-		{64, false, 32, false, func(n uint64, s uint32) uint64 { return n >> s }},
-		{64, true, 16, true, func(n int64, s uint16) int64 { return n << s }},
-		{64, true, 16, false, func(n int64, s uint16) int64 { return n >> s }},
-		{64, false, 16, false, func(n uint64, s uint16) uint64 { return n >> s }},
-		{64, true, 8, true, func(n int64, s uint8) int64 { return n << s }},
-		{64, true, 8, false, func(n int64, s uint8) int64 { return n >> s }},
-		{64, false, 8, false, func(n uint64, s uint8) uint64 { return n >> s }},
-
-		{32, true, 64, true, func(n int32, s uint64) int32 { return n << s }},
-		{32, true, 64, false, func(n int32, s uint64) int32 { return n >> s }},
-		{32, false, 64, false, func(n uint32, s uint64) uint32 { return n >> s }},
-		{32, true, 32, true, func(n int32, s uint32) int32 { return n << s }},
-		{32, true, 32, false, func(n int32, s uint32) int32 { return n >> s }},
-		{32, false, 32, false, func(n uint32, s uint32) uint32 { return n >> s }},
-		{32, true, 16, true, func(n int32, s uint16) int32 { return n << s }},
-		{32, true, 16, false, func(n int32, s uint16) int32 { return n >> s }},
-		{32, false, 16, false, func(n uint32, s uint16) uint32 { return n >> s }},
-		{32, true, 8, true, func(n int32, s uint8) int32 { return n << s }},
-		{32, true, 8, false, func(n int32, s uint8) int32 { return n >> s }},
-		{32, false, 8, false, func(n uint32, s uint8) uint32 { return n >> s }},
-
-		{16, true, 64, true, func(n int16, s uint64) int16 { return n << s }},
-		{16, true, 64, false, func(n int16, s uint64) int16 { return n >> s }},
-		{16, false, 64, false, func(n uint16, s uint64) uint16 { return n >> s }},
-		{16, true, 32, true, func(n int16, s uint32) int16 { return n << s }},
-		{16, true, 32, false, func(n int16, s uint32) int16 { return n >> s }},
-		{16, false, 32, false, func(n uint16, s uint32) uint16 { return n >> s }},
-		{16, true, 16, true, func(n int16, s uint16) int16 { return n << s }},
-		{16, true, 16, false, func(n int16, s uint16) int16 { return n >> s }},
-		{16, false, 16, false, func(n uint16, s uint16) uint16 { return n >> s }},
-		{16, true, 8, true, func(n int16, s uint8) int16 { return n << s }},
-		{16, true, 8, false, func(n int16, s uint8) int16 { return n >> s }},
-		{16, false, 8, false, func(n uint16, s uint8) uint16 { return n >> s }},
-
-		{8, true, 64, true, func(n int8, s uint64) int8 { return n << s }},
-		{8, true, 64, false, func(n int8, s uint64) int8 { return n >> s }},
-		{8, false, 64, false, func(n uint8, s uint64) uint8 { return n >> s }},
-		{8, true, 32, true, func(n int8, s uint32) int8 { return n << s }},
-		{8, true, 32, false, func(n int8, s uint32) int8 { return n >> s }},
-		{8, false, 32, false, func(n uint8, s uint32) uint8 { return n >> s }},
-		{8, true, 16, true, func(n int8, s uint16) int8 { return n << s }},
-		{8, true, 16, false, func(n int8, s uint16) int8 { return n >> s }},
-		{8, false, 16, false, func(n uint8, s uint16) uint8 { return n >> s }},
-		{8, true, 8, true, func(n int8, s uint8) int8 { return n << s }},
-		{8, true, 8, false, func(n int8, s uint8) int8 { return n >> s }},
-		{8, false, 8, false, func(n uint8, s uint8) uint8 { return n >> s }},
-	} {
-		fv := reflect.ValueOf(test.f)
-		var args [2]reflect.Value
-		for i := 0; i < test.valueWidth; i++ {
-			// Build value to be shifted.
-			var n int64 = 1
-			for j := 0; j < i; j++ {
-				n <<= 1
-			}
-			args[0] = reflect.ValueOf(n).Convert(fv.Type().In(0))
-			for s := 0; s <= test.shiftWidth; s++ {
-				args[1] = reflect.ValueOf(s).Convert(fv.Type().In(1))
-
-				// Compute desired result. We're testing variable shifts
-				// assuming constant shifts are correct.
-				r := n
-				var op string
-				switch {
-				case test.left:
-					op = "<<"
-					for j := 0; j < s; j++ {
-						r <<= 1
-					}
-					switch test.valueWidth {
-					case 32:
-						r = int64(int32(r))
-					case 16:
-						r = int64(int16(r))
-					case 8:
-						r = int64(int8(r))
-					}
-				case test.signed:
-					op = ">>"
-					switch test.valueWidth {
-					case 32:
-						r = int64(int32(r))
-					case 16:
-						r = int64(int16(r))
-					case 8:
-						r = int64(int8(r))
-					}
-					for j := 0; j < s; j++ {
-						r >>= 1
-					}
-				default:
-					op = ">>>"
-					for j := 0; j < s; j++ {
-						r = int64(uint64(r) >> 1)
-					}
-				}
-
-				// Call function.
-				res := fv.Call(args[:])[0].Convert(reflect.ValueOf(r).Type())
-
-				if res.Int() != r {
-					t.Errorf("%s%dx%d(%x,%x)=%x, want %x", op, test.valueWidth, test.shiftWidth, n, s, res.Int(), r)
-				}
-			}
-		}
-	}
-}
diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go
deleted file mode 100644
index 4d0837b..0000000
--- a/src/cmd/compile/internal/gc/sinit.go
+++ /dev/null
@@ -1,1172 +0,0 @@
-// Copyright 2009 The Go Authors. 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/compile/internal/types"
-	"cmd/internal/obj"
-	"fmt"
-)
-
-type InitEntry struct {
-	Xoffset int64 // struct, array only
-	Expr    *Node // bytes of run-time computed expressions
-}
-
-type InitPlan struct {
-	E []InitEntry
-}
-
-// An InitSchedule is used to decompose assignment statements into
-// static and dynamic initialization parts. Static initializations are
-// handled by populating variables' linker symbol data, while dynamic
-// initializations are accumulated to be executed in order.
-type InitSchedule struct {
-	// out is the ordered list of dynamic initialization
-	// statements.
-	out []*Node
-
-	initplans map[*Node]*InitPlan
-	inittemps map[*Node]*Node
-}
-
-func (s *InitSchedule) append(n *Node) {
-	s.out = append(s.out, n)
-}
-
-// staticInit adds an initialization statement n to the schedule.
-func (s *InitSchedule) staticInit(n *Node) {
-	if !s.tryStaticInit(n) {
-		if Debug.P != 0 {
-			Dump("nonstatic", n)
-		}
-		s.append(n)
-	}
-}
-
-// tryStaticInit attempts to statically execute an initialization
-// statement and reports whether it succeeded.
-func (s *InitSchedule) tryStaticInit(n *Node) bool {
-	// Only worry about simple "l = r" assignments. Multiple
-	// variable/expression OAS2 assignments have already been
-	// replaced by multiple simple OAS assignments, and the other
-	// OAS2* assignments mostly necessitate dynamic execution
-	// anyway.
-	if n.Op != OAS {
-		return false
-	}
-	if n.Left.isBlank() && candiscard(n.Right) {
-		return true
-	}
-	lno := setlineno(n)
-	defer func() { lineno = lno }()
-	return s.staticassign(n.Left, n.Right)
-}
-
-// like staticassign but we are copying an already
-// initialized value r.
-func (s *InitSchedule) staticcopy(l *Node, r *Node) bool {
-	if r.Op != ONAME {
-		return false
-	}
-	if r.Class() == PFUNC {
-		pfuncsym(l, r)
-		return true
-	}
-	if r.Class() != PEXTERN || r.Sym.Pkg != localpkg {
-		return false
-	}
-	if r.Name.Defn == nil { // probably zeroed but perhaps supplied externally and of unknown value
-		return false
-	}
-	if r.Name.Defn.Op != OAS {
-		return false
-	}
-	if r.Type.IsString() { // perhaps overwritten by cmd/link -X (#34675)
-		return false
-	}
-	orig := r
-	r = r.Name.Defn.Right
-
-	for r.Op == OCONVNOP && !types.Identical(r.Type, l.Type) {
-		r = r.Left
-	}
-
-	switch r.Op {
-	case ONAME:
-		if s.staticcopy(l, r) {
-			return true
-		}
-		// We may have skipped past one or more OCONVNOPs, so
-		// use conv to ensure r is assignable to l (#13263).
-		s.append(nod(OAS, l, conv(r, l.Type)))
-		return true
-
-	case OLITERAL:
-		if isZero(r) {
-			return true
-		}
-		litsym(l, r, int(l.Type.Width))
-		return true
-
-	case OADDR:
-		if a := r.Left; a.Op == ONAME {
-			addrsym(l, a)
-			return true
-		}
-
-	case OPTRLIT:
-		switch r.Left.Op {
-		case OARRAYLIT, OSLICELIT, OSTRUCTLIT, OMAPLIT:
-			// copy pointer
-			addrsym(l, s.inittemps[r])
-			return true
-		}
-
-	case OSLICELIT:
-		// copy slice
-		a := s.inittemps[r]
-		slicesym(l, a, r.Right.Int64Val())
-		return true
-
-	case OARRAYLIT, OSTRUCTLIT:
-		p := s.initplans[r]
-
-		n := l.copy()
-		for i := range p.E {
-			e := &p.E[i]
-			n.Xoffset = l.Xoffset + e.Xoffset
-			n.Type = e.Expr.Type
-			if e.Expr.Op == OLITERAL {
-				litsym(n, e.Expr, int(n.Type.Width))
-				continue
-			}
-			ll := n.sepcopy()
-			if s.staticcopy(ll, e.Expr) {
-				continue
-			}
-			// Requires computation, but we're
-			// copying someone else's computation.
-			rr := orig.sepcopy()
-			rr.Type = ll.Type
-			rr.Xoffset += e.Xoffset
-			setlineno(rr)
-			s.append(nod(OAS, ll, rr))
-		}
-
-		return true
-	}
-
-	return false
-}
-
-func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
-	for r.Op == OCONVNOP {
-		r = r.Left
-	}
-
-	switch r.Op {
-	case ONAME:
-		return s.staticcopy(l, r)
-
-	case OLITERAL:
-		if isZero(r) {
-			return true
-		}
-		litsym(l, r, int(l.Type.Width))
-		return true
-
-	case OADDR:
-		var nam Node
-		if stataddr(&nam, r.Left) {
-			addrsym(l, &nam)
-			return true
-		}
-		fallthrough
-
-	case OPTRLIT:
-		switch r.Left.Op {
-		case OARRAYLIT, OSLICELIT, OMAPLIT, OSTRUCTLIT:
-			// Init pointer.
-			a := staticname(r.Left.Type)
-
-			s.inittemps[r] = a
-			addrsym(l, a)
-
-			// Init underlying literal.
-			if !s.staticassign(a, r.Left) {
-				s.append(nod(OAS, a, r.Left))
-			}
-			return true
-		}
-		//dump("not static ptrlit", r);
-
-	case OSTR2BYTES:
-		if l.Class() == PEXTERN && r.Left.Op == OLITERAL {
-			sval := r.Left.StringVal()
-			slicebytes(l, sval)
-			return true
-		}
-
-	case OSLICELIT:
-		s.initplan(r)
-		// Init slice.
-		bound := r.Right.Int64Val()
-		ta := types.NewArray(r.Type.Elem(), bound)
-		ta.SetNoalg(true)
-		a := staticname(ta)
-		s.inittemps[r] = a
-		slicesym(l, a, bound)
-		// Fall through to init underlying array.
-		l = a
-		fallthrough
-
-	case OARRAYLIT, OSTRUCTLIT:
-		s.initplan(r)
-
-		p := s.initplans[r]
-		n := l.copy()
-		for i := range p.E {
-			e := &p.E[i]
-			n.Xoffset = l.Xoffset + e.Xoffset
-			n.Type = e.Expr.Type
-			if e.Expr.Op == OLITERAL {
-				litsym(n, e.Expr, int(n.Type.Width))
-				continue
-			}
-			setlineno(e.Expr)
-			a := n.sepcopy()
-			if !s.staticassign(a, e.Expr) {
-				s.append(nod(OAS, a, e.Expr))
-			}
-		}
-
-		return true
-
-	case OMAPLIT:
-		break
-
-	case OCLOSURE:
-		if hasemptycvars(r) {
-			if Debug_closure > 0 {
-				Warnl(r.Pos, "closure converted to global")
-			}
-			// Closures with no captured variables are globals,
-			// so the assignment can be done at link time.
-			pfuncsym(l, r.Func.Closure.Func.Nname)
-			return true
-		}
-		closuredebugruntimecheck(r)
-
-	case OCONVIFACE:
-		// This logic is mirrored in isStaticCompositeLiteral.
-		// If you change something here, change it there, and vice versa.
-
-		// Determine the underlying concrete type and value we are converting from.
-		val := r
-		for val.Op == OCONVIFACE {
-			val = val.Left
-		}
-		if val.Type.IsInterface() {
-			// val is an interface type.
-			// If val is nil, we can statically initialize l;
-			// both words are zero and so there no work to do, so report success.
-			// If val is non-nil, we have no concrete type to record,
-			// and we won't be able to statically initialize its value, so report failure.
-			return Isconst(val, CTNIL)
-		}
-
-		markTypeUsedInInterface(val.Type, l.Sym.Linksym())
-
-		var itab *Node
-		if l.Type.IsEmptyInterface() {
-			itab = typename(val.Type)
-		} else {
-			itab = itabname(val.Type, l.Type)
-		}
-
-		// Create a copy of l to modify while we emit data.
-		n := l.copy()
-
-		// Emit itab, advance offset.
-		addrsym(n, itab.Left) // itab is an OADDR node
-		n.Xoffset += int64(Widthptr)
-
-		// Emit data.
-		if isdirectiface(val.Type) {
-			if Isconst(val, CTNIL) {
-				// Nil is zero, nothing to do.
-				return true
-			}
-			// Copy val directly into n.
-			n.Type = val.Type
-			setlineno(val)
-			a := n.sepcopy()
-			if !s.staticassign(a, val) {
-				s.append(nod(OAS, a, val))
-			}
-		} else {
-			// Construct temp to hold val, write pointer to temp into n.
-			a := staticname(val.Type)
-			s.inittemps[val] = a
-			if !s.staticassign(a, val) {
-				s.append(nod(OAS, a, val))
-			}
-			addrsym(n, a)
-		}
-
-		return true
-	}
-
-	//dump("not static", r);
-	return false
-}
-
-// initContext is the context in which static data is populated.
-// It is either in an init function or in any other function.
-// Static data populated in an init function will be written either
-// zero times (as a readonly, static data symbol) or
-// one time (during init function execution).
-// Either way, there is no opportunity for races or further modification,
-// so the data can be written to a (possibly readonly) data symbol.
-// Static data populated in any other function needs to be local to
-// that function to allow multiple instances of that function
-// to execute concurrently without clobbering each others' data.
-type initContext uint8
-
-const (
-	inInitFunction initContext = iota
-	inNonInitFunction
-)
-
-func (c initContext) String() string {
-	if c == inInitFunction {
-		return "inInitFunction"
-	}
-	return "inNonInitFunction"
-}
-
-// from here down is the walk analysis
-// of composite literals.
-// most of the work is to generate
-// data statements for the constant
-// part of the composite literal.
-
-var statuniqgen int // name generator for static temps
-
-// staticname returns a name backed by a (writable) static data symbol.
-// Use readonlystaticname for read-only node.
-func staticname(t *types.Type) *Node {
-	// Don't use lookupN; it interns the resulting string, but these are all unique.
-	n := newname(lookup(fmt.Sprintf("%s%d", obj.StaticNamePref, statuniqgen)))
-	statuniqgen++
-	addvar(n, t, PEXTERN)
-	return n
-}
-
-// readonlystaticname returns a name backed by a read-only static data symbol.
-func readonlystaticname(t *types.Type) *Node {
-	n := staticname(t)
-	n.MarkReadonly()
-	n.Sym.Linksym().Set(obj.AttrContentAddressable, true)
-	n.Sym.Linksym().Set(obj.AttrLocal, true)
-	return n
-}
-
-func (n *Node) isSimpleName() bool {
-	return n.Op == ONAME && n.Class() != PAUTOHEAP && n.Class() != PEXTERN
-}
-
-func litas(l *Node, r *Node, init *Nodes) {
-	a := nod(OAS, l, r)
-	a = typecheck(a, ctxStmt)
-	a = walkexpr(a, init)
-	init.Append(a)
-}
-
-// initGenType is a bitmap indicating the types of generation that will occur for a static value.
-type initGenType uint8
-
-const (
-	initDynamic initGenType = 1 << iota // contains some dynamic values, for which init code will be generated
-	initConst                           // contains some constant values, which may be written into data symbols
-)
-
-// getdyn calculates the initGenType for n.
-// If top is false, getdyn is recursing.
-func getdyn(n *Node, top bool) initGenType {
-	switch n.Op {
-	default:
-		if n.isGoConst() {
-			return initConst
-		}
-		return initDynamic
-
-	case OSLICELIT:
-		if !top {
-			return initDynamic
-		}
-		if n.Right.Int64Val()/4 > int64(n.List.Len()) {
-			// <25% of entries have explicit values.
-			// Very rough estimation, it takes 4 bytes of instructions
-			// to initialize 1 byte of result. So don't use a static
-			// initializer if the dynamic initialization code would be
-			// smaller than the static value.
-			// See issue 23780.
-			return initDynamic
-		}
-
-	case OARRAYLIT, OSTRUCTLIT:
-	}
-
-	var mode initGenType
-	for _, n1 := range n.List.Slice() {
-		switch n1.Op {
-		case OKEY:
-			n1 = n1.Right
-		case OSTRUCTKEY:
-			n1 = n1.Left
-		}
-		mode |= getdyn(n1, false)
-		if mode == initDynamic|initConst {
-			break
-		}
-	}
-	return mode
-}
-
-// isStaticCompositeLiteral reports whether n is a compile-time constant.
-func isStaticCompositeLiteral(n *Node) bool {
-	switch n.Op {
-	case OSLICELIT:
-		return false
-	case OARRAYLIT:
-		for _, r := range n.List.Slice() {
-			if r.Op == OKEY {
-				r = r.Right
-			}
-			if !isStaticCompositeLiteral(r) {
-				return false
-			}
-		}
-		return true
-	case OSTRUCTLIT:
-		for _, r := range n.List.Slice() {
-			if r.Op != OSTRUCTKEY {
-				Fatalf("isStaticCompositeLiteral: rhs not OSTRUCTKEY: %v", r)
-			}
-			if !isStaticCompositeLiteral(r.Left) {
-				return false
-			}
-		}
-		return true
-	case OLITERAL:
-		return true
-	case OCONVIFACE:
-		// See staticassign's OCONVIFACE case for comments.
-		val := n
-		for val.Op == OCONVIFACE {
-			val = val.Left
-		}
-		if val.Type.IsInterface() {
-			return Isconst(val, CTNIL)
-		}
-		if isdirectiface(val.Type) && Isconst(val, CTNIL) {
-			return true
-		}
-		return isStaticCompositeLiteral(val)
-	}
-	return false
-}
-
-// initKind is a kind of static initialization: static, dynamic, or local.
-// Static initialization represents literals and
-// literal components of composite literals.
-// Dynamic initialization represents non-literals and
-// non-literal components of composite literals.
-// LocalCode initialization represents initialization
-// that occurs purely in generated code local to the function of use.
-// Initialization code is sometimes generated in passes,
-// first static then dynamic.
-type initKind uint8
-
-const (
-	initKindStatic initKind = iota + 1
-	initKindDynamic
-	initKindLocalCode
-)
-
-// fixedlit handles struct, array, and slice literals.
-// TODO: expand documentation.
-func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes) {
-	isBlank := var_ == nblank
-	var splitnode func(*Node) (a *Node, value *Node)
-	switch n.Op {
-	case OARRAYLIT, OSLICELIT:
-		var k int64
-		splitnode = func(r *Node) (*Node, *Node) {
-			if r.Op == OKEY {
-				k = indexconst(r.Left)
-				if k < 0 {
-					Fatalf("fixedlit: invalid index %v", r.Left)
-				}
-				r = r.Right
-			}
-			a := nod(OINDEX, var_, nodintconst(k))
-			k++
-			if isBlank {
-				a = nblank
-			}
-			return a, r
-		}
-	case OSTRUCTLIT:
-		splitnode = func(r *Node) (*Node, *Node) {
-			if r.Op != OSTRUCTKEY {
-				Fatalf("fixedlit: rhs not OSTRUCTKEY: %v", r)
-			}
-			if r.Sym.IsBlank() || isBlank {
-				return nblank, r.Left
-			}
-			setlineno(r)
-			return nodSym(ODOT, var_, r.Sym), r.Left
-		}
-	default:
-		Fatalf("fixedlit bad op: %v", n.Op)
-	}
-
-	for _, r := range n.List.Slice() {
-		a, value := splitnode(r)
-		if a == nblank && candiscard(value) {
-			continue
-		}
-
-		switch value.Op {
-		case OSLICELIT:
-			if (kind == initKindStatic && ctxt == inNonInitFunction) || (kind == initKindDynamic && ctxt == inInitFunction) {
-				slicelit(ctxt, value, a, init)
-				continue
-			}
-
-		case OARRAYLIT, OSTRUCTLIT:
-			fixedlit(ctxt, kind, value, a, init)
-			continue
-		}
-
-		islit := value.isGoConst()
-		if (kind == initKindStatic && !islit) || (kind == initKindDynamic && islit) {
-			continue
-		}
-
-		// build list of assignments: var[index] = expr
-		setlineno(a)
-		a = nod(OAS, a, value)
-		a = typecheck(a, ctxStmt)
-		switch kind {
-		case initKindStatic:
-			genAsStatic(a)
-		case initKindDynamic, initKindLocalCode:
-			a = orderStmtInPlace(a, map[string][]*Node{})
-			a = walkstmt(a)
-			init.Append(a)
-		default:
-			Fatalf("fixedlit: bad kind %d", kind)
-		}
-
-	}
-}
-
-func isSmallSliceLit(n *Node) bool {
-	if n.Op != OSLICELIT {
-		return false
-	}
-
-	r := n.Right
-
-	return smallintconst(r) && (n.Type.Elem().Width == 0 || r.Int64Val() <= smallArrayBytes/n.Type.Elem().Width)
-}
-
-func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
-	// make an array type corresponding the number of elements we have
-	t := types.NewArray(n.Type.Elem(), n.Right.Int64Val())
-	dowidth(t)
-
-	if ctxt == inNonInitFunction {
-		// put everything into static array
-		vstat := staticname(t)
-
-		fixedlit(ctxt, initKindStatic, n, vstat, init)
-		fixedlit(ctxt, initKindDynamic, n, vstat, init)
-
-		// copy static to slice
-		var_ = typecheck(var_, ctxExpr|ctxAssign)
-		var nam Node
-		if !stataddr(&nam, var_) || nam.Class() != PEXTERN {
-			Fatalf("slicelit: %v", var_)
-		}
-		slicesym(&nam, vstat, t.NumElem())
-		return
-	}
-
-	// recipe for var = []t{...}
-	// 1. make a static array
-	//	var vstat [...]t
-	// 2. assign (data statements) the constant part
-	//	vstat = constpart{}
-	// 3. make an auto pointer to array and allocate heap to it
-	//	var vauto *[...]t = new([...]t)
-	// 4. copy the static array to the auto array
-	//	*vauto = vstat
-	// 5. for each dynamic part assign to the array
-	//	vauto[i] = dynamic part
-	// 6. assign slice of allocated heap to var
-	//	var = vauto[:]
-	//
-	// an optimization is done if there is no constant part
-	//	3. var vauto *[...]t = new([...]t)
-	//	5. vauto[i] = dynamic part
-	//	6. var = vauto[:]
-
-	// if the literal contains constants,
-	// make static initialized array (1),(2)
-	var vstat *Node
-
-	mode := getdyn(n, true)
-	if mode&initConst != 0 && !isSmallSliceLit(n) {
-		if ctxt == inInitFunction {
-			vstat = readonlystaticname(t)
-		} else {
-			vstat = staticname(t)
-		}
-		fixedlit(ctxt, initKindStatic, n, vstat, init)
-	}
-
-	// make new auto *array (3 declare)
-	vauto := temp(types.NewPtr(t))
-
-	// set auto to point at new temp or heap (3 assign)
-	var a *Node
-	if x := prealloc[n]; x != nil {
-		// temp allocated during order.go for dddarg
-		if !types.Identical(t, x.Type) {
-			panic("dotdotdot base type does not match order's assigned type")
-		}
-
-		if vstat == nil {
-			a = nod(OAS, x, nil)
-			a = typecheck(a, ctxStmt)
-			init.Append(a) // zero new temp
-		} else {
-			// Declare that we're about to initialize all of x.
-			// (Which happens at the *vauto = vstat below.)
-			init.Append(nod(OVARDEF, x, nil))
-		}
-
-		a = nod(OADDR, x, nil)
-	} else if n.Esc == EscNone {
-		a = temp(t)
-		if vstat == nil {
-			a = nod(OAS, temp(t), nil)
-			a = typecheck(a, ctxStmt)
-			init.Append(a) // zero new temp
-			a = a.Left
-		} else {
-			init.Append(nod(OVARDEF, a, nil))
-		}
-
-		a = nod(OADDR, a, nil)
-	} else {
-		a = nod(ONEW, nil, nil)
-		a.List.Set1(typenod(t))
-	}
-
-	a = nod(OAS, vauto, a)
-	a = typecheck(a, ctxStmt)
-	a = walkexpr(a, init)
-	init.Append(a)
-
-	if vstat != nil {
-		// copy static to heap (4)
-		a = nod(ODEREF, vauto, nil)
-
-		a = nod(OAS, a, vstat)
-		a = typecheck(a, ctxStmt)
-		a = walkexpr(a, init)
-		init.Append(a)
-	}
-
-	// put dynamics into array (5)
-	var index int64
-	for _, value := range n.List.Slice() {
-		if value.Op == OKEY {
-			index = indexconst(value.Left)
-			if index < 0 {
-				Fatalf("slicelit: invalid index %v", value.Left)
-			}
-			value = value.Right
-		}
-		a := nod(OINDEX, vauto, nodintconst(index))
-		a.SetBounded(true)
-		index++
-
-		// TODO need to check bounds?
-
-		switch value.Op {
-		case OSLICELIT:
-			break
-
-		case OARRAYLIT, OSTRUCTLIT:
-			k := initKindDynamic
-			if vstat == nil {
-				// Generate both static and dynamic initializations.
-				// See issue #31987.
-				k = initKindLocalCode
-			}
-			fixedlit(ctxt, k, value, a, init)
-			continue
-		}
-
-		if vstat != nil && value.isGoConst() { // already set by copy from static value
-			continue
-		}
-
-		// build list of vauto[c] = expr
-		setlineno(value)
-		a = nod(OAS, a, value)
-
-		a = typecheck(a, ctxStmt)
-		a = orderStmtInPlace(a, map[string][]*Node{})
-		a = walkstmt(a)
-		init.Append(a)
-	}
-
-	// make slice out of heap (6)
-	a = nod(OAS, var_, nod(OSLICE, vauto, nil))
-
-	a = typecheck(a, ctxStmt)
-	a = orderStmtInPlace(a, map[string][]*Node{})
-	a = walkstmt(a)
-	init.Append(a)
-}
-
-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)
-
-	entries := n.List.Slice()
-
-	// The order pass already removed any dynamic (runtime-computed) entries.
-	// All remaining entries are static. Double-check that.
-	for _, r := range entries {
-		if !isStaticCompositeLiteral(r.Left) || !isStaticCompositeLiteral(r.Right) {
-			Fatalf("maplit: entry is not a literal: %v", r)
-		}
-	}
-
-	if len(entries) > 25 {
-		// For a large number of entries, put them in an array and loop.
-
-		// build types [count]Tindex and [count]Tvalue
-		tk := types.NewArray(n.Type.Key(), int64(len(entries)))
-		te := types.NewArray(n.Type.Elem(), int64(len(entries)))
-
-		tk.SetNoalg(true)
-		te.SetNoalg(true)
-
-		dowidth(tk)
-		dowidth(te)
-
-		// make and initialize static arrays
-		vstatk := readonlystaticname(tk)
-		vstate := readonlystaticname(te)
-
-		datak := nod(OARRAYLIT, nil, nil)
-		datae := nod(OARRAYLIT, nil, nil)
-		for _, r := range entries {
-			datak.List.Append(r.Left)
-			datae.List.Append(r.Right)
-		}
-		fixedlit(inInitFunction, initKindStatic, datak, vstatk, init)
-		fixedlit(inInitFunction, initKindStatic, datae, vstate, init)
-
-		// loop adding structure elements to map
-		// for i = 0; i < len(vstatk); i++ {
-		//	map[vstatk[i]] = vstate[i]
-		// }
-		i := temp(types.Types[TINT])
-		rhs := nod(OINDEX, vstate, i)
-		rhs.SetBounded(true)
-
-		kidx := nod(OINDEX, vstatk, i)
-		kidx.SetBounded(true)
-		lhs := nod(OINDEX, m, kidx)
-
-		zero := nod(OAS, i, nodintconst(0))
-		cond := nod(OLT, i, nodintconst(tk.NumElem()))
-		incr := nod(OAS, i, nod(OADD, i, nodintconst(1)))
-		body := nod(OAS, lhs, rhs)
-
-		loop := nod(OFOR, cond, incr)
-		loop.Nbody.Set1(body)
-		loop.Ninit.Set1(zero)
-
-		loop = typecheck(loop, ctxStmt)
-		loop = walkstmt(loop)
-		init.Append(loop)
-		return
-	}
-	// For a small number of entries, just add them directly.
-
-	// Build list of var[c] = expr.
-	// Use temporaries so that mapassign1 can have addressable key, elem.
-	// TODO(josharian): avoid map key temporaries for mapfast_* assignments with literal keys.
-	tmpkey := temp(m.Type.Key())
-	tmpelem := temp(m.Type.Elem())
-
-	for _, r := range entries {
-		index, elem := r.Left, r.Right
-
-		setlineno(index)
-		a := nod(OAS, tmpkey, index)
-		a = typecheck(a, ctxStmt)
-		a = walkstmt(a)
-		init.Append(a)
-
-		setlineno(elem)
-		a = nod(OAS, tmpelem, elem)
-		a = typecheck(a, ctxStmt)
-		a = walkstmt(a)
-		init.Append(a)
-
-		setlineno(tmpelem)
-		a = nod(OAS, nod(OINDEX, m, tmpkey), tmpelem)
-		a = typecheck(a, ctxStmt)
-		a = walkstmt(a)
-		init.Append(a)
-	}
-
-	a = nod(OVARKILL, tmpkey, nil)
-	a = typecheck(a, ctxStmt)
-	init.Append(a)
-	a = nod(OVARKILL, tmpelem, nil)
-	a = typecheck(a, ctxStmt)
-	init.Append(a)
-}
-
-func anylit(n *Node, var_ *Node, init *Nodes) {
-	t := n.Type
-	switch n.Op {
-	default:
-		Fatalf("anylit: not lit, op=%v node=%v", n.Op, n)
-
-	case ONAME:
-		a := nod(OAS, var_, n)
-		a = typecheck(a, ctxStmt)
-		init.Append(a)
-
-	case OPTRLIT:
-		if !t.IsPtr() {
-			Fatalf("anylit: not ptr")
-		}
-
-		var r *Node
-		if n.Right != nil {
-			// n.Right is stack temporary used as backing store.
-			init.Append(nod(OAS, n.Right, nil)) // zero backing store, just in case (#18410)
-			r = nod(OADDR, n.Right, nil)
-			r = typecheck(r, ctxExpr)
-		} else {
-			r = nod(ONEW, nil, nil)
-			r.SetTypecheck(1)
-			r.Type = t
-			r.Esc = n.Esc
-		}
-
-		r = walkexpr(r, init)
-		a := nod(OAS, var_, r)
-
-		a = typecheck(a, ctxStmt)
-		init.Append(a)
-
-		var_ = nod(ODEREF, var_, nil)
-		var_ = typecheck(var_, ctxExpr|ctxAssign)
-		anylit(n.Left, var_, init)
-
-	case OSTRUCTLIT, OARRAYLIT:
-		if !t.IsStruct() && !t.IsArray() {
-			Fatalf("anylit: not struct/array")
-		}
-
-		if var_.isSimpleName() && n.List.Len() > 4 {
-			// lay out static data
-			vstat := readonlystaticname(t)
-
-			ctxt := inInitFunction
-			if n.Op == OARRAYLIT {
-				ctxt = inNonInitFunction
-			}
-			fixedlit(ctxt, initKindStatic, n, vstat, init)
-
-			// copy static to var
-			a := nod(OAS, var_, vstat)
-
-			a = typecheck(a, ctxStmt)
-			a = walkexpr(a, init)
-			init.Append(a)
-
-			// add expressions to automatic
-			fixedlit(inInitFunction, initKindDynamic, n, var_, init)
-			break
-		}
-
-		var components int64
-		if n.Op == OARRAYLIT {
-			components = t.NumElem()
-		} else {
-			components = int64(t.NumFields())
-		}
-		// initialization of an array or struct with unspecified components (missing fields or arrays)
-		if var_.isSimpleName() || int64(n.List.Len()) < components {
-			a := nod(OAS, var_, nil)
-			a = typecheck(a, ctxStmt)
-			a = walkexpr(a, init)
-			init.Append(a)
-		}
-
-		fixedlit(inInitFunction, initKindLocalCode, n, var_, init)
-
-	case OSLICELIT:
-		slicelit(inInitFunction, n, var_, init)
-
-	case OMAPLIT:
-		if !t.IsMap() {
-			Fatalf("anylit: not map")
-		}
-		maplit(n, var_, init)
-	}
-}
-
-func oaslit(n *Node, init *Nodes) bool {
-	if n.Left == nil || n.Right == nil {
-		// not a special composite literal assignment
-		return false
-	}
-	if n.Left.Type == nil || n.Right.Type == nil {
-		// not a special composite literal assignment
-		return false
-	}
-	if !n.Left.isSimpleName() {
-		// not a special composite literal assignment
-		return false
-	}
-	if !types.Identical(n.Left.Type, n.Right.Type) {
-		// not a special composite literal assignment
-		return false
-	}
-
-	switch n.Right.Op {
-	default:
-		// not a special composite literal assignment
-		return false
-
-	case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
-		if vmatch1(n.Left, n.Right) {
-			// not a special composite literal assignment
-			return false
-		}
-		anylit(n.Right, n.Left, init)
-	}
-
-	n.Op = OEMPTY
-	n.Right = nil
-	return true
-}
-
-func getlit(lit *Node) int {
-	if smallintconst(lit) {
-		return int(lit.Int64Val())
-	}
-	return -1
-}
-
-// stataddr sets nam to the static address of n and reports whether it succeeded.
-func stataddr(nam *Node, n *Node) bool {
-	if n == nil {
-		return false
-	}
-
-	switch n.Op {
-	case ONAME:
-		*nam = *n
-		return true
-
-	case ODOT:
-		if !stataddr(nam, n.Left) {
-			break
-		}
-		nam.Xoffset += n.Xoffset
-		nam.Type = n.Type
-		return true
-
-	case OINDEX:
-		if n.Left.Type.IsSlice() {
-			break
-		}
-		if !stataddr(nam, n.Left) {
-			break
-		}
-		l := getlit(n.Right)
-		if l < 0 {
-			break
-		}
-
-		// Check for overflow.
-		if n.Type.Width != 0 && thearch.MAXWIDTH/n.Type.Width <= int64(l) {
-			break
-		}
-		nam.Xoffset += int64(l) * n.Type.Width
-		nam.Type = n.Type
-		return true
-	}
-
-	return false
-}
-
-func (s *InitSchedule) initplan(n *Node) {
-	if s.initplans[n] != nil {
-		return
-	}
-	p := new(InitPlan)
-	s.initplans[n] = p
-	switch n.Op {
-	default:
-		Fatalf("initplan")
-
-	case OARRAYLIT, OSLICELIT:
-		var k int64
-		for _, a := range n.List.Slice() {
-			if a.Op == OKEY {
-				k = indexconst(a.Left)
-				if k < 0 {
-					Fatalf("initplan arraylit: invalid index %v", a.Left)
-				}
-				a = a.Right
-			}
-			s.addvalue(p, k*n.Type.Elem().Width, a)
-			k++
-		}
-
-	case OSTRUCTLIT:
-		for _, a := range n.List.Slice() {
-			if a.Op != OSTRUCTKEY {
-				Fatalf("initplan structlit")
-			}
-			if a.Sym.IsBlank() {
-				continue
-			}
-			s.addvalue(p, a.Xoffset, a.Left)
-		}
-
-	case OMAPLIT:
-		for _, a := range n.List.Slice() {
-			if a.Op != OKEY {
-				Fatalf("initplan maplit")
-			}
-			s.addvalue(p, -1, a.Right)
-		}
-	}
-}
-
-func (s *InitSchedule) addvalue(p *InitPlan, xoffset int64, n *Node) {
-	// special case: zero can be dropped entirely
-	if isZero(n) {
-		return
-	}
-
-	// special case: inline struct and array (not slice) literals
-	if isvaluelit(n) {
-		s.initplan(n)
-		q := s.initplans[n]
-		for _, qe := range q.E {
-			// qe is a copy; we are not modifying entries in q.E
-			qe.Xoffset += xoffset
-			p.E = append(p.E, qe)
-		}
-		return
-	}
-
-	// add to plan
-	p.E = append(p.E, InitEntry{Xoffset: xoffset, Expr: n})
-}
-
-func isZero(n *Node) bool {
-	switch n.Op {
-	case OLITERAL:
-		switch u := n.Val().U.(type) {
-		default:
-			Dump("unexpected literal", n)
-			Fatalf("isZero")
-		case *NilVal:
-			return true
-		case string:
-			return u == ""
-		case bool:
-			return !u
-		case *Mpint:
-			return u.CmpInt64(0) == 0
-		case *Mpflt:
-			return u.CmpFloat64(0) == 0
-		case *Mpcplx:
-			return u.Real.CmpFloat64(0) == 0 && u.Imag.CmpFloat64(0) == 0
-		}
-
-	case OARRAYLIT:
-		for _, n1 := range n.List.Slice() {
-			if n1.Op == OKEY {
-				n1 = n1.Right
-			}
-			if !isZero(n1) {
-				return false
-			}
-		}
-		return true
-
-	case OSTRUCTLIT:
-		for _, n1 := range n.List.Slice() {
-			if !isZero(n1.Left) {
-				return false
-			}
-		}
-		return true
-	}
-
-	return false
-}
-
-func isvaluelit(n *Node) bool {
-	return n.Op == OARRAYLIT || n.Op == OSTRUCTLIT
-}
-
-func genAsStatic(as *Node) {
-	if as.Left.Type == nil {
-		Fatalf("genAsStatic as.Left not typechecked")
-	}
-
-	var nam Node
-	if !stataddr(&nam, as.Left) || (nam.Class() != PEXTERN && as.Left != nblank) {
-		Fatalf("genAsStatic: lhs %v", as.Left)
-	}
-
-	switch {
-	case as.Right.Op == OLITERAL:
-		litsym(&nam, as.Right, int(as.Right.Type.Width))
-	case as.Right.Op == ONAME && as.Right.Class() == PFUNC:
-		pfuncsym(&nam, as.Right)
-	default:
-		Fatalf("genAsStatic: rhs %v", as.Right)
-	}
-}
diff --git a/src/cmd/compile/internal/gc/sizeof_test.go b/src/cmd/compile/internal/gc/sizeof_test.go
deleted file mode 100644
index ce4a216..0000000
--- a/src/cmd/compile/internal/gc/sizeof_test.go
+++ /dev/null
@@ -1,39 +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.
-
-package gc
-
-import (
-	"reflect"
-	"testing"
-	"unsafe"
-)
-
-// Assert that the size of important structures do not change unexpectedly.
-
-func TestSizeof(t *testing.T) {
-	const _64bit = unsafe.Sizeof(uintptr(0)) == 8
-
-	var tests = []struct {
-		val    interface{} // type as a value
-		_32bit uintptr     // size on 32bit platforms
-		_64bit uintptr     // size on 64bit platforms
-	}{
-		{Func{}, 124, 224},
-		{Name{}, 32, 56},
-		{Param{}, 24, 48},
-		{Node{}, 76, 128},
-	}
-
-	for _, tt := range tests {
-		want := tt._32bit
-		if _64bit {
-			want = tt._64bit
-		}
-		got := reflect.TypeOf(tt.val).Size()
-		if want != got {
-			t.Errorf("unsafe.Sizeof(%T) = %d, want %d", tt.val, got, want)
-		}
-	}
-}
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
deleted file mode 100644
index 5b74754..0000000
--- a/src/cmd/compile/internal/gc/ssa.go
+++ /dev/null
@@ -1,7231 +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 gc
-
-import (
-	"encoding/binary"
-	"fmt"
-	"html"
-	"os"
-	"path/filepath"
-	"sort"
-
-	"bufio"
-	"bytes"
-	"cmd/compile/internal/ssa"
-	"cmd/compile/internal/types"
-	"cmd/internal/obj"
-	"cmd/internal/obj/x86"
-	"cmd/internal/objabi"
-	"cmd/internal/src"
-	"cmd/internal/sys"
-)
-
-var ssaConfig *ssa.Config
-var ssaCaches []ssa.Cache
-
-var ssaDump string     // early copy of $GOSSAFUNC; the func name to dump output for
-var ssaDir string      // optional destination for ssa dump file
-var ssaDumpStdout bool // whether to dump to stdout
-var ssaDumpCFG string  // generate CFGs for these phases
-const ssaDumpFile = "ssa.html"
-
-// The max number of defers in a function using open-coded defers. We enforce this
-// limit because the deferBits bitmask is currently a single byte (to minimize code size)
-const maxOpenDefers = 8
-
-// ssaDumpInlined holds all inlined functions when ssaDump contains a function name.
-var ssaDumpInlined []*Node
-
-func initssaconfig() {
-	types_ := ssa.NewTypes()
-
-	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{}
-	_ = types.NewPtr(types.NewPtr(types.Types[TSTRING]))              // **string
-	_ = types.NewPtr(types.NewSlice(types.Types[TINTER]))             // *[]interface{}
-	_ = types.NewPtr(types.NewPtr(types.Bytetype))                    // **byte
-	_ = types.NewPtr(types.NewSlice(types.Bytetype))                  // *[]byte
-	_ = types.NewPtr(types.NewSlice(types.Types[TSTRING]))            // *[]string
-	_ = types.NewPtr(types.NewPtr(types.NewPtr(types.Types[TUINT8]))) // ***uint8
-	_ = types.NewPtr(types.Types[TINT16])                             // *int16
-	_ = types.NewPtr(types.Types[TINT64])                             // *int64
-	_ = types.NewPtr(types.Errortype)                                 // *error
-	types.NewPtrCacheEnabled = false
-	ssaConfig = ssa.NewConfig(thearch.LinkArch.Name, *types_, Ctxt, Debug.N == 0)
-	ssaConfig.SoftFloat = thearch.SoftFloat
-	ssaConfig.Race = flag_race
-	ssaCaches = make([]ssa.Cache, nBackendWorkers)
-
-	// Set up some runtime functions we'll need to call.
-	assertE2I = sysfunc("assertE2I")
-	assertE2I2 = sysfunc("assertE2I2")
-	assertI2I = sysfunc("assertI2I")
-	assertI2I2 = sysfunc("assertI2I2")
-	deferproc = sysfunc("deferproc")
-	deferprocStack = sysfunc("deferprocStack")
-	Deferreturn = sysfunc("deferreturn")
-	Duffcopy = sysfunc("duffcopy")
-	Duffzero = sysfunc("duffzero")
-	gcWriteBarrier = sysfunc("gcWriteBarrier")
-	goschedguarded = sysfunc("goschedguarded")
-	growslice = sysfunc("growslice")
-	msanread = sysfunc("msanread")
-	msanwrite = sysfunc("msanwrite")
-	msanmove = sysfunc("msanmove")
-	newobject = sysfunc("newobject")
-	newproc = sysfunc("newproc")
-	panicdivide = sysfunc("panicdivide")
-	panicdottypeE = sysfunc("panicdottypeE")
-	panicdottypeI = sysfunc("panicdottypeI")
-	panicnildottype = sysfunc("panicnildottype")
-	panicoverflow = sysfunc("panicoverflow")
-	panicshift = sysfunc("panicshift")
-	raceread = sysfunc("raceread")
-	racereadrange = sysfunc("racereadrange")
-	racewrite = sysfunc("racewrite")
-	racewriterange = sysfunc("racewriterange")
-	x86HasPOPCNT = sysvar("x86HasPOPCNT")       // bool
-	x86HasSSE41 = sysvar("x86HasSSE41")         // bool
-	x86HasFMA = sysvar("x86HasFMA")             // bool
-	armHasVFPv4 = sysvar("armHasVFPv4")         // bool
-	arm64HasATOMICS = sysvar("arm64HasATOMICS") // bool
-	typedmemclr = sysfunc("typedmemclr")
-	typedmemmove = sysfunc("typedmemmove")
-	Udiv = sysvar("udiv")                 // asm func with special ABI
-	writeBarrier = sysvar("writeBarrier") // struct { bool; ... }
-	zerobaseSym = sysvar("zerobase")
-
-	// asm funcs with special ABI
-	if thearch.LinkArch.Name == "amd64" {
-		GCWriteBarrierReg = map[int16]*obj.LSym{
-			x86.REG_AX: sysfunc("gcWriteBarrier"),
-			x86.REG_CX: sysfunc("gcWriteBarrierCX"),
-			x86.REG_DX: sysfunc("gcWriteBarrierDX"),
-			x86.REG_BX: sysfunc("gcWriteBarrierBX"),
-			x86.REG_BP: sysfunc("gcWriteBarrierBP"),
-			x86.REG_SI: sysfunc("gcWriteBarrierSI"),
-			x86.REG_R8: sysfunc("gcWriteBarrierR8"),
-			x86.REG_R9: sysfunc("gcWriteBarrierR9"),
-		}
-	}
-
-	if thearch.LinkArch.Family == sys.Wasm {
-		BoundsCheckFunc[ssa.BoundsIndex] = sysfunc("goPanicIndex")
-		BoundsCheckFunc[ssa.BoundsIndexU] = sysfunc("goPanicIndexU")
-		BoundsCheckFunc[ssa.BoundsSliceAlen] = sysfunc("goPanicSliceAlen")
-		BoundsCheckFunc[ssa.BoundsSliceAlenU] = sysfunc("goPanicSliceAlenU")
-		BoundsCheckFunc[ssa.BoundsSliceAcap] = sysfunc("goPanicSliceAcap")
-		BoundsCheckFunc[ssa.BoundsSliceAcapU] = sysfunc("goPanicSliceAcapU")
-		BoundsCheckFunc[ssa.BoundsSliceB] = sysfunc("goPanicSliceB")
-		BoundsCheckFunc[ssa.BoundsSliceBU] = sysfunc("goPanicSliceBU")
-		BoundsCheckFunc[ssa.BoundsSlice3Alen] = sysfunc("goPanicSlice3Alen")
-		BoundsCheckFunc[ssa.BoundsSlice3AlenU] = sysfunc("goPanicSlice3AlenU")
-		BoundsCheckFunc[ssa.BoundsSlice3Acap] = sysfunc("goPanicSlice3Acap")
-		BoundsCheckFunc[ssa.BoundsSlice3AcapU] = sysfunc("goPanicSlice3AcapU")
-		BoundsCheckFunc[ssa.BoundsSlice3B] = sysfunc("goPanicSlice3B")
-		BoundsCheckFunc[ssa.BoundsSlice3BU] = sysfunc("goPanicSlice3BU")
-		BoundsCheckFunc[ssa.BoundsSlice3C] = sysfunc("goPanicSlice3C")
-		BoundsCheckFunc[ssa.BoundsSlice3CU] = sysfunc("goPanicSlice3CU")
-	} else {
-		BoundsCheckFunc[ssa.BoundsIndex] = sysfunc("panicIndex")
-		BoundsCheckFunc[ssa.BoundsIndexU] = sysfunc("panicIndexU")
-		BoundsCheckFunc[ssa.BoundsSliceAlen] = sysfunc("panicSliceAlen")
-		BoundsCheckFunc[ssa.BoundsSliceAlenU] = sysfunc("panicSliceAlenU")
-		BoundsCheckFunc[ssa.BoundsSliceAcap] = sysfunc("panicSliceAcap")
-		BoundsCheckFunc[ssa.BoundsSliceAcapU] = sysfunc("panicSliceAcapU")
-		BoundsCheckFunc[ssa.BoundsSliceB] = sysfunc("panicSliceB")
-		BoundsCheckFunc[ssa.BoundsSliceBU] = sysfunc("panicSliceBU")
-		BoundsCheckFunc[ssa.BoundsSlice3Alen] = sysfunc("panicSlice3Alen")
-		BoundsCheckFunc[ssa.BoundsSlice3AlenU] = sysfunc("panicSlice3AlenU")
-		BoundsCheckFunc[ssa.BoundsSlice3Acap] = sysfunc("panicSlice3Acap")
-		BoundsCheckFunc[ssa.BoundsSlice3AcapU] = sysfunc("panicSlice3AcapU")
-		BoundsCheckFunc[ssa.BoundsSlice3B] = sysfunc("panicSlice3B")
-		BoundsCheckFunc[ssa.BoundsSlice3BU] = sysfunc("panicSlice3BU")
-		BoundsCheckFunc[ssa.BoundsSlice3C] = sysfunc("panicSlice3C")
-		BoundsCheckFunc[ssa.BoundsSlice3CU] = sysfunc("panicSlice3CU")
-	}
-	if thearch.LinkArch.PtrSize == 4 {
-		ExtendCheckFunc[ssa.BoundsIndex] = sysvar("panicExtendIndex")
-		ExtendCheckFunc[ssa.BoundsIndexU] = sysvar("panicExtendIndexU")
-		ExtendCheckFunc[ssa.BoundsSliceAlen] = sysvar("panicExtendSliceAlen")
-		ExtendCheckFunc[ssa.BoundsSliceAlenU] = sysvar("panicExtendSliceAlenU")
-		ExtendCheckFunc[ssa.BoundsSliceAcap] = sysvar("panicExtendSliceAcap")
-		ExtendCheckFunc[ssa.BoundsSliceAcapU] = sysvar("panicExtendSliceAcapU")
-		ExtendCheckFunc[ssa.BoundsSliceB] = sysvar("panicExtendSliceB")
-		ExtendCheckFunc[ssa.BoundsSliceBU] = sysvar("panicExtendSliceBU")
-		ExtendCheckFunc[ssa.BoundsSlice3Alen] = sysvar("panicExtendSlice3Alen")
-		ExtendCheckFunc[ssa.BoundsSlice3AlenU] = sysvar("panicExtendSlice3AlenU")
-		ExtendCheckFunc[ssa.BoundsSlice3Acap] = sysvar("panicExtendSlice3Acap")
-		ExtendCheckFunc[ssa.BoundsSlice3AcapU] = sysvar("panicExtendSlice3AcapU")
-		ExtendCheckFunc[ssa.BoundsSlice3B] = sysvar("panicExtendSlice3B")
-		ExtendCheckFunc[ssa.BoundsSlice3BU] = sysvar("panicExtendSlice3BU")
-		ExtendCheckFunc[ssa.BoundsSlice3C] = sysvar("panicExtendSlice3C")
-		ExtendCheckFunc[ssa.BoundsSlice3CU] = sysvar("panicExtendSlice3CU")
-	}
-
-	// Wasm (all asm funcs with special ABIs)
-	WasmMove = sysvar("wasmMove")
-	WasmZero = sysvar("wasmZero")
-	WasmDiv = sysvar("wasmDiv")
-	WasmTruncS = sysvar("wasmTruncS")
-	WasmTruncU = sysvar("wasmTruncU")
-	SigPanic = sysfunc("sigpanic")
-}
-
-// getParam returns the Field of ith param of node n (which is a
-// function/method/interface call), where the receiver of a method call is
-// considered as the 0th parameter. This does not include the receiver of an
-// interface call.
-func getParam(n *Node, i int) *types.Field {
-	t := n.Left.Type
-	if n.Op == OCALLMETH {
-		if i == 0 {
-			return t.Recv()
-		}
-		return t.Params().Field(i - 1)
-	}
-	return t.Params().Field(i)
-}
-
-// dvarint writes a varint v to the funcdata in symbol x and returns the new offset
-func dvarint(x *obj.LSym, off int, v int64) int {
-	if v < 0 || v > 1e9 {
-		panic(fmt.Sprintf("dvarint: bad offset for funcdata - %v", v))
-	}
-	if v < 1<<7 {
-		return duint8(x, off, uint8(v))
-	}
-	off = duint8(x, off, uint8((v&127)|128))
-	if v < 1<<14 {
-		return duint8(x, off, uint8(v>>7))
-	}
-	off = duint8(x, off, uint8(((v>>7)&127)|128))
-	if v < 1<<21 {
-		return duint8(x, off, uint8(v>>14))
-	}
-	off = duint8(x, off, uint8(((v>>14)&127)|128))
-	if v < 1<<28 {
-		return duint8(x, off, uint8(v>>21))
-	}
-	off = duint8(x, off, uint8(((v>>21)&127)|128))
-	return duint8(x, off, uint8(v>>28))
-}
-
-// emitOpenDeferInfo emits FUNCDATA information about the defers in a function
-// that is using open-coded defers.  This funcdata is used to determine the active
-// defers in a function and execute those defers during panic processing.
-//
-// The funcdata is all encoded in varints (since values will almost always be less than
-// 128, but stack offsets could potentially be up to 2Gbyte). All "locations" (offsets)
-// for stack variables are specified as the number of bytes below varp (pointer to the
-// top of the local variables) for their starting address. The format is:
-//
-//  - Max total argument size among all the defers
-//  - Offset of the deferBits variable
-//  - Number of defers in the function
-//  - Information about each defer call, in reverse order of appearance in the function:
-//    - Total argument size of the call
-//    - Offset of the closure value to call
-//    - Number of arguments (including interface receiver or method receiver as first arg)
-//    - Information about each argument
-//      - Offset of the stored defer argument in this function's frame
-//      - Size of the argument
-//      - Offset of where argument should be placed in the args frame when making call
-func (s *state) emitOpenDeferInfo() {
-	x := Ctxt.Lookup(s.curfn.Func.lsym.Name + ".opendefer")
-	s.curfn.Func.lsym.Func().OpenCodedDeferInfo = x
-	off := 0
-
-	// Compute maxargsize (max size of arguments for all defers)
-	// first, so we can output it first to the funcdata
-	var maxargsize int64
-	for i := len(s.openDefers) - 1; i >= 0; i-- {
-		r := s.openDefers[i]
-		argsize := r.n.Left.Type.ArgWidth()
-		if argsize > maxargsize {
-			maxargsize = argsize
-		}
-	}
-	off = dvarint(x, off, maxargsize)
-	off = dvarint(x, off, -s.deferBitsTemp.Xoffset)
-	off = dvarint(x, off, int64(len(s.openDefers)))
-
-	// Write in reverse-order, for ease of running in that order at runtime
-	for i := len(s.openDefers) - 1; i >= 0; i-- {
-		r := s.openDefers[i]
-		off = dvarint(x, off, r.n.Left.Type.ArgWidth())
-		off = dvarint(x, off, -r.closureNode.Xoffset)
-		numArgs := len(r.argNodes)
-		if r.rcvrNode != nil {
-			// If there's an interface receiver, treat/place it as the first
-			// arg. (If there is a method receiver, it's already included as
-			// first arg in r.argNodes.)
-			numArgs++
-		}
-		off = dvarint(x, off, int64(numArgs))
-		if r.rcvrNode != nil {
-			off = dvarint(x, off, -r.rcvrNode.Xoffset)
-			off = dvarint(x, off, s.config.PtrSize)
-			off = dvarint(x, off, 0)
-		}
-		for j, arg := range r.argNodes {
-			f := getParam(r.n, j)
-			off = dvarint(x, off, -arg.Xoffset)
-			off = dvarint(x, off, f.Type.Size())
-			off = dvarint(x, off, f.Offset)
-		}
-	}
-}
-
-// buildssa builds an SSA function for fn.
-// worker indicates which of the backend workers is doing the processing.
-func buildssa(fn *Node, worker int) *ssa.Func {
-	name := fn.funcname()
-	printssa := false
-	if ssaDump != "" { // match either a simple name e.g. "(*Reader).Reset", or a package.name e.g. "compress/gzip.(*Reader).Reset"
-		printssa = name == ssaDump || myimportpath+"."+name == ssaDump
-	}
-	var astBuf *bytes.Buffer
-	if printssa {
-		astBuf = &bytes.Buffer{}
-		fdumplist(astBuf, "buildssa-enter", fn.Func.Enter)
-		fdumplist(astBuf, "buildssa-body", fn.Nbody)
-		fdumplist(astBuf, "buildssa-exit", fn.Func.Exit)
-		if ssaDumpStdout {
-			fmt.Println("generating SSA for", name)
-			fmt.Print(astBuf.String())
-		}
-	}
-
-	var s state
-	s.pushLine(fn.Pos)
-	defer s.popLine()
-
-	s.hasdefer = fn.Func.HasDefer()
-	if fn.Func.Pragma&CgoUnsafeArgs != 0 {
-		s.cgoUnsafeArgs = true
-	}
-
-	fe := ssafn{
-		curfn: fn,
-		log:   printssa && ssaDumpStdout,
-	}
-	s.curfn = fn
-
-	s.f = ssa.NewFunc(&fe)
-	s.config = ssaConfig
-	s.f.Type = fn.Type
-	s.f.Config = ssaConfig
-	s.f.Cache = &ssaCaches[worker]
-	s.f.Cache.Reset()
-	s.f.Name = name
-	s.f.DebugTest = s.f.DebugHashMatch("GOSSAHASH")
-	s.f.PrintOrHtmlSSA = printssa
-	if fn.Func.Pragma&Nosplit != 0 {
-		s.f.NoSplit = true
-	}
-	s.panics = map[funcLine]*ssa.Block{}
-	s.softFloat = s.config.SoftFloat
-
-	// Allocate starting block
-	s.f.Entry = s.f.NewBlock(ssa.BlockPlain)
-	s.f.Entry.Pos = fn.Pos
-
-	if printssa {
-		ssaDF := ssaDumpFile
-		if ssaDir != "" {
-			ssaDF = filepath.Join(ssaDir, myimportpath+"."+name+".html")
-			ssaD := filepath.Dir(ssaDF)
-			os.MkdirAll(ssaD, 0755)
-		}
-		s.f.HTMLWriter = ssa.NewHTMLWriter(ssaDF, s.f, ssaDumpCFG)
-		// TODO: generate and print a mapping from nodes to values and blocks
-		dumpSourcesColumn(s.f.HTMLWriter, fn)
-		s.f.HTMLWriter.WriteAST("AST", astBuf)
-	}
-
-	// Allocate starting values
-	s.labels = map[string]*ssaLabel{}
-	s.labeledNodes = map[*Node]*ssaLabel{}
-	s.fwdVars = map[*Node]*ssa.Value{}
-	s.startmem = s.entryNewValue0(ssa.OpInitMem, types.TypeMem)
-
-	s.hasOpenDefers = Debug.N == 0 && s.hasdefer && !s.curfn.Func.OpenCodedDeferDisallowed()
-	switch {
-	case s.hasOpenDefers && (Ctxt.Flag_shared || Ctxt.Flag_dynlink) && thearch.LinkArch.Name == "386":
-		// Don't support open-coded defers for 386 ONLY when using shared
-		// libraries, because there is extra code (added by rewriteToUseGot())
-		// preceding the deferreturn/ret code that is generated by gencallret()
-		// that we don't track correctly.
-		s.hasOpenDefers = false
-	}
-	if s.hasOpenDefers && s.curfn.Func.Exit.Len() > 0 {
-		// Skip doing open defers if there is any extra exit code (likely
-		// copying heap-allocated return values or race detection), since
-		// we will not generate that code in the case of the extra
-		// deferreturn/ret segment.
-		s.hasOpenDefers = false
-	}
-	if s.hasOpenDefers &&
-		s.curfn.Func.numReturns*s.curfn.Func.numDefers > 15 {
-		// Since we are generating defer calls at every exit for
-		// open-coded defers, skip doing open-coded defers if there are
-		// too many returns (especially if there are multiple defers).
-		// Open-coded defers are most important for improving performance
-		// for smaller functions (which don't have many returns).
-		s.hasOpenDefers = false
-	}
-
-	s.sp = s.entryNewValue0(ssa.OpSP, types.Types[TUINTPTR]) // TODO: use generic pointer type (unsafe.Pointer?) instead
-	s.sb = s.entryNewValue0(ssa.OpSB, types.Types[TUINTPTR])
-
-	s.startBlock(s.f.Entry)
-	s.vars[&memVar] = s.startmem
-	if s.hasOpenDefers {
-		// Create the deferBits variable and stack slot.  deferBits is a
-		// bitmask showing which of the open-coded defers in this function
-		// have been activated.
-		deferBitsTemp := tempAt(src.NoXPos, s.curfn, types.Types[TUINT8])
-		s.deferBitsTemp = deferBitsTemp
-		// For this value, AuxInt is initialized to zero by default
-		startDeferBits := s.entryNewValue0(ssa.OpConst8, types.Types[TUINT8])
-		s.vars[&deferBitsVar] = startDeferBits
-		s.deferBitsAddr = s.addr(deferBitsTemp)
-		s.store(types.Types[TUINT8], s.deferBitsAddr, startDeferBits)
-		// Make sure that the deferBits stack slot is kept alive (for use
-		// by panics) and stores to deferBits are not eliminated, even if
-		// all checking code on deferBits in the function exit can be
-		// eliminated, because the defer statements were all
-		// unconditional.
-		s.vars[&memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, deferBitsTemp, s.mem(), false)
-	}
-
-	// Generate addresses of local declarations
-	s.decladdrs = map[*Node]*ssa.Value{}
-	var args []ssa.Param
-	var results []ssa.Param
-	for _, n := range fn.Func.Dcl {
-		switch n.Class() {
-		case PPARAM:
-			s.decladdrs[n] = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(n.Type), n, s.sp, s.startmem)
-			args = append(args, ssa.Param{Type: n.Type, Offset: int32(n.Xoffset)})
-		case PPARAMOUT:
-			s.decladdrs[n] = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(n.Type), n, s.sp, s.startmem)
-			results = append(results, ssa.Param{Type: n.Type, Offset: int32(n.Xoffset)})
-			if s.canSSA(n) {
-				// Save ssa-able PPARAMOUT variables so we can
-				// store them back to the stack at the end of
-				// the function.
-				s.returns = append(s.returns, n)
-			}
-		case PAUTO:
-			// processed at each use, to prevent Addr coming
-			// before the decl.
-		case PAUTOHEAP:
-			// moved to heap - already handled by frontend
-		case PFUNC:
-			// local function - already handled by frontend
-		default:
-			s.Fatalf("local variable with class %v unimplemented", n.Class())
-		}
-	}
-
-	// Populate SSAable arguments.
-	for _, n := range fn.Func.Dcl {
-		if n.Class() == PPARAM && s.canSSA(n) {
-			v := s.newValue0A(ssa.OpArg, n.Type, n)
-			s.vars[n] = v
-			s.addNamedValue(n, v) // This helps with debugging information, not needed for compilation itself.
-		}
-	}
-
-	// Convert the AST-based IR to the SSA-based IR
-	s.stmtList(fn.Func.Enter)
-	s.stmtList(fn.Nbody)
-
-	// fallthrough to exit
-	if s.curBlock != nil {
-		s.pushLine(fn.Func.Endlineno)
-		s.exit()
-		s.popLine()
-	}
-
-	for _, b := range s.f.Blocks {
-		if b.Pos != src.NoXPos {
-			s.updateUnsetPredPos(b)
-		}
-	}
-
-	s.insertPhis()
-
-	// Main call to ssa package to compile function
-	ssa.Compile(s.f)
-
-	if s.hasOpenDefers {
-		s.emitOpenDeferInfo()
-	}
-
-	return s.f
-}
-
-func dumpSourcesColumn(writer *ssa.HTMLWriter, fn *Node) {
-	// Read sources of target function fn.
-	fname := Ctxt.PosTable.Pos(fn.Pos).Filename()
-	targetFn, err := readFuncLines(fname, fn.Pos.Line(), fn.Func.Endlineno.Line())
-	if err != nil {
-		writer.Logf("cannot read sources for function %v: %v", fn, err)
-	}
-
-	// Read sources of inlined functions.
-	var inlFns []*ssa.FuncLines
-	for _, fi := range ssaDumpInlined {
-		var elno src.XPos
-		if fi.Name.Defn == nil {
-			// Endlineno is filled from exported data.
-			elno = fi.Func.Endlineno
-		} else {
-			elno = fi.Name.Defn.Func.Endlineno
-		}
-		fname := Ctxt.PosTable.Pos(fi.Pos).Filename()
-		fnLines, err := readFuncLines(fname, fi.Pos.Line(), elno.Line())
-		if err != nil {
-			writer.Logf("cannot read sources for inlined function %v: %v", fi, err)
-			continue
-		}
-		inlFns = append(inlFns, fnLines)
-	}
-
-	sort.Sort(ssa.ByTopo(inlFns))
-	if targetFn != nil {
-		inlFns = append([]*ssa.FuncLines{targetFn}, inlFns...)
-	}
-
-	writer.WriteSources("sources", inlFns)
-}
-
-func readFuncLines(file string, start, end uint) (*ssa.FuncLines, error) {
-	f, err := os.Open(os.ExpandEnv(file))
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-	var lines []string
-	ln := uint(1)
-	scanner := bufio.NewScanner(f)
-	for scanner.Scan() && ln <= end {
-		if ln >= start {
-			lines = append(lines, scanner.Text())
-		}
-		ln++
-	}
-	return &ssa.FuncLines{Filename: file, StartLineno: start, Lines: lines}, nil
-}
-
-// 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.
-	}
-}
-
-// Information about each open-coded defer.
-type openDeferInfo struct {
-	// The ODEFER node representing the function call of the defer
-	n *Node
-	// If defer call is closure call, the address of the argtmp where the
-	// closure is stored.
-	closure *ssa.Value
-	// The node representing the argtmp where the closure is stored - used for
-	// function, method, or interface call, to store a closure that panic
-	// processing can use for this defer.
-	closureNode *Node
-	// If defer call is interface call, the address of the argtmp where the
-	// receiver is stored
-	rcvr *ssa.Value
-	// The node representing the argtmp where the receiver is stored
-	rcvrNode *Node
-	// The addresses of the argtmps where the evaluated arguments of the defer
-	// function call are stored.
-	argVals []*ssa.Value
-	// The nodes representing the argtmps where the args of the defer are stored
-	argNodes []*Node
-}
-
-type state struct {
-	// configuration (arch) information
-	config *ssa.Config
-
-	// function we're building
-	f *ssa.Func
-
-	// Node for function
-	curfn *Node
-
-	// labels and labeled control flow nodes (OFOR, OFORUNTIL, OSWITCH, OSELECT) in f
-	labels       map[string]*ssaLabel
-	labeledNodes map[*Node]*ssaLabel
-
-	// unlabeled break and continue statement tracking
-	breakTo    *ssa.Block // current target for plain break statement
-	continueTo *ssa.Block // current target for plain continue statement
-
-	// current location where we're interpreting the AST
-	curBlock *ssa.Block
-
-	// variable assignments in the current block (map from variable symbol to ssa value)
-	// *Node is the unique identifier (an ONAME Node) for the variable.
-	// TODO: keep a single varnum map, then make all of these maps slices instead?
-	vars map[*Node]*ssa.Value
-
-	// fwdVars are variables that are used before they are defined in the current block.
-	// This map exists just to coalesce multiple references into a single FwdRef op.
-	// *Node is the unique identifier (an ONAME Node) for the variable.
-	fwdVars map[*Node]*ssa.Value
-
-	// all defined variables at the end of each block. Indexed by block ID.
-	defvars []map[*Node]*ssa.Value
-
-	// addresses of PPARAM and PPARAMOUT variables.
-	decladdrs map[*Node]*ssa.Value
-
-	// starting values. Memory, stack pointer, and globals pointer
-	startmem *ssa.Value
-	sp       *ssa.Value
-	sb       *ssa.Value
-	// value representing address of where deferBits autotmp is stored
-	deferBitsAddr *ssa.Value
-	deferBitsTemp *Node
-
-	// 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.
-	panics map[funcLine]*ssa.Block
-
-	// list of PPARAMOUT (return) variables.
-	returns []*Node
-
-	cgoUnsafeArgs bool
-	hasdefer      bool // whether the function contains a defer statement
-	softFloat     bool
-	hasOpenDefers bool // whether we are doing open-coded defers
-
-	// If doing open-coded defers, list of info about the defer calls in
-	// scanning order. Hence, at exit we should run these defers in reverse
-	// order of this list
-	openDefers []*openDeferInfo
-	// For open-coded defers, this is the beginning and end blocks of the last
-	// defer exit code that we have generated so far. We use these to share
-	// code between exits if the shareDeferExits option (disabled by default)
-	// is on.
-	lastDeferExit       *ssa.Block // Entry block of last defer exit code we generated
-	lastDeferFinalBlock *ssa.Block // Final block of last defer exit code we generated
-	lastDeferCount      int        // Number of defers encountered at that point
-
-	prevCall *ssa.Value // the previous call; use this to tie results to the call op.
-}
-
-type funcLine struct {
-	f    *obj.LSym
-	base *src.PosBase
-	line uint
-}
-
-type ssaLabel struct {
-	target         *ssa.Block // block identified by this label
-	breakTarget    *ssa.Block // block to break to in control flow node identified by this label
-	continueTarget *ssa.Block // block to continue to in control flow node identified by this label
-}
-
-// label returns the label associated with sym, creating it if necessary.
-func (s *state) label(sym *types.Sym) *ssaLabel {
-	lab := s.labels[sym.Name]
-	if lab == nil {
-		lab = new(ssaLabel)
-		s.labels[sym.Name] = lab
-	}
-	return lab
-}
-
-func (s *state) Logf(msg string, args ...interface{}) { s.f.Logf(msg, args...) }
-func (s *state) Log() bool                            { return s.f.Log() }
-func (s *state) Fatalf(msg string, args ...interface{}) {
-	s.f.Frontend().Fatalf(s.peekPos(), msg, args...)
-}
-func (s *state) Warnl(pos src.XPos, msg string, args ...interface{}) { s.f.Warnl(pos, msg, args...) }
-func (s *state) Debug_checknil() bool                                { return s.f.Frontend().Debug_checknil() }
-
-var (
-	// dummy node for the memory variable
-	memVar = Node{Op: ONAME, Sym: &types.Sym{Name: "mem"}}
-
-	// dummy nodes for temporary variables
-	ptrVar       = Node{Op: ONAME, Sym: &types.Sym{Name: "ptr"}}
-	lenVar       = Node{Op: ONAME, Sym: &types.Sym{Name: "len"}}
-	newlenVar    = Node{Op: ONAME, Sym: &types.Sym{Name: "newlen"}}
-	capVar       = Node{Op: ONAME, Sym: &types.Sym{Name: "cap"}}
-	typVar       = Node{Op: ONAME, Sym: &types.Sym{Name: "typ"}}
-	okVar        = Node{Op: ONAME, Sym: &types.Sym{Name: "ok"}}
-	deferBitsVar = Node{Op: ONAME, Sym: &types.Sym{Name: "deferBits"}}
-)
-
-// startBlock sets the current block we're generating code in to b.
-func (s *state) startBlock(b *ssa.Block) {
-	if s.curBlock != nil {
-		s.Fatalf("starting block %v when block %v has not ended", b, s.curBlock)
-	}
-	s.curBlock = b
-	s.vars = map[*Node]*ssa.Value{}
-	for n := range s.fwdVars {
-		delete(s.fwdVars, n)
-	}
-}
-
-// endBlock marks the end of generating code for the current block.
-// Returns the (former) current block. Returns nil if there is no current
-// block, i.e. if no code flows to the current execution point.
-func (s *state) endBlock() *ssa.Block {
-	b := s.curBlock
-	if b == nil {
-		return nil
-	}
-	for len(s.defvars) <= int(b.ID) {
-		s.defvars = append(s.defvars, nil)
-	}
-	s.defvars[b.ID] = s.vars
-	s.curBlock = nil
-	s.vars = nil
-	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
-}
-
-// pushLine pushes a line number on the line number stack.
-func (s *state) pushLine(line src.XPos) {
-	if !line.IsKnown() {
-		// the frontend may emit node with line number missing,
-		// use the parent line number in this case.
-		line = s.peekPos()
-		if Debug.K != 0 {
-			Warn("buildssa: unknown position (line 0)")
-		}
-	} else {
-		s.lastPos = line
-	}
-
-	s.line = append(s.line, line)
-}
-
-// popLine pops the top of the line number stack.
-func (s *state) popLine() {
-	s.line = s.line[:len(s.line)-1]
-}
-
-// peekPos peeks the top of the line number stack.
-func (s *state) peekPos() src.XPos {
-	return s.line[len(s.line)-1]
-}
-
-// newValue0 adds a new value with no arguments to the current block.
-func (s *state) newValue0(op ssa.Op, t *types.Type) *ssa.Value {
-	return s.curBlock.NewValue0(s.peekPos(), op, t)
-}
-
-// newValue0A adds a new value with no arguments and an aux value to the current block.
-func (s *state) newValue0A(op ssa.Op, t *types.Type, aux interface{}) *ssa.Value {
-	return s.curBlock.NewValue0A(s.peekPos(), op, t, aux)
-}
-
-// newValue0I adds a new value with no arguments and an auxint value to the current block.
-func (s *state) newValue0I(op ssa.Op, t *types.Type, auxint int64) *ssa.Value {
-	return s.curBlock.NewValue0I(s.peekPos(), op, t, auxint)
-}
-
-// newValue1 adds a new value with one argument to the current block.
-func (s *state) newValue1(op ssa.Op, t *types.Type, arg *ssa.Value) *ssa.Value {
-	return s.curBlock.NewValue1(s.peekPos(), op, t, arg)
-}
-
-// newValue1A adds a new value with one argument and an aux value to the current block.
-func (s *state) newValue1A(op ssa.Op, t *types.Type, aux interface{}, arg *ssa.Value) *ssa.Value {
-	return s.curBlock.NewValue1A(s.peekPos(), op, t, aux, arg)
-}
-
-// newValue1Apos adds a new value with one argument and an aux value to the current block.
-// isStmt determines whether the created values may be a statement or not
-// (i.e., false means never, yes means maybe).
-func (s *state) newValue1Apos(op ssa.Op, t *types.Type, aux interface{}, arg *ssa.Value, isStmt bool) *ssa.Value {
-	if isStmt {
-		return s.curBlock.NewValue1A(s.peekPos(), op, t, aux, arg)
-	}
-	return s.curBlock.NewValue1A(s.peekPos().WithNotStmt(), op, t, aux, arg)
-}
-
-// newValue1I adds a new value with one argument and an auxint value to the current block.
-func (s *state) newValue1I(op ssa.Op, t *types.Type, aux int64, arg *ssa.Value) *ssa.Value {
-	return s.curBlock.NewValue1I(s.peekPos(), op, t, aux, arg)
-}
-
-// newValue2 adds a new value with two arguments to the current block.
-func (s *state) newValue2(op ssa.Op, t *types.Type, arg0, arg1 *ssa.Value) *ssa.Value {
-	return s.curBlock.NewValue2(s.peekPos(), op, t, arg0, arg1)
-}
-
-// newValue2A adds a new value with two arguments and an aux value to the current block.
-func (s *state) newValue2A(op ssa.Op, t *types.Type, aux interface{}, arg0, arg1 *ssa.Value) *ssa.Value {
-	return s.curBlock.NewValue2A(s.peekPos(), op, t, aux, arg0, arg1)
-}
-
-// newValue2Apos adds a new value with two arguments and an aux value to the current block.
-// isStmt determines whether the created values may be a statement or not
-// (i.e., false means never, yes means maybe).
-func (s *state) newValue2Apos(op ssa.Op, t *types.Type, aux interface{}, arg0, arg1 *ssa.Value, isStmt bool) *ssa.Value {
-	if isStmt {
-		return s.curBlock.NewValue2A(s.peekPos(), op, t, aux, arg0, arg1)
-	}
-	return s.curBlock.NewValue2A(s.peekPos().WithNotStmt(), op, t, aux, arg0, arg1)
-}
-
-// newValue2I adds a new value with two arguments and an auxint value to the current block.
-func (s *state) newValue2I(op ssa.Op, t *types.Type, aux int64, arg0, arg1 *ssa.Value) *ssa.Value {
-	return s.curBlock.NewValue2I(s.peekPos(), op, t, aux, arg0, arg1)
-}
-
-// newValue3 adds a new value with three arguments to the current block.
-func (s *state) newValue3(op ssa.Op, t *types.Type, arg0, arg1, arg2 *ssa.Value) *ssa.Value {
-	return s.curBlock.NewValue3(s.peekPos(), op, t, arg0, arg1, arg2)
-}
-
-// newValue3I adds a new value with three arguments and an auxint value to the current block.
-func (s *state) newValue3I(op ssa.Op, t *types.Type, aux int64, arg0, arg1, arg2 *ssa.Value) *ssa.Value {
-	return s.curBlock.NewValue3I(s.peekPos(), op, t, aux, arg0, arg1, arg2)
-}
-
-// newValue3A adds a new value with three arguments and an aux value to the current block.
-func (s *state) newValue3A(op ssa.Op, t *types.Type, aux interface{}, arg0, arg1, arg2 *ssa.Value) *ssa.Value {
-	return s.curBlock.NewValue3A(s.peekPos(), op, t, aux, arg0, arg1, arg2)
-}
-
-// newValue3Apos adds a new value with three arguments and an aux value to the current block.
-// isStmt determines whether the created values may be a statement or not
-// (i.e., false means never, yes means maybe).
-func (s *state) newValue3Apos(op ssa.Op, t *types.Type, aux interface{}, arg0, arg1, arg2 *ssa.Value, isStmt bool) *ssa.Value {
-	if isStmt {
-		return s.curBlock.NewValue3A(s.peekPos(), op, t, aux, arg0, arg1, arg2)
-	}
-	return s.curBlock.NewValue3A(s.peekPos().WithNotStmt(), op, t, aux, arg0, arg1, arg2)
-}
-
-// newValue4 adds a new value with four arguments to the current block.
-func (s *state) newValue4(op ssa.Op, t *types.Type, arg0, arg1, arg2, arg3 *ssa.Value) *ssa.Value {
-	return s.curBlock.NewValue4(s.peekPos(), op, t, arg0, arg1, arg2, arg3)
-}
-
-// newValue4 adds a new value with four arguments and an auxint value to the current block.
-func (s *state) newValue4I(op ssa.Op, t *types.Type, aux int64, arg0, arg1, arg2, arg3 *ssa.Value) *ssa.Value {
-	return s.curBlock.NewValue4I(s.peekPos(), op, t, aux, arg0, arg1, arg2, arg3)
-}
-
-// entryNewValue0 adds a new value with no arguments to the entry block.
-func (s *state) entryNewValue0(op ssa.Op, t *types.Type) *ssa.Value {
-	return s.f.Entry.NewValue0(src.NoXPos, op, t)
-}
-
-// 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(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(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(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(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(src.NoXPos, op, t, arg0, arg1)
-}
-
-// entryNewValue2A adds a new value with two arguments and an aux value to the entry block.
-func (s *state) entryNewValue2A(op ssa.Op, t *types.Type, aux interface{}, arg0, arg1 *ssa.Value) *ssa.Value {
-	return s.f.Entry.NewValue2A(src.NoXPos, op, t, aux, arg0, arg1)
-}
-
-// const* routines add a new const value to the entry block.
-func (s *state) constSlice(t *types.Type) *ssa.Value {
-	return s.f.ConstSlice(t)
-}
-func (s *state) constInterface(t *types.Type) *ssa.Value {
-	return s.f.ConstInterface(t)
-}
-func (s *state) constNil(t *types.Type) *ssa.Value { return s.f.ConstNil(t) }
-func (s *state) constEmptyString(t *types.Type) *ssa.Value {
-	return s.f.ConstEmptyString(t)
-}
-func (s *state) constBool(c bool) *ssa.Value {
-	return s.f.ConstBool(types.Types[TBOOL], c)
-}
-func (s *state) constInt8(t *types.Type, c int8) *ssa.Value {
-	return s.f.ConstInt8(t, c)
-}
-func (s *state) constInt16(t *types.Type, c int16) *ssa.Value {
-	return s.f.ConstInt16(t, c)
-}
-func (s *state) constInt32(t *types.Type, c int32) *ssa.Value {
-	return s.f.ConstInt32(t, c)
-}
-func (s *state) constInt64(t *types.Type, c int64) *ssa.Value {
-	return s.f.ConstInt64(t, c)
-}
-func (s *state) constFloat32(t *types.Type, c float64) *ssa.Value {
-	return s.f.ConstFloat32(t, c)
-}
-func (s *state) constFloat64(t *types.Type, c float64) *ssa.Value {
-	return s.f.ConstFloat64(t, c)
-}
-func (s *state) constInt(t *types.Type, c int64) *ssa.Value {
-	if s.config.PtrSize == 8 {
-		return s.constInt64(t, c)
-	}
-	if int64(int32(c)) != c {
-		s.Fatalf("integer constant too big %d", c)
-	}
-	return s.constInt32(t, int32(c))
-}
-func (s *state) constOffPtrSP(t *types.Type, c int64) *ssa.Value {
-	return s.f.ConstOffPtrSP(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)
-}
-
-type instrumentKind uint8
-
-const (
-	instrumentRead = iota
-	instrumentWrite
-	instrumentMove
-)
-
-func (s *state) instrument(t *types.Type, addr *ssa.Value, kind instrumentKind) {
-	s.instrument2(t, addr, nil, kind)
-}
-
-// instrumentFields instruments a read/write operation on addr.
-// If it is instrumenting for MSAN and t is a struct type, it instruments
-// operation for each field, instead of for the whole struct.
-func (s *state) instrumentFields(t *types.Type, addr *ssa.Value, kind instrumentKind) {
-	if !flag_msan || !t.IsStruct() {
-		s.instrument(t, addr, kind)
-		return
-	}
-	for _, f := range t.Fields().Slice() {
-		if f.Sym.IsBlank() {
-			continue
-		}
-		offptr := s.newValue1I(ssa.OpOffPtr, types.NewPtr(f.Type), f.Offset, addr)
-		s.instrumentFields(f.Type, offptr, kind)
-	}
-}
-
-func (s *state) instrumentMove(t *types.Type, dst, src *ssa.Value) {
-	if flag_msan {
-		s.instrument2(t, dst, src, instrumentMove)
-	} else {
-		s.instrument(t, src, instrumentRead)
-		s.instrument(t, dst, instrumentWrite)
-	}
-}
-
-func (s *state) instrument2(t *types.Type, addr, addr2 *ssa.Value, kind instrumentKind) {
-	if !s.curfn.Func.InstrumentBody() {
-		return
-	}
-
-	w := t.Size()
-	if w == 0 {
-		return // can't race on zero-sized things
-	}
-
-	if ssa.IsSanitizerSafeAddr(addr) {
-		return
-	}
-
-	var fn *obj.LSym
-	needWidth := false
-
-	if addr2 != nil && kind != instrumentMove {
-		panic("instrument2: non-nil addr2 for non-move instrumentation")
-	}
-
-	if flag_msan {
-		switch kind {
-		case instrumentRead:
-			fn = msanread
-		case instrumentWrite:
-			fn = msanwrite
-		case instrumentMove:
-			fn = msanmove
-		default:
-			panic("unreachable")
-		}
-		needWidth = true
-	} else if flag_race && t.NumComponents(types.CountBlankFields) > 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.
-		switch kind {
-		case instrumentRead:
-			fn = racereadrange
-		case instrumentWrite:
-			fn = racewriterange
-		default:
-			panic("unreachable")
-		}
-		needWidth = true
-	} else if flag_race {
-		// for non-composite objects we can write just the start
-		// address, as any write must write the first byte.
-		switch kind {
-		case instrumentRead:
-			fn = raceread
-		case instrumentWrite:
-			fn = racewrite
-		default:
-			panic("unreachable")
-		}
-	} else {
-		panic("unreachable")
-	}
-
-	args := []*ssa.Value{addr}
-	if addr2 != nil {
-		args = append(args, addr2)
-	}
-	if needWidth {
-		args = append(args, s.constInt(types.Types[TUINTPTR], w))
-	}
-	s.rtcall(fn, true, nil, args...)
-}
-
-func (s *state) load(t *types.Type, src *ssa.Value) *ssa.Value {
-	s.instrumentFields(t, src, instrumentRead)
-	return s.rawLoad(t, src)
-}
-
-func (s *state) rawLoad(t *types.Type, src *ssa.Value) *ssa.Value {
-	return s.newValue2(ssa.OpLoad, t, src, s.mem())
-}
-
-func (s *state) store(t *types.Type, dst, val *ssa.Value) {
-	s.vars[&memVar] = s.newValue3A(ssa.OpStore, types.TypeMem, t, dst, val, s.mem())
-}
-
-func (s *state) zero(t *types.Type, dst *ssa.Value) {
-	s.instrument(t, dst, instrumentWrite)
-	store := s.newValue2I(ssa.OpZero, types.TypeMem, t.Size(), dst, s.mem())
-	store.Aux = t
-	s.vars[&memVar] = store
-}
-
-func (s *state) move(t *types.Type, dst, src *ssa.Value) {
-	s.instrumentMove(t, dst, src)
-	store := s.newValue3I(ssa.OpMove, types.TypeMem, t.Size(), dst, src, s.mem())
-	store.Aux = t
-	s.vars[&memVar] = store
-}
-
-// stmtList converts the statement list n to SSA and adds it to s.
-func (s *state) stmtList(l Nodes) {
-	for _, n := range l.Slice() {
-		s.stmt(n)
-	}
-}
-
-// stmt converts the statement n to SSA and adds it to s.
-func (s *state) stmt(n *Node) {
-	if !(n.Op == OVARKILL || n.Op == OVARLIVE || n.Op == OVARDEF) {
-		// OVARKILL, OVARLIVE, and OVARDEF are invisible to the programmer, so we don't use their line numbers to avoid confusion in debugging.
-		s.pushLine(n.Pos)
-		defer s.popLine()
-	}
-
-	// 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.
-	if s.curBlock == nil && n.Op != OLABEL {
-		return
-	}
-
-	s.stmtList(n.Ninit)
-	switch n.Op {
-
-	case OBLOCK:
-		s.stmtList(n.List)
-
-	// No-ops
-	case OEMPTY, ODCLCONST, ODCLTYPE, OFALL:
-
-	// Expression statements
-	case OCALLFUNC:
-		if isIntrinsicCall(n) {
-			s.intrinsicCall(n)
-			return
-		}
-		fallthrough
-
-	case OCALLMETH, OCALLINTER:
-		s.callResult(n, callNormal)
-		if n.Op == OCALLFUNC && n.Left.Op == ONAME && n.Left.Class() == PFUNC {
-			if fn := n.Left.Sym.Name; compiling_runtime && fn == "throw" ||
-				n.Left.Sym.Pkg == Runtimepkg && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap") {
-				m := s.mem()
-				b := s.endBlock()
-				b.Kind = ssa.BlockExit
-				b.SetControl(m)
-				// TODO: never rewrite OPANIC to OCALLFUNC in the
-				// first place. Need to wait until all backends
-				// go through SSA.
-			}
-		}
-	case ODEFER:
-		if Debug_defer > 0 {
-			var defertype string
-			if s.hasOpenDefers {
-				defertype = "open-coded"
-			} else if n.Esc == EscNever {
-				defertype = "stack-allocated"
-			} else {
-				defertype = "heap-allocated"
-			}
-			Warnl(n.Pos, "%s defer", defertype)
-		}
-		if s.hasOpenDefers {
-			s.openDeferRecord(n.Left)
-		} else {
-			d := callDefer
-			if n.Esc == EscNever {
-				d = callDeferStack
-			}
-			s.callResult(n.Left, d)
-		}
-	case OGO:
-		s.callResult(n.Left, callGo)
-
-	case OAS2DOTTYPE:
-		res, resok := s.dottype(n.Right, true)
-		deref := false
-		if !canSSAType(n.Right.Type) {
-			if res.Op != ssa.OpLoad {
-				s.Fatalf("dottype of non-load")
-			}
-			mem := s.mem()
-			if mem.Op == ssa.OpVarKill {
-				mem = mem.Args[0]
-			}
-			if res.Args[1] != mem {
-				s.Fatalf("memory no longer live from 2-result dottype load")
-			}
-			deref = true
-			res = res.Args[0]
-		}
-		s.assign(n.List.First(), res, deref, 0)
-		s.assign(n.List.Second(), resok, false, 0)
-		return
-
-	case OAS2FUNC:
-		// We come here only when it is an intrinsic call returning two values.
-		if !isIntrinsicCall(n.Right) {
-			s.Fatalf("non-intrinsic AS2FUNC not expanded %v", n.Right)
-		}
-		v := s.intrinsicCall(n.Right)
-		v1 := s.newValue1(ssa.OpSelect0, n.List.First().Type, v)
-		v2 := s.newValue1(ssa.OpSelect1, n.List.Second().Type, v)
-		s.assign(n.List.First(), v1, false, 0)
-		s.assign(n.List.Second(), v2, false, 0)
-		return
-
-	case ODCL:
-		if n.Left.Class() == PAUTOHEAP {
-			s.Fatalf("DCL %v", n)
-		}
-
-	case OLABEL:
-		sym := n.Sym
-		lab := s.label(sym)
-
-		// Associate label with its control flow node, if any
-		if ctl := n.labeledControl(); ctl != nil {
-			s.labeledNodes[ctl] = lab
-		}
-
-		// The label might already have a target block via a goto.
-		if lab.target == nil {
-			lab.target = s.f.NewBlock(ssa.BlockPlain)
-		}
-
-		// Go to that label.
-		// (We pretend "label:" is preceded by "goto label", unless the predecessor is unreachable.)
-		if s.curBlock != nil {
-			b := s.endBlock()
-			b.AddEdgeTo(lab.target)
-		}
-		s.startBlock(lab.target)
-
-	case OGOTO:
-		sym := n.Sym
-
-		lab := s.label(sym)
-		if lab.target == nil {
-			lab.target = s.f.NewBlock(ssa.BlockPlain)
-		}
-
-		b := s.endBlock()
-		b.Pos = s.lastPos.WithIsStmt() // Do this even if b is an empty block.
-		b.AddEdgeTo(lab.target)
-
-	case OAS:
-		if n.Left == n.Right && n.Left.Op == ONAME {
-			// An x=x assignment. No point in doing anything
-			// here. In addition, skipping this assignment
-			// prevents generating:
-			//   VARDEF x
-			//   COPY x -> x
-			// which is bad because x is incorrectly considered
-			// dead before the vardef. See issue #14904.
-			return
-		}
-
-		// Evaluate RHS.
-		rhs := n.Right
-		if rhs != nil {
-			switch rhs.Op {
-			case OSTRUCTLIT, OARRAYLIT, OSLICELIT:
-				// All literals with nonzero fields have already been
-				// rewritten during walk. Any that remain are just T{}
-				// or equivalents. Use the zero value.
-				if !isZero(rhs) {
-					s.Fatalf("literal with nonzero value in SSA: %v", rhs)
-				}
-				rhs = nil
-			case OAPPEND:
-				// 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 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
-			}
-		}
-
-		if n.Left.isBlank() {
-			// _ = rhs
-			// Just evaluate rhs for side-effects.
-			if rhs != nil {
-				s.expr(rhs)
-			}
-			return
-		}
-
-		var t *types.Type
-		if n.Right != nil {
-			t = n.Right.Type
-		} else {
-			t = n.Left.Type
-		}
-
-		var r *ssa.Value
-		deref := !canSSAType(t)
-		if deref {
-			if rhs == nil {
-				r = nil // Signal assign to use OpZero.
-			} else {
-				r = s.addr(rhs)
-			}
-		} else {
-			if rhs == nil {
-				r = s.zeroVal(t)
-			} else {
-				r = s.expr(rhs)
-			}
-		}
-
-		var skip skipMask
-		if rhs != nil && (rhs.Op == OSLICE || rhs.Op == OSLICE3 || rhs.Op == OSLICESTR) && samesafeexpr(rhs.Left, n.Left) {
-			// We're assigning a slicing operation back to its source.
-			// Don't write back fields we aren't changing. See issue #14855.
-			i, j, k := rhs.SliceBounds()
-			if i != nil && (i.Op == OLITERAL && i.Val().Ctype() == CTINT && i.Int64Val() == 0) {
-				// [0:...] is the same as [:...]
-				i = nil
-			}
-			// TODO: detect defaults for len/cap also.
-			// Currently doesn't really work because (*p)[:len(*p)] appears here as:
-			//    tmp = len(*p)
-			//    (*p)[:tmp]
-			//if j != nil && (j.Op == OLEN && samesafeexpr(j.Left, n.Left)) {
-			//      j = nil
-			//}
-			//if k != nil && (k.Op == OCAP && samesafeexpr(k.Left, n.Left)) {
-			//      k = nil
-			//}
-			if i == nil {
-				skip |= skipPtr
-				if j == nil {
-					skip |= skipLen
-				}
-				if k == nil {
-					skip |= skipCap
-				}
-			}
-		}
-
-		s.assign(n.Left, r, deref, skip)
-
-	case OIF:
-		if Isconst(n.Left, CTBOOL) {
-			s.stmtList(n.Left.Ninit)
-			if n.Left.BoolVal() {
-				s.stmtList(n.Nbody)
-			} else {
-				s.stmtList(n.Rlist)
-			}
-			break
-		}
-
-		bEnd := s.f.NewBlock(ssa.BlockPlain)
-		var likely int8
-		if n.Likely() {
-			likely = 1
-		}
-		var bThen *ssa.Block
-		if n.Nbody.Len() != 0 {
-			bThen = s.f.NewBlock(ssa.BlockPlain)
-		} else {
-			bThen = bEnd
-		}
-		var bElse *ssa.Block
-		if n.Rlist.Len() != 0 {
-			bElse = s.f.NewBlock(ssa.BlockPlain)
-		} else {
-			bElse = bEnd
-		}
-		s.condBranch(n.Left, bThen, bElse, likely)
-
-		if n.Nbody.Len() != 0 {
-			s.startBlock(bThen)
-			s.stmtList(n.Nbody)
-			if b := s.endBlock(); b != nil {
-				b.AddEdgeTo(bEnd)
-			}
-		}
-		if n.Rlist.Len() != 0 {
-			s.startBlock(bElse)
-			s.stmtList(n.Rlist)
-			if b := s.endBlock(); b != nil {
-				b.AddEdgeTo(bEnd)
-			}
-		}
-		s.startBlock(bEnd)
-
-	case ORETURN:
-		s.stmtList(n.List)
-		b := s.exit()
-		b.Pos = s.lastPos.WithIsStmt()
-
-	case ORETJMP:
-		s.stmtList(n.List)
-		b := s.exit()
-		b.Kind = ssa.BlockRetJmp // override BlockRet
-		b.Aux = n.Sym.Linksym()
-
-	case OCONTINUE, OBREAK:
-		var to *ssa.Block
-		if n.Sym == nil {
-			// plain break/continue
-			switch n.Op {
-			case OCONTINUE:
-				to = s.continueTo
-			case OBREAK:
-				to = s.breakTo
-			}
-		} else {
-			// labeled break/continue; look up the target
-			sym := n.Sym
-			lab := s.label(sym)
-			switch n.Op {
-			case OCONTINUE:
-				to = lab.continueTarget
-			case OBREAK:
-				to = lab.breakTarget
-			}
-		}
-
-		b := s.endBlock()
-		b.Pos = s.lastPos.WithIsStmt() // Do this even if b is an empty block.
-		b.AddEdgeTo(to)
-
-	case OFOR, OFORUNTIL:
-		// OFOR: for Ninit; Left; Right { Nbody }
-		// cond (Left); body (Nbody); incr (Right)
-		//
-		// OFORUNTIL: for Ninit; Left; Right; List { Nbody }
-		// => body: { Nbody }; incr: Right; if Left { lateincr: List; goto body }; end:
-		bCond := s.f.NewBlock(ssa.BlockPlain)
-		bBody := s.f.NewBlock(ssa.BlockPlain)
-		bIncr := s.f.NewBlock(ssa.BlockPlain)
-		bEnd := s.f.NewBlock(ssa.BlockPlain)
-
-		// ensure empty for loops have correct position; issue #30167
-		bBody.Pos = n.Pos
-
-		// first, jump to condition test (OFOR) or body (OFORUNTIL)
-		b := s.endBlock()
-		if n.Op == OFOR {
-			b.AddEdgeTo(bCond)
-			// generate code to test condition
-			s.startBlock(bCond)
-			if n.Left != nil {
-				s.condBranch(n.Left, bBody, bEnd, 1)
-			} else {
-				b := s.endBlock()
-				b.Kind = ssa.BlockPlain
-				b.AddEdgeTo(bBody)
-			}
-
-		} else {
-			b.AddEdgeTo(bBody)
-		}
-
-		// set up for continue/break in body
-		prevContinue := s.continueTo
-		prevBreak := s.breakTo
-		s.continueTo = bIncr
-		s.breakTo = bEnd
-		lab := s.labeledNodes[n]
-		if lab != nil {
-			// labeled for loop
-			lab.continueTarget = bIncr
-			lab.breakTarget = bEnd
-		}
-
-		// generate body
-		s.startBlock(bBody)
-		s.stmtList(n.Nbody)
-
-		// tear down continue/break
-		s.continueTo = prevContinue
-		s.breakTo = prevBreak
-		if lab != nil {
-			lab.continueTarget = nil
-			lab.breakTarget = nil
-		}
-
-		// done with body, goto incr
-		if b := s.endBlock(); b != nil {
-			b.AddEdgeTo(bIncr)
-		}
-
-		// generate incr (and, for OFORUNTIL, condition)
-		s.startBlock(bIncr)
-		if n.Right != nil {
-			s.stmt(n.Right)
-		}
-		if n.Op == OFOR {
-			if b := s.endBlock(); b != nil {
-				b.AddEdgeTo(bCond)
-				// It can happen that bIncr ends in a block containing only VARKILL,
-				// and that muddles the debugging experience.
-				if n.Op != OFORUNTIL && b.Pos == src.NoXPos {
-					b.Pos = bCond.Pos
-				}
-			}
-		} else {
-			// bCond is unused in OFORUNTIL, so repurpose it.
-			bLateIncr := bCond
-			// test condition
-			s.condBranch(n.Left, bLateIncr, bEnd, 1)
-			// generate late increment
-			s.startBlock(bLateIncr)
-			s.stmtList(n.List)
-			s.endBlock().AddEdgeTo(bBody)
-		}
-
-		s.startBlock(bEnd)
-
-	case OSWITCH, OSELECT:
-		// These have been mostly rewritten by the front end into their Nbody fields.
-		// Our main task is to correctly hook up any break statements.
-		bEnd := s.f.NewBlock(ssa.BlockPlain)
-
-		prevBreak := s.breakTo
-		s.breakTo = bEnd
-		lab := s.labeledNodes[n]
-		if lab != nil {
-			// labeled
-			lab.breakTarget = bEnd
-		}
-
-		// generate body code
-		s.stmtList(n.Nbody)
-
-		s.breakTo = prevBreak
-		if lab != nil {
-			lab.breakTarget = nil
-		}
-
-		// walk adds explicit OBREAK nodes to the end of all reachable code paths.
-		// If we still have a current block here, then mark it unreachable.
-		if s.curBlock != nil {
-			m := s.mem()
-			b := s.endBlock()
-			b.Kind = ssa.BlockExit
-			b.SetControl(m)
-		}
-		s.startBlock(bEnd)
-
-	case OVARDEF:
-		if !s.canSSA(n.Left) {
-			s.vars[&memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, n.Left, s.mem(), false)
-		}
-	case OVARKILL:
-		// Insert a varkill op to record that a variable is no longer live.
-		// We only care about liveness info at call sites, so putting the
-		// varkill in the store chain is enough to keep it correctly ordered
-		// with respect to call ops.
-		if !s.canSSA(n.Left) {
-			s.vars[&memVar] = s.newValue1Apos(ssa.OpVarKill, types.TypeMem, n.Left, s.mem(), false)
-		}
-
-	case OVARLIVE:
-		// Insert a varlive op to record that a variable is still live.
-		if !n.Left.Name.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:
-		p := s.expr(n.Left)
-		s.nilCheck(p)
-
-	case OINLMARK:
-		s.newValue1I(ssa.OpInlMark, types.TypeVoid, n.Xoffset, s.mem())
-
-	default:
-		s.Fatalf("unhandled stmt %v", n.Op)
-	}
-}
-
-// If true, share as many open-coded defer exits as possible (with the downside of
-// worse line-number information)
-const shareDeferExits = false
-
-// exit processes any code that needs to be generated just before returning.
-// It returns a BlockRet block that ends the control flow. Its control value
-// will be set to the final memory state.
-func (s *state) exit() *ssa.Block {
-	if s.hasdefer {
-		if s.hasOpenDefers {
-			if shareDeferExits && s.lastDeferExit != nil && len(s.openDefers) == s.lastDeferCount {
-				if s.curBlock.Kind != ssa.BlockPlain {
-					panic("Block for an exit should be BlockPlain")
-				}
-				s.curBlock.AddEdgeTo(s.lastDeferExit)
-				s.endBlock()
-				return s.lastDeferFinalBlock
-			}
-			s.openDeferExit()
-		} else {
-			s.rtcall(Deferreturn, true, nil)
-		}
-	}
-
-	// Run exit code. Typically, this code copies heap-allocated PPARAMOUT
-	// variables back to the stack.
-	s.stmtList(s.curfn.Func.Exit)
-
-	// Store SSAable PPARAMOUT variables back to stack locations.
-	for _, n := range s.returns {
-		addr := s.decladdrs[n]
-		val := s.variable(n, n.Type)
-		s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
-		s.store(n.Type, addr, val)
-		// TODO: if val is ever spilled, we'd like to use the
-		// PPARAMOUT slot for spilling it. That won't happen
-		// currently.
-	}
-
-	// Do actual return.
-	m := s.mem()
-	b := s.endBlock()
-	b.Kind = ssa.BlockRet
-	b.SetControl(m)
-	if s.hasdefer && s.hasOpenDefers {
-		s.lastDeferFinalBlock = b
-	}
-	return b
-}
-
-type opAndType struct {
-	op    Op
-	etype types.EType
-}
-
-var opToSSA = map[opAndType]ssa.Op{
-	opAndType{OADD, TINT8}:    ssa.OpAdd8,
-	opAndType{OADD, TUINT8}:   ssa.OpAdd8,
-	opAndType{OADD, TINT16}:   ssa.OpAdd16,
-	opAndType{OADD, TUINT16}:  ssa.OpAdd16,
-	opAndType{OADD, TINT32}:   ssa.OpAdd32,
-	opAndType{OADD, TUINT32}:  ssa.OpAdd32,
-	opAndType{OADD, TINT64}:   ssa.OpAdd64,
-	opAndType{OADD, TUINT64}:  ssa.OpAdd64,
-	opAndType{OADD, TFLOAT32}: ssa.OpAdd32F,
-	opAndType{OADD, TFLOAT64}: ssa.OpAdd64F,
-
-	opAndType{OSUB, TINT8}:    ssa.OpSub8,
-	opAndType{OSUB, TUINT8}:   ssa.OpSub8,
-	opAndType{OSUB, TINT16}:   ssa.OpSub16,
-	opAndType{OSUB, TUINT16}:  ssa.OpSub16,
-	opAndType{OSUB, TINT32}:   ssa.OpSub32,
-	opAndType{OSUB, TUINT32}:  ssa.OpSub32,
-	opAndType{OSUB, TINT64}:   ssa.OpSub64,
-	opAndType{OSUB, TUINT64}:  ssa.OpSub64,
-	opAndType{OSUB, TFLOAT32}: ssa.OpSub32F,
-	opAndType{OSUB, TFLOAT64}: ssa.OpSub64F,
-
-	opAndType{ONOT, TBOOL}: ssa.OpNot,
-
-	opAndType{ONEG, TINT8}:    ssa.OpNeg8,
-	opAndType{ONEG, TUINT8}:   ssa.OpNeg8,
-	opAndType{ONEG, TINT16}:   ssa.OpNeg16,
-	opAndType{ONEG, TUINT16}:  ssa.OpNeg16,
-	opAndType{ONEG, TINT32}:   ssa.OpNeg32,
-	opAndType{ONEG, TUINT32}:  ssa.OpNeg32,
-	opAndType{ONEG, TINT64}:   ssa.OpNeg64,
-	opAndType{ONEG, TUINT64}:  ssa.OpNeg64,
-	opAndType{ONEG, TFLOAT32}: ssa.OpNeg32F,
-	opAndType{ONEG, TFLOAT64}: ssa.OpNeg64F,
-
-	opAndType{OBITNOT, TINT8}:   ssa.OpCom8,
-	opAndType{OBITNOT, TUINT8}:  ssa.OpCom8,
-	opAndType{OBITNOT, TINT16}:  ssa.OpCom16,
-	opAndType{OBITNOT, TUINT16}: ssa.OpCom16,
-	opAndType{OBITNOT, TINT32}:  ssa.OpCom32,
-	opAndType{OBITNOT, TUINT32}: ssa.OpCom32,
-	opAndType{OBITNOT, TINT64}:  ssa.OpCom64,
-	opAndType{OBITNOT, TUINT64}: ssa.OpCom64,
-
-	opAndType{OIMAG, TCOMPLEX64}:  ssa.OpComplexImag,
-	opAndType{OIMAG, TCOMPLEX128}: ssa.OpComplexImag,
-	opAndType{OREAL, TCOMPLEX64}:  ssa.OpComplexReal,
-	opAndType{OREAL, TCOMPLEX128}: ssa.OpComplexReal,
-
-	opAndType{OMUL, TINT8}:    ssa.OpMul8,
-	opAndType{OMUL, TUINT8}:   ssa.OpMul8,
-	opAndType{OMUL, TINT16}:   ssa.OpMul16,
-	opAndType{OMUL, TUINT16}:  ssa.OpMul16,
-	opAndType{OMUL, TINT32}:   ssa.OpMul32,
-	opAndType{OMUL, TUINT32}:  ssa.OpMul32,
-	opAndType{OMUL, TINT64}:   ssa.OpMul64,
-	opAndType{OMUL, TUINT64}:  ssa.OpMul64,
-	opAndType{OMUL, TFLOAT32}: ssa.OpMul32F,
-	opAndType{OMUL, TFLOAT64}: ssa.OpMul64F,
-
-	opAndType{ODIV, TFLOAT32}: ssa.OpDiv32F,
-	opAndType{ODIV, TFLOAT64}: ssa.OpDiv64F,
-
-	opAndType{ODIV, TINT8}:   ssa.OpDiv8,
-	opAndType{ODIV, TUINT8}:  ssa.OpDiv8u,
-	opAndType{ODIV, TINT16}:  ssa.OpDiv16,
-	opAndType{ODIV, TUINT16}: ssa.OpDiv16u,
-	opAndType{ODIV, TINT32}:  ssa.OpDiv32,
-	opAndType{ODIV, TUINT32}: ssa.OpDiv32u,
-	opAndType{ODIV, TINT64}:  ssa.OpDiv64,
-	opAndType{ODIV, TUINT64}: ssa.OpDiv64u,
-
-	opAndType{OMOD, TINT8}:   ssa.OpMod8,
-	opAndType{OMOD, TUINT8}:  ssa.OpMod8u,
-	opAndType{OMOD, TINT16}:  ssa.OpMod16,
-	opAndType{OMOD, TUINT16}: ssa.OpMod16u,
-	opAndType{OMOD, TINT32}:  ssa.OpMod32,
-	opAndType{OMOD, TUINT32}: ssa.OpMod32u,
-	opAndType{OMOD, TINT64}:  ssa.OpMod64,
-	opAndType{OMOD, TUINT64}: ssa.OpMod64u,
-
-	opAndType{OAND, TINT8}:   ssa.OpAnd8,
-	opAndType{OAND, TUINT8}:  ssa.OpAnd8,
-	opAndType{OAND, TINT16}:  ssa.OpAnd16,
-	opAndType{OAND, TUINT16}: ssa.OpAnd16,
-	opAndType{OAND, TINT32}:  ssa.OpAnd32,
-	opAndType{OAND, TUINT32}: ssa.OpAnd32,
-	opAndType{OAND, TINT64}:  ssa.OpAnd64,
-	opAndType{OAND, TUINT64}: ssa.OpAnd64,
-
-	opAndType{OOR, TINT8}:   ssa.OpOr8,
-	opAndType{OOR, TUINT8}:  ssa.OpOr8,
-	opAndType{OOR, TINT16}:  ssa.OpOr16,
-	opAndType{OOR, TUINT16}: ssa.OpOr16,
-	opAndType{OOR, TINT32}:  ssa.OpOr32,
-	opAndType{OOR, TUINT32}: ssa.OpOr32,
-	opAndType{OOR, TINT64}:  ssa.OpOr64,
-	opAndType{OOR, TUINT64}: ssa.OpOr64,
-
-	opAndType{OXOR, TINT8}:   ssa.OpXor8,
-	opAndType{OXOR, TUINT8}:  ssa.OpXor8,
-	opAndType{OXOR, TINT16}:  ssa.OpXor16,
-	opAndType{OXOR, TUINT16}: ssa.OpXor16,
-	opAndType{OXOR, TINT32}:  ssa.OpXor32,
-	opAndType{OXOR, TUINT32}: ssa.OpXor32,
-	opAndType{OXOR, TINT64}:  ssa.OpXor64,
-	opAndType{OXOR, TUINT64}: ssa.OpXor64,
-
-	opAndType{OEQ, TBOOL}:      ssa.OpEqB,
-	opAndType{OEQ, TINT8}:      ssa.OpEq8,
-	opAndType{OEQ, TUINT8}:     ssa.OpEq8,
-	opAndType{OEQ, TINT16}:     ssa.OpEq16,
-	opAndType{OEQ, TUINT16}:    ssa.OpEq16,
-	opAndType{OEQ, TINT32}:     ssa.OpEq32,
-	opAndType{OEQ, TUINT32}:    ssa.OpEq32,
-	opAndType{OEQ, TINT64}:     ssa.OpEq64,
-	opAndType{OEQ, TUINT64}:    ssa.OpEq64,
-	opAndType{OEQ, TINTER}:     ssa.OpEqInter,
-	opAndType{OEQ, TSLICE}:     ssa.OpEqSlice,
-	opAndType{OEQ, TFUNC}:      ssa.OpEqPtr,
-	opAndType{OEQ, TMAP}:       ssa.OpEqPtr,
-	opAndType{OEQ, TCHAN}:      ssa.OpEqPtr,
-	opAndType{OEQ, TPTR}:       ssa.OpEqPtr,
-	opAndType{OEQ, TUINTPTR}:   ssa.OpEqPtr,
-	opAndType{OEQ, TUNSAFEPTR}: ssa.OpEqPtr,
-	opAndType{OEQ, TFLOAT64}:   ssa.OpEq64F,
-	opAndType{OEQ, TFLOAT32}:   ssa.OpEq32F,
-
-	opAndType{ONE, TBOOL}:      ssa.OpNeqB,
-	opAndType{ONE, TINT8}:      ssa.OpNeq8,
-	opAndType{ONE, TUINT8}:     ssa.OpNeq8,
-	opAndType{ONE, TINT16}:     ssa.OpNeq16,
-	opAndType{ONE, TUINT16}:    ssa.OpNeq16,
-	opAndType{ONE, TINT32}:     ssa.OpNeq32,
-	opAndType{ONE, TUINT32}:    ssa.OpNeq32,
-	opAndType{ONE, TINT64}:     ssa.OpNeq64,
-	opAndType{ONE, TUINT64}:    ssa.OpNeq64,
-	opAndType{ONE, TINTER}:     ssa.OpNeqInter,
-	opAndType{ONE, TSLICE}:     ssa.OpNeqSlice,
-	opAndType{ONE, TFUNC}:      ssa.OpNeqPtr,
-	opAndType{ONE, TMAP}:       ssa.OpNeqPtr,
-	opAndType{ONE, TCHAN}:      ssa.OpNeqPtr,
-	opAndType{ONE, TPTR}:       ssa.OpNeqPtr,
-	opAndType{ONE, TUINTPTR}:   ssa.OpNeqPtr,
-	opAndType{ONE, TUNSAFEPTR}: ssa.OpNeqPtr,
-	opAndType{ONE, TFLOAT64}:   ssa.OpNeq64F,
-	opAndType{ONE, TFLOAT32}:   ssa.OpNeq32F,
-
-	opAndType{OLT, TINT8}:    ssa.OpLess8,
-	opAndType{OLT, TUINT8}:   ssa.OpLess8U,
-	opAndType{OLT, TINT16}:   ssa.OpLess16,
-	opAndType{OLT, TUINT16}:  ssa.OpLess16U,
-	opAndType{OLT, TINT32}:   ssa.OpLess32,
-	opAndType{OLT, TUINT32}:  ssa.OpLess32U,
-	opAndType{OLT, TINT64}:   ssa.OpLess64,
-	opAndType{OLT, TUINT64}:  ssa.OpLess64U,
-	opAndType{OLT, TFLOAT64}: ssa.OpLess64F,
-	opAndType{OLT, TFLOAT32}: ssa.OpLess32F,
-
-	opAndType{OLE, TINT8}:    ssa.OpLeq8,
-	opAndType{OLE, TUINT8}:   ssa.OpLeq8U,
-	opAndType{OLE, TINT16}:   ssa.OpLeq16,
-	opAndType{OLE, TUINT16}:  ssa.OpLeq16U,
-	opAndType{OLE, TINT32}:   ssa.OpLeq32,
-	opAndType{OLE, TUINT32}:  ssa.OpLeq32U,
-	opAndType{OLE, TINT64}:   ssa.OpLeq64,
-	opAndType{OLE, TUINT64}:  ssa.OpLeq64U,
-	opAndType{OLE, TFLOAT64}: ssa.OpLeq64F,
-	opAndType{OLE, TFLOAT32}: ssa.OpLeq32F,
-}
-
-func (s *state) concreteEtype(t *types.Type) types.EType {
-	e := t.Etype
-	switch e {
-	default:
-		return e
-	case TINT:
-		if s.config.PtrSize == 8 {
-			return TINT64
-		}
-		return TINT32
-	case TUINT:
-		if s.config.PtrSize == 8 {
-			return TUINT64
-		}
-		return TUINT32
-	case TUINTPTR:
-		if s.config.PtrSize == 8 {
-			return TUINT64
-		}
-		return TUINT32
-	}
-}
-
-func (s *state) ssaOp(op Op, t *types.Type) ssa.Op {
-	etype := s.concreteEtype(t)
-	x, ok := opToSSA[opAndType{op, etype}]
-	if !ok {
-		s.Fatalf("unhandled binary op %v %s", op, etype)
-	}
-	return x
-}
-
-func floatForComplex(t *types.Type) *types.Type {
-	switch t.Etype {
-	case TCOMPLEX64:
-		return types.Types[TFLOAT32]
-	case TCOMPLEX128:
-		return types.Types[TFLOAT64]
-	}
-	Fatalf("unexpected type: %v", t)
-	return nil
-}
-
-func complexForFloat(t *types.Type) *types.Type {
-	switch t.Etype {
-	case TFLOAT32:
-		return types.Types[TCOMPLEX64]
-	case TFLOAT64:
-		return types.Types[TCOMPLEX128]
-	}
-	Fatalf("unexpected type: %v", t)
-	return nil
-}
-
-type opAndTwoTypes struct {
-	op     Op
-	etype1 types.EType
-	etype2 types.EType
-}
-
-type twoTypes struct {
-	etype1 types.EType
-	etype2 types.EType
-}
-
-type twoOpsAndType struct {
-	op1              ssa.Op
-	op2              ssa.Op
-	intermediateType types.EType
-}
-
-var fpConvOpToSSA = map[twoTypes]twoOpsAndType{
-
-	twoTypes{TINT8, TFLOAT32}:  twoOpsAndType{ssa.OpSignExt8to32, ssa.OpCvt32to32F, TINT32},
-	twoTypes{TINT16, TFLOAT32}: twoOpsAndType{ssa.OpSignExt16to32, ssa.OpCvt32to32F, TINT32},
-	twoTypes{TINT32, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32to32F, TINT32},
-	twoTypes{TINT64, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64to32F, TINT64},
-
-	twoTypes{TINT8, TFLOAT64}:  twoOpsAndType{ssa.OpSignExt8to32, ssa.OpCvt32to64F, TINT32},
-	twoTypes{TINT16, TFLOAT64}: twoOpsAndType{ssa.OpSignExt16to32, ssa.OpCvt32to64F, TINT32},
-	twoTypes{TINT32, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32to64F, TINT32},
-	twoTypes{TINT64, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64to64F, TINT64},
-
-	twoTypes{TFLOAT32, TINT8}:  twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to8, TINT32},
-	twoTypes{TFLOAT32, TINT16}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to16, TINT32},
-	twoTypes{TFLOAT32, TINT32}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpCopy, TINT32},
-	twoTypes{TFLOAT32, TINT64}: twoOpsAndType{ssa.OpCvt32Fto64, ssa.OpCopy, TINT64},
-
-	twoTypes{TFLOAT64, TINT8}:  twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to8, TINT32},
-	twoTypes{TFLOAT64, TINT16}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to16, TINT32},
-	twoTypes{TFLOAT64, TINT32}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpCopy, TINT32},
-	twoTypes{TFLOAT64, TINT64}: twoOpsAndType{ssa.OpCvt64Fto64, ssa.OpCopy, TINT64},
-	// unsigned
-	twoTypes{TUINT8, TFLOAT32}:  twoOpsAndType{ssa.OpZeroExt8to32, ssa.OpCvt32to32F, TINT32},
-	twoTypes{TUINT16, TFLOAT32}: twoOpsAndType{ssa.OpZeroExt16to32, ssa.OpCvt32to32F, TINT32},
-	twoTypes{TUINT32, TFLOAT32}: twoOpsAndType{ssa.OpZeroExt32to64, ssa.OpCvt64to32F, TINT64}, // go wide to dodge unsigned
-	twoTypes{TUINT64, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpInvalid, TUINT64},            // Cvt64Uto32F, branchy code expansion instead
-
-	twoTypes{TUINT8, TFLOAT64}:  twoOpsAndType{ssa.OpZeroExt8to32, ssa.OpCvt32to64F, TINT32},
-	twoTypes{TUINT16, TFLOAT64}: twoOpsAndType{ssa.OpZeroExt16to32, ssa.OpCvt32to64F, TINT32},
-	twoTypes{TUINT32, TFLOAT64}: twoOpsAndType{ssa.OpZeroExt32to64, ssa.OpCvt64to64F, TINT64}, // go wide to dodge unsigned
-	twoTypes{TUINT64, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpInvalid, TUINT64},            // Cvt64Uto64F, branchy code expansion instead
-
-	twoTypes{TFLOAT32, TUINT8}:  twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to8, TINT32},
-	twoTypes{TFLOAT32, TUINT16}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to16, TINT32},
-	twoTypes{TFLOAT32, TUINT32}: twoOpsAndType{ssa.OpCvt32Fto64, ssa.OpTrunc64to32, TINT64}, // go wide to dodge unsigned
-	twoTypes{TFLOAT32, TUINT64}: twoOpsAndType{ssa.OpInvalid, ssa.OpCopy, TUINT64},          // Cvt32Fto64U, branchy code expansion instead
-
-	twoTypes{TFLOAT64, TUINT8}:  twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to8, TINT32},
-	twoTypes{TFLOAT64, TUINT16}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to16, TINT32},
-	twoTypes{TFLOAT64, TUINT32}: twoOpsAndType{ssa.OpCvt64Fto64, ssa.OpTrunc64to32, TINT64}, // go wide to dodge unsigned
-	twoTypes{TFLOAT64, TUINT64}: twoOpsAndType{ssa.OpInvalid, ssa.OpCopy, TUINT64},          // Cvt64Fto64U, branchy code expansion instead
-
-	// float
-	twoTypes{TFLOAT64, TFLOAT32}: twoOpsAndType{ssa.OpCvt64Fto32F, ssa.OpCopy, TFLOAT32},
-	twoTypes{TFLOAT64, TFLOAT64}: twoOpsAndType{ssa.OpRound64F, ssa.OpCopy, TFLOAT64},
-	twoTypes{TFLOAT32, TFLOAT32}: twoOpsAndType{ssa.OpRound32F, ssa.OpCopy, TFLOAT32},
-	twoTypes{TFLOAT32, TFLOAT64}: twoOpsAndType{ssa.OpCvt32Fto64F, ssa.OpCopy, TFLOAT64},
-}
-
-// this map is used only for 32-bit arch, and only includes the difference
-// on 32-bit arch, don't use int64<->float conversion for uint32
-var fpConvOpToSSA32 = map[twoTypes]twoOpsAndType{
-	twoTypes{TUINT32, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32Uto32F, TUINT32},
-	twoTypes{TUINT32, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32Uto64F, TUINT32},
-	twoTypes{TFLOAT32, TUINT32}: twoOpsAndType{ssa.OpCvt32Fto32U, ssa.OpCopy, TUINT32},
-	twoTypes{TFLOAT64, TUINT32}: twoOpsAndType{ssa.OpCvt64Fto32U, ssa.OpCopy, TUINT32},
-}
-
-// uint64<->float conversions, only on machines that have instructions for that
-var uint64fpConvOpToSSA = map[twoTypes]twoOpsAndType{
-	twoTypes{TUINT64, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64Uto32F, TUINT64},
-	twoTypes{TUINT64, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64Uto64F, TUINT64},
-	twoTypes{TFLOAT32, TUINT64}: twoOpsAndType{ssa.OpCvt32Fto64U, ssa.OpCopy, TUINT64},
-	twoTypes{TFLOAT64, TUINT64}: twoOpsAndType{ssa.OpCvt64Fto64U, ssa.OpCopy, TUINT64},
-}
-
-var shiftOpToSSA = map[opAndTwoTypes]ssa.Op{
-	opAndTwoTypes{OLSH, TINT8, TUINT8}:   ssa.OpLsh8x8,
-	opAndTwoTypes{OLSH, TUINT8, TUINT8}:  ssa.OpLsh8x8,
-	opAndTwoTypes{OLSH, TINT8, TUINT16}:  ssa.OpLsh8x16,
-	opAndTwoTypes{OLSH, TUINT8, TUINT16}: ssa.OpLsh8x16,
-	opAndTwoTypes{OLSH, TINT8, TUINT32}:  ssa.OpLsh8x32,
-	opAndTwoTypes{OLSH, TUINT8, TUINT32}: ssa.OpLsh8x32,
-	opAndTwoTypes{OLSH, TINT8, TUINT64}:  ssa.OpLsh8x64,
-	opAndTwoTypes{OLSH, TUINT8, TUINT64}: ssa.OpLsh8x64,
-
-	opAndTwoTypes{OLSH, TINT16, TUINT8}:   ssa.OpLsh16x8,
-	opAndTwoTypes{OLSH, TUINT16, TUINT8}:  ssa.OpLsh16x8,
-	opAndTwoTypes{OLSH, TINT16, TUINT16}:  ssa.OpLsh16x16,
-	opAndTwoTypes{OLSH, TUINT16, TUINT16}: ssa.OpLsh16x16,
-	opAndTwoTypes{OLSH, TINT16, TUINT32}:  ssa.OpLsh16x32,
-	opAndTwoTypes{OLSH, TUINT16, TUINT32}: ssa.OpLsh16x32,
-	opAndTwoTypes{OLSH, TINT16, TUINT64}:  ssa.OpLsh16x64,
-	opAndTwoTypes{OLSH, TUINT16, TUINT64}: ssa.OpLsh16x64,
-
-	opAndTwoTypes{OLSH, TINT32, TUINT8}:   ssa.OpLsh32x8,
-	opAndTwoTypes{OLSH, TUINT32, TUINT8}:  ssa.OpLsh32x8,
-	opAndTwoTypes{OLSH, TINT32, TUINT16}:  ssa.OpLsh32x16,
-	opAndTwoTypes{OLSH, TUINT32, TUINT16}: ssa.OpLsh32x16,
-	opAndTwoTypes{OLSH, TINT32, TUINT32}:  ssa.OpLsh32x32,
-	opAndTwoTypes{OLSH, TUINT32, TUINT32}: ssa.OpLsh32x32,
-	opAndTwoTypes{OLSH, TINT32, TUINT64}:  ssa.OpLsh32x64,
-	opAndTwoTypes{OLSH, TUINT32, TUINT64}: ssa.OpLsh32x64,
-
-	opAndTwoTypes{OLSH, TINT64, TUINT8}:   ssa.OpLsh64x8,
-	opAndTwoTypes{OLSH, TUINT64, TUINT8}:  ssa.OpLsh64x8,
-	opAndTwoTypes{OLSH, TINT64, TUINT16}:  ssa.OpLsh64x16,
-	opAndTwoTypes{OLSH, TUINT64, TUINT16}: ssa.OpLsh64x16,
-	opAndTwoTypes{OLSH, TINT64, TUINT32}:  ssa.OpLsh64x32,
-	opAndTwoTypes{OLSH, TUINT64, TUINT32}: ssa.OpLsh64x32,
-	opAndTwoTypes{OLSH, TINT64, TUINT64}:  ssa.OpLsh64x64,
-	opAndTwoTypes{OLSH, TUINT64, TUINT64}: ssa.OpLsh64x64,
-
-	opAndTwoTypes{ORSH, TINT8, TUINT8}:   ssa.OpRsh8x8,
-	opAndTwoTypes{ORSH, TUINT8, TUINT8}:  ssa.OpRsh8Ux8,
-	opAndTwoTypes{ORSH, TINT8, TUINT16}:  ssa.OpRsh8x16,
-	opAndTwoTypes{ORSH, TUINT8, TUINT16}: ssa.OpRsh8Ux16,
-	opAndTwoTypes{ORSH, TINT8, TUINT32}:  ssa.OpRsh8x32,
-	opAndTwoTypes{ORSH, TUINT8, TUINT32}: ssa.OpRsh8Ux32,
-	opAndTwoTypes{ORSH, TINT8, TUINT64}:  ssa.OpRsh8x64,
-	opAndTwoTypes{ORSH, TUINT8, TUINT64}: ssa.OpRsh8Ux64,
-
-	opAndTwoTypes{ORSH, TINT16, TUINT8}:   ssa.OpRsh16x8,
-	opAndTwoTypes{ORSH, TUINT16, TUINT8}:  ssa.OpRsh16Ux8,
-	opAndTwoTypes{ORSH, TINT16, TUINT16}:  ssa.OpRsh16x16,
-	opAndTwoTypes{ORSH, TUINT16, TUINT16}: ssa.OpRsh16Ux16,
-	opAndTwoTypes{ORSH, TINT16, TUINT32}:  ssa.OpRsh16x32,
-	opAndTwoTypes{ORSH, TUINT16, TUINT32}: ssa.OpRsh16Ux32,
-	opAndTwoTypes{ORSH, TINT16, TUINT64}:  ssa.OpRsh16x64,
-	opAndTwoTypes{ORSH, TUINT16, TUINT64}: ssa.OpRsh16Ux64,
-
-	opAndTwoTypes{ORSH, TINT32, TUINT8}:   ssa.OpRsh32x8,
-	opAndTwoTypes{ORSH, TUINT32, TUINT8}:  ssa.OpRsh32Ux8,
-	opAndTwoTypes{ORSH, TINT32, TUINT16}:  ssa.OpRsh32x16,
-	opAndTwoTypes{ORSH, TUINT32, TUINT16}: ssa.OpRsh32Ux16,
-	opAndTwoTypes{ORSH, TINT32, TUINT32}:  ssa.OpRsh32x32,
-	opAndTwoTypes{ORSH, TUINT32, TUINT32}: ssa.OpRsh32Ux32,
-	opAndTwoTypes{ORSH, TINT32, TUINT64}:  ssa.OpRsh32x64,
-	opAndTwoTypes{ORSH, TUINT32, TUINT64}: ssa.OpRsh32Ux64,
-
-	opAndTwoTypes{ORSH, TINT64, TUINT8}:   ssa.OpRsh64x8,
-	opAndTwoTypes{ORSH, TUINT64, TUINT8}:  ssa.OpRsh64Ux8,
-	opAndTwoTypes{ORSH, TINT64, TUINT16}:  ssa.OpRsh64x16,
-	opAndTwoTypes{ORSH, TUINT64, TUINT16}: ssa.OpRsh64Ux16,
-	opAndTwoTypes{ORSH, TINT64, TUINT32}:  ssa.OpRsh64x32,
-	opAndTwoTypes{ORSH, TUINT64, TUINT32}: ssa.OpRsh64Ux32,
-	opAndTwoTypes{ORSH, TINT64, TUINT64}:  ssa.OpRsh64x64,
-	opAndTwoTypes{ORSH, TUINT64, TUINT64}: ssa.OpRsh64Ux64,
-}
-
-func (s *state) ssaShiftOp(op Op, t *types.Type, u *types.Type) ssa.Op {
-	etype1 := s.concreteEtype(t)
-	etype2 := s.concreteEtype(u)
-	x, ok := shiftOpToSSA[opAndTwoTypes{op, etype1, etype2}]
-	if !ok {
-		s.Fatalf("unhandled shift op %v etype=%s/%s", op, etype1, etype2)
-	}
-	return x
-}
-
-// expr converts the expression n to ssa, adds it to s and returns the ssa result.
-func (s *state) expr(n *Node) *ssa.Value {
-	if !(n.Op == ONAME || n.Op == OLITERAL && n.Sym != nil) {
-		// ONAMEs and named OLITERALs have the line number
-		// of the decl, not the use. See issue 14742.
-		s.pushLine(n.Pos)
-		defer s.popLine()
-	}
-
-	s.stmtList(n.Ninit)
-	switch n.Op {
-	case OBYTES2STRTMP:
-		slice := s.expr(n.Left)
-		ptr := s.newValue1(ssa.OpSlicePtr, s.f.Config.Types.BytePtr, slice)
-		len := s.newValue1(ssa.OpSliceLen, types.Types[TINT], slice)
-		return s.newValue2(ssa.OpStringMake, n.Type, ptr, len)
-	case OSTR2BYTESTMP:
-		str := s.expr(n.Left)
-		ptr := s.newValue1(ssa.OpStringPtr, s.f.Config.Types.BytePtr, str)
-		len := s.newValue1(ssa.OpStringLen, types.Types[TINT], str)
-		return s.newValue3(ssa.OpSliceMake, n.Type, ptr, len, len)
-	case OCFUNC:
-		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()
-			return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), sym, s.sb)
-		}
-		if s.canSSA(n) {
-			return s.variable(n, n.Type)
-		}
-		addr := s.addr(n)
-		return s.load(n.Type, addr)
-	case OCLOSUREVAR:
-		addr := s.addr(n)
-		return s.load(n.Type, addr)
-	case OLITERAL:
-		switch u := n.Val().U.(type) {
-		case *Mpint:
-			i := u.Int64()
-			switch n.Type.Size() {
-			case 1:
-				return s.constInt8(n.Type, int8(i))
-			case 2:
-				return s.constInt16(n.Type, int16(i))
-			case 4:
-				return s.constInt32(n.Type, int32(i))
-			case 8:
-				return s.constInt64(n.Type, i)
-			default:
-				s.Fatalf("bad integer size %d", n.Type.Size())
-				return nil
-			}
-		case string:
-			if u == "" {
-				return s.constEmptyString(n.Type)
-			}
-			return s.entryNewValue0A(ssa.OpConstString, n.Type, u)
-		case bool:
-			return s.constBool(u)
-		case *NilVal:
-			t := n.Type
-			switch {
-			case t.IsSlice():
-				return s.constSlice(t)
-			case t.IsInterface():
-				return s.constInterface(t)
-			default:
-				return s.constNil(t)
-			}
-		case *Mpflt:
-			switch n.Type.Size() {
-			case 4:
-				return s.constFloat32(n.Type, u.Float32())
-			case 8:
-				return s.constFloat64(n.Type, u.Float64())
-			default:
-				s.Fatalf("bad float size %d", n.Type.Size())
-				return nil
-			}
-		case *Mpcplx:
-			r := &u.Real
-			i := &u.Imag
-			switch n.Type.Size() {
-			case 8:
-				pt := types.Types[TFLOAT32]
-				return s.newValue2(ssa.OpComplexMake, n.Type,
-					s.constFloat32(pt, r.Float32()),
-					s.constFloat32(pt, i.Float32()))
-			case 16:
-				pt := types.Types[TFLOAT64]
-				return s.newValue2(ssa.OpComplexMake, n.Type,
-					s.constFloat64(pt, r.Float64()),
-					s.constFloat64(pt, i.Float64()))
-			default:
-				s.Fatalf("bad float size %d", n.Type.Size())
-				return nil
-			}
-
-		default:
-			s.Fatalf("unhandled OLITERAL %v", n.Val().Ctype())
-			return nil
-		}
-	case OCONVNOP:
-		to := n.Type
-		from := n.Left.Type
-
-		// Assume everything will work out, so set up our return value.
-		// Anything interesting that happens from here is a fatal.
-		x := s.expr(n.Left)
-
-		// Special case for not confusing GC and liveness.
-		// We don't want pointers accidentally classified
-		// as not-pointers or vice-versa because of copy
-		// elision.
-		if to.IsPtrShaped() != from.IsPtrShaped() {
-			return s.newValue2(ssa.OpConvert, to, x, s.mem())
-		}
-
-		v := s.newValue1(ssa.OpCopy, to, x) // ensure that v has the right type
-
-		// CONVNOP closure
-		if to.Etype == TFUNC && from.IsPtrShaped() {
-			return v
-		}
-
-		// named <--> unnamed type or typed <--> untyped const
-		if from.Etype == to.Etype {
-			return v
-		}
-
-		// unsafe.Pointer <--> *T
-		if to.IsUnsafePtr() && from.IsPtrShaped() || from.IsUnsafePtr() && to.IsPtrShaped() {
-			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 {
-			s.Fatalf("CONVNOP width mismatch %v (%d) -> %v (%d)\n", from, from.Width, to, to.Width)
-			return nil
-		}
-		if etypesign(from.Etype) != etypesign(to.Etype) {
-			s.Fatalf("CONVNOP sign mismatch %v (%s) -> %v (%s)\n", from, from.Etype, to, to.Etype)
-			return nil
-		}
-
-		if instrumenting {
-			// These appear to be fine, but they fail the
-			// integer constraint below, so okay them here.
-			// Sample non-integer conversion: map[string]string -> *uint8
-			return v
-		}
-
-		if etypesign(from.Etype) == 0 {
-			s.Fatalf("CONVNOP unrecognized non-integer %v -> %v\n", from, to)
-			return nil
-		}
-
-		// integer, same width, same sign
-		return v
-
-	case OCONV:
-		x := s.expr(n.Left)
-		ft := n.Left.Type // from type
-		tt := n.Type      // to type
-		if ft.IsBoolean() && tt.IsKind(TUINT8) {
-			// Bool -> uint8 is generated internally when indexing into runtime.staticbyte.
-			return s.newValue1(ssa.OpCopy, n.Type, x)
-		}
-		if ft.IsInteger() && tt.IsInteger() {
-			var op ssa.Op
-			if tt.Size() == ft.Size() {
-				op = ssa.OpCopy
-			} else if tt.Size() < ft.Size() {
-				// truncation
-				switch 10*ft.Size() + tt.Size() {
-				case 21:
-					op = ssa.OpTrunc16to8
-				case 41:
-					op = ssa.OpTrunc32to8
-				case 42:
-					op = ssa.OpTrunc32to16
-				case 81:
-					op = ssa.OpTrunc64to8
-				case 82:
-					op = ssa.OpTrunc64to16
-				case 84:
-					op = ssa.OpTrunc64to32
-				default:
-					s.Fatalf("weird integer truncation %v -> %v", ft, tt)
-				}
-			} else if ft.IsSigned() {
-				// sign extension
-				switch 10*ft.Size() + tt.Size() {
-				case 12:
-					op = ssa.OpSignExt8to16
-				case 14:
-					op = ssa.OpSignExt8to32
-				case 18:
-					op = ssa.OpSignExt8to64
-				case 24:
-					op = ssa.OpSignExt16to32
-				case 28:
-					op = ssa.OpSignExt16to64
-				case 48:
-					op = ssa.OpSignExt32to64
-				default:
-					s.Fatalf("bad integer sign extension %v -> %v", ft, tt)
-				}
-			} else {
-				// zero extension
-				switch 10*ft.Size() + tt.Size() {
-				case 12:
-					op = ssa.OpZeroExt8to16
-				case 14:
-					op = ssa.OpZeroExt8to32
-				case 18:
-					op = ssa.OpZeroExt8to64
-				case 24:
-					op = ssa.OpZeroExt16to32
-				case 28:
-					op = ssa.OpZeroExt16to64
-				case 48:
-					op = ssa.OpZeroExt32to64
-				default:
-					s.Fatalf("weird integer sign extension %v -> %v", ft, tt)
-				}
-			}
-			return s.newValue1(op, n.Type, x)
-		}
-
-		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 && !s.softFloat {
-				if conv1, ok1 := fpConvOpToSSA32[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
-					conv = conv1
-				}
-			}
-			if thearch.LinkArch.Family == sys.ARM64 || thearch.LinkArch.Family == sys.Wasm || thearch.LinkArch.Family == sys.S390X || s.softFloat {
-				if conv1, ok1 := uint64fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
-					conv = conv1
-				}
-			}
-
-			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 {
-						return s.uint32Tofloat32(n, x, ft, tt)
-					}
-					if tt.Size() == 8 {
-						return s.uint32Tofloat64(n, x, ft, tt)
-					}
-				} else if tt.Size() == 4 && tt.IsInteger() && !tt.IsSigned() {
-					// ft is float32 or float64, and tt is unsigned integer
-					if ft.Size() == 4 {
-						return s.float32ToUint32(n, x, ft, tt)
-					}
-					if ft.Size() == 8 {
-						return s.float64ToUint32(n, x, ft, tt)
-					}
-				}
-			}
-
-			if !ok {
-				s.Fatalf("weird float conversion %v -> %v", ft, tt)
-			}
-			op1, op2, it := conv.op1, conv.op2, conv.intermediateType
-
-			if op1 != ssa.OpInvalid && op2 != ssa.OpInvalid {
-				// normal case, not tripping over unsigned 64
-				if op1 == ssa.OpCopy {
-					if op2 == ssa.OpCopy {
-						return x
-					}
-					return s.newValueOrSfCall1(op2, n.Type, x)
-				}
-				if op2 == ssa.OpCopy {
-					return s.newValueOrSfCall1(op1, n.Type, x)
-				}
-				return s.newValueOrSfCall1(op2, n.Type, s.newValueOrSfCall1(op1, types.Types[it], x))
-			}
-			// Tricky 64-bit unsigned cases.
-			if ft.IsInteger() {
-				// tt is float32 or float64, and ft is also unsigned
-				if tt.Size() == 4 {
-					return s.uint64Tofloat32(n, x, ft, tt)
-				}
-				if tt.Size() == 8 {
-					return s.uint64Tofloat64(n, x, ft, tt)
-				}
-				s.Fatalf("weird unsigned integer to float conversion %v -> %v", ft, tt)
-			}
-			// ft is float32 or float64, and tt is unsigned integer
-			if ft.Size() == 4 {
-				return s.float32ToUint64(n, x, ft, tt)
-			}
-			if ft.Size() == 8 {
-				return s.float64ToUint64(n, x, ft, tt)
-			}
-			s.Fatalf("weird float to unsigned integer conversion %v -> %v", ft, tt)
-			return nil
-		}
-
-		if ft.IsComplex() && tt.IsComplex() {
-			var op ssa.Op
-			if ft.Size() == tt.Size() {
-				switch ft.Size() {
-				case 8:
-					op = ssa.OpRound32F
-				case 16:
-					op = ssa.OpRound64F
-				default:
-					s.Fatalf("weird complex conversion %v -> %v", ft, tt)
-				}
-			} else if ft.Size() == 8 && tt.Size() == 16 {
-				op = ssa.OpCvt32Fto64F
-			} else if ft.Size() == 16 && tt.Size() == 8 {
-				op = ssa.OpCvt64Fto32F
-			} else {
-				s.Fatalf("weird complex conversion %v -> %v", ft, tt)
-			}
-			ftp := floatForComplex(ft)
-			ttp := floatForComplex(tt)
-			return s.newValue2(ssa.OpComplexMake, tt,
-				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)
-		return nil
-
-	case ODOTTYPE:
-		res, _ := s.dottype(n, false)
-		return res
-
-	// binary ops
-	case OLT, OEQ, ONE, OLE, OGE, OGT:
-		a := s.expr(n.Left)
-		b := s.expr(n.Right)
-		if n.Left.Type.IsComplex() {
-			pt := floatForComplex(n.Left.Type)
-			op := s.ssaOp(OEQ, pt)
-			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:
-				return c
-			case ONE:
-				return s.newValue1(ssa.OpNot, types.Types[TBOOL], c)
-			default:
-				s.Fatalf("ordered complex compare %v", n.Op)
-			}
-		}
-
-		// Convert OGE and OGT into OLE and OLT.
-		op := n.Op
-		switch op {
-		case OGE:
-			op, a, b = OLE, b, a
-		case OGT:
-			op, a, b = OLT, b, a
-		}
-		if n.Left.Type.IsFloat() {
-			// float comparison
-			return s.newValueOrSfCall2(s.ssaOp(op, n.Left.Type), types.Types[TBOOL], a, b)
-		}
-		// integer comparison
-		return s.newValue2(s.ssaOp(op, n.Left.Type), types.Types[TBOOL], a, b)
-	case OMUL:
-		a := s.expr(n.Left)
-		b := s.expr(n.Right)
-		if n.Type.IsComplex() {
-			mulop := ssa.OpMul64F
-			addop := ssa.OpAdd64F
-			subop := ssa.OpSub64F
-			pt := floatForComplex(n.Type) // Could be Float32 or Float64
-			wt := types.Types[TFLOAT64]   // Compute in Float64 to minimize cancellation error
-
-			areal := s.newValue1(ssa.OpComplexReal, pt, a)
-			breal := s.newValue1(ssa.OpComplexReal, pt, b)
-			aimag := s.newValue1(ssa.OpComplexImag, pt, a)
-			bimag := s.newValue1(ssa.OpComplexImag, pt, b)
-
-			if pt != wt { // Widen for calculation
-				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.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.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:
-		a := s.expr(n.Left)
-		b := s.expr(n.Right)
-		if n.Type.IsComplex() {
-			// TODO this is not executed because the front-end substitutes a runtime call.
-			// That probably ought to change; with modest optimization the widen/narrow
-			// conversions could all be elided in larger expression trees.
-			mulop := ssa.OpMul64F
-			addop := ssa.OpAdd64F
-			subop := ssa.OpSub64F
-			divop := ssa.OpDiv64F
-			pt := floatForComplex(n.Type) // Could be Float32 or Float64
-			wt := types.Types[TFLOAT64]   // Compute in Float64 to minimize cancellation error
-
-			areal := s.newValue1(ssa.OpComplexReal, pt, a)
-			breal := s.newValue1(ssa.OpComplexReal, pt, b)
-			aimag := s.newValue1(ssa.OpComplexImag, pt, a)
-			bimag := s.newValue1(ssa.OpComplexImag, pt, b)
-
-			if pt != wt { // Widen for calculation
-				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.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.newValueOrSfCall2(divop, wt, xreal, denom)
-			ximag = s.newValueOrSfCall2(divop, wt, ximag, denom)
-
-			if pt != wt { // Narrow to store back
-				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.intDivide(n, a, b)
-	case OMOD:
-		a := s.expr(n.Left)
-		b := s.expr(n.Right)
-		return s.intDivide(n, a, b)
-	case OADD, OSUB:
-		a := s.expr(n.Left)
-		b := s.expr(n.Right)
-		if n.Type.IsComplex() {
-			pt := floatForComplex(n.Type)
-			op := s.ssaOp(n.Op, pt)
-			return s.newValue2(ssa.OpComplexMake, n.Type,
-				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:
-		a := s.expr(n.Left)
-		b := s.expr(n.Right)
-		return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
-	case OANDNOT:
-		a := s.expr(n.Left)
-		b := s.expr(n.Right)
-		b = s.newValue1(s.ssaOp(OBITNOT, b.Type), b.Type, b)
-		return s.newValue2(s.ssaOp(OAND, n.Type), a.Type, a, b)
-	case OLSH, ORSH:
-		a := s.expr(n.Left)
-		b := s.expr(n.Right)
-		bt := b.Type
-		if bt.IsSigned() {
-			cmp := s.newValue2(s.ssaOp(OLE, bt), types.Types[TBOOL], s.zeroVal(bt), b)
-			s.check(cmp, panicshift)
-			bt = bt.ToUnsigned()
-		}
-		return s.newValue2(s.ssaShiftOp(n.Op, n.Type, bt), a.Type, a, b)
-	case OANDAND, OOROR:
-		// To implement OANDAND (and OOROR), we introduce a
-		// new temporary variable to hold the result. The
-		// variable is associated with the OANDAND node in the
-		// s.vars table (normally variables are only
-		// associated with ONAME nodes). We convert
-		//     A && B
-		// to
-		//     var = A
-		//     if var {
-		//         var = B
-		//     }
-		// Using var in the subsequent block introduces the
-		// necessary phi variable.
-		el := s.expr(n.Left)
-		s.vars[n] = el
-
-		b := s.endBlock()
-		b.Kind = ssa.BlockIf
-		b.SetControl(el)
-		// In theory, we should set b.Likely here based on context.
-		// However, gc only gives us likeliness hints
-		// in a single place, for plain OIF statements,
-		// and passing around context is finnicky, so don't bother for now.
-
-		bRight := s.f.NewBlock(ssa.BlockPlain)
-		bResult := s.f.NewBlock(ssa.BlockPlain)
-		if n.Op == OANDAND {
-			b.AddEdgeTo(bRight)
-			b.AddEdgeTo(bResult)
-		} else if n.Op == OOROR {
-			b.AddEdgeTo(bResult)
-			b.AddEdgeTo(bRight)
-		}
-
-		s.startBlock(bRight)
-		er := s.expr(n.Right)
-		s.vars[n] = er
-
-		b = s.endBlock()
-		b.AddEdgeTo(bResult)
-
-		s.startBlock(bResult)
-		return s.variable(n, types.Types[TBOOL])
-	case OCOMPLEX:
-		r := s.expr(n.Left)
-		i := s.expr(n.Right)
-		return s.newValue2(ssa.OpComplexMake, n.Type, r, i)
-
-	// unary ops
-	case ONEG:
-		a := s.expr(n.Left)
-		if n.Type.IsComplex() {
-			tp := floatForComplex(n.Type)
-			negop := s.ssaOp(n.Op, tp)
-			return s.newValue2(ssa.OpComplexMake, n.Type,
-				s.newValue1(negop, tp, s.newValue1(ssa.OpComplexReal, tp, a)),
-				s.newValue1(negop, tp, s.newValue1(ssa.OpComplexImag, tp, a)))
-		}
-		return s.newValue1(s.ssaOp(n.Op, n.Type), a.Type, a)
-	case ONOT, OBITNOT:
-		a := s.expr(n.Left)
-		return s.newValue1(s.ssaOp(n.Op, n.Type), a.Type, a)
-	case OIMAG, OREAL:
-		a := s.expr(n.Left)
-		return s.newValue1(s.ssaOp(n.Op, n.Left.Type), n.Type, a)
-	case OPLUS:
-		return s.expr(n.Left)
-
-	case OADDR:
-		return s.addr(n.Left)
-
-	case ORESULT:
-		if s.prevCall == nil || s.prevCall.Op != ssa.OpStaticLECall && s.prevCall.Op != ssa.OpInterLECall && s.prevCall.Op != ssa.OpClosureLECall {
-			// Do the old thing
-			addr := s.constOffPtrSP(types.NewPtr(n.Type), n.Xoffset)
-			return s.rawLoad(n.Type, addr)
-		}
-		which := s.prevCall.Aux.(*ssa.AuxCall).ResultForOffset(n.Xoffset)
-		if which == -1 {
-			// Do the old thing // TODO: Panic instead.
-			addr := s.constOffPtrSP(types.NewPtr(n.Type), n.Xoffset)
-			return s.rawLoad(n.Type, addr)
-		}
-		if canSSAType(n.Type) {
-			return s.newValue1I(ssa.OpSelectN, n.Type, which, s.prevCall)
-		} else {
-			addr := s.newValue1I(ssa.OpSelectNAddr, types.NewPtr(n.Type), which, s.prevCall)
-			return s.rawLoad(n.Type, addr)
-		}
-
-	case ODEREF:
-		p := s.exprPtr(n.Left, n.Bounded(), n.Pos)
-		return s.load(n.Type, p)
-
-	case ODOT:
-		if n.Left.Op == OSTRUCTLIT {
-			// All literals with nonzero fields have already been
-			// rewritten during walk. Any that remain are just T{}
-			// or equivalents. Use the zero value.
-			if !isZero(n.Left) {
-				s.Fatalf("literal with nonzero value in SSA: %v", n.Left)
-			}
-			return s.zeroVal(n.Type)
-		}
-		// If n is addressable and can't be represented in
-		// SSA, then load just the selected field. This
-		// prevents false memory dependencies in race/msan
-		// instrumentation.
-		if islvalue(n) && !s.canSSA(n) {
-			p := s.addr(n)
-			return s.load(n.Type, p)
-		}
-		v := s.expr(n.Left)
-		return s.newValue1I(ssa.OpStructSelect, n.Type, int64(fieldIdx(n)), v)
-
-	case ODOTPTR:
-		p := s.exprPtr(n.Left, n.Bounded(), n.Pos)
-		p = s.newValue1I(ssa.OpOffPtr, types.NewPtr(n.Type), n.Xoffset, p)
-		return s.load(n.Type, p)
-
-	case OINDEX:
-		switch {
-		case n.Left.Type.IsString():
-			if n.Bounded() && Isconst(n.Left, CTSTR) && Isconst(n.Right, CTINT) {
-				// Replace "abc"[1] with 'b'.
-				// Delayed until now because "abc"[1] is not an ideal constant.
-				// See test/fixedbugs/issue11370.go.
-				return s.newValue0I(ssa.OpConst8, types.Types[TUINT8], int64(int8(n.Left.StringVal()[n.Right.Int64Val()])))
-			}
-			a := s.expr(n.Left)
-			i := s.expr(n.Right)
-			len := s.newValue1(ssa.OpStringLen, types.Types[TINT], a)
-			i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
-			ptrtyp := s.f.Config.Types.BytePtr
-			ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a)
-			if Isconst(n.Right, CTINT) {
-				ptr = s.newValue1I(ssa.OpOffPtr, ptrtyp, n.Right.Int64Val(), ptr)
-			} else {
-				ptr = s.newValue2(ssa.OpAddPtr, ptrtyp, ptr, i)
-			}
-			return s.load(types.Types[TUINT8], ptr)
-		case n.Left.Type.IsSlice():
-			p := s.addr(n)
-			return s.load(n.Left.Type.Elem(), p)
-		case n.Left.Type.IsArray():
-			if canSSAType(n.Left.Type) {
-				// SSA can handle arrays of length at most 1.
-				bound := n.Left.Type.NumElem()
-				a := s.expr(n.Left)
-				i := s.expr(n.Right)
-				if bound == 0 {
-					// Bounds check will never succeed.  Might as well
-					// use constants for the bounds check.
-					z := s.constInt(types.Types[TINT], 0)
-					s.boundsCheck(z, z, ssa.BoundsIndex, false)
-					// The return value won't be live, return junk.
-					return s.newValue0(ssa.OpUnknown, n.Type)
-				}
-				len := s.constInt(types.Types[TINT], bound)
-				s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded()) // checks i == 0
-				return s.newValue1I(ssa.OpArraySelect, n.Type, 0, a)
-			}
-			p := s.addr(n)
-			return s.load(n.Left.Type.Elem(), p)
-		default:
-			s.Fatalf("bad type for index %v", n.Left.Type)
-			return nil
-		}
-
-	case OLEN, OCAP:
-		switch {
-		case n.Left.Type.IsSlice():
-			op := ssa.OpSliceLen
-			if n.Op == OCAP {
-				op = ssa.OpSliceCap
-			}
-			return s.newValue1(op, types.Types[TINT], s.expr(n.Left))
-		case n.Left.Type.IsString(): // string; not reachable for OCAP
-			return s.newValue1(ssa.OpStringLen, types.Types[TINT], s.expr(n.Left))
-		case n.Left.Type.IsMap(), n.Left.Type.IsChan():
-			return s.referenceTypeBuiltin(n, s.expr(n.Left))
-		default: // array
-			return s.constInt(types.Types[TINT], n.Left.Type.NumElem())
-		}
-
-	case OSPTR:
-		a := s.expr(n.Left)
-		if n.Left.Type.IsSlice() {
-			return s.newValue1(ssa.OpSlicePtr, n.Type, a)
-		} else {
-			return s.newValue1(ssa.OpStringPtr, n.Type, a)
-		}
-
-	case OITAB:
-		a := s.expr(n.Left)
-		return s.newValue1(ssa.OpITab, n.Type, a)
-
-	case OIDATA:
-		a := s.expr(n.Left)
-		return s.newValue1(ssa.OpIData, n.Type, a)
-
-	case OEFACE:
-		tab := s.expr(n.Left)
-		data := s.expr(n.Right)
-		return s.newValue2(ssa.OpIMake, n.Type, tab, data)
-
-	case OSLICEHEADER:
-		p := s.expr(n.Left)
-		l := s.expr(n.List.First())
-		c := s.expr(n.List.Second())
-		return s.newValue3(ssa.OpSliceMake, n.Type, p, l, c)
-
-	case OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR:
-		v := s.expr(n.Left)
-		var i, j, k *ssa.Value
-		low, high, max := n.SliceBounds()
-		if low != nil {
-			i = s.expr(low)
-		}
-		if high != nil {
-			j = s.expr(high)
-		}
-		if max != nil {
-			k = s.expr(max)
-		}
-		p, l, c := s.slice(v, i, j, k, n.Bounded())
-		return s.newValue3(ssa.OpSliceMake, n.Type, p, l, c)
-
-	case OSLICESTR:
-		v := s.expr(n.Left)
-		var i, j *ssa.Value
-		low, high, _ := n.SliceBounds()
-		if low != nil {
-			i = s.expr(low)
-		}
-		if high != nil {
-			j = s.expr(high)
-		}
-		p, l, _ := s.slice(v, i, j, nil, n.Bounded())
-		return s.newValue2(ssa.OpStringMake, n.Type, p, l)
-
-	case OCALLFUNC:
-		if isIntrinsicCall(n) {
-			return s.intrinsicCall(n)
-		}
-		fallthrough
-
-	case OCALLINTER, OCALLMETH:
-		return s.callResult(n, callNormal)
-
-	case OGETG:
-		return s.newValue1(ssa.OpGetG, n.Type, s.mem())
-
-	case OAPPEND:
-		return s.append(n, false)
-
-	case OSTRUCTLIT, OARRAYLIT:
-		// All literals with nonzero fields have already been
-		// rewritten during walk. Any that remain are just T{}
-		// or equivalents. Use the zero value.
-		if !isZero(n) {
-			s.Fatalf("literal with nonzero value in SSA: %v", n)
-		}
-		return s.zeroVal(n.Type)
-
-	case ONEWOBJ:
-		if n.Type.Elem().Size() == 0 {
-			return s.newValue1A(ssa.OpAddr, n.Type, zerobaseSym, s.sb)
-		}
-		typ := s.expr(n.Left)
-		vv := s.rtcall(newobject, true, []*types.Type{n.Type}, typ)
-		return vv[0]
-
-	default:
-		s.Fatalf("unhandled expr %v", n.Op)
-		return nil
-	}
-}
-
-// append converts an OAPPEND node to SSA.
-// If inplace is false, it converts the OAPPEND expression n to an ssa.Value,
-// adds it to s, and returns the Value.
-// If inplace is true, it writes the result of the OAPPEND expression n
-// back to the slice being appended to, and returns nil.
-// inplace MUST be set to false if the slice can be SSA'd.
-func (s *state) append(n *Node, inplace bool) *ssa.Value {
-	// If inplace is false, process as expression "append(s, e1, e2, e3)":
-	//
-	// ptr, len, cap := s
-	// newlen := len + 3
-	// if newlen > cap {
-	//     ptr, len, cap = growslice(s, newlen)
-	//     newlen = len + 3 // recalculate to avoid a spill
-	// }
-	// // with write barriers, if needed:
-	// *(ptr+len) = e1
-	// *(ptr+len+1) = e2
-	// *(ptr+len+2) = e3
-	// return makeslice(ptr, newlen, cap)
-	//
-	//
-	// If inplace is true, process as statement "s = append(s, e1, e2, e3)":
-	//
-	// a := &s
-	// ptr, len, cap := s
-	// newlen := len + 3
-	// if uint(newlen) > uint(cap) {
-	//    newptr, len, newcap = growslice(ptr, len, cap, newlen)
-	//    vardef(a)       // if necessary, advise liveness we are writing a new a
-	//    *a.cap = newcap // write before ptr to avoid a spill
-	//    *a.ptr = newptr // with write barrier
-	// }
-	// newlen = len + 3 // recalculate to avoid a spill
-	// *a.len = newlen
-	// // with write barriers, if needed:
-	// *(ptr+len) = e1
-	// *(ptr+len+1) = e2
-	// *(ptr+len+2) = e3
-
-	et := n.Type.Elem()
-	pt := types.NewPtr(et)
-
-	// Evaluate slice
-	sn := n.List.First() // the slice node is the first in the list
-
-	var slice, addr *ssa.Value
-	if inplace {
-		addr = s.addr(sn)
-		slice = s.load(n.Type, addr)
-	} else {
-		slice = s.expr(sn)
-	}
-
-	// Allocate new blocks
-	grow := s.f.NewBlock(ssa.BlockPlain)
-	assign := s.f.NewBlock(ssa.BlockPlain)
-
-	// Decide if we need to grow
-	nargs := int64(n.List.Len() - 1)
-	p := s.newValue1(ssa.OpSlicePtr, pt, slice)
-	l := s.newValue1(ssa.OpSliceLen, types.Types[TINT], slice)
-	c := s.newValue1(ssa.OpSliceCap, types.Types[TINT], slice)
-	nl := s.newValue2(s.ssaOp(OADD, types.Types[TINT]), types.Types[TINT], l, s.constInt(types.Types[TINT], nargs))
-
-	cmp := s.newValue2(s.ssaOp(OLT, types.Types[TUINT]), types.Types[TBOOL], c, nl)
-	s.vars[&ptrVar] = p
-
-	if !inplace {
-		s.vars[&newlenVar] = nl
-		s.vars[&capVar] = c
-	} else {
-		s.vars[&lenVar] = l
-	}
-
-	b := s.endBlock()
-	b.Kind = ssa.BlockIf
-	b.Likely = ssa.BranchUnlikely
-	b.SetControl(cmp)
-	b.AddEdgeTo(grow)
-	b.AddEdgeTo(assign)
-
-	// Call growslice
-	s.startBlock(grow)
-	taddr := s.expr(n.Left)
-	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 && 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())
-		}
-		capaddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, sliceCapOffset, addr)
-		s.store(types.Types[TINT], capaddr, r[2])
-		s.store(pt, addr, r[0])
-		// load the value we just stored to avoid having to spill it
-		s.vars[&ptrVar] = s.load(pt, addr)
-		s.vars[&lenVar] = r[1] // avoid a spill in the fast path
-	} else {
-		s.vars[&ptrVar] = r[0]
-		s.vars[&newlenVar] = s.newValue2(s.ssaOp(OADD, types.Types[TINT]), types.Types[TINT], r[1], s.constInt(types.Types[TINT], nargs))
-		s.vars[&capVar] = r[2]
-	}
-
-	b = s.endBlock()
-	b.AddEdgeTo(assign)
-
-	// assign new elements to slots
-	s.startBlock(assign)
-
-	if inplace {
-		l = s.variable(&lenVar, types.Types[TINT]) // generates phi for len
-		nl = s.newValue2(s.ssaOp(OADD, types.Types[TINT]), types.Types[TINT], l, s.constInt(types.Types[TINT], nargs))
-		lenaddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, sliceLenOffset, addr)
-		s.store(types.Types[TINT], lenaddr, nl)
-	}
-
-	// Evaluate args
-	type argRec struct {
-		// if store is true, we're appending the value v.  If false, we're appending the
-		// value at *v.
-		v     *ssa.Value
-		store bool
-	}
-	args := make([]argRec, 0, nargs)
-	for _, n := range n.List.Slice()[1:] {
-		if canSSAType(n.Type) {
-			args = append(args, argRec{v: s.expr(n), store: true})
-		} else {
-			v := s.addr(n)
-			args = append(args, argRec{v: v})
-		}
-	}
-
-	p = s.variable(&ptrVar, pt) // generates phi for ptr
-	if !inplace {
-		nl = s.variable(&newlenVar, types.Types[TINT]) // generates phi for nl
-		c = s.variable(&capVar, types.Types[TINT])     // generates phi for cap
-	}
-	p2 := s.newValue2(ssa.OpPtrIndex, pt, p, l)
-	for i, arg := range args {
-		addr := s.newValue2(ssa.OpPtrIndex, pt, p2, s.constInt(types.Types[TINT], int64(i)))
-		if arg.store {
-			s.storeType(et, addr, arg.v, 0, true)
-		} else {
-			s.move(et, addr, arg.v)
-		}
-	}
-
-	delete(s.vars, &ptrVar)
-	if inplace {
-		delete(s.vars, &lenVar)
-		return nil
-	}
-	delete(s.vars, &newlenVar)
-	delete(s.vars, &capVar)
-	// make result
-	return s.newValue3(ssa.OpSliceMake, n.Type, p, nl, c)
-}
-
-// condBranch evaluates the boolean expression cond and branches to yes
-// if cond is true and no if cond is false.
-// 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) {
-	switch cond.Op {
-	case OANDAND:
-		mid := s.f.NewBlock(ssa.BlockPlain)
-		s.stmtList(cond.Ninit)
-		s.condBranch(cond.Left, mid, no, max8(likely, 0))
-		s.startBlock(mid)
-		s.condBranch(cond.Right, yes, no, likely)
-		return
-		// Note: if likely==1, then both recursive calls pass 1.
-		// If likely==-1, then we don't have enough information to decide
-		// whether the first branch is likely or not. So we pass 0 for
-		// 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).
-	case OOROR:
-		mid := s.f.NewBlock(ssa.BlockPlain)
-		s.stmtList(cond.Ninit)
-		s.condBranch(cond.Left, yes, mid, min8(likely, 0))
-		s.startBlock(mid)
-		s.condBranch(cond.Right, yes, no, likely)
-		return
-		// 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.
-	case ONOT:
-		s.stmtList(cond.Ninit)
-		s.condBranch(cond.Left, no, yes, -likely)
-		return
-	}
-	c := s.expr(cond)
-	b := s.endBlock()
-	b.Kind = ssa.BlockIf
-	b.SetControl(c)
-	b.Likely = ssa.BranchPrediction(likely) // gc and ssa both use -1/0/+1 for likeliness
-	b.AddEdgeTo(yes)
-	b.AddEdgeTo(no)
-}
-
-type skipMask uint8
-
-const (
-	skipPtr skipMask = 1 << iota
-	skipLen
-	skipCap
-)
-
-// assign does left = right.
-// Right has already been evaluated to ssa, left has not.
-// If deref is true, then we do left = *right instead (and right has already been nil-checked).
-// If deref is true and right == nil, just do left = 0.
-// skip indicates assignments (at the top level) that can be avoided.
-func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask) {
-	if left.Op == ONAME && left.isBlank() {
-		return
-	}
-	t := left.Type
-	dowidth(t)
-	if s.canSSA(left) {
-		if deref {
-			s.Fatalf("can SSA LHS %v but not RHS %s", left, right)
-		}
-		if left.Op == ODOT {
-			// We're assigning to a field of an ssa-able value.
-			// We need to build a new structure with the new value for the
-			// field we're assigning and the old values for the other fields.
-			// For instance:
-			//   type T struct {a, b, c int}
-			//   var T x
-			//   x.b = 5
-			// For the x.b = 5 assignment we want to generate x = T{x.a, 5, x.c}
-
-			// Grab information about the structure type.
-			t := left.Left.Type
-			nf := t.NumFields()
-			idx := fieldIdx(left)
-
-			// Grab old value of structure.
-			old := s.expr(left.Left)
-
-			// Make new structure.
-			new := s.newValue0(ssa.StructMakeOp(t.NumFields()), t)
-
-			// Add fields as args.
-			for i := 0; i < nf; i++ {
-				if i == idx {
-					new.AddArg(right)
-				} else {
-					new.AddArg(s.newValue1I(ssa.OpStructSelect, t.FieldType(i), int64(i), old))
-				}
-			}
-
-			// Recursively assign the new value we've made to the base of the dot op.
-			s.assign(left.Left, new, false, 0)
-			// TODO: do we need to update named values here?
-			return
-		}
-		if left.Op == OINDEX && left.Left.Type.IsArray() {
-			s.pushLine(left.Pos)
-			defer s.popLine()
-			// We're assigning to an element of an ssa-able array.
-			// a[i] = v
-			t := left.Left.Type
-			n := t.NumElem()
-
-			i := s.expr(left.Right) // index
-			if n == 0 {
-				// The bounds check must fail.  Might as well
-				// ignore the actual index and just use zeros.
-				z := s.constInt(types.Types[TINT], 0)
-				s.boundsCheck(z, z, ssa.BoundsIndex, false)
-				return
-			}
-			if n != 1 {
-				s.Fatalf("assigning to non-1-length array")
-			}
-			// Rewrite to a = [1]{v}
-			len := s.constInt(types.Types[TINT], 1)
-			s.boundsCheck(i, len, ssa.BoundsIndex, false) // checks i == 0
-			v := s.newValue1(ssa.OpArrayMake1, t, right)
-			s.assign(left.Left, v, false, 0)
-			return
-		}
-		// Update variable assignment.
-		s.vars[left] = right
-		s.addNamedValue(left, right)
-		return
-	}
-
-	// If this assignment clobbers an entire local variable, then emit
-	// OpVarDef so liveness analysis knows the variable is redefined.
-	if base := clobberBase(left); base.Op == ONAME && base.Class() != PEXTERN && skip == 0 {
-		s.vars[&memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, base, s.mem(), !base.IsAutoTmp())
-	}
-
-	// Left is not ssa-able. Compute its address.
-	addr := s.addr(left)
-	if isReflectHeaderDataField(left) {
-		// 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).
-		// Mark it pointer type to signal the writebarrier pass to
-		// insert a write barrier.
-		t = types.Types[TUNSAFEPTR]
-	}
-	if deref {
-		// Treat as a mem->mem move.
-		if right == nil {
-			s.zero(t, addr)
-		} else {
-			s.move(t, addr, right)
-		}
-		return
-	}
-	// Treat as a store.
-	s.storeType(t, addr, right, skip, !left.IsAutoTmp())
-}
-
-// zeroVal returns the zero value for type t.
-func (s *state) zeroVal(t *types.Type) *ssa.Value {
-	switch {
-	case t.IsInteger():
-		switch t.Size() {
-		case 1:
-			return s.constInt8(t, 0)
-		case 2:
-			return s.constInt16(t, 0)
-		case 4:
-			return s.constInt32(t, 0)
-		case 8:
-			return s.constInt64(t, 0)
-		default:
-			s.Fatalf("bad sized integer type %v", t)
-		}
-	case t.IsFloat():
-		switch t.Size() {
-		case 4:
-			return s.constFloat32(t, 0)
-		case 8:
-			return s.constFloat64(t, 0)
-		default:
-			s.Fatalf("bad sized float type %v", t)
-		}
-	case t.IsComplex():
-		switch t.Size() {
-		case 8:
-			z := s.constFloat32(types.Types[TFLOAT32], 0)
-			return s.entryNewValue2(ssa.OpComplexMake, t, z, z)
-		case 16:
-			z := s.constFloat64(types.Types[TFLOAT64], 0)
-			return s.entryNewValue2(ssa.OpComplexMake, t, z, z)
-		default:
-			s.Fatalf("bad sized complex type %v", t)
-		}
-
-	case t.IsString():
-		return s.constEmptyString(t)
-	case t.IsPtrShaped():
-		return s.constNil(t)
-	case t.IsBoolean():
-		return s.constBool(false)
-	case t.IsInterface():
-		return s.constInterface(t)
-	case t.IsSlice():
-		return s.constSlice(t)
-	case t.IsStruct():
-		n := t.NumFields()
-		v := s.entryNewValue0(ssa.StructMakeOp(t.NumFields()), t)
-		for i := 0; i < n; i++ {
-			v.AddArg(s.zeroVal(t.FieldType(i)))
-		}
-		return v
-	case t.IsArray():
-		switch t.NumElem() {
-		case 0:
-			return s.entryNewValue0(ssa.OpArrayMake0, t)
-		case 1:
-			return s.entryNewValue1(ssa.OpArrayMake1, t, s.zeroVal(t.Elem()))
-		}
-	}
-	s.Fatalf("zero for type %v not implemented", t)
-	return nil
-}
-
-type callKind int8
-
-const (
-	callNormal callKind = iota
-	callDefer
-	callDeferStack
-	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.OpLeq64F:  sfRtCallDef{sysfunc("fge64"), TBOOL},
-		ssa.OpLeq32F:  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(ONEG, 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
-// implements that call as an intrinsic. args is a list of arguments to the func.
-type intrinsicBuilder func(s *state, n *Node, args []*ssa.Value) *ssa.Value
-
-type intrinsicKey struct {
-	arch *sys.Arch
-	pkg  string
-	fn   string
-}
-
-func init() {
-	intrinsics = map[intrinsicKey]intrinsicBuilder{}
-
-	var all []*sys.Arch
-	var p4 []*sys.Arch
-	var p8 []*sys.Arch
-	var lwatomics []*sys.Arch
-	for _, a := range &sys.Archs {
-		all = append(all, a)
-		if a.PtrSize == 4 {
-			p4 = append(p4, a)
-		} else {
-			p8 = append(p8, a)
-		}
-		if a.Family != sys.PPC64 {
-			lwatomics = append(lwatomics, a)
-		}
-	}
-
-	// add adds the intrinsic b for pkg.fn for the given list of architectures.
-	add := func(pkg, fn string, b intrinsicBuilder, archs ...*sys.Arch) {
-		for _, a := range archs {
-			intrinsics[intrinsicKey{a, pkg, fn}] = b
-		}
-	}
-	// addF does the same as add but operates on architecture families.
-	addF := func(pkg, fn string, b intrinsicBuilder, archFamilies ...sys.ArchFamily) {
-		m := 0
-		for _, f := range archFamilies {
-			if f >= 32 {
-				panic("too many architecture families")
-			}
-			m |= 1 << uint(f)
-		}
-		for _, a := range all {
-			if m>>uint(a.Family)&1 != 0 {
-				intrinsics[intrinsicKey{a, pkg, fn}] = b
-			}
-		}
-	}
-	// alias defines pkg.fn = pkg2.fn2 for all architectures in archs for which pkg2.fn2 exists.
-	alias := func(pkg, fn, pkg2, fn2 string, archs ...*sys.Arch) {
-		aliased := false
-		for _, a := range archs {
-			if b, ok := intrinsics[intrinsicKey{a, pkg2, fn2}]; ok {
-				intrinsics[intrinsicKey{a, pkg, fn}] = b
-				aliased = true
-			}
-		}
-		if !aliased {
-			panic(fmt.Sprintf("attempted to alias undefined intrinsic: %s.%s", pkg, fn))
-		}
-	}
-
-	/******** runtime ********/
-	if !instrumenting {
-		add("runtime", "slicebytetostringtmp",
-			func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-				// Compiler frontend optimizations emit OBYTES2STRTMP nodes
-				// for the backend instead of slicebytetostringtmp calls
-				// when not instrumenting.
-				return s.newValue2(ssa.OpStringMake, n.Type, args[0], args[1])
-			},
-			all...)
-	}
-	addF("runtime/internal/math", "MulUintptr",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			if s.config.PtrSize == 4 {
-				return s.newValue2(ssa.OpMul32uover, types.NewTuple(types.Types[TUINT], types.Types[TUINT]), args[0], args[1])
-			}
-			return s.newValue2(ssa.OpMul64uover, types.NewTuple(types.Types[TUINT], types.Types[TUINT]), args[0], args[1])
-		},
-		sys.AMD64, sys.I386, sys.MIPS64)
-	add("runtime", "KeepAlive",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			data := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, args[0])
-			s.vars[&memVar] = s.newValue2(ssa.OpKeepAlive, types.TypeMem, data, s.mem())
-			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...)
-
-	add("runtime", "getcallerpc",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue0(ssa.OpGetCallerPC, s.f.Config.Types.Uintptr)
-		},
-		all...)
-
-	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.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.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])
-		},
-		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X)
-	addF("runtime/internal/sys", "Bswap64",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpBswap64, types.Types[TUINT64], args[0])
-		},
-		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X)
-
-	/******** runtime/internal/atomic ********/
-	addF("runtime/internal/atomic", "Load",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			v := s.newValue2(ssa.OpAtomicLoad32, types.NewTuple(types.Types[TUINT32], types.TypeMem), args[0], s.mem())
-			s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-			return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v)
-		},
-		sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-	addF("runtime/internal/atomic", "Load8",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			v := s.newValue2(ssa.OpAtomicLoad8, types.NewTuple(types.Types[TUINT8], types.TypeMem), args[0], s.mem())
-			s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-			return s.newValue1(ssa.OpSelect0, types.Types[TUINT8], v)
-		},
-		sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-	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.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-	addF("runtime/internal/atomic", "LoadAcq",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			v := s.newValue2(ssa.OpAtomicLoadAcq32, types.NewTuple(types.Types[TUINT32], types.TypeMem), args[0], s.mem())
-			s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-			return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v)
-		},
-		sys.PPC64, sys.S390X)
-	addF("runtime/internal/atomic", "LoadAcq64",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			v := s.newValue2(ssa.OpAtomicLoadAcq64, 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.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.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-
-	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.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-	addF("runtime/internal/atomic", "Store8",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			s.vars[&memVar] = s.newValue3(ssa.OpAtomicStore8, types.TypeMem, args[0], args[1], s.mem())
-			return nil
-		},
-		sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-	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.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-	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.MIPS, sys.MIPS64, sys.RISCV64, sys.S390X)
-	addF("runtime/internal/atomic", "StoreRel",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			s.vars[&memVar] = s.newValue3(ssa.OpAtomicStoreRel32, types.TypeMem, args[0], args[1], s.mem())
-			return nil
-		},
-		sys.PPC64, sys.S390X)
-	addF("runtime/internal/atomic", "StoreRel64",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			s.vars[&memVar] = s.newValue3(ssa.OpAtomicStoreRel64, types.TypeMem, args[0], args[1], s.mem())
-			return nil
-		},
-		sys.PPC64)
-
-	addF("runtime/internal/atomic", "Xchg",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			v := s.newValue3(ssa.OpAtomicExchange32, types.NewTuple(types.Types[TUINT32], 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[TUINT32], v)
-		},
-		sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-	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.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-
-	type atomicOpEmitter func(s *state, n *Node, args []*ssa.Value, op ssa.Op, typ types.EType)
-
-	makeAtomicGuardedIntrinsicARM64 := func(op0, op1 ssa.Op, typ, rtyp types.EType, emit atomicOpEmitter) intrinsicBuilder {
-
-		return func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			// Target Atomic feature is identified by dynamic detection
-			addr := s.entryNewValue1A(ssa.OpAddr, types.Types[TBOOL].PtrTo(), arm64HasATOMICS, s.sb)
-			v := s.load(types.Types[TBOOL], addr)
-			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
-
-			// We have atomic instructions - use it directly.
-			s.startBlock(bTrue)
-			emit(s, n, args, op1, typ)
-			s.endBlock().AddEdgeTo(bEnd)
-
-			// Use original instruction sequence.
-			s.startBlock(bFalse)
-			emit(s, n, args, op0, typ)
-			s.endBlock().AddEdgeTo(bEnd)
-
-			// Merge results.
-			s.startBlock(bEnd)
-			if rtyp == TNIL {
-				return nil
-			} else {
-				return s.variable(n, types.Types[rtyp])
-			}
-		}
-	}
-
-	atomicXchgXaddEmitterARM64 := func(s *state, n *Node, args []*ssa.Value, op ssa.Op, typ types.EType) {
-		v := s.newValue3(op, types.NewTuple(types.Types[typ], types.TypeMem), args[0], args[1], s.mem())
-		s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-		s.vars[n] = s.newValue1(ssa.OpSelect0, types.Types[typ], v)
-	}
-	addF("runtime/internal/atomic", "Xchg",
-		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicExchange32, ssa.OpAtomicExchange32Variant, TUINT32, TUINT32, atomicXchgXaddEmitterARM64),
-		sys.ARM64)
-	addF("runtime/internal/atomic", "Xchg64",
-		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicExchange64, ssa.OpAtomicExchange64Variant, TUINT64, TUINT64, atomicXchgXaddEmitterARM64),
-		sys.ARM64)
-
-	addF("runtime/internal/atomic", "Xadd",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			v := s.newValue3(ssa.OpAtomicAdd32, types.NewTuple(types.Types[TUINT32], 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[TUINT32], v)
-		},
-		sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-	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.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-
-	addF("runtime/internal/atomic", "Xadd",
-		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAdd32, ssa.OpAtomicAdd32Variant, TUINT32, TUINT32, atomicXchgXaddEmitterARM64),
-		sys.ARM64)
-	addF("runtime/internal/atomic", "Xadd64",
-		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAdd64, ssa.OpAtomicAdd64Variant, TUINT64, TUINT64, atomicXchgXaddEmitterARM64),
-		sys.ARM64)
-
-	addF("runtime/internal/atomic", "Cas",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			v := s.newValue4(ssa.OpAtomicCompareAndSwap32, 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.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-	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.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
-	addF("runtime/internal/atomic", "CasRel",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			v := s.newValue4(ssa.OpAtomicCompareAndSwap32, 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.PPC64)
-
-	atomicCasEmitterARM64 := func(s *state, n *Node, args []*ssa.Value, op ssa.Op, typ types.EType) {
-		v := s.newValue4(op, 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)
-		s.vars[n] = s.newValue1(ssa.OpSelect0, types.Types[typ], v)
-	}
-
-	addF("runtime/internal/atomic", "Cas",
-		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicCompareAndSwap32, ssa.OpAtomicCompareAndSwap32Variant, TUINT32, TBOOL, atomicCasEmitterARM64),
-		sys.ARM64)
-	addF("runtime/internal/atomic", "Cas64",
-		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicCompareAndSwap64, ssa.OpAtomicCompareAndSwap64Variant, TUINT64, TBOOL, atomicCasEmitterARM64),
-		sys.ARM64)
-
-	addF("runtime/internal/atomic", "And8",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			s.vars[&memVar] = s.newValue3(ssa.OpAtomicAnd8, types.TypeMem, args[0], args[1], s.mem())
-			return nil
-		},
-		sys.AMD64, sys.MIPS, sys.PPC64, sys.S390X)
-	addF("runtime/internal/atomic", "And",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			s.vars[&memVar] = s.newValue3(ssa.OpAtomicAnd32, types.TypeMem, args[0], args[1], s.mem())
-			return nil
-		},
-		sys.AMD64, sys.MIPS, sys.PPC64, sys.S390X)
-	addF("runtime/internal/atomic", "Or8",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			s.vars[&memVar] = s.newValue3(ssa.OpAtomicOr8, types.TypeMem, args[0], args[1], s.mem())
-			return nil
-		},
-		sys.AMD64, sys.ARM64, sys.MIPS, sys.PPC64, sys.S390X)
-	addF("runtime/internal/atomic", "Or",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			s.vars[&memVar] = s.newValue3(ssa.OpAtomicOr32, types.TypeMem, args[0], args[1], s.mem())
-			return nil
-		},
-		sys.AMD64, sys.MIPS, sys.PPC64, sys.S390X)
-
-	atomicAndOrEmitterARM64 := func(s *state, n *Node, args []*ssa.Value, op ssa.Op, typ types.EType) {
-		s.vars[&memVar] = s.newValue3(op, types.TypeMem, args[0], args[1], s.mem())
-	}
-
-	addF("runtime/internal/atomic", "And8",
-		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAnd8, ssa.OpAtomicAnd8Variant, TNIL, TNIL, atomicAndOrEmitterARM64),
-		sys.ARM64)
-	addF("runtime/internal/atomic", "And",
-		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAnd32, ssa.OpAtomicAnd32Variant, TNIL, TNIL, atomicAndOrEmitterARM64),
-		sys.ARM64)
-	addF("runtime/internal/atomic", "Or8",
-		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicOr8, ssa.OpAtomicOr8Variant, TNIL, TNIL, atomicAndOrEmitterARM64),
-		sys.ARM64)
-	addF("runtime/internal/atomic", "Or",
-		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicOr32, ssa.OpAtomicOr32Variant, TNIL, TNIL, atomicAndOrEmitterARM64),
-		sys.ARM64)
-
-	alias("runtime/internal/atomic", "Loadint64", "runtime/internal/atomic", "Load64", all...)
-	alias("runtime/internal/atomic", "Xaddint64", "runtime/internal/atomic", "Xadd64", all...)
-	alias("runtime/internal/atomic", "Loaduint", "runtime/internal/atomic", "Load", p4...)
-	alias("runtime/internal/atomic", "Loaduint", "runtime/internal/atomic", "Load64", p8...)
-	alias("runtime/internal/atomic", "Loaduintptr", "runtime/internal/atomic", "Load", p4...)
-	alias("runtime/internal/atomic", "Loaduintptr", "runtime/internal/atomic", "Load64", p8...)
-	alias("runtime/internal/atomic", "LoadAcq", "runtime/internal/atomic", "Load", lwatomics...)
-	alias("runtime/internal/atomic", "LoadAcq64", "runtime/internal/atomic", "Load64", lwatomics...)
-	alias("runtime/internal/atomic", "LoadAcquintptr", "runtime/internal/atomic", "LoadAcq", p4...)
-	alias("sync", "runtime_LoadAcquintptr", "runtime/internal/atomic", "LoadAcq", p4...) // linknamed
-	alias("runtime/internal/atomic", "LoadAcquintptr", "runtime/internal/atomic", "LoadAcq64", p8...)
-	alias("sync", "runtime_LoadAcquintptr", "runtime/internal/atomic", "LoadAcq64", p8...) // linknamed
-	alias("runtime/internal/atomic", "Storeuintptr", "runtime/internal/atomic", "Store", p4...)
-	alias("runtime/internal/atomic", "Storeuintptr", "runtime/internal/atomic", "Store64", p8...)
-	alias("runtime/internal/atomic", "StoreRel", "runtime/internal/atomic", "Store", lwatomics...)
-	alias("runtime/internal/atomic", "StoreRel64", "runtime/internal/atomic", "Store64", lwatomics...)
-	alias("runtime/internal/atomic", "StoreReluintptr", "runtime/internal/atomic", "StoreRel", p4...)
-	alias("sync", "runtime_StoreReluintptr", "runtime/internal/atomic", "StoreRel", p4...) // linknamed
-	alias("runtime/internal/atomic", "StoreReluintptr", "runtime/internal/atomic", "StoreRel64", p8...)
-	alias("sync", "runtime_StoreReluintptr", "runtime/internal/atomic", "StoreRel64", p8...) // linknamed
-	alias("runtime/internal/atomic", "Xchguintptr", "runtime/internal/atomic", "Xchg", p4...)
-	alias("runtime/internal/atomic", "Xchguintptr", "runtime/internal/atomic", "Xchg64", p8...)
-	alias("runtime/internal/atomic", "Xadduintptr", "runtime/internal/atomic", "Xadd", p4...)
-	alias("runtime/internal/atomic", "Xadduintptr", "runtime/internal/atomic", "Xadd64", p8...)
-	alias("runtime/internal/atomic", "Casuintptr", "runtime/internal/atomic", "Cas", p4...)
-	alias("runtime/internal/atomic", "Casuintptr", "runtime/internal/atomic", "Cas64", p8...)
-	alias("runtime/internal/atomic", "Casp1", "runtime/internal/atomic", "Cas", p4...)
-	alias("runtime/internal/atomic", "Casp1", "runtime/internal/atomic", "Cas64", p8...)
-	alias("runtime/internal/atomic", "CasRel", "runtime/internal/atomic", "Cas", lwatomics...)
-
-	/******** math ********/
-	addF("math", "Sqrt",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpSqrt, types.Types[TFLOAT64], args[0])
-		},
-		sys.I386, sys.AMD64, sys.ARM, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.Wasm)
-	addF("math", "Trunc",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpTrunc, types.Types[TFLOAT64], args[0])
-		},
-		sys.ARM64, sys.PPC64, sys.S390X, sys.Wasm)
-	addF("math", "Ceil",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpCeil, types.Types[TFLOAT64], args[0])
-		},
-		sys.ARM64, sys.PPC64, sys.S390X, sys.Wasm)
-	addF("math", "Floor",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpFloor, types.Types[TFLOAT64], args[0])
-		},
-		sys.ARM64, sys.PPC64, sys.S390X, sys.Wasm)
-	addF("math", "Round",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpRound, types.Types[TFLOAT64], args[0])
-		},
-		sys.ARM64, sys.PPC64, 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.ARM64, sys.S390X, sys.Wasm)
-	addF("math", "Abs",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpAbs, types.Types[TFLOAT64], args[0])
-		},
-		sys.ARM64, sys.ARM, sys.PPC64, sys.Wasm)
-	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, sys.Wasm)
-	addF("math", "FMA",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue3(ssa.OpFMA, types.Types[TFLOAT64], args[0], args[1], args[2])
-		},
-		sys.ARM64, sys.PPC64, sys.S390X)
-	addF("math", "FMA",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			if !s.config.UseFMA {
-				s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64]
-				return s.variable(n, types.Types[TFLOAT64])
-			}
-			v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[TBOOL], x86HasFMA)
-			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 // >= haswell cpus are common
-
-			// We have the intrinsic - use it directly.
-			s.startBlock(bTrue)
-			s.vars[n] = s.newValue3(ssa.OpFMA, types.Types[TFLOAT64], args[0], args[1], args[2])
-			s.endBlock().AddEdgeTo(bEnd)
-
-			// Call the pure Go version.
-			s.startBlock(bFalse)
-			s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64]
-			s.endBlock().AddEdgeTo(bEnd)
-
-			// Merge results.
-			s.startBlock(bEnd)
-			return s.variable(n, types.Types[TFLOAT64])
-		},
-		sys.AMD64)
-	addF("math", "FMA",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			if !s.config.UseFMA {
-				s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64]
-				return s.variable(n, types.Types[TFLOAT64])
-			}
-			addr := s.entryNewValue1A(ssa.OpAddr, types.Types[TBOOL].PtrTo(), armHasVFPv4, s.sb)
-			v := s.load(types.Types[TBOOL], addr)
-			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
-
-			// We have the intrinsic - use it directly.
-			s.startBlock(bTrue)
-			s.vars[n] = s.newValue3(ssa.OpFMA, types.Types[TFLOAT64], args[0], args[1], args[2])
-			s.endBlock().AddEdgeTo(bEnd)
-
-			// Call the pure Go version.
-			s.startBlock(bFalse)
-			s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64]
-			s.endBlock().AddEdgeTo(bEnd)
-
-			// Merge results.
-			s.startBlock(bEnd)
-			return s.variable(n, types.Types[TFLOAT64])
-		},
-		sys.ARM)
-
-	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 {
-			v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[TBOOL], x86HasSSE41)
-			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)
-			s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64]
-			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",
-		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.PPC64, sys.Wasm)
-	addF("math/bits", "TrailingZeros32",
-		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.PPC64, sys.Wasm)
-	addF("math/bits", "TrailingZeros16",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			x := s.newValue1(ssa.OpZeroExt16to32, types.Types[TUINT32], args[0])
-			c := s.constInt32(types.Types[TUINT32], 1<<16)
-			y := s.newValue2(ssa.OpOr32, types.Types[TUINT32], x, c)
-			return s.newValue1(ssa.OpCtz32, types.Types[TINT], y)
-		},
-		sys.MIPS)
-	addF("math/bits", "TrailingZeros16",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpCtz16, types.Types[TINT], args[0])
-		},
-		sys.AMD64, sys.I386, sys.ARM, sys.ARM64, sys.Wasm)
-	addF("math/bits", "TrailingZeros16",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			x := s.newValue1(ssa.OpZeroExt16to64, types.Types[TUINT64], args[0])
-			c := s.constInt64(types.Types[TUINT64], 1<<16)
-			y := s.newValue2(ssa.OpOr64, types.Types[TUINT64], x, c)
-			return s.newValue1(ssa.OpCtz64, types.Types[TINT], y)
-		},
-		sys.S390X, sys.PPC64)
-	addF("math/bits", "TrailingZeros8",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			x := s.newValue1(ssa.OpZeroExt8to32, types.Types[TUINT32], args[0])
-			c := s.constInt32(types.Types[TUINT32], 1<<8)
-			y := s.newValue2(ssa.OpOr32, types.Types[TUINT32], x, c)
-			return s.newValue1(ssa.OpCtz32, types.Types[TINT], y)
-		},
-		sys.MIPS)
-	addF("math/bits", "TrailingZeros8",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpCtz8, types.Types[TINT], args[0])
-		},
-		sys.AMD64, sys.ARM, sys.ARM64, sys.Wasm)
-	addF("math/bits", "TrailingZeros8",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			x := s.newValue1(ssa.OpZeroExt8to64, types.Types[TUINT64], args[0])
-			c := s.constInt64(types.Types[TUINT64], 1<<8)
-			y := s.newValue2(ssa.OpOr64, types.Types[TUINT64], x, c)
-			return s.newValue1(ssa.OpCtz64, types.Types[TINT], y)
-		},
-		sys.S390X)
-	alias("math/bits", "ReverseBytes64", "runtime/internal/sys", "Bswap64", all...)
-	alias("math/bits", "ReverseBytes32", "runtime/internal/sys", "Bswap32", all...)
-	// ReverseBytes inlines correctly, no need to intrinsify it.
-	// ReverseBytes16 lowers to a rotate, no need for anything special here.
-	addF("math/bits", "Len64",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpBitLen64, types.Types[TINT], args[0])
-		},
-		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
-	addF("math/bits", "Len32",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpBitLen32, types.Types[TINT], args[0])
-		},
-		sys.AMD64, sys.ARM64)
-	addF("math/bits", "Len32",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			if s.config.PtrSize == 4 {
-				return s.newValue1(ssa.OpBitLen32, types.Types[TINT], args[0])
-			}
-			x := s.newValue1(ssa.OpZeroExt32to64, types.Types[TUINT64], args[0])
-			return s.newValue1(ssa.OpBitLen64, types.Types[TINT], x)
-		},
-		sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
-	addF("math/bits", "Len16",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			if s.config.PtrSize == 4 {
-				x := s.newValue1(ssa.OpZeroExt16to32, types.Types[TUINT32], args[0])
-				return s.newValue1(ssa.OpBitLen32, types.Types[TINT], x)
-			}
-			x := s.newValue1(ssa.OpZeroExt16to64, types.Types[TUINT64], args[0])
-			return s.newValue1(ssa.OpBitLen64, types.Types[TINT], x)
-		},
-		sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
-	addF("math/bits", "Len16",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpBitLen16, types.Types[TINT], args[0])
-		},
-		sys.AMD64)
-	addF("math/bits", "Len8",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			if s.config.PtrSize == 4 {
-				x := s.newValue1(ssa.OpZeroExt8to32, types.Types[TUINT32], args[0])
-				return s.newValue1(ssa.OpBitLen32, types.Types[TINT], x)
-			}
-			x := s.newValue1(ssa.OpZeroExt8to64, types.Types[TUINT64], args[0])
-			return s.newValue1(ssa.OpBitLen64, types.Types[TINT], x)
-		},
-		sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
-	addF("math/bits", "Len8",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpBitLen8, types.Types[TINT], args[0])
-		},
-		sys.AMD64)
-	addF("math/bits", "Len",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			if s.config.PtrSize == 4 {
-				return s.newValue1(ssa.OpBitLen32, types.Types[TINT], args[0])
-			}
-			return s.newValue1(ssa.OpBitLen64, types.Types[TINT], args[0])
-		},
-		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
-	// LeadingZeros is handled because it trivially calls Len.
-	addF("math/bits", "Reverse64",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpBitRev64, types.Types[TINT], args[0])
-		},
-		sys.ARM64)
-	addF("math/bits", "Reverse32",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpBitRev32, types.Types[TINT], args[0])
-		},
-		sys.ARM64)
-	addF("math/bits", "Reverse16",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpBitRev16, types.Types[TINT], args[0])
-		},
-		sys.ARM64)
-	addF("math/bits", "Reverse8",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpBitRev8, types.Types[TINT], args[0])
-		},
-		sys.ARM64)
-	addF("math/bits", "Reverse",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			if s.config.PtrSize == 4 {
-				return s.newValue1(ssa.OpBitRev32, types.Types[TINT], args[0])
-			}
-			return s.newValue1(ssa.OpBitRev64, types.Types[TINT], args[0])
-		},
-		sys.ARM64)
-	addF("math/bits", "RotateLeft8",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue2(ssa.OpRotateLeft8, types.Types[TUINT8], args[0], args[1])
-		},
-		sys.AMD64)
-	addF("math/bits", "RotateLeft16",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue2(ssa.OpRotateLeft16, types.Types[TUINT16], args[0], args[1])
-		},
-		sys.AMD64)
-	addF("math/bits", "RotateLeft32",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue2(ssa.OpRotateLeft32, types.Types[TUINT32], args[0], args[1])
-		},
-		sys.AMD64, sys.ARM, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
-	addF("math/bits", "RotateLeft64",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue2(ssa.OpRotateLeft64, types.Types[TUINT64], args[0], args[1])
-		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
-	alias("math/bits", "RotateLeft", "math/bits", "RotateLeft64", p8...)
-
-	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 {
-			v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[TBOOL], x86HasPOPCNT)
-			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 popcnt nowadays
-
-			// We have the intrinsic - use it directly.
-			s.startBlock(bTrue)
-			op := op64
-			if s.config.PtrSize == 4 {
-				op = op32
-			}
-			s.vars[n] = s.newValue1(op, types.Types[TINT], args[0])
-			s.endBlock().AddEdgeTo(bEnd)
-
-			// Call the pure Go version.
-			s.startBlock(bFalse)
-			s.vars[n] = s.callResult(n, callNormal) // types.Types[TINT]
-			s.endBlock().AddEdgeTo(bEnd)
-
-			// Merge results.
-			s.startBlock(bEnd)
-			return s.variable(n, types.Types[TINT])
-		}
-	}
-	addF("math/bits", "OnesCount64",
-		makeOnesCountAMD64(ssa.OpPopCount64, ssa.OpPopCount64),
-		sys.AMD64)
-	addF("math/bits", "OnesCount64",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpPopCount64, types.Types[TINT], args[0])
-		},
-		sys.PPC64, sys.ARM64, sys.S390X, sys.Wasm)
-	addF("math/bits", "OnesCount32",
-		makeOnesCountAMD64(ssa.OpPopCount32, ssa.OpPopCount32),
-		sys.AMD64)
-	addF("math/bits", "OnesCount32",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpPopCount32, types.Types[TINT], args[0])
-		},
-		sys.PPC64, sys.ARM64, sys.S390X, sys.Wasm)
-	addF("math/bits", "OnesCount16",
-		makeOnesCountAMD64(ssa.OpPopCount16, ssa.OpPopCount16),
-		sys.AMD64)
-	addF("math/bits", "OnesCount16",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpPopCount16, types.Types[TINT], args[0])
-		},
-		sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
-	addF("math/bits", "OnesCount8",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpPopCount8, types.Types[TINT], args[0])
-		},
-		sys.S390X, sys.PPC64, sys.Wasm)
-	addF("math/bits", "OnesCount",
-		makeOnesCountAMD64(ssa.OpPopCount64, ssa.OpPopCount32),
-		sys.AMD64)
-	addF("math/bits", "Mul64",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue2(ssa.OpMul64uhilo, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1])
-		},
-		sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X, sys.MIPS64)
-	alias("math/bits", "Mul", "math/bits", "Mul64", sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64, sys.ArchS390X, sys.ArchMIPS64, sys.ArchMIPS64LE)
-	addF("math/bits", "Add64",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue3(ssa.OpAdd64carry, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1], args[2])
-		},
-		sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X)
-	alias("math/bits", "Add", "math/bits", "Add64", sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64, sys.ArchS390X)
-	addF("math/bits", "Sub64",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue3(ssa.OpSub64borrow, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1], args[2])
-		},
-		sys.AMD64, sys.ARM64, sys.S390X)
-	alias("math/bits", "Sub", "math/bits", "Sub64", sys.ArchAMD64, sys.ArchARM64, sys.ArchS390X)
-	addF("math/bits", "Div64",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			// check for divide-by-zero/overflow and panic with appropriate message
-			cmpZero := s.newValue2(s.ssaOp(ONE, types.Types[TUINT64]), types.Types[TBOOL], args[2], s.zeroVal(types.Types[TUINT64]))
-			s.check(cmpZero, panicdivide)
-			cmpOverflow := s.newValue2(s.ssaOp(OLT, types.Types[TUINT64]), types.Types[TBOOL], args[0], args[2])
-			s.check(cmpOverflow, panicoverflow)
-			return s.newValue3(ssa.OpDiv128u, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1], args[2])
-		},
-		sys.AMD64)
-	alias("math/bits", "Div", "math/bits", "Div64", sys.ArchAMD64)
-
-	alias("runtime/internal/sys", "Ctz8", "math/bits", "TrailingZeros8", all...)
-	alias("runtime/internal/sys", "TrailingZeros8", "math/bits", "TrailingZeros8", all...)
-	alias("runtime/internal/sys", "TrailingZeros64", "math/bits", "TrailingZeros64", all...)
-	alias("runtime/internal/sys", "Len8", "math/bits", "Len8", all...)
-	alias("runtime/internal/sys", "Len64", "math/bits", "Len64", all...)
-	alias("runtime/internal/sys", "OnesCount64", "math/bits", "OnesCount64", all...)
-
-	/******** sync/atomic ********/
-
-	// Note: these are disabled by flag_race in findIntrinsic below.
-	alias("sync/atomic", "LoadInt32", "runtime/internal/atomic", "Load", all...)
-	alias("sync/atomic", "LoadInt64", "runtime/internal/atomic", "Load64", all...)
-	alias("sync/atomic", "LoadPointer", "runtime/internal/atomic", "Loadp", all...)
-	alias("sync/atomic", "LoadUint32", "runtime/internal/atomic", "Load", all...)
-	alias("sync/atomic", "LoadUint64", "runtime/internal/atomic", "Load64", all...)
-	alias("sync/atomic", "LoadUintptr", "runtime/internal/atomic", "Load", p4...)
-	alias("sync/atomic", "LoadUintptr", "runtime/internal/atomic", "Load64", p8...)
-
-	alias("sync/atomic", "StoreInt32", "runtime/internal/atomic", "Store", all...)
-	alias("sync/atomic", "StoreInt64", "runtime/internal/atomic", "Store64", all...)
-	// Note: not StorePointer, that needs a write barrier.  Same below for {CompareAnd}Swap.
-	alias("sync/atomic", "StoreUint32", "runtime/internal/atomic", "Store", all...)
-	alias("sync/atomic", "StoreUint64", "runtime/internal/atomic", "Store64", all...)
-	alias("sync/atomic", "StoreUintptr", "runtime/internal/atomic", "Store", p4...)
-	alias("sync/atomic", "StoreUintptr", "runtime/internal/atomic", "Store64", p8...)
-
-	alias("sync/atomic", "SwapInt32", "runtime/internal/atomic", "Xchg", all...)
-	alias("sync/atomic", "SwapInt64", "runtime/internal/atomic", "Xchg64", all...)
-	alias("sync/atomic", "SwapUint32", "runtime/internal/atomic", "Xchg", all...)
-	alias("sync/atomic", "SwapUint64", "runtime/internal/atomic", "Xchg64", all...)
-	alias("sync/atomic", "SwapUintptr", "runtime/internal/atomic", "Xchg", p4...)
-	alias("sync/atomic", "SwapUintptr", "runtime/internal/atomic", "Xchg64", p8...)
-
-	alias("sync/atomic", "CompareAndSwapInt32", "runtime/internal/atomic", "Cas", all...)
-	alias("sync/atomic", "CompareAndSwapInt64", "runtime/internal/atomic", "Cas64", all...)
-	alias("sync/atomic", "CompareAndSwapUint32", "runtime/internal/atomic", "Cas", all...)
-	alias("sync/atomic", "CompareAndSwapUint64", "runtime/internal/atomic", "Cas64", all...)
-	alias("sync/atomic", "CompareAndSwapUintptr", "runtime/internal/atomic", "Cas", p4...)
-	alias("sync/atomic", "CompareAndSwapUintptr", "runtime/internal/atomic", "Cas64", p8...)
-
-	alias("sync/atomic", "AddInt32", "runtime/internal/atomic", "Xadd", all...)
-	alias("sync/atomic", "AddInt64", "runtime/internal/atomic", "Xadd64", all...)
-	alias("sync/atomic", "AddUint32", "runtime/internal/atomic", "Xadd", all...)
-	alias("sync/atomic", "AddUint64", "runtime/internal/atomic", "Xadd64", all...)
-	alias("sync/atomic", "AddUintptr", "runtime/internal/atomic", "Xadd", p4...)
-	alias("sync/atomic", "AddUintptr", "runtime/internal/atomic", "Xadd64", p8...)
-
-	/******** math/big ********/
-	add("math/big", "mulWW",
-		func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-			return s.newValue2(ssa.OpMul64uhilo, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1])
-		},
-		sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64LE, sys.ArchPPC64, sys.ArchS390X)
-}
-
-// findIntrinsic returns a function which builds the SSA equivalent of the
-// function identified by the symbol sym.  If sym is not an intrinsic call, returns nil.
-func findIntrinsic(sym *types.Sym) intrinsicBuilder {
-	if sym == nil || sym.Pkg == nil {
-		return nil
-	}
-	pkg := sym.Pkg.Path
-	if sym.Pkg == localpkg {
-		pkg = myimportpath
-	}
-	if flag_race && pkg == "sync/atomic" {
-		// The race detector needs to be able to intercept these calls.
-		// 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
-	if ssa.IntrinsicsDisable {
-		if pkg == "runtime" && (fn == "getcallerpc" || fn == "getcallersp" || fn == "getclosureptr") {
-			// These runtime functions don't have definitions, must be intrinsics.
-		} else {
-			return nil
-		}
-	}
-	return intrinsics[intrinsicKey{thearch.LinkArch.Arch, pkg, fn}]
-}
-
-func isIntrinsicCall(n *Node) bool {
-	if n == nil || n.Left == nil {
-		return false
-	}
-	return findIntrinsic(n.Left.Sym) != nil
-}
-
-// intrinsicCall converts a call to a recognized intrinsic function into the intrinsic SSA operation.
-func (s *state) intrinsicCall(n *Node) *ssa.Value {
-	v := findIntrinsic(n.Left.Sym)(s, n, s.intrinsicArgs(n))
-	if ssa.IntrinsicsDebug > 0 {
-		x := v
-		if x == nil {
-			x = s.mem()
-		}
-		if x.Op == ssa.OpSelect0 || x.Op == ssa.OpSelect1 {
-			x = x.Args[0]
-		}
-		Warnl(n.Pos, "intrinsic substitution for %v with %s", n.Left.Sym.Name, x.LongString())
-	}
-	return v
-}
-
-// intrinsicArgs extracts args from n, evaluates them to SSA values, and returns them.
-func (s *state) intrinsicArgs(n *Node) []*ssa.Value {
-	// Construct map of temps; see comments in s.call about the structure of n.
-	temps := map[*Node]*ssa.Value{}
-	for _, a := range n.List.Slice() {
-		if a.Op != OAS {
-			s.Fatalf("non-assignment as a temp function argument %v", a.Op)
-		}
-		l, r := a.Left, a.Right
-		if l.Op != ONAME {
-			s.Fatalf("non-ONAME temp function argument %v", a.Op)
-		}
-		// Evaluate and store to "temporary".
-		// Walk ensures these temporaries are dead outside of n.
-		temps[l] = s.expr(r)
-	}
-	args := make([]*ssa.Value, n.Rlist.Len())
-	for i, n := range n.Rlist.Slice() {
-		// Store a value to an argument slot.
-		if x, ok := temps[n]; ok {
-			// This is a previously computed temporary.
-			args[i] = x
-			continue
-		}
-		// This is an explicit value; evaluate it.
-		args[i] = s.expr(n)
-	}
-	return args
-}
-
-// openDeferRecord adds code to evaluate and store the args for an open-code defer
-// call, and records info about the defer, so we can generate proper code on the
-// exit paths. n is the sub-node of the defer node that is the actual function
-// call. We will also record funcdata information on where the args are stored
-// (as well as the deferBits variable), and this will enable us to run the proper
-// defer calls during panics.
-func (s *state) openDeferRecord(n *Node) {
-	// Do any needed expression evaluation for the args (including the
-	// receiver, if any). This may be evaluating something like 'autotmp_3 =
-	// once.mutex'. Such a statement will create a mapping in s.vars[] from
-	// the autotmp name to the evaluated SSA arg value, but won't do any
-	// stores to the stack.
-	s.stmtList(n.List)
-
-	var args []*ssa.Value
-	var argNodes []*Node
-
-	opendefer := &openDeferInfo{
-		n: n,
-	}
-	fn := n.Left
-	if n.Op == OCALLFUNC {
-		// We must always store the function value in a stack slot for the
-		// runtime panic code to use. But in the defer exit code, we will
-		// call the function directly if it is a static function.
-		closureVal := s.expr(fn)
-		closure := s.openDeferSave(nil, fn.Type, closureVal)
-		opendefer.closureNode = closure.Aux.(*Node)
-		if !(fn.Op == ONAME && fn.Class() == PFUNC) {
-			opendefer.closure = closure
-		}
-	} else if n.Op == OCALLMETH {
-		if fn.Op != ODOTMETH {
-			Fatalf("OCALLMETH: n.Left not an ODOTMETH: %v", fn)
-		}
-		closureVal := s.getMethodClosure(fn)
-		// We must always store the function value in a stack slot for the
-		// runtime panic code to use. But in the defer exit code, we will
-		// call the method directly.
-		closure := s.openDeferSave(nil, fn.Type, closureVal)
-		opendefer.closureNode = closure.Aux.(*Node)
-	} else {
-		if fn.Op != ODOTINTER {
-			Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op)
-		}
-		closure, rcvr := s.getClosureAndRcvr(fn)
-		opendefer.closure = s.openDeferSave(nil, closure.Type, closure)
-		// Important to get the receiver type correct, so it is recognized
-		// as a pointer for GC purposes.
-		opendefer.rcvr = s.openDeferSave(nil, fn.Type.Recv().Type, rcvr)
-		opendefer.closureNode = opendefer.closure.Aux.(*Node)
-		opendefer.rcvrNode = opendefer.rcvr.Aux.(*Node)
-	}
-	for _, argn := range n.Rlist.Slice() {
-		var v *ssa.Value
-		if canSSAType(argn.Type) {
-			v = s.openDeferSave(nil, argn.Type, s.expr(argn))
-		} else {
-			v = s.openDeferSave(argn, argn.Type, nil)
-		}
-		args = append(args, v)
-		argNodes = append(argNodes, v.Aux.(*Node))
-	}
-	opendefer.argVals = args
-	opendefer.argNodes = argNodes
-	index := len(s.openDefers)
-	s.openDefers = append(s.openDefers, opendefer)
-
-	// Update deferBits only after evaluation and storage to stack of
-	// args/receiver/interface is successful.
-	bitvalue := s.constInt8(types.Types[TUINT8], 1<<uint(index))
-	newDeferBits := s.newValue2(ssa.OpOr8, types.Types[TUINT8], s.variable(&deferBitsVar, types.Types[TUINT8]), bitvalue)
-	s.vars[&deferBitsVar] = newDeferBits
-	s.store(types.Types[TUINT8], s.deferBitsAddr, newDeferBits)
-}
-
-// openDeferSave generates SSA nodes to store a value (with type t) for an
-// open-coded defer at an explicit autotmp location on the stack, so it can be
-// reloaded and used for the appropriate call on exit. If type t is SSAable, then
-// val must be non-nil (and n should be nil) and val is the value to be stored. If
-// type t is non-SSAable, then n must be non-nil (and val should be nil) and n is
-// evaluated (via s.addr() below) to get the value that is to be stored. The
-// function returns an SSA value representing a pointer to the autotmp location.
-func (s *state) openDeferSave(n *Node, t *types.Type, val *ssa.Value) *ssa.Value {
-	canSSA := canSSAType(t)
-	var pos src.XPos
-	if canSSA {
-		pos = val.Pos
-	} else {
-		pos = n.Pos
-	}
-	argTemp := tempAt(pos.WithNotStmt(), s.curfn, t)
-	argTemp.Name.SetOpenDeferSlot(true)
-	var addrArgTemp *ssa.Value
-	// Use OpVarLive to make sure stack slots for the args, etc. are not
-	// removed by dead-store elimination
-	if s.curBlock.ID != s.f.Entry.ID {
-		// Force the argtmp storing this defer function/receiver/arg to be
-		// declared in the entry block, so that it will be live for the
-		// defer exit code (which will actually access it only if the
-		// associated defer call has been activated).
-		s.defvars[s.f.Entry.ID][&memVar] = s.entryNewValue1A(ssa.OpVarDef, types.TypeMem, argTemp, s.defvars[s.f.Entry.ID][&memVar])
-		s.defvars[s.f.Entry.ID][&memVar] = s.entryNewValue1A(ssa.OpVarLive, types.TypeMem, argTemp, s.defvars[s.f.Entry.ID][&memVar])
-		addrArgTemp = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(argTemp.Type), argTemp, s.sp, s.defvars[s.f.Entry.ID][&memVar])
-	} else {
-		// Special case if we're still in the entry block. We can't use
-		// the above code, since s.defvars[s.f.Entry.ID] isn't defined
-		// until we end the entry block with s.endBlock().
-		s.vars[&memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, argTemp, s.mem(), false)
-		s.vars[&memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, argTemp, s.mem(), false)
-		addrArgTemp = s.newValue2Apos(ssa.OpLocalAddr, types.NewPtr(argTemp.Type), argTemp, s.sp, s.mem(), false)
-	}
-	if t.HasPointers() {
-		// Since we may use this argTemp during exit depending on the
-		// deferBits, we must define it unconditionally on entry.
-		// Therefore, we must make sure it is zeroed out in the entry
-		// block if it contains pointers, else GC may wrongly follow an
-		// uninitialized pointer value.
-		argTemp.Name.SetNeedzero(true)
-	}
-	if !canSSA {
-		a := s.addr(n)
-		s.move(t, addrArgTemp, a)
-		return addrArgTemp
-	}
-	// We are storing to the stack, hence we can avoid the full checks in
-	// storeType() (no write barrier) and do a simple store().
-	s.store(t, addrArgTemp, val)
-	return addrArgTemp
-}
-
-// openDeferExit generates SSA for processing all the open coded defers at exit.
-// The code involves loading deferBits, and checking each of the bits to see if
-// the corresponding defer statement was executed. For each bit that is turned
-// on, the associated defer call is made.
-func (s *state) openDeferExit() {
-	deferExit := s.f.NewBlock(ssa.BlockPlain)
-	s.endBlock().AddEdgeTo(deferExit)
-	s.startBlock(deferExit)
-	s.lastDeferExit = deferExit
-	s.lastDeferCount = len(s.openDefers)
-	zeroval := s.constInt8(types.Types[TUINT8], 0)
-	testLateExpansion := ssa.LateCallExpansionEnabledWithin(s.f)
-	// Test for and run defers in reverse order
-	for i := len(s.openDefers) - 1; i >= 0; i-- {
-		r := s.openDefers[i]
-		bCond := s.f.NewBlock(ssa.BlockPlain)
-		bEnd := s.f.NewBlock(ssa.BlockPlain)
-
-		deferBits := s.variable(&deferBitsVar, types.Types[TUINT8])
-		// Generate code to check if the bit associated with the current
-		// defer is set.
-		bitval := s.constInt8(types.Types[TUINT8], 1<<uint(i))
-		andval := s.newValue2(ssa.OpAnd8, types.Types[TUINT8], deferBits, bitval)
-		eqVal := s.newValue2(ssa.OpEq8, types.Types[TBOOL], andval, zeroval)
-		b := s.endBlock()
-		b.Kind = ssa.BlockIf
-		b.SetControl(eqVal)
-		b.AddEdgeTo(bEnd)
-		b.AddEdgeTo(bCond)
-		bCond.AddEdgeTo(bEnd)
-		s.startBlock(bCond)
-
-		// Clear this bit in deferBits and force store back to stack, so
-		// we will not try to re-run this defer call if this defer call panics.
-		nbitval := s.newValue1(ssa.OpCom8, types.Types[TUINT8], bitval)
-		maskedval := s.newValue2(ssa.OpAnd8, types.Types[TUINT8], deferBits, nbitval)
-		s.store(types.Types[TUINT8], s.deferBitsAddr, maskedval)
-		// Use this value for following tests, so we keep previous
-		// bits cleared.
-		s.vars[&deferBitsVar] = maskedval
-
-		// Generate code to call the function call of the defer, using the
-		// closure/receiver/args that were stored in argtmps at the point
-		// of the defer statement.
-		argStart := Ctxt.FixedFrameSize()
-		fn := r.n.Left
-		stksize := fn.Type.ArgWidth()
-		var ACArgs []ssa.Param
-		var ACResults []ssa.Param
-		var callArgs []*ssa.Value
-		if r.rcvr != nil {
-			// rcvr in case of OCALLINTER
-			v := s.load(r.rcvr.Type.Elem(), r.rcvr)
-			addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart)
-			ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(argStart)})
-			if testLateExpansion {
-				callArgs = append(callArgs, v)
-			} else {
-				s.store(types.Types[TUINTPTR], addr, v)
-			}
-		}
-		for j, argAddrVal := range r.argVals {
-			f := getParam(r.n, j)
-			pt := types.NewPtr(f.Type)
-			ACArgs = append(ACArgs, ssa.Param{Type: f.Type, Offset: int32(argStart + f.Offset)})
-			if testLateExpansion {
-				var a *ssa.Value
-				if !canSSAType(f.Type) {
-					a = s.newValue2(ssa.OpDereference, f.Type, argAddrVal, s.mem())
-				} else {
-					a = s.load(f.Type, argAddrVal)
-				}
-				callArgs = append(callArgs, a)
-			} else {
-				addr := s.constOffPtrSP(pt, argStart+f.Offset)
-				if !canSSAType(f.Type) {
-					s.move(f.Type, addr, argAddrVal)
-				} else {
-					argVal := s.load(f.Type, argAddrVal)
-					s.storeType(f.Type, addr, argVal, 0, false)
-				}
-			}
-		}
-		var call *ssa.Value
-		if r.closure != nil {
-			v := s.load(r.closure.Type.Elem(), r.closure)
-			s.maybeNilCheckClosure(v, callDefer)
-			codeptr := s.rawLoad(types.Types[TUINTPTR], v)
-			aux := ssa.ClosureAuxCall(ACArgs, ACResults)
-			if testLateExpansion {
-				callArgs = append(callArgs, s.mem())
-				call = s.newValue2A(ssa.OpClosureLECall, aux.LateExpansionResultType(), aux, codeptr, v)
-				call.AddArgs(callArgs...)
-			} else {
-				call = s.newValue3A(ssa.OpClosureCall, types.TypeMem, aux, codeptr, v, s.mem())
-			}
-		} else {
-			aux := ssa.StaticAuxCall(fn.Sym.Linksym(), ACArgs, ACResults)
-			if testLateExpansion {
-				callArgs = append(callArgs, s.mem())
-				call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
-				call.AddArgs(callArgs...)
-			} else {
-				// Do a static call if the original call was a static function or method
-				call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
-			}
-		}
-		call.AuxInt = stksize
-		if testLateExpansion {
-			s.vars[&memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call)
-		} else {
-			s.vars[&memVar] = call
-		}
-		// Make sure that the stack slots with pointers are kept live
-		// through the call (which is a pre-emption point). Also, we will
-		// use the first call of the last defer exit to compute liveness
-		// for the deferreturn, so we want all stack slots to be live.
-		if r.closureNode != nil {
-			s.vars[&memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, r.closureNode, s.mem(), false)
-		}
-		if r.rcvrNode != nil {
-			if r.rcvrNode.Type.HasPointers() {
-				s.vars[&memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, r.rcvrNode, s.mem(), false)
-			}
-		}
-		for _, argNode := range r.argNodes {
-			if argNode.Type.HasPointers() {
-				s.vars[&memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, argNode, s.mem(), false)
-			}
-		}
-
-		s.endBlock()
-		s.startBlock(bEnd)
-	}
-}
-
-func (s *state) callResult(n *Node, k callKind) *ssa.Value {
-	return s.call(n, k, false)
-}
-
-func (s *state) callAddr(n *Node, k callKind) *ssa.Value {
-	return s.call(n, k, true)
-}
-
-// Calls the function n using the specified call type.
-// Returns the address of the return value (or nil if none).
-func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
-	s.prevCall = nil
-	var sym *types.Sym     // target symbol (if static)
-	var closure *ssa.Value // ptr to closure to run (if dynamic)
-	var codeptr *ssa.Value // ptr to target code (if dynamic)
-	var rcvr *ssa.Value    // receiver to set
-	fn := n.Left
-	var ACArgs []ssa.Param
-	var ACResults []ssa.Param
-	var callArgs []*ssa.Value
-	res := n.Left.Type.Results()
-	if k == callNormal {
-		nf := res.NumFields()
-		for i := 0; i < nf; i++ {
-			fp := res.Field(i)
-			ACResults = append(ACResults, ssa.Param{Type: fp.Type, Offset: int32(fp.Offset + Ctxt.FixedFrameSize())})
-		}
-	}
-
-	testLateExpansion := false
-
-	switch n.Op {
-	case OCALLFUNC:
-		testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f)
-		if k == callNormal && fn.Op == ONAME && fn.Class() == PFUNC {
-			sym = fn.Sym
-			break
-		}
-		closure = s.expr(fn)
-		if k != callDefer && k != callDeferStack {
-			// Deferred nil function needs to panic when the function is invoked,
-			// not the point of defer statement.
-			s.maybeNilCheckClosure(closure, k)
-		}
-	case OCALLMETH:
-		if fn.Op != ODOTMETH {
-			s.Fatalf("OCALLMETH: n.Left not an ODOTMETH: %v", fn)
-		}
-		testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f)
-		if k == callNormal {
-			sym = fn.Sym
-			break
-		}
-		closure = s.getMethodClosure(fn)
-		// Note: receiver is already present in n.Rlist, so we don't
-		// want to set it here.
-	case OCALLINTER:
-		if fn.Op != ODOTINTER {
-			s.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op)
-		}
-		testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f)
-		var iclosure *ssa.Value
-		iclosure, rcvr = s.getClosureAndRcvr(fn)
-		if k == callNormal {
-			codeptr = s.load(types.Types[TUINTPTR], iclosure)
-		} else {
-			closure = iclosure
-		}
-	}
-	dowidth(fn.Type)
-	stksize := fn.Type.ArgWidth() // includes receiver, args, and results
-
-	// Run all assignments of temps.
-	// The temps are introduced to avoid overwriting argument
-	// slots when arguments themselves require function calls.
-	s.stmtList(n.List)
-
-	var call *ssa.Value
-	if k == callDeferStack {
-		testLateExpansion = ssa.LateCallExpansionEnabledWithin(s.f)
-		// Make a defer struct d on the stack.
-		t := deferstruct(stksize)
-		d := tempAt(n.Pos, s.curfn, t)
-
-		s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, d, s.mem())
-		addr := s.addr(d)
-
-		// Must match reflect.go:deferstruct and src/runtime/runtime2.go:_defer.
-		// 0: siz
-		s.store(types.Types[TUINT32],
-			s.newValue1I(ssa.OpOffPtr, types.Types[TUINT32].PtrTo(), t.FieldOff(0), addr),
-			s.constInt32(types.Types[TUINT32], int32(stksize)))
-		// 1: started, set in deferprocStack
-		// 2: heap, set in deferprocStack
-		// 3: openDefer
-		// 4: sp, set in deferprocStack
-		// 5: pc, set in deferprocStack
-		// 6: fn
-		s.store(closure.Type,
-			s.newValue1I(ssa.OpOffPtr, closure.Type.PtrTo(), t.FieldOff(6), addr),
-			closure)
-		// 7: panic, set in deferprocStack
-		// 8: link, set in deferprocStack
-		// 9: framepc
-		// 10: varp
-		// 11: fd
-
-		// Then, store all the arguments of the defer call.
-		ft := fn.Type
-		off := t.FieldOff(12)
-		args := n.Rlist.Slice()
-
-		// Set receiver (for interface calls). Always a pointer.
-		if rcvr != nil {
-			p := s.newValue1I(ssa.OpOffPtr, ft.Recv().Type.PtrTo(), off, addr)
-			s.store(types.Types[TUINTPTR], p, rcvr)
-		}
-		// Set receiver (for method calls).
-		if n.Op == OCALLMETH {
-			f := ft.Recv()
-			s.storeArgWithBase(args[0], f.Type, addr, off+f.Offset)
-			args = args[1:]
-		}
-		// Set other args.
-		for _, f := range ft.Params().Fields().Slice() {
-			s.storeArgWithBase(args[0], f.Type, addr, off+f.Offset)
-			args = args[1:]
-		}
-
-		// Call runtime.deferprocStack with pointer to _defer record.
-		ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(Ctxt.FixedFrameSize())})
-		aux := ssa.StaticAuxCall(deferprocStack, ACArgs, ACResults)
-		if testLateExpansion {
-			callArgs = append(callArgs, addr, s.mem())
-			call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
-			call.AddArgs(callArgs...)
-		} else {
-			arg0 := s.constOffPtrSP(types.Types[TUINTPTR], Ctxt.FixedFrameSize())
-			s.store(types.Types[TUINTPTR], arg0, addr)
-			call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
-		}
-		if stksize < int64(Widthptr) {
-			// We need room for both the call to deferprocStack and the call to
-			// the deferred function.
-			// TODO Revisit this if/when we pass args in registers.
-			stksize = int64(Widthptr)
-		}
-		call.AuxInt = stksize
-	} else {
-		// Store arguments to stack, including defer/go arguments and receiver for method calls.
-		// These are written in SP-offset order.
-		argStart := Ctxt.FixedFrameSize()
-		// Defer/go args.
-		if k != callNormal {
-			// Write argsize and closure (args to newproc/deferproc).
-			argsize := s.constInt32(types.Types[TUINT32], int32(stksize))
-			ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINT32], Offset: int32(argStart)})
-			if testLateExpansion {
-				callArgs = append(callArgs, argsize)
-			} else {
-				addr := s.constOffPtrSP(s.f.Config.Types.UInt32Ptr, argStart)
-				s.store(types.Types[TUINT32], addr, argsize)
-			}
-			ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(argStart) + int32(Widthptr)})
-			if testLateExpansion {
-				callArgs = append(callArgs, closure)
-			} else {
-				addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart+int64(Widthptr))
-				s.store(types.Types[TUINTPTR], addr, closure)
-			}
-			stksize += 2 * int64(Widthptr)
-			argStart += 2 * int64(Widthptr)
-		}
-
-		// Set receiver (for interface calls).
-		if rcvr != nil {
-			addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart)
-			ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(argStart)})
-			if testLateExpansion {
-				callArgs = append(callArgs, rcvr)
-			} else {
-				s.store(types.Types[TUINTPTR], addr, rcvr)
-			}
-		}
-
-		// Write args.
-		t := n.Left.Type
-		args := n.Rlist.Slice()
-		if n.Op == OCALLMETH {
-			f := t.Recv()
-			ACArg, arg := s.putArg(args[0], f.Type, argStart+f.Offset, testLateExpansion)
-			ACArgs = append(ACArgs, ACArg)
-			callArgs = append(callArgs, arg)
-			args = args[1:]
-		}
-		for i, n := range args {
-			f := t.Params().Field(i)
-			ACArg, arg := s.putArg(n, f.Type, argStart+f.Offset, testLateExpansion)
-			ACArgs = append(ACArgs, ACArg)
-			callArgs = append(callArgs, arg)
-		}
-
-		callArgs = append(callArgs, s.mem())
-
-		// call target
-		switch {
-		case k == callDefer:
-			aux := ssa.StaticAuxCall(deferproc, ACArgs, ACResults)
-			if testLateExpansion {
-				call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
-				call.AddArgs(callArgs...)
-			} else {
-				call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
-			}
-		case k == callGo:
-			aux := ssa.StaticAuxCall(newproc, ACArgs, ACResults)
-			if testLateExpansion {
-				call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
-				call.AddArgs(callArgs...)
-			} else {
-				call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
-			}
-		case closure != nil:
-			// rawLoad because loading the code pointer from a
-			// closure is always safe, but IsSanitizerSafeAddr
-			// can't always figure that out currently, and it's
-			// critical that we not clobber any arguments already
-			// stored onto the stack.
-			codeptr = s.rawLoad(types.Types[TUINTPTR], closure)
-			if testLateExpansion {
-				aux := ssa.ClosureAuxCall(ACArgs, ACResults)
-				call = s.newValue2A(ssa.OpClosureLECall, aux.LateExpansionResultType(), aux, codeptr, closure)
-				call.AddArgs(callArgs...)
-			} else {
-				call = s.newValue3A(ssa.OpClosureCall, types.TypeMem, ssa.ClosureAuxCall(ACArgs, ACResults), codeptr, closure, s.mem())
-			}
-		case codeptr != nil:
-			if testLateExpansion {
-				aux := ssa.InterfaceAuxCall(ACArgs, ACResults)
-				call = s.newValue1A(ssa.OpInterLECall, aux.LateExpansionResultType(), aux, codeptr)
-				call.AddArgs(callArgs...)
-			} else {
-				call = s.newValue2A(ssa.OpInterCall, types.TypeMem, ssa.InterfaceAuxCall(ACArgs, ACResults), codeptr, s.mem())
-			}
-		case sym != nil:
-			if testLateExpansion {
-				aux := ssa.StaticAuxCall(sym.Linksym(), ACArgs, ACResults)
-				call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
-				call.AddArgs(callArgs...)
-			} else {
-				call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, ssa.StaticAuxCall(sym.Linksym(), ACArgs, ACResults), s.mem())
-			}
-		default:
-			s.Fatalf("bad call type %v %v", n.Op, n)
-		}
-		call.AuxInt = stksize // Call operations carry the argsize of the callee along with them
-	}
-	if testLateExpansion {
-		s.prevCall = call
-		s.vars[&memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call)
-	} else {
-		s.vars[&memVar] = call
-	}
-	// Insert OVARLIVE nodes
-	s.stmtList(n.Nbody)
-
-	// Finish block for defers
-	if k == callDefer || k == callDeferStack {
-		b := s.endBlock()
-		b.Kind = ssa.BlockDefer
-		b.SetControl(call)
-		bNext := s.f.NewBlock(ssa.BlockPlain)
-		b.AddEdgeTo(bNext)
-		// Add recover edge to exit code.
-		r := s.f.NewBlock(ssa.BlockPlain)
-		s.startBlock(r)
-		s.exit()
-		b.AddEdgeTo(r)
-		b.Likely = ssa.BranchLikely
-		s.startBlock(bNext)
-	}
-
-	if res.NumFields() == 0 || k != callNormal {
-		// call has no return value. Continue with the next statement.
-		return nil
-	}
-	fp := res.Field(0)
-	if returnResultAddr {
-		pt := types.NewPtr(fp.Type)
-		if testLateExpansion {
-			return s.newValue1I(ssa.OpSelectNAddr, pt, 0, call)
-		}
-		return s.constOffPtrSP(pt, fp.Offset+Ctxt.FixedFrameSize())
-	}
-
-	if testLateExpansion {
-		return s.newValue1I(ssa.OpSelectN, fp.Type, 0, call)
-	}
-	return s.load(n.Type, s.constOffPtrSP(types.NewPtr(fp.Type), fp.Offset+Ctxt.FixedFrameSize()))
-}
-
-// maybeNilCheckClosure checks if a nil check of a closure is needed in some
-// architecture-dependent situations and, if so, emits the nil check.
-func (s *state) maybeNilCheckClosure(closure *ssa.Value, k callKind) {
-	if thearch.LinkArch.Family == sys.Wasm || objabi.GOOS == "aix" && k != callGo {
-		// On AIX, the closure needs to be verified as fn can be nil, except if it's a call go. This needs to be handled by the runtime to have the "go of nil func value" error.
-		// TODO(neelance): On other architectures this should be eliminated by the optimization steps
-		s.nilCheck(closure)
-	}
-}
-
-// getMethodClosure returns a value representing the closure for a method call
-func (s *state) getMethodClosure(fn *Node) *ssa.Value {
-	// Make a name n2 for the function.
-	// fn.Sym might be sync.(*Mutex).Unlock.
-	// Make a PFUNC node out of that, then evaluate it.
-	// We get back an SSA value representing &sync.(*Mutex).Unlock·f.
-	// We can then pass that to defer or go.
-	n2 := newnamel(fn.Pos, fn.Sym)
-	n2.Name.Curfn = s.curfn
-	n2.SetClass(PFUNC)
-	// n2.Sym already existed, so it's already marked as a function.
-	n2.Pos = fn.Pos
-	n2.Type = types.Types[TUINT8] // dummy type for a static closure. Could use runtime.funcval if we had it.
-	return s.expr(n2)
-}
-
-// getClosureAndRcvr returns values for the appropriate closure and receiver of an
-// interface call
-func (s *state) getClosureAndRcvr(fn *Node) (*ssa.Value, *ssa.Value) {
-	i := s.expr(fn.Left)
-	itab := s.newValue1(ssa.OpITab, types.Types[TUINTPTR], i)
-	s.nilCheck(itab)
-	itabidx := fn.Xoffset + 2*int64(Widthptr) + 8 // offset of fun field in runtime.itab
-	closure := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.UintptrPtr, itabidx, itab)
-	rcvr := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, i)
-	return closure, rcvr
-}
-
-// etypesign returns the signed-ness of e, for integer/pointer etypes.
-// -1 means signed, +1 means unsigned, 0 means non-integer/non-pointer.
-func etypesign(e types.EType) int8 {
-	switch e {
-	case TINT8, TINT16, TINT32, TINT64, TINT:
-		return -1
-	case TUINT8, TUINT16, TUINT32, TUINT64, TUINT, TUINTPTR, TUNSAFEPTR:
-		return +1
-	}
-	return 0
-}
-
-// 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.
-func (s *state) addr(n *Node) *ssa.Value {
-	if n.Op != ONAME {
-		s.pushLine(n.Pos)
-		defer s.popLine()
-	}
-
-	t := types.NewPtr(n.Type)
-	switch n.Op {
-	case ONAME:
-		switch n.Class() {
-		case PEXTERN:
-			// global variable
-			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)
-			}
-			return v
-		case PPARAM:
-			// parameter slot
-			v := s.decladdrs[n]
-			if v != nil {
-				return v
-			}
-			if n == nodfp {
-				// Special arg that points to the frame pointer (Used by ORECOVER).
-				return s.entryNewValue2A(ssa.OpLocalAddr, t, n, s.sp, s.startmem)
-			}
-			s.Fatalf("addr of undeclared ONAME %v. declared: %v", n, s.decladdrs)
-			return nil
-		case PAUTO:
-			return s.newValue2Apos(ssa.OpLocalAddr, t, n, s.sp, s.mem(), !n.IsAutoTmp())
-
-		case PPARAMOUT: // Same as PAUTO -- cannot generate LEA early.
-			// ensure that we reuse symbols for out parameters so
-			// that cse works on their addresses
-			return s.newValue2Apos(ssa.OpLocalAddr, t, n, s.sp, s.mem(), true)
-		default:
-			s.Fatalf("variable address class %v not implemented", n.Class())
-			return nil
-		}
-	case ORESULT:
-		// load return from callee
-		if s.prevCall == nil || s.prevCall.Op != ssa.OpStaticLECall && s.prevCall.Op != ssa.OpInterLECall && s.prevCall.Op != ssa.OpClosureLECall {
-			return s.constOffPtrSP(t, n.Xoffset)
-		}
-		which := s.prevCall.Aux.(*ssa.AuxCall).ResultForOffset(n.Xoffset)
-		if which == -1 {
-			// Do the old thing // TODO: Panic instead.
-			return s.constOffPtrSP(t, n.Xoffset)
-		}
-		x := s.newValue1I(ssa.OpSelectNAddr, t, which, s.prevCall)
-		return x
-
-	case OINDEX:
-		if n.Left.Type.IsSlice() {
-			a := s.expr(n.Left)
-			i := s.expr(n.Right)
-			len := s.newValue1(ssa.OpSliceLen, types.Types[TINT], a)
-			i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
-			p := s.newValue1(ssa.OpSlicePtr, t, a)
-			return s.newValue2(ssa.OpPtrIndex, t, p, i)
-		} else { // array
-			a := s.addr(n.Left)
-			i := s.expr(n.Right)
-			len := s.constInt(types.Types[TINT], n.Left.Type.NumElem())
-			i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
-			return s.newValue2(ssa.OpPtrIndex, types.NewPtr(n.Left.Type.Elem()), a, i)
-		}
-	case ODEREF:
-		return s.exprPtr(n.Left, n.Bounded(), n.Pos)
-	case ODOT:
-		p := s.addr(n.Left)
-		return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset, p)
-	case ODOTPTR:
-		p := s.exprPtr(n.Left, n.Bounded(), n.Pos)
-		return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset, p)
-	case OCLOSUREVAR:
-		return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset,
-			s.entryNewValue0(ssa.OpGetClosurePtr, s.f.Config.Types.BytePtr))
-	case OCONVNOP:
-		addr := s.addr(n.Left)
-		return s.newValue1(ssa.OpCopy, t, addr) // ensure that addr has the right type
-	case OCALLFUNC, OCALLINTER, OCALLMETH:
-		return s.callAddr(n, callNormal)
-	case ODOTTYPE:
-		v, _ := s.dottype(n, false)
-		if v.Op != ssa.OpLoad {
-			s.Fatalf("dottype of non-load")
-		}
-		if v.Args[1] != s.mem() {
-			s.Fatalf("memory no longer live from dottype load")
-		}
-		return v.Args[0]
-	default:
-		s.Fatalf("unhandled addr %v", n.Op)
-		return nil
-	}
-}
-
-// canSSA reports whether n is SSA-able.
-// n must be an ONAME (or an ODOT sequence with an ONAME base).
-func (s *state) canSSA(n *Node) bool {
-	if Debug.N != 0 {
-		return false
-	}
-	for n.Op == ODOT || (n.Op == OINDEX && n.Left.Type.IsArray()) {
-		n = n.Left
-	}
-	if n.Op != ONAME {
-		return false
-	}
-	if n.Name.Addrtaken() {
-		return false
-	}
-	if n.isParamHeapCopy() {
-		return false
-	}
-	if n.Class() == PAUTOHEAP {
-		s.Fatalf("canSSA of PAUTOHEAP %v", n)
-	}
-	switch n.Class() {
-	case PEXTERN:
-		return false
-	case PPARAMOUT:
-		if s.hasdefer {
-			// 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
-			// must be written back so if a defer recovers, the caller can see them.
-			return false
-		}
-		if s.cgoUnsafeArgs {
-			// Cgo effectively takes the address of all result args,
-			// but the compiler can't see that.
-			return false
-		}
-	}
-	if n.Class() == PPARAM && n.Sym != nil && n.Sym.Name == ".this" {
-		// wrappers generated by genwrapper need to update
-		// the .this pointer in place.
-		// TODO: treat as a PPARAMOUT?
-		return false
-	}
-	return canSSAType(n.Type)
-	// TODO: try to make more variables SSAable?
-}
-
-// canSSA reports whether variables of type t are SSA-able.
-func canSSAType(t *types.Type) bool {
-	dowidth(t)
-	if t.Width > int64(4*Widthptr) {
-		// 4*Widthptr is an arbitrary constant. We want it
-		// to be at least 3*Widthptr so slices can be registerized.
-		// Too big and we'll introduce too much register pressure.
-		return false
-	}
-	switch t.Etype {
-	case TARRAY:
-		// We can't do larger arrays because dynamic indexing is
-		// not supported on SSA variables.
-		// TODO: allow if all indexes are constant.
-		if t.NumElem() <= 1 {
-			return canSSAType(t.Elem())
-		}
-		return false
-	case TSTRUCT:
-		if t.NumFields() > ssa.MaxStruct {
-			return false
-		}
-		for _, t1 := range t.Fields().Slice() {
-			if !canSSAType(t1.Type) {
-				return false
-			}
-		}
-		return true
-	default:
-		return true
-	}
-}
-
-// exprPtr evaluates n to a pointer and nil-checks it.
-func (s *state) exprPtr(n *Node, bounded bool, lineno src.XPos) *ssa.Value {
-	p := s.expr(n)
-	if bounded || n.NonNil() {
-		if s.f.Frontend().Debug_checknil() && lineno.Line() > 1 {
-			s.f.Warnl(lineno, "removed nil check")
-		}
-		return p
-	}
-	s.nilCheck(p)
-	return p
-}
-
-// nilCheck generates nil pointer checking code.
-// Used only for automatically inserted nil checks,
-// not for user code like 'x != nil'.
-func (s *state) nilCheck(ptr *ssa.Value) {
-	if disable_checknil != 0 || s.curfn.Func.NilCheckDisabled() {
-		return
-	}
-	s.newValue2(ssa.OpNilCheck, types.TypeVoid, ptr, s.mem())
-}
-
-// boundsCheck generates bounds checking code. Checks if 0 <= idx <[=] len, branches to exit if not.
-// Starts a new block on return.
-// On input, len must be converted to full int width and be nonnegative.
-// Returns idx converted to full int width.
-// If bounded is true then caller guarantees the index is not out of bounds
-// (but boundsCheck will still extend the index to full int width).
-func (s *state) boundsCheck(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value {
-	idx = s.extendIndex(idx, len, kind, bounded)
-
-	if bounded || Debug.B != 0 {
-		// If bounded or bounds checking is flag-disabled, then no check necessary,
-		// just return the extended index.
-		//
-		// Here, bounded == true if the compiler generated the index itself,
-		// such as in the expansion of a slice initializer. These indexes are
-		// compiler-generated, not Go program variables, so they cannot be
-		// attacker-controlled, so we can omit Spectre masking as well.
-		//
-		// Note that we do not want to omit Spectre masking in code like:
-		//
-		//	if 0 <= i && i < len(x) {
-		//		use(x[i])
-		//	}
-		//
-		// Lucky for us, bounded==false for that code.
-		// In that case (handled below), we emit a bound check (and Spectre mask)
-		// and then the prove pass will remove the bounds check.
-		// In theory the prove pass could potentially remove certain
-		// Spectre masks, but it's very delicate and probably better
-		// to be conservative and leave them all in.
-		return idx
-	}
-
-	bNext := s.f.NewBlock(ssa.BlockPlain)
-	bPanic := s.f.NewBlock(ssa.BlockExit)
-
-	if !idx.Type.IsSigned() {
-		switch kind {
-		case ssa.BoundsIndex:
-			kind = ssa.BoundsIndexU
-		case ssa.BoundsSliceAlen:
-			kind = ssa.BoundsSliceAlenU
-		case ssa.BoundsSliceAcap:
-			kind = ssa.BoundsSliceAcapU
-		case ssa.BoundsSliceB:
-			kind = ssa.BoundsSliceBU
-		case ssa.BoundsSlice3Alen:
-			kind = ssa.BoundsSlice3AlenU
-		case ssa.BoundsSlice3Acap:
-			kind = ssa.BoundsSlice3AcapU
-		case ssa.BoundsSlice3B:
-			kind = ssa.BoundsSlice3BU
-		case ssa.BoundsSlice3C:
-			kind = ssa.BoundsSlice3CU
-		}
-	}
-
-	var cmp *ssa.Value
-	if kind == ssa.BoundsIndex || kind == ssa.BoundsIndexU {
-		cmp = s.newValue2(ssa.OpIsInBounds, types.Types[TBOOL], idx, len)
-	} else {
-		cmp = s.newValue2(ssa.OpIsSliceInBounds, types.Types[TBOOL], idx, len)
-	}
-	b := s.endBlock()
-	b.Kind = ssa.BlockIf
-	b.SetControl(cmp)
-	b.Likely = ssa.BranchLikely
-	b.AddEdgeTo(bNext)
-	b.AddEdgeTo(bPanic)
-
-	s.startBlock(bPanic)
-	if thearch.LinkArch.Family == sys.Wasm {
-		// TODO(khr): figure out how to do "register" based calling convention for bounds checks.
-		// Should be similar to gcWriteBarrier, but I can't make it work.
-		s.rtcall(BoundsCheckFunc[kind], false, nil, idx, len)
-	} else {
-		mem := s.newValue3I(ssa.OpPanicBounds, types.TypeMem, int64(kind), idx, len, s.mem())
-		s.endBlock().SetControl(mem)
-	}
-	s.startBlock(bNext)
-
-	// In Spectre index mode, apply an appropriate mask to avoid speculative out-of-bounds accesses.
-	if spectreIndex {
-		op := ssa.OpSpectreIndex
-		if kind != ssa.BoundsIndex && kind != ssa.BoundsIndexU {
-			op = ssa.OpSpectreSliceIndex
-		}
-		idx = s.newValue2(op, types.Types[TINT], idx, len)
-	}
-
-	return idx
-}
-
-// If cmp (a bool) is false, panic using the given function.
-func (s *state) check(cmp *ssa.Value, fn *obj.LSym) {
-	b := s.endBlock()
-	b.Kind = ssa.BlockIf
-	b.SetControl(cmp)
-	b.Likely = ssa.BranchLikely
-	bNext := s.f.NewBlock(ssa.BlockPlain)
-	line := s.peekPos()
-	pos := Ctxt.PosTable.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)
-		s.panics[fl] = bPanic
-		s.startBlock(bPanic)
-		// The panic call takes/returns memory to ensure that the right
-		// memory state is observed if the panic happens.
-		s.rtcall(fn, false, nil)
-	}
-	b.AddEdgeTo(bNext)
-	b.AddEdgeTo(bPanic)
-	s.startBlock(bNext)
-}
-
-func (s *state) intDivide(n *Node, a, b *ssa.Value) *ssa.Value {
-	needcheck := true
-	switch b.Op {
-	case ssa.OpConst8, ssa.OpConst16, ssa.OpConst32, ssa.OpConst64:
-		if b.AuxInt != 0 {
-			needcheck = false
-		}
-	}
-	if needcheck {
-		// do a size-appropriate check for zero
-		cmp := s.newValue2(s.ssaOp(ONE, n.Type), types.Types[TBOOL], b, s.zeroVal(n.Type))
-		s.check(cmp, panicdivide)
-	}
-	return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
-}
-
-// rtcall issues a call to the given runtime function fn with the listed args.
-// Returns a slice of results of the given result types.
-// The call is added to the end of the current block.
-// If returns is false, the block is marked as an exit block.
-func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args ...*ssa.Value) []*ssa.Value {
-	s.prevCall = nil
-	// Write args to the stack
-	off := Ctxt.FixedFrameSize()
-	testLateExpansion := ssa.LateCallExpansionEnabledWithin(s.f)
-	var ACArgs []ssa.Param
-	var ACResults []ssa.Param
-	var callArgs []*ssa.Value
-
-	for _, arg := range args {
-		t := arg.Type
-		off = Rnd(off, t.Alignment())
-		size := t.Size()
-		ACArgs = append(ACArgs, ssa.Param{Type: t, Offset: int32(off)})
-		if testLateExpansion {
-			callArgs = append(callArgs, arg)
-		} else {
-			ptr := s.constOffPtrSP(t.PtrTo(), off)
-			s.store(t, ptr, arg)
-		}
-		off += size
-	}
-	off = Rnd(off, int64(Widthreg))
-
-	// Accumulate results types and offsets
-	offR := off
-	for _, t := range results {
-		offR = Rnd(offR, t.Alignment())
-		ACResults = append(ACResults, ssa.Param{Type: t, Offset: int32(offR)})
-		offR += t.Size()
-	}
-
-	// Issue call
-	var call *ssa.Value
-	aux := ssa.StaticAuxCall(fn, ACArgs, ACResults)
-	if testLateExpansion {
-		callArgs = append(callArgs, s.mem())
-		call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
-		call.AddArgs(callArgs...)
-		s.vars[&memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call)
-	} else {
-		call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
-		s.vars[&memVar] = call
-	}
-
-	if !returns {
-		// Finish block
-		b := s.endBlock()
-		b.Kind = ssa.BlockExit
-		b.SetControl(call)
-		call.AuxInt = off - Ctxt.FixedFrameSize()
-		if len(results) > 0 {
-			s.Fatalf("panic call can't have results")
-		}
-		return nil
-	}
-
-	// Load results
-	res := make([]*ssa.Value, len(results))
-	if testLateExpansion {
-		for i, t := range results {
-			off = Rnd(off, t.Alignment())
-			if canSSAType(t) {
-				res[i] = s.newValue1I(ssa.OpSelectN, t, int64(i), call)
-			} else {
-				addr := s.newValue1I(ssa.OpSelectNAddr, types.NewPtr(t), int64(i), call)
-				res[i] = s.rawLoad(t, addr)
-			}
-			off += t.Size()
-		}
-	} else {
-		for i, t := range results {
-			off = Rnd(off, t.Alignment())
-			ptr := s.constOffPtrSP(types.NewPtr(t), off)
-			res[i] = s.load(t, ptr)
-			off += t.Size()
-		}
-	}
-	off = Rnd(off, int64(Widthptr))
-
-	// Remember how much callee stack space we needed.
-	call.AuxInt = off
-
-	return res
-}
-
-// do *left = right for type t.
-func (s *state) storeType(t *types.Type, left, right *ssa.Value, skip skipMask, leftIsStmt bool) {
-	s.instrument(t, left, instrumentWrite)
-
-	if skip == 0 && (!t.HasPointers() || ssa.IsStackAddr(left)) {
-		// Known to not have write barrier. Store the whole type.
-		s.vars[&memVar] = s.newValue3Apos(ssa.OpStore, types.TypeMem, t, left, right, s.mem(), leftIsStmt)
-		return
-	}
-
-	// store scalar fields first, so write barrier stores for
-	// pointer fields can be grouped together, and scalar values
-	// don't need to be live across the write barrier call.
-	// TODO: if the writebarrier pass knows how to reorder stores,
-	// we can do a single store here as long as skip==0.
-	s.storeTypeScalars(t, left, right, skip)
-	if skip&skipPtr == 0 && t.HasPointers() {
-		s.storeTypePtrs(t, left, right)
-	}
-}
-
-// do *left = right for all scalar (non-pointer) parts of t.
-func (s *state) storeTypeScalars(t *types.Type, left, right *ssa.Value, skip skipMask) {
-	switch {
-	case t.IsBoolean() || t.IsInteger() || t.IsFloat() || t.IsComplex():
-		s.store(t, left, right)
-	case t.IsPtrShaped():
-		if t.IsPtr() && t.Elem().NotInHeap() {
-			s.store(t, left, right) // see issue 42032
-		}
-		// otherwise, no scalar fields.
-	case t.IsString():
-		if skip&skipLen != 0 {
-			return
-		}
-		len := s.newValue1(ssa.OpStringLen, types.Types[TINT], right)
-		lenAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, s.config.PtrSize, left)
-		s.store(types.Types[TINT], lenAddr, len)
-	case t.IsSlice():
-		if skip&skipLen == 0 {
-			len := s.newValue1(ssa.OpSliceLen, types.Types[TINT], right)
-			lenAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, s.config.PtrSize, left)
-			s.store(types.Types[TINT], lenAddr, len)
-		}
-		if skip&skipCap == 0 {
-			cap := s.newValue1(ssa.OpSliceCap, types.Types[TINT], right)
-			capAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, 2*s.config.PtrSize, left)
-			s.store(types.Types[TINT], capAddr, cap)
-		}
-	case t.IsInterface():
-		// itab field doesn't need a write barrier (even though it is a pointer).
-		itab := s.newValue1(ssa.OpITab, s.f.Config.Types.BytePtr, right)
-		s.store(types.Types[TUINTPTR], left, itab)
-	case t.IsStruct():
-		n := t.NumFields()
-		for i := 0; i < n; i++ {
-			ft := t.FieldType(i)
-			addr := s.newValue1I(ssa.OpOffPtr, ft.PtrTo(), t.FieldOff(i), left)
-			val := s.newValue1I(ssa.OpStructSelect, ft, int64(i), right)
-			s.storeTypeScalars(ft, addr, val, 0)
-		}
-	case t.IsArray() && t.NumElem() == 0:
-		// nothing
-	case t.IsArray() && t.NumElem() == 1:
-		s.storeTypeScalars(t.Elem(), left, s.newValue1I(ssa.OpArraySelect, t.Elem(), 0, right), 0)
-	default:
-		s.Fatalf("bad write barrier type %v", t)
-	}
-}
-
-// do *left = right for all pointer parts of t.
-func (s *state) storeTypePtrs(t *types.Type, left, right *ssa.Value) {
-	switch {
-	case t.IsPtrShaped():
-		if t.IsPtr() && t.Elem().NotInHeap() {
-			break // see issue 42032
-		}
-		s.store(t, left, right)
-	case t.IsString():
-		ptr := s.newValue1(ssa.OpStringPtr, s.f.Config.Types.BytePtr, right)
-		s.store(s.f.Config.Types.BytePtr, left, ptr)
-	case t.IsSlice():
-		elType := types.NewPtr(t.Elem())
-		ptr := s.newValue1(ssa.OpSlicePtr, elType, right)
-		s.store(elType, left, ptr)
-	case t.IsInterface():
-		// itab field is treated as a scalar.
-		idata := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, right)
-		idataAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.BytePtrPtr, s.config.PtrSize, left)
-		s.store(s.f.Config.Types.BytePtr, idataAddr, idata)
-	case t.IsStruct():
-		n := t.NumFields()
-		for i := 0; i < n; i++ {
-			ft := t.FieldType(i)
-			if !ft.HasPointers() {
-				continue
-			}
-			addr := s.newValue1I(ssa.OpOffPtr, ft.PtrTo(), t.FieldOff(i), left)
-			val := s.newValue1I(ssa.OpStructSelect, ft, int64(i), right)
-			s.storeTypePtrs(ft, addr, val)
-		}
-	case t.IsArray() && t.NumElem() == 0:
-		// nothing
-	case t.IsArray() && t.NumElem() == 1:
-		s.storeTypePtrs(t.Elem(), left, s.newValue1I(ssa.OpArraySelect, t.Elem(), 0, right))
-	default:
-		s.Fatalf("bad write barrier type %v", t)
-	}
-}
-
-// putArg evaluates n for the purpose of passing it as an argument to a function and returns the corresponding Param for the call.
-// If forLateExpandedCall is true, it returns the argument value to pass to the call operation.
-// If forLateExpandedCall is false, then the value is stored at the specified stack offset, and the returned value is nil.
-func (s *state) putArg(n *Node, t *types.Type, off int64, forLateExpandedCall bool) (ssa.Param, *ssa.Value) {
-	var a *ssa.Value
-	if forLateExpandedCall {
-		if !canSSAType(t) {
-			a = s.newValue2(ssa.OpDereference, t, s.addr(n), s.mem())
-		} else {
-			a = s.expr(n)
-		}
-	} else {
-		s.storeArgWithBase(n, t, s.sp, off)
-	}
-	return ssa.Param{Type: t, Offset: int32(off)}, a
-}
-
-func (s *state) storeArgWithBase(n *Node, t *types.Type, base *ssa.Value, off int64) {
-	pt := types.NewPtr(t)
-	var addr *ssa.Value
-	if base == s.sp {
-		// Use special routine that avoids allocation on duplicate offsets.
-		addr = s.constOffPtrSP(pt, off)
-	} else {
-		addr = s.newValue1I(ssa.OpOffPtr, pt, off, base)
-	}
-
-	if !canSSAType(t) {
-		a := s.addr(n)
-		s.move(t, addr, a)
-		return
-	}
-
-	a := s.expr(n)
-	s.storeType(t, addr, a, 0, false)
-}
-
-// slice computes the slice v[i:j:k] and returns ptr, len, and cap of result.
-// i,j,k may be nil, in which case they are set to their default value.
-// v may be a slice, string or pointer to an array.
-func (s *state) slice(v, i, j, k *ssa.Value, bounded bool) (p, l, c *ssa.Value) {
-	t := v.Type
-	var ptr, len, cap *ssa.Value
-	switch {
-	case t.IsSlice():
-		ptr = s.newValue1(ssa.OpSlicePtr, types.NewPtr(t.Elem()), v)
-		len = s.newValue1(ssa.OpSliceLen, types.Types[TINT], v)
-		cap = s.newValue1(ssa.OpSliceCap, types.Types[TINT], v)
-	case t.IsString():
-		ptr = s.newValue1(ssa.OpStringPtr, types.NewPtr(types.Types[TUINT8]), v)
-		len = s.newValue1(ssa.OpStringLen, types.Types[TINT], v)
-		cap = len
-	case t.IsPtr():
-		if !t.Elem().IsArray() {
-			s.Fatalf("bad ptr to array in slice %v\n", t)
-		}
-		s.nilCheck(v)
-		ptr = s.newValue1(ssa.OpCopy, types.NewPtr(t.Elem().Elem()), v)
-		len = s.constInt(types.Types[TINT], t.Elem().NumElem())
-		cap = len
-	default:
-		s.Fatalf("bad type in slice %v\n", t)
-	}
-
-	// Set default values
-	if i == nil {
-		i = s.constInt(types.Types[TINT], 0)
-	}
-	if j == nil {
-		j = len
-	}
-	three := true
-	if k == nil {
-		three = false
-		k = cap
-	}
-
-	// Panic if slice indices are not in bounds.
-	// Make sure we check these in reverse order so that we're always
-	// comparing against a value known to be nonnegative. See issue 28797.
-	if three {
-		if k != cap {
-			kind := ssa.BoundsSlice3Alen
-			if t.IsSlice() {
-				kind = ssa.BoundsSlice3Acap
-			}
-			k = s.boundsCheck(k, cap, kind, bounded)
-		}
-		if j != k {
-			j = s.boundsCheck(j, k, ssa.BoundsSlice3B, bounded)
-		}
-		i = s.boundsCheck(i, j, ssa.BoundsSlice3C, bounded)
-	} else {
-		if j != k {
-			kind := ssa.BoundsSliceAlen
-			if t.IsSlice() {
-				kind = ssa.BoundsSliceAcap
-			}
-			j = s.boundsCheck(j, k, kind, bounded)
-		}
-		i = s.boundsCheck(i, j, ssa.BoundsSliceB, bounded)
-	}
-
-	// Word-sized integer operations.
-	subOp := s.ssaOp(OSUB, types.Types[TINT])
-	mulOp := s.ssaOp(OMUL, types.Types[TINT])
-	andOp := s.ssaOp(OAND, types.Types[TINT])
-
-	// Calculate the length (rlen) and capacity (rcap) of the new slice.
-	// For strings the capacity of the result is unimportant. However,
-	// we use rcap to test if we've generated a zero-length slice.
-	// Use length of strings for that.
-	rlen := s.newValue2(subOp, types.Types[TINT], j, i)
-	rcap := rlen
-	if j != k && !t.IsString() {
-		rcap = s.newValue2(subOp, types.Types[TINT], k, i)
-	}
-
-	if (i.Op == ssa.OpConst64 || i.Op == ssa.OpConst32) && i.AuxInt == 0 {
-		// No pointer arithmetic necessary.
-		return ptr, rlen, rcap
-	}
-
-	// Calculate the base pointer (rptr) for the new slice.
-	//
-	// Generate the following code assuming that indexes are in bounds.
-	// The masking is to make sure that we don't generate a slice
-	// that points to the next object in memory. We cannot just set
-	// the pointer to nil because then we would create a nil slice or
-	// string.
-	//
-	//     rcap = k - i
-	//     rlen = j - i
-	//     rptr = ptr + (mask(rcap) & (i * stride))
-	//
-	// Where mask(x) is 0 if x==0 and -1 if x>0 and stride is the width
-	// of the element type.
-	stride := s.constInt(types.Types[TINT], ptr.Type.Elem().Width)
-
-	// The delta is the number of bytes to offset ptr by.
-	delta := s.newValue2(mulOp, types.Types[TINT], i, stride)
-
-	// If we're slicing to the point where the capacity is zero,
-	// zero out the delta.
-	mask := s.newValue1(ssa.OpSlicemask, types.Types[TINT], rcap)
-	delta = s.newValue2(andOp, types.Types[TINT], delta, mask)
-
-	// Compute rptr = ptr + delta.
-	rptr := s.newValue2(ssa.OpAddPtr, ptr.Type, ptr, delta)
-
-	return rptr, rlen, rcap
-}
-
-type u642fcvtTab struct {
-	leq, cvt2F, and, rsh, or, add ssa.Op
-	one                           func(*state, *types.Type, int64) *ssa.Value
-}
-
-var u64_f64 = u642fcvtTab{
-	leq:   ssa.OpLeq64,
-	cvt2F: ssa.OpCvt64to64F,
-	and:   ssa.OpAnd64,
-	rsh:   ssa.OpRsh64Ux64,
-	or:    ssa.OpOr64,
-	add:   ssa.OpAdd64F,
-	one:   (*state).constInt64,
-}
-
-var u64_f32 = u642fcvtTab{
-	leq:   ssa.OpLeq64,
-	cvt2F: ssa.OpCvt64to32F,
-	and:   ssa.OpAnd64,
-	rsh:   ssa.OpRsh64Ux64,
-	or:    ssa.OpOr64,
-	add:   ssa.OpAdd32F,
-	one:   (*state).constInt64,
-}
-
-func (s *state) uint64Tofloat64(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
-	return s.uint64Tofloat(&u64_f64, n, x, ft, tt)
-}
-
-func (s *state) uint64Tofloat32(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
-	return s.uint64Tofloat(&u64_f32, n, x, ft, tt)
-}
-
-func (s *state) uint64Tofloat(cvttab *u642fcvtTab, n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
-	// if x >= 0 {
-	//    result = (floatY) x
-	// } else {
-	// 	  y = uintX(x) ; y = x & 1
-	// 	  z = uintX(x) ; z = z >> 1
-	// 	  z = z >> 1
-	// 	  z = z | y
-	// 	  result = floatY(z)
-	// 	  result = result + result
-	// }
-	//
-	// Code borrowed from old code generator.
-	// What's going on: large 64-bit "unsigned" looks like
-	// negative number to hardware's integer-to-float
-	// conversion. However, because the mantissa is only
-	// 63 bits, we don't need the LSB, so instead we do an
-	// unsigned right shift (divide by two), convert, and
-	// double. However, before we do that, we need to be
-	// sure that we do not lose a "1" if that made the
-	// difference in the resulting rounding. Therefore, we
-	// preserve it, and OR (not ADD) it back in. The case
-	// that matters is when the eleven discarded bits are
-	// equal to 10000000001; that rounds up, and the 1 cannot
-	// be lost else it would round down if the LSB of the
-	// candidate mantissa is 0.
-	cmp := s.newValue2(cvttab.leq, types.Types[TBOOL], s.zeroVal(ft), x)
-	b := s.endBlock()
-	b.Kind = ssa.BlockIf
-	b.SetControl(cmp)
-	b.Likely = ssa.BranchLikely
-
-	bThen := s.f.NewBlock(ssa.BlockPlain)
-	bElse := s.f.NewBlock(ssa.BlockPlain)
-	bAfter := s.f.NewBlock(ssa.BlockPlain)
-
-	b.AddEdgeTo(bThen)
-	s.startBlock(bThen)
-	a0 := s.newValue1(cvttab.cvt2F, tt, x)
-	s.vars[n] = a0
-	s.endBlock()
-	bThen.AddEdgeTo(bAfter)
-
-	b.AddEdgeTo(bElse)
-	s.startBlock(bElse)
-	one := cvttab.one(s, ft, 1)
-	y := s.newValue2(cvttab.and, ft, x, one)
-	z := s.newValue2(cvttab.rsh, ft, x, one)
-	z = s.newValue2(cvttab.or, ft, z, y)
-	a := s.newValue1(cvttab.cvt2F, tt, z)
-	a1 := s.newValue2(cvttab.add, tt, a, a)
-	s.vars[n] = a1
-	s.endBlock()
-	bElse.AddEdgeTo(bAfter)
-
-	s.startBlock(bAfter)
-	return s.variable(n, n.Type)
-}
-
-type u322fcvtTab struct {
-	cvtI2F, cvtF2F ssa.Op
-}
-
-var u32_f64 = u322fcvtTab{
-	cvtI2F: ssa.OpCvt32to64F,
-	cvtF2F: ssa.OpCopy,
-}
-
-var u32_f32 = u322fcvtTab{
-	cvtI2F: ssa.OpCvt32to32F,
-	cvtF2F: ssa.OpCvt64Fto32F,
-}
-
-func (s *state) uint32Tofloat64(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
-	return s.uint32Tofloat(&u32_f64, n, x, ft, tt)
-}
-
-func (s *state) uint32Tofloat32(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
-	return s.uint32Tofloat(&u32_f32, n, x, ft, tt)
-}
-
-func (s *state) uint32Tofloat(cvttab *u322fcvtTab, n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
-	// if x >= 0 {
-	// 	result = floatY(x)
-	// } else {
-	// 	result = floatY(float64(x) + (1<<32))
-	// }
-	cmp := s.newValue2(ssa.OpLeq32, types.Types[TBOOL], s.zeroVal(ft), x)
-	b := s.endBlock()
-	b.Kind = ssa.BlockIf
-	b.SetControl(cmp)
-	b.Likely = ssa.BranchLikely
-
-	bThen := s.f.NewBlock(ssa.BlockPlain)
-	bElse := s.f.NewBlock(ssa.BlockPlain)
-	bAfter := s.f.NewBlock(ssa.BlockPlain)
-
-	b.AddEdgeTo(bThen)
-	s.startBlock(bThen)
-	a0 := s.newValue1(cvttab.cvtI2F, tt, x)
-	s.vars[n] = a0
-	s.endBlock()
-	bThen.AddEdgeTo(bAfter)
-
-	b.AddEdgeTo(bElse)
-	s.startBlock(bElse)
-	a1 := s.newValue1(ssa.OpCvt32to64F, types.Types[TFLOAT64], x)
-	twoToThe32 := s.constFloat64(types.Types[TFLOAT64], float64(1<<32))
-	a2 := s.newValue2(ssa.OpAdd64F, types.Types[TFLOAT64], a1, twoToThe32)
-	a3 := s.newValue1(cvttab.cvtF2F, tt, a2)
-
-	s.vars[n] = a3
-	s.endBlock()
-	bElse.AddEdgeTo(bAfter)
-
-	s.startBlock(bAfter)
-	return s.variable(n, n.Type)
-}
-
-// referenceTypeBuiltin generates code for the len/cap builtins for maps and channels.
-func (s *state) referenceTypeBuiltin(n *Node, x *ssa.Value) *ssa.Value {
-	if !n.Left.Type.IsMap() && !n.Left.Type.IsChan() {
-		s.Fatalf("node must be a map or a channel")
-	}
-	// if n == nil {
-	//   return 0
-	// } else {
-	//   // len
-	//   return *((*int)n)
-	//   // cap
-	//   return *(((*int)n)+1)
-	// }
-	lenType := n.Type
-	nilValue := s.constNil(types.Types[TUINTPTR])
-	cmp := s.newValue2(ssa.OpEqPtr, types.Types[TBOOL], x, nilValue)
-	b := s.endBlock()
-	b.Kind = ssa.BlockIf
-	b.SetControl(cmp)
-	b.Likely = ssa.BranchUnlikely
-
-	bThen := s.f.NewBlock(ssa.BlockPlain)
-	bElse := s.f.NewBlock(ssa.BlockPlain)
-	bAfter := s.f.NewBlock(ssa.BlockPlain)
-
-	// length/capacity of a nil map/chan is zero
-	b.AddEdgeTo(bThen)
-	s.startBlock(bThen)
-	s.vars[n] = s.zeroVal(lenType)
-	s.endBlock()
-	bThen.AddEdgeTo(bAfter)
-
-	b.AddEdgeTo(bElse)
-	s.startBlock(bElse)
-	switch n.Op {
-	case OLEN:
-		// length is stored in the first word for map/chan
-		s.vars[n] = s.load(lenType, x)
-	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.load(lenType, sw)
-	default:
-		s.Fatalf("op must be OLEN or OCAP")
-	}
-	s.endBlock()
-	bElse.AddEdgeTo(bAfter)
-
-	s.startBlock(bAfter)
-	return s.variable(n, lenType)
-}
-
-type f2uCvtTab struct {
-	ltf, cvt2U, subf, or ssa.Op
-	floatValue           func(*state, *types.Type, float64) *ssa.Value
-	intValue             func(*state, *types.Type, int64) *ssa.Value
-	cutoff               uint64
-}
-
-var f32_u64 = f2uCvtTab{
-	ltf:        ssa.OpLess32F,
-	cvt2U:      ssa.OpCvt32Fto64,
-	subf:       ssa.OpSub32F,
-	or:         ssa.OpOr64,
-	floatValue: (*state).constFloat32,
-	intValue:   (*state).constInt64,
-	cutoff:     1 << 63,
-}
-
-var f64_u64 = f2uCvtTab{
-	ltf:        ssa.OpLess64F,
-	cvt2U:      ssa.OpCvt64Fto64,
-	subf:       ssa.OpSub64F,
-	or:         ssa.OpOr64,
-	floatValue: (*state).constFloat64,
-	intValue:   (*state).constInt64,
-	cutoff:     1 << 63,
-}
-
-var f32_u32 = f2uCvtTab{
-	ltf:        ssa.OpLess32F,
-	cvt2U:      ssa.OpCvt32Fto32,
-	subf:       ssa.OpSub32F,
-	or:         ssa.OpOr32,
-	floatValue: (*state).constFloat32,
-	intValue:   func(s *state, t *types.Type, v int64) *ssa.Value { return s.constInt32(t, int32(v)) },
-	cutoff:     1 << 31,
-}
-
-var f64_u32 = f2uCvtTab{
-	ltf:        ssa.OpLess64F,
-	cvt2U:      ssa.OpCvt64Fto32,
-	subf:       ssa.OpSub64F,
-	or:         ssa.OpOr32,
-	floatValue: (*state).constFloat64,
-	intValue:   func(s *state, t *types.Type, v int64) *ssa.Value { return s.constInt32(t, int32(v)) },
-	cutoff:     1 << 31,
-}
-
-func (s *state) float32ToUint64(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
-	return s.floatToUint(&f32_u64, n, x, ft, tt)
-}
-func (s *state) float64ToUint64(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
-	return s.floatToUint(&f64_u64, n, x, ft, tt)
-}
-
-func (s *state) float32ToUint32(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
-	return s.floatToUint(&f32_u32, n, x, ft, tt)
-}
-
-func (s *state) float64ToUint32(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
-	return s.floatToUint(&f64_u32, n, x, ft, tt)
-}
-
-func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
-	// cutoff:=1<<(intY_Size-1)
-	// if x < floatX(cutoff) {
-	// 	result = uintY(x)
-	// } else {
-	// 	y = x - floatX(cutoff)
-	// 	z = uintY(y)
-	// 	result = z | -(cutoff)
-	// }
-	cutoff := cvttab.floatValue(s, ft, float64(cvttab.cutoff))
-	cmp := s.newValue2(cvttab.ltf, types.Types[TBOOL], x, cutoff)
-	b := s.endBlock()
-	b.Kind = ssa.BlockIf
-	b.SetControl(cmp)
-	b.Likely = ssa.BranchLikely
-
-	bThen := s.f.NewBlock(ssa.BlockPlain)
-	bElse := s.f.NewBlock(ssa.BlockPlain)
-	bAfter := s.f.NewBlock(ssa.BlockPlain)
-
-	b.AddEdgeTo(bThen)
-	s.startBlock(bThen)
-	a0 := s.newValue1(cvttab.cvt2U, tt, x)
-	s.vars[n] = a0
-	s.endBlock()
-	bThen.AddEdgeTo(bAfter)
-
-	b.AddEdgeTo(bElse)
-	s.startBlock(bElse)
-	y := s.newValue2(cvttab.subf, ft, x, cutoff)
-	y = s.newValue1(cvttab.cvt2U, tt, y)
-	z := cvttab.intValue(s, tt, int64(-cvttab.cutoff))
-	a1 := s.newValue2(cvttab.or, tt, y, z)
-	s.vars[n] = a1
-	s.endBlock()
-	bElse.AddEdgeTo(bAfter)
-
-	s.startBlock(bAfter)
-	return s.variable(n, n.Type)
-}
-
-// dottype generates SSA for a type assertion node.
-// commaok indicates whether to panic or return a bool.
-// If commaok is false, resok will be nil.
-func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
-	iface := s.expr(n.Left)   // input interface
-	target := s.expr(n.Right) // target type
-	byteptr := s.f.Config.Types.BytePtr
-
-	if n.Type.IsInterface() {
-		if n.Type.IsEmptyInterface() {
-			// Converting to an empty interface.
-			// Input could be an empty or nonempty interface.
-			if Debug_typeassert > 0 {
-				Warnl(n.Pos, "type assertion inlined")
-			}
-
-			// Get itab/type field from input.
-			itab := s.newValue1(ssa.OpITab, byteptr, iface)
-			// Conversion succeeds iff that field is not nil.
-			cond := s.newValue2(ssa.OpNeqPtr, types.Types[TBOOL], itab, s.constNil(byteptr))
-
-			if n.Left.Type.IsEmptyInterface() && commaok {
-				// Converting empty interface to empty interface with ,ok is just a nil check.
-				return iface, cond
-			}
-
-			// Branch on nilness.
-			b := s.endBlock()
-			b.Kind = ssa.BlockIf
-			b.SetControl(cond)
-			b.Likely = ssa.BranchLikely
-			bOk := s.f.NewBlock(ssa.BlockPlain)
-			bFail := s.f.NewBlock(ssa.BlockPlain)
-			b.AddEdgeTo(bOk)
-			b.AddEdgeTo(bFail)
-
-			if !commaok {
-				// On failure, panic by calling panicnildottype.
-				s.startBlock(bFail)
-				s.rtcall(panicnildottype, false, nil, target)
-
-				// On success, return (perhaps modified) input interface.
-				s.startBlock(bOk)
-				if n.Left.Type.IsEmptyInterface() {
-					res = iface // Use input interface unchanged.
-					return
-				}
-				// Load type out of itab, build interface with existing idata.
-				off := s.newValue1I(ssa.OpOffPtr, byteptr, int64(Widthptr), itab)
-				typ := s.load(byteptr, off)
-				idata := s.newValue1(ssa.OpIData, byteptr, iface)
-				res = s.newValue2(ssa.OpIMake, n.Type, typ, idata)
-				return
-			}
-
-			s.startBlock(bOk)
-			// nonempty -> empty
-			// Need to load type from itab
-			off := s.newValue1I(ssa.OpOffPtr, byteptr, int64(Widthptr), itab)
-			s.vars[&typVar] = s.load(byteptr, off)
-			s.endBlock()
-
-			// itab is nil, might as well use that as the nil result.
-			s.startBlock(bFail)
-			s.vars[&typVar] = itab
-			s.endBlock()
-
-			// Merge point.
-			bEnd := s.f.NewBlock(ssa.BlockPlain)
-			bOk.AddEdgeTo(bEnd)
-			bFail.AddEdgeTo(bEnd)
-			s.startBlock(bEnd)
-			idata := s.newValue1(ssa.OpIData, byteptr, iface)
-			res = s.newValue2(ssa.OpIMake, n.Type, s.variable(&typVar, byteptr), idata)
-			resok = cond
-			delete(s.vars, &typVar)
-			return
-		}
-		// converting to a nonempty interface needs a runtime call.
-		if Debug_typeassert > 0 {
-			Warnl(n.Pos, "type assertion not inlined")
-		}
-		if n.Left.Type.IsEmptyInterface() {
-			if commaok {
-				call := s.rtcall(assertE2I2, true, []*types.Type{n.Type, types.Types[TBOOL]}, target, iface)
-				return call[0], call[1]
-			}
-			return s.rtcall(assertE2I, true, []*types.Type{n.Type}, target, iface)[0], nil
-		}
-		if commaok {
-			call := s.rtcall(assertI2I2, true, []*types.Type{n.Type, types.Types[TBOOL]}, target, iface)
-			return call[0], call[1]
-		}
-		return s.rtcall(assertI2I, true, []*types.Type{n.Type}, target, iface)[0], nil
-	}
-
-	if Debug_typeassert > 0 {
-		Warnl(n.Pos, "type assertion inlined")
-	}
-
-	// Converting to a concrete type.
-	direct := isdirectiface(n.Type)
-	itab := s.newValue1(ssa.OpITab, byteptr, iface) // type word of interface
-	if Debug_typeassert > 0 {
-		Warnl(n.Pos, "type assertion inlined")
-	}
-	var targetITab *ssa.Value
-	if n.Left.Type.IsEmptyInterface() {
-		// Looking for pointer to target type.
-		targetITab = target
-	} else {
-		// Looking for pointer to itab for target type and source interface.
-		targetITab = s.expr(n.List.First())
-	}
-
-	var tmp *Node       // temporary for use with large types
-	var addr *ssa.Value // address of tmp
-	if commaok && !canSSAType(n.Type) {
-		// unSSAable type, use temporary.
-		// TODO: get rid of some of these temporaries.
-		tmp = tempAt(n.Pos, s.curfn, n.Type)
-		s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, tmp, s.mem())
-		addr = s.addr(tmp)
-	}
-
-	cond := s.newValue2(ssa.OpEqPtr, types.Types[TBOOL], itab, targetITab)
-	b := s.endBlock()
-	b.Kind = ssa.BlockIf
-	b.SetControl(cond)
-	b.Likely = ssa.BranchLikely
-
-	bOk := s.f.NewBlock(ssa.BlockPlain)
-	bFail := s.f.NewBlock(ssa.BlockPlain)
-	b.AddEdgeTo(bOk)
-	b.AddEdgeTo(bFail)
-
-	if !commaok {
-		// on failure, panic by calling panicdottype
-		s.startBlock(bFail)
-		taddr := s.expr(n.Right.Right)
-		if n.Left.Type.IsEmptyInterface() {
-			s.rtcall(panicdottypeE, false, nil, itab, target, taddr)
-		} else {
-			s.rtcall(panicdottypeI, false, nil, itab, target, taddr)
-		}
-
-		// on success, return data from interface
-		s.startBlock(bOk)
-		if direct {
-			return s.newValue1(ssa.OpIData, n.Type, iface), nil
-		}
-		p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type), iface)
-		return s.load(n.Type, p), nil
-	}
-
-	// commaok is the more complicated case because we have
-	// a control flow merge point.
-	bEnd := s.f.NewBlock(ssa.BlockPlain)
-	// Note that we need a new valVar each time (unlike okVar where we can
-	// reuse the variable) because it might have a different type every time.
-	valVar := &Node{Op: ONAME, Sym: &types.Sym{Name: "val"}}
-
-	// type assertion succeeded
-	s.startBlock(bOk)
-	if tmp == nil {
-		if direct {
-			s.vars[valVar] = s.newValue1(ssa.OpIData, n.Type, iface)
-		} else {
-			p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type), iface)
-			s.vars[valVar] = s.load(n.Type, p)
-		}
-	} else {
-		p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type), iface)
-		s.move(n.Type, addr, p)
-	}
-	s.vars[&okVar] = s.constBool(true)
-	s.endBlock()
-	bOk.AddEdgeTo(bEnd)
-
-	// type assertion failed
-	s.startBlock(bFail)
-	if tmp == nil {
-		s.vars[valVar] = s.zeroVal(n.Type)
-	} else {
-		s.zero(n.Type, addr)
-	}
-	s.vars[&okVar] = s.constBool(false)
-	s.endBlock()
-	bFail.AddEdgeTo(bEnd)
-
-	// merge point
-	s.startBlock(bEnd)
-	if tmp == nil {
-		res = s.variable(valVar, n.Type)
-		delete(s.vars, valVar)
-	} else {
-		res = s.load(n.Type, addr)
-		s.vars[&memVar] = s.newValue1A(ssa.OpVarKill, types.TypeMem, tmp, s.mem())
-	}
-	resok = s.variable(&okVar, types.Types[TBOOL])
-	delete(s.vars, &okVar)
-	return res, resok
-}
-
-// variable returns the value of a variable at the current location.
-func (s *state) variable(name *Node, t *types.Type) *ssa.Value {
-	v := s.vars[name]
-	if v != nil {
-		return v
-	}
-	v = s.fwdVars[name]
-	if v != nil {
-		return v
-	}
-
-	if s.curBlock == s.f.Entry {
-		// No variable should be live at entry.
-		s.Fatalf("Value live at entry. It shouldn't be. func %s, node %v, value %v", s.f.Name, name, v)
-	}
-	// Make a FwdRef, which records a value that's live on block input.
-	// We'll find the matching definition as part of insertPhis.
-	v = s.newValue0A(ssa.OpFwdRef, t, name)
-	s.fwdVars[name] = v
-	s.addNamedValue(name, v)
-	return v
-}
-
-func (s *state) mem() *ssa.Value {
-	return s.variable(&memVar, types.TypeMem)
-}
-
-func (s *state) addNamedValue(n *Node, v *ssa.Value) {
-	if n.Class() == Pxxx {
-		// Don't track our dummy nodes (&memVar etc.).
-		return
-	}
-	if n.IsAutoTmp() {
-		// Don't track temporary variables.
-		return
-	}
-	if n.Class() == PPARAMOUT {
-		// Don't track named output values.  This prevents return values
-		// from being assigned too early. See #14591 and #14762. TODO: allow this.
-		return
-	}
-	if n.Class() == PAUTO && n.Xoffset != 0 {
-		s.Fatalf("AUTO var with offset %v %d", n, n.Xoffset)
-	}
-	loc := ssa.LocalSlot{N: n, Type: n.Type, Off: 0}
-	values, ok := s.f.NamedValues[loc]
-	if !ok {
-		s.f.Names = append(s.f.Names, loc)
-	}
-	s.f.NamedValues[loc] = append(values, v)
-}
-
-// Generate a disconnected call to a runtime routine and a return.
-func gencallret(pp *Progs, sym *obj.LSym) *obj.Prog {
-	p := pp.Prog(obj.ACALL)
-	p.To.Type = obj.TYPE_MEM
-	p.To.Name = obj.NAME_EXTERN
-	p.To.Sym = sym
-	p = pp.Prog(obj.ARET)
-	return p
-}
-
-// Branch is an unresolved branch.
-type Branch struct {
-	P *obj.Prog  // branch instruction
-	B *ssa.Block // target
-}
-
-// SSAGenState contains state needed during Prog generation.
-type SSAGenState struct {
-	pp *Progs
-
-	// Branches remembers all the branch instructions we've seen
-	// and where they would like to go.
-	Branches []Branch
-
-	// bstart remembers where each block starts (indexed by block ID)
-	bstart []*obj.Prog
-
-	// Some architectures require a 64-bit temporary for FP-related register shuffling. Examples include PPC and Sparc V8.
-	ScratchFpMem *Node
-
-	maxarg int64 // largest frame size for arguments to calls made by the function
-
-	// Map from GC safe points to liveness index, generated by
-	// liveness analysis.
-	livenessMap LivenessMap
-
-	// lineRunStart records the beginning of the current run of instructions
-	// within a single block sharing the same line number
-	// Used to move statement marks to the beginning of such runs.
-	lineRunStart *obj.Prog
-
-	// wasm: The number of values on the WebAssembly stack. This is only used as a safeguard.
-	OnWasmStackSkipped int
-}
-
-// Prog appends a new Prog.
-func (s *SSAGenState) Prog(as obj.As) *obj.Prog {
-	p := s.pp.Prog(as)
-	if ssa.LosesStmtMark(as) {
-		return p
-	}
-	// Float a statement start to the beginning of any same-line run.
-	// lineRunStart is reset at block boundaries, which appears to work well.
-	if s.lineRunStart == nil || s.lineRunStart.Pos.Line() != p.Pos.Line() {
-		s.lineRunStart = p
-	} else if p.Pos.IsStmt() == src.PosIsStmt {
-		s.lineRunStart.Pos = s.lineRunStart.Pos.WithIsStmt()
-		p.Pos = p.Pos.WithNotStmt()
-	}
-	return p
-}
-
-// Pc returns the current Prog.
-func (s *SSAGenState) Pc() *obj.Prog {
-	return s.pp.next
-}
-
-// SetPos sets the current source position.
-func (s *SSAGenState) SetPos(pos src.XPos) {
-	s.pp.pos = pos
-}
-
-// Br emits a single branch instruction and returns the instruction.
-// Not all architectures need the returned instruction, but otherwise
-// the boilerplate is common to all.
-func (s *SSAGenState) Br(op obj.As, target *ssa.Block) *obj.Prog {
-	p := s.Prog(op)
-	p.To.Type = obj.TYPE_BRANCH
-	s.Branches = append(s.Branches, Branch{P: p, B: target})
-	return p
-}
-
-// DebugFriendlySetPosFrom adjusts Pos.IsStmt subject to heuristics
-// that reduce "jumpy" line number churn when debugging.
-// Spill/fill/copy instructions from the register allocator,
-// phi functions, and instructions with a no-pos position
-// are examples of instructions that can cause churn.
-func (s *SSAGenState) DebugFriendlySetPosFrom(v *ssa.Value) {
-	switch v.Op {
-	case ssa.OpPhi, ssa.OpCopy, ssa.OpLoadReg, ssa.OpStoreReg:
-		// These are not statements
-		s.SetPos(v.Pos.WithNotStmt())
-	default:
-		p := v.Pos
-		if p != src.NoXPos {
-			// If the position is defined, update the position.
-			// Also convert default IsStmt to NotStmt; only
-			// explicit statement boundaries should appear
-			// in the generated code.
-			if p.IsStmt() != src.PosIsStmt {
-				p = p.WithNotStmt()
-				// Calls use the pos attached to v, but copy the statement mark from SSAGenState
-			}
-			s.SetPos(p)
-		} else {
-			s.SetPos(s.pp.pos.WithNotStmt())
-		}
-	}
-}
-
-// byXoffset implements sort.Interface for []*Node using Xoffset as the ordering.
-type byXoffset []*Node
-
-func (s byXoffset) Len() int           { return len(s) }
-func (s byXoffset) Less(i, j int) bool { return s[i].Xoffset < s[j].Xoffset }
-func (s byXoffset) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-
-func emitStackObjects(e *ssafn, pp *Progs) {
-	var vars []*Node
-	for _, n := range e.curfn.Func.Dcl {
-		if livenessShouldTrack(n) && n.Name.Addrtaken() {
-			vars = append(vars, n)
-		}
-	}
-	if len(vars) == 0 {
-		return
-	}
-
-	// Sort variables from lowest to highest address.
-	sort.Sort(byXoffset(vars))
-
-	// Populate the stack object data.
-	// Format must match runtime/stack.go:stackObjectRecord.
-	x := e.curfn.Func.lsym.Func().StackObjects
-	off := 0
-	off = duintptr(x, off, uint64(len(vars)))
-	for _, v := range vars {
-		// Note: arguments and return values have non-negative Xoffset,
-		// in which case the offset is relative to argp.
-		// Locals have a negative Xoffset, in which case the offset is relative to varp.
-		off = duintptr(x, off, uint64(v.Xoffset))
-		if !typesym(v.Type).Siggen() {
-			e.Fatalf(v.Pos, "stack object's type symbol not generated for type %s", v.Type)
-		}
-		off = dsymptr(x, off, dtypesym(v.Type), 0)
-	}
-
-	// Emit a funcdata pointing at the stack object data.
-	p := pp.Prog(obj.AFUNCDATA)
-	Addrconst(&p.From, objabi.FUNCDATA_StackObjects)
-	p.To.Type = obj.TYPE_MEM
-	p.To.Name = obj.NAME_EXTERN
-	p.To.Sym = x
-
-	if debuglive != 0 {
-		for _, v := range vars {
-			Warnl(v.Pos, "stack object %v %s", v, v.Type.String())
-		}
-	}
-}
-
-// genssa appends entries to pp for each instruction in f.
-func genssa(f *ssa.Func, pp *Progs) {
-	var s SSAGenState
-
-	e := f.Frontend().(*ssafn)
-
-	s.livenessMap = liveness(e, f, pp)
-	emitStackObjects(e, pp)
-
-	openDeferInfo := e.curfn.Func.lsym.Func().OpenCodedDeferInfo
-	if openDeferInfo != nil {
-		// This function uses open-coded defers -- write out the funcdata
-		// info that we computed at the end of genssa.
-		p := pp.Prog(obj.AFUNCDATA)
-		Addrconst(&p.From, objabi.FUNCDATA_OpenCodedDeferInfo)
-		p.To.Type = obj.TYPE_MEM
-		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = openDeferInfo
-	}
-
-	// Remember where each block starts.
-	s.bstart = make([]*obj.Prog, f.NumBlocks())
-	s.pp = pp
-	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.
-	if f.PrintOrHtmlSSA {
-		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)
-		progToBlock[s.pp.next] = f.Blocks[0]
-	}
-
-	s.ScratchFpMem = e.scratchFpMem
-
-	if Ctxt.Flag_locationlists {
-		if cap(f.Cache.ValueToProgAfter) < f.NumValues() {
-			f.Cache.ValueToProgAfter = make([]*obj.Prog, f.NumValues())
-		}
-		valueToProgAfter = f.Cache.ValueToProgAfter[:f.NumValues()]
-		for i := range valueToProgAfter {
-			valueToProgAfter[i] = nil
-		}
-	}
-
-	// If the very first instruction is not tagged as a statement,
-	// debuggers may attribute it to previous function in program.
-	firstPos := src.NoXPos
-	for _, v := range f.Entry.Values {
-		if v.Pos.IsStmt() == src.PosIsStmt {
-			firstPos = v.Pos
-			v.Pos = firstPos.WithDefaultStmt()
-			break
-		}
-	}
-
-	// inlMarks has an entry for each Prog that implements an inline mark.
-	// It maps from that Prog to the global inlining id of the inlined body
-	// which should unwind to this Prog's location.
-	var inlMarks map[*obj.Prog]int32
-	var inlMarkList []*obj.Prog
-
-	// inlMarksByPos maps from a (column 1) source position to the set of
-	// Progs that are in the set above and have that source position.
-	var inlMarksByPos map[src.XPos][]*obj.Prog
-
-	// Emit basic blocks
-	for i, b := range f.Blocks {
-		s.bstart[b.ID] = s.pp.next
-		s.lineRunStart = nil
-
-		// Attach a "default" liveness info. Normally this will be
-		// overwritten in the Values loop below for each Value. But
-		// for an empty block this will be used for its control
-		// instruction. We won't use the actual liveness map on a
-		// control instruction. Just mark it something that is
-		// preemptible, unless this function is "all unsafe".
-		s.pp.nextLive = LivenessIndex{-1, allUnsafe(f)}
-
-		// Emit values in block
-		thearch.SSAMarkMoves(&s, b)
-		for _, v := range b.Values {
-			x := s.pp.next
-			s.DebugFriendlySetPosFrom(v)
-
-			switch v.Op {
-			case ssa.OpInitMem:
-				// memory arg needs no code
-			case ssa.OpArg:
-				// input args need no code
-			case ssa.OpSP, ssa.OpSB:
-				// nothing to do
-			case ssa.OpSelect0, ssa.OpSelect1:
-				// nothing to do
-			case ssa.OpGetG:
-				// nothing to do when there's a g register,
-				// and checkLower complains if there's not
-			case ssa.OpVarDef, ssa.OpVarLive, ssa.OpKeepAlive, ssa.OpVarKill:
-				// nothing to do; already used by liveness
-			case ssa.OpPhi:
-				CheckLoweredPhi(v)
-			case ssa.OpConvert:
-				// nothing to do; no-op conversion for liveness
-				if v.Args[0].Reg() != v.Reg() {
-					v.Fatalf("OpConvert should be a no-op: %s; %s", v.Args[0].LongString(), v.LongString())
-				}
-			case ssa.OpInlMark:
-				p := thearch.Ginsnop(s.pp)
-				if inlMarks == nil {
-					inlMarks = map[*obj.Prog]int32{}
-					inlMarksByPos = map[src.XPos][]*obj.Prog{}
-				}
-				inlMarks[p] = v.AuxInt32()
-				inlMarkList = append(inlMarkList, p)
-				pos := v.Pos.AtColumn1()
-				inlMarksByPos[pos] = append(inlMarksByPos[pos], p)
-
-			default:
-				// Attach this safe point to the next
-				// instruction.
-				s.pp.nextLive = s.livenessMap.Get(v)
-
-				// Special case for first line in function; move it to the start.
-				if firstPos != src.NoXPos {
-					s.SetPos(firstPos)
-					firstPos = src.NoXPos
-				}
-				// let the backend handle it
-				thearch.SSAGenValue(&s, v)
-			}
-
-			if Ctxt.Flag_locationlists {
-				valueToProgAfter[v.ID] = s.pp.next
-			}
-
-			if f.PrintOrHtmlSSA {
-				for ; x != s.pp.next; x = x.Link {
-					progToValue[x] = v
-				}
-			}
-		}
-		// If this is an empty infinite loop, stick a hardware NOP in there so that debuggers are less confused.
-		if s.bstart[b.ID] == s.pp.next && len(b.Succs) == 1 && b.Succs[0].Block() == b {
-			p := thearch.Ginsnop(s.pp)
-			p.Pos = p.Pos.WithIsStmt()
-			if b.Pos == src.NoXPos {
-				b.Pos = p.Pos // It needs a file, otherwise a no-file non-zero line causes confusion.  See #35652.
-				if b.Pos == src.NoXPos {
-					b.Pos = pp.Text.Pos // Sometimes p.Pos is empty.  See #35695.
-				}
-			}
-			b.Pos = b.Pos.WithBogusLine() // Debuggers are not good about infinite loops, force a change in line number
-		}
-		// Emit control flow instructions for block
-		var next *ssa.Block
-		if i < len(f.Blocks)-1 && Debug.N == 0 {
-			// If -N, leave next==nil so every block with successors
-			// ends in a JMP (except call blocks - plive doesn't like
-			// select{send,recv} followed by a JMP call).  Helps keep
-			// line numbers for otherwise empty blocks.
-			next = f.Blocks[i+1]
-		}
-		x := s.pp.next
-		s.SetPos(b.Pos)
-		thearch.SSAGenBlock(&s, b, next)
-		if f.PrintOrHtmlSSA {
-			for ; x != s.pp.next; x = x.Link {
-				progToBlock[x] = b
-			}
-		}
-	}
-	if f.Blocks[len(f.Blocks)-1].Kind == ssa.BlockExit {
-		// We need the return address of a panic call to
-		// still be inside the function in question. So if
-		// it ends in a call which doesn't return, add a
-		// nop (which will never execute) after the call.
-		thearch.Ginsnop(pp)
-	}
-	if openDeferInfo != nil {
-		// When doing open-coded defers, generate a disconnected call to
-		// deferreturn and a return. This will be used to during panic
-		// recovery to unwind the stack and return back to the runtime.
-		s.pp.nextLive = s.livenessMap.deferreturn
-		gencallret(pp, Deferreturn)
-	}
-
-	if inlMarks != nil {
-		// We have some inline marks. Try to find other instructions we're
-		// going to emit anyway, and use those instructions instead of the
-		// inline marks.
-		for p := pp.Text; p != nil; p = p.Link {
-			if p.As == obj.ANOP || p.As == obj.AFUNCDATA || p.As == obj.APCDATA || p.As == obj.ATEXT || p.As == obj.APCALIGN || thearch.LinkArch.Family == sys.Wasm {
-				// Don't use 0-sized instructions as inline marks, because we need
-				// to identify inline mark instructions by pc offset.
-				// (Some of these instructions are sometimes zero-sized, sometimes not.
-				// We must not use anything that even might be zero-sized.)
-				// TODO: are there others?
-				continue
-			}
-			if _, ok := inlMarks[p]; ok {
-				// Don't use inline marks themselves. We don't know
-				// whether they will be zero-sized or not yet.
-				continue
-			}
-			pos := p.Pos.AtColumn1()
-			s := inlMarksByPos[pos]
-			if len(s) == 0 {
-				continue
-			}
-			for _, m := range s {
-				// We found an instruction with the same source position as
-				// some of the inline marks.
-				// Use this instruction instead.
-				p.Pos = p.Pos.WithIsStmt() // promote position to a statement
-				pp.curfn.Func.lsym.Func().AddInlMark(p, inlMarks[m])
-				// Make the inline mark a real nop, so it doesn't generate any code.
-				m.As = obj.ANOP
-				m.Pos = src.NoXPos
-				m.From = obj.Addr{}
-				m.To = obj.Addr{}
-			}
-			delete(inlMarksByPos, pos)
-		}
-		// Any unmatched inline marks now need to be added to the inlining tree (and will generate a nop instruction).
-		for _, p := range inlMarkList {
-			if p.As != obj.ANOP {
-				pp.curfn.Func.lsym.Func().AddInlMark(p, inlMarks[p])
-			}
-		}
-	}
-
-	if Ctxt.Flag_locationlists {
-		e.curfn.Func.DebugInfo = ssa.BuildFuncDebug(Ctxt, f, Debug_locationlist > 1, stackOffset)
-		bstart := s.bstart
-		// Note that at this moment, Prog.Pc is a sequence number; it's
-		// not a real PC until after assembly, so this mapping has to
-		// be done later.
-		e.curfn.Func.DebugInfo.GetPC = func(b, v ssa.ID) int64 {
-			switch v {
-			case ssa.BlockStart.ID:
-				if b == f.Entry.ID {
-					return 0 // Start at the very beginning, at the assembler-generated prologue.
-					// this should only happen for function args (ssa.OpArg)
-				}
-				return bstart[b].Pc
-			case ssa.BlockEnd.ID:
-				return e.curfn.Func.lsym.Size
-			default:
-				return valueToProgAfter[v].Pc
-			}
-		}
-	}
-
-	// Resolve branches, and relax DefaultStmt into NotStmt
-	for _, br := range s.Branches {
-		br.P.To.SetTarget(s.bstart[br.B.ID])
-		if br.P.Pos.IsStmt() != src.PosIsStmt {
-			br.P.Pos = br.P.Pos.WithNotStmt()
-		} else if v0 := br.B.FirstPossibleStmtValue(); v0 != nil && v0.Pos.Line() == br.P.Pos.Line() && v0.Pos.IsStmt() == src.PosIsStmt {
-			br.P.Pos = br.P.Pos.WithNotStmt()
-		}
-
-	}
-
-	if e.log { // spew to stdout
-		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 := progToValue[p]; ok {
-				s = v.String()
-			} else if b, ok := progToBlock[p]; ok {
-				s = b.String()
-			} else {
-				s = "   " // most value and branch strings are 2-3 characters long
-			}
-			f.Logf(" %-6s\t%.5d (%s)\t%s\n", s, p.Pc, p.InnermostLineNumber(), p.InstructionString())
-		}
-	}
-	if f.HTMLWriter != nil { // spew to ssa.html
-		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 := progToValue[p]; ok {
-				buf.WriteString(v.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(fmt.Sprintf("%.5d <span class=\"l%v line-number\">(%s)</span> %s", p.Pc, p.InnermostLineNumber(), p.InnermostLineNumberHTML(), html.EscapeString(p.InstructionString())))
-			buf.WriteString("</dd>")
-		}
-		buf.WriteString("</dl>")
-		buf.WriteString("</code>")
-		f.HTMLWriter.WriteColumn("genssa", "genssa", "ssa-prog", buf.String())
-	}
-
-	defframe(&s, e)
-
-	f.HTMLWriter.Close()
-	f.HTMLWriter = nil
-}
-
-func defframe(s *SSAGenState, e *ssafn) {
-	pp := s.pp
-
-	frame := Rnd(s.maxarg+e.stksize, int64(Widthreg))
-	if thearch.PadFrame != nil {
-		frame = thearch.PadFrame(frame)
-	}
-
-	// Fill in argument and frame size.
-	pp.Text.To.Type = obj.TYPE_TEXTSIZE
-	pp.Text.To.Val = int32(Rnd(e.curfn.Type.ArgWidth(), int64(Widthreg)))
-	pp.Text.To.Offset = frame
-
-	// Insert code to zero ambiguously live variables so that the
-	// garbage collector only sees initialized values when it
-	// looks for pointers.
-	p := pp.Text
-	var lo, hi int64
-
-	// Opaque state for backend to use. Current backends use it to
-	// keep track of which helper registers have been zeroed.
-	var state uint32
-
-	// Iterate through declarations. They are sorted in decreasing Xoffset order.
-	for _, n := range e.curfn.Func.Dcl {
-		if !n.Name.Needzero() {
-			continue
-		}
-		if n.Class() != PAUTO {
-			e.Fatalf(n.Pos, "needzero class %d", n.Class())
-		}
-		if n.Type.Size()%int64(Widthptr) != 0 || n.Xoffset%int64(Widthptr) != 0 || n.Type.Size() == 0 {
-			e.Fatalf(n.Pos, "var %L has size %d offset %d", n, n.Type.Size(), n.Xoffset)
-		}
-
-		if lo != hi && n.Xoffset+n.Type.Size() >= lo-int64(2*Widthreg) {
-			// Merge with range we already have.
-			lo = n.Xoffset
-			continue
-		}
-
-		// Zero old range
-		p = thearch.ZeroRange(pp, p, frame+lo, hi-lo, &state)
-
-		// Set new range.
-		lo = n.Xoffset
-		hi = lo + n.Type.Size()
-	}
-
-	// Zero final range.
-	thearch.ZeroRange(pp, p, frame+lo, hi-lo, &state)
-}
-
-// For generating consecutive jump instructions to model a specific branching
-type IndexJump struct {
-	Jump  obj.As
-	Index int
-}
-
-func (s *SSAGenState) oneJump(b *ssa.Block, jump *IndexJump) {
-	p := s.Br(jump.Jump, b.Succs[jump.Index].Block())
-	p.Pos = b.Pos
-}
-
-// CombJump generates combinational instructions (2 at present) for a block jump,
-// thereby the behaviour of non-standard condition codes could be simulated
-func (s *SSAGenState) CombJump(b, next *ssa.Block, jumps *[2][2]IndexJump) {
-	switch next {
-	case b.Succs[0].Block():
-		s.oneJump(b, &jumps[0][0])
-		s.oneJump(b, &jumps[0][1])
-	case b.Succs[1].Block():
-		s.oneJump(b, &jumps[1][0])
-		s.oneJump(b, &jumps[1][1])
-	default:
-		var q *obj.Prog
-		if b.Likely != ssa.BranchUnlikely {
-			s.oneJump(b, &jumps[1][0])
-			s.oneJump(b, &jumps[1][1])
-			q = s.Br(obj.AJMP, b.Succs[1].Block())
-		} else {
-			s.oneJump(b, &jumps[0][0])
-			s.oneJump(b, &jumps[0][1])
-			q = s.Br(obj.AJMP, b.Succs[0].Block())
-		}
-		q.Pos = b.Pos
-	}
-}
-
-// AddAux adds the offset in the aux fields (AuxInt and Aux) of v to a.
-func AddAux(a *obj.Addr, v *ssa.Value) {
-	AddAux2(a, v, v.AuxInt)
-}
-func AddAux2(a *obj.Addr, v *ssa.Value, offset int64) {
-	if a.Type != obj.TYPE_MEM && a.Type != obj.TYPE_ADDR {
-		v.Fatalf("bad AddAux addr %v", a)
-	}
-	// add integer offset
-	a.Offset += offset
-
-	// If no additional symbol offset, we're done.
-	if v.Aux == nil {
-		return
-	}
-	// Add symbol's offset from its base register.
-	switch n := v.Aux.(type) {
-	case *ssa.AuxCall:
-		a.Name = obj.NAME_EXTERN
-		a.Sym = n.Fn
-	case *obj.LSym:
-		a.Name = obj.NAME_EXTERN
-		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
-	default:
-		v.Fatalf("aux in %s not implemented %#v", v, v.Aux)
-	}
-}
-
-// extendIndex extends v to a full int width.
-// panic with the given kind if v does not fit in an int (only on 32-bit archs).
-func (s *state) extendIndex(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value {
-	size := idx.Type.Size()
-	if size == s.config.PtrSize {
-		return idx
-	}
-	if size > s.config.PtrSize {
-		// truncate 64-bit indexes on 32-bit pointer archs. Test the
-		// high word and branch to out-of-bounds failure if it is not 0.
-		var lo *ssa.Value
-		if idx.Type.IsSigned() {
-			lo = s.newValue1(ssa.OpInt64Lo, types.Types[TINT], idx)
-		} else {
-			lo = s.newValue1(ssa.OpInt64Lo, types.Types[TUINT], idx)
-		}
-		if bounded || Debug.B != 0 {
-			return lo
-		}
-		bNext := s.f.NewBlock(ssa.BlockPlain)
-		bPanic := s.f.NewBlock(ssa.BlockExit)
-		hi := s.newValue1(ssa.OpInt64Hi, types.Types[TUINT32], idx)
-		cmp := s.newValue2(ssa.OpEq32, types.Types[TBOOL], hi, s.constInt32(types.Types[TUINT32], 0))
-		if !idx.Type.IsSigned() {
-			switch kind {
-			case ssa.BoundsIndex:
-				kind = ssa.BoundsIndexU
-			case ssa.BoundsSliceAlen:
-				kind = ssa.BoundsSliceAlenU
-			case ssa.BoundsSliceAcap:
-				kind = ssa.BoundsSliceAcapU
-			case ssa.BoundsSliceB:
-				kind = ssa.BoundsSliceBU
-			case ssa.BoundsSlice3Alen:
-				kind = ssa.BoundsSlice3AlenU
-			case ssa.BoundsSlice3Acap:
-				kind = ssa.BoundsSlice3AcapU
-			case ssa.BoundsSlice3B:
-				kind = ssa.BoundsSlice3BU
-			case ssa.BoundsSlice3C:
-				kind = ssa.BoundsSlice3CU
-			}
-		}
-		b := s.endBlock()
-		b.Kind = ssa.BlockIf
-		b.SetControl(cmp)
-		b.Likely = ssa.BranchLikely
-		b.AddEdgeTo(bNext)
-		b.AddEdgeTo(bPanic)
-
-		s.startBlock(bPanic)
-		mem := s.newValue4I(ssa.OpPanicExtend, types.TypeMem, int64(kind), hi, lo, len, s.mem())
-		s.endBlock().SetControl(mem)
-		s.startBlock(bNext)
-
-		return lo
-	}
-
-	// Extend value to the required size
-	var op ssa.Op
-	if idx.Type.IsSigned() {
-		switch 10*size + s.config.PtrSize {
-		case 14:
-			op = ssa.OpSignExt8to32
-		case 18:
-			op = ssa.OpSignExt8to64
-		case 24:
-			op = ssa.OpSignExt16to32
-		case 28:
-			op = ssa.OpSignExt16to64
-		case 48:
-			op = ssa.OpSignExt32to64
-		default:
-			s.Fatalf("bad signed index extension %s", idx.Type)
-		}
-	} else {
-		switch 10*size + s.config.PtrSize {
-		case 14:
-			op = ssa.OpZeroExt8to32
-		case 18:
-			op = ssa.OpZeroExt8to64
-		case 24:
-			op = ssa.OpZeroExt16to32
-		case 28:
-			op = ssa.OpZeroExt16to64
-		case 48:
-			op = ssa.OpZeroExt32to64
-		default:
-			s.Fatalf("bad unsigned index extension %s", idx.Type)
-		}
-	}
-	return s.newValue1(op, types.Types[TINT], idx)
-}
-
-// CheckLoweredPhi checks that regalloc and stackalloc correctly handled phi values.
-// Called during ssaGenValue.
-func CheckLoweredPhi(v *ssa.Value) {
-	if v.Op != ssa.OpPhi {
-		v.Fatalf("CheckLoweredPhi called with non-phi value: %v", v.LongString())
-	}
-	if v.Type.IsMemory() {
-		return
-	}
-	f := v.Block.Func
-	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 @ %s, but arg %v @ %s\n%s\n", v, loc, a, aloc, v.Block.Func)
-		}
-	}
-}
-
-// CheckLoweredGetClosurePtr checks that v is the first instruction in the function's entry block.
-// The output of LoweredGetClosurePtr is generally hardwired to the correct register.
-// That register contains the closure pointer on closure entry.
-func CheckLoweredGetClosurePtr(v *ssa.Value) {
-	entry := v.Block.Func.Entry
-	if entry != v.Block || entry.Values[0] != v {
-		Fatalf("in %s, badly placed LoweredGetClosurePtr: %v %v", v.Block.Func.Name, v.Block, v)
-	}
-}
-
-// AutoVar returns a *Node and int64 representing the auto variable and offset within it
-// where v should be spilled.
-func AutoVar(v *ssa.Value) (*Node, int64) {
-	loc := v.Block.Func.RegAlloc[v.ID].(ssa.LocalSlot)
-	if v.Type.Size() > loc.Type.Size() {
-		v.Fatalf("spill/restore type %s doesn't fit in slot type %s", v.Type, loc.Type)
-	}
-	return loc.N.(*Node), loc.Off
-}
-
-func AddrAuto(a *obj.Addr, v *ssa.Value) {
-	n, off := AutoVar(v)
-	a.Type = obj.TYPE_MEM
-	a.Sym = n.Sym.Linksym()
-	a.Reg = int16(thearch.REGSP)
-	a.Offset = n.Xoffset + off
-	if n.Class() == PPARAM || n.Class() == PPARAMOUT {
-		a.Name = obj.NAME_PARAM
-	} else {
-		a.Name = obj.NAME_AUTO
-	}
-}
-
-func (s *SSAGenState) AddrScratch(a *obj.Addr) {
-	if s.ScratchFpMem == nil {
-		panic("no scratch memory available; forgot to declare usesScratch for Op?")
-	}
-	a.Type = obj.TYPE_MEM
-	a.Name = obj.NAME_AUTO
-	a.Sym = s.ScratchFpMem.Sym.Linksym()
-	a.Reg = int16(thearch.REGSP)
-	a.Offset = s.ScratchFpMem.Xoffset
-}
-
-// Call returns a new CALL instruction for the SSA value v.
-// It uses PrepareCall to prepare the call.
-func (s *SSAGenState) Call(v *ssa.Value) *obj.Prog {
-	pPosIsStmt := s.pp.pos.IsStmt() // The statement-ness fo the call comes from ssaGenState
-	s.PrepareCall(v)
-
-	p := s.Prog(obj.ACALL)
-	if pPosIsStmt == src.PosIsStmt {
-		p.Pos = v.Pos.WithIsStmt()
-	} else {
-		p.Pos = v.Pos.WithNotStmt()
-	}
-	if sym, ok := v.Aux.(*ssa.AuxCall); ok && sym.Fn != nil {
-		p.To.Type = obj.TYPE_MEM
-		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = sym.Fn
-	} else {
-		// TODO(mdempsky): Can these differences be eliminated?
-		switch thearch.LinkArch.Family {
-		case sys.AMD64, sys.I386, sys.PPC64, sys.RISCV64, sys.S390X, sys.Wasm:
-			p.To.Type = obj.TYPE_REG
-		case sys.ARM, sys.ARM64, sys.MIPS, sys.MIPS64:
-			p.To.Type = obj.TYPE_MEM
-		default:
-			Fatalf("unknown indirect call family")
-		}
-		p.To.Reg = v.Args[0].Reg()
-	}
-	return p
-}
-
-// PrepareCall prepares to emit a CALL instruction for v and does call-related bookkeeping.
-// It must be called immediately before emitting the actual CALL instruction,
-// since it emits PCDATA for the stack map at the call (calls are safe points).
-func (s *SSAGenState) PrepareCall(v *ssa.Value) {
-	idx := s.livenessMap.Get(v)
-	if !idx.StackMapValid() {
-		// See Liveness.hasStackMap.
-		if sym, ok := v.Aux.(*ssa.AuxCall); !ok || !(sym.Fn == typedmemclr || sym.Fn == typedmemmove) {
-			Fatalf("missing stack map index for %v", v.LongString())
-		}
-	}
-
-	call, ok := v.Aux.(*ssa.AuxCall)
-
-	if ok && call.Fn == Deferreturn {
-		// Deferred calls will appear to be returning to
-		// the CALL deferreturn(SB) that we are about to emit.
-		// However, the stack trace code will show the line
-		// of the instruction byte before the return PC.
-		// To avoid that being an unrelated instruction,
-		// insert an actual hardware NOP that will have the right line number.
-		// This is different from obj.ANOP, which is a virtual no-op
-		// that doesn't make it into the instruction stream.
-		thearch.Ginsnopdefer(s.pp)
-	}
-
-	if ok {
-		// Record call graph information for nowritebarrierrec
-		// analysis.
-		if nowritebarrierrecCheck != nil {
-			nowritebarrierrecCheck.recordCall(s.pp.curfn, call.Fn, v.Pos)
-		}
-	}
-
-	if s.maxarg < v.AuxInt {
-		s.maxarg = v.AuxInt
-	}
-}
-
-// UseArgs records the fact that an instruction needs a certain amount of
-// callee args space for its use.
-func (s *SSAGenState) UseArgs(n int64) {
-	if s.maxarg < n {
-		s.maxarg = n
-	}
-}
-
-// fieldIdx finds the index of the field referred to by the ODOT node n.
-func fieldIdx(n *Node) int {
-	t := n.Left.Type
-	f := n.Sym
-	if !t.IsStruct() {
-		panic("ODOT's LHS is not a struct")
-	}
-
-	var i int
-	for _, t1 := range t.Fields().Slice() {
-		if t1.Sym != f {
-			i++
-			continue
-		}
-		if t1.Offset != n.Xoffset {
-			panic("field offset doesn't match")
-		}
-		return i
-	}
-	panic(fmt.Sprintf("can't find field in expr %v\n", n))
-
-	// TODO: keep the result of this function somewhere in the ODOT Node
-	// so we don't have to recompute it each time we need it.
-}
-
-// ssafn holds frontend information about a function that the backend is processing.
-// It also exports a bunch of compiler services for the ssa backend.
-type ssafn struct {
-	curfn        *Node
-	strings      map[string]*obj.LSym // map from constant string to data symbols
-	scratchFpMem *Node                // temp for floating point register / memory moves on some architectures
-	stksize      int64                // stack size for current frame
-	stkptrsize   int64                // prefix of stack containing pointers
-	log          bool                 // print ssa debug to the stdout
-}
-
-// StringData returns a symbol which
-// is the data component of a global string constant containing s.
-func (e *ssafn) StringData(s string) *obj.LSym {
-	if aux, ok := e.strings[s]; ok {
-		return aux
-	}
-	if e.strings == nil {
-		e.strings = make(map[string]*obj.LSym)
-	}
-	data := stringsym(e.curfn.Pos, s)
-	e.strings[s] = data
-	return data
-}
-
-func (e *ssafn) Auto(pos src.XPos, t *types.Type) ssa.GCNode {
-	n := tempAt(pos, e.curfn, t) // Note: adds new auto to e.curfn.Func.Dcl list
-	return n
-}
-
-func (e *ssafn) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
-	ptrType := types.NewPtr(types.Types[TUINT8])
-	lenType := types.Types[TINT]
-	// Split this string up into two separate variables.
-	p := e.SplitSlot(&name, ".ptr", 0, ptrType)
-	l := e.SplitSlot(&name, ".len", ptrType.Size(), lenType)
-	return p, l
-}
-
-func (e *ssafn) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
-	n := name.N.(*Node)
-	u := types.Types[TUINTPTR]
-	t := types.NewPtr(types.Types[TUINT8])
-	// Split this interface up into two separate variables.
-	f := ".itab"
-	if n.Type.IsEmptyInterface() {
-		f = ".type"
-	}
-	c := e.SplitSlot(&name, f, 0, u) // see comment in plive.go:onebitwalktype1.
-	d := e.SplitSlot(&name, ".data", u.Size(), t)
-	return c, d
-}
-
-func (e *ssafn) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot, ssa.LocalSlot) {
-	ptrType := types.NewPtr(name.Type.Elem())
-	lenType := types.Types[TINT]
-	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
-}
-
-func (e *ssafn) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
-	s := name.Type.Size() / 2
-	var t *types.Type
-	if s == 8 {
-		t = types.Types[TFLOAT64]
-	} else {
-		t = types.Types[TFLOAT32]
-	}
-	r := e.SplitSlot(&name, ".real", 0, t)
-	i := e.SplitSlot(&name, ".imag", t.Size(), t)
-	return r, i
-}
-
-func (e *ssafn) SplitInt64(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
-	var t *types.Type
-	if name.Type.IsSigned() {
-		t = types.Types[TINT32]
-	} else {
-		t = types.Types[TUINT32]
-	}
-	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])
-}
-
-func (e *ssafn) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
-	st := name.Type
-	// Note: the _ field may appear several times.  But
-	// have no fear, identically-named but distinct Autos are
-	// ok, albeit maybe confusing for a debugger.
-	return e.SplitSlot(&name, "."+st.FieldName(i), st.FieldOff(i), st.FieldType(i))
-}
-
-func (e *ssafn) SplitArray(name ssa.LocalSlot) ssa.LocalSlot {
-	n := name.N.(*Node)
-	at := name.Type
-	if at.NumElem() != 1 {
-		e.Fatalf(n.Pos, "bad array size")
-	}
-	et := at.Elem()
-	return e.SplitSlot(&name, "[0]", 0, et)
-}
-
-func (e *ssafn) DerefItab(it *obj.LSym, offset int64) *obj.LSym {
-	return itabsym(it, offset)
-}
-
-// 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 {
-	node := parent.N.(*Node)
-
-	if node.Class() != PAUTO || node.Name.Addrtaken() {
-		// addressed things and non-autos retain their parents (i.e., cannot truly be split)
-		return ssa.LocalSlot{N: node, Type: t, Off: parent.Off + offset}
-	}
-
-	s := &types.Sym{Name: node.Sym.Name + suffix, Pkg: localpkg}
-
-	n := &Node{
-		Name: new(Name),
-		Op:   ONAME,
-		Pos:  parent.N.(*Node).Pos,
-	}
-	n.Orig = n
-
-	s.Def = asTypesNode(n)
-	asNode(s.Def).Name.SetUsed(true)
-	n.Sym = s
-	n.Type = t
-	n.SetClass(PAUTO)
-	n.Esc = EscNever
-	n.Name.Curfn = e.curfn
-	e.curfn.Func.Dcl = append(e.curfn.Func.Dcl, n)
-	dowidth(t)
-	return ssa.LocalSlot{N: n, Type: t, Off: 0, SplitOf: parent, SplitOffset: offset}
-}
-
-func (e *ssafn) CanSSA(t *types.Type) bool {
-	return canSSAType(t)
-}
-
-func (e *ssafn) Line(pos src.XPos) string {
-	return linestr(pos)
-}
-
-// Log logs a message from the compiler.
-func (e *ssafn) Logf(msg string, args ...interface{}) {
-	if e.log {
-		fmt.Printf(msg, args...)
-	}
-}
-
-func (e *ssafn) Log() bool {
-	return e.log
-}
-
-// Fatal reports a compiler error and exits.
-func (e *ssafn) Fatalf(pos src.XPos, msg string, args ...interface{}) {
-	lineno = pos
-	nargs := append([]interface{}{e.curfn.funcname()}, args...)
-	Fatalf("'%s': "+msg, nargs...)
-}
-
-// Warnl reports a "warning", which is usually flag-triggered
-// logging output for the benefit of tests.
-func (e *ssafn) Warnl(pos src.XPos, fmt_ string, args ...interface{}) {
-	Warnl(pos, fmt_, args...)
-}
-
-func (e *ssafn) Debug_checknil() bool {
-	return Debug_checknil != 0
-}
-
-func (e *ssafn) UseWriteBarrier() bool {
-	return use_writebarrier
-}
-
-func (e *ssafn) Syslook(name string) *obj.LSym {
-	switch name {
-	case "goschedguarded":
-		return goschedguarded
-	case "writeBarrier":
-		return writeBarrier
-	case "gcWriteBarrier":
-		return gcWriteBarrier
-	case "typedmemmove":
-		return typedmemmove
-	case "typedmemclr":
-		return typedmemclr
-	}
-	e.Fatalf(src.NoXPos, "unknown Syslook func %v", name)
-	return nil
-}
-
-func (e *ssafn) SetWBPos(pos src.XPos) {
-	e.curfn.Func.setWBPos(pos)
-}
-
-func (e *ssafn) MyImportPath() string {
-	return myimportpath
-}
-
-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("untranslatable storage class for %v: %s", n, n.Class())
-		return 0
-	}
-}
-
-func clobberBase(n *Node) *Node {
-	if n.Op == ODOT && n.Left.Type.NumFields() == 1 {
-		return clobberBase(n.Left)
-	}
-	if n.Op == OINDEX && n.Left.Type.IsArray() && n.Left.Type.NumElem() == 1 {
-		return clobberBase(n.Left)
-	}
-	return n
-}
diff --git a/src/cmd/compile/internal/gc/ssa_test.go b/src/cmd/compile/internal/gc/ssa_test.go
deleted file mode 100644
index 7f7c946..0000000
--- a/src/cmd/compile/internal/gc/ssa_test.go
+++ /dev/null
@@ -1,191 +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 gc
-
-import (
-	"bytes"
-	"fmt"
-	"go/ast"
-	"go/parser"
-	"go/token"
-	"internal/testenv"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"testing"
-)
-
-// 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) {
-	if testing.Short() {
-		t.Skip("not run in short mode.")
-	}
-	runGenTest(t, "flowgraph_generator1.go", "ssa_fg_tmp1")
-}
-
-// TestCode runs all the tests in the testdata directory as subtests.
-// These tests are special because we want to run them with different
-// compiler flags set (and thus they can't just be _test.go files in
-// this directory).
-func TestCode(t *testing.T) {
-	testenv.MustHaveGoBuild(t)
-	gotool := testenv.GoToolPath(t)
-
-	// Make a temporary directory to work in.
-	tmpdir, err := ioutil.TempDir("", "TestCode")
-	if err != nil {
-		t.Fatalf("Failed to create temporary directory: %v", err)
-	}
-	defer os.RemoveAll(tmpdir)
-
-	// Find all the test functions (and the files containing them).
-	var srcs []string // files containing Test functions
-	type test struct {
-		name      string // TestFoo
-		usesFloat bool   // might use float operations
-	}
-	var tests []test
-	files, err := ioutil.ReadDir("testdata")
-	if err != nil {
-		t.Fatalf("can't read testdata directory: %v", err)
-	}
-	for _, f := range files {
-		if !strings.HasSuffix(f.Name(), "_test.go") {
-			continue
-		}
-		text, err := ioutil.ReadFile(filepath.Join("testdata", f.Name()))
-		if err != nil {
-			t.Fatalf("can't read testdata/%s: %v", f.Name(), err)
-		}
-		fset := token.NewFileSet()
-		code, err := parser.ParseFile(fset, f.Name(), text, 0)
-		if err != nil {
-			t.Fatalf("can't parse testdata/%s: %v", f.Name(), err)
-		}
-		srcs = append(srcs, filepath.Join("testdata", f.Name()))
-		foundTest := false
-		for _, d := range code.Decls {
-			fd, ok := d.(*ast.FuncDecl)
-			if !ok {
-				continue
-			}
-			if !strings.HasPrefix(fd.Name.Name, "Test") {
-				continue
-			}
-			if fd.Recv != nil {
-				continue
-			}
-			if fd.Type.Results != nil {
-				continue
-			}
-			if len(fd.Type.Params.List) != 1 {
-				continue
-			}
-			p := fd.Type.Params.List[0]
-			if len(p.Names) != 1 {
-				continue
-			}
-			s, ok := p.Type.(*ast.StarExpr)
-			if !ok {
-				continue
-			}
-			sel, ok := s.X.(*ast.SelectorExpr)
-			if !ok {
-				continue
-			}
-			base, ok := sel.X.(*ast.Ident)
-			if !ok {
-				continue
-			}
-			if base.Name != "testing" {
-				continue
-			}
-			if sel.Sel.Name != "T" {
-				continue
-			}
-			// Found a testing function.
-			tests = append(tests, test{name: fd.Name.Name, usesFloat: bytes.Contains(text, []byte("float"))})
-			foundTest = true
-		}
-		if !foundTest {
-			t.Fatalf("test file testdata/%s has no tests in it", f.Name())
-		}
-	}
-
-	flags := []string{""}
-	if runtime.GOARCH == "arm" || runtime.GOARCH == "mips" || runtime.GOARCH == "mips64" {
-		flags = append(flags, ",softfloat")
-	}
-	for _, flag := range flags {
-		args := []string{"test", "-c", "-gcflags=-d=ssa/check/on" + flag, "-o", filepath.Join(tmpdir, "code.test")}
-		args = append(args, srcs...)
-		out, err := exec.Command(gotool, args...).CombinedOutput()
-		if err != nil || len(out) != 0 {
-			t.Fatalf("Build failed: %v\n%s\n", err, out)
-		}
-
-		// Now we have a test binary. Run it with all the tests as subtests of this one.
-		for _, test := range tests {
-			test := test
-			if flag == ",softfloat" && !test.usesFloat {
-				// No point in running the soft float version if the test doesn't use floats.
-				continue
-			}
-			t.Run(fmt.Sprintf("%s%s", test.name[4:], flag), func(t *testing.T) {
-				out, err := exec.Command(filepath.Join(tmpdir, "code.test"), "-test.run="+test.name).CombinedOutput()
-				if err != nil || string(out) != "PASS\n" {
-					t.Errorf("Failed:\n%s\n", out)
-				}
-			})
-		}
-	}
-}
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
deleted file mode 100644
index defefd7..0000000
--- a/src/cmd/compile/internal/gc/subr.go
+++ /dev/null
@@ -1,1918 +0,0 @@
-// Copyright 2009 The Go Authors. 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/compile/internal/types"
-	"cmd/internal/objabi"
-	"cmd/internal/src"
-	"crypto/md5"
-	"encoding/binary"
-	"fmt"
-	"os"
-	"runtime/debug"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-	"unicode"
-	"unicode/utf8"
-)
-
-type Error struct {
-	pos src.XPos
-	msg string
-}
-
-var errors []Error
-
-// largeStack is info about a function whose stack frame is too large (rare).
-type largeStack struct {
-	locals int64
-	args   int64
-	callee int64
-	pos    src.XPos
-}
-
-var (
-	largeStackFramesMu sync.Mutex // protects largeStackFrames
-	largeStackFrames   []largeStack
-)
-
-func errorexit() {
-	flusherrors()
-	if outfile != "" {
-		os.Remove(outfile)
-	}
-	os.Exit(2)
-}
-
-func adderrorname(n *Node) {
-	if n.Op != ODOT {
-		return
-	}
-	old := fmt.Sprintf("%v: undefined: %v\n", n.Line(), n.Left)
-	if len(errors) > 0 && errors[len(errors)-1].pos.Line() == n.Pos.Line() && errors[len(errors)-1].msg == old {
-		errors[len(errors)-1].msg = fmt.Sprintf("%v: undefined: %v in %v\n", n.Line(), n.Left, n)
-	}
-}
-
-func adderr(pos src.XPos, format string, args ...interface{}) {
-	msg := fmt.Sprintf(format, args...)
-	// Only add the position if know the position.
-	// See issue golang.org/issue/11361.
-	if pos.IsKnown() {
-		msg = fmt.Sprintf("%v: %s", linestr(pos), msg)
-	}
-	errors = append(errors, Error{
-		pos: pos,
-		msg: msg + "\n",
-	})
-}
-
-// byPos sorts errors by source position.
-type byPos []Error
-
-func (x byPos) Len() int           { return len(x) }
-func (x byPos) Less(i, j int) bool { return x[i].pos.Before(x[j].pos) }
-func (x byPos) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-
-// flusherrors sorts errors seen so far by line number, prints them to stdout,
-// and empties the errors array.
-func flusherrors() {
-	Ctxt.Bso.Flush()
-	if len(errors) == 0 {
-		return
-	}
-	sort.Stable(byPos(errors))
-	for i, err := range errors {
-		if i == 0 || err.msg != errors[i-1].msg {
-			fmt.Printf("%s", err.msg)
-		}
-	}
-	errors = errors[:0]
-}
-
-func hcrash() {
-	if Debug.h != 0 {
-		flusherrors()
-		if outfile != "" {
-			os.Remove(outfile)
-		}
-		var x *int
-		*x = 0
-	}
-}
-
-func linestr(pos src.XPos) string {
-	return Ctxt.OutermostPos(pos).Format(Debug.C == 0, Debug.L == 1)
-}
-
-// lasterror keeps track of the most recently issued error.
-// It is used to avoid multiple error messages on the same
-// line.
-var lasterror struct {
-	syntax src.XPos // source position of last syntax error
-	other  src.XPos // source position of last non-syntax error
-	msg    string   // error message of last non-syntax error
-}
-
-// sameline reports whether two positions a, b are on the same line.
-func sameline(a, b src.XPos) bool {
-	p := Ctxt.PosTable.Pos(a)
-	q := Ctxt.PosTable.Pos(b)
-	return p.Base() == q.Base() && p.Line() == q.Line()
-}
-
-func yyerrorl(pos src.XPos, format string, args ...interface{}) {
-	msg := fmt.Sprintf(format, args...)
-
-	if strings.HasPrefix(msg, "syntax error") {
-		nsyntaxerrors++
-		// only one syntax error per line, no matter what error
-		if sameline(lasterror.syntax, pos) {
-			return
-		}
-		lasterror.syntax = pos
-	} else {
-		// only one of multiple equal non-syntax errors per line
-		// (flusherrors shows only one of them, so we filter them
-		// here as best as we can (they may not appear in order)
-		// so that we don't count them here and exit early, and
-		// then have nothing to show for.)
-		if sameline(lasterror.other, pos) && lasterror.msg == msg {
-			return
-		}
-		lasterror.other = pos
-		lasterror.msg = msg
-	}
-
-	adderr(pos, "%s", msg)
-
-	hcrash()
-	nerrors++
-	if nsavederrors+nerrors >= 10 && Debug.e == 0 {
-		flusherrors()
-		fmt.Printf("%v: too many errors\n", linestr(pos))
-		errorexit()
-	}
-}
-
-func yyerrorv(lang string, format string, args ...interface{}) {
-	what := fmt.Sprintf(format, args...)
-	yyerrorl(lineno, "%s requires %s or later (-lang was set to %s; check go.mod)", what, lang, flag_lang)
-}
-
-func yyerror(format string, args ...interface{}) {
-	yyerrorl(lineno, format, args...)
-}
-
-func Warn(fmt_ string, args ...interface{}) {
-	Warnl(lineno, fmt_, args...)
-}
-
-func Warnl(line src.XPos, fmt_ string, args ...interface{}) {
-	adderr(line, fmt_, args...)
-	if Debug.m != 0 {
-		flusherrors()
-	}
-}
-
-func Fatalf(fmt_ string, args ...interface{}) {
-	flusherrors()
-
-	if Debug_panic != 0 || nsavederrors+nerrors == 0 {
-		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, "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()
-	errorexit()
-}
-
-// hasUniquePos reports whether n has a unique position that can be
-// used for reporting error messages.
-//
-// It's primarily used to distinguish references to named objects,
-// whose Pos will point back to their declaration position rather than
-// their usage position.
-func hasUniquePos(n *Node) bool {
-	switch n.Op {
-	case ONAME, OPACK:
-		return false
-	case OLITERAL, OTYPE:
-		if n.Sym != nil {
-			return false
-		}
-	}
-
-	if !n.Pos.IsKnown() {
-		if Debug.K != 0 {
-			Warn("setlineno: unknown position (line 0)")
-		}
-		return false
-	}
-
-	return true
-}
-
-func setlineno(n *Node) src.XPos {
-	lno := lineno
-	if n != nil && hasUniquePos(n) {
-		lineno = n.Pos
-	}
-	return lno
-}
-
-func lookup(name string) *types.Sym {
-	return localpkg.Lookup(name)
-}
-
-// lookupN looks up the symbol starting with prefix and ending with
-// the decimal n. If prefix is too long, lookupN panics.
-func lookupN(prefix string, n int) *types.Sym {
-	var buf [20]byte // plenty long enough for all current users
-	copy(buf[:], prefix)
-	b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10)
-	return localpkg.LookupBytes(b)
-}
-
-// autolabel generates a new Name node for use with
-// an automatically generated label.
-// prefix is a short mnemonic (e.g. ".s" for switch)
-// to help with debugging.
-// It should begin with "." to avoid conflicts with
-// user labels.
-func autolabel(prefix string) *types.Sym {
-	if prefix[0] != '.' {
-		Fatalf("autolabel prefix must start with '.', have %q", prefix)
-	}
-	fn := Curfn
-	if Curfn == nil {
-		Fatalf("autolabel outside function")
-	}
-	n := fn.Func.Label
-	fn.Func.Label++
-	return lookupN(prefix, int(n))
-}
-
-// find all the exported symbols in package opkg
-// and make them available in the current package
-func importdot(opkg *types.Pkg, pack *Node) {
-	n := 0
-	for _, s := range opkg.Syms {
-		if s.Def == nil {
-			continue
-		}
-		if !types.IsExported(s.Name) || strings.ContainsRune(s.Name, 0xb7) { // 0xb7 = center dot
-			continue
-		}
-		s1 := lookup(s.Name)
-		if s1.Def != nil {
-			pkgerror := fmt.Sprintf("during import %q", opkg.Path)
-			redeclare(lineno, s1, pkgerror)
-			continue
-		}
-
-		s1.Def = s.Def
-		s1.Block = s.Block
-		if asNode(s1.Def).Name == nil {
-			Dump("s1def", asNode(s1.Def))
-			Fatalf("missing Name")
-		}
-		asNode(s1.Def).Name.Pack = pack
-		s1.Origpkg = opkg
-		n++
-	}
-
-	if n == 0 {
-		// can't possibly be used - there were no symbols
-		yyerrorl(pack.Pos, "imported and not used: %q", opkg.Path)
-	}
-}
-
-func nod(op Op, nleft, nright *Node) *Node {
-	return nodl(lineno, op, nleft, nright)
-}
-
-func nodl(pos src.XPos, op Op, nleft, nright *Node) *Node {
-	var n *Node
-	switch op {
-	case OCLOSURE, ODCLFUNC:
-		var x struct {
-			n Node
-			f Func
-		}
-		n = &x.n
-		n.Func = &x.f
-	case ONAME:
-		Fatalf("use newname instead")
-	case OLABEL, OPACK:
-		var x struct {
-			n Node
-			m Name
-		}
-		n = &x.n
-		n.Name = &x.m
-	default:
-		n = new(Node)
-	}
-	n.Op = op
-	n.Left = nleft
-	n.Right = nright
-	n.Pos = pos
-	n.Xoffset = BADWIDTH
-	n.Orig = n
-	return n
-}
-
-// newname returns a new ONAME Node associated with symbol s.
-func newname(s *types.Sym) *Node {
-	n := newnamel(lineno, s)
-	n.Name.Curfn = Curfn
-	return n
-}
-
-// newnamel returns a new ONAME Node associated with symbol s at position pos.
-// The caller is responsible for setting n.Name.Curfn.
-func newnamel(pos src.XPos, s *types.Sym) *Node {
-	if s == nil {
-		Fatalf("newnamel nil")
-	}
-
-	var x struct {
-		n Node
-		m Name
-		p Param
-	}
-	n := &x.n
-	n.Name = &x.m
-	n.Name.Param = &x.p
-
-	n.Op = ONAME
-	n.Pos = pos
-	n.Orig = n
-
-	n.Sym = s
-	return n
-}
-
-// nodSym makes a Node with Op op and with the Left field set to left
-// and the Sym field set to sym. This is for ODOT and friends.
-func nodSym(op Op, left *Node, sym *types.Sym) *Node {
-	return nodlSym(lineno, op, left, sym)
-}
-
-// nodlSym makes a Node with position Pos, with Op op, and with the Left field set to left
-// and the Sym field set to sym. This is for ODOT and friends.
-func nodlSym(pos src.XPos, op Op, left *Node, sym *types.Sym) *Node {
-	n := nodl(pos, op, left, nil)
-	n.Sym = sym
-	return n
-}
-
-// rawcopy returns a shallow copy of n.
-// Note: copy or sepcopy (rather than rawcopy) is usually the
-//       correct choice (see comment with Node.copy, below).
-func (n *Node) rawcopy() *Node {
-	copy := *n
-	return &copy
-}
-
-// sepcopy returns a separate shallow copy of n, with the copy's
-// Orig pointing to itself.
-func (n *Node) sepcopy() *Node {
-	copy := *n
-	copy.Orig = &copy
-	return &copy
-}
-
-// copy returns shallow copy of n and adjusts the copy's Orig if
-// necessary: In general, if n.Orig points to itself, the copy's
-// Orig should point to itself as well. Otherwise, if n is modified,
-// the copy's Orig node appears modified, too, and then doesn't
-// represent the original node anymore.
-// (This caused the wrong complit Op to be used when printing error
-// messages; see issues #26855, #27765).
-func (n *Node) copy() *Node {
-	copy := *n
-	if n.Orig == n {
-		copy.Orig = &copy
-	}
-	return &copy
-}
-
-// methcmp sorts methods by symbol.
-type methcmp []*types.Field
-
-func (x methcmp) Len() int           { return len(x) }
-func (x methcmp) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x methcmp) Less(i, j int) bool { return x[i].Sym.Less(x[j].Sym) }
-
-func nodintconst(v int64) *Node {
-	u := new(Mpint)
-	u.SetInt64(v)
-	return nodlit(Val{u})
-}
-
-func nodnil() *Node {
-	return nodlit(Val{new(NilVal)})
-}
-
-func nodbool(b bool) *Node {
-	return nodlit(Val{b})
-}
-
-func nodstr(s string) *Node {
-	return nodlit(Val{s})
-}
-
-// treecopy recursively copies n, with the exception of
-// ONAME, OLITERAL, OTYPE, and ONONAME leaves.
-// If pos.IsKnown(), it sets the source position of newly
-// allocated nodes to pos.
-func treecopy(n *Node, pos src.XPos) *Node {
-	if n == nil {
-		return nil
-	}
-
-	switch n.Op {
-	default:
-		m := n.sepcopy()
-		m.Left = treecopy(n.Left, pos)
-		m.Right = treecopy(n.Right, pos)
-		m.List.Set(listtreecopy(n.List.Slice(), pos))
-		if pos.IsKnown() {
-			m.Pos = pos
-		}
-		if m.Name != nil && n.Op != ODCLFIELD {
-			Dump("treecopy", n)
-			Fatalf("treecopy Name")
-		}
-		return m
-
-	case OPACK:
-		// OPACK nodes are never valid in const value declarations,
-		// but allow them like any other declared symbol to avoid
-		// crashing (golang.org/issue/11361).
-		fallthrough
-
-	case ONAME, ONONAME, OLITERAL, OTYPE:
-		return n
-
-	}
-}
-
-// isNil reports whether n represents the universal untyped zero value "nil".
-func (n *Node) isNil() bool {
-	// Check n.Orig because constant propagation may produce typed nil constants,
-	// which don't exist in the Go spec.
-	return Isconst(n.Orig, CTNIL)
-}
-
-func isptrto(t *types.Type, et types.EType) bool {
-	if t == nil {
-		return false
-	}
-	if !t.IsPtr() {
-		return false
-	}
-	t = t.Elem()
-	if t == nil {
-		return false
-	}
-	if t.Etype != et {
-		return false
-	}
-	return true
-}
-
-func (n *Node) isBlank() bool {
-	if n == nil {
-		return false
-	}
-	return n.Sym.IsBlank()
-}
-
-// methtype returns the underlying type, if any,
-// that owns methods with receiver parameter t.
-// The result is either a named type or an anonymous struct.
-func methtype(t *types.Type) *types.Type {
-	if t == nil {
-		return nil
-	}
-
-	// Strip away pointer if it's there.
-	if t.IsPtr() {
-		if t.Sym != nil {
-			return nil
-		}
-		t = t.Elem()
-		if t == nil {
-			return nil
-		}
-	}
-
-	// Must be a named type or anonymous struct.
-	if t.Sym == nil && !t.IsStruct() {
-		return nil
-	}
-
-	// Check types.
-	if issimple[t.Etype] {
-		return t
-	}
-	switch t.Etype {
-	case TARRAY, TCHAN, TFUNC, TMAP, TSLICE, TSTRING, TSTRUCT:
-		return t
-	}
-	return nil
-}
-
-// Is type src assignment compatible to type dst?
-// If so, return op code to use in conversion.
-// If not, return OXXX. In this case, the string return parameter may
-// hold a reason why. In all other cases, it'll be the empty string.
-func assignop(src, dst *types.Type) (Op, string) {
-	if src == dst {
-		return OCONVNOP, ""
-	}
-	if src == nil || dst == nil || src.Etype == TFORW || dst.Etype == TFORW || src.Orig == nil || dst.Orig == nil {
-		return OXXX, ""
-	}
-
-	// 1. src type is identical to dst.
-	if types.Identical(src, dst) {
-		return OCONVNOP, ""
-	}
-
-	// 2. src and dst have identical underlying types
-	// and either src or dst is not a named type or
-	// both are empty interface types.
-	// For assignable but different non-empty interface types,
-	// we want to recompute the itab. Recomputing the itab ensures
-	// that itabs are unique (thus an interface with a compile-time
-	// type I has an itab with interface type I).
-	if types.Identical(src.Orig, dst.Orig) {
-		if src.IsEmptyInterface() {
-			// Conversion between two empty interfaces
-			// requires no code.
-			return OCONVNOP, ""
-		}
-		if (src.Sym == nil || dst.Sym == nil) && !src.IsInterface() {
-			// Conversion between two types, at least one unnamed,
-			// needs no conversion. The exception is nonempty interfaces
-			// which need to have their itab updated.
-			return OCONVNOP, ""
-		}
-	}
-
-	// 3. dst is an interface type and src implements dst.
-	if dst.IsInterface() && src.Etype != TNIL {
-		var missing, have *types.Field
-		var ptr int
-		if implements(src, dst, &missing, &have, &ptr) {
-			return OCONVIFACE, ""
-		}
-
-		// we'll have complained about this method anyway, suppress spurious messages.
-		if have != nil && have.Sym == missing.Sym && (have.Type.Broke() || missing.Type.Broke()) {
-			return OCONVIFACE, ""
-		}
-
-		var why string
-		if isptrto(src, TINTER) {
-			why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src)
-		} else if have != nil && have.Sym == missing.Sym && have.Nointerface() {
-			why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym)
-		} else if have != nil && have.Sym == missing.Sym {
-			why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+
-				"\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
-		} else if ptr != 0 {
-			why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym)
-		} else if have != nil {
-			why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)\n"+
-				"\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
-		} else {
-			why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym)
-		}
-
-		return OXXX, why
-	}
-
-	if isptrto(dst, TINTER) {
-		why := fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst)
-		return OXXX, why
-	}
-
-	if src.IsInterface() && dst.Etype != TBLANK {
-		var missing, have *types.Field
-		var ptr int
-		var why string
-		if implements(dst, src, &missing, &have, &ptr) {
-			why = ": need type assertion"
-		}
-		return OXXX, why
-	}
-
-	// 4. src is a bidirectional channel value, dst is a channel type,
-	// src and dst have identical element types, and
-	// either src or dst is not a named type.
-	if src.IsChan() && src.ChanDir() == types.Cboth && dst.IsChan() {
-		if types.Identical(src.Elem(), dst.Elem()) && (src.Sym == nil || dst.Sym == nil) {
-			return OCONVNOP, ""
-		}
-	}
-
-	// 5. src is the predeclared identifier nil and dst is a nillable type.
-	if src.Etype == TNIL {
-		switch dst.Etype {
-		case TPTR,
-			TFUNC,
-			TMAP,
-			TCHAN,
-			TINTER,
-			TSLICE:
-			return OCONVNOP, ""
-		}
-	}
-
-	// 6. rule about untyped constants - already converted by defaultlit.
-
-	// 7. Any typed value can be assigned to the blank identifier.
-	if dst.Etype == TBLANK {
-		return OCONVNOP, ""
-	}
-
-	return OXXX, ""
-}
-
-// Can we convert a value of type src to a value of type dst?
-// If so, return op code to use in conversion (maybe OCONVNOP).
-// If not, return OXXX. In this case, the string return parameter may
-// hold a reason why. In all other cases, it'll be the empty string.
-// srcConstant indicates whether the value of type src is a constant.
-func convertop(srcConstant bool, src, dst *types.Type) (Op, string) {
-	if src == dst {
-		return OCONVNOP, ""
-	}
-	if src == nil || dst == nil {
-		return OXXX, ""
-	}
-
-	// Conversions from regular to go:notinheap are not allowed
-	// (unless it's unsafe.Pointer). These are runtime-specific
-	// rules.
-	// (a) Disallow (*T) to (*U) where T is go:notinheap but U isn't.
-	if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() {
-		why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable), but %v is not", dst.Elem(), src.Elem())
-		return OXXX, why
-	}
-	// (b) Disallow string to []T where T is go:notinheap.
-	if src.IsString() && dst.IsSlice() && dst.Elem().NotInHeap() && (dst.Elem().Etype == types.Bytetype.Etype || dst.Elem().Etype == types.Runetype.Etype) {
-		why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable)", dst.Elem())
-		return OXXX, why
-	}
-
-	// 1. src can be assigned to dst.
-	op, why := assignop(src, dst)
-	if op != OXXX {
-		return op, why
-	}
-
-	// The rules for interfaces are no different in conversions
-	// than assignments. If interfaces are involved, stop now
-	// with the good message from assignop.
-	// Otherwise clear the error.
-	if src.IsInterface() || dst.IsInterface() {
-		return OXXX, why
-	}
-
-	// 2. Ignoring struct tags, src and dst have identical underlying types.
-	if types.IdenticalIgnoreTags(src.Orig, dst.Orig) {
-		return OCONVNOP, ""
-	}
-
-	// 3. src and dst are unnamed pointer types and, ignoring struct tags,
-	// their base types have identical underlying types.
-	if src.IsPtr() && dst.IsPtr() && src.Sym == nil && dst.Sym == nil {
-		if types.IdenticalIgnoreTags(src.Elem().Orig, dst.Elem().Orig) {
-			return OCONVNOP, ""
-		}
-	}
-
-	// 4. src and dst are both integer or floating point types.
-	if (src.IsInteger() || src.IsFloat()) && (dst.IsInteger() || dst.IsFloat()) {
-		if simtype[src.Etype] == simtype[dst.Etype] {
-			return OCONVNOP, ""
-		}
-		return OCONV, ""
-	}
-
-	// 5. src and dst are both complex types.
-	if src.IsComplex() && dst.IsComplex() {
-		if simtype[src.Etype] == simtype[dst.Etype] {
-			return OCONVNOP, ""
-		}
-		return OCONV, ""
-	}
-
-	// Special case for constant conversions: any numeric
-	// conversion is potentially okay. We'll validate further
-	// within evconst. See #38117.
-	if srcConstant && (src.IsInteger() || src.IsFloat() || src.IsComplex()) && (dst.IsInteger() || dst.IsFloat() || dst.IsComplex()) {
-		return OCONV, ""
-	}
-
-	// 6. src is an integer or has type []byte or []rune
-	// and dst is a string type.
-	if src.IsInteger() && dst.IsString() {
-		return ORUNESTR, ""
-	}
-
-	if src.IsSlice() && dst.IsString() {
-		if src.Elem().Etype == types.Bytetype.Etype {
-			return OBYTES2STR, ""
-		}
-		if src.Elem().Etype == types.Runetype.Etype {
-			return ORUNES2STR, ""
-		}
-	}
-
-	// 7. src is a string and dst is []byte or []rune.
-	// String to slice.
-	if src.IsString() && dst.IsSlice() {
-		if dst.Elem().Etype == types.Bytetype.Etype {
-			return OSTR2BYTES, ""
-		}
-		if dst.Elem().Etype == types.Runetype.Etype {
-			return OSTR2RUNES, ""
-		}
-	}
-
-	// 8. src is a pointer or uintptr and dst is unsafe.Pointer.
-	if (src.IsPtr() || src.IsUintptr()) && dst.IsUnsafePtr() {
-		return OCONVNOP, ""
-	}
-
-	// 9. src is unsafe.Pointer and dst is a pointer or uintptr.
-	if src.IsUnsafePtr() && (dst.IsPtr() || dst.IsUintptr()) {
-		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 OXXX, ""
-}
-
-func assignconv(n *Node, t *types.Type, context string) *Node {
-	return assignconvfn(n, t, func() string { return context })
-}
-
-// Convert node n for assignment to type t.
-func assignconvfn(n *Node, t *types.Type, context func() string) *Node {
-	if n == nil || n.Type == nil || n.Type.Broke() {
-		return n
-	}
-
-	if t.Etype == TBLANK && n.Type.Etype == TNIL {
-		yyerror("use of untyped nil")
-	}
-
-	n = convlit1(n, t, false, context)
-	if n.Type == nil {
-		return n
-	}
-	if t.Etype == TBLANK {
-		return n
-	}
-
-	// Convert ideal bool from comparison to plain bool
-	// if the next step is non-bool (like interface{}).
-	if n.Type == types.UntypedBool && !t.IsBoolean() {
-		if n.Op == ONAME || n.Op == OLITERAL {
-			r := nod(OCONVNOP, n, nil)
-			r.Type = types.Types[TBOOL]
-			r.SetTypecheck(1)
-			r.SetImplicit(true)
-			n = r
-		}
-	}
-
-	if types.Identical(n.Type, t) {
-		return n
-	}
-
-	op, why := assignop(n.Type, t)
-	if op == OXXX {
-		yyerror("cannot use %L as type %v in %s%s", n, t, context(), why)
-		op = OCONV
-	}
-
-	r := nod(op, n, nil)
-	r.Type = t
-	r.SetTypecheck(1)
-	r.SetImplicit(true)
-	r.Orig = n.Orig
-	return r
-}
-
-// IsMethod reports whether n is a method.
-// n must be a function or a method.
-func (n *Node) IsMethod() bool {
-	return n.Type.Recv() != nil
-}
-
-// SliceBounds returns n's slice bounds: low, high, and max in expr[low:high:max].
-// n must be a slice expression. max is nil if n is a simple slice expression.
-func (n *Node) SliceBounds() (low, high, max *Node) {
-	if n.List.Len() == 0 {
-		return nil, nil, nil
-	}
-
-	switch n.Op {
-	case OSLICE, OSLICEARR, OSLICESTR:
-		s := n.List.Slice()
-		return s[0], s[1], nil
-	case OSLICE3, OSLICE3ARR:
-		s := n.List.Slice()
-		return s[0], s[1], s[2]
-	}
-	Fatalf("SliceBounds op %v: %v", n.Op, n)
-	return nil, nil, nil
-}
-
-// SetSliceBounds sets n's slice bounds, where n is a slice expression.
-// n must be a slice expression. If max is non-nil, n must be a full slice expression.
-func (n *Node) SetSliceBounds(low, high, max *Node) {
-	switch n.Op {
-	case OSLICE, OSLICEARR, OSLICESTR:
-		if max != nil {
-			Fatalf("SetSliceBounds %v given three bounds", n.Op)
-		}
-		s := n.List.Slice()
-		if s == nil {
-			if low == nil && high == nil {
-				return
-			}
-			n.List.Set2(low, high)
-			return
-		}
-		s[0] = low
-		s[1] = high
-		return
-	case OSLICE3, OSLICE3ARR:
-		s := n.List.Slice()
-		if s == nil {
-			if low == nil && high == nil && max == nil {
-				return
-			}
-			n.List.Set3(low, high, max)
-			return
-		}
-		s[0] = low
-		s[1] = high
-		s[2] = max
-		return
-	}
-	Fatalf("SetSliceBounds op %v: %v", n.Op, n)
-}
-
-// IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
-// o must be a slicing op.
-func (o Op) IsSlice3() bool {
-	switch o {
-	case OSLICE, OSLICEARR, OSLICESTR:
-		return false
-	case OSLICE3, OSLICE3ARR:
-		return true
-	}
-	Fatalf("IsSlice3 op %v", o)
-	return false
-}
-
-// backingArrayPtrLen extracts the pointer and length from a slice or string.
-// This constructs two nodes referring to n, so n must be a cheapexpr.
-func (n *Node) backingArrayPtrLen() (ptr, len *Node) {
-	var init Nodes
-	c := cheapexpr(n, &init)
-	if c != n || init.Len() != 0 {
-		Fatalf("backingArrayPtrLen not cheap: %v", n)
-	}
-	ptr = nod(OSPTR, n, nil)
-	if n.Type.IsString() {
-		ptr.Type = types.Types[TUINT8].PtrTo()
-	} else {
-		ptr.Type = n.Type.Elem().PtrTo()
-	}
-	len = nod(OLEN, n, nil)
-	len.Type = types.Types[TINT]
-	return ptr, len
-}
-
-// labeledControl returns the control flow Node (for, switch, select)
-// associated with the label n, if any.
-func (n *Node) labeledControl() *Node {
-	if n.Op != OLABEL {
-		Fatalf("labeledControl %v", n.Op)
-	}
-	ctl := n.Name.Defn
-	if ctl == nil {
-		return nil
-	}
-	switch ctl.Op {
-	case OFOR, OFORUNTIL, OSWITCH, OSELECT:
-		return ctl
-	}
-	return nil
-}
-
-func syslook(name string) *Node {
-	s := Runtimepkg.Lookup(name)
-	if s == nil || s.Def == nil {
-		Fatalf("syslook: can't find runtime.%s", name)
-	}
-	return asNode(s.Def)
-}
-
-// typehash computes a hash value for type t to use in type switch statements.
-func typehash(t *types.Type) uint32 {
-	p := t.LongString()
-
-	// Using MD5 is overkill, but reduces accidental collisions.
-	h := md5.Sum([]byte(p))
-	return binary.LittleEndian.Uint32(h[:4])
-}
-
-// updateHasCall checks whether expression n contains any function
-// calls and sets the n.HasCall flag if so.
-func updateHasCall(n *Node) {
-	if n == nil {
-		return
-	}
-	n.SetHasCall(calcHasCall(n))
-}
-
-func calcHasCall(n *Node) bool {
-	if n.Ninit.Len() != 0 {
-		// TODO(mdempsky): This seems overly conservative.
-		return true
-	}
-
-	switch n.Op {
-	case OLITERAL, ONAME, OTYPE:
-		if n.HasCall() {
-			Fatalf("OLITERAL/ONAME/OTYPE should never have calls: %+v", n)
-		}
-		return false
-	case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER:
-		return true
-	case OANDAND, OOROR:
-		// hard with instrumented code
-		if instrumenting {
-			return true
-		}
-	case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR,
-		ODEREF, ODOTPTR, ODOTTYPE, ODIV, OMOD:
-		// These ops might panic, make sure they are done
-		// before we start marshaling args for a call. See issue 16760.
-		return true
-
-	// When using soft-float, these ops might be rewritten to function calls
-	// so we ensure they are evaluated first.
-	case OADD, OSUB, ONEG, OMUL:
-		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() {
-		return true
-	}
-	if n.Right != nil && n.Right.HasCall() {
-		return true
-	}
-	return false
-}
-
-func badtype(op Op, tl, tr *types.Type) {
-	var s string
-	if tl != nil {
-		s += fmt.Sprintf("\n\t%v", tl)
-	}
-	if tr != nil {
-		s += fmt.Sprintf("\n\t%v", tr)
-	}
-
-	// common mistake: *struct and *interface.
-	if tl != nil && tr != nil && tl.IsPtr() && tr.IsPtr() {
-		if tl.Elem().IsStruct() && tr.Elem().IsInterface() {
-			s += "\n\t(*struct vs *interface)"
-		} else if tl.Elem().IsInterface() && tr.Elem().IsStruct() {
-			s += "\n\t(*interface vs *struct)"
-		}
-	}
-
-	yyerror("illegal types for operand: %v%s", op, s)
-}
-
-// brcom returns !(op).
-// For example, brcom(==) is !=.
-func brcom(op Op) Op {
-	switch op {
-	case OEQ:
-		return ONE
-	case ONE:
-		return OEQ
-	case OLT:
-		return OGE
-	case OGT:
-		return OLE
-	case OLE:
-		return OGT
-	case OGE:
-		return OLT
-	}
-	Fatalf("brcom: no com for %v\n", op)
-	return op
-}
-
-// brrev returns reverse(op).
-// For example, Brrev(<) is >.
-func brrev(op Op) Op {
-	switch op {
-	case OEQ:
-		return OEQ
-	case ONE:
-		return ONE
-	case OLT:
-		return OGT
-	case OGT:
-		return OLT
-	case OLE:
-		return OGE
-	case OGE:
-		return OLE
-	}
-	Fatalf("brrev: no rev for %v\n", op)
-	return op
-}
-
-// return side effect-free n, appending side effects to init.
-// result is assignable if n is.
-func safeexpr(n *Node, init *Nodes) *Node {
-	if n == nil {
-		return nil
-	}
-
-	if n.Ninit.Len() != 0 {
-		walkstmtlist(n.Ninit.Slice())
-		init.AppendNodes(&n.Ninit)
-	}
-
-	switch n.Op {
-	case ONAME, OLITERAL:
-		return n
-
-	case ODOT, OLEN, OCAP:
-		l := safeexpr(n.Left, init)
-		if l == n.Left {
-			return n
-		}
-		r := n.copy()
-		r.Left = l
-		r = typecheck(r, ctxExpr)
-		r = walkexpr(r, init)
-		return r
-
-	case ODOTPTR, ODEREF:
-		l := safeexpr(n.Left, init)
-		if l == n.Left {
-			return n
-		}
-		a := n.copy()
-		a.Left = l
-		a = walkexpr(a, init)
-		return a
-
-	case OINDEX, OINDEXMAP:
-		l := safeexpr(n.Left, init)
-		r := safeexpr(n.Right, init)
-		if l == n.Left && r == n.Right {
-			return n
-		}
-		a := n.copy()
-		a.Left = l
-		a.Right = r
-		a = walkexpr(a, init)
-		return a
-
-	case OSTRUCTLIT, OARRAYLIT, OSLICELIT:
-		if isStaticCompositeLiteral(n) {
-			return n
-		}
-	}
-
-	// make a copy; must not be used as an lvalue
-	if islvalue(n) {
-		Fatalf("missing lvalue case in safeexpr: %v", n)
-	}
-	return cheapexpr(n, init)
-}
-
-func copyexpr(n *Node, t *types.Type, init *Nodes) *Node {
-	l := temp(t)
-	a := nod(OAS, l, n)
-	a = typecheck(a, ctxStmt)
-	a = walkexpr(a, init)
-	init.Append(a)
-	return l
-}
-
-// return side-effect free and cheap n, appending side effects to init.
-// result may not be assignable.
-func cheapexpr(n *Node, init *Nodes) *Node {
-	switch n.Op {
-	case ONAME, OLITERAL:
-		return n
-	}
-
-	return copyexpr(n, n.Type, init)
-}
-
-// Code to resolve elided DOTs in embedded types.
-
-// A Dlist stores a pointer to a TFIELD Type embedded within
-// a TSTRUCT or TINTER Type.
-type Dlist struct {
-	field *types.Field
-}
-
-// dotlist is used by adddot1 to record the path of embedded fields
-// used to access a target field or method.
-// Must be non-nil so that dotpath returns a non-nil slice even if d is zero.
-var dotlist = make([]Dlist, 10)
-
-// lookdot0 returns the number of fields or methods named s associated
-// with Type t. If exactly one exists, it will be returned in *save
-// (if save is not nil).
-func lookdot0(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) int {
-	u := t
-	if u.IsPtr() {
-		u = u.Elem()
-	}
-
-	c := 0
-	if u.IsStruct() || u.IsInterface() {
-		for _, f := range u.Fields().Slice() {
-			if f.Sym == s || (ignorecase && f.IsMethod() && strings.EqualFold(f.Sym.Name, s.Name)) {
-				if save != nil {
-					*save = f
-				}
-				c++
-			}
-		}
-	}
-
-	u = t
-	if t.Sym != nil && t.IsPtr() && !t.Elem().IsPtr() {
-		// If t is a defined pointer type, then x.m is shorthand for (*x).m.
-		u = t.Elem()
-	}
-	u = methtype(u)
-	if u != nil {
-		for _, f := range u.Methods().Slice() {
-			if f.Embedded == 0 && (f.Sym == s || (ignorecase && strings.EqualFold(f.Sym.Name, s.Name))) {
-				if save != nil {
-					*save = f
-				}
-				c++
-			}
-		}
-	}
-
-	return c
-}
-
-// adddot1 returns the number of fields or methods named s at depth d in Type t.
-// If exactly one exists, it will be returned in *save (if save is not nil),
-// and dotlist will contain the path of embedded fields traversed to find it,
-// in reverse order. If none exist, more will indicate whether t contains any
-// embedded fields at depth d, so callers can decide whether to retry at
-// a greater depth.
-func adddot1(s *types.Sym, t *types.Type, d int, save **types.Field, ignorecase bool) (c int, more bool) {
-	if t.Recur() {
-		return
-	}
-	t.SetRecur(true)
-	defer t.SetRecur(false)
-
-	var u *types.Type
-	d--
-	if d < 0 {
-		// We've reached our target depth. If t has any fields/methods
-		// named s, then we're done. Otherwise, we still need to check
-		// below for embedded fields.
-		c = lookdot0(s, t, save, ignorecase)
-		if c != 0 {
-			return c, false
-		}
-	}
-
-	u = t
-	if u.IsPtr() {
-		u = u.Elem()
-	}
-	if !u.IsStruct() && !u.IsInterface() {
-		return c, false
-	}
-
-	for _, f := range u.Fields().Slice() {
-		if f.Embedded == 0 || f.Sym == nil {
-			continue
-		}
-		if d < 0 {
-			// Found an embedded field at target depth.
-			return c, true
-		}
-		a, more1 := adddot1(s, f.Type, d, save, ignorecase)
-		if a != 0 && c == 0 {
-			dotlist[d].field = f
-		}
-		c += a
-		if more1 {
-			more = true
-		}
-	}
-
-	return c, more
-}
-
-// dotpath computes the unique shortest explicit selector path to fully qualify
-// a selection expression x.f, where x is of type t and f is the symbol s.
-// If no such path exists, dotpath returns nil.
-// If there are multiple shortest paths to the same depth, ambig is true.
-func dotpath(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) (path []Dlist, ambig bool) {
-	// The embedding of types within structs imposes a tree structure onto
-	// types: structs parent the types they embed, and types parent their
-	// fields or methods. Our goal here is to find the shortest path to
-	// a field or method named s in the subtree rooted at t. To accomplish
-	// that, we iteratively perform depth-first searches of increasing depth
-	// until we either find the named field/method or exhaust the tree.
-	for d := 0; ; d++ {
-		if d > len(dotlist) {
-			dotlist = append(dotlist, Dlist{})
-		}
-		if c, more := adddot1(s, t, d, save, ignorecase); c == 1 {
-			return dotlist[:d], false
-		} else if c > 1 {
-			return nil, true
-		} else if !more {
-			return nil, false
-		}
-	}
-}
-
-// in T.field
-// find missing fields that
-// will give shortest unique addressing.
-// modify the tree with missing type names.
-func adddot(n *Node) *Node {
-	n.Left = typecheck(n.Left, ctxType|ctxExpr)
-	if n.Left.Diag() {
-		n.SetDiag(true)
-	}
-	t := n.Left.Type
-	if t == nil {
-		return n
-	}
-
-	if n.Left.Op == OTYPE {
-		return n
-	}
-
-	s := n.Sym
-	if s == nil {
-		return n
-	}
-
-	switch path, ambig := dotpath(s, t, nil, false); {
-	case path != nil:
-		// rebuild elided dots
-		for c := len(path) - 1; c >= 0; c-- {
-			n.Left = nodSym(ODOT, n.Left, path[c].field.Sym)
-			n.Left.SetImplicit(true)
-		}
-	case ambig:
-		yyerror("ambiguous selector %v", n)
-		n.Left = nil
-	}
-
-	return n
-}
-
-// Code to help generate trampoline functions for methods on embedded
-// types. These are approx the same as the corresponding adddot
-// routines except that they expect to be called with unique tasks and
-// they return the actual methods.
-
-type Symlink struct {
-	field *types.Field
-}
-
-var slist []Symlink
-
-func expand0(t *types.Type) {
-	u := t
-	if u.IsPtr() {
-		u = u.Elem()
-	}
-
-	if u.IsInterface() {
-		for _, f := range u.Fields().Slice() {
-			if f.Sym.Uniq() {
-				continue
-			}
-			f.Sym.SetUniq(true)
-			slist = append(slist, Symlink{field: f})
-		}
-
-		return
-	}
-
-	u = methtype(t)
-	if u != nil {
-		for _, f := range u.Methods().Slice() {
-			if f.Sym.Uniq() {
-				continue
-			}
-			f.Sym.SetUniq(true)
-			slist = append(slist, Symlink{field: f})
-		}
-	}
-}
-
-func expand1(t *types.Type, top bool) {
-	if t.Recur() {
-		return
-	}
-	t.SetRecur(true)
-
-	if !top {
-		expand0(t)
-	}
-
-	u := t
-	if u.IsPtr() {
-		u = u.Elem()
-	}
-
-	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)
-		}
-	}
-
-	t.SetRecur(false)
-}
-
-func expandmeth(t *types.Type) {
-	if t == nil || t.AllMethods().Len() != 0 {
-		return
-	}
-
-	// mark top-level method symbols
-	// so that expand1 doesn't consider them.
-	for _, f := range t.Methods().Slice() {
-		f.Sym.SetUniq(true)
-	}
-
-	// generate all reachable methods
-	slist = slist[:0]
-	expand1(t, true)
-
-	// check each method to be uniquely reachable
-	var ms []*types.Field
-	for i, sl := range slist {
-		slist[i].field = nil
-		sl.field.Sym.SetUniq(false)
-
-		var f *types.Field
-		path, _ := dotpath(sl.field.Sym, t, &f, false)
-		if path == nil {
-			continue
-		}
-
-		// dotpath may have dug out arbitrary fields, we only want methods.
-		if !f.IsMethod() {
-			continue
-		}
-
-		// add it to the base type method list
-		f = f.Copy()
-		f.Embedded = 1 // needs a trampoline
-		for _, d := range path {
-			if d.field.Type.IsPtr() {
-				f.Embedded = 2
-				break
-			}
-		}
-		ms = append(ms, f)
-	}
-
-	for _, f := range t.Methods().Slice() {
-		f.Sym.SetUniq(false)
-	}
-
-	ms = append(ms, t.Methods().Slice()...)
-	sort.Sort(methcmp(ms))
-	t.AllMethods().Set(ms)
-}
-
-// Given funarg struct list, return list of ODCLFIELD Node fn args.
-func structargs(tl *types.Type, mustname bool) []*Node {
-	var args []*Node
-	gen := 0
-	for _, t := range tl.Fields().Slice() {
-		s := t.Sym
-		if mustname && (s == nil || s.Name == "_") {
-			// invent a name so that we can refer to it in the trampoline
-			s = lookupN(".anon", gen)
-			gen++
-		}
-		a := symfield(s, t.Type)
-		a.Pos = t.Pos
-		a.SetIsDDD(t.IsDDD())
-		args = append(args, a)
-	}
-
-	return args
-}
-
-// Generate a wrapper function to convert from
-// a receiver of type T to a receiver of type U.
-// That is,
-//
-//	func (t T) M() {
-//		...
-//	}
-//
-// already exists; this function generates
-//
-//	func (u U) M() {
-//		u.M()
-//	}
-//
-// where the types T and U are such that u.M() is valid
-// and calls the T.M method.
-// The resulting function is for use in method tables.
-//
-//	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) {
-	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
-	}
-
-	// Only generate I.M wrappers for I in I's own package
-	// but keep doing it for error.Error (was issue #29304).
-	if rcvr.IsInterface() && rcvr.Sym != nil && rcvr.Sym.Pkg != localpkg && rcvr != types.Errortype {
-		return
-	}
-
-	lineno = autogeneratedPos
-	dclcontext = PEXTERN
-
-	tfn := nod(OTFUNC, nil, nil)
-	tfn.Left = namedfield(".this", rcvr)
-	tfn.List.Set(structargs(method.Type.Params(), true))
-	tfn.Rlist.Set(structargs(method.Type.Results(), false))
-
-	fn := dclfunc(newnam, tfn)
-	fn.Func.SetDupok(true)
-
-	nthis := asNode(tfn.Type.Recv().Nname)
-
-	methodrcvr := method.Type.Recv().Type
-
-	// generate nil pointer check for better error
-	if rcvr.IsPtr() && rcvr.Elem() == methodrcvr {
-		// generating wrapper from *T to T.
-		n := nod(OIF, nil, nil)
-		n.Left = nod(OEQ, nthis, nodnil())
-		call := nod(OCALL, syslook("panicwrap"), nil)
-		n.Nbody.Set1(call)
-		fn.Nbody.Append(n)
-	}
-
-	dot := adddot(nodSym(OXDOT, nthis, method.Sym))
-
-	// generate call
-	// It's not possible to use a tail call when dynamic linking on ppc64le. The
-	// bad scenario is when a local call is made to the wrapper: the wrapper will
-	// call the implementation, which might be in a different module and so set
-	// the TOC to the appropriate value for that module. But if it returns
-	// directly to the wrapper's caller, nothing will reset it to the correct
-	// value for that function.
-	if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) && !(thearch.LinkArch.Name == "ppc64le" && Ctxt.Flag_dynlink) {
-		// generate tail call: adjust pointer receiver and jump to embedded method.
-		dot = dot.Left // skip final .M
-		// TODO(mdempsky): Remove dependency on dotlist.
-		if !dotlist[0].field.Type.IsPtr() {
-			dot = nod(OADDR, dot, nil)
-		}
-		as := nod(OAS, nthis, convnop(dot, rcvr))
-		fn.Nbody.Append(as)
-		fn.Nbody.Append(nodSym(ORETJMP, nil, methodSym(methodrcvr, method.Sym)))
-	} else {
-		fn.Func.SetWrapper(true) // ignore frame for panic+recover matching
-		call := nod(OCALL, dot, nil)
-		call.List.Set(paramNnames(tfn.Type))
-		call.SetIsDDD(tfn.Type.IsVariadic())
-		if method.Type.NumResults() > 0 {
-			n := nod(ORETURN, nil, nil)
-			n.List.Set1(call)
-			call = n
-		}
-		fn.Nbody.Append(call)
-	}
-
-	if false && Debug.r != 0 {
-		dumplist("genwrapper body", fn.Nbody)
-	}
-
-	funcbody()
-	if debug_dclstack != 0 {
-		testdclstack()
-	}
-
-	fn = typecheck(fn, ctxStmt)
-
-	Curfn = fn
-	typecheckslice(fn.Nbody.Slice(), ctxStmt)
-
-	// Inline calls within (*T).M wrappers. This is safe because we only
-	// generate those wrappers within the same compilation unit as (T).M.
-	// TODO(mdempsky): Investigate why we can't enable this more generally.
-	if rcvr.IsPtr() && rcvr.Elem() == method.Type.Recv().Type && rcvr.Elem().Sym != nil {
-		inlcalls(fn)
-	}
-	escapeFuncs([]*Node{fn}, false)
-
-	Curfn = nil
-	xtop = append(xtop, fn)
-}
-
-func paramNnames(ft *types.Type) []*Node {
-	args := make([]*Node, ft.NumParams())
-	for i, f := range ft.Params().FieldSlice() {
-		args[i] = asNode(f.Nname)
-	}
-	return args
-}
-
-func hashmem(t *types.Type) *Node {
-	sym := Runtimepkg.Lookup("memhash")
-
-	n := newname(sym)
-	setNodeNameFunc(n)
-	n.Type = functype(nil, []*Node{
-		anonfield(types.NewPtr(t)),
-		anonfield(types.Types[TUINTPTR]),
-		anonfield(types.Types[TUINTPTR]),
-	}, []*Node{
-		anonfield(types.Types[TUINTPTR]),
-	})
-	return n
-}
-
-func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) (m *types.Field, followptr bool) {
-	if t == nil {
-		return nil, false
-	}
-
-	path, ambig := dotpath(s, t, &m, ignorecase)
-	if path == nil {
-		if ambig {
-			yyerror("%v.%v is ambiguous", t, s)
-		}
-		return nil, false
-	}
-
-	for _, d := range path {
-		if d.field.Type.IsPtr() {
-			followptr = true
-			break
-		}
-	}
-
-	if !m.IsMethod() {
-		yyerror("%v.%v is a field, not a method", t, s)
-		return nil, followptr
-	}
-
-	return m, followptr
-}
-
-func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool {
-	t0 := t
-	if t == nil {
-		return false
-	}
-
-	if t.IsInterface() {
-		i := 0
-		tms := t.Fields().Slice()
-		for _, im := range iface.Fields().Slice() {
-			for i < len(tms) && tms[i].Sym != im.Sym {
-				i++
-			}
-			if i == len(tms) {
-				*m = im
-				*samename = nil
-				*ptr = 0
-				return false
-			}
-			tm := tms[i]
-			if !types.Identical(tm.Type, im.Type) {
-				*m = im
-				*samename = tm
-				*ptr = 0
-				return false
-			}
-		}
-
-		return true
-	}
-
-	t = methtype(t)
-	var tms []*types.Field
-	if t != nil {
-		expandmeth(t)
-		tms = t.AllMethods().Slice()
-	}
-	i := 0
-	for _, im := range iface.Fields().Slice() {
-		if im.Broke() {
-			continue
-		}
-		for i < len(tms) && tms[i].Sym != im.Sym {
-			i++
-		}
-		if i == len(tms) {
-			*m = im
-			*samename, _ = ifacelookdot(im.Sym, t, true)
-			*ptr = 0
-			return false
-		}
-		tm := tms[i]
-		if tm.Nointerface() || !types.Identical(tm.Type, im.Type) {
-			*m = im
-			*samename = tm
-			*ptr = 0
-			return false
-		}
-		followptr := tm.Embedded == 2
-
-		// if pointer receiver in method,
-		// the method does not exist for value types.
-		rcvr := tm.Type.Recv().Type
-		if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !isifacemethod(tm.Type) {
-			if false && Debug.r != 0 {
-				yyerror("interface pointer mismatch")
-			}
-
-			*m = im
-			*samename = nil
-			*ptr = 1
-			return false
-		}
-	}
-
-	// We're going to emit an OCONVIFACE.
-	// Call itabname so that (t, iface)
-	// gets added to itabs early, which allows
-	// us to de-virtualize calls through this
-	// type/interface pair later. See peekitabs in reflect.go
-	if isdirectiface(t0) && !iface.IsEmptyInterface() {
-		itabname(t0, iface)
-	}
-	return true
-}
-
-func listtreecopy(l []*Node, pos src.XPos) []*Node {
-	var out []*Node
-	for _, n := range l {
-		out = append(out, treecopy(n, pos))
-	}
-	return out
-}
-
-func liststmt(l []*Node) *Node {
-	n := nod(OBLOCK, nil, nil)
-	n.List.Set(l)
-	if len(l) != 0 {
-		n.Pos = l[0].Pos
-	}
-	return n
-}
-
-func (l Nodes) asblock() *Node {
-	n := nod(OBLOCK, nil, nil)
-	n.List = l
-	if l.Len() != 0 {
-		n.Pos = l.First().Pos
-	}
-	return n
-}
-
-func ngotype(n *Node) *types.Sym {
-	if n.Type != nil {
-		return typenamesym(n.Type)
-	}
-	return nil
-}
-
-// The result of addinit MUST be assigned back to n, e.g.
-// 	n.Left = addinit(n.Left, init)
-func addinit(n *Node, init []*Node) *Node {
-	if len(init) == 0 {
-		return n
-	}
-	if n.mayBeShared() {
-		// Introduce OCONVNOP to hold init list.
-		n = nod(OCONVNOP, n, nil)
-		n.Type = n.Left.Type
-		n.SetTypecheck(1)
-	}
-
-	n.Ninit.Prepend(init...)
-	n.SetHasCall(true)
-	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",
-}
-
-func isbadimport(path string, allowSpace bool) bool {
-	if strings.Contains(path, "\x00") {
-		yyerror("import path contains NUL")
-		return true
-	}
-
-	for _, ri := range reservedimports {
-		if path == ri {
-			yyerror("import path %q is reserved and cannot be used", path)
-			return true
-		}
-	}
-
-	for _, r := range path {
-		if r == utf8.RuneError {
-			yyerror("import path contains invalid UTF-8 sequence: %q", path)
-			return true
-		}
-
-		if r < 0x20 || r == 0x7f {
-			yyerror("import path contains control character: %q", path)
-			return true
-		}
-
-		if r == '\\' {
-			yyerror("import path contains backslash; use slash: %q", path)
-			return true
-		}
-
-		if !allowSpace && unicode.IsSpace(r) {
-			yyerror("import path contains space character: %q", path)
-			return true
-		}
-
-		if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) {
-			yyerror("import path contains invalid character '%c': %q", r, path)
-			return true
-		}
-	}
-
-	return false
-}
-
-// 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 TPTR:
-		// Pointers to notinheap types must be stored indirectly. See issue 42076.
-		return !t.Elem().NotInHeap()
-	case TCHAN,
-		TMAP,
-		TFUNC,
-		TUNSAFEPTR:
-		return true
-
-	case TARRAY:
-		// Array of 1 direct iface type can be direct.
-		return t.NumElem() == 1 && isdirectiface(t.Elem())
-
-	case TSTRUCT:
-		// Struct with 1 field of direct iface type can be direct.
-		return t.NumFields() == 1 && isdirectiface(t.Field(0).Type)
-	}
-
-	return false
-}
-
-// itabType loads the _type field from a runtime.itab struct.
-func itabType(itab *Node) *Node {
-	typ := nodSym(ODOTPTR, itab, nil)
-	typ.Type = types.NewPtr(types.Types[TUINT8])
-	typ.SetTypecheck(1)
-	typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab
-	typ.SetBounded(true)          // guaranteed not to fault
-	return typ
-}
-
-// ifaceData loads the data field from an interface.
-// The concrete type must be known to have type t.
-// It follows the pointer if !isdirectiface(t).
-func ifaceData(pos src.XPos, n *Node, t *types.Type) *Node {
-	if t.IsInterface() {
-		Fatalf("ifaceData interface: %v", t)
-	}
-	ptr := nodlSym(pos, OIDATA, n, nil)
-	if isdirectiface(t) {
-		ptr.Type = t
-		ptr.SetTypecheck(1)
-		return ptr
-	}
-	ptr.Type = types.NewPtr(t)
-	ptr.SetTypecheck(1)
-	ind := nodl(pos, ODEREF, ptr, nil)
-	ind.Type = t
-	ind.SetTypecheck(1)
-	ind.SetBounded(true)
-	return ind
-}
-
-// typePos returns the position associated with t.
-// This is where t was declared or where it appeared as a type expression.
-func typePos(t *types.Type) src.XPos {
-	n := asNode(t.Nod)
-	if n == nil || !n.Pos.IsKnown() {
-		Fatalf("bad type: %v", t)
-	}
-	return n.Pos
-}
diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go
deleted file mode 100644
index 8d9fbe3..0000000
--- a/src/cmd/compile/internal/gc/swt.go
+++ /dev/null
@@ -1,756 +0,0 @@
-// Copyright 2009 The Go Authors. 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/compile/internal/types"
-	"cmd/internal/src"
-	"sort"
-)
-
-// typecheckswitch typechecks a switch statement.
-func typecheckswitch(n *Node) {
-	typecheckslice(n.Ninit.Slice(), ctxStmt)
-	if n.Left != nil && n.Left.Op == OTYPESW {
-		typecheckTypeSwitch(n)
-	} else {
-		typecheckExprSwitch(n)
-	}
-}
-
-func typecheckTypeSwitch(n *Node) {
-	n.Left.Right = typecheck(n.Left.Right, ctxExpr)
-	t := n.Left.Right.Type
-	if t != nil && !t.IsInterface() {
-		yyerrorl(n.Pos, "cannot type switch on non-interface value %L", n.Left.Right)
-		t = nil
-	}
-
-	// We don't actually declare the type switch's guarded
-	// declaration itself. So if there are no cases, we won't
-	// notice that it went unused.
-	if v := n.Left.Left; v != nil && !v.isBlank() && n.List.Len() == 0 {
-		yyerrorl(v.Pos, "%v declared but not used", v.Sym)
-	}
-
-	var defCase, nilCase *Node
-	var ts typeSet
-	for _, ncase := range n.List.Slice() {
-		ls := ncase.List.Slice()
-		if len(ls) == 0 { // default:
-			if defCase != nil {
-				yyerrorl(ncase.Pos, "multiple defaults in switch (first at %v)", defCase.Line())
-			} else {
-				defCase = ncase
-			}
-		}
-
-		for i := range ls {
-			ls[i] = typecheck(ls[i], ctxExpr|ctxType)
-			n1 := ls[i]
-			if t == nil || n1.Type == nil {
-				continue
-			}
-
-			var missing, have *types.Field
-			var ptr int
-			switch {
-			case n1.isNil(): // case nil:
-				if nilCase != nil {
-					yyerrorl(ncase.Pos, "multiple nil cases in type switch (first at %v)", nilCase.Line())
-				} else {
-					nilCase = ncase
-				}
-			case n1.Op != OTYPE:
-				yyerrorl(ncase.Pos, "%L is not a type", n1)
-			case !n1.Type.IsInterface() && !implements(n1.Type, t, &missing, &have, &ptr) && !missing.Broke():
-				if have != nil && !have.Broke() {
-					yyerrorl(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
-						" (wrong type for %v method)\n\thave %v%S\n\twant %v%S", n.Left.Right, n1.Type, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
-				} else if ptr != 0 {
-					yyerrorl(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
-						" (%v method has pointer receiver)", n.Left.Right, n1.Type, missing.Sym)
-				} else {
-					yyerrorl(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
-						" (missing %v method)", n.Left.Right, n1.Type, missing.Sym)
-				}
-			}
-
-			if n1.Op == OTYPE {
-				ts.add(ncase.Pos, n1.Type)
-			}
-		}
-
-		if ncase.Rlist.Len() != 0 {
-			// Assign the clause variable's type.
-			vt := t
-			if len(ls) == 1 {
-				if ls[0].Op == OTYPE {
-					vt = ls[0].Type
-				} else if ls[0].Op != OLITERAL { // TODO(mdempsky): Should be !ls[0].isNil()
-					// Invalid single-type case;
-					// mark variable as broken.
-					vt = nil
-				}
-			}
-
-			// TODO(mdempsky): It should be possible to
-			// still typecheck the case body.
-			if vt == nil {
-				continue
-			}
-
-			nvar := ncase.Rlist.First()
-			nvar.Type = vt
-			nvar = typecheck(nvar, ctxExpr|ctxAssign)
-			ncase.Rlist.SetFirst(nvar)
-		}
-
-		typecheckslice(ncase.Nbody.Slice(), ctxStmt)
-	}
-}
-
-type typeSet struct {
-	m map[string][]typeSetEntry
-}
-
-type typeSetEntry struct {
-	pos src.XPos
-	typ *types.Type
-}
-
-func (s *typeSet) add(pos src.XPos, typ *types.Type) {
-	if s.m == nil {
-		s.m = make(map[string][]typeSetEntry)
-	}
-
-	// LongString does not uniquely identify types, so we need to
-	// disambiguate collisions with types.Identical.
-	// TODO(mdempsky): Add a method that *is* unique.
-	ls := typ.LongString()
-	prevs := s.m[ls]
-	for _, prev := range prevs {
-		if types.Identical(typ, prev.typ) {
-			yyerrorl(pos, "duplicate case %v in type switch\n\tprevious case at %s", typ, linestr(prev.pos))
-			return
-		}
-	}
-	s.m[ls] = append(prevs, typeSetEntry{pos, typ})
-}
-
-func typecheckExprSwitch(n *Node) {
-	t := types.Types[TBOOL]
-	if n.Left != nil {
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Left = defaultlit(n.Left, nil)
-		t = n.Left.Type
-	}
-
-	var nilonly string
-	if t != nil {
-		switch {
-		case t.IsMap():
-			nilonly = "map"
-		case t.Etype == TFUNC:
-			nilonly = "func"
-		case t.IsSlice():
-			nilonly = "slice"
-
-		case !IsComparable(t):
-			if t.IsStruct() {
-				yyerrorl(n.Pos, "cannot switch on %L (struct containing %v cannot be compared)", n.Left, IncomparableField(t).Type)
-			} else {
-				yyerrorl(n.Pos, "cannot switch on %L", n.Left)
-			}
-			t = nil
-		}
-	}
-
-	var defCase *Node
-	var cs constSet
-	for _, ncase := range n.List.Slice() {
-		ls := ncase.List.Slice()
-		if len(ls) == 0 { // default:
-			if defCase != nil {
-				yyerrorl(ncase.Pos, "multiple defaults in switch (first at %v)", defCase.Line())
-			} else {
-				defCase = ncase
-			}
-		}
-
-		for i := range ls {
-			setlineno(ncase)
-			ls[i] = typecheck(ls[i], ctxExpr)
-			ls[i] = defaultlit(ls[i], t)
-			n1 := ls[i]
-			if t == nil || n1.Type == nil {
-				continue
-			}
-
-			if nilonly != "" && !n1.isNil() {
-				yyerrorl(ncase.Pos, "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left)
-			} else if t.IsInterface() && !n1.Type.IsInterface() && !IsComparable(n1.Type) {
-				yyerrorl(ncase.Pos, "invalid case %L in switch (incomparable type)", n1)
-			} else {
-				op1, _ := assignop(n1.Type, t)
-				op2, _ := assignop(t, n1.Type)
-				if op1 == OXXX && op2 == OXXX {
-					if n.Left != nil {
-						yyerrorl(ncase.Pos, "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left, n1.Type, t)
-					} else {
-						yyerrorl(ncase.Pos, "invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type)
-					}
-				}
-			}
-
-			// Don't check for duplicate bools. Although the spec allows it,
-			// (1) the compiler hasn't checked it in the past, so compatibility mandates it, and
-			// (2) it would disallow useful things like
-			//       case GOARCH == "arm" && GOARM == "5":
-			//       case GOARCH == "arm":
-			//     which would both evaluate to false for non-ARM compiles.
-			if !n1.Type.IsBoolean() {
-				cs.add(ncase.Pos, n1, "case", "switch")
-			}
-		}
-
-		typecheckslice(ncase.Nbody.Slice(), ctxStmt)
-	}
-}
-
-// walkswitch walks a switch statement.
-func walkswitch(sw *Node) {
-	// Guard against double walk, see #25776.
-	if sw.List.Len() == 0 && sw.Nbody.Len() > 0 {
-		return // Was fatal, but eliminating every possible source of double-walking is hard
-	}
-
-	if sw.Left != nil && sw.Left.Op == OTYPESW {
-		walkTypeSwitch(sw)
-	} else {
-		walkExprSwitch(sw)
-	}
-}
-
-// walkExprSwitch generates an AST implementing sw.  sw is an
-// expression switch.
-func walkExprSwitch(sw *Node) {
-	lno := setlineno(sw)
-
-	cond := sw.Left
-	sw.Left = nil
-
-	// convert switch {...} to switch true {...}
-	if cond == nil {
-		cond = nodbool(true)
-		cond = typecheck(cond, ctxExpr)
-		cond = defaultlit(cond, nil)
-	}
-
-	// Given "switch string(byteslice)",
-	// with all cases being side-effect free,
-	// use a zero-cost alias of the byte slice.
-	// Do this before calling walkexpr on cond,
-	// because walkexpr will lower the string
-	// conversion into a runtime call.
-	// See issue 24937 for more discussion.
-	if cond.Op == OBYTES2STR && allCaseExprsAreSideEffectFree(sw) {
-		cond.Op = OBYTES2STRTMP
-	}
-
-	cond = walkexpr(cond, &sw.Ninit)
-	if cond.Op != OLITERAL {
-		cond = copyexpr(cond, cond.Type, &sw.Nbody)
-	}
-
-	lineno = lno
-
-	s := exprSwitch{
-		exprname: cond,
-	}
-
-	var defaultGoto *Node
-	var body Nodes
-	for _, ncase := range sw.List.Slice() {
-		label := autolabel(".s")
-		jmp := npos(ncase.Pos, nodSym(OGOTO, nil, label))
-
-		// Process case dispatch.
-		if ncase.List.Len() == 0 {
-			if defaultGoto != nil {
-				Fatalf("duplicate default case not detected during typechecking")
-			}
-			defaultGoto = jmp
-		}
-
-		for _, n1 := range ncase.List.Slice() {
-			s.Add(ncase.Pos, n1, jmp)
-		}
-
-		// Process body.
-		body.Append(npos(ncase.Pos, nodSym(OLABEL, nil, label)))
-		body.Append(ncase.Nbody.Slice()...)
-		if fall, pos := hasFall(ncase.Nbody.Slice()); !fall {
-			br := nod(OBREAK, nil, nil)
-			br.Pos = pos
-			body.Append(br)
-		}
-	}
-	sw.List.Set(nil)
-
-	if defaultGoto == nil {
-		br := nod(OBREAK, nil, nil)
-		br.Pos = br.Pos.WithNotStmt()
-		defaultGoto = br
-	}
-
-	s.Emit(&sw.Nbody)
-	sw.Nbody.Append(defaultGoto)
-	sw.Nbody.AppendNodes(&body)
-	walkstmtlist(sw.Nbody.Slice())
-}
-
-// An exprSwitch walks an expression switch.
-type exprSwitch struct {
-	exprname *Node // value being switched on
-
-	done    Nodes
-	clauses []exprClause
-}
-
-type exprClause struct {
-	pos    src.XPos
-	lo, hi *Node
-	jmp    *Node
-}
-
-func (s *exprSwitch) Add(pos src.XPos, expr, jmp *Node) {
-	c := exprClause{pos: pos, lo: expr, hi: expr, jmp: jmp}
-	if okforcmp[s.exprname.Type.Etype] && expr.Op == OLITERAL {
-		s.clauses = append(s.clauses, c)
-		return
-	}
-
-	s.flush()
-	s.clauses = append(s.clauses, c)
-	s.flush()
-}
-
-func (s *exprSwitch) Emit(out *Nodes) {
-	s.flush()
-	out.AppendNodes(&s.done)
-}
-
-func (s *exprSwitch) flush() {
-	cc := s.clauses
-	s.clauses = nil
-	if len(cc) == 0 {
-		return
-	}
-
-	// Caution: If len(cc) == 1, then cc[0] might not an OLITERAL.
-	// The code below is structured to implicitly handle this case
-	// (e.g., sort.Slice doesn't need to invoke the less function
-	// when there's only a single slice element).
-
-	if s.exprname.Type.IsString() && len(cc) >= 2 {
-		// Sort strings by length and then by value. It is
-		// much cheaper to compare lengths than values, and
-		// all we need here is consistency. We respect this
-		// sorting below.
-		sort.Slice(cc, func(i, j int) bool {
-			si := cc[i].lo.StringVal()
-			sj := cc[j].lo.StringVal()
-			if len(si) != len(sj) {
-				return len(si) < len(sj)
-			}
-			return si < sj
-		})
-
-		// runLen returns the string length associated with a
-		// particular run of exprClauses.
-		runLen := func(run []exprClause) int64 { return int64(len(run[0].lo.StringVal())) }
-
-		// Collapse runs of consecutive strings with the same length.
-		var runs [][]exprClause
-		start := 0
-		for i := 1; i < len(cc); i++ {
-			if runLen(cc[start:]) != runLen(cc[i:]) {
-				runs = append(runs, cc[start:i])
-				start = i
-			}
-		}
-		runs = append(runs, cc[start:])
-
-		// Perform two-level binary search.
-		nlen := nod(OLEN, s.exprname, nil)
-		binarySearch(len(runs), &s.done,
-			func(i int) *Node {
-				return nod(OLE, nlen, nodintconst(runLen(runs[i-1])))
-			},
-			func(i int, nif *Node) {
-				run := runs[i]
-				nif.Left = nod(OEQ, nlen, nodintconst(runLen(run)))
-				s.search(run, &nif.Nbody)
-			},
-		)
-		return
-	}
-
-	sort.Slice(cc, func(i, j int) bool {
-		return compareOp(cc[i].lo.Val(), OLT, cc[j].lo.Val())
-	})
-
-	// Merge consecutive integer cases.
-	if s.exprname.Type.IsInteger() {
-		merged := cc[:1]
-		for _, c := range cc[1:] {
-			last := &merged[len(merged)-1]
-			if last.jmp == c.jmp && last.hi.Int64Val()+1 == c.lo.Int64Val() {
-				last.hi = c.lo
-			} else {
-				merged = append(merged, c)
-			}
-		}
-		cc = merged
-	}
-
-	s.search(cc, &s.done)
-}
-
-func (s *exprSwitch) search(cc []exprClause, out *Nodes) {
-	binarySearch(len(cc), out,
-		func(i int) *Node {
-			return nod(OLE, s.exprname, cc[i-1].hi)
-		},
-		func(i int, nif *Node) {
-			c := &cc[i]
-			nif.Left = c.test(s.exprname)
-			nif.Nbody.Set1(c.jmp)
-		},
-	)
-}
-
-func (c *exprClause) test(exprname *Node) *Node {
-	// Integer range.
-	if c.hi != c.lo {
-		low := nodl(c.pos, OGE, exprname, c.lo)
-		high := nodl(c.pos, OLE, exprname, c.hi)
-		return nodl(c.pos, OANDAND, low, high)
-	}
-
-	// Optimize "switch true { ...}" and "switch false { ... }".
-	if Isconst(exprname, CTBOOL) && !c.lo.Type.IsInterface() {
-		if exprname.BoolVal() {
-			return c.lo
-		} else {
-			return nodl(c.pos, ONOT, c.lo, nil)
-		}
-	}
-
-	return nodl(c.pos, OEQ, exprname, c.lo)
-}
-
-func allCaseExprsAreSideEffectFree(sw *Node) bool {
-	// In theory, we could be more aggressive, allowing any
-	// side-effect-free expressions in cases, but it's a bit
-	// tricky because some of that information is unavailable due
-	// to the introduction of temporaries during order.
-	// Restricting to constants is simple and probably powerful
-	// enough.
-
-	for _, ncase := range sw.List.Slice() {
-		if ncase.Op != OCASE {
-			Fatalf("switch string(byteslice) bad op: %v", ncase.Op)
-		}
-		for _, v := range ncase.List.Slice() {
-			if v.Op != OLITERAL {
-				return false
-			}
-		}
-	}
-	return true
-}
-
-// hasFall reports whether stmts ends with a "fallthrough" statement.
-func hasFall(stmts []*Node) (bool, src.XPos) {
-	// Search backwards for the index of the fallthrough
-	// statement. Do not assume it'll be in the last
-	// position, since in some cases (e.g. when the statement
-	// list contains autotmp_ variables), one or more OVARKILL
-	// nodes will be at the end of the list.
-
-	i := len(stmts) - 1
-	for i >= 0 && stmts[i].Op == OVARKILL {
-		i--
-	}
-	if i < 0 {
-		return false, src.NoXPos
-	}
-	return stmts[i].Op == OFALL, stmts[i].Pos
-}
-
-// walkTypeSwitch generates an AST that implements sw, where sw is a
-// type switch.
-func walkTypeSwitch(sw *Node) {
-	var s typeSwitch
-	s.facename = sw.Left.Right
-	sw.Left = nil
-
-	s.facename = walkexpr(s.facename, &sw.Ninit)
-	s.facename = copyexpr(s.facename, s.facename.Type, &sw.Nbody)
-	s.okname = temp(types.Types[TBOOL])
-
-	// Get interface descriptor word.
-	// For empty interfaces this will be the type.
-	// For non-empty interfaces this will be the itab.
-	itab := nod(OITAB, s.facename, nil)
-
-	// For empty interfaces, do:
-	//     if e._type == nil {
-	//         do nil case if it exists, otherwise default
-	//     }
-	//     h := e._type.hash
-	// Use a similar strategy for non-empty interfaces.
-	ifNil := nod(OIF, nil, nil)
-	ifNil.Left = nod(OEQ, itab, nodnil())
-	lineno = lineno.WithNotStmt() // disable statement marks after the first check.
-	ifNil.Left = typecheck(ifNil.Left, ctxExpr)
-	ifNil.Left = defaultlit(ifNil.Left, nil)
-	// ifNil.Nbody assigned at end.
-	sw.Nbody.Append(ifNil)
-
-	// Load hash from type or itab.
-	dotHash := nodSym(ODOTPTR, itab, nil)
-	dotHash.Type = types.Types[TUINT32]
-	dotHash.SetTypecheck(1)
-	if s.facename.Type.IsEmptyInterface() {
-		dotHash.Xoffset = int64(2 * Widthptr) // offset of hash in runtime._type
-	} else {
-		dotHash.Xoffset = int64(2 * Widthptr) // offset of hash in runtime.itab
-	}
-	dotHash.SetBounded(true) // guaranteed not to fault
-	s.hashname = copyexpr(dotHash, dotHash.Type, &sw.Nbody)
-
-	br := nod(OBREAK, nil, nil)
-	var defaultGoto, nilGoto *Node
-	var body Nodes
-	for _, ncase := range sw.List.Slice() {
-		var caseVar *Node
-		if ncase.Rlist.Len() != 0 {
-			caseVar = ncase.Rlist.First()
-		}
-
-		// For single-type cases with an interface type,
-		// we initialize the case variable as part of the type assertion.
-		// In other cases, we initialize it in the body.
-		var singleType *types.Type
-		if ncase.List.Len() == 1 && ncase.List.First().Op == OTYPE {
-			singleType = ncase.List.First().Type
-		}
-		caseVarInitialized := false
-
-		label := autolabel(".s")
-		jmp := npos(ncase.Pos, nodSym(OGOTO, nil, label))
-
-		if ncase.List.Len() == 0 { // default:
-			if defaultGoto != nil {
-				Fatalf("duplicate default case not detected during typechecking")
-			}
-			defaultGoto = jmp
-		}
-
-		for _, n1 := range ncase.List.Slice() {
-			if n1.isNil() { // case nil:
-				if nilGoto != nil {
-					Fatalf("duplicate nil case not detected during typechecking")
-				}
-				nilGoto = jmp
-				continue
-			}
-
-			if singleType != nil && singleType.IsInterface() {
-				s.Add(ncase.Pos, n1.Type, caseVar, jmp)
-				caseVarInitialized = true
-			} else {
-				s.Add(ncase.Pos, n1.Type, nil, jmp)
-			}
-		}
-
-		body.Append(npos(ncase.Pos, nodSym(OLABEL, nil, label)))
-		if caseVar != nil && !caseVarInitialized {
-			val := s.facename
-			if singleType != nil {
-				// We have a single concrete type. Extract the data.
-				if singleType.IsInterface() {
-					Fatalf("singleType interface should have been handled in Add")
-				}
-				val = ifaceData(ncase.Pos, s.facename, singleType)
-			}
-			l := []*Node{
-				nodl(ncase.Pos, ODCL, caseVar, nil),
-				nodl(ncase.Pos, OAS, caseVar, val),
-			}
-			typecheckslice(l, ctxStmt)
-			body.Append(l...)
-		}
-		body.Append(ncase.Nbody.Slice()...)
-		body.Append(br)
-	}
-	sw.List.Set(nil)
-
-	if defaultGoto == nil {
-		defaultGoto = br
-	}
-	if nilGoto == nil {
-		nilGoto = defaultGoto
-	}
-	ifNil.Nbody.Set1(nilGoto)
-
-	s.Emit(&sw.Nbody)
-	sw.Nbody.Append(defaultGoto)
-	sw.Nbody.AppendNodes(&body)
-
-	walkstmtlist(sw.Nbody.Slice())
-}
-
-// A typeSwitch walks a type switch.
-type typeSwitch struct {
-	// Temporary variables (i.e., ONAMEs) used by type switch dispatch logic:
-	facename *Node // value being type-switched on
-	hashname *Node // type hash of the value being type-switched on
-	okname   *Node // boolean used for comma-ok type assertions
-
-	done    Nodes
-	clauses []typeClause
-}
-
-type typeClause struct {
-	hash uint32
-	body Nodes
-}
-
-func (s *typeSwitch) Add(pos src.XPos, typ *types.Type, caseVar, jmp *Node) {
-	var body Nodes
-	if caseVar != nil {
-		l := []*Node{
-			nodl(pos, ODCL, caseVar, nil),
-			nodl(pos, OAS, caseVar, nil),
-		}
-		typecheckslice(l, ctxStmt)
-		body.Append(l...)
-	} else {
-		caseVar = nblank
-	}
-
-	// cv, ok = iface.(type)
-	as := nodl(pos, OAS2, nil, nil)
-	as.List.Set2(caseVar, s.okname) // cv, ok =
-	dot := nodl(pos, ODOTTYPE, s.facename, nil)
-	dot.Type = typ // iface.(type)
-	as.Rlist.Set1(dot)
-	as = typecheck(as, ctxStmt)
-	as = walkexpr(as, &body)
-	body.Append(as)
-
-	// if ok { goto label }
-	nif := nodl(pos, OIF, nil, nil)
-	nif.Left = s.okname
-	nif.Nbody.Set1(jmp)
-	body.Append(nif)
-
-	if !typ.IsInterface() {
-		s.clauses = append(s.clauses, typeClause{
-			hash: typehash(typ),
-			body: body,
-		})
-		return
-	}
-
-	s.flush()
-	s.done.AppendNodes(&body)
-}
-
-func (s *typeSwitch) Emit(out *Nodes) {
-	s.flush()
-	out.AppendNodes(&s.done)
-}
-
-func (s *typeSwitch) flush() {
-	cc := s.clauses
-	s.clauses = nil
-	if len(cc) == 0 {
-		return
-	}
-
-	sort.Slice(cc, func(i, j int) bool { return cc[i].hash < cc[j].hash })
-
-	// Combine adjacent cases with the same hash.
-	merged := cc[:1]
-	for _, c := range cc[1:] {
-		last := &merged[len(merged)-1]
-		if last.hash == c.hash {
-			last.body.AppendNodes(&c.body)
-		} else {
-			merged = append(merged, c)
-		}
-	}
-	cc = merged
-
-	binarySearch(len(cc), &s.done,
-		func(i int) *Node {
-			return nod(OLE, s.hashname, nodintconst(int64(cc[i-1].hash)))
-		},
-		func(i int, nif *Node) {
-			// TODO(mdempsky): Omit hash equality check if
-			// there's only one type.
-			c := cc[i]
-			nif.Left = nod(OEQ, s.hashname, nodintconst(int64(c.hash)))
-			nif.Nbody.AppendNodes(&c.body)
-		},
-	)
-}
-
-// binarySearch constructs a binary search tree for handling n cases,
-// and appends it to out. It's used for efficiently implementing
-// switch statements.
-//
-// less(i) should return a boolean expression. If it evaluates true,
-// then cases before i will be tested; otherwise, cases i and later.
-//
-// base(i, nif) should setup nif (an OIF node) to test case i. In
-// particular, it should set nif.Left and nif.Nbody.
-func binarySearch(n int, out *Nodes, less func(i int) *Node, base func(i int, nif *Node)) {
-	const binarySearchMin = 4 // minimum number of cases for binary search
-
-	var do func(lo, hi int, out *Nodes)
-	do = func(lo, hi int, out *Nodes) {
-		n := hi - lo
-		if n < binarySearchMin {
-			for i := lo; i < hi; i++ {
-				nif := nod(OIF, nil, nil)
-				base(i, nif)
-				lineno = lineno.WithNotStmt()
-				nif.Left = typecheck(nif.Left, ctxExpr)
-				nif.Left = defaultlit(nif.Left, nil)
-				out.Append(nif)
-				out = &nif.Rlist
-			}
-			return
-		}
-
-		half := lo + n/2
-		nif := nod(OIF, nil, nil)
-		nif.Left = less(half)
-		lineno = lineno.WithNotStmt()
-		nif.Left = typecheck(nif.Left, ctxExpr)
-		nif.Left = defaultlit(nif.Left, nil)
-		do(lo, half, &nif.Nbody)
-		do(half, hi, &nif.Rlist)
-		out.Append(nif)
-	}
-
-	do(0, n, out)
-}
diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go
deleted file mode 100644
index 7b4a315..0000000
--- a/src/cmd/compile/internal/gc/syntax.go
+++ /dev/null
@@ -1,1196 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// “Abstract” syntax representation.
-
-package gc
-
-import (
-	"cmd/compile/internal/ssa"
-	"cmd/compile/internal/types"
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"cmd/internal/src"
-	"sort"
-)
-
-// A Node is a single node in the syntax tree.
-// Actually the syntax tree is a syntax DAG, because there is only one
-// node with Op=ONAME for a given instance of a variable x.
-// The same is true for Op=OTYPE and Op=OLITERAL. See Node.mayBeShared.
-type Node struct {
-	// Tree structure.
-	// Generic recursive walks should follow these fields.
-	Left  *Node
-	Right *Node
-	Ninit Nodes
-	Nbody Nodes
-	List  Nodes
-	Rlist Nodes
-
-	// most nodes
-	Type *types.Type
-	Orig *Node // original form, for printing, and tracking copies of ONAMEs
-
-	// func
-	Func *Func
-
-	// ONAME, OTYPE, OPACK, OLABEL, some OLITERAL
-	Name *Name
-
-	Sym *types.Sym  // various
-	E   interface{} // Opt or Val, see methods below
-
-	// Various. Usually an offset into a struct. For example:
-	// - ONAME nodes that refer to local variables use it to identify their stack frame position.
-	// - ODOT, ODOTPTR, and ORESULT use it to indicate offset relative to their base address.
-	// - OSTRUCTKEY uses it to store the named field's offset.
-	// - Named OLITERALs use it to store their ambient iota value.
-	// - OINLMARK stores an index into the inlTree data structure.
-	// - OCLOSURE uses it to store ambient iota value, if any.
-	// Possibly still more uses. If you find any, document them.
-	Xoffset int64
-
-	Pos src.XPos
-
-	flags bitset32
-
-	Esc uint16 // EscXXX
-
-	Op  Op
-	aux uint8
-}
-
-func (n *Node) ResetAux() {
-	n.aux = 0
-}
-
-func (n *Node) SubOp() Op {
-	switch n.Op {
-	case OASOP, ONAME:
-	default:
-		Fatalf("unexpected op: %v", n.Op)
-	}
-	return Op(n.aux)
-}
-
-func (n *Node) SetSubOp(op Op) {
-	switch n.Op {
-	case OASOP, ONAME:
-	default:
-		Fatalf("unexpected op: %v", n.Op)
-	}
-	n.aux = uint8(op)
-}
-
-func (n *Node) IndexMapLValue() bool {
-	if n.Op != OINDEXMAP {
-		Fatalf("unexpected op: %v", n.Op)
-	}
-	return n.aux != 0
-}
-
-func (n *Node) SetIndexMapLValue(b bool) {
-	if n.Op != OINDEXMAP {
-		Fatalf("unexpected op: %v", n.Op)
-	}
-	if b {
-		n.aux = 1
-	} else {
-		n.aux = 0
-	}
-}
-
-func (n *Node) TChanDir() types.ChanDir {
-	if n.Op != OTCHAN {
-		Fatalf("unexpected op: %v", n.Op)
-	}
-	return types.ChanDir(n.aux)
-}
-
-func (n *Node) SetTChanDir(dir types.ChanDir) {
-	if n.Op != OTCHAN {
-		Fatalf("unexpected op: %v", n.Op)
-	}
-	n.aux = uint8(dir)
-}
-
-func (n *Node) IsSynthetic() bool {
-	name := n.Sym.Name
-	return name[0] == '.' || name[0] == '~'
-}
-
-// IsAutoTmp indicates if n was created by the compiler as a temporary,
-// based on the setting of the .AutoTemp flag in n's Name.
-func (n *Node) IsAutoTmp() bool {
-	if n == nil || n.Op != ONAME {
-		return false
-	}
-	return n.Name.AutoTemp()
-}
-
-const (
-	nodeClass, _     = iota, 1 << iota // PPARAM, PAUTO, PEXTERN, etc; three bits; first in the list because frequently accessed
-	_, _                               // second nodeClass bit
-	_, _                               // third nodeClass bit
-	nodeWalkdef, _                     // tracks state during typecheckdef; 2 == loop detected; two bits
-	_, _                               // second nodeWalkdef bit
-	nodeTypecheck, _                   // tracks state during typechecking; 2 == loop detected; two bits
-	_, _                               // second nodeTypecheck bit
-	nodeInitorder, _                   // tracks state during init1; two bits
-	_, _                               // second nodeInitorder bit
-	_, nodeHasBreak
-	_, nodeNoInline  // used internally by inliner to indicate that a function call should not be inlined; set for OCALLFUNC and OCALLMETH only
-	_, nodeImplicit  // implicit OADDR or ODEREF; ++/-- statement represented as OASOP
-	_, nodeIsDDD     // is the argument variadic
-	_, nodeDiag      // already printed error about this
-	_, nodeColas     // OAS resulting from :=
-	_, nodeNonNil    // guaranteed to be non-nil
-	_, nodeTransient // storage can be reused immediately after this statement
-	_, nodeBounded   // bounds check unnecessary
-	_, 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
-)
-
-func (n *Node) Class() Class     { return Class(n.flags.get3(nodeClass)) }
-func (n *Node) Walkdef() uint8   { return n.flags.get2(nodeWalkdef) }
-func (n *Node) Typecheck() uint8 { return n.flags.get2(nodeTypecheck) }
-func (n *Node) Initorder() uint8 { return n.flags.get2(nodeInitorder) }
-
-func (n *Node) HasBreak() bool  { return n.flags&nodeHasBreak != 0 }
-func (n *Node) NoInline() bool  { return n.flags&nodeNoInline != 0 }
-func (n *Node) Implicit() bool  { return n.flags&nodeImplicit != 0 }
-func (n *Node) IsDDD() bool     { return n.flags&nodeIsDDD != 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 }
-func (n *Node) Transient() bool { return n.flags&nodeTransient != 0 }
-func (n *Node) Bounded() bool   { return n.flags&nodeBounded != 0 }
-func (n *Node) HasCall() bool   { return n.flags&nodeHasCall != 0 }
-func (n *Node) Likely() bool    { return n.flags&nodeLikely != 0 }
-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) SetClass(b Class)     { n.flags.set3(nodeClass, uint8(b)) }
-func (n *Node) SetWalkdef(b uint8)   { n.flags.set2(nodeWalkdef, b) }
-func (n *Node) SetTypecheck(b uint8) { n.flags.set2(nodeTypecheck, b) }
-func (n *Node) SetInitorder(b uint8) { n.flags.set2(nodeInitorder, b) }
-
-func (n *Node) SetHasBreak(b bool)  { n.flags.set(nodeHasBreak, b) }
-func (n *Node) SetNoInline(b bool)  { n.flags.set(nodeNoInline, 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) SetDiag(b bool)      { n.flags.set(nodeDiag, b) }
-func (n *Node) SetColas(b bool)     { n.flags.set(nodeColas, b) }
-func (n *Node) SetTransient(b bool) { n.flags.set(nodeTransient, b) }
-func (n *Node) SetHasCall(b bool)   { n.flags.set(nodeHasCall, b) }
-func (n *Node) SetLikely(b bool)    { n.flags.set(nodeLikely, b) }
-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) }
-
-// MarkNonNil marks a pointer n as being guaranteed non-nil,
-// on all code paths, at all times.
-// During conversion to SSA, non-nil pointers won't have nil checks
-// inserted before dereferencing. See state.exprPtr.
-func (n *Node) MarkNonNil() {
-	if !n.Type.IsPtr() && !n.Type.IsUnsafePtr() {
-		Fatalf("MarkNonNil(%v), type %v", n, n.Type)
-	}
-	n.flags.set(nodeNonNil, true)
-}
-
-// SetBounded indicates whether operation n does not need safety checks.
-// When n is an index or slice operation, n does not need bounds checks.
-// When n is a dereferencing operation, n does not need nil checks.
-// When n is a makeslice+copy operation, n does not need length and cap checks.
-func (n *Node) SetBounded(b bool) {
-	switch n.Op {
-	case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR:
-		// No bounds checks needed.
-	case ODOTPTR, ODEREF:
-		// No nil check needed.
-	case OMAKESLICECOPY:
-		// No length and cap checks needed
-		// since new slice and copied over slice data have same length.
-	default:
-		Fatalf("SetBounded(%v)", n)
-	}
-	n.flags.set(nodeBounded, b)
-}
-
-// MarkReadonly indicates that n is an ONAME with readonly contents.
-func (n *Node) MarkReadonly() {
-	if n.Op != ONAME {
-		Fatalf("Node.MarkReadonly %v", n.Op)
-	}
-	n.Name.SetReadonly(true)
-	// Mark the linksym as readonly immediately
-	// so that the SSA backend can use this information.
-	// It will be overridden later during dumpglobls.
-	n.Sym.Linksym().Type = objabi.SRODATA
-}
-
-// Val returns the Val for the node.
-func (n *Node) Val() Val {
-	if !n.HasVal() {
-		return Val{}
-	}
-	return Val{n.E}
-}
-
-// SetVal sets the Val for the node, which must not have been used with SetOpt.
-func (n *Node) SetVal(v Val) {
-	if n.HasOpt() {
-		Debug.h = 1
-		Dump("have Opt", n)
-		Fatalf("have Opt")
-	}
-	n.SetHasVal(true)
-	n.E = v.U
-}
-
-// Opt returns the optimizer data for the node.
-func (n *Node) Opt() interface{} {
-	if !n.HasOpt() {
-		return nil
-	}
-	return n.E
-}
-
-// SetOpt sets the optimizer data for the node, which must not have been used with SetVal.
-// SetOpt(nil) is ignored for Vals to simplify call sites that are clearing Opts.
-func (n *Node) SetOpt(x interface{}) {
-	if x == nil && n.HasVal() {
-		return
-	}
-	if n.HasVal() {
-		Debug.h = 1
-		Dump("have Val", n)
-		Fatalf("have Val")
-	}
-	n.SetHasOpt(true)
-	n.E = x
-}
-
-func (n *Node) Iota() int64 {
-	return n.Xoffset
-}
-
-func (n *Node) SetIota(x int64) {
-	n.Xoffset = x
-}
-
-// mayBeShared reports whether n may occur in multiple places in the AST.
-// Extra care must be taken when mutating such a node.
-func (n *Node) mayBeShared() bool {
-	switch n.Op {
-	case ONAME, OLITERAL, OTYPE:
-		return true
-	}
-	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 (without the package) of the function n.
-func (n *Node) funcname() string {
-	if n == nil || n.Func == nil || n.Func.Nname == nil {
-		return "<nil>"
-	}
-	return n.Func.Nname.Sym.Name
-}
-
-// pkgFuncName returns the name of the function referenced by n, with package prepended.
-// This differs from the compiler's internal convention where local functions lack a package
-// because the ultimate consumer of this is a human looking at an IDE; package is only empty
-// if the compilation package is actually the empty string.
-func (n *Node) pkgFuncName() string {
-	var s *types.Sym
-	if n == nil {
-		return "<nil>"
-	}
-	if n.Op == ONAME {
-		s = n.Sym
-	} else {
-		if n.Func == nil || n.Func.Nname == nil {
-			return "<nil>"
-		}
-		s = n.Func.Nname.Sym
-	}
-	pkg := s.Pkg
-
-	p := myimportpath
-	if pkg != nil && pkg.Path != "" {
-		p = pkg.Path
-	}
-	if p == "" {
-		return s.Name
-	}
-	return p + "." + s.Name
-}
-
-// The compiler needs *Node to be assignable to cmd/compile/internal/ssa.Sym.
-func (n *Node) CanBeAnSSASym() {
-}
-
-// Name holds Node fields used only by named nodes (ONAME, OTYPE, OPACK, OLABEL, some OLITERAL).
-type Name struct {
-	Pack *Node      // real package for import . names
-	Pkg  *types.Pkg // pkg for OPACK nodes
-	// For a local variable (not param) or extern, the initializing assignment (OAS or OAS2).
-	// For a closure var, the ONAME node of the outer captured variable
-	Defn *Node
-	// The ODCLFUNC node (for a static function/method or a closure) in which
-	// local variable or param is declared.
-	Curfn     *Node
-	Param     *Param // additional fields for ONAME, OTYPE
-	Decldepth int32  // declaration loop depth, increased for every loop or label
-	// Unique number for ONAME nodes within a function. Function outputs
-	// (results) are numbered starting at one, followed by function inputs
-	// (parameters), and then local variables. Vargen is used to distinguish
-	// local variables/params with the same name.
-	Vargen int32
-	flags  bitset16
-}
-
-const (
-	nameCaptured = 1 << iota // is the variable captured by a closure
-	nameReadonly
-	nameByval                 // is the variable captured by value or by reference
-	nameNeedzero              // if it contains pointers, needs to be zeroed on function entry
-	nameAutoTemp              // is the variable a temporary (implies no dwarf info. reset if escapes to heap)
-	nameUsed                  // for variable declared and not used error
-	nameIsClosureVar          // PAUTOHEAP closure pseudo-variable; original at n.Name.Defn
-	nameIsOutputParamHeapAddr // pointer to a result parameter's heap copy
-	nameAssigned              // is the variable ever assigned to
-	nameAddrtaken             // address taken, even if not moved to heap
-	nameInlFormal             // PAUTO created by inliner, derived from callee formal
-	nameInlLocal              // PAUTO created by inliner, derived from callee local
-	nameOpenDeferSlot         // if temporary var storing info for open-coded defers
-	nameLibfuzzerExtraCounter // if PEXTERN should be assigned to __libfuzzer_extra_counters section
-)
-
-func (n *Name) Captured() bool              { return n.flags&nameCaptured != 0 }
-func (n *Name) Readonly() bool              { return n.flags&nameReadonly != 0 }
-func (n *Name) Byval() bool                 { return n.flags&nameByval != 0 }
-func (n *Name) Needzero() bool              { return n.flags&nameNeedzero != 0 }
-func (n *Name) AutoTemp() bool              { return n.flags&nameAutoTemp != 0 }
-func (n *Name) Used() bool                  { return n.flags&nameUsed != 0 }
-func (n *Name) IsClosureVar() bool          { return n.flags&nameIsClosureVar != 0 }
-func (n *Name) IsOutputParamHeapAddr() bool { return n.flags&nameIsOutputParamHeapAddr != 0 }
-func (n *Name) Assigned() bool              { return n.flags&nameAssigned != 0 }
-func (n *Name) Addrtaken() bool             { return n.flags&nameAddrtaken != 0 }
-func (n *Name) InlFormal() bool             { return n.flags&nameInlFormal != 0 }
-func (n *Name) InlLocal() bool              { return n.flags&nameInlLocal != 0 }
-func (n *Name) OpenDeferSlot() bool         { return n.flags&nameOpenDeferSlot != 0 }
-func (n *Name) LibfuzzerExtraCounter() bool { return n.flags&nameLibfuzzerExtraCounter != 0 }
-
-func (n *Name) SetCaptured(b bool)              { n.flags.set(nameCaptured, b) }
-func (n *Name) SetReadonly(b bool)              { n.flags.set(nameReadonly, b) }
-func (n *Name) SetByval(b bool)                 { n.flags.set(nameByval, b) }
-func (n *Name) SetNeedzero(b bool)              { n.flags.set(nameNeedzero, b) }
-func (n *Name) SetAutoTemp(b bool)              { n.flags.set(nameAutoTemp, b) }
-func (n *Name) SetUsed(b bool)                  { n.flags.set(nameUsed, b) }
-func (n *Name) SetIsClosureVar(b bool)          { n.flags.set(nameIsClosureVar, b) }
-func (n *Name) SetIsOutputParamHeapAddr(b bool) { n.flags.set(nameIsOutputParamHeapAddr, b) }
-func (n *Name) SetAssigned(b bool)              { n.flags.set(nameAssigned, b) }
-func (n *Name) SetAddrtaken(b bool)             { n.flags.set(nameAddrtaken, b) }
-func (n *Name) SetInlFormal(b bool)             { n.flags.set(nameInlFormal, b) }
-func (n *Name) SetInlLocal(b bool)              { n.flags.set(nameInlLocal, b) }
-func (n *Name) SetOpenDeferSlot(b bool)         { n.flags.set(nameOpenDeferSlot, b) }
-func (n *Name) SetLibfuzzerExtraCounter(b bool) { n.flags.set(nameLibfuzzerExtraCounter, b) }
-
-type Param struct {
-	Ntype    *Node
-	Heapaddr *Node // temp holding heap address of param
-
-	// ONAME PAUTOHEAP
-	Stackcopy *Node // the PPARAM/PPARAMOUT on-stack slot (moved func params only)
-
-	// ONAME closure linkage
-	// Consider:
-	//
-	//	func f() {
-	//		x := 1 // x1
-	//		func() {
-	//			use(x) // x2
-	//			func() {
-	//				use(x) // x3
-	//				--- parser is here ---
-	//			}()
-	//		}()
-	//	}
-	//
-	// There is an original declaration of x and then a chain of mentions of x
-	// leading into the current function. Each time x is mentioned in a new closure,
-	// we create a variable representing x for use in that specific closure,
-	// since the way you get to x is different in each closure.
-	//
-	// Let's number the specific variables as shown in the code:
-	// x1 is the original x, x2 is when mentioned in the closure,
-	// and x3 is when mentioned in the closure in the closure.
-	//
-	// We keep these linked (assume N > 1):
-	//
-	//   - x1.Defn = original declaration statement for x (like most variables)
-	//   - x1.Innermost = current innermost closure x (in this case x3), or nil for none
-	//   - x1.IsClosureVar() = false
-	//
-	//   - xN.Defn = x1, N > 1
-	//   - xN.IsClosureVar() = true, N > 1
-	//   - x2.Outer = nil
-	//   - xN.Outer = x(N-1), N > 2
-	//
-	//
-	// When we look up x in the symbol table, we always get x1.
-	// Then we can use x1.Innermost (if not nil) to get the x
-	// for the innermost known closure function,
-	// but the first reference in a closure will find either no x1.Innermost
-	// or an x1.Innermost with .Funcdepth < Funcdepth.
-	// In that case, a new xN must be created, linked in with:
-	//
-	//     xN.Defn = x1
-	//     xN.Outer = x1.Innermost
-	//     x1.Innermost = xN
-	//
-	// When we finish the function, we'll process its closure variables
-	// and find xN and pop it off the list using:
-	//
-	//     x1 := xN.Defn
-	//     x1.Innermost = xN.Outer
-	//
-	// We leave x1.Innermost set so that we can still get to the original
-	// variable quickly. Not shown here, but once we're
-	// done parsing a function and no longer need xN.Outer for the
-	// lexical x reference links as described above, funcLit
-	// recomputes xN.Outer as the semantic x reference link tree,
-	// even filling in x in intermediate closures that might not
-	// have mentioned it along the way to inner closures that did.
-	// See funcLit for details.
-	//
-	// During the eventual compilation, then, for closure variables we have:
-	//
-	//     xN.Defn = original variable
-	//     xN.Outer = variable captured in next outward scope
-	//                to make closure where xN appears
-	//
-	// Because of the sharding of pieces of the node, x.Defn means x.Name.Defn
-	// and x.Innermost/Outer means x.Name.Param.Innermost/Outer.
-	Innermost *Node
-	Outer     *Node
-
-	// OTYPE & ONAME //go:embed info,
-	// sharing storage to reduce gc.Param size.
-	// Extra is nil, or else *Extra is a *paramType or an *embedFileList.
-	Extra *interface{}
-}
-
-type paramType struct {
-	flag  PragmaFlag
-	alias bool
-}
-
-type irEmbed struct {
-	Pos      src.XPos
-	Patterns []string
-}
-
-type embedList []irEmbed
-
-// Pragma returns the PragmaFlag for p, which must be for an OTYPE.
-func (p *Param) Pragma() PragmaFlag {
-	if p.Extra == nil {
-		return 0
-	}
-	return (*p.Extra).(*paramType).flag
-}
-
-// SetPragma sets the PragmaFlag for p, which must be for an OTYPE.
-func (p *Param) SetPragma(flag PragmaFlag) {
-	if p.Extra == nil {
-		if flag == 0 {
-			return
-		}
-		p.Extra = new(interface{})
-		*p.Extra = &paramType{flag: flag}
-		return
-	}
-	(*p.Extra).(*paramType).flag = flag
-}
-
-// Alias reports whether p, which must be for an OTYPE, is a type alias.
-func (p *Param) Alias() bool {
-	if p.Extra == nil {
-		return false
-	}
-	t, ok := (*p.Extra).(*paramType)
-	if !ok {
-		return false
-	}
-	return t.alias
-}
-
-// SetAlias sets whether p, which must be for an OTYPE, is a type alias.
-func (p *Param) SetAlias(alias bool) {
-	if p.Extra == nil {
-		if !alias {
-			return
-		}
-		p.Extra = new(interface{})
-		*p.Extra = &paramType{alias: alias}
-		return
-	}
-	(*p.Extra).(*paramType).alias = alias
-}
-
-// EmbedList returns the list of embedded files for p,
-// which must be for an ONAME var.
-func (p *Param) EmbedList() []irEmbed {
-	if p.Extra == nil {
-		return nil
-	}
-	return *(*p.Extra).(*embedList)
-}
-
-// SetEmbedList sets the list of embedded files for p,
-// which must be for an ONAME var.
-func (p *Param) SetEmbedList(list []irEmbed) {
-	if p.Extra == nil {
-		if len(list) == 0 {
-			return
-		}
-		f := embedList(list)
-		p.Extra = new(interface{})
-		*p.Extra = &f
-		return
-	}
-	*(*p.Extra).(*embedList) = list
-}
-
-// 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
-	// Extra entry code for the function. For example, allocate and initialize
-	// memory for escaping parameters. However, just for OCLOSURE, Enter is a
-	// list of ONAME nodes of captured variables
-	Enter Nodes
-	Exit  Nodes
-	// ONAME nodes for closure params, each should have closurevar set
-	Cvars Nodes
-	// ONAME nodes for all params/locals for this func/closure, does NOT
-	// include closurevars until transformclosure runs.
-	Dcl []*Node
-
-	// Parents records the parent scope of each scope within a
-	// function. The root scope (0) has no parent, so the i'th
-	// scope's parent is stored at Parents[i-1].
-	Parents []ScopeID
-
-	// Marks records scope boundary changes.
-	Marks []Mark
-
-	// Closgen tracks how many closures have been generated within
-	// this function. Used by closurename for creating unique
-	// function names.
-	Closgen int
-
-	FieldTrack map[*types.Sym]struct{}
-	DebugInfo  *ssa.FuncDebug
-	Ntype      *Node // signature
-	Top        int   // top context (ctxCallee, etc)
-	Closure    *Node // OCLOSURE <-> ODCLFUNC (see header comment above)
-	Nname      *Node // The ONAME node associated with an ODCLFUNC (both have same Type)
-	lsym       *obj.LSym
-
-	Inl *Inline
-
-	Label int32 // largest auto-generated label in this function
-
-	Endlineno src.XPos
-	WBPos     src.XPos // position of first write barrier; see SetWBPos
-
-	Pragma PragmaFlag // go:xxx function annotations
-
-	flags      bitset16
-	numDefers  int // number of defer calls in the function
-	numReturns int // number of explicit returns in the function
-
-	// nwbrCalls records the LSyms of functions called by this
-	// function for go:nowritebarrierrec analysis. Only filled in
-	// if nowritebarrierrecCheck != nil.
-	nwbrCalls *[]nowritebarrierrecCallSym
-}
-
-// An Inline holds fields used for function bodies that can be inlined.
-type Inline struct {
-	Cost int32 // heuristic cost of inlining this function
-
-	// Copies of Func.Dcl and Nbody for use during inlining.
-	Dcl  []*Node
-	Body []*Node
-}
-
-// A Mark represents a scope boundary.
-type Mark struct {
-	// Pos is the position of the token that marks the scope
-	// change.
-	Pos src.XPos
-
-	// Scope identifies the innermost scope to the right of Pos.
-	Scope ScopeID
-}
-
-// A ScopeID represents a lexical scope within a function.
-type ScopeID int32
-
-const (
-	funcDupok         = 1 << iota // duplicate definitions ok
-	funcWrapper                   // is method wrapper
-	funcNeedctxt                  // function uses context register (has closure variables)
-	funcReflectMethod             // function calls reflect.Type.Method or MethodByName
-	// true if closure inside a function; false if a simple function or a
-	// closure in a global variable initialization
-	funcIsHiddenClosure
-	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
-	funcInstrumentBody           // add race/msan instrumentation during SSA construction
-	funcOpenCodedDeferDisallowed // can't do open-coded defers
-)
-
-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) 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) InstrumentBody() bool           { return f.flags&funcInstrumentBody != 0 }
-func (f *Func) OpenCodedDeferDisallowed() bool { return f.flags&funcOpenCodedDeferDisallowed != 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) 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) SetInstrumentBody(b bool)           { f.flags.set(funcInstrumentBody, b) }
-func (f *Func) SetOpenCodedDeferDisallowed(b bool) { f.flags.set(funcOpenCodedDeferDisallowed, 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
-
-	// names
-	ONAME // var or func name
-	// Unnamed arg or return value: f(int, string) (int, error) { etc }
-	// Also used for a qualified package identifier that hasn't been resolved yet.
-	ONONAME
-	OTYPE    // type name
-	OPACK    // import
-	OLITERAL // literal
-
-	// expressions
-	OADD          // Left + Right
-	OSUB          // Left - Right
-	OOR           // Left | Right
-	OXOR          // Left ^ Right
-	OADDSTR       // +{List} (string addition, list elements are strings)
-	OADDR         // &Left
-	OANDAND       // Left && Right
-	OAPPEND       // append(List); after walk, Left may contain elem type descriptor
-	OBYTES2STR    // Type(Left) (Type is string, Left is a []byte)
-	OBYTES2STRTMP // Type(Left) (Type is string, Left is a []byte, ephemeral)
-	ORUNES2STR    // Type(Left) (Type is string, Left is a []rune)
-	OSTR2BYTES    // Type(Left) (Type is []byte, Left is a string)
-	OSTR2BYTESTMP // Type(Left) (Type is []byte, Left is a string, ephemeral)
-	OSTR2RUNES    // Type(Left) (Type is []rune, Left is a string)
-	// Left = Right or (if Colas=true) Left := Right
-	// If Colas, then Ninit includes a DCL node for Left.
-	OAS
-	// List = Rlist (x, y, z = a, b, c) or (if Colas=true) List := Rlist
-	// If Colas, then Ninit includes DCL nodes for List
-	OAS2
-	OAS2DOTTYPE // List = Right (x, ok = I.(int))
-	OAS2FUNC    // List = Right (x, y = f())
-	OAS2MAPR    // List = Right (x, ok = m["foo"])
-	OAS2RECV    // List = Right (x, ok = <-c)
-	OASOP       // Left Etype= Right (x += y)
-	OCALL       // Left(List) (function call, method call or type conversion)
-
-	// OCALLFUNC, OCALLMETH, and OCALLINTER have the same structure.
-	// Prior to walk, they are: Left(List), where List is all regular arguments.
-	// After walk, List is a series of assignments to temporaries,
-	// and Rlist is an updated set of arguments.
-	// Nbody is all OVARLIVE nodes that are attached to OCALLxxx.
-	// TODO(josharian/khr): Use Ninit instead of List for the assignments to temporaries. See CL 114797.
-	OCALLFUNC  // Left(List/Rlist) (function call f(args))
-	OCALLMETH  // Left(List/Rlist) (direct method call x.Method(args))
-	OCALLINTER // Left(List/Rlist) (interface method call x.Method(args))
-	OCALLPART  // Left.Right (method expression x.Method, not called)
-	OCAP       // cap(Left)
-	OCLOSE     // close(Left)
-	OCLOSURE   // func Type { Func.Closure.Nbody } (func literal)
-	OCOMPLIT   // Right{List} (composite literal, not yet lowered to specific form)
-	OMAPLIT    // Type{List} (composite literal, Type is map)
-	OSTRUCTLIT // Type{List} (composite literal, Type is struct)
-	OARRAYLIT  // Type{List} (composite literal, Type is array)
-	OSLICELIT  // Type{List} (composite literal, Type is slice) Right.Int64() = slice length.
-	OPTRLIT    // &Left (left is composite literal)
-	OCONV      // Type(Left) (type conversion)
-	OCONVIFACE // Type(Left) (type conversion, to interface)
-	OCONVNOP   // Type(Left) (type conversion, no effect)
-	OCOPY      // copy(Left, Right)
-	ODCL       // var Left (declares Left of type Left.Type)
-
-	// Used during parsing but don't last.
-	ODCLFUNC  // func f() or func (r) f()
-	ODCLFIELD // struct field, interface field, or func/method argument/return value.
-	ODCLCONST // const pi = 3.14
-	ODCLTYPE  // type Int int or type Int = int
-
-	ODELETE        // delete(List)
-	ODOT           // Left.Sym (Left is of struct type)
-	ODOTPTR        // Left.Sym (Left is of pointer to struct type)
-	ODOTMETH       // Left.Sym (Left is non-interface, Right is method name)
-	ODOTINTER      // Left.Sym (Left is interface, Right is method name)
-	OXDOT          // Left.Sym (before rewrite to one of the preceding)
-	ODOTTYPE       // Left.Right or Left.Type (.Right during parsing, .Type once resolved); after walk, .Right contains address of interface type descriptor and .Right.Right contains address of concrete type descriptor
-	ODOTTYPE2      // Left.Right or Left.Type (.Right during parsing, .Type once resolved; on rhs of OAS2DOTTYPE); after walk, .Right contains address of interface type descriptor
-	OEQ            // Left == Right
-	ONE            // Left != Right
-	OLT            // Left < Right
-	OLE            // Left <= Right
-	OGE            // Left >= Right
-	OGT            // Left > Right
-	ODEREF         // *Left
-	OINDEX         // Left[Right] (index of array or slice)
-	OINDEXMAP      // Left[Right] (index of map)
-	OKEY           // Left:Right (key:value in struct/array/map literal)
-	OSTRUCTKEY     // Sym:Left (key:value in struct literal, after type checking)
-	OLEN           // len(Left)
-	OMAKE          // make(List) (before type checking converts to one of the following)
-	OMAKECHAN      // make(Type, Left) (type is chan)
-	OMAKEMAP       // make(Type, Left) (type is map)
-	OMAKESLICE     // make(Type, Left, Right) (type is slice)
-	OMAKESLICECOPY // makeslicecopy(Type, Left, Right) (type is slice; Left is length and Right is the copied from slice)
-	// OMAKESLICECOPY is created by the order pass and corresponds to:
-	//  s = make(Type, Left); copy(s, Right)
-	//
-	// Bounded can be set on the node when Left == len(Right) is known at compile time.
-	//
-	// This node is created so the walk pass can optimize this pattern which would
-	// otherwise be hard to detect after the order pass.
-	OMUL         // Left * Right
-	ODIV         // Left / Right
-	OMOD         // Left % Right
-	OLSH         // Left << Right
-	ORSH         // Left >> Right
-	OAND         // Left & Right
-	OANDNOT      // Left &^ Right
-	ONEW         // new(Left); corresponds to calls to new in source code
-	ONEWOBJ      // runtime.newobject(n.Type); introduced by walk; Left is type descriptor
-	ONOT         // !Left
-	OBITNOT      // ^Left
-	OPLUS        // +Left
-	ONEG         // -Left
-	OOROR        // Left || Right
-	OPANIC       // panic(Left)
-	OPRINT       // print(List)
-	OPRINTN      // println(List)
-	OPAREN       // (Left)
-	OSEND        // Left <- Right
-	OSLICE       // Left[List[0] : List[1]] (Left is untypechecked or slice)
-	OSLICEARR    // Left[List[0] : List[1]] (Left is array)
-	OSLICESTR    // Left[List[0] : List[1]] (Left is string)
-	OSLICE3      // Left[List[0] : List[1] : List[2]] (Left is untypedchecked or slice)
-	OSLICE3ARR   // Left[List[0] : List[1] : List[2]] (Left is array)
-	OSLICEHEADER // sliceheader{Left, List[0], List[1]} (Left is unsafe.Pointer, List[0] is length, List[1] is capacity)
-	ORECOVER     // recover()
-	ORECV        // <-Left
-	ORUNESTR     // Type(Left) (Type is string, Left is rune)
-	OSELRECV     // Left = <-Right.Left: (appears as .Left of OCASE; Right.Op == ORECV)
-	OSELRECV2    // List = <-Right.Left: (appears as .Left of OCASE; count(List) == 2, Right.Op == ORECV)
-	OIOTA        // iota
-	OREAL        // real(Left)
-	OIMAG        // imag(Left)
-	OCOMPLEX     // complex(Left, Right) or complex(List[0]) where List[0] is a 2-result function call
-	OALIGNOF     // unsafe.Alignof(Left)
-	OOFFSETOF    // unsafe.Offsetof(Left)
-	OSIZEOF      // unsafe.Sizeof(Left)
-
-	// statements
-	OBLOCK // { List } (block of code)
-	OBREAK // break [Sym]
-	// OCASE:  case List: Nbody (List==nil means default)
-	//   For OTYPESW, List is a OTYPE node for the specified type (or OLITERAL
-	//   for nil), and, if a type-switch variable is specified, Rlist is an
-	//   ONAME for the version of the type-switch variable with the specified
-	//   type.
-	OCASE
-	OCONTINUE // continue [Sym]
-	ODEFER    // defer Left (Left must be call)
-	OEMPTY    // no-op (empty statement)
-	OFALL     // fallthrough
-	OFOR      // for Ninit; Left; Right { Nbody }
-	// OFORUNTIL is like OFOR, but the test (Left) is applied after the body:
-	// 	Ninit
-	// 	top: { Nbody }   // Execute the body at least once
-	// 	cont: Right
-	// 	if Left {        // And then test the loop condition
-	// 		List     // Before looping to top, execute List
-	// 		goto top
-	// 	}
-	// OFORUNTIL is created by walk. There's no way to write this in Go code.
-	OFORUNTIL
-	OGOTO   // goto Sym
-	OIF     // if Ninit; Left { Nbody } else { Rlist }
-	OLABEL  // Sym:
-	OGO     // go Left (Left must be call)
-	ORANGE  // for List = range Right { Nbody }
-	ORETURN // return List
-	OSELECT // select { List } (List is list of OCASE)
-	OSWITCH // switch Ninit; Left { List } (List is a list of OCASE)
-	// OTYPESW:  Left := Right.(type) (appears as .Left of OSWITCH)
-	//   Left is nil if there is no type-switch variable
-	OTYPESW
-
-	// types
-	OTCHAN   // chan int
-	OTMAP    // map[string]int
-	OTSTRUCT // struct{}
-	OTINTER  // interface{}
-	// OTFUNC: func() - Left is receiver field, List is list of param fields, Rlist is
-	// list of result fields.
-	OTFUNC
-	OTARRAY // []int, [8]int, [N]int or [...]int
-
-	// misc
-	ODDD        // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
-	OINLCALL    // intermediary representation of an inlined call.
-	OEFACE      // itable and data words of an empty-interface value.
-	OITAB       // itable word of an interface value.
-	OIDATA      // data word of an interface value in Left
-	OSPTR       // base pointer of a slice or string.
-	OCLOSUREVAR // variable reference at beginning of closure function
-	OCFUNC      // reference to c function pointer (not go func value)
-	OCHECKNIL   // emit code to ensure pointer/interface not nil
-	OVARDEF     // variable is about to be fully initialized
-	OVARKILL    // variable is dead
-	OVARLIVE    // variable is alive
-	ORESULT     // result of a function call; Xoffset is stack offset
-	OINLMARK    // start of an inlined body, with file/line of caller. Xoffset is an index into the inline tree.
-
-	// arch-specific opcodes
-	ORETJMP // return to other function
-	OGETG   // runtime.getg() (read g pointer)
-
-	OEND
-)
-
-// Nodes is a pointer to a slice of *Node.
-// For fields that are not used in most nodes, this is used instead of
-// a slice to save space.
-type Nodes struct{ slice *[]*Node }
-
-// asNodes returns a slice of *Node as a Nodes value.
-func asNodes(s []*Node) Nodes {
-	return Nodes{&s}
-}
-
-// Slice returns the entries in Nodes as a slice.
-// Changes to the slice entries (as in s[i] = n) will be reflected in
-// the Nodes.
-func (n Nodes) Slice() []*Node {
-	if n.slice == nil {
-		return nil
-	}
-	return *n.slice
-}
-
-// Len returns the number of entries in Nodes.
-func (n Nodes) Len() int {
-	if n.slice == nil {
-		return 0
-	}
-	return len(*n.slice)
-}
-
-// Index returns the i'th element of Nodes.
-// It panics if n does not have at least i+1 elements.
-func (n Nodes) Index(i int) *Node {
-	return (*n.slice)[i]
-}
-
-// First returns the first element of Nodes (same as n.Index(0)).
-// It panics if n has no elements.
-func (n Nodes) First() *Node {
-	return (*n.slice)[0]
-}
-
-// Second returns the second element of Nodes (same as n.Index(1)).
-// It panics if n has fewer than two elements.
-func (n Nodes) Second() *Node {
-	return (*n.slice)[1]
-}
-
-// Set sets n to a slice.
-// This takes ownership of the slice.
-func (n *Nodes) Set(s []*Node) {
-	if len(s) == 0 {
-		n.slice = nil
-	} else {
-		// Copy s and take address of t rather than s to avoid
-		// allocation in the case where len(s) == 0 (which is
-		// over 3x more common, dynamically, for make.bash).
-		t := s
-		n.slice = &t
-	}
-}
-
-// Set1 sets n to a slice containing a single node.
-func (n *Nodes) Set1(n1 *Node) {
-	n.slice = &[]*Node{n1}
-}
-
-// Set2 sets n to a slice containing two nodes.
-func (n *Nodes) Set2(n1, n2 *Node) {
-	n.slice = &[]*Node{n1, n2}
-}
-
-// Set3 sets n to a slice containing three nodes.
-func (n *Nodes) Set3(n1, n2, n3 *Node) {
-	n.slice = &[]*Node{n1, n2, n3}
-}
-
-// MoveNodes sets n to the contents of n2, then clears n2.
-func (n *Nodes) MoveNodes(n2 *Nodes) {
-	n.slice = n2.slice
-	n2.slice = nil
-}
-
-// SetIndex sets the i'th element of Nodes to node.
-// It panics if n does not have at least i+1 elements.
-func (n Nodes) SetIndex(i int, node *Node) {
-	(*n.slice)[i] = node
-}
-
-// SetFirst sets the first element of Nodes to node.
-// It panics if n does not have at least one elements.
-func (n Nodes) SetFirst(node *Node) {
-	(*n.slice)[0] = node
-}
-
-// SetSecond sets the second element of Nodes to node.
-// It panics if n does not have at least two elements.
-func (n Nodes) SetSecond(node *Node) {
-	(*n.slice)[1] = node
-}
-
-// Addr returns the address of the i'th element of Nodes.
-// It panics if n does not have at least i+1 elements.
-func (n Nodes) Addr(i int) **Node {
-	return &(*n.slice)[i]
-}
-
-// Append appends entries to Nodes.
-func (n *Nodes) Append(a ...*Node) {
-	if len(a) == 0 {
-		return
-	}
-	if n.slice == nil {
-		s := make([]*Node, len(a))
-		copy(s, a)
-		n.slice = &s
-		return
-	}
-	*n.slice = append(*n.slice, a...)
-}
-
-// Prepend prepends entries to Nodes.
-// If a slice is passed in, this will take ownership of it.
-func (n *Nodes) Prepend(a ...*Node) {
-	if len(a) == 0 {
-		return
-	}
-	if n.slice == nil {
-		n.slice = &a
-	} else {
-		*n.slice = append(a, *n.slice...)
-	}
-}
-
-// AppendNodes appends the contents of *n2 to n, then clears n2.
-func (n *Nodes) AppendNodes(n2 *Nodes) {
-	switch {
-	case n2.slice == nil:
-	case n.slice == nil:
-		n.slice = n2.slice
-	default:
-		*n.slice = append(*n.slice, *n2.slice...)
-	}
-	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 reports whether 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
-}
-
-// NodeSet is a set of Nodes.
-type NodeSet map[*Node]struct{}
-
-// Has reports whether s contains n.
-func (s NodeSet) Has(n *Node) bool {
-	_, isPresent := s[n]
-	return isPresent
-}
-
-// Add adds n to s.
-func (s *NodeSet) Add(n *Node) {
-	if *s == nil {
-		*s = make(map[*Node]struct{})
-	}
-	(*s)[n] = struct{}{}
-}
-
-// Sorted returns s sorted according to less.
-func (s NodeSet) Sorted(less func(*Node, *Node) bool) []*Node {
-	var res []*Node
-	for n := range s {
-		res = append(res, n)
-	}
-	sort.Slice(res, func(i, j int) bool { return less(res[i], res[j]) })
-	return res
-}
diff --git a/src/cmd/compile/internal/gc/testdata/arith_test.go b/src/cmd/compile/internal/gc/testdata/arith_test.go
deleted file mode 100644
index 158fedc..0000000
--- a/src/cmd/compile/internal/gc/testdata/arith_test.go
+++ /dev/null
@@ -1,1454 +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 arithmetic expressions
-
-package main
-
-import (
-	"math"
-	"runtime"
-	"testing"
-)
-
-const (
-	y = 0x0fffFFFF
-)
-
-var (
-	g8  int8
-	g16 int16
-	g32 int32
-	g64 int64
-)
-
-//go:noinline
-func lshNop1(x uint64) uint64 {
-	// two outer shifts should be removed
-	return (((x << 5) >> 2) << 2)
-}
-
-//go:noinline
-func lshNop2(x uint64) uint64 {
-	return (((x << 5) >> 2) << 3)
-}
-
-//go:noinline
-func lshNop3(x uint64) uint64 {
-	return (((x << 5) >> 2) << 6)
-}
-
-//go:noinline
-func lshNotNop(x uint64) uint64 {
-	// outer shift can't be removed
-	return (((x << 5) >> 2) << 1)
-}
-
-//go:noinline
-func rshNop1(x uint64) uint64 {
-	return (((x >> 5) << 2) >> 2)
-}
-
-//go:noinline
-func rshNop2(x uint64) uint64 {
-	return (((x >> 5) << 2) >> 3)
-}
-
-//go:noinline
-func rshNop3(x uint64) uint64 {
-	return (((x >> 5) << 2) >> 6)
-}
-
-//go:noinline
-func rshNotNop(x uint64) uint64 {
-	return (((x >> 5) << 2) >> 1)
-}
-
-func testShiftRemoval(t *testing.T) {
-	allSet := ^uint64(0)
-	if want, got := uint64(0x7ffffffffffffff), rshNop1(allSet); want != got {
-		t.Errorf("testShiftRemoval rshNop1 failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint64(0x3ffffffffffffff), rshNop2(allSet); want != got {
-		t.Errorf("testShiftRemoval rshNop2 failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint64(0x7fffffffffffff), rshNop3(allSet); want != got {
-		t.Errorf("testShiftRemoval rshNop3 failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint64(0xffffffffffffffe), rshNotNop(allSet); want != got {
-		t.Errorf("testShiftRemoval rshNotNop failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint64(0xffffffffffffffe0), lshNop1(allSet); want != got {
-		t.Errorf("testShiftRemoval lshNop1 failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint64(0xffffffffffffffc0), lshNop2(allSet); want != got {
-		t.Errorf("testShiftRemoval lshNop2 failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint64(0xfffffffffffffe00), lshNop3(allSet); want != got {
-		t.Errorf("testShiftRemoval lshNop3 failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint64(0x7ffffffffffffff0), lshNotNop(allSet); want != got {
-		t.Errorf("testShiftRemoval lshNotNop failed, wanted %d got %d", want, got)
-	}
-}
-
-//go:noinline
-func parseLE64(b []byte) uint64 {
-	// skip the first two bytes, and parse the remaining 8 as a uint64
-	return uint64(b[2]) | uint64(b[3])<<8 | uint64(b[4])<<16 | uint64(b[5])<<24 |
-		uint64(b[6])<<32 | uint64(b[7])<<40 | uint64(b[8])<<48 | uint64(b[9])<<56
-}
-
-//go:noinline
-func parseLE32(b []byte) uint32 {
-	return uint32(b[2]) | uint32(b[3])<<8 | uint32(b[4])<<16 | uint32(b[5])<<24
-}
-
-//go:noinline
-func parseLE16(b []byte) uint16 {
-	return uint16(b[2]) | uint16(b[3])<<8
-}
-
-// testLoadCombine tests for issue #14694 where load combining didn't respect the pointer offset.
-func testLoadCombine(t *testing.T) {
-	testData := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}
-	if want, got := uint64(0x0908070605040302), parseLE64(testData); want != got {
-		t.Errorf("testLoadCombine failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint32(0x05040302), parseLE32(testData); want != got {
-		t.Errorf("testLoadCombine failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint16(0x0302), parseLE16(testData); want != got {
-		t.Errorf("testLoadCombine failed, wanted %d got %d", want, got)
-	}
-}
-
-var loadSymData = [...]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
-
-func testLoadSymCombine(t *testing.T) {
-	w2 := uint16(0x0201)
-	g2 := uint16(loadSymData[0]) | uint16(loadSymData[1])<<8
-	if g2 != w2 {
-		t.Errorf("testLoadSymCombine failed, wanted %d got %d", w2, g2)
-	}
-	w4 := uint32(0x04030201)
-	g4 := uint32(loadSymData[0]) | uint32(loadSymData[1])<<8 |
-		uint32(loadSymData[2])<<16 | uint32(loadSymData[3])<<24
-	if g4 != w4 {
-		t.Errorf("testLoadSymCombine failed, wanted %d got %d", w4, g4)
-	}
-	w8 := uint64(0x0807060504030201)
-	g8 := uint64(loadSymData[0]) | uint64(loadSymData[1])<<8 |
-		uint64(loadSymData[2])<<16 | uint64(loadSymData[3])<<24 |
-		uint64(loadSymData[4])<<32 | uint64(loadSymData[5])<<40 |
-		uint64(loadSymData[6])<<48 | uint64(loadSymData[7])<<56
-	if g8 != w8 {
-		t.Errorf("testLoadSymCombine failed, wanted %d got %d", w8, g8)
-	}
-}
-
-//go:noinline
-func invalidAdd_ssa(x uint32) uint32 {
-	return x + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y
-}
-
-//go:noinline
-func invalidSub_ssa(x uint32) uint32 {
-	return x - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y
-}
-
-//go:noinline
-func invalidMul_ssa(x uint32) uint32 {
-	return x * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y
-}
-
-// testLargeConst tests a situation where larger than 32 bit consts were passed to ADDL
-// causing an invalid instruction error.
-func testLargeConst(t *testing.T) {
-	if want, got := uint32(268435440), invalidAdd_ssa(1); want != got {
-		t.Errorf("testLargeConst add failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint32(4026531858), invalidSub_ssa(1); want != got {
-		t.Errorf("testLargeConst sub failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint32(268435455), invalidMul_ssa(1); want != got {
-		t.Errorf("testLargeConst mul failed, wanted %d got %d", want, got)
-	}
-}
-
-// testArithRshConst ensures that "const >> const" right shifts correctly perform
-// sign extension on the lhs constant
-func testArithRshConst(t *testing.T) {
-	wantu := uint64(0x4000000000000000)
-	if got := arithRshuConst_ssa(); got != wantu {
-		t.Errorf("arithRshuConst failed, wanted %d got %d", wantu, got)
-	}
-
-	wants := int64(-0x4000000000000000)
-	if got := arithRshConst_ssa(); got != wants {
-		t.Errorf("arithRshConst failed, wanted %d got %d", wants, got)
-	}
-}
-
-//go:noinline
-func arithRshuConst_ssa() uint64 {
-	y := uint64(0x8000000000000001)
-	z := uint64(1)
-	return uint64(y >> z)
-}
-
-//go:noinline
-func arithRshConst_ssa() int64 {
-	y := int64(-0x8000000000000000)
-	z := uint64(1)
-	return int64(y >> z)
-}
-
-//go:noinline
-func arithConstShift_ssa(x int64) int64 {
-	return x >> 100
-}
-
-// testArithConstShift tests that right shift by large constants preserve
-// the sign of the input.
-func testArithConstShift(t *testing.T) {
-	want := int64(-1)
-	if got := arithConstShift_ssa(-1); want != got {
-		t.Errorf("arithConstShift_ssa(-1) failed, wanted %d got %d", want, got)
-	}
-	want = 0
-	if got := arithConstShift_ssa(1); want != got {
-		t.Errorf("arithConstShift_ssa(1) failed, wanted %d got %d", want, got)
-	}
-}
-
-// overflowConstShift_ssa verifes that constant folding for shift
-// doesn't wrap (i.e. x << MAX_INT << 1 doesn't get folded to x << 0).
-//go:noinline
-func overflowConstShift64_ssa(x int64) int64 {
-	return x << uint64(0xffffffffffffffff) << uint64(1)
-}
-
-//go:noinline
-func overflowConstShift32_ssa(x int64) int32 {
-	return int32(x) << uint32(0xffffffff) << uint32(1)
-}
-
-//go:noinline
-func overflowConstShift16_ssa(x int64) int16 {
-	return int16(x) << uint16(0xffff) << uint16(1)
-}
-
-//go:noinline
-func overflowConstShift8_ssa(x int64) int8 {
-	return int8(x) << uint8(0xff) << uint8(1)
-}
-
-func testOverflowConstShift(t *testing.T) {
-	want := int64(0)
-	for x := int64(-127); x < int64(127); x++ {
-		got := overflowConstShift64_ssa(x)
-		if want != got {
-			t.Errorf("overflowShift64 failed, wanted %d got %d", want, got)
-		}
-		got = int64(overflowConstShift32_ssa(x))
-		if want != got {
-			t.Errorf("overflowShift32 failed, wanted %d got %d", want, got)
-		}
-		got = int64(overflowConstShift16_ssa(x))
-		if want != got {
-			t.Errorf("overflowShift16 failed, wanted %d got %d", want, got)
-		}
-		got = int64(overflowConstShift8_ssa(x))
-		if want != got {
-			t.Errorf("overflowShift8 failed, wanted %d got %d", want, got)
-		}
-	}
-}
-
-// test64BitConstMult tests that rewrite rules don't fold 64 bit constants
-// into multiply instructions.
-func test64BitConstMult(t *testing.T) {
-	want := int64(103079215109)
-	if got := test64BitConstMult_ssa(1, 2); want != got {
-		t.Errorf("test64BitConstMult failed, wanted %d got %d", want, got)
-	}
-}
-
-//go:noinline
-func test64BitConstMult_ssa(a, b int64) int64 {
-	return 34359738369*a + b*34359738370
-}
-
-// test64BitConstAdd tests that rewrite rules don't fold 64 bit constants
-// into add instructions.
-func test64BitConstAdd(t *testing.T) {
-	want := int64(3567671782835376650)
-	if got := test64BitConstAdd_ssa(1, 2); want != got {
-		t.Errorf("test64BitConstAdd failed, wanted %d got %d", want, got)
-	}
-}
-
-//go:noinline
-func test64BitConstAdd_ssa(a, b int64) int64 {
-	return a + 575815584948629622 + b + 2991856197886747025
-}
-
-// testRegallocCVSpill tests that regalloc spills a value whose last use is the
-// current value.
-func testRegallocCVSpill(t *testing.T) {
-	want := int8(-9)
-	if got := testRegallocCVSpill_ssa(1, 2, 3, 4); want != got {
-		t.Errorf("testRegallocCVSpill failed, wanted %d got %d", want, got)
-	}
-}
-
-//go:noinline
-func testRegallocCVSpill_ssa(a, b, c, d int8) int8 {
-	return a + -32 + b + 63*c*-87*d
-}
-
-func testBitwiseLogic(t *testing.T) {
-	a, b := uint32(57623283), uint32(1314713839)
-	if want, got := uint32(38551779), testBitwiseAnd_ssa(a, b); want != got {
-		t.Errorf("testBitwiseAnd failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint32(1333785343), testBitwiseOr_ssa(a, b); want != got {
-		t.Errorf("testBitwiseOr failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint32(1295233564), testBitwiseXor_ssa(a, b); want != got {
-		t.Errorf("testBitwiseXor failed, wanted %d got %d", want, got)
-	}
-	if want, got := int32(832), testBitwiseLsh_ssa(13, 4, 2); want != got {
-		t.Errorf("testBitwiseLsh failed, wanted %d got %d", want, got)
-	}
-	if want, got := int32(0), testBitwiseLsh_ssa(13, 25, 15); want != got {
-		t.Errorf("testBitwiseLsh failed, wanted %d got %d", want, got)
-	}
-	if want, got := int32(0), testBitwiseLsh_ssa(-13, 25, 15); want != got {
-		t.Errorf("testBitwiseLsh failed, wanted %d got %d", want, got)
-	}
-	if want, got := int32(-13), testBitwiseRsh_ssa(-832, 4, 2); want != got {
-		t.Errorf("testBitwiseRsh failed, wanted %d got %d", want, got)
-	}
-	if want, got := int32(0), testBitwiseRsh_ssa(13, 25, 15); want != got {
-		t.Errorf("testBitwiseRsh failed, wanted %d got %d", want, got)
-	}
-	if want, got := int32(-1), testBitwiseRsh_ssa(-13, 25, 15); want != got {
-		t.Errorf("testBitwiseRsh failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint32(0x3ffffff), testBitwiseRshU_ssa(0xffffffff, 4, 2); want != got {
-		t.Errorf("testBitwiseRshU failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint32(0), testBitwiseRshU_ssa(13, 25, 15); want != got {
-		t.Errorf("testBitwiseRshU failed, wanted %d got %d", want, got)
-	}
-	if want, got := uint32(0), testBitwiseRshU_ssa(0x8aaaaaaa, 25, 15); want != got {
-		t.Errorf("testBitwiseRshU failed, wanted %d got %d", want, got)
-	}
-}
-
-//go:noinline
-func testBitwiseAnd_ssa(a, b uint32) uint32 {
-	return a & b
-}
-
-//go:noinline
-func testBitwiseOr_ssa(a, b uint32) uint32 {
-	return a | b
-}
-
-//go:noinline
-func testBitwiseXor_ssa(a, b uint32) uint32 {
-	return a ^ b
-}
-
-//go:noinline
-func testBitwiseLsh_ssa(a int32, b, c uint32) int32 {
-	return a << b << c
-}
-
-//go:noinline
-func testBitwiseRsh_ssa(a int32, b, c uint32) int32 {
-	return a >> b >> c
-}
-
-//go:noinline
-func testBitwiseRshU_ssa(a uint32, b, c uint32) uint32 {
-	return a >> b >> c
-}
-
-//go:noinline
-func testShiftCX_ssa() int {
-	v1 := uint8(3)
-	v4 := (v1 * v1) ^ v1 | v1 - v1 - v1&v1 ^ uint8(3+2) + v1*1>>0 - v1 | 1 | v1<<(2*3|0-0*0^1)
-	v5 := v4>>(3-0-uint(3)) | v1 | v1 + v1 ^ v4<<(0+1|3&1)<<(uint64(1)<<0*2*0<<0) ^ v1
-	v6 := v5 ^ (v1+v1)*v1 | v1 | v1*v1>>(v1&v1)>>(uint(1)<<0*uint(3)>>1)*v1<<2*v1<<v1 - v1>>2 | (v4 - v1) ^ v1 + v1 ^ v1>>1 | v1 + v1 - v1 ^ v1
-	v7 := v6 & v5 << 0
-	v1++
-	v11 := 2&1 ^ 0 + 3 | int(0^0)<<1>>(1*0*3) ^ 0*0 ^ 3&0*3&3 ^ 3*3 ^ 1 ^ int(2)<<(2*3) + 2 | 2 | 2 ^ 2 + 1 | 3 | 0 ^ int(1)>>1 ^ 2 // int
-	v7--
-	return int(uint64(2*1)<<(3-2)<<uint(3>>v7)-2)&v11 | v11 - int(2)<<0>>(2-1)*(v11*0&v11<<1<<(uint8(2)+v4))
-}
-
-func testShiftCX(t *testing.T) {
-	want := 141
-	if got := testShiftCX_ssa(); want != got {
-		t.Errorf("testShiftCX failed, wanted %d got %d", want, got)
-	}
-}
-
-// testSubqToNegq ensures that the SUBQ -> NEGQ translation works correctly.
-func testSubqToNegq(t *testing.T) {
-	want := int64(-318294940372190156)
-	if got := testSubqToNegq_ssa(1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2); want != got {
-		t.Errorf("testSubqToNegq failed, wanted %d got %d", want, got)
-	}
-}
-
-//go:noinline
-func testSubqToNegq_ssa(a, b, c, d, e, f, g, h, i, j, k int64) int64 {
-	return a + 8207351403619448057 - b - 1779494519303207690 + c*8810076340510052032*d - 4465874067674546219 - e*4361839741470334295 - f + 8688847565426072650*g*8065564729145417479
-}
-
-func testOcom(t *testing.T) {
-	want1, want2 := int32(0x55555555), int32(-0x55555556)
-	if got1, got2 := testOcom_ssa(0x55555555, 0x55555555); want1 != got1 || want2 != got2 {
-		t.Errorf("testOcom failed, wanted %d and %d got %d and %d", want1, want2, got1, got2)
-	}
-}
-
-//go:noinline
-func testOcom_ssa(a, b int32) (int32, int32) {
-	return ^^^^a, ^^^^^b
-}
-
-func lrot1_ssa(w uint8, x uint16, y uint32, z uint64) (a uint8, b uint16, c uint32, d uint64) {
-	a = (w << 5) | (w >> 3)
-	b = (x << 13) | (x >> 3)
-	c = (y << 29) | (y >> 3)
-	d = (z << 61) | (z >> 3)
-	return
-}
-
-//go:noinline
-func lrot2_ssa(w, n uint32) uint32 {
-	// Want to be sure that a "rotate by 32" which
-	// is really 0 | (w >> 0) == w
-	// is correctly compiled.
-	return (w << n) | (w >> (32 - n))
-}
-
-//go:noinline
-func lrot3_ssa(w uint32) uint32 {
-	// Want to be sure that a "rotate by 32" which
-	// is really 0 | (w >> 0) == w
-	// is correctly compiled.
-	return (w << 32) | (w >> (32 - 32))
-}
-
-func testLrot(t *testing.T) {
-	wantA, wantB, wantC, wantD := uint8(0xe1), uint16(0xe001),
-		uint32(0xe0000001), uint64(0xe000000000000001)
-	a, b, c, d := lrot1_ssa(0xf, 0xf, 0xf, 0xf)
-	if a != wantA || b != wantB || c != wantC || d != wantD {
-		t.Errorf("lrot1_ssa(0xf, 0xf, 0xf, 0xf)=%d %d %d %d, got %d %d %d %d", wantA, wantB, wantC, wantD, a, b, c, d)
-	}
-	x := lrot2_ssa(0xb0000001, 32)
-	wantX := uint32(0xb0000001)
-	if x != wantX {
-		t.Errorf("lrot2_ssa(0xb0000001, 32)=%d, got %d", wantX, x)
-	}
-	x = lrot3_ssa(0xb0000001)
-	if x != wantX {
-		t.Errorf("lrot3_ssa(0xb0000001)=%d, got %d", wantX, x)
-	}
-
-}
-
-//go:noinline
-func sub1_ssa() uint64 {
-	v1 := uint64(3) // uint64
-	return v1*v1 - (v1&v1)&v1
-}
-
-//go:noinline
-func sub2_ssa() uint8 {
-	v1 := uint8(0)
-	v3 := v1 + v1 + v1 ^ v1 | 3 + v1 ^ v1 | v1 ^ v1
-	v1-- // dev.ssa doesn't see this one
-	return v1 ^ v1*v1 - v3
-}
-
-func testSubConst(t *testing.T) {
-	x1 := sub1_ssa()
-	want1 := uint64(6)
-	if x1 != want1 {
-		t.Errorf("sub1_ssa()=%d, got %d", want1, x1)
-	}
-	x2 := sub2_ssa()
-	want2 := uint8(251)
-	if x2 != want2 {
-		t.Errorf("sub2_ssa()=%d, got %d", want2, x2)
-	}
-}
-
-//go:noinline
-func orPhi_ssa(a bool, x int) int {
-	v := 0
-	if a {
-		v = -1
-	} else {
-		v = -1
-	}
-	return x | v
-}
-
-func testOrPhi(t *testing.T) {
-	if want, got := -1, orPhi_ssa(true, 4); got != want {
-		t.Errorf("orPhi_ssa(true, 4)=%d, want %d", got, want)
-	}
-	if want, got := -1, orPhi_ssa(false, 0); got != want {
-		t.Errorf("orPhi_ssa(false, 0)=%d, want %d", got, want)
-	}
-}
-
-//go:noinline
-func addshiftLL_ssa(a, b uint32) uint32 {
-	return a + b<<3
-}
-
-//go:noinline
-func subshiftLL_ssa(a, b uint32) uint32 {
-	return a - b<<3
-}
-
-//go:noinline
-func rsbshiftLL_ssa(a, b uint32) uint32 {
-	return a<<3 - b
-}
-
-//go:noinline
-func andshiftLL_ssa(a, b uint32) uint32 {
-	return a & (b << 3)
-}
-
-//go:noinline
-func orshiftLL_ssa(a, b uint32) uint32 {
-	return a | b<<3
-}
-
-//go:noinline
-func xorshiftLL_ssa(a, b uint32) uint32 {
-	return a ^ b<<3
-}
-
-//go:noinline
-func bicshiftLL_ssa(a, b uint32) uint32 {
-	return a &^ (b << 3)
-}
-
-//go:noinline
-func notshiftLL_ssa(a uint32) uint32 {
-	return ^(a << 3)
-}
-
-//go:noinline
-func addshiftRL_ssa(a, b uint32) uint32 {
-	return a + b>>3
-}
-
-//go:noinline
-func subshiftRL_ssa(a, b uint32) uint32 {
-	return a - b>>3
-}
-
-//go:noinline
-func rsbshiftRL_ssa(a, b uint32) uint32 {
-	return a>>3 - b
-}
-
-//go:noinline
-func andshiftRL_ssa(a, b uint32) uint32 {
-	return a & (b >> 3)
-}
-
-//go:noinline
-func orshiftRL_ssa(a, b uint32) uint32 {
-	return a | b>>3
-}
-
-//go:noinline
-func xorshiftRL_ssa(a, b uint32) uint32 {
-	return a ^ b>>3
-}
-
-//go:noinline
-func bicshiftRL_ssa(a, b uint32) uint32 {
-	return a &^ (b >> 3)
-}
-
-//go:noinline
-func notshiftRL_ssa(a uint32) uint32 {
-	return ^(a >> 3)
-}
-
-//go:noinline
-func addshiftRA_ssa(a, b int32) int32 {
-	return a + b>>3
-}
-
-//go:noinline
-func subshiftRA_ssa(a, b int32) int32 {
-	return a - b>>3
-}
-
-//go:noinline
-func rsbshiftRA_ssa(a, b int32) int32 {
-	return a>>3 - b
-}
-
-//go:noinline
-func andshiftRA_ssa(a, b int32) int32 {
-	return a & (b >> 3)
-}
-
-//go:noinline
-func orshiftRA_ssa(a, b int32) int32 {
-	return a | b>>3
-}
-
-//go:noinline
-func xorshiftRA_ssa(a, b int32) int32 {
-	return a ^ b>>3
-}
-
-//go:noinline
-func bicshiftRA_ssa(a, b int32) int32 {
-	return a &^ (b >> 3)
-}
-
-//go:noinline
-func notshiftRA_ssa(a int32) int32 {
-	return ^(a >> 3)
-}
-
-//go:noinline
-func addshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a + b<<s
-}
-
-//go:noinline
-func subshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a - b<<s
-}
-
-//go:noinline
-func rsbshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a<<s - b
-}
-
-//go:noinline
-func andshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a & (b << s)
-}
-
-//go:noinline
-func orshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a | b<<s
-}
-
-//go:noinline
-func xorshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a ^ b<<s
-}
-
-//go:noinline
-func bicshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a &^ (b << s)
-}
-
-//go:noinline
-func notshiftLLreg_ssa(a uint32, s uint8) uint32 {
-	return ^(a << s)
-}
-
-//go:noinline
-func addshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a + b>>s
-}
-
-//go:noinline
-func subshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a - b>>s
-}
-
-//go:noinline
-func rsbshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a>>s - b
-}
-
-//go:noinline
-func andshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a & (b >> s)
-}
-
-//go:noinline
-func orshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a | b>>s
-}
-
-//go:noinline
-func xorshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a ^ b>>s
-}
-
-//go:noinline
-func bicshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
-	return a &^ (b >> s)
-}
-
-//go:noinline
-func notshiftRLreg_ssa(a uint32, s uint8) uint32 {
-	return ^(a >> s)
-}
-
-//go:noinline
-func addshiftRAreg_ssa(a, b int32, s uint8) int32 {
-	return a + b>>s
-}
-
-//go:noinline
-func subshiftRAreg_ssa(a, b int32, s uint8) int32 {
-	return a - b>>s
-}
-
-//go:noinline
-func rsbshiftRAreg_ssa(a, b int32, s uint8) int32 {
-	return a>>s - b
-}
-
-//go:noinline
-func andshiftRAreg_ssa(a, b int32, s uint8) int32 {
-	return a & (b >> s)
-}
-
-//go:noinline
-func orshiftRAreg_ssa(a, b int32, s uint8) int32 {
-	return a | b>>s
-}
-
-//go:noinline
-func xorshiftRAreg_ssa(a, b int32, s uint8) int32 {
-	return a ^ b>>s
-}
-
-//go:noinline
-func bicshiftRAreg_ssa(a, b int32, s uint8) int32 {
-	return a &^ (b >> s)
-}
-
-//go:noinline
-func notshiftRAreg_ssa(a int32, s uint8) int32 {
-	return ^(a >> s)
-}
-
-// test ARM shifted ops
-func testShiftedOps(t *testing.T) {
-	a, b := uint32(10), uint32(42)
-	if want, got := a+b<<3, addshiftLL_ssa(a, b); got != want {
-		t.Errorf("addshiftLL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := a-b<<3, subshiftLL_ssa(a, b); got != want {
-		t.Errorf("subshiftLL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := a<<3-b, rsbshiftLL_ssa(a, b); got != want {
-		t.Errorf("rsbshiftLL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := a&(b<<3), andshiftLL_ssa(a, b); got != want {
-		t.Errorf("andshiftLL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := a|b<<3, orshiftLL_ssa(a, b); got != want {
-		t.Errorf("orshiftLL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := a^b<<3, xorshiftLL_ssa(a, b); got != want {
-		t.Errorf("xorshiftLL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := a&^(b<<3), bicshiftLL_ssa(a, b); got != want {
-		t.Errorf("bicshiftLL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := ^(a << 3), notshiftLL_ssa(a); got != want {
-		t.Errorf("notshiftLL_ssa(10) = %d want %d", got, want)
-	}
-	if want, got := a+b>>3, addshiftRL_ssa(a, b); got != want {
-		t.Errorf("addshiftRL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := a-b>>3, subshiftRL_ssa(a, b); got != want {
-		t.Errorf("subshiftRL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := a>>3-b, rsbshiftRL_ssa(a, b); got != want {
-		t.Errorf("rsbshiftRL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := a&(b>>3), andshiftRL_ssa(a, b); got != want {
-		t.Errorf("andshiftRL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := a|b>>3, orshiftRL_ssa(a, b); got != want {
-		t.Errorf("orshiftRL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := a^b>>3, xorshiftRL_ssa(a, b); got != want {
-		t.Errorf("xorshiftRL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := a&^(b>>3), bicshiftRL_ssa(a, b); got != want {
-		t.Errorf("bicshiftRL_ssa(10, 42) = %d want %d", got, want)
-	}
-	if want, got := ^(a >> 3), notshiftRL_ssa(a); got != want {
-		t.Errorf("notshiftRL_ssa(10) = %d want %d", got, want)
-	}
-	c, d := int32(10), int32(-42)
-	if want, got := c+d>>3, addshiftRA_ssa(c, d); got != want {
-		t.Errorf("addshiftRA_ssa(10, -42) = %d want %d", got, want)
-	}
-	if want, got := c-d>>3, subshiftRA_ssa(c, d); got != want {
-		t.Errorf("subshiftRA_ssa(10, -42) = %d want %d", got, want)
-	}
-	if want, got := c>>3-d, rsbshiftRA_ssa(c, d); got != want {
-		t.Errorf("rsbshiftRA_ssa(10, -42) = %d want %d", got, want)
-	}
-	if want, got := c&(d>>3), andshiftRA_ssa(c, d); got != want {
-		t.Errorf("andshiftRA_ssa(10, -42) = %d want %d", got, want)
-	}
-	if want, got := c|d>>3, orshiftRA_ssa(c, d); got != want {
-		t.Errorf("orshiftRA_ssa(10, -42) = %d want %d", got, want)
-	}
-	if want, got := c^d>>3, xorshiftRA_ssa(c, d); got != want {
-		t.Errorf("xorshiftRA_ssa(10, -42) = %d want %d", got, want)
-	}
-	if want, got := c&^(d>>3), bicshiftRA_ssa(c, d); got != want {
-		t.Errorf("bicshiftRA_ssa(10, -42) = %d want %d", got, want)
-	}
-	if want, got := ^(d >> 3), notshiftRA_ssa(d); got != want {
-		t.Errorf("notshiftRA_ssa(-42) = %d want %d", got, want)
-	}
-	s := uint8(3)
-	if want, got := a+b<<s, addshiftLLreg_ssa(a, b, s); got != want {
-		t.Errorf("addshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := a-b<<s, subshiftLLreg_ssa(a, b, s); got != want {
-		t.Errorf("subshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := a<<s-b, rsbshiftLLreg_ssa(a, b, s); got != want {
-		t.Errorf("rsbshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := a&(b<<s), andshiftLLreg_ssa(a, b, s); got != want {
-		t.Errorf("andshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := a|b<<s, orshiftLLreg_ssa(a, b, s); got != want {
-		t.Errorf("orshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := a^b<<s, xorshiftLLreg_ssa(a, b, s); got != want {
-		t.Errorf("xorshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := a&^(b<<s), bicshiftLLreg_ssa(a, b, s); got != want {
-		t.Errorf("bicshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := ^(a << s), notshiftLLreg_ssa(a, s); got != want {
-		t.Errorf("notshiftLLreg_ssa(10) = %d want %d", got, want)
-	}
-	if want, got := a+b>>s, addshiftRLreg_ssa(a, b, s); got != want {
-		t.Errorf("addshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := a-b>>s, subshiftRLreg_ssa(a, b, s); got != want {
-		t.Errorf("subshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := a>>s-b, rsbshiftRLreg_ssa(a, b, s); got != want {
-		t.Errorf("rsbshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := a&(b>>s), andshiftRLreg_ssa(a, b, s); got != want {
-		t.Errorf("andshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := a|b>>s, orshiftRLreg_ssa(a, b, s); got != want {
-		t.Errorf("orshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := a^b>>s, xorshiftRLreg_ssa(a, b, s); got != want {
-		t.Errorf("xorshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := a&^(b>>s), bicshiftRLreg_ssa(a, b, s); got != want {
-		t.Errorf("bicshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
-	}
-	if want, got := ^(a >> s), notshiftRLreg_ssa(a, s); got != want {
-		t.Errorf("notshiftRLreg_ssa(10) = %d want %d", got, want)
-	}
-	if want, got := c+d>>s, addshiftRAreg_ssa(c, d, s); got != want {
-		t.Errorf("addshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
-	}
-	if want, got := c-d>>s, subshiftRAreg_ssa(c, d, s); got != want {
-		t.Errorf("subshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
-	}
-	if want, got := c>>s-d, rsbshiftRAreg_ssa(c, d, s); got != want {
-		t.Errorf("rsbshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
-	}
-	if want, got := c&(d>>s), andshiftRAreg_ssa(c, d, s); got != want {
-		t.Errorf("andshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
-	}
-	if want, got := c|d>>s, orshiftRAreg_ssa(c, d, s); got != want {
-		t.Errorf("orshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
-	}
-	if want, got := c^d>>s, xorshiftRAreg_ssa(c, d, s); got != want {
-		t.Errorf("xorshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
-	}
-	if want, got := c&^(d>>s), bicshiftRAreg_ssa(c, d, s); got != want {
-		t.Errorf("bicshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
-	}
-	if want, got := ^(d >> s), notshiftRAreg_ssa(d, s); got != want {
-		t.Errorf("notshiftRAreg_ssa(-42, 3) = %d want %d", got, want)
-	}
-}
-
-// TestArithmetic tests that both backends have the same result for arithmetic expressions.
-func TestArithmetic(t *testing.T) {
-	test64BitConstMult(t)
-	test64BitConstAdd(t)
-	testRegallocCVSpill(t)
-	testSubqToNegq(t)
-	testBitwiseLogic(t)
-	testOcom(t)
-	testLrot(t)
-	testShiftCX(t)
-	testSubConst(t)
-	testOverflowConstShift(t)
-	testArithConstShift(t)
-	testArithRshConst(t)
-	testLargeConst(t)
-	testLoadCombine(t)
-	testLoadSymCombine(t)
-	testShiftRemoval(t)
-	testShiftedOps(t)
-	testDivFixUp(t)
-	testDivisibleSignedPow2(t)
-	testDivisibility(t)
-}
-
-// testDivFixUp ensures that signed division fix-ups are being generated.
-func testDivFixUp(t *testing.T) {
-	defer func() {
-		if r := recover(); r != nil {
-			t.Error("testDivFixUp failed")
-			if e, ok := r.(runtime.Error); ok {
-				t.Logf("%v\n", e.Error())
-			}
-		}
-	}()
-	var w int8 = -128
-	var x int16 = -32768
-	var y int32 = -2147483648
-	var z int64 = -9223372036854775808
-
-	for i := -5; i < 0; i++ {
-		g8 = w / int8(i)
-		g16 = x / int16(i)
-		g32 = y / int32(i)
-		g64 = z / int64(i)
-		g8 = w % int8(i)
-		g16 = x % int16(i)
-		g32 = y % int32(i)
-		g64 = z % int64(i)
-	}
-}
-
-//go:noinline
-func divisible_int8_2to1(x int8) bool {
-	return x%(1<<1) == 0
-}
-
-//go:noinline
-func divisible_int8_2to2(x int8) bool {
-	return x%(1<<2) == 0
-}
-
-//go:noinline
-func divisible_int8_2to3(x int8) bool {
-	return x%(1<<3) == 0
-}
-
-//go:noinline
-func divisible_int8_2to4(x int8) bool {
-	return x%(1<<4) == 0
-}
-
-//go:noinline
-func divisible_int8_2to5(x int8) bool {
-	return x%(1<<5) == 0
-}
-
-//go:noinline
-func divisible_int8_2to6(x int8) bool {
-	return x%(1<<6) == 0
-}
-
-//go:noinline
-func divisible_int16_2to1(x int16) bool {
-	return x%(1<<1) == 0
-}
-
-//go:noinline
-func divisible_int16_2to2(x int16) bool {
-	return x%(1<<2) == 0
-}
-
-//go:noinline
-func divisible_int16_2to3(x int16) bool {
-	return x%(1<<3) == 0
-}
-
-//go:noinline
-func divisible_int16_2to4(x int16) bool {
-	return x%(1<<4) == 0
-}
-
-//go:noinline
-func divisible_int16_2to5(x int16) bool {
-	return x%(1<<5) == 0
-}
-
-//go:noinline
-func divisible_int16_2to6(x int16) bool {
-	return x%(1<<6) == 0
-}
-
-//go:noinline
-func divisible_int16_2to7(x int16) bool {
-	return x%(1<<7) == 0
-}
-
-//go:noinline
-func divisible_int16_2to8(x int16) bool {
-	return x%(1<<8) == 0
-}
-
-//go:noinline
-func divisible_int16_2to9(x int16) bool {
-	return x%(1<<9) == 0
-}
-
-//go:noinline
-func divisible_int16_2to10(x int16) bool {
-	return x%(1<<10) == 0
-}
-
-//go:noinline
-func divisible_int16_2to11(x int16) bool {
-	return x%(1<<11) == 0
-}
-
-//go:noinline
-func divisible_int16_2to12(x int16) bool {
-	return x%(1<<12) == 0
-}
-
-//go:noinline
-func divisible_int16_2to13(x int16) bool {
-	return x%(1<<13) == 0
-}
-
-//go:noinline
-func divisible_int16_2to14(x int16) bool {
-	return x%(1<<14) == 0
-}
-
-//go:noinline
-func divisible_int32_2to4(x int32) bool {
-	return x%(1<<4) == 0
-}
-
-//go:noinline
-func divisible_int32_2to15(x int32) bool {
-	return x%(1<<15) == 0
-}
-
-//go:noinline
-func divisible_int32_2to26(x int32) bool {
-	return x%(1<<26) == 0
-}
-
-//go:noinline
-func divisible_int64_2to4(x int64) bool {
-	return x%(1<<4) == 0
-}
-
-//go:noinline
-func divisible_int64_2to15(x int64) bool {
-	return x%(1<<15) == 0
-}
-
-//go:noinline
-func divisible_int64_2to26(x int64) bool {
-	return x%(1<<26) == 0
-}
-
-//go:noinline
-func divisible_int64_2to34(x int64) bool {
-	return x%(1<<34) == 0
-}
-
-//go:noinline
-func divisible_int64_2to48(x int64) bool {
-	return x%(1<<48) == 0
-}
-
-//go:noinline
-func divisible_int64_2to57(x int64) bool {
-	return x%(1<<57) == 0
-}
-
-// testDivisibleSignedPow2 confirms that x%(1<<k)==0 is rewritten correctly
-func testDivisibleSignedPow2(t *testing.T) {
-	var i int64
-	var pow2 = []int64{
-		1,
-		1 << 1,
-		1 << 2,
-		1 << 3,
-		1 << 4,
-		1 << 5,
-		1 << 6,
-		1 << 7,
-		1 << 8,
-		1 << 9,
-		1 << 10,
-		1 << 11,
-		1 << 12,
-		1 << 13,
-		1 << 14,
-	}
-	// exhaustive test for int8
-	for i = math.MinInt8; i <= math.MaxInt8; i++ {
-		if want, got := int8(i)%int8(pow2[1]) == 0, divisible_int8_2to1(int8(i)); got != want {
-			t.Errorf("divisible_int8_2to1(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int8(i)%int8(pow2[2]) == 0, divisible_int8_2to2(int8(i)); got != want {
-			t.Errorf("divisible_int8_2to2(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int8(i)%int8(pow2[3]) == 0, divisible_int8_2to3(int8(i)); got != want {
-			t.Errorf("divisible_int8_2to3(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int8(i)%int8(pow2[4]) == 0, divisible_int8_2to4(int8(i)); got != want {
-			t.Errorf("divisible_int8_2to4(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int8(i)%int8(pow2[5]) == 0, divisible_int8_2to5(int8(i)); got != want {
-			t.Errorf("divisible_int8_2to5(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int8(i)%int8(pow2[6]) == 0, divisible_int8_2to6(int8(i)); got != want {
-			t.Errorf("divisible_int8_2to6(%d) = %v want %v", i, got, want)
-		}
-	}
-	// exhaustive test for int16
-	for i = math.MinInt16; i <= math.MaxInt16; i++ {
-		if want, got := int16(i)%int16(pow2[1]) == 0, divisible_int16_2to1(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to1(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[2]) == 0, divisible_int16_2to2(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to2(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[3]) == 0, divisible_int16_2to3(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to3(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[4]) == 0, divisible_int16_2to4(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to4(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[5]) == 0, divisible_int16_2to5(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to5(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[6]) == 0, divisible_int16_2to6(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to6(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[7]) == 0, divisible_int16_2to7(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to7(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[8]) == 0, divisible_int16_2to8(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to8(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[9]) == 0, divisible_int16_2to9(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to9(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[10]) == 0, divisible_int16_2to10(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to10(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[11]) == 0, divisible_int16_2to11(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to11(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[12]) == 0, divisible_int16_2to12(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to12(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[13]) == 0, divisible_int16_2to13(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to13(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(pow2[14]) == 0, divisible_int16_2to14(int16(i)); got != want {
-			t.Errorf("divisible_int16_2to14(%d) = %v want %v", i, got, want)
-		}
-	}
-	// spot check for int32 and int64
-	var (
-		two4  int64 = 1 << 4
-		two15 int64 = 1 << 15
-		two26 int64 = 1 << 26
-		two34 int64 = 1 << 34
-		two48 int64 = 1 << 48
-		two57 int64 = 1 << 57
-	)
-	var xs = []int64{two4, two4 + 3, -3 * two4, -3*two4 + 1,
-		two15, two15 + 3, -3 * two15, -3*two15 + 1,
-		two26, two26 + 37, -5 * two26, -5*two26 + 2,
-		two34, two34 + 356, -7 * two34, -7*two34 + 13,
-		two48, two48 + 3000, -12 * two48, -12*two48 + 1111,
-		two57, two57 + 397654, -15 * two57, -15*two57 + 11234,
-	}
-	for _, x := range xs {
-		if int64(int32(x)) == x {
-			if want, got := int32(x)%int32(two4) == 0, divisible_int32_2to4(int32(x)); got != want {
-				t.Errorf("divisible_int32_2to4(%d) = %v want %v", x, got, want)
-			}
-
-			if want, got := int32(x)%int32(two15) == 0, divisible_int32_2to15(int32(x)); got != want {
-				t.Errorf("divisible_int32_2to15(%d) = %v want %v", x, got, want)
-			}
-
-			if want, got := int32(x)%int32(two26) == 0, divisible_int32_2to26(int32(x)); got != want {
-				t.Errorf("divisible_int32_2to26(%d) = %v want %v", x, got, want)
-			}
-		}
-		// spot check for int64
-		if want, got := x%two4 == 0, divisible_int64_2to4(x); got != want {
-			t.Errorf("divisible_int64_2to4(%d) = %v want %v", x, got, want)
-		}
-
-		if want, got := x%two15 == 0, divisible_int64_2to15(x); got != want {
-			t.Errorf("divisible_int64_2to15(%d) = %v want %v", x, got, want)
-		}
-
-		if want, got := x%two26 == 0, divisible_int64_2to26(x); got != want {
-			t.Errorf("divisible_int64_2to26(%d) = %v want %v", x, got, want)
-		}
-
-		if want, got := x%two34 == 0, divisible_int64_2to34(x); got != want {
-			t.Errorf("divisible_int64_2to34(%d) = %v want %v", x, got, want)
-		}
-
-		if want, got := x%two48 == 0, divisible_int64_2to48(x); got != want {
-			t.Errorf("divisible_int64_2to48(%d) = %v want %v", x, got, want)
-		}
-
-		if want, got := x%two57 == 0, divisible_int64_2to57(x); got != want {
-			t.Errorf("divisible_int64_2to57(%d) = %v want %v", x, got, want)
-		}
-	}
-}
-
-func div6_uint8(n uint8) bool {
-	return n%6 == 0
-}
-
-//go:noinline
-func div6_uint16(n uint16) bool {
-	return n%6 == 0
-}
-
-//go:noinline
-func div6_uint32(n uint32) bool {
-	return n%6 == 0
-}
-
-//go:noinline
-func div6_uint64(n uint64) bool {
-	return n%6 == 0
-}
-
-//go:noinline
-func div19_uint8(n uint8) bool {
-	return n%19 == 0
-}
-
-//go:noinline
-func div19_uint16(n uint16) bool {
-	return n%19 == 0
-}
-
-//go:noinline
-func div19_uint32(n uint32) bool {
-	return n%19 == 0
-}
-
-//go:noinline
-func div19_uint64(n uint64) bool {
-	return n%19 == 0
-}
-
-//go:noinline
-func div6_int8(n int8) bool {
-	return n%6 == 0
-}
-
-//go:noinline
-func div6_int16(n int16) bool {
-	return n%6 == 0
-}
-
-//go:noinline
-func div6_int32(n int32) bool {
-	return n%6 == 0
-}
-
-//go:noinline
-func div6_int64(n int64) bool {
-	return n%6 == 0
-}
-
-//go:noinline
-func div19_int8(n int8) bool {
-	return n%19 == 0
-}
-
-//go:noinline
-func div19_int16(n int16) bool {
-	return n%19 == 0
-}
-
-//go:noinline
-func div19_int32(n int32) bool {
-	return n%19 == 0
-}
-
-//go:noinline
-func div19_int64(n int64) bool {
-	return n%19 == 0
-}
-
-// testDivisibility confirms that rewrite rules x%c ==0 for c constant are correct.
-func testDivisibility(t *testing.T) {
-	// unsigned tests
-	// test an even and an odd divisor
-	var sixU, nineteenU uint64 = 6, 19
-	// test all inputs for uint8, uint16
-	for i := uint64(0); i <= math.MaxUint16; i++ {
-		if i <= math.MaxUint8 {
-			if want, got := uint8(i)%uint8(sixU) == 0, div6_uint8(uint8(i)); got != want {
-				t.Errorf("div6_uint8(%d) = %v want %v", i, got, want)
-			}
-			if want, got := uint8(i)%uint8(nineteenU) == 0, div19_uint8(uint8(i)); got != want {
-				t.Errorf("div6_uint19(%d) = %v want %v", i, got, want)
-			}
-		}
-		if want, got := uint16(i)%uint16(sixU) == 0, div6_uint16(uint16(i)); got != want {
-			t.Errorf("div6_uint16(%d) = %v want %v", i, got, want)
-		}
-		if want, got := uint16(i)%uint16(nineteenU) == 0, div19_uint16(uint16(i)); got != want {
-			t.Errorf("div19_uint16(%d) = %v want %v", i, got, want)
-		}
-	}
-	var maxU32, maxU64 uint64 = math.MaxUint32, math.MaxUint64
-	// spot check inputs for uint32 and uint64
-	xu := []uint64{
-		0, 1, 2, 3, 4, 5,
-		sixU, 2 * sixU, 3 * sixU, 5 * sixU, 12345 * sixU,
-		sixU + 1, 2*sixU - 5, 3*sixU + 3, 5*sixU + 4, 12345*sixU - 2,
-		nineteenU, 2 * nineteenU, 3 * nineteenU, 5 * nineteenU, 12345 * nineteenU,
-		nineteenU + 1, 2*nineteenU - 5, 3*nineteenU + 3, 5*nineteenU + 4, 12345*nineteenU - 2,
-		maxU32, maxU32 - 1, maxU32 - 2, maxU32 - 3, maxU32 - 4,
-		maxU32 - 5, maxU32 - 6, maxU32 - 7, maxU32 - 8,
-		maxU32 - 9, maxU32 - 10, maxU32 - 11, maxU32 - 12,
-		maxU32 - 13, maxU32 - 14, maxU32 - 15, maxU32 - 16,
-		maxU32 - 17, maxU32 - 18, maxU32 - 19, maxU32 - 20,
-		maxU64, maxU64 - 1, maxU64 - 2, maxU64 - 3, maxU64 - 4,
-		maxU64 - 5, maxU64 - 6, maxU64 - 7, maxU64 - 8,
-		maxU64 - 9, maxU64 - 10, maxU64 - 11, maxU64 - 12,
-		maxU64 - 13, maxU64 - 14, maxU64 - 15, maxU64 - 16,
-		maxU64 - 17, maxU64 - 18, maxU64 - 19, maxU64 - 20,
-	}
-	for _, x := range xu {
-		if x <= maxU32 {
-			if want, got := uint32(x)%uint32(sixU) == 0, div6_uint32(uint32(x)); got != want {
-				t.Errorf("div6_uint32(%d) = %v want %v", x, got, want)
-			}
-			if want, got := uint32(x)%uint32(nineteenU) == 0, div19_uint32(uint32(x)); got != want {
-				t.Errorf("div19_uint32(%d) = %v want %v", x, got, want)
-			}
-		}
-		if want, got := x%sixU == 0, div6_uint64(x); got != want {
-			t.Errorf("div6_uint64(%d) = %v want %v", x, got, want)
-		}
-		if want, got := x%nineteenU == 0, div19_uint64(x); got != want {
-			t.Errorf("div19_uint64(%d) = %v want %v", x, got, want)
-		}
-	}
-
-	// signed tests
-	// test an even and an odd divisor
-	var sixS, nineteenS int64 = 6, 19
-	// test all inputs for int8, int16
-	for i := int64(math.MinInt16); i <= math.MaxInt16; i++ {
-		if math.MinInt8 <= i && i <= math.MaxInt8 {
-			if want, got := int8(i)%int8(sixS) == 0, div6_int8(int8(i)); got != want {
-				t.Errorf("div6_int8(%d) = %v want %v", i, got, want)
-			}
-			if want, got := int8(i)%int8(nineteenS) == 0, div19_int8(int8(i)); got != want {
-				t.Errorf("div6_int19(%d) = %v want %v", i, got, want)
-			}
-		}
-		if want, got := int16(i)%int16(sixS) == 0, div6_int16(int16(i)); got != want {
-			t.Errorf("div6_int16(%d) = %v want %v", i, got, want)
-		}
-		if want, got := int16(i)%int16(nineteenS) == 0, div19_int16(int16(i)); got != want {
-			t.Errorf("div19_int16(%d) = %v want %v", i, got, want)
-		}
-	}
-	var minI32, maxI32, minI64, maxI64 int64 = math.MinInt32, math.MaxInt32, math.MinInt64, math.MaxInt64
-	// spot check inputs for int32 and int64
-	xs := []int64{
-		0, 1, 2, 3, 4, 5,
-		-1, -2, -3, -4, -5,
-		sixS, 2 * sixS, 3 * sixS, 5 * sixS, 12345 * sixS,
-		sixS + 1, 2*sixS - 5, 3*sixS + 3, 5*sixS + 4, 12345*sixS - 2,
-		-sixS, -2 * sixS, -3 * sixS, -5 * sixS, -12345 * sixS,
-		-sixS + 1, -2*sixS - 5, -3*sixS + 3, -5*sixS + 4, -12345*sixS - 2,
-		nineteenS, 2 * nineteenS, 3 * nineteenS, 5 * nineteenS, 12345 * nineteenS,
-		nineteenS + 1, 2*nineteenS - 5, 3*nineteenS + 3, 5*nineteenS + 4, 12345*nineteenS - 2,
-		-nineteenS, -2 * nineteenS, -3 * nineteenS, -5 * nineteenS, -12345 * nineteenS,
-		-nineteenS + 1, -2*nineteenS - 5, -3*nineteenS + 3, -5*nineteenS + 4, -12345*nineteenS - 2,
-		minI32, minI32 + 1, minI32 + 2, minI32 + 3, minI32 + 4,
-		minI32 + 5, minI32 + 6, minI32 + 7, minI32 + 8,
-		minI32 + 9, minI32 + 10, minI32 + 11, minI32 + 12,
-		minI32 + 13, minI32 + 14, minI32 + 15, minI32 + 16,
-		minI32 + 17, minI32 + 18, minI32 + 19, minI32 + 20,
-		maxI32, maxI32 - 1, maxI32 - 2, maxI32 - 3, maxI32 - 4,
-		maxI32 - 5, maxI32 - 6, maxI32 - 7, maxI32 - 8,
-		maxI32 - 9, maxI32 - 10, maxI32 - 11, maxI32 - 12,
-		maxI32 - 13, maxI32 - 14, maxI32 - 15, maxI32 - 16,
-		maxI32 - 17, maxI32 - 18, maxI32 - 19, maxI32 - 20,
-		minI64, minI64 + 1, minI64 + 2, minI64 + 3, minI64 + 4,
-		minI64 + 5, minI64 + 6, minI64 + 7, minI64 + 8,
-		minI64 + 9, minI64 + 10, minI64 + 11, minI64 + 12,
-		minI64 + 13, minI64 + 14, minI64 + 15, minI64 + 16,
-		minI64 + 17, minI64 + 18, minI64 + 19, minI64 + 20,
-		maxI64, maxI64 - 1, maxI64 - 2, maxI64 - 3, maxI64 - 4,
-		maxI64 - 5, maxI64 - 6, maxI64 - 7, maxI64 - 8,
-		maxI64 - 9, maxI64 - 10, maxI64 - 11, maxI64 - 12,
-		maxI64 - 13, maxI64 - 14, maxI64 - 15, maxI64 - 16,
-		maxI64 - 17, maxI64 - 18, maxI64 - 19, maxI64 - 20,
-	}
-	for _, x := range xs {
-		if minI32 <= x && x <= maxI32 {
-			if want, got := int32(x)%int32(sixS) == 0, div6_int32(int32(x)); got != want {
-				t.Errorf("div6_int32(%d) = %v want %v", x, got, want)
-			}
-			if want, got := int32(x)%int32(nineteenS) == 0, div19_int32(int32(x)); got != want {
-				t.Errorf("div19_int32(%d) = %v want %v", x, got, want)
-			}
-		}
-		if want, got := x%sixS == 0, div6_int64(x); got != want {
-			t.Errorf("div6_int64(%d) = %v want %v", x, got, want)
-		}
-		if want, got := x%nineteenS == 0, div19_int64(x); got != want {
-			t.Errorf("div19_int64(%d) = %v want %v", x, got, want)
-		}
-	}
-}
diff --git a/src/cmd/compile/internal/gc/testdata/reproducible/issue38068.go b/src/cmd/compile/internal/gc/testdata/reproducible/issue38068.go
deleted file mode 100644
index db5ca7d..0000000
--- a/src/cmd/compile/internal/gc/testdata/reproducible/issue38068.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package issue38068
-
-// A type with a couple of inlinable, non-pointer-receiver methods
-// that have params and local variables.
-type A struct {
-	s    string
-	next *A
-	prev *A
-}
-
-// Inlinable, value-received method with locals and parms.
-func (a A) double(x string, y int) string {
-	if y == 191 {
-		a.s = ""
-	}
-	q := a.s + "a"
-	r := a.s + "b"
-	return q + r
-}
-
-// Inlinable, value-received method with locals and parms.
-func (a A) triple(x string, y int) string {
-	q := a.s
-	if y == 998877 {
-		a.s = x
-	}
-	r := a.s + a.s
-	return q + r
-}
-
-type methods struct {
-	m1 func(a *A, x string, y int) string
-	m2 func(a *A, x string, y int) string
-}
-
-// Now a function that makes references to the methods via pointers,
-// which should trigger the wrapper generation.
-func P(a *A, ms *methods) {
-	if a != nil {
-		defer func() { println("done") }()
-	}
-	println(ms.m1(a, "a", 2))
-	println(ms.m2(a, "b", 3))
-}
-
-func G(x *A, n int) {
-	if n <= 0 {
-		println(n)
-		return
-	}
-	// Address-taken local of type A, which will insure that the
-	// compiler's dtypesym() routine will create a method wrapper.
-	var a, b A
-	a.next = x
-	a.prev = &b
-	x = &a
-	G(x, n-2)
-}
-
-var M methods
-
-func F() {
-	M.m1 = (*A).double
-	M.m2 = (*A).triple
-	G(nil, 100)
-}
diff --git a/src/cmd/compile/internal/gc/timings.go b/src/cmd/compile/internal/gc/timings.go
deleted file mode 100644
index 56b3899..0000000
--- a/src/cmd/compile/internal/gc/timings.go
+++ /dev/null
@@ -1,235 +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.
-
-package gc
-
-import (
-	"fmt"
-	"io"
-	"strings"
-	"time"
-)
-
-// Timings collects the execution times of labeled phases
-// which are added trough a sequence of Start/Stop calls.
-// Events may be associated with each phase via AddEvent.
-type Timings struct {
-	list   []timestamp
-	events map[int][]*event // lazily allocated
-}
-
-type timestamp struct {
-	time  time.Time
-	label string
-	start bool
-}
-
-type event struct {
-	size int64  // count or amount of data processed (allocations, data size, lines, funcs, ...)
-	unit string // unit of size measure (count, MB, lines, funcs, ...)
-}
-
-func (t *Timings) append(labels []string, start bool) {
-	t.list = append(t.list, timestamp{time.Now(), strings.Join(labels, ":"), start})
-}
-
-// Start marks the beginning of a new phase and implicitly stops the previous phase.
-// The phase name is the colon-separated concatenation of the labels.
-func (t *Timings) Start(labels ...string) {
-	t.append(labels, true)
-}
-
-// Stop marks the end of a phase and implicitly starts a new phase.
-// The labels are added to the labels of the ended phase.
-func (t *Timings) Stop(labels ...string) {
-	t.append(labels, false)
-}
-
-// AddEvent associates an event, i.e., a count, or an amount of data,
-// with the most recently started or stopped phase; or the very first
-// phase if Start or Stop hasn't been called yet. The unit specifies
-// the unit of measurement (e.g., MB, lines, no. of funcs, etc.).
-func (t *Timings) AddEvent(size int64, unit string) {
-	m := t.events
-	if m == nil {
-		m = make(map[int][]*event)
-		t.events = m
-	}
-	i := len(t.list)
-	if i > 0 {
-		i--
-	}
-	m[i] = append(m[i], &event{size, unit})
-}
-
-// Write prints the phase times to w.
-// The prefix is printed at the start of each line.
-func (t *Timings) Write(w io.Writer, prefix string) {
-	if len(t.list) > 0 {
-		var lines lines
-
-		// group of phases with shared non-empty label prefix
-		var group struct {
-			label string        // label prefix
-			tot   time.Duration // accumulated phase time
-			size  int           // number of phases collected in group
-		}
-
-		// accumulated time between Stop/Start timestamps
-		var unaccounted time.Duration
-
-		// process Start/Stop timestamps
-		pt := &t.list[0] // previous timestamp
-		tot := t.list[len(t.list)-1].time.Sub(pt.time)
-		for i := 1; i < len(t.list); i++ {
-			qt := &t.list[i] // current timestamp
-			dt := qt.time.Sub(pt.time)
-
-			var label string
-			var events []*event
-			if pt.start {
-				// previous phase started
-				label = pt.label
-				events = t.events[i-1]
-				if qt.start {
-					// start implicitly ended previous phase; nothing to do
-				} else {
-					// stop ended previous phase; append stop labels, if any
-					if qt.label != "" {
-						label += ":" + qt.label
-					}
-					// events associated with stop replace prior events
-					if e := t.events[i]; e != nil {
-						events = e
-					}
-				}
-			} else {
-				// previous phase stopped
-				if qt.start {
-					// between a stopped and started phase; unaccounted time
-					unaccounted += dt
-				} else {
-					// previous stop implicitly started current phase
-					label = qt.label
-					events = t.events[i]
-				}
-			}
-			if label != "" {
-				// add phase to existing group, or start a new group
-				l := commonPrefix(group.label, label)
-				if group.size == 1 && l != "" || group.size > 1 && l == group.label {
-					// add to existing group
-					group.label = l
-					group.tot += dt
-					group.size++
-				} else {
-					// start a new group
-					if group.size > 1 {
-						lines.add(prefix+group.label+"subtotal", 1, group.tot, tot, nil)
-					}
-					group.label = label
-					group.tot = dt
-					group.size = 1
-				}
-
-				// write phase
-				lines.add(prefix+label, 1, dt, tot, events)
-			}
-
-			pt = qt
-		}
-
-		if group.size > 1 {
-			lines.add(prefix+group.label+"subtotal", 1, group.tot, tot, nil)
-		}
-
-		if unaccounted != 0 {
-			lines.add(prefix+"unaccounted", 1, unaccounted, tot, nil)
-		}
-
-		lines.add(prefix+"total", 1, tot, tot, nil)
-
-		lines.write(w)
-	}
-}
-
-func commonPrefix(a, b string) string {
-	i := 0
-	for i < len(a) && i < len(b) && a[i] == b[i] {
-		i++
-	}
-	return a[:i]
-}
-
-type lines [][]string
-
-func (lines *lines) add(label string, n int, dt, tot time.Duration, events []*event) {
-	var line []string
-	add := func(format string, args ...interface{}) {
-		line = append(line, fmt.Sprintf(format, args...))
-	}
-
-	add("%s", label)
-	add("    %d", n)
-	add("    %d ns/op", dt)
-	add("    %.2f %%", float64(dt)/float64(tot)*100)
-
-	for _, e := range events {
-		add("    %d", e.size)
-		add(" %s", e.unit)
-		add("    %d", int64(float64(e.size)/dt.Seconds()+0.5))
-		add(" %s/s", e.unit)
-	}
-
-	*lines = append(*lines, line)
-}
-
-func (lines lines) write(w io.Writer) {
-	// determine column widths and contents
-	var widths []int
-	var number []bool
-	for _, line := range lines {
-		for i, col := range line {
-			if i < len(widths) {
-				if len(col) > widths[i] {
-					widths[i] = len(col)
-				}
-			} else {
-				widths = append(widths, len(col))
-				number = append(number, isnumber(col)) // first line determines column contents
-			}
-		}
-	}
-
-	// make column widths a multiple of align for more stable output
-	const align = 1 // set to a value > 1 to enable
-	if align > 1 {
-		for i, w := range widths {
-			w += align - 1
-			widths[i] = w - w%align
-		}
-	}
-
-	// print lines taking column widths and contents into account
-	for _, line := range lines {
-		for i, col := range line {
-			format := "%-*s"
-			if number[i] {
-				format = "%*s" // numbers are right-aligned
-			}
-			fmt.Fprintf(w, format, widths[i], col)
-		}
-		fmt.Fprintln(w)
-	}
-}
-
-func isnumber(s string) bool {
-	for _, ch := range s {
-		if ch <= ' ' {
-			continue // ignore leading whitespace
-		}
-		return '0' <= ch && ch <= '9' || ch == '.' || ch == '-' || ch == '+'
-	}
-	return false
-}
diff --git a/src/cmd/compile/internal/gc/trace.go b/src/cmd/compile/internal/gc/trace.go
index ed4b5a2..8cdbd4b 100644
--- a/src/cmd/compile/internal/gc/trace.go
+++ b/src/cmd/compile/internal/gc/trace.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.7
 // +build go1.7
 
 package gc
@@ -9,6 +10,8 @@
 import (
 	"os"
 	tracepkg "runtime/trace"
+
+	"cmd/compile/internal/base"
 )
 
 func init() {
@@ -18,10 +21,10 @@
 func traceHandlerGo17(traceprofile string) {
 	f, err := os.Create(traceprofile)
 	if err != nil {
-		Fatalf("%v", err)
+		base.Fatalf("%v", err)
 	}
 	if err := tracepkg.Start(f); err != nil {
-		Fatalf("%v", err)
+		base.Fatalf("%v", err)
 	}
-	atExit(tracepkg.Stop)
+	base.AtExit(tracepkg.Stop)
 }
diff --git a/src/cmd/compile/internal/gc/truncconst_test.go b/src/cmd/compile/internal/gc/truncconst_test.go
deleted file mode 100644
index d153818..0000000
--- a/src/cmd/compile/internal/gc/truncconst_test.go
+++ /dev/null
@@ -1,63 +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 gc
-
-import "testing"
-
-var f52want float64 = 1.0 / (1 << 52)
-var f53want float64 = 1.0 / (1 << 53)
-
-func TestTruncFlt(t *testing.T) {
-	const f52 = 1 + 1.0/(1<<52)
-	const f53 = 1 + 1.0/(1<<53)
-
-	if got := f52 - 1; got != f52want {
-		t.Errorf("f52-1 = %g, want %g", got, f52want)
-	}
-	if got := float64(f52) - 1; got != f52want {
-		t.Errorf("float64(f52)-1 = %g, want %g", got, f52want)
-	}
-	if got := f53 - 1; got != f53want {
-		t.Errorf("f53-1 = %g, want %g", got, f53want)
-	}
-	if got := float64(f53) - 1; got != 0 {
-		t.Errorf("float64(f53)-1 = %g, want 0", got)
-	}
-}
-
-func TestTruncCmplx(t *testing.T) {
-	const r52 = complex(1+1.0/(1<<52), 0)
-	const r53 = complex(1+1.0/(1<<53), 0)
-
-	if got := real(r52 - 1); got != f52want {
-		t.Errorf("real(r52-1) = %g, want %g", got, f52want)
-	}
-	if got := real(complex128(r52) - 1); got != f52want {
-		t.Errorf("real(complex128(r52)-1) = %g, want %g", got, f52want)
-	}
-	if got := real(r53 - 1); got != f53want {
-		t.Errorf("real(r53-1) = %g, want %g", got, f53want)
-	}
-	if got := real(complex128(r53) - 1); got != 0 {
-		t.Errorf("real(complex128(r53)-1) = %g, want 0", got)
-	}
-
-	const i52 = complex(0, 1+1.0/(1<<52))
-	const i53 = complex(0, 1+1.0/(1<<53))
-
-	if got := imag(i52 - 1i); got != f52want {
-		t.Errorf("imag(i52-1i) = %g, want %g", got, f52want)
-	}
-	if got := imag(complex128(i52) - 1i); got != f52want {
-		t.Errorf("imag(complex128(i52)-1i) = %g, want %g", got, f52want)
-	}
-	if got := imag(i53 - 1i); got != f53want {
-		t.Errorf("imag(i53-1i) = %g, want %g", got, f53want)
-	}
-	if got := imag(complex128(i53) - 1i); got != 0 {
-		t.Errorf("imag(complex128(i53)-1i) = %g, want 0", got)
-	}
-
-}
diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
deleted file mode 100644
index c0b0503..0000000
--- a/src/cmd/compile/internal/gc/typecheck.go
+++ /dev/null
@@ -1,4019 +0,0 @@
-// Copyright 2009 The Go Authors. 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/compile/internal/types"
-	"fmt"
-	"strings"
-)
-
-// To enable tracing support (-t flag), set enableTrace to true.
-const enableTrace = false
-
-var trace bool
-var traceIndent []byte
-var skipDowidthForTracing bool
-
-func tracePrint(title string, n *Node) func(np **Node) {
-	indent := traceIndent
-
-	// guard against nil
-	var pos, op string
-	var tc uint8
-	if n != nil {
-		pos = linestr(n.Pos)
-		op = n.Op.String()
-		tc = n.Typecheck()
-	}
-
-	skipDowidthForTracing = true
-	defer func() { skipDowidthForTracing = false }()
-	fmt.Printf("%s: %s%s %p %s %v tc=%d\n", pos, indent, title, n, op, n, tc)
-	traceIndent = append(traceIndent, ". "...)
-
-	return func(np **Node) {
-		traceIndent = traceIndent[:len(traceIndent)-2]
-
-		// if we have a result, use that
-		if np != nil {
-			n = *np
-		}
-
-		// guard against nil
-		// use outer pos, op so we don't get empty pos/op if n == nil (nicer output)
-		var tc uint8
-		var typ *types.Type
-		if n != nil {
-			pos = linestr(n.Pos)
-			op = n.Op.String()
-			tc = n.Typecheck()
-			typ = n.Type
-		}
-
-		skipDowidthForTracing = true
-		defer func() { skipDowidthForTracing = false }()
-		fmt.Printf("%s: %s=> %p %s %v tc=%d type=%#L\n", pos, indent, n, op, n, tc, typ)
-	}
-}
-
-const (
-	ctxStmt    = 1 << iota // evaluated at statement level
-	ctxExpr                // evaluated in value context
-	ctxType                // evaluated in type context
-	ctxCallee              // call-only expressions are ok
-	ctxMultiOK             // multivalue function returns are ok
-	ctxAssign              // assigning to expression
-)
-
-// type checks the whole tree of an expression.
-// calculates expression types.
-// evaluates compile time constants.
-// marks variables that escape the local frame.
-// rewrites n.Op to be more specific in some cases.
-
-var typecheckdefstack []*Node
-
-// resolve ONONAME to definition, if any.
-func resolve(n *Node) (res *Node) {
-	if n == nil || n.Op != ONONAME {
-		return n
-	}
-
-	// only trace if there's work to do
-	if enableTrace && trace {
-		defer tracePrint("resolve", n)(&res)
-	}
-
-	if n.Sym.Pkg != localpkg {
-		if inimport {
-			Fatalf("recursive inimport")
-		}
-		inimport = true
-		expandDecl(n)
-		inimport = false
-		return n
-	}
-
-	r := asNode(n.Sym.Def)
-	if r == nil {
-		return n
-	}
-
-	if r.Op == OIOTA {
-		if x := getIotaValue(); x >= 0 {
-			return nodintconst(x)
-		}
-		return n
-	}
-
-	return r
-}
-
-func typecheckslice(l []*Node, top int) {
-	for i := range l {
-		l[i] = typecheck(l[i], top)
-	}
-}
-
-var _typekind = []string{
-	TINT:        "int",
-	TUINT:       "uint",
-	TINT8:       "int8",
-	TUINT8:      "uint8",
-	TINT16:      "int16",
-	TUINT16:     "uint16",
-	TINT32:      "int32",
-	TUINT32:     "uint32",
-	TINT64:      "int64",
-	TUINT64:     "uint64",
-	TUINTPTR:    "uintptr",
-	TCOMPLEX64:  "complex64",
-	TCOMPLEX128: "complex128",
-	TFLOAT32:    "float32",
-	TFLOAT64:    "float64",
-	TBOOL:       "bool",
-	TSTRING:     "string",
-	TPTR:        "pointer",
-	TUNSAFEPTR:  "unsafe.Pointer",
-	TSTRUCT:     "struct",
-	TINTER:      "interface",
-	TCHAN:       "chan",
-	TMAP:        "map",
-	TARRAY:      "array",
-	TSLICE:      "slice",
-	TFUNC:       "func",
-	TNIL:        "nil",
-	TIDEAL:      "untyped number",
-}
-
-func typekind(t *types.Type) string {
-	if t.IsUntyped() {
-		return fmt.Sprintf("%v", t)
-	}
-	et := t.Etype
-	if int(et) < len(_typekind) {
-		s := _typekind[et]
-		if s != "" {
-			return s
-		}
-	}
-	return fmt.Sprintf("etype=%d", et)
-}
-
-func cycleFor(start *Node) []*Node {
-	// Find the start node in typecheck_tcstack.
-	// We know that it must exist because each time we mark
-	// a node with n.SetTypecheck(2) we push it on the stack,
-	// and each time we mark a node with n.SetTypecheck(2) we
-	// pop it from the stack. We hit a cycle when we encounter
-	// a node marked 2 in which case is must be on the stack.
-	i := len(typecheck_tcstack) - 1
-	for i > 0 && typecheck_tcstack[i] != start {
-		i--
-	}
-
-	// collect all nodes with same Op
-	var cycle []*Node
-	for _, n := range typecheck_tcstack[i:] {
-		if n.Op == start.Op {
-			cycle = append(cycle, n)
-		}
-	}
-
-	return cycle
-}
-
-func cycleTrace(cycle []*Node) string {
-	var s string
-	for i, n := range cycle {
-		s += fmt.Sprintf("\n\t%v: %v uses %v", n.Line(), n, cycle[(i+1)%len(cycle)])
-	}
-	return s
-}
-
-var typecheck_tcstack []*Node
-
-// typecheck type checks node n.
-// The result of typecheck MUST be assigned back to n, e.g.
-// 	n.Left = typecheck(n.Left, top)
-func typecheck(n *Node, top int) (res *Node) {
-	// cannot type check until all the source has been parsed
-	if !typecheckok {
-		Fatalf("early typecheck")
-	}
-
-	if n == nil {
-		return nil
-	}
-
-	// only trace if there's work to do
-	if enableTrace && trace {
-		defer tracePrint("typecheck", n)(&res)
-	}
-
-	lno := setlineno(n)
-
-	// Skip over parens.
-	for n.Op == OPAREN {
-		n = n.Left
-	}
-
-	// Resolve definition of name and value of iota lazily.
-	n = resolve(n)
-
-	// Skip typecheck if already done.
-	// But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
-	if n.Typecheck() == 1 {
-		switch n.Op {
-		case ONAME, OTYPE, OLITERAL, OPACK:
-			break
-
-		default:
-			lineno = lno
-			return n
-		}
-	}
-
-	if n.Typecheck() == 2 {
-		// Typechecking loop. Trying printing a meaningful message,
-		// otherwise a stack trace of typechecking.
-		switch n.Op {
-		// We can already diagnose variables used as types.
-		case ONAME:
-			if top&(ctxExpr|ctxType) == ctxType {
-				yyerror("%v is not a type", n)
-			}
-
-		case OTYPE:
-			// Only report a type cycle if we are expecting a type.
-			// Otherwise let other code report an error.
-			if top&ctxType == ctxType {
-				// A cycle containing only alias types is an error
-				// since it would expand indefinitely when aliases
-				// are substituted.
-				cycle := cycleFor(n)
-				for _, n1 := range cycle {
-					if n1.Name != nil && !n1.Name.Param.Alias() {
-						// Cycle is ok. But if n is an alias type and doesn't
-						// have a type yet, we have a recursive type declaration
-						// with aliases that we can't handle properly yet.
-						// Report an error rather than crashing later.
-						if n.Name != nil && n.Name.Param.Alias() && n.Type == nil {
-							lineno = n.Pos
-							Fatalf("cannot handle alias type declaration (issue #25838): %v", n)
-						}
-						lineno = lno
-						return n
-					}
-				}
-				yyerrorl(n.Pos, "invalid recursive type alias %v%s", n, cycleTrace(cycle))
-			}
-
-		case OLITERAL:
-			if top&(ctxExpr|ctxType) == ctxType {
-				yyerror("%v is not a type", n)
-				break
-			}
-			yyerrorl(n.Pos, "constant definition loop%s", cycleTrace(cycleFor(n)))
-		}
-
-		if nsavederrors+nerrors == 0 {
-			var trace string
-			for i := len(typecheck_tcstack) - 1; i >= 0; i-- {
-				x := typecheck_tcstack[i]
-				trace += fmt.Sprintf("\n\t%v %v", x.Line(), x)
-			}
-			yyerror("typechecking loop involving %v%s", n, trace)
-		}
-
-		lineno = lno
-		return n
-	}
-
-	n.SetTypecheck(2)
-
-	typecheck_tcstack = append(typecheck_tcstack, n)
-	n = typecheck1(n, top)
-
-	n.SetTypecheck(1)
-
-	last := len(typecheck_tcstack) - 1
-	typecheck_tcstack[last] = nil
-	typecheck_tcstack = typecheck_tcstack[:last]
-
-	lineno = lno
-	return n
-}
-
-// indexlit implements typechecking of untyped values as
-// 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 != nil && n.Type.Etype == TIDEAL {
-		return defaultlit(n, types.Types[TINT])
-	}
-	return n
-}
-
-// The result of typecheck1 MUST be assigned back to n, e.g.
-// 	n.Left = typecheck1(n.Left, top)
-func typecheck1(n *Node, top int) (res *Node) {
-	if enableTrace && trace {
-		defer tracePrint("typecheck1", n)(&res)
-	}
-
-	switch n.Op {
-	case OLITERAL, ONAME, ONONAME, OTYPE:
-		if n.Sym == nil {
-			break
-		}
-
-		if n.Op == ONAME && n.SubOp() != 0 && top&ctxCallee == 0 {
-			yyerror("use of builtin %v not in function call", n.Sym)
-			n.Type = nil
-			return n
-		}
-
-		typecheckdef(n)
-		if n.Op == ONONAME {
-			n.Type = nil
-			return n
-		}
-	}
-
-	ok := 0
-	switch n.Op {
-	// until typecheck is complete, do nothing.
-	default:
-		Dump("typecheck", n)
-
-		Fatalf("typecheck %v", n.Op)
-
-	// names
-	case OLITERAL:
-		ok |= ctxExpr
-
-		if n.Type == nil && n.Val().Ctype() == CTSTR {
-			n.Type = types.UntypedString
-		}
-
-	case ONONAME:
-		ok |= ctxExpr
-
-	case ONAME:
-		if n.Name.Decldepth == 0 {
-			n.Name.Decldepth = decldepth
-		}
-		if n.SubOp() != 0 {
-			ok |= ctxCallee
-			break
-		}
-
-		if top&ctxAssign == 0 {
-			// not a write to the variable
-			if n.isBlank() {
-				yyerror("cannot use _ as value")
-				n.Type = nil
-				return n
-			}
-
-			n.Name.SetUsed(true)
-		}
-
-		ok |= ctxExpr
-
-	case OPACK:
-		yyerror("use of package %v without selector", n.Sym)
-		n.Type = nil
-		return n
-
-	case ODDD:
-		break
-
-	// types (ODEREF is with exprs)
-	case OTYPE:
-		ok |= ctxType
-
-		if n.Type == nil {
-			return n
-		}
-
-	case OTARRAY:
-		ok |= ctxType
-		r := typecheck(n.Right, ctxType)
-		if r.Type == nil {
-			n.Type = nil
-			return n
-		}
-
-		var t *types.Type
-		if n.Left == nil {
-			t = types.NewSlice(r.Type)
-		} else if n.Left.Op == ODDD {
-			if !n.Diag() {
-				n.SetDiag(true)
-				yyerror("use of [...] array outside of array literal")
-			}
-			n.Type = nil
-			return n
-		} else {
-			n.Left = indexlit(typecheck(n.Left, ctxExpr))
-			l := n.Left
-			if consttype(l) != CTINT {
-				switch {
-				case l.Type == nil:
-					// Error already reported elsewhere.
-				case l.Type.IsInteger() && l.Op != OLITERAL:
-					yyerror("non-constant array bound %v", l)
-				default:
-					yyerror("invalid array bound %v", l)
-				}
-				n.Type = nil
-				return n
-			}
-
-			v := l.Val()
-			if doesoverflow(v, types.Types[TINT]) {
-				yyerror("array bound is too large")
-				n.Type = nil
-				return n
-			}
-
-			bound := v.U.(*Mpint).Int64()
-			if bound < 0 {
-				yyerror("array bound must be non-negative")
-				n.Type = nil
-				return n
-			}
-			t = types.NewArray(r.Type, bound)
-		}
-
-		setTypeNode(n, t)
-		n.Left = nil
-		n.Right = nil
-		checkwidth(t)
-
-	case OTMAP:
-		ok |= ctxType
-		n.Left = typecheck(n.Left, ctxType)
-		n.Right = typecheck(n.Right, ctxType)
-		l := n.Left
-		r := n.Right
-		if l.Type == nil || r.Type == nil {
-			n.Type = nil
-			return n
-		}
-		if l.Type.NotInHeap() {
-			yyerror("incomplete (or unallocatable) map key not allowed")
-		}
-		if r.Type.NotInHeap() {
-			yyerror("incomplete (or unallocatable) map value not allowed")
-		}
-
-		setTypeNode(n, types.NewMap(l.Type, r.Type))
-		mapqueue = append(mapqueue, n) // check map keys when all types are settled
-		n.Left = nil
-		n.Right = nil
-
-	case OTCHAN:
-		ok |= ctxType
-		n.Left = typecheck(n.Left, ctxType)
-		l := n.Left
-		if l.Type == nil {
-			n.Type = nil
-			return n
-		}
-		if l.Type.NotInHeap() {
-			yyerror("chan of incomplete (or unallocatable) type not allowed")
-		}
-
-		setTypeNode(n, types.NewChan(l.Type, n.TChanDir()))
-		n.Left = nil
-		n.ResetAux()
-
-	case OTSTRUCT:
-		ok |= ctxType
-		setTypeNode(n, tostruct(n.List.Slice()))
-		n.List.Set(nil)
-
-	case OTINTER:
-		ok |= ctxType
-		setTypeNode(n, tointerface(n.List.Slice()))
-
-	case OTFUNC:
-		ok |= ctxType
-		setTypeNode(n, functype(n.Left, n.List.Slice(), n.Rlist.Slice()))
-		n.Left = nil
-		n.List.Set(nil)
-		n.Rlist.Set(nil)
-
-	// type or expr
-	case ODEREF:
-		n.Left = typecheck(n.Left, ctxExpr|ctxType)
-		l := n.Left
-		t := l.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-		if l.Op == OTYPE {
-			ok |= ctxType
-			setTypeNode(n, types.NewPtr(l.Type))
-			n.Left = nil
-			// Ensure l.Type gets dowidth'd for the backend. Issue 20174.
-			checkwidth(l.Type)
-			break
-		}
-
-		if !t.IsPtr() {
-			if top&(ctxExpr|ctxStmt) != 0 {
-				yyerror("invalid indirect of %L", n.Left)
-				n.Type = nil
-				return n
-			}
-
-			break
-		}
-
-		ok |= ctxExpr
-		n.Type = t.Elem()
-
-	// arithmetic exprs
-	case OASOP,
-		OADD,
-		OAND,
-		OANDAND,
-		OANDNOT,
-		ODIV,
-		OEQ,
-		OGE,
-		OGT,
-		OLE,
-		OLT,
-		OLSH,
-		ORSH,
-		OMOD,
-		OMUL,
-		ONE,
-		OOR,
-		OOROR,
-		OSUB,
-		OXOR:
-		var l *Node
-		var op Op
-		var r *Node
-		if n.Op == OASOP {
-			ok |= ctxStmt
-			n.Left = typecheck(n.Left, ctxExpr)
-			n.Right = typecheck(n.Right, ctxExpr)
-			l = n.Left
-			r = n.Right
-			checkassign(n, n.Left)
-			if l.Type == nil || r.Type == nil {
-				n.Type = nil
-				return n
-			}
-			if n.Implicit() && !okforarith[l.Type.Etype] {
-				yyerror("invalid operation: %v (non-numeric type %v)", n, l.Type)
-				n.Type = nil
-				return n
-			}
-			// TODO(marvin): Fix Node.EType type union.
-			op = n.SubOp()
-		} else {
-			ok |= ctxExpr
-			n.Left = typecheck(n.Left, ctxExpr)
-			n.Right = typecheck(n.Right, ctxExpr)
-			l = n.Left
-			r = n.Right
-			if l.Type == nil || r.Type == nil {
-				n.Type = nil
-				return n
-			}
-			op = n.Op
-		}
-		if op == OLSH || op == ORSH {
-			r = defaultlit(r, types.Types[TUINT])
-			n.Right = r
-			t := r.Type
-			if !t.IsInteger() {
-				yyerror("invalid operation: %v (shift count type %v, must be integer)", n, r.Type)
-				n.Type = nil
-				return n
-			}
-			if t.IsSigned() && !langSupported(1, 13, curpkg()) {
-				yyerrorv("go1.13", "invalid operation: %v (signed shift count type %v)", n, r.Type)
-				n.Type = nil
-				return n
-			}
-			t = l.Type
-			if t != nil && t.Etype != TIDEAL && !t.IsInteger() {
-				yyerror("invalid operation: %v (shift of type %v)", n, t)
-				n.Type = nil
-				return n
-			}
-
-			// no defaultlit for left
-			// the outer context gives the type
-			n.Type = l.Type
-			if (l.Type == types.UntypedFloat || l.Type == types.UntypedComplex) && r.Op == OLITERAL {
-				n.Type = types.UntypedInt
-			}
-
-			break
-		}
-
-		// For "x == x && len(s)", it's better to report that "len(s)" (type int)
-		// can't be used with "&&" than to report that "x == x" (type untyped bool)
-		// can't be converted to int (see issue #41500).
-		if n.Op == OANDAND || n.Op == OOROR {
-			if !n.Left.Type.IsBoolean() {
-				yyerror("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(n.Left.Type))
-				n.Type = nil
-				return n
-			}
-			if !n.Right.Type.IsBoolean() {
-				yyerror("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(n.Right.Type))
-				n.Type = nil
-				return n
-			}
-		}
-
-		// ideal mixed with non-ideal
-		l, r = defaultlit2(l, r, false)
-
-		n.Left = l
-		n.Right = r
-		if l.Type == nil || r.Type == nil {
-			n.Type = nil
-			return n
-		}
-		t := l.Type
-		if t.Etype == TIDEAL {
-			t = r.Type
-		}
-		et := t.Etype
-		if et == TIDEAL {
-			et = TINT
-		}
-		aop := OXXX
-		if iscmp[n.Op] && t.Etype != TIDEAL && !types.Identical(l.Type, r.Type) {
-			// comparison is okay as long as one side is
-			// assignable to the other.  convert so they have
-			// the same type.
-			//
-			// 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)
-				if aop != OXXX {
-					if r.Type.IsInterface() && !l.Type.IsInterface() && !IsComparable(l.Type) {
-						yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type))
-						n.Type = nil
-						return n
-					}
-
-					dowidth(l.Type)
-					if r.Type.IsInterface() == l.Type.IsInterface() || l.Type.Width >= 1<<16 {
-						l = nod(aop, l, nil)
-						l.Type = r.Type
-						l.SetTypecheck(1)
-						n.Left = l
-					}
-
-					t = r.Type
-					converted = true
-				}
-			}
-
-			if !converted && l.Type.Etype != TBLANK {
-				aop, _ = assignop(r.Type, l.Type)
-				if aop != OXXX {
-					if l.Type.IsInterface() && !r.Type.IsInterface() && !IsComparable(r.Type) {
-						yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type))
-						n.Type = nil
-						return n
-					}
-
-					dowidth(r.Type)
-					if r.Type.IsInterface() == l.Type.IsInterface() || r.Type.Width >= 1<<16 {
-						r = nod(aop, r, nil)
-						r.Type = l.Type
-						r.SetTypecheck(1)
-						n.Right = r
-					}
-
-					t = l.Type
-				}
-			}
-
-			et = t.Etype
-		}
-
-		if t.Etype != TIDEAL && !types.Identical(l.Type, r.Type) {
-			l, r = defaultlit2(l, r, true)
-			if l.Type == nil || r.Type == nil {
-				n.Type = nil
-				return n
-			}
-			if l.Type.IsInterface() == r.Type.IsInterface() || aop == 0 {
-				yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type)
-				n.Type = nil
-				return n
-			}
-		}
-
-		if t.Etype == TIDEAL {
-			t = mixUntyped(l.Type, r.Type)
-		}
-		if dt := defaultType(t); !okfor[op][dt.Etype] {
-			yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(t))
-			n.Type = nil
-			return n
-		}
-
-		// okfor allows any array == array, map == map, func == func.
-		// restrict to slice/map/func == nil and nil == slice/map/func.
-		if l.Type.IsArray() && !IsComparable(l.Type) {
-			yyerror("invalid operation: %v (%v cannot be compared)", n, l.Type)
-			n.Type = nil
-			return n
-		}
-
-		if l.Type.IsSlice() && !l.isNil() && !r.isNil() {
-			yyerror("invalid operation: %v (slice can only be compared to nil)", n)
-			n.Type = nil
-			return n
-		}
-
-		if l.Type.IsMap() && !l.isNil() && !r.isNil() {
-			yyerror("invalid operation: %v (map can only be compared to nil)", n)
-			n.Type = nil
-			return n
-		}
-
-		if l.Type.Etype == TFUNC && !l.isNil() && !r.isNil() {
-			yyerror("invalid operation: %v (func can only be compared to nil)", n)
-			n.Type = nil
-			return n
-		}
-
-		if l.Type.IsStruct() {
-			if f := IncomparableField(l.Type); f != nil {
-				yyerror("invalid operation: %v (struct containing %v cannot be compared)", n, f.Type)
-				n.Type = nil
-				return n
-			}
-		}
-
-		if iscmp[n.Op] {
-			evconst(n)
-			t = types.UntypedBool
-			if n.Op != OLITERAL {
-				l, r = defaultlit2(l, r, true)
-				n.Left = l
-				n.Right = r
-			}
-		}
-
-		if et == TSTRING && n.Op == OADD {
-			// create OADDSTR node with list of strings in x + y + z + (w + v) + ...
-			n.Op = OADDSTR
-
-			if l.Op == OADDSTR {
-				n.List.Set(l.List.Slice())
-			} else {
-				n.List.Set1(l)
-			}
-			if r.Op == OADDSTR {
-				n.List.AppendNodes(&r.List)
-			} else {
-				n.List.Append(r)
-			}
-			n.Left = nil
-			n.Right = nil
-		}
-
-		if (op == ODIV || op == OMOD) && Isconst(r, CTINT) {
-			if r.Val().U.(*Mpint).CmpInt64(0) == 0 {
-				yyerror("division by zero")
-				n.Type = nil
-				return n
-			}
-		}
-
-		n.Type = t
-
-	case OBITNOT, ONEG, ONOT, OPLUS:
-		ok |= ctxExpr
-		n.Left = typecheck(n.Left, ctxExpr)
-		l := n.Left
-		t := l.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-		if !okfor[n.Op][defaultType(t).Etype] {
-			yyerror("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(t))
-			n.Type = nil
-			return n
-		}
-
-		n.Type = t
-
-	// exprs
-	case OADDR:
-		ok |= ctxExpr
-
-		n.Left = typecheck(n.Left, ctxExpr)
-		if n.Left.Type == nil {
-			n.Type = nil
-			return n
-		}
-
-		switch n.Left.Op {
-		case OARRAYLIT, OMAPLIT, OSLICELIT, OSTRUCTLIT:
-			n.Op = OPTRLIT
-
-		default:
-			checklvalue(n.Left, "take the address of")
-			r := outervalue(n.Left)
-			if r.Op == ONAME {
-				if r.Orig != r {
-					Fatalf("found non-orig name node %v", r) // TODO(mdempsky): What does this mean?
-				}
-				r.Name.SetAddrtaken(true)
-				if r.Name.IsClosureVar() && !capturevarscomplete {
-					// Mark the original variable as Addrtaken so that capturevars
-					// knows not to pass it by value.
-					// But if the capturevars phase is complete, don't touch it,
-					// in case l.Name's containing function has not yet been compiled.
-					r.Name.Defn.Name.SetAddrtaken(true)
-				}
-			}
-			n.Left = defaultlit(n.Left, nil)
-			if n.Left.Type == nil {
-				n.Type = nil
-				return n
-			}
-		}
-
-		n.Type = types.NewPtr(n.Left.Type)
-
-	case OCOMPLIT:
-		ok |= ctxExpr
-		n = typecheckcomplit(n)
-		if n.Type == nil {
-			return n
-		}
-
-	case OXDOT, ODOT:
-		if n.Op == OXDOT {
-			n = adddot(n)
-			n.Op = ODOT
-			if n.Left == nil {
-				n.Type = nil
-				return n
-			}
-		}
-
-		n.Left = typecheck(n.Left, ctxExpr|ctxType)
-
-		n.Left = defaultlit(n.Left, nil)
-
-		t := n.Left.Type
-		if t == nil {
-			adderrorname(n)
-			n.Type = nil
-			return n
-		}
-
-		s := n.Sym
-
-		if n.Left.Op == OTYPE {
-			n = typecheckMethodExpr(n)
-			if n.Type == nil {
-				return n
-			}
-			ok = ctxExpr
-			break
-		}
-
-		if t.IsPtr() && !t.Elem().IsInterface() {
-			t = t.Elem()
-			if t == nil {
-				n.Type = nil
-				return n
-			}
-			n.Op = ODOTPTR
-			checkwidth(t)
-		}
-
-		if n.Sym.IsBlank() {
-			yyerror("cannot refer to blank field or method")
-			n.Type = nil
-			return n
-		}
-
-		if lookdot(n, t, 0) == nil {
-			// Legitimate field or method lookup failed, try to explain the error
-			switch {
-			case t.IsEmptyInterface():
-				yyerror("%v undefined (type %v is interface with no methods)", n, n.Left.Type)
-
-			case t.IsPtr() && t.Elem().IsInterface():
-				// Pointer to interface is almost always a mistake.
-				yyerror("%v undefined (type %v is pointer to interface, not interface)", n, n.Left.Type)
-
-			case lookdot(n, t, 1) != nil:
-				// Field or method matches by name, but it is not exported.
-				yyerror("%v undefined (cannot refer to unexported field or method %v)", n, n.Sym)
-
-			default:
-				if mt := lookdot(n, t, 2); mt != nil && visible(mt.Sym) { // Case-insensitive lookup.
-					yyerror("%v undefined (type %v has no field or method %v, but does have %v)", n, n.Left.Type, n.Sym, mt.Sym)
-				} else {
-					yyerror("%v undefined (type %v has no field or method %v)", n, n.Left.Type, n.Sym)
-				}
-			}
-			n.Type = nil
-			return n
-		}
-
-		switch n.Op {
-		case ODOTINTER, ODOTMETH:
-			if top&ctxCallee != 0 {
-				ok |= ctxCallee
-			} else {
-				typecheckpartialcall(n, s)
-				ok |= ctxExpr
-			}
-
-		default:
-			ok |= ctxExpr
-		}
-
-	case ODOTTYPE:
-		ok |= ctxExpr
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Left = defaultlit(n.Left, nil)
-		l := n.Left
-		t := l.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-		if !t.IsInterface() {
-			yyerror("invalid type assertion: %v (non-interface type %v on left)", n, t)
-			n.Type = nil
-			return n
-		}
-
-		if n.Right != nil {
-			n.Right = typecheck(n.Right, ctxType)
-			n.Type = n.Right.Type
-			n.Right = nil
-			if n.Type == nil {
-				return n
-			}
-		}
-
-		if n.Type != nil && !n.Type.IsInterface() {
-			var missing, have *types.Field
-			var ptr int
-			if !implements(n.Type, t, &missing, &have, &ptr) {
-				if have != nil && have.Sym == missing.Sym {
-					yyerror("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+
-						"\t\thave %v%0S\n\t\twant %v%0S", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
-				} else if ptr != 0 {
-					yyerror("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", n.Type, t, missing.Sym)
-				} else if have != nil {
-					yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+
-						"\t\thave %v%0S\n\t\twant %v%0S", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
-				} else {
-					yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)", n.Type, t, missing.Sym)
-				}
-				n.Type = nil
-				return n
-			}
-		}
-
-	case OINDEX:
-		ok |= ctxExpr
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Left = defaultlit(n.Left, nil)
-		n.Left = implicitstar(n.Left)
-		l := n.Left
-		n.Right = typecheck(n.Right, ctxExpr)
-		r := n.Right
-		t := l.Type
-		if t == nil || r.Type == nil {
-			n.Type = nil
-			return n
-		}
-		switch t.Etype {
-		default:
-			yyerror("invalid operation: %v (type %v does not support indexing)", n, t)
-			n.Type = nil
-			return n
-
-		case TSTRING, TARRAY, TSLICE:
-			n.Right = indexlit(n.Right)
-			if t.IsString() {
-				n.Type = types.Bytetype
-			} else {
-				n.Type = t.Elem()
-			}
-			why := "string"
-			if t.IsArray() {
-				why = "array"
-			} else if t.IsSlice() {
-				why = "slice"
-			}
-
-			if n.Right.Type != nil && !n.Right.Type.IsInteger() {
-				yyerror("non-integer %s index %v", why, n.Right)
-				break
-			}
-
-			if !n.Bounded() && Isconst(n.Right, CTINT) {
-				x := n.Right.Int64Val()
-				if x < 0 {
-					yyerror("invalid %s index %v (index must be non-negative)", why, n.Right)
-				} else if t.IsArray() && x >= t.NumElem() {
-					yyerror("invalid array index %v (out of bounds for %d-element array)", n.Right, t.NumElem())
-				} else if Isconst(n.Left, CTSTR) && x >= int64(len(n.Left.StringVal())) {
-					yyerror("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.StringVal()))
-				} else if n.Right.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
-					yyerror("invalid %s index %v (index too large)", why, n.Right)
-				}
-			}
-
-		case TMAP:
-			n.Right = assignconv(n.Right, t.Key(), "map index")
-			n.Type = t.Elem()
-			n.Op = OINDEXMAP
-			n.ResetAux()
-		}
-
-	case ORECV:
-		ok |= ctxStmt | ctxExpr
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Left = defaultlit(n.Left, nil)
-		l := n.Left
-		t := l.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-		if !t.IsChan() {
-			yyerror("invalid operation: %v (receive from non-chan type %v)", n, t)
-			n.Type = nil
-			return n
-		}
-
-		if !t.ChanDir().CanRecv() {
-			yyerror("invalid operation: %v (receive from send-only type %v)", n, t)
-			n.Type = nil
-			return n
-		}
-
-		n.Type = t.Elem()
-
-	case OSEND:
-		ok |= ctxStmt
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Right = typecheck(n.Right, ctxExpr)
-		n.Left = defaultlit(n.Left, nil)
-		t := n.Left.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-		if !t.IsChan() {
-			yyerror("invalid operation: %v (send to non-chan type %v)", n, t)
-			n.Type = nil
-			return n
-		}
-
-		if !t.ChanDir().CanSend() {
-			yyerror("invalid operation: %v (send to receive-only type %v)", n, t)
-			n.Type = nil
-			return n
-		}
-
-		n.Right = assignconv(n.Right, t.Elem(), "send")
-		if n.Right.Type == nil {
-			n.Type = nil
-			return n
-		}
-		n.Type = nil
-
-	case OSLICEHEADER:
-		// Errors here are Fatalf instead of yyerror because only the compiler
-		// can construct an OSLICEHEADER node.
-		// Components used in OSLICEHEADER that are supplied by parsed source code
-		// have already been typechecked in e.g. OMAKESLICE earlier.
-		ok |= ctxExpr
-
-		t := n.Type
-		if t == nil {
-			Fatalf("no type specified for OSLICEHEADER")
-		}
-
-		if !t.IsSlice() {
-			Fatalf("invalid type %v for OSLICEHEADER", n.Type)
-		}
-
-		if n.Left == nil || n.Left.Type == nil || !n.Left.Type.IsUnsafePtr() {
-			Fatalf("need unsafe.Pointer for OSLICEHEADER")
-		}
-
-		if x := n.List.Len(); x != 2 {
-			Fatalf("expected 2 params (len, cap) for OSLICEHEADER, got %d", x)
-		}
-
-		n.Left = typecheck(n.Left, ctxExpr)
-		l := typecheck(n.List.First(), ctxExpr)
-		c := typecheck(n.List.Second(), ctxExpr)
-		l = defaultlit(l, types.Types[TINT])
-		c = defaultlit(c, types.Types[TINT])
-
-		if Isconst(l, CTINT) && l.Int64Val() < 0 {
-			Fatalf("len for OSLICEHEADER must be non-negative")
-		}
-
-		if Isconst(c, CTINT) && c.Int64Val() < 0 {
-			Fatalf("cap for OSLICEHEADER must be non-negative")
-		}
-
-		if Isconst(l, CTINT) && Isconst(c, CTINT) && l.Val().U.(*Mpint).Cmp(c.Val().U.(*Mpint)) > 0 {
-			Fatalf("len larger than cap for OSLICEHEADER")
-		}
-
-		n.List.SetFirst(l)
-		n.List.SetSecond(c)
-
-	case OMAKESLICECOPY:
-		// Errors here are Fatalf instead of yyerror because only the compiler
-		// can construct an OMAKESLICECOPY node.
-		// Components used in OMAKESCLICECOPY that are supplied by parsed source code
-		// have already been typechecked in OMAKE and OCOPY earlier.
-		ok |= ctxExpr
-
-		t := n.Type
-
-		if t == nil {
-			Fatalf("no type specified for OMAKESLICECOPY")
-		}
-
-		if !t.IsSlice() {
-			Fatalf("invalid type %v for OMAKESLICECOPY", n.Type)
-		}
-
-		if n.Left == nil {
-			Fatalf("missing len argument for OMAKESLICECOPY")
-		}
-
-		if n.Right == nil {
-			Fatalf("missing slice argument to copy for OMAKESLICECOPY")
-		}
-
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Right = typecheck(n.Right, ctxExpr)
-
-		n.Left = defaultlit(n.Left, types.Types[TINT])
-
-		if !n.Left.Type.IsInteger() && n.Type.Etype != TIDEAL {
-			yyerror("non-integer len argument in OMAKESLICECOPY")
-		}
-
-		if Isconst(n.Left, CTINT) {
-			if n.Left.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
-				Fatalf("len for OMAKESLICECOPY too large")
-			}
-			if n.Left.Int64Val() < 0 {
-				Fatalf("len for OMAKESLICECOPY must be non-negative")
-			}
-		}
-
-	case OSLICE, OSLICE3:
-		ok |= ctxExpr
-		n.Left = typecheck(n.Left, ctxExpr)
-		low, high, max := n.SliceBounds()
-		hasmax := n.Op.IsSlice3()
-		low = typecheck(low, ctxExpr)
-		high = typecheck(high, ctxExpr)
-		max = typecheck(max, ctxExpr)
-		n.Left = defaultlit(n.Left, nil)
-		low = indexlit(low)
-		high = indexlit(high)
-		max = indexlit(max)
-		n.SetSliceBounds(low, high, max)
-		l := n.Left
-		if l.Type == nil {
-			n.Type = nil
-			return n
-		}
-		if l.Type.IsArray() {
-			if !islvalue(n.Left) {
-				yyerror("invalid operation %v (slice of unaddressable value)", n)
-				n.Type = nil
-				return n
-			}
-
-			n.Left = nod(OADDR, n.Left, nil)
-			n.Left.SetImplicit(true)
-			n.Left = typecheck(n.Left, ctxExpr)
-			l = n.Left
-		}
-		t := l.Type
-		var tp *types.Type
-		if t.IsString() {
-			if hasmax {
-				yyerror("invalid operation %v (3-index slice of string)", n)
-				n.Type = nil
-				return n
-			}
-			n.Type = t
-			n.Op = OSLICESTR
-		} else if t.IsPtr() && t.Elem().IsArray() {
-			tp = t.Elem()
-			n.Type = types.NewSlice(tp.Elem())
-			dowidth(n.Type)
-			if hasmax {
-				n.Op = OSLICE3ARR
-			} else {
-				n.Op = OSLICEARR
-			}
-		} else if t.IsSlice() {
-			n.Type = t
-		} else {
-			yyerror("cannot slice %v (type %v)", l, t)
-			n.Type = nil
-			return n
-		}
-
-		if low != nil && !checksliceindex(l, low, tp) {
-			n.Type = nil
-			return n
-		}
-		if high != nil && !checksliceindex(l, high, tp) {
-			n.Type = nil
-			return n
-		}
-		if max != nil && !checksliceindex(l, max, tp) {
-			n.Type = nil
-			return n
-		}
-		if !checksliceconst(low, high) || !checksliceconst(low, max) || !checksliceconst(high, max) {
-			n.Type = nil
-			return n
-		}
-
-	// call and call like
-	case OCALL:
-		typecheckslice(n.Ninit.Slice(), ctxStmt) // imported rewritten f(g()) calls (#30907)
-		n.Left = typecheck(n.Left, ctxExpr|ctxType|ctxCallee)
-		if n.Left.Diag() {
-			n.SetDiag(true)
-		}
-
-		l := n.Left
-
-		if l.Op == ONAME && l.SubOp() != 0 {
-			if n.IsDDD() && l.SubOp() != OAPPEND {
-				yyerror("invalid use of ... with builtin %v", l)
-			}
-
-			// builtin: OLEN, OCAP, etc.
-			n.Op = l.SubOp()
-			n.Left = n.Right
-			n.Right = nil
-			n = typecheck1(n, top)
-			return n
-		}
-
-		n.Left = defaultlit(n.Left, nil)
-		l = n.Left
-		if l.Op == OTYPE {
-			if n.IsDDD() {
-				if !l.Type.Broke() {
-					yyerror("invalid use of ... in type conversion to %v", l.Type)
-				}
-				n.SetDiag(true)
-			}
-
-			// pick off before type-checking arguments
-			ok |= ctxExpr
-
-			// turn CALL(type, arg) into CONV(arg) w/ type
-			n.Left = nil
-
-			n.Op = OCONV
-			n.Type = l.Type
-			if !onearg(n, "conversion to %v", l.Type) {
-				n.Type = nil
-				return n
-			}
-			n = typecheck1(n, top)
-			return n
-		}
-
-		typecheckargs(n)
-		t := l.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-		checkwidth(t)
-
-		switch l.Op {
-		case ODOTINTER:
-			n.Op = OCALLINTER
-
-		case ODOTMETH:
-			n.Op = OCALLMETH
-
-			// typecheckaste was used here but there wasn't enough
-			// information further down the call chain to know if we
-			// were testing a method receiver for unexported fields.
-			// It isn't necessary, so just do a sanity check.
-			tp := t.Recv().Type
-
-			if l.Left == nil || !types.Identical(l.Left.Type, tp) {
-				Fatalf("method receiver")
-			}
-
-		default:
-			n.Op = OCALLFUNC
-			if t.Etype != TFUNC {
-				name := l.String()
-				if isBuiltinFuncName(name) && l.Name.Defn != nil {
-					// be more specific when the function
-					// name matches a predeclared function
-					yyerror("cannot call non-function %s (type %v), declared at %s",
-						name, t, linestr(l.Name.Defn.Pos))
-				} else {
-					yyerror("cannot call non-function %s (type %v)", name, t)
-				}
-				n.Type = nil
-				return n
-			}
-		}
-
-		typecheckaste(OCALL, n.Left, n.IsDDD(), t.Params(), n.List, func() string { return fmt.Sprintf("argument to %v", n.Left) })
-		ok |= ctxStmt
-		if t.NumResults() == 0 {
-			break
-		}
-		ok |= ctxExpr
-		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" {
-				// Emit code for runtime.getg() directly instead of calling function.
-				// Most such rewrites (for example the similar one for math.Sqrt) should be done in walk,
-				// so that the ordering pass can make sure to preserve the semantics of the original code
-				// (in particular, the exact time of the function call) by introducing temporaries.
-				// In this case, we know getg() always returns the same result within a given function
-				// and we want to avoid the temporaries, so we do the rewrite earlier than is typical.
-				n.Op = OGETG
-			}
-
-			break
-		}
-
-		// multiple return
-		if top&(ctxMultiOK|ctxStmt) == 0 {
-			yyerror("multiple-value %v() in single-value context", l)
-			break
-		}
-
-		n.Type = l.Type.Results()
-
-	case OALIGNOF, OOFFSETOF, OSIZEOF:
-		ok |= ctxExpr
-		if !onearg(n, "%v", n.Op) {
-			n.Type = nil
-			return n
-		}
-		n.Type = types.Types[TUINTPTR]
-
-	case OCAP, OLEN:
-		ok |= ctxExpr
-		if !onearg(n, "%v", n.Op) {
-			n.Type = nil
-			return n
-		}
-
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Left = defaultlit(n.Left, nil)
-		n.Left = implicitstar(n.Left)
-		l := n.Left
-		t := l.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-
-		var ok bool
-		if n.Op == OLEN {
-			ok = okforlen[t.Etype]
-		} else {
-			ok = okforcap[t.Etype]
-		}
-		if !ok {
-			yyerror("invalid argument %L for %v", l, n.Op)
-			n.Type = nil
-			return n
-		}
-
-		n.Type = types.Types[TINT]
-
-	case OREAL, OIMAG:
-		ok |= ctxExpr
-		if !onearg(n, "%v", n.Op) {
-			n.Type = nil
-			return n
-		}
-
-		n.Left = typecheck(n.Left, ctxExpr)
-		l := n.Left
-		t := l.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-
-		// Determine result type.
-		switch t.Etype {
-		case TIDEAL:
-			n.Type = types.UntypedFloat
-		case TCOMPLEX64:
-			n.Type = types.Types[TFLOAT32]
-		case TCOMPLEX128:
-			n.Type = types.Types[TFLOAT64]
-		default:
-			yyerror("invalid argument %L for %v", l, n.Op)
-			n.Type = nil
-			return n
-		}
-
-	case OCOMPLEX:
-		ok |= ctxExpr
-		typecheckargs(n)
-		if !twoarg(n) {
-			n.Type = nil
-			return n
-		}
-		l := n.Left
-		r := n.Right
-		if l.Type == nil || r.Type == nil {
-			n.Type = nil
-			return n
-		}
-		l, r = defaultlit2(l, r, false)
-		if l.Type == nil || r.Type == nil {
-			n.Type = nil
-			return n
-		}
-		n.Left = l
-		n.Right = r
-
-		if !types.Identical(l.Type, r.Type) {
-			yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type)
-			n.Type = nil
-			return n
-		}
-
-		var t *types.Type
-		switch l.Type.Etype {
-		default:
-			yyerror("invalid operation: %v (arguments have type %v, expected floating-point)", n, l.Type)
-			n.Type = nil
-			return n
-
-		case TIDEAL:
-			t = types.UntypedComplex
-
-		case TFLOAT32:
-			t = types.Types[TCOMPLEX64]
-
-		case TFLOAT64:
-			t = types.Types[TCOMPLEX128]
-		}
-		n.Type = t
-
-	case OCLOSE:
-		if !onearg(n, "%v", n.Op) {
-			n.Type = nil
-			return n
-		}
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Left = defaultlit(n.Left, nil)
-		l := n.Left
-		t := l.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-		if !t.IsChan() {
-			yyerror("invalid operation: %v (non-chan type %v)", n, t)
-			n.Type = nil
-			return n
-		}
-
-		if !t.ChanDir().CanSend() {
-			yyerror("invalid operation: %v (cannot close receive-only channel)", n)
-			n.Type = nil
-			return n
-		}
-
-		ok |= ctxStmt
-
-	case ODELETE:
-		ok |= ctxStmt
-		typecheckargs(n)
-		args := n.List
-		if args.Len() == 0 {
-			yyerror("missing arguments to delete")
-			n.Type = nil
-			return n
-		}
-
-		if args.Len() == 1 {
-			yyerror("missing second (key) argument to delete")
-			n.Type = nil
-			return n
-		}
-
-		if args.Len() != 2 {
-			yyerror("too many arguments to delete")
-			n.Type = nil
-			return n
-		}
-
-		l := args.First()
-		r := args.Second()
-		if l.Type != nil && !l.Type.IsMap() {
-			yyerror("first argument to delete must be map; have %L", l.Type)
-			n.Type = nil
-			return n
-		}
-
-		args.SetSecond(assignconv(r, l.Type.Key(), "delete"))
-
-	case OAPPEND:
-		ok |= ctxExpr
-		typecheckargs(n)
-		args := n.List
-		if args.Len() == 0 {
-			yyerror("missing arguments to append")
-			n.Type = nil
-			return n
-		}
-
-		t := args.First().Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-
-		n.Type = t
-		if !t.IsSlice() {
-			if Isconst(args.First(), CTNIL) {
-				yyerror("first argument to append must be typed slice; have untyped nil")
-				n.Type = nil
-				return n
-			}
-
-			yyerror("first argument to append must be slice; have %L", t)
-			n.Type = nil
-			return n
-		}
-
-		if n.IsDDD() {
-			if args.Len() == 1 {
-				yyerror("cannot use ... on first argument to append")
-				n.Type = nil
-				return n
-			}
-
-			if args.Len() != 2 {
-				yyerror("too many arguments to append")
-				n.Type = nil
-				return n
-			}
-
-			if t.Elem().IsKind(TUINT8) && args.Second().Type.IsString() {
-				args.SetSecond(defaultlit(args.Second(), types.Types[TSTRING]))
-				break
-			}
-
-			args.SetSecond(assignconv(args.Second(), t.Orig, "append"))
-			break
-		}
-
-		as := args.Slice()[1:]
-		for i, n := range as {
-			if n.Type == nil {
-				continue
-			}
-			as[i] = assignconv(n, t.Elem(), "append")
-			checkwidth(as[i].Type) // ensure width is calculated for backend
-		}
-
-	case OCOPY:
-		ok |= ctxStmt | ctxExpr
-		typecheckargs(n)
-		if !twoarg(n) {
-			n.Type = nil
-			return n
-		}
-		n.Type = types.Types[TINT]
-		if n.Left.Type == nil || n.Right.Type == nil {
-			n.Type = nil
-			return n
-		}
-		n.Left = defaultlit(n.Left, nil)
-		n.Right = defaultlit(n.Right, nil)
-		if n.Left.Type == nil || n.Right.Type == nil {
-			n.Type = nil
-			return n
-		}
-
-		// copy([]byte, string)
-		if n.Left.Type.IsSlice() && n.Right.Type.IsString() {
-			if types.Identical(n.Left.Type.Elem(), types.Bytetype) {
-				break
-			}
-			yyerror("arguments to copy have different element types: %L and string", n.Left.Type)
-			n.Type = nil
-			return n
-		}
-
-		if !n.Left.Type.IsSlice() || !n.Right.Type.IsSlice() {
-			if !n.Left.Type.IsSlice() && !n.Right.Type.IsSlice() {
-				yyerror("arguments to copy must be slices; have %L, %L", n.Left.Type, n.Right.Type)
-			} else if !n.Left.Type.IsSlice() {
-				yyerror("first argument to copy should be slice; have %L", n.Left.Type)
-			} else {
-				yyerror("second argument to copy should be slice or string; have %L", n.Right.Type)
-			}
-			n.Type = nil
-			return n
-		}
-
-		if !types.Identical(n.Left.Type.Elem(), n.Right.Type.Elem()) {
-			yyerror("arguments to copy have different element types: %L and %L", n.Left.Type, n.Right.Type)
-			n.Type = nil
-			return n
-		}
-
-	case OCONV:
-		ok |= ctxExpr
-		checkwidth(n.Type) // ensure width is calculated for backend
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Left = convlit1(n.Left, n.Type, true, nil)
-		t := n.Left.Type
-		if t == nil || n.Type == nil {
-			n.Type = nil
-			return n
-		}
-		var why string
-		n.Op, why = convertop(n.Left.Op == OLITERAL, t, n.Type)
-		if n.Op == OXXX {
-			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)
-			}
-			n.Op = OCONV
-			n.Type = nil
-			return n
-		}
-
-		switch n.Op {
-		case OCONVNOP:
-			if t.Etype == n.Type.Etype {
-				switch t.Etype {
-				case TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128:
-					// Floating point casts imply rounding and
-					// so the conversion must be kept.
-					n.Op = OCONV
-				}
-			}
-
-		// do not convert to []byte literal. See CL 125796.
-		// generated code and compiler memory footprint is better without it.
-		case OSTR2BYTES:
-			break
-
-		case OSTR2RUNES:
-			if n.Left.Op == OLITERAL {
-				n = stringtoruneslit(n)
-			}
-		}
-
-	case OMAKE:
-		ok |= ctxExpr
-		args := n.List.Slice()
-		if len(args) == 0 {
-			yyerror("missing argument to make")
-			n.Type = nil
-			return n
-		}
-
-		n.List.Set(nil)
-		l := args[0]
-		l = typecheck(l, ctxType)
-		t := l.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-
-		i := 1
-		switch t.Etype {
-		default:
-			yyerror("cannot make type %v", t)
-			n.Type = nil
-			return n
-
-		case TSLICE:
-			if i >= len(args) {
-				yyerror("missing len argument to make(%v)", t)
-				n.Type = nil
-				return n
-			}
-
-			l = args[i]
-			i++
-			l = typecheck(l, ctxExpr)
-			var r *Node
-			if i < len(args) {
-				r = args[i]
-				i++
-				r = typecheck(r, ctxExpr)
-			}
-
-			if l.Type == nil || (r != nil && r.Type == nil) {
-				n.Type = nil
-				return n
-			}
-			if !checkmake(t, "len", &l) || r != nil && !checkmake(t, "cap", &r) {
-				n.Type = nil
-				return n
-			}
-			if Isconst(l, CTINT) && r != nil && Isconst(r, CTINT) && l.Val().U.(*Mpint).Cmp(r.Val().U.(*Mpint)) > 0 {
-				yyerror("len larger than cap in make(%v)", t)
-				n.Type = nil
-				return n
-			}
-
-			n.Left = l
-			n.Right = r
-			n.Op = OMAKESLICE
-
-		case TMAP:
-			if i < len(args) {
-				l = args[i]
-				i++
-				l = typecheck(l, ctxExpr)
-				l = defaultlit(l, types.Types[TINT])
-				if l.Type == nil {
-					n.Type = nil
-					return n
-				}
-				if !checkmake(t, "size", &l) {
-					n.Type = nil
-					return n
-				}
-				n.Left = l
-			} else {
-				n.Left = nodintconst(0)
-			}
-			n.Op = OMAKEMAP
-
-		case TCHAN:
-			l = nil
-			if i < len(args) {
-				l = args[i]
-				i++
-				l = typecheck(l, ctxExpr)
-				l = defaultlit(l, types.Types[TINT])
-				if l.Type == nil {
-					n.Type = nil
-					return n
-				}
-				if !checkmake(t, "buffer", &l) {
-					n.Type = nil
-					return n
-				}
-				n.Left = l
-			} else {
-				n.Left = nodintconst(0)
-			}
-			n.Op = OMAKECHAN
-		}
-
-		if i < len(args) {
-			yyerror("too many arguments to make(%v)", t)
-			n.Op = OMAKE
-			n.Type = nil
-			return n
-		}
-
-		n.Type = t
-
-	case ONEW:
-		ok |= ctxExpr
-		args := n.List
-		if args.Len() == 0 {
-			yyerror("missing argument to new")
-			n.Type = nil
-			return n
-		}
-
-		l := args.First()
-		l = typecheck(l, ctxType)
-		t := l.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-		if args.Len() > 1 {
-			yyerror("too many arguments to new(%v)", t)
-			n.Type = nil
-			return n
-		}
-
-		n.Left = l
-		n.Type = types.NewPtr(t)
-
-	case OPRINT, OPRINTN:
-		ok |= ctxStmt
-		typecheckargs(n)
-		ls := n.List.Slice()
-		for i1, n1 := range ls {
-			// Special case for print: int constant is int64, not int.
-			if Isconst(n1, CTINT) {
-				ls[i1] = defaultlit(ls[i1], types.Types[TINT64])
-			} else {
-				ls[i1] = defaultlit(ls[i1], nil)
-			}
-		}
-
-	case OPANIC:
-		ok |= ctxStmt
-		if !onearg(n, "panic") {
-			n.Type = nil
-			return n
-		}
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Left = defaultlit(n.Left, types.Types[TINTER])
-		if n.Left.Type == nil {
-			n.Type = nil
-			return n
-		}
-
-	case ORECOVER:
-		ok |= ctxExpr | ctxStmt
-		if n.List.Len() != 0 {
-			yyerror("too many arguments to recover")
-			n.Type = nil
-			return n
-		}
-
-		n.Type = types.Types[TINTER]
-
-	case OCLOSURE:
-		ok |= ctxExpr
-		typecheckclosure(n, top)
-		if n.Type == nil {
-			return n
-		}
-
-	case OITAB:
-		ok |= ctxExpr
-		n.Left = typecheck(n.Left, ctxExpr)
-		t := n.Left.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-		if !t.IsInterface() {
-			Fatalf("OITAB of %v", t)
-		}
-		n.Type = types.NewPtr(types.Types[TUINTPTR])
-
-	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)
-
-	case OSPTR:
-		ok |= ctxExpr
-		n.Left = typecheck(n.Left, ctxExpr)
-		t := n.Left.Type
-		if t == nil {
-			n.Type = nil
-			return n
-		}
-		if !t.IsSlice() && !t.IsString() {
-			Fatalf("OSPTR of %v", t)
-		}
-		if t.IsString() {
-			n.Type = types.NewPtr(types.Types[TUINT8])
-		} else {
-			n.Type = types.NewPtr(t.Elem())
-		}
-
-	case OCLOSUREVAR:
-		ok |= ctxExpr
-
-	case OCFUNC:
-		ok |= ctxExpr
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Type = types.Types[TUINTPTR]
-
-	case OCONVNOP:
-		ok |= ctxExpr
-		n.Left = typecheck(n.Left, ctxExpr)
-
-	// statements
-	case OAS:
-		ok |= ctxStmt
-
-		typecheckas(n)
-
-		// Code that creates temps does not bother to set defn, so do it here.
-		if n.Left.Op == ONAME && n.Left.IsAutoTmp() {
-			n.Left.Name.Defn = n
-		}
-
-	case OAS2:
-		ok |= ctxStmt
-		typecheckas2(n)
-
-	case OBREAK,
-		OCONTINUE,
-		ODCL,
-		OEMPTY,
-		OGOTO,
-		OFALL,
-		OVARKILL,
-		OVARLIVE:
-		ok |= ctxStmt
-
-	case OLABEL:
-		ok |= ctxStmt
-		decldepth++
-		if n.Sym.IsBlank() {
-			// Empty identifier is valid but useless.
-			// Eliminate now to simplify life later.
-			// See issues 7538, 11589, 11593.
-			n.Op = OEMPTY
-			n.Left = nil
-		}
-
-	case ODEFER:
-		ok |= ctxStmt
-		n.Left = typecheck(n.Left, ctxStmt|ctxExpr)
-		if !n.Left.Diag() {
-			checkdefergo(n)
-		}
-
-	case OGO:
-		ok |= ctxStmt
-		n.Left = typecheck(n.Left, ctxStmt|ctxExpr)
-		checkdefergo(n)
-
-	case OFOR, OFORUNTIL:
-		ok |= ctxStmt
-		typecheckslice(n.Ninit.Slice(), ctxStmt)
-		decldepth++
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Left = defaultlit(n.Left, nil)
-		if n.Left != nil {
-			t := n.Left.Type
-			if t != nil && !t.IsBoolean() {
-				yyerror("non-bool %L used as for condition", n.Left)
-			}
-		}
-		n.Right = typecheck(n.Right, ctxStmt)
-		if n.Op == OFORUNTIL {
-			typecheckslice(n.List.Slice(), ctxStmt)
-		}
-		typecheckslice(n.Nbody.Slice(), ctxStmt)
-		decldepth--
-
-	case OIF:
-		ok |= ctxStmt
-		typecheckslice(n.Ninit.Slice(), ctxStmt)
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Left = defaultlit(n.Left, nil)
-		if n.Left != nil {
-			t := n.Left.Type
-			if t != nil && !t.IsBoolean() {
-				yyerror("non-bool %L used as if condition", n.Left)
-			}
-		}
-		typecheckslice(n.Nbody.Slice(), ctxStmt)
-		typecheckslice(n.Rlist.Slice(), ctxStmt)
-
-	case ORETURN:
-		ok |= ctxStmt
-		typecheckargs(n)
-		if Curfn == nil {
-			yyerror("return outside function")
-			n.Type = nil
-			return n
-		}
-
-		if Curfn.Type.FuncType().Outnamed && n.List.Len() == 0 {
-			break
-		}
-		typecheckaste(ORETURN, nil, false, Curfn.Type.Results(), n.List, func() string { return "return argument" })
-
-	case ORETJMP:
-		ok |= ctxStmt
-
-	case OSELECT:
-		ok |= ctxStmt
-		typecheckselect(n)
-
-	case OSWITCH:
-		ok |= ctxStmt
-		typecheckswitch(n)
-
-	case ORANGE:
-		ok |= ctxStmt
-		typecheckrange(n)
-
-	case OTYPESW:
-		yyerror("use of .(type) outside type switch")
-		n.Type = nil
-		return n
-
-	case ODCLFUNC:
-		ok |= ctxStmt
-		typecheckfunc(n)
-
-	case ODCLCONST:
-		ok |= ctxStmt
-		n.Left = typecheck(n.Left, ctxExpr)
-
-	case ODCLTYPE:
-		ok |= ctxStmt
-		n.Left = typecheck(n.Left, ctxType)
-		checkwidth(n.Left.Type)
-	}
-
-	t := n.Type
-	if t != nil && !t.IsFuncArgStruct() && n.Op != OTYPE {
-		switch t.Etype {
-		case TFUNC, // might have TANY; wait until it's called
-			TANY, TFORW, TIDEAL, TNIL, TBLANK:
-			break
-
-		default:
-			checkwidth(t)
-		}
-	}
-
-	evconst(n)
-	if n.Op == OTYPE && top&ctxType == 0 {
-		if !n.Type.Broke() {
-			yyerror("type %v is not an expression", n.Type)
-		}
-		n.Type = nil
-		return n
-	}
-
-	if top&(ctxExpr|ctxType) == ctxType && n.Op != OTYPE {
-		yyerror("%v is not a type", n)
-		n.Type = nil
-		return n
-	}
-
-	// TODO(rsc): simplify
-	if (top&(ctxCallee|ctxExpr|ctxType) != 0) && top&ctxStmt == 0 && ok&(ctxExpr|ctxType|ctxCallee) == 0 {
-		yyerror("%v used as value", n)
-		n.Type = nil
-		return n
-	}
-
-	if (top&ctxStmt != 0) && top&(ctxCallee|ctxExpr|ctxType) == 0 && ok&ctxStmt == 0 {
-		if !n.Diag() {
-			yyerror("%v evaluated but not used", n)
-			n.SetDiag(true)
-		}
-
-		n.Type = nil
-		return n
-	}
-
-	return n
-}
-
-func typecheckargs(n *Node) {
-	if n.List.Len() != 1 || n.IsDDD() {
-		typecheckslice(n.List.Slice(), ctxExpr)
-		return
-	}
-
-	typecheckslice(n.List.Slice(), ctxExpr|ctxMultiOK)
-	t := n.List.First().Type
-	if t == nil || !t.IsFuncArgStruct() {
-		return
-	}
-
-	// Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...).
-
-	// Save n as n.Orig for fmt.go.
-	if n.Orig == n {
-		n.Orig = n.sepcopy()
-	}
-
-	as := nod(OAS2, nil, nil)
-	as.Rlist.AppendNodes(&n.List)
-
-	// If we're outside of function context, then this call will
-	// be executed during the generated init function. However,
-	// init.go hasn't yet created it. Instead, associate the
-	// temporary variables with dummyInitFn for now, and init.go
-	// will reassociate them later when it's appropriate.
-	static := Curfn == nil
-	if static {
-		Curfn = dummyInitFn
-	}
-	for _, f := range t.FieldSlice() {
-		t := temp(f.Type)
-		as.Ninit.Append(nod(ODCL, t, nil))
-		as.List.Append(t)
-		n.List.Append(t)
-	}
-	if static {
-		Curfn = nil
-	}
-
-	as = typecheck(as, ctxStmt)
-	n.Ninit.Append(as)
-}
-
-func checksliceindex(l *Node, r *Node, tp *types.Type) bool {
-	t := r.Type
-	if t == nil {
-		return false
-	}
-	if !t.IsInteger() {
-		yyerror("invalid slice index %v (type %v)", r, t)
-		return false
-	}
-
-	if r.Op == OLITERAL {
-		if r.Int64Val() < 0 {
-			yyerror("invalid slice index %v (index must be non-negative)", r)
-			return false
-		} else if tp != nil && tp.NumElem() >= 0 && r.Int64Val() > tp.NumElem() {
-			yyerror("invalid slice index %v (out of bounds for %d-element array)", r, tp.NumElem())
-			return false
-		} else if Isconst(l, CTSTR) && r.Int64Val() > int64(len(l.StringVal())) {
-			yyerror("invalid slice index %v (out of bounds for %d-byte string)", r, len(l.StringVal()))
-			return false
-		} else if r.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
-			yyerror("invalid slice index %v (index too large)", r)
-			return false
-		}
-	}
-
-	return true
-}
-
-func checksliceconst(lo *Node, hi *Node) bool {
-	if lo != nil && hi != nil && lo.Op == OLITERAL && hi.Op == OLITERAL && lo.Val().U.(*Mpint).Cmp(hi.Val().U.(*Mpint)) > 0 {
-		yyerror("invalid slice index: %v > %v", lo, hi)
-		return false
-	}
-
-	return true
-}
-
-func checkdefergo(n *Node) {
-	what := "defer"
-	if n.Op == OGO {
-		what = "go"
-	}
-
-	switch n.Left.Op {
-	// ok
-	case OCALLINTER,
-		OCALLMETH,
-		OCALLFUNC,
-		OCLOSE,
-		OCOPY,
-		ODELETE,
-		OPANIC,
-		OPRINT,
-		OPRINTN,
-		ORECOVER:
-		return
-
-	case OAPPEND,
-		OCAP,
-		OCOMPLEX,
-		OIMAG,
-		OLEN,
-		OMAKE,
-		OMAKESLICE,
-		OMAKECHAN,
-		OMAKEMAP,
-		ONEW,
-		OREAL,
-		OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
-		if n.Left.Orig != nil && n.Left.Orig.Op == OCONV {
-			break
-		}
-		yyerrorl(n.Pos, "%s discards result of %v", what, n.Left)
-		return
-	}
-
-	// type is broken or missing, most likely a method call on a broken type
-	// we will warn about the broken type elsewhere. no need to emit a potentially confusing error
-	if n.Left.Type == nil || n.Left.Type.Broke() {
-		return
-	}
-
-	if !n.Diag() {
-		// The syntax made sure it was a call, so this must be
-		// a conversion.
-		n.SetDiag(true)
-		yyerrorl(n.Pos, "%s requires function call, not conversion", what)
-	}
-}
-
-// The result of implicitstar MUST be assigned back to n, e.g.
-// 	n.Left = implicitstar(n.Left)
-func implicitstar(n *Node) *Node {
-	// insert implicit * if needed for fixed array
-	t := n.Type
-	if t == nil || !t.IsPtr() {
-		return n
-	}
-	t = t.Elem()
-	if t == nil {
-		return n
-	}
-	if !t.IsArray() {
-		return n
-	}
-	n = nod(ODEREF, n, nil)
-	n.SetImplicit(true)
-	n = typecheck(n, ctxExpr)
-	return n
-}
-
-func onearg(n *Node, f string, args ...interface{}) bool {
-	if n.Left != nil {
-		return true
-	}
-	if n.List.Len() == 0 {
-		p := fmt.Sprintf(f, args...)
-		yyerror("missing argument to %s: %v", p, n)
-		return false
-	}
-
-	if n.List.Len() > 1 {
-		p := fmt.Sprintf(f, args...)
-		yyerror("too many arguments to %s: %v", p, n)
-		n.Left = n.List.First()
-		n.List.Set(nil)
-		return false
-	}
-
-	n.Left = n.List.First()
-	n.List.Set(nil)
-	return true
-}
-
-func twoarg(n *Node) bool {
-	if n.Left != nil {
-		return true
-	}
-	if n.List.Len() != 2 {
-		if n.List.Len() < 2 {
-			yyerror("not enough arguments in call to %v", n)
-		} else {
-			yyerror("too many arguments in call to %v", n)
-		}
-		return false
-	}
-	n.Left = n.List.First()
-	n.Right = n.List.Second()
-	n.List.Set(nil)
-	return true
-}
-
-func lookdot1(errnode *Node, s *types.Sym, t *types.Type, fs *types.Fields, dostrcmp int) *types.Field {
-	var r *types.Field
-	for _, f := range fs.Slice() {
-		if dostrcmp != 0 && f.Sym.Name == s.Name {
-			return f
-		}
-		if dostrcmp == 2 && strings.EqualFold(f.Sym.Name, s.Name) {
-			return f
-		}
-		if f.Sym != s {
-			continue
-		}
-		if r != nil {
-			if errnode != nil {
-				yyerror("ambiguous selector %v", errnode)
-			} else if t.IsPtr() {
-				yyerror("ambiguous selector (%v).%v", t, s)
-			} else {
-				yyerror("ambiguous selector %v.%v", t, s)
-			}
-			break
-		}
-
-		r = f
-	}
-
-	return r
-}
-
-// typecheckMethodExpr checks selector expressions (ODOT) where the
-// base expression is a type expression (OTYPE).
-func typecheckMethodExpr(n *Node) (res *Node) {
-	if enableTrace && trace {
-		defer tracePrint("typecheckMethodExpr", n)(&res)
-	}
-
-	t := n.Left.Type
-
-	// Compute the method set for t.
-	var ms *types.Fields
-	if t.IsInterface() {
-		ms = t.Fields()
-	} else {
-		mt := methtype(t)
-		if mt == nil {
-			yyerror("%v undefined (type %v has no method %v)", n, t, n.Sym)
-			n.Type = nil
-			return n
-		}
-		expandmeth(mt)
-		ms = mt.AllMethods()
-
-		// The method expression T.m requires a wrapper when T
-		// is different from m's declared receiver type. We
-		// normally generate these wrappers while writing out
-		// runtime type descriptors, which is always done for
-		// types declared at package scope. However, we need
-		// to make sure to generate wrappers for anonymous
-		// receiver types too.
-		if mt.Sym == nil {
-			addsignat(t)
-		}
-	}
-
-	s := n.Sym
-	m := lookdot1(n, s, t, ms, 0)
-	if m == nil {
-		if lookdot1(n, s, t, ms, 1) != nil {
-			yyerror("%v undefined (cannot refer to unexported method %v)", n, s)
-		} else if _, ambig := dotpath(s, t, nil, false); ambig {
-			yyerror("%v undefined (ambiguous selector)", n) // method or field
-		} else {
-			yyerror("%v undefined (type %v has no method %v)", n, t, s)
-		}
-		n.Type = nil
-		return n
-	}
-
-	if !isMethodApplicable(t, m) {
-		yyerror("invalid method expression %v (needs pointer receiver: (*%v).%S)", n, t, s)
-		n.Type = nil
-		return n
-	}
-
-	n.Op = ONAME
-	if n.Name == nil {
-		n.Name = new(Name)
-	}
-	n.Right = newname(n.Sym)
-	n.Sym = methodSym(t, n.Sym)
-	n.Type = methodfunc(m.Type, n.Left.Type)
-	n.Xoffset = 0
-	n.SetClass(PFUNC)
-	// methodSym already marked n.Sym as a function.
-
-	// Issue 25065. Make sure that we emit the symbol for a local method.
-	if Ctxt.Flag_dynlink && !inimport && (t.Sym == nil || t.Sym.Pkg == localpkg) {
-		makefuncsym(n.Sym)
-	}
-
-	return n
-}
-
-// isMethodApplicable reports whether method m can be called on a
-// value of type t. This is necessary because we compute a single
-// method set for both T and *T, but some *T methods are not
-// applicable to T receivers.
-func isMethodApplicable(t *types.Type, m *types.Field) bool {
-	return t.IsPtr() || !m.Type.Recv().Type.IsPtr() || isifacemethod(m.Type) || m.Embedded == 2
-}
-
-func derefall(t *types.Type) *types.Type {
-	for t != nil && t.IsPtr() {
-		t = t.Elem()
-	}
-	return t
-}
-
-func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field {
-	s := n.Sym
-
-	dowidth(t)
-	var f1 *types.Field
-	if t.IsStruct() || t.IsInterface() {
-		f1 = lookdot1(n, s, t, t.Fields(), dostrcmp)
-	}
-
-	var f2 *types.Field
-	if n.Left.Type == t || n.Left.Type.Sym == nil {
-		mt := methtype(t)
-		if mt != nil {
-			f2 = lookdot1(n, s, mt, mt.Methods(), dostrcmp)
-		}
-	}
-
-	if f1 != nil {
-		if dostrcmp > 1 || f1.Broke() {
-			// Already in the process of diagnosing an error.
-			return f1
-		}
-		if f2 != nil {
-			yyerror("%v is both field and method", n.Sym)
-		}
-		if f1.Offset == BADWIDTH {
-			Fatalf("lookdot badwidth %v %p", f1, f1)
-		}
-		n.Xoffset = f1.Offset
-		n.Type = f1.Type
-		if t.IsInterface() {
-			if n.Left.Type.IsPtr() {
-				n.Left = nod(ODEREF, n.Left, nil) // implicitstar
-				n.Left.SetImplicit(true)
-				n.Left = typecheck(n.Left, ctxExpr)
-			}
-
-			n.Op = ODOTINTER
-		} else {
-			n.SetOpt(f1)
-		}
-
-		return f1
-	}
-
-	if f2 != nil {
-		if dostrcmp > 1 {
-			// Already in the process of diagnosing an error.
-			return f2
-		}
-		tt := n.Left.Type
-		dowidth(tt)
-		rcvr := f2.Type.Recv().Type
-		if !types.Identical(rcvr, tt) {
-			if rcvr.IsPtr() && types.Identical(rcvr.Elem(), tt) {
-				checklvalue(n.Left, "call pointer method on")
-				n.Left = nod(OADDR, n.Left, nil)
-				n.Left.SetImplicit(true)
-				n.Left = typecheck(n.Left, ctxType|ctxExpr)
-			} else if tt.IsPtr() && (!rcvr.IsPtr() || rcvr.IsPtr() && rcvr.Elem().NotInHeap()) && types.Identical(tt.Elem(), rcvr) {
-				n.Left = nod(ODEREF, n.Left, nil)
-				n.Left.SetImplicit(true)
-				n.Left = typecheck(n.Left, ctxType|ctxExpr)
-			} else if tt.IsPtr() && tt.Elem().IsPtr() && types.Identical(derefall(tt), derefall(rcvr)) {
-				yyerror("calling method %v with receiver %L requires explicit dereference", n.Sym, n.Left)
-				for tt.IsPtr() {
-					// Stop one level early for method with pointer receiver.
-					if rcvr.IsPtr() && !tt.Elem().IsPtr() {
-						break
-					}
-					n.Left = nod(ODEREF, n.Left, nil)
-					n.Left.SetImplicit(true)
-					n.Left = typecheck(n.Left, ctxType|ctxExpr)
-					tt = tt.Elem()
-				}
-			} else {
-				Fatalf("method mismatch: %v for %v", rcvr, tt)
-			}
-		}
-
-		pll := n
-		ll := n.Left
-		for ll.Left != nil && (ll.Op == ODOT || ll.Op == ODOTPTR || ll.Op == ODEREF) {
-			pll = ll
-			ll = ll.Left
-		}
-		if pll.Implicit() && ll.Type.IsPtr() && ll.Type.Sym != nil && asNode(ll.Type.Sym.Def) != nil && asNode(ll.Type.Sym.Def).Op == OTYPE {
-			// It is invalid to automatically dereference a named pointer type when selecting a method.
-			// Make n.Left == ll to clarify error message.
-			n.Left = ll
-			return nil
-		}
-
-		n.Sym = methodSym(n.Left.Type, f2.Sym)
-		n.Xoffset = f2.Offset
-		n.Type = f2.Type
-		n.Op = ODOTMETH
-
-		return f2
-	}
-
-	return nil
-}
-
-func nokeys(l Nodes) bool {
-	for _, n := range l.Slice() {
-		if n.Op == OKEY || n.Op == OSTRUCTKEY {
-			return false
-		}
-	}
-	return true
-}
-
-func hasddd(t *types.Type) bool {
-	for _, tl := range t.Fields().Slice() {
-		if tl.IsDDD() {
-			return true
-		}
-	}
-
-	return false
-}
-
-// 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 i int
-
-	lno := lineno
-	defer func() { lineno = lno }()
-
-	if tstruct.Broke() {
-		return
-	}
-
-	var n *Node
-	if nl.Len() == 1 {
-		n = nl.First()
-	}
-
-	n1 := tstruct.NumFields()
-	n2 := nl.Len()
-	if !hasddd(tstruct) {
-		if n2 > n1 {
-			goto toomany
-		}
-		if n2 < n1 {
-			goto notenough
-		}
-	} else {
-		if !isddd {
-			if n2 < n1-1 {
-				goto notenough
-			}
-		} else {
-			if n2 > n1 {
-				goto toomany
-			}
-			if n2 < n1 {
-				goto notenough
-			}
-		}
-	}
-
-	i = 0
-	for _, tl := range tstruct.Fields().Slice() {
-		t = tl.Type
-		if tl.IsDDD() {
-			if isddd {
-				if i >= nl.Len() {
-					goto notenough
-				}
-				if nl.Len()-i > 1 {
-					goto toomany
-				}
-				n = nl.Index(i)
-				setlineno(n)
-				if n.Type != nil {
-					nl.SetIndex(i, assignconvfn(n, t, desc))
-				}
-				return
-			}
-
-			// TODO(mdempsky): Make into ... call with implicit slice.
-			for ; i < nl.Len(); i++ {
-				n = nl.Index(i)
-				setlineno(n)
-				if n.Type != nil {
-					nl.SetIndex(i, assignconvfn(n, t.Elem(), desc))
-				}
-			}
-			return
-		}
-
-		if i >= nl.Len() {
-			goto notenough
-		}
-		n = nl.Index(i)
-		setlineno(n)
-		if n.Type != nil {
-			nl.SetIndex(i, assignconvfn(n, t, desc))
-		}
-		i++
-	}
-
-	if i < nl.Len() {
-		goto toomany
-	}
-	if isddd {
-		if call != nil {
-			yyerror("invalid use of ... in call to %v", call)
-		} else {
-			yyerror("invalid use of ... in %v", op)
-		}
-	}
-	return
-
-notenough:
-	if n == nil || (!n.Diag() && n.Type != nil) {
-		details := errorDetails(nl, tstruct, isddd)
-		if call != nil {
-			// 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.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)
-			}
-		} else {
-			yyerror("not enough arguments to %v%s", op, details)
-		}
-		if n != nil {
-			n.SetDiag(true)
-		}
-	}
-	return
-
-toomany:
-	details := errorDetails(nl, tstruct, isddd)
-	if call != nil {
-		yyerror("too many arguments in call to %v%s", call, details)
-	} else {
-		yyerror("too many arguments to %v%s", op, details)
-	}
-}
-
-func errorDetails(nl Nodes, tstruct *types.Type, isddd bool) string {
-	// If we don't know any type at a call site, let's suppress any return
-	// message signatures. See Issue https://golang.org/issues/19012.
-	if tstruct == nil {
-		return ""
-	}
-	// If any node has an unknown type, suppress it as well
-	for _, n := range nl.Slice() {
-		if n.Type == nil {
-			return ""
-		}
-	}
-	return fmt.Sprintf("\n\thave %s\n\twant %v", nl.sigerr(isddd), tstruct)
-}
-
-// sigrepr is a type's representation to the outside world,
-// in string representations of return signatures
-// e.g in error messages about wrong arguments to return.
-func sigrepr(t *types.Type, isddd bool) string {
-	switch t {
-	case types.UntypedString:
-		return "string"
-	case types.UntypedBool:
-		return "bool"
-	}
-
-	if t.Etype == TIDEAL {
-		// "untyped number" is not commonly used
-		// outside of the compiler, so let's use "number".
-		// TODO(mdempsky): Revisit this.
-		return "number"
-	}
-
-	// Turn []T... argument to ...T for clearer error message.
-	if isddd {
-		if !t.IsSlice() {
-			Fatalf("bad type for ... argument: %v", t)
-		}
-		return "..." + t.Elem().String()
-	}
-	return t.String()
-}
-
-// sigerr returns the signature of the types at the call or return.
-func (nl Nodes) sigerr(isddd bool) string {
-	if nl.Len() < 1 {
-		return "()"
-	}
-
-	var typeStrings []string
-	for i, n := range nl.Slice() {
-		isdddArg := isddd && i == nl.Len()-1
-		typeStrings = append(typeStrings, sigrepr(n.Type, isdddArg))
-	}
-
-	return fmt.Sprintf("(%s)", strings.Join(typeStrings, ", "))
-}
-
-// type check composite
-func fielddup(name string, hash map[string]bool) {
-	if hash[name] {
-		yyerror("duplicate field name in struct literal: %s", name)
-		return
-	}
-	hash[name] = true
-}
-
-// iscomptype reports whether type t is a composite literal type.
-func iscomptype(t *types.Type) bool {
-	switch t.Etype {
-	case TARRAY, TSLICE, TSTRUCT, TMAP:
-		return true
-	default:
-		return false
-	}
-}
-
-// pushtype adds elided type information for composite literals if
-// appropriate, and returns the resulting expression.
-func pushtype(n *Node, t *types.Type) *Node {
-	if n == nil || n.Op != OCOMPLIT || n.Right != nil {
-		return n
-	}
-
-	switch {
-	case iscomptype(t):
-		// For T, return T{...}.
-		n.Right = typenod(t)
-
-	case t.IsPtr() && iscomptype(t.Elem()):
-		// For *T, return &T{...}.
-		n.Right = typenod(t.Elem())
-
-		n = nodl(n.Pos, OADDR, n, nil)
-		n.SetImplicit(true)
-	}
-
-	return n
-}
-
-// The result of typecheckcomplit MUST be assigned back to n, e.g.
-// 	n.Left = typecheckcomplit(n.Left)
-func typecheckcomplit(n *Node) (res *Node) {
-	if enableTrace && trace {
-		defer tracePrint("typecheckcomplit", n)(&res)
-	}
-
-	lno := lineno
-	defer func() {
-		lineno = lno
-	}()
-
-	if n.Right == nil {
-		yyerrorl(n.Pos, "missing type in composite literal")
-		n.Type = nil
-		return n
-	}
-
-	// Save original node (including n.Right)
-	n.Orig = n.copy()
-
-	setlineno(n.Right)
-
-	// Need to handle [...]T arrays specially.
-	if n.Right.Op == OTARRAY && n.Right.Left != nil && n.Right.Left.Op == ODDD {
-		n.Right.Right = typecheck(n.Right.Right, ctxType)
-		if n.Right.Right.Type == nil {
-			n.Type = nil
-			return n
-		}
-		elemType := n.Right.Right.Type
-
-		length := typecheckarraylit(elemType, -1, n.List.Slice(), "array literal")
-
-		n.Op = OARRAYLIT
-		n.Type = types.NewArray(elemType, length)
-		n.Right = nil
-		return n
-	}
-
-	n.Right = typecheck(n.Right, ctxType)
-	t := n.Right.Type
-	if t == nil {
-		n.Type = nil
-		return n
-	}
-	n.Type = t
-
-	switch t.Etype {
-	default:
-		yyerror("invalid composite literal type %v", t)
-		n.Type = nil
-
-	case TARRAY:
-		typecheckarraylit(t.Elem(), t.NumElem(), n.List.Slice(), "array literal")
-		n.Op = OARRAYLIT
-		n.Right = nil
-
-	case TSLICE:
-		length := typecheckarraylit(t.Elem(), -1, n.List.Slice(), "slice literal")
-		n.Op = OSLICELIT
-		n.Right = nodintconst(length)
-
-	case TMAP:
-		var cs constSet
-		for i3, l := range n.List.Slice() {
-			setlineno(l)
-			if l.Op != OKEY {
-				n.List.SetIndex(i3, typecheck(l, ctxExpr))
-				yyerror("missing key in map literal")
-				continue
-			}
-
-			r := l.Left
-			r = pushtype(r, t.Key())
-			r = typecheck(r, ctxExpr)
-			l.Left = assignconv(r, t.Key(), "map key")
-			cs.add(lineno, l.Left, "key", "map literal")
-
-			r = l.Right
-			r = pushtype(r, t.Elem())
-			r = typecheck(r, ctxExpr)
-			l.Right = assignconv(r, t.Elem(), "map value")
-		}
-
-		n.Op = OMAPLIT
-		n.Right = nil
-
-	case TSTRUCT:
-		// Need valid field offsets for Xoffset below.
-		dowidth(t)
-
-		errored := false
-		if n.List.Len() != 0 && nokeys(n.List) {
-			// simple list of variables
-			ls := n.List.Slice()
-			for i, n1 := range ls {
-				setlineno(n1)
-				n1 = typecheck(n1, ctxExpr)
-				ls[i] = n1
-				if i >= t.NumFields() {
-					if !errored {
-						yyerror("too many values in %v", n)
-						errored = true
-					}
-					continue
-				}
-
-				f := t.Field(i)
-				s := f.Sym
-				if s != nil && !types.IsExported(s.Name) && s.Pkg != localpkg {
-					yyerror("implicit assignment of unexported field '%s' in %v literal", s.Name, t)
-				}
-				// No pushtype allowed here. Must name fields for that.
-				n1 = assignconv(n1, f.Type, "field value")
-				n1 = nodSym(OSTRUCTKEY, n1, f.Sym)
-				n1.Xoffset = f.Offset
-				ls[i] = n1
-			}
-			if len(ls) < t.NumFields() {
-				yyerror("too few values in %v", n)
-			}
-		} else {
-			hash := make(map[string]bool)
-
-			// keyed list
-			ls := n.List.Slice()
-			for i, l := range ls {
-				setlineno(l)
-
-				if l.Op == OKEY {
-					key := l.Left
-
-					l.Op = OSTRUCTKEY
-					l.Left = l.Right
-					l.Right = nil
-
-					// An OXDOT uses the Sym field to hold
-					// the field to the right of the dot,
-					// so s will be non-nil, but an OXDOT
-					// is never a valid struct literal key.
-					if key.Sym == nil || key.Op == OXDOT || key.Sym.IsBlank() {
-						yyerror("invalid field name %v in struct initializer", key)
-						l.Left = typecheck(l.Left, ctxExpr)
-						continue
-					}
-
-					// Sym might have resolved to name in other top-level
-					// package, because of import dot. Redirect to correct sym
-					// before we do the lookup.
-					s := key.Sym
-					if s.Pkg != localpkg && types.IsExported(s.Name) {
-						s1 := lookup(s.Name)
-						if s1.Origpkg == s.Pkg {
-							s = s1
-						}
-					}
-					l.Sym = s
-				}
-
-				if l.Op != OSTRUCTKEY {
-					if !errored {
-						yyerror("mixture of field:value and value initializers")
-						errored = true
-					}
-					ls[i] = typecheck(ls[i], ctxExpr)
-					continue
-				}
-
-				f := lookdot1(nil, l.Sym, t, t.Fields(), 0)
-				if f == nil {
-					if ci := lookdot1(nil, l.Sym, t, t.Fields(), 2); ci != nil { // Case-insensitive lookup.
-						if visible(ci.Sym) {
-							yyerror("unknown field '%v' in struct literal of type %v (but does have %v)", l.Sym, t, ci.Sym)
-						} else if nonexported(l.Sym) && l.Sym.Name == ci.Sym.Name { // Ensure exactness before the suggestion.
-							yyerror("cannot refer to unexported field '%v' in struct literal of type %v", l.Sym, t)
-						} else {
-							yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t)
-						}
-						continue
-					}
-					var f *types.Field
-					p, _ := dotpath(l.Sym, t, &f, true)
-					if p == nil || f.IsMethod() {
-						yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t)
-						continue
-					}
-					// dotpath returns the parent embedded types in reverse order.
-					var ep []string
-					for ei := len(p) - 1; ei >= 0; ei-- {
-						ep = append(ep, p[ei].field.Sym.Name)
-					}
-					ep = append(ep, l.Sym.Name)
-					yyerror("cannot use promoted field %v in struct literal of type %v", strings.Join(ep, "."), t)
-					continue
-				}
-				fielddup(f.Sym.Name, hash)
-				l.Xoffset = f.Offset
-
-				// No pushtype allowed here. Tried and rejected.
-				l.Left = typecheck(l.Left, ctxExpr)
-				l.Left = assignconv(l.Left, f.Type, "field value")
-			}
-		}
-
-		n.Op = OSTRUCTLIT
-		n.Right = nil
-	}
-
-	return n
-}
-
-// typecheckarraylit type-checks a sequence of slice/array literal elements.
-func typecheckarraylit(elemType *types.Type, bound int64, elts []*Node, ctx string) int64 {
-	// If there are key/value pairs, create a map to keep seen
-	// keys so we can check for duplicate indices.
-	var indices map[int64]bool
-	for _, elt := range elts {
-		if elt.Op == OKEY {
-			indices = make(map[int64]bool)
-			break
-		}
-	}
-
-	var key, length int64
-	for i, elt := range elts {
-		setlineno(elt)
-		vp := &elts[i]
-		if elt.Op == OKEY {
-			elt.Left = typecheck(elt.Left, ctxExpr)
-			key = indexconst(elt.Left)
-			if key < 0 {
-				if !elt.Left.Diag() {
-					if key == -2 {
-						yyerror("index too large")
-					} else {
-						yyerror("index must be non-negative integer constant")
-					}
-					elt.Left.SetDiag(true)
-				}
-				key = -(1 << 30) // stay negative for a while
-			}
-			vp = &elt.Right
-		}
-
-		r := *vp
-		r = pushtype(r, elemType)
-		r = typecheck(r, ctxExpr)
-		*vp = assignconv(r, elemType, ctx)
-
-		if key >= 0 {
-			if indices != nil {
-				if indices[key] {
-					yyerror("duplicate index in %s: %d", ctx, key)
-				} else {
-					indices[key] = true
-				}
-			}
-
-			if bound >= 0 && key >= bound {
-				yyerror("array index %d out of bounds [0:%d]", key, bound)
-				bound = -1
-			}
-		}
-
-		key++
-		if key > length {
-			length = key
-		}
-	}
-
-	return length
-}
-
-// visible reports whether sym is exported or locally defined.
-func visible(sym *types.Sym) bool {
-	return sym != nil && (types.IsExported(sym.Name) || sym.Pkg == localpkg)
-}
-
-// nonexported reports whether sym is an unexported field.
-func nonexported(sym *types.Sym) bool {
-	return sym != nil && !types.IsExported(sym.Name)
-}
-
-// lvalue etc
-func islvalue(n *Node) bool {
-	switch n.Op {
-	case OINDEX:
-		if n.Left.Type != nil && n.Left.Type.IsArray() {
-			return islvalue(n.Left)
-		}
-		if n.Left.Type != nil && n.Left.Type.IsString() {
-			return false
-		}
-		fallthrough
-	case ODEREF, ODOTPTR, OCLOSUREVAR:
-		return true
-
-	case ODOT:
-		return islvalue(n.Left)
-
-	case ONAME:
-		if n.Class() == PFUNC {
-			return false
-		}
-		return true
-	}
-
-	return false
-}
-
-func checklvalue(n *Node, verb string) {
-	if !islvalue(n) {
-		yyerror("cannot %s %v", verb, n)
-	}
-}
-
-func checkassign(stmt *Node, n *Node) {
-	// Variables declared in ORANGE are assigned on every iteration.
-	if n.Name == nil || n.Name.Defn != stmt || stmt.Op == ORANGE {
-		r := outervalue(n)
-		if r.Op == ONAME {
-			r.Name.SetAssigned(true)
-			if r.Name.IsClosureVar() {
-				r.Name.Defn.Name.SetAssigned(true)
-			}
-		}
-	}
-
-	if islvalue(n) {
-		return
-	}
-	if n.Op == OINDEXMAP {
-		n.SetIndexMapLValue(true)
-		return
-	}
-
-	// have already complained about n being invalid
-	if n.Type == nil {
-		return
-	}
-
-	switch {
-	case n.Op == ODOT && n.Left.Op == OINDEXMAP:
-		yyerror("cannot assign to struct field %v in map", n)
-	case (n.Op == OINDEX && n.Left.Type.IsString()) || n.Op == OSLICESTR:
-		yyerror("cannot assign to %v (strings are immutable)", n)
-	case n.Op == OLITERAL && n.Sym != nil && n.isGoConst():
-		yyerror("cannot assign to %v (declared const)", n)
-	default:
-		yyerror("cannot assign to %v", n)
-	}
-	n.Type = nil
-}
-
-func checkassignlist(stmt *Node, l Nodes) {
-	for _, n := range l.Slice() {
-		checkassign(stmt, n)
-	}
-}
-
-// samesafeexpr checks whether it is safe to reuse one of l and r
-// instead of computing both. samesafeexpr assumes that l and r are
-// used in the same statement or expression. In order for it to be
-// safe to reuse l or r, they must:
-// * be the same expression
-// * not have side-effects (no function calls, no channel ops);
-//   however, panics are ok
-// * not cause inappropriate aliasing; e.g. two string to []byte
-//   conversions, must result in two distinct slices
-//
-// The handling of OINDEXMAP is subtle. OINDEXMAP can occur both
-// as an lvalue (map assignment) and an rvalue (map access). This is
-// currently OK, since the only place samesafeexpr gets used on an
-// lvalue expression is for OSLICE and OAPPEND optimizations, and it
-// is correct in those settings.
-func samesafeexpr(l *Node, r *Node) bool {
-	if l.Op != r.Op || !types.Identical(l.Type, r.Type) {
-		return false
-	}
-
-	switch l.Op {
-	case ONAME, OCLOSUREVAR:
-		return l == r
-
-	case ODOT, ODOTPTR:
-		return l.Sym != nil && r.Sym != nil && l.Sym == r.Sym && samesafeexpr(l.Left, r.Left)
-
-	case ODEREF, OCONVNOP,
-		ONOT, OBITNOT, OPLUS, ONEG:
-		return samesafeexpr(l.Left, r.Left)
-
-	case OCONV:
-		// Some conversions can't be reused, such as []byte(str).
-		// Allow only numeric-ish types. This is a bit conservative.
-		return issimple[l.Type.Etype] && samesafeexpr(l.Left, r.Left)
-
-	case OINDEX, OINDEXMAP,
-		OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
-		return samesafeexpr(l.Left, r.Left) && samesafeexpr(l.Right, r.Right)
-
-	case OLITERAL:
-		return eqval(l.Val(), r.Val())
-	}
-
-	return false
-}
-
-// type check assignment.
-// if this assignment is the definition of a var on the left side,
-// fill in the var's type.
-func typecheckas(n *Node) {
-	if enableTrace && trace {
-		defer tracePrint("typecheckas", n)(nil)
-	}
-
-	// delicate little dance.
-	// the definition of n may refer to this assignment
-	// as its definition, in which case it will call typecheckas.
-	// in that case, do not call typecheck back, or it will cycle.
-	// if the variable has a type (ntype) then typechecking
-	// will not look at defn, so it is okay (and desirable,
-	// so that the conversion below happens).
-	n.Left = resolve(n.Left)
-
-	if n.Left.Name == nil || n.Left.Name.Defn != n || n.Left.Name.Param.Ntype != nil {
-		n.Left = typecheck(n.Left, ctxExpr|ctxAssign)
-	}
-
-	// Use ctxMultiOK so we can emit an "N variables but M values" error
-	// to be consistent with typecheckas2 (#26616).
-	n.Right = typecheck(n.Right, ctxExpr|ctxMultiOK)
-	checkassign(n, n.Left)
-	if n.Right != nil && n.Right.Type != nil {
-		if n.Right.Type.IsFuncArgStruct() {
-			yyerror("assignment mismatch: 1 variable but %v returns %d values", n.Right.Left, n.Right.Type.NumFields())
-			// Multi-value RHS isn't actually valid for OAS; nil out
-			// to indicate failed typechecking.
-			n.Right.Type = nil
-		} else if n.Left.Type != nil {
-			n.Right = assignconv(n.Right, n.Left.Type, "assignment")
-		}
-	}
-
-	if n.Left.Name != nil && n.Left.Name.Defn == n && n.Left.Name.Param.Ntype == nil {
-		n.Right = defaultlit(n.Right, nil)
-		n.Left.Type = n.Right.Type
-	}
-
-	// second half of dance.
-	// now that right is done, typecheck the left
-	// just to get it over with.  see dance above.
-	n.SetTypecheck(1)
-
-	if n.Left.Typecheck() == 0 {
-		n.Left = typecheck(n.Left, ctxExpr|ctxAssign)
-	}
-	if !n.Left.isBlank() {
-		checkwidth(n.Left.Type) // ensure width is calculated for backend
-	}
-}
-
-func checkassignto(src *types.Type, dst *Node) {
-	if op, why := assignop(src, dst.Type); op == OXXX {
-		yyerror("cannot assign %v to %L in multiple assignment%s", src, dst, why)
-		return
-	}
-}
-
-func typecheckas2(n *Node) {
-	if enableTrace && trace {
-		defer tracePrint("typecheckas2", n)(nil)
-	}
-
-	ls := n.List.Slice()
-	for i1, n1 := range ls {
-		// delicate little dance.
-		n1 = resolve(n1)
-		ls[i1] = n1
-
-		if n1.Name == nil || n1.Name.Defn != n || n1.Name.Param.Ntype != nil {
-			ls[i1] = typecheck(ls[i1], ctxExpr|ctxAssign)
-		}
-	}
-
-	cl := n.List.Len()
-	cr := n.Rlist.Len()
-	if cl > 1 && cr == 1 {
-		n.Rlist.SetFirst(typecheck(n.Rlist.First(), ctxExpr|ctxMultiOK))
-	} else {
-		typecheckslice(n.Rlist.Slice(), ctxExpr)
-	}
-	checkassignlist(n, n.List)
-
-	var l *Node
-	var r *Node
-	if cl == cr {
-		// easy
-		ls := n.List.Slice()
-		rs := n.Rlist.Slice()
-		for il, nl := range ls {
-			nr := rs[il]
-			if nl.Type != nil && nr.Type != nil {
-				rs[il] = assignconv(nr, nl.Type, "assignment")
-			}
-			if nl.Name != nil && nl.Name.Defn == n && nl.Name.Param.Ntype == nil {
-				rs[il] = defaultlit(rs[il], nil)
-				nl.Type = rs[il].Type
-			}
-		}
-
-		goto out
-	}
-
-	l = n.List.First()
-	r = n.Rlist.First()
-
-	// x,y,z = f()
-	if cr == 1 {
-		if r.Type == nil {
-			goto out
-		}
-		switch r.Op {
-		case OCALLMETH, OCALLINTER, OCALLFUNC:
-			if !r.Type.IsFuncArgStruct() {
-				break
-			}
-			cr = r.Type.NumFields()
-			if cr != cl {
-				goto mismatch
-			}
-			n.Op = OAS2FUNC
-			n.Right = r
-			n.Rlist.Set(nil)
-			for i, l := range n.List.Slice() {
-				f := r.Type.Field(i)
-				if f.Type != nil && l.Type != nil {
-					checkassignto(f.Type, l)
-				}
-				if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil {
-					l.Type = f.Type
-				}
-			}
-			goto out
-		}
-	}
-
-	// x, ok = y
-	if cl == 2 && cr == 1 {
-		if r.Type == nil {
-			goto out
-		}
-		switch r.Op {
-		case OINDEXMAP, ORECV, ODOTTYPE:
-			switch r.Op {
-			case OINDEXMAP:
-				n.Op = OAS2MAPR
-			case ORECV:
-				n.Op = OAS2RECV
-			case ODOTTYPE:
-				n.Op = OAS2DOTTYPE
-				r.Op = ODOTTYPE2
-			}
-			n.Right = r
-			n.Rlist.Set(nil)
-			if l.Type != nil {
-				checkassignto(r.Type, l)
-			}
-			if l.Name != nil && l.Name.Defn == n {
-				l.Type = r.Type
-			}
-			l := n.List.Second()
-			if l.Type != nil && !l.Type.IsBoolean() {
-				checkassignto(types.Types[TBOOL], l)
-			}
-			if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil {
-				l.Type = types.Types[TBOOL]
-			}
-			goto out
-		}
-	}
-
-mismatch:
-	switch r.Op {
-	default:
-		yyerror("assignment mismatch: %d variables but %d values", cl, cr)
-	case OCALLFUNC, OCALLMETH, OCALLINTER:
-		yyerror("assignment mismatch: %d variables but %v returns %d values", cl, r.Left, cr)
-	}
-
-	// 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], ctxExpr|ctxAssign)
-		}
-	}
-}
-
-// type check function definition
-func typecheckfunc(n *Node) {
-	if enableTrace && trace {
-		defer tracePrint("typecheckfunc", n)(nil)
-	}
-
-	for _, ln := range n.Func.Dcl {
-		if ln.Op == ONAME && (ln.Class() == PPARAM || ln.Class() == PPARAMOUT) {
-			ln.Name.Decldepth = 1
-		}
-	}
-
-	n.Func.Nname = typecheck(n.Func.Nname, ctxExpr|ctxAssign)
-	t := n.Func.Nname.Type
-	if t == nil {
-		return
-	}
-	n.Type = t
-	t.FuncType().Nname = asTypesNode(n.Func.Nname)
-	rcvr := t.Recv()
-	if rcvr != nil && n.Func.Shortname != nil {
-		m := addmethod(n.Func.Shortname, t, true, n.Func.Pragma&Nointerface != 0)
-		if m == nil {
-			return
-		}
-
-		n.Func.Nname.Sym = methodSym(rcvr.Type, n.Func.Shortname)
-		declare(n.Func.Nname, PFUNC)
-	}
-
-	if Ctxt.Flag_dynlink && !inimport && n.Func.Nname != nil {
-		makefuncsym(n.Func.Nname.Sym)
-	}
-}
-
-// The result of stringtoruneslit MUST be assigned back to n, e.g.
-// 	n.Left = stringtoruneslit(n.Left)
-func stringtoruneslit(n *Node) *Node {
-	if n.Left.Op != OLITERAL || n.Left.Val().Ctype() != CTSTR {
-		Fatalf("stringtoarraylit %v", n)
-	}
-
-	var l []*Node
-	i := 0
-	for _, r := range n.Left.StringVal() {
-		l = append(l, nod(OKEY, nodintconst(int64(i)), nodintconst(int64(r))))
-		i++
-	}
-
-	nn := nod(OCOMPLIT, nil, typenod(n.Type))
-	nn.List.Set(l)
-	nn = typecheck(nn, ctxExpr)
-	return nn
-}
-
-var mapqueue []*Node
-
-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
-}
-
-func setUnderlying(t, underlying *types.Type) {
-	if underlying.Etype == TFORW {
-		// This type isn't computed yet; when it is, update n.
-		underlying.ForwardType().Copyto = append(underlying.ForwardType().Copyto, t)
-		return
-	}
-
-	n := asNode(t.Nod)
-	ft := t.ForwardType()
-	cache := t.Cache
-
-	// TODO(mdempsky): Fix Type rekinding.
-	*t = *underlying
-
-	// Restore unnecessarily clobbered attributes.
-	t.Nod = asTypesNode(n)
-	t.Sym = n.Sym
-	if n.Name != nil {
-		t.Vargen = n.Name.Vargen
-	}
-	t.Cache = cache
-	t.SetDeferwidth(false)
-
-	// spec: "The declared type does not inherit any methods bound
-	// to the existing type, but the method set of an interface
-	// type [...] remains unchanged."
-	if !t.IsInterface() {
-		*t.Methods() = types.Fields{}
-		*t.AllMethods() = types.Fields{}
-	}
-
-	// Propagate go:notinheap pragma from the Name to the Type.
-	if n.Name != nil && n.Name.Param != nil && n.Name.Param.Pragma()&NotInHeap != 0 {
-		t.SetNotInHeap(true)
-	}
-
-	// Update types waiting on this type.
-	for _, w := range ft.Copyto {
-		setUnderlying(w, t)
-	}
-
-	// Double-check use of type as embedded type.
-	if ft.Embedlineno.IsKnown() {
-		if t.IsPtr() || t.IsUnsafePtr() {
-			yyerrorl(ft.Embedlineno, "embedded type cannot be a pointer")
-		}
-	}
-}
-
-func typecheckdeftype(n *Node) {
-	if enableTrace && trace {
-		defer tracePrint("typecheckdeftype", n)(nil)
-	}
-
-	n.SetTypecheck(1)
-	n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, ctxType)
-	t := n.Name.Param.Ntype.Type
-	if t == nil {
-		n.SetDiag(true)
-		n.Type = nil
-	} else if n.Type == nil {
-		n.SetDiag(true)
-	} else {
-		// copy new type and clear fields
-		// that don't come along.
-		setUnderlying(n.Type, t)
-	}
-}
-
-func typecheckdef(n *Node) {
-	if enableTrace && trace {
-		defer tracePrint("typecheckdef", n)(nil)
-	}
-
-	lno := setlineno(n)
-
-	if n.Op == ONONAME {
-		if !n.Diag() {
-			n.SetDiag(true)
-
-			// Note: adderrorname looks for this string and
-			// adds context about the outer expression
-			yyerrorl(lineno, "undefined: %v", n.Sym)
-		}
-		lineno = lno
-		return
-	}
-
-	if n.Walkdef() == 1 {
-		lineno = lno
-		return
-	}
-
-	typecheckdefstack = append(typecheckdefstack, n)
-	if n.Walkdef() == 2 {
-		flusherrors()
-		fmt.Printf("typecheckdef loop:")
-		for i := len(typecheckdefstack) - 1; i >= 0; i-- {
-			n := typecheckdefstack[i]
-			fmt.Printf(" %v", n.Sym)
-		}
-		fmt.Printf("\n")
-		Fatalf("typecheckdef loop")
-	}
-
-	n.SetWalkdef(2)
-
-	if n.Type != nil || n.Sym == nil { // builtin or no name
-		goto ret
-	}
-
-	switch n.Op {
-	default:
-		Fatalf("typecheckdef %v", n.Op)
-
-	case OLITERAL:
-		if n.Name.Param.Ntype != nil {
-			n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, ctxType)
-			n.Type = n.Name.Param.Ntype.Type
-			n.Name.Param.Ntype = nil
-			if n.Type == nil {
-				n.SetDiag(true)
-				goto ret
-			}
-		}
-
-		e := n.Name.Defn
-		n.Name.Defn = nil
-		if e == nil {
-			Dump("typecheckdef nil defn", n)
-			yyerrorl(n.Pos, "xxx")
-		}
-
-		e = typecheck(e, ctxExpr)
-		if e.Type == nil {
-			goto ret
-		}
-		if !e.isGoConst() {
-			if !e.Diag() {
-				if Isconst(e, CTNIL) {
-					yyerrorl(n.Pos, "const initializer cannot be nil")
-				} else {
-					yyerrorl(n.Pos, "const initializer %v is not a constant", e)
-				}
-				e.SetDiag(true)
-			}
-			goto ret
-		}
-
-		t := n.Type
-		if t != nil {
-			if !okforconst[t.Etype] {
-				yyerrorl(n.Pos, "invalid constant type %v", t)
-				goto ret
-			}
-
-			if !e.Type.IsUntyped() && !types.Identical(t, e.Type) {
-				yyerrorl(n.Pos, "cannot use %L as type %v in const initializer", e, t)
-				goto ret
-			}
-
-			e = convlit(e, t)
-		}
-
-		n.SetVal(e.Val())
-		n.Type = e.Type
-
-	case ONAME:
-		if n.Name.Param.Ntype != nil {
-			n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, ctxType)
-			n.Type = n.Name.Param.Ntype.Type
-			if n.Type == nil {
-				n.SetDiag(true)
-				goto ret
-			}
-		}
-
-		if n.Type != nil {
-			break
-		}
-		if n.Name.Defn == nil {
-			if n.SubOp() != 0 { // like OPRINTN
-				break
-			}
-			if nsavederrors+nerrors > 0 {
-				// Can have undefined variables in x := foo
-				// that make x have an n.name.Defn == nil.
-				// If there are other errors anyway, don't
-				// bother adding to the noise.
-				break
-			}
-
-			Fatalf("var without type, init: %v", n.Sym)
-		}
-
-		if n.Name.Defn.Op == ONAME {
-			n.Name.Defn = typecheck(n.Name.Defn, ctxExpr)
-			n.Type = n.Name.Defn.Type
-			break
-		}
-
-		n.Name.Defn = typecheck(n.Name.Defn, ctxStmt) // fills in n.Type
-
-	case OTYPE:
-		if p := n.Name.Param; p.Alias() {
-			// Type alias declaration: Simply use the rhs type - no need
-			// to create a new type.
-			// If we have a syntax error, p.Ntype may be nil.
-			if p.Ntype != nil {
-				p.Ntype = typecheck(p.Ntype, ctxType)
-				n.Type = p.Ntype.Type
-				if n.Type == nil {
-					n.SetDiag(true)
-					goto ret
-				}
-				// For package-level type aliases, set n.Sym.Def so we can identify
-				// it as a type alias during export. See also #31959.
-				if n.Name.Curfn == nil {
-					n.Sym.Def = asTypesNode(p.Ntype)
-				}
-			}
-			break
-		}
-
-		// regular type declaration
-		defercheckwidth()
-		n.SetWalkdef(1)
-		setTypeNode(n, types.New(TFORW))
-		n.Type.Sym = n.Sym
-		nerrors0 := nerrors
-		typecheckdeftype(n)
-		if n.Type.Etype == TFORW && nerrors > nerrors0 {
-			// Something went wrong during type-checking,
-			// but it was reported. Silence future errors.
-			n.Type.SetBroke(true)
-		}
-		resumecheckwidth()
-	}
-
-ret:
-	if n.Op != OLITERAL && n.Type != nil && n.Type.IsUntyped() {
-		Fatalf("got %v for %v", n.Type, n)
-	}
-	last := len(typecheckdefstack) - 1
-	if typecheckdefstack[last] != n {
-		Fatalf("typecheckdefstack mismatch")
-	}
-	typecheckdefstack[last] = nil
-	typecheckdefstack = typecheckdefstack[:last]
-
-	lineno = lno
-	n.SetWalkdef(1)
-}
-
-func checkmake(t *types.Type, arg string, np **Node) bool {
-	n := *np
-	if !n.Type.IsInteger() && n.Type.Etype != TIDEAL {
-		yyerror("non-integer %s argument in make(%v) - %v", arg, t, n.Type)
-		return false
-	}
-
-	// Do range checks for constants before defaultlit
-	// to avoid redundant "constant NNN overflows int" errors.
-	switch consttype(n) {
-	case CTINT, CTRUNE, CTFLT, CTCPLX:
-		v := toint(n.Val()).U.(*Mpint)
-		if v.CmpInt64(0) < 0 {
-			yyerror("negative %s argument in make(%v)", arg, t)
-			return false
-		}
-		if v.Cmp(maxintval[TINT]) > 0 {
-			yyerror("%s argument too large in make(%v)", arg, t)
-			return false
-		}
-	}
-
-	// 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])
-	*np = n
-
-	return true
-}
-
-func markbreak(n *Node, implicit *Node) {
-	if n == nil {
-		return
-	}
-
-	switch n.Op {
-	case OBREAK:
-		if n.Sym == nil {
-			if implicit != nil {
-				implicit.SetHasBreak(true)
-			}
-		} else {
-			lab := asNode(n.Sym.Label)
-			if lab != nil {
-				lab.SetHasBreak(true)
-			}
-		}
-	case OFOR, OFORUNTIL, OSWITCH, OTYPESW, OSELECT, ORANGE:
-		implicit = n
-		fallthrough
-	default:
-		markbreak(n.Left, implicit)
-		markbreak(n.Right, implicit)
-		markbreaklist(n.Ninit, implicit)
-		markbreaklist(n.Nbody, implicit)
-		markbreaklist(n.List, implicit)
-		markbreaklist(n.Rlist, implicit)
-	}
-}
-
-func markbreaklist(l Nodes, implicit *Node) {
-	s := l.Slice()
-	for i := 0; i < len(s); i++ {
-		n := s[i]
-		if n == nil {
-			continue
-		}
-		if n.Op == OLABEL && i+1 < len(s) && n.Name.Defn == s[i+1] {
-			switch n.Name.Defn.Op {
-			case OFOR, OFORUNTIL, OSWITCH, OTYPESW, OSELECT, ORANGE:
-				n.Sym.Label = asTypesNode(n.Name.Defn)
-				markbreak(n.Name.Defn, n.Name.Defn)
-				n.Sym.Label = nil
-				i++
-				continue
-			}
-		}
-
-		markbreak(n, implicit)
-	}
-}
-
-// isterminating reports whether the Nodes list ends with a terminating statement.
-func (l Nodes) isterminating() bool {
-	s := l.Slice()
-	c := len(s)
-	if c == 0 {
-		return false
-	}
-	return s[c-1].isterminating()
-}
-
-// Isterminating reports whether the node n, the last one in a
-// statement list, is a terminating statement.
-func (n *Node) isterminating() bool {
-	switch n.Op {
-	// NOTE: OLABEL is treated as a separate statement,
-	// not a separate prefix, so skipping to the last statement
-	// in the block handles the labeled statement case by
-	// skipping over the label. No case OLABEL here.
-
-	case OBLOCK:
-		return n.List.isterminating()
-
-	case OGOTO, ORETURN, ORETJMP, OPANIC, OFALL:
-		return true
-
-	case OFOR, OFORUNTIL:
-		if n.Left != nil {
-			return false
-		}
-		if n.HasBreak() {
-			return false
-		}
-		return true
-
-	case OIF:
-		return n.Nbody.isterminating() && n.Rlist.isterminating()
-
-	case OSWITCH, OTYPESW, OSELECT:
-		if n.HasBreak() {
-			return false
-		}
-		def := false
-		for _, n1 := range n.List.Slice() {
-			if !n1.Nbody.isterminating() {
-				return false
-			}
-			if n1.List.Len() == 0 { // default
-				def = true
-			}
-		}
-
-		if n.Op != OSELECT && !def {
-			return false
-		}
-		return true
-	}
-
-	return false
-}
-
-// checkreturn makes sure that fn terminates appropriately.
-func checkreturn(fn *Node) {
-	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")
-		}
-	}
-}
-
-func deadcode(fn *Node) {
-	deadcodeslice(fn.Nbody)
-	deadcodefn(fn)
-}
-
-func deadcodefn(fn *Node) {
-	if fn.Nbody.Len() == 0 {
-		return
-	}
-
-	for _, n := range fn.Nbody.Slice() {
-		if n.Ninit.Len() > 0 {
-			return
-		}
-		switch n.Op {
-		case OIF:
-			if !Isconst(n.Left, CTBOOL) || n.Nbody.Len() > 0 || n.Rlist.Len() > 0 {
-				return
-			}
-		case OFOR:
-			if !Isconst(n.Left, CTBOOL) || n.Left.BoolVal() {
-				return
-			}
-		default:
-			return
-		}
-	}
-
-	fn.Nbody.Set([]*Node{nod(OEMPTY, nil, nil)})
-}
-
-func deadcodeslice(nn Nodes) {
-	var lastLabel = -1
-	for i, n := range nn.Slice() {
-		if n != nil && n.Op == OLABEL {
-			lastLabel = i
-		}
-	}
-	for i, n := range nn.Slice() {
-		// Cut is set to true when all nodes after i'th position
-		// should be removed.
-		// In other words, it marks whole slice "tail" as dead.
-		cut := false
-		if n == nil {
-			continue
-		}
-		if n.Op == OIF {
-			n.Left = deadcodeexpr(n.Left)
-			if Isconst(n.Left, CTBOOL) {
-				var body Nodes
-				if n.Left.BoolVal() {
-					n.Rlist = Nodes{}
-					body = n.Nbody
-				} else {
-					n.Nbody = Nodes{}
-					body = n.Rlist
-				}
-				// If "then" or "else" branch ends with panic or return statement,
-				// it is safe to remove all statements after this node.
-				// isterminating is not used to avoid goto-related complications.
-				// We must be careful not to deadcode-remove labels, as they
-				// might be the target of a goto. See issue 28616.
-				if body := body.Slice(); len(body) != 0 {
-					switch body[(len(body) - 1)].Op {
-					case ORETURN, ORETJMP, OPANIC:
-						if i > lastLabel {
-							cut = true
-						}
-					}
-				}
-			}
-		}
-
-		deadcodeslice(n.Ninit)
-		deadcodeslice(n.Nbody)
-		deadcodeslice(n.List)
-		deadcodeslice(n.Rlist)
-		if cut {
-			*nn.slice = nn.Slice()[:i+1]
-			break
-		}
-	}
-}
-
-func deadcodeexpr(n *Node) *Node {
-	// Perform dead-code elimination on short-circuited boolean
-	// expressions involving constants with the intent of
-	// producing a constant 'if' condition.
-	switch n.Op {
-	case OANDAND:
-		n.Left = deadcodeexpr(n.Left)
-		n.Right = deadcodeexpr(n.Right)
-		if Isconst(n.Left, CTBOOL) {
-			if n.Left.BoolVal() {
-				return n.Right // true && x => x
-			} else {
-				return n.Left // false && x => false
-			}
-		}
-	case OOROR:
-		n.Left = deadcodeexpr(n.Left)
-		n.Right = deadcodeexpr(n.Right)
-		if Isconst(n.Left, CTBOOL) {
-			if n.Left.BoolVal() {
-				return n.Left // true || x => true
-			} else {
-				return n.Right // false || x => x
-			}
-		}
-	}
-	return n
-}
-
-// setTypeNode sets n to an OTYPE node representing t.
-func setTypeNode(n *Node, t *types.Type) {
-	n.Op = OTYPE
-	n.Type = t
-	n.Type.Nod = asTypesNode(n)
-}
-
-// getIotaValue returns the current value for "iota",
-// or -1 if not within a ConstSpec.
-func getIotaValue() int64 {
-	if i := len(typecheckdefstack); i > 0 {
-		if x := typecheckdefstack[i-1]; x.Op == OLITERAL {
-			return x.Iota()
-		}
-	}
-
-	if Curfn != nil && Curfn.Iota() >= 0 {
-		return Curfn.Iota()
-	}
-
-	return -1
-}
-
-// curpkg returns the current package, based on Curfn.
-func curpkg() *types.Pkg {
-	fn := Curfn
-	if fn == nil {
-		// Initialization expressions for package-scope variables.
-		return localpkg
-	}
-
-	// TODO(mdempsky): Standardize on either ODCLFUNC or ONAME for
-	// Curfn, rather than mixing them.
-	if fn.Op == ODCLFUNC {
-		fn = fn.Func.Nname
-	}
-
-	return fnpkg(fn)
-}
diff --git a/src/cmd/compile/internal/gc/types.go b/src/cmd/compile/internal/gc/types.go
deleted file mode 100644
index 748f845..0000000
--- a/src/cmd/compile/internal/gc/types.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
-	"cmd/compile/internal/types"
-)
-
-// convenience constants
-const (
-	Txxx = types.Txxx
-
-	TINT8    = types.TINT8
-	TUINT8   = types.TUINT8
-	TINT16   = types.TINT16
-	TUINT16  = types.TUINT16
-	TINT32   = types.TINT32
-	TUINT32  = types.TUINT32
-	TINT64   = types.TINT64
-	TUINT64  = types.TUINT64
-	TINT     = types.TINT
-	TUINT    = types.TUINT
-	TUINTPTR = types.TUINTPTR
-
-	TCOMPLEX64  = types.TCOMPLEX64
-	TCOMPLEX128 = types.TCOMPLEX128
-
-	TFLOAT32 = types.TFLOAT32
-	TFLOAT64 = types.TFLOAT64
-
-	TBOOL = types.TBOOL
-
-	TPTR       = types.TPTR
-	TFUNC      = types.TFUNC
-	TSLICE     = types.TSLICE
-	TARRAY     = types.TARRAY
-	TSTRUCT    = types.TSTRUCT
-	TCHAN      = types.TCHAN
-	TMAP       = types.TMAP
-	TINTER     = types.TINTER
-	TFORW      = types.TFORW
-	TANY       = types.TANY
-	TSTRING    = types.TSTRING
-	TUNSAFEPTR = types.TUNSAFEPTR
-
-	// pseudo-types for literals
-	TIDEAL = types.TIDEAL
-	TNIL   = types.TNIL
-	TBLANK = types.TBLANK
-
-	// pseudo-types for frame layout
-	TFUNCARGS = types.TFUNCARGS
-	TCHANARGS = types.TCHANARGS
-
-	NTYPE = types.NTYPE
-)
diff --git a/src/cmd/compile/internal/gc/types_acc.go b/src/cmd/compile/internal/gc/types_acc.go
deleted file mode 100644
index 7240f72..0000000
--- a/src/cmd/compile/internal/gc/types_acc.go
+++ /dev/null
@@ -1,16 +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.
-
-// This file implements convertions between *types.Node and *Node.
-// TODO(gri) try to eliminate these soon
-
-package gc
-
-import (
-	"cmd/compile/internal/types"
-	"unsafe"
-)
-
-func asNode(n *types.Node) *Node      { return (*Node)(unsafe.Pointer(n)) }
-func asTypesNode(n *Node) *types.Node { return (*types.Node)(unsafe.Pointer(n)) }
diff --git a/src/cmd/compile/internal/gc/universe.go b/src/cmd/compile/internal/gc/universe.go
deleted file mode 100644
index ff8cabd..0000000
--- a/src/cmd/compile/internal/gc/universe.go
+++ /dev/null
@@ -1,453 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(gri) This file should probably become part of package types.
-
-package gc
-
-import "cmd/compile/internal/types"
-
-// builtinpkg is a fake package that declares the universe block.
-var builtinpkg *types.Pkg
-
-var basicTypes = [...]struct {
-	name  string
-	etype types.EType
-}{
-	{"int8", TINT8},
-	{"int16", TINT16},
-	{"int32", TINT32},
-	{"int64", TINT64},
-	{"uint8", TUINT8},
-	{"uint16", TUINT16},
-	{"uint32", TUINT32},
-	{"uint64", TUINT64},
-	{"float32", TFLOAT32},
-	{"float64", TFLOAT64},
-	{"complex64", TCOMPLEX64},
-	{"complex128", TCOMPLEX128},
-	{"bool", TBOOL},
-	{"string", TSTRING},
-}
-
-var typedefs = [...]struct {
-	name     string
-	etype    types.EType
-	sameas32 types.EType
-	sameas64 types.EType
-}{
-	{"int", TINT, TINT32, TINT64},
-	{"uint", TUINT, TUINT32, TUINT64},
-	{"uintptr", TUINTPTR, TUINT32, TUINT64},
-}
-
-var builtinFuncs = [...]struct {
-	name string
-	op   Op
-}{
-	{"append", OAPPEND},
-	{"cap", OCAP},
-	{"close", OCLOSE},
-	{"complex", OCOMPLEX},
-	{"copy", OCOPY},
-	{"delete", ODELETE},
-	{"imag", OIMAG},
-	{"len", OLEN},
-	{"make", OMAKE},
-	{"new", ONEW},
-	{"panic", OPANIC},
-	{"print", OPRINT},
-	{"println", OPRINTN},
-	{"real", OREAL},
-	{"recover", ORECOVER},
-}
-
-// isBuiltinFuncName reports whether name matches a builtin function
-// name.
-func isBuiltinFuncName(name string) bool {
-	for _, fn := range &builtinFuncs {
-		if fn.name == name {
-			return true
-		}
-	}
-	return false
-}
-
-var unsafeFuncs = [...]struct {
-	name string
-	op   Op
-}{
-	{"Alignof", OALIGNOF},
-	{"Offsetof", OOFFSETOF},
-	{"Sizeof", OSIZEOF},
-}
-
-// initUniverse initializes the universe block.
-func initUniverse() {
-	lexinit()
-	typeinit()
-	lexinit1()
-}
-
-// lexinit initializes known symbols and the basic types.
-func lexinit() {
-	for _, s := range &basicTypes {
-		etype := s.etype
-		if int(etype) >= len(types.Types) {
-			Fatalf("lexinit: %s bad etype", s.name)
-		}
-		s2 := builtinpkg.Lookup(s.name)
-		t := types.Types[etype]
-		if t == nil {
-			t = types.New(etype)
-			t.Sym = s2
-			if etype != TANY && etype != TSTRING {
-				dowidth(t)
-			}
-			types.Types[etype] = t
-		}
-		s2.Def = asTypesNode(typenod(t))
-		asNode(s2.Def).Name = new(Name)
-	}
-
-	for _, s := range &builtinFuncs {
-		s2 := builtinpkg.Lookup(s.name)
-		s2.Def = asTypesNode(newname(s2))
-		asNode(s2.Def).SetSubOp(s.op)
-	}
-
-	for _, s := range &unsafeFuncs {
-		s2 := unsafepkg.Lookup(s.name)
-		s2.Def = asTypesNode(newname(s2))
-		asNode(s2.Def).SetSubOp(s.op)
-	}
-
-	types.UntypedString = types.New(TSTRING)
-	types.UntypedBool = types.New(TBOOL)
-	types.Types[TANY] = types.New(TANY)
-
-	s := builtinpkg.Lookup("true")
-	s.Def = asTypesNode(nodbool(true))
-	asNode(s.Def).Sym = lookup("true")
-	asNode(s.Def).Name = new(Name)
-	asNode(s.Def).Type = types.UntypedBool
-
-	s = builtinpkg.Lookup("false")
-	s.Def = asTypesNode(nodbool(false))
-	asNode(s.Def).Sym = lookup("false")
-	asNode(s.Def).Name = new(Name)
-	asNode(s.Def).Type = types.UntypedBool
-
-	s = lookup("_")
-	s.Block = -100
-	s.Def = asTypesNode(newname(s))
-	types.Types[TBLANK] = types.New(TBLANK)
-	asNode(s.Def).Type = types.Types[TBLANK]
-	nblank = asNode(s.Def)
-
-	s = builtinpkg.Lookup("_")
-	s.Block = -100
-	s.Def = asTypesNode(newname(s))
-	types.Types[TBLANK] = types.New(TBLANK)
-	asNode(s.Def).Type = types.Types[TBLANK]
-
-	types.Types[TNIL] = types.New(TNIL)
-	s = builtinpkg.Lookup("nil")
-	var v Val
-	v.U = new(NilVal)
-	s.Def = asTypesNode(nodlit(v))
-	asNode(s.Def).Sym = s
-	asNode(s.Def).Name = new(Name)
-
-	s = builtinpkg.Lookup("iota")
-	s.Def = asTypesNode(nod(OIOTA, nil, nil))
-	asNode(s.Def).Sym = s
-	asNode(s.Def).Name = new(Name)
-}
-
-func typeinit() {
-	if Widthptr == 0 {
-		Fatalf("typeinit before betypeinit")
-	}
-
-	for et := types.EType(0); et < NTYPE; et++ {
-		simtype[et] = et
-	}
-
-	types.Types[TPTR] = types.New(TPTR)
-	dowidth(types.Types[TPTR])
-
-	t := types.New(TUNSAFEPTR)
-	types.Types[TUNSAFEPTR] = t
-	t.Sym = unsafepkg.Lookup("Pointer")
-	t.Sym.Def = asTypesNode(typenod(t))
-	asNode(t.Sym.Def).Name = new(Name)
-	dowidth(types.Types[TUNSAFEPTR])
-
-	for et := TINT8; et <= TUINT64; et++ {
-		isInt[et] = true
-	}
-	isInt[TINT] = true
-	isInt[TUINT] = true
-	isInt[TUINTPTR] = true
-
-	isFloat[TFLOAT32] = true
-	isFloat[TFLOAT64] = true
-
-	isComplex[TCOMPLEX64] = true
-	isComplex[TCOMPLEX128] = true
-
-	// initialize okfor
-	for et := types.EType(0); et < NTYPE; et++ {
-		if isInt[et] || et == TIDEAL {
-			okforeq[et] = true
-			okforcmp[et] = true
-			okforarith[et] = true
-			okforadd[et] = true
-			okforand[et] = true
-			okforconst[et] = true
-			issimple[et] = true
-			minintval[et] = new(Mpint)
-			maxintval[et] = new(Mpint)
-		}
-
-		if isFloat[et] {
-			okforeq[et] = true
-			okforcmp[et] = true
-			okforadd[et] = true
-			okforarith[et] = true
-			okforconst[et] = true
-			issimple[et] = true
-			minfltval[et] = newMpflt()
-			maxfltval[et] = newMpflt()
-		}
-
-		if isComplex[et] {
-			okforeq[et] = true
-			okforadd[et] = true
-			okforarith[et] = true
-			okforconst[et] = true
-			issimple[et] = true
-		}
-	}
-
-	issimple[TBOOL] = true
-
-	okforadd[TSTRING] = true
-
-	okforbool[TBOOL] = true
-
-	okforcap[TARRAY] = true
-	okforcap[TCHAN] = true
-	okforcap[TSLICE] = true
-
-	okforconst[TBOOL] = true
-	okforconst[TSTRING] = true
-
-	okforlen[TARRAY] = true
-	okforlen[TCHAN] = true
-	okforlen[TMAP] = true
-	okforlen[TSLICE] = true
-	okforlen[TSTRING] = true
-
-	okforeq[TPTR] = true
-	okforeq[TUNSAFEPTR] = true
-	okforeq[TINTER] = true
-	okforeq[TCHAN] = true
-	okforeq[TSTRING] = true
-	okforeq[TBOOL] = true
-	okforeq[TMAP] = true    // nil only; refined in typecheck
-	okforeq[TFUNC] = true   // nil only; refined in typecheck
-	okforeq[TSLICE] = true  // nil only; refined in typecheck
-	okforeq[TARRAY] = true  // only if element type is comparable; refined in typecheck
-	okforeq[TSTRUCT] = true // only if all struct fields are comparable; refined in typecheck
-
-	okforcmp[TSTRING] = true
-
-	var i int
-	for i = 0; i < len(okfor); i++ {
-		okfor[i] = okfornone[:]
-	}
-
-	// binary
-	okfor[OADD] = okforadd[:]
-	okfor[OAND] = okforand[:]
-	okfor[OANDAND] = okforbool[:]
-	okfor[OANDNOT] = okforand[:]
-	okfor[ODIV] = okforarith[:]
-	okfor[OEQ] = okforeq[:]
-	okfor[OGE] = okforcmp[:]
-	okfor[OGT] = okforcmp[:]
-	okfor[OLE] = okforcmp[:]
-	okfor[OLT] = okforcmp[:]
-	okfor[OMOD] = okforand[:]
-	okfor[OMUL] = okforarith[:]
-	okfor[ONE] = okforeq[:]
-	okfor[OOR] = okforand[:]
-	okfor[OOROR] = okforbool[:]
-	okfor[OSUB] = okforarith[:]
-	okfor[OXOR] = okforand[:]
-	okfor[OLSH] = okforand[:]
-	okfor[ORSH] = okforand[:]
-
-	// unary
-	okfor[OBITNOT] = okforand[:]
-	okfor[ONEG] = okforarith[:]
-	okfor[ONOT] = okforbool[:]
-	okfor[OPLUS] = okforarith[:]
-
-	// special
-	okfor[OCAP] = okforcap[:]
-	okfor[OLEN] = okforlen[:]
-
-	// comparison
-	iscmp[OLT] = true
-	iscmp[OGT] = true
-	iscmp[OGE] = true
-	iscmp[OLE] = true
-	iscmp[OEQ] = true
-	iscmp[ONE] = true
-
-	maxintval[TINT8].SetString("0x7f")
-	minintval[TINT8].SetString("-0x80")
-	maxintval[TINT16].SetString("0x7fff")
-	minintval[TINT16].SetString("-0x8000")
-	maxintval[TINT32].SetString("0x7fffffff")
-	minintval[TINT32].SetString("-0x80000000")
-	maxintval[TINT64].SetString("0x7fffffffffffffff")
-	minintval[TINT64].SetString("-0x8000000000000000")
-
-	maxintval[TUINT8].SetString("0xff")
-	maxintval[TUINT16].SetString("0xffff")
-	maxintval[TUINT32].SetString("0xffffffff")
-	maxintval[TUINT64].SetString("0xffffffffffffffff")
-
-	// f is valid float if min < f < max.  (min and max are not themselves valid.)
-	maxfltval[TFLOAT32].SetString("33554431p103") // 2^24-1 p (127-23) + 1/2 ulp
-	minfltval[TFLOAT32].SetString("-33554431p103")
-	maxfltval[TFLOAT64].SetString("18014398509481983p970") // 2^53-1 p (1023-52) + 1/2 ulp
-	minfltval[TFLOAT64].SetString("-18014398509481983p970")
-
-	maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32]
-	minfltval[TCOMPLEX64] = minfltval[TFLOAT32]
-	maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64]
-	minfltval[TCOMPLEX128] = minfltval[TFLOAT64]
-
-	types.Types[TINTER] = types.New(TINTER) // empty interface
-
-	// simple aliases
-	simtype[TMAP] = TPTR
-	simtype[TCHAN] = TPTR
-	simtype[TFUNC] = TPTR
-	simtype[TUNSAFEPTR] = TPTR
-
-	slicePtrOffset = 0
-	sliceLenOffset = Rnd(slicePtrOffset+int64(Widthptr), int64(Widthptr))
-	sliceCapOffset = Rnd(sliceLenOffset+int64(Widthptr), int64(Widthptr))
-	sizeofSlice = Rnd(sliceCapOffset+int64(Widthptr), int64(Widthptr))
-
-	// string is same as slice wo the cap
-	sizeofString = Rnd(sliceLenOffset+int64(Widthptr), int64(Widthptr))
-
-	dowidth(types.Types[TSTRING])
-	dowidth(types.UntypedString)
-}
-
-func makeErrorInterface() *types.Type {
-	field := types.NewField()
-	field.Type = types.Types[TSTRING]
-	f := functypefield(fakeRecvField(), nil, []*types.Field{field})
-
-	field = types.NewField()
-	field.Sym = lookup("Error")
-	field.Type = f
-
-	t := types.New(TINTER)
-	t.SetInterface([]*types.Field{field})
-	return t
-}
-
-func lexinit1() {
-	// error type
-	s := builtinpkg.Lookup("error")
-	types.Errortype = makeErrorInterface()
-	types.Errortype.Sym = s
-	types.Errortype.Orig = makeErrorInterface()
-	s.Def = asTypesNode(typenod(types.Errortype))
-	dowidth(types.Errortype)
-
-	// We create separate byte and rune types for better error messages
-	// rather than just creating type alias *types.Sym's for the uint8 and
-	// int32 types. Hence, (bytetype|runtype).Sym.isAlias() is false.
-	// TODO(gri) Should we get rid of this special case (at the cost
-	// of less informative error messages involving bytes and runes)?
-	// (Alternatively, we could introduce an OTALIAS node representing
-	// type aliases, albeit at the cost of having to deal with it everywhere).
-
-	// byte alias
-	s = builtinpkg.Lookup("byte")
-	types.Bytetype = types.New(TUINT8)
-	types.Bytetype.Sym = s
-	s.Def = asTypesNode(typenod(types.Bytetype))
-	asNode(s.Def).Name = new(Name)
-	dowidth(types.Bytetype)
-
-	// rune alias
-	s = builtinpkg.Lookup("rune")
-	types.Runetype = types.New(TINT32)
-	types.Runetype.Sym = s
-	s.Def = asTypesNode(typenod(types.Runetype))
-	asNode(s.Def).Name = new(Name)
-	dowidth(types.Runetype)
-
-	// backend-dependent builtin types (e.g. int).
-	for _, s := range &typedefs {
-		s1 := builtinpkg.Lookup(s.name)
-
-		sameas := s.sameas32
-		if Widthptr == 8 {
-			sameas = s.sameas64
-		}
-
-		simtype[s.etype] = sameas
-		minfltval[s.etype] = minfltval[sameas]
-		maxfltval[s.etype] = maxfltval[sameas]
-		minintval[s.etype] = minintval[sameas]
-		maxintval[s.etype] = maxintval[sameas]
-
-		t := types.New(s.etype)
-		t.Sym = s1
-		types.Types[s.etype] = t
-		s1.Def = asTypesNode(typenod(t))
-		asNode(s1.Def).Name = new(Name)
-		s1.Origpkg = builtinpkg
-
-		dowidth(t)
-	}
-}
-
-// finishUniverse makes the universe block visible within the current package.
-func finishUniverse() {
-	// Operationally, this is similar to a dot import of builtinpkg, except
-	// that we silently skip symbols that are already declared in the
-	// package block rather than emitting a redeclared symbol error.
-
-	for _, s := range builtinpkg.Syms {
-		if s.Def == nil {
-			continue
-		}
-		s1 := lookup(s.Name)
-		if s1.Def != nil {
-			continue
-		}
-
-		s1.Def = s.Def
-		s1.Block = s.Block
-	}
-
-	nodfp = newname(lookup(".fp"))
-	nodfp.Type = types.Types[TINT32]
-	nodfp.SetClass(PPARAM)
-	nodfp.Name.SetUsed(true)
-}
diff --git a/src/cmd/compile/internal/gc/unsafe.go b/src/cmd/compile/internal/gc/unsafe.go
deleted file mode 100644
index 2233961..0000000
--- a/src/cmd/compile/internal/gc/unsafe.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-// evalunsafe evaluates a package unsafe operation and returns the result.
-func evalunsafe(n *Node) int64 {
-	switch n.Op {
-	case OALIGNOF, OSIZEOF:
-		n.Left = typecheck(n.Left, ctxExpr)
-		n.Left = defaultlit(n.Left, nil)
-		tr := n.Left.Type
-		if tr == nil {
-			return 0
-		}
-		dowidth(tr)
-		if n.Op == OALIGNOF {
-			return int64(tr.Align)
-		}
-		return tr.Width
-
-	case OOFFSETOF:
-		// must be a selector.
-		if n.Left.Op != OXDOT {
-			yyerror("invalid expression %v", n)
-			return 0
-		}
-
-		// Remember base of selector to find it back after dot insertion.
-		// Since r->left may be mutated by typechecking, check it explicitly
-		// first to track it correctly.
-		n.Left.Left = typecheck(n.Left.Left, ctxExpr)
-		base := n.Left.Left
-
-		n.Left = typecheck(n.Left, ctxExpr)
-		if n.Left.Type == nil {
-			return 0
-		}
-		switch n.Left.Op {
-		case ODOT, ODOTPTR:
-			break
-		case OCALLPART:
-			yyerror("invalid expression %v: argument is a method value", n)
-			return 0
-		default:
-			yyerror("invalid expression %v", n)
-			return 0
-		}
-
-		// Sum offsets for dots until we reach base.
-		var v int64
-		for r := n.Left; r != base; r = r.Left {
-			switch r.Op {
-			case ODOTPTR:
-				// For Offsetof(s.f), s may itself be a pointer,
-				// but accessing f must not otherwise involve
-				// indirection via embedded pointer types.
-				if r.Left != base {
-					yyerror("invalid expression %v: selector implies indirection of embedded %v", n, r.Left)
-					return 0
-				}
-				fallthrough
-			case ODOT:
-				v += r.Xoffset
-			default:
-				Dump("unsafenmagic", n.Left)
-				Fatalf("impossible %#v node after dot insertion", r.Op)
-			}
-		}
-		return v
-	}
-
-	Fatalf("unexpected op %v", n.Op)
-	return 0
-}
diff --git a/src/cmd/compile/internal/gc/util.go b/src/cmd/compile/internal/gc/util.go
index 58be2f8..4baddbc 100644
--- a/src/cmd/compile/internal/gc/util.go
+++ b/src/cmd/compile/internal/gc/util.go
@@ -8,59 +8,35 @@
 	"os"
 	"runtime"
 	"runtime/pprof"
+
+	"cmd/compile/internal/base"
 )
 
-// Line returns n's position as a string. If n has been inlined,
-// it uses the outermost position where n has been inlined.
-func (n *Node) Line() string {
-	return linestr(n.Pos)
-}
-
-var atExitFuncs []func()
-
-func atExit(f func()) {
-	atExitFuncs = append(atExitFuncs, f)
-}
-
-func Exit(code int) {
-	for i := len(atExitFuncs) - 1; i >= 0; i-- {
-		f := atExitFuncs[i]
-		atExitFuncs = atExitFuncs[:i]
-		f()
-	}
-	os.Exit(code)
-}
-
 var (
-	blockprofile   string
-	cpuprofile     string
-	memprofile     string
 	memprofilerate int64
-	traceprofile   string
 	traceHandler   func(string)
-	mutexprofile   string
 )
 
 func startProfile() {
-	if cpuprofile != "" {
-		f, err := os.Create(cpuprofile)
+	if base.Flag.CPUProfile != "" {
+		f, err := os.Create(base.Flag.CPUProfile)
 		if err != nil {
-			Fatalf("%v", err)
+			base.Fatalf("%v", err)
 		}
 		if err := pprof.StartCPUProfile(f); err != nil {
-			Fatalf("%v", err)
+			base.Fatalf("%v", err)
 		}
-		atExit(pprof.StopCPUProfile)
+		base.AtExit(pprof.StopCPUProfile)
 	}
-	if memprofile != "" {
+	if base.Flag.MemProfile != "" {
 		if memprofilerate != 0 {
 			runtime.MemProfileRate = int(memprofilerate)
 		}
-		f, err := os.Create(memprofile)
+		f, err := os.Create(base.Flag.MemProfile)
 		if err != nil {
-			Fatalf("%v", err)
+			base.Fatalf("%v", err)
 		}
-		atExit(func() {
+		base.AtExit(func() {
 			// Profile all outstanding allocations.
 			runtime.GC()
 			// compilebench parses the memory profile to extract memstats,
@@ -68,36 +44,36 @@
 			// See golang.org/issue/18641 and runtime/pprof/pprof.go:writeHeap.
 			const writeLegacyFormat = 1
 			if err := pprof.Lookup("heap").WriteTo(f, writeLegacyFormat); err != nil {
-				Fatalf("%v", err)
+				base.Fatalf("%v", err)
 			}
 		})
 	} else {
 		// Not doing memory profiling; disable it entirely.
 		runtime.MemProfileRate = 0
 	}
-	if blockprofile != "" {
-		f, err := os.Create(blockprofile)
+	if base.Flag.BlockProfile != "" {
+		f, err := os.Create(base.Flag.BlockProfile)
 		if err != nil {
-			Fatalf("%v", err)
+			base.Fatalf("%v", err)
 		}
 		runtime.SetBlockProfileRate(1)
-		atExit(func() {
+		base.AtExit(func() {
 			pprof.Lookup("block").WriteTo(f, 0)
 			f.Close()
 		})
 	}
-	if mutexprofile != "" {
-		f, err := os.Create(mutexprofile)
+	if base.Flag.MutexProfile != "" {
+		f, err := os.Create(base.Flag.MutexProfile)
 		if err != nil {
-			Fatalf("%v", err)
+			base.Fatalf("%v", err)
 		}
 		startMutexProfiling()
-		atExit(func() {
+		base.AtExit(func() {
 			pprof.Lookup("mutex").WriteTo(f, 0)
 			f.Close()
 		})
 	}
-	if traceprofile != "" && traceHandler != nil {
-		traceHandler(traceprofile)
+	if base.Flag.TraceProfile != "" && traceHandler != nil {
+		traceHandler(base.Flag.TraceProfile)
 	}
 }
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
deleted file mode 100644
index 02a7269..0000000
--- a/src/cmd/compile/internal/gc/walk.go
+++ /dev/null
@@ -1,4125 +0,0 @@
-// Copyright 2009 The Go Authors. 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/compile/internal/types"
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"encoding/binary"
-	"fmt"
-	"strings"
-)
-
-// The constant is known to runtime.
-const tmpstringbufsize = 32
-const zeroValSize = 1024 // must match value of runtime/map.go:maxZero
-
-func walk(fn *Node) {
-	Curfn = fn
-
-	if Debug.W != 0 {
-		s := fmt.Sprintf("\nbefore walk %v", Curfn.Func.Nname.Sym)
-		dumplist(s, Curfn.Nbody)
-	}
-
-	lno := lineno
-
-	// Final typecheck for any unused variables.
-	for i, ln := range fn.Func.Dcl {
-		if ln.Op == ONAME && (ln.Class() == PAUTO || ln.Class() == PAUTOHEAP) {
-			ln = typecheck(ln, ctxExpr|ctxAssign)
-			fn.Func.Dcl[i] = ln
-		}
-	}
-
-	// Propagate the used flag for typeswitch variables up to the NONAME in its definition.
-	for _, ln := range fn.Func.Dcl {
-		if ln.Op == ONAME && (ln.Class() == PAUTO || ln.Class() == PAUTOHEAP) && ln.Name.Defn != nil && ln.Name.Defn.Op == OTYPESW && ln.Name.Used() {
-			ln.Name.Defn.Left.Name.SetUsed(true)
-		}
-	}
-
-	for _, ln := range fn.Func.Dcl {
-		if ln.Op != ONAME || (ln.Class() != PAUTO && ln.Class() != PAUTOHEAP) || ln.Sym.Name[0] == '&' || ln.Name.Used() {
-			continue
-		}
-		if defn := ln.Name.Defn; defn != nil && defn.Op == OTYPESW {
-			if defn.Left.Name.Used() {
-				continue
-			}
-			yyerrorl(defn.Left.Pos, "%v declared but not used", ln.Sym)
-			defn.Left.Name.SetUsed(true) // suppress repeats
-		} else {
-			yyerrorl(ln.Pos, "%v declared but not used", ln.Sym)
-		}
-	}
-
-	lineno = lno
-	if nerrors != 0 {
-		return
-	}
-	walkstmtlist(Curfn.Nbody.Slice())
-	if Debug.W != 0 {
-		s := fmt.Sprintf("after walk %v", Curfn.Func.Nname.Sym)
-		dumplist(s, Curfn.Nbody)
-	}
-
-	zeroResults()
-	heapmoves()
-	if Debug.W != 0 && Curfn.Func.Enter.Len() > 0 {
-		s := fmt.Sprintf("enter %v", Curfn.Func.Nname.Sym)
-		dumplist(s, Curfn.Func.Enter)
-	}
-}
-
-func walkstmtlist(s []*Node) {
-	for i := range s {
-		s[i] = walkstmt(s[i])
-	}
-}
-
-func paramoutheap(fn *Node) bool {
-	for _, ln := range fn.Func.Dcl {
-		switch ln.Class() {
-		case PPARAMOUT:
-			if ln.isParamStackCopy() || ln.Name.Addrtaken() {
-				return true
-			}
-
-		case PAUTO:
-			// stop early - parameters are over
-			return false
-		}
-	}
-
-	return false
-}
-
-// The result of walkstmt MUST be assigned back to n, e.g.
-// 	n.Left = walkstmt(n.Left)
-func walkstmt(n *Node) *Node {
-	if n == nil {
-		return n
-	}
-
-	setlineno(n)
-
-	walkstmtlist(n.Ninit.Slice())
-
-	switch n.Op {
-	default:
-		if n.Op == ONAME {
-			yyerror("%v is not a top level statement", n.Sym)
-		} else {
-			yyerror("%v is not a top level statement", n.Op)
-		}
-		Dump("nottop", n)
-
-	case OAS,
-		OASOP,
-		OAS2,
-		OAS2DOTTYPE,
-		OAS2RECV,
-		OAS2FUNC,
-		OAS2MAPR,
-		OCLOSE,
-		OCOPY,
-		OCALLMETH,
-		OCALLINTER,
-		OCALL,
-		OCALLFUNC,
-		ODELETE,
-		OSEND,
-		OPRINT,
-		OPRINTN,
-		OPANIC,
-		OEMPTY,
-		ORECOVER,
-		OGETG:
-		if n.Typecheck() == 0 {
-			Fatalf("missing typecheck: %+v", n)
-		}
-		wascopy := n.Op == OCOPY
-		init := n.Ninit
-		n.Ninit.Set(nil)
-		n = walkexpr(n, &init)
-		n = addinit(n, init.Slice())
-		if wascopy && n.Op == OCONVNOP {
-			n.Op = OEMPTY // don't leave plain values as statements.
-		}
-
-	// special case for a receive where we throw away
-	// the value received.
-	case ORECV:
-		if n.Typecheck() == 0 {
-			Fatalf("missing typecheck: %+v", n)
-		}
-		init := n.Ninit
-		n.Ninit.Set(nil)
-
-		n.Left = walkexpr(n.Left, &init)
-		n = mkcall1(chanfn("chanrecv1", 2, n.Left.Type), nil, &init, n.Left, nodnil())
-		n = walkexpr(n, &init)
-
-		n = addinit(n, init.Slice())
-
-	case OBREAK,
-		OCONTINUE,
-		OFALL,
-		OGOTO,
-		OLABEL,
-		ODCLCONST,
-		ODCLTYPE,
-		OCHECKNIL,
-		OVARDEF,
-		OVARKILL,
-		OVARLIVE:
-		break
-
-	case ODCL:
-		v := n.Left
-		if v.Class() == PAUTOHEAP {
-			if compiling_runtime {
-				yyerror("%v escapes to heap, not allowed in runtime", v)
-			}
-			if prealloc[v] == nil {
-				prealloc[v] = callnew(v.Type)
-			}
-			nn := nod(OAS, v.Name.Param.Heapaddr, prealloc[v])
-			nn.SetColas(true)
-			nn = typecheck(nn, ctxStmt)
-			return walkstmt(nn)
-		}
-
-	case OBLOCK:
-		walkstmtlist(n.List.Slice())
-
-	case OCASE:
-		yyerror("case statement out of place")
-
-	case ODEFER:
-		Curfn.Func.SetHasDefer(true)
-		Curfn.Func.numDefers++
-		if Curfn.Func.numDefers > maxOpenDefers {
-			// Don't allow open-coded defers if there are more than
-			// 8 defers in the function, since we use a single
-			// byte to record active defers.
-			Curfn.Func.SetOpenCodedDeferDisallowed(true)
-		}
-		if n.Esc != EscNever {
-			// If n.Esc is not EscNever, then this defer occurs in a loop,
-			// so open-coded defers cannot be used in this function.
-			Curfn.Func.SetOpenCodedDeferDisallowed(true)
-		}
-		fallthrough
-	case OGO:
-		switch n.Left.Op {
-		case OPRINT, OPRINTN:
-			n.Left = wrapCall(n.Left, &n.Ninit)
-
-		case ODELETE:
-			if mapfast(n.Left.List.First().Type) == mapslow {
-				n.Left = wrapCall(n.Left, &n.Ninit)
-			} else {
-				n.Left = walkexpr(n.Left, &n.Ninit)
-			}
-
-		case OCOPY:
-			n.Left = copyany(n.Left, &n.Ninit, true)
-
-		case OCALLFUNC, OCALLMETH, OCALLINTER:
-			if n.Left.Nbody.Len() > 0 {
-				n.Left = wrapCall(n.Left, &n.Ninit)
-			} else {
-				n.Left = walkexpr(n.Left, &n.Ninit)
-			}
-
-		default:
-			n.Left = walkexpr(n.Left, &n.Ninit)
-		}
-
-	case OFOR, OFORUNTIL:
-		if n.Left != nil {
-			walkstmtlist(n.Left.Ninit.Slice())
-			init := n.Left.Ninit
-			n.Left.Ninit.Set(nil)
-			n.Left = walkexpr(n.Left, &init)
-			n.Left = addinit(n.Left, init.Slice())
-		}
-
-		n.Right = walkstmt(n.Right)
-		if n.Op == OFORUNTIL {
-			walkstmtlist(n.List.Slice())
-		}
-		walkstmtlist(n.Nbody.Slice())
-
-	case OIF:
-		n.Left = walkexpr(n.Left, &n.Ninit)
-		walkstmtlist(n.Nbody.Slice())
-		walkstmtlist(n.Rlist.Slice())
-
-	case ORETURN:
-		Curfn.Func.numReturns++
-		if n.List.Len() == 0 {
-			break
-		}
-		if (Curfn.Type.FuncType().Outnamed && n.List.Len() > 1) || paramoutheap(Curfn) || Curfn.Func.HasDefer() {
-			// assign to the function out parameters,
-			// so that reorder3 can fix up conflicts
-			var rl []*Node
-
-			for _, ln := range Curfn.Func.Dcl {
-				cl := ln.Class()
-				if cl == PAUTO || cl == PAUTOHEAP {
-					break
-				}
-				if cl == PPARAMOUT {
-					if ln.isParamStackCopy() {
-						ln = walkexpr(typecheck(nod(ODEREF, ln.Name.Param.Heapaddr, nil), ctxExpr), nil)
-					}
-					rl = append(rl, ln)
-				}
-			}
-
-			if got, want := n.List.Len(), len(rl); got != want {
-				// order should have rewritten multi-value function calls
-				// with explicit OAS2FUNC nodes.
-				Fatalf("expected %v return arguments, have %v", want, got)
-			}
-
-			// move function calls out, to make reorder3's job easier.
-			walkexprlistsafe(n.List.Slice(), &n.Ninit)
-
-			ll := ascompatee(n.Op, rl, n.List.Slice(), &n.Ninit)
-			n.List.Set(reorder3(ll))
-			break
-		}
-		walkexprlist(n.List.Slice(), &n.Ninit)
-
-		// For each return parameter (lhs), assign the corresponding result (rhs).
-		lhs := Curfn.Type.Results()
-		rhs := n.List.Slice()
-		res := make([]*Node, lhs.NumFields())
-		for i, nl := range lhs.FieldSlice() {
-			nname := asNode(nl.Nname)
-			if nname.isParamHeapCopy() {
-				nname = nname.Name.Param.Stackcopy
-			}
-			a := nod(OAS, nname, rhs[i])
-			res[i] = convas(a, &n.Ninit)
-		}
-		n.List.Set(res)
-
-	case ORETJMP:
-		break
-
-	case OINLMARK:
-		break
-
-	case OSELECT:
-		walkselect(n)
-
-	case OSWITCH:
-		walkswitch(n)
-
-	case ORANGE:
-		n = walkrange(n)
-	}
-
-	if n.Op == ONAME {
-		Fatalf("walkstmt ended up with name: %+v", n)
-	}
-	return n
-}
-
-// walk the whole tree of the body of an
-// expression or simple statement.
-// the types expressions are calculated.
-// compile-time constants are evaluated.
-// complex side effects like statements are appended to init
-func walkexprlist(s []*Node, init *Nodes) {
-	for i := range s {
-		s[i] = walkexpr(s[i], init)
-	}
-}
-
-func walkexprlistsafe(s []*Node, init *Nodes) {
-	for i, n := range s {
-		s[i] = safeexpr(n, init)
-		s[i] = walkexpr(s[i], init)
-	}
-}
-
-func walkexprlistcheap(s []*Node, init *Nodes) {
-	for i, n := range s {
-		s[i] = cheapexpr(n, init)
-		s[i] = walkexpr(s[i], init)
-	}
-}
-
-// convFuncName builds the runtime function name for interface conversion.
-// It also reports whether the function expects the data by address.
-// Not all names are possible. For example, we never generate convE2E or convE2I.
-func convFuncName(from, to *types.Type) (fnname string, needsaddr bool) {
-	tkind := to.Tie()
-	switch from.Tie() {
-	case 'I':
-		if tkind == 'I' {
-			return "convI2I", false
-		}
-	case 'T':
-		switch {
-		case from.Size() == 2 && from.Align == 2:
-			return "convT16", false
-		case from.Size() == 4 && from.Align == 4 && !from.HasPointers():
-			return "convT32", false
-		case from.Size() == 8 && from.Align == types.Types[TUINT64].Align && !from.HasPointers():
-			return "convT64", false
-		}
-		if sc := from.SoleComponent(); sc != nil {
-			switch {
-			case sc.IsString():
-				return "convTstring", false
-			case sc.IsSlice():
-				return "convTslice", false
-			}
-		}
-
-		switch tkind {
-		case 'E':
-			if !from.HasPointers() {
-				return "convT2Enoptr", true
-			}
-			return "convT2E", true
-		case 'I':
-			if !from.HasPointers() {
-				return "convT2Inoptr", true
-			}
-			return "convT2I", true
-		}
-	}
-	Fatalf("unknown conv func %c2%c", from.Tie(), to.Tie())
-	panic("unreachable")
-}
-
-// The result of walkexpr MUST be assigned back to n, e.g.
-// 	n.Left = walkexpr(n.Left, init)
-func walkexpr(n *Node, init *Nodes) *Node {
-	if n == nil {
-		return n
-	}
-
-	// Eagerly checkwidth all expressions for the back end.
-	if n.Type != nil && !n.Type.WidthCalculated() {
-		switch n.Type.Etype {
-		case TBLANK, TNIL, TIDEAL:
-		default:
-			checkwidth(n.Type)
-		}
-	}
-
-	if init == &n.Ninit {
-		// not okay to use n->ninit when walking n,
-		// because we might replace n with some other node
-		// and would lose the init list.
-		Fatalf("walkexpr init == &n->ninit")
-	}
-
-	if n.Ninit.Len() != 0 {
-		walkstmtlist(n.Ninit.Slice())
-		init.AppendNodes(&n.Ninit)
-	}
-
-	lno := setlineno(n)
-
-	if Debug.w > 1 {
-		Dump("before walk expr", n)
-	}
-
-	if n.Typecheck() != 1 {
-		Fatalf("missed typecheck: %+v", n)
-	}
-
-	if n.Type.IsUntyped() {
-		Fatalf("expression has untyped type: %+v", n)
-	}
-
-	if n.Op == ONAME && n.Class() == PAUTOHEAP {
-		nn := nod(ODEREF, n.Name.Param.Heapaddr, nil)
-		nn = typecheck(nn, ctxExpr)
-		nn = walkexpr(nn, init)
-		nn.Left.MarkNonNil()
-		return nn
-	}
-
-opswitch:
-	switch n.Op {
-	default:
-		Dump("walk", n)
-		Fatalf("walkexpr: switch 1 unknown op %+S", n)
-
-	case ONONAME, OEMPTY, OGETG, ONEWOBJ:
-
-	case OTYPE, ONAME, OLITERAL:
-		// TODO(mdempsky): Just return n; see discussion on CL 38655.
-		// Perhaps refactor to use Node.mayBeShared for these instead.
-		// If these return early, make sure to still call
-		// stringsym for constant strings.
-
-	case ONOT, ONEG, OPLUS, OBITNOT, OREAL, OIMAG, ODOTMETH, ODOTINTER,
-		ODEREF, OSPTR, OITAB, OIDATA, OADDR:
-		n.Left = walkexpr(n.Left, init)
-
-	case OEFACE, OAND, OANDNOT, OSUB, OMUL, OADD, OOR, OXOR, OLSH, ORSH:
-		n.Left = walkexpr(n.Left, init)
-		n.Right = walkexpr(n.Right, init)
-
-	case ODOT, ODOTPTR:
-		usefield(n)
-		n.Left = walkexpr(n.Left, init)
-
-	case ODOTTYPE, ODOTTYPE2:
-		n.Left = walkexpr(n.Left, init)
-		// Set up interface type addresses for back end.
-		n.Right = typename(n.Type)
-		if n.Op == ODOTTYPE {
-			n.Right.Right = typename(n.Left.Type)
-		}
-		if !n.Type.IsInterface() && !n.Left.Type.IsEmptyInterface() {
-			n.List.Set1(itabname(n.Type, n.Left.Type))
-		}
-
-	case OLEN, OCAP:
-		if isRuneCount(n) {
-			// Replace len([]rune(string)) with runtime.countrunes(string).
-			n = mkcall("countrunes", n.Type, init, conv(n.Left.Left, types.Types[TSTRING]))
-			break
-		}
-
-		n.Left = walkexpr(n.Left, init)
-
-		// replace len(*[10]int) with 10.
-		// delayed until now to preserve side effects.
-		t := n.Left.Type
-
-		if t.IsPtr() {
-			t = t.Elem()
-		}
-		if t.IsArray() {
-			safeexpr(n.Left, init)
-			setintconst(n, t.NumElem())
-			n.SetTypecheck(1)
-		}
-
-	case OCOMPLEX:
-		// Use results from call expression as arguments for complex.
-		if n.Left == nil && n.Right == nil {
-			n.Left = n.List.First()
-			n.Right = n.List.Second()
-		}
-		n.Left = walkexpr(n.Left, init)
-		n.Right = walkexpr(n.Right, init)
-
-	case OEQ, ONE, OLT, OLE, OGT, OGE:
-		n = walkcompare(n, init)
-
-	case OANDAND, OOROR:
-		n.Left = walkexpr(n.Left, init)
-
-		// cannot put side effects from n.Right on init,
-		// because they cannot run before n.Left is checked.
-		// save elsewhere and store on the eventual n.Right.
-		var ll Nodes
-
-		n.Right = walkexpr(n.Right, &ll)
-		n.Right = addinit(n.Right, ll.Slice())
-
-	case OPRINT, OPRINTN:
-		n = walkprint(n, init)
-
-	case OPANIC:
-		n = mkcall("gopanic", nil, init, n.Left)
-
-	case ORECOVER:
-		n = mkcall("gorecover", n.Type, init, nod(OADDR, nodfp, nil))
-
-	case OCLOSUREVAR, OCFUNC:
-
-	case OCALLINTER, OCALLFUNC, OCALLMETH:
-		if n.Op == OCALLINTER || n.Op == OCALLMETH {
-			// We expect both interface call reflect.Type.Method and concrete
-			// call reflect.(*rtype).Method.
-			usemethod(n)
-		}
-		if n.Op == OCALLINTER {
-			markUsedIfaceMethod(n)
-		}
-
-		if n.Op == OCALLFUNC && n.Left.Op == OCLOSURE {
-			// Transform direct call of a closure to call of a normal function.
-			// transformclosure already did all preparation work.
-
-			// Prepend captured variables to argument list.
-			n.List.Prepend(n.Left.Func.Enter.Slice()...)
-
-			n.Left.Func.Enter.Set(nil)
-
-			// Replace OCLOSURE with ONAME/PFUNC.
-			n.Left = n.Left.Func.Closure.Func.Nname
-
-			// Update type of OCALLFUNC node.
-			// Output arguments had not changed, but their offsets could.
-			if n.Left.Type.NumResults() == 1 {
-				n.Type = n.Left.Type.Results().Field(0).Type
-			} else {
-				n.Type = n.Left.Type.Results()
-			}
-		}
-
-		walkCall(n, init)
-
-	case OAS, OASOP:
-		init.AppendNodes(&n.Ninit)
-
-		// Recognize m[k] = append(m[k], ...) so we can reuse
-		// the mapassign call.
-		mapAppend := n.Left.Op == OINDEXMAP && n.Right.Op == OAPPEND
-		if mapAppend && !samesafeexpr(n.Left, n.Right.List.First()) {
-			Fatalf("not same expressions: %v != %v", n.Left, n.Right.List.First())
-		}
-
-		n.Left = walkexpr(n.Left, init)
-		n.Left = safeexpr(n.Left, init)
-
-		if mapAppend {
-			n.Right.List.SetFirst(n.Left)
-		}
-
-		if n.Op == OASOP {
-			// Rewrite x op= y into x = x op y.
-			n.Right = nod(n.SubOp(), n.Left, n.Right)
-			n.Right = typecheck(n.Right, ctxExpr)
-
-			n.Op = OAS
-			n.ResetAux()
-		}
-
-		if oaslit(n, init) {
-			break
-		}
-
-		if n.Right == nil {
-			// TODO(austin): Check all "implicit zeroing"
-			break
-		}
-
-		if !instrumenting && isZero(n.Right) {
-			break
-		}
-
-		switch n.Right.Op {
-		default:
-			n.Right = walkexpr(n.Right, init)
-
-		case ORECV:
-			// x = <-c; n.Left is x, n.Right.Left is c.
-			// order.stmt made sure x is addressable.
-			n.Right.Left = walkexpr(n.Right.Left, init)
-
-			n1 := nod(OADDR, n.Left, nil)
-			r := n.Right.Left // the channel
-			n = mkcall1(chanfn("chanrecv1", 2, r.Type), nil, init, r, n1)
-			n = walkexpr(n, init)
-			break opswitch
-
-		case OAPPEND:
-			// x = append(...)
-			r := n.Right
-			if r.Type.Elem().NotInHeap() {
-				yyerror("%v can't be allocated in Go; it is incomplete (or unallocatable)", r.Type.Elem())
-			}
-			switch {
-			case isAppendOfMake(r):
-				// x = append(y, make([]T, y)...)
-				r = extendslice(r, init)
-			case r.IsDDD():
-				r = appendslice(r, init) // also works for append(slice, string).
-			default:
-				r = walkappend(r, init, n)
-			}
-			n.Right = r
-			if r.Op == OAPPEND {
-				// Left in place for back end.
-				// Do not add a new write barrier.
-				// Set up address of type for back end.
-				r.Left = typename(r.Type.Elem())
-				break opswitch
-			}
-			// Otherwise, lowered for race detector.
-			// Treat as ordinary assignment.
-		}
-
-		if n.Left != nil && n.Right != nil {
-			n = convas(n, init)
-		}
-
-	case OAS2:
-		init.AppendNodes(&n.Ninit)
-		walkexprlistsafe(n.List.Slice(), init)
-		walkexprlistsafe(n.Rlist.Slice(), init)
-		ll := ascompatee(OAS, n.List.Slice(), n.Rlist.Slice(), init)
-		ll = reorder3(ll)
-		n = liststmt(ll)
-
-	// a,b,... = fn()
-	case OAS2FUNC:
-		init.AppendNodes(&n.Ninit)
-
-		r := n.Right
-		walkexprlistsafe(n.List.Slice(), init)
-		r = walkexpr(r, init)
-
-		if isIntrinsicCall(r) {
-			n.Right = r
-			break
-		}
-		init.Append(r)
-
-		ll := ascompatet(n.List, r.Type)
-		n = liststmt(ll)
-
-	// x, y = <-c
-	// order.stmt made sure x is addressable or blank.
-	case OAS2RECV:
-		init.AppendNodes(&n.Ninit)
-
-		r := n.Right
-		walkexprlistsafe(n.List.Slice(), init)
-		r.Left = walkexpr(r.Left, init)
-		var n1 *Node
-		if n.List.First().isBlank() {
-			n1 = nodnil()
-		} else {
-			n1 = nod(OADDR, n.List.First(), nil)
-		}
-		fn := chanfn("chanrecv2", 2, r.Left.Type)
-		ok := n.List.Second()
-		call := mkcall1(fn, types.Types[TBOOL], init, r.Left, n1)
-		n = nod(OAS, ok, call)
-		n = typecheck(n, ctxStmt)
-
-	// a,b = m[i]
-	case OAS2MAPR:
-		init.AppendNodes(&n.Ninit)
-
-		r := n.Right
-		walkexprlistsafe(n.List.Slice(), init)
-		r.Left = walkexpr(r.Left, init)
-		r.Right = walkexpr(r.Right, init)
-		t := r.Left.Type
-
-		fast := mapfast(t)
-		var key *Node
-		if fast != mapslow {
-			// fast versions take key by value
-			key = r.Right
-		} else {
-			// standard version takes key by reference
-			// order.expr made sure key is addressable.
-			key = nod(OADDR, r.Right, nil)
-		}
-
-		// from:
-		//   a,b = m[i]
-		// to:
-		//   var,b = mapaccess2*(t, m, i)
-		//   a = *var
-		a := n.List.First()
-
-		if w := t.Elem().Width; w <= zeroValSize {
-			fn := mapfn(mapaccess2[fast], t)
-			r = mkcall1(fn, fn.Type.Results(), init, typename(t), r.Left, key)
-		} else {
-			fn := mapfn("mapaccess2_fat", t)
-			z := zeroaddr(w)
-			r = mkcall1(fn, fn.Type.Results(), init, typename(t), r.Left, key, z)
-		}
-
-		// mapaccess2* returns a typed bool, but due to spec changes,
-		// the boolean result of i.(T) is now untyped so we make it the
-		// same type as the variable on the lhs.
-		if ok := n.List.Second(); !ok.isBlank() && ok.Type.IsBoolean() {
-			r.Type.Field(1).Type = ok.Type
-		}
-		n.Right = r
-		n.Op = OAS2FUNC
-
-		// don't generate a = *var if a is _
-		if !a.isBlank() {
-			var_ := temp(types.NewPtr(t.Elem()))
-			var_.SetTypecheck(1)
-			var_.MarkNonNil() // mapaccess always returns a non-nil pointer
-			n.List.SetFirst(var_)
-			n = walkexpr(n, init)
-			init.Append(n)
-			n = nod(OAS, a, nod(ODEREF, var_, nil))
-		}
-
-		n = typecheck(n, ctxStmt)
-		n = walkexpr(n, init)
-
-	case ODELETE:
-		init.AppendNodes(&n.Ninit)
-		map_ := n.List.First()
-		key := n.List.Second()
-		map_ = walkexpr(map_, init)
-		key = walkexpr(key, init)
-
-		t := map_.Type
-		fast := mapfast(t)
-		if fast == mapslow {
-			// order.stmt made sure key is addressable.
-			key = nod(OADDR, key, nil)
-		}
-		n = mkcall1(mapfndel(mapdelete[fast], t), nil, init, typename(t), map_, key)
-
-	case OAS2DOTTYPE:
-		walkexprlistsafe(n.List.Slice(), init)
-		n.Right = walkexpr(n.Right, init)
-
-	case OCONVIFACE:
-		n.Left = walkexpr(n.Left, init)
-
-		fromType := n.Left.Type
-		toType := n.Type
-
-		if !fromType.IsInterface() && !Curfn.Func.Nname.isBlank() { // skip unnamed functions (func _())
-			markTypeUsedInInterface(fromType, Curfn.Func.lsym)
-		}
-
-		// typeword generates the type word of the interface value.
-		typeword := func() *Node {
-			if toType.IsEmptyInterface() {
-				return typename(fromType)
-			}
-			return itabname(fromType, toType)
-		}
-
-		// Optimize convT2E or convT2I as a two-word copy when T is pointer-shaped.
-		if isdirectiface(fromType) {
-			l := nod(OEFACE, typeword(), n.Left)
-			l.Type = toType
-			l.SetTypecheck(n.Typecheck())
-			n = l
-			break
-		}
-
-		if staticuint64s == nil {
-			staticuint64s = newname(Runtimepkg.Lookup("staticuint64s"))
-			staticuint64s.SetClass(PEXTERN)
-			// The actual type is [256]uint64, but we use [256*8]uint8 so we can address
-			// individual bytes.
-			staticuint64s.Type = types.NewArray(types.Types[TUINT8], 256*8)
-			zerobase = newname(Runtimepkg.Lookup("zerobase"))
-			zerobase.SetClass(PEXTERN)
-			zerobase.Type = types.Types[TUINTPTR]
-		}
-
-		// Optimize convT2{E,I} for many cases in which T is not pointer-shaped,
-		// by using an existing addressable value identical to n.Left
-		// or creating one on the stack.
-		var value *Node
-		switch {
-		case fromType.Size() == 0:
-			// n.Left is zero-sized. Use zerobase.
-			cheapexpr(n.Left, init) // Evaluate n.Left for side-effects. See issue 19246.
-			value = zerobase
-		case fromType.IsBoolean() || (fromType.Size() == 1 && fromType.IsInteger()):
-			// n.Left is a bool/byte. Use staticuint64s[n.Left * 8] on little-endian
-			// and staticuint64s[n.Left * 8 + 7] on big-endian.
-			n.Left = cheapexpr(n.Left, init)
-			// byteindex widens n.Left so that the multiplication doesn't overflow.
-			index := nod(OLSH, byteindex(n.Left), nodintconst(3))
-			if thearch.LinkArch.ByteOrder == binary.BigEndian {
-				index = nod(OADD, index, nodintconst(7))
-			}
-			value = nod(OINDEX, staticuint64s, index)
-			value.SetBounded(true)
-		case n.Left.Class() == PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly():
-			// n.Left is a readonly global; use it directly.
-			value = n.Left
-		case !fromType.IsInterface() && n.Esc == EscNone && fromType.Width <= 1024:
-			// n.Left does not escape. Use a stack temporary initialized to n.Left.
-			value = temp(fromType)
-			init.Append(typecheck(nod(OAS, value, n.Left), ctxStmt))
-		}
-
-		if value != nil {
-			// Value is identical to n.Left.
-			// Construct the interface directly: {type/itab, &value}.
-			l := nod(OEFACE, typeword(), typecheck(nod(OADDR, value, nil), ctxExpr))
-			l.Type = toType
-			l.SetTypecheck(n.Typecheck())
-			n = l
-			break
-		}
-
-		// Implement interface to empty interface conversion.
-		// tmp = i.itab
-		// if tmp != nil {
-		//    tmp = tmp.type
-		// }
-		// e = iface{tmp, i.data}
-		if toType.IsEmptyInterface() && fromType.IsInterface() && !fromType.IsEmptyInterface() {
-			// Evaluate the input interface.
-			c := temp(fromType)
-			init.Append(nod(OAS, c, n.Left))
-
-			// Get the itab out of the interface.
-			tmp := temp(types.NewPtr(types.Types[TUINT8]))
-			init.Append(nod(OAS, tmp, typecheck(nod(OITAB, c, nil), ctxExpr)))
-
-			// Get the type out of the itab.
-			nif := nod(OIF, typecheck(nod(ONE, tmp, nodnil()), ctxExpr), nil)
-			nif.Nbody.Set1(nod(OAS, tmp, itabType(tmp)))
-			init.Append(nif)
-
-			// Build the result.
-			e := nod(OEFACE, tmp, ifaceData(n.Pos, c, types.NewPtr(types.Types[TUINT8])))
-			e.Type = toType // assign type manually, typecheck doesn't understand OEFACE.
-			e.SetTypecheck(1)
-			n = e
-			break
-		}
-
-		fnname, needsaddr := convFuncName(fromType, toType)
-
-		if !needsaddr && !fromType.IsInterface() {
-			// Use a specialized conversion routine that only returns a data pointer.
-			// ptr = convT2X(val)
-			// e = iface{typ/tab, ptr}
-			fn := syslook(fnname)
-			dowidth(fromType)
-			fn = substArgTypes(fn, fromType)
-			dowidth(fn.Type)
-			call := nod(OCALL, fn, nil)
-			call.List.Set1(n.Left)
-			call = typecheck(call, ctxExpr)
-			call = walkexpr(call, init)
-			call = safeexpr(call, init)
-			e := nod(OEFACE, typeword(), call)
-			e.Type = toType
-			e.SetTypecheck(1)
-			n = e
-			break
-		}
-
-		var tab *Node
-		if fromType.IsInterface() {
-			// convI2I
-			tab = typename(toType)
-		} else {
-			// convT2x
-			tab = typeword()
-		}
-
-		v := n.Left
-		if needsaddr {
-			// Types of large or unknown size are passed by reference.
-			// Orderexpr arranged for n.Left to be a temporary for all
-			// the conversions it could see. Comparison of an interface
-			// with a non-interface, especially in a switch on interface value
-			// with non-interface cases, is not visible to order.stmt, so we
-			// have to fall back on allocating a temp here.
-			if !islvalue(v) {
-				v = copyexpr(v, v.Type, init)
-			}
-			v = nod(OADDR, v, nil)
-		}
-
-		dowidth(fromType)
-		fn := syslook(fnname)
-		fn = substArgTypes(fn, fromType, toType)
-		dowidth(fn.Type)
-		n = nod(OCALL, fn, nil)
-		n.List.Set2(tab, v)
-		n = typecheck(n, ctxExpr)
-		n = walkexpr(n, init)
-
-	case OCONV, OCONVNOP:
-		n.Left = walkexpr(n.Left, init)
-		if n.Op == OCONVNOP && checkPtr(Curfn, 1) {
-			if n.Type.IsPtr() && n.Left.Type.IsUnsafePtr() { // unsafe.Pointer to *T
-				n = walkCheckPtrAlignment(n, init, nil)
-				break
-			}
-			if n.Type.IsUnsafePtr() && n.Left.Type.IsUintptr() { // uintptr to unsafe.Pointer
-				n = walkCheckPtrArithmetic(n, init)
-				break
-			}
-		}
-		param, result := rtconvfn(n.Left.Type, n.Type)
-		if param == Txxx {
-			break
-		}
-		fn := basicnames[param] + "to" + basicnames[result]
-		n = conv(mkcall(fn, types.Types[result], init, conv(n.Left, types.Types[param])), n.Type)
-
-	case ODIV, OMOD:
-		n.Left = walkexpr(n.Left, init)
-		n.Right = walkexpr(n.Right, init)
-
-		// rewrite complex div into function call.
-		et := n.Left.Type.Etype
-
-		if isComplex[et] && n.Op == ODIV {
-			t := n.Type
-			n = mkcall("complex128div", types.Types[TCOMPLEX128], init, conv(n.Left, types.Types[TCOMPLEX128]), conv(n.Right, types.Types[TCOMPLEX128]))
-			n = conv(n, t)
-			break
-		}
-
-		// Nothing to do for float divisions.
-		if isFloat[et] {
-			break
-		}
-
-		// rewrite 64-bit div and mod on 32-bit architectures.
-		// TODO: Remove this code once we can introduce
-		// runtime calls late in SSA processing.
-		if Widthreg < 8 && (et == TINT64 || et == TUINT64) {
-			if n.Right.Op == OLITERAL {
-				// Leave div/mod by constant powers of 2 or small 16-bit constants.
-				// The SSA backend will handle those.
-				switch et {
-				case TINT64:
-					c := n.Right.Int64Val()
-					if c < 0 {
-						c = -c
-					}
-					if c != 0 && c&(c-1) == 0 {
-						break opswitch
-					}
-				case TUINT64:
-					c := uint64(n.Right.Int64Val())
-					if c < 1<<16 {
-						break opswitch
-					}
-					if c != 0 && c&(c-1) == 0 {
-						break opswitch
-					}
-				}
-			}
-			var fn string
-			if et == TINT64 {
-				fn = "int64"
-			} else {
-				fn = "uint64"
-			}
-			if n.Op == ODIV {
-				fn += "div"
-			} else {
-				fn += "mod"
-			}
-			n = mkcall(fn, n.Type, init, conv(n.Left, types.Types[et]), conv(n.Right, types.Types[et]))
-		}
-
-	case OINDEX:
-		n.Left = walkexpr(n.Left, init)
-
-		// save the original node for bounds checking elision.
-		// If it was a ODIV/OMOD walk might rewrite it.
-		r := n.Right
-
-		n.Right = walkexpr(n.Right, init)
-
-		// if range of type cannot exceed static array bound,
-		// disable bounds check.
-		if n.Bounded() {
-			break
-		}
-		t := n.Left.Type
-		if t != nil && t.IsPtr() {
-			t = t.Elem()
-		}
-		if t.IsArray() {
-			n.SetBounded(bounded(r, t.NumElem()))
-			if Debug.m != 0 && n.Bounded() && !Isconst(n.Right, CTINT) {
-				Warn("index bounds check elided")
-			}
-			if smallintconst(n.Right) && !n.Bounded() {
-				yyerror("index out of bounds")
-			}
-		} else if Isconst(n.Left, CTSTR) {
-			n.SetBounded(bounded(r, int64(len(n.Left.StringVal()))))
-			if Debug.m != 0 && n.Bounded() && !Isconst(n.Right, CTINT) {
-				Warn("index bounds check elided")
-			}
-			if smallintconst(n.Right) && !n.Bounded() {
-				yyerror("index out of bounds")
-			}
-		}
-
-		if Isconst(n.Right, CTINT) {
-			if n.Right.Val().U.(*Mpint).CmpInt64(0) < 0 || n.Right.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
-				yyerror("index out of bounds")
-			}
-		}
-
-	case OINDEXMAP:
-		// Replace m[k] with *map{access1,assign}(maptype, m, &k)
-		n.Left = walkexpr(n.Left, init)
-		n.Right = walkexpr(n.Right, init)
-		map_ := n.Left
-		key := n.Right
-		t := map_.Type
-		if n.IndexMapLValue() {
-			// This m[k] expression is on the left-hand side of an assignment.
-			fast := mapfast(t)
-			if fast == mapslow {
-				// standard version takes key by reference.
-				// order.expr made sure key is addressable.
-				key = nod(OADDR, key, nil)
-			}
-			n = mkcall1(mapfn(mapassign[fast], t), nil, init, typename(t), map_, key)
-		} else {
-			// m[k] is not the target of an assignment.
-			fast := mapfast(t)
-			if fast == mapslow {
-				// standard version takes key by reference.
-				// order.expr made sure key is addressable.
-				key = nod(OADDR, key, nil)
-			}
-
-			if w := t.Elem().Width; w <= zeroValSize {
-				n = mkcall1(mapfn(mapaccess1[fast], t), types.NewPtr(t.Elem()), init, typename(t), map_, key)
-			} else {
-				z := zeroaddr(w)
-				n = mkcall1(mapfn("mapaccess1_fat", t), types.NewPtr(t.Elem()), init, typename(t), map_, key, z)
-			}
-		}
-		n.Type = types.NewPtr(t.Elem())
-		n.MarkNonNil() // mapaccess1* and mapassign always return non-nil pointers.
-		n = nod(ODEREF, n, nil)
-		n.Type = t.Elem()
-		n.SetTypecheck(1)
-
-	case ORECV:
-		Fatalf("walkexpr ORECV") // should see inside OAS only
-
-	case OSLICEHEADER:
-		n.Left = walkexpr(n.Left, init)
-		n.List.SetFirst(walkexpr(n.List.First(), init))
-		n.List.SetSecond(walkexpr(n.List.Second(), init))
-
-	case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR:
-		checkSlice := checkPtr(Curfn, 1) && n.Op == OSLICE3ARR && n.Left.Op == OCONVNOP && n.Left.Left.Type.IsUnsafePtr()
-		if checkSlice {
-			n.Left.Left = walkexpr(n.Left.Left, init)
-		} else {
-			n.Left = walkexpr(n.Left, init)
-		}
-		low, high, max := n.SliceBounds()
-		low = walkexpr(low, init)
-		if low != nil && isZero(low) {
-			// Reduce x[0:j] to x[:j] and x[0:j:k] to x[:j:k].
-			low = nil
-		}
-		high = walkexpr(high, init)
-		max = walkexpr(max, init)
-		n.SetSliceBounds(low, high, max)
-		if checkSlice {
-			n.Left = walkCheckPtrAlignment(n.Left, init, max)
-		}
-		if n.Op.IsSlice3() {
-			if max != nil && max.Op == OCAP && samesafeexpr(n.Left, max.Left) {
-				// Reduce x[i:j:cap(x)] to x[i:j].
-				if n.Op == OSLICE3 {
-					n.Op = OSLICE
-				} else {
-					n.Op = OSLICEARR
-				}
-				n = reduceSlice(n)
-			}
-		} else {
-			n = reduceSlice(n)
-		}
-
-	case ONEW:
-		if n.Type.Elem().NotInHeap() {
-			yyerror("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type.Elem())
-		}
-		if n.Esc == EscNone {
-			if n.Type.Elem().Width >= maxImplicitStackVarSize {
-				Fatalf("large ONEW with EscNone: %v", n)
-			}
-			r := temp(n.Type.Elem())
-			r = nod(OAS, r, nil) // zero temp
-			r = typecheck(r, ctxStmt)
-			init.Append(r)
-			r = nod(OADDR, r.Left, nil)
-			r = typecheck(r, ctxExpr)
-			n = r
-		} else {
-			n = callnew(n.Type.Elem())
-		}
-
-	case OADDSTR:
-		n = addstr(n, init)
-
-	case OAPPEND:
-		// order should make sure we only see OAS(node, OAPPEND), which we handle above.
-		Fatalf("append outside assignment")
-
-	case OCOPY:
-		n = copyany(n, init, instrumenting && !compiling_runtime)
-
-		// cannot use chanfn - closechan takes any, not chan any
-	case OCLOSE:
-		fn := syslook("closechan")
-
-		fn = substArgTypes(fn, n.Left.Type)
-		n = mkcall1(fn, nil, init, n.Left)
-
-	case OMAKECHAN:
-		// 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
-
-		// var h *hmap
-		var h *Node
-		if n.Esc == EscNone {
-			// Allocate hmap on stack.
-
-			// var hv hmap
-			hv := temp(hmapType)
-			zero := nod(OAS, hv, nil)
-			zero = typecheck(zero, ctxStmt)
-			init.Append(zero)
-			// h = &hv
-			h = nod(OADDR, hv, nil)
-
-			// 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 elem size is 128 bytes, larger objects
-			// are stored with an indirection. So max bucket size is 2048+eps.
-			if !Isconst(hint, CTINT) ||
-				hint.Val().U.(*Mpint).CmpInt64(BUCKETSIZE) <= 0 {
-
-				// In case hint is larger than BUCKETSIZE runtime.makemap
-				// will allocate the buckets on the heap, see #20184
-				//
-				// if hint <= BUCKETSIZE {
-				//     var bv bmap
-				//     b = &bv
-				//     h.buckets = b
-				// }
-
-				nif := nod(OIF, nod(OLE, hint, nodintconst(BUCKETSIZE)), nil)
-				nif.SetLikely(true)
-
-				// var bv bmap
-				bv := temp(bmap(t))
-				zero = nod(OAS, bv, nil)
-				nif.Nbody.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)
-				nif.Nbody.Append(na)
-
-				nif = typecheck(nif, ctxStmt)
-				nif = walkstmt(nif)
-				init.Append(nif)
-			}
-		}
-
-		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, ctxStmt)
-				a = walkexpr(a, init)
-				init.Append(a)
-				n = convnop(h, t)
-			} 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.Elem())
-				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 initialize 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.Elem())
-			n = mkcall1(fn, n.Type, init, typename(n.Type), conv(hint, argtype), h)
-		}
-
-	case OMAKESLICE:
-		l := n.Left
-		r := n.Right
-		if r == nil {
-			r = safeexpr(l, init)
-			l = r
-		}
-		t := n.Type
-		if t.Elem().NotInHeap() {
-			yyerror("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem())
-		}
-		if n.Esc == EscNone {
-			if why := heapAllocReason(n); why != "" {
-				Fatalf("%v has EscNone, but %v", n, why)
-			}
-			// var arr [r]T
-			// n = arr[:l]
-			i := indexconst(r)
-			if i < 0 {
-				Fatalf("walkexpr: invalid index %v", r)
-			}
-
-			// cap is constrained to [0,2^31) or [0,2^63) depending on whether
-			// we're in 32-bit or 64-bit systems. So it's safe to do:
-			//
-			// if uint64(len) > cap {
-			//     if len < 0 { panicmakeslicelen() }
-			//     panicmakeslicecap()
-			// }
-			nif := nod(OIF, nod(OGT, conv(l, types.Types[TUINT64]), nodintconst(i)), nil)
-			niflen := nod(OIF, nod(OLT, l, nodintconst(0)), nil)
-			niflen.Nbody.Set1(mkcall("panicmakeslicelen", nil, init))
-			nif.Nbody.Append(niflen, mkcall("panicmakeslicecap", nil, init))
-			nif = typecheck(nif, ctxStmt)
-			init.Append(nif)
-
-			t = types.NewArray(t.Elem(), i) // [r]T
-			var_ := temp(t)
-			a := nod(OAS, var_, nil) // zero temp
-			a = typecheck(a, ctxStmt)
-			init.Append(a)
-			r := nod(OSLICE, var_, nil) // arr[:l]
-			r.SetSliceBounds(nil, l, nil)
-			r = conv(r, n.Type) // in case n.Type is named.
-			r = typecheck(r, ctxExpr)
-			r = walkexpr(r, init)
-			n = r
-		} else {
-			// n escapes; set up a call to makeslice.
-			// When len and cap can fit into int, use makeslice instead of
-			// makeslice64, which is faster and shorter on 32 bit platforms.
-
-			len, cap := l, r
-
-			fnname := "makeslice64"
-			argtype := types.Types[TINT64]
-
-			// 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) &&
-				(cap.Type.IsKind(TIDEAL) || maxintval[cap.Type.Etype].Cmp(maxintval[TUINT]) <= 0) {
-				fnname = "makeslice"
-				argtype = types.Types[TINT]
-			}
-
-			m := nod(OSLICEHEADER, nil, nil)
-			m.Type = t
-
-			fn := syslook(fnname)
-			m.Left = mkcall1(fn, types.Types[TUNSAFEPTR], init, typename(t.Elem()), conv(len, argtype), conv(cap, argtype))
-			m.Left.MarkNonNil()
-			m.List.Set2(conv(len, types.Types[TINT]), conv(cap, types.Types[TINT]))
-
-			m = typecheck(m, ctxExpr)
-			m = walkexpr(m, init)
-			n = m
-		}
-
-	case OMAKESLICECOPY:
-		if n.Esc == EscNone {
-			Fatalf("OMAKESLICECOPY with EscNone: %v", n)
-		}
-
-		t := n.Type
-		if t.Elem().NotInHeap() {
-			yyerror("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem())
-		}
-
-		length := conv(n.Left, types.Types[TINT])
-		copylen := nod(OLEN, n.Right, nil)
-		copyptr := nod(OSPTR, n.Right, nil)
-
-		if !t.Elem().HasPointers() && n.Bounded() {
-			// When len(to)==len(from) and elements have no pointers:
-			// replace make+copy with runtime.mallocgc+runtime.memmove.
-
-			// We do not check for overflow of len(to)*elem.Width here
-			// since len(from) is an existing checked slice capacity
-			// with same elem.Width for the from slice.
-			size := nod(OMUL, conv(length, types.Types[TUINTPTR]), conv(nodintconst(t.Elem().Width), types.Types[TUINTPTR]))
-
-			// instantiate mallocgc(size uintptr, typ *byte, needszero bool) unsafe.Pointer
-			fn := syslook("mallocgc")
-			sh := nod(OSLICEHEADER, nil, nil)
-			sh.Left = mkcall1(fn, types.Types[TUNSAFEPTR], init, size, nodnil(), nodbool(false))
-			sh.Left.MarkNonNil()
-			sh.List.Set2(length, length)
-			sh.Type = t
-
-			s := temp(t)
-			r := typecheck(nod(OAS, s, sh), ctxStmt)
-			r = walkexpr(r, init)
-			init.Append(r)
-
-			// instantiate memmove(to *any, frm *any, size uintptr)
-			fn = syslook("memmove")
-			fn = substArgTypes(fn, t.Elem(), t.Elem())
-			ncopy := mkcall1(fn, nil, init, nod(OSPTR, s, nil), copyptr, size)
-			ncopy = typecheck(ncopy, ctxStmt)
-			ncopy = walkexpr(ncopy, init)
-			init.Append(ncopy)
-
-			n = s
-		} else { // Replace make+copy with runtime.makeslicecopy.
-			// instantiate makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer
-			fn := syslook("makeslicecopy")
-			s := nod(OSLICEHEADER, nil, nil)
-			s.Left = mkcall1(fn, types.Types[TUNSAFEPTR], init, typename(t.Elem()), length, copylen, conv(copyptr, types.Types[TUNSAFEPTR]))
-			s.Left.MarkNonNil()
-			s.List.Set2(length, length)
-			s.Type = t
-			n = typecheck(s, ctxExpr)
-			n = walkexpr(n, init)
-		}
-
-	case ORUNESTR:
-		a := nodnil()
-		if n.Esc == EscNone {
-			t := types.NewArray(types.Types[TUINT8], 4)
-			a = nod(OADDR, temp(t), nil)
-		}
-		// intstring(*[4]byte, rune)
-		n = mkcall("intstring", n.Type, init, a, conv(n.Left, types.Types[TINT64]))
-
-	case OBYTES2STR, ORUNES2STR:
-		a := nodnil()
-		if n.Esc == EscNone {
-			// Create temporary buffer for string on stack.
-			t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)
-			a = nod(OADDR, temp(t), nil)
-		}
-		if n.Op == ORUNES2STR {
-			// slicerunetostring(*[32]byte, []rune) string
-			n = mkcall("slicerunetostring", n.Type, init, a, n.Left)
-		} else {
-			// slicebytetostring(*[32]byte, ptr *byte, n int) string
-			n.Left = cheapexpr(n.Left, init)
-			ptr, len := n.Left.backingArrayPtrLen()
-			n = mkcall("slicebytetostring", n.Type, init, a, ptr, len)
-		}
-
-	case OBYTES2STRTMP:
-		n.Left = walkexpr(n.Left, init)
-		if !instrumenting {
-			// Let the backend handle OBYTES2STRTMP directly
-			// to avoid a function call to slicebytetostringtmp.
-			break
-		}
-		// slicebytetostringtmp(ptr *byte, n int) string
-		n.Left = cheapexpr(n.Left, init)
-		ptr, len := n.Left.backingArrayPtrLen()
-		n = mkcall("slicebytetostringtmp", n.Type, init, ptr, len)
-
-	case OSTR2BYTES:
-		s := n.Left
-		if Isconst(s, CTSTR) {
-			sc := s.StringVal()
-
-			// Allocate a [n]byte of the right size.
-			t := types.NewArray(types.Types[TUINT8], int64(len(sc)))
-			var a *Node
-			if n.Esc == EscNone && len(sc) <= int(maxImplicitStackVarSize) {
-				a = nod(OADDR, temp(t), nil)
-			} else {
-				a = callnew(t)
-			}
-			p := temp(t.PtrTo()) // *[n]byte
-			init.Append(typecheck(nod(OAS, p, a), ctxStmt))
-
-			// Copy from the static string data to the [n]byte.
-			if len(sc) > 0 {
-				as := nod(OAS,
-					nod(ODEREF, p, nil),
-					nod(ODEREF, convnop(nod(OSPTR, s, nil), t.PtrTo()), nil))
-				as = typecheck(as, ctxStmt)
-				as = walkstmt(as)
-				init.Append(as)
-			}
-
-			// Slice the [n]byte to a []byte.
-			n.Op = OSLICEARR
-			n.Left = p
-			n = walkexpr(n, init)
-			break
-		}
-
-		a := nodnil()
-		if n.Esc == EscNone {
-			// Create temporary buffer for slice on stack.
-			t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)
-			a = nod(OADDR, temp(t), nil)
-		}
-		// stringtoslicebyte(*32[byte], string) []byte
-		n = mkcall("stringtoslicebyte", n.Type, init, a, conv(s, types.Types[TSTRING]))
-
-	case OSTR2BYTESTMP:
-		// []byte(string) conversion that creates a slice
-		// referring to the actual string bytes.
-		// This conversion is handled later by the backend and
-		// is only for use by internal compiler optimizations
-		// that know that the slice won't be mutated.
-		// The only such case today is:
-		// for i, c := range []byte(string)
-		n.Left = walkexpr(n.Left, init)
-
-	case OSTR2RUNES:
-		a := nodnil()
-		if n.Esc == EscNone {
-			// Create temporary buffer for slice on stack.
-			t := types.NewArray(types.Types[TINT32], tmpstringbufsize)
-			a = nod(OADDR, temp(t), nil)
-		}
-		// stringtoslicerune(*[32]rune, string) []rune
-		n = mkcall("stringtoslicerune", n.Type, init, a, conv(n.Left, types.Types[TSTRING]))
-
-	case OARRAYLIT, OSLICELIT, OMAPLIT, OSTRUCTLIT, OPTRLIT:
-		if isStaticCompositeLiteral(n) && !canSSAType(n.Type) {
-			// n can be directly represented in the read-only data section.
-			// Make direct reference to the static data. See issue 12841.
-			vstat := readonlystaticname(n.Type)
-			fixedlit(inInitFunction, initKindStatic, n, vstat, init)
-			n = vstat
-			n = typecheck(n, ctxExpr)
-			break
-		}
-		var_ := temp(n.Type)
-		anylit(n, var_, init)
-		n = var_
-
-	case OSEND:
-		n1 := n.Right
-		n1 = assignconv(n1, n.Left.Type.Elem(), "chan send")
-		n1 = walkexpr(n1, init)
-		n1 = nod(OADDR, n1, nil)
-		n = mkcall1(chanfn("chansend1", 2, n.Left.Type), nil, init, n.Left, n1)
-
-	case OCLOSURE:
-		n = walkclosure(n, init)
-
-	case OCALLPART:
-		n = walkpartialcall(n, init)
-	}
-
-	// Expressions that are constant at run time but not
-	// considered const by the language spec are not turned into
-	// constants until walk. For example, if n is y%1 == 0, the
-	// walk of y%1 may have replaced it by 0.
-	// Check whether n with its updated args is itself now a constant.
-	t := n.Type
-	evconst(n)
-	if n.Type != t {
-		Fatalf("evconst changed Type: %v had type %v, now %v", n, t, n.Type)
-	}
-	if n.Op == OLITERAL {
-		n = typecheck(n, ctxExpr)
-		// Emit string symbol now to avoid emitting
-		// any concurrently during the backend.
-		if s, ok := n.Val().U.(string); ok {
-			_ = stringsym(n.Pos, s)
-		}
-	}
-
-	updateHasCall(n)
-
-	if Debug.w != 0 && n != nil {
-		Dump("after walk expr", n)
-	}
-
-	lineno = lno
-	return n
-}
-
-// markTypeUsedInInterface marks that type t is converted to an interface.
-// This information is used in the linker in dead method elimination.
-func markTypeUsedInInterface(t *types.Type, from *obj.LSym) {
-	tsym := typenamesym(t).Linksym()
-	// Emit a marker relocation. The linker will know the type is converted
-	// to an interface if "from" is reachable.
-	r := obj.Addrel(from)
-	r.Sym = tsym
-	r.Type = objabi.R_USEIFACE
-}
-
-// markUsedIfaceMethod marks that an interface method is used in the current
-// function. n is OCALLINTER node.
-func markUsedIfaceMethod(n *Node) {
-	ityp := n.Left.Left.Type
-	tsym := typenamesym(ityp).Linksym()
-	r := obj.Addrel(Curfn.Func.lsym)
-	r.Sym = tsym
-	// n.Left.Xoffset is the method index * Widthptr (the offset of code pointer
-	// in itab).
-	midx := n.Left.Xoffset / int64(Widthptr)
-	r.Add = ifaceMethodOffset(ityp, midx)
-	r.Type = objabi.R_USEIFACEMETHOD
-}
-
-// rtconvfn returns the parameter and result types that will be used by a
-// runtime function to convert from type src to type dst. The runtime function
-// name can be derived from the names of the returned types.
-//
-// If no such function is necessary, it returns (Txxx, Txxx).
-func rtconvfn(src, dst *types.Type) (param, result types.EType) {
-	if thearch.SoftFloat {
-		return Txxx, Txxx
-	}
-
-	switch thearch.LinkArch.Family {
-	case sys.ARM, sys.MIPS:
-		if src.IsFloat() {
-			switch dst.Etype {
-			case TINT64, TUINT64:
-				return TFLOAT64, dst.Etype
-			}
-		}
-		if dst.IsFloat() {
-			switch src.Etype {
-			case TINT64, TUINT64:
-				return src.Etype, TFLOAT64
-			}
-		}
-
-	case sys.I386:
-		if src.IsFloat() {
-			switch dst.Etype {
-			case TINT64, TUINT64:
-				return TFLOAT64, dst.Etype
-			case TUINT32, TUINT, TUINTPTR:
-				return TFLOAT64, TUINT32
-			}
-		}
-		if dst.IsFloat() {
-			switch src.Etype {
-			case TINT64, TUINT64:
-				return src.Etype, TFLOAT64
-			case TUINT32, TUINT, TUINTPTR:
-				return TUINT32, TFLOAT64
-			}
-		}
-	}
-	return Txxx, Txxx
-}
-
-// TODO(josharian): combine this with its caller and simplify
-func reduceSlice(n *Node) *Node {
-	low, high, max := n.SliceBounds()
-	if high != nil && high.Op == OLEN && samesafeexpr(n.Left, high.Left) {
-		// Reduce x[i:len(x)] to x[i:].
-		high = nil
-	}
-	n.SetSliceBounds(low, high, max)
-	if (n.Op == OSLICE || n.Op == OSLICESTR) && low == nil && high == nil {
-		// Reduce x[:] to x.
-		if Debug_slice > 0 {
-			Warn("slice: omit slice operation")
-		}
-		return n.Left
-	}
-	return n
-}
-
-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)
-
-	if l.Op == OINDEXMAP {
-		return n
-	}
-
-	return convas(n, init)
-}
-
-func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node {
-	// check assign expression list to
-	// an expression list. called in
-	//	expr-list = expr-list
-
-	// ensure order of evaluation for function calls
-	for i := range nl {
-		nl[i] = safeexpr(nl[i], init)
-	}
-	for i1 := range nr {
-		nr[i1] = safeexpr(nr[i1], init)
-	}
-
-	var nn []*Node
-	i := 0
-	for ; i < len(nl); i++ {
-		if i >= len(nr) {
-			break
-		}
-		// Do not generate 'x = x' during return. See issue 4014.
-		if op == ORETURN && samesafeexpr(nl[i], nr[i]) {
-			continue
-		}
-		nn = append(nn, ascompatee1(nl[i], nr[i], init))
-	}
-
-	// cannot happen: caller checked that lists had same length
-	if i < len(nl) || i < len(nr) {
-		var nln, nrn Nodes
-		nln.Set(nl)
-		nrn.Set(nr)
-		Fatalf("error in shape across %+v %v %+v / %d %d [%s]", nln, op, nrn, len(nl), len(nr), Curfn.funcname())
-	}
-	return nn
-}
-
-// fncall reports whether assigning an rvalue of type rt to an lvalue l might involve a function call.
-func fncall(l *Node, rt *types.Type) bool {
-	if l.HasCall() || l.Op == OINDEXMAP {
-		return true
-	}
-	if types.Identical(l.Type, rt) {
-		return false
-	}
-	// There might be a conversion required, which might involve a runtime call.
-	return true
-}
-
-// check assign type list to
-// an expression list. called in
-//	expr-list = func()
-func ascompatet(nl Nodes, nr *types.Type) []*Node {
-	if nl.Len() != nr.NumFields() {
-		Fatalf("ascompatet: assignment count mismatch: %d = %d", nl.Len(), nr.NumFields())
-	}
-
-	var nn, mm Nodes
-	for i, l := range nl.Slice() {
-		if l.isBlank() {
-			continue
-		}
-		r := nr.Field(i)
-
-		// Any assignment to an lvalue that might cause a function call must be
-		// deferred until all the returned values have been read.
-		if fncall(l, r.Type) {
-			tmp := temp(r.Type)
-			tmp = typecheck(tmp, ctxExpr)
-			a := nod(OAS, l, tmp)
-			a = convas(a, &mm)
-			mm.Append(a)
-			l = tmp
-		}
-
-		res := nod(ORESULT, nil, nil)
-		res.Xoffset = Ctxt.FixedFrameSize() + r.Offset
-		res.Type = r.Type
-		res.SetTypecheck(1)
-
-		a := nod(OAS, l, res)
-		a = convas(a, &nn)
-		updateHasCall(a)
-		if a.HasCall() {
-			Dump("ascompatet ucount", a)
-			Fatalf("ascompatet: too many function calls evaluating parameters")
-		}
-
-		nn.Append(a)
-	}
-	return append(nn.Slice(), mm.Slice()...)
-}
-
-// package all the arguments that match a ... T parameter into a []T.
-func mkdotargslice(typ *types.Type, args []*Node) *Node {
-	var n *Node
-	if len(args) == 0 {
-		n = nodnil()
-		n.Type = typ
-	} else {
-		n = nod(OCOMPLIT, nil, typenod(typ))
-		n.List.Append(args...)
-		n.SetImplicit(true)
-	}
-
-	n = typecheck(n, ctxExpr)
-	if n.Type == nil {
-		Fatalf("mkdotargslice: typecheck failed")
-	}
-	return n
-}
-
-// fixVariadicCall rewrites calls to variadic functions to use an
-// explicit ... argument if one is not already present.
-func fixVariadicCall(call *Node) {
-	fntype := call.Left.Type
-	if !fntype.IsVariadic() || call.IsDDD() {
-		return
-	}
-
-	vi := fntype.NumParams() - 1
-	vt := fntype.Params().Field(vi).Type
-
-	args := call.List.Slice()
-	extra := args[vi:]
-	slice := mkdotargslice(vt, extra)
-	for i := range extra {
-		extra[i] = nil // allow GC
-	}
-
-	call.List.Set(append(args[:vi], slice))
-	call.SetIsDDD(true)
-}
-
-func walkCall(n *Node, init *Nodes) {
-	if n.Rlist.Len() != 0 {
-		return // already walked
-	}
-
-	params := n.Left.Type.Params()
-	args := n.List.Slice()
-
-	n.Left = walkexpr(n.Left, init)
-	walkexprlist(args, init)
-
-	// If this is a method call, add the receiver at the beginning of the args.
-	if n.Op == OCALLMETH {
-		withRecv := make([]*Node, len(args)+1)
-		withRecv[0] = n.Left.Left
-		n.Left.Left = nil
-		copy(withRecv[1:], args)
-		args = withRecv
-	}
-
-	// For any argument whose evaluation might require a function call,
-	// store that argument into a temporary variable,
-	// to prevent that calls from clobbering arguments already on the stack.
-	// When instrumenting, all arguments might require function calls.
-	var tempAssigns []*Node
-	for i, arg := range args {
-		updateHasCall(arg)
-		// Determine param type.
-		var t *types.Type
-		if n.Op == OCALLMETH {
-			if i == 0 {
-				t = n.Left.Type.Recv().Type
-			} else {
-				t = params.Field(i - 1).Type
-			}
-		} else {
-			t = params.Field(i).Type
-		}
-		if instrumenting || fncall(arg, t) {
-			// make assignment of fncall to tempAt
-			tmp := temp(t)
-			a := nod(OAS, tmp, arg)
-			a = convas(a, init)
-			tempAssigns = append(tempAssigns, a)
-			// replace arg with temp
-			args[i] = tmp
-		}
-	}
-
-	n.List.Set(tempAssigns)
-	n.Rlist.Set(args)
-}
-
-// generate code for print
-func walkprint(nn *Node, init *Nodes) *Node {
-	// Hoist all the argument evaluation up before the lock.
-	walkexprlistcheap(nn.List.Slice(), 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)
-	}
-
-	// 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].StringVal())
-			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)
-
-	calls := []*Node{mkcall("printlock", nil, init)}
-	for i, n := range nn.List.Slice() {
-		if n.Op == OLITERAL {
-			switch n.Val().Ctype() {
-			case CTRUNE:
-				n = defaultlit(n, types.Runetype)
-
-			case CTINT:
-				n = defaultlit(n, types.Types[TINT64])
-
-			case CTFLT:
-				n = defaultlit(n, types.Types[TFLOAT64])
-			}
-		}
-
-		if n.Op != OLITERAL && n.Type != nil && n.Type.Etype == TIDEAL {
-			n = defaultlit(n, types.Types[TINT64])
-		}
-		n = defaultlit(n, nil)
-		nn.List.SetIndex(i, n)
-		if n.Type == nil || n.Type.Etype == TFORW {
-			continue
-		}
-
-		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
-		case TPTR:
-			if n.Type.Elem().NotInHeap() {
-				on = syslook("printuintptr")
-				n = nod(OCONV, n, nil)
-				n.Type = types.Types[TUNSAFEPTR]
-				n = nod(OCONV, n, nil)
-				n.Type = types.Types[TUINTPTR]
-				break
-			}
-			fallthrough
-		case TCHAN, TMAP, TFUNC, TUNSAFEPTR:
-			on = syslook("printpointer")
-			on = substArgTypes(on, n.Type) // any-1
-		case TSLICE:
-			on = syslook("printslice")
-			on = substArgTypes(on, n.Type) // any-1
-		case TUINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINTPTR:
-			if isRuntimePkg(n.Type.Sym.Pkg) && n.Type.Sym.Name == "hex" {
-				on = syslook("printhex")
-			} else {
-				on = syslook("printuint")
-			}
-		case TINT, TINT8, TINT16, TINT32, TINT64:
-			on = syslook("printint")
-		case TFLOAT32, TFLOAT64:
-			on = syslook("printfloat")
-		case TCOMPLEX64, TCOMPLEX128:
-			on = syslook("printcomplex")
-		case TBOOL:
-			on = syslook("printbool")
-		case TSTRING:
-			cs := ""
-			if Isconst(n, CTSTR) {
-				cs = n.StringVal()
-			}
-			switch cs {
-			case " ":
-				on = syslook("printsp")
-			case "\n":
-				on = syslook("printnl")
-			default:
-				on = syslook("printstring")
-			}
-		default:
-			badtype(OPRINT, n.Type, nil)
-			continue
-		}
-
-		r := nod(OCALL, on, nil)
-		if params := on.Type.Params().FieldSlice(); len(params) > 0 {
-			t := params[0].Type
-			if !types.Identical(t, n.Type) {
-				n = nod(OCONV, n, nil)
-				n.Type = t
-			}
-			r.List.Append(n)
-		}
-		calls = append(calls, r)
-	}
-
-	calls = append(calls, mkcall("printunlock", nil, init))
-
-	typecheckslice(calls, ctxStmt)
-	walkexprlist(calls, init)
-
-	r := nod(OEMPTY, nil, nil)
-	r = typecheck(r, ctxStmt)
-	r = walkexpr(r, init)
-	r.Ninit.Set(calls)
-	return r
-}
-
-func callnew(t *types.Type) *Node {
-	dowidth(t)
-	n := nod(ONEWOBJ, typename(t), nil)
-	n.Type = types.NewPtr(t)
-	n.SetTypecheck(1)
-	n.MarkNonNil()
-	return n
-}
-
-// isReflectHeaderDataField reports whether l is an expression p.Data
-// where p has type reflect.SliceHeader or reflect.StringHeader.
-func isReflectHeaderDataField(l *Node) bool {
-	if l.Type != types.Types[TUINTPTR] {
-		return false
-	}
-
-	var tsym *types.Sym
-	switch l.Op {
-	case ODOT:
-		tsym = l.Left.Type.Sym
-	case ODOTPTR:
-		tsym = l.Left.Type.Elem().Sym
-	default:
-		return false
-	}
-
-	if tsym == nil || l.Sym.Name != "Data" || tsym.Pkg.Path != "reflect" {
-		return false
-	}
-	return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
-}
-
-func convas(n *Node, init *Nodes) *Node {
-	if n.Op != OAS {
-		Fatalf("convas: not OAS %v", n.Op)
-	}
-	defer updateHasCall(n)
-
-	n.SetTypecheck(1)
-
-	if n.Left == nil || n.Right == nil {
-		return n
-	}
-
-	lt := n.Left.Type
-	rt := n.Right.Type
-	if lt == nil || rt == nil {
-		return n
-	}
-
-	if n.Left.isBlank() {
-		n.Right = defaultlit(n.Right, nil)
-		return n
-	}
-
-	if !types.Identical(lt, rt) {
-		n.Right = assignconv(n.Right, lt, "assignment")
-		n.Right = walkexpr(n.Right, init)
-	}
-	dowidth(n.Right.Type)
-
-	return n
-}
-
-// from ascompat[ee]
-//	a,b = c,d
-// simultaneous assignment. there cannot
-// be later use of an earlier lvalue.
-//
-// function calls have been removed.
-func reorder3(all []*Node) []*Node {
-	// If a needed expression may be affected by an
-	// earlier assignment, make an early copy of that
-	// expression and use the copy instead.
-	var early []*Node
-
-	var mapinit Nodes
-	for i, n := range all {
-		l := n.Left
-
-		// Save subexpressions needed on left side.
-		// Drill through non-dereferences.
-		for {
-			if l.Op == ODOT || l.Op == OPAREN {
-				l = l.Left
-				continue
-			}
-
-			if l.Op == OINDEX && l.Left.Type.IsArray() {
-				l.Right = reorder3save(l.Right, all, i, &early)
-				l = l.Left
-				continue
-			}
-
-			break
-		}
-
-		switch l.Op {
-		default:
-			Fatalf("reorder3 unexpected lvalue %#v", l.Op)
-
-		case ONAME:
-			break
-
-		case OINDEX, OINDEXMAP:
-			l.Left = reorder3save(l.Left, all, i, &early)
-			l.Right = reorder3save(l.Right, all, i, &early)
-			if l.Op == OINDEXMAP {
-				all[i] = convas(all[i], &mapinit)
-			}
-
-		case ODEREF, ODOTPTR:
-			l.Left = reorder3save(l.Left, all, i, &early)
-		}
-
-		// Save expression on right side.
-		all[i].Right = reorder3save(all[i].Right, all, i, &early)
-	}
-
-	early = append(mapinit.Slice(), early...)
-	return append(early, all...)
-}
-
-// if the evaluation of *np would be affected by the
-// assignments in all up to but not including the ith assignment,
-// copy into a temporary during *early and
-// replace *np with that temp.
-// The result of reorder3save MUST be assigned back to n, e.g.
-// 	n.Left = reorder3save(n.Left, all, i, early)
-func reorder3save(n *Node, all []*Node, i int, early *[]*Node) *Node {
-	if !aliased(n, all[:i]) {
-		return n
-	}
-
-	q := temp(n.Type)
-	q = nod(OAS, q, n)
-	q = typecheck(q, ctxStmt)
-	*early = append(*early, q)
-	return q.Left
-}
-
-// what's the outer value that a write to n affects?
-// outer value means containing struct or array.
-func outervalue(n *Node) *Node {
-	for {
-		switch n.Op {
-		case OXDOT:
-			Fatalf("OXDOT in walk")
-		case ODOT, OPAREN, OCONVNOP:
-			n = n.Left
-			continue
-		case OINDEX:
-			if n.Left.Type != nil && n.Left.Type.IsArray() {
-				n = n.Left
-				continue
-			}
-		}
-
-		return n
-	}
-}
-
-// Is it possible that the computation of r might be
-// affected by assignments in all?
-func aliased(r *Node, all []*Node) bool {
-	if r == nil {
-		return false
-	}
-
-	// Treat all fields of a struct as referring to the whole struct.
-	// We could do better but we would have to keep track of the fields.
-	for r.Op == ODOT {
-		r = r.Left
-	}
-
-	// Look for obvious aliasing: a variable being assigned
-	// during the all list and appearing in n.
-	// Also record whether there are any writes to addressable
-	// memory (either main memory or variables whose addresses
-	// have been taken).
-	memwrite := false
-	for _, as := range all {
-		// We can ignore assignments to blank.
-		if as.Left.isBlank() {
-			continue
-		}
-
-		l := outervalue(as.Left)
-		if l.Op != ONAME {
-			memwrite = true
-			continue
-		}
-
-		switch l.Class() {
-		default:
-			Fatalf("unexpected class: %v, %v", l, l.Class())
-
-		case PAUTOHEAP, PEXTERN:
-			memwrite = true
-			continue
-
-		case PPARAMOUT:
-			// Assignments to a result parameter in a function with defers
-			// becomes visible early if evaluation of any later expression
-			// panics (#43835).
-			if Curfn.Func.HasDefer() {
-				return true
-			}
-			fallthrough
-		case PAUTO, PPARAM:
-			if l.Name.Addrtaken() {
-				memwrite = true
-				continue
-			}
-
-			if vmatch2(l, r) {
-				// Direct hit: l appears in r.
-				return true
-			}
-		}
-	}
-
-	// The variables being written do not appear in r.
-	// However, r might refer to computed addresses
-	// that are being written.
-
-	// If no computed addresses are affected by the writes, no aliasing.
-	if !memwrite {
-		return false
-	}
-
-	// If r does not refer to computed addresses
-	// (that is, if r only refers to variables whose addresses
-	// have not been taken), no aliasing.
-	if varexpr(r) {
-		return false
-	}
-
-	// Otherwise, both the writes and r refer to computed memory addresses.
-	// Assume that they might conflict.
-	return true
-}
-
-// does the evaluation of n only refer to variables
-// whose addresses have not been taken?
-// (and no other memory)
-func varexpr(n *Node) bool {
-	if n == nil {
-		return true
-	}
-
-	switch n.Op {
-	case OLITERAL:
-		return true
-
-	case ONAME:
-		switch n.Class() {
-		case PAUTO, PPARAM, PPARAMOUT:
-			if !n.Name.Addrtaken() {
-				return true
-			}
-		}
-
-		return false
-
-	case OADD,
-		OSUB,
-		OOR,
-		OXOR,
-		OMUL,
-		ODIV,
-		OMOD,
-		OLSH,
-		ORSH,
-		OAND,
-		OANDNOT,
-		OPLUS,
-		ONEG,
-		OBITNOT,
-		OPAREN,
-		OANDAND,
-		OOROR,
-		OCONV,
-		OCONVNOP,
-		OCONVIFACE,
-		ODOTTYPE:
-		return varexpr(n.Left) && varexpr(n.Right)
-
-	case ODOT: // but not ODOTPTR
-		// Should have been handled in aliased.
-		Fatalf("varexpr unexpected ODOT")
-	}
-
-	// Be conservative.
-	return false
-}
-
-// is the name l mentioned in r?
-func vmatch2(l *Node, r *Node) bool {
-	if r == nil {
-		return false
-	}
-	switch r.Op {
-	// match each right given left
-	case ONAME:
-		return l == r
-
-	case OLITERAL:
-		return false
-	}
-
-	if vmatch2(l, r.Left) {
-		return true
-	}
-	if vmatch2(l, r.Right) {
-		return true
-	}
-	for _, n := range r.List.Slice() {
-		if vmatch2(l, n) {
-			return true
-		}
-	}
-	return false
-}
-
-// is any name mentioned in l also mentioned in r?
-// called by sinit.go
-func vmatch1(l *Node, r *Node) bool {
-	// isolate all left sides
-	if l == nil || r == nil {
-		return false
-	}
-	switch l.Op {
-	case ONAME:
-		switch l.Class() {
-		case PPARAM, PAUTO:
-			break
-
-		default:
-			// assignment to non-stack variable must be
-			// delayed if right has function calls.
-			if r.HasCall() {
-				return true
-			}
-		}
-
-		return vmatch2(l, r)
-
-	case OLITERAL:
-		return false
-	}
-
-	if vmatch1(l.Left, r) {
-		return true
-	}
-	if vmatch1(l.Right, r) {
-		return true
-	}
-	for _, n := range l.List.Slice() {
-		if vmatch1(n, r) {
-			return true
-		}
-	}
-	return false
-}
-
-// paramstoheap returns code to allocate memory for heap-escaped parameters
-// and to copy non-result parameters' values from the stack.
-func paramstoheap(params *types.Type) []*Node {
-	var nn []*Node
-	for _, t := range params.Fields().Slice() {
-		v := asNode(t.Nname)
-		if v != nil && v.Sym != nil && strings.HasPrefix(v.Sym.Name, "~r") { // unnamed result
-			v = nil
-		}
-		if v == nil {
-			continue
-		}
-
-		if stackcopy := v.Name.Param.Stackcopy; stackcopy != nil {
-			nn = append(nn, walkstmt(nod(ODCL, v, nil)))
-			if stackcopy.Class() == PPARAM {
-				nn = append(nn, walkstmt(typecheck(nod(OAS, v, stackcopy), ctxStmt)))
-			}
-		}
-	}
-
-	return nn
-}
-
-// zeroResults zeros the return values at the start of the function.
-// We need to do this very early in the function.  Defer might stop a
-// panic and show the return values as they exist at the time of
-// panic.  For precise stacks, the garbage collector assumes results
-// are always live, so we need to zero them before any allocations,
-// even allocations to move params/results to the heap.
-// The generated code is added to Curfn's Enter list.
-func zeroResults() {
-	for _, f := range Curfn.Type.Results().Fields().Slice() {
-		v := asNode(f.Nname)
-		if v != nil && v.Name.Param.Heapaddr != nil {
-			// The local which points to the return value is the
-			// thing that needs zeroing. This is already handled
-			// by a Needzero annotation in plive.go:livenessepilogue.
-			continue
-		}
-		if v.isParamHeapCopy() {
-			// TODO(josharian/khr): Investigate whether we can switch to "continue" here,
-			// and document more in either case.
-			// In the review of CL 114797, Keith wrote (roughly):
-			// I don't think the zeroing below matters.
-			// The stack return value will never be marked as live anywhere in the function.
-			// It is not written to until deferreturn returns.
-			v = v.Name.Param.Stackcopy
-		}
-		// Zero the stack location containing f.
-		Curfn.Func.Enter.Append(nodl(Curfn.Pos, OAS, v, nil))
-	}
-}
-
-// returnsfromheap returns code to copy values for heap-escaped parameters
-// back to the stack.
-func returnsfromheap(params *types.Type) []*Node {
-	var nn []*Node
-	for _, t := range params.Fields().Slice() {
-		v := asNode(t.Nname)
-		if v == nil {
-			continue
-		}
-		if stackcopy := v.Name.Param.Stackcopy; stackcopy != nil && stackcopy.Class() == PPARAMOUT {
-			nn = append(nn, walkstmt(typecheck(nod(OAS, stackcopy, v), ctxStmt)))
-		}
-	}
-
-	return nn
-}
-
-// heapmoves generates code to handle migrating heap-escaped parameters
-// between the stack and the heap. The generated code is added to Curfn's
-// Enter and Exit lists.
-func heapmoves() {
-	lno := lineno
-	lineno = Curfn.Pos
-	nn := paramstoheap(Curfn.Type.Recvs())
-	nn = append(nn, paramstoheap(Curfn.Type.Params())...)
-	nn = append(nn, paramstoheap(Curfn.Type.Results())...)
-	Curfn.Func.Enter.Append(nn...)
-	lineno = Curfn.Func.Endlineno
-	Curfn.Func.Exit.Append(returnsfromheap(Curfn.Type.Results())...)
-	lineno = lno
-}
-
-func vmkcall(fn *Node, t *types.Type, init *Nodes, va []*Node) *Node {
-	if fn.Type == nil || fn.Type.Etype != TFUNC {
-		Fatalf("mkcall %v %v", fn, fn.Type)
-	}
-
-	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)
-	if fn.Type.NumResults() > 0 {
-		r = typecheck(r, ctxExpr|ctxMultiOK)
-	} else {
-		r = typecheck(r, ctxStmt)
-	}
-	r = walkexpr(r, init)
-	r.Type = t
-	return r
-}
-
-func mkcall(name string, t *types.Type, init *Nodes, args ...*Node) *Node {
-	return vmkcall(syslook(name), t, init, args)
-}
-
-func mkcall1(fn *Node, t *types.Type, init *Nodes, args ...*Node) *Node {
-	return vmkcall(fn, t, init, args)
-}
-
-func conv(n *Node, t *types.Type) *Node {
-	if types.Identical(n.Type, t) {
-		return n
-	}
-	n = nod(OCONV, n, nil)
-	n.Type = t
-	n = typecheck(n, ctxExpr)
-	return n
-}
-
-// convnop converts node n to type t using the OCONVNOP op
-// and typechecks the result with ctxExpr.
-func convnop(n *Node, t *types.Type) *Node {
-	if types.Identical(n.Type, t) {
-		return n
-	}
-	n = nod(OCONVNOP, n, nil)
-	n.Type = t
-	n = typecheck(n, ctxExpr)
-	return n
-}
-
-// byteindex converts n, which is byte-sized, to an int used to index into an array.
-// We cannot use conv, because we allow converting bool to int here,
-// which is forbidden in user code.
-func byteindex(n *Node) *Node {
-	// We cannot convert from bool to int directly.
-	// While converting from int8 to int is possible, it would yield
-	// the wrong result for negative values.
-	// Reinterpreting the value as an unsigned byte solves both cases.
-	if !types.Identical(n.Type, types.Types[TUINT8]) {
-		n = nod(OCONV, n, nil)
-		n.Type = types.Types[TUINT8]
-		n.SetTypecheck(1)
-	}
-	n = nod(OCONV, n, nil)
-	n.Type = types.Types[TINT]
-	n.SetTypecheck(1)
-	return n
-}
-
-func chanfn(name string, n int, t *types.Type) *Node {
-	if !t.IsChan() {
-		Fatalf("chanfn %v", t)
-	}
-	fn := syslook(name)
-	switch n {
-	default:
-		Fatalf("chanfn %d", n)
-	case 1:
-		fn = substArgTypes(fn, t.Elem())
-	case 2:
-		fn = substArgTypes(fn, t.Elem(), t.Elem())
-	}
-	return fn
-}
-
-func mapfn(name string, t *types.Type) *Node {
-	if !t.IsMap() {
-		Fatalf("mapfn %v", t)
-	}
-	fn := syslook(name)
-	fn = substArgTypes(fn, t.Key(), t.Elem(), t.Key(), t.Elem())
-	return fn
-}
-
-func mapfndel(name string, t *types.Type) *Node {
-	if !t.IsMap() {
-		Fatalf("mapfn %v", t)
-	}
-	fn := syslook(name)
-	fn = substArgTypes(fn, t.Key(), t.Elem(), t.Key())
-	return fn
-}
-
-const (
-	mapslow = iota
-	mapfast32
-	mapfast32ptr
-	mapfast64
-	mapfast64ptr
-	mapfaststr
-	nmapfast
-)
-
-type mapnames [nmapfast]string
-
-func mkmapnames(base string, ptr string) mapnames {
-	return mapnames{base, base + "_fast32", base + "_fast32" + ptr, base + "_fast64", base + "_fast64" + ptr, base + "_faststr"}
-}
-
-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/map.go:maxElemSize before changing.
-	if t.Elem().Width > 128 {
-		return mapslow
-	}
-	switch algtype(t.Key()) {
-	case AMEM32:
-		if !t.Key().HasPointers() {
-			return mapfast32
-		}
-		if Widthptr == 4 {
-			return mapfast32ptr
-		}
-		Fatalf("small pointer %v", t.Key())
-	case AMEM64:
-		if !t.Key().HasPointers() {
-			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
-	}
-	return mapslow
-}
-
-func writebarrierfn(name string, l *types.Type, r *types.Type) *Node {
-	fn := syslook(name)
-	fn = substArgTypes(fn, l, r)
-	return fn
-}
-
-func addstr(n *Node, init *Nodes) *Node {
-	// order.expr rewrote OADDSTR to have a list of strings.
-	c := n.List.Len()
-
-	if c < 2 {
-		Fatalf("addstr count %d too small", c)
-	}
-
-	buf := nodnil()
-	if n.Esc == EscNone {
-		sz := int64(0)
-		for _, n1 := range n.List.Slice() {
-			if n1.Op == OLITERAL {
-				sz += int64(len(n1.StringVal()))
-			}
-		}
-
-		// Don't allocate the buffer if the result won't fit.
-		if sz < tmpstringbufsize {
-			// Create temporary buffer for result string on stack.
-			t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)
-			buf = nod(OADDR, temp(t), nil)
-		}
-	}
-
-	// build list of string arguments
-	args := []*Node{buf}
-	for _, n2 := range n.List.Slice() {
-		args = append(args, conv(n2, types.Types[TSTRING]))
-	}
-
-	var fn string
-	if c <= 5 {
-		// small numbers of strings use direct runtime helpers.
-		// note: order.expr knows this cutoff too.
-		fn = fmt.Sprintf("concatstring%d", c)
-	} else {
-		// large numbers of strings are passed to the runtime as a slice.
-		fn = "concatstrings"
-
-		t := types.NewSlice(types.Types[TSTRING])
-		slice := nod(OCOMPLIT, nil, typenod(t))
-		if prealloc[n] != nil {
-			prealloc[slice] = prealloc[n]
-		}
-		slice.List.Set(args[1:]) // skip buf arg
-		args = []*Node{buf, slice}
-		slice.Esc = EscNone
-	}
-
-	cat := syslook(fn)
-	r := nod(OCALL, cat, nil)
-	r.List.Set(args)
-	r = typecheck(r, ctxExpr)
-	r = walkexpr(r, init)
-	r.Type = n.Type
-
-	return r
-}
-
-func walkAppendArgs(n *Node, init *Nodes) {
-	walkexprlistsafe(n.List.Slice(), init)
-
-	// walkexprlistsafe will leave OINDEX (s[n]) alone if both s
-	// and n are name or literal, but those may index the slice we're
-	// modifying here. Fix explicitly.
-	ls := n.List.Slice()
-	for i1, n1 := range ls {
-		ls[i1] = cheapexpr(n1, init)
-	}
-}
-
-// expand append(l1, l2...) to
-//   init {
-//     s := l1
-//     n := len(s) + len(l2)
-//     // Compare as uint so growslice can panic on overflow.
-//     if uint(n) > uint(cap(s)) {
-//       s = growslice(s, n)
-//     }
-//     s = s[:n]
-//     memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
-//   }
-//   s
-//
-// l2 is allowed to be a string.
-func appendslice(n *Node, init *Nodes) *Node {
-	walkAppendArgs(n, init)
-
-	l1 := n.List.First()
-	l2 := n.List.Second()
-	l2 = cheapexpr(l2, init)
-	n.List.SetSecond(l2)
-
-	var nodes Nodes
-
-	// var s []T
-	s := temp(l1.Type)
-	nodes.Append(nod(OAS, s, l1)) // s = l1
-
-	elemtype := s.Type.Elem()
-
-	// n := len(s) + len(l2)
-	nn := temp(types.Types[TINT])
-	nodes.Append(nod(OAS, nn, nod(OADD, nod(OLEN, s, nil), nod(OLEN, l2, nil))))
-
-	// if uint(n) > uint(cap(s))
-	nif := nod(OIF, nil, nil)
-	nuint := conv(nn, types.Types[TUINT])
-	scapuint := conv(nod(OCAP, s, nil), types.Types[TUINT])
-	nif.Left = nod(OGT, nuint, scapuint)
-
-	// instantiate growslice(typ *type, []any, int) []any
-	fn := syslook("growslice")
-	fn = substArgTypes(fn, elemtype, elemtype)
-
-	// s = growslice(T, s, n)
-	nif.Nbody.Set1(nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(elemtype), s, nn)))
-	nodes.Append(nif)
-
-	// s = s[:n]
-	nt := nod(OSLICE, s, nil)
-	nt.SetSliceBounds(nil, nn, nil)
-	nt.SetBounded(true)
-	nodes.Append(nod(OAS, s, nt))
-
-	var ncopy *Node
-	if elemtype.HasPointers() {
-		// copy(s[len(l1):], l2)
-		nptr1 := nod(OSLICE, s, nil)
-		nptr1.Type = s.Type
-		nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
-		nptr1 = cheapexpr(nptr1, &nodes)
-
-		nptr2 := l2
-
-		Curfn.Func.setWBPos(n.Pos)
-
-		// instantiate typedslicecopy(typ *type, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int
-		fn := syslook("typedslicecopy")
-		fn = substArgTypes(fn, l1.Type.Elem(), l2.Type.Elem())
-		ptr1, len1 := nptr1.backingArrayPtrLen()
-		ptr2, len2 := nptr2.backingArrayPtrLen()
-		ncopy = mkcall1(fn, types.Types[TINT], &nodes, typename(elemtype), ptr1, len1, ptr2, len2)
-	} else if instrumenting && !compiling_runtime {
-		// rely on runtime to instrument:
-		//  copy(s[len(l1):], l2)
-		// l2 can be a slice or string.
-		nptr1 := nod(OSLICE, s, nil)
-		nptr1.Type = s.Type
-		nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
-		nptr1 = cheapexpr(nptr1, &nodes)
-		nptr2 := l2
-
-		ptr1, len1 := nptr1.backingArrayPtrLen()
-		ptr2, len2 := nptr2.backingArrayPtrLen()
-
-		fn := syslook("slicecopy")
-		fn = substArgTypes(fn, ptr1.Type.Elem(), ptr2.Type.Elem())
-		ncopy = mkcall1(fn, types.Types[TINT], &nodes, ptr1, len1, ptr2, len2, nodintconst(elemtype.Width))
-	} else {
-		// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
-		nptr1 := nod(OINDEX, s, nod(OLEN, l1, nil))
-		nptr1.SetBounded(true)
-		nptr1 = nod(OADDR, nptr1, nil)
-
-		nptr2 := nod(OSPTR, l2, nil)
-
-		nwid := cheapexpr(conv(nod(OLEN, l2, nil), types.Types[TUINTPTR]), &nodes)
-		nwid = nod(OMUL, nwid, nodintconst(elemtype.Width))
-
-		// instantiate func memmove(to *any, frm *any, length uintptr)
-		fn := syslook("memmove")
-		fn = substArgTypes(fn, elemtype, elemtype)
-		ncopy = mkcall1(fn, nil, &nodes, nptr1, nptr2, nwid)
-	}
-	ln := append(nodes.Slice(), ncopy)
-
-	typecheckslice(ln, ctxStmt)
-	walkstmtlist(ln)
-	init.Append(ln...)
-	return s
-}
-
-// isAppendOfMake reports whether n is of the form append(x , make([]T, y)...).
-// isAppendOfMake assumes n has already been typechecked.
-func isAppendOfMake(n *Node) bool {
-	if Debug.N != 0 || instrumenting {
-		return false
-	}
-
-	if n.Typecheck() == 0 {
-		Fatalf("missing typecheck: %+v", n)
-	}
-
-	if n.Op != OAPPEND || !n.IsDDD() || n.List.Len() != 2 {
-		return false
-	}
-
-	second := n.List.Second()
-	if second.Op != OMAKESLICE || second.Right != nil {
-		return false
-	}
-
-	// y must be either an integer constant or the largest possible positive value
-	// of variable y needs to fit into an uint.
-
-	// typecheck made sure that constant arguments to make are not negative and fit into an int.
-
-	// The care of overflow of the len argument to make will be handled by an explicit check of int(len) < 0 during runtime.
-	y := second.Left
-	if !Isconst(y, CTINT) && maxintval[y.Type.Etype].Cmp(maxintval[TUINT]) > 0 {
-		return false
-	}
-
-	return true
-}
-
-// extendslice rewrites append(l1, make([]T, l2)...) to
-//   init {
-//     if l2 >= 0 { // Empty if block here for more meaningful node.SetLikely(true)
-//     } else {
-//       panicmakeslicelen()
-//     }
-//     s := l1
-//     n := len(s) + l2
-//     // Compare n and s as uint so growslice can panic on overflow of len(s) + l2.
-//     // cap is a positive int and n can become negative when len(s) + l2
-//     // overflows int. Interpreting n when negative as uint makes it larger
-//     // than cap(s). growslice will check the int n arg and panic if n is
-//     // negative. This prevents the overflow from being undetected.
-//     if uint(n) > uint(cap(s)) {
-//       s = growslice(T, s, n)
-//     }
-//     s = s[:n]
-//     lptr := &l1[0]
-//     sptr := &s[0]
-//     if lptr == sptr || !T.HasPointers() {
-//       // growslice did not clear the whole underlying array (or did not get called)
-//       hp := &s[len(l1)]
-//       hn := l2 * sizeof(T)
-//       memclr(hp, hn)
-//     }
-//   }
-//   s
-func extendslice(n *Node, init *Nodes) *Node {
-	// isAppendOfMake made sure all possible positive values of l2 fit into an uint.
-	// The case of l2 overflow when converting from e.g. uint to int is handled by an explicit
-	// check of l2 < 0 at runtime which is generated below.
-	l2 := conv(n.List.Second().Left, types.Types[TINT])
-	l2 = typecheck(l2, ctxExpr)
-	n.List.SetSecond(l2) // walkAppendArgs expects l2 in n.List.Second().
-
-	walkAppendArgs(n, init)
-
-	l1 := n.List.First()
-	l2 = n.List.Second() // re-read l2, as it may have been updated by walkAppendArgs
-
-	var nodes []*Node
-
-	// if l2 >= 0 (likely happens), do nothing
-	nifneg := nod(OIF, nod(OGE, l2, nodintconst(0)), nil)
-	nifneg.SetLikely(true)
-
-	// else panicmakeslicelen()
-	nifneg.Rlist.Set1(mkcall("panicmakeslicelen", nil, init))
-	nodes = append(nodes, nifneg)
-
-	// s := l1
-	s := temp(l1.Type)
-	nodes = append(nodes, nod(OAS, s, l1))
-
-	elemtype := s.Type.Elem()
-
-	// n := len(s) + l2
-	nn := temp(types.Types[TINT])
-	nodes = append(nodes, nod(OAS, nn, nod(OADD, nod(OLEN, s, nil), l2)))
-
-	// if uint(n) > uint(cap(s))
-	nuint := conv(nn, types.Types[TUINT])
-	capuint := conv(nod(OCAP, s, nil), types.Types[TUINT])
-	nif := nod(OIF, nod(OGT, nuint, capuint), nil)
-
-	// instantiate growslice(typ *type, old []any, newcap int) []any
-	fn := syslook("growslice")
-	fn = substArgTypes(fn, elemtype, elemtype)
-
-	// s = growslice(T, s, n)
-	nif.Nbody.Set1(nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(elemtype), s, nn)))
-	nodes = append(nodes, nif)
-
-	// s = s[:n]
-	nt := nod(OSLICE, s, nil)
-	nt.SetSliceBounds(nil, nn, nil)
-	nt.SetBounded(true)
-	nodes = append(nodes, nod(OAS, s, nt))
-
-	// lptr := &l1[0]
-	l1ptr := temp(l1.Type.Elem().PtrTo())
-	tmp := nod(OSPTR, l1, nil)
-	nodes = append(nodes, nod(OAS, l1ptr, tmp))
-
-	// sptr := &s[0]
-	sptr := temp(elemtype.PtrTo())
-	tmp = nod(OSPTR, s, nil)
-	nodes = append(nodes, nod(OAS, sptr, tmp))
-
-	// hp := &s[len(l1)]
-	hp := nod(OINDEX, s, nod(OLEN, l1, nil))
-	hp.SetBounded(true)
-	hp = nod(OADDR, hp, nil)
-	hp = convnop(hp, types.Types[TUNSAFEPTR])
-
-	// hn := l2 * sizeof(elem(s))
-	hn := nod(OMUL, l2, nodintconst(elemtype.Width))
-	hn = conv(hn, types.Types[TUINTPTR])
-
-	clrname := "memclrNoHeapPointers"
-	hasPointers := elemtype.HasPointers()
-	if hasPointers {
-		clrname = "memclrHasPointers"
-		Curfn.Func.setWBPos(n.Pos)
-	}
-
-	var clr Nodes
-	clrfn := mkcall(clrname, nil, &clr, hp, hn)
-	clr.Append(clrfn)
-
-	if hasPointers {
-		// if l1ptr == sptr
-		nifclr := nod(OIF, nod(OEQ, l1ptr, sptr), nil)
-		nifclr.Nbody = clr
-		nodes = append(nodes, nifclr)
-	} else {
-		nodes = append(nodes, clr.Slice()...)
-	}
-
-	typecheckslice(nodes, ctxStmt)
-	walkstmtlist(nodes)
-	init.Append(nodes...)
-	return s
-}
-
-// Rewrite append(src, x, y, z) so that any side effects in
-// x, y, z (including runtime panics) are evaluated in
-// initialization statements before the append.
-// For normal code generation, stop there and leave the
-// rest to cgen_append.
-//
-// For race detector, expand append(src, a [, b]* ) to
-//
-//   init {
-//     s := src
-//     const argc = len(args) - 1
-//     if cap(s) - len(s) < argc {
-//	    s = growslice(s, len(s)+argc)
-//     }
-//     n := len(s)
-//     s = s[:n+argc]
-//     s[n] = a
-//     s[n+1] = b
-//     ...
-//   }
-//   s
-func walkappend(n *Node, init *Nodes, dst *Node) *Node {
-	if !samesafeexpr(dst, n.List.First()) {
-		n.List.SetFirst(safeexpr(n.List.First(), init))
-		n.List.SetFirst(walkexpr(n.List.First(), init))
-	}
-	walkexprlistsafe(n.List.Slice()[1:], init)
-
-	nsrc := n.List.First()
-
-	// walkexprlistsafe will leave OINDEX (s[n]) alone if both s
-	// and n are name or literal, but those may index the slice we're
-	// modifying here. Fix explicitly.
-	// Using cheapexpr also makes sure that the evaluation
-	// of all arguments (and especially any panics) happen
-	// before we begin to modify the slice in a visible way.
-	ls := n.List.Slice()[1:]
-	for i, n := range ls {
-		n = cheapexpr(n, init)
-		if !types.Identical(n.Type, nsrc.Type.Elem()) {
-			n = assignconv(n, nsrc.Type.Elem(), "append")
-			n = walkexpr(n, init)
-		}
-		ls[i] = n
-	}
-
-	argc := n.List.Len() - 1
-	if argc < 1 {
-		return nsrc
-	}
-
-	// General case, with no function calls left as arguments.
-	// Leave for gen, except that instrumentation requires old form.
-	if !instrumenting || compiling_runtime {
-		return n
-	}
-
-	var l []*Node
-
-	ns := temp(nsrc.Type)
-	l = append(l, nod(OAS, ns, nsrc)) // s = src
-
-	na := nodintconst(int64(argc)) // const argc
-	nx := nod(OIF, nil, nil)       // if cap(s) - len(s) < argc
-	nx.Left = nod(OLT, nod(OSUB, nod(OCAP, ns, nil), nod(OLEN, ns, nil)), na)
-
-	fn := syslook("growslice") //   growslice(<type>, old []T, mincap int) (ret []T)
-	fn = substArgTypes(fn, ns.Type.Elem(), ns.Type.Elem())
-
-	nx.Nbody.Set1(nod(OAS, ns,
-		mkcall1(fn, ns.Type, &nx.Ninit, typename(ns.Type.Elem()), ns,
-			nod(OADD, nod(OLEN, ns, nil), na))))
-
-	l = append(l, nx)
-
-	nn := temp(types.Types[TINT])
-	l = append(l, nod(OAS, nn, nod(OLEN, ns, nil))) // n = len(s)
-
-	nx = nod(OSLICE, ns, nil) // ...s[:n+argc]
-	nx.SetSliceBounds(nil, nod(OADD, nn, na), nil)
-	nx.SetBounded(true)
-	l = append(l, nod(OAS, ns, nx)) // s = s[:n+argc]
-
-	ls = n.List.Slice()[1:]
-	for i, n := range ls {
-		nx = nod(OINDEX, ns, nn) // s[n] ...
-		nx.SetBounded(true)
-		l = append(l, nod(OAS, nx, n)) // s[n] = arg
-		if i+1 < len(ls) {
-			l = append(l, nod(OAS, nn, nod(OADD, nn, nodintconst(1)))) // n = n + 1
-		}
-	}
-
-	typecheckslice(l, ctxStmt)
-	walkstmtlist(l)
-	init.Append(l...)
-	return ns
-}
-
-// Lower copy(a, b) to a memmove call or a runtime call.
-//
-// init {
-//   n := len(a)
-//   if n > len(b) { n = len(b) }
-//   if a.ptr != b.ptr { memmove(a.ptr, b.ptr, n*sizeof(elem(a))) }
-// }
-// n;
-//
-// Also works if b is a string.
-//
-func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
-	if n.Left.Type.Elem().HasPointers() {
-		Curfn.Func.setWBPos(n.Pos)
-		fn := writebarrierfn("typedslicecopy", n.Left.Type.Elem(), n.Right.Type.Elem())
-		n.Left = cheapexpr(n.Left, init)
-		ptrL, lenL := n.Left.backingArrayPtrLen()
-		n.Right = cheapexpr(n.Right, init)
-		ptrR, lenR := n.Right.backingArrayPtrLen()
-		return mkcall1(fn, n.Type, init, typename(n.Left.Type.Elem()), ptrL, lenL, ptrR, lenR)
-	}
-
-	if runtimecall {
-		// rely on runtime to instrument:
-		//  copy(n.Left, n.Right)
-		// n.Right can be a slice or string.
-
-		n.Left = cheapexpr(n.Left, init)
-		ptrL, lenL := n.Left.backingArrayPtrLen()
-		n.Right = cheapexpr(n.Right, init)
-		ptrR, lenR := n.Right.backingArrayPtrLen()
-
-		fn := syslook("slicecopy")
-		fn = substArgTypes(fn, ptrL.Type.Elem(), ptrR.Type.Elem())
-
-		return mkcall1(fn, n.Type, init, ptrL, lenL, ptrR, lenR, nodintconst(n.Left.Type.Elem().Width))
-	}
-
-	n.Left = walkexpr(n.Left, init)
-	n.Right = walkexpr(n.Right, init)
-	nl := temp(n.Left.Type)
-	nr := temp(n.Right.Type)
-	var l []*Node
-	l = append(l, nod(OAS, nl, n.Left))
-	l = append(l, nod(OAS, nr, n.Right))
-
-	nfrm := nod(OSPTR, nr, nil)
-	nto := nod(OSPTR, nl, nil)
-
-	nlen := temp(types.Types[TINT])
-
-	// n = len(to)
-	l = append(l, nod(OAS, nlen, nod(OLEN, nl, nil)))
-
-	// if n > len(frm) { n = len(frm) }
-	nif := nod(OIF, nil, nil)
-
-	nif.Left = nod(OGT, nlen, nod(OLEN, nr, nil))
-	nif.Nbody.Append(nod(OAS, nlen, nod(OLEN, nr, nil)))
-	l = append(l, nif)
-
-	// if to.ptr != frm.ptr { memmove( ... ) }
-	ne := nod(OIF, nod(ONE, nto, nfrm), nil)
-	ne.SetLikely(true)
-	l = append(l, ne)
-
-	fn := syslook("memmove")
-	fn = substArgTypes(fn, nl.Type.Elem(), nl.Type.Elem())
-	nwid := temp(types.Types[TUINTPTR])
-	setwid := nod(OAS, nwid, conv(nlen, types.Types[TUINTPTR]))
-	ne.Nbody.Append(setwid)
-	nwid = nod(OMUL, nwid, nodintconst(nl.Type.Elem().Width))
-	call := mkcall1(fn, nil, init, nto, nfrm, nwid)
-	ne.Nbody.Append(call)
-
-	typecheckslice(l, ctxStmt)
-	walkstmtlist(l)
-	init.Append(l...)
-	return nlen
-}
-
-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
-	// is handled by walkcompare.
-	switch a, _ := algtype1(t); a {
-	case AMEM:
-		n := syslook("memequal")
-		n = substArgTypes(n, t, t)
-		return n, true
-	case ASPECIAL:
-		sym := typesymprefix(".eq", t)
-		n := newname(sym)
-		setNodeNameFunc(n)
-		n.Type = functype(nil, []*Node{
-			anonfield(types.NewPtr(t)),
-			anonfield(types.NewPtr(t)),
-		}, []*Node{
-			anonfield(types.Types[TBOOL]),
-		})
-		return n, false
-	}
-	Fatalf("eqfor %v", t)
-	return nil, false
-}
-
-// The result of walkcompare MUST be assigned back to n, e.g.
-// 	n.Left = walkcompare(n.Left, init)
-func walkcompare(n *Node, init *Nodes) *Node {
-	if n.Left.Type.IsInterface() && n.Right.Type.IsInterface() && n.Left.Op != OLITERAL && n.Right.Op != OLITERAL {
-		return walkcompareInterface(n, init)
-	}
-
-	if n.Left.Type.IsString() && n.Right.Type.IsString() {
-		return walkcompareString(n, init)
-	}
-
-	n.Left = walkexpr(n.Left, init)
-	n.Right = walkexpr(n.Right, init)
-
-	// Given mixed interface/concrete comparison,
-	// rewrite into types-equal && data-equal.
-	// This is efficient, avoids allocations, and avoids runtime calls.
-	if n.Left.Type.IsInterface() != n.Right.Type.IsInterface() {
-		// Preserve side-effects in case of short-circuiting; see #32187.
-		l := cheapexpr(n.Left, init)
-		r := cheapexpr(n.Right, init)
-		// Swap so that l is the interface value and r is the concrete value.
-		if n.Right.Type.IsInterface() {
-			l, r = r, l
-		}
-
-		// Handle both == and !=.
-		eq := n.Op
-		andor := OOROR
-		if eq == OEQ {
-			andor = OANDAND
-		}
-		// Check for types equal.
-		// For empty interface, this is:
-		//   l.tab == type(r)
-		// For non-empty interface, this is:
-		//   l.tab != nil && l.tab._type == type(r)
-		var eqtype *Node
-		tab := nod(OITAB, l, nil)
-		rtyp := typename(r.Type)
-		if l.Type.IsEmptyInterface() {
-			tab.Type = types.NewPtr(types.Types[TUINT8])
-			tab.SetTypecheck(1)
-			eqtype = nod(eq, tab, rtyp)
-		} else {
-			nonnil := nod(brcom(eq), nodnil(), tab)
-			match := nod(eq, itabType(tab), rtyp)
-			eqtype = nod(andor, nonnil, match)
-		}
-		// Check for data equal.
-		eqdata := nod(eq, ifaceData(n.Pos, l, r.Type), r)
-		// Put it all together.
-		expr := nod(andor, eqtype, eqdata)
-		n = finishcompare(n, expr, init)
-		return n
-	}
-
-	// Must be comparison of array or struct.
-	// Otherwise back end handles it.
-	// While we're here, decide whether to
-	// inline or call an eq alg.
-	t := n.Left.Type
-	var inline bool
-
-	maxcmpsize := int64(4)
-	unalignedLoad := canMergeLoads()
-	if unalignedLoad {
-		// Keep this low enough to generate less code than a function call.
-		maxcmpsize = 2 * int64(thearch.LinkArch.RegSize)
-	}
-
-	switch t.Etype {
-	default:
-		if Debug_libfuzzer != 0 && t.IsInteger() {
-			n.Left = cheapexpr(n.Left, init)
-			n.Right = cheapexpr(n.Right, init)
-
-			// If exactly one comparison operand is
-			// constant, invoke the constcmp functions
-			// instead, and arrange for the constant
-			// operand to be the first argument.
-			l, r := n.Left, n.Right
-			if r.Op == OLITERAL {
-				l, r = r, l
-			}
-			constcmp := l.Op == OLITERAL && r.Op != OLITERAL
-
-			var fn string
-			var paramType *types.Type
-			switch t.Size() {
-			case 1:
-				fn = "libfuzzerTraceCmp1"
-				if constcmp {
-					fn = "libfuzzerTraceConstCmp1"
-				}
-				paramType = types.Types[TUINT8]
-			case 2:
-				fn = "libfuzzerTraceCmp2"
-				if constcmp {
-					fn = "libfuzzerTraceConstCmp2"
-				}
-				paramType = types.Types[TUINT16]
-			case 4:
-				fn = "libfuzzerTraceCmp4"
-				if constcmp {
-					fn = "libfuzzerTraceConstCmp4"
-				}
-				paramType = types.Types[TUINT32]
-			case 8:
-				fn = "libfuzzerTraceCmp8"
-				if constcmp {
-					fn = "libfuzzerTraceConstCmp8"
-				}
-				paramType = types.Types[TUINT64]
-			default:
-				Fatalf("unexpected integer size %d for %v", t.Size(), t)
-			}
-			init.Append(mkcall(fn, nil, init, tracecmpArg(l, paramType, init), tracecmpArg(r, paramType, init)))
-		}
-		return n
-	case TARRAY:
-		// We can compare several elements at once with 2/4/8 byte integer compares
-		inline = t.NumElem() <= 1 || (issimple[t.Elem().Etype] && (t.NumElem() <= 4 || t.Elem().Width*t.NumElem() <= maxcmpsize))
-	case TSTRUCT:
-		inline = t.NumComponents(types.IgnoreBlankFields) <= 4
-	}
-
-	cmpl := n.Left
-	for cmpl != nil && cmpl.Op == OCONVNOP {
-		cmpl = cmpl.Left
-	}
-	cmpr := n.Right
-	for cmpr != nil && cmpr.Op == OCONVNOP {
-		cmpr = cmpr.Left
-	}
-
-	// Chose not to inline. Call equality function directly.
-	if !inline {
-		// eq algs take pointers; cmpl and cmpr must be addressable
-		if !islvalue(cmpl) || !islvalue(cmpr) {
-			Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
-		}
-
-		fn, needsize := eqfor(t)
-		call := nod(OCALL, fn, nil)
-		call.List.Append(nod(OADDR, cmpl, nil))
-		call.List.Append(nod(OADDR, cmpr, nil))
-		if needsize {
-			call.List.Append(nodintconst(t.Width))
-		}
-		res := call
-		if n.Op != OEQ {
-			res = nod(ONOT, res, nil)
-		}
-		n = finishcompare(n, res, init)
-		return n
-	}
-
-	// inline: build boolean expression comparing element by element
-	andor := OANDAND
-	if n.Op == ONE {
-		andor = OOROR
-	}
-	var expr *Node
-	compare := func(el, er *Node) {
-		a := nod(n.Op, el, er)
-		if expr == nil {
-			expr = a
-		} else {
-			expr = nod(andor, expr, a)
-		}
-	}
-	cmpl = safeexpr(cmpl, init)
-	cmpr = safeexpr(cmpr, init)
-	if t.IsStruct() {
-		for _, f := range t.Fields().Slice() {
-			sym := f.Sym
-			if sym.IsBlank() {
-				continue
-			}
-			compare(
-				nodSym(OXDOT, cmpl, sym),
-				nodSym(OXDOT, cmpr, sym),
-			)
-		}
-	} else {
-		step := int64(1)
-		remains := t.NumElem() * t.Elem().Width
-		combine64bit := unalignedLoad && Widthreg == 8 && t.Elem().Width <= 4 && t.Elem().IsInteger()
-		combine32bit := unalignedLoad && t.Elem().Width <= 2 && t.Elem().IsInteger()
-		combine16bit := unalignedLoad && t.Elem().Width == 1 && t.Elem().IsInteger()
-		for i := int64(0); remains > 0; {
-			var convType *types.Type
-			switch {
-			case remains >= 8 && combine64bit:
-				convType = types.Types[TINT64]
-				step = 8 / t.Elem().Width
-			case remains >= 4 && combine32bit:
-				convType = types.Types[TUINT32]
-				step = 4 / t.Elem().Width
-			case remains >= 2 && combine16bit:
-				convType = types.Types[TUINT16]
-				step = 2 / t.Elem().Width
-			default:
-				step = 1
-			}
-			if step == 1 {
-				compare(
-					nod(OINDEX, cmpl, nodintconst(i)),
-					nod(OINDEX, cmpr, nodintconst(i)),
-				)
-				i++
-				remains -= t.Elem().Width
-			} else {
-				elemType := t.Elem().ToUnsigned()
-				cmplw := nod(OINDEX, cmpl, nodintconst(i))
-				cmplw = conv(cmplw, elemType) // convert to unsigned
-				cmplw = conv(cmplw, convType) // widen
-				cmprw := nod(OINDEX, cmpr, nodintconst(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(i+offset))
-					lb = conv(lb, elemType)
-					lb = conv(lb, convType)
-					lb = nod(OLSH, lb, nodintconst(8*t.Elem().Width*offset))
-					cmplw = nod(OOR, cmplw, lb)
-					rb := nod(OINDEX, cmpr, nodintconst(i+offset))
-					rb = conv(rb, elemType)
-					rb = conv(rb, convType)
-					rb = nod(OLSH, rb, nodintconst(8*t.Elem().Width*offset))
-					cmprw = nod(OOR, cmprw, rb)
-				}
-				compare(cmplw, cmprw)
-				i += step
-				remains -= step * t.Elem().Width
-			}
-		}
-	}
-	if expr == nil {
-		expr = nodbool(n.Op == OEQ)
-		// We still need to use cmpl and cmpr, in case they contain
-		// an expression which might panic. See issue 23837.
-		t := temp(cmpl.Type)
-		a1 := nod(OAS, t, cmpl)
-		a1 = typecheck(a1, ctxStmt)
-		a2 := nod(OAS, t, cmpr)
-		a2 = typecheck(a2, ctxStmt)
-		init.Append(a1, a2)
-	}
-	n = finishcompare(n, expr, init)
-	return n
-}
-
-func tracecmpArg(n *Node, t *types.Type, init *Nodes) *Node {
-	// Ugly hack to avoid "constant -1 overflows uintptr" errors, etc.
-	if n.Op == OLITERAL && n.Type.IsSigned() && n.Int64Val() < 0 {
-		n = copyexpr(n, n.Type, init)
-	}
-
-	return conv(n, t)
-}
-
-func walkcompareInterface(n *Node, init *Nodes) *Node {
-	n.Right = cheapexpr(n.Right, init)
-	n.Left = cheapexpr(n.Left, init)
-	eqtab, eqdata := eqinterface(n.Left, n.Right)
-	var cmp *Node
-	if n.Op == OEQ {
-		cmp = nod(OANDAND, eqtab, eqdata)
-	} else {
-		eqtab.Op = ONE
-		cmp = nod(OOROR, eqtab, nod(ONOT, eqdata, nil))
-	}
-	return finishcompare(n, cmp, init)
-}
-
-func walkcompareString(n *Node, init *Nodes) *Node {
-	// Rewrite comparisons to short constant strings as length+byte-wise comparisons.
-	var cs, ncs *Node // const string, non-const string
-	switch {
-	case Isconst(n.Left, CTSTR) && Isconst(n.Right, CTSTR):
-		// ignore; will be constant evaluated
-	case Isconst(n.Left, CTSTR):
-		cs = n.Left
-		ncs = n.Right
-	case Isconst(n.Right, CTSTR):
-		cs = n.Right
-		ncs = n.Left
-	}
-	if cs != nil {
-		cmp := n.Op
-		// Our comparison below assumes that the non-constant string
-		// is on the left hand side, so rewrite "" cmp x to x cmp "".
-		// See issue 24817.
-		if Isconst(n.Left, CTSTR) {
-			cmp = brrev(cmp)
-		}
-
-		// maxRewriteLen was chosen empirically.
-		// It is the value that minimizes cmd/go file size
-		// across most architectures.
-		// See the commit description for CL 26758 for details.
-		maxRewriteLen := 6
-		// Some architectures can load unaligned byte sequence as 1 word.
-		// So we can cover longer strings with the same amount of code.
-		canCombineLoads := canMergeLoads()
-		combine64bit := false
-		if canCombineLoads {
-			// Keep this low enough to generate less code than a function call.
-			maxRewriteLen = 2 * thearch.LinkArch.RegSize
-			combine64bit = thearch.LinkArch.RegSize >= 8
-		}
-
-		var and Op
-		switch cmp {
-		case OEQ:
-			and = OANDAND
-		case ONE:
-			and = OOROR
-		default:
-			// Don't do byte-wise comparisons for <, <=, etc.
-			// They're fairly complicated.
-			// Length-only checks are ok, though.
-			maxRewriteLen = 0
-		}
-		if s := cs.StringVal(); len(s) <= maxRewriteLen {
-			if len(s) > 0 {
-				ncs = safeexpr(ncs, init)
-			}
-			r := nod(cmp, nod(OLEN, ncs, nil), nodintconst(int64(len(s))))
-			remains := len(s)
-			for i := 0; remains > 0; {
-				if remains == 1 || !canCombineLoads {
-					cb := nodintconst(int64(s[i]))
-					ncb := nod(OINDEX, ncs, nodintconst(int64(i)))
-					r = nod(and, r, nod(cmp, ncb, cb))
-					remains--
-					i++
-					continue
-				}
-				var step int
-				var convType *types.Type
-				switch {
-				case remains >= 8 && combine64bit:
-					convType = types.Types[TINT64]
-					step = 8
-				case remains >= 4:
-					convType = types.Types[TUINT32]
-					step = 4
-				case remains >= 2:
-					convType = types.Types[TUINT16]
-					step = 2
-				}
-				ncsubstr := nod(OINDEX, ncs, nodintconst(int64(i)))
-				ncsubstr = conv(ncsubstr, convType)
-				csubstr := int64(s[i])
-				// Calculate large constant from bytes as sequence of shifts and ors.
-				// Like this:  uint32(s[0]) | uint32(s[1])<<8 | uint32(s[2])<<16 ...
-				// ssa will combine this into a single large load.
-				for offset := 1; offset < step; offset++ {
-					b := nod(OINDEX, ncs, nodintconst(int64(i+offset)))
-					b = conv(b, convType)
-					b = nod(OLSH, b, nodintconst(int64(8*offset)))
-					ncsubstr = nod(OOR, ncsubstr, b)
-					csubstr |= int64(s[i+offset]) << uint8(8*offset)
-				}
-				csubstrPart := nodintconst(csubstr)
-				// Compare "step" bytes as once
-				r = nod(and, r, nod(cmp, csubstrPart, ncsubstr))
-				remains -= step
-				i += step
-			}
-			return finishcompare(n, r, init)
-		}
-	}
-
-	var r *Node
-	if n.Op == OEQ || n.Op == ONE {
-		// prepare for rewrite below
-		n.Left = cheapexpr(n.Left, init)
-		n.Right = cheapexpr(n.Right, init)
-		eqlen, eqmem := eqstring(n.Left, n.Right)
-		// quick check of len before full compare for == or !=.
-		// memequal then tests equality up to length len.
-		if n.Op == OEQ {
-			// len(left) == len(right) && memequal(left, right, len)
-			r = nod(OANDAND, eqlen, eqmem)
-		} else {
-			// len(left) != len(right) || !memequal(left, right, len)
-			eqlen.Op = ONE
-			r = nod(OOROR, eqlen, nod(ONOT, eqmem, nil))
-		}
-	} else {
-		// sys_cmpstring(s1, s2) :: 0
-		r = mkcall("cmpstring", types.Types[TINT], init, conv(n.Left, types.Types[TSTRING]), conv(n.Right, types.Types[TSTRING]))
-		r = nod(n.Op, r, nodintconst(0))
-	}
-
-	return finishcompare(n, r, init)
-}
-
-// The result of finishcompare MUST be assigned back to n, e.g.
-// 	n.Left = finishcompare(n.Left, x, r, init)
-func finishcompare(n, r *Node, init *Nodes) *Node {
-	r = typecheck(r, ctxExpr)
-	r = conv(r, n.Type)
-	r = walkexpr(r, init)
-	return r
-}
-
-// return 1 if integer n must be in range [0, max), 0 otherwise
-func bounded(n *Node, max int64) bool {
-	if n.Type == nil || !n.Type.IsInteger() {
-		return false
-	}
-
-	sign := n.Type.IsSigned()
-	bits := int32(8 * n.Type.Width)
-
-	if smallintconst(n) {
-		v := n.Int64Val()
-		return 0 <= v && v < max
-	}
-
-	switch n.Op {
-	case OAND, OANDNOT:
-		v := int64(-1)
-		switch {
-		case smallintconst(n.Left):
-			v = n.Left.Int64Val()
-		case smallintconst(n.Right):
-			v = n.Right.Int64Val()
-			if n.Op == OANDNOT {
-				v = ^v
-				if !sign {
-					v &= 1<<uint(bits) - 1
-				}
-			}
-		}
-		if 0 <= v && v < max {
-			return true
-		}
-
-	case OMOD:
-		if !sign && smallintconst(n.Right) {
-			v := n.Right.Int64Val()
-			if 0 <= v && v <= max {
-				return true
-			}
-		}
-
-	case ODIV:
-		if !sign && smallintconst(n.Right) {
-			v := n.Right.Int64Val()
-			for bits > 0 && v >= 2 {
-				bits--
-				v >>= 1
-			}
-		}
-
-	case ORSH:
-		if !sign && smallintconst(n.Right) {
-			v := n.Right.Int64Val()
-			if v > int64(bits) {
-				return true
-			}
-			bits -= int32(v)
-		}
-	}
-
-	if !sign && bits <= 62 && 1<<uint(bits) <= max {
-		return true
-	}
-
-	return false
-}
-
-// usemethod checks interface method calls for uses of reflect.Type.Method.
-func usemethod(n *Node) {
-	t := n.Left.Type
-
-	// Looking for either of:
-	//	Method(int) reflect.Method
-	//	MethodByName(string) (reflect.Method, bool)
-	//
-	// TODO(crawshaw): improve precision of match by working out
-	//                 how to check the method name.
-	if n := t.NumParams(); n != 1 {
-		return
-	}
-	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.NumResults() == 2 {
-		res1 = t.Results().Field(1)
-	}
-
-	if res1 == nil {
-		if p0.Type.Etype != TINT {
-			return
-		}
-	} else {
-		if !p0.Type.IsString() {
-			return
-		}
-		if !res1.Type.IsBoolean() {
-			return
-		}
-	}
-
-	// Don't mark reflect.(*rtype).Method, etc. themselves in the reflect package.
-	// Those functions may be alive via the itab, which should not cause all methods
-	// alive. We only want to mark their callers.
-	if myimportpath == "reflect" {
-		switch Curfn.Func.Nname.Sym.Name { // TODO: is there a better way than hardcoding the names?
-		case "(*rtype).Method", "(*rtype).MethodByName", "(*interfaceType).Method", "(*interfaceType).MethodByName":
-			return
-		}
-	}
-
-	// Note: Don't rely on res0.Type.String() since its formatting depends on multiple factors
-	//       (including global variables such as numImports - was issue #19028).
-	// Also need to check for reflect package itself (see Issue #38515).
-	if s := res0.Type.Sym; s != nil && s.Name == "Method" && isReflectPkg(s.Pkg) {
-		Curfn.Func.SetReflectMethod(true)
-		// The LSym is initialized at this point. We need to set the attribute on the LSym.
-		Curfn.Func.lsym.Set(obj.AttrReflectMethod, true)
-	}
-}
-
-func usefield(n *Node) {
-	if objabi.Fieldtrack_enabled == 0 {
-		return
-	}
-
-	switch n.Op {
-	default:
-		Fatalf("usefield %v", n.Op)
-
-	case ODOT, ODOTPTR:
-		break
-	}
-	if n.Sym == nil {
-		// No field name.  This DOTPTR was built by the compiler for access
-		// to runtime data structures.  Ignore.
-		return
-	}
-
-	t := n.Left.Type
-	if t.IsPtr() {
-		t = t.Elem()
-	}
-	field := n.Opt().(*types.Field)
-	if field == nil {
-		Fatalf("usefield %v %v without paramfld", n.Left.Type, n.Sym)
-	}
-	if field.Sym != n.Sym || field.Offset != n.Xoffset {
-		Fatalf("field inconsistency: %v,%v != %v,%v", field.Sym, field.Offset, n.Sym, n.Xoffset)
-	}
-	if !strings.Contains(field.Note, "go:\"track\"") {
-		return
-	}
-
-	outer := n.Left.Type
-	if outer.IsPtr() {
-		outer = outer.Elem()
-	}
-	if outer.Sym == nil {
-		yyerror("tracked field must be in named struct type")
-	}
-	if !types.IsExported(field.Sym.Name) {
-		yyerror("tracked field must be exported (upper case)")
-	}
-
-	sym := tracksym(outer, field)
-	if Curfn.Func.FieldTrack == nil {
-		Curfn.Func.FieldTrack = make(map[*types.Sym]struct{})
-	}
-	Curfn.Func.FieldTrack[sym] = struct{}{}
-}
-
-func candiscardlist(l Nodes) bool {
-	for _, n := range l.Slice() {
-		if !candiscard(n) {
-			return false
-		}
-	}
-	return true
-}
-
-func candiscard(n *Node) bool {
-	if n == nil {
-		return true
-	}
-
-	switch n.Op {
-	default:
-		return false
-
-		// Discardable as long as the subpieces are.
-	case ONAME,
-		ONONAME,
-		OTYPE,
-		OPACK,
-		OLITERAL,
-		OADD,
-		OSUB,
-		OOR,
-		OXOR,
-		OADDSTR,
-		OADDR,
-		OANDAND,
-		OBYTES2STR,
-		ORUNES2STR,
-		OSTR2BYTES,
-		OSTR2RUNES,
-		OCAP,
-		OCOMPLIT,
-		OMAPLIT,
-		OSTRUCTLIT,
-		OARRAYLIT,
-		OSLICELIT,
-		OPTRLIT,
-		OCONV,
-		OCONVIFACE,
-		OCONVNOP,
-		ODOT,
-		OEQ,
-		ONE,
-		OLT,
-		OLE,
-		OGT,
-		OGE,
-		OKEY,
-		OSTRUCTKEY,
-		OLEN,
-		OMUL,
-		OLSH,
-		ORSH,
-		OAND,
-		OANDNOT,
-		ONEW,
-		ONOT,
-		OBITNOT,
-		OPLUS,
-		ONEG,
-		OOROR,
-		OPAREN,
-		ORUNESTR,
-		OREAL,
-		OIMAG,
-		OCOMPLEX:
-		break
-
-		// Discardable as long as we know it's not division by zero.
-	case ODIV, OMOD:
-		if Isconst(n.Right, CTINT) && n.Right.Val().U.(*Mpint).CmpInt64(0) != 0 {
-			break
-		}
-		if Isconst(n.Right, CTFLT) && n.Right.Val().U.(*Mpflt).CmpFloat64(0) != 0 {
-			break
-		}
-		return false
-
-		// Discardable as long as we know it won't fail because of a bad size.
-	case OMAKECHAN, OMAKEMAP:
-		if Isconst(n.Left, CTINT) && n.Left.Val().U.(*Mpint).CmpInt64(0) == 0 {
-			break
-		}
-		return false
-
-		// Difficult to tell what sizes are okay.
-	case OMAKESLICE:
-		return false
-
-	case OMAKESLICECOPY:
-		return false
-	}
-
-	if !candiscard(n.Left) || !candiscard(n.Right) || !candiscardlist(n.Ninit) || !candiscardlist(n.Nbody) || !candiscardlist(n.List) || !candiscardlist(n.Rlist) {
-		return false
-	}
-
-	return true
-}
-
-// Rewrite
-//	go builtin(x, y, z)
-// into
-//	go func(a1, a2, a3) {
-//		builtin(a1, a2, a3)
-//	}(x, y, z)
-// for print, println, and delete.
-//
-// Rewrite
-//	go f(x, y, uintptr(unsafe.Pointer(z)))
-// into
-//	go func(a1, a2, a3) {
-//		builtin(a1, a2, uintptr(a3))
-//	}(x, y, unsafe.Pointer(z))
-// for function contains unsafe-uintptr arguments.
-
-var wrapCall_prgen int
-
-// The result of wrapCall MUST be assigned back to n, e.g.
-// 	n.Left = wrapCall(n.Left, init)
-func wrapCall(n *Node, init *Nodes) *Node {
-	if n.Ninit.Len() != 0 {
-		walkstmtlist(n.Ninit.Slice())
-		init.AppendNodes(&n.Ninit)
-	}
-
-	isBuiltinCall := n.Op != OCALLFUNC && n.Op != OCALLMETH && n.Op != OCALLINTER
-
-	// Turn f(a, b, []T{c, d, e}...) back into f(a, b, c, d, e).
-	if !isBuiltinCall && n.IsDDD() {
-		last := n.List.Len() - 1
-		if va := n.List.Index(last); va.Op == OSLICELIT {
-			n.List.Set(append(n.List.Slice()[:last], va.List.Slice()...))
-			n.SetIsDDD(false)
-		}
-	}
-
-	wrapArgs := n.List.Slice()
-	// If there's a receiver argument, it needs to be passed through the wrapper too.
-	if n.Op == OCALLMETH || n.Op == OCALLINTER {
-		recv := n.Left.Left
-		wrapArgs = append([]*Node{recv}, wrapArgs...)
-	}
-
-	// origArgs keeps track of what argument is uintptr-unsafe/unsafe-uintptr conversion.
-	origArgs := make([]*Node, len(wrapArgs))
-	t := nod(OTFUNC, nil, nil)
-	for i, arg := range wrapArgs {
-		s := lookupN("a", i)
-		if !isBuiltinCall && arg.Op == OCONVNOP && arg.Type.IsUintptr() && arg.Left.Type.IsUnsafePtr() {
-			origArgs[i] = arg
-			arg = arg.Left
-			wrapArgs[i] = arg
-		}
-		t.List.Append(symfield(s, arg.Type))
-	}
-
-	wrapCall_prgen++
-	sym := lookupN("wrap·", wrapCall_prgen)
-	fn := dclfunc(sym, t)
-
-	args := paramNnames(t.Type)
-	for i, origArg := range origArgs {
-		if origArg == nil {
-			continue
-		}
-		arg := nod(origArg.Op, args[i], nil)
-		arg.Type = origArg.Type
-		args[i] = arg
-	}
-	if n.Op == OCALLMETH || n.Op == OCALLINTER {
-		// Move wrapped receiver argument back to its appropriate place.
-		recv := typecheck(args[0], ctxExpr)
-		n.Left.Left = recv
-		args = args[1:]
-	}
-	call := nod(n.Op, nil, nil)
-	if !isBuiltinCall {
-		call.Op = OCALL
-		call.Left = n.Left
-		call.SetIsDDD(n.IsDDD())
-	}
-	call.List.Set(args)
-	fn.Nbody.Set1(call)
-
-	funcbody()
-
-	fn = typecheck(fn, ctxStmt)
-	typecheckslice(fn.Nbody.Slice(), ctxStmt)
-	xtop = append(xtop, fn)
-
-	call = nod(OCALL, nil, nil)
-	call.Left = fn.Func.Nname
-	call.List.Set(wrapArgs)
-	call = typecheck(call, ctxStmt)
-	call = walkexpr(call, init)
-	return call
-}
-
-// substArgTypes substitutes the given list of types for
-// successive occurrences of the "any" placeholder in the
-// type syntax expression n.Type.
-// The result of substArgTypes MUST be assigned back to old, e.g.
-// 	n.Left = substArgTypes(n.Left, t1, t2)
-func substArgTypes(old *Node, types_ ...*types.Type) *Node {
-	n := old.copy()
-
-	for _, t := range types_ {
-		dowidth(t)
-	}
-	n.Type = types.SubstAny(n.Type, &types_)
-	if len(types_) > 0 {
-		Fatalf("substArgTypes: too many argument types")
-	}
-	return n
-}
-
-// canMergeLoads reports whether the backend optimization passes for
-// the current architecture can combine adjacent loads into a single
-// larger, possibly unaligned, load. Note that currently the
-// optimizations must be able to handle little endian byte order.
-func canMergeLoads() bool {
-	switch thearch.LinkArch.Family {
-	case sys.ARM64, sys.AMD64, sys.I386, sys.S390X:
-		return true
-	case sys.PPC64:
-		// Load combining only supported on ppc64le.
-		return thearch.LinkArch.ByteOrder == binary.LittleEndian
-	}
-	return false
-}
-
-// isRuneCount reports whether n is of the form len([]rune(string)).
-// These are optimized into a call to runtime.countrunes.
-func isRuneCount(n *Node) bool {
-	return Debug.N == 0 && !instrumenting && n.Op == OLEN && n.Left.Op == OSTR2RUNES
-}
-
-func walkCheckPtrAlignment(n *Node, init *Nodes, count *Node) *Node {
-	if !n.Type.IsPtr() {
-		Fatalf("expected pointer type: %v", n.Type)
-	}
-	elem := n.Type.Elem()
-	if count != nil {
-		if !elem.IsArray() {
-			Fatalf("expected array type: %v", elem)
-		}
-		elem = elem.Elem()
-	}
-
-	size := elem.Size()
-	if elem.Alignment() == 1 && (size == 0 || size == 1 && count == nil) {
-		return n
-	}
-
-	if count == nil {
-		count = nodintconst(1)
-	}
-
-	n.Left = cheapexpr(n.Left, init)
-	init.Append(mkcall("checkptrAlignment", nil, init, convnop(n.Left, types.Types[TUNSAFEPTR]), typename(elem), conv(count, types.Types[TUINTPTR])))
-	return n
-}
-
-var walkCheckPtrArithmeticMarker byte
-
-func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
-	// Calling cheapexpr(n, init) below leads to a recursive call
-	// to walkexpr, which leads us back here again. Use n.Opt to
-	// prevent infinite loops.
-	if opt := n.Opt(); opt == &walkCheckPtrArithmeticMarker {
-		return n
-	} else if opt != nil {
-		// We use n.Opt() here because today it's not used for OCONVNOP. If that changes,
-		// there's no guarantee that temporarily replacing it is safe, so just hard fail here.
-		Fatalf("unexpected Opt: %v", opt)
-	}
-	n.SetOpt(&walkCheckPtrArithmeticMarker)
-	defer n.SetOpt(nil)
-
-	// TODO(mdempsky): Make stricter. We only need to exempt
-	// reflect.Value.Pointer and reflect.Value.UnsafeAddr.
-	switch n.Left.Op {
-	case OCALLFUNC, OCALLMETH, OCALLINTER:
-		return n
-	}
-
-	if n.Left.Op == ODOTPTR && isReflectHeaderDataField(n.Left) {
-		return n
-	}
-
-	// Find original unsafe.Pointer operands involved in this
-	// arithmetic expression.
-	//
-	// "It is valid both to add and to subtract offsets from a
-	// pointer in this way. It is also valid to use &^ to round
-	// pointers, usually for alignment."
-	var originals []*Node
-	var walk func(n *Node)
-	walk = func(n *Node) {
-		switch n.Op {
-		case OADD:
-			walk(n.Left)
-			walk(n.Right)
-		case OSUB, OANDNOT:
-			walk(n.Left)
-		case OCONVNOP:
-			if n.Left.Type.IsUnsafePtr() {
-				n.Left = cheapexpr(n.Left, init)
-				originals = append(originals, convnop(n.Left, types.Types[TUNSAFEPTR]))
-			}
-		}
-	}
-	walk(n.Left)
-
-	n = cheapexpr(n, init)
-
-	slice := mkdotargslice(types.NewSlice(types.Types[TUNSAFEPTR]), originals)
-	slice.Esc = EscNone
-
-	init.Append(mkcall("checkptrArithmetic", nil, init, convnop(n, types.Types[TUNSAFEPTR]), slice))
-	// TODO(khr): Mark backing store of slice as dead. This will allow us to reuse
-	// the backing store for multiple calls to checkptrArithmetic.
-
-	return n
-}
-
-// checkPtr reports whether pointer checking should be enabled for
-// function fn at a given level. See debugHelpFooter for defined
-// levels.
-func checkPtr(fn *Node, level int) bool {
-	return Debug_checkptr >= level && fn.Func.Pragma&NoCheckPtr == 0
-}
diff --git a/src/cmd/compile/internal/gc/zerorange_test.go b/src/cmd/compile/internal/gc/zerorange_test.go
deleted file mode 100644
index 89f4cb9..0000000
--- a/src/cmd/compile/internal/gc/zerorange_test.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
-	"testing"
-)
-
-var glob = 3
-var globp *int64
-
-// Testing compilation of arch.ZeroRange of various sizes.
-
-// By storing a pointer to an int64 output param in a global, the compiler must
-// ensure that output param is allocated on the heap. Also, since there is a
-// defer, the pointer to each output param must be zeroed in the prologue (see
-// plive.go:epilogue()). So, we will get a block of one or more stack slots that
-// need to be zeroed. Hence, we are testing compilation completes successfully when
-// zerorange calls of various sizes (8-136 bytes) are generated. We are not
-// testing runtime correctness (which is hard to do for the current uses of
-// ZeroRange).
-
-func TestZeroRange(t *testing.T) {
-	testZeroRange8(t)
-	testZeroRange16(t)
-	testZeroRange32(t)
-	testZeroRange64(t)
-	testZeroRange136(t)
-}
-
-func testZeroRange8(t *testing.T) (r int64) {
-	defer func() {
-		glob = 4
-	}()
-	globp = &r
-	return
-}
-
-func testZeroRange16(t *testing.T) (r, s int64) {
-	defer func() {
-		glob = 4
-	}()
-	globp = &r
-	globp = &s
-	return
-}
-
-func testZeroRange32(t *testing.T) (r, s, t2, u int64) {
-	defer func() {
-		glob = 4
-	}()
-	globp = &r
-	globp = &s
-	globp = &t2
-	globp = &u
-	return
-}
-
-func testZeroRange64(t *testing.T) (r, s, t2, u, v, w, x, y int64) {
-	defer func() {
-		glob = 4
-	}()
-	globp = &r
-	globp = &s
-	globp = &t2
-	globp = &u
-	globp = &v
-	globp = &w
-	globp = &x
-	globp = &y
-	return
-}
-
-func testZeroRange136(t *testing.T) (r, s, t2, u, v, w, x, y, r1, s1, t1, u1, v1, w1, x1, y1, z1 int64) {
-	defer func() {
-		glob = 4
-	}()
-	globp = &r
-	globp = &s
-	globp = &t2
-	globp = &u
-	globp = &v
-	globp = &w
-	globp = &x
-	globp = &y
-	globp = &r1
-	globp = &s1
-	globp = &t1
-	globp = &u1
-	globp = &v1
-	globp = &w1
-	globp = &x1
-	globp = &y1
-	globp = &z1
-	return
-}
diff --git a/src/cmd/compile/internal/importer/exportdata.go b/src/cmd/compile/internal/importer/exportdata.go
new file mode 100644
index 0000000..3925a64
--- /dev/null
+++ b/src/cmd/compile/internal/importer/exportdata.go
@@ -0,0 +1,92 @@
+// UNREVIEWED
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements FindExportData.
+
+package importer
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"strconv"
+	"strings"
+)
+
+func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
+	// See $GOROOT/include/ar.h.
+	hdr := make([]byte, 16+12+6+6+8+10+2)
+	_, err = io.ReadFull(r, hdr)
+	if err != nil {
+		return
+	}
+	// leave for debugging
+	if false {
+		fmt.Printf("header: %s", hdr)
+	}
+	s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
+	size, err = strconv.Atoi(s)
+	if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
+		err = fmt.Errorf("invalid archive header")
+		return
+	}
+	name = strings.TrimSpace(string(hdr[:16]))
+	return
+}
+
+// FindExportData positions the reader r at the beginning of the
+// export data section of an underlying GC-created object/archive
+// file by reading from it. The reader must be positioned at the
+// start of the file before calling this function. The hdr result
+// is the string before the export data, either "$$" or "$$B".
+//
+func FindExportData(r *bufio.Reader) (hdr string, err error) {
+	// Read first line to make sure this is an object file.
+	line, err := r.ReadSlice('\n')
+	if err != nil {
+		err = fmt.Errorf("can't find export data (%v)", err)
+		return
+	}
+
+	if string(line) == "!<arch>\n" {
+		// Archive file. Scan to __.PKGDEF.
+		var name string
+		if name, _, err = readGopackHeader(r); err != nil {
+			return
+		}
+
+		// First entry should be __.PKGDEF.
+		if name != "__.PKGDEF" {
+			err = fmt.Errorf("go archive is missing __.PKGDEF")
+			return
+		}
+
+		// Read first line of __.PKGDEF data, so that line
+		// is once again the first line of the input.
+		if line, err = r.ReadSlice('\n'); err != nil {
+			err = fmt.Errorf("can't find export data (%v)", err)
+			return
+		}
+	}
+
+	// Now at __.PKGDEF in archive or still at beginning of file.
+	// Either way, line should begin with "go object ".
+	if !strings.HasPrefix(string(line), "go object ") {
+		err = fmt.Errorf("not a Go object file")
+		return
+	}
+
+	// Skip over object header to export data.
+	// Begins after first line starting with $$.
+	for line[0] != '$' {
+		if line, err = r.ReadSlice('\n'); err != nil {
+			err = fmt.Errorf("can't find export data (%v)", err)
+			return
+		}
+	}
+	hdr = string(line)
+
+	return
+}
diff --git a/src/cmd/compile/internal/importer/gcimporter.go b/src/cmd/compile/internal/importer/gcimporter.go
new file mode 100644
index 0000000..feb18cf
--- /dev/null
+++ b/src/cmd/compile/internal/importer/gcimporter.go
@@ -0,0 +1,175 @@
+// UNREVIEWED
+// Copyright 2011 The Go Authors. 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 implements Import for gc-generated object files.
+package importer
+
+import (
+	"bufio"
+	"cmd/compile/internal/types2"
+	"fmt"
+	"go/build"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+// debugging/development support
+const debug = false
+
+var pkgExts = [...]string{".a", ".o"}
+
+// FindPkg returns the filename and unique package id for an import
+// path based on package information provided by build.Import (using
+// the build.Default build.Context). A relative srcDir is interpreted
+// relative to the current working directory.
+// If no file was found, an empty filename is returned.
+//
+func FindPkg(path, srcDir string) (filename, id string) {
+	if path == "" {
+		return
+	}
+
+	var noext string
+	switch {
+	default:
+		// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
+		// Don't require the source files to be present.
+		if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
+			srcDir = abs
+		}
+		bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
+		if bp.PkgObj == "" {
+			id = path // make sure we have an id to print in error message
+			return
+		}
+		noext = strings.TrimSuffix(bp.PkgObj, ".a")
+		id = bp.ImportPath
+
+	case build.IsLocalImport(path):
+		// "./x" -> "/this/directory/x.ext", "/this/directory/x"
+		noext = filepath.Join(srcDir, path)
+		id = noext
+
+	case filepath.IsAbs(path):
+		// for completeness only - go/build.Import
+		// does not support absolute imports
+		// "/x" -> "/x.ext", "/x"
+		noext = path
+		id = path
+	}
+
+	if false { // for debugging
+		if path != id {
+			fmt.Printf("%s -> %s\n", path, id)
+		}
+	}
+
+	// try extensions
+	for _, ext := range pkgExts {
+		filename = noext + ext
+		if f, err := os.Stat(filename); err == nil && !f.IsDir() {
+			return
+		}
+	}
+
+	filename = "" // not found
+	return
+}
+
+// Import imports a gc-generated package given its import path and srcDir, adds
+// 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]*types2.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types2.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 types2.Unsafe, nil
+		}
+		id = path
+
+		// 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 types2.Unsafe, nil
+			}
+			return nil, fmt.Errorf("can't find import: %q", id)
+		}
+
+		// 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 rc.Close()
+
+	var hdr string
+	buf := bufio.NewReader(rc)
+	if hdr, err = FindExportData(buf); err != nil {
+		return
+	}
+
+	switch hdr {
+	case "$$\n":
+		err = fmt.Errorf("import %q: old textual export format no longer supported (recompile library)", path)
+
+	case "$$B\n":
+		var data []byte
+		data, err = ioutil.ReadAll(buf)
+		if err != nil {
+			break
+		}
+
+		// The indexed export format starts with an 'i'; the older
+		// binary export format starts with a 'c', 'd', or 'v'
+		// (from "version"). Select appropriate importer.
+		if len(data) > 0 && data[0] == 'i' {
+			_, pkg, err = iImportData(packages, data[1:], id)
+		} else {
+			err = fmt.Errorf("import %q: old binary export format no longer supported (recompile library)", path)
+		}
+
+	default:
+		err = fmt.Errorf("import %q: unknown export data header: %q", path, hdr)
+	}
+
+	return
+}
+
+type byPath []*types2.Package
+
+func (a byPath) Len() int           { return len(a) }
+func (a byPath) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
diff --git a/src/cmd/compile/internal/importer/gcimporter_test.go b/src/cmd/compile/internal/importer/gcimporter_test.go
new file mode 100644
index 0000000..7fb8fed
--- /dev/null
+++ b/src/cmd/compile/internal/importer/gcimporter_test.go
@@ -0,0 +1,611 @@
+// UNREVIEWED
+// Copyright 2011 The Go Authors. 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 (
+	"bytes"
+	"cmd/compile/internal/types2"
+	"fmt"
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+	"time"
+)
+
+// skipSpecialPlatforms causes the test to be skipped for platforms where
+// builders (build.golang.org) don't have access to compiled packages for
+// import.
+func skipSpecialPlatforms(t *testing.T) {
+	switch platform := runtime.GOOS + "-" + runtime.GOARCH; platform {
+	case "darwin-arm64":
+		t.Skipf("no compiled packages available for import on %s", platform)
+	}
+}
+
+// compile runs the compiler on filename, with dirname as the working directory,
+// and writes the output file to outdirname.
+func compile(t *testing.T, dirname, filename, outdirname string) string {
+	// filename must end with ".go"
+	if !strings.HasSuffix(filename, ".go") {
+		t.Fatalf("filename doesn't end in .go: %s", filename)
+	}
+	basename := filepath.Base(filename)
+	outname := filepath.Join(outdirname, basename[:len(basename)-2]+"o")
+	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-o", outname, filename)
+	cmd.Dir = dirname
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Logf("%s", out)
+		t.Fatalf("go tool compile %s failed: %s", filename, err)
+	}
+	return outname
+}
+
+func testPath(t *testing.T, path, srcDir string) *types2.Package {
+	t0 := time.Now()
+	pkg, err := Import(make(map[string]*types2.Package), path, srcDir, nil)
+	if err != nil {
+		t.Errorf("testPath(%s): %s", path, err)
+		return nil
+	}
+	t.Logf("testPath(%s): %v", path, time.Since(t0))
+	return pkg
+}
+
+const maxTime = 30 * time.Second
+
+func testDir(t *testing.T, dir string, endTime time.Time) (nimports int) {
+	dirname := filepath.Join(runtime.GOROOT(), "pkg", runtime.GOOS+"_"+runtime.GOARCH, dir)
+	list, err := ioutil.ReadDir(dirname)
+	if err != nil {
+		t.Fatalf("testDir(%s): %s", dirname, err)
+	}
+	for _, f := range list {
+		if time.Now().After(endTime) {
+			t.Log("testing time used up")
+			return
+		}
+		switch {
+		case !f.IsDir():
+			// try extensions
+			for _, ext := range pkgExts {
+				if strings.HasSuffix(f.Name(), ext) {
+					name := f.Name()[0 : len(f.Name())-len(ext)] // remove extension
+					if testPath(t, filepath.Join(dir, name), dir) != nil {
+						nimports++
+					}
+				}
+			}
+		case f.IsDir():
+			nimports += testDir(t, filepath.Join(dir, f.Name()), endTime)
+		}
+	}
+	return
+}
+
+func mktmpdir(t *testing.T) string {
+	tmpdir, err := ioutil.TempDir("", "gcimporter_test")
+	if err != nil {
+		t.Fatal("mktmpdir:", err)
+	}
+	if err := os.Mkdir(filepath.Join(tmpdir, "testdata"), 0700); err != nil {
+		os.RemoveAll(tmpdir)
+		t.Fatal("mktmpdir:", err)
+	}
+	return tmpdir
+}
+
+func TestImportTestdata(t *testing.T) {
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	tmpdir := mktmpdir(t)
+	defer os.RemoveAll(tmpdir)
+
+	compile(t, "testdata", "exports.go", filepath.Join(tmpdir, "testdata"))
+
+	if pkg := testPath(t, "./testdata/exports", tmpdir); pkg != nil {
+		// The package's Imports list must include all packages
+		// explicitly imported by exports.go, plus all packages
+		// referenced indirectly via exported objects in exports.go.
+		// With the textual export format, the list may also include
+		// additional packages that are not strictly required for
+		// import processing alone (they are exported to err "on
+		// the safe side").
+		// TODO(gri) update the want list to be precise, now that
+		// the textual export data is gone.
+		got := fmt.Sprint(pkg.Imports())
+		for _, want := range []string{"go/ast", "go/token"} {
+			if !strings.Contains(got, want) {
+				t.Errorf(`Package("exports").Imports() = %s, does not contain %s`, got, want)
+			}
+		}
+	}
+}
+
+func TestVersionHandling(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	const dir = "./testdata/versions"
+	list, err := ioutil.ReadDir(dir)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	tmpdir := mktmpdir(t)
+	defer os.RemoveAll(tmpdir)
+	corruptdir := filepath.Join(tmpdir, "testdata", "versions")
+	if err := os.Mkdir(corruptdir, 0700); err != nil {
+		t.Fatal(err)
+	}
+
+	for _, f := range list {
+		name := f.Name()
+		if !strings.HasSuffix(name, ".a") {
+			continue // not a package file
+		}
+		if strings.Contains(name, "corrupted") {
+			continue // don't process a leftover corrupted file
+		}
+		pkgpath := "./" + name[:len(name)-2]
+
+		if testing.Verbose() {
+			t.Logf("importing %s", name)
+		}
+
+		// test that export data can be imported
+		_, err := Import(make(map[string]*types2.Package), pkgpath, dir, nil)
+		if err != nil {
+			// ok to fail if it fails with a no longer supported error for select files
+			if strings.Contains(err.Error(), "no longer supported") {
+				switch name {
+				case "test_go1.7_0.a", "test_go1.7_1.a",
+					"test_go1.8_4.a", "test_go1.8_5.a",
+					"test_go1.11_6b.a", "test_go1.11_999b.a":
+					continue
+				}
+				// fall through
+			}
+			// ok to fail if it fails with a newer version error for select files
+			if strings.Contains(err.Error(), "newer version") {
+				switch name {
+				case "test_go1.11_999i.a":
+					continue
+				}
+				// fall through
+			}
+			t.Errorf("import %q failed: %v", pkgpath, err)
+			continue
+		}
+
+		// create file with corrupted export data
+		// 1) read file
+		data, err := ioutil.ReadFile(filepath.Join(dir, name))
+		if err != nil {
+			t.Fatal(err)
+		}
+		// 2) find export data
+		i := bytes.Index(data, []byte("\n$$B\n")) + 5
+		j := bytes.Index(data[i:], []byte("\n$$\n")) + i
+		if i < 0 || j < 0 || i > j {
+			t.Fatalf("export data section not found (i = %d, j = %d)", i, j)
+		}
+		// 3) corrupt the data (increment every 7th byte)
+		for k := j - 13; k >= i; k -= 7 {
+			data[k]++
+		}
+		// 4) write the file
+		pkgpath += "_corrupted"
+		filename := filepath.Join(corruptdir, pkgpath) + ".a"
+		ioutil.WriteFile(filename, data, 0666)
+
+		// test that importing the corrupted file results in an error
+		_, err = Import(make(map[string]*types2.Package), pkgpath, corruptdir, nil)
+		if err == nil {
+			t.Errorf("import corrupted %q succeeded", pkgpath)
+		} else if msg := err.Error(); !strings.Contains(msg, "version skew") {
+			t.Errorf("import %q error incorrect (%s)", pkgpath, msg)
+		}
+	}
+}
+
+func TestImportStdLib(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	dt := maxTime
+	if testing.Short() && testenv.Builder() == "" {
+		dt = 10 * time.Millisecond
+	}
+	nimports := testDir(t, "", time.Now().Add(dt)) // installed packages
+	t.Logf("tested %d imports", nimports)
+}
+
+var importedObjectTests = []struct {
+	name string
+	want string
+}{
+	// non-interfaces
+	{"crypto.Hash", "type Hash uint"},
+	{"go/ast.ObjKind", "type ObjKind int"},
+	{"go/types.Qualifier", "type Qualifier func(*Package) string"},
+	{"go/types.Comparable", "func Comparable(T Type) bool"},
+	{"math.Pi", "const Pi untyped float"},
+	{"math.Sin", "func Sin(x float64) float64"},
+	{"go/ast.NotNilFilter", "func NotNilFilter(_ string, v reflect.Value) bool"},
+	{"go/internal/gcimporter.FindPkg", "func FindPkg(path string, srcDir string) (filename string, id string)"},
+
+	// interfaces
+	{"context.Context", "type Context interface{Deadline() (deadline time.Time, ok bool); Done() <-chan struct{}; Err() error; Value(key interface{}) interface{}}"},
+	{"crypto.Decrypter", "type Decrypter interface{Decrypt(rand io.Reader, msg []byte, opts DecrypterOpts) (plaintext []byte, err error); Public() PublicKey}"},
+	{"encoding.BinaryMarshaler", "type BinaryMarshaler interface{MarshalBinary() (data []byte, err error)}"},
+	{"io.Reader", "type Reader interface{Read(p []byte) (n int, err error)}"},
+	{"io.ReadWriter", "type ReadWriter interface{Reader; Writer}"},
+	{"go/ast.Node", "type Node interface{End() go/token.Pos; Pos() go/token.Pos}"},
+	// go/types.Type has grown much larger - excluded for now
+	// {"go/types.Type", "type Type interface{String() string; Underlying() Type}"},
+}
+
+func TestImportedTypes(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	for _, test := range importedObjectTests {
+		s := strings.Split(test.name, ".")
+		if len(s) != 2 {
+			t.Fatal("inconsistent test data")
+		}
+		importPath := s[0]
+		objName := s[1]
+
+		pkg, err := Import(make(map[string]*types2.Package), importPath, ".", nil)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+
+		obj := pkg.Scope().Lookup(objName)
+		if obj == nil {
+			t.Errorf("%s: object not found", test.name)
+			continue
+		}
+
+		got := types2.ObjectString(obj, types2.RelativeTo(pkg))
+		if got != test.want {
+			t.Errorf("%s: got %q; want %q", test.name, got, test.want)
+		}
+
+		if named, _ := obj.Type().(*types2.Named); named != nil {
+			verifyInterfaceMethodRecvs(t, named, 0)
+		}
+	}
+}
+
+// verifyInterfaceMethodRecvs verifies that method receiver types
+// are named if the methods belong to a named interface type.
+func verifyInterfaceMethodRecvs(t *testing.T, named *types2.Named, level int) {
+	// avoid endless recursion in case of an embedding bug that lead to a cycle
+	if level > 10 {
+		t.Errorf("%s: embeds itself", named)
+		return
+	}
+
+	iface, _ := named.Underlying().(*types2.Interface)
+	if iface == nil {
+		return // not an interface
+	}
+
+	// check explicitly declared methods
+	for i := 0; i < iface.NumExplicitMethods(); i++ {
+		m := iface.ExplicitMethod(i)
+		recv := m.Type().(*types2.Signature).Recv()
+		if recv == nil {
+			t.Errorf("%s: missing receiver type", m)
+			continue
+		}
+		if recv.Type() != named {
+			t.Errorf("%s: got recv type %s; want %s", m, recv.Type(), named)
+		}
+	}
+
+	// check embedded interfaces (if they are named, too)
+	for i := 0; i < iface.NumEmbeddeds(); i++ {
+		// embedding of interfaces cannot have cycles; recursion will terminate
+		if etype, _ := iface.EmbeddedType(i).(*types2.Named); etype != nil {
+			verifyInterfaceMethodRecvs(t, etype, level+1)
+		}
+	}
+}
+
+func TestIssue5815(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	pkg := importPkg(t, "strings", ".")
+
+	scope := pkg.Scope()
+	for _, name := range scope.Names() {
+		obj := scope.Lookup(name)
+		if obj.Pkg() == nil {
+			t.Errorf("no pkg for %s", obj)
+		}
+		if tname, _ := obj.(*types2.TypeName); tname != nil {
+			named := tname.Type().(*types2.Named)
+			for i := 0; i < named.NumMethods(); i++ {
+				m := named.Method(i)
+				if m.Pkg() == nil {
+					t.Errorf("no pkg for %s", m)
+				}
+			}
+		}
+	}
+}
+
+// Smoke test to ensure that imported methods get the correct package.
+func TestCorrectMethodPackage(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	imports := make(map[string]*types2.Package)
+	_, err := Import(imports, "net/http", ".", nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	mutex := imports["sync"].Scope().Lookup("Mutex").(*types2.TypeName).Type()
+	obj, _, _ := types2.LookupFieldOrMethod(types2.NewPointer(mutex), false, nil, "Lock")
+	lock := obj.(*types2.Func)
+	if got, want := lock.Pkg().Path(), "sync"; got != want {
+		t.Errorf("got package path %q; want %q", got, want)
+	}
+}
+
+func TestIssue13566(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	// On windows, we have to set the -D option for the compiler to avoid having a drive
+	// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
+	if runtime.GOOS == "windows" {
+		t.Skip("avoid dealing with relative paths/drive letters on windows")
+	}
+
+	tmpdir := mktmpdir(t)
+	defer os.RemoveAll(tmpdir)
+	testoutdir := filepath.Join(tmpdir, "testdata")
+
+	// b.go needs to be compiled from the output directory so that the compiler can
+	// find the compiled package a. We pass the full path to compile() so that we
+	// don't have to copy the file to that directory.
+	bpath, err := filepath.Abs(filepath.Join("testdata", "b.go"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	compile(t, "testdata", "a.go", testoutdir)
+	compile(t, testoutdir, bpath, testoutdir)
+
+	// import must succeed (test for issue at hand)
+	pkg := importPkg(t, "./testdata/b", tmpdir)
+
+	// make sure all indirectly imported packages have names
+	for _, imp := range pkg.Imports() {
+		if imp.Name() == "" {
+			t.Errorf("no name for %s package", imp.Path())
+		}
+	}
+}
+
+func TestIssue13898(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	// import go/internal/gcimporter which imports go/types partially
+	imports := make(map[string]*types2.Package)
+	_, err := Import(imports, "go/internal/gcimporter", ".", nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// look for go/types package
+	var goTypesPkg *types2.Package
+	for path, pkg := range imports {
+		if path == "go/types" {
+			goTypesPkg = pkg
+			break
+		}
+	}
+	if goTypesPkg == nil {
+		t.Fatal("go/types not found")
+	}
+
+	// look for go/types2.Object type
+	obj := lookupObj(t, goTypesPkg.Scope(), "Object")
+	typ, ok := obj.Type().(*types2.Named)
+	if !ok {
+		t.Fatalf("go/types2.Object type is %v; wanted named type", typ)
+	}
+
+	// lookup go/types2.Object.Pkg method
+	m, index, indirect := types2.LookupFieldOrMethod(typ, false, nil, "Pkg")
+	if m == nil {
+		t.Fatalf("go/types2.Object.Pkg not found (index = %v, indirect = %v)", index, indirect)
+	}
+
+	// the method must belong to go/types
+	if m.Pkg().Path() != "go/types" {
+		t.Fatalf("found %v; want go/types", m.Pkg())
+	}
+}
+
+func TestIssue15517(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	// On windows, we have to set the -D option for the compiler to avoid having a drive
+	// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
+	if runtime.GOOS == "windows" {
+		t.Skip("avoid dealing with relative paths/drive letters on windows")
+	}
+
+	tmpdir := mktmpdir(t)
+	defer os.RemoveAll(tmpdir)
+
+	compile(t, "testdata", "p.go", filepath.Join(tmpdir, "testdata"))
+
+	// Multiple imports of p must succeed without redeclaration errors.
+	// We use an import path that's not cleaned up so that the eventual
+	// file path for the package is different from the package path; this
+	// will expose the error if it is present.
+	//
+	// (Issue: Both the textual and the binary importer used the file path
+	// of the package to be imported as key into the shared packages map.
+	// However, the binary importer then used the package path to identify
+	// the imported package to mark it as complete; effectively marking the
+	// wrong package as complete. By using an "unclean" package path, the
+	// file and package path are different, exposing the problem if present.
+	// The same issue occurs with vendoring.)
+	imports := make(map[string]*types2.Package)
+	for i := 0; i < 3; i++ {
+		if _, err := Import(imports, "./././testdata/p", tmpdir, nil); err != nil {
+			t.Fatal(err)
+		}
+	}
+}
+
+func TestIssue15920(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	// On windows, we have to set the -D option for the compiler to avoid having a drive
+	// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
+	if runtime.GOOS == "windows" {
+		t.Skip("avoid dealing with relative paths/drive letters on windows")
+	}
+
+	compileAndImportPkg(t, "issue15920")
+}
+
+func TestIssue20046(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	// On windows, we have to set the -D option for the compiler to avoid having a drive
+	// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
+	if runtime.GOOS == "windows" {
+		t.Skip("avoid dealing with relative paths/drive letters on windows")
+	}
+
+	// "./issue20046".V.M must exist
+	pkg := compileAndImportPkg(t, "issue20046")
+	obj := lookupObj(t, pkg.Scope(), "V")
+	if m, index, indirect := types2.LookupFieldOrMethod(obj.Type(), false, nil, "M"); m == nil {
+		t.Fatalf("V.M not found (index = %v, indirect = %v)", index, indirect)
+	}
+}
+func TestIssue25301(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	// On windows, we have to set the -D option for the compiler to avoid having a drive
+	// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
+	if runtime.GOOS == "windows" {
+		t.Skip("avoid dealing with relative paths/drive letters on windows")
+	}
+
+	compileAndImportPkg(t, "issue25301")
+}
+
+func TestIssue25596(t *testing.T) {
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	// On windows, we have to set the -D option for the compiler to avoid having a drive
+	// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
+	if runtime.GOOS == "windows" {
+		t.Skip("avoid dealing with relative paths/drive letters on windows")
+	}
+
+	compileAndImportPkg(t, "issue25596")
+}
+
+func importPkg(t *testing.T, path, srcDir string) *types2.Package {
+	pkg, err := Import(make(map[string]*types2.Package), path, srcDir, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return pkg
+}
+
+func compileAndImportPkg(t *testing.T, name string) *types2.Package {
+	tmpdir := mktmpdir(t)
+	defer os.RemoveAll(tmpdir)
+	compile(t, "testdata", name+".go", filepath.Join(tmpdir, "testdata"))
+	return importPkg(t, "./testdata/"+name, tmpdir)
+}
+
+func lookupObj(t *testing.T, scope *types2.Scope, name string) types2.Object {
+	if obj := scope.Lookup(name); obj != nil {
+		return obj
+	}
+	t.Fatalf("%s not found", name)
+	return nil
+}
diff --git a/src/cmd/compile/internal/importer/iimport.go b/src/cmd/compile/internal/importer/iimport.go
new file mode 100644
index 0000000..8ab0b7b
--- /dev/null
+++ b/src/cmd/compile/internal/importer/iimport.go
@@ -0,0 +1,612 @@
+// UNREVIEWED
+// 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.
+
+// Indexed package import.
+// See cmd/compile/internal/typecheck/iexport.go for the export data format.
+
+package importer
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/types2"
+	"encoding/binary"
+	"fmt"
+	"go/constant"
+	"go/token"
+	"io"
+	"math/big"
+	"sort"
+)
+
+type intReader struct {
+	*bytes.Reader
+	path string
+}
+
+func (r *intReader) int64() int64 {
+	i, err := binary.ReadVarint(r.Reader)
+	if err != nil {
+		errorf("import %q: read varint error: %v", r.path, err)
+	}
+	return i
+}
+
+func (r *intReader) uint64() uint64 {
+	i, err := binary.ReadUvarint(r.Reader)
+	if err != nil {
+		errorf("import %q: read varint error: %v", r.path, err)
+	}
+	return i
+}
+
+const predeclReserved = 32
+
+type itag uint64
+
+const (
+	// Types
+	definedType itag = iota
+	pointerType
+	sliceType
+	arrayType
+	chanType
+	mapType
+	signatureType
+	structType
+	interfaceType
+)
+
+const io_SeekCurrent = 1 // io.SeekCurrent (not defined in Go 1.4)
+
+// iImportData imports a package from the serialized package data
+// and returns the number of bytes consumed and a reference to the package.
+// If the export data version is not recognized or the format is otherwise
+// compromised, an error is returned.
+func iImportData(imports map[string]*types2.Package, data []byte, path string) (_ int, pkg *types2.Package, err error) {
+	const currentVersion = 1
+	version := int64(-1)
+	defer func() {
+		if e := recover(); e != nil {
+			if version > currentVersion {
+				err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
+			} else {
+				err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
+			}
+		}
+	}()
+
+	r := &intReader{bytes.NewReader(data), path}
+
+	version = int64(r.uint64())
+	switch version {
+	case currentVersion, 0:
+	default:
+		errorf("unknown iexport format version %d", version)
+	}
+
+	sLen := int64(r.uint64())
+	dLen := int64(r.uint64())
+
+	whence, _ := r.Seek(0, io_SeekCurrent)
+	stringData := data[whence : whence+sLen]
+	declData := data[whence+sLen : whence+sLen+dLen]
+	r.Seek(sLen+dLen, io_SeekCurrent)
+
+	p := iimporter{
+		ipath:   path,
+		version: int(version),
+
+		stringData:  stringData,
+		stringCache: make(map[uint64]string),
+		pkgCache:    make(map[uint64]*types2.Package),
+
+		declData: declData,
+		pkgIndex: make(map[*types2.Package]map[string]uint64),
+		typCache: make(map[uint64]types2.Type),
+	}
+
+	for i, pt := range predeclared {
+		p.typCache[uint64(i)] = pt
+	}
+
+	pkgList := make([]*types2.Package, r.uint64())
+	for i := range pkgList {
+		pkgPathOff := r.uint64()
+		pkgPath := p.stringAt(pkgPathOff)
+		pkgName := p.stringAt(r.uint64())
+		_ = r.uint64() // package height; unused by go/types
+
+		if pkgPath == "" {
+			pkgPath = path
+		}
+		pkg := imports[pkgPath]
+		if pkg == nil {
+			pkg = types2.NewPackage(pkgPath, pkgName)
+			imports[pkgPath] = pkg
+		} else if pkg.Name() != pkgName {
+			errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
+		}
+
+		p.pkgCache[pkgPathOff] = pkg
+
+		nameIndex := make(map[string]uint64)
+		for nSyms := r.uint64(); nSyms > 0; nSyms-- {
+			name := p.stringAt(r.uint64())
+			nameIndex[name] = r.uint64()
+		}
+
+		p.pkgIndex[pkg] = nameIndex
+		pkgList[i] = pkg
+	}
+
+	localpkg := pkgList[0]
+
+	names := make([]string, 0, len(p.pkgIndex[localpkg]))
+	for name := range p.pkgIndex[localpkg] {
+		names = append(names, name)
+	}
+	sort.Strings(names)
+	for _, name := range names {
+		p.doDecl(localpkg, name)
+	}
+
+	for _, typ := range p.interfaceList {
+		typ.Complete()
+	}
+
+	// record all referenced packages as imports
+	list := append(([]*types2.Package)(nil), pkgList[1:]...)
+	sort.Sort(byPath(list))
+	localpkg.SetImports(list)
+
+	// package was imported completely and without errors
+	localpkg.MarkComplete()
+
+	consumed, _ := r.Seek(0, io_SeekCurrent)
+	return int(consumed), localpkg, nil
+}
+
+type iimporter struct {
+	ipath   string
+	version int
+
+	stringData  []byte
+	stringCache map[uint64]string
+	pkgCache    map[uint64]*types2.Package
+
+	declData []byte
+	pkgIndex map[*types2.Package]map[string]uint64
+	typCache map[uint64]types2.Type
+
+	interfaceList []*types2.Interface
+}
+
+func (p *iimporter) doDecl(pkg *types2.Package, name string) {
+	// See if we've already imported this declaration.
+	if obj := pkg.Scope().Lookup(name); obj != nil {
+		return
+	}
+
+	off, ok := p.pkgIndex[pkg][name]
+	if !ok {
+		errorf("%v.%v not in index", pkg, name)
+	}
+
+	r := &importReader{p: p, currPkg: pkg}
+	// Reader.Reset is not available in Go 1.4.
+	// Use bytes.NewReader for now.
+	// r.declReader.Reset(p.declData[off:])
+	r.declReader = *bytes.NewReader(p.declData[off:])
+
+	r.obj(name)
+}
+
+func (p *iimporter) stringAt(off uint64) string {
+	if s, ok := p.stringCache[off]; ok {
+		return s
+	}
+
+	slen, n := binary.Uvarint(p.stringData[off:])
+	if n <= 0 {
+		errorf("varint failed")
+	}
+	spos := off + uint64(n)
+	s := string(p.stringData[spos : spos+slen])
+	p.stringCache[off] = s
+	return s
+}
+
+func (p *iimporter) pkgAt(off uint64) *types2.Package {
+	if pkg, ok := p.pkgCache[off]; ok {
+		return pkg
+	}
+	path := p.stringAt(off)
+	errorf("missing package %q in %q", path, p.ipath)
+	return nil
+}
+
+func (p *iimporter) typAt(off uint64, base *types2.Named) types2.Type {
+	if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) {
+		return t
+	}
+
+	if off < predeclReserved {
+		errorf("predeclared type missing from cache: %v", off)
+	}
+
+	r := &importReader{p: p}
+	// Reader.Reset is not available in Go 1.4.
+	// Use bytes.NewReader for now.
+	// r.declReader.Reset(p.declData[off-predeclReserved:])
+	r.declReader = *bytes.NewReader(p.declData[off-predeclReserved:])
+	t := r.doType(base)
+
+	if base == nil || !isInterface(t) {
+		p.typCache[off] = t
+	}
+	return t
+}
+
+type importReader struct {
+	p          *iimporter
+	declReader bytes.Reader
+	currPkg    *types2.Package
+	prevFile   string
+	prevLine   int64
+	prevColumn int64
+}
+
+func (r *importReader) obj(name string) {
+	tag := r.byte()
+	pos := r.pos()
+
+	switch tag {
+	case 'A':
+		typ := r.typ()
+
+		r.declare(types2.NewTypeName(pos, r.currPkg, name, typ))
+
+	case 'C':
+		typ, val := r.value()
+
+		r.declare(types2.NewConst(pos, r.currPkg, name, typ, val))
+
+	case 'F':
+		sig := r.signature(nil)
+
+		r.declare(types2.NewFunc(pos, r.currPkg, name, sig))
+
+	case 'T':
+		// Types can be recursive. We need to setup a stub
+		// declaration before recursing.
+		obj := types2.NewTypeName(pos, r.currPkg, name, nil)
+		named := types2.NewNamed(obj, nil, nil)
+		r.declare(obj)
+
+		underlying := r.p.typAt(r.uint64(), named).Underlying()
+		named.SetUnderlying(underlying)
+
+		if !isInterface(underlying) {
+			for n := r.uint64(); n > 0; n-- {
+				mpos := r.pos()
+				mname := r.ident()
+				recv := r.param()
+				msig := r.signature(recv)
+
+				named.AddMethod(types2.NewFunc(mpos, r.currPkg, mname, msig))
+			}
+		}
+
+	case 'V':
+		typ := r.typ()
+
+		r.declare(types2.NewVar(pos, r.currPkg, name, typ))
+
+	default:
+		errorf("unexpected tag: %v", tag)
+	}
+}
+
+func (r *importReader) declare(obj types2.Object) {
+	obj.Pkg().Scope().Insert(obj)
+}
+
+func (r *importReader) value() (typ types2.Type, val constant.Value) {
+	typ = r.typ()
+
+	switch b := typ.Underlying().(*types2.Basic); b.Info() & types2.IsConstType {
+	case types2.IsBoolean:
+		val = constant.MakeBool(r.bool())
+
+	case types2.IsString:
+		val = constant.MakeString(r.string())
+
+	case types2.IsInteger:
+		var x big.Int
+		r.mpint(&x, b)
+		val = constant.Make(&x)
+
+	case types2.IsFloat:
+		val = r.mpfloat(b)
+
+	case types2.IsComplex:
+		re := r.mpfloat(b)
+		im := r.mpfloat(b)
+		val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+
+	default:
+		errorf("unexpected type %v", typ) // panics
+		panic("unreachable")
+	}
+
+	return
+}
+
+func intSize(b *types2.Basic) (signed bool, maxBytes uint) {
+	if (b.Info() & types2.IsUntyped) != 0 {
+		return true, 64
+	}
+
+	switch b.Kind() {
+	case types2.Float32, types2.Complex64:
+		return true, 3
+	case types2.Float64, types2.Complex128:
+		return true, 7
+	}
+
+	signed = (b.Info() & types2.IsUnsigned) == 0
+	switch b.Kind() {
+	case types2.Int8, types2.Uint8:
+		maxBytes = 1
+	case types2.Int16, types2.Uint16:
+		maxBytes = 2
+	case types2.Int32, types2.Uint32:
+		maxBytes = 4
+	default:
+		maxBytes = 8
+	}
+
+	return
+}
+
+func (r *importReader) mpint(x *big.Int, typ *types2.Basic) {
+	signed, maxBytes := intSize(typ)
+
+	maxSmall := 256 - maxBytes
+	if signed {
+		maxSmall = 256 - 2*maxBytes
+	}
+	if maxBytes == 1 {
+		maxSmall = 256
+	}
+
+	n, _ := r.declReader.ReadByte()
+	if uint(n) < maxSmall {
+		v := int64(n)
+		if signed {
+			v >>= 1
+			if n&1 != 0 {
+				v = ^v
+			}
+		}
+		x.SetInt64(v)
+		return
+	}
+
+	v := -n
+	if signed {
+		v = -(n &^ 1) >> 1
+	}
+	if v < 1 || uint(v) > maxBytes {
+		errorf("weird decoding: %v, %v => %v", n, signed, v)
+	}
+	b := make([]byte, v)
+	io.ReadFull(&r.declReader, b)
+	x.SetBytes(b)
+	if signed && n&1 != 0 {
+		x.Neg(x)
+	}
+}
+
+func (r *importReader) mpfloat(typ *types2.Basic) constant.Value {
+	var mant big.Int
+	r.mpint(&mant, typ)
+	var f big.Float
+	f.SetInt(&mant)
+	if f.Sign() != 0 {
+		f.SetMantExp(&f, int(r.int64()))
+	}
+	return constant.Make(&f)
+}
+
+func (r *importReader) ident() string {
+	return r.string()
+}
+
+func (r *importReader) qualifiedIdent() (*types2.Package, string) {
+	name := r.string()
+	pkg := r.pkg()
+	return pkg, name
+}
+
+func (r *importReader) pos() syntax.Pos {
+	if r.p.version >= 1 {
+		r.posv1()
+	} else {
+		r.posv0()
+	}
+
+	if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 {
+		return syntax.Pos{}
+	}
+	// TODO(gri) fix this
+	// return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn))
+	return syntax.Pos{}
+}
+
+func (r *importReader) posv0() {
+	delta := r.int64()
+	if delta != deltaNewFile {
+		r.prevLine += delta
+	} else if l := r.int64(); l == -1 {
+		r.prevLine += deltaNewFile
+	} else {
+		r.prevFile = r.string()
+		r.prevLine = l
+	}
+}
+
+func (r *importReader) posv1() {
+	delta := r.int64()
+	r.prevColumn += delta >> 1
+	if delta&1 != 0 {
+		delta = r.int64()
+		r.prevLine += delta >> 1
+		if delta&1 != 0 {
+			r.prevFile = r.string()
+		}
+	}
+}
+
+func (r *importReader) typ() types2.Type {
+	return r.p.typAt(r.uint64(), nil)
+}
+
+func isInterface(t types2.Type) bool {
+	_, ok := t.(*types2.Interface)
+	return ok
+}
+
+func (r *importReader) pkg() *types2.Package { return r.p.pkgAt(r.uint64()) }
+func (r *importReader) string() string       { return r.p.stringAt(r.uint64()) }
+
+func (r *importReader) doType(base *types2.Named) types2.Type {
+	switch k := r.kind(); k {
+	default:
+		errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
+		return nil
+
+	case definedType:
+		pkg, name := r.qualifiedIdent()
+		r.p.doDecl(pkg, name)
+		return pkg.Scope().Lookup(name).(*types2.TypeName).Type()
+	case pointerType:
+		return types2.NewPointer(r.typ())
+	case sliceType:
+		return types2.NewSlice(r.typ())
+	case arrayType:
+		n := r.uint64()
+		return types2.NewArray(r.typ(), int64(n))
+	case chanType:
+		dir := chanDir(int(r.uint64()))
+		return types2.NewChan(dir, r.typ())
+	case mapType:
+		return types2.NewMap(r.typ(), r.typ())
+	case signatureType:
+		r.currPkg = r.pkg()
+		return r.signature(nil)
+
+	case structType:
+		r.currPkg = r.pkg()
+
+		fields := make([]*types2.Var, r.uint64())
+		tags := make([]string, len(fields))
+		for i := range fields {
+			fpos := r.pos()
+			fname := r.ident()
+			ftyp := r.typ()
+			emb := r.bool()
+			tag := r.string()
+
+			fields[i] = types2.NewField(fpos, r.currPkg, fname, ftyp, emb)
+			tags[i] = tag
+		}
+		return types2.NewStruct(fields, tags)
+
+	case interfaceType:
+		r.currPkg = r.pkg()
+
+		embeddeds := make([]types2.Type, r.uint64())
+		for i := range embeddeds {
+			_ = r.pos()
+			embeddeds[i] = r.typ()
+		}
+
+		methods := make([]*types2.Func, r.uint64())
+		for i := range methods {
+			mpos := r.pos()
+			mname := r.ident()
+
+			// TODO(mdempsky): Matches bimport.go, but I
+			// don't agree with this.
+			var recv *types2.Var
+			if base != nil {
+				recv = types2.NewVar(syntax.Pos{}, r.currPkg, "", base)
+			}
+
+			msig := r.signature(recv)
+			methods[i] = types2.NewFunc(mpos, r.currPkg, mname, msig)
+		}
+
+		typ := types2.NewInterfaceType(methods, embeddeds)
+		r.p.interfaceList = append(r.p.interfaceList, typ)
+		return typ
+	}
+}
+
+func (r *importReader) kind() itag {
+	return itag(r.uint64())
+}
+
+func (r *importReader) signature(recv *types2.Var) *types2.Signature {
+	params := r.paramList()
+	results := r.paramList()
+	variadic := params.Len() > 0 && r.bool()
+	return types2.NewSignature(recv, params, results, variadic)
+}
+
+func (r *importReader) paramList() *types2.Tuple {
+	xs := make([]*types2.Var, r.uint64())
+	for i := range xs {
+		xs[i] = r.param()
+	}
+	return types2.NewTuple(xs...)
+}
+
+func (r *importReader) param() *types2.Var {
+	pos := r.pos()
+	name := r.ident()
+	typ := r.typ()
+	return types2.NewParam(pos, r.currPkg, name, typ)
+}
+
+func (r *importReader) bool() bool {
+	return r.uint64() != 0
+}
+
+func (r *importReader) int64() int64 {
+	n, err := binary.ReadVarint(&r.declReader)
+	if err != nil {
+		errorf("readVarint: %v", err)
+	}
+	return n
+}
+
+func (r *importReader) uint64() uint64 {
+	n, err := binary.ReadUvarint(&r.declReader)
+	if err != nil {
+		errorf("readUvarint: %v", err)
+	}
+	return n
+}
+
+func (r *importReader) byte() byte {
+	x, err := r.declReader.ReadByte()
+	if err != nil {
+		errorf("declReader.ReadByte: %v", err)
+	}
+	return x
+}
diff --git a/src/cmd/compile/internal/importer/support.go b/src/cmd/compile/internal/importer/support.go
new file mode 100644
index 0000000..40b9c7c
--- /dev/null
+++ b/src/cmd/compile/internal/importer/support.go
@@ -0,0 +1,128 @@
+// UNREVIEWED
+// 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 file implements support functionality for iimport.go.
+
+package importer
+
+import (
+	"cmd/compile/internal/types2"
+	"fmt"
+	"go/token"
+	"sync"
+)
+
+func errorf(format string, args ...interface{}) {
+	panic(fmt.Sprintf(format, args...))
+}
+
+const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
+
+// Synthesize a token.Pos
+type fakeFileSet struct {
+	fset  *token.FileSet
+	files map[string]*token.File
+}
+
+func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
+	// TODO(mdempsky): Make use of column.
+
+	// Since we don't know the set of needed file positions, we
+	// reserve maxlines positions per file.
+	const maxlines = 64 * 1024
+	f := s.files[file]
+	if f == nil {
+		f = s.fset.AddFile(file, -1, maxlines)
+		s.files[file] = f
+		// Allocate the fake linebreak indices on first use.
+		// TODO(adonovan): opt: save ~512KB using a more complex scheme?
+		fakeLinesOnce.Do(func() {
+			fakeLines = make([]int, maxlines)
+			for i := range fakeLines {
+				fakeLines[i] = i
+			}
+		})
+		f.SetLines(fakeLines)
+	}
+
+	if line > maxlines {
+		line = 1
+	}
+
+	// Treat the file as if it contained only newlines
+	// and column=1: use the line number as the offset.
+	return f.Pos(line - 1)
+}
+
+var (
+	fakeLines     []int
+	fakeLinesOnce sync.Once
+)
+
+func chanDir(d int) types2.ChanDir {
+	// tag values must match the constants in cmd/compile/internal/gc/go.go
+	switch d {
+	case 1 /* Crecv */ :
+		return types2.RecvOnly
+	case 2 /* Csend */ :
+		return types2.SendOnly
+	case 3 /* Cboth */ :
+		return types2.SendRecv
+	default:
+		errorf("unexpected channel dir %d", d)
+		return 0
+	}
+}
+
+var predeclared = []types2.Type{
+	// basic types
+	types2.Typ[types2.Bool],
+	types2.Typ[types2.Int],
+	types2.Typ[types2.Int8],
+	types2.Typ[types2.Int16],
+	types2.Typ[types2.Int32],
+	types2.Typ[types2.Int64],
+	types2.Typ[types2.Uint],
+	types2.Typ[types2.Uint8],
+	types2.Typ[types2.Uint16],
+	types2.Typ[types2.Uint32],
+	types2.Typ[types2.Uint64],
+	types2.Typ[types2.Uintptr],
+	types2.Typ[types2.Float32],
+	types2.Typ[types2.Float64],
+	types2.Typ[types2.Complex64],
+	types2.Typ[types2.Complex128],
+	types2.Typ[types2.String],
+
+	// basic type aliases
+	types2.Universe.Lookup("byte").Type(),
+	types2.Universe.Lookup("rune").Type(),
+
+	// error
+	types2.Universe.Lookup("error").Type(),
+
+	// untyped types
+	types2.Typ[types2.UntypedBool],
+	types2.Typ[types2.UntypedInt],
+	types2.Typ[types2.UntypedRune],
+	types2.Typ[types2.UntypedFloat],
+	types2.Typ[types2.UntypedComplex],
+	types2.Typ[types2.UntypedString],
+	types2.Typ[types2.UntypedNil],
+
+	// package unsafe
+	types2.Typ[types2.UnsafePointer],
+
+	// invalid type
+	types2.Typ[types2.Invalid], // only appears in packages with errors
+
+	// used internally by gc; never used by this package or in .a files
+	anyType{},
+}
+
+type anyType struct{}
+
+func (t anyType) Underlying() types2.Type { return t }
+func (t anyType) String() string          { return "any" }
diff --git a/src/cmd/compile/internal/importer/testdata/a.go b/src/cmd/compile/internal/importer/testdata/a.go
new file mode 100644
index 0000000..06dafee
--- /dev/null
+++ b/src/cmd/compile/internal/importer/testdata/a.go
@@ -0,0 +1,15 @@
+// UNREVIEWED
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Input for TestIssue13566
+
+package a
+
+import "encoding/json"
+
+type A struct {
+	a    *A
+	json json.RawMessage
+}
diff --git a/src/cmd/compile/internal/importer/testdata/b.go b/src/cmd/compile/internal/importer/testdata/b.go
new file mode 100644
index 0000000..a601dbc
--- /dev/null
+++ b/src/cmd/compile/internal/importer/testdata/b.go
@@ -0,0 +1,12 @@
+// UNREVIEWED
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Input for TestIssue13566
+
+package b
+
+import "./a"
+
+type A a.A
diff --git a/src/cmd/compile/internal/importer/testdata/exports.go b/src/cmd/compile/internal/importer/testdata/exports.go
new file mode 100644
index 0000000..2a720fd
--- /dev/null
+++ b/src/cmd/compile/internal/importer/testdata/exports.go
@@ -0,0 +1,89 @@
+// UNREVIEWED
+// Copyright 2011 The Go 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 used to generate an object file which
+// serves as test file for gcimporter_test.go.
+
+package exports
+
+import "go/ast"
+
+// Issue 3682: Correctly read dotted identifiers from export data.
+const init1 = 0
+
+func init() {}
+
+const (
+	C0 int = 0
+	C1     = 3.14159265
+	C2     = 2.718281828i
+	C3     = -123.456e-789
+	C4     = +123.456e+789
+	C5     = 1234i
+	C6     = "foo\n"
+	C7     = `bar\n`
+)
+
+type (
+	T1  int
+	T2  [10]int
+	T3  []int
+	T4  *int
+	T5  chan int
+	T6a chan<- int
+	T6b chan (<-chan int)
+	T6c chan<- (chan int)
+	T7  <-chan *ast.File
+	T8  struct{}
+	T9  struct {
+		a    int
+		b, c float32
+		d    []string `go:"tag"`
+	}
+	T10 struct {
+		T8
+		T9
+		_ *T10
+	}
+	T11 map[int]string
+	T12 interface{}
+	T13 interface {
+		m1()
+		m2(int) float32
+	}
+	T14 interface {
+		T12
+		T13
+		m3(x ...struct{}) []T9
+	}
+	T15 func()
+	T16 func(int)
+	T17 func(x int)
+	T18 func() float32
+	T19 func() (x float32)
+	T20 func(...interface{})
+	T21 struct{ next *T21 }
+	T22 struct{ link *T23 }
+	T23 struct{ link *T22 }
+	T24 *T24
+	T25 *T26
+	T26 *T27
+	T27 *T25
+	T28 func(T28) T28
+)
+
+var (
+	V0 int
+	V1         = -991.0
+	V2 float32 = 1.2
+)
+
+func F1()         {}
+func F2(x int)    {}
+func F3() int     { return 0 }
+func F4() float32 { return 0 }
+func F5(a, b, c int, u, v, w struct{ x, y T1 }, more ...interface{}) (p, q, r chan<- T10)
+
+func (p *T1) M1()
diff --git a/src/cmd/compile/internal/importer/testdata/issue15920.go b/src/cmd/compile/internal/importer/testdata/issue15920.go
new file mode 100644
index 0000000..b402026
--- /dev/null
+++ b/src/cmd/compile/internal/importer/testdata/issue15920.go
@@ -0,0 +1,12 @@
+// UNREVIEWED
+// 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 p
+
+// The underlying type of Error is the underlying type of error.
+// Make sure we can import this again without problems.
+type Error error
+
+func F() Error { return nil }
diff --git a/src/cmd/compile/internal/importer/testdata/issue20046.go b/src/cmd/compile/internal/importer/testdata/issue20046.go
new file mode 100644
index 0000000..e412f35
--- /dev/null
+++ b/src/cmd/compile/internal/importer/testdata/issue20046.go
@@ -0,0 +1,10 @@
+// UNREVIEWED
+// Copyright 2017 The Go Authors. 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 V interface {
+	M()
+}
diff --git a/src/cmd/compile/internal/importer/testdata/issue25301.go b/src/cmd/compile/internal/importer/testdata/issue25301.go
new file mode 100644
index 0000000..a9dc1d7
--- /dev/null
+++ b/src/cmd/compile/internal/importer/testdata/issue25301.go
@@ -0,0 +1,18 @@
+// UNREVIEWED
+// 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 issue25301
+
+type (
+	A = interface {
+		M()
+	}
+	T interface {
+		A
+	}
+	S struct{}
+)
+
+func (S) M() { println("m") }
diff --git a/src/cmd/compile/internal/importer/testdata/issue25596.go b/src/cmd/compile/internal/importer/testdata/issue25596.go
new file mode 100644
index 0000000..95bef42
--- /dev/null
+++ b/src/cmd/compile/internal/importer/testdata/issue25596.go
@@ -0,0 +1,14 @@
+// UNREVIEWED
+// 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 issue25596
+
+type E interface {
+	M() T
+}
+
+type T interface {
+	E
+}
diff --git a/src/cmd/compile/internal/importer/testdata/p.go b/src/cmd/compile/internal/importer/testdata/p.go
new file mode 100644
index 0000000..34a20ea
--- /dev/null
+++ b/src/cmd/compile/internal/importer/testdata/p.go
@@ -0,0 +1,14 @@
+// UNREVIEWED
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Input for TestIssue15517
+
+package p
+
+const C = 0
+
+var V int
+
+func F() {}
diff --git a/src/cmd/compile/internal/importer/testdata/versions/test.go b/src/cmd/compile/internal/importer/testdata/versions/test.go
new file mode 100644
index 0000000..2f8eb5c
--- /dev/null
+++ b/src/cmd/compile/internal/importer/testdata/versions/test.go
@@ -0,0 +1,29 @@
+// UNREVIEWED
+// 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.
+
+// To create a test case for a new export format version,
+// build this package with the latest compiler and store
+// the resulting .a file appropriately named in the versions
+// directory. The VersionHandling test will pick it up.
+//
+// In the testdata/versions:
+//
+// go build -o test_go1.$X_$Y.a test.go
+//
+// with $X = Go version and $Y = export format version
+// (add 'b' or 'i' to distinguish between binary and
+// indexed format starting with 1.11 as long as both
+// formats are supported).
+//
+// Make sure this source is extended such that it exercises
+// whatever export format change has taken place.
+
+package test
+
+// Any release before and including Go 1.7 didn't encode
+// the package for a blank struct field.
+type BlankField struct {
+	_ int
+}
diff --git a/src/cmd/compile/internal/inline/inl.go b/src/cmd/compile/internal/inline/inl.go
new file mode 100644
index 0000000..d6b4ced
--- /dev/null
+++ b/src/cmd/compile/internal/inline/inl.go
@@ -0,0 +1,1506 @@
+// Copyright 2011 The Go 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 inlining facility makes 2 passes: first caninl determines which
+// functions are suitable for inlining, and for those that are it
+// saves a copy of the body. Then InlineCalls walks each function body to
+// expand calls to inlinable functions.
+//
+// The Debug.l flag controls the aggressiveness. Note that main() swaps level 0 and 1,
+// 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, panic, lazy typechecking (default)
+//      2: (unassigned)
+//      3: (unassigned)
+//      4: allow non-leaf functions
+//
+// At some point this may get another default and become switch-offable with -N.
+//
+// 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.
+
+package inline
+
+import (
+	"fmt"
+	"go/constant"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/logopt"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/src"
+)
+
+// Inlining budget parameters, gathered in one place
+const (
+	inlineMaxBudget       = 80
+	inlineExtraAppendCost = 0
+	// default is to inline if there's at most one call. -l=4 overrides this by using 1 instead.
+	inlineExtraCallCost  = 57              // 57 was benchmarked to provided most benefit with no bad surprises; see https://github.com/golang/go/issues/19348#issuecomment-439370742
+	inlineExtraPanicCost = 1               // do not penalize inlining panics.
+	inlineExtraThrowCost = inlineMaxBudget // with current (2018-05/1.11) code, inlining runtime.throw does not help.
+
+	inlineBigFunctionNodes   = 5000 // Functions with this many nodes are considered "big".
+	inlineBigFunctionMaxCost = 20   // Max cost of inlinee when inlining into a "big" function.
+)
+
+// InlinePackage finds functions that can be inlined and clones them before walk expands them.
+func InlinePackage() {
+	ir.VisitFuncsBottomUp(typecheck.Target.Decls, func(list []*ir.Func, recursive bool) {
+		numfns := numNonClosures(list)
+		for _, n := range list {
+			if !recursive || numfns > 1 {
+				// We allow inlining if there is no
+				// recursion, or the recursion cycle is
+				// across more than one function.
+				CanInline(n)
+			} else {
+				if base.Flag.LowerM > 1 {
+					fmt.Printf("%v: cannot inline %v: recursive\n", ir.Line(n), n.Nname)
+				}
+			}
+			InlineCalls(n)
+		}
+	})
+}
+
+// CanInline determines whether fn is inlineable.
+// If so, CanInline saves copies of fn.Body and fn.Dcl in fn.Inl.
+// fn and fn.Body will already have been typechecked.
+func CanInline(fn *ir.Func) {
+	if fn.Nname == nil {
+		base.Fatalf("CanInline no nname %+v", fn)
+	}
+
+	var reason string // reason, if any, that the function was not inlined
+	if base.Flag.LowerM > 1 || logopt.Enabled() {
+		defer func() {
+			if reason != "" {
+				if base.Flag.LowerM > 1 {
+					fmt.Printf("%v: cannot inline %v: %s\n", ir.Line(fn), fn.Nname, reason)
+				}
+				if logopt.Enabled() {
+					logopt.LogOpt(fn.Pos(), "cannotInlineFunction", "inline", ir.FuncName(fn), reason)
+				}
+			}
+		}()
+	}
+
+	// If marked "go:noinline", don't inline
+	if fn.Pragma&ir.Noinline != 0 {
+		reason = "marked go:noinline"
+		return
+	}
+
+	// If marked "go:norace" and -race compilation, don't inline.
+	if base.Flag.Race && fn.Pragma&ir.Norace != 0 {
+		reason = "marked go:norace with -race compilation"
+		return
+	}
+
+	// If marked "go:nocheckptr" and -d checkptr compilation, don't inline.
+	if base.Debug.Checkptr != 0 && fn.Pragma&ir.NoCheckPtr != 0 {
+		reason = "marked go:nocheckptr"
+		return
+	}
+
+	// If marked "go:cgo_unsafe_args", don't inline, since the
+	// function makes assumptions about its argument frame layout.
+	if fn.Pragma&ir.CgoUnsafeArgs != 0 {
+		reason = "marked go:cgo_unsafe_args"
+		return
+	}
+
+	// If marked as "go:uintptrescapes", don't inline, since the
+	// escape information is lost during inlining.
+	if fn.Pragma&ir.UintptrEscapes != 0 {
+		reason = "marked as having an escaping uintptr argument"
+		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.Pragma&ir.Yeswritebarrierrec != 0 {
+		reason = "marked go:yeswritebarrierrec"
+		return
+	}
+
+	// If fn has no body (is defined outside of Go), cannot inline it.
+	if len(fn.Body) == 0 {
+		reason = "no function body"
+		return
+	}
+
+	if fn.Typecheck() == 0 {
+		base.Fatalf("CanInline on non-typechecked function %v", fn)
+	}
+
+	n := fn.Nname
+	if n.Func.InlinabilityChecked() {
+		return
+	}
+	defer n.Func.SetInlinabilityChecked(true)
+
+	cc := int32(inlineExtraCallCost)
+	if base.Flag.LowerL == 4 {
+		cc = 1 // this appears to yield better performance than 0.
+	}
+
+	// At this point in the game the function we're looking at may
+	// have "stale" autos, vars that still appear in the Dcl list, but
+	// which no longer have any uses in the function body (due to
+	// elimination by deadcode). We'd like to exclude these dead vars
+	// when creating the "Inline.Dcl" field below; to accomplish this,
+	// the hairyVisitor below builds up a map of used/referenced
+	// locals, and we use this map to produce a pruned Inline.Dcl
+	// list. See issue 25249 for more context.
+
+	visitor := hairyVisitor{
+		budget:        inlineMaxBudget,
+		extraCallCost: cc,
+	}
+	if visitor.tooHairy(fn) {
+		reason = visitor.reason
+		return
+	}
+
+	n.Func.Inl = &ir.Inline{
+		Cost: inlineMaxBudget - visitor.budget,
+		Dcl:  pruneUnusedAutos(n.Defn.(*ir.Func).Dcl, &visitor),
+		Body: inlcopylist(fn.Body),
+	}
+
+	if base.Flag.LowerM > 1 {
+		fmt.Printf("%v: can inline %v with cost %d as: %v { %v }\n", ir.Line(fn), n, inlineMaxBudget-visitor.budget, fn.Type(), ir.Nodes(n.Func.Inl.Body))
+	} else if base.Flag.LowerM != 0 {
+		fmt.Printf("%v: can inline %v\n", ir.Line(fn), n)
+	}
+	if logopt.Enabled() {
+		logopt.LogOpt(fn.Pos(), "canInlineFunction", "inline", ir.FuncName(fn), fmt.Sprintf("cost: %d", inlineMaxBudget-visitor.budget))
+	}
+}
+
+// Inline_Flood marks n's inline body for export and recursively ensures
+// all called functions are marked too.
+func Inline_Flood(n *ir.Name, exportsym func(*ir.Name)) {
+	if n == nil {
+		return
+	}
+	if n.Op() != ir.ONAME || n.Class != ir.PFUNC {
+		base.Fatalf("Inline_Flood: unexpected %v, %v, %v", n, n.Op(), n.Class)
+	}
+	fn := n.Func
+	if fn == nil {
+		base.Fatalf("Inline_Flood: missing Func on %v", n)
+	}
+	if fn.Inl == nil {
+		return
+	}
+
+	if fn.ExportInline() {
+		return
+	}
+	fn.SetExportInline(true)
+
+	typecheck.ImportedBody(fn)
+
+	var doFlood func(n ir.Node)
+	doFlood = func(n ir.Node) {
+		switch n.Op() {
+		case ir.OMETHEXPR, ir.ODOTMETH:
+			Inline_Flood(ir.MethodExprName(n), exportsym)
+
+		case ir.ONAME:
+			n := n.(*ir.Name)
+			switch n.Class {
+			case ir.PFUNC:
+				Inline_Flood(n, exportsym)
+				exportsym(n)
+			case ir.PEXTERN:
+				exportsym(n)
+			}
+
+		case ir.OCALLPART:
+			// Okay, because we don't yet inline indirect
+			// calls to method values.
+		case ir.OCLOSURE:
+			// VisitList doesn't visit closure bodies, so force a
+			// recursive call to VisitList on the body of the closure.
+			ir.VisitList(n.(*ir.ClosureExpr).Func.Body, doFlood)
+		}
+	}
+
+	// Recursively identify all referenced functions for
+	// reexport. We want to include even non-called functions,
+	// because after inlining they might be callable.
+	ir.VisitList(ir.Nodes(fn.Inl.Body), doFlood)
+}
+
+// hairyVisitor visits a function body to determine its inlining
+// hairiness and whether or not it can be inlined.
+type hairyVisitor struct {
+	budget        int32
+	reason        string
+	extraCallCost int32
+	usedLocals    ir.NameSet
+	do            func(ir.Node) bool
+}
+
+func (v *hairyVisitor) tooHairy(fn *ir.Func) bool {
+	v.do = v.doNode // cache closure
+	if ir.DoChildren(fn, v.do) {
+		return true
+	}
+	if v.budget < 0 {
+		v.reason = fmt.Sprintf("function too complex: cost %d exceeds budget %d", inlineMaxBudget-v.budget, inlineMaxBudget)
+		return true
+	}
+	return false
+}
+
+func (v *hairyVisitor) doNode(n ir.Node) bool {
+	if n == nil {
+		return false
+	}
+	switch n.Op() {
+	// Call is okay if inlinable and we have the budget for the body.
+	case ir.OCALLFUNC:
+		n := n.(*ir.CallExpr)
+		// Functions that call runtime.getcaller{pc,sp} can not be inlined
+		// because getcaller{pc,sp} expect a pointer to the caller's first argument.
+		//
+		// runtime.throw is a "cheap call" like panic in normal code.
+		if n.X.Op() == ir.ONAME {
+			name := n.X.(*ir.Name)
+			if name.Class == ir.PFUNC && types.IsRuntimePkg(name.Sym().Pkg) {
+				fn := name.Sym().Name
+				if fn == "getcallerpc" || fn == "getcallersp" {
+					v.reason = "call to " + fn
+					return true
+				}
+				if fn == "throw" {
+					v.budget -= inlineExtraThrowCost
+					break
+				}
+			}
+		}
+
+		if ir.IsIntrinsicCall(n) {
+			// Treat like any other node.
+			break
+		}
+
+		if fn := inlCallee(n.X); fn != nil && fn.Inl != nil {
+			v.budget -= fn.Inl.Cost
+			break
+		}
+
+		// Call cost for non-leaf inlining.
+		v.budget -= v.extraCallCost
+
+	// Call is okay if inlinable and we have the budget for the body.
+	case ir.OCALLMETH:
+		n := n.(*ir.CallExpr)
+		t := n.X.Type()
+		if t == nil {
+			base.Fatalf("no function type for [%p] %+v\n", n.X, n.X)
+		}
+		fn := ir.MethodExprName(n.X).Func
+		if types.IsRuntimePkg(fn.Sym().Pkg) && fn.Sym().Name == "heapBits.nextArena" {
+			// Special case: explicitly allow
+			// mid-stack inlining of
+			// runtime.heapBits.next even though
+			// it calls slow-path
+			// runtime.heapBits.nextArena.
+			break
+		}
+		if fn.Inl != nil {
+			v.budget -= fn.Inl.Cost
+			break
+		}
+		// Call cost for non-leaf inlining.
+		v.budget -= v.extraCallCost
+
+	// Things that are too hairy, irrespective of the budget
+	case ir.OCALL, ir.OCALLINTER:
+		// Call cost for non-leaf inlining.
+		v.budget -= v.extraCallCost
+
+	case ir.OPANIC:
+		n := n.(*ir.UnaryExpr)
+		if n.X.Op() == ir.OCONVIFACE && n.X.(*ir.ConvExpr).Implicit() {
+			// Hack to keep reflect.flag.mustBe inlinable for TestIntendedInlining.
+			// Before CL 284412, these conversions were introduced later in the
+			// compiler, so they didn't count against inlining budget.
+			v.budget++
+		}
+		v.budget -= inlineExtraPanicCost
+
+	case ir.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 ir.OCLOSURE:
+		if base.Debug.InlFuncsWithClosures == 0 {
+			v.reason = "not inlining functions with closures"
+			return true
+		}
+
+		// TODO(danscales): Maybe make budget proportional to number of closure
+		// variables, e.g.:
+		//v.budget -= int32(len(n.(*ir.ClosureExpr).Func.ClosureVars) * 3)
+		v.budget -= 15
+		// Scan body of closure (which DoChildren doesn't automatically
+		// do) to check for disallowed ops in the body and include the
+		// body in the budget.
+		if doList(n.(*ir.ClosureExpr).Func.Body, v.do) {
+			return true
+		}
+
+	case ir.ORANGE,
+		ir.OSELECT,
+		ir.OGO,
+		ir.ODEFER,
+		ir.ODCLTYPE, // can't print yet
+		ir.OTAILCALL:
+		v.reason = "unhandled op " + n.Op().String()
+		return true
+
+	case ir.OAPPEND:
+		v.budget -= inlineExtraAppendCost
+
+	case ir.ODEREF:
+		// *(*X)(unsafe.Pointer(&x)) is low-cost
+		n := n.(*ir.StarExpr)
+
+		ptr := n.X
+		for ptr.Op() == ir.OCONVNOP {
+			ptr = ptr.(*ir.ConvExpr).X
+		}
+		if ptr.Op() == ir.OADDR {
+			v.budget += 1 // undo half of default cost of ir.ODEREF+ir.OADDR
+		}
+
+	case ir.OCONVNOP:
+		// This doesn't produce code, but the children might.
+		v.budget++ // undo default cost
+
+	case ir.ODCLCONST, ir.OFALL:
+		// These nodes don't produce code; omit from inlining budget.
+		return false
+
+	case ir.OFOR, ir.OFORUNTIL:
+		n := n.(*ir.ForStmt)
+		if n.Label != nil {
+			v.reason = "labeled control"
+			return true
+		}
+	case ir.OSWITCH:
+		n := n.(*ir.SwitchStmt)
+		if n.Label != nil {
+			v.reason = "labeled control"
+			return true
+		}
+	// case ir.ORANGE, ir.OSELECT in "unhandled" above
+
+	case ir.OBREAK, ir.OCONTINUE:
+		n := n.(*ir.BranchStmt)
+		if n.Label != nil {
+			// Should have short-circuited due to labeled control error above.
+			base.Fatalf("unexpected labeled break/continue: %v", n)
+		}
+
+	case ir.OIF:
+		n := n.(*ir.IfStmt)
+		if ir.IsConst(n.Cond, constant.Bool) {
+			// This if and the condition cost nothing.
+			// TODO(rsc): It seems strange that we visit the dead branch.
+			return doList(n.Init(), v.do) ||
+				doList(n.Body, v.do) ||
+				doList(n.Else, v.do)
+		}
+
+	case ir.ONAME:
+		n := n.(*ir.Name)
+		if n.Class == ir.PAUTO {
+			v.usedLocals.Add(n)
+		}
+
+	case ir.OBLOCK:
+		// The only OBLOCK we should see at this point is an empty one.
+		// In any event, let the visitList(n.List()) below take care of the statements,
+		// and don't charge for the OBLOCK itself. The ++ undoes the -- below.
+		v.budget++
+
+	case ir.OCALLPART, ir.OSLICELIT:
+		v.budget-- // Hack for toolstash -cmp.
+
+	case ir.OMETHEXPR:
+		v.budget++ // Hack for toolstash -cmp.
+	}
+
+	v.budget--
+
+	// When debugging, don't stop early, to get full cost of inlining this function
+	if v.budget < 0 && base.Flag.LowerM < 2 && !logopt.Enabled() {
+		v.reason = "too expensive"
+		return true
+	}
+
+	return ir.DoChildren(n, v.do)
+}
+
+func isBigFunc(fn *ir.Func) bool {
+	budget := inlineBigFunctionNodes
+	return ir.Any(fn, func(n ir.Node) bool {
+		budget--
+		return budget <= 0
+	})
+}
+
+// inlcopylist (together with inlcopy) recursively copies a list of nodes, except
+// that it keeps the same ONAME, OTYPE, and OLITERAL nodes. It is used for copying
+// the body and dcls of an inlineable function.
+func inlcopylist(ll []ir.Node) []ir.Node {
+	s := make([]ir.Node, len(ll))
+	for i, n := range ll {
+		s[i] = inlcopy(n)
+	}
+	return s
+}
+
+// inlcopy is like DeepCopy(), but does extra work to copy closures.
+func inlcopy(n ir.Node) ir.Node {
+	var edit func(ir.Node) ir.Node
+	edit = func(x ir.Node) ir.Node {
+		switch x.Op() {
+		case ir.ONAME, ir.OTYPE, ir.OLITERAL, ir.ONIL:
+			return x
+		}
+		m := ir.Copy(x)
+		ir.EditChildren(m, edit)
+		if x.Op() == ir.OCLOSURE {
+			x := x.(*ir.ClosureExpr)
+			// Need to save/duplicate x.Func.Nname,
+			// x.Func.Nname.Ntype, x.Func.Dcl, x.Func.ClosureVars, and
+			// x.Func.Body for iexport and local inlining.
+			oldfn := x.Func
+			newfn := ir.NewFunc(oldfn.Pos())
+			if oldfn.ClosureCalled() {
+				newfn.SetClosureCalled(true)
+			}
+			m.(*ir.ClosureExpr).Func = newfn
+			newfn.Nname = ir.NewNameAt(oldfn.Nname.Pos(), oldfn.Nname.Sym())
+			// XXX OK to share fn.Type() ??
+			newfn.Nname.SetType(oldfn.Nname.Type())
+			// Ntype can be nil for -G=3 mode.
+			if oldfn.Nname.Ntype != nil {
+				newfn.Nname.Ntype = inlcopy(oldfn.Nname.Ntype).(ir.Ntype)
+			}
+			newfn.Body = inlcopylist(oldfn.Body)
+			// Make shallow copy of the Dcl and ClosureVar slices
+			newfn.Dcl = append([]*ir.Name(nil), oldfn.Dcl...)
+			newfn.ClosureVars = append([]*ir.Name(nil), oldfn.ClosureVars...)
+		}
+		return m
+	}
+	return edit(n)
+}
+
+// InlineCalls/inlnode walks fn's statements and expressions and substitutes any
+// calls made to inlineable functions. This is the external entry point.
+func InlineCalls(fn *ir.Func) {
+	savefn := ir.CurFunc
+	ir.CurFunc = fn
+	maxCost := int32(inlineMaxBudget)
+	if isBigFunc(fn) {
+		maxCost = inlineBigFunctionMaxCost
+	}
+	// Map to keep track of functions that have been inlined at a particular
+	// call site, in order to stop inlining when we reach the beginning of a
+	// recursion cycle again. We don't inline immediately recursive functions,
+	// but allow inlining if there is a recursion cycle of many functions.
+	// Most likely, the inlining will stop before we even hit the beginning of
+	// the cycle again, but the map catches the unusual case.
+	inlMap := make(map[*ir.Func]bool)
+	var edit func(ir.Node) ir.Node
+	edit = func(n ir.Node) ir.Node {
+		return inlnode(n, maxCost, inlMap, edit)
+	}
+	ir.EditChildren(fn, edit)
+	ir.CurFunc = savefn
+}
+
+// Turn an OINLCALL into a statement.
+func inlconv2stmt(inlcall *ir.InlinedCallExpr) ir.Node {
+	n := ir.NewBlockStmt(inlcall.Pos(), nil)
+	n.List = inlcall.Init()
+	n.List.Append(inlcall.Body.Take()...)
+	return n
+}
+
+// Turn an OINLCALL into a single valued expression.
+// The result of inlconv2expr MUST be assigned back to n, e.g.
+// 	n.Left = inlconv2expr(n.Left)
+func inlconv2expr(n *ir.InlinedCallExpr) ir.Node {
+	r := n.ReturnVars[0]
+	return ir.InitExpr(append(n.Init(), n.Body...), r)
+}
+
+// Turn the rlist (with the return values) of the OINLCALL in
+// n into an expression list lumping the ninit and body
+// containing the inlined statements on the first list element so
+// order will be preserved. Used in return, oas2func and call
+// statements.
+func inlconv2list(n *ir.InlinedCallExpr) []ir.Node {
+	if n.Op() != ir.OINLCALL || len(n.ReturnVars) == 0 {
+		base.Fatalf("inlconv2list %+v\n", n)
+	}
+
+	s := n.ReturnVars
+	s[0] = ir.InitExpr(append(n.Init(), n.Body...), s[0])
+	return s
+}
+
+// inlnode recurses over the tree to find inlineable calls, which will
+// be turned into OINLCALLs by mkinlcall. When the recursion comes
+// back up will examine left, right, list, rlist, ninit, ntest, nincr,
+// nbody and nelse and use one of the 4 inlconv/glue functions above
+// to turn the OINLCALL into an expression, a statement, or patch it
+// in to this nodes list or rlist as appropriate.
+// NOTE it makes no sense to pass the glue functions down the
+// recursion to the level where the OINLCALL gets created because they
+// have to edit /this/ n, so you'd have to push that one down as well,
+// but then you may as well do it here.  so this is cleaner and
+// shorter and less complicated.
+// The result of inlnode MUST be assigned back to n, e.g.
+// 	n.Left = inlnode(n.Left)
+func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.Node) ir.Node) ir.Node {
+	if n == nil {
+		return n
+	}
+
+	switch n.Op() {
+	case ir.ODEFER, ir.OGO:
+		n := n.(*ir.GoDeferStmt)
+		switch call := n.Call; call.Op() {
+		case ir.OCALLFUNC, ir.OCALLMETH:
+			call := call.(*ir.CallExpr)
+			call.NoInline = true
+		}
+
+	// TODO do them here (or earlier),
+	// so escape analysis can avoid more heapmoves.
+	case ir.OCLOSURE:
+		return n
+	case ir.OCALLMETH:
+		// Prevent inlining some reflect.Value methods when using checkptr,
+		// even when package reflect was compiled without it (#35073).
+		n := n.(*ir.CallExpr)
+		if s := ir.MethodExprName(n.X).Sym(); base.Debug.Checkptr != 0 && types.IsReflectPkg(s.Pkg) && (s.Name == "Value.UnsafeAddr" || s.Name == "Value.Pointer") {
+			return n
+		}
+	}
+
+	lno := ir.SetPos(n)
+
+	ir.EditChildren(n, edit)
+
+	if as := n; as.Op() == ir.OAS2FUNC {
+		as := as.(*ir.AssignListStmt)
+		if as.Rhs[0].Op() == ir.OINLCALL {
+			as.Rhs = inlconv2list(as.Rhs[0].(*ir.InlinedCallExpr))
+			as.SetOp(ir.OAS2)
+			as.SetTypecheck(0)
+			n = typecheck.Stmt(as)
+		}
+	}
+
+	// with all the branches out of the way, it is now time to
+	// transmogrify this node itself unless inhibited by the
+	// switch at the top of this function.
+	switch n.Op() {
+	case ir.OCALLFUNC, ir.OCALLMETH:
+		n := n.(*ir.CallExpr)
+		if n.NoInline {
+			return n
+		}
+	}
+
+	var call *ir.CallExpr
+	switch n.Op() {
+	case ir.OCALLFUNC:
+		call = n.(*ir.CallExpr)
+		if base.Flag.LowerM > 3 {
+			fmt.Printf("%v:call to func %+v\n", ir.Line(n), call.X)
+		}
+		if ir.IsIntrinsicCall(call) {
+			break
+		}
+		if fn := inlCallee(call.X); fn != nil && fn.Inl != nil {
+			n = mkinlcall(call, fn, maxCost, inlMap, edit)
+		}
+
+	case ir.OCALLMETH:
+		call = n.(*ir.CallExpr)
+		if base.Flag.LowerM > 3 {
+			fmt.Printf("%v:call to meth %v\n", ir.Line(n), call.X.(*ir.SelectorExpr).Sel)
+		}
+
+		// typecheck should have resolved ODOTMETH->type, whose nname points to the actual function.
+		if call.X.Type() == nil {
+			base.Fatalf("no function type for [%p] %+v\n", call.X, call.X)
+		}
+
+		n = mkinlcall(call, ir.MethodExprName(call.X).Func, maxCost, inlMap, edit)
+	}
+
+	base.Pos = lno
+
+	if n.Op() == ir.OINLCALL {
+		ic := n.(*ir.InlinedCallExpr)
+		switch call.Use {
+		default:
+			ir.Dump("call", call)
+			base.Fatalf("call missing use")
+		case ir.CallUseExpr:
+			n = inlconv2expr(ic)
+		case ir.CallUseStmt:
+			n = inlconv2stmt(ic)
+		case ir.CallUseList:
+			// leave for caller to convert
+		}
+	}
+
+	return n
+}
+
+// inlCallee takes a function-typed expression and returns the underlying function ONAME
+// that it refers to if statically known. Otherwise, it returns nil.
+func inlCallee(fn ir.Node) *ir.Func {
+	fn = ir.StaticValue(fn)
+	switch fn.Op() {
+	case ir.OMETHEXPR:
+		fn := fn.(*ir.SelectorExpr)
+		n := ir.MethodExprName(fn)
+		// Check that receiver type matches fn.X.
+		// TODO(mdempsky): Handle implicit dereference
+		// of pointer receiver argument?
+		if n == nil || !types.Identical(n.Type().Recv().Type, fn.X.Type()) {
+			return nil
+		}
+		return n.Func
+	case ir.ONAME:
+		fn := fn.(*ir.Name)
+		if fn.Class == ir.PFUNC {
+			return fn.Func
+		}
+	case ir.OCLOSURE:
+		fn := fn.(*ir.ClosureExpr)
+		c := fn.Func
+		CanInline(c)
+		return c
+	}
+	return nil
+}
+
+func inlParam(t *types.Field, as ir.InitNode, inlvars map[*ir.Name]*ir.Name) ir.Node {
+	if t.Nname == nil {
+		return ir.BlankNode
+	}
+	n := t.Nname.(*ir.Name)
+	if ir.IsBlank(n) {
+		return ir.BlankNode
+	}
+	inlvar := inlvars[n]
+	if inlvar == nil {
+		base.Fatalf("missing inlvar for %v", n)
+	}
+	as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, inlvar))
+	inlvar.Name().Defn = as
+	return inlvar
+}
+
+var inlgen int
+
+// SSADumpInline gives the SSA back end a chance to dump the function
+// when producing output for debugging the compiler itself.
+var SSADumpInline = func(*ir.Func) {}
+
+// If n is a call node (OCALLFUNC or OCALLMETH), and fn is an ONAME node for a
+// function with an inlinable body, return an OINLCALL node that can replace n.
+// The returned node's Ninit has the parameter assignments, the Nbody is the
+// inlined function body, and (List, Rlist) contain the (input, output)
+// parameters.
+// The result of mkinlcall MUST be assigned back to n, e.g.
+// 	n.Left = mkinlcall(n.Left, fn, isddd)
+func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.Node) ir.Node) ir.Node {
+	if fn.Inl == nil {
+		if logopt.Enabled() {
+			logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
+				fmt.Sprintf("%s cannot be inlined", ir.PkgFuncName(fn)))
+		}
+		return n
+	}
+	if fn.Inl.Cost > maxCost {
+		// The inlined function body is too big. Typically we use this check to restrict
+		// inlining into very big functions.  See issue 26546 and 17566.
+		if logopt.Enabled() {
+			logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
+				fmt.Sprintf("cost %d of %s exceeds max large caller cost %d", fn.Inl.Cost, ir.PkgFuncName(fn), maxCost))
+		}
+		return n
+	}
+
+	if fn == ir.CurFunc {
+		// Can't recursively inline a function into itself.
+		if logopt.Enabled() {
+			logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to %s", ir.FuncName(ir.CurFunc)))
+		}
+		return n
+	}
+
+	if base.Flag.Cfg.Instrumenting && types.IsRuntimePkg(fn.Sym().Pkg) {
+		// Runtime package must not be instrumented.
+		// Instrument skips runtime package. However, some runtime code can be
+		// inlined into other packages and instrumented there. To avoid this,
+		// we disable inlining of runtime functions when instrumenting.
+		// The example that we observed is inlining of LockOSThread,
+		// which lead to false race reports on m contents.
+		return n
+	}
+
+	if inlMap[fn] {
+		if base.Flag.LowerM > 1 {
+			fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", ir.Line(n), fn, ir.FuncName(ir.CurFunc))
+		}
+		return n
+	}
+	inlMap[fn] = true
+	defer func() {
+		inlMap[fn] = false
+	}()
+	if base.Debug.TypecheckInl == 0 {
+		typecheck.ImportedBody(fn)
+	}
+
+	// We have a function node, and it has an inlineable body.
+	if base.Flag.LowerM > 1 {
+		fmt.Printf("%v: inlining call to %v %v { %v }\n", ir.Line(n), fn.Sym(), fn.Type(), ir.Nodes(fn.Inl.Body))
+	} else if base.Flag.LowerM != 0 {
+		fmt.Printf("%v: inlining call to %v\n", ir.Line(n), fn)
+	}
+	if base.Flag.LowerM > 2 {
+		fmt.Printf("%v: Before inlining: %+v\n", ir.Line(n), n)
+	}
+
+	SSADumpInline(fn)
+
+	ninit := n.Init()
+
+	// For normal function calls, the function callee expression
+	// may contain side effects (e.g., added by addinit during
+	// inlconv2expr or inlconv2list). Make sure to preserve these,
+	// if necessary (#42703).
+	if n.Op() == ir.OCALLFUNC {
+		callee := n.X
+		for callee.Op() == ir.OCONVNOP {
+			conv := callee.(*ir.ConvExpr)
+			ninit.Append(ir.TakeInit(conv)...)
+			callee = conv.X
+		}
+		if callee.Op() != ir.ONAME && callee.Op() != ir.OCLOSURE && callee.Op() != ir.OMETHEXPR {
+			base.Fatalf("unexpected callee expression: %v", callee)
+		}
+	}
+
+	// Make temp names to use instead of the originals.
+	inlvars := make(map[*ir.Name]*ir.Name)
+
+	// record formals/locals for later post-processing
+	var inlfvars []*ir.Name
+
+	for _, ln := range fn.Inl.Dcl {
+		if ln.Op() != ir.ONAME {
+			continue
+		}
+		if ln.Class == ir.PPARAMOUT { // return values handled below.
+			continue
+		}
+		inlf := typecheck.Expr(inlvar(ln)).(*ir.Name)
+		inlvars[ln] = inlf
+		if base.Flag.GenDwarfInl > 0 {
+			if ln.Class == ir.PPARAM {
+				inlf.Name().SetInlFormal(true)
+			} else {
+				inlf.Name().SetInlLocal(true)
+			}
+			inlf.SetPos(ln.Pos())
+			inlfvars = append(inlfvars, inlf)
+		}
+	}
+
+	// We can delay declaring+initializing result parameters if:
+	// (1) there's exactly one "return" statement in the inlined function;
+	// (2) it's not an empty return statement (#44355); and
+	// (3) the result parameters aren't named.
+	delayretvars := true
+
+	nreturns := 0
+	ir.VisitList(ir.Nodes(fn.Inl.Body), func(n ir.Node) {
+		if n, ok := n.(*ir.ReturnStmt); ok {
+			nreturns++
+			if len(n.Results) == 0 {
+				delayretvars = false // empty return statement (case 2)
+			}
+		}
+	})
+
+	if nreturns != 1 {
+		delayretvars = false // not exactly one return statement (case 1)
+	}
+
+	// temporaries for return values.
+	var retvars []ir.Node
+	for i, t := range fn.Type().Results().Fields().Slice() {
+		var m *ir.Name
+		if nn := t.Nname; nn != nil && !ir.IsBlank(nn.(*ir.Name)) && !strings.HasPrefix(nn.Sym().Name, "~r") {
+			n := nn.(*ir.Name)
+			m = inlvar(n)
+			m = typecheck.Expr(m).(*ir.Name)
+			inlvars[n] = m
+			delayretvars = false // found a named result parameter (case 3)
+		} else {
+			// anonymous return values, synthesize names for use in assignment that replaces return
+			m = retvar(t, i)
+		}
+
+		if base.Flag.GenDwarfInl > 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.Name().SetInlFormal(true)
+				m.SetPos(t.Pos)
+				inlfvars = append(inlfvars, m)
+			}
+		}
+
+		retvars = append(retvars, m)
+	}
+
+	// Assign arguments to the parameters' temp names.
+	as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil)
+	as.Def = true
+	if n.Op() == ir.OCALLMETH {
+		sel := n.X.(*ir.SelectorExpr)
+		if sel.X == nil {
+			base.Fatalf("method call without receiver: %+v", n)
+		}
+		as.Rhs.Append(sel.X)
+	}
+	as.Rhs.Append(n.Args...)
+
+	// For non-dotted calls to variadic functions, we assign the
+	// variadic parameter's temp name separately.
+	var vas *ir.AssignStmt
+
+	if recv := fn.Type().Recv(); recv != nil {
+		as.Lhs.Append(inlParam(recv, as, inlvars))
+	}
+	for _, param := range fn.Type().Params().Fields().Slice() {
+		// For ordinary parameters or variadic parameters in
+		// dotted calls, just add the variable to the
+		// assignment list, and we're done.
+		if !param.IsDDD() || n.IsDDD {
+			as.Lhs.Append(inlParam(param, as, inlvars))
+			continue
+		}
+
+		// Otherwise, we need to collect the remaining values
+		// to pass as a slice.
+
+		x := len(as.Lhs)
+		for len(as.Lhs) < len(as.Rhs) {
+			as.Lhs.Append(argvar(param.Type, len(as.Lhs)))
+		}
+		varargs := as.Lhs[x:]
+
+		vas = ir.NewAssignStmt(base.Pos, nil, nil)
+		vas.X = inlParam(param, vas, inlvars)
+		if len(varargs) == 0 {
+			vas.Y = typecheck.NodNil()
+			vas.Y.SetType(param.Type)
+		} else {
+			lit := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(param.Type), nil)
+			lit.List = varargs
+			vas.Y = lit
+		}
+	}
+
+	if len(as.Rhs) != 0 {
+		ninit.Append(typecheck.Stmt(as))
+	}
+
+	if vas != nil {
+		ninit.Append(typecheck.Stmt(vas))
+	}
+
+	if !delayretvars {
+		// Zero the return parameters.
+		for _, n := range retvars {
+			ninit.Append(ir.NewDecl(base.Pos, ir.ODCL, n.(*ir.Name)))
+			ras := ir.NewAssignStmt(base.Pos, n, nil)
+			ninit.Append(typecheck.Stmt(ras))
+		}
+	}
+
+	retlabel := typecheck.AutoLabel(".i")
+
+	inlgen++
+
+	parent := -1
+	if b := base.Ctxt.PosTable.Pos(n.Pos()).Base(); b != nil {
+		parent = b.InliningIndex()
+	}
+
+	sym := fn.Linksym()
+	newIndex := base.Ctxt.InlTree.Add(parent, n.Pos(), sym)
+
+	// Add an inline mark just before the inlined body.
+	// This mark is inline in the code so that it's a reasonable spot
+	// to put a breakpoint. Not sure if that's really necessary or not
+	// (in which case it could go at the end of the function instead).
+	// Note issue 28603.
+	inlMark := ir.NewInlineMarkStmt(base.Pos, types.BADWIDTH)
+	inlMark.SetPos(n.Pos().WithIsStmt())
+	inlMark.Index = int64(newIndex)
+	ninit.Append(inlMark)
+
+	if base.Flag.GenDwarfInl > 0 {
+		if !sym.WasInlined() {
+			base.Ctxt.DwFixups.SetPrecursorFunc(sym, fn)
+			sym.Set(obj.AttrWasInlined, true)
+		}
+	}
+
+	subst := inlsubst{
+		retlabel:     retlabel,
+		retvars:      retvars,
+		delayretvars: delayretvars,
+		inlvars:      inlvars,
+		defnMarker:   ir.NilExpr{},
+		bases:        make(map[*src.PosBase]*src.PosBase),
+		newInlIndex:  newIndex,
+		fn:           fn,
+	}
+	subst.edit = subst.node
+
+	body := subst.list(ir.Nodes(fn.Inl.Body))
+
+	lab := ir.NewLabelStmt(base.Pos, retlabel)
+	body = append(body, lab)
+
+	if !typecheck.Go117ExportTypes {
+		typecheck.Stmts(body)
+	}
+
+	if base.Flag.GenDwarfInl > 0 {
+		for _, v := range inlfvars {
+			v.SetPos(subst.updatedPos(v.Pos()))
+		}
+	}
+
+	//dumplist("ninit post", ninit);
+
+	call := ir.NewInlinedCallExpr(base.Pos, nil, nil)
+	*call.PtrInit() = ninit
+	call.Body = body
+	call.ReturnVars = retvars
+	call.SetType(n.Type())
+	call.SetTypecheck(1)
+
+	// transitive inlining
+	// might be nice to do this before exporting the body,
+	// but can't emit the body with inlining expanded.
+	// instead we emit the things that the body needs
+	// and each use must redo the inlining.
+	// luckily these are small.
+	ir.EditChildren(call, edit)
+
+	if base.Flag.LowerM > 2 {
+		fmt.Printf("%v: After inlining %+v\n\n", ir.Line(call), call)
+	}
+
+	return call
+}
+
+// Every time we expand a function we generate a new set of tmpnames,
+// PAUTO's in the calling functions, and link them off of the
+// PPARAM's, PAUTOS and PPARAMOUTs of the called function.
+func inlvar(var_ *ir.Name) *ir.Name {
+	if base.Flag.LowerM > 3 {
+		fmt.Printf("inlvar %+v\n", var_)
+	}
+
+	n := typecheck.NewName(var_.Sym())
+	n.SetType(var_.Type())
+	n.Class = ir.PAUTO
+	n.SetUsed(true)
+	n.Curfn = ir.CurFunc // the calling function, not the called one
+	n.SetAddrtaken(var_.Addrtaken())
+
+	ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n)
+	return n
+}
+
+// Synthesize a variable to store the inlined function's results in.
+func retvar(t *types.Field, i int) *ir.Name {
+	n := typecheck.NewName(typecheck.LookupNum("~R", i))
+	n.SetType(t.Type)
+	n.Class = ir.PAUTO
+	n.SetUsed(true)
+	n.Curfn = ir.CurFunc // the calling function, not the called one
+	ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n)
+	return n
+}
+
+// Synthesize a variable to store the inlined function's arguments
+// when they come from a multiple return call.
+func argvar(t *types.Type, i int) ir.Node {
+	n := typecheck.NewName(typecheck.LookupNum("~arg", i))
+	n.SetType(t.Elem())
+	n.Class = ir.PAUTO
+	n.SetUsed(true)
+	n.Curfn = ir.CurFunc // the calling function, not the called one
+	ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n)
+	return n
+}
+
+// The inlsubst type implements the actual inlining of a single
+// function call.
+type inlsubst struct {
+	// Target of the goto substituted in place of a return.
+	retlabel *types.Sym
+
+	// Temporary result variables.
+	retvars []ir.Node
+
+	// Whether result variables should be initialized at the
+	// "return" statement.
+	delayretvars bool
+
+	inlvars map[*ir.Name]*ir.Name
+	// defnMarker is used to mark a Node for reassignment.
+	// inlsubst.clovar set this during creating new ONAME.
+	// inlsubst.node will set the correct Defn for inlvar.
+	defnMarker ir.NilExpr
+
+	// 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
+
+	edit func(ir.Node) ir.Node // cached copy of subst.node method value closure
+
+	// If non-nil, we are inside a closure inside the inlined function, and
+	// newclofn is the Func of the new inlined closure.
+	newclofn *ir.Func
+
+	fn *ir.Func // For debug -- the func that is being inlined
+
+	// If true, then don't update source positions during substitution
+	// (retain old source positions).
+	noPosUpdate bool
+}
+
+// list inlines a list of nodes.
+func (subst *inlsubst) list(ll ir.Nodes) []ir.Node {
+	s := make([]ir.Node, 0, len(ll))
+	for _, n := range ll {
+		s = append(s, subst.node(n))
+	}
+	return s
+}
+
+// fields returns a list of the fields of a struct type representing receiver,
+// params, or results, after duplicating the field nodes and substituting the
+// Nname nodes inside the field nodes.
+func (subst *inlsubst) fields(oldt *types.Type) []*types.Field {
+	oldfields := oldt.FieldSlice()
+	newfields := make([]*types.Field, len(oldfields))
+	for i := range oldfields {
+		newfields[i] = oldfields[i].Copy()
+		if oldfields[i].Nname != nil {
+			newfields[i].Nname = subst.node(oldfields[i].Nname.(*ir.Name))
+		}
+	}
+	return newfields
+}
+
+// clovar creates a new ONAME node for a local variable or param of a closure
+// inside a function being inlined.
+func (subst *inlsubst) clovar(n *ir.Name) *ir.Name {
+	// TODO(danscales): want to get rid of this shallow copy, with code like the
+	// following, but it is hard to copy all the necessary flags in a maintainable way.
+	// m := ir.NewNameAt(n.Pos(), n.Sym())
+	// m.Class = n.Class
+	// m.SetType(n.Type())
+	// m.SetTypecheck(1)
+	//if n.IsClosureVar() {
+	//	m.SetIsClosureVar(true)
+	//}
+	m := &ir.Name{}
+	*m = *n
+	m.Curfn = subst.newclofn
+
+	switch defn := n.Defn.(type) {
+	case nil:
+		// ok
+	case *ir.Name:
+		if !n.IsClosureVar() {
+			base.FatalfAt(n.Pos(), "want closure variable, got: %+v", n)
+		}
+		if n.Sym().Pkg != types.LocalPkg {
+			// If the closure came from inlining a function from
+			// another package, must change package of captured
+			// variable to localpkg, so that the fields of the closure
+			// struct are local package and can be accessed even if
+			// name is not exported. If you disable this code, you can
+			// reproduce the problem by running 'go test
+			// go/internal/srcimporter'. TODO(mdempsky) - maybe change
+			// how we create closure structs?
+			m.SetSym(types.LocalPkg.Lookup(n.Sym().Name))
+		}
+		// Make sure any inlvar which is the Defn
+		// of an ONAME closure var is rewritten
+		// during inlining. Don't substitute
+		// if Defn node is outside inlined function.
+		if subst.inlvars[n.Defn.(*ir.Name)] != nil {
+			m.Defn = subst.node(n.Defn)
+		}
+	case *ir.AssignStmt, *ir.AssignListStmt:
+		// Mark node for reassignment at the end of inlsubst.node.
+		m.Defn = &subst.defnMarker
+	case *ir.TypeSwitchGuard:
+		// TODO(mdempsky): Set m.Defn properly. See discussion on #45743.
+	default:
+		base.FatalfAt(n.Pos(), "unexpected Defn: %+v", defn)
+	}
+
+	if n.Outer != nil {
+		// Either the outer variable is defined in function being inlined,
+		// and we will replace it with the substituted variable, or it is
+		// defined outside the function being inlined, and we should just
+		// skip the outer variable (the closure variable of the function
+		// being inlined).
+		s := subst.node(n.Outer).(*ir.Name)
+		if s == n.Outer {
+			s = n.Outer.Outer
+		}
+		m.Outer = s
+	}
+	return m
+}
+
+// closure does the necessary substitions for a ClosureExpr n and returns the new
+// closure node.
+func (subst *inlsubst) closure(n *ir.ClosureExpr) ir.Node {
+	m := ir.Copy(n)
+
+	// Prior to the subst edit, set a flag in the inlsubst to
+	// indicated that we don't want to update the source positions in
+	// the new closure. If we do this, it will appear that the closure
+	// itself has things inlined into it, which is not the case. See
+	// issue #46234 for more details.
+	defer func(prev bool) { subst.noPosUpdate = prev }(subst.noPosUpdate)
+	subst.noPosUpdate = true
+	ir.EditChildren(m, subst.edit)
+
+	//fmt.Printf("Inlining func %v with closure into %v\n", subst.fn, ir.FuncName(ir.CurFunc))
+
+	// The following is similar to funcLit
+	oldfn := n.Func
+	newfn := ir.NewFunc(oldfn.Pos())
+	// These three lines are not strictly necessary, but just to be clear
+	// that new function needs to redo typechecking and inlinability.
+	newfn.SetTypecheck(0)
+	newfn.SetInlinabilityChecked(false)
+	newfn.Inl = nil
+	newfn.SetIsHiddenClosure(true)
+	newfn.Nname = ir.NewNameAt(n.Pos(), ir.BlankNode.Sym())
+	newfn.Nname.Func = newfn
+	// Ntype can be nil for -G=3 mode.
+	if oldfn.Nname.Ntype != nil {
+		newfn.Nname.Ntype = subst.node(oldfn.Nname.Ntype).(ir.Ntype)
+	}
+	newfn.Nname.Defn = newfn
+
+	m.(*ir.ClosureExpr).Func = newfn
+	newfn.OClosure = m.(*ir.ClosureExpr)
+
+	if subst.newclofn != nil {
+		//fmt.Printf("Inlining a closure with a nested closure\n")
+	}
+	prevxfunc := subst.newclofn
+
+	// Mark that we are now substituting within a closure (within the
+	// inlined function), and create new nodes for all the local
+	// vars/params inside this closure.
+	subst.newclofn = newfn
+	newfn.Dcl = nil
+	newfn.ClosureVars = nil
+	for _, oldv := range oldfn.Dcl {
+		newv := subst.clovar(oldv)
+		subst.inlvars[oldv] = newv
+		newfn.Dcl = append(newfn.Dcl, newv)
+	}
+	for _, oldv := range oldfn.ClosureVars {
+		newv := subst.clovar(oldv)
+		subst.inlvars[oldv] = newv
+		newfn.ClosureVars = append(newfn.ClosureVars, newv)
+	}
+
+	// Need to replace ONAME nodes in
+	// newfn.Type().FuncType().Receiver/Params/Results.FieldSlice().Nname
+	oldt := oldfn.Type()
+	newrecvs := subst.fields(oldt.Recvs())
+	var newrecv *types.Field
+	if len(newrecvs) > 0 {
+		newrecv = newrecvs[0]
+	}
+	newt := types.NewSignature(oldt.Pkg(), newrecv,
+		nil, subst.fields(oldt.Params()), subst.fields(oldt.Results()))
+
+	newfn.Nname.SetType(newt)
+	newfn.Body = subst.list(oldfn.Body)
+
+	// Remove the nodes for the current closure from subst.inlvars
+	for _, oldv := range oldfn.Dcl {
+		delete(subst.inlvars, oldv)
+	}
+	for _, oldv := range oldfn.ClosureVars {
+		delete(subst.inlvars, oldv)
+	}
+	// Go back to previous closure func
+	subst.newclofn = prevxfunc
+
+	// Actually create the named function for the closure, now that
+	// the closure is inlined in a specific function.
+	m.SetTypecheck(0)
+	if oldfn.ClosureCalled() {
+		typecheck.Callee(m)
+	} else {
+		typecheck.Expr(m)
+	}
+	return m
+}
+
+// node recursively copies a node from the saved pristine body of the
+// inlined function, substituting references to input/output
+// parameters with ones to the tmpnames, and substituting returns with
+// assignments to the output.
+func (subst *inlsubst) node(n ir.Node) ir.Node {
+	if n == nil {
+		return nil
+	}
+
+	switch n.Op() {
+	case ir.ONAME:
+		n := n.(*ir.Name)
+
+		// Handle captured variables when inlining closures.
+		if n.IsClosureVar() && subst.newclofn == nil {
+			o := n.Outer
+
+			// Deal with case where sequence of closures are inlined.
+			// TODO(danscales) - write test case to see if we need to
+			// go up multiple levels.
+			if o.Curfn != ir.CurFunc {
+				o = o.Outer
+			}
+
+			// make sure the outer param matches the inlining location
+			if o == nil || o.Curfn != ir.CurFunc {
+				base.Fatalf("%v: unresolvable capture %v\n", ir.Line(n), n)
+			}
+
+			if base.Flag.LowerM > 2 {
+				fmt.Printf("substituting captured name %+v  ->  %+v\n", n, o)
+			}
+			return o
+		}
+
+		if inlvar := subst.inlvars[n]; inlvar != nil { // These will be set during inlnode
+			if base.Flag.LowerM > 2 {
+				fmt.Printf("substituting name %+v  ->  %+v\n", n, inlvar)
+			}
+			return inlvar
+		}
+
+		if base.Flag.LowerM > 2 {
+			fmt.Printf("not substituting name %+v\n", n)
+		}
+		return n
+
+	case ir.OMETHEXPR:
+		n := n.(*ir.SelectorExpr)
+		return n
+
+	case ir.OLITERAL, ir.ONIL, ir.OTYPE:
+		// If n is a named constant or type, we can continue
+		// using it in the inline copy. Otherwise, make a copy
+		// so we can update the line number.
+		if n.Sym() != nil {
+			return n
+		}
+
+	case ir.ORETURN:
+		if subst.newclofn != nil {
+			// Don't do special substitutions if inside a closure
+			break
+		}
+		// Since we don't handle bodies with closures,
+		// this return is guaranteed to belong to the current inlined function.
+		n := n.(*ir.ReturnStmt)
+		init := subst.list(n.Init())
+		if len(subst.retvars) != 0 && len(n.Results) != 0 {
+			as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil)
+
+			// Make a shallow copy of retvars.
+			// Otherwise OINLCALL.Rlist will be the same list,
+			// and later walk and typecheck may clobber it.
+			for _, n := range subst.retvars {
+				as.Lhs.Append(n)
+			}
+			as.Rhs = subst.list(n.Results)
+
+			if subst.delayretvars {
+				for _, n := range as.Lhs {
+					as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, n.(*ir.Name)))
+					n.Name().Defn = as
+				}
+			}
+
+			init = append(init, typecheck.Stmt(as))
+		}
+		init = append(init, ir.NewBranchStmt(base.Pos, ir.OGOTO, subst.retlabel))
+		typecheck.Stmts(init)
+		return ir.NewBlockStmt(base.Pos, init)
+
+	case ir.OGOTO:
+		if subst.newclofn != nil {
+			// Don't do special substitutions if inside a closure
+			break
+		}
+		n := n.(*ir.BranchStmt)
+		m := ir.Copy(n).(*ir.BranchStmt)
+		m.SetPos(subst.updatedPos(m.Pos()))
+		*m.PtrInit() = nil
+		p := fmt.Sprintf("%s·%d", n.Label.Name, inlgen)
+		m.Label = typecheck.Lookup(p)
+		return m
+
+	case ir.OLABEL:
+		if subst.newclofn != nil {
+			// Don't do special substitutions if inside a closure
+			break
+		}
+		n := n.(*ir.LabelStmt)
+		m := ir.Copy(n).(*ir.LabelStmt)
+		m.SetPos(subst.updatedPos(m.Pos()))
+		*m.PtrInit() = nil
+		p := fmt.Sprintf("%s·%d", n.Label.Name, inlgen)
+		m.Label = typecheck.Lookup(p)
+		return m
+
+	case ir.OCLOSURE:
+		return subst.closure(n.(*ir.ClosureExpr))
+
+	}
+
+	m := ir.Copy(n)
+	m.SetPos(subst.updatedPos(m.Pos()))
+	ir.EditChildren(m, subst.edit)
+
+	switch m := m.(type) {
+	case *ir.AssignStmt:
+		if lhs, ok := m.X.(*ir.Name); ok && lhs.Defn == &subst.defnMarker {
+			lhs.Defn = m
+		}
+	case *ir.AssignListStmt:
+		for _, lhs := range m.Lhs {
+			if lhs, ok := lhs.(*ir.Name); ok && lhs.Defn == &subst.defnMarker {
+				lhs.Defn = m
+			}
+		}
+	}
+
+	return m
+}
+
+func (subst *inlsubst) updatedPos(xpos src.XPos) src.XPos {
+	if subst.noPosUpdate {
+		return xpos
+	}
+	pos := base.Ctxt.PosTable.Pos(xpos)
+	oldbase := pos.Base() // can be nil
+	newbase := subst.bases[oldbase]
+	if newbase == nil {
+		newbase = src.NewInliningBase(oldbase, subst.newInlIndex)
+		subst.bases[oldbase] = newbase
+	}
+	pos.SetBase(newbase)
+	return base.Ctxt.PosTable.XPos(pos)
+}
+
+func pruneUnusedAutos(ll []*ir.Name, vis *hairyVisitor) []*ir.Name {
+	s := make([]*ir.Name, 0, len(ll))
+	for _, n := range ll {
+		if n.Class == ir.PAUTO {
+			if !vis.usedLocals.Has(n) {
+				continue
+			}
+		}
+		s = append(s, n)
+	}
+	return s
+}
+
+// numNonClosures returns the number of functions in list which are not closures.
+func numNonClosures(list []*ir.Func) int {
+	count := 0
+	for _, fn := range list {
+		if fn.OClosure == nil {
+			count++
+		}
+	}
+	return count
+}
+
+func doList(list []ir.Node, do func(ir.Node) bool) bool {
+	for _, x := range list {
+		if x != nil {
+			if do(x) {
+				return true
+			}
+		}
+	}
+	return false
+}
diff --git a/src/cmd/compile/internal/ir/bitset.go b/src/cmd/compile/internal/ir/bitset.go
new file mode 100644
index 0000000..0c7bd54
--- /dev/null
+++ b/src/cmd/compile/internal/ir/bitset.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 ir
+
+type bitset8 uint8
+
+func (f *bitset8) set(mask uint8, b bool) {
+	if b {
+		*(*uint8)(f) |= mask
+	} else {
+		*(*uint8)(f) &^= mask
+	}
+}
+
+func (f bitset8) get2(shift uint8) uint8 {
+	return uint8(f>>shift) & 3
+}
+
+// set2 sets two bits in f using the bottom two bits of b.
+func (f *bitset8) set2(shift uint8, b uint8) {
+	// Clear old bits.
+	*(*uint8)(f) &^= 3 << shift
+	// Set new bits.
+	*(*uint8)(f) |= uint8(b&3) << shift
+}
+
+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) {
+	if b {
+		*(*uint32)(f) |= mask
+	} else {
+		*(*uint32)(f) &^= mask
+	}
+}
+
+func (f bitset32) get2(shift uint8) uint8 {
+	return uint8(f>>shift) & 3
+}
+
+// set2 sets two bits in f using the bottom two bits of b.
+func (f *bitset32) set2(shift uint8, b uint8) {
+	// Clear old bits.
+	*(*uint32)(f) &^= 3 << shift
+	// Set new bits.
+	*(*uint32)(f) |= uint32(b&3) << shift
+}
+
+func (f bitset32) get3(shift uint8) uint8 {
+	return uint8(f>>shift) & 7
+}
+
+// set3 sets three bits in f using the bottom three bits of b.
+func (f *bitset32) set3(shift uint8, b uint8) {
+	// Clear old bits.
+	*(*uint32)(f) &^= 7 << shift
+	// Set new bits.
+	*(*uint32)(f) |= uint32(b&7) << shift
+}
diff --git a/src/cmd/compile/internal/ir/cfg.go b/src/cmd/compile/internal/ir/cfg.go
new file mode 100644
index 0000000..d986ac3
--- /dev/null
+++ b/src/cmd/compile/internal/ir/cfg.go
@@ -0,0 +1,26 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+var (
+	// maximum size variable which we will allocate on the stack.
+	// This limit is for explicit variable declarations like "var x T" or "x := ...".
+	// Note: the flag smallframes can update this value.
+	MaxStackVarSize = int64(10 * 1024 * 1024)
+
+	// maximum size of implicit variables that we will allocate on the stack.
+	//   p := new(T)          allocating T on the stack
+	//   p := &T{}            allocating T on the stack
+	//   s := make([]T, n)    allocating [n]T on the stack
+	//   s := []byte("...")   allocating [n]byte on the stack
+	// Note: the flag smallframes can update this value.
+	MaxImplicitStackVarSize = int64(64 * 1024)
+
+	// MaxSmallArraySize is the maximum size of an array which is considered small.
+	// Small arrays will be initialized directly with a sequence of constant stores.
+	// Large arrays will be initialized by copying from a static temp.
+	// 256 bytes was chosen to minimize generated code + statictmp size.
+	MaxSmallArraySize = int64(256)
+)
diff --git a/src/cmd/compile/internal/ir/class_string.go b/src/cmd/compile/internal/ir/class_string.go
new file mode 100644
index 0000000..11a94c0
--- /dev/null
+++ b/src/cmd/compile/internal/ir/class_string.go
@@ -0,0 +1,30 @@
+// Code generated by "stringer -type=Class name.go"; DO NOT EDIT.
+
+package ir
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[Pxxx-0]
+	_ = x[PEXTERN-1]
+	_ = x[PAUTO-2]
+	_ = x[PAUTOHEAP-3]
+	_ = x[PPARAM-4]
+	_ = x[PPARAMOUT-5]
+	_ = x[PTYPEPARAM-6]
+	_ = x[PFUNC-7]
+}
+
+const _Class_name = "PxxxPEXTERNPAUTOPAUTOHEAPPPARAMPPARAMOUTPTYPEPARAMPFUNC"
+
+var _Class_index = [...]uint8{0, 4, 11, 16, 25, 31, 40, 50, 55}
+
+func (i Class) String() string {
+	if i >= Class(len(_Class_index)-1) {
+		return "Class(" + strconv.FormatInt(int64(i), 10) + ")"
+	}
+	return _Class_name[_Class_index[i]:_Class_index[i+1]]
+}
diff --git a/src/cmd/compile/internal/ir/const.go b/src/cmd/compile/internal/ir/const.go
new file mode 100644
index 0000000..eaa4d5b
--- /dev/null
+++ b/src/cmd/compile/internal/ir/const.go
@@ -0,0 +1,99 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"go/constant"
+	"math"
+	"math/big"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/types"
+)
+
+func NewBool(b bool) Node {
+	return NewLiteral(constant.MakeBool(b))
+}
+
+func NewInt(v int64) Node {
+	return NewLiteral(constant.MakeInt64(v))
+}
+
+func NewString(s string) Node {
+	return NewLiteral(constant.MakeString(s))
+}
+
+const (
+	// Maximum size in bits for big.Ints before signalling
+	// overflow and also mantissa precision for big.Floats.
+	ConstPrec = 512
+)
+
+func BigFloat(v constant.Value) *big.Float {
+	f := new(big.Float)
+	f.SetPrec(ConstPrec)
+	switch u := constant.Val(v).(type) {
+	case int64:
+		f.SetInt64(u)
+	case *big.Int:
+		f.SetInt(u)
+	case *big.Float:
+		f.Set(u)
+	case *big.Rat:
+		f.SetRat(u)
+	default:
+		base.Fatalf("unexpected: %v", u)
+	}
+	return f
+}
+
+// ConstOverflow reports whether constant value v is too large
+// to represent with type t.
+func ConstOverflow(v constant.Value, t *types.Type) bool {
+	switch {
+	case t.IsInteger():
+		bits := uint(8 * t.Size())
+		if t.IsUnsigned() {
+			x, ok := constant.Uint64Val(v)
+			return !ok || x>>bits != 0
+		}
+		x, ok := constant.Int64Val(v)
+		if x < 0 {
+			x = ^x
+		}
+		return !ok || x>>(bits-1) != 0
+	case t.IsFloat():
+		switch t.Size() {
+		case 4:
+			f, _ := constant.Float32Val(v)
+			return math.IsInf(float64(f), 0)
+		case 8:
+			f, _ := constant.Float64Val(v)
+			return math.IsInf(f, 0)
+		}
+	case t.IsComplex():
+		ft := types.FloatForComplex(t)
+		return ConstOverflow(constant.Real(v), ft) || ConstOverflow(constant.Imag(v), ft)
+	}
+	base.Fatalf("ConstOverflow: %v, %v", v, t)
+	panic("unreachable")
+}
+
+// IsConstNode reports whether n is a Go language constant (as opposed to a
+// compile-time constant).
+//
+// Expressions derived from nil, like string([]byte(nil)), while they
+// may be known at compile time, are not Go language constants.
+func IsConstNode(n Node) bool {
+	return n.Op() == OLITERAL
+}
+
+func IsSmallIntConst(n Node) bool {
+	if n.Op() == OLITERAL {
+		v, ok := constant.Int64Val(n.Val())
+		return ok && int64(int32(v)) == v
+	}
+	return false
+}
diff --git a/src/cmd/compile/internal/ir/copy.go b/src/cmd/compile/internal/ir/copy.go
new file mode 100644
index 0000000..7da9b24
--- /dev/null
+++ b/src/cmd/compile/internal/ir/copy.go
@@ -0,0 +1,102 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/internal/src"
+)
+
+// A Node may implement the Orig and SetOrig method to
+// maintain a pointer to the "unrewritten" form of a Node.
+// If a Node does not implement OrigNode, it is its own Orig.
+//
+// Note that both SepCopy and Copy have definitions compatible
+// with a Node that does not implement OrigNode: such a Node
+// is its own Orig, and in that case, that's what both want to return
+// anyway (SepCopy unconditionally, and Copy only when the input
+// is its own Orig as well, but if the output does not implement
+// OrigNode, then neither does the input, making the condition true).
+type OrigNode interface {
+	Node
+	Orig() Node
+	SetOrig(Node)
+}
+
+// origNode may be embedded into a Node to make it implement OrigNode.
+type origNode struct {
+	orig Node `mknode:"-"`
+}
+
+func (n *origNode) Orig() Node     { return n.orig }
+func (n *origNode) SetOrig(o Node) { n.orig = o }
+
+// Orig returns the “original” node for n.
+// If n implements OrigNode, Orig returns n.Orig().
+// Otherwise Orig returns n itself.
+func Orig(n Node) Node {
+	if n, ok := n.(OrigNode); ok {
+		o := n.Orig()
+		if o == nil {
+			Dump("Orig nil", n)
+			base.Fatalf("Orig returned nil")
+		}
+		return o
+	}
+	return n
+}
+
+// SepCopy returns a separate shallow copy of n,
+// breaking any Orig link to any other nodes.
+func SepCopy(n Node) Node {
+	n = n.copy()
+	if n, ok := n.(OrigNode); ok {
+		n.SetOrig(n)
+	}
+	return n
+}
+
+// Copy returns a shallow copy of n.
+// If Orig(n) == n, then Orig(Copy(n)) == the copy.
+// Otherwise the Orig link is preserved as well.
+//
+// The specific semantics surrounding Orig are subtle but right for most uses.
+// See issues #26855 and #27765 for pitfalls.
+func Copy(n Node) Node {
+	c := n.copy()
+	if n, ok := n.(OrigNode); ok && n.Orig() == n {
+		c.(OrigNode).SetOrig(c)
+	}
+	return c
+}
+
+// DeepCopy returns a “deep” copy of n, with its entire structure copied
+// (except for shared nodes like ONAME, ONONAME, OLITERAL, and OTYPE).
+// If pos.IsKnown(), it sets the source position of newly allocated Nodes to pos.
+func DeepCopy(pos src.XPos, n Node) Node {
+	var edit func(Node) Node
+	edit = func(x Node) Node {
+		switch x.Op() {
+		case OPACK, ONAME, ONONAME, OLITERAL, ONIL, OTYPE:
+			return x
+		}
+		x = Copy(x)
+		if pos.IsKnown() {
+			x.SetPos(pos)
+		}
+		EditChildren(x, edit)
+		return x
+	}
+	return edit(n)
+}
+
+// DeepCopyList returns a list of deep copies (using DeepCopy) of the nodes in list.
+func DeepCopyList(pos src.XPos, list []Node) []Node {
+	var out []Node
+	for _, n := range list {
+		out = append(out, DeepCopy(pos, n))
+	}
+	return out
+}
diff --git a/src/cmd/compile/internal/ir/dump.go b/src/cmd/compile/internal/ir/dump.go
new file mode 100644
index 0000000..59914ba
--- /dev/null
+++ b/src/cmd/compile/internal/ir/dump.go
@@ -0,0 +1,272 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements textual dumping of arbitrary data structures
+// for debugging purposes. The code is customized for Node graphs
+// and may be used for an alternative view of the node structure.
+
+package ir
+
+import (
+	"fmt"
+	"io"
+	"os"
+	"reflect"
+	"regexp"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// DumpAny is like FDumpAny but prints to stderr.
+func DumpAny(root interface{}, filter string, depth int) {
+	FDumpAny(os.Stderr, root, filter, depth)
+}
+
+// FDumpAny prints the structure of a rooted data structure
+// to w by depth-first traversal of the data structure.
+//
+// The filter parameter is a regular expression. If it is
+// non-empty, only struct fields whose names match filter
+// are printed.
+//
+// The depth parameter controls how deep traversal recurses
+// before it returns (higher value means greater depth).
+// If an empty field filter is given, a good depth default value
+// is 4. A negative depth means no depth limit, which may be fine
+// for small data structures or if there is a non-empty filter.
+//
+// In the output, Node structs are identified by their Op name
+// rather than their type; struct fields with zero values or
+// non-matching field names are omitted, and "…" means recursion
+// depth has been reached or struct fields have been omitted.
+func FDumpAny(w io.Writer, root interface{}, filter string, depth int) {
+	if root == nil {
+		fmt.Fprintln(w, "nil")
+		return
+	}
+
+	if filter == "" {
+		filter = ".*" // default
+	}
+
+	p := dumper{
+		output:  w,
+		fieldrx: regexp.MustCompile(filter),
+		ptrmap:  make(map[uintptr]int),
+		last:    '\n', // force printing of line number on first line
+	}
+
+	p.dump(reflect.ValueOf(root), depth)
+	p.printf("\n")
+}
+
+type dumper struct {
+	output  io.Writer
+	fieldrx *regexp.Regexp  // field name filter
+	ptrmap  map[uintptr]int // ptr -> dump line number
+	lastadr string          // last address string printed (for shortening)
+
+	// output
+	indent int  // current indentation level
+	last   byte // last byte processed by Write
+	line   int  // current line number
+}
+
+var indentBytes = []byte(".  ")
+
+func (p *dumper) Write(data []byte) (n int, err error) {
+	var m int
+	for i, b := range data {
+		// invariant: data[0:n] has been written
+		if b == '\n' {
+			m, err = p.output.Write(data[n : i+1])
+			n += m
+			if err != nil {
+				return
+			}
+		} else if p.last == '\n' {
+			p.line++
+			_, err = fmt.Fprintf(p.output, "%6d  ", p.line)
+			if err != nil {
+				return
+			}
+			for j := p.indent; j > 0; j-- {
+				_, err = p.output.Write(indentBytes)
+				if err != nil {
+					return
+				}
+			}
+		}
+		p.last = b
+	}
+	if len(data) > n {
+		m, err = p.output.Write(data[n:])
+		n += m
+	}
+	return
+}
+
+// printf is a convenience wrapper.
+func (p *dumper) printf(format string, args ...interface{}) {
+	if _, err := fmt.Fprintf(p, format, args...); err != nil {
+		panic(err)
+	}
+}
+
+// addr returns the (hexadecimal) address string of the object
+// represented by x (or "?" if x is not addressable), with the
+// common prefix between this and the prior address replaced by
+// "0x…" to make it easier to visually match addresses.
+func (p *dumper) addr(x reflect.Value) string {
+	if !x.CanAddr() {
+		return "?"
+	}
+	adr := fmt.Sprintf("%p", x.Addr().Interface())
+	s := adr
+	if i := commonPrefixLen(p.lastadr, adr); i > 0 {
+		s = "0x…" + adr[i:]
+	}
+	p.lastadr = adr
+	return s
+}
+
+// dump prints the contents of x.
+func (p *dumper) dump(x reflect.Value, depth int) {
+	if depth == 0 {
+		p.printf("…")
+		return
+	}
+
+	if pos, ok := x.Interface().(src.XPos); ok {
+		p.printf("%s", base.FmtPos(pos))
+		return
+	}
+
+	switch x.Kind() {
+	case reflect.String:
+		p.printf("%q", x.Interface()) // print strings in quotes
+
+	case reflect.Interface:
+		if x.IsNil() {
+			p.printf("nil")
+			return
+		}
+		p.dump(x.Elem(), depth-1)
+
+	case reflect.Ptr:
+		if x.IsNil() {
+			p.printf("nil")
+			return
+		}
+
+		p.printf("*")
+		ptr := x.Pointer()
+		if line, exists := p.ptrmap[ptr]; exists {
+			p.printf("(@%d)", line)
+			return
+		}
+		p.ptrmap[ptr] = p.line
+		p.dump(x.Elem(), depth) // don't count pointer indirection towards depth
+
+	case reflect.Slice:
+		if x.IsNil() {
+			p.printf("nil")
+			return
+		}
+		p.printf("%s (%d entries) {", x.Type(), x.Len())
+		if x.Len() > 0 {
+			p.indent++
+			p.printf("\n")
+			for i, n := 0, x.Len(); i < n; i++ {
+				p.printf("%d: ", i)
+				p.dump(x.Index(i), depth-1)
+				p.printf("\n")
+			}
+			p.indent--
+		}
+		p.printf("}")
+
+	case reflect.Struct:
+		typ := x.Type()
+
+		isNode := false
+		if n, ok := x.Interface().(Node); ok {
+			isNode = true
+			p.printf("%s %s {", n.Op().String(), p.addr(x))
+		} else {
+			p.printf("%s {", typ)
+		}
+		p.indent++
+
+		first := true
+		omitted := false
+		for i, n := 0, typ.NumField(); i < n; i++ {
+			// Exclude non-exported fields because their
+			// values cannot be accessed via reflection.
+			if name := typ.Field(i).Name; types.IsExported(name) {
+				if !p.fieldrx.MatchString(name) {
+					omitted = true
+					continue // field name not selected by filter
+				}
+
+				// special cases
+				if isNode && name == "Op" {
+					omitted = true
+					continue // Op field already printed for Nodes
+				}
+				x := x.Field(i)
+				if isZeroVal(x) {
+					omitted = true
+					continue // exclude zero-valued fields
+				}
+				if n, ok := x.Interface().(Nodes); ok && len(n) == 0 {
+					omitted = true
+					continue // exclude empty Nodes slices
+				}
+
+				if first {
+					p.printf("\n")
+					first = false
+				}
+				p.printf("%s: ", name)
+				p.dump(x, depth-1)
+				p.printf("\n")
+			}
+		}
+		if omitted {
+			p.printf("…\n")
+		}
+
+		p.indent--
+		p.printf("}")
+
+	default:
+		p.printf("%v", x.Interface())
+	}
+}
+
+func isZeroVal(x reflect.Value) bool {
+	switch x.Kind() {
+	case reflect.Bool:
+		return !x.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return x.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return x.Uint() == 0
+	case reflect.String:
+		return x.String() == ""
+	case reflect.Interface, reflect.Ptr, reflect.Slice:
+		return x.IsNil()
+	}
+	return false
+}
+
+func commonPrefixLen(a, b string) (i int) {
+	for i < len(a) && i < len(b) && a[i] == b[i] {
+		i++
+	}
+	return
+}
diff --git a/src/cmd/compile/internal/ir/expr.go b/src/cmd/compile/internal/ir/expr.go
new file mode 100644
index 0000000..f70645f
--- /dev/null
+++ b/src/cmd/compile/internal/ir/expr.go
@@ -0,0 +1,1079 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"bytes"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/src"
+	"fmt"
+	"go/constant"
+	"go/token"
+)
+
+// An Expr is a Node that can appear as an expression.
+type Expr interface {
+	Node
+	isExpr()
+}
+
+// A miniExpr is a miniNode with extra fields common to expressions.
+// TODO(rsc): Once we are sure about the contents, compact the bools
+// into a bit field and leave extra bits available for implementations
+// embedding miniExpr. Right now there are ~60 unused bits sitting here.
+type miniExpr struct {
+	miniNode
+	typ   *types.Type
+	init  Nodes // TODO(rsc): Don't require every Node to have an init
+	flags bitset8
+}
+
+const (
+	miniExprNonNil = 1 << iota
+	miniExprTransient
+	miniExprBounded
+	miniExprImplicit // for use by implementations; not supported by every Expr
+	miniExprCheckPtr
+)
+
+func (*miniExpr) isExpr() {}
+
+func (n *miniExpr) Type() *types.Type     { return n.typ }
+func (n *miniExpr) SetType(x *types.Type) { n.typ = x }
+func (n *miniExpr) NonNil() bool          { return n.flags&miniExprNonNil != 0 }
+func (n *miniExpr) MarkNonNil()           { n.flags |= miniExprNonNil }
+func (n *miniExpr) Transient() bool       { return n.flags&miniExprTransient != 0 }
+func (n *miniExpr) SetTransient(b bool)   { n.flags.set(miniExprTransient, b) }
+func (n *miniExpr) Bounded() bool         { return n.flags&miniExprBounded != 0 }
+func (n *miniExpr) SetBounded(b bool)     { n.flags.set(miniExprBounded, b) }
+func (n *miniExpr) Init() Nodes           { return n.init }
+func (n *miniExpr) PtrInit() *Nodes       { return &n.init }
+func (n *miniExpr) SetInit(x Nodes)       { n.init = x }
+
+// An AddStringExpr is a string concatenation Expr[0] + Exprs[1] + ... + Expr[len(Expr)-1].
+type AddStringExpr struct {
+	miniExpr
+	List     Nodes
+	Prealloc *Name
+}
+
+func NewAddStringExpr(pos src.XPos, list []Node) *AddStringExpr {
+	n := &AddStringExpr{}
+	n.pos = pos
+	n.op = OADDSTR
+	n.List = list
+	return n
+}
+
+// An AddrExpr is an address-of expression &X.
+// It may end up being a normal address-of or an allocation of a composite literal.
+type AddrExpr struct {
+	miniExpr
+	X        Node
+	Prealloc *Name // preallocated storage if any
+}
+
+func NewAddrExpr(pos src.XPos, x Node) *AddrExpr {
+	n := &AddrExpr{X: x}
+	n.op = OADDR
+	n.pos = pos
+	return n
+}
+
+func (n *AddrExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
+func (n *AddrExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
+
+func (n *AddrExpr) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OADDR, OPTRLIT:
+		n.op = op
+	}
+}
+
+// A BasicLit is a literal of basic type.
+type BasicLit struct {
+	miniExpr
+	val constant.Value
+}
+
+func NewBasicLit(pos src.XPos, val constant.Value) Node {
+	n := &BasicLit{val: val}
+	n.op = OLITERAL
+	n.pos = pos
+	if k := val.Kind(); k != constant.Unknown {
+		n.SetType(idealType(k))
+	}
+	return n
+}
+
+func (n *BasicLit) Val() constant.Value       { return n.val }
+func (n *BasicLit) SetVal(val constant.Value) { n.val = val }
+
+// A BinaryExpr is a binary expression X Op Y,
+// or Op(X, Y) for builtin functions that do not become calls.
+type BinaryExpr struct {
+	miniExpr
+	X Node
+	Y Node
+}
+
+func NewBinaryExpr(pos src.XPos, op Op, x, y Node) *BinaryExpr {
+	n := &BinaryExpr{X: x, Y: y}
+	n.pos = pos
+	n.SetOp(op)
+	return n
+}
+
+func (n *BinaryExpr) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OADD, OADDSTR, OAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE,
+		OLSH, OLT, OMOD, OMUL, ONE, OOR, ORSH, OSUB, OXOR,
+		OCOPY, OCOMPLEX, OUNSAFEADD, OUNSAFESLICE,
+		OEFACE:
+		n.op = op
+	}
+}
+
+// A CallUse records how the result of the call is used:
+type CallUse byte
+
+const (
+	_ CallUse = iota
+
+	CallUseExpr // single expression result is used
+	CallUseList // list of results are used
+	CallUseStmt // results not used - call is a statement
+)
+
+// A CallExpr is a function call X(Args).
+type CallExpr struct {
+	miniExpr
+	origNode
+	X               Node
+	Args            Nodes
+	KeepAlive       []*Name // vars to be kept alive until call returns
+	IsDDD           bool
+	Use             CallUse
+	NoInline        bool
+	PreserveClosure bool // disable directClosureCall for this call
+}
+
+func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
+	n := &CallExpr{X: fun}
+	n.pos = pos
+	n.orig = n
+	n.SetOp(op)
+	n.Args = args
+	return n
+}
+
+func (*CallExpr) isStmt() {}
+
+func (n *CallExpr) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH,
+		OAPPEND, ODELETE, OGETG, OMAKE, OPRINT, OPRINTN, ORECOVER:
+		n.op = op
+	}
+}
+
+// A ClosureExpr is a function literal expression.
+type ClosureExpr struct {
+	miniExpr
+	Func     *Func `mknode:"-"`
+	Prealloc *Name
+}
+
+func NewClosureExpr(pos src.XPos, fn *Func) *ClosureExpr {
+	n := &ClosureExpr{Func: fn}
+	n.op = OCLOSURE
+	n.pos = pos
+	return n
+}
+
+// A CompLitExpr is a composite literal Type{Vals}.
+// Before type-checking, the type is Ntype.
+type CompLitExpr struct {
+	miniExpr
+	origNode
+	Ntype    Ntype
+	List     Nodes // initialized values
+	Prealloc *Name
+	Len      int64 // backing array length for OSLICELIT
+}
+
+func NewCompLitExpr(pos src.XPos, op Op, typ Ntype, list []Node) *CompLitExpr {
+	n := &CompLitExpr{Ntype: typ}
+	n.pos = pos
+	n.SetOp(op)
+	n.List = list
+	n.orig = n
+	return n
+}
+
+func (n *CompLitExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
+func (n *CompLitExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
+
+func (n *CompLitExpr) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OARRAYLIT, OCOMPLIT, OMAPLIT, OSTRUCTLIT, OSLICELIT:
+		n.op = op
+	}
+}
+
+type ConstExpr struct {
+	miniExpr
+	origNode
+	val constant.Value
+}
+
+func NewConstExpr(val constant.Value, orig Node) Node {
+	n := &ConstExpr{val: val}
+	n.op = OLITERAL
+	n.pos = orig.Pos()
+	n.orig = orig
+	n.SetType(orig.Type())
+	n.SetTypecheck(orig.Typecheck())
+	n.SetDiag(orig.Diag())
+	return n
+}
+
+func (n *ConstExpr) Sym() *types.Sym     { return n.orig.Sym() }
+func (n *ConstExpr) Val() constant.Value { return n.val }
+
+// A ConvExpr is a conversion Type(X).
+// It may end up being a value or a type.
+type ConvExpr struct {
+	miniExpr
+	X Node
+}
+
+func NewConvExpr(pos src.XPos, op Op, typ *types.Type, x Node) *ConvExpr {
+	n := &ConvExpr{X: x}
+	n.pos = pos
+	n.typ = typ
+	n.SetOp(op)
+	return n
+}
+
+func (n *ConvExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
+func (n *ConvExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
+func (n *ConvExpr) CheckPtr() bool     { return n.flags&miniExprCheckPtr != 0 }
+func (n *ConvExpr) SetCheckPtr(b bool) { n.flags.set(miniExprCheckPtr, b) }
+
+func (n *ConvExpr) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARRPTR:
+		n.op = op
+	}
+}
+
+// An IndexExpr is an index expression X[Y].
+type IndexExpr struct {
+	miniExpr
+	X        Node
+	Index    Node
+	Assigned bool
+}
+
+func NewIndexExpr(pos src.XPos, x, index Node) *IndexExpr {
+	n := &IndexExpr{X: x, Index: index}
+	n.pos = pos
+	n.op = OINDEX
+	return n
+}
+
+func (n *IndexExpr) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OINDEX, OINDEXMAP:
+		n.op = op
+	}
+}
+
+// A KeyExpr is a Key: Value composite literal key.
+type KeyExpr struct {
+	miniExpr
+	Key   Node
+	Value Node
+}
+
+func NewKeyExpr(pos src.XPos, key, value Node) *KeyExpr {
+	n := &KeyExpr{Key: key, Value: value}
+	n.pos = pos
+	n.op = OKEY
+	return n
+}
+
+// A StructKeyExpr is an Field: Value composite literal key.
+type StructKeyExpr struct {
+	miniExpr
+	Field  *types.Sym
+	Value  Node
+	Offset int64
+}
+
+func NewStructKeyExpr(pos src.XPos, field *types.Sym, value Node) *StructKeyExpr {
+	n := &StructKeyExpr{Field: field, Value: value}
+	n.pos = pos
+	n.op = OSTRUCTKEY
+	n.Offset = types.BADWIDTH
+	return n
+}
+
+func (n *StructKeyExpr) Sym() *types.Sym { return n.Field }
+
+// An InlinedCallExpr is an inlined function call.
+type InlinedCallExpr struct {
+	miniExpr
+	Body       Nodes
+	ReturnVars Nodes
+}
+
+func NewInlinedCallExpr(pos src.XPos, body, retvars []Node) *InlinedCallExpr {
+	n := &InlinedCallExpr{}
+	n.pos = pos
+	n.op = OINLCALL
+	n.Body = body
+	n.ReturnVars = retvars
+	return n
+}
+
+// A LogicalExpr is a expression X Op Y where Op is && or ||.
+// It is separate from BinaryExpr to make room for statements
+// that must be executed before Y but after X.
+type LogicalExpr struct {
+	miniExpr
+	X Node
+	Y Node
+}
+
+func NewLogicalExpr(pos src.XPos, op Op, x, y Node) *LogicalExpr {
+	n := &LogicalExpr{X: x, Y: y}
+	n.pos = pos
+	n.SetOp(op)
+	return n
+}
+
+func (n *LogicalExpr) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OANDAND, OOROR:
+		n.op = op
+	}
+}
+
+// A MakeExpr is a make expression: make(Type[, Len[, Cap]]).
+// Op is OMAKECHAN, OMAKEMAP, OMAKESLICE, or OMAKESLICECOPY,
+// but *not* OMAKE (that's a pre-typechecking CallExpr).
+type MakeExpr struct {
+	miniExpr
+	Len Node
+	Cap Node
+}
+
+func NewMakeExpr(pos src.XPos, op Op, len, cap Node) *MakeExpr {
+	n := &MakeExpr{Len: len, Cap: cap}
+	n.pos = pos
+	n.SetOp(op)
+	return n
+}
+
+func (n *MakeExpr) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OMAKECHAN, OMAKEMAP, OMAKESLICE, OMAKESLICECOPY:
+		n.op = op
+	}
+}
+
+// A NilExpr represents the predefined untyped constant nil.
+// (It may be copied and assigned a type, though.)
+type NilExpr struct {
+	miniExpr
+	Sym_ *types.Sym // TODO: Remove
+}
+
+func NewNilExpr(pos src.XPos) *NilExpr {
+	n := &NilExpr{}
+	n.pos = pos
+	n.op = ONIL
+	return n
+}
+
+func (n *NilExpr) Sym() *types.Sym     { return n.Sym_ }
+func (n *NilExpr) SetSym(x *types.Sym) { n.Sym_ = x }
+
+// A ParenExpr is a parenthesized expression (X).
+// It may end up being a value or a type.
+type ParenExpr struct {
+	miniExpr
+	X Node
+}
+
+func NewParenExpr(pos src.XPos, x Node) *ParenExpr {
+	n := &ParenExpr{X: x}
+	n.op = OPAREN
+	n.pos = pos
+	return n
+}
+
+func (n *ParenExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
+func (n *ParenExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
+
+func (*ParenExpr) CanBeNtype() {}
+
+// SetOTYPE changes n to be an OTYPE node returning t,
+// like all the type nodes in type.go.
+func (n *ParenExpr) SetOTYPE(t *types.Type) {
+	n.op = OTYPE
+	n.typ = t
+	t.SetNod(n)
+}
+
+// A ResultExpr represents a direct access to a result.
+type ResultExpr struct {
+	miniExpr
+	Index int64 // index of the result expr.
+}
+
+func NewResultExpr(pos src.XPos, typ *types.Type, index int64) *ResultExpr {
+	n := &ResultExpr{Index: index}
+	n.pos = pos
+	n.op = ORESULT
+	n.typ = typ
+	return n
+}
+
+// A LinksymOffsetExpr refers to an offset within a global variable.
+// It is like a SelectorExpr but without the field name.
+type LinksymOffsetExpr struct {
+	miniExpr
+	Linksym *obj.LSym
+	Offset_ int64
+}
+
+func NewLinksymOffsetExpr(pos src.XPos, lsym *obj.LSym, offset int64, typ *types.Type) *LinksymOffsetExpr {
+	n := &LinksymOffsetExpr{Linksym: lsym, Offset_: offset}
+	n.typ = typ
+	n.op = OLINKSYMOFFSET
+	return n
+}
+
+// NewLinksymExpr is NewLinksymOffsetExpr, but with offset fixed at 0.
+func NewLinksymExpr(pos src.XPos, lsym *obj.LSym, typ *types.Type) *LinksymOffsetExpr {
+	return NewLinksymOffsetExpr(pos, lsym, 0, typ)
+}
+
+// NewNameOffsetExpr is NewLinksymOffsetExpr, but taking a *Name
+// representing a global variable instead of an *obj.LSym directly.
+func NewNameOffsetExpr(pos src.XPos, name *Name, offset int64, typ *types.Type) *LinksymOffsetExpr {
+	if name == nil || IsBlank(name) || !(name.Op() == ONAME && name.Class == PEXTERN) {
+		base.FatalfAt(pos, "cannot take offset of nil, blank name or non-global variable: %v", name)
+	}
+	return NewLinksymOffsetExpr(pos, name.Linksym(), offset, typ)
+}
+
+// A SelectorExpr is a selector expression X.Sel.
+type SelectorExpr struct {
+	miniExpr
+	X         Node
+	Sel       *types.Sym
+	Selection *types.Field
+	Prealloc  *Name // preallocated storage for OCALLPART, if any
+}
+
+func NewSelectorExpr(pos src.XPos, op Op, x Node, sel *types.Sym) *SelectorExpr {
+	n := &SelectorExpr{X: x, Sel: sel}
+	n.pos = pos
+	n.SetOp(op)
+	return n
+}
+
+func (n *SelectorExpr) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OCALLPART, OMETHEXPR:
+		n.op = op
+	}
+}
+
+func (n *SelectorExpr) Sym() *types.Sym    { return n.Sel }
+func (n *SelectorExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
+func (n *SelectorExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
+func (n *SelectorExpr) Offset() int64      { return n.Selection.Offset }
+
+func (n *SelectorExpr) FuncName() *Name {
+	if n.Op() != OMETHEXPR {
+		panic(n.no("FuncName"))
+	}
+	fn := NewNameAt(n.Selection.Pos, MethodSym(n.X.Type(), n.Sel))
+	fn.Class = PFUNC
+	fn.SetType(n.Type())
+	if n.Selection.Nname != nil {
+		// TODO(austin): Nname is nil for interface method
+		// expressions (I.M), so we can't attach a Func to
+		// those here. reflectdata.methodWrapper generates the
+		// Func.
+		fn.Func = n.Selection.Nname.(*Name).Func
+	}
+	return fn
+}
+
+// Before type-checking, bytes.Buffer is a SelectorExpr.
+// After type-checking it becomes a Name.
+func (*SelectorExpr) CanBeNtype() {}
+
+// A SliceExpr is a slice expression X[Low:High] or X[Low:High:Max].
+type SliceExpr struct {
+	miniExpr
+	X    Node
+	Low  Node
+	High Node
+	Max  Node
+}
+
+func NewSliceExpr(pos src.XPos, op Op, x, low, high, max Node) *SliceExpr {
+	n := &SliceExpr{X: x, Low: low, High: high, Max: max}
+	n.pos = pos
+	n.op = op
+	return n
+}
+
+func (n *SliceExpr) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR:
+		n.op = op
+	}
+}
+
+// IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
+// o must be a slicing op.
+func (o Op) IsSlice3() bool {
+	switch o {
+	case OSLICE, OSLICEARR, OSLICESTR:
+		return false
+	case OSLICE3, OSLICE3ARR:
+		return true
+	}
+	base.Fatalf("IsSlice3 op %v", o)
+	return false
+}
+
+// A SliceHeader expression constructs a slice header from its parts.
+type SliceHeaderExpr struct {
+	miniExpr
+	Ptr Node
+	Len Node
+	Cap Node
+}
+
+func NewSliceHeaderExpr(pos src.XPos, typ *types.Type, ptr, len, cap Node) *SliceHeaderExpr {
+	n := &SliceHeaderExpr{Ptr: ptr, Len: len, Cap: cap}
+	n.pos = pos
+	n.op = OSLICEHEADER
+	n.typ = typ
+	return n
+}
+
+// A StarExpr is a dereference expression *X.
+// It may end up being a value or a type.
+type StarExpr struct {
+	miniExpr
+	X Node
+}
+
+func NewStarExpr(pos src.XPos, x Node) *StarExpr {
+	n := &StarExpr{X: x}
+	n.op = ODEREF
+	n.pos = pos
+	return n
+}
+
+func (n *StarExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
+func (n *StarExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
+
+func (*StarExpr) CanBeNtype() {}
+
+// SetOTYPE changes n to be an OTYPE node returning t,
+// like all the type nodes in type.go.
+func (n *StarExpr) SetOTYPE(t *types.Type) {
+	n.op = OTYPE
+	n.X = nil
+	n.typ = t
+	t.SetNod(n)
+}
+
+// A TypeAssertionExpr is a selector expression X.(Type).
+// Before type-checking, the type is Ntype.
+type TypeAssertExpr struct {
+	miniExpr
+	X     Node
+	Ntype Ntype
+
+	// Runtime type information provided by walkDotType for
+	// assertions from non-empty interface to concrete type.
+	Itab *AddrExpr `mknode:"-"` // *runtime.itab for Type implementing X's type
+}
+
+func NewTypeAssertExpr(pos src.XPos, x Node, typ Ntype) *TypeAssertExpr {
+	n := &TypeAssertExpr{X: x, Ntype: typ}
+	n.pos = pos
+	n.op = ODOTTYPE
+	return n
+}
+
+func (n *TypeAssertExpr) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case ODOTTYPE, ODOTTYPE2:
+		n.op = op
+	}
+}
+
+// A UnaryExpr is a unary expression Op X,
+// or Op(X) for a builtin function that does not end up being a call.
+type UnaryExpr struct {
+	miniExpr
+	X Node
+}
+
+func NewUnaryExpr(pos src.XPos, op Op, x Node) *UnaryExpr {
+	n := &UnaryExpr{X: x}
+	n.pos = pos
+	n.SetOp(op)
+	return n
+}
+
+func (n *UnaryExpr) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OBITNOT, ONEG, ONOT, OPLUS, ORECV,
+		OALIGNOF, OCAP, OCLOSE, OIMAG, OLEN, ONEW,
+		OOFFSETOF, OPANIC, OREAL, OSIZEOF,
+		OCHECKNIL, OCFUNC, OIDATA, OITAB, OSPTR, OVARDEF, OVARKILL, OVARLIVE:
+		n.op = op
+	}
+}
+
+// An InstExpr is a generic function or type instantiation.
+type InstExpr struct {
+	miniExpr
+	X     Node
+	Targs []Node
+}
+
+func NewInstExpr(pos src.XPos, op Op, x Node, targs []Node) *InstExpr {
+	n := &InstExpr{X: x, Targs: targs}
+	n.pos = pos
+	n.op = op
+	return n
+}
+
+func IsZero(n Node) bool {
+	switch n.Op() {
+	case ONIL:
+		return true
+
+	case OLITERAL:
+		switch u := n.Val(); u.Kind() {
+		case constant.String:
+			return constant.StringVal(u) == ""
+		case constant.Bool:
+			return !constant.BoolVal(u)
+		default:
+			return constant.Sign(u) == 0
+		}
+
+	case OARRAYLIT:
+		n := n.(*CompLitExpr)
+		for _, n1 := range n.List {
+			if n1.Op() == OKEY {
+				n1 = n1.(*KeyExpr).Value
+			}
+			if !IsZero(n1) {
+				return false
+			}
+		}
+		return true
+
+	case OSTRUCTLIT:
+		n := n.(*CompLitExpr)
+		for _, n1 := range n.List {
+			n1 := n1.(*StructKeyExpr)
+			if !IsZero(n1.Value) {
+				return false
+			}
+		}
+		return true
+	}
+
+	return false
+}
+
+// lvalue etc
+func IsAddressable(n Node) bool {
+	switch n.Op() {
+	case OINDEX:
+		n := n.(*IndexExpr)
+		if n.X.Type() != nil && n.X.Type().IsArray() {
+			return IsAddressable(n.X)
+		}
+		if n.X.Type() != nil && n.X.Type().IsString() {
+			return false
+		}
+		fallthrough
+	case ODEREF, ODOTPTR:
+		return true
+
+	case ODOT:
+		n := n.(*SelectorExpr)
+		return IsAddressable(n.X)
+
+	case ONAME:
+		n := n.(*Name)
+		if n.Class == PFUNC {
+			return false
+		}
+		return true
+
+	case OLINKSYMOFFSET:
+		return true
+	}
+
+	return false
+}
+
+func StaticValue(n Node) Node {
+	for {
+		if n.Op() == OCONVNOP {
+			n = n.(*ConvExpr).X
+			continue
+		}
+
+		n1 := staticValue1(n)
+		if n1 == nil {
+			return n
+		}
+		n = n1
+	}
+}
+
+// staticValue1 implements a simple SSA-like optimization. If n is a local variable
+// that is initialized and never reassigned, staticValue1 returns the initializer
+// expression. Otherwise, it returns nil.
+func staticValue1(nn Node) Node {
+	if nn.Op() != ONAME {
+		return nil
+	}
+	n := nn.(*Name)
+	if n.Class != PAUTO {
+		return nil
+	}
+
+	defn := n.Defn
+	if defn == nil {
+		return nil
+	}
+
+	var rhs Node
+FindRHS:
+	switch defn.Op() {
+	case OAS:
+		defn := defn.(*AssignStmt)
+		rhs = defn.Y
+	case OAS2:
+		defn := defn.(*AssignListStmt)
+		for i, lhs := range defn.Lhs {
+			if lhs == n {
+				rhs = defn.Rhs[i]
+				break FindRHS
+			}
+		}
+		base.Fatalf("%v missing from LHS of %v", n, defn)
+	default:
+		return nil
+	}
+	if rhs == nil {
+		base.Fatalf("RHS is nil: %v", defn)
+	}
+
+	if reassigned(n) {
+		return nil
+	}
+
+	return rhs
+}
+
+// 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(name *Name) bool {
+	if name.Op() != ONAME {
+		base.Fatalf("reassigned %v", name)
+	}
+	// no way to reliably check for no-reassignment of globals, assume it can be
+	if name.Curfn == nil {
+		return true
+	}
+
+	// TODO(mdempsky): This is inefficient and becoming increasingly
+	// unwieldy. Figure out a way to generalize escape analysis's
+	// reassignment detection for use by inlining and devirtualization.
+
+	// isName reports whether n is a reference to name.
+	isName := func(x Node) bool {
+		n, ok := x.(*Name)
+		return ok && n.Canonical() == name
+	}
+
+	var do func(n Node) bool
+	do = func(n Node) bool {
+		switch n.Op() {
+		case OAS:
+			n := n.(*AssignStmt)
+			if isName(n.X) && n != name.Defn {
+				return true
+			}
+		case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV, OSELRECV2:
+			n := n.(*AssignListStmt)
+			for _, p := range n.Lhs {
+				if isName(p) && n != name.Defn {
+					return true
+				}
+			}
+		case OADDR:
+			n := n.(*AddrExpr)
+			if isName(OuterValue(n.X)) {
+				return true
+			}
+		case OCLOSURE:
+			n := n.(*ClosureExpr)
+			if Any(n.Func, do) {
+				return true
+			}
+		}
+		return false
+	}
+	return Any(name.Curfn, do)
+}
+
+// IsIntrinsicCall reports whether the compiler back end will treat the call as an intrinsic operation.
+var IsIntrinsicCall = func(*CallExpr) bool { return false }
+
+// SameSafeExpr checks whether it is safe to reuse one of l and r
+// instead of computing both. SameSafeExpr assumes that l and r are
+// used in the same statement or expression. In order for it to be
+// safe to reuse l or r, they must:
+// * be the same expression
+// * not have side-effects (no function calls, no channel ops);
+//   however, panics are ok
+// * not cause inappropriate aliasing; e.g. two string to []byte
+//   conversions, must result in two distinct slices
+//
+// The handling of OINDEXMAP is subtle. OINDEXMAP can occur both
+// as an lvalue (map assignment) and an rvalue (map access). This is
+// currently OK, since the only place SameSafeExpr gets used on an
+// lvalue expression is for OSLICE and OAPPEND optimizations, and it
+// is correct in those settings.
+func SameSafeExpr(l Node, r Node) bool {
+	if l.Op() != r.Op() || !types.Identical(l.Type(), r.Type()) {
+		return false
+	}
+
+	switch l.Op() {
+	case ONAME:
+		return l == r
+
+	case ODOT, ODOTPTR:
+		l := l.(*SelectorExpr)
+		r := r.(*SelectorExpr)
+		return l.Sel != nil && r.Sel != nil && l.Sel == r.Sel && SameSafeExpr(l.X, r.X)
+
+	case ODEREF:
+		l := l.(*StarExpr)
+		r := r.(*StarExpr)
+		return SameSafeExpr(l.X, r.X)
+
+	case ONOT, OBITNOT, OPLUS, ONEG:
+		l := l.(*UnaryExpr)
+		r := r.(*UnaryExpr)
+		return SameSafeExpr(l.X, r.X)
+
+	case OCONVNOP:
+		l := l.(*ConvExpr)
+		r := r.(*ConvExpr)
+		return SameSafeExpr(l.X, r.X)
+
+	case OCONV:
+		l := l.(*ConvExpr)
+		r := r.(*ConvExpr)
+		// Some conversions can't be reused, such as []byte(str).
+		// Allow only numeric-ish types. This is a bit conservative.
+		return types.IsSimple[l.Type().Kind()] && SameSafeExpr(l.X, r.X)
+
+	case OINDEX, OINDEXMAP:
+		l := l.(*IndexExpr)
+		r := r.(*IndexExpr)
+		return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Index, r.Index)
+
+	case OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
+		l := l.(*BinaryExpr)
+		r := r.(*BinaryExpr)
+		return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Y, r.Y)
+
+	case OLITERAL:
+		return constant.Compare(l.Val(), token.EQL, r.Val())
+
+	case ONIL:
+		return true
+	}
+
+	return false
+}
+
+// ShouldCheckPtr reports whether pointer checking should be enabled for
+// function fn at a given level. See debugHelpFooter for defined
+// levels.
+func ShouldCheckPtr(fn *Func, level int) bool {
+	return base.Debug.Checkptr >= level && fn.Pragma&NoCheckPtr == 0
+}
+
+// IsReflectHeaderDataField reports whether l is an expression p.Data
+// where p has type reflect.SliceHeader or reflect.StringHeader.
+func IsReflectHeaderDataField(l Node) bool {
+	if l.Type() != types.Types[types.TUINTPTR] {
+		return false
+	}
+
+	var tsym *types.Sym
+	switch l.Op() {
+	case ODOT:
+		l := l.(*SelectorExpr)
+		tsym = l.X.Type().Sym()
+	case ODOTPTR:
+		l := l.(*SelectorExpr)
+		tsym = l.X.Type().Elem().Sym()
+	default:
+		return false
+	}
+
+	if tsym == nil || l.Sym().Name != "Data" || tsym.Pkg.Path != "reflect" {
+		return false
+	}
+	return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
+}
+
+func ParamNames(ft *types.Type) []Node {
+	args := make([]Node, ft.NumParams())
+	for i, f := range ft.Params().FieldSlice() {
+		args[i] = AsNode(f.Nname)
+	}
+	return args
+}
+
+// MethodSym returns the method symbol representing a method name
+// associated with a specific receiver type.
+//
+// Method symbols can be used to distinguish the same method appearing
+// in different method sets. For example, T.M and (*T).M have distinct
+// method symbols.
+//
+// The returned symbol will be marked as a function.
+func MethodSym(recv *types.Type, msym *types.Sym) *types.Sym {
+	sym := MethodSymSuffix(recv, msym, "")
+	sym.SetFunc(true)
+	return sym
+}
+
+// MethodSymSuffix is like methodsym, but allows attaching a
+// distinguisher suffix. To avoid collisions, the suffix must not
+// start with a letter, number, or period.
+func MethodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
+	if msym.IsBlank() {
+		base.Fatalf("blank method name")
+	}
+
+	rsym := recv.Sym()
+	if recv.IsPtr() {
+		if rsym != nil {
+			base.Fatalf("declared pointer receiver type: %v", recv)
+		}
+		rsym = recv.Elem().Sym()
+	}
+
+	// Find the package the receiver type appeared in. For
+	// anonymous receiver types (i.e., anonymous structs with
+	// embedded fields), use the "go" pseudo-package instead.
+	rpkg := Pkgs.Go
+	if rsym != nil {
+		rpkg = rsym.Pkg
+	}
+
+	var b bytes.Buffer
+	if recv.IsPtr() {
+		// The parentheses aren't really necessary, but
+		// they're pretty traditional at this point.
+		fmt.Fprintf(&b, "(%-S)", recv)
+	} else {
+		fmt.Fprintf(&b, "%-S", recv)
+	}
+
+	// A particular receiver type may have multiple non-exported
+	// methods with the same name. To disambiguate them, include a
+	// package qualifier for names that came from a different
+	// package than the receiver type.
+	if !types.IsExported(msym.Name) && msym.Pkg != rpkg {
+		b.WriteString(".")
+		b.WriteString(msym.Pkg.Prefix)
+	}
+
+	b.WriteString(".")
+	b.WriteString(msym.Name)
+	b.WriteString(suffix)
+
+	return rpkg.LookupBytes(b.Bytes())
+}
+
+// MethodExprName returns the ONAME representing the method
+// referenced by expression n, which must be a method selector,
+// method expression, or method value.
+func MethodExprName(n Node) *Name {
+	name, _ := MethodExprFunc(n).Nname.(*Name)
+	return name
+}
+
+// MethodExprFunc is like MethodExprName, but returns the types.Field instead.
+func MethodExprFunc(n Node) *types.Field {
+	switch n.Op() {
+	case ODOTMETH, OMETHEXPR, OCALLPART:
+		return n.(*SelectorExpr).Selection
+	}
+	base.Fatalf("unexpected node: %v (%v)", n, n.Op())
+	panic("unreachable")
+}
diff --git a/src/cmd/compile/internal/ir/fmt.go b/src/cmd/compile/internal/ir/fmt.go
new file mode 100644
index 0000000..f2ae0f7
--- /dev/null
+++ b/src/cmd/compile/internal/ir/fmt.go
@@ -0,0 +1,1337 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"bytes"
+	"fmt"
+	"go/constant"
+	"io"
+	"math"
+	"os"
+	"path/filepath"
+	"reflect"
+	"strings"
+
+	"unicode/utf8"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// Op
+
+var OpNames = []string{
+	OADDR:        "&",
+	OADD:         "+",
+	OADDSTR:      "+",
+	OALIGNOF:     "unsafe.Alignof",
+	OANDAND:      "&&",
+	OANDNOT:      "&^",
+	OAND:         "&",
+	OAPPEND:      "append",
+	OAS:          "=",
+	OAS2:         "=",
+	OBREAK:       "break",
+	OCALL:        "function call", // not actual syntax
+	OCAP:         "cap",
+	OCASE:        "case",
+	OCLOSE:       "close",
+	OCOMPLEX:     "complex",
+	OBITNOT:      "^",
+	OCONTINUE:    "continue",
+	OCOPY:        "copy",
+	ODELETE:      "delete",
+	ODEFER:       "defer",
+	ODIV:         "/",
+	OEQ:          "==",
+	OFALL:        "fallthrough",
+	OFOR:         "for",
+	OFORUNTIL:    "foruntil", // not actual syntax; used to avoid off-end pointer live on backedge.892
+	OGE:          ">=",
+	OGOTO:        "goto",
+	OGT:          ">",
+	OIF:          "if",
+	OIMAG:        "imag",
+	OINLMARK:     "inlmark",
+	ODEREF:       "*",
+	OLEN:         "len",
+	OLE:          "<=",
+	OLSH:         "<<",
+	OLT:          "<",
+	OMAKE:        "make",
+	ONEG:         "-",
+	OMOD:         "%",
+	OMUL:         "*",
+	ONEW:         "new",
+	ONE:          "!=",
+	ONOT:         "!",
+	OOFFSETOF:    "unsafe.Offsetof",
+	OOROR:        "||",
+	OOR:          "|",
+	OPANIC:       "panic",
+	OPLUS:        "+",
+	OPRINTN:      "println",
+	OPRINT:       "print",
+	ORANGE:       "range",
+	OREAL:        "real",
+	ORECV:        "<-",
+	ORECOVER:     "recover",
+	ORETURN:      "return",
+	ORSH:         ">>",
+	OSELECT:      "select",
+	OSEND:        "<-",
+	OSIZEOF:      "unsafe.Sizeof",
+	OSUB:         "-",
+	OSWITCH:      "switch",
+	OUNSAFEADD:   "unsafe.Add",
+	OUNSAFESLICE: "unsafe.Slice",
+	OXOR:         "^",
+}
+
+// GoString returns the Go syntax for the Op, or else its name.
+func (o Op) GoString() string {
+	if int(o) < len(OpNames) && OpNames[o] != "" {
+		return OpNames[o]
+	}
+	return o.String()
+}
+
+// Format implements formatting for an Op.
+// The valid formats are:
+//
+//	%v	Go syntax ("+", "<-", "print")
+//	%+v	Debug syntax ("ADD", "RECV", "PRINT")
+//
+func (o Op) Format(s fmt.State, verb rune) {
+	switch verb {
+	default:
+		fmt.Fprintf(s, "%%!%c(Op=%d)", verb, int(o))
+	case 'v':
+		if s.Flag('+') {
+			// %+v is OMUL instead of "*"
+			io.WriteString(s, o.String())
+			return
+		}
+		io.WriteString(s, o.GoString())
+	}
+}
+
+// Node
+
+// FmtNode implements formatting for a Node n.
+// Every Node implementation must define a Format method that calls FmtNode.
+// The valid formats are:
+//
+//	%v	Go syntax
+//	%L	Go syntax followed by " (type T)" if type is known.
+//	%+v	Debug syntax, as in Dump.
+//
+func fmtNode(n Node, s fmt.State, verb rune) {
+	// %+v prints Dump.
+	// Otherwise we print Go syntax.
+	if s.Flag('+') && verb == 'v' {
+		dumpNode(s, n, 1)
+		return
+	}
+
+	if verb != 'v' && verb != 'S' && verb != 'L' {
+		fmt.Fprintf(s, "%%!%c(*Node=%p)", verb, n)
+		return
+	}
+
+	if n == nil {
+		fmt.Fprint(s, "<nil>")
+		return
+	}
+
+	t := n.Type()
+	if verb == 'L' && t != nil {
+		if t.Kind() == types.TNIL {
+			fmt.Fprint(s, "nil")
+		} else if n.Op() == ONAME && n.Name().AutoTemp() {
+			fmt.Fprintf(s, "%v value", t)
+		} else {
+			fmt.Fprintf(s, "%v (type %v)", n, t)
+		}
+		return
+	}
+
+	// TODO inlining produces expressions with ninits. we can't print these yet.
+
+	if OpPrec[n.Op()] < 0 {
+		stmtFmt(n, s)
+		return
+	}
+
+	exprFmt(n, s, 0)
+}
+
+var OpPrec = []int{
+	OALIGNOF:       8,
+	OAPPEND:        8,
+	OBYTES2STR:     8,
+	OARRAYLIT:      8,
+	OSLICELIT:      8,
+	ORUNES2STR:     8,
+	OCALLFUNC:      8,
+	OCALLINTER:     8,
+	OCALLMETH:      8,
+	OCALL:          8,
+	OCAP:           8,
+	OCLOSE:         8,
+	OCOMPLIT:       8,
+	OCONVIFACE:     8,
+	OCONVNOP:       8,
+	OCONV:          8,
+	OCOPY:          8,
+	ODELETE:        8,
+	OGETG:          8,
+	OLEN:           8,
+	OLITERAL:       8,
+	OMAKESLICE:     8,
+	OMAKESLICECOPY: 8,
+	OMAKE:          8,
+	OMAPLIT:        8,
+	ONAME:          8,
+	ONEW:           8,
+	ONIL:           8,
+	ONONAME:        8,
+	OOFFSETOF:      8,
+	OPACK:          8,
+	OPANIC:         8,
+	OPAREN:         8,
+	OPRINTN:        8,
+	OPRINT:         8,
+	ORUNESTR:       8,
+	OSIZEOF:        8,
+	OSLICE2ARRPTR:  8,
+	OSTR2BYTES:     8,
+	OSTR2RUNES:     8,
+	OSTRUCTLIT:     8,
+	OTARRAY:        8,
+	OTSLICE:        8,
+	OTCHAN:         8,
+	OTFUNC:         8,
+	OTINTER:        8,
+	OTMAP:          8,
+	OTSTRUCT:       8,
+	OTYPE:          8,
+	OUNSAFEADD:     8,
+	OUNSAFESLICE:   8,
+	OINDEXMAP:      8,
+	OINDEX:         8,
+	OSLICE:         8,
+	OSLICESTR:      8,
+	OSLICEARR:      8,
+	OSLICE3:        8,
+	OSLICE3ARR:     8,
+	OSLICEHEADER:   8,
+	ODOTINTER:      8,
+	ODOTMETH:       8,
+	ODOTPTR:        8,
+	ODOTTYPE2:      8,
+	ODOTTYPE:       8,
+	ODOT:           8,
+	OXDOT:          8,
+	OCALLPART:      8,
+	OMETHEXPR:      8,
+	OPLUS:          7,
+	ONOT:           7,
+	OBITNOT:        7,
+	ONEG:           7,
+	OADDR:          7,
+	ODEREF:         7,
+	ORECV:          7,
+	OMUL:           6,
+	ODIV:           6,
+	OMOD:           6,
+	OLSH:           6,
+	ORSH:           6,
+	OAND:           6,
+	OANDNOT:        6,
+	OADD:           5,
+	OSUB:           5,
+	OOR:            5,
+	OXOR:           5,
+	OEQ:            4,
+	OLT:            4,
+	OLE:            4,
+	OGE:            4,
+	OGT:            4,
+	ONE:            4,
+	OSEND:          3,
+	OANDAND:        2,
+	OOROR:          1,
+
+	// Statements handled by stmtfmt
+	OAS:         -1,
+	OAS2:        -1,
+	OAS2DOTTYPE: -1,
+	OAS2FUNC:    -1,
+	OAS2MAPR:    -1,
+	OAS2RECV:    -1,
+	OASOP:       -1,
+	OBLOCK:      -1,
+	OBREAK:      -1,
+	OCASE:       -1,
+	OCONTINUE:   -1,
+	ODCL:        -1,
+	ODEFER:      -1,
+	OFALL:       -1,
+	OFOR:        -1,
+	OFORUNTIL:   -1,
+	OGOTO:       -1,
+	OIF:         -1,
+	OLABEL:      -1,
+	OGO:         -1,
+	ORANGE:      -1,
+	ORETURN:     -1,
+	OSELECT:     -1,
+	OSWITCH:     -1,
+
+	OEND: 0,
+}
+
+// StmtWithInit reports whether op is a statement with an explicit init list.
+func StmtWithInit(op Op) bool {
+	switch op {
+	case OIF, OFOR, OFORUNTIL, OSWITCH:
+		return true
+	}
+	return false
+}
+
+func stmtFmt(n Node, s fmt.State) {
+	// NOTE(rsc): This code used to support the text-based
+	// which was more aggressive about printing full Go syntax
+	// (for example, an actual loop instead of "for loop").
+	// The code is preserved for now in case we want to expand
+	// any of those shortenings later. Or maybe we will delete
+	// the code. But for now, keep it.
+	const exportFormat = false
+
+	// some statements allow for an init, but at most one,
+	// but we may have an arbitrary number added, eg by typecheck
+	// and inlining. If it doesn't fit the syntax, emit an enclosing
+	// block starting with the init statements.
+
+	// if we can just say "for" n->ninit; ... then do so
+	simpleinit := len(n.Init()) == 1 && len(n.Init()[0].Init()) == 0 && StmtWithInit(n.Op())
+
+	// otherwise, print the inits as separate statements
+	complexinit := len(n.Init()) != 0 && !simpleinit && exportFormat
+
+	// but if it was for if/for/switch, put in an extra surrounding block to limit the scope
+	extrablock := complexinit && StmtWithInit(n.Op())
+
+	if extrablock {
+		fmt.Fprint(s, "{")
+	}
+
+	if complexinit {
+		fmt.Fprintf(s, " %v; ", n.Init())
+	}
+
+	switch n.Op() {
+	case ODCL:
+		n := n.(*Decl)
+		fmt.Fprintf(s, "var %v %v", n.X.Sym(), n.X.Type())
+
+	// Don't export "v = <N>" initializing statements, hope they're always
+	// preceded by the DCL which will be re-parsed and typechecked to reproduce
+	// the "v = <N>" again.
+	case OAS:
+		n := n.(*AssignStmt)
+		if n.Def && !complexinit {
+			fmt.Fprintf(s, "%v := %v", n.X, n.Y)
+		} else {
+			fmt.Fprintf(s, "%v = %v", n.X, n.Y)
+		}
+
+	case OASOP:
+		n := n.(*AssignOpStmt)
+		if n.IncDec {
+			if n.AsOp == OADD {
+				fmt.Fprintf(s, "%v++", n.X)
+			} else {
+				fmt.Fprintf(s, "%v--", n.X)
+			}
+			break
+		}
+
+		fmt.Fprintf(s, "%v %v= %v", n.X, n.AsOp, n.Y)
+
+	case OAS2, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
+		n := n.(*AssignListStmt)
+		if n.Def && !complexinit {
+			fmt.Fprintf(s, "%.v := %.v", n.Lhs, n.Rhs)
+		} else {
+			fmt.Fprintf(s, "%.v = %.v", n.Lhs, n.Rhs)
+		}
+
+	case OBLOCK:
+		n := n.(*BlockStmt)
+		if len(n.List) != 0 {
+			fmt.Fprintf(s, "%v", n.List)
+		}
+
+	case ORETURN:
+		n := n.(*ReturnStmt)
+		fmt.Fprintf(s, "return %.v", n.Results)
+
+	case OTAILCALL:
+		n := n.(*TailCallStmt)
+		fmt.Fprintf(s, "tailcall %v", n.Target)
+
+	case OINLMARK:
+		n := n.(*InlineMarkStmt)
+		fmt.Fprintf(s, "inlmark %d", n.Index)
+
+	case OGO:
+		n := n.(*GoDeferStmt)
+		fmt.Fprintf(s, "go %v", n.Call)
+
+	case ODEFER:
+		n := n.(*GoDeferStmt)
+		fmt.Fprintf(s, "defer %v", n.Call)
+
+	case OIF:
+		n := n.(*IfStmt)
+		if simpleinit {
+			fmt.Fprintf(s, "if %v; %v { %v }", n.Init()[0], n.Cond, n.Body)
+		} else {
+			fmt.Fprintf(s, "if %v { %v }", n.Cond, n.Body)
+		}
+		if len(n.Else) != 0 {
+			fmt.Fprintf(s, " else { %v }", n.Else)
+		}
+
+	case OFOR, OFORUNTIL:
+		n := n.(*ForStmt)
+		opname := "for"
+		if n.Op() == OFORUNTIL {
+			opname = "foruntil"
+		}
+		if !exportFormat { // TODO maybe only if FmtShort, same below
+			fmt.Fprintf(s, "%s loop", opname)
+			break
+		}
+
+		fmt.Fprint(s, opname)
+		if simpleinit {
+			fmt.Fprintf(s, " %v;", n.Init()[0])
+		} else if n.Post != nil {
+			fmt.Fprint(s, " ;")
+		}
+
+		if n.Cond != nil {
+			fmt.Fprintf(s, " %v", n.Cond)
+		}
+
+		if n.Post != nil {
+			fmt.Fprintf(s, "; %v", n.Post)
+		} else if simpleinit {
+			fmt.Fprint(s, ";")
+		}
+
+		if n.Op() == OFORUNTIL && len(n.Late) != 0 {
+			fmt.Fprintf(s, "; %v", n.Late)
+		}
+
+		fmt.Fprintf(s, " { %v }", n.Body)
+
+	case ORANGE:
+		n := n.(*RangeStmt)
+		if !exportFormat {
+			fmt.Fprint(s, "for loop")
+			break
+		}
+
+		fmt.Fprint(s, "for")
+		if n.Key != nil {
+			fmt.Fprintf(s, " %v", n.Key)
+			if n.Value != nil {
+				fmt.Fprintf(s, ", %v", n.Value)
+			}
+			fmt.Fprint(s, " =")
+		}
+		fmt.Fprintf(s, " range %v { %v }", n.X, n.Body)
+
+	case OSELECT:
+		n := n.(*SelectStmt)
+		if !exportFormat {
+			fmt.Fprintf(s, "%v statement", n.Op())
+			break
+		}
+		fmt.Fprintf(s, "select { %v }", n.Cases)
+
+	case OSWITCH:
+		n := n.(*SwitchStmt)
+		if !exportFormat {
+			fmt.Fprintf(s, "%v statement", n.Op())
+			break
+		}
+		fmt.Fprintf(s, "switch")
+		if simpleinit {
+			fmt.Fprintf(s, " %v;", n.Init()[0])
+		}
+		if n.Tag != nil {
+			fmt.Fprintf(s, " %v ", n.Tag)
+		}
+		fmt.Fprintf(s, " { %v }", n.Cases)
+
+	case OCASE:
+		n := n.(*CaseClause)
+		if len(n.List) != 0 {
+			fmt.Fprintf(s, "case %.v", n.List)
+		} else {
+			fmt.Fprint(s, "default")
+		}
+		fmt.Fprintf(s, ": %v", n.Body)
+
+	case OBREAK, OCONTINUE, OGOTO, OFALL:
+		n := n.(*BranchStmt)
+		if n.Label != nil {
+			fmt.Fprintf(s, "%v %v", n.Op(), n.Label)
+		} else {
+			fmt.Fprintf(s, "%v", n.Op())
+		}
+
+	case OLABEL:
+		n := n.(*LabelStmt)
+		fmt.Fprintf(s, "%v: ", n.Label)
+	}
+
+	if extrablock {
+		fmt.Fprint(s, "}")
+	}
+}
+
+func exprFmt(n Node, s fmt.State, prec int) {
+	// NOTE(rsc): This code used to support the text-based
+	// which was more aggressive about printing full Go syntax
+	// (for example, an actual loop instead of "for loop").
+	// The code is preserved for now in case we want to expand
+	// any of those shortenings later. Or maybe we will delete
+	// the code. But for now, keep it.
+	const exportFormat = false
+
+	for {
+		if n == nil {
+			fmt.Fprint(s, "<nil>")
+			return
+		}
+
+		// We always want the original, if any.
+		if o := Orig(n); o != n {
+			n = o
+			continue
+		}
+
+		// Skip implicit operations introduced during typechecking.
+		switch nn := n; nn.Op() {
+		case OADDR:
+			nn := nn.(*AddrExpr)
+			if nn.Implicit() {
+				n = nn.X
+				continue
+			}
+		case ODEREF:
+			nn := nn.(*StarExpr)
+			if nn.Implicit() {
+				n = nn.X
+				continue
+			}
+		case OCONV, OCONVNOP, OCONVIFACE:
+			nn := nn.(*ConvExpr)
+			if nn.Implicit() {
+				n = nn.X
+				continue
+			}
+		}
+
+		break
+	}
+
+	nprec := OpPrec[n.Op()]
+	if n.Op() == OTYPE && n.Type().IsPtr() {
+		nprec = OpPrec[ODEREF]
+	}
+
+	if prec > nprec {
+		fmt.Fprintf(s, "(%v)", n)
+		return
+	}
+
+	switch n.Op() {
+	case OPAREN:
+		n := n.(*ParenExpr)
+		fmt.Fprintf(s, "(%v)", n.X)
+
+	case ONIL:
+		fmt.Fprint(s, "nil")
+
+	case OLITERAL: // this is a bit of a mess
+		if !exportFormat && n.Sym() != nil {
+			fmt.Fprint(s, n.Sym())
+			return
+		}
+
+		needUnparen := false
+		if n.Type() != nil && !n.Type().IsUntyped() {
+			// Need parens when type begins with what might
+			// be misinterpreted as a unary operator: * or <-.
+			if n.Type().IsPtr() || (n.Type().IsChan() && n.Type().ChanDir() == types.Crecv) {
+				fmt.Fprintf(s, "(%v)(", n.Type())
+			} else {
+				fmt.Fprintf(s, "%v(", n.Type())
+			}
+			needUnparen = true
+		}
+
+		if n.Type() == types.UntypedRune {
+			switch x, ok := constant.Uint64Val(n.Val()); {
+			case !ok:
+				fallthrough
+			default:
+				fmt.Fprintf(s, "('\\x00' + %v)", n.Val())
+
+			case x < utf8.RuneSelf:
+				fmt.Fprintf(s, "%q", x)
+
+			case x < 1<<16:
+				fmt.Fprintf(s, "'\\u%04x'", x)
+
+			case x <= utf8.MaxRune:
+				fmt.Fprintf(s, "'\\U%08x'", x)
+			}
+		} else {
+			fmt.Fprint(s, types.FmtConst(n.Val(), s.Flag('#')))
+		}
+
+		if needUnparen {
+			fmt.Fprintf(s, ")")
+		}
+
+	case ODCLFUNC:
+		n := n.(*Func)
+		if sym := n.Sym(); sym != nil {
+			fmt.Fprint(s, sym)
+			return
+		}
+		fmt.Fprintf(s, "<unnamed Func>")
+
+	case ONAME:
+		n := n.(*Name)
+		// Special case: name used as local variable in export.
+		// _ becomes ~b%d internally; print as _ for export
+		if !exportFormat && n.Sym() != nil && n.Sym().Name[0] == '~' && n.Sym().Name[1] == 'b' {
+			fmt.Fprint(s, "_")
+			return
+		}
+		fallthrough
+	case OPACK, ONONAME:
+		fmt.Fprint(s, n.Sym())
+
+	case OLINKSYMOFFSET:
+		n := n.(*LinksymOffsetExpr)
+		fmt.Fprintf(s, "(%v)(%s@%d)", n.Type(), n.Linksym.Name, n.Offset_)
+
+	case OTYPE:
+		if n.Type() == nil && n.Sym() != nil {
+			fmt.Fprint(s, n.Sym())
+			return
+		}
+		fmt.Fprintf(s, "%v", n.Type())
+
+	case OTSLICE:
+		n := n.(*SliceType)
+		if n.DDD {
+			fmt.Fprintf(s, "...%v", n.Elem)
+		} else {
+			fmt.Fprintf(s, "[]%v", n.Elem) // happens before typecheck
+		}
+
+	case OTARRAY:
+		n := n.(*ArrayType)
+		if n.Len == nil {
+			fmt.Fprintf(s, "[...]%v", n.Elem)
+		} else {
+			fmt.Fprintf(s, "[%v]%v", n.Len, n.Elem)
+		}
+
+	case OTMAP:
+		n := n.(*MapType)
+		fmt.Fprintf(s, "map[%v]%v", n.Key, n.Elem)
+
+	case OTCHAN:
+		n := n.(*ChanType)
+		switch n.Dir {
+		case types.Crecv:
+			fmt.Fprintf(s, "<-chan %v", n.Elem)
+
+		case types.Csend:
+			fmt.Fprintf(s, "chan<- %v", n.Elem)
+
+		default:
+			if n.Elem != nil && n.Elem.Op() == OTCHAN && n.Elem.(*ChanType).Dir == types.Crecv {
+				fmt.Fprintf(s, "chan (%v)", n.Elem)
+			} else {
+				fmt.Fprintf(s, "chan %v", n.Elem)
+			}
+		}
+
+	case OTSTRUCT:
+		fmt.Fprint(s, "<struct>")
+
+	case OTINTER:
+		fmt.Fprint(s, "<inter>")
+
+	case OTFUNC:
+		fmt.Fprint(s, "<func>")
+
+	case OCLOSURE:
+		n := n.(*ClosureExpr)
+		if !exportFormat {
+			fmt.Fprint(s, "func literal")
+			return
+		}
+		fmt.Fprintf(s, "%v { %v }", n.Type(), n.Func.Body)
+
+	case OCOMPLIT:
+		n := n.(*CompLitExpr)
+		if !exportFormat {
+			if n.Implicit() {
+				fmt.Fprintf(s, "... argument")
+				return
+			}
+			if n.Ntype != nil {
+				fmt.Fprintf(s, "%v{%s}", n.Ntype, ellipsisIf(len(n.List) != 0))
+				return
+			}
+
+			fmt.Fprint(s, "composite literal")
+			return
+		}
+		fmt.Fprintf(s, "(%v{ %.v })", n.Ntype, n.List)
+
+	case OPTRLIT:
+		n := n.(*AddrExpr)
+		fmt.Fprintf(s, "&%v", n.X)
+
+	case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
+		n := n.(*CompLitExpr)
+		if !exportFormat {
+			fmt.Fprintf(s, "%v{%s}", n.Type(), ellipsisIf(len(n.List) != 0))
+			return
+		}
+		fmt.Fprintf(s, "(%v{ %.v })", n.Type(), n.List)
+
+	case OKEY:
+		n := n.(*KeyExpr)
+		if n.Key != nil && n.Value != nil {
+			fmt.Fprintf(s, "%v:%v", n.Key, n.Value)
+			return
+		}
+
+		if n.Key == nil && n.Value != nil {
+			fmt.Fprintf(s, ":%v", n.Value)
+			return
+		}
+		if n.Key != nil && n.Value == nil {
+			fmt.Fprintf(s, "%v:", n.Key)
+			return
+		}
+		fmt.Fprint(s, ":")
+
+	case OSTRUCTKEY:
+		n := n.(*StructKeyExpr)
+		fmt.Fprintf(s, "%v:%v", n.Field, n.Value)
+
+	case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH, OCALLPART, OMETHEXPR:
+		n := n.(*SelectorExpr)
+		exprFmt(n.X, s, nprec)
+		if n.Sel == nil {
+			fmt.Fprint(s, ".<nil>")
+			return
+		}
+		fmt.Fprintf(s, ".%s", n.Sel.Name)
+
+	case ODOTTYPE, ODOTTYPE2:
+		n := n.(*TypeAssertExpr)
+		exprFmt(n.X, s, nprec)
+		if n.Ntype != nil {
+			fmt.Fprintf(s, ".(%v)", n.Ntype)
+			return
+		}
+		fmt.Fprintf(s, ".(%v)", n.Type())
+
+	case OINDEX, OINDEXMAP:
+		n := n.(*IndexExpr)
+		exprFmt(n.X, s, nprec)
+		fmt.Fprintf(s, "[%v]", n.Index)
+
+	case OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
+		n := n.(*SliceExpr)
+		exprFmt(n.X, s, nprec)
+		fmt.Fprint(s, "[")
+		if n.Low != nil {
+			fmt.Fprint(s, n.Low)
+		}
+		fmt.Fprint(s, ":")
+		if n.High != nil {
+			fmt.Fprint(s, n.High)
+		}
+		if n.Op().IsSlice3() {
+			fmt.Fprint(s, ":")
+			if n.Max != nil {
+				fmt.Fprint(s, n.Max)
+			}
+		}
+		fmt.Fprint(s, "]")
+
+	case OSLICEHEADER:
+		n := n.(*SliceHeaderExpr)
+		fmt.Fprintf(s, "sliceheader{%v,%v,%v}", n.Ptr, n.Len, n.Cap)
+
+	case OCOMPLEX, OCOPY, OUNSAFEADD, OUNSAFESLICE:
+		n := n.(*BinaryExpr)
+		fmt.Fprintf(s, "%v(%v, %v)", n.Op(), n.X, n.Y)
+
+	case OCONV,
+		OCONVIFACE,
+		OCONVNOP,
+		OBYTES2STR,
+		ORUNES2STR,
+		OSTR2BYTES,
+		OSTR2RUNES,
+		ORUNESTR,
+		OSLICE2ARRPTR:
+		n := n.(*ConvExpr)
+		if n.Type() == nil || n.Type().Sym() == nil {
+			fmt.Fprintf(s, "(%v)", n.Type())
+		} else {
+			fmt.Fprintf(s, "%v", n.Type())
+		}
+		fmt.Fprintf(s, "(%v)", n.X)
+
+	case OREAL,
+		OIMAG,
+		OCAP,
+		OCLOSE,
+		OLEN,
+		ONEW,
+		OPANIC,
+		OALIGNOF,
+		OOFFSETOF,
+		OSIZEOF:
+		n := n.(*UnaryExpr)
+		fmt.Fprintf(s, "%v(%v)", n.Op(), n.X)
+
+	case OAPPEND,
+		ODELETE,
+		OMAKE,
+		ORECOVER,
+		OPRINT,
+		OPRINTN:
+		n := n.(*CallExpr)
+		if n.IsDDD {
+			fmt.Fprintf(s, "%v(%.v...)", n.Op(), n.Args)
+			return
+		}
+		fmt.Fprintf(s, "%v(%.v)", n.Op(), n.Args)
+
+	case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG:
+		n := n.(*CallExpr)
+		exprFmt(n.X, s, nprec)
+		if n.IsDDD {
+			fmt.Fprintf(s, "(%.v...)", n.Args)
+			return
+		}
+		fmt.Fprintf(s, "(%.v)", n.Args)
+
+	case OMAKEMAP, OMAKECHAN, OMAKESLICE:
+		n := n.(*MakeExpr)
+		if n.Cap != nil {
+			fmt.Fprintf(s, "make(%v, %v, %v)", n.Type(), n.Len, n.Cap)
+			return
+		}
+		if n.Len != nil && (n.Op() == OMAKESLICE || !n.Len.Type().IsUntyped()) {
+			fmt.Fprintf(s, "make(%v, %v)", n.Type(), n.Len)
+			return
+		}
+		fmt.Fprintf(s, "make(%v)", n.Type())
+
+	case OMAKESLICECOPY:
+		n := n.(*MakeExpr)
+		fmt.Fprintf(s, "makeslicecopy(%v, %v, %v)", n.Type(), n.Len, n.Cap)
+
+	case OPLUS, ONEG, OBITNOT, ONOT, ORECV:
+		// Unary
+		n := n.(*UnaryExpr)
+		fmt.Fprintf(s, "%v", n.Op())
+		if n.X != nil && n.X.Op() == n.Op() {
+			fmt.Fprint(s, " ")
+		}
+		exprFmt(n.X, s, nprec+1)
+
+	case OADDR:
+		n := n.(*AddrExpr)
+		fmt.Fprintf(s, "%v", n.Op())
+		if n.X != nil && n.X.Op() == n.Op() {
+			fmt.Fprint(s, " ")
+		}
+		exprFmt(n.X, s, nprec+1)
+
+	case ODEREF:
+		n := n.(*StarExpr)
+		fmt.Fprintf(s, "%v", n.Op())
+		exprFmt(n.X, s, nprec+1)
+
+		// Binary
+	case OADD,
+		OAND,
+		OANDNOT,
+		ODIV,
+		OEQ,
+		OGE,
+		OGT,
+		OLE,
+		OLT,
+		OLSH,
+		OMOD,
+		OMUL,
+		ONE,
+		OOR,
+		ORSH,
+		OSUB,
+		OXOR:
+		n := n.(*BinaryExpr)
+		exprFmt(n.X, s, nprec)
+		fmt.Fprintf(s, " %v ", n.Op())
+		exprFmt(n.Y, s, nprec+1)
+
+	case OANDAND,
+		OOROR:
+		n := n.(*LogicalExpr)
+		exprFmt(n.X, s, nprec)
+		fmt.Fprintf(s, " %v ", n.Op())
+		exprFmt(n.Y, s, nprec+1)
+
+	case OSEND:
+		n := n.(*SendStmt)
+		exprFmt(n.Chan, s, nprec)
+		fmt.Fprintf(s, " <- ")
+		exprFmt(n.Value, s, nprec+1)
+
+	case OADDSTR:
+		n := n.(*AddStringExpr)
+		for i, n1 := range n.List {
+			if i != 0 {
+				fmt.Fprint(s, " + ")
+			}
+			exprFmt(n1, s, nprec)
+		}
+	default:
+		fmt.Fprintf(s, "<node %v>", n.Op())
+	}
+}
+
+func ellipsisIf(b bool) string {
+	if b {
+		return "..."
+	}
+	return ""
+}
+
+// Nodes
+
+// Format implements formatting for a Nodes.
+// The valid formats are:
+//
+//	%v	Go syntax, semicolon-separated
+//	%.v	Go syntax, comma-separated
+//	%+v	Debug syntax, as in DumpList.
+//
+func (l Nodes) Format(s fmt.State, verb rune) {
+	if s.Flag('+') && verb == 'v' {
+		// %+v is DumpList output
+		dumpNodes(s, l, 1)
+		return
+	}
+
+	if verb != 'v' {
+		fmt.Fprintf(s, "%%!%c(Nodes)", verb)
+		return
+	}
+
+	sep := "; "
+	if _, ok := s.Precision(); ok { // %.v is expr list
+		sep = ", "
+	}
+
+	for i, n := range l {
+		fmt.Fprint(s, n)
+		if i+1 < len(l) {
+			fmt.Fprint(s, sep)
+		}
+	}
+}
+
+// Dump
+
+// Dump prints the message s followed by a debug dump of n.
+func Dump(s string, n Node) {
+	fmt.Printf("%s [%p]%+v\n", s, n, n)
+}
+
+// DumpList prints the message s followed by a debug dump of each node in the list.
+func DumpList(s string, list Nodes) {
+	var buf bytes.Buffer
+	FDumpList(&buf, s, list)
+	os.Stdout.Write(buf.Bytes())
+}
+
+// FDumpList prints to w the message s followed by a debug dump of each node in the list.
+func FDumpList(w io.Writer, s string, list Nodes) {
+	io.WriteString(w, s)
+	dumpNodes(w, list, 1)
+	io.WriteString(w, "\n")
+}
+
+// indent prints indentation to w.
+func indent(w io.Writer, depth int) {
+	fmt.Fprint(w, "\n")
+	for i := 0; i < depth; i++ {
+		fmt.Fprint(w, ".   ")
+	}
+}
+
+// EscFmt is set by the escape analysis code to add escape analysis details to the node print.
+var EscFmt func(n Node) string
+
+// dumpNodeHeader prints the debug-format node header line to w.
+func dumpNodeHeader(w io.Writer, n Node) {
+	// Useful to see which nodes in an AST printout are actually identical
+	if base.Debug.DumpPtrs != 0 {
+		fmt.Fprintf(w, " p(%p)", n)
+	}
+
+	if base.Debug.DumpPtrs != 0 && n.Name() != nil && n.Name().Defn != nil {
+		// Useful to see where Defn is set and what node it points to
+		fmt.Fprintf(w, " defn(%p)", n.Name().Defn)
+	}
+
+	if base.Debug.DumpPtrs != 0 && n.Name() != nil && n.Name().Curfn != nil {
+		// Useful to see where Defn is set and what node it points to
+		fmt.Fprintf(w, " curfn(%p)", n.Name().Curfn)
+	}
+	if base.Debug.DumpPtrs != 0 && n.Name() != nil && n.Name().Outer != nil {
+		// Useful to see where Defn is set and what node it points to
+		fmt.Fprintf(w, " outer(%p)", n.Name().Outer)
+	}
+
+	if EscFmt != nil {
+		if esc := EscFmt(n); esc != "" {
+			fmt.Fprintf(w, " %s", esc)
+		}
+	}
+
+	if n.Typecheck() != 0 {
+		fmt.Fprintf(w, " tc(%d)", n.Typecheck())
+	}
+
+	// Print Node-specific fields of basic type in header line.
+	v := reflect.ValueOf(n).Elem()
+	t := v.Type()
+	nf := t.NumField()
+	for i := 0; i < nf; i++ {
+		tf := t.Field(i)
+		if tf.PkgPath != "" {
+			// skip unexported field - Interface will fail
+			continue
+		}
+		k := tf.Type.Kind()
+		if reflect.Bool <= k && k <= reflect.Complex128 {
+			name := strings.TrimSuffix(tf.Name, "_")
+			vf := v.Field(i)
+			vfi := vf.Interface()
+			if name == "Offset" && vfi == types.BADWIDTH || name != "Offset" && isZero(vf) {
+				continue
+			}
+			if vfi == true {
+				fmt.Fprintf(w, " %s", name)
+			} else {
+				fmt.Fprintf(w, " %s:%+v", name, vf.Interface())
+			}
+		}
+	}
+
+	// Print Node-specific booleans by looking for methods.
+	// Different v, t from above - want *Struct not Struct, for methods.
+	v = reflect.ValueOf(n)
+	t = v.Type()
+	nm := t.NumMethod()
+	for i := 0; i < nm; i++ {
+		tm := t.Method(i)
+		if tm.PkgPath != "" {
+			// skip unexported method - call will fail
+			continue
+		}
+		m := v.Method(i)
+		mt := m.Type()
+		if mt.NumIn() == 0 && mt.NumOut() == 1 && mt.Out(0).Kind() == reflect.Bool {
+			// TODO(rsc): Remove the func/defer/recover wrapping,
+			// which is guarding against panics in miniExpr,
+			// once we get down to the simpler state in which
+			// nodes have no getter methods that aren't allowed to be called.
+			func() {
+				defer func() { recover() }()
+				if m.Call(nil)[0].Bool() {
+					name := strings.TrimSuffix(tm.Name, "_")
+					fmt.Fprintf(w, " %s", name)
+				}
+			}()
+		}
+	}
+
+	if n.Op() == OCLOSURE {
+		n := n.(*ClosureExpr)
+		if fn := n.Func; fn != nil && fn.Nname.Sym() != nil {
+			fmt.Fprintf(w, " fnName(%+v)", fn.Nname.Sym())
+		}
+	}
+
+	if n.Type() != nil {
+		if n.Op() == OTYPE {
+			fmt.Fprintf(w, " type")
+		}
+		fmt.Fprintf(w, " %+v", n.Type())
+	}
+
+	if n.Pos().IsKnown() {
+		pfx := ""
+		switch n.Pos().IsStmt() {
+		case src.PosNotStmt:
+			pfx = "_" // "-" would be confusing
+		case src.PosIsStmt:
+			pfx = "+"
+		}
+		pos := base.Ctxt.PosTable.Pos(n.Pos())
+		file := filepath.Base(pos.Filename())
+		fmt.Fprintf(w, " # %s%s:%d", pfx, file, pos.Line())
+	}
+}
+
+func dumpNode(w io.Writer, n Node, depth int) {
+	indent(w, depth)
+	if depth > 40 {
+		fmt.Fprint(w, "...")
+		return
+	}
+
+	if n == nil {
+		fmt.Fprint(w, "NilIrNode")
+		return
+	}
+
+	if len(n.Init()) != 0 {
+		fmt.Fprintf(w, "%+v-init", n.Op())
+		dumpNodes(w, n.Init(), depth+1)
+		indent(w, depth)
+	}
+
+	switch n.Op() {
+	default:
+		fmt.Fprintf(w, "%+v", n.Op())
+		dumpNodeHeader(w, n)
+
+	case OLITERAL:
+		fmt.Fprintf(w, "%+v-%v", n.Op(), n.Val())
+		dumpNodeHeader(w, n)
+		return
+
+	case ONAME, ONONAME:
+		if n.Sym() != nil {
+			fmt.Fprintf(w, "%+v-%+v", n.Op(), n.Sym())
+		} else {
+			fmt.Fprintf(w, "%+v", n.Op())
+		}
+		dumpNodeHeader(w, n)
+		if n.Type() == nil && n.Name() != nil && n.Name().Ntype != nil {
+			indent(w, depth)
+			fmt.Fprintf(w, "%+v-ntype", n.Op())
+			dumpNode(w, n.Name().Ntype, depth+1)
+		}
+		return
+
+	case OASOP:
+		n := n.(*AssignOpStmt)
+		fmt.Fprintf(w, "%+v-%+v", n.Op(), n.AsOp)
+		dumpNodeHeader(w, n)
+
+	case OTYPE:
+		fmt.Fprintf(w, "%+v %+v", n.Op(), n.Sym())
+		dumpNodeHeader(w, n)
+		if n.Type() == nil && n.Name() != nil && n.Name().Ntype != nil {
+			indent(w, depth)
+			fmt.Fprintf(w, "%+v-ntype", n.Op())
+			dumpNode(w, n.Name().Ntype, depth+1)
+		}
+		return
+
+	case OCLOSURE:
+		fmt.Fprintf(w, "%+v", n.Op())
+		dumpNodeHeader(w, n)
+
+	case ODCLFUNC:
+		// Func has many fields we don't want to print.
+		// Bypass reflection and just print what we want.
+		n := n.(*Func)
+		fmt.Fprintf(w, "%+v", n.Op())
+		dumpNodeHeader(w, n)
+		fn := n
+		if len(fn.Dcl) > 0 {
+			indent(w, depth)
+			fmt.Fprintf(w, "%+v-Dcl", n.Op())
+			for _, dcl := range n.Dcl {
+				dumpNode(w, dcl, depth+1)
+			}
+		}
+		if len(fn.ClosureVars) > 0 {
+			indent(w, depth)
+			fmt.Fprintf(w, "%+v-ClosureVars", n.Op())
+			for _, cv := range fn.ClosureVars {
+				dumpNode(w, cv, depth+1)
+			}
+		}
+		if len(fn.Enter) > 0 {
+			indent(w, depth)
+			fmt.Fprintf(w, "%+v-Enter", n.Op())
+			dumpNodes(w, fn.Enter, depth+1)
+		}
+		if len(fn.Body) > 0 {
+			indent(w, depth)
+			fmt.Fprintf(w, "%+v-body", n.Op())
+			dumpNodes(w, fn.Body, depth+1)
+		}
+		return
+	}
+
+	if n.Sym() != nil {
+		fmt.Fprintf(w, " %+v", n.Sym())
+	}
+	if n.Type() != nil {
+		fmt.Fprintf(w, " %+v", n.Type())
+	}
+
+	v := reflect.ValueOf(n).Elem()
+	t := reflect.TypeOf(n).Elem()
+	nf := t.NumField()
+	for i := 0; i < nf; i++ {
+		tf := t.Field(i)
+		vf := v.Field(i)
+		if tf.PkgPath != "" {
+			// skip unexported field - Interface will fail
+			continue
+		}
+		switch tf.Type.Kind() {
+		case reflect.Interface, reflect.Ptr, reflect.Slice:
+			if vf.IsNil() {
+				continue
+			}
+		}
+		name := strings.TrimSuffix(tf.Name, "_")
+		// Do not bother with field name header lines for the
+		// most common positional arguments: unary, binary expr,
+		// index expr, send stmt, go and defer call expression.
+		switch name {
+		case "X", "Y", "Index", "Chan", "Value", "Call":
+			name = ""
+		}
+		switch val := vf.Interface().(type) {
+		case Node:
+			if name != "" {
+				indent(w, depth)
+				fmt.Fprintf(w, "%+v-%s", n.Op(), name)
+			}
+			dumpNode(w, val, depth+1)
+		case Nodes:
+			if len(val) == 0 {
+				continue
+			}
+			if name != "" {
+				indent(w, depth)
+				fmt.Fprintf(w, "%+v-%s", n.Op(), name)
+			}
+			dumpNodes(w, val, depth+1)
+		default:
+			if vf.Kind() == reflect.Slice && vf.Type().Elem().Implements(nodeType) {
+				if vf.Len() == 0 {
+					continue
+				}
+				if name != "" {
+					indent(w, depth)
+					fmt.Fprintf(w, "%+v-%s", n.Op(), name)
+				}
+				for i, n := 0, vf.Len(); i < n; i++ {
+					dumpNode(w, vf.Index(i).Interface().(Node), depth+1)
+				}
+			}
+		}
+	}
+}
+
+var nodeType = reflect.TypeOf((*Node)(nil)).Elem()
+
+func dumpNodes(w io.Writer, list Nodes, depth int) {
+	if len(list) == 0 {
+		fmt.Fprintf(w, " <nil>")
+		return
+	}
+
+	for _, n := range list {
+		dumpNode(w, n, depth)
+	}
+}
+
+// reflect.IsZero is not available in Go 1.4 (added in Go 1.13), so we use this copy instead.
+func isZero(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Bool:
+		return !v.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return math.Float64bits(v.Float()) == 0
+	case reflect.Complex64, reflect.Complex128:
+		c := v.Complex()
+		return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
+	case reflect.Array:
+		for i := 0; i < v.Len(); i++ {
+			if !isZero(v.Index(i)) {
+				return false
+			}
+		}
+		return true
+	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
+		return v.IsNil()
+	case reflect.String:
+		return v.Len() == 0
+	case reflect.Struct:
+		for i := 0; i < v.NumField(); i++ {
+			if !isZero(v.Field(i)) {
+				return false
+			}
+		}
+		return true
+	default:
+		return false
+	}
+}
diff --git a/src/cmd/compile/internal/ir/func.go b/src/cmd/compile/internal/ir/func.go
new file mode 100644
index 0000000..20fe965
--- /dev/null
+++ b/src/cmd/compile/internal/ir/func.go
@@ -0,0 +1,308 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/src"
+)
+
+// A Func corresponds to a single function in a Go program
+// (and vice versa: each function is denoted by exactly one *Func).
+//
+// There are multiple nodes that represent a Func in the IR.
+//
+// The ONAME node (Func.Nname) is used for plain references to it.
+// The ODCLFUNC node (the Func itself) is used for its declaration code.
+// The OCLOSURE node (Func.OClosure) is used for a reference to a
+// function literal.
+//
+// An imported function will have an ONAME node which points to a Func
+// with an empty body.
+// A declared function or method has an ODCLFUNC (the Func itself) and an ONAME.
+// A function literal is represented directly by an OCLOSURE, but it also
+// has an ODCLFUNC (and a matching ONAME) representing the compiled
+// underlying form of the closure, which accesses the captured variables
+// using a special data structure passed in a register.
+//
+// A method declaration is represented like functions, except f.Sym
+// will be the qualified method name (e.g., "T.m") and
+// f.Func.Shortname is the bare method name (e.g., "m").
+//
+// A method expression (T.M) is represented as an OMETHEXPR node,
+// in which n.Left and n.Right point to the type and method, respectively.
+// Each distinct mention of a method expression in the source code
+// constructs a fresh node.
+//
+// A method value (t.M) is represented by ODOTMETH/ODOTINTER
+// when it is called directly and by OCALLPART otherwise.
+// These are like method expressions, except that for ODOTMETH/ODOTINTER,
+// the method name is stored in Sym instead of Right.
+// Each OCALLPART ends up being implemented as a new
+// function, a bit like a closure, with its own ODCLFUNC.
+// The OCALLPART uses n.Func to record the linkage to
+// the generated ODCLFUNC, but there is no
+// pointer from the Func back to the OCALLPART.
+type Func struct {
+	miniNode
+	Body Nodes
+	Iota int64
+
+	Nname    *Name        // ONAME node
+	OClosure *ClosureExpr // OCLOSURE node
+
+	Shortname *types.Sym
+
+	// Extra entry code for the function. For example, allocate and initialize
+	// memory for escaping parameters.
+	Enter Nodes
+	Exit  Nodes
+
+	// ONAME nodes for all params/locals for this func/closure, does NOT
+	// include closurevars until transforming closures during walk.
+	// Names must be listed PPARAMs, PPARAMOUTs, then PAUTOs,
+	// with PPARAMs and PPARAMOUTs in order corresponding to the function signature.
+	// However, as anonymous or blank PPARAMs are not actually declared,
+	// they are omitted from Dcl.
+	// Anonymous and blank PPARAMOUTs are declared as ~rNN and ~bNN Names, respectively.
+	Dcl []*Name
+
+	// ClosureVars lists the free variables that are used within a
+	// function literal, but formally declared in an enclosing
+	// function. The variables in this slice are the closure function's
+	// own copy of the variables, which are used within its function
+	// body. They will also each have IsClosureVar set, and will have
+	// Byval set if they're captured by value.
+	ClosureVars []*Name
+
+	// Enclosed functions that need to be compiled.
+	// Populated during walk.
+	Closures []*Func
+
+	// Parents records the parent scope of each scope within a
+	// function. The root scope (0) has no parent, so the i'th
+	// scope's parent is stored at Parents[i-1].
+	Parents []ScopeID
+
+	// Marks records scope boundary changes.
+	Marks []Mark
+
+	FieldTrack map[*obj.LSym]struct{}
+	DebugInfo  interface{}
+	LSym       *obj.LSym // Linker object in this function's native ABI (Func.ABI)
+
+	Inl *Inline
+
+	// Closgen tracks how many closures have been generated within
+	// this function. Used by closurename for creating unique
+	// function names.
+	Closgen int32
+
+	Label int32 // largest auto-generated label in this function
+
+	Endlineno src.XPos
+	WBPos     src.XPos // position of first write barrier; see SetWBPos
+
+	Pragma PragmaFlag // go:xxx function annotations
+
+	flags bitset16
+
+	// ABI is a function's "definition" ABI. This is the ABI that
+	// this function's generated code is expecting to be called by.
+	//
+	// For most functions, this will be obj.ABIInternal. It may be
+	// a different ABI for functions defined in assembly or ABI wrappers.
+	//
+	// This is included in the export data and tracked across packages.
+	ABI obj.ABI
+	// ABIRefs is the set of ABIs by which this function is referenced.
+	// For ABIs other than this function's definition ABI, the
+	// compiler generates ABI wrapper functions. This is only tracked
+	// within a package.
+	ABIRefs obj.ABISet
+
+	NumDefers  int32 // number of defer calls in the function
+	NumReturns int32 // number of explicit returns in the function
+
+	// nwbrCalls records the LSyms of functions called by this
+	// function for go:nowritebarrierrec analysis. Only filled in
+	// if nowritebarrierrecCheck != nil.
+	NWBRCalls *[]SymAndPos
+}
+
+func NewFunc(pos src.XPos) *Func {
+	f := new(Func)
+	f.pos = pos
+	f.op = ODCLFUNC
+	f.Iota = -1
+	// Most functions are ABIInternal. The importer or symabis
+	// pass may override this.
+	f.ABI = obj.ABIInternal
+	return f
+}
+
+func (f *Func) isStmt() {}
+
+func (n *Func) copy() Node                         { panic(n.no("copy")) }
+func (n *Func) doChildren(do func(Node) bool) bool { return doNodes(n.Body, do) }
+func (n *Func) editChildren(edit func(Node) Node)  { editNodes(n.Body, edit) }
+
+func (f *Func) Type() *types.Type                { return f.Nname.Type() }
+func (f *Func) Sym() *types.Sym                  { return f.Nname.Sym() }
+func (f *Func) Linksym() *obj.LSym               { return f.Nname.Linksym() }
+func (f *Func) LinksymABI(abi obj.ABI) *obj.LSym { return f.Nname.LinksymABI(abi) }
+
+// An Inline holds fields used for function bodies that can be inlined.
+type Inline struct {
+	Cost int32 // heuristic cost of inlining this function
+
+	// Copies of Func.Dcl and Func.Body for use during inlining. Copies are
+	// needed because the function's dcl/body may be changed by later compiler
+	// transformations. These fields are also populated when a function from
+	// another package is imported.
+	Dcl  []*Name
+	Body []Node
+}
+
+// A Mark represents a scope boundary.
+type Mark struct {
+	// Pos is the position of the token that marks the scope
+	// change.
+	Pos src.XPos
+
+	// Scope identifies the innermost scope to the right of Pos.
+	Scope ScopeID
+}
+
+// A ScopeID represents a lexical scope within a function.
+type ScopeID int32
+
+const (
+	funcDupok         = 1 << iota // duplicate definitions ok
+	funcWrapper                   // hide frame from users (elide in tracebacks, don't count as a frame for recover())
+	funcABIWrapper                // is an ABI wrapper (also set flagWrapper)
+	funcNeedctxt                  // function uses context register (has closure variables)
+	funcReflectMethod             // function calls reflect.Type.Method or MethodByName
+	// true if closure inside a function; false if a simple function or a
+	// closure in a global variable initialization
+	funcIsHiddenClosure
+	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
+	funcInstrumentBody           // add race/msan instrumentation during SSA construction
+	funcOpenCodedDeferDisallowed // can't do open-coded defers
+	funcClosureCalled            // closure is only immediately called
+)
+
+type SymAndPos struct {
+	Sym *obj.LSym // LSym of callee
+	Pos src.XPos  // line of call
+}
+
+func (f *Func) Dupok() bool                    { return f.flags&funcDupok != 0 }
+func (f *Func) Wrapper() bool                  { return f.flags&funcWrapper != 0 }
+func (f *Func) ABIWrapper() bool               { return f.flags&funcABIWrapper != 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) 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) InstrumentBody() bool           { return f.flags&funcInstrumentBody != 0 }
+func (f *Func) OpenCodedDeferDisallowed() bool { return f.flags&funcOpenCodedDeferDisallowed != 0 }
+func (f *Func) ClosureCalled() bool            { return f.flags&funcClosureCalled != 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) SetABIWrapper(b bool)               { f.flags.set(funcABIWrapper, 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) 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) SetInstrumentBody(b bool)           { f.flags.set(funcInstrumentBody, b) }
+func (f *Func) SetOpenCodedDeferDisallowed(b bool) { f.flags.set(funcOpenCodedDeferDisallowed, b) }
+func (f *Func) SetClosureCalled(b bool)            { f.flags.set(funcClosureCalled, b) }
+
+func (f *Func) SetWBPos(pos src.XPos) {
+	if base.Debug.WB != 0 {
+		base.WarnfAt(pos, "write barrier")
+	}
+	if !f.WBPos.IsKnown() {
+		f.WBPos = pos
+	}
+}
+
+// FuncName returns the name (without the package) of the function n.
+func FuncName(f *Func) string {
+	if f == nil || f.Nname == nil {
+		return "<nil>"
+	}
+	return f.Sym().Name
+}
+
+// PkgFuncName returns the name of the function referenced by n, with package prepended.
+// This differs from the compiler's internal convention where local functions lack a package
+// because the ultimate consumer of this is a human looking at an IDE; package is only empty
+// if the compilation package is actually the empty string.
+func PkgFuncName(f *Func) string {
+	if f == nil || f.Nname == nil {
+		return "<nil>"
+	}
+	s := f.Sym()
+	pkg := s.Pkg
+
+	p := base.Ctxt.Pkgpath
+	if pkg != nil && pkg.Path != "" {
+		p = pkg.Path
+	}
+	if p == "" {
+		return s.Name
+	}
+	return p + "." + s.Name
+}
+
+var CurFunc *Func
+
+func FuncSymName(s *types.Sym) string {
+	return s.Name + "·f"
+}
+
+// MarkFunc marks a node as a function.
+func MarkFunc(n *Name) {
+	if n.Op() != ONAME || n.Class != Pxxx {
+		base.Fatalf("expected ONAME/Pxxx node, got %v", n)
+	}
+
+	n.Class = PFUNC
+	n.Sym().SetFunc(true)
+}
+
+// ClosureDebugRuntimeCheck applies boilerplate checks for debug flags
+// and compiling runtime
+func ClosureDebugRuntimeCheck(clo *ClosureExpr) {
+	if base.Debug.Closure > 0 {
+		if clo.Esc() == EscHeap {
+			base.WarnfAt(clo.Pos(), "heap closure, captured vars = %v", clo.Func.ClosureVars)
+		} else {
+			base.WarnfAt(clo.Pos(), "stack closure, captured vars = %v", clo.Func.ClosureVars)
+		}
+	}
+	if base.Flag.CompilingRuntime && clo.Esc() == EscHeap {
+		base.ErrorfAt(clo.Pos(), "heap-allocated closure, not allowed in runtime")
+	}
+}
+
+// IsTrivialClosure reports whether closure clo has an
+// empty list of captured vars.
+func IsTrivialClosure(clo *ClosureExpr) bool {
+	return len(clo.Func.ClosureVars) == 0
+}
diff --git a/src/cmd/compile/internal/ir/ir.go b/src/cmd/compile/internal/ir/ir.go
new file mode 100644
index 0000000..82224ca
--- /dev/null
+++ b/src/cmd/compile/internal/ir/ir.go
@@ -0,0 +1,5 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
diff --git a/src/cmd/compile/internal/ir/mini.go b/src/cmd/compile/internal/ir/mini.go
new file mode 100644
index 0000000..a7ff4ac
--- /dev/null
+++ b/src/cmd/compile/internal/ir/mini.go
@@ -0,0 +1,92 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run -mod=mod mknode.go
+
+package ir
+
+import (
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+	"fmt"
+	"go/constant"
+)
+
+// A miniNode is a minimal node implementation,
+// meant to be embedded as the first field in a larger node implementation,
+// at a cost of 8 bytes.
+//
+// A miniNode is NOT a valid Node by itself: the embedding struct
+// must at the least provide:
+//
+//	func (n *MyNode) String() string { return fmt.Sprint(n) }
+//	func (n *MyNode) rawCopy() Node { c := *n; return &c }
+//	func (n *MyNode) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+//
+// The embedding struct should also fill in n.op in its constructor,
+// for more useful panic messages when invalid methods are called,
+// instead of implementing Op itself.
+//
+type miniNode struct {
+	pos  src.XPos // uint32
+	op   Op       // uint8
+	bits bitset8
+	esc  uint16
+}
+
+// posOr returns pos if known, or else n.pos.
+// For use in DeepCopy.
+func (n *miniNode) posOr(pos src.XPos) src.XPos {
+	if pos.IsKnown() {
+		return pos
+	}
+	return n.pos
+}
+
+// op can be read, but not written.
+// An embedding implementation can provide a SetOp if desired.
+// (The panicking SetOp is with the other panics below.)
+func (n *miniNode) Op() Op            { return n.op }
+func (n *miniNode) Pos() src.XPos     { return n.pos }
+func (n *miniNode) SetPos(x src.XPos) { n.pos = x }
+func (n *miniNode) Esc() uint16       { return n.esc }
+func (n *miniNode) SetEsc(x uint16)   { n.esc = x }
+
+const (
+	miniWalkdefShift   = 0 // TODO(mdempsky): Move to Name.flags.
+	miniTypecheckShift = 2
+	miniDiag           = 1 << 4
+	miniWalked         = 1 << 5 // to prevent/catch re-walking
+)
+
+func (n *miniNode) Typecheck() uint8 { return n.bits.get2(miniTypecheckShift) }
+func (n *miniNode) SetTypecheck(x uint8) {
+	if x > 3 {
+		panic(fmt.Sprintf("cannot SetTypecheck %d", x))
+	}
+	n.bits.set2(miniTypecheckShift, x)
+}
+
+func (n *miniNode) Diag() bool     { return n.bits&miniDiag != 0 }
+func (n *miniNode) SetDiag(x bool) { n.bits.set(miniDiag, x) }
+
+func (n *miniNode) Walked() bool     { return n.bits&miniWalked != 0 }
+func (n *miniNode) SetWalked(x bool) { n.bits.set(miniWalked, x) }
+
+// Empty, immutable graph structure.
+
+func (n *miniNode) Init() Nodes { return Nodes{} }
+
+// Additional functionality unavailable.
+
+func (n *miniNode) no(name string) string { return "cannot " + name + " on " + n.op.String() }
+
+func (n *miniNode) Type() *types.Type       { return nil }
+func (n *miniNode) SetType(*types.Type)     { panic(n.no("SetType")) }
+func (n *miniNode) Name() *Name             { return nil }
+func (n *miniNode) Sym() *types.Sym         { return nil }
+func (n *miniNode) Val() constant.Value     { panic(n.no("Val")) }
+func (n *miniNode) SetVal(v constant.Value) { panic(n.no("SetVal")) }
+func (n *miniNode) NonNil() bool            { return false }
+func (n *miniNode) MarkNonNil()             { panic(n.no("MarkNonNil")) }
diff --git a/src/cmd/compile/internal/ir/mknode.go b/src/cmd/compile/internal/ir/mknode.go
new file mode 100644
index 0000000..5a0aaad
--- /dev/null
+++ b/src/cmd/compile/internal/ir/mknode.go
@@ -0,0 +1,229 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build ignore
+// +build ignore
+
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"go/format"
+	"go/types"
+	"io/ioutil"
+	"log"
+	"reflect"
+	"sort"
+	"strings"
+
+	"golang.org/x/tools/go/packages"
+)
+
+var irPkg *types.Package
+var buf bytes.Buffer
+
+func main() {
+	cfg := &packages.Config{
+		Mode: packages.NeedSyntax | packages.NeedTypes,
+	}
+	pkgs, err := packages.Load(cfg, "cmd/compile/internal/ir")
+	if err != nil {
+		log.Fatal(err)
+	}
+	irPkg = pkgs[0].Types
+
+	fmt.Fprintln(&buf, "// Code generated by mknode.go. DO NOT EDIT.")
+	fmt.Fprintln(&buf)
+	fmt.Fprintln(&buf, "package ir")
+	fmt.Fprintln(&buf)
+	fmt.Fprintln(&buf, `import "fmt"`)
+
+	scope := irPkg.Scope()
+	for _, name := range scope.Names() {
+		if strings.HasPrefix(name, "mini") {
+			continue
+		}
+
+		obj, ok := scope.Lookup(name).(*types.TypeName)
+		if !ok {
+			continue
+		}
+		typ := obj.Type().(*types.Named)
+		if !implementsNode(types.NewPointer(typ)) {
+			continue
+		}
+
+		fmt.Fprintf(&buf, "\n")
+		fmt.Fprintf(&buf, "func (n *%s) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }\n", name)
+
+		switch name {
+		case "Name", "Func":
+			// Too specialized to automate.
+			continue
+		}
+
+		forNodeFields(typ,
+			"func (n *%[1]s) copy() Node { c := *n\n",
+			"",
+			"c.%[1]s = copy%[2]s(c.%[1]s)",
+			"return &c }\n")
+
+		forNodeFields(typ,
+			"func (n *%[1]s) doChildren(do func(Node) bool) bool {\n",
+			"if n.%[1]s != nil && do(n.%[1]s) { return true }",
+			"if do%[2]s(n.%[1]s, do) { return true }",
+			"return false }\n")
+
+		forNodeFields(typ,
+			"func (n *%[1]s) editChildren(edit func(Node) Node) {\n",
+			"if n.%[1]s != nil { n.%[1]s = edit(n.%[1]s).(%[2]s) }",
+			"edit%[2]s(n.%[1]s, edit)",
+			"}\n")
+	}
+
+	makeHelpers()
+
+	out, err := format.Source(buf.Bytes())
+	if err != nil {
+		// write out mangled source so we can see the bug.
+		out = buf.Bytes()
+	}
+
+	err = ioutil.WriteFile("node_gen.go", out, 0666)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+// needHelper maps needed slice helpers from their base name to their
+// respective slice-element type.
+var needHelper = map[string]string{}
+
+func makeHelpers() {
+	var names []string
+	for name := range needHelper {
+		names = append(names, name)
+	}
+	sort.Strings(names)
+
+	for _, name := range names {
+		fmt.Fprintf(&buf, sliceHelperTmpl, name, needHelper[name])
+	}
+}
+
+const sliceHelperTmpl = `
+func copy%[1]s(list []%[2]s) []%[2]s {
+	if list == nil {
+		return nil
+	}
+	c := make([]%[2]s, len(list))
+	copy(c, list)
+	return c
+}
+func do%[1]s(list []%[2]s, do func(Node) bool) bool {
+	for _, x := range list {
+		if x != nil && do(x) {
+			return true
+		}
+	}
+	return false
+}
+func edit%[1]s(list []%[2]s, edit func(Node) Node) {
+	for i, x := range list {
+		if x != nil {
+			list[i] = edit(x).(%[2]s)
+		}
+	}
+}
+`
+
+func forNodeFields(named *types.Named, prologue, singleTmpl, sliceTmpl, epilogue string) {
+	fmt.Fprintf(&buf, prologue, named.Obj().Name())
+
+	anyField(named.Underlying().(*types.Struct), func(f *types.Var) bool {
+		if f.Embedded() {
+			return false
+		}
+		name, typ := f.Name(), f.Type()
+
+		slice, _ := typ.Underlying().(*types.Slice)
+		if slice != nil {
+			typ = slice.Elem()
+		}
+
+		tmpl, what := singleTmpl, types.TypeString(typ, types.RelativeTo(irPkg))
+		if implementsNode(typ) {
+			if slice != nil {
+				helper := strings.TrimPrefix(what, "*") + "s"
+				needHelper[helper] = what
+				tmpl, what = sliceTmpl, helper
+			}
+		} else if what == "*Field" {
+			// Special case for *Field.
+			tmpl = sliceTmpl
+			if slice != nil {
+				what = "Fields"
+			} else {
+				what = "Field"
+			}
+		} else {
+			return false
+		}
+
+		if tmpl == "" {
+			return false
+		}
+
+		// Allow template to not use all arguments without
+		// upsetting fmt.Printf.
+		s := fmt.Sprintf(tmpl+"\x00 %[1]s %[2]s", name, what)
+		fmt.Fprintln(&buf, s[:strings.LastIndex(s, "\x00")])
+		return false
+	})
+
+	fmt.Fprintf(&buf, epilogue)
+}
+
+func implementsNode(typ types.Type) bool {
+	if _, ok := typ.Underlying().(*types.Interface); ok {
+		// TODO(mdempsky): Check the interface implements Node.
+		// Worst case, node_gen.go will fail to compile if we're wrong.
+		return true
+	}
+
+	if ptr, ok := typ.(*types.Pointer); ok {
+		if str, ok := ptr.Elem().Underlying().(*types.Struct); ok {
+			return anyField(str, func(f *types.Var) bool {
+				return f.Embedded() && f.Name() == "miniNode"
+			})
+		}
+	}
+
+	return false
+}
+
+func anyField(typ *types.Struct, pred func(f *types.Var) bool) bool {
+	for i, n := 0, typ.NumFields(); i < n; i++ {
+		if value, ok := reflect.StructTag(typ.Tag(i)).Lookup("mknode"); ok {
+			if value != "-" {
+				panic(fmt.Sprintf("unexpected tag value: %q", value))
+			}
+			continue
+		}
+
+		f := typ.Field(i)
+		if pred(f) {
+			return true
+		}
+		if f.Embedded() {
+			if typ, ok := f.Type().Underlying().(*types.Struct); ok {
+				if anyField(typ, pred) {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
diff --git a/src/cmd/compile/internal/ir/name.go b/src/cmd/compile/internal/ir/name.go
new file mode 100644
index 0000000..b6c68bc
--- /dev/null
+++ b/src/cmd/compile/internal/ir/name.go
@@ -0,0 +1,516 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/objabi"
+	"cmd/internal/src"
+	"fmt"
+
+	"go/constant"
+)
+
+// An Ident is an identifier, possibly qualified.
+type Ident struct {
+	miniExpr
+	sym *types.Sym
+}
+
+func NewIdent(pos src.XPos, sym *types.Sym) *Ident {
+	n := new(Ident)
+	n.op = ONONAME
+	n.pos = pos
+	n.sym = sym
+	return n
+}
+
+func (n *Ident) Sym() *types.Sym { return n.sym }
+
+func (*Ident) CanBeNtype() {}
+
+// Name holds Node fields used only by named nodes (ONAME, OTYPE, some OLITERAL).
+type Name struct {
+	miniExpr
+	BuiltinOp Op         // uint8
+	Class     Class      // uint8
+	pragma    PragmaFlag // int16
+	flags     bitset16
+	sym       *types.Sym
+	Func      *Func // TODO(austin): nil for I.M, eqFor, hashfor, and hashmem
+	Offset_   int64
+	val       constant.Value
+	Opt       interface{} // for use by escape analysis
+	Embed     *[]Embed    // list of embedded files, for ONAME var
+
+	PkgName *PkgName // real package for import . names
+	// For a local variable (not param) or extern, the initializing assignment (OAS or OAS2).
+	// For a closure var, the ONAME node of the outer captured variable.
+	// For the case-local variables of a type switch, the type switch guard (OTYPESW).
+	// For the name of a function, points to corresponding Func node.
+	Defn Node
+
+	// The function, method, or closure in which local variable or param is declared.
+	Curfn *Func
+
+	Ntype    Ntype
+	Heapaddr *Name // temp holding heap address of param
+
+	// ONAME closure linkage
+	// Consider:
+	//
+	//	func f() {
+	//		x := 1 // x1
+	//		func() {
+	//			use(x) // x2
+	//			func() {
+	//				use(x) // x3
+	//				--- parser is here ---
+	//			}()
+	//		}()
+	//	}
+	//
+	// There is an original declaration of x and then a chain of mentions of x
+	// leading into the current function. Each time x is mentioned in a new closure,
+	// we create a variable representing x for use in that specific closure,
+	// since the way you get to x is different in each closure.
+	//
+	// Let's number the specific variables as shown in the code:
+	// x1 is the original x, x2 is when mentioned in the closure,
+	// and x3 is when mentioned in the closure in the closure.
+	//
+	// We keep these linked (assume N > 1):
+	//
+	//   - x1.Defn = original declaration statement for x (like most variables)
+	//   - x1.Innermost = current innermost closure x (in this case x3), or nil for none
+	//   - x1.IsClosureVar() = false
+	//
+	//   - xN.Defn = x1, N > 1
+	//   - xN.IsClosureVar() = true, N > 1
+	//   - x2.Outer = nil
+	//   - xN.Outer = x(N-1), N > 2
+	//
+	//
+	// When we look up x in the symbol table, we always get x1.
+	// Then we can use x1.Innermost (if not nil) to get the x
+	// for the innermost known closure function,
+	// but the first reference in a closure will find either no x1.Innermost
+	// or an x1.Innermost with .Funcdepth < Funcdepth.
+	// In that case, a new xN must be created, linked in with:
+	//
+	//     xN.Defn = x1
+	//     xN.Outer = x1.Innermost
+	//     x1.Innermost = xN
+	//
+	// When we finish the function, we'll process its closure variables
+	// and find xN and pop it off the list using:
+	//
+	//     x1 := xN.Defn
+	//     x1.Innermost = xN.Outer
+	//
+	// We leave x1.Innermost set so that we can still get to the original
+	// variable quickly. Not shown here, but once we're
+	// done parsing a function and no longer need xN.Outer for the
+	// lexical x reference links as described above, funcLit
+	// recomputes xN.Outer as the semantic x reference link tree,
+	// even filling in x in intermediate closures that might not
+	// have mentioned it along the way to inner closures that did.
+	// See funcLit for details.
+	//
+	// During the eventual compilation, then, for closure variables we have:
+	//
+	//     xN.Defn = original variable
+	//     xN.Outer = variable captured in next outward scope
+	//                to make closure where xN appears
+	//
+	// Because of the sharding of pieces of the node, x.Defn means x.Name.Defn
+	// and x.Innermost/Outer means x.Name.Param.Innermost/Outer.
+	Innermost *Name
+	Outer     *Name
+}
+
+func (n *Name) isExpr() {}
+
+func (n *Name) copy() Node                         { panic(n.no("copy")) }
+func (n *Name) doChildren(do func(Node) bool) bool { return false }
+func (n *Name) editChildren(edit func(Node) Node)  {}
+
+// TypeDefn returns the type definition for a named OTYPE.
+// That is, given "type T Defn", it returns Defn.
+// It is used by package types.
+func (n *Name) TypeDefn() *types.Type {
+	return n.Ntype.Type()
+}
+
+// RecordFrameOffset records the frame offset for the name.
+// It is used by package types when laying out function arguments.
+func (n *Name) RecordFrameOffset(offset int64) {
+	n.SetFrameOffset(offset)
+}
+
+// NewNameAt returns a new ONAME Node associated with symbol s at position pos.
+// The caller is responsible for setting Curfn.
+func NewNameAt(pos src.XPos, sym *types.Sym) *Name {
+	if sym == nil {
+		base.Fatalf("NewNameAt nil")
+	}
+	return newNameAt(pos, ONAME, sym)
+}
+
+// NewIota returns a new OIOTA Node.
+func NewIota(pos src.XPos, sym *types.Sym) *Name {
+	if sym == nil {
+		base.Fatalf("NewIota nil")
+	}
+	return newNameAt(pos, OIOTA, sym)
+}
+
+// NewDeclNameAt returns a new Name associated with symbol s at position pos.
+// The caller is responsible for setting Curfn.
+func NewDeclNameAt(pos src.XPos, op Op, sym *types.Sym) *Name {
+	if sym == nil {
+		base.Fatalf("NewDeclNameAt nil")
+	}
+	switch op {
+	case ONAME, OTYPE, OLITERAL:
+		// ok
+	default:
+		base.Fatalf("NewDeclNameAt op %v", op)
+	}
+	return newNameAt(pos, op, sym)
+}
+
+// NewConstAt returns a new OLITERAL Node associated with symbol s at position pos.
+func NewConstAt(pos src.XPos, sym *types.Sym, typ *types.Type, val constant.Value) *Name {
+	if sym == nil {
+		base.Fatalf("NewConstAt nil")
+	}
+	n := newNameAt(pos, OLITERAL, sym)
+	n.SetType(typ)
+	n.SetVal(val)
+	return n
+}
+
+// newNameAt is like NewNameAt but allows sym == nil.
+func newNameAt(pos src.XPos, op Op, sym *types.Sym) *Name {
+	n := new(Name)
+	n.op = op
+	n.pos = pos
+	n.sym = sym
+	return n
+}
+
+func (n *Name) Name() *Name         { return n }
+func (n *Name) Sym() *types.Sym     { return n.sym }
+func (n *Name) SetSym(x *types.Sym) { n.sym = x }
+func (n *Name) SubOp() Op           { return n.BuiltinOp }
+func (n *Name) SetSubOp(x Op)       { n.BuiltinOp = x }
+func (n *Name) SetFunc(x *Func)     { n.Func = x }
+func (n *Name) Offset() int64       { panic("Name.Offset") }
+func (n *Name) SetOffset(x int64) {
+	if x != 0 {
+		panic("Name.SetOffset")
+	}
+}
+func (n *Name) FrameOffset() int64     { return n.Offset_ }
+func (n *Name) SetFrameOffset(x int64) { n.Offset_ = x }
+func (n *Name) Iota() int64            { return n.Offset_ }
+func (n *Name) SetIota(x int64)        { n.Offset_ = x }
+func (n *Name) Walkdef() uint8         { return n.bits.get2(miniWalkdefShift) }
+func (n *Name) SetWalkdef(x uint8) {
+	if x > 3 {
+		panic(fmt.Sprintf("cannot SetWalkdef %d", x))
+	}
+	n.bits.set2(miniWalkdefShift, x)
+}
+
+func (n *Name) Linksym() *obj.LSym               { return n.sym.Linksym() }
+func (n *Name) LinksymABI(abi obj.ABI) *obj.LSym { return n.sym.LinksymABI(abi) }
+
+func (*Name) CanBeNtype()    {}
+func (*Name) CanBeAnSSASym() {}
+func (*Name) CanBeAnSSAAux() {}
+
+// Pragma returns the PragmaFlag for p, which must be for an OTYPE.
+func (n *Name) Pragma() PragmaFlag { return n.pragma }
+
+// SetPragma sets the PragmaFlag for p, which must be for an OTYPE.
+func (n *Name) SetPragma(flag PragmaFlag) { n.pragma = flag }
+
+// Alias reports whether p, which must be for an OTYPE, is a type alias.
+func (n *Name) Alias() bool { return n.flags&nameAlias != 0 }
+
+// SetAlias sets whether p, which must be for an OTYPE, is a type alias.
+func (n *Name) SetAlias(alias bool) { n.flags.set(nameAlias, alias) }
+
+const (
+	nameReadonly                 = 1 << iota
+	nameByval                    // is the variable captured by value or by reference
+	nameNeedzero                 // if it contains pointers, needs to be zeroed on function entry
+	nameAutoTemp                 // is the variable a temporary (implies no dwarf info. reset if escapes to heap)
+	nameUsed                     // for variable declared and not used error
+	nameIsClosureVar             // PAUTOHEAP closure pseudo-variable; original (if any) at n.Defn
+	nameIsOutputParamHeapAddr    // pointer to a result parameter's heap copy
+	nameIsOutputParamInRegisters // output parameter in registers spills as an auto
+	nameAddrtaken                // address taken, even if not moved to heap
+	nameInlFormal                // PAUTO created by inliner, derived from callee formal
+	nameInlLocal                 // PAUTO created by inliner, derived from callee local
+	nameOpenDeferSlot            // if temporary var storing info for open-coded defers
+	nameLibfuzzerExtraCounter    // if PEXTERN should be assigned to __libfuzzer_extra_counters section
+	nameAlias                    // is type name an alias
+)
+
+func (n *Name) Readonly() bool                 { return n.flags&nameReadonly != 0 }
+func (n *Name) Needzero() bool                 { return n.flags&nameNeedzero != 0 }
+func (n *Name) AutoTemp() bool                 { return n.flags&nameAutoTemp != 0 }
+func (n *Name) Used() bool                     { return n.flags&nameUsed != 0 }
+func (n *Name) IsClosureVar() bool             { return n.flags&nameIsClosureVar != 0 }
+func (n *Name) IsOutputParamHeapAddr() bool    { return n.flags&nameIsOutputParamHeapAddr != 0 }
+func (n *Name) IsOutputParamInRegisters() bool { return n.flags&nameIsOutputParamInRegisters != 0 }
+func (n *Name) Addrtaken() bool                { return n.flags&nameAddrtaken != 0 }
+func (n *Name) InlFormal() bool                { return n.flags&nameInlFormal != 0 }
+func (n *Name) InlLocal() bool                 { return n.flags&nameInlLocal != 0 }
+func (n *Name) OpenDeferSlot() bool            { return n.flags&nameOpenDeferSlot != 0 }
+func (n *Name) LibfuzzerExtraCounter() bool    { return n.flags&nameLibfuzzerExtraCounter != 0 }
+
+func (n *Name) setReadonly(b bool)                 { n.flags.set(nameReadonly, b) }
+func (n *Name) SetNeedzero(b bool)                 { n.flags.set(nameNeedzero, b) }
+func (n *Name) SetAutoTemp(b bool)                 { n.flags.set(nameAutoTemp, b) }
+func (n *Name) SetUsed(b bool)                     { n.flags.set(nameUsed, b) }
+func (n *Name) SetIsClosureVar(b bool)             { n.flags.set(nameIsClosureVar, b) }
+func (n *Name) SetIsOutputParamHeapAddr(b bool)    { n.flags.set(nameIsOutputParamHeapAddr, b) }
+func (n *Name) SetIsOutputParamInRegisters(b bool) { n.flags.set(nameIsOutputParamInRegisters, b) }
+func (n *Name) SetAddrtaken(b bool)                { n.flags.set(nameAddrtaken, b) }
+func (n *Name) SetInlFormal(b bool)                { n.flags.set(nameInlFormal, b) }
+func (n *Name) SetInlLocal(b bool)                 { n.flags.set(nameInlLocal, b) }
+func (n *Name) SetOpenDeferSlot(b bool)            { n.flags.set(nameOpenDeferSlot, b) }
+func (n *Name) SetLibfuzzerExtraCounter(b bool)    { n.flags.set(nameLibfuzzerExtraCounter, b) }
+
+// OnStack reports whether variable n may reside on the stack.
+func (n *Name) OnStack() bool {
+	if n.Op() == ONAME {
+		switch n.Class {
+		case PPARAM, PPARAMOUT, PAUTO:
+			return n.Esc() != EscHeap
+		case PEXTERN, PAUTOHEAP:
+			return false
+		}
+	}
+	// Note: fmt.go:dumpNodeHeader calls all "func() bool"-typed
+	// methods, but it can only recover from panics, not Fatalf.
+	panic(fmt.Sprintf("%v: not a variable: %v", base.FmtPos(n.Pos()), n))
+}
+
+// MarkReadonly indicates that n is an ONAME with readonly contents.
+func (n *Name) MarkReadonly() {
+	if n.Op() != ONAME {
+		base.Fatalf("Node.MarkReadonly %v", n.Op())
+	}
+	n.setReadonly(true)
+	// Mark the linksym as readonly immediately
+	// so that the SSA backend can use this information.
+	// It will be overridden later during dumpglobls.
+	n.Linksym().Type = objabi.SRODATA
+}
+
+// Val returns the constant.Value for the node.
+func (n *Name) Val() constant.Value {
+	if n.val == nil {
+		return constant.MakeUnknown()
+	}
+	return n.val
+}
+
+// SetVal sets the constant.Value for the node.
+func (n *Name) SetVal(v constant.Value) {
+	if n.op != OLITERAL {
+		panic(n.no("SetVal"))
+	}
+	AssertValidTypeForConst(n.Type(), v)
+	n.val = v
+}
+
+// Canonical returns the logical declaration that n represents. If n
+// is a closure variable, then Canonical returns the original Name as
+// it appears in the function that immediately contains the
+// declaration. Otherwise, Canonical simply returns n itself.
+func (n *Name) Canonical() *Name {
+	if n.IsClosureVar() && n.Defn != nil {
+		n = n.Defn.(*Name)
+	}
+	return n
+}
+
+func (n *Name) SetByval(b bool) {
+	if n.Canonical() != n {
+		base.Fatalf("SetByval called on non-canonical variable: %v", n)
+	}
+	n.flags.set(nameByval, b)
+}
+
+func (n *Name) Byval() bool {
+	// We require byval to be set on the canonical variable, but we
+	// allow it to be accessed from any instance.
+	return n.Canonical().flags&nameByval != 0
+}
+
+// CaptureName returns a Name suitable for referring to n from within function
+// fn or from the package block if fn is nil. If n is a free variable declared
+// within a function that encloses fn, then CaptureName returns a closure
+// variable that refers to n and adds it to fn.ClosureVars. Otherwise, it simply
+// returns n.
+func CaptureName(pos src.XPos, fn *Func, n *Name) *Name {
+	if n.IsClosureVar() {
+		base.FatalfAt(pos, "misuse of CaptureName on closure variable: %v", n)
+	}
+	if n.Op() != ONAME || n.Curfn == nil || n.Curfn == fn {
+		return n // okay to use directly
+	}
+	if fn == nil {
+		base.FatalfAt(pos, "package-block reference to %v, declared in %v", n, n.Curfn)
+	}
+
+	c := n.Innermost
+	if c != nil && c.Curfn == fn {
+		return c
+	}
+
+	// Do not have a closure var for the active closure yet; make one.
+	c = NewNameAt(pos, n.Sym())
+	c.Curfn = fn
+	c.Class = PAUTOHEAP
+	c.SetIsClosureVar(true)
+	c.Defn = n
+
+	// Link into list of active closure variables.
+	// Popped from list in FinishCaptureNames.
+	c.Outer = n.Innermost
+	n.Innermost = c
+	fn.ClosureVars = append(fn.ClosureVars, c)
+
+	return c
+}
+
+// FinishCaptureNames handles any work leftover from calling CaptureName
+// earlier. outerfn should be the function that immediately encloses fn.
+func FinishCaptureNames(pos src.XPos, outerfn, fn *Func) {
+	// closure-specific variables are hanging off the
+	// ordinary ones; see CaptureName above.
+	// unhook them.
+	// make the list of pointers for the closure call.
+	for _, cv := range fn.ClosureVars {
+		// Unlink from n; see comment above on type Name for these fields.
+		n := cv.Defn.(*Name)
+		n.Innermost = cv.Outer
+
+		// If the closure usage of n is not dense, we need to make it
+		// dense by recapturing n within the enclosing function.
+		//
+		// That is, suppose we just finished parsing the innermost
+		// closure f4 in this code:
+		//
+		//	func f() {
+		//		n := 1
+		//		func() { // f2
+		//			use(n)
+		//			func() { // f3
+		//				func() { // f4
+		//					use(n)
+		//				}()
+		//			}()
+		//		}()
+		//	}
+		//
+		// At this point cv.Outer is f2's n; there is no n for f3. To
+		// construct the closure f4 from within f3, we need to use f3's
+		// n and in this case we need to create f3's n with CaptureName.
+		//
+		// We'll decide later in walk whether to use v directly or &v.
+		cv.Outer = CaptureName(pos, outerfn, n)
+	}
+}
+
+// SameSource reports whether two nodes refer to the same source
+// element.
+//
+// It exists to help incrementally migrate the compiler towards
+// allowing the introduction of IdentExpr (#42990). Once we have
+// IdentExpr, it will no longer be safe to directly compare Node
+// values to tell if they refer to the same Name. Instead, code will
+// need to explicitly get references to the underlying Name object(s),
+// and compare those instead.
+//
+// It will still be safe to compare Nodes directly for checking if two
+// nodes are syntactically the same. The SameSource function exists to
+// indicate code that intentionally compares Nodes for syntactic
+// equality as opposed to code that has yet to be updated in
+// preparation for IdentExpr.
+func SameSource(n1, n2 Node) bool {
+	return n1 == n2
+}
+
+// Uses reports whether expression x is a (direct) use of the given
+// variable.
+func Uses(x Node, v *Name) bool {
+	if v == nil || v.Op() != ONAME {
+		base.Fatalf("RefersTo bad Name: %v", v)
+	}
+	return x.Op() == ONAME && x.Name() == v
+}
+
+// DeclaredBy reports whether expression x refers (directly) to a
+// variable that was declared by the given statement.
+func DeclaredBy(x, stmt Node) bool {
+	if stmt == nil {
+		base.Fatalf("DeclaredBy nil")
+	}
+	return x.Op() == ONAME && SameSource(x.Name().Defn, stmt)
+}
+
+// The Class of a variable/function describes the "storage class"
+// of a variable or function. During parsing, storage classes are
+// called declaration contexts.
+type Class uint8
+
+//go:generate stringer -type=Class name.go
+const (
+	Pxxx       Class = iota // no class; used during ssa conversion to indicate pseudo-variables
+	PEXTERN                 // global variables
+	PAUTO                   // local variables
+	PAUTOHEAP               // local variables or parameters moved to heap
+	PPARAM                  // input arguments
+	PPARAMOUT               // output results
+	PTYPEPARAM              // type params
+	PFUNC                   // global functions
+
+	// Careful: Class is stored in three bits in Node.flags.
+	_ = uint((1 << 3) - iota) // static assert for iota <= (1 << 3)
+)
+
+type Embed struct {
+	Pos      src.XPos
+	Patterns []string
+}
+
+// A Pack is an identifier referring to an imported package.
+type PkgName struct {
+	miniNode
+	sym  *types.Sym
+	Pkg  *types.Pkg
+	Used bool
+}
+
+func (p *PkgName) Sym() *types.Sym { return p.sym }
+
+func (*PkgName) CanBeNtype() {}
+
+func NewPkgName(pos src.XPos, sym *types.Sym, pkg *types.Pkg) *PkgName {
+	p := &PkgName{sym: sym, Pkg: pkg}
+	p.op = OPACK
+	p.pos = pos
+	return p
+}
diff --git a/src/cmd/compile/internal/ir/node.go b/src/cmd/compile/internal/ir/node.go
new file mode 100644
index 0000000..af559cc
--- /dev/null
+++ b/src/cmd/compile/internal/ir/node.go
@@ -0,0 +1,599 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// “Abstract” syntax representation.
+
+package ir
+
+import (
+	"fmt"
+	"go/constant"
+	"sort"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// A Node is the abstract interface to an IR node.
+type Node interface {
+	// Formatting
+	Format(s fmt.State, verb rune)
+
+	// Source position.
+	Pos() src.XPos
+	SetPos(x src.XPos)
+
+	// For making copies. For Copy and SepCopy.
+	copy() Node
+
+	doChildren(func(Node) bool) bool
+	editChildren(func(Node) Node)
+
+	// Abstract graph structure, for generic traversals.
+	Op() Op
+	Init() Nodes
+
+	// Fields specific to certain Ops only.
+	Type() *types.Type
+	SetType(t *types.Type)
+	Name() *Name
+	Sym() *types.Sym
+	Val() constant.Value
+	SetVal(v constant.Value)
+
+	// Storage for analysis passes.
+	Esc() uint16
+	SetEsc(x uint16)
+	Diag() bool
+	SetDiag(x bool)
+
+	// Typecheck values:
+	//  0 means the node is not typechecked
+	//  1 means the node is completely typechecked
+	//  2 means typechecking of the node is in progress
+	//  3 means the node has its type from types2, but may need transformation
+	Typecheck() uint8
+	SetTypecheck(x uint8)
+	NonNil() bool
+	MarkNonNil()
+}
+
+// Line returns n's position as a string. If n has been inlined,
+// it uses the outermost position where n has been inlined.
+func Line(n Node) string {
+	return base.FmtPos(n.Pos())
+}
+
+func IsSynthetic(n Node) bool {
+	name := n.Sym().Name
+	return name[0] == '.' || name[0] == '~'
+}
+
+// IsAutoTmp indicates if n was created by the compiler as a temporary,
+// based on the setting of the .AutoTemp flag in n's Name.
+func IsAutoTmp(n Node) bool {
+	if n == nil || n.Op() != ONAME {
+		return false
+	}
+	return n.Name().AutoTemp()
+}
+
+// MayBeShared reports whether n may occur in multiple places in the AST.
+// Extra care must be taken when mutating such a node.
+func MayBeShared(n Node) bool {
+	switch n.Op() {
+	case ONAME, OLITERAL, ONIL, OTYPE:
+		return true
+	}
+	return false
+}
+
+type InitNode interface {
+	Node
+	PtrInit() *Nodes
+	SetInit(x Nodes)
+}
+
+func TakeInit(n Node) Nodes {
+	init := n.Init()
+	if len(init) != 0 {
+		n.(InitNode).SetInit(nil)
+	}
+	return init
+}
+
+//go:generate stringer -type=Op -trimprefix=O node.go
+
+type Op uint8
+
+// Node ops.
+const (
+	OXXX Op = iota
+
+	// names
+	ONAME // var or func name
+	// Unnamed arg or return value: f(int, string) (int, error) { etc }
+	// Also used for a qualified package identifier that hasn't been resolved yet.
+	ONONAME
+	OTYPE    // type name
+	OPACK    // import
+	OLITERAL // literal
+	ONIL     // nil
+
+	// expressions
+	OADD          // X + Y
+	OSUB          // X - Y
+	OOR           // X | Y
+	OXOR          // X ^ Y
+	OADDSTR       // +{List} (string addition, list elements are strings)
+	OADDR         // &X
+	OANDAND       // X && Y
+	OAPPEND       // append(Args); after walk, X may contain elem type descriptor
+	OBYTES2STR    // Type(X) (Type is string, X is a []byte)
+	OBYTES2STRTMP // Type(X) (Type is string, X is a []byte, ephemeral)
+	ORUNES2STR    // Type(X) (Type is string, X is a []rune)
+	OSTR2BYTES    // Type(X) (Type is []byte, X is a string)
+	OSTR2BYTESTMP // Type(X) (Type is []byte, X is a string, ephemeral)
+	OSTR2RUNES    // Type(X) (Type is []rune, X is a string)
+	OSLICE2ARRPTR // Type(X) (Type is *[N]T, X is a []T)
+	// X = Y or (if Def=true) X := Y
+	// If Def, then Init includes a DCL node for X.
+	OAS
+	// Lhs = Rhs (x, y, z = a, b, c) or (if Def=true) Lhs := Rhs
+	// If Def, then Init includes DCL nodes for Lhs
+	OAS2
+	OAS2DOTTYPE // Lhs = Rhs (x, ok = I.(int))
+	OAS2FUNC    // Lhs = Rhs (x, y = f())
+	OAS2MAPR    // Lhs = Rhs (x, ok = m["foo"])
+	OAS2RECV    // Lhs = Rhs (x, ok = <-c)
+	OASOP       // X AsOp= Y (x += y)
+	OCALL       // X(Args) (function call, method call or type conversion)
+
+	// OCALLFUNC, OCALLMETH, and OCALLINTER have the same structure.
+	// Prior to walk, they are: X(Args), where Args is all regular arguments.
+	// After walk, if any argument whose evaluation might requires temporary variable,
+	// that temporary variable will be pushed to Init, Args will contains an updated
+	// set of arguments. KeepAlive is all OVARLIVE nodes that are attached to OCALLxxx.
+	OCALLFUNC  // X(Args) (function call f(args))
+	OCALLMETH  // X(Args) (direct method call x.Method(args))
+	OCALLINTER // X(Args) (interface method call x.Method(args))
+	OCALLPART  // X.Sel (method expression x.Method, not called)
+	OCAP       // cap(X)
+	OCLOSE     // close(X)
+	OCLOSURE   // func Type { Func.Closure.Body } (func literal)
+	OCOMPLIT   // Type{List} (composite literal, not yet lowered to specific form)
+	OMAPLIT    // Type{List} (composite literal, Type is map)
+	OSTRUCTLIT // Type{List} (composite literal, Type is struct)
+	OARRAYLIT  // Type{List} (composite literal, Type is array)
+	OSLICELIT  // Type{List} (composite literal, Type is slice), Len is slice length.
+	OPTRLIT    // &X (X is composite literal)
+	OCONV      // Type(X) (type conversion)
+	OCONVIFACE // Type(X) (type conversion, to interface)
+	OCONVNOP   // Type(X) (type conversion, no effect)
+	OCOPY      // copy(X, Y)
+	ODCL       // var X (declares X of type X.Type)
+
+	// Used during parsing but don't last.
+	ODCLFUNC  // func f() or func (r) f()
+	ODCLCONST // const pi = 3.14
+	ODCLTYPE  // type Int int or type Int = int
+
+	ODELETE        // delete(Args)
+	ODOT           // X.Sel (X is of struct type)
+	ODOTPTR        // X.Sel (X is of pointer to struct type)
+	ODOTMETH       // X.Sel (X is non-interface, Sel is method name)
+	ODOTINTER      // X.Sel (X is interface, Sel is method name)
+	OXDOT          // X.Sel (before rewrite to one of the preceding)
+	ODOTTYPE       // X.Ntype or X.Type (.Ntype during parsing, .Type once resolved); after walk, Itab contains address of interface type descriptor and Itab.X contains address of concrete type descriptor
+	ODOTTYPE2      // X.Ntype or X.Type (.Ntype during parsing, .Type once resolved; on rhs of OAS2DOTTYPE); after walk, Itab contains address of interface type descriptor
+	OEQ            // X == Y
+	ONE            // X != Y
+	OLT            // X < Y
+	OLE            // X <= Y
+	OGE            // X >= Y
+	OGT            // X > Y
+	ODEREF         // *X
+	OINDEX         // X[Index] (index of array or slice)
+	OINDEXMAP      // X[Index] (index of map)
+	OKEY           // Key:Value (key:value in struct/array/map literal)
+	OSTRUCTKEY     // Field:Value (key:value in struct literal, after type checking)
+	OLEN           // len(X)
+	OMAKE          // make(Args) (before type checking converts to one of the following)
+	OMAKECHAN      // make(Type[, Len]) (type is chan)
+	OMAKEMAP       // make(Type[, Len]) (type is map)
+	OMAKESLICE     // make(Type[, Len[, Cap]]) (type is slice)
+	OMAKESLICECOPY // makeslicecopy(Type, Len, Cap) (type is slice; Len is length and Cap is the copied from slice)
+	// OMAKESLICECOPY is created by the order pass and corresponds to:
+	//  s = make(Type, Len); copy(s, Cap)
+	//
+	// Bounded can be set on the node when Len == len(Cap) is known at compile time.
+	//
+	// This node is created so the walk pass can optimize this pattern which would
+	// otherwise be hard to detect after the order pass.
+	OMUL         // X * Y
+	ODIV         // X / Y
+	OMOD         // X % Y
+	OLSH         // X << Y
+	ORSH         // X >> Y
+	OAND         // X & Y
+	OANDNOT      // X &^ Y
+	ONEW         // new(X); corresponds to calls to new in source code
+	ONOT         // !X
+	OBITNOT      // ^X
+	OPLUS        // +X
+	ONEG         // -X
+	OOROR        // X || Y
+	OPANIC       // panic(X)
+	OPRINT       // print(List)
+	OPRINTN      // println(List)
+	OPAREN       // (X)
+	OSEND        // Chan <- Value
+	OSLICE       // X[Low : High] (X is untypechecked or slice)
+	OSLICEARR    // X[Low : High] (X is pointer to array)
+	OSLICESTR    // X[Low : High] (X is string)
+	OSLICE3      // X[Low : High : Max] (X is untypedchecked or slice)
+	OSLICE3ARR   // X[Low : High : Max] (X is pointer to array)
+	OSLICEHEADER // sliceheader{Ptr, Len, Cap} (Ptr is unsafe.Pointer, Len is length, Cap is capacity)
+	ORECOVER     // recover()
+	ORECV        // <-X
+	ORUNESTR     // Type(X) (Type is string, X is rune)
+	OSELRECV2    // like OAS2: Lhs = Rhs where len(Lhs)=2, len(Rhs)=1, Rhs[0].Op = ORECV (appears as .Var of OCASE)
+	OIOTA        // iota
+	OREAL        // real(X)
+	OIMAG        // imag(X)
+	OCOMPLEX     // complex(X, Y)
+	OALIGNOF     // unsafe.Alignof(X)
+	OOFFSETOF    // unsafe.Offsetof(X)
+	OSIZEOF      // unsafe.Sizeof(X)
+	OUNSAFEADD   // unsafe.Add(X, Y)
+	OUNSAFESLICE // unsafe.Slice(X, Y)
+	OMETHEXPR    // method expression
+
+	// statements
+	OBLOCK // { List } (block of code)
+	OBREAK // break [Label]
+	// OCASE:  case List: Body (List==nil means default)
+	//   For OTYPESW, List is a OTYPE node for the specified type (or OLITERAL
+	//   for nil), and, if a type-switch variable is specified, Rlist is an
+	//   ONAME for the version of the type-switch variable with the specified
+	//   type.
+	OCASE
+	OCONTINUE // continue [Label]
+	ODEFER    // defer Call
+	OFALL     // fallthrough
+	OFOR      // for Init; Cond; Post { Body }
+	// OFORUNTIL is like OFOR, but the test (Cond) is applied after the body:
+	// 	Init
+	// 	top: { Body }   // Execute the body at least once
+	// 	cont: Post
+	// 	if Cond {        // And then test the loop condition
+	// 		List     // Before looping to top, execute List
+	// 		goto top
+	// 	}
+	// OFORUNTIL is created by walk. There's no way to write this in Go code.
+	OFORUNTIL
+	OGOTO   // goto Label
+	OIF     // if Init; Cond { Then } else { Else }
+	OLABEL  // Label:
+	OGO     // go Call
+	ORANGE  // for Key, Value = range X { Body }
+	ORETURN // return Results
+	OSELECT // select { Cases }
+	OSWITCH // switch Init; Expr { Cases }
+	// OTYPESW:  X := Y.(type) (appears as .Tag of OSWITCH)
+	//   X is nil if there is no type-switch variable
+	OTYPESW
+	OFUNCINST // instantiation of a generic function
+
+	// types
+	OTCHAN   // chan int
+	OTMAP    // map[string]int
+	OTSTRUCT // struct{}
+	OTINTER  // interface{}
+	// OTFUNC: func() - Recv is receiver field, Params is list of param fields, Results is
+	// list of result fields.
+	OTFUNC
+	OTARRAY // [8]int or [...]int
+	OTSLICE // []int
+
+	// misc
+	// intermediate representation of an inlined call.  Uses Init (assignments
+	// for the captured variables, parameters, retvars, & INLMARK op),
+	// Body (body of the inlined function), and ReturnVars (list of
+	// return values)
+	OINLCALL       // intermediary representation of an inlined call.
+	OEFACE         // itable and data words of an empty-interface value.
+	OITAB          // itable word of an interface value.
+	OIDATA         // data word of an interface value in X
+	OSPTR          // base pointer of a slice or string.
+	OCFUNC         // reference to c function pointer (not go func value)
+	OCHECKNIL      // emit code to ensure pointer/interface not nil
+	OVARDEF        // variable is about to be fully initialized
+	OVARKILL       // variable is dead
+	OVARLIVE       // variable is alive
+	ORESULT        // result of a function call; Xoffset is stack offset
+	OINLMARK       // start of an inlined body, with file/line of caller. Xoffset is an index into the inline tree.
+	OLINKSYMOFFSET // offset within a name
+
+	// arch-specific opcodes
+	OTAILCALL // tail call to another function
+	OGETG     // runtime.getg() (read g pointer)
+
+	OEND
+)
+
+// Nodes is a pointer to a slice of *Node.
+// For fields that are not used in most nodes, this is used instead of
+// a slice to save space.
+type Nodes []Node
+
+// Append appends entries to Nodes.
+func (n *Nodes) Append(a ...Node) {
+	if len(a) == 0 {
+		return
+	}
+	*n = append(*n, a...)
+}
+
+// Prepend prepends entries to Nodes.
+// If a slice is passed in, this will take ownership of it.
+func (n *Nodes) Prepend(a ...Node) {
+	if len(a) == 0 {
+		return
+	}
+	*n = append(a, *n...)
+}
+
+// Take clears n, returning its former contents.
+func (n *Nodes) Take() []Node {
+	ret := *n
+	*n = nil
+	return ret
+}
+
+// Copy returns a copy of the content of the slice.
+func (n Nodes) Copy() Nodes {
+	if n == nil {
+		return nil
+	}
+	c := make(Nodes, len(n))
+	copy(c, n)
+	return c
+}
+
+// NameQueue is a FIFO queue of *Name. The zero value of NameQueue is
+// a ready-to-use empty queue.
+type NameQueue struct {
+	ring       []*Name
+	head, tail int
+}
+
+// Empty reports whether q contains no Names.
+func (q *NameQueue) Empty() bool {
+	return q.head == q.tail
+}
+
+// PushRight appends n to the right of the queue.
+func (q *NameQueue) PushRight(n *Name) {
+	if len(q.ring) == 0 {
+		q.ring = make([]*Name, 16)
+	} else if q.head+len(q.ring) == q.tail {
+		// Grow the ring.
+		nring := make([]*Name, 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 Name from the left of the queue. It panics if q is
+// empty.
+func (q *NameQueue) PopLeft() *Name {
+	if q.Empty() {
+		panic("dequeue empty")
+	}
+	n := q.ring[q.head%len(q.ring)]
+	q.head++
+	return n
+}
+
+// NameSet is a set of Names.
+type NameSet map[*Name]struct{}
+
+// Has reports whether s contains n.
+func (s NameSet) Has(n *Name) bool {
+	_, isPresent := s[n]
+	return isPresent
+}
+
+// Add adds n to s.
+func (s *NameSet) Add(n *Name) {
+	if *s == nil {
+		*s = make(map[*Name]struct{})
+	}
+	(*s)[n] = struct{}{}
+}
+
+// Sorted returns s sorted according to less.
+func (s NameSet) Sorted(less func(*Name, *Name) bool) []*Name {
+	var res []*Name
+	for n := range s {
+		res = append(res, n)
+	}
+	sort.Slice(res, func(i, j int) bool { return less(res[i], res[j]) })
+	return res
+}
+
+type PragmaFlag int16
+
+const (
+	// Func pragmas.
+	Nointerface    PragmaFlag = 1 << iota
+	Noescape                  // func parameters don't escape
+	Norace                    // func must not have race detector annotations
+	Nosplit                   // func should not execute on separate stack
+	Noinline                  // func should not be inlined
+	NoCheckPtr                // func should not be instrumented by checkptr
+	CgoUnsafeArgs             // treat a pointer to one arg as a pointer to them all
+	UintptrEscapes            // pointers converted to uintptr escape
+
+	// Runtime-only func pragmas.
+	// See ../../../../runtime/README.md for detailed descriptions.
+	Systemstack        // func must run on system stack
+	Nowritebarrier     // emit compiler error instead of write barrier
+	Nowritebarrierrec  // error on write barrier in this or recursive callees
+	Yeswritebarrierrec // cancels Nowritebarrierrec in this function and callees
+
+	// Runtime and cgo type pragmas
+	NotInHeap // values of this type must not be heap allocated
+
+	// Go command pragmas
+	GoBuildPragma
+
+	RegisterParams // TODO(register args) remove after register abi is working
+
+)
+
+func AsNode(n types.Object) Node {
+	if n == nil {
+		return nil
+	}
+	return n.(Node)
+}
+
+var BlankNode Node
+
+func IsConst(n Node, ct constant.Kind) bool {
+	return ConstType(n) == ct
+}
+
+// IsNil reports whether n represents the universal untyped zero value "nil".
+func IsNil(n Node) bool {
+	// Check n.Orig because constant propagation may produce typed nil constants,
+	// which don't exist in the Go spec.
+	return n != nil && Orig(n).Op() == ONIL
+}
+
+func IsBlank(n Node) bool {
+	if n == nil {
+		return false
+	}
+	return n.Sym().IsBlank()
+}
+
+// IsMethod reports whether n is a method.
+// n must be a function or a method.
+func IsMethod(n Node) bool {
+	return n.Type().Recv() != nil
+}
+
+func HasNamedResults(fn *Func) bool {
+	typ := fn.Type()
+	return typ.NumResults() > 0 && types.OrigSym(typ.Results().Field(0).Sym) != nil
+}
+
+// HasUniquePos reports whether n has a unique position that can be
+// used for reporting error messages.
+//
+// It's primarily used to distinguish references to named objects,
+// whose Pos will point back to their declaration position rather than
+// their usage position.
+func HasUniquePos(n Node) bool {
+	switch n.Op() {
+	case ONAME, OPACK:
+		return false
+	case OLITERAL, ONIL, OTYPE:
+		if n.Sym() != nil {
+			return false
+		}
+	}
+
+	if !n.Pos().IsKnown() {
+		if base.Flag.K != 0 {
+			base.Warn("setlineno: unknown position (line 0)")
+		}
+		return false
+	}
+
+	return true
+}
+
+func SetPos(n Node) src.XPos {
+	lno := base.Pos
+	if n != nil && HasUniquePos(n) {
+		base.Pos = n.Pos()
+	}
+	return lno
+}
+
+// The result of InitExpr MUST be assigned back to n, e.g.
+// 	n.X = InitExpr(init, n.X)
+func InitExpr(init []Node, expr Node) Node {
+	if len(init) == 0 {
+		return expr
+	}
+
+	n, ok := expr.(InitNode)
+	if !ok || MayBeShared(n) {
+		// Introduce OCONVNOP to hold init list.
+		n = NewConvExpr(base.Pos, OCONVNOP, nil, expr)
+		n.SetType(expr.Type())
+		n.SetTypecheck(1)
+	}
+
+	n.PtrInit().Prepend(init...)
+	return n
+}
+
+// what's the outer value that a write to n affects?
+// outer value means containing struct or array.
+func OuterValue(n Node) Node {
+	for {
+		switch nn := n; nn.Op() {
+		case OXDOT:
+			base.Fatalf("OXDOT in walk")
+		case ODOT:
+			nn := nn.(*SelectorExpr)
+			n = nn.X
+			continue
+		case OPAREN:
+			nn := nn.(*ParenExpr)
+			n = nn.X
+			continue
+		case OCONVNOP:
+			nn := nn.(*ConvExpr)
+			n = nn.X
+			continue
+		case OINDEX:
+			nn := nn.(*IndexExpr)
+			if nn.X.Type() == nil {
+				base.Fatalf("OuterValue needs type for %v", nn.X)
+			}
+			if nn.X.Type().IsArray() {
+				n = nn.X
+				continue
+			}
+		}
+
+		return n
+	}
+}
+
+const (
+	EscUnknown = iota
+	EscNone    // Does not escape to heap, result, or parameters.
+	EscHeap    // Reachable from the heap
+	EscNever   // By construction will not escape.
+)
diff --git a/src/cmd/compile/internal/ir/node_gen.go b/src/cmd/compile/internal/ir/node_gen.go
new file mode 100644
index 0000000..22855d7
--- /dev/null
+++ b/src/cmd/compile/internal/ir/node_gen.go
@@ -0,0 +1,1452 @@
+// Code generated by mknode.go. DO NOT EDIT.
+
+package ir
+
+import "fmt"
+
+func (n *AddStringExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *AddStringExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.List = copyNodes(c.List)
+	return &c
+}
+func (n *AddStringExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if doNodes(n.List, do) {
+		return true
+	}
+	if n.Prealloc != nil && do(n.Prealloc) {
+		return true
+	}
+	return false
+}
+func (n *AddStringExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editNodes(n.List, edit)
+	if n.Prealloc != nil {
+		n.Prealloc = edit(n.Prealloc).(*Name)
+	}
+}
+
+func (n *AddrExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *AddrExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *AddrExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	if n.Prealloc != nil && do(n.Prealloc) {
+		return true
+	}
+	return false
+}
+func (n *AddrExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Prealloc != nil {
+		n.Prealloc = edit(n.Prealloc).(*Name)
+	}
+}
+
+func (n *ArrayType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *ArrayType) copy() Node {
+	c := *n
+	return &c
+}
+func (n *ArrayType) doChildren(do func(Node) bool) bool {
+	if n.Len != nil && do(n.Len) {
+		return true
+	}
+	if n.Elem != nil && do(n.Elem) {
+		return true
+	}
+	return false
+}
+func (n *ArrayType) editChildren(edit func(Node) Node) {
+	if n.Len != nil {
+		n.Len = edit(n.Len).(Node)
+	}
+	if n.Elem != nil {
+		n.Elem = edit(n.Elem).(Ntype)
+	}
+}
+
+func (n *AssignListStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *AssignListStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.Lhs = copyNodes(c.Lhs)
+	c.Rhs = copyNodes(c.Rhs)
+	return &c
+}
+func (n *AssignListStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if doNodes(n.Lhs, do) {
+		return true
+	}
+	if doNodes(n.Rhs, do) {
+		return true
+	}
+	return false
+}
+func (n *AssignListStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editNodes(n.Lhs, edit)
+	editNodes(n.Rhs, edit)
+}
+
+func (n *AssignOpStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *AssignOpStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *AssignOpStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	if n.Y != nil && do(n.Y) {
+		return true
+	}
+	return false
+}
+func (n *AssignOpStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Y != nil {
+		n.Y = edit(n.Y).(Node)
+	}
+}
+
+func (n *AssignStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *AssignStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *AssignStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	if n.Y != nil && do(n.Y) {
+		return true
+	}
+	return false
+}
+func (n *AssignStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Y != nil {
+		n.Y = edit(n.Y).(Node)
+	}
+}
+
+func (n *BasicLit) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *BasicLit) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *BasicLit) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	return false
+}
+func (n *BasicLit) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
+
+func (n *BinaryExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *BinaryExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *BinaryExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	if n.Y != nil && do(n.Y) {
+		return true
+	}
+	return false
+}
+func (n *BinaryExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Y != nil {
+		n.Y = edit(n.Y).(Node)
+	}
+}
+
+func (n *BlockStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *BlockStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.List = copyNodes(c.List)
+	return &c
+}
+func (n *BlockStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if doNodes(n.List, do) {
+		return true
+	}
+	return false
+}
+func (n *BlockStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editNodes(n.List, edit)
+}
+
+func (n *BranchStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *BranchStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *BranchStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	return false
+}
+func (n *BranchStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
+
+func (n *CallExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *CallExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.Args = copyNodes(c.Args)
+	c.KeepAlive = copyNames(c.KeepAlive)
+	return &c
+}
+func (n *CallExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	if doNodes(n.Args, do) {
+		return true
+	}
+	if doNames(n.KeepAlive, do) {
+		return true
+	}
+	return false
+}
+func (n *CallExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	editNodes(n.Args, edit)
+	editNames(n.KeepAlive, edit)
+}
+
+func (n *CaseClause) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *CaseClause) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.List = copyNodes(c.List)
+	c.Body = copyNodes(c.Body)
+	return &c
+}
+func (n *CaseClause) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Var != nil && do(n.Var) {
+		return true
+	}
+	if doNodes(n.List, do) {
+		return true
+	}
+	if doNodes(n.Body, do) {
+		return true
+	}
+	return false
+}
+func (n *CaseClause) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Var != nil {
+		n.Var = edit(n.Var).(*Name)
+	}
+	editNodes(n.List, edit)
+	editNodes(n.Body, edit)
+}
+
+func (n *ChanType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *ChanType) copy() Node {
+	c := *n
+	return &c
+}
+func (n *ChanType) doChildren(do func(Node) bool) bool {
+	if n.Elem != nil && do(n.Elem) {
+		return true
+	}
+	return false
+}
+func (n *ChanType) editChildren(edit func(Node) Node) {
+	if n.Elem != nil {
+		n.Elem = edit(n.Elem).(Ntype)
+	}
+}
+
+func (n *ClosureExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *ClosureExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *ClosureExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Prealloc != nil && do(n.Prealloc) {
+		return true
+	}
+	return false
+}
+func (n *ClosureExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Prealloc != nil {
+		n.Prealloc = edit(n.Prealloc).(*Name)
+	}
+}
+
+func (n *CommClause) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *CommClause) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.Body = copyNodes(c.Body)
+	return &c
+}
+func (n *CommClause) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Comm != nil && do(n.Comm) {
+		return true
+	}
+	if doNodes(n.Body, do) {
+		return true
+	}
+	return false
+}
+func (n *CommClause) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Comm != nil {
+		n.Comm = edit(n.Comm).(Node)
+	}
+	editNodes(n.Body, edit)
+}
+
+func (n *CompLitExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *CompLitExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.List = copyNodes(c.List)
+	return &c
+}
+func (n *CompLitExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Ntype != nil && do(n.Ntype) {
+		return true
+	}
+	if doNodes(n.List, do) {
+		return true
+	}
+	if n.Prealloc != nil && do(n.Prealloc) {
+		return true
+	}
+	return false
+}
+func (n *CompLitExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Ntype != nil {
+		n.Ntype = edit(n.Ntype).(Ntype)
+	}
+	editNodes(n.List, edit)
+	if n.Prealloc != nil {
+		n.Prealloc = edit(n.Prealloc).(*Name)
+	}
+}
+
+func (n *ConstExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *ConstExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *ConstExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	return false
+}
+func (n *ConstExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
+
+func (n *ConvExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *ConvExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *ConvExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	return false
+}
+func (n *ConvExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+}
+
+func (n *Decl) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *Decl) copy() Node {
+	c := *n
+	return &c
+}
+func (n *Decl) doChildren(do func(Node) bool) bool {
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	return false
+}
+func (n *Decl) editChildren(edit func(Node) Node) {
+	if n.X != nil {
+		n.X = edit(n.X).(*Name)
+	}
+}
+
+func (n *ForStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *ForStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.Late = copyNodes(c.Late)
+	c.Body = copyNodes(c.Body)
+	return &c
+}
+func (n *ForStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Cond != nil && do(n.Cond) {
+		return true
+	}
+	if doNodes(n.Late, do) {
+		return true
+	}
+	if n.Post != nil && do(n.Post) {
+		return true
+	}
+	if doNodes(n.Body, do) {
+		return true
+	}
+	return false
+}
+func (n *ForStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Cond != nil {
+		n.Cond = edit(n.Cond).(Node)
+	}
+	editNodes(n.Late, edit)
+	if n.Post != nil {
+		n.Post = edit(n.Post).(Node)
+	}
+	editNodes(n.Body, edit)
+}
+
+func (n *Func) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+
+func (n *FuncType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *FuncType) copy() Node {
+	c := *n
+	c.Recv = copyField(c.Recv)
+	c.Params = copyFields(c.Params)
+	c.Results = copyFields(c.Results)
+	return &c
+}
+func (n *FuncType) doChildren(do func(Node) bool) bool {
+	if doField(n.Recv, do) {
+		return true
+	}
+	if doFields(n.Params, do) {
+		return true
+	}
+	if doFields(n.Results, do) {
+		return true
+	}
+	return false
+}
+func (n *FuncType) editChildren(edit func(Node) Node) {
+	editField(n.Recv, edit)
+	editFields(n.Params, edit)
+	editFields(n.Results, edit)
+}
+
+func (n *GoDeferStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *GoDeferStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *GoDeferStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Call != nil && do(n.Call) {
+		return true
+	}
+	return false
+}
+func (n *GoDeferStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Call != nil {
+		n.Call = edit(n.Call).(Node)
+	}
+}
+
+func (n *Ident) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *Ident) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *Ident) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	return false
+}
+func (n *Ident) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
+
+func (n *IfStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *IfStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.Body = copyNodes(c.Body)
+	c.Else = copyNodes(c.Else)
+	return &c
+}
+func (n *IfStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Cond != nil && do(n.Cond) {
+		return true
+	}
+	if doNodes(n.Body, do) {
+		return true
+	}
+	if doNodes(n.Else, do) {
+		return true
+	}
+	return false
+}
+func (n *IfStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Cond != nil {
+		n.Cond = edit(n.Cond).(Node)
+	}
+	editNodes(n.Body, edit)
+	editNodes(n.Else, edit)
+}
+
+func (n *IndexExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *IndexExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *IndexExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	if n.Index != nil && do(n.Index) {
+		return true
+	}
+	return false
+}
+func (n *IndexExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Index != nil {
+		n.Index = edit(n.Index).(Node)
+	}
+}
+
+func (n *InlineMarkStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *InlineMarkStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *InlineMarkStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	return false
+}
+func (n *InlineMarkStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
+
+func (n *InlinedCallExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *InlinedCallExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.Body = copyNodes(c.Body)
+	c.ReturnVars = copyNodes(c.ReturnVars)
+	return &c
+}
+func (n *InlinedCallExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if doNodes(n.Body, do) {
+		return true
+	}
+	if doNodes(n.ReturnVars, do) {
+		return true
+	}
+	return false
+}
+func (n *InlinedCallExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editNodes(n.Body, edit)
+	editNodes(n.ReturnVars, edit)
+}
+
+func (n *InstExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *InstExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.Targs = copyNodes(c.Targs)
+	return &c
+}
+func (n *InstExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	if doNodes(n.Targs, do) {
+		return true
+	}
+	return false
+}
+func (n *InstExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	editNodes(n.Targs, edit)
+}
+
+func (n *InterfaceType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *InterfaceType) copy() Node {
+	c := *n
+	c.Methods = copyFields(c.Methods)
+	return &c
+}
+func (n *InterfaceType) doChildren(do func(Node) bool) bool {
+	if doFields(n.Methods, do) {
+		return true
+	}
+	return false
+}
+func (n *InterfaceType) editChildren(edit func(Node) Node) {
+	editFields(n.Methods, edit)
+}
+
+func (n *KeyExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *KeyExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *KeyExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Key != nil && do(n.Key) {
+		return true
+	}
+	if n.Value != nil && do(n.Value) {
+		return true
+	}
+	return false
+}
+func (n *KeyExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Key != nil {
+		n.Key = edit(n.Key).(Node)
+	}
+	if n.Value != nil {
+		n.Value = edit(n.Value).(Node)
+	}
+}
+
+func (n *LabelStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *LabelStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *LabelStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	return false
+}
+func (n *LabelStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
+
+func (n *LinksymOffsetExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *LinksymOffsetExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *LinksymOffsetExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	return false
+}
+func (n *LinksymOffsetExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
+
+func (n *LogicalExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *LogicalExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *LogicalExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	if n.Y != nil && do(n.Y) {
+		return true
+	}
+	return false
+}
+func (n *LogicalExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Y != nil {
+		n.Y = edit(n.Y).(Node)
+	}
+}
+
+func (n *MakeExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *MakeExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *MakeExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Len != nil && do(n.Len) {
+		return true
+	}
+	if n.Cap != nil && do(n.Cap) {
+		return true
+	}
+	return false
+}
+func (n *MakeExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Len != nil {
+		n.Len = edit(n.Len).(Node)
+	}
+	if n.Cap != nil {
+		n.Cap = edit(n.Cap).(Node)
+	}
+}
+
+func (n *MapType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *MapType) copy() Node {
+	c := *n
+	return &c
+}
+func (n *MapType) doChildren(do func(Node) bool) bool {
+	if n.Key != nil && do(n.Key) {
+		return true
+	}
+	if n.Elem != nil && do(n.Elem) {
+		return true
+	}
+	return false
+}
+func (n *MapType) editChildren(edit func(Node) Node) {
+	if n.Key != nil {
+		n.Key = edit(n.Key).(Ntype)
+	}
+	if n.Elem != nil {
+		n.Elem = edit(n.Elem).(Ntype)
+	}
+}
+
+func (n *Name) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+
+func (n *NilExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *NilExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *NilExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	return false
+}
+func (n *NilExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
+
+func (n *ParenExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *ParenExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *ParenExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	return false
+}
+func (n *ParenExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+}
+
+func (n *PkgName) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *PkgName) copy() Node {
+	c := *n
+	return &c
+}
+func (n *PkgName) doChildren(do func(Node) bool) bool {
+	return false
+}
+func (n *PkgName) editChildren(edit func(Node) Node) {
+}
+
+func (n *RangeStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *RangeStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.Body = copyNodes(c.Body)
+	return &c
+}
+func (n *RangeStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	if n.Key != nil && do(n.Key) {
+		return true
+	}
+	if n.Value != nil && do(n.Value) {
+		return true
+	}
+	if doNodes(n.Body, do) {
+		return true
+	}
+	if n.Prealloc != nil && do(n.Prealloc) {
+		return true
+	}
+	return false
+}
+func (n *RangeStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Key != nil {
+		n.Key = edit(n.Key).(Node)
+	}
+	if n.Value != nil {
+		n.Value = edit(n.Value).(Node)
+	}
+	editNodes(n.Body, edit)
+	if n.Prealloc != nil {
+		n.Prealloc = edit(n.Prealloc).(*Name)
+	}
+}
+
+func (n *ResultExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *ResultExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *ResultExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	return false
+}
+func (n *ResultExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
+
+func (n *ReturnStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *ReturnStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.Results = copyNodes(c.Results)
+	return &c
+}
+func (n *ReturnStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if doNodes(n.Results, do) {
+		return true
+	}
+	return false
+}
+func (n *ReturnStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editNodes(n.Results, edit)
+}
+
+func (n *SelectStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *SelectStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.Cases = copyCommClauses(c.Cases)
+	c.Compiled = copyNodes(c.Compiled)
+	return &c
+}
+func (n *SelectStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if doCommClauses(n.Cases, do) {
+		return true
+	}
+	if doNodes(n.Compiled, do) {
+		return true
+	}
+	return false
+}
+func (n *SelectStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editCommClauses(n.Cases, edit)
+	editNodes(n.Compiled, edit)
+}
+
+func (n *SelectorExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *SelectorExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *SelectorExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	if n.Prealloc != nil && do(n.Prealloc) {
+		return true
+	}
+	return false
+}
+func (n *SelectorExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Prealloc != nil {
+		n.Prealloc = edit(n.Prealloc).(*Name)
+	}
+}
+
+func (n *SendStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *SendStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *SendStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Chan != nil && do(n.Chan) {
+		return true
+	}
+	if n.Value != nil && do(n.Value) {
+		return true
+	}
+	return false
+}
+func (n *SendStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Chan != nil {
+		n.Chan = edit(n.Chan).(Node)
+	}
+	if n.Value != nil {
+		n.Value = edit(n.Value).(Node)
+	}
+}
+
+func (n *SliceExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *SliceExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *SliceExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	if n.Low != nil && do(n.Low) {
+		return true
+	}
+	if n.High != nil && do(n.High) {
+		return true
+	}
+	if n.Max != nil && do(n.Max) {
+		return true
+	}
+	return false
+}
+func (n *SliceExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Low != nil {
+		n.Low = edit(n.Low).(Node)
+	}
+	if n.High != nil {
+		n.High = edit(n.High).(Node)
+	}
+	if n.Max != nil {
+		n.Max = edit(n.Max).(Node)
+	}
+}
+
+func (n *SliceHeaderExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *SliceHeaderExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *SliceHeaderExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Ptr != nil && do(n.Ptr) {
+		return true
+	}
+	if n.Len != nil && do(n.Len) {
+		return true
+	}
+	if n.Cap != nil && do(n.Cap) {
+		return true
+	}
+	return false
+}
+func (n *SliceHeaderExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Ptr != nil {
+		n.Ptr = edit(n.Ptr).(Node)
+	}
+	if n.Len != nil {
+		n.Len = edit(n.Len).(Node)
+	}
+	if n.Cap != nil {
+		n.Cap = edit(n.Cap).(Node)
+	}
+}
+
+func (n *SliceType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *SliceType) copy() Node {
+	c := *n
+	return &c
+}
+func (n *SliceType) doChildren(do func(Node) bool) bool {
+	if n.Elem != nil && do(n.Elem) {
+		return true
+	}
+	return false
+}
+func (n *SliceType) editChildren(edit func(Node) Node) {
+	if n.Elem != nil {
+		n.Elem = edit(n.Elem).(Ntype)
+	}
+}
+
+func (n *StarExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *StarExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *StarExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	return false
+}
+func (n *StarExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+}
+
+func (n *StructKeyExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *StructKeyExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *StructKeyExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Value != nil && do(n.Value) {
+		return true
+	}
+	return false
+}
+func (n *StructKeyExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Value != nil {
+		n.Value = edit(n.Value).(Node)
+	}
+}
+
+func (n *StructType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *StructType) copy() Node {
+	c := *n
+	c.Fields = copyFields(c.Fields)
+	return &c
+}
+func (n *StructType) doChildren(do func(Node) bool) bool {
+	if doFields(n.Fields, do) {
+		return true
+	}
+	return false
+}
+func (n *StructType) editChildren(edit func(Node) Node) {
+	editFields(n.Fields, edit)
+}
+
+func (n *SwitchStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *SwitchStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	c.Cases = copyCaseClauses(c.Cases)
+	c.Compiled = copyNodes(c.Compiled)
+	return &c
+}
+func (n *SwitchStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Tag != nil && do(n.Tag) {
+		return true
+	}
+	if doCaseClauses(n.Cases, do) {
+		return true
+	}
+	if doNodes(n.Compiled, do) {
+		return true
+	}
+	return false
+}
+func (n *SwitchStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Tag != nil {
+		n.Tag = edit(n.Tag).(Node)
+	}
+	editCaseClauses(n.Cases, edit)
+	editNodes(n.Compiled, edit)
+}
+
+func (n *TailCallStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *TailCallStmt) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *TailCallStmt) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Target != nil && do(n.Target) {
+		return true
+	}
+	return false
+}
+func (n *TailCallStmt) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Target != nil {
+		n.Target = edit(n.Target).(*Name)
+	}
+}
+
+func (n *TypeAssertExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *TypeAssertExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *TypeAssertExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	if n.Ntype != nil && do(n.Ntype) {
+		return true
+	}
+	return false
+}
+func (n *TypeAssertExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Ntype != nil {
+		n.Ntype = edit(n.Ntype).(Ntype)
+	}
+}
+
+func (n *TypeSwitchGuard) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *TypeSwitchGuard) copy() Node {
+	c := *n
+	return &c
+}
+func (n *TypeSwitchGuard) doChildren(do func(Node) bool) bool {
+	if n.Tag != nil && do(n.Tag) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	return false
+}
+func (n *TypeSwitchGuard) editChildren(edit func(Node) Node) {
+	if n.Tag != nil {
+		n.Tag = edit(n.Tag).(*Ident)
+	}
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+}
+
+func (n *UnaryExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *UnaryExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *UnaryExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.X != nil && do(n.X) {
+		return true
+	}
+	return false
+}
+func (n *UnaryExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+}
+
+func (n *typeNode) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *typeNode) copy() Node {
+	c := *n
+	return &c
+}
+func (n *typeNode) doChildren(do func(Node) bool) bool {
+	return false
+}
+func (n *typeNode) editChildren(edit func(Node) Node) {
+}
+
+func copyCaseClauses(list []*CaseClause) []*CaseClause {
+	if list == nil {
+		return nil
+	}
+	c := make([]*CaseClause, len(list))
+	copy(c, list)
+	return c
+}
+func doCaseClauses(list []*CaseClause, do func(Node) bool) bool {
+	for _, x := range list {
+		if x != nil && do(x) {
+			return true
+		}
+	}
+	return false
+}
+func editCaseClauses(list []*CaseClause, edit func(Node) Node) {
+	for i, x := range list {
+		if x != nil {
+			list[i] = edit(x).(*CaseClause)
+		}
+	}
+}
+
+func copyCommClauses(list []*CommClause) []*CommClause {
+	if list == nil {
+		return nil
+	}
+	c := make([]*CommClause, len(list))
+	copy(c, list)
+	return c
+}
+func doCommClauses(list []*CommClause, do func(Node) bool) bool {
+	for _, x := range list {
+		if x != nil && do(x) {
+			return true
+		}
+	}
+	return false
+}
+func editCommClauses(list []*CommClause, edit func(Node) Node) {
+	for i, x := range list {
+		if x != nil {
+			list[i] = edit(x).(*CommClause)
+		}
+	}
+}
+
+func copyNames(list []*Name) []*Name {
+	if list == nil {
+		return nil
+	}
+	c := make([]*Name, len(list))
+	copy(c, list)
+	return c
+}
+func doNames(list []*Name, do func(Node) bool) bool {
+	for _, x := range list {
+		if x != nil && do(x) {
+			return true
+		}
+	}
+	return false
+}
+func editNames(list []*Name, edit func(Node) Node) {
+	for i, x := range list {
+		if x != nil {
+			list[i] = edit(x).(*Name)
+		}
+	}
+}
+
+func copyNodes(list []Node) []Node {
+	if list == nil {
+		return nil
+	}
+	c := make([]Node, len(list))
+	copy(c, list)
+	return c
+}
+func doNodes(list []Node, do func(Node) bool) bool {
+	for _, x := range list {
+		if x != nil && do(x) {
+			return true
+		}
+	}
+	return false
+}
+func editNodes(list []Node, edit func(Node) Node) {
+	for i, x := range list {
+		if x != nil {
+			list[i] = edit(x).(Node)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/ir/op_string.go b/src/cmd/compile/internal/ir/op_string.go
new file mode 100644
index 0000000..405a0c6
--- /dev/null
+++ b/src/cmd/compile/internal/ir/op_string.go
@@ -0,0 +1,177 @@
+// Code generated by "stringer -type=Op -trimprefix=O node.go"; DO NOT EDIT.
+
+package ir
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[OXXX-0]
+	_ = x[ONAME-1]
+	_ = x[ONONAME-2]
+	_ = x[OTYPE-3]
+	_ = x[OPACK-4]
+	_ = x[OLITERAL-5]
+	_ = x[ONIL-6]
+	_ = x[OADD-7]
+	_ = x[OSUB-8]
+	_ = x[OOR-9]
+	_ = x[OXOR-10]
+	_ = x[OADDSTR-11]
+	_ = x[OADDR-12]
+	_ = x[OANDAND-13]
+	_ = x[OAPPEND-14]
+	_ = x[OBYTES2STR-15]
+	_ = x[OBYTES2STRTMP-16]
+	_ = x[ORUNES2STR-17]
+	_ = x[OSTR2BYTES-18]
+	_ = x[OSTR2BYTESTMP-19]
+	_ = x[OSTR2RUNES-20]
+	_ = x[OSLICE2ARRPTR-21]
+	_ = x[OAS-22]
+	_ = x[OAS2-23]
+	_ = x[OAS2DOTTYPE-24]
+	_ = x[OAS2FUNC-25]
+	_ = x[OAS2MAPR-26]
+	_ = x[OAS2RECV-27]
+	_ = x[OASOP-28]
+	_ = x[OCALL-29]
+	_ = x[OCALLFUNC-30]
+	_ = x[OCALLMETH-31]
+	_ = x[OCALLINTER-32]
+	_ = x[OCALLPART-33]
+	_ = x[OCAP-34]
+	_ = x[OCLOSE-35]
+	_ = x[OCLOSURE-36]
+	_ = x[OCOMPLIT-37]
+	_ = x[OMAPLIT-38]
+	_ = x[OSTRUCTLIT-39]
+	_ = x[OARRAYLIT-40]
+	_ = x[OSLICELIT-41]
+	_ = x[OPTRLIT-42]
+	_ = x[OCONV-43]
+	_ = x[OCONVIFACE-44]
+	_ = x[OCONVNOP-45]
+	_ = x[OCOPY-46]
+	_ = x[ODCL-47]
+	_ = x[ODCLFUNC-48]
+	_ = x[ODCLCONST-49]
+	_ = x[ODCLTYPE-50]
+	_ = x[ODELETE-51]
+	_ = x[ODOT-52]
+	_ = x[ODOTPTR-53]
+	_ = x[ODOTMETH-54]
+	_ = x[ODOTINTER-55]
+	_ = x[OXDOT-56]
+	_ = x[ODOTTYPE-57]
+	_ = x[ODOTTYPE2-58]
+	_ = x[OEQ-59]
+	_ = x[ONE-60]
+	_ = x[OLT-61]
+	_ = x[OLE-62]
+	_ = x[OGE-63]
+	_ = x[OGT-64]
+	_ = x[ODEREF-65]
+	_ = x[OINDEX-66]
+	_ = x[OINDEXMAP-67]
+	_ = x[OKEY-68]
+	_ = x[OSTRUCTKEY-69]
+	_ = x[OLEN-70]
+	_ = x[OMAKE-71]
+	_ = x[OMAKECHAN-72]
+	_ = x[OMAKEMAP-73]
+	_ = x[OMAKESLICE-74]
+	_ = x[OMAKESLICECOPY-75]
+	_ = x[OMUL-76]
+	_ = x[ODIV-77]
+	_ = x[OMOD-78]
+	_ = x[OLSH-79]
+	_ = x[ORSH-80]
+	_ = x[OAND-81]
+	_ = x[OANDNOT-82]
+	_ = x[ONEW-83]
+	_ = x[ONOT-84]
+	_ = x[OBITNOT-85]
+	_ = x[OPLUS-86]
+	_ = x[ONEG-87]
+	_ = x[OOROR-88]
+	_ = x[OPANIC-89]
+	_ = x[OPRINT-90]
+	_ = x[OPRINTN-91]
+	_ = x[OPAREN-92]
+	_ = x[OSEND-93]
+	_ = x[OSLICE-94]
+	_ = x[OSLICEARR-95]
+	_ = x[OSLICESTR-96]
+	_ = x[OSLICE3-97]
+	_ = x[OSLICE3ARR-98]
+	_ = x[OSLICEHEADER-99]
+	_ = x[ORECOVER-100]
+	_ = x[ORECV-101]
+	_ = x[ORUNESTR-102]
+	_ = x[OSELRECV2-103]
+	_ = x[OIOTA-104]
+	_ = x[OREAL-105]
+	_ = x[OIMAG-106]
+	_ = x[OCOMPLEX-107]
+	_ = x[OALIGNOF-108]
+	_ = x[OOFFSETOF-109]
+	_ = x[OSIZEOF-110]
+	_ = x[OUNSAFEADD-111]
+	_ = x[OUNSAFESLICE-112]
+	_ = x[OMETHEXPR-113]
+	_ = x[OBLOCK-114]
+	_ = x[OBREAK-115]
+	_ = x[OCASE-116]
+	_ = x[OCONTINUE-117]
+	_ = x[ODEFER-118]
+	_ = x[OFALL-119]
+	_ = x[OFOR-120]
+	_ = x[OFORUNTIL-121]
+	_ = x[OGOTO-122]
+	_ = x[OIF-123]
+	_ = x[OLABEL-124]
+	_ = x[OGO-125]
+	_ = x[ORANGE-126]
+	_ = x[ORETURN-127]
+	_ = x[OSELECT-128]
+	_ = x[OSWITCH-129]
+	_ = x[OTYPESW-130]
+	_ = x[OFUNCINST-131]
+	_ = x[OTCHAN-132]
+	_ = x[OTMAP-133]
+	_ = x[OTSTRUCT-134]
+	_ = x[OTINTER-135]
+	_ = x[OTFUNC-136]
+	_ = x[OTARRAY-137]
+	_ = x[OTSLICE-138]
+	_ = x[OINLCALL-139]
+	_ = x[OEFACE-140]
+	_ = x[OITAB-141]
+	_ = x[OIDATA-142]
+	_ = x[OSPTR-143]
+	_ = x[OCFUNC-144]
+	_ = x[OCHECKNIL-145]
+	_ = x[OVARDEF-146]
+	_ = x[OVARKILL-147]
+	_ = x[OVARLIVE-148]
+	_ = x[ORESULT-149]
+	_ = x[OINLMARK-150]
+	_ = x[OLINKSYMOFFSET-151]
+	_ = x[OTAILCALL-152]
+	_ = x[OGETG-153]
+	_ = x[OEND-154]
+}
+
+const _Op_name = "XXXNAMENONAMETYPEPACKLITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESSLICE2ARRPTRASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECVRUNESTRSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFUNSAFEADDUNSAFESLICEMETHEXPRBLOCKBREAKCASECONTINUEDEFERFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWFUNCINSTTCHANTMAPTSTRUCTTINTERTFUNCTARRAYTSLICEINLCALLEFACEITABIDATASPTRCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKLINKSYMOFFSETTAILCALLGETGEND"
+
+var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 37, 39, 42, 48, 52, 58, 64, 73, 85, 94, 103, 115, 124, 136, 138, 141, 151, 158, 165, 172, 176, 180, 188, 196, 205, 213, 216, 221, 228, 235, 241, 250, 258, 266, 272, 276, 285, 292, 296, 299, 306, 314, 321, 327, 330, 336, 343, 351, 355, 362, 370, 372, 374, 376, 378, 380, 382, 387, 392, 400, 403, 412, 415, 419, 427, 434, 443, 456, 459, 462, 465, 468, 471, 474, 480, 483, 486, 492, 496, 499, 503, 508, 513, 519, 524, 528, 533, 541, 549, 555, 564, 575, 582, 586, 593, 601, 605, 609, 613, 620, 627, 635, 641, 650, 661, 669, 674, 679, 683, 691, 696, 700, 703, 711, 715, 717, 722, 724, 729, 735, 741, 747, 753, 761, 766, 770, 777, 783, 788, 794, 800, 807, 812, 816, 821, 825, 830, 838, 844, 851, 858, 864, 871, 884, 892, 896, 899}
+
+func (i Op) String() string {
+	if i >= Op(len(_Op_index)-1) {
+		return "Op(" + strconv.FormatInt(int64(i), 10) + ")"
+	}
+	return _Op_name[_Op_index[i]:_Op_index[i+1]]
+}
diff --git a/src/cmd/compile/internal/ir/package.go b/src/cmd/compile/internal/ir/package.go
new file mode 100644
index 0000000..e4b93d1
--- /dev/null
+++ b/src/cmd/compile/internal/ir/package.go
@@ -0,0 +1,38 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import "cmd/compile/internal/types"
+
+// A Package holds information about the package being compiled.
+type Package struct {
+	// Imports, listed in source order.
+	// See golang.org/issue/31636.
+	Imports []*types.Pkg
+
+	// Init functions, listed in source order.
+	Inits []*Func
+
+	// Top-level declarations.
+	Decls []Node
+
+	// Extern (package global) declarations.
+	Externs []Node
+
+	// Assembly function declarations.
+	Asms []*Name
+
+	// Cgo directives.
+	CgoPragmas [][]string
+
+	// Variables with //go:embed lines.
+	Embeds []*Name
+
+	// Exported (or re-exported) symbols.
+	Exports []*Name
+
+	// Map from function names of stencils to already-created stencils.
+	Stencils map[*types.Sym]*Func
+}
diff --git a/src/cmd/compile/internal/ir/scc.go b/src/cmd/compile/internal/ir/scc.go
new file mode 100644
index 0000000..83c6074
--- /dev/null
+++ b/src/cmd/compile/internal/ir/scc.go
@@ -0,0 +1,132 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// Strongly connected components.
+//
+// Run analysis on minimal sets of mutually recursive functions
+// or single non-recursive functions, bottom up.
+//
+// Finding these sets is finding strongly connected components
+// by reverse topological order in the static call graph.
+// The algorithm (known as Tarjan's algorithm) for doing that is taken from
+// Sedgewick, Algorithms, Second Edition, p. 482, with two adaptations.
+//
+// First, a hidden closure function (n.Func.IsHiddenClosure()) cannot be the
+// root of a connected component. Refusing to use it as a root
+// forces it into the component of the function in which it appears.
+// This is more convenient for escape analysis.
+//
+// Second, each function becomes two virtual nodes in the graph,
+// with numbers n and n+1. We record the function's node number as n
+// but search from node n+1. If the search tells us that the component
+// number (min) is n+1, we know that this is a trivial component: one function
+// plus its closures. If the search tells us that the component number is
+// n, then there was a path from node n+1 back to node n, meaning that
+// the function set is mutually recursive. The escape analysis can be
+// more precise when analyzing a single non-recursive function than
+// when analyzing a set of mutually recursive functions.
+
+type bottomUpVisitor struct {
+	analyze  func([]*Func, bool)
+	visitgen uint32
+	nodeID   map[*Func]uint32
+	stack    []*Func
+}
+
+// VisitFuncsBottomUp invokes analyze on the ODCLFUNC nodes listed in list.
+// It calls analyze with successive groups of functions, working from
+// the bottom of the call graph upward. Each time analyze is called with
+// a list of functions, every function on that list only calls other functions
+// on the list or functions that have been passed in previous invocations of
+// analyze. Closures appear in the same list as their outer functions.
+// The lists are as short as possible while preserving those requirements.
+// (In a typical program, many invocations of analyze will be passed just
+// a single function.) The boolean argument 'recursive' passed to analyze
+// specifies whether the functions on the list are mutually recursive.
+// If recursive is false, the list consists of only a single function and its closures.
+// If recursive is true, the list may still contain only a single function,
+// if that function is itself recursive.
+func VisitFuncsBottomUp(list []Node, analyze func(list []*Func, recursive bool)) {
+	var v bottomUpVisitor
+	v.analyze = analyze
+	v.nodeID = make(map[*Func]uint32)
+	for _, n := range list {
+		if n.Op() == ODCLFUNC {
+			n := n.(*Func)
+			if !n.IsHiddenClosure() {
+				v.visit(n)
+			}
+		}
+	}
+}
+
+func (v *bottomUpVisitor) visit(n *Func) uint32 {
+	if id := v.nodeID[n]; id > 0 {
+		// already visited
+		return id
+	}
+
+	v.visitgen++
+	id := v.visitgen
+	v.nodeID[n] = id
+	v.visitgen++
+	min := v.visitgen
+	v.stack = append(v.stack, n)
+
+	do := func(defn Node) {
+		if defn != nil {
+			if m := v.visit(defn.(*Func)); m < min {
+				min = m
+			}
+		}
+	}
+
+	Visit(n, func(n Node) {
+		switch n.Op() {
+		case ONAME:
+			if n := n.(*Name); n.Class == PFUNC {
+				do(n.Defn)
+			}
+		case ODOTMETH, OCALLPART, OMETHEXPR:
+			if fn := MethodExprName(n); fn != nil {
+				do(fn.Defn)
+			}
+		case OCLOSURE:
+			n := n.(*ClosureExpr)
+			do(n.Func)
+		}
+	})
+
+	if (min == id || min == id+1) && !n.IsHiddenClosure() {
+		// This node is the root of a strongly connected component.
+
+		// The original min passed to visitcodelist was v.nodeID[n]+1.
+		// If visitcodelist found its way back to v.nodeID[n], then this
+		// block is a set of mutually recursive functions.
+		// Otherwise it's just a lone function that does not recurse.
+		recursive := min == id
+
+		// Remove connected component from stack.
+		// Mark walkgen so that future visits return a large number
+		// so as not to affect the caller's min.
+
+		var i int
+		for i = len(v.stack) - 1; i >= 0; i-- {
+			x := v.stack[i]
+			if x == n {
+				break
+			}
+			v.nodeID[x] = ^uint32(0)
+		}
+		v.nodeID[n] = ^uint32(0)
+		block := v.stack[i:]
+		// Run escape analysis on this set of functions.
+		v.stack = v.stack[:i]
+		v.analyze(block, recursive)
+	}
+
+	return min
+}
diff --git a/src/cmd/compile/internal/ir/sizeof_test.go b/src/cmd/compile/internal/ir/sizeof_test.go
new file mode 100644
index 0000000..a4421fc
--- /dev/null
+++ b/src/cmd/compile/internal/ir/sizeof_test.go
@@ -0,0 +1,37 @@
+// 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 ir
+
+import (
+	"reflect"
+	"testing"
+	"unsafe"
+)
+
+// Assert that the size of important structures do not change unexpectedly.
+
+func TestSizeof(t *testing.T) {
+	const _64bit = unsafe.Sizeof(uintptr(0)) == 8
+
+	var tests = []struct {
+		val    interface{} // type as a value
+		_32bit uintptr     // size on 32bit platforms
+		_64bit uintptr     // size on 64bit platforms
+	}{
+		{Func{}, 192, 328},
+		{Name{}, 112, 200},
+	}
+
+	for _, tt := range tests {
+		want := tt._32bit
+		if _64bit {
+			want = tt._64bit
+		}
+		got := reflect.TypeOf(tt.val).Size()
+		if want != got {
+			t.Errorf("unsafe.Sizeof(%T) = %d, want %d", tt.val, got, want)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/ir/stmt.go b/src/cmd/compile/internal/ir/stmt.go
new file mode 100644
index 0000000..8115012
--- /dev/null
+++ b/src/cmd/compile/internal/ir/stmt.go
@@ -0,0 +1,414 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// A Decl is a declaration of a const, type, or var. (A declared func is a Func.)
+type Decl struct {
+	miniNode
+	X *Name // the thing being declared
+}
+
+func NewDecl(pos src.XPos, op Op, x *Name) *Decl {
+	n := &Decl{X: x}
+	n.pos = pos
+	switch op {
+	default:
+		panic("invalid Decl op " + op.String())
+	case ODCL, ODCLCONST, ODCLTYPE:
+		n.op = op
+	}
+	return n
+}
+
+func (*Decl) isStmt() {}
+
+// A Stmt is a Node that can appear as a statement.
+// This includes statement-like expressions such as f().
+//
+// (It's possible it should include <-c, but that would require
+// splitting ORECV out of UnaryExpr, which hasn't yet been
+// necessary. Maybe instead we will introduce ExprStmt at
+// some point.)
+type Stmt interface {
+	Node
+	isStmt()
+}
+
+// A miniStmt is a miniNode with extra fields common to statements.
+type miniStmt struct {
+	miniNode
+	init Nodes
+}
+
+func (*miniStmt) isStmt() {}
+
+func (n *miniStmt) Init() Nodes     { return n.init }
+func (n *miniStmt) SetInit(x Nodes) { n.init = x }
+func (n *miniStmt) PtrInit() *Nodes { return &n.init }
+
+// An AssignListStmt is an assignment statement with
+// more than one item on at least one side: Lhs = Rhs.
+// If Def is true, the assignment is a :=.
+type AssignListStmt struct {
+	miniStmt
+	Lhs Nodes
+	Def bool
+	Rhs Nodes
+}
+
+func NewAssignListStmt(pos src.XPos, op Op, lhs, rhs []Node) *AssignListStmt {
+	n := &AssignListStmt{}
+	n.pos = pos
+	n.SetOp(op)
+	n.Lhs = lhs
+	n.Rhs = rhs
+	return n
+}
+
+func (n *AssignListStmt) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OAS2, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV, OSELRECV2:
+		n.op = op
+	}
+}
+
+// An AssignStmt is a simple assignment statement: X = Y.
+// If Def is true, the assignment is a :=.
+type AssignStmt struct {
+	miniStmt
+	X   Node
+	Def bool
+	Y   Node
+}
+
+func NewAssignStmt(pos src.XPos, x, y Node) *AssignStmt {
+	n := &AssignStmt{X: x, Y: y}
+	n.pos = pos
+	n.op = OAS
+	return n
+}
+
+func (n *AssignStmt) SetOp(op Op) {
+	switch op {
+	default:
+		panic(n.no("SetOp " + op.String()))
+	case OAS:
+		n.op = op
+	}
+}
+
+// An AssignOpStmt is an AsOp= assignment statement: X AsOp= Y.
+type AssignOpStmt struct {
+	miniStmt
+	X      Node
+	AsOp   Op // OADD etc
+	Y      Node
+	IncDec bool // actually ++ or --
+}
+
+func NewAssignOpStmt(pos src.XPos, asOp Op, x, y Node) *AssignOpStmt {
+	n := &AssignOpStmt{AsOp: asOp, X: x, Y: y}
+	n.pos = pos
+	n.op = OASOP
+	return n
+}
+
+// A BlockStmt is a block: { List }.
+type BlockStmt struct {
+	miniStmt
+	List Nodes
+}
+
+func NewBlockStmt(pos src.XPos, list []Node) *BlockStmt {
+	n := &BlockStmt{}
+	n.pos = pos
+	if !pos.IsKnown() {
+		n.pos = base.Pos
+		if len(list) > 0 {
+			n.pos = list[0].Pos()
+		}
+	}
+	n.op = OBLOCK
+	n.List = list
+	return n
+}
+
+// A BranchStmt is a break, continue, fallthrough, or goto statement.
+type BranchStmt struct {
+	miniStmt
+	Label *types.Sym // label if present
+}
+
+func NewBranchStmt(pos src.XPos, op Op, label *types.Sym) *BranchStmt {
+	switch op {
+	case OBREAK, OCONTINUE, OFALL, OGOTO:
+		// ok
+	default:
+		panic("NewBranch " + op.String())
+	}
+	n := &BranchStmt{Label: label}
+	n.pos = pos
+	n.op = op
+	return n
+}
+
+func (n *BranchStmt) Sym() *types.Sym { return n.Label }
+
+// A CaseClause is a case statement in a switch or select: case List: Body.
+type CaseClause struct {
+	miniStmt
+	Var  *Name // declared variable for this case in type switch
+	List Nodes // list of expressions for switch, early select
+	Body Nodes
+}
+
+func NewCaseStmt(pos src.XPos, list, body []Node) *CaseClause {
+	n := &CaseClause{List: list, Body: body}
+	n.pos = pos
+	n.op = OCASE
+	return n
+}
+
+type CommClause struct {
+	miniStmt
+	Comm Node // communication case
+	Body Nodes
+}
+
+func NewCommStmt(pos src.XPos, comm Node, body []Node) *CommClause {
+	n := &CommClause{Comm: comm, Body: body}
+	n.pos = pos
+	n.op = OCASE
+	return n
+}
+
+// A ForStmt is a non-range for loop: for Init; Cond; Post { Body }
+// Op can be OFOR or OFORUNTIL (!Cond).
+type ForStmt struct {
+	miniStmt
+	Label    *types.Sym
+	Cond     Node
+	Late     Nodes
+	Post     Node
+	Body     Nodes
+	HasBreak bool
+}
+
+func NewForStmt(pos src.XPos, init Node, cond, post Node, body []Node) *ForStmt {
+	n := &ForStmt{Cond: cond, Post: post}
+	n.pos = pos
+	n.op = OFOR
+	if init != nil {
+		n.init = []Node{init}
+	}
+	n.Body = body
+	return n
+}
+
+func (n *ForStmt) SetOp(op Op) {
+	if op != OFOR && op != OFORUNTIL {
+		panic(n.no("SetOp " + op.String()))
+	}
+	n.op = op
+}
+
+// A GoDeferStmt is a go or defer statement: go Call / defer Call.
+//
+// The two opcodes use a single syntax because the implementations
+// are very similar: both are concerned with saving Call and running it
+// in a different context (a separate goroutine or a later time).
+type GoDeferStmt struct {
+	miniStmt
+	Call Node
+}
+
+func NewGoDeferStmt(pos src.XPos, op Op, call Node) *GoDeferStmt {
+	n := &GoDeferStmt{Call: call}
+	n.pos = pos
+	switch op {
+	case ODEFER, OGO:
+		n.op = op
+	default:
+		panic("NewGoDeferStmt " + op.String())
+	}
+	return n
+}
+
+// A IfStmt is a return statement: if Init; Cond { Then } else { Else }.
+type IfStmt struct {
+	miniStmt
+	Cond   Node
+	Body   Nodes
+	Else   Nodes
+	Likely bool // code layout hint
+}
+
+func NewIfStmt(pos src.XPos, cond Node, body, els []Node) *IfStmt {
+	n := &IfStmt{Cond: cond}
+	n.pos = pos
+	n.op = OIF
+	n.Body = body
+	n.Else = els
+	return n
+}
+
+// An InlineMarkStmt is a marker placed just before an inlined body.
+type InlineMarkStmt struct {
+	miniStmt
+	Index int64
+}
+
+func NewInlineMarkStmt(pos src.XPos, index int64) *InlineMarkStmt {
+	n := &InlineMarkStmt{Index: index}
+	n.pos = pos
+	n.op = OINLMARK
+	return n
+}
+
+func (n *InlineMarkStmt) Offset() int64     { return n.Index }
+func (n *InlineMarkStmt) SetOffset(x int64) { n.Index = x }
+
+// A LabelStmt is a label statement (just the label, not including the statement it labels).
+type LabelStmt struct {
+	miniStmt
+	Label *types.Sym // "Label:"
+}
+
+func NewLabelStmt(pos src.XPos, label *types.Sym) *LabelStmt {
+	n := &LabelStmt{Label: label}
+	n.pos = pos
+	n.op = OLABEL
+	return n
+}
+
+func (n *LabelStmt) Sym() *types.Sym { return n.Label }
+
+// A RangeStmt is a range loop: for Key, Value = range X { Body }
+type RangeStmt struct {
+	miniStmt
+	Label    *types.Sym
+	Def      bool
+	X        Node
+	Key      Node
+	Value    Node
+	Body     Nodes
+	HasBreak bool
+	Prealloc *Name
+}
+
+func NewRangeStmt(pos src.XPos, key, value, x Node, body []Node) *RangeStmt {
+	n := &RangeStmt{X: x, Key: key, Value: value}
+	n.pos = pos
+	n.op = ORANGE
+	n.Body = body
+	return n
+}
+
+// A ReturnStmt is a return statement.
+type ReturnStmt struct {
+	miniStmt
+	origNode       // for typecheckargs rewrite
+	Results  Nodes // return list
+}
+
+func NewReturnStmt(pos src.XPos, results []Node) *ReturnStmt {
+	n := &ReturnStmt{}
+	n.pos = pos
+	n.op = ORETURN
+	n.orig = n
+	n.Results = results
+	return n
+}
+
+// A SelectStmt is a block: { Cases }.
+type SelectStmt struct {
+	miniStmt
+	Label    *types.Sym
+	Cases    []*CommClause
+	HasBreak bool
+
+	// TODO(rsc): Instead of recording here, replace with a block?
+	Compiled Nodes // compiled form, after walkSwitch
+}
+
+func NewSelectStmt(pos src.XPos, cases []*CommClause) *SelectStmt {
+	n := &SelectStmt{Cases: cases}
+	n.pos = pos
+	n.op = OSELECT
+	return n
+}
+
+// A SendStmt is a send statement: X <- Y.
+type SendStmt struct {
+	miniStmt
+	Chan  Node
+	Value Node
+}
+
+func NewSendStmt(pos src.XPos, ch, value Node) *SendStmt {
+	n := &SendStmt{Chan: ch, Value: value}
+	n.pos = pos
+	n.op = OSEND
+	return n
+}
+
+// A SwitchStmt is a switch statement: switch Init; Expr { Cases }.
+type SwitchStmt struct {
+	miniStmt
+	Tag      Node
+	Cases    []*CaseClause
+	Label    *types.Sym
+	HasBreak bool
+
+	// TODO(rsc): Instead of recording here, replace with a block?
+	Compiled Nodes // compiled form, after walkSwitch
+}
+
+func NewSwitchStmt(pos src.XPos, tag Node, cases []*CaseClause) *SwitchStmt {
+	n := &SwitchStmt{Tag: tag, Cases: cases}
+	n.pos = pos
+	n.op = OSWITCH
+	return n
+}
+
+// A TailCallStmt is a tail call statement, which is used for back-end
+// code generation to jump directly to another function entirely.
+type TailCallStmt struct {
+	miniStmt
+	Target *Name
+}
+
+func NewTailCallStmt(pos src.XPos, target *Name) *TailCallStmt {
+	if target.Op() != ONAME || target.Class != PFUNC {
+		base.FatalfAt(pos, "tail call to non-func %v", target)
+	}
+	n := &TailCallStmt{Target: target}
+	n.pos = pos
+	n.op = OTAILCALL
+	return n
+}
+
+// A TypeSwitchGuard is the [Name :=] X.(type) in a type switch.
+type TypeSwitchGuard struct {
+	miniNode
+	Tag  *Ident
+	X    Node
+	Used bool
+}
+
+func NewTypeSwitchGuard(pos src.XPos, tag *Ident, x Node) *TypeSwitchGuard {
+	n := &TypeSwitchGuard{Tag: tag, X: x}
+	n.pos = pos
+	n.op = OTYPESW
+	return n
+}
diff --git a/src/cmd/compile/internal/ir/symtab.go b/src/cmd/compile/internal/ir/symtab.go
new file mode 100644
index 0000000..61727fb
--- /dev/null
+++ b/src/cmd/compile/internal/ir/symtab.go
@@ -0,0 +1,72 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+)
+
+// Syms holds known symbols.
+var Syms struct {
+	AssertE2I       *obj.LSym
+	AssertE2I2      *obj.LSym
+	AssertI2I       *obj.LSym
+	AssertI2I2      *obj.LSym
+	Deferproc       *obj.LSym
+	DeferprocStack  *obj.LSym
+	Deferreturn     *obj.LSym
+	Duffcopy        *obj.LSym
+	Duffzero        *obj.LSym
+	GCWriteBarrier  *obj.LSym
+	Goschedguarded  *obj.LSym
+	Growslice       *obj.LSym
+	Msanread        *obj.LSym
+	Msanwrite       *obj.LSym
+	Msanmove        *obj.LSym
+	Newobject       *obj.LSym
+	Newproc         *obj.LSym
+	Panicdivide     *obj.LSym
+	Panicshift      *obj.LSym
+	PanicdottypeE   *obj.LSym
+	PanicdottypeI   *obj.LSym
+	Panicnildottype *obj.LSym
+	Panicoverflow   *obj.LSym
+	Raceread        *obj.LSym
+	Racereadrange   *obj.LSym
+	Racewrite       *obj.LSym
+	Racewriterange  *obj.LSym
+	// Wasm
+	SigPanic        *obj.LSym
+	Staticuint64s   *obj.LSym
+	Typedmemclr     *obj.LSym
+	Typedmemmove    *obj.LSym
+	Udiv            *obj.LSym
+	WriteBarrier    *obj.LSym
+	Zerobase        *obj.LSym
+	ARM64HasATOMICS *obj.LSym
+	ARMHasVFPv4     *obj.LSym
+	X86HasFMA       *obj.LSym
+	X86HasPOPCNT    *obj.LSym
+	X86HasSSE41     *obj.LSym
+	// Wasm
+	WasmDiv *obj.LSym
+	// Wasm
+	WasmMove *obj.LSym
+	// Wasm
+	WasmZero *obj.LSym
+	// Wasm
+	WasmTruncS *obj.LSym
+	// Wasm
+	WasmTruncU *obj.LSym
+}
+
+// Pkgs holds known packages.
+var Pkgs struct {
+	Go      *types.Pkg
+	Itab    *types.Pkg
+	Runtime *types.Pkg
+	Unsafe  *types.Pkg
+}
diff --git a/src/cmd/compile/internal/ir/type.go b/src/cmd/compile/internal/ir/type.go
new file mode 100644
index 0000000..a903ea8
--- /dev/null
+++ b/src/cmd/compile/internal/ir/type.go
@@ -0,0 +1,310 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+	"fmt"
+)
+
+// Nodes that represent the syntax of a type before type-checking.
+// After type-checking, they serve only as shells around a *types.Type.
+// Calling TypeNode converts a *types.Type to a Node shell.
+
+// An Ntype is a Node that syntactically looks like a type.
+// It can be the raw syntax for a type before typechecking,
+// or it can be an OTYPE with Type() set to a *types.Type.
+// Note that syntax doesn't guarantee it's a type: an expression
+// like *fmt is an Ntype (we don't know whether names are types yet),
+// but at least 1+1 is not an Ntype.
+type Ntype interface {
+	Node
+	CanBeNtype()
+}
+
+// A miniType is a minimal type syntax Node implementation,
+// to be embedded as the first field in a larger node implementation.
+type miniType struct {
+	miniNode
+	typ *types.Type
+}
+
+func (*miniType) CanBeNtype() {}
+
+func (n *miniType) Type() *types.Type { return n.typ }
+
+// setOTYPE changes n to be an OTYPE node returning t.
+// Rewriting the node in place this way should not be strictly
+// necessary (we should be able to update the uses with
+// proper OTYPE nodes), but it's mostly harmless and easy
+// to keep doing for now.
+//
+// setOTYPE also records t.Nod = self if t.Nod is not already set.
+// (Some types are shared by multiple OTYPE nodes, so only
+// the first such node is used as t.Nod.)
+func (n *miniType) setOTYPE(t *types.Type, self Ntype) {
+	if n.typ != nil {
+		panic(n.op.String() + " SetType: type already set")
+	}
+	n.op = OTYPE
+	n.typ = t
+	t.SetNod(self)
+}
+
+func (n *miniType) Sym() *types.Sym { return nil }   // for Format OTYPE
+func (n *miniType) Implicit() bool  { return false } // for Format OTYPE
+
+// A ChanType represents a chan Elem syntax with the direction Dir.
+type ChanType struct {
+	miniType
+	Elem Ntype
+	Dir  types.ChanDir
+}
+
+func NewChanType(pos src.XPos, elem Ntype, dir types.ChanDir) *ChanType {
+	n := &ChanType{Elem: elem, Dir: dir}
+	n.op = OTCHAN
+	n.pos = pos
+	return n
+}
+
+func (n *ChanType) SetOTYPE(t *types.Type) {
+	n.setOTYPE(t, n)
+	n.Elem = nil
+}
+
+// A MapType represents a map[Key]Value type syntax.
+type MapType struct {
+	miniType
+	Key  Ntype
+	Elem Ntype
+}
+
+func NewMapType(pos src.XPos, key, elem Ntype) *MapType {
+	n := &MapType{Key: key, Elem: elem}
+	n.op = OTMAP
+	n.pos = pos
+	return n
+}
+
+func (n *MapType) SetOTYPE(t *types.Type) {
+	n.setOTYPE(t, n)
+	n.Key = nil
+	n.Elem = nil
+}
+
+// A StructType represents a struct { ... } type syntax.
+type StructType struct {
+	miniType
+	Fields []*Field
+}
+
+func NewStructType(pos src.XPos, fields []*Field) *StructType {
+	n := &StructType{Fields: fields}
+	n.op = OTSTRUCT
+	n.pos = pos
+	return n
+}
+
+func (n *StructType) SetOTYPE(t *types.Type) {
+	n.setOTYPE(t, n)
+	n.Fields = nil
+}
+
+// An InterfaceType represents a struct { ... } type syntax.
+type InterfaceType struct {
+	miniType
+	Methods []*Field
+}
+
+func NewInterfaceType(pos src.XPos, methods []*Field) *InterfaceType {
+	n := &InterfaceType{Methods: methods}
+	n.op = OTINTER
+	n.pos = pos
+	return n
+}
+
+func (n *InterfaceType) SetOTYPE(t *types.Type) {
+	n.setOTYPE(t, n)
+	n.Methods = nil
+}
+
+// A FuncType represents a func(Args) Results type syntax.
+type FuncType struct {
+	miniType
+	Recv    *Field
+	Params  []*Field
+	Results []*Field
+}
+
+func NewFuncType(pos src.XPos, rcvr *Field, args, results []*Field) *FuncType {
+	n := &FuncType{Recv: rcvr, Params: args, Results: results}
+	n.op = OTFUNC
+	n.pos = pos
+	return n
+}
+
+func (n *FuncType) SetOTYPE(t *types.Type) {
+	n.setOTYPE(t, n)
+	n.Recv = nil
+	n.Params = nil
+	n.Results = nil
+}
+
+// A Field is a declared struct field, interface method, or function argument.
+// It is not a Node.
+type Field struct {
+	Pos      src.XPos
+	Sym      *types.Sym
+	Ntype    Ntype
+	Type     *types.Type
+	Embedded bool
+	IsDDD    bool
+	Note     string
+	Decl     *Name
+}
+
+func NewField(pos src.XPos, sym *types.Sym, ntyp Ntype, typ *types.Type) *Field {
+	return &Field{Pos: pos, Sym: sym, Ntype: ntyp, Type: typ}
+}
+
+func (f *Field) String() string {
+	var typ string
+	if f.Type != nil {
+		typ = fmt.Sprint(f.Type)
+	} else {
+		typ = fmt.Sprint(f.Ntype)
+	}
+	if f.Sym != nil {
+		return fmt.Sprintf("%v %v", f.Sym, typ)
+	}
+	return typ
+}
+
+// TODO(mdempsky): Make Field a Node again so these can be generated?
+// Fields are Nodes in go/ast and cmd/compile/internal/syntax.
+
+func copyField(f *Field) *Field {
+	if f == nil {
+		return nil
+	}
+	c := *f
+	return &c
+}
+func doField(f *Field, do func(Node) bool) bool {
+	if f == nil {
+		return false
+	}
+	if f.Decl != nil && do(f.Decl) {
+		return true
+	}
+	if f.Ntype != nil && do(f.Ntype) {
+		return true
+	}
+	return false
+}
+func editField(f *Field, edit func(Node) Node) {
+	if f == nil {
+		return
+	}
+	if f.Decl != nil {
+		f.Decl = edit(f.Decl).(*Name)
+	}
+	if f.Ntype != nil {
+		f.Ntype = edit(f.Ntype).(Ntype)
+	}
+}
+
+func copyFields(list []*Field) []*Field {
+	out := make([]*Field, len(list))
+	for i, f := range list {
+		out[i] = copyField(f)
+	}
+	return out
+}
+func doFields(list []*Field, do func(Node) bool) bool {
+	for _, x := range list {
+		if doField(x, do) {
+			return true
+		}
+	}
+	return false
+}
+func editFields(list []*Field, edit func(Node) Node) {
+	for _, f := range list {
+		editField(f, edit)
+	}
+}
+
+// A SliceType represents a []Elem type syntax.
+// If DDD is true, it's the ...Elem at the end of a function list.
+type SliceType struct {
+	miniType
+	Elem Ntype
+	DDD  bool
+}
+
+func NewSliceType(pos src.XPos, elem Ntype) *SliceType {
+	n := &SliceType{Elem: elem}
+	n.op = OTSLICE
+	n.pos = pos
+	return n
+}
+
+func (n *SliceType) SetOTYPE(t *types.Type) {
+	n.setOTYPE(t, n)
+	n.Elem = nil
+}
+
+// An ArrayType represents a [Len]Elem type syntax.
+// If Len is nil, the type is a [...]Elem in an array literal.
+type ArrayType struct {
+	miniType
+	Len  Node
+	Elem Ntype
+}
+
+func NewArrayType(pos src.XPos, len Node, elem Ntype) *ArrayType {
+	n := &ArrayType{Len: len, Elem: elem}
+	n.op = OTARRAY
+	n.pos = pos
+	return n
+}
+
+func (n *ArrayType) SetOTYPE(t *types.Type) {
+	n.setOTYPE(t, n)
+	n.Len = nil
+	n.Elem = nil
+}
+
+// A typeNode is a Node wrapper for type t.
+type typeNode struct {
+	miniNode
+	typ *types.Type
+}
+
+func newTypeNode(pos src.XPos, typ *types.Type) *typeNode {
+	n := &typeNode{typ: typ}
+	n.pos = pos
+	n.op = OTYPE
+	return n
+}
+
+func (n *typeNode) Type() *types.Type { return n.typ }
+func (n *typeNode) Sym() *types.Sym   { return n.typ.Sym() }
+func (n *typeNode) CanBeNtype()       {}
+
+// TypeNode returns the Node representing the type t.
+func TypeNode(t *types.Type) Ntype {
+	if n := t.Obj(); n != nil {
+		if n.Type() != t {
+			base.Fatalf("type skew: %v has type %v, but expected %v", n, n.Type(), t)
+		}
+		return n.(Ntype)
+	}
+	return newTypeNode(src.NoXPos, t)
+}
diff --git a/src/cmd/compile/internal/ir/val.go b/src/cmd/compile/internal/ir/val.go
new file mode 100644
index 0000000..03c320e
--- /dev/null
+++ b/src/cmd/compile/internal/ir/val.go
@@ -0,0 +1,171 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"go/constant"
+	"math"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/types"
+)
+
+func ConstType(n Node) constant.Kind {
+	if n == nil || n.Op() != OLITERAL {
+		return constant.Unknown
+	}
+	return n.Val().Kind()
+}
+
+// ConstValue returns the constant value stored in n as an interface{}.
+// It returns int64s for ints and runes, float64s for floats,
+// and complex128s for complex values.
+func ConstValue(n Node) interface{} {
+	switch v := n.Val(); v.Kind() {
+	default:
+		base.Fatalf("unexpected constant: %v", v)
+		panic("unreachable")
+	case constant.Bool:
+		return constant.BoolVal(v)
+	case constant.String:
+		return constant.StringVal(v)
+	case constant.Int:
+		return IntVal(n.Type(), v)
+	case constant.Float:
+		return Float64Val(v)
+	case constant.Complex:
+		return complex(Float64Val(constant.Real(v)), Float64Val(constant.Imag(v)))
+	}
+}
+
+// IntVal returns v converted to int64.
+// Note: if t is uint64, very large values will be converted to negative int64.
+func IntVal(t *types.Type, v constant.Value) int64 {
+	if t.IsUnsigned() {
+		if x, ok := constant.Uint64Val(v); ok {
+			return int64(x)
+		}
+	} else {
+		if x, ok := constant.Int64Val(v); ok {
+			return x
+		}
+	}
+	base.Fatalf("%v out of range for %v", v, t)
+	panic("unreachable")
+}
+
+func Float64Val(v constant.Value) float64 {
+	if x, _ := constant.Float64Val(v); !math.IsInf(x, 0) {
+		return x + 0 // avoid -0 (should not be needed, but be conservative)
+	}
+	base.Fatalf("bad float64 value: %v", v)
+	panic("unreachable")
+}
+
+func AssertValidTypeForConst(t *types.Type, v constant.Value) {
+	if !ValidTypeForConst(t, v) {
+		base.Fatalf("%v does not represent %v", t, v)
+	}
+}
+
+func ValidTypeForConst(t *types.Type, v constant.Value) bool {
+	switch v.Kind() {
+	case constant.Unknown:
+		return OKForConst[t.Kind()]
+	case constant.Bool:
+		return t.IsBoolean()
+	case constant.String:
+		return t.IsString()
+	case constant.Int:
+		return t.IsInteger()
+	case constant.Float:
+		return t.IsFloat()
+	case constant.Complex:
+		return t.IsComplex()
+	}
+
+	base.Fatalf("unexpected constant kind: %v", v)
+	panic("unreachable")
+}
+
+// NewLiteral returns a new untyped constant with value v.
+func NewLiteral(v constant.Value) Node {
+	return NewBasicLit(base.Pos, v)
+}
+
+func idealType(ct constant.Kind) *types.Type {
+	switch ct {
+	case constant.String:
+		return types.UntypedString
+	case constant.Bool:
+		return types.UntypedBool
+	case constant.Int:
+		return types.UntypedInt
+	case constant.Float:
+		return types.UntypedFloat
+	case constant.Complex:
+		return types.UntypedComplex
+	}
+	base.Fatalf("unexpected Ctype: %v", ct)
+	return nil
+}
+
+var OKForConst [types.NTYPE]bool
+
+// CanInt64 reports whether it is safe to call Int64Val() on n.
+func CanInt64(n Node) bool {
+	if !IsConst(n, constant.Int) {
+		return false
+	}
+
+	// if the value inside n cannot be represented as an int64, the
+	// return value of Int64 is undefined
+	_, ok := constant.Int64Val(n.Val())
+	return ok
+}
+
+// Int64Val returns n as an int64.
+// n must be an integer or rune constant.
+func Int64Val(n Node) int64 {
+	if !IsConst(n, constant.Int) {
+		base.Fatalf("Int64Val(%v)", n)
+	}
+	x, ok := constant.Int64Val(n.Val())
+	if !ok {
+		base.Fatalf("Int64Val(%v)", n)
+	}
+	return x
+}
+
+// Uint64Val returns n as an uint64.
+// n must be an integer or rune constant.
+func Uint64Val(n Node) uint64 {
+	if !IsConst(n, constant.Int) {
+		base.Fatalf("Uint64Val(%v)", n)
+	}
+	x, ok := constant.Uint64Val(n.Val())
+	if !ok {
+		base.Fatalf("Uint64Val(%v)", n)
+	}
+	return x
+}
+
+// BoolVal returns n as a bool.
+// n must be a boolean constant.
+func BoolVal(n Node) bool {
+	if !IsConst(n, constant.Bool) {
+		base.Fatalf("BoolVal(%v)", n)
+	}
+	return constant.BoolVal(n.Val())
+}
+
+// StringVal returns the value of a literal string Node as a string.
+// n must be a string constant.
+func StringVal(n Node) string {
+	if !IsConst(n, constant.String) {
+		base.Fatalf("StringVal(%v)", n)
+	}
+	return constant.StringVal(n.Val())
+}
diff --git a/src/cmd/compile/internal/ir/visit.go b/src/cmd/compile/internal/ir/visit.go
new file mode 100644
index 0000000..e4aeae3
--- /dev/null
+++ b/src/cmd/compile/internal/ir/visit.go
@@ -0,0 +1,186 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// IR visitors for walking the IR tree.
+//
+// The lowest level helpers are DoChildren and EditChildren, which
+// nodes help implement and provide control over whether and when
+// recursion happens during the walk of the IR.
+//
+// Although these are both useful directly, two simpler patterns
+// are fairly common and also provided: Visit and Any.
+
+package ir
+
+// DoChildren calls do(x) on each of n's non-nil child nodes x.
+// If any call returns true, DoChildren stops and returns true.
+// Otherwise, DoChildren returns false.
+//
+// Note that DoChildren(n, do) only calls do(x) for n's immediate children.
+// If x's children should be processed, then do(x) must call DoChildren(x, do).
+//
+// DoChildren allows constructing general traversals of the IR graph
+// that can stop early if needed. The most general usage is:
+//
+//	var do func(ir.Node) bool
+//	do = func(x ir.Node) bool {
+//		... processing BEFORE visiting children ...
+//		if ... should visit children ... {
+//			ir.DoChildren(x, do)
+//			... processing AFTER visiting children ...
+//		}
+//		if ... should stop parent DoChildren call from visiting siblings ... {
+//			return true
+//		}
+//		return false
+//	}
+//	do(root)
+//
+// Since DoChildren does not return true itself, if the do function
+// never wants to stop the traversal, it can assume that DoChildren
+// itself will always return false, simplifying to:
+//
+//	var do func(ir.Node) bool
+//	do = func(x ir.Node) bool {
+//		... processing BEFORE visiting children ...
+//		if ... should visit children ... {
+//			ir.DoChildren(x, do)
+//		}
+//		... processing AFTER visiting children ...
+//		return false
+//	}
+//	do(root)
+//
+// The Visit function illustrates a further simplification of the pattern,
+// only processing before visiting children and never stopping:
+//
+//	func Visit(n ir.Node, visit func(ir.Node)) {
+//		if n == nil {
+//			return
+//		}
+//		var do func(ir.Node) bool
+//		do = func(x ir.Node) bool {
+//			visit(x)
+//			return ir.DoChildren(x, do)
+//		}
+//		do(n)
+//	}
+//
+// The Any function illustrates a different simplification of the pattern,
+// visiting each node and then its children, recursively, until finding
+// a node x for which cond(x) returns true, at which point the entire
+// traversal stops and returns true.
+//
+//	func Any(n ir.Node, cond(ir.Node) bool) bool {
+//		if n == nil {
+//			return false
+//		}
+//		var do func(ir.Node) bool
+//		do = func(x ir.Node) bool {
+//			return cond(x) || ir.DoChildren(x, do)
+//		}
+//		return do(n)
+//	}
+//
+// Visit and Any are presented above as examples of how to use
+// DoChildren effectively, but of course, usage that fits within the
+// simplifications captured by Visit or Any will be best served
+// by directly calling the ones provided by this package.
+func DoChildren(n Node, do func(Node) bool) bool {
+	if n == nil {
+		return false
+	}
+	return n.doChildren(do)
+}
+
+// Visit visits each non-nil node x in the IR tree rooted at n
+// in a depth-first preorder traversal, calling visit on each node visited.
+func Visit(n Node, visit func(Node)) {
+	if n == nil {
+		return
+	}
+	var do func(Node) bool
+	do = func(x Node) bool {
+		visit(x)
+		return DoChildren(x, do)
+	}
+	do(n)
+}
+
+// VisitList calls Visit(x, visit) for each node x in the list.
+func VisitList(list Nodes, visit func(Node)) {
+	for _, x := range list {
+		Visit(x, visit)
+	}
+}
+
+// Any looks for a non-nil node x in the IR tree rooted at n
+// for which cond(x) returns true.
+// Any considers nodes in a depth-first, preorder traversal.
+// When Any finds a node x such that cond(x) is true,
+// Any ends the traversal and returns true immediately.
+// Otherwise Any returns false after completing the entire traversal.
+func Any(n Node, cond func(Node) bool) bool {
+	if n == nil {
+		return false
+	}
+	var do func(Node) bool
+	do = func(x Node) bool {
+		return cond(x) || DoChildren(x, do)
+	}
+	return do(n)
+}
+
+// AnyList calls Any(x, cond) for each node x in the list, in order.
+// If any call returns true, AnyList stops and returns true.
+// Otherwise, AnyList returns false after calling Any(x, cond)
+// for every x in the list.
+func AnyList(list Nodes, cond func(Node) bool) bool {
+	for _, x := range list {
+		if Any(x, cond) {
+			return true
+		}
+	}
+	return false
+}
+
+// EditChildren edits the child nodes of n, replacing each child x with edit(x).
+//
+// Note that EditChildren(n, edit) only calls edit(x) for n's immediate children.
+// If x's children should be processed, then edit(x) must call EditChildren(x, edit).
+//
+// EditChildren allows constructing general editing passes of the IR graph.
+// The most general usage is:
+//
+//	var edit func(ir.Node) ir.Node
+//	edit = func(x ir.Node) ir.Node {
+//		... processing BEFORE editing children ...
+//		if ... should edit children ... {
+//			EditChildren(x, edit)
+//			... processing AFTER editing children ...
+//		}
+//		... return x ...
+//	}
+//	n = edit(n)
+//
+// EditChildren edits the node in place. To edit a copy, call Copy first.
+// As an example, a simple deep copy implementation would be:
+//
+//	func deepCopy(n ir.Node) ir.Node {
+//		var edit func(ir.Node) ir.Node
+//		edit = func(x ir.Node) ir.Node {
+//			x = ir.Copy(x)
+//			ir.EditChildren(x, edit)
+//			return x
+//		}
+//		return edit(n)
+//	}
+//
+// Of course, in this case it is better to call ir.DeepCopy than to build one anew.
+func EditChildren(n Node, edit func(Node) Node) {
+	if n == nil {
+		return
+	}
+	n.editChildren(edit)
+}
diff --git a/src/cmd/compile/internal/liveness/bvset.go b/src/cmd/compile/internal/liveness/bvset.go
new file mode 100644
index 0000000..3431f54
--- /dev/null
+++ b/src/cmd/compile/internal/liveness/bvset.go
@@ -0,0 +1,97 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package liveness
+
+import "cmd/compile/internal/bitvec"
+
+// FNV-1 hash function constants.
+const (
+	h0 = 2166136261
+	hp = 16777619
+)
+
+// bvecSet is a set of bvecs, in initial insertion order.
+type bvecSet struct {
+	index []int           // hash -> uniq index. -1 indicates empty slot.
+	uniq  []bitvec.BitVec // unique bvecs, in insertion order
+}
+
+func (m *bvecSet) grow() {
+	// Allocate new index.
+	n := len(m.index) * 2
+	if n == 0 {
+		n = 32
+	}
+	newIndex := make([]int, n)
+	for i := range newIndex {
+		newIndex[i] = -1
+	}
+
+	// Rehash into newIndex.
+	for i, bv := range m.uniq {
+		h := hashbitmap(h0, bv) % uint32(len(newIndex))
+		for {
+			j := newIndex[h]
+			if j < 0 {
+				newIndex[h] = i
+				break
+			}
+			h++
+			if h == uint32(len(newIndex)) {
+				h = 0
+			}
+		}
+	}
+	m.index = newIndex
+}
+
+// add adds bv to the set and returns its index in m.extractUnique.
+// The caller must not modify bv after this.
+func (m *bvecSet) add(bv bitvec.BitVec) int {
+	if len(m.uniq)*4 >= len(m.index) {
+		m.grow()
+	}
+
+	index := m.index
+	h := hashbitmap(h0, bv) % uint32(len(index))
+	for {
+		j := index[h]
+		if j < 0 {
+			// New bvec.
+			index[h] = len(m.uniq)
+			m.uniq = append(m.uniq, bv)
+			return len(m.uniq) - 1
+		}
+		jlive := m.uniq[j]
+		if bv.Eq(jlive) {
+			// Existing bvec.
+			return j
+		}
+
+		h++
+		if h == uint32(len(index)) {
+			h = 0
+		}
+	}
+}
+
+// extractUnique returns this slice of unique bit vectors in m, as
+// indexed by the result of bvecSet.add.
+func (m *bvecSet) extractUnique() []bitvec.BitVec {
+	return m.uniq
+}
+
+func hashbitmap(h uint32, bv bitvec.BitVec) uint32 {
+	n := int((bv.N + 31) / 32)
+	for i := 0; i < n; i++ {
+		w := bv.B[i]
+		h = (h * hp) ^ (w & 0xff)
+		h = (h * hp) ^ ((w >> 8) & 0xff)
+		h = (h * hp) ^ ((w >> 16) & 0xff)
+		h = (h * hp) ^ ((w >> 24) & 0xff)
+	}
+
+	return h
+}
diff --git a/src/cmd/compile/internal/liveness/plive.go b/src/cmd/compile/internal/liveness/plive.go
new file mode 100644
index 0000000..f5c2ef7
--- /dev/null
+++ b/src/cmd/compile/internal/liveness/plive.go
@@ -0,0 +1,1535 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Garbage collector liveness bitmap generation.
+
+// The command line flag -live causes this code to print debug information.
+// The levels are:
+//
+//	-live (aka -live=1): print liveness lists as code warnings at safe points
+//	-live=2: print an assembly listing with liveness annotations
+//
+// Each level includes the earlier output as well.
+
+package liveness
+
+import (
+	"crypto/md5"
+	"crypto/sha1"
+	"fmt"
+	"os"
+	"sort"
+	"strings"
+
+	"cmd/compile/internal/abi"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/bitvec"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/typebits"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/objabi"
+	"cmd/internal/src"
+)
+
+// OpVarDef is an annotation for the liveness analysis, marking a place
+// where a complete initialization (definition) of a variable begins.
+// Since the liveness analysis can see initialization of single-word
+// variables quite easy, OpVarDef is only needed for multi-word
+// variables satisfying isfat(n.Type). For simplicity though, buildssa
+// emits OpVarDef regardless of variable width.
+//
+// An 'OpVarDef x' annotation in the instruction stream tells the liveness
+// analysis to behave as though the variable x is being initialized at that
+// point in the instruction stream. The OpVarDef must appear before the
+// actual (multi-instruction) initialization, and it must also appear after
+// any uses of the previous value, if any. For example, if compiling:
+//
+//	x = x[1:]
+//
+// it is important to generate code like:
+//
+//	base, len, cap = pieces of x[1:]
+//	OpVarDef x
+//	x = {base, len, cap}
+//
+// If instead the generated code looked like:
+//
+//	OpVarDef x
+//	base, len, cap = pieces of x[1:]
+//	x = {base, len, cap}
+//
+// then the liveness analysis would decide the previous value of x was
+// unnecessary even though it is about to be used by the x[1:] computation.
+// Similarly, if the generated code looked like:
+//
+//	base, len, cap = pieces of x[1:]
+//	x = {base, len, cap}
+//	OpVarDef x
+//
+// then the liveness analysis will not preserve the new value of x, because
+// the OpVarDef appears to have "overwritten" it.
+//
+// OpVarDef is a bit of a kludge to work around the fact that the instruction
+// stream is working on single-word values but the liveness analysis
+// wants to work on individual variables, which might be multi-word
+// aggregates. It might make sense at some point to look into letting
+// the liveness analysis work on single-word values as well, although
+// there are complications around interface values, slices, and strings,
+// all of which cannot be treated as individual words.
+//
+// OpVarKill is the opposite of OpVarDef: it marks a value as no longer needed,
+// even if its address has been taken. That is, an OpVarKill annotation asserts
+// that its argument is certainly dead, for use when the liveness analysis
+// would not otherwise be able to deduce that fact.
+
+// TODO: get rid of OpVarKill here. It's useful for stack frame allocation
+// so the compiler can allocate two temps to the same location. Here it's now
+// useless, since the implementation of stack objects.
+
+// blockEffects summarizes the liveness effects on an SSA block.
+type blockEffects struct {
+	// Computed during Liveness.prologue using only the content of
+	// individual blocks:
+	//
+	//	uevar: upward exposed variables (used before set in block)
+	//	varkill: killed variables (set in block)
+	uevar   bitvec.BitVec
+	varkill bitvec.BitVec
+
+	// Computed during Liveness.solve using control flow information:
+	//
+	//	livein: variables live at block entry
+	//	liveout: variables live at block exit
+	livein  bitvec.BitVec
+	liveout bitvec.BitVec
+}
+
+// A collection of global state used by liveness analysis.
+type liveness struct {
+	fn         *ir.Func
+	f          *ssa.Func
+	vars       []*ir.Name
+	idx        map[*ir.Name]int32
+	stkptrsize int64
+
+	be []blockEffects
+
+	// allUnsafe indicates that all points in this function are
+	// unsafe-points.
+	allUnsafe bool
+	// unsafePoints bit i is set if Value ID i is an unsafe-point
+	// (preemption is not allowed). Only valid if !allUnsafe.
+	unsafePoints bitvec.BitVec
+
+	// An array with a bit vector for each safe point in the
+	// current Block during liveness.epilogue. Indexed in Value
+	// order for that block. Additionally, for the entry block
+	// livevars[0] is the entry bitmap. liveness.compact moves
+	// these to stackMaps.
+	livevars []bitvec.BitVec
+
+	// livenessMap maps from safe points (i.e., CALLs) to their
+	// liveness map indexes.
+	livenessMap Map
+	stackMapSet bvecSet
+	stackMaps   []bitvec.BitVec
+
+	cache progeffectscache
+
+	// partLiveArgs includes input arguments (PPARAM) that may
+	// be partially live. That is, it is considered live because
+	// a part of it is used, but we may not initialize all parts.
+	partLiveArgs map[*ir.Name]bool
+
+	doClobber     bool // Whether to clobber dead stack slots in this function.
+	noClobberArgs bool // Do not clobber function arguments
+}
+
+// Map maps from *ssa.Value to LivenessIndex.
+type Map struct {
+	Vals map[ssa.ID]objw.LivenessIndex
+	// The set of live, pointer-containing variables at the DeferReturn
+	// call (only set when open-coded defers are used).
+	DeferReturn objw.LivenessIndex
+}
+
+func (m *Map) reset() {
+	if m.Vals == nil {
+		m.Vals = make(map[ssa.ID]objw.LivenessIndex)
+	} else {
+		for k := range m.Vals {
+			delete(m.Vals, k)
+		}
+	}
+	m.DeferReturn = objw.LivenessDontCare
+}
+
+func (m *Map) set(v *ssa.Value, i objw.LivenessIndex) {
+	m.Vals[v.ID] = i
+}
+
+func (m Map) Get(v *ssa.Value) objw.LivenessIndex {
+	// If v isn't in the map, then it's a "don't care" and not an
+	// unsafe-point.
+	if idx, ok := m.Vals[v.ID]; ok {
+		return idx
+	}
+	return objw.LivenessIndex{StackMapIndex: objw.StackMapDontCare, IsUnsafePoint: false}
+}
+
+type progeffectscache struct {
+	retuevar    []int32
+	tailuevar   []int32
+	initialized bool
+}
+
+// shouldTrack reports whether the liveness analysis
+// should track the variable n.
+// We don't care about variables that have no pointers,
+// nor do we care about non-local variables,
+// nor do we care about empty structs (handled by the pointer check),
+// nor do we care about the fake PAUTOHEAP variables.
+func shouldTrack(n *ir.Name) bool {
+	return (n.Class == ir.PAUTO && n.Esc() != ir.EscHeap || n.Class == ir.PPARAM || n.Class == ir.PPARAMOUT) && n.Type().HasPointers()
+}
+
+// getvariables returns the list of on-stack variables that we need to track
+// and a map for looking up indices by *Node.
+func getvariables(fn *ir.Func) ([]*ir.Name, map[*ir.Name]int32) {
+	var vars []*ir.Name
+	for _, n := range fn.Dcl {
+		if shouldTrack(n) {
+			vars = append(vars, n)
+		}
+	}
+	idx := make(map[*ir.Name]int32, len(vars))
+	for i, n := range vars {
+		idx[n] = int32(i)
+	}
+	return vars, idx
+}
+
+func (lv *liveness) initcache() {
+	if lv.cache.initialized {
+		base.Fatalf("liveness cache initialized twice")
+		return
+	}
+	lv.cache.initialized = true
+
+	for i, node := range lv.vars {
+		switch node.Class {
+		case ir.PPARAM:
+			// A return instruction with a p.to is a tail return, which brings
+			// the stack pointer back up (if it ever went down) and then jumps
+			// to a new function entirely. That form of instruction must read
+			// all the parameters for correctness, and similarly it must not
+			// read the out arguments - they won't be set until the new
+			// function runs.
+			lv.cache.tailuevar = append(lv.cache.tailuevar, int32(i))
+
+		case ir.PPARAMOUT:
+			// All results are live at every return point.
+			// Note that this point is after escaping return values
+			// are copied back to the stack using their PAUTOHEAP references.
+			lv.cache.retuevar = append(lv.cache.retuevar, int32(i))
+		}
+	}
+}
+
+// A liveEffect is a set of flags that describe an instruction's
+// liveness effects on a variable.
+//
+// The possible flags are:
+//	uevar - used by the instruction
+//	varkill - killed by the instruction (set)
+// A kill happens after the use (for an instruction that updates a value, for example).
+type liveEffect int
+
+const (
+	uevar liveEffect = 1 << iota
+	varkill
+)
+
+// valueEffects returns the index of a variable in lv.vars and the
+// liveness effects v has on that variable.
+// If v does not affect any tracked variables, it returns -1, 0.
+func (lv *liveness) valueEffects(v *ssa.Value) (int32, liveEffect) {
+	n, e := affectedVar(v)
+	if e == 0 || n == nil { // cheapest checks first
+		return -1, 0
+	}
+	// AllocFrame has dropped unused variables from
+	// lv.fn.Func.Dcl, but they might still be referenced by
+	// OpVarFoo pseudo-ops. Ignore them to prevent "lost track of
+	// variable" ICEs (issue 19632).
+	switch v.Op {
+	case ssa.OpVarDef, ssa.OpVarKill, ssa.OpVarLive, ssa.OpKeepAlive:
+		if !n.Used() {
+			return -1, 0
+		}
+	}
+
+	if n.Class == ir.PPARAM && !n.Addrtaken() && n.Type().Width > int64(types.PtrSize) {
+		// Only aggregate-typed arguments that are not address-taken can be
+		// partially live.
+		lv.partLiveArgs[n] = true
+	}
+
+	var effect liveEffect
+	// Read is a read, obviously.
+	//
+	// Addr is a read also, as any subsequent holder of the pointer must be able
+	// to see all the values (including initialization) written so far.
+	// This also prevents a variable from "coming back from the dead" and presenting
+	// stale pointers to the garbage collector. See issue 28445.
+	if e&(ssa.SymRead|ssa.SymAddr) != 0 {
+		effect |= uevar
+	}
+	if e&ssa.SymWrite != 0 && (!isfat(n.Type()) || v.Op == ssa.OpVarDef) {
+		effect |= varkill
+	}
+
+	if effect == 0 {
+		return -1, 0
+	}
+
+	if pos, ok := lv.idx[n]; ok {
+		return pos, effect
+	}
+	return -1, 0
+}
+
+// affectedVar returns the *ir.Name node affected by v
+func affectedVar(v *ssa.Value) (*ir.Name, ssa.SymEffect) {
+	// Special cases.
+	switch v.Op {
+	case ssa.OpLoadReg:
+		n, _ := ssa.AutoVar(v.Args[0])
+		return n, ssa.SymRead
+	case ssa.OpStoreReg:
+		n, _ := ssa.AutoVar(v)
+		return n, ssa.SymWrite
+
+	case ssa.OpArgIntReg:
+		// This forces the spill slot for the register to be live at function entry.
+		// one of the following holds for a function F with pointer-valued register arg X:
+		//  0. No GC (so an uninitialized spill slot is okay)
+		//  1. GC at entry of F.  GC is precise, but the spills around morestack initialize X's spill slot
+		//  2. Stack growth at entry of F.  Same as GC.
+		//  3. GC occurs within F itself.  This has to be from preemption, and thus GC is conservative.
+		//     a. X is in a register -- then X is seen, and the spill slot is also scanned conservatively.
+		//     b. X is spilled -- the spill slot is initialized, and scanned conservatively
+		//     c. X is not live -- the spill slot is scanned conservatively, and it may contain X from an earlier spill.
+		//  4. GC within G, transitively called from F
+		//    a. X is live at call site, therefore is spilled, to its spill slot (which is live because of subsequent LoadReg).
+		//    b. X is not live at call site -- but neither is its spill slot.
+		n, _ := ssa.AutoVar(v)
+		return n, ssa.SymRead
+
+	case ssa.OpVarLive:
+		return v.Aux.(*ir.Name), ssa.SymRead
+	case ssa.OpVarDef, ssa.OpVarKill:
+		return v.Aux.(*ir.Name), ssa.SymWrite
+	case ssa.OpKeepAlive:
+		n, _ := ssa.AutoVar(v.Args[0])
+		return n, ssa.SymRead
+	}
+
+	e := v.Op.SymEffect()
+	if e == 0 {
+		return nil, 0
+	}
+
+	switch a := v.Aux.(type) {
+	case nil, *obj.LSym:
+		// ok, but no node
+		return nil, e
+	case *ir.Name:
+		return a, e
+	default:
+		base.Fatalf("weird aux: %s", v.LongString())
+		return nil, e
+	}
+}
+
+type livenessFuncCache struct {
+	be          []blockEffects
+	livenessMap Map
+}
+
+// Constructs a new liveness structure used to hold the global state of the
+// liveness computation. The cfg argument is a slice of *BasicBlocks and the
+// vars argument is a slice of *Nodes.
+func newliveness(fn *ir.Func, f *ssa.Func, vars []*ir.Name, idx map[*ir.Name]int32, stkptrsize int64) *liveness {
+	lv := &liveness{
+		fn:         fn,
+		f:          f,
+		vars:       vars,
+		idx:        idx,
+		stkptrsize: stkptrsize,
+	}
+
+	// Significant sources of allocation are kept in the ssa.Cache
+	// and reused. Surprisingly, the bit vectors themselves aren't
+	// a major source of allocation, but the liveness maps are.
+	if lc, _ := f.Cache.Liveness.(*livenessFuncCache); lc == nil {
+		// Prep the cache so liveness can fill it later.
+		f.Cache.Liveness = new(livenessFuncCache)
+	} else {
+		if cap(lc.be) >= f.NumBlocks() {
+			lv.be = lc.be[:f.NumBlocks()]
+		}
+		lv.livenessMap = Map{Vals: lc.livenessMap.Vals, DeferReturn: objw.LivenessDontCare}
+		lc.livenessMap.Vals = nil
+	}
+	if lv.be == nil {
+		lv.be = make([]blockEffects, f.NumBlocks())
+	}
+
+	nblocks := int32(len(f.Blocks))
+	nvars := int32(len(vars))
+	bulk := bitvec.NewBulk(nvars, nblocks*7)
+	for _, b := range f.Blocks {
+		be := lv.blockEffects(b)
+
+		be.uevar = bulk.Next()
+		be.varkill = bulk.Next()
+		be.livein = bulk.Next()
+		be.liveout = bulk.Next()
+	}
+	lv.livenessMap.reset()
+
+	lv.markUnsafePoints()
+
+	lv.partLiveArgs = make(map[*ir.Name]bool)
+
+	lv.enableClobber()
+
+	return lv
+}
+
+func (lv *liveness) blockEffects(b *ssa.Block) *blockEffects {
+	return &lv.be[b.ID]
+}
+
+// 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 (lv *liveness) pointerMap(liveout bitvec.BitVec, vars []*ir.Name, args, locals bitvec.BitVec) {
+	for i := int32(0); ; i++ {
+		i = liveout.Next(i)
+		if i < 0 {
+			break
+		}
+		node := vars[i]
+		switch node.Class {
+		case ir.PPARAM, ir.PPARAMOUT:
+			if !node.IsOutputParamInRegisters() {
+				if node.FrameOffset() < 0 {
+					lv.f.Fatalf("Node %v has frameoffset %d\n", node.Sym().Name, node.FrameOffset())
+				}
+				typebits.Set(node.Type(), node.FrameOffset(), args)
+				break
+			}
+			fallthrough // PPARAMOUT in registers acts memory-allocates like an AUTO
+		case ir.PAUTO:
+			typebits.Set(node.Type(), node.FrameOffset()+lv.stkptrsize, locals)
+		}
+	}
+}
+
+// IsUnsafe indicates that all points in this function are
+// unsafe-points.
+func IsUnsafe(f *ssa.Func) bool {
+	// The runtime assumes the only safe-points are function
+	// prologues (because that's how it used to be). We could and
+	// should improve that, but for now keep consider all points
+	// in the runtime unsafe. obj will add prologues and their
+	// safe-points.
+	//
+	// go:nosplit functions are similar. Since safe points used to
+	// be coupled with stack checks, go:nosplit often actually
+	// means "no safe points in this function".
+	return base.Flag.CompilingRuntime || f.NoSplit
+}
+
+// markUnsafePoints finds unsafe points and computes lv.unsafePoints.
+func (lv *liveness) markUnsafePoints() {
+	if IsUnsafe(lv.f) {
+		// No complex analysis necessary.
+		lv.allUnsafe = true
+		return
+	}
+
+	lv.unsafePoints = bitvec.New(int32(lv.f.NumValues()))
+
+	// Mark architecture-specific unsafe points.
+	for _, b := range lv.f.Blocks {
+		for _, v := range b.Values {
+			if v.Op.UnsafePoint() {
+				lv.unsafePoints.Set(int32(v.ID))
+			}
+		}
+	}
+
+	// Mark write barrier unsafe points.
+	for _, wbBlock := range lv.f.WBLoads {
+		if wbBlock.Kind == ssa.BlockPlain && len(wbBlock.Values) == 0 {
+			// The write barrier block was optimized away
+			// but we haven't done dead block elimination.
+			// (This can happen in -N mode.)
+			continue
+		}
+		// Check that we have the expected diamond shape.
+		if len(wbBlock.Succs) != 2 {
+			lv.f.Fatalf("expected branch at write barrier block %v", wbBlock)
+		}
+		s0, s1 := wbBlock.Succs[0].Block(), wbBlock.Succs[1].Block()
+		if s0 == s1 {
+			// There's no difference between write barrier on and off.
+			// Thus there's no unsafe locations. See issue 26024.
+			continue
+		}
+		if s0.Kind != ssa.BlockPlain || s1.Kind != ssa.BlockPlain {
+			lv.f.Fatalf("expected successors of write barrier block %v to be plain", wbBlock)
+		}
+		if s0.Succs[0].Block() != s1.Succs[0].Block() {
+			lv.f.Fatalf("expected successors of write barrier block %v to converge", wbBlock)
+		}
+
+		// Flow backwards from the control value to find the
+		// flag load. We don't know what lowered ops we're
+		// looking for, but all current arches produce a
+		// single op that does the memory load from the flag
+		// address, so we look for that.
+		var load *ssa.Value
+		v := wbBlock.Controls[0]
+		for {
+			if sym, ok := v.Aux.(*obj.LSym); ok && sym == ir.Syms.WriteBarrier {
+				load = v
+				break
+			}
+			switch v.Op {
+			case ssa.Op386TESTL:
+				// 386 lowers Neq32 to (TESTL cond cond),
+				if v.Args[0] == v.Args[1] {
+					v = v.Args[0]
+					continue
+				}
+			case ssa.Op386MOVLload, ssa.OpARM64MOVWUload, ssa.OpPPC64MOVWZload, ssa.OpWasmI64Load32U:
+				// Args[0] is the address of the write
+				// barrier control. Ignore Args[1],
+				// which is the mem operand.
+				// TODO: Just ignore mem operands?
+				v = v.Args[0]
+				continue
+			}
+			// Common case: just flow backwards.
+			if len(v.Args) != 1 {
+				v.Fatalf("write barrier control value has more than one argument: %s", v.LongString())
+			}
+			v = v.Args[0]
+		}
+
+		// Mark everything after the load unsafe.
+		found := false
+		for _, v := range wbBlock.Values {
+			found = found || v == load
+			if found {
+				lv.unsafePoints.Set(int32(v.ID))
+			}
+		}
+
+		// Mark the two successor blocks unsafe. These come
+		// back together immediately after the direct write in
+		// one successor and the last write barrier call in
+		// the other, so there's no need to be more precise.
+		for _, succ := range wbBlock.Succs {
+			for _, v := range succ.Block().Values {
+				lv.unsafePoints.Set(int32(v.ID))
+			}
+		}
+	}
+
+	// Find uintptr -> unsafe.Pointer conversions and flood
+	// unsafeness back to a call (which is always a safe point).
+	//
+	// Looking for the uintptr -> unsafe.Pointer conversion has a
+	// few advantages over looking for unsafe.Pointer -> uintptr
+	// conversions:
+	//
+	// 1. We avoid needlessly blocking safe-points for
+	// unsafe.Pointer -> uintptr conversions that never go back to
+	// a Pointer.
+	//
+	// 2. We don't have to detect calls to reflect.Value.Pointer,
+	// reflect.Value.UnsafeAddr, and reflect.Value.InterfaceData,
+	// which are implicit unsafe.Pointer -> uintptr conversions.
+	// We can't even reliably detect this if there's an indirect
+	// call to one of these methods.
+	//
+	// TODO: For trivial unsafe.Pointer arithmetic, it would be
+	// nice to only flood as far as the unsafe.Pointer -> uintptr
+	// conversion, but it's hard to know which argument of an Add
+	// or Sub to follow.
+	var flooded bitvec.BitVec
+	var flood func(b *ssa.Block, vi int)
+	flood = func(b *ssa.Block, vi int) {
+		if flooded.N == 0 {
+			flooded = bitvec.New(int32(lv.f.NumBlocks()))
+		}
+		if flooded.Get(int32(b.ID)) {
+			return
+		}
+		for i := vi - 1; i >= 0; i-- {
+			v := b.Values[i]
+			if v.Op.IsCall() {
+				// Uintptrs must not contain live
+				// pointers across calls, so stop
+				// flooding.
+				return
+			}
+			lv.unsafePoints.Set(int32(v.ID))
+		}
+		if vi == len(b.Values) {
+			// We marked all values in this block, so no
+			// need to flood this block again.
+			flooded.Set(int32(b.ID))
+		}
+		for _, pred := range b.Preds {
+			flood(pred.Block(), len(pred.Block().Values))
+		}
+	}
+	for _, b := range lv.f.Blocks {
+		for i, v := range b.Values {
+			if !(v.Op == ssa.OpConvert && v.Type.IsPtrShaped()) {
+				continue
+			}
+			// Flood the unsafe-ness of this backwards
+			// until we hit a call.
+			flood(b, i+1)
+		}
+	}
+}
+
+// Returns true for instructions that must have a stack map.
+//
+// This does not necessarily mean the instruction is a safe-point. In
+// particular, call Values can have a stack map in case the callee
+// grows the stack, but not themselves be a safe-point.
+func (lv *liveness) hasStackMap(v *ssa.Value) bool {
+	if !v.Op.IsCall() {
+		return false
+	}
+	// typedmemclr and typedmemmove are write barriers and
+	// deeply non-preemptible. They are unsafe points and
+	// hence should not have liveness maps.
+	if sym, ok := v.Aux.(*ssa.AuxCall); ok && (sym.Fn == ir.Syms.Typedmemclr || sym.Fn == ir.Syms.Typedmemmove) {
+		return false
+	}
+	return true
+}
+
+// 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 (lv *liveness) prologue() {
+	lv.initcache()
+
+	for _, b := range lv.f.Blocks {
+		be := lv.blockEffects(b)
+
+		// Walk the block instructions backward and update the block
+		// effects with the each prog effects.
+		for j := len(b.Values) - 1; j >= 0; j-- {
+			pos, e := lv.valueEffects(b.Values[j])
+			if e&varkill != 0 {
+				be.varkill.Set(pos)
+				be.uevar.Unset(pos)
+			}
+			if e&uevar != 0 {
+				be.uevar.Set(pos)
+			}
+		}
+	}
+}
+
+// Solve the liveness dataflow equations.
+func (lv *liveness) solve() {
+	// These temporary bitvectors exist to avoid successive allocations and
+	// frees within the loop.
+	nvars := int32(len(lv.vars))
+	newlivein := bitvec.New(nvars)
+	newliveout := bitvec.New(nvars)
+
+	// Walk blocks in postorder ordering. This improves convergence.
+	po := lv.f.Postorder()
+
+	// Iterate through the blocks in reverse round-robin fashion. A work
+	// queue might be slightly faster. As is, the number of iterations is
+	// so low that it hardly seems to be worth the complexity.
+
+	for change := true; change; {
+		change = false
+		for _, b := range po {
+			be := lv.blockEffects(b)
+
+			newliveout.Clear()
+			switch b.Kind {
+			case ssa.BlockRet:
+				for _, pos := range lv.cache.retuevar {
+					newliveout.Set(pos)
+				}
+			case ssa.BlockRetJmp:
+				for _, pos := range lv.cache.tailuevar {
+					newliveout.Set(pos)
+				}
+			case ssa.BlockExit:
+				// panic exit - nothing to do
+			default:
+				// A variable is live on output from this block
+				// if it is live on input to some successor.
+				//
+				// out[b] = \bigcup_{s \in succ[b]} in[s]
+				newliveout.Copy(lv.blockEffects(b.Succs[0].Block()).livein)
+				for _, succ := range b.Succs[1:] {
+					newliveout.Or(newliveout, lv.blockEffects(succ.Block()).livein)
+				}
+			}
+
+			if !be.liveout.Eq(newliveout) {
+				change = true
+				be.liveout.Copy(newliveout)
+			}
+
+			// A variable is live on input to this block
+			// if it is used by this block, or live on output from this block and
+			// not set by the code in this block.
+			//
+			// in[b] = uevar[b] \cup (out[b] \setminus varkill[b])
+			newlivein.AndNot(be.liveout, be.varkill)
+			be.livein.Or(newlivein, be.uevar)
+		}
+	}
+}
+
+// Visits all instructions in a basic block and computes a bit vector of live
+// variables at each safe point locations.
+func (lv *liveness) epilogue() {
+	nvars := int32(len(lv.vars))
+	liveout := bitvec.New(nvars)
+	livedefer := bitvec.New(nvars) // always-live variables
+
+	// If there is a defer (that could recover), then all output
+	// parameters are live all the time.  In addition, any locals
+	// that are pointers to heap-allocated output parameters are
+	// also always live (post-deferreturn code needs these
+	// pointers to copy values back to the stack).
+	// TODO: if the output parameter is heap-allocated, then we
+	// don't need to keep the stack copy live?
+	if lv.fn.HasDefer() {
+		for i, n := range lv.vars {
+			if n.Class == ir.PPARAMOUT {
+				if n.IsOutputParamHeapAddr() {
+					// Just to be paranoid.  Heap addresses are PAUTOs.
+					base.Fatalf("variable %v both output param and heap output param", n)
+				}
+				if n.Heapaddr != nil {
+					// If this variable moved to the heap, then
+					// its stack copy is not live.
+					continue
+				}
+				// Note: zeroing is handled by zeroResults in walk.go.
+				livedefer.Set(int32(i))
+			}
+			if n.IsOutputParamHeapAddr() {
+				// This variable will be overwritten early in the function
+				// prologue (from the result of a mallocgc) but we need to
+				// zero it in case that malloc causes a stack scan.
+				n.SetNeedzero(true)
+				livedefer.Set(int32(i))
+			}
+			if n.OpenDeferSlot() {
+				// Open-coded defer args slots must be live
+				// everywhere in a function, since a panic can
+				// occur (almost) anywhere. Because it is live
+				// everywhere, it must be zeroed on entry.
+				livedefer.Set(int32(i))
+				// It was already marked as Needzero when created.
+				if !n.Needzero() {
+					base.Fatalf("all pointer-containing defer arg slots should have Needzero set")
+				}
+			}
+		}
+	}
+
+	// We must analyze the entry block first. The runtime assumes
+	// the function entry map is index 0. Conveniently, layout
+	// already ensured that the entry block is first.
+	if lv.f.Entry != lv.f.Blocks[0] {
+		lv.f.Fatalf("entry block must be first")
+	}
+
+	{
+		// Reserve an entry for function entry.
+		live := bitvec.New(nvars)
+		lv.livevars = append(lv.livevars, live)
+	}
+
+	for _, b := range lv.f.Blocks {
+		be := lv.blockEffects(b)
+
+		// Walk forward through the basic block instructions and
+		// allocate liveness maps for those instructions that need them.
+		for _, v := range b.Values {
+			if !lv.hasStackMap(v) {
+				continue
+			}
+
+			live := bitvec.New(nvars)
+			lv.livevars = append(lv.livevars, live)
+		}
+
+		// walk backward, construct maps at each safe point
+		index := int32(len(lv.livevars) - 1)
+
+		liveout.Copy(be.liveout)
+		for i := len(b.Values) - 1; i >= 0; i-- {
+			v := b.Values[i]
+
+			if lv.hasStackMap(v) {
+				// Found an interesting instruction, record the
+				// corresponding liveness information.
+
+				live := &lv.livevars[index]
+				live.Or(*live, liveout)
+				live.Or(*live, livedefer) // only for non-entry safe points
+				index--
+			}
+
+			// Update liveness information.
+			pos, e := lv.valueEffects(v)
+			if e&varkill != 0 {
+				liveout.Unset(pos)
+			}
+			if e&uevar != 0 {
+				liveout.Set(pos)
+			}
+		}
+
+		if b == lv.f.Entry {
+			if index != 0 {
+				base.Fatalf("bad index for entry point: %v", index)
+			}
+
+			// Check to make sure only input variables are live.
+			for i, n := range lv.vars {
+				if !liveout.Get(int32(i)) {
+					continue
+				}
+				if n.Class == ir.PPARAM {
+					continue // ok
+				}
+				base.FatalfAt(n.Pos(), "bad live variable at entry of %v: %L", lv.fn.Nname, n)
+			}
+
+			// Record live variables.
+			live := &lv.livevars[index]
+			live.Or(*live, liveout)
+		}
+
+		if lv.doClobber {
+			lv.clobber(b)
+		}
+
+		// The liveness maps for this block are now complete. Compact them.
+		lv.compact(b)
+	}
+
+	// If we have an open-coded deferreturn call, make a liveness map for it.
+	if lv.fn.OpenCodedDeferDisallowed() {
+		lv.livenessMap.DeferReturn = objw.LivenessDontCare
+	} else {
+		lv.livenessMap.DeferReturn = objw.LivenessIndex{
+			StackMapIndex: lv.stackMapSet.add(livedefer),
+			IsUnsafePoint: false,
+		}
+	}
+
+	// Done compacting. Throw out the stack map set.
+	lv.stackMaps = lv.stackMapSet.extractUnique()
+	lv.stackMapSet = bvecSet{}
+
+	// Useful sanity check: on entry to the function,
+	// the only things that can possibly be live are the
+	// input parameters.
+	for j, n := range lv.vars {
+		if n.Class != ir.PPARAM && lv.stackMaps[0].Get(int32(j)) {
+			lv.f.Fatalf("%v %L recorded as live on entry", lv.fn.Nname, n)
+		}
+	}
+}
+
+// Compact coalesces identical bitmaps from lv.livevars into the sets
+// lv.stackMapSet.
+//
+// Compact clears lv.livevars.
+//
+// There are actually two lists of bitmaps, one list for the local variables and one
+// list for the function arguments. Both lists are indexed by the same PCDATA
+// index, so the corresponding pairs must be considered together when
+// merging duplicates. The argument bitmaps change much less often during
+// function execution than the local variable bitmaps, so it is possible that
+// we could introduce a separate PCDATA index for arguments vs locals and
+// then compact the set of argument bitmaps separately from the set of
+// local variable bitmaps. As of 2014-04-02, doing this to the godoc binary
+// 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 (lv *liveness) compact(b *ssa.Block) {
+	pos := 0
+	if b == lv.f.Entry {
+		// Handle entry stack map.
+		lv.stackMapSet.add(lv.livevars[0])
+		pos++
+	}
+	for _, v := range b.Values {
+		hasStackMap := lv.hasStackMap(v)
+		isUnsafePoint := lv.allUnsafe || v.Op != ssa.OpClobber && lv.unsafePoints.Get(int32(v.ID))
+		idx := objw.LivenessIndex{StackMapIndex: objw.StackMapDontCare, IsUnsafePoint: isUnsafePoint}
+		if hasStackMap {
+			idx.StackMapIndex = lv.stackMapSet.add(lv.livevars[pos])
+			pos++
+		}
+		if hasStackMap || isUnsafePoint {
+			lv.livenessMap.set(v, idx)
+		}
+	}
+
+	// Reset livevars.
+	lv.livevars = lv.livevars[:0]
+}
+
+func (lv *liveness) enableClobber() {
+	// The clobberdead experiment inserts code to clobber pointer slots in all
+	// the dead variables (locals and args) at every synchronous safepoint.
+	if !base.Flag.ClobberDead {
+		return
+	}
+	if lv.fn.Pragma&ir.CgoUnsafeArgs != 0 {
+		// C or assembly code uses the exact frame layout. Don't clobber.
+		return
+	}
+	if len(lv.vars) > 10000 || len(lv.f.Blocks) > 10000 {
+		// Be careful to avoid doing too much work.
+		// Bail if >10000 variables or >10000 blocks.
+		// Otherwise, giant functions make this experiment generate too much code.
+		return
+	}
+	if lv.f.Name == "forkAndExecInChild" {
+		// forkAndExecInChild calls vfork on some platforms.
+		// The code we add here clobbers parts of the stack in the child.
+		// When the parent resumes, it is using the same stack frame. But the
+		// child has clobbered stack variables that the parent needs. Boom!
+		// In particular, the sys argument gets clobbered.
+		return
+	}
+	if lv.f.Name == "wbBufFlush" ||
+		((lv.f.Name == "callReflect" || lv.f.Name == "callMethod") && lv.fn.ABIWrapper()) {
+		// runtime.wbBufFlush must not modify its arguments. See the comments
+		// in runtime/mwbbuf.go:wbBufFlush.
+		//
+		// reflect.callReflect and reflect.callMethod are called from special
+		// functions makeFuncStub and methodValueCall. The runtime expects
+		// that it can find the first argument (ctxt) at 0(SP) in makeFuncStub
+		// and methodValueCall's frame (see runtime/traceback.go:getArgInfo).
+		// Normally callReflect and callMethod already do not modify the
+		// argument, and keep it alive. But the compiler-generated ABI wrappers
+		// don't do that. Special case the wrappers to not clobber its arguments.
+		lv.noClobberArgs = true
+	}
+	if h := os.Getenv("GOCLOBBERDEADHASH"); h != "" {
+		// Clobber only functions where the hash of the function name matches a pattern.
+		// Useful for binary searching for a miscompiled function.
+		hstr := ""
+		for _, b := range sha1.Sum([]byte(lv.f.Name)) {
+			hstr += fmt.Sprintf("%08b", b)
+		}
+		if !strings.HasSuffix(hstr, h) {
+			return
+		}
+		fmt.Printf("\t\t\tCLOBBERDEAD %s\n", lv.f.Name)
+	}
+	lv.doClobber = true
+}
+
+// Inserts code to clobber pointer slots in all the dead variables (locals and args)
+// at every synchronous safepoint in b.
+func (lv *liveness) clobber(b *ssa.Block) {
+	// Copy block's values to a temporary.
+	oldSched := append([]*ssa.Value{}, b.Values...)
+	b.Values = b.Values[:0]
+	idx := 0
+
+	// Clobber pointer slots in all dead variables at entry.
+	if b == lv.f.Entry {
+		for len(oldSched) > 0 && len(oldSched[0].Args) == 0 {
+			// Skip argless ops. We need to skip at least
+			// the lowered ClosurePtr op, because it
+			// really wants to be first. This will also
+			// skip ops like InitMem and SP, which are ok.
+			b.Values = append(b.Values, oldSched[0])
+			oldSched = oldSched[1:]
+		}
+		clobber(lv, b, lv.livevars[0])
+		idx++
+	}
+
+	// Copy values into schedule, adding clobbering around safepoints.
+	for _, v := range oldSched {
+		if !lv.hasStackMap(v) {
+			b.Values = append(b.Values, v)
+			continue
+		}
+		clobber(lv, b, lv.livevars[idx])
+		b.Values = append(b.Values, v)
+		idx++
+	}
+}
+
+// clobber generates code to clobber pointer slots in all dead variables
+// (those not marked in live). Clobbering instructions are added to the end
+// of b.Values.
+func clobber(lv *liveness, b *ssa.Block, live bitvec.BitVec) {
+	for i, n := range lv.vars {
+		if !live.Get(int32(i)) && !n.Addrtaken() && !n.OpenDeferSlot() && !n.IsOutputParamHeapAddr() {
+			// Don't clobber stack objects (address-taken). They are
+			// tracked dynamically.
+			// Also don't clobber slots that are live for defers (see
+			// the code setting livedefer in epilogue).
+			if lv.noClobberArgs && n.Class == ir.PPARAM {
+				continue
+			}
+			clobberVar(b, n)
+		}
+	}
+}
+
+// clobberVar generates code to trash the pointers in v.
+// Clobbering instructions are added to the end of b.Values.
+func clobberVar(b *ssa.Block, v *ir.Name) {
+	clobberWalk(b, v, 0, v.Type())
+}
+
+// b = block to which we append instructions
+// v = variable
+// offset = offset of (sub-portion of) variable to clobber (in bytes)
+// t = type of sub-portion of v.
+func clobberWalk(b *ssa.Block, v *ir.Name, offset int64, t *types.Type) {
+	if !t.HasPointers() {
+		return
+	}
+	switch t.Kind() {
+	case types.TPTR,
+		types.TUNSAFEPTR,
+		types.TFUNC,
+		types.TCHAN,
+		types.TMAP:
+		clobberPtr(b, v, offset)
+
+	case types.TSTRING:
+		// struct { byte *str; int len; }
+		clobberPtr(b, v, offset)
+
+	case types.TINTER:
+		// struct { Itab *tab; void *data; }
+		// or, when isnilinter(t)==true:
+		// struct { Type *type; void *data; }
+		clobberPtr(b, v, offset)
+		clobberPtr(b, v, offset+int64(types.PtrSize))
+
+	case types.TSLICE:
+		// struct { byte *array; int len; int cap; }
+		clobberPtr(b, v, offset)
+
+	case types.TARRAY:
+		for i := int64(0); i < t.NumElem(); i++ {
+			clobberWalk(b, v, offset+i*t.Elem().Size(), t.Elem())
+		}
+
+	case types.TSTRUCT:
+		for _, t1 := range t.Fields().Slice() {
+			clobberWalk(b, v, offset+t1.Offset, t1.Type)
+		}
+
+	default:
+		base.Fatalf("clobberWalk: unexpected type, %v", t)
+	}
+}
+
+// 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 *ir.Name, offset int64) {
+	b.NewValue0IA(src.NoXPos, ssa.OpClobber, types.TypeVoid, offset, v)
+}
+
+func (lv *liveness) showlive(v *ssa.Value, live bitvec.BitVec) {
+	if base.Flag.Live == 0 || ir.FuncName(lv.fn) == "init" || strings.HasPrefix(ir.FuncName(lv.fn), ".") {
+		return
+	}
+	if !(v == nil || v.Op.IsCall()) {
+		// Historically we only printed this information at
+		// calls. Keep doing so.
+		return
+	}
+	if live.IsEmpty() {
+		return
+	}
+
+	pos := lv.fn.Nname.Pos()
+	if v != nil {
+		pos = v.Pos
+	}
+
+	s := "live at "
+	if v == nil {
+		s += fmt.Sprintf("entry to %s:", ir.FuncName(lv.fn))
+	} else if sym, ok := v.Aux.(*ssa.AuxCall); ok && sym.Fn != nil {
+		fn := sym.Fn.Name
+		if pos := strings.Index(fn, "."); pos >= 0 {
+			fn = fn[pos+1:]
+		}
+		s += fmt.Sprintf("call to %s:", fn)
+	} else {
+		s += "indirect call:"
+	}
+
+	for j, n := range lv.vars {
+		if live.Get(int32(j)) {
+			s += fmt.Sprintf(" %v", n)
+		}
+	}
+
+	base.WarnfAt(pos, s)
+}
+
+func (lv *liveness) printbvec(printed bool, name string, live bitvec.BitVec) bool {
+	if live.IsEmpty() {
+		return printed
+	}
+
+	if !printed {
+		fmt.Printf("\t")
+	} else {
+		fmt.Printf(" ")
+	}
+	fmt.Printf("%s=", name)
+
+	comma := ""
+	for i, n := range lv.vars {
+		if !live.Get(int32(i)) {
+			continue
+		}
+		fmt.Printf("%s%s", comma, n.Sym().Name)
+		comma = ","
+	}
+	return true
+}
+
+// printeffect is like printbvec, but for valueEffects.
+func (lv *liveness) printeffect(printed bool, name string, pos int32, x bool) bool {
+	if !x {
+		return printed
+	}
+	if !printed {
+		fmt.Printf("\t")
+	} else {
+		fmt.Printf(" ")
+	}
+	fmt.Printf("%s=", name)
+	if x {
+		fmt.Printf("%s", lv.vars[pos].Sym().Name)
+	}
+
+	return true
+}
+
+// Prints the computed liveness information and inputs, for debugging.
+// This format synthesizes the information used during the multiple passes
+// into a single presentation.
+func (lv *liveness) printDebug() {
+	fmt.Printf("liveness: %s\n", ir.FuncName(lv.fn))
+
+	for i, b := range lv.f.Blocks {
+		if i > 0 {
+			fmt.Printf("\n")
+		}
+
+		// bb#0 pred=1,2 succ=3,4
+		fmt.Printf("bb#%d pred=", b.ID)
+		for j, pred := range b.Preds {
+			if j > 0 {
+				fmt.Printf(",")
+			}
+			fmt.Printf("%d", pred.Block().ID)
+		}
+		fmt.Printf(" succ=")
+		for j, succ := range b.Succs {
+			if j > 0 {
+				fmt.Printf(",")
+			}
+			fmt.Printf("%d", succ.Block().ID)
+		}
+		fmt.Printf("\n")
+
+		be := lv.blockEffects(b)
+
+		// initial settings
+		printed := false
+		printed = lv.printbvec(printed, "uevar", be.uevar)
+		printed = lv.printbvec(printed, "livein", be.livein)
+		if printed {
+			fmt.Printf("\n")
+		}
+
+		// program listing, with individual effects listed
+
+		if b == lv.f.Entry {
+			live := lv.stackMaps[0]
+			fmt.Printf("(%s) function entry\n", base.FmtPos(lv.fn.Nname.Pos()))
+			fmt.Printf("\tlive=")
+			printed = false
+			for j, n := range lv.vars {
+				if !live.Get(int32(j)) {
+					continue
+				}
+				if printed {
+					fmt.Printf(",")
+				}
+				fmt.Printf("%v", n)
+				printed = true
+			}
+			fmt.Printf("\n")
+		}
+
+		for _, v := range b.Values {
+			fmt.Printf("(%s) %v\n", base.FmtPos(v.Pos), v.LongString())
+
+			pcdata := lv.livenessMap.Get(v)
+
+			pos, effect := lv.valueEffects(v)
+			printed = false
+			printed = lv.printeffect(printed, "uevar", pos, effect&uevar != 0)
+			printed = lv.printeffect(printed, "varkill", pos, effect&varkill != 0)
+			if printed {
+				fmt.Printf("\n")
+			}
+
+			if pcdata.StackMapValid() {
+				fmt.Printf("\tlive=")
+				printed = false
+				if pcdata.StackMapValid() {
+					live := lv.stackMaps[pcdata.StackMapIndex]
+					for j, n := range lv.vars {
+						if !live.Get(int32(j)) {
+							continue
+						}
+						if printed {
+							fmt.Printf(",")
+						}
+						fmt.Printf("%v", n)
+						printed = true
+					}
+				}
+				fmt.Printf("\n")
+			}
+
+			if pcdata.IsUnsafePoint {
+				fmt.Printf("\tunsafe-point\n")
+			}
+		}
+
+		// bb bitsets
+		fmt.Printf("end\n")
+		printed = false
+		printed = lv.printbvec(printed, "varkill", be.varkill)
+		printed = lv.printbvec(printed, "liveout", be.liveout)
+		if printed {
+			fmt.Printf("\n")
+		}
+	}
+
+	fmt.Printf("\n")
+}
+
+// Dumps a slice of bitmaps to a symbol as a sequence of uint32 values. The
+// 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 (lv *liveness) emit() (argsSym, liveSym *obj.LSym) {
+	// Size args bitmaps to be just large enough to hold the largest pointer.
+	// First, find the largest Xoffset node we care about.
+	// (Nodes without pointers aren't in lv.vars; see ShouldTrack.)
+	var maxArgNode *ir.Name
+	for _, n := range lv.vars {
+		switch n.Class {
+		case ir.PPARAM, ir.PPARAMOUT:
+			if !n.IsOutputParamInRegisters() {
+				if maxArgNode == nil || n.FrameOffset() > maxArgNode.FrameOffset() {
+					maxArgNode = n
+				}
+			}
+		}
+	}
+	// Next, find the offset of the largest pointer in the largest node.
+	var maxArgs int64
+	if maxArgNode != nil {
+		maxArgs = maxArgNode.FrameOffset() + types.PtrDataSize(maxArgNode.Type())
+	}
+
+	// Size locals bitmaps to be stkptrsize sized.
+	// We cannot shrink them to only hold the largest pointer,
+	// because their size is used to calculate the beginning
+	// of the local variables frame.
+	// Further discussion in https://golang.org/cl/104175.
+	// TODO: consider trimming leading zeros.
+	// This would require shifting all bitmaps.
+	maxLocals := lv.stkptrsize
+
+	// Temporary symbols for encoding bitmaps.
+	var argsSymTmp, liveSymTmp obj.LSym
+
+	args := bitvec.New(int32(maxArgs / int64(types.PtrSize)))
+	aoff := objw.Uint32(&argsSymTmp, 0, uint32(len(lv.stackMaps))) // number of bitmaps
+	aoff = objw.Uint32(&argsSymTmp, aoff, uint32(args.N))          // number of bits in each bitmap
+
+	locals := bitvec.New(int32(maxLocals / int64(types.PtrSize)))
+	loff := objw.Uint32(&liveSymTmp, 0, uint32(len(lv.stackMaps))) // number of bitmaps
+	loff = objw.Uint32(&liveSymTmp, loff, uint32(locals.N))        // number of bits in each bitmap
+
+	for _, live := range lv.stackMaps {
+		args.Clear()
+		locals.Clear()
+
+		lv.pointerMap(live, lv.vars, args, locals)
+
+		aoff = objw.BitVec(&argsSymTmp, aoff, args)
+		loff = objw.BitVec(&liveSymTmp, loff, locals)
+	}
+
+	// Give these LSyms content-addressable names,
+	// so that they can be de-duplicated.
+	// This provides significant binary size savings.
+	//
+	// These symbols will be added to Ctxt.Data by addGCLocals
+	// after parallel compilation is done.
+	makeSym := func(tmpSym *obj.LSym) *obj.LSym {
+		return base.Ctxt.LookupInit(fmt.Sprintf("gclocals·%x", md5.Sum(tmpSym.P)), func(lsym *obj.LSym) {
+			lsym.P = tmpSym.P
+			lsym.Set(obj.AttrContentAddressable, true)
+		})
+	}
+	return makeSym(&argsSymTmp), makeSym(&liveSymTmp)
+}
+
+// Entry pointer for Compute analysis. Solves for the Compute of
+// pointer variables in the function and emits a runtime data
+// structure read by the garbage collector.
+// Returns a map from GC safe points to their corresponding stack map index,
+// and a map that contains all input parameters that may be partially live.
+func Compute(curfn *ir.Func, f *ssa.Func, stkptrsize int64, pp *objw.Progs) (Map, map[*ir.Name]bool) {
+	// Construct the global liveness state.
+	vars, idx := getvariables(curfn)
+	lv := newliveness(curfn, f, vars, idx, stkptrsize)
+
+	// Run the dataflow framework.
+	lv.prologue()
+	lv.solve()
+	lv.epilogue()
+	if base.Flag.Live > 0 {
+		lv.showlive(nil, lv.stackMaps[0])
+		for _, b := range f.Blocks {
+			for _, val := range b.Values {
+				if idx := lv.livenessMap.Get(val); idx.StackMapValid() {
+					lv.showlive(val, lv.stackMaps[idx.StackMapIndex])
+				}
+			}
+		}
+	}
+	if base.Flag.Live >= 2 {
+		lv.printDebug()
+	}
+
+	// Update the function cache.
+	{
+		cache := f.Cache.Liveness.(*livenessFuncCache)
+		if cap(lv.be) < 2000 { // Threshold from ssa.Cache slices.
+			for i := range lv.be {
+				lv.be[i] = blockEffects{}
+			}
+			cache.be = lv.be
+		}
+		if len(lv.livenessMap.Vals) < 2000 {
+			cache.livenessMap = lv.livenessMap
+		}
+	}
+
+	// Emit the live pointer map data structures
+	ls := curfn.LSym
+	fninfo := ls.Func()
+	fninfo.GCArgs, fninfo.GCLocals = lv.emit()
+
+	p := pp.Prog(obj.AFUNCDATA)
+	p.From.SetConst(objabi.FUNCDATA_ArgsPointerMaps)
+	p.To.Type = obj.TYPE_MEM
+	p.To.Name = obj.NAME_EXTERN
+	p.To.Sym = fninfo.GCArgs
+
+	p = pp.Prog(obj.AFUNCDATA)
+	p.From.SetConst(objabi.FUNCDATA_LocalsPointerMaps)
+	p.To.Type = obj.TYPE_MEM
+	p.To.Name = obj.NAME_EXTERN
+	p.To.Sym = fninfo.GCLocals
+
+	if x := lv.emitStackObjects(); x != nil {
+		p := pp.Prog(obj.AFUNCDATA)
+		p.From.SetConst(objabi.FUNCDATA_StackObjects)
+		p.To.Type = obj.TYPE_MEM
+		p.To.Name = obj.NAME_EXTERN
+		p.To.Sym = x
+	}
+
+	return lv.livenessMap, lv.partLiveArgs
+}
+
+func (lv *liveness) emitStackObjects() *obj.LSym {
+	var vars []*ir.Name
+	for _, n := range lv.fn.Dcl {
+		if shouldTrack(n) && n.Addrtaken() && n.Esc() != ir.EscHeap {
+			vars = append(vars, n)
+		}
+	}
+	if len(vars) == 0 {
+		return nil
+	}
+
+	// Sort variables from lowest to highest address.
+	sort.Slice(vars, func(i, j int) bool { return vars[i].FrameOffset() < vars[j].FrameOffset() })
+
+	// Populate the stack object data.
+	// Format must match runtime/stack.go:stackObjectRecord.
+	x := base.Ctxt.Lookup(lv.fn.LSym.Name + ".stkobj")
+	lv.fn.LSym.Func().StackObjects = x
+	off := 0
+	off = objw.Uintptr(x, off, uint64(len(vars)))
+	for _, v := range vars {
+		// Note: arguments and return values have non-negative Xoffset,
+		// in which case the offset is relative to argp.
+		// Locals have a negative Xoffset, in which case the offset is relative to varp.
+		// We already limit the frame size, so the offset and the object size
+		// should not be too big.
+		frameOffset := v.FrameOffset()
+		if frameOffset != int64(int32(frameOffset)) {
+			base.Fatalf("frame offset too big: %v %d", v, frameOffset)
+		}
+		off = objw.Uint32(x, off, uint32(frameOffset))
+
+		t := v.Type()
+		sz := t.Width
+		if sz != int64(int32(sz)) {
+			base.Fatalf("stack object too big: %v of type %v, size %d", v, t, sz)
+		}
+		lsym, useGCProg, ptrdata := reflectdata.GCSym(t)
+		if useGCProg {
+			ptrdata = -ptrdata
+		}
+		off = objw.Uint32(x, off, uint32(sz))
+		off = objw.Uint32(x, off, uint32(ptrdata))
+		off = objw.SymPtr(x, off, lsym, 0)
+	}
+
+	if base.Flag.Live != 0 {
+		for _, v := range vars {
+			base.WarnfAt(v.Pos(), "stack object %v %v", v, v.Type())
+		}
+	}
+
+	return x
+}
+
+// isfat reports whether a variable of type t needs multiple assignments to initialize.
+// For example:
+//
+// 	type T struct { x, y int }
+// 	x := T{x: 0, y: 1}
+//
+// Then we need:
+//
+// 	var t T
+// 	t.x = 0
+// 	t.y = 1
+//
+// to fully initialize t.
+func isfat(t *types.Type) bool {
+	if t != nil {
+		switch t.Kind() {
+		case types.TSLICE, types.TSTRING,
+			types.TINTER: // maybe remove later
+			return true
+		case types.TARRAY:
+			// Array of 1 element, check if element is fat
+			if t.NumElem() == 1 {
+				return isfat(t.Elem())
+			}
+			return true
+		case types.TSTRUCT:
+			// Struct with 1 field, check if field is fat
+			if t.NumFields() == 1 {
+				return isfat(t.Field(0).Type)
+			}
+			return true
+		}
+	}
+
+	return false
+}
+
+// WriteFuncMap writes the pointer bitmaps for bodyless function fn's
+// inputs and outputs as the value of symbol <fn>.args_stackmap.
+// If fn has outputs, two bitmaps are written, otherwise just one.
+func WriteFuncMap(fn *ir.Func, abiInfo *abi.ABIParamResultInfo) {
+	if ir.FuncName(fn) == "_" || fn.Sym().Linkname != "" {
+		return
+	}
+	nptr := int(abiInfo.ArgWidth() / int64(types.PtrSize))
+	bv := bitvec.New(int32(nptr) * 2)
+
+	for _, p := range abiInfo.InParams() {
+		typebits.Set(p.Type, p.FrameOffset(abiInfo), bv)
+	}
+
+	nbitmap := 1
+	if fn.Type().NumResults() > 0 {
+		nbitmap = 2
+	}
+	lsym := base.Ctxt.Lookup(fn.LSym.Name + ".args_stackmap")
+	off := objw.Uint32(lsym, 0, uint32(nbitmap))
+	off = objw.Uint32(lsym, off, uint32(bv.N))
+	off = objw.BitVec(lsym, off, bv)
+
+	if fn.Type().NumResults() > 0 {
+		for _, p := range abiInfo.OutParams() {
+			if len(p.Registers) == 0 {
+				typebits.Set(p.Type, p.FrameOffset(abiInfo), bv)
+			}
+		}
+		off = objw.BitVec(lsym, off, bv)
+	}
+
+	objw.Global(lsym, int32(off), obj.RODATA|obj.LOCAL)
+}
diff --git a/src/cmd/compile/internal/logopt/escape.go b/src/cmd/compile/internal/logopt/escape.go
index 802f967..9660e93 100644
--- a/src/cmd/compile/internal/logopt/escape.go
+++ b/src/cmd/compile/internal/logopt/escape.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.8
 // +build go1.8
 
 package logopt
diff --git a/src/cmd/compile/internal/logopt/escape_bootstrap.go b/src/cmd/compile/internal/logopt/escape_bootstrap.go
index 66ff0b8..cc04eaa 100644
--- a/src/cmd/compile/internal/logopt/escape_bootstrap.go
+++ b/src/cmd/compile/internal/logopt/escape_bootstrap.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !go1.8
 // +build !go1.8
 
 package logopt
diff --git a/src/cmd/compile/internal/logopt/log_opts.go b/src/cmd/compile/internal/logopt/log_opts.go
index 37a049d..97ebf56 100644
--- a/src/cmd/compile/internal/logopt/log_opts.go
+++ b/src/cmd/compile/internal/logopt/log_opts.go
@@ -6,10 +6,10 @@
 
 import (
 	"cmd/internal/obj"
-	"cmd/internal/objabi"
 	"cmd/internal/src"
 	"encoding/json"
 	"fmt"
+	"internal/buildcfg"
 	"io"
 	"log"
 	"net/url"
@@ -408,7 +408,7 @@
 	if !strings.HasPrefix(filename, "$GOROOT/") {
 		return filename
 	}
-	return objabi.GOROOT + filename[len("$GOROOT"):]
+	return buildcfg.GOROOT + filename[len("$GOROOT"):]
 }
 
 // FlushLoggedOpts flushes all the accumulated optimization log entries.
@@ -448,7 +448,7 @@
 				currentFile = p0f
 				w = writerForLSP(subdirpath, currentFile)
 				encoder = json.NewEncoder(w)
-				encoder.Encode(VersionHeader{Version: 0, Package: slashPkgPath, Goos: objabi.GOOS, Goarch: objabi.GOARCH, GcVersion: objabi.Version, File: currentFile})
+				encoder.Encode(VersionHeader{Version: 0, Package: slashPkgPath, Goos: buildcfg.GOOS, Goarch: buildcfg.GOARCH, GcVersion: buildcfg.Version, File: currentFile})
 			}
 
 			// The first "target" is the most important one.
diff --git a/src/cmd/compile/internal/logopt/logopt_test.go b/src/cmd/compile/internal/logopt/logopt_test.go
index e121c1a..7197617 100644
--- a/src/cmd/compile/internal/logopt/logopt_test.go
+++ b/src/cmd/compile/internal/logopt/logopt_test.go
@@ -132,7 +132,7 @@
 	// Check at both 1 and 8-byte alignments.
 	t.Run("Copy", func(t *testing.T) {
 		const copyCode = `package x
-func s128a1(x *[128]int8) [128]int8 { 
+func s128a1(x *[128]int8) [128]int8 {
 	return *x
 }
 func s127a1(x *[127]int8) [127]int8 {
@@ -219,7 +219,7 @@
 			`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":4,"character":11},"end":{"line":4,"character":11}}},"message":"inlineLoc"},`+
 			`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow:      from \u0026y.b (address-of)"},`+
 			`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":4,"character":9},"end":{"line":4,"character":9}}},"message":"inlineLoc"},`+
-			`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow:      from ~R0 = \u003cN\u003e (assign-pair)"},`+
+			`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow:      from ~R0 = \u0026y.b (assign-pair)"},`+
 			`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow:    flow: ~r2 = ~R0:"},`+
 			`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow:      from return (*int)(~R0) (return)"}]}`)
 	})
diff --git a/src/cmd/compile/internal/mips/galign.go b/src/cmd/compile/internal/mips/galign.go
index be40c16..f892923 100644
--- a/src/cmd/compile/internal/mips/galign.go
+++ b/src/cmd/compile/internal/mips/galign.go
@@ -5,24 +5,24 @@
 package mips
 
 import (
-	"cmd/compile/internal/gc"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/internal/obj/mips"
-	"cmd/internal/objabi"
+	"internal/buildcfg"
 )
 
-func Init(arch *gc.Arch) {
+func Init(arch *ssagen.ArchInfo) {
 	arch.LinkArch = &mips.Linkmips
-	if objabi.GOARCH == "mipsle" {
+	if buildcfg.GOARCH == "mipsle" {
 		arch.LinkArch = &mips.Linkmipsle
 	}
 	arch.REGSP = mips.REGSP
 	arch.MAXWIDTH = (1 << 31) - 1
-	arch.SoftFloat = (objabi.GOMIPS == "softfloat")
+	arch.SoftFloat = (buildcfg.GOMIPS == "softfloat")
 	arch.ZeroRange = zerorange
 	arch.Ginsnop = ginsnop
 	arch.Ginsnopdefer = ginsnop
-	arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
+	arch.SSAMarkMoves = func(s *ssagen.State, b *ssa.Block) {}
 	arch.SSAGenValue = ssaGenValue
 	arch.SSAGenBlock = ssaGenBlock
 }
diff --git a/src/cmd/compile/internal/mips/ggen.go b/src/cmd/compile/internal/mips/ggen.go
index 5e86772..1a51252 100644
--- a/src/cmd/compile/internal/mips/ggen.go
+++ b/src/cmd/compile/internal/mips/ggen.go
@@ -5,20 +5,22 @@
 package mips
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/mips"
 )
 
 // TODO(mips): implement DUFFZERO
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
 
 	if cnt == 0 {
 		return p
 	}
-	if cnt < int64(4*gc.Widthptr) {
-		for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
-			p = pp.Appendpp(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, gc.Ctxt.FixedFrameSize()+off+i)
+	if cnt < int64(4*types.PtrSize) {
+		for i := int64(0); i < cnt; i += int64(types.PtrSize) {
+			p = pp.Append(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, base.Ctxt.FixedFrameSize()+off+i)
 		}
 	} else {
 		//fmt.Printf("zerorange frame:%v, lo: %v, hi:%v \n", frame ,lo, hi)
@@ -28,22 +30,22 @@
 		//	MOVW	R0, (Widthptr)r1
 		//	ADD 	$Widthptr, r1
 		//	BNE		r1, r2, loop
-		p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+off-4, obj.TYPE_REG, mips.REGRT1, 0)
+		p = pp.Append(p, mips.AADD, obj.TYPE_CONST, 0, base.Ctxt.FixedFrameSize()+off-4, obj.TYPE_REG, mips.REGRT1, 0)
 		p.Reg = mips.REGSP
-		p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
+		p = pp.Append(p, mips.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
 		p.Reg = mips.REGRT1
-		p = pp.Appendpp(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGRT1, int64(gc.Widthptr))
+		p = pp.Append(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGRT1, int64(types.PtrSize))
 		p1 := p
-		p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, int64(gc.Widthptr), obj.TYPE_REG, mips.REGRT1, 0)
-		p = pp.Appendpp(p, mips.ABNE, obj.TYPE_REG, mips.REGRT1, 0, obj.TYPE_BRANCH, 0, 0)
+		p = pp.Append(p, mips.AADD, obj.TYPE_CONST, 0, int64(types.PtrSize), obj.TYPE_REG, mips.REGRT1, 0)
+		p = pp.Append(p, mips.ABNE, obj.TYPE_REG, mips.REGRT1, 0, obj.TYPE_BRANCH, 0, 0)
 		p.Reg = mips.REGRT2
-		gc.Patch(p, p1)
+		p.To.SetTarget(p1)
 	}
 
 	return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
 	p := pp.Prog(mips.ANOR)
 	p.From.Type = obj.TYPE_REG
 	p.From.Reg = mips.REG_R0
diff --git a/src/cmd/compile/internal/mips/ssa.go b/src/cmd/compile/internal/mips/ssa.go
index 9d11c6b..e0447f3 100644
--- a/src/cmd/compile/internal/mips/ssa.go
+++ b/src/cmd/compile/internal/mips/ssa.go
@@ -7,9 +7,11 @@
 import (
 	"math"
 
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/logopt"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/mips"
@@ -75,7 +77,7 @@
 	panic("bad store type")
 }
 
-func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
+func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 	switch v.Op {
 	case ssa.OpCopy, ssa.OpMIPSMOVWreg:
 		t := v.Type
@@ -110,9 +112,6 @@
 			p.To.Reg = y
 		}
 	case ssa.OpMIPSMOVWnop:
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		// nothing to do
 	case ssa.OpLoadReg:
 		if v.Type.IsFlags() {
@@ -121,7 +120,7 @@
 		}
 		r := v.Reg()
 		p := s.Prog(loadByType(v.Type, r))
-		gc.AddrAuto(&p.From, v.Args[0])
+		ssagen.AddrAuto(&p.From, v.Args[0])
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
 		if isHILO(r) {
@@ -151,7 +150,7 @@
 		p := s.Prog(storeByType(v.Type, r))
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = r
-		gc.AddrAuto(&p.To, v)
+		ssagen.AddrAuto(&p.To, v)
 	case ssa.OpMIPSADD,
 		ssa.OpMIPSSUB,
 		ssa.OpMIPSAND,
@@ -242,9 +241,6 @@
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpMIPSCMOVZ:
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[2].Reg()
@@ -252,9 +248,6 @@
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpMIPSCMOVZzero:
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[1].Reg()
@@ -286,10 +279,10 @@
 			v.Fatalf("aux is of unknown type %T", v.Aux)
 		case *obj.LSym:
 			wantreg = "SB"
-			gc.AddAux(&p.From, v)
-		case *gc.Node:
+			ssagen.AddAux(&p.From, v)
+		case *ir.Name:
 			wantreg = "SP"
-			gc.AddAux(&p.From, v)
+			ssagen.AddAux(&p.From, v)
 		case nil:
 			// No sym, just MOVW $off(SP), R
 			wantreg = "SP"
@@ -310,7 +303,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpMIPSMOVBstore,
@@ -323,7 +316,7 @@
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpMIPSMOVBstorezero,
 		ssa.OpMIPSMOVHstorezero,
 		ssa.OpMIPSMOVWstorezero:
@@ -332,7 +325,7 @@
 		p.From.Reg = mips.REGZERO
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpMIPSMOVBreg,
 		ssa.OpMIPSMOVBUreg,
 		ssa.OpMIPSMOVHreg,
@@ -370,6 +363,7 @@
 		ssa.OpMIPSMOVDF,
 		ssa.OpMIPSNEGF,
 		ssa.OpMIPSNEGD,
+		ssa.OpMIPSSQRTF,
 		ssa.OpMIPSSQRTD,
 		ssa.OpMIPSCLZ:
 		p := s.Prog(v.Op.Asm())
@@ -425,7 +419,7 @@
 		p4.From.Reg = v.Args[1].Reg()
 		p4.Reg = mips.REG_R1
 		p4.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p4, p2)
+		p4.To.SetTarget(p2)
 	case ssa.OpMIPSLoweredMove:
 		// SUBU	$4, R1
 		// MOVW	4(R1), Rtmp
@@ -478,7 +472,7 @@
 		p6.From.Reg = v.Args[2].Reg()
 		p6.Reg = mips.REG_R1
 		p6.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p6, p2)
+		p6.To.SetTarget(p2)
 	case ssa.OpMIPSCALLstatic, ssa.OpMIPSCALLclosure, ssa.OpMIPSCALLinter:
 		s.Call(v)
 	case ssa.OpMIPSLoweredWB:
@@ -490,13 +484,13 @@
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+		p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
 		s.UseArgs(8) // space used in callee args area by assembly stubs
 	case ssa.OpMIPSLoweredPanicExtendA, ssa.OpMIPSLoweredPanicExtendB, ssa.OpMIPSLoweredPanicExtendC:
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.ExtendCheckFunc[v.AuxInt]
+		p.To.Sym = ssagen.ExtendCheckFunc[v.AuxInt]
 		s.UseArgs(12) // space used in callee args area by assembly stubs
 	case ssa.OpMIPSLoweredAtomicLoad8,
 		ssa.OpMIPSLoweredAtomicLoad32:
@@ -575,7 +569,7 @@
 		p3.From.Type = obj.TYPE_REG
 		p3.From.Reg = mips.REGTMP
 		p3.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 
 		s.Prog(mips.ASYNC)
 	case ssa.OpMIPSLoweredAtomicAdd:
@@ -611,7 +605,7 @@
 		p3.From.Type = obj.TYPE_REG
 		p3.From.Reg = mips.REGTMP
 		p3.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 
 		s.Prog(mips.ASYNC)
 
@@ -655,7 +649,7 @@
 		p3.From.Type = obj.TYPE_REG
 		p3.From.Reg = mips.REGTMP
 		p3.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 
 		s.Prog(mips.ASYNC)
 
@@ -699,7 +693,7 @@
 		p3.From.Type = obj.TYPE_REG
 		p3.From.Reg = mips.REGTMP
 		p3.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 
 		s.Prog(mips.ASYNC)
 
@@ -748,26 +742,26 @@
 		p5.From.Type = obj.TYPE_REG
 		p5.From.Reg = v.Reg0()
 		p5.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p5, p1)
+		p5.To.SetTarget(p1)
 
 		s.Prog(mips.ASYNC)
 
 		p6 := s.Prog(obj.ANOP)
-		gc.Patch(p2, p6)
+		p2.To.SetTarget(p6)
 
 	case ssa.OpMIPSLoweredNilCheck:
 		// Issue a load which will fault if arg is nil.
 		p := s.Prog(mips.AMOVB)
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = mips.REGTMP
 		if logopt.Enabled() {
 			logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
 		}
-		if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
-			gc.Warnl(v.Pos, "generated nil check")
+		if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
+			base.WarnfAt(v.Pos, "generated nil check")
 		}
 	case ssa.OpMIPSFPFlagTrue,
 		ssa.OpMIPSFPFlagFalse:
@@ -791,12 +785,12 @@
 
 	case ssa.OpMIPSLoweredGetClosurePtr:
 		// Closure pointer is R22 (mips.REGCTXT).
-		gc.CheckLoweredGetClosurePtr(v)
+		ssagen.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.Offset = -base.Ctxt.FixedFrameSize()
 		p.From.Name = obj.NAME_PARAM
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
@@ -804,7 +798,7 @@
 		p := s.Prog(obj.AGETCALLERPC)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
-	case ssa.OpClobber:
+	case ssa.OpClobber, ssa.OpClobberReg:
 		// TODO: implement for clobberdead experiment. Nop is ok for now.
 	default:
 		v.Fatalf("genValue not implemented: %s", v.LongString())
@@ -824,13 +818,13 @@
 	ssa.BlockMIPSFPF: {mips.ABFPF, mips.ABFPT},
 }
 
-func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
+func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
 	switch b.Kind {
 	case ssa.BlockPlain:
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 	case ssa.BlockDefer:
 		// defer returns in R1:
@@ -841,11 +835,11 @@
 		p.From.Reg = mips.REGZERO
 		p.Reg = mips.REG_R1
 		p.To.Type = obj.TYPE_BRANCH
-		s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+		s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[1].Block()})
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 	case ssa.BlockExit:
 	case ssa.BlockRet:
diff --git a/src/cmd/compile/internal/mips64/galign.go b/src/cmd/compile/internal/mips64/galign.go
index 90c381a..af81366 100644
--- a/src/cmd/compile/internal/mips64/galign.go
+++ b/src/cmd/compile/internal/mips64/galign.go
@@ -5,25 +5,25 @@
 package mips64
 
 import (
-	"cmd/compile/internal/gc"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/internal/obj/mips"
-	"cmd/internal/objabi"
+	"internal/buildcfg"
 )
 
-func Init(arch *gc.Arch) {
+func Init(arch *ssagen.ArchInfo) {
 	arch.LinkArch = &mips.Linkmips64
-	if objabi.GOARCH == "mips64le" {
+	if buildcfg.GOARCH == "mips64le" {
 		arch.LinkArch = &mips.Linkmips64le
 	}
 	arch.REGSP = mips.REGSP
 	arch.MAXWIDTH = 1 << 50
-	arch.SoftFloat = objabi.GOMIPS64 == "softfloat"
+	arch.SoftFloat = buildcfg.GOMIPS64 == "softfloat"
 	arch.ZeroRange = zerorange
 	arch.Ginsnop = ginsnop
 	arch.Ginsnopdefer = ginsnop
 
-	arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
+	arch.SSAMarkMoves = func(s *ssagen.State, b *ssa.Block) {}
 	arch.SSAGenValue = ssaGenValue
 	arch.SSAGenBlock = ssaGenBlock
 }
diff --git a/src/cmd/compile/internal/mips64/ggen.go b/src/cmd/compile/internal/mips64/ggen.go
index 04e7a66..37bb871 100644
--- a/src/cmd/compile/internal/mips64/ggen.go
+++ b/src/cmd/compile/internal/mips64/ggen.go
@@ -5,26 +5,28 @@
 package mips64
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/mips"
 )
 
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
 	if cnt == 0 {
 		return p
 	}
-	if cnt < int64(4*gc.Widthptr) {
-		for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
-			p = pp.Appendpp(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, 8+off+i)
+	if cnt < int64(4*types.PtrSize) {
+		for i := int64(0); i < cnt; i += int64(types.PtrSize) {
+			p = pp.Append(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, 8+off+i)
 		}
-	} else if cnt <= int64(128*gc.Widthptr) {
-		p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, mips.REGRT1, 0)
+	} else if cnt <= int64(128*types.PtrSize) {
+		p = pp.Append(p, mips.AADDV, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, mips.REGRT1, 0)
 		p.Reg = mips.REGSP
-		p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
+		p = pp.Append(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 = 8 * (128 - cnt/int64(gc.Widthptr))
+		p.To.Sym = ir.Syms.Duffzero
+		p.To.Offset = 8 * (128 - cnt/int64(types.PtrSize))
 	} else {
 		//	ADDV	$(8+frame+lo-8), SP, r1
 		//	ADDV	$cnt, r1, r2
@@ -32,22 +34,22 @@
 		//	MOVV	R0, (Widthptr)r1
 		//	ADDV	$Widthptr, r1
 		//	BNE		r1, r2, loop
-		p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, mips.REGRT1, 0)
+		p = pp.Append(p, mips.AADDV, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, mips.REGRT1, 0)
 		p.Reg = mips.REGSP
-		p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
+		p = pp.Append(p, mips.AADDV, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
 		p.Reg = mips.REGRT1
-		p = pp.Appendpp(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGRT1, int64(gc.Widthptr))
+		p = pp.Append(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGRT1, int64(types.PtrSize))
 		p1 := p
-		p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, int64(gc.Widthptr), obj.TYPE_REG, mips.REGRT1, 0)
-		p = pp.Appendpp(p, mips.ABNE, obj.TYPE_REG, mips.REGRT1, 0, obj.TYPE_BRANCH, 0, 0)
+		p = pp.Append(p, mips.AADDV, obj.TYPE_CONST, 0, int64(types.PtrSize), obj.TYPE_REG, mips.REGRT1, 0)
+		p = pp.Append(p, mips.ABNE, obj.TYPE_REG, mips.REGRT1, 0, obj.TYPE_BRANCH, 0, 0)
 		p.Reg = mips.REGRT2
-		gc.Patch(p, p1)
+		p.To.SetTarget(p1)
 	}
 
 	return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
 	p := pp.Prog(mips.ANOR)
 	p.From.Type = obj.TYPE_REG
 	p.From.Reg = mips.REG_R0
diff --git a/src/cmd/compile/internal/mips64/ssa.go b/src/cmd/compile/internal/mips64/ssa.go
index 2727c4d..e821a00 100644
--- a/src/cmd/compile/internal/mips64/ssa.go
+++ b/src/cmd/compile/internal/mips64/ssa.go
@@ -7,9 +7,11 @@
 import (
 	"math"
 
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/logopt"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/mips"
@@ -83,7 +85,7 @@
 	panic("bad store type")
 }
 
-func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
+func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 	switch v.Op {
 	case ssa.OpCopy, ssa.OpMIPS64MOVVreg:
 		if v.Type.IsMemory() {
@@ -113,9 +115,6 @@
 			p.To.Reg = y
 		}
 	case ssa.OpMIPS64MOVVnop:
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		// nothing to do
 	case ssa.OpLoadReg:
 		if v.Type.IsFlags() {
@@ -124,7 +123,7 @@
 		}
 		r := v.Reg()
 		p := s.Prog(loadByType(v.Type, r))
-		gc.AddrAuto(&p.From, v.Args[0])
+		ssagen.AddrAuto(&p.From, v.Args[0])
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
 		if isHILO(r) {
@@ -154,7 +153,7 @@
 		p := s.Prog(storeByType(v.Type, r))
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = r
-		gc.AddrAuto(&p.To, v)
+		ssagen.AddrAuto(&p.To, v)
 	case ssa.OpMIPS64ADDV,
 		ssa.OpMIPS64SUBV,
 		ssa.OpMIPS64AND,
@@ -260,10 +259,10 @@
 			v.Fatalf("aux is of unknown type %T", v.Aux)
 		case *obj.LSym:
 			wantreg = "SB"
-			gc.AddAux(&p.From, v)
-		case *gc.Node:
+			ssagen.AddAux(&p.From, v)
+		case *ir.Name:
 			wantreg = "SP"
-			gc.AddAux(&p.From, v)
+			ssagen.AddAux(&p.From, v)
 		case nil:
 			// No sym, just MOVV $off(SP), R
 			wantreg = "SP"
@@ -286,7 +285,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpMIPS64MOVBstore,
@@ -300,7 +299,7 @@
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpMIPS64MOVBstorezero,
 		ssa.OpMIPS64MOVHstorezero,
 		ssa.OpMIPS64MOVWstorezero,
@@ -310,7 +309,7 @@
 		p.From.Reg = mips.REGZERO
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpMIPS64MOVBreg,
 		ssa.OpMIPS64MOVBUreg,
 		ssa.OpMIPS64MOVHreg,
@@ -356,6 +355,7 @@
 		ssa.OpMIPS64MOVDF,
 		ssa.OpMIPS64NEGF,
 		ssa.OpMIPS64NEGD,
+		ssa.OpMIPS64SQRTF,
 		ssa.OpMIPS64SQRTD:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
@@ -381,7 +381,7 @@
 		p = s.Prog(obj.ADUFFZERO)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.Duffzero
+		p.To.Sym = ir.Syms.Duffzero
 		p.To.Offset = v.AuxInt
 	case ssa.OpMIPS64LoweredZero:
 		// SUBV	$8, R1
@@ -426,12 +426,12 @@
 		p4.From.Reg = v.Args[1].Reg()
 		p4.Reg = mips.REG_R1
 		p4.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p4, p2)
+		p4.To.SetTarget(p2)
 	case ssa.OpMIPS64DUFFCOPY:
 		p := s.Prog(obj.ADUFFCOPY)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.Duffcopy
+		p.To.Sym = ir.Syms.Duffcopy
 		p.To.Offset = v.AuxInt
 	case ssa.OpMIPS64LoweredMove:
 		// SUBV	$8, R1
@@ -488,7 +488,7 @@
 		p6.From.Reg = v.Args[2].Reg()
 		p6.Reg = mips.REG_R1
 		p6.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p6, p2)
+		p6.To.SetTarget(p2)
 	case ssa.OpMIPS64CALLstatic, ssa.OpMIPS64CALLclosure, ssa.OpMIPS64CALLinter:
 		s.Call(v)
 	case ssa.OpMIPS64LoweredWB:
@@ -500,7 +500,7 @@
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+		p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
 		s.UseArgs(16) // space used in callee args area by assembly stubs
 	case ssa.OpMIPS64LoweredAtomicLoad8, ssa.OpMIPS64LoweredAtomicLoad32, ssa.OpMIPS64LoweredAtomicLoad64:
 		as := mips.AMOVV
@@ -577,7 +577,7 @@
 		p3.From.Type = obj.TYPE_REG
 		p3.From.Reg = mips.REGTMP
 		p3.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 		s.Prog(mips.ASYNC)
 	case ssa.OpMIPS64LoweredAtomicAdd32, ssa.OpMIPS64LoweredAtomicAdd64:
 		// SYNC
@@ -614,7 +614,7 @@
 		p3.From.Type = obj.TYPE_REG
 		p3.From.Reg = mips.REGTMP
 		p3.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 		s.Prog(mips.ASYNC)
 		p4 := s.Prog(mips.AADDVU)
 		p4.From.Type = obj.TYPE_REG
@@ -657,7 +657,7 @@
 		p3.From.Type = obj.TYPE_REG
 		p3.From.Reg = mips.REGTMP
 		p3.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 		s.Prog(mips.ASYNC)
 		p4 := s.Prog(mips.AADDVU)
 		p4.From.Type = obj.TYPE_CONST
@@ -710,22 +710,22 @@
 		p5.From.Type = obj.TYPE_REG
 		p5.From.Reg = v.Reg0()
 		p5.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p5, p1)
+		p5.To.SetTarget(p1)
 		p6 := s.Prog(mips.ASYNC)
-		gc.Patch(p2, p6)
+		p2.To.SetTarget(p6)
 	case ssa.OpMIPS64LoweredNilCheck:
 		// Issue a load which will fault if arg is nil.
 		p := s.Prog(mips.AMOVB)
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = mips.REGTMP
 		if logopt.Enabled() {
 			logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
 		}
-		if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
-			gc.Warnl(v.Pos, "generated nil check")
+		if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
+			base.WarnfAt(v.Pos, "generated nil check")
 		}
 	case ssa.OpMIPS64FPFlagTrue,
 		ssa.OpMIPS64FPFlagFalse:
@@ -749,15 +749,15 @@
 		p3.To.Type = obj.TYPE_REG
 		p3.To.Reg = v.Reg()
 		p4 := s.Prog(obj.ANOP) // not a machine instruction, for branch to land
-		gc.Patch(p2, p4)
+		p2.To.SetTarget(p4)
 	case ssa.OpMIPS64LoweredGetClosurePtr:
 		// Closure pointer is R22 (mips.REGCTXT).
-		gc.CheckLoweredGetClosurePtr(v)
+		ssagen.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.Offset = -base.Ctxt.FixedFrameSize()
 		p.From.Name = obj.NAME_PARAM
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
@@ -765,7 +765,7 @@
 		p := s.Prog(obj.AGETCALLERPC)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
-	case ssa.OpClobber:
+	case ssa.OpClobber, ssa.OpClobberReg:
 		// TODO: implement for clobberdead experiment. Nop is ok for now.
 	default:
 		v.Fatalf("genValue not implemented: %s", v.LongString())
@@ -785,13 +785,13 @@
 	ssa.BlockMIPS64FPF: {mips.ABFPF, mips.ABFPT},
 }
 
-func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
+func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
 	switch b.Kind {
 	case ssa.BlockPlain:
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 	case ssa.BlockDefer:
 		// defer returns in R1:
@@ -802,11 +802,11 @@
 		p.From.Reg = mips.REGZERO
 		p.Reg = mips.REG_R1
 		p.To.Type = obj.TYPE_BRANCH
-		s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+		s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[1].Block()})
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 	case ssa.BlockExit:
 	case ssa.BlockRet:
diff --git a/src/cmd/compile/internal/noder/decl.go b/src/cmd/compile/internal/noder/decl.go
new file mode 100644
index 0000000..4ca2eb4
--- /dev/null
+++ b/src/cmd/compile/internal/noder/decl.go
@@ -0,0 +1,260 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"go/constant"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/compile/internal/types2"
+)
+
+// TODO(mdempsky): Skip blank declarations? Probably only safe
+// for declarations without pragmas.
+
+func (g *irgen) decls(decls []syntax.Decl) []ir.Node {
+	var res ir.Nodes
+	for _, decl := range decls {
+		switch decl := decl.(type) {
+		case *syntax.ConstDecl:
+			g.constDecl(&res, decl)
+		case *syntax.FuncDecl:
+			g.funcDecl(&res, decl)
+		case *syntax.TypeDecl:
+			if ir.CurFunc == nil {
+				continue // already handled in irgen.generate
+			}
+			g.typeDecl(&res, decl)
+		case *syntax.VarDecl:
+			g.varDecl(&res, decl)
+		default:
+			g.unhandled("declaration", decl)
+		}
+	}
+	return res
+}
+
+func (g *irgen) importDecl(p *noder, decl *syntax.ImportDecl) {
+	// TODO(mdempsky): Merge with gcimports so we don't have to import
+	// packages twice.
+
+	g.pragmaFlags(decl.Pragma, 0)
+
+	ipkg := importfile(decl)
+	if ipkg == ir.Pkgs.Unsafe {
+		p.importedUnsafe = true
+	}
+	if ipkg.Path == "embed" {
+		p.importedEmbed = true
+	}
+}
+
+func (g *irgen) constDecl(out *ir.Nodes, decl *syntax.ConstDecl) {
+	g.pragmaFlags(decl.Pragma, 0)
+
+	for _, name := range decl.NameList {
+		name, obj := g.def(name)
+
+		// For untyped numeric constants, make sure the value
+		// representation matches what the rest of the
+		// compiler (really just iexport) expects.
+		// TODO(mdempsky): Revisit after #43891 is resolved.
+		val := obj.(*types2.Const).Val()
+		switch name.Type() {
+		case types.UntypedInt, types.UntypedRune:
+			val = constant.ToInt(val)
+		case types.UntypedFloat:
+			val = constant.ToFloat(val)
+		case types.UntypedComplex:
+			val = constant.ToComplex(val)
+		}
+		name.SetVal(val)
+
+		out.Append(ir.NewDecl(g.pos(decl), ir.ODCLCONST, name))
+	}
+}
+
+func (g *irgen) funcDecl(out *ir.Nodes, decl *syntax.FuncDecl) {
+	fn := ir.NewFunc(g.pos(decl))
+	fn.Nname, _ = g.def(decl.Name)
+	fn.Nname.Func = fn
+	fn.Nname.Defn = fn
+
+	fn.Pragma = g.pragmaFlags(decl.Pragma, funcPragmas)
+	if fn.Pragma&ir.Systemstack != 0 && fn.Pragma&ir.Nosplit != 0 {
+		base.ErrorfAt(fn.Pos(), "go:nosplit and go:systemstack cannot be combined")
+	}
+
+	if decl.Name.Value == "init" && decl.Recv == nil {
+		g.target.Inits = append(g.target.Inits, fn)
+	}
+
+	g.funcBody(fn, decl.Recv, decl.Type, decl.Body)
+
+	out.Append(fn)
+}
+
+func (g *irgen) typeDecl(out *ir.Nodes, decl *syntax.TypeDecl) {
+	if decl.Alias {
+		name, _ := g.def(decl.Name)
+		g.pragmaFlags(decl.Pragma, 0)
+
+		// TODO(mdempsky): This matches how typecheckdef marks aliases for
+		// export, but this won't generalize to exporting function-scoped
+		// type aliases. We should maybe just use n.Alias() instead.
+		if ir.CurFunc == nil {
+			name.Sym().Def = ir.TypeNode(name.Type())
+		}
+
+		out.Append(ir.NewDecl(g.pos(decl), ir.ODCLTYPE, name))
+		return
+	}
+
+	// Prevent size calculations until we set the underlying type.
+	types.DeferCheckSize()
+
+	name, obj := g.def(decl.Name)
+	ntyp, otyp := name.Type(), obj.Type()
+	if ir.CurFunc != nil {
+		typecheck.TypeGen++
+		ntyp.Vargen = typecheck.TypeGen
+	}
+
+	pragmas := g.pragmaFlags(decl.Pragma, typePragmas)
+	name.SetPragma(pragmas) // TODO(mdempsky): Is this still needed?
+
+	if pragmas&ir.NotInHeap != 0 {
+		ntyp.SetNotInHeap(true)
+	}
+
+	// We need to use g.typeExpr(decl.Type) here to ensure that for
+	// chained, defined-type declarations like:
+	//
+	//	type T U
+	//
+	//	//go:notinheap
+	//	type U struct { … }
+	//
+	// we mark both T and U as NotInHeap. If we instead used just
+	// g.typ(otyp.Underlying()), then we'd instead set T's underlying
+	// type directly to the struct type (which is not marked NotInHeap)
+	// and fail to mark T as NotInHeap.
+	//
+	// Also, we rely here on Type.SetUnderlying allowing passing a
+	// defined type and handling forward references like from T to U
+	// above. Contrast with go/types's Named.SetUnderlying, which
+	// disallows this.
+	//
+	// [mdempsky: Subtleties like these are why I always vehemently
+	// object to new type pragmas.]
+	ntyp.SetUnderlying(g.typeExpr(decl.Type))
+	if len(decl.TParamList) > 0 {
+		// Set HasTParam if there are any tparams, even if no tparams are
+		// used in the type itself (e.g., if it is an empty struct, or no
+		// fields in the struct use the tparam).
+		ntyp.SetHasTParam(true)
+	}
+	types.ResumeCheckSize()
+
+	if otyp, ok := otyp.(*types2.Named); ok && otyp.NumMethods() != 0 {
+		methods := make([]*types.Field, otyp.NumMethods())
+		for i := range methods {
+			m := otyp.Method(i)
+			meth := g.obj(m)
+			methods[i] = types.NewField(meth.Pos(), g.selector(m), meth.Type())
+			methods[i].Nname = meth
+		}
+		ntyp.Methods().Set(methods)
+	}
+
+	out.Append(ir.NewDecl(g.pos(decl), ir.ODCLTYPE, name))
+}
+
+func (g *irgen) varDecl(out *ir.Nodes, decl *syntax.VarDecl) {
+	pos := g.pos(decl)
+	names := make([]*ir.Name, len(decl.NameList))
+	for i, name := range decl.NameList {
+		names[i], _ = g.def(name)
+	}
+	values := g.exprList(decl.Values)
+
+	if decl.Pragma != nil {
+		pragma := decl.Pragma.(*pragmas)
+		// TODO(mdempsky): Plumb noder.importedEmbed through to here.
+		varEmbed(g.makeXPos, names[0], decl, pragma, true)
+		g.reportUnused(pragma)
+	}
+
+	var as2 *ir.AssignListStmt
+	if len(values) != 0 && len(names) != len(values) {
+		as2 = ir.NewAssignListStmt(pos, ir.OAS2, make([]ir.Node, len(names)), values)
+	}
+
+	for i, name := range names {
+		if ir.CurFunc != nil {
+			out.Append(ir.NewDecl(pos, ir.ODCL, name))
+		}
+		if as2 != nil {
+			as2.Lhs[i] = name
+			name.Defn = as2
+		} else {
+			as := ir.NewAssignStmt(pos, name, nil)
+			if len(values) != 0 {
+				as.Y = values[i]
+				name.Defn = as
+			} else if ir.CurFunc == nil {
+				name.Defn = as
+			}
+			lhs := []ir.Node{as.X}
+			rhs := []ir.Node{}
+			if as.Y != nil {
+				rhs = []ir.Node{as.Y}
+			}
+			transformAssign(as, lhs, rhs)
+			as.X = lhs[0]
+			if as.Y != nil {
+				as.Y = rhs[0]
+			}
+			as.SetTypecheck(1)
+			out.Append(as)
+		}
+	}
+	if as2 != nil {
+		transformAssign(as2, as2.Lhs, as2.Rhs)
+		as2.SetTypecheck(1)
+		out.Append(as2)
+	}
+}
+
+// pragmaFlags returns any specified pragma flags included in allowed,
+// and reports errors about any other, unexpected pragmas.
+func (g *irgen) pragmaFlags(pragma syntax.Pragma, allowed ir.PragmaFlag) ir.PragmaFlag {
+	if pragma == nil {
+		return 0
+	}
+	p := pragma.(*pragmas)
+	present := p.Flag & allowed
+	p.Flag &^= allowed
+	g.reportUnused(p)
+	return present
+}
+
+// reportUnused reports errors about any unused pragmas.
+func (g *irgen) reportUnused(pragma *pragmas) {
+	for _, pos := range pragma.Pos {
+		if pos.Flag&pragma.Flag != 0 {
+			base.ErrorfAt(g.makeXPos(pos.Pos), "misplaced compiler directive")
+		}
+	}
+	if len(pragma.Embeds) > 0 {
+		for _, e := range pragma.Embeds {
+			base.ErrorfAt(g.makeXPos(e.Pos), "misplaced go:embed directive")
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/noder/expr.go b/src/cmd/compile/internal/noder/expr.go
new file mode 100644
index 0000000..c7695ed
--- /dev/null
+++ b/src/cmd/compile/internal/noder/expr.go
@@ -0,0 +1,400 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/compile/internal/types2"
+	"cmd/internal/src"
+)
+
+func (g *irgen) expr(expr syntax.Expr) ir.Node {
+	if expr == nil {
+		return nil
+	}
+
+	if expr, ok := expr.(*syntax.Name); ok && expr.Value == "_" {
+		return ir.BlankNode
+	}
+
+	tv, ok := g.info.Types[expr]
+	if !ok {
+		base.FatalfAt(g.pos(expr), "missing type for %v (%T)", expr, expr)
+	}
+	switch {
+	case tv.IsBuiltin():
+		// Qualified builtins, such as unsafe.Add and unsafe.Slice.
+		if expr, ok := expr.(*syntax.SelectorExpr); ok {
+			if name, ok := expr.X.(*syntax.Name); ok {
+				if _, ok := g.info.Uses[name].(*types2.PkgName); ok {
+					return g.use(expr.Sel)
+				}
+			}
+		}
+		return g.use(expr.(*syntax.Name))
+	case tv.IsType():
+		return ir.TypeNode(g.typ(tv.Type))
+	case tv.IsValue(), tv.IsVoid():
+		// ok
+	default:
+		base.FatalfAt(g.pos(expr), "unrecognized type-checker result")
+	}
+
+	// The gc backend expects all expressions to have a concrete type, and
+	// types2 mostly satisfies this expectation already. But there are a few
+	// cases where the Go spec doesn't require converting to concrete type,
+	// and so types2 leaves them untyped. So we need to fix those up here.
+	typ := tv.Type
+	if basic, ok := typ.(*types2.Basic); ok && basic.Info()&types2.IsUntyped != 0 {
+		switch basic.Kind() {
+		case types2.UntypedNil:
+			// ok; can appear in type switch case clauses
+			// TODO(mdempsky): Handle as part of type switches instead?
+		case types2.UntypedBool:
+			typ = types2.Typ[types2.Bool] // expression in "if" or "for" condition
+		case types2.UntypedString:
+			typ = types2.Typ[types2.String] // argument to "append" or "copy" calls
+		default:
+			base.FatalfAt(g.pos(expr), "unexpected untyped type: %v", basic)
+		}
+	}
+
+	// Constant expression.
+	if tv.Value != nil {
+		return Const(g.pos(expr), g.typ(typ), tv.Value)
+	}
+
+	n := g.expr0(typ, expr)
+	if n.Typecheck() != 1 && n.Typecheck() != 3 {
+		base.FatalfAt(g.pos(expr), "missed typecheck: %+v", n)
+	}
+	if !g.match(n.Type(), typ, tv.HasOk()) {
+		base.FatalfAt(g.pos(expr), "expected %L to have type %v", n, typ)
+	}
+	return n
+}
+
+func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node {
+	pos := g.pos(expr)
+
+	switch expr := expr.(type) {
+	case *syntax.Name:
+		if _, isNil := g.info.Uses[expr].(*types2.Nil); isNil {
+			return Nil(pos, g.typ(typ))
+		}
+		return g.use(expr)
+
+	case *syntax.CompositeLit:
+		return g.compLit(typ, expr)
+
+	case *syntax.FuncLit:
+		return g.funcLit(typ, expr)
+
+	case *syntax.AssertExpr:
+		return Assert(pos, g.expr(expr.X), g.typeExpr(expr.Type))
+
+	case *syntax.CallExpr:
+		fun := g.expr(expr.Fun)
+
+		// The key for the Inferred map is the CallExpr (if inferring
+		// types required the function arguments) or the IndexExpr below
+		// (if types could be inferred without the function arguments).
+		if inferred, ok := g.info.Inferred[expr]; ok && len(inferred.Targs) > 0 {
+			// This is the case where inferring types required the
+			// types of the function arguments.
+			targs := make([]ir.Node, len(inferred.Targs))
+			for i, targ := range inferred.Targs {
+				targs[i] = ir.TypeNode(g.typ(targ))
+			}
+			if fun.Op() == ir.OFUNCINST {
+				// Replace explicit type args with the full list that
+				// includes the additional inferred type args
+				fun.(*ir.InstExpr).Targs = targs
+			} else {
+				// Create a function instantiation here, given
+				// there are only inferred type args (e.g.
+				// min(5,6), where min is a generic function)
+				inst := ir.NewInstExpr(pos, ir.OFUNCINST, fun, targs)
+				typed(fun.Type(), inst)
+				fun = inst
+			}
+
+		}
+		return Call(pos, g.typ(typ), fun, g.exprs(expr.ArgList), expr.HasDots)
+
+	case *syntax.IndexExpr:
+		var targs []ir.Node
+
+		if inferred, ok := g.info.Inferred[expr]; ok && len(inferred.Targs) > 0 {
+			// This is the partial type inference case where the types
+			// can be inferred from other type arguments without using
+			// the types of the function arguments.
+			targs = make([]ir.Node, len(inferred.Targs))
+			for i, targ := range inferred.Targs {
+				targs[i] = ir.TypeNode(g.typ(targ))
+			}
+		} else if _, ok := expr.Index.(*syntax.ListExpr); ok {
+			targs = g.exprList(expr.Index)
+		} else {
+			index := g.expr(expr.Index)
+			if index.Op() != ir.OTYPE {
+				// This is just a normal index expression
+				return Index(pos, g.typ(typ), g.expr(expr.X), index)
+			}
+			// This is generic function instantiation with a single type
+			targs = []ir.Node{index}
+		}
+		// This is a generic function instantiation (e.g. min[int]).
+		// Generic type instantiation is handled in the type
+		// section of expr() above (using g.typ).
+		x := g.expr(expr.X)
+		if x.Op() != ir.ONAME || x.Type().Kind() != types.TFUNC {
+			panic("Incorrect argument for generic func instantiation")
+		}
+		n := ir.NewInstExpr(pos, ir.OFUNCINST, x, targs)
+		typed(g.typ(typ), n)
+		return n
+
+	case *syntax.ParenExpr:
+		return g.expr(expr.X) // skip parens; unneeded after parse+typecheck
+
+	case *syntax.SelectorExpr:
+		// Qualified identifier.
+		if name, ok := expr.X.(*syntax.Name); ok {
+			if _, ok := g.info.Uses[name].(*types2.PkgName); ok {
+				return g.use(expr.Sel)
+			}
+		}
+		return g.selectorExpr(pos, typ, expr)
+
+	case *syntax.SliceExpr:
+		return Slice(pos, g.typ(typ), g.expr(expr.X), g.expr(expr.Index[0]), g.expr(expr.Index[1]), g.expr(expr.Index[2]))
+
+	case *syntax.Operation:
+		if expr.Y == nil {
+			return Unary(pos, g.typ(typ), g.op(expr.Op, unOps[:]), g.expr(expr.X))
+		}
+		switch op := g.op(expr.Op, binOps[:]); op {
+		case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
+			return Compare(pos, g.typ(typ), op, g.expr(expr.X), g.expr(expr.Y))
+		default:
+			return Binary(pos, op, g.typ(typ), g.expr(expr.X), g.expr(expr.Y))
+		}
+
+	default:
+		g.unhandled("expression", expr)
+		panic("unreachable")
+	}
+}
+
+// selectorExpr resolves the choice of ODOT, ODOTPTR, OCALLPART (eventually
+// ODOTMETH & ODOTINTER), and OMETHEXPR and deals with embedded fields here rather
+// than in typecheck.go.
+func (g *irgen) selectorExpr(pos src.XPos, typ types2.Type, expr *syntax.SelectorExpr) ir.Node {
+	x := g.expr(expr.X)
+	if x.Type().HasTParam() {
+		// Leave a method call on a type param as an OXDOT, since it can
+		// only be fully transformed once it has an instantiated type.
+		n := ir.NewSelectorExpr(pos, ir.OXDOT, x, typecheck.Lookup(expr.Sel.Value))
+		typed(g.typ(typ), n)
+		return n
+	}
+
+	selinfo := g.info.Selections[expr]
+	// Everything up to the last selection is an implicit embedded field access,
+	// and the last selection is determined by selinfo.Kind().
+	index := selinfo.Index()
+	embeds, last := index[:len(index)-1], index[len(index)-1]
+
+	origx := x
+	for _, ix := range embeds {
+		x = Implicit(DotField(pos, x, ix))
+	}
+
+	kind := selinfo.Kind()
+	if kind == types2.FieldVal {
+		return DotField(pos, x, last)
+	}
+
+	// TODO(danscales,mdempsky): Interface method sets are not sorted the
+	// same between types and types2. In particular, using "last" here
+	// without conversion will likely fail if an interface contains
+	// unexported methods from two different packages (due to cross-package
+	// interface embedding).
+
+	var n ir.Node
+	method2 := selinfo.Obj().(*types2.Func)
+
+	if kind == types2.MethodExpr {
+		// OMETHEXPR is unusual in using directly the node and type of the
+		// original OTYPE node (origx) before passing through embedded
+		// fields, even though the method is selected from the type
+		// (x.Type()) reached after following the embedded fields. We will
+		// actually drop any ODOT nodes we created due to the embedded
+		// fields.
+		n = MethodExpr(pos, origx, x.Type(), last)
+	} else {
+		// Add implicit addr/deref for method values, if needed.
+		if x.Type().IsInterface() {
+			n = DotMethod(pos, x, last)
+		} else {
+			recvType2 := method2.Type().(*types2.Signature).Recv().Type()
+			_, wantPtr := recvType2.(*types2.Pointer)
+			havePtr := x.Type().IsPtr()
+
+			if havePtr != wantPtr {
+				if havePtr {
+					x = Implicit(Deref(pos, x.Type().Elem(), x))
+				} else {
+					x = Implicit(Addr(pos, x))
+				}
+			}
+			recvType2Base := recvType2
+			if wantPtr {
+				recvType2Base = types2.AsPointer(recvType2).Elem()
+			}
+			if len(types2.AsNamed(recvType2Base).TParams()) > 0 {
+				// recvType2 is the original generic type that is
+				// instantiated for this method call.
+				// selinfo.Recv() is the instantiated type
+				recvType2 = recvType2Base
+				// method is the generic method associated with the gen type
+				method := g.obj(types2.AsNamed(recvType2).Method(last))
+				n = ir.NewSelectorExpr(pos, ir.OCALLPART, x, method.Sym())
+				n.(*ir.SelectorExpr).Selection = types.NewField(pos, method.Sym(), method.Type())
+				n.(*ir.SelectorExpr).Selection.Nname = method
+				typed(method.Type(), n)
+
+				// selinfo.Targs() are the types used to
+				// instantiate the type of receiver
+				targs2 := getTargs(selinfo)
+				targs := make([]ir.Node, len(targs2))
+				for i, targ2 := range targs2 {
+					targs[i] = ir.TypeNode(g.typ(targ2))
+				}
+
+				// Create function instantiation with the type
+				// args for the receiver type for the method call.
+				n = ir.NewInstExpr(pos, ir.OFUNCINST, n, targs)
+				typed(g.typ(typ), n)
+				return n
+			}
+
+			if !g.match(x.Type(), recvType2, false) {
+				base.FatalfAt(pos, "expected %L to have type %v", x, recvType2)
+			} else {
+				n = DotMethod(pos, x, last)
+			}
+		}
+	}
+	if have, want := n.Sym(), g.selector(method2); have != want {
+		base.FatalfAt(pos, "bad Sym: have %v, want %v", have, want)
+	}
+	return n
+}
+
+// getTargs gets the targs associated with the receiver of a selected method
+func getTargs(selinfo *types2.Selection) []types2.Type {
+	r := selinfo.Recv()
+	if p := types2.AsPointer(r); p != nil {
+		r = p.Elem()
+	}
+	n := types2.AsNamed(r)
+	if n == nil {
+		base.Fatalf("Incorrect type for selinfo %v", selinfo)
+	}
+	return n.TArgs()
+}
+
+func (g *irgen) exprList(expr syntax.Expr) []ir.Node {
+	switch expr := expr.(type) {
+	case nil:
+		return nil
+	case *syntax.ListExpr:
+		return g.exprs(expr.ElemList)
+	default:
+		return []ir.Node{g.expr(expr)}
+	}
+}
+
+func (g *irgen) exprs(exprs []syntax.Expr) []ir.Node {
+	nodes := make([]ir.Node, len(exprs))
+	for i, expr := range exprs {
+		nodes[i] = g.expr(expr)
+	}
+	return nodes
+}
+
+func (g *irgen) compLit(typ types2.Type, lit *syntax.CompositeLit) ir.Node {
+	if ptr, ok := typ.Underlying().(*types2.Pointer); ok {
+		n := ir.NewAddrExpr(g.pos(lit), g.compLit(ptr.Elem(), lit))
+		n.SetOp(ir.OPTRLIT)
+		return typed(g.typ(typ), n)
+	}
+
+	_, isStruct := typ.Underlying().(*types2.Struct)
+
+	exprs := make([]ir.Node, len(lit.ElemList))
+	for i, elem := range lit.ElemList {
+		switch elem := elem.(type) {
+		case *syntax.KeyValueExpr:
+			if isStruct {
+				exprs[i] = ir.NewStructKeyExpr(g.pos(elem), g.name(elem.Key.(*syntax.Name)), g.expr(elem.Value))
+			} else {
+				exprs[i] = ir.NewKeyExpr(g.pos(elem), g.expr(elem.Key), g.expr(elem.Value))
+			}
+		default:
+			exprs[i] = g.expr(elem)
+		}
+	}
+
+	n := ir.NewCompLitExpr(g.pos(lit), ir.OCOMPLIT, nil, exprs)
+	typed(g.typ(typ), n)
+	return transformCompLit(n)
+}
+
+func (g *irgen) funcLit(typ2 types2.Type, expr *syntax.FuncLit) ir.Node {
+	fn := ir.NewFunc(g.pos(expr))
+	fn.SetIsHiddenClosure(ir.CurFunc != nil)
+
+	fn.Nname = ir.NewNameAt(g.pos(expr), typecheck.ClosureName(ir.CurFunc))
+	ir.MarkFunc(fn.Nname)
+	typ := g.typ(typ2)
+	fn.Nname.Func = fn
+	fn.Nname.Defn = fn
+	typed(typ, fn.Nname)
+	fn.SetTypecheck(1)
+
+	fn.OClosure = ir.NewClosureExpr(g.pos(expr), fn)
+	typed(typ, fn.OClosure)
+
+	g.funcBody(fn, nil, expr.Type, expr.Body)
+
+	ir.FinishCaptureNames(fn.Pos(), ir.CurFunc, fn)
+
+	// TODO(mdempsky): ir.CaptureName should probably handle
+	// copying these fields from the canonical variable.
+	for _, cv := range fn.ClosureVars {
+		cv.SetType(cv.Canonical().Type())
+		cv.SetTypecheck(1)
+		cv.SetWalkdef(1)
+	}
+
+	g.target.Decls = append(g.target.Decls, fn)
+
+	return fn.OClosure
+}
+
+func (g *irgen) typeExpr(typ syntax.Expr) *types.Type {
+	n := g.expr(typ)
+	if n.Op() != ir.OTYPE {
+		base.FatalfAt(g.pos(typ), "expected type: %L", n)
+	}
+	return n.Type()
+}
diff --git a/src/cmd/compile/internal/noder/func.go b/src/cmd/compile/internal/noder/func.go
new file mode 100644
index 0000000..7021381
--- /dev/null
+++ b/src/cmd/compile/internal/noder/func.go
@@ -0,0 +1,74 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+func (g *irgen) funcBody(fn *ir.Func, recv *syntax.Field, sig *syntax.FuncType, block *syntax.BlockStmt) {
+	typecheck.Func(fn)
+
+	// TODO(mdempsky): Remove uses of ir.CurFunc and
+	// typecheck.DeclContext after we stop relying on typecheck
+	// for desugaring.
+	outerfn, outerctxt := ir.CurFunc, typecheck.DeclContext
+	ir.CurFunc = fn
+
+	typ := fn.Type()
+	if param := typ.Recv(); param != nil {
+		g.defParam(param, recv, ir.PPARAM)
+	}
+	for i, param := range typ.Params().FieldSlice() {
+		g.defParam(param, sig.ParamList[i], ir.PPARAM)
+	}
+	for i, result := range typ.Results().FieldSlice() {
+		g.defParam(result, sig.ResultList[i], ir.PPARAMOUT)
+	}
+
+	// We may have type-checked a call to this function already and
+	// calculated its size, including parameter offsets. Now that we've
+	// created the parameter Names, force a recalculation to ensure
+	// their offsets are correct.
+	typ.Align = 0
+	types.CalcSize(typ)
+
+	if block != nil {
+		typecheck.DeclContext = ir.PAUTO
+
+		fn.Body = g.stmts(block.List)
+		if fn.Body == nil {
+			fn.Body = []ir.Node{ir.NewBlockStmt(src.NoXPos, nil)}
+		}
+		fn.Endlineno = g.makeXPos(block.Rbrace)
+
+		if base.Flag.Dwarf {
+			g.recordScopes(fn, sig)
+		}
+	}
+
+	ir.CurFunc, typecheck.DeclContext = outerfn, outerctxt
+}
+
+func (g *irgen) defParam(param *types.Field, decl *syntax.Field, class ir.Class) {
+	typecheck.DeclContext = class
+
+	var name *ir.Name
+	if decl.Name != nil {
+		name, _ = g.def(decl.Name)
+	} else if class == ir.PPARAMOUT {
+		name = g.obj(g.info.Implicits[decl])
+	}
+
+	if name != nil {
+		param.Nname = name
+		param.Sym = name.Sym() // in case it was renamed
+	}
+}
diff --git a/src/cmd/compile/internal/noder/helpers.go b/src/cmd/compile/internal/noder/helpers.go
new file mode 100644
index 0000000..9da0e49
--- /dev/null
+++ b/src/cmd/compile/internal/noder/helpers.go
@@ -0,0 +1,325 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"go/constant"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// Helpers for constructing typed IR nodes.
+//
+// TODO(mdempsky): Move into their own package so they can be easily
+// reused by iimport and frontend optimizations.
+
+type ImplicitNode interface {
+	ir.Node
+	SetImplicit(x bool)
+}
+
+// Implicit returns n after marking it as Implicit.
+func Implicit(n ImplicitNode) ImplicitNode {
+	n.SetImplicit(true)
+	return n
+}
+
+// typed returns n after setting its type to typ.
+func typed(typ *types.Type, n ir.Node) ir.Node {
+	n.SetType(typ)
+	n.SetTypecheck(1)
+	return n
+}
+
+// Values
+
+func Const(pos src.XPos, typ *types.Type, val constant.Value) ir.Node {
+	return typed(typ, ir.NewBasicLit(pos, val))
+}
+
+func Nil(pos src.XPos, typ *types.Type) ir.Node {
+	return typed(typ, ir.NewNilExpr(pos))
+}
+
+// Expressions
+
+func Addr(pos src.XPos, x ir.Node) *ir.AddrExpr {
+	n := typecheck.NodAddrAt(pos, x)
+	switch x.Op() {
+	case ir.OARRAYLIT, ir.OMAPLIT, ir.OSLICELIT, ir.OSTRUCTLIT:
+		n.SetOp(ir.OPTRLIT)
+	}
+	typed(types.NewPtr(x.Type()), n)
+	return n
+}
+
+func Assert(pos src.XPos, x ir.Node, typ *types.Type) ir.Node {
+	return typed(typ, ir.NewTypeAssertExpr(pos, x, nil))
+}
+
+func Binary(pos src.XPos, op ir.Op, typ *types.Type, x, y ir.Node) ir.Node {
+	switch op {
+	case ir.OANDAND, ir.OOROR:
+		return typed(x.Type(), ir.NewLogicalExpr(pos, op, x, y))
+	case ir.OADD:
+		n := ir.NewBinaryExpr(pos, op, x, y)
+		if x.Type().HasTParam() || y.Type().HasTParam() {
+			// Delay transformAdd() if either arg has a type param,
+			// since it needs to know the exact types to decide whether
+			// to transform OADD to OADDSTR.
+			n.SetType(typ)
+			n.SetTypecheck(3)
+			return n
+		}
+		typed(typ, n)
+		return transformAdd(n)
+	default:
+		return typed(x.Type(), ir.NewBinaryExpr(pos, op, x, y))
+	}
+}
+
+func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool) ir.Node {
+	n := ir.NewCallExpr(pos, ir.OCALL, fun, args)
+	n.IsDDD = dots
+	// n.Use will be changed to ir.CallUseStmt in g.stmt() if this call is
+	// just a statement (any return values are ignored).
+	n.Use = ir.CallUseExpr
+
+	if fun.Op() == ir.OTYPE {
+		// Actually a type conversion, not a function call.
+		if fun.Type().HasTParam() || args[0].Type().HasTParam() {
+			// For type params, don't typecheck until we actually know
+			// the type.
+			return typed(typ, n)
+		}
+		typed(typ, n)
+		return transformConvCall(n)
+	}
+
+	if fun, ok := fun.(*ir.Name); ok && fun.BuiltinOp != 0 {
+		// For Builtin ops, we currently stay with using the old
+		// typechecker to transform the call to a more specific expression
+		// and possibly use more specific ops. However, for a bunch of the
+		// ops, we delay doing the old typechecker if any of the args have
+		// type params, for a variety of reasons:
+		//
+		// OMAKE: hard to choose specific ops OMAKESLICE, etc. until arg type is known
+		// OREAL/OIMAG: can't determine type float32/float64 until arg type know
+		// OLEN/OCAP: old typechecker will complain if arg is not obviously a slice/array.
+		// OAPPEND: old typechecker will complain if arg is not obviously slice, etc.
+		//
+		// We will eventually break out the transforming functionality
+		// needed for builtin's, and call it here or during stenciling, as
+		// appropriate.
+		switch fun.BuiltinOp {
+		case ir.OMAKE, ir.OREAL, ir.OIMAG, ir.OLEN, ir.OCAP, ir.OAPPEND:
+			hasTParam := false
+			for _, arg := range args {
+				if arg.Type().HasTParam() {
+					hasTParam = true
+					break
+				}
+			}
+			if hasTParam {
+				return typed(typ, n)
+			}
+		}
+
+		typed(typ, n)
+		return transformBuiltin(n)
+	}
+
+	// Add information, now that we know that fun is actually being called.
+	switch fun := fun.(type) {
+	case *ir.ClosureExpr:
+		fun.Func.SetClosureCalled(true)
+	case *ir.SelectorExpr:
+		if fun.Op() == ir.OCALLPART {
+			op := ir.ODOTMETH
+			if fun.X.Type().IsInterface() {
+				op = ir.ODOTINTER
+			}
+			fun.SetOp(op)
+			// Set the type to include the receiver, since that's what
+			// later parts of the compiler expect
+			fun.SetType(fun.Selection.Type)
+		}
+	}
+
+	if fun.Type().HasTParam() {
+		// If the fun arg is or has a type param, don't do any extra
+		// transformations, since we may not have needed properties yet
+		// (e.g. number of return values, etc). The type param is probably
+		// described by a structural constraint that requires it to be a
+		// certain function type, etc., but we don't want to analyze that.
+		return typed(typ, n)
+	}
+
+	if fun.Op() == ir.OXDOT {
+		if !fun.(*ir.SelectorExpr).X.Type().HasTParam() {
+			base.FatalfAt(pos, "Expecting type param receiver in %v", fun)
+		}
+		// For methods called in a generic function, don't do any extra
+		// transformations. We will do those later when we create the
+		// instantiated function and have the correct receiver type.
+		typed(typ, n)
+		return n
+	}
+	if fun.Op() != ir.OFUNCINST {
+		// If no type params, do the normal call transformations. This
+		// will convert OCALL to OCALLFUNC.
+		typed(typ, n)
+		transformCall(n)
+		return n
+	}
+
+	// Leave the op as OCALL, which indicates the call still needs typechecking.
+	typed(typ, n)
+	return n
+}
+
+func Compare(pos src.XPos, typ *types.Type, op ir.Op, x, y ir.Node) ir.Node {
+	n := ir.NewBinaryExpr(pos, op, x, y)
+	if x.Type().HasTParam() || y.Type().HasTParam() {
+		// Delay transformCompare() if either arg has a type param, since
+		// it needs to know the exact types to decide on any needed conversions.
+		n.SetType(typ)
+		n.SetTypecheck(3)
+		return n
+	}
+	typed(typ, n)
+	transformCompare(n)
+	return n
+}
+
+func Deref(pos src.XPos, typ *types.Type, x ir.Node) *ir.StarExpr {
+	n := ir.NewStarExpr(pos, x)
+	typed(typ, n)
+	return n
+}
+
+func DotField(pos src.XPos, x ir.Node, index int) *ir.SelectorExpr {
+	op, typ := ir.ODOT, x.Type()
+	if typ.IsPtr() {
+		op, typ = ir.ODOTPTR, typ.Elem()
+	}
+	if !typ.IsStruct() {
+		base.FatalfAt(pos, "DotField of non-struct: %L", x)
+	}
+
+	// TODO(mdempsky): This is the backend's responsibility.
+	types.CalcSize(typ)
+
+	field := typ.Field(index)
+	return dot(pos, field.Type, op, x, field)
+}
+
+func DotMethod(pos src.XPos, x ir.Node, index int) *ir.SelectorExpr {
+	method := method(x.Type(), index)
+
+	// Method value.
+	typ := typecheck.NewMethodType(method.Type, nil)
+	return dot(pos, typ, ir.OCALLPART, x, method)
+}
+
+// MethodExpr returns a OMETHEXPR node with the indicated index into the methods
+// of typ. The receiver type is set from recv, which is different from typ if the
+// method was accessed via embedded fields. Similarly, the X value of the
+// ir.SelectorExpr is recv, the original OTYPE node before passing through the
+// embedded fields.
+func MethodExpr(pos src.XPos, recv ir.Node, embed *types.Type, index int) *ir.SelectorExpr {
+	method := method(embed, index)
+	typ := typecheck.NewMethodType(method.Type, recv.Type())
+	// The method expression T.m requires a wrapper when T
+	// is different from m's declared receiver type. We
+	// normally generate these wrappers while writing out
+	// runtime type descriptors, which is always done for
+	// types declared at package scope. However, we need
+	// to make sure to generate wrappers for anonymous
+	// receiver types too.
+	if recv.Sym() == nil {
+		typecheck.NeedRuntimeType(recv.Type())
+	}
+	return dot(pos, typ, ir.OMETHEXPR, recv, method)
+}
+
+func dot(pos src.XPos, typ *types.Type, op ir.Op, x ir.Node, selection *types.Field) *ir.SelectorExpr {
+	n := ir.NewSelectorExpr(pos, op, x, selection.Sym)
+	n.Selection = selection
+	typed(typ, n)
+	return n
+}
+
+// TODO(mdempsky): Move to package types.
+func method(typ *types.Type, index int) *types.Field {
+	if typ.IsInterface() {
+		return typ.AllMethods().Index(index)
+	}
+	return types.ReceiverBaseType(typ).Methods().Index(index)
+}
+
+func Index(pos src.XPos, typ *types.Type, x, index ir.Node) ir.Node {
+	n := ir.NewIndexExpr(pos, x, index)
+	if x.Type().HasTParam() {
+		// transformIndex needs to know exact type
+		n.SetType(typ)
+		n.SetTypecheck(3)
+		return n
+	}
+	typed(typ, n)
+	// transformIndex will modify n.Type() for OINDEXMAP.
+	transformIndex(n)
+	return n
+}
+
+func Slice(pos src.XPos, typ *types.Type, x, low, high, max ir.Node) ir.Node {
+	op := ir.OSLICE
+	if max != nil {
+		op = ir.OSLICE3
+	}
+	n := ir.NewSliceExpr(pos, op, x, low, high, max)
+	if x.Type().HasTParam() {
+		// transformSlice needs to know if x.Type() is a string or an array or a slice.
+		n.SetType(typ)
+		n.SetTypecheck(3)
+		return n
+	}
+	typed(typ, n)
+	transformSlice(n)
+	return n
+}
+
+func Unary(pos src.XPos, typ *types.Type, op ir.Op, x ir.Node) ir.Node {
+	switch op {
+	case ir.OADDR:
+		return Addr(pos, x)
+	case ir.ODEREF:
+		return Deref(pos, typ, x)
+	}
+
+	if op == ir.ORECV {
+		if typ.IsFuncArgStruct() && typ.NumFields() == 2 {
+			// Remove the second boolean type (if provided by type2),
+			// since that works better with the rest of the compiler
+			// (which will add it back in later).
+			assert(typ.Field(1).Type.Kind() == types.TBOOL)
+			typ = typ.Field(0).Type
+		}
+	}
+	return typed(typ, ir.NewUnaryExpr(pos, op, x))
+}
+
+// Statements
+
+var one = constant.MakeInt64(1)
+
+func IncDec(pos src.XPos, op ir.Op, x ir.Node) *ir.AssignOpStmt {
+	assert(x.Type() != nil)
+	return ir.NewAssignOpStmt(pos, op, x, typecheck.DefaultLit(ir.NewBasicLit(pos, one), x.Type()))
+}
diff --git a/src/cmd/compile/internal/noder/import.go b/src/cmd/compile/internal/noder/import.go
new file mode 100644
index 0000000..701e900
--- /dev/null
+++ b/src/cmd/compile/internal/noder/import.go
@@ -0,0 +1,507 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"errors"
+	"fmt"
+	"internal/buildcfg"
+	"io"
+	"os"
+	pathpkg "path"
+	"runtime"
+	"sort"
+	"strconv"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/importer"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/compile/internal/types2"
+	"cmd/internal/archive"
+	"cmd/internal/bio"
+	"cmd/internal/goobj"
+	"cmd/internal/objabi"
+	"cmd/internal/src"
+)
+
+// Temporary import helper to get type2-based type-checking going.
+type gcimports struct {
+	packages map[string]*types2.Package
+}
+
+func (m *gcimports) Import(path string) (*types2.Package, error) {
+	return m.ImportFrom(path, "" /* no vendoring */, 0)
+}
+
+func (m *gcimports) ImportFrom(path, srcDir string, mode types2.ImportMode) (*types2.Package, error) {
+	if mode != 0 {
+		panic("mode must be 0")
+	}
+
+	path, err := resolveImportPath(path)
+	if err != nil {
+		return nil, err
+	}
+
+	lookup := func(path string) (io.ReadCloser, error) { return openPackage(path) }
+	return importer.Import(m.packages, path, srcDir, lookup)
+}
+
+func isDriveLetter(b byte) bool {
+	return 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z'
+}
+
+// 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] == '/' ||
+		strings.HasPrefix(name, "./") || name == "." ||
+		strings.HasPrefix(name, "../") || name == ".."
+}
+
+func openPackage(path string) (*os.File, error) {
+	if islocalname(path) {
+		if base.Flag.NoLocalImports {
+			return nil, errors.New("local imports disallowed")
+		}
+
+		if base.Flag.Cfg.PackageFile != nil {
+			return os.Open(base.Flag.Cfg.PackageFile[path])
+		}
+
+		// try .a before .o.  important for building libraries:
+		// if there is an array.o in the array.a library,
+		// want to find all of array.a, not just array.o.
+		if file, err := os.Open(fmt.Sprintf("%s.a", path)); err == nil {
+			return file, nil
+		}
+		if file, err := os.Open(fmt.Sprintf("%s.o", path)); err == nil {
+			return file, nil
+		}
+		return nil, errors.New("file not found")
+	}
+
+	// local imports should be canonicalized already.
+	// don't want to see "encoding/../encoding/base64"
+	// as different from "encoding/base64".
+	if q := pathpkg.Clean(path); q != path {
+		return nil, fmt.Errorf("non-canonical import path %q (should be %q)", path, q)
+	}
+
+	if base.Flag.Cfg.PackageFile != nil {
+		return os.Open(base.Flag.Cfg.PackageFile[path])
+	}
+
+	for _, dir := range base.Flag.Cfg.ImportDirs {
+		if file, err := os.Open(fmt.Sprintf("%s/%s.a", dir, path)); err == nil {
+			return file, nil
+		}
+		if file, err := os.Open(fmt.Sprintf("%s/%s.o", dir, path)); err == nil {
+			return file, nil
+		}
+	}
+
+	if buildcfg.GOROOT != "" {
+		suffix := ""
+		if base.Flag.InstallSuffix != "" {
+			suffix = "_" + base.Flag.InstallSuffix
+		} else if base.Flag.Race {
+			suffix = "_race"
+		} else if base.Flag.MSan {
+			suffix = "_msan"
+		}
+
+		if file, err := os.Open(fmt.Sprintf("%s/pkg/%s_%s%s/%s.a", buildcfg.GOROOT, buildcfg.GOOS, buildcfg.GOARCH, suffix, path)); err == nil {
+			return file, nil
+		}
+		if file, err := os.Open(fmt.Sprintf("%s/pkg/%s_%s%s/%s.o", buildcfg.GOROOT, buildcfg.GOOS, buildcfg.GOARCH, suffix, path)); err == nil {
+			return file, nil
+		}
+	}
+	return nil, errors.New("file not found")
+}
+
+// myheight tracks the local package's height based on packages
+// imported so far.
+var myheight int
+
+// resolveImportPath resolves an import path as it appears in a Go
+// source file to the package's full path.
+func resolveImportPath(path string) (string, error) {
+	// The package name main is no longer reserved,
+	// but we reserve the import path "main" to identify
+	// the main package, just as we reserve the import
+	// path "math" to identify the standard math package.
+	if path == "main" {
+		return "", errors.New("cannot import \"main\"")
+	}
+
+	if base.Ctxt.Pkgpath != "" && path == base.Ctxt.Pkgpath {
+		return "", fmt.Errorf("import %q while compiling that package (import cycle)", path)
+	}
+
+	if mapped, ok := base.Flag.Cfg.ImportMap[path]; ok {
+		path = mapped
+	}
+
+	if islocalname(path) {
+		if path[0] == '/' {
+			return "", errors.New("import path cannot be absolute path")
+		}
+
+		prefix := base.Flag.D
+		if prefix == "" {
+			// Questionable, but when -D isn't specified, historically we
+			// resolve local import paths relative to the directory the
+			// compiler's current directory, not the respective source
+			// file's directory.
+			prefix = base.Ctxt.Pathname
+		}
+		path = pathpkg.Join(prefix, path)
+
+		if err := checkImportPath(path, true); err != nil {
+			return "", err
+		}
+	}
+
+	return path, nil
+}
+
+// TODO(mdempsky): Return an error instead.
+func importfile(decl *syntax.ImportDecl) *types.Pkg {
+	if decl.Path.Kind != syntax.StringLit {
+		base.Errorf("import path must be a string")
+		return nil
+	}
+
+	path, err := strconv.Unquote(decl.Path.Value)
+	if err != nil {
+		base.Errorf("import path must be a string")
+		return nil
+	}
+
+	if err := checkImportPath(path, false); err != nil {
+		base.Errorf("%s", err.Error())
+		return nil
+	}
+
+	path, err = resolveImportPath(path)
+	if err != nil {
+		base.Errorf("%s", err)
+		return nil
+	}
+
+	importpkg := types.NewPkg(path, "")
+	if importpkg.Direct {
+		return importpkg // already fully loaded
+	}
+	importpkg.Direct = true
+	typecheck.Target.Imports = append(typecheck.Target.Imports, importpkg)
+
+	if path == "unsafe" {
+		return importpkg // initialized with universe
+	}
+
+	f, err := openPackage(path)
+	if err != nil {
+		base.Errorf("could not import %q: %v", path, err)
+		base.ErrorExit()
+	}
+	imp := bio.NewReader(f)
+	defer imp.Close()
+	file := f.Name()
+
+	// check object header
+	p, err := imp.ReadString('\n')
+	if err != nil {
+		base.Errorf("import %s: reading input: %v", file, err)
+		base.ErrorExit()
+	}
+
+	if p == "!<arch>\n" { // package archive
+		// package export block should be first
+		sz := archive.ReadHeader(imp.Reader, "__.PKGDEF")
+		if sz <= 0 {
+			base.Errorf("import %s: not a package file", file)
+			base.ErrorExit()
+		}
+		p, err = imp.ReadString('\n')
+		if err != nil {
+			base.Errorf("import %s: reading input: %v", file, err)
+			base.ErrorExit()
+		}
+	}
+
+	if !strings.HasPrefix(p, "go object ") {
+		base.Errorf("import %s: not a go object file: %s", file, p)
+		base.ErrorExit()
+	}
+	q := objabi.HeaderString()
+	if p != q {
+		base.Errorf("import %s: object is [%s] expected [%s]", file, p, q)
+		base.ErrorExit()
+	}
+
+	// process header lines
+	for {
+		p, err = imp.ReadString('\n')
+		if err != nil {
+			base.Errorf("import %s: reading input: %v", file, err)
+			base.ErrorExit()
+		}
+		if p == "\n" {
+			break // header ends with blank line
+		}
+	}
+
+	// Expect $$B\n to signal binary import format.
+
+	// look for $$
+	var c byte
+	for {
+		c, err = imp.ReadByte()
+		if err != nil {
+			break
+		}
+		if c == '$' {
+			c, err = imp.ReadByte()
+			if c == '$' || err != nil {
+				break
+			}
+		}
+	}
+
+	// get character after $$
+	if err == nil {
+		c, _ = imp.ReadByte()
+	}
+
+	var fingerprint goobj.FingerprintType
+	switch c {
+	case '\n':
+		base.Errorf("cannot import %s: old export format no longer supported (recompile library)", path)
+		return nil
+
+	case 'B':
+		if base.Debug.Export != 0 {
+			fmt.Printf("importing %s (%s)\n", path, file)
+		}
+		imp.ReadByte() // skip \n after $$B
+
+		c, err = imp.ReadByte()
+		if err != nil {
+			base.Errorf("import %s: reading input: %v", file, err)
+			base.ErrorExit()
+		}
+
+		// Indexed format is distinguished by an 'i' byte,
+		// whereas previous export formats started with 'c', 'd', or 'v'.
+		if c != 'i' {
+			base.Errorf("import %s: unexpected package format byte: %v", file, c)
+			base.ErrorExit()
+		}
+		fingerprint = typecheck.ReadImports(importpkg, imp)
+
+	default:
+		base.Errorf("no import in %q", path)
+		base.ErrorExit()
+	}
+
+	// assume files move (get installed) so don't record the full path
+	if base.Flag.Cfg.PackageFile != nil {
+		// If using a packageFile map, assume path_ can be recorded directly.
+		base.Ctxt.AddImport(path, fingerprint)
+	} else {
+		// For file "/Users/foo/go/pkg/darwin_amd64/math.a" record "math.a".
+		base.Ctxt.AddImport(file[len(file)-len(path)-len(".a"):], fingerprint)
+	}
+
+	if importpkg.Height >= myheight {
+		myheight = importpkg.Height + 1
+	}
+
+	return importpkg
+}
+
+// The linker uses the magic symbol prefixes "go." and "type."
+// Avoid potential confusion between import paths and symbols
+// by rejecting these reserved imports for now. Also, people
+// "can do weird things in GOPATH and we'd prefer they didn't
+// do _that_ weird thing" (per rsc). See also #4257.
+var reservedimports = []string{
+	"go",
+	"type",
+}
+
+func checkImportPath(path string, allowSpace bool) error {
+	if path == "" {
+		return errors.New("import path is empty")
+	}
+
+	if strings.Contains(path, "\x00") {
+		return errors.New("import path contains NUL")
+	}
+
+	for _, ri := range reservedimports {
+		if path == ri {
+			return fmt.Errorf("import path %q is reserved and cannot be used", path)
+		}
+	}
+
+	for _, r := range path {
+		switch {
+		case r == utf8.RuneError:
+			return fmt.Errorf("import path contains invalid UTF-8 sequence: %q", path)
+		case r < 0x20 || r == 0x7f:
+			return fmt.Errorf("import path contains control character: %q", path)
+		case r == '\\':
+			return fmt.Errorf("import path contains backslash; use slash: %q", path)
+		case !allowSpace && unicode.IsSpace(r):
+			return fmt.Errorf("import path contains space character: %q", path)
+		case strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r):
+			return fmt.Errorf("import path contains invalid character '%c': %q", r, path)
+		}
+	}
+
+	return nil
+}
+
+func pkgnotused(lineno src.XPos, path string, name string) {
+	// If the package was imported with a name other than the final
+	// import path element, show it explicitly in the error message.
+	// Note that this handles both renamed imports and imports of
+	// packages containing unconventional package declarations.
+	// Note that this uses / always, even on Windows, because Go import
+	// paths always use forward slashes.
+	elem := path
+	if i := strings.LastIndex(elem, "/"); i >= 0 {
+		elem = elem[i+1:]
+	}
+	if name == "" || elem == name {
+		base.ErrorfAt(lineno, "imported and not used: %q", path)
+	} else {
+		base.ErrorfAt(lineno, "imported and not used: %q as %s", path, name)
+	}
+}
+
+func mkpackage(pkgname string) {
+	if types.LocalPkg.Name == "" {
+		if pkgname == "_" {
+			base.Errorf("invalid package name _")
+		}
+		types.LocalPkg.Name = pkgname
+	} else {
+		if pkgname != types.LocalPkg.Name {
+			base.Errorf("package %s; expected %s", pkgname, types.LocalPkg.Name)
+		}
+	}
+}
+
+func clearImports() {
+	type importedPkg struct {
+		pos  src.XPos
+		path string
+		name string
+	}
+	var unused []importedPkg
+
+	for _, s := range types.LocalPkg.Syms {
+		n := ir.AsNode(s.Def)
+		if n == nil {
+			continue
+		}
+		if n.Op() == ir.OPACK {
+			// throw away top-level package name left over
+			// from previous file.
+			// leave s->block set to cause redeclaration
+			// errors if a conflicting top-level name is
+			// introduced by a different file.
+			p := n.(*ir.PkgName)
+			if !p.Used && base.SyntaxErrors() == 0 {
+				unused = append(unused, importedPkg{p.Pos(), p.Pkg.Path, s.Name})
+			}
+			s.Def = nil
+			continue
+		}
+		if types.IsDotAlias(s) {
+			// throw away top-level name left over
+			// from previous import . "x"
+			// We'll report errors after type checking in CheckDotImports.
+			s.Def = nil
+			continue
+		}
+	}
+
+	sort.Slice(unused, func(i, j int) bool { return unused[i].pos.Before(unused[j].pos) })
+	for _, pkg := range unused {
+		pkgnotused(pkg.pos, pkg.path, pkg.name)
+	}
+}
+
+// CheckDotImports reports errors for any unused dot imports.
+func CheckDotImports() {
+	for _, pack := range dotImports {
+		if !pack.Used {
+			base.ErrorfAt(pack.Pos(), "imported and not used: %q", pack.Pkg.Path)
+		}
+	}
+
+	// No longer needed; release memory.
+	dotImports = nil
+	typecheck.DotImportRefs = nil
+}
+
+// dotImports tracks all PkgNames that have been dot-imported.
+var dotImports []*ir.PkgName
+
+// find all the exported symbols in package referenced by PkgName,
+// and make them available in the current package
+func importDot(pack *ir.PkgName) {
+	if typecheck.DotImportRefs == nil {
+		typecheck.DotImportRefs = make(map[*ir.Ident]*ir.PkgName)
+	}
+
+	opkg := pack.Pkg
+	for _, s := range opkg.Syms {
+		if s.Def == nil {
+			if _, ok := typecheck.DeclImporter[s]; !ok {
+				continue
+			}
+		}
+		if !types.IsExported(s.Name) || strings.ContainsRune(s.Name, 0xb7) { // 0xb7 = center dot
+			continue
+		}
+		s1 := typecheck.Lookup(s.Name)
+		if s1.Def != nil {
+			pkgerror := fmt.Sprintf("during import %q", opkg.Path)
+			typecheck.Redeclared(base.Pos, s1, pkgerror)
+			continue
+		}
+
+		id := ir.NewIdent(src.NoXPos, s)
+		typecheck.DotImportRefs[id] = pack
+		s1.Def = id
+		s1.Block = 1
+	}
+
+	dotImports = append(dotImports, pack)
+}
+
+// importName is like oldname,
+// but it reports an error if sym is from another package and not exported.
+func importName(sym *types.Sym) ir.Node {
+	n := oldname(sym)
+	if !types.IsExported(sym.Name) && sym.Pkg != types.LocalPkg {
+		n.SetDiag(true)
+		base.Errorf("cannot refer to unexported name %s.%s", sym.Pkg.Name, sym.Name)
+	}
+	return n
+}
diff --git a/src/cmd/compile/internal/noder/irgen.go b/src/cmd/compile/internal/noder/irgen.go
new file mode 100644
index 0000000..3e0d328
--- /dev/null
+++ b/src/cmd/compile/internal/noder/irgen.go
@@ -0,0 +1,203 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"fmt"
+	"os"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/dwarfgen"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/compile/internal/types2"
+	"cmd/internal/src"
+)
+
+// check2 type checks a Go package using types2, and then generates IR
+// using the results.
+func check2(noders []*noder) {
+	if base.SyntaxErrors() != 0 {
+		base.ErrorExit()
+	}
+
+	// setup and syntax error reporting
+	var m posMap
+	files := make([]*syntax.File, len(noders))
+	for i, p := range noders {
+		m.join(&p.posMap)
+		files[i] = p.file
+	}
+
+	// typechecking
+	conf := types2.Config{
+		GoVersion:             base.Flag.Lang,
+		IgnoreLabels:          true, // parser already checked via syntax.CheckBranches mode
+		CompilerErrorMessages: true, // use error strings matching existing compiler errors
+		Error: func(err error) {
+			terr := err.(types2.Error)
+			base.ErrorfAt(m.makeXPos(terr.Pos), "%s", terr.Msg)
+		},
+		Importer: &gcimports{
+			packages: make(map[string]*types2.Package),
+		},
+		Sizes: &gcSizes{},
+	}
+	info := types2.Info{
+		Types:      make(map[syntax.Expr]types2.TypeAndValue),
+		Defs:       make(map[*syntax.Name]types2.Object),
+		Uses:       make(map[*syntax.Name]types2.Object),
+		Selections: make(map[*syntax.SelectorExpr]*types2.Selection),
+		Implicits:  make(map[syntax.Node]types2.Object),
+		Scopes:     make(map[syntax.Node]*types2.Scope),
+		Inferred:   make(map[syntax.Expr]types2.Inferred),
+		// expand as needed
+	}
+	pkg, err := conf.Check(base.Ctxt.Pkgpath, files, &info)
+	files = nil
+	base.ExitIfErrors()
+	if err != nil {
+		base.FatalfAt(src.NoXPos, "conf.Check error: %v", err)
+	}
+	if base.Flag.G < 2 {
+		os.Exit(0)
+	}
+
+	g := irgen{
+		target: typecheck.Target,
+		self:   pkg,
+		info:   &info,
+		posMap: m,
+		objs:   make(map[types2.Object]*ir.Name),
+		typs:   make(map[types2.Type]*types.Type),
+	}
+	g.generate(noders)
+
+	if base.Flag.G < 3 {
+		os.Exit(0)
+	}
+}
+
+type irgen struct {
+	target *ir.Package
+	self   *types2.Package
+	info   *types2.Info
+
+	posMap
+	objs   map[types2.Object]*ir.Name
+	typs   map[types2.Type]*types.Type
+	marker dwarfgen.ScopeMarker
+
+	// Fully-instantiated generic types whose methods should be instantiated
+	instTypeList []*types.Type
+}
+
+func (g *irgen) generate(noders []*noder) {
+	types.LocalPkg.Name = g.self.Name()
+	typecheck.TypecheckAllowed = true
+
+	// Prevent size calculations until we set the underlying type
+	// for all package-block defined types.
+	types.DeferCheckSize()
+
+	// At this point, types2 has already handled name resolution and
+	// type checking. We just need to map from its object and type
+	// representations to those currently used by the rest of the
+	// compiler. This happens mostly in 3 passes.
+
+	// 1. Process all import declarations. We use the compiler's own
+	// importer for this, rather than types2's gcimporter-derived one,
+	// to handle extensions and inline function bodies correctly.
+	//
+	// Also, we need to do this in a separate pass, because mappings are
+	// instantiated on demand. If we interleaved processing import
+	// declarations with other declarations, it's likely we'd end up
+	// wanting to map an object/type from another source file, but not
+	// yet have the import data it relies on.
+	declLists := make([][]syntax.Decl, len(noders))
+Outer:
+	for i, p := range noders {
+		g.pragmaFlags(p.file.Pragma, ir.GoBuildPragma)
+		for j, decl := range p.file.DeclList {
+			switch decl := decl.(type) {
+			case *syntax.ImportDecl:
+				g.importDecl(p, decl)
+			default:
+				declLists[i] = p.file.DeclList[j:]
+				continue Outer // no more ImportDecls
+			}
+		}
+	}
+	types.LocalPkg.Height = myheight
+
+	// 2. Process all package-block type declarations. As with imports,
+	// we need to make sure all types are properly instantiated before
+	// trying to map any expressions that utilize them. In particular,
+	// we need to make sure type pragmas are already known (see comment
+	// in irgen.typeDecl).
+	//
+	// We could perhaps instead defer processing of package-block
+	// variable initializers and function bodies, like noder does, but
+	// special-casing just package-block type declarations minimizes the
+	// differences between processing package-block and function-scoped
+	// declarations.
+	for _, declList := range declLists {
+		for _, decl := range declList {
+			switch decl := decl.(type) {
+			case *syntax.TypeDecl:
+				g.typeDecl((*ir.Nodes)(&g.target.Decls), decl)
+			}
+		}
+	}
+	types.ResumeCheckSize()
+
+	// 3. Process all remaining declarations.
+	for _, declList := range declLists {
+		g.target.Decls = append(g.target.Decls, g.decls(declList)...)
+	}
+
+	if base.Flag.W > 1 {
+		for _, n := range g.target.Decls {
+			s := fmt.Sprintf("\nafter noder2 %v", n)
+			ir.Dump(s, n)
+		}
+	}
+
+	typecheck.DeclareUniverse()
+
+	for _, p := range noders {
+		// Process linkname and cgo pragmas.
+		p.processPragmas()
+
+		// Double check for any type-checking inconsistencies. This can be
+		// removed once we're confident in IR generation results.
+		syntax.Walk(p.file, func(n syntax.Node) bool {
+			g.validate(n)
+			return false
+		})
+	}
+
+	// Create any needed stencils of generic functions
+	g.stencil()
+
+	// For now, remove all generic functions from g.target.Decl, since they
+	// have been used for stenciling, but don't compile. TODO: We will
+	// eventually export any exportable generic functions.
+	j := 0
+	for i, decl := range g.target.Decls {
+		if decl.Op() != ir.ODCLFUNC || !decl.Type().HasTParam() {
+			g.target.Decls[j] = g.target.Decls[i]
+			j++
+		}
+	}
+	g.target.Decls = g.target.Decls[:j]
+}
+
+func (g *irgen) unhandled(what string, p poser) {
+	base.FatalfAt(g.pos(p), "unhandled %s: %T", what, p)
+	panic("unreachable")
+}
diff --git a/src/cmd/compile/internal/noder/lex.go b/src/cmd/compile/internal/noder/lex.go
new file mode 100644
index 0000000..66a56a5
--- /dev/null
+++ b/src/cmd/compile/internal/noder/lex.go
@@ -0,0 +1,193 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"fmt"
+	"internal/buildcfg"
+	"strings"
+
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/syntax"
+)
+
+func isSpace(c rune) bool {
+	return c == ' ' || c == '\t' || c == '\n' || c == '\r'
+}
+
+func isQuoted(s string) bool {
+	return len(s) >= 2 && s[0] == '"' && s[len(s)-1] == '"'
+}
+
+const (
+	funcPragmas = ir.Nointerface |
+		ir.Noescape |
+		ir.Norace |
+		ir.Nosplit |
+		ir.Noinline |
+		ir.NoCheckPtr |
+		ir.RegisterParams | // TODO(register args) remove after register abi is working
+		ir.CgoUnsafeArgs |
+		ir.UintptrEscapes |
+		ir.Systemstack |
+		ir.Nowritebarrier |
+		ir.Nowritebarrierrec |
+		ir.Yeswritebarrierrec
+
+	typePragmas = ir.NotInHeap
+)
+
+func pragmaFlag(verb string) ir.PragmaFlag {
+	switch verb {
+	case "go:build":
+		return ir.GoBuildPragma
+	case "go:nointerface":
+		if buildcfg.Experiment.FieldTrack {
+			return ir.Nointerface
+		}
+	case "go:noescape":
+		return ir.Noescape
+	case "go:norace":
+		return ir.Norace
+	case "go:nosplit":
+		return ir.Nosplit | ir.NoCheckPtr // implies NoCheckPtr (see #34972)
+	case "go:noinline":
+		return ir.Noinline
+	case "go:nocheckptr":
+		return ir.NoCheckPtr
+	case "go:systemstack":
+		return ir.Systemstack
+	case "go:nowritebarrier":
+		return ir.Nowritebarrier
+	case "go:nowritebarrierrec":
+		return ir.Nowritebarrierrec | ir.Nowritebarrier // implies Nowritebarrier
+	case "go:yeswritebarrierrec":
+		return ir.Yeswritebarrierrec
+	case "go:cgo_unsafe_args":
+		return ir.CgoUnsafeArgs | ir.NoCheckPtr // implies NoCheckPtr (see #34968)
+	case "go:uintptrescapes":
+		// For the next function declared in the file
+		// any uintptr arguments may be pointer values
+		// converted to uintptr. This directive
+		// ensures that the referenced allocated
+		// object, if any, is retained and not moved
+		// until the call completes, even though from
+		// the types alone it would appear that the
+		// object is no longer needed during the
+		// call. The conversion to uintptr must appear
+		// in the argument list.
+		// Used in syscall/dll_windows.go.
+		return ir.UintptrEscapes
+	case "go:registerparams": // TODO(register args) remove after register abi is working
+		return ir.RegisterParams
+	case "go:notinheap":
+		return ir.NotInHeap
+	}
+	return 0
+}
+
+// pragcgo is called concurrently if files are parsed concurrently.
+func (p *noder) pragcgo(pos syntax.Pos, text string) {
+	f := pragmaFields(text)
+
+	verb := strings.TrimPrefix(f[0], "go:")
+	f[0] = verb
+
+	switch verb {
+	case "cgo_export_static", "cgo_export_dynamic":
+		switch {
+		case len(f) == 2 && !isQuoted(f[1]):
+		case len(f) == 3 && !isQuoted(f[1]) && !isQuoted(f[2]):
+		default:
+			p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf(`usage: //go:%s local [remote]`, verb)})
+			return
+		}
+	case "cgo_import_dynamic":
+		switch {
+		case len(f) == 2 && !isQuoted(f[1]):
+		case len(f) == 3 && !isQuoted(f[1]) && !isQuoted(f[2]):
+		case len(f) == 4 && !isQuoted(f[1]) && !isQuoted(f[2]) && isQuoted(f[3]):
+			f[3] = strings.Trim(f[3], `"`)
+			if buildcfg.GOOS == "aix" && f[3] != "" {
+				// On Aix, library pattern must be "lib.a/object.o"
+				// or "lib.a/libname.so.X"
+				n := strings.Split(f[3], "/")
+				if len(n) != 2 || !strings.HasSuffix(n[0], ".a") || (!strings.HasSuffix(n[1], ".o") && !strings.Contains(n[1], ".so.")) {
+					p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_dynamic local [remote ["lib.a/object.o"]]`})
+					return
+				}
+			}
+		default:
+			p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_dynamic local [remote ["library"]]`})
+			return
+		}
+	case "cgo_import_static":
+		switch {
+		case len(f) == 2 && !isQuoted(f[1]):
+		default:
+			p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_static local`})
+			return
+		}
+	case "cgo_dynamic_linker":
+		switch {
+		case len(f) == 2 && isQuoted(f[1]):
+			f[1] = strings.Trim(f[1], `"`)
+		default:
+			p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_dynamic_linker "path"`})
+			return
+		}
+	case "cgo_ldflag":
+		switch {
+		case len(f) == 2 && isQuoted(f[1]):
+			f[1] = strings.Trim(f[1], `"`)
+		default:
+			p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_ldflag "arg"`})
+			return
+		}
+	default:
+		return
+	}
+	p.pragcgobuf = append(p.pragcgobuf, f)
+}
+
+// pragmaFields is similar to strings.FieldsFunc(s, isSpace)
+// but does not split when inside double quoted regions and always
+// splits before the start and after the end of a double quoted region.
+// pragmaFields does not recognize escaped quotes. If a quote in s is not
+// closed the part after the opening quote will not be returned as a field.
+func pragmaFields(s string) []string {
+	var a []string
+	inQuote := false
+	fieldStart := -1 // Set to -1 when looking for start of field.
+	for i, c := range s {
+		switch {
+		case c == '"':
+			if inQuote {
+				inQuote = false
+				a = append(a, s[fieldStart:i+1])
+				fieldStart = -1
+			} else {
+				inQuote = true
+				if fieldStart >= 0 {
+					a = append(a, s[fieldStart:i])
+				}
+				fieldStart = i
+			}
+		case !inQuote && isSpace(c):
+			if fieldStart >= 0 {
+				a = append(a, s[fieldStart:i])
+				fieldStart = -1
+			}
+		default:
+			if fieldStart == -1 {
+				fieldStart = i
+			}
+		}
+	}
+	if !inQuote && fieldStart >= 0 { // Last field might end at the end of the string.
+		a = append(a, s[fieldStart:])
+	}
+	return a
+}
diff --git a/src/cmd/compile/internal/noder/lex_test.go b/src/cmd/compile/internal/noder/lex_test.go
new file mode 100644
index 0000000..85a3f06
--- /dev/null
+++ b/src/cmd/compile/internal/noder/lex_test.go
@@ -0,0 +1,122 @@
+// 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 noder
+
+import (
+	"reflect"
+	"runtime"
+	"testing"
+
+	"cmd/compile/internal/syntax"
+)
+
+func eq(a, b []string) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for i := 0; i < len(a); i++ {
+		if a[i] != b[i] {
+			return false
+		}
+	}
+	return true
+}
+
+func TestPragmaFields(t *testing.T) {
+	var tests = []struct {
+		in   string
+		want []string
+	}{
+		{"", []string{}},
+		{" \t ", []string{}},
+		{`""""`, []string{`""`, `""`}},
+		{"  a'b'c  ", []string{"a'b'c"}},
+		{"1 2 3 4", []string{"1", "2", "3", "4"}},
+		{"\n☺\t☹\n", []string{"☺", "☹"}},
+		{`"1 2 "  3  " 4 5"`, []string{`"1 2 "`, `3`, `" 4 5"`}},
+		{`"1""2 3""4"`, []string{`"1"`, `"2 3"`, `"4"`}},
+		{`12"34"`, []string{`12`, `"34"`}},
+		{`12"34 `, []string{`12`}},
+	}
+
+	for _, tt := range tests {
+		got := pragmaFields(tt.in)
+		if !eq(got, tt.want) {
+			t.Errorf("pragmaFields(%q) = %v; want %v", tt.in, got, tt.want)
+			continue
+		}
+	}
+}
+
+func TestPragcgo(t *testing.T) {
+	type testStruct struct {
+		in   string
+		want []string
+	}
+
+	var tests = []testStruct{
+		{`go:cgo_export_dynamic local`, []string{`cgo_export_dynamic`, `local`}},
+		{`go:cgo_export_dynamic local remote`, []string{`cgo_export_dynamic`, `local`, `remote`}},
+		{`go:cgo_export_dynamic local' remote'`, []string{`cgo_export_dynamic`, `local'`, `remote'`}},
+		{`go:cgo_export_static local`, []string{`cgo_export_static`, `local`}},
+		{`go:cgo_export_static local remote`, []string{`cgo_export_static`, `local`, `remote`}},
+		{`go:cgo_export_static local' remote'`, []string{`cgo_export_static`, `local'`, `remote'`}},
+		{`go:cgo_import_dynamic local`, []string{`cgo_import_dynamic`, `local`}},
+		{`go:cgo_import_dynamic local remote`, []string{`cgo_import_dynamic`, `local`, `remote`}},
+		{`go:cgo_import_static local`, []string{`cgo_import_static`, `local`}},
+		{`go:cgo_import_static local'`, []string{`cgo_import_static`, `local'`}},
+		{`go:cgo_dynamic_linker "/path/"`, []string{`cgo_dynamic_linker`, `/path/`}},
+		{`go:cgo_dynamic_linker "/p ath/"`, []string{`cgo_dynamic_linker`, `/p ath/`}},
+		{`go:cgo_ldflag "arg"`, []string{`cgo_ldflag`, `arg`}},
+		{`go:cgo_ldflag "a rg"`, []string{`cgo_ldflag`, `a rg`}},
+	}
+
+	if runtime.GOOS != "aix" {
+		tests = append(tests, []testStruct{
+			{`go:cgo_import_dynamic local remote "library"`, []string{`cgo_import_dynamic`, `local`, `remote`, `library`}},
+			{`go:cgo_import_dynamic local' remote' "lib rary"`, []string{`cgo_import_dynamic`, `local'`, `remote'`, `lib rary`}},
+		}...)
+	} else {
+		// cgo_import_dynamic with a library is slightly different on AIX
+		// as the library field must follow the pattern [libc.a/object.o].
+		tests = append(tests, []testStruct{
+			{`go:cgo_import_dynamic local remote "lib.a/obj.o"`, []string{`cgo_import_dynamic`, `local`, `remote`, `lib.a/obj.o`}},
+			// This test must fail.
+			{`go:cgo_import_dynamic local' remote' "library"`, []string{`<unknown position>: usage: //go:cgo_import_dynamic local [remote ["lib.a/object.o"]]`}},
+		}...)
+
+	}
+
+	var p noder
+	var nopos syntax.Pos
+	for _, tt := range tests {
+
+		p.err = make(chan syntax.Error)
+		gotch := make(chan [][]string, 1)
+		go func() {
+			p.pragcgobuf = nil
+			p.pragcgo(nopos, tt.in)
+			if p.pragcgobuf != nil {
+				gotch <- p.pragcgobuf
+			}
+		}()
+
+		select {
+		case e := <-p.err:
+			want := tt.want[0]
+			if e.Error() != want {
+				t.Errorf("pragcgo(%q) = %q; want %q", tt.in, e, want)
+				continue
+			}
+		case got := <-gotch:
+			want := [][]string{tt.want}
+			if !reflect.DeepEqual(got, want) {
+				t.Errorf("pragcgo(%q) = %q; want %q", tt.in, got, want)
+				continue
+			}
+		}
+
+	}
+}
diff --git a/src/cmd/compile/internal/noder/noder.go b/src/cmd/compile/internal/noder/noder.go
new file mode 100644
index 0000000..5fcad09
--- /dev/null
+++ b/src/cmd/compile/internal/noder/noder.go
@@ -0,0 +1,1880 @@
+// 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 noder
+
+import (
+	"fmt"
+	"go/constant"
+	"go/token"
+	"os"
+	"path/filepath"
+	"runtime"
+	"strconv"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/dwarfgen"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/objabi"
+	"cmd/internal/src"
+)
+
+func LoadPackage(filenames []string) {
+	base.Timer.Start("fe", "parse")
+
+	mode := syntax.CheckBranches
+	if base.Flag.G != 0 {
+		mode |= syntax.AllowGenerics
+	}
+
+	// Limit the number of simultaneously open files.
+	sem := make(chan struct{}, runtime.GOMAXPROCS(0)+10)
+
+	noders := make([]*noder, len(filenames))
+	for i, filename := range filenames {
+		p := noder{
+			err:         make(chan syntax.Error),
+			trackScopes: base.Flag.Dwarf,
+		}
+		noders[i] = &p
+
+		filename := filename
+		go func() {
+			sem <- struct{}{}
+			defer func() { <-sem }()
+			defer close(p.err)
+			fbase := syntax.NewFileBase(filename)
+
+			f, err := os.Open(filename)
+			if err != nil {
+				p.error(syntax.Error{Msg: err.Error()})
+				return
+			}
+			defer f.Close()
+
+			p.file, _ = syntax.Parse(fbase, f, p.error, p.pragma, mode) // errors are tracked via p.error
+		}()
+	}
+
+	var lines uint
+	for _, p := range noders {
+		for e := range p.err {
+			p.errorAt(e.Pos, "%s", e.Msg)
+		}
+		if p.file == nil {
+			base.ErrorExit()
+		}
+		lines += p.file.EOF.Line()
+	}
+	base.Timer.AddEvent(int64(lines), "lines")
+
+	if base.Flag.G != 0 {
+		// Use types2 to type-check and possibly generate IR.
+		check2(noders)
+		return
+	}
+
+	for _, p := range noders {
+		p.node()
+		p.file = nil // release memory
+	}
+
+	if base.SyntaxErrors() != 0 {
+		base.ErrorExit()
+	}
+	types.CheckDclstack()
+
+	for _, p := range noders {
+		p.processPragmas()
+	}
+
+	// Typecheck.
+	types.LocalPkg.Height = myheight
+	typecheck.DeclareUniverse()
+	typecheck.TypecheckAllowed = true
+
+	// Process top-level declarations in phases.
+
+	// Phase 1: const, type, and names and types of funcs.
+	//   This will gather all the information about types
+	//   and methods but doesn't depend on any of it.
+	//
+	//   We also defer type alias declarations until phase 2
+	//   to avoid cycles like #18640.
+	//   TODO(gri) Remove this again once we have a fix for #25838.
+
+	// Don't use range--typecheck can add closures to Target.Decls.
+	base.Timer.Start("fe", "typecheck", "top1")
+	for i := 0; i < len(typecheck.Target.Decls); i++ {
+		n := typecheck.Target.Decls[i]
+		if op := n.Op(); op != ir.ODCL && op != ir.OAS && op != ir.OAS2 && (op != ir.ODCLTYPE || !n.(*ir.Decl).X.Alias()) {
+			typecheck.Target.Decls[i] = typecheck.Stmt(n)
+		}
+	}
+
+	// Phase 2: Variable assignments.
+	//   To check interface assignments, depends on phase 1.
+
+	// Don't use range--typecheck can add closures to Target.Decls.
+	base.Timer.Start("fe", "typecheck", "top2")
+	for i := 0; i < len(typecheck.Target.Decls); i++ {
+		n := typecheck.Target.Decls[i]
+		if op := n.Op(); op == ir.ODCL || op == ir.OAS || op == ir.OAS2 || op == ir.ODCLTYPE && n.(*ir.Decl).X.Alias() {
+			typecheck.Target.Decls[i] = typecheck.Stmt(n)
+		}
+	}
+
+	// Phase 3: Type check function bodies.
+	// Don't use range--typecheck can add closures to Target.Decls.
+	base.Timer.Start("fe", "typecheck", "func")
+	var fcount int64
+	for i := 0; i < len(typecheck.Target.Decls); i++ {
+		n := typecheck.Target.Decls[i]
+		if n.Op() == ir.ODCLFUNC {
+			if base.Flag.W > 1 {
+				s := fmt.Sprintf("\nbefore typecheck %v", n)
+				ir.Dump(s, n)
+			}
+			typecheck.FuncBody(n.(*ir.Func))
+			if base.Flag.W > 1 {
+				s := fmt.Sprintf("\nafter typecheck %v", n)
+				ir.Dump(s, n)
+			}
+			fcount++
+		}
+	}
+
+	// Phase 4: Check external declarations.
+	// TODO(mdempsky): This should be handled when type checking their
+	// corresponding ODCL nodes.
+	base.Timer.Start("fe", "typecheck", "externdcls")
+	for i, n := range typecheck.Target.Externs {
+		if n.Op() == ir.ONAME {
+			typecheck.Target.Externs[i] = typecheck.Expr(typecheck.Target.Externs[i])
+		}
+	}
+
+	// Phase 5: With all user code type-checked, it's now safe to verify map keys.
+	// With all user code typechecked, it's now safe to verify unused dot imports.
+	typecheck.CheckMapKeys()
+	CheckDotImports()
+	base.ExitIfErrors()
+}
+
+func (p *noder) errorAt(pos syntax.Pos, format string, args ...interface{}) {
+	base.ErrorfAt(p.makeXPos(pos), format, args...)
+}
+
+// TODO(gri) Can we eliminate fileh in favor of absFilename?
+func fileh(name string) string {
+	return objabi.AbsFile("", name, base.Flag.TrimPath)
+}
+
+func absFilename(name string) string {
+	return objabi.AbsFile(base.Ctxt.Pathname, name, base.Flag.TrimPath)
+}
+
+// noder transforms package syntax's AST into a Node tree.
+type noder struct {
+	posMap
+
+	file           *syntax.File
+	linknames      []linkname
+	pragcgobuf     [][]string
+	err            chan syntax.Error
+	importedUnsafe bool
+	importedEmbed  bool
+	trackScopes    bool
+
+	funcState *funcState
+}
+
+// funcState tracks all per-function state to make handling nested
+// functions easier.
+type funcState struct {
+	// scopeVars is a stack tracking the number of variables declared in
+	// the current function at the moment each open scope was opened.
+	scopeVars []int
+	marker    dwarfgen.ScopeMarker
+
+	lastCloseScopePos syntax.Pos
+}
+
+func (p *noder) funcBody(fn *ir.Func, block *syntax.BlockStmt) {
+	outerFuncState := p.funcState
+	p.funcState = new(funcState)
+	typecheck.StartFuncBody(fn)
+
+	if block != nil {
+		body := p.stmts(block.List)
+		if body == nil {
+			body = []ir.Node{ir.NewBlockStmt(base.Pos, nil)}
+		}
+		fn.Body = body
+
+		base.Pos = p.makeXPos(block.Rbrace)
+		fn.Endlineno = base.Pos
+	}
+
+	typecheck.FinishFuncBody()
+	p.funcState.marker.WriteTo(fn)
+	p.funcState = outerFuncState
+}
+
+func (p *noder) openScope(pos syntax.Pos) {
+	fs := p.funcState
+	types.Markdcl()
+
+	if p.trackScopes {
+		fs.scopeVars = append(fs.scopeVars, len(ir.CurFunc.Dcl))
+		fs.marker.Push(p.makeXPos(pos))
+	}
+}
+
+func (p *noder) closeScope(pos syntax.Pos) {
+	fs := p.funcState
+	fs.lastCloseScopePos = pos
+	types.Popdcl()
+
+	if p.trackScopes {
+		scopeVars := fs.scopeVars[len(fs.scopeVars)-1]
+		fs.scopeVars = fs.scopeVars[:len(fs.scopeVars)-1]
+		if scopeVars == len(ir.CurFunc.Dcl) {
+			// no variables were declared in this scope, so we can retract it.
+			fs.marker.Unpush()
+		} else {
+			fs.marker.Pop(p.makeXPos(pos))
+		}
+	}
+}
+
+// closeAnotherScope is like closeScope, but it reuses the same mark
+// position as the last closeScope call. This is useful for "for" and
+// "if" statements, as their implicit blocks always end at the same
+// position as an explicit block.
+func (p *noder) closeAnotherScope() {
+	p.closeScope(p.funcState.lastCloseScopePos)
+}
+
+// linkname records a //go:linkname directive.
+type linkname struct {
+	pos    syntax.Pos
+	local  string
+	remote string
+}
+
+func (p *noder) node() {
+	p.importedUnsafe = false
+	p.importedEmbed = false
+
+	p.setlineno(p.file.PkgName)
+	mkpackage(p.file.PkgName.Value)
+
+	if pragma, ok := p.file.Pragma.(*pragmas); ok {
+		pragma.Flag &^= ir.GoBuildPragma
+		p.checkUnused(pragma)
+	}
+
+	typecheck.Target.Decls = append(typecheck.Target.Decls, p.decls(p.file.DeclList)...)
+
+	base.Pos = src.NoXPos
+	clearImports()
+}
+
+func (p *noder) processPragmas() {
+	for _, l := range p.linknames {
+		if !p.importedUnsafe {
+			p.errorAt(l.pos, "//go:linkname only allowed in Go files that import \"unsafe\"")
+			continue
+		}
+		n := ir.AsNode(typecheck.Lookup(l.local).Def)
+		if n == nil || n.Op() != ir.ONAME {
+			// TODO(mdempsky): Change to p.errorAt before Go 1.17 release.
+			// base.WarnfAt(p.makeXPos(l.pos), "//go:linkname must refer to declared function or variable (will be an error in Go 1.17)")
+			continue
+		}
+		if n.Sym().Linkname != "" {
+			p.errorAt(l.pos, "duplicate //go:linkname for %s", l.local)
+			continue
+		}
+		n.Sym().Linkname = l.remote
+	}
+	typecheck.Target.CgoPragmas = append(typecheck.Target.CgoPragmas, p.pragcgobuf...)
+}
+
+func (p *noder) decls(decls []syntax.Decl) (l []ir.Node) {
+	var cs constState
+
+	for _, decl := range decls {
+		p.setlineno(decl)
+		switch decl := decl.(type) {
+		case *syntax.ImportDecl:
+			p.importDecl(decl)
+
+		case *syntax.VarDecl:
+			l = append(l, p.varDecl(decl)...)
+
+		case *syntax.ConstDecl:
+			l = append(l, p.constDecl(decl, &cs)...)
+
+		case *syntax.TypeDecl:
+			l = append(l, p.typeDecl(decl))
+
+		case *syntax.FuncDecl:
+			l = append(l, p.funcDecl(decl))
+
+		default:
+			panic("unhandled Decl")
+		}
+	}
+
+	return
+}
+
+func (p *noder) importDecl(imp *syntax.ImportDecl) {
+	if imp.Path == nil || imp.Path.Bad {
+		return // avoid follow-on errors if there was a syntax error
+	}
+
+	if pragma, ok := imp.Pragma.(*pragmas); ok {
+		p.checkUnused(pragma)
+	}
+
+	ipkg := importfile(imp)
+	if ipkg == nil {
+		if base.Errors() == 0 {
+			base.Fatalf("phase error in import")
+		}
+		return
+	}
+
+	if ipkg == ir.Pkgs.Unsafe {
+		p.importedUnsafe = true
+	}
+	if ipkg.Path == "embed" {
+		p.importedEmbed = true
+	}
+
+	var my *types.Sym
+	if imp.LocalPkgName != nil {
+		my = p.name(imp.LocalPkgName)
+	} else {
+		my = typecheck.Lookup(ipkg.Name)
+	}
+
+	pack := ir.NewPkgName(p.pos(imp), my, ipkg)
+
+	switch my.Name {
+	case ".":
+		importDot(pack)
+		return
+	case "init":
+		base.ErrorfAt(pack.Pos(), "cannot import package as init - init must be a func")
+		return
+	case "_":
+		return
+	}
+	if my.Def != nil {
+		typecheck.Redeclared(pack.Pos(), my, "as imported package name")
+	}
+	my.Def = pack
+	my.Lastlineno = pack.Pos()
+	my.Block = 1 // at top level
+}
+
+func (p *noder) varDecl(decl *syntax.VarDecl) []ir.Node {
+	names := p.declNames(ir.ONAME, decl.NameList)
+	typ := p.typeExprOrNil(decl.Type)
+	exprs := p.exprList(decl.Values)
+
+	if pragma, ok := decl.Pragma.(*pragmas); ok {
+		varEmbed(p.makeXPos, names[0], decl, pragma, p.importedEmbed)
+		p.checkUnused(pragma)
+	}
+
+	var init []ir.Node
+	p.setlineno(decl)
+
+	if len(names) > 1 && len(exprs) == 1 {
+		as2 := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, exprs)
+		for _, v := range names {
+			as2.Lhs.Append(v)
+			typecheck.Declare(v, typecheck.DeclContext)
+			v.Ntype = typ
+			v.Defn = as2
+			if ir.CurFunc != nil {
+				init = append(init, ir.NewDecl(base.Pos, ir.ODCL, v))
+			}
+		}
+
+		return append(init, as2)
+	}
+
+	for i, v := range names {
+		var e ir.Node
+		if i < len(exprs) {
+			e = exprs[i]
+		}
+
+		typecheck.Declare(v, typecheck.DeclContext)
+		v.Ntype = typ
+
+		if ir.CurFunc != nil {
+			init = append(init, ir.NewDecl(base.Pos, ir.ODCL, v))
+		}
+		as := ir.NewAssignStmt(base.Pos, v, e)
+		init = append(init, as)
+		if e != nil || ir.CurFunc == nil {
+			v.Defn = as
+		}
+	}
+
+	if len(exprs) != 0 && len(names) != len(exprs) {
+		base.Errorf("assignment mismatch: %d variables but %d values", len(names), len(exprs))
+	}
+
+	return init
+}
+
+// constState tracks state between constant specifiers within a
+// declaration group. This state is kept separate from noder so nested
+// constant declarations are handled correctly (e.g., issue 15550).
+type constState struct {
+	group  *syntax.Group
+	typ    ir.Ntype
+	values []ir.Node
+	iota   int64
+}
+
+func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []ir.Node {
+	if decl.Group == nil || decl.Group != cs.group {
+		*cs = constState{
+			group: decl.Group,
+		}
+	}
+
+	if pragma, ok := decl.Pragma.(*pragmas); ok {
+		p.checkUnused(pragma)
+	}
+
+	names := p.declNames(ir.OLITERAL, decl.NameList)
+	typ := p.typeExprOrNil(decl.Type)
+
+	var values []ir.Node
+	if decl.Values != nil {
+		values = p.exprList(decl.Values)
+		cs.typ, cs.values = typ, values
+	} else {
+		if typ != nil {
+			base.Errorf("const declaration cannot have type without expression")
+		}
+		typ, values = cs.typ, cs.values
+	}
+
+	nn := make([]ir.Node, 0, len(names))
+	for i, n := range names {
+		if i >= len(values) {
+			base.Errorf("missing value in const declaration")
+			break
+		}
+		v := values[i]
+		if decl.Values == nil {
+			v = ir.DeepCopy(n.Pos(), v)
+		}
+		typecheck.Declare(n, typecheck.DeclContext)
+
+		n.Ntype = typ
+		n.Defn = v
+		n.SetIota(cs.iota)
+
+		nn = append(nn, ir.NewDecl(p.pos(decl), ir.ODCLCONST, n))
+	}
+
+	if len(values) > len(names) {
+		base.Errorf("extra expression in const declaration")
+	}
+
+	cs.iota++
+
+	return nn
+}
+
+func (p *noder) typeDecl(decl *syntax.TypeDecl) ir.Node {
+	n := p.declName(ir.OTYPE, decl.Name)
+	typecheck.Declare(n, typecheck.DeclContext)
+
+	// decl.Type may be nil but in that case we got a syntax error during parsing
+	typ := p.typeExprOrNil(decl.Type)
+
+	n.Ntype = typ
+	n.SetAlias(decl.Alias)
+	if pragma, ok := decl.Pragma.(*pragmas); ok {
+		if !decl.Alias {
+			n.SetPragma(pragma.Flag & typePragmas)
+			pragma.Flag &^= typePragmas
+		}
+		p.checkUnused(pragma)
+	}
+
+	nod := ir.NewDecl(p.pos(decl), ir.ODCLTYPE, n)
+	if n.Alias() && !types.AllowsGoVersion(types.LocalPkg, 1, 9) {
+		base.ErrorfAt(nod.Pos(), "type aliases only supported as of -lang=go1.9")
+	}
+	return nod
+}
+
+func (p *noder) declNames(op ir.Op, names []*syntax.Name) []*ir.Name {
+	nodes := make([]*ir.Name, 0, len(names))
+	for _, name := range names {
+		nodes = append(nodes, p.declName(op, name))
+	}
+	return nodes
+}
+
+func (p *noder) declName(op ir.Op, name *syntax.Name) *ir.Name {
+	return ir.NewDeclNameAt(p.pos(name), op, p.name(name))
+}
+
+func (p *noder) funcDecl(fun *syntax.FuncDecl) ir.Node {
+	name := p.name(fun.Name)
+	t := p.signature(fun.Recv, fun.Type)
+	f := ir.NewFunc(p.pos(fun))
+
+	if fun.Recv == nil {
+		if name.Name == "init" {
+			name = renameinit()
+			if len(t.Params) > 0 || len(t.Results) > 0 {
+				base.ErrorfAt(f.Pos(), "func init must have no arguments and no return values")
+			}
+			typecheck.Target.Inits = append(typecheck.Target.Inits, f)
+		}
+
+		if types.LocalPkg.Name == "main" && name.Name == "main" {
+			if len(t.Params) > 0 || len(t.Results) > 0 {
+				base.ErrorfAt(f.Pos(), "func main must have no arguments and no return values")
+			}
+		}
+	} else {
+		f.Shortname = name
+		name = ir.BlankNode.Sym() // filled in by tcFunc
+	}
+
+	f.Nname = ir.NewNameAt(p.pos(fun.Name), name)
+	f.Nname.Func = f
+	f.Nname.Defn = f
+	f.Nname.Ntype = t
+
+	if pragma, ok := fun.Pragma.(*pragmas); ok {
+		f.Pragma = pragma.Flag & funcPragmas
+		if pragma.Flag&ir.Systemstack != 0 && pragma.Flag&ir.Nosplit != 0 {
+			base.ErrorfAt(f.Pos(), "go:nosplit and go:systemstack cannot be combined")
+		}
+		pragma.Flag &^= funcPragmas
+		p.checkUnused(pragma)
+	}
+
+	if fun.Recv == nil {
+		typecheck.Declare(f.Nname, ir.PFUNC)
+	}
+
+	p.funcBody(f, fun.Body)
+
+	if fun.Body != nil {
+		if f.Pragma&ir.Noescape != 0 {
+			base.ErrorfAt(f.Pos(), "can only use //go:noescape with external func implementations")
+		}
+	} else {
+		if base.Flag.Complete || strings.HasPrefix(ir.FuncName(f), "init.") {
+			// Linknamed functions are allowed to have no body. Hopefully
+			// the linkname target has a body. See issue 23311.
+			isLinknamed := false
+			for _, n := range p.linknames {
+				if ir.FuncName(f) == n.local {
+					isLinknamed = true
+					break
+				}
+			}
+			if !isLinknamed {
+				base.ErrorfAt(f.Pos(), "missing function body")
+			}
+		}
+	}
+
+	return f
+}
+
+func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *ir.FuncType {
+	var rcvr *ir.Field
+	if recv != nil {
+		rcvr = p.param(recv, false, false)
+	}
+	return ir.NewFuncType(p.pos(typ), rcvr,
+		p.params(typ.ParamList, true),
+		p.params(typ.ResultList, false))
+}
+
+func (p *noder) params(params []*syntax.Field, dddOk bool) []*ir.Field {
+	nodes := make([]*ir.Field, 0, len(params))
+	for i, param := range params {
+		p.setlineno(param)
+		nodes = append(nodes, p.param(param, dddOk, i+1 == len(params)))
+	}
+	return nodes
+}
+
+func (p *noder) param(param *syntax.Field, dddOk, final bool) *ir.Field {
+	var name *types.Sym
+	if param.Name != nil {
+		name = p.name(param.Name)
+	}
+
+	typ := p.typeExpr(param.Type)
+	n := ir.NewField(p.pos(param), name, typ, nil)
+
+	// rewrite ...T parameter
+	if typ, ok := typ.(*ir.SliceType); ok && typ.DDD {
+		if !dddOk {
+			// We mark these as syntax errors to get automatic elimination
+			// of multiple such errors per line (see ErrorfAt in subr.go).
+			base.Errorf("syntax error: cannot use ... in receiver or result parameter list")
+		} else if !final {
+			if param.Name == nil {
+				base.Errorf("syntax error: cannot use ... with non-final parameter")
+			} else {
+				p.errorAt(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value)
+			}
+		}
+		typ.DDD = false
+		n.IsDDD = true
+	}
+
+	return n
+}
+
+func (p *noder) exprList(expr syntax.Expr) []ir.Node {
+	switch expr := expr.(type) {
+	case nil:
+		return nil
+	case *syntax.ListExpr:
+		return p.exprs(expr.ElemList)
+	default:
+		return []ir.Node{p.expr(expr)}
+	}
+}
+
+func (p *noder) exprs(exprs []syntax.Expr) []ir.Node {
+	nodes := make([]ir.Node, 0, len(exprs))
+	for _, expr := range exprs {
+		nodes = append(nodes, p.expr(expr))
+	}
+	return nodes
+}
+
+func (p *noder) expr(expr syntax.Expr) ir.Node {
+	p.setlineno(expr)
+	switch expr := expr.(type) {
+	case nil, *syntax.BadExpr:
+		return nil
+	case *syntax.Name:
+		return p.mkname(expr)
+	case *syntax.BasicLit:
+		n := ir.NewBasicLit(p.pos(expr), p.basicLit(expr))
+		if expr.Kind == syntax.RuneLit {
+			n.SetType(types.UntypedRune)
+		}
+		n.SetDiag(expr.Bad || n.Val().Kind() == constant.Unknown) // avoid follow-on errors if there was a syntax error
+		return n
+	case *syntax.CompositeLit:
+		n := ir.NewCompLitExpr(p.pos(expr), ir.OCOMPLIT, p.typeExpr(expr.Type), nil)
+		l := p.exprs(expr.ElemList)
+		for i, e := range l {
+			l[i] = p.wrapname(expr.ElemList[i], e)
+		}
+		n.List = l
+		base.Pos = p.makeXPos(expr.Rbrace)
+		return n
+	case *syntax.KeyValueExpr:
+		// use position of expr.Key rather than of expr (which has position of ':')
+		return ir.NewKeyExpr(p.pos(expr.Key), p.expr(expr.Key), p.wrapname(expr.Value, p.expr(expr.Value)))
+	case *syntax.FuncLit:
+		return p.funcLit(expr)
+	case *syntax.ParenExpr:
+		return ir.NewParenExpr(p.pos(expr), p.expr(expr.X))
+	case *syntax.SelectorExpr:
+		// parser.new_dotname
+		obj := p.expr(expr.X)
+		if obj.Op() == ir.OPACK {
+			pack := obj.(*ir.PkgName)
+			pack.Used = true
+			return importName(pack.Pkg.Lookup(expr.Sel.Value))
+		}
+		n := ir.NewSelectorExpr(base.Pos, ir.OXDOT, obj, p.name(expr.Sel))
+		n.SetPos(p.pos(expr)) // lineno may have been changed by p.expr(expr.X)
+		return n
+	case *syntax.IndexExpr:
+		return ir.NewIndexExpr(p.pos(expr), p.expr(expr.X), p.expr(expr.Index))
+	case *syntax.SliceExpr:
+		op := ir.OSLICE
+		if expr.Full {
+			op = ir.OSLICE3
+		}
+		x := p.expr(expr.X)
+		var index [3]ir.Node
+		for i, n := range &expr.Index {
+			if n != nil {
+				index[i] = p.expr(n)
+			}
+		}
+		return ir.NewSliceExpr(p.pos(expr), op, x, index[0], index[1], index[2])
+	case *syntax.AssertExpr:
+		return ir.NewTypeAssertExpr(p.pos(expr), p.expr(expr.X), p.typeExpr(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 {
+			pos, op := p.pos(expr), p.unOp(expr.Op)
+			switch op {
+			case ir.OADDR:
+				return typecheck.NodAddrAt(pos, x)
+			case ir.ODEREF:
+				return ir.NewStarExpr(pos, x)
+			}
+			return ir.NewUnaryExpr(pos, op, x)
+		}
+
+		pos, op, y := p.pos(expr), p.binOp(expr.Op), p.expr(expr.Y)
+		switch op {
+		case ir.OANDAND, ir.OOROR:
+			return ir.NewLogicalExpr(pos, op, x, y)
+		}
+		return ir.NewBinaryExpr(pos, op, x, y)
+	case *syntax.CallExpr:
+		n := ir.NewCallExpr(p.pos(expr), ir.OCALL, p.expr(expr.Fun), p.exprs(expr.ArgList))
+		n.IsDDD = expr.HasDots
+		return n
+
+	case *syntax.ArrayType:
+		var len ir.Node
+		if expr.Len != nil {
+			len = p.expr(expr.Len)
+		}
+		return ir.NewArrayType(p.pos(expr), len, p.typeExpr(expr.Elem))
+	case *syntax.SliceType:
+		return ir.NewSliceType(p.pos(expr), p.typeExpr(expr.Elem))
+	case *syntax.DotsType:
+		t := ir.NewSliceType(p.pos(expr), p.typeExpr(expr.Elem))
+		t.DDD = true
+		return t
+	case *syntax.StructType:
+		return p.structType(expr)
+	case *syntax.InterfaceType:
+		return p.interfaceType(expr)
+	case *syntax.FuncType:
+		return p.signature(nil, expr)
+	case *syntax.MapType:
+		return ir.NewMapType(p.pos(expr),
+			p.typeExpr(expr.Key), p.typeExpr(expr.Value))
+	case *syntax.ChanType:
+		return ir.NewChanType(p.pos(expr),
+			p.typeExpr(expr.Elem), p.chanDir(expr.Dir))
+
+	case *syntax.TypeSwitchGuard:
+		var tag *ir.Ident
+		if expr.Lhs != nil {
+			tag = ir.NewIdent(p.pos(expr.Lhs), p.name(expr.Lhs))
+			if ir.IsBlank(tag) {
+				base.Errorf("invalid variable name %v in type switch", tag)
+			}
+		}
+		return ir.NewTypeSwitchGuard(p.pos(expr), tag, p.expr(expr.X))
+	}
+	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) ir.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 ir.Node
+	chunks := make([]string, 0, 1)
+
+	n := p.expr(x)
+	if ir.IsConst(n, constant.String) && n.Sym() == nil {
+		nstr = n
+		chunks = append(chunks, ir.StringVal(nstr))
+	}
+
+	for i := len(adds) - 1; i >= 0; i-- {
+		add := adds[i]
+
+		r := p.expr(add.Y)
+		if ir.IsConst(r, constant.String) && r.Sym() == nil {
+			if nstr != nil {
+				// Collapse r into nstr instead of adding to n.
+				chunks = append(chunks, ir.StringVal(r))
+				continue
+			}
+
+			nstr = r
+			chunks = append(chunks, ir.StringVal(nstr))
+		} else {
+			if len(chunks) > 1 {
+				nstr.SetVal(constant.MakeString(strings.Join(chunks, "")))
+			}
+			nstr = nil
+			chunks = chunks[:0]
+		}
+		n = ir.NewBinaryExpr(p.pos(add), ir.OADD, n, r)
+	}
+	if len(chunks) > 1 {
+		nstr.SetVal(constant.MakeString(strings.Join(chunks, "")))
+	}
+
+	return n
+}
+
+func (p *noder) typeExpr(typ syntax.Expr) ir.Ntype {
+	// TODO(mdempsky): Be stricter? typecheck should handle errors anyway.
+	n := p.expr(typ)
+	if n == nil {
+		return nil
+	}
+	return n.(ir.Ntype)
+}
+
+func (p *noder) typeExprOrNil(typ syntax.Expr) ir.Ntype {
+	if typ != nil {
+		return p.typeExpr(typ)
+	}
+	return nil
+}
+
+func (p *noder) chanDir(dir syntax.ChanDir) types.ChanDir {
+	switch dir {
+	case 0:
+		return types.Cboth
+	case syntax.SendOnly:
+		return types.Csend
+	case syntax.RecvOnly:
+		return types.Crecv
+	}
+	panic("unhandled ChanDir")
+}
+
+func (p *noder) structType(expr *syntax.StructType) ir.Node {
+	l := make([]*ir.Field, 0, len(expr.FieldList))
+	for i, field := range expr.FieldList {
+		p.setlineno(field)
+		var n *ir.Field
+		if field.Name == nil {
+			n = p.embedded(field.Type)
+		} else {
+			n = ir.NewField(p.pos(field), p.name(field.Name), p.typeExpr(field.Type), nil)
+		}
+		if i < len(expr.TagList) && expr.TagList[i] != nil {
+			n.Note = constant.StringVal(p.basicLit(expr.TagList[i]))
+		}
+		l = append(l, n)
+	}
+
+	p.setlineno(expr)
+	return ir.NewStructType(p.pos(expr), l)
+}
+
+func (p *noder) interfaceType(expr *syntax.InterfaceType) ir.Node {
+	l := make([]*ir.Field, 0, len(expr.MethodList))
+	for _, method := range expr.MethodList {
+		p.setlineno(method)
+		var n *ir.Field
+		if method.Name == nil {
+			n = ir.NewField(p.pos(method), nil, importName(p.packname(method.Type)).(ir.Ntype), nil)
+		} else {
+			mname := p.name(method.Name)
+			if mname.IsBlank() {
+				base.Errorf("methods must have a unique non-blank name")
+				continue
+			}
+			sig := p.typeExpr(method.Type).(*ir.FuncType)
+			sig.Recv = fakeRecv()
+			n = ir.NewField(p.pos(method), mname, sig, nil)
+		}
+		l = append(l, n)
+	}
+
+	return ir.NewInterfaceType(p.pos(expr), l)
+}
+
+func (p *noder) packname(expr syntax.Expr) *types.Sym {
+	switch expr := expr.(type) {
+	case *syntax.Name:
+		name := p.name(expr)
+		if n := oldname(name); n.Name() != nil && n.Name().PkgName != nil {
+			n.Name().PkgName.Used = true
+		}
+		return name
+	case *syntax.SelectorExpr:
+		name := p.name(expr.X.(*syntax.Name))
+		def := ir.AsNode(name.Def)
+		if def == nil {
+			base.Errorf("undefined: %v", name)
+			return name
+		}
+		var pkg *types.Pkg
+		if def.Op() != ir.OPACK {
+			base.Errorf("%v is not a package", name)
+			pkg = types.LocalPkg
+		} else {
+			def := def.(*ir.PkgName)
+			def.Used = true
+			pkg = def.Pkg
+		}
+		return pkg.Lookup(expr.Sel.Value)
+	}
+	panic(fmt.Sprintf("unexpected packname: %#v", expr))
+}
+
+func (p *noder) embedded(typ syntax.Expr) *ir.Field {
+	op, isStar := typ.(*syntax.Operation)
+	if isStar {
+		if op.Op != syntax.Mul || op.Y != nil {
+			panic("unexpected Operation")
+		}
+		typ = op.X
+	}
+
+	sym := p.packname(typ)
+	n := ir.NewField(p.pos(typ), typecheck.Lookup(sym.Name), importName(sym).(ir.Ntype), nil)
+	n.Embedded = true
+
+	if isStar {
+		n.Ntype = ir.NewStarExpr(p.pos(op), n.Ntype)
+	}
+	return n
+}
+
+func (p *noder) stmts(stmts []syntax.Stmt) []ir.Node {
+	return p.stmtsFall(stmts, false)
+}
+
+func (p *noder) stmtsFall(stmts []syntax.Stmt, fallOK bool) []ir.Node {
+	var nodes []ir.Node
+	for i, stmt := range stmts {
+		s := p.stmtFall(stmt, fallOK && i+1 == len(stmts))
+		if s == nil {
+		} else if s.Op() == ir.OBLOCK && len(s.(*ir.BlockStmt).List) > 0 {
+			// Inline non-empty block.
+			// Empty blocks must be preserved for CheckReturn.
+			nodes = append(nodes, s.(*ir.BlockStmt).List...)
+		} else {
+			nodes = append(nodes, s)
+		}
+	}
+	return nodes
+}
+
+func (p *noder) stmt(stmt syntax.Stmt) ir.Node {
+	return p.stmtFall(stmt, false)
+}
+
+func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node {
+	p.setlineno(stmt)
+	switch stmt := stmt.(type) {
+	case nil, *syntax.EmptyStmt:
+		return nil
+	case *syntax.LabeledStmt:
+		return p.labeledStmt(stmt, fallOK)
+	case *syntax.BlockStmt:
+		l := p.blockStmt(stmt)
+		if len(l) == 0 {
+			// TODO(mdempsky): Line number?
+			return ir.NewBlockStmt(base.Pos, nil)
+		}
+		return ir.NewBlockStmt(src.NoXPos, l)
+	case *syntax.ExprStmt:
+		return p.wrapname(stmt, p.expr(stmt.X))
+	case *syntax.SendStmt:
+		return ir.NewSendStmt(p.pos(stmt), p.expr(stmt.Chan), p.expr(stmt.Value))
+	case *syntax.DeclStmt:
+		return ir.NewBlockStmt(src.NoXPos, p.decls(stmt.DeclList))
+	case *syntax.AssignStmt:
+		if stmt.Rhs == nil {
+			pos := p.pos(stmt)
+			n := ir.NewAssignOpStmt(pos, p.binOp(stmt.Op), p.expr(stmt.Lhs), ir.NewBasicLit(pos, one))
+			n.IncDec = true
+			return n
+		}
+
+		if stmt.Op != 0 && stmt.Op != syntax.Def {
+			n := ir.NewAssignOpStmt(p.pos(stmt), p.binOp(stmt.Op), p.expr(stmt.Lhs), p.expr(stmt.Rhs))
+			return n
+		}
+
+		rhs := p.exprList(stmt.Rhs)
+		if list, ok := stmt.Lhs.(*syntax.ListExpr); ok && len(list.ElemList) != 1 || len(rhs) != 1 {
+			n := ir.NewAssignListStmt(p.pos(stmt), ir.OAS2, nil, nil)
+			n.Def = stmt.Op == syntax.Def
+			n.Lhs = p.assignList(stmt.Lhs, n, n.Def)
+			n.Rhs = rhs
+			return n
+		}
+
+		n := ir.NewAssignStmt(p.pos(stmt), nil, nil)
+		n.Def = stmt.Op == syntax.Def
+		n.X = p.assignList(stmt.Lhs, n, n.Def)[0]
+		n.Y = rhs[0]
+		return n
+
+	case *syntax.BranchStmt:
+		var op ir.Op
+		switch stmt.Tok {
+		case syntax.Break:
+			op = ir.OBREAK
+		case syntax.Continue:
+			op = ir.OCONTINUE
+		case syntax.Fallthrough:
+			if !fallOK {
+				base.Errorf("fallthrough statement out of place")
+			}
+			op = ir.OFALL
+		case syntax.Goto:
+			op = ir.OGOTO
+		default:
+			panic("unhandled BranchStmt")
+		}
+		var sym *types.Sym
+		if stmt.Label != nil {
+			sym = p.name(stmt.Label)
+		}
+		return ir.NewBranchStmt(p.pos(stmt), op, sym)
+	case *syntax.CallStmt:
+		var op ir.Op
+		switch stmt.Tok {
+		case syntax.Defer:
+			op = ir.ODEFER
+		case syntax.Go:
+			op = ir.OGO
+		default:
+			panic("unhandled CallStmt")
+		}
+		return ir.NewGoDeferStmt(p.pos(stmt), op, p.expr(stmt.Call))
+	case *syntax.ReturnStmt:
+		n := ir.NewReturnStmt(p.pos(stmt), p.exprList(stmt.Results))
+		if len(n.Results) == 0 && ir.CurFunc != nil {
+			for _, ln := range ir.CurFunc.Dcl {
+				if ln.Class == ir.PPARAM {
+					continue
+				}
+				if ln.Class != ir.PPARAMOUT {
+					break
+				}
+				if ln.Sym().Def != ln {
+					base.Errorf("%s is shadowed during return", ln.Sym().Name)
+				}
+			}
+		}
+		return n
+	case *syntax.IfStmt:
+		return p.ifStmt(stmt)
+	case *syntax.ForStmt:
+		return p.forStmt(stmt)
+	case *syntax.SwitchStmt:
+		return p.switchStmt(stmt)
+	case *syntax.SelectStmt:
+		return p.selectStmt(stmt)
+	}
+	panic("unhandled Stmt")
+}
+
+func (p *noder) assignList(expr syntax.Expr, defn ir.InitNode, colas bool) []ir.Node {
+	if !colas {
+		return p.exprList(expr)
+	}
+
+	var exprs []syntax.Expr
+	if list, ok := expr.(*syntax.ListExpr); ok {
+		exprs = list.ElemList
+	} else {
+		exprs = []syntax.Expr{expr}
+	}
+
+	res := make([]ir.Node, len(exprs))
+	seen := make(map[*types.Sym]bool, len(exprs))
+
+	newOrErr := false
+	for i, expr := range exprs {
+		p.setlineno(expr)
+		res[i] = ir.BlankNode
+
+		name, ok := expr.(*syntax.Name)
+		if !ok {
+			p.errorAt(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] {
+			p.errorAt(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 := typecheck.NewName(sym)
+		typecheck.Declare(n, typecheck.DeclContext)
+		n.Defn = defn
+		defn.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, n))
+		res[i] = n
+	}
+
+	if !newOrErr {
+		base.ErrorfAt(defn.Pos(), "no new variables on left side of :=")
+	}
+	return res
+}
+
+func (p *noder) blockStmt(stmt *syntax.BlockStmt) []ir.Node {
+	p.openScope(stmt.Pos())
+	nodes := p.stmts(stmt.List)
+	p.closeScope(stmt.Rbrace)
+	return nodes
+}
+
+func (p *noder) ifStmt(stmt *syntax.IfStmt) ir.Node {
+	p.openScope(stmt.Pos())
+	init := p.stmt(stmt.Init)
+	n := ir.NewIfStmt(p.pos(stmt), p.expr(stmt.Cond), p.blockStmt(stmt.Then), nil)
+	if init != nil {
+		*n.PtrInit() = []ir.Node{init}
+	}
+	if stmt.Else != nil {
+		e := p.stmt(stmt.Else)
+		if e.Op() == ir.OBLOCK {
+			e := e.(*ir.BlockStmt)
+			n.Else = e.List
+		} else {
+			n.Else = []ir.Node{e}
+		}
+	}
+	p.closeAnotherScope()
+	return n
+}
+
+func (p *noder) forStmt(stmt *syntax.ForStmt) ir.Node {
+	p.openScope(stmt.Pos())
+	if r, ok := stmt.Init.(*syntax.RangeClause); ok {
+		if stmt.Cond != nil || stmt.Post != nil {
+			panic("unexpected RangeClause")
+		}
+
+		n := ir.NewRangeStmt(p.pos(r), nil, nil, p.expr(r.X), nil)
+		if r.Lhs != nil {
+			n.Def = r.Def
+			lhs := p.assignList(r.Lhs, n, n.Def)
+			n.Key = lhs[0]
+			if len(lhs) > 1 {
+				n.Value = lhs[1]
+			}
+		}
+		n.Body = p.blockStmt(stmt.Body)
+		p.closeAnotherScope()
+		return n
+	}
+
+	n := ir.NewForStmt(p.pos(stmt), p.stmt(stmt.Init), p.expr(stmt.Cond), p.stmt(stmt.Post), p.blockStmt(stmt.Body))
+	p.closeAnotherScope()
+	return n
+}
+
+func (p *noder) switchStmt(stmt *syntax.SwitchStmt) ir.Node {
+	p.openScope(stmt.Pos())
+
+	init := p.stmt(stmt.Init)
+	n := ir.NewSwitchStmt(p.pos(stmt), p.expr(stmt.Tag), nil)
+	if init != nil {
+		*n.PtrInit() = []ir.Node{init}
+	}
+
+	var tswitch *ir.TypeSwitchGuard
+	if l := n.Tag; l != nil && l.Op() == ir.OTYPESW {
+		tswitch = l.(*ir.TypeSwitchGuard)
+	}
+	n.Cases = p.caseClauses(stmt.Body, tswitch, stmt.Rbrace)
+
+	p.closeScope(stmt.Rbrace)
+	return n
+}
+
+func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *ir.TypeSwitchGuard, rbrace syntax.Pos) []*ir.CaseClause {
+	nodes := make([]*ir.CaseClause, 0, len(clauses))
+	for i, clause := range clauses {
+		p.setlineno(clause)
+		if i > 0 {
+			p.closeScope(clause.Pos())
+		}
+		p.openScope(clause.Pos())
+
+		n := ir.NewCaseStmt(p.pos(clause), p.exprList(clause.Cases), nil)
+		if tswitch != nil && tswitch.Tag != nil {
+			nn := typecheck.NewName(tswitch.Tag.Sym())
+			typecheck.Declare(nn, typecheck.DeclContext)
+			n.Var = nn
+			// keep track of the instances for reporting unused
+			nn.Defn = tswitch
+		}
+
+		// 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.Body = p.stmtsFall(body, true)
+		if l := len(n.Body); l > 0 && n.Body[l-1].Op() == ir.OFALL {
+			if tswitch != nil {
+				base.Errorf("cannot fallthrough in type switch")
+			}
+			if i+1 == len(clauses) {
+				base.Errorf("cannot fallthrough final case in switch")
+			}
+		}
+
+		nodes = append(nodes, n)
+	}
+	if len(clauses) > 0 {
+		p.closeScope(rbrace)
+	}
+	return nodes
+}
+
+func (p *noder) selectStmt(stmt *syntax.SelectStmt) ir.Node {
+	return ir.NewSelectStmt(p.pos(stmt), p.commClauses(stmt.Body, stmt.Rbrace))
+}
+
+func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*ir.CommClause {
+	nodes := make([]*ir.CommClause, len(clauses))
+	for i, clause := range clauses {
+		p.setlineno(clause)
+		if i > 0 {
+			p.closeScope(clause.Pos())
+		}
+		p.openScope(clause.Pos())
+
+		nodes[i] = ir.NewCommStmt(p.pos(clause), p.stmt(clause.Comm), p.stmts(clause.Body))
+	}
+	if len(clauses) > 0 {
+		p.closeScope(rbrace)
+	}
+	return nodes
+}
+
+func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) ir.Node {
+	sym := p.name(label.Label)
+	lhs := ir.NewLabelStmt(p.pos(label), sym)
+
+	var ls ir.Node
+	if label.Stmt != nil { // TODO(mdempsky): Should always be present.
+		ls = p.stmtFall(label.Stmt, fallOK)
+		// Attach label directly to control statement too.
+		if ls != nil {
+			switch ls.Op() {
+			case ir.OFOR:
+				ls := ls.(*ir.ForStmt)
+				ls.Label = sym
+			case ir.ORANGE:
+				ls := ls.(*ir.RangeStmt)
+				ls.Label = sym
+			case ir.OSWITCH:
+				ls := ls.(*ir.SwitchStmt)
+				ls.Label = sym
+			case ir.OSELECT:
+				ls := ls.(*ir.SelectStmt)
+				ls.Label = sym
+			}
+		}
+	}
+
+	l := []ir.Node{lhs}
+	if ls != nil {
+		if ls.Op() == ir.OBLOCK {
+			ls := ls.(*ir.BlockStmt)
+			l = append(l, ls.List...)
+		} else {
+			l = append(l, ls)
+		}
+	}
+	return ir.NewBlockStmt(src.NoXPos, l)
+}
+
+var unOps = [...]ir.Op{
+	syntax.Recv: ir.ORECV,
+	syntax.Mul:  ir.ODEREF,
+	syntax.And:  ir.OADDR,
+
+	syntax.Not: ir.ONOT,
+	syntax.Xor: ir.OBITNOT,
+	syntax.Add: ir.OPLUS,
+	syntax.Sub: ir.ONEG,
+}
+
+func (p *noder) unOp(op syntax.Operator) ir.Op {
+	if uint64(op) >= uint64(len(unOps)) || unOps[op] == 0 {
+		panic("invalid Operator")
+	}
+	return unOps[op]
+}
+
+var binOps = [...]ir.Op{
+	syntax.OrOr:   ir.OOROR,
+	syntax.AndAnd: ir.OANDAND,
+
+	syntax.Eql: ir.OEQ,
+	syntax.Neq: ir.ONE,
+	syntax.Lss: ir.OLT,
+	syntax.Leq: ir.OLE,
+	syntax.Gtr: ir.OGT,
+	syntax.Geq: ir.OGE,
+
+	syntax.Add: ir.OADD,
+	syntax.Sub: ir.OSUB,
+	syntax.Or:  ir.OOR,
+	syntax.Xor: ir.OXOR,
+
+	syntax.Mul:    ir.OMUL,
+	syntax.Div:    ir.ODIV,
+	syntax.Rem:    ir.OMOD,
+	syntax.And:    ir.OAND,
+	syntax.AndNot: ir.OANDNOT,
+	syntax.Shl:    ir.OLSH,
+	syntax.Shr:    ir.ORSH,
+}
+
+func (p *noder) binOp(op syntax.Operator) ir.Op {
+	if uint64(op) >= uint64(len(binOps)) || binOps[op] == 0 {
+		panic("invalid Operator")
+	}
+	return binOps[op]
+}
+
+// checkLangCompat reports an error if the representation of a numeric
+// literal is not compatible with the current language version.
+func checkLangCompat(lit *syntax.BasicLit) {
+	s := lit.Value
+	if len(s) <= 2 || types.AllowsGoVersion(types.LocalPkg, 1, 13) {
+		return
+	}
+	// len(s) > 2
+	if strings.Contains(s, "_") {
+		base.ErrorfVers("go1.13", "underscores in numeric literals")
+		return
+	}
+	if s[0] != '0' {
+		return
+	}
+	radix := s[1]
+	if radix == 'b' || radix == 'B' {
+		base.ErrorfVers("go1.13", "binary literals")
+		return
+	}
+	if radix == 'o' || radix == 'O' {
+		base.ErrorfVers("go1.13", "0o/0O-style octal literals")
+		return
+	}
+	if lit.Kind != syntax.IntLit && (radix == 'x' || radix == 'X') {
+		base.ErrorfVers("go1.13", "hexadecimal floating-point literals")
+	}
+}
+
+func (p *noder) basicLit(lit *syntax.BasicLit) constant.Value {
+	// We don't use the errors of the conversion routines to determine
+	// if a literal string is valid because the conversion routines may
+	// accept a wider syntax than the language permits. Rely on lit.Bad
+	// instead.
+	if lit.Bad {
+		return constant.MakeUnknown()
+	}
+
+	switch lit.Kind {
+	case syntax.IntLit, syntax.FloatLit, syntax.ImagLit:
+		checkLangCompat(lit)
+		// The max. mantissa precision for untyped numeric values
+		// is 512 bits, or 4048 bits for each of the two integer
+		// parts of a fraction for floating-point numbers that are
+		// represented accurately in the go/constant package.
+		// Constant literals that are longer than this many bits
+		// are not meaningful; and excessively long constants may
+		// consume a lot of space and time for a useless conversion.
+		// Cap constant length with a generous upper limit that also
+		// allows for separators between all digits.
+		const limit = 10000
+		if len(lit.Value) > limit {
+			p.errorAt(lit.Pos(), "excessively long constant: %s... (%d chars)", lit.Value[:10], len(lit.Value))
+			return constant.MakeUnknown()
+		}
+	}
+
+	v := constant.MakeFromLiteral(lit.Value, tokenForLitKind[lit.Kind], 0)
+	if v.Kind() == constant.Unknown {
+		// TODO(mdempsky): Better error message?
+		p.errorAt(lit.Pos(), "malformed constant: %s", lit.Value)
+	}
+
+	return v
+}
+
+var tokenForLitKind = [...]token.Token{
+	syntax.IntLit:    token.INT,
+	syntax.RuneLit:   token.CHAR,
+	syntax.FloatLit:  token.FLOAT,
+	syntax.ImagLit:   token.IMAG,
+	syntax.StringLit: token.STRING,
+}
+
+func (p *noder) name(name *syntax.Name) *types.Sym {
+	return typecheck.Lookup(name.Value)
+}
+
+func (p *noder) mkname(name *syntax.Name) ir.Node {
+	// TODO(mdempsky): Set line number?
+	return mkname(p.name(name))
+}
+
+func (p *noder) wrapname(n syntax.Node, x ir.Node) ir.Node {
+	// These nodes do not carry line numbers.
+	// Introduce a wrapper node to give them the correct line.
+	switch x.Op() {
+	case ir.OTYPE, ir.OLITERAL:
+		if x.Sym() == nil {
+			break
+		}
+		fallthrough
+	case ir.ONAME, ir.ONONAME, ir.OPACK:
+		p := ir.NewParenExpr(p.pos(n), x)
+		p.SetImplicit(true)
+		return p
+	}
+	return x
+}
+
+func (p *noder) setlineno(n syntax.Node) {
+	if n != nil {
+		base.Pos = p.pos(n)
+	}
+}
+
+// error is called concurrently if files are parsed concurrently.
+func (p *noder) error(err error) {
+	p.err <- err.(syntax.Error)
+}
+
+// pragmas that are allowed in the std lib, but don't have
+// a syntax.Pragma value (see lex.go) associated with them.
+var allowedStdPragmas = map[string]bool{
+	"go:cgo_export_static":  true,
+	"go:cgo_export_dynamic": true,
+	"go:cgo_import_static":  true,
+	"go:cgo_import_dynamic": true,
+	"go:cgo_ldflag":         true,
+	"go:cgo_dynamic_linker": true,
+	"go:embed":              true,
+	"go:generate":           true,
+}
+
+// *pragmas is the value stored in a syntax.pragmas during parsing.
+type pragmas struct {
+	Flag   ir.PragmaFlag // collected bits
+	Pos    []pragmaPos   // position of each individual flag
+	Embeds []pragmaEmbed
+}
+
+type pragmaPos struct {
+	Flag ir.PragmaFlag
+	Pos  syntax.Pos
+}
+
+type pragmaEmbed struct {
+	Pos      syntax.Pos
+	Patterns []string
+}
+
+func (p *noder) checkUnused(pragma *pragmas) {
+	for _, pos := range pragma.Pos {
+		if pos.Flag&pragma.Flag != 0 {
+			p.errorAt(pos.Pos, "misplaced compiler directive")
+		}
+	}
+	if len(pragma.Embeds) > 0 {
+		for _, e := range pragma.Embeds {
+			p.errorAt(e.Pos, "misplaced go:embed directive")
+		}
+	}
+}
+
+func (p *noder) checkUnusedDuringParse(pragma *pragmas) {
+	for _, pos := range pragma.Pos {
+		if pos.Flag&pragma.Flag != 0 {
+			p.error(syntax.Error{Pos: pos.Pos, Msg: "misplaced compiler directive"})
+		}
+	}
+	if len(pragma.Embeds) > 0 {
+		for _, e := range pragma.Embeds {
+			p.error(syntax.Error{Pos: e.Pos, Msg: "misplaced go:embed directive"})
+		}
+	}
+}
+
+// pragma is called concurrently if files are parsed concurrently.
+func (p *noder) pragma(pos syntax.Pos, blankLine bool, text string, old syntax.Pragma) syntax.Pragma {
+	pragma, _ := old.(*pragmas)
+	if pragma == nil {
+		pragma = new(pragmas)
+	}
+
+	if text == "" {
+		// unused pragma; only called with old != nil.
+		p.checkUnusedDuringParse(pragma)
+		return nil
+	}
+
+	if strings.HasPrefix(text, "line ") {
+		// line directives are handled by syntax package
+		panic("unreachable")
+	}
+
+	if !blankLine {
+		// directive must be on line by itself
+		p.error(syntax.Error{Pos: pos, Msg: "misplaced compiler directive"})
+		return pragma
+	}
+
+	switch {
+	case strings.HasPrefix(text, "go:linkname "):
+		f := strings.Fields(text)
+		if !(2 <= len(f) && len(f) <= 3) {
+			p.error(syntax.Error{Pos: pos, Msg: "usage: //go:linkname localname [linkname]"})
+			break
+		}
+		// The second argument is optional. If omitted, we use
+		// the default object symbol name for this and
+		// linkname only serves to mark this symbol as
+		// something that may be referenced via the object
+		// symbol name from another package.
+		var target string
+		if len(f) == 3 {
+			target = f[2]
+		} else if base.Ctxt.Pkgpath != "" {
+			// Use the default object symbol name if the
+			// user didn't provide one.
+			target = objabi.PathToPrefix(base.Ctxt.Pkgpath) + "." + f[1]
+		} else {
+			p.error(syntax.Error{Pos: pos, Msg: "//go:linkname requires linkname argument or -p compiler flag"})
+			break
+		}
+		p.linknames = append(p.linknames, linkname{pos, f[1], target})
+
+	case text == "go:embed", strings.HasPrefix(text, "go:embed "):
+		args, err := parseGoEmbed(text[len("go:embed"):])
+		if err != nil {
+			p.error(syntax.Error{Pos: pos, Msg: err.Error()})
+		}
+		if len(args) == 0 {
+			p.error(syntax.Error{Pos: pos, Msg: "usage: //go:embed pattern..."})
+			break
+		}
+		pragma.Embeds = append(pragma.Embeds, pragmaEmbed{pos, args})
+
+	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.pragcgo(pos, text)
+			pragma.Flag |= pragmaFlag("go:cgo_import_dynamic")
+			break
+		}
+		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) && !base.Flag.Std {
+			p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in cgo-generated code", text)})
+		}
+		p.pragcgo(pos, text)
+		fallthrough // because of //go:cgo_unsafe_args
+	default:
+		verb := text
+		if i := strings.Index(text, " "); i >= 0 {
+			verb = verb[:i]
+		}
+		flag := pragmaFlag(verb)
+		const runtimePragmas = ir.Systemstack | ir.Nowritebarrier | ir.Nowritebarrierrec | ir.Yeswritebarrierrec
+		if !base.Flag.CompilingRuntime && flag&runtimePragmas != 0 {
+			p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in runtime", verb)})
+		}
+		if flag == 0 && !allowedStdPragmas[verb] && base.Flag.Std {
+			p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s is not allowed in the standard library", verb)})
+		}
+		pragma.Flag |= flag
+		pragma.Pos = append(pragma.Pos, pragmaPos{flag, pos})
+	}
+
+	return pragma
+}
+
+// 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 syntax.Pos) bool {
+	return strings.HasPrefix(filepath.Base(filepath.Clean(fileh(pos.Base().Filename()))), "_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) ir.Node {
+	n := oldname(sym)
+	if n.Name() != nil && n.Name().PkgName != nil {
+		n.Name().PkgName.Used = true
+	}
+	return n
+}
+
+// parseGoEmbed parses the text following "//go:embed" to extract the glob patterns.
+// It accepts unquoted space-separated patterns as well as double-quoted and back-quoted Go strings.
+// go/build/read.go also processes these strings and contains similar logic.
+func parseGoEmbed(args string) ([]string, error) {
+	var list []string
+	for args = strings.TrimSpace(args); args != ""; args = strings.TrimSpace(args) {
+		var path string
+	Switch:
+		switch args[0] {
+		default:
+			i := len(args)
+			for j, c := range args {
+				if unicode.IsSpace(c) {
+					i = j
+					break
+				}
+			}
+			path = args[:i]
+			args = args[i:]
+
+		case '`':
+			i := strings.Index(args[1:], "`")
+			if i < 0 {
+				return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
+			}
+			path = args[1 : 1+i]
+			args = args[1+i+1:]
+
+		case '"':
+			i := 1
+			for ; i < len(args); i++ {
+				if args[i] == '\\' {
+					i++
+					continue
+				}
+				if args[i] == '"' {
+					q, err := strconv.Unquote(args[:i+1])
+					if err != nil {
+						return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args[:i+1])
+					}
+					path = q
+					args = args[i+1:]
+					break Switch
+				}
+			}
+			if i >= len(args) {
+				return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
+			}
+		}
+
+		if args != "" {
+			r, _ := utf8.DecodeRuneInString(args)
+			if !unicode.IsSpace(r) {
+				return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
+			}
+		}
+		list = append(list, path)
+	}
+	return list, nil
+}
+
+func fakeRecv() *ir.Field {
+	return ir.NewField(base.Pos, nil, nil, types.FakeRecvType())
+}
+
+func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
+	xtype := p.typeExpr(expr.Type)
+
+	fn := ir.NewFunc(p.pos(expr))
+	fn.SetIsHiddenClosure(ir.CurFunc != nil)
+
+	fn.Nname = ir.NewNameAt(p.pos(expr), ir.BlankNode.Sym()) // filled in by tcClosure
+	fn.Nname.Func = fn
+	fn.Nname.Ntype = xtype
+	fn.Nname.Defn = fn
+
+	clo := ir.NewClosureExpr(p.pos(expr), fn)
+	fn.OClosure = clo
+
+	p.funcBody(fn, expr.Body)
+
+	ir.FinishCaptureNames(base.Pos, ir.CurFunc, fn)
+
+	return clo
+}
+
+// A function named init is a special case.
+// It is called by the initialization before main is run.
+// To make it unique within a package and also uncallable,
+// the name, normally "pkg.init", is altered to "pkg.init.0".
+var renameinitgen int
+
+func renameinit() *types.Sym {
+	s := typecheck.LookupNum("init.", renameinitgen)
+	renameinitgen++
+	return s
+}
+
+// oldname returns the Node that declares symbol s in the current scope.
+// If no such Node currently exists, an ONONAME Node is returned instead.
+// Automatically creates a new closure variable if the referenced symbol was
+// declared in a different (containing) function.
+func oldname(s *types.Sym) ir.Node {
+	if s.Pkg != types.LocalPkg {
+		return ir.NewIdent(base.Pos, s)
+	}
+
+	n := ir.AsNode(s.Def)
+	if n == nil {
+		// Maybe a top-level declaration will come along later to
+		// define s. resolve will check s.Def again once all input
+		// source has been processed.
+		return ir.NewIdent(base.Pos, s)
+	}
+
+	if n, ok := n.(*ir.Name); ok {
+		// TODO(rsc): If there is an outer variable x and we
+		// are parsing x := 5 inside the closure, until we get to
+		// the := it looks like a reference to the outer x so we'll
+		// make x a closure variable unnecessarily.
+		return ir.CaptureName(base.Pos, ir.CurFunc, n)
+	}
+
+	return n
+}
+
+func varEmbed(makeXPos func(syntax.Pos) src.XPos, name *ir.Name, decl *syntax.VarDecl, pragma *pragmas, haveEmbed bool) {
+	if pragma.Embeds == nil {
+		return
+	}
+
+	pragmaEmbeds := pragma.Embeds
+	pragma.Embeds = nil
+	pos := makeXPos(pragmaEmbeds[0].Pos)
+
+	if !haveEmbed {
+		base.ErrorfAt(pos, "go:embed only allowed in Go files that import \"embed\"")
+		return
+	}
+	if len(decl.NameList) > 1 {
+		base.ErrorfAt(pos, "go:embed cannot apply to multiple vars")
+		return
+	}
+	if decl.Values != nil {
+		base.ErrorfAt(pos, "go:embed cannot apply to var with initializer")
+		return
+	}
+	if decl.Type == nil {
+		// Should not happen, since Values == nil now.
+		base.ErrorfAt(pos, "go:embed cannot apply to var without type")
+		return
+	}
+	if typecheck.DeclContext != ir.PEXTERN {
+		base.ErrorfAt(pos, "go:embed cannot apply to var inside func")
+		return
+	}
+
+	var embeds []ir.Embed
+	for _, e := range pragmaEmbeds {
+		embeds = append(embeds, ir.Embed{Pos: makeXPos(e.Pos), Patterns: e.Patterns})
+	}
+	typecheck.Target.Embeds = append(typecheck.Target.Embeds, name)
+	name.Embed = &embeds
+}
diff --git a/src/cmd/compile/internal/noder/object.go b/src/cmd/compile/internal/noder/object.go
new file mode 100644
index 0000000..82cce1a
--- /dev/null
+++ b/src/cmd/compile/internal/noder/object.go
@@ -0,0 +1,184 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/compile/internal/types2"
+	"cmd/internal/src"
+)
+
+func (g *irgen) def(name *syntax.Name) (*ir.Name, types2.Object) {
+	obj, ok := g.info.Defs[name]
+	if !ok {
+		base.FatalfAt(g.pos(name), "unknown name %v", name)
+	}
+	return g.obj(obj), obj
+}
+
+// use returns the Name node associated with the use of name. The returned node
+// will have the correct type and be marked as typechecked.
+func (g *irgen) use(name *syntax.Name) *ir.Name {
+	obj2, ok := g.info.Uses[name]
+	if !ok {
+		base.FatalfAt(g.pos(name), "unknown name %v", name)
+	}
+	obj := ir.CaptureName(g.pos(obj2), ir.CurFunc, g.obj(obj2))
+	if obj.Defn != nil && obj.Defn.Op() == ir.ONAME {
+		// If CaptureName created a closure variable, then transfer the
+		// type of the captured name to the new closure variable.
+		obj.SetTypecheck(1)
+		obj.SetType(obj.Defn.Type())
+	}
+	return obj
+}
+
+// obj returns the Name that represents the given object. If no such Name exists
+// yet, it will be implicitly created. The returned node will have the correct
+// type and be marked as typechecked.
+//
+// For objects declared at function scope, ir.CurFunc must already be
+// set to the respective function when the Name is created.
+func (g *irgen) obj(obj types2.Object) *ir.Name {
+	// For imported objects, we use iimport directly instead of mapping
+	// the types2 representation.
+	if obj.Pkg() != g.self {
+		sym := g.sym(obj)
+		if sym.Def != nil {
+			return sym.Def.(*ir.Name)
+		}
+		n := typecheck.Resolve(ir.NewIdent(src.NoXPos, sym))
+		if n, ok := n.(*ir.Name); ok {
+			n.SetTypecheck(1)
+			return n
+		}
+		base.FatalfAt(g.pos(obj), "failed to resolve %v", obj)
+	}
+
+	if name, ok := g.objs[obj]; ok {
+		return name // previously mapped
+	}
+
+	var name *ir.Name
+	pos := g.pos(obj)
+
+	class := typecheck.DeclContext
+	if obj.Parent() == g.self.Scope() {
+		class = ir.PEXTERN // forward reference to package-block declaration
+	}
+
+	// "You are in a maze of twisting little passages, all different."
+	switch obj := obj.(type) {
+	case *types2.Const:
+		name = g.objCommon(pos, ir.OLITERAL, g.sym(obj), class, g.typ(obj.Type()))
+
+	case *types2.Func:
+		sig := obj.Type().(*types2.Signature)
+		var sym *types.Sym
+		var typ *types.Type
+		if recv := sig.Recv(); recv == nil {
+			if obj.Name() == "init" {
+				sym = renameinit()
+			} else {
+				sym = g.sym(obj)
+			}
+			typ = g.typ(sig)
+		} else {
+			sym = g.selector(obj)
+			if !sym.IsBlank() {
+				sym = ir.MethodSym(g.typ(recv.Type()), sym)
+			}
+			typ = g.signature(g.param(recv), sig)
+		}
+		name = g.objCommon(pos, ir.ONAME, sym, ir.PFUNC, typ)
+
+	case *types2.TypeName:
+		if obj.IsAlias() {
+			name = g.objCommon(pos, ir.OTYPE, g.sym(obj), class, g.typ(obj.Type()))
+		} else {
+			name = ir.NewDeclNameAt(pos, ir.OTYPE, g.sym(obj))
+			g.objFinish(name, class, types.NewNamed(name))
+		}
+
+	case *types2.Var:
+		var sym *types.Sym
+		if class == ir.PPARAMOUT {
+			// Backend needs names for result parameters,
+			// even if they're anonymous or blank.
+			switch obj.Name() {
+			case "":
+				sym = typecheck.LookupNum("~r", len(ir.CurFunc.Dcl)) // 'r' for "result"
+			case "_":
+				sym = typecheck.LookupNum("~b", len(ir.CurFunc.Dcl)) // 'b' for "blank"
+			}
+		}
+		if sym == nil {
+			sym = g.sym(obj)
+		}
+		name = g.objCommon(pos, ir.ONAME, sym, class, g.typ(obj.Type()))
+
+	default:
+		g.unhandled("object", obj)
+	}
+
+	g.objs[obj] = name
+	name.SetTypecheck(1)
+	return name
+}
+
+func (g *irgen) objCommon(pos src.XPos, op ir.Op, sym *types.Sym, class ir.Class, typ *types.Type) *ir.Name {
+	name := ir.NewDeclNameAt(pos, op, sym)
+	g.objFinish(name, class, typ)
+	return name
+}
+
+func (g *irgen) objFinish(name *ir.Name, class ir.Class, typ *types.Type) {
+	sym := name.Sym()
+
+	name.SetType(typ)
+	name.Class = class
+	if name.Class == ir.PFUNC {
+		sym.SetFunc(true)
+	}
+
+	name.SetTypecheck(1)
+	name.SetWalkdef(1)
+
+	if ir.IsBlank(name) {
+		return
+	}
+
+	switch class {
+	case ir.PEXTERN:
+		g.target.Externs = append(g.target.Externs, name)
+		fallthrough
+	case ir.PFUNC:
+		sym.Def = name
+		if name.Class == ir.PFUNC && name.Type().Recv() != nil {
+			break // methods are exported with their receiver type
+		}
+		if types.IsExported(sym.Name) {
+			if name.Class == ir.PFUNC && name.Type().NumTParams() > 0 {
+				base.FatalfAt(name.Pos(), "Cannot export a generic function (yet): %v", name)
+			}
+			typecheck.Export(name)
+		}
+		if base.Flag.AsmHdr != "" && !name.Sym().Asm() {
+			name.Sym().SetAsm(true)
+			g.target.Asms = append(g.target.Asms, name)
+		}
+
+	default:
+		// Function-scoped declaration.
+		name.Curfn = ir.CurFunc
+		if name.Op() == ir.ONAME {
+			ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, name)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/noder/posmap.go b/src/cmd/compile/internal/noder/posmap.go
new file mode 100644
index 0000000..a6d3e2d
--- /dev/null
+++ b/src/cmd/compile/internal/noder/posmap.go
@@ -0,0 +1,83 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/syntax"
+	"cmd/internal/src"
+)
+
+// A posMap handles mapping from syntax.Pos to src.XPos.
+type posMap struct {
+	bases map[*syntax.PosBase]*src.PosBase
+	cache struct {
+		last *syntax.PosBase
+		base *src.PosBase
+	}
+}
+
+type poser interface{ Pos() syntax.Pos }
+type ender interface{ End() syntax.Pos }
+
+func (m *posMap) pos(p poser) src.XPos { return m.makeXPos(p.Pos()) }
+func (m *posMap) end(p ender) src.XPos { return m.makeXPos(p.End()) }
+
+func (m *posMap) makeXPos(pos syntax.Pos) src.XPos {
+	if !pos.IsKnown() {
+		// TODO(mdempsky): Investigate restoring base.Fatalf.
+		return src.NoXPos
+	}
+
+	posBase := m.makeSrcPosBase(pos.Base())
+	return base.Ctxt.PosTable.XPos(src.MakePos(posBase, pos.Line(), pos.Col()))
+}
+
+// makeSrcPosBase translates from a *syntax.PosBase to a *src.PosBase.
+func (m *posMap) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase {
+	// fast path: most likely PosBase hasn't changed
+	if m.cache.last == b0 {
+		return m.cache.base
+	}
+
+	b1, ok := m.bases[b0]
+	if !ok {
+		fn := b0.Filename()
+		if b0.IsFileBase() {
+			b1 = src.NewFileBase(fn, absFilename(fn))
+		} else {
+			// line directive base
+			p0 := b0.Pos()
+			p0b := p0.Base()
+			if p0b == b0 {
+				panic("infinite recursion in makeSrcPosBase")
+			}
+			p1 := src.MakePos(m.makeSrcPosBase(p0b), p0.Line(), p0.Col())
+			b1 = src.NewLinePragmaBase(p1, fn, fileh(fn), b0.Line(), b0.Col())
+		}
+		if m.bases == nil {
+			m.bases = make(map[*syntax.PosBase]*src.PosBase)
+		}
+		m.bases[b0] = b1
+	}
+
+	// update cache
+	m.cache.last = b0
+	m.cache.base = b1
+
+	return b1
+}
+
+func (m *posMap) join(other *posMap) {
+	if m.bases == nil {
+		m.bases = make(map[*syntax.PosBase]*src.PosBase)
+	}
+	for k, v := range other.bases {
+		if m.bases[k] != nil {
+			base.Fatalf("duplicate posmap bases")
+		}
+		m.bases[k] = v
+	}
+}
diff --git a/src/cmd/compile/internal/noder/scopes.go b/src/cmd/compile/internal/noder/scopes.go
new file mode 100644
index 0000000..eb51847
--- /dev/null
+++ b/src/cmd/compile/internal/noder/scopes.go
@@ -0,0 +1,64 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/types2"
+)
+
+// recordScopes populates fn.Parents and fn.Marks based on the scoping
+// information provided by types2.
+func (g *irgen) recordScopes(fn *ir.Func, sig *syntax.FuncType) {
+	scope, ok := g.info.Scopes[sig]
+	if !ok {
+		base.FatalfAt(fn.Pos(), "missing scope for %v", fn)
+	}
+
+	for i, n := 0, scope.NumChildren(); i < n; i++ {
+		g.walkScope(scope.Child(i))
+	}
+
+	g.marker.WriteTo(fn)
+}
+
+func (g *irgen) walkScope(scope *types2.Scope) bool {
+	// types2 doesn't provide a proper API for determining the
+	// lexical element a scope represents, so we have to resort to
+	// string matching. Conveniently though, this allows us to
+	// skip both function types and function literals, neither of
+	// which are interesting to us here.
+	if strings.HasPrefix(scope.String(), "function scope ") {
+		return false
+	}
+
+	g.marker.Push(g.pos(scope))
+
+	haveVars := false
+	for _, name := range scope.Names() {
+		if obj, ok := scope.Lookup(name).(*types2.Var); ok && obj.Name() != "_" {
+			haveVars = true
+			break
+		}
+	}
+
+	for i, n := 0, scope.NumChildren(); i < n; i++ {
+		if g.walkScope(scope.Child(i)) {
+			haveVars = true
+		}
+	}
+
+	if haveVars {
+		g.marker.Pop(g.end(scope))
+	} else {
+		g.marker.Unpush()
+	}
+
+	return haveVars
+}
diff --git a/src/cmd/compile/internal/noder/sizes.go b/src/cmd/compile/internal/noder/sizes.go
new file mode 100644
index 0000000..23f2062
--- /dev/null
+++ b/src/cmd/compile/internal/noder/sizes.go
@@ -0,0 +1,150 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"fmt"
+
+	"cmd/compile/internal/types"
+	"cmd/compile/internal/types2"
+)
+
+// Code below based on go/types.StdSizes.
+// Intentional differences are marked with "gc:".
+
+type gcSizes struct{}
+
+func (s *gcSizes) Alignof(T types2.Type) int64 {
+	// For arrays and structs, alignment is defined in terms
+	// of alignment of the elements and fields, respectively.
+	switch t := T.Underlying().(type) {
+	case *types2.Array:
+		// spec: "For a variable x of array type: unsafe.Alignof(x)
+		// is the same as unsafe.Alignof(x[0]), but at least 1."
+		return s.Alignof(t.Elem())
+	case *types2.Struct:
+		// spec: "For a variable x of struct type: unsafe.Alignof(x)
+		// is the largest of the values unsafe.Alignof(x.f) for each
+		// field f of x, but at least 1."
+		max := int64(1)
+		for i, nf := 0, t.NumFields(); i < nf; i++ {
+			if a := s.Alignof(t.Field(i).Type()); a > max {
+				max = a
+			}
+		}
+		return max
+	case *types2.Slice, *types2.Interface:
+		// Multiword data structures are effectively structs
+		// in which each element has size PtrSize.
+		return int64(types.PtrSize)
+	case *types2.Basic:
+		// Strings are like slices and interfaces.
+		if t.Info()&types2.IsString != 0 {
+			return int64(types.PtrSize)
+		}
+	}
+	a := s.Sizeof(T) // may be 0
+	// spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
+	if a < 1 {
+		return 1
+	}
+	// complex{64,128} are aligned like [2]float{32,64}.
+	if isComplex(T) {
+		a /= 2
+	}
+	if a > int64(types.RegSize) {
+		return int64(types.RegSize)
+	}
+	return a
+}
+
+func isComplex(T types2.Type) bool {
+	basic, ok := T.Underlying().(*types2.Basic)
+	return ok && basic.Info()&types2.IsComplex != 0
+}
+
+func (s *gcSizes) Offsetsof(fields []*types2.Var) []int64 {
+	offsets := make([]int64, len(fields))
+	var o int64
+	for i, f := range fields {
+		typ := f.Type()
+		a := s.Alignof(typ)
+		o = types.Rnd(o, a)
+		offsets[i] = o
+		o += s.Sizeof(typ)
+	}
+	return offsets
+}
+
+func (s *gcSizes) Sizeof(T types2.Type) int64 {
+	switch t := T.Underlying().(type) {
+	case *types2.Basic:
+		k := t.Kind()
+		if int(k) < len(basicSizes) {
+			if s := basicSizes[k]; s > 0 {
+				return int64(s)
+			}
+		}
+		switch k {
+		case types2.String:
+			return int64(types.PtrSize) * 2
+		case types2.Int, types2.Uint, types2.Uintptr, types2.UnsafePointer:
+			return int64(types.PtrSize)
+		}
+		panic(fmt.Sprintf("unimplemented basic: %v (kind %v)", T, k))
+	case *types2.Array:
+		n := t.Len()
+		if n <= 0 {
+			return 0
+		}
+		// n > 0
+		// gc: Size includes alignment padding.
+		return s.Sizeof(t.Elem()) * n
+	case *types2.Slice:
+		return int64(types.PtrSize) * 3
+	case *types2.Struct:
+		n := t.NumFields()
+		if n == 0 {
+			return 0
+		}
+		fields := make([]*types2.Var, n)
+		for i := range fields {
+			fields[i] = t.Field(i)
+		}
+		offsets := s.Offsetsof(fields)
+
+		// gc: The last field of a non-zero-sized struct is not allowed to
+		// have size 0.
+		last := s.Sizeof(fields[n-1].Type())
+		if last == 0 && offsets[n-1] > 0 {
+			last = 1
+		}
+
+		// gc: Size includes alignment padding.
+		return types.Rnd(offsets[n-1]+last, s.Alignof(t))
+	case *types2.Interface:
+		return int64(types.PtrSize) * 2
+	case *types2.Chan, *types2.Map, *types2.Pointer, *types2.Signature:
+		return int64(types.PtrSize)
+	default:
+		panic(fmt.Sprintf("unimplemented type: %T", t))
+	}
+}
+
+var basicSizes = [...]byte{
+	types2.Bool:       1,
+	types2.Int8:       1,
+	types2.Int16:      2,
+	types2.Int32:      4,
+	types2.Int64:      8,
+	types2.Uint8:      1,
+	types2.Uint16:     2,
+	types2.Uint32:     4,
+	types2.Uint64:     8,
+	types2.Float32:    4,
+	types2.Float64:    8,
+	types2.Complex64:  8,
+	types2.Complex128: 16,
+}
diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go
new file mode 100644
index 0000000..3ebc8df
--- /dev/null
+++ b/src/cmd/compile/internal/noder/stencil.go
@@ -0,0 +1,917 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file will evolve, since we plan to do a mix of stenciling and passing
+// around dictionaries.
+
+package noder
+
+import (
+	"bytes"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+	"fmt"
+	"strings"
+)
+
+// For catching problems as we add more features
+// TODO(danscales): remove assertions or replace with base.FatalfAt()
+func assert(p bool) {
+	if !p {
+		panic("assertion failed")
+	}
+}
+
+// stencil scans functions for instantiated generic function calls and creates the
+// required instantiations for simple generic functions. It also creates
+// instantiated methods for all fully-instantiated generic types that have been
+// encountered already or new ones that are encountered during the stenciling
+// process.
+func (g *irgen) stencil() {
+	g.target.Stencils = make(map[*types.Sym]*ir.Func)
+
+	// Instantiate the methods of instantiated generic types that we have seen so far.
+	g.instantiateMethods()
+
+	// Don't use range(g.target.Decls) - we also want to process any new instantiated
+	// functions that are created during this loop, in order to handle generic
+	// functions calling other generic functions.
+	for i := 0; i < len(g.target.Decls); i++ {
+		decl := g.target.Decls[i]
+
+		// Look for function instantiations in bodies of non-generic
+		// functions or in global assignments (ignore global type and
+		// constant declarations).
+		switch decl.Op() {
+		case ir.ODCLFUNC:
+			if decl.Type().HasTParam() {
+				// Skip any generic functions
+				continue
+			}
+			// transformCall() below depends on CurFunc being set.
+			ir.CurFunc = decl.(*ir.Func)
+
+		case ir.OAS, ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV, ir.OASOP:
+			// These are all the various kinds of global assignments,
+			// whose right-hand-sides might contain a function
+			// instantiation.
+
+		default:
+			// The other possible ops at the top level are ODCLCONST
+			// and ODCLTYPE, which don't have any function
+			// instantiations.
+			continue
+		}
+
+		// For all non-generic code, search for any function calls using
+		// generic function instantiations. Then create the needed
+		// instantiated function if it hasn't been created yet, and change
+		// to calling that function directly.
+		modified := false
+		foundFuncInst := false
+		ir.Visit(decl, func(n ir.Node) {
+			if n.Op() == ir.OFUNCINST {
+				// We found a function instantiation that is not
+				// immediately called.
+				foundFuncInst = true
+			}
+			if n.Op() != ir.OCALL || n.(*ir.CallExpr).X.Op() != ir.OFUNCINST {
+				return
+			}
+			// We have found a function call using a generic function
+			// instantiation.
+			call := n.(*ir.CallExpr)
+			inst := call.X.(*ir.InstExpr)
+			st := g.getInstantiationForNode(inst)
+			// Replace the OFUNCINST with a direct reference to the
+			// new stenciled function
+			call.X = st.Nname
+			if inst.X.Op() == ir.OCALLPART {
+				// When we create an instantiation of a method
+				// call, we make it a function. So, move the
+				// receiver to be the first arg of the function
+				// call.
+				withRecv := make([]ir.Node, len(call.Args)+1)
+				dot := inst.X.(*ir.SelectorExpr)
+				withRecv[0] = dot.X
+				copy(withRecv[1:], call.Args)
+				call.Args = withRecv
+			}
+			// Transform the Call now, which changes OCALL
+			// to OCALLFUNC and does typecheckaste/assignconvfn.
+			transformCall(call)
+			modified = true
+		})
+
+		// If we found an OFUNCINST without a corresponding call in the
+		// above decl, then traverse the nodes of decl again (with
+		// EditChildren rather than Visit), where we actually change the
+		// OFUNCINST node to an ONAME for the instantiated function.
+		// EditChildren is more expensive than Visit, so we only do this
+		// in the infrequent case of an OFUNCINSt without a corresponding
+		// call.
+		if foundFuncInst {
+			var edit func(ir.Node) ir.Node
+			edit = func(x ir.Node) ir.Node {
+				if x.Op() == ir.OFUNCINST {
+					st := g.getInstantiationForNode(x.(*ir.InstExpr))
+					return st.Nname
+				}
+				ir.EditChildren(x, edit)
+				return x
+			}
+			edit(decl)
+		}
+		if base.Flag.W > 1 && modified {
+			ir.Dump(fmt.Sprintf("\nmodified %v", decl), decl)
+		}
+		ir.CurFunc = nil
+		// We may have seen new fully-instantiated generic types while
+		// instantiating any needed functions/methods in the above
+		// function. If so, instantiate all the methods of those types
+		// (which will then lead to more function/methods to scan in the loop).
+		g.instantiateMethods()
+	}
+
+}
+
+// instantiateMethods instantiates all the methods of all fully-instantiated
+// generic types that have been added to g.instTypeList.
+func (g *irgen) instantiateMethods() {
+	for i := 0; i < len(g.instTypeList); i++ {
+		typ := g.instTypeList[i]
+		// Get the base generic type by looking up the symbol of the
+		// generic (uninstantiated) name.
+		baseSym := typ.Sym().Pkg.Lookup(genericTypeName(typ.Sym()))
+		baseType := baseSym.Def.(*ir.Name).Type()
+		for j, m := range typ.Methods().Slice() {
+			name := m.Nname.(*ir.Name)
+			targs := make([]ir.Node, len(typ.RParams()))
+			for k, targ := range typ.RParams() {
+				targs[k] = ir.TypeNode(targ)
+			}
+			baseNname := baseType.Methods().Slice()[j].Nname.(*ir.Name)
+			name.Func = g.getInstantiation(baseNname, targs, true)
+		}
+	}
+	g.instTypeList = nil
+
+}
+
+// genericSym returns the name of the base generic type for the type named by
+// sym. It simply returns the name obtained by removing everything after the
+// first bracket ("[").
+func genericTypeName(sym *types.Sym) string {
+	return sym.Name[0:strings.Index(sym.Name, "[")]
+}
+
+// getInstantiationForNode returns the function/method instantiation for a
+// InstExpr node inst.
+func (g *irgen) getInstantiationForNode(inst *ir.InstExpr) *ir.Func {
+	if meth, ok := inst.X.(*ir.SelectorExpr); ok {
+		return g.getInstantiation(meth.Selection.Nname.(*ir.Name), inst.Targs, true)
+	} else {
+		return g.getInstantiation(inst.X.(*ir.Name), inst.Targs, false)
+	}
+}
+
+// getInstantiation gets the instantiantion of the function or method nameNode
+// with the type arguments targs. If the instantiated function is not already
+// cached, then it calls genericSubst to create the new instantiation.
+func (g *irgen) getInstantiation(nameNode *ir.Name, targs []ir.Node, isMeth bool) *ir.Func {
+	sym := makeInstName(nameNode.Sym(), targs, isMeth)
+	st := g.target.Stencils[sym]
+	if st == nil {
+		// If instantiation doesn't exist yet, create it and add
+		// to the list of decls.
+		st = g.genericSubst(sym, nameNode, targs, isMeth)
+		g.target.Stencils[sym] = st
+		g.target.Decls = append(g.target.Decls, st)
+		if base.Flag.W > 1 {
+			ir.Dump(fmt.Sprintf("\nstenciled %v", st), st)
+		}
+	}
+	return st
+}
+
+// makeInstName makes the unique name for a stenciled generic function or method,
+// based on the name of the function fy=nsym and the targs. It replaces any
+// existing bracket type list in the name. makeInstName asserts that fnsym has
+// brackets in its name if and only if hasBrackets is true.
+// TODO(danscales): remove the assertions and the hasBrackets argument later.
+//
+// Names of declared generic functions have no brackets originally, so hasBrackets
+// should be false. Names of generic methods already have brackets, since the new
+// type parameter is specified in the generic type of the receiver (e.g. func
+// (func (v *value[T]).set(...) { ... } has the original name (*value[T]).set.
+//
+// The standard naming is something like: 'genFn[int,bool]' for functions and
+// '(*genType[int,bool]).methodName' for methods
+func makeInstName(fnsym *types.Sym, targs []ir.Node, hasBrackets bool) *types.Sym {
+	b := bytes.NewBufferString("")
+	name := fnsym.Name
+	i := strings.Index(name, "[")
+	assert(hasBrackets == (i >= 0))
+	if i >= 0 {
+		b.WriteString(name[0:i])
+	} else {
+		b.WriteString(name)
+	}
+	b.WriteString("[")
+	for i, targ := range targs {
+		if i > 0 {
+			b.WriteString(",")
+		}
+		b.WriteString(targ.Type().String())
+	}
+	b.WriteString("]")
+	if i >= 0 {
+		i2 := strings.Index(name[i:], "]")
+		assert(i2 >= 0)
+		b.WriteString(name[i+i2+1:])
+	}
+	return typecheck.Lookup(b.String())
+}
+
+// Struct containing info needed for doing the substitution as we create the
+// instantiation of a generic function with specified type arguments.
+type subster struct {
+	g        *irgen
+	isMethod bool     // If a method is being instantiated
+	newf     *ir.Func // Func node for the new stenciled function
+	tparams  []*types.Field
+	targs    []ir.Node
+	// The substitution map from name nodes in the generic function to the
+	// name nodes in the new stenciled function.
+	vars map[*ir.Name]*ir.Name
+}
+
+// genericSubst returns a new function with name newsym. The function is an
+// instantiation of a generic function or method specified by namedNode with type
+// args targs. For a method with a generic receiver, it returns an instantiated
+// function type where the receiver becomes the first parameter. Otherwise the
+// instantiated method would still need to be transformed by later compiler
+// phases.
+func (g *irgen) genericSubst(newsym *types.Sym, nameNode *ir.Name, targs []ir.Node, isMethod bool) *ir.Func {
+	var tparams []*types.Field
+	if isMethod {
+		// Get the type params from the method receiver (after skipping
+		// over any pointer)
+		recvType := nameNode.Type().Recv().Type
+		recvType = deref(recvType)
+		tparams = make([]*types.Field, len(recvType.RParams()))
+		for i, rparam := range recvType.RParams() {
+			tparams[i] = types.NewField(src.NoXPos, nil, rparam)
+		}
+	} else {
+		tparams = nameNode.Type().TParams().Fields().Slice()
+	}
+	gf := nameNode.Func
+	// Pos of the instantiated function is same as the generic function
+	newf := ir.NewFunc(gf.Pos())
+	newf.Pragma = gf.Pragma // copy over pragmas from generic function to stenciled implementation.
+	newf.Nname = ir.NewNameAt(gf.Pos(), newsym)
+	newf.Nname.Func = newf
+	newf.Nname.Defn = newf
+	newsym.Def = newf.Nname
+	savef := ir.CurFunc
+	// transformCall/transformReturn (called during stenciling of the body)
+	// depend on ir.CurFunc being set.
+	ir.CurFunc = newf
+
+	assert(len(tparams) == len(targs))
+
+	subst := &subster{
+		g:        g,
+		isMethod: isMethod,
+		newf:     newf,
+		tparams:  tparams,
+		targs:    targs,
+		vars:     make(map[*ir.Name]*ir.Name),
+	}
+
+	newf.Dcl = make([]*ir.Name, len(gf.Dcl))
+	for i, n := range gf.Dcl {
+		newf.Dcl[i] = subst.node(n).(*ir.Name)
+	}
+
+	// Ugly: we have to insert the Name nodes of the parameters/results into
+	// the function type. The current function type has no Nname fields set,
+	// because it came via conversion from the types2 type.
+	oldt := nameNode.Type()
+	// We also transform a generic method type to the corresponding
+	// instantiated function type where the receiver is the first parameter.
+	newt := types.NewSignature(oldt.Pkg(), nil, nil,
+		subst.fields(ir.PPARAM, append(oldt.Recvs().FieldSlice(), oldt.Params().FieldSlice()...), newf.Dcl),
+		subst.fields(ir.PPARAMOUT, oldt.Results().FieldSlice(), newf.Dcl))
+
+	newf.Nname.SetType(newt)
+	ir.MarkFunc(newf.Nname)
+	newf.SetTypecheck(1)
+	newf.Nname.SetTypecheck(1)
+
+	// Make sure name/type of newf is set before substituting the body.
+	newf.Body = subst.list(gf.Body)
+	ir.CurFunc = savef
+
+	return newf
+}
+
+// node is like DeepCopy(), but creates distinct ONAME nodes, and also descends
+// into closures. It substitutes type arguments for type parameters in all the new
+// nodes.
+func (subst *subster) node(n ir.Node) ir.Node {
+	// Use closure to capture all state needed by the ir.EditChildren argument.
+	var edit func(ir.Node) ir.Node
+	edit = func(x ir.Node) ir.Node {
+		switch x.Op() {
+		case ir.OTYPE:
+			return ir.TypeNode(subst.typ(x.Type()))
+
+		case ir.ONAME:
+			name := x.(*ir.Name)
+			if v := subst.vars[name]; v != nil {
+				return v
+			}
+			m := ir.NewNameAt(name.Pos(), name.Sym())
+			if name.IsClosureVar() {
+				m.SetIsClosureVar(true)
+			}
+			t := x.Type()
+			if t == nil {
+				assert(name.BuiltinOp != 0)
+			} else {
+				newt := subst.typ(t)
+				m.SetType(newt)
+			}
+			m.BuiltinOp = name.BuiltinOp
+			m.Curfn = subst.newf
+			m.Class = name.Class
+			m.Func = name.Func
+			subst.vars[name] = m
+			m.SetTypecheck(1)
+			return m
+		case ir.OLITERAL, ir.ONIL:
+			if x.Sym() != nil {
+				return x
+			}
+		}
+		m := ir.Copy(x)
+		if _, isExpr := m.(ir.Expr); isExpr {
+			t := x.Type()
+			if t == nil {
+				// t can be nil only if this is a call that has no
+				// return values, so allow that and otherwise give
+				// an error.
+				_, isCallExpr := m.(*ir.CallExpr)
+				_, isStructKeyExpr := m.(*ir.StructKeyExpr)
+				if !isCallExpr && !isStructKeyExpr && x.Op() != ir.OPANIC &&
+					x.Op() != ir.OCLOSE {
+					base.Fatalf(fmt.Sprintf("Nil type for %v", x))
+				}
+			} else if x.Op() != ir.OCLOSURE {
+				m.SetType(subst.typ(x.Type()))
+			}
+		}
+		ir.EditChildren(m, edit)
+
+		if x.Typecheck() == 3 {
+			// These are nodes whose transforms were delayed until
+			// their instantiated type was known.
+			m.SetTypecheck(1)
+			if typecheck.IsCmp(x.Op()) {
+				transformCompare(m.(*ir.BinaryExpr))
+			} else {
+				switch x.Op() {
+				case ir.OSLICE, ir.OSLICE3:
+					transformSlice(m.(*ir.SliceExpr))
+
+				case ir.OADD:
+					m = transformAdd(m.(*ir.BinaryExpr))
+
+				case ir.OINDEX:
+					transformIndex(m.(*ir.IndexExpr))
+
+				case ir.OAS2:
+					as2 := m.(*ir.AssignListStmt)
+					transformAssign(as2, as2.Lhs, as2.Rhs)
+
+				case ir.OAS:
+					as := m.(*ir.AssignStmt)
+					lhs, rhs := []ir.Node{as.X}, []ir.Node{as.Y}
+					transformAssign(as, lhs, rhs)
+
+				case ir.OASOP:
+					as := m.(*ir.AssignOpStmt)
+					transformCheckAssign(as, as.X)
+
+				case ir.ORETURN:
+					transformReturn(m.(*ir.ReturnStmt))
+
+				case ir.OSEND:
+					transformSend(m.(*ir.SendStmt))
+
+				default:
+					base.Fatalf("Unexpected node with Typecheck() == 3")
+				}
+			}
+		}
+
+		switch x.Op() {
+		case ir.OLITERAL:
+			t := m.Type()
+			if t != x.Type() {
+				// types2 will give us a constant with a type T,
+				// if an untyped constant is used with another
+				// operand of type T (in a provably correct way).
+				// When we substitute in the type args during
+				// stenciling, we now know the real type of the
+				// constant. We may then need to change the
+				// BasicLit.val to be the correct type (e.g.
+				// convert an int64Val constant to a floatVal
+				// constant).
+				m.SetType(types.UntypedInt) // use any untyped type for DefaultLit to work
+				m = typecheck.DefaultLit(m, t)
+			}
+
+		case ir.OXDOT:
+			// A method value/call via a type param will have been
+			// left as an OXDOT. When we see this during stenciling,
+			// finish the transformation, now that we have the
+			// instantiated receiver type. We need to do this now,
+			// since the access/selection to the method for the real
+			// type is very different from the selection for the type
+			// param. m will be transformed to an OCALLPART node. It
+			// will be transformed to an ODOTMETH or ODOTINTER node if
+			// we find in the OCALL case below that the method value
+			// is actually called.
+			transformDot(m.(*ir.SelectorExpr), false)
+			m.SetTypecheck(1)
+
+		case ir.OCALL:
+			call := m.(*ir.CallExpr)
+			switch call.X.Op() {
+			case ir.OTYPE:
+				// Transform the conversion, now that we know the
+				// type argument.
+				m = transformConvCall(m.(*ir.CallExpr))
+
+			case ir.OCALLPART:
+				// Redo the transformation of OXDOT, now that we
+				// know the method value is being called. Then
+				// transform the call.
+				call.X.(*ir.SelectorExpr).SetOp(ir.OXDOT)
+				transformDot(call.X.(*ir.SelectorExpr), true)
+				transformCall(call)
+
+			case ir.ODOT, ir.ODOTPTR:
+				// An OXDOT for a generic receiver was resolved to
+				// an access to a field which has a function
+				// value. Transform the call to that function, now
+				// that the OXDOT was resolved.
+				transformCall(call)
+
+			case ir.ONAME:
+				name := call.X.Name()
+				if name.BuiltinOp != ir.OXXX {
+					switch name.BuiltinOp {
+					case ir.OMAKE, ir.OREAL, ir.OIMAG, ir.OLEN, ir.OCAP, ir.OAPPEND:
+						// Transform these builtins now that we
+						// know the type of the args.
+						m = transformBuiltin(call)
+					default:
+						base.FatalfAt(call.Pos(), "Unexpected builtin op")
+					}
+				} else {
+					// This is the case of a function value that was a
+					// type parameter (implied to be a function via a
+					// structural constraint) which is now resolved.
+					transformCall(call)
+				}
+
+			case ir.OCLOSURE:
+				transformCall(call)
+
+			case ir.OFUNCINST:
+				// A call with an OFUNCINST will get transformed
+				// in stencil() once we have created & attached the
+				// instantiation to be called.
+
+			default:
+				base.FatalfAt(call.Pos(), fmt.Sprintf("Unexpected op with CALL during stenciling: %v", call.X.Op()))
+			}
+
+		case ir.OCLOSURE:
+			x := x.(*ir.ClosureExpr)
+			// Need to duplicate x.Func.Nname, x.Func.Dcl, x.Func.ClosureVars, and
+			// x.Func.Body.
+			oldfn := x.Func
+			newfn := ir.NewFunc(oldfn.Pos())
+			if oldfn.ClosureCalled() {
+				newfn.SetClosureCalled(true)
+			}
+			newfn.SetIsHiddenClosure(true)
+			m.(*ir.ClosureExpr).Func = newfn
+			// Closure name can already have brackets, if it derives
+			// from a generic method
+			newsym := makeInstName(oldfn.Nname.Sym(), subst.targs, subst.isMethod)
+			newfn.Nname = ir.NewNameAt(oldfn.Nname.Pos(), newsym)
+			newfn.Nname.Func = newfn
+			newfn.Nname.Defn = newfn
+			ir.MarkFunc(newfn.Nname)
+			newfn.OClosure = m.(*ir.ClosureExpr)
+
+			saveNewf := subst.newf
+			ir.CurFunc = newfn
+			subst.newf = newfn
+			newfn.Dcl = subst.namelist(oldfn.Dcl)
+			newfn.ClosureVars = subst.namelist(oldfn.ClosureVars)
+
+			typed(subst.typ(oldfn.Nname.Type()), newfn.Nname)
+			typed(newfn.Nname.Type(), m)
+			newfn.SetTypecheck(1)
+
+			// Make sure type of closure function is set before doing body.
+			newfn.Body = subst.list(oldfn.Body)
+			subst.newf = saveNewf
+			ir.CurFunc = saveNewf
+
+			subst.g.target.Decls = append(subst.g.target.Decls, newfn)
+		}
+		return m
+	}
+
+	return edit(n)
+}
+
+func (subst *subster) namelist(l []*ir.Name) []*ir.Name {
+	s := make([]*ir.Name, len(l))
+	for i, n := range l {
+		s[i] = subst.node(n).(*ir.Name)
+		if n.Defn != nil {
+			s[i].Defn = subst.node(n.Defn)
+		}
+		if n.Outer != nil {
+			s[i].Outer = subst.node(n.Outer).(*ir.Name)
+		}
+	}
+	return s
+}
+
+func (subst *subster) list(l []ir.Node) []ir.Node {
+	s := make([]ir.Node, len(l))
+	for i, n := range l {
+		s[i] = subst.node(n)
+	}
+	return s
+}
+
+// tstruct substitutes type params in types of the fields of a structure type. For
+// each field, if Nname is set, tstruct also translates the Nname using
+// subst.vars, if Nname is in subst.vars. To always force the creation of a new
+// (top-level) struct, regardless of whether anything changed with the types or
+// names of the struct's fields, set force to true.
+func (subst *subster) tstruct(t *types.Type, force bool) *types.Type {
+	if t.NumFields() == 0 {
+		if t.HasTParam() {
+			// For an empty struct, we need to return a new type,
+			// since it may now be fully instantiated (HasTParam
+			// becomes false).
+			return types.NewStruct(t.Pkg(), nil)
+		}
+		return t
+	}
+	var newfields []*types.Field
+	if force {
+		newfields = make([]*types.Field, t.NumFields())
+	}
+	for i, f := range t.Fields().Slice() {
+		t2 := subst.typ(f.Type)
+		if (t2 != f.Type || f.Nname != nil) && newfields == nil {
+			newfields = make([]*types.Field, t.NumFields())
+			for j := 0; j < i; j++ {
+				newfields[j] = t.Field(j)
+			}
+		}
+		if newfields != nil {
+			// TODO(danscales): make sure this works for the field
+			// names of embedded types (which should keep the name of
+			// the type param, not the instantiated type).
+			newfields[i] = types.NewField(f.Pos, f.Sym, t2)
+			if f.Nname != nil {
+				// f.Nname may not be in subst.vars[] if this is
+				// a function name or a function instantiation type
+				// that we are translating
+				v := subst.vars[f.Nname.(*ir.Name)]
+				// Be careful not to put a nil var into Nname,
+				// since Nname is an interface, so it would be a
+				// non-nil interface.
+				if v != nil {
+					newfields[i].Nname = v
+				}
+			}
+		}
+	}
+	if newfields != nil {
+		return types.NewStruct(t.Pkg(), newfields)
+	}
+	return t
+
+}
+
+// tinter substitutes type params in types of the methods of an interface type.
+func (subst *subster) tinter(t *types.Type) *types.Type {
+	if t.Methods().Len() == 0 {
+		return t
+	}
+	var newfields []*types.Field
+	for i, f := range t.Methods().Slice() {
+		t2 := subst.typ(f.Type)
+		if (t2 != f.Type || f.Nname != nil) && newfields == nil {
+			newfields = make([]*types.Field, t.Methods().Len())
+			for j := 0; j < i; j++ {
+				newfields[j] = t.Methods().Index(j)
+			}
+		}
+		if newfields != nil {
+			newfields[i] = types.NewField(f.Pos, f.Sym, t2)
+		}
+	}
+	if newfields != nil {
+		return types.NewInterface(t.Pkg(), newfields)
+	}
+	return t
+}
+
+// instTypeName creates a name for an instantiated type, based on the name of the
+// generic type and the type args
+func instTypeName(name string, targs []*types.Type) string {
+	b := bytes.NewBufferString(name)
+	b.WriteByte('[')
+	for i, targ := range targs {
+		if i > 0 {
+			b.WriteByte(',')
+		}
+		b.WriteString(targ.String())
+	}
+	b.WriteByte(']')
+	return b.String()
+}
+
+// typ computes the type obtained by substituting any type parameter in t with the
+// corresponding type argument in subst. If t contains no type parameters, the
+// result is t; otherwise the result is a new type. It deals with recursive types
+// by using TFORW types and finding partially or fully created types via sym.Def.
+func (subst *subster) typ(t *types.Type) *types.Type {
+	if !t.HasTParam() && t.Kind() != types.TFUNC {
+		// Note: function types need to be copied regardless, as the
+		// types of closures may contain declarations that need
+		// to be copied. See #45738.
+		return t
+	}
+
+	if t.Kind() == types.TTYPEPARAM {
+		for i, tp := range subst.tparams {
+			if tp.Type == t {
+				return subst.targs[i].Type()
+			}
+		}
+		// If t is a simple typeparam T, then t has the name/symbol 'T'
+		// and t.Underlying() == t.
+		//
+		// However, consider the type definition: 'type P[T any] T'. We
+		// might use this definition so we can have a variant of type T
+		// that we can add new methods to. Suppose t is a reference to
+		// P[T]. t has the name 'P[T]', but its kind is TTYPEPARAM,
+		// because P[T] is defined as T. If we look at t.Underlying(), it
+		// is different, because the name of t.Underlying() is 'T' rather
+		// than 'P[T]'. But the kind of t.Underlying() is also TTYPEPARAM.
+		// In this case, we do the needed recursive substitution in the
+		// case statement below.
+		if t.Underlying() == t {
+			// t is a simple typeparam that didn't match anything in tparam
+			return t
+		}
+		// t is a more complex typeparam (e.g. P[T], as above, whose
+		// definition is just T).
+		assert(t.Sym() != nil)
+	}
+
+	var newsym *types.Sym
+	var neededTargs []*types.Type
+	var forw *types.Type
+
+	if t.Sym() != nil {
+		// Translate the type params for this type according to
+		// the tparam/targs mapping from subst.
+		neededTargs = make([]*types.Type, len(t.RParams()))
+		for i, rparam := range t.RParams() {
+			neededTargs[i] = subst.typ(rparam)
+		}
+		// For a named (defined) type, we have to change the name of the
+		// type as well. We do this first, so we can look up if we've
+		// already seen this type during this substitution or other
+		// definitions/substitutions.
+		genName := genericTypeName(t.Sym())
+		newsym = t.Sym().Pkg.Lookup(instTypeName(genName, neededTargs))
+		if newsym.Def != nil {
+			// We've already created this instantiated defined type.
+			return newsym.Def.Type()
+		}
+
+		// In order to deal with recursive generic types, create a TFORW
+		// type initially and set the Def field of its sym, so it can be
+		// found if this type appears recursively within the type.
+		forw = newIncompleteNamedType(t.Pos(), newsym)
+		//println("Creating new type by sub", newsym.Name, forw.HasTParam())
+		forw.SetRParams(neededTargs)
+	}
+
+	var newt *types.Type
+
+	switch t.Kind() {
+	case types.TTYPEPARAM:
+		if t.Sym() == newsym {
+			// The substitution did not change the type.
+			return t
+		}
+		// Substitute the underlying typeparam (e.g. T in P[T], see
+		// the example describing type P[T] above).
+		newt = subst.typ(t.Underlying())
+		assert(newt != t)
+
+	case types.TARRAY:
+		elem := t.Elem()
+		newelem := subst.typ(elem)
+		if newelem != elem {
+			newt = types.NewArray(newelem, t.NumElem())
+		}
+
+	case types.TPTR:
+		elem := t.Elem()
+		newelem := subst.typ(elem)
+		if newelem != elem {
+			newt = types.NewPtr(newelem)
+		}
+
+	case types.TSLICE:
+		elem := t.Elem()
+		newelem := subst.typ(elem)
+		if newelem != elem {
+			newt = types.NewSlice(newelem)
+		}
+
+	case types.TSTRUCT:
+		newt = subst.tstruct(t, false)
+		if newt == t {
+			newt = nil
+		}
+
+	case types.TFUNC:
+		newrecvs := subst.tstruct(t.Recvs(), false)
+		newparams := subst.tstruct(t.Params(), false)
+		newresults := subst.tstruct(t.Results(), false)
+		if newrecvs != t.Recvs() || newparams != t.Params() || newresults != t.Results() {
+			// If any types have changed, then the all the fields of
+			// of recv, params, and results must be copied, because they have
+			// offset fields that are dependent, and so must have an
+			// independent copy for each new signature.
+			var newrecv *types.Field
+			if newrecvs.NumFields() > 0 {
+				if newrecvs == t.Recvs() {
+					newrecvs = subst.tstruct(t.Recvs(), true)
+				}
+				newrecv = newrecvs.Field(0)
+			}
+			if newparams == t.Params() {
+				newparams = subst.tstruct(t.Params(), true)
+			}
+			if newresults == t.Results() {
+				newresults = subst.tstruct(t.Results(), true)
+			}
+			newt = types.NewSignature(t.Pkg(), newrecv, t.TParams().FieldSlice(), newparams.FieldSlice(), newresults.FieldSlice())
+		}
+
+	case types.TINTER:
+		newt = subst.tinter(t)
+		if newt == t {
+			newt = nil
+		}
+
+	case types.TMAP:
+		newkey := subst.typ(t.Key())
+		newval := subst.typ(t.Elem())
+		if newkey != t.Key() || newval != t.Elem() {
+			newt = types.NewMap(newkey, newval)
+		}
+
+	case types.TCHAN:
+		elem := t.Elem()
+		newelem := subst.typ(elem)
+		if newelem != elem {
+			newt = types.NewChan(newelem, t.ChanDir())
+			if !newt.HasTParam() {
+				// TODO(danscales): not sure why I have to do this
+				// only for channels.....
+				types.CheckSize(newt)
+			}
+		}
+	}
+	if newt == nil {
+		// Even though there were typeparams in the type, there may be no
+		// change if this is a function type for a function call (which will
+		// have its own tparams/targs in the function instantiation).
+		return t
+	}
+
+	if t.Sym() == nil {
+		// Not a named type, so there was no forwarding type and there are
+		// no methods to substitute.
+		assert(t.Methods().Len() == 0)
+		return newt
+	}
+
+	forw.SetUnderlying(newt)
+	newt = forw
+
+	if t.Kind() != types.TINTER && t.Methods().Len() > 0 {
+		// Fill in the method info for the new type.
+		var newfields []*types.Field
+		newfields = make([]*types.Field, t.Methods().Len())
+		for i, f := range t.Methods().Slice() {
+			t2 := subst.typ(f.Type)
+			oldsym := f.Nname.Sym()
+			newsym := makeInstName(oldsym, subst.targs, true)
+			var nname *ir.Name
+			if newsym.Def != nil {
+				nname = newsym.Def.(*ir.Name)
+			} else {
+				nname = ir.NewNameAt(f.Pos, newsym)
+				nname.SetType(t2)
+				newsym.Def = nname
+			}
+			newfields[i] = types.NewField(f.Pos, f.Sym, t2)
+			newfields[i].Nname = nname
+		}
+		newt.Methods().Set(newfields)
+		if !newt.HasTParam() {
+			// Generate all the methods for a new fully-instantiated type.
+			subst.g.instTypeList = append(subst.g.instTypeList, newt)
+		}
+	}
+	return newt
+}
+
+// fields sets the Nname field for the Field nodes inside a type signature, based
+// on the corresponding in/out parameters in dcl. It depends on the in and out
+// parameters being in order in dcl.
+func (subst *subster) fields(class ir.Class, oldfields []*types.Field, dcl []*ir.Name) []*types.Field {
+	// Find the starting index in dcl of declarations of the class (either
+	// PPARAM or PPARAMOUT).
+	var i int
+	for i = range dcl {
+		if dcl[i].Class == class {
+			break
+		}
+	}
+
+	// Create newfields nodes that are copies of the oldfields nodes, but
+	// with substitution for any type params, and with Nname set to be the node in
+	// Dcl for the corresponding PPARAM or PPARAMOUT.
+	newfields := make([]*types.Field, len(oldfields))
+	for j := range oldfields {
+		newfields[j] = oldfields[j].Copy()
+		newfields[j].Type = subst.typ(oldfields[j].Type)
+		// A param field will be missing from dcl if its name is
+		// unspecified or specified as "_". So, we compare the dcl sym
+		// with the field sym. If they don't match, this dcl (if there is
+		// one left) must apply to a later field.
+		if i < len(dcl) && dcl[i].Sym() == oldfields[j].Sym {
+			newfields[j].Nname = dcl[i]
+			i++
+		}
+	}
+	return newfields
+}
+
+// defer does a single defer of type t, if it is a pointer type.
+func deref(t *types.Type) *types.Type {
+	if t.IsPtr() {
+		return t.Elem()
+	}
+	return t
+}
+
+// newIncompleteNamedType returns a TFORW type t with name specified by sym, such
+// that t.nod and sym.Def are set correctly.
+func newIncompleteNamedType(pos src.XPos, sym *types.Sym) *types.Type {
+	name := ir.NewDeclNameAt(pos, ir.OTYPE, sym)
+	forw := types.NewNamed(name)
+	name.SetType(forw)
+	sym.Def = name
+	return forw
+}
diff --git a/src/cmd/compile/internal/noder/stmt.go b/src/cmd/compile/internal/noder/stmt.go
new file mode 100644
index 0000000..32a1483
--- /dev/null
+++ b/src/cmd/compile/internal/noder/stmt.go
@@ -0,0 +1,363 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+func (g *irgen) stmts(stmts []syntax.Stmt) []ir.Node {
+	var nodes []ir.Node
+	for _, stmt := range stmts {
+		switch s := g.stmt(stmt).(type) {
+		case nil: // EmptyStmt
+		case *ir.BlockStmt:
+			nodes = append(nodes, s.List...)
+		default:
+			nodes = append(nodes, s)
+		}
+	}
+	return nodes
+}
+
+func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
+	switch stmt := stmt.(type) {
+	case nil, *syntax.EmptyStmt:
+		return nil
+	case *syntax.LabeledStmt:
+		return g.labeledStmt(stmt)
+	case *syntax.BlockStmt:
+		return ir.NewBlockStmt(g.pos(stmt), g.blockStmt(stmt))
+	case *syntax.ExprStmt:
+		x := g.expr(stmt.X)
+		if call, ok := x.(*ir.CallExpr); ok {
+			call.Use = ir.CallUseStmt
+		}
+		return x
+	case *syntax.SendStmt:
+		n := ir.NewSendStmt(g.pos(stmt), g.expr(stmt.Chan), g.expr(stmt.Value))
+		if n.Chan.Type().HasTParam() || n.Value.Type().HasTParam() {
+			// Delay transforming the send if the channel or value
+			// have a type param.
+			n.SetTypecheck(3)
+			return n
+		}
+		transformSend(n)
+		n.SetTypecheck(1)
+		return n
+	case *syntax.DeclStmt:
+		return ir.NewBlockStmt(g.pos(stmt), g.decls(stmt.DeclList))
+
+	case *syntax.AssignStmt:
+		if stmt.Op != 0 && stmt.Op != syntax.Def {
+			op := g.op(stmt.Op, binOps[:])
+			var n *ir.AssignOpStmt
+			if stmt.Rhs == nil {
+				n = IncDec(g.pos(stmt), op, g.expr(stmt.Lhs))
+			} else {
+				n = ir.NewAssignOpStmt(g.pos(stmt), op, g.expr(stmt.Lhs), g.expr(stmt.Rhs))
+			}
+			if n.X.Typecheck() == 3 {
+				n.SetTypecheck(3)
+				return n
+			}
+			transformAsOp(n)
+			n.SetTypecheck(1)
+			return n
+		}
+
+		names, lhs := g.assignList(stmt.Lhs, stmt.Op == syntax.Def)
+		rhs := g.exprList(stmt.Rhs)
+
+		// We must delay transforming the assign statement if any of the
+		// lhs or rhs nodes are also delayed, since transformAssign needs
+		// to know the types of the left and right sides in various cases.
+		delay := false
+		for _, e := range lhs {
+			if e.Typecheck() == 3 {
+				delay = true
+				break
+			}
+		}
+		for _, e := range rhs {
+			if e.Typecheck() == 3 {
+				delay = true
+				break
+			}
+		}
+
+		if len(lhs) == 1 && len(rhs) == 1 {
+			n := ir.NewAssignStmt(g.pos(stmt), lhs[0], rhs[0])
+			n.Def = initDefn(n, names)
+
+			if delay {
+				n.SetTypecheck(3)
+				return n
+			}
+
+			lhs, rhs := []ir.Node{n.X}, []ir.Node{n.Y}
+			transformAssign(n, lhs, rhs)
+			n.X, n.Y = lhs[0], rhs[0]
+			n.SetTypecheck(1)
+			return n
+		}
+
+		n := ir.NewAssignListStmt(g.pos(stmt), ir.OAS2, lhs, rhs)
+		n.Def = initDefn(n, names)
+		if delay {
+			n.SetTypecheck(3)
+			return n
+		}
+		transformAssign(n, n.Lhs, n.Rhs)
+		n.SetTypecheck(1)
+		return n
+
+	case *syntax.BranchStmt:
+		return ir.NewBranchStmt(g.pos(stmt), g.tokOp(int(stmt.Tok), branchOps[:]), g.name(stmt.Label))
+	case *syntax.CallStmt:
+		return ir.NewGoDeferStmt(g.pos(stmt), g.tokOp(int(stmt.Tok), callOps[:]), g.expr(stmt.Call))
+	case *syntax.ReturnStmt:
+		n := ir.NewReturnStmt(g.pos(stmt), g.exprList(stmt.Results))
+		for _, e := range n.Results {
+			if e.Type().HasTParam() {
+				// Delay transforming the return statement if any of the
+				// return values have a type param.
+				n.SetTypecheck(3)
+				return n
+			}
+		}
+		transformReturn(n)
+		n.SetTypecheck(1)
+		return n
+	case *syntax.IfStmt:
+		return g.ifStmt(stmt)
+	case *syntax.ForStmt:
+		return g.forStmt(stmt)
+	case *syntax.SelectStmt:
+		n := g.selectStmt(stmt)
+		transformSelect(n.(*ir.SelectStmt))
+		n.SetTypecheck(1)
+		return n
+	case *syntax.SwitchStmt:
+		return g.switchStmt(stmt)
+
+	default:
+		g.unhandled("statement", stmt)
+		panic("unreachable")
+	}
+}
+
+// TODO(mdempsky): Investigate replacing with switch statements or dense arrays.
+
+var branchOps = [...]ir.Op{
+	syntax.Break:       ir.OBREAK,
+	syntax.Continue:    ir.OCONTINUE,
+	syntax.Fallthrough: ir.OFALL,
+	syntax.Goto:        ir.OGOTO,
+}
+
+var callOps = [...]ir.Op{
+	syntax.Defer: ir.ODEFER,
+	syntax.Go:    ir.OGO,
+}
+
+func (g *irgen) tokOp(tok int, ops []ir.Op) ir.Op {
+	// TODO(mdempsky): Validate.
+	return ops[tok]
+}
+
+func (g *irgen) op(op syntax.Operator, ops []ir.Op) ir.Op {
+	// TODO(mdempsky): Validate.
+	return ops[op]
+}
+
+func (g *irgen) assignList(expr syntax.Expr, def bool) ([]*ir.Name, []ir.Node) {
+	if !def {
+		return nil, g.exprList(expr)
+	}
+
+	var exprs []syntax.Expr
+	if list, ok := expr.(*syntax.ListExpr); ok {
+		exprs = list.ElemList
+	} else {
+		exprs = []syntax.Expr{expr}
+	}
+
+	var names []*ir.Name
+	res := make([]ir.Node, len(exprs))
+	for i, expr := range exprs {
+		expr := expr.(*syntax.Name)
+		if expr.Value == "_" {
+			res[i] = ir.BlankNode
+			continue
+		}
+
+		if obj, ok := g.info.Uses[expr]; ok {
+			res[i] = g.obj(obj)
+			continue
+		}
+
+		name, _ := g.def(expr)
+		names = append(names, name)
+		res[i] = name
+	}
+
+	return names, res
+}
+
+// initDefn marks the given names as declared by defn and populates
+// its Init field with ODCL nodes. It then reports whether any names
+// were so declared, which can be used to initialize defn.Def.
+func initDefn(defn ir.InitNode, names []*ir.Name) bool {
+	if len(names) == 0 {
+		return false
+	}
+
+	init := make([]ir.Node, len(names))
+	for i, name := range names {
+		name.Defn = defn
+		init[i] = ir.NewDecl(name.Pos(), ir.ODCL, name)
+	}
+	defn.SetInit(init)
+	return true
+}
+
+func (g *irgen) blockStmt(stmt *syntax.BlockStmt) []ir.Node {
+	return g.stmts(stmt.List)
+}
+
+func (g *irgen) ifStmt(stmt *syntax.IfStmt) ir.Node {
+	init := g.stmt(stmt.Init)
+	n := ir.NewIfStmt(g.pos(stmt), g.expr(stmt.Cond), g.blockStmt(stmt.Then), nil)
+	if stmt.Else != nil {
+		e := g.stmt(stmt.Else)
+		if e.Op() == ir.OBLOCK {
+			e := e.(*ir.BlockStmt)
+			n.Else = e.List
+		} else {
+			n.Else = []ir.Node{e}
+		}
+	}
+	return g.init(init, n)
+}
+
+// unpackTwo returns the first two nodes in list. If list has fewer
+// than 2 nodes, then the missing nodes are replaced with nils.
+func unpackTwo(list []ir.Node) (fst, snd ir.Node) {
+	switch len(list) {
+	case 0:
+		return nil, nil
+	case 1:
+		return list[0], nil
+	default:
+		return list[0], list[1]
+	}
+}
+
+func (g *irgen) forStmt(stmt *syntax.ForStmt) ir.Node {
+	if r, ok := stmt.Init.(*syntax.RangeClause); ok {
+		names, lhs := g.assignList(r.Lhs, r.Def)
+		key, value := unpackTwo(lhs)
+		n := ir.NewRangeStmt(g.pos(r), key, value, g.expr(r.X), g.blockStmt(stmt.Body))
+		n.Def = initDefn(n, names)
+		return n
+	}
+
+	return ir.NewForStmt(g.pos(stmt), g.stmt(stmt.Init), g.expr(stmt.Cond), g.stmt(stmt.Post), g.blockStmt(stmt.Body))
+}
+
+func (g *irgen) selectStmt(stmt *syntax.SelectStmt) ir.Node {
+	body := make([]*ir.CommClause, len(stmt.Body))
+	for i, clause := range stmt.Body {
+		body[i] = ir.NewCommStmt(g.pos(clause), g.stmt(clause.Comm), g.stmts(clause.Body))
+	}
+	return ir.NewSelectStmt(g.pos(stmt), body)
+}
+
+func (g *irgen) switchStmt(stmt *syntax.SwitchStmt) ir.Node {
+	pos := g.pos(stmt)
+	init := g.stmt(stmt.Init)
+
+	var expr ir.Node
+	switch tag := stmt.Tag.(type) {
+	case *syntax.TypeSwitchGuard:
+		var ident *ir.Ident
+		if tag.Lhs != nil {
+			ident = ir.NewIdent(g.pos(tag.Lhs), g.name(tag.Lhs))
+		}
+		expr = ir.NewTypeSwitchGuard(pos, ident, g.expr(tag.X))
+	default:
+		expr = g.expr(tag)
+	}
+
+	body := make([]*ir.CaseClause, len(stmt.Body))
+	for i, clause := range stmt.Body {
+		// Check for an implicit clause variable before
+		// visiting body, because it may contain function
+		// literals that reference it, and then it'll be
+		// associated to the wrong function.
+		//
+		// Also, override its position to the clause's colon, so that
+		// dwarfgen can find the right scope for it later.
+		// TODO(mdempsky): We should probably just store the scope
+		// directly in the ir.Name.
+		var cv *ir.Name
+		if obj, ok := g.info.Implicits[clause]; ok {
+			cv = g.obj(obj)
+			cv.SetPos(g.makeXPos(clause.Colon))
+		}
+		body[i] = ir.NewCaseStmt(g.pos(clause), g.exprList(clause.Cases), g.stmts(clause.Body))
+		body[i].Var = cv
+	}
+
+	return g.init(init, ir.NewSwitchStmt(pos, expr, body))
+}
+
+func (g *irgen) labeledStmt(label *syntax.LabeledStmt) ir.Node {
+	sym := g.name(label.Label)
+	lhs := ir.NewLabelStmt(g.pos(label), sym)
+	ls := g.stmt(label.Stmt)
+
+	// Attach label directly to control statement too.
+	switch ls := ls.(type) {
+	case *ir.ForStmt:
+		ls.Label = sym
+	case *ir.RangeStmt:
+		ls.Label = sym
+	case *ir.SelectStmt:
+		ls.Label = sym
+	case *ir.SwitchStmt:
+		ls.Label = sym
+	}
+
+	l := []ir.Node{lhs}
+	if ls != nil {
+		if ls.Op() == ir.OBLOCK {
+			ls := ls.(*ir.BlockStmt)
+			l = append(l, ls.List...)
+		} else {
+			l = append(l, ls)
+		}
+	}
+	return ir.NewBlockStmt(src.NoXPos, l)
+}
+
+func (g *irgen) init(init ir.Node, stmt ir.InitNode) ir.InitNode {
+	if init != nil {
+		stmt.SetInit([]ir.Node{init})
+	}
+	return stmt
+}
+
+func (g *irgen) name(name *syntax.Name) *types.Sym {
+	if name == nil {
+		return nil
+	}
+	return typecheck.Lookup(name.Value)
+}
diff --git a/src/cmd/compile/internal/noder/transform.go b/src/cmd/compile/internal/noder/transform.go
new file mode 100644
index 0000000..2859089
--- /dev/null
+++ b/src/cmd/compile/internal/noder/transform.go
@@ -0,0 +1,961 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains transformation functions on nodes, which are the
+// transformations that the typecheck package does that are distinct from the
+// typechecking functionality. These transform functions are pared-down copies of
+// the original typechecking functions, with all code removed that is related to:
+//
+//    - Detecting compile-time errors (already done by types2)
+//    - Setting the actual type of existing nodes (already done based on
+//      type info from types2)
+//    - Dealing with untyped constants (which types2 has already resolved)
+//
+// Each of the transformation functions requires that node passed in has its type
+// and typecheck flag set. If the transformation function replaces or adds new
+// nodes, it will set the type and typecheck flag for those new nodes.
+
+package noder
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"fmt"
+	"go/constant"
+)
+
+// Transformation functions for expressions
+
+// transformAdd transforms an addition operation (currently just addition of
+// strings). Corresponds to the "binary operators" case in typecheck.typecheck1.
+func transformAdd(n *ir.BinaryExpr) ir.Node {
+	assert(n.Type() != nil && n.Typecheck() == 1)
+	l := n.X
+	if l.Type().IsString() {
+		var add *ir.AddStringExpr
+		if l.Op() == ir.OADDSTR {
+			add = l.(*ir.AddStringExpr)
+			add.SetPos(n.Pos())
+		} else {
+			add = ir.NewAddStringExpr(n.Pos(), []ir.Node{l})
+		}
+		r := n.Y
+		if r.Op() == ir.OADDSTR {
+			r := r.(*ir.AddStringExpr)
+			add.List.Append(r.List.Take()...)
+		} else {
+			add.List.Append(r)
+		}
+		typed(l.Type(), add)
+		return add
+	}
+	return n
+}
+
+// Corresponds to typecheck.stringtoruneslit.
+func stringtoruneslit(n *ir.ConvExpr) ir.Node {
+	if n.X.Op() != ir.OLITERAL || n.X.Val().Kind() != constant.String {
+		base.Fatalf("stringtoarraylit %v", n)
+	}
+
+	var list []ir.Node
+	i := 0
+	eltType := n.Type().Elem()
+	for _, r := range ir.StringVal(n.X) {
+		elt := ir.NewKeyExpr(base.Pos, ir.NewInt(int64(i)), ir.NewInt(int64(r)))
+		// Change from untyped int to the actual element type determined
+		// by types2.  No need to change elt.Key, since the array indexes
+		// are just used for setting up the element ordering.
+		elt.Value.SetType(eltType)
+		list = append(list, elt)
+		i++
+	}
+
+	nn := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(n.Type()), nil)
+	nn.List = list
+	typed(n.Type(), nn)
+	// Need to transform the OCOMPLIT.
+	return transformCompLit(nn)
+}
+
+// transformConv transforms an OCONV node as needed, based on the types involved,
+// etc.  Corresponds to typecheck.tcConv.
+func transformConv(n *ir.ConvExpr) ir.Node {
+	t := n.X.Type()
+	op, _ := typecheck.Convertop(n.X.Op() == ir.OLITERAL, t, n.Type())
+	n.SetOp(op)
+	switch n.Op() {
+	case ir.OCONVNOP:
+		if t.Kind() == n.Type().Kind() {
+			switch t.Kind() {
+			case types.TFLOAT32, types.TFLOAT64, types.TCOMPLEX64, types.TCOMPLEX128:
+				// Floating point casts imply rounding and
+				// so the conversion must be kept.
+				n.SetOp(ir.OCONV)
+			}
+		}
+
+	// Do not convert to []byte literal. See CL 125796.
+	// Generated code and compiler memory footprint is better without it.
+	case ir.OSTR2BYTES:
+		// ok
+
+	case ir.OSTR2RUNES:
+		if n.X.Op() == ir.OLITERAL {
+			return stringtoruneslit(n)
+		}
+	}
+	return n
+}
+
+// transformConvCall transforms a conversion call. Corresponds to the OTYPE part of
+// typecheck.tcCall.
+func transformConvCall(n *ir.CallExpr) ir.Node {
+	assert(n.Type() != nil && n.Typecheck() == 1)
+	arg := n.Args[0]
+	n1 := ir.NewConvExpr(n.Pos(), ir.OCONV, nil, arg)
+	typed(n.X.Type(), n1)
+	return transformConv(n1)
+}
+
+// transformCall transforms a normal function/method call. Corresponds to last half
+// (non-conversion, non-builtin part) of typecheck.tcCall.
+func transformCall(n *ir.CallExpr) {
+	// n.Type() can be nil for calls with no return value
+	assert(n.Typecheck() == 1)
+	transformArgs(n)
+	l := n.X
+	t := l.Type()
+
+	switch l.Op() {
+	case ir.ODOTINTER:
+		n.SetOp(ir.OCALLINTER)
+
+	case ir.ODOTMETH:
+		l := l.(*ir.SelectorExpr)
+		n.SetOp(ir.OCALLMETH)
+
+		tp := t.Recv().Type
+
+		if l.X == nil || !types.Identical(l.X.Type(), tp) {
+			base.Fatalf("method receiver")
+		}
+
+	default:
+		n.SetOp(ir.OCALLFUNC)
+	}
+
+	typecheckaste(ir.OCALL, n.X, n.IsDDD, t.Params(), n.Args)
+	if t.NumResults() == 1 {
+		n.SetType(l.Type().Results().Field(0).Type)
+
+		if n.Op() == ir.OCALLFUNC && n.X.Op() == ir.ONAME {
+			if sym := n.X.(*ir.Name).Sym(); types.IsRuntimePkg(sym.Pkg) && sym.Name == "getg" {
+				// Emit code for runtime.getg() directly instead of calling function.
+				// Most such rewrites (for example the similar one for math.Sqrt) should be done in walk,
+				// so that the ordering pass can make sure to preserve the semantics of the original code
+				// (in particular, the exact time of the function call) by introducing temporaries.
+				// In this case, we know getg() always returns the same result within a given function
+				// and we want to avoid the temporaries, so we do the rewrite earlier than is typical.
+				n.SetOp(ir.OGETG)
+			}
+		}
+		return
+	}
+}
+
+// transformCompare transforms a compare operation (currently just equals/not
+// equals). Corresponds to the "comparison operators" case in
+// typecheck.typecheck1, including tcArith.
+func transformCompare(n *ir.BinaryExpr) {
+	assert(n.Type() != nil && n.Typecheck() == 1)
+	if (n.Op() == ir.OEQ || n.Op() == ir.ONE) && !types.Identical(n.X.Type(), n.Y.Type()) {
+		// Comparison is okay as long as one side is assignable to the
+		// other. The only allowed case where the conversion is not CONVNOP 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.
+		l, r := n.X, n.Y
+		lt, rt := l.Type(), r.Type()
+		converted := false
+		if rt.Kind() != types.TBLANK {
+			aop, _ := typecheck.Assignop(lt, rt)
+			if aop != ir.OXXX {
+				types.CalcSize(lt)
+				if rt.IsInterface() == lt.IsInterface() || lt.Width >= 1<<16 {
+					l = ir.NewConvExpr(base.Pos, aop, rt, l)
+					l.SetTypecheck(1)
+				}
+
+				converted = true
+			}
+		}
+
+		if !converted && lt.Kind() != types.TBLANK {
+			aop, _ := typecheck.Assignop(rt, lt)
+			if aop != ir.OXXX {
+				types.CalcSize(rt)
+				if rt.IsInterface() == lt.IsInterface() || rt.Width >= 1<<16 {
+					r = ir.NewConvExpr(base.Pos, aop, lt, r)
+					r.SetTypecheck(1)
+				}
+			}
+		}
+		n.X, n.Y = l, r
+	}
+}
+
+// Corresponds to typecheck.implicitstar.
+func implicitstar(n ir.Node) ir.Node {
+	// insert implicit * if needed for fixed array
+	t := n.Type()
+	if !t.IsPtr() {
+		return n
+	}
+	t = t.Elem()
+	if !t.IsArray() {
+		return n
+	}
+	star := ir.NewStarExpr(base.Pos, n)
+	star.SetImplicit(true)
+	return typed(t, star)
+}
+
+// transformIndex transforms an index operation.  Corresponds to typecheck.tcIndex.
+func transformIndex(n *ir.IndexExpr) {
+	assert(n.Type() != nil && n.Typecheck() == 1)
+	n.X = implicitstar(n.X)
+	l := n.X
+	t := l.Type()
+	if t.Kind() == types.TMAP {
+		n.Index = assignconvfn(n.Index, t.Key())
+		n.SetOp(ir.OINDEXMAP)
+		// Set type to just the map value, not (value, bool). This is
+		// different from types2, but fits the later stages of the
+		// compiler better.
+		n.SetType(t.Elem())
+		n.Assigned = false
+	}
+}
+
+// transformSlice transforms a slice operation.  Corresponds to typecheck.tcSlice.
+func transformSlice(n *ir.SliceExpr) {
+	assert(n.Type() != nil && n.Typecheck() == 1)
+	l := n.X
+	if l.Type().IsArray() {
+		addr := typecheck.NodAddr(n.X)
+		addr.SetImplicit(true)
+		typed(types.NewPtr(n.X.Type()), addr)
+		n.X = addr
+		l = addr
+	}
+	t := l.Type()
+	if t.IsString() {
+		n.SetOp(ir.OSLICESTR)
+	} else if t.IsPtr() && t.Elem().IsArray() {
+		if n.Op().IsSlice3() {
+			n.SetOp(ir.OSLICE3ARR)
+		} else {
+			n.SetOp(ir.OSLICEARR)
+		}
+	}
+}
+
+// Transformation functions for statements
+
+// Corresponds to typecheck.checkassign.
+func transformCheckAssign(stmt ir.Node, n ir.Node) {
+	if n.Op() == ir.OINDEXMAP {
+		n := n.(*ir.IndexExpr)
+		n.Assigned = true
+		return
+	}
+}
+
+// Corresponds to typecheck.assign.
+func transformAssign(stmt ir.Node, lhs, rhs []ir.Node) {
+	checkLHS := func(i int, typ *types.Type) {
+		transformCheckAssign(stmt, lhs[i])
+	}
+
+	cr := len(rhs)
+	if len(rhs) == 1 {
+		if rtyp := rhs[0].Type(); rtyp != nil && rtyp.IsFuncArgStruct() {
+			cr = rtyp.NumFields()
+		}
+	}
+
+	// x, ok = y
+assignOK:
+	for len(lhs) == 2 && cr == 1 {
+		stmt := stmt.(*ir.AssignListStmt)
+		r := rhs[0]
+
+		switch r.Op() {
+		case ir.OINDEXMAP:
+			stmt.SetOp(ir.OAS2MAPR)
+		case ir.ORECV:
+			stmt.SetOp(ir.OAS2RECV)
+		case ir.ODOTTYPE:
+			r := r.(*ir.TypeAssertExpr)
+			stmt.SetOp(ir.OAS2DOTTYPE)
+			r.SetOp(ir.ODOTTYPE2)
+		default:
+			break assignOK
+		}
+		checkLHS(0, r.Type())
+		checkLHS(1, types.UntypedBool)
+		return
+	}
+
+	if len(lhs) != cr {
+		for i := range lhs {
+			checkLHS(i, nil)
+		}
+		return
+	}
+
+	// x,y,z = f()
+	if cr > len(rhs) {
+		stmt := stmt.(*ir.AssignListStmt)
+		stmt.SetOp(ir.OAS2FUNC)
+		r := rhs[0].(*ir.CallExpr)
+		r.Use = ir.CallUseList
+		rtyp := r.Type()
+
+		for i := range lhs {
+			checkLHS(i, rtyp.Field(i).Type)
+		}
+		return
+	}
+
+	for i, r := range rhs {
+		checkLHS(i, r.Type())
+		if lhs[i].Type() != nil {
+			rhs[i] = assignconvfn(r, lhs[i].Type())
+		}
+	}
+}
+
+// Corresponds to typecheck.typecheckargs.
+func transformArgs(n ir.InitNode) {
+	var list []ir.Node
+	switch n := n.(type) {
+	default:
+		base.Fatalf("typecheckargs %+v", n.Op())
+	case *ir.CallExpr:
+		list = n.Args
+		if n.IsDDD {
+			return
+		}
+	case *ir.ReturnStmt:
+		list = n.Results
+	}
+	if len(list) != 1 {
+		return
+	}
+
+	t := list[0].Type()
+	if t == nil || !t.IsFuncArgStruct() {
+		return
+	}
+
+	// Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...).
+
+	// Save n as n.Orig for fmt.go.
+	if ir.Orig(n) == n {
+		n.(ir.OrigNode).SetOrig(ir.SepCopy(n))
+	}
+
+	as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil)
+	as.Rhs.Append(list...)
+
+	// If we're outside of function context, then this call will
+	// be executed during the generated init function. However,
+	// init.go hasn't yet created it. Instead, associate the
+	// temporary variables with  InitTodoFunc for now, and init.go
+	// will reassociate them later when it's appropriate.
+	static := ir.CurFunc == nil
+	if static {
+		ir.CurFunc = typecheck.InitTodoFunc
+	}
+	list = nil
+	for _, f := range t.FieldSlice() {
+		t := typecheck.Temp(f.Type)
+		as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, t))
+		as.Lhs.Append(t)
+		list = append(list, t)
+	}
+	if static {
+		ir.CurFunc = nil
+	}
+
+	switch n := n.(type) {
+	case *ir.CallExpr:
+		n.Args = list
+	case *ir.ReturnStmt:
+		n.Results = list
+	}
+
+	transformAssign(as, as.Lhs, as.Rhs)
+	as.SetTypecheck(1)
+	n.PtrInit().Append(as)
+}
+
+// assignconvfn converts node n for assignment to type t. Corresponds to
+// typecheck.assignconvfn.
+func assignconvfn(n ir.Node, t *types.Type) ir.Node {
+	if t.Kind() == types.TBLANK {
+		return n
+	}
+
+	if types.Identical(n.Type(), t) {
+		return n
+	}
+
+	op, _ := typecheck.Assignop(n.Type(), t)
+
+	r := ir.NewConvExpr(base.Pos, op, t, n)
+	r.SetTypecheck(1)
+	r.SetImplicit(true)
+	return r
+}
+
+// Corresponds to typecheck.typecheckaste.
+func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl ir.Nodes) {
+	var t *types.Type
+	var i int
+
+	lno := base.Pos
+	defer func() { base.Pos = lno }()
+
+	var n ir.Node
+	if len(nl) == 1 {
+		n = nl[0]
+	}
+
+	i = 0
+	for _, tl := range tstruct.Fields().Slice() {
+		t = tl.Type
+		if tl.IsDDD() {
+			if isddd {
+				n = nl[i]
+				ir.SetPos(n)
+				if n.Type() != nil {
+					nl[i] = assignconvfn(n, t)
+				}
+				return
+			}
+
+			// TODO(mdempsky): Make into ... call with implicit slice.
+			for ; i < len(nl); i++ {
+				n = nl[i]
+				ir.SetPos(n)
+				if n.Type() != nil {
+					nl[i] = assignconvfn(n, t.Elem())
+				}
+			}
+			return
+		}
+
+		n = nl[i]
+		ir.SetPos(n)
+		if n.Type() != nil {
+			nl[i] = assignconvfn(n, t)
+		}
+		i++
+	}
+}
+
+// transformSend transforms a send statement, converting the value to appropriate
+// type for the channel, as needed. Corresponds of typecheck.tcSend.
+func transformSend(n *ir.SendStmt) {
+	n.Value = assignconvfn(n.Value, n.Chan.Type().Elem())
+}
+
+// transformReturn transforms a return node, by doing the needed assignments and
+// any necessary conversions. Corresponds to typecheck.tcReturn()
+func transformReturn(rs *ir.ReturnStmt) {
+	transformArgs(rs)
+	nl := rs.Results
+	if ir.HasNamedResults(ir.CurFunc) && len(nl) == 0 {
+		return
+	}
+
+	typecheckaste(ir.ORETURN, nil, false, ir.CurFunc.Type().Results(), nl)
+}
+
+// transformSelect transforms a select node, creating an assignment list as needed
+// for each case. Corresponds to typecheck.tcSelect().
+func transformSelect(sel *ir.SelectStmt) {
+	for _, ncase := range sel.Cases {
+		if ncase.Comm != nil {
+			n := ncase.Comm
+			oselrecv2 := func(dst, recv ir.Node, def bool) {
+				n := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
+				n.Def = def
+				n.SetTypecheck(1)
+				ncase.Comm = n
+			}
+			switch n.Op() {
+			case ir.OAS:
+				// convert x = <-c into x, _ = <-c
+				// remove implicit conversions; the eventual assignment
+				// will reintroduce them.
+				n := n.(*ir.AssignStmt)
+				if r := n.Y; r.Op() == ir.OCONVNOP || r.Op() == ir.OCONVIFACE {
+					r := r.(*ir.ConvExpr)
+					if r.Implicit() {
+						n.Y = r.X
+					}
+				}
+				oselrecv2(n.X, n.Y, n.Def)
+
+			case ir.OAS2RECV:
+				n := n.(*ir.AssignListStmt)
+				n.SetOp(ir.OSELRECV2)
+
+			case ir.ORECV:
+				// convert <-c into _, _ = <-c
+				n := n.(*ir.UnaryExpr)
+				oselrecv2(ir.BlankNode, n, false)
+
+			case ir.OSEND:
+				break
+			}
+		}
+	}
+}
+
+// transformAsOp transforms an AssignOp statement. Corresponds to OASOP case in
+// typecheck1.
+func transformAsOp(n *ir.AssignOpStmt) {
+	transformCheckAssign(n, n.X)
+}
+
+// transformDot transforms an OXDOT (or ODOT) or ODOT, ODOTPTR, ODOTMETH,
+// ODOTINTER, or OCALLPART, as appropriate. It adds in extra nodes as needed to
+// access embedded fields. Corresponds to typecheck.tcDot.
+func transformDot(n *ir.SelectorExpr, isCall bool) ir.Node {
+	assert(n.Type() != nil && n.Typecheck() == 1)
+	if n.Op() == ir.OXDOT {
+		n = typecheck.AddImplicitDots(n)
+		n.SetOp(ir.ODOT)
+	}
+
+	t := n.X.Type()
+
+	if n.X.Op() == ir.OTYPE {
+		return transformMethodExpr(n)
+	}
+
+	if t.IsPtr() && !t.Elem().IsInterface() {
+		t = t.Elem()
+		n.SetOp(ir.ODOTPTR)
+	}
+
+	f := typecheck.Lookdot(n, t, 0)
+	assert(f != nil)
+
+	if (n.Op() == ir.ODOTINTER || n.Op() == ir.ODOTMETH) && !isCall {
+		n.SetOp(ir.OCALLPART)
+		n.SetType(typecheck.MethodValueWrapper(n).Type())
+	}
+	return n
+}
+
+// Corresponds to typecheck.typecheckMethodExpr.
+func transformMethodExpr(n *ir.SelectorExpr) (res ir.Node) {
+	t := n.X.Type()
+
+	// Compute the method set for t.
+	var ms *types.Fields
+	if t.IsInterface() {
+		ms = t.AllMethods()
+	} else {
+		mt := types.ReceiverBaseType(t)
+		typecheck.CalcMethods(mt)
+		ms = mt.AllMethods()
+
+		// The method expression T.m requires a wrapper when T
+		// is different from m's declared receiver type. We
+		// normally generate these wrappers while writing out
+		// runtime type descriptors, which is always done for
+		// types declared at package scope. However, we need
+		// to make sure to generate wrappers for anonymous
+		// receiver types too.
+		if mt.Sym() == nil {
+			typecheck.NeedRuntimeType(t)
+		}
+	}
+
+	s := n.Sel
+	m := typecheck.Lookdot1(n, s, t, ms, 0)
+	assert(m != nil)
+
+	n.SetOp(ir.OMETHEXPR)
+	n.Selection = m
+	n.SetType(typecheck.NewMethodType(m.Type, n.X.Type()))
+	return n
+}
+
+// Corresponds to typecheck.tcAppend.
+func transformAppend(n *ir.CallExpr) ir.Node {
+	transformArgs(n)
+	args := n.Args
+	t := args[0].Type()
+	assert(t.IsSlice())
+
+	if n.IsDDD {
+		if t.Elem().IsKind(types.TUINT8) && args[1].Type().IsString() {
+			return n
+		}
+
+		args[1] = assignconvfn(args[1], t.Underlying())
+		return n
+	}
+
+	as := args[1:]
+	for i, n := range as {
+		assert(n.Type() != nil)
+		as[i] = assignconvfn(n, t.Elem())
+	}
+	return n
+}
+
+// Corresponds to typecheck.tcComplex.
+func transformComplex(n *ir.BinaryExpr) ir.Node {
+	l := n.X
+	r := n.Y
+
+	assert(types.Identical(l.Type(), r.Type()))
+
+	var t *types.Type
+	switch l.Type().Kind() {
+	case types.TFLOAT32:
+		t = types.Types[types.TCOMPLEX64]
+	case types.TFLOAT64:
+		t = types.Types[types.TCOMPLEX128]
+	default:
+		panic(fmt.Sprintf("transformComplex: unexpected type %v", l.Type()))
+	}
+
+	// Must set the type here for generics, because this can't be determined
+	// by substitution of the generic types.
+	typed(t, n)
+	return n
+}
+
+// Corresponds to typecheck.tcDelete.
+func transformDelete(n *ir.CallExpr) ir.Node {
+	transformArgs(n)
+	args := n.Args
+	assert(len(args) == 2)
+
+	l := args[0]
+	r := args[1]
+
+	args[1] = assignconvfn(r, l.Type().Key())
+	return n
+}
+
+// Corresponds to typecheck.tcMake.
+func transformMake(n *ir.CallExpr) ir.Node {
+	args := n.Args
+
+	n.Args = nil
+	l := args[0]
+	t := l.Type()
+	assert(t != nil)
+
+	i := 1
+	var nn ir.Node
+	switch t.Kind() {
+	case types.TSLICE:
+		l = args[i]
+		i++
+		var r ir.Node
+		if i < len(args) {
+			r = args[i]
+			i++
+		}
+		nn = ir.NewMakeExpr(n.Pos(), ir.OMAKESLICE, l, r)
+
+	case types.TMAP:
+		if i < len(args) {
+			l = args[i]
+			i++
+		} else {
+			l = ir.NewInt(0)
+		}
+		nn = ir.NewMakeExpr(n.Pos(), ir.OMAKEMAP, l, nil)
+		nn.SetEsc(n.Esc())
+
+	case types.TCHAN:
+		l = nil
+		if i < len(args) {
+			l = args[i]
+			i++
+		} else {
+			l = ir.NewInt(0)
+		}
+		nn = ir.NewMakeExpr(n.Pos(), ir.OMAKECHAN, l, nil)
+	default:
+		panic(fmt.Sprintf("transformMake: unexpected type %v", t))
+	}
+
+	assert(i == len(args))
+	typed(n.Type(), nn)
+	return nn
+}
+
+// Corresponds to typecheck.tcPanic.
+func transformPanic(n *ir.UnaryExpr) ir.Node {
+	n.X = assignconvfn(n.X, types.Types[types.TINTER])
+	return n
+}
+
+// Corresponds to typecheck.tcPrint.
+func transformPrint(n *ir.CallExpr) ir.Node {
+	transformArgs(n)
+	return n
+}
+
+// Corresponds to typecheck.tcRealImag.
+func transformRealImag(n *ir.UnaryExpr) ir.Node {
+	l := n.X
+	var t *types.Type
+
+	// Determine result type.
+	switch l.Type().Kind() {
+	case types.TCOMPLEX64:
+		t = types.Types[types.TFLOAT32]
+	case types.TCOMPLEX128:
+		t = types.Types[types.TFLOAT64]
+	default:
+		panic(fmt.Sprintf("transformRealImag: unexpected type %v", l.Type()))
+	}
+
+	// Must set the type here for generics, because this can't be determined
+	// by substitution of the generic types.
+	typed(t, n)
+	return n
+}
+
+// Corresponds to typecheck.tcLenCap.
+func transformLenCap(n *ir.UnaryExpr) ir.Node {
+	n.X = implicitstar(n.X)
+	return n
+}
+
+// Corresponds to Builtin part of tcCall.
+func transformBuiltin(n *ir.CallExpr) ir.Node {
+	// n.Type() can be nil for builtins with no return value
+	assert(n.Typecheck() == 1)
+	fun := n.X.(*ir.Name)
+	op := fun.BuiltinOp
+
+	switch op {
+	case ir.OAPPEND, ir.ODELETE, ir.OMAKE, ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
+		n.SetOp(op)
+		n.X = nil
+		switch op {
+		case ir.OAPPEND:
+			return transformAppend(n)
+		case ir.ODELETE:
+			return transformDelete(n)
+		case ir.OMAKE:
+			return transformMake(n)
+		case ir.OPRINT, ir.OPRINTN:
+			return transformPrint(n)
+		case ir.ORECOVER:
+			// nothing more to do
+			return n
+		}
+
+	case ir.OCAP, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.OPANIC, ir.OREAL:
+		transformArgs(n)
+		fallthrough
+
+	case ir.ONEW, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
+		u := ir.NewUnaryExpr(n.Pos(), op, n.Args[0])
+		u1 := typed(n.Type(), ir.InitExpr(n.Init(), u)) // typecheckargs can add to old.Init
+		switch op {
+		case ir.OCAP, ir.OLEN:
+			return transformLenCap(u1.(*ir.UnaryExpr))
+		case ir.OREAL, ir.OIMAG:
+			return transformRealImag(u1.(*ir.UnaryExpr))
+		case ir.OPANIC:
+			return transformPanic(u1.(*ir.UnaryExpr))
+		case ir.OCLOSE, ir.ONEW, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
+			// nothing more to do
+			return u1
+		}
+
+	case ir.OCOMPLEX, ir.OCOPY, ir.OUNSAFEADD, ir.OUNSAFESLICE:
+		transformArgs(n)
+		b := ir.NewBinaryExpr(n.Pos(), op, n.Args[0], n.Args[1])
+		n1 := typed(n.Type(), ir.InitExpr(n.Init(), b))
+		if op != ir.OCOMPLEX {
+			// nothing more to do
+			return n1
+		}
+		return transformComplex(n1.(*ir.BinaryExpr))
+
+	default:
+		panic(fmt.Sprintf("transformBuiltin: unexpected op %v", op))
+	}
+
+	return n
+}
+
+func hasKeys(l ir.Nodes) bool {
+	for _, n := range l {
+		if n.Op() == ir.OKEY || n.Op() == ir.OSTRUCTKEY {
+			return true
+		}
+	}
+	return false
+}
+
+// transformArrayLit runs assignconvfn on each array element and returns the
+// length of the slice/array that is needed to hold all the array keys/indexes
+// (one more than the highest index). Corresponds to typecheck.typecheckarraylit.
+func transformArrayLit(elemType *types.Type, bound int64, elts []ir.Node) int64 {
+	var key, length int64
+	for i, elt := range elts {
+		ir.SetPos(elt)
+		r := elts[i]
+		var kv *ir.KeyExpr
+		if elt.Op() == ir.OKEY {
+			elt := elt.(*ir.KeyExpr)
+			key = typecheck.IndexConst(elt.Key)
+			assert(key >= 0)
+			kv = elt
+			r = elt.Value
+		}
+
+		r = assignconvfn(r, elemType)
+		if kv != nil {
+			kv.Value = r
+		} else {
+			elts[i] = r
+		}
+
+		key++
+		if key > length {
+			length = key
+		}
+	}
+
+	return length
+}
+
+// transformCompLit transforms n to an OARRAYLIT, OSLICELIT, OMAPLIT, or
+// OSTRUCTLIT node, with any needed conversions. Corresponds to
+// typecheck.tcCompLit.
+func transformCompLit(n *ir.CompLitExpr) (res ir.Node) {
+	assert(n.Type() != nil && n.Typecheck() == 1)
+	lno := base.Pos
+	defer func() {
+		base.Pos = lno
+	}()
+
+	// Save original node (including n.Right)
+	n.SetOrig(ir.Copy(n))
+
+	ir.SetPos(n)
+
+	t := n.Type()
+
+	switch t.Kind() {
+	default:
+		base.Fatalf("transformCompLit %v", t.Kind())
+
+	case types.TARRAY:
+		transformArrayLit(t.Elem(), t.NumElem(), n.List)
+		n.SetOp(ir.OARRAYLIT)
+
+	case types.TSLICE:
+		length := transformArrayLit(t.Elem(), -1, n.List)
+		n.SetOp(ir.OSLICELIT)
+		n.Len = length
+
+	case types.TMAP:
+		for _, l := range n.List {
+			ir.SetPos(l)
+			assert(l.Op() == ir.OKEY)
+			l := l.(*ir.KeyExpr)
+
+			r := l.Key
+			l.Key = assignconvfn(r, t.Key())
+
+			r = l.Value
+			l.Value = assignconvfn(r, t.Elem())
+		}
+
+		n.SetOp(ir.OMAPLIT)
+
+	case types.TSTRUCT:
+		// Need valid field offsets for Xoffset below.
+		types.CalcSize(t)
+
+		if len(n.List) != 0 && !hasKeys(n.List) {
+			// simple list of values
+			ls := n.List
+			for i, n1 := range ls {
+				ir.SetPos(n1)
+
+				f := t.Field(i)
+				n1 = assignconvfn(n1, f.Type)
+				sk := ir.NewStructKeyExpr(base.Pos, f.Sym, n1)
+				sk.Offset = f.Offset
+				ls[i] = sk
+			}
+			assert(len(ls) >= t.NumFields())
+		} else {
+			// keyed list
+			ls := n.List
+			for i, l := range ls {
+				ir.SetPos(l)
+
+				if l.Op() == ir.OKEY {
+					kv := l.(*ir.KeyExpr)
+					key := kv.Key
+
+					// Sym might have resolved to name in other top-level
+					// package, because of import dot. Redirect to correct sym
+					// before we do the lookup.
+					s := key.Sym()
+					if id, ok := key.(*ir.Ident); ok && typecheck.DotImportRefs[id] != nil {
+						s = typecheck.Lookup(s.Name)
+					}
+
+					// An OXDOT uses the Sym field to hold
+					// the field to the right of the dot,
+					// so s will be non-nil, but an OXDOT
+					// is never a valid struct literal key.
+					assert(!(s == nil || s.Pkg != types.LocalPkg || key.Op() == ir.OXDOT || s.IsBlank()))
+
+					l = ir.NewStructKeyExpr(l.Pos(), s, kv.Value)
+					ls[i] = l
+				}
+
+				assert(l.Op() == ir.OSTRUCTKEY)
+				l := l.(*ir.StructKeyExpr)
+
+				f := typecheck.Lookdot1(nil, l.Field, t, t.Fields(), 0)
+				l.Offset = f.Offset
+
+				l.Value = assignconvfn(l.Value, f.Type)
+			}
+		}
+
+		n.SetOp(ir.OSTRUCTLIT)
+	}
+
+	return n
+}
diff --git a/src/cmd/compile/internal/noder/types.go b/src/cmd/compile/internal/noder/types.go
new file mode 100644
index 0000000..8680559
--- /dev/null
+++ b/src/cmd/compile/internal/noder/types.go
@@ -0,0 +1,432 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"bytes"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/compile/internal/types2"
+	"cmd/internal/src"
+	"strings"
+)
+
+func (g *irgen) pkg(pkg *types2.Package) *types.Pkg {
+	switch pkg {
+	case nil:
+		return types.BuiltinPkg
+	case g.self:
+		return types.LocalPkg
+	case types2.Unsafe:
+		return ir.Pkgs.Unsafe
+	}
+	return types.NewPkg(pkg.Path(), pkg.Name())
+}
+
+// typ converts a types2.Type to a types.Type, including caching of previously
+// translated types.
+func (g *irgen) typ(typ types2.Type) *types.Type {
+	res := g.typ1(typ)
+
+	// Calculate the size for all concrete types seen by the frontend. The old
+	// typechecker calls CheckSize() a lot, and we want to eliminate calling
+	// it eventually, so we should do it here instead. We only call it for
+	// top-level types (i.e. we do it here rather in typ1), to make sure that
+	// recursive types have been fully constructed before we call CheckSize.
+	if res != nil && !res.IsUntyped() && !res.IsFuncArgStruct() && !res.HasTParam() {
+		types.CheckSize(res)
+	}
+	return res
+}
+
+// typ1 is like typ, but doesn't call CheckSize, since it may have only
+// constructed part of a recursive type. Should not be called from outside this
+// file (g.typ is the "external" entry point).
+func (g *irgen) typ1(typ types2.Type) *types.Type {
+	// Cache type2-to-type mappings. Important so that each defined generic
+	// type (instantiated or not) has a single types.Type representation.
+	// Also saves a lot of computation and memory by avoiding re-translating
+	// types2 types repeatedly.
+	res, ok := g.typs[typ]
+	if !ok {
+		res = g.typ0(typ)
+		g.typs[typ] = res
+	}
+	return res
+}
+
+// instTypeName2 creates a name for an instantiated type, base on the type args
+// (given as types2 types).
+func instTypeName2(name string, targs []types2.Type) string {
+	b := bytes.NewBufferString(name)
+	b.WriteByte('[')
+	for i, targ := range targs {
+		if i > 0 {
+			b.WriteByte(',')
+		}
+		tname := types2.TypeString(targ,
+			func(*types2.Package) string { return "" })
+		if strings.Index(tname, ", ") >= 0 {
+			// types2.TypeString puts spaces after a comma in a type
+			// list, but we don't want spaces in our actual type names
+			// and method/function names derived from them.
+			tname = strings.Replace(tname, ", ", ",", -1)
+		}
+		b.WriteString(tname)
+	}
+	b.WriteByte(']')
+	return b.String()
+}
+
+// typ0 converts a types2.Type to a types.Type, but doesn't do the caching check
+// at the top level.
+func (g *irgen) typ0(typ types2.Type) *types.Type {
+	switch typ := typ.(type) {
+	case *types2.Basic:
+		return g.basic(typ)
+	case *types2.Named:
+		if typ.TParams() != nil {
+			// typ is an instantiation of a defined (named) generic type.
+			// This instantiation should also be a defined (named) type.
+			// types2 gives us the substituted type in t.Underlying()
+			// The substituted type may or may not still have type
+			// params. We might, for example, be substituting one type
+			// param for another type param.
+
+			if typ.TArgs() == nil {
+				base.Fatalf("In typ0, Targs should be set if TParams is set")
+			}
+
+			// When converted to types.Type, typ must have a name,
+			// based on the names of the type arguments. We need a
+			// name to deal with recursive generic types (and it also
+			// looks better when printing types).
+			instName := instTypeName2(typ.Obj().Name(), typ.TArgs())
+			s := g.pkg(typ.Obj().Pkg()).Lookup(instName)
+			if s.Def != nil {
+				// We have already encountered this instantiation,
+				// so use the type we previously created, since there
+				// must be exactly one instance of a defined type.
+				return s.Def.Type()
+			}
+
+			// Create a forwarding type first and put it in the g.typs
+			// map, in order to deal with recursive generic types.
+			// Fully set up the extra ntyp information (Def, RParams,
+			// which may set HasTParam) before translating the
+			// underlying type itself, so we handle recursion
+			// correctly, including via method signatures.
+			ntyp := newIncompleteNamedType(g.pos(typ.Obj().Pos()), s)
+			g.typs[typ] = ntyp
+
+			// If ntyp still has type params, then we must be
+			// referencing something like 'value[T2]', as when
+			// specifying the generic receiver of a method,
+			// where value was defined as "type value[T any]
+			// ...". Save the type args, which will now be the
+			// new type  of the current type.
+			//
+			// If ntyp does not have type params, we are saving the
+			// concrete types used to instantiate this type. We'll use
+			// these when instantiating the methods of the
+			// instantiated type.
+			rparams := make([]*types.Type, len(typ.TArgs()))
+			for i, targ := range typ.TArgs() {
+				rparams[i] = g.typ1(targ)
+			}
+			ntyp.SetRParams(rparams)
+			//fmt.Printf("Saw new type %v %v\n", instName, ntyp.HasTParam())
+
+			ntyp.SetUnderlying(g.typ1(typ.Underlying()))
+			g.fillinMethods(typ, ntyp)
+			return ntyp
+		}
+		obj := g.obj(typ.Obj())
+		if obj.Op() != ir.OTYPE {
+			base.FatalfAt(obj.Pos(), "expected type: %L", obj)
+		}
+		return obj.Type()
+
+	case *types2.Array:
+		return types.NewArray(g.typ1(typ.Elem()), typ.Len())
+	case *types2.Chan:
+		return types.NewChan(g.typ1(typ.Elem()), dirs[typ.Dir()])
+	case *types2.Map:
+		return types.NewMap(g.typ1(typ.Key()), g.typ1(typ.Elem()))
+	case *types2.Pointer:
+		return types.NewPtr(g.typ1(typ.Elem()))
+	case *types2.Signature:
+		return g.signature(nil, typ)
+	case *types2.Slice:
+		return types.NewSlice(g.typ1(typ.Elem()))
+
+	case *types2.Struct:
+		fields := make([]*types.Field, typ.NumFields())
+		for i := range fields {
+			v := typ.Field(i)
+			f := types.NewField(g.pos(v), g.selector(v), g.typ1(v.Type()))
+			f.Note = typ.Tag(i)
+			if v.Embedded() {
+				f.Embedded = 1
+			}
+			fields[i] = f
+		}
+		return types.NewStruct(g.tpkg(typ), fields)
+
+	case *types2.Interface:
+		embeddeds := make([]*types.Field, typ.NumEmbeddeds())
+		j := 0
+		for i := range embeddeds {
+			// TODO(mdempsky): Get embedding position.
+			e := typ.EmbeddedType(i)
+			if t := types2.AsInterface(e); t != nil && t.IsComparable() {
+				// Ignore predefined type 'comparable', since it
+				// doesn't resolve and it doesn't have any
+				// relevant methods.
+				continue
+			}
+			embeddeds[j] = types.NewField(src.NoXPos, nil, g.typ1(e))
+			j++
+		}
+		embeddeds = embeddeds[:j]
+
+		methods := make([]*types.Field, typ.NumExplicitMethods())
+		for i := range methods {
+			m := typ.ExplicitMethod(i)
+			mtyp := g.signature(typecheck.FakeRecv(), m.Type().(*types2.Signature))
+			methods[i] = types.NewField(g.pos(m), g.selector(m), mtyp)
+		}
+
+		return types.NewInterface(g.tpkg(typ), append(embeddeds, methods...))
+
+	case *types2.TypeParam:
+		tp := types.NewTypeParam(g.tpkg(typ))
+		// Save the name of the type parameter in the sym of the type.
+		// Include the types2 subscript in the sym name
+		sym := g.pkg(typ.Obj().Pkg()).Lookup(types2.TypeString(typ, func(*types2.Package) string { return "" }))
+		tp.SetSym(sym)
+		// Set g.typs[typ] in case the bound methods reference typ.
+		g.typs[typ] = tp
+
+		// TODO(danscales): we don't currently need to use the bounds
+		// anywhere, so eventually we can probably remove.
+		bound := g.typ1(typ.Bound())
+		*tp.Methods() = *bound.Methods()
+		return tp
+
+	case *types2.Tuple:
+		// Tuples are used for the type of a function call (i.e. the
+		// return value of the function).
+		if typ == nil {
+			return (*types.Type)(nil)
+		}
+		fields := make([]*types.Field, typ.Len())
+		for i := range fields {
+			fields[i] = g.param(typ.At(i))
+		}
+		t := types.NewStruct(types.LocalPkg, fields)
+		t.StructType().Funarg = types.FunargResults
+		return t
+
+	default:
+		base.FatalfAt(src.NoXPos, "unhandled type: %v (%T)", typ, typ)
+		panic("unreachable")
+	}
+}
+
+// fillinMethods fills in the method name nodes and types for a defined type. This
+// is needed for later typechecking when looking up methods of instantiated types,
+// and for actually generating the methods for instantiated types.
+func (g *irgen) fillinMethods(typ *types2.Named, ntyp *types.Type) {
+	if typ.NumMethods() != 0 {
+		targs := make([]ir.Node, len(typ.TArgs()))
+		for i, targ := range typ.TArgs() {
+			targs[i] = ir.TypeNode(g.typ1(targ))
+		}
+
+		methods := make([]*types.Field, typ.NumMethods())
+		for i := range methods {
+			m := typ.Method(i)
+			meth := g.obj(m)
+			recvType := types2.AsSignature(m.Type()).Recv().Type()
+			ptr := types2.AsPointer(recvType)
+			if ptr != nil {
+				recvType = ptr.Elem()
+			}
+			if recvType != types2.Type(typ) {
+				// Unfortunately, meth is the type of the method of the
+				// generic type, so we have to do a substitution to get
+				// the name/type of the method of the instantiated type,
+				// using m.Type().RParams() and typ.TArgs()
+				inst2 := instTypeName2("", typ.TArgs())
+				name := meth.Sym().Name
+				i1 := strings.Index(name, "[")
+				i2 := strings.Index(name[i1:], "]")
+				assert(i1 >= 0 && i2 >= 0)
+				// Generate the name of the instantiated method.
+				name = name[0:i1] + inst2 + name[i1+i2+1:]
+				newsym := meth.Sym().Pkg.Lookup(name)
+				var meth2 *ir.Name
+				if newsym.Def != nil {
+					meth2 = newsym.Def.(*ir.Name)
+				} else {
+					meth2 = ir.NewNameAt(meth.Pos(), newsym)
+					rparams := types2.AsSignature(m.Type()).RParams()
+					tparams := make([]*types.Field, len(rparams))
+					for i, rparam := range rparams {
+						tparams[i] = types.NewField(src.NoXPos, nil, g.typ1(rparam.Type()))
+					}
+					assert(len(tparams) == len(targs))
+					subst := &subster{
+						g:       g,
+						tparams: tparams,
+						targs:   targs,
+					}
+					// Do the substitution of the type
+					meth2.SetType(subst.typ(meth.Type()))
+					newsym.Def = meth2
+				}
+				meth = meth2
+			}
+			methods[i] = types.NewField(meth.Pos(), g.selector(m), meth.Type())
+			methods[i].Nname = meth
+		}
+		ntyp.Methods().Set(methods)
+		if !ntyp.HasTParam() {
+			// Generate all the methods for a new fully-instantiated type.
+			g.instTypeList = append(g.instTypeList, ntyp)
+		}
+	}
+}
+
+func (g *irgen) signature(recv *types.Field, sig *types2.Signature) *types.Type {
+	tparams2 := sig.TParams()
+	tparams := make([]*types.Field, len(tparams2))
+	for i := range tparams {
+		tp := tparams2[i]
+		tparams[i] = types.NewField(g.pos(tp), g.sym(tp), g.typ1(tp.Type()))
+	}
+
+	do := func(typ *types2.Tuple) []*types.Field {
+		fields := make([]*types.Field, typ.Len())
+		for i := range fields {
+			fields[i] = g.param(typ.At(i))
+		}
+		return fields
+	}
+	params := do(sig.Params())
+	results := do(sig.Results())
+	if sig.Variadic() {
+		params[len(params)-1].SetIsDDD(true)
+	}
+
+	return types.NewSignature(g.tpkg(sig), recv, tparams, params, results)
+}
+
+func (g *irgen) param(v *types2.Var) *types.Field {
+	return types.NewField(g.pos(v), g.sym(v), g.typ1(v.Type()))
+}
+
+func (g *irgen) sym(obj types2.Object) *types.Sym {
+	if name := obj.Name(); name != "" {
+		return g.pkg(obj.Pkg()).Lookup(obj.Name())
+	}
+	return nil
+}
+
+func (g *irgen) selector(obj types2.Object) *types.Sym {
+	pkg, name := g.pkg(obj.Pkg()), obj.Name()
+	if types.IsExported(name) {
+		pkg = types.LocalPkg
+	}
+	return pkg.Lookup(name)
+}
+
+// tpkg returns the package that a function, interface, or struct type
+// expression appeared in.
+//
+// Caveat: For the degenerate types "func()", "interface{}", and
+// "struct{}", tpkg always returns LocalPkg. However, we only need the
+// package information so that go/types can report it via its API, and
+// the reason we fail to return the original package for these
+// particular types is because go/types does *not* report it for
+// them. So in practice this limitation is probably moot.
+func (g *irgen) tpkg(typ types2.Type) *types.Pkg {
+	anyObj := func() types2.Object {
+		switch typ := typ.(type) {
+		case *types2.Signature:
+			if recv := typ.Recv(); recv != nil {
+				return recv
+			}
+			if params := typ.Params(); params.Len() > 0 {
+				return params.At(0)
+			}
+			if results := typ.Results(); results.Len() > 0 {
+				return results.At(0)
+			}
+		case *types2.Struct:
+			if typ.NumFields() > 0 {
+				return typ.Field(0)
+			}
+		case *types2.Interface:
+			if typ.NumExplicitMethods() > 0 {
+				return typ.ExplicitMethod(0)
+			}
+		}
+		return nil
+	}
+
+	if obj := anyObj(); obj != nil {
+		return g.pkg(obj.Pkg())
+	}
+	return types.LocalPkg
+}
+
+func (g *irgen) basic(typ *types2.Basic) *types.Type {
+	switch typ.Name() {
+	case "byte":
+		return types.ByteType
+	case "rune":
+		return types.RuneType
+	}
+	return *basics[typ.Kind()]
+}
+
+var basics = [...]**types.Type{
+	types2.Invalid:        new(*types.Type),
+	types2.Bool:           &types.Types[types.TBOOL],
+	types2.Int:            &types.Types[types.TINT],
+	types2.Int8:           &types.Types[types.TINT8],
+	types2.Int16:          &types.Types[types.TINT16],
+	types2.Int32:          &types.Types[types.TINT32],
+	types2.Int64:          &types.Types[types.TINT64],
+	types2.Uint:           &types.Types[types.TUINT],
+	types2.Uint8:          &types.Types[types.TUINT8],
+	types2.Uint16:         &types.Types[types.TUINT16],
+	types2.Uint32:         &types.Types[types.TUINT32],
+	types2.Uint64:         &types.Types[types.TUINT64],
+	types2.Uintptr:        &types.Types[types.TUINTPTR],
+	types2.Float32:        &types.Types[types.TFLOAT32],
+	types2.Float64:        &types.Types[types.TFLOAT64],
+	types2.Complex64:      &types.Types[types.TCOMPLEX64],
+	types2.Complex128:     &types.Types[types.TCOMPLEX128],
+	types2.String:         &types.Types[types.TSTRING],
+	types2.UnsafePointer:  &types.Types[types.TUNSAFEPTR],
+	types2.UntypedBool:    &types.UntypedBool,
+	types2.UntypedInt:     &types.UntypedInt,
+	types2.UntypedRune:    &types.UntypedRune,
+	types2.UntypedFloat:   &types.UntypedFloat,
+	types2.UntypedComplex: &types.UntypedComplex,
+	types2.UntypedString:  &types.UntypedString,
+	types2.UntypedNil:     &types.Types[types.TNIL],
+}
+
+var dirs = [...]types.ChanDir{
+	types2.SendRecv: types.Cboth,
+	types2.SendOnly: types.Csend,
+	types2.RecvOnly: types.Crecv,
+}
diff --git a/src/cmd/compile/internal/noder/validate.go b/src/cmd/compile/internal/noder/validate.go
new file mode 100644
index 0000000..b926222
--- /dev/null
+++ b/src/cmd/compile/internal/noder/validate.go
@@ -0,0 +1,115 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+	"go/constant"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/types"
+	"cmd/compile/internal/types2"
+)
+
+// match reports whether types t1 and t2 are consistent
+// representations for a given expression's type.
+func (g *irgen) match(t1 *types.Type, t2 types2.Type, hasOK bool) bool {
+	tuple, ok := t2.(*types2.Tuple)
+	if !ok {
+		// Not a tuple; can use simple type identity comparison.
+		return types.Identical(t1, g.typ(t2))
+	}
+
+	if hasOK {
+		// For has-ok values, types2 represents the expression's type as a
+		// 2-element tuple, whereas ir just uses the first type and infers
+		// that the second type is boolean. Must match either, since we
+		// sometimes delay the transformation to the ir form.
+		if tuple.Len() == 2 && types.Identical(t1, g.typ(tuple.At(0).Type())) {
+			return true
+		}
+		return types.Identical(t1, g.typ(t2))
+	}
+
+	if t1 == nil || tuple == nil {
+		return t1 == nil && tuple == nil
+	}
+	if !t1.IsFuncArgStruct() {
+		return false
+	}
+	if t1.NumFields() != tuple.Len() {
+		return false
+	}
+	for i, result := range t1.FieldSlice() {
+		if !types.Identical(result.Type, g.typ(tuple.At(i).Type())) {
+			return false
+		}
+	}
+	return true
+}
+
+func (g *irgen) validate(n syntax.Node) {
+	switch n := n.(type) {
+	case *syntax.CallExpr:
+		tv := g.info.Types[n.Fun]
+		if tv.IsBuiltin() {
+			switch builtin := n.Fun.(type) {
+			case *syntax.Name:
+				g.validateBuiltin(builtin.Value, n)
+			case *syntax.SelectorExpr:
+				g.validateBuiltin(builtin.Sel.Value, n)
+			default:
+				g.unhandled("builtin", n)
+			}
+		}
+	}
+}
+
+func (g *irgen) validateBuiltin(name string, call *syntax.CallExpr) {
+	switch name {
+	case "Alignof", "Offsetof", "Sizeof":
+		// Check that types2+gcSizes calculates sizes the same
+		// as cmd/compile does.
+
+		got, ok := constant.Int64Val(g.info.Types[call].Value)
+		if !ok {
+			base.FatalfAt(g.pos(call), "expected int64 constant value")
+		}
+
+		want := g.unsafeExpr(name, call.ArgList[0])
+		if got != want {
+			base.FatalfAt(g.pos(call), "got %v from types2, but want %v", got, want)
+		}
+	}
+}
+
+// unsafeExpr evaluates the given unsafe builtin function on arg.
+func (g *irgen) unsafeExpr(name string, arg syntax.Expr) int64 {
+	switch name {
+	case "Alignof":
+		return g.typ(g.info.Types[arg].Type).Alignment()
+	case "Sizeof":
+		return g.typ(g.info.Types[arg].Type).Size()
+	}
+
+	// Offsetof
+
+	sel := arg.(*syntax.SelectorExpr)
+	selection := g.info.Selections[sel]
+
+	typ := g.typ(g.info.Types[sel.X].Type)
+	typ = deref(typ)
+
+	var offset int64
+	for _, i := range selection.Index() {
+		// Ensure field offsets have been calculated.
+		types.CalcSize(typ)
+
+		f := typ.Field(i)
+		offset += f.Offset
+		typ = f.Type
+	}
+	return offset
+}
diff --git a/src/cmd/compile/internal/objw/objw.go b/src/cmd/compile/internal/objw/objw.go
new file mode 100644
index 0000000..ed5ad75
--- /dev/null
+++ b/src/cmd/compile/internal/objw/objw.go
@@ -0,0 +1,85 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package objw
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/bitvec"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+)
+
+// Uint8 writes an unsigned byte v into s at offset off,
+// and returns the next unused offset (i.e., off+1).
+func Uint8(s *obj.LSym, off int, v uint8) int {
+	return UintN(s, off, uint64(v), 1)
+}
+
+func Uint16(s *obj.LSym, off int, v uint16) int {
+	return UintN(s, off, uint64(v), 2)
+}
+
+func Uint32(s *obj.LSym, off int, v uint32) int {
+	return UintN(s, off, uint64(v), 4)
+}
+
+func Uintptr(s *obj.LSym, off int, v uint64) int {
+	return UintN(s, off, v, types.PtrSize)
+}
+
+// UintN writes an unsigned integer v of size wid bytes into s at offset off,
+// and returns the next unused offset.
+func UintN(s *obj.LSym, off int, v uint64, wid int) int {
+	if off&(wid-1) != 0 {
+		base.Fatalf("duintxxLSym: misaligned: v=%d wid=%d off=%d", v, wid, off)
+	}
+	s.WriteInt(base.Ctxt, int64(off), wid, int64(v))
+	return off + wid
+}
+
+func SymPtr(s *obj.LSym, off int, x *obj.LSym, xoff int) int {
+	off = int(types.Rnd(int64(off), int64(types.PtrSize)))
+	s.WriteAddr(base.Ctxt, int64(off), types.PtrSize, x, int64(xoff))
+	off += types.PtrSize
+	return off
+}
+
+func SymPtrWeak(s *obj.LSym, off int, x *obj.LSym, xoff int) int {
+	off = int(types.Rnd(int64(off), int64(types.PtrSize)))
+	s.WriteWeakAddr(base.Ctxt, int64(off), types.PtrSize, x, int64(xoff))
+	off += types.PtrSize
+	return off
+}
+
+func SymPtrOff(s *obj.LSym, off int, x *obj.LSym) int {
+	s.WriteOff(base.Ctxt, int64(off), x, 0)
+	off += 4
+	return off
+}
+
+func SymPtrWeakOff(s *obj.LSym, off int, x *obj.LSym) int {
+	s.WriteWeakOff(base.Ctxt, int64(off), x, 0)
+	off += 4
+	return off
+}
+
+func Global(s *obj.LSym, width int32, flags int16) {
+	if flags&obj.LOCAL != 0 {
+		s.Set(obj.AttrLocal, true)
+		flags &^= obj.LOCAL
+	}
+	base.Ctxt.Globl(s, int64(width), int(flags))
+}
+
+// Bitvec writes the contents of bv into s as sequence of bytes
+// in little-endian order, and returns the next unused offset.
+func BitVec(s *obj.LSym, off int, bv bitvec.BitVec) int {
+	// Runtime reads the bitmaps as byte arrays. Oblige.
+	for j := 0; int32(j) < bv.N; j += 8 {
+		word := bv.B[j/32]
+		off = Uint8(s, off, uint8(word>>(uint(j)%32)))
+	}
+	return off
+}
diff --git a/src/cmd/compile/internal/objw/prog.go b/src/cmd/compile/internal/objw/prog.go
new file mode 100644
index 0000000..b5ac4dd
--- /dev/null
+++ b/src/cmd/compile/internal/objw/prog.go
@@ -0,0 +1,226 @@
+// Derived from Inferno utils/6c/txt.c
+// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6c/txt.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 objw
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/internal/obj"
+	"cmd/internal/objabi"
+	"cmd/internal/src"
+)
+
+var sharedProgArray = new([10000]obj.Prog) // *T instead of T to work around issue 19839
+
+// NewProgs returns a new Progs for fn.
+// worker indicates which of the backend workers will use the Progs.
+func NewProgs(fn *ir.Func, worker int) *Progs {
+	pp := new(Progs)
+	if base.Ctxt.CanReuseProgs() {
+		sz := len(sharedProgArray) / base.Flag.LowerC
+		pp.Cache = sharedProgArray[sz*worker : sz*(worker+1)]
+	}
+	pp.CurFunc = fn
+
+	// prime the pump
+	pp.Next = pp.NewProg()
+	pp.Clear(pp.Next)
+
+	pp.Pos = fn.Pos()
+	pp.SetText(fn)
+	// PCDATA tables implicitly start with index -1.
+	pp.PrevLive = LivenessIndex{-1, false}
+	pp.NextLive = pp.PrevLive
+	return pp
+}
+
+// Progs accumulates Progs for a function and converts them into machine code.
+type Progs struct {
+	Text       *obj.Prog  // ATEXT Prog for this function
+	Next       *obj.Prog  // next Prog
+	PC         int64      // virtual PC; count of Progs
+	Pos        src.XPos   // position to use for new Progs
+	CurFunc    *ir.Func   // fn these Progs are for
+	Cache      []obj.Prog // local progcache
+	CacheIndex int        // first free element of progcache
+
+	NextLive LivenessIndex // liveness index for the next Prog
+	PrevLive LivenessIndex // last emitted liveness index
+}
+
+// LivenessIndex stores the liveness map information for a Value.
+type LivenessIndex struct {
+	StackMapIndex int
+
+	// IsUnsafePoint indicates that this is an unsafe-point.
+	//
+	// Note that it's possible for a call Value to have a stack
+	// map while also being an unsafe-point. This means it cannot
+	// be preempted at this instruction, but that a preemption or
+	// stack growth may happen in the called function.
+	IsUnsafePoint bool
+}
+
+// StackMapDontCare indicates that the stack map index at a Value
+// doesn't matter.
+//
+// This is a sentinel value that should never be emitted to the PCDATA
+// stream. We use -1000 because that's obviously never a valid stack
+// index (but -1 is).
+const StackMapDontCare = -1000
+
+// LivenessDontCare indicates that the liveness information doesn't
+// matter. Currently it is used in deferreturn liveness when we don't
+// actually need it. It should never be emitted to the PCDATA stream.
+var LivenessDontCare = LivenessIndex{StackMapDontCare, true}
+
+func (idx LivenessIndex) StackMapValid() bool {
+	return idx.StackMapIndex != StackMapDontCare
+}
+
+func (pp *Progs) NewProg() *obj.Prog {
+	var p *obj.Prog
+	if pp.CacheIndex < len(pp.Cache) {
+		p = &pp.Cache[pp.CacheIndex]
+		pp.CacheIndex++
+	} else {
+		p = new(obj.Prog)
+	}
+	p.Ctxt = base.Ctxt
+	return p
+}
+
+// Flush converts from pp to machine code.
+func (pp *Progs) Flush() {
+	plist := &obj.Plist{Firstpc: pp.Text, Curfn: pp.CurFunc}
+	obj.Flushplist(base.Ctxt, plist, pp.NewProg, base.Ctxt.Pkgpath)
+}
+
+// Free clears pp and any associated resources.
+func (pp *Progs) Free() {
+	if base.Ctxt.CanReuseProgs() {
+		// Clear progs to enable GC and avoid abuse.
+		s := pp.Cache[:pp.CacheIndex]
+		for i := range s {
+			s[i] = obj.Prog{}
+		}
+	}
+	// Clear pp to avoid abuse.
+	*pp = Progs{}
+}
+
+// Prog adds a Prog with instruction As to pp.
+func (pp *Progs) Prog(as obj.As) *obj.Prog {
+	if pp.NextLive.StackMapValid() && pp.NextLive.StackMapIndex != pp.PrevLive.StackMapIndex {
+		// Emit stack map index change.
+		idx := pp.NextLive.StackMapIndex
+		pp.PrevLive.StackMapIndex = idx
+		p := pp.Prog(obj.APCDATA)
+		p.From.SetConst(objabi.PCDATA_StackMapIndex)
+		p.To.SetConst(int64(idx))
+	}
+	if pp.NextLive.IsUnsafePoint != pp.PrevLive.IsUnsafePoint {
+		// Emit unsafe-point marker.
+		pp.PrevLive.IsUnsafePoint = pp.NextLive.IsUnsafePoint
+		p := pp.Prog(obj.APCDATA)
+		p.From.SetConst(objabi.PCDATA_UnsafePoint)
+		if pp.NextLive.IsUnsafePoint {
+			p.To.SetConst(objabi.PCDATA_UnsafePointUnsafe)
+		} else {
+			p.To.SetConst(objabi.PCDATA_UnsafePointSafe)
+		}
+	}
+
+	p := pp.Next
+	pp.Next = pp.NewProg()
+	pp.Clear(pp.Next)
+	p.Link = pp.Next
+
+	if !pp.Pos.IsKnown() && base.Flag.K != 0 {
+		base.Warn("prog: unknown position (line 0)")
+	}
+
+	p.As = as
+	p.Pos = pp.Pos
+	if pp.Pos.IsStmt() == src.PosIsStmt {
+		// Clear IsStmt for later Progs at this pos provided that as can be marked as a stmt
+		if LosesStmtMark(as) {
+			return p
+		}
+		pp.Pos = pp.Pos.WithNotStmt()
+	}
+	return p
+}
+
+func (pp *Progs) Clear(p *obj.Prog) {
+	obj.Nopout(p)
+	p.As = obj.AEND
+	p.Pc = pp.PC
+	pp.PC++
+}
+
+func (pp *Progs) Append(p *obj.Prog, as obj.As, ftype obj.AddrType, freg int16, foffset int64, ttype obj.AddrType, treg int16, toffset int64) *obj.Prog {
+	q := pp.NewProg()
+	pp.Clear(q)
+	q.As = as
+	q.Pos = p.Pos
+	q.From.Type = ftype
+	q.From.Reg = freg
+	q.From.Offset = foffset
+	q.To.Type = ttype
+	q.To.Reg = treg
+	q.To.Offset = toffset
+	q.Link = p.Link
+	p.Link = q
+	return q
+}
+
+func (pp *Progs) SetText(fn *ir.Func) {
+	if pp.Text != nil {
+		base.Fatalf("Progs.SetText called twice")
+	}
+	ptxt := pp.Prog(obj.ATEXT)
+	pp.Text = ptxt
+
+	fn.LSym.Func().Text = ptxt
+	ptxt.From.Type = obj.TYPE_MEM
+	ptxt.From.Name = obj.NAME_EXTERN
+	ptxt.From.Sym = fn.LSym
+}
+
+// LosesStmtMark reports whether a prog with op as loses its statement mark on the way to DWARF.
+// The attributes from some opcodes are lost in translation.
+// TODO: this is an artifact of how funcpctab combines information for instructions at a single PC.
+// Should try to fix it there.
+func LosesStmtMark(as obj.As) bool {
+	// is_stmt does not work for these; it DOES for ANOP even though that generates no code.
+	return as == obj.APCDATA || as == obj.AFUNCDATA
+}
diff --git a/src/cmd/compile/internal/pkginit/init.go b/src/cmd/compile/internal/pkginit/init.go
new file mode 100644
index 0000000..7cad262
--- /dev/null
+++ b/src/cmd/compile/internal/pkginit/init.go
@@ -0,0 +1,109 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkginit
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/deadcode"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+)
+
+// Task makes and returns an initialization record for the package.
+// See runtime/proc.go:initTask for its layout.
+// The 3 tasks for initialization are:
+//   1) Initialize all of the packages the current package depends on.
+//   2) Initialize all the variables that have initializers.
+//   3) Run any init functions.
+func Task() *ir.Name {
+	nf := initOrder(typecheck.Target.Decls)
+
+	var deps []*obj.LSym // initTask records for packages the current package depends on
+	var fns []*obj.LSym  // functions to call for package initialization
+
+	// Find imported packages with init tasks.
+	for _, pkg := range typecheck.Target.Imports {
+		n := typecheck.Resolve(ir.NewIdent(base.Pos, pkg.Lookup(".inittask")))
+		if n.Op() == ir.ONONAME {
+			continue
+		}
+		if n.Op() != ir.ONAME || n.(*ir.Name).Class != ir.PEXTERN {
+			base.Fatalf("bad inittask: %v", n)
+		}
+		deps = append(deps, n.(*ir.Name).Linksym())
+	}
+
+	// Make a function that contains all the initialization statements.
+	if len(nf) > 0 {
+		base.Pos = nf[0].Pos() // prolog/epilog gets line number of first init stmt
+		initializers := typecheck.Lookup("init")
+		fn := typecheck.DeclFunc(initializers, ir.NewFuncType(base.Pos, nil, nil, nil))
+		for _, dcl := range typecheck.InitTodoFunc.Dcl {
+			dcl.Curfn = fn
+		}
+		fn.Dcl = append(fn.Dcl, typecheck.InitTodoFunc.Dcl...)
+		typecheck.InitTodoFunc.Dcl = nil
+
+		fn.Body = nf
+		typecheck.FinishFuncBody()
+
+		typecheck.Func(fn)
+		ir.CurFunc = fn
+		typecheck.Stmts(nf)
+		ir.CurFunc = nil
+		typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
+		fns = append(fns, fn.Linksym())
+	}
+	if typecheck.InitTodoFunc.Dcl != nil {
+		// We only generate temps using InitTodoFunc if there
+		// are package-scope initialization statements, so
+		// something's weird if we get here.
+		base.Fatalf("InitTodoFunc still has declarations")
+	}
+	typecheck.InitTodoFunc = nil
+
+	// Record user init functions.
+	for _, fn := range typecheck.Target.Inits {
+		// Must happen after initOrder; see #43444.
+		deadcode.Func(fn)
+
+		// Skip init functions with empty bodies.
+		if len(fn.Body) == 1 {
+			if stmt := fn.Body[0]; stmt.Op() == ir.OBLOCK && len(stmt.(*ir.BlockStmt).List) == 0 {
+				continue
+			}
+		}
+		fns = append(fns, fn.Nname.Linksym())
+	}
+
+	if len(deps) == 0 && len(fns) == 0 && types.LocalPkg.Name != "main" && types.LocalPkg.Name != "runtime" {
+		return nil // nothing to initialize
+	}
+
+	// Make an .inittask structure.
+	sym := typecheck.Lookup(".inittask")
+	task := typecheck.NewName(sym)
+	task.SetType(types.Types[types.TUINT8]) // fake type
+	task.Class = ir.PEXTERN
+	sym.Def = task
+	lsym := task.Linksym()
+	ot := 0
+	ot = objw.Uintptr(lsym, ot, 0) // state: not initialized yet
+	ot = objw.Uintptr(lsym, ot, uint64(len(deps)))
+	ot = objw.Uintptr(lsym, ot, uint64(len(fns)))
+	for _, d := range deps {
+		ot = objw.SymPtr(lsym, ot, d, 0)
+	}
+	for _, f := range fns {
+		ot = objw.SymPtr(lsym, ot, f, 0)
+	}
+	// An initTask has pointers, but none into the Go heap.
+	// It's not quite read only, the state field must be modifiable.
+	objw.Global(lsym, int32(ot), obj.NOPTR)
+	return task
+}
diff --git a/src/cmd/compile/internal/pkginit/initorder.go b/src/cmd/compile/internal/pkginit/initorder.go
new file mode 100644
index 0000000..97d6962
--- /dev/null
+++ b/src/cmd/compile/internal/pkginit/initorder.go
@@ -0,0 +1,372 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkginit
+
+import (
+	"bytes"
+	"container/heap"
+	"fmt"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/staticinit"
+)
+
+// Package initialization
+//
+// Here we implement the algorithm for ordering package-level variable
+// initialization. The spec is written in terms of variable
+// initialization, but multiple variables initialized by a single
+// assignment are handled together, so here we instead focus on
+// ordering initialization assignments. Conveniently, this maps well
+// to how we represent package-level initializations using the Node
+// AST.
+//
+// Assignments are in one of three phases: NotStarted, Pending, or
+// Done. For assignments in the Pending phase, we use Xoffset to
+// record the number of unique variable dependencies whose
+// initialization assignment is not yet Done. We also maintain a
+// "blocking" map that maps assignments back to all of the assignments
+// that depend on it.
+//
+// For example, for an initialization like:
+//
+//     var x = f(a, b, b)
+//     var a, b = g()
+//
+// the "x = f(a, b, b)" assignment depends on two variables (a and b),
+// so its Xoffset will be 2. Correspondingly, the "a, b = g()"
+// assignment's "blocking" entry will have two entries back to x's
+// assignment.
+//
+// Logically, initialization works by (1) taking all NotStarted
+// assignments, calculating their dependencies, and marking them
+// Pending; (2) adding all Pending assignments with Xoffset==0 to a
+// "ready" priority queue (ordered by variable declaration position);
+// and (3) iteratively processing the next Pending assignment from the
+// queue, decreasing the Xoffset of assignments it's blocking, and
+// adding them to the queue if decremented to 0.
+//
+// As an optimization, we actually apply each of these three steps for
+// each assignment. This yields the same order, but keeps queue size
+// down and thus also heap operation costs.
+
+// Static initialization phase.
+// These values are stored in two bits in Node.flags.
+const (
+	InitNotStarted = iota
+	InitDone
+	InitPending
+)
+
+type InitOrder struct {
+	// blocking maps initialization assignments to the assignments
+	// that depend on it.
+	blocking map[ir.Node][]ir.Node
+
+	// ready is the queue of Pending initialization assignments
+	// that are ready for initialization.
+	ready declOrder
+
+	order map[ir.Node]int
+}
+
+// initOrder computes initialization order for a list l of
+// package-level declarations (in declaration order) and outputs the
+// corresponding list of statements to include in the init() function
+// body.
+func initOrder(l []ir.Node) []ir.Node {
+	s := staticinit.Schedule{
+		Plans: make(map[ir.Node]*staticinit.Plan),
+		Temps: make(map[ir.Node]*ir.Name),
+	}
+	o := InitOrder{
+		blocking: make(map[ir.Node][]ir.Node),
+		order:    make(map[ir.Node]int),
+	}
+
+	// Process all package-level assignment in declaration order.
+	for _, n := range l {
+		switch n.Op() {
+		case ir.OAS, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
+			o.processAssign(n)
+			o.flushReady(s.StaticInit)
+		case ir.ODCLCONST, ir.ODCLFUNC, ir.ODCLTYPE:
+			// nop
+		default:
+			base.Fatalf("unexpected package-level statement: %v", n)
+		}
+	}
+
+	// Check that all assignments are now Done; if not, there must
+	// have been a dependency cycle.
+	for _, n := range l {
+		switch n.Op() {
+		case ir.OAS, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
+			if o.order[n] != orderDone {
+				// If there have already been errors
+				// printed, those errors may have
+				// confused us and there might not be
+				// a loop. Let the user fix those
+				// first.
+				base.ExitIfErrors()
+
+				o.findInitLoopAndExit(firstLHS(n), new([]*ir.Name), new(ir.NameSet))
+				base.Fatalf("initialization unfinished, but failed to identify loop")
+			}
+		}
+	}
+
+	// Invariant consistency check. If this is non-zero, then we
+	// should have found a cycle above.
+	if len(o.blocking) != 0 {
+		base.Fatalf("expected empty map: %v", o.blocking)
+	}
+
+	return s.Out
+}
+
+func (o *InitOrder) processAssign(n ir.Node) {
+	if _, ok := o.order[n]; ok {
+		base.Fatalf("unexpected state: %v, %v", n, o.order[n])
+	}
+	o.order[n] = 0
+
+	// Compute number of variable dependencies and build the
+	// inverse dependency ("blocking") graph.
+	for dep := range collectDeps(n, true) {
+		defn := dep.Defn
+		// Skip dependencies on functions (PFUNC) and
+		// variables already initialized (InitDone).
+		if dep.Class != ir.PEXTERN || o.order[defn] == orderDone {
+			continue
+		}
+		o.order[n]++
+		o.blocking[defn] = append(o.blocking[defn], n)
+	}
+
+	if o.order[n] == 0 {
+		heap.Push(&o.ready, n)
+	}
+}
+
+const orderDone = -1000
+
+// flushReady repeatedly applies initialize to the earliest (in
+// declaration order) assignment ready for initialization and updates
+// the inverse dependency ("blocking") graph.
+func (o *InitOrder) flushReady(initialize func(ir.Node)) {
+	for o.ready.Len() != 0 {
+		n := heap.Pop(&o.ready).(ir.Node)
+		if order, ok := o.order[n]; !ok || order != 0 {
+			base.Fatalf("unexpected state: %v, %v, %v", n, ok, order)
+		}
+
+		initialize(n)
+		o.order[n] = orderDone
+
+		blocked := o.blocking[n]
+		delete(o.blocking, n)
+
+		for _, m := range blocked {
+			if o.order[m]--; o.order[m] == 0 {
+				heap.Push(&o.ready, m)
+			}
+		}
+	}
+}
+
+// findInitLoopAndExit searches for an initialization loop involving variable
+// or function n. If one is found, it reports the loop as an error and exits.
+//
+// path points to a slice used for tracking the sequence of
+// variables/functions visited. Using a pointer to a slice allows the
+// slice capacity to grow and limit reallocations.
+func (o *InitOrder) findInitLoopAndExit(n *ir.Name, path *[]*ir.Name, ok *ir.NameSet) {
+	for i, x := range *path {
+		if x == n {
+			reportInitLoopAndExit((*path)[i:])
+			return
+		}
+	}
+
+	// There might be multiple loops involving n; by sorting
+	// references, we deterministically pick the one reported.
+	refers := collectDeps(n.Defn, false).Sorted(func(ni, nj *ir.Name) bool {
+		return ni.Pos().Before(nj.Pos())
+	})
+
+	*path = append(*path, n)
+	for _, ref := range refers {
+		// Short-circuit variables that were initialized.
+		if ref.Class == ir.PEXTERN && o.order[ref.Defn] == orderDone || ok.Has(ref) {
+			continue
+		}
+
+		o.findInitLoopAndExit(ref, path, ok)
+	}
+
+	// n is not involved in a cycle.
+	// Record that fact to avoid checking it again when reached another way,
+	// or else this traversal will take exponential time traversing all paths
+	// through the part of the package's call graph implicated in the cycle.
+	ok.Add(n)
+
+	*path = (*path)[:len(*path)-1]
+}
+
+// reportInitLoopAndExit reports and initialization loop as an error
+// and exits. However, if l is not actually an initialization loop, it
+// simply returns instead.
+func reportInitLoopAndExit(l []*ir.Name) {
+	// Rotate loop so that the earliest variable declaration is at
+	// the start.
+	i := -1
+	for j, n := range l {
+		if n.Class == ir.PEXTERN && (i == -1 || n.Pos().Before(l[i].Pos())) {
+			i = j
+		}
+	}
+	if i == -1 {
+		// False positive: loop only involves recursive
+		// functions. Return so that findInitLoop can continue
+		// searching.
+		return
+	}
+	l = append(l[i:], l[:i]...)
+
+	// TODO(mdempsky): Method values are printed as "T.m-fm"
+	// rather than "T.m". Figure out how to avoid that.
+
+	var msg bytes.Buffer
+	fmt.Fprintf(&msg, "initialization loop:\n")
+	for _, n := range l {
+		fmt.Fprintf(&msg, "\t%v: %v refers to\n", ir.Line(n), n)
+	}
+	fmt.Fprintf(&msg, "\t%v: %v", ir.Line(l[0]), l[0])
+
+	base.ErrorfAt(l[0].Pos(), msg.String())
+	base.ErrorExit()
+}
+
+// collectDeps returns all of the package-level functions and
+// variables that declaration n depends on. If transitive is true,
+// then it also includes the transitive dependencies of any depended
+// upon functions (but not variables).
+func collectDeps(n ir.Node, transitive bool) ir.NameSet {
+	d := initDeps{transitive: transitive}
+	switch n.Op() {
+	case ir.OAS:
+		n := n.(*ir.AssignStmt)
+		d.inspect(n.Y)
+	case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
+		n := n.(*ir.AssignListStmt)
+		d.inspect(n.Rhs[0])
+	case ir.ODCLFUNC:
+		n := n.(*ir.Func)
+		d.inspectList(n.Body)
+	default:
+		base.Fatalf("unexpected Op: %v", n.Op())
+	}
+	return d.seen
+}
+
+type initDeps struct {
+	transitive bool
+	seen       ir.NameSet
+	cvisit     func(ir.Node)
+}
+
+func (d *initDeps) cachedVisit() func(ir.Node) {
+	if d.cvisit == nil {
+		d.cvisit = d.visit // cache closure
+	}
+	return d.cvisit
+}
+
+func (d *initDeps) inspect(n ir.Node)      { ir.Visit(n, d.cachedVisit()) }
+func (d *initDeps) inspectList(l ir.Nodes) { ir.VisitList(l, d.cachedVisit()) }
+
+// visit calls foundDep on any package-level functions or variables
+// referenced by n, if any.
+func (d *initDeps) visit(n ir.Node) {
+	switch n.Op() {
+	case ir.ONAME:
+		n := n.(*ir.Name)
+		switch n.Class {
+		case ir.PEXTERN, ir.PFUNC:
+			d.foundDep(n)
+		}
+
+	case ir.OCLOSURE:
+		n := n.(*ir.ClosureExpr)
+		d.inspectList(n.Func.Body)
+
+	case ir.ODOTMETH, ir.OCALLPART, ir.OMETHEXPR:
+		d.foundDep(ir.MethodExprName(n))
+	}
+}
+
+// foundDep records that we've found a dependency on n by adding it to
+// seen.
+func (d *initDeps) foundDep(n *ir.Name) {
+	// Can happen with method expressions involving interface
+	// types; e.g., fixedbugs/issue4495.go.
+	if n == nil {
+		return
+	}
+
+	// Names without definitions aren't interesting as far as
+	// initialization ordering goes.
+	if n.Defn == nil {
+		return
+	}
+
+	if d.seen.Has(n) {
+		return
+	}
+	d.seen.Add(n)
+	if d.transitive && n.Class == ir.PFUNC {
+		d.inspectList(n.Defn.(*ir.Func).Body)
+	}
+}
+
+// declOrder implements heap.Interface, ordering assignment statements
+// by the position of their first LHS expression.
+//
+// N.B., the Pos of the first LHS expression is used because because
+// an OAS node's Pos may not be unique. For example, given the
+// declaration "var a, b = f(), g()", "a" must be ordered before "b",
+// but both OAS nodes use the "=" token's position as their Pos.
+type declOrder []ir.Node
+
+func (s declOrder) Len() int { return len(s) }
+func (s declOrder) Less(i, j int) bool {
+	return firstLHS(s[i]).Pos().Before(firstLHS(s[j]).Pos())
+}
+func (s declOrder) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+func (s *declOrder) Push(x interface{}) { *s = append(*s, x.(ir.Node)) }
+func (s *declOrder) Pop() interface{} {
+	n := (*s)[len(*s)-1]
+	*s = (*s)[:len(*s)-1]
+	return n
+}
+
+// firstLHS returns the first expression on the left-hand side of
+// assignment n.
+func firstLHS(n ir.Node) *ir.Name {
+	switch n.Op() {
+	case ir.OAS:
+		n := n.(*ir.AssignStmt)
+		return n.X.Name()
+	case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2RECV, ir.OAS2MAPR:
+		n := n.(*ir.AssignListStmt)
+		return n.Lhs[0].Name()
+	}
+
+	base.Fatalf("unexpected Op: %v", n.Op())
+	return nil
+}
diff --git a/src/cmd/compile/internal/ppc64/galign.go b/src/cmd/compile/internal/ppc64/galign.go
index c8ef567..590290f 100644
--- a/src/cmd/compile/internal/ppc64/galign.go
+++ b/src/cmd/compile/internal/ppc64/galign.go
@@ -5,14 +5,14 @@
 package ppc64
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/ssagen"
 	"cmd/internal/obj/ppc64"
-	"cmd/internal/objabi"
+	"internal/buildcfg"
 )
 
-func Init(arch *gc.Arch) {
+func Init(arch *ssagen.ArchInfo) {
 	arch.LinkArch = &ppc64.Linkppc64
-	if objabi.GOARCH == "ppc64le" {
+	if buildcfg.GOARCH == "ppc64le" {
 		arch.LinkArch = &ppc64.Linkppc64le
 	}
 	arch.REGSP = ppc64.REGSP
diff --git a/src/cmd/compile/internal/ppc64/ggen.go b/src/cmd/compile/internal/ppc64/ggen.go
index a5a772b..c76962c 100644
--- a/src/cmd/compile/internal/ppc64/ggen.go
+++ b/src/cmd/compile/internal/ppc64/ggen.go
@@ -5,44 +5,47 @@
 package ppc64
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/ppc64"
 )
 
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
 	if cnt == 0 {
 		return p
 	}
-	if cnt < int64(4*gc.Widthptr) {
-		for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
-			p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, gc.Ctxt.FixedFrameSize()+off+i)
+	if cnt < int64(4*types.PtrSize) {
+		for i := int64(0); i < cnt; i += int64(types.PtrSize) {
+			p = pp.Append(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, base.Ctxt.FixedFrameSize()+off+i)
 		}
-	} else if cnt <= int64(128*gc.Widthptr) {
-		p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGRT1, 0)
+	} else if cnt <= int64(128*types.PtrSize) {
+		p = pp.Append(p, ppc64.AADD, obj.TYPE_CONST, 0, base.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGRT1, 0)
 		p.Reg = ppc64.REGSP
-		p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
+		p = pp.Append(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.Sym = ir.Syms.Duffzero
+		p.To.Offset = 4 * (128 - cnt/int64(types.PtrSize))
 	} else {
-		p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGTMP, 0)
-		p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT1, 0)
+		p = pp.Append(p, ppc64.AMOVD, obj.TYPE_CONST, 0, base.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGTMP, 0)
+		p = pp.Append(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT1, 0)
 		p.Reg = ppc64.REGSP
-		p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, ppc64.REGTMP, 0)
-		p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT2, 0)
+		p = pp.Append(p, ppc64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, ppc64.REGTMP, 0)
+		p = pp.Append(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT2, 0)
 		p.Reg = ppc64.REGRT1
-		p = pp.Appendpp(p, ppc64.AMOVDU, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGRT1, int64(gc.Widthptr))
+		p = pp.Append(p, ppc64.AMOVDU, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGRT1, int64(types.PtrSize))
 		p1 := p
-		p = pp.Appendpp(p, ppc64.ACMP, obj.TYPE_REG, ppc64.REGRT1, 0, obj.TYPE_REG, ppc64.REGRT2, 0)
-		p = pp.Appendpp(p, ppc64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
-		gc.Patch(p, p1)
+		p = pp.Append(p, ppc64.ACMP, obj.TYPE_REG, ppc64.REGRT1, 0, obj.TYPE_REG, ppc64.REGRT2, 0)
+		p = pp.Append(p, ppc64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
+		p.To.SetTarget(p1)
 	}
 
 	return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
 	p := pp.Prog(ppc64.AOR)
 	p.From.Type = obj.TYPE_REG
 	p.From.Reg = ppc64.REG_R0
@@ -51,7 +54,7 @@
 	return p
 }
 
-func ginsnopdefer(pp *gc.Progs) *obj.Prog {
+func ginsnopdefer(pp *objw.Progs) *obj.Prog {
 	// On PPC64 two nops are required in the defer case.
 	//
 	// (see gc/cgen.go, gc/plive.go -- copy of comment below)
@@ -66,7 +69,7 @@
 	// on ppc64 in both shared and non-shared modes.
 
 	ginsnop(pp)
-	if gc.Ctxt.Flag_shared {
+	if base.Ctxt.Flag_shared {
 		p := pp.Prog(ppc64.AMOVD)
 		p.From.Type = obj.TYPE_MEM
 		p.From.Offset = 24
diff --git a/src/cmd/compile/internal/ppc64/ssa.go b/src/cmd/compile/internal/ppc64/ssa.go
index 3e20c44..11226f6 100644
--- a/src/cmd/compile/internal/ppc64/ssa.go
+++ b/src/cmd/compile/internal/ppc64/ssa.go
@@ -5,19 +5,21 @@
 package ppc64
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/logopt"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/ppc64"
-	"cmd/internal/objabi"
+	"internal/buildcfg"
 	"math"
 	"strings"
 )
 
 // markMoves marks any MOVXconst ops that need to avoid clobbering flags.
-func ssaMarkMoves(s *gc.SSAGenState, b *ssa.Block) {
+func ssaMarkMoves(s *ssagen.State, b *ssa.Block) {
 	//	flive := b.FlagsLiveAtEnd
 	//	if b.Control != nil && b.Control.Type.IsFlags() {
 	//		flive = true
@@ -99,7 +101,7 @@
 	panic("bad store type")
 }
 
-func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
+func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 	switch v.Op {
 	case ssa.OpCopy:
 		t := v.Type
@@ -208,7 +210,7 @@
 		// BNE retry
 		p3 := s.Prog(ppc64.ABNE)
 		p3.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 
 	case ssa.OpPPC64LoweredAtomicAdd32,
 		ssa.OpPPC64LoweredAtomicAdd64:
@@ -252,7 +254,7 @@
 		// BNE retry
 		p4 := s.Prog(ppc64.ABNE)
 		p4.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p4, p)
+		p4.To.SetTarget(p)
 
 		// Ensure a 32 bit result
 		if v.Op == ssa.OpPPC64LoweredAtomicAdd32 {
@@ -298,7 +300,7 @@
 		// BNE retry
 		p2 := s.Prog(ppc64.ABNE)
 		p2.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p2, p)
+		p2.To.SetTarget(p)
 		// ISYNC
 		pisync := s.Prog(ppc64.AISYNC)
 		pisync.To.Type = obj.TYPE_NONE
@@ -346,7 +348,7 @@
 		// ISYNC
 		pisync := s.Prog(ppc64.AISYNC)
 		pisync.To.Type = obj.TYPE_NONE
-		gc.Patch(p2, pisync)
+		p2.To.SetTarget(pisync)
 
 	case ssa.OpPPC64LoweredAtomicStore8,
 		ssa.OpPPC64LoweredAtomicStore32,
@@ -417,7 +419,7 @@
 		// If it is a Compare-and-Swap-Release operation, set the EH field with
 		// the release hint.
 		if v.AuxInt == 0 {
-			p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: 0})
+			p.SetFrom3Const(0)
 		}
 		// CMP reg1,reg2
 		p1 := s.Prog(cmp)
@@ -437,7 +439,7 @@
 		// BNE retry
 		p4 := s.Prog(ppc64.ABNE)
 		p4.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p4, p)
+		p4.To.SetTarget(p)
 		// LWSYNC - Assuming shared data not write-through-required nor
 		// caching-inhibited. See Appendix B.2.1.1 in the ISA 2.07b.
 		// If the operation is a CAS-Release, then synchronization is not necessary.
@@ -460,20 +462,20 @@
 		p7.From.Offset = 0
 		p7.To.Type = obj.TYPE_REG
 		p7.To.Reg = out
-		gc.Patch(p2, p7)
+		p2.To.SetTarget(p7)
 		// done (label)
 		p8 := s.Prog(obj.ANOP)
-		gc.Patch(p6, p8)
+		p6.To.SetTarget(p8)
 
 	case ssa.OpPPC64LoweredGetClosurePtr:
 		// Closure pointer is R11 (already)
-		gc.CheckLoweredGetClosurePtr(v)
+		ssagen.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.Offset = -base.Ctxt.FixedFrameSize()
 		p.From.Name = obj.NAME_PARAM
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
@@ -489,7 +491,7 @@
 	case ssa.OpLoadReg:
 		loadOp := loadByType(v.Type)
 		p := s.Prog(loadOp)
-		gc.AddrAuto(&p.From, v.Args[0])
+		ssagen.AddrAuto(&p.From, v.Args[0])
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 
@@ -498,7 +500,7 @@
 		p := s.Prog(storeOp)
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddrAuto(&p.To, v)
+		ssagen.AddrAuto(&p.To, v)
 
 	case ssa.OpPPC64DIVD:
 		// For now,
@@ -537,10 +539,10 @@
 		p.To.Reg = r
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = r0
-		gc.Patch(pbahead, p)
+		pbahead.To.SetTarget(p)
 
 		p = s.Prog(obj.ANOP)
-		gc.Patch(pbover, p)
+		pbover.To.SetTarget(p)
 
 	case ssa.OpPPC64DIVW:
 		// word-width version of above
@@ -572,10 +574,10 @@
 		p.To.Reg = r
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = r0
-		gc.Patch(pbahead, p)
+		pbahead.To.SetTarget(p)
 
 		p = s.Prog(obj.ANOP)
-		gc.Patch(pbover, p)
+		pbover.To.SetTarget(p)
 
 	case ssa.OpPPC64CLRLSLWI:
 		r := v.Reg()
@@ -584,7 +586,7 @@
 		p := s.Prog(v.Op.Asm())
 		// clrlslwi ra,rs,mb,sh will become rlwinm ra,rs,sh,mb-sh,31-sh as described in ISA
 		p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftmb(shifts)}
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftsh(shifts)})
+		p.SetFrom3Const(ssa.GetPPC64Shiftsh(shifts))
 		p.Reg = r1
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
@@ -596,7 +598,7 @@
 		p := s.Prog(v.Op.Asm())
 		// clrlsldi ra,rs,mb,sh will become rldic ra,rs,sh,mb-sh
 		p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftmb(shifts)}
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftsh(shifts)})
+		p.SetFrom3Const(ssa.GetPPC64Shiftsh(shifts))
 		p.Reg = r1
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
@@ -608,7 +610,7 @@
 		shifts := v.AuxInt
 		p := s.Prog(v.Op.Asm())
 		p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftsh(shifts)}
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftmb(shifts)})
+		p.SetFrom3Const(ssa.GetPPC64Shiftmb(shifts))
 		p.Reg = r1
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
@@ -651,21 +653,21 @@
 
 		// Auxint holds encoded rotate + mask
 	case ssa.OpPPC64RLWINM, ssa.OpPPC64RLWMI:
-		rot, _, _, mask := ssa.DecodePPC64RotateMask(v.AuxInt)
+		rot, mb, me, _ := ssa.DecodePPC64RotateMask(v.AuxInt)
 		p := s.Prog(v.Op.Asm())
 		p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
 		p.Reg = v.Args[0].Reg()
 		p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(rot)}
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: int64(mask)})
+		p.SetRestArgs([]obj.Addr{{Type: obj.TYPE_CONST, Offset: mb}, {Type: obj.TYPE_CONST, Offset: me}})
 
 		// Auxint holds mask
 	case ssa.OpPPC64RLWNM:
-		_, _, _, mask := ssa.DecodePPC64RotateMask(v.AuxInt)
+		_, mb, me, _ := ssa.DecodePPC64RotateMask(v.AuxInt)
 		p := s.Prog(v.Op.Asm())
 		p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
 		p.Reg = v.Args[0].Reg()
 		p.From = obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[1].Reg()}
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: int64(mask)})
+		p.SetRestArgs([]obj.Addr{{Type: obj.TYPE_CONST, Offset: mb}, {Type: obj.TYPE_CONST, Offset: me}})
 
 	case ssa.OpPPC64MADDLD:
 		r := v.Reg()
@@ -677,7 +679,7 @@
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = r1
 		p.Reg = r2
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: r3})
+		p.SetFrom3Reg(r3)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
 
@@ -691,7 +693,7 @@
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = r1
 		p.Reg = r3
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: r2})
+		p.SetFrom3Reg(r2)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
 
@@ -718,7 +720,7 @@
 
 	case ssa.OpPPC64SUBFCconst:
 		p := s.Prog(v.Op.Asm())
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: v.AuxInt})
+		p.SetFrom3Const(v.AuxInt)
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
 		p.To.Type = obj.TYPE_REG
@@ -750,13 +752,13 @@
 				p.To.Reg = v.Reg()
 			}
 
-		case *obj.LSym, *gc.Node:
+		case *obj.LSym, ir.Node:
 			p := s.Prog(ppc64.AMOVD)
 			p.From.Type = obj.TYPE_ADDR
 			p.From.Reg = v.Args[0].Reg()
 			p.To.Type = obj.TYPE_REG
 			p.To.Reg = v.Reg()
-			gc.AddAux(&p.From, v)
+			ssagen.AddAux(&p.From, v)
 
 		}
 
@@ -796,46 +798,67 @@
 		p.To.Reg = v.Reg()
 		p.To.Type = obj.TYPE_REG
 
-	case ssa.OpPPC64MOVDload:
+	case ssa.OpPPC64MOVDload, ssa.OpPPC64MOVWload:
 
-		// MOVDload uses a DS instruction which requires the offset value of the data to be a multiple of 4.
-		// For offsets known at compile time, a MOVDload won't be selected, but in the case of a go.string,
-		// the offset is not known until link time. If the load of a go.string uses relocation for the
-		// offset field of the instruction, and if the offset is not aligned to 4, then a link error will occur.
-		// To avoid this problem, the full address of the go.string is computed and loaded into the base register,
-		// and that base register is used for the MOVDload using a 0 offset. This problem can only occur with
-		// go.string types because other types will have proper alignment.
+		// MOVDload and MOVWload are DS form instructions that are restricted to
+		// offsets that are a multiple of 4. If the offset is not a multple of 4,
+		// then the address of the symbol to be loaded is computed (base + offset)
+		// and used as the new base register and the offset field in the instruction
+		// can be set to zero.
 
-		gostring := false
-		switch n := v.Aux.(type) {
-		case *obj.LSym:
-			gostring = strings.HasPrefix(n.Name, "go.string.")
+		// This same problem can happen with gostrings since the final offset is not
+		// known yet, but could be unaligned after the relocation is resolved.
+		// So gostrings are handled the same way.
+
+		// This allows the MOVDload and MOVWload to be generated in more cases and
+		// eliminates some offset and alignment checking in the rules file.
+
+		fromAddr := obj.Addr{Type: obj.TYPE_MEM, Reg: v.Args[0].Reg()}
+		ssagen.AddAux(&fromAddr, v)
+
+		genAddr := false
+
+		switch fromAddr.Name {
+		case obj.NAME_EXTERN, obj.NAME_STATIC:
+			// Special case for a rule combines the bytes of gostring.
+			// The v alignment might seem OK, but we don't want to load it
+			// using an offset because relocation comes later.
+			genAddr = strings.HasPrefix(fromAddr.Sym.Name, "go.string") || v.Type.Alignment()%4 != 0 || fromAddr.Offset%4 != 0
+		default:
+			genAddr = fromAddr.Offset%4 != 0
 		}
-		if gostring {
-			// Generate full addr of the go.string const
-			// including AuxInt
+		if genAddr {
+			// Load full address into the temp register.
 			p := s.Prog(ppc64.AMOVD)
 			p.From.Type = obj.TYPE_ADDR
 			p.From.Reg = v.Args[0].Reg()
-			gc.AddAux(&p.From, v)
+			ssagen.AddAux(&p.From, v)
+			// Load target using temp as base register
+			// and offset zero. Setting NAME_NONE
+			// prevents any extra offsets from being
+			// added.
 			p.To.Type = obj.TYPE_REG
-			p.To.Reg = v.Reg()
-			// Load go.string using 0 offset
-			p = s.Prog(v.Op.Asm())
-			p.From.Type = obj.TYPE_MEM
-			p.From.Reg = v.Reg()
-			p.To.Type = obj.TYPE_REG
-			p.To.Reg = v.Reg()
-			break
+			p.To.Reg = ppc64.REGTMP
+			fromAddr.Reg = ppc64.REGTMP
+			// Clear the offset field and other
+			// information that might be used
+			// by the assembler to add to the
+			// final offset value.
+			fromAddr.Offset = 0
+			fromAddr.Name = obj.NAME_NONE
+			fromAddr.Sym = nil
 		}
-		// Not a go.string, generate a normal load
-		fallthrough
+		p := s.Prog(v.Op.Asm())
+		p.From = fromAddr
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
+		break
 
-	case ssa.OpPPC64MOVWload, ssa.OpPPC64MOVHload, ssa.OpPPC64MOVWZload, ssa.OpPPC64MOVBZload, ssa.OpPPC64MOVHZload, ssa.OpPPC64FMOVDload, ssa.OpPPC64FMOVSload:
+	case ssa.OpPPC64MOVHload, ssa.OpPPC64MOVWZload, ssa.OpPPC64MOVBZload, ssa.OpPPC64MOVHZload, ssa.OpPPC64FMOVDload, ssa.OpPPC64FMOVSload:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 
@@ -863,21 +886,60 @@
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 
-	case ssa.OpPPC64MOVDstorezero, ssa.OpPPC64MOVWstorezero, ssa.OpPPC64MOVHstorezero, ssa.OpPPC64MOVBstorezero:
+	case ssa.OpPPC64MOVWstorezero, ssa.OpPPC64MOVHstorezero, ssa.OpPPC64MOVBstorezero:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = ppc64.REGZERO
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 
-	case ssa.OpPPC64MOVDstore, ssa.OpPPC64MOVWstore, ssa.OpPPC64MOVHstore, ssa.OpPPC64MOVBstore, ssa.OpPPC64FMOVDstore, ssa.OpPPC64FMOVSstore:
+	case ssa.OpPPC64MOVDstore, ssa.OpPPC64MOVDstorezero:
+
+		// MOVDstore and MOVDstorezero become DS form instructions that are restricted
+		// to offset values that are a multple of 4. If the offset field is not a
+		// multiple of 4, then the full address of the store target is computed (base +
+		// offset) and used as the new base register and the offset in the instruction
+		// is set to 0.
+
+		// This allows the MOVDstore and MOVDstorezero to be generated in more cases,
+		// and prevents checking of the offset value and alignment in the rules.
+
+		toAddr := obj.Addr{Type: obj.TYPE_MEM, Reg: v.Args[0].Reg()}
+		ssagen.AddAux(&toAddr, v)
+
+		if toAddr.Offset%4 != 0 {
+			p := s.Prog(ppc64.AMOVD)
+			p.From.Type = obj.TYPE_ADDR
+			p.From.Reg = v.Args[0].Reg()
+			ssagen.AddAux(&p.From, v)
+			p.To.Type = obj.TYPE_REG
+			p.To.Reg = ppc64.REGTMP
+			toAddr.Reg = ppc64.REGTMP
+			// Clear the offset field and other
+			// information that might be used
+			// by the assembler to add to the
+			// final offset value.
+			toAddr.Offset = 0
+			toAddr.Name = obj.NAME_NONE
+			toAddr.Sym = nil
+		}
+		p := s.Prog(v.Op.Asm())
+		p.To = toAddr
+		p.From.Type = obj.TYPE_REG
+		if v.Op == ssa.OpPPC64MOVDstorezero {
+			p.From.Reg = ppc64.REGZERO
+		} else {
+			p.From.Reg = v.Args[1].Reg()
+		}
+
+	case ssa.OpPPC64MOVWstore, ssa.OpPPC64MOVHstore, ssa.OpPPC64MOVBstore, ssa.OpPPC64FMOVDstore, ssa.OpPPC64FMOVSstore:
 		p := s.Prog(v.Op.Asm())
 		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()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 
 	case ssa.OpPPC64MOVDstoreidx, ssa.OpPPC64MOVWstoreidx, ssa.OpPPC64MOVHstoreidx, ssa.OpPPC64MOVBstoreidx,
 		ssa.OpPPC64FMOVDstoreidx, ssa.OpPPC64FMOVSstoreidx, ssa.OpPPC64MOVDBRstoreidx, ssa.OpPPC64MOVWBRstoreidx,
@@ -908,7 +970,7 @@
 		// AuxInt values 4,5,6 implemented with reverse operand order from 0,1,2
 		if v.AuxInt > 3 {
 			p.Reg = r.Reg
-			p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[0].Reg()})
+			p.SetFrom3Reg(v.Args[0].Reg())
 		} else {
 			p.Reg = v.Args[0].Reg()
 			p.SetFrom3(r)
@@ -1026,7 +1088,7 @@
 			p.From.Offset = ppc64.BO_BCTR
 			p.Reg = ppc64.REG_R0
 			p.To.Type = obj.TYPE_BRANCH
-			gc.Patch(p, top)
+			p.To.SetTarget(top)
 		}
 		// When ctr == 1 the loop was not generated but
 		// there are at least 64 bytes to clear, so add
@@ -1226,7 +1288,7 @@
 			p.From.Offset = ppc64.BO_BCTR
 			p.Reg = ppc64.REG_R0
 			p.To.Type = obj.TYPE_BRANCH
-			gc.Patch(p, top)
+			p.To.SetTarget(top)
 		}
 
 		// when ctr == 1 the loop was not generated but
@@ -1405,7 +1467,7 @@
 			p.From.Offset = ppc64.BO_BCTR
 			p.Reg = ppc64.REG_R0
 			p.To.Type = obj.TYPE_BRANCH
-			gc.Patch(p, top)
+			p.To.SetTarget(top)
 
 			// srcReg and dstReg were incremented in the loop, so
 			// later instructions start with offset 0.
@@ -1474,7 +1536,7 @@
 			case rem >= 8:
 				op, size = ppc64.AMOVD, 8
 			case rem >= 4:
-				op, size = ppc64.AMOVW, 4
+				op, size = ppc64.AMOVWZ, 4
 			case rem >= 2:
 				op, size = ppc64.AMOVH, 2
 			}
@@ -1652,7 +1714,7 @@
 			p.From.Offset = ppc64.BO_BCTR
 			p.Reg = ppc64.REG_R0
 			p.To.Type = obj.TYPE_BRANCH
-			gc.Patch(p, top)
+			p.To.SetTarget(top)
 
 			// srcReg and dstReg were incremented in the loop, so
 			// later instructions start with offset 0.
@@ -1741,7 +1803,7 @@
 			case rem >= 8:
 				op, size = ppc64.AMOVD, 8
 			case rem >= 4:
-				op, size = ppc64.AMOVW, 4
+				op, size = ppc64.AMOVWZ, 4
 			case rem >= 2:
 				op, size = ppc64.AMOVH, 2
 			}
@@ -1782,9 +1844,9 @@
 		pp.To.Reg = ppc64.REG_LR
 
 		// Insert a hint this is not a subroutine return.
-		pp.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: 1})
+		pp.SetFrom3Const(1)
 
-		if gc.Ctxt.Flag_shared {
+		if base.Ctxt.Flag_shared {
 			// When compiling Go into PIC, the function we just
 			// called via pointer might have been implemented in
 			// a separate module and so overwritten the TOC
@@ -1807,11 +1869,11 @@
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+		p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
 		s.UseArgs(16) // space used in callee args area by assembly stubs
 
 	case ssa.OpPPC64LoweredNilCheck:
-		if objabi.GOOS == "aix" {
+		if buildcfg.GOOS == "aix" {
 			// CMP Rarg0, R0
 			// BNE 2(PC)
 			// STW R0, 0(R0)
@@ -1838,22 +1900,22 @@
 
 			// NOP (so the BNE has somewhere to land)
 			nop := s.Prog(obj.ANOP)
-			gc.Patch(p2, nop)
+			p2.To.SetTarget(nop)
 
 		} else {
 			// Issue a load which will fault if arg is nil.
 			p := s.Prog(ppc64.AMOVBZ)
 			p.From.Type = obj.TYPE_MEM
 			p.From.Reg = v.Args[0].Reg()
-			gc.AddAux(&p.From, v)
+			ssagen.AddAux(&p.From, v)
 			p.To.Type = obj.TYPE_REG
 			p.To.Reg = ppc64.REGTMP
 		}
 		if logopt.Enabled() {
 			logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
 		}
-		if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
-			gc.Warnl(v.Pos, "generated nil check")
+		if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
+			base.WarnfAt(v.Pos, "generated nil check")
 		}
 
 	// These should be resolved by rules and not make it here.
@@ -1865,7 +1927,7 @@
 		v.Fatalf("InvertFlags should never make it to codegen %v", v.LongString())
 	case ssa.OpPPC64FlagEQ, ssa.OpPPC64FlagLT, ssa.OpPPC64FlagGT:
 		v.Fatalf("Flag* ops should never make it to codegen %v", v.LongString())
-	case ssa.OpClobber:
+	case ssa.OpClobber, ssa.OpClobberReg:
 		// TODO: implement for clobberdead experiment. Nop is ok for now.
 	default:
 		v.Fatalf("genValue not implemented: %s", v.LongString())
@@ -1891,7 +1953,7 @@
 	ssa.BlockPPC64FGT: {ppc64.ABGT, ppc64.ABLE, false, false},
 }
 
-func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
+func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
 	switch b.Kind {
 	case ssa.BlockDefer:
 		// defer returns in R3:
@@ -1905,18 +1967,18 @@
 
 		p = s.Prog(ppc64.ABNE)
 		p.To.Type = obj.TYPE_BRANCH
-		s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+		s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[1].Block()})
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 
 	case ssa.BlockPlain:
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 	case ssa.BlockExit:
 	case ssa.BlockRet:
diff --git a/src/cmd/compile/internal/reflectdata/alg.go b/src/cmd/compile/internal/reflectdata/alg.go
new file mode 100644
index 0000000..0707e0b
--- /dev/null
+++ b/src/cmd/compile/internal/reflectdata/alg.go
@@ -0,0 +1,810 @@
+// 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 reflectdata
+
+import (
+	"fmt"
+	"math/bits"
+	"sort"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+)
+
+// isRegularMemory reports whether t can be compared/hashed as regular memory.
+func isRegularMemory(t *types.Type) bool {
+	a, _ := types.AlgType(t)
+	return a == types.AMEM
+}
+
+// eqCanPanic reports whether == on type t could panic (has an interface somewhere).
+// t must be comparable.
+func eqCanPanic(t *types.Type) bool {
+	switch t.Kind() {
+	default:
+		return false
+	case types.TINTER:
+		return true
+	case types.TARRAY:
+		return eqCanPanic(t.Elem())
+	case types.TSTRUCT:
+		for _, f := range t.FieldSlice() {
+			if !f.Sym.IsBlank() && eqCanPanic(f.Type) {
+				return true
+			}
+		}
+		return false
+	}
+}
+
+// AlgType returns the fixed-width AMEMxx variants instead of the general
+// AMEM kind when possible.
+func AlgType(t *types.Type) types.AlgKind {
+	a, _ := types.AlgType(t)
+	if a == types.AMEM {
+		if t.Alignment() < int64(base.Ctxt.Arch.Alignment) && t.Alignment() < t.Width {
+			// For example, we can't treat [2]int16 as an int32 if int32s require
+			// 4-byte alignment. See issue 46283.
+			return a
+		}
+		switch t.Width {
+		case 0:
+			return types.AMEM0
+		case 1:
+			return types.AMEM8
+		case 2:
+			return types.AMEM16
+		case 4:
+			return types.AMEM32
+		case 8:
+			return types.AMEM64
+		case 16:
+			return types.AMEM128
+		}
+	}
+
+	return a
+}
+
+// genhash returns a symbol which is the closure used to compute
+// the hash of a value of type t.
+// Note: the generated function must match runtime.typehash exactly.
+func genhash(t *types.Type) *obj.LSym {
+	switch AlgType(t) {
+	default:
+		// genhash is only called for types that have equality
+		base.Fatalf("genhash %v", t)
+	case types.AMEM0:
+		return sysClosure("memhash0")
+	case types.AMEM8:
+		return sysClosure("memhash8")
+	case types.AMEM16:
+		return sysClosure("memhash16")
+	case types.AMEM32:
+		return sysClosure("memhash32")
+	case types.AMEM64:
+		return sysClosure("memhash64")
+	case types.AMEM128:
+		return sysClosure("memhash128")
+	case types.ASTRING:
+		return sysClosure("strhash")
+	case types.AINTER:
+		return sysClosure("interhash")
+	case types.ANILINTER:
+		return sysClosure("nilinterhash")
+	case types.AFLOAT32:
+		return sysClosure("f32hash")
+	case types.AFLOAT64:
+		return sysClosure("f64hash")
+	case types.ACPLX64:
+		return sysClosure("c64hash")
+	case types.ACPLX128:
+		return sysClosure("c128hash")
+	case types.AMEM:
+		// For other sizes of plain memory, we build a closure
+		// that calls memhash_varlen. The size of the memory is
+		// encoded in the first slot of the closure.
+		closure := TypeLinksymLookup(fmt.Sprintf(".hashfunc%d", t.Width))
+		if len(closure.P) > 0 { // already generated
+			return closure
+		}
+		if memhashvarlen == nil {
+			memhashvarlen = typecheck.LookupRuntimeFunc("memhash_varlen")
+		}
+		ot := 0
+		ot = objw.SymPtr(closure, ot, memhashvarlen, 0)
+		ot = objw.Uintptr(closure, ot, uint64(t.Width)) // size encoded in closure
+		objw.Global(closure, int32(ot), obj.DUPOK|obj.RODATA)
+		return closure
+	case types.ASPECIAL:
+		break
+	}
+
+	closure := TypeLinksymPrefix(".hashfunc", t)
+	if len(closure.P) > 0 { // already generated
+		return closure
+	}
+
+	// Generate hash functions for subtypes.
+	// There are cases where we might not use these hashes,
+	// but in that case they will get dead-code eliminated.
+	// (And the closure generated by genhash will also get
+	// dead-code eliminated, as we call the subtype hashers
+	// directly.)
+	switch t.Kind() {
+	case types.TARRAY:
+		genhash(t.Elem())
+	case types.TSTRUCT:
+		for _, f := range t.FieldSlice() {
+			genhash(f.Type)
+		}
+	}
+
+	sym := TypeSymPrefix(".hash", t)
+	if base.Flag.LowerR != 0 {
+		fmt.Printf("genhash %v %v %v\n", closure, sym, t)
+	}
+
+	base.Pos = base.AutogeneratedPos // less confusing than end of input
+	typecheck.DeclContext = ir.PEXTERN
+
+	// func sym(p *T, h uintptr) uintptr
+	args := []*ir.Field{
+		ir.NewField(base.Pos, typecheck.Lookup("p"), nil, types.NewPtr(t)),
+		ir.NewField(base.Pos, typecheck.Lookup("h"), nil, types.Types[types.TUINTPTR]),
+	}
+	results := []*ir.Field{ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR])}
+	tfn := ir.NewFuncType(base.Pos, nil, args, results)
+
+	fn := typecheck.DeclFunc(sym, tfn)
+	np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
+	nh := ir.AsNode(tfn.Type().Params().Field(1).Nname)
+
+	switch t.Kind() {
+	case types.TARRAY:
+		// An array of pure memory would be handled by the
+		// standard algorithm, so the element type must not be
+		// pure memory.
+		hashel := hashfor(t.Elem())
+
+		// for i := 0; i < nelem; i++
+		ni := typecheck.Temp(types.Types[types.TINT])
+		init := ir.NewAssignStmt(base.Pos, ni, ir.NewInt(0))
+		cond := ir.NewBinaryExpr(base.Pos, ir.OLT, ni, ir.NewInt(t.NumElem()))
+		post := ir.NewAssignStmt(base.Pos, ni, ir.NewBinaryExpr(base.Pos, ir.OADD, ni, ir.NewInt(1)))
+		loop := ir.NewForStmt(base.Pos, nil, cond, post, nil)
+		loop.PtrInit().Append(init)
+
+		// h = hashel(&p[i], h)
+		call := ir.NewCallExpr(base.Pos, ir.OCALL, hashel, nil)
+
+		nx := ir.NewIndexExpr(base.Pos, np, ni)
+		nx.SetBounded(true)
+		na := typecheck.NodAddr(nx)
+		call.Args.Append(na)
+		call.Args.Append(nh)
+		loop.Body.Append(ir.NewAssignStmt(base.Pos, nh, call))
+
+		fn.Body.Append(loop)
+
+	case types.TSTRUCT:
+		// Walk the struct using memhash for runs of AMEM
+		// and calling specific hash functions for the others.
+		for i, fields := 0, t.FieldSlice(); i < len(fields); {
+			f := fields[i]
+
+			// Skip blank fields.
+			if f.Sym.IsBlank() {
+				i++
+				continue
+			}
+
+			// Hash non-memory fields with appropriate hash function.
+			if !isRegularMemory(f.Type) {
+				hashel := hashfor(f.Type)
+				call := ir.NewCallExpr(base.Pos, ir.OCALL, hashel, nil)
+				nx := ir.NewSelectorExpr(base.Pos, ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
+				na := typecheck.NodAddr(nx)
+				call.Args.Append(na)
+				call.Args.Append(nh)
+				fn.Body.Append(ir.NewAssignStmt(base.Pos, nh, call))
+				i++
+				continue
+			}
+
+			// Otherwise, hash a maximal length run of raw memory.
+			size, next := memrun(t, i)
+
+			// h = hashel(&p.first, size, h)
+			hashel := hashmem(f.Type)
+			call := ir.NewCallExpr(base.Pos, ir.OCALL, hashel, nil)
+			nx := ir.NewSelectorExpr(base.Pos, ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
+			na := typecheck.NodAddr(nx)
+			call.Args.Append(na)
+			call.Args.Append(nh)
+			call.Args.Append(ir.NewInt(size))
+			fn.Body.Append(ir.NewAssignStmt(base.Pos, nh, call))
+
+			i = next
+		}
+	}
+
+	r := ir.NewReturnStmt(base.Pos, nil)
+	r.Results.Append(nh)
+	fn.Body.Append(r)
+
+	if base.Flag.LowerR != 0 {
+		ir.DumpList("genhash body", fn.Body)
+	}
+
+	typecheck.FinishFuncBody()
+
+	fn.SetDupok(true)
+	typecheck.Func(fn)
+
+	ir.CurFunc = fn
+	typecheck.Stmts(fn.Body)
+	ir.CurFunc = nil
+
+	if base.Debug.DclStack != 0 {
+		types.CheckDclstack()
+	}
+
+	fn.SetNilCheckDisabled(true)
+	typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
+
+	// Build closure. It doesn't close over any variables, so
+	// it contains just the function pointer.
+	objw.SymPtr(closure, 0, fn.Linksym(), 0)
+	objw.Global(closure, int32(types.PtrSize), obj.DUPOK|obj.RODATA)
+
+	return closure
+}
+
+func hashfor(t *types.Type) ir.Node {
+	var sym *types.Sym
+
+	switch a, _ := types.AlgType(t); a {
+	case types.AMEM:
+		base.Fatalf("hashfor with AMEM type")
+	case types.AINTER:
+		sym = ir.Pkgs.Runtime.Lookup("interhash")
+	case types.ANILINTER:
+		sym = ir.Pkgs.Runtime.Lookup("nilinterhash")
+	case types.ASTRING:
+		sym = ir.Pkgs.Runtime.Lookup("strhash")
+	case types.AFLOAT32:
+		sym = ir.Pkgs.Runtime.Lookup("f32hash")
+	case types.AFLOAT64:
+		sym = ir.Pkgs.Runtime.Lookup("f64hash")
+	case types.ACPLX64:
+		sym = ir.Pkgs.Runtime.Lookup("c64hash")
+	case types.ACPLX128:
+		sym = ir.Pkgs.Runtime.Lookup("c128hash")
+	default:
+		// Note: the caller of hashfor ensured that this symbol
+		// exists and has a body by calling genhash for t.
+		sym = TypeSymPrefix(".hash", t)
+	}
+
+	// TODO(austin): This creates an ir.Name with a nil Func.
+	n := typecheck.NewName(sym)
+	ir.MarkFunc(n)
+	n.SetType(types.NewSignature(types.NoPkg, nil, nil, []*types.Field{
+		types.NewField(base.Pos, nil, types.NewPtr(t)),
+		types.NewField(base.Pos, nil, types.Types[types.TUINTPTR]),
+	}, []*types.Field{
+		types.NewField(base.Pos, nil, types.Types[types.TUINTPTR]),
+	}))
+	return n
+}
+
+// sysClosure returns a closure which will call the
+// given runtime function (with no closed-over variables).
+func sysClosure(name string) *obj.LSym {
+	s := typecheck.LookupRuntimeVar(name + "·f")
+	if len(s.P) == 0 {
+		f := typecheck.LookupRuntimeFunc(name)
+		objw.SymPtr(s, 0, f, 0)
+		objw.Global(s, int32(types.PtrSize), obj.DUPOK|obj.RODATA)
+	}
+	return s
+}
+
+// geneq returns a symbol which is the closure used to compute
+// equality for two objects of type t.
+func geneq(t *types.Type) *obj.LSym {
+	switch AlgType(t) {
+	case types.ANOEQ:
+		// The runtime will panic if it tries to compare
+		// a type with a nil equality function.
+		return nil
+	case types.AMEM0:
+		return sysClosure("memequal0")
+	case types.AMEM8:
+		return sysClosure("memequal8")
+	case types.AMEM16:
+		return sysClosure("memequal16")
+	case types.AMEM32:
+		return sysClosure("memequal32")
+	case types.AMEM64:
+		return sysClosure("memequal64")
+	case types.AMEM128:
+		return sysClosure("memequal128")
+	case types.ASTRING:
+		return sysClosure("strequal")
+	case types.AINTER:
+		return sysClosure("interequal")
+	case types.ANILINTER:
+		return sysClosure("nilinterequal")
+	case types.AFLOAT32:
+		return sysClosure("f32equal")
+	case types.AFLOAT64:
+		return sysClosure("f64equal")
+	case types.ACPLX64:
+		return sysClosure("c64equal")
+	case types.ACPLX128:
+		return sysClosure("c128equal")
+	case types.AMEM:
+		// make equality closure. The size of the type
+		// is encoded in the closure.
+		closure := TypeLinksymLookup(fmt.Sprintf(".eqfunc%d", t.Width))
+		if len(closure.P) != 0 {
+			return closure
+		}
+		if memequalvarlen == nil {
+			memequalvarlen = typecheck.LookupRuntimeFunc("memequal_varlen")
+		}
+		ot := 0
+		ot = objw.SymPtr(closure, ot, memequalvarlen, 0)
+		ot = objw.Uintptr(closure, ot, uint64(t.Width))
+		objw.Global(closure, int32(ot), obj.DUPOK|obj.RODATA)
+		return closure
+	case types.ASPECIAL:
+		break
+	}
+
+	closure := TypeLinksymPrefix(".eqfunc", t)
+	if len(closure.P) > 0 { // already generated
+		return closure
+	}
+	sym := TypeSymPrefix(".eq", t)
+	if base.Flag.LowerR != 0 {
+		fmt.Printf("geneq %v\n", t)
+	}
+
+	// Autogenerate code for equality of structs and arrays.
+
+	base.Pos = base.AutogeneratedPos // less confusing than end of input
+	typecheck.DeclContext = ir.PEXTERN
+
+	// func sym(p, q *T) bool
+	tfn := ir.NewFuncType(base.Pos, nil,
+		[]*ir.Field{ir.NewField(base.Pos, typecheck.Lookup("p"), nil, types.NewPtr(t)), ir.NewField(base.Pos, typecheck.Lookup("q"), nil, types.NewPtr(t))},
+		[]*ir.Field{ir.NewField(base.Pos, typecheck.Lookup("r"), nil, types.Types[types.TBOOL])})
+
+	fn := typecheck.DeclFunc(sym, tfn)
+	np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
+	nq := ir.AsNode(tfn.Type().Params().Field(1).Nname)
+	nr := ir.AsNode(tfn.Type().Results().Field(0).Nname)
+
+	// Label to jump to if an equality test fails.
+	neq := typecheck.AutoLabel(".neq")
+
+	// We reach here only for types that have equality but
+	// cannot be handled by the standard algorithms,
+	// so t must be either an array or a struct.
+	switch t.Kind() {
+	default:
+		base.Fatalf("geneq %v", t)
+
+	case types.TARRAY:
+		nelem := t.NumElem()
+
+		// checkAll generates code to check the equality of all array elements.
+		// If unroll is greater than nelem, checkAll generates:
+		//
+		// if eq(p[0], q[0]) && eq(p[1], q[1]) && ... {
+		// } else {
+		//   return
+		// }
+		//
+		// And so on.
+		//
+		// Otherwise it generates:
+		//
+		// for i := 0; i < nelem; i++ {
+		//   if eq(p[i], q[i]) {
+		//   } else {
+		//     goto neq
+		//   }
+		// }
+		//
+		// TODO(josharian): consider doing some loop unrolling
+		// for larger nelem as well, processing a few elements at a time in a loop.
+		checkAll := func(unroll int64, last bool, eq func(pi, qi ir.Node) ir.Node) {
+			// checkIdx generates a node to check for equality at index i.
+			checkIdx := func(i ir.Node) ir.Node {
+				// pi := p[i]
+				pi := ir.NewIndexExpr(base.Pos, np, i)
+				pi.SetBounded(true)
+				pi.SetType(t.Elem())
+				// qi := q[i]
+				qi := ir.NewIndexExpr(base.Pos, nq, i)
+				qi.SetBounded(true)
+				qi.SetType(t.Elem())
+				return eq(pi, qi)
+			}
+
+			if nelem <= unroll {
+				if last {
+					// Do last comparison in a different manner.
+					nelem--
+				}
+				// Generate a series of checks.
+				for i := int64(0); i < nelem; i++ {
+					// if check {} else { goto neq }
+					nif := ir.NewIfStmt(base.Pos, checkIdx(ir.NewInt(i)), nil, nil)
+					nif.Else.Append(ir.NewBranchStmt(base.Pos, ir.OGOTO, neq))
+					fn.Body.Append(nif)
+				}
+				if last {
+					fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, checkIdx(ir.NewInt(nelem))))
+				}
+			} else {
+				// Generate a for loop.
+				// for i := 0; i < nelem; i++
+				i := typecheck.Temp(types.Types[types.TINT])
+				init := ir.NewAssignStmt(base.Pos, i, ir.NewInt(0))
+				cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, ir.NewInt(nelem))
+				post := ir.NewAssignStmt(base.Pos, i, ir.NewBinaryExpr(base.Pos, ir.OADD, i, ir.NewInt(1)))
+				loop := ir.NewForStmt(base.Pos, nil, cond, post, nil)
+				loop.PtrInit().Append(init)
+				// if eq(pi, qi) {} else { goto neq }
+				nif := ir.NewIfStmt(base.Pos, checkIdx(i), nil, nil)
+				nif.Else.Append(ir.NewBranchStmt(base.Pos, ir.OGOTO, neq))
+				loop.Body.Append(nif)
+				fn.Body.Append(loop)
+				if last {
+					fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, ir.NewBool(true)))
+				}
+			}
+		}
+
+		switch t.Elem().Kind() {
+		case types.TSTRING:
+			// Do two loops. First, check that all the lengths match (cheap).
+			// Second, check that all the contents match (expensive).
+			// TODO: when the array size is small, unroll the length match checks.
+			checkAll(3, false, func(pi, qi ir.Node) ir.Node {
+				// Compare lengths.
+				eqlen, _ := EqString(pi, qi)
+				return eqlen
+			})
+			checkAll(1, true, func(pi, qi ir.Node) ir.Node {
+				// Compare contents.
+				_, eqmem := EqString(pi, qi)
+				return eqmem
+			})
+		case types.TFLOAT32, types.TFLOAT64:
+			checkAll(2, true, func(pi, qi ir.Node) ir.Node {
+				// p[i] == q[i]
+				return ir.NewBinaryExpr(base.Pos, ir.OEQ, pi, qi)
+			})
+		// TODO: pick apart structs, do them piecemeal too
+		default:
+			checkAll(1, true, func(pi, qi ir.Node) ir.Node {
+				// p[i] == q[i]
+				return ir.NewBinaryExpr(base.Pos, ir.OEQ, pi, qi)
+			})
+		}
+
+	case types.TSTRUCT:
+		// Build a list of conditions to satisfy.
+		// The conditions are a list-of-lists. Conditions are reorderable
+		// within each inner list. The outer lists must be evaluated in order.
+		var conds [][]ir.Node
+		conds = append(conds, []ir.Node{})
+		and := func(n ir.Node) {
+			i := len(conds) - 1
+			conds[i] = append(conds[i], n)
+		}
+
+		// Walk the struct using memequal for runs of AMEM
+		// and calling specific equality tests for the others.
+		for i, fields := 0, t.FieldSlice(); i < len(fields); {
+			f := fields[i]
+
+			// Skip blank-named fields.
+			if f.Sym.IsBlank() {
+				i++
+				continue
+			}
+
+			// Compare non-memory fields with field equality.
+			if !isRegularMemory(f.Type) {
+				if eqCanPanic(f.Type) {
+					// Enforce ordering by starting a new set of reorderable conditions.
+					conds = append(conds, []ir.Node{})
+				}
+				p := ir.NewSelectorExpr(base.Pos, ir.OXDOT, np, f.Sym)
+				q := ir.NewSelectorExpr(base.Pos, ir.OXDOT, nq, f.Sym)
+				switch {
+				case f.Type.IsString():
+					eqlen, eqmem := EqString(p, q)
+					and(eqlen)
+					and(eqmem)
+				default:
+					and(ir.NewBinaryExpr(base.Pos, ir.OEQ, p, q))
+				}
+				if eqCanPanic(f.Type) {
+					// Also enforce ordering after something that can panic.
+					conds = append(conds, []ir.Node{})
+				}
+				i++
+				continue
+			}
+
+			// Find maximal length run of memory-only fields.
+			size, next := memrun(t, i)
+
+			// TODO(rsc): All the calls to newname are wrong for
+			// cross-package unexported fields.
+			if s := fields[i:next]; len(s) <= 2 {
+				// Two or fewer fields: use plain field equality.
+				for _, f := range s {
+					and(eqfield(np, nq, f.Sym))
+				}
+			} else {
+				// More than two fields: use memequal.
+				and(eqmem(np, nq, f.Sym, size))
+			}
+			i = next
+		}
+
+		// Sort conditions to put runtime calls last.
+		// Preserve the rest of the ordering.
+		var flatConds []ir.Node
+		for _, c := range conds {
+			isCall := func(n ir.Node) bool {
+				return n.Op() == ir.OCALL || n.Op() == ir.OCALLFUNC
+			}
+			sort.SliceStable(c, func(i, j int) bool {
+				return !isCall(c[i]) && isCall(c[j])
+			})
+			flatConds = append(flatConds, c...)
+		}
+
+		if len(flatConds) == 0 {
+			fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, ir.NewBool(true)))
+		} else {
+			for _, c := range flatConds[:len(flatConds)-1] {
+				// if cond {} else { goto neq }
+				n := ir.NewIfStmt(base.Pos, c, nil, nil)
+				n.Else.Append(ir.NewBranchStmt(base.Pos, ir.OGOTO, neq))
+				fn.Body.Append(n)
+			}
+			fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, flatConds[len(flatConds)-1]))
+		}
+	}
+
+	// ret:
+	//   return
+	ret := typecheck.AutoLabel(".ret")
+	fn.Body.Append(ir.NewLabelStmt(base.Pos, ret))
+	fn.Body.Append(ir.NewReturnStmt(base.Pos, nil))
+
+	// neq:
+	//   r = false
+	//   return (or goto ret)
+	fn.Body.Append(ir.NewLabelStmt(base.Pos, neq))
+	fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, ir.NewBool(false)))
+	if eqCanPanic(t) || anyCall(fn) {
+		// Epilogue is large, so share it with the equal case.
+		fn.Body.Append(ir.NewBranchStmt(base.Pos, ir.OGOTO, ret))
+	} else {
+		// Epilogue is small, so don't bother sharing.
+		fn.Body.Append(ir.NewReturnStmt(base.Pos, nil))
+	}
+	// TODO(khr): the epilogue size detection condition above isn't perfect.
+	// We should really do a generic CL that shares epilogues across
+	// the board. See #24936.
+
+	if base.Flag.LowerR != 0 {
+		ir.DumpList("geneq body", fn.Body)
+	}
+
+	typecheck.FinishFuncBody()
+
+	fn.SetDupok(true)
+	typecheck.Func(fn)
+
+	ir.CurFunc = fn
+	typecheck.Stmts(fn.Body)
+	ir.CurFunc = nil
+
+	if base.Debug.DclStack != 0 {
+		types.CheckDclstack()
+	}
+
+	// Disable checknils while compiling this code.
+	// We are comparing a struct or an array,
+	// neither of which can be nil, and our comparisons
+	// are shallow.
+	fn.SetNilCheckDisabled(true)
+	typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
+
+	// Generate a closure which points at the function we just generated.
+	objw.SymPtr(closure, 0, fn.Linksym(), 0)
+	objw.Global(closure, int32(types.PtrSize), obj.DUPOK|obj.RODATA)
+	return closure
+}
+
+func anyCall(fn *ir.Func) bool {
+	return ir.Any(fn, func(n ir.Node) bool {
+		// TODO(rsc): No methods?
+		op := n.Op()
+		return op == ir.OCALL || op == ir.OCALLFUNC
+	})
+}
+
+// eqfield returns the node
+// 	p.field == q.field
+func eqfield(p ir.Node, q ir.Node, field *types.Sym) ir.Node {
+	nx := ir.NewSelectorExpr(base.Pos, ir.OXDOT, p, field)
+	ny := ir.NewSelectorExpr(base.Pos, ir.OXDOT, q, field)
+	ne := ir.NewBinaryExpr(base.Pos, ir.OEQ, nx, ny)
+	return ne
+}
+
+// EqString returns the nodes
+//   len(s) == len(t)
+// and
+//   memequal(s.ptr, t.ptr, len(s))
+// which can be used to construct string equality comparison.
+// eqlen must be evaluated before eqmem, and shortcircuiting is required.
+func EqString(s, t ir.Node) (eqlen *ir.BinaryExpr, eqmem *ir.CallExpr) {
+	s = typecheck.Conv(s, types.Types[types.TSTRING])
+	t = typecheck.Conv(t, types.Types[types.TSTRING])
+	sptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, s)
+	tptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, t)
+	slen := typecheck.Conv(ir.NewUnaryExpr(base.Pos, ir.OLEN, s), types.Types[types.TUINTPTR])
+	tlen := typecheck.Conv(ir.NewUnaryExpr(base.Pos, ir.OLEN, t), types.Types[types.TUINTPTR])
+
+	fn := typecheck.LookupRuntime("memequal")
+	fn = typecheck.SubstArgTypes(fn, types.Types[types.TUINT8], types.Types[types.TUINT8])
+	call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, []ir.Node{sptr, tptr, ir.Copy(slen)})
+	typecheck.Call(call)
+
+	cmp := ir.NewBinaryExpr(base.Pos, ir.OEQ, slen, tlen)
+	cmp = typecheck.Expr(cmp).(*ir.BinaryExpr)
+	cmp.SetType(types.Types[types.TBOOL])
+	return cmp, call
+}
+
+// EqInterface returns the nodes
+//   s.tab == t.tab (or s.typ == t.typ, as appropriate)
+// and
+//   ifaceeq(s.tab, s.data, t.data) (or efaceeq(s.typ, s.data, t.data), as appropriate)
+// which can be used to construct interface equality comparison.
+// eqtab must be evaluated before eqdata, and shortcircuiting is required.
+func EqInterface(s, t ir.Node) (eqtab *ir.BinaryExpr, eqdata *ir.CallExpr) {
+	if !types.Identical(s.Type(), t.Type()) {
+		base.Fatalf("EqInterface %v %v", s.Type(), t.Type())
+	}
+	// func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
+	// func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
+	var fn ir.Node
+	if s.Type().IsEmptyInterface() {
+		fn = typecheck.LookupRuntime("efaceeq")
+	} else {
+		fn = typecheck.LookupRuntime("ifaceeq")
+	}
+
+	stab := ir.NewUnaryExpr(base.Pos, ir.OITAB, s)
+	ttab := ir.NewUnaryExpr(base.Pos, ir.OITAB, t)
+	sdata := ir.NewUnaryExpr(base.Pos, ir.OIDATA, s)
+	tdata := ir.NewUnaryExpr(base.Pos, ir.OIDATA, t)
+	sdata.SetType(types.Types[types.TUNSAFEPTR])
+	tdata.SetType(types.Types[types.TUNSAFEPTR])
+	sdata.SetTypecheck(1)
+	tdata.SetTypecheck(1)
+
+	call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, []ir.Node{stab, sdata, tdata})
+	typecheck.Call(call)
+
+	cmp := ir.NewBinaryExpr(base.Pos, ir.OEQ, stab, ttab)
+	cmp = typecheck.Expr(cmp).(*ir.BinaryExpr)
+	cmp.SetType(types.Types[types.TBOOL])
+	return cmp, call
+}
+
+// eqmem returns the node
+// 	memequal(&p.field, &q.field [, size])
+func eqmem(p ir.Node, q ir.Node, field *types.Sym, size int64) ir.Node {
+	nx := typecheck.Expr(typecheck.NodAddr(ir.NewSelectorExpr(base.Pos, ir.OXDOT, p, field)))
+	ny := typecheck.Expr(typecheck.NodAddr(ir.NewSelectorExpr(base.Pos, ir.OXDOT, q, field)))
+
+	fn, needsize := eqmemfunc(size, nx.Type().Elem())
+	call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, nil)
+	call.Args.Append(nx)
+	call.Args.Append(ny)
+	if needsize {
+		call.Args.Append(ir.NewInt(size))
+	}
+
+	return call
+}
+
+func eqmemfunc(size int64, t *types.Type) (fn *ir.Name, needsize bool) {
+	switch size {
+	default:
+		fn = typecheck.LookupRuntime("memequal")
+		needsize = true
+	case 1, 2, 4, 8, 16:
+		buf := fmt.Sprintf("memequal%d", int(size)*8)
+		fn = typecheck.LookupRuntime(buf)
+	}
+
+	fn = typecheck.SubstArgTypes(fn, t, t)
+	return fn, needsize
+}
+
+// memrun finds runs of struct fields for which memory-only algs are appropriate.
+// t is the parent struct type, and start is the field index at which to start the run.
+// size is the length in bytes of the memory included in the run.
+// next is the index just after the end of the memory run.
+func memrun(t *types.Type, start int) (size int64, next int) {
+	next = start
+	for {
+		next++
+		if next == t.NumFields() {
+			break
+		}
+		// Stop run after a padded field.
+		if types.IsPaddedField(t, next-1) {
+			break
+		}
+		// Also, stop before a blank or non-memory field.
+		if f := t.Field(next); f.Sym.IsBlank() || !isRegularMemory(f.Type) {
+			break
+		}
+		// For issue 46283, don't combine fields if the resulting load would
+		// require a larger alignment than the component fields.
+		if base.Ctxt.Arch.Alignment > 1 {
+			align := t.Alignment()
+			if off := t.Field(start).Offset; off&(align-1) != 0 {
+				// Offset is less aligned than the containing type.
+				// Use offset to determine alignment.
+				align = 1 << uint(bits.TrailingZeros64(uint64(off)))
+			}
+			size := t.Field(next).End() - t.Field(start).Offset
+			if size > align {
+				break
+			}
+		}
+	}
+	return t.Field(next-1).End() - t.Field(start).Offset, next
+}
+
+func hashmem(t *types.Type) ir.Node {
+	sym := ir.Pkgs.Runtime.Lookup("memhash")
+
+	// TODO(austin): This creates an ir.Name with a nil Func.
+	n := typecheck.NewName(sym)
+	ir.MarkFunc(n)
+	n.SetType(types.NewSignature(types.NoPkg, nil, nil, []*types.Field{
+		types.NewField(base.Pos, nil, types.NewPtr(t)),
+		types.NewField(base.Pos, nil, types.Types[types.TUINTPTR]),
+		types.NewField(base.Pos, nil, types.Types[types.TUINTPTR]),
+	}, []*types.Field{
+		types.NewField(base.Pos, nil, types.Types[types.TUINTPTR]),
+	}))
+	return n
+}
diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go
new file mode 100644
index 0000000..eb9a8a6
--- /dev/null
+++ b/src/cmd/compile/internal/reflectdata/reflect.go
@@ -0,0 +1,1905 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package reflectdata
+
+import (
+	"encoding/binary"
+	"fmt"
+	"internal/buildcfg"
+	"os"
+	"sort"
+	"strings"
+	"sync"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/bitvec"
+	"cmd/compile/internal/escape"
+	"cmd/compile/internal/inline"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/typebits"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/gcprog"
+	"cmd/internal/obj"
+	"cmd/internal/objabi"
+	"cmd/internal/src"
+)
+
+type itabEntry struct {
+	t, itype *types.Type
+	lsym     *obj.LSym // symbol of the itab itself
+
+	// symbols of each method in
+	// the itab, sorted by byte offset;
+	// filled in by CompileITabs
+	entries []*obj.LSym
+}
+
+type ptabEntry struct {
+	s *types.Sym
+	t *types.Type
+}
+
+func CountTabs() (numPTabs, numITabs int) {
+	return len(ptabs), len(itabs)
+}
+
+// runtime interface and reflection data structures
+var (
+	signatmu    sync.Mutex // protects signatset and signatslice
+	signatset   = make(map[*types.Type]struct{})
+	signatslice []*types.Type
+
+	gcsymmu  sync.Mutex // protects gcsymset and gcsymslice
+	gcsymset = make(map[*types.Type]struct{})
+
+	itabs []itabEntry
+	ptabs []*ir.Name
+)
+
+type typeSig struct {
+	name  *types.Sym
+	isym  *obj.LSym
+	tsym  *obj.LSym
+	type_ *types.Type
+	mtype *types.Type
+}
+
+// Builds a type representing a Bucket structure for
+// the given map type. This type is not visible to users -
+// we include only enough information to generate a correct GC
+// program for it.
+// Make sure this stays in sync with runtime/map.go.
+const (
+	BUCKETSIZE  = 8
+	MAXKEYSIZE  = 128
+	MAXELEMSIZE = 128
+)
+
+func structfieldSize() int { return 3 * types.PtrSize }       // Sizeof(runtime.structfield{})
+func imethodSize() int     { return 4 + 4 }                   // Sizeof(runtime.imethod{})
+func commonSize() int      { return 4*types.PtrSize + 8 + 8 } // Sizeof(runtime._type{})
+
+func uncommonSize(t *types.Type) int { // Sizeof(runtime.uncommontype{})
+	if t.Sym() == nil && len(methods(t)) == 0 {
+		return 0
+	}
+	return 4 + 2 + 2 + 4 + 4
+}
+
+func makefield(name string, t *types.Type) *types.Field {
+	sym := (*types.Pkg)(nil).Lookup(name)
+	return types.NewField(src.NoXPos, sym, t)
+}
+
+// MapBucketType makes the map bucket type given the type of the map.
+func MapBucketType(t *types.Type) *types.Type {
+	if t.MapType().Bucket != nil {
+		return t.MapType().Bucket
+	}
+
+	keytype := t.Key()
+	elemtype := t.Elem()
+	types.CalcSize(keytype)
+	types.CalcSize(elemtype)
+	if keytype.Width > MAXKEYSIZE {
+		keytype = types.NewPtr(keytype)
+	}
+	if elemtype.Width > MAXELEMSIZE {
+		elemtype = types.NewPtr(elemtype)
+	}
+
+	field := make([]*types.Field, 0, 5)
+
+	// The first field is: uint8 topbits[BUCKETSIZE].
+	arr := types.NewArray(types.Types[types.TUINT8], BUCKETSIZE)
+	field = append(field, makefield("topbits", arr))
+
+	arr = types.NewArray(keytype, BUCKETSIZE)
+	arr.SetNoalg(true)
+	keys := makefield("keys", arr)
+	field = append(field, keys)
+
+	arr = types.NewArray(elemtype, BUCKETSIZE)
+	arr.SetNoalg(true)
+	elems := makefield("elems", arr)
+	field = append(field, elems)
+
+	// If keys and elems have no pointers, the map implementation
+	// can keep a list of overflow pointers on the side so that
+	// buckets can be marked as having no pointers.
+	// Arrange for the bucket to have no pointers by changing
+	// the type of the overflow field to uintptr in this case.
+	// See comment on hmap.overflow in runtime/map.go.
+	otyp := types.Types[types.TUNSAFEPTR]
+	if !elemtype.HasPointers() && !keytype.HasPointers() {
+		otyp = types.Types[types.TUINTPTR]
+	}
+	overflow := makefield("overflow", otyp)
+	field = append(field, overflow)
+
+	// link up fields
+	bucket := types.NewStruct(types.NoPkg, field[:])
+	bucket.SetNoalg(true)
+	types.CalcSize(bucket)
+
+	// Check invariants that map code depends on.
+	if !types.IsComparable(t.Key()) {
+		base.Fatalf("unsupported map key type for %v", t)
+	}
+	if BUCKETSIZE < 8 {
+		base.Fatalf("bucket size too small for proper alignment")
+	}
+	if keytype.Align > BUCKETSIZE {
+		base.Fatalf("key align too big for %v", t)
+	}
+	if elemtype.Align > BUCKETSIZE {
+		base.Fatalf("elem align too big for %v", t)
+	}
+	if keytype.Width > MAXKEYSIZE {
+		base.Fatalf("key size to large for %v", t)
+	}
+	if elemtype.Width > MAXELEMSIZE {
+		base.Fatalf("elem size to large for %v", t)
+	}
+	if t.Key().Width > MAXKEYSIZE && !keytype.IsPtr() {
+		base.Fatalf("key indirect incorrect for %v", t)
+	}
+	if t.Elem().Width > MAXELEMSIZE && !elemtype.IsPtr() {
+		base.Fatalf("elem indirect incorrect for %v", t)
+	}
+	if keytype.Width%int64(keytype.Align) != 0 {
+		base.Fatalf("key size not a multiple of key align for %v", t)
+	}
+	if elemtype.Width%int64(elemtype.Align) != 0 {
+		base.Fatalf("elem size not a multiple of elem align for %v", t)
+	}
+	if bucket.Align%keytype.Align != 0 {
+		base.Fatalf("bucket align not multiple of key align %v", t)
+	}
+	if bucket.Align%elemtype.Align != 0 {
+		base.Fatalf("bucket align not multiple of elem align %v", t)
+	}
+	if keys.Offset%int64(keytype.Align) != 0 {
+		base.Fatalf("bad alignment of keys in bmap for %v", t)
+	}
+	if elems.Offset%int64(elemtype.Align) != 0 {
+		base.Fatalf("bad alignment of elems in bmap for %v", t)
+	}
+
+	// Double-check that overflow field is final memory in struct,
+	// with no padding at end.
+	if overflow.Offset != bucket.Width-int64(types.PtrSize) {
+		base.Fatalf("bad offset of overflow in bmap for %v", t)
+	}
+
+	t.MapType().Bucket = bucket
+
+	bucket.StructType().Map = t
+	return bucket
+}
+
+// MapType builds a type representing a Hmap structure for the given map type.
+// Make sure this stays in sync with runtime/map.go.
+func MapType(t *types.Type) *types.Type {
+	if t.MapType().Hmap != nil {
+		return t.MapType().Hmap
+	}
+
+	bmap := MapBucketType(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/map.go:hmap.
+	fields := []*types.Field{
+		makefield("count", types.Types[types.TINT]),
+		makefield("flags", types.Types[types.TUINT8]),
+		makefield("B", types.Types[types.TUINT8]),
+		makefield("noverflow", types.Types[types.TUINT16]),
+		makefield("hash0", types.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[types.TUINTPTR]),
+		makefield("extra", types.Types[types.TUNSAFEPTR]),
+	}
+
+	hmap := types.NewStruct(types.NoPkg, fields)
+	hmap.SetNoalg(true)
+	types.CalcSize(hmap)
+
+	// The size of hmap should be 48 bytes on 64 bit
+	// and 28 bytes on 32 bit platforms.
+	if size := int64(8 + 5*types.PtrSize); hmap.Width != size {
+		base.Fatalf("hmap size not correct: got %d, want %d", hmap.Width, size)
+	}
+
+	t.MapType().Hmap = hmap
+	hmap.StructType().Map = t
+	return hmap
+}
+
+// MapIterType builds a type representing an Hiter structure for the given map type.
+// Make sure this stays in sync with runtime/map.go.
+func MapIterType(t *types.Type) *types.Type {
+	if t.MapType().Hiter != nil {
+		return t.MapType().Hiter
+	}
+
+	hmap := MapType(t)
+	bmap := MapBucketType(t)
+
+	// build a struct:
+	// type hiter struct {
+	//    key         *Key
+	//    elem        *Elem
+	//    t           unsafe.Pointer // *MapType
+	//    h           *hmap
+	//    buckets     *bmap
+	//    bptr        *bmap
+	//    overflow    unsafe.Pointer // *[]*bmap
+	//    oldoverflow unsafe.Pointer // *[]*bmap
+	//    startBucket uintptr
+	//    offset      uint8
+	//    wrapped     bool
+	//    B           uint8
+	//    i           uint8
+	//    bucket      uintptr
+	//    checkBucket uintptr
+	// }
+	// must match runtime/map.go:hiter.
+	fields := []*types.Field{
+		makefield("key", types.NewPtr(t.Key())),   // Used in range.go for TMAP.
+		makefield("elem", types.NewPtr(t.Elem())), // Used in range.go for TMAP.
+		makefield("t", types.Types[types.TUNSAFEPTR]),
+		makefield("h", types.NewPtr(hmap)),
+		makefield("buckets", types.NewPtr(bmap)),
+		makefield("bptr", types.NewPtr(bmap)),
+		makefield("overflow", types.Types[types.TUNSAFEPTR]),
+		makefield("oldoverflow", types.Types[types.TUNSAFEPTR]),
+		makefield("startBucket", types.Types[types.TUINTPTR]),
+		makefield("offset", types.Types[types.TUINT8]),
+		makefield("wrapped", types.Types[types.TBOOL]),
+		makefield("B", types.Types[types.TUINT8]),
+		makefield("i", types.Types[types.TUINT8]),
+		makefield("bucket", types.Types[types.TUINTPTR]),
+		makefield("checkBucket", types.Types[types.TUINTPTR]),
+	}
+
+	// build iterator struct holding the above fields
+	hiter := types.NewStruct(types.NoPkg, fields)
+	hiter.SetNoalg(true)
+	types.CalcSize(hiter)
+	if hiter.Width != int64(12*types.PtrSize) {
+		base.Fatalf("hash_iter size not correct %d %d", hiter.Width, 12*types.PtrSize)
+	}
+	t.MapType().Hiter = hiter
+	hiter.StructType().Map = t
+	return hiter
+}
+
+// methods returns the methods of the non-interface type t, sorted by name.
+// Generates stub functions as needed.
+func methods(t *types.Type) []*typeSig {
+	// method type
+	mt := types.ReceiverBaseType(t)
+
+	if mt == nil {
+		return nil
+	}
+	typecheck.CalcMethods(mt)
+
+	// type stored in interface word
+	it := t
+
+	if !types.IsDirectIface(it) {
+		it = types.NewPtr(t)
+	}
+
+	// make list of methods for t,
+	// generating code if necessary.
+	var ms []*typeSig
+	for _, f := range mt.AllMethods().Slice() {
+		if f.Sym == nil {
+			base.Fatalf("method with no sym on %v", mt)
+		}
+		if !f.IsMethod() {
+			base.Fatalf("non-method on %v method %v %v", mt, f.Sym, f)
+		}
+		if f.Type.Recv() == nil {
+			base.Fatalf("receiver with no type on %v method %v %v", mt, f.Sym, f)
+		}
+		if f.Nointerface() {
+			continue
+		}
+
+		// get receiver type for this particular method.
+		// if pointer receiver but non-pointer t and
+		// this is not an embedded pointer inside a struct,
+		// method does not apply.
+		if !types.IsMethodApplicable(t, f) {
+			continue
+		}
+
+		sig := &typeSig{
+			name:  f.Sym,
+			isym:  methodWrapper(it, f),
+			tsym:  methodWrapper(t, f),
+			type_: typecheck.NewMethodType(f.Type, t),
+			mtype: typecheck.NewMethodType(f.Type, nil),
+		}
+		ms = append(ms, sig)
+	}
+
+	return ms
+}
+
+// imethods returns the methods of the interface type t, sorted by name.
+func imethods(t *types.Type) []*typeSig {
+	var methods []*typeSig
+	for _, f := range t.AllMethods().Slice() {
+		if f.Type.Kind() != types.TFUNC || f.Sym == nil {
+			continue
+		}
+		if f.Sym.IsBlank() {
+			base.Fatalf("unexpected blank symbol in interface method set")
+		}
+		if n := len(methods); n > 0 {
+			last := methods[n-1]
+			if !last.name.Less(f.Sym) {
+				base.Fatalf("sigcmp vs sortinter %v %v", last.name, f.Sym)
+			}
+		}
+
+		sig := &typeSig{
+			name:  f.Sym,
+			mtype: f.Type,
+			type_: typecheck.NewMethodType(f.Type, nil),
+		}
+		methods = append(methods, sig)
+
+		// NOTE(rsc): Perhaps an oversight that
+		// IfaceType.Method is not in the reflect data.
+		// Generate the method body, so that compiled
+		// code can refer to it.
+		methodWrapper(t, f)
+	}
+
+	return methods
+}
+
+func dimportpath(p *types.Pkg) {
+	if p.Pathsym != nil {
+		return
+	}
+
+	// If we are compiling the runtime package, there are two runtime packages around
+	// -- localpkg and Pkgs.Runtime. We don't want to produce import path symbols for
+	// both of them, so just produce one for localpkg.
+	if base.Ctxt.Pkgpath == "runtime" && p == ir.Pkgs.Runtime {
+		return
+	}
+
+	str := p.Path
+	if p == types.LocalPkg {
+		// Note: myimportpath != "", or else dgopkgpath won't call dimportpath.
+		str = base.Ctxt.Pkgpath
+	}
+
+	s := base.Ctxt.Lookup("type..importpath." + p.Prefix + ".")
+	ot := dnameData(s, 0, str, "", nil, false)
+	objw.Global(s, int32(ot), obj.DUPOK|obj.RODATA)
+	s.Set(obj.AttrContentAddressable, true)
+	p.Pathsym = s
+}
+
+func dgopkgpath(s *obj.LSym, ot int, pkg *types.Pkg) int {
+	if pkg == nil {
+		return objw.Uintptr(s, ot, 0)
+	}
+
+	if pkg == types.LocalPkg && base.Ctxt.Pkgpath == "" {
+		// If we don't know the full import path of the package being compiled
+		// (i.e. -p was not passed on the compiler command line), emit a reference to
+		// type..importpath.""., which the linker will rewrite using the correct import path.
+		// Every package that imports this one directly defines the symbol.
+		// See also https://groups.google.com/forum/#!topic/golang-dev/myb9s53HxGQ.
+		ns := base.Ctxt.Lookup(`type..importpath."".`)
+		return objw.SymPtr(s, ot, ns, 0)
+	}
+
+	dimportpath(pkg)
+	return objw.SymPtr(s, ot, pkg.Pathsym, 0)
+}
+
+// dgopkgpathOff writes an offset relocation in s at offset ot to the pkg path symbol.
+func dgopkgpathOff(s *obj.LSym, ot int, pkg *types.Pkg) int {
+	if pkg == nil {
+		return objw.Uint32(s, ot, 0)
+	}
+	if pkg == types.LocalPkg && base.Ctxt.Pkgpath == "" {
+		// If we don't know the full import path of the package being compiled
+		// (i.e. -p was not passed on the compiler command line), emit a reference to
+		// type..importpath.""., which the linker will rewrite using the correct import path.
+		// Every package that imports this one directly defines the symbol.
+		// See also https://groups.google.com/forum/#!topic/golang-dev/myb9s53HxGQ.
+		ns := base.Ctxt.Lookup(`type..importpath."".`)
+		return objw.SymPtrOff(s, ot, ns)
+	}
+
+	dimportpath(pkg)
+	return objw.SymPtrOff(s, ot, pkg.Pathsym)
+}
+
+// dnameField dumps a reflect.name for a struct field.
+func dnameField(lsym *obj.LSym, ot int, spkg *types.Pkg, ft *types.Field) int {
+	if !types.IsExported(ft.Sym.Name) && ft.Sym.Pkg != spkg {
+		base.Fatalf("package mismatch for %v", ft.Sym)
+	}
+	nsym := dname(ft.Sym.Name, ft.Note, nil, types.IsExported(ft.Sym.Name))
+	return objw.SymPtr(lsym, ot, nsym, 0)
+}
+
+// dnameData writes the contents of a reflect.name into s at offset ot.
+func dnameData(s *obj.LSym, ot int, name, tag string, pkg *types.Pkg, exported bool) int {
+	if len(name) >= 1<<29 {
+		base.Fatalf("name too long: %d %s...", len(name), name[:1024])
+	}
+	if len(tag) >= 1<<29 {
+		base.Fatalf("tag too long: %d %s...", len(tag), tag[:1024])
+	}
+	var nameLen [binary.MaxVarintLen64]byte
+	nameLenLen := binary.PutUvarint(nameLen[:], uint64(len(name)))
+	var tagLen [binary.MaxVarintLen64]byte
+	tagLenLen := binary.PutUvarint(tagLen[:], uint64(len(tag)))
+
+	// Encode name and tag. See reflect/type.go for details.
+	var bits byte
+	l := 1 + nameLenLen + len(name)
+	if exported {
+		bits |= 1 << 0
+	}
+	if len(tag) > 0 {
+		l += tagLenLen + len(tag)
+		bits |= 1 << 1
+	}
+	if pkg != nil {
+		bits |= 1 << 2
+	}
+	b := make([]byte, l)
+	b[0] = bits
+	copy(b[1:], nameLen[:nameLenLen])
+	copy(b[1+nameLenLen:], name)
+	if len(tag) > 0 {
+		tb := b[1+nameLenLen+len(name):]
+		copy(tb, tagLen[:tagLenLen])
+		copy(tb[tagLenLen:], tag)
+	}
+
+	ot = int(s.WriteBytes(base.Ctxt, int64(ot), b))
+
+	if pkg != nil {
+		ot = dgopkgpathOff(s, ot, pkg)
+	}
+
+	return ot
+}
+
+var dnameCount int
+
+// dname creates a reflect.name for a struct field or method.
+func dname(name, tag string, pkg *types.Pkg, exported bool) *obj.LSym {
+	// Write out data as "type.." to signal two things to the
+	// linker, first that when dynamically linking, the symbol
+	// should be moved to a relro section, and second that the
+	// contents should not be decoded as a type.
+	sname := "type..namedata."
+	if pkg == nil {
+		// In the common case, share data with other packages.
+		if name == "" {
+			if exported {
+				sname += "-noname-exported." + tag
+			} else {
+				sname += "-noname-unexported." + tag
+			}
+		} else {
+			if exported {
+				sname += name + "." + tag
+			} else {
+				sname += name + "-" + tag
+			}
+		}
+	} else {
+		sname = fmt.Sprintf(`%s"".%d`, sname, dnameCount)
+		dnameCount++
+	}
+	s := base.Ctxt.Lookup(sname)
+	if len(s.P) > 0 {
+		return s
+	}
+	ot := dnameData(s, 0, name, tag, pkg, exported)
+	objw.Global(s, int32(ot), obj.DUPOK|obj.RODATA)
+	s.Set(obj.AttrContentAddressable, true)
+	return s
+}
+
+// dextratype dumps the fields of a runtime.uncommontype.
+// dataAdd is the offset in bytes after the header where the
+// backing array of the []method field is written (by dextratypeData).
+func dextratype(lsym *obj.LSym, ot int, t *types.Type, dataAdd int) int {
+	m := methods(t)
+	if t.Sym() == nil && len(m) == 0 {
+		return ot
+	}
+	noff := int(types.Rnd(int64(ot), int64(types.PtrSize)))
+	if noff != ot {
+		base.Fatalf("unexpected alignment in dextratype for %v", t)
+	}
+
+	for _, a := range m {
+		writeType(a.type_)
+	}
+
+	ot = dgopkgpathOff(lsym, ot, typePkg(t))
+
+	dataAdd += uncommonSize(t)
+	mcount := len(m)
+	if mcount != int(uint16(mcount)) {
+		base.Fatalf("too many methods on %v: %d", t, mcount)
+	}
+	xcount := sort.Search(mcount, func(i int) bool { return !types.IsExported(m[i].name.Name) })
+	if dataAdd != int(uint32(dataAdd)) {
+		base.Fatalf("methods are too far away on %v: %d", t, dataAdd)
+	}
+
+	ot = objw.Uint16(lsym, ot, uint16(mcount))
+	ot = objw.Uint16(lsym, ot, uint16(xcount))
+	ot = objw.Uint32(lsym, ot, uint32(dataAdd))
+	ot = objw.Uint32(lsym, ot, 0)
+	return ot
+}
+
+func typePkg(t *types.Type) *types.Pkg {
+	tsym := t.Sym()
+	if tsym == nil {
+		switch t.Kind() {
+		case types.TARRAY, types.TSLICE, types.TPTR, types.TCHAN:
+			if t.Elem() != nil {
+				tsym = t.Elem().Sym()
+			}
+		}
+	}
+	if tsym != nil && tsym.Pkg != types.BuiltinPkg {
+		return tsym.Pkg
+	}
+	return nil
+}
+
+// dextratypeData dumps the backing array for the []method field of
+// runtime.uncommontype.
+func dextratypeData(lsym *obj.LSym, ot int, t *types.Type) int {
+	for _, a := range methods(t) {
+		// ../../../../runtime/type.go:/method
+		exported := types.IsExported(a.name.Name)
+		var pkg *types.Pkg
+		if !exported && a.name.Pkg != typePkg(t) {
+			pkg = a.name.Pkg
+		}
+		nsym := dname(a.name.Name, "", pkg, exported)
+
+		ot = objw.SymPtrOff(lsym, ot, nsym)
+		ot = dmethodptrOff(lsym, ot, writeType(a.mtype))
+		ot = dmethodptrOff(lsym, ot, a.isym)
+		ot = dmethodptrOff(lsym, ot, a.tsym)
+	}
+	return ot
+}
+
+func dmethodptrOff(s *obj.LSym, ot int, x *obj.LSym) int {
+	objw.Uint32(s, ot, 0)
+	r := obj.Addrel(s)
+	r.Off = int32(ot)
+	r.Siz = 4
+	r.Sym = x
+	r.Type = objabi.R_METHODOFF
+	return ot + 4
+}
+
+var kinds = []int{
+	types.TINT:        objabi.KindInt,
+	types.TUINT:       objabi.KindUint,
+	types.TINT8:       objabi.KindInt8,
+	types.TUINT8:      objabi.KindUint8,
+	types.TINT16:      objabi.KindInt16,
+	types.TUINT16:     objabi.KindUint16,
+	types.TINT32:      objabi.KindInt32,
+	types.TUINT32:     objabi.KindUint32,
+	types.TINT64:      objabi.KindInt64,
+	types.TUINT64:     objabi.KindUint64,
+	types.TUINTPTR:    objabi.KindUintptr,
+	types.TFLOAT32:    objabi.KindFloat32,
+	types.TFLOAT64:    objabi.KindFloat64,
+	types.TBOOL:       objabi.KindBool,
+	types.TSTRING:     objabi.KindString,
+	types.TPTR:        objabi.KindPtr,
+	types.TSTRUCT:     objabi.KindStruct,
+	types.TINTER:      objabi.KindInterface,
+	types.TCHAN:       objabi.KindChan,
+	types.TMAP:        objabi.KindMap,
+	types.TARRAY:      objabi.KindArray,
+	types.TSLICE:      objabi.KindSlice,
+	types.TFUNC:       objabi.KindFunc,
+	types.TCOMPLEX64:  objabi.KindComplex64,
+	types.TCOMPLEX128: objabi.KindComplex128,
+	types.TUNSAFEPTR:  objabi.KindUnsafePointer,
+}
+
+// tflag is documented in reflect/type.go.
+//
+// tflag values must be kept in sync with copies in:
+//	cmd/compile/internal/reflectdata/reflect.go
+//	cmd/link/internal/ld/decodesym.go
+//	reflect/type.go
+//	runtime/type.go
+const (
+	tflagUncommon      = 1 << 0
+	tflagExtraStar     = 1 << 1
+	tflagNamed         = 1 << 2
+	tflagRegularMemory = 1 << 3
+)
+
+var (
+	memhashvarlen  *obj.LSym
+	memequalvarlen *obj.LSym
+)
+
+// dcommontype dumps the contents of a reflect.rtype (runtime._type).
+func dcommontype(lsym *obj.LSym, t *types.Type) int {
+	types.CalcSize(t)
+	eqfunc := geneq(t)
+
+	sptrWeak := true
+	var sptr *obj.LSym
+	if !t.IsPtr() || t.IsPtrElem() {
+		tptr := types.NewPtr(t)
+		if t.Sym() != nil || methods(tptr) != nil {
+			sptrWeak = false
+		}
+		sptr = writeType(tptr)
+	}
+
+	gcsym, useGCProg, ptrdata := dgcsym(t, true)
+	delete(gcsymset, t)
+
+	// ../../../../reflect/type.go:/^type.rtype
+	// actual type structure
+	//	type rtype struct {
+	//		size          uintptr
+	//		ptrdata       uintptr
+	//		hash          uint32
+	//		tflag         tflag
+	//		align         uint8
+	//		fieldAlign    uint8
+	//		kind          uint8
+	//		equal         func(unsafe.Pointer, unsafe.Pointer) bool
+	//		gcdata        *byte
+	//		str           nameOff
+	//		ptrToThis     typeOff
+	//	}
+	ot := 0
+	ot = objw.Uintptr(lsym, ot, uint64(t.Width))
+	ot = objw.Uintptr(lsym, ot, uint64(ptrdata))
+	ot = objw.Uint32(lsym, ot, types.TypeHash(t))
+
+	var tflag uint8
+	if uncommonSize(t) != 0 {
+		tflag |= tflagUncommon
+	}
+	if t.Sym() != nil && t.Sym().Name != "" {
+		tflag |= tflagNamed
+	}
+	if isRegularMemory(t) {
+		tflag |= tflagRegularMemory
+	}
+
+	exported := false
+	p := t.LongString()
+	// If we're writing out type T,
+	// we are very likely to write out type *T as well.
+	// Use the string "*T"[1:] for "T", so that the two
+	// share storage. This is a cheap way to reduce the
+	// amount of space taken up by reflect strings.
+	if !strings.HasPrefix(p, "*") {
+		p = "*" + p
+		tflag |= tflagExtraStar
+		if t.Sym() != nil {
+			exported = types.IsExported(t.Sym().Name)
+		}
+	} else {
+		if t.Elem() != nil && t.Elem().Sym() != nil {
+			exported = types.IsExported(t.Elem().Sym().Name)
+		}
+	}
+
+	ot = objw.Uint8(lsym, ot, tflag)
+
+	// runtime (and common sense) expects alignment to be a power of two.
+	i := int(t.Align)
+
+	if i == 0 {
+		i = 1
+	}
+	if i&(i-1) != 0 {
+		base.Fatalf("invalid alignment %d for %v", t.Align, t)
+	}
+	ot = objw.Uint8(lsym, ot, t.Align) // align
+	ot = objw.Uint8(lsym, ot, t.Align) // fieldAlign
+
+	i = kinds[t.Kind()]
+	if types.IsDirectIface(t) {
+		i |= objabi.KindDirectIface
+	}
+	if useGCProg {
+		i |= objabi.KindGCProg
+	}
+	ot = objw.Uint8(lsym, ot, uint8(i)) // kind
+	if eqfunc != nil {
+		ot = objw.SymPtr(lsym, ot, eqfunc, 0) // equality function
+	} else {
+		ot = objw.Uintptr(lsym, ot, 0) // type we can't do == with
+	}
+	ot = objw.SymPtr(lsym, ot, gcsym, 0) // gcdata
+
+	nsym := dname(p, "", nil, exported)
+	ot = objw.SymPtrOff(lsym, ot, nsym) // str
+	// ptrToThis
+	if sptr == nil {
+		ot = objw.Uint32(lsym, ot, 0)
+	} else if sptrWeak {
+		ot = objw.SymPtrWeakOff(lsym, ot, sptr)
+	} else {
+		ot = objw.SymPtrOff(lsym, ot, sptr)
+	}
+
+	return ot
+}
+
+// TrackSym returns the symbol for tracking use of field/method f, assumed
+// to be a member of struct/interface type t.
+func TrackSym(t *types.Type, f *types.Field) *obj.LSym {
+	return base.PkgLinksym("go.track", t.ShortString()+"."+f.Sym.Name, obj.ABI0)
+}
+
+func TypeSymPrefix(prefix string, t *types.Type) *types.Sym {
+	p := prefix + "." + t.ShortString()
+	s := types.TypeSymLookup(p)
+
+	// This function is for looking up type-related generated functions
+	// (e.g. eq and hash). Make sure they are indeed generated.
+	signatmu.Lock()
+	NeedRuntimeType(t)
+	signatmu.Unlock()
+
+	//print("algsym: %s -> %+S\n", p, s);
+
+	return s
+}
+
+func TypeSym(t *types.Type) *types.Sym {
+	if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() {
+		base.Fatalf("TypeSym %v", t)
+	}
+	if t.Kind() == types.TFUNC && t.Recv() != nil {
+		base.Fatalf("misuse of method type: %v", t)
+	}
+	s := types.TypeSym(t)
+	signatmu.Lock()
+	NeedRuntimeType(t)
+	signatmu.Unlock()
+	return s
+}
+
+func TypeLinksymPrefix(prefix string, t *types.Type) *obj.LSym {
+	return TypeSymPrefix(prefix, t).Linksym()
+}
+
+func TypeLinksymLookup(name string) *obj.LSym {
+	return types.TypeSymLookup(name).Linksym()
+}
+
+func TypeLinksym(t *types.Type) *obj.LSym {
+	return TypeSym(t).Linksym()
+}
+
+func TypePtr(t *types.Type) *ir.AddrExpr {
+	n := ir.NewLinksymExpr(base.Pos, TypeLinksym(t), types.Types[types.TUINT8])
+	return typecheck.Expr(typecheck.NodAddr(n)).(*ir.AddrExpr)
+}
+
+func ITabAddr(t, itype *types.Type) *ir.AddrExpr {
+	if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() || !itype.IsInterface() || itype.IsEmptyInterface() {
+		base.Fatalf("ITabAddr(%v, %v)", t, itype)
+	}
+	s, existed := ir.Pkgs.Itab.LookupOK(t.ShortString() + "," + itype.ShortString())
+	if !existed {
+		itabs = append(itabs, itabEntry{t: t, itype: itype, lsym: s.Linksym()})
+	}
+
+	lsym := s.Linksym()
+	n := ir.NewLinksymExpr(base.Pos, lsym, types.Types[types.TUINT8])
+	return typecheck.Expr(typecheck.NodAddr(n)).(*ir.AddrExpr)
+}
+
+// needkeyupdate reports whether map updates with t as a key
+// need the key to be updated.
+func needkeyupdate(t *types.Type) bool {
+	switch t.Kind() {
+	case types.TBOOL, types.TINT, types.TUINT, types.TINT8, types.TUINT8, types.TINT16, types.TUINT16, types.TINT32, types.TUINT32,
+		types.TINT64, types.TUINT64, types.TUINTPTR, types.TPTR, types.TUNSAFEPTR, types.TCHAN:
+		return false
+
+	case types.TFLOAT32, types.TFLOAT64, types.TCOMPLEX64, types.TCOMPLEX128, // floats and complex can be +0/-0
+		types.TINTER,
+		types.TSTRING: // strings might have smaller backing stores
+		return true
+
+	case types.TARRAY:
+		return needkeyupdate(t.Elem())
+
+	case types.TSTRUCT:
+		for _, t1 := range t.Fields().Slice() {
+			if needkeyupdate(t1.Type) {
+				return true
+			}
+		}
+		return false
+
+	default:
+		base.Fatalf("bad type for map key: %v", t)
+		return true
+	}
+}
+
+// hashMightPanic reports whether the hash of a map key of type t might panic.
+func hashMightPanic(t *types.Type) bool {
+	switch t.Kind() {
+	case types.TINTER:
+		return true
+
+	case types.TARRAY:
+		return hashMightPanic(t.Elem())
+
+	case types.TSTRUCT:
+		for _, t1 := range t.Fields().Slice() {
+			if hashMightPanic(t1.Type) {
+				return true
+			}
+		}
+		return false
+
+	default:
+		return false
+	}
+}
+
+// formalType replaces byte and rune aliases with real types.
+// They've been separate internally to make error messages
+// better, but we have to merge them in the reflect tables.
+func formalType(t *types.Type) *types.Type {
+	if t == types.ByteType || t == types.RuneType {
+		return types.Types[t.Kind()]
+	}
+	return t
+}
+
+func writeType(t *types.Type) *obj.LSym {
+	t = formalType(t)
+	if t.IsUntyped() {
+		base.Fatalf("writeType %v", t)
+	}
+
+	s := types.TypeSym(t)
+	lsym := s.Linksym()
+	if s.Siggen() {
+		return lsym
+	}
+	s.SetSiggen(true)
+
+	// special case (look for runtime below):
+	// when compiling package runtime,
+	// emit the type structures for int, float, etc.
+	tbase := t
+
+	if t.IsPtr() && t.Sym() == nil && t.Elem().Sym() != nil {
+		tbase = t.Elem()
+	}
+	dupok := 0
+	if tbase.Sym() == nil {
+		dupok = obj.DUPOK
+	}
+
+	if base.Ctxt.Pkgpath != "runtime" || (tbase != types.Types[tbase.Kind()] && 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 != types.LocalPkg {
+			if i := typecheck.BaseTypeIndex(t); i >= 0 {
+				lsym.Pkg = tbase.Sym().Pkg.Prefix
+				lsym.SymIdx = int32(i)
+				lsym.Set(obj.AttrIndexed, true)
+			}
+			return lsym
+		}
+		// TODO(mdempsky): Investigate whether this can happen.
+		if tbase.Kind() == types.TFORW {
+			return lsym
+		}
+	}
+
+	ot := 0
+	switch t.Kind() {
+	default:
+		ot = dcommontype(lsym, t)
+		ot = dextratype(lsym, ot, t, 0)
+
+	case types.TARRAY:
+		// ../../../../runtime/type.go:/arrayType
+		s1 := writeType(t.Elem())
+		t2 := types.NewSlice(t.Elem())
+		s2 := writeType(t2)
+		ot = dcommontype(lsym, t)
+		ot = objw.SymPtr(lsym, ot, s1, 0)
+		ot = objw.SymPtr(lsym, ot, s2, 0)
+		ot = objw.Uintptr(lsym, ot, uint64(t.NumElem()))
+		ot = dextratype(lsym, ot, t, 0)
+
+	case types.TSLICE:
+		// ../../../../runtime/type.go:/sliceType
+		s1 := writeType(t.Elem())
+		ot = dcommontype(lsym, t)
+		ot = objw.SymPtr(lsym, ot, s1, 0)
+		ot = dextratype(lsym, ot, t, 0)
+
+	case types.TCHAN:
+		// ../../../../runtime/type.go:/chanType
+		s1 := writeType(t.Elem())
+		ot = dcommontype(lsym, t)
+		ot = objw.SymPtr(lsym, ot, s1, 0)
+		ot = objw.Uintptr(lsym, ot, uint64(t.ChanDir()))
+		ot = dextratype(lsym, ot, t, 0)
+
+	case types.TFUNC:
+		for _, t1 := range t.Recvs().Fields().Slice() {
+			writeType(t1.Type)
+		}
+		isddd := false
+		for _, t1 := range t.Params().Fields().Slice() {
+			isddd = t1.IsDDD()
+			writeType(t1.Type)
+		}
+		for _, t1 := range t.Results().Fields().Slice() {
+			writeType(t1.Type)
+		}
+
+		ot = dcommontype(lsym, t)
+		inCount := t.NumRecvs() + t.NumParams()
+		outCount := t.NumResults()
+		if isddd {
+			outCount |= 1 << 15
+		}
+		ot = objw.Uint16(lsym, ot, uint16(inCount))
+		ot = objw.Uint16(lsym, ot, uint16(outCount))
+		if types.PtrSize == 8 {
+			ot += 4 // align for *rtype
+		}
+
+		dataAdd := (inCount + t.NumResults()) * types.PtrSize
+		ot = dextratype(lsym, ot, t, dataAdd)
+
+		// Array of rtype pointers follows funcType.
+		for _, t1 := range t.Recvs().Fields().Slice() {
+			ot = objw.SymPtr(lsym, ot, writeType(t1.Type), 0)
+		}
+		for _, t1 := range t.Params().Fields().Slice() {
+			ot = objw.SymPtr(lsym, ot, writeType(t1.Type), 0)
+		}
+		for _, t1 := range t.Results().Fields().Slice() {
+			ot = objw.SymPtr(lsym, ot, writeType(t1.Type), 0)
+		}
+
+	case types.TINTER:
+		m := imethods(t)
+		n := len(m)
+		for _, a := range m {
+			writeType(a.type_)
+		}
+
+		// ../../../../runtime/type.go:/interfaceType
+		ot = dcommontype(lsym, t)
+
+		var tpkg *types.Pkg
+		if t.Sym() != nil && t != types.Types[t.Kind()] && t != types.ErrorType {
+			tpkg = t.Sym().Pkg
+		}
+		ot = dgopkgpath(lsym, ot, tpkg)
+
+		ot = objw.SymPtr(lsym, ot, lsym, ot+3*types.PtrSize+uncommonSize(t))
+		ot = objw.Uintptr(lsym, ot, uint64(n))
+		ot = objw.Uintptr(lsym, ot, uint64(n))
+		dataAdd := imethodSize() * n
+		ot = dextratype(lsym, ot, t, dataAdd)
+
+		for _, a := range m {
+			// ../../../../runtime/type.go:/imethod
+			exported := types.IsExported(a.name.Name)
+			var pkg *types.Pkg
+			if !exported && a.name.Pkg != tpkg {
+				pkg = a.name.Pkg
+			}
+			nsym := dname(a.name.Name, "", pkg, exported)
+
+			ot = objw.SymPtrOff(lsym, ot, nsym)
+			ot = objw.SymPtrOff(lsym, ot, writeType(a.type_))
+		}
+
+	// ../../../../runtime/type.go:/mapType
+	case types.TMAP:
+		s1 := writeType(t.Key())
+		s2 := writeType(t.Elem())
+		s3 := writeType(MapBucketType(t))
+		hasher := genhash(t.Key())
+
+		ot = dcommontype(lsym, t)
+		ot = objw.SymPtr(lsym, ot, s1, 0)
+		ot = objw.SymPtr(lsym, ot, s2, 0)
+		ot = objw.SymPtr(lsym, ot, s3, 0)
+		ot = objw.SymPtr(lsym, ot, hasher, 0)
+		var flags uint32
+		// Note: flags must match maptype accessors in ../../../../runtime/type.go
+		// and maptype builder in ../../../../reflect/type.go:MapOf.
+		if t.Key().Width > MAXKEYSIZE {
+			ot = objw.Uint8(lsym, ot, uint8(types.PtrSize))
+			flags |= 1 // indirect key
+		} else {
+			ot = objw.Uint8(lsym, ot, uint8(t.Key().Width))
+		}
+
+		if t.Elem().Width > MAXELEMSIZE {
+			ot = objw.Uint8(lsym, ot, uint8(types.PtrSize))
+			flags |= 2 // indirect value
+		} else {
+			ot = objw.Uint8(lsym, ot, uint8(t.Elem().Width))
+		}
+		ot = objw.Uint16(lsym, ot, uint16(MapBucketType(t).Width))
+		if types.IsReflexive(t.Key()) {
+			flags |= 4 // reflexive key
+		}
+		if needkeyupdate(t.Key()) {
+			flags |= 8 // need key update
+		}
+		if hashMightPanic(t.Key()) {
+			flags |= 16 // hash might panic
+		}
+		ot = objw.Uint32(lsym, ot, flags)
+		ot = dextratype(lsym, ot, t, 0)
+		if u := t.Underlying(); u != t {
+			// If t is a named map type, also keep the underlying map
+			// type live in the binary. This is important to make sure that
+			// a named map and that same map cast to its underlying type via
+			// reflection, use the same hash function. See issue 37716.
+			r := obj.Addrel(lsym)
+			r.Sym = writeType(u)
+			r.Type = objabi.R_KEEP
+		}
+
+	case types.TPTR:
+		if t.Elem().Kind() == types.TANY {
+			// ../../../../runtime/type.go:/UnsafePointerType
+			ot = dcommontype(lsym, t)
+			ot = dextratype(lsym, ot, t, 0)
+
+			break
+		}
+
+		// ../../../../runtime/type.go:/ptrType
+		s1 := writeType(t.Elem())
+
+		ot = dcommontype(lsym, t)
+		ot = objw.SymPtr(lsym, ot, s1, 0)
+		ot = dextratype(lsym, ot, t, 0)
+
+	// ../../../../runtime/type.go:/structType
+	// for security, only the exported fields.
+	case types.TSTRUCT:
+		fields := t.Fields().Slice()
+		for _, t1 := range fields {
+			writeType(t1.Type)
+		}
+
+		// 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 !types.IsExported(f.Sym.Name) {
+				spkg = f.Sym.Pkg
+				break
+			}
+		}
+
+		ot = dcommontype(lsym, t)
+		ot = dgopkgpath(lsym, ot, spkg)
+		ot = objw.SymPtr(lsym, ot, lsym, ot+3*types.PtrSize+uncommonSize(t))
+		ot = objw.Uintptr(lsym, ot, uint64(len(fields)))
+		ot = objw.Uintptr(lsym, ot, uint64(len(fields)))
+
+		dataAdd := len(fields) * structfieldSize()
+		ot = dextratype(lsym, ot, t, dataAdd)
+
+		for _, f := range fields {
+			// ../../../../runtime/type.go:/structField
+			ot = dnameField(lsym, ot, spkg, f)
+			ot = objw.SymPtr(lsym, ot, writeType(f.Type), 0)
+			offsetAnon := uint64(f.Offset) << 1
+			if offsetAnon>>1 != uint64(f.Offset) {
+				base.Fatalf("%v: bad field offset for %s", t, f.Sym.Name)
+			}
+			if f.Embedded != 0 {
+				offsetAnon |= 1
+			}
+			ot = objw.Uintptr(lsym, ot, offsetAnon)
+		}
+	}
+
+	ot = dextratypeData(lsym, ot, t)
+	objw.Global(lsym, int32(ot), int16(dupok|obj.RODATA))
+
+	// The linker will leave a table of all the typelinks for
+	// types in the binary, so the runtime can find them.
+	//
+	// When buildmode=shared, all types are in typelinks so the
+	// runtime can deduplicate type pointers.
+	keep := base.Ctxt.Flag_dynlink
+	if !keep && t.Sym() == nil {
+		// For an unnamed type, we only need the link if the type can
+		// be created at run time by reflect.PtrTo and similar
+		// functions. If the type exists in the program, those
+		// functions must return the existing type structure rather
+		// than creating a new one.
+		switch t.Kind() {
+		case types.TPTR, types.TARRAY, types.TCHAN, types.TFUNC, types.TMAP, types.TSLICE, types.TSTRUCT:
+			keep = true
+		}
+	}
+	// Do not put Noalg types in typelinks.  See issue #22605.
+	if types.TypeHasNoAlg(t) {
+		keep = false
+	}
+	lsym.Set(obj.AttrMakeTypelink, keep)
+
+	return lsym
+}
+
+// InterfaceMethodOffset returns the offset of the i-th method in the interface
+// type descriptor, ityp.
+func InterfaceMethodOffset(ityp *types.Type, i int64) int64 {
+	// interface type descriptor layout is struct {
+	//   _type        // commonSize
+	//   pkgpath      // 1 word
+	//   []imethod    // 3 words (pointing to [...]imethod below)
+	//   uncommontype // uncommonSize
+	//   [...]imethod
+	// }
+	// The size of imethod is 8.
+	return int64(commonSize()+4*types.PtrSize+uncommonSize(ityp)) + i*8
+}
+
+// for each itabEntry, gather the methods on
+// the concrete type that implement the interface
+func CompileITabs() {
+	for i := range itabs {
+		tab := &itabs[i]
+		methods := genfun(tab.t, tab.itype)
+		if len(methods) == 0 {
+			continue
+		}
+		tab.entries = methods
+	}
+}
+
+// for the given concrete type and interface
+// type, return the (sorted) set of methods
+// on the concrete type that implement the interface
+func genfun(t, it *types.Type) []*obj.LSym {
+	if t == nil || it == nil {
+		return nil
+	}
+	sigs := imethods(it)
+	methods := methods(t)
+	out := make([]*obj.LSym, 0, len(sigs))
+	// TODO(mdempsky): Short circuit before calling methods(t)?
+	// See discussion on CL 105039.
+	if len(sigs) == 0 {
+		return nil
+	}
+
+	// both sigs and methods are sorted by name,
+	// so we can find the intersect in a single pass
+	for _, m := range methods {
+		if m.name == sigs[0].name {
+			out = append(out, m.isym)
+			sigs = sigs[1:]
+			if len(sigs) == 0 {
+				break
+			}
+		}
+	}
+
+	if len(sigs) != 0 {
+		base.Fatalf("incomplete itab")
+	}
+
+	return out
+}
+
+// ITabSym uses the information gathered in
+// CompileITabs to de-virtualize interface methods.
+// Since this is called by the SSA backend, it shouldn't
+// generate additional Nodes, Syms, etc.
+func ITabSym(it *obj.LSym, offset int64) *obj.LSym {
+	var syms []*obj.LSym
+	if it == nil {
+		return nil
+	}
+
+	for i := range itabs {
+		e := &itabs[i]
+		if e.lsym == it {
+			syms = e.entries
+			break
+		}
+	}
+	if syms == nil {
+		return nil
+	}
+
+	// keep this arithmetic in sync with *itab layout
+	methodnum := int((offset - 2*int64(types.PtrSize) - 8) / int64(types.PtrSize))
+	if methodnum >= len(syms) {
+		return nil
+	}
+	return syms[methodnum]
+}
+
+// NeedRuntimeType ensures that a runtime type descriptor is emitted for t.
+func NeedRuntimeType(t *types.Type) {
+	if t.HasTParam() {
+		// Generic types don't have a runtime type descriptor (but will
+		// have a dictionary)
+		return
+	}
+	if _, ok := signatset[t]; !ok {
+		signatset[t] = struct{}{}
+		signatslice = append(signatslice, t)
+	}
+}
+
+func WriteRuntimeTypes() {
+	// Process signatset. Use a loop, as writeType adds
+	// entries to signatset while it is being processed.
+	signats := make([]typeAndStr, len(signatslice))
+	for len(signatslice) > 0 {
+		signats = signats[:0]
+		// Transfer entries to a slice and sort, for reproducible builds.
+		for _, t := range signatslice {
+			signats = append(signats, typeAndStr{t: t, short: types.TypeSymName(t), regular: t.String()})
+			delete(signatset, t)
+		}
+		signatslice = signatslice[:0]
+		sort.Sort(typesByString(signats))
+		for _, ts := range signats {
+			t := ts.t
+			writeType(t)
+			if t.Sym() != nil {
+				writeType(types.NewPtr(t))
+			}
+		}
+	}
+
+	// Emit GC data symbols.
+	gcsyms := make([]typeAndStr, 0, len(gcsymset))
+	for t := range gcsymset {
+		gcsyms = append(gcsyms, typeAndStr{t: t, short: types.TypeSymName(t), regular: t.String()})
+	}
+	sort.Sort(typesByString(gcsyms))
+	for _, ts := range gcsyms {
+		dgcsym(ts.t, true)
+	}
+}
+
+func WriteTabs() {
+	// process itabs
+	for _, i := range itabs {
+		// dump empty itab symbol into i.sym
+		// type itab struct {
+		//   inter  *interfacetype
+		//   _type  *_type
+		//   hash   uint32
+		//   _      [4]byte
+		//   fun    [1]uintptr // variable sized
+		// }
+		o := objw.SymPtr(i.lsym, 0, writeType(i.itype), 0)
+		o = objw.SymPtr(i.lsym, o, writeType(i.t), 0)
+		o = objw.Uint32(i.lsym, o, types.TypeHash(i.t)) // copy of type hash
+		o += 4                                          // skip unused field
+		for _, fn := range genfun(i.t, i.itype) {
+			o = objw.SymPtrWeak(i.lsym, o, fn, 0) // method pointer for each method
+		}
+		// Nothing writes static itabs, so they are read only.
+		objw.Global(i.lsym, int32(o), int16(obj.DUPOK|obj.RODATA))
+		i.lsym.Set(obj.AttrContentAddressable, true)
+	}
+
+	// process ptabs
+	if types.LocalPkg.Name == "main" && len(ptabs) > 0 {
+		ot := 0
+		s := base.Ctxt.Lookup("go.plugin.tabs")
+		for _, p := range ptabs {
+			// Dump ptab symbol into go.pluginsym package.
+			//
+			// type ptab struct {
+			//	name nameOff
+			//	typ  typeOff // pointer to symbol
+			// }
+			nsym := dname(p.Sym().Name, "", nil, true)
+			t := p.Type()
+			if p.Class != ir.PFUNC {
+				t = types.NewPtr(t)
+			}
+			tsym := writeType(t)
+			ot = objw.SymPtrOff(s, ot, nsym)
+			ot = objw.SymPtrOff(s, ot, tsym)
+			// Plugin exports symbols as interfaces. Mark their types
+			// as UsedInIface.
+			tsym.Set(obj.AttrUsedInIface, true)
+		}
+		objw.Global(s, int32(ot), int16(obj.RODATA))
+
+		ot = 0
+		s = base.Ctxt.Lookup("go.plugin.exports")
+		for _, p := range ptabs {
+			ot = objw.SymPtr(s, ot, p.Linksym(), 0)
+		}
+		objw.Global(s, int32(ot), int16(obj.RODATA))
+	}
+}
+
+func WriteImportStrings() {
+	// generate import strings for imported packages
+	for _, p := range types.ImportedPkgList() {
+		dimportpath(p)
+	}
+}
+
+func WriteBasicTypes() {
+	// do basic types if compiling package runtime.
+	// they have to be in at least one package,
+	// and runtime is always loaded implicitly,
+	// so this is as good as any.
+	// another possible choice would be package main,
+	// but using runtime means fewer copies in object files.
+	if base.Ctxt.Pkgpath == "runtime" {
+		for i := types.Kind(1); i <= types.TBOOL; i++ {
+			writeType(types.NewPtr(types.Types[i]))
+		}
+		writeType(types.NewPtr(types.Types[types.TSTRING]))
+		writeType(types.NewPtr(types.Types[types.TUNSAFEPTR]))
+
+		// emit type structs for error and func(error) string.
+		// The latter is the type of an auto-generated wrapper.
+		writeType(types.NewPtr(types.ErrorType))
+
+		writeType(types.NewSignature(types.NoPkg, nil, nil, []*types.Field{
+			types.NewField(base.Pos, nil, types.ErrorType),
+		}, []*types.Field{
+			types.NewField(base.Pos, nil, types.Types[types.TSTRING]),
+		}))
+
+		// add paths for runtime and main, which 6l imports implicitly.
+		dimportpath(ir.Pkgs.Runtime)
+
+		if base.Flag.Race {
+			dimportpath(types.NewPkg("runtime/race", ""))
+		}
+		if base.Flag.MSan {
+			dimportpath(types.NewPkg("runtime/msan", ""))
+		}
+
+		dimportpath(types.NewPkg("main", ""))
+	}
+}
+
+type typeAndStr struct {
+	t       *types.Type
+	short   string
+	regular string
+}
+
+type typesByString []typeAndStr
+
+func (a typesByString) Len() int { return len(a) }
+func (a typesByString) Less(i, j int) bool {
+	if a[i].short != a[j].short {
+		return a[i].short < a[j].short
+	}
+	// When the only difference between the types is whether
+	// they refer to byte or uint8, such as **byte vs **uint8,
+	// the types' ShortStrings can be identical.
+	// To preserve deterministic sort ordering, sort these by String().
+	if a[i].regular != a[j].regular {
+		return a[i].regular < a[j].regular
+	}
+	// Identical anonymous interfaces defined in different locations
+	// will be equal for the above checks, but different in DWARF output.
+	// Sort by source position to ensure deterministic order.
+	// See issues 27013 and 30202.
+	if a[i].t.Kind() == types.TINTER && a[i].t.AllMethods().Len() > 0 {
+		return a[i].t.AllMethods().Index(0).Pos.Before(a[j].t.AllMethods().Index(0).Pos)
+	}
+	return false
+}
+func (a typesByString) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+// maxPtrmaskBytes is the maximum length of a GC ptrmask bitmap,
+// which holds 1-bit entries describing where pointers are in a given type.
+// Above this length, the GC information is recorded as a GC program,
+// which can express repetition compactly. In either form, the
+// information is used by the runtime to initialize the heap bitmap,
+// and for large types (like 128 or more words), they are roughly the
+// same speed. GC programs are never much larger and often more
+// compact. (If large arrays are involved, they can be arbitrarily
+// more compact.)
+//
+// The cutoff must be large enough that any allocation large enough to
+// use a GC program is large enough that it does not share heap bitmap
+// bytes with any other objects, allowing the GC program execution to
+// assume an aligned start and not use atomic operations. In the current
+// runtime, this means all malloc size classes larger than the cutoff must
+// be multiples of four words. On 32-bit systems that's 16 bytes, and
+// all size classes >= 16 bytes are 16-byte aligned, so no real constraint.
+// On 64-bit systems, that's 32 bytes, and 32-byte alignment is guaranteed
+// for size classes >= 256 bytes. On a 64-bit system, 256 bytes allocated
+// is 32 pointers, the bits for which fit in 4 bytes. So maxPtrmaskBytes
+// must be >= 4.
+//
+// We used to use 16 because the GC programs do have some constant overhead
+// to get started, and processing 128 pointers seems to be enough to
+// amortize that overhead well.
+//
+// To make sure that the runtime's chansend can call typeBitsBulkBarrier,
+// we raised the limit to 2048, so that even 32-bit systems are guaranteed to
+// use bitmaps for objects up to 64 kB in size.
+//
+// Also known to reflect/type.go.
+//
+const maxPtrmaskBytes = 2048
+
+// GCSym returns a data symbol containing GC information for type t, along
+// with a boolean reporting whether the UseGCProg bit should be set in the
+// type kind, and the ptrdata field to record in the reflect type information.
+// GCSym may be called in concurrent backend, so it does not emit the symbol
+// content.
+func GCSym(t *types.Type) (lsym *obj.LSym, useGCProg bool, ptrdata int64) {
+	// Record that we need to emit the GC symbol.
+	gcsymmu.Lock()
+	if _, ok := gcsymset[t]; !ok {
+		gcsymset[t] = struct{}{}
+	}
+	gcsymmu.Unlock()
+
+	return dgcsym(t, false)
+}
+
+// dgcsym returns a data symbol containing GC information for type t, along
+// with a boolean reporting whether the UseGCProg bit should be set in the
+// type kind, and the ptrdata field to record in the reflect type information.
+// When write is true, it writes the symbol data.
+func dgcsym(t *types.Type, write bool) (lsym *obj.LSym, useGCProg bool, ptrdata int64) {
+	ptrdata = types.PtrDataSize(t)
+	if ptrdata/int64(types.PtrSize) <= maxPtrmaskBytes*8 {
+		lsym = dgcptrmask(t, write)
+		return
+	}
+
+	useGCProg = true
+	lsym, ptrdata = dgcprog(t, write)
+	return
+}
+
+// dgcptrmask emits and returns the symbol containing a pointer mask for type t.
+func dgcptrmask(t *types.Type, write bool) *obj.LSym {
+	ptrmask := make([]byte, (types.PtrDataSize(t)/int64(types.PtrSize)+7)/8)
+	fillptrmask(t, ptrmask)
+	p := fmt.Sprintf("runtime.gcbits.%x", ptrmask)
+
+	lsym := base.Ctxt.Lookup(p)
+	if write && !lsym.OnList() {
+		for i, x := range ptrmask {
+			objw.Uint8(lsym, i, x)
+		}
+		objw.Global(lsym, int32(len(ptrmask)), obj.DUPOK|obj.RODATA|obj.LOCAL)
+		lsym.Set(obj.AttrContentAddressable, true)
+	}
+	return lsym
+}
+
+// fillptrmask fills in ptrmask with 1s corresponding to the
+// word offsets in t that hold pointers.
+// ptrmask is assumed to fit at least types.PtrDataSize(t)/PtrSize bits.
+func fillptrmask(t *types.Type, ptrmask []byte) {
+	for i := range ptrmask {
+		ptrmask[i] = 0
+	}
+	if !t.HasPointers() {
+		return
+	}
+
+	vec := bitvec.New(8 * int32(len(ptrmask)))
+	typebits.Set(t, 0, vec)
+
+	nptr := types.PtrDataSize(t) / int64(types.PtrSize)
+	for i := int64(0); i < nptr; i++ {
+		if vec.Get(int32(i)) {
+			ptrmask[i/8] |= 1 << (uint(i) % 8)
+		}
+	}
+}
+
+// dgcprog emits and returns the symbol containing a GC program for type t
+// along with the size of the data described by the program (in the range
+// [types.PtrDataSize(t), t.Width]).
+// In practice, the size is types.PtrDataSize(t) except for non-trivial arrays.
+// For non-trivial arrays, the program describes the full t.Width size.
+func dgcprog(t *types.Type, write bool) (*obj.LSym, int64) {
+	types.CalcSize(t)
+	if t.Width == types.BADWIDTH {
+		base.Fatalf("dgcprog: %v badwidth", t)
+	}
+	lsym := TypeLinksymPrefix(".gcprog", t)
+	var p gcProg
+	p.init(lsym, write)
+	p.emit(t, 0)
+	offset := p.w.BitIndex() * int64(types.PtrSize)
+	p.end()
+	if ptrdata := types.PtrDataSize(t); offset < ptrdata || offset > t.Width {
+		base.Fatalf("dgcprog: %v: offset=%d but ptrdata=%d size=%d", t, offset, ptrdata, t.Width)
+	}
+	return lsym, offset
+}
+
+type gcProg struct {
+	lsym   *obj.LSym
+	symoff int
+	w      gcprog.Writer
+	write  bool
+}
+
+func (p *gcProg) init(lsym *obj.LSym, write bool) {
+	p.lsym = lsym
+	p.write = write && !lsym.OnList()
+	p.symoff = 4 // first 4 bytes hold program length
+	if !write {
+		p.w.Init(func(byte) {})
+		return
+	}
+	p.w.Init(p.writeByte)
+	if base.Debug.GCProg > 0 {
+		fmt.Fprintf(os.Stderr, "compile: start GCProg for %v\n", lsym)
+		p.w.Debug(os.Stderr)
+	}
+}
+
+func (p *gcProg) writeByte(x byte) {
+	p.symoff = objw.Uint8(p.lsym, p.symoff, x)
+}
+
+func (p *gcProg) end() {
+	p.w.End()
+	if !p.write {
+		return
+	}
+	objw.Uint32(p.lsym, 0, uint32(p.symoff-4))
+	objw.Global(p.lsym, int32(p.symoff), obj.DUPOK|obj.RODATA|obj.LOCAL)
+	p.lsym.Set(obj.AttrContentAddressable, true)
+	if base.Debug.GCProg > 0 {
+		fmt.Fprintf(os.Stderr, "compile: end GCProg for %v\n", p.lsym)
+	}
+}
+
+func (p *gcProg) emit(t *types.Type, offset int64) {
+	types.CalcSize(t)
+	if !t.HasPointers() {
+		return
+	}
+	if t.Width == int64(types.PtrSize) {
+		p.w.Ptr(offset / int64(types.PtrSize))
+		return
+	}
+	switch t.Kind() {
+	default:
+		base.Fatalf("gcProg.emit: unexpected type %v", t)
+
+	case types.TSTRING:
+		p.w.Ptr(offset / int64(types.PtrSize))
+
+	case types.TINTER:
+		// Note: the first word isn't a pointer. See comment in typebits.Set
+		p.w.Ptr(offset/int64(types.PtrSize) + 1)
+
+	case types.TSLICE:
+		p.w.Ptr(offset / int64(types.PtrSize))
+
+	case types.TARRAY:
+		if t.NumElem() == 0 {
+			// should have been handled by haspointers check above
+			base.Fatalf("gcProg.emit: empty array")
+		}
+
+		// Flatten array-of-array-of-array to just a big array by multiplying counts.
+		count := t.NumElem()
+		elem := t.Elem()
+		for elem.IsArray() {
+			count *= elem.NumElem()
+			elem = elem.Elem()
+		}
+
+		if !p.w.ShouldRepeat(elem.Width/int64(types.PtrSize), count) {
+			// Cheaper to just emit the bits.
+			for i := int64(0); i < count; i++ {
+				p.emit(elem, offset+i*elem.Width)
+			}
+			return
+		}
+		p.emit(elem, offset)
+		p.w.ZeroUntil((offset + elem.Width) / int64(types.PtrSize))
+		p.w.Repeat(elem.Width/int64(types.PtrSize), count-1)
+
+	case types.TSTRUCT:
+		for _, t1 := range t.Fields().Slice() {
+			p.emit(t1.Type, offset+t1.Offset)
+		}
+	}
+}
+
+// ZeroAddr returns the address of a symbol with at least
+// size bytes of zeros.
+func ZeroAddr(size int64) ir.Node {
+	if size >= 1<<31 {
+		base.Fatalf("map elem too big %d", size)
+	}
+	if ZeroSize < size {
+		ZeroSize = size
+	}
+	lsym := base.PkgLinksym("go.map", "zero", obj.ABI0)
+	x := ir.NewLinksymExpr(base.Pos, lsym, types.Types[types.TUINT8])
+	return typecheck.Expr(typecheck.NodAddr(x))
+}
+
+func CollectPTabs() {
+	if !base.Ctxt.Flag_dynlink || types.LocalPkg.Name != "main" {
+		return
+	}
+	for _, exportn := range typecheck.Target.Exports {
+		s := exportn.Sym()
+		nn := ir.AsNode(s.Def)
+		if nn == nil {
+			continue
+		}
+		if nn.Op() != ir.ONAME {
+			continue
+		}
+		n := nn.(*ir.Name)
+		if !types.IsExported(s.Name) {
+			continue
+		}
+		if s.Pkg.Name != "main" {
+			continue
+		}
+		ptabs = append(ptabs, n)
+	}
+}
+
+// Generate a wrapper function to convert from
+// a receiver of type T to a receiver of type U.
+// That is,
+//
+//	func (t T) M() {
+//		...
+//	}
+//
+// already exists; this function generates
+//
+//	func (u U) M() {
+//		u.M()
+//	}
+//
+// where the types T and U are such that u.M() is valid
+// and calls the T.M method.
+// The resulting function is for use in method tables.
+//
+//	rcvr - U
+//	method - M func (t T)(), a TFIELD type struct
+func methodWrapper(rcvr *types.Type, method *types.Field) *obj.LSym {
+	newnam := ir.MethodSym(rcvr, method.Sym)
+	lsym := newnam.Linksym()
+	if newnam.Siggen() {
+		return lsym
+	}
+	newnam.SetSiggen(true)
+
+	if types.Identical(rcvr, method.Type.Recv().Type) {
+		return lsym
+	}
+
+	// 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 != types.LocalPkg {
+		return lsym
+	}
+
+	// Only generate I.M wrappers for I in I's own package
+	// but keep doing it for error.Error (was issue #29304).
+	if rcvr.IsInterface() && rcvr.Sym() != nil && rcvr.Sym().Pkg != types.LocalPkg && rcvr != types.ErrorType {
+		return lsym
+	}
+
+	base.Pos = base.AutogeneratedPos
+	typecheck.DeclContext = ir.PEXTERN
+
+	tfn := ir.NewFuncType(base.Pos,
+		ir.NewField(base.Pos, typecheck.Lookup(".this"), nil, rcvr),
+		typecheck.NewFuncParams(method.Type.Params(), true),
+		typecheck.NewFuncParams(method.Type.Results(), false))
+
+	// TODO(austin): SelectorExpr may have created one or more
+	// ir.Names for these already with a nil Func field. We should
+	// consolidate these and always attach a Func to the Name.
+	fn := typecheck.DeclFunc(newnam, tfn)
+	fn.SetDupok(true)
+
+	nthis := ir.AsNode(tfn.Type().Recv().Nname)
+
+	methodrcvr := method.Type.Recv().Type
+
+	// generate nil pointer check for better error
+	if rcvr.IsPtr() && rcvr.Elem() == methodrcvr {
+		// generating wrapper from *T to T.
+		n := ir.NewIfStmt(base.Pos, nil, nil, nil)
+		n.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, nthis, typecheck.NodNil())
+		call := ir.NewCallExpr(base.Pos, ir.OCALL, typecheck.LookupRuntime("panicwrap"), nil)
+		n.Body = []ir.Node{call}
+		fn.Body.Append(n)
+	}
+
+	dot := typecheck.AddImplicitDots(ir.NewSelectorExpr(base.Pos, ir.OXDOT, nthis, method.Sym))
+
+	// generate call
+	// It's not possible to use a tail call when dynamic linking on ppc64le. The
+	// bad scenario is when a local call is made to the wrapper: the wrapper will
+	// call the implementation, which might be in a different module and so set
+	// the TOC to the appropriate value for that module. But if it returns
+	// directly to the wrapper's caller, nothing will reset it to the correct
+	// value for that function.
+	//
+	// Disable tailcall for RegabiArgs for now. The IR does not connect the
+	// arguments with the OTAILCALL node, and the arguments are not marshaled
+	// correctly.
+	if !base.Flag.Cfg.Instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !types.IsInterfaceMethod(method.Type) && !(base.Ctxt.Arch.Name == "ppc64le" && base.Ctxt.Flag_dynlink) && !buildcfg.Experiment.RegabiArgs {
+		// generate tail call: adjust pointer receiver and jump to embedded method.
+		left := dot.X // skip final .M
+		if !left.Type().IsPtr() {
+			left = typecheck.NodAddr(left)
+		}
+		as := ir.NewAssignStmt(base.Pos, nthis, typecheck.ConvNop(left, rcvr))
+		fn.Body.Append(as)
+		fn.Body.Append(ir.NewTailCallStmt(base.Pos, method.Nname.(*ir.Name)))
+	} else {
+		fn.SetWrapper(true) // ignore frame for panic+recover matching
+		call := ir.NewCallExpr(base.Pos, ir.OCALL, dot, nil)
+		call.Args = ir.ParamNames(tfn.Type())
+		call.IsDDD = tfn.Type().IsVariadic()
+		if method.Type.NumResults() > 0 {
+			ret := ir.NewReturnStmt(base.Pos, nil)
+			ret.Results = []ir.Node{call}
+			fn.Body.Append(ret)
+		} else {
+			fn.Body.Append(call)
+		}
+	}
+
+	typecheck.FinishFuncBody()
+	if base.Debug.DclStack != 0 {
+		types.CheckDclstack()
+	}
+
+	typecheck.Func(fn)
+	ir.CurFunc = fn
+	typecheck.Stmts(fn.Body)
+
+	// Inline calls within (*T).M wrappers. This is safe because we only
+	// generate those wrappers within the same compilation unit as (T).M.
+	// TODO(mdempsky): Investigate why we can't enable this more generally.
+	if rcvr.IsPtr() && rcvr.Elem() == method.Type.Recv().Type && rcvr.Elem().Sym() != nil {
+		inline.InlineCalls(fn)
+	}
+	escape.Batch([]*ir.Func{fn}, false)
+
+	ir.CurFunc = nil
+	typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
+
+	return lsym
+}
+
+var ZeroSize int64
+
+// MarkTypeUsedInInterface marks that type t is converted to an interface.
+// This information is used in the linker in dead method elimination.
+func MarkTypeUsedInInterface(t *types.Type, from *obj.LSym) {
+	tsym := TypeLinksym(t)
+	// Emit a marker relocation. The linker will know the type is converted
+	// to an interface if "from" is reachable.
+	r := obj.Addrel(from)
+	r.Sym = tsym
+	r.Type = objabi.R_USEIFACE
+}
+
+// MarkUsedIfaceMethod marks that an interface method is used in the current
+// function. n is OCALLINTER node.
+func MarkUsedIfaceMethod(n *ir.CallExpr) {
+	// skip unnamed functions (func _())
+	if ir.CurFunc.LSym == nil {
+		return
+	}
+	dot := n.X.(*ir.SelectorExpr)
+	ityp := dot.X.Type()
+	tsym := TypeLinksym(ityp)
+	r := obj.Addrel(ir.CurFunc.LSym)
+	r.Sym = tsym
+	// dot.Xoffset is the method index * PtrSize (the offset of code pointer
+	// in itab).
+	midx := dot.Offset() / int64(types.PtrSize)
+	r.Add = InterfaceMethodOffset(ityp, midx)
+	r.Type = objabi.R_USEIFACEMETHOD
+}
diff --git a/src/cmd/compile/internal/riscv64/galign.go b/src/cmd/compile/internal/riscv64/galign.go
index 4db0fac..338248a 100644
--- a/src/cmd/compile/internal/riscv64/galign.go
+++ b/src/cmd/compile/internal/riscv64/galign.go
@@ -5,11 +5,11 @@
 package riscv64
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/ssagen"
 	"cmd/internal/obj/riscv"
 )
 
-func Init(arch *gc.Arch) {
+func Init(arch *ssagen.ArchInfo) {
 	arch.LinkArch = &riscv.LinkRISCV64
 
 	arch.REGSP = riscv.REG_SP
diff --git a/src/cmd/compile/internal/riscv64/ggen.go b/src/cmd/compile/internal/riscv64/ggen.go
index f7c03fe..9df7394 100644
--- a/src/cmd/compile/internal/riscv64/ggen.go
+++ b/src/cmd/compile/internal/riscv64/ggen.go
@@ -5,33 +5,36 @@
 package riscv64
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/riscv"
 )
 
-func zeroRange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
+func zeroRange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
 	if cnt == 0 {
 		return p
 	}
 
 	// Adjust the frame to account for LR.
-	off += gc.Ctxt.FixedFrameSize()
+	off += base.Ctxt.FixedFrameSize()
 
-	if cnt < int64(4*gc.Widthptr) {
-		for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
-			p = pp.Appendpp(p, riscv.AMOV, obj.TYPE_REG, riscv.REG_ZERO, 0, obj.TYPE_MEM, riscv.REG_SP, off+i)
+	if cnt < int64(4*types.PtrSize) {
+		for i := int64(0); i < cnt; i += int64(types.PtrSize) {
+			p = pp.Append(p, riscv.AMOV, obj.TYPE_REG, riscv.REG_ZERO, 0, obj.TYPE_MEM, riscv.REG_SP, off+i)
 		}
 		return p
 	}
 
-	if cnt <= int64(128*gc.Widthptr) {
-		p = pp.Appendpp(p, riscv.AADDI, obj.TYPE_CONST, 0, off, obj.TYPE_REG, riscv.REG_A0, 0)
+	if cnt <= int64(128*types.PtrSize) {
+		p = pp.Append(p, riscv.AADDI, obj.TYPE_CONST, 0, off, obj.TYPE_REG, riscv.REG_A0, 0)
 		p.Reg = riscv.REG_SP
-		p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
+		p = pp.Append(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 = 8 * (128 - cnt/int64(gc.Widthptr))
+		p.To.Sym = ir.Syms.Duffzero
+		p.To.Offset = 8 * (128 - cnt/int64(types.PtrSize))
 		return p
 	}
 
@@ -42,15 +45,15 @@
 	// 	MOV	ZERO, (T0)
 	// 	ADD	$Widthptr, T0
 	//	BNE	T0, T1, loop
-	p = pp.Appendpp(p, riscv.AADD, obj.TYPE_CONST, 0, off, obj.TYPE_REG, riscv.REG_T0, 0)
+	p = pp.Append(p, riscv.AADD, obj.TYPE_CONST, 0, off, obj.TYPE_REG, riscv.REG_T0, 0)
 	p.Reg = riscv.REG_SP
-	p = pp.Appendpp(p, riscv.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, riscv.REG_T1, 0)
+	p = pp.Append(p, riscv.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, riscv.REG_T1, 0)
 	p.Reg = riscv.REG_T0
-	p = pp.Appendpp(p, riscv.AMOV, obj.TYPE_REG, riscv.REG_ZERO, 0, obj.TYPE_MEM, riscv.REG_T0, 0)
+	p = pp.Append(p, riscv.AMOV, obj.TYPE_REG, riscv.REG_ZERO, 0, obj.TYPE_MEM, riscv.REG_T0, 0)
 	loop := p
-	p = pp.Appendpp(p, riscv.AADD, obj.TYPE_CONST, 0, int64(gc.Widthptr), obj.TYPE_REG, riscv.REG_T0, 0)
-	p = pp.Appendpp(p, riscv.ABNE, obj.TYPE_REG, riscv.REG_T0, 0, obj.TYPE_BRANCH, 0, 0)
+	p = pp.Append(p, riscv.AADD, obj.TYPE_CONST, 0, int64(types.PtrSize), obj.TYPE_REG, riscv.REG_T0, 0)
+	p = pp.Append(p, riscv.ABNE, obj.TYPE_REG, riscv.REG_T0, 0, obj.TYPE_BRANCH, 0, 0)
 	p.Reg = riscv.REG_T1
-	gc.Patch(p, loop)
+	p.To.SetTarget(loop)
 	return p
 }
diff --git a/src/cmd/compile/internal/riscv64/gsubr.go b/src/cmd/compile/internal/riscv64/gsubr.go
index d40bdf7..74bccf8 100644
--- a/src/cmd/compile/internal/riscv64/gsubr.go
+++ b/src/cmd/compile/internal/riscv64/gsubr.go
@@ -5,12 +5,12 @@
 package riscv64
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/objw"
 	"cmd/internal/obj"
 	"cmd/internal/obj/riscv"
 )
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
 	// Hardware nop is ADD $0, ZERO
 	p := pp.Prog(riscv.AADD)
 	p.From.Type = obj.TYPE_CONST
diff --git a/src/cmd/compile/internal/riscv64/ssa.go b/src/cmd/compile/internal/riscv64/ssa.go
index 0beb5b4..64a9b3b 100644
--- a/src/cmd/compile/internal/riscv64/ssa.go
+++ b/src/cmd/compile/internal/riscv64/ssa.go
@@ -5,8 +5,10 @@
 package riscv64
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/riscv"
@@ -91,7 +93,7 @@
 		case 8:
 			return riscv.AMOVD
 		default:
-			gc.Fatalf("unknown float width for load %d in type %v", width, t)
+			base.Fatalf("unknown float width for load %d in type %v", width, t)
 			return 0
 		}
 	}
@@ -118,7 +120,7 @@
 	case 8:
 		return riscv.AMOV
 	default:
-		gc.Fatalf("unknown width for load %d in type %v", width, t)
+		base.Fatalf("unknown width for load %d in type %v", width, t)
 		return 0
 	}
 }
@@ -134,7 +136,7 @@
 		case 8:
 			return riscv.AMOVD
 		default:
-			gc.Fatalf("unknown float width for store %d in type %v", width, t)
+			base.Fatalf("unknown float width for store %d in type %v", width, t)
 			return 0
 		}
 	}
@@ -149,7 +151,7 @@
 	case 8:
 		return riscv.AMOV
 	default:
-		gc.Fatalf("unknown width for store %d in type %v", width, t)
+		base.Fatalf("unknown width for store %d in type %v", width, t)
 		return 0
 	}
 }
@@ -178,9 +180,9 @@
 
 // markMoves marks any MOVXconst ops that need to avoid clobbering flags.
 // RISC-V has no flags, so this is a no-op.
-func ssaMarkMoves(s *gc.SSAGenState, b *ssa.Block) {}
+func ssaMarkMoves(s *ssagen.State, b *ssa.Block) {}
 
-func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
+func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 	s.SetPos(v.Pos)
 
 	switch v.Op {
@@ -189,7 +191,7 @@
 	case ssa.OpArg:
 		// input args need no code
 	case ssa.OpPhi:
-		gc.CheckLoweredPhi(v)
+		ssagen.CheckLoweredPhi(v)
 	case ssa.OpCopy, ssa.OpRISCV64MOVconvert, ssa.OpRISCV64MOVDreg:
 		if v.Type.IsMemory() {
 			return
@@ -209,9 +211,6 @@
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = rd
 	case ssa.OpRISCV64MOVDnop:
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		// nothing to do
 	case ssa.OpLoadReg:
 		if v.Type.IsFlags() {
@@ -219,7 +218,7 @@
 			return
 		}
 		p := s.Prog(loadByType(v.Type))
-		gc.AddrAuto(&p.From, v.Args[0])
+		ssagen.AddrAuto(&p.From, v.Args[0])
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpStoreReg:
@@ -230,7 +229,7 @@
 		p := s.Prog(storeByType(v.Type))
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddrAuto(&p.To, v)
+		ssagen.AddrAuto(&p.To, v)
 	case ssa.OpSP, ssa.OpSB, ssa.OpGetG:
 		// nothing to do
 	case ssa.OpRISCV64MOVBreg, ssa.OpRISCV64MOVHreg, ssa.OpRISCV64MOVWreg,
@@ -302,7 +301,7 @@
 		p.Reg = v.Args[0].Reg()
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
-	case ssa.OpRISCV64MOVBconst, ssa.OpRISCV64MOVHconst, ssa.OpRISCV64MOVWconst, ssa.OpRISCV64MOVDconst:
+	case ssa.OpRISCV64MOVDconst:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = v.AuxInt
@@ -321,10 +320,10 @@
 			v.Fatalf("aux is of unknown type %T", v.Aux)
 		case *obj.LSym:
 			wantreg = "SB"
-			gc.AddAux(&p.From, v)
-		case *gc.Node:
+			ssagen.AddAux(&p.From, v)
+		case *ir.Name:
 			wantreg = "SP"
-			gc.AddAux(&p.From, v)
+			ssagen.AddAux(&p.From, v)
 		case nil:
 			// No sym, just MOVW $off(SP), R
 			wantreg = "SP"
@@ -340,7 +339,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpRISCV64MOVBstore, ssa.OpRISCV64MOVHstore, ssa.OpRISCV64MOVWstore, ssa.OpRISCV64MOVDstore,
@@ -350,14 +349,14 @@
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpRISCV64MOVBstorezero, ssa.OpRISCV64MOVHstorezero, ssa.OpRISCV64MOVWstorezero, ssa.OpRISCV64MOVDstorezero:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = riscv.REG_ZERO
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpRISCV64SEQZ, ssa.OpRISCV64SNEZ:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
@@ -375,7 +374,7 @@
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+		p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
 		s.UseArgs(16) // space used in callee args area by assembly stubs
 
 	case ssa.OpRISCV64LoweredAtomicLoad8:
@@ -500,7 +499,7 @@
 		p4.From.Reg = riscv.REG_TMP
 		p4.Reg = riscv.REG_ZERO
 		p4.To.Type = obj.TYPE_BRANCH
-		gc.Patch(p4, p1)
+		p4.To.SetTarget(p1)
 
 		p5 := s.Prog(riscv.AMOV)
 		p5.From.Type = obj.TYPE_CONST
@@ -509,7 +508,15 @@
 		p5.To.Reg = out
 
 		p6 := s.Prog(obj.ANOP)
-		gc.Patch(p2, p6)
+		p2.To.SetTarget(p6)
+
+	case ssa.OpRISCV64LoweredAtomicAnd32, ssa.OpRISCV64LoweredAtomicOr32:
+		p := s.Prog(v.Op.Asm())
+		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()
+		p.RegTo2 = riscv.REG_ZERO
 
 	case ssa.OpRISCV64LoweredZero:
 		mov, sz := largestMove(v.AuxInt)
@@ -535,7 +542,7 @@
 		p3.Reg = v.Args[0].Reg()
 		p3.From.Type = obj.TYPE_REG
 		p3.From.Reg = v.Args[1].Reg()
-		gc.Patch(p3, p)
+		p3.To.SetTarget(p)
 
 	case ssa.OpRISCV64LoweredMove:
 		mov, sz := largestMove(v.AuxInt)
@@ -575,7 +582,7 @@
 		p5.Reg = v.Args[1].Reg()
 		p5.From.Type = obj.TYPE_REG
 		p5.From.Reg = v.Args[2].Reg()
-		gc.Patch(p5, p)
+		p5.To.SetTarget(p)
 
 	case ssa.OpRISCV64LoweredNilCheck:
 		// Issue a load which will fault if arg is nil.
@@ -583,22 +590,22 @@
 		p := s.Prog(riscv.AMOVB)
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = riscv.REG_ZERO
-		if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Pos == 1 in generated wrappers
-			gc.Warnl(v.Pos, "generated nil check")
+		if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos == 1 in generated wrappers
+			base.WarnfAt(v.Pos, "generated nil check")
 		}
 
 	case ssa.OpRISCV64LoweredGetClosurePtr:
 		// Closure pointer is S4 (riscv.REG_CTXT).
-		gc.CheckLoweredGetClosurePtr(v)
+		ssagen.CheckLoweredGetClosurePtr(v)
 
 	case ssa.OpRISCV64LoweredGetCallerSP:
 		// caller's SP is FixedFrameSize below the address of the first arg
 		p := s.Prog(riscv.AMOV)
 		p.From.Type = obj.TYPE_ADDR
-		p.From.Offset = -gc.Ctxt.FixedFrameSize()
+		p.From.Offset = -base.Ctxt.FixedFrameSize()
 		p.From.Name = obj.NAME_PARAM
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
@@ -612,16 +619,19 @@
 		p := s.Prog(obj.ADUFFZERO)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.Duffzero
+		p.To.Sym = ir.Syms.Duffzero
 		p.To.Offset = v.AuxInt
 
 	case ssa.OpRISCV64DUFFCOPY:
 		p := s.Prog(obj.ADUFFCOPY)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.Duffcopy
+		p.To.Sym = ir.Syms.Duffcopy
 		p.To.Offset = v.AuxInt
 
+	case ssa.OpClobber, ssa.OpClobberReg:
+		// TODO: implement for clobberdead experiment. Nop is ok for now.
+
 	default:
 		v.Fatalf("Unhandled op %v", v.Op)
 	}
@@ -642,7 +652,7 @@
 	ssa.BlockRISCV64BNEZ: riscv.ABNEZ,
 }
 
-func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
+func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
 	s.SetPos(b.Pos)
 
 	switch b.Kind {
@@ -655,17 +665,17 @@
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = riscv.REG_ZERO
 		p.Reg = riscv.REG_A0
-		s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+		s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[1].Block()})
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 	case ssa.BlockPlain:
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 	case ssa.BlockExit:
 	case ssa.BlockRet:
diff --git a/src/cmd/compile/internal/s390x/galign.go b/src/cmd/compile/internal/s390x/galign.go
index cb68fd3..b004a2d 100644
--- a/src/cmd/compile/internal/s390x/galign.go
+++ b/src/cmd/compile/internal/s390x/galign.go
@@ -5,11 +5,11 @@
 package s390x
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/ssagen"
 	"cmd/internal/obj/s390x"
 )
 
-func Init(arch *gc.Arch) {
+func Init(arch *ssagen.ArchInfo) {
 	arch.LinkArch = &s390x.Links390x
 	arch.REGSP = s390x.REGSP
 	arch.MAXWIDTH = 1 << 50
diff --git a/src/cmd/compile/internal/s390x/ggen.go b/src/cmd/compile/internal/s390x/ggen.go
index 5a837d8..488a080 100644
--- a/src/cmd/compile/internal/s390x/ggen.go
+++ b/src/cmd/compile/internal/s390x/ggen.go
@@ -5,7 +5,8 @@
 package s390x
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/objw"
 	"cmd/internal/obj"
 	"cmd/internal/obj/s390x"
 )
@@ -17,20 +18,20 @@
 const clearLoopCutoff = 1024
 
 // zerorange clears the stack in the given range.
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
 	if cnt == 0 {
 		return p
 	}
 
 	// Adjust the frame to account for LR.
-	off += gc.Ctxt.FixedFrameSize()
+	off += base.Ctxt.FixedFrameSize()
 	reg := int16(s390x.REGSP)
 
 	// If the off cannot fit in a 12-bit unsigned displacement then we
 	// need to create a copy of the stack pointer that we can adjust.
 	// We also need to do this if we are going to loop.
 	if off < 0 || off > 4096-clearLoopCutoff || cnt > clearLoopCutoff {
-		p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, off, obj.TYPE_REG, s390x.REGRT1, 0)
+		p = pp.Append(p, s390x.AADD, obj.TYPE_CONST, 0, off, obj.TYPE_REG, s390x.REGRT1, 0)
 		p.Reg = int16(s390x.REGSP)
 		reg = s390x.REGRT1
 		off = 0
@@ -39,12 +40,12 @@
 	// Generate a loop of large clears.
 	if cnt > clearLoopCutoff {
 		ireg := int16(s390x.REGRT2) // register holds number of remaining loop iterations
-		p = pp.Appendpp(p, s390x.AMOVD, obj.TYPE_CONST, 0, cnt/256, obj.TYPE_REG, ireg, 0)
-		p = pp.Appendpp(p, s390x.ACLEAR, obj.TYPE_CONST, 0, 256, obj.TYPE_MEM, reg, off)
+		p = pp.Append(p, s390x.AMOVD, obj.TYPE_CONST, 0, cnt/256, obj.TYPE_REG, ireg, 0)
+		p = pp.Append(p, s390x.ACLEAR, obj.TYPE_CONST, 0, 256, obj.TYPE_MEM, reg, off)
 		pl := p
-		p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, 256, obj.TYPE_REG, reg, 0)
-		p = pp.Appendpp(p, s390x.ABRCTG, obj.TYPE_REG, ireg, 0, obj.TYPE_BRANCH, 0, 0)
-		gc.Patch(p, pl)
+		p = pp.Append(p, s390x.AADD, obj.TYPE_CONST, 0, 256, obj.TYPE_REG, reg, 0)
+		p = pp.Append(p, s390x.ABRCTG, obj.TYPE_REG, ireg, 0, obj.TYPE_BRANCH, 0, 0)
+		p.To.SetTarget(pl)
 		cnt = cnt % 256
 	}
 
@@ -69,11 +70,11 @@
 			case 2:
 				ins = s390x.AMOVH
 			}
-			p = pp.Appendpp(p, ins, obj.TYPE_CONST, 0, 0, obj.TYPE_MEM, reg, off)
+			p = pp.Append(p, ins, obj.TYPE_CONST, 0, 0, obj.TYPE_MEM, reg, off)
 
 		// Handle clears that would require multiple move instructions with CLEAR (assembled as XC).
 		default:
-			p = pp.Appendpp(p, s390x.ACLEAR, obj.TYPE_CONST, 0, n, obj.TYPE_MEM, reg, off)
+			p = pp.Append(p, s390x.ACLEAR, obj.TYPE_CONST, 0, n, obj.TYPE_MEM, reg, off)
 		}
 
 		cnt -= n
@@ -83,6 +84,6 @@
 	return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
 	return pp.Prog(s390x.ANOPH)
 }
diff --git a/src/cmd/compile/internal/s390x/ssa.go b/src/cmd/compile/internal/s390x/ssa.go
index 8037357..ddc05b3 100644
--- a/src/cmd/compile/internal/s390x/ssa.go
+++ b/src/cmd/compile/internal/s390x/ssa.go
@@ -7,16 +7,17 @@
 import (
 	"math"
 
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
 	"cmd/compile/internal/logopt"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/s390x"
 )
 
 // markMoves marks any MOVXconst ops that need to avoid clobbering flags.
-func ssaMarkMoves(s *gc.SSAGenState, b *ssa.Block) {
+func ssaMarkMoves(s *ssagen.State, b *ssa.Block) {
 	flive := b.FlagsLiveAtEnd
 	for _, c := range b.ControlValues() {
 		flive = c.Type.IsFlags() || flive
@@ -134,7 +135,7 @@
 //     dest := dest(To) op src(From)
 // and also returns the created obj.Prog so it
 // may be further adjusted (offset, scale, etc).
-func opregreg(s *gc.SSAGenState, op obj.As, dest, src int16) *obj.Prog {
+func opregreg(s *ssagen.State, op obj.As, dest, src int16) *obj.Prog {
 	p := s.Prog(op)
 	p.From.Type = obj.TYPE_REG
 	p.To.Type = obj.TYPE_REG
@@ -147,7 +148,7 @@
 //	dest := src(From) op off
 // and also returns the created obj.Prog so it
 // may be further adjusted (offset, scale, etc).
-func opregregimm(s *gc.SSAGenState, op obj.As, dest, src int16, off int64) *obj.Prog {
+func opregregimm(s *ssagen.State, op obj.As, dest, src int16, off int64) *obj.Prog {
 	p := s.Prog(op)
 	p.From.Type = obj.TYPE_CONST
 	p.From.Offset = off
@@ -157,7 +158,7 @@
 	return p
 }
 
-func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
+func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 	switch v.Op {
 	case ssa.OpS390XSLD, ssa.OpS390XSLW,
 		ssa.OpS390XSRD, ssa.OpS390XSRW,
@@ -174,10 +175,6 @@
 			p.Reg = r1
 		}
 	case ssa.OpS390XRXSBG:
-		r1 := v.Reg()
-		if r1 != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		r2 := v.Args[1].Reg()
 		i := v.Aux.(s390x.RotateParams)
 		p := s.Prog(v.Op.Asm())
@@ -187,7 +184,7 @@
 			{Type: obj.TYPE_CONST, Offset: int64(i.Amount)},
 			{Type: obj.TYPE_REG, Reg: r2},
 		})
-		p.To = obj.Addr{Type: obj.TYPE_REG, Reg: r1}
+		p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
 	case ssa.OpS390XRISBGZ:
 		r1 := v.Reg()
 		r2 := v.Args[0].Reg()
@@ -232,12 +229,8 @@
 			p.Reg = r2
 		}
 	case ssa.OpS390XADDE, ssa.OpS390XSUBE:
-		r1 := v.Reg0()
-		if r1 != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		r2 := v.Args[1].Reg()
-		opregreg(s, v.Op.Asm(), r1, r2)
+		opregreg(s, v.Op.Asm(), v.Reg0(), r2)
 	case ssa.OpS390XADDCconst:
 		r1 := v.Reg0()
 		r3 := v.Args[0].Reg()
@@ -247,18 +240,10 @@
 	case ssa.OpS390XMULLD, ssa.OpS390XMULLW,
 		ssa.OpS390XMULHD, ssa.OpS390XMULHDU,
 		ssa.OpS390XFMULS, ssa.OpS390XFMUL, ssa.OpS390XFDIVS, ssa.OpS390XFDIV:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
-		opregreg(s, v.Op.Asm(), r, v.Args[1].Reg())
+		opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
 	case ssa.OpS390XFSUBS, ssa.OpS390XFSUB,
 		ssa.OpS390XFADDS, ssa.OpS390XFADD:
-		r := v.Reg0()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
-		opregreg(s, v.Op.Asm(), r, v.Args[1].Reg())
+		opregreg(s, v.Op.Asm(), v.Reg0(), v.Args[1].Reg())
 	case ssa.OpS390XMLGR:
 		// MLGR Rx R3 -> R2:R3
 		r0 := v.Args[0].Reg()
@@ -273,10 +258,6 @@
 		p.To.Type = obj.TYPE_REG
 	case ssa.OpS390XFMADD, ssa.OpS390XFMADDS,
 		ssa.OpS390XFMSUB, ssa.OpS390XFMSUBS:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		r1 := v.Args[1].Reg()
 		r2 := v.Args[2].Reg()
 		p := s.Prog(v.Op.Asm())
@@ -284,7 +265,7 @@
 		p.From.Reg = r1
 		p.Reg = r2
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
+		p.To.Reg = v.Reg()
 	case ssa.OpS390XFIDBR:
 		switch v.AuxInt {
 		case 0, 1, 3, 4, 5, 6, 7:
@@ -360,15 +341,11 @@
 		ssa.OpS390XANDconst, ssa.OpS390XANDWconst,
 		ssa.OpS390XORconst, ssa.OpS390XORWconst,
 		ssa.OpS390XXORconst, ssa.OpS390XXORWconst:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		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 = r
+		p.To.Reg = v.Reg()
 	case ssa.OpS390XSLDconst, ssa.OpS390XSLWconst,
 		ssa.OpS390XSRDconst, ssa.OpS390XSRWconst,
 		ssa.OpS390XSRADconst, ssa.OpS390XSRAWconst,
@@ -394,14 +371,14 @@
 		p.From.Type = obj.TYPE_ADDR
 		p.From.Reg = r
 		p.From.Index = i
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpS390XMOVDaddr:
 		p := s.Prog(s390x.AMOVD)
 		p.From.Type = obj.TYPE_ADDR
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpS390XCMP, ssa.OpS390XCMPW, ssa.OpS390XCMPU, ssa.OpS390XCMPWU:
@@ -440,16 +417,12 @@
 		ssa.OpS390XANDWload, ssa.OpS390XANDload,
 		ssa.OpS390XORWload, ssa.OpS390XORload,
 		ssa.OpS390XXORWload, ssa.OpS390XXORload:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[1].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
+		p.To.Reg = v.Reg()
 	case ssa.OpS390XMOVDload,
 		ssa.OpS390XMOVWZload, ssa.OpS390XMOVHZload, ssa.OpS390XMOVBZload,
 		ssa.OpS390XMOVDBRload, ssa.OpS390XMOVWBRload, ssa.OpS390XMOVHBRload,
@@ -458,7 +431,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpS390XMOVBZloadidx, ssa.OpS390XMOVHZloadidx, ssa.OpS390XMOVWZloadidx,
@@ -475,7 +448,7 @@
 		p.From.Reg = r
 		p.From.Scale = 1
 		p.From.Index = i
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpS390XMOVBstore, ssa.OpS390XMOVHstore, ssa.OpS390XMOVWstore, ssa.OpS390XMOVDstore,
@@ -486,7 +459,7 @@
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpS390XMOVBstoreidx, ssa.OpS390XMOVHstoreidx, ssa.OpS390XMOVWstoreidx, ssa.OpS390XMOVDstoreidx,
 		ssa.OpS390XMOVHBRstoreidx, ssa.OpS390XMOVWBRstoreidx, ssa.OpS390XMOVDBRstoreidx,
 		ssa.OpS390XFMOVSstoreidx, ssa.OpS390XFMOVDstoreidx:
@@ -502,15 +475,15 @@
 		p.To.Reg = r
 		p.To.Scale = 1
 		p.To.Index = i
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpS390XMOVDstoreconst, ssa.OpS390XMOVWstoreconst, ssa.OpS390XMOVHstoreconst, ssa.OpS390XMOVBstoreconst:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_CONST
 		sc := v.AuxValAndOff()
-		p.From.Offset = sc.Val()
+		p.From.Offset = sc.Val64()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux2(&p.To, v, sc.Off())
+		ssagen.AddAux2(&p.To, v, sc.Off64())
 	case ssa.OpS390XMOVBreg, ssa.OpS390XMOVHreg, ssa.OpS390XMOVWreg,
 		ssa.OpS390XMOVBZreg, ssa.OpS390XMOVHZreg, ssa.OpS390XMOVWZreg,
 		ssa.OpS390XLDGR, ssa.OpS390XLGDR,
@@ -526,10 +499,10 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_CONST
 		sc := v.AuxValAndOff()
-		p.From.Offset = sc.Val()
+		p.From.Offset = sc.Val64()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux2(&p.To, v, sc.Off())
+		ssagen.AddAux2(&p.To, v, sc.Off64())
 	case ssa.OpCopy:
 		if v.Type.IsMemory() {
 			return
@@ -545,7 +518,7 @@
 			return
 		}
 		p := s.Prog(loadByType(v.Type))
-		gc.AddrAuto(&p.From, v.Args[0])
+		ssagen.AddrAuto(&p.From, v.Args[0])
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.OpStoreReg:
@@ -556,10 +529,10 @@
 		p := s.Prog(storeByType(v.Type))
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddrAuto(&p.To, v)
+		ssagen.AddrAuto(&p.To, v)
 	case ssa.OpS390XLoweredGetClosurePtr:
 		// Closure pointer is R12 (already)
-		gc.CheckLoweredGetClosurePtr(v)
+		ssagen.CheckLoweredGetClosurePtr(v)
 	case ssa.OpS390XLoweredRound32F, ssa.OpS390XLoweredRound64F:
 		// input is already rounded
 	case ssa.OpS390XLoweredGetG:
@@ -573,7 +546,7 @@
 		// 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.Offset = -base.Ctxt.FixedFrameSize()
 		p.From.Name = obj.NAME_PARAM
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
@@ -592,7 +565,7 @@
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+		p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
 		s.UseArgs(16) // space used in callee args area by assembly stubs
 	case ssa.OpS390XFLOGR, ssa.OpS390XPOPCNT,
 		ssa.OpS390XNEG, ssa.OpS390XNEGW,
@@ -607,17 +580,13 @@
 	case ssa.OpS390XSumBytes2, ssa.OpS390XSumBytes4, ssa.OpS390XSumBytes8:
 		v.Fatalf("SumBytes generated %s", v.LongString())
 	case ssa.OpS390XLOCGR:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = int64(v.Aux.(s390x.CCMask))
 		p.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
-	case ssa.OpS390XFSQRT:
+		p.To.Reg = v.Reg()
+	case ssa.OpS390XFSQRTS, ssa.OpS390XFSQRT:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
@@ -636,28 +605,28 @@
 		p := s.Prog(s390x.AMOVBZ)
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = s390x.REGTMP
 		if logopt.Enabled() {
 			logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
 		}
-		if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
-			gc.Warnl(v.Pos, "generated nil check")
+		if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
+			base.WarnfAt(v.Pos, "generated nil check")
 		}
 	case ssa.OpS390XMVC:
 		vo := v.AuxValAndOff()
 		p := s.Prog(s390x.AMVC)
 		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = vo.Val()
+		p.From.Offset = vo.Val64()
 		p.SetFrom3(obj.Addr{
 			Type:   obj.TYPE_MEM,
 			Reg:    v.Args[1].Reg(),
-			Offset: vo.Off(),
+			Offset: vo.Off64(),
 		})
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		p.To.Offset = vo.Off()
+		p.To.Offset = vo.Off64()
 	case ssa.OpS390XSTMG2, ssa.OpS390XSTMG3, ssa.OpS390XSTMG4,
 		ssa.OpS390XSTM2, ssa.OpS390XSTM3, ssa.OpS390XSTM4:
 		for i := 2; i < len(v.Args)-1; i++ {
@@ -671,7 +640,7 @@
 		p.Reg = v.Args[len(v.Args)-2].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpS390XLoweredMove:
 		// Inputs must be valid pointers to memory,
 		// so adjust arg0 and arg1 as part of the expansion.
@@ -708,7 +677,7 @@
 
 		bne := s.Prog(s390x.ABLT)
 		bne.To.Type = obj.TYPE_BRANCH
-		gc.Patch(bne, mvc)
+		bne.To.SetTarget(mvc)
 
 		if v.AuxInt > 0 {
 			mvc := s.Prog(s390x.AMVC)
@@ -750,7 +719,7 @@
 
 		bne := s.Prog(s390x.ABLT)
 		bne.To.Type = obj.TYPE_BRANCH
-		gc.Patch(bne, clear)
+		bne.To.SetTarget(clear)
 
 		if v.AuxInt > 0 {
 			clear := s.Prog(s390x.ACLEAR)
@@ -763,7 +732,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg0()
 	case ssa.OpS390XMOVBatomicstore, ssa.OpS390XMOVWatomicstore, ssa.OpS390XMOVDatomicstore:
@@ -772,7 +741,7 @@
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpS390XLAN, ssa.OpS390XLAO:
 		// LA(N|O) Ry, TMP, 0(Rx)
 		op := s.Prog(v.Op.Asm())
@@ -807,7 +776,7 @@
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.OpS390XLoweredAtomicCas32, ssa.OpS390XLoweredAtomicCas64:
 		// Convert the flags output of CS{,G} into a bool.
 		//    CS{,G} arg1, arg2, arg0
@@ -823,7 +792,7 @@
 		cs.Reg = v.Args[2].Reg()      // new
 		cs.To.Type = obj.TYPE_MEM
 		cs.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&cs.To, v)
+		ssagen.AddAux(&cs.To, v)
 
 		// MOVD $0, ret
 		movd := s.Prog(s390x.AMOVD)
@@ -845,7 +814,7 @@
 
 		// NOP (so the BNE has somewhere to land)
 		nop := s.Prog(obj.ANOP)
-		gc.Patch(bne, nop)
+		bne.To.SetTarget(nop)
 	case ssa.OpS390XLoweredAtomicExchange32, ssa.OpS390XLoweredAtomicExchange64:
 		// Loop until the CS{,G} succeeds.
 		//     MOV{WZ,D} arg0, ret
@@ -858,7 +827,7 @@
 		load.From.Reg = v.Args[0].Reg()
 		load.To.Type = obj.TYPE_REG
 		load.To.Reg = v.Reg0()
-		gc.AddAux(&load.From, v)
+		ssagen.AddAux(&load.From, v)
 
 		// CS{,G} ret, arg1, arg0
 		cs := s.Prog(v.Op.Asm())
@@ -867,15 +836,15 @@
 		cs.Reg = v.Args[1].Reg() // new
 		cs.To.Type = obj.TYPE_MEM
 		cs.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&cs.To, v)
+		ssagen.AddAux(&cs.To, v)
 
 		// BNE cs
 		bne := s.Prog(s390x.ABNE)
 		bne.To.Type = obj.TYPE_BRANCH
-		gc.Patch(bne, cs)
+		bne.To.SetTarget(cs)
 	case ssa.OpS390XSYNC:
 		s.Prog(s390x.ASYNC)
-	case ssa.OpClobber:
+	case ssa.OpClobber, ssa.OpClobberReg:
 		// TODO: implement for clobberdead experiment. Nop is ok for now.
 	default:
 		v.Fatalf("genValue not implemented: %s", v.LongString())
@@ -907,14 +876,14 @@
 	panic("unreachable")
 }
 
-func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
+func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
 	// Handle generic blocks first.
 	switch b.Kind {
 	case ssa.BlockPlain:
 		if b.Succs[0].Block() != next {
 			p := s.Prog(s390x.ABR)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 		return
 	case ssa.BlockDefer:
@@ -925,7 +894,7 @@
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = int64(s390x.NotEqual & s390x.NotUnordered) // unordered is not possible
 		p.Reg = s390x.REG_R3
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: 0})
+		p.SetFrom3Const(0)
 		if b.Succs[0].Block() != next {
 			s.Br(s390x.ABR, b.Succs[0].Block())
 		}
@@ -968,17 +937,17 @@
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible
 		p.Reg = b.Controls[0].Reg()
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: b.Controls[1].Reg()})
+		p.SetFrom3Reg(b.Controls[1].Reg())
 	case ssa.BlockS390XCGIJ, ssa.BlockS390XCIJ:
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible
 		p.Reg = b.Controls[0].Reg()
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: int64(int8(b.AuxInt))})
+		p.SetFrom3Const(int64(int8(b.AuxInt)))
 	case ssa.BlockS390XCLGIJ, ssa.BlockS390XCLIJ:
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible
 		p.Reg = b.Controls[0].Reg()
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: int64(uint8(b.AuxInt))})
+		p.SetFrom3Const(int64(uint8(b.AuxInt)))
 	default:
 		b.Fatalf("branch not implemented: %s", b.LongString())
 	}
diff --git a/src/cmd/compile/internal/ssa/README.md b/src/cmd/compile/internal/ssa/README.md
index 4483c2c..833bf1d 100644
--- a/src/cmd/compile/internal/ssa/README.md
+++ b/src/cmd/compile/internal/ssa/README.md
@@ -184,6 +184,19 @@
 program. You can also click on values and blocks to highlight them, to help
 follow the control flow and values.
 
+The value specified in GOSSAFUNC can also be a package-qualified function
+name, e.g. 
+
+	GOSSAFUNC=blah.Foo go build
+    
+This will match any function named "Foo" within a package whose final
+suffix is "blah" (e.g. something/blah.Foo, anotherthing/extra/blah.Foo).
+
+If non-HTML dumps are needed, append a "+" to the GOSSAFUNC value
+and dumps will be written to stdout:
+
+	GOSSAFUNC=Bar+ go build
+
 <!---
 TODO: need more ideas for this section
 -->
diff --git a/src/cmd/compile/internal/ssa/bench_test.go b/src/cmd/compile/internal/ssa/bench_test.go
new file mode 100644
index 0000000..0971667
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/bench_test.go
@@ -0,0 +1,32 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+package ssa
+
+import (
+	"math/rand"
+	"testing"
+)
+
+var d int
+
+//go:noinline
+func fn(a, b int) bool {
+	c := false
+	if a > 0 {
+		if b < 0 {
+			d = d + 1
+		}
+		c = true
+	}
+	return c
+}
+
+func BenchmarkPhioptPass(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		a := rand.Perm(i/10 + 10)
+		for i := 1; i < len(a)/2; i++ {
+			fn(a[i]-a[i-1], a[i+len(a)/2-2]-a[i+len(a)/2-1])
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/ssa/block.go b/src/cmd/compile/internal/ssa/block.go
index 519ac21..71ca774 100644
--- a/src/cmd/compile/internal/ssa/block.go
+++ b/src/cmd/compile/internal/ssa/block.go
@@ -52,7 +52,7 @@
 	Controls [2]*Value
 
 	// Auxiliary info for the block. Its value depends on the Kind.
-	Aux    interface{}
+	Aux    Aux
 	AuxInt int64
 
 	// The unordered set of Values that define the operation of this block.
@@ -358,6 +358,22 @@
 	}
 }
 
+// likelyBranch reports whether block b is the likely branch of all of its predecessors.
+func (b *Block) likelyBranch() bool {
+	if len(b.Preds) == 0 {
+		return false
+	}
+	for _, e := range b.Preds {
+		p := e.b
+		if len(p.Succs) == 1 || len(p.Succs) == 2 && (p.Likely == BranchLikely && p.Succs[0].b == b ||
+			p.Likely == BranchUnlikely && p.Succs[1].b == b) {
+			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/check.go b/src/cmd/compile/internal/ssa/check.go
index 2dade7a..969fd96 100644
--- a/src/cmd/compile/internal/ssa/check.go
+++ b/src/cmd/compile/internal/ssa/check.go
@@ -166,7 +166,7 @@
 					f.Fatalf("value %v has an AuxInt that encodes a NaN", v)
 				}
 			case auxString:
-				if _, ok := v.Aux.(string); !ok {
+				if _, ok := v.Aux.(stringAux); !ok {
 					f.Fatalf("value %v has Aux type %T, want string", v, v.Aux)
 				}
 				canHaveAux = true
@@ -182,6 +182,12 @@
 					f.Fatalf("value %v has Aux type %T, want *AuxCall", v, v.Aux)
 				}
 				canHaveAux = true
+			case auxNameOffsetInt8:
+				if _, ok := v.Aux.(*AuxNameOffset); !ok {
+					f.Fatalf("value %v has Aux type %T, want *AuxNameOffset", v, v.Aux)
+				}
+				canHaveAux = true
+				canHaveAuxInt = true
 			case auxSym, auxTyp:
 				canHaveAux = true
 			case auxSymOff, auxSymValAndOff, auxTypSize:
diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go
index 63994d1..cd8eba4 100644
--- a/src/cmd/compile/internal/ssa/compile.go
+++ b/src/cmd/compile/internal/ssa/compile.go
@@ -6,10 +6,10 @@
 
 import (
 	"bytes"
-	"cmd/internal/objabi"
 	"cmd/internal/src"
 	"fmt"
 	"hash/crc32"
+	"internal/buildcfg"
 	"log"
 	"math/rand"
 	"os"
@@ -297,6 +297,11 @@
     -d=ssa/prove/debug=2
 sets debugging level to 2 in the prove pass
 
+Be aware that when "/debug=X" is applied to a pass, some passes
+will emit debug output for all functions, and other passes will
+only emit debug output for functions that match the current
+GOSSAFUNC value.
+
 Multiple flags can be passed at once, by separating them with
 commas. For example:
 
@@ -431,7 +436,6 @@
 	{name: "early copyelim", fn: copyelim},
 	{name: "early deadcode", fn: deadcode}, // remove generated dead code to avoid doing pointless work during opt
 	{name: "short circuit", fn: shortcircuit},
-	{name: "decompose args", fn: decomposeArgs, required: !go116lateCallExpansion, disabled: go116lateCallExpansion}, // handled by late call lowering
 	{name: "decompose user", fn: decomposeUser, required: true},
 	{name: "pre-opt deadcode", fn: deadcode},
 	{name: "opt", fn: opt, required: true},               // NB: some generic rules know the name of the opt pass. TODO: split required rules and optimizing rules
@@ -455,7 +459,7 @@
 	{name: "dse", fn: dse},
 	{name: "writebarrier", fn: writebarrier, required: true}, // expand write barrier ops
 	{name: "insert resched checks", fn: insertLoopReschedChecks,
-		disabled: objabi.Preemptibleloops_enabled == 0}, // insert resched checks in loops.
+		disabled: !buildcfg.Experiment.PreemptibleLoops}, // insert resched checks in loops.
 	{name: "lower", fn: lower, required: true},
 	{name: "addressing modes", fn: addressingModes, required: false},
 	{name: "lowered deadcode for cse", fn: deadcode}, // deadcode immediately before CSE avoids CSE making dead values live again
diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go
index 0fe0337..a8393a1 100644
--- a/src/cmd/compile/internal/ssa/config.go
+++ b/src/cmd/compile/internal/ssa/config.go
@@ -5,10 +5,12 @@
 package ssa
 
 import (
+	"cmd/compile/internal/abi"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
-	"cmd/internal/objabi"
 	"cmd/internal/src"
+	"internal/buildcfg"
 )
 
 // A Config holds readonly compilation information.
@@ -19,30 +21,33 @@
 	PtrSize        int64  // 4 or 8; copy of cmd/internal/sys.Arch.PtrSize
 	RegSize        int64  // 4 or 8; copy of cmd/internal/sys.Arch.RegSize
 	Types          Types
-	lowerBlock     blockRewriter // lowering function
-	lowerValue     valueRewriter // lowering function
-	splitLoad      valueRewriter // function for splitting merged load ops; only used on some architectures
-	registers      []Register    // machine registers
-	gpRegMask      regMask       // general purpose integer register mask
-	fpRegMask      regMask       // floating point register mask
-	fp32RegMask    regMask       // floating point register mask
-	fp64RegMask    regMask       // floating point register mask
-	specialRegMask regMask       // special register mask
-	GCRegMap       []*Register   // garbage collector register map, by GC register index
-	FPReg          int8          // register number of frame pointer, -1 if not used
-	LinkReg        int8          // register number of link register if it is a general purpose register, -1 if not used
-	hasGReg        bool          // has hardware g register
-	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
-	useAvg         bool          // Use optimizations that need Avg* operations
-	useHmul        bool          // Use optimizations that need Hmul* operations
-	SoftFloat      bool          //
-	Race           bool          // race detector enabled
-	NeedsFpScratch bool          // No direct move between GP and FP register sets
-	BigEndian      bool          //
-	UseFMA         bool          // Use hardware FMA operation
+	lowerBlock     blockRewriter  // lowering function
+	lowerValue     valueRewriter  // lowering function
+	splitLoad      valueRewriter  // function for splitting merged load ops; only used on some architectures
+	registers      []Register     // machine registers
+	gpRegMask      regMask        // general purpose integer register mask
+	fpRegMask      regMask        // floating point register mask
+	fp32RegMask    regMask        // floating point register mask
+	fp64RegMask    regMask        // floating point register mask
+	specialRegMask regMask        // special register mask
+	intParamRegs   []int8         // register numbers of integer param (in/out) registers
+	floatParamRegs []int8         // register numbers of floating param (in/out) registers
+	ABI1           *abi.ABIConfig // "ABIInternal" under development // TODO change comment when this becomes current
+	ABI0           *abi.ABIConfig
+	GCRegMap       []*Register // garbage collector register map, by GC register index
+	FPReg          int8        // register number of frame pointer, -1 if not used
+	LinkReg        int8        // register number of link register if it is a general purpose register, -1 if not used
+	hasGReg        bool        // has hardware g register
+	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
+	useAvg         bool        // Use optimizations that need Avg* operations
+	useHmul        bool        // Use optimizations that need Hmul* operations
+	SoftFloat      bool        //
+	Race           bool        // race detector enabled
+	BigEndian      bool        //
+	UseFMA         bool        // Use hardware FMA operation
 }
 
 type (
@@ -138,17 +143,10 @@
 
 	// Auto returns a Node for an auto variable of the given type.
 	// The SSA compiler uses this function to allocate space for spills.
-	Auto(src.XPos, *types.Type) GCNode
+	Auto(src.XPos, *types.Type) *ir.Name
 
 	// Given the name for a compound type, returns the name we should use
 	// for the parts of that compound type.
-	SplitString(LocalSlot) (LocalSlot, LocalSlot)
-	SplitInterface(LocalSlot) (LocalSlot, LocalSlot)
-	SplitSlice(LocalSlot) (LocalSlot, LocalSlot, LocalSlot)
-	SplitComplex(LocalSlot) (LocalSlot, LocalSlot)
-	SplitStruct(LocalSlot, int) LocalSlot
-	SplitArray(LocalSlot) LocalSlot              // array must be length 1
-	SplitInt64(LocalSlot) (LocalSlot, LocalSlot) // returns (hi, lo)
 	SplitSlot(parent *LocalSlot, suffix string, offset int64, t *types.Type) LocalSlot
 
 	// DerefItab dereferences an itab function
@@ -178,32 +176,6 @@
 	MyImportPath() string
 }
 
-// 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
-	IsSynthetic() bool
-	IsAutoTmp() bool
-	StorageClass() StorageClass
-}
-
-type StorageClass uint8
-
-const (
-	ClassAuto     StorageClass = iota // local stack variable
-	ClassParam                        // argument
-	ClassParamOut                     // return value
-)
-
-const go116lateCallExpansion = true
-
-// LateCallExpansionEnabledWithin returns true if late call expansion should be tested
-// within compilation of a function/method.
-func LateCallExpansionEnabledWithin(f *Func) bool {
-	return go116lateCallExpansion
-}
-
 // 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}
@@ -219,9 +191,12 @@
 		c.registers = registersAMD64[:]
 		c.gpRegMask = gpRegMaskAMD64
 		c.fpRegMask = fpRegMaskAMD64
+		c.specialRegMask = specialRegMaskAMD64
+		c.intParamRegs = paramIntRegAMD64
+		c.floatParamRegs = paramFloatRegAMD64
 		c.FPReg = framepointerRegAMD64
 		c.LinkReg = linkRegAMD64
-		c.hasGReg = false
+		c.hasGReg = buildcfg.Experiment.RegabiG
 	case "386":
 		c.PtrSize = 4
 		c.RegSize = 4
@@ -256,7 +231,7 @@
 		c.FPReg = framepointerRegARM64
 		c.LinkReg = linkRegARM64
 		c.hasGReg = true
-		c.noDuffDevice = objabi.GOOS == "darwin" || objabi.GOOS == "ios" // darwin linker cannot handle BR26 reloc with non-zero addend
+		c.noDuffDevice = buildcfg.GOOS == "darwin" || buildcfg.GOOS == "ios" // darwin linker cannot handle BR26 reloc with non-zero addend
 	case "ppc64":
 		c.BigEndian = true
 		fallthrough
@@ -350,8 +325,11 @@
 	c.useSSE = true
 	c.UseFMA = true
 
+	c.ABI0 = abi.NewABIConfig(0, 0, ctxt.FixedFrameSize())
+	c.ABI1 = abi.NewABIConfig(len(c.intParamRegs), len(c.floatParamRegs), ctxt.FixedFrameSize())
+
 	// On Plan 9, floating point operations are not allowed in note handler.
-	if objabi.GOOS == "plan9" {
+	if buildcfg.GOOS == "plan9" {
 		// Don't use FMA on Plan 9
 		c.UseFMA = false
 
diff --git a/src/cmd/compile/internal/ssa/copyelim.go b/src/cmd/compile/internal/ssa/copyelim.go
index 5954d3b..17f6512 100644
--- a/src/cmd/compile/internal/ssa/copyelim.go
+++ b/src/cmd/compile/internal/ssa/copyelim.go
@@ -26,7 +26,7 @@
 
 	// Update named values.
 	for _, name := range f.Names {
-		values := f.NamedValues[name]
+		values := f.NamedValues[*name]
 		for i, v := range values {
 			if v.Op == OpCopy {
 				values[i] = v.Args[0]
diff --git a/src/cmd/compile/internal/ssa/cse.go b/src/cmd/compile/internal/ssa/cse.go
index 3b4f2be..ade5e06 100644
--- a/src/cmd/compile/internal/ssa/cse.go
+++ b/src/cmd/compile/internal/ssa/cse.go
@@ -275,7 +275,7 @@
 	return types.CMPgt
 }
 
-type auxmap map[interface{}]int32
+type auxmap map[Aux]int32
 
 func cmpVal(v, w *Value, auxIDs auxmap) types.Cmp {
 	// Try to order these comparison by cost (cheaper first)
@@ -299,7 +299,7 @@
 	// OpSelect is a pseudo-op. We need to be more aggressive
 	// regarding CSE to keep multiple OpSelect's of the same
 	// argument from existing.
-	if v.Op != OpSelect0 && v.Op != OpSelect1 {
+	if v.Op != OpSelect0 && v.Op != OpSelect1 && v.Op != OpSelectN {
 		if tc := v.Type.Compare(w.Type); tc != types.CMPeq {
 			return tc
 		}
diff --git a/src/cmd/compile/internal/ssa/cse_test.go b/src/cmd/compile/internal/ssa/cse_test.go
index 9e76645..8052016 100644
--- a/src/cmd/compile/internal/ssa/cse_test.go
+++ b/src/cmd/compile/internal/ssa/cse_test.go
@@ -14,6 +14,8 @@
 	s string
 }
 
+func (*tstAux) CanBeAnSSAAux() {}
+
 // This tests for a bug found when partitioning, but not sorting by the Aux value.
 func TestCSEAuxPartitionBug(t *testing.T) {
 	c := testConfig(t)
diff --git a/src/cmd/compile/internal/ssa/deadcode.go b/src/cmd/compile/internal/ssa/deadcode.go
index 96b552e..5d10dfe 100644
--- a/src/cmd/compile/internal/ssa/deadcode.go
+++ b/src/cmd/compile/internal/ssa/deadcode.go
@@ -223,7 +223,7 @@
 	for _, name := range f.Names {
 		j := 0
 		s.clear()
-		values := f.NamedValues[name]
+		values := f.NamedValues[*name]
 		for _, v := range values {
 			if live[v.ID] && !s.contains(v.ID) {
 				values[j] = v
@@ -232,19 +232,19 @@
 			}
 		}
 		if j == 0 {
-			delete(f.NamedValues, name)
+			delete(f.NamedValues, *name)
 		} else {
 			f.Names[i] = name
 			i++
 			for k := len(values) - 1; k >= j; k-- {
 				values[k] = nil
 			}
-			f.NamedValues[name] = values[:j]
+			f.NamedValues[*name] = values[:j]
 		}
 	}
 	clearNames := f.Names[i:]
 	for j := range clearNames {
-		clearNames[j] = LocalSlot{}
+		clearNames[j] = nil
 	}
 	f.Names = f.Names[:i]
 
diff --git a/src/cmd/compile/internal/ssa/deadstore.go b/src/cmd/compile/internal/ssa/deadstore.go
index 0664013..d694133 100644
--- a/src/cmd/compile/internal/ssa/deadstore.go
+++ b/src/cmd/compile/internal/ssa/deadstore.go
@@ -5,6 +5,7 @@
 package ssa
 
 import (
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/types"
 	"cmd/internal/src"
 )
@@ -136,9 +137,9 @@
 // reaches stores then we delete all the stores. The other operations will then
 // be eliminated by the dead code elimination pass.
 func elimDeadAutosGeneric(f *Func) {
-	addr := make(map[*Value]GCNode) // values that the address of the auto reaches
-	elim := make(map[*Value]GCNode) // values that could be eliminated if the auto is
-	used := make(map[GCNode]bool)   // used autos that must be kept
+	addr := make(map[*Value]*ir.Name) // values that the address of the auto reaches
+	elim := make(map[*Value]*ir.Name) // values that could be eliminated if the auto is
+	var used ir.NameSet               // used autos that must be kept
 
 	// visit the value and report whether any of the maps are updated
 	visit := func(v *Value) (changed bool) {
@@ -146,8 +147,8 @@
 		switch v.Op {
 		case OpAddr, OpLocalAddr:
 			// Propagate the address if it points to an auto.
-			n, ok := v.Aux.(GCNode)
-			if !ok || n.StorageClass() != ClassAuto {
+			n, ok := v.Aux.(*ir.Name)
+			if !ok || n.Class != ir.PAUTO {
 				return
 			}
 			if addr[v] == nil {
@@ -157,8 +158,8 @@
 			return
 		case OpVarDef, OpVarKill:
 			// v should be eliminated if we eliminate the auto.
-			n, ok := v.Aux.(GCNode)
-			if !ok || n.StorageClass() != ClassAuto {
+			n, ok := v.Aux.(*ir.Name)
+			if !ok || n.Class != ir.PAUTO {
 				return
 			}
 			if elim[v] == nil {
@@ -173,12 +174,12 @@
 			// for open-coded defers from being removed (since they
 			// may not be used by the inline code, but will be used by
 			// panic processing).
-			n, ok := v.Aux.(GCNode)
-			if !ok || n.StorageClass() != ClassAuto {
+			n, ok := v.Aux.(*ir.Name)
+			if !ok || n.Class != ir.PAUTO {
 				return
 			}
-			if !used[n] {
-				used[n] = true
+			if !used.Has(n) {
+				used.Add(n)
 				changed = true
 			}
 			return
@@ -200,8 +201,9 @@
 			panic("unhandled op with sym effect")
 		}
 
-		if v.Uses == 0 && v.Op != OpNilCheck || len(args) == 0 {
+		if v.Uses == 0 && v.Op != OpNilCheck && !v.Op.IsCall() && !v.Op.HasSideEffects() || len(args) == 0 {
 			// Nil check has no use, but we need to keep it.
+			// Also keep calls and values that have side effects.
 			return
 		}
 
@@ -211,8 +213,8 @@
 		if v.Type.IsMemory() || v.Type.IsFlags() || v.Op == OpPhi || v.MemoryArg() != nil {
 			for _, a := range args {
 				if n, ok := addr[a]; ok {
-					if !used[n] {
-						used[n] = true
+					if !used.Has(n) {
+						used.Add(n)
 						changed = true
 					}
 				}
@@ -221,9 +223,9 @@
 		}
 
 		// Propagate any auto addresses through v.
-		node := GCNode(nil)
+		var node *ir.Name
 		for _, a := range args {
-			if n, ok := addr[a]; ok && !used[n] {
+			if n, ok := addr[a]; ok && !used.Has(n) {
 				if node == nil {
 					node = n
 				} else if node != n {
@@ -232,7 +234,7 @@
 					// multiple pointers (e.g. NeqPtr, Phi etc.).
 					// This is rare, so just propagate the first
 					// value to keep things simple.
-					used[n] = true
+					used.Add(n)
 					changed = true
 				}
 			}
@@ -248,7 +250,7 @@
 		}
 		if addr[v] != node {
 			// This doesn't happen in practice, but catch it just in case.
-			used[node] = true
+			used.Add(node)
 			changed = true
 		}
 		return
@@ -268,8 +270,8 @@
 			}
 			// keep the auto if its address reaches a control value
 			for _, c := range b.ControlValues() {
-				if n, ok := addr[c]; ok && !used[n] {
-					used[n] = true
+				if n, ok := addr[c]; ok && !used.Has(n) {
+					used.Add(n)
 					changed = true
 				}
 			}
@@ -281,7 +283,7 @@
 
 	// Eliminate stores to unread autos.
 	for v, n := range elim {
-		if used[n] {
+		if used.Has(n) {
 			continue
 		}
 		// replace with OpCopy
@@ -298,15 +300,15 @@
 	// 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 seen ir.NameSet
 	var stores []*Value
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
-			n, ok := v.Aux.(GCNode)
+			n, ok := v.Aux.(*ir.Name)
 			if !ok {
 				continue
 			}
-			if n.StorageClass() != ClassAuto {
+			if n.Class != ir.PAUTO {
 				continue
 			}
 
@@ -316,7 +318,7 @@
 				// If we haven't seen the auto yet
 				// then this might be a store we can
 				// eliminate.
-				if !seen[n] {
+				if !seen.Has(n) {
 					stores = append(stores, v)
 				}
 			default:
@@ -326,7 +328,7 @@
 				// because dead loads haven't been
 				// eliminated yet.
 				if v.Uses > 0 {
-					seen[n] = true
+					seen.Add(n)
 				}
 			}
 		}
@@ -334,8 +336,8 @@
 
 	// Eliminate stores to unread autos.
 	for _, store := range stores {
-		n, _ := store.Aux.(GCNode)
-		if seen[n] {
+		n, _ := store.Aux.(*ir.Name)
+		if seen.Has(n) {
 			continue
 		}
 
diff --git a/src/cmd/compile/internal/ssa/debug.go b/src/cmd/compile/internal/ssa/debug.go
index 6353f72..8e28723 100644
--- a/src/cmd/compile/internal/ssa/debug.go
+++ b/src/cmd/compile/internal/ssa/debug.go
@@ -5,10 +5,15 @@
 package ssa
 
 import (
+	"cmd/compile/internal/abi"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
 	"cmd/internal/dwarf"
 	"cmd/internal/obj"
+	"cmd/internal/src"
 	"encoding/hex"
 	"fmt"
+	"internal/buildcfg"
 	"math/bits"
 	"sort"
 	"strings"
@@ -24,7 +29,7 @@
 	// Slots is all the slots used in the debug info, indexed by their SlotID.
 	Slots []LocalSlot
 	// The user variables, indexed by VarID.
-	Vars []GCNode
+	Vars []*ir.Name
 	// The slots that make up each variable, indexed by VarID.
 	VarSlots [][]SlotID
 	// The location list data, indexed by VarID. Must be processed by PutLocationList.
@@ -142,13 +147,19 @@
 var BlockStart = &Value{
 	ID:  -10000,
 	Op:  OpInvalid,
-	Aux: "BlockStart",
+	Aux: StringToAux("BlockStart"),
 }
 
 var BlockEnd = &Value{
 	ID:  -20000,
 	Op:  OpInvalid,
-	Aux: "BlockEnd",
+	Aux: StringToAux("BlockEnd"),
+}
+
+var FuncEnd = &Value{
+	ID:  -30000,
+	Op:  OpInvalid,
+	Aux: StringToAux("FuncEnd"),
 }
 
 // RegisterSet is a bitmap of registers, indexed by Register.num.
@@ -165,7 +176,7 @@
 type debugState struct {
 	// See FuncDebug.
 	slots    []LocalSlot
-	vars     []GCNode
+	vars     []*ir.Name
 	varSlots [][]SlotID
 	lists    [][]byte
 
@@ -189,7 +200,7 @@
 	// The pending location list entry for each user variable, indexed by VarID.
 	pendingEntries []pendingEntry
 
-	varParts           map[GCNode][]SlotID
+	varParts           map[*ir.Name][]SlotID
 	blockDebug         []BlockDebug
 	pendingSlotLocs    []VarLoc
 	liveSlots          []liveSlot
@@ -327,6 +338,216 @@
 	return strings.Join(strs, "")
 }
 
+// slotCanonicalizer is a table used to lookup and canonicalize
+// LocalSlot's in a type insensitive way (e.g. taking into account the
+// base name, offset, and width of the slot, but ignoring the slot
+// type).
+type slotCanonicalizer struct {
+	slmap  map[slotKey]SlKeyIdx
+	slkeys []LocalSlot
+}
+
+func newSlotCanonicalizer() *slotCanonicalizer {
+	return &slotCanonicalizer{
+		slmap:  make(map[slotKey]SlKeyIdx),
+		slkeys: []LocalSlot{LocalSlot{N: nil}},
+	}
+}
+
+type SlKeyIdx uint32
+
+const noSlot = SlKeyIdx(0)
+
+// slotKey is a type-insensitive encapsulation of a LocalSlot; it
+// is used to key a map within slotCanonicalizer.
+type slotKey struct {
+	name        *ir.Name
+	offset      int64
+	width       int64
+	splitOf     SlKeyIdx // idx in slkeys slice in slotCanonicalizer
+	splitOffset int64
+}
+
+// lookup looks up a LocalSlot in the slot canonicalizer "sc", returning
+// a canonical index for the slot, and adding it to the table if need
+// be. Return value is the canonical slot index, and a boolean indicating
+// whether the slot was found in the table already (TRUE => found).
+func (sc *slotCanonicalizer) lookup(ls LocalSlot) (SlKeyIdx, bool) {
+	split := noSlot
+	if ls.SplitOf != nil {
+		split, _ = sc.lookup(*ls.SplitOf)
+	}
+	k := slotKey{
+		name: ls.N, offset: ls.Off, width: ls.Type.Width,
+		splitOf: split, splitOffset: ls.SplitOffset,
+	}
+	if idx, ok := sc.slmap[k]; ok {
+		return idx, true
+	}
+	rv := SlKeyIdx(len(sc.slkeys))
+	sc.slkeys = append(sc.slkeys, ls)
+	sc.slmap[k] = rv
+	return rv, false
+}
+
+func (sc *slotCanonicalizer) canonSlot(idx SlKeyIdx) LocalSlot {
+	return sc.slkeys[idx]
+}
+
+// PopulateABIInRegArgOps examines the entry block of the function
+// and looks for incoming parameters that have missing or partial
+// OpArg{Int,Float}Reg values, inserting additional values in
+// cases where they are missing. Example:
+//
+//      func foo(s string, used int, notused int) int {
+//        return len(s) + used
+//      }
+//
+// In the function above, the incoming parameter "used" is fully live,
+// "notused" is not live, and "s" is partially live (only the length
+// field of the string is used). At the point where debug value
+// analysis runs, we might expect to see an entry block with:
+//
+//   b1:
+//     v4 = ArgIntReg <uintptr> {s+8} [0] : BX
+//     v5 = ArgIntReg <int> {used} [0] : CX
+//
+// While this is an accurate picture of the live incoming params,
+// we also want to have debug locations for non-live params (or
+// their non-live pieces), e.g. something like
+//
+//   b1:
+//     v9 = ArgIntReg <*uint8> {s+0} [0] : AX
+//     v4 = ArgIntReg <uintptr> {s+8} [0] : BX
+//     v5 = ArgIntReg <int> {used} [0] : CX
+//     v10 = ArgIntReg <int> {unused} [0] : DI
+//
+// This function examines the live OpArg{Int,Float}Reg values and
+// synthesizes new (dead) values for the non-live params or the
+// non-live pieces of partially live params.
+//
+func PopulateABIInRegArgOps(f *Func) {
+	pri := f.ABISelf.ABIAnalyzeFuncType(f.Type.FuncType())
+
+	// When manufacturing new slots that correspond to splits of
+	// composite parameters, we want to avoid creating a new sub-slot
+	// that differs from some existing sub-slot only by type, since
+	// the debug location analysis will treat that slot as a separate
+	// entity. To achieve this, create a lookup table of existing
+	// slots that is type-insenstitive.
+	sc := newSlotCanonicalizer()
+	for _, sl := range f.Names {
+		sc.lookup(*sl)
+	}
+
+	// Add slot -> value entry to f.NamedValues if not already present.
+	addToNV := func(v *Value, sl LocalSlot) {
+		values, ok := f.NamedValues[sl]
+		if !ok {
+			// Haven't seen this slot yet.
+			sla := f.localSlotAddr(sl)
+			f.Names = append(f.Names, sla)
+		} else {
+			for _, ev := range values {
+				if v == ev {
+					return
+				}
+			}
+		}
+		values = append(values, v)
+		f.NamedValues[sl] = values
+	}
+
+	newValues := []*Value{}
+
+	abiRegIndexToRegister := func(reg abi.RegIndex) int8 {
+		i := f.ABISelf.FloatIndexFor(reg)
+		if i >= 0 { // float PR
+			return f.Config.floatParamRegs[i]
+		} else {
+			return f.Config.intParamRegs[reg]
+		}
+	}
+
+	// Helper to construct a new OpArg{Float,Int}Reg op value.
+	var pos src.XPos
+	if len(f.Entry.Values) != 0 {
+		pos = f.Entry.Values[0].Pos
+	}
+	synthesizeOpIntFloatArg := func(n *ir.Name, t *types.Type, reg abi.RegIndex, sl LocalSlot) *Value {
+		aux := &AuxNameOffset{n, sl.Off}
+		op, auxInt := ArgOpAndRegisterFor(reg, f.ABISelf)
+		v := f.newValueNoBlock(op, t, pos)
+		v.AuxInt = auxInt
+		v.Aux = aux
+		v.Args = nil
+		v.Block = f.Entry
+		newValues = append(newValues, v)
+		addToNV(v, sl)
+		f.setHome(v, &f.Config.registers[abiRegIndexToRegister(reg)])
+		return v
+	}
+
+	// Make a pass through the entry block looking for
+	// OpArg{Int,Float}Reg ops. Record the slots they use in a table
+	// ("sc"). We use a type-insensitive lookup for the slot table,
+	// since the type we get from the ABI analyzer won't always match
+	// what the compiler uses when creating OpArg{Int,Float}Reg ops.
+	for _, v := range f.Entry.Values {
+		if v.Op == OpArgIntReg || v.Op == OpArgFloatReg {
+			aux := v.Aux.(*AuxNameOffset)
+			sl := LocalSlot{N: aux.Name, Type: v.Type, Off: aux.Offset}
+			// install slot in lookup table
+			idx, _ := sc.lookup(sl)
+			// add to f.NamedValues if not already present
+			addToNV(v, sc.canonSlot(idx))
+		} else if v.Op.IsCall() {
+			// if we hit a call, we've gone too far.
+			break
+		}
+	}
+
+	// Now make a pass through the ABI in-params, looking for params
+	// or pieces of params that we didn't encounter in the loop above.
+	for _, inp := range pri.InParams() {
+		if !isNamedRegParam(inp) {
+			continue
+		}
+		n := inp.Name.(*ir.Name)
+
+		// Param is spread across one or more registers. Walk through
+		// each piece to see whether we've seen an arg reg op for it.
+		types, offsets := inp.RegisterTypesAndOffsets()
+		for k, t := range types {
+			// Note: this recipe for creating a LocalSlot is designed
+			// to be compatible with the one used in expand_calls.go
+			// as opposed to decompose.go. The expand calls code just
+			// takes the base name and creates an offset into it,
+			// without using the SplitOf/SplitOffset fields. The code
+			// in decompose.go does the opposite -- it creates a
+			// LocalSlot object with "Off" set to zero, but with
+			// SplitOf pointing to a parent slot, and SplitOffset
+			// holding the offset into the parent object.
+			pieceSlot := LocalSlot{N: n, Type: t, Off: offsets[k]}
+
+			// Look up this piece to see if we've seen a reg op
+			// for it. If not, create one.
+			_, found := sc.lookup(pieceSlot)
+			if !found {
+				// This slot doesn't appear in the map, meaning it
+				// corresponds to an in-param that is not live, or
+				// a portion of an in-param that is not live/used.
+				// Add a new dummy OpArg{Int,Float}Reg for it.
+				synthesizeOpIntFloatArg(n, t, inp.Registers[k],
+					pieceSlot)
+			}
+		}
+	}
+
+	// Insert the new values into the head of the block.
+	f.Entry.Values = append(newValues, f.Entry.Values...)
+}
+
 // 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.
@@ -341,12 +562,16 @@
 	state.stackOffset = stackOffset
 	state.ctxt = ctxt
 
+	if buildcfg.Experiment.RegabiArgs {
+		PopulateABIInRegArgOps(f)
+	}
+
 	if state.loggingEnabled {
 		state.logf("Generating location lists for function %q\n", f.Name)
 	}
 
 	if state.varParts == nil {
-		state.varParts = make(map[GCNode][]SlotID)
+		state.varParts = make(map[*ir.Name][]SlotID)
 	} else {
 		for n := range state.varParts {
 			delete(state.varParts, n)
@@ -359,12 +584,12 @@
 	state.slots = state.slots[:0]
 	state.vars = state.vars[:0]
 	for i, slot := range f.Names {
-		state.slots = append(state.slots, slot)
-		if slot.N.IsSynthetic() {
+		state.slots = append(state.slots, *slot)
+		if ir.IsSynthetic(slot.N) {
 			continue
 		}
 
-		topSlot := &slot
+		topSlot := slot
 		for topSlot.SplitOf != nil {
 			topSlot = topSlot.SplitOf
 		}
@@ -379,8 +604,8 @@
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
 			if v.Op == OpVarDef || v.Op == OpVarKill {
-				n := v.Aux.(GCNode)
-				if n.IsSynthetic() {
+				n := v.Aux.(*ir.Name)
+				if ir.IsSynthetic(n) {
 					continue
 				}
 
@@ -425,10 +650,10 @@
 	state.initializeCache(f, len(state.varParts), len(state.slots))
 
 	for i, slot := range f.Names {
-		if slot.N.IsSynthetic() {
+		if ir.IsSynthetic(slot.N) {
 			continue
 		}
-		for _, value := range f.NamedValues[slot] {
+		for _, value := range f.NamedValues[*slot] {
 			state.valueNames[value.ID] = append(state.valueNames[value.ID], SlotID(i))
 		}
 	}
@@ -717,8 +942,8 @@
 
 	switch {
 	case v.Op == OpVarDef, v.Op == OpVarKill:
-		n := v.Aux.(GCNode)
-		if n.IsSynthetic() {
+		n := v.Aux.(*ir.Name)
+		if ir.IsSynthetic(n) {
 			break
 		}
 
@@ -890,8 +1115,14 @@
 			continue
 		}
 
+		mustBeFirst := func(v *Value) bool {
+			return v.Op == OpPhi || v.Op.isLoweredGetClosurePtr() ||
+				v.Op == OpArgIntReg || v.Op == OpArgFloatReg
+		}
+
 		zeroWidthPending := false
-		apcChangedSize := 0 // size of changedVars for leading Args, Phi, ClosurePtr
+		blockPrologComplete := false // set to true at first non-zero-width op
+		apcChangedSize := 0          // size of changedVars for leading Args, Phi, ClosurePtr
 		// expect to see values in pattern (apc)* (zerowidth|real)*
 		for _, v := range b.Values {
 			slots := state.valueNames[v.ID]
@@ -900,16 +1131,16 @@
 
 			if opcodeTable[v.Op].zeroWidth {
 				if changed {
-					if v.Op == OpArg || v.Op == OpPhi || v.Op.isLoweredGetClosurePtr() {
+					if mustBeFirst(v) || v.Op == OpArg {
 						// These ranges begin at true beginning of block, not after first instruction
-						if zeroWidthPending {
-							b.Func.Fatalf("Unexpected op mixed with OpArg/OpPhi/OpLoweredGetClosurePtr at beginning of block %s in %s\n%s", b, b.Func.Name, b.Func)
+						if blockPrologComplete && mustBeFirst(v) {
+							panic(fmt.Errorf("Unexpected placement of op '%s' appearing after non-pseudo-op at beginning of block %s in %s\n%s", v.LongString(), b, b.Func.Name, b.Func))
 						}
 						apcChangedSize = len(state.changedVars.contents())
+						// Other zero-width ops must wait on a "real" op.
+						zeroWidthPending = true
 						continue
 					}
-					// Other zero-width ops must wait on a "real" op.
-					zeroWidthPending = true
 				}
 				continue
 			}
@@ -920,6 +1151,7 @@
 			// Not zero-width; i.e., a "real" instruction.
 
 			zeroWidthPending = false
+			blockPrologComplete = true
 			for i, varID := range state.changedVars.contents() {
 				if i < apcChangedSize { // buffered true start-of-block changes
 					state.updateVar(VarID(varID), v.Block, BlockStart)
@@ -947,7 +1179,7 @@
 
 	// Flush any leftover entries live at the end of the last block.
 	for varID := range state.lists {
-		state.writePendingEntry(VarID(varID), state.f.Blocks[len(state.f.Blocks)-1].ID, BlockEnd.ID)
+		state.writePendingEntry(VarID(varID), state.f.Blocks[len(state.f.Blocks)-1].ID, FuncEnd.ID)
 		list := state.lists[varID]
 		if state.loggingEnabled {
 			if len(list) == 0 {
@@ -1117,8 +1349,11 @@
 	listSym.WriteInt(ctxt, listSym.Size, ctxt.Arch.PtrSize, 0)
 }
 
-// Pack a value and block ID into an address-sized uint, returning ~0 if they
-// don't fit.
+// Pack a value and block ID into an address-sized uint, returning encoded
+// value and boolean indicating whether the encoding succeeded.  For
+// 32-bit architectures the process may fail for very large procedures
+// (the theory being that it's ok to have degraded debug quality in
+// this case).
 func encodeValue(ctxt *obj.Link, b, v ID) (uint64, bool) {
 	if ctxt.Arch.PtrSize == 8 {
 		result := uint64(b)<<32 | uint64(uint32(v))
@@ -1185,3 +1420,276 @@
 	}
 
 }
+
+// setupLocList creates the initial portion of a location list for a
+// user variable. It emits the encoded start/end of the range and a
+// placeholder for the size. Return value is the new list plus the
+// slot in the list holding the size (to be updated later).
+func setupLocList(ctxt *obj.Link, f *Func, list []byte, st, en ID) ([]byte, int) {
+	start, startOK := encodeValue(ctxt, f.Entry.ID, st)
+	end, endOK := encodeValue(ctxt, f.Entry.ID, en)
+	if !startOK || !endOK {
+		// This could happen if someone writes a function that uses
+		// >65K values on a 32-bit platform. Hopefully a degraded debugging
+		// experience is ok in that case.
+		return nil, 0
+	}
+	list = appendPtr(ctxt, list, start)
+	list = appendPtr(ctxt, list, end)
+
+	// Where to write the length of the location description once
+	// we know how big it is.
+	sizeIdx := len(list)
+	list = list[:len(list)+2]
+	return list, sizeIdx
+}
+
+// locatePrologEnd walks the entry block of a function with incoming
+// register arguments and locates the last instruction in the prolog
+// that spills a register arg. It returns the ID of that instruction
+// Example:
+//
+//   b1:
+//       v3 = ArgIntReg <int> {p1+0} [0] : AX
+//       ... more arg regs ..
+//       v4 = ArgFloatReg <float32> {f1+0} [0] : X0
+//       v52 = MOVQstore <mem> {p1} v2 v3 v1
+//       ... more stores ...
+//       v68 = MOVSSstore <mem> {f4} v2 v67 v66
+//       v38 = MOVQstoreconst <mem> {blob} [val=0,off=0] v2 v32
+//
+// Important: locatePrologEnd is expected to work properly only with
+// optimization turned off (e.g. "-N"). If optimization is enabled
+// we can't be assured of finding all input arguments spilled in the
+// entry block prolog.
+func locatePrologEnd(f *Func) ID {
+
+	// returns true if this instruction looks like it moves an ABI
+	// register to the stack, along with the value being stored.
+	isRegMoveLike := func(v *Value) (bool, ID) {
+		n, ok := v.Aux.(*ir.Name)
+		var r ID
+		if !ok || n.Class != ir.PPARAM {
+			return false, r
+		}
+		regInputs, memInputs, spInputs := 0, 0, 0
+		for _, a := range v.Args {
+			if a.Op == OpArgIntReg || a.Op == OpArgFloatReg {
+				regInputs++
+				r = a.ID
+			} else if a.Type.IsMemory() {
+				memInputs++
+			} else if a.Op == OpSP {
+				spInputs++
+			} else {
+				return false, r
+			}
+		}
+		return v.Type.IsMemory() && memInputs == 1 &&
+			regInputs == 1 && spInputs == 1, r
+	}
+
+	// OpArg*Reg values we've seen so far on our forward walk,
+	// for which we have not yet seen a corresponding spill.
+	regArgs := make([]ID, 0, 32)
+
+	// removeReg tries to remove a value from regArgs, returning true
+	// if found and removed, or false otherwise.
+	removeReg := func(r ID) bool {
+		for i := 0; i < len(regArgs); i++ {
+			if regArgs[i] == r {
+				regArgs = append(regArgs[:i], regArgs[i+1:]...)
+				return true
+			}
+		}
+		return false
+	}
+
+	// Walk forwards through the block. When we see OpArg*Reg, record
+	// the value it produces in the regArgs list. When see a store that uses
+	// the value, remove the entry. When we hit the last store (use)
+	// then we've arrived at the end of the prolog.
+	for k, v := range f.Entry.Values {
+		if v.Op == OpArgIntReg || v.Op == OpArgFloatReg {
+			regArgs = append(regArgs, v.ID)
+			continue
+		}
+		if ok, r := isRegMoveLike(v); ok {
+			if removed := removeReg(r); removed {
+				if len(regArgs) == 0 {
+					// Found our last spill; return the value after
+					// it. Note that it is possible that this spill is
+					// the last instruction in the block. If so, then
+					// return the "end of block" sentinel.
+					if k < len(f.Entry.Values)-1 {
+						return f.Entry.Values[k+1].ID
+					}
+					return BlockEnd.ID
+				}
+			}
+		}
+		if v.Op.IsCall() {
+			// if we hit a call, we've gone too far.
+			return v.ID
+		}
+	}
+	// nothing found
+	return ID(-1)
+}
+
+// isNamedRegParam returns true if the param corresponding to "p"
+// is a named, non-blank input parameter assigned to one or more
+// registers.
+func isNamedRegParam(p abi.ABIParamAssignment) bool {
+	if p.Name == nil {
+		return false
+	}
+	n := p.Name.(*ir.Name)
+	if n.Sym() == nil || n.Sym().IsBlank() {
+		return false
+	}
+	if len(p.Registers) == 0 {
+		return false
+	}
+	return true
+}
+
+// BuildFuncDebugNoOptimized constructs a FuncDebug object with
+// entries corresponding to the register-resident input parameters for
+// the function "f"; it is used when we are compiling without
+// optimization but the register ABI is enabled. For each reg param,
+// it constructs a 2-element location list: the first element holds
+// the input register, and the second element holds the stack location
+// of the param (the assumption being that when optimization is off,
+// each input param reg will be spilled in the prolog.
+func BuildFuncDebugNoOptimized(ctxt *obj.Link, f *Func, loggingEnabled bool, stackOffset func(LocalSlot) int32) *FuncDebug {
+	fd := FuncDebug{}
+
+	pri := f.ABISelf.ABIAnalyzeFuncType(f.Type.FuncType())
+
+	// Look to see if we have any named register-promoted parameters.
+	// If there are none, bail early and let the caller sort things
+	// out for the remainder of the params/locals.
+	numRegParams := 0
+	for _, inp := range pri.InParams() {
+		if isNamedRegParam(inp) {
+			numRegParams++
+		}
+	}
+	if numRegParams == 0 {
+		return &fd
+	}
+
+	state := debugState{f: f}
+
+	if loggingEnabled {
+		state.logf("generating -N reg param loc lists for func %q\n", f.Name)
+	}
+
+	// Allocate location lists.
+	fd.LocationLists = make([][]byte, numRegParams)
+
+	// Locate the value corresponding to the last spill of
+	// an input register.
+	afterPrologVal := locatePrologEnd(f)
+
+	// Walk the input params again and process the register-resident elements.
+	pidx := 0
+	for _, inp := range pri.InParams() {
+		if !isNamedRegParam(inp) {
+			// will be sorted out elsewhere
+			continue
+		}
+
+		n := inp.Name.(*ir.Name)
+		sl := LocalSlot{N: n, Type: inp.Type, Off: 0}
+		fd.Vars = append(fd.Vars, n)
+		fd.Slots = append(fd.Slots, sl)
+		slid := len(fd.VarSlots)
+		fd.VarSlots = append(fd.VarSlots, []SlotID{SlotID(slid)})
+
+		if afterPrologVal == ID(-1) {
+			// This can happen for degenerate functions with infinite
+			// loops such as that in issue 45948. In such cases, leave
+			// the var/slot set up for the param, but don't try to
+			// emit a location list.
+			if loggingEnabled {
+				state.logf("locatePrologEnd failed, skipping %v\n", n)
+			}
+			pidx++
+			continue
+		}
+
+		// Param is arriving in one or more registers. We need a 2-element
+		// location expression for it. First entry in location list
+		// will correspond to lifetime in input registers.
+		list, sizeIdx := setupLocList(ctxt, f, fd.LocationLists[pidx],
+			BlockStart.ID, afterPrologVal)
+		if list == nil {
+			pidx++
+			continue
+		}
+		if loggingEnabled {
+			state.logf("param %v:\n  [<entry>, %d]:\n", n, afterPrologVal)
+		}
+		rtypes, _ := inp.RegisterTypesAndOffsets()
+		padding := make([]uint64, 0, 32)
+		padding = inp.ComputePadding(padding)
+		for k, r := range inp.Registers {
+			reg := ObjRegForAbiReg(r, f.Config)
+			dwreg := ctxt.Arch.DWARFRegisters[reg]
+			if dwreg < 32 {
+				list = append(list, dwarf.DW_OP_reg0+byte(dwreg))
+			} else {
+				list = append(list, dwarf.DW_OP_regx)
+				list = dwarf.AppendUleb128(list, uint64(dwreg))
+			}
+			if loggingEnabled {
+				state.logf("    piece %d -> dwreg %d", k, dwreg)
+			}
+			if len(inp.Registers) > 1 {
+				list = append(list, dwarf.DW_OP_piece)
+				ts := rtypes[k].Width
+				list = dwarf.AppendUleb128(list, uint64(ts))
+				if padding[k] > 0 {
+					if loggingEnabled {
+						state.logf(" [pad %d bytes]", padding[k])
+					}
+					list = append(list, dwarf.DW_OP_piece)
+					list = dwarf.AppendUleb128(list, padding[k])
+				}
+			}
+			if loggingEnabled {
+				state.logf("\n")
+			}
+		}
+		// fill in length of location expression element
+		ctxt.Arch.ByteOrder.PutUint16(list[sizeIdx:], uint16(len(list)-sizeIdx-2))
+
+		// Second entry in the location list will be the stack home
+		// of the param, once it has been spilled.  Emit that now.
+		list, sizeIdx = setupLocList(ctxt, f, list,
+			afterPrologVal, FuncEnd.ID)
+		if list == nil {
+			pidx++
+			continue
+		}
+		soff := stackOffset(sl)
+		if soff == 0 {
+			list = append(list, dwarf.DW_OP_call_frame_cfa)
+		} else {
+			list = append(list, dwarf.DW_OP_fbreg)
+			list = dwarf.AppendSleb128(list, int64(soff))
+		}
+		if loggingEnabled {
+			state.logf("  [%d, <end>): stackOffset=%d\n", afterPrologVal, soff)
+		}
+
+		// fill in size
+		ctxt.Arch.ByteOrder.PutUint16(list[sizeIdx:], uint16(len(list)-sizeIdx-2))
+
+		fd.LocationLists[pidx] = list
+		pidx++
+	}
+	return &fd
+}
diff --git a/src/cmd/compile/internal/ssa/decompose.go b/src/cmd/compile/internal/ssa/decompose.go
index bf7f1e8..753d69c 100644
--- a/src/cmd/compile/internal/ssa/decompose.go
+++ b/src/cmd/compile/internal/ssa/decompose.go
@@ -24,7 +24,7 @@
 	}
 
 	// Decompose other values
-	// Note: deadcode is false because we need to keep the original
+	// Note: Leave dead values because we need to keep the original
 	// values around so the name component resolution below can still work.
 	applyRewrite(f, rewriteBlockdec, rewriteValuedec, leaveDeadValues)
 	if f.Config.RegSize == 4 {
@@ -36,64 +36,65 @@
 	// accumulate new LocalSlots in newNames for addition after the iteration.  This decomposition is for
 	// builtin types with leaf components, and thus there is no need to reprocess the newly create LocalSlots.
 	var toDelete []namedVal
-	var newNames []LocalSlot
+	var newNames []*LocalSlot
 	for i, name := range f.Names {
 		t := name.Type
 		switch {
 		case t.IsInteger() && t.Size() > f.Config.RegSize:
-			hiName, loName := f.fe.SplitInt64(name)
-			newNames = append(newNames, hiName, loName)
-			for j, v := range f.NamedValues[name] {
+			hiName, loName := f.SplitInt64(name)
+			newNames = maybeAppend2(f, newNames, hiName, loName)
+			for j, v := range f.NamedValues[*name] {
 				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])
+				f.NamedValues[*hiName] = append(f.NamedValues[*hiName], v.Args[0])
+				f.NamedValues[*loName] = append(f.NamedValues[*loName], v.Args[1])
 				toDelete = append(toDelete, namedVal{i, j})
 			}
 		case t.IsComplex():
-			rName, iName := f.fe.SplitComplex(name)
-			newNames = append(newNames, rName, iName)
-			for j, v := range f.NamedValues[name] {
+			rName, iName := f.SplitComplex(name)
+			newNames = maybeAppend2(f, newNames, rName, iName)
+			for j, v := range f.NamedValues[*name] {
 				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])
+				f.NamedValues[*rName] = append(f.NamedValues[*rName], v.Args[0])
+				f.NamedValues[*iName] = append(f.NamedValues[*iName], v.Args[1])
 				toDelete = append(toDelete, namedVal{i, j})
 			}
 		case t.IsString():
-			ptrName, lenName := f.fe.SplitString(name)
-			newNames = append(newNames, ptrName, lenName)
-			for j, v := range f.NamedValues[name] {
+			ptrName, lenName := f.SplitString(name)
+			newNames = maybeAppend2(f, newNames, ptrName, lenName)
+			for j, v := range f.NamedValues[*name] {
 				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])
+				f.NamedValues[*ptrName] = append(f.NamedValues[*ptrName], v.Args[0])
+				f.NamedValues[*lenName] = append(f.NamedValues[*lenName], v.Args[1])
 				toDelete = append(toDelete, namedVal{i, j})
 			}
 		case t.IsSlice():
-			ptrName, lenName, capName := f.fe.SplitSlice(name)
-			newNames = append(newNames, ptrName, lenName, capName)
-			for j, v := range f.NamedValues[name] {
+			ptrName, lenName, capName := f.SplitSlice(name)
+			newNames = maybeAppend2(f, newNames, ptrName, lenName)
+			newNames = maybeAppend(f, newNames, capName)
+			for j, v := range f.NamedValues[*name] {
 				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])
+				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])
 				toDelete = append(toDelete, namedVal{i, j})
 			}
 		case t.IsInterface():
-			typeName, dataName := f.fe.SplitInterface(name)
-			newNames = append(newNames, typeName, dataName)
-			for j, v := range f.NamedValues[name] {
+			typeName, dataName := f.SplitInterface(name)
+			newNames = maybeAppend2(f, newNames, typeName, dataName)
+			for j, v := range f.NamedValues[*name] {
 				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])
+				f.NamedValues[*typeName] = append(f.NamedValues[*typeName], v.Args[0])
+				f.NamedValues[*dataName] = append(f.NamedValues[*dataName], v.Args[1])
 				toDelete = append(toDelete, namedVal{i, j})
 			}
 		case t.IsFloat():
@@ -107,6 +108,18 @@
 	f.Names = append(f.Names, newNames...)
 }
 
+func maybeAppend(f *Func, ss []*LocalSlot, s *LocalSlot) []*LocalSlot {
+	if _, ok := f.NamedValues[*s]; !ok {
+		f.NamedValues[*s] = nil
+		return append(ss, s)
+	}
+	return ss
+}
+
+func maybeAppend2(f *Func, ss []*LocalSlot, s1, s2 *LocalSlot) []*LocalSlot {
+	return maybeAppend(f, maybeAppend(f, ss, s1), s2)
+}
+
 func decomposeBuiltInPhi(v *Value) {
 	switch {
 	case v.Type.IsInteger() && v.Type.Size() > v.Block.Func.Config.RegSize:
@@ -219,10 +232,6 @@
 	v.AddArg(data)
 }
 
-func decomposeArgs(f *Func) {
-	applyRewrite(f, rewriteBlockdecArgs, rewriteValuedecArgs, removeDeadValues)
-}
-
 func decomposeUser(f *Func) {
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
@@ -234,7 +243,7 @@
 	}
 	// Split up named values into their components.
 	i := 0
-	var newNames []LocalSlot
+	var newNames []*LocalSlot
 	for _, name := range f.Names {
 		t := name.Type
 		switch {
@@ -254,7 +263,7 @@
 // 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 {
+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.
@@ -265,20 +274,20 @@
 		// shouldn't get here due to CanSSA
 		f.Fatalf("array not of size 1")
 	}
-	elemName := f.fe.SplitArray(name)
+	elemName := f.SplitArray(name)
 	var keep []*Value
-	for _, v := range f.NamedValues[name] {
+	for _, v := range f.NamedValues[*name] {
 		if v.Op != OpArrayMake1 {
 			keep = append(keep, v)
 			continue
 		}
-		f.NamedValues[elemName] = append(f.NamedValues[elemName], v.Args[0])
+		f.NamedValues[*elemName] = append(f.NamedValues[*elemName], v.Args[0])
 	}
 	if len(keep) == 0 {
 		// delete the name for the array as a whole
-		delete(f.NamedValues, name)
+		delete(f.NamedValues, *name)
 	} else {
-		f.NamedValues[name] = keep
+		f.NamedValues[*name] = keep
 	}
 
 	if t.Elem().IsArray() {
@@ -293,38 +302,38 @@
 // 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
+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)
+		fs := f.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)
+			slots = maybeAppend(f, slots, fs)
 		}
 	}
 
 	makeOp := StructMakeOp(n)
 	var keep []*Value
 	// create named values for each struct field
-	for _, v := range f.NamedValues[name] {
+	for _, v := range f.NamedValues[*name] {
 		if v.Op != makeOp {
 			keep = append(keep, v)
 			continue
 		}
 		for i := 0; i < len(fnames); i++ {
-			f.NamedValues[fnames[i]] = append(f.NamedValues[fnames[i]], v.Args[i])
+			f.NamedValues[*fnames[i]] = append(f.NamedValues[*fnames[i]], v.Args[i])
 		}
 	}
 	if len(keep) == 0 {
 		// delete the name for the struct as a whole
-		delete(f.NamedValues, name)
+		delete(f.NamedValues, *name)
 	} else {
-		f.NamedValues[name] = keep
+		f.NamedValues[*name] = keep
 	}
 
 	// now that this f.NamedValues contains values for the struct
@@ -332,10 +341,10 @@
 	for i := 0; i < n; i++ {
 		if name.Type.FieldType(i).IsStruct() {
 			slots = decomposeUserStructInto(f, fnames[i], slots)
-			delete(f.NamedValues, fnames[i])
+			delete(f.NamedValues, *fnames[i])
 		} else if name.Type.FieldType(i).IsArray() {
 			slots = decomposeUserArrayInto(f, fnames[i], slots)
-			delete(f.NamedValues, fnames[i])
+			delete(f.NamedValues, *fnames[i])
 		}
 	}
 	return slots
@@ -420,9 +429,10 @@
 	locIndex, valIndex int // f.NamedValues[f.Names[locIndex]][valIndex] = key
 }
 
-// deleteNamedVals removes particular values with debugger names from f's naming data structures
+// deleteNamedVals removes particular values with debugger names from f's naming data structures,
+// removes all values with OpInvalid, and re-sorts the list of Names.
 func deleteNamedVals(f *Func, toDelete []namedVal) {
-	// Arrange to delete from larger indices to smaller, to ensure swap-with-end deletion does not invalid pending indices.
+	// Arrange to delete from larger indices to smaller, to ensure swap-with-end deletion does not invalidate pending indices.
 	sort.Slice(toDelete, func(i, j int) bool {
 		if toDelete[i].locIndex != toDelete[j].locIndex {
 			return toDelete[i].locIndex > toDelete[j].locIndex
@@ -434,16 +444,36 @@
 	// Get rid of obsolete names
 	for _, d := range toDelete {
 		loc := f.Names[d.locIndex]
-		vals := f.NamedValues[loc]
+		vals := f.NamedValues[*loc]
 		l := len(vals) - 1
 		if l > 0 {
 			vals[d.valIndex] = vals[l]
-			f.NamedValues[loc] = vals[:l]
-		} else {
-			delete(f.NamedValues, loc)
-			l = len(f.Names) - 1
-			f.Names[d.locIndex] = f.Names[l]
-			f.Names = f.Names[:l]
+		}
+		vals[l] = nil
+		f.NamedValues[*loc] = vals[:l]
+	}
+	// Delete locations with no values attached.
+	end := len(f.Names)
+	for i := len(f.Names) - 1; i >= 0; i-- {
+		loc := f.Names[i]
+		vals := f.NamedValues[*loc]
+		last := len(vals)
+		for j := len(vals) - 1; j >= 0; j-- {
+			if vals[j].Op == OpInvalid {
+				last--
+				vals[j] = vals[last]
+				vals[last] = nil
+			}
+		}
+		if last < len(vals) {
+			f.NamedValues[*loc] = vals[:last]
+		}
+		if len(vals) == 0 {
+			delete(f.NamedValues, *loc)
+			end--
+			f.Names[i] = f.Names[end]
+			f.Names[end] = nil
 		}
 	}
+	f.Names = f.Names[:end]
 }
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go
index 679ee8a..7e973ab 100644
--- a/src/cmd/compile/internal/ssa/expand_calls.go
+++ b/src/cmd/compile/internal/ssa/expand_calls.go
@@ -5,6 +5,9 @@
 package ssa
 
 import (
+	"cmd/compile/internal/abi"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/types"
 	"cmd/internal/src"
 	"fmt"
@@ -12,16 +15,1113 @@
 )
 
 type selKey struct {
-	from   *Value
-	offset int64
-	size   int64
-	typ    *types.Type
+	from          *Value // what is selected from
+	offsetOrIndex int64  // whatever is appropriate for the selector
+	size          int64
+	typ           *types.Type
 }
 
-type offsetKey struct {
-	from   *Value
-	offset int64
-	pt     *types.Type
+type Abi1RO uint8 // An offset within a parameter's slice of register indices, for abi1.
+
+func isBlockMultiValueExit(b *Block) bool {
+	return (b.Kind == BlockRet || b.Kind == BlockRetJmp) && len(b.Controls) > 0 && b.Controls[0].Op == OpMakeResult
+}
+
+func badVal(s string, v *Value) error {
+	return fmt.Errorf("%s %s", s, v.LongString())
+}
+
+// removeTrivialWrapperTypes unwraps layers of
+// struct { singleField SomeType } and [1]SomeType
+// until a non-wrapper type is reached.  This is useful
+// for working with assignments to/from interface data
+// fields (either second operand to OpIMake or OpIData)
+// where the wrapping or type conversion can be elided
+// because of type conversions/assertions in source code
+// that do not appear in SSA.
+func removeTrivialWrapperTypes(t *types.Type) *types.Type {
+	for {
+		if t.IsStruct() && t.NumFields() == 1 {
+			t = t.Field(0).Type
+			continue
+		}
+		if t.IsArray() && t.NumElem() == 1 {
+			t = t.Elem()
+			continue
+		}
+		break
+	}
+	return t
+}
+
+// A registerCursor tracks which register is used for an Arg or regValues, or a piece of such.
+type registerCursor struct {
+	// TODO(register args) convert this to a generalized target cursor.
+	storeDest *Value // if there are no register targets, then this is the base of the store.
+	regsLen   int    // the number of registers available for this Arg/result (which is all in registers or not at all)
+	nextSlice Abi1RO // the next register/register-slice offset
+	config    *abi.ABIConfig
+	regValues *[]*Value // values assigned to registers accumulate here
+}
+
+func (rc *registerCursor) String() string {
+	dest := "<none>"
+	if rc.storeDest != nil {
+		dest = rc.storeDest.String()
+	}
+	regs := "<none>"
+	if rc.regValues != nil {
+		regs = ""
+		for i, x := range *rc.regValues {
+			if i > 0 {
+				regs = regs + "; "
+			}
+			regs = regs + x.LongString()
+		}
+	}
+	// not printing the config because that has not been useful
+	return fmt.Sprintf("RCSR{storeDest=%v, regsLen=%d, nextSlice=%d, regValues=[%s]}", dest, rc.regsLen, rc.nextSlice, regs)
+}
+
+// next effectively post-increments the register cursor; the receiver is advanced,
+// the old value is returned.
+func (c *registerCursor) next(t *types.Type) registerCursor {
+	rc := *c
+	if int(c.nextSlice) < c.regsLen {
+		w := c.config.NumParamRegs(t)
+		c.nextSlice += Abi1RO(w)
+	}
+	return rc
+}
+
+// plus returns a register cursor offset from the original, without modifying the original.
+func (c *registerCursor) plus(regWidth Abi1RO) registerCursor {
+	rc := *c
+	rc.nextSlice += regWidth
+	return rc
+}
+
+const (
+	// Register offsets for fields of built-in aggregate types; the ones not listed are zero.
+	RO_complex_imag = 1
+	RO_string_len   = 1
+	RO_slice_len    = 1
+	RO_slice_cap    = 2
+	RO_iface_data   = 1
+)
+
+func (x *expandState) regWidth(t *types.Type) Abi1RO {
+	return Abi1RO(x.abi1.NumParamRegs(t))
+}
+
+// regOffset returns the register offset of the i'th element of type t
+func (x *expandState) regOffset(t *types.Type, i int) Abi1RO {
+	// TODO maybe cache this in a map if profiling recommends.
+	if i == 0 {
+		return 0
+	}
+	if t.IsArray() {
+		return Abi1RO(i) * x.regWidth(t.Elem())
+	}
+	if t.IsStruct() {
+		k := Abi1RO(0)
+		for j := 0; j < i; j++ {
+			k += x.regWidth(t.FieldType(j))
+		}
+		return k
+	}
+	panic("Haven't implemented this case yet, do I need to?")
+}
+
+// at returns the register cursor for component i of t, where the first
+// component is numbered 0.
+func (c *registerCursor) at(t *types.Type, i int) registerCursor {
+	rc := *c
+	if i == 0 || c.regsLen == 0 {
+		return rc
+	}
+	if t.IsArray() {
+		w := c.config.NumParamRegs(t.Elem())
+		rc.nextSlice += Abi1RO(i * w)
+		return rc
+	}
+	if t.IsStruct() {
+		for j := 0; j < i; j++ {
+			rc.next(t.FieldType(j))
+		}
+		return rc
+	}
+	panic("Haven't implemented this case yet, do I need to?")
+}
+
+func (c *registerCursor) init(regs []abi.RegIndex, info *abi.ABIParamResultInfo, result *[]*Value, storeDest *Value) {
+	c.regsLen = len(regs)
+	c.nextSlice = 0
+	if len(regs) == 0 {
+		c.storeDest = storeDest // only save this if there are no registers, will explode if misused.
+		return
+	}
+	c.config = info.Config()
+	c.regValues = result
+}
+
+func (c *registerCursor) addArg(v *Value) {
+	*c.regValues = append(*c.regValues, v)
+}
+
+func (c *registerCursor) hasRegs() bool {
+	return c.regsLen > 0
+}
+
+type expandState struct {
+	f                  *Func
+	abi1               *abi.ABIConfig
+	debug              bool
+	canSSAType         func(*types.Type) bool
+	regSize            int64
+	sp                 *Value
+	typs               *Types
+	ptrSize            int64
+	hiOffset           int64
+	lowOffset          int64
+	hiRo               Abi1RO
+	loRo               Abi1RO
+	namedSelects       map[*Value][]namedVal
+	sdom               SparseTree
+	commonSelectors    map[selKey]*Value // used to de-dupe selectors
+	commonArgs         map[selKey]*Value // used to de-dupe OpArg/OpArgIntReg/OpArgFloatReg
+	memForCall         map[ID]*Value     // For a call, need to know the unique selector that gets the mem.
+	transformedSelects map[ID]bool       // OpSelectN after rewriting, either created or renumbered.
+	indentLevel        int               // Indentation for debugging recursion
+}
+
+// intPairTypes returns the pair of 32-bit int types needed to encode a 64-bit integer type on a target
+// that has no 64-bit integer registers.
+func (x *expandState) intPairTypes(et types.Kind) (tHi, tLo *types.Type) {
+	tHi = x.typs.UInt32
+	if et == types.TINT64 {
+		tHi = x.typs.Int32
+	}
+	tLo = x.typs.UInt32
+	return
+}
+
+// isAlreadyExpandedAggregateType returns whether a type is an SSA-able "aggregate" (multiple register) type
+// that was expanded in an earlier phase (currently, expand_calls is intended to run after decomposeBuiltin,
+// so this is all aggregate types -- small struct and array, complex, interface, string, slice, and 64-bit
+// integer on 32-bit).
+func (x *expandState) isAlreadyExpandedAggregateType(t *types.Type) bool {
+	if !x.canSSAType(t) {
+		return false
+	}
+	return t.IsStruct() || t.IsArray() || t.IsComplex() || t.IsInterface() || t.IsString() || t.IsSlice() ||
+		t.Size() > x.regSize && t.IsInteger()
+}
+
+// offsetFrom creates an offset from a pointer, simplifying chained offsets and offsets from SP
+// TODO should also optimize offsets from SB?
+func (x *expandState) offsetFrom(b *Block, from *Value, offset int64, pt *types.Type) *Value {
+	ft := from.Type
+	if offset == 0 {
+		if ft == pt {
+			return from
+		}
+		// This captures common, (apparently) safe cases.  The unsafe cases involve ft == uintptr
+		if (ft.IsPtr() || ft.IsUnsafePtr()) && pt.IsPtr() {
+			return from
+		}
+	}
+	// Simplify, canonicalize
+	for from.Op == OpOffPtr {
+		offset += from.AuxInt
+		from = from.Args[0]
+	}
+	if from == x.sp {
+		return x.f.ConstOffPtrSP(pt, offset, x.sp)
+	}
+	return b.NewValue1I(from.Pos.WithNotStmt(), OpOffPtr, pt, offset, from)
+}
+
+// splitSlots splits one "field" (specified by sfx, offset, and ty) out of the LocalSlots in ls and returns the new LocalSlots this generates.
+func (x *expandState) splitSlots(ls []*LocalSlot, sfx string, offset int64, ty *types.Type) []*LocalSlot {
+	var locs []*LocalSlot
+	for i := range ls {
+		locs = append(locs, x.f.SplitSlot(ls[i], sfx, offset, ty))
+	}
+	return locs
+}
+
+// prAssignForArg returns the ABIParamAssignment for v, assumed to be an OpArg.
+func (x *expandState) prAssignForArg(v *Value) *abi.ABIParamAssignment {
+	if v.Op != OpArg {
+		panic(badVal("Wanted OpArg, instead saw", v))
+	}
+	return ParamAssignmentForArgName(x.f, v.Aux.(*ir.Name))
+}
+
+// ParamAssignmentForArgName returns the ABIParamAssignment for f's arg with matching name.
+func ParamAssignmentForArgName(f *Func, name *ir.Name) *abi.ABIParamAssignment {
+	abiInfo := f.OwnAux.abiInfo
+	ip := abiInfo.InParams()
+	for i, a := range ip {
+		if a.Name == name {
+			return &ip[i]
+		}
+	}
+	panic(fmt.Errorf("Did not match param %v in prInfo %+v", name, abiInfo.InParams()))
+}
+
+// indent increments (or decrements) the indentation.
+func (x *expandState) indent(n int) {
+	x.indentLevel += n
+}
+
+// Printf does an indented fmt.Printf on te format and args.
+func (x *expandState) Printf(format string, a ...interface{}) (n int, err error) {
+	if x.indentLevel > 0 {
+		fmt.Printf("%[1]*s", x.indentLevel, "")
+	}
+	return fmt.Printf(format, a...)
+}
+
+// Calls that need lowering have some number of inputs, including a memory input,
+// and produce a tuple of (value1, value2, ..., mem) where valueK may or may not be SSA-able.
+
+// With the current ABI those inputs need to be converted into stores to memory,
+// rethreading the call's memory input to the first, and the new call now receiving the last.
+
+// With the current ABI, the outputs need to be converted to loads, which will all use the call's
+// memory output as their input.
+
+// rewriteSelect recursively walks from leaf selector to a root (OpSelectN, OpLoad, OpArg)
+// through a chain of Struct/Array/builtin Select operations.  If the chain of selectors does not
+// end in an expected root, it does nothing (this can happen depending on compiler phase ordering).
+// The "leaf" provides the type, the root supplies the container, and the leaf-to-root path
+// accumulates the offset.
+// It emits the code necessary to implement the leaf select operation that leads to the root.
+//
+// TODO when registers really arrive, must also decompose anything split across two registers or registers and memory.
+func (x *expandState) rewriteSelect(leaf *Value, selector *Value, offset int64, regOffset Abi1RO) []*LocalSlot {
+	if x.debug {
+		x.indent(3)
+		defer x.indent(-3)
+		x.Printf("rewriteSelect(%s; %s; memOff=%d; regOff=%d)\n", leaf.LongString(), selector.LongString(), offset, regOffset)
+	}
+	var locs []*LocalSlot
+	leafType := leaf.Type
+	if len(selector.Args) > 0 {
+		w := selector.Args[0]
+		if w.Op == OpCopy {
+			for w.Op == OpCopy {
+				w = w.Args[0]
+			}
+			selector.SetArg(0, w)
+		}
+	}
+	switch selector.Op {
+	case OpArgIntReg, OpArgFloatReg:
+		if leafType == selector.Type { // OpIData leads us here, sometimes.
+			leaf.copyOf(selector)
+		} else {
+			x.f.Fatalf("Unexpected %s type, selector=%s, leaf=%s\n", selector.Op.String(), selector.LongString(), leaf.LongString())
+		}
+		if x.debug {
+			x.Printf("---%s, break\n", selector.Op.String())
+		}
+	case OpArg:
+		if !x.isAlreadyExpandedAggregateType(selector.Type) {
+			if leafType == selector.Type { // OpIData leads us here, sometimes.
+				x.newArgToMemOrRegs(selector, leaf, offset, regOffset, leafType, leaf.Pos)
+			} else {
+				x.f.Fatalf("Unexpected OpArg type, selector=%s, leaf=%s\n", selector.LongString(), leaf.LongString())
+			}
+			if x.debug {
+				x.Printf("---OpArg, break\n")
+			}
+			break
+		}
+		switch leaf.Op {
+		case OpIData, OpStructSelect, OpArraySelect:
+			leafType = removeTrivialWrapperTypes(leaf.Type)
+		}
+		x.newArgToMemOrRegs(selector, leaf, offset, regOffset, leafType, leaf.Pos)
+
+		for _, s := range x.namedSelects[selector] {
+			locs = append(locs, x.f.Names[s.locIndex])
+		}
+
+	case OpLoad: // We end up here because of IData of immediate structures.
+		// Failure case:
+		// (note the failure case is very rare; w/o this case, make.bash and run.bash both pass, as well as
+		// the hard cases of building {syscall,math,math/cmplx,math/bits,go/constant} on ppc64le and mips-softfloat).
+		//
+		// GOSSAFUNC='(*dumper).dump' go build -gcflags=-l -tags=math_big_pure_go cmd/compile/internal/gc
+		// cmd/compile/internal/gc/dump.go:136:14: internal compiler error: '(*dumper).dump': not lowered: v827, StructSelect PTR PTR
+		// b2: ← b1
+		// v20 (+142) = StaticLECall <interface {},mem> {AuxCall{reflect.Value.Interface([reflect.Value,0])[interface {},24]}} [40] v8 v1
+		// v21 (142) = SelectN <mem> [1] v20
+		// v22 (142) = SelectN <interface {}> [0] v20
+		// b15: ← b8
+		// v71 (+143) = IData <Nodes> v22 (v[Nodes])
+		// v73 (+146) = StaticLECall <[]*Node,mem> {AuxCall{"".Nodes.Slice([Nodes,0])[[]*Node,8]}} [32] v71 v21
+		//
+		// translates (w/o the "case OpLoad:" above) to:
+		//
+		// b2: ← b1
+		// v20 (+142) = StaticCall <mem> {AuxCall{reflect.Value.Interface([reflect.Value,0])[interface {},24]}} [40] v715
+		// v23 (142) = Load <*uintptr> v19 v20
+		// v823 (142) = IsNonNil <bool> v23
+		// v67 (+143) = Load <*[]*Node> v880 v20
+		// b15: ← b8
+		// v827 (146) = StructSelect <*[]*Node> [0] v67
+		// v846 (146) = Store <mem> {*[]*Node} v769 v827 v20
+		// v73 (+146) = StaticCall <mem> {AuxCall{"".Nodes.Slice([Nodes,0])[[]*Node,8]}} [32] v846
+		// i.e., the struct select is generated and remains in because it is not applied to an actual structure.
+		// The OpLoad was created to load the single field of the IData
+		// This case removes that StructSelect.
+		if leafType != selector.Type {
+			x.f.Fatalf("Unexpected Load as selector, leaf=%s, selector=%s\n", leaf.LongString(), selector.LongString())
+		}
+		leaf.copyOf(selector)
+		for _, s := range x.namedSelects[selector] {
+			locs = append(locs, x.f.Names[s.locIndex])
+		}
+
+	case OpSelectN:
+		// TODO(register args) result case
+		// if applied to Op-mumble-call, the Aux tells us which result, regOffset specifies offset within result.  If a register, should rewrite to OpSelectN for new call.
+		// TODO these may be duplicated. Should memoize. Intermediate selectors will go dead, no worries there.
+		call := selector.Args[0]
+		call0 := call
+		aux := call.Aux.(*AuxCall)
+		which := selector.AuxInt
+		if x.transformedSelects[selector.ID] {
+			// This is a minor hack.  Either this select has had its operand adjusted (mem) or
+			// it is some other intermediate node that was rewritten to reference a register (not a generic arg).
+			// This can occur with chains of selection/indexing from single field/element aggregates.
+			leaf.copyOf(selector)
+			break
+		}
+		if which == aux.NResults() { // mem is after the results.
+			// rewrite v as a Copy of call -- the replacement call will produce a mem.
+			if leaf != selector {
+				panic(fmt.Errorf("Unexpected selector of memory, selector=%s, call=%s, leaf=%s", selector.LongString(), call.LongString(), leaf.LongString()))
+			}
+			if aux.abiInfo == nil {
+				panic(badVal("aux.abiInfo nil for call", call))
+			}
+			if existing := x.memForCall[call.ID]; existing == nil {
+				selector.AuxInt = int64(aux.abiInfo.OutRegistersUsed())
+				x.memForCall[call.ID] = selector
+				x.transformedSelects[selector.ID] = true // operand adjusted
+			} else {
+				selector.copyOf(existing)
+			}
+
+		} else {
+			leafType := removeTrivialWrapperTypes(leaf.Type)
+			if x.canSSAType(leafType) {
+				pt := types.NewPtr(leafType)
+				// Any selection right out of the arg area/registers has to be same Block as call, use call as mem input.
+				// Create a "mem" for any loads that need to occur.
+				if mem := x.memForCall[call.ID]; mem != nil {
+					if mem.Block != call.Block {
+						panic(fmt.Errorf("selector and call need to be in same block, selector=%s; call=%s", selector.LongString(), call.LongString()))
+					}
+					call = mem
+				} else {
+					mem = call.Block.NewValue1I(call.Pos.WithNotStmt(), OpSelectN, types.TypeMem, int64(aux.abiInfo.OutRegistersUsed()), call)
+					x.transformedSelects[mem.ID] = true // select uses post-expansion indexing
+					x.memForCall[call.ID] = mem
+					call = mem
+				}
+				outParam := aux.abiInfo.OutParam(int(which))
+				if len(outParam.Registers) > 0 {
+					firstReg := uint32(0)
+					for i := 0; i < int(which); i++ {
+						firstReg += uint32(len(aux.abiInfo.OutParam(i).Registers))
+					}
+					reg := int64(regOffset + Abi1RO(firstReg))
+					if leaf.Block == call.Block {
+						leaf.reset(OpSelectN)
+						leaf.SetArgs1(call0)
+						leaf.Type = leafType
+						leaf.AuxInt = reg
+						x.transformedSelects[leaf.ID] = true // leaf, rewritten to use post-expansion indexing.
+					} else {
+						w := call.Block.NewValue1I(leaf.Pos, OpSelectN, leafType, reg, call0)
+						x.transformedSelects[w.ID] = true // select, using post-expansion indexing.
+						leaf.copyOf(w)
+					}
+				} else {
+					off := x.offsetFrom(x.f.Entry, x.sp, offset+aux.OffsetOfResult(which), pt)
+					if leaf.Block == call.Block {
+						leaf.reset(OpLoad)
+						leaf.SetArgs2(off, call)
+						leaf.Type = leafType
+					} else {
+						w := call.Block.NewValue2(leaf.Pos, OpLoad, leafType, off, call)
+						leaf.copyOf(w)
+						if x.debug {
+							x.Printf("---new %s\n", w.LongString())
+						}
+					}
+				}
+				for _, s := range x.namedSelects[selector] {
+					locs = append(locs, x.f.Names[s.locIndex])
+				}
+			} else {
+				x.f.Fatalf("Should not have non-SSA-able OpSelectN, selector=%s", selector.LongString())
+			}
+		}
+
+	case OpStructSelect:
+		w := selector.Args[0]
+		var ls []*LocalSlot
+		if w.Type.Kind() != types.TSTRUCT { // IData artifact
+			ls = x.rewriteSelect(leaf, w, offset, regOffset)
+		} else {
+			fldi := int(selector.AuxInt)
+			ls = x.rewriteSelect(leaf, w, offset+w.Type.FieldOff(fldi), regOffset+x.regOffset(w.Type, fldi))
+			if w.Op != OpIData {
+				for _, l := range ls {
+					locs = append(locs, x.f.SplitStruct(l, int(selector.AuxInt)))
+				}
+			}
+		}
+
+	case OpArraySelect:
+		w := selector.Args[0]
+		index := selector.AuxInt
+		x.rewriteSelect(leaf, w, offset+selector.Type.Size()*index, regOffset+x.regOffset(w.Type, int(index)))
+
+	case OpInt64Hi:
+		w := selector.Args[0]
+		ls := x.rewriteSelect(leaf, w, offset+x.hiOffset, regOffset+x.hiRo)
+		locs = x.splitSlots(ls, ".hi", x.hiOffset, leafType)
+
+	case OpInt64Lo:
+		w := selector.Args[0]
+		ls := x.rewriteSelect(leaf, w, offset+x.lowOffset, regOffset+x.loRo)
+		locs = x.splitSlots(ls, ".lo", x.lowOffset, leafType)
+
+	case OpStringPtr:
+		ls := x.rewriteSelect(leaf, selector.Args[0], offset, regOffset)
+		locs = x.splitSlots(ls, ".ptr", 0, x.typs.BytePtr)
+
+	case OpSlicePtr, OpSlicePtrUnchecked:
+		w := selector.Args[0]
+		ls := x.rewriteSelect(leaf, w, offset, regOffset)
+		locs = x.splitSlots(ls, ".ptr", 0, types.NewPtr(w.Type.Elem()))
+
+	case OpITab:
+		w := selector.Args[0]
+		ls := x.rewriteSelect(leaf, w, offset, regOffset)
+		sfx := ".itab"
+		if w.Type.IsEmptyInterface() {
+			sfx = ".type"
+		}
+		locs = x.splitSlots(ls, sfx, 0, x.typs.Uintptr)
+
+	case OpComplexReal:
+		ls := x.rewriteSelect(leaf, selector.Args[0], offset, regOffset)
+		locs = x.splitSlots(ls, ".real", 0, leafType)
+
+	case OpComplexImag:
+		ls := x.rewriteSelect(leaf, selector.Args[0], offset+leafType.Width, regOffset+RO_complex_imag) // result is FloatNN, width of result is offset of imaginary part.
+		locs = x.splitSlots(ls, ".imag", leafType.Width, leafType)
+
+	case OpStringLen, OpSliceLen:
+		ls := x.rewriteSelect(leaf, selector.Args[0], offset+x.ptrSize, regOffset+RO_slice_len)
+		locs = x.splitSlots(ls, ".len", x.ptrSize, leafType)
+
+	case OpIData:
+		ls := x.rewriteSelect(leaf, selector.Args[0], offset+x.ptrSize, regOffset+RO_iface_data)
+		locs = x.splitSlots(ls, ".data", x.ptrSize, leafType)
+
+	case OpSliceCap:
+		ls := x.rewriteSelect(leaf, selector.Args[0], offset+2*x.ptrSize, regOffset+RO_slice_cap)
+		locs = x.splitSlots(ls, ".cap", 2*x.ptrSize, leafType)
+
+	case OpCopy: // If it's an intermediate result, recurse
+		locs = x.rewriteSelect(leaf, selector.Args[0], offset, regOffset)
+		for _, s := range x.namedSelects[selector] {
+			// this copy may have had its own name, preserve that, too.
+			locs = append(locs, x.f.Names[s.locIndex])
+		}
+
+	default:
+		// Ignore dead ends. These can occur if this phase is run before decompose builtin (which is not intended, but allowed).
+	}
+
+	return locs
+}
+
+func (x *expandState) rewriteDereference(b *Block, base, a, mem *Value, offset, size int64, typ *types.Type, pos src.XPos) *Value {
+	source := a.Args[0]
+	dst := x.offsetFrom(b, base, offset, source.Type)
+	if a.Uses == 1 && a.Block == b {
+		a.reset(OpMove)
+		a.Pos = pos
+		a.Type = types.TypeMem
+		a.Aux = typ
+		a.AuxInt = size
+		a.SetArgs3(dst, source, mem)
+		mem = a
+	} else {
+		mem = b.NewValue3A(pos, OpMove, types.TypeMem, typ, dst, source, mem)
+		mem.AuxInt = size
+	}
+	return mem
+}
+
+var indexNames [1]string = [1]string{"[0]"}
+
+// pathTo returns the selection path to the leaf type at offset within container.
+// e.g. len(thing.field[0]) => ".field[0].len"
+// this is for purposes of generating names ultimately fed to a debugger.
+func (x *expandState) pathTo(container, leaf *types.Type, offset int64) string {
+	if container == leaf || offset == 0 && container.Size() == leaf.Size() {
+		return ""
+	}
+	path := ""
+outer:
+	for {
+		switch container.Kind() {
+		case types.TARRAY:
+			container = container.Elem()
+			if container.Size() == 0 {
+				return path
+			}
+			i := offset / container.Size()
+			offset = offset % container.Size()
+			// If a future compiler/ABI supports larger SSA/Arg-able arrays, expand indexNames.
+			path = path + indexNames[i]
+			continue
+		case types.TSTRUCT:
+			for i := 0; i < container.NumFields(); i++ {
+				fld := container.Field(i)
+				if fld.Offset+fld.Type.Size() > offset {
+					offset -= fld.Offset
+					path += "." + fld.Sym.Name
+					container = fld.Type
+					continue outer
+				}
+			}
+			return path
+		case types.TINT64, types.TUINT64:
+			if container.Width == x.regSize {
+				return path
+			}
+			if offset == x.hiOffset {
+				return path + ".hi"
+			}
+			return path + ".lo"
+		case types.TINTER:
+			if offset != 0 {
+				return path + ".data"
+			}
+			if container.IsEmptyInterface() {
+				return path + ".type"
+			}
+			return path + ".itab"
+
+		case types.TSLICE:
+			if offset == 2*x.regSize {
+				return path + ".cap"
+			}
+			fallthrough
+		case types.TSTRING:
+			if offset == 0 {
+				return path + ".ptr"
+			}
+			return path + ".len"
+		case types.TCOMPLEX64, types.TCOMPLEX128:
+			if offset == 0 {
+				return path + ".real"
+			}
+			return path + ".imag"
+		}
+		return path
+	}
+}
+
+// decomposeArg is a helper for storeArgOrLoad.
+// It decomposes a Load or an Arg into smaller parts and returns the new mem.
+// If the type does not match one of the expected aggregate types, it returns nil instead.
+// Parameters:
+//  pos           -- the location of any generated code.
+//  b             -- the block into which any generated code should normally be placed
+//  source        -- the value, possibly an aggregate, to be stored.
+//  mem           -- the mem flowing into this decomposition (loads depend on it, stores updated it)
+//  t             -- the type of the value to be stored
+//  storeOffset   -- if the value is stored in memory, it is stored at base (see storeRc) + storeOffset
+//  loadRegOffset -- regarding source as a value in registers, the register offset in ABI1.  Meaningful only if source is OpArg.
+//  storeRc       -- storeRC; if the value is stored in registers, this specifies the registers.
+//                   StoreRc also identifies whether the target is registers or memory, and has the base for the store operation.
+func (x *expandState) decomposeArg(pos src.XPos, b *Block, source, mem *Value, t *types.Type, storeOffset int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value {
+
+	pa := x.prAssignForArg(source)
+	var locs []*LocalSlot
+	for _, s := range x.namedSelects[source] {
+		locs = append(locs, x.f.Names[s.locIndex])
+	}
+
+	if len(pa.Registers) > 0 {
+		// Handle the in-registers case directly
+		rts, offs := pa.RegisterTypesAndOffsets()
+		last := loadRegOffset + x.regWidth(t)
+		if offs[loadRegOffset] != 0 {
+			// Document the problem before panicking.
+			for i := 0; i < len(rts); i++ {
+				rt := rts[i]
+				off := offs[i]
+				fmt.Printf("rt=%s, off=%d, rt.Width=%d, rt.Align=%d\n", rt.String(), off, rt.Width, rt.Align)
+			}
+			panic(fmt.Errorf("offset %d of requested register %d should be zero, source=%s", offs[loadRegOffset], loadRegOffset, source.LongString()))
+		}
+
+		if x.debug {
+			x.Printf("decompose arg %s has %d locs\n", source.LongString(), len(locs))
+		}
+
+		for i := loadRegOffset; i < last; i++ {
+			rt := rts[i]
+			off := offs[i]
+			w := x.commonArgs[selKey{source, off, rt.Width, rt}]
+			if w == nil {
+				w = x.newArgToMemOrRegs(source, w, off, i, rt, pos)
+				suffix := x.pathTo(source.Type, rt, off)
+				if suffix != "" {
+					x.splitSlotsIntoNames(locs, suffix, off, rt, w)
+				}
+			}
+			if t.IsPtrShaped() {
+				// Preserve the original store type. This ensures pointer type
+				// properties aren't discarded (e.g, notinheap).
+				if rt.Width != t.Width || len(pa.Registers) != 1 || i != loadRegOffset {
+					b.Func.Fatalf("incompatible store type %v and %v, i=%d", t, rt, i)
+				}
+				rt = t
+			}
+			mem = x.storeArgOrLoad(pos, b, w, mem, rt, storeOffset+off, i, storeRc.next(rt))
+		}
+		return mem
+	}
+
+	u := source.Type
+	switch u.Kind() {
+	case types.TARRAY:
+		elem := u.Elem()
+		elemRO := x.regWidth(elem)
+		for i := int64(0); i < u.NumElem(); i++ {
+			elemOff := i * elem.Size()
+			mem = storeOneArg(x, pos, b, locs, indexNames[i], source, mem, elem, elemOff, storeOffset+elemOff, loadRegOffset, storeRc.next(elem))
+			loadRegOffset += elemRO
+			pos = pos.WithNotStmt()
+		}
+		return mem
+	case types.TSTRUCT:
+		for i := 0; i < u.NumFields(); i++ {
+			fld := u.Field(i)
+			mem = storeOneArg(x, pos, b, locs, "."+fld.Sym.Name, source, mem, fld.Type, fld.Offset, storeOffset+fld.Offset, loadRegOffset, storeRc.next(fld.Type))
+			loadRegOffset += x.regWidth(fld.Type)
+			pos = pos.WithNotStmt()
+		}
+		return mem
+	case types.TINT64, types.TUINT64:
+		if t.Width == x.regSize {
+			break
+		}
+		tHi, tLo := x.intPairTypes(t.Kind())
+		mem = storeOneArg(x, pos, b, locs, ".hi", source, mem, tHi, x.hiOffset, storeOffset+x.hiOffset, loadRegOffset+x.hiRo, storeRc.plus(x.hiRo))
+		pos = pos.WithNotStmt()
+		return storeOneArg(x, pos, b, locs, ".lo", source, mem, tLo, x.lowOffset, storeOffset+x.lowOffset, loadRegOffset+x.loRo, storeRc.plus(x.loRo))
+	case types.TINTER:
+		sfx := ".itab"
+		if u.IsEmptyInterface() {
+			sfx = ".type"
+		}
+		return storeTwoArg(x, pos, b, locs, sfx, ".idata", source, mem, x.typs.Uintptr, x.typs.BytePtr, 0, storeOffset, loadRegOffset, storeRc)
+	case types.TSTRING:
+		return storeTwoArg(x, pos, b, locs, ".ptr", ".len", source, mem, x.typs.BytePtr, x.typs.Int, 0, storeOffset, loadRegOffset, storeRc)
+	case types.TCOMPLEX64:
+		return storeTwoArg(x, pos, b, locs, ".real", ".imag", source, mem, x.typs.Float32, x.typs.Float32, 0, storeOffset, loadRegOffset, storeRc)
+	case types.TCOMPLEX128:
+		return storeTwoArg(x, pos, b, locs, ".real", ".imag", source, mem, x.typs.Float64, x.typs.Float64, 0, storeOffset, loadRegOffset, storeRc)
+	case types.TSLICE:
+		mem = storeOneArg(x, pos, b, locs, ".ptr", source, mem, x.typs.BytePtr, 0, storeOffset, loadRegOffset, storeRc.next(x.typs.BytePtr))
+		return storeTwoArg(x, pos, b, locs, ".len", ".cap", source, mem, x.typs.Int, x.typs.Int, x.ptrSize, storeOffset+x.ptrSize, loadRegOffset+RO_slice_len, storeRc)
+	}
+	return nil
+}
+
+func (x *expandState) splitSlotsIntoNames(locs []*LocalSlot, suffix string, off int64, rt *types.Type, w *Value) {
+	wlocs := x.splitSlots(locs, suffix, off, rt)
+	for _, l := range wlocs {
+		old, ok := x.f.NamedValues[*l]
+		x.f.NamedValues[*l] = append(old, w)
+		if !ok {
+			x.f.Names = append(x.f.Names, l)
+		}
+	}
+}
+
+// decomposeLoad is a helper for storeArgOrLoad.
+// It decomposes a Load  into smaller parts and returns the new mem.
+// If the type does not match one of the expected aggregate types, it returns nil instead.
+// Parameters:
+//  pos           -- the location of any generated code.
+//  b             -- the block into which any generated code should normally be placed
+//  source        -- the value, possibly an aggregate, to be stored.
+//  mem           -- the mem flowing into this decomposition (loads depend on it, stores updated it)
+//  t             -- the type of the value to be stored
+//  storeOffset   -- if the value is stored in memory, it is stored at base (see storeRc) + offset
+//  loadRegOffset -- regarding source as a value in registers, the register offset in ABI1.  Meaningful only if source is OpArg.
+//  storeRc       -- storeRC; if the value is stored in registers, this specifies the registers.
+//                   StoreRc also identifies whether the target is registers or memory, and has the base for the store operation.
+//
+// TODO -- this needs cleanup; it just works for SSA-able aggregates, and won't fully generalize to register-args aggregates.
+func (x *expandState) decomposeLoad(pos src.XPos, b *Block, source, mem *Value, t *types.Type, storeOffset int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value {
+	u := source.Type
+	switch u.Kind() {
+	case types.TARRAY:
+		elem := u.Elem()
+		elemRO := x.regWidth(elem)
+		for i := int64(0); i < u.NumElem(); i++ {
+			elemOff := i * elem.Size()
+			mem = storeOneLoad(x, pos, b, source, mem, elem, elemOff, storeOffset+elemOff, loadRegOffset, storeRc.next(elem))
+			loadRegOffset += elemRO
+			pos = pos.WithNotStmt()
+		}
+		return mem
+	case types.TSTRUCT:
+		for i := 0; i < u.NumFields(); i++ {
+			fld := u.Field(i)
+			mem = storeOneLoad(x, pos, b, source, mem, fld.Type, fld.Offset, storeOffset+fld.Offset, loadRegOffset, storeRc.next(fld.Type))
+			loadRegOffset += x.regWidth(fld.Type)
+			pos = pos.WithNotStmt()
+		}
+		return mem
+	case types.TINT64, types.TUINT64:
+		if t.Width == x.regSize {
+			break
+		}
+		tHi, tLo := x.intPairTypes(t.Kind())
+		mem = storeOneLoad(x, pos, b, source, mem, tHi, x.hiOffset, storeOffset+x.hiOffset, loadRegOffset+x.hiRo, storeRc.plus(x.hiRo))
+		pos = pos.WithNotStmt()
+		return storeOneLoad(x, pos, b, source, mem, tLo, x.lowOffset, storeOffset+x.lowOffset, loadRegOffset+x.loRo, storeRc.plus(x.loRo))
+	case types.TINTER:
+		return storeTwoLoad(x, pos, b, source, mem, x.typs.Uintptr, x.typs.BytePtr, 0, storeOffset, loadRegOffset, storeRc)
+	case types.TSTRING:
+		return storeTwoLoad(x, pos, b, source, mem, x.typs.BytePtr, x.typs.Int, 0, storeOffset, loadRegOffset, storeRc)
+	case types.TCOMPLEX64:
+		return storeTwoLoad(x, pos, b, source, mem, x.typs.Float32, x.typs.Float32, 0, storeOffset, loadRegOffset, storeRc)
+	case types.TCOMPLEX128:
+		return storeTwoLoad(x, pos, b, source, mem, x.typs.Float64, x.typs.Float64, 0, storeOffset, loadRegOffset, storeRc)
+	case types.TSLICE:
+		mem = storeOneLoad(x, pos, b, source, mem, x.typs.BytePtr, 0, storeOffset, loadRegOffset, storeRc.next(x.typs.BytePtr))
+		return storeTwoLoad(x, pos, b, source, mem, x.typs.Int, x.typs.Int, x.ptrSize, storeOffset+x.ptrSize, loadRegOffset+RO_slice_len, storeRc)
+	}
+	return nil
+}
+
+// storeOneArg creates a decomposed (one step) arg that is then stored.
+// pos and b locate the store instruction, source is the "base" of the value input,
+// mem is the input mem, t is the type in question, and offArg and offStore are the offsets from the respective bases.
+func storeOneArg(x *expandState, pos src.XPos, b *Block, locs []*LocalSlot, suffix string, source, mem *Value, t *types.Type, argOffset, storeOffset int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value {
+	if x.debug {
+		x.indent(3)
+		defer x.indent(-3)
+		x.Printf("storeOneArg(%s;  %s;  %s; aO=%d; sO=%d; lrO=%d; %s)\n", source.LongString(), mem.String(), t.String(), argOffset, storeOffset, loadRegOffset, storeRc.String())
+	}
+
+	w := x.commonArgs[selKey{source, argOffset, t.Width, t}]
+	if w == nil {
+		w = x.newArgToMemOrRegs(source, w, argOffset, loadRegOffset, t, pos)
+		x.splitSlotsIntoNames(locs, suffix, argOffset, t, w)
+	}
+	return x.storeArgOrLoad(pos, b, w, mem, t, storeOffset, loadRegOffset, storeRc)
+}
+
+// storeOneLoad creates a decomposed (one step) load that is then stored.
+func storeOneLoad(x *expandState, pos src.XPos, b *Block, source, mem *Value, t *types.Type, offArg, offStore int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value {
+	from := x.offsetFrom(b, source.Args[0], offArg, types.NewPtr(t))
+	w := source.Block.NewValue2(source.Pos, OpLoad, t, from, mem)
+	return x.storeArgOrLoad(pos, b, w, mem, t, offStore, loadRegOffset, storeRc)
+}
+
+func storeTwoArg(x *expandState, pos src.XPos, b *Block, locs []*LocalSlot, suffix1 string, suffix2 string, source, mem *Value, t1, t2 *types.Type, offArg, offStore int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value {
+	mem = storeOneArg(x, pos, b, locs, suffix1, source, mem, t1, offArg, offStore, loadRegOffset, storeRc.next(t1))
+	pos = pos.WithNotStmt()
+	t1Size := t1.Size()
+	return storeOneArg(x, pos, b, locs, suffix2, source, mem, t2, offArg+t1Size, offStore+t1Size, loadRegOffset+1, storeRc)
+}
+
+// storeTwoLoad creates a pair of decomposed (one step) loads that are then stored.
+// the elements of the pair must not require any additional alignment.
+func storeTwoLoad(x *expandState, pos src.XPos, b *Block, source, mem *Value, t1, t2 *types.Type, offArg, offStore int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value {
+	mem = storeOneLoad(x, pos, b, source, mem, t1, offArg, offStore, loadRegOffset, storeRc.next(t1))
+	pos = pos.WithNotStmt()
+	t1Size := t1.Size()
+	return storeOneLoad(x, pos, b, source, mem, t2, offArg+t1Size, offStore+t1Size, loadRegOffset+1, storeRc)
+}
+
+// storeArgOrLoad converts stores of SSA-able potentially aggregatable arguments (passed to a call) into a series of primitive-typed
+// stores of non-aggregate types.  It recursively walks up a chain of selectors until it reaches a Load or an Arg.
+// If it does not reach a Load or an Arg, nothing happens; this allows a little freedom in phase ordering.
+func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value, t *types.Type, storeOffset int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value {
+	if x.debug {
+		x.indent(3)
+		defer x.indent(-3)
+		x.Printf("storeArgOrLoad(%s;  %s;  %s; %d; %s)\n", source.LongString(), mem.String(), t.String(), storeOffset, storeRc.String())
+	}
+
+	// Start with Opcodes that can be disassembled
+	switch source.Op {
+	case OpCopy:
+		return x.storeArgOrLoad(pos, b, source.Args[0], mem, t, storeOffset, loadRegOffset, storeRc)
+
+	case OpLoad, OpDereference:
+		ret := x.decomposeLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
+		if ret != nil {
+			return ret
+		}
+
+	case OpArg:
+		ret := x.decomposeArg(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
+		if ret != nil {
+			return ret
+		}
+
+	case OpArrayMake0, OpStructMake0:
+		// TODO(register args) is this correct for registers?
+		return mem
+
+	case OpStructMake1, OpStructMake2, OpStructMake3, OpStructMake4:
+		for i := 0; i < t.NumFields(); i++ {
+			fld := t.Field(i)
+			mem = x.storeArgOrLoad(pos, b, source.Args[i], mem, fld.Type, storeOffset+fld.Offset, 0, storeRc.next(fld.Type))
+			pos = pos.WithNotStmt()
+		}
+		return mem
+
+	case OpArrayMake1:
+		return x.storeArgOrLoad(pos, b, source.Args[0], mem, t.Elem(), storeOffset, 0, storeRc.at(t, 0))
+
+	case OpInt64Make:
+		tHi, tLo := x.intPairTypes(t.Kind())
+		mem = x.storeArgOrLoad(pos, b, source.Args[0], mem, tHi, storeOffset+x.hiOffset, 0, storeRc.next(tHi))
+		pos = pos.WithNotStmt()
+		return x.storeArgOrLoad(pos, b, source.Args[1], mem, tLo, storeOffset+x.lowOffset, 0, storeRc)
+
+	case OpComplexMake:
+		tPart := x.typs.Float32
+		wPart := t.Width / 2
+		if wPart == 8 {
+			tPart = x.typs.Float64
+		}
+		mem = x.storeArgOrLoad(pos, b, source.Args[0], mem, tPart, storeOffset, 0, storeRc.next(tPart))
+		pos = pos.WithNotStmt()
+		return x.storeArgOrLoad(pos, b, source.Args[1], mem, tPart, storeOffset+wPart, 0, storeRc)
+
+	case OpIMake:
+		mem = x.storeArgOrLoad(pos, b, source.Args[0], mem, x.typs.Uintptr, storeOffset, 0, storeRc.next(x.typs.Uintptr))
+		pos = pos.WithNotStmt()
+		return x.storeArgOrLoad(pos, b, source.Args[1], mem, x.typs.BytePtr, storeOffset+x.ptrSize, 0, storeRc)
+
+	case OpStringMake:
+		mem = x.storeArgOrLoad(pos, b, source.Args[0], mem, x.typs.BytePtr, storeOffset, 0, storeRc.next(x.typs.BytePtr))
+		pos = pos.WithNotStmt()
+		return x.storeArgOrLoad(pos, b, source.Args[1], mem, x.typs.Int, storeOffset+x.ptrSize, 0, storeRc)
+
+	case OpSliceMake:
+		mem = x.storeArgOrLoad(pos, b, source.Args[0], mem, x.typs.BytePtr, storeOffset, 0, storeRc.next(x.typs.BytePtr))
+		pos = pos.WithNotStmt()
+		mem = x.storeArgOrLoad(pos, b, source.Args[1], mem, x.typs.Int, storeOffset+x.ptrSize, 0, storeRc.next(x.typs.Int))
+		return x.storeArgOrLoad(pos, b, source.Args[2], mem, x.typs.Int, storeOffset+2*x.ptrSize, 0, storeRc)
+	}
+
+	// For nodes that cannot be taken apart -- OpSelectN, other structure selectors.
+	switch t.Kind() {
+	case types.TARRAY:
+		elt := t.Elem()
+		if source.Type != t && t.NumElem() == 1 && elt.Width == t.Width && t.Width == x.regSize {
+			t = removeTrivialWrapperTypes(t)
+			// it could be a leaf type, but the "leaf" could be complex64 (for example)
+			return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
+		}
+		eltRO := x.regWidth(elt)
+		for i := int64(0); i < t.NumElem(); i++ {
+			sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source)
+			mem = x.storeArgOrLoad(pos, b, sel, mem, elt, storeOffset+i*elt.Width, loadRegOffset, storeRc.at(t, 0))
+			loadRegOffset += eltRO
+			pos = pos.WithNotStmt()
+		}
+		return mem
+
+	case types.TSTRUCT:
+		if source.Type != t && t.NumFields() == 1 && t.Field(0).Type.Width == t.Width && t.Width == x.regSize {
+			// This peculiar test deals with accesses to immediate interface data.
+			// It works okay because everything is the same size.
+			// Example code that triggers this can be found in go/constant/value.go, function ToComplex
+			// v119 (+881) = IData <intVal> v6
+			// v121 (+882) = StaticLECall <floatVal,mem> {AuxCall{"".itof([intVal,0])[floatVal,8]}} [16] v119 v1
+			// This corresponds to the generic rewrite rule "(StructSelect [0] (IData x)) => (IData x)"
+			// Guard against "struct{struct{*foo}}"
+			// Other rewriting phases create minor glitches when they transform IData, for instance the
+			// interface-typed Arg "x" of ToFloat in go/constant/value.go
+			//   v6 (858) = Arg <Value> {x} (x[Value], x[Value])
+			// is rewritten by decomposeArgs into
+			//   v141 (858) = Arg <uintptr> {x}
+			//   v139 (858) = Arg <*uint8> {x} [8]
+			// because of a type case clause on line 862 of go/constant/value.go
+			//  	case intVal:
+			//		   return itof(x)
+			// v139 is later stored as an intVal == struct{val *big.Int} which naively requires the fields of
+			// of a *uint8, which does not succeed.
+			t = removeTrivialWrapperTypes(t)
+			// it could be a leaf type, but the "leaf" could be complex64 (for example)
+			return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
+		}
+
+		for i := 0; i < t.NumFields(); i++ {
+			fld := t.Field(i)
+			sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source)
+			mem = x.storeArgOrLoad(pos, b, sel, mem, fld.Type, storeOffset+fld.Offset, loadRegOffset, storeRc.next(fld.Type))
+			loadRegOffset += x.regWidth(fld.Type)
+			pos = pos.WithNotStmt()
+		}
+		return mem
+
+	case types.TINT64, types.TUINT64:
+		if t.Width == x.regSize {
+			break
+		}
+		tHi, tLo := x.intPairTypes(t.Kind())
+		sel := source.Block.NewValue1(pos, OpInt64Hi, tHi, source)
+		mem = x.storeArgOrLoad(pos, b, sel, mem, tHi, storeOffset+x.hiOffset, loadRegOffset+x.hiRo, storeRc.plus(x.hiRo))
+		pos = pos.WithNotStmt()
+		sel = source.Block.NewValue1(pos, OpInt64Lo, tLo, source)
+		return x.storeArgOrLoad(pos, b, sel, mem, tLo, storeOffset+x.lowOffset, loadRegOffset+x.loRo, storeRc.plus(x.hiRo))
+
+	case types.TINTER:
+		sel := source.Block.NewValue1(pos, OpITab, x.typs.BytePtr, source)
+		mem = x.storeArgOrLoad(pos, b, sel, mem, x.typs.BytePtr, storeOffset, loadRegOffset, storeRc.next(x.typs.BytePtr))
+		pos = pos.WithNotStmt()
+		sel = source.Block.NewValue1(pos, OpIData, x.typs.BytePtr, source)
+		return x.storeArgOrLoad(pos, b, sel, mem, x.typs.BytePtr, storeOffset+x.ptrSize, loadRegOffset+RO_iface_data, storeRc)
+
+	case types.TSTRING:
+		sel := source.Block.NewValue1(pos, OpStringPtr, x.typs.BytePtr, source)
+		mem = x.storeArgOrLoad(pos, b, sel, mem, x.typs.BytePtr, storeOffset, loadRegOffset, storeRc.next(x.typs.BytePtr))
+		pos = pos.WithNotStmt()
+		sel = source.Block.NewValue1(pos, OpStringLen, x.typs.Int, source)
+		return x.storeArgOrLoad(pos, b, sel, mem, x.typs.Int, storeOffset+x.ptrSize, loadRegOffset+RO_string_len, storeRc)
+
+	case types.TSLICE:
+		et := types.NewPtr(t.Elem())
+		sel := source.Block.NewValue1(pos, OpSlicePtr, et, source)
+		mem = x.storeArgOrLoad(pos, b, sel, mem, et, storeOffset, loadRegOffset, storeRc.next(et))
+		pos = pos.WithNotStmt()
+		sel = source.Block.NewValue1(pos, OpSliceLen, x.typs.Int, source)
+		mem = x.storeArgOrLoad(pos, b, sel, mem, x.typs.Int, storeOffset+x.ptrSize, loadRegOffset+RO_slice_len, storeRc.next(x.typs.Int))
+		sel = source.Block.NewValue1(pos, OpSliceCap, x.typs.Int, source)
+		return x.storeArgOrLoad(pos, b, sel, mem, x.typs.Int, storeOffset+2*x.ptrSize, loadRegOffset+RO_slice_cap, storeRc)
+
+	case types.TCOMPLEX64:
+		sel := source.Block.NewValue1(pos, OpComplexReal, x.typs.Float32, source)
+		mem = x.storeArgOrLoad(pos, b, sel, mem, x.typs.Float32, storeOffset, loadRegOffset, storeRc.next(x.typs.Float32))
+		pos = pos.WithNotStmt()
+		sel = source.Block.NewValue1(pos, OpComplexImag, x.typs.Float32, source)
+		return x.storeArgOrLoad(pos, b, sel, mem, x.typs.Float32, storeOffset+4, loadRegOffset+RO_complex_imag, storeRc)
+
+	case types.TCOMPLEX128:
+		sel := source.Block.NewValue1(pos, OpComplexReal, x.typs.Float64, source)
+		mem = x.storeArgOrLoad(pos, b, sel, mem, x.typs.Float64, storeOffset, loadRegOffset, storeRc.next(x.typs.Float64))
+		pos = pos.WithNotStmt()
+		sel = source.Block.NewValue1(pos, OpComplexImag, x.typs.Float64, source)
+		return x.storeArgOrLoad(pos, b, sel, mem, x.typs.Float64, storeOffset+8, loadRegOffset+RO_complex_imag, storeRc)
+	}
+
+	s := mem
+	if source.Op == OpDereference {
+		source.Op = OpLoad // For purposes of parameter passing expansion, a Dereference is a Load.
+	}
+	if storeRc.hasRegs() {
+		storeRc.addArg(source)
+	} else {
+		dst := x.offsetFrom(b, storeRc.storeDest, storeOffset, types.NewPtr(t))
+		s = b.NewValue3A(pos, OpStore, types.TypeMem, t, dst, source, mem)
+	}
+	if x.debug {
+		x.Printf("-->storeArg returns %s, storeRc=%s\n", s.LongString(), storeRc.String())
+	}
+	return s
+}
+
+// rewriteArgs replaces all the call-parameter Args to a call with their register translation (if any).
+// Preceding parameters (code pointers, closure pointer) are preserved, and the memory input is modified
+// to account for any parameter stores required.
+// Any of the old Args that have their use count fall to zero are marked OpInvalid.
+func (x *expandState) rewriteArgs(v *Value, firstArg int) {
+	if x.debug {
+		x.indent(3)
+		defer x.indent(-3)
+		x.Printf("rewriteArgs(%s; %d)\n", v.LongString(), firstArg)
+	}
+	// Thread the stores on the memory arg
+	aux := v.Aux.(*AuxCall)
+	pos := v.Pos.WithNotStmt()
+	m0 := v.MemoryArg()
+	mem := m0
+	newArgs := []*Value{}
+	oldArgs := []*Value{}
+	for i, a := range v.Args[firstArg : len(v.Args)-1] { // skip leading non-parameter SSA Args and trailing mem SSA Arg.
+		oldArgs = append(oldArgs, a)
+		auxI := int64(i)
+		aRegs := aux.RegsOfArg(auxI)
+		aType := aux.TypeOfArg(auxI)
+		if len(aRegs) == 0 && a.Op == OpDereference {
+			aOffset := aux.OffsetOfArg(auxI)
+			if a.MemoryArg() != m0 {
+				x.f.Fatalf("Op...LECall and OpDereference have mismatched mem, %s and %s", v.LongString(), a.LongString())
+			}
+			// "Dereference" of addressed (probably not-SSA-eligible) value becomes Move
+			// TODO(register args) this will be more complicated with registers in the picture.
+			mem = x.rewriteDereference(v.Block, x.sp, a, mem, aOffset, aux.SizeOfArg(auxI), aType, pos)
+		} else {
+			var rc registerCursor
+			var result *[]*Value
+			var aOffset int64
+			if len(aRegs) > 0 {
+				result = &newArgs
+			} else {
+				aOffset = aux.OffsetOfArg(auxI)
+			}
+			if x.debug {
+				x.Printf("...storeArg %s, %v, %d\n", a.LongString(), aType, aOffset)
+			}
+			rc.init(aRegs, aux.abiInfo, result, x.sp)
+			mem = x.storeArgOrLoad(pos, v.Block, a, mem, aType, aOffset, 0, rc)
+		}
+	}
+	var preArgStore [2]*Value
+	preArgs := append(preArgStore[:0], v.Args[0:firstArg]...)
+	v.resetArgs()
+	v.AddArgs(preArgs...)
+	v.AddArgs(newArgs...)
+	v.AddArg(mem)
+	for _, a := range oldArgs {
+		if a.Uses == 0 {
+			if x.debug {
+				x.Printf("...marking %v unused\n", a.LongString())
+			}
+			a.invalidateRecursively()
+		}
+	}
+
+	return
 }
 
 // expandCalls converts LE (Late Expansion) calls that act like they receive value args into a lower-level form
@@ -38,675 +1138,132 @@
 
 	// With the current ABI, the outputs need to be converted to loads, which will all use the call's
 	// memory output as their input.
-	if !LateCallExpansionEnabledWithin(f) {
-		return
-	}
-	debug := f.pass.debug > 0
-
-	if debug {
-		fmt.Printf("\nexpandsCalls(%s)\n", f.Name)
-	}
-
-	canSSAType := f.fe.CanSSA
-	regSize := f.Config.RegSize
 	sp, _ := f.spSb()
-	typ := &f.Config.Types
-	ptrSize := f.Config.PtrSize
+	x := &expandState{
+		f:                  f,
+		abi1:               f.ABI1,
+		debug:              f.pass.debug > 0,
+		canSSAType:         f.fe.CanSSA,
+		regSize:            f.Config.RegSize,
+		sp:                 sp,
+		typs:               &f.Config.Types,
+		ptrSize:            f.Config.PtrSize,
+		namedSelects:       make(map[*Value][]namedVal),
+		sdom:               f.Sdom(),
+		commonArgs:         make(map[selKey]*Value),
+		memForCall:         make(map[ID]*Value),
+		transformedSelects: make(map[ID]bool),
+	}
 
 	// For 32-bit, need to deal with decomposition of 64-bit integers, which depends on endianness.
-	var hiOffset, lowOffset int64
 	if f.Config.BigEndian {
-		lowOffset = 4
+		x.lowOffset, x.hiOffset = 4, 0
+		x.loRo, x.hiRo = 1, 0
 	} else {
-		hiOffset = 4
+		x.lowOffset, x.hiOffset = 0, 4
+		x.loRo, x.hiRo = 0, 1
 	}
 
-	namedSelects := make(map[*Value][]namedVal)
-
-	sdom := f.Sdom()
-
-	common := make(map[selKey]*Value)
-
-	// intPairTypes returns the pair of 32-bit int types needed to encode a 64-bit integer type on a target
-	// that has no 64-bit integer registers.
-	intPairTypes := func(et types.EType) (tHi, tLo *types.Type) {
-		tHi = typ.UInt32
-		if et == types.TINT64 {
-			tHi = typ.Int32
-		}
-		tLo = typ.UInt32
-		return
-	}
-
-	// isAlreadyExpandedAggregateType returns whether a type is an SSA-able "aggregate" (multiple register) type
-	// that was expanded in an earlier phase (currently, expand_calls is intended to run after decomposeBuiltin,
-	// so this is all aggregate types -- small struct and array, complex, interface, string, slice, and 64-bit
-	// integer on 32-bit).
-	isAlreadyExpandedAggregateType := func(t *types.Type) bool {
-		if !canSSAType(t) {
-			return false
-		}
-		return t.IsStruct() || t.IsArray() || t.IsComplex() || t.IsInterface() || t.IsString() || t.IsSlice() ||
-			t.Size() > regSize && t.IsInteger()
-	}
-
-	offsets := make(map[offsetKey]*Value)
-
-	// offsetFrom creates an offset from a pointer, simplifying chained offsets and offsets from SP
-	// TODO should also optimize offsets from SB?
-	offsetFrom := func(from *Value, offset int64, pt *types.Type) *Value {
-		if offset == 0 && from.Type == pt { // this is not actually likely
-			return from
-		}
-		// Simplify, canonicalize
-		for from.Op == OpOffPtr {
-			offset += from.AuxInt
-			from = from.Args[0]
-		}
-		if from == sp {
-			return f.ConstOffPtrSP(pt, offset, sp)
-		}
-		key := offsetKey{from, offset, pt}
-		v := offsets[key]
-		if v != nil {
-			return v
-		}
-		v = from.Block.NewValue1I(from.Pos.WithNotStmt(), OpOffPtr, pt, offset, from)
-		offsets[key] = v
-		return v
-	}
-
-	// splitSlots splits one "field" (specified by sfx, offset, and ty) out of the LocalSlots in ls and returns the new LocalSlots this generates.
-	splitSlots := func(ls []LocalSlot, sfx string, offset int64, ty *types.Type) []LocalSlot {
-		var locs []LocalSlot
-		for i := range ls {
-			locs = append(locs, f.fe.SplitSlot(&ls[i], sfx, offset, ty))
-		}
-		return locs
-	}
-
-	// removeTrivialWrapperTypes unwraps layers of
-	// struct { singleField SomeType } and [1]SomeType
-	// until a non-wrapper type is reached.  This is useful
-	// for working with assignments to/from interface data
-	// fields (either second operand to OpIMake or OpIData)
-	// where the wrapping or type conversion can be elided
-	// because of type conversions/assertions in source code
-	// that do not appear in SSA.
-	removeTrivialWrapperTypes := func(t *types.Type) *types.Type {
-		for {
-			if t.IsStruct() && t.NumFields() == 1 {
-				t = t.Field(0).Type
-				continue
-			}
-			if t.IsArray() && t.NumElem() == 1 {
-				t = t.Elem()
-				continue
-			}
-			break
-		}
-		return t
-	}
-
-	// Calls that need lowering have some number of inputs, including a memory input,
-	// and produce a tuple of (value1, value2, ..., mem) where valueK may or may not be SSA-able.
-
-	// With the current ABI those inputs need to be converted into stores to memory,
-	// rethreading the call's memory input to the first, and the new call now receiving the last.
-
-	// With the current ABI, the outputs need to be converted to loads, which will all use the call's
-	// memory output as their input.
-
-	// rewriteSelect recursively walks from leaf selector to a root (OpSelectN, OpLoad, OpArg)
-	// through a chain of Struct/Array/builtin Select operations.  If the chain of selectors does not
-	// end in an expected root, it does nothing (this can happen depending on compiler phase ordering).
-	// The "leaf" provides the type, the root supplies the container, and the leaf-to-root path
-	// accumulates the offset.
-	// It emits the code necessary to implement the leaf select operation that leads to the root.
-	//
-	// TODO when registers really arrive, must also decompose anything split across two registers or registers and memory.
-	var rewriteSelect func(leaf *Value, selector *Value, offset int64) []LocalSlot
-	rewriteSelect = func(leaf *Value, selector *Value, offset int64) []LocalSlot {
-		if debug {
-			fmt.Printf("rewriteSelect(%s, %s, %d)\n", leaf.LongString(), selector.LongString(), offset)
-		}
-		var locs []LocalSlot
-		leafType := leaf.Type
-		if len(selector.Args) > 0 {
-			w := selector.Args[0]
-			if w.Op == OpCopy {
-				for w.Op == OpCopy {
-					w = w.Args[0]
-				}
-				selector.SetArg(0, w)
-			}
-		}
-		switch selector.Op {
-		case OpArg:
-			if !isAlreadyExpandedAggregateType(selector.Type) {
-				if leafType == selector.Type { // OpIData leads us here, sometimes.
-					leaf.copyOf(selector)
-				} else {
-					f.Fatalf("Unexpected OpArg type, selector=%s, leaf=%s\n", selector.LongString(), leaf.LongString())
-				}
-				if debug {
-					fmt.Printf("\tOpArg, break\n")
-				}
-				break
-			}
-			switch leaf.Op {
-			case OpIData, OpStructSelect, OpArraySelect:
-				leafType = removeTrivialWrapperTypes(leaf.Type)
-			}
-			aux := selector.Aux
-			auxInt := selector.AuxInt + offset
-			if leaf.Block == selector.Block {
-				leaf.reset(OpArg)
-				leaf.Aux = aux
-				leaf.AuxInt = auxInt
-				leaf.Type = leafType
-			} else {
-				w := selector.Block.NewValue0IA(leaf.Pos, OpArg, leafType, auxInt, aux)
-				leaf.copyOf(w)
-				if debug {
-					fmt.Printf("\tnew %s\n", w.LongString())
-				}
-			}
-			for _, s := range namedSelects[selector] {
-				locs = append(locs, f.Names[s.locIndex])
-			}
-
-		case OpLoad: // We end up here because of IData of immediate structures.
-			// Failure case:
-			// (note the failure case is very rare; w/o this case, make.bash and run.bash both pass, as well as
-			// the hard cases of building {syscall,math,math/cmplx,math/bits,go/constant} on ppc64le and mips-softfloat).
-			//
-			// GOSSAFUNC='(*dumper).dump' go build -gcflags=-l -tags=math_big_pure_go cmd/compile/internal/gc
-			// cmd/compile/internal/gc/dump.go:136:14: internal compiler error: '(*dumper).dump': not lowered: v827, StructSelect PTR PTR
-			// b2: ← b1
-			// v20 (+142) = StaticLECall <interface {},mem> {AuxCall{reflect.Value.Interface([reflect.Value,0])[interface {},24]}} [40] v8 v1
-			// v21 (142) = SelectN <mem> [1] v20
-			// v22 (142) = SelectN <interface {}> [0] v20
-			// b15: ← b8
-			// v71 (+143) = IData <Nodes> v22 (v[Nodes])
-			// v73 (+146) = StaticLECall <[]*Node,mem> {AuxCall{"".Nodes.Slice([Nodes,0])[[]*Node,8]}} [32] v71 v21
-			//
-			// translates (w/o the "case OpLoad:" above) to:
-			//
-			// b2: ← b1
-			// v20 (+142) = StaticCall <mem> {AuxCall{reflect.Value.Interface([reflect.Value,0])[interface {},24]}} [40] v715
-			// v23 (142) = Load <*uintptr> v19 v20
-			// v823 (142) = IsNonNil <bool> v23
-			// v67 (+143) = Load <*[]*Node> v880 v20
-			// b15: ← b8
-			// v827 (146) = StructSelect <*[]*Node> [0] v67
-			// v846 (146) = Store <mem> {*[]*Node} v769 v827 v20
-			// v73 (+146) = StaticCall <mem> {AuxCall{"".Nodes.Slice([Nodes,0])[[]*Node,8]}} [32] v846
-			// i.e., the struct select is generated and remains in because it is not applied to an actual structure.
-			// The OpLoad was created to load the single field of the IData
-			// This case removes that StructSelect.
-			if leafType != selector.Type {
-				f.Fatalf("Unexpected Load as selector, leaf=%s, selector=%s\n", leaf.LongString(), selector.LongString())
-			}
-			leaf.copyOf(selector)
-			for _, s := range namedSelects[selector] {
-				locs = append(locs, f.Names[s.locIndex])
-			}
-
-		case OpSelectN:
-			// TODO these may be duplicated. Should memoize. Intermediate selectors will go dead, no worries there.
-			call := selector.Args[0]
-			aux := call.Aux.(*AuxCall)
-			which := selector.AuxInt
-			if which == aux.NResults() { // mem is after the results.
-				// rewrite v as a Copy of call -- the replacement call will produce a mem.
-				leaf.copyOf(call)
-			} else {
-				leafType := removeTrivialWrapperTypes(leaf.Type)
-				if canSSAType(leafType) {
-					pt := types.NewPtr(leafType)
-					off := offsetFrom(sp, offset+aux.OffsetOfResult(which), pt)
-					// Any selection right out of the arg area/registers has to be same Block as call, use call as mem input.
-					if leaf.Block == call.Block {
-						leaf.reset(OpLoad)
-						leaf.SetArgs2(off, call)
-						leaf.Type = leafType
-					} else {
-						w := call.Block.NewValue2(leaf.Pos, OpLoad, leafType, off, call)
-						leaf.copyOf(w)
-						if debug {
-							fmt.Printf("\tnew %s\n", w.LongString())
-						}
-					}
-					for _, s := range namedSelects[selector] {
-						locs = append(locs, f.Names[s.locIndex])
-					}
-				} else {
-					f.Fatalf("Should not have non-SSA-able OpSelectN, selector=%s", selector.LongString())
-				}
-			}
-
-		case OpStructSelect:
-			w := selector.Args[0]
-			var ls []LocalSlot
-			if w.Type.Etype != types.TSTRUCT { // IData artifact
-				ls = rewriteSelect(leaf, w, offset)
-			} else {
-				ls = rewriteSelect(leaf, w, offset+w.Type.FieldOff(int(selector.AuxInt)))
-				if w.Op != OpIData {
-					for _, l := range ls {
-						locs = append(locs, f.fe.SplitStruct(l, int(selector.AuxInt)))
-					}
-				}
-			}
-
-		case OpArraySelect:
-			w := selector.Args[0]
-			rewriteSelect(leaf, w, offset+selector.Type.Size()*selector.AuxInt)
-
-		case OpInt64Hi:
-			w := selector.Args[0]
-			ls := rewriteSelect(leaf, w, offset+hiOffset)
-			locs = splitSlots(ls, ".hi", hiOffset, leafType)
-
-		case OpInt64Lo:
-			w := selector.Args[0]
-			ls := rewriteSelect(leaf, w, offset+lowOffset)
-			locs = splitSlots(ls, ".lo", lowOffset, leafType)
-
-		case OpStringPtr:
-			ls := rewriteSelect(leaf, selector.Args[0], offset)
-			locs = splitSlots(ls, ".ptr", 0, typ.BytePtr)
-
-		case OpSlicePtr:
-			w := selector.Args[0]
-			ls := rewriteSelect(leaf, w, offset)
-			locs = splitSlots(ls, ".ptr", 0, types.NewPtr(w.Type.Elem()))
-
-		case OpITab:
-			w := selector.Args[0]
-			ls := rewriteSelect(leaf, w, offset)
-			sfx := ".itab"
-			if w.Type.IsEmptyInterface() {
-				sfx = ".type"
-			}
-			locs = splitSlots(ls, sfx, 0, typ.Uintptr)
-
-		case OpComplexReal:
-			ls := rewriteSelect(leaf, selector.Args[0], offset)
-			locs = splitSlots(ls, ".real", 0, leafType)
-
-		case OpComplexImag:
-			ls := rewriteSelect(leaf, selector.Args[0], offset+leafType.Width) // result is FloatNN, width of result is offset of imaginary part.
-			locs = splitSlots(ls, ".imag", leafType.Width, leafType)
-
-		case OpStringLen, OpSliceLen:
-			ls := rewriteSelect(leaf, selector.Args[0], offset+ptrSize)
-			locs = splitSlots(ls, ".len", ptrSize, leafType)
-
-		case OpIData:
-			ls := rewriteSelect(leaf, selector.Args[0], offset+ptrSize)
-			locs = splitSlots(ls, ".data", ptrSize, leafType)
-
-		case OpSliceCap:
-			ls := rewriteSelect(leaf, selector.Args[0], offset+2*ptrSize)
-			locs = splitSlots(ls, ".cap", 2*ptrSize, leafType)
-
-		case OpCopy: // If it's an intermediate result, recurse
-			locs = rewriteSelect(leaf, selector.Args[0], offset)
-			for _, s := range namedSelects[selector] {
-				// this copy may have had its own name, preserve that, too.
-				locs = append(locs, f.Names[s.locIndex])
-			}
-
-		default:
-			// Ignore dead ends. These can occur if this phase is run before decompose builtin (which is not intended, but allowed).
-		}
-
-		return locs
-	}
-
-	// storeArgOrLoad converts stores of SSA-able aggregate arguments (passed to a call) into a series of primitive-typed
-	// stores of non-aggregate types.  It recursively walks up a chain of selectors until it reaches a Load or an Arg.
-	// If it does not reach a Load or an Arg, nothing happens; this allows a little freedom in phase ordering.
-	var storeArgOrLoad func(pos src.XPos, b *Block, base, source, mem *Value, t *types.Type, offset int64) *Value
-
-	// decomposeArgOrLoad is a helper for storeArgOrLoad.
-	// It decomposes a Load or an Arg into smaller parts, parameterized by the decomposeOne and decomposeTwo functions
-	// passed to it, and returns the new mem. If the type does not match one of the expected aggregate types, it returns nil instead.
-	decomposeArgOrLoad := func(pos src.XPos, b *Block, base, source, mem *Value, t *types.Type, offset int64,
-		decomposeOne func(pos src.XPos, b *Block, base, source, mem *Value, t1 *types.Type, offArg, offStore int64) *Value,
-		decomposeTwo func(pos src.XPos, b *Block, base, source, mem *Value, t1, t2 *types.Type, offArg, offStore int64) *Value) *Value {
-		u := source.Type
-		switch u.Etype {
-		case types.TARRAY:
-			elem := u.Elem()
-			for i := int64(0); i < u.NumElem(); i++ {
-				elemOff := i * elem.Size()
-				mem = decomposeOne(pos, b, base, source, mem, elem, source.AuxInt+elemOff, offset+elemOff)
-				pos = pos.WithNotStmt()
-			}
-			return mem
-		case types.TSTRUCT:
-			for i := 0; i < u.NumFields(); i++ {
-				fld := u.Field(i)
-				mem = decomposeOne(pos, b, base, source, mem, fld.Type, source.AuxInt+fld.Offset, offset+fld.Offset)
-				pos = pos.WithNotStmt()
-			}
-			return mem
-		case types.TINT64, types.TUINT64:
-			if t.Width == regSize {
-				break
-			}
-			tHi, tLo := intPairTypes(t.Etype)
-			mem = decomposeOne(pos, b, base, source, mem, tHi, source.AuxInt+hiOffset, offset+hiOffset)
-			pos = pos.WithNotStmt()
-			return decomposeOne(pos, b, base, source, mem, tLo, source.AuxInt+lowOffset, offset+lowOffset)
-		case types.TINTER:
-			return decomposeTwo(pos, b, base, source, mem, typ.Uintptr, typ.BytePtr, source.AuxInt, offset)
-		case types.TSTRING:
-			return decomposeTwo(pos, b, base, source, mem, typ.BytePtr, typ.Int, source.AuxInt, offset)
-		case types.TCOMPLEX64:
-			return decomposeTwo(pos, b, base, source, mem, typ.Float32, typ.Float32, source.AuxInt, offset)
-		case types.TCOMPLEX128:
-			return decomposeTwo(pos, b, base, source, mem, typ.Float64, typ.Float64, source.AuxInt, offset)
-		case types.TSLICE:
-			mem = decomposeTwo(pos, b, base, source, mem, typ.BytePtr, typ.Int, source.AuxInt, offset)
-			return decomposeOne(pos, b, base, source, mem, typ.Int, source.AuxInt+2*ptrSize, offset+2*ptrSize)
-		}
-		return nil
-	}
-
-	// storeOneArg creates a decomposed (one step) arg that is then stored.
-	// pos and b locate the store instruction, base is the base of the store target, source is the "base" of the value input,
-	// mem is the input mem, t is the type in question, and offArg and offStore are the offsets from the respective bases.
-	storeOneArg := func(pos src.XPos, b *Block, base, source, mem *Value, t *types.Type, offArg, offStore int64) *Value {
-		w := common[selKey{source, offArg, t.Width, t}]
-		if w == nil {
-			w = source.Block.NewValue0IA(source.Pos, OpArg, t, offArg, source.Aux)
-			common[selKey{source, offArg, t.Width, t}] = w
-		}
-		return storeArgOrLoad(pos, b, base, w, mem, t, offStore)
-	}
-
-	// storeOneLoad creates a decomposed (one step) load that is then stored.
-	storeOneLoad := func(pos src.XPos, b *Block, base, source, mem *Value, t *types.Type, offArg, offStore int64) *Value {
-		from := offsetFrom(source.Args[0], offArg, types.NewPtr(t))
-		w := source.Block.NewValue2(source.Pos, OpLoad, t, from, mem)
-		return storeArgOrLoad(pos, b, base, w, mem, t, offStore)
-	}
-
-	storeTwoArg := func(pos src.XPos, b *Block, base, source, mem *Value, t1, t2 *types.Type, offArg, offStore int64) *Value {
-		mem = storeOneArg(pos, b, base, source, mem, t1, offArg, offStore)
-		pos = pos.WithNotStmt()
-		t1Size := t1.Size()
-		return storeOneArg(pos, b, base, source, mem, t2, offArg+t1Size, offStore+t1Size)
-	}
-
-	storeTwoLoad := func(pos src.XPos, b *Block, base, source, mem *Value, t1, t2 *types.Type, offArg, offStore int64) *Value {
-		mem = storeOneLoad(pos, b, base, source, mem, t1, offArg, offStore)
-		pos = pos.WithNotStmt()
-		t1Size := t1.Size()
-		return storeOneLoad(pos, b, base, source, mem, t2, offArg+t1Size, offStore+t1Size)
-	}
-
-	storeArgOrLoad = func(pos src.XPos, b *Block, base, source, mem *Value, t *types.Type, offset int64) *Value {
-		if debug {
-			fmt.Printf("\tstoreArgOrLoad(%s;  %s;  %s;  %s; %d)\n", base.LongString(), source.LongString(), mem.String(), t.String(), offset)
-		}
-
-		switch source.Op {
-		case OpCopy:
-			return storeArgOrLoad(pos, b, base, source.Args[0], mem, t, offset)
-
-		case OpLoad:
-			ret := decomposeArgOrLoad(pos, b, base, source, mem, t, offset, storeOneLoad, storeTwoLoad)
-			if ret != nil {
-				return ret
-			}
-
-		case OpArg:
-			ret := decomposeArgOrLoad(pos, b, base, source, mem, t, offset, storeOneArg, storeTwoArg)
-			if ret != nil {
-				return ret
-			}
-
-		case OpArrayMake0, OpStructMake0:
-			return mem
-
-		case OpStructMake1, OpStructMake2, OpStructMake3, OpStructMake4:
-			for i := 0; i < t.NumFields(); i++ {
-				fld := t.Field(i)
-				mem = storeArgOrLoad(pos, b, base, source.Args[i], mem, fld.Type, offset+fld.Offset)
-				pos = pos.WithNotStmt()
-			}
-			return mem
-
-		case OpArrayMake1:
-			return storeArgOrLoad(pos, b, base, source.Args[0], mem, t.Elem(), offset)
-
-		case OpInt64Make:
-			tHi, tLo := intPairTypes(t.Etype)
-			mem = storeArgOrLoad(pos, b, base, source.Args[0], mem, tHi, offset+hiOffset)
-			pos = pos.WithNotStmt()
-			return storeArgOrLoad(pos, b, base, source.Args[1], mem, tLo, offset+lowOffset)
-
-		case OpComplexMake:
-			tPart := typ.Float32
-			wPart := t.Width / 2
-			if wPart == 8 {
-				tPart = typ.Float64
-			}
-			mem = storeArgOrLoad(pos, b, base, source.Args[0], mem, tPart, offset)
-			pos = pos.WithNotStmt()
-			return storeArgOrLoad(pos, b, base, source.Args[1], mem, tPart, offset+wPart)
-
-		case OpIMake:
-			mem = storeArgOrLoad(pos, b, base, source.Args[0], mem, typ.Uintptr, offset)
-			pos = pos.WithNotStmt()
-			return storeArgOrLoad(pos, b, base, source.Args[1], mem, typ.BytePtr, offset+ptrSize)
-
-		case OpStringMake:
-			mem = storeArgOrLoad(pos, b, base, source.Args[0], mem, typ.BytePtr, offset)
-			pos = pos.WithNotStmt()
-			return storeArgOrLoad(pos, b, base, source.Args[1], mem, typ.Int, offset+ptrSize)
-
-		case OpSliceMake:
-			mem = storeArgOrLoad(pos, b, base, source.Args[0], mem, typ.BytePtr, offset)
-			pos = pos.WithNotStmt()
-			mem = storeArgOrLoad(pos, b, base, source.Args[1], mem, typ.Int, offset+ptrSize)
-			return storeArgOrLoad(pos, b, base, source.Args[2], mem, typ.Int, offset+2*ptrSize)
-		}
-
-		// For nodes that cannot be taken apart -- OpSelectN, other structure selectors.
-		switch t.Etype {
-		case types.TARRAY:
-			elt := t.Elem()
-			if source.Type != t && t.NumElem() == 1 && elt.Width == t.Width && t.Width == regSize {
-				t = removeTrivialWrapperTypes(t)
-				// it could be a leaf type, but the "leaf" could be complex64 (for example)
-				return storeArgOrLoad(pos, b, base, source, mem, t, offset)
-			}
-			for i := int64(0); i < t.NumElem(); i++ {
-				sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source)
-				mem = storeArgOrLoad(pos, b, base, sel, mem, elt, offset+i*elt.Width)
-				pos = pos.WithNotStmt()
-			}
-			return mem
-
-		case types.TSTRUCT:
-			if source.Type != t && t.NumFields() == 1 && t.Field(0).Type.Width == t.Width && t.Width == regSize {
-				// This peculiar test deals with accesses to immediate interface data.
-				// It works okay because everything is the same size.
-				// Example code that triggers this can be found in go/constant/value.go, function ToComplex
-				// v119 (+881) = IData <intVal> v6
-				// v121 (+882) = StaticLECall <floatVal,mem> {AuxCall{"".itof([intVal,0])[floatVal,8]}} [16] v119 v1
-				// This corresponds to the generic rewrite rule "(StructSelect [0] (IData x)) => (IData x)"
-				// Guard against "struct{struct{*foo}}"
-				// Other rewriting phases create minor glitches when they transform IData, for instance the
-				// interface-typed Arg "x" of ToFloat in go/constant/value.go
-				//   v6 (858) = Arg <Value> {x} (x[Value], x[Value])
-				// is rewritten by decomposeArgs into
-				//   v141 (858) = Arg <uintptr> {x}
-				//   v139 (858) = Arg <*uint8> {x} [8]
-				// because of a type case clause on line 862 of go/constant/value.go
-				//  	case intVal:
-				//		   return itof(x)
-				// v139 is later stored as an intVal == struct{val *big.Int} which naively requires the fields of
-				// of a *uint8, which does not succeed.
-				t = removeTrivialWrapperTypes(t)
-				// it could be a leaf type, but the "leaf" could be complex64 (for example)
-				return storeArgOrLoad(pos, b, base, source, mem, t, offset)
-			}
-
-			for i := 0; i < t.NumFields(); i++ {
-				fld := t.Field(i)
-				sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source)
-				mem = storeArgOrLoad(pos, b, base, sel, mem, fld.Type, offset+fld.Offset)
-				pos = pos.WithNotStmt()
-			}
-			return mem
-
-		case types.TINT64, types.TUINT64:
-			if t.Width == regSize {
-				break
-			}
-			tHi, tLo := intPairTypes(t.Etype)
-			sel := source.Block.NewValue1(pos, OpInt64Hi, tHi, source)
-			mem = storeArgOrLoad(pos, b, base, sel, mem, tHi, offset+hiOffset)
-			pos = pos.WithNotStmt()
-			sel = source.Block.NewValue1(pos, OpInt64Lo, tLo, source)
-			return storeArgOrLoad(pos, b, base, sel, mem, tLo, offset+lowOffset)
-
-		case types.TINTER:
-			sel := source.Block.NewValue1(pos, OpITab, typ.BytePtr, source)
-			mem = storeArgOrLoad(pos, b, base, sel, mem, typ.BytePtr, offset)
-			pos = pos.WithNotStmt()
-			sel = source.Block.NewValue1(pos, OpIData, typ.BytePtr, source)
-			return storeArgOrLoad(pos, b, base, sel, mem, typ.BytePtr, offset+ptrSize)
-
-		case types.TSTRING:
-			sel := source.Block.NewValue1(pos, OpStringPtr, typ.BytePtr, source)
-			mem = storeArgOrLoad(pos, b, base, sel, mem, typ.BytePtr, offset)
-			pos = pos.WithNotStmt()
-			sel = source.Block.NewValue1(pos, OpStringLen, typ.Int, source)
-			return storeArgOrLoad(pos, b, base, sel, mem, typ.Int, offset+ptrSize)
-
-		case types.TSLICE:
-			et := types.NewPtr(t.Elem())
-			sel := source.Block.NewValue1(pos, OpSlicePtr, et, source)
-			mem = storeArgOrLoad(pos, b, base, sel, mem, et, offset)
-			pos = pos.WithNotStmt()
-			sel = source.Block.NewValue1(pos, OpSliceLen, typ.Int, source)
-			mem = storeArgOrLoad(pos, b, base, sel, mem, typ.Int, offset+ptrSize)
-			sel = source.Block.NewValue1(pos, OpSliceCap, typ.Int, source)
-			return storeArgOrLoad(pos, b, base, sel, mem, typ.Int, offset+2*ptrSize)
-
-		case types.TCOMPLEX64:
-			sel := source.Block.NewValue1(pos, OpComplexReal, typ.Float32, source)
-			mem = storeArgOrLoad(pos, b, base, sel, mem, typ.Float32, offset)
-			pos = pos.WithNotStmt()
-			sel = source.Block.NewValue1(pos, OpComplexImag, typ.Float32, source)
-			return storeArgOrLoad(pos, b, base, sel, mem, typ.Float32, offset+4)
-
-		case types.TCOMPLEX128:
-			sel := source.Block.NewValue1(pos, OpComplexReal, typ.Float64, source)
-			mem = storeArgOrLoad(pos, b, base, sel, mem, typ.Float64, offset)
-			pos = pos.WithNotStmt()
-			sel = source.Block.NewValue1(pos, OpComplexImag, typ.Float64, source)
-			return storeArgOrLoad(pos, b, base, sel, mem, typ.Float64, offset+8)
-		}
-
-		dst := offsetFrom(base, offset, types.NewPtr(t))
-		x := b.NewValue3A(pos, OpStore, types.TypeMem, t, dst, source, mem)
-		if debug {
-			fmt.Printf("\t\tstoreArg returns %s\n", x.LongString())
-		}
-		return x
-	}
-
-	// rewriteArgs removes all the Args from a call and converts the call args into appropriate
-	// stores (or later, register movement).  Extra args for interface and closure calls are ignored,
-	// but removed.
-	rewriteArgs := func(v *Value, firstArg int) *Value {
-		// Thread the stores on the memory arg
-		aux := v.Aux.(*AuxCall)
-		pos := v.Pos.WithNotStmt()
-		m0 := v.Args[len(v.Args)-1]
-		mem := m0
-		for i, a := range v.Args {
-			if i < firstArg {
-				continue
-			}
-			if a == m0 { // mem is last.
-				break
-			}
-			auxI := int64(i - firstArg)
-			if a.Op == OpDereference {
-				if a.MemoryArg() != m0 {
-					f.Fatalf("Op...LECall and OpDereference have mismatched mem, %s and %s", v.LongString(), a.LongString())
-				}
-				// "Dereference" of addressed (probably not-SSA-eligible) value becomes Move
-				// TODO this will be more complicated with registers in the picture.
-				source := a.Args[0]
-				dst := f.ConstOffPtrSP(source.Type, aux.OffsetOfArg(auxI), sp)
-				if a.Uses == 1 && a.Block == v.Block {
-					a.reset(OpMove)
-					a.Pos = pos
-					a.Type = types.TypeMem
-					a.Aux = aux.TypeOfArg(auxI)
-					a.AuxInt = aux.SizeOfArg(auxI)
-					a.SetArgs3(dst, source, mem)
-					mem = a
-				} else {
-					mem = v.Block.NewValue3A(pos, OpMove, types.TypeMem, aux.TypeOfArg(auxI), dst, source, mem)
-					mem.AuxInt = aux.SizeOfArg(auxI)
-				}
-			} else {
-				if debug {
-					fmt.Printf("storeArg %s, %v, %d\n", a.LongString(), aux.TypeOfArg(auxI), aux.OffsetOfArg(auxI))
-				}
-				mem = storeArgOrLoad(pos, v.Block, sp, a, mem, aux.TypeOfArg(auxI), aux.OffsetOfArg(auxI))
-			}
-		}
-		v.resetArgs()
-		return mem
-	}
-
-	// TODO if too slow, whole program iteration can be replaced w/ slices of appropriate values, accumulated in first loop here.
-
-	// Step 0: rewrite the calls to convert incoming args to stores.
-	for _, b := range f.Blocks {
-		for _, v := range b.Values {
-			switch v.Op {
-			case OpStaticLECall:
-				mem := rewriteArgs(v, 0)
-				v.SetArgs1(mem)
-			case OpClosureLECall:
-				code := v.Args[0]
-				context := v.Args[1]
-				mem := rewriteArgs(v, 2)
-				v.SetArgs3(code, context, mem)
-			case OpInterLECall:
-				code := v.Args[0]
-				mem := rewriteArgs(v, 1)
-				v.SetArgs2(code, mem)
-			}
-		}
+	if x.debug {
+		x.Printf("\nexpandsCalls(%s)\n", f.Name)
 	}
 
 	for i, name := range f.Names {
 		t := name.Type
-		if isAlreadyExpandedAggregateType(t) {
-			for j, v := range f.NamedValues[name] {
-				if v.Op == OpSelectN || v.Op == OpArg && isAlreadyExpandedAggregateType(v.Type) {
-					ns := namedSelects[v]
-					namedSelects[v] = append(ns, namedVal{locIndex: i, valIndex: j})
+		if x.isAlreadyExpandedAggregateType(t) {
+			for j, v := range f.NamedValues[*name] {
+				if v.Op == OpSelectN || v.Op == OpArg && x.isAlreadyExpandedAggregateType(v.Type) {
+					ns := x.namedSelects[v]
+					x.namedSelects[v] = append(ns, namedVal{locIndex: i, valIndex: j})
 				}
 			}
 		}
 	}
 
+	// TODO if too slow, whole program iteration can be replaced w/ slices of appropriate values, accumulated in first loop here.
+
+	// Step 0: rewrite the calls to convert args to calls into stores/register movement.
+	for _, b := range f.Blocks {
+		for _, v := range b.Values {
+			firstArg := 0
+			switch v.Op {
+			case OpStaticLECall:
+			case OpInterLECall:
+				firstArg = 1
+			case OpClosureLECall:
+				firstArg = 2
+			default:
+				continue
+			}
+			x.rewriteArgs(v, firstArg)
+		}
+		if isBlockMultiValueExit(b) {
+			x.indent(3)
+			// Very similar to code in rewriteArgs, but results instead of args.
+			v := b.Controls[0]
+			m0 := v.MemoryArg()
+			mem := m0
+			aux := f.OwnAux
+			pos := v.Pos.WithNotStmt()
+			allResults := []*Value{}
+			if x.debug {
+				x.Printf("multiValueExit rewriting %s\n", v.LongString())
+			}
+			var oldArgs []*Value
+			for j, a := range v.Args[:len(v.Args)-1] {
+				oldArgs = append(oldArgs, a)
+				i := int64(j)
+				auxType := aux.TypeOfResult(i)
+				auxBase := b.NewValue2A(v.Pos, OpLocalAddr, types.NewPtr(auxType), aux.NameOfResult(i), x.sp, mem)
+				auxOffset := int64(0)
+				auxSize := aux.SizeOfResult(i)
+				aRegs := aux.RegsOfResult(int64(j))
+				if len(aRegs) == 0 && a.Op == OpDereference {
+					// Avoid a self-move, and if one is detected try to remove the already-inserted VarDef for the assignment that won't happen.
+					if dAddr, dMem := a.Args[0], a.Args[1]; dAddr.Op == OpLocalAddr && dAddr.Args[0].Op == OpSP &&
+						dAddr.Args[1] == dMem && dAddr.Aux == aux.NameOfResult(i) {
+						if dMem.Op == OpVarDef && dMem.Aux == dAddr.Aux {
+							dMem.copyOf(dMem.MemoryArg()) // elide the VarDef
+						}
+						continue
+					}
+					mem = x.rewriteDereference(v.Block, auxBase, a, mem, auxOffset, auxSize, auxType, pos)
+				} else {
+					if a.Op == OpLoad && a.Args[0].Op == OpLocalAddr {
+						addr := a.Args[0] // This is a self-move. // TODO(register args) do what here for registers?
+						if addr.MemoryArg() == a.MemoryArg() && addr.Aux == aux.NameOfResult(i) {
+							continue
+						}
+					}
+					var rc registerCursor
+					var result *[]*Value
+					if len(aRegs) > 0 {
+						result = &allResults
+					}
+					rc.init(aRegs, aux.abiInfo, result, auxBase)
+					mem = x.storeArgOrLoad(v.Pos, b, a, mem, aux.TypeOfResult(i), auxOffset, 0, rc)
+				}
+			}
+			v.resetArgs()
+			v.AddArgs(allResults...)
+			v.AddArg(mem)
+			v.Type = types.NewResults(append(abi.RegisterTypes(aux.abiInfo.OutParams()), types.TypeMem))
+			b.SetControl(v)
+			for _, a := range oldArgs {
+				if a.Uses == 0 {
+					if x.debug {
+						x.Printf("...marking %v unused\n", a.LongString())
+					}
+					a.invalidateRecursively()
+				}
+			}
+			if x.debug {
+				x.Printf("...multiValueExit new result %s\n", v.LongString())
+			}
+			x.indent(-3)
+		}
+	}
+
 	// Step 1: any stores of aggregates remaining are believed to be sourced from call results or args.
 	// Decompose those stores into a series of smaller stores, adding selection ops as necessary.
 	for _, b := range f.Blocks {
@@ -715,24 +1272,19 @@
 				t := v.Aux.(*types.Type)
 				source := v.Args[1]
 				tSrc := source.Type
-				iAEATt := isAlreadyExpandedAggregateType(t)
+				iAEATt := x.isAlreadyExpandedAggregateType(t)
 
 				if !iAEATt {
 					// guarding against store immediate struct into interface data field -- store type is *uint8
 					// TODO can this happen recursively?
-					iAEATt = isAlreadyExpandedAggregateType(tSrc)
+					iAEATt = x.isAlreadyExpandedAggregateType(tSrc)
 					if iAEATt {
 						t = tSrc
 					}
 				}
-				if iAEATt {
-					if debug {
-						fmt.Printf("Splitting store %s\n", v.LongString())
-					}
-					dst, mem := v.Args[0], v.Args[2]
-					mem = storeArgOrLoad(v.Pos, b, dst, source, mem, t, 0)
-					v.copyOf(mem)
-				}
+				dst, mem := v.Args[0], v.Args[2]
+				mem = x.storeArgOrLoad(v.Pos, b, source, mem, t, 0, 0, registerCursor{storeDest: dst})
+				v.copyOf(mem)
 			}
 		}
 	}
@@ -752,15 +1304,15 @@
 			case OpStructSelect, OpArraySelect,
 				OpIData, OpITab,
 				OpStringPtr, OpStringLen,
-				OpSlicePtr, OpSliceLen, OpSliceCap,
+				OpSlicePtr, OpSliceLen, OpSliceCap, OpSlicePtrUnchecked,
 				OpComplexReal, OpComplexImag,
 				OpInt64Hi, OpInt64Lo:
 				w := v.Args[0]
 				switch w.Op {
 				case OpStructSelect, OpArraySelect, OpSelectN, OpArg:
 					val2Preds[w] += 1
-					if debug {
-						fmt.Printf("v2p[%s] = %d\n", w.LongString(), val2Preds[w])
+					if x.debug {
+						x.Printf("v2p[%s] = %d\n", w.LongString(), val2Preds[w])
 					}
 				}
 				fallthrough
@@ -768,19 +1320,19 @@
 			case OpSelectN:
 				if _, ok := val2Preds[v]; !ok {
 					val2Preds[v] = 0
-					if debug {
-						fmt.Printf("v2p[%s] = %d\n", v.LongString(), val2Preds[v])
+					if x.debug {
+						x.Printf("v2p[%s] = %d\n", v.LongString(), val2Preds[v])
 					}
 				}
 
 			case OpArg:
-				if !isAlreadyExpandedAggregateType(v.Type) {
+				if !x.isAlreadyExpandedAggregateType(v.Type) {
 					continue
 				}
 				if _, ok := val2Preds[v]; !ok {
 					val2Preds[v] = 0
-					if debug {
-						fmt.Printf("v2p[%s] = %d\n", v.LongString(), val2Preds[v])
+					if x.debug {
+						x.Printf("v2p[%s] = %d\n", v.LongString(), val2Preds[v])
 					}
 				}
 
@@ -790,7 +1342,7 @@
 				which := v.AuxInt
 				aux := call.Aux.(*AuxCall)
 				pt := v.Type
-				off := offsetFrom(sp, aux.OffsetOfResult(which), pt)
+				off := x.offsetFrom(x.f.Entry, x.sp, aux.OffsetOfResult(which), pt)
 				v.copyOf(off)
 			}
 		}
@@ -812,7 +1364,7 @@
 		if bi == bj {
 			return vi.ID < vj.ID
 		}
-		return sdom.domorder(bi) > sdom.domorder(bj) // reverse the order to put dominators last.
+		return x.sdom.domorder(bi) > x.sdom.domorder(bj) // reverse the order to put dominators last.
 	}
 
 	// Accumulate order in allOrdered
@@ -846,7 +1398,7 @@
 		}
 	}
 
-	common = make(map[selKey]*Value)
+	x.commonSelectors = make(map[selKey]*Value)
 	// Rewrite duplicate selectors as copies where possible.
 	for i := len(allOrdered) - 1; i >= 0; i-- {
 		v := allOrdered[i]
@@ -868,7 +1420,7 @@
 		offset := int64(0)
 		switch v.Op {
 		case OpStructSelect:
-			if w.Type.Etype == types.TSTRUCT {
+			if w.Type.Kind() == types.TSTRUCT {
 				offset = w.Type.FieldOff(int(v.AuxInt))
 			} else { // Immediate interface data artifact, offset is zero.
 				f.Fatalf("Expand calls interface data problem, func %s, v=%s, w=%s\n", f.Name, v.LongString(), w.LongString())
@@ -876,28 +1428,31 @@
 		case OpArraySelect:
 			offset = size * v.AuxInt
 		case OpSelectN:
-			offset = w.Aux.(*AuxCall).OffsetOfResult(v.AuxInt)
+			offset = v.AuxInt // offset is just a key, really.
 		case OpInt64Hi:
-			offset = hiOffset
+			offset = x.hiOffset
 		case OpInt64Lo:
-			offset = lowOffset
+			offset = x.lowOffset
 		case OpStringLen, OpSliceLen, OpIData:
-			offset = ptrSize
+			offset = x.ptrSize
 		case OpSliceCap:
-			offset = 2 * ptrSize
+			offset = 2 * x.ptrSize
 		case OpComplexImag:
 			offset = size
 		}
-		sk := selKey{from: w, size: size, offset: offset, typ: typ}
-		dupe := common[sk]
+		sk := selKey{from: w, size: size, offsetOrIndex: offset, typ: typ}
+		dupe := x.commonSelectors[sk]
 		if dupe == nil {
-			common[sk] = v
-		} else if sdom.IsAncestorEq(dupe.Block, v.Block) {
+			x.commonSelectors[sk] = v
+		} else if x.sdom.IsAncestorEq(dupe.Block, v.Block) {
+			if x.debug {
+				x.Printf("Duplicate, make %s copy of %s\n", v, dupe)
+			}
 			v.copyOf(dupe)
 		} else {
 			// Because values are processed in dominator order, the old common[s] will never dominate after a miss is seen.
 			// Installing the new value might match some future values.
-			common[sk] = v
+			x.commonSelectors[sk] = v
 		}
 	}
 
@@ -906,56 +1461,112 @@
 
 	// Rewrite selectors.
 	for i, v := range allOrdered {
-		if debug {
+		if x.debug {
 			b := v.Block
-			fmt.Printf("allOrdered[%d] = b%d, %s, uses=%d\n", i, b.ID, v.LongString(), v.Uses)
+			x.Printf("allOrdered[%d] = b%d, %s, uses=%d\n", i, b.ID, v.LongString(), v.Uses)
 		}
 		if v.Uses == 0 {
-			v.reset(OpInvalid)
+			v.invalidateRecursively()
 			continue
 		}
 		if v.Op == OpCopy {
 			continue
 		}
-		locs := rewriteSelect(v, v, 0)
+		locs := x.rewriteSelect(v, v, 0, 0)
 		// Install new names.
 		if v.Type.IsMemory() {
 			continue
 		}
 		// Leaf types may have debug locations
-		if !isAlreadyExpandedAggregateType(v.Type) {
+		if !x.isAlreadyExpandedAggregateType(v.Type) {
 			for _, l := range locs {
-				f.NamedValues[l] = append(f.NamedValues[l], v)
+				if _, ok := f.NamedValues[*l]; !ok {
+					f.Names = append(f.Names, l)
+				}
+				f.NamedValues[*l] = append(f.NamedValues[*l], v)
 			}
-			f.Names = append(f.Names, locs...)
 			continue
 		}
-		// Not-leaf types that had debug locations need to lose them.
-		if ns, ok := namedSelects[v]; ok {
+		if ns, ok := x.namedSelects[v]; ok {
+			// Not-leaf types that had debug locations need to lose them.
+
 			toDelete = append(toDelete, ns...)
 		}
 	}
 
 	deleteNamedVals(f, toDelete)
 
-	// Step 4: rewrite the calls themselves, correcting the type
+	// Step 4: rewrite the calls themselves, correcting the type.
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
 			switch v.Op {
+			case OpArg:
+				x.rewriteArgToMemOrRegs(v)
 			case OpStaticLECall:
 				v.Op = OpStaticCall
-				v.Type = types.TypeMem
+				rts := abi.RegisterTypes(v.Aux.(*AuxCall).abiInfo.OutParams())
+				v.Type = types.NewResults(append(rts, types.TypeMem))
 			case OpClosureLECall:
 				v.Op = OpClosureCall
-				v.Type = types.TypeMem
+				rts := abi.RegisterTypes(v.Aux.(*AuxCall).abiInfo.OutParams())
+				v.Type = types.NewResults(append(rts, types.TypeMem))
 			case OpInterLECall:
 				v.Op = OpInterCall
-				v.Type = types.TypeMem
+				rts := abi.RegisterTypes(v.Aux.(*AuxCall).abiInfo.OutParams())
+				v.Type = types.NewResults(append(rts, types.TypeMem))
 			}
 		}
 	}
 
-	// Step 5: elide any copies introduced.
+	// Step 5: dedup OpArgXXXReg values. Mostly it is already dedup'd by commonArgs,
+	// but there are cases that we have same OpArgXXXReg values with different types.
+	// E.g. string is sometimes decomposed as { *int8, int }, sometimes as { unsafe.Pointer, uintptr }.
+	// (Can we avoid that?)
+	var IArg, FArg [32]*Value
+	for _, v := range f.Entry.Values {
+		switch v.Op {
+		case OpArgIntReg:
+			i := v.AuxInt
+			if w := IArg[i]; w != nil {
+				if w.Type.Width != v.Type.Width {
+					f.Fatalf("incompatible OpArgIntReg [%d]: %s and %s", i, v.LongString(), w.LongString())
+				}
+				if w.Type.IsUnsafePtr() && !v.Type.IsUnsafePtr() {
+					// Update unsafe.Pointer type if we know the actual pointer type.
+					w.Type = v.Type
+				}
+				// TODO: don't dedup pointer and scalar? Rewrite to OpConvert? Can it happen?
+				v.copyOf(w)
+			} else {
+				IArg[i] = v
+			}
+		case OpArgFloatReg:
+			i := v.AuxInt
+			if w := FArg[i]; w != nil {
+				if w.Type.Width != v.Type.Width {
+					f.Fatalf("incompatible OpArgFloatReg [%d]: %v and %v", i, v, w)
+				}
+				v.copyOf(w)
+			} else {
+				FArg[i] = v
+			}
+		}
+	}
+
+	// Step 6: elide any copies introduced.
+	// Update named values.
+	for _, name := range f.Names {
+		values := f.NamedValues[*name]
+		for i, v := range values {
+			if v.Op == OpCopy {
+				a := v.Args[0]
+				for a.Op == OpCopy {
+					a = a.Args[0]
+				}
+				values[i] = a
+			}
+		}
+	}
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
 			for i, a := range v.Args {
@@ -966,10 +1577,163 @@
 				v.SetArg(i, aa)
 				for a.Uses == 0 {
 					b := a.Args[0]
-					a.reset(OpInvalid)
+					a.invalidateRecursively()
 					a = b
 				}
 			}
 		}
 	}
+
+	// Rewriting can attach lines to values that are unlikely to survive code generation, so move them to a use.
+	for _, b := range f.Blocks {
+		for _, v := range b.Values {
+			for _, a := range v.Args {
+				if a.Pos.IsStmt() != src.PosIsStmt {
+					continue
+				}
+				if a.Type.IsMemory() {
+					continue
+				}
+				if a.Pos.Line() != v.Pos.Line() {
+					continue
+				}
+				if !a.Pos.SameFile(v.Pos) {
+					continue
+				}
+				switch a.Op {
+				case OpArgIntReg, OpArgFloatReg, OpSelectN:
+					v.Pos = v.Pos.WithIsStmt()
+					a.Pos = a.Pos.WithDefaultStmt()
+				}
+			}
+		}
+	}
+}
+
+// rewriteArgToMemOrRegs converts OpArg v in-place into the register version of v,
+// if that is appropriate.
+func (x *expandState) rewriteArgToMemOrRegs(v *Value) *Value {
+	if x.debug {
+		x.indent(3)
+		defer x.indent(-3)
+		x.Printf("rewriteArgToMemOrRegs(%s)\n", v.LongString())
+	}
+	pa := x.prAssignForArg(v)
+	switch len(pa.Registers) {
+	case 0:
+		frameOff := v.Aux.(*ir.Name).FrameOffset()
+		if pa.Offset() != int32(frameOff+x.f.ABISelf.LocalsOffset()) {
+			panic(fmt.Errorf("Parameter assignment %d and OpArg.Aux frameOffset %d disagree, op=%s",
+				pa.Offset(), frameOff, v.LongString()))
+		}
+	case 1:
+		t := v.Type
+		key := selKey{v, 0, t.Width, t}
+		w := x.commonArgs[key]
+		if w != nil {
+			v.copyOf(w)
+			break
+		}
+		r := pa.Registers[0]
+		var i int64
+		v.Op, i = ArgOpAndRegisterFor(r, x.f.ABISelf)
+		v.Aux = &AuxNameOffset{v.Aux.(*ir.Name), 0}
+		v.AuxInt = i
+		x.commonArgs[key] = v
+
+	default:
+		panic(badVal("Saw unexpanded OpArg", v))
+	}
+	if x.debug {
+		x.Printf("-->%s\n", v.LongString())
+	}
+	return v
+}
+
+// newArgToMemOrRegs either rewrites toReplace into an OpArg referencing memory or into an OpArgXXXReg to a register,
+// or rewrites it into a copy of the appropriate OpArgXXX.  The actual OpArgXXX is determined by combining baseArg (an OpArg)
+// with offset, regOffset, and t to determine which portion of it to reference (either all or a part, in memory or in registers).
+func (x *expandState) newArgToMemOrRegs(baseArg, toReplace *Value, offset int64, regOffset Abi1RO, t *types.Type, pos src.XPos) *Value {
+	if x.debug {
+		x.indent(3)
+		defer x.indent(-3)
+		x.Printf("newArgToMemOrRegs(base=%s; toReplace=%s; t=%s; memOff=%d; regOff=%d)\n", baseArg.String(), toReplace.LongString(), t.String(), offset, regOffset)
+	}
+	key := selKey{baseArg, offset, t.Width, t}
+	w := x.commonArgs[key]
+	if w != nil {
+		if toReplace != nil {
+			toReplace.copyOf(w)
+		}
+		return w
+	}
+
+	pa := x.prAssignForArg(baseArg)
+	if len(pa.Registers) == 0 { // Arg is on stack
+		frameOff := baseArg.Aux.(*ir.Name).FrameOffset()
+		if pa.Offset() != int32(frameOff+x.f.ABISelf.LocalsOffset()) {
+			panic(fmt.Errorf("Parameter assignment %d and OpArg.Aux frameOffset %d disagree, op=%s",
+				pa.Offset(), frameOff, baseArg.LongString()))
+		}
+		aux := baseArg.Aux
+		auxInt := baseArg.AuxInt + offset
+		if toReplace != nil && toReplace.Block == baseArg.Block {
+			toReplace.reset(OpArg)
+			toReplace.Aux = aux
+			toReplace.AuxInt = auxInt
+			toReplace.Type = t
+			w = toReplace
+		} else {
+			w = baseArg.Block.NewValue0IA(pos, OpArg, t, auxInt, aux)
+		}
+		x.commonArgs[key] = w
+		if toReplace != nil {
+			toReplace.copyOf(w)
+		}
+		if x.debug {
+			x.Printf("-->%s\n", w.LongString())
+		}
+		return w
+	}
+	// Arg is in registers
+	r := pa.Registers[regOffset]
+	op, auxInt := ArgOpAndRegisterFor(r, x.f.ABISelf)
+	if op == OpArgIntReg && t.IsFloat() || op == OpArgFloatReg && t.IsInteger() {
+		fmt.Printf("pa=%v\nx.f.OwnAux.abiInfo=%s\n",
+			pa.ToString(x.f.ABISelf, true),
+			x.f.OwnAux.abiInfo.String())
+		panic(fmt.Errorf("Op/Type mismatch, op=%s, type=%s", op.String(), t.String()))
+	}
+	if baseArg.AuxInt != 0 {
+		base.Fatalf("BaseArg %s bound to registers has non-zero AuxInt", baseArg.LongString())
+	}
+	aux := &AuxNameOffset{baseArg.Aux.(*ir.Name), offset}
+	if toReplace != nil && toReplace.Block == baseArg.Block {
+		toReplace.reset(op)
+		toReplace.Aux = aux
+		toReplace.AuxInt = auxInt
+		toReplace.Type = t
+		w = toReplace
+	} else {
+		w = baseArg.Block.NewValue0IA(pos, op, t, auxInt, aux)
+	}
+	x.commonArgs[key] = w
+	if toReplace != nil {
+		toReplace.copyOf(w)
+	}
+	if x.debug {
+		x.Printf("-->%s\n", w.LongString())
+	}
+	return w
+
+}
+
+// argOpAndRegisterFor converts an abi register index into an ssa Op and corresponding
+// arg register index.
+func ArgOpAndRegisterFor(r abi.RegIndex, abiConfig *abi.ABIConfig) (Op, int64) {
+	i := abiConfig.FloatIndexFor(r)
+	if i >= 0 { // float PR
+		return OpArgFloatReg, i
+	}
+	return OpArgIntReg, int64(r)
 }
diff --git a/src/cmd/compile/internal/ssa/export_test.go b/src/cmd/compile/internal/ssa/export_test.go
index b4c3e5c..8ed8a0c 100644
--- a/src/cmd/compile/internal/ssa/export_test.go
+++ b/src/cmd/compile/internal/ssa/export_test.go
@@ -5,13 +5,13 @@
 package ssa
 
 import (
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/arm64"
 	"cmd/internal/obj/s390x"
 	"cmd/internal/obj/x86"
 	"cmd/internal/src"
-	"fmt"
 	"testing"
 )
 
@@ -36,10 +36,10 @@
 		tb.Fatalf("unknown arch %s", arch)
 	}
 	if ctxt.Arch.PtrSize != 8 {
-		tb.Fatal("dummyTypes is 64-bit only")
+		tb.Fatal("testTypes is 64-bit only")
 	}
 	c := &Conf{
-		config: NewConfig(arch, dummyTypes, ctxt, true),
+		config: NewConfig(arch, testTypes, ctxt, true),
 		tb:     tb,
 	}
 	return c
@@ -53,131 +53,64 @@
 
 func (c *Conf) Frontend() Frontend {
 	if c.fe == nil {
-		c.fe = DummyFrontend{t: c.tb, ctxt: c.config.ctxt}
+		c.fe = TestFrontend{t: c.tb, ctxt: c.config.ctxt}
 	}
 	return c.fe
 }
 
-// DummyFrontend is a test-only frontend.
+// TestFrontend is a test-only frontend.
 // It assumes 64 bit integers and pointers.
-type DummyFrontend struct {
+type TestFrontend struct {
 	t    testing.TB
 	ctxt *obj.Link
 }
 
-type DummyAuto struct {
-	t *types.Type
-	s string
-}
-
-func (d *DummyAuto) Typ() *types.Type {
-	return d.t
-}
-
-func (d *DummyAuto) String() string {
-	return d.s
-}
-
-func (d *DummyAuto) StorageClass() StorageClass {
-	return ClassAuto
-}
-
-func (d *DummyAuto) IsSynthetic() bool {
-	return false
-}
-
-func (d *DummyAuto) IsAutoTmp() bool {
-	return true
-}
-
-func (DummyFrontend) StringData(s string) *obj.LSym {
+func (TestFrontend) StringData(s string) *obj.LSym {
 	return nil
 }
-func (DummyFrontend) Auto(pos src.XPos, t *types.Type) GCNode {
-	return &DummyAuto{t: t, s: "aDummyAuto"}
+func (TestFrontend) Auto(pos src.XPos, t *types.Type) *ir.Name {
+	n := ir.NewNameAt(pos, &types.Sym{Name: "aFakeAuto"})
+	n.Class = ir.PAUTO
+	return n
 }
-func (d DummyFrontend) SplitString(s LocalSlot) (LocalSlot, LocalSlot) {
-	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{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{N: s.N, Type: s.Type.Elem().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{N: s.N, Type: dummyTypes.Float64, Off: s.Off}, LocalSlot{N: s.N, Type: dummyTypes.Float64, Off: s.Off + 8}
-	}
-	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{N: s.N, Type: dummyTypes.Int32, Off: s.Off + 4}, LocalSlot{N: s.N, Type: dummyTypes.UInt32, Off: 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{N: s.N, Type: s.Type.FieldType(i), Off: s.Off + s.Type.FieldOff(i)}
-}
-func (d DummyFrontend) SplitArray(s LocalSlot) LocalSlot {
-	return LocalSlot{N: s.N, Type: s.Type.Elem(), Off: s.Off}
-}
-
-func (d DummyFrontend) SplitSlot(parent *LocalSlot, suffix string, offset int64, t *types.Type) LocalSlot {
+func (d TestFrontend) SplitSlot(parent *LocalSlot, suffix string, offset int64, t *types.Type) LocalSlot {
 	return LocalSlot{N: parent.N, Type: t, Off: offset}
 }
-func (DummyFrontend) Line(_ src.XPos) string {
+func (TestFrontend) Line(_ src.XPos) string {
 	return "unknown.go:0"
 }
-func (DummyFrontend) AllocFrame(f *Func) {
+func (TestFrontend) AllocFrame(f *Func) {
 }
-func (d DummyFrontend) Syslook(s string) *obj.LSym {
+func (d TestFrontend) Syslook(s string) *obj.LSym {
 	return d.ctxt.Lookup(s)
 }
-func (DummyFrontend) UseWriteBarrier() bool {
+func (TestFrontend) UseWriteBarrier() bool {
 	return true // only writebarrier_test cares
 }
-func (DummyFrontend) SetWBPos(pos src.XPos) {
+func (TestFrontend) SetWBPos(pos src.XPos) {
 }
 
-func (d DummyFrontend) Logf(msg string, args ...interface{}) { d.t.Logf(msg, args...) }
-func (d DummyFrontend) Log() bool                            { return true }
+func (d TestFrontend) Logf(msg string, args ...interface{}) { d.t.Logf(msg, args...) }
+func (d TestFrontend) Log() bool                            { return true }
 
-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 TestFrontend) Fatalf(_ src.XPos, msg string, args ...interface{}) { d.t.Fatalf(msg, args...) }
+func (d TestFrontend) Warnl(_ src.XPos, msg string, args ...interface{})  { d.t.Logf(msg, args...) }
+func (d TestFrontend) Debug_checknil() bool                               { return false }
 
-func (d DummyFrontend) MyImportPath() string {
+func (d TestFrontend) MyImportPath() string {
 	return "my/import/path"
 }
 
-var dummyTypes Types
+var testTypes Types
 
 func init() {
 	// Initialize just enough of the universe and the types package to make our tests function.
 	// TODO(josharian): move universe initialization to the types package,
 	// so this test setup can share it.
 
-	types.Tconv = func(t *types.Type, flag, mode int) string {
-		return t.Etype.String()
-	}
-	types.Sconv = func(s *types.Sym, flag, mode int) string {
-		return "sym"
-	}
-	types.FormatSym = func(sym *types.Sym, s fmt.State, verb rune, mode int) {
-		fmt.Fprintf(s, "sym")
-	}
-	types.FormatType = func(t *types.Type, s fmt.State, verb rune, mode int) {
-		fmt.Fprintf(s, "%v", t.Etype)
-	}
-	types.Dowidth = func(t *types.Type) {}
-
 	for _, typ := range [...]struct {
 		width int64
-		et    types.EType
+		et    types.Kind
 	}{
 		{1, types.TINT8},
 		{1, types.TUINT8},
@@ -198,12 +131,12 @@
 		t.Align = uint8(typ.width)
 		types.Types[typ.et] = t
 	}
-	dummyTypes.SetTypPtrs()
+	testTypes.SetTypPtrs()
 }
 
-func (d DummyFrontend) DerefItab(sym *obj.LSym, off int64) *obj.LSym { return nil }
+func (d TestFrontend) DerefItab(sym *obj.LSym, off int64) *obj.LSym { return nil }
 
-func (d DummyFrontend) CanSSA(t *types.Type) bool {
-	// There are no un-SSAable types in dummy land.
+func (d TestFrontend) CanSSA(t *types.Type) bool {
+	// There are no un-SSAable types in test land.
 	return true
 }
diff --git a/src/cmd/compile/internal/ssa/flags_amd64_test.s b/src/cmd/compile/internal/ssa/flags_amd64_test.s
index 8bd8701..7402f6b 100644
--- a/src/cmd/compile/internal/ssa/flags_amd64_test.s
+++ b/src/cmd/compile/internal/ssa/flags_amd64_test.s
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build amd64
-
 #include "textflag.h"
 
 TEXT ·asmAddFlags(SB),NOSPLIT,$0-24
diff --git a/src/cmd/compile/internal/ssa/flags_arm64_test.s b/src/cmd/compile/internal/ssa/flags_arm64_test.s
index f201bcc..639d7e3 100644
--- a/src/cmd/compile/internal/ssa/flags_arm64_test.s
+++ b/src/cmd/compile/internal/ssa/flags_arm64_test.s
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build arm64
-
 #include "textflag.h"
 
 TEXT ·asmAddFlags(SB),NOSPLIT,$0-24
diff --git a/src/cmd/compile/internal/ssa/flags_test.go b/src/cmd/compile/internal/ssa/flags_test.go
index d64abf6..0bc1097 100644
--- a/src/cmd/compile/internal/ssa/flags_test.go
+++ b/src/cmd/compile/internal/ssa/flags_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 || arm64
 // +build amd64 arm64
 
 package ssa
diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go
index e6f899a..fac876c 100644
--- a/src/cmd/compile/internal/ssa/func.go
+++ b/src/cmd/compile/internal/ssa/func.go
@@ -5,6 +5,8 @@
 package ssa
 
 import (
+	"cmd/compile/internal/abi"
+	"cmd/compile/internal/base"
 	"cmd/compile/internal/types"
 	"cmd/internal/src"
 	"crypto/sha1"
@@ -43,6 +45,10 @@
 	DebugTest      bool           // default true unless $GOSSAHASH != ""; as a debugging aid, make new code conditional on this and use GOSSAHASH to binary search for failing cases
 	PrintOrHtmlSSA bool           // true if GOSSAFUNC matches, true even if fe.Log() (spew phase results to stdout) is false.
 	ruleMatches    map[string]int // number of times countRule was called during compilation for any given string
+	ABI0           *abi.ABIConfig // A copy, for no-sync access
+	ABI1           *abi.ABIConfig // A copy, for no-sync access
+	ABISelf        *abi.ABIConfig // ABI for function being compiled
+	ABIDefault     *abi.ABIConfig // ABI for rtcall and other no-parsed-signature/pragma functions.
 
 	scheduled   bool  // Values in Blocks are in final order
 	laidout     bool  // Blocks are ordered
@@ -56,7 +62,16 @@
 	NamedValues map[LocalSlot][]*Value
 	// Names is a copy of NamedValues.Keys. We keep a separate list
 	// of keys to make iteration order deterministic.
-	Names []LocalSlot
+	Names []*LocalSlot
+	// Canonicalize root/top-level local slots, and canonicalize their pieces.
+	// Because LocalSlot pieces refer to their parents with a pointer, this ensures that equivalent slots really are equal.
+	CanonicalLocalSlots  map[LocalSlot]*LocalSlot
+	CanonicalLocalSplits map[LocalSlotSplitKey]*LocalSlot
+
+	// RegArgs is a slice of register-memory pairs that must be spilled and unspilled in the uncommon path of function entry.
+	RegArgs []Spill
+	// AuxCall describing parameters and results for this function.
+	OwnAux *AuxCall
 
 	// WBLoads is a list of Blocks that branch on the write
 	// barrier flag. Safe-points are disabled from the OpLoad that
@@ -77,10 +92,16 @@
 	constants map[int64][]*Value // constants cache, keyed by constant value; users must check value's Op and Type
 }
 
+type LocalSlotSplitKey struct {
+	parent *LocalSlot
+	Off    int64       // offset of slot in N
+	Type   *types.Type // type of slot
+}
+
 // NewFunc returns a new, empty function object.
 // Caller must set f.Config and f.Cache before using f.
 func NewFunc(fe Frontend) *Func {
-	return &Func{fe: fe, NamedValues: make(map[LocalSlot][]*Value)}
+	return &Func{fe: fe, NamedValues: make(map[LocalSlot][]*Value), CanonicalLocalSlots: make(map[LocalSlot]*LocalSlot), CanonicalLocalSplits: make(map[LocalSlotSplitKey]*LocalSlot)}
 }
 
 // NumBlocks returns an integer larger than the id of any Block in the Func.
@@ -183,6 +204,101 @@
 	f.Cache.deadcode.liveOrderStmts = liveOrderStmts
 }
 
+func (f *Func) localSlotAddr(slot LocalSlot) *LocalSlot {
+	a, ok := f.CanonicalLocalSlots[slot]
+	if !ok {
+		a = new(LocalSlot)
+		*a = slot // don't escape slot
+		f.CanonicalLocalSlots[slot] = a
+	}
+	return a
+}
+
+func (f *Func) SplitString(name *LocalSlot) (*LocalSlot, *LocalSlot) {
+	ptrType := types.NewPtr(types.Types[types.TUINT8])
+	lenType := types.Types[types.TINT]
+	// Split this string up into two separate variables.
+	p := f.SplitSlot(name, ".ptr", 0, ptrType)
+	l := f.SplitSlot(name, ".len", ptrType.Size(), lenType)
+	return p, l
+}
+
+func (f *Func) SplitInterface(name *LocalSlot) (*LocalSlot, *LocalSlot) {
+	n := name.N
+	u := types.Types[types.TUINTPTR]
+	t := types.NewPtr(types.Types[types.TUINT8])
+	// Split this interface up into two separate variables.
+	sfx := ".itab"
+	if n.Type().IsEmptyInterface() {
+		sfx = ".type"
+	}
+	c := f.SplitSlot(name, sfx, 0, u) // see comment in typebits.Set
+	d := f.SplitSlot(name, ".data", u.Size(), t)
+	return c, d
+}
+
+func (f *Func) SplitSlice(name *LocalSlot) (*LocalSlot, *LocalSlot, *LocalSlot) {
+	ptrType := types.NewPtr(name.Type.Elem())
+	lenType := types.Types[types.TINT]
+	p := f.SplitSlot(name, ".ptr", 0, ptrType)
+	l := f.SplitSlot(name, ".len", ptrType.Size(), lenType)
+	c := f.SplitSlot(name, ".cap", ptrType.Size()+lenType.Size(), lenType)
+	return p, l, c
+}
+
+func (f *Func) SplitComplex(name *LocalSlot) (*LocalSlot, *LocalSlot) {
+	s := name.Type.Size() / 2
+	var t *types.Type
+	if s == 8 {
+		t = types.Types[types.TFLOAT64]
+	} else {
+		t = types.Types[types.TFLOAT32]
+	}
+	r := f.SplitSlot(name, ".real", 0, t)
+	i := f.SplitSlot(name, ".imag", t.Size(), t)
+	return r, i
+}
+
+func (f *Func) SplitInt64(name *LocalSlot) (*LocalSlot, *LocalSlot) {
+	var t *types.Type
+	if name.Type.IsSigned() {
+		t = types.Types[types.TINT32]
+	} else {
+		t = types.Types[types.TUINT32]
+	}
+	if f.Config.BigEndian {
+		return f.SplitSlot(name, ".hi", 0, t), f.SplitSlot(name, ".lo", t.Size(), types.Types[types.TUINT32])
+	}
+	return f.SplitSlot(name, ".hi", t.Size(), t), f.SplitSlot(name, ".lo", 0, types.Types[types.TUINT32])
+}
+
+func (f *Func) SplitStruct(name *LocalSlot, i int) *LocalSlot {
+	st := name.Type
+	return f.SplitSlot(name, st.FieldName(i), st.FieldOff(i), st.FieldType(i))
+}
+func (f *Func) SplitArray(name *LocalSlot) *LocalSlot {
+	n := name.N
+	at := name.Type
+	if at.NumElem() != 1 {
+		base.FatalfAt(n.Pos(), "bad array size")
+	}
+	et := at.Elem()
+	return f.SplitSlot(name, "[0]", 0, et)
+}
+
+func (f *Func) SplitSlot(name *LocalSlot, sfx string, offset int64, t *types.Type) *LocalSlot {
+	lssk := LocalSlotSplitKey{name, offset, t}
+	if als, ok := f.CanonicalLocalSplits[lssk]; ok {
+		return als
+	}
+	// Note: the _ field may appear several times.  But
+	// have no fear, identically-named but distinct Autos are
+	// ok, albeit maybe confusing for a debugger.
+	ls := f.fe.SplitSlot(name, sfx, offset, t)
+	f.CanonicalLocalSplits[lssk] = &ls
+	return &ls
+}
+
 // newValue allocates a new Value with the given fields and places it at the end of b.Values.
 func (f *Func) newValue(op Op, t *types.Type, b *Block, pos src.XPos) *Value {
 	var v *Value
@@ -377,13 +493,7 @@
 }
 
 // NewValue returns a new value in the block with no arguments and an aux value.
-func (b *Block) NewValue0A(pos src.XPos, op Op, t *types.Type, aux interface{}) *Value {
-	if _, ok := aux.(int64); ok {
-		// Disallow int64 aux values. They should be in the auxint field instead.
-		// Maybe we want to allow this at some point, but for now we disallow it
-		// to prevent errors like using NewValue1A instead of NewValue1I.
-		b.Fatalf("aux field has int64 type op=%s type=%s aux=%v", op, t, aux)
-	}
+func (b *Block) NewValue0A(pos src.XPos, op Op, t *types.Type, aux Aux) *Value {
 	v := b.Func.newValue(op, t, b, pos)
 	v.AuxInt = 0
 	v.Aux = aux
@@ -392,7 +502,7 @@
 }
 
 // NewValue returns a new value in the block with no arguments and both an auxint and aux values.
-func (b *Block) NewValue0IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux interface{}) *Value {
+func (b *Block) NewValue0IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux Aux) *Value {
 	v := b.Func.newValue(op, t, b, pos)
 	v.AuxInt = auxint
 	v.Aux = aux
@@ -421,7 +531,7 @@
 }
 
 // NewValue1A returns a new value in the block with one argument and an aux value.
-func (b *Block) NewValue1A(pos src.XPos, op Op, t *types.Type, aux interface{}, arg *Value) *Value {
+func (b *Block) NewValue1A(pos src.XPos, op Op, t *types.Type, aux Aux, arg *Value) *Value {
 	v := b.Func.newValue(op, t, b, pos)
 	v.AuxInt = 0
 	v.Aux = aux
@@ -432,7 +542,7 @@
 }
 
 // NewValue1IA returns a new value in the block with one argument and both an auxint and aux values.
-func (b *Block) NewValue1IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux interface{}, arg *Value) *Value {
+func (b *Block) NewValue1IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux Aux, arg *Value) *Value {
 	v := b.Func.newValue(op, t, b, pos)
 	v.AuxInt = auxint
 	v.Aux = aux
@@ -455,7 +565,7 @@
 }
 
 // NewValue2A returns a new value in the block with two arguments and one aux values.
-func (b *Block) NewValue2A(pos src.XPos, op Op, t *types.Type, aux interface{}, arg0, arg1 *Value) *Value {
+func (b *Block) NewValue2A(pos src.XPos, op Op, t *types.Type, aux Aux, arg0, arg1 *Value) *Value {
 	v := b.Func.newValue(op, t, b, pos)
 	v.AuxInt = 0
 	v.Aux = aux
@@ -480,7 +590,7 @@
 }
 
 // NewValue2IA returns a new value in the block with two arguments and both an auxint and aux values.
-func (b *Block) NewValue2IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux interface{}, arg0, arg1 *Value) *Value {
+func (b *Block) NewValue2IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux Aux, arg0, arg1 *Value) *Value {
 	v := b.Func.newValue(op, t, b, pos)
 	v.AuxInt = auxint
 	v.Aux = aux
@@ -521,7 +631,7 @@
 }
 
 // NewValue3A returns a new value in the block with three argument and an aux value.
-func (b *Block) NewValue3A(pos src.XPos, op Op, t *types.Type, aux interface{}, arg0, arg1, arg2 *Value) *Value {
+func (b *Block) NewValue3A(pos src.XPos, op Op, t *types.Type, aux Aux, arg0, arg1, arg2 *Value) *Value {
 	v := b.Func.newValue(op, t, b, pos)
 	v.AuxInt = 0
 	v.Aux = aux
@@ -547,7 +657,7 @@
 	return v
 }
 
-// NewValue4I returns a new value in the block with four arguments and and auxint value.
+// NewValue4I returns a new value in the block with four arguments and auxint value.
 func (b *Block) NewValue4I(pos src.XPos, op Op, t *types.Type, auxint int64, arg0, arg1, arg2, arg3 *Value) *Value {
 	v := b.Func.newValue(op, t, b, pos)
 	v.AuxInt = auxint
@@ -633,7 +743,7 @@
 }
 func (f *Func) ConstEmptyString(t *types.Type) *Value {
 	v := f.constVal(OpConstString, t, constEmptyStringMagic, false)
-	v.Aux = ""
+	v.Aux = StringToAux("")
 	return v
 }
 func (f *Func) ConstOffPtrSP(t *types.Type, c int64, sp *Value) *Value {
@@ -649,7 +759,19 @@
 func (f *Func) Warnl(pos src.XPos, msg string, args ...interface{}) { f.fe.Warnl(pos, msg, args...) }
 func (f *Func) Logf(msg string, args ...interface{})                { f.fe.Logf(msg, args...) }
 func (f *Func) Log() bool                                           { return f.fe.Log() }
-func (f *Func) Fatalf(msg string, args ...interface{})              { f.fe.Fatalf(f.Entry.Pos, msg, args...) }
+
+func (f *Func) Fatalf(msg string, args ...interface{}) {
+	stats := "crashed"
+	if f.Log() {
+		f.Logf("  pass %s end %s\n", f.pass.name, stats)
+		printFunc(f)
+	}
+	if f.HTMLWriter != nil {
+		f.HTMLWriter.WritePhase(f.pass.name, fmt.Sprintf("%s <span class=\"stats\">%s</span>", f.pass.name, stats))
+		f.HTMLWriter.flushPhases()
+	}
+	f.fe.Fatalf(f.Entry.Pos, msg, args...)
+}
 
 // postorder returns the reachable blocks in f in a postorder traversal.
 func (f *Func) postorder() []*Block {
@@ -777,7 +899,7 @@
 }
 
 func (f *Func) spSb() (sp, sb *Value) {
-	initpos := f.Entry.Pos
+	initpos := src.NoXPos // These are originally created with no position in ssa.go; if they are optimized out then recreated, should be the same.
 	for _, v := range f.Entry.Values {
 		if v.Op == OpSB {
 			sb = v
@@ -786,7 +908,7 @@
 			sp = v
 		}
 		if sb != nil && sp != nil {
-			break
+			return
 		}
 	}
 	if sb == nil {
diff --git a/src/cmd/compile/internal/ssa/func_test.go b/src/cmd/compile/internal/ssa/func_test.go
index 568c643..276c444 100644
--- a/src/cmd/compile/internal/ssa/func_test.go
+++ b/src/cmd/compile/internal/ssa/func_test.go
@@ -232,7 +232,7 @@
 }
 
 // Valu defines a value in a block.
-func Valu(name string, op Op, t *types.Type, auxint int64, aux interface{}, args ...string) valu {
+func Valu(name string, op Op, t *types.Type, auxint int64, aux Aux, args ...string) valu {
 	return valu{name, op, t, auxint, aux, args}
 }
 
@@ -277,7 +277,7 @@
 	op     Op
 	t      *types.Type
 	auxint int64
-	aux    interface{}
+	aux    Aux
 	args   []string
 }
 
@@ -402,12 +402,12 @@
 			cfg.Fun("entry",
 				Bloc("entry",
 					Valu("mem", OpInitMem, types.TypeMem, 0, nil),
-					Valu("a", OpConst64, cfg.config.Types.Int64, 0, 14),
+					Valu("a", OpConstString, cfg.config.Types.String, 0, StringToAux("foo")),
 					Exit("mem"))),
 			cfg.Fun("entry",
 				Bloc("entry",
 					Valu("mem", OpInitMem, types.TypeMem, 0, nil),
-					Valu("a", OpConst64, cfg.config.Types.Int64, 0, 26),
+					Valu("a", OpConstString, cfg.config.Types.String, 0, StringToAux("bar")),
 					Exit("mem"))),
 		},
 		// value args different
diff --git a/src/cmd/compile/internal/ssa/fuse.go b/src/cmd/compile/internal/ssa/fuse.go
index c51461c..fec2ba8 100644
--- a/src/cmd/compile/internal/ssa/fuse.go
+++ b/src/cmd/compile/internal/ssa/fuse.go
@@ -11,8 +11,8 @@
 // fuseEarly runs fuse(f, fuseTypePlain|fuseTypeIntInRange).
 func fuseEarly(f *Func) { fuse(f, fuseTypePlain|fuseTypeIntInRange) }
 
-// fuseLate runs fuse(f, fuseTypePlain|fuseTypeIf).
-func fuseLate(f *Func) { fuse(f, fuseTypePlain|fuseTypeIf) }
+// fuseLate runs fuse(f, fuseTypePlain|fuseTypeIf|fuseTypeBranchRedirect).
+func fuseLate(f *Func) { fuse(f, fuseTypePlain|fuseTypeIf|fuseTypeBranchRedirect) }
 
 type fuseType uint8
 
@@ -20,6 +20,7 @@
 	fuseTypePlain fuseType = 1 << iota
 	fuseTypeIf
 	fuseTypeIntInRange
+	fuseTypeBranchRedirect
 	fuseTypeShortCircuit
 )
 
@@ -43,6 +44,9 @@
 				changed = shortcircuitBlock(b) || changed
 			}
 		}
+		if typ&fuseTypeBranchRedirect != 0 {
+			changed = fuseBranchRedirect(f) || changed
+		}
 		if changed {
 			f.invalidateCFG()
 		}
@@ -51,11 +55,11 @@
 
 // fuseBlockIf handles the following cases where s0 and s1 are empty blocks.
 //
-//   b        b        b      b
-//  / \      | \      / |    | |
-// s0  s1    |  s1   s0 |    | |
-//  \ /      | /      \ |    | |
-//   ss      ss        ss     ss
+//       b        b           b       b
+//    \ / \ /    | \  /    \ / |     | |
+//     s0  s1    |  s1      s0 |     | |
+//      \ /      | /         \ |     | |
+//       ss      ss           ss      ss
 //
 // If all Phi ops in ss have identical variables for slots corresponding to
 // s0, s1 and b then the branch can be dropped.
@@ -69,11 +73,11 @@
 	if b.Kind != BlockIf {
 		return false
 	}
-
+	// It doesn't matter how much Preds does s0 or s1 have.
 	var ss0, ss1 *Block
 	s0 := b.Succs[0].b
 	i0 := b.Succs[0].i
-	if s0.Kind != BlockPlain || len(s0.Preds) != 1 || !isEmpty(s0) {
+	if s0.Kind != BlockPlain || !isEmpty(s0) {
 		s0, ss0 = b, s0
 	} else {
 		ss0 = s0.Succs[0].b
@@ -81,15 +85,25 @@
 	}
 	s1 := b.Succs[1].b
 	i1 := b.Succs[1].i
-	if s1.Kind != BlockPlain || len(s1.Preds) != 1 || !isEmpty(s1) {
+	if s1.Kind != BlockPlain || !isEmpty(s1) {
 		s1, ss1 = b, s1
 	} else {
 		ss1 = s1.Succs[0].b
 		i1 = s1.Succs[0].i
 	}
-
 	if ss0 != ss1 {
-		return false
+		if s0.Kind == BlockPlain && isEmpty(s0) && s1.Kind == BlockPlain && isEmpty(s1) {
+			// Two special cases where both s0, s1 and ss are empty blocks.
+			if s0 == ss1 {
+				s0, ss0 = b, ss1
+			} else if ss0 == s1 {
+				s1, ss1 = b, ss0
+			} else {
+				return false
+			}
+		} else {
+			return false
+		}
 	}
 	ss := ss0
 
@@ -102,48 +116,45 @@
 		}
 	}
 
-	// Now we have two of following b->ss, b->s0->ss and b->s1->ss,
-	// with s0 and s1 empty if exist.
-	// We can replace it with b->ss without if all OpPhis in ss
-	// have identical predecessors (verified above).
-	// No critical edge is introduced because b will have one successor.
-	if s0 != b && s1 != b {
-		// Replace edge b->s0->ss with b->ss.
-		// We need to keep a slot for Phis corresponding to b.
-		b.Succs[0] = Edge{ss, i0}
-		ss.Preds[i0] = Edge{b, 0}
-		b.removeEdge(1)
-		s1.removeEdge(0)
-	} else if s0 != b {
-		b.removeEdge(0)
+	// We do not need to redirect the Preds of s0 and s1 to ss,
+	// the following optimization will do this.
+	b.removeEdge(0)
+	if s0 != b && len(s0.Preds) == 0 {
 		s0.removeEdge(0)
-	} else if s1 != b {
-		b.removeEdge(1)
-		s1.removeEdge(0)
-	} else {
-		b.removeEdge(1)
+		// Move any (dead) values in s0 to b,
+		// where they will be eliminated by the next deadcode pass.
+		for _, v := range s0.Values {
+			v.Block = b
+		}
+		b.Values = append(b.Values, s0.Values...)
+		// Clear s0.
+		s0.Kind = BlockInvalid
+		s0.Values = nil
+		s0.Succs = nil
+		s0.Preds = nil
 	}
+
 	b.Kind = BlockPlain
 	b.Likely = BranchUnknown
 	b.ResetControls()
-
-	// Trash the empty blocks s0 and s1.
-	blocks := [...]*Block{s0, s1}
-	for _, s := range &blocks {
-		if s == b {
-			continue
+	// The values in b may be dead codes, and clearing them in time may
+	// obtain new optimization opportunities.
+	// First put dead values that can be deleted into a slice walkValues.
+	// Then put their arguments in walkValues before resetting the dead values
+	// in walkValues, because the arguments may also become dead values.
+	walkValues := []*Value{}
+	for _, v := range b.Values {
+		if v.Uses == 0 && v.removeable() {
+			walkValues = append(walkValues, v)
 		}
-		// Move any (dead) values in s0 or s1 to b,
-		// where they will be eliminated by the next deadcode pass.
-		for _, v := range s.Values {
-			v.Block = b
+	}
+	for len(walkValues) != 0 {
+		v := walkValues[len(walkValues)-1]
+		walkValues = walkValues[:len(walkValues)-1]
+		if v.Uses == 0 && v.removeable() {
+			walkValues = append(walkValues, v.Args...)
+			v.reset(OpInvalid)
 		}
-		b.Values = append(b.Values, s.Values...)
-		// Clear s.
-		s.Kind = BlockInvalid
-		s.Values = nil
-		s.Succs = nil
-		s.Preds = nil
 	}
 	return true
 }
diff --git a/src/cmd/compile/internal/ssa/fuse_branchredirect.go b/src/cmd/compile/internal/ssa/fuse_branchredirect.go
new file mode 100644
index 0000000..1b8b307
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/fuse_branchredirect.go
@@ -0,0 +1,110 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// fuseBranchRedirect checks for a CFG in which the outbound branch
+// of an If block can be derived from its predecessor If block, in
+// some such cases, we can redirect the predecessor If block to the
+// corresponding successor block directly. For example:
+// p:
+//   v11 = Less64 <bool> v10 v8
+//   If v11 goto b else u
+// b: <- p ...
+//   v17 = Leq64 <bool> v10 v8
+//   If v17 goto s else o
+// We can redirect p to s directly.
+//
+// The implementation here borrows the framework of the prove pass.
+// 1, Traverse all blocks of function f to find If blocks.
+// 2,   For any If block b, traverse all its predecessors to find If blocks.
+// 3,     For any If block predecessor p, update relationship p->b.
+// 4,     Traverse all successors of b.
+// 5,       For any successor s of b, try to update relationship b->s, if a
+//          contradiction is found then redirect p to another successor of b.
+func fuseBranchRedirect(f *Func) bool {
+	ft := newFactsTable(f)
+	ft.checkpoint()
+
+	changed := false
+	for i := len(f.Blocks) - 1; i >= 0; i-- {
+		b := f.Blocks[i]
+		if b.Kind != BlockIf {
+			continue
+		}
+		// b is either empty or only contains the control value.
+		// TODO: if b contains only OpCopy or OpNot related to b.Controls,
+		// such as Copy(Not(Copy(Less64(v1, v2)))), perhaps it can be optimized.
+		bCtl := b.Controls[0]
+		if bCtl.Block != b && len(b.Values) != 0 || (len(b.Values) != 1 || bCtl.Uses != 1) && bCtl.Block == b {
+			continue
+		}
+
+		for k := 0; k < len(b.Preds); k++ {
+			pk := b.Preds[k]
+			p := pk.b
+			if p.Kind != BlockIf || p == b {
+				continue
+			}
+			pbranch := positive
+			if pk.i == 1 {
+				pbranch = negative
+			}
+			ft.checkpoint()
+			// Assume branch p->b is taken.
+			addBranchRestrictions(ft, p, pbranch)
+			// Check if any outgoing branch is unreachable based on the above condition.
+			parent := b
+			for j, bbranch := range [...]branch{positive, negative} {
+				ft.checkpoint()
+				// Try to update relationship b->child, and check if the contradiction occurs.
+				addBranchRestrictions(ft, parent, bbranch)
+				unsat := ft.unsat
+				ft.restore()
+				if !unsat {
+					continue
+				}
+				// This branch is impossible,so redirect p directly to another branch.
+				out := 1 ^ j
+				child := parent.Succs[out].b
+				if child == b {
+					continue
+				}
+				b.removePred(k)
+				p.Succs[pk.i] = Edge{child, len(child.Preds)}
+				// Fix up Phi value in b to have one less argument.
+				for _, v := range b.Values {
+					if v.Op != OpPhi {
+						continue
+					}
+					v.RemoveArg(k)
+					phielimValue(v)
+				}
+				// Fix up child to have one more predecessor.
+				child.Preds = append(child.Preds, Edge{p, pk.i})
+				ai := b.Succs[out].i
+				for _, v := range child.Values {
+					if v.Op != OpPhi {
+						continue
+					}
+					v.AddArg(v.Args[ai])
+				}
+				if b.Func.pass.debug > 0 {
+					b.Func.Warnl(b.Controls[0].Pos, "Redirect %s based on %s", b.Controls[0].Op, p.Controls[0].Op)
+				}
+				changed = true
+				k--
+				break
+			}
+			ft.restore()
+		}
+		if len(b.Preds) == 0 && b != f.Entry {
+			// Block is now dead.
+			b.Kind = BlockInvalid
+		}
+	}
+	ft.restore()
+	ft.cleanup(f)
+	return changed
+}
diff --git a/src/cmd/compile/internal/ssa/fuse_test.go b/src/cmd/compile/internal/ssa/fuse_test.go
index 1519099..27a14b1 100644
--- a/src/cmd/compile/internal/ssa/fuse_test.go
+++ b/src/cmd/compile/internal/ssa/fuse_test.go
@@ -104,6 +104,18 @@
 
 func TestFuseEliminatesEmptyBlocks(t *testing.T) {
 	c := testConfig(t)
+	// Case 1, plain type empty blocks z0 ~ z3 will be eliminated.
+	//     entry
+	//       |
+	//      z0
+	//       |
+	//      z1
+	//       |
+	//      z2
+	//       |
+	//      z3
+	//       |
+	//     exit
 	fun := c.Fun("entry",
 		Bloc("entry",
 			Valu("mem", OpInitMem, types.TypeMem, 0, nil),
@@ -126,16 +138,77 @@
 
 	for k, b := range fun.blocks {
 		if k[:1] == "z" && b.Kind != BlockInvalid {
-			t.Errorf("%s was not eliminated, but should have", k)
+			t.Errorf("case1 %s was not eliminated, but should have", k)
+		}
+	}
+
+	// Case 2, empty blocks with If branch, z0 and z1 will be eliminated.
+	//     entry
+	//     /  \
+	//    z0  z1
+	//     \  /
+	//     exit
+	fun = c.Fun("entry",
+		Bloc("entry",
+			Valu("mem", OpInitMem, types.TypeMem, 0, nil),
+			Valu("c", OpArg, c.config.Types.Bool, 0, nil),
+			If("c", "z0", "z1")),
+		Bloc("z0",
+			Goto("exit")),
+		Bloc("z1",
+			Goto("exit")),
+		Bloc("exit",
+			Exit("mem"),
+		))
+
+	CheckFunc(fun.f)
+	fuseLate(fun.f)
+
+	for k, b := range fun.blocks {
+		if k[:1] == "z" && b.Kind != BlockInvalid {
+			t.Errorf("case2 %s was not eliminated, but should have", k)
+		}
+	}
+
+	// Case 3, empty blocks with multiple predecessors, z0 and z1 will be eliminated.
+	//     entry
+	//      |  \
+	//      |  b0
+	//      | /  \
+	//      z0   z1
+	//       \   /
+	//       exit
+	fun = c.Fun("entry",
+		Bloc("entry",
+			Valu("mem", OpInitMem, types.TypeMem, 0, nil),
+			Valu("c1", OpArg, c.config.Types.Bool, 0, nil),
+			If("c1", "b0", "z0")),
+		Bloc("b0",
+			Valu("c2", OpArg, c.config.Types.Bool, 0, nil),
+			If("c2", "z1", "z0")),
+		Bloc("z0",
+			Goto("exit")),
+		Bloc("z1",
+			Goto("exit")),
+		Bloc("exit",
+			Exit("mem"),
+		))
+
+	CheckFunc(fun.f)
+	fuseLate(fun.f)
+
+	for k, b := range fun.blocks {
+		if k[:1] == "z" && b.Kind != BlockInvalid {
+			t.Errorf("case3 %s was not eliminated, but should have", k)
 		}
 	}
 }
 
 func TestFuseSideEffects(t *testing.T) {
-	// Test that we don't fuse branches that have side effects but
+	c := testConfig(t)
+	// Case1, test that we don't fuse branches that have side effects but
 	// have no use (e.g. followed by infinite loop).
 	// See issue #36005.
-	c := testConfig(t)
 	fun := c.Fun("entry",
 		Bloc("entry",
 			Valu("mem", OpInitMem, types.TypeMem, 0, nil),
@@ -163,6 +236,31 @@
 			t.Errorf("else is eliminated, but should not")
 		}
 	}
+
+	// Case2, z0 contains a value that has side effect, z0 shouldn't be eliminated.
+	//     entry
+	//      | \
+	//      |  z0
+	//      | /
+	//     exit
+	fun = c.Fun("entry",
+		Bloc("entry",
+			Valu("mem", OpInitMem, types.TypeMem, 0, nil),
+			Valu("c1", OpArg, c.config.Types.Bool, 0, nil),
+			Valu("p", OpArg, c.config.Types.IntPtr, 0, nil),
+			If("c1", "z0", "exit")),
+		Bloc("z0",
+			Valu("nilcheck", OpNilCheck, types.TypeVoid, 0, nil, "p", "mem"),
+			Goto("exit")),
+		Bloc("exit",
+			Exit("mem"),
+		))
+	CheckFunc(fun.f)
+	fuseLate(fun.f)
+	z0, ok := fun.blocks["z0"]
+	if !ok || z0.Kind == BlockInvalid {
+		t.Errorf("case2 z0 is eliminated, but should not")
+	}
 }
 
 func BenchmarkFuse(b *testing.B) {
diff --git a/src/cmd/compile/internal/ssa/gen/386.rules b/src/cmd/compile/internal/ssa/gen/386.rules
index fbc12fd..199b73c 100644
--- a/src/cmd/compile/internal/ssa/gen/386.rules
+++ b/src/cmd/compile/internal/ssa/gen/386.rules
@@ -54,6 +54,7 @@
 (Bswap32 ...) => (BSWAPL ...)
 
 (Sqrt ...) => (SQRTSD ...)
+(Sqrt32 ...) => (SQRTSS ...)
 
 (Ctz16 x) => (BSFL (ORLconst <typ.UInt32> [0x10000] x))
 (Ctz16NonZero ...) => (BSFL ...)
@@ -257,17 +258,17 @@
 (Zero [4] destptr mem) => (MOVLstoreconst [0] destptr mem)
 
 (Zero [3] destptr mem) =>
-	(MOVBstoreconst [makeValAndOff32(0,2)] destptr
-		(MOVWstoreconst [makeValAndOff32(0,0)] destptr mem))
+	(MOVBstoreconst [makeValAndOff(0,2)] destptr
+		(MOVWstoreconst [makeValAndOff(0,0)] destptr mem))
 (Zero [5] destptr mem) =>
-	(MOVBstoreconst [makeValAndOff32(0,4)] destptr
-		(MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	(MOVBstoreconst [makeValAndOff(0,4)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 (Zero [6] destptr mem) =>
-	(MOVWstoreconst [makeValAndOff32(0,4)] destptr
-		(MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	(MOVWstoreconst [makeValAndOff(0,4)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 (Zero [7] destptr mem) =>
-	(MOVLstoreconst [makeValAndOff32(0,3)] destptr
-		(MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	(MOVLstoreconst [makeValAndOff(0,3)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 
 // Strip off any fractional word zeroing.
 (Zero [s] destptr mem) && s%4 != 0 && s > 4 =>
@@ -276,17 +277,17 @@
 
 // Zero small numbers of words directly.
 (Zero [8] destptr mem) =>
-	(MOVLstoreconst [makeValAndOff32(0,4)] destptr
-		(MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	(MOVLstoreconst [makeValAndOff(0,4)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 (Zero [12] destptr mem) =>
-	(MOVLstoreconst [makeValAndOff32(0,8)] destptr
-		(MOVLstoreconst [makeValAndOff32(0,4)] destptr
-			(MOVLstoreconst [makeValAndOff32(0,0)] destptr mem)))
+	(MOVLstoreconst [makeValAndOff(0,8)] destptr
+		(MOVLstoreconst [makeValAndOff(0,4)] destptr
+			(MOVLstoreconst [makeValAndOff(0,0)] destptr mem)))
 (Zero [16] destptr mem) =>
-	(MOVLstoreconst [makeValAndOff32(0,12)] destptr
-		(MOVLstoreconst [makeValAndOff32(0,8)] destptr
-			(MOVLstoreconst [makeValAndOff32(0,4)] destptr
-				(MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))))
+	(MOVLstoreconst [makeValAndOff(0,12)] destptr
+		(MOVLstoreconst [makeValAndOff(0,8)] destptr
+			(MOVLstoreconst [makeValAndOff(0,4)] destptr
+				(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))))
 
 // Medium zeroing uses a duff device.
 (Zero [s] destptr mem)
@@ -475,7 +476,7 @@
 (CMPB (MOVLconst [c]) x) => (InvertFlags (CMPBconst x [int8(c)]))
 
 // Canonicalize the order of arguments to comparisons - helps with CSE.
-(CMP(L|W|B) x y) && x.ID > y.ID => (InvertFlags (CMP(L|W|B) y x))
+(CMP(L|W|B) x y) && canonLessThan(x,y) => (InvertFlags (CMP(L|W|B) y x))
 
 // strength reduction
 // Assumes that the following costs from https://gmplib.org/~tege/x86-timing.pdf:
@@ -620,12 +621,12 @@
 	((ADD|AND|OR|XOR)Lconstmodify [valoff1.addOffset32(off2)] {sym} base mem)
 
 // Fold constants into stores.
-(MOVLstore [off] {sym} ptr (MOVLconst [c]) mem) && validOff(int64(off)) =>
-	(MOVLstoreconst [makeValAndOff32(c,off)] {sym} ptr mem)
-(MOVWstore [off] {sym} ptr (MOVLconst [c]) mem) && validOff(int64(off)) =>
-	(MOVWstoreconst [makeValAndOff32(c,off)] {sym} ptr mem)
-(MOVBstore [off] {sym} ptr (MOVLconst [c]) mem) && validOff(int64(off)) =>
-	(MOVBstoreconst [makeValAndOff32(c,off)] {sym} ptr mem)
+(MOVLstore [off] {sym} ptr (MOVLconst [c]) mem) =>
+	(MOVLstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
+(MOVWstore [off] {sym} ptr (MOVLconst [c]) mem) =>
+	(MOVWstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
+(MOVBstore [off] {sym} ptr (MOVLconst [c]) mem) =>
+	(MOVBstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
 
 // Fold address offsets into constant stores.
 (MOV(L|W|B)storeconst [sc] {s} (ADDLconst [off] ptr) mem) && sc.canAdd32(off) =>
@@ -675,8 +676,8 @@
 (MOVLstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR)L l:(MOVLload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) =>
 	((ADD|SUB|AND|OR|XOR)Lmodify [off] {sym} ptr x mem)
 (MOVLstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Lconst [c] l:(MOVLload [off] {sym} ptr mem)) mem)
-	&& y.Uses==1 && l.Uses==1 && clobber(y, l) && validValAndOff(int64(c),int64(off)) =>
-	((ADD|AND|OR|XOR)Lconstmodify [makeValAndOff32(c,off)] {sym} ptr mem)
+	&& y.Uses==1 && l.Uses==1 && clobber(y, l) =>
+	((ADD|AND|OR|XOR)Lconstmodify [makeValAndOff(c,off)] {sym} ptr mem)
 
 // fold LEALs together
 (LEAL [off1] {sym1} (LEAL [off2] {sym2} x)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
@@ -994,49 +995,49 @@
   && x.Uses == 1
   && a.Off() + 1 == c.Off()
   && clobber(x)
-  => (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p mem)
+  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
 (MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem))
   && x.Uses == 1
   && a.Off() + 1 == c.Off()
   && clobber(x)
-  => (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p mem)
+  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
 
 (MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem))
   && x.Uses == 1
   && a.Off() == c.Off()
   && sequentialAddresses(p0, p1, 1)
   && clobber(x)
-  => (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p0 mem)
+  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
 (MOVBstoreconst [a] {s} p0 x:(MOVBstoreconst [c] {s} p1 mem))
   && x.Uses == 1
   && a.Off() == c.Off()
   && sequentialAddresses(p0, p1, 1)
   && clobber(x)
-  => (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p0 mem)
+  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
 
 (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
   && x.Uses == 1
   && a.Off() + 2 == c.Off()
   && clobber(x)
-  => (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p mem)
+  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
 (MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem))
   && x.Uses == 1
   && ValAndOff(a).Off() + 2 == ValAndOff(c).Off()
   && clobber(x)
-  => (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p mem)
+  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
 
 (MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem))
   && x.Uses == 1
   && a.Off() == c.Off()
   && sequentialAddresses(p0, p1, 2)
   && clobber(x)
-  => (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p0 mem)
+  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
 (MOVWstoreconst [a] {s} p0 x:(MOVWstoreconst [c] {s} p1 mem))
   && x.Uses == 1
   && a.Off() == c.Off()
   && sequentialAddresses(p0, p1, 2)
   && clobber(x)
-  => (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p0 mem)
+  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
 
 // Combine stores into larger (unaligned) stores.
 (MOVBstore [i] {s} p (SHR(W|L)const [8] w) x:(MOVBstore [i-1] {s} p w mem))
@@ -1098,13 +1099,12 @@
 
 (CMP(L|W|B)const l:(MOV(L|W|B)load {sym} [off] ptr mem) [c])
 	&& l.Uses == 1
-	&& validValAndOff(int64(c), int64(off))
 	&& clobber(l) =>
-  @l.Block (CMP(L|W|B)constload {sym} [makeValAndOff32(int32(c),int32(off))] ptr mem)
+  @l.Block (CMP(L|W|B)constload {sym} [makeValAndOff(int32(c),off)] ptr mem)
 
-(CMPLload {sym} [off] ptr (MOVLconst [c]) mem) && validValAndOff(int64(c),int64(off)) => (CMPLconstload {sym} [makeValAndOff32(c,off)] ptr mem)
-(CMPWload {sym} [off] ptr (MOVLconst [c]) mem) && validValAndOff(int64(int16(c)),int64(off)) => (CMPWconstload {sym} [makeValAndOff32(int32(int16(c)),off)] ptr mem)
-(CMPBload {sym} [off] ptr (MOVLconst [c]) mem) && validValAndOff(int64(int8(c)),int64(off)) => (CMPBconstload {sym} [makeValAndOff32(int32(int8(c)),off)] ptr mem)
+(CMPLload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPLconstload {sym} [makeValAndOff(c,off)] ptr mem)
+(CMPWload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPWconstload {sym} [makeValAndOff(int32(int16(c)),off)] ptr mem)
+(CMPBload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPBconstload {sym} [makeValAndOff(int32(int8(c)),off)] ptr mem)
 
 (MOVBload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read8(sym, int64(off)))])
 (MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
diff --git a/src/cmd/compile/internal/ssa/gen/386Ops.go b/src/cmd/compile/internal/ssa/gen/386Ops.go
index 737b99c..c4b49fb 100644
--- a/src/cmd/compile/internal/ssa/gen/386Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/386Ops.go
@@ -146,14 +146,14 @@
 
 	var _386ops = []opData{
 		// fp ops
-		{name: "ADDSS", argLength: 2, reg: fp21, asm: "ADDSS", commutative: true, resultInArg0: true, usesScratch: true}, // fp32 add
-		{name: "ADDSD", argLength: 2, reg: fp21, asm: "ADDSD", commutative: true, resultInArg0: true},                    // fp64 add
-		{name: "SUBSS", argLength: 2, reg: fp21, asm: "SUBSS", resultInArg0: true, usesScratch: true},                    // fp32 sub
-		{name: "SUBSD", argLength: 2, reg: fp21, asm: "SUBSD", resultInArg0: true},                                       // fp64 sub
-		{name: "MULSS", argLength: 2, reg: fp21, asm: "MULSS", commutative: true, resultInArg0: true, usesScratch: true}, // fp32 mul
-		{name: "MULSD", argLength: 2, reg: fp21, asm: "MULSD", commutative: true, resultInArg0: true},                    // fp64 mul
-		{name: "DIVSS", argLength: 2, reg: fp21, asm: "DIVSS", resultInArg0: true, usesScratch: true},                    // fp32 div
-		{name: "DIVSD", argLength: 2, reg: fp21, asm: "DIVSD", resultInArg0: true},                                       // fp64 div
+		{name: "ADDSS", argLength: 2, reg: fp21, asm: "ADDSS", commutative: true, resultInArg0: true}, // fp32 add
+		{name: "ADDSD", argLength: 2, reg: fp21, asm: "ADDSD", commutative: true, resultInArg0: true}, // fp64 add
+		{name: "SUBSS", argLength: 2, reg: fp21, asm: "SUBSS", resultInArg0: true},                    // fp32 sub
+		{name: "SUBSD", argLength: 2, reg: fp21, asm: "SUBSD", resultInArg0: true},                    // fp64 sub
+		{name: "MULSS", argLength: 2, reg: fp21, asm: "MULSS", commutative: true, resultInArg0: true}, // fp32 mul
+		{name: "MULSD", argLength: 2, reg: fp21, asm: "MULSD", commutative: true, resultInArg0: true}, // fp64 mul
+		{name: "DIVSS", argLength: 2, reg: fp21, asm: "DIVSS", resultInArg0: true},                    // fp32 div
+		{name: "DIVSD", argLength: 2, reg: fp21, asm: "DIVSD", resultInArg0: true},                    // fp64 div
 
 		{name: "MOVSSload", argLength: 2, reg: fpload, asm: "MOVSS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp32 load
 		{name: "MOVSDload", argLength: 2, reg: fpload, asm: "MOVSD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp64 load
@@ -246,8 +246,8 @@
 		{name: "CMPWconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPW", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
 		{name: "CMPBconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPB", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
 
-		{name: "UCOMISS", argLength: 2, reg: fp2flags, asm: "UCOMISS", typ: "Flags", usesScratch: true}, // arg0 compare to arg1, f32
-		{name: "UCOMISD", argLength: 2, reg: fp2flags, asm: "UCOMISD", typ: "Flags", usesScratch: true}, // arg0 compare to arg1, f64
+		{name: "UCOMISS", argLength: 2, reg: fp2flags, asm: "UCOMISS", typ: "Flags"}, // arg0 compare to arg1, f32
+		{name: "UCOMISD", argLength: 2, reg: fp2flags, asm: "UCOMISD", typ: "Flags"}, // arg0 compare to arg1, f64
 
 		{name: "TESTL", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTL", typ: "Flags"}, // (arg0 & arg1) compare to 0
 		{name: "TESTW", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTW", typ: "Flags"}, // (arg0 & arg1) compare to 0
@@ -308,6 +308,7 @@
 		{name: "BSWAPL", argLength: 1, reg: gp11, asm: "BSWAPL", resultInArg0: true, clobberFlags: true}, // arg0 swap bytes
 
 		{name: "SQRTSD", argLength: 1, reg: fp11, asm: "SQRTSD"}, // sqrt(arg0)
+		{name: "SQRTSS", argLength: 1, reg: fp11, asm: "SQRTSS"}, // sqrt(arg0), float32
 
 		{name: "SBBLcarrymask", argLength: 1, reg: flagsgp, asm: "SBBL"}, // (int32)(-1) if carry is set, 0 if carry is clear.
 		// Note: SBBW and SBBB are subsumed by SBBL
@@ -341,12 +342,12 @@
 
 		{name: "MOVLconst", reg: gp01, asm: "MOVL", typ: "UInt32", aux: "Int32", rematerializeable: true}, // 32 low bits of auxint
 
-		{name: "CVTTSD2SL", argLength: 1, reg: fpgp, asm: "CVTTSD2SL", usesScratch: true}, // convert float64 to int32
-		{name: "CVTTSS2SL", argLength: 1, reg: fpgp, asm: "CVTTSS2SL", usesScratch: true}, // convert float32 to int32
-		{name: "CVTSL2SS", argLength: 1, reg: gpfp, asm: "CVTSL2SS", usesScratch: true},   // convert int32 to float32
-		{name: "CVTSL2SD", argLength: 1, reg: gpfp, asm: "CVTSL2SD", usesScratch: true},   // convert int32 to float64
-		{name: "CVTSD2SS", argLength: 1, reg: fp11, asm: "CVTSD2SS", usesScratch: true},   // convert float64 to float32
-		{name: "CVTSS2SD", argLength: 1, reg: fp11, asm: "CVTSS2SD"},                      // convert float32 to float64
+		{name: "CVTTSD2SL", argLength: 1, reg: fpgp, asm: "CVTTSD2SL"}, // convert float64 to int32
+		{name: "CVTTSS2SL", argLength: 1, reg: fpgp, asm: "CVTTSS2SL"}, // convert float32 to int32
+		{name: "CVTSL2SS", argLength: 1, reg: gpfp, asm: "CVTSL2SS"},   // convert int32 to float32
+		{name: "CVTSL2SD", argLength: 1, reg: gpfp, asm: "CVTSL2SD"},   // convert int32 to float64
+		{name: "CVTSD2SS", argLength: 1, reg: fp11, asm: "CVTSD2SS"},   // convert float64 to float32
+		{name: "CVTSS2SD", argLength: 1, reg: fp11, asm: "CVTSS2SD"},   // convert float32 to float64
 
 		{name: "PXOR", argLength: 2, reg: fp21, asm: "PXOR", commutative: true, resultInArg0: true}, // exclusive or, applied to X regs for float negation.
 
diff --git a/src/cmd/compile/internal/ssa/gen/386splitload.rules b/src/cmd/compile/internal/ssa/gen/386splitload.rules
index ed93b90..29d4f8c 100644
--- a/src/cmd/compile/internal/ssa/gen/386splitload.rules
+++ b/src/cmd/compile/internal/ssa/gen/386splitload.rules
@@ -6,6 +6,6 @@
 
 (CMP(L|W|B)load {sym} [off] ptr x mem) => (CMP(L|W|B) (MOV(L|W|B)load {sym} [off] ptr mem) x)
 
-(CMPLconstload {sym} [vo] ptr mem) => (CMPLconst (MOVLload {sym} [vo.Off32()] ptr mem) [vo.Val32()])
-(CMPWconstload {sym} [vo] ptr mem) => (CMPWconst (MOVWload {sym} [vo.Off32()] ptr mem) [vo.Val16()])
-(CMPBconstload {sym} [vo] ptr mem) => (CMPBconst (MOVBload {sym} [vo.Off32()] ptr mem) [vo.Val8()])
+(CMPLconstload {sym} [vo] ptr mem) => (CMPLconst (MOVLload {sym} [vo.Off()] ptr mem) [vo.Val()])
+(CMPWconstload {sym} [vo] ptr mem) => (CMPWconst (MOVWload {sym} [vo.Off()] ptr mem) [vo.Val16()])
+(CMPBconstload {sym} [vo] ptr mem) => (CMPBconst (MOVBload {sym} [vo.Off()] ptr mem) [vo.Val8()])
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules
index 5de1e1e..4cd0073 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64.rules
+++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules
@@ -104,6 +104,7 @@
 (PopCount8 x) => (POPCNTL (MOVBQZX <typ.UInt32> x))
 
 (Sqrt ...) => (SQRTSD ...)
+(Sqrt32 ...) => (SQRTSS ...)
 
 (RoundToEven x) => (ROUNDSD [0] x)
 (Floor x)       => (ROUNDSD [1] x)
@@ -317,75 +318,75 @@
 
 // Lowering Zero instructions
 (Zero [0] _ mem) => mem
-(Zero [1] destptr mem) => (MOVBstoreconst [makeValAndOff32(0,0)] destptr mem)
-(Zero [2] destptr mem) => (MOVWstoreconst [makeValAndOff32(0,0)] destptr mem)
-(Zero [4] destptr mem) => (MOVLstoreconst [makeValAndOff32(0,0)] destptr mem)
-(Zero [8] destptr mem) => (MOVQstoreconst [makeValAndOff32(0,0)] destptr mem)
+(Zero [1] destptr mem) => (MOVBstoreconst [makeValAndOff(0,0)] destptr mem)
+(Zero [2] destptr mem) => (MOVWstoreconst [makeValAndOff(0,0)] destptr mem)
+(Zero [4] destptr mem) => (MOVLstoreconst [makeValAndOff(0,0)] destptr mem)
+(Zero [8] destptr mem) => (MOVQstoreconst [makeValAndOff(0,0)] destptr mem)
 
 (Zero [3] destptr mem) =>
-	(MOVBstoreconst [makeValAndOff32(0,2)] destptr
-		(MOVWstoreconst [makeValAndOff32(0,0)] destptr mem))
+	(MOVBstoreconst [makeValAndOff(0,2)] destptr
+		(MOVWstoreconst [makeValAndOff(0,0)] destptr mem))
 (Zero [5] destptr mem) =>
-	(MOVBstoreconst [makeValAndOff32(0,4)] destptr
-		(MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	(MOVBstoreconst [makeValAndOff(0,4)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 (Zero [6] destptr mem) =>
-	(MOVWstoreconst [makeValAndOff32(0,4)] destptr
-		(MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	(MOVWstoreconst [makeValAndOff(0,4)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 (Zero [7] destptr mem) =>
-	(MOVLstoreconst [makeValAndOff32(0,3)] destptr
-		(MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	(MOVLstoreconst [makeValAndOff(0,3)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 
 // Strip off any fractional word zeroing.
 (Zero [s] destptr mem) && s%8 != 0 && s > 8 && !config.useSSE =>
 	(Zero [s-s%8] (OffPtr <destptr.Type> destptr [s%8])
-		(MOVQstoreconst [makeValAndOff32(0,0)] destptr mem))
+		(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
 
 // Zero small numbers of words directly.
 (Zero [16] destptr mem) && !config.useSSE =>
-	(MOVQstoreconst [makeValAndOff32(0,8)] destptr
-		(MOVQstoreconst [makeValAndOff32(0,0)] destptr mem))
+	(MOVQstoreconst [makeValAndOff(0,8)] destptr
+		(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
 (Zero [24] destptr mem) && !config.useSSE =>
-	(MOVQstoreconst [makeValAndOff32(0,16)] destptr
-		(MOVQstoreconst [makeValAndOff32(0,8)] destptr
-			(MOVQstoreconst [makeValAndOff32(0,0)] destptr mem)))
+	(MOVQstoreconst [makeValAndOff(0,16)] destptr
+		(MOVQstoreconst [makeValAndOff(0,8)] destptr
+			(MOVQstoreconst [makeValAndOff(0,0)] destptr mem)))
 (Zero [32] destptr mem) && !config.useSSE =>
-	(MOVQstoreconst [makeValAndOff32(0,24)] destptr
-		(MOVQstoreconst [makeValAndOff32(0,16)] destptr
-			(MOVQstoreconst [makeValAndOff32(0,8)] destptr
-				(MOVQstoreconst [makeValAndOff32(0,0)] destptr mem))))
+	(MOVQstoreconst [makeValAndOff(0,24)] destptr
+		(MOVQstoreconst [makeValAndOff(0,16)] destptr
+			(MOVQstoreconst [makeValAndOff(0,8)] destptr
+				(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))))
 
 (Zero [s] destptr mem) && s > 8 && s < 16 && config.useSSE =>
-	(MOVQstoreconst [makeValAndOff32(0,int32(s-8))] destptr
-		(MOVQstoreconst [makeValAndOff32(0,0)] destptr mem))
+	(MOVQstoreconst [makeValAndOff(0,int32(s-8))] destptr
+		(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
 
 // Adjust zeros to be a multiple of 16 bytes.
 (Zero [s] destptr mem) && s%16 != 0 && s > 16 && s%16 > 8 && config.useSSE =>
 	(Zero [s-s%16] (OffPtr <destptr.Type> destptr [s%16])
-		(MOVOstore destptr (MOVOconst [0]) mem))
+		(MOVOstorezero destptr mem))
 
 (Zero [s] destptr mem) && s%16 != 0 && s > 16 && s%16 <= 8 && config.useSSE =>
 	(Zero [s-s%16] (OffPtr <destptr.Type> destptr [s%16])
-		(MOVQstoreconst [makeValAndOff32(0,0)] destptr mem))
+		(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
 
 (Zero [16] destptr mem) && config.useSSE =>
-	(MOVOstore destptr (MOVOconst [0]) mem)
+	(MOVOstorezero destptr mem)
 (Zero [32] destptr mem) && config.useSSE =>
-	(MOVOstore (OffPtr <destptr.Type> destptr [16]) (MOVOconst [0])
-		(MOVOstore destptr (MOVOconst [0]) mem))
+	(MOVOstorezero (OffPtr <destptr.Type> destptr [16])
+		(MOVOstorezero destptr 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)))
+	(MOVOstorezero (OffPtr <destptr.Type> destptr [32])
+		(MOVOstorezero (OffPtr <destptr.Type> destptr [16])
+			(MOVOstorezero destptr 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))))
+	(MOVOstorezero (OffPtr <destptr.Type> destptr [48])
+		(MOVOstorezero (OffPtr <destptr.Type> destptr [32])
+			(MOVOstorezero (OffPtr <destptr.Type> destptr [16])
+				(MOVOstorezero destptr mem))))
 
 // Medium zeroing uses a duff device.
 (Zero [s] destptr mem)
 	&& s > 64 && s <= 1024 && s%16 == 0 && !config.noDuffDevice =>
-	(DUFFZERO [s] destptr (MOVOconst [0]) mem)
+	(DUFFZERO [s] destptr mem)
 
 // Large zeroing uses REP STOSQ.
 (Zero [s] destptr mem)
@@ -459,7 +460,7 @@
 (IsInBounds idx len) => (SETB (CMPQ idx len))
 (IsSliceInBounds idx len) => (SETBE (CMPQ idx len))
 (NilCheck ...) => (LoweredNilCheck ...)
-(GetG ...) => (LoweredGetG ...)
+(GetG mem) && !(buildcfg.Experiment.RegabiG && v.Block.Func.OwnAux.Fn.ABI() == obj.ABIInternal) => (LoweredGetG mem) // only lower in old ABI. in new ABI we have a G register.
 (GetClosurePtr ...) => (LoweredGetClosurePtr ...)
 (GetCallerPC ...) => (LoweredGetCallerPC ...)
 (GetCallerSP ...) => (LoweredGetCallerSP ...)
@@ -623,14 +624,6 @@
 // Recognize bit setting (a |= 1<<b) and toggling (a ^= 1<<b)
 (OR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTS(Q|L) x y)
 (XOR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTC(Q|L) x y)
-(ORLmodify [off] {sym} ptr s:(SHLL (MOVLconst [1]) <t> x) mem) =>
-	(BTSLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem)
-(ORQmodify [off] {sym} ptr s:(SHLQ (MOVQconst [1]) <t> x) mem) =>
-	(BTSQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem)
-(XORLmodify [off] {sym} ptr s:(SHLL (MOVLconst [1]) <t> x) mem) =>
-	(BTCLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem)
-(XORQmodify [off] {sym} ptr s:(SHLQ (MOVQconst [1]) <t> x) mem) =>
-	(BTCQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem)
 
 // Convert ORconst into BTS, if the code gets smaller, with boundary being
 // (ORL $40,AX is 3 bytes, ORL $80,AX is 6 bytes).
@@ -653,10 +646,6 @@
     => (BTRQconst [int8(log64(^c))] x)
 (ANDL (MOVLconst [c]) x) && isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128
     => (BTRLconst [int8(log32(^c))] x)
-(ANDLmodify [off] {sym} ptr (NOTL s:(SHLL (MOVLconst [1]) <t> x)) mem) =>
-	(BTRLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem)
-(ANDQmodify [off] {sym} ptr (NOTQ s:(SHLQ (MOVQconst [1]) <t> x)) mem) =>
-	(BTRQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem)
 
 // Special-case bit patterns on first/last bit.
 // generic.rules changes ANDs of high-part/low-part masks into a couple of shifts,
@@ -913,6 +902,9 @@
 ((SHRB|SARB)const           x [0]) => x
 ((ROLQ|ROLL|ROLW|ROLB)const x [0]) => x
 
+// Multi-register shifts
+(ORQ (SH(R|L)Q lo bits) (SH(L|R)Q hi (NEGQ bits))) => (SH(R|L)DQ lo hi bits)
+
 // Note: the word and byte shifts keep the low 5 bits (not the low 4 or 3 bits)
 // because the x86 instructions are defined to use all 5 bits of the shift even
 // for the small shifts. I don't think we'll ever generate a weird shift (e.g.
@@ -928,7 +920,7 @@
 (CMPB (MOVLconst [c]) x) => (InvertFlags (CMPBconst x [int8(c)]))
 
 // Canonicalize the order of arguments to comparisons - helps with CSE.
-(CMP(Q|L|W|B) x y) && x.ID > y.ID => (InvertFlags (CMP(Q|L|W|B) y x))
+(CMP(Q|L|W|B) x y) && canonLessThan(x,y) => (InvertFlags (CMP(Q|L|W|B) y x))
 
 // Using MOVZX instead of AND is cheaper.
 (AND(Q|L)const [  0xFF] x) => (MOVBQZX x)
@@ -1122,24 +1114,24 @@
 	((ADD|SUB|MUL|DIV)SSload [off1+off2] {sym} val base mem)
 ((ADD|SUB|MUL|DIV)SDload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
 	((ADD|SUB|MUL|DIV)SDload [off1+off2] {sym} val base mem)
-((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
-	((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
-((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
-	((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
-((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
-	((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1+off2] {sym} base val mem)
-((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
-	((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1+off2] {sym} base val mem)
+((ADD|AND|OR|XOR)Qconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
+	((ADD|AND|OR|XOR)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
+((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
+	((ADD|AND|OR|XOR)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
+((ADD|SUB|AND|OR|XOR)Qmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
+	((ADD|SUB|AND|OR|XOR)Qmodify [off1+off2] {sym} base val mem)
+((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
+	((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {sym} base val mem)
 
 // Fold constants into stores.
 (MOVQstore [off] {sym} ptr (MOVQconst [c]) mem) && validVal(c) =>
-	(MOVQstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+	(MOVQstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
 (MOVLstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) =>
-	(MOVLstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+	(MOVLstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
 (MOVWstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) =>
-	(MOVWstoreconst [makeValAndOff32(int32(int16(c)),off)] {sym} ptr mem)
+	(MOVWstoreconst [makeValAndOff(int32(int16(c)),off)] {sym} ptr mem)
 (MOVBstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) =>
-	(MOVBstoreconst [makeValAndOff32(int32(int8(c)),off)] {sym} ptr mem)
+	(MOVBstoreconst [makeValAndOff(int32(int8(c)),off)] {sym} ptr mem)
 
 // Fold address offsets into constant stores.
 (MOV(Q|L|W|B)storeconst [sc] {s} (ADDQconst [off] ptr) mem) && ValAndOff(sc).canAdd32(off) =>
@@ -1177,18 +1169,18 @@
 ((ADD|SUB|MUL|DIV)SDload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem)
 	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
 	((ADD|SUB|MUL|DIV)SDload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
-((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
+((ADD|AND|OR|XOR)Qconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
 	&& ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) =>
-	((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
-((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
+	((ADD|AND|OR|XOR)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
+((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
 	&& ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) =>
-	((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
-((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+	((ADD|AND|OR|XOR)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
+((ADD|SUB|AND|OR|XOR)Qmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
 	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+	((ADD|SUB|AND|OR|XOR)Qmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
 	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+	((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
 
 // fold LEAQs together
 (LEAQ [off1] {sym1} (LEAQ [off2] {sym2} x)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
@@ -1879,32 +1871,32 @@
   && x.Uses == 1
   && a.Off() + 1 == c.Off()
   && clobber(x)
-  => (MOVWstoreconst [makeValAndOff64(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
+  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
 (MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem))
   && x.Uses == 1
   && a.Off() + 1 == c.Off()
   && clobber(x)
-  => (MOVWstoreconst [makeValAndOff64(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
+  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
 (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
   && x.Uses == 1
   && a.Off() + 2 == c.Off()
   && clobber(x)
-  => (MOVLstoreconst [makeValAndOff64(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
+  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
 (MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem))
   && x.Uses == 1
   && a.Off() + 2 == c.Off()
   && clobber(x)
-  => (MOVLstoreconst [makeValAndOff64(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
+  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
 (MOVLstoreconst [c] {s} p x:(MOVLstoreconst [a] {s} p mem))
   && x.Uses == 1
   && a.Off() + 4 == c.Off()
   && clobber(x)
-  => (MOVQstore [a.Off32()] {s} p (MOVQconst [a.Val()&0xffffffff | c.Val()<<32]) mem)
+  => (MOVQstore [a.Off()] {s} p (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
 (MOVLstoreconst [a] {s} p x:(MOVLstoreconst [c] {s} p mem))
   && x.Uses == 1
   && a.Off() + 4 == c.Off()
   && clobber(x)
-  => (MOVQstore [a.Off32()] {s} p (MOVQconst [a.Val()&0xffffffff | c.Val()<<32]) mem)
+  => (MOVQstore [a.Off()] {s} p (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
 (MOVQstoreconst [c] {s} p x:(MOVQstoreconst [c2] {s} p mem))
   && config.useSSE
   && x.Uses == 1
@@ -1912,7 +1904,7 @@
   && c.Val() == 0
   && c2.Val() == 0
   && clobber(x)
-  => (MOVOstore [c2.Off32()] {s} p (MOVOconst [0]) mem)
+  => (MOVOstorezero [c2.Off()] {s} p mem)
 
 // Combine stores into larger (unaligned) stores. Little endian.
 (MOVBstore [i] {s} p (SHR(W|L|Q)const [8] w) x:(MOVBstore [i-1] {s} p w mem))
@@ -1981,6 +1973,16 @@
   && clobber(x)
   => (MOVQstore [i] {s} p0 w0 mem)
 
+(MOVBstore [7] {s} p1 (SHRQconst [56] w)
+  x1:(MOVWstore [5] {s} p1 (SHRQconst [40] w)
+  x2:(MOVLstore [1] {s} p1 (SHRQconst [8] w)
+  x3:(MOVBstore [0] {s} p1 w mem))))
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && x3.Uses == 1
+  && clobber(x1, x2, x3)
+  => (MOVQstore {s} p1 w mem)
+
 (MOVBstore [i] {s} p
   x1:(MOVBload [j] {s2} p2 mem)
     mem2:(MOVBstore [i-1] {s} p
@@ -2064,13 +2066,9 @@
 (MOVLstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Lload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Lmodify [off] {sym} ptr x mem)
 (MOVLstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR)L l:(MOVLload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) =>
 	((ADD|SUB|AND|OR|XOR)Lmodify [off] {sym} ptr x mem)
-(MOVLstore {sym} [off] ptr y:((BTC|BTR|BTS)L l:(MOVLload [off] {sym} ptr mem) <t> x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) =>
-	((BTC|BTR|BTS)Lmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem)
 (MOVQstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Qload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Qmodify [off] {sym} ptr x mem)
 (MOVQstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR)Q l:(MOVQload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) =>
 	((ADD|SUB|AND|OR|XOR)Qmodify [off] {sym} ptr x mem)
-(MOVQstore {sym} [off] ptr y:((BTC|BTR|BTS)Q l:(MOVQload [off] {sym} ptr mem) <t> x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) =>
-	((BTC|BTR|BTS)Qmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem)
 
 // Merge ADDQconst and LEAQ into atomic loads.
 (MOV(Q|L|B)atomicload [off1] {sym} (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
@@ -2124,12 +2122,12 @@
 (MOVWQZX (MOVBQZX x)) => (MOVBQZX x)
 (MOVBQZX (MOVBQZX x)) => (MOVBQZX x)
 
-(MOVQstore [off] {sym} ptr a:((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem)
-	&& isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) =>
-	((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
-(MOVLstore [off] {sym} ptr a:((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem)
-	&& isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) =>
-	((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
+(MOVQstore [off] {sym} ptr a:((ADD|AND|OR|XOR)Qconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem)
+	&& isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a) =>
+	((ADD|AND|OR|XOR)Qconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
+(MOVLstore [off] {sym} ptr a:((ADD|AND|OR|XOR)Lconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem)
+	&& isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a) =>
+	((ADD|AND|OR|XOR)Lconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
 
 // float <-> int register moves, with no conversion.
 // These come up when compiling math.{Float{32,64}bits,Float{32,64}frombits}.
@@ -2189,23 +2187,27 @@
 (CMP(Q|L)const l:(MOV(Q|L)load {sym} [off] ptr mem) [c])
 	&& l.Uses == 1
 	&& clobber(l) =>
-@l.Block (CMP(Q|L)constload {sym} [makeValAndOff32(c,off)] ptr mem)
+@l.Block (CMP(Q|L)constload {sym} [makeValAndOff(c,off)] ptr mem)
 (CMP(W|B)const l:(MOV(W|B)load {sym} [off] ptr mem) [c])
 	&& l.Uses == 1
 	&& clobber(l) =>
-@l.Block (CMP(W|B)constload {sym} [makeValAndOff32(int32(c),off)] ptr mem)
+@l.Block (CMP(W|B)constload {sym} [makeValAndOff(int32(c),off)] ptr mem)
 
-(CMPQload {sym} [off] ptr (MOVQconst [c]) mem) && validValAndOff(c,int64(off)) => (CMPQconstload {sym} [makeValAndOff64(c,int64(off))] ptr mem)
-(CMPLload {sym} [off] ptr (MOVLconst [c]) mem) && validValAndOff(int64(c),int64(off)) => (CMPLconstload {sym} [makeValAndOff32(c,off)] ptr mem)
-(CMPWload {sym} [off] ptr (MOVLconst [c]) mem) && validValAndOff(int64(int16(c)),int64(off)) => (CMPWconstload {sym} [makeValAndOff32(int32(int16(c)),off)] ptr mem)
-(CMPBload {sym} [off] ptr (MOVLconst [c]) mem) && validValAndOff(int64(int8(c)),int64(off)) => (CMPBconstload {sym} [makeValAndOff32(int32(int8(c)),off)] ptr mem)
+(CMPQload {sym} [off] ptr (MOVQconst [c]) mem) && validVal(c) => (CMPQconstload {sym} [makeValAndOff(int32(c),off)] ptr mem)
+(CMPLload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPLconstload {sym} [makeValAndOff(c,off)] ptr mem)
+(CMPWload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPWconstload {sym} [makeValAndOff(int32(int16(c)),off)] ptr mem)
+(CMPBload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPBconstload {sym} [makeValAndOff(int32(int8(c)),off)] ptr mem)
 
 (TEST(Q|L|W|B)  l:(MOV(Q|L|W|B)load {sym} [off] ptr mem) l2)
         && l == l2
 	&& l.Uses == 2
-	&& validValAndOff(0, int64(off))
 	&& clobber(l) =>
-  @l.Block (CMP(Q|L|W|B)constload {sym} [makeValAndOff64(0, int64(off))] ptr mem)
+  @l.Block (CMP(Q|L|W|B)constload {sym} [makeValAndOff(0, off)] ptr mem)
+
+// Convert ANDload to MOVload when we can do the AND in a containing TEST op.
+// Only do when it's within the same block, so we don't have flags live across basic block boundaries.
+// See issue 44228.
+(TEST(Q|L) a:(AND(Q|L)load [off] {sym} x ptr mem) a) && a.Uses == 2 && a.Block == v.Block && clobber(a) => (TEST(Q|L) (MOV(Q|L)load <a.Type> [off] {sym} ptr mem) x)
 
 (MOVBload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read8(sym, int64(off)))])
 (MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
@@ -2214,3 +2216,22 @@
 (MOVOstore [dstOff] {dstSym} ptr (MOVOload [srcOff] {srcSym} (SB) _) mem) && symIsRO(srcSym) =>
   (MOVQstore [dstOff+8] {dstSym} ptr (MOVQconst [int64(read64(srcSym, int64(srcOff)+8, config.ctxt.Arch.ByteOrder))])
     (MOVQstore [dstOff] {dstSym} ptr (MOVQconst [int64(read64(srcSym, int64(srcOff), config.ctxt.Arch.ByteOrder))]) mem))
+
+// Arch-specific inlining for small or disjoint runtime.memmove
+// Match post-lowering calls, memory version.
+(SelectN [0] call:(CALLstatic {sym} s1:(MOVQstoreconst _ [sc] s2:(MOVQstore _ src s3:(MOVQstore _ dst mem)))))
+	&& sc.Val64() >= 0
+	&& isSameCall(sym, "runtime.memmove")
+	&& s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
+	&& isInlinableMemmove(dst, src, sc.Val64(), config)
+	&& clobber(s1, s2, s3, call)
+	=> (Move [sc.Val64()] dst src mem)
+
+// Match post-lowering calls, register version.
+(SelectN [0] call:(CALLstatic {sym} dst src (MOVQconst [sz]) mem))
+	&& sz >= 0
+	&& isSameCall(sym, "runtime.memmove")
+	&& call.Uses == 1
+	&& isInlinableMemmove(dst, src, sz, config)
+	&& clobber(call)
+	=> (Move [sz] dst src mem)
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
index a87581b..67b3293 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 package main
@@ -44,7 +45,7 @@
 	"R11",
 	"R12",
 	"R13",
-	"R14",
+	"g", // a.k.a. R14
 	"R15",
 	"X0",
 	"X1",
@@ -61,7 +62,7 @@
 	"X12",
 	"X13",
 	"X14",
-	"X15",
+	"X15", // constant 0 in ABIInternal
 
 	// If you add registers, update asyncPreempt in runtime
 
@@ -96,11 +97,14 @@
 		cx         = buildReg("CX")
 		dx         = buildReg("DX")
 		bx         = buildReg("BX")
-		gp         = buildReg("AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15")
-		fp         = buildReg("X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15")
+		gp         = buildReg("AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15")
+		g          = buildReg("g")
+		fp         = buildReg("X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14")
+		x15        = buildReg("X15")
 		gpsp       = gp | buildReg("SP")
 		gpspsb     = gpsp | buildReg("SB")
-		callerSave = gp | fp
+		gpspsbg    = gpspsb | g
+		callerSave = gp | fp | g // runtime.setg (and anything calling it) may clobber g
 	)
 	// Common slices of register masks
 	var (
@@ -113,11 +117,12 @@
 		gp01           = regInfo{inputs: nil, outputs: gponly}
 		gp11           = regInfo{inputs: []regMask{gp}, outputs: gponly}
 		gp11sp         = regInfo{inputs: []regMask{gpsp}, outputs: gponly}
-		gp11sb         = regInfo{inputs: []regMask{gpspsb}, outputs: gponly}
+		gp11sb         = regInfo{inputs: []regMask{gpspsbg}, outputs: gponly}
 		gp21           = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
 		gp21sp         = regInfo{inputs: []regMask{gpsp, gp}, outputs: gponly}
-		gp21sb         = regInfo{inputs: []regMask{gpspsb, gpsp}, outputs: gponly}
+		gp21sb         = regInfo{inputs: []regMask{gpspsbg, gpsp}, outputs: gponly}
 		gp21shift      = regInfo{inputs: []regMask{gp, cx}, outputs: []regMask{gp}}
+		gp31shift      = regInfo{inputs: []regMask{gp, gp, cx}, outputs: []regMask{gp}}
 		gp11div        = regInfo{inputs: []regMask{ax, gpsp &^ dx}, outputs: []regMask{ax, dx}}
 		gp21hmul       = regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{dx}, clobbers: ax}
 		gp21flags      = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp, 0}}
@@ -125,9 +130,9 @@
 
 		gp2flags     = regInfo{inputs: []regMask{gpsp, gpsp}}
 		gp1flags     = regInfo{inputs: []regMask{gpsp}}
-		gp0flagsLoad = regInfo{inputs: []regMask{gpspsb, 0}}
-		gp1flagsLoad = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
-		gp2flagsLoad = regInfo{inputs: []regMask{gpspsb, gpsp, gpsp, 0}}
+		gp0flagsLoad = regInfo{inputs: []regMask{gpspsbg, 0}}
+		gp1flagsLoad = regInfo{inputs: []regMask{gpspsbg, gpsp, 0}}
+		gp2flagsLoad = regInfo{inputs: []regMask{gpspsbg, gpsp, gpsp, 0}}
 		flagsgp      = regInfo{inputs: nil, outputs: gponly}
 
 		gp11flags      = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp, 0}}
@@ -136,24 +141,24 @@
 		readflags = regInfo{inputs: nil, outputs: gponly}
 		flagsgpax = regInfo{inputs: nil, clobbers: ax, outputs: []regMask{gp &^ ax}}
 
-		gpload      = regInfo{inputs: []regMask{gpspsb, 0}, outputs: gponly}
-		gp21load    = regInfo{inputs: []regMask{gp, gpspsb, 0}, outputs: gponly}
-		gploadidx   = regInfo{inputs: []regMask{gpspsb, gpsp, 0}, outputs: gponly}
-		gp21loadidx = regInfo{inputs: []regMask{gp, gpspsb, gpsp, 0}, outputs: gponly}
+		gpload      = regInfo{inputs: []regMask{gpspsbg, 0}, outputs: gponly}
+		gp21load    = regInfo{inputs: []regMask{gp, gpspsbg, 0}, outputs: gponly}
+		gploadidx   = regInfo{inputs: []regMask{gpspsbg, gpsp, 0}, outputs: gponly}
+		gp21loadidx = regInfo{inputs: []regMask{gp, gpspsbg, gpsp, 0}, outputs: gponly}
 		gp21pax     = regInfo{inputs: []regMask{gp &^ ax, gp}, outputs: []regMask{gp &^ ax}, clobbers: ax}
 
-		gpstore         = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
-		gpstoreconst    = regInfo{inputs: []regMask{gpspsb, 0}}
-		gpstoreidx      = regInfo{inputs: []regMask{gpspsb, gpsp, gpsp, 0}}
-		gpstoreconstidx = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
-		gpstorexchg     = regInfo{inputs: []regMask{gp, gpspsb, 0}, outputs: []regMask{gp}}
+		gpstore         = regInfo{inputs: []regMask{gpspsbg, gpsp, 0}}
+		gpstoreconst    = regInfo{inputs: []regMask{gpspsbg, 0}}
+		gpstoreidx      = regInfo{inputs: []regMask{gpspsbg, gpsp, gpsp, 0}}
+		gpstoreconstidx = regInfo{inputs: []regMask{gpspsbg, gpsp, 0}}
+		gpstorexchg     = regInfo{inputs: []regMask{gp, gpspsbg, 0}, outputs: []regMask{gp}}
 		cmpxchg         = regInfo{inputs: []regMask{gp, ax, gp, 0}, outputs: []regMask{gp, 0}, clobbers: ax}
 
 		fp01        = regInfo{inputs: nil, outputs: fponly}
 		fp21        = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
 		fp31        = regInfo{inputs: []regMask{fp, fp, fp}, outputs: fponly}
-		fp21load    = regInfo{inputs: []regMask{fp, gpspsb, 0}, outputs: fponly}
-		fp21loadidx = regInfo{inputs: []regMask{fp, gpspsb, gpspsb, 0}, outputs: fponly}
+		fp21load    = regInfo{inputs: []regMask{fp, gpspsbg, 0}, outputs: fponly}
+		fp21loadidx = regInfo{inputs: []regMask{fp, gpspsbg, gpspsb, 0}, outputs: fponly}
 		fpgp        = regInfo{inputs: fponly, outputs: gponly}
 		gpfp        = regInfo{inputs: gponly, outputs: fponly}
 		fp11        = regInfo{inputs: fponly, outputs: fponly}
@@ -357,25 +362,6 @@
 		{name: "BTSLconst", argLength: 1, reg: gp11, asm: "BTSL", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // set bit auxint in arg0, 0 <= auxint < 32
 		{name: "BTSQconst", argLength: 1, reg: gp11, asm: "BTSQ", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // set bit auxint in arg0, 0 <= auxint < 64
 
-		// direct bit operation on memory operand
-		//
-		// Note that these operations do not mask the bit offset (arg1), and will write beyond their expected
-		// bounds if that argument is larger than 64/32 (for BT*Q and BT*L, respectively). If the compiler
-		// cannot prove that arg1 is in range, it must be explicitly masked (see e.g. the patterns that produce
-		// BT*modify from (MOVstore (BT* (MOVLload ptr mem) x) mem)).
-		{name: "BTCQmodify", argLength: 3, reg: gpstore, asm: "BTCQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},     // complement bit arg1 in 64-bit arg0+auxint+aux, arg2=mem
-		{name: "BTCLmodify", argLength: 3, reg: gpstore, asm: "BTCL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},     // complement bit arg1 in 32-bit arg0+auxint+aux, arg2=mem
-		{name: "BTSQmodify", argLength: 3, reg: gpstore, asm: "BTSQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},     // set bit arg1 in 64-bit arg0+auxint+aux, arg2=mem
-		{name: "BTSLmodify", argLength: 3, reg: gpstore, asm: "BTSL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},     // set bit arg1 in 32-bit arg0+auxint+aux, arg2=mem
-		{name: "BTRQmodify", argLength: 3, reg: gpstore, asm: "BTRQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},     // reset bit arg1 in 64-bit arg0+auxint+aux, arg2=mem
-		{name: "BTRLmodify", argLength: 3, reg: gpstore, asm: "BTRL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},     // reset bit arg1 in 32-bit arg0+auxint+aux, arg2=mem
-		{name: "BTCQconstmodify", argLength: 2, reg: gpstoreconst, asm: "BTCQ", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // complement bit ValAndOff(AuxInt).Val() in 64-bit arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-		{name: "BTCLconstmodify", argLength: 2, reg: gpstoreconst, asm: "BTCL", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // complement bit ValAndOff(AuxInt).Val() in 32-bit arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-		{name: "BTSQconstmodify", argLength: 2, reg: gpstoreconst, asm: "BTSQ", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // set bit ValAndOff(AuxInt).Val() in 64-bit arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-		{name: "BTSLconstmodify", argLength: 2, reg: gpstoreconst, asm: "BTSL", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // set bit ValAndOff(AuxInt).Val() in 32-bit arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-		{name: "BTRQconstmodify", argLength: 2, reg: gpstoreconst, asm: "BTRQ", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // reset bit ValAndOff(AuxInt).Val() in 64-bit arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-		{name: "BTRLconstmodify", argLength: 2, reg: gpstoreconst, asm: "BTRL", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // reset bit ValAndOff(AuxInt).Val() in 32-bit arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-
 		{name: "TESTQ", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTQ", typ: "Flags"}, // (arg0 & arg1) compare to 0
 		{name: "TESTL", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTL", typ: "Flags"}, // (arg0 & arg1) compare to 0
 		{name: "TESTW", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTW", typ: "Flags"}, // (arg0 & arg1) compare to 0
@@ -409,6 +395,9 @@
 		{name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed int16(arg0) >> auxint, shift amount 0-15
 		{name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed int8(arg0) >> auxint, shift amount 0-7
 
+		{name: "SHRDQ", argLength: 3, reg: gp31shift, asm: "SHRQ", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> arg2, shifting in bits from arg1 (==(arg1<<64+arg0)>>arg2, keeping low 64 bits), shift amount is mod 64
+		{name: "SHLDQ", argLength: 3, reg: gp31shift, asm: "SHLQ", resultInArg0: true, clobberFlags: true}, // unsigned arg0 << arg2, shifting in bits from arg1 (==(arg0<<64+arg1)<<arg2, keeping high 64 bits), shift amount is mod 64
+
 		{name: "ROLQ", argLength: 2, reg: gp21shift, asm: "ROLQ", resultInArg0: true, clobberFlags: true},              // arg0 rotate left arg1 bits.
 		{name: "ROLL", argLength: 2, reg: gp21shift, asm: "ROLL", resultInArg0: true, clobberFlags: true},              // arg0 rotate left arg1 bits.
 		{name: "ROLW", argLength: 2, reg: gp21shift, asm: "ROLW", resultInArg0: true, clobberFlags: true},              // arg0 rotate left arg1 bits.
@@ -595,6 +584,7 @@
 		{name: "POPCNTL", argLength: 1, reg: gp11, asm: "POPCNTL", clobberFlags: true}, // count number of set bits in arg0
 
 		{name: "SQRTSD", argLength: 1, reg: fp11, asm: "SQRTSD"}, // sqrt(arg0)
+		{name: "SQRTSS", argLength: 1, reg: fp11, asm: "SQRTSS"}, // sqrt(arg0), float32
 
 		// ROUNDSD instruction isn't guaranteed to be on the target platform (it is SSE4.1)
 		// Any use must be preceded by a successful check of runtime.x86HasSSE41.
@@ -689,19 +679,20 @@
 		// Note: LEAx{1,2,4,8} must not have OpSB as either argument.
 
 		// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
-		{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVBLZX", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load byte from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVBQSXload", argLength: 2, reg: gpload, asm: "MOVBQSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},             // ditto, sign extend to int64
-		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVWLZX", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVWQSXload", argLength: 2, reg: gpload, asm: "MOVWQSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},             // ditto, sign extend to int64
-		{name: "MOVLload", argLength: 2, reg: gpload, asm: "MOVL", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},    // load 4 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVLQSXload", argLength: 2, reg: gpload, asm: "MOVLQSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},             // ditto, sign extend to int64
-		{name: "MOVQload", argLength: 2, reg: gpload, asm: "MOVQ", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},    // load 8 bytes from arg0+auxint+aux. arg1=mem
-		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store byte in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVLstore", argLength: 3, reg: gpstore, asm: "MOVL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVQstore", argLength: 3, reg: gpstore, asm: "MOVQ", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVOload", argLength: 2, reg: fpload, asm: "MOVUPS", aux: "SymOff", typ: "Int128", faultOnNilArg0: true, symEffect: "Read"},  // load 16 bytes from arg0+auxint+aux. arg1=mem
-		{name: "MOVOstore", argLength: 3, reg: fpstore, asm: "MOVUPS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // store 16 bytes in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVBLZX", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},                                   // load byte from arg0+auxint+aux. arg1=mem.  Zero extend.
+		{name: "MOVBQSXload", argLength: 2, reg: gpload, asm: "MOVBQSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},                                              // ditto, sign extend to int64
+		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVWLZX", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"},                                  // load 2 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
+		{name: "MOVWQSXload", argLength: 2, reg: gpload, asm: "MOVWQSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},                                              // ditto, sign extend to int64
+		{name: "MOVLload", argLength: 2, reg: gpload, asm: "MOVL", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},                                     // load 4 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
+		{name: "MOVLQSXload", argLength: 2, reg: gpload, asm: "MOVLQSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},                                              // ditto, sign extend to int64
+		{name: "MOVQload", argLength: 2, reg: gpload, asm: "MOVQ", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},                                     // load 8 bytes from arg0+auxint+aux. arg1=mem
+		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},                                     // store byte in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},                                     // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVLstore", argLength: 3, reg: gpstore, asm: "MOVL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},                                     // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVQstore", argLength: 3, reg: gpstore, asm: "MOVQ", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},                                     // store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVOload", argLength: 2, reg: fpload, asm: "MOVUPS", aux: "SymOff", typ: "Int128", faultOnNilArg0: true, symEffect: "Read"},                                   // load 16 bytes from arg0+auxint+aux. arg1=mem
+		{name: "MOVOstore", argLength: 3, reg: fpstore, asm: "MOVUPS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},                                   // store 16 bytes in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVOstorezero", argLength: 2, reg: regInfo{inputs: []regMask{gpspsb, 0}}, asm: "MOVUPS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 16 bytes of zero to arg0+auxint+aux. arg1=mem
 
 		// indexed loads/stores
 		{name: "MOVBloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBLZX", scale: 1, aux: "SymOff", typ: "UInt8", symEffect: "Read"},  // load a byte from arg0+arg1+auxint+aux. arg2=mem
@@ -740,22 +731,20 @@
 		{name: "MOVQstoreconstidx8", argLength: 3, reg: gpstoreconstidx, asm: "MOVQ", scale: 8, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"},                    // store 8 bytes of ... 8*arg1 ...
 
 		// arg0 = pointer to start of memory to zero
-		// arg1 = value to store (will always be zero)
-		// arg2 = mem
+		// arg1 = mem
 		// auxint = # of bytes to zero
 		// returns mem
 		{
 			name:      "DUFFZERO",
 			aux:       "Int64",
-			argLength: 3,
+			argLength: 2,
 			reg: regInfo{
-				inputs:   []regMask{buildReg("DI"), buildReg("X0")},
+				inputs:   []regMask{buildReg("DI")},
 				clobbers: buildReg("DI"),
 			},
 			faultOnNilArg0: true,
 			unsafePoint:    true, // FP maintenance around DUFFCOPY can be clobbered by interrupts
 		},
-		{name: "MOVOconst", reg: regInfo{nil, 0, []regMask{fp}}, typ: "Int128", aux: "Int128", rematerializeable: true},
 
 		// arg0 = address of memory to zero
 		// arg1 = # of 8-byte words to zero
@@ -772,9 +761,10 @@
 			faultOnNilArg0: true,
 		},
 
-		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                              // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("DX"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
-		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                        // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
+		// With a register ABI, the actual register info for these instructions (i.e., what is used in regalloc) is augmented with per-call-site bindings of additional arguments to specific in and out registers.
+		{name: "CALLstatic", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                              // call static function aux.(*obj.LSym).  last arg=mem, auxint=argsize, returns mem
+		{name: "CALLclosure", argLength: -1, reg: regInfo{inputs: []regMask{gpsp, buildReg("DX"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, last arg=mem, auxint=argsize, returns mem
+		{name: "CALLinter", argLength: -1, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                        // call fn by pointer.  arg0=codeptr, last arg=mem, auxint=argsize, returns mem
 
 		// arg0 = destination pointer
 		// arg1 = source pointer
@@ -835,7 +825,7 @@
 		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
 		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
 		// It saves all GP registers if necessary, but may clobber others.
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), buildReg("AX CX DX BX BP SI R8 R9")}, clobbers: callerSave &^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), buildReg("AX CX DX BX BP SI R8 R9")}, clobbers: callerSave &^ (gp | g)}, clobberFlags: true, aux: "Sym", symEffect: "None"},
 
 		{name: "LoweredHasCPUFeature", argLength: 0, reg: gp01, rematerializeable: true, typ: "UInt64", aux: "Sym", symEffect: "None"},
 
@@ -932,15 +922,18 @@
 	}
 
 	archs = append(archs, arch{
-		name:            "AMD64",
-		pkg:             "cmd/internal/obj/x86",
-		genfile:         "../../amd64/ssa.go",
-		ops:             AMD64ops,
-		blocks:          AMD64blocks,
-		regnames:        regNamesAMD64,
-		gpregmask:       gp,
-		fpregmask:       fp,
-		framepointerreg: int8(num["BP"]),
-		linkreg:         -1, // not used
+		name:               "AMD64",
+		pkg:                "cmd/internal/obj/x86",
+		genfile:            "../../amd64/ssa.go",
+		ops:                AMD64ops,
+		blocks:             AMD64blocks,
+		regnames:           regNamesAMD64,
+		ParamIntRegNames:   "AX BX CX DI SI R8 R9 R10 R11",
+		ParamFloatRegNames: "X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14",
+		gpregmask:          gp,
+		fpregmask:          fp,
+		specialregmask:     x15,
+		framepointerreg:    int8(num["BP"]),
+		linkreg:            -1, // not used
 	})
 }
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64splitload.rules b/src/cmd/compile/internal/ssa/gen/AMD64splitload.rules
index a50d509..dd8f8ac 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64splitload.rules
+++ b/src/cmd/compile/internal/ssa/gen/AMD64splitload.rules
@@ -18,28 +18,28 @@
 
 (CMP(Q|L|W|B)load {sym} [off] ptr x mem) => (CMP(Q|L|W|B) (MOV(Q|L|W|B)load {sym} [off] ptr mem) x)
 
-(CMP(Q|L|W|B)constload {sym} [vo] ptr mem) && vo.Val() == 0 => (TEST(Q|L|W|B) x:(MOV(Q|L|W|B)load {sym} [vo.Off32()] ptr mem) x)
+(CMP(Q|L|W|B)constload {sym} [vo] ptr mem) && vo.Val() == 0 => (TEST(Q|L|W|B) x:(MOV(Q|L|W|B)load {sym} [vo.Off()] ptr mem) x)
 
-(CMPQconstload {sym} [vo] ptr mem) && vo.Val() != 0 => (CMPQconst (MOVQload {sym} [vo.Off32()] ptr mem) [vo.Val32()])
-(CMPLconstload {sym} [vo] ptr mem) && vo.Val() != 0 => (CMPLconst (MOVLload {sym} [vo.Off32()] ptr mem) [vo.Val32()])
-(CMPWconstload {sym} [vo] ptr mem) && vo.Val() != 0 => (CMPWconst (MOVWload {sym} [vo.Off32()] ptr mem) [vo.Val16()])
-(CMPBconstload {sym} [vo] ptr mem) && vo.Val() != 0 => (CMPBconst (MOVBload {sym} [vo.Off32()] ptr mem) [vo.Val8()])
+(CMPQconstload {sym} [vo] ptr mem) && vo.Val() != 0 => (CMPQconst (MOVQload {sym} [vo.Off()] ptr mem) [vo.Val()])
+(CMPLconstload {sym} [vo] ptr mem) && vo.Val() != 0 => (CMPLconst (MOVLload {sym} [vo.Off()] ptr mem) [vo.Val()])
+(CMPWconstload {sym} [vo] ptr mem) && vo.Val() != 0 => (CMPWconst (MOVWload {sym} [vo.Off()] ptr mem) [vo.Val16()])
+(CMPBconstload {sym} [vo] ptr mem) && vo.Val() != 0 => (CMPBconst (MOVBload {sym} [vo.Off()] ptr mem) [vo.Val8()])
 
 (CMP(Q|L|W|B)loadidx1 {sym} [off] ptr idx x mem) => (CMP(Q|L|W|B) (MOV(Q|L|W|B)loadidx1 {sym} [off] ptr idx mem) x)
 (CMPQloadidx8 {sym} [off] ptr idx x mem) => (CMPQ (MOVQloadidx8 {sym} [off] ptr idx mem) x)
 (CMPLloadidx4 {sym} [off] ptr idx x mem) => (CMPL (MOVLloadidx4 {sym} [off] ptr idx mem) x)
 (CMPWloadidx2 {sym} [off] ptr idx x mem) => (CMPW (MOVWloadidx2 {sym} [off] ptr idx mem) x)
 
-(CMP(Q|L|W|B)constloadidx1 {sym} [vo] ptr idx mem) && vo.Val() == 0 => (TEST(Q|L|W|B) x:(MOV(Q|L|W|B)loadidx1 {sym} [vo.Off32()] ptr idx mem) x)
-(CMPQconstloadidx8         {sym} [vo] ptr idx mem) && vo.Val() == 0 => (TESTQ         x:(MOVQloadidx8         {sym} [vo.Off32()] ptr idx mem) x)
-(CMPLconstloadidx4         {sym} [vo] ptr idx mem) && vo.Val() == 0 => (TESTL         x:(MOVLloadidx4         {sym} [vo.Off32()] ptr idx mem) x)
-(CMPWconstloadidx2         {sym} [vo] ptr idx mem) && vo.Val() == 0 => (TESTW         x:(MOVWloadidx2         {sym} [vo.Off32()] ptr idx mem) x)
+(CMP(Q|L|W|B)constloadidx1 {sym} [vo] ptr idx mem) && vo.Val() == 0 => (TEST(Q|L|W|B) x:(MOV(Q|L|W|B)loadidx1 {sym} [vo.Off()] ptr idx mem) x)
+(CMPQconstloadidx8         {sym} [vo] ptr idx mem) && vo.Val() == 0 => (TESTQ         x:(MOVQloadidx8         {sym} [vo.Off()] ptr idx mem) x)
+(CMPLconstloadidx4         {sym} [vo] ptr idx mem) && vo.Val() == 0 => (TESTL         x:(MOVLloadidx4         {sym} [vo.Off()] ptr idx mem) x)
+(CMPWconstloadidx2         {sym} [vo] ptr idx mem) && vo.Val() == 0 => (TESTW         x:(MOVWloadidx2         {sym} [vo.Off()] ptr idx mem) x)
 
-(CMPQconstloadidx1 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPQconst (MOVQloadidx1 {sym} [vo.Off32()] ptr idx mem) [vo.Val32()])
-(CMPLconstloadidx1 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPLconst (MOVLloadidx1 {sym} [vo.Off32()] ptr idx mem) [vo.Val32()])
-(CMPWconstloadidx1 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPWconst (MOVWloadidx1 {sym} [vo.Off32()] ptr idx mem) [vo.Val16()])
-(CMPBconstloadidx1 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPBconst (MOVBloadidx1 {sym} [vo.Off32()] ptr idx mem) [vo.Val8()])
+(CMPQconstloadidx1 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPQconst (MOVQloadidx1 {sym} [vo.Off()] ptr idx mem) [vo.Val()])
+(CMPLconstloadidx1 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPLconst (MOVLloadidx1 {sym} [vo.Off()] ptr idx mem) [vo.Val()])
+(CMPWconstloadidx1 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPWconst (MOVWloadidx1 {sym} [vo.Off()] ptr idx mem) [vo.Val16()])
+(CMPBconstloadidx1 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPBconst (MOVBloadidx1 {sym} [vo.Off()] ptr idx mem) [vo.Val8()])
 
-(CMPQconstloadidx8 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPQconst (MOVQloadidx8 {sym} [vo.Off32()] ptr idx mem) [vo.Val32()])
-(CMPLconstloadidx4 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPLconst (MOVLloadidx4 {sym} [vo.Off32()] ptr idx mem) [vo.Val32()])
-(CMPWconstloadidx2 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPWconst (MOVWloadidx2 {sym} [vo.Off32()] ptr idx mem) [vo.Val16()])
+(CMPQconstloadidx8 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPQconst (MOVQloadidx8 {sym} [vo.Off()] ptr idx mem) [vo.Val()])
+(CMPLconstloadidx4 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPLconst (MOVLloadidx4 {sym} [vo.Off()] ptr idx mem) [vo.Val()])
+(CMPWconstloadidx2 {sym} [vo] ptr idx mem) && vo.Val() != 0 => (CMPWconst (MOVWloadidx2 {sym} [vo.Off()] ptr idx mem) [vo.Val16()])
diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules
index 11c36b5..bcacbaf 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM.rules
+++ b/src/cmd/compile/internal/ssa/gen/ARM.rules
@@ -56,6 +56,7 @@
 (Com(32|16|8) ...) => (MVN ...)
 
 (Sqrt ...) => (SQRTD ...)
+(Sqrt32 ...) => (SQRTF ...)
 (Abs ...) => (ABSD ...)
 
 // TODO: optimize this for ARMv5 and ARMv6
@@ -65,17 +66,17 @@
 
 // count trailing zero for ARMv5 and ARMv6
 // 32 - CLZ(x&-x - 1)
-(Ctz32 <t> x) && objabi.GOARM<=6 =>
+(Ctz32 <t> x) && buildcfg.GOARM<=6 =>
 	(RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1])))
-(Ctz16 <t> x) && objabi.GOARM<=6 =>
+(Ctz16 <t> x) && buildcfg.GOARM<=6 =>
 	(RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x10000] x))) [1])))
-(Ctz8 <t> x) && objabi.GOARM<=6 =>
+(Ctz8 <t> x) && buildcfg.GOARM<=6 =>
 	(RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x100] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x100] x))) [1])))
 
 // count trailing zero for ARMv7
-(Ctz32 <t> x) && objabi.GOARM==7 => (CLZ <t> (RBIT <t> x))
-(Ctz16 <t> x) && objabi.GOARM==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x)))
-(Ctz8 <t> x) && objabi.GOARM==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x100] x)))
+(Ctz32 <t> x) && buildcfg.GOARM==7 => (CLZ <t> (RBIT <t> x))
+(Ctz16 <t> x) && buildcfg.GOARM==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x)))
+(Ctz8 <t> x) && buildcfg.GOARM==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x100] x)))
 
 // bit length
 (BitLen32 <t> x) => (RSBconst [32] (CLZ <t> x))
@@ -89,13 +90,13 @@
 // t5 = x right rotate 8 bits  -- (d,   a,   b,   c  )
 // result = t4 ^ t5            -- (d,   c,   b,   a  )
 // using shifted ops this can be done in 4 instructions.
-(Bswap32 <t> x) && objabi.GOARM==5 =>
+(Bswap32 <t> x) && buildcfg.GOARM==5 =>
 	(XOR <t>
 		(SRLconst <t> (BICconst <t> (XOR <t> x (SRRconst <t> [16] x)) [0xff0000]) [8])
 		(SRRconst <t> x [8]))
 
 // byte swap for ARMv6 and above
-(Bswap32 x) && objabi.GOARM>=6 => (REV x)
+(Bswap32 x) && buildcfg.GOARM>=6 => (REV x)
 
 // boolean ops -- booleans are represented with 0=false, 1=true
 (AndB ...) => (AND ...)
@@ -172,7 +173,7 @@
 (Const(8|16|32) [val]) => (MOVWconst [int32(val)])
 (Const(32|64)F [val]) => (MOV(F|D)const [float64(val)])
 (ConstNil) => (MOVWconst [0])
-(ConstBool [b]) => (MOVWconst [b2i32(b)])
+(ConstBool [t]) => (MOVWconst [b2i32(t)])
 
 // truncations
 // Because we ignore high parts of registers, truncates are just copies.
@@ -507,7 +508,7 @@
 (TEQ x (MOVWconst [c])) => (TEQconst [c] x)
 
 // Canonicalize the order of arguments to comparisons - helps with CSE.
-(CMP x y) && x.ID > y.ID => (InvertFlags (CMP y x))
+(CMP x y) && canonLessThan(x,y) => (InvertFlags (CMP y x))
 
 // don't extend after proper load
 // MOVWreg instruction is not emitted if src and dst registers are same, but it ensures the type.
@@ -546,6 +547,10 @@
 // MOVWnop doesn't emit instruction, only for ensuring the type.
 (MOVWreg x) && x.Uses == 1 => (MOVWnop x)
 
+// TODO: we should be able to get rid of MOVWnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVWnop (MOVWconst [c])) => (MOVWconst [c])
+
 // mul by constant
 (MUL x (MOVWconst [c])) && int32(c) == -1 => (RSBconst [0] x)
 (MUL _ (MOVWconst [0])) => (MOVWconst [0])
@@ -732,10 +737,10 @@
 (SUBconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) => (ADDconst [-c] x)
 (ANDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) => (BICconst [int32(^uint32(c))] x)
 (BICconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) => (ANDconst [int32(^uint32(c))] x)
-(ADDconst [c] x) && objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (SUBconst [-c] x)
-(SUBconst [c] x) && objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (ADDconst [-c] x)
-(ANDconst [c] x) && objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (BICconst [int32(^uint32(c))] x)
-(BICconst [c] x) && objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (ANDconst [int32(^uint32(c))] x)
+(ADDconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (SUBconst [-c] x)
+(SUBconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (ADDconst [-c] x)
+(ANDconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (BICconst [int32(^uint32(c))] x)
+(BICconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (ANDconst [int32(^uint32(c))] x)
 (ADDconst [c] (MOVWconst [d])) => (MOVWconst [c+d])
 (ADDconst [c] (ADDconst [d] x)) => (ADDconst [c+d] x)
 (ADDconst [c] (SUBconst [d] x)) => (ADDconst [c-d] x)
@@ -1139,7 +1144,7 @@
 // UBFX instruction is supported by ARMv6T2, ARMv7 and above versions, REV16 is supported by
 // ARMv6 and above versions. So for ARMv6, we need to match SLLconst, SRLconst and ORshiftLL.
 ((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x) => (REV16 x)
-((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x) && objabi.GOARM>=6 => (REV16 x)
+((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x) && buildcfg.GOARM>=6 => (REV16 x)
 
 // use indexed loads and stores
 (MOVWload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVWloadidx ptr idx mem)
@@ -1209,25 +1214,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)
+(SUB a (MUL x y)) && buildcfg.GOARM == 7 => (MULS x y a)
+(RSB (MUL x y) a) && buildcfg.GOARM == 7 => (MULS x y a)
 
-(NEGF (MULF x y)) && 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)
+(NEGF (MULF x y)) && buildcfg.GOARM >= 6 => (NMULF x y)
+(NEGD (MULD x y)) && buildcfg.GOARM >= 6 => (NMULD x y)
+(MULF (NEGF x) y) && buildcfg.GOARM >= 6 => (NMULF x y)
+(MULD (NEGD x) y) && buildcfg.GOARM >= 6 => (NMULD x y)
 (NMULF (NEGF x) y) => (MULF x y)
 (NMULD (NEGD x) y) => (MULD x y)
 
 // the result will overwrite the addend, since they are in the same register
-(ADDF a (MULF x y)) && a.Uses == 1 && 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)
+(ADDF a (MULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAF a x y)
+(ADDF a (NMULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSF a x y)
+(ADDD a (MULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAD a x y)
+(ADDD a (NMULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSD a x y)
+(SUBF a (MULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSF a x y)
+(SUBF a (NMULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAF a x y)
+(SUBD a (MULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSD a x y)
+(SUBD a (NMULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAD a x y)
 
 (AND x (MVN y)) => (BIC x y)
 
@@ -1259,8 +1264,8 @@
 (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)
+(SRAconst (SLLconst x [c]) [d]) && buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFX [(d-c)|(32-d)<<8] x)
+(SRLconst (SLLconst x [c]) [d]) && buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFXU [(d-c)|(32-d)<<8] x)
 
 // comparison simplification
 ((LT|LE|EQ|NE|GE|GT) (CMP x (RSBconst [0] y))) => ((LT|LE|EQ|NE|GE|GT) (CMN x y)) // sense of carry bit not preserved
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64.rules b/src/cmd/compile/internal/ssa/gen/ARM64.rules
index 3f4d0c1..62699f2 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM64.rules
+++ b/src/cmd/compile/internal/ssa/gen/ARM64.rules
@@ -60,6 +60,8 @@
 (Trunc ...) => (FRINTZD ...)
 (FMA x y z) => (FMADDD z x y)
 
+(Sqrt32 ...) => (FSQRTS ...)
+
 // lowering rotates
 (RotateLeft8 <t> x (MOVDconst [c])) => (Or8 (Lsh8x64 <t> x (MOVDconst [c&7])) (Rsh8Ux64 <t> x (MOVDconst [-c&7])))
 (RotateLeft16 <t> x (MOVDconst [c])) => (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
@@ -196,7 +198,7 @@
 (Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])
 (Const(32F|64F) [val]) => (FMOV(S|D)const [float64(val)])
 (ConstNil) => (MOVDconst [0])
-(ConstBool [b]) => (MOVDconst [b2i(b)])
+(ConstBool [t]) => (MOVDconst [b2i(t)])
 
 (Slicemask <t> x) => (SRAconst (NEG <t> x) [63])
 
@@ -792,6 +794,15 @@
 (MOVHUloadidx2 ptr (MOVDconst [c]) mem) && is32Bit(c<<1) => (MOVHUload [int32(c)<<1] ptr mem)
 (MOVHloadidx2  ptr (MOVDconst [c]) mem) && is32Bit(c<<1) => (MOVHload  [int32(c)<<1] ptr mem)
 
+(FMOVDload [off] {sym} (ADDshiftLL [3] ptr idx) mem) && off == 0 && sym == nil => (FMOVDloadidx8 ptr idx mem)
+(FMOVSload [off] {sym} (ADDshiftLL [2] ptr idx) mem) && off == 0 && sym == nil => (FMOVSloadidx4 ptr idx mem)
+(FMOVDloadidx ptr (SLLconst [3] idx) mem) => (FMOVDloadidx8 ptr idx mem)
+(FMOVSloadidx ptr (SLLconst [2] idx) mem) => (FMOVSloadidx4 ptr idx mem)
+(FMOVDloadidx (SLLconst [3] idx) ptr mem) => (FMOVDloadidx8 ptr idx mem)
+(FMOVSloadidx (SLLconst [2] idx) ptr mem) => (FMOVSloadidx4 ptr idx mem)
+(FMOVDloadidx8 ptr (MOVDconst [c]) mem) && is32Bit(c<<3) => (FMOVDload ptr [int32(c)<<3] mem)
+(FMOVSloadidx4 ptr (MOVDconst [c]) mem) && is32Bit(c<<2) => (FMOVSload ptr [int32(c)<<2] mem)
+
 (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
 	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
 	(MOVBstore [off1+int32(off2)] {sym} ptr val mem)
@@ -865,6 +876,15 @@
 (MOVWstoreidx4 ptr (MOVDconst [c]) val mem) && is32Bit(c<<2) => (MOVWstore [int32(c)<<2] ptr val mem)
 (MOVHstoreidx2 ptr (MOVDconst [c]) val mem) && is32Bit(c<<1) => (MOVHstore [int32(c)<<1] ptr val mem)
 
+(FMOVDstore [off] {sym} (ADDshiftLL [3] ptr idx) val mem) && off == 0 && sym == nil => (FMOVDstoreidx8 ptr idx val mem)
+(FMOVSstore [off] {sym} (ADDshiftLL [2] ptr idx) val mem) && off == 0 && sym == nil => (FMOVSstoreidx4 ptr idx val mem)
+(FMOVDstoreidx ptr (SLLconst [3] idx) val mem) => (FMOVDstoreidx8 ptr idx val mem)
+(FMOVSstoreidx ptr (SLLconst [2] idx) val mem) => (FMOVSstoreidx4 ptr idx val mem)
+(FMOVDstoreidx (SLLconst [3] idx) ptr val mem) => (FMOVDstoreidx8 ptr idx val mem)
+(FMOVSstoreidx (SLLconst [2] idx) ptr val mem) => (FMOVSstoreidx4 ptr idx val mem)
+(FMOVDstoreidx8 ptr (MOVDconst [c]) val mem) && is32Bit(c<<3) => (FMOVDstore [int32(c)<<3] ptr val mem)
+(FMOVSstoreidx4 ptr (MOVDconst [c]) val mem) && is32Bit(c<<2) => (FMOVSstore [int32(c)<<2] ptr val mem)
+
 (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
 	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
@@ -1127,6 +1147,10 @@
 // MOVDnop doesn't emit instruction, only for ensuring the type.
 (MOVDreg x) && x.Uses == 1 => (MOVDnop x)
 
+// TODO: we should be able to get rid of MOVDnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVDnop (MOVDconst [c])) => (MOVDconst [c])
+
 // fold constant into arithmatic ops
 (ADD x (MOVDconst [c])) => (ADDconst [c] x)
 (SUB x (MOVDconst [c])) => (SUBconst [c] x)
@@ -1151,7 +1175,7 @@
 (CMPW (MOVDconst [c]) x) => (InvertFlags (CMPWconst [int32(c)] x))
 
 // Canonicalize the order of arguments to comparisons - helps with CSE.
-((CMP|CMPW) x y) && x.ID > y.ID => (InvertFlags ((CMP|CMPW) y x))
+((CMP|CMPW) x y) && canonLessThan(x,y) => (InvertFlags ((CMP|CMPW) y x))
 
 // mul-neg => mneg
 (NEG (MUL x y)) => (MNEG x y)
@@ -1335,8 +1359,18 @@
 (XOR x (MVN y)) => (EON x y)
 (OR  x (MVN y)) => (ORN x y)
 (MVN (XOR x y)) => (EON x y)
+
+(CSEL [cc] (MOVDconst [-1]) (MOVDconst [0]) flag) => (CSETM [cc] flag)
+(CSEL [cc] (MOVDconst [0]) (MOVDconst [-1]) flag) => (CSETM [arm64Negate(cc)] flag)
 (CSEL [cc] x (MOVDconst [0]) flag) => (CSEL0 [cc] x flag)
 (CSEL [cc] (MOVDconst [0]) y flag) => (CSEL0 [arm64Negate(cc)] y flag)
+(CSEL [cc] x (ADDconst [1] a) flag) => (CSINC [cc] x a flag)
+(CSEL [cc] (ADDconst [1] a) x flag) => (CSINC [arm64Negate(cc)] x a flag)
+(CSEL [cc] x (MVN a) flag) => (CSINV [cc] x a flag)
+(CSEL [cc] (MVN a) x flag) => (CSINV [arm64Negate(cc)] x a flag)
+(CSEL [cc] x (NEG a) flag) => (CSNEG [cc] x a flag)
+(CSEL [cc] (NEG a) x flag) => (CSNEG [arm64Negate(cc)] x a flag)
+
 (SUB x (SUB y z)) => (SUB (ADD <v.Type> x z) y)
 (SUB (SUB x y) z) => (SUB x (ADD <y.Type> y z))
 
@@ -1491,9 +1525,13 @@
 (LEnoov (InvertFlags cmp) yes no) => (GEnoov cmp yes no)
 (GTnoov (InvertFlags cmp) yes no) => (LTnoov cmp yes no)
 
-// absorb InvertFlags into CSEL(0)
+// absorb InvertFlags into conditional instructions
 (CSEL [cc] x y (InvertFlags cmp)) => (CSEL [arm64Invert(cc)] x y cmp)
 (CSEL0 [cc] x (InvertFlags cmp)) => (CSEL0 [arm64Invert(cc)] x cmp)
+(CSETM [cc] (InvertFlags cmp)) => (CSETM [arm64Invert(cc)] cmp)
+(CSINC [cc] x y (InvertFlags cmp)) => (CSINC [arm64Invert(cc)] x y cmp)
+(CSINV [cc] x y (InvertFlags cmp)) => (CSINV [arm64Invert(cc)] x y cmp)
+(CSNEG [cc] x y (InvertFlags cmp)) => (CSNEG [arm64Invert(cc)] x y cmp)
 
 // absorb flag constants into boolean values
 (Equal (FlagConstant [fc])) => (MOVDconst [b2i(fc.eq())])
@@ -1532,6 +1570,14 @@
 (CSEL [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => y
 (CSEL0 [cc] x flag) && ccARM64Eval(cc, flag) > 0 => x
 (CSEL0 [cc] _ flag) && ccARM64Eval(cc, flag) < 0 => (MOVDconst [0])
+(CSNEG [cc] x _ flag) && ccARM64Eval(cc, flag) > 0 => x
+(CSNEG [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => (NEG y)
+(CSINV [cc] x _ flag) && ccARM64Eval(cc, flag) > 0 => x
+(CSINV [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => (Not y)
+(CSINC [cc] x _ flag) && ccARM64Eval(cc, flag) > 0 => x
+(CSINC [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => (ADDconst [1] y)
+(CSETM [cc] flag) && ccARM64Eval(cc, flag) > 0 => (MOVDconst [-1])
+(CSETM [cc] flag) && ccARM64Eval(cc, flag) < 0 => (MOVDconst [0])
 
 // absorb flags back into boolean CSEL
 (CSEL [cc] x y (CMPWconst [0] boolval)) && cc == OpARM64NotEqual && flagArg(boolval) != nil =>
@@ -1724,9 +1770,25 @@
 		(CMPconst [64]  (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))))) && cc == OpARM64LessThanU
 	=> (RORW x y)
 
+// rev16w | rev16
 // ((x>>8) | (x<<8)) => (REV16W x), the type of x is uint16, "|" can also be "^" or "+".
 ((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (UBFX <typ.UInt16> [armBFAuxInt(8, 8)] x) x) => (REV16W x)
 
+// ((x & 0xff00ff00)>>8) | ((x & 0x00ff00ff)<<8), "|" can also be "^" or "+".
+((ADDshiftLL|ORshiftLL|XORshiftLL) [8] (UBFX [armBFAuxInt(8, 24)] (ANDconst [c1] x)) (ANDconst [c2] x))
+	&& uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
+	=> (REV16W x)
+
+// ((x & 0xff00ff00ff00ff00)>>8) | ((x & 0x00ff00ff00ff00ff)<<8), "|" can also be "^" or "+".
+((ADDshiftLL|ORshiftLL|XORshiftLL) [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
+	&& (uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff)
+	=> (REV16 x)
+
+// ((x & 0xff00ff00)>>8) | ((x & 0x00ff00ff)<<8), "|" can also be "^" or "+".
+((ADDshiftLL|ORshiftLL|XORshiftLL) [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
+	&& (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff)
+	=> (REV16 (ANDconst <x.Type> [0xffffffff] x))
+
 // Extract from reg pair
 (ADDshiftLL [c] (SRLconst x [64-c]) x2) => (EXTRconst [64-c] x2 x)
 ( ORshiftLL [c] (SRLconst x [64-c]) x2) => (EXTRconst [64-c] x2 x)
@@ -1747,6 +1809,16 @@
 // Special case setting bit as 1. An example is math.Copysign(c,-1)
 (ORconst [c1] (ANDconst [c2] x)) && c2|c1 == ^0  => (ORconst [c1] x)
 
+// If the shift amount is larger than the datasize(32, 16, 8), we can optimize to constant 0.
+(MOVWUreg (SLLconst [lc] x)) && lc >= 32 => (MOVDconst [0])
+(MOVHUreg (SLLconst [lc] x)) && lc >= 16 => (MOVDconst [0])
+(MOVBUreg (SLLconst [lc] x)) && lc >= 8 => (MOVDconst [0])
+
+// After zero extension, the upper (64-datasize(32|16|8)) bits are zero, we can optimiza to constant 0.
+(SRLconst [rc] (MOVWUreg x)) && rc >= 32 => (MOVDconst [0])
+(SRLconst [rc] (MOVHUreg x)) && rc >= 16 => (MOVDconst [0])
+(SRLconst [rc] (MOVBUreg x)) && rc >= 8 => (MOVDconst [0])
+
 // bitfield ops
 
 // sbfiz
@@ -2787,3 +2859,12 @@
 (MOVHUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVDconst [int64(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
 (MOVWUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVDconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
 (MOVDload  [off] {sym} (SB) _) && symIsRO(sym) => (MOVDconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+
+// Arch-specific inlining for small or disjoint runtime.memmove
+(SelectN [0] call:(CALLstatic {sym} s1:(MOVDstore _ (MOVDconst [sz]) s2:(MOVDstore  _ src s3:(MOVDstore {t} _ dst mem)))))
+	&& sz >= 0
+	&& isSameCall(sym, "runtime.memmove")
+	&& s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
+	&& isInlinableMemmove(dst, src, sz, config)
+	&& clobber(s1, s2, s3, call)
+	=> (Move [sz] dst src mem)
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
index b0bc9c7..18a5666 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 package main
@@ -236,8 +237,10 @@
 		{name: "FNEGS", argLength: 1, reg: fp11, asm: "FNEGS"},                                // -arg0, float32
 		{name: "FNEGD", argLength: 1, reg: fp11, asm: "FNEGD"},                                // -arg0, float64
 		{name: "FSQRTD", argLength: 1, reg: fp11, asm: "FSQRTD"},                              // sqrt(arg0), float64
+		{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"},                              // sqrt(arg0), float32
 		{name: "REV", argLength: 1, reg: gp11, asm: "REV"},                                    // byte reverse, 64-bit
 		{name: "REVW", argLength: 1, reg: gp11, asm: "REVW"},                                  // byte reverse, 32-bit
+		{name: "REV16", argLength: 1, reg: gp11, asm: "REV16"},                                // byte reverse in each 16-bit halfword, 64-bit
 		{name: "REV16W", argLength: 1, reg: gp11, asm: "REV16W"},                              // byte reverse in each 16-bit halfword, 32-bit
 		{name: "RBIT", argLength: 1, reg: gp11, asm: "RBIT"},                                  // bit reverse, 64-bit
 		{name: "RBITW", argLength: 1, reg: gp11, asm: "RBITW"},                                // bit reverse, 32-bit
@@ -264,17 +267,17 @@
 
 		// shifts
 		{name: "SLL", argLength: 2, reg: gp21, asm: "LSL"},                        // arg0 << arg1, shift amount is mod 64
-		{name: "SLLconst", argLength: 1, reg: gp11, asm: "LSL", aux: "Int64"},     // arg0 << auxInt
+		{name: "SLLconst", argLength: 1, reg: gp11, asm: "LSL", aux: "Int64"},     // arg0 << auxInt, auxInt should be in the range 0 to 63.
 		{name: "SRL", argLength: 2, reg: gp21, asm: "LSR"},                        // arg0 >> arg1, unsigned, shift amount is mod 64
-		{name: "SRLconst", argLength: 1, reg: gp11, asm: "LSR", aux: "Int64"},     // arg0 >> auxInt, unsigned
+		{name: "SRLconst", argLength: 1, reg: gp11, asm: "LSR", aux: "Int64"},     // arg0 >> auxInt, unsigned, auxInt should be in the range 0 to 63.
 		{name: "SRA", argLength: 2, reg: gp21, asm: "ASR"},                        // arg0 >> arg1, signed, shift amount is mod 64
-		{name: "SRAconst", argLength: 1, reg: gp11, asm: "ASR", aux: "Int64"},     // arg0 >> auxInt, signed
+		{name: "SRAconst", argLength: 1, reg: gp11, asm: "ASR", aux: "Int64"},     // arg0 >> auxInt, signed, auxInt should be in the range 0 to 63.
 		{name: "ROR", argLength: 2, reg: gp21, asm: "ROR"},                        // arg0 right rotate by (arg1 mod 64) bits
 		{name: "RORW", argLength: 2, reg: gp21, asm: "RORW"},                      // arg0 right rotate by (arg1 mod 32) bits
-		{name: "RORconst", argLength: 1, reg: gp11, asm: "ROR", aux: "Int64"},     // arg0 right rotate by auxInt bits
-		{name: "RORWconst", argLength: 1, reg: gp11, asm: "RORW", aux: "Int64"},   // uint32(arg0) right rotate by auxInt bits
-		{name: "EXTRconst", argLength: 2, reg: gp21, asm: "EXTR", aux: "Int64"},   // extract 64 bits from arg0:arg1 starting at lsb auxInt
-		{name: "EXTRWconst", argLength: 2, reg: gp21, asm: "EXTRW", aux: "Int64"}, // extract 32 bits from arg0[31:0]:arg1[31:0] starting at lsb auxInt and zero top 32 bits
+		{name: "RORconst", argLength: 1, reg: gp11, asm: "ROR", aux: "Int64"},     // arg0 right rotate by auxInt bits, auxInt should be in the range 0 to 63.
+		{name: "RORWconst", argLength: 1, reg: gp11, asm: "RORW", aux: "Int64"},   // uint32(arg0) right rotate by auxInt bits, auxInt should be in the range 0 to 31.
+		{name: "EXTRconst", argLength: 2, reg: gp21, asm: "EXTR", aux: "Int64"},   // extract 64 bits from arg0:arg1 starting at lsb auxInt, auxInt should be in the range 0 to 63.
+		{name: "EXTRWconst", argLength: 2, reg: gp21, asm: "EXTRW", aux: "Int64"}, // extract 32 bits from arg0[31:0]:arg1[31:0] starting at lsb auxInt and zero top 32 bits, auxInt should be in the range 0 to 31.
 
 		// comparisons
 		{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"},                      // arg0 compare to arg1
@@ -295,45 +298,45 @@
 		{name: "FCMPD0", argLength: 1, reg: fp1flags, asm: "FCMPD", typ: "Flags"},                 // arg0 compare to 0, float64
 
 		// shifted ops
-		{name: "MVNshiftLL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0<<auxInt)
-		{name: "MVNshiftRL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0>>auxInt), unsigned shift
-		{name: "MVNshiftRA", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0>>auxInt), signed shift
-		{name: "NEGshiftLL", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0<<auxInt)
-		{name: "NEGshiftRL", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0>>auxInt), unsigned shift
-		{name: "NEGshiftRA", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0>>auxInt), signed shift
-		{name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1<<auxInt
-		{name: "ADDshiftRL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1>>auxInt, unsigned shift
-		{name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1>>auxInt, signed shift
-		{name: "SUBshiftLL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int64"},                   // arg0 - arg1<<auxInt
-		{name: "SUBshiftRL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int64"},                   // arg0 - arg1>>auxInt, unsigned shift
-		{name: "SUBshiftRA", argLength: 2, reg: gp21, asm: "SUB", aux: "Int64"},                   // arg0 - arg1>>auxInt, signed shift
-		{name: "ANDshiftLL", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1<<auxInt)
-		{name: "ANDshiftRL", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1>>auxInt), unsigned shift
-		{name: "ANDshiftRA", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1>>auxInt), signed shift
-		{name: "ORshiftLL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1<<auxInt
-		{name: "ORshiftRL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1>>auxInt, unsigned shift
-		{name: "ORshiftRA", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1>>auxInt, signed shift
-		{name: "XORshiftLL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1<<auxInt
-		{name: "XORshiftRL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1>>auxInt, unsigned shift
-		{name: "XORshiftRA", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1>>auxInt, signed shift
-		{name: "BICshiftLL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1<<auxInt)
-		{name: "BICshiftRL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1>>auxInt), unsigned shift
-		{name: "BICshiftRA", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1>>auxInt), signed shift
-		{name: "EONshiftLL", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1<<auxInt)
-		{name: "EONshiftRL", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1>>auxInt), unsigned shift
-		{name: "EONshiftRA", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1>>auxInt), signed shift
-		{name: "ORNshiftLL", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1<<auxInt)
-		{name: "ORNshiftRL", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1>>auxInt), unsigned shift
-		{name: "ORNshiftRA", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1>>auxInt), signed shift
-		{name: "CMPshiftLL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1<<auxInt
-		{name: "CMPshiftRL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1>>auxInt, unsigned shift
-		{name: "CMPshiftRA", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1>>auxInt, signed shift
-		{name: "CMNshiftLL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1<<auxInt) compare to 0
-		{name: "CMNshiftRL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1>>auxInt) compare to 0, unsigned shift
-		{name: "CMNshiftRA", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1>>auxInt) compare to 0, signed shift
-		{name: "TSTshiftLL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1<<auxInt) compare to 0
-		{name: "TSTshiftRL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1>>auxInt) compare to 0, unsigned shift
-		{name: "TSTshiftRA", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1>>auxInt) compare to 0, signed shift
+		{name: "MVNshiftLL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0<<auxInt), auxInt should be in the range 0 to 63.
+		{name: "MVNshiftRL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "MVNshiftRA", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0>>auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "NEGshiftLL", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0<<auxInt), auxInt should be in the range 0 to 63.
+		{name: "NEGshiftRL", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "NEGshiftRA", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0>>auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1<<auxInt, auxInt should be in the range 0 to 63.
+		{name: "ADDshiftRL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
+		{name: "SUBshiftLL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int64"},                   // arg0 - arg1<<auxInt, auxInt should be in the range 0 to 63.
+		{name: "SUBshiftRL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int64"},                   // arg0 - arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "SUBshiftRA", argLength: 2, reg: gp21, asm: "SUB", aux: "Int64"},                   // arg0 - arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
+		{name: "ANDshiftLL", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1<<auxInt), auxInt should be in the range 0 to 63.
+		{name: "ANDshiftRL", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "ANDshiftRA", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "ORshiftLL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1<<auxInt, auxInt should be in the range 0 to 63.
+		{name: "ORshiftRL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "ORshiftRA", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
+		{name: "XORshiftLL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1<<auxInt, auxInt should be in the range 0 to 63.
+		{name: "XORshiftRL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "XORshiftRA", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
+		{name: "BICshiftLL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1<<auxInt), auxInt should be in the range 0 to 63.
+		{name: "BICshiftRL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "BICshiftRA", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "EONshiftLL", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1<<auxInt), auxInt should be in the range 0 to 63.
+		{name: "EONshiftRL", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "EONshiftRA", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "ORNshiftLL", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1<<auxInt), auxInt should be in the range 0 to 63.
+		{name: "ORNshiftRL", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "ORNshiftRA", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "CMPshiftLL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1<<auxInt, auxInt should be in the range 0 to 63.
+		{name: "CMPshiftRL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "CMPshiftRA", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
+		{name: "CMNshiftLL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1<<auxInt) compare to 0, auxInt should be in the range 0 to 63.
+		{name: "CMNshiftRL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1>>auxInt) compare to 0, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "CMNshiftRA", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1>>auxInt) compare to 0, signed shift, auxInt should be in the range 0 to 63.
+		{name: "TSTshiftLL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1<<auxInt) compare to 0, auxInt should be in the range 0 to 63.
+		{name: "TSTshiftRL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1>>auxInt) compare to 0, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "TSTshiftRA", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1>>auxInt) compare to 0, signed shift, auxInt should be in the range 0 to 63.
 
 		// bitfield ops
 		// for all bitfield ops lsb is auxInt>>8, width is auxInt&0xff
@@ -379,11 +382,13 @@
 		{name: "FMOVDloadidx", argLength: 3, reg: fp2load, asm: "FMOVD", typ: "Float64"}, // load 64-bit float from arg0 + arg1, arg2=mem.
 
 		// shifted register indexed load
-		{name: "MOVHloadidx2", argLength: 3, reg: gp2load, asm: "MOVH", typ: "Int16"},    // load 16-bit half-word from arg0 + arg1*2, sign-extended to 64-bit, arg2=mem.
-		{name: "MOVHUloadidx2", argLength: 3, reg: gp2load, asm: "MOVHU", typ: "UInt16"}, // load 16-bit half-word from arg0 + arg1*2, zero-extended to 64-bit, arg2=mem.
-		{name: "MOVWloadidx4", argLength: 3, reg: gp2load, asm: "MOVW", typ: "Int32"},    // load 32-bit word from arg0 + arg1*4, sign-extended to 64-bit, arg2=mem.
-		{name: "MOVWUloadidx4", argLength: 3, reg: gp2load, asm: "MOVWU", typ: "UInt32"}, // load 32-bit word from arg0 + arg1*4, zero-extended to 64-bit, arg2=mem.
-		{name: "MOVDloadidx8", argLength: 3, reg: gp2load, asm: "MOVD", typ: "UInt64"},   // load 64-bit double-word from arg0 + arg1*8, arg2 = mem.
+		{name: "MOVHloadidx2", argLength: 3, reg: gp2load, asm: "MOVH", typ: "Int16"},     // load 16-bit half-word from arg0 + arg1*2, sign-extended to 64-bit, arg2=mem.
+		{name: "MOVHUloadidx2", argLength: 3, reg: gp2load, asm: "MOVHU", typ: "UInt16"},  // load 16-bit half-word from arg0 + arg1*2, zero-extended to 64-bit, arg2=mem.
+		{name: "MOVWloadidx4", argLength: 3, reg: gp2load, asm: "MOVW", typ: "Int32"},     // load 32-bit word from arg0 + arg1*4, sign-extended to 64-bit, arg2=mem.
+		{name: "MOVWUloadidx4", argLength: 3, reg: gp2load, asm: "MOVWU", typ: "UInt32"},  // load 32-bit word from arg0 + arg1*4, zero-extended to 64-bit, arg2=mem.
+		{name: "MOVDloadidx8", argLength: 3, reg: gp2load, asm: "MOVD", typ: "UInt64"},    // load 64-bit double-word from arg0 + arg1*8, arg2 = mem.
+		{name: "FMOVSloadidx4", argLength: 3, reg: fp2load, asm: "FMOVS", typ: "Float32"}, // load 32-bit float from arg0 + arg1*4, arg2 = mem.
+		{name: "FMOVDloadidx8", argLength: 3, reg: fp2load, asm: "FMOVD", typ: "Float64"}, // load 64-bit float from arg0 + arg1*8, arg2 = mem.
 
 		{name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 1 byte of arg1 to arg0 + auxInt + aux.  arg2=mem.
 		{name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
@@ -402,9 +407,11 @@
 		{name: "FMOVDstoreidx", argLength: 4, reg: fpstore2, asm: "FMOVD", typ: "Mem"}, // store 64-bit float of arg2 to arg0 + arg1, arg3=mem.
 
 		// shifted register indexed store
-		{name: "MOVHstoreidx2", argLength: 4, reg: gpstore2, asm: "MOVH", typ: "Mem"}, // store 2 bytes of arg2 to arg0 + arg1*2, arg3 = mem.
-		{name: "MOVWstoreidx4", argLength: 4, reg: gpstore2, asm: "MOVW", typ: "Mem"}, // store 4 bytes of arg2 to arg0 + arg1*4, arg3 = mem.
-		{name: "MOVDstoreidx8", argLength: 4, reg: gpstore2, asm: "MOVD", typ: "Mem"}, // store 8 bytes of arg2 to arg0 + arg1*8, arg3 = mem.
+		{name: "MOVHstoreidx2", argLength: 4, reg: gpstore2, asm: "MOVH", typ: "Mem"},   // store 2 bytes of arg2 to arg0 + arg1*2, arg3 = mem.
+		{name: "MOVWstoreidx4", argLength: 4, reg: gpstore2, asm: "MOVW", typ: "Mem"},   // store 4 bytes of arg2 to arg0 + arg1*4, arg3 = mem.
+		{name: "MOVDstoreidx8", argLength: 4, reg: gpstore2, asm: "MOVD", typ: "Mem"},   // store 8 bytes of arg2 to arg0 + arg1*8, arg3 = mem.
+		{name: "FMOVSstoreidx4", argLength: 4, reg: fpstore2, asm: "FMOVS", typ: "Mem"}, // store 32-bit float of arg2 to arg0 + arg1*4, arg3=mem.
+		{name: "FMOVDstoreidx8", argLength: 4, reg: fpstore2, asm: "FMOVD", typ: "Mem"}, // store 64-bit float of arg2 to arg0 + arg1*8, arg3=mem.
 
 		{name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of zero to arg0 + auxInt + aux.  arg1=mem.
 		{name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
@@ -467,8 +474,12 @@
 
 		// conditional instructions; auxint is
 		// one of the arm64 comparison pseudo-ops (LessThan, LessThanU, etc.)
-		{name: "CSEL", argLength: 3, reg: gp2flags1, asm: "CSEL", aux: "CCop"},  // auxint(flags) ? arg0 : arg1
-		{name: "CSEL0", argLength: 2, reg: gp1flags1, asm: "CSEL", aux: "CCop"}, // auxint(flags) ? arg0 : 0
+		{name: "CSEL", argLength: 3, reg: gp2flags1, asm: "CSEL", aux: "CCop"},   // auxint(flags) ? arg0 : arg1
+		{name: "CSEL0", argLength: 2, reg: gp1flags1, asm: "CSEL", aux: "CCop"},  // auxint(flags) ? arg0 : 0
+		{name: "CSINC", argLength: 3, reg: gp2flags1, asm: "CSINC", aux: "CCop"}, // auxint(flags) ? arg0 : arg1 + 1
+		{name: "CSINV", argLength: 3, reg: gp2flags1, asm: "CSINV", aux: "CCop"}, // auxint(flags) ? arg0 : ^arg1
+		{name: "CSNEG", argLength: 3, reg: gp2flags1, asm: "CSNEG", aux: "CCop"}, // auxint(flags) ? arg0 : -arg1
+		{name: "CSETM", argLength: 1, reg: readflags, asm: "CSETM", aux: "CCop"}, // auxint(flags) ? -1 : 0
 
 		// function calls
 		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                               // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
@@ -502,13 +513,14 @@
 		// auxint = offset into duffzero code to start executing
 		// returns mem
 		// R20 changed as side effect
+		// R16 and R17 may be clobbered by linker trampoline.
 		{
 			name:      "DUFFZERO",
 			aux:       "Int64",
 			argLength: 2,
 			reg: regInfo{
 				inputs:   []regMask{buildReg("R20")},
-				clobbers: buildReg("R20 R30"),
+				clobbers: buildReg("R16 R17 R20 R30"),
 			},
 			faultOnNilArg0: true,
 			unsafePoint:    true, // FP maintenance around DUFFZERO can be clobbered by interrupts
@@ -542,13 +554,14 @@
 		// auxint = offset into duffcopy code to start executing
 		// returns mem
 		// R20, R21 changed as side effect
+		// R16 and R17 may be clobbered by linker trampoline.
 		{
 			name:      "DUFFCOPY",
 			aux:       "Int64",
 			argLength: 3,
 			reg: regInfo{
 				inputs:   []regMask{buildReg("R21"), buildReg("R20")},
-				clobbers: buildReg("R20 R21 R26 R30"),
+				clobbers: buildReg("R16 R17 R20 R21 R26 R30"),
 			},
 			faultOnNilArg0: true,
 			faultOnNilArg1: true,
@@ -707,7 +720,8 @@
 		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
 		// It saves all GP registers if necessary,
 		// but clobbers R30 (LR) because it's a call.
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R30")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+		// R16 and R17 may be clobbered by linker trampoline.
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R16 R17 R30")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
 
 		// There are three of these functions so that they can have three different register inputs.
 		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
diff --git a/src/cmd/compile/internal/ssa/gen/ARMOps.go b/src/cmd/compile/internal/ssa/gen/ARMOps.go
index 70c7899..d1f8603 100644
--- a/src/cmd/compile/internal/ssa/gen/ARMOps.go
+++ b/src/cmd/compile/internal/ssa/gen/ARMOps.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 package main
@@ -156,7 +157,7 @@
 			reg: regInfo{
 				inputs:   []regMask{buildReg("R1"), buildReg("R0")},
 				outputs:  []regMask{buildReg("R0"), buildReg("R1")},
-				clobbers: buildReg("R2 R3 R14"),
+				clobbers: buildReg("R2 R3 R12 R14"), // R14 is LR, R12 is linker trampoline scratch register
 			},
 			clobberFlags: true,
 			typ:          "(UInt32,UInt32)",
@@ -217,6 +218,7 @@
 		{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"},   // -arg0, float32
 		{name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"},   // -arg0, float64
 		{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
+		{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
 		{name: "ABSD", argLength: 1, reg: fp11, asm: "ABSD"},   // abs(arg0), float64
 
 		{name: "CLZ", argLength: 1, reg: gp11, asm: "CLZ"},     // count leading zero
@@ -458,7 +460,7 @@
 			argLength: 3,
 			reg: regInfo{
 				inputs:   []regMask{buildReg("R1"), buildReg("R0")},
-				clobbers: buildReg("R1 R14"),
+				clobbers: buildReg("R1 R12 R14"), // R14 is LR, R12 is linker trampoline scratch register
 			},
 			faultOnNilArg0: true,
 		},
@@ -475,7 +477,7 @@
 			argLength: 3,
 			reg: regInfo{
 				inputs:   []regMask{buildReg("R2"), buildReg("R1")},
-				clobbers: buildReg("R0 R1 R2 R14"),
+				clobbers: buildReg("R0 R1 R2 R12 R14"), // R14 is LR, R12 is linker trampoline scratch register
 			},
 			faultOnNilArg0: true,
 			faultOnNilArg1: true,
@@ -563,8 +565,8 @@
 
 		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
 		// It saves all GP registers if necessary,
-		// but clobbers R14 (LR) because it's a call.
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R14")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+		// but clobbers R14 (LR) because it's a call, and R12 which is linker trampoline scratch register.
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R12 R14")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
 	}
 
 	blocks := []blockData{
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS.rules b/src/cmd/compile/internal/ssa/gen/MIPS.rules
index 8ad2c90..4ac9668 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPS.rules
+++ b/src/cmd/compile/internal/ssa/gen/MIPS.rules
@@ -121,6 +121,7 @@
 (Com(32|16|8) x) => (NORconst [0] x)
 
 (Sqrt ...) => (SQRTD ...)
+(Sqrt32 ...) => (SQRTF ...)
 
 // TODO: optimize this case?
 (Ctz32NonZero ...) => (Ctz32 ...)
@@ -143,7 +144,7 @@
 (Const(32|16|8) [val]) => (MOVWconst [int32(val)])
 (Const(32|64)F ...) => (MOV(F|D)const ...)
 (ConstNil) => (MOVWconst [0])
-(ConstBool [b]) => (MOVWconst [b2i32(b)])
+(ConstBool [t]) => (MOVWconst [b2i32(t)])
 
 // truncations
 // Because we ignore high parts of registers, truncates are just copies.
@@ -559,6 +560,10 @@
 // MOVWnop doesn't emit instruction, only for ensuring the type.
 (MOVWreg x) && x.Uses == 1 => (MOVWnop x)
 
+// TODO: we should be able to get rid of MOVWnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVWnop (MOVWconst [c])) => (MOVWconst [c])
+
 // fold constant into arithmatic ops
 (ADD x (MOVWconst [c])) => (ADDconst [c] x)
 (SUB x (MOVWconst [c])) => (SUBconst [c] x)
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS64.rules b/src/cmd/compile/internal/ssa/gen/MIPS64.rules
index 088c9b1..fd04a6c 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPS64.rules
+++ b/src/cmd/compile/internal/ssa/gen/MIPS64.rules
@@ -121,6 +121,7 @@
 (Com(64|32|16|8) x) => (NOR (MOVVconst [0]) x)
 
 (Sqrt ...) => (SQRTD ...)
+(Sqrt32 ...) => (SQRTF ...)
 
 // boolean ops -- booleans are represented with 0=false, 1=true
 (AndB ...) => (AND ...)
@@ -133,7 +134,7 @@
 (Const(64|32|16|8) [val]) => (MOVVconst [int64(val)])
 (Const(32|64)F [val]) => (MOV(F|D)const [float64(val)])
 (ConstNil) => (MOVVconst [0])
-(ConstBool [b]) => (MOVVconst [int64(b2i(b))])
+(ConstBool [t]) => (MOVVconst [int64(b2i(t))])
 
 (Slicemask <t> x) => (SRAVconst (NEGV <t> x) [63])
 
@@ -558,6 +559,10 @@
 // MOVVnop doesn't emit instruction, only for ensuring the type.
 (MOVVreg x) && x.Uses == 1 => (MOVVnop x)
 
+// TODO: we should be able to get rid of MOVVnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVVnop (MOVVconst [c])) => (MOVVconst [c])
+
 // fold constant into arithmatic ops
 (ADDV x (MOVVconst [c])) && is32Bit(c) => (ADDVconst [c] x)
 (SUBV x (MOVVconst [c])) && is32Bit(c) => (SUBVconst [c] x)
@@ -676,3 +681,9 @@
 (GTZ (MOVVconst [c]) yes no) && c <= 0 => (First no yes)
 (GEZ (MOVVconst [c]) yes no) && c >= 0 => (First yes no)
 (GEZ (MOVVconst [c]) yes no) && c <  0 => (First no yes)
+
+// fold readonly sym load
+(MOVBload [off] {sym} (SB) _) && symIsRO(sym) => (MOVVconst [int64(read8(sym, int64(off)))])
+(MOVHload [off] {sym} (SB) _) && symIsRO(sym) => (MOVVconst [int64(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+(MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVVconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+(MOVVload  [off] {sym} (SB) _) && symIsRO(sym) => (MOVVconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))])
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go b/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
index e1e3933..77f251c 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
@@ -199,6 +199,7 @@
 		{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"},   // -arg0, float32
 		{name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"},   // -arg0, float64
 		{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
+		{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
 
 		// shifts
 		{name: "SLLV", argLength: 2, reg: gp21, asm: "SLLV"},                    // arg0 << arg1, shift amount is mod 64
diff --git a/src/cmd/compile/internal/ssa/gen/MIPSOps.go b/src/cmd/compile/internal/ssa/gen/MIPSOps.go
index 75ab99e..b92e8cb 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPSOps.go
+++ b/src/cmd/compile/internal/ssa/gen/MIPSOps.go
@@ -182,6 +182,7 @@
 		{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"},   // -arg0, float32
 		{name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"},   // -arg0, float64
 		{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
+		{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
 
 		// shifts
 		{name: "SLL", argLength: 2, reg: gp21, asm: "SLL"},                    // arg0 << arg1, shift amount is mod 32
diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules
index c064046..ce4b324 100644
--- a/src/cmd/compile/internal/ssa/gen/PPC64.rules
+++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules
@@ -12,20 +12,20 @@
 (Sub64F ...) => (FSUB ...)
 
 // Combine 64 bit integer multiply and adds
-(ADD l:(MULLD x y) z) && objabi.GOPPC64 >= 9 && l.Uses == 1 && clobber(l) => (MADDLD x y z)
+(ADD l:(MULLD x y) z) && buildcfg.GOPPC64 >= 9 && l.Uses == 1 && clobber(l) => (MADDLD x y z)
 
 (Mod16 x y) => (Mod32 (SignExt16to32 x) (SignExt16to32 y))
 (Mod16u x y) => (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y))
 (Mod8 x y) => (Mod32 (SignExt8to32 x) (SignExt8to32 y))
 (Mod8u x y) => (Mod32u (ZeroExt8to32 x) (ZeroExt8to32 y))
-(Mod64 x y) && objabi.GOPPC64 >=9 => (MODSD x y)
-(Mod64 x y) && objabi.GOPPC64 <=8 => (SUB x (MULLD y (DIVD x y)))
-(Mod64u x y) && objabi.GOPPC64 >= 9 => (MODUD x y)
-(Mod64u x y) && objabi.GOPPC64 <= 8 => (SUB x (MULLD y (DIVDU x y)))
-(Mod32 x y) && objabi.GOPPC64 >= 9 => (MODSW x y)
-(Mod32 x y) && objabi.GOPPC64 <= 8 => (SUB x (MULLW y (DIVW x y)))
-(Mod32u x y) && objabi.GOPPC64 >= 9 => (MODUW x y)
-(Mod32u x y) && objabi.GOPPC64 <= 8 => (SUB x (MULLW y (DIVWU x y)))
+(Mod64 x y) && buildcfg.GOPPC64 >=9 => (MODSD x y)
+(Mod64 x y) && buildcfg.GOPPC64 <=8 => (SUB x (MULLD y (DIVD x y)))
+(Mod64u x y) && buildcfg.GOPPC64 >= 9 => (MODUD x y)
+(Mod64u x y) && buildcfg.GOPPC64 <= 8 => (SUB x (MULLD y (DIVDU x y)))
+(Mod32 x y) && buildcfg.GOPPC64 >= 9 => (MODSW x y)
+(Mod32 x y) && buildcfg.GOPPC64 <= 8 => (SUB x (MULLW y (DIVW x y)))
+(Mod32u x y) && buildcfg.GOPPC64 >= 9 => (MODUW x y)
+(Mod32u x y) && buildcfg.GOPPC64 <= 8 => (SUB x (MULLW y (DIVWU x y)))
 
 // (x + y) / 2 with x>=y => (x - y) / 2 + y
 (Avg64u <t> x y) => (ADD (SRDconst <t> (SUB <t> x y) [1]) y)
@@ -71,6 +71,7 @@
 (Round(32|64)F ...) => (LoweredRound(32|64)F ...)
 
 (Sqrt ...) => (FSQRT ...)
+(Sqrt32 ...) => (FSQRTS ...)
 (Floor ...) => (FFLOOR ...)
 (Ceil ...) => (FCEIL ...)
 (Trunc ...) => (FTRUNC ...)
@@ -100,7 +101,7 @@
 (Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])
 (Const(32|64)F ...) => (FMOV(S|D)const ...)
 (ConstNil) => (MOVDconst [0])
-(ConstBool [b]) => (MOVDconst [b2i(b)])
+(ConstBool [t]) => (MOVDconst [b2i(t)])
 
 // Constant folding
 (FABS (FMOVDconst [x])) => (FMOVDconst [math.Abs(x)])
@@ -350,9 +351,9 @@
 (Ctz32NonZero ...) => (Ctz32 ...)
 (Ctz64NonZero ...) => (Ctz64 ...)
 
-(Ctz64 x) && objabi.GOPPC64<=8 => (POPCNTD (ANDN <typ.Int64> (ADDconst <typ.Int64> [-1] x) x))
+(Ctz64 x) && buildcfg.GOPPC64<=8 => (POPCNTD (ANDN <typ.Int64> (ADDconst <typ.Int64> [-1] x) x))
 (Ctz64 x) => (CNTTZD x)
-(Ctz32 x) && objabi.GOPPC64<=8 => (POPCNTW (MOVWZreg (ANDN <typ.Int> (ADDconst <typ.Int> [-1] x) x)))
+(Ctz32 x) && buildcfg.GOPPC64<=8 => (POPCNTW (MOVWZreg (ANDN <typ.Int> (ADDconst <typ.Int> [-1] x) x)))
 (Ctz32 x) => (CNTTZW (MOVWZreg x))
 (Ctz16 x) => (POPCNTW (MOVHZreg (ANDN <typ.Int16> (ADDconst <typ.Int16> [-1] x) x)))
 (Ctz8 x)  => (POPCNTB (MOVBZreg (ANDN <typ.UInt8> (ADDconst <typ.UInt8> [-1] x) x)))
@@ -606,24 +607,18 @@
 		(MOVHstorezero [4] destptr
 			(MOVWstorezero destptr mem)))
 
-// MOVD for store with DS must have offsets that are multiple of 4
-(Zero [8] {t} destptr mem) && t.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.Alignment()%4 == 0 =>
+(Zero [8] {t} destptr mem) => (MOVDstorezero destptr mem)
+(Zero [12] {t} destptr mem) =>
         (MOVWstorezero [8] destptr
                 (MOVDstorezero [0] destptr mem))
-(Zero [16] {t} destptr mem) && t.Alignment()%4 == 0 =>
+(Zero [16] {t} destptr mem) =>
        (MOVDstorezero [8] destptr
                 (MOVDstorezero [0] destptr mem))
-(Zero [24] {t} destptr mem) && t.Alignment()%4 == 0 =>
+(Zero [24] {t} destptr mem) =>
        (MOVDstorezero [16] destptr
                (MOVDstorezero [8] destptr
                        (MOVDstorezero [0] destptr mem)))
-(Zero [32] {t} destptr mem) && t.Alignment()%4 == 0 =>
+(Zero [32] {t} destptr mem) =>
        (MOVDstorezero [24] destptr
                (MOVDstorezero [16] destptr
                        (MOVDstorezero [8] destptr
@@ -632,15 +627,12 @@
 // Handle cases not handled above
 // Lowered Short cases do not generate loops, and as a result don't clobber
 // the address registers or flags.
-(Zero [s] ptr mem) && objabi.GOPPC64 <= 8 && s < 64 => (LoweredZeroShort [s] ptr mem)
-(Zero [s] ptr mem) && objabi.GOPPC64 <= 8 => (LoweredZero [s] ptr mem)
-(Zero [s] ptr mem) && s < 128 && objabi.GOPPC64 >= 9 => (LoweredQuadZeroShort [s] ptr mem)
-(Zero [s] ptr mem) && objabi.GOPPC64 >= 9 => (LoweredQuadZero [s] ptr mem)
+(Zero [s] ptr mem) && buildcfg.GOPPC64 <= 8 && s < 64 => (LoweredZeroShort [s] ptr mem)
+(Zero [s] ptr mem) && buildcfg.GOPPC64 <= 8 => (LoweredZero [s] ptr mem)
+(Zero [s] ptr mem) && s < 128 && buildcfg.GOPPC64 >= 9 => (LoweredQuadZeroShort [s] ptr mem)
+(Zero [s] ptr mem) && buildcfg.GOPPC64 >= 9 => (LoweredQuadZero [s] ptr mem)
 
 // moves
-// Only the MOVD and MOVW instructions require 4 byte
-// alignment in the offset field.  The other MOVx instructions
-// allow any alignment.
 (Move [0] _ _ mem) => mem
 (Move [1] dst src mem) => (MOVBstore dst (MOVBZload src mem) mem)
 (Move [2] dst src mem) =>
@@ -648,11 +640,8 @@
 (Move [4] dst src mem) =>
 	(MOVWstore dst (MOVWZload src mem) mem)
 // MOVD for load and store must have offsets that are multiple of 4
-(Move [8] {t} dst src mem) && t.Alignment()%4 == 0 =>
+(Move [8] {t} dst src mem) =>
 	(MOVDstore dst (MOVDload src mem) mem)
-(Move [8] dst src mem) =>
-	(MOVWstore [4] dst (MOVWZload [4] src mem)
-		(MOVWstore dst (MOVWZload src mem) mem))
 (Move [3] dst src mem) =>
         (MOVBstore [2] dst (MOVBZload [2] src mem)
                 (MOVHstore dst (MOVHload src mem) mem))
@@ -669,11 +658,11 @@
 
 // Large move uses a loop. Since the address is computed and the
 // offset is zero, any alignment can be used.
-(Move [s] dst src mem) && s > 8 && objabi.GOPPC64 <= 8 && logLargeCopy(v, s) =>
+(Move [s] dst src mem) && s > 8 && buildcfg.GOPPC64 <= 8 && logLargeCopy(v, s) =>
         (LoweredMove [s] dst src mem)
-(Move [s] dst src mem) && s > 8 && s <= 64 && objabi.GOPPC64 >= 9 =>
+(Move [s] dst src mem) && s > 8 && s <= 64 && buildcfg.GOPPC64 >= 9 =>
         (LoweredQuadMoveShort [s] dst src mem)
-(Move [s] dst src mem) && s > 8 && objabi.GOPPC64 >= 9 && logLargeCopy(v, s) =>
+(Move [s] dst src mem) && s > 8 && buildcfg.GOPPC64 >= 9 && logLargeCopy(v, s) =>
         (LoweredQuadMove [s] dst src mem)
 
 // Calls
@@ -874,7 +863,7 @@
 (MFVSRD x:(FMOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVDload [off] {sym} ptr mem)
 
 // Fold offsets for stores.
-(MOVDstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(int64(off1)+off2) && (int64(off1)+off2)%4 == 0 => (MOVDstore [off1+int32(off2)] {sym} x val mem)
+(MOVDstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(int64(off1)+off2) => (MOVDstore [off1+int32(off2)] {sym} x val mem)
 (MOVWstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(int64(off1)+off2) => (MOVWstore [off1+int32(off2)] {sym} x val mem)
 (MOVHstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(int64(off1)+off2) => (MOVHstore [off1+int32(off2)] {sym} x val mem)
 (MOVBstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(int64(off1)+off2) => (MOVBstore [off1+int32(off2)] {sym} x val mem)
@@ -897,7 +886,7 @@
 	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
         (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 (MOVDstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0 =>
+	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
         (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 
 (FMOVSstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
@@ -917,13 +906,13 @@
 	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
         (MOVHZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVWload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0 =>
+	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
         (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVWZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
 	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
         (MOVWZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVDload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0 =>
+	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
         (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (FMOVSload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
 	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
@@ -936,8 +925,8 @@
 (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (FMOVSload [off1+int32(off2)] {sym} ptr mem)
 (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (FMOVDload [off1+int32(off2)] {sym} ptr mem)
 
-(MOVDload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) && (int64(off1)+off2)%4 == 0 => (MOVDload [off1+int32(off2)] {sym} x mem)
-(MOVWload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) && (int64(off1)+off2)%4 == 0 => (MOVWload [off1+int32(off2)] {sym} x mem)
+(MOVDload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) => (MOVDload [off1+int32(off2)] {sym} x mem)
+(MOVWload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) => (MOVWload [off1+int32(off2)] {sym} x mem)
 (MOVWZload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) => (MOVWZload [off1+int32(off2)] {sym} x mem)
 (MOVHload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) => (MOVHload [off1+int32(off2)] {sym} x mem)
 (MOVHZload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) => (MOVHZload [off1+int32(off2)] {sym} x mem)
@@ -946,7 +935,10 @@
 // Determine load + addressing that can be done as a register indexed load
 (MOV(D|W|WZ|H|HZ|BZ)load [0] {sym} p:(ADD ptr idx) mem) && sym == nil && p.Uses == 1 => (MOV(D|W|WZ|H|HZ|BZ)loadidx ptr idx mem)
 
-// Determine indexed loads with constant values that can be done without index
+// Determine if there is benefit to using a non-indexed load, since that saves the load
+// of the index register. With MOVDload and MOVWload, there is no benefit if the offset
+// value is not a multiple of 4, since that results in an extra instruction in the base
+// register address computation.
 (MOV(D|W)loadidx ptr (MOVDconst [c]) mem) && is16Bit(c) && c%4 == 0 => (MOV(D|W)load [int32(c)] ptr mem)
 (MOV(WZ|H|HZ|BZ)loadidx ptr (MOVDconst [c]) mem) && is16Bit(c) => (MOV(WZ|H|HZ|BZ)load [int32(c)] ptr mem)
 (MOV(D|W)loadidx (MOVDconst [c]) ptr mem) && is16Bit(c) && c%4 == 0 => (MOV(D|W)load [int32(c)] ptr mem)
@@ -959,7 +951,7 @@
 (MOVBstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem)
 
 // Fold offsets for storezero
-(MOVDstorezero [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) && (int64(off1)+off2)%4 == 0 =>
+(MOVDstorezero [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) =>
     (MOVDstorezero [off1+int32(off2)] {sym} x mem)
 (MOVWstorezero [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) =>
     (MOVWstorezero [off1+int32(off2)] {sym} x mem)
@@ -972,6 +964,7 @@
 (MOV(D|W|H|B)store [0] {sym} p:(ADD ptr idx) val mem) && sym == nil && p.Uses == 1 => (MOV(D|W|H|B)storeidx ptr idx val mem)
 
 // Stores with constant index values can be done without indexed instructions
+// No need to lower the idx cases if c%4 is not 0
 (MOVDstoreidx ptr (MOVDconst [c]) val mem) && is16Bit(c) && c%4 == 0 => (MOVDstore [int32(c)] ptr val mem)
 (MOV(W|H|B)storeidx ptr (MOVDconst [c]) val mem) && is16Bit(c) => (MOV(W|H|B)store [int32(c)] ptr val mem)
 (MOVDstoreidx (MOVDconst [c]) ptr val mem) && is16Bit(c) && c%4 == 0 => (MOVDstore [int32(c)] ptr val mem)
@@ -979,7 +972,7 @@
 
 // Fold symbols into storezero
 (MOVDstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2)
-	&& (x.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0 =>
+	&& (x.Op != OpSB || p.Uses == 1) =>
     (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
 (MOVWstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2)
 	&& (x.Op != OpSB || p.Uses == 1) =>
@@ -1055,7 +1048,7 @@
 (SLWconst [c] z:(ANDconst [d] x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d)) => (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x)
 (SLWconst [c] z:(AND (MOVDconst [d]) x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d)) => (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x)
 // special case for power9
-(SL(W|D)const [c] z:(MOVWreg x)) && c < 32 && objabi.GOPPC64 >= 9 => (EXTSWSLconst [c] x)
+(SL(W|D)const [c] z:(MOVWreg x)) && c < 32 && buildcfg.GOPPC64 >= 9 => (EXTSWSLconst [c] x)
 
 // Lose widening ops fed to stores
 (MOVBstore [off] {sym} ptr (MOV(B|BZ|H|HZ|W|WZ)reg x) mem) => (MOVBstore [off] {sym} ptr x mem)
@@ -1088,7 +1081,7 @@
 (CMPWU (MOVDconst [c]) y) && isU16Bit(c) => (InvertFlags (CMPWUconst y [int32(c)]))
 
 // Canonicalize the order of arguments to comparisons - helps with CSE.
-((CMP|CMPW|CMPU|CMPWU) x y) && x.ID > y.ID => (InvertFlags ((CMP|CMPW|CMPU|CMPWU) y x))
+((CMP|CMPW|CMPU|CMPWU) x y) && canonLessThan(x,y) => (InvertFlags ((CMP|CMPW|CMPU|CMPWU) y x))
 
 // ISEL auxInt values 0=LT 1=GT 2=EQ   arg2 ? arg0 : arg1
 // ISEL auxInt values 4=GE 5=LE 6=NE   arg2 ? arg1 : arg0
@@ -1293,7 +1286,6 @@
 	o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])
 	x0:(MOVWZload {s} [i0] p mem)))))
 	&& !config.BigEndian
-	&& i0%4 == 0
 	&& i4 == i0+4
 	&& i5 == i0+5
 	&& i6 == i0+6
@@ -1430,7 +1422,6 @@
 	x2:(MOVBstore [i4] {s} p (SRDconst w [32])
 	x3:(MOVWstore [i0] {s} p w mem)))))
 	&& !config.BigEndian
-	&& i0%4 == 0
 	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
 	&& i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7
 	&& clobber(x0, x1, x2, x3)
diff --git a/src/cmd/compile/internal/ssa/gen/RISCV64.rules b/src/cmd/compile/internal/ssa/gen/RISCV64.rules
index 4380a5e..9cdd62e 100644
--- a/src/cmd/compile/internal/ssa/gen/RISCV64.rules
+++ b/src/cmd/compile/internal/ssa/gen/RISCV64.rules
@@ -92,6 +92,7 @@
 (Com8  ...) => (NOT ...)
 
 (Sqrt ...) => (FSQRTD ...)
+(Sqrt32 ...) => (FSQRTS ...)
 
 // Sign and zero extension.
 
@@ -221,9 +222,9 @@
 (Rsh64x64 <t> x y) => (SRA <t> x                 (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
 
 // rotates
-(RotateLeft8 <t> x (MOVBconst [c])) => (Or8 (Lsh8x64 <t> x (MOVBconst [c&7])) (Rsh8Ux64 <t> x (MOVBconst [-c&7])))
-(RotateLeft16 <t> x (MOVHconst [c])) => (Or16 (Lsh16x64 <t> x (MOVHconst [c&15])) (Rsh16Ux64 <t> x (MOVHconst [-c&15])))
-(RotateLeft32 <t> x (MOVWconst [c])) => (Or32 (Lsh32x64 <t> x (MOVWconst [c&31])) (Rsh32Ux64 <t> x (MOVWconst [-c&31])))
+(RotateLeft8  <t> x (MOVDconst [c])) => (Or8  (Lsh8x64  <t> x (MOVDconst [c&7]))  (Rsh8Ux64  <t> x (MOVDconst [-c&7])))
+(RotateLeft16 <t> x (MOVDconst [c])) => (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
+(RotateLeft32 <t> x (MOVDconst [c])) => (Or32 (Lsh32x64 <t> x (MOVDconst [c&31])) (Rsh32Ux64 <t> x (MOVDconst [-c&31])))
 (RotateLeft64 <t> x (MOVDconst [c])) => (Or64 (Lsh64x64 <t> x (MOVDconst [c&63])) (Rsh64Ux64 <t> x (MOVDconst [-c&63])))
 
 (Less64  ...) => (SLT  ...)
@@ -251,7 +252,7 @@
 
 (EqPtr x y) => (SEQZ (SUB <x.Type> x y))
 (Eq64  x y) => (SEQZ (SUB <x.Type> x y))
-(Eq32  x y) => (SEQZ (SUBW <x.Type> x y))
+(Eq32  x y) => (SEQZ (SUB <x.Type> (ZeroExt32to64 x) (ZeroExt32to64 y)))
 (Eq16  x y) => (SEQZ (SUB <x.Type> (ZeroExt16to64 x) (ZeroExt16to64 y)))
 (Eq8   x y) => (SEQZ (SUB <x.Type> (ZeroExt8to64  x) (ZeroExt8to64  y)))
 (Eq64F ...) => (FEQD ...)
@@ -259,7 +260,7 @@
 
 (NeqPtr x y) => (SNEZ (SUB <x.Type> x y))
 (Neq64  x y) => (SNEZ (SUB <x.Type> x y))
-(Neq32  x y) => (SNEZ (SUBW <x.Type> x y))
+(Neq32  x y) => (SNEZ (SUB <x.Type> (ZeroExt32to64 x) (ZeroExt32to64 y)))
 (Neq16  x y) => (SNEZ (SUB <x.Type> (ZeroExt16to64 x) (ZeroExt16to64 y)))
 (Neq8   x y) => (SNEZ (SUB <x.Type> (ZeroExt8to64  x) (ZeroExt8to64  y)))
 (Neq64F ...) => (FNED ...)
@@ -353,45 +354,45 @@
 
 // Small zeroing
 (Zero [0] _ mem) => mem
-(Zero [1] ptr mem) => (MOVBstore ptr (MOVBconst [0]) mem)
+(Zero [1] ptr mem) => (MOVBstore ptr (MOVDconst [0]) mem)
 (Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore ptr (MOVHconst [0]) mem)
+	(MOVHstore ptr (MOVDconst [0]) mem)
 (Zero [2] ptr mem) =>
-	(MOVBstore [1] ptr (MOVBconst [0])
-		(MOVBstore ptr (MOVBconst [0]) mem))
+	(MOVBstore [1] ptr (MOVDconst [0])
+		(MOVBstore ptr (MOVDconst [0]) mem))
 (Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore ptr (MOVWconst [0]) mem)
+	(MOVWstore ptr (MOVDconst [0]) mem)
 (Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [2] ptr (MOVHconst [0])
-		(MOVHstore ptr (MOVHconst [0]) mem))
+	(MOVHstore [2] ptr (MOVDconst [0])
+		(MOVHstore ptr (MOVDconst [0]) mem))
 (Zero [4] ptr mem) =>
-	(MOVBstore [3] ptr (MOVBconst [0])
-		(MOVBstore [2] ptr (MOVBconst [0])
-			(MOVBstore [1] ptr (MOVBconst [0])
-				(MOVBstore ptr (MOVBconst [0]) mem))))
+	(MOVBstore [3] ptr (MOVDconst [0])
+		(MOVBstore [2] ptr (MOVDconst [0])
+			(MOVBstore [1] ptr (MOVDconst [0])
+				(MOVBstore ptr (MOVDconst [0]) mem))))
 (Zero [8] {t} ptr mem) && t.Alignment()%8 == 0 =>
 	(MOVDstore ptr (MOVDconst [0]) mem)
 (Zero [8] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [4] ptr (MOVWconst [0])
-		(MOVWstore ptr (MOVWconst [0]) mem))
+	(MOVWstore [4] ptr (MOVDconst [0])
+		(MOVWstore ptr (MOVDconst [0]) mem))
 (Zero [8] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [6] ptr (MOVHconst [0])
-		(MOVHstore [4] ptr (MOVHconst [0])
-			(MOVHstore [2] ptr (MOVHconst [0])
-				(MOVHstore ptr (MOVHconst [0]) mem))))
+	(MOVHstore [6] ptr (MOVDconst [0])
+		(MOVHstore [4] ptr (MOVDconst [0])
+			(MOVHstore [2] ptr (MOVDconst [0])
+				(MOVHstore ptr (MOVDconst [0]) mem))))
 
 (Zero [3] ptr mem) =>
-	(MOVBstore [2] ptr (MOVBconst [0])
-		(MOVBstore [1] ptr (MOVBconst [0])
-			(MOVBstore ptr (MOVBconst [0]) mem)))
+	(MOVBstore [2] ptr (MOVDconst [0])
+		(MOVBstore [1] ptr (MOVDconst [0])
+			(MOVBstore ptr (MOVDconst [0]) mem)))
 (Zero [6] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [4] ptr (MOVHconst [0])
-		(MOVHstore [2] ptr (MOVHconst [0])
-			(MOVHstore ptr (MOVHconst [0]) mem)))
+	(MOVHstore [4] ptr (MOVDconst [0])
+		(MOVHstore [2] ptr (MOVDconst [0])
+			(MOVHstore ptr (MOVDconst [0]) mem)))
 (Zero [12] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [8] ptr (MOVWconst [0])
-		(MOVWstore [4] ptr (MOVWconst [0])
-			(MOVWstore ptr (MOVWconst [0]) mem)))
+	(MOVWstore [8] ptr (MOVDconst [0])
+		(MOVWstore [4] ptr (MOVDconst [0])
+			(MOVWstore ptr (MOVDconst [0]) mem)))
 (Zero [16] {t} ptr mem) && t.Alignment()%8 == 0 =>
 	(MOVDstore [8] ptr (MOVDconst [0])
 		(MOVDstore ptr (MOVDconst [0]) mem))
@@ -422,7 +423,7 @@
 (Convert ...) => (MOVconvert ...)
 
 // Checks
-(IsNonNil p) => (NeqPtr (MOVDconst [0]) p)
+(IsNonNil ...) => (SNEZ ...)
 (IsInBounds ...) => (Less64U ...)
 (IsSliceInBounds ...) => (Leq64U ...)
 
@@ -521,25 +522,14 @@
 (OffPtr [off] ptr) && is32Bit(off) => (ADDI [off] ptr)
 (OffPtr [off] ptr) => (ADD (MOVDconst [off]) ptr)
 
-// TODO(jsing): Check if we actually need MOV{B,H,W}const as most platforms
-// use a single MOVDconst op.
-(Const8 ...) => (MOVBconst ...)
-(Const16 ...) => (MOVHconst ...)
-(Const32 ...) => (MOVWconst ...)
-(Const64 ...) => (MOVDconst ...)
-(Const32F [val]) => (FMVSX (MOVWconst [int32(math.Float32bits(val))]))
+(Const8  [val]) => (MOVDconst [int64(val)])
+(Const16 [val]) => (MOVDconst [int64(val)])
+(Const32 [val]) => (MOVDconst [int64(val)])
+(Const64 [val]) => (MOVDconst [int64(val)])
+(Const32F [val]) => (FMVSX (MOVDconst [int64(math.Float32bits(val))]))
 (Const64F [val]) => (FMVDX (MOVDconst [int64(math.Float64bits(val))]))
 (ConstNil) => (MOVDconst [0])
-(ConstBool [val]) => (MOVBconst [int8(b2i(val))])
-
-// Convert 64 bit immediate to two 32 bit immediates, combine with add and shift.
-// The lower 32 bit immediate will be treated as signed,
-// so if it is negative, adjust for the borrow by incrementing the top half.
-// We don't have to worry about overflow from the increment,
-// because if the top half is all 1s, and int32(c) is negative,
-// then the overall constant fits in an int32.
-(MOVDconst <t> [c]) && !is32Bit(c) && int32(c) <  0 => (ADD (SLLI <t> [32] (MOVDconst [c>>32+1])) (MOVDconst [int64(int32(c))]))
-(MOVDconst <t> [c]) && !is32Bit(c) && int32(c) >= 0 => (ADD (SLLI <t> [32] (MOVDconst [c>>32+0])) (MOVDconst [int64(int32(c))]))
+(ConstBool [val]) => (MOVDconst [int64(b2i(val))])
 
 (Addr {sym} base) => (MOVaddr {sym} [0] base)
 (LocalAddr {sym} base _) => (MOVaddr {sym} base)
@@ -563,12 +553,28 @@
 (AtomicAdd32 ...) => (LoweredAtomicAdd32 ...)
 (AtomicAdd64 ...) => (LoweredAtomicAdd64 ...)
 
+// AtomicAnd8(ptr,val) => LoweredAtomicAnd32(ptr&^3, ^((uint8(val) ^ 0xff) << ((ptr & 3) * 8)))
+(AtomicAnd8 ptr val mem) =>
+	(LoweredAtomicAnd32 (ANDI <typ.Uintptr> [^3] ptr)
+		(NOT <typ.UInt32> (SLL <typ.UInt32> (XORI <typ.UInt32> [0xff] (ZeroExt8to32 val))
+			(SLLI <typ.UInt64> [3] (ANDI <typ.UInt64> [3] ptr)))) mem)
+
+(AtomicAnd32 ...) => (LoweredAtomicAnd32 ...)
+
 (AtomicCompareAndSwap32 ...) => (LoweredAtomicCas32 ...)
 (AtomicCompareAndSwap64 ...) => (LoweredAtomicCas64 ...)
 
 (AtomicExchange32 ...) => (LoweredAtomicExchange32 ...)
 (AtomicExchange64 ...) => (LoweredAtomicExchange64 ...)
 
+// AtomicOr8(ptr,val)  => LoweredAtomicOr32(ptr&^3, uint32(val)<<((ptr&3)*8))
+(AtomicOr8 ptr val mem) =>
+	(LoweredAtomicOr32 (ANDI <typ.Uintptr> [^3] ptr)
+		(SLL <typ.UInt32> (ZeroExt8to32 val)
+			(SLLI <typ.UInt64> [3] (ANDI <typ.UInt64> [3] ptr))) mem)
+
+(AtomicOr32  ...) => (LoweredAtomicOr32  ...)
+
 // Conditional branches
 (If cond yes no) => (BNEZ cond yes no)
 
@@ -595,24 +601,18 @@
 (BNE cond (MOVDconst [0]) yes no) => (BNEZ cond yes no)
 
 // Store zero
-(MOVBstore [off] {sym} ptr (MOVBconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem)
-(MOVHstore [off] {sym} ptr (MOVHconst [0]) mem) => (MOVHstorezero [off] {sym} ptr mem)
-(MOVWstore [off] {sym} ptr (MOVWconst [0]) mem) => (MOVWstorezero [off] {sym} ptr mem)
+(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)
 
 // Avoid sign/zero extension for consts.
-(MOVBreg  (MOVBconst [c])) => (MOVDconst [int64(c)])
-(MOVHreg  (MOVBconst [c])) => (MOVDconst [int64(c)])
-(MOVHreg  (MOVHconst [c])) => (MOVDconst [int64(c)])
-(MOVWreg  (MOVBconst [c])) => (MOVDconst [int64(c)])
-(MOVWreg  (MOVHconst [c])) => (MOVDconst [int64(c)])
-(MOVWreg  (MOVWconst [c])) => (MOVDconst [int64(c)])
-(MOVBUreg (MOVBconst [c])) => (MOVDconst [int64(uint8(c))])
-(MOVHUreg (MOVBconst [c])) => (MOVDconst [int64(uint16(c))])
-(MOVHUreg (MOVHconst [c])) => (MOVDconst [int64(uint16(c))])
-(MOVWUreg (MOVBconst [c])) => (MOVDconst [int64(uint32(c))])
-(MOVWUreg (MOVHconst [c])) => (MOVDconst [int64(uint32(c))])
-(MOVWUreg (MOVWconst [c])) => (MOVDconst [int64(uint32(c))])
+(MOVBreg  (MOVDconst [c])) => (MOVDconst [int64(int8(c))])
+(MOVHreg  (MOVDconst [c])) => (MOVDconst [int64(int16(c))])
+(MOVWreg  (MOVDconst [c])) => (MOVDconst [int64(int32(c))])
+(MOVBUreg (MOVDconst [c])) => (MOVDconst [int64(uint8(c))])
+(MOVHUreg (MOVDconst [c])) => (MOVDconst [int64(uint16(c))])
+(MOVWUreg (MOVDconst [c])) => (MOVDconst [int64(uint32(c))])
 
 // Avoid sign/zero extension after properly typed load.
 (MOVBreg  x:(MOVBload  _ _)) => (MOVDreg x)
@@ -673,61 +673,29 @@
 // MOVnop does not emit an instruction, only for ensuring the type.
 (MOVDreg x) && x.Uses == 1 => (MOVDnop x)
 
+// TODO: we should be able to get rid of MOVDnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVDnop (MOVDconst [c])) => (MOVDconst [c])
+
 // Fold constant into immediate instructions where possible.
-(ADD (MOVBconst [val]) x) => (ADDI [int64(val)] x)
-(ADD (MOVHconst [val]) x) => (ADDI [int64(val)] x)
-(ADD (MOVWconst [val]) x) => (ADDI [int64(val)] x)
 (ADD (MOVDconst [val]) x) && is32Bit(val) => (ADDI [val] x)
-
-(AND (MOVBconst [val]) x) => (ANDI [int64(val)] x)
-(AND (MOVHconst [val]) x) => (ANDI [int64(val)] x)
-(AND (MOVWconst [val]) x) => (ANDI [int64(val)] x)
 (AND (MOVDconst [val]) x) && is32Bit(val) => (ANDI [val] x)
-
-(OR (MOVBconst [val]) x) => (ORI [int64(val)] x)
-(OR (MOVHconst [val]) x) => (ORI [int64(val)] x)
-(OR (MOVWconst [val]) x) => (ORI [int64(val)] x)
-(OR (MOVDconst [val]) x) && is32Bit(val) => (ORI [val] x)
-
-(XOR (MOVBconst [val]) x) => (XORI [int64(val)] x)
-(XOR (MOVHconst [val]) x) => (XORI [int64(val)] x)
-(XOR (MOVWconst [val]) x) => (XORI [int64(val)] x)
+(OR  (MOVDconst [val]) x) && is32Bit(val) => (ORI  [val] x)
 (XOR (MOVDconst [val]) x) && is32Bit(val) => (XORI [val] x)
-
-(SLL x (MOVBconst [val])) => (SLLI [int64(val&63)] x)
-(SLL x (MOVHconst [val])) => (SLLI [int64(val&63)] x)
-(SLL x (MOVWconst [val])) => (SLLI [int64(val&63)] x)
 (SLL x (MOVDconst [val])) => (SLLI [int64(val&63)] x)
-
-(SRL x (MOVBconst [val])) => (SRLI [int64(val&63)] x)
-(SRL x (MOVHconst [val])) => (SRLI [int64(val&63)] x)
-(SRL x (MOVWconst [val])) => (SRLI [int64(val&63)] x)
 (SRL x (MOVDconst [val])) => (SRLI [int64(val&63)] x)
-
-(SRA x (MOVBconst [val])) => (SRAI [int64(val&63)] x)
-(SRA x (MOVHconst [val])) => (SRAI [int64(val&63)] x)
-(SRA x (MOVWconst [val])) => (SRAI [int64(val&63)] x)
 (SRA x (MOVDconst [val])) => (SRAI [int64(val&63)] x)
 
 // Convert subtraction of a const into ADDI with negative immediate, where possible.
-(SUB x (MOVBconst [val])) => (ADDI [-int64(val)] x)
-(SUB x (MOVHconst [val])) => (ADDI [-int64(val)] x)
-(SUB x (MOVWconst [val])) && is32Bit(-int64(val)) => (ADDI [-int64(val)] x)
 (SUB x (MOVDconst [val])) && is32Bit(-val) => (ADDI [-val] x)
 
 // Subtraction of zero.
-(SUB x (MOVBconst [0])) => x
-(SUB x (MOVHconst [0])) => x
-(SUB x (MOVWconst [0])) => x
 (SUB x (MOVDconst [0])) => x
 
 // Subtraction of zero with sign extension.
-(SUBW x (MOVWconst [0])) => (ADDIW [0] x)
+(SUBW x (MOVDconst [0])) => (ADDIW [0] x)
 
 // Subtraction from zero.
-(SUB (MOVBconst [0]) x) => (NEG x)
-(SUB (MOVHconst [0]) x) => (NEG x)
-(SUB (MOVWconst [0]) x) => (NEG x)
 (SUB (MOVDconst [0]) x) => (NEG x)
 
 // Subtraction from zero with sign extension.
diff --git a/src/cmd/compile/internal/ssa/gen/RISCV64Ops.go b/src/cmd/compile/internal/ssa/gen/RISCV64Ops.go
index f643192..0ac9c5f 100644
--- a/src/cmd/compile/internal/ssa/gen/RISCV64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/RISCV64Ops.go
@@ -126,6 +126,7 @@
 		gp11sb   = regInfo{inputs: []regMask{gpspsbMask}, outputs: []regMask{gpMask}}
 		gpxchg   = regInfo{inputs: []regMask{gpspsbgMask, gpgMask}, outputs: []regMask{gpMask}}
 		gpcas    = regInfo{inputs: []regMask{gpspsbgMask, gpgMask, gpgMask}, outputs: []regMask{gpMask}}
+		gpatomic = regInfo{inputs: []regMask{gpspsbgMask, gpgMask}}
 
 		fp11    = regInfo{inputs: []regMask{fpMask}, outputs: []regMask{fpMask}}
 		fp21    = regInfo{inputs: []regMask{fpMask, fpMask}, outputs: []regMask{fpMask}}
@@ -167,9 +168,6 @@
 		{name: "MOVaddr", argLength: 1, reg: gp11sb, asm: "MOV", aux: "SymOff", rematerializeable: true, symEffect: "RdWr"}, // arg0 + auxint + offset encoded in aux
 		// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
 
-		{name: "MOVBconst", reg: gp01, asm: "MOV", typ: "UInt8", aux: "Int8", rematerializeable: true},   // 8 low bits of auxint
-		{name: "MOVHconst", reg: gp01, asm: "MOV", typ: "UInt16", aux: "Int16", rematerializeable: true}, // 16 low bits of auxint
-		{name: "MOVWconst", reg: gp01, asm: "MOV", typ: "UInt32", aux: "Int32", rematerializeable: true}, // 32 low bits of auxint
 		{name: "MOVDconst", reg: gp01, asm: "MOV", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint
 
 		// Loads: load <size> bits from arg0+auxint+aux and extend to 64 bits; arg1=mem
@@ -335,7 +333,7 @@
 		{name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, faultOnNilArg0: true},
 
 		// Atomic stores.
-		// store arg1 to arg0. arg2=mem. returns memory.
+		// store arg1 to *arg0. arg2=mem. returns memory.
 		{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
 		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
 		{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
@@ -367,6 +365,11 @@
 		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
 		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
 
+		// Atomic 32 bit AND/OR.
+		// *arg0 &= (|=) arg1. arg2=mem. returns nil.
+		{name: "LoweredAtomicAnd32", argLength: 3, reg: gpatomic, asm: "AMOANDW", faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicOr32", argLength: 3, reg: gpatomic, asm: "AMOORW", faultOnNilArg0: true, hasSideEffects: true},
+
 		// Lowering pass-throughs
 		{name: "LoweredNilCheck", argLength: 2, faultOnNilArg0: true, nilCheck: true, reg: regInfo{inputs: []regMask{gpspMask}}}, // arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
 		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{regCtxt}}},                                                // scheduler ensures only at beginning of entry block
diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules
index 384f2e8..88762f7 100644
--- a/src/cmd/compile/internal/ssa/gen/S390X.rules
+++ b/src/cmd/compile/internal/ssa/gen/S390X.rules
@@ -142,6 +142,8 @@
 (Round       x) => (FIDBR [1] x)
 (FMA     x y z) => (FMADD z x y)
 
+(Sqrt32    ...) => (FSQRTS ...)
+
 // Atomic loads and stores.
 // The SYNC instruction (fast-BCR-serialization) prevents store-load
 // reordering. Other sequences of memory operations (load-load,
@@ -384,13 +386,13 @@
 
 // MVC for other moves. Use up to 4 instructions (sizes up to 1024 bytes).
 (Move [s] dst src mem) && s > 0 && s <= 256 && logLargeCopy(v, s) =>
-	(MVC [makeValAndOff32(int32(s), 0)] dst src mem)
+	(MVC [makeValAndOff(int32(s), 0)] dst src mem)
 (Move [s] dst src mem) && s > 256 && s <= 512 && logLargeCopy(v, s) =>
-	(MVC [makeValAndOff32(int32(s)-256, 256)] dst src (MVC [makeValAndOff32(256, 0)] dst src mem))
+	(MVC [makeValAndOff(int32(s)-256, 256)] dst src (MVC [makeValAndOff(256, 0)] dst src mem))
 (Move [s] dst src mem) && s > 512 && s <= 768 && logLargeCopy(v, s) =>
-	(MVC [makeValAndOff32(int32(s)-512, 512)] dst src (MVC [makeValAndOff32(256, 256)] dst src (MVC [makeValAndOff32(256, 0)] dst src mem)))
+	(MVC [makeValAndOff(int32(s)-512, 512)] dst src (MVC [makeValAndOff(256, 256)] dst src (MVC [makeValAndOff(256, 0)] dst src mem)))
 (Move [s] dst src mem) && s > 768 && s <= 1024 && logLargeCopy(v, s) =>
-	(MVC [makeValAndOff32(int32(s)-768, 768)] dst src (MVC [makeValAndOff32(256, 512)] dst src (MVC [makeValAndOff32(256, 256)] dst src (MVC [makeValAndOff32(256, 0)] dst src mem))))
+	(MVC [makeValAndOff(int32(s)-768, 768)] dst src (MVC [makeValAndOff(256, 512)] dst src (MVC [makeValAndOff(256, 256)] dst src (MVC [makeValAndOff(256, 0)] dst src mem))))
 
 // Move more than 1024 bytes using a loop.
 (Move [s] dst src mem) && s > 1024 && logLargeCopy(v, s) =>
@@ -403,20 +405,20 @@
 (Zero [4] destptr mem) => (MOVWstoreconst [0] destptr mem)
 (Zero [8] destptr mem) => (MOVDstoreconst [0] destptr mem)
 (Zero [3] destptr mem) =>
-	(MOVBstoreconst [makeValAndOff32(0,2)] destptr
+	(MOVBstoreconst [makeValAndOff(0,2)] destptr
 		(MOVHstoreconst [0] destptr mem))
 (Zero [5] destptr mem) =>
-	(MOVBstoreconst [makeValAndOff32(0,4)] destptr
+	(MOVBstoreconst [makeValAndOff(0,4)] destptr
 		(MOVWstoreconst [0] destptr mem))
 (Zero [6] destptr mem) =>
-	(MOVHstoreconst [makeValAndOff32(0,4)] destptr
+	(MOVHstoreconst [makeValAndOff(0,4)] destptr
 		(MOVWstoreconst [0] destptr mem))
 (Zero [7] destptr mem) =>
-	(MOVWstoreconst [makeValAndOff32(0,3)] destptr
+	(MOVWstoreconst [makeValAndOff(0,3)] destptr
 		(MOVWstoreconst [0] destptr mem))
 
 (Zero [s] destptr mem) && s > 0 && s <= 1024 =>
-	(CLEAR [makeValAndOff32(int32(s), 0)] destptr mem)
+	(CLEAR [makeValAndOff(int32(s), 0)] destptr mem)
 
 // Zero more than 1024 bytes using a loop.
 (Zero [s] destptr mem) && s > 1024 =>
@@ -426,7 +428,7 @@
 (Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])
 (Const(32|64)F ...) => (FMOV(S|D)const ...)
 (ConstNil) => (MOVDconst [0])
-(ConstBool [b]) => (MOVDconst [b2i(b)])
+(ConstBool [t]) => (MOVDconst [b2i(t)])
 
 // Lowering calls
 (StaticCall ...) => (CALLstatic ...)
@@ -785,7 +787,7 @@
   => (RISBGZ x {s390x.NewRotateParams(r.Start, r.Start, -r.Start&63)})
 
 // Canonicalize the order of arguments to comparisons - helps with CSE.
-((CMP|CMPW|CMPU|CMPWU) x y) && x.ID > y.ID => (InvertFlags ((CMP|CMPW|CMPU|CMPWU) y x))
+((CMP|CMPW|CMPU|CMPWU) x y) && canonLessThan(x,y) => (InvertFlags ((CMP|CMPW|CMPU|CMPWU) y x))
 
 // Use sign/zero extend instead of RISBGZ.
 (RISBGZ x {r}) && r == s390x.NewRotateParams(56, 63, 0) => (MOVBZreg x)
@@ -946,22 +948,22 @@
 
 // Fold constants into stores.
 (MOVDstore [off] {sym} ptr (MOVDconst [c]) mem) && is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB =>
-	(MOVDstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+	(MOVDstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
 (MOVWstore [off] {sym} ptr (MOVDconst [c]) mem) && is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB =>
-	(MOVWstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+	(MOVWstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
 (MOVHstore [off] {sym} ptr (MOVDconst [c]) mem) && isU12Bit(int64(off)) && ptr.Op != OpSB =>
-	(MOVHstoreconst [makeValAndOff32(int32(int16(c)),off)] {sym} ptr mem)
+	(MOVHstoreconst [makeValAndOff(int32(int16(c)),off)] {sym} ptr mem)
 (MOVBstore [off] {sym} ptr (MOVDconst [c]) mem) && is20Bit(int64(off)) && ptr.Op != OpSB =>
-	(MOVBstoreconst [makeValAndOff32(int32(int8(c)),off)] {sym} ptr mem)
+	(MOVBstoreconst [makeValAndOff(int32(int8(c)),off)] {sym} ptr mem)
 
 // Fold address offsets into constant stores.
-(MOVDstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off()+int64(off)) =>
+(MOVDstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off64()+int64(off)) =>
 	(MOVDstoreconst [sc.addOffset32(off)] {s} ptr mem)
-(MOVWstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off()+int64(off)) =>
+(MOVWstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off64()+int64(off)) =>
 	(MOVWstoreconst [sc.addOffset32(off)] {s} ptr mem)
-(MOVHstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off()+int64(off)) =>
+(MOVHstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off64()+int64(off)) =>
 	(MOVHstoreconst [sc.addOffset32(off)] {s} ptr mem)
-(MOVBstoreconst [sc] {s} (ADDconst [off] ptr) mem) && is20Bit(sc.Off()+int64(off)) =>
+(MOVBstoreconst [sc] {s} (ADDconst [off] ptr) mem) && is20Bit(sc.Off64()+int64(off)) =>
 	(MOVBstoreconst [sc.addOffset32(off)] {s} ptr mem)
 
 // Merge address calculations into loads and stores.
@@ -1304,19 +1306,19 @@
   && x.Uses == 1
   && a.Off() + 1 == c.Off()
   && clobber(x)
-  => (MOVHstoreconst [makeValAndOff32(c.Val32()&0xff | a.Val32()<<8, a.Off32())] {s} p mem)
+  => (MOVHstoreconst [makeValAndOff(c.Val()&0xff | a.Val()<<8, a.Off())] {s} p mem)
 (MOVHstoreconst [c] {s} p x:(MOVHstoreconst [a] {s} p mem))
   && p.Op != OpSB
   && x.Uses == 1
   && a.Off() + 2 == c.Off()
   && clobber(x)
-  => (MOVWstore [a.Off32()] {s} p (MOVDconst [int64(c.Val32()&0xffff | a.Val32()<<16)]) mem)
+  => (MOVWstore [a.Off()] {s} p (MOVDconst [int64(c.Val()&0xffff | a.Val()<<16)]) mem)
 (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
   && p.Op != OpSB
   && x.Uses == 1
   && a.Off() + 4 == c.Off()
   && clobber(x)
-  => (MOVDstore [a.Off32()] {s} p (MOVDconst [c.Val()&0xffffffff | a.Val()<<32]) mem)
+  => (MOVDstore [a.Off()] {s} p (MOVDconst [c.Val64()&0xffffffff | a.Val64()<<32]) mem)
 
 // Combine stores into larger (unaligned) stores.
 // It doesn't work on global data (based on SB) because stores with relative addressing
@@ -1420,6 +1422,16 @@
   && clobber(x)
   => (MOVDBRstore [i-4] {s} p w0 mem)
 
+(MOVBstore [7] {s} p1 (SRDconst w)
+  x1:(MOVHBRstore [5] {s} p1 (SRDconst w)
+  x2:(MOVWBRstore [1] {s} p1 (SRDconst w)
+  x3:(MOVBstore [0] {s} p1 w mem))))
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && x3.Uses == 1
+  && clobber(x1, x2, x3)
+  => (MOVDBRstore {s} p1 w mem)
+
 // Combining byte loads into larger (unaligned) loads.
 
 // Big-endian loads
diff --git a/src/cmd/compile/internal/ssa/gen/S390XOps.go b/src/cmd/compile/internal/ssa/gen/S390XOps.go
index b24fd61..5b33ba7 100644
--- a/src/cmd/compile/internal/ssa/gen/S390XOps.go
+++ b/src/cmd/compile/internal/ssa/gen/S390XOps.go
@@ -381,7 +381,8 @@
 		{name: "NOT", argLength: 1, reg: gp11, resultInArg0: true, clobberFlags: true},  // ^arg0
 		{name: "NOTW", argLength: 1, reg: gp11, resultInArg0: true, clobberFlags: true}, // ^arg0
 
-		{name: "FSQRT", argLength: 1, reg: fp11, asm: "FSQRT"}, // sqrt(arg0)
+		{name: "FSQRT", argLength: 1, reg: fp11, asm: "FSQRT"},   // sqrt(arg0)
+		{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"}, // sqrt(arg0), float32
 
 		// Conditional register-register moves.
 		// The aux for these values is an s390x.CCMask value representing the condition code mask.
diff --git a/src/cmd/compile/internal/ssa/gen/Wasm.rules b/src/cmd/compile/internal/ssa/gen/Wasm.rules
index fc45cd3..7ad3d1c 100644
--- a/src/cmd/compile/internal/ssa/gen/Wasm.rules
+++ b/src/cmd/compile/internal/ssa/gen/Wasm.rules
@@ -55,9 +55,9 @@
 (ZeroExt32to64        x:(I64Load32U _ _)) => x
 (ZeroExt16to(64|32)   x:(I64Load16U _ _)) => x
 (ZeroExt8to(64|32|16) x:(I64Load8U  _ _)) => x
-(SignExt32to64        x) && objabi.GOWASM.SignExt => (I64Extend32S x)
-(SignExt8to(64|32|16) x) && objabi.GOWASM.SignExt => (I64Extend8S x)
-(SignExt16to(64|32)   x) && objabi.GOWASM.SignExt => (I64Extend16S x)
+(SignExt32to64        x) && buildcfg.GOWASM.SignExt => (I64Extend32S x)
+(SignExt8to(64|32|16) x) && buildcfg.GOWASM.SignExt => (I64Extend8S x)
+(SignExt16to(64|32)   x) && buildcfg.GOWASM.SignExt => (I64Extend16S x)
 (SignExt32to64        x) => (I64ShrS (I64Shl x (I64Const [32])) (I64Const [32]))
 (SignExt16to(64|32)   x) => (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
 (SignExt8to(64|32|16) x) => (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
@@ -332,6 +332,8 @@
 (Abs ...) => (F64Abs ...)
 (Copysign ...) => (F64Copysign ...)
 
+(Sqrt32 ...) => (F32Sqrt ...)
+
 (Ctz64 ...) => (I64Ctz ...)
 (Ctz32 x) => (I64Ctz (I64Or x (I64Const [0x100000000])))
 (Ctz16 x) => (I64Ctz (I64Or x (I64Const [0x10000])))
diff --git a/src/cmd/compile/internal/ssa/gen/WasmOps.go b/src/cmd/compile/internal/ssa/gen/WasmOps.go
index 36c53bc..c92878c 100644
--- a/src/cmd/compile/internal/ssa/gen/WasmOps.go
+++ b/src/cmd/compile/internal/ssa/gen/WasmOps.go
@@ -238,13 +238,13 @@
 		{name: "I64Extend16S", asm: "I64Extend16S", argLength: 1, reg: gp11, typ: "Int64"}, // sign-extend arg0 from 16 to 64 bit
 		{name: "I64Extend32S", asm: "I64Extend32S", argLength: 1, reg: gp11, typ: "Int64"}, // sign-extend arg0 from 32 to 64 bit
 
-		{name: "F32Sqrt", asm: "F32Sqrt", argLength: 1, reg: fp64_11, typ: "Float32"},         // sqrt(arg0)
-		{name: "F32Trunc", asm: "F32Trunc", argLength: 1, reg: fp64_11, typ: "Float32"},       // trunc(arg0)
-		{name: "F32Ceil", asm: "F32Ceil", argLength: 1, reg: fp64_11, typ: "Float32"},         // ceil(arg0)
-		{name: "F32Floor", asm: "F32Floor", argLength: 1, reg: fp64_11, typ: "Float32"},       // floor(arg0)
-		{name: "F32Nearest", asm: "F32Nearest", argLength: 1, reg: fp64_11, typ: "Float32"},   // round(arg0)
-		{name: "F32Abs", asm: "F32Abs", argLength: 1, reg: fp64_11, typ: "Float32"},           // abs(arg0)
-		{name: "F32Copysign", asm: "F32Copysign", argLength: 2, reg: fp64_21, typ: "Float32"}, // copysign(arg0, arg1)
+		{name: "F32Sqrt", asm: "F32Sqrt", argLength: 1, reg: fp32_11, typ: "Float32"},         // sqrt(arg0)
+		{name: "F32Trunc", asm: "F32Trunc", argLength: 1, reg: fp32_11, typ: "Float32"},       // trunc(arg0)
+		{name: "F32Ceil", asm: "F32Ceil", argLength: 1, reg: fp32_11, typ: "Float32"},         // ceil(arg0)
+		{name: "F32Floor", asm: "F32Floor", argLength: 1, reg: fp32_11, typ: "Float32"},       // floor(arg0)
+		{name: "F32Nearest", asm: "F32Nearest", argLength: 1, reg: fp32_11, typ: "Float32"},   // round(arg0)
+		{name: "F32Abs", asm: "F32Abs", argLength: 1, reg: fp32_11, typ: "Float32"},           // abs(arg0)
+		{name: "F32Copysign", asm: "F32Copysign", argLength: 2, reg: fp32_21, typ: "Float32"}, // copysign(arg0, arg1)
 
 		{name: "F64Sqrt", asm: "F64Sqrt", argLength: 1, reg: fp64_11, typ: "Float64"},         // sqrt(arg0)
 		{name: "F64Trunc", asm: "F64Trunc", argLength: 1, reg: fp64_11, typ: "Float64"},       // trunc(arg0)
diff --git a/src/cmd/compile/internal/ssa/gen/dec.rules b/src/cmd/compile/internal/ssa/gen/dec.rules
index 4c677f8..b194898 100644
--- a/src/cmd/compile/internal/ssa/gen/dec.rules
+++ b/src/cmd/compile/internal/ssa/gen/dec.rules
@@ -56,6 +56,7 @@
 (SlicePtr (SliceMake ptr _ _ )) => ptr
 (SliceLen (SliceMake _ len _)) => len
 (SliceCap (SliceMake _ _ cap)) => cap
+(SlicePtrUnchecked (SliceMake ptr _ _ )) => ptr
 
 (Load <t> ptr mem) && t.IsSlice() =>
   (SliceMake
diff --git a/src/cmd/compile/internal/ssa/gen/dec64.rules b/src/cmd/compile/internal/ssa/gen/dec64.rules
index 9297ed8..b0f10d0 100644
--- a/src/cmd/compile/internal/ssa/gen/dec64.rules
+++ b/src/cmd/compile/internal/ssa/gen/dec64.rules
@@ -42,20 +42,20 @@
 		(Store {hi.Type} dst hi mem))
 
 // These are not enabled during decomposeBuiltin if late call expansion, but they are always enabled for softFloat
-(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") =>
+(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
   (Int64Make
     (Arg <typ.Int32> {n} [off+4])
     (Arg <typ.UInt32> {n} [off]))
-(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")  =>
+(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")  =>
   (Int64Make
     (Arg <typ.UInt32> {n} [off+4])
     (Arg <typ.UInt32> {n} [off]))
 
-(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") =>
+(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
   (Int64Make
     (Arg <typ.Int32> {n} [off])
     (Arg <typ.UInt32> {n} [off+4]))
-(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") =>
+(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
   (Int64Make
     (Arg <typ.UInt32> {n} [off])
     (Arg <typ.UInt32> {n} [off+4]))
diff --git a/src/cmd/compile/internal/ssa/gen/decArgs.rules b/src/cmd/compile/internal/ssa/gen/decArgs.rules
deleted file mode 100644
index 1c9a0bb..0000000
--- a/src/cmd/compile/internal/ssa/gen/decArgs.rules
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Decompose compound argument values
-// Do this early to simplify tracking names for debugging.
-
-(Arg {n} [off]) && v.Type.IsString() =>
-  (StringMake
-    (Arg <typ.BytePtr> {n} [off])
-    (Arg <typ.Int> {n} [off+int32(config.PtrSize)]))
-
-(Arg {n} [off]) && v.Type.IsSlice() =>
-  (SliceMake
-    (Arg <v.Type.Elem().PtrTo()> {n} [off])
-    (Arg <typ.Int> {n} [off+int32(config.PtrSize)])
-    (Arg <typ.Int> {n} [off+2*int32(config.PtrSize)]))
-
-(Arg {n} [off]) && v.Type.IsInterface() =>
-  (IMake
-    (Arg <typ.Uintptr> {n} [off])
-    (Arg <typ.BytePtr> {n} [off+int32(config.PtrSize)]))
-
-(Arg {n} [off]) && v.Type.IsComplex() && v.Type.Size() == 16 =>
-  (ComplexMake
-    (Arg <typ.Float64> {n} [off])
-    (Arg <typ.Float64> {n} [off+8]))
-
-(Arg {n} [off]) && v.Type.IsComplex() && v.Type.Size() == 8 =>
-  (ComplexMake
-    (Arg <typ.Float32> {n} [off])
-    (Arg <typ.Float32> {n} [off+4]))
-
-(Arg <t>) && t.IsStruct() && t.NumFields() == 0 && fe.CanSSA(t) =>
-  (StructMake0)
-(Arg <t> {n} [off]) && t.IsStruct() && t.NumFields() == 1 && fe.CanSSA(t) =>
-  (StructMake1
-    (Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))]))
-(Arg <t> {n} [off]) && t.IsStruct() && t.NumFields() == 2 && fe.CanSSA(t) =>
-  (StructMake2
-    (Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))])
-    (Arg <t.FieldType(1)> {n} [off+int32(t.FieldOff(1))]))
-(Arg <t> {n} [off]) && t.IsStruct() && t.NumFields() == 3 && fe.CanSSA(t) =>
-  (StructMake3
-    (Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))])
-    (Arg <t.FieldType(1)> {n} [off+int32(t.FieldOff(1))])
-    (Arg <t.FieldType(2)> {n} [off+int32(t.FieldOff(2))]))
-(Arg <t> {n} [off]) && t.IsStruct() && t.NumFields() == 4 && fe.CanSSA(t) =>
-  (StructMake4
-    (Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))])
-    (Arg <t.FieldType(1)> {n} [off+int32(t.FieldOff(1))])
-    (Arg <t.FieldType(2)> {n} [off+int32(t.FieldOff(2))])
-    (Arg <t.FieldType(3)> {n} [off+int32(t.FieldOff(3))]))
-
-(Arg <t>) && t.IsArray() && t.NumElem() == 0 =>
-  (ArrayMake0)
-(Arg <t> {n} [off]) && t.IsArray() && t.NumElem() == 1 && fe.CanSSA(t) =>
-  (ArrayMake1 (Arg <t.Elem()> {n} [off]))
diff --git a/src/cmd/compile/internal/ssa/gen/decArgsOps.go b/src/cmd/compile/internal/ssa/gen/decArgsOps.go
deleted file mode 100644
index b73d9d3..0000000
--- a/src/cmd/compile/internal/ssa/gen/decArgsOps.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package main
-
-var decArgsOps = []opData{}
-
-var decArgsBlocks = []blockData{}
-
-func init() {
-	archs = append(archs, arch{
-		name:    "decArgs",
-		ops:     decArgsOps,
-		blocks:  decArgsBlocks,
-		generic: true,
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules
index 1784923..5cbc70c 100644
--- a/src/cmd/compile/internal/ssa/gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/gen/generic.rules
@@ -768,7 +768,7 @@
 	=> mem
 
 // Collapse OffPtr
-(OffPtr (OffPtr p [b]) [a]) => (OffPtr p [a+b])
+(OffPtr (OffPtr p [y]) [x]) => (OffPtr p [x+y])
 (OffPtr p [0]) && v.Type.Compare(p.Type) == types.CMPeq => p
 
 // indexing operations
@@ -847,7 +847,7 @@
             f0 mem))))
 
 // Putting struct{*byte} and similar into direct interfaces.
-(IMake typ (StructMake1 val)) => (IMake typ val)
+(IMake _typ (StructMake1 val)) => (IMake _typ val)
 (StructSelect [0] (IData x)) => (IData x)
 
 // un-SSAable values use mem->mem copies
@@ -869,7 +869,7 @@
 (Store dst (ArrayMake1 e) mem) => (Store {e.Type} dst e mem)
 
 // Putting [1]*byte and similar into direct interfaces.
-(IMake typ (ArrayMake1 val)) => (IMake typ val)
+(IMake _typ (ArrayMake1 val)) => (IMake _typ val)
 (ArraySelect [0] (IData x)) => (IData x)
 
 // string ops
@@ -1968,43 +1968,15 @@
 (Div32F x (Const32F <t> [c])) && reciprocalExact32(c) => (Mul32F x (Const32F <t> [1/c]))
 (Div64F x (Const64F <t> [c])) && reciprocalExact64(c) => (Mul64F x (Const64F <t> [1/c]))
 
+// rewrite single-precision sqrt expression "float32(math.Sqrt(float64(x)))"
+(Cvt64Fto32F sqrt0:(Sqrt (Cvt32Fto64F x))) && sqrt0.Uses==1 => (Sqrt32 x)
+
 (Sqrt (Const64F [c])) && !math.IsNaN(math.Sqrt(c)) => (Const64F [math.Sqrt(c)])
 
-// recognize runtime.newobject and don't Zero/Nilcheck it
-(Zero (Load (OffPtr [c] (SP)) mem) mem)
-	&& mem.Op == OpStaticCall
-	&& isSameCall(mem.Aux, "runtime.newobject")
-	&& c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value
-	=> mem
-(Store (Load (OffPtr [c] (SP)) mem) x mem)
-	&& isConstZero(x)
-	&& mem.Op == OpStaticCall
-	&& isSameCall(mem.Aux, "runtime.newobject")
-	&& c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value
-	=> mem
-(Store (OffPtr (Load (OffPtr [c] (SP)) mem)) x mem)
-	&& isConstZero(x)
-	&& mem.Op == OpStaticCall
-	&& isSameCall(mem.Aux, "runtime.newobject")
-	&& c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value
-	=> mem
-// nil checks just need to rewrite to something useless.
-// they will be deadcode eliminated soon afterwards.
-(NilCheck (Load (OffPtr [c] (SP)) (StaticCall {sym} _)) _)
-	&& isSameCall(sym, "runtime.newobject")
-	&& c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value
-	&& warnRule(fe.Debug_checknil(), v, "removed nil check")
-	=> (Invalid)
-(NilCheck (OffPtr (Load (OffPtr [c] (SP)) (StaticCall {sym} _))) _)
-	&& isSameCall(sym, "runtime.newobject")
-	&& c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value
-	&& warnRule(fe.Debug_checknil(), v, "removed nil check")
-	=> (Invalid)
-
 // for rewriting results of some late-expanded rewrites (below)
-(SelectN [0] (MakeResult a ___)) => a
-(SelectN [1] (MakeResult a b ___)) => b
-(SelectN [2] (MakeResult a b c ___)) => c
+(SelectN [0] (MakeResult x ___)) => x
+(SelectN [1] (MakeResult x y ___)) => y
+(SelectN [2] (MakeResult x y z ___)) => z
 
 // for late-expanded calls, recognize newobject and remove zeroing and nilchecks
 (Zero (SelectN [0] call:(StaticLECall _ _)) mem:(SelectN [1] call))
@@ -2021,12 +1993,12 @@
 	&& isSameCall(call.Aux, "runtime.newobject")
 	=> mem
 
-(NilCheck (SelectN [0] call:(StaticLECall _ _)) (SelectN [1] call))
+(NilCheck (SelectN [0] call:(StaticLECall _ _)) _)
 	&& isSameCall(call.Aux, "runtime.newobject")
 	&& warnRule(fe.Debug_checknil(), v, "removed nil check")
 	=> (Invalid)
 
-(NilCheck (OffPtr (SelectN [0] call:(StaticLECall _ _))) (SelectN [1] call))
+(NilCheck (OffPtr (SelectN [0] call:(StaticLECall _ _))) _)
 	&& isSameCall(call.Aux, "runtime.newobject")
 	&& warnRule(fe.Debug_checknil(), v, "removed nil check")
 	=> (Invalid)
@@ -2041,18 +2013,18 @@
 // Evaluate constant address comparisons.
 (EqPtr  x x) => (ConstBool [true])
 (NeqPtr x x) => (ConstBool [false])
-(EqPtr  (Addr {a} _) (Addr {b} _)) => (ConstBool [a == b])
-(EqPtr  (Addr {a} _) (OffPtr [o] (Addr {b} _))) => (ConstBool [a == b && o == 0])
-(EqPtr  (OffPtr [o1] (Addr {a} _)) (OffPtr [o2] (Addr {b} _))) => (ConstBool [a == b && o1 == o2])
-(NeqPtr (Addr {a} _) (Addr {b} _)) => (ConstBool [a != b])
-(NeqPtr (Addr {a} _) (OffPtr [o] (Addr {b} _))) => (ConstBool [a != b || o != 0])
-(NeqPtr (OffPtr [o1] (Addr {a} _)) (OffPtr [o2] (Addr {b} _))) => (ConstBool [a != b || o1 != o2])
-(EqPtr  (LocalAddr {a} _ _) (LocalAddr {b} _ _)) => (ConstBool [a == b])
-(EqPtr  (LocalAddr {a} _ _) (OffPtr [o] (LocalAddr {b} _ _))) => (ConstBool [a == b && o == 0])
-(EqPtr  (OffPtr [o1] (LocalAddr {a} _ _)) (OffPtr [o2] (LocalAddr {b} _ _))) => (ConstBool [a == b && o1 == o2])
-(NeqPtr (LocalAddr {a} _ _) (LocalAddr {b} _ _)) => (ConstBool [a != b])
-(NeqPtr (LocalAddr {a} _ _) (OffPtr [o] (LocalAddr {b} _ _))) => (ConstBool [a != b || o != 0])
-(NeqPtr (OffPtr [o1] (LocalAddr {a} _ _)) (OffPtr [o2] (LocalAddr {b} _ _))) => (ConstBool [a != b || o1 != o2])
+(EqPtr  (Addr {x} _) (Addr {y} _)) => (ConstBool [x == y])
+(EqPtr  (Addr {x} _) (OffPtr [o] (Addr {y} _))) => (ConstBool [x == y && o == 0])
+(EqPtr  (OffPtr [o1] (Addr {x} _)) (OffPtr [o2] (Addr {y} _))) => (ConstBool [x == y && o1 == o2])
+(NeqPtr (Addr {x} _) (Addr {y} _)) => (ConstBool [x != y])
+(NeqPtr (Addr {x} _) (OffPtr [o] (Addr {y} _))) => (ConstBool [x != y || o != 0])
+(NeqPtr (OffPtr [o1] (Addr {x} _)) (OffPtr [o2] (Addr {y} _))) => (ConstBool [x != y || o1 != o2])
+(EqPtr  (LocalAddr {x} _ _) (LocalAddr {y} _ _)) => (ConstBool [x == y])
+(EqPtr  (LocalAddr {x} _ _) (OffPtr [o] (LocalAddr {y} _ _))) => (ConstBool [x == y && o == 0])
+(EqPtr  (OffPtr [o1] (LocalAddr {x} _ _)) (OffPtr [o2] (LocalAddr {y} _ _))) => (ConstBool [x == y && o1 == o2])
+(NeqPtr (LocalAddr {x} _ _) (LocalAddr {y} _ _)) => (ConstBool [x != y])
+(NeqPtr (LocalAddr {x} _ _) (OffPtr [o] (LocalAddr {y} _ _))) => (ConstBool [x != y || o != 0])
+(NeqPtr (OffPtr [o1] (LocalAddr {x} _ _)) (OffPtr [o2] (LocalAddr {y} _ _))) => (ConstBool [x != y || o1 != o2])
 (EqPtr  (OffPtr [o1] p1) p2) && isSamePtr(p1, p2) => (ConstBool [o1 == 0])
 (NeqPtr (OffPtr [o1] p1) p2) && isSamePtr(p1, p2) => (ConstBool [o1 != 0])
 (EqPtr  (OffPtr [o1] p1) (OffPtr [o2] p2)) && isSamePtr(p1, p2) => (ConstBool [o1 == o2])
@@ -2085,32 +2057,39 @@
 
 // Inline small or disjoint runtime.memmove calls with constant length.
 // See the comment in op Move in genericOps.go for discussion of the type.
-(StaticCall {sym} s1:(Store _ (Const(64|32) [sz]) s2:(Store  _ src s3:(Store {t} _ dst mem))))
+
+// Because expand calls runs after prove, constants useful to this pattern may not appear.
+// Both versions need to exist; the memory and register variants.
+//
+// Match post-expansion calls, memory version.
+(SelectN [0] call:(StaticCall {sym} s1:(Store _ (Const(64|32) [sz]) s2:(Store  _ src s3:(Store {t} _ dst mem)))))
 	&& sz >= 0
 	&& isSameCall(sym, "runtime.memmove")
-	&& t.IsPtr() // avoids TUINTPTR, see issue 30061
+	&& t.IsPtr() // avoids TUNSAFEPTR, see issue 30061
 	&& s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
 	&& isInlinableMemmove(dst, src, int64(sz), config)
-	&& clobber(s1, s2, s3)
+	&& clobber(s1, s2, s3, call)
 	=> (Move {t.Elem()} [int64(sz)] dst src mem)
 
-// Inline small or disjoint runtime.memmove calls with constant length.
-// See the comment in op Move in genericOps.go for discussion of the type.
-(SelectN [0] call:(StaticLECall {sym} dst src (Const(64|32) [sz]) mem))
+// Match post-expansion calls, register version.
+(SelectN [0] call:(StaticCall {sym} dst src (Const(64|32) [sz]) mem))
 	&& sz >= 0
 	&& call.Uses == 1 // this will exclude all calls with results
 	&& isSameCall(sym, "runtime.memmove")
-	&& dst.Type.IsPtr() // avoids TUINTPTR, see issue 30061
+	&& dst.Type.IsPtr() // avoids TUNSAFEPTR, see issue 30061
 	&& isInlinableMemmove(dst, src, int64(sz), config)
 	&& clobber(call)
 	=> (Move {dst.Type.Elem()} [int64(sz)] dst src mem)
 
-// De-virtualize interface calls into static calls.
-// Note that (ITab (IMake)) doesn't get
-// rewritten until after the first opt pass,
-// so this rule should trigger reliably.
-(InterCall [argsize] {auxCall} (Load (OffPtr [off] (ITab (IMake (Addr {itab} (SB)) _))) _) mem) && devirt(v, auxCall, itab, off) != nil =>
-	(StaticCall [int32(argsize)] {devirt(v, auxCall, itab, off)} mem)
+// Match pre-expansion calls.
+(SelectN [0] call:(StaticLECall {sym} dst src (Const(64|32) [sz]) mem))
+	&& sz >= 0
+	&& call.Uses == 1 // this will exclude all calls with results
+	&& isSameCall(sym, "runtime.memmove")
+	&& dst.Type.IsPtr() // avoids TUNSAFEPTR, see issue 30061
+	&& isInlinableMemmove(dst, src, int64(sz), config)
+	&& clobber(call)
+	=> (Move {dst.Type.Elem()} [int64(sz)] dst src mem)
 
 // De-virtualize late-expanded interface calls into late-expanded static calls.
 // Note that (ITab (IMake)) doesn't get rewritten until after the first opt pass,
@@ -2499,8 +2478,8 @@
 				(Store {t5} (OffPtr <tt5> [o5] dst) d4
 					(Zero {t1} [n] dst mem)))))
 
-// TODO this does not fire before call expansion; is that acceptable?
-(StaticCall {sym} x) && needRaceCleanup(sym, v) => x
+(SelectN [0] call:(StaticLECall {sym} a x)) && needRaceCleanup(sym, call) && clobber(call) => x
+(SelectN [0] call:(StaticLECall {sym} x)) && needRaceCleanup(sym, call) && clobber(call) => x
 
 // Collapse moving A -> B -> C into just A -> C.
 // Later passes (deadstore, elim unread auto) will remove the A -> B move, if possible.
diff --git a/src/cmd/compile/internal/ssa/gen/genericOps.go b/src/cmd/compile/internal/ssa/gen/genericOps.go
index 8cfda35..9f66643 100644
--- a/src/cmd/compile/internal/ssa/gen/genericOps.go
+++ b/src/cmd/compile/internal/ssa/gen/genericOps.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 package main
@@ -257,13 +258,14 @@
 	{name: "RotateLeft32", argLength: 2}, // Rotate bits in arg[0] left by arg[1]
 	{name: "RotateLeft64", argLength: 2}, // Rotate bits in arg[0] left by arg[1]
 
-	// Square root, float64 only.
+	// Square root.
 	// Special cases:
 	//   +∞  → +∞
 	//   ±0  → ±0 (sign preserved)
 	//   x<0 → NaN
 	//   NaN → NaN
-	{name: "Sqrt", argLength: 1}, // √arg0
+	{name: "Sqrt", argLength: 1},   // √arg0 (floating point, double precision)
+	{name: "Sqrt32", argLength: 1}, // √arg0 (floating point, single precision)
 
 	// Round to integer, float64 only.
 	// Special cases:
@@ -332,6 +334,11 @@
 	{name: "InitMem", zeroWidth: true},                               // memory input to the function.
 	{name: "Arg", aux: "SymOff", symEffect: "Read", zeroWidth: true}, // argument to the function.  aux=GCNode of arg, off = offset in that arg.
 
+	// Like Arg, these are generic ops that survive lowering. AuxInt is a register index, and the actual output register for each index is defined by the architecture.
+	// AuxInt = integer argument index (not a register number). ABI-specified spill loc obtained from function
+	{name: "ArgIntReg", aux: "NameOffsetInt8", zeroWidth: true},   // argument to the function in an int reg.
+	{name: "ArgFloatReg", aux: "NameOffsetInt8", zeroWidth: true}, // argument to the function in a float reg.
+
 	// The address of a variable.  arg0 is the base pointer.
 	// If the variable is a global, the base pointer will be SB and
 	// the Aux field will be a *obj.LSym.
@@ -389,9 +396,28 @@
 	// TODO(josharian): ClosureCall and InterCall should have Int32 aux
 	// to match StaticCall's 32 bit arg size limit.
 	// TODO(drchase,josharian): could the arg size limit be bundled into the rules for CallOff?
-	{name: "ClosureCall", argLength: 3, aux: "CallOff", call: true},    // arg0=code pointer, arg1=context ptr, arg2=memory.  auxint=arg size.  Returns memory.
-	{name: "StaticCall", argLength: 1, aux: "CallOff", call: true},     // call function aux.(*obj.LSym), arg0=memory.  auxint=arg size.  Returns memory.
-	{name: "InterCall", argLength: 2, aux: "CallOff", call: true},      // interface call.  arg0=code pointer, arg1=memory, auxint=arg size.  Returns memory.
+
+	// Before lowering, LECalls receive their fixed inputs (first), memory (last),
+	// and a variable number of input values in the middle.
+	// They produce a variable number of result values.
+	// These values are not necessarily "SSA-able"; they can be too large,
+	// but in that case inputs are loaded immediately before with OpDereference,
+	// and outputs are stored immediately with OpStore.
+	//
+	// After call expansion, Calls have the same fixed-middle-memory arrangement of inputs,
+	// with the difference that the "middle" is only the register-resident inputs,
+	// and the non-register inputs are instead stored at ABI-defined offsets from SP
+	// (and the stores thread through the memory that is ultimately an input to the call).
+	// Outputs follow a similar pattern; register-resident outputs are the leading elements
+	// of a Result-typed output, with memory last, and any memory-resident outputs have been
+	// stored to ABI-defined locations.  Each non-memory input or output fits in a register.
+	//
+	// Subsequent architecture-specific lowering only changes the opcode.
+
+	{name: "ClosureCall", argLength: -1, aux: "CallOff", call: true}, // arg0=code pointer, arg1=context ptr, arg2..argN-1 are register inputs, argN=memory.  auxint=arg size.  Returns Result of register results, plus memory.
+	{name: "StaticCall", argLength: -1, aux: "CallOff", call: true},  // call function aux.(*obj.LSym), arg0..argN-1 are register inputs, argN=memory.  auxint=arg size.  Returns Result of register results, plus memory.
+	{name: "InterCall", argLength: -1, aux: "CallOff", call: true},   // interface call.  arg0=code pointer, arg1..argN-1 are register inputs, argN=memory, auxint=arg size.  Returns Result of register results, plus memory.
+
 	{name: "ClosureLECall", argLength: -1, aux: "CallOff", call: true}, // late-expanded closure call. arg0=code pointer, arg1=context ptr,  arg2..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
 	{name: "StaticLECall", argLength: -1, aux: "CallOff", call: true},  // late-expanded static call function aux.(*ssa.AuxCall.Fn). arg0..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
 	{name: "InterLECall", argLength: -1, aux: "CallOff", call: true},   // late-expanded interface call. arg0=code pointer, arg1..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
@@ -453,6 +479,10 @@
 	{name: "SlicePtr", argLength: 1, typ: "BytePtr"}, // ptr(arg0)
 	{name: "SliceLen", argLength: 1},                 // len(arg0)
 	{name: "SliceCap", argLength: 1},                 // cap(arg0)
+	// SlicePtrUnchecked, like SlicePtr, extracts the pointer from a slice.
+	// SlicePtr values are assumed non-nil, because they are guarded by bounds checks.
+	// SlicePtrUnchecked values can be nil.
+	{name: "SlicePtrUnchecked", argLength: 1},
 
 	// Complex (part/whole)
 	{name: "ComplexMake", argLength: 2}, // arg0=real, arg1=imag
@@ -587,6 +617,7 @@
 
 	// Clobber experiment op
 	{name: "Clobber", argLength: 0, typ: "Void", aux: "SymOff", symEffect: "None"}, // write an invalid pointer value to the given pointer slot of a stack variable
+	{name: "ClobberReg", argLength: 0, typ: "Void"},                                // clobber a register
 }
 
 //     kind          controls        successors   implicit exit
diff --git a/src/cmd/compile/internal/ssa/gen/main.go b/src/cmd/compile/internal/ssa/gen/main.go
index dfa146a..8e5997b 100644
--- a/src/cmd/compile/internal/ssa/gen/main.go
+++ b/src/cmd/compile/internal/ssa/gen/main.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // The gen command generates Go code (in the parent directory) for all
@@ -30,21 +31,23 @@
 // apart from type names, and avoid awkward func parameters like "arch arch".
 
 type arch struct {
-	name            string
-	pkg             string // obj package to import for this arch.
-	genfile         string // source file containing opcode code generation.
-	ops             []opData
-	blocks          []blockData
-	regnames        []string
-	gpregmask       regMask
-	fpregmask       regMask
-	fp32regmask     regMask
-	fp64regmask     regMask
-	specialregmask  regMask
-	framepointerreg int8
-	linkreg         int8
-	generic         bool
-	imports         []string
+	name               string
+	pkg                string // obj package to import for this arch.
+	genfile            string // source file containing opcode code generation.
+	ops                []opData
+	blocks             []blockData
+	regnames           []string
+	ParamIntRegNames   string
+	ParamFloatRegNames string
+	gpregmask          regMask
+	fpregmask          regMask
+	fp32regmask        regMask
+	fp64regmask        regMask
+	specialregmask     regMask
+	framepointerreg    int8
+	linkreg            int8
+	generic            bool
+	imports            []string
 }
 
 type opData struct {
@@ -63,7 +66,6 @@
 	nilCheck          bool   // this op is a nil check on arg0
 	faultOnNilArg0    bool   // this op will fault if arg0 is nil (and aux encodes a small offset)
 	faultOnNilArg1    bool   // this op will fault if arg1 is nil (and aux encodes a small offset)
-	usesScratch       bool   // this op requires scratch memory space
 	hasSideEffects    bool   // for "reasons", not to be eliminated.  E.g., atomic store, #19182.
 	zeroWidth         bool   // op never translates into any machine code. example: copy, which may sometimes translate to machine code, is not zero-width.
 	unsafePoint       bool   // this op is an unsafe point, i.e. not safe for async preemption
@@ -320,9 +322,6 @@
 					log.Fatalf("faultOnNilArg1 with aux %s not allowed", v.aux)
 				}
 			}
-			if v.usesScratch {
-				fmt.Fprintln(w, "usesScratch: true,")
-			}
 			if v.hasSideEffects {
 				fmt.Fprintln(w, "hasSideEffects: true,")
 			}
@@ -404,12 +403,11 @@
 	// generate op string method
 	fmt.Fprintln(w, "func (o Op) String() string {return opcodeTable[o].name }")
 
-	fmt.Fprintln(w, "func (o Op) UsesScratch() bool { return opcodeTable[o].usesScratch }")
-
 	fmt.Fprintln(w, "func (o Op) SymEffect() SymEffect { return opcodeTable[o].symEffect }")
 	fmt.Fprintln(w, "func (o Op) IsCall() bool { return opcodeTable[o].call }")
 	fmt.Fprintln(w, "func (o Op) HasSideEffects() bool { return opcodeTable[o].hasSideEffects }")
 	fmt.Fprintln(w, "func (o Op) UnsafePoint() bool { return opcodeTable[o].unsafePoint }")
+	fmt.Fprintln(w, "func (o Op) ResultInArg0() bool { return opcodeTable[o].resultInArg0 }")
 
 	// generate registers
 	for _, a := range archs {
@@ -418,7 +416,9 @@
 		}
 		fmt.Fprintf(w, "var registers%s = [...]Register {\n", a.name)
 		var gcRegN int
+		num := map[string]int8{}
 		for i, r := range a.regnames {
+			num[r] = int8(i)
 			pkg := a.pkg[len("cmd/internal/obj/"):]
 			var objname string // name in cmd/internal/obj/$ARCH
 			switch r {
@@ -441,11 +441,38 @@
 			}
 			fmt.Fprintf(w, "  {%d, %s, %d, \"%s\"},\n", i, objname, gcRegIdx, r)
 		}
+		parameterRegisterList := func(paramNamesString string) []int8 {
+			paramNamesString = strings.TrimSpace(paramNamesString)
+			if paramNamesString == "" {
+				return nil
+			}
+			paramNames := strings.Split(paramNamesString, " ")
+			var paramRegs []int8
+			for _, regName := range paramNames {
+				if regName == "" {
+					// forgive extra spaces
+					continue
+				}
+				if regNum, ok := num[regName]; ok {
+					paramRegs = append(paramRegs, regNum)
+					delete(num, regName)
+				} else {
+					log.Fatalf("parameter register %s for architecture %s not a register name (or repeated in parameter list)", regName, a.name)
+				}
+			}
+			return paramRegs
+		}
+
+		paramIntRegs := parameterRegisterList(a.ParamIntRegNames)
+		paramFloatRegs := parameterRegisterList(a.ParamFloatRegNames)
+
 		if gcRegN > 32 {
 			// Won't fit in a uint32 mask.
 			log.Fatalf("too many GC registers (%d > 32) on %s", gcRegN, a.name)
 		}
 		fmt.Fprintln(w, "}")
+		fmt.Fprintf(w, "var paramIntReg%s = %#v\n", a.name, paramIntRegs)
+		fmt.Fprintf(w, "var paramFloatReg%s = %#v\n", a.name, paramFloatRegs)
 		fmt.Fprintf(w, "var gpRegMask%s = regMask(%d)\n", a.name, a.gpregmask)
 		fmt.Fprintf(w, "var fpRegMask%s = regMask(%d)\n", a.name, a.fpregmask)
 		if a.fp32regmask != 0 {
diff --git a/src/cmd/compile/internal/ssa/gen/rulegen.go b/src/cmd/compile/internal/ssa/gen/rulegen.go
index aaf9101..fe8db4e 100644
--- a/src/cmd/compile/internal/ssa/gen/rulegen.go
+++ b/src/cmd/compile/internal/ssa/gen/rulegen.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gen
 // +build gen
 
 // This program generates Go code that applies rewrite rules to a Value.
@@ -194,7 +195,9 @@
 		swc.add(stmtf("return rewriteValue%s%s_%s(v)", arch.name, suff, op))
 		sw.add(swc)
 	}
-	fn.add(sw)
+	if len(sw.List) > 0 { // skip if empty
+		fn.add(sw)
+	}
 	fn.add(stmtf("return false"))
 	genFile.add(fn)
 
@@ -215,10 +218,10 @@
 			Suffix: fmt.Sprintf("_%s", op),
 			ArgLen: opByName(arch, op).argLength,
 		}
-		fn.add(declf("b", "v.Block"))
-		fn.add(declf("config", "b.Func.Config"))
-		fn.add(declf("fe", "b.Func.fe"))
-		fn.add(declf("typ", "&b.Func.Config.Types"))
+		fn.add(declReserved("b", "v.Block"))
+		fn.add(declReserved("config", "b.Func.Config"))
+		fn.add(declReserved("fe", "b.Func.fe"))
+		fn.add(declReserved("typ", "&b.Func.Config.Types"))
 		for _, rule := range rules {
 			if rr != nil && !rr.CanFail {
 				log.Fatalf("unconditional rule %s is followed by other rules", rr.Match)
@@ -247,8 +250,8 @@
 	// Generate block rewrite function. There are only a few block types
 	// so we can make this one function with a switch.
 	fn = &Func{Kind: "Block"}
-	fn.add(declf("config", "b.Func.Config"))
-	fn.add(declf("typ", "&b.Func.Config.Types"))
+	fn.add(declReserved("config", "b.Func.Config"))
+	fn.add(declReserved("typ", "&b.Func.Config.Types"))
 
 	sw = &Switch{Expr: exprf("b.Kind")}
 	ops = ops[:0]
@@ -264,7 +267,9 @@
 		}
 		sw.add(swc)
 	}
-	fn.add(sw)
+	if len(sw.List) > 0 { // skip if empty
+		fn.add(sw)
+	}
 	fn.add(stmtf("return false"))
 	genFile.add(fn)
 
@@ -579,9 +584,10 @@
 		fmt.Fprintf(w, "\npackage ssa\n")
 		for _, path := range append([]string{
 			"fmt",
+			"internal/buildcfg",
 			"math",
 			"cmd/internal/obj",
-			"cmd/internal/objabi",
+			"cmd/compile/internal/base",
 			"cmd/compile/internal/types",
 		}, n.Arch.imports...) {
 			fmt.Fprintf(w, "import %q\n", path)
@@ -822,12 +828,36 @@
 	return file.Decls[0].(*ast.FuncDecl).Body.List[0]
 }
 
-// declf constructs a simple "name := value" declaration, using exprf for its
-// value.
-func declf(name, format string, a ...interface{}) *Declare {
+var reservedNames = map[string]bool{
+	"v":      true, // Values[i], etc
+	"b":      true, // v.Block
+	"config": true, // b.Func.Config
+	"fe":     true, // b.Func.fe
+	"typ":    true, // &b.Func.Config.Types
+}
+
+// declf constructs a simple "name := value" declaration,
+// using exprf for its value.
+//
+// name must not be one of reservedNames.
+// This helps prevent unintended shadowing and name clashes.
+// To declare a reserved name, use declReserved.
+func declf(loc, name, format string, a ...interface{}) *Declare {
+	if reservedNames[name] {
+		log.Fatalf("rule %s uses the reserved name %s", loc, name)
+	}
 	return &Declare{name, exprf(format, a...)}
 }
 
+// declReserved is like declf, but the name must be one of reservedNames.
+// Calls to declReserved should generally be static and top-level.
+func declReserved(name, value string) *Declare {
+	if !reservedNames[name] {
+		panic(fmt.Sprintf("declReserved call does not use a reserved name: %q", name))
+	}
+	return &Declare{name, exprf(value)}
+}
+
 // breakf constructs a simple "if cond { break }" statement, using exprf for its
 // condition.
 func breakf(format string, a ...interface{}) *CondBreak {
@@ -852,7 +882,7 @@
 			if vname == "" {
 				vname = fmt.Sprintf("v_%v", i)
 			}
-			rr.add(declf(vname, cname))
+			rr.add(declf(rr.Loc, vname, cname))
 			p, op := genMatch0(rr, arch, expr, vname, nil, false) // TODO: pass non-nil cnt?
 			if op != "" {
 				check := fmt.Sprintf("%s.Op == %s", cname, op)
@@ -867,7 +897,7 @@
 			}
 			pos[i] = p
 		} else {
-			rr.add(declf(arg, cname))
+			rr.add(declf(rr.Loc, arg, cname))
 			pos[i] = arg + ".Pos"
 		}
 	}
@@ -887,7 +917,7 @@
 		if !token.IsIdentifier(e.name) || rr.declared(e.name) {
 			rr.add(breakf("%sTo%s(b.%s) != %s", unTitle(e.field), title(e.dclType), e.field, e.name))
 		} else {
-			rr.add(declf(e.name, "%sTo%s(b.%s)", unTitle(e.field), title(e.dclType), e.field))
+			rr.add(declf(rr.Loc, e.name, "%sTo%s(b.%s)", unTitle(e.field), title(e.dclType), e.field))
 		}
 	}
 	if rr.Cond != "" {
@@ -1037,11 +1067,11 @@
 		} else {
 			switch e.field {
 			case "Aux":
-				rr.add(declf(e.name, "auxTo%s(%s.%s)", title(e.dclType), v, e.field))
+				rr.add(declf(rr.Loc, e.name, "auxTo%s(%s.%s)", title(e.dclType), v, e.field))
 			case "AuxInt":
-				rr.add(declf(e.name, "auxIntTo%s(%s.%s)", title(e.dclType), v, e.field))
+				rr.add(declf(rr.Loc, e.name, "auxIntTo%s(%s.%s)", title(e.dclType), v, e.field))
 			case "Type":
-				rr.add(declf(e.name, "%s.%s", v, e.field))
+				rr.add(declf(rr.Loc, e.name, "%s.%s", v, e.field))
 			}
 		}
 	}
@@ -1071,7 +1101,7 @@
 				continue
 			}
 			if !rr.declared(a) && token.IsIdentifier(a) && !(commutative && len(args) == 2) {
-				rr.add(declf(a, "%s.Args[%d]", v, n))
+				rr.add(declf(rr.Loc, a, "%s.Args[%d]", v, n))
 				// delete the last argument so it is not reprocessed
 				args = args[:n]
 			} else {
@@ -1083,7 +1113,7 @@
 	if commutative && !pregenTop {
 		for i := 0; i <= 1; i++ {
 			vname := fmt.Sprintf("%s_%d", v, i)
-			rr.add(declf(vname, "%s.Args[%d]", v, i))
+			rr.add(declf(rr.Loc, vname, "%s.Args[%d]", v, i))
 		}
 	}
 	if commutative {
@@ -1110,7 +1140,7 @@
 				rr.add(breakf("%s != %s", arg, rhs))
 			} else {
 				if arg != rhs {
-					rr.add(declf(arg, "%s", rhs))
+					rr.add(declf(rr.Loc, arg, "%s", rhs))
 				}
 			}
 			continue
@@ -1125,7 +1155,7 @@
 		}
 
 		if argname != rhs {
-			rr.add(declf(argname, "%s", rhs))
+			rr.add(declf(rr.Loc, argname, "%s", rhs))
 		}
 		bexpr := exprf("%s.Op != addLater", argname)
 		rr.add(&CondBreak{Cond: bexpr})
@@ -1202,7 +1232,7 @@
 			v = resname
 		}
 		rr.Alloc++
-		rr.add(declf(v, "b.NewValue0(%s, Op%s%s, %s)", pos, oparch, op.name, typ))
+		rr.add(declf(rr.Loc, v, "b.NewValue0(%s, Op%s%s, %s)", pos, oparch, op.name, typ))
 		if move && top {
 			// Rewrite original into a copy
 			rr.add(stmtf("v.copyOf(%s)", v))
diff --git a/src/cmd/compile/internal/ssa/html.go b/src/cmd/compile/internal/ssa/html.go
index c06b580..4d19119 100644
--- a/src/cmd/compile/internal/ssa/html.go
+++ b/src/cmd/compile/internal/ssa/html.go
@@ -1064,7 +1064,7 @@
 	p := htmlFuncPrinter{w: buf}
 	fprintFunc(p, f)
 
-	// fprintFunc(&buf, f) // TODO: HTML, not text, <br /> for line breaks, etc.
+	// fprintFunc(&buf, f) // TODO: HTML, not text, <br> for line breaks, etc.
 	fmt.Fprint(buf, "</code>")
 	return buf.String()
 }
diff --git a/src/cmd/compile/internal/ssa/layout.go b/src/cmd/compile/internal/ssa/layout.go
index 30b7b97..6abdb0d 100644
--- a/src/cmd/compile/internal/ssa/layout.go
+++ b/src/cmd/compile/internal/ssa/layout.go
@@ -12,26 +12,10 @@
 }
 
 // Register allocation may use a different order which has constraints
-// imposed by the linear-scan algorithm. Note that f.pass here is
-// regalloc, so the switch is conditional on -d=ssa/regalloc/test=N
+// imposed by the linear-scan algorithm.
 func layoutRegallocOrder(f *Func) []*Block {
-
-	switch f.pass.test {
-	case 0: // layout order
-		return layoutOrder(f)
-	case 1: // existing block order
-		return f.Blocks
-	case 2: // reverse of postorder; legal, but usually not good.
-		po := f.postorder()
-		visitOrder := make([]*Block, len(po))
-		for i, b := range po {
-			j := len(po) - i - 1
-			visitOrder[j] = b
-		}
-		return visitOrder
-	}
-
-	return nil
+	// remnant of an experiment; perhaps there will be another.
+	return layoutOrder(f)
 }
 
 func layoutOrder(f *Func) []*Block {
@@ -41,8 +25,13 @@
 	indegree := make([]int, f.NumBlocks())
 	posdegree := f.newSparseSet(f.NumBlocks()) // blocks with positive remaining degree
 	defer f.retSparseSet(posdegree)
-	zerodegree := f.newSparseSet(f.NumBlocks()) // blocks with zero remaining degree
-	defer f.retSparseSet(zerodegree)
+	// blocks with zero remaining degree. Use slice to simulate a LIFO queue to implement
+	// the depth-first topology sorting algorithm.
+	var zerodegree []ID
+	// LIFO queue. Track the successor blocks of the scheduled block so that when we
+	// encounter loops, we choose to schedule the successor block of the most recently
+	// scheduled block.
+	var succs []ID
 	exit := f.newSparseSet(f.NumBlocks()) // exit blocks
 	defer f.retSparseSet(exit)
 
@@ -88,7 +77,8 @@
 		}
 		indegree[b.ID] = len(b.Preds)
 		if len(b.Preds) == 0 {
-			zerodegree.add(b.ID)
+			// Push an element to the tail of the queue.
+			zerodegree = append(zerodegree, b.ID)
 		} else {
 			posdegree.add(b.ID)
 		}
@@ -105,12 +95,24 @@
 			break
 		}
 
-		for _, e := range b.Succs {
-			c := e.b
+		// Here, the order of traversing the b.Succs affects the direction in which the topological
+		// sort advances in depth. Take the following cfg as an example, regardless of other factors.
+		//           b1
+		//         0/ \1
+		//        b2   b3
+		// Traverse b.Succs in order, the right child node b3 will be scheduled immediately after
+		// b1, traverse b.Succs in reverse order, the left child node b2 will be scheduled
+		// immediately after b1. The test results show that reverse traversal performs a little
+		// better.
+		// Note: You need to consider both layout and register allocation when testing performance.
+		for i := len(b.Succs) - 1; i >= 0; i-- {
+			c := b.Succs[i].b
 			indegree[c.ID]--
 			if indegree[c.ID] == 0 {
 				posdegree.remove(c.ID)
-				zerodegree.add(c.ID)
+				zerodegree = append(zerodegree, c.ID)
+			} else {
+				succs = append(succs, c.ID)
 			}
 		}
 
@@ -132,30 +134,30 @@
 
 		// Use degree for now.
 		bid = 0
-		mindegree := f.NumBlocks()
-		for _, e := range order[len(order)-1].Succs {
-			c := e.b
-			if scheduled[c.ID] || c.Kind == BlockExit {
-				continue
-			}
-			if indegree[c.ID] < mindegree {
-				mindegree = indegree[c.ID]
-				bid = c.ID
-			}
-		}
-		if bid != 0 {
-			continue
-		}
 		// TODO: improve this part
 		// No successor of the previously scheduled block works.
 		// Pick a zero-degree block if we can.
-		for zerodegree.size() > 0 {
-			cid := zerodegree.pop()
+		for len(zerodegree) > 0 {
+			// Pop an element from the tail of the queue.
+			cid := zerodegree[len(zerodegree)-1]
+			zerodegree = zerodegree[:len(zerodegree)-1]
 			if !scheduled[cid] {
 				bid = cid
 				continue blockloop
 			}
 		}
+
+		// Still nothing, pick the unscheduled successor block encountered most recently.
+		for len(succs) > 0 {
+			// Pop an element from the tail of the queue.
+			cid := succs[len(succs)-1]
+			succs = succs[:len(succs)-1]
+			if !scheduled[cid] {
+				bid = cid
+				continue blockloop
+			}
+		}
+
 		// Still nothing, pick any non-exit block.
 		for posdegree.size() > 0 {
 			cid := posdegree.pop()
diff --git a/src/cmd/compile/internal/ssa/lca.go b/src/cmd/compile/internal/ssa/lca.go
index 5cb7391..90daebe 100644
--- a/src/cmd/compile/internal/ssa/lca.go
+++ b/src/cmd/compile/internal/ssa/lca.go
@@ -4,6 +4,10 @@
 
 package ssa
 
+import (
+	"math/bits"
+)
+
 // Code to compute lowest common ancestors in the dominator tree.
 // https://en.wikipedia.org/wiki/Lowest_common_ancestor
 // https://en.wikipedia.org/wiki/Range_minimum_query#Solution_using_constant_time_and_linearithmic_space
@@ -79,7 +83,7 @@
 	}
 
 	// Compute fast range-minimum query data structure
-	var rangeMin [][]ID
+	rangeMin := make([][]ID, 0, bits.Len64(uint64(len(tour))))
 	rangeMin = append(rangeMin, tour) // 1-size windows are just the tour itself.
 	for logS, s := 1, 2; s < len(tour); logS, s = logS+1, s*2 {
 		r := make([]ID, len(tour)-s+1)
diff --git a/src/cmd/compile/internal/ssa/likelyadjust.go b/src/cmd/compile/internal/ssa/likelyadjust.go
index 49898a1..f462bf2 100644
--- a/src/cmd/compile/internal/ssa/likelyadjust.go
+++ b/src/cmd/compile/internal/ssa/likelyadjust.go
@@ -222,6 +222,7 @@
 				if opcodeTable[v.Op].call {
 					local[b.ID] = blCALL
 					certain[b.ID] = max8(blCALL, certain[b.Succs[0].b.ID])
+					break
 				}
 			}
 		}
diff --git a/src/cmd/compile/internal/ssa/location.go b/src/cmd/compile/internal/ssa/location.go
index a333982..252c47c 100644
--- a/src/cmd/compile/internal/ssa/location.go
+++ b/src/cmd/compile/internal/ssa/location.go
@@ -5,6 +5,7 @@
 package ssa
 
 import (
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/types"
 	"fmt"
 )
@@ -59,7 +60,7 @@
 //                           { 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.
+	N    *ir.Name    // an ONAME *ir.Name representing a stack location.
 	Type *types.Type // type of slot
 	Off  int64       // offset of slot in N
 
@@ -86,3 +87,23 @@
 	}
 	return fmt.Sprintf("<%s,%s>", n0, n1)
 }
+
+type LocResults []Location
+
+func (t LocResults) String() string {
+	s := "<"
+	a := ""
+	for _, r := range t {
+		a += s
+		s = ","
+		a += r.String()
+	}
+	a += ">"
+	return a
+}
+
+type Spill struct {
+	Type   *types.Type
+	Offset int64
+	Reg    int16
+}
diff --git a/src/cmd/compile/internal/ssa/loopreschedchecks.go b/src/cmd/compile/internal/ssa/loopreschedchecks.go
index 9c73bcf..738c626 100644
--- a/src/cmd/compile/internal/ssa/loopreschedchecks.go
+++ b/src/cmd/compile/internal/ssa/loopreschedchecks.go
@@ -246,7 +246,8 @@
 		//    mem1 := call resched (mem0)
 		//    goto header
 		resched := f.fe.Syslook("goschedguarded")
-		mem1 := sched.NewValue1A(bb.Pos, OpStaticCall, types.TypeMem, StaticAuxCall(resched, nil, nil), mem0)
+		// TODO(register args) -- will need more details
+		mem1 := sched.NewValue1A(bb.Pos, OpStaticCall, types.TypeMem, StaticAuxCall(resched, nil), mem0)
 		sched.AddEdgeTo(h)
 		headerMemPhi.AddArg(mem1)
 
diff --git a/src/cmd/compile/internal/ssa/looprotate.go b/src/cmd/compile/internal/ssa/looprotate.go
index 2e5e421..35010a7 100644
--- a/src/cmd/compile/internal/ssa/looprotate.go
+++ b/src/cmd/compile/internal/ssa/looprotate.go
@@ -68,12 +68,15 @@
 			if nextb == p { // original loop predecessor is next
 				break
 			}
-			if loopnest.b2l[nextb.ID] != loop { // about to leave loop
-				break
+			if loopnest.b2l[nextb.ID] == loop {
+				after[p.ID] = append(after[p.ID], nextb)
 			}
-			after[p.ID] = append(after[p.ID], nextb)
 			b = nextb
 		}
+		// Swap b and p so that we'll handle p before b when moving blocks.
+		f.Blocks[idToIdx[loop.header.ID]] = p
+		f.Blocks[idToIdx[p.ID]] = loop.header
+		idToIdx[loop.header.ID], idToIdx[p.ID] = idToIdx[p.ID], idToIdx[loop.header.ID]
 
 		// Place b after p.
 		for _, b := range after[p.ID] {
@@ -86,21 +89,23 @@
 	// before the rest of the loop.  And that relies on the
 	// fact that we only identify reducible loops.
 	j := 0
-	for i, b := range f.Blocks {
+	// Some blocks that are not part of a loop may be placed
+	// between loop blocks. In order to avoid these blocks from
+	// being overwritten, use a temporary slice.
+	newOrder := make([]*Block, 0, f.NumBlocks())
+	for _, b := range f.Blocks {
 		if _, ok := move[b.ID]; ok {
 			continue
 		}
-		f.Blocks[j] = b
+		newOrder = append(newOrder, b)
 		j++
 		for _, a := range after[b.ID] {
-			if j > i {
-				f.Fatalf("head before tail in loop %s", b)
-			}
-			f.Blocks[j] = a
+			newOrder = append(newOrder, a)
 			j++
 		}
 	}
 	if j != len(f.Blocks) {
 		f.Fatalf("bad reordering in looprotate")
 	}
+	f.Blocks = newOrder
 }
diff --git a/src/cmd/compile/internal/ssa/lower.go b/src/cmd/compile/internal/ssa/lower.go
index f332b2e..5760c35 100644
--- a/src/cmd/compile/internal/ssa/lower.go
+++ b/src/cmd/compile/internal/ssa/lower.go
@@ -21,8 +21,12 @@
 				continue // lowered
 			}
 			switch v.Op {
-			case OpSP, OpSB, OpInitMem, OpArg, OpPhi, OpVarDef, OpVarKill, OpVarLive, OpKeepAlive, OpSelect0, OpSelect1, OpConvert, OpInlMark:
+			case OpSP, OpSB, OpInitMem, OpArg, OpArgIntReg, OpArgFloatReg, OpPhi, OpVarDef, OpVarKill, OpVarLive, OpKeepAlive, OpSelect0, OpSelect1, OpSelectN, OpConvert, OpInlMark:
 				continue // ok not to lower
+			case OpMakeResult:
+				if b.Controls[0] == v {
+					continue
+				}
 			case OpGetG:
 				if f.Config.hasGReg {
 					// has hardware g register, regalloc takes care of it
@@ -30,6 +34,7 @@
 				}
 			}
 			s := "not lowered: " + v.String() + ", " + v.Op.String() + " " + v.Type.SimpleString()
+
 			for _, a := range v.Args {
 				s += " " + a.Type.SimpleString()
 			}
diff --git a/src/cmd/compile/internal/ssa/nilcheck.go b/src/cmd/compile/internal/ssa/nilcheck.go
index d1bad52..14f511a 100644
--- a/src/cmd/compile/internal/ssa/nilcheck.go
+++ b/src/cmd/compile/internal/ssa/nilcheck.go
@@ -5,8 +5,9 @@
 package ssa
 
 import (
-	"cmd/internal/objabi"
+	"cmd/compile/internal/ir"
 	"cmd/internal/src"
+	"internal/buildcfg"
 )
 
 // nilcheckelim eliminates unnecessary nil checks.
@@ -191,7 +192,7 @@
 const minZeroPage = 4096
 
 // faultOnLoad is true if a load to an address below minZeroPage will trigger a SIGSEGV.
-var faultOnLoad = objabi.GOOS != "aix"
+var faultOnLoad = buildcfg.GOOS != "aix"
 
 // nilcheckelim2 eliminates unnecessary nil checks.
 // Runs after lowering and scheduling.
@@ -235,7 +236,7 @@
 				continue
 			}
 			if v.Type.IsMemory() || v.Type.IsTuple() && v.Type.FieldType(1).IsMemory() {
-				if v.Op == OpVarKill || v.Op == OpVarLive || (v.Op == OpVarDef && !v.Aux.(GCNode).Typ().HasPointers()) {
+				if v.Op == OpVarKill || v.Op == OpVarLive || (v.Op == OpVarDef && !v.Aux.(*ir.Name).Type().HasPointers()) {
 					// These ops don't really change memory.
 					continue
 					// Note: OpVarDef requires that the defined variable not have pointers.
diff --git a/src/cmd/compile/internal/ssa/nilcheck_test.go b/src/cmd/compile/internal/ssa/nilcheck_test.go
index 16d9461..2e32afe 100644
--- a/src/cmd/compile/internal/ssa/nilcheck_test.go
+++ b/src/cmd/compile/internal/ssa/nilcheck_test.go
@@ -212,7 +212,7 @@
 			Valu("mem", OpInitMem, types.TypeMem, 0, nil),
 			Valu("sb", OpSB, c.config.Types.Uintptr, 0, nil),
 			Valu("sp", OpSP, c.config.Types.Uintptr, 0, nil),
-			Valu("baddr", OpLocalAddr, c.config.Types.Bool, 0, "b", "sp", "mem"),
+			Valu("baddr", OpLocalAddr, c.config.Types.Bool, 0, StringToAux("b"), "sp", "mem"),
 			Valu("bool1", OpLoad, c.config.Types.Bool, 0, nil, "baddr", "mem"),
 			If("bool1", "b1", "b2")),
 		Bloc("b1",
diff --git a/src/cmd/compile/internal/ssa/numberlines.go b/src/cmd/compile/internal/ssa/numberlines.go
index f4e62b8..9d6aeca 100644
--- a/src/cmd/compile/internal/ssa/numberlines.go
+++ b/src/cmd/compile/internal/ssa/numberlines.go
@@ -5,7 +5,6 @@
 package ssa
 
 import (
-	"cmd/internal/obj"
 	"cmd/internal/src"
 	"fmt"
 	"sort"
@@ -17,21 +16,13 @@
 	// so that a debugger-user sees the stop before the panic, and can examine the value.
 	case OpAddr, OpLocalAddr, OpOffPtr, OpStructSelect, OpPhi, OpITab, OpIData,
 		OpIMake, OpStringMake, OpSliceMake, OpStructMake0, OpStructMake1, OpStructMake2, OpStructMake3, OpStructMake4,
-		OpConstBool, OpConst8, OpConst16, OpConst32, OpConst64, OpConst32F, OpConst64F:
+		OpConstBool, OpConst8, OpConst16, OpConst32, OpConst64, OpConst32F, OpConst64F, OpSB, OpSP,
+		OpArgIntReg, OpArgFloatReg:
 		return true
 	}
 	return false
 }
 
-// LosesStmtMark reports whether a prog with op as loses its statement mark on the way to DWARF.
-// The attributes from some opcodes are lost in translation.
-// TODO: this is an artifact of how funcpctab combines information for instructions at a single PC.
-// Should try to fix it there.
-func LosesStmtMark(as obj.As) bool {
-	// is_stmt does not work for these; it DOES for ANOP even though that generates no code.
-	return as == obj.APCDATA || as == obj.AFUNCDATA
-}
-
 // nextGoodStatementIndex returns an index at i or later that is believed
 // to be a good place to start the statement for b.  This decision is
 // based on v's Op, the possibility of a better later operation, and
@@ -71,7 +62,7 @@
 // statement boundary.
 func notStmtBoundary(op Op) bool {
 	switch op {
-	case OpCopy, OpPhi, OpVarKill, OpVarDef, OpVarLive, OpUnknown, OpFwdRef, OpArg:
+	case OpCopy, OpPhi, OpVarKill, OpVarDef, OpVarLive, OpUnknown, OpFwdRef, OpArg, OpArgIntReg, OpArgFloatReg:
 		return true
 	}
 	return false
diff --git a/src/cmd/compile/internal/ssa/op.go b/src/cmd/compile/internal/ssa/op.go
index d167335..f09a08a 100644
--- a/src/cmd/compile/internal/ssa/op.go
+++ b/src/cmd/compile/internal/ssa/op.go
@@ -5,9 +5,12 @@
 package ssa
 
 import (
+	"cmd/compile/internal/abi"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"fmt"
+	"strings"
 )
 
 // An Op encodes the specific operation that a Value performs.
@@ -66,50 +69,187 @@
 	outputs []outputInfo
 }
 
+func (r *regInfo) String() string {
+	s := ""
+	s += "INS:\n"
+	for _, i := range r.inputs {
+		mask := fmt.Sprintf("%64b", i.regs)
+		mask = strings.Replace(mask, "0", ".", -1)
+		s += fmt.Sprintf("%2d |%s|\n", i.idx, mask)
+	}
+	s += "OUTS:\n"
+	for _, i := range r.outputs {
+		mask := fmt.Sprintf("%64b", i.regs)
+		mask = strings.Replace(mask, "0", ".", -1)
+		s += fmt.Sprintf("%2d |%s|\n", i.idx, mask)
+	}
+	s += "CLOBBERS:\n"
+	mask := fmt.Sprintf("%64b", r.clobbers)
+	mask = strings.Replace(mask, "0", ".", -1)
+	s += fmt.Sprintf("   |%s|\n", mask)
+	return s
+}
+
 type auxType int8
 
-type Param struct {
-	Type   *types.Type
-	Offset int32 // TODO someday this will be a register
+type AuxNameOffset struct {
+	Name   *ir.Name
+	Offset int64
+}
+
+func (a *AuxNameOffset) CanBeAnSSAAux() {}
+func (a *AuxNameOffset) String() string {
+	return fmt.Sprintf("%s+%d", a.Name.Sym().Name, a.Offset)
 }
 
 type AuxCall struct {
 	Fn      *obj.LSym
-	args    []Param // Includes receiver for method calls.  Does NOT include hidden closure pointer.
-	results []Param
+	reg     *regInfo // regInfo for this call
+	abiInfo *abi.ABIParamResultInfo
 }
 
-// ResultForOffset returns the index of the result at a particular offset among the results
-// This does not include the mem result for the call opcode.
-func (a *AuxCall) ResultForOffset(offset int64) int64 {
-	which := int64(-1)
-	for i := int64(0); i < a.NResults(); i++ { // note aux NResults does not include mem result.
-		if a.OffsetOfResult(i) == offset {
-			which = i
-			break
+// Reg returns the regInfo for a given call, combining the derived in/out register masks
+// with the machine-specific register information in the input i.  (The machine-specific
+// regInfo is much handier at the call site than it is when the AuxCall is being constructed,
+// therefore do this lazily).
+//
+// TODO: there is a Clever Hack that allows pre-generation of a small-ish number of the slices
+// of inputInfo and outputInfo used here, provided that we are willing to reorder the inputs
+// and outputs from calls, so that all integer registers come first, then all floating registers.
+// At this point (active development of register ABI) that is very premature,
+// but if this turns out to be a cost, we could do it.
+func (a *AuxCall) Reg(i *regInfo, c *Config) *regInfo {
+	if a.reg.clobbers != 0 {
+		// Already updated
+		return a.reg
+	}
+	if a.abiInfo.InRegistersUsed()+a.abiInfo.OutRegistersUsed() == 0 {
+		// Shortcut for zero case, also handles old ABI.
+		a.reg = i
+		return a.reg
+	}
+
+	k := len(i.inputs)
+	for _, p := range a.abiInfo.InParams() {
+		for _, r := range p.Registers {
+			m := archRegForAbiReg(r, c)
+			a.reg.inputs = append(a.reg.inputs, inputInfo{idx: k, regs: (1 << m)})
+			k++
 		}
 	}
-	return which
+	a.reg.inputs = append(a.reg.inputs, i.inputs...) // These are less constrained, thus should come last
+	k = len(i.outputs)
+	for _, p := range a.abiInfo.OutParams() {
+		for _, r := range p.Registers {
+			m := archRegForAbiReg(r, c)
+			a.reg.outputs = append(a.reg.outputs, outputInfo{idx: k, regs: (1 << m)})
+			k++
+		}
+	}
+	a.reg.outputs = append(a.reg.outputs, i.outputs...)
+	a.reg.clobbers = i.clobbers
+	return a.reg
+}
+func (a *AuxCall) ABI() *abi.ABIConfig {
+	return a.abiInfo.Config()
+}
+func (a *AuxCall) ABIInfo() *abi.ABIParamResultInfo {
+	return a.abiInfo
+}
+func (a *AuxCall) ResultReg(c *Config) *regInfo {
+	if a.abiInfo.OutRegistersUsed() == 0 {
+		return a.reg
+	}
+	if len(a.reg.inputs) > 0 {
+		return a.reg
+	}
+	k := 0
+	for _, p := range a.abiInfo.OutParams() {
+		for _, r := range p.Registers {
+			m := archRegForAbiReg(r, c)
+			a.reg.inputs = append(a.reg.inputs, inputInfo{idx: k, regs: (1 << m)})
+			k++
+		}
+	}
+	return a.reg
+}
+
+// For ABI register index r, returns the (dense) register number used in
+// SSA backend.
+func archRegForAbiReg(r abi.RegIndex, c *Config) uint8 {
+	var m int8
+	if int(r) < len(c.intParamRegs) {
+		m = c.intParamRegs[r]
+	} else {
+		m = c.floatParamRegs[int(r)-len(c.intParamRegs)]
+	}
+	return uint8(m)
+}
+
+// For ABI register index r, returns the register number used in the obj
+// package (assembler).
+func ObjRegForAbiReg(r abi.RegIndex, c *Config) int16 {
+	m := archRegForAbiReg(r, c)
+	return c.registers[m].objNum
+}
+
+// ArgWidth returns the amount of stack needed for all the inputs
+// and outputs of a function or method, including ABI-defined parameter
+// slots and ABI-defined spill slots for register-resident parameters.
+//
+// The name is taken from the types package's ArgWidth(<function type>),
+// which predated changes to the ABI; this version handles those changes.
+func (a *AuxCall) ArgWidth() int64 {
+	return a.abiInfo.ArgWidth()
+}
+
+// ParamAssignmentForResult returns the ABI Parameter assignment for result which (indexed 0, 1, etc).
+func (a *AuxCall) ParamAssignmentForResult(which int64) *abi.ABIParamAssignment {
+	return a.abiInfo.OutParam(int(which))
 }
 
 // OffsetOfResult returns the SP offset of result which (indexed 0, 1, etc).
 func (a *AuxCall) OffsetOfResult(which int64) int64 {
-	return int64(a.results[which].Offset)
+	n := int64(a.abiInfo.OutParam(int(which)).Offset())
+	return n
 }
 
 // OffsetOfArg returns the SP offset of argument which (indexed 0, 1, etc).
+// If the call is to a method, the receiver is the first argument (i.e., index 0)
 func (a *AuxCall) OffsetOfArg(which int64) int64 {
-	return int64(a.args[which].Offset)
+	n := int64(a.abiInfo.InParam(int(which)).Offset())
+	return n
+}
+
+// RegsOfResult returns the register(s) used for result which (indexed 0, 1, etc).
+func (a *AuxCall) RegsOfResult(which int64) []abi.RegIndex {
+	return a.abiInfo.OutParam(int(which)).Registers
+}
+
+// RegsOfArg returns the register(s) used for argument which (indexed 0, 1, etc).
+// If the call is to a method, the receiver is the first argument (i.e., index 0)
+func (a *AuxCall) RegsOfArg(which int64) []abi.RegIndex {
+	return a.abiInfo.InParam(int(which)).Registers
+}
+
+// NameOfResult returns the type of result which (indexed 0, 1, etc).
+func (a *AuxCall) NameOfResult(which int64) *ir.Name {
+	name := a.abiInfo.OutParam(int(which)).Name
+	if name == nil {
+		return nil
+	}
+	return name.(*ir.Name)
 }
 
 // TypeOfResult returns the type of result which (indexed 0, 1, etc).
 func (a *AuxCall) TypeOfResult(which int64) *types.Type {
-	return a.results[which].Type
+	return a.abiInfo.OutParam(int(which)).Type
 }
 
 // TypeOfArg returns the type of argument which (indexed 0, 1, etc).
+// If the call is to a method, the receiver is the first argument (i.e., index 0)
 func (a *AuxCall) TypeOfArg(which int64) *types.Type {
-	return a.args[which].Type
+	return a.abiInfo.InParam(int(which)).Type
 }
 
 // SizeOfResult returns the size of result which (indexed 0, 1, etc).
@@ -118,13 +258,14 @@
 }
 
 // SizeOfArg returns the size of argument which (indexed 0, 1, etc).
+// If the call is to a method, the receiver is the first argument (i.e., index 0)
 func (a *AuxCall) SizeOfArg(which int64) int64 {
 	return a.TypeOfArg(which).Width
 }
 
 // NResults returns the number of results
 func (a *AuxCall) NResults() int64 {
-	return int64(len(a.results))
+	return int64(len(a.abiInfo.OutParams()))
 }
 
 // LateExpansionResultType returns the result type (including trailing mem)
@@ -138,15 +279,12 @@
 	return types.NewResults(tys)
 }
 
-// NArgs returns the number of arguments
+// NArgs returns the number of arguments (including receiver, if there is one).
 func (a *AuxCall) NArgs() int64 {
-	return int64(len(a.args))
+	return int64(len(a.abiInfo.InParams()))
 }
 
-// String returns
-// "AuxCall{<fn>(<args>)}"             if len(results) == 0;
-// "AuxCall{<fn>(<args>)<results[0]>}" if len(results) == 1;
-// "AuxCall{<fn>(<args>)(<results>)}"  otherwise.
+// String returns "AuxCall{<fn>}"
 func (a *AuxCall) String() string {
 	var fn string
 	if a.Fn == nil {
@@ -154,70 +292,75 @@
 	} else {
 		fn = fmt.Sprintf("AuxCall{%v", a.Fn)
 	}
-
-	if len(a.args) == 0 {
-		fn += "()"
-	} else {
-		s := "("
-		for _, arg := range a.args {
-			fn += fmt.Sprintf("%s[%v,%v]", s, arg.Type, arg.Offset)
-			s = ","
-		}
-		fn += ")"
-	}
-
-	if len(a.results) > 0 { // usual is zero or one; only some RT calls have more than one.
-		if len(a.results) == 1 {
-			fn += fmt.Sprintf("[%v,%v]", a.results[0].Type, a.results[0].Offset)
-		} else {
-			s := "("
-			for _, result := range a.results {
-				fn += fmt.Sprintf("%s[%v,%v]", s, result.Type, result.Offset)
-				s = ","
-			}
-			fn += ")"
-		}
-	}
+	// TODO how much of the ABI should be printed?
 
 	return fn + "}"
 }
 
 // StaticAuxCall returns an AuxCall for a static call.
-func StaticAuxCall(sym *obj.LSym, args []Param, results []Param) *AuxCall {
-	return &AuxCall{Fn: sym, args: args, results: results}
+func StaticAuxCall(sym *obj.LSym, paramResultInfo *abi.ABIParamResultInfo) *AuxCall {
+	if paramResultInfo == nil {
+		panic(fmt.Errorf("Nil paramResultInfo, sym=%v", sym))
+	}
+	var reg *regInfo
+	if paramResultInfo.InRegistersUsed()+paramResultInfo.OutRegistersUsed() > 0 {
+		reg = &regInfo{}
+	}
+	return &AuxCall{Fn: sym, abiInfo: paramResultInfo, reg: reg}
 }
 
 // InterfaceAuxCall returns an AuxCall for an interface call.
-func InterfaceAuxCall(args []Param, results []Param) *AuxCall {
-	return &AuxCall{Fn: nil, args: args, results: results}
+func InterfaceAuxCall(paramResultInfo *abi.ABIParamResultInfo) *AuxCall {
+	var reg *regInfo
+	if paramResultInfo.InRegistersUsed()+paramResultInfo.OutRegistersUsed() > 0 {
+		reg = &regInfo{}
+	}
+	return &AuxCall{Fn: nil, abiInfo: paramResultInfo, reg: reg}
 }
 
 // ClosureAuxCall returns an AuxCall for a closure call.
-func ClosureAuxCall(args []Param, results []Param) *AuxCall {
-	return &AuxCall{Fn: nil, args: args, results: results}
+func ClosureAuxCall(paramResultInfo *abi.ABIParamResultInfo) *AuxCall {
+	var reg *regInfo
+	if paramResultInfo.InRegistersUsed()+paramResultInfo.OutRegistersUsed() > 0 {
+		reg = &regInfo{}
+	}
+	return &AuxCall{Fn: nil, abiInfo: paramResultInfo, reg: reg}
+}
+
+func (*AuxCall) CanBeAnSSAAux() {}
+
+// OwnAuxCall returns a function's own AuxCall
+func OwnAuxCall(fn *obj.LSym, paramResultInfo *abi.ABIParamResultInfo) *AuxCall {
+	// TODO if this remains identical to ClosureAuxCall above after new ABI is done, should deduplicate.
+	var reg *regInfo
+	if paramResultInfo.InRegistersUsed()+paramResultInfo.OutRegistersUsed() > 0 {
+		reg = &regInfo{}
+	}
+	return &AuxCall{Fn: fn, abiInfo: paramResultInfo, reg: reg}
 }
 
 const (
-	auxNone         auxType = iota
-	auxBool                 // auxInt is 0/1 for false/true
-	auxInt8                 // auxInt is an 8-bit integer
-	auxInt16                // auxInt is a 16-bit integer
-	auxInt32                // auxInt is a 32-bit integer
-	auxInt64                // auxInt is a 64-bit integer
-	auxInt128               // auxInt represents a 128-bit integer.  Always 0.
-	auxUInt8                // auxInt is an 8-bit unsigned integer
-	auxFloat32              // auxInt is a float32 (encoded with math.Float64bits)
-	auxFloat64              // auxInt is a float64 (encoded with math.Float64bits)
-	auxFlagConstant         // auxInt is a flagConstant
-	auxString               // aux is a string
-	auxSym                  // aux is a symbol (a *gc.Node for locals, an *obj.LSym for globals, or nil for none)
-	auxSymOff               // aux is a symbol, auxInt is an offset
-	auxSymValAndOff         // aux is a symbol, auxInt is a ValAndOff
-	auxTyp                  // aux is a type
-	auxTypSize              // aux is a type, auxInt is a size, must have Aux.(Type).Size() == AuxInt
-	auxCCop                 // aux is a ssa.Op that represents a flags-to-bool conversion (e.g. LessThan)
-	auxCall                 // aux is a *ssa.AuxCall
-	auxCallOff              // aux is a *ssa.AuxCall, AuxInt is int64 param (in+out) size
+	auxNone           auxType = iota
+	auxBool                   // auxInt is 0/1 for false/true
+	auxInt8                   // auxInt is an 8-bit integer
+	auxInt16                  // auxInt is a 16-bit integer
+	auxInt32                  // auxInt is a 32-bit integer
+	auxInt64                  // auxInt is a 64-bit integer
+	auxInt128                 // auxInt represents a 128-bit integer.  Always 0.
+	auxUInt8                  // auxInt is an 8-bit unsigned integer
+	auxFloat32                // auxInt is a float32 (encoded with math.Float64bits)
+	auxFloat64                // auxInt is a float64 (encoded with math.Float64bits)
+	auxFlagConstant           // auxInt is a flagConstant
+	auxNameOffsetInt8         // aux is a &struct{Name ir.Name, Offset int64}; auxInt is index in parameter registers array
+	auxString                 // aux is a string
+	auxSym                    // aux is a symbol (a *gc.Node for locals, an *obj.LSym for globals, or nil for none)
+	auxSymOff                 // aux is a symbol, auxInt is an offset
+	auxSymValAndOff           // aux is a symbol, auxInt is a ValAndOff
+	auxTyp                    // aux is a type
+	auxTypSize                // aux is a type, auxInt is a size, must have Aux.(Type).Size() == AuxInt
+	auxCCop                   // aux is a ssa.Op that represents a flags-to-bool conversion (e.g. LessThan)
+	auxCall                   // aux is a *ssa.AuxCall
+	auxCallOff                // aux is a *ssa.AuxCall, AuxInt is int64 param (in+out) size
 
 	// architecture specific aux types
 	auxARM64BitField     // aux is an arm64 bitfield lsb and width packed into auxInt
@@ -247,8 +390,8 @@
 //  - a *obj.LSym, for an offset from SB (the global pointer)
 //  - nil, for no offset
 type Sym interface {
-	String() string
 	CanBeAnSSASym()
+	CanBeAnSSAAux()
 }
 
 // A ValAndOff is used by the several opcodes. It holds
@@ -259,13 +402,13 @@
 // The low 32 bits hold a pointer offset.
 type ValAndOff int64
 
-func (x ValAndOff) Val() int64   { return int64(x) >> 32 }
-func (x ValAndOff) Val32() int32 { return int32(int64(x) >> 32) }
+func (x ValAndOff) Val() int32   { return int32(int64(x) >> 32) }
+func (x ValAndOff) Val64() int64 { return int64(x) >> 32 }
 func (x ValAndOff) Val16() int16 { return int16(int64(x) >> 32) }
 func (x ValAndOff) Val8() int8   { return int8(int64(x) >> 32) }
 
-func (x ValAndOff) Off() int64   { return int64(int32(x)) }
-func (x ValAndOff) Off32() int32 { return int32(x) }
+func (x ValAndOff) Off64() int64 { return int64(int32(x)) }
+func (x ValAndOff) Off() int32   { return int32(x) }
 
 func (x ValAndOff) String() string {
 	return fmt.Sprintf("val=%d,off=%d", x.Val(), x.Off())
@@ -277,40 +420,16 @@
 	return val == int64(int32(val))
 }
 
-// validOff reports whether the offset can be used
-// as an argument to makeValAndOff.
-func validOff(off int64) bool {
-	return off == int64(int32(off))
-}
-
-// validValAndOff reports whether we can fit the value and offset into
-// a ValAndOff value.
-func validValAndOff(val, off int64) bool {
-	if !validVal(val) {
-		return false
-	}
-	if !validOff(off) {
-		return false
-	}
-	return true
-}
-
-func makeValAndOff32(val, off int32) ValAndOff {
+func makeValAndOff(val, off int32) ValAndOff {
 	return ValAndOff(int64(val)<<32 + int64(uint32(off)))
 }
-func makeValAndOff64(val, off int64) ValAndOff {
-	if !validValAndOff(val, off) {
-		panic("invalid makeValAndOff64")
-	}
-	return ValAndOff(val<<32 + int64(uint32(off)))
-}
 
 func (x ValAndOff) canAdd32(off int32) bool {
-	newoff := x.Off() + int64(off)
+	newoff := x.Off64() + int64(off)
 	return newoff == int64(int32(newoff))
 }
 func (x ValAndOff) canAdd64(off int64) bool {
-	newoff := x.Off() + off
+	newoff := x.Off64() + off
 	return newoff == int64(int32(newoff))
 }
 
@@ -318,13 +437,13 @@
 	if !x.canAdd32(off) {
 		panic("invalid ValAndOff.addOffset32")
 	}
-	return makeValAndOff64(x.Val(), x.Off()+int64(off))
+	return makeValAndOff(x.Val(), x.Off()+off)
 }
 func (x ValAndOff) addOffset64(off int64) ValAndOff {
 	if !x.canAdd64(off) {
 		panic("invalid ValAndOff.addOffset64")
 	}
-	return makeValAndOff64(x.Val(), x.Off()+off)
+	return makeValAndOff(x.Val(), x.Off()+int32(off))
 }
 
 // int128 is a type that stores a 128-bit constant.
@@ -350,6 +469,7 @@
 	BoundsSlice3BU                      // ... with unsigned high
 	BoundsSlice3C                       // 3-arg slicing operation, 0 <= low <= high failed
 	BoundsSlice3CU                      // ... with unsigned low
+	BoundsConvert                       // conversion to array pointer failed
 	BoundsKindCount
 )
 
@@ -377,7 +497,8 @@
 	case BoundsSlice3Alen,
 		BoundsSlice3AlenU,
 		BoundsSlice3Acap,
-		BoundsSlice3AcapU:
+		BoundsSlice3AcapU,
+		BoundsConvert:
 		return 0
 	case BoundsSliceAlen,
 		BoundsSliceAlenU,
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index e590f6b..1c37fbe 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -432,6 +432,7 @@
 	Op386BSRW
 	Op386BSWAPL
 	Op386SQRTSD
+	Op386SQRTSS
 	Op386SBBLcarrymask
 	Op386SETEQ
 	Op386SETNE
@@ -691,18 +692,6 @@
 	OpAMD64BTRQconst
 	OpAMD64BTSLconst
 	OpAMD64BTSQconst
-	OpAMD64BTCQmodify
-	OpAMD64BTCLmodify
-	OpAMD64BTSQmodify
-	OpAMD64BTSLmodify
-	OpAMD64BTRQmodify
-	OpAMD64BTRLmodify
-	OpAMD64BTCQconstmodify
-	OpAMD64BTCLconstmodify
-	OpAMD64BTSQconstmodify
-	OpAMD64BTSLconstmodify
-	OpAMD64BTRQconstmodify
-	OpAMD64BTRLconstmodify
 	OpAMD64TESTQ
 	OpAMD64TESTL
 	OpAMD64TESTW
@@ -731,6 +720,8 @@
 	OpAMD64SARLconst
 	OpAMD64SARWconst
 	OpAMD64SARBconst
+	OpAMD64SHRDQ
+	OpAMD64SHLDQ
 	OpAMD64ROLQ
 	OpAMD64ROLL
 	OpAMD64ROLW
@@ -888,6 +879,7 @@
 	OpAMD64POPCNTQ
 	OpAMD64POPCNTL
 	OpAMD64SQRTSD
+	OpAMD64SQRTSS
 	OpAMD64ROUNDSD
 	OpAMD64VFMADD231SD
 	OpAMD64SBBQcarrymask
@@ -970,6 +962,7 @@
 	OpAMD64MOVQstore
 	OpAMD64MOVOload
 	OpAMD64MOVOstore
+	OpAMD64MOVOstorezero
 	OpAMD64MOVBloadidx1
 	OpAMD64MOVWloadidx1
 	OpAMD64MOVWloadidx2
@@ -998,7 +991,6 @@
 	OpAMD64MOVQstoreconstidx1
 	OpAMD64MOVQstoreconstidx8
 	OpAMD64DUFFZERO
-	OpAMD64MOVOconst
 	OpAMD64REPSTOSQ
 	OpAMD64CALLstatic
 	OpAMD64CALLclosure
@@ -1090,6 +1082,7 @@
 	OpARMNEGF
 	OpARMNEGD
 	OpARMSQRTD
+	OpARMSQRTF
 	OpARMABSD
 	OpARMCLZ
 	OpARMREV
@@ -1358,8 +1351,10 @@
 	OpARM64FNEGS
 	OpARM64FNEGD
 	OpARM64FSQRTD
+	OpARM64FSQRTS
 	OpARM64REV
 	OpARM64REVW
+	OpARM64REV16
 	OpARM64REV16W
 	OpARM64RBIT
 	OpARM64RBITW
@@ -1481,6 +1476,8 @@
 	OpARM64MOVWloadidx4
 	OpARM64MOVWUloadidx4
 	OpARM64MOVDloadidx8
+	OpARM64FMOVSloadidx4
+	OpARM64FMOVDloadidx8
 	OpARM64MOVBstore
 	OpARM64MOVHstore
 	OpARM64MOVWstore
@@ -1497,6 +1494,8 @@
 	OpARM64MOVHstoreidx2
 	OpARM64MOVWstoreidx4
 	OpARM64MOVDstoreidx8
+	OpARM64FMOVSstoreidx4
+	OpARM64FMOVDstoreidx8
 	OpARM64MOVBstorezero
 	OpARM64MOVHstorezero
 	OpARM64MOVWstorezero
@@ -1546,6 +1545,10 @@
 	OpARM64FRINTZD
 	OpARM64CSEL
 	OpARM64CSEL0
+	OpARM64CSINC
+	OpARM64CSINV
+	OpARM64CSNEG
+	OpARM64CSETM
 	OpARM64CALLstatic
 	OpARM64CALLclosure
 	OpARM64CALLinter
@@ -1637,6 +1640,7 @@
 	OpMIPSNEGF
 	OpMIPSNEGD
 	OpMIPSSQRTD
+	OpMIPSSQRTF
 	OpMIPSSLL
 	OpMIPSSLLconst
 	OpMIPSSRL
@@ -1747,6 +1751,7 @@
 	OpMIPS64NEGF
 	OpMIPS64NEGD
 	OpMIPS64SQRTD
+	OpMIPS64SQRTF
 	OpMIPS64SLLV
 	OpMIPS64SLLVconst
 	OpMIPS64SRLV
@@ -2073,9 +2078,6 @@
 	OpRISCV64REMW
 	OpRISCV64REMUW
 	OpRISCV64MOVaddr
-	OpRISCV64MOVBconst
-	OpRISCV64MOVHconst
-	OpRISCV64MOVWconst
 	OpRISCV64MOVDconst
 	OpRISCV64MOVBload
 	OpRISCV64MOVHload
@@ -2139,6 +2141,8 @@
 	OpRISCV64LoweredAtomicAdd64
 	OpRISCV64LoweredAtomicCas32
 	OpRISCV64LoweredAtomicCas64
+	OpRISCV64LoweredAtomicAnd32
+	OpRISCV64LoweredAtomicOr32
 	OpRISCV64LoweredNilCheck
 	OpRISCV64LoweredGetClosurePtr
 	OpRISCV64LoweredGetCallerSP
@@ -2297,6 +2301,7 @@
 	OpS390XNOT
 	OpS390XNOTW
 	OpS390XFSQRT
+	OpS390XFSQRTS
 	OpS390XLOCGR
 	OpS390XMOVBreg
 	OpS390XMOVBZreg
@@ -2723,6 +2728,7 @@
 	OpRotateLeft32
 	OpRotateLeft64
 	OpSqrt
+	OpSqrt32
 	OpFloor
 	OpCeil
 	OpTrunc
@@ -2747,6 +2753,8 @@
 	OpConstSlice
 	OpInitMem
 	OpArg
+	OpArgIntReg
+	OpArgFloatReg
 	OpAddr
 	OpLocalAddr
 	OpSP
@@ -2814,6 +2822,7 @@
 	OpSlicePtr
 	OpSliceLen
 	OpSliceCap
+	OpSlicePtrUnchecked
 	OpComplexMake
 	OpComplexReal
 	OpComplexImag
@@ -2902,6 +2911,7 @@
 	OpAtomicOr8Variant
 	OpAtomicOr32Variant
 	OpClobber
+	OpClobberReg
 )
 
 var opcodeTable = [...]opInfo{
@@ -2912,7 +2922,6 @@
 		argLen:       2,
 		commutative:  true,
 		resultInArg0: true,
-		usesScratch:  true,
 		asm:          x86.AADDSS,
 		reg: regInfo{
 			inputs: []inputInfo{
@@ -2944,7 +2953,6 @@
 		name:         "SUBSS",
 		argLen:       2,
 		resultInArg0: true,
-		usesScratch:  true,
 		asm:          x86.ASUBSS,
 		reg: regInfo{
 			inputs: []inputInfo{
@@ -2976,7 +2984,6 @@
 		argLen:       2,
 		commutative:  true,
 		resultInArg0: true,
-		usesScratch:  true,
 		asm:          x86.AMULSS,
 		reg: regInfo{
 			inputs: []inputInfo{
@@ -3008,7 +3015,6 @@
 		name:         "DIVSS",
 		argLen:       2,
 		resultInArg0: true,
-		usesScratch:  true,
 		asm:          x86.ADIVSS,
 		reg: regInfo{
 			inputs: []inputInfo{
@@ -4072,10 +4078,9 @@
 		},
 	},
 	{
-		name:        "UCOMISS",
-		argLen:      2,
-		usesScratch: true,
-		asm:         x86.AUCOMISS,
+		name:   "UCOMISS",
+		argLen: 2,
+		asm:    x86.AUCOMISS,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 65280}, // X0 X1 X2 X3 X4 X5 X6 X7
@@ -4084,10 +4089,9 @@
 		},
 	},
 	{
-		name:        "UCOMISD",
-		argLen:      2,
-		usesScratch: true,
-		asm:         x86.AUCOMISD,
+		name:   "UCOMISD",
+		argLen: 2,
+		asm:    x86.AUCOMISD,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 65280}, // X0 X1 X2 X3 X4 X5 X6 X7
@@ -4779,6 +4783,19 @@
 		},
 	},
 	{
+		name:   "SQRTSS",
+		argLen: 1,
+		asm:    x86.ASQRTSS,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 65280}, // X0 X1 X2 X3 X4 X5 X6 X7
+			},
+			outputs: []outputInfo{
+				{0, 65280}, // X0 X1 X2 X3 X4 X5 X6 X7
+			},
+		},
+	},
+	{
 		name:   "SBBLcarrymask",
 		argLen: 1,
 		asm:    x86.ASBBL,
@@ -5027,10 +5044,9 @@
 		},
 	},
 	{
-		name:        "CVTTSD2SL",
-		argLen:      1,
-		usesScratch: true,
-		asm:         x86.ACVTTSD2SL,
+		name:   "CVTTSD2SL",
+		argLen: 1,
+		asm:    x86.ACVTTSD2SL,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 65280}, // X0 X1 X2 X3 X4 X5 X6 X7
@@ -5041,10 +5057,9 @@
 		},
 	},
 	{
-		name:        "CVTTSS2SL",
-		argLen:      1,
-		usesScratch: true,
-		asm:         x86.ACVTTSS2SL,
+		name:   "CVTTSS2SL",
+		argLen: 1,
+		asm:    x86.ACVTTSS2SL,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 65280}, // X0 X1 X2 X3 X4 X5 X6 X7
@@ -5055,10 +5070,9 @@
 		},
 	},
 	{
-		name:        "CVTSL2SS",
-		argLen:      1,
-		usesScratch: true,
-		asm:         x86.ACVTSL2SS,
+		name:   "CVTSL2SS",
+		argLen: 1,
+		asm:    x86.ACVTSL2SS,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 239}, // AX CX DX BX BP SI DI
@@ -5069,10 +5083,9 @@
 		},
 	},
 	{
-		name:        "CVTSL2SD",
-		argLen:      1,
-		usesScratch: true,
-		asm:         x86.ACVTSL2SD,
+		name:   "CVTSL2SD",
+		argLen: 1,
+		asm:    x86.ACVTSL2SD,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 239}, // AX CX DX BX BP SI DI
@@ -5083,10 +5096,9 @@
 		},
 	},
 	{
-		name:        "CVTSD2SS",
-		argLen:      1,
-		usesScratch: true,
-		asm:         x86.ACVTSD2SS,
+		name:   "CVTSD2SS",
+		argLen: 1,
+		asm:    x86.ACVTSD2SS,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 65280}, // X0 X1 X2 X3 X4 X5 X6 X7
@@ -6162,11 +6174,11 @@
 		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
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6178,11 +6190,11 @@
 		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
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6193,11 +6205,11 @@
 		asm:          x86.ASUBSS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6208,11 +6220,11 @@
 		asm:          x86.ASUBSD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6224,11 +6236,11 @@
 		asm:          x86.AMULSS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6240,11 +6252,11 @@
 		asm:          x86.AMULSD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6255,11 +6267,11 @@
 		asm:          x86.ADIVSS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6270,11 +6282,11 @@
 		asm:          x86.ADIVSD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6287,10 +6299,10 @@
 		asm:            x86.AMOVSS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6303,10 +6315,10 @@
 		asm:            x86.AMOVSD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6318,7 +6330,7 @@
 		asm:               x86.AMOVSS,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6330,7 +6342,7 @@
 		asm:               x86.AMOVSD,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6343,11 +6355,11 @@
 		scale:     1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6360,11 +6372,11 @@
 		scale:     4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6377,11 +6389,11 @@
 		scale:     1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6394,11 +6406,11 @@
 		scale:     8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6411,8 +6423,8 @@
 		asm:            x86.AMOVSS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 		},
 	},
@@ -6425,8 +6437,8 @@
 		asm:            x86.AMOVSD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 		},
 	},
@@ -6439,9 +6451,9 @@
 		scale:     1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{1, 65535},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{2, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 		},
 	},
@@ -6454,9 +6466,9 @@
 		scale:     4,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{1, 65535},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{2, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 		},
 	},
@@ -6469,9 +6481,9 @@
 		scale:     1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{1, 65535},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{2, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 		},
 	},
@@ -6484,9 +6496,9 @@
 		scale:     8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{1, 65535},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{2, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 		},
 	},
@@ -6500,11 +6512,11 @@
 		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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6518,11 +6530,11 @@
 		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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6536,11 +6548,11 @@
 		asm:            x86.ASUBSS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6554,11 +6566,11 @@
 		asm:            x86.ASUBSD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6572,11 +6584,11 @@
 		asm:            x86.AMULSS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6590,11 +6602,11 @@
 		asm:            x86.AMULSD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6608,11 +6620,11 @@
 		asm:            x86.ADIVSS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6626,11 +6638,11 @@
 		asm:            x86.ADIVSD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6644,12 +6656,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6663,12 +6675,12 @@
 		scale:        4,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6682,12 +6694,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6701,12 +6713,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6720,12 +6732,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6739,12 +6751,12 @@
 		scale:        4,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6758,12 +6770,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6777,12 +6789,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6796,12 +6808,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6815,12 +6827,12 @@
 		scale:        4,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6834,12 +6846,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6853,12 +6865,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6872,12 +6884,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6891,12 +6903,12 @@
 		scale:        4,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6910,12 +6922,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6929,12 +6941,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-				{2, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -6946,11 +6958,11 @@
 		asm:          x86.AADDQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -6962,11 +6974,11 @@
 		asm:          x86.AADDL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -6978,10 +6990,10 @@
 		asm:          x86.AADDQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -6993,10 +7005,10 @@
 		asm:          x86.AADDL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7010,7 +7022,7 @@
 		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
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7024,7 +7036,7 @@
 		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
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7036,11 +7048,11 @@
 		asm:          x86.ASUBQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7052,11 +7064,11 @@
 		asm:          x86.ASUBL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7069,10 +7081,10 @@
 		asm:          x86.ASUBQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7085,10 +7097,10 @@
 		asm:          x86.ASUBL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7101,11 +7113,11 @@
 		asm:          x86.AIMULQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7118,11 +7130,11 @@
 		asm:          x86.AIMULL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7134,10 +7146,10 @@
 		asm:          x86.AIMUL3Q,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7149,10 +7161,10 @@
 		asm:          x86.AIMUL3L,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7165,7 +7177,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			clobbers: 4, // DX
 			outputs: []outputInfo{
@@ -7183,7 +7195,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			clobbers: 4, // DX
 			outputs: []outputInfo{
@@ -7200,7 +7212,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			clobbers: 1, // AX
 			outputs: []outputInfo{
@@ -7216,7 +7228,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			clobbers: 1, // AX
 			outputs: []outputInfo{
@@ -7232,7 +7244,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			clobbers: 1, // AX
 			outputs: []outputInfo{
@@ -7248,7 +7260,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			clobbers: 1, // AX
 			outputs: []outputInfo{
@@ -7264,11 +7276,11 @@
 		clobberFlags: true,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7281,7 +7293,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65531}, // AX CX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49147}, // AX CX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{0, 1}, // AX
@@ -7298,7 +7310,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65531}, // AX CX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49147}, // AX CX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{0, 1}, // AX
@@ -7315,7 +7327,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65531}, // AX CX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49147}, // AX CX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{0, 1}, // AX
@@ -7331,7 +7343,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65531}, // AX CX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49147}, // AX CX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{0, 1}, // AX
@@ -7347,7 +7359,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65531}, // AX CX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49147}, // AX CX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{0, 1}, // AX
@@ -7363,7 +7375,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65531}, // AX CX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49147}, // AX CX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{0, 1}, // AX
@@ -7378,11 +7390,11 @@
 		asm:          x86.ANEGL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7394,12 +7406,12 @@
 		asm:          x86.AADDQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7411,12 +7423,12 @@
 		asm:          x86.AADCQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7428,11 +7440,11 @@
 		asm:          x86.AADDQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7444,11 +7456,11 @@
 		asm:          x86.AADCQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7459,12 +7471,12 @@
 		asm:          x86.ASUBQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7475,12 +7487,12 @@
 		asm:          x86.ASBBQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7492,11 +7504,11 @@
 		asm:          x86.ASUBQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7508,11 +7520,11 @@
 		asm:          x86.ASBBQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7525,7 +7537,7 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1},     // AX
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{0, 4}, // DX
@@ -7542,7 +7554,7 @@
 			inputs: []inputInfo{
 				{0, 4},     // DX
 				{1, 1},     // AX
-				{2, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{2, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{0, 1}, // AX
@@ -7559,11 +7571,11 @@
 		asm:          x86.AANDQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7576,11 +7588,11 @@
 		asm:          x86.AANDL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7593,10 +7605,10 @@
 		asm:          x86.AANDQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7609,10 +7621,10 @@
 		asm:          x86.AANDL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7626,7 +7638,7 @@
 		asm:            x86.AANDQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7640,7 +7652,7 @@
 		asm:            x86.AANDL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7653,11 +7665,11 @@
 		asm:          x86.AORQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7670,11 +7682,11 @@
 		asm:          x86.AORL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7687,10 +7699,10 @@
 		asm:          x86.AORQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7703,10 +7715,10 @@
 		asm:          x86.AORL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7720,7 +7732,7 @@
 		asm:            x86.AORQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7734,7 +7746,7 @@
 		asm:            x86.AORL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7747,11 +7759,11 @@
 		asm:          x86.AXORQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7764,11 +7776,11 @@
 		asm:          x86.AXORL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7781,10 +7793,10 @@
 		asm:          x86.AXORQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7797,10 +7809,10 @@
 		asm:          x86.AXORL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7814,7 +7826,7 @@
 		asm:            x86.AXORQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7828,7 +7840,7 @@
 		asm:            x86.AXORL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7838,8 +7850,8 @@
 		asm:    x86.ACMPQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7849,8 +7861,8 @@
 		asm:    x86.ACMPL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7860,8 +7872,8 @@
 		asm:    x86.ACMPW,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7871,8 +7883,8 @@
 		asm:    x86.ACMPB,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7883,7 +7895,7 @@
 		asm:     x86.ACMPQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7894,7 +7906,7 @@
 		asm:     x86.ACMPL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7905,7 +7917,7 @@
 		asm:     x86.ACMPW,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7916,7 +7928,7 @@
 		asm:     x86.ACMPB,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -7929,8 +7941,8 @@
 		asm:            x86.ACMPQ,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7943,8 +7955,8 @@
 		asm:            x86.ACMPL,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7957,8 +7969,8 @@
 		asm:            x86.ACMPW,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7971,8 +7983,8 @@
 		asm:            x86.ACMPB,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7985,7 +7997,7 @@
 		asm:            x86.ACMPQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -7998,7 +8010,7 @@
 		asm:            x86.ACMPL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8011,7 +8023,7 @@
 		asm:            x86.ACMPW,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8024,7 +8036,7 @@
 		asm:            x86.ACMPB,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8037,9 +8049,9 @@
 		scale:     8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8053,9 +8065,9 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8068,9 +8080,9 @@
 		scale:     4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8084,9 +8096,9 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8099,9 +8111,9 @@
 		scale:     2,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8115,9 +8127,9 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8131,9 +8143,9 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8146,8 +8158,8 @@
 		scale:     8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8161,8 +8173,8 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8175,8 +8187,8 @@
 		scale:     4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8190,8 +8202,8 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8204,8 +8216,8 @@
 		scale:     2,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8219,8 +8231,8 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8234,8 +8246,8 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -8245,8 +8257,8 @@
 		asm:    x86.AUCOMISS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -8256,8 +8268,8 @@
 		asm:    x86.AUCOMISD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -8267,8 +8279,8 @@
 		asm:    x86.ABTL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8278,8 +8290,8 @@
 		asm:    x86.ABTQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8291,11 +8303,11 @@
 		asm:          x86.ABTCL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8307,11 +8319,11 @@
 		asm:          x86.ABTCQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8323,11 +8335,11 @@
 		asm:          x86.ABTRL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8339,11 +8351,11 @@
 		asm:          x86.ABTRQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8355,11 +8367,11 @@
 		asm:          x86.ABTSL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8371,11 +8383,11 @@
 		asm:          x86.ABTSQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8386,7 +8398,7 @@
 		asm:     x86.ABTL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8397,7 +8409,7 @@
 		asm:     x86.ABTQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8410,10 +8422,10 @@
 		asm:          x86.ABTCL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8426,10 +8438,10 @@
 		asm:          x86.ABTCQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8442,10 +8454,10 @@
 		asm:          x86.ABTRL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8458,10 +8470,10 @@
 		asm:          x86.ABTRQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8474,10 +8486,10 @@
 		asm:          x86.ABTSL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8490,184 +8502,10 @@
 		asm:          x86.ABTSQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-			},
-		},
-	},
-	{
-		name:           "BTCQmodify",
-		auxType:        auxSymOff,
-		argLen:         3,
-		clobberFlags:   true,
-		faultOnNilArg0: true,
-		symEffect:      SymRead | SymWrite,
-		asm:            x86.ABTCQ,
-		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
-			},
-		},
-	},
-	{
-		name:           "BTCLmodify",
-		auxType:        auxSymOff,
-		argLen:         3,
-		clobberFlags:   true,
-		faultOnNilArg0: true,
-		symEffect:      SymRead | SymWrite,
-		asm:            x86.ABTCL,
-		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
-			},
-		},
-	},
-	{
-		name:           "BTSQmodify",
-		auxType:        auxSymOff,
-		argLen:         3,
-		clobberFlags:   true,
-		faultOnNilArg0: true,
-		symEffect:      SymRead | SymWrite,
-		asm:            x86.ABTSQ,
-		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
-			},
-		},
-	},
-	{
-		name:           "BTSLmodify",
-		auxType:        auxSymOff,
-		argLen:         3,
-		clobberFlags:   true,
-		faultOnNilArg0: true,
-		symEffect:      SymRead | SymWrite,
-		asm:            x86.ABTSL,
-		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
-			},
-		},
-	},
-	{
-		name:           "BTRQmodify",
-		auxType:        auxSymOff,
-		argLen:         3,
-		clobberFlags:   true,
-		faultOnNilArg0: true,
-		symEffect:      SymRead | SymWrite,
-		asm:            x86.ABTRQ,
-		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
-			},
-		},
-	},
-	{
-		name:           "BTRLmodify",
-		auxType:        auxSymOff,
-		argLen:         3,
-		clobberFlags:   true,
-		faultOnNilArg0: true,
-		symEffect:      SymRead | SymWrite,
-		asm:            x86.ABTRL,
-		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
-			},
-		},
-	},
-	{
-		name:           "BTCQconstmodify",
-		auxType:        auxSymValAndOff,
-		argLen:         2,
-		clobberFlags:   true,
-		faultOnNilArg0: true,
-		symEffect:      SymRead | SymWrite,
-		asm:            x86.ABTCQ,
-		reg: regInfo{
-			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-			},
-		},
-	},
-	{
-		name:           "BTCLconstmodify",
-		auxType:        auxSymValAndOff,
-		argLen:         2,
-		clobberFlags:   true,
-		faultOnNilArg0: true,
-		symEffect:      SymRead | SymWrite,
-		asm:            x86.ABTCL,
-		reg: regInfo{
-			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-			},
-		},
-	},
-	{
-		name:           "BTSQconstmodify",
-		auxType:        auxSymValAndOff,
-		argLen:         2,
-		clobberFlags:   true,
-		faultOnNilArg0: true,
-		symEffect:      SymRead | SymWrite,
-		asm:            x86.ABTSQ,
-		reg: regInfo{
-			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-			},
-		},
-	},
-	{
-		name:           "BTSLconstmodify",
-		auxType:        auxSymValAndOff,
-		argLen:         2,
-		clobberFlags:   true,
-		faultOnNilArg0: true,
-		symEffect:      SymRead | SymWrite,
-		asm:            x86.ABTSL,
-		reg: regInfo{
-			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-			},
-		},
-	},
-	{
-		name:           "BTRQconstmodify",
-		auxType:        auxSymValAndOff,
-		argLen:         2,
-		clobberFlags:   true,
-		faultOnNilArg0: true,
-		symEffect:      SymRead | SymWrite,
-		asm:            x86.ABTRQ,
-		reg: regInfo{
-			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
-			},
-		},
-	},
-	{
-		name:           "BTRLconstmodify",
-		auxType:        auxSymValAndOff,
-		argLen:         2,
-		clobberFlags:   true,
-		faultOnNilArg0: true,
-		symEffect:      SymRead | SymWrite,
-		asm:            x86.ABTRL,
-		reg: regInfo{
-			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8678,8 +8516,8 @@
 		asm:         x86.ATESTQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8690,8 +8528,8 @@
 		asm:         x86.ATESTL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8702,8 +8540,8 @@
 		asm:         x86.ATESTW,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8714,8 +8552,8 @@
 		asm:         x86.ATESTB,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8726,7 +8564,7 @@
 		asm:     x86.ATESTQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8737,7 +8575,7 @@
 		asm:     x86.ATESTL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8748,7 +8586,7 @@
 		asm:     x86.ATESTW,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8759,7 +8597,7 @@
 		asm:     x86.ATESTB,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8772,10 +8610,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8788,10 +8626,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8804,10 +8642,10 @@
 		asm:          x86.ASHLQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8820,10 +8658,10 @@
 		asm:          x86.ASHLL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8836,10 +8674,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8852,10 +8690,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8868,10 +8706,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8884,10 +8722,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8900,10 +8738,10 @@
 		asm:          x86.ASHRQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8916,10 +8754,10 @@
 		asm:          x86.ASHRL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8932,10 +8770,10 @@
 		asm:          x86.ASHRW,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8948,10 +8786,10 @@
 		asm:          x86.ASHRB,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8964,10 +8802,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8980,10 +8818,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -8996,10 +8834,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9012,10 +8850,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9028,10 +8866,10 @@
 		asm:          x86.ASARQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9044,10 +8882,10 @@
 		asm:          x86.ASARL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9060,10 +8898,10 @@
 		asm:          x86.ASARW,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9076,10 +8914,44 @@
 		asm:          x86.ASARB,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+			},
+		},
+	},
+	{
+		name:         "SHRDQ",
+		argLen:       3,
+		resultInArg0: true,
+		clobberFlags: true,
+		asm:          x86.ASHRQ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{2, 2},     // CX
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+			},
+			outputs: []outputInfo{
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+			},
+		},
+	},
+	{
+		name:         "SHLDQ",
+		argLen:       3,
+		resultInArg0: true,
+		clobberFlags: true,
+		asm:          x86.ASHLQ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{2, 2},     // CX
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+			},
+			outputs: []outputInfo{
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9092,10 +8964,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9108,10 +8980,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9124,10 +8996,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9140,10 +9012,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9156,10 +9028,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9172,10 +9044,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9188,10 +9060,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9204,10 +9076,10 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 2},     // CX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9220,10 +9092,10 @@
 		asm:          x86.AROLQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9236,10 +9108,10 @@
 		asm:          x86.AROLL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9252,10 +9124,10 @@
 		asm:          x86.AROLW,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9268,10 +9140,10 @@
 		asm:          x86.AROLB,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9286,11 +9158,11 @@
 		asm:            x86.AADDL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9305,11 +9177,11 @@
 		asm:            x86.AADDQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9324,11 +9196,11 @@
 		asm:            x86.ASUBQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9343,11 +9215,11 @@
 		asm:            x86.ASUBL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9362,11 +9234,11 @@
 		asm:            x86.AANDL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9381,11 +9253,11 @@
 		asm:            x86.AANDQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9400,11 +9272,11 @@
 		asm:            x86.AORQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9419,11 +9291,11 @@
 		asm:            x86.AORL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9438,11 +9310,11 @@
 		asm:            x86.AXORQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9457,11 +9329,11 @@
 		asm:            x86.AXORL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9476,12 +9348,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9496,12 +9368,12 @@
 		scale:        4,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9516,12 +9388,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9536,12 +9408,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9556,12 +9428,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9576,12 +9448,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9596,12 +9468,12 @@
 		scale:        4,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9616,12 +9488,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9636,12 +9508,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9656,12 +9528,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9676,12 +9548,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9696,12 +9568,12 @@
 		scale:        4,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9716,12 +9588,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9736,12 +9608,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9756,12 +9628,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9776,12 +9648,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9796,12 +9668,12 @@
 		scale:        4,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9816,12 +9688,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9836,12 +9708,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9856,12 +9728,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9876,12 +9748,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9896,12 +9768,12 @@
 		scale:        4,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9916,12 +9788,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9936,12 +9808,12 @@
 		scale:        1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9956,12 +9828,12 @@
 		scale:        8,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX 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
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -9975,8 +9847,8 @@
 		asm:            x86.AADDQ,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -9990,8 +9862,8 @@
 		asm:            x86.ASUBQ,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10005,8 +9877,8 @@
 		asm:            x86.AANDQ,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10020,8 +9892,8 @@
 		asm:            x86.AORQ,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10035,8 +9907,8 @@
 		asm:            x86.AXORQ,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10050,8 +9922,8 @@
 		asm:            x86.AADDL,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10065,8 +9937,8 @@
 		asm:            x86.ASUBL,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10080,8 +9952,8 @@
 		asm:            x86.AANDL,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10095,8 +9967,8 @@
 		asm:            x86.AORL,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10110,8 +9982,8 @@
 		asm:            x86.AXORL,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10125,9 +9997,9 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10141,9 +10013,9 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10157,9 +10029,9 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10173,9 +10045,9 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10189,9 +10061,9 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10205,9 +10077,9 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10221,9 +10093,9 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10237,9 +10109,9 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10253,9 +10125,9 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10269,9 +10141,9 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10285,9 +10157,9 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10301,9 +10173,9 @@
 		scale:        4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10317,9 +10189,9 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10333,9 +10205,9 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10349,9 +10221,9 @@
 		scale:        4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10365,9 +10237,9 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10381,9 +10253,9 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10397,9 +10269,9 @@
 		scale:        4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10413,9 +10285,9 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10429,9 +10301,9 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10445,9 +10317,9 @@
 		scale:        4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10461,9 +10333,9 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10477,9 +10349,9 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10493,9 +10365,9 @@
 		scale:        4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10509,9 +10381,9 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10525,8 +10397,8 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10540,8 +10412,8 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10555,8 +10427,8 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10570,8 +10442,8 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10585,8 +10457,8 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10600,8 +10472,8 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10615,8 +10487,8 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10630,8 +10502,8 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10645,8 +10517,8 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10660,8 +10532,8 @@
 		scale:        4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10675,8 +10547,8 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10690,8 +10562,8 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10705,8 +10577,8 @@
 		scale:        4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10720,8 +10592,8 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10735,8 +10607,8 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10750,8 +10622,8 @@
 		scale:        4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10765,8 +10637,8 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10780,8 +10652,8 @@
 		scale:        1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10795,8 +10667,8 @@
 		scale:        4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10810,8 +10682,8 @@
 		scale:        8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -10823,10 +10695,10 @@
 		asm:          x86.ANEGQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -10838,10 +10710,10 @@
 		asm:          x86.ANEGL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -10853,10 +10725,10 @@
 		asm:          x86.ANOTQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -10868,10 +10740,10 @@
 		asm:          x86.ANOTL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -10881,11 +10753,11 @@
 		asm:    x86.ABSFQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -10896,10 +10768,10 @@
 		asm:          x86.ABSFL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -10909,11 +10781,11 @@
 		asm:    x86.ABSRQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -10924,10 +10796,10 @@
 		asm:          x86.ABSRL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -10938,11 +10810,11 @@
 		asm:          x86.ACMOVQEQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -10953,11 +10825,11 @@
 		asm:          x86.ACMOVQNE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -10968,11 +10840,11 @@
 		asm:          x86.ACMOVQLT,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -10983,11 +10855,11 @@
 		asm:          x86.ACMOVQGT,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -10998,11 +10870,11 @@
 		asm:          x86.ACMOVQLE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11013,11 +10885,11 @@
 		asm:          x86.ACMOVQGE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11028,11 +10900,11 @@
 		asm:          x86.ACMOVQLS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11043,11 +10915,11 @@
 		asm:          x86.ACMOVQHI,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11058,11 +10930,11 @@
 		asm:          x86.ACMOVQCC,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11073,11 +10945,11 @@
 		asm:          x86.ACMOVQCS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11088,11 +10960,11 @@
 		asm:          x86.ACMOVLEQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11103,11 +10975,11 @@
 		asm:          x86.ACMOVLNE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11118,11 +10990,11 @@
 		asm:          x86.ACMOVLLT,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11133,11 +11005,11 @@
 		asm:          x86.ACMOVLGT,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11148,11 +11020,11 @@
 		asm:          x86.ACMOVLLE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11163,11 +11035,11 @@
 		asm:          x86.ACMOVLGE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11178,11 +11050,11 @@
 		asm:          x86.ACMOVLLS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11193,11 +11065,11 @@
 		asm:          x86.ACMOVLHI,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11208,11 +11080,11 @@
 		asm:          x86.ACMOVLCC,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11223,11 +11095,11 @@
 		asm:          x86.ACMOVLCS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11238,11 +11110,11 @@
 		asm:          x86.ACMOVWEQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11253,11 +11125,11 @@
 		asm:          x86.ACMOVWNE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11268,11 +11140,11 @@
 		asm:          x86.ACMOVWLT,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11283,11 +11155,11 @@
 		asm:          x86.ACMOVWGT,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11298,11 +11170,11 @@
 		asm:          x86.ACMOVWLE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11313,11 +11185,11 @@
 		asm:          x86.ACMOVWGE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11328,11 +11200,11 @@
 		asm:          x86.ACMOVWLS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11343,11 +11215,11 @@
 		asm:          x86.ACMOVWHI,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11358,11 +11230,11 @@
 		asm:          x86.ACMOVWCC,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11373,11 +11245,11 @@
 		asm:          x86.ACMOVWCS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11388,12 +11260,12 @@
 		asm:          x86.ACMOVQNE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65518}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			clobbers: 1, // AX
 			outputs: []outputInfo{
-				{0, 65518}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11404,11 +11276,11 @@
 		asm:          x86.ACMOVQNE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11419,11 +11291,11 @@
 		asm:          x86.ACMOVQHI,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11434,11 +11306,11 @@
 		asm:          x86.ACMOVQCC,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11449,12 +11321,12 @@
 		asm:          x86.ACMOVLNE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65518}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			clobbers: 1, // AX
 			outputs: []outputInfo{
-				{0, 65518}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11465,11 +11337,11 @@
 		asm:          x86.ACMOVLNE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11480,11 +11352,11 @@
 		asm:          x86.ACMOVLHI,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11495,11 +11367,11 @@
 		asm:          x86.ACMOVLCC,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11510,12 +11382,12 @@
 		asm:          x86.ACMOVWNE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65518}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			clobbers: 1, // AX
 			outputs: []outputInfo{
-				{0, 65518}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11526,11 +11398,11 @@
 		asm:          x86.ACMOVWNE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11541,11 +11413,11 @@
 		asm:          x86.ACMOVWHI,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11556,11 +11428,11 @@
 		asm:          x86.ACMOVWCC,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11572,10 +11444,10 @@
 		asm:          x86.ABSWAPQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11587,10 +11459,10 @@
 		asm:          x86.ABSWAPL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11601,10 +11473,10 @@
 		asm:          x86.APOPCNTQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11615,10 +11487,10 @@
 		asm:          x86.APOPCNTL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11628,10 +11500,23 @@
 		asm:    x86.ASQRTSD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+			},
+		},
+	},
+	{
+		name:   "SQRTSS",
+		argLen: 1,
+		asm:    x86.ASQRTSS,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+			},
+			outputs: []outputInfo{
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -11642,10 +11527,10 @@
 		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
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -11656,12 +11541,12 @@
 		asm:          x86.AVFMADD231SD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{2, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{2, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -11671,7 +11556,7 @@
 		asm:    x86.ASBBQ,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11681,7 +11566,7 @@
 		asm:    x86.ASBBL,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11691,7 +11576,7 @@
 		asm:    x86.ASETEQ,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11701,7 +11586,7 @@
 		asm:    x86.ASETNE,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11711,7 +11596,7 @@
 		asm:    x86.ASETLT,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11721,7 +11606,7 @@
 		asm:    x86.ASETLE,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11731,7 +11616,7 @@
 		asm:    x86.ASETGT,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11741,7 +11626,7 @@
 		asm:    x86.ASETGE,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11751,7 +11636,7 @@
 		asm:    x86.ASETCS,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11761,7 +11646,7 @@
 		asm:    x86.ASETLS,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11771,7 +11656,7 @@
 		asm:    x86.ASETHI,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11781,7 +11666,7 @@
 		asm:    x86.ASETCC,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11791,7 +11676,7 @@
 		asm:    x86.ASETOS,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11804,7 +11689,7 @@
 		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
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -11817,7 +11702,7 @@
 		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
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -11830,7 +11715,7 @@
 		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
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -11843,7 +11728,7 @@
 		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
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -11856,7 +11741,7 @@
 		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
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -11869,7 +11754,7 @@
 		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
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -11882,7 +11767,7 @@
 		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
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -11895,7 +11780,7 @@
 		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
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -11908,7 +11793,7 @@
 		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
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -11921,7 +11806,7 @@
 		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
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -11933,7 +11818,7 @@
 		reg: regInfo{
 			clobbers: 1, // AX
 			outputs: []outputInfo{
-				{0, 65518}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11945,7 +11830,7 @@
 		reg: regInfo{
 			clobbers: 1, // AX
 			outputs: []outputInfo{
-				{0, 65518}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11955,7 +11840,7 @@
 		asm:    x86.ASETPC,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11965,7 +11850,7 @@
 		asm:    x86.ASETPS,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11975,7 +11860,7 @@
 		asm:    x86.ASETHI,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11985,7 +11870,7 @@
 		asm:    x86.ASETCC,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11995,10 +11880,10 @@
 		asm:    x86.AMOVBQSX,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12008,10 +11893,10 @@
 		asm:    x86.AMOVBLZX,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12021,10 +11906,10 @@
 		asm:    x86.AMOVWQSX,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12034,10 +11919,10 @@
 		asm:    x86.AMOVWLZX,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12047,10 +11932,10 @@
 		asm:    x86.AMOVLQSX,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12060,10 +11945,10 @@
 		asm:    x86.AMOVL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12075,7 +11960,7 @@
 		asm:               x86.AMOVL,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12087,7 +11972,7 @@
 		asm:               x86.AMOVQ,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12097,10 +11982,10 @@
 		asm:    x86.ACVTTSD2SL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12110,10 +11995,10 @@
 		asm:    x86.ACVTTSD2SQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12123,10 +12008,10 @@
 		asm:    x86.ACVTTSS2SL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12136,10 +12021,10 @@
 		asm:    x86.ACVTTSS2SQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12149,10 +12034,10 @@
 		asm:    x86.ACVTSL2SS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -12162,10 +12047,10 @@
 		asm:    x86.ACVTSL2SD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -12175,10 +12060,10 @@
 		asm:    x86.ACVTSQ2SS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -12188,10 +12073,10 @@
 		asm:    x86.ACVTSQ2SD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -12201,10 +12086,10 @@
 		asm:    x86.ACVTSD2SS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -12214,10 +12099,10 @@
 		asm:    x86.ACVTSS2SD,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -12226,10 +12111,10 @@
 		argLen: 1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -12238,10 +12123,10 @@
 		argLen: 1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12250,10 +12135,10 @@
 		argLen: 1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -12262,10 +12147,10 @@
 		argLen: 1,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12277,11 +12162,11 @@
 		asm:          x86.APXOR,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -12294,10 +12179,10 @@
 		asm:               x86.ALEAQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12310,10 +12195,10 @@
 		asm:               x86.ALEAL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12326,10 +12211,10 @@
 		asm:               x86.ALEAW,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12343,11 +12228,11 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12361,11 +12246,11 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12379,11 +12264,11 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12396,11 +12281,11 @@
 		scale:     2,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12413,11 +12298,11 @@
 		scale:     2,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12430,11 +12315,11 @@
 		scale:     2,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12447,11 +12332,11 @@
 		scale:     4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12464,11 +12349,11 @@
 		scale:     4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12481,11 +12366,11 @@
 		scale:     4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12498,11 +12383,11 @@
 		scale:     8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12515,11 +12400,11 @@
 		scale:     8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12532,11 +12417,11 @@
 		scale:     8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12549,10 +12434,10 @@
 		asm:            x86.AMOVBLZX,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12565,10 +12450,10 @@
 		asm:            x86.AMOVBQSX,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12581,10 +12466,10 @@
 		asm:            x86.AMOVWLZX,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12597,10 +12482,10 @@
 		asm:            x86.AMOVWQSX,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12613,10 +12498,10 @@
 		asm:            x86.AMOVL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12629,10 +12514,10 @@
 		asm:            x86.AMOVLQSX,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12645,10 +12530,10 @@
 		asm:            x86.AMOVQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12661,8 +12546,8 @@
 		asm:            x86.AMOVB,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -12675,8 +12560,8 @@
 		asm:            x86.AMOVW,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -12689,8 +12574,8 @@
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -12703,8 +12588,8 @@
 		asm:            x86.AMOVQ,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -12717,10 +12602,10 @@
 		asm:            x86.AMOVUPS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+				{0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 			},
 		},
 	},
@@ -12733,8 +12618,21 @@
 		asm:            x86.AMOVUPS,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{1, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+			},
+		},
+	},
+	{
+		name:           "MOVOstorezero",
+		auxType:        auxSymOff,
+		argLen:         2,
+		faultOnNilArg0: true,
+		symEffect:      SymWrite,
+		asm:            x86.AMOVUPS,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 4295016447}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
 			},
 		},
 	},
@@ -12748,11 +12646,11 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12766,11 +12664,11 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12783,11 +12681,11 @@
 		scale:     2,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12801,11 +12699,11 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12818,11 +12716,11 @@
 		scale:     4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12835,11 +12733,11 @@
 		scale:     8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12853,11 +12751,11 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12870,11 +12768,11 @@
 		scale:     8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12888,9 +12786,9 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -12904,9 +12802,9 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -12919,9 +12817,9 @@
 		scale:     2,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -12935,9 +12833,9 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -12950,9 +12848,9 @@
 		scale:     4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -12965,9 +12863,9 @@
 		scale:     8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -12981,9 +12879,9 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -12996,9 +12894,9 @@
 		scale:     8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13011,7 +12909,7 @@
 		asm:            x86.AMOVB,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13024,7 +12922,7 @@
 		asm:            x86.AMOVW,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13037,7 +12935,7 @@
 		asm:            x86.AMOVL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13050,7 +12948,7 @@
 		asm:            x86.AMOVQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13064,8 +12962,8 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13079,8 +12977,8 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13093,8 +12991,8 @@
 		scale:     2,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13108,8 +13006,8 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13122,8 +13020,8 @@
 		scale:     4,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13137,8 +13035,8 @@
 		scale:       1,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13151,37 +13049,25 @@
 		scale:     8,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
 	{
 		name:           "DUFFZERO",
 		auxType:        auxInt64,
-		argLen:         3,
+		argLen:         2,
 		faultOnNilArg0: true,
 		unsafePoint:    true,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 128},   // DI
-				{1, 65536}, // X0
+				{0, 128}, // DI
 			},
 			clobbers: 128, // DI
 		},
 	},
 	{
-		name:              "MOVOconst",
-		auxType:           auxInt128,
-		argLen:            0,
-		rematerializeable: true,
-		reg: regInfo{
-			outputs: []outputInfo{
-				{0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
-			},
-		},
-	},
-	{
 		name:           "REPSTOSQ",
 		argLen:         4,
 		faultOnNilArg0: true,
@@ -13197,38 +13083,38 @@
 	{
 		name:         "CALLstatic",
 		auxType:      auxCallOff,
-		argLen:       1,
+		argLen:       -1,
 		clobberFlags: true,
 		call:         true,
 		reg: regInfo{
-			clobbers: 4294967279, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+			clobbers: 2147483631, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 g R15 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 		},
 	},
 	{
 		name:         "CALLclosure",
 		auxType:      auxCallOff,
-		argLen:       3,
+		argLen:       -1,
 		clobberFlags: true,
 		call:         true,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 4},     // DX
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
-			clobbers: 4294967279, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+			clobbers: 2147483631, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 g R15 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 		},
 	},
 	{
 		name:         "CALLinter",
 		auxType:      auxCallOff,
-		argLen:       2,
+		argLen:       -1,
 		clobberFlags: true,
 		call:         true,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
-			clobbers: 4294967279, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+			clobbers: 2147483631, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 g R15 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 		},
 	},
 	{
@@ -13271,7 +13157,7 @@
 		argLen: 1,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13291,7 +13177,7 @@
 		rematerializeable: true,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13301,7 +13187,7 @@
 		rematerializeable: true,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13313,7 +13199,7 @@
 		faultOnNilArg0: true,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49151}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13328,7 +13214,7 @@
 				{0, 128}, // DI
 				{1, 879}, // AX CX DX BX BP SI R8 R9
 			},
-			clobbers: 4294901760, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+			clobbers: 2147418112, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
 		},
 	},
 	{
@@ -13339,7 +13225,7 @@
 		symEffect:         SymNone,
 		reg: regInfo{
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13413,10 +13299,10 @@
 		asm:            x86.AMOVB,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13429,10 +13315,10 @@
 		asm:            x86.AMOVL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13445,10 +13331,10 @@
 		asm:            x86.AMOVQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13463,11 +13349,11 @@
 		asm:            x86.AXCHGB,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13482,11 +13368,11 @@
 		asm:            x86.AXCHGL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13501,11 +13387,11 @@
 		asm:            x86.AXCHGQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13521,11 +13407,11 @@
 		asm:            x86.AXADDL,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13541,11 +13427,11 @@
 		asm:            x86.AXADDQ,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 65519},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB
+				{0, 49135},      // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{1, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 			outputs: []outputInfo{
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13571,13 +13457,13 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 1},     // AX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{2, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			clobbers: 1, // AX
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13593,13 +13479,13 @@
 		reg: regInfo{
 			inputs: []inputInfo{
 				{1, 1},     // AX
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-				{2, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{2, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 			clobbers: 1, // AX
 			outputs: []outputInfo{
 				{1, 0},
-				{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -13614,8 +13500,8 @@
 		asm:            x86.AANDB,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13630,8 +13516,8 @@
 		asm:            x86.AANDL,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13646,8 +13532,8 @@
 		asm:            x86.AORB,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13662,8 +13548,8 @@
 		asm:            x86.AORL,
 		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
+				{1, 49151},      // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 g R15 SB
 			},
 		},
 	},
@@ -13807,7 +13693,7 @@
 				{0, 2}, // R1
 				{1, 1}, // R0
 			},
-			clobbers: 16396, // R2 R3 R14
+			clobbers: 20492, // R2 R3 R12 R14
 			outputs: []outputInfo{
 				{0, 1}, // R0
 				{1, 2}, // R1
@@ -14429,6 +14315,19 @@
 		},
 	},
 	{
+		name:   "SQRTF",
+		argLen: 1,
+		asm:    arm.ASQRTF,
+		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:   "ABSD",
 		argLen: 1,
 		asm:    arm.AABSD,
@@ -17143,7 +17042,7 @@
 				{0, 2}, // R1
 				{1, 1}, // R0
 			},
-			clobbers: 16386, // R1 R14
+			clobbers: 20482, // R1 R12 R14
 		},
 	},
 	{
@@ -17157,7 +17056,7 @@
 				{0, 4}, // R2
 				{1, 2}, // R1
 			},
-			clobbers: 16391, // R0 R1 R2 R14
+			clobbers: 20487, // R0 R1 R2 R12 R14
 		},
 	},
 	{
@@ -17318,7 +17217,7 @@
 				{0, 4}, // R2
 				{1, 8}, // R3
 			},
-			clobbers: 4294918144, // R14 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+			clobbers: 4294922240, // R12 R14 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 		},
 	},
 
@@ -18091,6 +17990,19 @@
 		},
 	},
 	{
+		name:   "FSQRTS",
+		argLen: 1,
+		asm:    arm64.AFSQRTS,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+			},
+			outputs: []outputInfo{
+				{0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+			},
+		},
+	},
+	{
 		name:   "REV",
 		argLen: 1,
 		asm:    arm64.AREV,
@@ -18117,6 +18029,19 @@
 		},
 	},
 	{
+		name:   "REV16",
+		argLen: 1,
+		asm:    arm64.AREV16,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+			},
+			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:   "REV16W",
 		argLen: 1,
 		asm:    arm64.AREV16W,
@@ -19796,6 +19721,34 @@
 		},
 	},
 	{
+		name:   "FMOVSloadidx4",
+		argLen: 3,
+		asm:    arm64.AFMOVS,
+		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
+				{0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
+			},
+			outputs: []outputInfo{
+				{0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+			},
+		},
+	},
+	{
+		name:   "FMOVDloadidx8",
+		argLen: 3,
+		asm:    arm64.AFMOVD,
+		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
+				{0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
+			},
+			outputs: []outputInfo{
+				{0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+			},
+		},
+	},
+	{
 		name:           "MOVBstore",
 		auxType:        auxSymOff,
 		argLen:         3,
@@ -20003,6 +19956,30 @@
 		},
 	},
 	{
+		name:   "FMOVSstoreidx4",
+		argLen: 4,
+		asm:    arm64.AFMOVS,
+		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
+				{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
+				{2, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+			},
+		},
+	},
+	{
+		name:   "FMOVDstoreidx8",
+		argLen: 4,
+		asm:    arm64.AFMOVD,
+		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
+				{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
+				{2, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+			},
+		},
+	},
+	{
 		name:           "MOVBstorezero",
 		auxType:        auxSymOff,
 		argLen:         2,
@@ -20629,6 +20606,62 @@
 		},
 	},
 	{
+		name:    "CSINC",
+		auxType: auxCCop,
+		argLen:  3,
+		asm:     arm64.ACSINC,
+		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
+				{1, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+			},
+			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:    "CSINV",
+		auxType: auxCCop,
+		argLen:  3,
+		asm:     arm64.ACSINV,
+		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
+				{1, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+			},
+			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:    "CSNEG",
+		auxType: auxCCop,
+		argLen:  3,
+		asm:     arm64.ACSNEG,
+		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
+				{1, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+			},
+			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:    "CSETM",
+		auxType: auxCCop,
+		argLen:  1,
+		asm:     arm64.ACSETM,
+		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:         "CALLstatic",
 		auxType:      auxCallOff,
 		argLen:       1,
@@ -20848,7 +20881,7 @@
 			inputs: []inputInfo{
 				{0, 1048576}, // R20
 			},
-			clobbers: 537919488, // R20 R30
+			clobbers: 538116096, // R16 R17 R20 R30
 		},
 	},
 	{
@@ -20876,7 +20909,7 @@
 				{0, 2097152}, // R21
 				{1, 1048576}, // R20
 			},
-			clobbers: 607125504, // R20 R21 R26 R30
+			clobbers: 607322112, // R16 R17 R20 R21 R26 R30
 		},
 	},
 	{
@@ -21373,7 +21406,7 @@
 				{0, 4}, // R2
 				{1, 8}, // R3
 			},
-			clobbers: 9223372035244163072, // R30 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+			clobbers: 9223372035244359680, // R16 R17 R30 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
 		},
 	},
 	{
@@ -21832,6 +21865,19 @@
 		},
 	},
 	{
+		name:   "SQRTF",
+		argLen: 1,
+		asm:    mips.ASQRTF,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 35183835217920}, // F0 F2 F4 F6 F8 F10 F12 F14 F16 F18 F20 F22 F24 F26 F28 F30
+			},
+			outputs: []outputInfo{
+				{0, 35183835217920}, // F0 F2 F4 F6 F8 F10 F12 F14 F16 F18 F20 F22 F24 F26 F28 F30
+			},
+		},
+	},
+	{
 		name:   "SLL",
 		argLen: 2,
 		asm:    mips.ASLL,
@@ -23311,6 +23357,19 @@
 		},
 	},
 	{
+		name:   "SQRTF",
+		argLen: 1,
+		asm:    mips.ASQRTF,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 1152921504338411520}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+			},
+			outputs: []outputInfo{
+				{0, 1152921504338411520}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+			},
+		},
+	},
+	{
 		name:   "SLLV",
 		argLen: 2,
 		asm:    mips.ASLLV,
@@ -27673,42 +27732,6 @@
 		},
 	},
 	{
-		name:              "MOVBconst",
-		auxType:           auxInt8,
-		argLen:            0,
-		rematerializeable: true,
-		asm:               riscv.AMOV,
-		reg: regInfo{
-			outputs: []outputInfo{
-				{0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
-			},
-		},
-	},
-	{
-		name:              "MOVHconst",
-		auxType:           auxInt16,
-		argLen:            0,
-		rematerializeable: true,
-		asm:               riscv.AMOV,
-		reg: regInfo{
-			outputs: []outputInfo{
-				{0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
-			},
-		},
-	},
-	{
-		name:              "MOVWconst",
-		auxType:           auxInt32,
-		argLen:            0,
-		rematerializeable: true,
-		asm:               riscv.AMOV,
-		reg: regInfo{
-			outputs: []outputInfo{
-				{0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
-			},
-		},
-	},
-	{
 		name:              "MOVDconst",
 		auxType:           auxInt64,
 		argLen:            0,
@@ -28589,6 +28612,32 @@
 		},
 	},
 	{
+		name:           "LoweredAtomicAnd32",
+		argLen:         3,
+		faultOnNilArg0: true,
+		hasSideEffects: true,
+		asm:            riscv.AAMOANDW,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 1073741812},          // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30
+				{0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 SB
+			},
+		},
+	},
+	{
+		name:           "LoweredAtomicOr32",
+		argLen:         3,
+		faultOnNilArg0: true,
+		hasSideEffects: true,
+		asm:            riscv.AAMOORW,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 1073741812},          // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30
+				{0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 SB
+			},
+		},
+	},
+	{
 		name:           "LoweredNilCheck",
 		argLen:         2,
 		nilCheck:       true,
@@ -30895,6 +30944,19 @@
 		},
 	},
 	{
+		name:   "FSQRTS",
+		argLen: 1,
+		asm:    s390x.AFSQRTS,
+		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:         "LOCGR",
 		auxType:      auxS390XCCMask,
 		argLen:       3,
@@ -33828,10 +33890,10 @@
 		asm:    wasm.AF32Sqrt,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 			outputs: []outputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 		},
 	},
@@ -33841,10 +33903,10 @@
 		asm:    wasm.AF32Trunc,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 			outputs: []outputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 		},
 	},
@@ -33854,10 +33916,10 @@
 		asm:    wasm.AF32Ceil,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 			outputs: []outputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 		},
 	},
@@ -33867,10 +33929,10 @@
 		asm:    wasm.AF32Floor,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 			outputs: []outputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 		},
 	},
@@ -33880,10 +33942,10 @@
 		asm:    wasm.AF32Nearest,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 			outputs: []outputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 		},
 	},
@@ -33893,10 +33955,10 @@
 		asm:    wasm.AF32Abs,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 			outputs: []outputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 		},
 	},
@@ -33906,11 +33968,11 @@
 		asm:    wasm.AF32Copysign,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
-				{1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{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, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+				{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
 			},
 		},
 	},
@@ -35129,6 +35191,11 @@
 		generic: true,
 	},
 	{
+		name:    "Sqrt32",
+		argLen:  1,
+		generic: true,
+	},
+	{
 		name:    "Floor",
 		argLen:  1,
 		generic: true,
@@ -35264,6 +35331,20 @@
 		generic:   true,
 	},
 	{
+		name:      "ArgIntReg",
+		auxType:   auxNameOffsetInt8,
+		argLen:    0,
+		zeroWidth: true,
+		generic:   true,
+	},
+	{
+		name:      "ArgFloatReg",
+		auxType:   auxNameOffsetInt8,
+		argLen:    0,
+		zeroWidth: true,
+		generic:   true,
+	},
+	{
 		name:      "Addr",
 		auxType:   auxSym,
 		argLen:    1,
@@ -35366,21 +35447,21 @@
 	{
 		name:    "ClosureCall",
 		auxType: auxCallOff,
-		argLen:  3,
+		argLen:  -1,
 		call:    true,
 		generic: true,
 	},
 	{
 		name:    "StaticCall",
 		auxType: auxCallOff,
-		argLen:  1,
+		argLen:  -1,
 		call:    true,
 		generic: true,
 	},
 	{
 		name:    "InterCall",
 		auxType: auxCallOff,
-		argLen:  2,
+		argLen:  -1,
 		call:    true,
 		generic: true,
 	},
@@ -35633,6 +35714,11 @@
 		generic: true,
 	},
 	{
+		name:    "SlicePtrUnchecked",
+		argLen:  1,
+		generic: true,
+	},
+	{
 		name:    "ComplexMake",
 		argLen:  2,
 		generic: true,
@@ -36122,16 +36208,21 @@
 		symEffect: SymNone,
 		generic:   true,
 	},
+	{
+		name:    "ClobberReg",
+		argLen:  0,
+		generic: true,
+	},
 }
 
 func (o Op) Asm() obj.As          { return opcodeTable[o].asm }
 func (o Op) Scale() int16         { return int16(opcodeTable[o].scale) }
 func (o Op) String() string       { return opcodeTable[o].name }
-func (o Op) UsesScratch() bool    { return opcodeTable[o].usesScratch }
 func (o Op) SymEffect() SymEffect { return opcodeTable[o].symEffect }
 func (o Op) IsCall() bool         { return opcodeTable[o].call }
 func (o Op) HasSideEffects() bool { return opcodeTable[o].hasSideEffects }
 func (o Op) UnsafePoint() bool    { return opcodeTable[o].unsafePoint }
+func (o Op) ResultInArg0() bool   { return opcodeTable[o].resultInArg0 }
 
 var registers386 = [...]Register{
 	{0, x86.REG_AX, 0, "AX"},
@@ -36152,6 +36243,8 @@
 	{15, x86.REG_X7, -1, "X7"},
 	{16, 0, -1, "SB"},
 }
+var paramIntReg386 = []int8(nil)
+var paramFloatReg386 = []int8(nil)
 var gpRegMask386 = regMask(239)
 var fpRegMask386 = regMask(65280)
 var specialRegMask386 = regMask(0)
@@ -36172,8 +36265,8 @@
 	{11, x86.REG_R11, 10, "R11"},
 	{12, x86.REG_R12, 11, "R12"},
 	{13, x86.REG_R13, 12, "R13"},
-	{14, x86.REG_R14, 13, "R14"},
-	{15, x86.REG_R15, 14, "R15"},
+	{14, x86.REGG, -1, "g"},
+	{15, x86.REG_R15, 13, "R15"},
 	{16, x86.REG_X0, -1, "X0"},
 	{17, x86.REG_X1, -1, "X1"},
 	{18, x86.REG_X2, -1, "X2"},
@@ -36192,9 +36285,11 @@
 	{31, x86.REG_X15, -1, "X15"},
 	{32, 0, -1, "SB"},
 }
-var gpRegMaskAMD64 = regMask(65519)
-var fpRegMaskAMD64 = regMask(4294901760)
-var specialRegMaskAMD64 = regMask(0)
+var paramIntRegAMD64 = []int8{0, 3, 1, 7, 6, 8, 9, 10, 11}
+var paramFloatRegAMD64 = []int8{16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
+var gpRegMaskAMD64 = regMask(49135)
+var fpRegMaskAMD64 = regMask(2147418112)
+var specialRegMaskAMD64 = regMask(2147483648)
 var framepointerRegAMD64 = int8(5)
 var linkRegAMD64 = int8(-1)
 var registersARM = [...]Register{
@@ -36232,6 +36327,8 @@
 	{31, arm.REG_F15, -1, "F15"},
 	{32, 0, -1, "SB"},
 }
+var paramIntRegARM = []int8(nil)
+var paramFloatRegARM = []int8(nil)
 var gpRegMaskARM = regMask(21503)
 var fpRegMaskARM = regMask(4294901760)
 var specialRegMaskARM = regMask(0)
@@ -36303,6 +36400,8 @@
 	{62, arm64.REG_F31, -1, "F31"},
 	{63, 0, -1, "SB"},
 }
+var paramIntRegARM64 = []int8(nil)
+var paramFloatRegARM64 = []int8(nil)
 var gpRegMaskARM64 = regMask(670826495)
 var fpRegMaskARM64 = regMask(9223372034707292160)
 var specialRegMaskARM64 = regMask(0)
@@ -36358,6 +36457,8 @@
 	{46, mips.REG_LO, -1, "LO"},
 	{47, 0, -1, "SB"},
 }
+var paramIntRegMIPS = []int8(nil)
+var paramFloatRegMIPS = []int8(nil)
 var gpRegMaskMIPS = regMask(335544318)
 var fpRegMaskMIPS = regMask(35183835217920)
 var specialRegMaskMIPS = regMask(105553116266496)
@@ -36428,6 +36529,8 @@
 	{61, mips.REG_LO, -1, "LO"},
 	{62, 0, -1, "SB"},
 }
+var paramIntRegMIPS64 = []int8(nil)
+var paramFloatRegMIPS64 = []int8(nil)
 var gpRegMaskMIPS64 = regMask(167772158)
 var fpRegMaskMIPS64 = regMask(1152921504338411520)
 var specialRegMaskMIPS64 = regMask(3458764513820540928)
@@ -36499,6 +36602,8 @@
 	{62, ppc64.REG_F30, -1, "F30"},
 	{63, ppc64.REG_F31, -1, "F31"},
 }
+var paramIntRegPPC64 = []int8(nil)
+var paramFloatRegPPC64 = []int8(nil)
 var gpRegMaskPPC64 = regMask(1073733624)
 var fpRegMaskPPC64 = regMask(576460743713488896)
 var specialRegMaskPPC64 = regMask(0)
@@ -36570,6 +36675,8 @@
 	{62, riscv.REG_F31, -1, "F31"},
 	{63, 0, -1, "SB"},
 }
+var paramIntRegRISCV64 = []int8(nil)
+var paramFloatRegRISCV64 = []int8(nil)
 var gpRegMaskRISCV64 = regMask(1006632948)
 var fpRegMaskRISCV64 = regMask(9223372034707292160)
 var specialRegMaskRISCV64 = regMask(0)
@@ -36610,6 +36717,8 @@
 	{31, s390x.REG_F15, -1, "F15"},
 	{32, 0, -1, "SB"},
 }
+var paramIntRegS390X = []int8(nil)
+var paramFloatRegS390X = []int8(nil)
 var gpRegMaskS390X = regMask(23551)
 var fpRegMaskS390X = regMask(4294901760)
 var specialRegMaskS390X = regMask(0)
@@ -36668,6 +36777,8 @@
 	{49, wasm.REGG, -1, "g"},
 	{50, 0, -1, "SB"},
 }
+var paramIntRegWasm = []int8(nil)
+var paramFloatRegWasm = []int8(nil)
 var gpRegMaskWasm = regMask(65535)
 var fpRegMaskWasm = regMask(281474976645120)
 var fp32RegMaskWasm = regMask(4294901760)
diff --git a/src/cmd/compile/internal/ssa/phiopt.go b/src/cmd/compile/internal/ssa/phiopt.go
index db7b022..745c61c 100644
--- a/src/cmd/compile/internal/ssa/phiopt.go
+++ b/src/cmd/compile/internal/ssa/phiopt.go
@@ -46,7 +46,6 @@
 			continue
 		}
 		// b0 is the if block giving the boolean value.
-
 		// reverse is the predecessor from which the truth value comes.
 		var reverse int
 		if b0.Succs[0].b == pb0 && b0.Succs[1].b == pb1 {
@@ -120,6 +119,141 @@
 			}
 		}
 	}
+	// strengthen phi optimization.
+	// Main use case is to transform:
+	//   x := false
+	//   if c {
+	//     x = true
+	//     ...
+	//   }
+	// into
+	//   x := c
+	//   if x { ... }
+	//
+	// For example, in SSA code a case appears as
+	// b0
+	//   If c -> b, sb0
+	// sb0
+	//   If d -> sd0, sd1
+	// sd1
+	//   ...
+	// sd0
+	//   Plain -> b
+	// b
+	//   x = (OpPhi (ConstBool [true]) (ConstBool [false]))
+	//
+	// In this case we can also replace x with a copy of c.
+	//
+	// The optimization idea:
+	// 1. block b has a phi value x, x = OpPhi (ConstBool [true]) (ConstBool [false]),
+	//    and len(b.Preds) is equal to 2.
+	// 2. find the common dominator(b0) of the predecessors(pb0, pb1) of block b, and the
+	//    dominator(b0) is a If block.
+	//    Special case: one of the predecessors(pb0 or pb1) is the dominator(b0).
+	// 3. the successors(sb0, sb1) of the dominator need to dominate the predecessors(pb0, pb1)
+	//    of block b respectively.
+	// 4. replace this boolean Phi based on dominator block.
+	//
+	//     b0(pb0)            b0(pb1)          b0
+	//    |  \               /  |             /  \
+	//    |  sb1           sb0  |           sb0  sb1
+	//    |  ...           ...  |           ...   ...
+	//    |  pb1           pb0  |           pb0  pb1
+	//    |  /               \  |            \   /
+	//     b                   b               b
+	//
+	var lca *lcaRange
+	for _, b := range f.Blocks {
+		if len(b.Preds) != 2 || len(b.Values) == 0 {
+			// TODO: handle more than 2 predecessors, e.g. a || b || c.
+			continue
+		}
+
+		for _, v := range b.Values {
+			// find a phi value v = OpPhi (ConstBool [true]) (ConstBool [false]).
+			// TODO: v = OpPhi (ConstBool [true]) (Arg <bool> {value})
+			if v.Op != OpPhi {
+				continue
+			}
+			if v.Args[0].Op != OpConstBool || v.Args[1].Op != OpConstBool {
+				continue
+			}
+			if v.Args[0].AuxInt == v.Args[1].AuxInt {
+				continue
+			}
+
+			pb0 := b.Preds[0].b
+			pb1 := b.Preds[1].b
+			if pb0.Kind == BlockIf && pb0 == sdom.Parent(b) {
+				// special case: pb0 is the dominator block b0.
+				//     b0(pb0)
+				//    |  \
+				//    |  sb1
+				//    |  ...
+				//    |  pb1
+				//    |  /
+				//     b
+				// if another successor sb1 of b0(pb0) dominates pb1, do replace.
+				ei := b.Preds[0].i
+				sb1 := pb0.Succs[1-ei].b
+				if sdom.IsAncestorEq(sb1, pb1) {
+					convertPhi(pb0, v, ei)
+					break
+				}
+			} else if pb1.Kind == BlockIf && pb1 == sdom.Parent(b) {
+				// special case: pb1 is the dominator block b0.
+				//       b0(pb1)
+				//     /   |
+				//    sb0  |
+				//    ...  |
+				//    pb0  |
+				//      \  |
+				//        b
+				// if another successor sb0 of b0(pb0) dominates pb0, do replace.
+				ei := b.Preds[1].i
+				sb0 := pb1.Succs[1-ei].b
+				if sdom.IsAncestorEq(sb0, pb0) {
+					convertPhi(pb1, v, 1-ei)
+					break
+				}
+			} else {
+				//      b0
+				//     /   \
+				//    sb0  sb1
+				//    ...  ...
+				//    pb0  pb1
+				//      \   /
+				//        b
+				//
+				// Build data structure for fast least-common-ancestor queries.
+				if lca == nil {
+					lca = makeLCArange(f)
+				}
+				b0 := lca.find(pb0, pb1)
+				if b0.Kind != BlockIf {
+					break
+				}
+				sb0 := b0.Succs[0].b
+				sb1 := b0.Succs[1].b
+				var reverse int
+				if sdom.IsAncestorEq(sb0, pb0) && sdom.IsAncestorEq(sb1, pb1) {
+					reverse = 0
+				} else if sdom.IsAncestorEq(sb1, pb0) && sdom.IsAncestorEq(sb0, pb1) {
+					reverse = 1
+				} else {
+					break
+				}
+				if len(sb0.Preds) != 1 || len(sb1.Preds) != 1 {
+					// we can not replace phi value x in the following case.
+					//   if gp == nil || sp < lo { x = true}
+					//   if a || b { x = true }
+					// so the if statement can only have one condition.
+					break
+				}
+				convertPhi(b0, v, reverse)
+			}
+		}
+	}
 }
 
 func phioptint(v *Value, b0 *Block, reverse int) {
@@ -174,3 +308,16 @@
 		f.Warnl(v.Block.Pos, "converted OpPhi bool -> int%d", v.Type.Size()*8)
 	}
 }
+
+// b is the If block giving the boolean value.
+// v is the phi value v = (OpPhi (ConstBool [true]) (ConstBool [false])).
+// reverse is the predecessor from which the truth value comes.
+func convertPhi(b *Block, v *Value, reverse int) {
+	f := b.Func
+	ops := [2]Op{OpNot, OpCopy}
+	v.reset(ops[v.Args[reverse].AuxInt])
+	v.AddArg(b.Controls[0])
+	if f.pass.debug > 0 {
+		f.Warnl(b.Pos, "converted OpPhi to %v", v.Op)
+	}
+}
diff --git a/src/cmd/compile/internal/ssa/poset.go b/src/cmd/compile/internal/ssa/poset.go
index f5a2b3a..d2719eb 100644
--- a/src/cmd/compile/internal/ssa/poset.go
+++ b/src/cmd/compile/internal/ssa/poset.go
@@ -12,7 +12,7 @@
 // If true, check poset integrity after every mutation
 var debugPoset = false
 
-const uintSize = 32 << (^uint(0) >> 32 & 1) // 32 or 64
+const uintSize = 32 << (^uint(0) >> 63) // 32 or 64
 
 // bitset is a bit array for dense indexes.
 type bitset []uint
@@ -136,13 +136,13 @@
 // Most internal data structures are pre-allocated and flat, so for instance adding a
 // new relation does not cause any allocation. For performance reasons,
 // each node has only up to two outgoing edges (like a binary tree), so intermediate
-// "dummy" nodes are required to represent more than two relations. For instance,
+// "extra" nodes are required to represent more than two relations. For instance,
 // to record that A<I, A<J, A<K (with no known relation between I,J,K), we create the
 // following DAG:
 //
 //         A
 //        / \
-//       I  dummy
+//       I  extra
 //           /  \
 //          J    K
 //
@@ -223,7 +223,7 @@
 		po.setchr(i1, e2)
 		po.upush(undoSetChr, i1, 0)
 	} else {
-		// If n1 already has two children, add an intermediate dummy
+		// If n1 already has two children, add an intermediate extra
 		// node to record the relation correctly (without relating
 		// n2 to other existing nodes). Use a non-deterministic value
 		// to decide whether to append on the left or the right, to avoid
@@ -231,27 +231,27 @@
 		//
 		//      n1
 		//     /  \
-		//   i1l  dummy
+		//   i1l  extra
 		//        /   \
 		//      i1r   n2
 		//
-		dummy := po.newnode(nil)
+		extra := po.newnode(nil)
 		if (i1^i2)&1 != 0 { // non-deterministic
-			po.setchl(dummy, i1r)
-			po.setchr(dummy, e2)
-			po.setchr(i1, newedge(dummy, false))
+			po.setchl(extra, i1r)
+			po.setchr(extra, e2)
+			po.setchr(i1, newedge(extra, false))
 			po.upush(undoSetChr, i1, i1r)
 		} else {
-			po.setchl(dummy, i1l)
-			po.setchr(dummy, e2)
-			po.setchl(i1, newedge(dummy, false))
+			po.setchl(extra, i1l)
+			po.setchr(extra, e2)
+			po.setchl(i1, newedge(extra, false))
 			po.upush(undoSetChl, i1, i1l)
 		}
 	}
 }
 
 // newnode allocates a new node bound to SSA value n.
-// If n is nil, this is a dummy node (= only used internally).
+// If n is nil, this is an extra node (= only used internally).
 func (po *poset) newnode(n *Value) uint32 {
 	i := po.lastidx + 1
 	po.lastidx++
@@ -380,9 +380,9 @@
 
 	case higherptr != 0:
 		// Higher bound only. To record n < higher, we need
-		// a dummy root:
+		// an extra root:
 		//
-		//        dummy
+		//        extra
 		//        /   \
 		//      root   \
 		//       /      n
@@ -395,11 +395,11 @@
 		if r2 != po.roots[0] { // all constants should be in root #0
 			panic("constant not in root #0")
 		}
-		dummy := po.newnode(nil)
-		po.changeroot(r2, dummy)
-		po.upush(undoChangeRoot, dummy, newedge(r2, false))
-		po.addchild(dummy, r2, false)
-		po.addchild(dummy, i, false)
+		extra := po.newnode(nil)
+		po.changeroot(r2, extra)
+		po.upush(undoChangeRoot, extra, newedge(r2, false))
+		po.addchild(extra, r2, false)
+		po.addchild(extra, i, false)
 		po.addchild(i, i2, true)
 	}
 
@@ -612,7 +612,7 @@
 	panic("findroot didn't find any root")
 }
 
-// mergeroot merges two DAGs into one DAG by creating a new dummy root
+// mergeroot merges two DAGs into one DAG by creating a new extra root
 func (po *poset) mergeroot(r1, r2 uint32) uint32 {
 	// Root #0 is special as it contains all constants. Since mergeroot
 	// discards r2 as root and keeps r1, make sure that r2 is not root #0,
@@ -1004,7 +1004,7 @@
 	case !f1 && f2:
 		// n1 is not in any DAG but n2 is. If n2 is a root, we can put
 		// n1 in its place as a root; otherwise, we need to create a new
-		// dummy root to record the relation.
+		// extra root to record the relation.
 		i1 = po.newnode(n1)
 
 		if po.isroot(i2) {
@@ -1020,17 +1020,17 @@
 
 		// Re-parent as follows:
 		//
-		//                  dummy
+		//                  extra
 		//     r            /   \
 		//      \   ===>   r    i1
 		//      i2          \   /
 		//                    i2
 		//
-		dummy := po.newnode(nil)
-		po.changeroot(r, dummy)
-		po.upush(undoChangeRoot, dummy, newedge(r, false))
-		po.addchild(dummy, r, false)
-		po.addchild(dummy, i1, false)
+		extra := po.newnode(nil)
+		po.changeroot(r, extra)
+		po.upush(undoChangeRoot, extra, newedge(r, false))
+		po.addchild(extra, r, false)
+		po.addchild(extra, i1, false)
 		po.addchild(i1, i2, strict)
 
 	case f1 && f2:
diff --git a/src/cmd/compile/internal/ssa/print.go b/src/cmd/compile/internal/ssa/print.go
index 36f09c3..d917183 100644
--- a/src/cmd/compile/internal/ssa/print.go
+++ b/src/cmd/compile/internal/ssa/print.go
@@ -154,6 +154,6 @@
 		p.endBlock(b)
 	}
 	for _, name := range f.Names {
-		p.named(name, f.NamedValues[name])
+		p.named(*name, f.NamedValues[*name])
 	}
 }
diff --git a/src/cmd/compile/internal/ssa/prove.go b/src/cmd/compile/internal/ssa/prove.go
index 8a2e7c0..b203584 100644
--- a/src/cmd/compile/internal/ssa/prove.go
+++ b/src/cmd/compile/internal/ssa/prove.go
@@ -726,6 +726,20 @@
 	}
 )
 
+// cleanup returns the posets to the free list
+func (ft *factsTable) cleanup(f *Func) {
+	for _, po := range []*poset{ft.orderS, ft.orderU} {
+		// Make sure it's empty as it should be. A non-empty poset
+		// might cause errors and miscompilations if reused.
+		if checkEnabled {
+			if err := po.CheckEmpty(); err != nil {
+				f.Fatalf("poset not empty after function %s: %v", f.Name, err)
+			}
+		}
+		f.retPoset(po)
+	}
+}
+
 // prove removes redundant BlockIf branches that can be inferred
 // from previous dominating comparisons.
 //
@@ -778,7 +792,14 @@
 				if ft.lens == nil {
 					ft.lens = map[ID]*Value{}
 				}
-				ft.lens[v.Args[0].ID] = v
+				// Set all len Values for the same slice as equal in the poset.
+				// The poset handles transitive relations, so Values related to
+				// any OpSliceLen for this slice will be correctly related to others.
+				if l, ok := ft.lens[v.Args[0].ID]; ok {
+					ft.update(b, v, l, signed, eq)
+				} else {
+					ft.lens[v.Args[0].ID] = v
+				}
 				ft.update(b, v, ft.zero, signed, gt|eq)
 				if v.Args[0].Op == OpSliceMake {
 					if lensVars == nil {
@@ -790,7 +811,12 @@
 				if ft.caps == nil {
 					ft.caps = map[ID]*Value{}
 				}
-				ft.caps[v.Args[0].ID] = v
+				// Same as case OpSliceLen above, but for slice cap.
+				if c, ok := ft.caps[v.Args[0].ID]; ok {
+					ft.update(b, v, c, signed, eq)
+				} else {
+					ft.caps[v.Args[0].ID] = v
+				}
 				ft.update(b, v, ft.zero, signed, gt|eq)
 				if v.Args[0].Op == OpSliceMake {
 					if lensVars == nil {
@@ -905,17 +931,7 @@
 
 	ft.restore()
 
-	// Return the posets to the free list
-	for _, po := range []*poset{ft.orderS, ft.orderU} {
-		// Make sure it's empty as it should be. A non-empty poset
-		// might cause errors and miscompilations if reused.
-		if checkEnabled {
-			if err := po.CheckEmpty(); err != nil {
-				f.Fatalf("prove poset not empty after function %s: %v", f.Name, err)
-			}
-		}
-		f.retPoset(po)
-	}
+	ft.cleanup(f)
 }
 
 // getBranch returns the range restrictions added by p
diff --git a/src/cmd/compile/internal/ssa/redblack32.go b/src/cmd/compile/internal/ssa/redblack32.go
deleted file mode 100644
index fc9cc71..0000000
--- a/src/cmd/compile/internal/ssa/redblack32.go
+++ /dev/null
@@ -1,429 +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.
-
-package ssa
-
-import "fmt"
-
-const (
-	rankLeaf rbrank = 1
-	rankZero rbrank = 0
-)
-
-type rbrank int8
-
-// RBTint32 is a red-black tree with data stored at internal nodes,
-// following Tarjan, Data Structures and Network Algorithms,
-// pp 48-52, using explicit rank instead of red and black.
-// Deletion is not yet implemented because it is not yet needed.
-// Extra operations glb, lub, glbEq, lubEq are provided for
-// use in sparse lookup algorithms.
-type RBTint32 struct {
-	root *node32
-	// An extra-clever implementation will have special cases
-	// for small sets, but we are not extra-clever today.
-}
-
-func (t *RBTint32) String() string {
-	if t.root == nil {
-		return "[]"
-	}
-	return "[" + t.root.String() + "]"
-}
-
-func (t *node32) String() string {
-	s := ""
-	if t.left != nil {
-		s = t.left.String() + " "
-	}
-	s = s + fmt.Sprintf("k=%d,d=%v", t.key, t.data)
-	if t.right != nil {
-		s = s + " " + t.right.String()
-	}
-	return s
-}
-
-type node32 struct {
-	// Standard conventions hold for left = smaller, right = larger
-	left, right, parent *node32
-	data                interface{}
-	key                 int32
-	rank                rbrank // From Tarjan pp 48-49:
-	// If x is a node with a parent, then x.rank <= x.parent.rank <= x.rank+1.
-	// If x is a node with a grandparent, then x.rank < x.parent.parent.rank.
-	// If x is an "external [null] node", then x.rank = 0 && x.parent.rank = 1.
-	// Any node with one or more null children should have rank = 1.
-}
-
-// makeNode returns a new leaf node with the given key and nil data.
-func (t *RBTint32) makeNode(key int32) *node32 {
-	return &node32{key: key, rank: rankLeaf}
-}
-
-// IsEmpty reports whether t is empty.
-func (t *RBTint32) IsEmpty() bool {
-	return t.root == nil
-}
-
-// IsSingle reports whether t is a singleton (leaf).
-func (t *RBTint32) IsSingle() bool {
-	return t.root != nil && t.root.isLeaf()
-}
-
-// VisitInOrder applies f to the key and data pairs in t,
-// with keys ordered from smallest to largest.
-func (t *RBTint32) VisitInOrder(f func(int32, interface{})) {
-	if t.root == nil {
-		return
-	}
-	t.root.visitInOrder(f)
-}
-
-func (n *node32) Data() interface{} {
-	if n == nil {
-		return nil
-	}
-	return n.data
-}
-
-func (n *node32) keyAndData() (k int32, d interface{}) {
-	if n == nil {
-		k = 0
-		d = nil
-	} else {
-		k = n.key
-		d = n.data
-	}
-	return
-}
-
-func (n *node32) Rank() rbrank {
-	if n == nil {
-		return 0
-	}
-	return n.rank
-}
-
-// Find returns the data associated with key in the tree, or
-// nil if key is not in the tree.
-func (t *RBTint32) Find(key int32) interface{} {
-	return t.root.find(key).Data()
-}
-
-// Insert adds key to the tree and associates key with data.
-// If key was already in the tree, it updates the associated data.
-// Insert returns the previous data associated with key,
-// or nil if key was not present.
-// Insert panics if data is nil.
-func (t *RBTint32) Insert(key int32, data interface{}) interface{} {
-	if data == nil {
-		panic("Cannot insert nil data into tree")
-	}
-	n := t.root
-	var newroot *node32
-	if n == nil {
-		n = t.makeNode(key)
-		newroot = n
-	} else {
-		newroot, n = n.insert(key, t)
-	}
-	r := n.data
-	n.data = data
-	t.root = newroot
-	return r
-}
-
-// Min returns the minimum element of t and its associated data.
-// If t is empty, then (0, nil) is returned.
-func (t *RBTint32) Min() (k int32, d interface{}) {
-	return t.root.min().keyAndData()
-}
-
-// Max returns the maximum element of t and its associated data.
-// If t is empty, then (0, nil) is returned.
-func (t *RBTint32) Max() (k int32, d interface{}) {
-	return t.root.max().keyAndData()
-}
-
-// Glb returns the greatest-lower-bound-exclusive of x and its associated
-// data.  If x has no glb in the tree, then (0, nil) is returned.
-func (t *RBTint32) Glb(x int32) (k int32, d interface{}) {
-	return t.root.glb(x, false).keyAndData()
-}
-
-// GlbEq returns the greatest-lower-bound-inclusive of x and its associated
-// data.  If x has no glbEQ in the tree, then (0, nil) is returned.
-func (t *RBTint32) GlbEq(x int32) (k int32, d interface{}) {
-	return t.root.glb(x, true).keyAndData()
-}
-
-// Lub returns the least-upper-bound-exclusive of x and its associated
-// data.  If x has no lub in the tree, then (0, nil) is returned.
-func (t *RBTint32) Lub(x int32) (k int32, d interface{}) {
-	return t.root.lub(x, false).keyAndData()
-}
-
-// LubEq returns the least-upper-bound-inclusive of x and its associated
-// data.  If x has no lubEq in the tree, then (0, nil) is returned.
-func (t *RBTint32) LubEq(x int32) (k int32, d interface{}) {
-	return t.root.lub(x, true).keyAndData()
-}
-
-func (t *node32) isLeaf() bool {
-	return t.left == nil && t.right == nil
-}
-
-func (t *node32) visitInOrder(f func(int32, interface{})) {
-	if t.left != nil {
-		t.left.visitInOrder(f)
-	}
-	f(t.key, t.data)
-	if t.right != nil {
-		t.right.visitInOrder(f)
-	}
-}
-
-func (t *node32) maxChildRank() rbrank {
-	if t.left == nil {
-		if t.right == nil {
-			return rankZero
-		}
-		return t.right.rank
-	}
-	if t.right == nil {
-		return t.left.rank
-	}
-	if t.right.rank > t.left.rank {
-		return t.right.rank
-	}
-	return t.left.rank
-}
-
-func (t *node32) minChildRank() rbrank {
-	if t.left == nil || t.right == nil {
-		return rankZero
-	}
-	if t.right.rank < t.left.rank {
-		return t.right.rank
-	}
-	return t.left.rank
-}
-
-func (t *node32) find(key int32) *node32 {
-	for t != nil {
-		if key < t.key {
-			t = t.left
-		} else if key > t.key {
-			t = t.right
-		} else {
-			return t
-		}
-	}
-	return nil
-}
-
-func (t *node32) min() *node32 {
-	if t == nil {
-		return t
-	}
-	for t.left != nil {
-		t = t.left
-	}
-	return t
-}
-
-func (t *node32) max() *node32 {
-	if t == nil {
-		return t
-	}
-	for t.right != nil {
-		t = t.right
-	}
-	return t
-}
-
-func (t *node32) glb(key int32, allow_eq bool) *node32 {
-	var best *node32
-	for t != nil {
-		if key <= t.key {
-			if key == t.key && allow_eq {
-				return t
-			}
-			// t is too big, glb is to left.
-			t = t.left
-		} else {
-			// t is a lower bound, record it and seek a better one.
-			best = t
-			t = t.right
-		}
-	}
-	return best
-}
-
-func (t *node32) lub(key int32, allow_eq bool) *node32 {
-	var best *node32
-	for t != nil {
-		if key >= t.key {
-			if key == t.key && allow_eq {
-				return t
-			}
-			// t is too small, lub is to right.
-			t = t.right
-		} else {
-			// t is a upper bound, record it and seek a better one.
-			best = t
-			t = t.left
-		}
-	}
-	return best
-}
-
-func (t *node32) insert(x int32, w *RBTint32) (newroot, newnode *node32) {
-	// defaults
-	newroot = t
-	newnode = t
-	if x == t.key {
-		return
-	}
-	if x < t.key {
-		if t.left == nil {
-			n := w.makeNode(x)
-			n.parent = t
-			t.left = n
-			newnode = n
-			return
-		}
-		var new_l *node32
-		new_l, newnode = t.left.insert(x, w)
-		t.left = new_l
-		new_l.parent = t
-		newrank := 1 + new_l.maxChildRank()
-		if newrank > t.rank {
-			if newrank > 1+t.right.Rank() { // rotations required
-				if new_l.left.Rank() < new_l.right.Rank() {
-					// double rotation
-					t.left = new_l.rightToRoot()
-				}
-				newroot = t.leftToRoot()
-				return
-			} else {
-				t.rank = newrank
-			}
-		}
-	} else { // x > t.key
-		if t.right == nil {
-			n := w.makeNode(x)
-			n.parent = t
-			t.right = n
-			newnode = n
-			return
-		}
-		var new_r *node32
-		new_r, newnode = t.right.insert(x, w)
-		t.right = new_r
-		new_r.parent = t
-		newrank := 1 + new_r.maxChildRank()
-		if newrank > t.rank {
-			if newrank > 1+t.left.Rank() { // rotations required
-				if new_r.right.Rank() < new_r.left.Rank() {
-					// double rotation
-					t.right = new_r.leftToRoot()
-				}
-				newroot = t.rightToRoot()
-				return
-			} else {
-				t.rank = newrank
-			}
-		}
-	}
-	return
-}
-
-func (t *node32) rightToRoot() *node32 {
-	//    this
-	// left  right
-	//      rl   rr
-	//
-	// becomes
-	//
-	//       right
-	//    this   rr
-	// left  rl
-	//
-	right := t.right
-	rl := right.left
-	right.parent = t.parent
-	right.left = t
-	t.parent = right
-	// parent's child ptr fixed in caller
-	t.right = rl
-	if rl != nil {
-		rl.parent = t
-	}
-	return right
-}
-
-func (t *node32) leftToRoot() *node32 {
-	//     this
-	//  left  right
-	// ll  lr
-	//
-	// becomes
-	//
-	//    left
-	//   ll  this
-	//      lr  right
-	//
-	left := t.left
-	lr := left.right
-	left.parent = t.parent
-	left.right = t
-	t.parent = left
-	// parent's child ptr fixed in caller
-	t.left = lr
-	if lr != nil {
-		lr.parent = t
-	}
-	return left
-}
-
-// next returns the successor of t in a left-to-right
-// walk of the tree in which t is embedded.
-func (t *node32) next() *node32 {
-	// If there is a right child, it is to the right
-	r := t.right
-	if r != nil {
-		return r.min()
-	}
-	// if t is p.left, then p, else repeat.
-	p := t.parent
-	for p != nil {
-		if p.left == t {
-			return p
-		}
-		t = p
-		p = t.parent
-	}
-	return nil
-}
-
-// prev returns the predecessor of t in a left-to-right
-// walk of the tree in which t is embedded.
-func (t *node32) prev() *node32 {
-	// If there is a left child, it is to the left
-	l := t.left
-	if l != nil {
-		return l.max()
-	}
-	// if t is p.right, then p, else repeat.
-	p := t.parent
-	for p != nil {
-		if p.right == t {
-			return p
-		}
-		t = p
-		p = t.parent
-	}
-	return nil
-}
diff --git a/src/cmd/compile/internal/ssa/redblack32_test.go b/src/cmd/compile/internal/ssa/redblack32_test.go
deleted file mode 100644
index 376e8cf..0000000
--- a/src/cmd/compile/internal/ssa/redblack32_test.go
+++ /dev/null
@@ -1,274 +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.
-
-package ssa
-
-import (
-	"fmt"
-	"testing"
-)
-
-type sstring string
-
-func (s sstring) String() string {
-	return string(s)
-}
-
-// wellFormed ensures that a red-black tree meets
-// all of its invariants and returns a string identifying
-// the first problem encountered. If there is no problem
-// then the returned string is empty. The size is also
-// returned to allow comparison of calculated tree size
-// with expected.
-func (t *RBTint32) wellFormed() (s string, i int) {
-	if t.root == nil {
-		s = ""
-		i = 0
-		return
-	}
-	return t.root.wellFormedSubtree(nil, -0x80000000, 0x7fffffff)
-}
-
-// wellFormedSubtree ensures that a red-black subtree meets
-// all of its invariants and returns a string identifying
-// the first problem encountered. If there is no problem
-// then the returned string is empty. The size is also
-// returned to allow comparison of calculated tree size
-// with expected.
-func (t *node32) wellFormedSubtree(parent *node32, min, max int32) (s string, i int) {
-	i = -1 // initialize to a failing value
-	s = "" // s is the reason for failure; empty means okay.
-
-	if t.parent != parent {
-		s = "t.parent != parent"
-		return
-	}
-
-	if min >= t.key {
-		s = "min >= t.key"
-		return
-	}
-
-	if max <= t.key {
-		s = "max <= t.key"
-		return
-	}
-
-	l := t.left
-	r := t.right
-	if l == nil && r == nil {
-		if t.rank != rankLeaf {
-			s = "leaf rank wrong"
-			return
-		}
-	}
-	if l != nil {
-		if t.rank < l.rank {
-			s = "t.rank < l.rank"
-		} else if t.rank > 1+l.rank {
-			s = "t.rank > 1+l.rank"
-		} else if t.rank <= l.maxChildRank() {
-			s = "t.rank <= l.maxChildRank()"
-		} else if t.key <= l.key {
-			s = "t.key <= l.key"
-		}
-		if s != "" {
-			return
-		}
-	} else {
-		if t.rank != 1 {
-			s = "t w/ left nil has rank != 1"
-			return
-		}
-	}
-	if r != nil {
-		if t.rank < r.rank {
-			s = "t.rank < r.rank"
-		} else if t.rank > 1+r.rank {
-			s = "t.rank > 1+r.rank"
-		} else if t.rank <= r.maxChildRank() {
-			s = "t.rank <= r.maxChildRank()"
-		} else if t.key >= r.key {
-			s = "t.key >= r.key"
-		}
-		if s != "" {
-			return
-		}
-	} else {
-		if t.rank != 1 {
-			s = "t w/ right nil has rank != 1"
-			return
-		}
-	}
-	ii := 1
-	if l != nil {
-		res, il := l.wellFormedSubtree(t, min, t.key)
-		if res != "" {
-			s = "L." + res
-			return
-		}
-		ii += il
-	}
-	if r != nil {
-		res, ir := r.wellFormedSubtree(t, t.key, max)
-		if res != "" {
-			s = "R." + res
-			return
-		}
-		ii += ir
-	}
-	i = ii
-	return
-}
-
-func (t *RBTint32) DebugString() string {
-	if t.root == nil {
-		return ""
-	}
-	return t.root.DebugString()
-}
-
-// DebugString prints the tree with nested information
-// to allow an eyeball check on the tree balance.
-func (t *node32) DebugString() string {
-	s := ""
-	if t.left != nil {
-		s += "["
-		s += t.left.DebugString()
-		s += "]"
-	}
-	s += fmt.Sprintf("%v=%v:%d", t.key, t.data, t.rank)
-	if t.right != nil {
-		s += "["
-		s += t.right.DebugString()
-		s += "]"
-	}
-	return s
-}
-
-func allRBT32Ops(te *testing.T, x []int32) {
-	t := &RBTint32{}
-	for i, d := range x {
-		x[i] = d + d // Double everything for glb/lub testing
-	}
-
-	// fmt.Printf("Inserting double of %v", x)
-	k := 0
-	min := int32(0x7fffffff)
-	max := int32(-0x80000000)
-	for _, d := range x {
-		if d < min {
-			min = d
-		}
-
-		if d > max {
-			max = d
-		}
-
-		t.Insert(d, sstring(fmt.Sprintf("%v", d)))
-		k++
-		s, i := t.wellFormed()
-		if i != k {
-			te.Errorf("Wrong tree size %v, expected %v for %v", i, k, t.DebugString())
-		}
-		if s != "" {
-			te.Errorf("Tree consistency problem at %v", s)
-			return
-		}
-	}
-
-	oops := false
-
-	for _, d := range x {
-		s := fmt.Sprintf("%v", d)
-		f := t.Find(d)
-
-		// data
-		if s != fmt.Sprintf("%v", f) {
-			te.Errorf("s(%v) != f(%v)", s, f)
-			oops = true
-		}
-	}
-
-	if !oops {
-		for _, d := range x {
-			s := fmt.Sprintf("%v", d)
-
-			kg, g := t.Glb(d + 1)
-			kge, ge := t.GlbEq(d)
-			kl, l := t.Lub(d - 1)
-			kle, le := t.LubEq(d)
-
-			// keys
-			if d != kg {
-				te.Errorf("d(%v) != kg(%v)", d, kg)
-			}
-			if d != kl {
-				te.Errorf("d(%v) != kl(%v)", d, kl)
-			}
-			if d != kge {
-				te.Errorf("d(%v) != kge(%v)", d, kge)
-			}
-			if d != kle {
-				te.Errorf("d(%v) != kle(%v)", d, kle)
-			}
-			// data
-			if s != fmt.Sprintf("%v", g) {
-				te.Errorf("s(%v) != g(%v)", s, g)
-			}
-			if s != fmt.Sprintf("%v", l) {
-				te.Errorf("s(%v) != l(%v)", s, l)
-			}
-			if s != fmt.Sprintf("%v", ge) {
-				te.Errorf("s(%v) != ge(%v)", s, ge)
-			}
-			if s != fmt.Sprintf("%v", le) {
-				te.Errorf("s(%v) != le(%v)", s, le)
-			}
-		}
-
-		for _, d := range x {
-			s := fmt.Sprintf("%v", d)
-			kge, ge := t.GlbEq(d + 1)
-			kle, le := t.LubEq(d - 1)
-			if d != kge {
-				te.Errorf("d(%v) != kge(%v)", d, kge)
-			}
-			if d != kle {
-				te.Errorf("d(%v) != kle(%v)", d, kle)
-			}
-			if s != fmt.Sprintf("%v", ge) {
-				te.Errorf("s(%v) != ge(%v)", s, ge)
-			}
-			if s != fmt.Sprintf("%v", le) {
-				te.Errorf("s(%v) != le(%v)", s, le)
-			}
-		}
-
-		kg, g := t.Glb(min)
-		kge, ge := t.GlbEq(min - 1)
-		kl, l := t.Lub(max)
-		kle, le := t.LubEq(max + 1)
-		fmin := t.Find(min - 1)
-		fmax := t.Find(min + 11)
-
-		if kg != 0 || kge != 0 || kl != 0 || kle != 0 {
-			te.Errorf("Got non-zero-key for missing query")
-		}
-
-		if g != nil || ge != nil || l != nil || le != nil || fmin != nil || fmax != nil {
-			te.Errorf("Got non-error-data for missing query")
-		}
-
-	}
-}
-
-func TestAllRBTreeOps(t *testing.T) {
-	allRBT32Ops(t, []int32{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})
-	allRBT32Ops(t, []int32{22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 3, 2, 1, 25, 24, 23, 12, 11, 10, 9, 8, 7, 6, 5, 4})
-	allRBT32Ops(t, []int32{25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1})
-	allRBT32Ops(t, []int32{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24})
-	allRBT32Ops(t, []int32{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2})
-	allRBT32Ops(t, []int32{24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25})
-}
diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go
index 0339b07..3b90b87 100644
--- a/src/cmd/compile/internal/ssa/regalloc.go
+++ b/src/cmd/compile/internal/ssa/regalloc.go
@@ -104,7 +104,7 @@
 // If b3 is the primary predecessor of b2, then we use x3 in b2 and
 // add a x4:CX->BX copy at the end of b4.
 // But the definition of x3 doesn't dominate b2.  We should really
-// insert a dummy phi at the start of b2 (x5=phi(x3,x4):BX) to keep
+// insert an extra phi at the start of b2 (x5=phi(x3,x4):BX) to keep
 // SSA form. For now, we ignore this problem as remaining in strict
 // SSA form isn't needed after regalloc. We'll just leave the use
 // of x3 not dominated by the definition of x3, and the CX->BX copy
@@ -114,11 +114,13 @@
 package ssa
 
 import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/types"
-	"cmd/internal/objabi"
 	"cmd/internal/src"
 	"cmd/internal/sys"
 	"fmt"
+	"internal/buildcfg"
 	"math/bits"
 	"unsafe"
 )
@@ -150,6 +152,14 @@
 
 const noRegister register = 255
 
+// For bulk initializing
+var noRegisters [32]register = [32]register{
+	noRegister, noRegister, noRegister, noRegister, noRegister, noRegister, noRegister, noRegister,
+	noRegister, noRegister, noRegister, noRegister, noRegister, noRegister, noRegister, noRegister,
+	noRegister, noRegister, noRegister, noRegister, noRegister, noRegister, noRegister, noRegister,
+	noRegister, noRegister, noRegister, noRegister, noRegister, noRegister, noRegister, noRegister,
+}
+
 // A regMask encodes a set of machine registers.
 // TODO: regMask -> regSet?
 type regMask uint64
@@ -232,12 +242,6 @@
 	GReg        register
 	allocatable regMask
 
-	// for each block, its primary predecessor.
-	// A predecessor of b is primary if it is the closest
-	// predecessor that appears before b in the layout order.
-	// We record the index in the Preds list where the primary predecessor sits.
-	primary []int32
-
 	// live values at the end of each block.  live[b.ID] is a list of value IDs
 	// which are live at the end of b, together with a count of how many instructions
 	// forward to the next use.
@@ -295,6 +299,12 @@
 
 	// choose a good order in which to visit blocks for allocation purposes.
 	visitOrder []*Block
+
+	// blockOrder[b.ID] corresponds to the index of block b in visitOrder.
+	blockOrder []int32
+
+	// whether to insert instructions that clobber dead registers at call sites
+	doClobber bool
 }
 
 type endReg struct {
@@ -333,6 +343,17 @@
 	}
 }
 
+// clobberRegs inserts instructions that clobber registers listed in m.
+func (s *regAllocState) clobberRegs(m regMask) {
+	m &= s.allocatable & s.f.Config.gpRegMask // only integer register can contain pointers, only clobber them
+	for m != 0 {
+		r := pickReg(m)
+		m &^= 1 << r
+		x := s.curBlock.NewValue0(src.NoXPos, OpClobberReg, types.TypeVoid)
+		s.f.setHome(x, &s.registers[r])
+	}
+}
+
 // setOrig records that c's original value is the same as
 // v's original value.
 func (s *regAllocState) setOrig(c *Value, v *Value) {
@@ -588,7 +609,7 @@
 	if s.f.Config.hasGReg {
 		s.allocatable &^= 1 << s.GReg
 	}
-	if objabi.Framepointer_enabled && s.f.Config.FPReg >= 0 {
+	if buildcfg.FramePointerEnabled && s.f.Config.FPReg >= 0 {
 		s.allocatable &^= 1 << uint(s.f.Config.FPReg)
 	}
 	if s.f.Config.LinkReg != -1 {
@@ -596,12 +617,6 @@
 			// Leaf functions don't save/restore the link register.
 			s.allocatable &^= 1 << uint(s.f.Config.LinkReg)
 		}
-		if s.f.Config.arch == "arm" && objabi.GOARM == 5 {
-			// On ARMv5 we insert softfloat calls at each FP instruction.
-			// This clobbers LR almost everywhere. Disable allocating LR
-			// on ARMv5.
-			s.allocatable &^= 1 << uint(s.f.Config.LinkReg)
-		}
 	}
 	if s.f.Config.ctxt.Flag_dynlink {
 		switch s.f.Config.arch {
@@ -633,9 +648,9 @@
 
 	// Compute block order. This array allows us to distinguish forward edges
 	// from backward edges and compute how far they go.
-	blockOrder := make([]int32, f.NumBlocks())
+	s.blockOrder = make([]int32, f.NumBlocks())
 	for i, b := range s.visitOrder {
-		blockOrder[b.ID] = int32(i)
+		s.blockOrder[b.ID] = int32(i)
 	}
 
 	s.regs = make([]regState, s.numRegs)
@@ -661,22 +676,6 @@
 	}
 	s.computeLive()
 
-	// Compute primary predecessors.
-	s.primary = make([]int32, f.NumBlocks())
-	for _, b := range s.visitOrder {
-		best := -1
-		for i, e := range b.Preds {
-			p := e.b
-			if blockOrder[p.ID] >= blockOrder[b.ID] {
-				continue // backward edge
-			}
-			if best == -1 || blockOrder[p.ID] > blockOrder[b.Preds[best].b.ID] {
-				best = i
-			}
-		}
-		s.primary[b.ID] = int32(best)
-	}
-
 	s.endRegs = make([][]endReg, f.NumBlocks())
 	s.startRegs = make([][]startReg, f.NumBlocks())
 	s.spillLive = make([][]ID, f.NumBlocks())
@@ -716,6 +715,14 @@
 			}
 		}
 	}
+
+	// The clobberdeadreg experiment inserts code to clobber dead registers
+	// at call sites.
+	// Ignore huge functions to avoid doing too much work.
+	if base.Flag.ClobberDeadReg && len(s.f.Blocks) <= 10000 {
+		// TODO: honor GOCLOBBERDEADHASH, or maybe GOSSAHASH.
+		s.doClobber = true
+	}
 }
 
 // Adds a use record for id at distance dist from the start of the block.
@@ -760,6 +767,9 @@
 // current instruction.
 func (s *regAllocState) liveAfterCurrentInstruction(v *Value) bool {
 	u := s.values[v.ID].uses
+	if u == nil {
+		panic(fmt.Errorf("u is nil, v = %s, s.values[v.ID] = %v", v.LongString(), s.values[v.ID]))
+	}
 	d := u.dist
 	for u != nil && u.dist == d {
 		u = u.next
@@ -782,9 +792,9 @@
 		return 0
 	}
 	if t.IsFloat() || t == types.TypeInt128 {
-		if t.Etype == types.TFLOAT32 && s.f.Config.fp32RegMask != 0 {
+		if t.Kind() == types.TFLOAT32 && s.f.Config.fp32RegMask != 0 {
 			m = s.f.Config.fp32RegMask
-		} else if t.Etype == types.TFLOAT64 && s.f.Config.fp64RegMask != 0 {
+		} else if t.Kind() == types.TFLOAT64 && s.f.Config.fp64RegMask != 0 {
 			m = s.f.Config.fp64RegMask
 		} else {
 			m = s.f.Config.fpRegMask
@@ -796,7 +806,8 @@
 }
 
 // regspec returns the regInfo for operation op.
-func (s *regAllocState) regspec(op Op) regInfo {
+func (s *regAllocState) regspec(v *Value) regInfo {
+	op := v.Op
 	if op == OpConvert {
 		// OpConvert is a generic op, so it doesn't have a
 		// register set in the static table. It can use any
@@ -804,6 +815,22 @@
 		m := s.allocatable & s.f.Config.gpRegMask
 		return regInfo{inputs: []inputInfo{{regs: m}}, outputs: []outputInfo{{regs: m}}}
 	}
+	if op == OpArgIntReg {
+		reg := v.Block.Func.Config.intParamRegs[v.AuxInt8()]
+		return regInfo{outputs: []outputInfo{{regs: 1 << uint(reg)}}}
+	}
+	if op == OpArgFloatReg {
+		reg := v.Block.Func.Config.floatParamRegs[v.AuxInt8()]
+		return regInfo{outputs: []outputInfo{{regs: 1 << uint(reg)}}}
+	}
+	if op.IsCall() {
+		if ac, ok := v.Aux.(*AuxCall); ok && ac.reg != nil {
+			return *ac.Reg(&opcodeTable[op].reg, s.f.Config)
+		}
+	}
+	if op == OpMakeResult && s.f.OwnAux.reg != nil {
+		return *s.f.OwnAux.ResultReg(s.f.Config)
+	}
 	return opcodeTable[op].reg
 }
 
@@ -934,10 +961,49 @@
 			// This is the complicated case. We have more than one predecessor,
 			// which means we may have Phi ops.
 
-			// Start with the final register state of the primary predecessor
-			idx := s.primary[b.ID]
+			// Start with the final register state of the predecessor with least spill values.
+			// This is based on the following points:
+			// 1, The less spill value indicates that the register pressure of this path is smaller,
+			//    so the values of this block are more likely to be allocated to registers.
+			// 2, Avoid the predecessor that contains the function call, because the predecessor that
+			//    contains the function call usually generates a lot of spills and lose the previous
+			//    allocation state.
+			// TODO: Improve this part. At least the size of endRegs of the predecessor also has
+			// an impact on the code size and compiler speed. But it is not easy to find a simple
+			// and efficient method that combines multiple factors.
+			idx := -1
+			for i, p := range b.Preds {
+				// If the predecessor has not been visited yet, skip it because its end state
+				// (redRegs and spillLive) has not been computed yet.
+				pb := p.b
+				if s.blockOrder[pb.ID] >= s.blockOrder[b.ID] {
+					continue
+				}
+				if idx == -1 {
+					idx = i
+					continue
+				}
+				pSel := b.Preds[idx].b
+				if len(s.spillLive[pb.ID]) < len(s.spillLive[pSel.ID]) {
+					idx = i
+				} else if len(s.spillLive[pb.ID]) == len(s.spillLive[pSel.ID]) {
+					// Use a bit of likely information. After critical pass, pb and pSel must
+					// be plain blocks, so check edge pb->pb.Preds instead of edge pb->b.
+					// TODO: improve the prediction of the likely predecessor. The following
+					// method is only suitable for the simplest cases. For complex cases,
+					// the prediction may be inaccurate, but this does not affect the
+					// correctness of the program.
+					// According to the layout algorithm, the predecessor with the
+					// smaller blockOrder is the true branch, and the test results show
+					// that it is better to choose the predecessor with a smaller
+					// blockOrder than no choice.
+					if pb.likelyBranch() && !pSel.likelyBranch() || s.blockOrder[pb.ID] < s.blockOrder[pSel.ID] {
+						idx = i
+					}
+				}
+			}
 			if idx < 0 {
-				f.Fatalf("block with no primary predecessor %s", b)
+				f.Fatalf("bad visitOrder, no predecessor of %s has been visited before it", b)
 			}
 			p := b.Preds[idx].b
 			s.setState(s.endRegs[p.ID])
@@ -1025,7 +1091,7 @@
 				// If one of the other inputs of v is in a register, and the register is available,
 				// select this register, which can save some unnecessary copies.
 				for i, pe := range b.Preds {
-					if int32(i) == idx {
+					if i == idx {
 						continue
 					}
 					ri := noRegister
@@ -1159,7 +1225,7 @@
 		for i := len(oldSched) - 1; i >= 0; i-- {
 			v := oldSched[i]
 			prefs := desired.remove(v.ID)
-			regspec := s.regspec(v.Op)
+			regspec := s.regspec(v)
 			desired.clobber(regspec.clobbers)
 			for _, j := range regspec.inputs {
 				if countRegs(j.regs) != 1 {
@@ -1189,7 +1255,7 @@
 			if s.f.pass.debug > regDebug {
 				fmt.Printf("  processing %s\n", v.LongString())
 			}
-			regspec := s.regspec(v.Op)
+			regspec := s.regspec(v)
 			if v.Op == OpPhi {
 				f.Fatalf("phi %s not at start of block", v)
 			}
@@ -1207,13 +1273,17 @@
 				s.sb = v.ID
 				continue
 			}
-			if v.Op == OpSelect0 || v.Op == OpSelect1 {
+			if v.Op == OpSelect0 || v.Op == OpSelect1 || v.Op == OpSelectN {
 				if s.values[v.ID].needReg {
-					var i = 0
-					if v.Op == OpSelect1 {
-						i = 1
+					if v.Op == OpSelectN {
+						s.assignReg(register(s.f.getHome(v.Args[0].ID).(LocResults)[int(v.AuxInt)].(*Register).num), v, v)
+					} else {
+						var i = 0
+						if v.Op == OpSelect1 {
+							i = 1
+						}
+						s.assignReg(register(s.f.getHome(v.Args[0].ID).(LocPair)[i].(*Register).num), v, v)
 					}
-					s.assignReg(register(s.f.getHome(v.Args[0].ID).(LocPair)[i].(*Register).num), v, v)
 				}
 				b.Values = append(b.Values, v)
 				s.advanceUses(v)
@@ -1248,7 +1318,7 @@
 					// This forces later liveness analysis to make the
 					// value live at this point.
 					v.SetArg(0, s.makeSpill(a, b))
-				} else if _, ok := a.Aux.(GCNode); ok && vi.rematerializeable {
+				} else if _, ok := a.Aux.(*ir.Name); ok && vi.rematerializeable {
 					// Rematerializeable value with a gc.Node. This is the address of
 					// a stack object (e.g. an LEAQ). Keep the object live.
 					// Change it to VarLive, which is what plive expects for locals.
@@ -1267,6 +1337,9 @@
 			}
 			if len(regspec.inputs) == 0 && len(regspec.outputs) == 0 {
 				// No register allocation required (or none specified yet)
+				if s.doClobber && v.Op.IsCall() {
+					s.clobberRegs(regspec.clobbers)
+				}
 				s.freeRegs(regspec.clobbers)
 				b.Values = append(b.Values, v)
 				s.advanceUses(v)
@@ -1304,12 +1377,58 @@
 				}
 			}
 
-			// Move arguments to registers. Process in an ordering defined
-			// by the register specification (most constrained first).
-			args = append(args[:0], v.Args...)
+			// Move arguments to registers.
+			// First, if an arg must be in a specific register and it is already
+			// in place, keep it.
+			args = append(args[:0], make([]*Value, len(v.Args))...)
+			for i, a := range v.Args {
+				if !s.values[a.ID].needReg {
+					args[i] = a
+				}
+			}
 			for _, i := range regspec.inputs {
 				mask := i.regs
-				if mask&s.values[args[i.idx].ID].regs == 0 {
+				if countRegs(mask) == 1 && mask&s.values[v.Args[i.idx].ID].regs != 0 {
+					args[i.idx] = s.allocValToReg(v.Args[i.idx], mask, true, v.Pos)
+				}
+			}
+			// Then, if an arg must be in a specific register and that
+			// register is free, allocate that one. Otherwise when processing
+			// another input we may kick a value into the free register, which
+			// then will be kicked out again.
+			// This is a common case for passing-in-register arguments for
+			// function calls.
+			for {
+				freed := false
+				for _, i := range regspec.inputs {
+					if args[i.idx] != nil {
+						continue // already allocated
+					}
+					mask := i.regs
+					if countRegs(mask) == 1 && mask&^s.used != 0 {
+						args[i.idx] = s.allocValToReg(v.Args[i.idx], mask, true, v.Pos)
+						// If the input is in other registers that will be clobbered by v,
+						// or the input is dead, free the registers. This may make room
+						// for other inputs.
+						oldregs := s.values[v.Args[i.idx].ID].regs
+						if oldregs&^regspec.clobbers == 0 || !s.liveAfterCurrentInstruction(v.Args[i.idx]) {
+							s.freeRegs(oldregs &^ mask &^ s.nospill)
+							freed = true
+						}
+					}
+				}
+				if !freed {
+					break
+				}
+			}
+			// Last, allocate remaining ones, in an ordering defined
+			// by the register specification (most constrained first).
+			for _, i := range regspec.inputs {
+				if args[i.idx] != nil {
+					continue // already allocated
+				}
+				mask := i.regs
+				if mask&s.values[v.Args[i.idx].ID].regs == 0 {
 					// Need a new register for the input.
 					mask &= s.allocatable
 					mask &^= s.nospill
@@ -1328,7 +1447,7 @@
 						mask &^= desired.avoid
 					}
 				}
-				args[i.idx] = s.allocValToReg(args[i.idx], mask, true, v.Pos)
+				args[i.idx] = s.allocValToReg(v.Args[i.idx], mask, true, v.Pos)
 			}
 
 			// If the output clobbers the input register, make sure we have
@@ -1374,9 +1493,9 @@
 					goto ok
 				}
 
-				// Try to move an input to the desired output.
+				// Try to move an input to the desired output, if allowed.
 				for _, r := range dinfo[idx].out {
-					if r != noRegister && m>>r&1 != 0 {
+					if r != noRegister && (m&regspec.outputs[0].regs)>>r&1 != 0 {
 						m = regMask(1) << r
 						args[0] = s.allocValToReg(v.Args[0], m, true, v.Pos)
 						// Note: we update args[0] so the instruction will
@@ -1428,12 +1547,18 @@
 			}
 
 			// Dump any registers which will be clobbered
+			if s.doClobber && v.Op.IsCall() {
+				// clobber registers that are marked as clobber in regmask, but
+				// don't clobber inputs.
+				s.clobberRegs(regspec.clobbers &^ s.tmpused &^ s.nospill)
+			}
 			s.freeRegs(regspec.clobbers)
 			s.tmpused |= regspec.clobbers
 
 			// Pick registers for outputs.
 			{
-				outRegs := [2]register{noRegister, noRegister}
+				outRegs := noRegisters // TODO if this is costly, hoist and clear incrementally below.
+				maxOutIdx := -1
 				var used regMask
 				for _, out := range regspec.outputs {
 					mask := out.regs & s.allocatable &^ used
@@ -1444,6 +1569,9 @@
 						if !opcodeTable[v.Op].commutative {
 							// Output must use the same register as input 0.
 							r := register(s.f.getHome(args[0].ID).(*Register).num)
+							if mask>>r&1 == 0 {
+								s.f.Fatalf("resultInArg0 value's input %v cannot be an output of %s", s.f.getHome(args[0].ID).(*Register), v.LongString())
+							}
 							mask = regMask(1) << r
 						} else {
 							// Output must use the same register as input 0 or 1.
@@ -1479,6 +1607,9 @@
 						mask &^= desired.avoid
 					}
 					r := s.allocReg(mask, v)
+					if out.idx > maxOutIdx {
+						maxOutIdx = out.idx
+					}
 					outRegs[out.idx] = r
 					used |= regMask(1) << r
 					s.tmpused |= regMask(1) << r
@@ -1494,6 +1625,15 @@
 					}
 					s.f.setHome(v, outLocs)
 					// Note that subsequent SelectX instructions will do the assignReg calls.
+				} else if v.Type.IsResults() {
+					// preallocate outLocs to the right size, which is maxOutIdx+1
+					outLocs := make(LocResults, maxOutIdx+1, maxOutIdx+1)
+					for i := 0; i <= maxOutIdx; i++ {
+						if r := outRegs[i]; r != noRegister {
+							outLocs[i] = &s.registers[r]
+						}
+					}
+					s.f.setHome(v, outLocs)
 				} else {
 					if r := outRegs[0]; r != noRegister {
 						s.assignReg(r, v, v)
@@ -1742,6 +1882,10 @@
 		phiRegs[b.ID] = m
 	}
 
+	mustBeFirst := func(op Op) bool {
+		return op.isLoweredGetClosurePtr() || op == OpPhi || op == OpArgIntReg || op == OpArgFloatReg
+	}
+
 	// Start maps block IDs to the list of spills
 	// that go at the start of the block (but after any phis).
 	start := map[ID][]*Value{}
@@ -1766,6 +1910,9 @@
 		// put the spill of v.  At the start "best" is the best place
 		// we have found so far.
 		// TODO: find a way to make this O(1) without arbitrary cutoffs.
+		if v == nil {
+			panic(fmt.Errorf("nil v, s.orig[%d], vi = %v, spill = %s", i, vi, spill.LongString()))
+		}
 		best := v.Block
 		bestArg := v
 		var bestDepth int16
@@ -1828,7 +1975,7 @@
 		// Put the spill in the best block we found.
 		spill.Block = best
 		spill.AddArg(bestArg)
-		if best == v.Block && v.Op != OpPhi {
+		if best == v.Block && !mustBeFirst(v.Op) {
 			// Place immediately after v.
 			after[v.ID] = append(after[v.ID], spill)
 		} else {
@@ -1840,15 +1987,15 @@
 	// Insert spill instructions into the block schedules.
 	var oldSched []*Value
 	for _, b := range s.visitOrder {
-		nphi := 0
+		nfirst := 0
 		for _, v := range b.Values {
-			if v.Op != OpPhi {
+			if !mustBeFirst(v.Op) {
 				break
 			}
-			nphi++
+			nfirst++
 		}
-		oldSched = append(oldSched[:0], b.Values[nphi:]...)
-		b.Values = b.Values[:nphi]
+		oldSched = append(oldSched[:0], b.Values[nfirst:]...)
+		b.Values = b.Values[:nfirst]
 		b.Values = append(b.Values, start[b.ID]...)
 		for _, v := range oldSched {
 			b.Values = append(b.Values, v)
@@ -2436,7 +2583,7 @@
 					// desired registers back though phi nodes.
 					continue
 				}
-				regspec := s.regspec(v.Op)
+				regspec := s.regspec(v)
 				// Cancel desired registers if they get clobbered.
 				desired.clobber(regspec.clobbers)
 				// Update desired registers if there are any fixed register inputs.
diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go
index f5d1a78..375c4d5 100644
--- a/src/cmd/compile/internal/ssa/rewrite.go
+++ b/src/cmd/compile/internal/ssa/rewrite.go
@@ -27,7 +27,7 @@
 	removeDeadValues                 = true
 )
 
-// deadcode indicates that rewrite should try to remove any values that become dead.
+// deadcode indicates whether rewrite should try to remove any values that become dead.
 func applyRewrite(f *Func, rb blockRewriter, rv valueRewriter, deadcode deadValueChoice) {
 	// repeat rewrites until we find no more rewrites
 	pendingLines := f.cachedLineStarts // Holds statement boundaries that need to be moved to a new value/block
@@ -159,7 +159,7 @@
 				f.freeValue(v)
 				continue
 			}
-			if v.Pos.IsStmt() != src.PosNotStmt && pendingLines.get(vl) == int32(b.ID) {
+			if v.Pos.IsStmt() != src.PosNotStmt && !notStmtBoundary(v.Op) && pendingLines.get(vl) == int32(b.ID) {
 				pendingLines.remove(vl)
 				v.Pos = v.Pos.WithIsStmt()
 			}
@@ -521,6 +521,18 @@
 	return v.AuxInt != 0
 }
 
+// canonLessThan returns whether x is "ordered" less than y, for purposes of normalizing
+// generated code as much as possible.
+func canonLessThan(x, y *Value) bool {
+	if x.Op != y.Op {
+		return x.Op < y.Op
+	}
+	if !x.Pos.SameFileAndLine(y.Pos) {
+		return x.Pos.Before(y.Pos)
+	}
+	return x.ID < y.ID
+}
+
 // truncate64Fto32F converts a float64 value to a float32 preserving the bit pattern
 // of the mantissa. It will panic if the truncation results in lost information.
 func truncate64Fto32F(f float64) float32 {
@@ -678,43 +690,53 @@
 	return int64(o)
 }
 
-func auxToString(i interface{}) string {
-	return i.(string)
+// Aux is an interface to hold miscellaneous data in Blocks and Values.
+type Aux interface {
+	CanBeAnSSAAux()
 }
-func auxToSym(i interface{}) Sym {
+
+// stringAux wraps string values for use in Aux.
+type stringAux string
+
+func (stringAux) CanBeAnSSAAux() {}
+
+func auxToString(i Aux) string {
+	return string(i.(stringAux))
+}
+func auxToSym(i Aux) Sym {
 	// TODO: kind of a hack - allows nil interface through
 	s, _ := i.(Sym)
 	return s
 }
-func auxToType(i interface{}) *types.Type {
+func auxToType(i Aux) *types.Type {
 	return i.(*types.Type)
 }
-func auxToCall(i interface{}) *AuxCall {
+func auxToCall(i Aux) *AuxCall {
 	return i.(*AuxCall)
 }
-func auxToS390xCCMask(i interface{}) s390x.CCMask {
+func auxToS390xCCMask(i Aux) s390x.CCMask {
 	return i.(s390x.CCMask)
 }
-func auxToS390xRotateParams(i interface{}) s390x.RotateParams {
+func auxToS390xRotateParams(i Aux) s390x.RotateParams {
 	return i.(s390x.RotateParams)
 }
 
-func stringToAux(s string) interface{} {
+func StringToAux(s string) Aux {
+	return stringAux(s)
+}
+func symToAux(s Sym) Aux {
 	return s
 }
-func symToAux(s Sym) interface{} {
+func callToAux(s *AuxCall) Aux {
 	return s
 }
-func callToAux(s *AuxCall) interface{} {
-	return s
-}
-func typeToAux(t *types.Type) interface{} {
+func typeToAux(t *types.Type) Aux {
 	return t
 }
-func s390xCCMaskToAux(c s390x.CCMask) interface{} {
+func s390xCCMaskToAux(c s390x.CCMask) Aux {
 	return c
 }
-func s390xRotateParamsToAux(r s390x.RotateParams) interface{} {
+func s390xRotateParamsToAux(r s390x.RotateParams) Aux {
 	return r
 }
 
@@ -725,7 +747,7 @@
 
 // de-virtualize an InterCall
 // 'sym' is the symbol for the itab
-func devirt(v *Value, aux interface{}, sym Sym, offset int64) *AuxCall {
+func devirt(v *Value, aux Aux, sym Sym, offset int64) *AuxCall {
 	f := v.Block.Func
 	n, ok := sym.(*obj.LSym)
 	if !ok {
@@ -743,12 +765,12 @@
 		return nil
 	}
 	va := aux.(*AuxCall)
-	return StaticAuxCall(lsym, va.args, va.results)
+	return StaticAuxCall(lsym, va.abiInfo)
 }
 
 // de-virtualize an InterLECall
 // 'sym' is the symbol for the itab
-func devirtLESym(v *Value, aux interface{}, sym Sym, offset int64) *obj.LSym {
+func devirtLESym(v *Value, aux Aux, sym Sym, offset int64) *obj.LSym {
 	n, ok := sym.(*obj.LSym)
 	if !ok {
 		return nil
@@ -771,7 +793,8 @@
 
 func devirtLECall(v *Value, sym *obj.LSym) *Value {
 	v.Op = OpStaticLECall
-	v.Aux.(*AuxCall).Fn = sym
+	auxcall := v.Aux.(*AuxCall)
+	auxcall.Fn = sym
 	v.RemoveArg(0)
 	return v
 }
@@ -836,13 +859,13 @@
 		if p2.Op == OpAddr || p2.Op == OpLocalAddr || p2.Op == OpSP {
 			return true
 		}
-		return p2.Op == OpArg && p1.Args[0].Op == OpSP
-	case OpArg:
+		return (p2.Op == OpArg || p2.Op == OpArgIntReg) && p1.Args[0].Op == OpSP
+	case OpArg, OpArgIntReg:
 		if p2.Op == OpSP || p2.Op == OpLocalAddr {
 			return true
 		}
 	case OpSP:
-		return p2.Op == OpAddr || p2.Op == OpLocalAddr || p2.Op == OpArg || p2.Op == OpSP
+		return p2.Op == OpAddr || p2.Op == OpLocalAddr || p2.Op == OpArg || p2.Op == OpArgIntReg || p2.Op == OpSP
 	}
 	return false
 }
@@ -1391,7 +1414,7 @@
 	return (v&vp == 0 || vn&vpn == 0) && v != 0
 }
 
-// Compress mask and and shift into single value of the form
+// Compress mask and shift into single value of the form
 // me | mb<<8 | rotate<<16 | nbits<<24 where me and mb can
 // be used to regenerate the input mask.
 func encodePPC64RotateMask(rotate, mask, nbits int64) int64 {
@@ -1469,7 +1492,7 @@
 	if !isPPC64WordRotateMask(mask) {
 		return 0
 	}
-	return encodePPC64RotateMask(32-s, mask, 32)
+	return encodePPC64RotateMask((32-s)&31, mask, 32)
 }
 
 // Test if a shift right feeding into a CLRLSLDI can be merged into RLWINM.
@@ -1589,18 +1612,18 @@
 	if !f.Config.Race {
 		return false
 	}
-	if !isSameCall(sym, "runtime.racefuncenter") && !isSameCall(sym, "runtime.racefuncenterfp") && !isSameCall(sym, "runtime.racefuncexit") {
+	if !isSameCall(sym, "runtime.racefuncenter") && !isSameCall(sym, "runtime.racefuncexit") {
 		return false
 	}
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
 			switch v.Op {
-			case OpStaticCall:
-				// Check for racefuncenter/racefuncenterfp will encounter racefuncexit and vice versa.
+			case OpStaticCall, OpStaticLECall:
+				// Check for racefuncenter will encounter racefuncexit and vice versa.
 				// Allow calls to panic*
 				s := v.Aux.(*AuxCall).Fn.String()
 				switch s {
-				case "runtime.racefuncenter", "runtime.racefuncenterfp", "runtime.racefuncexit",
+				case "runtime.racefuncenter", "runtime.racefuncexit",
 					"runtime.panicdivide", "runtime.panicwrap",
 					"runtime.panicshift":
 					continue
@@ -1610,15 +1633,20 @@
 				return false
 			case OpPanicBounds, OpPanicExtend:
 				// Note: these are panic generators that are ok (like the static calls above).
-			case OpClosureCall, OpInterCall:
+			case OpClosureCall, OpInterCall, OpClosureLECall, OpInterLECall:
 				// We must keep the race functions if there are any other call types.
 				return false
 			}
 		}
 	}
 	if isSameCall(sym, "runtime.racefuncenter") {
+		// TODO REGISTER ABI this needs to be cleaned up.
 		// If we're removing racefuncenter, remove its argument as well.
 		if v.Args[0].Op != OpStore {
+			if v.Op == OpStaticLECall {
+				// there is no store, yet.
+				return true
+			}
 			return false
 		}
 		mem := v.Args[0].Args[2]
diff --git a/src/cmd/compile/internal/ssa/rewrite386.go b/src/cmd/compile/internal/ssa/rewrite386.go
index 2acdccd..1ec2d26 100644
--- a/src/cmd/compile/internal/ssa/rewrite386.go
+++ b/src/cmd/compile/internal/ssa/rewrite386.go
@@ -620,6 +620,9 @@
 	case OpSqrt:
 		v.Op = Op386SQRTSD
 		return true
+	case OpSqrt32:
+		v.Op = Op386SQRTSS
+		return true
 	case OpStaticCall:
 		v.Op = Op386CALLstatic
 		return true
@@ -1785,12 +1788,12 @@
 		return true
 	}
 	// match: (CMPB x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPB y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(Op386InvertFlags)
@@ -1993,8 +1996,8 @@
 		return true
 	}
 	// match: (CMPBconst l:(MOVBload {sym} [off] ptr mem) [c])
-	// cond: l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l)
-	// result: @l.Block (CMPBconstload {sym} [makeValAndOff32(int32(c),int32(off))] ptr mem)
+	// cond: l.Uses == 1 && clobber(l)
+	// result: @l.Block (CMPBconstload {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		c := auxIntToInt8(v.AuxInt)
 		l := v_0
@@ -2005,13 +2008,13 @@
 		sym := auxToSym(l.Aux)
 		mem := l.Args[1]
 		ptr := l.Args[0]
-		if !(l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l)) {
+		if !(l.Uses == 1 && clobber(l)) {
 			break
 		}
 		b = l.Block
 		v0 := b.NewValue0(l.Pos, Op386CMPBconstload, types.TypeFlags)
 		v.copyOf(v0)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), int32(off)))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		return true
@@ -2023,8 +2026,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (CMPBload {sym} [off] ptr (MOVLconst [c]) mem)
-	// cond: validValAndOff(int64(int8(c)),int64(off))
-	// result: (CMPBconstload {sym} [makeValAndOff32(int32(int8(c)),off)] ptr mem)
+	// result: (CMPBconstload {sym} [makeValAndOff(int32(int8(c)),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -2034,11 +2036,8 @@
 		}
 		c := auxIntToInt32(v_1.AuxInt)
 		mem := v_2
-		if !(validValAndOff(int64(int8(c)), int64(off))) {
-			break
-		}
 		v.reset(Op386CMPBconstload)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(int8(c)), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(int8(c)), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -2078,12 +2077,12 @@
 		return true
 	}
 	// match: (CMPL x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPL y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(Op386InvertFlags)
@@ -2301,8 +2300,8 @@
 		return true
 	}
 	// match: (CMPLconst l:(MOVLload {sym} [off] ptr mem) [c])
-	// cond: l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l)
-	// result: @l.Block (CMPLconstload {sym} [makeValAndOff32(int32(c),int32(off))] ptr mem)
+	// cond: l.Uses == 1 && clobber(l)
+	// result: @l.Block (CMPLconstload {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		c := auxIntToInt32(v.AuxInt)
 		l := v_0
@@ -2313,13 +2312,13 @@
 		sym := auxToSym(l.Aux)
 		mem := l.Args[1]
 		ptr := l.Args[0]
-		if !(l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l)) {
+		if !(l.Uses == 1 && clobber(l)) {
 			break
 		}
 		b = l.Block
 		v0 := b.NewValue0(l.Pos, Op386CMPLconstload, types.TypeFlags)
 		v.copyOf(v0)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), int32(off)))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		return true
@@ -2331,8 +2330,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (CMPLload {sym} [off] ptr (MOVLconst [c]) mem)
-	// cond: validValAndOff(int64(c),int64(off))
-	// result: (CMPLconstload {sym} [makeValAndOff32(c,off)] ptr mem)
+	// result: (CMPLconstload {sym} [makeValAndOff(c,off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -2342,11 +2340,8 @@
 		}
 		c := auxIntToInt32(v_1.AuxInt)
 		mem := v_2
-		if !(validValAndOff(int64(c), int64(off))) {
-			break
-		}
 		v.reset(Op386CMPLconstload)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(c, off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(c, off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -2386,12 +2381,12 @@
 		return true
 	}
 	// match: (CMPW x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPW y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(Op386InvertFlags)
@@ -2594,8 +2589,8 @@
 		return true
 	}
 	// match: (CMPWconst l:(MOVWload {sym} [off] ptr mem) [c])
-	// cond: l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l)
-	// result: @l.Block (CMPWconstload {sym} [makeValAndOff32(int32(c),int32(off))] ptr mem)
+	// cond: l.Uses == 1 && clobber(l)
+	// result: @l.Block (CMPWconstload {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		c := auxIntToInt16(v.AuxInt)
 		l := v_0
@@ -2606,13 +2601,13 @@
 		sym := auxToSym(l.Aux)
 		mem := l.Args[1]
 		ptr := l.Args[0]
-		if !(l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l)) {
+		if !(l.Uses == 1 && clobber(l)) {
 			break
 		}
 		b = l.Block
 		v0 := b.NewValue0(l.Pos, Op386CMPWconstload, types.TypeFlags)
 		v.copyOf(v0)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), int32(off)))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		return true
@@ -2624,8 +2619,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (CMPWload {sym} [off] ptr (MOVLconst [c]) mem)
-	// cond: validValAndOff(int64(int16(c)),int64(off))
-	// result: (CMPWconstload {sym} [makeValAndOff32(int32(int16(c)),off)] ptr mem)
+	// result: (CMPWconstload {sym} [makeValAndOff(int32(int16(c)),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -2635,11 +2629,8 @@
 		}
 		c := auxIntToInt32(v_1.AuxInt)
 		mem := v_2
-		if !(validValAndOff(int64(int16(c)), int64(off))) {
-			break
-		}
 		v.reset(Op386CMPWconstload)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(int16(c)), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(int16(c)), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -3732,8 +3723,7 @@
 		return true
 	}
 	// match: (MOVBstore [off] {sym} ptr (MOVLconst [c]) mem)
-	// cond: validOff(int64(off))
-	// result: (MOVBstoreconst [makeValAndOff32(c,off)] {sym} ptr mem)
+	// result: (MOVBstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -3743,11 +3733,8 @@
 		}
 		c := auxIntToInt32(v_1.AuxInt)
 		mem := v_2
-		if !(validOff(int64(off))) {
-			break
-		}
 		v.reset(Op386MOVBstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(c, off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(c, off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -4087,7 +4074,7 @@
 	}
 	// match: (MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
 	// cond: x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x)
-	// result: (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p mem)
+	// result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -4105,14 +4092,14 @@
 			break
 		}
 		v.reset(Op386MOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xff|c.Val()<<8), a.Off32()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p, mem)
 		return true
 	}
 	// match: (MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem))
 	// cond: x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x)
-	// result: (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p mem)
+	// result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
 	for {
 		a := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -4130,14 +4117,14 @@
 			break
 		}
 		v.reset(Op386MOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xff|c.Val()<<8), a.Off32()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p, mem)
 		return true
 	}
 	// match: (MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem))
 	// cond: x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 1) && clobber(x)
-	// result: (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p0 mem)
+	// result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -4156,14 +4143,14 @@
 			break
 		}
 		v.reset(Op386MOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xff|c.Val()<<8), a.Off32()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p0, mem)
 		return true
 	}
 	// match: (MOVBstoreconst [a] {s} p0 x:(MOVBstoreconst [c] {s} p1 mem))
 	// cond: x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 1) && clobber(x)
-	// result: (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p0 mem)
+	// result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
 	for {
 		a := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -4182,7 +4169,7 @@
 			break
 		}
 		v.reset(Op386MOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xff|c.Val()<<8), a.Off32()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p0, mem)
 		return true
@@ -4301,8 +4288,7 @@
 		return true
 	}
 	// match: (MOVLstore [off] {sym} ptr (MOVLconst [c]) mem)
-	// cond: validOff(int64(off))
-	// result: (MOVLstoreconst [makeValAndOff32(c,off)] {sym} ptr mem)
+	// result: (MOVLstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -4312,11 +4298,8 @@
 		}
 		c := auxIntToInt32(v_1.AuxInt)
 		mem := v_2
-		if !(validOff(int64(off))) {
-			break
-		}
 		v.reset(Op386MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(c, off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(c, off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -4599,8 +4582,8 @@
 		break
 	}
 	// match: (MOVLstore {sym} [off] ptr y:(ADDLconst [c] l:(MOVLload [off] {sym} ptr mem)) mem)
-	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l) && validValAndOff(int64(c),int64(off))
-	// result: (ADDLconstmodify [makeValAndOff32(c,off)] {sym} ptr mem)
+	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l)
+	// result: (ADDLconstmodify [makeValAndOff(c,off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -4615,18 +4598,18 @@
 			break
 		}
 		mem := l.Args[1]
-		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l) && validValAndOff(int64(c), int64(off))) {
+		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l)) {
 			break
 		}
 		v.reset(Op386ADDLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(c, off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(c, off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
 	}
 	// match: (MOVLstore {sym} [off] ptr y:(ANDLconst [c] l:(MOVLload [off] {sym} ptr mem)) mem)
-	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l) && validValAndOff(int64(c),int64(off))
-	// result: (ANDLconstmodify [makeValAndOff32(c,off)] {sym} ptr mem)
+	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l)
+	// result: (ANDLconstmodify [makeValAndOff(c,off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -4641,18 +4624,18 @@
 			break
 		}
 		mem := l.Args[1]
-		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l) && validValAndOff(int64(c), int64(off))) {
+		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l)) {
 			break
 		}
 		v.reset(Op386ANDLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(c, off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(c, off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
 	}
 	// match: (MOVLstore {sym} [off] ptr y:(ORLconst [c] l:(MOVLload [off] {sym} ptr mem)) mem)
-	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l) && validValAndOff(int64(c),int64(off))
-	// result: (ORLconstmodify [makeValAndOff32(c,off)] {sym} ptr mem)
+	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l)
+	// result: (ORLconstmodify [makeValAndOff(c,off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -4667,18 +4650,18 @@
 			break
 		}
 		mem := l.Args[1]
-		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l) && validValAndOff(int64(c), int64(off))) {
+		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l)) {
 			break
 		}
 		v.reset(Op386ORLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(c, off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(c, off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
 	}
 	// match: (MOVLstore {sym} [off] ptr y:(XORLconst [c] l:(MOVLload [off] {sym} ptr mem)) mem)
-	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l) && validValAndOff(int64(c),int64(off))
-	// result: (XORLconstmodify [makeValAndOff32(c,off)] {sym} ptr mem)
+	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l)
+	// result: (XORLconstmodify [makeValAndOff(c,off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -4693,11 +4676,11 @@
 			break
 		}
 		mem := l.Args[1]
-		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l) && validValAndOff(int64(c), int64(off))) {
+		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l)) {
 			break
 		}
 		v.reset(Op386XORLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(c, off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(c, off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -5283,8 +5266,7 @@
 		return true
 	}
 	// match: (MOVWstore [off] {sym} ptr (MOVLconst [c]) mem)
-	// cond: validOff(int64(off))
-	// result: (MOVWstoreconst [makeValAndOff32(c,off)] {sym} ptr mem)
+	// result: (MOVWstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -5294,11 +5276,8 @@
 		}
 		c := auxIntToInt32(v_1.AuxInt)
 		mem := v_2
-		if !(validOff(int64(off))) {
-			break
-		}
 		v.reset(Op386MOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(c, off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(c, off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -5487,7 +5466,7 @@
 	}
 	// match: (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
 	// cond: x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x)
-	// result: (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p mem)
+	// result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -5505,14 +5484,14 @@
 			break
 		}
 		v.reset(Op386MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xffff|c.Val()<<16), a.Off32()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p, mem)
 		return true
 	}
 	// match: (MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem))
 	// cond: x.Uses == 1 && ValAndOff(a).Off() + 2 == ValAndOff(c).Off() && clobber(x)
-	// result: (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p mem)
+	// result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
 	for {
 		a := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -5530,14 +5509,14 @@
 			break
 		}
 		v.reset(Op386MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xffff|c.Val()<<16), a.Off32()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p, mem)
 		return true
 	}
 	// match: (MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem))
 	// cond: x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 2) && clobber(x)
-	// result: (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p0 mem)
+	// result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -5556,14 +5535,14 @@
 			break
 		}
 		v.reset(Op386MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xffff|c.Val()<<16), a.Off32()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p0, mem)
 		return true
 	}
 	// match: (MOVWstoreconst [a] {s} p0 x:(MOVWstoreconst [c] {s} p1 mem))
 	// cond: x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 2) && clobber(x)
-	// result: (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p0 mem)
+	// result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
 	for {
 		a := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -5582,7 +5561,7 @@
 			break
 		}
 		v.reset(Op386MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xffff|c.Val()<<16), a.Off32()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p0, mem)
 		return true
@@ -11571,7 +11550,7 @@
 		return true
 	}
 	// match: (Zero [3] destptr mem)
-	// result: (MOVBstoreconst [makeValAndOff32(0,2)] destptr (MOVWstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (MOVBstoreconst [makeValAndOff(0,2)] destptr (MOVWstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 3 {
 			break
@@ -11579,15 +11558,15 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(Op386MOVBstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 2))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 2))
 		v0 := b.NewValue0(v.Pos, Op386MOVWstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v0.AddArg2(destptr, mem)
 		v.AddArg2(destptr, v0)
 		return true
 	}
 	// match: (Zero [5] destptr mem)
-	// result: (MOVBstoreconst [makeValAndOff32(0,4)] destptr (MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (MOVBstoreconst [makeValAndOff(0,4)] destptr (MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 5 {
 			break
@@ -11595,15 +11574,15 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(Op386MOVBstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 4))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 4))
 		v0 := b.NewValue0(v.Pos, Op386MOVLstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v0.AddArg2(destptr, mem)
 		v.AddArg2(destptr, v0)
 		return true
 	}
 	// match: (Zero [6] destptr mem)
-	// result: (MOVWstoreconst [makeValAndOff32(0,4)] destptr (MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (MOVWstoreconst [makeValAndOff(0,4)] destptr (MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 6 {
 			break
@@ -11611,15 +11590,15 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(Op386MOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 4))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 4))
 		v0 := b.NewValue0(v.Pos, Op386MOVLstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v0.AddArg2(destptr, mem)
 		v.AddArg2(destptr, v0)
 		return true
 	}
 	// match: (Zero [7] destptr mem)
-	// result: (MOVLstoreconst [makeValAndOff32(0,3)] destptr (MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (MOVLstoreconst [makeValAndOff(0,3)] destptr (MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 7 {
 			break
@@ -11627,9 +11606,9 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(Op386MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 3))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 3))
 		v0 := b.NewValue0(v.Pos, Op386MOVLstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v0.AddArg2(destptr, mem)
 		v.AddArg2(destptr, v0)
 		return true
@@ -11656,7 +11635,7 @@
 		return true
 	}
 	// match: (Zero [8] destptr mem)
-	// result: (MOVLstoreconst [makeValAndOff32(0,4)] destptr (MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (MOVLstoreconst [makeValAndOff(0,4)] destptr (MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 8 {
 			break
@@ -11664,15 +11643,15 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(Op386MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 4))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 4))
 		v0 := b.NewValue0(v.Pos, Op386MOVLstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v0.AddArg2(destptr, mem)
 		v.AddArg2(destptr, v0)
 		return true
 	}
 	// match: (Zero [12] destptr mem)
-	// result: (MOVLstoreconst [makeValAndOff32(0,8)] destptr (MOVLstoreconst [makeValAndOff32(0,4)] destptr (MOVLstoreconst [makeValAndOff32(0,0)] destptr mem)))
+	// result: (MOVLstoreconst [makeValAndOff(0,8)] destptr (MOVLstoreconst [makeValAndOff(0,4)] destptr (MOVLstoreconst [makeValAndOff(0,0)] destptr mem)))
 	for {
 		if auxIntToInt64(v.AuxInt) != 12 {
 			break
@@ -11680,18 +11659,18 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(Op386MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 8))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 8))
 		v0 := b.NewValue0(v.Pos, Op386MOVLstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 4))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 4))
 		v1 := b.NewValue0(v.Pos, Op386MOVLstoreconst, types.TypeMem)
-		v1.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v1.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v1.AddArg2(destptr, mem)
 		v0.AddArg2(destptr, v1)
 		v.AddArg2(destptr, v0)
 		return true
 	}
 	// match: (Zero [16] destptr mem)
-	// result: (MOVLstoreconst [makeValAndOff32(0,12)] destptr (MOVLstoreconst [makeValAndOff32(0,8)] destptr (MOVLstoreconst [makeValAndOff32(0,4)] destptr (MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))))
+	// result: (MOVLstoreconst [makeValAndOff(0,12)] destptr (MOVLstoreconst [makeValAndOff(0,8)] destptr (MOVLstoreconst [makeValAndOff(0,4)] destptr (MOVLstoreconst [makeValAndOff(0,0)] destptr mem))))
 	for {
 		if auxIntToInt64(v.AuxInt) != 16 {
 			break
@@ -11699,13 +11678,13 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(Op386MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 12))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 12))
 		v0 := b.NewValue0(v.Pos, Op386MOVLstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 8))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 8))
 		v1 := b.NewValue0(v.Pos, Op386MOVLstoreconst, types.TypeMem)
-		v1.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 4))
+		v1.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 4))
 		v2 := b.NewValue0(v.Pos, Op386MOVLstoreconst, types.TypeMem)
-		v2.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v2.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v2.AddArg2(destptr, mem)
 		v1.AddArg2(destptr, v2)
 		v0.AddArg2(destptr, v1)
diff --git a/src/cmd/compile/internal/ssa/rewrite386splitload.go b/src/cmd/compile/internal/ssa/rewrite386splitload.go
index fff26fa..670e7f4 100644
--- a/src/cmd/compile/internal/ssa/rewrite386splitload.go
+++ b/src/cmd/compile/internal/ssa/rewrite386splitload.go
@@ -26,7 +26,7 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (CMPBconstload {sym} [vo] ptr mem)
-	// result: (CMPBconst (MOVBload {sym} [vo.Off32()] ptr mem) [vo.Val8()])
+	// result: (CMPBconst (MOVBload {sym} [vo.Off()] ptr mem) [vo.Val8()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -35,7 +35,7 @@
 		v.reset(Op386CMPBconst)
 		v.AuxInt = int8ToAuxInt(vo.Val8())
 		v0 := b.NewValue0(v.Pos, Op386MOVBload, typ.UInt8)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		v.AddArg(v0)
@@ -71,16 +71,16 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (CMPLconstload {sym} [vo] ptr mem)
-	// result: (CMPLconst (MOVLload {sym} [vo.Off32()] ptr mem) [vo.Val32()])
+	// result: (CMPLconst (MOVLload {sym} [vo.Off()] ptr mem) [vo.Val()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
 		ptr := v_0
 		mem := v_1
 		v.reset(Op386CMPLconst)
-		v.AuxInt = int32ToAuxInt(vo.Val32())
+		v.AuxInt = int32ToAuxInt(vo.Val())
 		v0 := b.NewValue0(v.Pos, Op386MOVLload, typ.UInt32)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		v.AddArg(v0)
@@ -116,7 +116,7 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (CMPWconstload {sym} [vo] ptr mem)
-	// result: (CMPWconst (MOVWload {sym} [vo.Off32()] ptr mem) [vo.Val16()])
+	// result: (CMPWconst (MOVWload {sym} [vo.Off()] ptr mem) [vo.Val16()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -125,7 +125,7 @@
 		v.reset(Op386CMPWconst)
 		v.AuxInt = int16ToAuxInt(vo.Val16())
 		v0 := b.NewValue0(v.Pos, Op386MOVWload, typ.UInt16)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		v.AddArg(v0)
@@ -156,7 +156,5 @@
 	}
 }
 func rewriteBlock386splitload(b *Block) bool {
-	switch b.Kind {
-	}
 	return false
 }
diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go
index 8272a40..5045ba7 100644
--- a/src/cmd/compile/internal/ssa/rewriteAMD64.go
+++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go
@@ -3,7 +3,9 @@
 
 package ssa
 
+import "internal/buildcfg"
 import "math"
+import "cmd/internal/obj"
 import "cmd/compile/internal/types"
 
 func rewriteValueAMD64(v *Value) bool {
@@ -66,44 +68,20 @@
 		return rewriteValueAMD64_OpAMD64BSFQ(v)
 	case OpAMD64BTCLconst:
 		return rewriteValueAMD64_OpAMD64BTCLconst(v)
-	case OpAMD64BTCLconstmodify:
-		return rewriteValueAMD64_OpAMD64BTCLconstmodify(v)
-	case OpAMD64BTCLmodify:
-		return rewriteValueAMD64_OpAMD64BTCLmodify(v)
 	case OpAMD64BTCQconst:
 		return rewriteValueAMD64_OpAMD64BTCQconst(v)
-	case OpAMD64BTCQconstmodify:
-		return rewriteValueAMD64_OpAMD64BTCQconstmodify(v)
-	case OpAMD64BTCQmodify:
-		return rewriteValueAMD64_OpAMD64BTCQmodify(v)
 	case OpAMD64BTLconst:
 		return rewriteValueAMD64_OpAMD64BTLconst(v)
 	case OpAMD64BTQconst:
 		return rewriteValueAMD64_OpAMD64BTQconst(v)
 	case OpAMD64BTRLconst:
 		return rewriteValueAMD64_OpAMD64BTRLconst(v)
-	case OpAMD64BTRLconstmodify:
-		return rewriteValueAMD64_OpAMD64BTRLconstmodify(v)
-	case OpAMD64BTRLmodify:
-		return rewriteValueAMD64_OpAMD64BTRLmodify(v)
 	case OpAMD64BTRQconst:
 		return rewriteValueAMD64_OpAMD64BTRQconst(v)
-	case OpAMD64BTRQconstmodify:
-		return rewriteValueAMD64_OpAMD64BTRQconstmodify(v)
-	case OpAMD64BTRQmodify:
-		return rewriteValueAMD64_OpAMD64BTRQmodify(v)
 	case OpAMD64BTSLconst:
 		return rewriteValueAMD64_OpAMD64BTSLconst(v)
-	case OpAMD64BTSLconstmodify:
-		return rewriteValueAMD64_OpAMD64BTSLconstmodify(v)
-	case OpAMD64BTSLmodify:
-		return rewriteValueAMD64_OpAMD64BTSLmodify(v)
 	case OpAMD64BTSQconst:
 		return rewriteValueAMD64_OpAMD64BTSQconst(v)
-	case OpAMD64BTSQconstmodify:
-		return rewriteValueAMD64_OpAMD64BTSQconstmodify(v)
-	case OpAMD64BTSQmodify:
-		return rewriteValueAMD64_OpAMD64BTSQmodify(v)
 	case OpAMD64CMOVLCC:
 		return rewriteValueAMD64_OpAMD64CMOVLCC(v)
 	case OpAMD64CMOVLCS:
@@ -767,8 +745,7 @@
 		v.Op = OpAMD64LoweredGetClosurePtr
 		return true
 	case OpGetG:
-		v.Op = OpAMD64LoweredGetG
-		return true
+		return rewriteValueAMD64_OpGetG(v)
 	case OpHasCPUFeature:
 		return rewriteValueAMD64_OpHasCPUFeature(v)
 	case OpHmul32:
@@ -1061,6 +1038,8 @@
 		return rewriteValueAMD64_OpSelect0(v)
 	case OpSelect1:
 		return rewriteValueAMD64_OpSelect1(v)
+	case OpSelectN:
+		return rewriteValueAMD64_OpSelectN(v)
 	case OpSignExt16to32:
 		v.Op = OpAMD64MOVWQSX
 		return true
@@ -1088,6 +1067,9 @@
 	case OpSqrt:
 		v.Op = OpAMD64SQRTSD
 		return true
+	case OpSqrt32:
+		v.Op = OpAMD64SQRTSS
+		return true
 	case OpStaticCall:
 		v.Op = OpAMD64CALLstatic
 		return true
@@ -2998,36 +2980,6 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	// match: (ANDLmodify [off] {sym} ptr (NOTL s:(SHLL (MOVLconst [1]) <t> x)) mem)
-	// result: (BTRLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		if v_1.Op != OpAMD64NOTL {
-			break
-		}
-		s := v_1.Args[0]
-		if s.Op != OpAMD64SHLL {
-			break
-		}
-		t := s.Type
-		x := s.Args[1]
-		s_0 := s.Args[0]
-		if s_0.Op != OpAMD64MOVLconst || auxIntToInt32(s_0.AuxInt) != 1 {
-			break
-		}
-		mem := v_2
-		v.reset(OpAMD64BTRLmodify)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v0 := b.NewValue0(v.Pos, OpAMD64ANDLconst, t)
-		v0.AuxInt = int32ToAuxInt(31)
-		v0.AddArg(x)
-		v.AddArg3(ptr, v0, mem)
-		return true
-	}
 	// match: (ANDLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
 	// cond: is32Bit(int64(off1)+int64(off2))
 	// result: (ANDLmodify [off1+off2] {sym} base val mem)
@@ -3407,36 +3359,6 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	// match: (ANDQmodify [off] {sym} ptr (NOTQ s:(SHLQ (MOVQconst [1]) <t> x)) mem)
-	// result: (BTRQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		if v_1.Op != OpAMD64NOTQ {
-			break
-		}
-		s := v_1.Args[0]
-		if s.Op != OpAMD64SHLQ {
-			break
-		}
-		t := s.Type
-		x := s.Args[1]
-		s_0 := s.Args[0]
-		if s_0.Op != OpAMD64MOVQconst || auxIntToInt64(s_0.AuxInt) != 1 {
-			break
-		}
-		mem := v_2
-		v.reset(OpAMD64BTRQmodify)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v0 := b.NewValue0(v.Pos, OpAMD64ANDQconst, t)
-		v0.AuxInt = int32ToAuxInt(63)
-		v0.AddArg(x)
-		v.AddArg3(ptr, v0, mem)
-		return true
-	}
 	// match: (ANDQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
 	// cond: is32Bit(int64(off1)+int64(off2))
 	// result: (ANDQmodify [off1+off2] {sym} base val mem)
@@ -3577,105 +3499,6 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64BTCLconstmodify(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (BTCLconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
-	// cond: ValAndOff(valoff1).canAdd32(off2)
-	// result: (BTCLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
-	for {
-		valoff1 := auxIntToValAndOff(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		base := v_0.Args[0]
-		mem := v_1
-		if !(ValAndOff(valoff1).canAdd32(off2)) {
-			break
-		}
-		v.reset(OpAMD64BTCLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
-		v.Aux = symToAux(sym)
-		v.AddArg2(base, mem)
-		return true
-	}
-	// match: (BTCLconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
-	// cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)
-	// result: (BTCLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
-	for {
-		valoff1 := auxIntToValAndOff(v.AuxInt)
-		sym1 := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64LEAQ {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		sym2 := auxToSym(v_0.Aux)
-		base := v_0.Args[0]
-		mem := v_1
-		if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) {
-			break
-		}
-		v.reset(OpAMD64BTCLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
-		v.Aux = symToAux(mergeSym(sym1, sym2))
-		v.AddArg2(base, mem)
-		return true
-	}
-	return false
-}
-func rewriteValueAMD64_OpAMD64BTCLmodify(v *Value) bool {
-	v_2 := v.Args[2]
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (BTCLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
-	// cond: is32Bit(int64(off1)+int64(off2))
-	// result: (BTCLmodify [off1+off2] {sym} base val mem)
-	for {
-		off1 := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		base := v_0.Args[0]
-		val := v_1
-		mem := v_2
-		if !(is32Bit(int64(off1) + int64(off2))) {
-			break
-		}
-		v.reset(OpAMD64BTCLmodify)
-		v.AuxInt = int32ToAuxInt(off1 + off2)
-		v.Aux = symToAux(sym)
-		v.AddArg3(base, val, mem)
-		return true
-	}
-	// match: (BTCLmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
-	// cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
-	// result: (BTCLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-	for {
-		off1 := auxIntToInt32(v.AuxInt)
-		sym1 := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64LEAQ {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		sym2 := auxToSym(v_0.Aux)
-		base := v_0.Args[0]
-		val := v_1
-		mem := v_2
-		if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) {
-			break
-		}
-		v.reset(OpAMD64BTCLmodify)
-		v.AuxInt = int32ToAuxInt(off1 + off2)
-		v.Aux = symToAux(mergeSym(sym1, sym2))
-		v.AddArg3(base, val, mem)
-		return true
-	}
-	return false
-}
 func rewriteValueAMD64_OpAMD64BTCQconst(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (BTCQconst [c] (XORQconst [d] x))
@@ -3728,105 +3551,6 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64BTCQconstmodify(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (BTCQconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
-	// cond: ValAndOff(valoff1).canAdd32(off2)
-	// result: (BTCQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
-	for {
-		valoff1 := auxIntToValAndOff(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		base := v_0.Args[0]
-		mem := v_1
-		if !(ValAndOff(valoff1).canAdd32(off2)) {
-			break
-		}
-		v.reset(OpAMD64BTCQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
-		v.Aux = symToAux(sym)
-		v.AddArg2(base, mem)
-		return true
-	}
-	// match: (BTCQconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
-	// cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)
-	// result: (BTCQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
-	for {
-		valoff1 := auxIntToValAndOff(v.AuxInt)
-		sym1 := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64LEAQ {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		sym2 := auxToSym(v_0.Aux)
-		base := v_0.Args[0]
-		mem := v_1
-		if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) {
-			break
-		}
-		v.reset(OpAMD64BTCQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
-		v.Aux = symToAux(mergeSym(sym1, sym2))
-		v.AddArg2(base, mem)
-		return true
-	}
-	return false
-}
-func rewriteValueAMD64_OpAMD64BTCQmodify(v *Value) bool {
-	v_2 := v.Args[2]
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (BTCQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
-	// cond: is32Bit(int64(off1)+int64(off2))
-	// result: (BTCQmodify [off1+off2] {sym} base val mem)
-	for {
-		off1 := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		base := v_0.Args[0]
-		val := v_1
-		mem := v_2
-		if !(is32Bit(int64(off1) + int64(off2))) {
-			break
-		}
-		v.reset(OpAMD64BTCQmodify)
-		v.AuxInt = int32ToAuxInt(off1 + off2)
-		v.Aux = symToAux(sym)
-		v.AddArg3(base, val, mem)
-		return true
-	}
-	// match: (BTCQmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
-	// cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
-	// result: (BTCQmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-	for {
-		off1 := auxIntToInt32(v.AuxInt)
-		sym1 := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64LEAQ {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		sym2 := auxToSym(v_0.Aux)
-		base := v_0.Args[0]
-		val := v_1
-		mem := v_2
-		if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) {
-			break
-		}
-		v.reset(OpAMD64BTCQmodify)
-		v.AuxInt = int32ToAuxInt(off1 + off2)
-		v.Aux = symToAux(mergeSym(sym1, sym2))
-		v.AddArg3(base, val, mem)
-		return true
-	}
-	return false
-}
 func rewriteValueAMD64_OpAMD64BTLconst(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (BTLconst [c] (SHRQconst [d] x))
@@ -4061,105 +3785,6 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64BTRLconstmodify(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (BTRLconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
-	// cond: ValAndOff(valoff1).canAdd32(off2)
-	// result: (BTRLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
-	for {
-		valoff1 := auxIntToValAndOff(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		base := v_0.Args[0]
-		mem := v_1
-		if !(ValAndOff(valoff1).canAdd32(off2)) {
-			break
-		}
-		v.reset(OpAMD64BTRLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
-		v.Aux = symToAux(sym)
-		v.AddArg2(base, mem)
-		return true
-	}
-	// match: (BTRLconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
-	// cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)
-	// result: (BTRLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
-	for {
-		valoff1 := auxIntToValAndOff(v.AuxInt)
-		sym1 := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64LEAQ {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		sym2 := auxToSym(v_0.Aux)
-		base := v_0.Args[0]
-		mem := v_1
-		if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) {
-			break
-		}
-		v.reset(OpAMD64BTRLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
-		v.Aux = symToAux(mergeSym(sym1, sym2))
-		v.AddArg2(base, mem)
-		return true
-	}
-	return false
-}
-func rewriteValueAMD64_OpAMD64BTRLmodify(v *Value) bool {
-	v_2 := v.Args[2]
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (BTRLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
-	// cond: is32Bit(int64(off1)+int64(off2))
-	// result: (BTRLmodify [off1+off2] {sym} base val mem)
-	for {
-		off1 := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		base := v_0.Args[0]
-		val := v_1
-		mem := v_2
-		if !(is32Bit(int64(off1) + int64(off2))) {
-			break
-		}
-		v.reset(OpAMD64BTRLmodify)
-		v.AuxInt = int32ToAuxInt(off1 + off2)
-		v.Aux = symToAux(sym)
-		v.AddArg3(base, val, mem)
-		return true
-	}
-	// match: (BTRLmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
-	// cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
-	// result: (BTRLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-	for {
-		off1 := auxIntToInt32(v.AuxInt)
-		sym1 := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64LEAQ {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		sym2 := auxToSym(v_0.Aux)
-		base := v_0.Args[0]
-		val := v_1
-		mem := v_2
-		if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) {
-			break
-		}
-		v.reset(OpAMD64BTRLmodify)
-		v.AuxInt = int32ToAuxInt(off1 + off2)
-		v.Aux = symToAux(mergeSym(sym1, sym2))
-		v.AddArg3(base, val, mem)
-		return true
-	}
-	return false
-}
 func rewriteValueAMD64_OpAMD64BTRQconst(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (BTRQconst [c] (BTSQconst [c] x))
@@ -4238,105 +3863,6 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64BTRQconstmodify(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (BTRQconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
-	// cond: ValAndOff(valoff1).canAdd32(off2)
-	// result: (BTRQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
-	for {
-		valoff1 := auxIntToValAndOff(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		base := v_0.Args[0]
-		mem := v_1
-		if !(ValAndOff(valoff1).canAdd32(off2)) {
-			break
-		}
-		v.reset(OpAMD64BTRQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
-		v.Aux = symToAux(sym)
-		v.AddArg2(base, mem)
-		return true
-	}
-	// match: (BTRQconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
-	// cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)
-	// result: (BTRQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
-	for {
-		valoff1 := auxIntToValAndOff(v.AuxInt)
-		sym1 := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64LEAQ {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		sym2 := auxToSym(v_0.Aux)
-		base := v_0.Args[0]
-		mem := v_1
-		if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) {
-			break
-		}
-		v.reset(OpAMD64BTRQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
-		v.Aux = symToAux(mergeSym(sym1, sym2))
-		v.AddArg2(base, mem)
-		return true
-	}
-	return false
-}
-func rewriteValueAMD64_OpAMD64BTRQmodify(v *Value) bool {
-	v_2 := v.Args[2]
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (BTRQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
-	// cond: is32Bit(int64(off1)+int64(off2))
-	// result: (BTRQmodify [off1+off2] {sym} base val mem)
-	for {
-		off1 := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		base := v_0.Args[0]
-		val := v_1
-		mem := v_2
-		if !(is32Bit(int64(off1) + int64(off2))) {
-			break
-		}
-		v.reset(OpAMD64BTRQmodify)
-		v.AuxInt = int32ToAuxInt(off1 + off2)
-		v.Aux = symToAux(sym)
-		v.AddArg3(base, val, mem)
-		return true
-	}
-	// match: (BTRQmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
-	// cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
-	// result: (BTRQmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-	for {
-		off1 := auxIntToInt32(v.AuxInt)
-		sym1 := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64LEAQ {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		sym2 := auxToSym(v_0.Aux)
-		base := v_0.Args[0]
-		val := v_1
-		mem := v_2
-		if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) {
-			break
-		}
-		v.reset(OpAMD64BTRQmodify)
-		v.AuxInt = int32ToAuxInt(off1 + off2)
-		v.Aux = symToAux(mergeSym(sym1, sym2))
-		v.AddArg3(base, val, mem)
-		return true
-	}
-	return false
-}
 func rewriteValueAMD64_OpAMD64BTSLconst(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (BTSLconst [c] (BTRLconst [c] x))
@@ -4407,105 +3933,6 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64BTSLconstmodify(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (BTSLconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
-	// cond: ValAndOff(valoff1).canAdd32(off2)
-	// result: (BTSLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
-	for {
-		valoff1 := auxIntToValAndOff(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		base := v_0.Args[0]
-		mem := v_1
-		if !(ValAndOff(valoff1).canAdd32(off2)) {
-			break
-		}
-		v.reset(OpAMD64BTSLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
-		v.Aux = symToAux(sym)
-		v.AddArg2(base, mem)
-		return true
-	}
-	// match: (BTSLconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
-	// cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)
-	// result: (BTSLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
-	for {
-		valoff1 := auxIntToValAndOff(v.AuxInt)
-		sym1 := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64LEAQ {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		sym2 := auxToSym(v_0.Aux)
-		base := v_0.Args[0]
-		mem := v_1
-		if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) {
-			break
-		}
-		v.reset(OpAMD64BTSLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
-		v.Aux = symToAux(mergeSym(sym1, sym2))
-		v.AddArg2(base, mem)
-		return true
-	}
-	return false
-}
-func rewriteValueAMD64_OpAMD64BTSLmodify(v *Value) bool {
-	v_2 := v.Args[2]
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (BTSLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
-	// cond: is32Bit(int64(off1)+int64(off2))
-	// result: (BTSLmodify [off1+off2] {sym} base val mem)
-	for {
-		off1 := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		base := v_0.Args[0]
-		val := v_1
-		mem := v_2
-		if !(is32Bit(int64(off1) + int64(off2))) {
-			break
-		}
-		v.reset(OpAMD64BTSLmodify)
-		v.AuxInt = int32ToAuxInt(off1 + off2)
-		v.Aux = symToAux(sym)
-		v.AddArg3(base, val, mem)
-		return true
-	}
-	// match: (BTSLmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
-	// cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
-	// result: (BTSLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-	for {
-		off1 := auxIntToInt32(v.AuxInt)
-		sym1 := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64LEAQ {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		sym2 := auxToSym(v_0.Aux)
-		base := v_0.Args[0]
-		val := v_1
-		mem := v_2
-		if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) {
-			break
-		}
-		v.reset(OpAMD64BTSLmodify)
-		v.AuxInt = int32ToAuxInt(off1 + off2)
-		v.Aux = symToAux(mergeSym(sym1, sym2))
-		v.AddArg3(base, val, mem)
-		return true
-	}
-	return false
-}
 func rewriteValueAMD64_OpAMD64BTSQconst(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (BTSQconst [c] (BTRQconst [c] x))
@@ -4584,105 +4011,6 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64BTSQconstmodify(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (BTSQconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
-	// cond: ValAndOff(valoff1).canAdd32(off2)
-	// result: (BTSQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
-	for {
-		valoff1 := auxIntToValAndOff(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		base := v_0.Args[0]
-		mem := v_1
-		if !(ValAndOff(valoff1).canAdd32(off2)) {
-			break
-		}
-		v.reset(OpAMD64BTSQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
-		v.Aux = symToAux(sym)
-		v.AddArg2(base, mem)
-		return true
-	}
-	// match: (BTSQconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
-	// cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)
-	// result: (BTSQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
-	for {
-		valoff1 := auxIntToValAndOff(v.AuxInt)
-		sym1 := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64LEAQ {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		sym2 := auxToSym(v_0.Aux)
-		base := v_0.Args[0]
-		mem := v_1
-		if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) {
-			break
-		}
-		v.reset(OpAMD64BTSQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
-		v.Aux = symToAux(mergeSym(sym1, sym2))
-		v.AddArg2(base, mem)
-		return true
-	}
-	return false
-}
-func rewriteValueAMD64_OpAMD64BTSQmodify(v *Value) bool {
-	v_2 := v.Args[2]
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (BTSQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
-	// cond: is32Bit(int64(off1)+int64(off2))
-	// result: (BTSQmodify [off1+off2] {sym} base val mem)
-	for {
-		off1 := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		base := v_0.Args[0]
-		val := v_1
-		mem := v_2
-		if !(is32Bit(int64(off1) + int64(off2))) {
-			break
-		}
-		v.reset(OpAMD64BTSQmodify)
-		v.AuxInt = int32ToAuxInt(off1 + off2)
-		v.Aux = symToAux(sym)
-		v.AddArg3(base, val, mem)
-		return true
-	}
-	// match: (BTSQmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
-	// cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
-	// result: (BTSQmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-	for {
-		off1 := auxIntToInt32(v.AuxInt)
-		sym1 := auxToSym(v.Aux)
-		if v_0.Op != OpAMD64LEAQ {
-			break
-		}
-		off2 := auxIntToInt32(v_0.AuxInt)
-		sym2 := auxToSym(v_0.Aux)
-		base := v_0.Args[0]
-		val := v_1
-		mem := v_2
-		if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) {
-			break
-		}
-		v.reset(OpAMD64BTSQmodify)
-		v.AuxInt = int32ToAuxInt(off1 + off2)
-		v.Aux = symToAux(mergeSym(sym1, sym2))
-		v.AddArg3(base, val, mem)
-		return true
-	}
-	return false
-}
 func rewriteValueAMD64_OpAMD64CMOVLCC(v *Value) bool {
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
@@ -6809,12 +6137,12 @@
 		return true
 	}
 	// match: (CMPB x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPB y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpAMD64InvertFlags)
@@ -7018,7 +6346,7 @@
 	}
 	// match: (CMPBconst l:(MOVBload {sym} [off] ptr mem) [c])
 	// cond: l.Uses == 1 && clobber(l)
-	// result: @l.Block (CMPBconstload {sym} [makeValAndOff32(int32(c),off)] ptr mem)
+	// result: @l.Block (CMPBconstload {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		c := auxIntToInt8(v.AuxInt)
 		l := v_0
@@ -7035,7 +6363,7 @@
 		b = l.Block
 		v0 := b.NewValue0(l.Pos, OpAMD64CMPBconstload, types.TypeFlags)
 		v.copyOf(v0)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		return true
@@ -7140,8 +6468,7 @@
 		return true
 	}
 	// match: (CMPBload {sym} [off] ptr (MOVLconst [c]) mem)
-	// cond: validValAndOff(int64(int8(c)),int64(off))
-	// result: (CMPBconstload {sym} [makeValAndOff32(int32(int8(c)),off)] ptr mem)
+	// result: (CMPBconstload {sym} [makeValAndOff(int32(int8(c)),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -7151,11 +6478,8 @@
 		}
 		c := auxIntToInt32(v_1.AuxInt)
 		mem := v_2
-		if !(validValAndOff(int64(int8(c)), int64(off))) {
-			break
-		}
 		v.reset(OpAMD64CMPBconstload)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(int8(c)), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(int8(c)), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -7195,12 +6519,12 @@
 		return true
 	}
 	// match: (CMPL x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPL y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpAMD64InvertFlags)
@@ -7419,7 +6743,7 @@
 	}
 	// match: (CMPLconst l:(MOVLload {sym} [off] ptr mem) [c])
 	// cond: l.Uses == 1 && clobber(l)
-	// result: @l.Block (CMPLconstload {sym} [makeValAndOff32(c,off)] ptr mem)
+	// result: @l.Block (CMPLconstload {sym} [makeValAndOff(c,off)] ptr mem)
 	for {
 		c := auxIntToInt32(v.AuxInt)
 		l := v_0
@@ -7436,7 +6760,7 @@
 		b = l.Block
 		v0 := b.NewValue0(l.Pos, OpAMD64CMPLconstload, types.TypeFlags)
 		v.copyOf(v0)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(c, off))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(c, off))
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		return true
@@ -7541,8 +6865,7 @@
 		return true
 	}
 	// match: (CMPLload {sym} [off] ptr (MOVLconst [c]) mem)
-	// cond: validValAndOff(int64(c),int64(off))
-	// result: (CMPLconstload {sym} [makeValAndOff32(c,off)] ptr mem)
+	// result: (CMPLconstload {sym} [makeValAndOff(c,off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -7552,11 +6875,8 @@
 		}
 		c := auxIntToInt32(v_1.AuxInt)
 		mem := v_2
-		if !(validValAndOff(int64(c), int64(off))) {
-			break
-		}
 		v.reset(OpAMD64CMPLconstload)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(c, off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(c, off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -7604,12 +6924,12 @@
 		return true
 	}
 	// match: (CMPQ x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPQ y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpAMD64InvertFlags)
@@ -7989,7 +7309,7 @@
 	}
 	// match: (CMPQconst l:(MOVQload {sym} [off] ptr mem) [c])
 	// cond: l.Uses == 1 && clobber(l)
-	// result: @l.Block (CMPQconstload {sym} [makeValAndOff32(c,off)] ptr mem)
+	// result: @l.Block (CMPQconstload {sym} [makeValAndOff(c,off)] ptr mem)
 	for {
 		c := auxIntToInt32(v.AuxInt)
 		l := v_0
@@ -8006,7 +7326,7 @@
 		b = l.Block
 		v0 := b.NewValue0(l.Pos, OpAMD64CMPQconstload, types.TypeFlags)
 		v.copyOf(v0)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(c, off))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(c, off))
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		return true
@@ -8111,8 +7431,8 @@
 		return true
 	}
 	// match: (CMPQload {sym} [off] ptr (MOVQconst [c]) mem)
-	// cond: validValAndOff(c,int64(off))
-	// result: (CMPQconstload {sym} [makeValAndOff64(c,int64(off))] ptr mem)
+	// cond: validVal(c)
+	// result: (CMPQconstload {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -8122,11 +7442,11 @@
 		}
 		c := auxIntToInt64(v_1.AuxInt)
 		mem := v_2
-		if !(validValAndOff(c, int64(off))) {
+		if !(validVal(c)) {
 			break
 		}
 		v.reset(OpAMD64CMPQconstload)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff64(c, int64(off)))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -8166,12 +7486,12 @@
 		return true
 	}
 	// match: (CMPW x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPW y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpAMD64InvertFlags)
@@ -8375,7 +7695,7 @@
 	}
 	// match: (CMPWconst l:(MOVWload {sym} [off] ptr mem) [c])
 	// cond: l.Uses == 1 && clobber(l)
-	// result: @l.Block (CMPWconstload {sym} [makeValAndOff32(int32(c),off)] ptr mem)
+	// result: @l.Block (CMPWconstload {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		c := auxIntToInt16(v.AuxInt)
 		l := v_0
@@ -8392,7 +7712,7 @@
 		b = l.Block
 		v0 := b.NewValue0(l.Pos, OpAMD64CMPWconstload, types.TypeFlags)
 		v.copyOf(v0)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		return true
@@ -8497,8 +7817,7 @@
 		return true
 	}
 	// match: (CMPWload {sym} [off] ptr (MOVLconst [c]) mem)
-	// cond: validValAndOff(int64(int16(c)),int64(off))
-	// result: (CMPWconstload {sym} [makeValAndOff32(int32(int16(c)),off)] ptr mem)
+	// result: (CMPWconstload {sym} [makeValAndOff(int32(int16(c)),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -8508,11 +7827,8 @@
 		}
 		c := auxIntToInt32(v_1.AuxInt)
 		mem := v_2
-		if !(validValAndOff(int64(int16(c)), int64(off))) {
-			break
-		}
 		v.reset(OpAMD64CMPWconstload)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(int16(c)), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(int16(c)), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -10656,7 +9972,7 @@
 		return true
 	}
 	// match: (MOVBstore [off] {sym} ptr (MOVLconst [c]) mem)
-	// result: (MOVBstoreconst [makeValAndOff32(int32(int8(c)),off)] {sym} ptr mem)
+	// result: (MOVBstoreconst [makeValAndOff(int32(int8(c)),off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -10667,13 +9983,13 @@
 		c := auxIntToInt32(v_1.AuxInt)
 		mem := v_2
 		v.reset(OpAMD64MOVBstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(int8(c)), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(int8(c)), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
 	}
 	// match: (MOVBstore [off] {sym} ptr (MOVQconst [c]) mem)
-	// result: (MOVBstoreconst [makeValAndOff32(int32(int8(c)),off)] {sym} ptr mem)
+	// result: (MOVBstoreconst [makeValAndOff(int32(int8(c)),off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -10684,7 +10000,7 @@
 		c := auxIntToInt64(v_1.AuxInt)
 		mem := v_2
 		v.reset(OpAMD64MOVBstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(int8(c)), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(int8(c)), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -11471,6 +10787,56 @@
 		v.AddArg3(p0, w0, mem)
 		return true
 	}
+	// match: (MOVBstore [7] {s} p1 (SHRQconst [56] w) x1:(MOVWstore [5] {s} p1 (SHRQconst [40] w) x2:(MOVLstore [1] {s} p1 (SHRQconst [8] w) x3:(MOVBstore [0] {s} p1 w mem))))
+	// cond: x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && clobber(x1, x2, x3)
+	// result: (MOVQstore {s} p1 w mem)
+	for {
+		if auxIntToInt32(v.AuxInt) != 7 {
+			break
+		}
+		s := auxToSym(v.Aux)
+		p1 := v_0
+		if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 56 {
+			break
+		}
+		w := v_1.Args[0]
+		x1 := v_2
+		if x1.Op != OpAMD64MOVWstore || auxIntToInt32(x1.AuxInt) != 5 || auxToSym(x1.Aux) != s {
+			break
+		}
+		_ = x1.Args[2]
+		if p1 != x1.Args[0] {
+			break
+		}
+		x1_1 := x1.Args[1]
+		if x1_1.Op != OpAMD64SHRQconst || auxIntToInt8(x1_1.AuxInt) != 40 || w != x1_1.Args[0] {
+			break
+		}
+		x2 := x1.Args[2]
+		if x2.Op != OpAMD64MOVLstore || auxIntToInt32(x2.AuxInt) != 1 || auxToSym(x2.Aux) != s {
+			break
+		}
+		_ = x2.Args[2]
+		if p1 != x2.Args[0] {
+			break
+		}
+		x2_1 := x2.Args[1]
+		if x2_1.Op != OpAMD64SHRQconst || auxIntToInt8(x2_1.AuxInt) != 8 || w != x2_1.Args[0] {
+			break
+		}
+		x3 := x2.Args[2]
+		if x3.Op != OpAMD64MOVBstore || auxIntToInt32(x3.AuxInt) != 0 || auxToSym(x3.Aux) != s {
+			break
+		}
+		mem := x3.Args[2]
+		if p1 != x3.Args[0] || w != x3.Args[1] || !(x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && clobber(x1, x2, x3)) {
+			break
+		}
+		v.reset(OpAMD64MOVQstore)
+		v.Aux = symToAux(s)
+		v.AddArg3(p1, w, mem)
+		return true
+	}
 	// match: (MOVBstore [i] {s} p x1:(MOVBload [j] {s2} p2 mem) mem2:(MOVBstore [i-1] {s} p x2:(MOVBload [j-1] {s2} p2 mem) mem))
 	// cond: x1.Uses == 1 && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1, x2, mem2)
 	// result: (MOVWstore [i-1] {s} p (MOVWload [j-1] {s2} p2 mem) mem)
@@ -11607,7 +10973,7 @@
 	}
 	// match: (MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
 	// cond: x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x)
-	// result: (MOVWstoreconst [makeValAndOff64(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
+	// result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -11625,14 +10991,14 @@
 			break
 		}
 		v.reset(OpAMD64MOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff64(a.Val()&0xff|c.Val()<<8, a.Off()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p, mem)
 		return true
 	}
 	// match: (MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem))
 	// cond: x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x)
-	// result: (MOVWstoreconst [makeValAndOff64(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
+	// result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
 	for {
 		a := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -11650,7 +11016,7 @@
 			break
 		}
 		v.reset(OpAMD64MOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff64(a.Val()&0xff|c.Val()<<8, a.Off()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p, mem)
 		return true
@@ -12264,7 +11630,7 @@
 		return true
 	}
 	// match: (MOVLstore [off] {sym} ptr (MOVLconst [c]) mem)
-	// result: (MOVLstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+	// result: (MOVLstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -12275,13 +11641,13 @@
 		c := auxIntToInt32(v_1.AuxInt)
 		mem := v_2
 		v.reset(OpAMD64MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
 	}
 	// match: (MOVLstore [off] {sym} ptr (MOVQconst [c]) mem)
-	// result: (MOVLstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+	// result: (MOVLstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -12292,7 +11658,7 @@
 		c := auxIntToInt64(v_1.AuxInt)
 		mem := v_2
 		v.reset(OpAMD64MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -12769,99 +12135,9 @@
 		}
 		break
 	}
-	// match: (MOVLstore {sym} [off] ptr y:(BTCL l:(MOVLload [off] {sym} ptr mem) <t> x) mem)
-	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l)
-	// result: (BTCLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		y := v_1
-		if y.Op != OpAMD64BTCL {
-			break
-		}
-		t := y.Type
-		x := y.Args[1]
-		l := y.Args[0]
-		if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym {
-			break
-		}
-		mem := l.Args[1]
-		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l)) {
-			break
-		}
-		v.reset(OpAMD64BTCLmodify)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v0 := b.NewValue0(l.Pos, OpAMD64ANDLconst, t)
-		v0.AuxInt = int32ToAuxInt(31)
-		v0.AddArg(x)
-		v.AddArg3(ptr, v0, mem)
-		return true
-	}
-	// match: (MOVLstore {sym} [off] ptr y:(BTRL l:(MOVLload [off] {sym} ptr mem) <t> x) mem)
-	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l)
-	// result: (BTRLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		y := v_1
-		if y.Op != OpAMD64BTRL {
-			break
-		}
-		t := y.Type
-		x := y.Args[1]
-		l := y.Args[0]
-		if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym {
-			break
-		}
-		mem := l.Args[1]
-		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l)) {
-			break
-		}
-		v.reset(OpAMD64BTRLmodify)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v0 := b.NewValue0(l.Pos, OpAMD64ANDLconst, t)
-		v0.AuxInt = int32ToAuxInt(31)
-		v0.AddArg(x)
-		v.AddArg3(ptr, v0, mem)
-		return true
-	}
-	// match: (MOVLstore {sym} [off] ptr y:(BTSL l:(MOVLload [off] {sym} ptr mem) <t> x) mem)
-	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l)
-	// result: (BTSLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		y := v_1
-		if y.Op != OpAMD64BTSL {
-			break
-		}
-		t := y.Type
-		x := y.Args[1]
-		l := y.Args[0]
-		if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym {
-			break
-		}
-		mem := l.Args[1]
-		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l)) {
-			break
-		}
-		v.reset(OpAMD64BTSLmodify)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v0 := b.NewValue0(l.Pos, OpAMD64ANDLconst, t)
-		v0.AuxInt = int32ToAuxInt(31)
-		v0.AddArg(x)
-		v.AddArg3(ptr, v0, 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(int64(c),int64(off)) && clobber(l, a)
-	// result: (ADDLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
+	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)
+	// result: (ADDLconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -12877,18 +12153,18 @@
 		}
 		mem := l.Args[1]
 		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
+		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)) {
 			break
 		}
 		v.reset(OpAMD64ADDLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
 	}
 	// match: (MOVLstore [off] {sym} ptr a:(ANDLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem)
-	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a)
-	// result: (ANDLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
+	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)
+	// result: (ANDLconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -12904,18 +12180,18 @@
 		}
 		mem := l.Args[1]
 		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
+		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)) {
 			break
 		}
 		v.reset(OpAMD64ANDLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
 	}
 	// match: (MOVLstore [off] {sym} ptr a:(ORLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem)
-	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a)
-	// result: (ORLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
+	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)
+	// result: (ORLconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -12931,18 +12207,18 @@
 		}
 		mem := l.Args[1]
 		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
+		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)) {
 			break
 		}
 		v.reset(OpAMD64ORLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
 	}
 	// match: (MOVLstore [off] {sym} ptr a:(XORLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem)
-	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a)
-	// result: (XORLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
+	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)
+	// result: (XORLconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -12958,92 +12234,11 @@
 		}
 		mem := l.Args[1]
 		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
+		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)) {
 			break
 		}
 		v.reset(OpAMD64XORLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
-		v.Aux = symToAux(sym)
-		v.AddArg2(ptr, mem)
-		return true
-	}
-	// match: (MOVLstore [off] {sym} ptr a:(BTCLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem)
-	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a)
-	// result: (BTCLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		a := v_1
-		if a.Op != OpAMD64BTCLconst {
-			break
-		}
-		c := auxIntToInt8(a.AuxInt)
-		l := a.Args[0]
-		if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym {
-			break
-		}
-		mem := l.Args[1]
-		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
-			break
-		}
-		v.reset(OpAMD64BTCLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
-		v.Aux = symToAux(sym)
-		v.AddArg2(ptr, mem)
-		return true
-	}
-	// match: (MOVLstore [off] {sym} ptr a:(BTRLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem)
-	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a)
-	// result: (BTRLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		a := v_1
-		if a.Op != OpAMD64BTRLconst {
-			break
-		}
-		c := auxIntToInt8(a.AuxInt)
-		l := a.Args[0]
-		if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym {
-			break
-		}
-		mem := l.Args[1]
-		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
-			break
-		}
-		v.reset(OpAMD64BTRLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
-		v.Aux = symToAux(sym)
-		v.AddArg2(ptr, mem)
-		return true
-	}
-	// match: (MOVLstore [off] {sym} ptr a:(BTSLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem)
-	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a)
-	// result: (BTSLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		a := v_1
-		if a.Op != OpAMD64BTSLconst {
-			break
-		}
-		c := auxIntToInt8(a.AuxInt)
-		l := a.Args[0]
-		if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym {
-			break
-		}
-		mem := l.Args[1]
-		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
-			break
-		}
-		v.reset(OpAMD64BTSLconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -13117,7 +12312,7 @@
 	}
 	// match: (MOVLstoreconst [c] {s} p x:(MOVLstoreconst [a] {s} p mem))
 	// cond: x.Uses == 1 && a.Off() + 4 == c.Off() && clobber(x)
-	// result: (MOVQstore [a.Off32()] {s} p (MOVQconst [a.Val()&0xffffffff | c.Val()<<32]) mem)
+	// result: (MOVQstore [a.Off()] {s} p (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -13135,16 +12330,16 @@
 			break
 		}
 		v.reset(OpAMD64MOVQstore)
-		v.AuxInt = int32ToAuxInt(a.Off32())
+		v.AuxInt = int32ToAuxInt(a.Off())
 		v.Aux = symToAux(s)
 		v0 := b.NewValue0(x.Pos, OpAMD64MOVQconst, typ.UInt64)
-		v0.AuxInt = int64ToAuxInt(a.Val()&0xffffffff | c.Val()<<32)
+		v0.AuxInt = int64ToAuxInt(a.Val64()&0xffffffff | c.Val64()<<32)
 		v.AddArg3(p, v0, mem)
 		return true
 	}
 	// match: (MOVLstoreconst [a] {s} p x:(MOVLstoreconst [c] {s} p mem))
 	// cond: x.Uses == 1 && a.Off() + 4 == c.Off() && clobber(x)
-	// result: (MOVQstore [a.Off32()] {s} p (MOVQconst [a.Val()&0xffffffff | c.Val()<<32]) mem)
+	// result: (MOVQstore [a.Off()] {s} p (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
 	for {
 		a := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -13162,10 +12357,10 @@
 			break
 		}
 		v.reset(OpAMD64MOVQstore)
-		v.AuxInt = int32ToAuxInt(a.Off32())
+		v.AuxInt = int32ToAuxInt(a.Off())
 		v.Aux = symToAux(s)
 		v0 := b.NewValue0(x.Pos, OpAMD64MOVQconst, typ.UInt64)
-		v0.AuxInt = int64ToAuxInt(a.Val()&0xffffffff | c.Val()<<32)
+		v0.AuxInt = int64ToAuxInt(a.Val64()&0xffffffff | c.Val64()<<32)
 		v.AddArg3(p, v0, mem)
 		return true
 	}
@@ -13597,7 +12792,6 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
 	// match: (MOVQstore [off1] {sym} (ADDQconst [off2] ptr) val mem)
 	// cond: is32Bit(int64(off1)+int64(off2))
 	// result: (MOVQstore [off1+off2] {sym} ptr val mem)
@@ -13622,7 +12816,7 @@
 	}
 	// match: (MOVQstore [off] {sym} ptr (MOVQconst [c]) mem)
 	// cond: validVal(c)
-	// result: (MOVQstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+	// result: (MOVQstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -13636,7 +12830,7 @@
 			break
 		}
 		v.reset(OpAMD64MOVQstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -13963,99 +13157,9 @@
 		}
 		break
 	}
-	// match: (MOVQstore {sym} [off] ptr y:(BTCQ l:(MOVQload [off] {sym} ptr mem) <t> x) mem)
-	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l)
-	// result: (BTCQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		y := v_1
-		if y.Op != OpAMD64BTCQ {
-			break
-		}
-		t := y.Type
-		x := y.Args[1]
-		l := y.Args[0]
-		if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym {
-			break
-		}
-		mem := l.Args[1]
-		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l)) {
-			break
-		}
-		v.reset(OpAMD64BTCQmodify)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v0 := b.NewValue0(l.Pos, OpAMD64ANDQconst, t)
-		v0.AuxInt = int32ToAuxInt(63)
-		v0.AddArg(x)
-		v.AddArg3(ptr, v0, mem)
-		return true
-	}
-	// match: (MOVQstore {sym} [off] ptr y:(BTRQ l:(MOVQload [off] {sym} ptr mem) <t> x) mem)
-	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l)
-	// result: (BTRQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		y := v_1
-		if y.Op != OpAMD64BTRQ {
-			break
-		}
-		t := y.Type
-		x := y.Args[1]
-		l := y.Args[0]
-		if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym {
-			break
-		}
-		mem := l.Args[1]
-		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l)) {
-			break
-		}
-		v.reset(OpAMD64BTRQmodify)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v0 := b.NewValue0(l.Pos, OpAMD64ANDQconst, t)
-		v0.AuxInt = int32ToAuxInt(63)
-		v0.AddArg(x)
-		v.AddArg3(ptr, v0, mem)
-		return true
-	}
-	// match: (MOVQstore {sym} [off] ptr y:(BTSQ l:(MOVQload [off] {sym} ptr mem) <t> x) mem)
-	// cond: y.Uses==1 && l.Uses==1 && clobber(y, l)
-	// result: (BTSQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		y := v_1
-		if y.Op != OpAMD64BTSQ {
-			break
-		}
-		t := y.Type
-		x := y.Args[1]
-		l := y.Args[0]
-		if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym {
-			break
-		}
-		mem := l.Args[1]
-		if ptr != l.Args[0] || mem != v_2 || !(y.Uses == 1 && l.Uses == 1 && clobber(y, l)) {
-			break
-		}
-		v.reset(OpAMD64BTSQmodify)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v0 := b.NewValue0(l.Pos, OpAMD64ANDQconst, t)
-		v0.AuxInt = int32ToAuxInt(63)
-		v0.AddArg(x)
-		v.AddArg3(ptr, v0, 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(int64(c),int64(off)) && clobber(l, a)
-	// result: (ADDQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
+	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)
+	// result: (ADDQconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -14071,18 +13175,18 @@
 		}
 		mem := l.Args[1]
 		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
+		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)) {
 			break
 		}
 		v.reset(OpAMD64ADDQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
 	}
 	// match: (MOVQstore [off] {sym} ptr a:(ANDQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem)
-	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a)
-	// result: (ANDQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
+	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)
+	// result: (ANDQconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -14098,18 +13202,18 @@
 		}
 		mem := l.Args[1]
 		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
+		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)) {
 			break
 		}
 		v.reset(OpAMD64ANDQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
 	}
 	// match: (MOVQstore [off] {sym} ptr a:(ORQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem)
-	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a)
-	// result: (ORQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
+	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)
+	// result: (ORQconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -14125,18 +13229,18 @@
 		}
 		mem := l.Args[1]
 		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
+		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)) {
 			break
 		}
 		v.reset(OpAMD64ORQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
 	}
 	// match: (MOVQstore [off] {sym} ptr a:(XORQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem)
-	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a)
-	// result: (XORQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
+	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)
+	// result: (XORQconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -14152,92 +13256,11 @@
 		}
 		mem := l.Args[1]
 		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
+		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a)) {
 			break
 		}
 		v.reset(OpAMD64XORQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
-		v.Aux = symToAux(sym)
-		v.AddArg2(ptr, mem)
-		return true
-	}
-	// match: (MOVQstore [off] {sym} ptr a:(BTCQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem)
-	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a)
-	// result: (BTCQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		a := v_1
-		if a.Op != OpAMD64BTCQconst {
-			break
-		}
-		c := auxIntToInt8(a.AuxInt)
-		l := a.Args[0]
-		if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym {
-			break
-		}
-		mem := l.Args[1]
-		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
-			break
-		}
-		v.reset(OpAMD64BTCQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
-		v.Aux = symToAux(sym)
-		v.AddArg2(ptr, mem)
-		return true
-	}
-	// match: (MOVQstore [off] {sym} ptr a:(BTRQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem)
-	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a)
-	// result: (BTRQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		a := v_1
-		if a.Op != OpAMD64BTRQconst {
-			break
-		}
-		c := auxIntToInt8(a.AuxInt)
-		l := a.Args[0]
-		if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym {
-			break
-		}
-		mem := l.Args[1]
-		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
-			break
-		}
-		v.reset(OpAMD64BTRQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
-		v.Aux = symToAux(sym)
-		v.AddArg2(ptr, mem)
-		return true
-	}
-	// match: (MOVQstore [off] {sym} ptr a:(BTSQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem)
-	// cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a)
-	// result: (BTSQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		a := v_1
-		if a.Op != OpAMD64BTSQconst {
-			break
-		}
-		c := auxIntToInt8(a.AuxInt)
-		l := a.Args[0]
-		if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym {
-			break
-		}
-		mem := l.Args[1]
-		ptr2 := l.Args[0]
-		if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) {
-			break
-		}
-		v.reset(OpAMD64BTSQconstmodify)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -14311,7 +13334,7 @@
 	}
 	// match: (MOVQstoreconst [c] {s} p x:(MOVQstoreconst [c2] {s} p mem))
 	// cond: config.useSSE && x.Uses == 1 && c2.Off() + 8 == c.Off() && c.Val() == 0 && c2.Val() == 0 && clobber(x)
-	// result: (MOVOstore [c2.Off32()] {s} p (MOVOconst [0]) mem)
+	// result: (MOVOstorezero [c2.Off()] {s} p mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -14328,12 +13351,10 @@
 		if p != x.Args[0] || !(config.useSSE && x.Uses == 1 && c2.Off()+8 == c.Off() && c.Val() == 0 && c2.Val() == 0 && clobber(x)) {
 			break
 		}
-		v.reset(OpAMD64MOVOstore)
-		v.AuxInt = int32ToAuxInt(c2.Off32())
+		v.reset(OpAMD64MOVOstorezero)
+		v.AuxInt = int32ToAuxInt(c2.Off())
 		v.Aux = symToAux(s)
-		v0 := b.NewValue0(x.Pos, OpAMD64MOVOconst, types.TypeInt128)
-		v0.AuxInt = int128ToAuxInt(0)
-		v.AddArg3(p, v0, mem)
+		v.AddArg2(p, mem)
 		return true
 	}
 	// match: (MOVQstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem)
@@ -15118,7 +14139,7 @@
 		return true
 	}
 	// match: (MOVWstore [off] {sym} ptr (MOVLconst [c]) mem)
-	// result: (MOVWstoreconst [makeValAndOff32(int32(int16(c)),off)] {sym} ptr mem)
+	// result: (MOVWstoreconst [makeValAndOff(int32(int16(c)),off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -15129,13 +14150,13 @@
 		c := auxIntToInt32(v_1.AuxInt)
 		mem := v_2
 		v.reset(OpAMD64MOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(int16(c)), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(int16(c)), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
 	}
 	// match: (MOVWstore [off] {sym} ptr (MOVQconst [c]) mem)
-	// result: (MOVWstoreconst [makeValAndOff32(int32(int16(c)),off)] {sym} ptr mem)
+	// result: (MOVWstoreconst [makeValAndOff(int32(int16(c)),off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -15146,7 +14167,7 @@
 		c := auxIntToInt64(v_1.AuxInt)
 		mem := v_2
 		v.reset(OpAMD64MOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(int16(c)), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(int16(c)), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -15528,7 +14549,7 @@
 	}
 	// match: (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
 	// cond: x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x)
-	// result: (MOVLstoreconst [makeValAndOff64(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
+	// result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -15546,14 +14567,14 @@
 			break
 		}
 		v.reset(OpAMD64MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff64(a.Val()&0xffff|c.Val()<<16, a.Off()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p, mem)
 		return true
 	}
 	// match: (MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem))
 	// cond: x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x)
-	// result: (MOVLstoreconst [makeValAndOff64(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
+	// result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
 	for {
 		a := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -15571,7 +14592,7 @@
 			break
 		}
 		v.reset(OpAMD64MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff64(a.Val()&0xffff|c.Val()<<16, a.Off()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p, mem)
 		return true
@@ -18437,33 +17458,6 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	// match: (ORLmodify [off] {sym} ptr s:(SHLL (MOVLconst [1]) <t> x) mem)
-	// result: (BTSLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		s := v_1
-		if s.Op != OpAMD64SHLL {
-			break
-		}
-		t := s.Type
-		x := s.Args[1]
-		s_0 := s.Args[0]
-		if s_0.Op != OpAMD64MOVLconst || auxIntToInt32(s_0.AuxInt) != 1 {
-			break
-		}
-		mem := v_2
-		v.reset(OpAMD64BTSLmodify)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v0 := b.NewValue0(v.Pos, OpAMD64ANDLconst, t)
-		v0.AuxInt = int32ToAuxInt(31)
-		v0.AddArg(x)
-		v.AddArg3(ptr, v0, mem)
-		return true
-	}
 	// match: (ORLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
 	// cond: is32Bit(int64(off1)+int64(off2))
 	// result: (ORLmodify [off1+off2] {sym} base val mem)
@@ -18815,6 +17809,54 @@
 		}
 		break
 	}
+	// match: (ORQ (SHRQ lo bits) (SHLQ hi (NEGQ bits)))
+	// result: (SHRDQ lo hi bits)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpAMD64SHRQ {
+				continue
+			}
+			bits := v_0.Args[1]
+			lo := v_0.Args[0]
+			if v_1.Op != OpAMD64SHLQ {
+				continue
+			}
+			_ = v_1.Args[1]
+			hi := v_1.Args[0]
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpAMD64NEGQ || bits != v_1_1.Args[0] {
+				continue
+			}
+			v.reset(OpAMD64SHRDQ)
+			v.AddArg3(lo, hi, bits)
+			return true
+		}
+		break
+	}
+	// match: (ORQ (SHLQ lo bits) (SHRQ hi (NEGQ bits)))
+	// result: (SHLDQ lo hi bits)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpAMD64SHLQ {
+				continue
+			}
+			bits := v_0.Args[1]
+			lo := v_0.Args[0]
+			if v_1.Op != OpAMD64SHRQ {
+				continue
+			}
+			_ = v_1.Args[1]
+			hi := v_1.Args[0]
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpAMD64NEGQ || bits != v_1_1.Args[0] {
+				continue
+			}
+			v.reset(OpAMD64SHLDQ)
+			v.AddArg3(lo, hi, bits)
+			return true
+		}
+		break
+	}
 	// match: (ORQ (MOVQconst [c]) (MOVQconst [d]))
 	// result: (MOVQconst [c|d])
 	for {
@@ -20091,33 +19133,6 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	// match: (ORQmodify [off] {sym} ptr s:(SHLQ (MOVQconst [1]) <t> x) mem)
-	// result: (BTSQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		s := v_1
-		if s.Op != OpAMD64SHLQ {
-			break
-		}
-		t := s.Type
-		x := s.Args[1]
-		s_0 := s.Args[0]
-		if s_0.Op != OpAMD64MOVQconst || auxIntToInt64(s_0.AuxInt) != 1 {
-			break
-		}
-		mem := v_2
-		v.reset(OpAMD64BTSQmodify)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v0 := b.NewValue0(v.Pos, OpAMD64ANDQconst, t)
-		v0.AuxInt = int32ToAuxInt(63)
-		v0.AddArg(x)
-		v.AddArg3(ptr, v0, mem)
-		return true
-	}
 	// match: (ORQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
 	// cond: is32Bit(int64(off1)+int64(off2))
 	// result: (ORQmodify [off1+off2] {sym} base val mem)
@@ -27187,8 +26202,8 @@
 		break
 	}
 	// match: (TESTB l:(MOVBload {sym} [off] ptr mem) l2)
-	// cond: l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l)
-	// result: @l.Block (CMPBconstload {sym} [makeValAndOff64(0, int64(off))] ptr mem)
+	// cond: l == l2 && l.Uses == 2 && clobber(l)
+	// result: @l.Block (CMPBconstload {sym} [makeValAndOff(0, off)] ptr mem)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			l := v_0
@@ -27200,13 +26215,13 @@
 			mem := l.Args[1]
 			ptr := l.Args[0]
 			l2 := v_1
-			if !(l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l)) {
+			if !(l == l2 && l.Uses == 2 && clobber(l)) {
 				continue
 			}
 			b = l.Block
 			v0 := b.NewValue0(l.Pos, OpAMD64CMPBconstload, types.TypeFlags)
 			v.copyOf(v0)
-			v0.AuxInt = valAndOffToAuxInt(makeValAndOff64(0, int64(off)))
+			v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, off))
 			v0.Aux = symToAux(sym)
 			v0.AddArg2(ptr, mem)
 			return true
@@ -27255,8 +26270,8 @@
 		break
 	}
 	// match: (TESTL l:(MOVLload {sym} [off] ptr mem) l2)
-	// cond: l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l)
-	// result: @l.Block (CMPLconstload {sym} [makeValAndOff64(0, int64(off))] ptr mem)
+	// cond: l == l2 && l.Uses == 2 && clobber(l)
+	// result: @l.Block (CMPLconstload {sym} [makeValAndOff(0, off)] ptr mem)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			l := v_0
@@ -27268,19 +26283,46 @@
 			mem := l.Args[1]
 			ptr := l.Args[0]
 			l2 := v_1
-			if !(l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l)) {
+			if !(l == l2 && l.Uses == 2 && clobber(l)) {
 				continue
 			}
 			b = l.Block
 			v0 := b.NewValue0(l.Pos, OpAMD64CMPLconstload, types.TypeFlags)
 			v.copyOf(v0)
-			v0.AuxInt = valAndOffToAuxInt(makeValAndOff64(0, int64(off)))
+			v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, off))
 			v0.Aux = symToAux(sym)
 			v0.AddArg2(ptr, mem)
 			return true
 		}
 		break
 	}
+	// match: (TESTL a:(ANDLload [off] {sym} x ptr mem) a)
+	// cond: a.Uses == 2 && a.Block == v.Block && clobber(a)
+	// result: (TESTL (MOVLload <a.Type> [off] {sym} ptr mem) x)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			a := v_0
+			if a.Op != OpAMD64ANDLload {
+				continue
+			}
+			off := auxIntToInt32(a.AuxInt)
+			sym := auxToSym(a.Aux)
+			mem := a.Args[2]
+			x := a.Args[0]
+			ptr := a.Args[1]
+			if a != v_1 || !(a.Uses == 2 && a.Block == v.Block && clobber(a)) {
+				continue
+			}
+			v.reset(OpAMD64TESTL)
+			v0 := b.NewValue0(a.Pos, OpAMD64MOVLload, a.Type)
+			v0.AuxInt = int32ToAuxInt(off)
+			v0.Aux = symToAux(sym)
+			v0.AddArg2(ptr, mem)
+			v.AddArg2(v0, x)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64TESTLconst(v *Value) bool {
@@ -27360,8 +26402,8 @@
 		break
 	}
 	// match: (TESTQ l:(MOVQload {sym} [off] ptr mem) l2)
-	// cond: l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l)
-	// result: @l.Block (CMPQconstload {sym} [makeValAndOff64(0, int64(off))] ptr mem)
+	// cond: l == l2 && l.Uses == 2 && clobber(l)
+	// result: @l.Block (CMPQconstload {sym} [makeValAndOff(0, off)] ptr mem)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			l := v_0
@@ -27373,19 +26415,46 @@
 			mem := l.Args[1]
 			ptr := l.Args[0]
 			l2 := v_1
-			if !(l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l)) {
+			if !(l == l2 && l.Uses == 2 && clobber(l)) {
 				continue
 			}
 			b = l.Block
 			v0 := b.NewValue0(l.Pos, OpAMD64CMPQconstload, types.TypeFlags)
 			v.copyOf(v0)
-			v0.AuxInt = valAndOffToAuxInt(makeValAndOff64(0, int64(off)))
+			v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, off))
 			v0.Aux = symToAux(sym)
 			v0.AddArg2(ptr, mem)
 			return true
 		}
 		break
 	}
+	// match: (TESTQ a:(ANDQload [off] {sym} x ptr mem) a)
+	// cond: a.Uses == 2 && a.Block == v.Block && clobber(a)
+	// result: (TESTQ (MOVQload <a.Type> [off] {sym} ptr mem) x)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			a := v_0
+			if a.Op != OpAMD64ANDQload {
+				continue
+			}
+			off := auxIntToInt32(a.AuxInt)
+			sym := auxToSym(a.Aux)
+			mem := a.Args[2]
+			x := a.Args[0]
+			ptr := a.Args[1]
+			if a != v_1 || !(a.Uses == 2 && a.Block == v.Block && clobber(a)) {
+				continue
+			}
+			v.reset(OpAMD64TESTQ)
+			v0 := b.NewValue0(a.Pos, OpAMD64MOVQload, a.Type)
+			v0.AuxInt = int32ToAuxInt(off)
+			v0.Aux = symToAux(sym)
+			v0.AddArg2(ptr, mem)
+			v.AddArg2(v0, x)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64TESTQconst(v *Value) bool {
@@ -27473,8 +26542,8 @@
 		break
 	}
 	// match: (TESTW l:(MOVWload {sym} [off] ptr mem) l2)
-	// cond: l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l)
-	// result: @l.Block (CMPWconstload {sym} [makeValAndOff64(0, int64(off))] ptr mem)
+	// cond: l == l2 && l.Uses == 2 && clobber(l)
+	// result: @l.Block (CMPWconstload {sym} [makeValAndOff(0, off)] ptr mem)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			l := v_0
@@ -27486,13 +26555,13 @@
 			mem := l.Args[1]
 			ptr := l.Args[0]
 			l2 := v_1
-			if !(l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l)) {
+			if !(l == l2 && l.Uses == 2 && clobber(l)) {
 				continue
 			}
 			b = l.Block
 			v0 := b.NewValue0(l.Pos, OpAMD64CMPWconstload, types.TypeFlags)
 			v.copyOf(v0)
-			v0.AuxInt = valAndOffToAuxInt(makeValAndOff64(0, int64(off)))
+			v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, off))
 			v0.Aux = symToAux(sym)
 			v0.AddArg2(ptr, mem)
 			return true
@@ -28153,33 +27222,6 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	// match: (XORLmodify [off] {sym} ptr s:(SHLL (MOVLconst [1]) <t> x) mem)
-	// result: (BTCLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		s := v_1
-		if s.Op != OpAMD64SHLL {
-			break
-		}
-		t := s.Type
-		x := s.Args[1]
-		s_0 := s.Args[0]
-		if s_0.Op != OpAMD64MOVLconst || auxIntToInt32(s_0.AuxInt) != 1 {
-			break
-		}
-		mem := v_2
-		v.reset(OpAMD64BTCLmodify)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v0 := b.NewValue0(v.Pos, OpAMD64ANDLconst, t)
-		v0.AuxInt = int32ToAuxInt(31)
-		v0.AddArg(x)
-		v.AddArg3(ptr, v0, mem)
-		return true
-	}
 	// match: (XORLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
 	// cond: is32Bit(int64(off1)+int64(off2))
 	// result: (XORLmodify [off1+off2] {sym} base val mem)
@@ -28548,33 +27590,6 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	// match: (XORQmodify [off] {sym} ptr s:(SHLQ (MOVQconst [1]) <t> x) mem)
-	// result: (BTCQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		s := v_1
-		if s.Op != OpAMD64SHLQ {
-			break
-		}
-		t := s.Type
-		x := s.Args[1]
-		s_0 := s.Args[0]
-		if s_0.Op != OpAMD64MOVQconst || auxIntToInt64(s_0.AuxInt) != 1 {
-			break
-		}
-		mem := v_2
-		v.reset(OpAMD64BTCQmodify)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v0 := b.NewValue0(v.Pos, OpAMD64ANDQconst, t)
-		v0.AuxInt = int32ToAuxInt(63)
-		v0.AddArg(x)
-		v.AddArg3(ptr, v0, mem)
-		return true
-	}
 	// match: (XORQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
 	// cond: is32Bit(int64(off1)+int64(off2))
 	// result: (XORQmodify [off1+off2] {sym} base val mem)
@@ -30321,6 +29336,22 @@
 		return true
 	}
 }
+func rewriteValueAMD64_OpGetG(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (GetG mem)
+	// cond: !(buildcfg.Experiment.RegabiG && v.Block.Func.OwnAux.Fn.ABI() == obj.ABIInternal)
+	// result: (LoweredGetG mem)
+	for {
+		mem := v_0
+		if !(!(buildcfg.Experiment.RegabiG && v.Block.Func.OwnAux.Fn.ABI() == obj.ABIInternal)) {
+			break
+		}
+		v.reset(OpAMD64LoweredGetG)
+		v.AddArg(mem)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpHasCPUFeature(v *Value) bool {
 	b := v.Block
 	typ := &b.Func.Config.Types
@@ -33952,6 +32983,78 @@
 	}
 	return false
 }
+func rewriteValueAMD64_OpSelectN(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	config := b.Func.Config
+	// match: (SelectN [0] call:(CALLstatic {sym} s1:(MOVQstoreconst _ [sc] s2:(MOVQstore _ src s3:(MOVQstore _ dst mem)))))
+	// cond: sc.Val64() >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sc.Val64(), config) && clobber(s1, s2, s3, call)
+	// result: (Move [sc.Val64()] dst src mem)
+	for {
+		if auxIntToInt64(v.AuxInt) != 0 {
+			break
+		}
+		call := v_0
+		if call.Op != OpAMD64CALLstatic || len(call.Args) != 1 {
+			break
+		}
+		sym := auxToCall(call.Aux)
+		s1 := call.Args[0]
+		if s1.Op != OpAMD64MOVQstoreconst {
+			break
+		}
+		sc := auxIntToValAndOff(s1.AuxInt)
+		_ = s1.Args[1]
+		s2 := s1.Args[1]
+		if s2.Op != OpAMD64MOVQstore {
+			break
+		}
+		_ = s2.Args[2]
+		src := s2.Args[1]
+		s3 := s2.Args[2]
+		if s3.Op != OpAMD64MOVQstore {
+			break
+		}
+		mem := s3.Args[2]
+		dst := s3.Args[1]
+		if !(sc.Val64() >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sc.Val64(), config) && clobber(s1, s2, s3, call)) {
+			break
+		}
+		v.reset(OpMove)
+		v.AuxInt = int64ToAuxInt(sc.Val64())
+		v.AddArg3(dst, src, mem)
+		return true
+	}
+	// match: (SelectN [0] call:(CALLstatic {sym} dst src (MOVQconst [sz]) mem))
+	// cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && call.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(call)
+	// result: (Move [sz] dst src mem)
+	for {
+		if auxIntToInt64(v.AuxInt) != 0 {
+			break
+		}
+		call := v_0
+		if call.Op != OpAMD64CALLstatic || len(call.Args) != 4 {
+			break
+		}
+		sym := auxToCall(call.Aux)
+		mem := call.Args[3]
+		dst := call.Args[0]
+		src := call.Args[1]
+		call_2 := call.Args[2]
+		if call_2.Op != OpAMD64MOVQconst {
+			break
+		}
+		sz := auxIntToInt64(call_2.AuxInt)
+		if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && call.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(call)) {
+			break
+		}
+		v.reset(OpMove)
+		v.AuxInt = int64ToAuxInt(sz)
+		v.AddArg3(dst, src, mem)
+		return true
+	}
+	return false
+}
 func rewriteValueAMD64_OpSlicemask(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
@@ -34131,7 +33234,7 @@
 		return true
 	}
 	// match: (Zero [1] destptr mem)
-	// result: (MOVBstoreconst [makeValAndOff32(0,0)] destptr mem)
+	// result: (MOVBstoreconst [makeValAndOff(0,0)] destptr mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 1 {
 			break
@@ -34139,12 +33242,12 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(OpAMD64MOVBstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v.AddArg2(destptr, mem)
 		return true
 	}
 	// match: (Zero [2] destptr mem)
-	// result: (MOVWstoreconst [makeValAndOff32(0,0)] destptr mem)
+	// result: (MOVWstoreconst [makeValAndOff(0,0)] destptr mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 2 {
 			break
@@ -34152,12 +33255,12 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(OpAMD64MOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v.AddArg2(destptr, mem)
 		return true
 	}
 	// match: (Zero [4] destptr mem)
-	// result: (MOVLstoreconst [makeValAndOff32(0,0)] destptr mem)
+	// result: (MOVLstoreconst [makeValAndOff(0,0)] destptr mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 4 {
 			break
@@ -34165,12 +33268,12 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(OpAMD64MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v.AddArg2(destptr, mem)
 		return true
 	}
 	// match: (Zero [8] destptr mem)
-	// result: (MOVQstoreconst [makeValAndOff32(0,0)] destptr mem)
+	// result: (MOVQstoreconst [makeValAndOff(0,0)] destptr mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 8 {
 			break
@@ -34178,12 +33281,12 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(OpAMD64MOVQstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v.AddArg2(destptr, mem)
 		return true
 	}
 	// match: (Zero [3] destptr mem)
-	// result: (MOVBstoreconst [makeValAndOff32(0,2)] destptr (MOVWstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (MOVBstoreconst [makeValAndOff(0,2)] destptr (MOVWstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 3 {
 			break
@@ -34191,15 +33294,15 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(OpAMD64MOVBstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 2))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 2))
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVWstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v0.AddArg2(destptr, mem)
 		v.AddArg2(destptr, v0)
 		return true
 	}
 	// match: (Zero [5] destptr mem)
-	// result: (MOVBstoreconst [makeValAndOff32(0,4)] destptr (MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (MOVBstoreconst [makeValAndOff(0,4)] destptr (MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 5 {
 			break
@@ -34207,15 +33310,15 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(OpAMD64MOVBstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 4))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 4))
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVLstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v0.AddArg2(destptr, mem)
 		v.AddArg2(destptr, v0)
 		return true
 	}
 	// match: (Zero [6] destptr mem)
-	// result: (MOVWstoreconst [makeValAndOff32(0,4)] destptr (MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (MOVWstoreconst [makeValAndOff(0,4)] destptr (MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 6 {
 			break
@@ -34223,15 +33326,15 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(OpAMD64MOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 4))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 4))
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVLstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v0.AddArg2(destptr, mem)
 		v.AddArg2(destptr, v0)
 		return true
 	}
 	// match: (Zero [7] destptr mem)
-	// result: (MOVLstoreconst [makeValAndOff32(0,3)] destptr (MOVLstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (MOVLstoreconst [makeValAndOff(0,3)] destptr (MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 7 {
 			break
@@ -34239,16 +33342,16 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(OpAMD64MOVLstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 3))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 3))
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVLstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v0.AddArg2(destptr, mem)
 		v.AddArg2(destptr, v0)
 		return true
 	}
 	// match: (Zero [s] destptr mem)
 	// cond: s%8 != 0 && s > 8 && !config.useSSE
-	// result: (Zero [s-s%8] (OffPtr <destptr.Type> destptr [s%8]) (MOVQstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (Zero [s-s%8] (OffPtr <destptr.Type> destptr [s%8]) (MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		destptr := v_0
@@ -34262,14 +33365,14 @@
 		v0.AuxInt = int64ToAuxInt(s % 8)
 		v0.AddArg(destptr)
 		v1 := b.NewValue0(v.Pos, OpAMD64MOVQstoreconst, types.TypeMem)
-		v1.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v1.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v1.AddArg2(destptr, mem)
 		v.AddArg2(v0, v1)
 		return true
 	}
 	// match: (Zero [16] destptr mem)
 	// cond: !config.useSSE
-	// result: (MOVQstoreconst [makeValAndOff32(0,8)] destptr (MOVQstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (MOVQstoreconst [makeValAndOff(0,8)] destptr (MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 16 {
 			break
@@ -34280,16 +33383,16 @@
 			break
 		}
 		v.reset(OpAMD64MOVQstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 8))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 8))
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVQstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v0.AddArg2(destptr, mem)
 		v.AddArg2(destptr, v0)
 		return true
 	}
 	// match: (Zero [24] destptr mem)
 	// cond: !config.useSSE
-	// result: (MOVQstoreconst [makeValAndOff32(0,16)] destptr (MOVQstoreconst [makeValAndOff32(0,8)] destptr (MOVQstoreconst [makeValAndOff32(0,0)] destptr mem)))
+	// result: (MOVQstoreconst [makeValAndOff(0,16)] destptr (MOVQstoreconst [makeValAndOff(0,8)] destptr (MOVQstoreconst [makeValAndOff(0,0)] destptr mem)))
 	for {
 		if auxIntToInt64(v.AuxInt) != 24 {
 			break
@@ -34300,11 +33403,11 @@
 			break
 		}
 		v.reset(OpAMD64MOVQstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 16))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 16))
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVQstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 8))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 8))
 		v1 := b.NewValue0(v.Pos, OpAMD64MOVQstoreconst, types.TypeMem)
-		v1.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v1.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v1.AddArg2(destptr, mem)
 		v0.AddArg2(destptr, v1)
 		v.AddArg2(destptr, v0)
@@ -34312,7 +33415,7 @@
 	}
 	// match: (Zero [32] destptr mem)
 	// cond: !config.useSSE
-	// result: (MOVQstoreconst [makeValAndOff32(0,24)] destptr (MOVQstoreconst [makeValAndOff32(0,16)] destptr (MOVQstoreconst [makeValAndOff32(0,8)] destptr (MOVQstoreconst [makeValAndOff32(0,0)] destptr mem))))
+	// result: (MOVQstoreconst [makeValAndOff(0,24)] destptr (MOVQstoreconst [makeValAndOff(0,16)] destptr (MOVQstoreconst [makeValAndOff(0,8)] destptr (MOVQstoreconst [makeValAndOff(0,0)] destptr mem))))
 	for {
 		if auxIntToInt64(v.AuxInt) != 32 {
 			break
@@ -34323,13 +33426,13 @@
 			break
 		}
 		v.reset(OpAMD64MOVQstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 24))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 24))
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVQstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 16))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 16))
 		v1 := b.NewValue0(v.Pos, OpAMD64MOVQstoreconst, types.TypeMem)
-		v1.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 8))
+		v1.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 8))
 		v2 := b.NewValue0(v.Pos, OpAMD64MOVQstoreconst, types.TypeMem)
-		v2.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v2.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v2.AddArg2(destptr, mem)
 		v1.AddArg2(destptr, v2)
 		v0.AddArg2(destptr, v1)
@@ -34338,7 +33441,7 @@
 	}
 	// match: (Zero [s] destptr mem)
 	// cond: s > 8 && s < 16 && config.useSSE
-	// result: (MOVQstoreconst [makeValAndOff32(0,int32(s-8))] destptr (MOVQstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (MOVQstoreconst [makeValAndOff(0,int32(s-8))] destptr (MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		destptr := v_0
@@ -34347,16 +33450,16 @@
 			break
 		}
 		v.reset(OpAMD64MOVQstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, int32(s-8)))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, int32(s-8)))
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVQstoreconst, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v0.AddArg2(destptr, mem)
 		v.AddArg2(destptr, 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))
+	// result: (Zero [s-s%16] (OffPtr <destptr.Type> destptr [s%16]) (MOVOstorezero destptr mem))
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		destptr := v_0
@@ -34369,16 +33472,14 @@
 		v0 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
 		v0.AuxInt = int64ToAuxInt(s % 16)
 		v0.AddArg(destptr)
-		v1 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
-		v2 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
-		v2.AuxInt = int128ToAuxInt(0)
-		v1.AddArg3(destptr, v2, mem)
+		v1 := b.NewValue0(v.Pos, OpAMD64MOVOstorezero, types.TypeMem)
+		v1.AddArg2(destptr, mem)
 		v.AddArg2(v0, v1)
 		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]) (MOVQstoreconst [makeValAndOff32(0,0)] destptr mem))
+	// result: (Zero [s-s%16] (OffPtr <destptr.Type> destptr [s%16]) (MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		destptr := v_0
@@ -34392,14 +33493,14 @@
 		v0.AuxInt = int64ToAuxInt(s % 16)
 		v0.AddArg(destptr)
 		v1 := b.NewValue0(v.Pos, OpAMD64MOVQstoreconst, types.TypeMem)
-		v1.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 0))
+		v1.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 0))
 		v1.AddArg2(destptr, mem)
 		v.AddArg2(v0, v1)
 		return true
 	}
 	// match: (Zero [16] destptr mem)
 	// cond: config.useSSE
-	// result: (MOVOstore destptr (MOVOconst [0]) mem)
+	// result: (MOVOstorezero destptr mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 16 {
 			break
@@ -34409,15 +33510,13 @@
 		if !(config.useSSE) {
 			break
 		}
-		v.reset(OpAMD64MOVOstore)
-		v0 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
-		v0.AuxInt = int128ToAuxInt(0)
-		v.AddArg3(destptr, v0, mem)
+		v.reset(OpAMD64MOVOstorezero)
+		v.AddArg2(destptr, 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))
+	// result: (MOVOstorezero (OffPtr <destptr.Type> destptr [16]) (MOVOstorezero destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 32 {
 			break
@@ -34427,20 +33526,18 @@
 		if !(config.useSSE) {
 			break
 		}
-		v.reset(OpAMD64MOVOstore)
+		v.reset(OpAMD64MOVOstorezero)
 		v0 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
 		v0.AuxInt = int64ToAuxInt(16)
 		v0.AddArg(destptr)
-		v1 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
-		v1.AuxInt = int128ToAuxInt(0)
-		v2 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
-		v2.AddArg3(destptr, v1, mem)
-		v.AddArg3(v0, v1, v2)
+		v1 := b.NewValue0(v.Pos, OpAMD64MOVOstorezero, types.TypeMem)
+		v1.AddArg2(destptr, mem)
+		v.AddArg2(v0, v1)
 		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)))
+	// result: (MOVOstorezero (OffPtr <destptr.Type> destptr [32]) (MOVOstorezero (OffPtr <destptr.Type> destptr [16]) (MOVOstorezero destptr mem)))
 	for {
 		if auxIntToInt64(v.AuxInt) != 48 {
 			break
@@ -34450,25 +33547,23 @@
 		if !(config.useSSE) {
 			break
 		}
-		v.reset(OpAMD64MOVOstore)
+		v.reset(OpAMD64MOVOstorezero)
 		v0 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
 		v0.AuxInt = int64ToAuxInt(32)
 		v0.AddArg(destptr)
-		v1 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
-		v1.AuxInt = int128ToAuxInt(0)
-		v2 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
-		v3 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
-		v3.AuxInt = int64ToAuxInt(16)
-		v3.AddArg(destptr)
-		v4 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
-		v4.AddArg3(destptr, v1, mem)
-		v2.AddArg3(v3, v1, v4)
-		v.AddArg3(v0, v1, v2)
+		v1 := b.NewValue0(v.Pos, OpAMD64MOVOstorezero, types.TypeMem)
+		v2 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
+		v2.AuxInt = int64ToAuxInt(16)
+		v2.AddArg(destptr)
+		v3 := b.NewValue0(v.Pos, OpAMD64MOVOstorezero, types.TypeMem)
+		v3.AddArg2(destptr, mem)
+		v1.AddArg2(v2, v3)
+		v.AddArg2(v0, v1)
 		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))))
+	// result: (MOVOstorezero (OffPtr <destptr.Type> destptr [48]) (MOVOstorezero (OffPtr <destptr.Type> destptr [32]) (MOVOstorezero (OffPtr <destptr.Type> destptr [16]) (MOVOstorezero destptr mem))))
 	for {
 		if auxIntToInt64(v.AuxInt) != 64 {
 			break
@@ -34478,30 +33573,28 @@
 		if !(config.useSSE) {
 			break
 		}
-		v.reset(OpAMD64MOVOstore)
+		v.reset(OpAMD64MOVOstorezero)
 		v0 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
 		v0.AuxInt = int64ToAuxInt(48)
 		v0.AddArg(destptr)
-		v1 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
-		v1.AuxInt = int128ToAuxInt(0)
-		v2 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
-		v3 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
-		v3.AuxInt = int64ToAuxInt(32)
-		v3.AddArg(destptr)
-		v4 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
-		v5 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
-		v5.AuxInt = int64ToAuxInt(16)
-		v5.AddArg(destptr)
-		v6 := b.NewValue0(v.Pos, OpAMD64MOVOstore, types.TypeMem)
-		v6.AddArg3(destptr, v1, mem)
-		v4.AddArg3(v5, v1, v6)
-		v2.AddArg3(v3, v1, v4)
-		v.AddArg3(v0, v1, v2)
+		v1 := b.NewValue0(v.Pos, OpAMD64MOVOstorezero, types.TypeMem)
+		v2 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
+		v2.AuxInt = int64ToAuxInt(32)
+		v2.AddArg(destptr)
+		v3 := b.NewValue0(v.Pos, OpAMD64MOVOstorezero, types.TypeMem)
+		v4 := b.NewValue0(v.Pos, OpOffPtr, destptr.Type)
+		v4.AuxInt = int64ToAuxInt(16)
+		v4.AddArg(destptr)
+		v5 := b.NewValue0(v.Pos, OpAMD64MOVOstorezero, types.TypeMem)
+		v5.AddArg2(destptr, mem)
+		v3.AddArg2(v4, v5)
+		v1.AddArg2(v2, v3)
+		v.AddArg2(v0, v1)
 		return true
 	}
 	// match: (Zero [s] destptr mem)
 	// cond: s > 64 && s <= 1024 && s%16 == 0 && !config.noDuffDevice
-	// result: (DUFFZERO [s] destptr (MOVOconst [0]) mem)
+	// result: (DUFFZERO [s] destptr mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		destptr := v_0
@@ -34511,9 +33604,7 @@
 		}
 		v.reset(OpAMD64DUFFZERO)
 		v.AuxInt = int64ToAuxInt(s)
-		v0 := b.NewValue0(v.Pos, OpAMD64MOVOconst, types.TypeInt128)
-		v0.AuxInt = int128ToAuxInt(0)
-		v.AddArg3(destptr, v0, mem)
+		v.AddArg2(destptr, mem)
 		return true
 	}
 	// match: (Zero [s] destptr mem)
diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64splitload.go b/src/cmd/compile/internal/ssa/rewriteAMD64splitload.go
index 65bfec0..ae50aaa 100644
--- a/src/cmd/compile/internal/ssa/rewriteAMD64splitload.go
+++ b/src/cmd/compile/internal/ssa/rewriteAMD64splitload.go
@@ -59,7 +59,7 @@
 	typ := &b.Func.Config.Types
 	// match: (CMPBconstload {sym} [vo] ptr mem)
 	// cond: vo.Val() == 0
-	// result: (TESTB x:(MOVBload {sym} [vo.Off32()] ptr mem) x)
+	// result: (TESTB x:(MOVBload {sym} [vo.Off()] ptr mem) x)
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -70,7 +70,7 @@
 		}
 		v.reset(OpAMD64TESTB)
 		x := b.NewValue0(v.Pos, OpAMD64MOVBload, typ.UInt8)
-		x.AuxInt = int32ToAuxInt(vo.Off32())
+		x.AuxInt = int32ToAuxInt(vo.Off())
 		x.Aux = symToAux(sym)
 		x.AddArg2(ptr, mem)
 		v.AddArg2(x, x)
@@ -78,7 +78,7 @@
 	}
 	// match: (CMPBconstload {sym} [vo] ptr mem)
 	// cond: vo.Val() != 0
-	// result: (CMPBconst (MOVBload {sym} [vo.Off32()] ptr mem) [vo.Val8()])
+	// result: (CMPBconst (MOVBload {sym} [vo.Off()] ptr mem) [vo.Val8()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -90,7 +90,7 @@
 		v.reset(OpAMD64CMPBconst)
 		v.AuxInt = int8ToAuxInt(vo.Val8())
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVBload, typ.UInt8)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		v.AddArg(v0)
@@ -106,7 +106,7 @@
 	typ := &b.Func.Config.Types
 	// match: (CMPBconstloadidx1 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() == 0
-	// result: (TESTB x:(MOVBloadidx1 {sym} [vo.Off32()] ptr idx mem) x)
+	// result: (TESTB x:(MOVBloadidx1 {sym} [vo.Off()] ptr idx mem) x)
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -118,7 +118,7 @@
 		}
 		v.reset(OpAMD64TESTB)
 		x := b.NewValue0(v.Pos, OpAMD64MOVBloadidx1, typ.UInt8)
-		x.AuxInt = int32ToAuxInt(vo.Off32())
+		x.AuxInt = int32ToAuxInt(vo.Off())
 		x.Aux = symToAux(sym)
 		x.AddArg3(ptr, idx, mem)
 		v.AddArg2(x, x)
@@ -126,7 +126,7 @@
 	}
 	// match: (CMPBconstloadidx1 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() != 0
-	// result: (CMPBconst (MOVBloadidx1 {sym} [vo.Off32()] ptr idx mem) [vo.Val8()])
+	// result: (CMPBconst (MOVBloadidx1 {sym} [vo.Off()] ptr idx mem) [vo.Val8()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -139,7 +139,7 @@
 		v.reset(OpAMD64CMPBconst)
 		v.AuxInt = int8ToAuxInt(vo.Val8())
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVBloadidx1, typ.UInt8)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg3(ptr, idx, mem)
 		v.AddArg(v0)
@@ -202,7 +202,7 @@
 	typ := &b.Func.Config.Types
 	// match: (CMPLconstload {sym} [vo] ptr mem)
 	// cond: vo.Val() == 0
-	// result: (TESTL x:(MOVLload {sym} [vo.Off32()] ptr mem) x)
+	// result: (TESTL x:(MOVLload {sym} [vo.Off()] ptr mem) x)
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -213,7 +213,7 @@
 		}
 		v.reset(OpAMD64TESTL)
 		x := b.NewValue0(v.Pos, OpAMD64MOVLload, typ.UInt32)
-		x.AuxInt = int32ToAuxInt(vo.Off32())
+		x.AuxInt = int32ToAuxInt(vo.Off())
 		x.Aux = symToAux(sym)
 		x.AddArg2(ptr, mem)
 		v.AddArg2(x, x)
@@ -221,7 +221,7 @@
 	}
 	// match: (CMPLconstload {sym} [vo] ptr mem)
 	// cond: vo.Val() != 0
-	// result: (CMPLconst (MOVLload {sym} [vo.Off32()] ptr mem) [vo.Val32()])
+	// result: (CMPLconst (MOVLload {sym} [vo.Off()] ptr mem) [vo.Val()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -231,9 +231,9 @@
 			break
 		}
 		v.reset(OpAMD64CMPLconst)
-		v.AuxInt = int32ToAuxInt(vo.Val32())
+		v.AuxInt = int32ToAuxInt(vo.Val())
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVLload, typ.UInt32)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		v.AddArg(v0)
@@ -249,7 +249,7 @@
 	typ := &b.Func.Config.Types
 	// match: (CMPLconstloadidx1 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() == 0
-	// result: (TESTL x:(MOVLloadidx1 {sym} [vo.Off32()] ptr idx mem) x)
+	// result: (TESTL x:(MOVLloadidx1 {sym} [vo.Off()] ptr idx mem) x)
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -261,7 +261,7 @@
 		}
 		v.reset(OpAMD64TESTL)
 		x := b.NewValue0(v.Pos, OpAMD64MOVLloadidx1, typ.UInt32)
-		x.AuxInt = int32ToAuxInt(vo.Off32())
+		x.AuxInt = int32ToAuxInt(vo.Off())
 		x.Aux = symToAux(sym)
 		x.AddArg3(ptr, idx, mem)
 		v.AddArg2(x, x)
@@ -269,7 +269,7 @@
 	}
 	// match: (CMPLconstloadidx1 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() != 0
-	// result: (CMPLconst (MOVLloadidx1 {sym} [vo.Off32()] ptr idx mem) [vo.Val32()])
+	// result: (CMPLconst (MOVLloadidx1 {sym} [vo.Off()] ptr idx mem) [vo.Val()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -280,9 +280,9 @@
 			break
 		}
 		v.reset(OpAMD64CMPLconst)
-		v.AuxInt = int32ToAuxInt(vo.Val32())
+		v.AuxInt = int32ToAuxInt(vo.Val())
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVLloadidx1, typ.UInt32)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg3(ptr, idx, mem)
 		v.AddArg(v0)
@@ -298,7 +298,7 @@
 	typ := &b.Func.Config.Types
 	// match: (CMPLconstloadidx4 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() == 0
-	// result: (TESTL x:(MOVLloadidx4 {sym} [vo.Off32()] ptr idx mem) x)
+	// result: (TESTL x:(MOVLloadidx4 {sym} [vo.Off()] ptr idx mem) x)
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -310,7 +310,7 @@
 		}
 		v.reset(OpAMD64TESTL)
 		x := b.NewValue0(v.Pos, OpAMD64MOVLloadidx4, typ.UInt32)
-		x.AuxInt = int32ToAuxInt(vo.Off32())
+		x.AuxInt = int32ToAuxInt(vo.Off())
 		x.Aux = symToAux(sym)
 		x.AddArg3(ptr, idx, mem)
 		v.AddArg2(x, x)
@@ -318,7 +318,7 @@
 	}
 	// match: (CMPLconstloadidx4 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() != 0
-	// result: (CMPLconst (MOVLloadidx4 {sym} [vo.Off32()] ptr idx mem) [vo.Val32()])
+	// result: (CMPLconst (MOVLloadidx4 {sym} [vo.Off()] ptr idx mem) [vo.Val()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -329,9 +329,9 @@
 			break
 		}
 		v.reset(OpAMD64CMPLconst)
-		v.AuxInt = int32ToAuxInt(vo.Val32())
+		v.AuxInt = int32ToAuxInt(vo.Val())
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVLloadidx4, typ.UInt32)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg3(ptr, idx, mem)
 		v.AddArg(v0)
@@ -419,7 +419,7 @@
 	typ := &b.Func.Config.Types
 	// match: (CMPQconstload {sym} [vo] ptr mem)
 	// cond: vo.Val() == 0
-	// result: (TESTQ x:(MOVQload {sym} [vo.Off32()] ptr mem) x)
+	// result: (TESTQ x:(MOVQload {sym} [vo.Off()] ptr mem) x)
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -430,7 +430,7 @@
 		}
 		v.reset(OpAMD64TESTQ)
 		x := b.NewValue0(v.Pos, OpAMD64MOVQload, typ.UInt64)
-		x.AuxInt = int32ToAuxInt(vo.Off32())
+		x.AuxInt = int32ToAuxInt(vo.Off())
 		x.Aux = symToAux(sym)
 		x.AddArg2(ptr, mem)
 		v.AddArg2(x, x)
@@ -438,7 +438,7 @@
 	}
 	// match: (CMPQconstload {sym} [vo] ptr mem)
 	// cond: vo.Val() != 0
-	// result: (CMPQconst (MOVQload {sym} [vo.Off32()] ptr mem) [vo.Val32()])
+	// result: (CMPQconst (MOVQload {sym} [vo.Off()] ptr mem) [vo.Val()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -448,9 +448,9 @@
 			break
 		}
 		v.reset(OpAMD64CMPQconst)
-		v.AuxInt = int32ToAuxInt(vo.Val32())
+		v.AuxInt = int32ToAuxInt(vo.Val())
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVQload, typ.UInt64)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		v.AddArg(v0)
@@ -466,7 +466,7 @@
 	typ := &b.Func.Config.Types
 	// match: (CMPQconstloadidx1 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() == 0
-	// result: (TESTQ x:(MOVQloadidx1 {sym} [vo.Off32()] ptr idx mem) x)
+	// result: (TESTQ x:(MOVQloadidx1 {sym} [vo.Off()] ptr idx mem) x)
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -478,7 +478,7 @@
 		}
 		v.reset(OpAMD64TESTQ)
 		x := b.NewValue0(v.Pos, OpAMD64MOVQloadidx1, typ.UInt64)
-		x.AuxInt = int32ToAuxInt(vo.Off32())
+		x.AuxInt = int32ToAuxInt(vo.Off())
 		x.Aux = symToAux(sym)
 		x.AddArg3(ptr, idx, mem)
 		v.AddArg2(x, x)
@@ -486,7 +486,7 @@
 	}
 	// match: (CMPQconstloadidx1 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() != 0
-	// result: (CMPQconst (MOVQloadidx1 {sym} [vo.Off32()] ptr idx mem) [vo.Val32()])
+	// result: (CMPQconst (MOVQloadidx1 {sym} [vo.Off()] ptr idx mem) [vo.Val()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -497,9 +497,9 @@
 			break
 		}
 		v.reset(OpAMD64CMPQconst)
-		v.AuxInt = int32ToAuxInt(vo.Val32())
+		v.AuxInt = int32ToAuxInt(vo.Val())
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVQloadidx1, typ.UInt64)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg3(ptr, idx, mem)
 		v.AddArg(v0)
@@ -515,7 +515,7 @@
 	typ := &b.Func.Config.Types
 	// match: (CMPQconstloadidx8 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() == 0
-	// result: (TESTQ x:(MOVQloadidx8 {sym} [vo.Off32()] ptr idx mem) x)
+	// result: (TESTQ x:(MOVQloadidx8 {sym} [vo.Off()] ptr idx mem) x)
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -527,7 +527,7 @@
 		}
 		v.reset(OpAMD64TESTQ)
 		x := b.NewValue0(v.Pos, OpAMD64MOVQloadidx8, typ.UInt64)
-		x.AuxInt = int32ToAuxInt(vo.Off32())
+		x.AuxInt = int32ToAuxInt(vo.Off())
 		x.Aux = symToAux(sym)
 		x.AddArg3(ptr, idx, mem)
 		v.AddArg2(x, x)
@@ -535,7 +535,7 @@
 	}
 	// match: (CMPQconstloadidx8 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() != 0
-	// result: (CMPQconst (MOVQloadidx8 {sym} [vo.Off32()] ptr idx mem) [vo.Val32()])
+	// result: (CMPQconst (MOVQloadidx8 {sym} [vo.Off()] ptr idx mem) [vo.Val()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -546,9 +546,9 @@
 			break
 		}
 		v.reset(OpAMD64CMPQconst)
-		v.AuxInt = int32ToAuxInt(vo.Val32())
+		v.AuxInt = int32ToAuxInt(vo.Val())
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVQloadidx8, typ.UInt64)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg3(ptr, idx, mem)
 		v.AddArg(v0)
@@ -636,7 +636,7 @@
 	typ := &b.Func.Config.Types
 	// match: (CMPWconstload {sym} [vo] ptr mem)
 	// cond: vo.Val() == 0
-	// result: (TESTW x:(MOVWload {sym} [vo.Off32()] ptr mem) x)
+	// result: (TESTW x:(MOVWload {sym} [vo.Off()] ptr mem) x)
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -647,7 +647,7 @@
 		}
 		v.reset(OpAMD64TESTW)
 		x := b.NewValue0(v.Pos, OpAMD64MOVWload, typ.UInt16)
-		x.AuxInt = int32ToAuxInt(vo.Off32())
+		x.AuxInt = int32ToAuxInt(vo.Off())
 		x.Aux = symToAux(sym)
 		x.AddArg2(ptr, mem)
 		v.AddArg2(x, x)
@@ -655,7 +655,7 @@
 	}
 	// match: (CMPWconstload {sym} [vo] ptr mem)
 	// cond: vo.Val() != 0
-	// result: (CMPWconst (MOVWload {sym} [vo.Off32()] ptr mem) [vo.Val16()])
+	// result: (CMPWconst (MOVWload {sym} [vo.Off()] ptr mem) [vo.Val16()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -667,7 +667,7 @@
 		v.reset(OpAMD64CMPWconst)
 		v.AuxInt = int16ToAuxInt(vo.Val16())
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVWload, typ.UInt16)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg2(ptr, mem)
 		v.AddArg(v0)
@@ -683,7 +683,7 @@
 	typ := &b.Func.Config.Types
 	// match: (CMPWconstloadidx1 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() == 0
-	// result: (TESTW x:(MOVWloadidx1 {sym} [vo.Off32()] ptr idx mem) x)
+	// result: (TESTW x:(MOVWloadidx1 {sym} [vo.Off()] ptr idx mem) x)
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -695,7 +695,7 @@
 		}
 		v.reset(OpAMD64TESTW)
 		x := b.NewValue0(v.Pos, OpAMD64MOVWloadidx1, typ.UInt16)
-		x.AuxInt = int32ToAuxInt(vo.Off32())
+		x.AuxInt = int32ToAuxInt(vo.Off())
 		x.Aux = symToAux(sym)
 		x.AddArg3(ptr, idx, mem)
 		v.AddArg2(x, x)
@@ -703,7 +703,7 @@
 	}
 	// match: (CMPWconstloadidx1 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() != 0
-	// result: (CMPWconst (MOVWloadidx1 {sym} [vo.Off32()] ptr idx mem) [vo.Val16()])
+	// result: (CMPWconst (MOVWloadidx1 {sym} [vo.Off()] ptr idx mem) [vo.Val16()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -716,7 +716,7 @@
 		v.reset(OpAMD64CMPWconst)
 		v.AuxInt = int16ToAuxInt(vo.Val16())
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVWloadidx1, typ.UInt16)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg3(ptr, idx, mem)
 		v.AddArg(v0)
@@ -732,7 +732,7 @@
 	typ := &b.Func.Config.Types
 	// match: (CMPWconstloadidx2 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() == 0
-	// result: (TESTW x:(MOVWloadidx2 {sym} [vo.Off32()] ptr idx mem) x)
+	// result: (TESTW x:(MOVWloadidx2 {sym} [vo.Off()] ptr idx mem) x)
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -744,7 +744,7 @@
 		}
 		v.reset(OpAMD64TESTW)
 		x := b.NewValue0(v.Pos, OpAMD64MOVWloadidx2, typ.UInt16)
-		x.AuxInt = int32ToAuxInt(vo.Off32())
+		x.AuxInt = int32ToAuxInt(vo.Off())
 		x.Aux = symToAux(sym)
 		x.AddArg3(ptr, idx, mem)
 		v.AddArg2(x, x)
@@ -752,7 +752,7 @@
 	}
 	// match: (CMPWconstloadidx2 {sym} [vo] ptr idx mem)
 	// cond: vo.Val() != 0
-	// result: (CMPWconst (MOVWloadidx2 {sym} [vo.Off32()] ptr idx mem) [vo.Val16()])
+	// result: (CMPWconst (MOVWloadidx2 {sym} [vo.Off()] ptr idx mem) [vo.Val16()])
 	for {
 		vo := auxIntToValAndOff(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -765,7 +765,7 @@
 		v.reset(OpAMD64CMPWconst)
 		v.AuxInt = int16ToAuxInt(vo.Val16())
 		v0 := b.NewValue0(v.Pos, OpAMD64MOVWloadidx2, typ.UInt16)
-		v0.AuxInt = int32ToAuxInt(vo.Off32())
+		v0.AuxInt = int32ToAuxInt(vo.Off())
 		v0.Aux = symToAux(sym)
 		v0.AddArg3(ptr, idx, mem)
 		v.AddArg(v0)
@@ -847,7 +847,5 @@
 	}
 }
 func rewriteBlockAMD64splitload(b *Block) bool {
-	switch b.Kind {
-	}
 	return false
 }
diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go
index d9d439f..febb556 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM.go
@@ -3,7 +3,7 @@
 
 package ssa
 
-import "cmd/internal/objabi"
+import "internal/buildcfg"
 import "cmd/compile/internal/types"
 
 func rewriteValueARM(v *Value) bool {
@@ -202,6 +202,8 @@
 		return rewriteValueARM_OpARMMOVWloadshiftRA(v)
 	case OpARMMOVWloadshiftRL:
 		return rewriteValueARM_OpARMMOVWloadshiftRL(v)
+	case OpARMMOVWnop:
+		return rewriteValueARM_OpARMMOVWnop(v)
 	case OpARMMOVWreg:
 		return rewriteValueARM_OpARMMOVWreg(v)
 	case OpARMMOVWstore:
@@ -821,6 +823,9 @@
 	case OpSqrt:
 		v.Op = OpARMSQRTD
 		return true
+	case OpSqrt32:
+		v.Op = OpARMSQRTF
+		return true
 	case OpStaticCall:
 		v.Op = OpARMCALLstatic
 		return true
@@ -1470,7 +1475,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (ADDD a (MULD x y))
-	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// cond: a.Uses == 1 && buildcfg.GOARM >= 6
 	// result: (MULAD a x y)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -1480,7 +1485,7 @@
 			}
 			y := v_1.Args[1]
 			x := v_1.Args[0]
-			if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
 				continue
 			}
 			v.reset(OpARMMULAD)
@@ -1490,7 +1495,7 @@
 		break
 	}
 	// match: (ADDD a (NMULD x y))
-	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// cond: a.Uses == 1 && buildcfg.GOARM >= 6
 	// result: (MULSD a x y)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -1500,7 +1505,7 @@
 			}
 			y := v_1.Args[1]
 			x := v_1.Args[0]
-			if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
 				continue
 			}
 			v.reset(OpARMMULSD)
@@ -1515,7 +1520,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (ADDF a (MULF x y))
-	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// cond: a.Uses == 1 && buildcfg.GOARM >= 6
 	// result: (MULAF a x y)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -1525,7 +1530,7 @@
 			}
 			y := v_1.Args[1]
 			x := v_1.Args[0]
-			if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
 				continue
 			}
 			v.reset(OpARMMULAF)
@@ -1535,7 +1540,7 @@
 		break
 	}
 	// match: (ADDF a (NMULF x y))
-	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// cond: a.Uses == 1 && buildcfg.GOARM >= 6
 	// result: (MULSF a x y)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -1545,7 +1550,7 @@
 			}
 			y := v_1.Args[1]
 			x := v_1.Args[0]
-			if !(a.Uses == 1 && objabi.GOARM >= 6) {
+			if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
 				continue
 			}
 			v.reset(OpARMMULSF)
@@ -1941,12 +1946,12 @@
 		return true
 	}
 	// match: (ADDconst [c] x)
-	// cond: objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff
+	// cond: buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff
 	// result: (SUBconst [-c] x)
 	for {
 		c := auxIntToInt32(v.AuxInt)
 		x := v_0
-		if !(objabi.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && uint32(-c) <= 0xffff) {
+		if !(buildcfg.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && uint32(-c) <= 0xffff) {
 			break
 		}
 		v.reset(OpARMSUBconst)
@@ -2077,7 +2082,7 @@
 		return true
 	}
 	// match: (ADDshiftLL <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x)
-	// cond: objabi.GOARM>=6
+	// cond: buildcfg.GOARM>=6
 	// result: (REV16 x)
 	for {
 		if v.Type != typ.UInt16 || auxIntToInt32(v.AuxInt) != 8 || v_0.Op != OpARMSRLconst || v_0.Type != typ.UInt16 || auxIntToInt32(v_0.AuxInt) != 24 {
@@ -2088,7 +2093,7 @@
 			break
 		}
 		x := v_0_0.Args[0]
-		if x != v_1 || !(objabi.GOARM >= 6) {
+		if x != v_1 || !(buildcfg.GOARM >= 6) {
 			break
 		}
 		v.reset(OpARMREV16)
@@ -2533,12 +2538,12 @@
 		return true
 	}
 	// match: (ANDconst [c] x)
-	// cond: objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff
+	// cond: buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff
 	// result: (BICconst [int32(^uint32(c))] x)
 	for {
 		c := auxIntToInt32(v.AuxInt)
 		x := v_0
-		if !(objabi.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && ^uint32(c) <= 0xffff) {
+		if !(buildcfg.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && ^uint32(c) <= 0xffff) {
 			break
 		}
 		v.reset(OpARMBICconst)
@@ -3028,12 +3033,12 @@
 		return true
 	}
 	// match: (BICconst [c] x)
-	// cond: objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff
+	// cond: buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff
 	// result: (ANDconst [int32(^uint32(c))] x)
 	for {
 		c := auxIntToInt32(v.AuxInt)
 		x := v_0
-		if !(objabi.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && ^uint32(c) <= 0xffff) {
+		if !(buildcfg.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && ^uint32(c) <= 0xffff) {
 			break
 		}
 		v.reset(OpARMANDconst)
@@ -3728,12 +3733,12 @@
 		return true
 	}
 	// match: (CMP x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMP y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpARMInvertFlags)
@@ -6501,6 +6506,21 @@
 	}
 	return false
 }
+func rewriteValueARM_OpARMMOVWnop(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (MOVWnop (MOVWconst [c]))
+	// result: (MOVWconst [c])
+	for {
+		if v_0.Op != OpARMMOVWconst {
+			break
+		}
+		c := auxIntToInt32(v_0.AuxInt)
+		v.reset(OpARMMOVWconst)
+		v.AuxInt = int32ToAuxInt(c)
+		return true
+	}
+	return false
+}
 func rewriteValueARM_OpARMMOVWreg(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (MOVWreg x)
@@ -7521,7 +7541,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (MULD (NEGD x) y)
-	// cond: objabi.GOARM >= 6
+	// cond: buildcfg.GOARM >= 6
 	// result: (NMULD x y)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -7530,7 +7550,7 @@
 			}
 			x := v_0.Args[0]
 			y := v_1
-			if !(objabi.GOARM >= 6) {
+			if !(buildcfg.GOARM >= 6) {
 				continue
 			}
 			v.reset(OpARMNMULD)
@@ -7545,7 +7565,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (MULF (NEGF x) y)
-	// cond: objabi.GOARM >= 6
+	// cond: buildcfg.GOARM >= 6
 	// result: (NMULF x y)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -7554,7 +7574,7 @@
 			}
 			x := v_0.Args[0]
 			y := v_1
-			if !(objabi.GOARM >= 6) {
+			if !(buildcfg.GOARM >= 6) {
 				continue
 			}
 			v.reset(OpARMNMULF)
@@ -8166,7 +8186,7 @@
 func rewriteValueARM_OpARMNEGD(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (NEGD (MULD x y))
-	// cond: objabi.GOARM >= 6
+	// cond: buildcfg.GOARM >= 6
 	// result: (NMULD x y)
 	for {
 		if v_0.Op != OpARMMULD {
@@ -8174,7 +8194,7 @@
 		}
 		y := v_0.Args[1]
 		x := v_0.Args[0]
-		if !(objabi.GOARM >= 6) {
+		if !(buildcfg.GOARM >= 6) {
 			break
 		}
 		v.reset(OpARMNMULD)
@@ -8186,7 +8206,7 @@
 func rewriteValueARM_OpARMNEGF(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (NEGF (MULF x y))
-	// cond: objabi.GOARM >= 6
+	// cond: buildcfg.GOARM >= 6
 	// result: (NMULF x y)
 	for {
 		if v_0.Op != OpARMMULF {
@@ -8194,7 +8214,7 @@
 		}
 		y := v_0.Args[1]
 		x := v_0.Args[0]
-		if !(objabi.GOARM >= 6) {
+		if !(buildcfg.GOARM >= 6) {
 			break
 		}
 		v.reset(OpARMNMULF)
@@ -8518,7 +8538,7 @@
 		return true
 	}
 	// match: (ORshiftLL <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x)
-	// cond: objabi.GOARM>=6
+	// cond: buildcfg.GOARM>=6
 	// result: (REV16 x)
 	for {
 		if v.Type != typ.UInt16 || auxIntToInt32(v.AuxInt) != 8 || v_0.Op != OpARMSRLconst || v_0.Type != typ.UInt16 || auxIntToInt32(v_0.AuxInt) != 24 {
@@ -8529,7 +8549,7 @@
 			break
 		}
 		x := v_0_0.Args[0]
-		if x != v_1 || !(objabi.GOARM >= 6) {
+		if x != v_1 || !(buildcfg.GOARM >= 6) {
 			break
 		}
 		v.reset(OpARMREV16)
@@ -8993,7 +9013,7 @@
 		return true
 	}
 	// match: (RSB (MUL x y) a)
-	// cond: objabi.GOARM == 7
+	// cond: buildcfg.GOARM == 7
 	// result: (MULS x y a)
 	for {
 		if v_0.Op != OpARMMUL {
@@ -9002,7 +9022,7 @@
 		y := v_0.Args[1]
 		x := v_0.Args[0]
 		a := v_1
-		if !(objabi.GOARM == 7) {
+		if !(buildcfg.GOARM == 7) {
 			break
 		}
 		v.reset(OpARMMULS)
@@ -10429,7 +10449,7 @@
 		return true
 	}
 	// match: (SRAconst (SLLconst x [c]) [d])
-	// cond: objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31
+	// cond: buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31
 	// result: (BFX [(d-c)|(32-d)<<8] x)
 	for {
 		d := auxIntToInt32(v.AuxInt)
@@ -10438,7 +10458,7 @@
 		}
 		c := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
-		if !(objabi.GOARM == 7 && uint64(d) >= uint64(c) && uint64(d) <= 31) {
+		if !(buildcfg.GOARM == 7 && uint64(d) >= uint64(c) && uint64(d) <= 31) {
 			break
 		}
 		v.reset(OpARMBFX)
@@ -10481,7 +10501,7 @@
 		return true
 	}
 	// match: (SRLconst (SLLconst x [c]) [d])
-	// cond: objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31
+	// cond: buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31
 	// result: (BFXU [(d-c)|(32-d)<<8] x)
 	for {
 		d := auxIntToInt32(v.AuxInt)
@@ -10490,7 +10510,7 @@
 		}
 		c := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
-		if !(objabi.GOARM == 7 && uint64(d) >= uint64(c) && uint64(d) <= 31) {
+		if !(buildcfg.GOARM == 7 && uint64(d) >= uint64(c) && uint64(d) <= 31) {
 			break
 		}
 		v.reset(OpARMBFXU)
@@ -10703,7 +10723,7 @@
 		return true
 	}
 	// match: (SUB a (MUL x y))
-	// cond: objabi.GOARM == 7
+	// cond: buildcfg.GOARM == 7
 	// result: (MULS x y a)
 	for {
 		a := v_0
@@ -10712,7 +10732,7 @@
 		}
 		y := v_1.Args[1]
 		x := v_1.Args[0]
-		if !(objabi.GOARM == 7) {
+		if !(buildcfg.GOARM == 7) {
 			break
 		}
 		v.reset(OpARMMULS)
@@ -10725,7 +10745,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (SUBD a (MULD x y))
-	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// cond: a.Uses == 1 && buildcfg.GOARM >= 6
 	// result: (MULSD a x y)
 	for {
 		a := v_0
@@ -10734,7 +10754,7 @@
 		}
 		y := v_1.Args[1]
 		x := v_1.Args[0]
-		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+		if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
 			break
 		}
 		v.reset(OpARMMULSD)
@@ -10742,7 +10762,7 @@
 		return true
 	}
 	// match: (SUBD a (NMULD x y))
-	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// cond: a.Uses == 1 && buildcfg.GOARM >= 6
 	// result: (MULAD a x y)
 	for {
 		a := v_0
@@ -10751,7 +10771,7 @@
 		}
 		y := v_1.Args[1]
 		x := v_1.Args[0]
-		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+		if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
 			break
 		}
 		v.reset(OpARMMULAD)
@@ -10764,7 +10784,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (SUBF a (MULF x y))
-	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// cond: a.Uses == 1 && buildcfg.GOARM >= 6
 	// result: (MULSF a x y)
 	for {
 		a := v_0
@@ -10773,7 +10793,7 @@
 		}
 		y := v_1.Args[1]
 		x := v_1.Args[0]
-		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+		if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
 			break
 		}
 		v.reset(OpARMMULSF)
@@ -10781,7 +10801,7 @@
 		return true
 	}
 	// match: (SUBF a (NMULF x y))
-	// cond: a.Uses == 1 && objabi.GOARM >= 6
+	// cond: a.Uses == 1 && buildcfg.GOARM >= 6
 	// result: (MULAF a x y)
 	for {
 		a := v_0
@@ -10790,7 +10810,7 @@
 		}
 		y := v_1.Args[1]
 		x := v_1.Args[0]
-		if !(a.Uses == 1 && objabi.GOARM >= 6) {
+		if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
 			break
 		}
 		v.reset(OpARMMULAF)
@@ -11244,12 +11264,12 @@
 		return true
 	}
 	// match: (SUBconst [c] x)
-	// cond: objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff
+	// cond: buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff
 	// result: (ADDconst [-c] x)
 	for {
 		c := auxIntToInt32(v.AuxInt)
 		x := v_0
-		if !(objabi.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && uint32(-c) <= 0xffff) {
+		if !(buildcfg.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && uint32(-c) <= 0xffff) {
 			break
 		}
 		v.reset(OpARMADDconst)
@@ -12557,7 +12577,7 @@
 		return true
 	}
 	// match: (XORshiftLL <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x)
-	// cond: objabi.GOARM>=6
+	// cond: buildcfg.GOARM>=6
 	// result: (REV16 x)
 	for {
 		if v.Type != typ.UInt16 || auxIntToInt32(v.AuxInt) != 8 || v_0.Op != OpARMSRLconst || v_0.Type != typ.UInt16 || auxIntToInt32(v_0.AuxInt) != 24 {
@@ -12568,7 +12588,7 @@
 			break
 		}
 		x := v_0_0.Args[0]
-		if x != v_1 || !(objabi.GOARM >= 6) {
+		if x != v_1 || !(buildcfg.GOARM >= 6) {
 			break
 		}
 		v.reset(OpARMREV16)
@@ -12919,12 +12939,12 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Bswap32 <t> x)
-	// cond: objabi.GOARM==5
+	// cond: buildcfg.GOARM==5
 	// result: (XOR <t> (SRLconst <t> (BICconst <t> (XOR <t> x (SRRconst <t> [16] x)) [0xff0000]) [8]) (SRRconst <t> x [8]))
 	for {
 		t := v.Type
 		x := v_0
-		if !(objabi.GOARM == 5) {
+		if !(buildcfg.GOARM == 5) {
 			break
 		}
 		v.reset(OpARMXOR)
@@ -12947,11 +12967,11 @@
 		return true
 	}
 	// match: (Bswap32 x)
-	// cond: objabi.GOARM>=6
+	// cond: buildcfg.GOARM>=6
 	// result: (REV x)
 	for {
 		x := v_0
-		if !(objabi.GOARM >= 6) {
+		if !(buildcfg.GOARM >= 6) {
 			break
 		}
 		v.reset(OpARMREV)
@@ -13011,12 +13031,12 @@
 	}
 }
 func rewriteValueARM_OpConstBool(v *Value) bool {
-	// match: (ConstBool [b])
-	// result: (MOVWconst [b2i32(b)])
+	// match: (ConstBool [t])
+	// result: (MOVWconst [b2i32(t)])
 	for {
-		b := auxIntToBool(v.AuxInt)
+		t := auxIntToBool(v.AuxInt)
 		v.reset(OpARMMOVWconst)
-		v.AuxInt = int32ToAuxInt(b2i32(b))
+		v.AuxInt = int32ToAuxInt(b2i32(t))
 		return true
 	}
 }
@@ -13034,12 +13054,12 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Ctz16 <t> x)
-	// cond: objabi.GOARM<=6
+	// cond: buildcfg.GOARM<=6
 	// result: (RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x10000] x))) [1])))
 	for {
 		t := v.Type
 		x := v_0
-		if !(objabi.GOARM <= 6) {
+		if !(buildcfg.GOARM <= 6) {
 			break
 		}
 		v.reset(OpARMRSBconst)
@@ -13061,12 +13081,12 @@
 		return true
 	}
 	// match: (Ctz16 <t> x)
-	// cond: objabi.GOARM==7
+	// cond: buildcfg.GOARM==7
 	// result: (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x)))
 	for {
 		t := v.Type
 		x := v_0
-		if !(objabi.GOARM == 7) {
+		if !(buildcfg.GOARM == 7) {
 			break
 		}
 		v.reset(OpARMCLZ)
@@ -13085,12 +13105,12 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Ctz32 <t> x)
-	// cond: objabi.GOARM<=6
+	// cond: buildcfg.GOARM<=6
 	// result: (RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1])))
 	for {
 		t := v.Type
 		x := v_0
-		if !(objabi.GOARM <= 6) {
+		if !(buildcfg.GOARM <= 6) {
 			break
 		}
 		v.reset(OpARMRSBconst)
@@ -13109,12 +13129,12 @@
 		return true
 	}
 	// match: (Ctz32 <t> x)
-	// cond: objabi.GOARM==7
+	// cond: buildcfg.GOARM==7
 	// result: (CLZ <t> (RBIT <t> x))
 	for {
 		t := v.Type
 		x := v_0
-		if !(objabi.GOARM == 7) {
+		if !(buildcfg.GOARM == 7) {
 			break
 		}
 		v.reset(OpARMCLZ)
@@ -13131,12 +13151,12 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Ctz8 <t> x)
-	// cond: objabi.GOARM<=6
+	// cond: buildcfg.GOARM<=6
 	// result: (RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x100] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x100] x))) [1])))
 	for {
 		t := v.Type
 		x := v_0
-		if !(objabi.GOARM <= 6) {
+		if !(buildcfg.GOARM <= 6) {
 			break
 		}
 		v.reset(OpARMRSBconst)
@@ -13158,12 +13178,12 @@
 		return true
 	}
 	// match: (Ctz8 <t> x)
-	// cond: objabi.GOARM==7
+	// cond: buildcfg.GOARM==7
 	// result: (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x100] x)))
 	for {
 		t := v.Type
 		x := v_0
-		if !(objabi.GOARM == 7) {
+		if !(buildcfg.GOARM == 7) {
 			break
 		}
 		v.reset(OpARMCLZ)
diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go
index 5d5e526..3cdc4d3 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM64.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM64.go
@@ -69,6 +69,14 @@
 		return rewriteValueARM64_OpARM64CSEL(v)
 	case OpARM64CSEL0:
 		return rewriteValueARM64_OpARM64CSEL0(v)
+	case OpARM64CSETM:
+		return rewriteValueARM64_OpARM64CSETM(v)
+	case OpARM64CSINC:
+		return rewriteValueARM64_OpARM64CSINC(v)
+	case OpARM64CSINV:
+		return rewriteValueARM64_OpARM64CSINV(v)
+	case OpARM64CSNEG:
+		return rewriteValueARM64_OpARM64CSNEG(v)
 	case OpARM64DIV:
 		return rewriteValueARM64_OpARM64DIV(v)
 	case OpARM64DIVW:
@@ -99,18 +107,26 @@
 		return rewriteValueARM64_OpARM64FMOVDload(v)
 	case OpARM64FMOVDloadidx:
 		return rewriteValueARM64_OpARM64FMOVDloadidx(v)
+	case OpARM64FMOVDloadidx8:
+		return rewriteValueARM64_OpARM64FMOVDloadidx8(v)
 	case OpARM64FMOVDstore:
 		return rewriteValueARM64_OpARM64FMOVDstore(v)
 	case OpARM64FMOVDstoreidx:
 		return rewriteValueARM64_OpARM64FMOVDstoreidx(v)
+	case OpARM64FMOVDstoreidx8:
+		return rewriteValueARM64_OpARM64FMOVDstoreidx8(v)
 	case OpARM64FMOVSload:
 		return rewriteValueARM64_OpARM64FMOVSload(v)
 	case OpARM64FMOVSloadidx:
 		return rewriteValueARM64_OpARM64FMOVSloadidx(v)
+	case OpARM64FMOVSloadidx4:
+		return rewriteValueARM64_OpARM64FMOVSloadidx4(v)
 	case OpARM64FMOVSstore:
 		return rewriteValueARM64_OpARM64FMOVSstore(v)
 	case OpARM64FMOVSstoreidx:
 		return rewriteValueARM64_OpARM64FMOVSstoreidx(v)
+	case OpARM64FMOVSstoreidx4:
+		return rewriteValueARM64_OpARM64FMOVSstoreidx4(v)
 	case OpARM64FMULD:
 		return rewriteValueARM64_OpARM64FMULD(v)
 	case OpARM64FMULS:
@@ -189,6 +205,8 @@
 		return rewriteValueARM64_OpARM64MOVDloadidx(v)
 	case OpARM64MOVDloadidx8:
 		return rewriteValueARM64_OpARM64MOVDloadidx8(v)
+	case OpARM64MOVDnop:
+		return rewriteValueARM64_OpARM64MOVDnop(v)
 	case OpARM64MOVDreg:
 		return rewriteValueARM64_OpARM64MOVDreg(v)
 	case OpARM64MOVDstore:
@@ -966,6 +984,8 @@
 		return rewriteValueARM64_OpSelect0(v)
 	case OpSelect1:
 		return rewriteValueARM64_OpSelect1(v)
+	case OpSelectN:
+		return rewriteValueARM64_OpSelectN(v)
 	case OpSignExt16to32:
 		v.Op = OpARM64MOVHreg
 		return true
@@ -989,6 +1009,9 @@
 	case OpSqrt:
 		v.Op = OpARM64FSQRTD
 		return true
+	case OpSqrt32:
+		v.Op = OpARM64FSQRTS
+		return true
 	case OpStaticCall:
 		v.Op = OpARM64CALLstatic
 		return true
@@ -1751,6 +1774,81 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (ADDshiftLL [8] (UBFX [armBFAuxInt(8, 24)] (ANDconst [c1] x)) (ANDconst [c2] x))
+	// cond: uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
+	// result: (REV16W x)
+	for {
+		if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 24) {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpARM64ANDconst {
+			break
+		}
+		c1 := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
+		if v_1.Op != OpARM64ANDconst {
+			break
+		}
+		c2 := auxIntToInt64(v_1.AuxInt)
+		if x != v_1.Args[0] || !(uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff) {
+			break
+		}
+		v.reset(OpARM64REV16W)
+		v.AddArg(x)
+		return true
+	}
+	// match: (ADDshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
+	// cond: (uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff)
+	// result: (REV16 x)
+	for {
+		if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpARM64ANDconst {
+			break
+		}
+		c1 := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
+		if v_1.Op != OpARM64ANDconst {
+			break
+		}
+		c2 := auxIntToInt64(v_1.AuxInt)
+		if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff) {
+			break
+		}
+		v.reset(OpARM64REV16)
+		v.AddArg(x)
+		return true
+	}
+	// match: (ADDshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
+	// cond: (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff)
+	// result: (REV16 (ANDconst <x.Type> [0xffffffff] x))
+	for {
+		if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpARM64ANDconst {
+			break
+		}
+		c1 := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
+		if v_1.Op != OpARM64ANDconst {
+			break
+		}
+		c2 := auxIntToInt64(v_1.AuxInt)
+		if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) {
+			break
+		}
+		v.reset(OpARM64REV16)
+		v0 := b.NewValue0(v.Pos, OpARM64ANDconst, x.Type)
+		v0.AuxInt = int64ToAuxInt(0xffffffff)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (ADDshiftLL [c] (SRLconst x [64-c]) x2)
 	// result: (EXTRconst [64-c] x2 x)
 	for {
@@ -2772,12 +2870,12 @@
 		return true
 	}
 	// match: (CMP x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMP y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpARM64InvertFlags)
@@ -2941,12 +3039,12 @@
 		return true
 	}
 	// match: (CMPW x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPW y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpARM64InvertFlags)
@@ -3202,6 +3300,32 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
+	// match: (CSEL [cc] (MOVDconst [-1]) (MOVDconst [0]) flag)
+	// result: (CSETM [cc] flag)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != -1 || v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
+			break
+		}
+		flag := v_2
+		v.reset(OpARM64CSETM)
+		v.AuxInt = opToAuxInt(cc)
+		v.AddArg(flag)
+		return true
+	}
+	// match: (CSEL [cc] (MOVDconst [0]) (MOVDconst [-1]) flag)
+	// result: (CSETM [arm64Negate(cc)] flag)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != 0 || v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 {
+			break
+		}
+		flag := v_2
+		v.reset(OpARM64CSETM)
+		v.AuxInt = opToAuxInt(arm64Negate(cc))
+		v.AddArg(flag)
+		return true
+	}
 	// match: (CSEL [cc] x (MOVDconst [0]) flag)
 	// result: (CSEL0 [cc] x flag)
 	for {
@@ -3230,6 +3354,96 @@
 		v.AddArg2(y, flag)
 		return true
 	}
+	// match: (CSEL [cc] x (ADDconst [1] a) flag)
+	// result: (CSINC [cc] x a flag)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		x := v_0
+		if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 1 {
+			break
+		}
+		a := v_1.Args[0]
+		flag := v_2
+		v.reset(OpARM64CSINC)
+		v.AuxInt = opToAuxInt(cc)
+		v.AddArg3(x, a, flag)
+		return true
+	}
+	// match: (CSEL [cc] (ADDconst [1] a) x flag)
+	// result: (CSINC [arm64Negate(cc)] x a flag)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		if v_0.Op != OpARM64ADDconst || auxIntToInt64(v_0.AuxInt) != 1 {
+			break
+		}
+		a := v_0.Args[0]
+		x := v_1
+		flag := v_2
+		v.reset(OpARM64CSINC)
+		v.AuxInt = opToAuxInt(arm64Negate(cc))
+		v.AddArg3(x, a, flag)
+		return true
+	}
+	// match: (CSEL [cc] x (MVN a) flag)
+	// result: (CSINV [cc] x a flag)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		x := v_0
+		if v_1.Op != OpARM64MVN {
+			break
+		}
+		a := v_1.Args[0]
+		flag := v_2
+		v.reset(OpARM64CSINV)
+		v.AuxInt = opToAuxInt(cc)
+		v.AddArg3(x, a, flag)
+		return true
+	}
+	// match: (CSEL [cc] (MVN a) x flag)
+	// result: (CSINV [arm64Negate(cc)] x a flag)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		if v_0.Op != OpARM64MVN {
+			break
+		}
+		a := v_0.Args[0]
+		x := v_1
+		flag := v_2
+		v.reset(OpARM64CSINV)
+		v.AuxInt = opToAuxInt(arm64Negate(cc))
+		v.AddArg3(x, a, flag)
+		return true
+	}
+	// match: (CSEL [cc] x (NEG a) flag)
+	// result: (CSNEG [cc] x a flag)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		x := v_0
+		if v_1.Op != OpARM64NEG {
+			break
+		}
+		a := v_1.Args[0]
+		flag := v_2
+		v.reset(OpARM64CSNEG)
+		v.AuxInt = opToAuxInt(cc)
+		v.AddArg3(x, a, flag)
+		return true
+	}
+	// match: (CSEL [cc] (NEG a) x flag)
+	// result: (CSNEG [arm64Negate(cc)] x a flag)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		if v_0.Op != OpARM64NEG {
+			break
+		}
+		a := v_0.Args[0]
+		x := v_1
+		flag := v_2
+		v.reset(OpARM64CSNEG)
+		v.AuxInt = opToAuxInt(arm64Negate(cc))
+		v.AddArg3(x, a, flag)
+		return true
+	}
 	// match: (CSEL [cc] x y (InvertFlags cmp))
 	// result: (CSEL [arm64Invert(cc)] x y cmp)
 	for {
@@ -3392,6 +3606,194 @@
 	}
 	return false
 }
+func rewriteValueARM64_OpARM64CSETM(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (CSETM [cc] (InvertFlags cmp))
+	// result: (CSETM [arm64Invert(cc)] cmp)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		if v_0.Op != OpARM64InvertFlags {
+			break
+		}
+		cmp := v_0.Args[0]
+		v.reset(OpARM64CSETM)
+		v.AuxInt = opToAuxInt(arm64Invert(cc))
+		v.AddArg(cmp)
+		return true
+	}
+	// match: (CSETM [cc] flag)
+	// cond: ccARM64Eval(cc, flag) > 0
+	// result: (MOVDconst [-1])
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		flag := v_0
+		if !(ccARM64Eval(cc, flag) > 0) {
+			break
+		}
+		v.reset(OpARM64MOVDconst)
+		v.AuxInt = int64ToAuxInt(-1)
+		return true
+	}
+	// match: (CSETM [cc] flag)
+	// cond: ccARM64Eval(cc, flag) < 0
+	// result: (MOVDconst [0])
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		flag := v_0
+		if !(ccARM64Eval(cc, flag) < 0) {
+			break
+		}
+		v.reset(OpARM64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64_OpARM64CSINC(v *Value) bool {
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (CSINC [cc] x y (InvertFlags cmp))
+	// result: (CSINC [arm64Invert(cc)] x y cmp)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		x := v_0
+		y := v_1
+		if v_2.Op != OpARM64InvertFlags {
+			break
+		}
+		cmp := v_2.Args[0]
+		v.reset(OpARM64CSINC)
+		v.AuxInt = opToAuxInt(arm64Invert(cc))
+		v.AddArg3(x, y, cmp)
+		return true
+	}
+	// match: (CSINC [cc] x _ flag)
+	// cond: ccARM64Eval(cc, flag) > 0
+	// result: x
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		x := v_0
+		flag := v_2
+		if !(ccARM64Eval(cc, flag) > 0) {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (CSINC [cc] _ y flag)
+	// cond: ccARM64Eval(cc, flag) < 0
+	// result: (ADDconst [1] y)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		y := v_1
+		flag := v_2
+		if !(ccARM64Eval(cc, flag) < 0) {
+			break
+		}
+		v.reset(OpARM64ADDconst)
+		v.AuxInt = int64ToAuxInt(1)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64_OpARM64CSINV(v *Value) bool {
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (CSINV [cc] x y (InvertFlags cmp))
+	// result: (CSINV [arm64Invert(cc)] x y cmp)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		x := v_0
+		y := v_1
+		if v_2.Op != OpARM64InvertFlags {
+			break
+		}
+		cmp := v_2.Args[0]
+		v.reset(OpARM64CSINV)
+		v.AuxInt = opToAuxInt(arm64Invert(cc))
+		v.AddArg3(x, y, cmp)
+		return true
+	}
+	// match: (CSINV [cc] x _ flag)
+	// cond: ccARM64Eval(cc, flag) > 0
+	// result: x
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		x := v_0
+		flag := v_2
+		if !(ccARM64Eval(cc, flag) > 0) {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (CSINV [cc] _ y flag)
+	// cond: ccARM64Eval(cc, flag) < 0
+	// result: (Not y)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		y := v_1
+		flag := v_2
+		if !(ccARM64Eval(cc, flag) < 0) {
+			break
+		}
+		v.reset(OpNot)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64_OpARM64CSNEG(v *Value) bool {
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (CSNEG [cc] x y (InvertFlags cmp))
+	// result: (CSNEG [arm64Invert(cc)] x y cmp)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		x := v_0
+		y := v_1
+		if v_2.Op != OpARM64InvertFlags {
+			break
+		}
+		cmp := v_2.Args[0]
+		v.reset(OpARM64CSNEG)
+		v.AuxInt = opToAuxInt(arm64Invert(cc))
+		v.AddArg3(x, y, cmp)
+		return true
+	}
+	// match: (CSNEG [cc] x _ flag)
+	// cond: ccARM64Eval(cc, flag) > 0
+	// result: x
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		x := v_0
+		flag := v_2
+		if !(ccARM64Eval(cc, flag) > 0) {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (CSNEG [cc] _ y flag)
+	// cond: ccARM64Eval(cc, flag) < 0
+	// result: (NEG y)
+	for {
+		cc := auxIntToOp(v.AuxInt)
+		y := v_1
+		flag := v_2
+		if !(ccARM64Eval(cc, flag) < 0) {
+			break
+		}
+		v.reset(OpARM64NEG)
+		v.AddArg(y)
+		return true
+	}
+	return false
+}
 func rewriteValueARM64_OpARM64DIV(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
@@ -3898,6 +4300,25 @@
 		v.AddArg3(ptr, idx, mem)
 		return true
 	}
+	// match: (FMOVDload [off] {sym} (ADDshiftLL [3] ptr idx) mem)
+	// cond: off == 0 && sym == nil
+	// result: (FMOVDloadidx8 ptr idx mem)
+	for {
+		off := auxIntToInt32(v.AuxInt)
+		sym := auxToSym(v.Aux)
+		if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 3 {
+			break
+		}
+		idx := v_0.Args[1]
+		ptr := v_0.Args[0]
+		mem := v_1
+		if !(off == 0 && sym == nil) {
+			break
+		}
+		v.reset(OpARM64FMOVDloadidx8)
+		v.AddArg3(ptr, idx, mem)
+		return true
+	}
 	// match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
 	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
 	// result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
@@ -3962,6 +4383,56 @@
 		v.AddArg2(ptr, mem)
 		return true
 	}
+	// match: (FMOVDloadidx ptr (SLLconst [3] idx) mem)
+	// result: (FMOVDloadidx8 ptr idx mem)
+	for {
+		ptr := v_0
+		if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 3 {
+			break
+		}
+		idx := v_1.Args[0]
+		mem := v_2
+		v.reset(OpARM64FMOVDloadidx8)
+		v.AddArg3(ptr, idx, mem)
+		return true
+	}
+	// match: (FMOVDloadidx (SLLconst [3] idx) ptr mem)
+	// result: (FMOVDloadidx8 ptr idx mem)
+	for {
+		if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 3 {
+			break
+		}
+		idx := v_0.Args[0]
+		ptr := v_1
+		mem := v_2
+		v.reset(OpARM64FMOVDloadidx8)
+		v.AddArg3(ptr, idx, mem)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64_OpARM64FMOVDloadidx8(v *Value) bool {
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (FMOVDloadidx8 ptr (MOVDconst [c]) mem)
+	// cond: is32Bit(c<<3)
+	// result: (FMOVDload ptr [int32(c)<<3] mem)
+	for {
+		ptr := v_0
+		if v_1.Op != OpARM64MOVDconst {
+			break
+		}
+		c := auxIntToInt64(v_1.AuxInt)
+		mem := v_2
+		if !(is32Bit(c << 3)) {
+			break
+		}
+		v.reset(OpARM64FMOVDload)
+		v.AuxInt = int32ToAuxInt(int32(c) << 3)
+		v.AddArg2(ptr, mem)
+		return true
+	}
 	return false
 }
 func rewriteValueARM64_OpARM64FMOVDstore(v *Value) bool {
@@ -4029,6 +4500,26 @@
 		v.AddArg4(ptr, idx, val, mem)
 		return true
 	}
+	// match: (FMOVDstore [off] {sym} (ADDshiftLL [3] ptr idx) val mem)
+	// cond: off == 0 && sym == nil
+	// result: (FMOVDstoreidx8 ptr idx val mem)
+	for {
+		off := auxIntToInt32(v.AuxInt)
+		sym := auxToSym(v.Aux)
+		if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 3 {
+			break
+		}
+		idx := v_0.Args[1]
+		ptr := v_0.Args[0]
+		val := v_1
+		mem := v_2
+		if !(off == 0 && sym == nil) {
+			break
+		}
+		v.reset(OpARM64FMOVDstoreidx8)
+		v.AddArg4(ptr, idx, val, mem)
+		return true
+	}
 	// match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
 	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
 	// result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
@@ -4097,6 +4588,60 @@
 		v.AddArg3(idx, val, mem)
 		return true
 	}
+	// match: (FMOVDstoreidx ptr (SLLconst [3] idx) val mem)
+	// result: (FMOVDstoreidx8 ptr idx val mem)
+	for {
+		ptr := v_0
+		if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 3 {
+			break
+		}
+		idx := v_1.Args[0]
+		val := v_2
+		mem := v_3
+		v.reset(OpARM64FMOVDstoreidx8)
+		v.AddArg4(ptr, idx, val, mem)
+		return true
+	}
+	// match: (FMOVDstoreidx (SLLconst [3] idx) ptr val mem)
+	// result: (FMOVDstoreidx8 ptr idx val mem)
+	for {
+		if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 3 {
+			break
+		}
+		idx := v_0.Args[0]
+		ptr := v_1
+		val := v_2
+		mem := v_3
+		v.reset(OpARM64FMOVDstoreidx8)
+		v.AddArg4(ptr, idx, val, mem)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64_OpARM64FMOVDstoreidx8(v *Value) bool {
+	v_3 := v.Args[3]
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (FMOVDstoreidx8 ptr (MOVDconst [c]) val mem)
+	// cond: is32Bit(c<<3)
+	// result: (FMOVDstore [int32(c)<<3] ptr val mem)
+	for {
+		ptr := v_0
+		if v_1.Op != OpARM64MOVDconst {
+			break
+		}
+		c := auxIntToInt64(v_1.AuxInt)
+		val := v_2
+		mem := v_3
+		if !(is32Bit(c << 3)) {
+			break
+		}
+		v.reset(OpARM64FMOVDstore)
+		v.AuxInt = int32ToAuxInt(int32(c) << 3)
+		v.AddArg3(ptr, val, mem)
+		return true
+	}
 	return false
 }
 func rewriteValueARM64_OpARM64FMOVSload(v *Value) bool {
@@ -4161,6 +4706,25 @@
 		v.AddArg3(ptr, idx, mem)
 		return true
 	}
+	// match: (FMOVSload [off] {sym} (ADDshiftLL [2] ptr idx) mem)
+	// cond: off == 0 && sym == nil
+	// result: (FMOVSloadidx4 ptr idx mem)
+	for {
+		off := auxIntToInt32(v.AuxInt)
+		sym := auxToSym(v.Aux)
+		if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
+			break
+		}
+		idx := v_0.Args[1]
+		ptr := v_0.Args[0]
+		mem := v_1
+		if !(off == 0 && sym == nil) {
+			break
+		}
+		v.reset(OpARM64FMOVSloadidx4)
+		v.AddArg3(ptr, idx, mem)
+		return true
+	}
 	// match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
 	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
 	// result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
@@ -4225,6 +4789,56 @@
 		v.AddArg2(ptr, mem)
 		return true
 	}
+	// match: (FMOVSloadidx ptr (SLLconst [2] idx) mem)
+	// result: (FMOVSloadidx4 ptr idx mem)
+	for {
+		ptr := v_0
+		if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
+			break
+		}
+		idx := v_1.Args[0]
+		mem := v_2
+		v.reset(OpARM64FMOVSloadidx4)
+		v.AddArg3(ptr, idx, mem)
+		return true
+	}
+	// match: (FMOVSloadidx (SLLconst [2] idx) ptr mem)
+	// result: (FMOVSloadidx4 ptr idx mem)
+	for {
+		if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
+			break
+		}
+		idx := v_0.Args[0]
+		ptr := v_1
+		mem := v_2
+		v.reset(OpARM64FMOVSloadidx4)
+		v.AddArg3(ptr, idx, mem)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64_OpARM64FMOVSloadidx4(v *Value) bool {
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (FMOVSloadidx4 ptr (MOVDconst [c]) mem)
+	// cond: is32Bit(c<<2)
+	// result: (FMOVSload ptr [int32(c)<<2] mem)
+	for {
+		ptr := v_0
+		if v_1.Op != OpARM64MOVDconst {
+			break
+		}
+		c := auxIntToInt64(v_1.AuxInt)
+		mem := v_2
+		if !(is32Bit(c << 2)) {
+			break
+		}
+		v.reset(OpARM64FMOVSload)
+		v.AuxInt = int32ToAuxInt(int32(c) << 2)
+		v.AddArg2(ptr, mem)
+		return true
+	}
 	return false
 }
 func rewriteValueARM64_OpARM64FMOVSstore(v *Value) bool {
@@ -4292,6 +4906,26 @@
 		v.AddArg4(ptr, idx, val, mem)
 		return true
 	}
+	// match: (FMOVSstore [off] {sym} (ADDshiftLL [2] ptr idx) val mem)
+	// cond: off == 0 && sym == nil
+	// result: (FMOVSstoreidx4 ptr idx val mem)
+	for {
+		off := auxIntToInt32(v.AuxInt)
+		sym := auxToSym(v.Aux)
+		if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
+			break
+		}
+		idx := v_0.Args[1]
+		ptr := v_0.Args[0]
+		val := v_1
+		mem := v_2
+		if !(off == 0 && sym == nil) {
+			break
+		}
+		v.reset(OpARM64FMOVSstoreidx4)
+		v.AddArg4(ptr, idx, val, mem)
+		return true
+	}
 	// match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
 	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
 	// result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
@@ -4360,6 +4994,60 @@
 		v.AddArg3(idx, val, mem)
 		return true
 	}
+	// match: (FMOVSstoreidx ptr (SLLconst [2] idx) val mem)
+	// result: (FMOVSstoreidx4 ptr idx val mem)
+	for {
+		ptr := v_0
+		if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
+			break
+		}
+		idx := v_1.Args[0]
+		val := v_2
+		mem := v_3
+		v.reset(OpARM64FMOVSstoreidx4)
+		v.AddArg4(ptr, idx, val, mem)
+		return true
+	}
+	// match: (FMOVSstoreidx (SLLconst [2] idx) ptr val mem)
+	// result: (FMOVSstoreidx4 ptr idx val mem)
+	for {
+		if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
+			break
+		}
+		idx := v_0.Args[0]
+		ptr := v_1
+		val := v_2
+		mem := v_3
+		v.reset(OpARM64FMOVSstoreidx4)
+		v.AddArg4(ptr, idx, val, mem)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64_OpARM64FMOVSstoreidx4(v *Value) bool {
+	v_3 := v.Args[3]
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (FMOVSstoreidx4 ptr (MOVDconst [c]) val mem)
+	// cond: is32Bit(c<<2)
+	// result: (FMOVSstore [int32(c)<<2] ptr val mem)
+	for {
+		ptr := v_0
+		if v_1.Op != OpARM64MOVDconst {
+			break
+		}
+		c := auxIntToInt64(v_1.AuxInt)
+		val := v_2
+		mem := v_3
+		if !(is32Bit(c << 2)) {
+			break
+		}
+		v.reset(OpARM64FMOVSstore)
+		v.AuxInt = int32ToAuxInt(int32(c) << 2)
+		v.AddArg3(ptr, val, mem)
+		return true
+	}
 	return false
 }
 func rewriteValueARM64_OpARM64FMULD(v *Value) bool {
@@ -6450,6 +7138,21 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (MOVBUreg (SLLconst [lc] x))
+	// cond: lc >= 8
+	// result: (MOVDconst [0])
+	for {
+		if v_0.Op != OpARM64SLLconst {
+			break
+		}
+		lc := auxIntToInt64(v_0.AuxInt)
+		if !(lc >= 8) {
+			break
+		}
+		v.reset(OpARM64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
 	// match: (MOVBUreg (SLLconst [sc] x))
 	// cond: isARM64BFMask(sc, 1<<8-1, sc)
 	// result: (UBFIZ [armBFAuxInt(sc, arm64BFWidth(1<<8-1, sc))] x)
@@ -9011,6 +9714,21 @@
 	}
 	return false
 }
+func rewriteValueARM64_OpARM64MOVDnop(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (MOVDnop (MOVDconst [c]))
+	// result: (MOVDconst [c])
+	for {
+		if v_0.Op != OpARM64MOVDconst {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		v.reset(OpARM64MOVDconst)
+		v.AuxInt = int64ToAuxInt(c)
+		return true
+	}
+	return false
+}
 func rewriteValueARM64_OpARM64MOVDreg(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (MOVDreg x)
@@ -9932,6 +10650,21 @@
 		v.AuxInt = int64ToAuxInt(int64(uint16(c)))
 		return true
 	}
+	// match: (MOVHUreg (SLLconst [lc] x))
+	// cond: lc >= 16
+	// result: (MOVDconst [0])
+	for {
+		if v_0.Op != OpARM64SLLconst {
+			break
+		}
+		lc := auxIntToInt64(v_0.AuxInt)
+		if !(lc >= 16) {
+			break
+		}
+		v.reset(OpARM64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
 	// match: (MOVHUreg (SLLconst [sc] x))
 	// cond: isARM64BFMask(sc, 1<<16-1, sc)
 	// result: (UBFIZ [armBFAuxInt(sc, arm64BFWidth(1<<16-1, sc))] x)
@@ -12029,6 +12762,21 @@
 		v.AuxInt = int64ToAuxInt(int64(uint32(c)))
 		return true
 	}
+	// match: (MOVWUreg (SLLconst [lc] x))
+	// cond: lc >= 32
+	// result: (MOVDconst [0])
+	for {
+		if v_0.Op != OpARM64SLLconst {
+			break
+		}
+		lc := auxIntToInt64(v_0.AuxInt)
+		if !(lc >= 32) {
+			break
+		}
+		v.reset(OpARM64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
 	// match: (MOVWUreg (SLLconst [sc] x))
 	// cond: isARM64BFMask(sc, 1<<32-1, sc)
 	// result: (UBFIZ [armBFAuxInt(sc, arm64BFWidth(1<<32-1, sc))] x)
@@ -17332,6 +18080,81 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (ORshiftLL [8] (UBFX [armBFAuxInt(8, 24)] (ANDconst [c1] x)) (ANDconst [c2] x))
+	// cond: uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
+	// result: (REV16W x)
+	for {
+		if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 24) {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpARM64ANDconst {
+			break
+		}
+		c1 := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
+		if v_1.Op != OpARM64ANDconst {
+			break
+		}
+		c2 := auxIntToInt64(v_1.AuxInt)
+		if x != v_1.Args[0] || !(uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff) {
+			break
+		}
+		v.reset(OpARM64REV16W)
+		v.AddArg(x)
+		return true
+	}
+	// match: (ORshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
+	// cond: (uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff)
+	// result: (REV16 x)
+	for {
+		if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpARM64ANDconst {
+			break
+		}
+		c1 := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
+		if v_1.Op != OpARM64ANDconst {
+			break
+		}
+		c2 := auxIntToInt64(v_1.AuxInt)
+		if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff) {
+			break
+		}
+		v.reset(OpARM64REV16)
+		v.AddArg(x)
+		return true
+	}
+	// match: (ORshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
+	// cond: (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff)
+	// result: (REV16 (ANDconst <x.Type> [0xffffffff] x))
+	for {
+		if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpARM64ANDconst {
+			break
+		}
+		c1 := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
+		if v_1.Op != OpARM64ANDconst {
+			break
+		}
+		c2 := auxIntToInt64(v_1.AuxInt)
+		if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) {
+			break
+		}
+		v.reset(OpARM64REV16)
+		v0 := b.NewValue0(v.Pos, OpARM64ANDconst, x.Type)
+		v0.AuxInt = int64ToAuxInt(0xffffffff)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
 	// match: ( ORshiftLL [c] (SRLconst x [64-c]) x2)
 	// result: (EXTRconst [64-c] x2 x)
 	for {
@@ -19457,6 +20280,51 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (SRLconst [rc] (MOVWUreg x))
+	// cond: rc >= 32
+	// result: (MOVDconst [0])
+	for {
+		rc := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpARM64MOVWUreg {
+			break
+		}
+		if !(rc >= 32) {
+			break
+		}
+		v.reset(OpARM64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
+	// match: (SRLconst [rc] (MOVHUreg x))
+	// cond: rc >= 16
+	// result: (MOVDconst [0])
+	for {
+		rc := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpARM64MOVHUreg {
+			break
+		}
+		if !(rc >= 16) {
+			break
+		}
+		v.reset(OpARM64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
+	// match: (SRLconst [rc] (MOVBUreg x))
+	// cond: rc >= 8
+	// result: (MOVDconst [0])
+	for {
+		rc := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpARM64MOVBUreg {
+			break
+		}
+		if !(rc >= 8) {
+			break
+		}
+		v.reset(OpARM64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
 	// match: (SRLconst [rc] (SLLconst [lc] x))
 	// cond: lc > rc
 	// result: (UBFIZ [armBFAuxInt(lc-rc, 64-lc)] x)
@@ -21205,6 +22073,81 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (XORshiftLL [8] (UBFX [armBFAuxInt(8, 24)] (ANDconst [c1] x)) (ANDconst [c2] x))
+	// cond: uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
+	// result: (REV16W x)
+	for {
+		if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 24) {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpARM64ANDconst {
+			break
+		}
+		c1 := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
+		if v_1.Op != OpARM64ANDconst {
+			break
+		}
+		c2 := auxIntToInt64(v_1.AuxInt)
+		if x != v_1.Args[0] || !(uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff) {
+			break
+		}
+		v.reset(OpARM64REV16W)
+		v.AddArg(x)
+		return true
+	}
+	// match: (XORshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
+	// cond: (uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff)
+	// result: (REV16 x)
+	for {
+		if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpARM64ANDconst {
+			break
+		}
+		c1 := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
+		if v_1.Op != OpARM64ANDconst {
+			break
+		}
+		c2 := auxIntToInt64(v_1.AuxInt)
+		if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff) {
+			break
+		}
+		v.reset(OpARM64REV16)
+		v.AddArg(x)
+		return true
+	}
+	// match: (XORshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
+	// cond: (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff)
+	// result: (REV16 (ANDconst <x.Type> [0xffffffff] x))
+	for {
+		if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpARM64ANDconst {
+			break
+		}
+		c1 := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
+		if v_1.Op != OpARM64ANDconst {
+			break
+		}
+		c2 := auxIntToInt64(v_1.AuxInt)
+		if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) {
+			break
+		}
+		v.reset(OpARM64REV16)
+		v0 := b.NewValue0(v.Pos, OpARM64ANDconst, x.Type)
+		v0.AuxInt = int64ToAuxInt(0xffffffff)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (XORshiftLL [c] (SRLconst x [64-c]) x2)
 	// result: (EXTRconst [64-c] x2 x)
 	for {
@@ -21735,12 +22678,12 @@
 	}
 }
 func rewriteValueARM64_OpConstBool(v *Value) bool {
-	// match: (ConstBool [b])
-	// result: (MOVDconst [b2i(b)])
+	// match: (ConstBool [t])
+	// result: (MOVDconst [b2i(t)])
 	for {
-		b := auxIntToBool(v.AuxInt)
+		t := auxIntToBool(v.AuxInt)
 		v.reset(OpARM64MOVDconst)
-		v.AuxInt = int64ToAuxInt(b2i(b))
+		v.AuxInt = int64ToAuxInt(b2i(t))
 		return true
 	}
 }
@@ -25042,6 +25985,54 @@
 	}
 	return false
 }
+func rewriteValueARM64_OpSelectN(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	config := b.Func.Config
+	// match: (SelectN [0] call:(CALLstatic {sym} s1:(MOVDstore _ (MOVDconst [sz]) s2:(MOVDstore _ src s3:(MOVDstore {t} _ dst mem)))))
+	// cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1, s2, s3, call)
+	// result: (Move [sz] dst src mem)
+	for {
+		if auxIntToInt64(v.AuxInt) != 0 {
+			break
+		}
+		call := v_0
+		if call.Op != OpARM64CALLstatic {
+			break
+		}
+		sym := auxToCall(call.Aux)
+		s1 := call.Args[0]
+		if s1.Op != OpARM64MOVDstore {
+			break
+		}
+		_ = s1.Args[2]
+		s1_1 := s1.Args[1]
+		if s1_1.Op != OpARM64MOVDconst {
+			break
+		}
+		sz := auxIntToInt64(s1_1.AuxInt)
+		s2 := s1.Args[2]
+		if s2.Op != OpARM64MOVDstore {
+			break
+		}
+		_ = s2.Args[2]
+		src := s2.Args[1]
+		s3 := s2.Args[2]
+		if s3.Op != OpARM64MOVDstore {
+			break
+		}
+		mem := s3.Args[2]
+		dst := s3.Args[1]
+		if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1, s2, s3, call)) {
+			break
+		}
+		v.reset(OpMove)
+		v.AuxInt = int64ToAuxInt(sz)
+		v.AddArg3(dst, src, mem)
+		return true
+	}
+	return false
+}
 func rewriteValueARM64_OpSlicemask(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS.go b/src/cmd/compile/internal/ssa/rewriteMIPS.go
index 3fc5527..429369d 100644
--- a/src/cmd/compile/internal/ssa/rewriteMIPS.go
+++ b/src/cmd/compile/internal/ssa/rewriteMIPS.go
@@ -297,6 +297,8 @@
 		return rewriteValueMIPS_OpMIPSMOVHstorezero(v)
 	case OpMIPSMOVWload:
 		return rewriteValueMIPS_OpMIPSMOVWload(v)
+	case OpMIPSMOVWnop:
+		return rewriteValueMIPS_OpMIPSMOVWnop(v)
 	case OpMIPSMOVWreg:
 		return rewriteValueMIPS_OpMIPSMOVWreg(v)
 	case OpMIPSMOVWstore:
@@ -514,6 +516,9 @@
 	case OpSqrt:
 		v.Op = OpMIPSSQRTD
 		return true
+	case OpSqrt32:
+		v.Op = OpMIPSSQRTF
+		return true
 	case OpStaticCall:
 		v.Op = OpMIPSCALLstatic
 		return true
@@ -867,12 +872,12 @@
 	}
 }
 func rewriteValueMIPS_OpConstBool(v *Value) bool {
-	// match: (ConstBool [b])
-	// result: (MOVWconst [b2i32(b)])
+	// match: (ConstBool [t])
+	// result: (MOVWconst [b2i32(t)])
 	for {
-		b := auxIntToBool(v.AuxInt)
+		t := auxIntToBool(v.AuxInt)
 		v.reset(OpMIPSMOVWconst)
-		v.AuxInt = int32ToAuxInt(b2i32(b))
+		v.AuxInt = int32ToAuxInt(b2i32(t))
 		return true
 	}
 }
@@ -3647,6 +3652,21 @@
 	}
 	return false
 }
+func rewriteValueMIPS_OpMIPSMOVWnop(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (MOVWnop (MOVWconst [c]))
+	// result: (MOVWconst [c])
+	for {
+		if v_0.Op != OpMIPSMOVWconst {
+			break
+		}
+		c := auxIntToInt32(v_0.AuxInt)
+		v.reset(OpMIPSMOVWconst)
+		v.AuxInt = int32ToAuxInt(c)
+		return true
+	}
+	return false
+}
 func rewriteValueMIPS_OpMIPSMOVWreg(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (MOVWreg x)
diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS64.go b/src/cmd/compile/internal/ssa/rewriteMIPS64.go
index d78f608..772d7b6 100644
--- a/src/cmd/compile/internal/ssa/rewriteMIPS64.go
+++ b/src/cmd/compile/internal/ssa/rewriteMIPS64.go
@@ -339,6 +339,8 @@
 		return rewriteValueMIPS64_OpMIPS64MOVHstorezero(v)
 	case OpMIPS64MOVVload:
 		return rewriteValueMIPS64_OpMIPS64MOVVload(v)
+	case OpMIPS64MOVVnop:
+		return rewriteValueMIPS64_OpMIPS64MOVVnop(v)
 	case OpMIPS64MOVVreg:
 		return rewriteValueMIPS64_OpMIPS64MOVVreg(v)
 	case OpMIPS64MOVVstore:
@@ -594,6 +596,9 @@
 	case OpSqrt:
 		v.Op = OpMIPS64SQRTD
 		return true
+	case OpSqrt32:
+		v.Op = OpMIPS64SQRTF
+		return true
 	case OpStaticCall:
 		v.Op = OpMIPS64CALLstatic
 		return true
@@ -830,12 +835,12 @@
 	}
 }
 func rewriteValueMIPS64_OpConstBool(v *Value) bool {
-	// match: (ConstBool [b])
-	// result: (MOVVconst [int64(b2i(b))])
+	// match: (ConstBool [t])
+	// result: (MOVVconst [int64(b2i(t))])
 	for {
-		b := auxIntToBool(v.AuxInt)
+		t := auxIntToBool(v.AuxInt)
 		v.reset(OpMIPS64MOVVconst)
-		v.AuxInt = int64ToAuxInt(int64(b2i(b)))
+		v.AuxInt = int64ToAuxInt(int64(b2i(t)))
 		return true
 	}
 }
@@ -2663,6 +2668,19 @@
 		v.AddArg2(ptr, mem)
 		return true
 	}
+	// match: (MOVBload [off] {sym} (SB) _)
+	// cond: symIsRO(sym)
+	// result: (MOVVconst [int64(read8(sym, int64(off)))])
+	for {
+		off := auxIntToInt32(v.AuxInt)
+		sym := auxToSym(v.Aux)
+		if v_0.Op != OpSB || !(symIsRO(sym)) {
+			break
+		}
+		v.reset(OpMIPS64MOVVconst)
+		v.AuxInt = int64ToAuxInt(int64(read8(sym, int64(off))))
+		return true
+	}
 	return false
 }
 func rewriteValueMIPS64_OpMIPS64MOVBreg(v *Value) bool {
@@ -3227,6 +3245,8 @@
 func rewriteValueMIPS64_OpMIPS64MOVHload(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
+	b := v.Block
+	config := b.Func.Config
 	// match: (MOVHload [off1] {sym} (ADDVconst [off2] ptr) mem)
 	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVHload [off1+int32(off2)] {sym} ptr mem)
@@ -3270,6 +3290,19 @@
 		v.AddArg2(ptr, mem)
 		return true
 	}
+	// match: (MOVHload [off] {sym} (SB) _)
+	// cond: symIsRO(sym)
+	// result: (MOVVconst [int64(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+	for {
+		off := auxIntToInt32(v.AuxInt)
+		sym := auxToSym(v.Aux)
+		if v_0.Op != OpSB || !(symIsRO(sym)) {
+			break
+		}
+		v.reset(OpMIPS64MOVVconst)
+		v.AuxInt = int64ToAuxInt(int64(read16(sym, int64(off), config.ctxt.Arch.ByteOrder)))
+		return true
+	}
 	return false
 }
 func rewriteValueMIPS64_OpMIPS64MOVHreg(v *Value) bool {
@@ -3539,6 +3572,8 @@
 func rewriteValueMIPS64_OpMIPS64MOVVload(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
+	b := v.Block
+	config := b.Func.Config
 	// match: (MOVVload [off1] {sym} (ADDVconst [off2] ptr) mem)
 	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVVload [off1+int32(off2)] {sym} ptr mem)
@@ -3582,6 +3617,34 @@
 		v.AddArg2(ptr, mem)
 		return true
 	}
+	// match: (MOVVload [off] {sym} (SB) _)
+	// cond: symIsRO(sym)
+	// result: (MOVVconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+	for {
+		off := auxIntToInt32(v.AuxInt)
+		sym := auxToSym(v.Aux)
+		if v_0.Op != OpSB || !(symIsRO(sym)) {
+			break
+		}
+		v.reset(OpMIPS64MOVVconst)
+		v.AuxInt = int64ToAuxInt(int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder)))
+		return true
+	}
+	return false
+}
+func rewriteValueMIPS64_OpMIPS64MOVVnop(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (MOVVnop (MOVVconst [c]))
+	// result: (MOVVconst [c])
+	for {
+		if v_0.Op != OpMIPS64MOVVconst {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		v.reset(OpMIPS64MOVVconst)
+		v.AuxInt = int64ToAuxInt(c)
+		return true
+	}
 	return false
 }
 func rewriteValueMIPS64_OpMIPS64MOVVreg(v *Value) bool {
@@ -3858,6 +3921,8 @@
 func rewriteValueMIPS64_OpMIPS64MOVWload(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
+	b := v.Block
+	config := b.Func.Config
 	// match: (MOVWload [off1] {sym} (ADDVconst [off2] ptr) mem)
 	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVWload [off1+int32(off2)] {sym} ptr mem)
@@ -3901,6 +3966,19 @@
 		v.AddArg2(ptr, mem)
 		return true
 	}
+	// match: (MOVWload [off] {sym} (SB) _)
+	// cond: symIsRO(sym)
+	// result: (MOVVconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+	for {
+		off := auxIntToInt32(v.AuxInt)
+		sym := auxToSym(v.Aux)
+		if v_0.Op != OpSB || !(symIsRO(sym)) {
+			break
+		}
+		v.reset(OpMIPS64MOVVconst)
+		v.AuxInt = int64ToAuxInt(int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder)))
+		return true
+	}
 	return false
 }
 func rewriteValueMIPS64_OpMIPS64MOVWreg(v *Value) bool {
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go
index 455f9b1..96dee0b 100644
--- a/src/cmd/compile/internal/ssa/rewritePPC64.go
+++ b/src/cmd/compile/internal/ssa/rewritePPC64.go
@@ -3,8 +3,8 @@
 
 package ssa
 
+import "internal/buildcfg"
 import "math"
-import "cmd/internal/objabi"
 import "cmd/compile/internal/types"
 
 func rewriteValuePPC64(v *Value) bool {
@@ -743,6 +743,9 @@
 	case OpSqrt:
 		v.Op = OpPPC64FSQRT
 		return true
+	case OpSqrt32:
+		v.Op = OpPPC64FSQRTS
+		return true
 	case OpStaticCall:
 		v.Op = OpPPC64CALLstatic
 		return true
@@ -1231,12 +1234,12 @@
 	}
 }
 func rewriteValuePPC64_OpConstBool(v *Value) bool {
-	// match: (ConstBool [b])
-	// result: (MOVDconst [b2i(b)])
+	// match: (ConstBool [t])
+	// result: (MOVDconst [b2i(t)])
 	for {
-		b := auxIntToBool(v.AuxInt)
+		t := auxIntToBool(v.AuxInt)
 		v.reset(OpPPC64MOVDconst)
-		v.AuxInt = int64ToAuxInt(b2i(b))
+		v.AuxInt = int64ToAuxInt(b2i(t))
 		return true
 	}
 }
@@ -1287,11 +1290,11 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Ctz32 x)
-	// cond: objabi.GOPPC64<=8
+	// cond: buildcfg.GOPPC64<=8
 	// result: (POPCNTW (MOVWZreg (ANDN <typ.Int> (ADDconst <typ.Int> [-1] x) x)))
 	for {
 		x := v_0
-		if !(objabi.GOPPC64 <= 8) {
+		if !(buildcfg.GOPPC64 <= 8) {
 			break
 		}
 		v.reset(OpPPC64POPCNTW)
@@ -1321,11 +1324,11 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Ctz64 x)
-	// cond: objabi.GOPPC64<=8
+	// cond: buildcfg.GOPPC64<=8
 	// result: (POPCNTD (ANDN <typ.Int64> (ADDconst <typ.Int64> [-1] x) x))
 	for {
 		x := v_0
-		if !(objabi.GOPPC64 <= 8) {
+		if !(buildcfg.GOPPC64 <= 8) {
 			break
 		}
 		v.reset(OpPPC64POPCNTD)
@@ -3283,12 +3286,12 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Mod32 x y)
-	// cond: objabi.GOPPC64 >= 9
+	// cond: buildcfg.GOPPC64 >= 9
 	// result: (MODSW x y)
 	for {
 		x := v_0
 		y := v_1
-		if !(objabi.GOPPC64 >= 9) {
+		if !(buildcfg.GOPPC64 >= 9) {
 			break
 		}
 		v.reset(OpPPC64MODSW)
@@ -3296,12 +3299,12 @@
 		return true
 	}
 	// match: (Mod32 x y)
-	// cond: objabi.GOPPC64 <= 8
+	// cond: buildcfg.GOPPC64 <= 8
 	// result: (SUB x (MULLW y (DIVW x y)))
 	for {
 		x := v_0
 		y := v_1
-		if !(objabi.GOPPC64 <= 8) {
+		if !(buildcfg.GOPPC64 <= 8) {
 			break
 		}
 		v.reset(OpPPC64SUB)
@@ -3320,12 +3323,12 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Mod32u x y)
-	// cond: objabi.GOPPC64 >= 9
+	// cond: buildcfg.GOPPC64 >= 9
 	// result: (MODUW x y)
 	for {
 		x := v_0
 		y := v_1
-		if !(objabi.GOPPC64 >= 9) {
+		if !(buildcfg.GOPPC64 >= 9) {
 			break
 		}
 		v.reset(OpPPC64MODUW)
@@ -3333,12 +3336,12 @@
 		return true
 	}
 	// match: (Mod32u x y)
-	// cond: objabi.GOPPC64 <= 8
+	// cond: buildcfg.GOPPC64 <= 8
 	// result: (SUB x (MULLW y (DIVWU x y)))
 	for {
 		x := v_0
 		y := v_1
-		if !(objabi.GOPPC64 <= 8) {
+		if !(buildcfg.GOPPC64 <= 8) {
 			break
 		}
 		v.reset(OpPPC64SUB)
@@ -3357,12 +3360,12 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Mod64 x y)
-	// cond: objabi.GOPPC64 >=9
+	// cond: buildcfg.GOPPC64 >=9
 	// result: (MODSD x y)
 	for {
 		x := v_0
 		y := v_1
-		if !(objabi.GOPPC64 >= 9) {
+		if !(buildcfg.GOPPC64 >= 9) {
 			break
 		}
 		v.reset(OpPPC64MODSD)
@@ -3370,12 +3373,12 @@
 		return true
 	}
 	// match: (Mod64 x y)
-	// cond: objabi.GOPPC64 <=8
+	// cond: buildcfg.GOPPC64 <=8
 	// result: (SUB x (MULLD y (DIVD x y)))
 	for {
 		x := v_0
 		y := v_1
-		if !(objabi.GOPPC64 <= 8) {
+		if !(buildcfg.GOPPC64 <= 8) {
 			break
 		}
 		v.reset(OpPPC64SUB)
@@ -3394,12 +3397,12 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Mod64u x y)
-	// cond: objabi.GOPPC64 >= 9
+	// cond: buildcfg.GOPPC64 >= 9
 	// result: (MODUD x y)
 	for {
 		x := v_0
 		y := v_1
-		if !(objabi.GOPPC64 >= 9) {
+		if !(buildcfg.GOPPC64 >= 9) {
 			break
 		}
 		v.reset(OpPPC64MODUD)
@@ -3407,12 +3410,12 @@
 		return true
 	}
 	// match: (Mod64u x y)
-	// cond: objabi.GOPPC64 <= 8
+	// cond: buildcfg.GOPPC64 <= 8
 	// result: (SUB x (MULLD y (DIVDU x y)))
 	for {
 		x := v_0
 		y := v_1
-		if !(objabi.GOPPC64 <= 8) {
+		if !(buildcfg.GOPPC64 <= 8) {
 			break
 		}
 		v.reset(OpPPC64SUB)
@@ -3525,46 +3528,20 @@
 		return true
 	}
 	// match: (Move [8] {t} dst src mem)
-	// cond: t.Alignment()%4 == 0
 	// result: (MOVDstore dst (MOVDload src mem) mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 8 {
 			break
 		}
-		t := auxToType(v.Aux)
 		dst := v_0
 		src := v_1
 		mem := v_2
-		if !(t.Alignment()%4 == 0) {
-			break
-		}
 		v.reset(OpPPC64MOVDstore)
 		v0 := b.NewValue0(v.Pos, OpPPC64MOVDload, typ.Int64)
 		v0.AddArg2(src, mem)
 		v.AddArg3(dst, v0, mem)
 		return true
 	}
-	// match: (Move [8] dst src mem)
-	// result: (MOVWstore [4] dst (MOVWZload [4] src mem) (MOVWstore dst (MOVWZload src mem) mem))
-	for {
-		if auxIntToInt64(v.AuxInt) != 8 {
-			break
-		}
-		dst := v_0
-		src := v_1
-		mem := v_2
-		v.reset(OpPPC64MOVWstore)
-		v.AuxInt = int32ToAuxInt(4)
-		v0 := b.NewValue0(v.Pos, OpPPC64MOVWZload, typ.UInt32)
-		v0.AuxInt = int32ToAuxInt(4)
-		v0.AddArg2(src, mem)
-		v1 := b.NewValue0(v.Pos, OpPPC64MOVWstore, types.TypeMem)
-		v2 := b.NewValue0(v.Pos, OpPPC64MOVWZload, typ.UInt32)
-		v2.AddArg2(src, mem)
-		v1.AddArg3(dst, v2, mem)
-		v.AddArg3(dst, v0, v1)
-		return true
-	}
 	// match: (Move [3] dst src mem)
 	// result: (MOVBstore [2] dst (MOVBZload [2] src mem) (MOVHstore dst (MOVHload src mem) mem))
 	for {
@@ -3656,14 +3633,14 @@
 		return true
 	}
 	// match: (Move [s] dst src mem)
-	// cond: s > 8 && objabi.GOPPC64 <= 8 && logLargeCopy(v, s)
+	// cond: s > 8 && buildcfg.GOPPC64 <= 8 && logLargeCopy(v, s)
 	// result: (LoweredMove [s] dst src mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		dst := v_0
 		src := v_1
 		mem := v_2
-		if !(s > 8 && objabi.GOPPC64 <= 8 && logLargeCopy(v, s)) {
+		if !(s > 8 && buildcfg.GOPPC64 <= 8 && logLargeCopy(v, s)) {
 			break
 		}
 		v.reset(OpPPC64LoweredMove)
@@ -3672,14 +3649,14 @@
 		return true
 	}
 	// match: (Move [s] dst src mem)
-	// cond: s > 8 && s <= 64 && objabi.GOPPC64 >= 9
+	// cond: s > 8 && s <= 64 && buildcfg.GOPPC64 >= 9
 	// result: (LoweredQuadMoveShort [s] dst src mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		dst := v_0
 		src := v_1
 		mem := v_2
-		if !(s > 8 && s <= 64 && objabi.GOPPC64 >= 9) {
+		if !(s > 8 && s <= 64 && buildcfg.GOPPC64 >= 9) {
 			break
 		}
 		v.reset(OpPPC64LoweredQuadMoveShort)
@@ -3688,14 +3665,14 @@
 		return true
 	}
 	// match: (Move [s] dst src mem)
-	// cond: s > 8 && objabi.GOPPC64 >= 9 && logLargeCopy(v, s)
+	// cond: s > 8 && buildcfg.GOPPC64 >= 9 && logLargeCopy(v, s)
 	// result: (LoweredQuadMove [s] dst src mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		dst := v_0
 		src := v_1
 		mem := v_2
-		if !(s > 8 && objabi.GOPPC64 >= 9 && logLargeCopy(v, s)) {
+		if !(s > 8 && buildcfg.GOPPC64 >= 9 && logLargeCopy(v, s)) {
 			break
 		}
 		v.reset(OpPPC64LoweredQuadMove)
@@ -3905,7 +3882,7 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (ADD l:(MULLD x y) z)
-	// cond: objabi.GOPPC64 >= 9 && l.Uses == 1 && clobber(l)
+	// cond: buildcfg.GOPPC64 >= 9 && l.Uses == 1 && clobber(l)
 	// result: (MADDLD x y z)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -3916,7 +3893,7 @@
 			y := l.Args[1]
 			x := l.Args[0]
 			z := v_1
-			if !(objabi.GOPPC64 >= 9 && l.Uses == 1 && clobber(l)) {
+			if !(buildcfg.GOPPC64 >= 9 && l.Uses == 1 && clobber(l)) {
 				continue
 			}
 			v.reset(OpPPC64MADDLD)
@@ -4777,12 +4754,12 @@
 		return true
 	}
 	// match: (CMP x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMP y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpPPC64InvertFlags)
@@ -4834,12 +4811,12 @@
 		return true
 	}
 	// match: (CMPU x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPU y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpPPC64InvertFlags)
@@ -4964,12 +4941,12 @@
 		return true
 	}
 	// match: (CMPW x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPW y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpPPC64InvertFlags)
@@ -5045,12 +5022,12 @@
 		return true
 	}
 	// match: (CMPWU x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPWU y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpPPC64InvertFlags)
@@ -7878,7 +7855,7 @@
 		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:(MOVWstore [i0] {s} p w mem)))))
-	// cond: !config.BigEndian && i0%4 == 0 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && clobber(x0, x1, x2, x3)
+	// cond: !config.BigEndian && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && clobber(x0, x1, x2, x3)
 	// result: (MOVDstore [i0] {s} p w mem)
 	for {
 		i7 := auxIntToInt32(v.AuxInt)
@@ -7945,7 +7922,7 @@
 			break
 		}
 		mem := x3.Args[2]
-		if p != x3.Args[0] || w != x3.Args[1] || !(!config.BigEndian && i0%4 == 0 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && clobber(x0, x1, x2, x3)) {
+		if p != x3.Args[0] || w != x3.Args[1] || !(!config.BigEndian && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && clobber(x0, x1, x2, x3)) {
 			break
 		}
 		v.reset(OpPPC64MOVDstore)
@@ -8389,7 +8366,7 @@
 		return true
 	}
 	// match: (MOVDload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0
+	// cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -8402,7 +8379,7 @@
 		sym2 := auxToSym(p.Aux)
 		ptr := p.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0) {
+		if !(canMergeSym(sym1, sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVDload)
@@ -8412,7 +8389,7 @@
 		return true
 	}
 	// match: (MOVDload [off1] {sym} (ADDconst [off2] x) mem)
-	// cond: is16Bit(int64(off1)+off2) && (int64(off1)+off2)%4 == 0
+	// cond: is16Bit(int64(off1)+off2)
 	// result: (MOVDload [off1+int32(off2)] {sym} x mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -8423,7 +8400,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		x := v_0.Args[0]
 		mem := v_1
-		if !(is16Bit(int64(off1)+off2) && (int64(off1)+off2)%4 == 0) {
+		if !(is16Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpPPC64MOVDload)
@@ -8520,7 +8497,7 @@
 		return true
 	}
 	// match: (MOVDstore [off1] {sym} (ADDconst [off2] x) val mem)
-	// cond: is16Bit(int64(off1)+off2) && (int64(off1)+off2)%4 == 0
+	// cond: is16Bit(int64(off1)+off2)
 	// result: (MOVDstore [off1+int32(off2)] {sym} x val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -8532,7 +8509,7 @@
 		x := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(is16Bit(int64(off1)+off2) && (int64(off1)+off2)%4 == 0) {
+		if !(is16Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpPPC64MOVDstore)
@@ -8542,7 +8519,7 @@
 		return true
 	}
 	// match: (MOVDstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0
+	// cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -8556,7 +8533,7 @@
 		ptr := p.Args[0]
 		val := v_1
 		mem := v_2
-		if !(canMergeSym(sym1, sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0) {
+		if !(canMergeSym(sym1, sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVDstore)
@@ -8655,7 +8632,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (MOVDstorezero [off1] {sym} (ADDconst [off2] x) mem)
-	// cond: is16Bit(int64(off1)+off2) && (int64(off1)+off2)%4 == 0
+	// cond: is16Bit(int64(off1)+off2)
 	// result: (MOVDstorezero [off1+int32(off2)] {sym} x mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -8666,7 +8643,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		x := v_0.Args[0]
 		mem := v_1
-		if !(is16Bit(int64(off1)+off2) && (int64(off1)+off2)%4 == 0) {
+		if !(is16Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpPPC64MOVDstorezero)
@@ -8676,7 +8653,7 @@
 		return true
 	}
 	// match: (MOVDstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem)
-	// cond: canMergeSym(sym1,sym2) && (x.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0
+	// cond: canMergeSym(sym1,sym2) && (x.Op != OpSB || p.Uses == 1)
 	// result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -8689,7 +8666,7 @@
 		sym2 := auxToSym(p.Aux)
 		x := p.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && (x.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0) {
+		if !(canMergeSym(sym1, sym2) && (x.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVDstorezero)
@@ -10595,7 +10572,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (MOVWload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0
+	// cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1)
 	// result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -10608,7 +10585,7 @@
 		sym2 := auxToSym(p.Aux)
 		ptr := p.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0) {
+		if !(canMergeSym(sym1, sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1)) {
 			break
 		}
 		v.reset(OpPPC64MOVWload)
@@ -10618,7 +10595,7 @@
 		return true
 	}
 	// match: (MOVWload [off1] {sym} (ADDconst [off2] x) mem)
-	// cond: is16Bit(int64(off1)+off2) && (int64(off1)+off2)%4 == 0
+	// cond: is16Bit(int64(off1)+off2)
 	// result: (MOVWload [off1+int32(off2)] {sym} x mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -10629,7 +10606,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		x := v_0.Args[0]
 		mem := v_1
-		if !(is16Bit(int64(off1)+off2) && (int64(off1)+off2)%4 == 0) {
+		if !(is16Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpPPC64MOVWload)
@@ -12501,7 +12478,7 @@
 		break
 	}
 	// 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]) x0:(MOVWZload {s} [i0] p mem)))))
-	// cond: !config.BigEndian && i0%4 == 0 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x4, x5, x6, x7) != nil && clobber(x0, x4, x5, x6, x7, s3, s4, s5, s6, o3, o4, o5)
+	// cond: !config.BigEndian && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x4, x5, x6, x7) != nil && clobber(x0, x4, x5, x6, x7, s3, s4, s5, s6, o3, o4, o5)
 	// result: @mergePoint(b,x0,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
 	for {
 		t := v.Type
@@ -12599,7 +12576,7 @@
 							continue
 						}
 						_ = x0.Args[1]
-						if p != x0.Args[0] || mem != x0.Args[1] || !(!config.BigEndian && i0%4 == 0 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x4, x5, x6, x7) != nil && clobber(x0, x4, x5, x6, x7, s3, s4, s5, s6, o3, o4, o5)) {
+						if p != x0.Args[0] || mem != x0.Args[1] || !(!config.BigEndian && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1 && mergePoint(b, x0, x4, x5, x6, x7) != nil && clobber(x0, x4, x5, x6, x7, s3, s4, s5, s6, o3, o4, o5)) {
 							continue
 						}
 						b = mergePoint(b, x0, x4, x5, x6, x7)
@@ -13264,7 +13241,7 @@
 		break
 	}
 	// match: (SLDconst [c] z:(MOVWreg x))
-	// cond: c < 32 && objabi.GOPPC64 >= 9
+	// cond: c < 32 && buildcfg.GOPPC64 >= 9
 	// result: (EXTSWSLconst [c] x)
 	for {
 		c := auxIntToInt64(v.AuxInt)
@@ -13273,7 +13250,7 @@
 			break
 		}
 		x := z.Args[0]
-		if !(c < 32 && objabi.GOPPC64 >= 9) {
+		if !(c < 32 && buildcfg.GOPPC64 >= 9) {
 			break
 		}
 		v.reset(OpPPC64EXTSWSLconst)
@@ -13387,7 +13364,7 @@
 		break
 	}
 	// match: (SLWconst [c] z:(MOVWreg x))
-	// cond: c < 32 && objabi.GOPPC64 >= 9
+	// cond: c < 32 && buildcfg.GOPPC64 >= 9
 	// result: (EXTSWSLconst [c] x)
 	for {
 		c := auxIntToInt64(v.AuxInt)
@@ -13396,7 +13373,7 @@
 			break
 		}
 		x := z.Args[0]
-		if !(c < 32 && objabi.GOPPC64 >= 9) {
+		if !(c < 32 && buildcfg.GOPPC64 >= 9) {
 			break
 		}
 		v.reset(OpPPC64EXTSWSLconst)
@@ -16844,51 +16821,25 @@
 		return true
 	}
 	// match: (Zero [8] {t} destptr mem)
-	// cond: t.Alignment()%4 == 0
 	// result: (MOVDstorezero destptr mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 8 {
 			break
 		}
-		t := auxToType(v.Aux)
 		destptr := v_0
 		mem := v_1
-		if !(t.Alignment()%4 == 0) {
-			break
-		}
 		v.reset(OpPPC64MOVDstorezero)
 		v.AddArg2(destptr, mem)
 		return true
 	}
-	// match: (Zero [8] destptr mem)
-	// result: (MOVWstorezero [4] destptr (MOVWstorezero [0] destptr mem))
-	for {
-		if auxIntToInt64(v.AuxInt) != 8 {
-			break
-		}
-		destptr := v_0
-		mem := v_1
-		v.reset(OpPPC64MOVWstorezero)
-		v.AuxInt = int32ToAuxInt(4)
-		v0 := b.NewValue0(v.Pos, OpPPC64MOVWstorezero, types.TypeMem)
-		v0.AuxInt = int32ToAuxInt(0)
-		v0.AddArg2(destptr, mem)
-		v.AddArg2(destptr, v0)
-		return true
-	}
 	// match: (Zero [12] {t} destptr mem)
-	// cond: t.Alignment()%4 == 0
 	// result: (MOVWstorezero [8] destptr (MOVDstorezero [0] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 12 {
 			break
 		}
-		t := auxToType(v.Aux)
 		destptr := v_0
 		mem := v_1
-		if !(t.Alignment()%4 == 0) {
-			break
-		}
 		v.reset(OpPPC64MOVWstorezero)
 		v.AuxInt = int32ToAuxInt(8)
 		v0 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
@@ -16898,18 +16849,13 @@
 		return true
 	}
 	// match: (Zero [16] {t} destptr mem)
-	// cond: t.Alignment()%4 == 0
 	// result: (MOVDstorezero [8] destptr (MOVDstorezero [0] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 16 {
 			break
 		}
-		t := auxToType(v.Aux)
 		destptr := v_0
 		mem := v_1
-		if !(t.Alignment()%4 == 0) {
-			break
-		}
 		v.reset(OpPPC64MOVDstorezero)
 		v.AuxInt = int32ToAuxInt(8)
 		v0 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
@@ -16919,18 +16865,13 @@
 		return true
 	}
 	// match: (Zero [24] {t} destptr mem)
-	// cond: t.Alignment()%4 == 0
 	// result: (MOVDstorezero [16] destptr (MOVDstorezero [8] destptr (MOVDstorezero [0] destptr mem)))
 	for {
 		if auxIntToInt64(v.AuxInt) != 24 {
 			break
 		}
-		t := auxToType(v.Aux)
 		destptr := v_0
 		mem := v_1
-		if !(t.Alignment()%4 == 0) {
-			break
-		}
 		v.reset(OpPPC64MOVDstorezero)
 		v.AuxInt = int32ToAuxInt(16)
 		v0 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
@@ -16943,18 +16884,13 @@
 		return true
 	}
 	// match: (Zero [32] {t} destptr mem)
-	// cond: t.Alignment()%4 == 0
 	// result: (MOVDstorezero [24] destptr (MOVDstorezero [16] destptr (MOVDstorezero [8] destptr (MOVDstorezero [0] destptr mem))))
 	for {
 		if auxIntToInt64(v.AuxInt) != 32 {
 			break
 		}
-		t := auxToType(v.Aux)
 		destptr := v_0
 		mem := v_1
-		if !(t.Alignment()%4 == 0) {
-			break
-		}
 		v.reset(OpPPC64MOVDstorezero)
 		v.AuxInt = int32ToAuxInt(24)
 		v0 := b.NewValue0(v.Pos, OpPPC64MOVDstorezero, types.TypeMem)
@@ -16970,13 +16906,13 @@
 		return true
 	}
 	// match: (Zero [s] ptr mem)
-	// cond: objabi.GOPPC64 <= 8 && s < 64
+	// cond: buildcfg.GOPPC64 <= 8 && s < 64
 	// result: (LoweredZeroShort [s] ptr mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		ptr := v_0
 		mem := v_1
-		if !(objabi.GOPPC64 <= 8 && s < 64) {
+		if !(buildcfg.GOPPC64 <= 8 && s < 64) {
 			break
 		}
 		v.reset(OpPPC64LoweredZeroShort)
@@ -16985,13 +16921,13 @@
 		return true
 	}
 	// match: (Zero [s] ptr mem)
-	// cond: objabi.GOPPC64 <= 8
+	// cond: buildcfg.GOPPC64 <= 8
 	// result: (LoweredZero [s] ptr mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		ptr := v_0
 		mem := v_1
-		if !(objabi.GOPPC64 <= 8) {
+		if !(buildcfg.GOPPC64 <= 8) {
 			break
 		}
 		v.reset(OpPPC64LoweredZero)
@@ -17000,13 +16936,13 @@
 		return true
 	}
 	// match: (Zero [s] ptr mem)
-	// cond: s < 128 && objabi.GOPPC64 >= 9
+	// cond: s < 128 && buildcfg.GOPPC64 >= 9
 	// result: (LoweredQuadZeroShort [s] ptr mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		ptr := v_0
 		mem := v_1
-		if !(s < 128 && objabi.GOPPC64 >= 9) {
+		if !(s < 128 && buildcfg.GOPPC64 >= 9) {
 			break
 		}
 		v.reset(OpPPC64LoweredQuadZeroShort)
@@ -17015,13 +16951,13 @@
 		return true
 	}
 	// match: (Zero [s] ptr mem)
-	// cond: objabi.GOPPC64 >= 9
+	// cond: buildcfg.GOPPC64 >= 9
 	// result: (LoweredQuadZero [s] ptr mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		ptr := v_0
 		mem := v_1
-		if !(objabi.GOPPC64 >= 9) {
+		if !(buildcfg.GOPPC64 >= 9) {
 			break
 		}
 		v.reset(OpPPC64LoweredQuadZero)
diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go
index fb507b6..431fb1a 100644
--- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go
+++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go
@@ -52,6 +52,11 @@
 	case OpAtomicAdd64:
 		v.Op = OpRISCV64LoweredAtomicAdd64
 		return true
+	case OpAtomicAnd32:
+		v.Op = OpRISCV64LoweredAtomicAnd32
+		return true
+	case OpAtomicAnd8:
+		return rewriteValueRISCV64_OpAtomicAnd8(v)
 	case OpAtomicCompareAndSwap32:
 		v.Op = OpRISCV64LoweredAtomicCas32
 		return true
@@ -76,6 +81,11 @@
 	case OpAtomicLoadPtr:
 		v.Op = OpRISCV64LoweredAtomicLoad64
 		return true
+	case OpAtomicOr32:
+		v.Op = OpRISCV64LoweredAtomicOr32
+		return true
+	case OpAtomicOr8:
+		return rewriteValueRISCV64_OpAtomicOr8(v)
 	case OpAtomicStore32:
 		v.Op = OpRISCV64LoweredAtomicStore32
 		return true
@@ -106,21 +116,17 @@
 		v.Op = OpRISCV64NOT
 		return true
 	case OpConst16:
-		v.Op = OpRISCV64MOVHconst
-		return true
+		return rewriteValueRISCV64_OpConst16(v)
 	case OpConst32:
-		v.Op = OpRISCV64MOVWconst
-		return true
+		return rewriteValueRISCV64_OpConst32(v)
 	case OpConst32F:
 		return rewriteValueRISCV64_OpConst32F(v)
 	case OpConst64:
-		v.Op = OpRISCV64MOVDconst
-		return true
+		return rewriteValueRISCV64_OpConst64(v)
 	case OpConst64F:
 		return rewriteValueRISCV64_OpConst64F(v)
 	case OpConst8:
-		v.Op = OpRISCV64MOVBconst
-		return true
+		return rewriteValueRISCV64_OpConst8(v)
 	case OpConstBool:
 		return rewriteValueRISCV64_OpConstBool(v)
 	case OpConstNil:
@@ -229,7 +235,8 @@
 		v.Op = OpLess64U
 		return true
 	case OpIsNonNil:
-		return rewriteValueRISCV64_OpIsNonNil(v)
+		v.Op = OpRISCV64SNEZ
+		return true
 	case OpIsSliceInBounds:
 		v.Op = OpLeq64U
 		return true
@@ -431,10 +438,10 @@
 		return rewriteValueRISCV64_OpRISCV64MOVBstore(v)
 	case OpRISCV64MOVBstorezero:
 		return rewriteValueRISCV64_OpRISCV64MOVBstorezero(v)
-	case OpRISCV64MOVDconst:
-		return rewriteValueRISCV64_OpRISCV64MOVDconst(v)
 	case OpRISCV64MOVDload:
 		return rewriteValueRISCV64_OpRISCV64MOVDload(v)
+	case OpRISCV64MOVDnop:
+		return rewriteValueRISCV64_OpRISCV64MOVDnop(v)
 	case OpRISCV64MOVDreg:
 		return rewriteValueRISCV64_OpRISCV64MOVDreg(v)
 	case OpRISCV64MOVDstore:
@@ -580,6 +587,9 @@
 	case OpSqrt:
 		v.Op = OpRISCV64FSQRTD
 		return true
+	case OpSqrt32:
+		v.Op = OpRISCV64FSQRTS
+		return true
 	case OpStaticCall:
 		v.Op = OpRISCV64CALLstatic
 		return true
@@ -676,6 +686,71 @@
 		return true
 	}
 }
+func rewriteValueRISCV64_OpAtomicAnd8(v *Value) bool {
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (AtomicAnd8 ptr val mem)
+	// result: (LoweredAtomicAnd32 (ANDI <typ.Uintptr> [^3] ptr) (NOT <typ.UInt32> (SLL <typ.UInt32> (XORI <typ.UInt32> [0xff] (ZeroExt8to32 val)) (SLLI <typ.UInt64> [3] (ANDI <typ.UInt64> [3] ptr)))) mem)
+	for {
+		ptr := v_0
+		val := v_1
+		mem := v_2
+		v.reset(OpRISCV64LoweredAtomicAnd32)
+		v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Uintptr)
+		v0.AuxInt = int64ToAuxInt(^3)
+		v0.AddArg(ptr)
+		v1 := b.NewValue0(v.Pos, OpRISCV64NOT, typ.UInt32)
+		v2 := b.NewValue0(v.Pos, OpRISCV64SLL, typ.UInt32)
+		v3 := b.NewValue0(v.Pos, OpRISCV64XORI, typ.UInt32)
+		v3.AuxInt = int64ToAuxInt(0xff)
+		v4 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+		v4.AddArg(val)
+		v3.AddArg(v4)
+		v5 := b.NewValue0(v.Pos, OpRISCV64SLLI, typ.UInt64)
+		v5.AuxInt = int64ToAuxInt(3)
+		v6 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.UInt64)
+		v6.AuxInt = int64ToAuxInt(3)
+		v6.AddArg(ptr)
+		v5.AddArg(v6)
+		v2.AddArg2(v3, v5)
+		v1.AddArg(v2)
+		v.AddArg3(v0, v1, mem)
+		return true
+	}
+}
+func rewriteValueRISCV64_OpAtomicOr8(v *Value) bool {
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (AtomicOr8 ptr val mem)
+	// result: (LoweredAtomicOr32 (ANDI <typ.Uintptr> [^3] ptr) (SLL <typ.UInt32> (ZeroExt8to32 val) (SLLI <typ.UInt64> [3] (ANDI <typ.UInt64> [3] ptr))) mem)
+	for {
+		ptr := v_0
+		val := v_1
+		mem := v_2
+		v.reset(OpRISCV64LoweredAtomicOr32)
+		v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Uintptr)
+		v0.AuxInt = int64ToAuxInt(^3)
+		v0.AddArg(ptr)
+		v1 := b.NewValue0(v.Pos, OpRISCV64SLL, typ.UInt32)
+		v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+		v2.AddArg(val)
+		v3 := b.NewValue0(v.Pos, OpRISCV64SLLI, typ.UInt64)
+		v3.AuxInt = int64ToAuxInt(3)
+		v4 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.UInt64)
+		v4.AuxInt = int64ToAuxInt(3)
+		v4.AddArg(ptr)
+		v3.AddArg(v4)
+		v1.AddArg2(v2, v3)
+		v.AddArg3(v0, v1, mem)
+		return true
+	}
+}
 func rewriteValueRISCV64_OpAvg64u(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
@@ -704,20 +779,50 @@
 		return true
 	}
 }
+func rewriteValueRISCV64_OpConst16(v *Value) bool {
+	// match: (Const16 [val])
+	// result: (MOVDconst [int64(val)])
+	for {
+		val := auxIntToInt16(v.AuxInt)
+		v.reset(OpRISCV64MOVDconst)
+		v.AuxInt = int64ToAuxInt(int64(val))
+		return true
+	}
+}
+func rewriteValueRISCV64_OpConst32(v *Value) bool {
+	// match: (Const32 [val])
+	// result: (MOVDconst [int64(val)])
+	for {
+		val := auxIntToInt32(v.AuxInt)
+		v.reset(OpRISCV64MOVDconst)
+		v.AuxInt = int64ToAuxInt(int64(val))
+		return true
+	}
+}
 func rewriteValueRISCV64_OpConst32F(v *Value) bool {
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Const32F [val])
-	// result: (FMVSX (MOVWconst [int32(math.Float32bits(val))]))
+	// result: (FMVSX (MOVDconst [int64(math.Float32bits(val))]))
 	for {
 		val := auxIntToFloat32(v.AuxInt)
 		v.reset(OpRISCV64FMVSX)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVWconst, typ.UInt32)
-		v0.AuxInt = int32ToAuxInt(int32(math.Float32bits(val)))
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(int64(math.Float32bits(val)))
 		v.AddArg(v0)
 		return true
 	}
 }
+func rewriteValueRISCV64_OpConst64(v *Value) bool {
+	// match: (Const64 [val])
+	// result: (MOVDconst [int64(val)])
+	for {
+		val := auxIntToInt64(v.AuxInt)
+		v.reset(OpRISCV64MOVDconst)
+		v.AuxInt = int64ToAuxInt(int64(val))
+		return true
+	}
+}
 func rewriteValueRISCV64_OpConst64F(v *Value) bool {
 	b := v.Block
 	typ := &b.Func.Config.Types
@@ -732,13 +837,23 @@
 		return true
 	}
 }
+func rewriteValueRISCV64_OpConst8(v *Value) bool {
+	// match: (Const8 [val])
+	// result: (MOVDconst [int64(val)])
+	for {
+		val := auxIntToInt8(v.AuxInt)
+		v.reset(OpRISCV64MOVDconst)
+		v.AuxInt = int64ToAuxInt(int64(val))
+		return true
+	}
+}
 func rewriteValueRISCV64_OpConstBool(v *Value) bool {
 	// match: (ConstBool [val])
-	// result: (MOVBconst [int8(b2i(val))])
+	// result: (MOVDconst [int64(b2i(val))])
 	for {
 		val := auxIntToBool(v.AuxInt)
-		v.reset(OpRISCV64MOVBconst)
-		v.AuxInt = int8ToAuxInt(int8(b2i(val)))
+		v.reset(OpRISCV64MOVDconst)
+		v.AuxInt = int64ToAuxInt(int64(b2i(val)))
 		return true
 	}
 }
@@ -890,14 +1005,19 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	typ := &b.Func.Config.Types
 	// match: (Eq32 x y)
-	// result: (SEQZ (SUBW <x.Type> x y))
+	// result: (SEQZ (SUB <x.Type> (ZeroExt32to64 x) (ZeroExt32to64 y)))
 	for {
 		x := v_0
 		y := v_1
 		v.reset(OpRISCV64SEQZ)
-		v0 := b.NewValue0(v.Pos, OpRISCV64SUBW, x.Type)
-		v0.AddArg2(x, y)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SUB, x.Type)
+		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v1.AddArg(x)
+		v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v2.AddArg(y)
+		v0.AddArg2(v1, v2)
 		v.AddArg(v0)
 		return true
 	}
@@ -1016,21 +1136,6 @@
 		return true
 	}
 }
-func rewriteValueRISCV64_OpIsNonNil(v *Value) bool {
-	v_0 := v.Args[0]
-	b := v.Block
-	typ := &b.Func.Config.Types
-	// match: (IsNonNil p)
-	// result: (NeqPtr (MOVDconst [0]) p)
-	for {
-		p := v_0
-		v.reset(OpNeqPtr)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
-		v0.AuxInt = int64ToAuxInt(0)
-		v.AddArg2(v0, p)
-		return true
-	}
-}
 func rewriteValueRISCV64_OpLeq16(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
@@ -2466,14 +2571,19 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	typ := &b.Func.Config.Types
 	// match: (Neq32 x y)
-	// result: (SNEZ (SUBW <x.Type> x y))
+	// result: (SNEZ (SUB <x.Type> (ZeroExt32to64 x) (ZeroExt32to64 y)))
 	for {
 		x := v_0
 		y := v_1
 		v.reset(OpRISCV64SNEZ)
-		v0 := b.NewValue0(v.Pos, OpRISCV64SUBW, x.Type)
-		v0.AddArg2(x, y)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SUB, x.Type)
+		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v1.AddArg(x)
+		v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v2.AddArg(y)
+		v0.AddArg2(v1, v2)
 		v.AddArg(v0)
 		return true
 	}
@@ -2632,54 +2742,6 @@
 func rewriteValueRISCV64_OpRISCV64ADD(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (ADD (MOVBconst [val]) x)
-	// result: (ADDI [int64(val)] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpRISCV64MOVBconst {
-				continue
-			}
-			val := auxIntToInt8(v_0.AuxInt)
-			x := v_1
-			v.reset(OpRISCV64ADDI)
-			v.AuxInt = int64ToAuxInt(int64(val))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (ADD (MOVHconst [val]) x)
-	// result: (ADDI [int64(val)] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpRISCV64MOVHconst {
-				continue
-			}
-			val := auxIntToInt16(v_0.AuxInt)
-			x := v_1
-			v.reset(OpRISCV64ADDI)
-			v.AuxInt = int64ToAuxInt(int64(val))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (ADD (MOVWconst [val]) x)
-	// result: (ADDI [int64(val)] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpRISCV64MOVWconst {
-				continue
-			}
-			val := auxIntToInt32(v_0.AuxInt)
-			x := v_1
-			v.reset(OpRISCV64ADDI)
-			v.AuxInt = int64ToAuxInt(int64(val))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (ADD (MOVDconst [val]) x)
 	// cond: is32Bit(val)
 	// result: (ADDI [val] x)
@@ -2739,54 +2801,6 @@
 func rewriteValueRISCV64_OpRISCV64AND(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (AND (MOVBconst [val]) x)
-	// result: (ANDI [int64(val)] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpRISCV64MOVBconst {
-				continue
-			}
-			val := auxIntToInt8(v_0.AuxInt)
-			x := v_1
-			v.reset(OpRISCV64ANDI)
-			v.AuxInt = int64ToAuxInt(int64(val))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (AND (MOVHconst [val]) x)
-	// result: (ANDI [int64(val)] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpRISCV64MOVHconst {
-				continue
-			}
-			val := auxIntToInt16(v_0.AuxInt)
-			x := v_1
-			v.reset(OpRISCV64ANDI)
-			v.AuxInt = int64ToAuxInt(int64(val))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (AND (MOVWconst [val]) x)
-	// result: (ANDI [int64(val)] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpRISCV64MOVWconst {
-				continue
-			}
-			val := auxIntToInt32(v_0.AuxInt)
-			x := v_1
-			v.reset(OpRISCV64ANDI)
-			v.AuxInt = int64ToAuxInt(int64(val))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (AND (MOVDconst [val]) x)
 	// cond: is32Bit(val)
 	// result: (ANDI [val] x)
@@ -2860,13 +2874,13 @@
 func rewriteValueRISCV64_OpRISCV64MOVBUreg(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (MOVBUreg (MOVBconst [c]))
+	// match: (MOVBUreg (MOVDconst [c]))
 	// result: (MOVDconst [int64(uint8(c))])
 	for {
-		if v_0.Op != OpRISCV64MOVBconst {
+		if v_0.Op != OpRISCV64MOVDconst {
 			break
 		}
-		c := auxIntToInt8(v_0.AuxInt)
+		c := auxIntToInt64(v_0.AuxInt)
 		v.reset(OpRISCV64MOVDconst)
 		v.AuxInt = int64ToAuxInt(int64(uint8(c)))
 		return true
@@ -2970,15 +2984,15 @@
 func rewriteValueRISCV64_OpRISCV64MOVBreg(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (MOVBreg (MOVBconst [c]))
-	// result: (MOVDconst [int64(c)])
+	// match: (MOVBreg (MOVDconst [c]))
+	// result: (MOVDconst [int64(int8(c))])
 	for {
-		if v_0.Op != OpRISCV64MOVBconst {
+		if v_0.Op != OpRISCV64MOVDconst {
 			break
 		}
-		c := auxIntToInt8(v_0.AuxInt)
+		c := auxIntToInt64(v_0.AuxInt)
 		v.reset(OpRISCV64MOVDconst)
-		v.AuxInt = int64ToAuxInt(int64(c))
+		v.AuxInt = int64ToAuxInt(int64(int8(c)))
 		return true
 	}
 	// match: (MOVBreg x:(MOVBload _ _))
@@ -3078,13 +3092,13 @@
 		v.AddArg3(base, val, mem)
 		return true
 	}
-	// match: (MOVBstore [off] {sym} ptr (MOVBconst [0]) mem)
+	// match: (MOVBstore [off] {sym} ptr (MOVDconst [0]) mem)
 	// result: (MOVBstorezero [off] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
 		ptr := v_0
-		if v_1.Op != OpRISCV64MOVBconst || auxIntToInt8(v_1.AuxInt) != 0 {
+		if v_1.Op != OpRISCV64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
 			break
 		}
 		mem := v_2
@@ -3246,51 +3260,6 @@
 	}
 	return false
 }
-func rewriteValueRISCV64_OpRISCV64MOVDconst(v *Value) bool {
-	b := v.Block
-	typ := &b.Func.Config.Types
-	// match: (MOVDconst <t> [c])
-	// cond: !is32Bit(c) && int32(c) < 0
-	// result: (ADD (SLLI <t> [32] (MOVDconst [c>>32+1])) (MOVDconst [int64(int32(c))]))
-	for {
-		t := v.Type
-		c := auxIntToInt64(v.AuxInt)
-		if !(!is32Bit(c) && int32(c) < 0) {
-			break
-		}
-		v.reset(OpRISCV64ADD)
-		v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t)
-		v0.AuxInt = int64ToAuxInt(32)
-		v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
-		v1.AuxInt = int64ToAuxInt(c>>32 + 1)
-		v0.AddArg(v1)
-		v2 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
-		v2.AuxInt = int64ToAuxInt(int64(int32(c)))
-		v.AddArg2(v0, v2)
-		return true
-	}
-	// match: (MOVDconst <t> [c])
-	// cond: !is32Bit(c) && int32(c) >= 0
-	// result: (ADD (SLLI <t> [32] (MOVDconst [c>>32+0])) (MOVDconst [int64(int32(c))]))
-	for {
-		t := v.Type
-		c := auxIntToInt64(v.AuxInt)
-		if !(!is32Bit(c) && int32(c) >= 0) {
-			break
-		}
-		v.reset(OpRISCV64ADD)
-		v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t)
-		v0.AuxInt = int64ToAuxInt(32)
-		v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
-		v1.AuxInt = int64ToAuxInt(c>>32 + 0)
-		v0.AddArg(v1)
-		v2 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
-		v2.AuxInt = int64ToAuxInt(int64(int32(c)))
-		v.AddArg2(v0, v2)
-		return true
-	}
-	return false
-}
 func rewriteValueRISCV64_OpRISCV64MOVDload(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
@@ -3339,6 +3308,21 @@
 	}
 	return false
 }
+func rewriteValueRISCV64_OpRISCV64MOVDnop(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (MOVDnop (MOVDconst [c]))
+	// result: (MOVDconst [c])
+	for {
+		if v_0.Op != OpRISCV64MOVDconst {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		v.reset(OpRISCV64MOVDconst)
+		v.AuxInt = int64ToAuxInt(c)
+		return true
+	}
+	return false
+}
 func rewriteValueRISCV64_OpRISCV64MOVDreg(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (MOVDreg x)
@@ -3521,24 +3505,13 @@
 func rewriteValueRISCV64_OpRISCV64MOVHUreg(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (MOVHUreg (MOVBconst [c]))
+	// match: (MOVHUreg (MOVDconst [c]))
 	// result: (MOVDconst [int64(uint16(c))])
 	for {
-		if v_0.Op != OpRISCV64MOVBconst {
+		if v_0.Op != OpRISCV64MOVDconst {
 			break
 		}
-		c := auxIntToInt8(v_0.AuxInt)
-		v.reset(OpRISCV64MOVDconst)
-		v.AuxInt = int64ToAuxInt(int64(uint16(c)))
-		return true
-	}
-	// match: (MOVHUreg (MOVHconst [c]))
-	// result: (MOVDconst [int64(uint16(c))])
-	for {
-		if v_0.Op != OpRISCV64MOVHconst {
-			break
-		}
-		c := auxIntToInt16(v_0.AuxInt)
+		c := auxIntToInt64(v_0.AuxInt)
 		v.reset(OpRISCV64MOVDconst)
 		v.AuxInt = int64ToAuxInt(int64(uint16(c)))
 		return true
@@ -3664,26 +3637,15 @@
 func rewriteValueRISCV64_OpRISCV64MOVHreg(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (MOVHreg (MOVBconst [c]))
-	// result: (MOVDconst [int64(c)])
+	// match: (MOVHreg (MOVDconst [c]))
+	// result: (MOVDconst [int64(int16(c))])
 	for {
-		if v_0.Op != OpRISCV64MOVBconst {
+		if v_0.Op != OpRISCV64MOVDconst {
 			break
 		}
-		c := auxIntToInt8(v_0.AuxInt)
+		c := auxIntToInt64(v_0.AuxInt)
 		v.reset(OpRISCV64MOVDconst)
-		v.AuxInt = int64ToAuxInt(int64(c))
-		return true
-	}
-	// match: (MOVHreg (MOVHconst [c]))
-	// result: (MOVDconst [int64(c)])
-	for {
-		if v_0.Op != OpRISCV64MOVHconst {
-			break
-		}
-		c := auxIntToInt16(v_0.AuxInt)
-		v.reset(OpRISCV64MOVDconst)
-		v.AuxInt = int64ToAuxInt(int64(c))
+		v.AuxInt = int64ToAuxInt(int64(int16(c)))
 		return true
 	}
 	// match: (MOVHreg x:(MOVBload _ _))
@@ -3827,13 +3789,13 @@
 		v.AddArg3(base, val, mem)
 		return true
 	}
-	// match: (MOVHstore [off] {sym} ptr (MOVHconst [0]) mem)
+	// match: (MOVHstore [off] {sym} ptr (MOVDconst [0]) mem)
 	// result: (MOVHstorezero [off] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
 		ptr := v_0
-		if v_1.Op != OpRISCV64MOVHconst || auxIntToInt16(v_1.AuxInt) != 0 {
+		if v_1.Op != OpRISCV64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
 			break
 		}
 		mem := v_2
@@ -4012,35 +3974,13 @@
 func rewriteValueRISCV64_OpRISCV64MOVWUreg(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (MOVWUreg (MOVBconst [c]))
+	// match: (MOVWUreg (MOVDconst [c]))
 	// result: (MOVDconst [int64(uint32(c))])
 	for {
-		if v_0.Op != OpRISCV64MOVBconst {
+		if v_0.Op != OpRISCV64MOVDconst {
 			break
 		}
-		c := auxIntToInt8(v_0.AuxInt)
-		v.reset(OpRISCV64MOVDconst)
-		v.AuxInt = int64ToAuxInt(int64(uint32(c)))
-		return true
-	}
-	// match: (MOVWUreg (MOVHconst [c]))
-	// result: (MOVDconst [int64(uint32(c))])
-	for {
-		if v_0.Op != OpRISCV64MOVHconst {
-			break
-		}
-		c := auxIntToInt16(v_0.AuxInt)
-		v.reset(OpRISCV64MOVDconst)
-		v.AuxInt = int64ToAuxInt(int64(uint32(c)))
-		return true
-	}
-	// match: (MOVWUreg (MOVWconst [c]))
-	// result: (MOVDconst [int64(uint32(c))])
-	for {
-		if v_0.Op != OpRISCV64MOVWconst {
-			break
-		}
-		c := auxIntToInt32(v_0.AuxInt)
+		c := auxIntToInt64(v_0.AuxInt)
 		v.reset(OpRISCV64MOVDconst)
 		v.AuxInt = int64ToAuxInt(int64(uint32(c)))
 		return true
@@ -4188,37 +4128,15 @@
 func rewriteValueRISCV64_OpRISCV64MOVWreg(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (MOVWreg (MOVBconst [c]))
-	// result: (MOVDconst [int64(c)])
+	// match: (MOVWreg (MOVDconst [c]))
+	// result: (MOVDconst [int64(int32(c))])
 	for {
-		if v_0.Op != OpRISCV64MOVBconst {
+		if v_0.Op != OpRISCV64MOVDconst {
 			break
 		}
-		c := auxIntToInt8(v_0.AuxInt)
+		c := auxIntToInt64(v_0.AuxInt)
 		v.reset(OpRISCV64MOVDconst)
-		v.AuxInt = int64ToAuxInt(int64(c))
-		return true
-	}
-	// match: (MOVWreg (MOVHconst [c]))
-	// result: (MOVDconst [int64(c)])
-	for {
-		if v_0.Op != OpRISCV64MOVHconst {
-			break
-		}
-		c := auxIntToInt16(v_0.AuxInt)
-		v.reset(OpRISCV64MOVDconst)
-		v.AuxInt = int64ToAuxInt(int64(c))
-		return true
-	}
-	// match: (MOVWreg (MOVWconst [c]))
-	// result: (MOVDconst [int64(c)])
-	for {
-		if v_0.Op != OpRISCV64MOVWconst {
-			break
-		}
-		c := auxIntToInt32(v_0.AuxInt)
-		v.reset(OpRISCV64MOVDconst)
-		v.AuxInt = int64ToAuxInt(int64(c))
+		v.AuxInt = int64ToAuxInt(int64(int32(c)))
 		return true
 	}
 	// match: (MOVWreg x:(MOVBload _ _))
@@ -4395,13 +4313,13 @@
 		v.AddArg3(base, val, mem)
 		return true
 	}
-	// match: (MOVWstore [off] {sym} ptr (MOVWconst [0]) mem)
+	// match: (MOVWstore [off] {sym} ptr (MOVDconst [0]) mem)
 	// result: (MOVWstorezero [off] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
 		ptr := v_0
-		if v_1.Op != OpRISCV64MOVWconst || auxIntToInt32(v_1.AuxInt) != 0 {
+		if v_1.Op != OpRISCV64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
 			break
 		}
 		mem := v_2
@@ -4498,54 +4416,6 @@
 func rewriteValueRISCV64_OpRISCV64OR(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (OR (MOVBconst [val]) x)
-	// result: (ORI [int64(val)] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpRISCV64MOVBconst {
-				continue
-			}
-			val := auxIntToInt8(v_0.AuxInt)
-			x := v_1
-			v.reset(OpRISCV64ORI)
-			v.AuxInt = int64ToAuxInt(int64(val))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (OR (MOVHconst [val]) x)
-	// result: (ORI [int64(val)] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpRISCV64MOVHconst {
-				continue
-			}
-			val := auxIntToInt16(v_0.AuxInt)
-			x := v_1
-			v.reset(OpRISCV64ORI)
-			v.AuxInt = int64ToAuxInt(int64(val))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (OR (MOVWconst [val]) x)
-	// result: (ORI [int64(val)] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpRISCV64MOVWconst {
-				continue
-			}
-			val := auxIntToInt32(v_0.AuxInt)
-			x := v_1
-			v.reset(OpRISCV64ORI)
-			v.AuxInt = int64ToAuxInt(int64(val))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (OR (MOVDconst [val]) x)
 	// cond: is32Bit(val)
 	// result: (ORI [val] x)
@@ -4571,45 +4441,6 @@
 func rewriteValueRISCV64_OpRISCV64SLL(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (SLL x (MOVBconst [val]))
-	// result: (SLLI [int64(val&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVBconst {
-			break
-		}
-		val := auxIntToInt8(v_1.AuxInt)
-		v.reset(OpRISCV64SLLI)
-		v.AuxInt = int64ToAuxInt(int64(val & 63))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SLL x (MOVHconst [val]))
-	// result: (SLLI [int64(val&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVHconst {
-			break
-		}
-		val := auxIntToInt16(v_1.AuxInt)
-		v.reset(OpRISCV64SLLI)
-		v.AuxInt = int64ToAuxInt(int64(val & 63))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SLL x (MOVWconst [val]))
-	// result: (SLLI [int64(val&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVWconst {
-			break
-		}
-		val := auxIntToInt32(v_1.AuxInt)
-		v.reset(OpRISCV64SLLI)
-		v.AuxInt = int64ToAuxInt(int64(val & 63))
-		v.AddArg(x)
-		return true
-	}
 	// match: (SLL x (MOVDconst [val]))
 	// result: (SLLI [int64(val&63)] x)
 	for {
@@ -4628,45 +4459,6 @@
 func rewriteValueRISCV64_OpRISCV64SRA(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (SRA x (MOVBconst [val]))
-	// result: (SRAI [int64(val&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVBconst {
-			break
-		}
-		val := auxIntToInt8(v_1.AuxInt)
-		v.reset(OpRISCV64SRAI)
-		v.AuxInt = int64ToAuxInt(int64(val & 63))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SRA x (MOVHconst [val]))
-	// result: (SRAI [int64(val&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVHconst {
-			break
-		}
-		val := auxIntToInt16(v_1.AuxInt)
-		v.reset(OpRISCV64SRAI)
-		v.AuxInt = int64ToAuxInt(int64(val & 63))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SRA x (MOVWconst [val]))
-	// result: (SRAI [int64(val&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVWconst {
-			break
-		}
-		val := auxIntToInt32(v_1.AuxInt)
-		v.reset(OpRISCV64SRAI)
-		v.AuxInt = int64ToAuxInt(int64(val & 63))
-		v.AddArg(x)
-		return true
-	}
 	// match: (SRA x (MOVDconst [val]))
 	// result: (SRAI [int64(val&63)] x)
 	for {
@@ -4685,45 +4477,6 @@
 func rewriteValueRISCV64_OpRISCV64SRL(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (SRL x (MOVBconst [val]))
-	// result: (SRLI [int64(val&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVBconst {
-			break
-		}
-		val := auxIntToInt8(v_1.AuxInt)
-		v.reset(OpRISCV64SRLI)
-		v.AuxInt = int64ToAuxInt(int64(val & 63))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SRL x (MOVHconst [val]))
-	// result: (SRLI [int64(val&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVHconst {
-			break
-		}
-		val := auxIntToInt16(v_1.AuxInt)
-		v.reset(OpRISCV64SRLI)
-		v.AuxInt = int64ToAuxInt(int64(val & 63))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SRL x (MOVWconst [val]))
-	// result: (SRLI [int64(val&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVWconst {
-			break
-		}
-		val := auxIntToInt32(v_1.AuxInt)
-		v.reset(OpRISCV64SRLI)
-		v.AuxInt = int64ToAuxInt(int64(val & 63))
-		v.AddArg(x)
-		return true
-	}
 	// match: (SRL x (MOVDconst [val]))
 	// result: (SRLI [int64(val&63)] x)
 	for {
@@ -4742,49 +4495,6 @@
 func rewriteValueRISCV64_OpRISCV64SUB(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (SUB x (MOVBconst [val]))
-	// result: (ADDI [-int64(val)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVBconst {
-			break
-		}
-		val := auxIntToInt8(v_1.AuxInt)
-		v.reset(OpRISCV64ADDI)
-		v.AuxInt = int64ToAuxInt(-int64(val))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SUB x (MOVHconst [val]))
-	// result: (ADDI [-int64(val)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVHconst {
-			break
-		}
-		val := auxIntToInt16(v_1.AuxInt)
-		v.reset(OpRISCV64ADDI)
-		v.AuxInt = int64ToAuxInt(-int64(val))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SUB x (MOVWconst [val]))
-	// cond: is32Bit(-int64(val))
-	// result: (ADDI [-int64(val)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVWconst {
-			break
-		}
-		val := auxIntToInt32(v_1.AuxInt)
-		if !(is32Bit(-int64(val))) {
-			break
-		}
-		v.reset(OpRISCV64ADDI)
-		v.AuxInt = int64ToAuxInt(-int64(val))
-		v.AddArg(x)
-		return true
-	}
 	// match: (SUB x (MOVDconst [val]))
 	// cond: is32Bit(-val)
 	// result: (ADDI [-val] x)
@@ -4802,36 +4512,6 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (SUB x (MOVBconst [0]))
-	// result: x
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVBconst || auxIntToInt8(v_1.AuxInt) != 0 {
-			break
-		}
-		v.copyOf(x)
-		return true
-	}
-	// match: (SUB x (MOVHconst [0]))
-	// result: x
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVHconst || auxIntToInt16(v_1.AuxInt) != 0 {
-			break
-		}
-		v.copyOf(x)
-		return true
-	}
-	// match: (SUB x (MOVWconst [0]))
-	// result: x
-	for {
-		x := v_0
-		if v_1.Op != OpRISCV64MOVWconst || auxIntToInt32(v_1.AuxInt) != 0 {
-			break
-		}
-		v.copyOf(x)
-		return true
-	}
 	// match: (SUB x (MOVDconst [0]))
 	// result: x
 	for {
@@ -4842,39 +4522,6 @@
 		v.copyOf(x)
 		return true
 	}
-	// match: (SUB (MOVBconst [0]) x)
-	// result: (NEG x)
-	for {
-		if v_0.Op != OpRISCV64MOVBconst || auxIntToInt8(v_0.AuxInt) != 0 {
-			break
-		}
-		x := v_1
-		v.reset(OpRISCV64NEG)
-		v.AddArg(x)
-		return true
-	}
-	// match: (SUB (MOVHconst [0]) x)
-	// result: (NEG x)
-	for {
-		if v_0.Op != OpRISCV64MOVHconst || auxIntToInt16(v_0.AuxInt) != 0 {
-			break
-		}
-		x := v_1
-		v.reset(OpRISCV64NEG)
-		v.AddArg(x)
-		return true
-	}
-	// match: (SUB (MOVWconst [0]) x)
-	// result: (NEG x)
-	for {
-		if v_0.Op != OpRISCV64MOVWconst || auxIntToInt32(v_0.AuxInt) != 0 {
-			break
-		}
-		x := v_1
-		v.reset(OpRISCV64NEG)
-		v.AddArg(x)
-		return true
-	}
 	// match: (SUB (MOVDconst [0]) x)
 	// result: (NEG x)
 	for {
@@ -4891,11 +4538,11 @@
 func rewriteValueRISCV64_OpRISCV64SUBW(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (SUBW x (MOVWconst [0]))
+	// match: (SUBW x (MOVDconst [0]))
 	// result: (ADDIW [0] x)
 	for {
 		x := v_0
-		if v_1.Op != OpRISCV64MOVWconst || auxIntToInt32(v_1.AuxInt) != 0 {
+		if v_1.Op != OpRISCV64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
 			break
 		}
 		v.reset(OpRISCV64ADDIW)
@@ -4919,54 +4566,6 @@
 func rewriteValueRISCV64_OpRISCV64XOR(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (XOR (MOVBconst [val]) x)
-	// result: (XORI [int64(val)] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpRISCV64MOVBconst {
-				continue
-			}
-			val := auxIntToInt8(v_0.AuxInt)
-			x := v_1
-			v.reset(OpRISCV64XORI)
-			v.AuxInt = int64ToAuxInt(int64(val))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (XOR (MOVHconst [val]) x)
-	// result: (XORI [int64(val)] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpRISCV64MOVHconst {
-				continue
-			}
-			val := auxIntToInt16(v_0.AuxInt)
-			x := v_1
-			v.reset(OpRISCV64XORI)
-			v.AuxInt = int64ToAuxInt(int64(val))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (XOR (MOVWconst [val]) x)
-	// result: (XORI [int64(val)] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpRISCV64MOVWconst {
-				continue
-			}
-			val := auxIntToInt32(v_0.AuxInt)
-			x := v_1
-			v.reset(OpRISCV64XORI)
-			v.AuxInt = int64ToAuxInt(int64(val))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (XOR (MOVDconst [val]) x)
 	// cond: is32Bit(val)
 	// result: (XORI [val] x)
@@ -4994,23 +4593,23 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (RotateLeft16 <t> x (MOVHconst [c]))
-	// result: (Or16 (Lsh16x64 <t> x (MOVHconst [c&15])) (Rsh16Ux64 <t> x (MOVHconst [-c&15])))
+	// match: (RotateLeft16 <t> x (MOVDconst [c]))
+	// result: (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
 	for {
 		t := v.Type
 		x := v_0
-		if v_1.Op != OpRISCV64MOVHconst {
+		if v_1.Op != OpRISCV64MOVDconst {
 			break
 		}
-		c := auxIntToInt16(v_1.AuxInt)
+		c := auxIntToInt64(v_1.AuxInt)
 		v.reset(OpOr16)
 		v0 := b.NewValue0(v.Pos, OpLsh16x64, t)
-		v1 := b.NewValue0(v.Pos, OpRISCV64MOVHconst, typ.UInt16)
-		v1.AuxInt = int16ToAuxInt(c & 15)
+		v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v1.AuxInt = int64ToAuxInt(c & 15)
 		v0.AddArg2(x, v1)
 		v2 := b.NewValue0(v.Pos, OpRsh16Ux64, t)
-		v3 := b.NewValue0(v.Pos, OpRISCV64MOVHconst, typ.UInt16)
-		v3.AuxInt = int16ToAuxInt(-c & 15)
+		v3 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v3.AuxInt = int64ToAuxInt(-c & 15)
 		v2.AddArg2(x, v3)
 		v.AddArg2(v0, v2)
 		return true
@@ -5022,23 +4621,23 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (RotateLeft32 <t> x (MOVWconst [c]))
-	// result: (Or32 (Lsh32x64 <t> x (MOVWconst [c&31])) (Rsh32Ux64 <t> x (MOVWconst [-c&31])))
+	// match: (RotateLeft32 <t> x (MOVDconst [c]))
+	// result: (Or32 (Lsh32x64 <t> x (MOVDconst [c&31])) (Rsh32Ux64 <t> x (MOVDconst [-c&31])))
 	for {
 		t := v.Type
 		x := v_0
-		if v_1.Op != OpRISCV64MOVWconst {
+		if v_1.Op != OpRISCV64MOVDconst {
 			break
 		}
-		c := auxIntToInt32(v_1.AuxInt)
+		c := auxIntToInt64(v_1.AuxInt)
 		v.reset(OpOr32)
 		v0 := b.NewValue0(v.Pos, OpLsh32x64, t)
-		v1 := b.NewValue0(v.Pos, OpRISCV64MOVWconst, typ.UInt32)
-		v1.AuxInt = int32ToAuxInt(c & 31)
+		v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v1.AuxInt = int64ToAuxInt(c & 31)
 		v0.AddArg2(x, v1)
 		v2 := b.NewValue0(v.Pos, OpRsh32Ux64, t)
-		v3 := b.NewValue0(v.Pos, OpRISCV64MOVWconst, typ.UInt32)
-		v3.AuxInt = int32ToAuxInt(-c & 31)
+		v3 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v3.AuxInt = int64ToAuxInt(-c & 31)
 		v2.AddArg2(x, v3)
 		v.AddArg2(v0, v2)
 		return true
@@ -5078,23 +4677,23 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (RotateLeft8 <t> x (MOVBconst [c]))
-	// result: (Or8 (Lsh8x64 <t> x (MOVBconst [c&7])) (Rsh8Ux64 <t> x (MOVBconst [-c&7])))
+	// match: (RotateLeft8 <t> x (MOVDconst [c]))
+	// result: (Or8 (Lsh8x64 <t> x (MOVDconst [c&7])) (Rsh8Ux64 <t> x (MOVDconst [-c&7])))
 	for {
 		t := v.Type
 		x := v_0
-		if v_1.Op != OpRISCV64MOVBconst {
+		if v_1.Op != OpRISCV64MOVDconst {
 			break
 		}
-		c := auxIntToInt8(v_1.AuxInt)
+		c := auxIntToInt64(v_1.AuxInt)
 		v.reset(OpOr8)
 		v0 := b.NewValue0(v.Pos, OpLsh8x64, t)
-		v1 := b.NewValue0(v.Pos, OpRISCV64MOVBconst, typ.UInt8)
-		v1.AuxInt = int8ToAuxInt(c & 7)
+		v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v1.AuxInt = int64ToAuxInt(c & 7)
 		v0.AddArg2(x, v1)
 		v2 := b.NewValue0(v.Pos, OpRsh8Ux64, t)
-		v3 := b.NewValue0(v.Pos, OpRISCV64MOVBconst, typ.UInt8)
-		v3.AuxInt = int8ToAuxInt(-c & 7)
+		v3 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v3.AuxInt = int64ToAuxInt(-c & 7)
 		v2.AddArg2(x, v3)
 		v.AddArg2(v0, v2)
 		return true
@@ -6095,7 +5694,7 @@
 		return true
 	}
 	// match: (Zero [1] ptr mem)
-	// result: (MOVBstore ptr (MOVBconst [0]) mem)
+	// result: (MOVBstore ptr (MOVDconst [0]) mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 1 {
 			break
@@ -6103,14 +5702,14 @@
 		ptr := v_0
 		mem := v_1
 		v.reset(OpRISCV64MOVBstore)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVBconst, typ.UInt8)
-		v0.AuxInt = int8ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(0)
 		v.AddArg3(ptr, v0, mem)
 		return true
 	}
 	// match: (Zero [2] {t} ptr mem)
 	// cond: t.Alignment()%2 == 0
-	// result: (MOVHstore ptr (MOVHconst [0]) mem)
+	// result: (MOVHstore ptr (MOVDconst [0]) mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 2 {
 			break
@@ -6122,13 +5721,13 @@
 			break
 		}
 		v.reset(OpRISCV64MOVHstore)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVHconst, typ.UInt16)
-		v0.AuxInt = int16ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(0)
 		v.AddArg3(ptr, v0, mem)
 		return true
 	}
 	// match: (Zero [2] ptr mem)
-	// result: (MOVBstore [1] ptr (MOVBconst [0]) (MOVBstore ptr (MOVBconst [0]) mem))
+	// result: (MOVBstore [1] ptr (MOVDconst [0]) (MOVBstore ptr (MOVDconst [0]) mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 2 {
 			break
@@ -6137,8 +5736,8 @@
 		mem := v_1
 		v.reset(OpRISCV64MOVBstore)
 		v.AuxInt = int32ToAuxInt(1)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVBconst, typ.UInt8)
-		v0.AuxInt = int8ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(0)
 		v1 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem)
 		v1.AddArg3(ptr, v0, mem)
 		v.AddArg3(ptr, v0, v1)
@@ -6146,7 +5745,7 @@
 	}
 	// match: (Zero [4] {t} ptr mem)
 	// cond: t.Alignment()%4 == 0
-	// result: (MOVWstore ptr (MOVWconst [0]) mem)
+	// result: (MOVWstore ptr (MOVDconst [0]) mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 4 {
 			break
@@ -6158,14 +5757,14 @@
 			break
 		}
 		v.reset(OpRISCV64MOVWstore)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVWconst, typ.UInt32)
-		v0.AuxInt = int32ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(0)
 		v.AddArg3(ptr, v0, mem)
 		return true
 	}
 	// match: (Zero [4] {t} ptr mem)
 	// cond: t.Alignment()%2 == 0
-	// result: (MOVHstore [2] ptr (MOVHconst [0]) (MOVHstore ptr (MOVHconst [0]) mem))
+	// result: (MOVHstore [2] ptr (MOVDconst [0]) (MOVHstore ptr (MOVDconst [0]) mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 4 {
 			break
@@ -6178,15 +5777,15 @@
 		}
 		v.reset(OpRISCV64MOVHstore)
 		v.AuxInt = int32ToAuxInt(2)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVHconst, typ.UInt16)
-		v0.AuxInt = int16ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(0)
 		v1 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem)
 		v1.AddArg3(ptr, v0, mem)
 		v.AddArg3(ptr, v0, v1)
 		return true
 	}
 	// match: (Zero [4] ptr mem)
-	// result: (MOVBstore [3] ptr (MOVBconst [0]) (MOVBstore [2] ptr (MOVBconst [0]) (MOVBstore [1] ptr (MOVBconst [0]) (MOVBstore ptr (MOVBconst [0]) mem))))
+	// result: (MOVBstore [3] ptr (MOVDconst [0]) (MOVBstore [2] ptr (MOVDconst [0]) (MOVBstore [1] ptr (MOVDconst [0]) (MOVBstore ptr (MOVDconst [0]) mem))))
 	for {
 		if auxIntToInt64(v.AuxInt) != 4 {
 			break
@@ -6195,8 +5794,8 @@
 		mem := v_1
 		v.reset(OpRISCV64MOVBstore)
 		v.AuxInt = int32ToAuxInt(3)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVBconst, typ.UInt8)
-		v0.AuxInt = int8ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(0)
 		v1 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem)
 		v1.AuxInt = int32ToAuxInt(2)
 		v2 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem)
@@ -6229,7 +5828,7 @@
 	}
 	// match: (Zero [8] {t} ptr mem)
 	// cond: t.Alignment()%4 == 0
-	// result: (MOVWstore [4] ptr (MOVWconst [0]) (MOVWstore ptr (MOVWconst [0]) mem))
+	// result: (MOVWstore [4] ptr (MOVDconst [0]) (MOVWstore ptr (MOVDconst [0]) mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 8 {
 			break
@@ -6242,8 +5841,8 @@
 		}
 		v.reset(OpRISCV64MOVWstore)
 		v.AuxInt = int32ToAuxInt(4)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVWconst, typ.UInt32)
-		v0.AuxInt = int32ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(0)
 		v1 := b.NewValue0(v.Pos, OpRISCV64MOVWstore, types.TypeMem)
 		v1.AddArg3(ptr, v0, mem)
 		v.AddArg3(ptr, v0, v1)
@@ -6251,7 +5850,7 @@
 	}
 	// match: (Zero [8] {t} ptr mem)
 	// cond: t.Alignment()%2 == 0
-	// result: (MOVHstore [6] ptr (MOVHconst [0]) (MOVHstore [4] ptr (MOVHconst [0]) (MOVHstore [2] ptr (MOVHconst [0]) (MOVHstore ptr (MOVHconst [0]) mem))))
+	// result: (MOVHstore [6] ptr (MOVDconst [0]) (MOVHstore [4] ptr (MOVDconst [0]) (MOVHstore [2] ptr (MOVDconst [0]) (MOVHstore ptr (MOVDconst [0]) mem))))
 	for {
 		if auxIntToInt64(v.AuxInt) != 8 {
 			break
@@ -6264,8 +5863,8 @@
 		}
 		v.reset(OpRISCV64MOVHstore)
 		v.AuxInt = int32ToAuxInt(6)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVHconst, typ.UInt16)
-		v0.AuxInt = int16ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(0)
 		v1 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem)
 		v1.AuxInt = int32ToAuxInt(4)
 		v2 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem)
@@ -6278,7 +5877,7 @@
 		return true
 	}
 	// match: (Zero [3] ptr mem)
-	// result: (MOVBstore [2] ptr (MOVBconst [0]) (MOVBstore [1] ptr (MOVBconst [0]) (MOVBstore ptr (MOVBconst [0]) mem)))
+	// result: (MOVBstore [2] ptr (MOVDconst [0]) (MOVBstore [1] ptr (MOVDconst [0]) (MOVBstore ptr (MOVDconst [0]) mem)))
 	for {
 		if auxIntToInt64(v.AuxInt) != 3 {
 			break
@@ -6287,8 +5886,8 @@
 		mem := v_1
 		v.reset(OpRISCV64MOVBstore)
 		v.AuxInt = int32ToAuxInt(2)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVBconst, typ.UInt8)
-		v0.AuxInt = int8ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(0)
 		v1 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem)
 		v1.AuxInt = int32ToAuxInt(1)
 		v2 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem)
@@ -6299,7 +5898,7 @@
 	}
 	// match: (Zero [6] {t} ptr mem)
 	// cond: t.Alignment()%2 == 0
-	// result: (MOVHstore [4] ptr (MOVHconst [0]) (MOVHstore [2] ptr (MOVHconst [0]) (MOVHstore ptr (MOVHconst [0]) mem)))
+	// result: (MOVHstore [4] ptr (MOVDconst [0]) (MOVHstore [2] ptr (MOVDconst [0]) (MOVHstore ptr (MOVDconst [0]) mem)))
 	for {
 		if auxIntToInt64(v.AuxInt) != 6 {
 			break
@@ -6312,8 +5911,8 @@
 		}
 		v.reset(OpRISCV64MOVHstore)
 		v.AuxInt = int32ToAuxInt(4)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVHconst, typ.UInt16)
-		v0.AuxInt = int16ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(0)
 		v1 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem)
 		v1.AuxInt = int32ToAuxInt(2)
 		v2 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem)
@@ -6324,7 +5923,7 @@
 	}
 	// match: (Zero [12] {t} ptr mem)
 	// cond: t.Alignment()%4 == 0
-	// result: (MOVWstore [8] ptr (MOVWconst [0]) (MOVWstore [4] ptr (MOVWconst [0]) (MOVWstore ptr (MOVWconst [0]) mem)))
+	// result: (MOVWstore [8] ptr (MOVDconst [0]) (MOVWstore [4] ptr (MOVDconst [0]) (MOVWstore ptr (MOVDconst [0]) mem)))
 	for {
 		if auxIntToInt64(v.AuxInt) != 12 {
 			break
@@ -6337,8 +5936,8 @@
 		}
 		v.reset(OpRISCV64MOVWstore)
 		v.AuxInt = int32ToAuxInt(8)
-		v0 := b.NewValue0(v.Pos, OpRISCV64MOVWconst, typ.UInt32)
-		v0.AuxInt = int32ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(0)
 		v1 := b.NewValue0(v.Pos, OpRISCV64MOVWstore, types.TypeMem)
 		v1.AuxInt = int32ToAuxInt(4)
 		v2 := b.NewValue0(v.Pos, OpRISCV64MOVWstore, types.TypeMem)
diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go
index a9722b8..8b41d62 100644
--- a/src/cmd/compile/internal/ssa/rewriteS390X.go
+++ b/src/cmd/compile/internal/ssa/rewriteS390X.go
@@ -792,6 +792,9 @@
 	case OpSqrt:
 		v.Op = OpS390XFSQRT
 		return true
+	case OpSqrt32:
+		v.Op = OpS390XFSQRTS
+		return true
 	case OpStaticCall:
 		v.Op = OpS390XCALLstatic
 		return true
@@ -1318,12 +1321,12 @@
 	}
 }
 func rewriteValueS390X_OpConstBool(v *Value) bool {
-	// match: (ConstBool [b])
-	// result: (MOVDconst [b2i(b)])
+	// match: (ConstBool [t])
+	// result: (MOVDconst [b2i(t)])
 	for {
-		b := auxIntToBool(v.AuxInt)
+		t := auxIntToBool(v.AuxInt)
 		v.reset(OpS390XMOVDconst)
-		v.AuxInt = int64ToAuxInt(b2i(b))
+		v.AuxInt = int64ToAuxInt(b2i(t))
 		return true
 	}
 }
@@ -3430,7 +3433,7 @@
 	}
 	// match: (Move [s] dst src mem)
 	// cond: s > 0 && s <= 256 && logLargeCopy(v, s)
-	// result: (MVC [makeValAndOff32(int32(s), 0)] dst src mem)
+	// result: (MVC [makeValAndOff(int32(s), 0)] dst src mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		dst := v_0
@@ -3440,13 +3443,13 @@
 			break
 		}
 		v.reset(OpS390XMVC)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(s), 0))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(s), 0))
 		v.AddArg3(dst, src, mem)
 		return true
 	}
 	// match: (Move [s] dst src mem)
 	// cond: s > 256 && s <= 512 && logLargeCopy(v, s)
-	// result: (MVC [makeValAndOff32(int32(s)-256, 256)] dst src (MVC [makeValAndOff32(256, 0)] dst src mem))
+	// result: (MVC [makeValAndOff(int32(s)-256, 256)] dst src (MVC [makeValAndOff(256, 0)] dst src mem))
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		dst := v_0
@@ -3456,16 +3459,16 @@
 			break
 		}
 		v.reset(OpS390XMVC)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(s)-256, 256))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(s)-256, 256))
 		v0 := b.NewValue0(v.Pos, OpS390XMVC, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(256, 0))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(256, 0))
 		v0.AddArg3(dst, src, mem)
 		v.AddArg3(dst, src, v0)
 		return true
 	}
 	// match: (Move [s] dst src mem)
 	// cond: s > 512 && s <= 768 && logLargeCopy(v, s)
-	// result: (MVC [makeValAndOff32(int32(s)-512, 512)] dst src (MVC [makeValAndOff32(256, 256)] dst src (MVC [makeValAndOff32(256, 0)] dst src mem)))
+	// result: (MVC [makeValAndOff(int32(s)-512, 512)] dst src (MVC [makeValAndOff(256, 256)] dst src (MVC [makeValAndOff(256, 0)] dst src mem)))
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		dst := v_0
@@ -3475,11 +3478,11 @@
 			break
 		}
 		v.reset(OpS390XMVC)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(s)-512, 512))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(s)-512, 512))
 		v0 := b.NewValue0(v.Pos, OpS390XMVC, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(256, 256))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(256, 256))
 		v1 := b.NewValue0(v.Pos, OpS390XMVC, types.TypeMem)
-		v1.AuxInt = valAndOffToAuxInt(makeValAndOff32(256, 0))
+		v1.AuxInt = valAndOffToAuxInt(makeValAndOff(256, 0))
 		v1.AddArg3(dst, src, mem)
 		v0.AddArg3(dst, src, v1)
 		v.AddArg3(dst, src, v0)
@@ -3487,7 +3490,7 @@
 	}
 	// match: (Move [s] dst src mem)
 	// cond: s > 768 && s <= 1024 && logLargeCopy(v, s)
-	// result: (MVC [makeValAndOff32(int32(s)-768, 768)] dst src (MVC [makeValAndOff32(256, 512)] dst src (MVC [makeValAndOff32(256, 256)] dst src (MVC [makeValAndOff32(256, 0)] dst src mem))))
+	// result: (MVC [makeValAndOff(int32(s)-768, 768)] dst src (MVC [makeValAndOff(256, 512)] dst src (MVC [makeValAndOff(256, 256)] dst src (MVC [makeValAndOff(256, 0)] dst src mem))))
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		dst := v_0
@@ -3497,13 +3500,13 @@
 			break
 		}
 		v.reset(OpS390XMVC)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(s)-768, 768))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(s)-768, 768))
 		v0 := b.NewValue0(v.Pos, OpS390XMVC, types.TypeMem)
-		v0.AuxInt = valAndOffToAuxInt(makeValAndOff32(256, 512))
+		v0.AuxInt = valAndOffToAuxInt(makeValAndOff(256, 512))
 		v1 := b.NewValue0(v.Pos, OpS390XMVC, types.TypeMem)
-		v1.AuxInt = valAndOffToAuxInt(makeValAndOff32(256, 256))
+		v1.AuxInt = valAndOffToAuxInt(makeValAndOff(256, 256))
 		v2 := b.NewValue0(v.Pos, OpS390XMVC, types.TypeMem)
-		v2.AuxInt = valAndOffToAuxInt(makeValAndOff32(256, 0))
+		v2.AuxInt = valAndOffToAuxInt(makeValAndOff(256, 0))
 		v2.AddArg3(dst, src, mem)
 		v1.AddArg3(dst, src, v2)
 		v0.AddArg3(dst, src, v1)
@@ -6332,12 +6335,12 @@
 		return true
 	}
 	// match: (CMP x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMP y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpS390XInvertFlags)
@@ -6389,12 +6392,12 @@
 		return true
 	}
 	// match: (CMPU x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPU y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpS390XInvertFlags)
@@ -6624,12 +6627,12 @@
 		return true
 	}
 	// match: (CMPW x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPW y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpS390XInvertFlags)
@@ -6721,12 +6724,12 @@
 		return true
 	}
 	// match: (CMPWU x y)
-	// cond: x.ID > y.ID
+	// cond: canonLessThan(x,y)
 	// result: (InvertFlags (CMPWU y x))
 	for {
 		x := v_0
 		y := v_1
-		if !(x.ID > y.ID) {
+		if !(canonLessThan(x, y)) {
 			break
 		}
 		v.reset(OpS390XInvertFlags)
@@ -8614,7 +8617,7 @@
 	}
 	// match: (MOVBstore [off] {sym} ptr (MOVDconst [c]) mem)
 	// cond: is20Bit(int64(off)) && ptr.Op != OpSB
-	// result: (MOVBstoreconst [makeValAndOff32(int32(int8(c)),off)] {sym} ptr mem)
+	// result: (MOVBstoreconst [makeValAndOff(int32(int8(c)),off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -8628,7 +8631,7 @@
 			break
 		}
 		v.reset(OpS390XMOVBstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(int8(c)), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(int8(c)), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -8880,13 +8883,63 @@
 		v.AddArg3(p, w0, mem)
 		return true
 	}
+	// match: (MOVBstore [7] {s} p1 (SRDconst w) x1:(MOVHBRstore [5] {s} p1 (SRDconst w) x2:(MOVWBRstore [1] {s} p1 (SRDconst w) x3:(MOVBstore [0] {s} p1 w mem))))
+	// cond: x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && clobber(x1, x2, x3)
+	// result: (MOVDBRstore {s} p1 w mem)
+	for {
+		if auxIntToInt32(v.AuxInt) != 7 {
+			break
+		}
+		s := auxToSym(v.Aux)
+		p1 := v_0
+		if v_1.Op != OpS390XSRDconst {
+			break
+		}
+		w := v_1.Args[0]
+		x1 := v_2
+		if x1.Op != OpS390XMOVHBRstore || auxIntToInt32(x1.AuxInt) != 5 || auxToSym(x1.Aux) != s {
+			break
+		}
+		_ = x1.Args[2]
+		if p1 != x1.Args[0] {
+			break
+		}
+		x1_1 := x1.Args[1]
+		if x1_1.Op != OpS390XSRDconst || w != x1_1.Args[0] {
+			break
+		}
+		x2 := x1.Args[2]
+		if x2.Op != OpS390XMOVWBRstore || auxIntToInt32(x2.AuxInt) != 1 || auxToSym(x2.Aux) != s {
+			break
+		}
+		_ = x2.Args[2]
+		if p1 != x2.Args[0] {
+			break
+		}
+		x2_1 := x2.Args[1]
+		if x2_1.Op != OpS390XSRDconst || w != x2_1.Args[0] {
+			break
+		}
+		x3 := x2.Args[2]
+		if x3.Op != OpS390XMOVBstore || auxIntToInt32(x3.AuxInt) != 0 || auxToSym(x3.Aux) != s {
+			break
+		}
+		mem := x3.Args[2]
+		if p1 != x3.Args[0] || w != x3.Args[1] || !(x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && clobber(x1, x2, x3)) {
+			break
+		}
+		v.reset(OpS390XMOVDBRstore)
+		v.Aux = symToAux(s)
+		v.AddArg3(p1, w, mem)
+		return true
+	}
 	return false
 }
 func rewriteValueS390X_OpS390XMOVBstoreconst(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (MOVBstoreconst [sc] {s} (ADDconst [off] ptr) mem)
-	// cond: is20Bit(sc.Off()+int64(off))
+	// cond: is20Bit(sc.Off64()+int64(off))
 	// result: (MOVBstoreconst [sc.addOffset32(off)] {s} ptr mem)
 	for {
 		sc := auxIntToValAndOff(v.AuxInt)
@@ -8897,7 +8950,7 @@
 		off := auxIntToInt32(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is20Bit(sc.Off() + int64(off))) {
+		if !(is20Bit(sc.Off64() + int64(off))) {
 			break
 		}
 		v.reset(OpS390XMOVBstoreconst)
@@ -8930,7 +8983,7 @@
 	}
 	// match: (MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
 	// cond: p.Op != OpSB && x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x)
-	// result: (MOVHstoreconst [makeValAndOff32(c.Val32()&0xff | a.Val32()<<8, a.Off32())] {s} p mem)
+	// result: (MOVHstoreconst [makeValAndOff(c.Val()&0xff | a.Val()<<8, a.Off())] {s} p mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -8948,7 +9001,7 @@
 			break
 		}
 		v.reset(OpS390XMOVHstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(c.Val32()&0xff|a.Val32()<<8, a.Off32()))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(c.Val()&0xff|a.Val()<<8, a.Off()))
 		v.Aux = symToAux(s)
 		v.AddArg2(p, mem)
 		return true
@@ -9160,7 +9213,7 @@
 	}
 	// match: (MOVDstore [off] {sym} ptr (MOVDconst [c]) mem)
 	// cond: is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB
-	// result: (MOVDstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+	// result: (MOVDstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -9174,7 +9227,7 @@
 			break
 		}
 		v.reset(OpS390XMOVDstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -9290,7 +9343,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (MOVDstoreconst [sc] {s} (ADDconst [off] ptr) mem)
-	// cond: isU12Bit(sc.Off()+int64(off))
+	// cond: isU12Bit(sc.Off64()+int64(off))
 	// result: (MOVDstoreconst [sc.addOffset32(off)] {s} ptr mem)
 	for {
 		sc := auxIntToValAndOff(v.AuxInt)
@@ -9301,7 +9354,7 @@
 		off := auxIntToInt32(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(isU12Bit(sc.Off() + int64(off))) {
+		if !(isU12Bit(sc.Off64() + int64(off))) {
 			break
 		}
 		v.reset(OpS390XMOVDstoreconst)
@@ -10026,7 +10079,7 @@
 	}
 	// match: (MOVHstore [off] {sym} ptr (MOVDconst [c]) mem)
 	// cond: isU12Bit(int64(off)) && ptr.Op != OpSB
-	// result: (MOVHstoreconst [makeValAndOff32(int32(int16(c)),off)] {sym} ptr mem)
+	// result: (MOVHstoreconst [makeValAndOff(int32(int16(c)),off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -10040,7 +10093,7 @@
 			break
 		}
 		v.reset(OpS390XMOVHstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(int16(c)), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(int16(c)), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -10191,7 +10244,7 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (MOVHstoreconst [sc] {s} (ADDconst [off] ptr) mem)
-	// cond: isU12Bit(sc.Off()+int64(off))
+	// cond: isU12Bit(sc.Off64()+int64(off))
 	// result: (MOVHstoreconst [sc.addOffset32(off)] {s} ptr mem)
 	for {
 		sc := auxIntToValAndOff(v.AuxInt)
@@ -10202,7 +10255,7 @@
 		off := auxIntToInt32(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(isU12Bit(sc.Off() + int64(off))) {
+		if !(isU12Bit(sc.Off64() + int64(off))) {
 			break
 		}
 		v.reset(OpS390XMOVHstoreconst)
@@ -10235,7 +10288,7 @@
 	}
 	// match: (MOVHstoreconst [c] {s} p x:(MOVHstoreconst [a] {s} p mem))
 	// cond: p.Op != OpSB && x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x)
-	// result: (MOVWstore [a.Off32()] {s} p (MOVDconst [int64(c.Val32()&0xffff | a.Val32()<<16)]) mem)
+	// result: (MOVWstore [a.Off()] {s} p (MOVDconst [int64(c.Val()&0xffff | a.Val()<<16)]) mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -10253,10 +10306,10 @@
 			break
 		}
 		v.reset(OpS390XMOVWstore)
-		v.AuxInt = int32ToAuxInt(a.Off32())
+		v.AuxInt = int32ToAuxInt(a.Off())
 		v.Aux = symToAux(s)
 		v0 := b.NewValue0(x.Pos, OpS390XMOVDconst, typ.UInt64)
-		v0.AuxInt = int64ToAuxInt(int64(c.Val32()&0xffff | a.Val32()<<16))
+		v0.AuxInt = int64ToAuxInt(int64(c.Val()&0xffff | a.Val()<<16))
 		v.AddArg3(p, v0, mem)
 		return true
 	}
@@ -10864,7 +10917,7 @@
 	}
 	// match: (MOVWstore [off] {sym} ptr (MOVDconst [c]) mem)
 	// cond: is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB
-	// result: (MOVWstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+	// result: (MOVWstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		sym := auxToSym(v.Aux)
@@ -10878,7 +10931,7 @@
 			break
 		}
 		v.reset(OpS390XMOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(c), off))
 		v.Aux = symToAux(sym)
 		v.AddArg2(ptr, mem)
 		return true
@@ -11052,7 +11105,7 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (MOVWstoreconst [sc] {s} (ADDconst [off] ptr) mem)
-	// cond: isU12Bit(sc.Off()+int64(off))
+	// cond: isU12Bit(sc.Off64()+int64(off))
 	// result: (MOVWstoreconst [sc.addOffset32(off)] {s} ptr mem)
 	for {
 		sc := auxIntToValAndOff(v.AuxInt)
@@ -11063,7 +11116,7 @@
 		off := auxIntToInt32(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(isU12Bit(sc.Off() + int64(off))) {
+		if !(isU12Bit(sc.Off64() + int64(off))) {
 			break
 		}
 		v.reset(OpS390XMOVWstoreconst)
@@ -11096,7 +11149,7 @@
 	}
 	// match: (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
 	// cond: p.Op != OpSB && x.Uses == 1 && a.Off() + 4 == c.Off() && clobber(x)
-	// result: (MOVDstore [a.Off32()] {s} p (MOVDconst [c.Val()&0xffffffff | a.Val()<<32]) mem)
+	// result: (MOVDstore [a.Off()] {s} p (MOVDconst [c.Val64()&0xffffffff | a.Val64()<<32]) mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
@@ -11114,10 +11167,10 @@
 			break
 		}
 		v.reset(OpS390XMOVDstore)
-		v.AuxInt = int32ToAuxInt(a.Off32())
+		v.AuxInt = int32ToAuxInt(a.Off())
 		v.Aux = symToAux(s)
 		v0 := b.NewValue0(x.Pos, OpS390XMOVDconst, typ.UInt64)
-		v0.AuxInt = int64ToAuxInt(c.Val()&0xffffffff | a.Val()<<32)
+		v0.AuxInt = int64ToAuxInt(c.Val64()&0xffffffff | a.Val64()<<32)
 		v.AddArg3(p, v0, mem)
 		return true
 	}
@@ -15865,7 +15918,7 @@
 		return true
 	}
 	// match: (Zero [3] destptr mem)
-	// result: (MOVBstoreconst [makeValAndOff32(0,2)] destptr (MOVHstoreconst [0] destptr mem))
+	// result: (MOVBstoreconst [makeValAndOff(0,2)] destptr (MOVHstoreconst [0] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 3 {
 			break
@@ -15873,7 +15926,7 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(OpS390XMOVBstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 2))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 2))
 		v0 := b.NewValue0(v.Pos, OpS390XMOVHstoreconst, types.TypeMem)
 		v0.AuxInt = valAndOffToAuxInt(0)
 		v0.AddArg2(destptr, mem)
@@ -15881,7 +15934,7 @@
 		return true
 	}
 	// match: (Zero [5] destptr mem)
-	// result: (MOVBstoreconst [makeValAndOff32(0,4)] destptr (MOVWstoreconst [0] destptr mem))
+	// result: (MOVBstoreconst [makeValAndOff(0,4)] destptr (MOVWstoreconst [0] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 5 {
 			break
@@ -15889,7 +15942,7 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(OpS390XMOVBstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 4))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 4))
 		v0 := b.NewValue0(v.Pos, OpS390XMOVWstoreconst, types.TypeMem)
 		v0.AuxInt = valAndOffToAuxInt(0)
 		v0.AddArg2(destptr, mem)
@@ -15897,7 +15950,7 @@
 		return true
 	}
 	// match: (Zero [6] destptr mem)
-	// result: (MOVHstoreconst [makeValAndOff32(0,4)] destptr (MOVWstoreconst [0] destptr mem))
+	// result: (MOVHstoreconst [makeValAndOff(0,4)] destptr (MOVWstoreconst [0] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 6 {
 			break
@@ -15905,7 +15958,7 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(OpS390XMOVHstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 4))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 4))
 		v0 := b.NewValue0(v.Pos, OpS390XMOVWstoreconst, types.TypeMem)
 		v0.AuxInt = valAndOffToAuxInt(0)
 		v0.AddArg2(destptr, mem)
@@ -15913,7 +15966,7 @@
 		return true
 	}
 	// match: (Zero [7] destptr mem)
-	// result: (MOVWstoreconst [makeValAndOff32(0,3)] destptr (MOVWstoreconst [0] destptr mem))
+	// result: (MOVWstoreconst [makeValAndOff(0,3)] destptr (MOVWstoreconst [0] destptr mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 7 {
 			break
@@ -15921,7 +15974,7 @@
 		destptr := v_0
 		mem := v_1
 		v.reset(OpS390XMOVWstoreconst)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(0, 3))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, 3))
 		v0 := b.NewValue0(v.Pos, OpS390XMOVWstoreconst, types.TypeMem)
 		v0.AuxInt = valAndOffToAuxInt(0)
 		v0.AddArg2(destptr, mem)
@@ -15930,7 +15983,7 @@
 	}
 	// match: (Zero [s] destptr mem)
 	// cond: s > 0 && s <= 1024
-	// result: (CLEAR [makeValAndOff32(int32(s), 0)] destptr mem)
+	// result: (CLEAR [makeValAndOff(int32(s), 0)] destptr mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		destptr := v_0
@@ -15939,7 +15992,7 @@
 			break
 		}
 		v.reset(OpS390XCLEAR)
-		v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(s), 0))
+		v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(s), 0))
 		v.AddArg2(destptr, mem)
 		return true
 	}
diff --git a/src/cmd/compile/internal/ssa/rewriteWasm.go b/src/cmd/compile/internal/ssa/rewriteWasm.go
index c8ecefc..5dab09f 100644
--- a/src/cmd/compile/internal/ssa/rewriteWasm.go
+++ b/src/cmd/compile/internal/ssa/rewriteWasm.go
@@ -3,8 +3,8 @@
 
 package ssa
 
+import "internal/buildcfg"
 import "math"
-import "cmd/internal/objabi"
 import "cmd/compile/internal/types"
 
 func rewriteValueWasm(v *Value) bool {
@@ -527,6 +527,9 @@
 	case OpSqrt:
 		v.Op = OpWasmF64Sqrt
 		return true
+	case OpSqrt32:
+		v.Op = OpWasmF32Sqrt
+		return true
 	case OpStaticCall:
 		v.Op = OpWasmLoweredStaticCall
 		return true
@@ -3190,11 +3193,11 @@
 		return true
 	}
 	// match: (SignExt16to32 x)
-	// cond: objabi.GOWASM.SignExt
+	// cond: buildcfg.GOWASM.SignExt
 	// result: (I64Extend16S x)
 	for {
 		x := v_0
-		if !(objabi.GOWASM.SignExt) {
+		if !(buildcfg.GOWASM.SignExt) {
 			break
 		}
 		v.reset(OpWasmI64Extend16S)
@@ -3229,11 +3232,11 @@
 		return true
 	}
 	// match: (SignExt16to64 x)
-	// cond: objabi.GOWASM.SignExt
+	// cond: buildcfg.GOWASM.SignExt
 	// result: (I64Extend16S x)
 	for {
 		x := v_0
-		if !(objabi.GOWASM.SignExt) {
+		if !(buildcfg.GOWASM.SignExt) {
 			break
 		}
 		v.reset(OpWasmI64Extend16S)
@@ -3268,11 +3271,11 @@
 		return true
 	}
 	// match: (SignExt32to64 x)
-	// cond: objabi.GOWASM.SignExt
+	// cond: buildcfg.GOWASM.SignExt
 	// result: (I64Extend32S x)
 	for {
 		x := v_0
-		if !(objabi.GOWASM.SignExt) {
+		if !(buildcfg.GOWASM.SignExt) {
 			break
 		}
 		v.reset(OpWasmI64Extend32S)
@@ -3307,11 +3310,11 @@
 		return true
 	}
 	// match: (SignExt8to16 x)
-	// cond: objabi.GOWASM.SignExt
+	// cond: buildcfg.GOWASM.SignExt
 	// result: (I64Extend8S x)
 	for {
 		x := v_0
-		if !(objabi.GOWASM.SignExt) {
+		if !(buildcfg.GOWASM.SignExt) {
 			break
 		}
 		v.reset(OpWasmI64Extend8S)
@@ -3346,11 +3349,11 @@
 		return true
 	}
 	// match: (SignExt8to32 x)
-	// cond: objabi.GOWASM.SignExt
+	// cond: buildcfg.GOWASM.SignExt
 	// result: (I64Extend8S x)
 	for {
 		x := v_0
-		if !(objabi.GOWASM.SignExt) {
+		if !(buildcfg.GOWASM.SignExt) {
 			break
 		}
 		v.reset(OpWasmI64Extend8S)
@@ -3385,11 +3388,11 @@
 		return true
 	}
 	// match: (SignExt8to64 x)
-	// cond: objabi.GOWASM.SignExt
+	// cond: buildcfg.GOWASM.SignExt
 	// result: (I64Extend8S x)
 	for {
 		x := v_0
-		if !(objabi.GOWASM.SignExt) {
+		if !(buildcfg.GOWASM.SignExt) {
 			break
 		}
 		v.reset(OpWasmI64Extend8S)
@@ -4899,7 +4902,5 @@
 	}
 }
 func rewriteBlockWasm(b *Block) bool {
-	switch b.Kind {
-	}
 	return false
 }
diff --git a/src/cmd/compile/internal/ssa/rewrite_test.go b/src/cmd/compile/internal/ssa/rewrite_test.go
index 6fe429e..357fe11 100644
--- a/src/cmd/compile/internal/ssa/rewrite_test.go
+++ b/src/cmd/compile/internal/ssa/rewrite_test.go
@@ -13,7 +13,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 insted of %d in position %d", int(x[i]), i, i+1)
+			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)
 		}
 	}
 }
@@ -205,6 +205,7 @@
 		{0x00000000, 4, false, 0, 0},
 		{0xF0000000, 4, false, 0, 0},
 		{0xF0000000, 32, false, 0, 0},
+		{0xFFFFFFFF, 0, true, 0, 0xFFFFFFFF},
 	}
 	for i, v := range tests {
 		result := mergePPC64AndSrwi(v.and, v.srw)
diff --git a/src/cmd/compile/internal/ssa/rewritedec.go b/src/cmd/compile/internal/ssa/rewritedec.go
index e0fa976..2a73a5d 100644
--- a/src/cmd/compile/internal/ssa/rewritedec.go
+++ b/src/cmd/compile/internal/ssa/rewritedec.go
@@ -23,6 +23,8 @@
 		return rewriteValuedec_OpSliceLen(v)
 	case OpSlicePtr:
 		return rewriteValuedec_OpSlicePtr(v)
+	case OpSlicePtrUnchecked:
+		return rewriteValuedec_OpSlicePtrUnchecked(v)
 	case OpStore:
 		return rewriteValuedec_OpStore(v)
 	case OpStringLen:
@@ -248,6 +250,20 @@
 	}
 	return false
 }
+func rewriteValuedec_OpSlicePtrUnchecked(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (SlicePtrUnchecked (SliceMake ptr _ _ ))
+	// result: ptr
+	for {
+		if v_0.Op != OpSliceMake {
+			break
+		}
+		ptr := v_0.Args[0]
+		v.copyOf(ptr)
+		return true
+	}
+	return false
+}
 func rewriteValuedec_OpStore(v *Value) bool {
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
@@ -409,7 +425,5 @@
 	return false
 }
 func rewriteBlockdec(b *Block) bool {
-	switch b.Kind {
-	}
 	return false
 }
diff --git a/src/cmd/compile/internal/ssa/rewritedec64.go b/src/cmd/compile/internal/ssa/rewritedec64.go
index c49bc80..7d9656a 100644
--- a/src/cmd/compile/internal/ssa/rewritedec64.go
+++ b/src/cmd/compile/internal/ssa/rewritedec64.go
@@ -184,12 +184,12 @@
 	config := b.Func.Config
 	typ := &b.Func.Config.Types
 	// match: (Arg {n} [off])
-	// cond: is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")
+	// cond: is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")
 	// result: (Int64Make (Arg <typ.Int32> {n} [off+4]) (Arg <typ.UInt32> {n} [off]))
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		n := auxToSym(v.Aux)
-		if !(is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")) {
+		if !(is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")) {
 			break
 		}
 		v.reset(OpInt64Make)
@@ -203,12 +203,12 @@
 		return true
 	}
 	// match: (Arg {n} [off])
-	// cond: is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")
+	// cond: is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")
 	// result: (Int64Make (Arg <typ.UInt32> {n} [off+4]) (Arg <typ.UInt32> {n} [off]))
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		n := auxToSym(v.Aux)
-		if !(is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")) {
+		if !(is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")) {
 			break
 		}
 		v.reset(OpInt64Make)
@@ -222,12 +222,12 @@
 		return true
 	}
 	// match: (Arg {n} [off])
-	// cond: is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")
+	// cond: is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")
 	// result: (Int64Make (Arg <typ.Int32> {n} [off]) (Arg <typ.UInt32> {n} [off+4]))
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		n := auxToSym(v.Aux)
-		if !(is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")) {
+		if !(is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")) {
 			break
 		}
 		v.reset(OpInt64Make)
@@ -241,12 +241,12 @@
 		return true
 	}
 	// match: (Arg {n} [off])
-	// cond: is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")
+	// cond: is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")
 	// result: (Int64Make (Arg <typ.UInt32> {n} [off]) (Arg <typ.UInt32> {n} [off+4]))
 	for {
 		off := auxIntToInt32(v.AuxInt)
 		n := auxToSym(v.Aux)
-		if !(is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")) {
+		if !(is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")) {
 			break
 		}
 		v.reset(OpInt64Make)
@@ -2458,7 +2458,5 @@
 	}
 }
 func rewriteBlockdec64(b *Block) bool {
-	switch b.Kind {
-	}
 	return false
 }
diff --git a/src/cmd/compile/internal/ssa/rewritedecArgs.go b/src/cmd/compile/internal/ssa/rewritedecArgs.go
deleted file mode 100644
index 23ff417..0000000
--- a/src/cmd/compile/internal/ssa/rewritedecArgs.go
+++ /dev/null
@@ -1,247 +0,0 @@
-// Code generated from gen/decArgs.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
-
-package ssa
-
-func rewriteValuedecArgs(v *Value) bool {
-	switch v.Op {
-	case OpArg:
-		return rewriteValuedecArgs_OpArg(v)
-	}
-	return false
-}
-func rewriteValuedecArgs_OpArg(v *Value) bool {
-	b := v.Block
-	config := b.Func.Config
-	fe := b.Func.fe
-	typ := &b.Func.Config.Types
-	// match: (Arg {n} [off])
-	// cond: v.Type.IsString()
-	// result: (StringMake (Arg <typ.BytePtr> {n} [off]) (Arg <typ.Int> {n} [off+int32(config.PtrSize)]))
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		n := auxToSym(v.Aux)
-		if !(v.Type.IsString()) {
-			break
-		}
-		v.reset(OpStringMake)
-		v0 := b.NewValue0(v.Pos, OpArg, typ.BytePtr)
-		v0.AuxInt = int32ToAuxInt(off)
-		v0.Aux = symToAux(n)
-		v1 := b.NewValue0(v.Pos, OpArg, typ.Int)
-		v1.AuxInt = int32ToAuxInt(off + int32(config.PtrSize))
-		v1.Aux = symToAux(n)
-		v.AddArg2(v0, v1)
-		return true
-	}
-	// match: (Arg {n} [off])
-	// cond: v.Type.IsSlice()
-	// result: (SliceMake (Arg <v.Type.Elem().PtrTo()> {n} [off]) (Arg <typ.Int> {n} [off+int32(config.PtrSize)]) (Arg <typ.Int> {n} [off+2*int32(config.PtrSize)]))
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		n := auxToSym(v.Aux)
-		if !(v.Type.IsSlice()) {
-			break
-		}
-		v.reset(OpSliceMake)
-		v0 := b.NewValue0(v.Pos, OpArg, v.Type.Elem().PtrTo())
-		v0.AuxInt = int32ToAuxInt(off)
-		v0.Aux = symToAux(n)
-		v1 := b.NewValue0(v.Pos, OpArg, typ.Int)
-		v1.AuxInt = int32ToAuxInt(off + int32(config.PtrSize))
-		v1.Aux = symToAux(n)
-		v2 := b.NewValue0(v.Pos, OpArg, typ.Int)
-		v2.AuxInt = int32ToAuxInt(off + 2*int32(config.PtrSize))
-		v2.Aux = symToAux(n)
-		v.AddArg3(v0, v1, v2)
-		return true
-	}
-	// match: (Arg {n} [off])
-	// cond: v.Type.IsInterface()
-	// result: (IMake (Arg <typ.Uintptr> {n} [off]) (Arg <typ.BytePtr> {n} [off+int32(config.PtrSize)]))
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		n := auxToSym(v.Aux)
-		if !(v.Type.IsInterface()) {
-			break
-		}
-		v.reset(OpIMake)
-		v0 := b.NewValue0(v.Pos, OpArg, typ.Uintptr)
-		v0.AuxInt = int32ToAuxInt(off)
-		v0.Aux = symToAux(n)
-		v1 := b.NewValue0(v.Pos, OpArg, typ.BytePtr)
-		v1.AuxInt = int32ToAuxInt(off + int32(config.PtrSize))
-		v1.Aux = symToAux(n)
-		v.AddArg2(v0, v1)
-		return true
-	}
-	// match: (Arg {n} [off])
-	// cond: v.Type.IsComplex() && v.Type.Size() == 16
-	// result: (ComplexMake (Arg <typ.Float64> {n} [off]) (Arg <typ.Float64> {n} [off+8]))
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		n := auxToSym(v.Aux)
-		if !(v.Type.IsComplex() && v.Type.Size() == 16) {
-			break
-		}
-		v.reset(OpComplexMake)
-		v0 := b.NewValue0(v.Pos, OpArg, typ.Float64)
-		v0.AuxInt = int32ToAuxInt(off)
-		v0.Aux = symToAux(n)
-		v1 := b.NewValue0(v.Pos, OpArg, typ.Float64)
-		v1.AuxInt = int32ToAuxInt(off + 8)
-		v1.Aux = symToAux(n)
-		v.AddArg2(v0, v1)
-		return true
-	}
-	// match: (Arg {n} [off])
-	// cond: v.Type.IsComplex() && v.Type.Size() == 8
-	// result: (ComplexMake (Arg <typ.Float32> {n} [off]) (Arg <typ.Float32> {n} [off+4]))
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		n := auxToSym(v.Aux)
-		if !(v.Type.IsComplex() && v.Type.Size() == 8) {
-			break
-		}
-		v.reset(OpComplexMake)
-		v0 := b.NewValue0(v.Pos, OpArg, typ.Float32)
-		v0.AuxInt = int32ToAuxInt(off)
-		v0.Aux = symToAux(n)
-		v1 := b.NewValue0(v.Pos, OpArg, typ.Float32)
-		v1.AuxInt = int32ToAuxInt(off + 4)
-		v1.Aux = symToAux(n)
-		v.AddArg2(v0, v1)
-		return true
-	}
-	// match: (Arg <t>)
-	// cond: t.IsStruct() && t.NumFields() == 0 && fe.CanSSA(t)
-	// result: (StructMake0)
-	for {
-		t := v.Type
-		if !(t.IsStruct() && t.NumFields() == 0 && fe.CanSSA(t)) {
-			break
-		}
-		v.reset(OpStructMake0)
-		return true
-	}
-	// match: (Arg <t> {n} [off])
-	// cond: t.IsStruct() && t.NumFields() == 1 && fe.CanSSA(t)
-	// result: (StructMake1 (Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))]))
-	for {
-		t := v.Type
-		off := auxIntToInt32(v.AuxInt)
-		n := auxToSym(v.Aux)
-		if !(t.IsStruct() && t.NumFields() == 1 && fe.CanSSA(t)) {
-			break
-		}
-		v.reset(OpStructMake1)
-		v0 := b.NewValue0(v.Pos, OpArg, t.FieldType(0))
-		v0.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(0)))
-		v0.Aux = symToAux(n)
-		v.AddArg(v0)
-		return true
-	}
-	// match: (Arg <t> {n} [off])
-	// cond: t.IsStruct() && t.NumFields() == 2 && fe.CanSSA(t)
-	// result: (StructMake2 (Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))]) (Arg <t.FieldType(1)> {n} [off+int32(t.FieldOff(1))]))
-	for {
-		t := v.Type
-		off := auxIntToInt32(v.AuxInt)
-		n := auxToSym(v.Aux)
-		if !(t.IsStruct() && t.NumFields() == 2 && fe.CanSSA(t)) {
-			break
-		}
-		v.reset(OpStructMake2)
-		v0 := b.NewValue0(v.Pos, OpArg, t.FieldType(0))
-		v0.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(0)))
-		v0.Aux = symToAux(n)
-		v1 := b.NewValue0(v.Pos, OpArg, t.FieldType(1))
-		v1.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(1)))
-		v1.Aux = symToAux(n)
-		v.AddArg2(v0, v1)
-		return true
-	}
-	// match: (Arg <t> {n} [off])
-	// cond: t.IsStruct() && t.NumFields() == 3 && fe.CanSSA(t)
-	// result: (StructMake3 (Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))]) (Arg <t.FieldType(1)> {n} [off+int32(t.FieldOff(1))]) (Arg <t.FieldType(2)> {n} [off+int32(t.FieldOff(2))]))
-	for {
-		t := v.Type
-		off := auxIntToInt32(v.AuxInt)
-		n := auxToSym(v.Aux)
-		if !(t.IsStruct() && t.NumFields() == 3 && fe.CanSSA(t)) {
-			break
-		}
-		v.reset(OpStructMake3)
-		v0 := b.NewValue0(v.Pos, OpArg, t.FieldType(0))
-		v0.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(0)))
-		v0.Aux = symToAux(n)
-		v1 := b.NewValue0(v.Pos, OpArg, t.FieldType(1))
-		v1.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(1)))
-		v1.Aux = symToAux(n)
-		v2 := b.NewValue0(v.Pos, OpArg, t.FieldType(2))
-		v2.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(2)))
-		v2.Aux = symToAux(n)
-		v.AddArg3(v0, v1, v2)
-		return true
-	}
-	// match: (Arg <t> {n} [off])
-	// cond: t.IsStruct() && t.NumFields() == 4 && fe.CanSSA(t)
-	// result: (StructMake4 (Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))]) (Arg <t.FieldType(1)> {n} [off+int32(t.FieldOff(1))]) (Arg <t.FieldType(2)> {n} [off+int32(t.FieldOff(2))]) (Arg <t.FieldType(3)> {n} [off+int32(t.FieldOff(3))]))
-	for {
-		t := v.Type
-		off := auxIntToInt32(v.AuxInt)
-		n := auxToSym(v.Aux)
-		if !(t.IsStruct() && t.NumFields() == 4 && fe.CanSSA(t)) {
-			break
-		}
-		v.reset(OpStructMake4)
-		v0 := b.NewValue0(v.Pos, OpArg, t.FieldType(0))
-		v0.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(0)))
-		v0.Aux = symToAux(n)
-		v1 := b.NewValue0(v.Pos, OpArg, t.FieldType(1))
-		v1.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(1)))
-		v1.Aux = symToAux(n)
-		v2 := b.NewValue0(v.Pos, OpArg, t.FieldType(2))
-		v2.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(2)))
-		v2.Aux = symToAux(n)
-		v3 := b.NewValue0(v.Pos, OpArg, t.FieldType(3))
-		v3.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(3)))
-		v3.Aux = symToAux(n)
-		v.AddArg4(v0, v1, v2, v3)
-		return true
-	}
-	// match: (Arg <t>)
-	// cond: t.IsArray() && t.NumElem() == 0
-	// result: (ArrayMake0)
-	for {
-		t := v.Type
-		if !(t.IsArray() && t.NumElem() == 0) {
-			break
-		}
-		v.reset(OpArrayMake0)
-		return true
-	}
-	// match: (Arg <t> {n} [off])
-	// cond: t.IsArray() && t.NumElem() == 1 && fe.CanSSA(t)
-	// result: (ArrayMake1 (Arg <t.Elem()> {n} [off]))
-	for {
-		t := v.Type
-		off := auxIntToInt32(v.AuxInt)
-		n := auxToSym(v.Aux)
-		if !(t.IsArray() && t.NumElem() == 1 && fe.CanSSA(t)) {
-			break
-		}
-		v.reset(OpArrayMake1)
-		v0 := b.NewValue0(v.Pos, OpArg, t.Elem())
-		v0.AuxInt = int32ToAuxInt(off)
-		v0.Aux = symToAux(n)
-		v.AddArg(v0)
-		return true
-	}
-	return false
-}
-func rewriteBlockdecArgs(b *Block) bool {
-	switch b.Kind {
-	}
-	return false
-}
diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
index 958e24d..5225820 100644
--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
+++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
@@ -122,8 +122,6 @@
 		return rewriteValuegeneric_OpEqSlice(v)
 	case OpIMake:
 		return rewriteValuegeneric_OpIMake(v)
-	case OpInterCall:
-		return rewriteValuegeneric_OpInterCall(v)
 	case OpInterLECall:
 		return rewriteValuegeneric_OpInterLECall(v)
 	case OpIsInBounds:
@@ -392,8 +390,6 @@
 		return rewriteValuegeneric_OpSlicemask(v)
 	case OpSqrt:
 		return rewriteValuegeneric_OpSqrt(v)
-	case OpStaticCall:
-		return rewriteValuegeneric_OpStaticCall(v)
 	case OpStaticLECall:
 		return rewriteValuegeneric_OpStaticLECall(v)
 	case OpStore:
@@ -4089,6 +4085,26 @@
 		v.AuxInt = float32ToAuxInt(float32(c))
 		return true
 	}
+	// match: (Cvt64Fto32F sqrt0:(Sqrt (Cvt32Fto64F x)))
+	// cond: sqrt0.Uses==1
+	// result: (Sqrt32 x)
+	for {
+		sqrt0 := v_0
+		if sqrt0.Op != OpSqrt {
+			break
+		}
+		sqrt0_0 := sqrt0.Args[0]
+		if sqrt0_0.Op != OpCvt32Fto64F {
+			break
+		}
+		x := sqrt0_0.Args[0]
+		if !(sqrt0.Uses == 1) {
+			break
+		}
+		v.reset(OpSqrt32)
+		v.AddArg(x)
+		return true
+	}
 	return false
 }
 func rewriteValuegeneric_OpCvt64Fto64(v *Value) bool {
@@ -8136,32 +8152,32 @@
 		v.AuxInt = boolToAuxInt(true)
 		return true
 	}
-	// match: (EqPtr (Addr {a} _) (Addr {b} _))
-	// result: (ConstBool [a == b])
+	// match: (EqPtr (Addr {x} _) (Addr {y} _))
+	// result: (ConstBool [x == y])
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpAddr {
 				continue
 			}
-			a := auxToSym(v_0.Aux)
+			x := auxToSym(v_0.Aux)
 			if v_1.Op != OpAddr {
 				continue
 			}
-			b := auxToSym(v_1.Aux)
+			y := auxToSym(v_1.Aux)
 			v.reset(OpConstBool)
-			v.AuxInt = boolToAuxInt(a == b)
+			v.AuxInt = boolToAuxInt(x == y)
 			return true
 		}
 		break
 	}
-	// match: (EqPtr (Addr {a} _) (OffPtr [o] (Addr {b} _)))
-	// result: (ConstBool [a == b && o == 0])
+	// match: (EqPtr (Addr {x} _) (OffPtr [o] (Addr {y} _)))
+	// result: (ConstBool [x == y && o == 0])
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpAddr {
 				continue
 			}
-			a := auxToSym(v_0.Aux)
+			x := auxToSym(v_0.Aux)
 			if v_1.Op != OpOffPtr {
 				continue
 			}
@@ -8170,15 +8186,15 @@
 			if v_1_0.Op != OpAddr {
 				continue
 			}
-			b := auxToSym(v_1_0.Aux)
+			y := auxToSym(v_1_0.Aux)
 			v.reset(OpConstBool)
-			v.AuxInt = boolToAuxInt(a == b && o == 0)
+			v.AuxInt = boolToAuxInt(x == y && o == 0)
 			return true
 		}
 		break
 	}
-	// match: (EqPtr (OffPtr [o1] (Addr {a} _)) (OffPtr [o2] (Addr {b} _)))
-	// result: (ConstBool [a == b && o1 == o2])
+	// match: (EqPtr (OffPtr [o1] (Addr {x} _)) (OffPtr [o2] (Addr {y} _)))
+	// result: (ConstBool [x == y && o1 == o2])
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpOffPtr {
@@ -8189,7 +8205,7 @@
 			if v_0_0.Op != OpAddr {
 				continue
 			}
-			a := auxToSym(v_0_0.Aux)
+			x := auxToSym(v_0_0.Aux)
 			if v_1.Op != OpOffPtr {
 				continue
 			}
@@ -8198,39 +8214,39 @@
 			if v_1_0.Op != OpAddr {
 				continue
 			}
-			b := auxToSym(v_1_0.Aux)
+			y := auxToSym(v_1_0.Aux)
 			v.reset(OpConstBool)
-			v.AuxInt = boolToAuxInt(a == b && o1 == o2)
+			v.AuxInt = boolToAuxInt(x == y && o1 == o2)
 			return true
 		}
 		break
 	}
-	// match: (EqPtr (LocalAddr {a} _ _) (LocalAddr {b} _ _))
-	// result: (ConstBool [a == b])
+	// match: (EqPtr (LocalAddr {x} _ _) (LocalAddr {y} _ _))
+	// result: (ConstBool [x == y])
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpLocalAddr {
 				continue
 			}
-			a := auxToSym(v_0.Aux)
+			x := auxToSym(v_0.Aux)
 			if v_1.Op != OpLocalAddr {
 				continue
 			}
-			b := auxToSym(v_1.Aux)
+			y := auxToSym(v_1.Aux)
 			v.reset(OpConstBool)
-			v.AuxInt = boolToAuxInt(a == b)
+			v.AuxInt = boolToAuxInt(x == y)
 			return true
 		}
 		break
 	}
-	// match: (EqPtr (LocalAddr {a} _ _) (OffPtr [o] (LocalAddr {b} _ _)))
-	// result: (ConstBool [a == b && o == 0])
+	// match: (EqPtr (LocalAddr {x} _ _) (OffPtr [o] (LocalAddr {y} _ _)))
+	// result: (ConstBool [x == y && o == 0])
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpLocalAddr {
 				continue
 			}
-			a := auxToSym(v_0.Aux)
+			x := auxToSym(v_0.Aux)
 			if v_1.Op != OpOffPtr {
 				continue
 			}
@@ -8239,15 +8255,15 @@
 			if v_1_0.Op != OpLocalAddr {
 				continue
 			}
-			b := auxToSym(v_1_0.Aux)
+			y := auxToSym(v_1_0.Aux)
 			v.reset(OpConstBool)
-			v.AuxInt = boolToAuxInt(a == b && o == 0)
+			v.AuxInt = boolToAuxInt(x == y && o == 0)
 			return true
 		}
 		break
 	}
-	// match: (EqPtr (OffPtr [o1] (LocalAddr {a} _ _)) (OffPtr [o2] (LocalAddr {b} _ _)))
-	// result: (ConstBool [a == b && o1 == o2])
+	// match: (EqPtr (OffPtr [o1] (LocalAddr {x} _ _)) (OffPtr [o2] (LocalAddr {y} _ _)))
+	// result: (ConstBool [x == y && o1 == o2])
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpOffPtr {
@@ -8258,7 +8274,7 @@
 			if v_0_0.Op != OpLocalAddr {
 				continue
 			}
-			a := auxToSym(v_0_0.Aux)
+			x := auxToSym(v_0_0.Aux)
 			if v_1.Op != OpOffPtr {
 				continue
 			}
@@ -8267,9 +8283,9 @@
 			if v_1_0.Op != OpLocalAddr {
 				continue
 			}
-			b := auxToSym(v_1_0.Aux)
+			y := auxToSym(v_1_0.Aux)
 			v.reset(OpConstBool)
-			v.AuxInt = boolToAuxInt(a == b && o1 == o2)
+			v.AuxInt = boolToAuxInt(x == y && o1 == o2)
 			return true
 		}
 		break
@@ -8516,74 +8532,28 @@
 func rewriteValuegeneric_OpIMake(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (IMake typ (StructMake1 val))
-	// result: (IMake typ val)
+	// match: (IMake _typ (StructMake1 val))
+	// result: (IMake _typ val)
 	for {
-		typ := v_0
+		_typ := v_0
 		if v_1.Op != OpStructMake1 {
 			break
 		}
 		val := v_1.Args[0]
 		v.reset(OpIMake)
-		v.AddArg2(typ, val)
+		v.AddArg2(_typ, val)
 		return true
 	}
-	// match: (IMake typ (ArrayMake1 val))
-	// result: (IMake typ val)
+	// match: (IMake _typ (ArrayMake1 val))
+	// result: (IMake _typ val)
 	for {
-		typ := v_0
+		_typ := v_0
 		if v_1.Op != OpArrayMake1 {
 			break
 		}
 		val := v_1.Args[0]
 		v.reset(OpIMake)
-		v.AddArg2(typ, val)
-		return true
-	}
-	return false
-}
-func rewriteValuegeneric_OpInterCall(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (InterCall [argsize] {auxCall} (Load (OffPtr [off] (ITab (IMake (Addr {itab} (SB)) _))) _) mem)
-	// cond: devirt(v, auxCall, itab, off) != nil
-	// result: (StaticCall [int32(argsize)] {devirt(v, auxCall, itab, off)} mem)
-	for {
-		argsize := auxIntToInt32(v.AuxInt)
-		auxCall := auxToCall(v.Aux)
-		if v_0.Op != OpLoad {
-			break
-		}
-		v_0_0 := v_0.Args[0]
-		if v_0_0.Op != OpOffPtr {
-			break
-		}
-		off := auxIntToInt64(v_0_0.AuxInt)
-		v_0_0_0 := v_0_0.Args[0]
-		if v_0_0_0.Op != OpITab {
-			break
-		}
-		v_0_0_0_0 := v_0_0_0.Args[0]
-		if v_0_0_0_0.Op != OpIMake {
-			break
-		}
-		v_0_0_0_0_0 := v_0_0_0_0.Args[0]
-		if v_0_0_0_0_0.Op != OpAddr {
-			break
-		}
-		itab := auxToSym(v_0_0_0_0_0.Aux)
-		v_0_0_0_0_0_0 := v_0_0_0_0_0.Args[0]
-		if v_0_0_0_0_0_0.Op != OpSB {
-			break
-		}
-		mem := v_1
-		if !(devirt(v, auxCall, itab, off) != nil) {
-			break
-		}
-		v.reset(OpStaticCall)
-		v.AuxInt = int32ToAuxInt(int32(argsize))
-		v.Aux = callToAux(devirt(v, auxCall, itab, off))
-		v.AddArg(mem)
+		v.AddArg2(_typ, val)
 		return true
 	}
 	return false
@@ -15740,32 +15710,32 @@
 		v.AuxInt = boolToAuxInt(false)
 		return true
 	}
-	// match: (NeqPtr (Addr {a} _) (Addr {b} _))
-	// result: (ConstBool [a != b])
+	// match: (NeqPtr (Addr {x} _) (Addr {y} _))
+	// result: (ConstBool [x != y])
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpAddr {
 				continue
 			}
-			a := auxToSym(v_0.Aux)
+			x := auxToSym(v_0.Aux)
 			if v_1.Op != OpAddr {
 				continue
 			}
-			b := auxToSym(v_1.Aux)
+			y := auxToSym(v_1.Aux)
 			v.reset(OpConstBool)
-			v.AuxInt = boolToAuxInt(a != b)
+			v.AuxInt = boolToAuxInt(x != y)
 			return true
 		}
 		break
 	}
-	// match: (NeqPtr (Addr {a} _) (OffPtr [o] (Addr {b} _)))
-	// result: (ConstBool [a != b || o != 0])
+	// match: (NeqPtr (Addr {x} _) (OffPtr [o] (Addr {y} _)))
+	// result: (ConstBool [x != y || o != 0])
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpAddr {
 				continue
 			}
-			a := auxToSym(v_0.Aux)
+			x := auxToSym(v_0.Aux)
 			if v_1.Op != OpOffPtr {
 				continue
 			}
@@ -15774,15 +15744,15 @@
 			if v_1_0.Op != OpAddr {
 				continue
 			}
-			b := auxToSym(v_1_0.Aux)
+			y := auxToSym(v_1_0.Aux)
 			v.reset(OpConstBool)
-			v.AuxInt = boolToAuxInt(a != b || o != 0)
+			v.AuxInt = boolToAuxInt(x != y || o != 0)
 			return true
 		}
 		break
 	}
-	// match: (NeqPtr (OffPtr [o1] (Addr {a} _)) (OffPtr [o2] (Addr {b} _)))
-	// result: (ConstBool [a != b || o1 != o2])
+	// match: (NeqPtr (OffPtr [o1] (Addr {x} _)) (OffPtr [o2] (Addr {y} _)))
+	// result: (ConstBool [x != y || o1 != o2])
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpOffPtr {
@@ -15793,7 +15763,7 @@
 			if v_0_0.Op != OpAddr {
 				continue
 			}
-			a := auxToSym(v_0_0.Aux)
+			x := auxToSym(v_0_0.Aux)
 			if v_1.Op != OpOffPtr {
 				continue
 			}
@@ -15802,39 +15772,39 @@
 			if v_1_0.Op != OpAddr {
 				continue
 			}
-			b := auxToSym(v_1_0.Aux)
+			y := auxToSym(v_1_0.Aux)
 			v.reset(OpConstBool)
-			v.AuxInt = boolToAuxInt(a != b || o1 != o2)
+			v.AuxInt = boolToAuxInt(x != y || o1 != o2)
 			return true
 		}
 		break
 	}
-	// match: (NeqPtr (LocalAddr {a} _ _) (LocalAddr {b} _ _))
-	// result: (ConstBool [a != b])
+	// match: (NeqPtr (LocalAddr {x} _ _) (LocalAddr {y} _ _))
+	// result: (ConstBool [x != y])
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpLocalAddr {
 				continue
 			}
-			a := auxToSym(v_0.Aux)
+			x := auxToSym(v_0.Aux)
 			if v_1.Op != OpLocalAddr {
 				continue
 			}
-			b := auxToSym(v_1.Aux)
+			y := auxToSym(v_1.Aux)
 			v.reset(OpConstBool)
-			v.AuxInt = boolToAuxInt(a != b)
+			v.AuxInt = boolToAuxInt(x != y)
 			return true
 		}
 		break
 	}
-	// match: (NeqPtr (LocalAddr {a} _ _) (OffPtr [o] (LocalAddr {b} _ _)))
-	// result: (ConstBool [a != b || o != 0])
+	// match: (NeqPtr (LocalAddr {x} _ _) (OffPtr [o] (LocalAddr {y} _ _)))
+	// result: (ConstBool [x != y || o != 0])
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpLocalAddr {
 				continue
 			}
-			a := auxToSym(v_0.Aux)
+			x := auxToSym(v_0.Aux)
 			if v_1.Op != OpOffPtr {
 				continue
 			}
@@ -15843,15 +15813,15 @@
 			if v_1_0.Op != OpLocalAddr {
 				continue
 			}
-			b := auxToSym(v_1_0.Aux)
+			y := auxToSym(v_1_0.Aux)
 			v.reset(OpConstBool)
-			v.AuxInt = boolToAuxInt(a != b || o != 0)
+			v.AuxInt = boolToAuxInt(x != y || o != 0)
 			return true
 		}
 		break
 	}
-	// match: (NeqPtr (OffPtr [o1] (LocalAddr {a} _ _)) (OffPtr [o2] (LocalAddr {b} _ _)))
-	// result: (ConstBool [a != b || o1 != o2])
+	// match: (NeqPtr (OffPtr [o1] (LocalAddr {x} _ _)) (OffPtr [o2] (LocalAddr {y} _ _)))
+	// result: (ConstBool [x != y || o1 != o2])
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpOffPtr {
@@ -15862,7 +15832,7 @@
 			if v_0_0.Op != OpLocalAddr {
 				continue
 			}
-			a := auxToSym(v_0_0.Aux)
+			x := auxToSym(v_0_0.Aux)
 			if v_1.Op != OpOffPtr {
 				continue
 			}
@@ -15871,9 +15841,9 @@
 			if v_1_0.Op != OpLocalAddr {
 				continue
 			}
-			b := auxToSym(v_1_0.Aux)
+			y := auxToSym(v_1_0.Aux)
 			v.reset(OpConstBool)
-			v.AuxInt = boolToAuxInt(a != b || o1 != o2)
+			v.AuxInt = boolToAuxInt(x != y || o1 != o2)
 			return true
 		}
 		break
@@ -16113,7 +16083,6 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	config := b.Func.Config
 	fe := b.Func.fe
 	// match: (NilCheck (GetG mem) mem)
 	// result: mem
@@ -16128,67 +16097,7 @@
 		v.copyOf(mem)
 		return true
 	}
-	// match: (NilCheck (Load (OffPtr [c] (SP)) (StaticCall {sym} _)) _)
-	// cond: isSameCall(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize && warnRule(fe.Debug_checknil(), v, "removed nil check")
-	// result: (Invalid)
-	for {
-		if v_0.Op != OpLoad {
-			break
-		}
-		_ = v_0.Args[1]
-		v_0_0 := v_0.Args[0]
-		if v_0_0.Op != OpOffPtr {
-			break
-		}
-		c := auxIntToInt64(v_0_0.AuxInt)
-		v_0_0_0 := v_0_0.Args[0]
-		if v_0_0_0.Op != OpSP {
-			break
-		}
-		v_0_1 := v_0.Args[1]
-		if v_0_1.Op != OpStaticCall {
-			break
-		}
-		sym := auxToCall(v_0_1.Aux)
-		if !(isSameCall(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(fe.Debug_checknil(), v, "removed nil check")) {
-			break
-		}
-		v.reset(OpInvalid)
-		return true
-	}
-	// match: (NilCheck (OffPtr (Load (OffPtr [c] (SP)) (StaticCall {sym} _))) _)
-	// cond: isSameCall(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize && warnRule(fe.Debug_checknil(), v, "removed nil check")
-	// result: (Invalid)
-	for {
-		if v_0.Op != OpOffPtr {
-			break
-		}
-		v_0_0 := v_0.Args[0]
-		if v_0_0.Op != OpLoad {
-			break
-		}
-		_ = v_0_0.Args[1]
-		v_0_0_0 := v_0_0.Args[0]
-		if v_0_0_0.Op != OpOffPtr {
-			break
-		}
-		c := auxIntToInt64(v_0_0_0.AuxInt)
-		v_0_0_0_0 := v_0_0_0.Args[0]
-		if v_0_0_0_0.Op != OpSP {
-			break
-		}
-		v_0_0_1 := v_0_0.Args[1]
-		if v_0_0_1.Op != OpStaticCall {
-			break
-		}
-		sym := auxToCall(v_0_0_1.Aux)
-		if !(isSameCall(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(fe.Debug_checknil(), v, "removed nil check")) {
-			break
-		}
-		v.reset(OpInvalid)
-		return true
-	}
-	// match: (NilCheck (SelectN [0] call:(StaticLECall _ _)) (SelectN [1] call))
+	// match: (NilCheck (SelectN [0] call:(StaticLECall _ _)) _)
 	// cond: isSameCall(call.Aux, "runtime.newobject") && warnRule(fe.Debug_checknil(), v, "removed nil check")
 	// result: (Invalid)
 	for {
@@ -16196,13 +16105,13 @@
 			break
 		}
 		call := v_0.Args[0]
-		if call.Op != OpStaticLECall || len(call.Args) != 2 || v_1.Op != OpSelectN || auxIntToInt64(v_1.AuxInt) != 1 || call != v_1.Args[0] || !(isSameCall(call.Aux, "runtime.newobject") && warnRule(fe.Debug_checknil(), v, "removed nil check")) {
+		if call.Op != OpStaticLECall || len(call.Args) != 2 || !(isSameCall(call.Aux, "runtime.newobject") && warnRule(fe.Debug_checknil(), v, "removed nil check")) {
 			break
 		}
 		v.reset(OpInvalid)
 		return true
 	}
-	// match: (NilCheck (OffPtr (SelectN [0] call:(StaticLECall _ _))) (SelectN [1] call))
+	// match: (NilCheck (OffPtr (SelectN [0] call:(StaticLECall _ _))) _)
 	// cond: isSameCall(call.Aux, "runtime.newobject") && warnRule(fe.Debug_checknil(), v, "removed nil check")
 	// result: (Invalid)
 	for {
@@ -16214,7 +16123,7 @@
 			break
 		}
 		call := v_0_0.Args[0]
-		if call.Op != OpStaticLECall || len(call.Args) != 2 || v_1.Op != OpSelectN || auxIntToInt64(v_1.AuxInt) != 1 || call != v_1.Args[0] || !(isSameCall(call.Aux, "runtime.newobject") && warnRule(fe.Debug_checknil(), v, "removed nil check")) {
+		if call.Op != OpStaticLECall || len(call.Args) != 2 || !(isSameCall(call.Aux, "runtime.newobject") && warnRule(fe.Debug_checknil(), v, "removed nil check")) {
 			break
 		}
 		v.reset(OpInvalid)
@@ -16623,17 +16532,17 @@
 }
 func rewriteValuegeneric_OpOffPtr(v *Value) bool {
 	v_0 := v.Args[0]
-	// match: (OffPtr (OffPtr p [b]) [a])
-	// result: (OffPtr p [a+b])
+	// match: (OffPtr (OffPtr p [y]) [x])
+	// result: (OffPtr p [x+y])
 	for {
-		a := auxIntToInt64(v.AuxInt)
+		x := auxIntToInt64(v.AuxInt)
 		if v_0.Op != OpOffPtr {
 			break
 		}
-		b := auxIntToInt64(v_0.AuxInt)
+		y := auxIntToInt64(v_0.AuxInt)
 		p := v_0.Args[0]
 		v.reset(OpOffPtr)
-		v.AuxInt = int64ToAuxInt(a + b)
+		v.AuxInt = int64ToAuxInt(x + y)
 		v.AddArg(p)
 		return true
 	}
@@ -20769,34 +20678,180 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	config := b.Func.Config
-	// match: (SelectN [0] (MakeResult a ___))
-	// result: a
+	// match: (SelectN [0] (MakeResult x ___))
+	// result: x
 	for {
 		if auxIntToInt64(v.AuxInt) != 0 || v_0.Op != OpMakeResult || len(v_0.Args) < 1 {
 			break
 		}
-		a := v_0.Args[0]
-		v.copyOf(a)
+		x := v_0.Args[0]
+		v.copyOf(x)
 		return true
 	}
-	// match: (SelectN [1] (MakeResult a b ___))
-	// result: b
+	// match: (SelectN [1] (MakeResult x y ___))
+	// result: y
 	for {
 		if auxIntToInt64(v.AuxInt) != 1 || v_0.Op != OpMakeResult || len(v_0.Args) < 2 {
 			break
 		}
-		b := v_0.Args[1]
-		v.copyOf(b)
+		y := v_0.Args[1]
+		v.copyOf(y)
 		return true
 	}
-	// match: (SelectN [2] (MakeResult a b c ___))
-	// result: c
+	// match: (SelectN [2] (MakeResult x y z ___))
+	// result: z
 	for {
 		if auxIntToInt64(v.AuxInt) != 2 || v_0.Op != OpMakeResult || len(v_0.Args) < 3 {
 			break
 		}
-		c := v_0.Args[2]
-		v.copyOf(c)
+		z := v_0.Args[2]
+		v.copyOf(z)
+		return true
+	}
+	// match: (SelectN [0] call:(StaticCall {sym} s1:(Store _ (Const64 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem)))))
+	// cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)
+	// result: (Move {t.Elem()} [int64(sz)] dst src mem)
+	for {
+		if auxIntToInt64(v.AuxInt) != 0 {
+			break
+		}
+		call := v_0
+		if call.Op != OpStaticCall || len(call.Args) != 1 {
+			break
+		}
+		sym := auxToCall(call.Aux)
+		s1 := call.Args[0]
+		if s1.Op != OpStore {
+			break
+		}
+		_ = s1.Args[2]
+		s1_1 := s1.Args[1]
+		if s1_1.Op != OpConst64 {
+			break
+		}
+		sz := auxIntToInt64(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 := auxToType(s3.Aux)
+		mem := s3.Args[2]
+		dst := s3.Args[1]
+		if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)) {
+			break
+		}
+		v.reset(OpMove)
+		v.AuxInt = int64ToAuxInt(int64(sz))
+		v.Aux = typeToAux(t.Elem())
+		v.AddArg3(dst, src, mem)
+		return true
+	}
+	// match: (SelectN [0] call:(StaticCall {sym} s1:(Store _ (Const32 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem)))))
+	// cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)
+	// result: (Move {t.Elem()} [int64(sz)] dst src mem)
+	for {
+		if auxIntToInt64(v.AuxInt) != 0 {
+			break
+		}
+		call := v_0
+		if call.Op != OpStaticCall || len(call.Args) != 1 {
+			break
+		}
+		sym := auxToCall(call.Aux)
+		s1 := call.Args[0]
+		if s1.Op != OpStore {
+			break
+		}
+		_ = s1.Args[2]
+		s1_1 := s1.Args[1]
+		if s1_1.Op != OpConst32 {
+			break
+		}
+		sz := auxIntToInt32(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 := auxToType(s3.Aux)
+		mem := s3.Args[2]
+		dst := s3.Args[1]
+		if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)) {
+			break
+		}
+		v.reset(OpMove)
+		v.AuxInt = int64ToAuxInt(int64(sz))
+		v.Aux = typeToAux(t.Elem())
+		v.AddArg3(dst, src, mem)
+		return true
+	}
+	// match: (SelectN [0] call:(StaticCall {sym} dst src (Const64 [sz]) mem))
+	// cond: sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)
+	// result: (Move {dst.Type.Elem()} [int64(sz)] dst src mem)
+	for {
+		if auxIntToInt64(v.AuxInt) != 0 {
+			break
+		}
+		call := v_0
+		if call.Op != OpStaticCall || len(call.Args) != 4 {
+			break
+		}
+		sym := auxToCall(call.Aux)
+		mem := call.Args[3]
+		dst := call.Args[0]
+		src := call.Args[1]
+		call_2 := call.Args[2]
+		if call_2.Op != OpConst64 {
+			break
+		}
+		sz := auxIntToInt64(call_2.AuxInt)
+		if !(sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)) {
+			break
+		}
+		v.reset(OpMove)
+		v.AuxInt = int64ToAuxInt(int64(sz))
+		v.Aux = typeToAux(dst.Type.Elem())
+		v.AddArg3(dst, src, mem)
+		return true
+	}
+	// match: (SelectN [0] call:(StaticCall {sym} dst src (Const32 [sz]) mem))
+	// cond: sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)
+	// result: (Move {dst.Type.Elem()} [int64(sz)] dst src mem)
+	for {
+		if auxIntToInt64(v.AuxInt) != 0 {
+			break
+		}
+		call := v_0
+		if call.Op != OpStaticCall || len(call.Args) != 4 {
+			break
+		}
+		sym := auxToCall(call.Aux)
+		mem := call.Args[3]
+		dst := call.Args[0]
+		src := call.Args[1]
+		call_2 := call.Args[2]
+		if call_2.Op != OpConst32 {
+			break
+		}
+		sz := auxIntToInt32(call_2.AuxInt)
+		if !(sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)) {
+			break
+		}
+		v.reset(OpMove)
+		v.AuxInt = int64ToAuxInt(int64(sz))
+		v.Aux = typeToAux(dst.Type.Elem())
+		v.AddArg3(dst, src, mem)
 		return true
 	}
 	// match: (SelectN [0] call:(StaticLECall {sym} dst src (Const64 [sz]) mem))
@@ -20857,6 +20912,44 @@
 		v.AddArg3(dst, src, mem)
 		return true
 	}
+	// match: (SelectN [0] call:(StaticLECall {sym} a x))
+	// cond: needRaceCleanup(sym, call) && clobber(call)
+	// result: x
+	for {
+		if auxIntToInt64(v.AuxInt) != 0 {
+			break
+		}
+		call := v_0
+		if call.Op != OpStaticLECall || len(call.Args) != 2 {
+			break
+		}
+		sym := auxToCall(call.Aux)
+		x := call.Args[1]
+		if !(needRaceCleanup(sym, call) && clobber(call)) {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (SelectN [0] call:(StaticLECall {sym} x))
+	// cond: needRaceCleanup(sym, call) && clobber(call)
+	// result: x
+	for {
+		if auxIntToInt64(v.AuxInt) != 0 {
+			break
+		}
+		call := v_0
+		if call.Op != OpStaticLECall || len(call.Args) != 1 {
+			break
+		}
+		sym := auxToCall(call.Aux)
+		x := call.Args[0]
+		if !(needRaceCleanup(sym, call) && clobber(call)) {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
 	return false
 }
 func rewriteValuegeneric_OpSignExt16to32(v *Value) bool {
@@ -21307,98 +21400,6 @@
 	}
 	return false
 }
-func rewriteValuegeneric_OpStaticCall(v *Value) bool {
-	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
-	// match: (StaticCall {sym} s1:(Store _ (Const64 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
-	// cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3)
-	// result: (Move {t.Elem()} [int64(sz)] dst src mem)
-	for {
-		sym := auxToCall(v.Aux)
-		s1 := v_0
-		if s1.Op != OpStore {
-			break
-		}
-		_ = s1.Args[2]
-		s1_1 := s1.Args[1]
-		if s1_1.Op != OpConst64 {
-			break
-		}
-		sz := auxIntToInt64(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 := auxToType(s3.Aux)
-		mem := s3.Args[2]
-		dst := s3.Args[1]
-		if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3)) {
-			break
-		}
-		v.reset(OpMove)
-		v.AuxInt = int64ToAuxInt(int64(sz))
-		v.Aux = typeToAux(t.Elem())
-		v.AddArg3(dst, src, mem)
-		return true
-	}
-	// match: (StaticCall {sym} s1:(Store _ (Const32 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
-	// cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3)
-	// result: (Move {t.Elem()} [int64(sz)] dst src mem)
-	for {
-		sym := auxToCall(v.Aux)
-		s1 := v_0
-		if s1.Op != OpStore {
-			break
-		}
-		_ = s1.Args[2]
-		s1_1 := s1.Args[1]
-		if s1_1.Op != OpConst32 {
-			break
-		}
-		sz := auxIntToInt32(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 := auxToType(s3.Aux)
-		mem := s3.Args[2]
-		dst := s3.Args[1]
-		if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3)) {
-			break
-		}
-		v.reset(OpMove)
-		v.AuxInt = int64ToAuxInt(int64(sz))
-		v.Aux = typeToAux(t.Elem())
-		v.AddArg3(dst, src, mem)
-		return true
-	}
-	// match: (StaticCall {sym} x)
-	// cond: needRaceCleanup(sym, v)
-	// result: x
-	for {
-		sym := auxToCall(v.Aux)
-		x := v_0
-		if !(needRaceCleanup(sym, v)) {
-			break
-		}
-		v.copyOf(x)
-		return true
-	}
-	return false
-}
 func rewriteValuegeneric_OpStaticLECall(v *Value) bool {
 	b := v.Block
 	typ := &b.Func.Config.Types
@@ -21442,7 +21443,6 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	config := b.Func.Config
 	fe := b.Func.fe
 	// match: (Store {t1} p1 (Load <t2> p2 mem) mem)
 	// cond: isSamePtr(p1, p2) && t2.Size() == t1.Size()
@@ -21890,58 +21890,6 @@
 		v.AddArg3(dst, e, mem)
 		return true
 	}
-	// match: (Store (Load (OffPtr [c] (SP)) mem) x mem)
-	// cond: isConstZero(x) && mem.Op == OpStaticCall && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize
-	// result: mem
-	for {
-		if v_0.Op != OpLoad {
-			break
-		}
-		mem := v_0.Args[1]
-		v_0_0 := v_0.Args[0]
-		if v_0_0.Op != OpOffPtr {
-			break
-		}
-		c := auxIntToInt64(v_0_0.AuxInt)
-		v_0_0_0 := v_0_0.Args[0]
-		if v_0_0_0.Op != OpSP {
-			break
-		}
-		x := v_1
-		if mem != v_2 || !(isConstZero(x) && mem.Op == OpStaticCall && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize) {
-			break
-		}
-		v.copyOf(mem)
-		return true
-	}
-	// match: (Store (OffPtr (Load (OffPtr [c] (SP)) mem)) x mem)
-	// cond: isConstZero(x) && mem.Op == OpStaticCall && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize
-	// result: mem
-	for {
-		if v_0.Op != OpOffPtr {
-			break
-		}
-		v_0_0 := v_0.Args[0]
-		if v_0_0.Op != OpLoad {
-			break
-		}
-		mem := v_0_0.Args[1]
-		v_0_0_0 := v_0_0.Args[0]
-		if v_0_0_0.Op != OpOffPtr {
-			break
-		}
-		c := auxIntToInt64(v_0_0_0.AuxInt)
-		v_0_0_0_0 := v_0_0_0.Args[0]
-		if v_0_0_0_0.Op != OpSP {
-			break
-		}
-		x := v_1
-		if mem != v_2 || !(isConstZero(x) && mem.Op == OpStaticCall && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize) {
-			break
-		}
-		v.copyOf(mem)
-		return true
-	}
 	// match: (Store (SelectN [0] call:(StaticLECall _ _)) x mem:(SelectN [1] call))
 	// cond: isConstZero(x) && isSameCall(call.Aux, "runtime.newobject")
 	// result: mem
@@ -24660,27 +24608,6 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	config := b.Func.Config
-	// match: (Zero (Load (OffPtr [c] (SP)) mem) mem)
-	// cond: mem.Op == OpStaticCall && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize
-	// result: mem
-	for {
-		if v_0.Op != OpLoad {
-			break
-		}
-		mem := v_0.Args[1]
-		v_0_0 := v_0.Args[0]
-		if v_0_0.Op != OpOffPtr {
-			break
-		}
-		c := auxIntToInt64(v_0_0.AuxInt)
-		v_0_0_0 := v_0_0.Args[0]
-		if v_0_0_0.Op != OpSP || mem != v_1 || !(mem.Op == OpStaticCall && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize) {
-			break
-		}
-		v.copyOf(mem)
-		return true
-	}
 	// match: (Zero (SelectN [0] call:(StaticLECall _ _)) mem:(SelectN [1] call))
 	// cond: isSameCall(call.Aux, "runtime.newobject")
 	// result: mem
diff --git a/src/cmd/compile/internal/ssa/schedule.go b/src/cmd/compile/internal/ssa/schedule.go
index 8facb91..4e3e5e7 100644
--- a/src/cmd/compile/internal/ssa/schedule.go
+++ b/src/cmd/compile/internal/ssa/schedule.go
@@ -137,6 +137,13 @@
 			case v.Op == OpVarDef:
 				// We want all the vardefs next.
 				score[v.ID] = ScoreVarDef
+			case v.Op == OpArgIntReg || v.Op == OpArgFloatReg:
+				// In-register args must be scheduled as early as possible to ensure that the
+				// context register is not stomped. They should only appear in the entry block.
+				if b != f.Entry {
+					f.Fatalf("%s appeared outside of entry block, b=%s", v.Op, b.String())
+				}
+				score[v.ID] = ScorePhi
 			case v.Op == OpArg:
 				// We want all the args as early as possible, for better debugging.
 				score[v.ID] = ScoreArg
@@ -145,7 +152,7 @@
 				// reduce register pressure. It also helps make sure
 				// VARDEF ops are scheduled before the corresponding LEA.
 				score[v.ID] = ScoreMemory
-			case v.Op == OpSelect0 || v.Op == OpSelect1:
+			case v.Op == OpSelect0 || v.Op == OpSelect1 || v.Op == OpSelectN:
 				// Schedule the pseudo-op of reading part of a tuple
 				// immediately after the tuple-generating op, since
 				// this value is already live. This also removes its
@@ -270,6 +277,20 @@
 					tuples[v.Args[0].ID] = make([]*Value, 2)
 				}
 				tuples[v.Args[0].ID][1] = v
+			case v.Op == OpSelectN:
+				if tuples[v.Args[0].ID] == nil {
+					tuples[v.Args[0].ID] = make([]*Value, v.Args[0].Type.NumFields())
+				}
+				tuples[v.Args[0].ID][v.AuxInt] = v
+			case v.Type.IsResults() && tuples[v.ID] != nil:
+				tup := tuples[v.ID]
+				for i := len(tup) - 1; i >= 0; i-- {
+					if tup[i] != nil {
+						order = append(order, tup[i])
+					}
+				}
+				delete(tuples, v.ID)
+				order = append(order, v)
 			case v.Type.IsTuple() && tuples[v.ID] != nil:
 				if tuples[v.ID][1] != nil {
 					order = append(order, tuples[v.ID][1])
diff --git a/src/cmd/compile/internal/ssa/shortcircuit.go b/src/cmd/compile/internal/ssa/shortcircuit.go
index 4dd86ec..29abf3c 100644
--- a/src/cmd/compile/internal/ssa/shortcircuit.go
+++ b/src/cmd/compile/internal/ssa/shortcircuit.go
@@ -284,6 +284,13 @@
 	// u is the "untaken" branch: the successor we never go to when coming in from p.
 	u := b.Succs[1^ti].b
 
+	// In the following CFG matching, ensure that b's preds are entirely distinct from b's succs.
+	// This is probably a stronger condition than required, but this happens extremely rarely,
+	// and it makes it easier to avoid getting deceived by pretty ASCII charts. See #44465.
+	if p0, p1 := b.Preds[0].b, b.Preds[1].b; p0 == t || p1 == t || p0 == u || p1 == u {
+		return nil
+	}
+
 	// Look for some common CFG structures
 	// in which the outbound paths from b merge,
 	// with no other preds joining them.
diff --git a/src/cmd/compile/internal/ssa/sizeof_test.go b/src/cmd/compile/internal/ssa/sizeof_test.go
index 60ada01..a27002e 100644
--- a/src/cmd/compile/internal/ssa/sizeof_test.go
+++ b/src/cmd/compile/internal/ssa/sizeof_test.go
@@ -22,7 +22,7 @@
 	}{
 		{Value{}, 72, 112},
 		{Block{}, 164, 304},
-		{LocalSlot{}, 32, 48},
+		{LocalSlot{}, 28, 40},
 		{valState{}, 28, 40},
 	}
 
diff --git a/src/cmd/compile/internal/ssa/sparsetree.go b/src/cmd/compile/internal/ssa/sparsetree.go
index 1be20b2..be914c8 100644
--- a/src/cmd/compile/internal/ssa/sparsetree.go
+++ b/src/cmd/compile/internal/ssa/sparsetree.go
@@ -178,6 +178,12 @@
 	return t[x.ID].child
 }
 
+// Parent returns the parent of x in the dominator tree, or
+// nil if x is the function's entry.
+func (t SparseTree) Parent(x *Block) *Block {
+	return t[x.ID].parent
+}
+
 // isAncestorEq reports whether x is an ancestor of or equal to y.
 func (t SparseTree) IsAncestorEq(x, y *Block) bool {
 	if x == y {
diff --git a/src/cmd/compile/internal/ssa/sparsetreemap.go b/src/cmd/compile/internal/ssa/sparsetreemap.go
deleted file mode 100644
index d264675..0000000
--- a/src/cmd/compile/internal/ssa/sparsetreemap.go
+++ /dev/null
@@ -1,189 +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.
-
-package ssa
-
-import "fmt"
-
-// A SparseTreeMap encodes a subset of nodes within a tree
-// used for sparse-ancestor queries.
-//
-// Combined with a SparseTreeHelper, this supports an Insert
-// to add a tree node to the set and a Find operation to locate
-// the nearest tree ancestor of a given node such that the
-// ancestor is also in the set.
-//
-// Given a set of blocks {B1, B2, B3} within the dominator tree, established
-// by stm.Insert()ing B1, B2, B3, etc, a query at block B
-// (performed with stm.Find(stm, B, adjust, helper))
-// will return the member of the set that is the nearest strict
-// ancestor of B within the dominator tree, or nil if none exists.
-// The expected complexity of this operation is the log of the size
-// the set, given certain assumptions about sparsity (the log complexity
-// could be guaranteed with additional data structures whose constant-
-// factor overhead has not yet been justified.)
-//
-// The adjust parameter allows positioning of the insertion
-// and lookup points within a block -- one of
-// AdjustBefore, AdjustWithin, AdjustAfter,
-// where lookups at AdjustWithin can find insertions at
-// AdjustBefore in the same block, and lookups at AdjustAfter
-// can find insertions at either AdjustBefore or AdjustWithin
-// in the same block.  (Note that this assumes a gappy numbering
-// such that exit number or exit number is separated from its
-// nearest neighbor by at least 3).
-//
-// The Sparse Tree lookup algorithm is described by
-// Paul F. Dietz. Maintaining order in a linked list. In
-// Proceedings of the Fourteenth Annual ACM Symposium on
-// Theory of Computing, pages 122–127, May 1982.
-// and by
-// Ben Wegbreit. Faster retrieval from context trees.
-// Communications of the ACM, 19(9):526–529, September 1976.
-type SparseTreeMap RBTint32
-
-// A SparseTreeHelper contains indexing and allocation data
-// structures common to a collection of SparseTreeMaps, as well
-// as exposing some useful control-flow-related data to other
-// packages, such as gc.
-type SparseTreeHelper struct {
-	Sdom   []SparseTreeNode // indexed by block.ID
-	Po     []*Block         // exported data; the blocks, in a post-order
-	Dom    []*Block         // exported data; the dominator of this block.
-	Ponums []int32          // exported data; Po[Ponums[b.ID]] == b; the index of b in Po
-}
-
-// NewSparseTreeHelper returns a SparseTreeHelper for use
-// in the gc package, for example in phi-function placement.
-func NewSparseTreeHelper(f *Func) *SparseTreeHelper {
-	dom := f.Idom()
-	ponums := make([]int32, f.NumBlocks())
-	po := postorderWithNumbering(f, ponums)
-	return makeSparseTreeHelper(newSparseTree(f, dom), dom, po, ponums)
-}
-
-func (h *SparseTreeHelper) NewTree() *SparseTreeMap {
-	return &SparseTreeMap{}
-}
-
-func makeSparseTreeHelper(sdom SparseTree, dom, po []*Block, ponums []int32) *SparseTreeHelper {
-	helper := &SparseTreeHelper{Sdom: []SparseTreeNode(sdom),
-		Dom:    dom,
-		Po:     po,
-		Ponums: ponums,
-	}
-	return helper
-}
-
-// A sparseTreeMapEntry contains the data stored in a binary search
-// data structure indexed by (dominator tree walk) entry and exit numbers.
-// Each entry is added twice, once keyed by entry-1/entry/entry+1 and
-// once keyed by exit+1/exit/exit-1.
-//
-// Within a sparse tree, the two entries added bracket all their descendant
-// entries within the tree; the first insertion is keyed by entry number,
-// which comes before all the entry and exit numbers of descendants, and
-// the second insertion is keyed by exit number, which comes after all the
-// entry and exit numbers of the descendants.
-type sparseTreeMapEntry struct {
-	index        *SparseTreeNode // references the entry and exit numbers for a block in the sparse tree
-	block        *Block          // TODO: store this in a separate index.
-	data         interface{}
-	sparseParent *sparseTreeMapEntry // references the nearest ancestor of this block in the sparse tree.
-	adjust       int32               // at what adjustment was this node entered into the sparse tree? The same block may be entered more than once, but at different adjustments.
-}
-
-// Insert creates a definition within b with data x.
-// adjust indicates where in the block should be inserted:
-// AdjustBefore means defined at a phi function (visible Within or After in the same block)
-// AdjustWithin means defined within the block (visible After in the same block)
-// AdjustAfter means after the block (visible within child blocks)
-func (m *SparseTreeMap) Insert(b *Block, adjust int32, x interface{}, helper *SparseTreeHelper) {
-	rbtree := (*RBTint32)(m)
-	blockIndex := &helper.Sdom[b.ID]
-	if blockIndex.entry == 0 {
-		// assert unreachable
-		return
-	}
-	// sp will be the sparse parent in this sparse tree (nearest ancestor in the larger tree that is also in this sparse tree)
-	sp := m.findEntry(b, adjust, helper)
-	entry := &sparseTreeMapEntry{index: blockIndex, block: b, data: x, sparseParent: sp, adjust: adjust}
-
-	right := blockIndex.exit - adjust
-	_ = rbtree.Insert(right, entry)
-
-	left := blockIndex.entry + adjust
-	_ = rbtree.Insert(left, entry)
-
-	// This newly inserted block may now be the sparse parent of some existing nodes (the new sparse children of this block)
-	// Iterate over nodes bracketed by this new node to correct their parent, but not over the proper sparse descendants of those nodes.
-	_, d := rbtree.Lub(left) // Lub (not EQ) of left is either right or a sparse child
-	for tme := d.(*sparseTreeMapEntry); tme != entry; tme = d.(*sparseTreeMapEntry) {
-		tme.sparseParent = entry
-		// all descendants of tme are unchanged;
-		// next sparse sibling (or right-bracketing sparse parent == entry) is first node after tme.index.exit - tme.adjust
-		_, d = rbtree.Lub(tme.index.exit - tme.adjust)
-	}
-}
-
-// Find returns the definition visible from block b, or nil if none can be found.
-// Adjust indicates where the block should be searched.
-// AdjustBefore searches before the phi functions of b.
-// AdjustWithin searches starting at the phi functions of b.
-// AdjustAfter searches starting at the exit from the block, including normal within-block definitions.
-//
-// Note that Finds are properly nested with Inserts:
-// m.Insert(b, a) followed by m.Find(b, a) will not return the result of the insert,
-// but m.Insert(b, AdjustBefore) followed by m.Find(b, AdjustWithin) will.
-//
-// Another way to think of this is that Find searches for inputs, Insert defines outputs.
-func (m *SparseTreeMap) Find(b *Block, adjust int32, helper *SparseTreeHelper) interface{} {
-	v := m.findEntry(b, adjust, helper)
-	if v == nil {
-		return nil
-	}
-	return v.data
-}
-
-func (m *SparseTreeMap) findEntry(b *Block, adjust int32, helper *SparseTreeHelper) *sparseTreeMapEntry {
-	rbtree := (*RBTint32)(m)
-	if rbtree == nil {
-		return nil
-	}
-	blockIndex := &helper.Sdom[b.ID]
-
-	// The Glb (not EQ) of this probe is either the entry-indexed end of a sparse parent
-	// or the exit-indexed end of a sparse sibling
-	_, v := rbtree.Glb(blockIndex.entry + adjust)
-
-	if v == nil {
-		return nil
-	}
-
-	otherEntry := v.(*sparseTreeMapEntry)
-	if otherEntry.index.exit >= blockIndex.exit { // otherEntry exit after blockIndex exit; therefore, brackets
-		return otherEntry
-	}
-	// otherEntry is a sparse Sibling, and shares the same sparse parent (nearest ancestor within larger tree)
-	sp := otherEntry.sparseParent
-	if sp != nil {
-		if sp.index.exit < blockIndex.exit { // no ancestor found
-			return nil
-		}
-		return sp
-	}
-	return nil
-}
-
-func (m *SparseTreeMap) String() string {
-	tree := (*RBTint32)(m)
-	return tree.String()
-}
-
-func (e *sparseTreeMapEntry) String() string {
-	if e == nil {
-		return "nil"
-	}
-	return fmt.Sprintf("(index=%v, block=%v, data=%v)->%v", e.index, e.block, e.data, e.sparseParent)
-}
diff --git a/src/cmd/compile/internal/ssa/stackalloc.go b/src/cmd/compile/internal/ssa/stackalloc.go
index 406a3c3..d41f399 100644
--- a/src/cmd/compile/internal/ssa/stackalloc.go
+++ b/src/cmd/compile/internal/ssa/stackalloc.go
@@ -7,6 +7,7 @@
 package ssa
 
 import (
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/types"
 	"cmd/internal/src"
 	"fmt"
@@ -111,7 +112,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() && !v.OnWasmStack
-			s.values[v.ID].isArg = v.Op == OpArg
+			s.values[v.ID].isArg = hasAnyArgOp(v)
 			if f.pass.debug > stackDebug && s.values[v.ID].needSlot {
 				fmt.Printf("%s needs a stack slot\n", v)
 			}
@@ -140,27 +141,72 @@
 		s.names = make([]LocalSlot, n)
 	}
 	names := s.names
+	empty := LocalSlot{}
 	for _, name := range f.Names {
 		// Note: not "range f.NamedValues" above, because
 		// that would be nondeterministic.
-		for _, v := range f.NamedValues[name] {
-			names[v.ID] = name
+		for _, v := range f.NamedValues[*name] {
+			if v.Op == OpArgIntReg || v.Op == OpArgFloatReg {
+				aux := v.Aux.(*AuxNameOffset)
+				// Never let an arg be bound to a differently named thing.
+				if name.N != aux.Name || name.Off != aux.Offset {
+					if f.pass.debug > stackDebug {
+						fmt.Printf("stackalloc register arg %s skipping name %s\n", v, name)
+					}
+					continue
+				}
+			} else if name.N.Class == ir.PPARAM && v.Op != OpArg {
+				// PPARAM's only bind to OpArg
+				if f.pass.debug > stackDebug {
+					fmt.Printf("stackalloc PPARAM name %s skipping non-Arg %s\n", name, v)
+				}
+				continue
+			}
+
+			if names[v.ID] == empty {
+				if f.pass.debug > stackDebug {
+					fmt.Printf("stackalloc value %s to name %s\n", v, *name)
+				}
+				names[v.ID] = *name
+			}
 		}
 	}
 
 	// Allocate args to their assigned locations.
 	for _, v := range f.Entry.Values {
-		if v.Op != OpArg {
+		if !hasAnyArgOp(v) {
 			continue
 		}
 		if v.Aux == nil {
 			f.Fatalf("%s has nil Aux\n", v.LongString())
 		}
-		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)
+		if v.Op == OpArg {
+			loc := LocalSlot{N: v.Aux.(*ir.Name), Type: v.Type, Off: v.AuxInt}
+			if f.pass.debug > stackDebug {
+				fmt.Printf("stackalloc OpArg %s to %s\n", v, loc)
+			}
+			f.setHome(v, loc)
+			continue
 		}
-		f.setHome(v, loc)
+		// You might think this below would be the right idea, but you would be wrong.
+		// It almost works; as of 105a6e9518 - 2021-04-23,
+		// GOSSAHASH=11011011001011111 == cmd/compile/internal/noder.(*noder).embedded
+		// is compiled incorrectly.  I believe the cause is one of those SSA-to-registers
+		// puzzles that the register allocator untangles; in the event that a register
+		// parameter does not end up bound to a name, "fixing" it is a bad idea.
+		//
+		//if f.DebugTest {
+		//	if v.Op == OpArgIntReg || v.Op == OpArgFloatReg {
+		//		aux := v.Aux.(*AuxNameOffset)
+		//		loc := LocalSlot{N: aux.Name, Type: v.Type, Off: aux.Offset}
+		//		if f.pass.debug > stackDebug {
+		//			fmt.Printf("stackalloc Op%s %s to %s\n", v.Op, v, loc)
+		//		}
+		//		names[v.ID] = loc
+		//		continue
+		//	}
+		//}
+
 	}
 
 	// For each type, we keep track of all the stack slots we
@@ -197,7 +243,7 @@
 				s.nNotNeed++
 				continue
 			}
-			if v.Op == OpArg {
+			if hasAnyArgOp(v) {
 				s.nArgSlot++
 				continue // already picked
 			}
@@ -384,7 +430,7 @@
 				for _, id := range live.contents() {
 					// 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 {
+					if s.values[v.ID].typ.Compare(s.values[id].typ) == types.CMPeq || hasAnyArgOp(v) || s.values[id].isArg {
 						s.interfere[v.ID] = append(s.interfere[v.ID], id)
 						s.interfere[id] = append(s.interfere[id], v.ID)
 					}
@@ -395,13 +441,15 @@
 					live.add(a.ID)
 				}
 			}
-			if v.Op == OpArg && s.values[v.ID].needSlot {
+			if hasAnyArgOp(v) && s.values[v.ID].needSlot {
 				// OpArg is an input argument which is pre-spilled.
 				// We add back v.ID here because we want this value
 				// to appear live even before this point. Being live
 				// all the way to the start of the entry block prevents other
 				// values from being allocated to the same slot and clobbering
 				// the input value before we have a chance to load it.
+
+				// TODO(register args) this is apparently not wrong for register args -- is it necessary?
 				live.add(v.ID)
 			}
 		}
@@ -418,3 +466,7 @@
 		}
 	}
 }
+
+func hasAnyArgOp(v *Value) bool {
+	return v.Op == OpArg || v.Op == OpArgIntReg || v.Op == OpArgFloatReg
+}
diff --git a/src/cmd/compile/internal/ssa/stmtlines_test.go b/src/cmd/compile/internal/ssa/stmtlines_test.go
index f5ff3a5..a510d0b 100644
--- a/src/cmd/compile/internal/ssa/stmtlines_test.go
+++ b/src/cmd/compile/internal/ssa/stmtlines_test.go
@@ -117,6 +117,7 @@
 	} else if len(nonStmtLines)*100 > 2*len(lines) { // expect 98% elsewhere.
 		t.Errorf("Saw too many (not amd64, > 2%%) lines without statement marks, total=%d, nostmt=%d ('-run TestStmtLines -v' lists failing lines)\n", len(lines), len(nonStmtLines))
 	}
+	t.Logf("Saw %d out of %d lines without statement marks", len(nonStmtLines), len(lines))
 	if testing.Verbose() {
 		sort.Slice(nonStmtLines, func(i, j int) bool {
 			if nonStmtLines[i].File != nonStmtLines[j].File {
diff --git a/src/cmd/compile/internal/ssa/tighten.go b/src/cmd/compile/internal/ssa/tighten.go
index 5dfc453..214bf62 100644
--- a/src/cmd/compile/internal/ssa/tighten.go
+++ b/src/cmd/compile/internal/ssa/tighten.go
@@ -18,10 +18,11 @@
 				continue
 			}
 			switch v.Op {
-			case OpPhi, OpArg, OpSelect0, OpSelect1:
+			case OpPhi, OpArg, OpArgIntReg, OpArgFloatReg, OpSelect0, OpSelect1, OpSelectN:
 				// Phis need to stay in their block.
 				// Arg must stay in the entry block.
 				// Tuple selectors must stay with the tuple generator.
+				// SelectN is typically, ultimately, a register.
 				continue
 			}
 			if v.MemoryArg() != nil {
diff --git a/src/cmd/compile/internal/ssa/tuple.go b/src/cmd/compile/internal/ssa/tuple.go
index 38deabf..289df40 100644
--- a/src/cmd/compile/internal/ssa/tuple.go
+++ b/src/cmd/compile/internal/ssa/tuple.go
@@ -4,8 +4,8 @@
 
 package ssa
 
-// tightenTupleSelectors ensures that tuple selectors (Select0 and
-// Select1 ops) are in the same block as their tuple generator. The
+// tightenTupleSelectors ensures that tuple selectors (Select0, Select1,
+// and SelectN ops) are in the same block as their tuple generator. The
 // function also ensures that there are no duplicate tuple selectors.
 // These properties are expected by the scheduler but may not have
 // been maintained by the optimization pipeline up to this point.
@@ -13,28 +13,40 @@
 // See issues 16741 and 39472.
 func tightenTupleSelectors(f *Func) {
 	selectors := make(map[struct {
-		id ID
-		op Op
+		id    ID
+		which int
 	}]*Value)
 	for _, b := range f.Blocks {
 		for _, selector := range b.Values {
-			if selector.Op != OpSelect0 && selector.Op != OpSelect1 {
+			// Key fields for de-duplication
+			var tuple *Value
+			idx := 0
+			switch selector.Op {
+			default:
 				continue
-			}
-
-			// Get the tuple generator to use as a key for de-duplication.
-			tuple := selector.Args[0]
-			if !tuple.Type.IsTuple() {
-				f.Fatalf("arg of tuple selector %s is not a tuple: %s", selector.String(), tuple.LongString())
+			case OpSelect1:
+				idx = 1
+				fallthrough
+			case OpSelect0:
+				tuple = selector.Args[0]
+				if !tuple.Type.IsTuple() {
+					f.Fatalf("arg of tuple selector %s is not a tuple: %s", selector.String(), tuple.LongString())
+				}
+			case OpSelectN:
+				tuple = selector.Args[0]
+				idx = int(selector.AuxInt)
+				if !tuple.Type.IsResults() {
+					f.Fatalf("arg of result selector %s is not a results: %s", selector.String(), tuple.LongString())
+				}
 			}
 
 			// If there is a pre-existing selector in the target block then
 			// use that. Do this even if the selector is already in the
 			// target block to avoid duplicate tuple selectors.
 			key := struct {
-				id ID
-				op Op
-			}{tuple.ID, selector.Op}
+				id    ID
+				which int
+			}{tuple.ID, idx}
 			if t := selectors[key]; t != nil {
 				if selector != t {
 					selector.copyOf(t)
diff --git a/src/cmd/compile/internal/ssa/value.go b/src/cmd/compile/internal/ssa/value.go
index edc43aa..630e481 100644
--- a/src/cmd/compile/internal/ssa/value.go
+++ b/src/cmd/compile/internal/ssa/value.go
@@ -5,6 +5,7 @@
 package ssa
 
 import (
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/types"
 	"cmd/internal/src"
 	"fmt"
@@ -36,7 +37,7 @@
 	// Users of AuxInt which interpret AuxInt as unsigned (e.g. shifts) must be careful.
 	// Use Value.AuxUnsigned to get the zero-extended value of AuxInt.
 	AuxInt int64
-	Aux    interface{}
+	Aux    Aux
 
 	// Arguments of this value
 	Args []*Value
@@ -77,7 +78,7 @@
 }
 
 func (v *Value) AuxInt8() int8 {
-	if opcodeTable[v.Op].auxType != auxInt8 {
+	if opcodeTable[v.Op].auxType != auxInt8 && opcodeTable[v.Op].auxType != auxNameOffsetInt8 {
 		v.Fatalf("op %s doesn't have an int8 aux field", v.Op)
 	}
 	return int8(v.AuxInt)
@@ -138,6 +139,9 @@
 
 // long form print.  v# = opcode <type> [aux] args [: reg] (names)
 func (v *Value) LongString() string {
+	if v == nil {
+		return "<NIL VALUE>"
+	}
 	s := fmt.Sprintf("v%d = %s", v.ID, v.Op)
 	s += " <" + v.Type.String() + ">"
 	s += v.auxString()
@@ -197,12 +201,12 @@
 		if v.Aux != nil {
 			return fmt.Sprintf(" {%v}", v.Aux)
 		}
-	case auxSymOff, auxCallOff, auxTypSize:
+	case auxSymOff, auxCallOff, auxTypSize, auxNameOffsetInt8:
 		s := ""
 		if v.Aux != nil {
 			s = fmt.Sprintf(" {%v}", v.Aux)
 		}
-		if v.AuxInt != 0 {
+		if v.AuxInt != 0 || opcodeTable[v.Op].auxType == auxNameOffsetInt8 {
 			s += fmt.Sprintf(" [%v]", v.AuxInt)
 		}
 		return s
@@ -344,6 +348,35 @@
 	v.Aux = nil
 }
 
+// invalidateRecursively marks a value as invalid (unused)
+// and after decrementing reference counts on its Args,
+// also recursively invalidates any of those whose use
+// count goes to zero.
+//
+// BEWARE of doing this *before* you've applied intended
+// updates to SSA.
+func (v *Value) invalidateRecursively() {
+	if v.InCache {
+		v.Block.Func.unCache(v)
+	}
+	v.Op = OpInvalid
+
+	for _, a := range v.Args {
+		a.Uses--
+		if a.Uses == 0 {
+			a.invalidateRecursively()
+		}
+	}
+
+	v.argstorage[0] = nil
+	v.argstorage[1] = nil
+	v.argstorage[2] = nil
+	v.Args = v.argstorage[:0]
+
+	v.AuxInt = 0
+	v.Aux = nil
+}
+
 // copyOf is called from rewrite rules.
 // It modifies v to be (Copy a).
 //go:noinline
@@ -410,6 +443,23 @@
 	return v != nil && (v.Op == OpConst64 || v.Op == OpConst32 || v.Op == OpConst16 || v.Op == OpConst8)
 }
 
+// ResultReg returns the result register assigned to v, in cmd/internal/obj/$ARCH numbering.
+// It is similar to Reg and Reg0, except that it is usable interchangeably for all Value Ops.
+// If you know v.Op, using Reg or Reg0 (as appropriate) will be more efficient.
+func (v *Value) ResultReg() int16 {
+	reg := v.Block.Func.RegAlloc[v.ID]
+	if reg == nil {
+		v.Fatalf("nil reg for value: %s\n%s\n", v.LongString(), v.Block.Func)
+	}
+	if pair, ok := reg.(LocPair); ok {
+		reg = pair[0]
+	}
+	if reg == nil {
+		v.Fatalf("nil reg0 for value: %s\n%s\n", v.LongString(), v.Block.Func)
+	}
+	return reg.(*Register).objNum
+}
+
 // 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]
@@ -481,9 +531,9 @@
 		return false
 	}
 	if v.Type.IsMemory() {
-		// All memory ops aren't needed here, but we do need
+		// We don't need to preserve all memory ops, but we do need
 		// to keep calls at least (because they might have
-		// syncronization operations we can't see).
+		// synchronization operations we can't see).
 		return false
 	}
 	if v.Op.HasSideEffects() {
@@ -492,3 +542,20 @@
 	}
 	return true
 }
+
+// TODO(mdempsky): Shouldn't be necessary; see discussion at golang.org/cl/275756
+func (*Value) CanBeAnSSAAux() {}
+
+// AutoVar returns a *Name and int64 representing the auto variable and offset within it
+// where v should be spilled.
+func AutoVar(v *Value) (*ir.Name, int64) {
+	if loc, ok := v.Block.Func.RegAlloc[v.ID].(LocalSlot); ok {
+		if v.Type.Size() > loc.Type.Size() {
+			v.Fatalf("spill/restore type %s doesn't fit in slot type %s", v.Type, loc.Type)
+		}
+		return loc.N, loc.Off
+	}
+	// Assume it is a register, return its spill slot, which needs to be live
+	nameOff := v.Aux.(*AuxNameOffset)
+	return nameOff.Name, nameOff.Offset
+}
diff --git a/src/cmd/compile/internal/ssa/writebarrier.go b/src/cmd/compile/internal/ssa/writebarrier.go
index 849c9e8..419d91d 100644
--- a/src/cmd/compile/internal/ssa/writebarrier.go
+++ b/src/cmd/compile/internal/ssa/writebarrier.go
@@ -5,6 +5,7 @@
 package ssa
 
 import (
+	"cmd/compile/internal/reflectdata"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/objabi"
@@ -37,9 +38,11 @@
 	if IsStackAddr(v.Args[0]) {
 		return false // write on stack doesn't need write barrier
 	}
-	if v.Op == OpMove && IsReadOnlyGlobalAddr(v.Args[1]) && IsNewObject(v.Args[0], v.MemoryArg()) {
-		// Copying data from readonly memory into a fresh object doesn't need a write barrier.
-		return false
+	if v.Op == OpMove && IsReadOnlyGlobalAddr(v.Args[1]) {
+		if mem, ok := IsNewObject(v.Args[0]); ok && mem == v.MemoryArg() {
+			// Copying data from readonly memory into a fresh object doesn't need a write barrier.
+			return false
+		}
 	}
 	if v.Op == OpStore && IsGlobalAddr(v.Args[1]) {
 		// Storing pointers to non-heap locations into zeroed memory doesn't need a write barrier.
@@ -270,11 +273,11 @@
 			case OpMoveWB:
 				fn = typedmemmove
 				val = w.Args[1]
-				typ = w.Aux.(*types.Type).Symbol()
+				typ = reflectdata.TypeLinksym(w.Aux.(*types.Type))
 				nWBops--
 			case OpZeroWB:
 				fn = typedmemclr
-				typ = w.Aux.(*types.Type).Symbol()
+				typ = reflectdata.TypeLinksym(w.Aux.(*types.Type))
 				nWBops--
 			case OpVarDef, OpVarLive, OpVarKill:
 			}
@@ -388,11 +391,7 @@
 	// Find new objects.
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
-			if v.Op != OpLoad {
-				continue
-			}
-			mem := v.MemoryArg()
-			if IsNewObject(v, mem) {
+			if mem, ok := IsNewObject(v); ok {
 				nptr := v.Type.Elem().Size() / ptrSize
 				if nptr > 64 {
 					nptr = 64
@@ -482,38 +481,56 @@
 func wbcall(pos src.XPos, b *Block, fn, typ *obj.LSym, ptr, val, mem, sp, sb *Value) *Value {
 	config := b.Func.Config
 
+	var wbargs []*Value
+	// TODO (register args) this is a bit of a hack.
+	inRegs := b.Func.ABIDefault == b.Func.ABI1 && len(config.intParamRegs) >= 3
+
 	// put arguments on stack
 	off := config.ctxt.FixedFrameSize()
 
-	var ACArgs []Param
+	var argTypes []*types.Type
 	if typ != nil { // for typedmemmove
 		taddr := b.NewValue1A(pos, OpAddr, b.Func.Config.Types.Uintptr, typ, sb)
+		argTypes = append(argTypes, b.Func.Config.Types.Uintptr)
 		off = round(off, taddr.Type.Alignment())
-		arg := b.NewValue1I(pos, OpOffPtr, taddr.Type.PtrTo(), off, sp)
-		mem = b.NewValue3A(pos, OpStore, types.TypeMem, ptr.Type, arg, taddr, mem)
-		ACArgs = append(ACArgs, Param{Type: b.Func.Config.Types.Uintptr, Offset: int32(off)})
+		if inRegs {
+			wbargs = append(wbargs, taddr)
+		} else {
+			arg := b.NewValue1I(pos, OpOffPtr, taddr.Type.PtrTo(), off, sp)
+			mem = b.NewValue3A(pos, OpStore, types.TypeMem, ptr.Type, arg, taddr, mem)
+		}
 		off += taddr.Type.Size()
 	}
 
+	argTypes = append(argTypes, ptr.Type)
 	off = round(off, ptr.Type.Alignment())
-	arg := b.NewValue1I(pos, OpOffPtr, ptr.Type.PtrTo(), off, sp)
-	mem = b.NewValue3A(pos, OpStore, types.TypeMem, ptr.Type, arg, ptr, mem)
-	ACArgs = append(ACArgs, Param{Type: ptr.Type, Offset: int32(off)})
+	if inRegs {
+		wbargs = append(wbargs, ptr)
+	} else {
+		arg := b.NewValue1I(pos, OpOffPtr, ptr.Type.PtrTo(), off, sp)
+		mem = b.NewValue3A(pos, OpStore, types.TypeMem, ptr.Type, arg, ptr, mem)
+	}
 	off += ptr.Type.Size()
 
 	if val != nil {
+		argTypes = append(argTypes, val.Type)
 		off = round(off, val.Type.Alignment())
-		arg = b.NewValue1I(pos, OpOffPtr, val.Type.PtrTo(), off, sp)
-		mem = b.NewValue3A(pos, OpStore, types.TypeMem, val.Type, arg, val, mem)
-		ACArgs = append(ACArgs, Param{Type: val.Type, Offset: int32(off)})
+		if inRegs {
+			wbargs = append(wbargs, val)
+		} else {
+			arg := b.NewValue1I(pos, OpOffPtr, val.Type.PtrTo(), off, sp)
+			mem = b.NewValue3A(pos, OpStore, types.TypeMem, val.Type, arg, val, mem)
+		}
 		off += val.Type.Size()
 	}
 	off = round(off, config.PtrSize)
+	wbargs = append(wbargs, mem)
 
 	// issue call
-	mem = b.NewValue1A(pos, OpStaticCall, types.TypeMem, StaticAuxCall(fn, ACArgs, nil), mem)
-	mem.AuxInt = off - config.ctxt.FixedFrameSize()
-	return mem
+	call := b.NewValue0A(pos, OpStaticCall, types.TypeResultMem, StaticAuxCall(fn, b.Func.ABIDefault.ABIAnalyzeTypes(nil, argTypes, nil)))
+	call.AddArgs(wbargs...)
+	call.AuxInt = off - config.ctxt.FixedFrameSize()
+	return b.NewValue1I(pos, OpSelectN, types.TypeMem, 0, call)
 }
 
 // round to a multiple of r, r is a power of 2
@@ -559,31 +576,60 @@
 	return false
 }
 
-// IsNewObject reports whether v is a pointer to a freshly allocated & zeroed object at memory state mem.
-func IsNewObject(v *Value, mem *Value) bool {
-	if v.Op != OpLoad {
-		return false
+// IsNewObject reports whether v is a pointer to a freshly allocated & zeroed object,
+// if so, also returns the memory state mem at which v is zero.
+func IsNewObject(v *Value) (mem *Value, ok bool) {
+	f := v.Block.Func
+	c := f.Config
+	if f.ABIDefault == f.ABI1 && len(c.intParamRegs) >= 1 {
+		if v.Op != OpSelectN || v.AuxInt != 0 {
+			return nil, false
+		}
+		// Find the memory
+		for _, w := range v.Block.Values {
+			if w.Op == OpSelectN && w.AuxInt == 1 && w.Args[0] == v.Args[0] {
+				mem = w
+				break
+			}
+		}
+		if mem == nil {
+			return nil, false
+		}
+	} else {
+		if v.Op != OpLoad {
+			return nil, false
+		}
+		mem = v.MemoryArg()
+		if mem.Op != OpSelectN {
+			return nil, false
+		}
+		if mem.Type != types.TypeMem {
+			return nil, false
+		} // assume it is the right selection if true
 	}
-	if v.MemoryArg() != mem {
-		return false
+	call := mem.Args[0]
+	if call.Op != OpStaticCall {
+		return nil, false
 	}
-	if mem.Op != OpStaticCall {
-		return false
+	if !isSameCall(call.Aux, "runtime.newobject") {
+		return nil, false
 	}
-	if !isSameCall(mem.Aux, "runtime.newobject") {
-		return false
+	if f.ABIDefault == f.ABI1 && len(c.intParamRegs) >= 1 {
+		if v.Args[0] == call {
+			return mem, true
+		}
+		return nil, false
 	}
 	if v.Args[0].Op != OpOffPtr {
-		return false
+		return nil, false
 	}
 	if v.Args[0].Args[0].Op != OpSP {
-		return false
+		return nil, false
 	}
-	c := v.Block.Func.Config
 	if v.Args[0].AuxInt != c.ctxt.FixedFrameSize()+c.RegSize { // offset of return value
-		return false
+		return nil, false
 	}
-	return true
+	return mem, true
 }
 
 // IsSanitizerSafeAddr reports whether v is known to be an address
diff --git a/src/cmd/compile/internal/ssa/zcse.go b/src/cmd/compile/internal/ssa/zcse.go
index ec38b7d..e08272c 100644
--- a/src/cmd/compile/internal/ssa/zcse.go
+++ b/src/cmd/compile/internal/ssa/zcse.go
@@ -57,7 +57,7 @@
 type vkey struct {
 	op Op
 	ai int64       // aux int
-	ax interface{} // aux
+	ax Aux         // aux
 	t  *types.Type // type
 }
 
diff --git a/src/cmd/compile/internal/ssagen/abi.go b/src/cmd/compile/internal/ssagen/abi.go
new file mode 100644
index 0000000..e460ada
--- /dev/null
+++ b/src/cmd/compile/internal/ssagen/abi.go
@@ -0,0 +1,456 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssagen
+
+import (
+	"fmt"
+	"internal/buildcfg"
+	"io/ioutil"
+	"log"
+	"os"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/staticdata"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/objabi"
+)
+
+// SymABIs records information provided by the assembler about symbol
+// definition ABIs and reference ABIs.
+type SymABIs struct {
+	defs map[string]obj.ABI
+	refs map[string]obj.ABISet
+
+	localPrefix string
+}
+
+func NewSymABIs(myimportpath string) *SymABIs {
+	var localPrefix string
+	if myimportpath != "" {
+		localPrefix = objabi.PathToPrefix(myimportpath) + "."
+	}
+
+	return &SymABIs{
+		defs:        make(map[string]obj.ABI),
+		refs:        make(map[string]obj.ABISet),
+		localPrefix: localPrefix,
+	}
+}
+
+// canonicalize returns the canonical name used for a linker symbol in
+// s's maps. Symbols in this package may be written either as "".X or
+// with the package's import path already in the symbol. This rewrites
+// both to `"".`, which matches compiler-generated linker symbol names.
+func (s *SymABIs) canonicalize(linksym string) string {
+	// If the symbol is already prefixed with localPrefix,
+	// rewrite it to start with "" so it matches the
+	// compiler's internal symbol names.
+	if s.localPrefix != "" && strings.HasPrefix(linksym, s.localPrefix) {
+		return `"".` + linksym[len(s.localPrefix):]
+	}
+	return linksym
+}
+
+// ReadSymABIs reads a symabis file that specifies definitions and
+// references of text symbols by ABI.
+//
+// The symabis format is a set of lines, where each line is a sequence
+// of whitespace-separated fields. The first field is a verb and is
+// either "def" for defining a symbol ABI or "ref" for referencing a
+// symbol using an ABI. For both "def" and "ref", the second field is
+// the symbol name and the third field is the ABI name, as one of the
+// named cmd/internal/obj.ABI constants.
+func (s *SymABIs) ReadSymABIs(file string) {
+	data, err := ioutil.ReadFile(file)
+	if err != nil {
+		log.Fatalf("-symabis: %v", err)
+	}
+
+	for lineNum, line := range strings.Split(string(data), "\n") {
+		lineNum++ // 1-based
+		line = strings.TrimSpace(line)
+		if line == "" || strings.HasPrefix(line, "#") {
+			continue
+		}
+
+		parts := strings.Fields(line)
+		switch parts[0] {
+		case "def", "ref":
+			// Parse line.
+			if len(parts) != 3 {
+				log.Fatalf(`%s:%d: invalid symabi: syntax is "%s sym abi"`, file, lineNum, parts[0])
+			}
+			sym, abistr := parts[1], parts[2]
+			abi, valid := obj.ParseABI(abistr)
+			if !valid {
+				log.Fatalf(`%s:%d: invalid symabi: unknown abi "%s"`, file, lineNum, abistr)
+			}
+
+			sym = s.canonicalize(sym)
+
+			// Record for later.
+			if parts[0] == "def" {
+				s.defs[sym] = abi
+			} else {
+				s.refs[sym] |= obj.ABISetOf(abi)
+			}
+		default:
+			log.Fatalf(`%s:%d: invalid symabi type "%s"`, file, lineNum, parts[0])
+		}
+	}
+}
+
+// GenABIWrappers applies ABI information to Funcs and generates ABI
+// wrapper functions where necessary.
+func (s *SymABIs) GenABIWrappers() {
+	// For cgo exported symbols, we tell the linker to export the
+	// definition ABI to C. That also means that we don't want to
+	// create ABI wrappers even if there's a linkname.
+	//
+	// TODO(austin): Maybe we want to create the ABI wrappers, but
+	// ensure the linker exports the right ABI definition under
+	// the unmangled name?
+	cgoExports := make(map[string][]*[]string)
+	for i, prag := range typecheck.Target.CgoPragmas {
+		switch prag[0] {
+		case "cgo_export_static", "cgo_export_dynamic":
+			symName := s.canonicalize(prag[1])
+			pprag := &typecheck.Target.CgoPragmas[i]
+			cgoExports[symName] = append(cgoExports[symName], pprag)
+		}
+	}
+
+	// Apply ABI defs and refs to Funcs and generate wrappers.
+	//
+	// This may generate new decls for the wrappers, but we
+	// specifically *don't* want to visit those, lest we create
+	// wrappers for wrappers.
+	for _, fn := range typecheck.Target.Decls {
+		if fn.Op() != ir.ODCLFUNC {
+			continue
+		}
+		fn := fn.(*ir.Func)
+		nam := fn.Nname
+		if ir.IsBlank(nam) {
+			continue
+		}
+		sym := nam.Sym()
+		var symName string
+		if sym.Linkname != "" {
+			symName = s.canonicalize(sym.Linkname)
+		} else {
+			// These names will already be canonical.
+			symName = sym.Pkg.Prefix + "." + sym.Name
+		}
+
+		// Apply definitions.
+		defABI, hasDefABI := s.defs[symName]
+		if hasDefABI {
+			fn.ABI = defABI
+		}
+
+		if fn.Pragma&ir.CgoUnsafeArgs != 0 {
+			// CgoUnsafeArgs indicates the function (or its callee) uses
+			// offsets to dispatch arguments, which currently using ABI0
+			// frame layout. Pin it to ABI0.
+			fn.ABI = obj.ABI0
+		}
+
+		// If cgo-exported, add the definition ABI to the cgo
+		// pragmas.
+		cgoExport := cgoExports[symName]
+		for _, pprag := range cgoExport {
+			// The export pragmas have the form:
+			//
+			//   cgo_export_* <local> [<remote>]
+			//
+			// If <remote> is omitted, it's the same as
+			// <local>.
+			//
+			// Expand to
+			//
+			//   cgo_export_* <local> <remote> <ABI>
+			if len(*pprag) == 2 {
+				*pprag = append(*pprag, (*pprag)[1])
+			}
+			// Add the ABI argument.
+			*pprag = append(*pprag, fn.ABI.String())
+		}
+
+		// Apply references.
+		if abis, ok := s.refs[symName]; ok {
+			fn.ABIRefs |= abis
+		}
+		// Assume all functions are referenced at least as
+		// ABIInternal, since they may be referenced from
+		// other packages.
+		fn.ABIRefs.Set(obj.ABIInternal, true)
+
+		// If a symbol is defined in this package (either in
+		// Go or assembly) and given a linkname, it may be
+		// referenced from another package, so make it
+		// callable via any ABI. It's important that we know
+		// it's defined in this package since other packages
+		// may "pull" symbols using linkname and we don't want
+		// to create duplicate ABI wrappers.
+		//
+		// However, if it's given a linkname for exporting to
+		// C, then we don't make ABI wrappers because the cgo
+		// tool wants the original definition.
+		hasBody := len(fn.Body) != 0
+		if sym.Linkname != "" && (hasBody || hasDefABI) && len(cgoExport) == 0 {
+			fn.ABIRefs |= obj.ABISetCallable
+		}
+
+		// Double check that cgo-exported symbols don't get
+		// any wrappers.
+		if len(cgoExport) > 0 && fn.ABIRefs&^obj.ABISetOf(fn.ABI) != 0 {
+			base.Fatalf("cgo exported function %s cannot have ABI wrappers", fn)
+		}
+
+		if !buildcfg.Experiment.RegabiWrappers {
+			// We'll generate ABI aliases instead of
+			// wrappers once we have LSyms in InitLSym.
+			continue
+		}
+
+		forEachWrapperABI(fn, makeABIWrapper)
+	}
+}
+
+// InitLSym defines f's obj.LSym and initializes it based on the
+// properties of f. This includes setting the symbol flags and ABI and
+// creating and initializing related DWARF symbols.
+//
+// InitLSym must be called exactly once per function and must be
+// called for both functions with bodies and functions without bodies.
+// For body-less functions, we only create the LSym; for functions
+// with bodies call a helper to setup up / populate the LSym.
+func InitLSym(f *ir.Func, hasBody bool) {
+	if f.LSym != nil {
+		base.FatalfAt(f.Pos(), "InitLSym called twice on %v", f)
+	}
+
+	if nam := f.Nname; !ir.IsBlank(nam) {
+		f.LSym = nam.LinksymABI(f.ABI)
+		if f.Pragma&ir.Systemstack != 0 {
+			f.LSym.Set(obj.AttrCFunc, true)
+		}
+		if f.ABI == obj.ABIInternal || !buildcfg.Experiment.RegabiWrappers {
+			// Function values can only point to
+			// ABIInternal entry points. This will create
+			// the funcsym for either the defining
+			// function or its wrapper as appropriate.
+			//
+			// If we're using ABI aliases instead of
+			// wrappers, we only InitLSym for the defining
+			// ABI of a function, so we make the funcsym
+			// when we see that.
+			staticdata.NeedFuncSym(f)
+		}
+		if !buildcfg.Experiment.RegabiWrappers {
+			// Create ABI aliases instead of wrappers.
+			forEachWrapperABI(f, makeABIAlias)
+		}
+	}
+	if hasBody {
+		setupTextLSym(f, 0)
+	}
+}
+
+func forEachWrapperABI(fn *ir.Func, cb func(fn *ir.Func, wrapperABI obj.ABI)) {
+	need := fn.ABIRefs &^ obj.ABISetOf(fn.ABI)
+	if need == 0 {
+		return
+	}
+
+	for wrapperABI := obj.ABI(0); wrapperABI < obj.ABICount; wrapperABI++ {
+		if !need.Get(wrapperABI) {
+			continue
+		}
+		cb(fn, wrapperABI)
+	}
+}
+
+// makeABIAlias creates a new ABI alias so calls to f via wrapperABI
+// will be resolved directly to f's ABI by the linker.
+func makeABIAlias(f *ir.Func, wrapperABI obj.ABI) {
+	// These LSyms have the same name as the native function, so
+	// we create them directly rather than looking them up.
+	// The uniqueness of f.lsym ensures uniqueness of asym.
+	asym := &obj.LSym{
+		Name: f.LSym.Name,
+		Type: objabi.SABIALIAS,
+		R:    []obj.Reloc{{Sym: f.LSym}}, // 0 size, so "informational"
+	}
+	asym.SetABI(wrapperABI)
+	asym.Set(obj.AttrDuplicateOK, true)
+	base.Ctxt.ABIAliases = append(base.Ctxt.ABIAliases, asym)
+}
+
+// makeABIWrapper creates a new function that will be called with
+// wrapperABI and calls "f" using f.ABI.
+func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) {
+	if base.Debug.ABIWrap != 0 {
+		fmt.Fprintf(os.Stderr, "=-= %v to %v wrapper for %v\n", wrapperABI, f.ABI, f)
+	}
+
+	// Q: is this needed?
+	savepos := base.Pos
+	savedclcontext := typecheck.DeclContext
+	savedcurfn := ir.CurFunc
+
+	base.Pos = base.AutogeneratedPos
+	typecheck.DeclContext = ir.PEXTERN
+
+	// At the moment we don't support wrapping a method, we'd need machinery
+	// below to handle the receiver. Panic if we see this scenario.
+	ft := f.Nname.Type()
+	if ft.NumRecvs() != 0 {
+		panic("makeABIWrapper support for wrapping methods not implemented")
+	}
+
+	// Manufacture a new func type to use for the wrapper.
+	var noReceiver *ir.Field
+	tfn := ir.NewFuncType(base.Pos,
+		noReceiver,
+		typecheck.NewFuncParams(ft.Params(), true),
+		typecheck.NewFuncParams(ft.Results(), false))
+
+	// Reuse f's types.Sym to create a new ODCLFUNC/function.
+	fn := typecheck.DeclFunc(f.Nname.Sym(), tfn)
+	fn.ABI = wrapperABI
+
+	fn.SetABIWrapper(true)
+	fn.SetDupok(true)
+
+	// ABI0-to-ABIInternal wrappers will be mainly loading params from
+	// stack into registers (and/or storing stack locations back to
+	// registers after the wrapped call); in most cases they won't
+	// need to allocate stack space, so it should be OK to mark them
+	// as NOSPLIT in these cases. In addition, my assumption is that
+	// functions written in assembly are NOSPLIT in most (but not all)
+	// cases. In the case of an ABIInternal target that has too many
+	// parameters to fit into registers, the wrapper would need to
+	// allocate stack space, but this seems like an unlikely scenario.
+	// Hence: mark these wrappers NOSPLIT.
+	//
+	// ABIInternal-to-ABI0 wrappers on the other hand will be taking
+	// things in registers and pushing them onto the stack prior to
+	// the ABI0 call, meaning that they will always need to allocate
+	// stack space. If the compiler marks them as NOSPLIT this seems
+	// as though it could lead to situations where the linker's
+	// nosplit-overflow analysis would trigger a link failure. On the
+	// other hand if they not tagged NOSPLIT then this could cause
+	// problems when building the runtime (since there may be calls to
+	// asm routine in cases where it's not safe to grow the stack). In
+	// most cases the wrapper would be (in effect) inlined, but are
+	// there (perhaps) indirect calls from the runtime that could run
+	// into trouble here.
+	// FIXME: at the moment all.bash does not pass when I leave out
+	// NOSPLIT for these wrappers, so all are currently tagged with NOSPLIT.
+	fn.Pragma |= ir.Nosplit
+
+	// Generate call. Use tail call if no params and no returns,
+	// but a regular call otherwise.
+	//
+	// Note: ideally we would be using a tail call in cases where
+	// there are params but no returns for ABI0->ABIInternal wrappers,
+	// provided that all params fit into registers (e.g. we don't have
+	// to allocate any stack space). Doing this will require some
+	// extra work in typecheck/walk/ssa, might want to add a new node
+	// OTAILCALL or something to this effect.
+	tailcall := tfn.Type().NumResults() == 0 && tfn.Type().NumParams() == 0 && tfn.Type().NumRecvs() == 0
+	if base.Ctxt.Arch.Name == "ppc64le" && base.Ctxt.Flag_dynlink {
+		// cannot tailcall on PPC64 with dynamic linking, as we need
+		// to restore R2 after call.
+		tailcall = false
+	}
+	if base.Ctxt.Arch.Name == "amd64" && wrapperABI == obj.ABIInternal {
+		// cannot tailcall from ABIInternal to ABI0 on AMD64, as we need
+		// to special registers (X15) when returning to ABIInternal.
+		tailcall = false
+	}
+
+	var tail ir.Node
+	if tailcall {
+		tail = ir.NewTailCallStmt(base.Pos, f.Nname)
+	} else {
+		call := ir.NewCallExpr(base.Pos, ir.OCALL, f.Nname, nil)
+		call.Args = ir.ParamNames(tfn.Type())
+		call.IsDDD = tfn.Type().IsVariadic()
+		tail = call
+		if tfn.Type().NumResults() > 0 {
+			n := ir.NewReturnStmt(base.Pos, nil)
+			n.Results = []ir.Node{call}
+			tail = n
+		}
+	}
+	fn.Body.Append(tail)
+
+	typecheck.FinishFuncBody()
+	if base.Debug.DclStack != 0 {
+		types.CheckDclstack()
+	}
+
+	typecheck.Func(fn)
+	ir.CurFunc = fn
+	typecheck.Stmts(fn.Body)
+
+	typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
+
+	// Restore previous context.
+	base.Pos = savepos
+	typecheck.DeclContext = savedclcontext
+	ir.CurFunc = savedcurfn
+}
+
+// setupTextLsym initializes the LSym for a with-body text symbol.
+func setupTextLSym(f *ir.Func, flag int) {
+	if f.Dupok() {
+		flag |= obj.DUPOK
+	}
+	if f.Wrapper() {
+		flag |= obj.WRAPPER
+	}
+	if f.ABIWrapper() {
+		flag |= obj.ABIWRAPPER
+	}
+	if f.Needctxt() {
+		flag |= obj.NEEDCTXT
+	}
+	if f.Pragma&ir.Nosplit != 0 {
+		flag |= obj.NOSPLIT
+	}
+	if f.ReflectMethod() {
+		flag |= obj.REFLECTMETHOD
+	}
+
+	// Clumsy but important.
+	// For functions that could be on the path of invoking a deferred
+	// function that can recover (runtime.reflectcall, reflect.callReflect,
+	// and reflect.callMethod), we want the panic+recover special handling.
+	// See test/recover.go for test cases and src/reflect/value.go
+	// for the actual functions being considered.
+	//
+	// runtime.reflectcall is an assembly function which tailcalls
+	// WRAPPER functions (runtime.callNN). Its ABI wrapper needs WRAPPER
+	// flag as well.
+	fnname := f.Sym().Name
+	if base.Ctxt.Pkgpath == "runtime" && fnname == "reflectcall" {
+		flag |= obj.WRAPPER
+	} else if base.Ctxt.Pkgpath == "reflect" {
+		switch fnname {
+		case "callReflect", "callMethod":
+			flag |= obj.WRAPPER
+		}
+	}
+
+	base.Ctxt.InitTextSym(f.LSym, flag)
+}
diff --git a/src/cmd/compile/internal/ssagen/arch.go b/src/cmd/compile/internal/ssagen/arch.go
new file mode 100644
index 0000000..7215f42
--- /dev/null
+++ b/src/cmd/compile/internal/ssagen/arch.go
@@ -0,0 +1,52 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssagen
+
+import (
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+)
+
+var Arch ArchInfo
+
+// interface to back end
+
+type ArchInfo struct {
+	LinkArch *obj.LinkArch
+
+	REGSP     int
+	MAXWIDTH  int64
+	SoftFloat bool
+
+	PadFrame func(int64) int64
+
+	// ZeroRange zeroes a range of memory on stack. It is only inserted
+	// at function entry, and it is ok to clobber registers.
+	ZeroRange func(*objw.Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog
+
+	Ginsnop      func(*objw.Progs) *obj.Prog
+	Ginsnopdefer func(*objw.Progs) *obj.Prog // special ginsnop for deferreturn
+
+	// SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
+	SSAMarkMoves func(*State, *ssa.Block)
+
+	// SSAGenValue emits Prog(s) for the Value.
+	SSAGenValue func(*State, *ssa.Value)
+
+	// SSAGenBlock emits end-of-block Progs. SSAGenValue should be called
+	// for all values in the block before SSAGenBlock.
+	SSAGenBlock func(s *State, b, next *ssa.Block)
+
+	// LoadRegResults emits instructions that loads register-assigned results
+	// into registers. They are already in memory (PPARAMOUT nodes).
+	// Used in open-coded defer return path.
+	LoadRegResults func(s *State, f *ssa.Func)
+
+	// SpillArgReg emits instructions that spill reg to n+off.
+	SpillArgReg func(pp *objw.Progs, p *obj.Prog, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog
+}
diff --git a/src/cmd/compile/internal/ssagen/nowb.go b/src/cmd/compile/internal/ssagen/nowb.go
new file mode 100644
index 0000000..1fbc6a8
--- /dev/null
+++ b/src/cmd/compile/internal/ssagen/nowb.go
@@ -0,0 +1,206 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssagen
+
+import (
+	"bytes"
+	"fmt"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/src"
+)
+
+func EnableNoWriteBarrierRecCheck() {
+	nowritebarrierrecCheck = newNowritebarrierrecChecker()
+}
+
+func NoWriteBarrierRecCheck() {
+	// Write barriers are now known. Check the
+	// call graph.
+	nowritebarrierrecCheck.check()
+	nowritebarrierrecCheck = nil
+}
+
+var nowritebarrierrecCheck *nowritebarrierrecChecker
+
+type nowritebarrierrecChecker struct {
+	// 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[*ir.Func][]nowritebarrierrecCall
+
+	// curfn is the current function during AST walks.
+	curfn *ir.Func
+}
+
+type nowritebarrierrecCall struct {
+	target *ir.Func // caller or callee
+	lineno src.XPos // line of call
+}
+
+// newNowritebarrierrecChecker creates a nowritebarrierrecChecker. It
+// must be called before walk
+func newNowritebarrierrecChecker() *nowritebarrierrecChecker {
+	c := &nowritebarrierrecChecker{
+		extraCalls: make(map[*ir.Func][]nowritebarrierrecCall),
+	}
+
+	// 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 transforming closures in walk since
+	// it's a lot harder to work out the argument after.
+	for _, n := range typecheck.Target.Decls {
+		if n.Op() != ir.ODCLFUNC {
+			continue
+		}
+		c.curfn = n.(*ir.Func)
+		if c.curfn.ABIWrapper() {
+			// We only want "real" calls to these
+			// functions, not the generated ones within
+			// their own ABI wrappers.
+			continue
+		}
+		ir.Visit(n, c.findExtraCalls)
+	}
+	c.curfn = nil
+	return c
+}
+
+func (c *nowritebarrierrecChecker) findExtraCalls(nn ir.Node) {
+	if nn.Op() != ir.OCALLFUNC {
+		return
+	}
+	n := nn.(*ir.CallExpr)
+	if n.X == nil || n.X.Op() != ir.ONAME {
+		return
+	}
+	fn := n.X.(*ir.Name)
+	if fn.Class != ir.PFUNC || fn.Defn == nil {
+		return
+	}
+	if !types.IsRuntimePkg(fn.Sym().Pkg) || fn.Sym().Name != "systemstack" {
+		return
+	}
+
+	var callee *ir.Func
+	arg := n.Args[0]
+	switch arg.Op() {
+	case ir.ONAME:
+		arg := arg.(*ir.Name)
+		callee = arg.Defn.(*ir.Func)
+	case ir.OCLOSURE:
+		arg := arg.(*ir.ClosureExpr)
+		callee = arg.Func
+	default:
+		base.Fatalf("expected ONAME or OCLOSURE node, got %+v", arg)
+	}
+	if callee.Op() != ir.ODCLFUNC {
+		base.Fatalf("expected ODCLFUNC node, got %+v", callee)
+	}
+	c.extraCalls[c.curfn] = append(c.extraCalls[c.curfn], nowritebarrierrecCall{callee, n.Pos()})
+}
+
+// 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(fn *ir.Func, to *obj.LSym, pos src.XPos) {
+	// We record this information on the *Func so this is concurrent-safe.
+	if fn.NWBRCalls == nil {
+		fn.NWBRCalls = new([]ir.SymAndPos)
+	}
+	*fn.NWBRCalls = append(*fn.NWBRCalls, ir.SymAndPos{Sym: to, Pos: 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]*ir.Func)
+	// 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[*ir.Func]nowritebarrierrecCall)
+	// q is the queue of ODCLFUNC Nodes to visit in BFS order.
+	var q ir.NameQueue
+
+	for _, n := range typecheck.Target.Decls {
+		if n.Op() != ir.ODCLFUNC {
+			continue
+		}
+		fn := n.(*ir.Func)
+
+		symToFunc[fn.LSym] = fn
+
+		// Make nowritebarrierrec functions BFS roots.
+		if fn.Pragma&ir.Nowritebarrierrec != 0 {
+			funcs[fn] = nowritebarrierrecCall{}
+			q.PushRight(fn.Nname)
+		}
+		// Check go:nowritebarrier functions.
+		if fn.Pragma&ir.Nowritebarrier != 0 && fn.WBPos.IsKnown() {
+			base.ErrorfAt(fn.WBPos, "write barrier prohibited")
+		}
+	}
+
+	// Perform a BFS of the call graph from all
+	// go:nowritebarrierrec functions.
+	enqueue := func(src, target *ir.Func, pos src.XPos) {
+		if target.Pragma&ir.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.Nname)
+	}
+	for !q.Empty() {
+		fn := q.PopLeft().Func
+
+		// Check fn.
+		if fn.WBPos.IsKnown() {
+			var err bytes.Buffer
+			call := funcs[fn]
+			for call.target != nil {
+				fmt.Fprintf(&err, "\n\t%v: called by %v", base.FmtPos(call.lineno), call.target.Nname)
+				call = funcs[call.target]
+			}
+			base.ErrorfAt(fn.WBPos, "write barrier prohibited by caller; %v%s", fn.Nname, err.String())
+			continue
+		}
+
+		// Enqueue fn's calls.
+		for _, callee := range c.extraCalls[fn] {
+			enqueue(fn, callee.target, callee.lineno)
+		}
+		if fn.NWBRCalls == nil {
+			continue
+		}
+		for _, callee := range *fn.NWBRCalls {
+			target := symToFunc[callee.Sym]
+			if target != nil {
+				enqueue(fn, target, callee.Pos)
+			}
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/ssagen/pgen.go b/src/cmd/compile/internal/ssagen/pgen.go
new file mode 100644
index 0000000..6256753
--- /dev/null
+++ b/src/cmd/compile/internal/ssagen/pgen.go
@@ -0,0 +1,273 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssagen
+
+import (
+	"internal/buildcfg"
+	"internal/race"
+	"math/rand"
+	"sort"
+	"sync"
+	"time"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/objabi"
+	"cmd/internal/src"
+)
+
+// cmpstackvarlt reports whether the stack variable a sorts before b.
+//
+// Sort the list of stack variables. Autos after anything else,
+// within autos, unused after used, within used, things with
+// pointers first, zeroed things first, and then decreasing size.
+// Because autos are laid out in decreasing addresses
+// on the stack, pointers first, zeroed things first and decreasing size
+// really means, in memory, things with pointers needing zeroing at
+// the top of the stack and increasing in size.
+// Non-autos sort on offset.
+func cmpstackvarlt(a, b *ir.Name) bool {
+	if needAlloc(a) != needAlloc(b) {
+		return needAlloc(b)
+	}
+
+	if !needAlloc(a) {
+		return a.FrameOffset() < b.FrameOffset()
+	}
+
+	if a.Used() != b.Used() {
+		return a.Used()
+	}
+
+	ap := a.Type().HasPointers()
+	bp := b.Type().HasPointers()
+	if ap != bp {
+		return ap
+	}
+
+	ap = a.Needzero()
+	bp = b.Needzero()
+	if ap != bp {
+		return ap
+	}
+
+	if a.Type().Width != b.Type().Width {
+		return a.Type().Width > b.Type().Width
+	}
+
+	return a.Sym().Name < b.Sym().Name
+}
+
+// byStackvar implements sort.Interface for []*Node using cmpstackvarlt.
+type byStackVar []*ir.Name
+
+func (s byStackVar) Len() int           { return len(s) }
+func (s byStackVar) Less(i, j int) bool { return cmpstackvarlt(s[i], s[j]) }
+func (s byStackVar) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+
+// needAlloc reports whether n is within the current frame, for which we need to
+// allocate space. In particular, it excludes arguments and results, which are in
+// the callers frame.
+func needAlloc(n *ir.Name) bool {
+	return n.Class == ir.PAUTO || n.Class == ir.PPARAMOUT && n.IsOutputParamInRegisters()
+}
+
+func (s *ssafn) AllocFrame(f *ssa.Func) {
+	s.stksize = 0
+	s.stkptrsize = 0
+	fn := s.curfn
+
+	// Mark the PAUTO's unused.
+	for _, ln := range fn.Dcl {
+		if needAlloc(ln) {
+			ln.SetUsed(false)
+		}
+	}
+
+	for _, l := range f.RegAlloc {
+		if ls, ok := l.(ssa.LocalSlot); ok {
+			ls.N.SetUsed(true)
+		}
+	}
+
+	for _, b := range f.Blocks {
+		for _, v := range b.Values {
+			if n, ok := v.Aux.(*ir.Name); ok {
+				switch n.Class {
+				case ir.PPARAMOUT:
+					if n.IsOutputParamInRegisters() && v.Op == ssa.OpVarDef {
+						// ignore VarDef, look for "real" uses.
+						// TODO: maybe do this for PAUTO as well?
+						continue
+					}
+					fallthrough
+				case ir.PPARAM, ir.PAUTO:
+					n.SetUsed(true)
+				}
+			}
+		}
+	}
+
+	sort.Sort(byStackVar(fn.Dcl))
+
+	// Reassign stack offsets of the locals that are used.
+	lastHasPtr := false
+	for i, n := range fn.Dcl {
+		if n.Op() != ir.ONAME || n.Class != ir.PAUTO && !(n.Class == ir.PPARAMOUT && n.IsOutputParamInRegisters()) {
+			// i.e., stack assign if AUTO, or if PARAMOUT in registers (which has no predefined spill locations)
+			continue
+		}
+		if !n.Used() {
+			fn.Dcl = fn.Dcl[:i]
+			break
+		}
+
+		types.CalcSize(n.Type())
+		w := n.Type().Width
+		if w >= types.MaxWidth || w < 0 {
+			base.Fatalf("bad width")
+		}
+		if w == 0 && lastHasPtr {
+			// Pad between a pointer-containing object and a zero-sized object.
+			// This prevents a pointer to the zero-sized object from being interpreted
+			// as a pointer to the pointer-containing object (and causing it
+			// to be scanned when it shouldn't be). See issue 24993.
+			w = 1
+		}
+		s.stksize += w
+		s.stksize = types.Rnd(s.stksize, int64(n.Type().Align))
+		if n.Type().HasPointers() {
+			s.stkptrsize = s.stksize
+			lastHasPtr = true
+		} else {
+			lastHasPtr = false
+		}
+		n.SetFrameOffset(-s.stksize)
+	}
+
+	s.stksize = types.Rnd(s.stksize, int64(types.RegSize))
+	s.stkptrsize = types.Rnd(s.stkptrsize, int64(types.RegSize))
+}
+
+const maxStackSize = 1 << 30
+
+// Compile 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 Compile(fn *ir.Func, worker int) {
+	f := buildssa(fn, worker)
+	// Note: check arg size to fix issue 25507.
+	if f.Frontend().(*ssafn).stksize >= maxStackSize || f.OwnAux.ArgWidth() >= maxStackSize {
+		largeStackFramesMu.Lock()
+		largeStackFrames = append(largeStackFrames, largeStack{locals: f.Frontend().(*ssafn).stksize, args: f.OwnAux.ArgWidth(), pos: fn.Pos()})
+		largeStackFramesMu.Unlock()
+		return
+	}
+	pp := objw.NewProgs(fn, worker)
+	defer pp.Free()
+	genssa(f, pp)
+	// Check frame size again.
+	// The check above included only the space needed for local variables.
+	// After genssa, the space needed includes local variables and the callee arg region.
+	// We must do this check prior to calling pp.Flush.
+	// If there are any oversized stack frames,
+	// the assembler may emit inscrutable complaints about invalid instructions.
+	if pp.Text.To.Offset >= maxStackSize {
+		largeStackFramesMu.Lock()
+		locals := f.Frontend().(*ssafn).stksize
+		largeStackFrames = append(largeStackFrames, largeStack{locals: locals, args: f.OwnAux.ArgWidth(), callee: pp.Text.To.Offset - locals, pos: fn.Pos()})
+		largeStackFramesMu.Unlock()
+		return
+	}
+
+	pp.Flush() // assemble, fill in boilerplate, etc.
+	// fieldtrack must be called after pp.Flush. See issue 20014.
+	fieldtrack(pp.Text.From.Sym, fn.FieldTrack)
+}
+
+func init() {
+	if race.Enabled {
+		rand.Seed(time.Now().UnixNano())
+	}
+}
+
+// StackOffset returns the stack location of a LocalSlot relative to the
+// stack pointer, suitable for use in a DWARF location entry. This has nothing
+// to do with its offset in the user variable.
+func StackOffset(slot ssa.LocalSlot) int32 {
+	n := slot.N
+	var off int64
+	switch n.Class {
+	case ir.PPARAM, ir.PPARAMOUT:
+		if !n.IsOutputParamInRegisters() {
+			off = n.FrameOffset() + base.Ctxt.FixedFrameSize()
+			break
+		}
+		fallthrough // PPARAMOUT in registers allocates like an AUTO
+	case ir.PAUTO:
+		off = n.FrameOffset()
+		if base.Ctxt.FixedFrameSize() == 0 {
+			off -= int64(types.PtrSize)
+		}
+		if buildcfg.FramePointerEnabled {
+			off -= int64(types.PtrSize)
+		}
+	}
+	return int32(off + slot.Off)
+}
+
+// fieldtrack adds R_USEFIELD relocations to fnsym to record any
+// struct fields that it used.
+func fieldtrack(fnsym *obj.LSym, tracked map[*obj.LSym]struct{}) {
+	if fnsym == nil {
+		return
+	}
+	if !buildcfg.Experiment.FieldTrack || len(tracked) == 0 {
+		return
+	}
+
+	trackSyms := make([]*obj.LSym, 0, len(tracked))
+	for sym := range tracked {
+		trackSyms = append(trackSyms, sym)
+	}
+	sort.Slice(trackSyms, func(i, j int) bool { return trackSyms[i].Name < trackSyms[j].Name })
+	for _, sym := range trackSyms {
+		r := obj.Addrel(fnsym)
+		r.Sym = sym
+		r.Type = objabi.R_USEFIELD
+	}
+}
+
+// largeStack is info about a function whose stack frame is too large (rare).
+type largeStack struct {
+	locals int64
+	args   int64
+	callee int64
+	pos    src.XPos
+}
+
+var (
+	largeStackFramesMu sync.Mutex // protects largeStackFrames
+	largeStackFrames   []largeStack
+)
+
+func CheckLargeStacks() {
+	// Check whether any of the functions we have compiled have gigantic stack frames.
+	sort.Slice(largeStackFrames, func(i, j int) bool {
+		return largeStackFrames[i].pos.Before(largeStackFrames[j].pos)
+	})
+	for _, large := range largeStackFrames {
+		if large.callee != 0 {
+			base.ErrorfAt(large.pos, "stack frame too large (>1GB): %d MB locals + %d MB args + %d MB callee", large.locals>>20, large.args>>20, large.callee>>20)
+		} else {
+			base.ErrorfAt(large.pos, "stack frame too large (>1GB): %d MB locals + %d MB args", large.locals>>20, large.args>>20)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/ssagen/pgen_test.go b/src/cmd/compile/internal/ssagen/pgen_test.go
new file mode 100644
index 0000000..69ed8ad
--- /dev/null
+++ b/src/cmd/compile/internal/ssagen/pgen_test.go
@@ -0,0 +1,209 @@
+// 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 ssagen
+
+import (
+	"reflect"
+	"sort"
+	"testing"
+
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+func typeWithoutPointers() *types.Type {
+	return types.NewStruct(types.NoPkg, []*types.Field{
+		types.NewField(src.NoXPos, nil, types.New(types.TINT)),
+	})
+}
+
+func typeWithPointers() *types.Type {
+	return types.NewStruct(types.NoPkg, []*types.Field{
+		types.NewField(src.NoXPos, nil, types.NewPtr(types.New(types.TINT))),
+	})
+}
+
+func markUsed(n *ir.Name) *ir.Name {
+	n.SetUsed(true)
+	return n
+}
+
+func markNeedZero(n *ir.Name) *ir.Name {
+	n.SetNeedzero(true)
+	return n
+}
+
+// Test all code paths for cmpstackvarlt.
+func TestCmpstackvar(t *testing.T) {
+	nod := func(xoffset int64, t *types.Type, s *types.Sym, cl ir.Class) *ir.Name {
+		if s == nil {
+			s = &types.Sym{Name: "."}
+		}
+		n := typecheck.NewName(s)
+		n.SetType(t)
+		n.SetFrameOffset(xoffset)
+		n.Class = cl
+		return n
+	}
+	testdata := []struct {
+		a, b *ir.Name
+		lt   bool
+	}{
+		{
+			nod(0, nil, nil, ir.PAUTO),
+			nod(0, nil, nil, ir.PFUNC),
+			false,
+		},
+		{
+			nod(0, nil, nil, ir.PFUNC),
+			nod(0, nil, nil, ir.PAUTO),
+			true,
+		},
+		{
+			nod(0, nil, nil, ir.PFUNC),
+			nod(10, nil, nil, ir.PFUNC),
+			true,
+		},
+		{
+			nod(20, nil, nil, ir.PFUNC),
+			nod(10, nil, nil, ir.PFUNC),
+			false,
+		},
+		{
+			nod(10, nil, nil, ir.PFUNC),
+			nod(10, nil, nil, ir.PFUNC),
+			false,
+		},
+		{
+			nod(10, nil, nil, ir.PPARAM),
+			nod(20, nil, nil, ir.PPARAMOUT),
+			true,
+		},
+		{
+			nod(10, nil, nil, ir.PPARAMOUT),
+			nod(20, nil, nil, ir.PPARAM),
+			true,
+		},
+		{
+			markUsed(nod(0, nil, nil, ir.PAUTO)),
+			nod(0, nil, nil, ir.PAUTO),
+			true,
+		},
+		{
+			nod(0, nil, nil, ir.PAUTO),
+			markUsed(nod(0, nil, nil, ir.PAUTO)),
+			false,
+		},
+		{
+			nod(0, typeWithoutPointers(), nil, ir.PAUTO),
+			nod(0, typeWithPointers(), nil, ir.PAUTO),
+			false,
+		},
+		{
+			nod(0, typeWithPointers(), nil, ir.PAUTO),
+			nod(0, typeWithoutPointers(), nil, ir.PAUTO),
+			true,
+		},
+		{
+			markNeedZero(nod(0, &types.Type{}, nil, ir.PAUTO)),
+			nod(0, &types.Type{}, nil, ir.PAUTO),
+			true,
+		},
+		{
+			nod(0, &types.Type{}, nil, ir.PAUTO),
+			markNeedZero(nod(0, &types.Type{}, nil, ir.PAUTO)),
+			false,
+		},
+		{
+			nod(0, &types.Type{Width: 1}, nil, ir.PAUTO),
+			nod(0, &types.Type{Width: 2}, nil, ir.PAUTO),
+			false,
+		},
+		{
+			nod(0, &types.Type{Width: 2}, nil, ir.PAUTO),
+			nod(0, &types.Type{Width: 1}, nil, ir.PAUTO),
+			true,
+		},
+		{
+			nod(0, &types.Type{}, &types.Sym{Name: "abc"}, ir.PAUTO),
+			nod(0, &types.Type{}, &types.Sym{Name: "xyz"}, ir.PAUTO),
+			true,
+		},
+		{
+			nod(0, &types.Type{}, &types.Sym{Name: "abc"}, ir.PAUTO),
+			nod(0, &types.Type{}, &types.Sym{Name: "abc"}, ir.PAUTO),
+			false,
+		},
+		{
+			nod(0, &types.Type{}, &types.Sym{Name: "xyz"}, ir.PAUTO),
+			nod(0, &types.Type{}, &types.Sym{Name: "abc"}, ir.PAUTO),
+			false,
+		},
+	}
+	for _, d := range testdata {
+		got := cmpstackvarlt(d.a, d.b)
+		if got != d.lt {
+			t.Errorf("want %v < %v", d.a, d.b)
+		}
+		// If we expect a < b to be true, check that b < a is false.
+		if d.lt && cmpstackvarlt(d.b, d.a) {
+			t.Errorf("unexpected %v < %v", d.b, d.a)
+		}
+	}
+}
+
+func TestStackvarSort(t *testing.T) {
+	nod := func(xoffset int64, t *types.Type, s *types.Sym, cl ir.Class) *ir.Name {
+		n := typecheck.NewName(s)
+		n.SetType(t)
+		n.SetFrameOffset(xoffset)
+		n.Class = cl
+		return n
+	}
+	inp := []*ir.Name{
+		nod(0, &types.Type{}, &types.Sym{}, ir.PFUNC),
+		nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO),
+		nod(0, &types.Type{}, &types.Sym{}, ir.PFUNC),
+		nod(10, &types.Type{}, &types.Sym{}, ir.PFUNC),
+		nod(20, &types.Type{}, &types.Sym{}, ir.PFUNC),
+		markUsed(nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO)),
+		nod(0, typeWithoutPointers(), &types.Sym{}, ir.PAUTO),
+		nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO),
+		markNeedZero(nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO)),
+		nod(0, &types.Type{Width: 1}, &types.Sym{}, ir.PAUTO),
+		nod(0, &types.Type{Width: 2}, &types.Sym{}, ir.PAUTO),
+		nod(0, &types.Type{}, &types.Sym{Name: "abc"}, ir.PAUTO),
+		nod(0, &types.Type{}, &types.Sym{Name: "xyz"}, ir.PAUTO),
+	}
+	want := []*ir.Name{
+		nod(0, &types.Type{}, &types.Sym{}, ir.PFUNC),
+		nod(0, &types.Type{}, &types.Sym{}, ir.PFUNC),
+		nod(10, &types.Type{}, &types.Sym{}, ir.PFUNC),
+		nod(20, &types.Type{}, &types.Sym{}, ir.PFUNC),
+		markUsed(nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO)),
+		markNeedZero(nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO)),
+		nod(0, &types.Type{Width: 2}, &types.Sym{}, ir.PAUTO),
+		nod(0, &types.Type{Width: 1}, &types.Sym{}, ir.PAUTO),
+		nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO),
+		nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO),
+		nod(0, &types.Type{}, &types.Sym{Name: "abc"}, ir.PAUTO),
+		nod(0, &types.Type{}, &types.Sym{Name: "xyz"}, ir.PAUTO),
+		nod(0, typeWithoutPointers(), &types.Sym{}, ir.PAUTO),
+	}
+	sort.Sort(byStackVar(inp))
+	if !reflect.DeepEqual(want, inp) {
+		t.Error("sort failed")
+		for i := range inp {
+			g := inp[i]
+			w := want[i]
+			eq := reflect.DeepEqual(w, g)
+			if !eq {
+				t.Log(i, w, g)
+			}
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/ssagen/phi.go b/src/cmd/compile/internal/ssagen/phi.go
new file mode 100644
index 0000000..01ad211
--- /dev/null
+++ b/src/cmd/compile/internal/ssagen/phi.go
@@ -0,0 +1,557 @@
+// 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 ssagen
+
+import (
+	"container/heap"
+	"fmt"
+
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// This file contains the algorithm to place phi nodes in a function.
+// For small functions, we use Braun, Buchwald, Hack, Leißa, Mallon, and Zwinkau.
+// https://pp.info.uni-karlsruhe.de/uploads/publikationen/braun13cc.pdf
+// For large functions, we use Sreedhar & Gao: A Linear Time Algorithm for Placing Φ-Nodes.
+// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.8.1979&rep=rep1&type=pdf
+
+const smallBlocks = 500
+
+const debugPhi = false
+
+// fwdRefAux wraps an arbitrary ir.Node as an ssa.Aux for use with OpFwdref.
+type fwdRefAux struct {
+	_ [0]func() // ensure ir.Node isn't compared for equality
+	N ir.Node
+}
+
+func (fwdRefAux) CanBeAnSSAAux() {}
+
+// insertPhis finds all the places in the function where a phi is
+// necessary and inserts them.
+// Uses FwdRef ops to find all uses of variables, and s.defvars to find
+// all definitions.
+// Phi values are inserted, and all FwdRefs are changed to a Copy
+// of the appropriate phi or definition.
+// TODO: make this part of cmd/compile/internal/ssa somehow?
+func (s *state) insertPhis() {
+	if len(s.f.Blocks) <= smallBlocks {
+		sps := simplePhiState{s: s, f: s.f, defvars: s.defvars}
+		sps.insertPhis()
+		return
+	}
+	ps := phiState{s: s, f: s.f, defvars: s.defvars}
+	ps.insertPhis()
+}
+
+type phiState struct {
+	s       *state                   // SSA state
+	f       *ssa.Func                // function to work on
+	defvars []map[ir.Node]*ssa.Value // defined variables at end of each block
+
+	varnum map[ir.Node]int32 // variable numbering
+
+	// properties of the dominator tree
+	idom  []*ssa.Block // dominator parents
+	tree  []domBlock   // dominator child+sibling
+	level []int32      // level in dominator tree (0 = root or unreachable, 1 = children of root, ...)
+
+	// scratch locations
+	priq   blockHeap    // priority queue of blocks, higher level (toward leaves) = higher priority
+	q      []*ssa.Block // inner loop queue
+	queued *sparseSet   // has been put in q
+	hasPhi *sparseSet   // has a phi
+	hasDef *sparseSet   // has a write of the variable we're processing
+
+	// miscellaneous
+	placeholder *ssa.Value // value to use as a "not set yet" placeholder.
+}
+
+func (s *phiState) insertPhis() {
+	if debugPhi {
+		fmt.Println(s.f.String())
+	}
+
+	// Find all the variables for which we need to match up reads & writes.
+	// This step prunes any basic-block-only variables from consideration.
+	// Generate a numbering for these variables.
+	s.varnum = map[ir.Node]int32{}
+	var vars []ir.Node
+	var vartypes []*types.Type
+	for _, b := range s.f.Blocks {
+		for _, v := range b.Values {
+			if v.Op != ssa.OpFwdRef {
+				continue
+			}
+			var_ := v.Aux.(fwdRefAux).N
+
+			// Optimization: look back 1 block for the definition.
+			if len(b.Preds) == 1 {
+				c := b.Preds[0].Block()
+				if w := s.defvars[c.ID][var_]; w != nil {
+					v.Op = ssa.OpCopy
+					v.Aux = nil
+					v.AddArg(w)
+					continue
+				}
+			}
+
+			if _, ok := s.varnum[var_]; ok {
+				continue
+			}
+			s.varnum[var_] = int32(len(vartypes))
+			if debugPhi {
+				fmt.Printf("var%d = %v\n", len(vartypes), var_)
+			}
+			vars = append(vars, var_)
+			vartypes = append(vartypes, v.Type)
+		}
+	}
+
+	if len(vartypes) == 0 {
+		return
+	}
+
+	// Find all definitions of the variables we need to process.
+	// defs[n] contains all the blocks in which variable number n is assigned.
+	defs := make([][]*ssa.Block, len(vartypes))
+	for _, b := range s.f.Blocks {
+		for var_ := range s.defvars[b.ID] { // TODO: encode defvars some other way (explicit ops)? make defvars[n] a slice instead of a map.
+			if n, ok := s.varnum[var_]; ok {
+				defs[n] = append(defs[n], b)
+			}
+		}
+	}
+
+	// Make dominator tree.
+	s.idom = s.f.Idom()
+	s.tree = make([]domBlock, s.f.NumBlocks())
+	for _, b := range s.f.Blocks {
+		p := s.idom[b.ID]
+		if p != nil {
+			s.tree[b.ID].sibling = s.tree[p.ID].firstChild
+			s.tree[p.ID].firstChild = b
+		}
+	}
+	// Compute levels in dominator tree.
+	// With parent pointers we can do a depth-first walk without
+	// any auxiliary storage.
+	s.level = make([]int32, s.f.NumBlocks())
+	b := s.f.Entry
+levels:
+	for {
+		if p := s.idom[b.ID]; p != nil {
+			s.level[b.ID] = s.level[p.ID] + 1
+			if debugPhi {
+				fmt.Printf("level %s = %d\n", b, s.level[b.ID])
+			}
+		}
+		if c := s.tree[b.ID].firstChild; c != nil {
+			b = c
+			continue
+		}
+		for {
+			if c := s.tree[b.ID].sibling; c != nil {
+				b = c
+				continue levels
+			}
+			b = s.idom[b.ID]
+			if b == nil {
+				break levels
+			}
+		}
+	}
+
+	// Allocate scratch locations.
+	s.priq.level = s.level
+	s.q = make([]*ssa.Block, 0, s.f.NumBlocks())
+	s.queued = newSparseSet(s.f.NumBlocks())
+	s.hasPhi = newSparseSet(s.f.NumBlocks())
+	s.hasDef = newSparseSet(s.f.NumBlocks())
+	s.placeholder = s.s.entryNewValue0(ssa.OpUnknown, types.TypeInvalid)
+
+	// Generate phi ops for each variable.
+	for n := range vartypes {
+		s.insertVarPhis(n, vars[n], defs[n], vartypes[n])
+	}
+
+	// Resolve FwdRefs to the correct write or phi.
+	s.resolveFwdRefs()
+
+	// Erase variable numbers stored in AuxInt fields of phi ops. They are no longer needed.
+	for _, b := range s.f.Blocks {
+		for _, v := range b.Values {
+			if v.Op == ssa.OpPhi {
+				v.AuxInt = 0
+			}
+			// Any remaining FwdRefs are dead code.
+			if v.Op == ssa.OpFwdRef {
+				v.Op = ssa.OpUnknown
+				v.Aux = nil
+			}
+		}
+	}
+}
+
+func (s *phiState) insertVarPhis(n int, var_ ir.Node, defs []*ssa.Block, typ *types.Type) {
+	priq := &s.priq
+	q := s.q
+	queued := s.queued
+	queued.clear()
+	hasPhi := s.hasPhi
+	hasPhi.clear()
+	hasDef := s.hasDef
+	hasDef.clear()
+
+	// Add defining blocks to priority queue.
+	for _, b := range defs {
+		priq.a = append(priq.a, b)
+		hasDef.add(b.ID)
+		if debugPhi {
+			fmt.Printf("def of var%d in %s\n", n, b)
+		}
+	}
+	heap.Init(priq)
+
+	// Visit blocks defining variable n, from deepest to shallowest.
+	for len(priq.a) > 0 {
+		currentRoot := heap.Pop(priq).(*ssa.Block)
+		if debugPhi {
+			fmt.Printf("currentRoot %s\n", currentRoot)
+		}
+		// Walk subtree below definition.
+		// Skip subtrees we've done in previous iterations.
+		// Find edges exiting tree dominated by definition (the dominance frontier).
+		// Insert phis at target blocks.
+		if queued.contains(currentRoot.ID) {
+			s.s.Fatalf("root already in queue")
+		}
+		q = append(q, currentRoot)
+		queued.add(currentRoot.ID)
+		for len(q) > 0 {
+			b := q[len(q)-1]
+			q = q[:len(q)-1]
+			if debugPhi {
+				fmt.Printf("  processing %s\n", b)
+			}
+
+			currentRootLevel := s.level[currentRoot.ID]
+			for _, e := range b.Succs {
+				c := e.Block()
+				// TODO: if the variable is dead at c, skip it.
+				if s.level[c.ID] > currentRootLevel {
+					// a D-edge, or an edge whose target is in currentRoot's subtree.
+					continue
+				}
+				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.
+				if var_.Op() == ir.ONAME {
+					s.s.addNamedValue(var_.(*ir.Name), v)
+				}
+				for range c.Preds {
+					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)
+				}
+			}
+
+			// Visit children if they have not been visited yet.
+			for c := s.tree[b.ID].firstChild; c != nil; c = s.tree[c.ID].sibling {
+				if !queued.contains(c.ID) {
+					q = append(q, c)
+					queued.add(c.ID)
+				}
+			}
+		}
+	}
+}
+
+// resolveFwdRefs links all FwdRef uses up to their nearest dominating definition.
+func (s *phiState) resolveFwdRefs() {
+	// Do a depth-first walk of the dominator tree, keeping track
+	// of the most-recently-seen value for each variable.
+
+	// Map from variable ID to SSA value at the current point of the walk.
+	values := make([]*ssa.Value, len(s.varnum))
+	for i := range values {
+		values[i] = s.placeholder
+	}
+
+	// Stack of work to do.
+	type stackEntry struct {
+		b *ssa.Block // block to explore
+
+		// variable/value pair to reinstate on exit
+		n int32 // variable ID
+		v *ssa.Value
+
+		// Note: only one of b or n,v will be set.
+	}
+	var stk []stackEntry
+
+	stk = append(stk, stackEntry{b: s.f.Entry})
+	for len(stk) > 0 {
+		work := stk[len(stk)-1]
+		stk = stk[:len(stk)-1]
+
+		b := work.b
+		if b == nil {
+			// On exit from a block, this case will undo any assignments done below.
+			values[work.n] = work.v
+			continue
+		}
+
+		// Process phis as new defs. They come before FwdRefs in this block.
+		for _, v := range b.Values {
+			if v.Op != ssa.OpPhi {
+				continue
+			}
+			n := int32(v.AuxInt)
+			// Remember the old assignment so we can undo it when we exit b.
+			stk = append(stk, stackEntry{n: n, v: values[n]})
+			// Record the new assignment.
+			values[n] = v
+		}
+
+		// Replace a FwdRef op with the current incoming value for its variable.
+		for _, v := range b.Values {
+			if v.Op != ssa.OpFwdRef {
+				continue
+			}
+			n := s.varnum[v.Aux.(fwdRefAux).N]
+			v.Op = ssa.OpCopy
+			v.Aux = nil
+			v.AddArg(values[n])
+		}
+
+		// Establish values for variables defined in b.
+		for var_, v := range s.defvars[b.ID] {
+			n, ok := s.varnum[var_]
+			if !ok {
+				// some variable not live across a basic block boundary.
+				continue
+			}
+			// Remember the old assignment so we can undo it when we exit b.
+			stk = append(stk, stackEntry{n: n, v: values[n]})
+			// Record the new assignment.
+			values[n] = v
+		}
+
+		// Replace phi args in successors with the current incoming value.
+		for _, e := range b.Succs {
+			c, i := e.Block(), e.Index()
+			for j := len(c.Values) - 1; j >= 0; j-- {
+				v := c.Values[j]
+				if v.Op != ssa.OpPhi {
+					break // All phis will be at the end of the block during phi building.
+				}
+				// Only set arguments that have been resolved.
+				// For very wide CFGs, this significantly speeds up phi resolution.
+				// See golang.org/issue/8225.
+				if w := values[v.AuxInt]; w.Op != ssa.OpUnknown {
+					v.SetArg(i, w)
+				}
+			}
+		}
+
+		// Walk children in dominator tree.
+		for c := s.tree[b.ID].firstChild; c != nil; c = s.tree[c.ID].sibling {
+			stk = append(stk, stackEntry{b: c})
+		}
+	}
+}
+
+// domBlock contains extra per-block information to record the dominator tree.
+type domBlock struct {
+	firstChild *ssa.Block // first child of block in dominator tree
+	sibling    *ssa.Block // next child of parent in dominator tree
+}
+
+// A block heap is used as a priority queue to implement the PiggyBank
+// from Sreedhar and Gao.  That paper uses an array which is better
+// asymptotically but worse in the common case when the PiggyBank
+// holds a sparse set of blocks.
+type blockHeap struct {
+	a     []*ssa.Block // block IDs in heap
+	level []int32      // depth in dominator tree (static, used for determining priority)
+}
+
+func (h *blockHeap) Len() int      { return len(h.a) }
+func (h *blockHeap) Swap(i, j int) { a := h.a; a[i], a[j] = a[j], a[i] }
+
+func (h *blockHeap) Push(x interface{}) {
+	v := x.(*ssa.Block)
+	h.a = append(h.a, v)
+}
+func (h *blockHeap) Pop() interface{} {
+	old := h.a
+	n := len(old)
+	x := old[n-1]
+	h.a = old[:n-1]
+	return x
+}
+func (h *blockHeap) Less(i, j int) bool {
+	return h.level[h.a[i].ID] > h.level[h.a[j].ID]
+}
+
+// TODO: stop walking the iterated domininance frontier when
+// the variable is dead. Maybe detect that by checking if the
+// node we're on is reverse dominated by all the reads?
+// Reverse dominated by the highest common successor of all the reads?
+
+// copy of ../ssa/sparseset.go
+// TODO: move this file to ../ssa, then use sparseSet there.
+type sparseSet struct {
+	dense  []ssa.ID
+	sparse []int32
+}
+
+// newSparseSet returns a sparseSet that can represent
+// integers between 0 and n-1
+func newSparseSet(n int) *sparseSet {
+	return &sparseSet{dense: nil, sparse: make([]int32, n)}
+}
+
+func (s *sparseSet) contains(x ssa.ID) bool {
+	i := s.sparse[x]
+	return i < int32(len(s.dense)) && s.dense[i] == x
+}
+
+func (s *sparseSet) add(x ssa.ID) {
+	i := s.sparse[x]
+	if i < int32(len(s.dense)) && s.dense[i] == x {
+		return
+	}
+	s.dense = append(s.dense, x)
+	s.sparse[x] = int32(len(s.dense)) - 1
+}
+
+func (s *sparseSet) clear() {
+	s.dense = s.dense[:0]
+}
+
+// Variant to use for small functions.
+type simplePhiState struct {
+	s         *state                   // SSA state
+	f         *ssa.Func                // function to work on
+	fwdrefs   []*ssa.Value             // list of FwdRefs to be processed
+	defvars   []map[ir.Node]*ssa.Value // defined variables at end of each block
+	reachable []bool                   // which blocks are reachable
+}
+
+func (s *simplePhiState) insertPhis() {
+	s.reachable = ssa.ReachableBlocks(s.f)
+
+	// Find FwdRef ops.
+	for _, b := range s.f.Blocks {
+		for _, v := range b.Values {
+			if v.Op != ssa.OpFwdRef {
+				continue
+			}
+			s.fwdrefs = append(s.fwdrefs, v)
+			var_ := v.Aux.(fwdRefAux).N
+			if _, ok := s.defvars[b.ID][var_]; !ok {
+				s.defvars[b.ID][var_] = v // treat FwdDefs as definitions.
+			}
+		}
+	}
+
+	var args []*ssa.Value
+
+loop:
+	for len(s.fwdrefs) > 0 {
+		v := s.fwdrefs[len(s.fwdrefs)-1]
+		s.fwdrefs = s.fwdrefs[:len(s.fwdrefs)-1]
+		b := v.Block
+		var_ := v.Aux.(fwdRefAux).N
+		if b == s.f.Entry {
+			// No variable should be live at entry.
+			s.s.Fatalf("Value live at entry. It shouldn't be. func %s, node %v, value %v", s.f.Name, var_, v)
+		}
+		if !s.reachable[b.ID] {
+			// This block is dead.
+			// It doesn't matter what we use here as long as it is well-formed.
+			v.Op = ssa.OpUnknown
+			v.Aux = nil
+			continue
+		}
+		// Find variable value on each predecessor.
+		args = args[:0]
+		for _, e := range b.Preds {
+			args = append(args, s.lookupVarOutgoing(e.Block(), v.Type, var_, v.Pos))
+		}
+
+		// Decide if we need a phi or not. We need a phi if there
+		// are two different args (which are both not v).
+		var w *ssa.Value
+		for _, a := range args {
+			if a == v {
+				continue // self-reference
+			}
+			if a == w {
+				continue // already have this witness
+			}
+			if w != nil {
+				// two witnesses, need a phi value
+				v.Op = ssa.OpPhi
+				v.AddArgs(args...)
+				v.Aux = nil
+				continue loop
+			}
+			w = a // save witness
+		}
+		if w == nil {
+			s.s.Fatalf("no witness for reachable phi %s", v)
+		}
+		// One witness. Make v a copy of w.
+		v.Op = ssa.OpCopy
+		v.Aux = nil
+		v.AddArg(w)
+	}
+}
+
+// lookupVarOutgoing finds the variable's value at the end of block b.
+func (s *simplePhiState) lookupVarOutgoing(b *ssa.Block, t *types.Type, var_ ir.Node, line src.XPos) *ssa.Value {
+	for {
+		if v := s.defvars[b.ID][var_]; v != nil {
+			return v
+		}
+		// The variable is not defined by b and we haven't looked it up yet.
+		// If b has exactly one predecessor, loop to look it up there.
+		// Otherwise, give up and insert a new FwdRef and resolve it later.
+		if len(b.Preds) != 1 {
+			break
+		}
+		b = b.Preds[0].Block()
+		if !s.reachable[b.ID] {
+			// This is rare; it happens with oddly interleaved infinite loops in dead code.
+			// See issue 19783.
+			break
+		}
+	}
+	// Generate a FwdRef for the variable and return that.
+	v := b.NewValue0A(line, ssa.OpFwdRef, t, fwdRefAux{N: var_})
+	s.defvars[b.ID][var_] = v
+	if var_.Op() == ir.ONAME {
+		s.s.addNamedValue(var_.(*ir.Name), v)
+	}
+	s.fwdrefs = append(s.fwdrefs, v)
+	return v
+}
diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go
new file mode 100644
index 0000000..dfa7600
--- /dev/null
+++ b/src/cmd/compile/internal/ssagen/ssa.go
@@ -0,0 +1,7739 @@
+// 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 ssagen
+
+import (
+	"bufio"
+	"bytes"
+	"cmd/compile/internal/abi"
+	"fmt"
+	"go/constant"
+	"html"
+	"internal/buildcfg"
+	"os"
+	"path/filepath"
+	"sort"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/liveness"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/staticdata"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/obj/x86"
+	"cmd/internal/objabi"
+	"cmd/internal/src"
+	"cmd/internal/sys"
+)
+
+var ssaConfig *ssa.Config
+var ssaCaches []ssa.Cache
+
+var ssaDump string     // early copy of $GOSSAFUNC; the func name to dump output for
+var ssaDir string      // optional destination for ssa dump file
+var ssaDumpStdout bool // whether to dump to stdout
+var ssaDumpCFG string  // generate CFGs for these phases
+const ssaDumpFile = "ssa.html"
+
+// ssaDumpInlined holds all inlined functions when ssaDump contains a function name.
+var ssaDumpInlined []*ir.Func
+
+func DumpInline(fn *ir.Func) {
+	if ssaDump != "" && ssaDump == ir.FuncName(fn) {
+		ssaDumpInlined = append(ssaDumpInlined, fn)
+	}
+}
+
+func InitEnv() {
+	ssaDump = os.Getenv("GOSSAFUNC")
+	ssaDir = os.Getenv("GOSSADIR")
+	if ssaDump != "" {
+		if strings.HasSuffix(ssaDump, "+") {
+			ssaDump = ssaDump[:len(ssaDump)-1]
+			ssaDumpStdout = true
+		}
+		spl := strings.Split(ssaDump, ":")
+		if len(spl) > 1 {
+			ssaDump = spl[0]
+			ssaDumpCFG = spl[1]
+		}
+	}
+}
+
+func InitConfig() {
+	types_ := ssa.NewTypes()
+
+	if Arch.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[types.TINTER])                             // *interface{}
+	_ = types.NewPtr(types.NewPtr(types.Types[types.TSTRING]))              // **string
+	_ = types.NewPtr(types.NewSlice(types.Types[types.TINTER]))             // *[]interface{}
+	_ = types.NewPtr(types.NewPtr(types.ByteType))                          // **byte
+	_ = types.NewPtr(types.NewSlice(types.ByteType))                        // *[]byte
+	_ = types.NewPtr(types.NewSlice(types.Types[types.TSTRING]))            // *[]string
+	_ = types.NewPtr(types.NewPtr(types.NewPtr(types.Types[types.TUINT8]))) // ***uint8
+	_ = types.NewPtr(types.Types[types.TINT16])                             // *int16
+	_ = types.NewPtr(types.Types[types.TINT64])                             // *int64
+	_ = types.NewPtr(types.ErrorType)                                       // *error
+	types.NewPtrCacheEnabled = false
+	ssaConfig = ssa.NewConfig(base.Ctxt.Arch.Name, *types_, base.Ctxt, base.Flag.N == 0)
+	ssaConfig.SoftFloat = Arch.SoftFloat
+	ssaConfig.Race = base.Flag.Race
+	ssaCaches = make([]ssa.Cache, base.Flag.LowerC)
+
+	// Set up some runtime functions we'll need to call.
+	ir.Syms.AssertE2I = typecheck.LookupRuntimeFunc("assertE2I")
+	ir.Syms.AssertE2I2 = typecheck.LookupRuntimeFunc("assertE2I2")
+	ir.Syms.AssertI2I = typecheck.LookupRuntimeFunc("assertI2I")
+	ir.Syms.AssertI2I2 = typecheck.LookupRuntimeFunc("assertI2I2")
+	ir.Syms.Deferproc = typecheck.LookupRuntimeFunc("deferproc")
+	ir.Syms.DeferprocStack = typecheck.LookupRuntimeFunc("deferprocStack")
+	ir.Syms.Deferreturn = typecheck.LookupRuntimeFunc("deferreturn")
+	ir.Syms.Duffcopy = typecheck.LookupRuntimeFunc("duffcopy")
+	ir.Syms.Duffzero = typecheck.LookupRuntimeFunc("duffzero")
+	ir.Syms.GCWriteBarrier = typecheck.LookupRuntimeFunc("gcWriteBarrier")
+	ir.Syms.Goschedguarded = typecheck.LookupRuntimeFunc("goschedguarded")
+	ir.Syms.Growslice = typecheck.LookupRuntimeFunc("growslice")
+	ir.Syms.Msanread = typecheck.LookupRuntimeFunc("msanread")
+	ir.Syms.Msanwrite = typecheck.LookupRuntimeFunc("msanwrite")
+	ir.Syms.Msanmove = typecheck.LookupRuntimeFunc("msanmove")
+	ir.Syms.Newobject = typecheck.LookupRuntimeFunc("newobject")
+	ir.Syms.Newproc = typecheck.LookupRuntimeFunc("newproc")
+	ir.Syms.Panicdivide = typecheck.LookupRuntimeFunc("panicdivide")
+	ir.Syms.PanicdottypeE = typecheck.LookupRuntimeFunc("panicdottypeE")
+	ir.Syms.PanicdottypeI = typecheck.LookupRuntimeFunc("panicdottypeI")
+	ir.Syms.Panicnildottype = typecheck.LookupRuntimeFunc("panicnildottype")
+	ir.Syms.Panicoverflow = typecheck.LookupRuntimeFunc("panicoverflow")
+	ir.Syms.Panicshift = typecheck.LookupRuntimeFunc("panicshift")
+	ir.Syms.Raceread = typecheck.LookupRuntimeFunc("raceread")
+	ir.Syms.Racereadrange = typecheck.LookupRuntimeFunc("racereadrange")
+	ir.Syms.Racewrite = typecheck.LookupRuntimeFunc("racewrite")
+	ir.Syms.Racewriterange = typecheck.LookupRuntimeFunc("racewriterange")
+	ir.Syms.X86HasPOPCNT = typecheck.LookupRuntimeVar("x86HasPOPCNT")       // bool
+	ir.Syms.X86HasSSE41 = typecheck.LookupRuntimeVar("x86HasSSE41")         // bool
+	ir.Syms.X86HasFMA = typecheck.LookupRuntimeVar("x86HasFMA")             // bool
+	ir.Syms.ARMHasVFPv4 = typecheck.LookupRuntimeVar("armHasVFPv4")         // bool
+	ir.Syms.ARM64HasATOMICS = typecheck.LookupRuntimeVar("arm64HasATOMICS") // bool
+	ir.Syms.Staticuint64s = typecheck.LookupRuntimeVar("staticuint64s")
+	ir.Syms.Typedmemclr = typecheck.LookupRuntimeFunc("typedmemclr")
+	ir.Syms.Typedmemmove = typecheck.LookupRuntimeFunc("typedmemmove")
+	ir.Syms.Udiv = typecheck.LookupRuntimeVar("udiv")                 // asm func with special ABI
+	ir.Syms.WriteBarrier = typecheck.LookupRuntimeVar("writeBarrier") // struct { bool; ... }
+	ir.Syms.Zerobase = typecheck.LookupRuntimeVar("zerobase")
+
+	// asm funcs with special ABI
+	if base.Ctxt.Arch.Name == "amd64" {
+		GCWriteBarrierReg = map[int16]*obj.LSym{
+			x86.REG_AX: typecheck.LookupRuntimeFunc("gcWriteBarrier"),
+			x86.REG_CX: typecheck.LookupRuntimeFunc("gcWriteBarrierCX"),
+			x86.REG_DX: typecheck.LookupRuntimeFunc("gcWriteBarrierDX"),
+			x86.REG_BX: typecheck.LookupRuntimeFunc("gcWriteBarrierBX"),
+			x86.REG_BP: typecheck.LookupRuntimeFunc("gcWriteBarrierBP"),
+			x86.REG_SI: typecheck.LookupRuntimeFunc("gcWriteBarrierSI"),
+			x86.REG_R8: typecheck.LookupRuntimeFunc("gcWriteBarrierR8"),
+			x86.REG_R9: typecheck.LookupRuntimeFunc("gcWriteBarrierR9"),
+		}
+	}
+
+	if Arch.LinkArch.Family == sys.Wasm {
+		BoundsCheckFunc[ssa.BoundsIndex] = typecheck.LookupRuntimeFunc("goPanicIndex")
+		BoundsCheckFunc[ssa.BoundsIndexU] = typecheck.LookupRuntimeFunc("goPanicIndexU")
+		BoundsCheckFunc[ssa.BoundsSliceAlen] = typecheck.LookupRuntimeFunc("goPanicSliceAlen")
+		BoundsCheckFunc[ssa.BoundsSliceAlenU] = typecheck.LookupRuntimeFunc("goPanicSliceAlenU")
+		BoundsCheckFunc[ssa.BoundsSliceAcap] = typecheck.LookupRuntimeFunc("goPanicSliceAcap")
+		BoundsCheckFunc[ssa.BoundsSliceAcapU] = typecheck.LookupRuntimeFunc("goPanicSliceAcapU")
+		BoundsCheckFunc[ssa.BoundsSliceB] = typecheck.LookupRuntimeFunc("goPanicSliceB")
+		BoundsCheckFunc[ssa.BoundsSliceBU] = typecheck.LookupRuntimeFunc("goPanicSliceBU")
+		BoundsCheckFunc[ssa.BoundsSlice3Alen] = typecheck.LookupRuntimeFunc("goPanicSlice3Alen")
+		BoundsCheckFunc[ssa.BoundsSlice3AlenU] = typecheck.LookupRuntimeFunc("goPanicSlice3AlenU")
+		BoundsCheckFunc[ssa.BoundsSlice3Acap] = typecheck.LookupRuntimeFunc("goPanicSlice3Acap")
+		BoundsCheckFunc[ssa.BoundsSlice3AcapU] = typecheck.LookupRuntimeFunc("goPanicSlice3AcapU")
+		BoundsCheckFunc[ssa.BoundsSlice3B] = typecheck.LookupRuntimeFunc("goPanicSlice3B")
+		BoundsCheckFunc[ssa.BoundsSlice3BU] = typecheck.LookupRuntimeFunc("goPanicSlice3BU")
+		BoundsCheckFunc[ssa.BoundsSlice3C] = typecheck.LookupRuntimeFunc("goPanicSlice3C")
+		BoundsCheckFunc[ssa.BoundsSlice3CU] = typecheck.LookupRuntimeFunc("goPanicSlice3CU")
+		BoundsCheckFunc[ssa.BoundsConvert] = typecheck.LookupRuntimeFunc("goPanicSliceConvert")
+	} else {
+		BoundsCheckFunc[ssa.BoundsIndex] = typecheck.LookupRuntimeFunc("panicIndex")
+		BoundsCheckFunc[ssa.BoundsIndexU] = typecheck.LookupRuntimeFunc("panicIndexU")
+		BoundsCheckFunc[ssa.BoundsSliceAlen] = typecheck.LookupRuntimeFunc("panicSliceAlen")
+		BoundsCheckFunc[ssa.BoundsSliceAlenU] = typecheck.LookupRuntimeFunc("panicSliceAlenU")
+		BoundsCheckFunc[ssa.BoundsSliceAcap] = typecheck.LookupRuntimeFunc("panicSliceAcap")
+		BoundsCheckFunc[ssa.BoundsSliceAcapU] = typecheck.LookupRuntimeFunc("panicSliceAcapU")
+		BoundsCheckFunc[ssa.BoundsSliceB] = typecheck.LookupRuntimeFunc("panicSliceB")
+		BoundsCheckFunc[ssa.BoundsSliceBU] = typecheck.LookupRuntimeFunc("panicSliceBU")
+		BoundsCheckFunc[ssa.BoundsSlice3Alen] = typecheck.LookupRuntimeFunc("panicSlice3Alen")
+		BoundsCheckFunc[ssa.BoundsSlice3AlenU] = typecheck.LookupRuntimeFunc("panicSlice3AlenU")
+		BoundsCheckFunc[ssa.BoundsSlice3Acap] = typecheck.LookupRuntimeFunc("panicSlice3Acap")
+		BoundsCheckFunc[ssa.BoundsSlice3AcapU] = typecheck.LookupRuntimeFunc("panicSlice3AcapU")
+		BoundsCheckFunc[ssa.BoundsSlice3B] = typecheck.LookupRuntimeFunc("panicSlice3B")
+		BoundsCheckFunc[ssa.BoundsSlice3BU] = typecheck.LookupRuntimeFunc("panicSlice3BU")
+		BoundsCheckFunc[ssa.BoundsSlice3C] = typecheck.LookupRuntimeFunc("panicSlice3C")
+		BoundsCheckFunc[ssa.BoundsSlice3CU] = typecheck.LookupRuntimeFunc("panicSlice3CU")
+		BoundsCheckFunc[ssa.BoundsConvert] = typecheck.LookupRuntimeFunc("panicSliceConvert")
+	}
+	if Arch.LinkArch.PtrSize == 4 {
+		ExtendCheckFunc[ssa.BoundsIndex] = typecheck.LookupRuntimeVar("panicExtendIndex")
+		ExtendCheckFunc[ssa.BoundsIndexU] = typecheck.LookupRuntimeVar("panicExtendIndexU")
+		ExtendCheckFunc[ssa.BoundsSliceAlen] = typecheck.LookupRuntimeVar("panicExtendSliceAlen")
+		ExtendCheckFunc[ssa.BoundsSliceAlenU] = typecheck.LookupRuntimeVar("panicExtendSliceAlenU")
+		ExtendCheckFunc[ssa.BoundsSliceAcap] = typecheck.LookupRuntimeVar("panicExtendSliceAcap")
+		ExtendCheckFunc[ssa.BoundsSliceAcapU] = typecheck.LookupRuntimeVar("panicExtendSliceAcapU")
+		ExtendCheckFunc[ssa.BoundsSliceB] = typecheck.LookupRuntimeVar("panicExtendSliceB")
+		ExtendCheckFunc[ssa.BoundsSliceBU] = typecheck.LookupRuntimeVar("panicExtendSliceBU")
+		ExtendCheckFunc[ssa.BoundsSlice3Alen] = typecheck.LookupRuntimeVar("panicExtendSlice3Alen")
+		ExtendCheckFunc[ssa.BoundsSlice3AlenU] = typecheck.LookupRuntimeVar("panicExtendSlice3AlenU")
+		ExtendCheckFunc[ssa.BoundsSlice3Acap] = typecheck.LookupRuntimeVar("panicExtendSlice3Acap")
+		ExtendCheckFunc[ssa.BoundsSlice3AcapU] = typecheck.LookupRuntimeVar("panicExtendSlice3AcapU")
+		ExtendCheckFunc[ssa.BoundsSlice3B] = typecheck.LookupRuntimeVar("panicExtendSlice3B")
+		ExtendCheckFunc[ssa.BoundsSlice3BU] = typecheck.LookupRuntimeVar("panicExtendSlice3BU")
+		ExtendCheckFunc[ssa.BoundsSlice3C] = typecheck.LookupRuntimeVar("panicExtendSlice3C")
+		ExtendCheckFunc[ssa.BoundsSlice3CU] = typecheck.LookupRuntimeVar("panicExtendSlice3CU")
+	}
+
+	// Wasm (all asm funcs with special ABIs)
+	ir.Syms.WasmMove = typecheck.LookupRuntimeVar("wasmMove")
+	ir.Syms.WasmZero = typecheck.LookupRuntimeVar("wasmZero")
+	ir.Syms.WasmDiv = typecheck.LookupRuntimeVar("wasmDiv")
+	ir.Syms.WasmTruncS = typecheck.LookupRuntimeVar("wasmTruncS")
+	ir.Syms.WasmTruncU = typecheck.LookupRuntimeVar("wasmTruncU")
+	ir.Syms.SigPanic = typecheck.LookupRuntimeFunc("sigpanic")
+}
+
+// AbiForBodylessFuncStackMap returns the ABI for a bodyless function's stack map.
+// This is not necessarily the ABI used to call it.
+// Currently (1.17 dev) such a stack map is always ABI0;
+// any ABI wrapper that is present is nosplit, hence a precise
+// stack map is not needed there (the parameters survive only long
+// enough to call the wrapped assembly function).
+// This always returns a freshly copied ABI.
+func AbiForBodylessFuncStackMap(fn *ir.Func) *abi.ABIConfig {
+	return ssaConfig.ABI0.Copy() // No idea what races will result, be safe
+}
+
+// These are disabled but remain ready for use in case they are needed for the next regabi port.
+// TODO if they are not needed for 1.18 / next register abi port, delete them.
+const magicNameDotSuffix = ".*disabled*MagicMethodNameForTestingRegisterABI"
+const magicLastTypeName = "*disabled*MagicLastTypeNameForTestingRegisterABI"
+
+// abiForFunc implements ABI policy for a function, but does not return a copy of the ABI.
+// Passing a nil function returns the default ABI based on experiment configuration.
+func abiForFunc(fn *ir.Func, abi0, abi1 *abi.ABIConfig) *abi.ABIConfig {
+	if buildcfg.Experiment.RegabiArgs {
+		// Select the ABI based on the function's defining ABI.
+		if fn == nil {
+			return abi1
+		}
+		switch fn.ABI {
+		case obj.ABI0:
+			return abi0
+		case obj.ABIInternal:
+			// TODO(austin): Clean up the nomenclature here.
+			// It's not clear that "abi1" is ABIInternal.
+			return abi1
+		}
+		base.Fatalf("function %v has unknown ABI %v", fn, fn.ABI)
+		panic("not reachable")
+	}
+
+	a := abi0
+	if fn != nil {
+		name := ir.FuncName(fn)
+		magicName := strings.HasSuffix(name, magicNameDotSuffix)
+		if fn.Pragma&ir.RegisterParams != 0 { // TODO(register args) remove after register abi is working
+			if strings.Contains(name, ".") {
+				if !magicName {
+					base.ErrorfAt(fn.Pos(), "Calls to //go:registerparams method %s won't work, remove the pragma from the declaration.", name)
+				}
+			}
+			a = abi1
+		} else if magicName {
+			if base.FmtPos(fn.Pos()) == "<autogenerated>:1" {
+				// no way to put a pragma here, and it will error out in the real source code if they did not do it there.
+				a = abi1
+			} else {
+				base.ErrorfAt(fn.Pos(), "Methods with magic name %s (method %s) must also specify //go:registerparams", magicNameDotSuffix[1:], name)
+			}
+		}
+		if regAbiForFuncType(fn.Type().FuncType()) {
+			// fmt.Printf("Saw magic last type name for function %s\n", name)
+			a = abi1
+		}
+	}
+	return a
+}
+
+func regAbiForFuncType(ft *types.Func) bool {
+	np := ft.Params.NumFields()
+	return np > 0 && strings.Contains(ft.Params.FieldType(np-1).String(), magicLastTypeName)
+}
+
+// getParam returns the Field of ith param of node n (which is a
+// function/method/interface call), where the receiver of a method call is
+// considered as the 0th parameter. This does not include the receiver of an
+// interface call.
+func getParam(n *ir.CallExpr, i int) *types.Field {
+	t := n.X.Type()
+	if n.Op() == ir.OCALLMETH {
+		base.Fatalf("OCALLMETH missed by walkCall")
+	}
+	return t.Params().Field(i)
+}
+
+// dvarint writes a varint v to the funcdata in symbol x and returns the new offset
+func dvarint(x *obj.LSym, off int, v int64) int {
+	if v < 0 || v > 1e9 {
+		panic(fmt.Sprintf("dvarint: bad offset for funcdata - %v", v))
+	}
+	if v < 1<<7 {
+		return objw.Uint8(x, off, uint8(v))
+	}
+	off = objw.Uint8(x, off, uint8((v&127)|128))
+	if v < 1<<14 {
+		return objw.Uint8(x, off, uint8(v>>7))
+	}
+	off = objw.Uint8(x, off, uint8(((v>>7)&127)|128))
+	if v < 1<<21 {
+		return objw.Uint8(x, off, uint8(v>>14))
+	}
+	off = objw.Uint8(x, off, uint8(((v>>14)&127)|128))
+	if v < 1<<28 {
+		return objw.Uint8(x, off, uint8(v>>21))
+	}
+	off = objw.Uint8(x, off, uint8(((v>>21)&127)|128))
+	return objw.Uint8(x, off, uint8(v>>28))
+}
+
+// emitOpenDeferInfo emits FUNCDATA information about the defers in a function
+// that is using open-coded defers.  This funcdata is used to determine the active
+// defers in a function and execute those defers during panic processing.
+//
+// The funcdata is all encoded in varints (since values will almost always be less than
+// 128, but stack offsets could potentially be up to 2Gbyte). All "locations" (offsets)
+// for stack variables are specified as the number of bytes below varp (pointer to the
+// top of the local variables) for their starting address. The format is:
+//
+//  - Max total argument size among all the defers
+//  - Offset of the deferBits variable
+//  - Number of defers in the function
+//  - Information about each defer call, in reverse order of appearance in the function:
+//    - Total argument size of the call
+//    - Offset of the closure value to call
+//    - Number of arguments (including interface receiver or method receiver as first arg)
+//    - Information about each argument
+//      - Offset of the stored defer argument in this function's frame
+//      - Size of the argument
+//      - Offset of where argument should be placed in the args frame when making call
+func (s *state) emitOpenDeferInfo() {
+	x := base.Ctxt.Lookup(s.curfn.LSym.Name + ".opendefer")
+	s.curfn.LSym.Func().OpenCodedDeferInfo = x
+	off := 0
+
+	// Compute maxargsize (max size of arguments for all defers)
+	// first, so we can output it first to the funcdata
+	var maxargsize int64
+	for i := len(s.openDefers) - 1; i >= 0; i-- {
+		r := s.openDefers[i]
+		argsize := r.n.X.Type().ArgWidth() // TODO register args: but maybe use of abi0 will make this easy
+		if argsize > maxargsize {
+			maxargsize = argsize
+		}
+	}
+	off = dvarint(x, off, maxargsize)
+	off = dvarint(x, off, -s.deferBitsTemp.FrameOffset())
+	off = dvarint(x, off, int64(len(s.openDefers)))
+
+	// Write in reverse-order, for ease of running in that order at runtime
+	for i := len(s.openDefers) - 1; i >= 0; i-- {
+		r := s.openDefers[i]
+		off = dvarint(x, off, r.n.X.Type().ArgWidth())
+		off = dvarint(x, off, -r.closureNode.FrameOffset())
+		numArgs := len(r.argNodes)
+		if r.rcvrNode != nil {
+			// If there's an interface receiver, treat/place it as the first
+			// arg. (If there is a method receiver, it's already included as
+			// first arg in r.argNodes.)
+			numArgs++
+		}
+		off = dvarint(x, off, int64(numArgs))
+		argAdjust := 0 // presence of receiver offsets the parameter count.
+		if r.rcvrNode != nil {
+			off = dvarint(x, off, -okOffset(r.rcvrNode.FrameOffset()))
+			off = dvarint(x, off, s.config.PtrSize)
+			off = dvarint(x, off, 0) // This is okay because defer records use ABI0 (for now)
+			argAdjust++
+		}
+
+		// TODO(register args) assume abi0 for this?
+		ab := s.f.ABI0
+		pri := ab.ABIAnalyzeFuncType(r.n.X.Type().FuncType())
+		for j, arg := range r.argNodes {
+			f := getParam(r.n, j)
+			off = dvarint(x, off, -okOffset(arg.FrameOffset()))
+			off = dvarint(x, off, f.Type.Size())
+			off = dvarint(x, off, okOffset(pri.InParam(j+argAdjust).FrameOffset(pri)))
+		}
+	}
+}
+
+func okOffset(offset int64) int64 {
+	if offset == types.BOGUS_FUNARG_OFFSET {
+		panic(fmt.Errorf("Bogus offset %d", offset))
+	}
+	return offset
+}
+
+// buildssa builds an SSA function for fn.
+// worker indicates which of the backend workers is doing the processing.
+func buildssa(fn *ir.Func, worker int) *ssa.Func {
+	name := ir.FuncName(fn)
+	printssa := false
+	if ssaDump != "" { // match either a simple name e.g. "(*Reader).Reset", package.name e.g. "compress/gzip.(*Reader).Reset", or subpackage name "gzip.(*Reader).Reset"
+		pkgDotName := base.Ctxt.Pkgpath + "." + name
+		printssa = name == ssaDump ||
+			strings.HasSuffix(pkgDotName, ssaDump) && (pkgDotName == ssaDump || strings.HasSuffix(pkgDotName, "/"+ssaDump))
+	}
+	var astBuf *bytes.Buffer
+	if printssa {
+		astBuf = &bytes.Buffer{}
+		ir.FDumpList(astBuf, "buildssa-enter", fn.Enter)
+		ir.FDumpList(astBuf, "buildssa-body", fn.Body)
+		ir.FDumpList(astBuf, "buildssa-exit", fn.Exit)
+		if ssaDumpStdout {
+			fmt.Println("generating SSA for", name)
+			fmt.Print(astBuf.String())
+		}
+	}
+
+	var s state
+	s.pushLine(fn.Pos())
+	defer s.popLine()
+
+	s.hasdefer = fn.HasDefer()
+	if fn.Pragma&ir.CgoUnsafeArgs != 0 {
+		s.cgoUnsafeArgs = true
+	}
+
+	fe := ssafn{
+		curfn: fn,
+		log:   printssa && ssaDumpStdout,
+	}
+	s.curfn = fn
+
+	s.f = ssa.NewFunc(&fe)
+	s.config = ssaConfig
+	s.f.Type = fn.Type()
+	s.f.Config = ssaConfig
+	s.f.Cache = &ssaCaches[worker]
+	s.f.Cache.Reset()
+	s.f.Name = name
+	s.f.DebugTest = s.f.DebugHashMatch("GOSSAHASH")
+	s.f.PrintOrHtmlSSA = printssa
+	if fn.Pragma&ir.Nosplit != 0 {
+		s.f.NoSplit = true
+	}
+	s.f.ABI0 = ssaConfig.ABI0.Copy() // Make a copy to avoid racy map operations in type-register-width cache.
+	s.f.ABI1 = ssaConfig.ABI1.Copy()
+	s.f.ABIDefault = abiForFunc(nil, s.f.ABI0, s.f.ABI1)
+	s.f.ABISelf = abiForFunc(fn, s.f.ABI0, s.f.ABI1)
+
+	s.panics = map[funcLine]*ssa.Block{}
+	s.softFloat = s.config.SoftFloat
+
+	// Allocate starting block
+	s.f.Entry = s.f.NewBlock(ssa.BlockPlain)
+	s.f.Entry.Pos = fn.Pos()
+
+	if printssa {
+		ssaDF := ssaDumpFile
+		if ssaDir != "" {
+			ssaDF = filepath.Join(ssaDir, base.Ctxt.Pkgpath+"."+name+".html")
+			ssaD := filepath.Dir(ssaDF)
+			os.MkdirAll(ssaD, 0755)
+		}
+		s.f.HTMLWriter = ssa.NewHTMLWriter(ssaDF, s.f, ssaDumpCFG)
+		// TODO: generate and print a mapping from nodes to values and blocks
+		dumpSourcesColumn(s.f.HTMLWriter, fn)
+		s.f.HTMLWriter.WriteAST("AST", astBuf)
+	}
+
+	// Allocate starting values
+	s.labels = map[string]*ssaLabel{}
+	s.fwdVars = map[ir.Node]*ssa.Value{}
+	s.startmem = s.entryNewValue0(ssa.OpInitMem, types.TypeMem)
+
+	s.hasOpenDefers = base.Flag.N == 0 && s.hasdefer && !s.curfn.OpenCodedDeferDisallowed()
+	switch {
+	case base.Debug.NoOpenDefer != 0:
+		s.hasOpenDefers = false
+	case s.hasOpenDefers && (base.Ctxt.Flag_shared || base.Ctxt.Flag_dynlink) && base.Ctxt.Arch.Name == "386":
+		// Don't support open-coded defers for 386 ONLY when using shared
+		// libraries, because there is extra code (added by rewriteToUseGot())
+		// preceding the deferreturn/ret code that we don't track correctly.
+		s.hasOpenDefers = false
+	}
+	if s.hasOpenDefers && len(s.curfn.Exit) > 0 {
+		// Skip doing open defers if there is any extra exit code (likely
+		// race detection), since we will not generate that code in the
+		// case of the extra deferreturn/ret segment.
+		s.hasOpenDefers = false
+	}
+	if s.hasOpenDefers {
+		// Similarly, skip if there are any heap-allocated result
+		// parameters that need to be copied back to their stack slots.
+		for _, f := range s.curfn.Type().Results().FieldSlice() {
+			if !f.Nname.(*ir.Name).OnStack() {
+				s.hasOpenDefers = false
+				break
+			}
+		}
+	}
+	if s.hasOpenDefers &&
+		s.curfn.NumReturns*s.curfn.NumDefers > 15 {
+		// Since we are generating defer calls at every exit for
+		// open-coded defers, skip doing open-coded defers if there are
+		// too many returns (especially if there are multiple defers).
+		// Open-coded defers are most important for improving performance
+		// for smaller functions (which don't have many returns).
+		s.hasOpenDefers = false
+	}
+
+	s.sp = s.entryNewValue0(ssa.OpSP, types.Types[types.TUINTPTR]) // TODO: use generic pointer type (unsafe.Pointer?) instead
+	s.sb = s.entryNewValue0(ssa.OpSB, types.Types[types.TUINTPTR])
+
+	s.startBlock(s.f.Entry)
+	s.vars[memVar] = s.startmem
+	if s.hasOpenDefers {
+		// Create the deferBits variable and stack slot.  deferBits is a
+		// bitmask showing which of the open-coded defers in this function
+		// have been activated.
+		deferBitsTemp := typecheck.TempAt(src.NoXPos, s.curfn, types.Types[types.TUINT8])
+		deferBitsTemp.SetAddrtaken(true)
+		s.deferBitsTemp = deferBitsTemp
+		// For this value, AuxInt is initialized to zero by default
+		startDeferBits := s.entryNewValue0(ssa.OpConst8, types.Types[types.TUINT8])
+		s.vars[deferBitsVar] = startDeferBits
+		s.deferBitsAddr = s.addr(deferBitsTemp)
+		s.store(types.Types[types.TUINT8], s.deferBitsAddr, startDeferBits)
+		// Make sure that the deferBits stack slot is kept alive (for use
+		// by panics) and stores to deferBits are not eliminated, even if
+		// all checking code on deferBits in the function exit can be
+		// eliminated, because the defer statements were all
+		// unconditional.
+		s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, deferBitsTemp, s.mem(), false)
+	}
+
+	var params *abi.ABIParamResultInfo
+	params = s.f.ABISelf.ABIAnalyze(fn.Type(), true)
+
+	// Generate addresses of local declarations
+	s.decladdrs = map[*ir.Name]*ssa.Value{}
+	for _, n := range fn.Dcl {
+		switch n.Class {
+		case ir.PPARAM:
+			// Be aware that blank and unnamed input parameters will not appear here, but do appear in the type
+			s.decladdrs[n] = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(n.Type()), n, s.sp, s.startmem)
+		case ir.PPARAMOUT:
+			s.decladdrs[n] = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(n.Type()), n, s.sp, s.startmem)
+		case ir.PAUTO:
+			// processed at each use, to prevent Addr coming
+			// before the decl.
+		default:
+			s.Fatalf("local variable with class %v unimplemented", n.Class)
+		}
+	}
+
+	s.f.OwnAux = ssa.OwnAuxCall(fn.LSym, params)
+
+	// Populate SSAable arguments.
+	for _, n := range fn.Dcl {
+		if n.Class == ir.PPARAM {
+			if s.canSSA(n) {
+				v := s.newValue0A(ssa.OpArg, n.Type(), n)
+				s.vars[n] = v
+				s.addNamedValue(n, v) // This helps with debugging information, not needed for compilation itself.
+			} else { // address was taken AND/OR too large for SSA
+				paramAssignment := ssa.ParamAssignmentForArgName(s.f, n)
+				if len(paramAssignment.Registers) > 0 {
+					if TypeOK(n.Type()) { // SSA-able type, so address was taken -- receive value in OpArg, DO NOT bind to var, store immediately to memory.
+						v := s.newValue0A(ssa.OpArg, n.Type(), n)
+						s.store(n.Type(), s.decladdrs[n], v)
+					} else { // Too big for SSA.
+						// Brute force, and early, do a bunch of stores from registers
+						// TODO fix the nasty storeArgOrLoad recursion in ssa/expand_calls.go so this Just Works with store of a big Arg.
+						s.storeParameterRegsToStack(s.f.ABISelf, paramAssignment, n, s.decladdrs[n], false)
+					}
+				}
+			}
+		}
+	}
+
+	// Populate closure variables.
+	if !fn.ClosureCalled() {
+		clo := s.entryNewValue0(ssa.OpGetClosurePtr, s.f.Config.Types.BytePtr)
+		offset := int64(types.PtrSize) // PtrSize to skip past function entry PC field
+		for _, n := range fn.ClosureVars {
+			typ := n.Type()
+			if !n.Byval() {
+				typ = types.NewPtr(typ)
+			}
+
+			offset = types.Rnd(offset, typ.Alignment())
+			ptr := s.newValue1I(ssa.OpOffPtr, types.NewPtr(typ), offset, clo)
+			offset += typ.Size()
+
+			// If n is a small variable captured by value, promote
+			// it to PAUTO so it can be converted to SSA.
+			//
+			// Note: While we never capture a variable by value if
+			// the user took its address, we may have generated
+			// runtime calls that did (#43701). Since we don't
+			// convert Addrtaken variables to SSA anyway, no point
+			// in promoting them either.
+			if n.Byval() && !n.Addrtaken() && TypeOK(n.Type()) {
+				n.Class = ir.PAUTO
+				fn.Dcl = append(fn.Dcl, n)
+				s.assign(n, s.load(n.Type(), ptr), false, 0)
+				continue
+			}
+
+			if !n.Byval() {
+				ptr = s.load(typ, ptr)
+			}
+			s.setHeapaddr(fn.Pos(), n, ptr)
+		}
+	}
+
+	// Convert the AST-based IR to the SSA-based IR
+	s.stmtList(fn.Enter)
+	s.zeroResults()
+	s.paramsToHeap()
+	s.stmtList(fn.Body)
+
+	// fallthrough to exit
+	if s.curBlock != nil {
+		s.pushLine(fn.Endlineno)
+		s.exit()
+		s.popLine()
+	}
+
+	for _, b := range s.f.Blocks {
+		if b.Pos != src.NoXPos {
+			s.updateUnsetPredPos(b)
+		}
+	}
+
+	s.f.HTMLWriter.WritePhase("before insert phis", "before insert phis")
+
+	s.insertPhis()
+
+	// Main call to ssa package to compile function
+	ssa.Compile(s.f)
+
+	if s.hasOpenDefers {
+		s.emitOpenDeferInfo()
+	}
+
+	// Record incoming parameter spill information for morestack calls emitted in the assembler.
+	// This is done here, using all the parameters (used, partially used, and unused) because
+	// it mimics the behavior of the former ABI (everything stored) and because it's not 100%
+	// clear if naming conventions are respected in autogenerated code.
+	// TODO figure out exactly what's unused, don't spill it. Make liveness fine-grained, also.
+	// TODO non-amd64 architectures have link registers etc that may require adjustment here.
+	for _, p := range params.InParams() {
+		typs, offs := p.RegisterTypesAndOffsets()
+		for i, t := range typs {
+			o := offs[i]                // offset within parameter
+			fo := p.FrameOffset(params) // offset of parameter in frame
+			reg := ssa.ObjRegForAbiReg(p.Registers[i], s.f.Config)
+			s.f.RegArgs = append(s.f.RegArgs, ssa.Spill{Reg: reg, Offset: fo + o, Type: t})
+		}
+	}
+
+	return s.f
+}
+
+func (s *state) storeParameterRegsToStack(abi *abi.ABIConfig, paramAssignment *abi.ABIParamAssignment, n *ir.Name, addr *ssa.Value, pointersOnly bool) {
+	typs, offs := paramAssignment.RegisterTypesAndOffsets()
+	for i, t := range typs {
+		if pointersOnly && !t.IsPtrShaped() {
+			continue
+		}
+		r := paramAssignment.Registers[i]
+		o := offs[i]
+		op, reg := ssa.ArgOpAndRegisterFor(r, abi)
+		aux := &ssa.AuxNameOffset{Name: n, Offset: o}
+		v := s.newValue0I(op, t, reg)
+		v.Aux = aux
+		p := s.newValue1I(ssa.OpOffPtr, types.NewPtr(t), o, addr)
+		s.store(t, p, v)
+	}
+}
+
+// zeroResults zeros the return values at the start of the function.
+// We need to do this very early in the function.  Defer might stop a
+// panic and show the return values as they exist at the time of
+// panic.  For precise stacks, the garbage collector assumes results
+// are always live, so we need to zero them before any allocations,
+// even allocations to move params/results to the heap.
+func (s *state) zeroResults() {
+	for _, f := range s.curfn.Type().Results().FieldSlice() {
+		n := f.Nname.(*ir.Name)
+		if !n.OnStack() {
+			// The local which points to the return value is the
+			// thing that needs zeroing. This is already handled
+			// by a Needzero annotation in plive.go:(*liveness).epilogue.
+			continue
+		}
+		// Zero the stack location containing f.
+		if typ := n.Type(); TypeOK(typ) {
+			s.assign(n, s.zeroVal(typ), false, 0)
+		} else {
+			s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
+			s.zero(n.Type(), s.decladdrs[n])
+		}
+	}
+}
+
+// paramsToHeap produces code to allocate memory for heap-escaped parameters
+// and to copy non-result parameters' values from the stack.
+func (s *state) paramsToHeap() {
+	do := func(params *types.Type) {
+		for _, f := range params.FieldSlice() {
+			if f.Nname == nil {
+				continue // anonymous or blank parameter
+			}
+			n := f.Nname.(*ir.Name)
+			if ir.IsBlank(n) || n.OnStack() {
+				continue
+			}
+			s.newHeapaddr(n)
+			if n.Class == ir.PPARAM {
+				s.move(n.Type(), s.expr(n.Heapaddr), s.decladdrs[n])
+			}
+		}
+	}
+
+	typ := s.curfn.Type()
+	do(typ.Recvs())
+	do(typ.Params())
+	do(typ.Results())
+}
+
+// newHeapaddr allocates heap memory for n and sets its heap address.
+func (s *state) newHeapaddr(n *ir.Name) {
+	s.setHeapaddr(n.Pos(), n, s.newObject(n.Type()))
+}
+
+// setHeapaddr allocates a new PAUTO variable to store ptr (which must be non-nil)
+// and then sets it as n's heap address.
+func (s *state) setHeapaddr(pos src.XPos, n *ir.Name, ptr *ssa.Value) {
+	if !ptr.Type.IsPtr() || !types.Identical(n.Type(), ptr.Type.Elem()) {
+		base.FatalfAt(n.Pos(), "setHeapaddr %L with type %v", n, ptr.Type)
+	}
+
+	// Declare variable to hold address.
+	addr := ir.NewNameAt(pos, &types.Sym{Name: "&" + n.Sym().Name, Pkg: types.LocalPkg})
+	addr.SetType(types.NewPtr(n.Type()))
+	addr.Class = ir.PAUTO
+	addr.SetUsed(true)
+	addr.Curfn = s.curfn
+	s.curfn.Dcl = append(s.curfn.Dcl, addr)
+	types.CalcSize(addr.Type())
+
+	if n.Class == ir.PPARAMOUT {
+		addr.SetIsOutputParamHeapAddr(true)
+	}
+
+	n.Heapaddr = addr
+	s.assign(addr, ptr, false, 0)
+}
+
+// newObject returns an SSA value denoting new(typ).
+func (s *state) newObject(typ *types.Type) *ssa.Value {
+	if typ.Size() == 0 {
+		return s.newValue1A(ssa.OpAddr, types.NewPtr(typ), ir.Syms.Zerobase, s.sb)
+	}
+	return s.rtcall(ir.Syms.Newobject, true, []*types.Type{types.NewPtr(typ)}, s.reflectType(typ))[0]
+}
+
+// reflectType returns an SSA value representing a pointer to typ's
+// reflection type descriptor.
+func (s *state) reflectType(typ *types.Type) *ssa.Value {
+	lsym := reflectdata.TypeLinksym(typ)
+	return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(types.Types[types.TUINT8]), lsym, s.sb)
+}
+
+func dumpSourcesColumn(writer *ssa.HTMLWriter, fn *ir.Func) {
+	// Read sources of target function fn.
+	fname := base.Ctxt.PosTable.Pos(fn.Pos()).Filename()
+	targetFn, err := readFuncLines(fname, fn.Pos().Line(), fn.Endlineno.Line())
+	if err != nil {
+		writer.Logf("cannot read sources for function %v: %v", fn, err)
+	}
+
+	// Read sources of inlined functions.
+	var inlFns []*ssa.FuncLines
+	for _, fi := range ssaDumpInlined {
+		elno := fi.Endlineno
+		fname := base.Ctxt.PosTable.Pos(fi.Pos()).Filename()
+		fnLines, err := readFuncLines(fname, fi.Pos().Line(), elno.Line())
+		if err != nil {
+			writer.Logf("cannot read sources for inlined function %v: %v", fi, err)
+			continue
+		}
+		inlFns = append(inlFns, fnLines)
+	}
+
+	sort.Sort(ssa.ByTopo(inlFns))
+	if targetFn != nil {
+		inlFns = append([]*ssa.FuncLines{targetFn}, inlFns...)
+	}
+
+	writer.WriteSources("sources", inlFns)
+}
+
+func readFuncLines(file string, start, end uint) (*ssa.FuncLines, error) {
+	f, err := os.Open(os.ExpandEnv(file))
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	var lines []string
+	ln := uint(1)
+	scanner := bufio.NewScanner(f)
+	for scanner.Scan() && ln <= end {
+		if ln >= start {
+			lines = append(lines, scanner.Text())
+		}
+		ln++
+	}
+	return &ssa.FuncLines{Filename: file, StartLineno: start, Lines: lines}, nil
+}
+
+// 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.
+	}
+}
+
+// Information about each open-coded defer.
+type openDeferInfo struct {
+	// The node representing the call of the defer
+	n *ir.CallExpr
+	// If defer call is closure call, the address of the argtmp where the
+	// closure is stored.
+	closure *ssa.Value
+	// The node representing the argtmp where the closure is stored - used for
+	// function, method, or interface call, to store a closure that panic
+	// processing can use for this defer.
+	closureNode *ir.Name
+	// If defer call is interface call, the address of the argtmp where the
+	// receiver is stored
+	rcvr *ssa.Value
+	// The node representing the argtmp where the receiver is stored
+	rcvrNode *ir.Name
+	// The addresses of the argtmps where the evaluated arguments of the defer
+	// function call are stored.
+	argVals []*ssa.Value
+	// The nodes representing the argtmps where the args of the defer are stored
+	argNodes []*ir.Name
+}
+
+type state struct {
+	// configuration (arch) information
+	config *ssa.Config
+
+	// function we're building
+	f *ssa.Func
+
+	// Node for function
+	curfn *ir.Func
+
+	// labels in f
+	labels map[string]*ssaLabel
+
+	// unlabeled break and continue statement tracking
+	breakTo    *ssa.Block // current target for plain break statement
+	continueTo *ssa.Block // current target for plain continue statement
+
+	// current location where we're interpreting the AST
+	curBlock *ssa.Block
+
+	// variable assignments in the current block (map from variable symbol to ssa value)
+	// *Node is the unique identifier (an ONAME Node) for the variable.
+	// TODO: keep a single varnum map, then make all of these maps slices instead?
+	vars map[ir.Node]*ssa.Value
+
+	// fwdVars are variables that are used before they are defined in the current block.
+	// This map exists just to coalesce multiple references into a single FwdRef op.
+	// *Node is the unique identifier (an ONAME Node) for the variable.
+	fwdVars map[ir.Node]*ssa.Value
+
+	// all defined variables at the end of each block. Indexed by block ID.
+	defvars []map[ir.Node]*ssa.Value
+
+	// addresses of PPARAM and PPARAMOUT variables on the stack.
+	decladdrs map[*ir.Name]*ssa.Value
+
+	// starting values. Memory, stack pointer, and globals pointer
+	startmem *ssa.Value
+	sp       *ssa.Value
+	sb       *ssa.Value
+	// value representing address of where deferBits autotmp is stored
+	deferBitsAddr *ssa.Value
+	deferBitsTemp *ir.Name
+
+	// 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.
+	panics map[funcLine]*ssa.Block
+
+	cgoUnsafeArgs bool
+	hasdefer      bool // whether the function contains a defer statement
+	softFloat     bool
+	hasOpenDefers bool // whether we are doing open-coded defers
+
+	// If doing open-coded defers, list of info about the defer calls in
+	// scanning order. Hence, at exit we should run these defers in reverse
+	// order of this list
+	openDefers []*openDeferInfo
+	// For open-coded defers, this is the beginning and end blocks of the last
+	// defer exit code that we have generated so far. We use these to share
+	// code between exits if the shareDeferExits option (disabled by default)
+	// is on.
+	lastDeferExit       *ssa.Block // Entry block of last defer exit code we generated
+	lastDeferFinalBlock *ssa.Block // Final block of last defer exit code we generated
+	lastDeferCount      int        // Number of defers encountered at that point
+
+	prevCall *ssa.Value // the previous call; use this to tie results to the call op.
+}
+
+type funcLine struct {
+	f    *obj.LSym
+	base *src.PosBase
+	line uint
+}
+
+type ssaLabel struct {
+	target         *ssa.Block // block identified by this label
+	breakTarget    *ssa.Block // block to break to in control flow node identified by this label
+	continueTarget *ssa.Block // block to continue to in control flow node identified by this label
+}
+
+// label returns the label associated with sym, creating it if necessary.
+func (s *state) label(sym *types.Sym) *ssaLabel {
+	lab := s.labels[sym.Name]
+	if lab == nil {
+		lab = new(ssaLabel)
+		s.labels[sym.Name] = lab
+	}
+	return lab
+}
+
+func (s *state) Logf(msg string, args ...interface{}) { s.f.Logf(msg, args...) }
+func (s *state) Log() bool                            { return s.f.Log() }
+func (s *state) Fatalf(msg string, args ...interface{}) {
+	s.f.Frontend().Fatalf(s.peekPos(), msg, args...)
+}
+func (s *state) Warnl(pos src.XPos, msg string, args ...interface{}) { s.f.Warnl(pos, msg, args...) }
+func (s *state) Debug_checknil() bool                                { return s.f.Frontend().Debug_checknil() }
+
+func ssaMarker(name string) *ir.Name {
+	return typecheck.NewName(&types.Sym{Name: name})
+}
+
+var (
+	// marker node for the memory variable
+	memVar = ssaMarker("mem")
+
+	// marker nodes for temporary variables
+	ptrVar       = ssaMarker("ptr")
+	lenVar       = ssaMarker("len")
+	newlenVar    = ssaMarker("newlen")
+	capVar       = ssaMarker("cap")
+	typVar       = ssaMarker("typ")
+	okVar        = ssaMarker("ok")
+	deferBitsVar = ssaMarker("deferBits")
+)
+
+// startBlock sets the current block we're generating code in to b.
+func (s *state) startBlock(b *ssa.Block) {
+	if s.curBlock != nil {
+		s.Fatalf("starting block %v when block %v has not ended", b, s.curBlock)
+	}
+	s.curBlock = b
+	s.vars = map[ir.Node]*ssa.Value{}
+	for n := range s.fwdVars {
+		delete(s.fwdVars, n)
+	}
+}
+
+// endBlock marks the end of generating code for the current block.
+// Returns the (former) current block. Returns nil if there is no current
+// block, i.e. if no code flows to the current execution point.
+func (s *state) endBlock() *ssa.Block {
+	b := s.curBlock
+	if b == nil {
+		return nil
+	}
+	for len(s.defvars) <= int(b.ID) {
+		s.defvars = append(s.defvars, nil)
+	}
+	s.defvars[b.ID] = s.vars
+	s.curBlock = nil
+	s.vars = nil
+	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
+}
+
+// pushLine pushes a line number on the line number stack.
+func (s *state) pushLine(line src.XPos) {
+	if !line.IsKnown() {
+		// the frontend may emit node with line number missing,
+		// use the parent line number in this case.
+		line = s.peekPos()
+		if base.Flag.K != 0 {
+			base.Warn("buildssa: unknown position (line 0)")
+		}
+	} else {
+		s.lastPos = line
+	}
+
+	s.line = append(s.line, line)
+}
+
+// popLine pops the top of the line number stack.
+func (s *state) popLine() {
+	s.line = s.line[:len(s.line)-1]
+}
+
+// peekPos peeks the top of the line number stack.
+func (s *state) peekPos() src.XPos {
+	return s.line[len(s.line)-1]
+}
+
+// newValue0 adds a new value with no arguments to the current block.
+func (s *state) newValue0(op ssa.Op, t *types.Type) *ssa.Value {
+	return s.curBlock.NewValue0(s.peekPos(), op, t)
+}
+
+// newValue0A adds a new value with no arguments and an aux value to the current block.
+func (s *state) newValue0A(op ssa.Op, t *types.Type, aux ssa.Aux) *ssa.Value {
+	return s.curBlock.NewValue0A(s.peekPos(), op, t, aux)
+}
+
+// newValue0I adds a new value with no arguments and an auxint value to the current block.
+func (s *state) newValue0I(op ssa.Op, t *types.Type, auxint int64) *ssa.Value {
+	return s.curBlock.NewValue0I(s.peekPos(), op, t, auxint)
+}
+
+// newValue1 adds a new value with one argument to the current block.
+func (s *state) newValue1(op ssa.Op, t *types.Type, arg *ssa.Value) *ssa.Value {
+	return s.curBlock.NewValue1(s.peekPos(), op, t, arg)
+}
+
+// newValue1A adds a new value with one argument and an aux value to the current block.
+func (s *state) newValue1A(op ssa.Op, t *types.Type, aux ssa.Aux, arg *ssa.Value) *ssa.Value {
+	return s.curBlock.NewValue1A(s.peekPos(), op, t, aux, arg)
+}
+
+// newValue1Apos adds a new value with one argument and an aux value to the current block.
+// isStmt determines whether the created values may be a statement or not
+// (i.e., false means never, yes means maybe).
+func (s *state) newValue1Apos(op ssa.Op, t *types.Type, aux ssa.Aux, arg *ssa.Value, isStmt bool) *ssa.Value {
+	if isStmt {
+		return s.curBlock.NewValue1A(s.peekPos(), op, t, aux, arg)
+	}
+	return s.curBlock.NewValue1A(s.peekPos().WithNotStmt(), op, t, aux, arg)
+}
+
+// newValue1I adds a new value with one argument and an auxint value to the current block.
+func (s *state) newValue1I(op ssa.Op, t *types.Type, aux int64, arg *ssa.Value) *ssa.Value {
+	return s.curBlock.NewValue1I(s.peekPos(), op, t, aux, arg)
+}
+
+// newValue2 adds a new value with two arguments to the current block.
+func (s *state) newValue2(op ssa.Op, t *types.Type, arg0, arg1 *ssa.Value) *ssa.Value {
+	return s.curBlock.NewValue2(s.peekPos(), op, t, arg0, arg1)
+}
+
+// newValue2A adds a new value with two arguments and an aux value to the current block.
+func (s *state) newValue2A(op ssa.Op, t *types.Type, aux ssa.Aux, arg0, arg1 *ssa.Value) *ssa.Value {
+	return s.curBlock.NewValue2A(s.peekPos(), op, t, aux, arg0, arg1)
+}
+
+// newValue2Apos adds a new value with two arguments and an aux value to the current block.
+// isStmt determines whether the created values may be a statement or not
+// (i.e., false means never, yes means maybe).
+func (s *state) newValue2Apos(op ssa.Op, t *types.Type, aux ssa.Aux, arg0, arg1 *ssa.Value, isStmt bool) *ssa.Value {
+	if isStmt {
+		return s.curBlock.NewValue2A(s.peekPos(), op, t, aux, arg0, arg1)
+	}
+	return s.curBlock.NewValue2A(s.peekPos().WithNotStmt(), op, t, aux, arg0, arg1)
+}
+
+// newValue2I adds a new value with two arguments and an auxint value to the current block.
+func (s *state) newValue2I(op ssa.Op, t *types.Type, aux int64, arg0, arg1 *ssa.Value) *ssa.Value {
+	return s.curBlock.NewValue2I(s.peekPos(), op, t, aux, arg0, arg1)
+}
+
+// newValue3 adds a new value with three arguments to the current block.
+func (s *state) newValue3(op ssa.Op, t *types.Type, arg0, arg1, arg2 *ssa.Value) *ssa.Value {
+	return s.curBlock.NewValue3(s.peekPos(), op, t, arg0, arg1, arg2)
+}
+
+// newValue3I adds a new value with three arguments and an auxint value to the current block.
+func (s *state) newValue3I(op ssa.Op, t *types.Type, aux int64, arg0, arg1, arg2 *ssa.Value) *ssa.Value {
+	return s.curBlock.NewValue3I(s.peekPos(), op, t, aux, arg0, arg1, arg2)
+}
+
+// newValue3A adds a new value with three arguments and an aux value to the current block.
+func (s *state) newValue3A(op ssa.Op, t *types.Type, aux ssa.Aux, arg0, arg1, arg2 *ssa.Value) *ssa.Value {
+	return s.curBlock.NewValue3A(s.peekPos(), op, t, aux, arg0, arg1, arg2)
+}
+
+// newValue3Apos adds a new value with three arguments and an aux value to the current block.
+// isStmt determines whether the created values may be a statement or not
+// (i.e., false means never, yes means maybe).
+func (s *state) newValue3Apos(op ssa.Op, t *types.Type, aux ssa.Aux, arg0, arg1, arg2 *ssa.Value, isStmt bool) *ssa.Value {
+	if isStmt {
+		return s.curBlock.NewValue3A(s.peekPos(), op, t, aux, arg0, arg1, arg2)
+	}
+	return s.curBlock.NewValue3A(s.peekPos().WithNotStmt(), op, t, aux, arg0, arg1, arg2)
+}
+
+// newValue4 adds a new value with four arguments to the current block.
+func (s *state) newValue4(op ssa.Op, t *types.Type, arg0, arg1, arg2, arg3 *ssa.Value) *ssa.Value {
+	return s.curBlock.NewValue4(s.peekPos(), op, t, arg0, arg1, arg2, arg3)
+}
+
+// newValue4 adds a new value with four arguments and an auxint value to the current block.
+func (s *state) newValue4I(op ssa.Op, t *types.Type, aux int64, arg0, arg1, arg2, arg3 *ssa.Value) *ssa.Value {
+	return s.curBlock.NewValue4I(s.peekPos(), op, t, aux, arg0, arg1, arg2, arg3)
+}
+
+func (s *state) entryBlock() *ssa.Block {
+	b := s.f.Entry
+	if base.Flag.N > 0 && s.curBlock != nil {
+		// If optimizations are off, allocate in current block instead. Since with -N
+		// we're not doing the CSE or tighten passes, putting lots of stuff in the
+		// entry block leads to O(n^2) entries in the live value map during regalloc.
+		// See issue 45897.
+		b = s.curBlock
+	}
+	return b
+}
+
+// entryNewValue0 adds a new value with no arguments to the entry block.
+func (s *state) entryNewValue0(op ssa.Op, t *types.Type) *ssa.Value {
+	return s.entryBlock().NewValue0(src.NoXPos, op, t)
+}
+
+// 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 ssa.Aux) *ssa.Value {
+	return s.entryBlock().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.entryBlock().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.entryBlock().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 ssa.Aux, arg *ssa.Value) *ssa.Value {
+	return s.entryBlock().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.entryBlock().NewValue2(src.NoXPos, op, t, arg0, arg1)
+}
+
+// entryNewValue2A adds a new value with two arguments and an aux value to the entry block.
+func (s *state) entryNewValue2A(op ssa.Op, t *types.Type, aux ssa.Aux, arg0, arg1 *ssa.Value) *ssa.Value {
+	return s.entryBlock().NewValue2A(src.NoXPos, op, t, aux, arg0, arg1)
+}
+
+// const* routines add a new const value to the entry block.
+func (s *state) constSlice(t *types.Type) *ssa.Value {
+	return s.f.ConstSlice(t)
+}
+func (s *state) constInterface(t *types.Type) *ssa.Value {
+	return s.f.ConstInterface(t)
+}
+func (s *state) constNil(t *types.Type) *ssa.Value { return s.f.ConstNil(t) }
+func (s *state) constEmptyString(t *types.Type) *ssa.Value {
+	return s.f.ConstEmptyString(t)
+}
+func (s *state) constBool(c bool) *ssa.Value {
+	return s.f.ConstBool(types.Types[types.TBOOL], c)
+}
+func (s *state) constInt8(t *types.Type, c int8) *ssa.Value {
+	return s.f.ConstInt8(t, c)
+}
+func (s *state) constInt16(t *types.Type, c int16) *ssa.Value {
+	return s.f.ConstInt16(t, c)
+}
+func (s *state) constInt32(t *types.Type, c int32) *ssa.Value {
+	return s.f.ConstInt32(t, c)
+}
+func (s *state) constInt64(t *types.Type, c int64) *ssa.Value {
+	return s.f.ConstInt64(t, c)
+}
+func (s *state) constFloat32(t *types.Type, c float64) *ssa.Value {
+	return s.f.ConstFloat32(t, c)
+}
+func (s *state) constFloat64(t *types.Type, c float64) *ssa.Value {
+	return s.f.ConstFloat64(t, c)
+}
+func (s *state) constInt(t *types.Type, c int64) *ssa.Value {
+	if s.config.PtrSize == 8 {
+		return s.constInt64(t, c)
+	}
+	if int64(int32(c)) != c {
+		s.Fatalf("integer constant too big %d", c)
+	}
+	return s.constInt32(t, int32(c))
+}
+func (s *state) constOffPtrSP(t *types.Type, c int64) *ssa.Value {
+	return s.f.ConstOffPtrSP(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)
+}
+
+type instrumentKind uint8
+
+const (
+	instrumentRead = iota
+	instrumentWrite
+	instrumentMove
+)
+
+func (s *state) instrument(t *types.Type, addr *ssa.Value, kind instrumentKind) {
+	s.instrument2(t, addr, nil, kind)
+}
+
+// instrumentFields instruments a read/write operation on addr.
+// If it is instrumenting for MSAN and t is a struct type, it instruments
+// operation for each field, instead of for the whole struct.
+func (s *state) instrumentFields(t *types.Type, addr *ssa.Value, kind instrumentKind) {
+	if !base.Flag.MSan || !t.IsStruct() {
+		s.instrument(t, addr, kind)
+		return
+	}
+	for _, f := range t.Fields().Slice() {
+		if f.Sym.IsBlank() {
+			continue
+		}
+		offptr := s.newValue1I(ssa.OpOffPtr, types.NewPtr(f.Type), f.Offset, addr)
+		s.instrumentFields(f.Type, offptr, kind)
+	}
+}
+
+func (s *state) instrumentMove(t *types.Type, dst, src *ssa.Value) {
+	if base.Flag.MSan {
+		s.instrument2(t, dst, src, instrumentMove)
+	} else {
+		s.instrument(t, src, instrumentRead)
+		s.instrument(t, dst, instrumentWrite)
+	}
+}
+
+func (s *state) instrument2(t *types.Type, addr, addr2 *ssa.Value, kind instrumentKind) {
+	if !s.curfn.InstrumentBody() {
+		return
+	}
+
+	w := t.Size()
+	if w == 0 {
+		return // can't race on zero-sized things
+	}
+
+	if ssa.IsSanitizerSafeAddr(addr) {
+		return
+	}
+
+	var fn *obj.LSym
+	needWidth := false
+
+	if addr2 != nil && kind != instrumentMove {
+		panic("instrument2: non-nil addr2 for non-move instrumentation")
+	}
+
+	if base.Flag.MSan {
+		switch kind {
+		case instrumentRead:
+			fn = ir.Syms.Msanread
+		case instrumentWrite:
+			fn = ir.Syms.Msanwrite
+		case instrumentMove:
+			fn = ir.Syms.Msanmove
+		default:
+			panic("unreachable")
+		}
+		needWidth = true
+	} else if base.Flag.Race && t.NumComponents(types.CountBlankFields) > 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.
+		switch kind {
+		case instrumentRead:
+			fn = ir.Syms.Racereadrange
+		case instrumentWrite:
+			fn = ir.Syms.Racewriterange
+		default:
+			panic("unreachable")
+		}
+		needWidth = true
+	} else if base.Flag.Race {
+		// for non-composite objects we can write just the start
+		// address, as any write must write the first byte.
+		switch kind {
+		case instrumentRead:
+			fn = ir.Syms.Raceread
+		case instrumentWrite:
+			fn = ir.Syms.Racewrite
+		default:
+			panic("unreachable")
+		}
+	} else {
+		panic("unreachable")
+	}
+
+	args := []*ssa.Value{addr}
+	if addr2 != nil {
+		args = append(args, addr2)
+	}
+	if needWidth {
+		args = append(args, s.constInt(types.Types[types.TUINTPTR], w))
+	}
+	s.rtcall(fn, true, nil, args...)
+}
+
+func (s *state) load(t *types.Type, src *ssa.Value) *ssa.Value {
+	s.instrumentFields(t, src, instrumentRead)
+	return s.rawLoad(t, src)
+}
+
+func (s *state) rawLoad(t *types.Type, src *ssa.Value) *ssa.Value {
+	return s.newValue2(ssa.OpLoad, t, src, s.mem())
+}
+
+func (s *state) store(t *types.Type, dst, val *ssa.Value) {
+	s.vars[memVar] = s.newValue3A(ssa.OpStore, types.TypeMem, t, dst, val, s.mem())
+}
+
+func (s *state) zero(t *types.Type, dst *ssa.Value) {
+	s.instrument(t, dst, instrumentWrite)
+	store := s.newValue2I(ssa.OpZero, types.TypeMem, t.Size(), dst, s.mem())
+	store.Aux = t
+	s.vars[memVar] = store
+}
+
+func (s *state) move(t *types.Type, dst, src *ssa.Value) {
+	s.instrumentMove(t, dst, src)
+	store := s.newValue3I(ssa.OpMove, types.TypeMem, t.Size(), dst, src, s.mem())
+	store.Aux = t
+	s.vars[memVar] = store
+}
+
+// stmtList converts the statement list n to SSA and adds it to s.
+func (s *state) stmtList(l ir.Nodes) {
+	for _, n := range l {
+		s.stmt(n)
+	}
+}
+
+// stmt converts the statement n to SSA and adds it to s.
+func (s *state) stmt(n ir.Node) {
+	if !(n.Op() == ir.OVARKILL || n.Op() == ir.OVARLIVE || n.Op() == ir.OVARDEF) {
+		// OVARKILL, OVARLIVE, and OVARDEF are invisible to the programmer, so we don't use their line numbers to avoid confusion in debugging.
+		s.pushLine(n.Pos())
+		defer s.popLine()
+	}
+
+	// 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.
+	if s.curBlock == nil && n.Op() != ir.OLABEL {
+		return
+	}
+
+	s.stmtList(n.Init())
+	switch n.Op() {
+
+	case ir.OBLOCK:
+		n := n.(*ir.BlockStmt)
+		s.stmtList(n.List)
+
+	// No-ops
+	case ir.ODCLCONST, ir.ODCLTYPE, ir.OFALL:
+
+	// Expression statements
+	case ir.OCALLFUNC:
+		n := n.(*ir.CallExpr)
+		if ir.IsIntrinsicCall(n) {
+			s.intrinsicCall(n)
+			return
+		}
+		fallthrough
+
+	case ir.OCALLINTER:
+		n := n.(*ir.CallExpr)
+		s.callResult(n, callNormal)
+		if n.Op() == ir.OCALLFUNC && n.X.Op() == ir.ONAME && n.X.(*ir.Name).Class == ir.PFUNC {
+			if fn := n.X.Sym().Name; base.Flag.CompilingRuntime && fn == "throw" ||
+				n.X.Sym().Pkg == ir.Pkgs.Runtime && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap") {
+				m := s.mem()
+				b := s.endBlock()
+				b.Kind = ssa.BlockExit
+				b.SetControl(m)
+				// TODO: never rewrite OPANIC to OCALLFUNC in the
+				// first place. Need to wait until all backends
+				// go through SSA.
+			}
+		}
+	case ir.ODEFER:
+		n := n.(*ir.GoDeferStmt)
+		if base.Debug.Defer > 0 {
+			var defertype string
+			if s.hasOpenDefers {
+				defertype = "open-coded"
+			} else if n.Esc() == ir.EscNever {
+				defertype = "stack-allocated"
+			} else {
+				defertype = "heap-allocated"
+			}
+			base.WarnfAt(n.Pos(), "%s defer", defertype)
+		}
+		if s.hasOpenDefers {
+			s.openDeferRecord(n.Call.(*ir.CallExpr))
+		} else {
+			d := callDefer
+			if n.Esc() == ir.EscNever {
+				d = callDeferStack
+			}
+			s.callResult(n.Call.(*ir.CallExpr), d)
+		}
+	case ir.OGO:
+		n := n.(*ir.GoDeferStmt)
+		s.callResult(n.Call.(*ir.CallExpr), callGo)
+
+	case ir.OAS2DOTTYPE:
+		n := n.(*ir.AssignListStmt)
+		res, resok := s.dottype(n.Rhs[0].(*ir.TypeAssertExpr), true)
+		deref := false
+		if !TypeOK(n.Rhs[0].Type()) {
+			if res.Op != ssa.OpLoad {
+				s.Fatalf("dottype of non-load")
+			}
+			mem := s.mem()
+			if mem.Op == ssa.OpVarKill {
+				mem = mem.Args[0]
+			}
+			if res.Args[1] != mem {
+				s.Fatalf("memory no longer live from 2-result dottype load")
+			}
+			deref = true
+			res = res.Args[0]
+		}
+		s.assign(n.Lhs[0], res, deref, 0)
+		s.assign(n.Lhs[1], resok, false, 0)
+		return
+
+	case ir.OAS2FUNC:
+		// We come here only when it is an intrinsic call returning two values.
+		n := n.(*ir.AssignListStmt)
+		call := n.Rhs[0].(*ir.CallExpr)
+		if !ir.IsIntrinsicCall(call) {
+			s.Fatalf("non-intrinsic AS2FUNC not expanded %v", call)
+		}
+		v := s.intrinsicCall(call)
+		v1 := s.newValue1(ssa.OpSelect0, n.Lhs[0].Type(), v)
+		v2 := s.newValue1(ssa.OpSelect1, n.Lhs[1].Type(), v)
+		s.assign(n.Lhs[0], v1, false, 0)
+		s.assign(n.Lhs[1], v2, false, 0)
+		return
+
+	case ir.ODCL:
+		n := n.(*ir.Decl)
+		if v := n.X; v.Esc() == ir.EscHeap {
+			s.newHeapaddr(v)
+		}
+
+	case ir.OLABEL:
+		n := n.(*ir.LabelStmt)
+		sym := n.Label
+		lab := s.label(sym)
+
+		// The label might already have a target block via a goto.
+		if lab.target == nil {
+			lab.target = s.f.NewBlock(ssa.BlockPlain)
+		}
+
+		// Go to that label.
+		// (We pretend "label:" is preceded by "goto label", unless the predecessor is unreachable.)
+		if s.curBlock != nil {
+			b := s.endBlock()
+			b.AddEdgeTo(lab.target)
+		}
+		s.startBlock(lab.target)
+
+	case ir.OGOTO:
+		n := n.(*ir.BranchStmt)
+		sym := n.Label
+
+		lab := s.label(sym)
+		if lab.target == nil {
+			lab.target = s.f.NewBlock(ssa.BlockPlain)
+		}
+
+		b := s.endBlock()
+		b.Pos = s.lastPos.WithIsStmt() // Do this even if b is an empty block.
+		b.AddEdgeTo(lab.target)
+
+	case ir.OAS:
+		n := n.(*ir.AssignStmt)
+		if n.X == n.Y && n.X.Op() == ir.ONAME {
+			// An x=x assignment. No point in doing anything
+			// here. In addition, skipping this assignment
+			// prevents generating:
+			//   VARDEF x
+			//   COPY x -> x
+			// which is bad because x is incorrectly considered
+			// dead before the vardef. See issue #14904.
+			return
+		}
+
+		// Evaluate RHS.
+		rhs := n.Y
+		if rhs != nil {
+			switch rhs.Op() {
+			case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT:
+				// All literals with nonzero fields have already been
+				// rewritten during walk. Any that remain are just T{}
+				// or equivalents. Use the zero value.
+				if !ir.IsZero(rhs) {
+					s.Fatalf("literal with nonzero value in SSA: %v", rhs)
+				}
+				rhs = nil
+			case ir.OAPPEND:
+				rhs := rhs.(*ir.CallExpr)
+				// 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 !ir.SameSafeExpr(n.X, rhs.Args[0]) || base.Flag.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 s.canSSA(n.X) {
+					if base.Debug.Append > 0 { // replicating old diagnostic message
+						base.WarnfAt(n.Pos(), "append: len-only update (in local slice)")
+					}
+					break
+				}
+				if base.Debug.Append > 0 {
+					base.WarnfAt(n.Pos(), "append: len-only update")
+				}
+				s.append(rhs, true)
+				return
+			}
+		}
+
+		if ir.IsBlank(n.X) {
+			// _ = rhs
+			// Just evaluate rhs for side-effects.
+			if rhs != nil {
+				s.expr(rhs)
+			}
+			return
+		}
+
+		var t *types.Type
+		if n.Y != nil {
+			t = n.Y.Type()
+		} else {
+			t = n.X.Type()
+		}
+
+		var r *ssa.Value
+		deref := !TypeOK(t)
+		if deref {
+			if rhs == nil {
+				r = nil // Signal assign to use OpZero.
+			} else {
+				r = s.addr(rhs)
+			}
+		} else {
+			if rhs == nil {
+				r = s.zeroVal(t)
+			} else {
+				r = s.expr(rhs)
+			}
+		}
+
+		var skip skipMask
+		if rhs != nil && (rhs.Op() == ir.OSLICE || rhs.Op() == ir.OSLICE3 || rhs.Op() == ir.OSLICESTR) && ir.SameSafeExpr(rhs.(*ir.SliceExpr).X, n.X) {
+			// We're assigning a slicing operation back to its source.
+			// Don't write back fields we aren't changing. See issue #14855.
+			rhs := rhs.(*ir.SliceExpr)
+			i, j, k := rhs.Low, rhs.High, rhs.Max
+			if i != nil && (i.Op() == ir.OLITERAL && i.Val().Kind() == constant.Int && ir.Int64Val(i) == 0) {
+				// [0:...] is the same as [:...]
+				i = nil
+			}
+			// TODO: detect defaults for len/cap also.
+			// Currently doesn't really work because (*p)[:len(*p)] appears here as:
+			//    tmp = len(*p)
+			//    (*p)[:tmp]
+			//if j != nil && (j.Op == OLEN && SameSafeExpr(j.Left, n.Left)) {
+			//      j = nil
+			//}
+			//if k != nil && (k.Op == OCAP && SameSafeExpr(k.Left, n.Left)) {
+			//      k = nil
+			//}
+			if i == nil {
+				skip |= skipPtr
+				if j == nil {
+					skip |= skipLen
+				}
+				if k == nil {
+					skip |= skipCap
+				}
+			}
+		}
+
+		s.assign(n.X, r, deref, skip)
+
+	case ir.OIF:
+		n := n.(*ir.IfStmt)
+		if ir.IsConst(n.Cond, constant.Bool) {
+			s.stmtList(n.Cond.Init())
+			if ir.BoolVal(n.Cond) {
+				s.stmtList(n.Body)
+			} else {
+				s.stmtList(n.Else)
+			}
+			break
+		}
+
+		bEnd := s.f.NewBlock(ssa.BlockPlain)
+		var likely int8
+		if n.Likely {
+			likely = 1
+		}
+		var bThen *ssa.Block
+		if len(n.Body) != 0 {
+			bThen = s.f.NewBlock(ssa.BlockPlain)
+		} else {
+			bThen = bEnd
+		}
+		var bElse *ssa.Block
+		if len(n.Else) != 0 {
+			bElse = s.f.NewBlock(ssa.BlockPlain)
+		} else {
+			bElse = bEnd
+		}
+		s.condBranch(n.Cond, bThen, bElse, likely)
+
+		if len(n.Body) != 0 {
+			s.startBlock(bThen)
+			s.stmtList(n.Body)
+			if b := s.endBlock(); b != nil {
+				b.AddEdgeTo(bEnd)
+			}
+		}
+		if len(n.Else) != 0 {
+			s.startBlock(bElse)
+			s.stmtList(n.Else)
+			if b := s.endBlock(); b != nil {
+				b.AddEdgeTo(bEnd)
+			}
+		}
+		s.startBlock(bEnd)
+
+	case ir.ORETURN:
+		n := n.(*ir.ReturnStmt)
+		s.stmtList(n.Results)
+		b := s.exit()
+		b.Pos = s.lastPos.WithIsStmt()
+
+	case ir.OTAILCALL:
+		n := n.(*ir.TailCallStmt)
+		b := s.exit()
+		b.Kind = ssa.BlockRetJmp // override BlockRet
+		b.Aux = callTargetLSym(n.Target)
+
+	case ir.OCONTINUE, ir.OBREAK:
+		n := n.(*ir.BranchStmt)
+		var to *ssa.Block
+		if n.Label == nil {
+			// plain break/continue
+			switch n.Op() {
+			case ir.OCONTINUE:
+				to = s.continueTo
+			case ir.OBREAK:
+				to = s.breakTo
+			}
+		} else {
+			// labeled break/continue; look up the target
+			sym := n.Label
+			lab := s.label(sym)
+			switch n.Op() {
+			case ir.OCONTINUE:
+				to = lab.continueTarget
+			case ir.OBREAK:
+				to = lab.breakTarget
+			}
+		}
+
+		b := s.endBlock()
+		b.Pos = s.lastPos.WithIsStmt() // Do this even if b is an empty block.
+		b.AddEdgeTo(to)
+
+	case ir.OFOR, ir.OFORUNTIL:
+		// OFOR: for Ninit; Left; Right { Nbody }
+		// cond (Left); body (Nbody); incr (Right)
+		//
+		// OFORUNTIL: for Ninit; Left; Right; List { Nbody }
+		// => body: { Nbody }; incr: Right; if Left { lateincr: List; goto body }; end:
+		n := n.(*ir.ForStmt)
+		bCond := s.f.NewBlock(ssa.BlockPlain)
+		bBody := s.f.NewBlock(ssa.BlockPlain)
+		bIncr := s.f.NewBlock(ssa.BlockPlain)
+		bEnd := s.f.NewBlock(ssa.BlockPlain)
+
+		// ensure empty for loops have correct position; issue #30167
+		bBody.Pos = n.Pos()
+
+		// first, jump to condition test (OFOR) or body (OFORUNTIL)
+		b := s.endBlock()
+		if n.Op() == ir.OFOR {
+			b.AddEdgeTo(bCond)
+			// generate code to test condition
+			s.startBlock(bCond)
+			if n.Cond != nil {
+				s.condBranch(n.Cond, bBody, bEnd, 1)
+			} else {
+				b := s.endBlock()
+				b.Kind = ssa.BlockPlain
+				b.AddEdgeTo(bBody)
+			}
+
+		} else {
+			b.AddEdgeTo(bBody)
+		}
+
+		// set up for continue/break in body
+		prevContinue := s.continueTo
+		prevBreak := s.breakTo
+		s.continueTo = bIncr
+		s.breakTo = bEnd
+		var lab *ssaLabel
+		if sym := n.Label; sym != nil {
+			// labeled for loop
+			lab = s.label(sym)
+			lab.continueTarget = bIncr
+			lab.breakTarget = bEnd
+		}
+
+		// generate body
+		s.startBlock(bBody)
+		s.stmtList(n.Body)
+
+		// tear down continue/break
+		s.continueTo = prevContinue
+		s.breakTo = prevBreak
+		if lab != nil {
+			lab.continueTarget = nil
+			lab.breakTarget = nil
+		}
+
+		// done with body, goto incr
+		if b := s.endBlock(); b != nil {
+			b.AddEdgeTo(bIncr)
+		}
+
+		// generate incr (and, for OFORUNTIL, condition)
+		s.startBlock(bIncr)
+		if n.Post != nil {
+			s.stmt(n.Post)
+		}
+		if n.Op() == ir.OFOR {
+			if b := s.endBlock(); b != nil {
+				b.AddEdgeTo(bCond)
+				// It can happen that bIncr ends in a block containing only VARKILL,
+				// and that muddles the debugging experience.
+				if b.Pos == src.NoXPos {
+					b.Pos = bCond.Pos
+				}
+			}
+		} else {
+			// bCond is unused in OFORUNTIL, so repurpose it.
+			bLateIncr := bCond
+			// test condition
+			s.condBranch(n.Cond, bLateIncr, bEnd, 1)
+			// generate late increment
+			s.startBlock(bLateIncr)
+			s.stmtList(n.Late)
+			s.endBlock().AddEdgeTo(bBody)
+		}
+
+		s.startBlock(bEnd)
+
+	case ir.OSWITCH, ir.OSELECT:
+		// These have been mostly rewritten by the front end into their Nbody fields.
+		// Our main task is to correctly hook up any break statements.
+		bEnd := s.f.NewBlock(ssa.BlockPlain)
+
+		prevBreak := s.breakTo
+		s.breakTo = bEnd
+		var sym *types.Sym
+		var body ir.Nodes
+		if n.Op() == ir.OSWITCH {
+			n := n.(*ir.SwitchStmt)
+			sym = n.Label
+			body = n.Compiled
+		} else {
+			n := n.(*ir.SelectStmt)
+			sym = n.Label
+			body = n.Compiled
+		}
+
+		var lab *ssaLabel
+		if sym != nil {
+			// labeled
+			lab = s.label(sym)
+			lab.breakTarget = bEnd
+		}
+
+		// generate body code
+		s.stmtList(body)
+
+		s.breakTo = prevBreak
+		if lab != nil {
+			lab.breakTarget = nil
+		}
+
+		// walk adds explicit OBREAK nodes to the end of all reachable code paths.
+		// If we still have a current block here, then mark it unreachable.
+		if s.curBlock != nil {
+			m := s.mem()
+			b := s.endBlock()
+			b.Kind = ssa.BlockExit
+			b.SetControl(m)
+		}
+		s.startBlock(bEnd)
+
+	case ir.OVARDEF:
+		n := n.(*ir.UnaryExpr)
+		if !s.canSSA(n.X) {
+			s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, n.X.(*ir.Name), s.mem(), false)
+		}
+	case ir.OVARKILL:
+		// Insert a varkill op to record that a variable is no longer live.
+		// We only care about liveness info at call sites, so putting the
+		// varkill in the store chain is enough to keep it correctly ordered
+		// with respect to call ops.
+		n := n.(*ir.UnaryExpr)
+		if !s.canSSA(n.X) {
+			s.vars[memVar] = s.newValue1Apos(ssa.OpVarKill, types.TypeMem, n.X.(*ir.Name), s.mem(), false)
+		}
+
+	case ir.OVARLIVE:
+		// Insert a varlive op to record that a variable is still live.
+		n := n.(*ir.UnaryExpr)
+		v := n.X.(*ir.Name)
+		if !v.Addrtaken() {
+			s.Fatalf("VARLIVE variable %v must have Addrtaken set", v)
+		}
+		switch v.Class {
+		case ir.PAUTO, ir.PPARAM, ir.PPARAMOUT:
+		default:
+			s.Fatalf("VARLIVE variable %v must be Auto or Arg", v)
+		}
+		s.vars[memVar] = s.newValue1A(ssa.OpVarLive, types.TypeMem, v, s.mem())
+
+	case ir.OCHECKNIL:
+		n := n.(*ir.UnaryExpr)
+		p := s.expr(n.X)
+		s.nilCheck(p)
+
+	case ir.OINLMARK:
+		n := n.(*ir.InlineMarkStmt)
+		s.newValue1I(ssa.OpInlMark, types.TypeVoid, n.Index, s.mem())
+
+	default:
+		s.Fatalf("unhandled stmt %v", n.Op())
+	}
+}
+
+// If true, share as many open-coded defer exits as possible (with the downside of
+// worse line-number information)
+const shareDeferExits = false
+
+// exit processes any code that needs to be generated just before returning.
+// It returns a BlockRet block that ends the control flow. Its control value
+// will be set to the final memory state.
+func (s *state) exit() *ssa.Block {
+	if s.hasdefer {
+		if s.hasOpenDefers {
+			if shareDeferExits && s.lastDeferExit != nil && len(s.openDefers) == s.lastDeferCount {
+				if s.curBlock.Kind != ssa.BlockPlain {
+					panic("Block for an exit should be BlockPlain")
+				}
+				s.curBlock.AddEdgeTo(s.lastDeferExit)
+				s.endBlock()
+				return s.lastDeferFinalBlock
+			}
+			s.openDeferExit()
+		} else {
+			s.rtcall(ir.Syms.Deferreturn, true, nil)
+		}
+	}
+
+	var b *ssa.Block
+	var m *ssa.Value
+	// Do actual return.
+	// These currently turn into self-copies (in many cases).
+	resultFields := s.curfn.Type().Results().FieldSlice()
+	results := make([]*ssa.Value, len(resultFields)+1, len(resultFields)+1)
+	m = s.newValue0(ssa.OpMakeResult, s.f.OwnAux.LateExpansionResultType())
+	// Store SSAable and heap-escaped PPARAMOUT variables back to stack locations.
+	for i, f := range resultFields {
+		n := f.Nname.(*ir.Name)
+		if s.canSSA(n) { // result is in some SSA variable
+			if !n.IsOutputParamInRegisters() {
+				// We are about to store to the result slot.
+				s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
+			}
+			results[i] = s.variable(n, n.Type())
+		} else if !n.OnStack() { // result is actually heap allocated
+			// We are about to copy the in-heap result to the result slot.
+			s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
+			ha := s.expr(n.Heapaddr)
+			s.instrumentFields(n.Type(), ha, instrumentRead)
+			results[i] = s.newValue2(ssa.OpDereference, n.Type(), ha, s.mem())
+		} else { // result is not SSA-able; not escaped, so not on heap, but too large for SSA.
+			// Before register ABI this ought to be a self-move, home=dest,
+			// With register ABI, it's still a self-move if parameter is on stack (i.e., too big or overflowed)
+			// No VarDef, as the result slot is already holding live value.
+			results[i] = s.newValue2(ssa.OpDereference, n.Type(), s.addr(n), s.mem())
+		}
+	}
+
+	// Run exit code. Today, this is just racefuncexit, in -race mode.
+	// TODO(register args) this seems risky here with a register-ABI, but not clear it is right to do it earlier either.
+	// Spills in register allocation might just fix it.
+	s.stmtList(s.curfn.Exit)
+
+	results[len(results)-1] = s.mem()
+	m.AddArgs(results...)
+
+	b = s.endBlock()
+	b.Kind = ssa.BlockRet
+	b.SetControl(m)
+	if s.hasdefer && s.hasOpenDefers {
+		s.lastDeferFinalBlock = b
+	}
+	return b
+}
+
+type opAndType struct {
+	op    ir.Op
+	etype types.Kind
+}
+
+var opToSSA = map[opAndType]ssa.Op{
+	opAndType{ir.OADD, types.TINT8}:    ssa.OpAdd8,
+	opAndType{ir.OADD, types.TUINT8}:   ssa.OpAdd8,
+	opAndType{ir.OADD, types.TINT16}:   ssa.OpAdd16,
+	opAndType{ir.OADD, types.TUINT16}:  ssa.OpAdd16,
+	opAndType{ir.OADD, types.TINT32}:   ssa.OpAdd32,
+	opAndType{ir.OADD, types.TUINT32}:  ssa.OpAdd32,
+	opAndType{ir.OADD, types.TINT64}:   ssa.OpAdd64,
+	opAndType{ir.OADD, types.TUINT64}:  ssa.OpAdd64,
+	opAndType{ir.OADD, types.TFLOAT32}: ssa.OpAdd32F,
+	opAndType{ir.OADD, types.TFLOAT64}: ssa.OpAdd64F,
+
+	opAndType{ir.OSUB, types.TINT8}:    ssa.OpSub8,
+	opAndType{ir.OSUB, types.TUINT8}:   ssa.OpSub8,
+	opAndType{ir.OSUB, types.TINT16}:   ssa.OpSub16,
+	opAndType{ir.OSUB, types.TUINT16}:  ssa.OpSub16,
+	opAndType{ir.OSUB, types.TINT32}:   ssa.OpSub32,
+	opAndType{ir.OSUB, types.TUINT32}:  ssa.OpSub32,
+	opAndType{ir.OSUB, types.TINT64}:   ssa.OpSub64,
+	opAndType{ir.OSUB, types.TUINT64}:  ssa.OpSub64,
+	opAndType{ir.OSUB, types.TFLOAT32}: ssa.OpSub32F,
+	opAndType{ir.OSUB, types.TFLOAT64}: ssa.OpSub64F,
+
+	opAndType{ir.ONOT, types.TBOOL}: ssa.OpNot,
+
+	opAndType{ir.ONEG, types.TINT8}:    ssa.OpNeg8,
+	opAndType{ir.ONEG, types.TUINT8}:   ssa.OpNeg8,
+	opAndType{ir.ONEG, types.TINT16}:   ssa.OpNeg16,
+	opAndType{ir.ONEG, types.TUINT16}:  ssa.OpNeg16,
+	opAndType{ir.ONEG, types.TINT32}:   ssa.OpNeg32,
+	opAndType{ir.ONEG, types.TUINT32}:  ssa.OpNeg32,
+	opAndType{ir.ONEG, types.TINT64}:   ssa.OpNeg64,
+	opAndType{ir.ONEG, types.TUINT64}:  ssa.OpNeg64,
+	opAndType{ir.ONEG, types.TFLOAT32}: ssa.OpNeg32F,
+	opAndType{ir.ONEG, types.TFLOAT64}: ssa.OpNeg64F,
+
+	opAndType{ir.OBITNOT, types.TINT8}:   ssa.OpCom8,
+	opAndType{ir.OBITNOT, types.TUINT8}:  ssa.OpCom8,
+	opAndType{ir.OBITNOT, types.TINT16}:  ssa.OpCom16,
+	opAndType{ir.OBITNOT, types.TUINT16}: ssa.OpCom16,
+	opAndType{ir.OBITNOT, types.TINT32}:  ssa.OpCom32,
+	opAndType{ir.OBITNOT, types.TUINT32}: ssa.OpCom32,
+	opAndType{ir.OBITNOT, types.TINT64}:  ssa.OpCom64,
+	opAndType{ir.OBITNOT, types.TUINT64}: ssa.OpCom64,
+
+	opAndType{ir.OIMAG, types.TCOMPLEX64}:  ssa.OpComplexImag,
+	opAndType{ir.OIMAG, types.TCOMPLEX128}: ssa.OpComplexImag,
+	opAndType{ir.OREAL, types.TCOMPLEX64}:  ssa.OpComplexReal,
+	opAndType{ir.OREAL, types.TCOMPLEX128}: ssa.OpComplexReal,
+
+	opAndType{ir.OMUL, types.TINT8}:    ssa.OpMul8,
+	opAndType{ir.OMUL, types.TUINT8}:   ssa.OpMul8,
+	opAndType{ir.OMUL, types.TINT16}:   ssa.OpMul16,
+	opAndType{ir.OMUL, types.TUINT16}:  ssa.OpMul16,
+	opAndType{ir.OMUL, types.TINT32}:   ssa.OpMul32,
+	opAndType{ir.OMUL, types.TUINT32}:  ssa.OpMul32,
+	opAndType{ir.OMUL, types.TINT64}:   ssa.OpMul64,
+	opAndType{ir.OMUL, types.TUINT64}:  ssa.OpMul64,
+	opAndType{ir.OMUL, types.TFLOAT32}: ssa.OpMul32F,
+	opAndType{ir.OMUL, types.TFLOAT64}: ssa.OpMul64F,
+
+	opAndType{ir.ODIV, types.TFLOAT32}: ssa.OpDiv32F,
+	opAndType{ir.ODIV, types.TFLOAT64}: ssa.OpDiv64F,
+
+	opAndType{ir.ODIV, types.TINT8}:   ssa.OpDiv8,
+	opAndType{ir.ODIV, types.TUINT8}:  ssa.OpDiv8u,
+	opAndType{ir.ODIV, types.TINT16}:  ssa.OpDiv16,
+	opAndType{ir.ODIV, types.TUINT16}: ssa.OpDiv16u,
+	opAndType{ir.ODIV, types.TINT32}:  ssa.OpDiv32,
+	opAndType{ir.ODIV, types.TUINT32}: ssa.OpDiv32u,
+	opAndType{ir.ODIV, types.TINT64}:  ssa.OpDiv64,
+	opAndType{ir.ODIV, types.TUINT64}: ssa.OpDiv64u,
+
+	opAndType{ir.OMOD, types.TINT8}:   ssa.OpMod8,
+	opAndType{ir.OMOD, types.TUINT8}:  ssa.OpMod8u,
+	opAndType{ir.OMOD, types.TINT16}:  ssa.OpMod16,
+	opAndType{ir.OMOD, types.TUINT16}: ssa.OpMod16u,
+	opAndType{ir.OMOD, types.TINT32}:  ssa.OpMod32,
+	opAndType{ir.OMOD, types.TUINT32}: ssa.OpMod32u,
+	opAndType{ir.OMOD, types.TINT64}:  ssa.OpMod64,
+	opAndType{ir.OMOD, types.TUINT64}: ssa.OpMod64u,
+
+	opAndType{ir.OAND, types.TINT8}:   ssa.OpAnd8,
+	opAndType{ir.OAND, types.TUINT8}:  ssa.OpAnd8,
+	opAndType{ir.OAND, types.TINT16}:  ssa.OpAnd16,
+	opAndType{ir.OAND, types.TUINT16}: ssa.OpAnd16,
+	opAndType{ir.OAND, types.TINT32}:  ssa.OpAnd32,
+	opAndType{ir.OAND, types.TUINT32}: ssa.OpAnd32,
+	opAndType{ir.OAND, types.TINT64}:  ssa.OpAnd64,
+	opAndType{ir.OAND, types.TUINT64}: ssa.OpAnd64,
+
+	opAndType{ir.OOR, types.TINT8}:   ssa.OpOr8,
+	opAndType{ir.OOR, types.TUINT8}:  ssa.OpOr8,
+	opAndType{ir.OOR, types.TINT16}:  ssa.OpOr16,
+	opAndType{ir.OOR, types.TUINT16}: ssa.OpOr16,
+	opAndType{ir.OOR, types.TINT32}:  ssa.OpOr32,
+	opAndType{ir.OOR, types.TUINT32}: ssa.OpOr32,
+	opAndType{ir.OOR, types.TINT64}:  ssa.OpOr64,
+	opAndType{ir.OOR, types.TUINT64}: ssa.OpOr64,
+
+	opAndType{ir.OXOR, types.TINT8}:   ssa.OpXor8,
+	opAndType{ir.OXOR, types.TUINT8}:  ssa.OpXor8,
+	opAndType{ir.OXOR, types.TINT16}:  ssa.OpXor16,
+	opAndType{ir.OXOR, types.TUINT16}: ssa.OpXor16,
+	opAndType{ir.OXOR, types.TINT32}:  ssa.OpXor32,
+	opAndType{ir.OXOR, types.TUINT32}: ssa.OpXor32,
+	opAndType{ir.OXOR, types.TINT64}:  ssa.OpXor64,
+	opAndType{ir.OXOR, types.TUINT64}: ssa.OpXor64,
+
+	opAndType{ir.OEQ, types.TBOOL}:      ssa.OpEqB,
+	opAndType{ir.OEQ, types.TINT8}:      ssa.OpEq8,
+	opAndType{ir.OEQ, types.TUINT8}:     ssa.OpEq8,
+	opAndType{ir.OEQ, types.TINT16}:     ssa.OpEq16,
+	opAndType{ir.OEQ, types.TUINT16}:    ssa.OpEq16,
+	opAndType{ir.OEQ, types.TINT32}:     ssa.OpEq32,
+	opAndType{ir.OEQ, types.TUINT32}:    ssa.OpEq32,
+	opAndType{ir.OEQ, types.TINT64}:     ssa.OpEq64,
+	opAndType{ir.OEQ, types.TUINT64}:    ssa.OpEq64,
+	opAndType{ir.OEQ, types.TINTER}:     ssa.OpEqInter,
+	opAndType{ir.OEQ, types.TSLICE}:     ssa.OpEqSlice,
+	opAndType{ir.OEQ, types.TFUNC}:      ssa.OpEqPtr,
+	opAndType{ir.OEQ, types.TMAP}:       ssa.OpEqPtr,
+	opAndType{ir.OEQ, types.TCHAN}:      ssa.OpEqPtr,
+	opAndType{ir.OEQ, types.TPTR}:       ssa.OpEqPtr,
+	opAndType{ir.OEQ, types.TUINTPTR}:   ssa.OpEqPtr,
+	opAndType{ir.OEQ, types.TUNSAFEPTR}: ssa.OpEqPtr,
+	opAndType{ir.OEQ, types.TFLOAT64}:   ssa.OpEq64F,
+	opAndType{ir.OEQ, types.TFLOAT32}:   ssa.OpEq32F,
+
+	opAndType{ir.ONE, types.TBOOL}:      ssa.OpNeqB,
+	opAndType{ir.ONE, types.TINT8}:      ssa.OpNeq8,
+	opAndType{ir.ONE, types.TUINT8}:     ssa.OpNeq8,
+	opAndType{ir.ONE, types.TINT16}:     ssa.OpNeq16,
+	opAndType{ir.ONE, types.TUINT16}:    ssa.OpNeq16,
+	opAndType{ir.ONE, types.TINT32}:     ssa.OpNeq32,
+	opAndType{ir.ONE, types.TUINT32}:    ssa.OpNeq32,
+	opAndType{ir.ONE, types.TINT64}:     ssa.OpNeq64,
+	opAndType{ir.ONE, types.TUINT64}:    ssa.OpNeq64,
+	opAndType{ir.ONE, types.TINTER}:     ssa.OpNeqInter,
+	opAndType{ir.ONE, types.TSLICE}:     ssa.OpNeqSlice,
+	opAndType{ir.ONE, types.TFUNC}:      ssa.OpNeqPtr,
+	opAndType{ir.ONE, types.TMAP}:       ssa.OpNeqPtr,
+	opAndType{ir.ONE, types.TCHAN}:      ssa.OpNeqPtr,
+	opAndType{ir.ONE, types.TPTR}:       ssa.OpNeqPtr,
+	opAndType{ir.ONE, types.TUINTPTR}:   ssa.OpNeqPtr,
+	opAndType{ir.ONE, types.TUNSAFEPTR}: ssa.OpNeqPtr,
+	opAndType{ir.ONE, types.TFLOAT64}:   ssa.OpNeq64F,
+	opAndType{ir.ONE, types.TFLOAT32}:   ssa.OpNeq32F,
+
+	opAndType{ir.OLT, types.TINT8}:    ssa.OpLess8,
+	opAndType{ir.OLT, types.TUINT8}:   ssa.OpLess8U,
+	opAndType{ir.OLT, types.TINT16}:   ssa.OpLess16,
+	opAndType{ir.OLT, types.TUINT16}:  ssa.OpLess16U,
+	opAndType{ir.OLT, types.TINT32}:   ssa.OpLess32,
+	opAndType{ir.OLT, types.TUINT32}:  ssa.OpLess32U,
+	opAndType{ir.OLT, types.TINT64}:   ssa.OpLess64,
+	opAndType{ir.OLT, types.TUINT64}:  ssa.OpLess64U,
+	opAndType{ir.OLT, types.TFLOAT64}: ssa.OpLess64F,
+	opAndType{ir.OLT, types.TFLOAT32}: ssa.OpLess32F,
+
+	opAndType{ir.OLE, types.TINT8}:    ssa.OpLeq8,
+	opAndType{ir.OLE, types.TUINT8}:   ssa.OpLeq8U,
+	opAndType{ir.OLE, types.TINT16}:   ssa.OpLeq16,
+	opAndType{ir.OLE, types.TUINT16}:  ssa.OpLeq16U,
+	opAndType{ir.OLE, types.TINT32}:   ssa.OpLeq32,
+	opAndType{ir.OLE, types.TUINT32}:  ssa.OpLeq32U,
+	opAndType{ir.OLE, types.TINT64}:   ssa.OpLeq64,
+	opAndType{ir.OLE, types.TUINT64}:  ssa.OpLeq64U,
+	opAndType{ir.OLE, types.TFLOAT64}: ssa.OpLeq64F,
+	opAndType{ir.OLE, types.TFLOAT32}: ssa.OpLeq32F,
+}
+
+func (s *state) concreteEtype(t *types.Type) types.Kind {
+	e := t.Kind()
+	switch e {
+	default:
+		return e
+	case types.TINT:
+		if s.config.PtrSize == 8 {
+			return types.TINT64
+		}
+		return types.TINT32
+	case types.TUINT:
+		if s.config.PtrSize == 8 {
+			return types.TUINT64
+		}
+		return types.TUINT32
+	case types.TUINTPTR:
+		if s.config.PtrSize == 8 {
+			return types.TUINT64
+		}
+		return types.TUINT32
+	}
+}
+
+func (s *state) ssaOp(op ir.Op, t *types.Type) ssa.Op {
+	etype := s.concreteEtype(t)
+	x, ok := opToSSA[opAndType{op, etype}]
+	if !ok {
+		s.Fatalf("unhandled binary op %v %s", op, etype)
+	}
+	return x
+}
+
+type opAndTwoTypes struct {
+	op     ir.Op
+	etype1 types.Kind
+	etype2 types.Kind
+}
+
+type twoTypes struct {
+	etype1 types.Kind
+	etype2 types.Kind
+}
+
+type twoOpsAndType struct {
+	op1              ssa.Op
+	op2              ssa.Op
+	intermediateType types.Kind
+}
+
+var fpConvOpToSSA = map[twoTypes]twoOpsAndType{
+
+	twoTypes{types.TINT8, types.TFLOAT32}:  twoOpsAndType{ssa.OpSignExt8to32, ssa.OpCvt32to32F, types.TINT32},
+	twoTypes{types.TINT16, types.TFLOAT32}: twoOpsAndType{ssa.OpSignExt16to32, ssa.OpCvt32to32F, types.TINT32},
+	twoTypes{types.TINT32, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32to32F, types.TINT32},
+	twoTypes{types.TINT64, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64to32F, types.TINT64},
+
+	twoTypes{types.TINT8, types.TFLOAT64}:  twoOpsAndType{ssa.OpSignExt8to32, ssa.OpCvt32to64F, types.TINT32},
+	twoTypes{types.TINT16, types.TFLOAT64}: twoOpsAndType{ssa.OpSignExt16to32, ssa.OpCvt32to64F, types.TINT32},
+	twoTypes{types.TINT32, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32to64F, types.TINT32},
+	twoTypes{types.TINT64, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64to64F, types.TINT64},
+
+	twoTypes{types.TFLOAT32, types.TINT8}:  twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to8, types.TINT32},
+	twoTypes{types.TFLOAT32, types.TINT16}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to16, types.TINT32},
+	twoTypes{types.TFLOAT32, types.TINT32}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpCopy, types.TINT32},
+	twoTypes{types.TFLOAT32, types.TINT64}: twoOpsAndType{ssa.OpCvt32Fto64, ssa.OpCopy, types.TINT64},
+
+	twoTypes{types.TFLOAT64, types.TINT8}:  twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to8, types.TINT32},
+	twoTypes{types.TFLOAT64, types.TINT16}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to16, types.TINT32},
+	twoTypes{types.TFLOAT64, types.TINT32}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpCopy, types.TINT32},
+	twoTypes{types.TFLOAT64, types.TINT64}: twoOpsAndType{ssa.OpCvt64Fto64, ssa.OpCopy, types.TINT64},
+	// unsigned
+	twoTypes{types.TUINT8, types.TFLOAT32}:  twoOpsAndType{ssa.OpZeroExt8to32, ssa.OpCvt32to32F, types.TINT32},
+	twoTypes{types.TUINT16, types.TFLOAT32}: twoOpsAndType{ssa.OpZeroExt16to32, ssa.OpCvt32to32F, types.TINT32},
+	twoTypes{types.TUINT32, types.TFLOAT32}: twoOpsAndType{ssa.OpZeroExt32to64, ssa.OpCvt64to32F, types.TINT64}, // go wide to dodge unsigned
+	twoTypes{types.TUINT64, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpInvalid, types.TUINT64},            // Cvt64Uto32F, branchy code expansion instead
+
+	twoTypes{types.TUINT8, types.TFLOAT64}:  twoOpsAndType{ssa.OpZeroExt8to32, ssa.OpCvt32to64F, types.TINT32},
+	twoTypes{types.TUINT16, types.TFLOAT64}: twoOpsAndType{ssa.OpZeroExt16to32, ssa.OpCvt32to64F, types.TINT32},
+	twoTypes{types.TUINT32, types.TFLOAT64}: twoOpsAndType{ssa.OpZeroExt32to64, ssa.OpCvt64to64F, types.TINT64}, // go wide to dodge unsigned
+	twoTypes{types.TUINT64, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpInvalid, types.TUINT64},            // Cvt64Uto64F, branchy code expansion instead
+
+	twoTypes{types.TFLOAT32, types.TUINT8}:  twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to8, types.TINT32},
+	twoTypes{types.TFLOAT32, types.TUINT16}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to16, types.TINT32},
+	twoTypes{types.TFLOAT32, types.TUINT32}: twoOpsAndType{ssa.OpCvt32Fto64, ssa.OpTrunc64to32, types.TINT64}, // go wide to dodge unsigned
+	twoTypes{types.TFLOAT32, types.TUINT64}: twoOpsAndType{ssa.OpInvalid, ssa.OpCopy, types.TUINT64},          // Cvt32Fto64U, branchy code expansion instead
+
+	twoTypes{types.TFLOAT64, types.TUINT8}:  twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to8, types.TINT32},
+	twoTypes{types.TFLOAT64, types.TUINT16}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to16, types.TINT32},
+	twoTypes{types.TFLOAT64, types.TUINT32}: twoOpsAndType{ssa.OpCvt64Fto64, ssa.OpTrunc64to32, types.TINT64}, // go wide to dodge unsigned
+	twoTypes{types.TFLOAT64, types.TUINT64}: twoOpsAndType{ssa.OpInvalid, ssa.OpCopy, types.TUINT64},          // Cvt64Fto64U, branchy code expansion instead
+
+	// float
+	twoTypes{types.TFLOAT64, types.TFLOAT32}: twoOpsAndType{ssa.OpCvt64Fto32F, ssa.OpCopy, types.TFLOAT32},
+	twoTypes{types.TFLOAT64, types.TFLOAT64}: twoOpsAndType{ssa.OpRound64F, ssa.OpCopy, types.TFLOAT64},
+	twoTypes{types.TFLOAT32, types.TFLOAT32}: twoOpsAndType{ssa.OpRound32F, ssa.OpCopy, types.TFLOAT32},
+	twoTypes{types.TFLOAT32, types.TFLOAT64}: twoOpsAndType{ssa.OpCvt32Fto64F, ssa.OpCopy, types.TFLOAT64},
+}
+
+// this map is used only for 32-bit arch, and only includes the difference
+// on 32-bit arch, don't use int64<->float conversion for uint32
+var fpConvOpToSSA32 = map[twoTypes]twoOpsAndType{
+	twoTypes{types.TUINT32, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32Uto32F, types.TUINT32},
+	twoTypes{types.TUINT32, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32Uto64F, types.TUINT32},
+	twoTypes{types.TFLOAT32, types.TUINT32}: twoOpsAndType{ssa.OpCvt32Fto32U, ssa.OpCopy, types.TUINT32},
+	twoTypes{types.TFLOAT64, types.TUINT32}: twoOpsAndType{ssa.OpCvt64Fto32U, ssa.OpCopy, types.TUINT32},
+}
+
+// uint64<->float conversions, only on machines that have instructions for that
+var uint64fpConvOpToSSA = map[twoTypes]twoOpsAndType{
+	twoTypes{types.TUINT64, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64Uto32F, types.TUINT64},
+	twoTypes{types.TUINT64, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64Uto64F, types.TUINT64},
+	twoTypes{types.TFLOAT32, types.TUINT64}: twoOpsAndType{ssa.OpCvt32Fto64U, ssa.OpCopy, types.TUINT64},
+	twoTypes{types.TFLOAT64, types.TUINT64}: twoOpsAndType{ssa.OpCvt64Fto64U, ssa.OpCopy, types.TUINT64},
+}
+
+var shiftOpToSSA = map[opAndTwoTypes]ssa.Op{
+	opAndTwoTypes{ir.OLSH, types.TINT8, types.TUINT8}:   ssa.OpLsh8x8,
+	opAndTwoTypes{ir.OLSH, types.TUINT8, types.TUINT8}:  ssa.OpLsh8x8,
+	opAndTwoTypes{ir.OLSH, types.TINT8, types.TUINT16}:  ssa.OpLsh8x16,
+	opAndTwoTypes{ir.OLSH, types.TUINT8, types.TUINT16}: ssa.OpLsh8x16,
+	opAndTwoTypes{ir.OLSH, types.TINT8, types.TUINT32}:  ssa.OpLsh8x32,
+	opAndTwoTypes{ir.OLSH, types.TUINT8, types.TUINT32}: ssa.OpLsh8x32,
+	opAndTwoTypes{ir.OLSH, types.TINT8, types.TUINT64}:  ssa.OpLsh8x64,
+	opAndTwoTypes{ir.OLSH, types.TUINT8, types.TUINT64}: ssa.OpLsh8x64,
+
+	opAndTwoTypes{ir.OLSH, types.TINT16, types.TUINT8}:   ssa.OpLsh16x8,
+	opAndTwoTypes{ir.OLSH, types.TUINT16, types.TUINT8}:  ssa.OpLsh16x8,
+	opAndTwoTypes{ir.OLSH, types.TINT16, types.TUINT16}:  ssa.OpLsh16x16,
+	opAndTwoTypes{ir.OLSH, types.TUINT16, types.TUINT16}: ssa.OpLsh16x16,
+	opAndTwoTypes{ir.OLSH, types.TINT16, types.TUINT32}:  ssa.OpLsh16x32,
+	opAndTwoTypes{ir.OLSH, types.TUINT16, types.TUINT32}: ssa.OpLsh16x32,
+	opAndTwoTypes{ir.OLSH, types.TINT16, types.TUINT64}:  ssa.OpLsh16x64,
+	opAndTwoTypes{ir.OLSH, types.TUINT16, types.TUINT64}: ssa.OpLsh16x64,
+
+	opAndTwoTypes{ir.OLSH, types.TINT32, types.TUINT8}:   ssa.OpLsh32x8,
+	opAndTwoTypes{ir.OLSH, types.TUINT32, types.TUINT8}:  ssa.OpLsh32x8,
+	opAndTwoTypes{ir.OLSH, types.TINT32, types.TUINT16}:  ssa.OpLsh32x16,
+	opAndTwoTypes{ir.OLSH, types.TUINT32, types.TUINT16}: ssa.OpLsh32x16,
+	opAndTwoTypes{ir.OLSH, types.TINT32, types.TUINT32}:  ssa.OpLsh32x32,
+	opAndTwoTypes{ir.OLSH, types.TUINT32, types.TUINT32}: ssa.OpLsh32x32,
+	opAndTwoTypes{ir.OLSH, types.TINT32, types.TUINT64}:  ssa.OpLsh32x64,
+	opAndTwoTypes{ir.OLSH, types.TUINT32, types.TUINT64}: ssa.OpLsh32x64,
+
+	opAndTwoTypes{ir.OLSH, types.TINT64, types.TUINT8}:   ssa.OpLsh64x8,
+	opAndTwoTypes{ir.OLSH, types.TUINT64, types.TUINT8}:  ssa.OpLsh64x8,
+	opAndTwoTypes{ir.OLSH, types.TINT64, types.TUINT16}:  ssa.OpLsh64x16,
+	opAndTwoTypes{ir.OLSH, types.TUINT64, types.TUINT16}: ssa.OpLsh64x16,
+	opAndTwoTypes{ir.OLSH, types.TINT64, types.TUINT32}:  ssa.OpLsh64x32,
+	opAndTwoTypes{ir.OLSH, types.TUINT64, types.TUINT32}: ssa.OpLsh64x32,
+	opAndTwoTypes{ir.OLSH, types.TINT64, types.TUINT64}:  ssa.OpLsh64x64,
+	opAndTwoTypes{ir.OLSH, types.TUINT64, types.TUINT64}: ssa.OpLsh64x64,
+
+	opAndTwoTypes{ir.ORSH, types.TINT8, types.TUINT8}:   ssa.OpRsh8x8,
+	opAndTwoTypes{ir.ORSH, types.TUINT8, types.TUINT8}:  ssa.OpRsh8Ux8,
+	opAndTwoTypes{ir.ORSH, types.TINT8, types.TUINT16}:  ssa.OpRsh8x16,
+	opAndTwoTypes{ir.ORSH, types.TUINT8, types.TUINT16}: ssa.OpRsh8Ux16,
+	opAndTwoTypes{ir.ORSH, types.TINT8, types.TUINT32}:  ssa.OpRsh8x32,
+	opAndTwoTypes{ir.ORSH, types.TUINT8, types.TUINT32}: ssa.OpRsh8Ux32,
+	opAndTwoTypes{ir.ORSH, types.TINT8, types.TUINT64}:  ssa.OpRsh8x64,
+	opAndTwoTypes{ir.ORSH, types.TUINT8, types.TUINT64}: ssa.OpRsh8Ux64,
+
+	opAndTwoTypes{ir.ORSH, types.TINT16, types.TUINT8}:   ssa.OpRsh16x8,
+	opAndTwoTypes{ir.ORSH, types.TUINT16, types.TUINT8}:  ssa.OpRsh16Ux8,
+	opAndTwoTypes{ir.ORSH, types.TINT16, types.TUINT16}:  ssa.OpRsh16x16,
+	opAndTwoTypes{ir.ORSH, types.TUINT16, types.TUINT16}: ssa.OpRsh16Ux16,
+	opAndTwoTypes{ir.ORSH, types.TINT16, types.TUINT32}:  ssa.OpRsh16x32,
+	opAndTwoTypes{ir.ORSH, types.TUINT16, types.TUINT32}: ssa.OpRsh16Ux32,
+	opAndTwoTypes{ir.ORSH, types.TINT16, types.TUINT64}:  ssa.OpRsh16x64,
+	opAndTwoTypes{ir.ORSH, types.TUINT16, types.TUINT64}: ssa.OpRsh16Ux64,
+
+	opAndTwoTypes{ir.ORSH, types.TINT32, types.TUINT8}:   ssa.OpRsh32x8,
+	opAndTwoTypes{ir.ORSH, types.TUINT32, types.TUINT8}:  ssa.OpRsh32Ux8,
+	opAndTwoTypes{ir.ORSH, types.TINT32, types.TUINT16}:  ssa.OpRsh32x16,
+	opAndTwoTypes{ir.ORSH, types.TUINT32, types.TUINT16}: ssa.OpRsh32Ux16,
+	opAndTwoTypes{ir.ORSH, types.TINT32, types.TUINT32}:  ssa.OpRsh32x32,
+	opAndTwoTypes{ir.ORSH, types.TUINT32, types.TUINT32}: ssa.OpRsh32Ux32,
+	opAndTwoTypes{ir.ORSH, types.TINT32, types.TUINT64}:  ssa.OpRsh32x64,
+	opAndTwoTypes{ir.ORSH, types.TUINT32, types.TUINT64}: ssa.OpRsh32Ux64,
+
+	opAndTwoTypes{ir.ORSH, types.TINT64, types.TUINT8}:   ssa.OpRsh64x8,
+	opAndTwoTypes{ir.ORSH, types.TUINT64, types.TUINT8}:  ssa.OpRsh64Ux8,
+	opAndTwoTypes{ir.ORSH, types.TINT64, types.TUINT16}:  ssa.OpRsh64x16,
+	opAndTwoTypes{ir.ORSH, types.TUINT64, types.TUINT16}: ssa.OpRsh64Ux16,
+	opAndTwoTypes{ir.ORSH, types.TINT64, types.TUINT32}:  ssa.OpRsh64x32,
+	opAndTwoTypes{ir.ORSH, types.TUINT64, types.TUINT32}: ssa.OpRsh64Ux32,
+	opAndTwoTypes{ir.ORSH, types.TINT64, types.TUINT64}:  ssa.OpRsh64x64,
+	opAndTwoTypes{ir.ORSH, types.TUINT64, types.TUINT64}: ssa.OpRsh64Ux64,
+}
+
+func (s *state) ssaShiftOp(op ir.Op, t *types.Type, u *types.Type) ssa.Op {
+	etype1 := s.concreteEtype(t)
+	etype2 := s.concreteEtype(u)
+	x, ok := shiftOpToSSA[opAndTwoTypes{op, etype1, etype2}]
+	if !ok {
+		s.Fatalf("unhandled shift op %v etype=%s/%s", op, etype1, etype2)
+	}
+	return x
+}
+
+// expr converts the expression n to ssa, adds it to s and returns the ssa result.
+func (s *state) expr(n ir.Node) *ssa.Value {
+	if ir.HasUniquePos(n) {
+		// ONAMEs and named OLITERALs have the line number
+		// of the decl, not the use. See issue 14742.
+		s.pushLine(n.Pos())
+		defer s.popLine()
+	}
+
+	s.stmtList(n.Init())
+	switch n.Op() {
+	case ir.OBYTES2STRTMP:
+		n := n.(*ir.ConvExpr)
+		slice := s.expr(n.X)
+		ptr := s.newValue1(ssa.OpSlicePtr, s.f.Config.Types.BytePtr, slice)
+		len := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], slice)
+		return s.newValue2(ssa.OpStringMake, n.Type(), ptr, len)
+	case ir.OSTR2BYTESTMP:
+		n := n.(*ir.ConvExpr)
+		str := s.expr(n.X)
+		ptr := s.newValue1(ssa.OpStringPtr, s.f.Config.Types.BytePtr, str)
+		len := s.newValue1(ssa.OpStringLen, types.Types[types.TINT], str)
+		return s.newValue3(ssa.OpSliceMake, n.Type(), ptr, len, len)
+	case ir.OCFUNC:
+		n := n.(*ir.UnaryExpr)
+		aux := n.X.(*ir.Name).Linksym()
+		// OCFUNC is used to build function values, which must
+		// always reference ABIInternal entry points.
+		if aux.ABI() != obj.ABIInternal {
+			s.Fatalf("expected ABIInternal: %v", aux.ABI())
+		}
+		return s.entryNewValue1A(ssa.OpAddr, n.Type(), aux, s.sb)
+	case ir.ONAME:
+		n := n.(*ir.Name)
+		if n.Class == ir.PFUNC {
+			// "value" of a function is the address of the function's closure
+			sym := staticdata.FuncLinksym(n)
+			return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type()), sym, s.sb)
+		}
+		if s.canSSA(n) {
+			return s.variable(n, n.Type())
+		}
+		return s.load(n.Type(), s.addr(n))
+	case ir.OLINKSYMOFFSET:
+		n := n.(*ir.LinksymOffsetExpr)
+		return s.load(n.Type(), s.addr(n))
+	case ir.ONIL:
+		n := n.(*ir.NilExpr)
+		t := n.Type()
+		switch {
+		case t.IsSlice():
+			return s.constSlice(t)
+		case t.IsInterface():
+			return s.constInterface(t)
+		default:
+			return s.constNil(t)
+		}
+	case ir.OLITERAL:
+		switch u := n.Val(); u.Kind() {
+		case constant.Int:
+			i := ir.IntVal(n.Type(), u)
+			switch n.Type().Size() {
+			case 1:
+				return s.constInt8(n.Type(), int8(i))
+			case 2:
+				return s.constInt16(n.Type(), int16(i))
+			case 4:
+				return s.constInt32(n.Type(), int32(i))
+			case 8:
+				return s.constInt64(n.Type(), i)
+			default:
+				s.Fatalf("bad integer size %d", n.Type().Size())
+				return nil
+			}
+		case constant.String:
+			i := constant.StringVal(u)
+			if i == "" {
+				return s.constEmptyString(n.Type())
+			}
+			return s.entryNewValue0A(ssa.OpConstString, n.Type(), ssa.StringToAux(i))
+		case constant.Bool:
+			return s.constBool(constant.BoolVal(u))
+		case constant.Float:
+			f, _ := constant.Float64Val(u)
+			switch n.Type().Size() {
+			case 4:
+				return s.constFloat32(n.Type(), f)
+			case 8:
+				return s.constFloat64(n.Type(), f)
+			default:
+				s.Fatalf("bad float size %d", n.Type().Size())
+				return nil
+			}
+		case constant.Complex:
+			re, _ := constant.Float64Val(constant.Real(u))
+			im, _ := constant.Float64Val(constant.Imag(u))
+			switch n.Type().Size() {
+			case 8:
+				pt := types.Types[types.TFLOAT32]
+				return s.newValue2(ssa.OpComplexMake, n.Type(),
+					s.constFloat32(pt, re),
+					s.constFloat32(pt, im))
+			case 16:
+				pt := types.Types[types.TFLOAT64]
+				return s.newValue2(ssa.OpComplexMake, n.Type(),
+					s.constFloat64(pt, re),
+					s.constFloat64(pt, im))
+			default:
+				s.Fatalf("bad complex size %d", n.Type().Size())
+				return nil
+			}
+		default:
+			s.Fatalf("unhandled OLITERAL %v", u.Kind())
+			return nil
+		}
+	case ir.OCONVNOP:
+		n := n.(*ir.ConvExpr)
+		to := n.Type()
+		from := n.X.Type()
+
+		// Assume everything will work out, so set up our return value.
+		// Anything interesting that happens from here is a fatal.
+		x := s.expr(n.X)
+		if to == from {
+			return x
+		}
+
+		// Special case for not confusing GC and liveness.
+		// We don't want pointers accidentally classified
+		// as not-pointers or vice-versa because of copy
+		// elision.
+		if to.IsPtrShaped() != from.IsPtrShaped() {
+			return s.newValue2(ssa.OpConvert, to, x, s.mem())
+		}
+
+		v := s.newValue1(ssa.OpCopy, to, x) // ensure that v has the right type
+
+		// CONVNOP closure
+		if to.Kind() == types.TFUNC && from.IsPtrShaped() {
+			return v
+		}
+
+		// named <--> unnamed type or typed <--> untyped const
+		if from.Kind() == to.Kind() {
+			return v
+		}
+
+		// unsafe.Pointer <--> *T
+		if to.IsUnsafePtr() && from.IsPtrShaped() || from.IsUnsafePtr() && to.IsPtrShaped() {
+			return v
+		}
+
+		// map <--> *hmap
+		if to.Kind() == types.TMAP && from.IsPtr() &&
+			to.MapType().Hmap == from.Elem() {
+			return v
+		}
+
+		types.CalcSize(from)
+		types.CalcSize(to)
+		if from.Width != to.Width {
+			s.Fatalf("CONVNOP width mismatch %v (%d) -> %v (%d)\n", from, from.Width, to, to.Width)
+			return nil
+		}
+		if etypesign(from.Kind()) != etypesign(to.Kind()) {
+			s.Fatalf("CONVNOP sign mismatch %v (%s) -> %v (%s)\n", from, from.Kind(), to, to.Kind())
+			return nil
+		}
+
+		if base.Flag.Cfg.Instrumenting {
+			// These appear to be fine, but they fail the
+			// integer constraint below, so okay them here.
+			// Sample non-integer conversion: map[string]string -> *uint8
+			return v
+		}
+
+		if etypesign(from.Kind()) == 0 {
+			s.Fatalf("CONVNOP unrecognized non-integer %v -> %v\n", from, to)
+			return nil
+		}
+
+		// integer, same width, same sign
+		return v
+
+	case ir.OCONV:
+		n := n.(*ir.ConvExpr)
+		x := s.expr(n.X)
+		ft := n.X.Type() // from type
+		tt := n.Type()   // to type
+		if ft.IsBoolean() && tt.IsKind(types.TUINT8) {
+			// Bool -> uint8 is generated internally when indexing into runtime.staticbyte.
+			return s.newValue1(ssa.OpCopy, n.Type(), x)
+		}
+		if ft.IsInteger() && tt.IsInteger() {
+			var op ssa.Op
+			if tt.Size() == ft.Size() {
+				op = ssa.OpCopy
+			} else if tt.Size() < ft.Size() {
+				// truncation
+				switch 10*ft.Size() + tt.Size() {
+				case 21:
+					op = ssa.OpTrunc16to8
+				case 41:
+					op = ssa.OpTrunc32to8
+				case 42:
+					op = ssa.OpTrunc32to16
+				case 81:
+					op = ssa.OpTrunc64to8
+				case 82:
+					op = ssa.OpTrunc64to16
+				case 84:
+					op = ssa.OpTrunc64to32
+				default:
+					s.Fatalf("weird integer truncation %v -> %v", ft, tt)
+				}
+			} else if ft.IsSigned() {
+				// sign extension
+				switch 10*ft.Size() + tt.Size() {
+				case 12:
+					op = ssa.OpSignExt8to16
+				case 14:
+					op = ssa.OpSignExt8to32
+				case 18:
+					op = ssa.OpSignExt8to64
+				case 24:
+					op = ssa.OpSignExt16to32
+				case 28:
+					op = ssa.OpSignExt16to64
+				case 48:
+					op = ssa.OpSignExt32to64
+				default:
+					s.Fatalf("bad integer sign extension %v -> %v", ft, tt)
+				}
+			} else {
+				// zero extension
+				switch 10*ft.Size() + tt.Size() {
+				case 12:
+					op = ssa.OpZeroExt8to16
+				case 14:
+					op = ssa.OpZeroExt8to32
+				case 18:
+					op = ssa.OpZeroExt8to64
+				case 24:
+					op = ssa.OpZeroExt16to32
+				case 28:
+					op = ssa.OpZeroExt16to64
+				case 48:
+					op = ssa.OpZeroExt32to64
+				default:
+					s.Fatalf("weird integer sign extension %v -> %v", ft, tt)
+				}
+			}
+			return s.newValue1(op, n.Type(), x)
+		}
+
+		if ft.IsFloat() || tt.IsFloat() {
+			conv, ok := fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]
+			if s.config.RegSize == 4 && Arch.LinkArch.Family != sys.MIPS && !s.softFloat {
+				if conv1, ok1 := fpConvOpToSSA32[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
+					conv = conv1
+				}
+			}
+			if Arch.LinkArch.Family == sys.ARM64 || Arch.LinkArch.Family == sys.Wasm || Arch.LinkArch.Family == sys.S390X || s.softFloat {
+				if conv1, ok1 := uint64fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
+					conv = conv1
+				}
+			}
+
+			if Arch.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 {
+						return s.uint32Tofloat32(n, x, ft, tt)
+					}
+					if tt.Size() == 8 {
+						return s.uint32Tofloat64(n, x, ft, tt)
+					}
+				} else if tt.Size() == 4 && tt.IsInteger() && !tt.IsSigned() {
+					// ft is float32 or float64, and tt is unsigned integer
+					if ft.Size() == 4 {
+						return s.float32ToUint32(n, x, ft, tt)
+					}
+					if ft.Size() == 8 {
+						return s.float64ToUint32(n, x, ft, tt)
+					}
+				}
+			}
+
+			if !ok {
+				s.Fatalf("weird float conversion %v -> %v", ft, tt)
+			}
+			op1, op2, it := conv.op1, conv.op2, conv.intermediateType
+
+			if op1 != ssa.OpInvalid && op2 != ssa.OpInvalid {
+				// normal case, not tripping over unsigned 64
+				if op1 == ssa.OpCopy {
+					if op2 == ssa.OpCopy {
+						return x
+					}
+					return s.newValueOrSfCall1(op2, n.Type(), x)
+				}
+				if op2 == ssa.OpCopy {
+					return s.newValueOrSfCall1(op1, n.Type(), x)
+				}
+				return s.newValueOrSfCall1(op2, n.Type(), s.newValueOrSfCall1(op1, types.Types[it], x))
+			}
+			// Tricky 64-bit unsigned cases.
+			if ft.IsInteger() {
+				// tt is float32 or float64, and ft is also unsigned
+				if tt.Size() == 4 {
+					return s.uint64Tofloat32(n, x, ft, tt)
+				}
+				if tt.Size() == 8 {
+					return s.uint64Tofloat64(n, x, ft, tt)
+				}
+				s.Fatalf("weird unsigned integer to float conversion %v -> %v", ft, tt)
+			}
+			// ft is float32 or float64, and tt is unsigned integer
+			if ft.Size() == 4 {
+				return s.float32ToUint64(n, x, ft, tt)
+			}
+			if ft.Size() == 8 {
+				return s.float64ToUint64(n, x, ft, tt)
+			}
+			s.Fatalf("weird float to unsigned integer conversion %v -> %v", ft, tt)
+			return nil
+		}
+
+		if ft.IsComplex() && tt.IsComplex() {
+			var op ssa.Op
+			if ft.Size() == tt.Size() {
+				switch ft.Size() {
+				case 8:
+					op = ssa.OpRound32F
+				case 16:
+					op = ssa.OpRound64F
+				default:
+					s.Fatalf("weird complex conversion %v -> %v", ft, tt)
+				}
+			} else if ft.Size() == 8 && tt.Size() == 16 {
+				op = ssa.OpCvt32Fto64F
+			} else if ft.Size() == 16 && tt.Size() == 8 {
+				op = ssa.OpCvt64Fto32F
+			} else {
+				s.Fatalf("weird complex conversion %v -> %v", ft, tt)
+			}
+			ftp := types.FloatForComplex(ft)
+			ttp := types.FloatForComplex(tt)
+			return s.newValue2(ssa.OpComplexMake, tt,
+				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.X.Type().Kind(), n.Type().Kind())
+		return nil
+
+	case ir.ODOTTYPE:
+		n := n.(*ir.TypeAssertExpr)
+		res, _ := s.dottype(n, false)
+		return res
+
+	// binary ops
+	case ir.OLT, ir.OEQ, ir.ONE, ir.OLE, ir.OGE, ir.OGT:
+		n := n.(*ir.BinaryExpr)
+		a := s.expr(n.X)
+		b := s.expr(n.Y)
+		if n.X.Type().IsComplex() {
+			pt := types.FloatForComplex(n.X.Type())
+			op := s.ssaOp(ir.OEQ, pt)
+			r := s.newValueOrSfCall2(op, types.Types[types.TBOOL], s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b))
+			i := s.newValueOrSfCall2(op, types.Types[types.TBOOL], s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b))
+			c := s.newValue2(ssa.OpAndB, types.Types[types.TBOOL], r, i)
+			switch n.Op() {
+			case ir.OEQ:
+				return c
+			case ir.ONE:
+				return s.newValue1(ssa.OpNot, types.Types[types.TBOOL], c)
+			default:
+				s.Fatalf("ordered complex compare %v", n.Op())
+			}
+		}
+
+		// Convert OGE and OGT into OLE and OLT.
+		op := n.Op()
+		switch op {
+		case ir.OGE:
+			op, a, b = ir.OLE, b, a
+		case ir.OGT:
+			op, a, b = ir.OLT, b, a
+		}
+		if n.X.Type().IsFloat() {
+			// float comparison
+			return s.newValueOrSfCall2(s.ssaOp(op, n.X.Type()), types.Types[types.TBOOL], a, b)
+		}
+		// integer comparison
+		return s.newValue2(s.ssaOp(op, n.X.Type()), types.Types[types.TBOOL], a, b)
+	case ir.OMUL:
+		n := n.(*ir.BinaryExpr)
+		a := s.expr(n.X)
+		b := s.expr(n.Y)
+		if n.Type().IsComplex() {
+			mulop := ssa.OpMul64F
+			addop := ssa.OpAdd64F
+			subop := ssa.OpSub64F
+			pt := types.FloatForComplex(n.Type()) // Could be Float32 or Float64
+			wt := types.Types[types.TFLOAT64]     // Compute in Float64 to minimize cancellation error
+
+			areal := s.newValue1(ssa.OpComplexReal, pt, a)
+			breal := s.newValue1(ssa.OpComplexReal, pt, b)
+			aimag := s.newValue1(ssa.OpComplexImag, pt, a)
+			bimag := s.newValue1(ssa.OpComplexImag, pt, b)
+
+			if pt != wt { // Widen for calculation
+				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.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.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 ir.ODIV:
+		n := n.(*ir.BinaryExpr)
+		a := s.expr(n.X)
+		b := s.expr(n.Y)
+		if n.Type().IsComplex() {
+			// TODO this is not executed because the front-end substitutes a runtime call.
+			// That probably ought to change; with modest optimization the widen/narrow
+			// conversions could all be elided in larger expression trees.
+			mulop := ssa.OpMul64F
+			addop := ssa.OpAdd64F
+			subop := ssa.OpSub64F
+			divop := ssa.OpDiv64F
+			pt := types.FloatForComplex(n.Type()) // Could be Float32 or Float64
+			wt := types.Types[types.TFLOAT64]     // Compute in Float64 to minimize cancellation error
+
+			areal := s.newValue1(ssa.OpComplexReal, pt, a)
+			breal := s.newValue1(ssa.OpComplexReal, pt, b)
+			aimag := s.newValue1(ssa.OpComplexImag, pt, a)
+			bimag := s.newValue1(ssa.OpComplexImag, pt, b)
+
+			if pt != wt { // Widen for calculation
+				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.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.newValueOrSfCall2(divop, wt, xreal, denom)
+			ximag = s.newValueOrSfCall2(divop, wt, ximag, denom)
+
+			if pt != wt { // Narrow to store back
+				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.intDivide(n, a, b)
+	case ir.OMOD:
+		n := n.(*ir.BinaryExpr)
+		a := s.expr(n.X)
+		b := s.expr(n.Y)
+		return s.intDivide(n, a, b)
+	case ir.OADD, ir.OSUB:
+		n := n.(*ir.BinaryExpr)
+		a := s.expr(n.X)
+		b := s.expr(n.Y)
+		if n.Type().IsComplex() {
+			pt := types.FloatForComplex(n.Type())
+			op := s.ssaOp(n.Op(), pt)
+			return s.newValue2(ssa.OpComplexMake, n.Type(),
+				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 ir.OAND, ir.OOR, ir.OXOR:
+		n := n.(*ir.BinaryExpr)
+		a := s.expr(n.X)
+		b := s.expr(n.Y)
+		return s.newValue2(s.ssaOp(n.Op(), n.Type()), a.Type, a, b)
+	case ir.OANDNOT:
+		n := n.(*ir.BinaryExpr)
+		a := s.expr(n.X)
+		b := s.expr(n.Y)
+		b = s.newValue1(s.ssaOp(ir.OBITNOT, b.Type), b.Type, b)
+		return s.newValue2(s.ssaOp(ir.OAND, n.Type()), a.Type, a, b)
+	case ir.OLSH, ir.ORSH:
+		n := n.(*ir.BinaryExpr)
+		a := s.expr(n.X)
+		b := s.expr(n.Y)
+		bt := b.Type
+		if bt.IsSigned() {
+			cmp := s.newValue2(s.ssaOp(ir.OLE, bt), types.Types[types.TBOOL], s.zeroVal(bt), b)
+			s.check(cmp, ir.Syms.Panicshift)
+			bt = bt.ToUnsigned()
+		}
+		return s.newValue2(s.ssaShiftOp(n.Op(), n.Type(), bt), a.Type, a, b)
+	case ir.OANDAND, ir.OOROR:
+		// To implement OANDAND (and OOROR), we introduce a
+		// new temporary variable to hold the result. The
+		// variable is associated with the OANDAND node in the
+		// s.vars table (normally variables are only
+		// associated with ONAME nodes). We convert
+		//     A && B
+		// to
+		//     var = A
+		//     if var {
+		//         var = B
+		//     }
+		// Using var in the subsequent block introduces the
+		// necessary phi variable.
+		n := n.(*ir.LogicalExpr)
+		el := s.expr(n.X)
+		s.vars[n] = el
+
+		b := s.endBlock()
+		b.Kind = ssa.BlockIf
+		b.SetControl(el)
+		// In theory, we should set b.Likely here based on context.
+		// However, gc only gives us likeliness hints
+		// in a single place, for plain OIF statements,
+		// and passing around context is finnicky, so don't bother for now.
+
+		bRight := s.f.NewBlock(ssa.BlockPlain)
+		bResult := s.f.NewBlock(ssa.BlockPlain)
+		if n.Op() == ir.OANDAND {
+			b.AddEdgeTo(bRight)
+			b.AddEdgeTo(bResult)
+		} else if n.Op() == ir.OOROR {
+			b.AddEdgeTo(bResult)
+			b.AddEdgeTo(bRight)
+		}
+
+		s.startBlock(bRight)
+		er := s.expr(n.Y)
+		s.vars[n] = er
+
+		b = s.endBlock()
+		b.AddEdgeTo(bResult)
+
+		s.startBlock(bResult)
+		return s.variable(n, types.Types[types.TBOOL])
+	case ir.OCOMPLEX:
+		n := n.(*ir.BinaryExpr)
+		r := s.expr(n.X)
+		i := s.expr(n.Y)
+		return s.newValue2(ssa.OpComplexMake, n.Type(), r, i)
+
+	// unary ops
+	case ir.ONEG:
+		n := n.(*ir.UnaryExpr)
+		a := s.expr(n.X)
+		if n.Type().IsComplex() {
+			tp := types.FloatForComplex(n.Type())
+			negop := s.ssaOp(n.Op(), tp)
+			return s.newValue2(ssa.OpComplexMake, n.Type(),
+				s.newValue1(negop, tp, s.newValue1(ssa.OpComplexReal, tp, a)),
+				s.newValue1(negop, tp, s.newValue1(ssa.OpComplexImag, tp, a)))
+		}
+		return s.newValue1(s.ssaOp(n.Op(), n.Type()), a.Type, a)
+	case ir.ONOT, ir.OBITNOT:
+		n := n.(*ir.UnaryExpr)
+		a := s.expr(n.X)
+		return s.newValue1(s.ssaOp(n.Op(), n.Type()), a.Type, a)
+	case ir.OIMAG, ir.OREAL:
+		n := n.(*ir.UnaryExpr)
+		a := s.expr(n.X)
+		return s.newValue1(s.ssaOp(n.Op(), n.X.Type()), n.Type(), a)
+	case ir.OPLUS:
+		n := n.(*ir.UnaryExpr)
+		return s.expr(n.X)
+
+	case ir.OADDR:
+		n := n.(*ir.AddrExpr)
+		return s.addr(n.X)
+
+	case ir.ORESULT:
+		n := n.(*ir.ResultExpr)
+		if s.prevCall == nil || s.prevCall.Op != ssa.OpStaticLECall && s.prevCall.Op != ssa.OpInterLECall && s.prevCall.Op != ssa.OpClosureLECall {
+			panic("Expected to see a previous call")
+		}
+		which := n.Index
+		if which == -1 {
+			panic(fmt.Errorf("ORESULT %v does not match call %s", n, s.prevCall))
+		}
+		return s.resultOfCall(s.prevCall, which, n.Type())
+
+	case ir.ODEREF:
+		n := n.(*ir.StarExpr)
+		p := s.exprPtr(n.X, n.Bounded(), n.Pos())
+		return s.load(n.Type(), p)
+
+	case ir.ODOT:
+		n := n.(*ir.SelectorExpr)
+		if n.X.Op() == ir.OSTRUCTLIT {
+			// All literals with nonzero fields have already been
+			// rewritten during walk. Any that remain are just T{}
+			// or equivalents. Use the zero value.
+			if !ir.IsZero(n.X) {
+				s.Fatalf("literal with nonzero value in SSA: %v", n.X)
+			}
+			return s.zeroVal(n.Type())
+		}
+		// If n is addressable and can't be represented in
+		// SSA, then load just the selected field. This
+		// prevents false memory dependencies in race/msan
+		// instrumentation.
+		if ir.IsAddressable(n) && !s.canSSA(n) {
+			p := s.addr(n)
+			return s.load(n.Type(), p)
+		}
+		v := s.expr(n.X)
+		return s.newValue1I(ssa.OpStructSelect, n.Type(), int64(fieldIdx(n)), v)
+
+	case ir.ODOTPTR:
+		n := n.(*ir.SelectorExpr)
+		p := s.exprPtr(n.X, n.Bounded(), n.Pos())
+		p = s.newValue1I(ssa.OpOffPtr, types.NewPtr(n.Type()), n.Offset(), p)
+		return s.load(n.Type(), p)
+
+	case ir.OINDEX:
+		n := n.(*ir.IndexExpr)
+		switch {
+		case n.X.Type().IsString():
+			if n.Bounded() && ir.IsConst(n.X, constant.String) && ir.IsConst(n.Index, constant.Int) {
+				// Replace "abc"[1] with 'b'.
+				// Delayed until now because "abc"[1] is not an ideal constant.
+				// See test/fixedbugs/issue11370.go.
+				return s.newValue0I(ssa.OpConst8, types.Types[types.TUINT8], int64(int8(ir.StringVal(n.X)[ir.Int64Val(n.Index)])))
+			}
+			a := s.expr(n.X)
+			i := s.expr(n.Index)
+			len := s.newValue1(ssa.OpStringLen, types.Types[types.TINT], a)
+			i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
+			ptrtyp := s.f.Config.Types.BytePtr
+			ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a)
+			if ir.IsConst(n.Index, constant.Int) {
+				ptr = s.newValue1I(ssa.OpOffPtr, ptrtyp, ir.Int64Val(n.Index), ptr)
+			} else {
+				ptr = s.newValue2(ssa.OpAddPtr, ptrtyp, ptr, i)
+			}
+			return s.load(types.Types[types.TUINT8], ptr)
+		case n.X.Type().IsSlice():
+			p := s.addr(n)
+			return s.load(n.X.Type().Elem(), p)
+		case n.X.Type().IsArray():
+			if TypeOK(n.X.Type()) {
+				// SSA can handle arrays of length at most 1.
+				bound := n.X.Type().NumElem()
+				a := s.expr(n.X)
+				i := s.expr(n.Index)
+				if bound == 0 {
+					// Bounds check will never succeed.  Might as well
+					// use constants for the bounds check.
+					z := s.constInt(types.Types[types.TINT], 0)
+					s.boundsCheck(z, z, ssa.BoundsIndex, false)
+					// The return value won't be live, return junk.
+					return s.newValue0(ssa.OpUnknown, n.Type())
+				}
+				len := s.constInt(types.Types[types.TINT], bound)
+				s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded()) // checks i == 0
+				return s.newValue1I(ssa.OpArraySelect, n.Type(), 0, a)
+			}
+			p := s.addr(n)
+			return s.load(n.X.Type().Elem(), p)
+		default:
+			s.Fatalf("bad type for index %v", n.X.Type())
+			return nil
+		}
+
+	case ir.OLEN, ir.OCAP:
+		n := n.(*ir.UnaryExpr)
+		switch {
+		case n.X.Type().IsSlice():
+			op := ssa.OpSliceLen
+			if n.Op() == ir.OCAP {
+				op = ssa.OpSliceCap
+			}
+			return s.newValue1(op, types.Types[types.TINT], s.expr(n.X))
+		case n.X.Type().IsString(): // string; not reachable for OCAP
+			return s.newValue1(ssa.OpStringLen, types.Types[types.TINT], s.expr(n.X))
+		case n.X.Type().IsMap(), n.X.Type().IsChan():
+			return s.referenceTypeBuiltin(n, s.expr(n.X))
+		default: // array
+			return s.constInt(types.Types[types.TINT], n.X.Type().NumElem())
+		}
+
+	case ir.OSPTR:
+		n := n.(*ir.UnaryExpr)
+		a := s.expr(n.X)
+		if n.X.Type().IsSlice() {
+			return s.newValue1(ssa.OpSlicePtr, n.Type(), a)
+		} else {
+			return s.newValue1(ssa.OpStringPtr, n.Type(), a)
+		}
+
+	case ir.OITAB:
+		n := n.(*ir.UnaryExpr)
+		a := s.expr(n.X)
+		return s.newValue1(ssa.OpITab, n.Type(), a)
+
+	case ir.OIDATA:
+		n := n.(*ir.UnaryExpr)
+		a := s.expr(n.X)
+		return s.newValue1(ssa.OpIData, n.Type(), a)
+
+	case ir.OEFACE:
+		n := n.(*ir.BinaryExpr)
+		tab := s.expr(n.X)
+		data := s.expr(n.Y)
+		return s.newValue2(ssa.OpIMake, n.Type(), tab, data)
+
+	case ir.OSLICEHEADER:
+		n := n.(*ir.SliceHeaderExpr)
+		p := s.expr(n.Ptr)
+		l := s.expr(n.Len)
+		c := s.expr(n.Cap)
+		return s.newValue3(ssa.OpSliceMake, n.Type(), p, l, c)
+
+	case ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR:
+		n := n.(*ir.SliceExpr)
+		v := s.expr(n.X)
+		var i, j, k *ssa.Value
+		if n.Low != nil {
+			i = s.expr(n.Low)
+		}
+		if n.High != nil {
+			j = s.expr(n.High)
+		}
+		if n.Max != nil {
+			k = s.expr(n.Max)
+		}
+		p, l, c := s.slice(v, i, j, k, n.Bounded())
+		return s.newValue3(ssa.OpSliceMake, n.Type(), p, l, c)
+
+	case ir.OSLICESTR:
+		n := n.(*ir.SliceExpr)
+		v := s.expr(n.X)
+		var i, j *ssa.Value
+		if n.Low != nil {
+			i = s.expr(n.Low)
+		}
+		if n.High != nil {
+			j = s.expr(n.High)
+		}
+		p, l, _ := s.slice(v, i, j, nil, n.Bounded())
+		return s.newValue2(ssa.OpStringMake, n.Type(), p, l)
+
+	case ir.OSLICE2ARRPTR:
+		// if arrlen > slice.len {
+		//   panic(...)
+		// }
+		// slice.ptr
+		n := n.(*ir.ConvExpr)
+		v := s.expr(n.X)
+		arrlen := s.constInt(types.Types[types.TINT], n.Type().Elem().NumElem())
+		cap := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], v)
+		s.boundsCheck(arrlen, cap, ssa.BoundsConvert, false)
+		return s.newValue1(ssa.OpSlicePtrUnchecked, n.Type(), v)
+
+	case ir.OCALLFUNC:
+		n := n.(*ir.CallExpr)
+		if ir.IsIntrinsicCall(n) {
+			return s.intrinsicCall(n)
+		}
+		fallthrough
+
+	case ir.OCALLINTER, ir.OCALLMETH:
+		n := n.(*ir.CallExpr)
+		return s.callResult(n, callNormal)
+
+	case ir.OGETG:
+		n := n.(*ir.CallExpr)
+		return s.newValue1(ssa.OpGetG, n.Type(), s.mem())
+
+	case ir.OAPPEND:
+		return s.append(n.(*ir.CallExpr), false)
+
+	case ir.OSTRUCTLIT, ir.OARRAYLIT:
+		// All literals with nonzero fields have already been
+		// rewritten during walk. Any that remain are just T{}
+		// or equivalents. Use the zero value.
+		n := n.(*ir.CompLitExpr)
+		if !ir.IsZero(n) {
+			s.Fatalf("literal with nonzero value in SSA: %v", n)
+		}
+		return s.zeroVal(n.Type())
+
+	case ir.ONEW:
+		n := n.(*ir.UnaryExpr)
+		return s.newObject(n.Type().Elem())
+
+	case ir.OUNSAFEADD:
+		n := n.(*ir.BinaryExpr)
+		ptr := s.expr(n.X)
+		len := s.expr(n.Y)
+		return s.newValue2(ssa.OpAddPtr, n.Type(), ptr, len)
+
+	default:
+		s.Fatalf("unhandled expr %v", n.Op())
+		return nil
+	}
+}
+
+func (s *state) resultOfCall(c *ssa.Value, which int64, t *types.Type) *ssa.Value {
+	aux := c.Aux.(*ssa.AuxCall)
+	pa := aux.ParamAssignmentForResult(which)
+	// TODO(register args) determine if in-memory TypeOK is better loaded early from SelectNAddr or later when SelectN is expanded.
+	// SelectN is better for pattern-matching and possible call-aware analysis we might want to do in the future.
+	if len(pa.Registers) == 0 && !TypeOK(t) {
+		addr := s.newValue1I(ssa.OpSelectNAddr, types.NewPtr(t), which, c)
+		return s.rawLoad(t, addr)
+	}
+	return s.newValue1I(ssa.OpSelectN, t, which, c)
+}
+
+func (s *state) resultAddrOfCall(c *ssa.Value, which int64, t *types.Type) *ssa.Value {
+	aux := c.Aux.(*ssa.AuxCall)
+	pa := aux.ParamAssignmentForResult(which)
+	if len(pa.Registers) == 0 {
+		return s.newValue1I(ssa.OpSelectNAddr, types.NewPtr(t), which, c)
+	}
+	_, addr := s.temp(c.Pos, t)
+	rval := s.newValue1I(ssa.OpSelectN, t, which, c)
+	s.vars[memVar] = s.newValue3Apos(ssa.OpStore, types.TypeMem, t, addr, rval, s.mem(), false)
+	return addr
+}
+
+// append converts an OAPPEND node to SSA.
+// If inplace is false, it converts the OAPPEND expression n to an ssa.Value,
+// adds it to s, and returns the Value.
+// If inplace is true, it writes the result of the OAPPEND expression n
+// back to the slice being appended to, and returns nil.
+// inplace MUST be set to false if the slice can be SSA'd.
+func (s *state) append(n *ir.CallExpr, inplace bool) *ssa.Value {
+	// If inplace is false, process as expression "append(s, e1, e2, e3)":
+	//
+	// ptr, len, cap := s
+	// newlen := len + 3
+	// if newlen > cap {
+	//     ptr, len, cap = growslice(s, newlen)
+	//     newlen = len + 3 // recalculate to avoid a spill
+	// }
+	// // with write barriers, if needed:
+	// *(ptr+len) = e1
+	// *(ptr+len+1) = e2
+	// *(ptr+len+2) = e3
+	// return makeslice(ptr, newlen, cap)
+	//
+	//
+	// If inplace is true, process as statement "s = append(s, e1, e2, e3)":
+	//
+	// a := &s
+	// ptr, len, cap := s
+	// newlen := len + 3
+	// if uint(newlen) > uint(cap) {
+	//    newptr, len, newcap = growslice(ptr, len, cap, newlen)
+	//    vardef(a)       // if necessary, advise liveness we are writing a new a
+	//    *a.cap = newcap // write before ptr to avoid a spill
+	//    *a.ptr = newptr // with write barrier
+	// }
+	// newlen = len + 3 // recalculate to avoid a spill
+	// *a.len = newlen
+	// // with write barriers, if needed:
+	// *(ptr+len) = e1
+	// *(ptr+len+1) = e2
+	// *(ptr+len+2) = e3
+
+	et := n.Type().Elem()
+	pt := types.NewPtr(et)
+
+	// Evaluate slice
+	sn := n.Args[0] // the slice node is the first in the list
+
+	var slice, addr *ssa.Value
+	if inplace {
+		addr = s.addr(sn)
+		slice = s.load(n.Type(), addr)
+	} else {
+		slice = s.expr(sn)
+	}
+
+	// Allocate new blocks
+	grow := s.f.NewBlock(ssa.BlockPlain)
+	assign := s.f.NewBlock(ssa.BlockPlain)
+
+	// Decide if we need to grow
+	nargs := int64(len(n.Args) - 1)
+	p := s.newValue1(ssa.OpSlicePtr, pt, slice)
+	l := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], slice)
+	c := s.newValue1(ssa.OpSliceCap, types.Types[types.TINT], slice)
+	nl := s.newValue2(s.ssaOp(ir.OADD, types.Types[types.TINT]), types.Types[types.TINT], l, s.constInt(types.Types[types.TINT], nargs))
+
+	cmp := s.newValue2(s.ssaOp(ir.OLT, types.Types[types.TUINT]), types.Types[types.TBOOL], c, nl)
+	s.vars[ptrVar] = p
+
+	if !inplace {
+		s.vars[newlenVar] = nl
+		s.vars[capVar] = c
+	} else {
+		s.vars[lenVar] = l
+	}
+
+	b := s.endBlock()
+	b.Kind = ssa.BlockIf
+	b.Likely = ssa.BranchUnlikely
+	b.SetControl(cmp)
+	b.AddEdgeTo(grow)
+	b.AddEdgeTo(assign)
+
+	// Call growslice
+	s.startBlock(grow)
+	taddr := s.expr(n.X)
+	r := s.rtcall(ir.Syms.Growslice, true, []*types.Type{pt, types.Types[types.TINT], types.Types[types.TINT]}, taddr, p, l, c, nl)
+
+	if inplace {
+		if sn.Op() == ir.ONAME {
+			sn := sn.(*ir.Name)
+			if sn.Class != ir.PEXTERN {
+				// Tell liveness we're about to build a new slice
+				s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, sn, s.mem())
+			}
+		}
+		capaddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, types.SliceCapOffset, addr)
+		s.store(types.Types[types.TINT], capaddr, r[2])
+		s.store(pt, addr, r[0])
+		// load the value we just stored to avoid having to spill it
+		s.vars[ptrVar] = s.load(pt, addr)
+		s.vars[lenVar] = r[1] // avoid a spill in the fast path
+	} else {
+		s.vars[ptrVar] = r[0]
+		s.vars[newlenVar] = s.newValue2(s.ssaOp(ir.OADD, types.Types[types.TINT]), types.Types[types.TINT], r[1], s.constInt(types.Types[types.TINT], nargs))
+		s.vars[capVar] = r[2]
+	}
+
+	b = s.endBlock()
+	b.AddEdgeTo(assign)
+
+	// assign new elements to slots
+	s.startBlock(assign)
+
+	if inplace {
+		l = s.variable(lenVar, types.Types[types.TINT]) // generates phi for len
+		nl = s.newValue2(s.ssaOp(ir.OADD, types.Types[types.TINT]), types.Types[types.TINT], l, s.constInt(types.Types[types.TINT], nargs))
+		lenaddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, types.SliceLenOffset, addr)
+		s.store(types.Types[types.TINT], lenaddr, nl)
+	}
+
+	// Evaluate args
+	type argRec struct {
+		// if store is true, we're appending the value v.  If false, we're appending the
+		// value at *v.
+		v     *ssa.Value
+		store bool
+	}
+	args := make([]argRec, 0, nargs)
+	for _, n := range n.Args[1:] {
+		if TypeOK(n.Type()) {
+			args = append(args, argRec{v: s.expr(n), store: true})
+		} else {
+			v := s.addr(n)
+			args = append(args, argRec{v: v})
+		}
+	}
+
+	p = s.variable(ptrVar, pt) // generates phi for ptr
+	if !inplace {
+		nl = s.variable(newlenVar, types.Types[types.TINT]) // generates phi for nl
+		c = s.variable(capVar, types.Types[types.TINT])     // generates phi for cap
+	}
+	p2 := s.newValue2(ssa.OpPtrIndex, pt, p, l)
+	for i, arg := range args {
+		addr := s.newValue2(ssa.OpPtrIndex, pt, p2, s.constInt(types.Types[types.TINT], int64(i)))
+		if arg.store {
+			s.storeType(et, addr, arg.v, 0, true)
+		} else {
+			s.move(et, addr, arg.v)
+		}
+	}
+
+	delete(s.vars, ptrVar)
+	if inplace {
+		delete(s.vars, lenVar)
+		return nil
+	}
+	delete(s.vars, newlenVar)
+	delete(s.vars, capVar)
+	// make result
+	return s.newValue3(ssa.OpSliceMake, n.Type(), p, nl, c)
+}
+
+// condBranch evaluates the boolean expression cond and branches to yes
+// if cond is true and no if cond is false.
+// This function is intended to handle && and || better than just calling
+// s.expr(cond) and branching on the result.
+func (s *state) condBranch(cond ir.Node, yes, no *ssa.Block, likely int8) {
+	switch cond.Op() {
+	case ir.OANDAND:
+		cond := cond.(*ir.LogicalExpr)
+		mid := s.f.NewBlock(ssa.BlockPlain)
+		s.stmtList(cond.Init())
+		s.condBranch(cond.X, mid, no, max8(likely, 0))
+		s.startBlock(mid)
+		s.condBranch(cond.Y, yes, no, likely)
+		return
+		// Note: if likely==1, then both recursive calls pass 1.
+		// If likely==-1, then we don't have enough information to decide
+		// whether the first branch is likely or not. So we pass 0 for
+		// 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).
+	case ir.OOROR:
+		cond := cond.(*ir.LogicalExpr)
+		mid := s.f.NewBlock(ssa.BlockPlain)
+		s.stmtList(cond.Init())
+		s.condBranch(cond.X, yes, mid, min8(likely, 0))
+		s.startBlock(mid)
+		s.condBranch(cond.Y, yes, no, likely)
+		return
+		// 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.
+	case ir.ONOT:
+		cond := cond.(*ir.UnaryExpr)
+		s.stmtList(cond.Init())
+		s.condBranch(cond.X, no, yes, -likely)
+		return
+	case ir.OCONVNOP:
+		cond := cond.(*ir.ConvExpr)
+		s.stmtList(cond.Init())
+		s.condBranch(cond.X, yes, no, likely)
+		return
+	}
+	c := s.expr(cond)
+	b := s.endBlock()
+	b.Kind = ssa.BlockIf
+	b.SetControl(c)
+	b.Likely = ssa.BranchPrediction(likely) // gc and ssa both use -1/0/+1 for likeliness
+	b.AddEdgeTo(yes)
+	b.AddEdgeTo(no)
+}
+
+type skipMask uint8
+
+const (
+	skipPtr skipMask = 1 << iota
+	skipLen
+	skipCap
+)
+
+// assign does left = right.
+// Right has already been evaluated to ssa, left has not.
+// If deref is true, then we do left = *right instead (and right has already been nil-checked).
+// If deref is true and right == nil, just do left = 0.
+// skip indicates assignments (at the top level) that can be avoided.
+func (s *state) assign(left ir.Node, right *ssa.Value, deref bool, skip skipMask) {
+	if left.Op() == ir.ONAME && ir.IsBlank(left) {
+		return
+	}
+	t := left.Type()
+	types.CalcSize(t)
+	if s.canSSA(left) {
+		if deref {
+			s.Fatalf("can SSA LHS %v but not RHS %s", left, right)
+		}
+		if left.Op() == ir.ODOT {
+			// We're assigning to a field of an ssa-able value.
+			// We need to build a new structure with the new value for the
+			// field we're assigning and the old values for the other fields.
+			// For instance:
+			//   type T struct {a, b, c int}
+			//   var T x
+			//   x.b = 5
+			// For the x.b = 5 assignment we want to generate x = T{x.a, 5, x.c}
+
+			// Grab information about the structure type.
+			left := left.(*ir.SelectorExpr)
+			t := left.X.Type()
+			nf := t.NumFields()
+			idx := fieldIdx(left)
+
+			// Grab old value of structure.
+			old := s.expr(left.X)
+
+			// Make new structure.
+			new := s.newValue0(ssa.StructMakeOp(t.NumFields()), t)
+
+			// Add fields as args.
+			for i := 0; i < nf; i++ {
+				if i == idx {
+					new.AddArg(right)
+				} else {
+					new.AddArg(s.newValue1I(ssa.OpStructSelect, t.FieldType(i), int64(i), old))
+				}
+			}
+
+			// Recursively assign the new value we've made to the base of the dot op.
+			s.assign(left.X, new, false, 0)
+			// TODO: do we need to update named values here?
+			return
+		}
+		if left.Op() == ir.OINDEX && left.(*ir.IndexExpr).X.Type().IsArray() {
+			left := left.(*ir.IndexExpr)
+			s.pushLine(left.Pos())
+			defer s.popLine()
+			// We're assigning to an element of an ssa-able array.
+			// a[i] = v
+			t := left.X.Type()
+			n := t.NumElem()
+
+			i := s.expr(left.Index) // index
+			if n == 0 {
+				// The bounds check must fail.  Might as well
+				// ignore the actual index and just use zeros.
+				z := s.constInt(types.Types[types.TINT], 0)
+				s.boundsCheck(z, z, ssa.BoundsIndex, false)
+				return
+			}
+			if n != 1 {
+				s.Fatalf("assigning to non-1-length array")
+			}
+			// Rewrite to a = [1]{v}
+			len := s.constInt(types.Types[types.TINT], 1)
+			s.boundsCheck(i, len, ssa.BoundsIndex, false) // checks i == 0
+			v := s.newValue1(ssa.OpArrayMake1, t, right)
+			s.assign(left.X, v, false, 0)
+			return
+		}
+		left := left.(*ir.Name)
+		// Update variable assignment.
+		s.vars[left] = right
+		s.addNamedValue(left, right)
+		return
+	}
+
+	// If this assignment clobbers an entire local variable, then emit
+	// OpVarDef so liveness analysis knows the variable is redefined.
+	if base, ok := clobberBase(left).(*ir.Name); ok && base.OnStack() && skip == 0 {
+		s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, base, s.mem(), !ir.IsAutoTmp(base))
+	}
+
+	// Left is not ssa-able. Compute its address.
+	addr := s.addr(left)
+	if ir.IsReflectHeaderDataField(left) {
+		// 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).
+		// Mark it pointer type to signal the writebarrier pass to
+		// insert a write barrier.
+		t = types.Types[types.TUNSAFEPTR]
+	}
+	if deref {
+		// Treat as a mem->mem move.
+		if right == nil {
+			s.zero(t, addr)
+		} else {
+			s.move(t, addr, right)
+		}
+		return
+	}
+	// Treat as a store.
+	s.storeType(t, addr, right, skip, !ir.IsAutoTmp(left))
+}
+
+// zeroVal returns the zero value for type t.
+func (s *state) zeroVal(t *types.Type) *ssa.Value {
+	switch {
+	case t.IsInteger():
+		switch t.Size() {
+		case 1:
+			return s.constInt8(t, 0)
+		case 2:
+			return s.constInt16(t, 0)
+		case 4:
+			return s.constInt32(t, 0)
+		case 8:
+			return s.constInt64(t, 0)
+		default:
+			s.Fatalf("bad sized integer type %v", t)
+		}
+	case t.IsFloat():
+		switch t.Size() {
+		case 4:
+			return s.constFloat32(t, 0)
+		case 8:
+			return s.constFloat64(t, 0)
+		default:
+			s.Fatalf("bad sized float type %v", t)
+		}
+	case t.IsComplex():
+		switch t.Size() {
+		case 8:
+			z := s.constFloat32(types.Types[types.TFLOAT32], 0)
+			return s.entryNewValue2(ssa.OpComplexMake, t, z, z)
+		case 16:
+			z := s.constFloat64(types.Types[types.TFLOAT64], 0)
+			return s.entryNewValue2(ssa.OpComplexMake, t, z, z)
+		default:
+			s.Fatalf("bad sized complex type %v", t)
+		}
+
+	case t.IsString():
+		return s.constEmptyString(t)
+	case t.IsPtrShaped():
+		return s.constNil(t)
+	case t.IsBoolean():
+		return s.constBool(false)
+	case t.IsInterface():
+		return s.constInterface(t)
+	case t.IsSlice():
+		return s.constSlice(t)
+	case t.IsStruct():
+		n := t.NumFields()
+		v := s.entryNewValue0(ssa.StructMakeOp(t.NumFields()), t)
+		for i := 0; i < n; i++ {
+			v.AddArg(s.zeroVal(t.FieldType(i)))
+		}
+		return v
+	case t.IsArray():
+		switch t.NumElem() {
+		case 0:
+			return s.entryNewValue0(ssa.OpArrayMake0, t)
+		case 1:
+			return s.entryNewValue1(ssa.OpArrayMake1, t, s.zeroVal(t.Elem()))
+		}
+	}
+	s.Fatalf("zero for type %v not implemented", t)
+	return nil
+}
+
+type callKind int8
+
+const (
+	callNormal callKind = iota
+	callDefer
+	callDeferStack
+	callGo
+)
+
+type sfRtCallDef struct {
+	rtfn  *obj.LSym
+	rtype types.Kind
+}
+
+var softFloatOps map[ssa.Op]sfRtCallDef
+
+func softfloatInit() {
+	// Some of these operations get transformed by sfcall.
+	softFloatOps = map[ssa.Op]sfRtCallDef{
+		ssa.OpAdd32F: sfRtCallDef{typecheck.LookupRuntimeFunc("fadd32"), types.TFLOAT32},
+		ssa.OpAdd64F: sfRtCallDef{typecheck.LookupRuntimeFunc("fadd64"), types.TFLOAT64},
+		ssa.OpSub32F: sfRtCallDef{typecheck.LookupRuntimeFunc("fadd32"), types.TFLOAT32},
+		ssa.OpSub64F: sfRtCallDef{typecheck.LookupRuntimeFunc("fadd64"), types.TFLOAT64},
+		ssa.OpMul32F: sfRtCallDef{typecheck.LookupRuntimeFunc("fmul32"), types.TFLOAT32},
+		ssa.OpMul64F: sfRtCallDef{typecheck.LookupRuntimeFunc("fmul64"), types.TFLOAT64},
+		ssa.OpDiv32F: sfRtCallDef{typecheck.LookupRuntimeFunc("fdiv32"), types.TFLOAT32},
+		ssa.OpDiv64F: sfRtCallDef{typecheck.LookupRuntimeFunc("fdiv64"), types.TFLOAT64},
+
+		ssa.OpEq64F:   sfRtCallDef{typecheck.LookupRuntimeFunc("feq64"), types.TBOOL},
+		ssa.OpEq32F:   sfRtCallDef{typecheck.LookupRuntimeFunc("feq32"), types.TBOOL},
+		ssa.OpNeq64F:  sfRtCallDef{typecheck.LookupRuntimeFunc("feq64"), types.TBOOL},
+		ssa.OpNeq32F:  sfRtCallDef{typecheck.LookupRuntimeFunc("feq32"), types.TBOOL},
+		ssa.OpLess64F: sfRtCallDef{typecheck.LookupRuntimeFunc("fgt64"), types.TBOOL},
+		ssa.OpLess32F: sfRtCallDef{typecheck.LookupRuntimeFunc("fgt32"), types.TBOOL},
+		ssa.OpLeq64F:  sfRtCallDef{typecheck.LookupRuntimeFunc("fge64"), types.TBOOL},
+		ssa.OpLeq32F:  sfRtCallDef{typecheck.LookupRuntimeFunc("fge32"), types.TBOOL},
+
+		ssa.OpCvt32to32F:  sfRtCallDef{typecheck.LookupRuntimeFunc("fint32to32"), types.TFLOAT32},
+		ssa.OpCvt32Fto32:  sfRtCallDef{typecheck.LookupRuntimeFunc("f32toint32"), types.TINT32},
+		ssa.OpCvt64to32F:  sfRtCallDef{typecheck.LookupRuntimeFunc("fint64to32"), types.TFLOAT32},
+		ssa.OpCvt32Fto64:  sfRtCallDef{typecheck.LookupRuntimeFunc("f32toint64"), types.TINT64},
+		ssa.OpCvt64Uto32F: sfRtCallDef{typecheck.LookupRuntimeFunc("fuint64to32"), types.TFLOAT32},
+		ssa.OpCvt32Fto64U: sfRtCallDef{typecheck.LookupRuntimeFunc("f32touint64"), types.TUINT64},
+		ssa.OpCvt32to64F:  sfRtCallDef{typecheck.LookupRuntimeFunc("fint32to64"), types.TFLOAT64},
+		ssa.OpCvt64Fto32:  sfRtCallDef{typecheck.LookupRuntimeFunc("f64toint32"), types.TINT32},
+		ssa.OpCvt64to64F:  sfRtCallDef{typecheck.LookupRuntimeFunc("fint64to64"), types.TFLOAT64},
+		ssa.OpCvt64Fto64:  sfRtCallDef{typecheck.LookupRuntimeFunc("f64toint64"), types.TINT64},
+		ssa.OpCvt64Uto64F: sfRtCallDef{typecheck.LookupRuntimeFunc("fuint64to64"), types.TFLOAT64},
+		ssa.OpCvt64Fto64U: sfRtCallDef{typecheck.LookupRuntimeFunc("f64touint64"), types.TUINT64},
+		ssa.OpCvt32Fto64F: sfRtCallDef{typecheck.LookupRuntimeFunc("f32to64"), types.TFLOAT64},
+		ssa.OpCvt64Fto32F: sfRtCallDef{typecheck.LookupRuntimeFunc("f64to32"), types.TFLOAT32},
+	}
+}
+
+// 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(ir.ONEG, 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
+// implements that call as an intrinsic. args is a list of arguments to the func.
+type intrinsicBuilder func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value
+
+type intrinsicKey struct {
+	arch *sys.Arch
+	pkg  string
+	fn   string
+}
+
+func InitTables() {
+	intrinsics = map[intrinsicKey]intrinsicBuilder{}
+
+	var all []*sys.Arch
+	var p4 []*sys.Arch
+	var p8 []*sys.Arch
+	var lwatomics []*sys.Arch
+	for _, a := range &sys.Archs {
+		all = append(all, a)
+		if a.PtrSize == 4 {
+			p4 = append(p4, a)
+		} else {
+			p8 = append(p8, a)
+		}
+		if a.Family != sys.PPC64 {
+			lwatomics = append(lwatomics, a)
+		}
+	}
+
+	// add adds the intrinsic b for pkg.fn for the given list of architectures.
+	add := func(pkg, fn string, b intrinsicBuilder, archs ...*sys.Arch) {
+		for _, a := range archs {
+			intrinsics[intrinsicKey{a, pkg, fn}] = b
+		}
+	}
+	// addF does the same as add but operates on architecture families.
+	addF := func(pkg, fn string, b intrinsicBuilder, archFamilies ...sys.ArchFamily) {
+		m := 0
+		for _, f := range archFamilies {
+			if f >= 32 {
+				panic("too many architecture families")
+			}
+			m |= 1 << uint(f)
+		}
+		for _, a := range all {
+			if m>>uint(a.Family)&1 != 0 {
+				intrinsics[intrinsicKey{a, pkg, fn}] = b
+			}
+		}
+	}
+	// alias defines pkg.fn = pkg2.fn2 for all architectures in archs for which pkg2.fn2 exists.
+	alias := func(pkg, fn, pkg2, fn2 string, archs ...*sys.Arch) {
+		aliased := false
+		for _, a := range archs {
+			if b, ok := intrinsics[intrinsicKey{a, pkg2, fn2}]; ok {
+				intrinsics[intrinsicKey{a, pkg, fn}] = b
+				aliased = true
+			}
+		}
+		if !aliased {
+			panic(fmt.Sprintf("attempted to alias undefined intrinsic: %s.%s", pkg, fn))
+		}
+	}
+
+	/******** runtime ********/
+	if !base.Flag.Cfg.Instrumenting {
+		add("runtime", "slicebytetostringtmp",
+			func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+				// Compiler frontend optimizations emit OBYTES2STRTMP nodes
+				// for the backend instead of slicebytetostringtmp calls
+				// when not instrumenting.
+				return s.newValue2(ssa.OpStringMake, n.Type(), args[0], args[1])
+			},
+			all...)
+	}
+	addF("runtime/internal/math", "MulUintptr",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			if s.config.PtrSize == 4 {
+				return s.newValue2(ssa.OpMul32uover, types.NewTuple(types.Types[types.TUINT], types.Types[types.TUINT]), args[0], args[1])
+			}
+			return s.newValue2(ssa.OpMul64uover, types.NewTuple(types.Types[types.TUINT], types.Types[types.TUINT]), args[0], args[1])
+		},
+		sys.AMD64, sys.I386, sys.MIPS64)
+	add("runtime", "KeepAlive",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			data := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, args[0])
+			s.vars[memVar] = s.newValue2(ssa.OpKeepAlive, types.TypeMem, data, s.mem())
+			return nil
+		},
+		all...)
+	add("runtime", "getclosureptr",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue0(ssa.OpGetClosurePtr, s.f.Config.Types.Uintptr)
+		},
+		all...)
+
+	add("runtime", "getcallerpc",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue0(ssa.OpGetCallerPC, s.f.Config.Types.Uintptr)
+		},
+		all...)
+
+	add("runtime", "getcallersp",
+		func(s *state, n *ir.CallExpr, 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 *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpCtz32, types.Types[types.TINT], args[0])
+		},
+		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64)
+	addF("runtime/internal/sys", "Ctz64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], args[0])
+		},
+		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64)
+	addF("runtime/internal/sys", "Bswap32",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpBswap32, types.Types[types.TUINT32], args[0])
+		},
+		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X)
+	addF("runtime/internal/sys", "Bswap64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpBswap64, types.Types[types.TUINT64], args[0])
+		},
+		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X)
+
+	/******** runtime/internal/atomic ********/
+	addF("runtime/internal/atomic", "Load",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.newValue2(ssa.OpAtomicLoad32, types.NewTuple(types.Types[types.TUINT32], types.TypeMem), args[0], s.mem())
+			s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
+			return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT32], v)
+		},
+		sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "Load8",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.newValue2(ssa.OpAtomicLoad8, types.NewTuple(types.Types[types.TUINT8], types.TypeMem), args[0], s.mem())
+			s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
+			return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT8], v)
+		},
+		sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "Load64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.newValue2(ssa.OpAtomicLoad64, types.NewTuple(types.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[types.TUINT64], v)
+		},
+		sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "LoadAcq",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.newValue2(ssa.OpAtomicLoadAcq32, types.NewTuple(types.Types[types.TUINT32], types.TypeMem), args[0], s.mem())
+			s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
+			return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT32], v)
+		},
+		sys.PPC64, sys.S390X)
+	addF("runtime/internal/atomic", "LoadAcq64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.newValue2(ssa.OpAtomicLoadAcq64, types.NewTuple(types.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[types.TUINT64], v)
+		},
+		sys.PPC64)
+	addF("runtime/internal/atomic", "Loadp",
+		func(s *state, n *ir.CallExpr, 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.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+
+	addF("runtime/internal/atomic", "Store",
+		func(s *state, n *ir.CallExpr, 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.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "Store8",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			s.vars[memVar] = s.newValue3(ssa.OpAtomicStore8, types.TypeMem, args[0], args[1], s.mem())
+			return nil
+		},
+		sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "Store64",
+		func(s *state, n *ir.CallExpr, 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.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "StorepNoWB",
+		func(s *state, n *ir.CallExpr, 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.MIPS, sys.MIPS64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "StoreRel",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			s.vars[memVar] = s.newValue3(ssa.OpAtomicStoreRel32, types.TypeMem, args[0], args[1], s.mem())
+			return nil
+		},
+		sys.PPC64, sys.S390X)
+	addF("runtime/internal/atomic", "StoreRel64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			s.vars[memVar] = s.newValue3(ssa.OpAtomicStoreRel64, types.TypeMem, args[0], args[1], s.mem())
+			return nil
+		},
+		sys.PPC64)
+
+	addF("runtime/internal/atomic", "Xchg",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.newValue3(ssa.OpAtomicExchange32, types.NewTuple(types.Types[types.TUINT32], 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[types.TUINT32], v)
+		},
+		sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "Xchg64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.newValue3(ssa.OpAtomicExchange64, types.NewTuple(types.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[types.TUINT64], v)
+		},
+		sys.AMD64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+
+	type atomicOpEmitter func(s *state, n *ir.CallExpr, args []*ssa.Value, op ssa.Op, typ types.Kind)
+
+	makeAtomicGuardedIntrinsicARM64 := func(op0, op1 ssa.Op, typ, rtyp types.Kind, emit atomicOpEmitter) intrinsicBuilder {
+
+		return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			// Target Atomic feature is identified by dynamic detection
+			addr := s.entryNewValue1A(ssa.OpAddr, types.Types[types.TBOOL].PtrTo(), ir.Syms.ARM64HasATOMICS, s.sb)
+			v := s.load(types.Types[types.TBOOL], addr)
+			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
+
+			// We have atomic instructions - use it directly.
+			s.startBlock(bTrue)
+			emit(s, n, args, op1, typ)
+			s.endBlock().AddEdgeTo(bEnd)
+
+			// Use original instruction sequence.
+			s.startBlock(bFalse)
+			emit(s, n, args, op0, typ)
+			s.endBlock().AddEdgeTo(bEnd)
+
+			// Merge results.
+			s.startBlock(bEnd)
+			if rtyp == types.TNIL {
+				return nil
+			} else {
+				return s.variable(n, types.Types[rtyp])
+			}
+		}
+	}
+
+	atomicXchgXaddEmitterARM64 := func(s *state, n *ir.CallExpr, args []*ssa.Value, op ssa.Op, typ types.Kind) {
+		v := s.newValue3(op, types.NewTuple(types.Types[typ], types.TypeMem), args[0], args[1], s.mem())
+		s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
+		s.vars[n] = s.newValue1(ssa.OpSelect0, types.Types[typ], v)
+	}
+	addF("runtime/internal/atomic", "Xchg",
+		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicExchange32, ssa.OpAtomicExchange32Variant, types.TUINT32, types.TUINT32, atomicXchgXaddEmitterARM64),
+		sys.ARM64)
+	addF("runtime/internal/atomic", "Xchg64",
+		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicExchange64, ssa.OpAtomicExchange64Variant, types.TUINT64, types.TUINT64, atomicXchgXaddEmitterARM64),
+		sys.ARM64)
+
+	addF("runtime/internal/atomic", "Xadd",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.newValue3(ssa.OpAtomicAdd32, types.NewTuple(types.Types[types.TUINT32], 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[types.TUINT32], v)
+		},
+		sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "Xadd64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.newValue3(ssa.OpAtomicAdd64, types.NewTuple(types.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[types.TUINT64], v)
+		},
+		sys.AMD64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+
+	addF("runtime/internal/atomic", "Xadd",
+		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAdd32, ssa.OpAtomicAdd32Variant, types.TUINT32, types.TUINT32, atomicXchgXaddEmitterARM64),
+		sys.ARM64)
+	addF("runtime/internal/atomic", "Xadd64",
+		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAdd64, ssa.OpAtomicAdd64Variant, types.TUINT64, types.TUINT64, atomicXchgXaddEmitterARM64),
+		sys.ARM64)
+
+	addF("runtime/internal/atomic", "Cas",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.newValue4(ssa.OpAtomicCompareAndSwap32, types.NewTuple(types.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[types.TBOOL], v)
+		},
+		sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "Cas64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.newValue4(ssa.OpAtomicCompareAndSwap64, types.NewTuple(types.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[types.TBOOL], v)
+		},
+		sys.AMD64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "CasRel",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.newValue4(ssa.OpAtomicCompareAndSwap32, types.NewTuple(types.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[types.TBOOL], v)
+		},
+		sys.PPC64)
+
+	atomicCasEmitterARM64 := func(s *state, n *ir.CallExpr, args []*ssa.Value, op ssa.Op, typ types.Kind) {
+		v := s.newValue4(op, types.NewTuple(types.Types[types.TBOOL], types.TypeMem), args[0], args[1], args[2], s.mem())
+		s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
+		s.vars[n] = s.newValue1(ssa.OpSelect0, types.Types[typ], v)
+	}
+
+	addF("runtime/internal/atomic", "Cas",
+		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicCompareAndSwap32, ssa.OpAtomicCompareAndSwap32Variant, types.TUINT32, types.TBOOL, atomicCasEmitterARM64),
+		sys.ARM64)
+	addF("runtime/internal/atomic", "Cas64",
+		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicCompareAndSwap64, ssa.OpAtomicCompareAndSwap64Variant, types.TUINT64, types.TBOOL, atomicCasEmitterARM64),
+		sys.ARM64)
+
+	addF("runtime/internal/atomic", "And8",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			s.vars[memVar] = s.newValue3(ssa.OpAtomicAnd8, types.TypeMem, args[0], args[1], s.mem())
+			return nil
+		},
+		sys.AMD64, sys.MIPS, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "And",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			s.vars[memVar] = s.newValue3(ssa.OpAtomicAnd32, types.TypeMem, args[0], args[1], s.mem())
+			return nil
+		},
+		sys.AMD64, sys.MIPS, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "Or8",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			s.vars[memVar] = s.newValue3(ssa.OpAtomicOr8, types.TypeMem, args[0], args[1], s.mem())
+			return nil
+		},
+		sys.AMD64, sys.ARM64, sys.MIPS, sys.PPC64, sys.RISCV64, sys.S390X)
+	addF("runtime/internal/atomic", "Or",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			s.vars[memVar] = s.newValue3(ssa.OpAtomicOr32, types.TypeMem, args[0], args[1], s.mem())
+			return nil
+		},
+		sys.AMD64, sys.MIPS, sys.PPC64, sys.RISCV64, sys.S390X)
+
+	atomicAndOrEmitterARM64 := func(s *state, n *ir.CallExpr, args []*ssa.Value, op ssa.Op, typ types.Kind) {
+		s.vars[memVar] = s.newValue3(op, types.TypeMem, args[0], args[1], s.mem())
+	}
+
+	addF("runtime/internal/atomic", "And8",
+		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAnd8, ssa.OpAtomicAnd8Variant, types.TNIL, types.TNIL, atomicAndOrEmitterARM64),
+		sys.ARM64)
+	addF("runtime/internal/atomic", "And",
+		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAnd32, ssa.OpAtomicAnd32Variant, types.TNIL, types.TNIL, atomicAndOrEmitterARM64),
+		sys.ARM64)
+	addF("runtime/internal/atomic", "Or8",
+		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicOr8, ssa.OpAtomicOr8Variant, types.TNIL, types.TNIL, atomicAndOrEmitterARM64),
+		sys.ARM64)
+	addF("runtime/internal/atomic", "Or",
+		makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicOr32, ssa.OpAtomicOr32Variant, types.TNIL, types.TNIL, atomicAndOrEmitterARM64),
+		sys.ARM64)
+
+	// Aliases for atomic load operations
+	alias("runtime/internal/atomic", "Loadint32", "runtime/internal/atomic", "Load", all...)
+	alias("runtime/internal/atomic", "Loadint64", "runtime/internal/atomic", "Load64", all...)
+	alias("runtime/internal/atomic", "Loaduintptr", "runtime/internal/atomic", "Load", p4...)
+	alias("runtime/internal/atomic", "Loaduintptr", "runtime/internal/atomic", "Load64", p8...)
+	alias("runtime/internal/atomic", "Loaduint", "runtime/internal/atomic", "Load", p4...)
+	alias("runtime/internal/atomic", "Loaduint", "runtime/internal/atomic", "Load64", p8...)
+	alias("runtime/internal/atomic", "LoadAcq", "runtime/internal/atomic", "Load", lwatomics...)
+	alias("runtime/internal/atomic", "LoadAcq64", "runtime/internal/atomic", "Load64", lwatomics...)
+	alias("runtime/internal/atomic", "LoadAcquintptr", "runtime/internal/atomic", "LoadAcq", p4...)
+	alias("sync", "runtime_LoadAcquintptr", "runtime/internal/atomic", "LoadAcq", p4...) // linknamed
+	alias("runtime/internal/atomic", "LoadAcquintptr", "runtime/internal/atomic", "LoadAcq64", p8...)
+	alias("sync", "runtime_LoadAcquintptr", "runtime/internal/atomic", "LoadAcq64", p8...) // linknamed
+
+	// Aliases for atomic store operations
+	alias("runtime/internal/atomic", "Storeint32", "runtime/internal/atomic", "Store", all...)
+	alias("runtime/internal/atomic", "Storeint64", "runtime/internal/atomic", "Store64", all...)
+	alias("runtime/internal/atomic", "Storeuintptr", "runtime/internal/atomic", "Store", p4...)
+	alias("runtime/internal/atomic", "Storeuintptr", "runtime/internal/atomic", "Store64", p8...)
+	alias("runtime/internal/atomic", "StoreRel", "runtime/internal/atomic", "Store", lwatomics...)
+	alias("runtime/internal/atomic", "StoreRel64", "runtime/internal/atomic", "Store64", lwatomics...)
+	alias("runtime/internal/atomic", "StoreReluintptr", "runtime/internal/atomic", "StoreRel", p4...)
+	alias("sync", "runtime_StoreReluintptr", "runtime/internal/atomic", "StoreRel", p4...) // linknamed
+	alias("runtime/internal/atomic", "StoreReluintptr", "runtime/internal/atomic", "StoreRel64", p8...)
+	alias("sync", "runtime_StoreReluintptr", "runtime/internal/atomic", "StoreRel64", p8...) // linknamed
+
+	// Aliases for atomic swap operations
+	alias("runtime/internal/atomic", "Xchgint32", "runtime/internal/atomic", "Xchg", all...)
+	alias("runtime/internal/atomic", "Xchgint64", "runtime/internal/atomic", "Xchg64", all...)
+	alias("runtime/internal/atomic", "Xchguintptr", "runtime/internal/atomic", "Xchg", p4...)
+	alias("runtime/internal/atomic", "Xchguintptr", "runtime/internal/atomic", "Xchg64", p8...)
+
+	// Aliases for atomic add operations
+	alias("runtime/internal/atomic", "Xaddint32", "runtime/internal/atomic", "Xadd", all...)
+	alias("runtime/internal/atomic", "Xaddint64", "runtime/internal/atomic", "Xadd64", all...)
+	alias("runtime/internal/atomic", "Xadduintptr", "runtime/internal/atomic", "Xadd", p4...)
+	alias("runtime/internal/atomic", "Xadduintptr", "runtime/internal/atomic", "Xadd64", p8...)
+
+	// Aliases for atomic CAS operations
+	alias("runtime/internal/atomic", "Casint32", "runtime/internal/atomic", "Cas", all...)
+	alias("runtime/internal/atomic", "Casint64", "runtime/internal/atomic", "Cas64", all...)
+	alias("runtime/internal/atomic", "Casuintptr", "runtime/internal/atomic", "Cas", p4...)
+	alias("runtime/internal/atomic", "Casuintptr", "runtime/internal/atomic", "Cas64", p8...)
+	alias("runtime/internal/atomic", "Casp1", "runtime/internal/atomic", "Cas", p4...)
+	alias("runtime/internal/atomic", "Casp1", "runtime/internal/atomic", "Cas64", p8...)
+	alias("runtime/internal/atomic", "CasRel", "runtime/internal/atomic", "Cas", lwatomics...)
+
+	/******** math ********/
+	addF("math", "Sqrt",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpSqrt, types.Types[types.TFLOAT64], args[0])
+		},
+		sys.I386, sys.AMD64, sys.ARM, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.Wasm)
+	addF("math", "Trunc",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpTrunc, types.Types[types.TFLOAT64], args[0])
+		},
+		sys.ARM64, sys.PPC64, sys.S390X, sys.Wasm)
+	addF("math", "Ceil",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpCeil, types.Types[types.TFLOAT64], args[0])
+		},
+		sys.ARM64, sys.PPC64, sys.S390X, sys.Wasm)
+	addF("math", "Floor",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpFloor, types.Types[types.TFLOAT64], args[0])
+		},
+		sys.ARM64, sys.PPC64, sys.S390X, sys.Wasm)
+	addF("math", "Round",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpRound, types.Types[types.TFLOAT64], args[0])
+		},
+		sys.ARM64, sys.PPC64, sys.S390X)
+	addF("math", "RoundToEven",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpRoundToEven, types.Types[types.TFLOAT64], args[0])
+		},
+		sys.ARM64, sys.S390X, sys.Wasm)
+	addF("math", "Abs",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpAbs, types.Types[types.TFLOAT64], args[0])
+		},
+		sys.ARM64, sys.ARM, sys.PPC64, sys.Wasm)
+	addF("math", "Copysign",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue2(ssa.OpCopysign, types.Types[types.TFLOAT64], args[0], args[1])
+		},
+		sys.PPC64, sys.Wasm)
+	addF("math", "FMA",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue3(ssa.OpFMA, types.Types[types.TFLOAT64], args[0], args[1], args[2])
+		},
+		sys.ARM64, sys.PPC64, sys.S390X)
+	addF("math", "FMA",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			if !s.config.UseFMA {
+				s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64]
+				return s.variable(n, types.Types[types.TFLOAT64])
+			}
+			v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[types.TBOOL], ir.Syms.X86HasFMA)
+			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 // >= haswell cpus are common
+
+			// We have the intrinsic - use it directly.
+			s.startBlock(bTrue)
+			s.vars[n] = s.newValue3(ssa.OpFMA, types.Types[types.TFLOAT64], args[0], args[1], args[2])
+			s.endBlock().AddEdgeTo(bEnd)
+
+			// Call the pure Go version.
+			s.startBlock(bFalse)
+			s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64]
+			s.endBlock().AddEdgeTo(bEnd)
+
+			// Merge results.
+			s.startBlock(bEnd)
+			return s.variable(n, types.Types[types.TFLOAT64])
+		},
+		sys.AMD64)
+	addF("math", "FMA",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			if !s.config.UseFMA {
+				s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64]
+				return s.variable(n, types.Types[types.TFLOAT64])
+			}
+			addr := s.entryNewValue1A(ssa.OpAddr, types.Types[types.TBOOL].PtrTo(), ir.Syms.ARMHasVFPv4, s.sb)
+			v := s.load(types.Types[types.TBOOL], addr)
+			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
+
+			// We have the intrinsic - use it directly.
+			s.startBlock(bTrue)
+			s.vars[n] = s.newValue3(ssa.OpFMA, types.Types[types.TFLOAT64], args[0], args[1], args[2])
+			s.endBlock().AddEdgeTo(bEnd)
+
+			// Call the pure Go version.
+			s.startBlock(bFalse)
+			s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64]
+			s.endBlock().AddEdgeTo(bEnd)
+
+			// Merge results.
+			s.startBlock(bEnd)
+			return s.variable(n, types.Types[types.TFLOAT64])
+		},
+		sys.ARM)
+
+	makeRoundAMD64 := func(op ssa.Op) func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+		return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[types.TBOOL], ir.Syms.X86HasSSE41)
+			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[types.TFLOAT64], args[0])
+			s.endBlock().AddEdgeTo(bEnd)
+
+			// Call the pure Go version.
+			s.startBlock(bFalse)
+			s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64]
+			s.endBlock().AddEdgeTo(bEnd)
+
+			// Merge results.
+			s.startBlock(bEnd)
+			return s.variable(n, types.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",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], args[0])
+		},
+		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
+	addF("math/bits", "TrailingZeros32",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpCtz32, types.Types[types.TINT], args[0])
+		},
+		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
+	addF("math/bits", "TrailingZeros16",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			x := s.newValue1(ssa.OpZeroExt16to32, types.Types[types.TUINT32], args[0])
+			c := s.constInt32(types.Types[types.TUINT32], 1<<16)
+			y := s.newValue2(ssa.OpOr32, types.Types[types.TUINT32], x, c)
+			return s.newValue1(ssa.OpCtz32, types.Types[types.TINT], y)
+		},
+		sys.MIPS)
+	addF("math/bits", "TrailingZeros16",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpCtz16, types.Types[types.TINT], args[0])
+		},
+		sys.AMD64, sys.I386, sys.ARM, sys.ARM64, sys.Wasm)
+	addF("math/bits", "TrailingZeros16",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			x := s.newValue1(ssa.OpZeroExt16to64, types.Types[types.TUINT64], args[0])
+			c := s.constInt64(types.Types[types.TUINT64], 1<<16)
+			y := s.newValue2(ssa.OpOr64, types.Types[types.TUINT64], x, c)
+			return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], y)
+		},
+		sys.S390X, sys.PPC64)
+	addF("math/bits", "TrailingZeros8",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			x := s.newValue1(ssa.OpZeroExt8to32, types.Types[types.TUINT32], args[0])
+			c := s.constInt32(types.Types[types.TUINT32], 1<<8)
+			y := s.newValue2(ssa.OpOr32, types.Types[types.TUINT32], x, c)
+			return s.newValue1(ssa.OpCtz32, types.Types[types.TINT], y)
+		},
+		sys.MIPS)
+	addF("math/bits", "TrailingZeros8",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpCtz8, types.Types[types.TINT], args[0])
+		},
+		sys.AMD64, sys.ARM, sys.ARM64, sys.Wasm)
+	addF("math/bits", "TrailingZeros8",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			x := s.newValue1(ssa.OpZeroExt8to64, types.Types[types.TUINT64], args[0])
+			c := s.constInt64(types.Types[types.TUINT64], 1<<8)
+			y := s.newValue2(ssa.OpOr64, types.Types[types.TUINT64], x, c)
+			return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], y)
+		},
+		sys.S390X)
+	alias("math/bits", "ReverseBytes64", "runtime/internal/sys", "Bswap64", all...)
+	alias("math/bits", "ReverseBytes32", "runtime/internal/sys", "Bswap32", all...)
+	// ReverseBytes inlines correctly, no need to intrinsify it.
+	// ReverseBytes16 lowers to a rotate, no need for anything special here.
+	addF("math/bits", "Len64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], args[0])
+		},
+		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
+	addF("math/bits", "Len32",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], args[0])
+		},
+		sys.AMD64, sys.ARM64)
+	addF("math/bits", "Len32",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			if s.config.PtrSize == 4 {
+				return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], args[0])
+			}
+			x := s.newValue1(ssa.OpZeroExt32to64, types.Types[types.TUINT64], args[0])
+			return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], x)
+		},
+		sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
+	addF("math/bits", "Len16",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			if s.config.PtrSize == 4 {
+				x := s.newValue1(ssa.OpZeroExt16to32, types.Types[types.TUINT32], args[0])
+				return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], x)
+			}
+			x := s.newValue1(ssa.OpZeroExt16to64, types.Types[types.TUINT64], args[0])
+			return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], x)
+		},
+		sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
+	addF("math/bits", "Len16",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpBitLen16, types.Types[types.TINT], args[0])
+		},
+		sys.AMD64)
+	addF("math/bits", "Len8",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			if s.config.PtrSize == 4 {
+				x := s.newValue1(ssa.OpZeroExt8to32, types.Types[types.TUINT32], args[0])
+				return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], x)
+			}
+			x := s.newValue1(ssa.OpZeroExt8to64, types.Types[types.TUINT64], args[0])
+			return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], x)
+		},
+		sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
+	addF("math/bits", "Len8",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpBitLen8, types.Types[types.TINT], args[0])
+		},
+		sys.AMD64)
+	addF("math/bits", "Len",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			if s.config.PtrSize == 4 {
+				return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], args[0])
+			}
+			return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], args[0])
+		},
+		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
+	// LeadingZeros is handled because it trivially calls Len.
+	addF("math/bits", "Reverse64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpBitRev64, types.Types[types.TINT], args[0])
+		},
+		sys.ARM64)
+	addF("math/bits", "Reverse32",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpBitRev32, types.Types[types.TINT], args[0])
+		},
+		sys.ARM64)
+	addF("math/bits", "Reverse16",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpBitRev16, types.Types[types.TINT], args[0])
+		},
+		sys.ARM64)
+	addF("math/bits", "Reverse8",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpBitRev8, types.Types[types.TINT], args[0])
+		},
+		sys.ARM64)
+	addF("math/bits", "Reverse",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			if s.config.PtrSize == 4 {
+				return s.newValue1(ssa.OpBitRev32, types.Types[types.TINT], args[0])
+			}
+			return s.newValue1(ssa.OpBitRev64, types.Types[types.TINT], args[0])
+		},
+		sys.ARM64)
+	addF("math/bits", "RotateLeft8",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue2(ssa.OpRotateLeft8, types.Types[types.TUINT8], args[0], args[1])
+		},
+		sys.AMD64)
+	addF("math/bits", "RotateLeft16",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue2(ssa.OpRotateLeft16, types.Types[types.TUINT16], args[0], args[1])
+		},
+		sys.AMD64)
+	addF("math/bits", "RotateLeft32",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue2(ssa.OpRotateLeft32, types.Types[types.TUINT32], args[0], args[1])
+		},
+		sys.AMD64, sys.ARM, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
+	addF("math/bits", "RotateLeft64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue2(ssa.OpRotateLeft64, types.Types[types.TUINT64], args[0], args[1])
+		},
+		sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
+	alias("math/bits", "RotateLeft", "math/bits", "RotateLeft64", p8...)
+
+	makeOnesCountAMD64 := func(op64 ssa.Op, op32 ssa.Op) func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+		return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[types.TBOOL], ir.Syms.X86HasPOPCNT)
+			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 popcnt nowadays
+
+			// We have the intrinsic - use it directly.
+			s.startBlock(bTrue)
+			op := op64
+			if s.config.PtrSize == 4 {
+				op = op32
+			}
+			s.vars[n] = s.newValue1(op, types.Types[types.TINT], args[0])
+			s.endBlock().AddEdgeTo(bEnd)
+
+			// Call the pure Go version.
+			s.startBlock(bFalse)
+			s.vars[n] = s.callResult(n, callNormal) // types.Types[TINT]
+			s.endBlock().AddEdgeTo(bEnd)
+
+			// Merge results.
+			s.startBlock(bEnd)
+			return s.variable(n, types.Types[types.TINT])
+		}
+	}
+	addF("math/bits", "OnesCount64",
+		makeOnesCountAMD64(ssa.OpPopCount64, ssa.OpPopCount64),
+		sys.AMD64)
+	addF("math/bits", "OnesCount64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpPopCount64, types.Types[types.TINT], args[0])
+		},
+		sys.PPC64, sys.ARM64, sys.S390X, sys.Wasm)
+	addF("math/bits", "OnesCount32",
+		makeOnesCountAMD64(ssa.OpPopCount32, ssa.OpPopCount32),
+		sys.AMD64)
+	addF("math/bits", "OnesCount32",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpPopCount32, types.Types[types.TINT], args[0])
+		},
+		sys.PPC64, sys.ARM64, sys.S390X, sys.Wasm)
+	addF("math/bits", "OnesCount16",
+		makeOnesCountAMD64(ssa.OpPopCount16, ssa.OpPopCount16),
+		sys.AMD64)
+	addF("math/bits", "OnesCount16",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpPopCount16, types.Types[types.TINT], args[0])
+		},
+		sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
+	addF("math/bits", "OnesCount8",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue1(ssa.OpPopCount8, types.Types[types.TINT], args[0])
+		},
+		sys.S390X, sys.PPC64, sys.Wasm)
+	addF("math/bits", "OnesCount",
+		makeOnesCountAMD64(ssa.OpPopCount64, ssa.OpPopCount32),
+		sys.AMD64)
+	addF("math/bits", "Mul64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue2(ssa.OpMul64uhilo, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1])
+		},
+		sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X, sys.MIPS64)
+	alias("math/bits", "Mul", "math/bits", "Mul64", sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64, sys.ArchPPC64LE, sys.ArchS390X, sys.ArchMIPS64, sys.ArchMIPS64LE)
+	alias("runtime/internal/math", "Mul64", "math/bits", "Mul64", sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64, sys.ArchPPC64LE, sys.ArchS390X, sys.ArchMIPS64, sys.ArchMIPS64LE)
+	addF("math/bits", "Add64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue3(ssa.OpAdd64carry, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1], args[2])
+		},
+		sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X)
+	alias("math/bits", "Add", "math/bits", "Add64", sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64, sys.ArchPPC64LE, sys.ArchS390X)
+	addF("math/bits", "Sub64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue3(ssa.OpSub64borrow, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1], args[2])
+		},
+		sys.AMD64, sys.ARM64, sys.S390X)
+	alias("math/bits", "Sub", "math/bits", "Sub64", sys.ArchAMD64, sys.ArchARM64, sys.ArchS390X)
+	addF("math/bits", "Div64",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			// check for divide-by-zero/overflow and panic with appropriate message
+			cmpZero := s.newValue2(s.ssaOp(ir.ONE, types.Types[types.TUINT64]), types.Types[types.TBOOL], args[2], s.zeroVal(types.Types[types.TUINT64]))
+			s.check(cmpZero, ir.Syms.Panicdivide)
+			cmpOverflow := s.newValue2(s.ssaOp(ir.OLT, types.Types[types.TUINT64]), types.Types[types.TBOOL], args[0], args[2])
+			s.check(cmpOverflow, ir.Syms.Panicoverflow)
+			return s.newValue3(ssa.OpDiv128u, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1], args[2])
+		},
+		sys.AMD64)
+	alias("math/bits", "Div", "math/bits", "Div64", sys.ArchAMD64)
+
+	alias("runtime/internal/sys", "Ctz8", "math/bits", "TrailingZeros8", all...)
+	alias("runtime/internal/sys", "TrailingZeros8", "math/bits", "TrailingZeros8", all...)
+	alias("runtime/internal/sys", "TrailingZeros64", "math/bits", "TrailingZeros64", all...)
+	alias("runtime/internal/sys", "Len8", "math/bits", "Len8", all...)
+	alias("runtime/internal/sys", "Len64", "math/bits", "Len64", all...)
+	alias("runtime/internal/sys", "OnesCount64", "math/bits", "OnesCount64", all...)
+
+	/******** sync/atomic ********/
+
+	// Note: these are disabled by flag_race in findIntrinsic below.
+	alias("sync/atomic", "LoadInt32", "runtime/internal/atomic", "Load", all...)
+	alias("sync/atomic", "LoadInt64", "runtime/internal/atomic", "Load64", all...)
+	alias("sync/atomic", "LoadPointer", "runtime/internal/atomic", "Loadp", all...)
+	alias("sync/atomic", "LoadUint32", "runtime/internal/atomic", "Load", all...)
+	alias("sync/atomic", "LoadUint64", "runtime/internal/atomic", "Load64", all...)
+	alias("sync/atomic", "LoadUintptr", "runtime/internal/atomic", "Load", p4...)
+	alias("sync/atomic", "LoadUintptr", "runtime/internal/atomic", "Load64", p8...)
+
+	alias("sync/atomic", "StoreInt32", "runtime/internal/atomic", "Store", all...)
+	alias("sync/atomic", "StoreInt64", "runtime/internal/atomic", "Store64", all...)
+	// Note: not StorePointer, that needs a write barrier.  Same below for {CompareAnd}Swap.
+	alias("sync/atomic", "StoreUint32", "runtime/internal/atomic", "Store", all...)
+	alias("sync/atomic", "StoreUint64", "runtime/internal/atomic", "Store64", all...)
+	alias("sync/atomic", "StoreUintptr", "runtime/internal/atomic", "Store", p4...)
+	alias("sync/atomic", "StoreUintptr", "runtime/internal/atomic", "Store64", p8...)
+
+	alias("sync/atomic", "SwapInt32", "runtime/internal/atomic", "Xchg", all...)
+	alias("sync/atomic", "SwapInt64", "runtime/internal/atomic", "Xchg64", all...)
+	alias("sync/atomic", "SwapUint32", "runtime/internal/atomic", "Xchg", all...)
+	alias("sync/atomic", "SwapUint64", "runtime/internal/atomic", "Xchg64", all...)
+	alias("sync/atomic", "SwapUintptr", "runtime/internal/atomic", "Xchg", p4...)
+	alias("sync/atomic", "SwapUintptr", "runtime/internal/atomic", "Xchg64", p8...)
+
+	alias("sync/atomic", "CompareAndSwapInt32", "runtime/internal/atomic", "Cas", all...)
+	alias("sync/atomic", "CompareAndSwapInt64", "runtime/internal/atomic", "Cas64", all...)
+	alias("sync/atomic", "CompareAndSwapUint32", "runtime/internal/atomic", "Cas", all...)
+	alias("sync/atomic", "CompareAndSwapUint64", "runtime/internal/atomic", "Cas64", all...)
+	alias("sync/atomic", "CompareAndSwapUintptr", "runtime/internal/atomic", "Cas", p4...)
+	alias("sync/atomic", "CompareAndSwapUintptr", "runtime/internal/atomic", "Cas64", p8...)
+
+	alias("sync/atomic", "AddInt32", "runtime/internal/atomic", "Xadd", all...)
+	alias("sync/atomic", "AddInt64", "runtime/internal/atomic", "Xadd64", all...)
+	alias("sync/atomic", "AddUint32", "runtime/internal/atomic", "Xadd", all...)
+	alias("sync/atomic", "AddUint64", "runtime/internal/atomic", "Xadd64", all...)
+	alias("sync/atomic", "AddUintptr", "runtime/internal/atomic", "Xadd", p4...)
+	alias("sync/atomic", "AddUintptr", "runtime/internal/atomic", "Xadd64", p8...)
+
+	/******** math/big ********/
+	add("math/big", "mulWW",
+		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+			return s.newValue2(ssa.OpMul64uhilo, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1])
+		},
+		sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64LE, sys.ArchPPC64, sys.ArchS390X)
+}
+
+// findIntrinsic returns a function which builds the SSA equivalent of the
+// function identified by the symbol sym.  If sym is not an intrinsic call, returns nil.
+func findIntrinsic(sym *types.Sym) intrinsicBuilder {
+	if sym == nil || sym.Pkg == nil {
+		return nil
+	}
+	pkg := sym.Pkg.Path
+	if sym.Pkg == types.LocalPkg {
+		pkg = base.Ctxt.Pkgpath
+	}
+	if sym.Pkg == ir.Pkgs.Runtime {
+		pkg = "runtime"
+	}
+	if base.Flag.Race && pkg == "sync/atomic" {
+		// The race detector needs to be able to intercept these calls.
+		// We can't intrinsify them.
+		return nil
+	}
+	// Skip intrinsifying math functions (which may contain hard-float
+	// instructions) when soft-float
+	if Arch.SoftFloat && pkg == "math" {
+		return nil
+	}
+
+	fn := sym.Name
+	if ssa.IntrinsicsDisable {
+		if pkg == "runtime" && (fn == "getcallerpc" || fn == "getcallersp" || fn == "getclosureptr") {
+			// These runtime functions don't have definitions, must be intrinsics.
+		} else {
+			return nil
+		}
+	}
+	return intrinsics[intrinsicKey{Arch.LinkArch.Arch, pkg, fn}]
+}
+
+func IsIntrinsicCall(n *ir.CallExpr) bool {
+	if n == nil {
+		return false
+	}
+	name, ok := n.X.(*ir.Name)
+	if !ok {
+		return false
+	}
+	return findIntrinsic(name.Sym()) != nil
+}
+
+// intrinsicCall converts a call to a recognized intrinsic function into the intrinsic SSA operation.
+func (s *state) intrinsicCall(n *ir.CallExpr) *ssa.Value {
+	v := findIntrinsic(n.X.Sym())(s, n, s.intrinsicArgs(n))
+	if ssa.IntrinsicsDebug > 0 {
+		x := v
+		if x == nil {
+			x = s.mem()
+		}
+		if x.Op == ssa.OpSelect0 || x.Op == ssa.OpSelect1 {
+			x = x.Args[0]
+		}
+		base.WarnfAt(n.Pos(), "intrinsic substitution for %v with %s", n.X.Sym().Name, x.LongString())
+	}
+	return v
+}
+
+// intrinsicArgs extracts args from n, evaluates them to SSA values, and returns them.
+func (s *state) intrinsicArgs(n *ir.CallExpr) []*ssa.Value {
+	args := make([]*ssa.Value, len(n.Args))
+	for i, n := range n.Args {
+		args[i] = s.expr(n)
+	}
+	return args
+}
+
+// openDeferRecord adds code to evaluate and store the args for an open-code defer
+// call, and records info about the defer, so we can generate proper code on the
+// exit paths. n is the sub-node of the defer node that is the actual function
+// call. We will also record funcdata information on where the args are stored
+// (as well as the deferBits variable), and this will enable us to run the proper
+// defer calls during panics.
+func (s *state) openDeferRecord(n *ir.CallExpr) {
+	var args []*ssa.Value
+	var argNodes []*ir.Name
+
+	if buildcfg.Experiment.RegabiDefer && (len(n.Args) != 0 || n.Op() == ir.OCALLINTER || n.X.Type().NumResults() != 0) {
+		s.Fatalf("defer call with arguments or results: %v", n)
+	}
+
+	opendefer := &openDeferInfo{
+		n: n,
+	}
+	fn := n.X
+	if n.Op() == ir.OCALLFUNC {
+		// We must always store the function value in a stack slot for the
+		// runtime panic code to use. But in the defer exit code, we will
+		// call the function directly if it is a static function.
+		closureVal := s.expr(fn)
+		closure := s.openDeferSave(nil, fn.Type(), closureVal)
+		opendefer.closureNode = closure.Aux.(*ir.Name)
+		if !(fn.Op() == ir.ONAME && fn.(*ir.Name).Class == ir.PFUNC) {
+			opendefer.closure = closure
+		}
+	} else if n.Op() == ir.OCALLMETH {
+		base.Fatalf("OCALLMETH missed by walkCall")
+	} else {
+		if fn.Op() != ir.ODOTINTER {
+			base.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op())
+		}
+		fn := fn.(*ir.SelectorExpr)
+		closure, rcvr := s.getClosureAndRcvr(fn)
+		opendefer.closure = s.openDeferSave(nil, closure.Type, closure)
+		// Important to get the receiver type correct, so it is recognized
+		// as a pointer for GC purposes.
+		opendefer.rcvr = s.openDeferSave(nil, fn.Type().Recv().Type, rcvr)
+		opendefer.closureNode = opendefer.closure.Aux.(*ir.Name)
+		opendefer.rcvrNode = opendefer.rcvr.Aux.(*ir.Name)
+	}
+	for _, argn := range n.Args {
+		var v *ssa.Value
+		if TypeOK(argn.Type()) {
+			v = s.openDeferSave(nil, argn.Type(), s.expr(argn))
+		} else {
+			v = s.openDeferSave(argn, argn.Type(), nil)
+		}
+		args = append(args, v)
+		argNodes = append(argNodes, v.Aux.(*ir.Name))
+	}
+	opendefer.argVals = args
+	opendefer.argNodes = argNodes
+	index := len(s.openDefers)
+	s.openDefers = append(s.openDefers, opendefer)
+
+	// Update deferBits only after evaluation and storage to stack of
+	// args/receiver/interface is successful.
+	bitvalue := s.constInt8(types.Types[types.TUINT8], 1<<uint(index))
+	newDeferBits := s.newValue2(ssa.OpOr8, types.Types[types.TUINT8], s.variable(deferBitsVar, types.Types[types.TUINT8]), bitvalue)
+	s.vars[deferBitsVar] = newDeferBits
+	s.store(types.Types[types.TUINT8], s.deferBitsAddr, newDeferBits)
+}
+
+// openDeferSave generates SSA nodes to store a value (with type t) for an
+// open-coded defer at an explicit autotmp location on the stack, so it can be
+// reloaded and used for the appropriate call on exit. If type t is SSAable, then
+// val must be non-nil (and n should be nil) and val is the value to be stored. If
+// type t is non-SSAable, then n must be non-nil (and val should be nil) and n is
+// evaluated (via s.addr() below) to get the value that is to be stored. The
+// function returns an SSA value representing a pointer to the autotmp location.
+func (s *state) openDeferSave(n ir.Node, t *types.Type, val *ssa.Value) *ssa.Value {
+	canSSA := TypeOK(t)
+	var pos src.XPos
+	if canSSA {
+		pos = val.Pos
+	} else {
+		pos = n.Pos()
+	}
+	argTemp := typecheck.TempAt(pos.WithNotStmt(), s.curfn, t)
+	argTemp.SetOpenDeferSlot(true)
+	var addrArgTemp *ssa.Value
+	// Use OpVarLive to make sure stack slots for the args, etc. are not
+	// removed by dead-store elimination
+	if s.curBlock.ID != s.f.Entry.ID {
+		// Force the argtmp storing this defer function/receiver/arg to be
+		// declared in the entry block, so that it will be live for the
+		// defer exit code (which will actually access it only if the
+		// associated defer call has been activated).
+		s.defvars[s.f.Entry.ID][memVar] = s.f.Entry.NewValue1A(src.NoXPos, ssa.OpVarDef, types.TypeMem, argTemp, s.defvars[s.f.Entry.ID][memVar])
+		s.defvars[s.f.Entry.ID][memVar] = s.f.Entry.NewValue1A(src.NoXPos, ssa.OpVarLive, types.TypeMem, argTemp, s.defvars[s.f.Entry.ID][memVar])
+		addrArgTemp = s.f.Entry.NewValue2A(src.NoXPos, ssa.OpLocalAddr, types.NewPtr(argTemp.Type()), argTemp, s.sp, s.defvars[s.f.Entry.ID][memVar])
+	} else {
+		// Special case if we're still in the entry block. We can't use
+		// the above code, since s.defvars[s.f.Entry.ID] isn't defined
+		// until we end the entry block with s.endBlock().
+		s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, argTemp, s.mem(), false)
+		s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, argTemp, s.mem(), false)
+		addrArgTemp = s.newValue2Apos(ssa.OpLocalAddr, types.NewPtr(argTemp.Type()), argTemp, s.sp, s.mem(), false)
+	}
+	if t.HasPointers() {
+		// Since we may use this argTemp during exit depending on the
+		// deferBits, we must define it unconditionally on entry.
+		// Therefore, we must make sure it is zeroed out in the entry
+		// block if it contains pointers, else GC may wrongly follow an
+		// uninitialized pointer value.
+		argTemp.SetNeedzero(true)
+	}
+	if !canSSA {
+		a := s.addr(n)
+		s.move(t, addrArgTemp, a)
+		return addrArgTemp
+	}
+	// We are storing to the stack, hence we can avoid the full checks in
+	// storeType() (no write barrier) and do a simple store().
+	s.store(t, addrArgTemp, val)
+	return addrArgTemp
+}
+
+// openDeferExit generates SSA for processing all the open coded defers at exit.
+// The code involves loading deferBits, and checking each of the bits to see if
+// the corresponding defer statement was executed. For each bit that is turned
+// on, the associated defer call is made.
+func (s *state) openDeferExit() {
+	deferExit := s.f.NewBlock(ssa.BlockPlain)
+	s.endBlock().AddEdgeTo(deferExit)
+	s.startBlock(deferExit)
+	s.lastDeferExit = deferExit
+	s.lastDeferCount = len(s.openDefers)
+	zeroval := s.constInt8(types.Types[types.TUINT8], 0)
+	// Test for and run defers in reverse order
+	for i := len(s.openDefers) - 1; i >= 0; i-- {
+		r := s.openDefers[i]
+		bCond := s.f.NewBlock(ssa.BlockPlain)
+		bEnd := s.f.NewBlock(ssa.BlockPlain)
+
+		deferBits := s.variable(deferBitsVar, types.Types[types.TUINT8])
+		// Generate code to check if the bit associated with the current
+		// defer is set.
+		bitval := s.constInt8(types.Types[types.TUINT8], 1<<uint(i))
+		andval := s.newValue2(ssa.OpAnd8, types.Types[types.TUINT8], deferBits, bitval)
+		eqVal := s.newValue2(ssa.OpEq8, types.Types[types.TBOOL], andval, zeroval)
+		b := s.endBlock()
+		b.Kind = ssa.BlockIf
+		b.SetControl(eqVal)
+		b.AddEdgeTo(bEnd)
+		b.AddEdgeTo(bCond)
+		bCond.AddEdgeTo(bEnd)
+		s.startBlock(bCond)
+
+		// Clear this bit in deferBits and force store back to stack, so
+		// we will not try to re-run this defer call if this defer call panics.
+		nbitval := s.newValue1(ssa.OpCom8, types.Types[types.TUINT8], bitval)
+		maskedval := s.newValue2(ssa.OpAnd8, types.Types[types.TUINT8], deferBits, nbitval)
+		s.store(types.Types[types.TUINT8], s.deferBitsAddr, maskedval)
+		// Use this value for following tests, so we keep previous
+		// bits cleared.
+		s.vars[deferBitsVar] = maskedval
+
+		// Generate code to call the function call of the defer, using the
+		// closure/receiver/args that were stored in argtmps at the point
+		// of the defer statement.
+		fn := r.n.X
+		stksize := fn.Type().ArgWidth()
+		var ACArgs []*types.Type
+		var ACResults []*types.Type
+		var callArgs []*ssa.Value
+		if r.rcvr != nil {
+			// rcvr in case of OCALLINTER
+			v := s.load(r.rcvr.Type.Elem(), r.rcvr)
+			ACArgs = append(ACArgs, types.Types[types.TUINTPTR])
+			callArgs = append(callArgs, v)
+		}
+		for j, argAddrVal := range r.argVals {
+			f := getParam(r.n, j)
+			ACArgs = append(ACArgs, f.Type)
+			var a *ssa.Value
+			if !TypeOK(f.Type) {
+				a = s.newValue2(ssa.OpDereference, f.Type, argAddrVal, s.mem())
+			} else {
+				a = s.load(f.Type, argAddrVal)
+			}
+			callArgs = append(callArgs, a)
+		}
+		var call *ssa.Value
+		if r.closure != nil {
+			v := s.load(r.closure.Type.Elem(), r.closure)
+			s.maybeNilCheckClosure(v, callDefer)
+			codeptr := s.rawLoad(types.Types[types.TUINTPTR], v)
+			aux := ssa.ClosureAuxCall(s.f.ABIDefault.ABIAnalyzeTypes(nil, ACArgs, ACResults))
+			call = s.newValue2A(ssa.OpClosureLECall, aux.LateExpansionResultType(), aux, codeptr, v)
+		} else {
+			aux := ssa.StaticAuxCall(fn.(*ir.Name).Linksym(), s.f.ABIDefault.ABIAnalyzeTypes(nil, ACArgs, ACResults))
+			call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
+		}
+		callArgs = append(callArgs, s.mem())
+		call.AddArgs(callArgs...)
+		call.AuxInt = stksize
+		s.vars[memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call)
+		// Make sure that the stack slots with pointers are kept live
+		// through the call (which is a pre-emption point). Also, we will
+		// use the first call of the last defer exit to compute liveness
+		// for the deferreturn, so we want all stack slots to be live.
+		if r.closureNode != nil {
+			s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, r.closureNode, s.mem(), false)
+		}
+		if r.rcvrNode != nil {
+			if r.rcvrNode.Type().HasPointers() {
+				s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, r.rcvrNode, s.mem(), false)
+			}
+		}
+		for _, argNode := range r.argNodes {
+			if argNode.Type().HasPointers() {
+				s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, argNode, s.mem(), false)
+			}
+		}
+
+		s.endBlock()
+		s.startBlock(bEnd)
+	}
+}
+
+func (s *state) callResult(n *ir.CallExpr, k callKind) *ssa.Value {
+	return s.call(n, k, false)
+}
+
+func (s *state) callAddr(n *ir.CallExpr, k callKind) *ssa.Value {
+	return s.call(n, k, true)
+}
+
+// Calls the function n using the specified call type.
+// Returns the address of the return value (or nil if none).
+func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Value {
+	s.prevCall = nil
+	var callee *ir.Name    // target function (if static)
+	var closure *ssa.Value // ptr to closure to run (if dynamic)
+	var codeptr *ssa.Value // ptr to target code (if dynamic)
+	var rcvr *ssa.Value    // receiver to set
+	fn := n.X
+	var ACArgs []*types.Type    // AuxCall args
+	var ACResults []*types.Type // AuxCall results
+	var callArgs []*ssa.Value   // For late-expansion, the args themselves (not stored, args to the call instead).
+
+	callABI := s.f.ABIDefault
+
+	if !buildcfg.Experiment.RegabiArgs {
+		var magicFnNameSym *types.Sym
+		if fn.Name() != nil {
+			magicFnNameSym = fn.Name().Sym()
+			ss := magicFnNameSym.Name
+			if strings.HasSuffix(ss, magicNameDotSuffix) {
+				callABI = s.f.ABI1
+			}
+		}
+		if magicFnNameSym == nil && n.Op() == ir.OCALLINTER {
+			magicFnNameSym = fn.(*ir.SelectorExpr).Sym()
+			ss := magicFnNameSym.Name
+			if strings.HasSuffix(ss, magicNameDotSuffix[1:]) {
+				callABI = s.f.ABI1
+			}
+		}
+	}
+
+	if buildcfg.Experiment.RegabiDefer && k != callNormal && (len(n.Args) != 0 || n.Op() == ir.OCALLINTER || n.X.Type().NumResults() != 0) {
+		s.Fatalf("go/defer call with arguments: %v", n)
+	}
+
+	switch n.Op() {
+	case ir.OCALLFUNC:
+		if k == callNormal && fn.Op() == ir.ONAME && fn.(*ir.Name).Class == ir.PFUNC {
+			fn := fn.(*ir.Name)
+			callee = fn
+			if buildcfg.Experiment.RegabiArgs {
+				// This is a static call, so it may be
+				// a direct call to a non-ABIInternal
+				// function. fn.Func may be nil for
+				// some compiler-generated functions,
+				// but those are all ABIInternal.
+				if fn.Func != nil {
+					callABI = abiForFunc(fn.Func, s.f.ABI0, s.f.ABI1)
+				}
+			} else {
+				// TODO(register args) remove after register abi is working
+				inRegistersImported := fn.Pragma()&ir.RegisterParams != 0
+				inRegistersSamePackage := fn.Func != nil && fn.Func.Pragma&ir.RegisterParams != 0
+				if inRegistersImported || inRegistersSamePackage {
+					callABI = s.f.ABI1
+				}
+			}
+			break
+		}
+		closure = s.expr(fn)
+		if k != callDefer && k != callDeferStack {
+			// Deferred nil function needs to panic when the function is invoked,
+			// not the point of defer statement.
+			s.maybeNilCheckClosure(closure, k)
+		}
+	case ir.OCALLMETH:
+		base.Fatalf("OCALLMETH missed by walkCall")
+	case ir.OCALLINTER:
+		if fn.Op() != ir.ODOTINTER {
+			s.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op())
+		}
+		fn := fn.(*ir.SelectorExpr)
+		var iclosure *ssa.Value
+		iclosure, rcvr = s.getClosureAndRcvr(fn)
+		if k == callNormal {
+			codeptr = s.load(types.Types[types.TUINTPTR], iclosure)
+		} else {
+			closure = iclosure
+		}
+	}
+
+	if !buildcfg.Experiment.RegabiArgs {
+		if regAbiForFuncType(n.X.Type().FuncType()) {
+			// Magic last type in input args to call
+			callABI = s.f.ABI1
+		}
+	}
+
+	params := callABI.ABIAnalyze(n.X.Type(), false /* Do not set (register) nNames from caller side -- can cause races. */)
+	types.CalcSize(fn.Type())
+	stksize := params.ArgWidth() // includes receiver, args, and results
+
+	res := n.X.Type().Results()
+	if k == callNormal {
+		for _, p := range params.OutParams() {
+			ACResults = append(ACResults, p.Type)
+		}
+	}
+
+	var call *ssa.Value
+	if k == callDeferStack {
+		// Make a defer struct d on the stack.
+		t := deferstruct(stksize)
+		d := typecheck.TempAt(n.Pos(), s.curfn, t)
+
+		s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, d, s.mem())
+		addr := s.addr(d)
+
+		// Must match reflect.go:deferstruct and src/runtime/runtime2.go:_defer.
+		// 0: siz
+		s.store(types.Types[types.TUINT32],
+			s.newValue1I(ssa.OpOffPtr, types.Types[types.TUINT32].PtrTo(), t.FieldOff(0), addr),
+			s.constInt32(types.Types[types.TUINT32], int32(stksize)))
+		// 1: started, set in deferprocStack
+		// 2: heap, set in deferprocStack
+		// 3: openDefer
+		// 4: sp, set in deferprocStack
+		// 5: pc, set in deferprocStack
+		// 6: fn
+		s.store(closure.Type,
+			s.newValue1I(ssa.OpOffPtr, closure.Type.PtrTo(), t.FieldOff(6), addr),
+			closure)
+		// 7: panic, set in deferprocStack
+		// 8: link, set in deferprocStack
+		// 9: framepc
+		// 10: varp
+		// 11: fd
+
+		// Then, store all the arguments of the defer call.
+		ft := fn.Type()
+		off := t.FieldOff(12) // TODO register args: be sure this isn't a hardcoded param stack offset.
+		args := n.Args
+		i0 := 0
+
+		// Set receiver (for interface calls). Always a pointer.
+		if rcvr != nil {
+			p := s.newValue1I(ssa.OpOffPtr, ft.Recv().Type.PtrTo(), off, addr)
+			s.store(types.Types[types.TUINTPTR], p, rcvr)
+			i0 = 1
+		}
+		// Set receiver (for method calls).
+		if n.Op() == ir.OCALLMETH {
+			base.Fatalf("OCALLMETH missed by walkCall")
+		}
+		// Set other args.
+		// This code is only used when RegabiDefer is not enabled, and arguments are always
+		// passed on stack.
+		for i, f := range ft.Params().Fields().Slice() {
+			s.storeArgWithBase(args[0], f.Type, addr, off+params.InParam(i+i0).FrameOffset(params))
+			args = args[1:]
+		}
+
+		// Call runtime.deferprocStack with pointer to _defer record.
+		ACArgs = append(ACArgs, types.Types[types.TUINTPTR])
+		aux := ssa.StaticAuxCall(ir.Syms.DeferprocStack, s.f.ABIDefault.ABIAnalyzeTypes(nil, ACArgs, ACResults))
+		callArgs = append(callArgs, addr, s.mem())
+		call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
+		call.AddArgs(callArgs...)
+		if stksize < int64(types.PtrSize) {
+			// We need room for both the call to deferprocStack and the call to
+			// the deferred function.
+			stksize = int64(types.PtrSize)
+		}
+		call.AuxInt = stksize
+	} else {
+		// Store arguments to stack, including defer/go arguments and receiver for method calls.
+		// These are written in SP-offset order.
+		argStart := base.Ctxt.FixedFrameSize()
+		// Defer/go args.
+		if k != callNormal {
+			// Write argsize and closure (args to newproc/deferproc).
+			argsize := s.constInt32(types.Types[types.TUINT32], int32(stksize))
+			ACArgs = append(ACArgs, types.Types[types.TUINT32]) // not argExtra
+			callArgs = append(callArgs, argsize)
+			ACArgs = append(ACArgs, types.Types[types.TUINTPTR])
+			callArgs = append(callArgs, closure)
+			stksize += 2 * int64(types.PtrSize)
+			argStart += 2 * int64(types.PtrSize)
+		}
+
+		// Set receiver (for interface calls).
+		if rcvr != nil {
+			callArgs = append(callArgs, rcvr)
+		}
+
+		// Write args.
+		t := n.X.Type()
+		args := n.Args
+		if n.Op() == ir.OCALLMETH {
+			base.Fatalf("OCALLMETH missed by walkCall")
+		}
+
+		for _, p := range params.InParams() { // includes receiver for interface calls
+			ACArgs = append(ACArgs, p.Type)
+		}
+		for i, n := range args {
+			callArgs = append(callArgs, s.putArg(n, t.Params().Field(i).Type))
+		}
+
+		callArgs = append(callArgs, s.mem())
+
+		// call target
+		switch {
+		case k == callDefer:
+			aux := ssa.StaticAuxCall(ir.Syms.Deferproc, s.f.ABIDefault.ABIAnalyzeTypes(nil, ACArgs, ACResults)) // TODO paramResultInfo for DeferProc
+			call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
+		case k == callGo:
+			aux := ssa.StaticAuxCall(ir.Syms.Newproc, s.f.ABIDefault.ABIAnalyzeTypes(nil, ACArgs, ACResults))
+			call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux) // TODO paramResultInfo for NewProc
+		case closure != nil:
+			// rawLoad because loading the code pointer from a
+			// closure is always safe, but IsSanitizerSafeAddr
+			// can't always figure that out currently, and it's
+			// critical that we not clobber any arguments already
+			// stored onto the stack.
+			codeptr = s.rawLoad(types.Types[types.TUINTPTR], closure)
+			aux := ssa.ClosureAuxCall(callABI.ABIAnalyzeTypes(nil, ACArgs, ACResults))
+			call = s.newValue2A(ssa.OpClosureLECall, aux.LateExpansionResultType(), aux, codeptr, closure)
+		case codeptr != nil:
+			// Note that the "receiver" parameter is nil because the actual receiver is the first input parameter.
+			aux := ssa.InterfaceAuxCall(params)
+			call = s.newValue1A(ssa.OpInterLECall, aux.LateExpansionResultType(), aux, codeptr)
+		case callee != nil:
+			aux := ssa.StaticAuxCall(callTargetLSym(callee), params)
+			call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
+		default:
+			s.Fatalf("bad call type %v %v", n.Op(), n)
+		}
+		call.AddArgs(callArgs...)
+		call.AuxInt = stksize // Call operations carry the argsize of the callee along with them
+	}
+	s.prevCall = call
+	s.vars[memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call)
+	// Insert OVARLIVE nodes
+	for _, name := range n.KeepAlive {
+		s.stmt(ir.NewUnaryExpr(n.Pos(), ir.OVARLIVE, name))
+	}
+
+	// Finish block for defers
+	if k == callDefer || k == callDeferStack {
+		b := s.endBlock()
+		b.Kind = ssa.BlockDefer
+		b.SetControl(call)
+		bNext := s.f.NewBlock(ssa.BlockPlain)
+		b.AddEdgeTo(bNext)
+		// Add recover edge to exit code.
+		r := s.f.NewBlock(ssa.BlockPlain)
+		s.startBlock(r)
+		s.exit()
+		b.AddEdgeTo(r)
+		b.Likely = ssa.BranchLikely
+		s.startBlock(bNext)
+	}
+
+	if res.NumFields() == 0 || k != callNormal {
+		// call has no return value. Continue with the next statement.
+		return nil
+	}
+	fp := res.Field(0)
+	if returnResultAddr {
+		return s.resultAddrOfCall(call, 0, fp.Type)
+	}
+	return s.newValue1I(ssa.OpSelectN, fp.Type, 0, call)
+}
+
+// maybeNilCheckClosure checks if a nil check of a closure is needed in some
+// architecture-dependent situations and, if so, emits the nil check.
+func (s *state) maybeNilCheckClosure(closure *ssa.Value, k callKind) {
+	if Arch.LinkArch.Family == sys.Wasm || buildcfg.GOOS == "aix" && k != callGo {
+		// On AIX, the closure needs to be verified as fn can be nil, except if it's a call go. This needs to be handled by the runtime to have the "go of nil func value" error.
+		// TODO(neelance): On other architectures this should be eliminated by the optimization steps
+		s.nilCheck(closure)
+	}
+}
+
+// getClosureAndRcvr returns values for the appropriate closure and receiver of an
+// interface call
+func (s *state) getClosureAndRcvr(fn *ir.SelectorExpr) (*ssa.Value, *ssa.Value) {
+	i := s.expr(fn.X)
+	itab := s.newValue1(ssa.OpITab, types.Types[types.TUINTPTR], i)
+	s.nilCheck(itab)
+	itabidx := fn.Offset() + 2*int64(types.PtrSize) + 8 // offset of fun field in runtime.itab
+	closure := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.UintptrPtr, itabidx, itab)
+	rcvr := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, i)
+	return closure, rcvr
+}
+
+// etypesign returns the signed-ness of e, for integer/pointer etypes.
+// -1 means signed, +1 means unsigned, 0 means non-integer/non-pointer.
+func etypesign(e types.Kind) int8 {
+	switch e {
+	case types.TINT8, types.TINT16, types.TINT32, types.TINT64, types.TINT:
+		return -1
+	case types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64, types.TUINT, types.TUINTPTR, types.TUNSAFEPTR:
+		return +1
+	}
+	return 0
+}
+
+// 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.
+func (s *state) addr(n ir.Node) *ssa.Value {
+	if n.Op() != ir.ONAME {
+		s.pushLine(n.Pos())
+		defer s.popLine()
+	}
+
+	if s.canSSA(n) {
+		s.Fatalf("addr of canSSA expression: %+v", n)
+	}
+
+	t := types.NewPtr(n.Type())
+	linksymOffset := func(lsym *obj.LSym, offset int64) *ssa.Value {
+		v := s.entryNewValue1A(ssa.OpAddr, t, lsym, s.sb)
+		// TODO: Make OpAddr use AuxInt as well as Aux.
+		if offset != 0 {
+			v = s.entryNewValue1I(ssa.OpOffPtr, v.Type, offset, v)
+		}
+		return v
+	}
+	switch n.Op() {
+	case ir.OLINKSYMOFFSET:
+		no := n.(*ir.LinksymOffsetExpr)
+		return linksymOffset(no.Linksym, no.Offset_)
+	case ir.ONAME:
+		n := n.(*ir.Name)
+		if n.Heapaddr != nil {
+			return s.expr(n.Heapaddr)
+		}
+		switch n.Class {
+		case ir.PEXTERN:
+			// global variable
+			return linksymOffset(n.Linksym(), 0)
+		case ir.PPARAM:
+			// parameter slot
+			v := s.decladdrs[n]
+			if v != nil {
+				return v
+			}
+			s.Fatalf("addr of undeclared ONAME %v. declared: %v", n, s.decladdrs)
+			return nil
+		case ir.PAUTO:
+			return s.newValue2Apos(ssa.OpLocalAddr, t, n, s.sp, s.mem(), !ir.IsAutoTmp(n))
+
+		case ir.PPARAMOUT: // Same as PAUTO -- cannot generate LEA early.
+			// ensure that we reuse symbols for out parameters so
+			// that cse works on their addresses
+			return s.newValue2Apos(ssa.OpLocalAddr, t, n, s.sp, s.mem(), true)
+		default:
+			s.Fatalf("variable address class %v not implemented", n.Class)
+			return nil
+		}
+	case ir.ORESULT:
+		// load return from callee
+		n := n.(*ir.ResultExpr)
+		return s.resultAddrOfCall(s.prevCall, n.Index, n.Type())
+	case ir.OINDEX:
+		n := n.(*ir.IndexExpr)
+		if n.X.Type().IsSlice() {
+			a := s.expr(n.X)
+			i := s.expr(n.Index)
+			len := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], a)
+			i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
+			p := s.newValue1(ssa.OpSlicePtr, t, a)
+			return s.newValue2(ssa.OpPtrIndex, t, p, i)
+		} else { // array
+			a := s.addr(n.X)
+			i := s.expr(n.Index)
+			len := s.constInt(types.Types[types.TINT], n.X.Type().NumElem())
+			i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
+			return s.newValue2(ssa.OpPtrIndex, types.NewPtr(n.X.Type().Elem()), a, i)
+		}
+	case ir.ODEREF:
+		n := n.(*ir.StarExpr)
+		return s.exprPtr(n.X, n.Bounded(), n.Pos())
+	case ir.ODOT:
+		n := n.(*ir.SelectorExpr)
+		p := s.addr(n.X)
+		return s.newValue1I(ssa.OpOffPtr, t, n.Offset(), p)
+	case ir.ODOTPTR:
+		n := n.(*ir.SelectorExpr)
+		p := s.exprPtr(n.X, n.Bounded(), n.Pos())
+		return s.newValue1I(ssa.OpOffPtr, t, n.Offset(), p)
+	case ir.OCONVNOP:
+		n := n.(*ir.ConvExpr)
+		if n.Type() == n.X.Type() {
+			return s.addr(n.X)
+		}
+		addr := s.addr(n.X)
+		return s.newValue1(ssa.OpCopy, t, addr) // ensure that addr has the right type
+	case ir.OCALLFUNC, ir.OCALLINTER:
+		n := n.(*ir.CallExpr)
+		return s.callAddr(n, callNormal)
+	case ir.ODOTTYPE:
+		n := n.(*ir.TypeAssertExpr)
+		v, _ := s.dottype(n, false)
+		if v.Op != ssa.OpLoad {
+			s.Fatalf("dottype of non-load")
+		}
+		if v.Args[1] != s.mem() {
+			s.Fatalf("memory no longer live from dottype load")
+		}
+		return v.Args[0]
+	default:
+		s.Fatalf("unhandled addr %v", n.Op())
+		return nil
+	}
+}
+
+// canSSA reports whether n is SSA-able.
+// n must be an ONAME (or an ODOT sequence with an ONAME base).
+func (s *state) canSSA(n ir.Node) bool {
+	if base.Flag.N != 0 {
+		return false
+	}
+	for {
+		nn := n
+		if nn.Op() == ir.ODOT {
+			nn := nn.(*ir.SelectorExpr)
+			n = nn.X
+			continue
+		}
+		if nn.Op() == ir.OINDEX {
+			nn := nn.(*ir.IndexExpr)
+			if nn.X.Type().IsArray() {
+				n = nn.X
+				continue
+			}
+		}
+		break
+	}
+	if n.Op() != ir.ONAME {
+		return false
+	}
+	return s.canSSAName(n.(*ir.Name)) && TypeOK(n.Type())
+}
+
+func (s *state) canSSAName(name *ir.Name) bool {
+	if name.Addrtaken() || !name.OnStack() {
+		return false
+	}
+	switch name.Class {
+	case ir.PPARAMOUT:
+		if s.hasdefer {
+			// 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
+			// must be written back so if a defer recovers, the caller can see them.
+			return false
+		}
+		if s.cgoUnsafeArgs {
+			// Cgo effectively takes the address of all result args,
+			// but the compiler can't see that.
+			return false
+		}
+	}
+	if name.Class == ir.PPARAM && name.Sym() != nil && name.Sym().Name == ".this" {
+		// wrappers generated by genwrapper need to update
+		// the .this pointer in place.
+		// TODO: treat as a PPARAMOUT?
+		return false
+	}
+	return true
+	// TODO: try to make more variables SSAable?
+}
+
+// TypeOK reports whether variables of type t are SSA-able.
+func TypeOK(t *types.Type) bool {
+	types.CalcSize(t)
+	if t.Width > int64(4*types.PtrSize) {
+		// 4*Widthptr is an arbitrary constant. We want it
+		// to be at least 3*Widthptr so slices can be registerized.
+		// Too big and we'll introduce too much register pressure.
+		return false
+	}
+	switch t.Kind() {
+	case types.TARRAY:
+		// We can't do larger arrays because dynamic indexing is
+		// not supported on SSA variables.
+		// TODO: allow if all indexes are constant.
+		if t.NumElem() <= 1 {
+			return TypeOK(t.Elem())
+		}
+		return false
+	case types.TSTRUCT:
+		if t.NumFields() > ssa.MaxStruct {
+			return false
+		}
+		for _, t1 := range t.Fields().Slice() {
+			if !TypeOK(t1.Type) {
+				return false
+			}
+		}
+		return true
+	default:
+		return true
+	}
+}
+
+// exprPtr evaluates n to a pointer and nil-checks it.
+func (s *state) exprPtr(n ir.Node, bounded bool, lineno src.XPos) *ssa.Value {
+	p := s.expr(n)
+	if bounded || n.NonNil() {
+		if s.f.Frontend().Debug_checknil() && lineno.Line() > 1 {
+			s.f.Warnl(lineno, "removed nil check")
+		}
+		return p
+	}
+	s.nilCheck(p)
+	return p
+}
+
+// nilCheck generates nil pointer checking code.
+// Used only for automatically inserted nil checks,
+// not for user code like 'x != nil'.
+func (s *state) nilCheck(ptr *ssa.Value) {
+	if base.Debug.DisableNil != 0 || s.curfn.NilCheckDisabled() {
+		return
+	}
+	s.newValue2(ssa.OpNilCheck, types.TypeVoid, ptr, s.mem())
+}
+
+// boundsCheck generates bounds checking code. Checks if 0 <= idx <[=] len, branches to exit if not.
+// Starts a new block on return.
+// On input, len must be converted to full int width and be nonnegative.
+// Returns idx converted to full int width.
+// If bounded is true then caller guarantees the index is not out of bounds
+// (but boundsCheck will still extend the index to full int width).
+func (s *state) boundsCheck(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value {
+	idx = s.extendIndex(idx, len, kind, bounded)
+
+	if bounded || base.Flag.B != 0 {
+		// If bounded or bounds checking is flag-disabled, then no check necessary,
+		// just return the extended index.
+		//
+		// Here, bounded == true if the compiler generated the index itself,
+		// such as in the expansion of a slice initializer. These indexes are
+		// compiler-generated, not Go program variables, so they cannot be
+		// attacker-controlled, so we can omit Spectre masking as well.
+		//
+		// Note that we do not want to omit Spectre masking in code like:
+		//
+		//	if 0 <= i && i < len(x) {
+		//		use(x[i])
+		//	}
+		//
+		// Lucky for us, bounded==false for that code.
+		// In that case (handled below), we emit a bound check (and Spectre mask)
+		// and then the prove pass will remove the bounds check.
+		// In theory the prove pass could potentially remove certain
+		// Spectre masks, but it's very delicate and probably better
+		// to be conservative and leave them all in.
+		return idx
+	}
+
+	bNext := s.f.NewBlock(ssa.BlockPlain)
+	bPanic := s.f.NewBlock(ssa.BlockExit)
+
+	if !idx.Type.IsSigned() {
+		switch kind {
+		case ssa.BoundsIndex:
+			kind = ssa.BoundsIndexU
+		case ssa.BoundsSliceAlen:
+			kind = ssa.BoundsSliceAlenU
+		case ssa.BoundsSliceAcap:
+			kind = ssa.BoundsSliceAcapU
+		case ssa.BoundsSliceB:
+			kind = ssa.BoundsSliceBU
+		case ssa.BoundsSlice3Alen:
+			kind = ssa.BoundsSlice3AlenU
+		case ssa.BoundsSlice3Acap:
+			kind = ssa.BoundsSlice3AcapU
+		case ssa.BoundsSlice3B:
+			kind = ssa.BoundsSlice3BU
+		case ssa.BoundsSlice3C:
+			kind = ssa.BoundsSlice3CU
+		}
+	}
+
+	var cmp *ssa.Value
+	if kind == ssa.BoundsIndex || kind == ssa.BoundsIndexU {
+		cmp = s.newValue2(ssa.OpIsInBounds, types.Types[types.TBOOL], idx, len)
+	} else {
+		cmp = s.newValue2(ssa.OpIsSliceInBounds, types.Types[types.TBOOL], idx, len)
+	}
+	b := s.endBlock()
+	b.Kind = ssa.BlockIf
+	b.SetControl(cmp)
+	b.Likely = ssa.BranchLikely
+	b.AddEdgeTo(bNext)
+	b.AddEdgeTo(bPanic)
+
+	s.startBlock(bPanic)
+	if Arch.LinkArch.Family == sys.Wasm {
+		// TODO(khr): figure out how to do "register" based calling convention for bounds checks.
+		// Should be similar to gcWriteBarrier, but I can't make it work.
+		s.rtcall(BoundsCheckFunc[kind], false, nil, idx, len)
+	} else {
+		mem := s.newValue3I(ssa.OpPanicBounds, types.TypeMem, int64(kind), idx, len, s.mem())
+		s.endBlock().SetControl(mem)
+	}
+	s.startBlock(bNext)
+
+	// In Spectre index mode, apply an appropriate mask to avoid speculative out-of-bounds accesses.
+	if base.Flag.Cfg.SpectreIndex {
+		op := ssa.OpSpectreIndex
+		if kind != ssa.BoundsIndex && kind != ssa.BoundsIndexU {
+			op = ssa.OpSpectreSliceIndex
+		}
+		idx = s.newValue2(op, types.Types[types.TINT], idx, len)
+	}
+
+	return idx
+}
+
+// If cmp (a bool) is false, panic using the given function.
+func (s *state) check(cmp *ssa.Value, fn *obj.LSym) {
+	b := s.endBlock()
+	b.Kind = ssa.BlockIf
+	b.SetControl(cmp)
+	b.Likely = ssa.BranchLikely
+	bNext := s.f.NewBlock(ssa.BlockPlain)
+	line := s.peekPos()
+	pos := base.Ctxt.PosTable.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)
+		s.panics[fl] = bPanic
+		s.startBlock(bPanic)
+		// The panic call takes/returns memory to ensure that the right
+		// memory state is observed if the panic happens.
+		s.rtcall(fn, false, nil)
+	}
+	b.AddEdgeTo(bNext)
+	b.AddEdgeTo(bPanic)
+	s.startBlock(bNext)
+}
+
+func (s *state) intDivide(n ir.Node, a, b *ssa.Value) *ssa.Value {
+	needcheck := true
+	switch b.Op {
+	case ssa.OpConst8, ssa.OpConst16, ssa.OpConst32, ssa.OpConst64:
+		if b.AuxInt != 0 {
+			needcheck = false
+		}
+	}
+	if needcheck {
+		// do a size-appropriate check for zero
+		cmp := s.newValue2(s.ssaOp(ir.ONE, n.Type()), types.Types[types.TBOOL], b, s.zeroVal(n.Type()))
+		s.check(cmp, ir.Syms.Panicdivide)
+	}
+	return s.newValue2(s.ssaOp(n.Op(), n.Type()), a.Type, a, b)
+}
+
+// rtcall issues a call to the given runtime function fn with the listed args.
+// Returns a slice of results of the given result types.
+// The call is added to the end of the current block.
+// If returns is false, the block is marked as an exit block.
+func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args ...*ssa.Value) []*ssa.Value {
+	s.prevCall = nil
+	// Write args to the stack
+	off := base.Ctxt.FixedFrameSize()
+	var callArgs []*ssa.Value
+	var callArgTypes []*types.Type
+
+	for _, arg := range args {
+		t := arg.Type
+		off = types.Rnd(off, t.Alignment())
+		size := t.Size()
+		callArgs = append(callArgs, arg)
+		callArgTypes = append(callArgTypes, t)
+		off += size
+	}
+	off = types.Rnd(off, int64(types.RegSize))
+
+	// Accumulate results types and offsets
+	offR := off
+	for _, t := range results {
+		offR = types.Rnd(offR, t.Alignment())
+		offR += t.Size()
+	}
+
+	// Issue call
+	var call *ssa.Value
+	aux := ssa.StaticAuxCall(fn, s.f.ABIDefault.ABIAnalyzeTypes(nil, callArgTypes, results))
+	callArgs = append(callArgs, s.mem())
+	call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
+	call.AddArgs(callArgs...)
+	s.vars[memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(results)), call)
+
+	if !returns {
+		// Finish block
+		b := s.endBlock()
+		b.Kind = ssa.BlockExit
+		b.SetControl(call)
+		call.AuxInt = off - base.Ctxt.FixedFrameSize()
+		if len(results) > 0 {
+			s.Fatalf("panic call can't have results")
+		}
+		return nil
+	}
+
+	// Load results
+	res := make([]*ssa.Value, len(results))
+	for i, t := range results {
+		off = types.Rnd(off, t.Alignment())
+		res[i] = s.resultOfCall(call, int64(i), t)
+		off += t.Size()
+	}
+	off = types.Rnd(off, int64(types.PtrSize))
+
+	// Remember how much callee stack space we needed.
+	call.AuxInt = off
+
+	return res
+}
+
+// do *left = right for type t.
+func (s *state) storeType(t *types.Type, left, right *ssa.Value, skip skipMask, leftIsStmt bool) {
+	s.instrument(t, left, instrumentWrite)
+
+	if skip == 0 && (!t.HasPointers() || ssa.IsStackAddr(left)) {
+		// Known to not have write barrier. Store the whole type.
+		s.vars[memVar] = s.newValue3Apos(ssa.OpStore, types.TypeMem, t, left, right, s.mem(), leftIsStmt)
+		return
+	}
+
+	// store scalar fields first, so write barrier stores for
+	// pointer fields can be grouped together, and scalar values
+	// don't need to be live across the write barrier call.
+	// TODO: if the writebarrier pass knows how to reorder stores,
+	// we can do a single store here as long as skip==0.
+	s.storeTypeScalars(t, left, right, skip)
+	if skip&skipPtr == 0 && t.HasPointers() {
+		s.storeTypePtrs(t, left, right)
+	}
+}
+
+// do *left = right for all scalar (non-pointer) parts of t.
+func (s *state) storeTypeScalars(t *types.Type, left, right *ssa.Value, skip skipMask) {
+	switch {
+	case t.IsBoolean() || t.IsInteger() || t.IsFloat() || t.IsComplex():
+		s.store(t, left, right)
+	case t.IsPtrShaped():
+		if t.IsPtr() && t.Elem().NotInHeap() {
+			s.store(t, left, right) // see issue 42032
+		}
+		// otherwise, no scalar fields.
+	case t.IsString():
+		if skip&skipLen != 0 {
+			return
+		}
+		len := s.newValue1(ssa.OpStringLen, types.Types[types.TINT], right)
+		lenAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, s.config.PtrSize, left)
+		s.store(types.Types[types.TINT], lenAddr, len)
+	case t.IsSlice():
+		if skip&skipLen == 0 {
+			len := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], right)
+			lenAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, s.config.PtrSize, left)
+			s.store(types.Types[types.TINT], lenAddr, len)
+		}
+		if skip&skipCap == 0 {
+			cap := s.newValue1(ssa.OpSliceCap, types.Types[types.TINT], right)
+			capAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, 2*s.config.PtrSize, left)
+			s.store(types.Types[types.TINT], capAddr, cap)
+		}
+	case t.IsInterface():
+		// itab field doesn't need a write barrier (even though it is a pointer).
+		itab := s.newValue1(ssa.OpITab, s.f.Config.Types.BytePtr, right)
+		s.store(types.Types[types.TUINTPTR], left, itab)
+	case t.IsStruct():
+		n := t.NumFields()
+		for i := 0; i < n; i++ {
+			ft := t.FieldType(i)
+			addr := s.newValue1I(ssa.OpOffPtr, ft.PtrTo(), t.FieldOff(i), left)
+			val := s.newValue1I(ssa.OpStructSelect, ft, int64(i), right)
+			s.storeTypeScalars(ft, addr, val, 0)
+		}
+	case t.IsArray() && t.NumElem() == 0:
+		// nothing
+	case t.IsArray() && t.NumElem() == 1:
+		s.storeTypeScalars(t.Elem(), left, s.newValue1I(ssa.OpArraySelect, t.Elem(), 0, right), 0)
+	default:
+		s.Fatalf("bad write barrier type %v", t)
+	}
+}
+
+// do *left = right for all pointer parts of t.
+func (s *state) storeTypePtrs(t *types.Type, left, right *ssa.Value) {
+	switch {
+	case t.IsPtrShaped():
+		if t.IsPtr() && t.Elem().NotInHeap() {
+			break // see issue 42032
+		}
+		s.store(t, left, right)
+	case t.IsString():
+		ptr := s.newValue1(ssa.OpStringPtr, s.f.Config.Types.BytePtr, right)
+		s.store(s.f.Config.Types.BytePtr, left, ptr)
+	case t.IsSlice():
+		elType := types.NewPtr(t.Elem())
+		ptr := s.newValue1(ssa.OpSlicePtr, elType, right)
+		s.store(elType, left, ptr)
+	case t.IsInterface():
+		// itab field is treated as a scalar.
+		idata := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, right)
+		idataAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.BytePtrPtr, s.config.PtrSize, left)
+		s.store(s.f.Config.Types.BytePtr, idataAddr, idata)
+	case t.IsStruct():
+		n := t.NumFields()
+		for i := 0; i < n; i++ {
+			ft := t.FieldType(i)
+			if !ft.HasPointers() {
+				continue
+			}
+			addr := s.newValue1I(ssa.OpOffPtr, ft.PtrTo(), t.FieldOff(i), left)
+			val := s.newValue1I(ssa.OpStructSelect, ft, int64(i), right)
+			s.storeTypePtrs(ft, addr, val)
+		}
+	case t.IsArray() && t.NumElem() == 0:
+		// nothing
+	case t.IsArray() && t.NumElem() == 1:
+		s.storeTypePtrs(t.Elem(), left, s.newValue1I(ssa.OpArraySelect, t.Elem(), 0, right))
+	default:
+		s.Fatalf("bad write barrier type %v", t)
+	}
+}
+
+// putArg evaluates n for the purpose of passing it as an argument to a function and returns the value for the call.
+func (s *state) putArg(n ir.Node, t *types.Type) *ssa.Value {
+	var a *ssa.Value
+	if !TypeOK(t) {
+		a = s.newValue2(ssa.OpDereference, t, s.addr(n), s.mem())
+	} else {
+		a = s.expr(n)
+	}
+	return a
+}
+
+func (s *state) storeArgWithBase(n ir.Node, t *types.Type, base *ssa.Value, off int64) {
+	pt := types.NewPtr(t)
+	var addr *ssa.Value
+	if base == s.sp {
+		// Use special routine that avoids allocation on duplicate offsets.
+		addr = s.constOffPtrSP(pt, off)
+	} else {
+		addr = s.newValue1I(ssa.OpOffPtr, pt, off, base)
+	}
+
+	if !TypeOK(t) {
+		a := s.addr(n)
+		s.move(t, addr, a)
+		return
+	}
+
+	a := s.expr(n)
+	s.storeType(t, addr, a, 0, false)
+}
+
+// slice computes the slice v[i:j:k] and returns ptr, len, and cap of result.
+// i,j,k may be nil, in which case they are set to their default value.
+// v may be a slice, string or pointer to an array.
+func (s *state) slice(v, i, j, k *ssa.Value, bounded bool) (p, l, c *ssa.Value) {
+	t := v.Type
+	var ptr, len, cap *ssa.Value
+	switch {
+	case t.IsSlice():
+		ptr = s.newValue1(ssa.OpSlicePtr, types.NewPtr(t.Elem()), v)
+		len = s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], v)
+		cap = s.newValue1(ssa.OpSliceCap, types.Types[types.TINT], v)
+	case t.IsString():
+		ptr = s.newValue1(ssa.OpStringPtr, types.NewPtr(types.Types[types.TUINT8]), v)
+		len = s.newValue1(ssa.OpStringLen, types.Types[types.TINT], v)
+		cap = len
+	case t.IsPtr():
+		if !t.Elem().IsArray() {
+			s.Fatalf("bad ptr to array in slice %v\n", t)
+		}
+		s.nilCheck(v)
+		ptr = s.newValue1(ssa.OpCopy, types.NewPtr(t.Elem().Elem()), v)
+		len = s.constInt(types.Types[types.TINT], t.Elem().NumElem())
+		cap = len
+	default:
+		s.Fatalf("bad type in slice %v\n", t)
+	}
+
+	// Set default values
+	if i == nil {
+		i = s.constInt(types.Types[types.TINT], 0)
+	}
+	if j == nil {
+		j = len
+	}
+	three := true
+	if k == nil {
+		three = false
+		k = cap
+	}
+
+	// Panic if slice indices are not in bounds.
+	// Make sure we check these in reverse order so that we're always
+	// comparing against a value known to be nonnegative. See issue 28797.
+	if three {
+		if k != cap {
+			kind := ssa.BoundsSlice3Alen
+			if t.IsSlice() {
+				kind = ssa.BoundsSlice3Acap
+			}
+			k = s.boundsCheck(k, cap, kind, bounded)
+		}
+		if j != k {
+			j = s.boundsCheck(j, k, ssa.BoundsSlice3B, bounded)
+		}
+		i = s.boundsCheck(i, j, ssa.BoundsSlice3C, bounded)
+	} else {
+		if j != k {
+			kind := ssa.BoundsSliceAlen
+			if t.IsSlice() {
+				kind = ssa.BoundsSliceAcap
+			}
+			j = s.boundsCheck(j, k, kind, bounded)
+		}
+		i = s.boundsCheck(i, j, ssa.BoundsSliceB, bounded)
+	}
+
+	// Word-sized integer operations.
+	subOp := s.ssaOp(ir.OSUB, types.Types[types.TINT])
+	mulOp := s.ssaOp(ir.OMUL, types.Types[types.TINT])
+	andOp := s.ssaOp(ir.OAND, types.Types[types.TINT])
+
+	// Calculate the length (rlen) and capacity (rcap) of the new slice.
+	// For strings the capacity of the result is unimportant. However,
+	// we use rcap to test if we've generated a zero-length slice.
+	// Use length of strings for that.
+	rlen := s.newValue2(subOp, types.Types[types.TINT], j, i)
+	rcap := rlen
+	if j != k && !t.IsString() {
+		rcap = s.newValue2(subOp, types.Types[types.TINT], k, i)
+	}
+
+	if (i.Op == ssa.OpConst64 || i.Op == ssa.OpConst32) && i.AuxInt == 0 {
+		// No pointer arithmetic necessary.
+		return ptr, rlen, rcap
+	}
+
+	// Calculate the base pointer (rptr) for the new slice.
+	//
+	// Generate the following code assuming that indexes are in bounds.
+	// The masking is to make sure that we don't generate a slice
+	// that points to the next object in memory. We cannot just set
+	// the pointer to nil because then we would create a nil slice or
+	// string.
+	//
+	//     rcap = k - i
+	//     rlen = j - i
+	//     rptr = ptr + (mask(rcap) & (i * stride))
+	//
+	// Where mask(x) is 0 if x==0 and -1 if x>0 and stride is the width
+	// of the element type.
+	stride := s.constInt(types.Types[types.TINT], ptr.Type.Elem().Width)
+
+	// The delta is the number of bytes to offset ptr by.
+	delta := s.newValue2(mulOp, types.Types[types.TINT], i, stride)
+
+	// If we're slicing to the point where the capacity is zero,
+	// zero out the delta.
+	mask := s.newValue1(ssa.OpSlicemask, types.Types[types.TINT], rcap)
+	delta = s.newValue2(andOp, types.Types[types.TINT], delta, mask)
+
+	// Compute rptr = ptr + delta.
+	rptr := s.newValue2(ssa.OpAddPtr, ptr.Type, ptr, delta)
+
+	return rptr, rlen, rcap
+}
+
+type u642fcvtTab struct {
+	leq, cvt2F, and, rsh, or, add ssa.Op
+	one                           func(*state, *types.Type, int64) *ssa.Value
+}
+
+var u64_f64 = u642fcvtTab{
+	leq:   ssa.OpLeq64,
+	cvt2F: ssa.OpCvt64to64F,
+	and:   ssa.OpAnd64,
+	rsh:   ssa.OpRsh64Ux64,
+	or:    ssa.OpOr64,
+	add:   ssa.OpAdd64F,
+	one:   (*state).constInt64,
+}
+
+var u64_f32 = u642fcvtTab{
+	leq:   ssa.OpLeq64,
+	cvt2F: ssa.OpCvt64to32F,
+	and:   ssa.OpAnd64,
+	rsh:   ssa.OpRsh64Ux64,
+	or:    ssa.OpOr64,
+	add:   ssa.OpAdd32F,
+	one:   (*state).constInt64,
+}
+
+func (s *state) uint64Tofloat64(n ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+	return s.uint64Tofloat(&u64_f64, n, x, ft, tt)
+}
+
+func (s *state) uint64Tofloat32(n ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+	return s.uint64Tofloat(&u64_f32, n, x, ft, tt)
+}
+
+func (s *state) uint64Tofloat(cvttab *u642fcvtTab, n ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+	// if x >= 0 {
+	//    result = (floatY) x
+	// } else {
+	// 	  y = uintX(x) ; y = x & 1
+	// 	  z = uintX(x) ; z = z >> 1
+	// 	  z = z >> 1
+	// 	  z = z | y
+	// 	  result = floatY(z)
+	// 	  result = result + result
+	// }
+	//
+	// Code borrowed from old code generator.
+	// What's going on: large 64-bit "unsigned" looks like
+	// negative number to hardware's integer-to-float
+	// conversion. However, because the mantissa is only
+	// 63 bits, we don't need the LSB, so instead we do an
+	// unsigned right shift (divide by two), convert, and
+	// double. However, before we do that, we need to be
+	// sure that we do not lose a "1" if that made the
+	// difference in the resulting rounding. Therefore, we
+	// preserve it, and OR (not ADD) it back in. The case
+	// that matters is when the eleven discarded bits are
+	// equal to 10000000001; that rounds up, and the 1 cannot
+	// be lost else it would round down if the LSB of the
+	// candidate mantissa is 0.
+	cmp := s.newValue2(cvttab.leq, types.Types[types.TBOOL], s.zeroVal(ft), x)
+	b := s.endBlock()
+	b.Kind = ssa.BlockIf
+	b.SetControl(cmp)
+	b.Likely = ssa.BranchLikely
+
+	bThen := s.f.NewBlock(ssa.BlockPlain)
+	bElse := s.f.NewBlock(ssa.BlockPlain)
+	bAfter := s.f.NewBlock(ssa.BlockPlain)
+
+	b.AddEdgeTo(bThen)
+	s.startBlock(bThen)
+	a0 := s.newValue1(cvttab.cvt2F, tt, x)
+	s.vars[n] = a0
+	s.endBlock()
+	bThen.AddEdgeTo(bAfter)
+
+	b.AddEdgeTo(bElse)
+	s.startBlock(bElse)
+	one := cvttab.one(s, ft, 1)
+	y := s.newValue2(cvttab.and, ft, x, one)
+	z := s.newValue2(cvttab.rsh, ft, x, one)
+	z = s.newValue2(cvttab.or, ft, z, y)
+	a := s.newValue1(cvttab.cvt2F, tt, z)
+	a1 := s.newValue2(cvttab.add, tt, a, a)
+	s.vars[n] = a1
+	s.endBlock()
+	bElse.AddEdgeTo(bAfter)
+
+	s.startBlock(bAfter)
+	return s.variable(n, n.Type())
+}
+
+type u322fcvtTab struct {
+	cvtI2F, cvtF2F ssa.Op
+}
+
+var u32_f64 = u322fcvtTab{
+	cvtI2F: ssa.OpCvt32to64F,
+	cvtF2F: ssa.OpCopy,
+}
+
+var u32_f32 = u322fcvtTab{
+	cvtI2F: ssa.OpCvt32to32F,
+	cvtF2F: ssa.OpCvt64Fto32F,
+}
+
+func (s *state) uint32Tofloat64(n ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+	return s.uint32Tofloat(&u32_f64, n, x, ft, tt)
+}
+
+func (s *state) uint32Tofloat32(n ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+	return s.uint32Tofloat(&u32_f32, n, x, ft, tt)
+}
+
+func (s *state) uint32Tofloat(cvttab *u322fcvtTab, n ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+	// if x >= 0 {
+	// 	result = floatY(x)
+	// } else {
+	// 	result = floatY(float64(x) + (1<<32))
+	// }
+	cmp := s.newValue2(ssa.OpLeq32, types.Types[types.TBOOL], s.zeroVal(ft), x)
+	b := s.endBlock()
+	b.Kind = ssa.BlockIf
+	b.SetControl(cmp)
+	b.Likely = ssa.BranchLikely
+
+	bThen := s.f.NewBlock(ssa.BlockPlain)
+	bElse := s.f.NewBlock(ssa.BlockPlain)
+	bAfter := s.f.NewBlock(ssa.BlockPlain)
+
+	b.AddEdgeTo(bThen)
+	s.startBlock(bThen)
+	a0 := s.newValue1(cvttab.cvtI2F, tt, x)
+	s.vars[n] = a0
+	s.endBlock()
+	bThen.AddEdgeTo(bAfter)
+
+	b.AddEdgeTo(bElse)
+	s.startBlock(bElse)
+	a1 := s.newValue1(ssa.OpCvt32to64F, types.Types[types.TFLOAT64], x)
+	twoToThe32 := s.constFloat64(types.Types[types.TFLOAT64], float64(1<<32))
+	a2 := s.newValue2(ssa.OpAdd64F, types.Types[types.TFLOAT64], a1, twoToThe32)
+	a3 := s.newValue1(cvttab.cvtF2F, tt, a2)
+
+	s.vars[n] = a3
+	s.endBlock()
+	bElse.AddEdgeTo(bAfter)
+
+	s.startBlock(bAfter)
+	return s.variable(n, n.Type())
+}
+
+// referenceTypeBuiltin generates code for the len/cap builtins for maps and channels.
+func (s *state) referenceTypeBuiltin(n *ir.UnaryExpr, x *ssa.Value) *ssa.Value {
+	if !n.X.Type().IsMap() && !n.X.Type().IsChan() {
+		s.Fatalf("node must be a map or a channel")
+	}
+	// if n == nil {
+	//   return 0
+	// } else {
+	//   // len
+	//   return *((*int)n)
+	//   // cap
+	//   return *(((*int)n)+1)
+	// }
+	lenType := n.Type()
+	nilValue := s.constNil(types.Types[types.TUINTPTR])
+	cmp := s.newValue2(ssa.OpEqPtr, types.Types[types.TBOOL], x, nilValue)
+	b := s.endBlock()
+	b.Kind = ssa.BlockIf
+	b.SetControl(cmp)
+	b.Likely = ssa.BranchUnlikely
+
+	bThen := s.f.NewBlock(ssa.BlockPlain)
+	bElse := s.f.NewBlock(ssa.BlockPlain)
+	bAfter := s.f.NewBlock(ssa.BlockPlain)
+
+	// length/capacity of a nil map/chan is zero
+	b.AddEdgeTo(bThen)
+	s.startBlock(bThen)
+	s.vars[n] = s.zeroVal(lenType)
+	s.endBlock()
+	bThen.AddEdgeTo(bAfter)
+
+	b.AddEdgeTo(bElse)
+	s.startBlock(bElse)
+	switch n.Op() {
+	case ir.OLEN:
+		// length is stored in the first word for map/chan
+		s.vars[n] = s.load(lenType, x)
+	case ir.OCAP:
+		// capacity is stored in the second word for chan
+		sw := s.newValue1I(ssa.OpOffPtr, lenType.PtrTo(), lenType.Width, x)
+		s.vars[n] = s.load(lenType, sw)
+	default:
+		s.Fatalf("op must be OLEN or OCAP")
+	}
+	s.endBlock()
+	bElse.AddEdgeTo(bAfter)
+
+	s.startBlock(bAfter)
+	return s.variable(n, lenType)
+}
+
+type f2uCvtTab struct {
+	ltf, cvt2U, subf, or ssa.Op
+	floatValue           func(*state, *types.Type, float64) *ssa.Value
+	intValue             func(*state, *types.Type, int64) *ssa.Value
+	cutoff               uint64
+}
+
+var f32_u64 = f2uCvtTab{
+	ltf:        ssa.OpLess32F,
+	cvt2U:      ssa.OpCvt32Fto64,
+	subf:       ssa.OpSub32F,
+	or:         ssa.OpOr64,
+	floatValue: (*state).constFloat32,
+	intValue:   (*state).constInt64,
+	cutoff:     1 << 63,
+}
+
+var f64_u64 = f2uCvtTab{
+	ltf:        ssa.OpLess64F,
+	cvt2U:      ssa.OpCvt64Fto64,
+	subf:       ssa.OpSub64F,
+	or:         ssa.OpOr64,
+	floatValue: (*state).constFloat64,
+	intValue:   (*state).constInt64,
+	cutoff:     1 << 63,
+}
+
+var f32_u32 = f2uCvtTab{
+	ltf:        ssa.OpLess32F,
+	cvt2U:      ssa.OpCvt32Fto32,
+	subf:       ssa.OpSub32F,
+	or:         ssa.OpOr32,
+	floatValue: (*state).constFloat32,
+	intValue:   func(s *state, t *types.Type, v int64) *ssa.Value { return s.constInt32(t, int32(v)) },
+	cutoff:     1 << 31,
+}
+
+var f64_u32 = f2uCvtTab{
+	ltf:        ssa.OpLess64F,
+	cvt2U:      ssa.OpCvt64Fto32,
+	subf:       ssa.OpSub64F,
+	or:         ssa.OpOr32,
+	floatValue: (*state).constFloat64,
+	intValue:   func(s *state, t *types.Type, v int64) *ssa.Value { return s.constInt32(t, int32(v)) },
+	cutoff:     1 << 31,
+}
+
+func (s *state) float32ToUint64(n ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+	return s.floatToUint(&f32_u64, n, x, ft, tt)
+}
+func (s *state) float64ToUint64(n ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+	return s.floatToUint(&f64_u64, n, x, ft, tt)
+}
+
+func (s *state) float32ToUint32(n ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+	return s.floatToUint(&f32_u32, n, x, ft, tt)
+}
+
+func (s *state) float64ToUint32(n ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+	return s.floatToUint(&f64_u32, n, x, ft, tt)
+}
+
+func (s *state) floatToUint(cvttab *f2uCvtTab, n ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+	// cutoff:=1<<(intY_Size-1)
+	// if x < floatX(cutoff) {
+	// 	result = uintY(x)
+	// } else {
+	// 	y = x - floatX(cutoff)
+	// 	z = uintY(y)
+	// 	result = z | -(cutoff)
+	// }
+	cutoff := cvttab.floatValue(s, ft, float64(cvttab.cutoff))
+	cmp := s.newValue2(cvttab.ltf, types.Types[types.TBOOL], x, cutoff)
+	b := s.endBlock()
+	b.Kind = ssa.BlockIf
+	b.SetControl(cmp)
+	b.Likely = ssa.BranchLikely
+
+	bThen := s.f.NewBlock(ssa.BlockPlain)
+	bElse := s.f.NewBlock(ssa.BlockPlain)
+	bAfter := s.f.NewBlock(ssa.BlockPlain)
+
+	b.AddEdgeTo(bThen)
+	s.startBlock(bThen)
+	a0 := s.newValue1(cvttab.cvt2U, tt, x)
+	s.vars[n] = a0
+	s.endBlock()
+	bThen.AddEdgeTo(bAfter)
+
+	b.AddEdgeTo(bElse)
+	s.startBlock(bElse)
+	y := s.newValue2(cvttab.subf, ft, x, cutoff)
+	y = s.newValue1(cvttab.cvt2U, tt, y)
+	z := cvttab.intValue(s, tt, int64(-cvttab.cutoff))
+	a1 := s.newValue2(cvttab.or, tt, y, z)
+	s.vars[n] = a1
+	s.endBlock()
+	bElse.AddEdgeTo(bAfter)
+
+	s.startBlock(bAfter)
+	return s.variable(n, n.Type())
+}
+
+// dottype generates SSA for a type assertion node.
+// commaok indicates whether to panic or return a bool.
+// If commaok is false, resok will be nil.
+func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Value) {
+	iface := s.expr(n.X)              // input interface
+	target := s.reflectType(n.Type()) // target type
+	byteptr := s.f.Config.Types.BytePtr
+
+	if n.Type().IsInterface() {
+		if n.Type().IsEmptyInterface() {
+			// Converting to an empty interface.
+			// Input could be an empty or nonempty interface.
+			if base.Debug.TypeAssert > 0 {
+				base.WarnfAt(n.Pos(), "type assertion inlined")
+			}
+
+			// Get itab/type field from input.
+			itab := s.newValue1(ssa.OpITab, byteptr, iface)
+			// Conversion succeeds iff that field is not nil.
+			cond := s.newValue2(ssa.OpNeqPtr, types.Types[types.TBOOL], itab, s.constNil(byteptr))
+
+			if n.X.Type().IsEmptyInterface() && commaok {
+				// Converting empty interface to empty interface with ,ok is just a nil check.
+				return iface, cond
+			}
+
+			// Branch on nilness.
+			b := s.endBlock()
+			b.Kind = ssa.BlockIf
+			b.SetControl(cond)
+			b.Likely = ssa.BranchLikely
+			bOk := s.f.NewBlock(ssa.BlockPlain)
+			bFail := s.f.NewBlock(ssa.BlockPlain)
+			b.AddEdgeTo(bOk)
+			b.AddEdgeTo(bFail)
+
+			if !commaok {
+				// On failure, panic by calling panicnildottype.
+				s.startBlock(bFail)
+				s.rtcall(ir.Syms.Panicnildottype, false, nil, target)
+
+				// On success, return (perhaps modified) input interface.
+				s.startBlock(bOk)
+				if n.X.Type().IsEmptyInterface() {
+					res = iface // Use input interface unchanged.
+					return
+				}
+				// Load type out of itab, build interface with existing idata.
+				off := s.newValue1I(ssa.OpOffPtr, byteptr, int64(types.PtrSize), itab)
+				typ := s.load(byteptr, off)
+				idata := s.newValue1(ssa.OpIData, byteptr, iface)
+				res = s.newValue2(ssa.OpIMake, n.Type(), typ, idata)
+				return
+			}
+
+			s.startBlock(bOk)
+			// nonempty -> empty
+			// Need to load type from itab
+			off := s.newValue1I(ssa.OpOffPtr, byteptr, int64(types.PtrSize), itab)
+			s.vars[typVar] = s.load(byteptr, off)
+			s.endBlock()
+
+			// itab is nil, might as well use that as the nil result.
+			s.startBlock(bFail)
+			s.vars[typVar] = itab
+			s.endBlock()
+
+			// Merge point.
+			bEnd := s.f.NewBlock(ssa.BlockPlain)
+			bOk.AddEdgeTo(bEnd)
+			bFail.AddEdgeTo(bEnd)
+			s.startBlock(bEnd)
+			idata := s.newValue1(ssa.OpIData, byteptr, iface)
+			res = s.newValue2(ssa.OpIMake, n.Type(), s.variable(typVar, byteptr), idata)
+			resok = cond
+			delete(s.vars, typVar)
+			return
+		}
+		// converting to a nonempty interface needs a runtime call.
+		if base.Debug.TypeAssert > 0 {
+			base.WarnfAt(n.Pos(), "type assertion not inlined")
+		}
+		if !commaok {
+			fn := ir.Syms.AssertI2I
+			if n.X.Type().IsEmptyInterface() {
+				fn = ir.Syms.AssertE2I
+			}
+			data := s.newValue1(ssa.OpIData, types.Types[types.TUNSAFEPTR], iface)
+			tab := s.newValue1(ssa.OpITab, byteptr, iface)
+			tab = s.rtcall(fn, true, []*types.Type{byteptr}, target, tab)[0]
+			return s.newValue2(ssa.OpIMake, n.Type(), tab, data), nil
+		}
+		fn := ir.Syms.AssertI2I2
+		if n.X.Type().IsEmptyInterface() {
+			fn = ir.Syms.AssertE2I2
+		}
+		res = s.rtcall(fn, true, []*types.Type{n.Type()}, target, iface)[0]
+		resok = s.newValue2(ssa.OpNeqInter, types.Types[types.TBOOL], res, s.constInterface(n.Type()))
+		return
+	}
+
+	if base.Debug.TypeAssert > 0 {
+		base.WarnfAt(n.Pos(), "type assertion inlined")
+	}
+
+	// Converting to a concrete type.
+	direct := types.IsDirectIface(n.Type())
+	itab := s.newValue1(ssa.OpITab, byteptr, iface) // type word of interface
+	if base.Debug.TypeAssert > 0 {
+		base.WarnfAt(n.Pos(), "type assertion inlined")
+	}
+	var targetITab *ssa.Value
+	if n.X.Type().IsEmptyInterface() {
+		// Looking for pointer to target type.
+		targetITab = target
+	} else {
+		// Looking for pointer to itab for target type and source interface.
+		targetITab = s.expr(n.Itab)
+	}
+
+	var tmp ir.Node     // temporary for use with large types
+	var addr *ssa.Value // address of tmp
+	if commaok && !TypeOK(n.Type()) {
+		// unSSAable type, use temporary.
+		// TODO: get rid of some of these temporaries.
+		tmp, addr = s.temp(n.Pos(), n.Type())
+	}
+
+	cond := s.newValue2(ssa.OpEqPtr, types.Types[types.TBOOL], itab, targetITab)
+	b := s.endBlock()
+	b.Kind = ssa.BlockIf
+	b.SetControl(cond)
+	b.Likely = ssa.BranchLikely
+
+	bOk := s.f.NewBlock(ssa.BlockPlain)
+	bFail := s.f.NewBlock(ssa.BlockPlain)
+	b.AddEdgeTo(bOk)
+	b.AddEdgeTo(bFail)
+
+	if !commaok {
+		// on failure, panic by calling panicdottype
+		s.startBlock(bFail)
+		taddr := s.reflectType(n.X.Type())
+		if n.X.Type().IsEmptyInterface() {
+			s.rtcall(ir.Syms.PanicdottypeE, false, nil, itab, target, taddr)
+		} else {
+			s.rtcall(ir.Syms.PanicdottypeI, false, nil, itab, target, taddr)
+		}
+
+		// on success, return data from interface
+		s.startBlock(bOk)
+		if direct {
+			return s.newValue1(ssa.OpIData, n.Type(), iface), nil
+		}
+		p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type()), iface)
+		return s.load(n.Type(), p), nil
+	}
+
+	// commaok is the more complicated case because we have
+	// a control flow merge point.
+	bEnd := s.f.NewBlock(ssa.BlockPlain)
+	// Note that we need a new valVar each time (unlike okVar where we can
+	// reuse the variable) because it might have a different type every time.
+	valVar := ssaMarker("val")
+
+	// type assertion succeeded
+	s.startBlock(bOk)
+	if tmp == nil {
+		if direct {
+			s.vars[valVar] = s.newValue1(ssa.OpIData, n.Type(), iface)
+		} else {
+			p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type()), iface)
+			s.vars[valVar] = s.load(n.Type(), p)
+		}
+	} else {
+		p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type()), iface)
+		s.move(n.Type(), addr, p)
+	}
+	s.vars[okVar] = s.constBool(true)
+	s.endBlock()
+	bOk.AddEdgeTo(bEnd)
+
+	// type assertion failed
+	s.startBlock(bFail)
+	if tmp == nil {
+		s.vars[valVar] = s.zeroVal(n.Type())
+	} else {
+		s.zero(n.Type(), addr)
+	}
+	s.vars[okVar] = s.constBool(false)
+	s.endBlock()
+	bFail.AddEdgeTo(bEnd)
+
+	// merge point
+	s.startBlock(bEnd)
+	if tmp == nil {
+		res = s.variable(valVar, n.Type())
+		delete(s.vars, valVar)
+	} else {
+		res = s.load(n.Type(), addr)
+		s.vars[memVar] = s.newValue1A(ssa.OpVarKill, types.TypeMem, tmp.(*ir.Name), s.mem())
+	}
+	resok = s.variable(okVar, types.Types[types.TBOOL])
+	delete(s.vars, okVar)
+	return res, resok
+}
+
+// temp allocates a temp of type t at position pos
+func (s *state) temp(pos src.XPos, t *types.Type) (*ir.Name, *ssa.Value) {
+	tmp := typecheck.TempAt(pos, s.curfn, t)
+	s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, tmp, s.mem())
+	addr := s.addr(tmp)
+	return tmp, addr
+}
+
+// variable returns the value of a variable at the current location.
+func (s *state) variable(n ir.Node, t *types.Type) *ssa.Value {
+	v := s.vars[n]
+	if v != nil {
+		return v
+	}
+	v = s.fwdVars[n]
+	if v != nil {
+		return v
+	}
+
+	if s.curBlock == s.f.Entry {
+		// No variable should be live at entry.
+		s.Fatalf("Value live at entry. It shouldn't be. func %s, node %v, value %v", s.f.Name, n, v)
+	}
+	// Make a FwdRef, which records a value that's live on block input.
+	// We'll find the matching definition as part of insertPhis.
+	v = s.newValue0A(ssa.OpFwdRef, t, fwdRefAux{N: n})
+	s.fwdVars[n] = v
+	if n.Op() == ir.ONAME {
+		s.addNamedValue(n.(*ir.Name), v)
+	}
+	return v
+}
+
+func (s *state) mem() *ssa.Value {
+	return s.variable(memVar, types.TypeMem)
+}
+
+func (s *state) addNamedValue(n *ir.Name, v *ssa.Value) {
+	if n.Class == ir.Pxxx {
+		// Don't track our marker nodes (memVar etc.).
+		return
+	}
+	if ir.IsAutoTmp(n) {
+		// Don't track temporary variables.
+		return
+	}
+	if n.Class == ir.PPARAMOUT {
+		// Don't track named output values.  This prevents return values
+		// from being assigned too early. See #14591 and #14762. TODO: allow this.
+		return
+	}
+	loc := ssa.LocalSlot{N: n, Type: n.Type(), Off: 0}
+	values, ok := s.f.NamedValues[loc]
+	if !ok {
+		s.f.Names = append(s.f.Names, &loc)
+		s.f.CanonicalLocalSlots[loc] = &loc
+	}
+	s.f.NamedValues[loc] = append(values, v)
+}
+
+// Branch is an unresolved branch.
+type Branch struct {
+	P *obj.Prog  // branch instruction
+	B *ssa.Block // target
+}
+
+// State contains state needed during Prog generation.
+type State struct {
+	ABI obj.ABI
+
+	pp *objw.Progs
+
+	// Branches remembers all the branch instructions we've seen
+	// and where they would like to go.
+	Branches []Branch
+
+	// bstart remembers where each block starts (indexed by block ID)
+	bstart []*obj.Prog
+
+	maxarg int64 // largest frame size for arguments to calls made by the function
+
+	// Map from GC safe points to liveness index, generated by
+	// liveness analysis.
+	livenessMap liveness.Map
+
+	// partLiveArgs includes arguments that may be partially live, for which we
+	// need to generate instructions that spill the argument registers.
+	partLiveArgs map[*ir.Name]bool
+
+	// lineRunStart records the beginning of the current run of instructions
+	// within a single block sharing the same line number
+	// Used to move statement marks to the beginning of such runs.
+	lineRunStart *obj.Prog
+
+	// wasm: The number of values on the WebAssembly stack. This is only used as a safeguard.
+	OnWasmStackSkipped int
+}
+
+func (s *State) FuncInfo() *obj.FuncInfo {
+	return s.pp.CurFunc.LSym.Func()
+}
+
+// Prog appends a new Prog.
+func (s *State) Prog(as obj.As) *obj.Prog {
+	p := s.pp.Prog(as)
+	if objw.LosesStmtMark(as) {
+		return p
+	}
+	// Float a statement start to the beginning of any same-line run.
+	// lineRunStart is reset at block boundaries, which appears to work well.
+	if s.lineRunStart == nil || s.lineRunStart.Pos.Line() != p.Pos.Line() {
+		s.lineRunStart = p
+	} else if p.Pos.IsStmt() == src.PosIsStmt {
+		s.lineRunStart.Pos = s.lineRunStart.Pos.WithIsStmt()
+		p.Pos = p.Pos.WithNotStmt()
+	}
+	return p
+}
+
+// Pc returns the current Prog.
+func (s *State) Pc() *obj.Prog {
+	return s.pp.Next
+}
+
+// SetPos sets the current source position.
+func (s *State) SetPos(pos src.XPos) {
+	s.pp.Pos = pos
+}
+
+// Br emits a single branch instruction and returns the instruction.
+// Not all architectures need the returned instruction, but otherwise
+// the boilerplate is common to all.
+func (s *State) Br(op obj.As, target *ssa.Block) *obj.Prog {
+	p := s.Prog(op)
+	p.To.Type = obj.TYPE_BRANCH
+	s.Branches = append(s.Branches, Branch{P: p, B: target})
+	return p
+}
+
+// DebugFriendlySetPosFrom adjusts Pos.IsStmt subject to heuristics
+// that reduce "jumpy" line number churn when debugging.
+// Spill/fill/copy instructions from the register allocator,
+// phi functions, and instructions with a no-pos position
+// are examples of instructions that can cause churn.
+func (s *State) DebugFriendlySetPosFrom(v *ssa.Value) {
+	switch v.Op {
+	case ssa.OpPhi, ssa.OpCopy, ssa.OpLoadReg, ssa.OpStoreReg:
+		// These are not statements
+		s.SetPos(v.Pos.WithNotStmt())
+	default:
+		p := v.Pos
+		if p != src.NoXPos {
+			// If the position is defined, update the position.
+			// Also convert default IsStmt to NotStmt; only
+			// explicit statement boundaries should appear
+			// in the generated code.
+			if p.IsStmt() != src.PosIsStmt {
+				p = p.WithNotStmt()
+				// Calls use the pos attached to v, but copy the statement mark from State
+			}
+			s.SetPos(p)
+		} else {
+			s.SetPos(s.pp.Pos.WithNotStmt())
+		}
+	}
+}
+
+// emit argument info (locations on stack) for traceback.
+func emitArgInfo(e *ssafn, f *ssa.Func, pp *objw.Progs) {
+	ft := e.curfn.Type()
+	if ft.NumRecvs() == 0 && ft.NumParams() == 0 {
+		return
+	}
+
+	x := EmitArgInfo(e.curfn, f.OwnAux.ABIInfo())
+	e.curfn.LSym.Func().ArgInfo = x
+
+	// Emit a funcdata pointing at the arg info data.
+	p := pp.Prog(obj.AFUNCDATA)
+	p.From.SetConst(objabi.FUNCDATA_ArgInfo)
+	p.To.Type = obj.TYPE_MEM
+	p.To.Name = obj.NAME_EXTERN
+	p.To.Sym = x
+}
+
+// emit argument info (locations on stack) of f for traceback.
+func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym {
+	x := base.Ctxt.Lookup(fmt.Sprintf("%s.arginfo%d", f.LSym.Name, f.ABI))
+
+	PtrSize := int64(types.PtrSize)
+	uintptrTyp := types.Types[types.TUINTPTR]
+
+	isAggregate := func(t *types.Type) bool {
+		return t.IsStruct() || t.IsArray() || t.IsComplex() || t.IsInterface() || t.IsString() || t.IsSlice()
+	}
+
+	// Populate the data.
+	// The data is a stream of bytes, which contains the offsets and sizes of the
+	// non-aggregate arguments or non-aggregate fields/elements of aggregate-typed
+	// arguments, along with special "operators". Specifically,
+	// - for each non-aggrgate arg/field/element, its offset from FP (1 byte) and
+	//   size (1 byte)
+	// - special operators:
+	//   - 0xff - end of sequence
+	//   - 0xfe - print { (at the start of an aggregate-typed argument)
+	//   - 0xfd - print } (at the end of an aggregate-typed argument)
+	//   - 0xfc - print ... (more args/fields/elements)
+	//   - 0xfb - print _ (offset too large)
+	// These constants need to be in sync with runtime.traceback.go:printArgs.
+	const (
+		_endSeq         = 0xff
+		_startAgg       = 0xfe
+		_endAgg         = 0xfd
+		_dotdotdot      = 0xfc
+		_offsetTooLarge = 0xfb
+		_special        = 0xf0 // above this are operators, below this are ordinary offsets
+	)
+
+	const (
+		limit    = 10 // print no more than 10 args/components
+		maxDepth = 5  // no more than 5 layers of nesting
+
+		// maxLen is a (conservative) upper bound of the byte stream length. For
+		// each arg/component, it has no more than 2 bytes of data (size, offset),
+		// and no more than one {, }, ... at each level (it cannot have both the
+		// data and ... unless it is the last one, just be conservative). Plus 1
+		// for _endSeq.
+		maxLen = (maxDepth*3+2)*limit + 1
+	)
+
+	wOff := 0
+	n := 0
+	writebyte := func(o uint8) { wOff = objw.Uint8(x, wOff, o) }
+
+	// Write one non-aggrgate arg/field/element.
+	write1 := func(sz, offset int64) {
+		if offset >= _special {
+			writebyte(_offsetTooLarge)
+		} else {
+			writebyte(uint8(offset))
+			writebyte(uint8(sz))
+		}
+		n++
+	}
+
+	// Visit t recursively and write it out.
+	// Returns whether to continue visiting.
+	var visitType func(baseOffset int64, t *types.Type, depth int) bool
+	visitType = func(baseOffset int64, t *types.Type, depth int) bool {
+		if n >= limit {
+			writebyte(_dotdotdot)
+			return false
+		}
+		if !isAggregate(t) {
+			write1(t.Size(), baseOffset)
+			return true
+		}
+		writebyte(_startAgg)
+		depth++
+		if depth >= maxDepth {
+			writebyte(_dotdotdot)
+			writebyte(_endAgg)
+			n++
+			return true
+		}
+		switch {
+		case t.IsInterface(), t.IsString():
+			_ = visitType(baseOffset, uintptrTyp, depth) &&
+				visitType(baseOffset+PtrSize, uintptrTyp, depth)
+		case t.IsSlice():
+			_ = visitType(baseOffset, uintptrTyp, depth) &&
+				visitType(baseOffset+PtrSize, uintptrTyp, depth) &&
+				visitType(baseOffset+PtrSize*2, uintptrTyp, depth)
+		case t.IsComplex():
+			_ = visitType(baseOffset, types.FloatForComplex(t), depth) &&
+				visitType(baseOffset+t.Size()/2, types.FloatForComplex(t), depth)
+		case t.IsArray():
+			if t.NumElem() == 0 {
+				n++ // {} counts as a component
+				break
+			}
+			for i := int64(0); i < t.NumElem(); i++ {
+				if !visitType(baseOffset, t.Elem(), depth) {
+					break
+				}
+				baseOffset += t.Elem().Size()
+			}
+		case t.IsStruct():
+			if t.NumFields() == 0 {
+				n++ // {} counts as a component
+				break
+			}
+			for _, field := range t.Fields().Slice() {
+				if !visitType(baseOffset+field.Offset, field.Type, depth) {
+					break
+				}
+			}
+		}
+		writebyte(_endAgg)
+		return true
+	}
+
+	for _, a := range abiInfo.InParams() {
+		if !visitType(a.FrameOffset(abiInfo), a.Type, 0) {
+			break
+		}
+	}
+	writebyte(_endSeq)
+	if wOff > maxLen {
+		base.Fatalf("ArgInfo too large")
+	}
+
+	return x
+}
+
+// genssa appends entries to pp for each instruction in f.
+func genssa(f *ssa.Func, pp *objw.Progs) {
+	var s State
+	s.ABI = f.OwnAux.Fn.ABI()
+
+	e := f.Frontend().(*ssafn)
+
+	s.livenessMap, s.partLiveArgs = liveness.Compute(e.curfn, f, e.stkptrsize, pp)
+	emitArgInfo(e, f, pp)
+
+	openDeferInfo := e.curfn.LSym.Func().OpenCodedDeferInfo
+	if openDeferInfo != nil {
+		// This function uses open-coded defers -- write out the funcdata
+		// info that we computed at the end of genssa.
+		p := pp.Prog(obj.AFUNCDATA)
+		p.From.SetConst(objabi.FUNCDATA_OpenCodedDeferInfo)
+		p.To.Type = obj.TYPE_MEM
+		p.To.Name = obj.NAME_EXTERN
+		p.To.Sym = openDeferInfo
+	}
+
+	// Remember where each block starts.
+	s.bstart = make([]*obj.Prog, f.NumBlocks())
+	s.pp = pp
+	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.
+	if f.PrintOrHtmlSSA {
+		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)
+		progToBlock[s.pp.Next] = f.Blocks[0]
+	}
+
+	if base.Ctxt.Flag_locationlists {
+		if cap(f.Cache.ValueToProgAfter) < f.NumValues() {
+			f.Cache.ValueToProgAfter = make([]*obj.Prog, f.NumValues())
+		}
+		valueToProgAfter = f.Cache.ValueToProgAfter[:f.NumValues()]
+		for i := range valueToProgAfter {
+			valueToProgAfter[i] = nil
+		}
+	}
+
+	// If the very first instruction is not tagged as a statement,
+	// debuggers may attribute it to previous function in program.
+	firstPos := src.NoXPos
+	for _, v := range f.Entry.Values {
+		if v.Pos.IsStmt() == src.PosIsStmt {
+			firstPos = v.Pos
+			v.Pos = firstPos.WithDefaultStmt()
+			break
+		}
+	}
+
+	// inlMarks has an entry for each Prog that implements an inline mark.
+	// It maps from that Prog to the global inlining id of the inlined body
+	// which should unwind to this Prog's location.
+	var inlMarks map[*obj.Prog]int32
+	var inlMarkList []*obj.Prog
+
+	// inlMarksByPos maps from a (column 1) source position to the set of
+	// Progs that are in the set above and have that source position.
+	var inlMarksByPos map[src.XPos][]*obj.Prog
+
+	// Emit basic blocks
+	for i, b := range f.Blocks {
+		s.bstart[b.ID] = s.pp.Next
+		s.lineRunStart = nil
+
+		// Attach a "default" liveness info. Normally this will be
+		// overwritten in the Values loop below for each Value. But
+		// for an empty block this will be used for its control
+		// instruction. We won't use the actual liveness map on a
+		// control instruction. Just mark it something that is
+		// preemptible, unless this function is "all unsafe".
+		s.pp.NextLive = objw.LivenessIndex{StackMapIndex: -1, IsUnsafePoint: liveness.IsUnsafe(f)}
+
+		// Emit values in block
+		Arch.SSAMarkMoves(&s, b)
+		for _, v := range b.Values {
+			x := s.pp.Next
+			s.DebugFriendlySetPosFrom(v)
+
+			if v.Op.ResultInArg0() && v.ResultReg() != v.Args[0].Reg() {
+				v.Fatalf("input[0] and output not in same register %s", v.LongString())
+			}
+
+			switch v.Op {
+			case ssa.OpInitMem:
+				// memory arg needs no code
+			case ssa.OpArg:
+				// input args need no code
+			case ssa.OpSP, ssa.OpSB:
+				// nothing to do
+			case ssa.OpSelect0, ssa.OpSelect1, ssa.OpSelectN, ssa.OpMakeResult:
+				// nothing to do
+			case ssa.OpGetG:
+				// nothing to do when there's a g register,
+				// and checkLower complains if there's not
+			case ssa.OpVarDef, ssa.OpVarLive, ssa.OpKeepAlive, ssa.OpVarKill:
+				// nothing to do; already used by liveness
+			case ssa.OpPhi:
+				CheckLoweredPhi(v)
+			case ssa.OpConvert:
+				// nothing to do; no-op conversion for liveness
+				if v.Args[0].Reg() != v.Reg() {
+					v.Fatalf("OpConvert should be a no-op: %s; %s", v.Args[0].LongString(), v.LongString())
+				}
+			case ssa.OpInlMark:
+				p := Arch.Ginsnop(s.pp)
+				if inlMarks == nil {
+					inlMarks = map[*obj.Prog]int32{}
+					inlMarksByPos = map[src.XPos][]*obj.Prog{}
+				}
+				inlMarks[p] = v.AuxInt32()
+				inlMarkList = append(inlMarkList, p)
+				pos := v.Pos.AtColumn1()
+				inlMarksByPos[pos] = append(inlMarksByPos[pos], p)
+
+			default:
+				// Special case for first line in function; move it to the start (which cannot be a register-valued instruction)
+				if firstPos != src.NoXPos && v.Op != ssa.OpArgIntReg && v.Op != ssa.OpArgFloatReg && v.Op != ssa.OpLoadReg && v.Op != ssa.OpStoreReg {
+					s.SetPos(firstPos)
+					firstPos = src.NoXPos
+				}
+				// Attach this safe point to the next
+				// instruction.
+				s.pp.NextLive = s.livenessMap.Get(v)
+
+				// let the backend handle it
+				Arch.SSAGenValue(&s, v)
+			}
+
+			if base.Ctxt.Flag_locationlists {
+				valueToProgAfter[v.ID] = s.pp.Next
+			}
+
+			if f.PrintOrHtmlSSA {
+				for ; x != s.pp.Next; x = x.Link {
+					progToValue[x] = v
+				}
+			}
+		}
+		// If this is an empty infinite loop, stick a hardware NOP in there so that debuggers are less confused.
+		if s.bstart[b.ID] == s.pp.Next && len(b.Succs) == 1 && b.Succs[0].Block() == b {
+			p := Arch.Ginsnop(s.pp)
+			p.Pos = p.Pos.WithIsStmt()
+			if b.Pos == src.NoXPos {
+				b.Pos = p.Pos // It needs a file, otherwise a no-file non-zero line causes confusion.  See #35652.
+				if b.Pos == src.NoXPos {
+					b.Pos = pp.Text.Pos // Sometimes p.Pos is empty.  See #35695.
+				}
+			}
+			b.Pos = b.Pos.WithBogusLine() // Debuggers are not good about infinite loops, force a change in line number
+		}
+		// Emit control flow instructions for block
+		var next *ssa.Block
+		if i < len(f.Blocks)-1 && base.Flag.N == 0 {
+			// If -N, leave next==nil so every block with successors
+			// ends in a JMP (except call blocks - plive doesn't like
+			// select{send,recv} followed by a JMP call).  Helps keep
+			// line numbers for otherwise empty blocks.
+			next = f.Blocks[i+1]
+		}
+		x := s.pp.Next
+		s.SetPos(b.Pos)
+		Arch.SSAGenBlock(&s, b, next)
+		if f.PrintOrHtmlSSA {
+			for ; x != s.pp.Next; x = x.Link {
+				progToBlock[x] = b
+			}
+		}
+	}
+	if f.Blocks[len(f.Blocks)-1].Kind == ssa.BlockExit {
+		// We need the return address of a panic call to
+		// still be inside the function in question. So if
+		// it ends in a call which doesn't return, add a
+		// nop (which will never execute) after the call.
+		Arch.Ginsnop(pp)
+	}
+	if openDeferInfo != nil {
+		// When doing open-coded defers, generate a disconnected call to
+		// deferreturn and a return. This will be used to during panic
+		// recovery to unwind the stack and return back to the runtime.
+		s.pp.NextLive = s.livenessMap.DeferReturn
+		p := pp.Prog(obj.ACALL)
+		p.To.Type = obj.TYPE_MEM
+		p.To.Name = obj.NAME_EXTERN
+		p.To.Sym = ir.Syms.Deferreturn
+
+		// Load results into registers. So when a deferred function
+		// recovers a panic, it will return to caller with right results.
+		// The results are already in memory, because they are not SSA'd
+		// when the function has defers (see canSSAName).
+		if f.OwnAux.ABIInfo().OutRegistersUsed() != 0 {
+			Arch.LoadRegResults(&s, f)
+		}
+
+		pp.Prog(obj.ARET)
+	}
+
+	if inlMarks != nil {
+		// We have some inline marks. Try to find other instructions we're
+		// going to emit anyway, and use those instructions instead of the
+		// inline marks.
+		for p := pp.Text; p != nil; p = p.Link {
+			if p.As == obj.ANOP || p.As == obj.AFUNCDATA || p.As == obj.APCDATA || p.As == obj.ATEXT || p.As == obj.APCALIGN || Arch.LinkArch.Family == sys.Wasm {
+				// Don't use 0-sized instructions as inline marks, because we need
+				// to identify inline mark instructions by pc offset.
+				// (Some of these instructions are sometimes zero-sized, sometimes not.
+				// We must not use anything that even might be zero-sized.)
+				// TODO: are there others?
+				continue
+			}
+			if _, ok := inlMarks[p]; ok {
+				// Don't use inline marks themselves. We don't know
+				// whether they will be zero-sized or not yet.
+				continue
+			}
+			pos := p.Pos.AtColumn1()
+			s := inlMarksByPos[pos]
+			if len(s) == 0 {
+				continue
+			}
+			for _, m := range s {
+				// We found an instruction with the same source position as
+				// some of the inline marks.
+				// Use this instruction instead.
+				p.Pos = p.Pos.WithIsStmt() // promote position to a statement
+				pp.CurFunc.LSym.Func().AddInlMark(p, inlMarks[m])
+				// Make the inline mark a real nop, so it doesn't generate any code.
+				m.As = obj.ANOP
+				m.Pos = src.NoXPos
+				m.From = obj.Addr{}
+				m.To = obj.Addr{}
+			}
+			delete(inlMarksByPos, pos)
+		}
+		// Any unmatched inline marks now need to be added to the inlining tree (and will generate a nop instruction).
+		for _, p := range inlMarkList {
+			if p.As != obj.ANOP {
+				pp.CurFunc.LSym.Func().AddInlMark(p, inlMarks[p])
+			}
+		}
+	}
+
+	if base.Ctxt.Flag_locationlists {
+		var debugInfo *ssa.FuncDebug
+		if e.curfn.ABI == obj.ABIInternal && base.Flag.N != 0 {
+			debugInfo = ssa.BuildFuncDebugNoOptimized(base.Ctxt, f, base.Debug.LocationLists > 1, StackOffset)
+		} else {
+			debugInfo = ssa.BuildFuncDebug(base.Ctxt, f, base.Debug.LocationLists > 1, StackOffset)
+		}
+		e.curfn.DebugInfo = debugInfo
+		bstart := s.bstart
+		idToIdx := make([]int, f.NumBlocks())
+		for i, b := range f.Blocks {
+			idToIdx[b.ID] = i
+		}
+		// Note that at this moment, Prog.Pc is a sequence number; it's
+		// not a real PC until after assembly, so this mapping has to
+		// be done later.
+		debugInfo.GetPC = func(b, v ssa.ID) int64 {
+			switch v {
+			case ssa.BlockStart.ID:
+				if b == f.Entry.ID {
+					return 0 // Start at the very beginning, at the assembler-generated prologue.
+					// this should only happen for function args (ssa.OpArg)
+				}
+				return bstart[b].Pc
+			case ssa.BlockEnd.ID:
+				blk := f.Blocks[idToIdx[b]]
+				nv := len(blk.Values)
+				return valueToProgAfter[blk.Values[nv-1].ID].Pc
+			case ssa.FuncEnd.ID:
+				return e.curfn.LSym.Size
+			default:
+				return valueToProgAfter[v].Pc
+			}
+		}
+	}
+
+	// Resolve branches, and relax DefaultStmt into NotStmt
+	for _, br := range s.Branches {
+		br.P.To.SetTarget(s.bstart[br.B.ID])
+		if br.P.Pos.IsStmt() != src.PosIsStmt {
+			br.P.Pos = br.P.Pos.WithNotStmt()
+		} else if v0 := br.B.FirstPossibleStmtValue(); v0 != nil && v0.Pos.Line() == br.P.Pos.Line() && v0.Pos.IsStmt() == src.PosIsStmt {
+			br.P.Pos = br.P.Pos.WithNotStmt()
+		}
+
+	}
+
+	if e.log { // spew to stdout
+		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 := progToValue[p]; ok {
+				s = v.String()
+			} else if b, ok := progToBlock[p]; ok {
+				s = b.String()
+			} else {
+				s = "   " // most value and branch strings are 2-3 characters long
+			}
+			f.Logf(" %-6s\t%.5d (%s)\t%s\n", s, p.Pc, p.InnermostLineNumber(), p.InstructionString())
+		}
+	}
+	if f.HTMLWriter != nil { // spew to ssa.html
+		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 := progToValue[p]; ok {
+				buf.WriteString(v.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(fmt.Sprintf("%.5d <span class=\"l%v line-number\">(%s)</span> %s", p.Pc, p.InnermostLineNumber(), p.InnermostLineNumberHTML(), html.EscapeString(p.InstructionString())))
+			buf.WriteString("</dd>")
+		}
+		buf.WriteString("</dl>")
+		buf.WriteString("</code>")
+		f.HTMLWriter.WriteColumn("genssa", "genssa", "ssa-prog", buf.String())
+	}
+
+	defframe(&s, e, f)
+
+	f.HTMLWriter.Close()
+	f.HTMLWriter = nil
+}
+
+func defframe(s *State, e *ssafn, f *ssa.Func) {
+	pp := s.pp
+
+	frame := types.Rnd(s.maxarg+e.stksize, int64(types.RegSize))
+	if Arch.PadFrame != nil {
+		frame = Arch.PadFrame(frame)
+	}
+
+	// Fill in argument and frame size.
+	pp.Text.To.Type = obj.TYPE_TEXTSIZE
+	pp.Text.To.Val = int32(types.Rnd(f.OwnAux.ArgWidth(), int64(types.RegSize)))
+	pp.Text.To.Offset = frame
+
+	p := pp.Text
+
+	// Insert code to spill argument registers if the named slot may be partially
+	// live. That is, the named slot is considered live by liveness analysis,
+	// (because a part of it is live), but we may not spill all parts into the
+	// slot. This can only happen with aggregate-typed arguments that are SSA-able
+	// and not address-taken (for non-SSA-able or address-taken arguments we always
+	// spill upfront).
+	// Note: spilling is unnecessary in the -N/no-optimize case, since all values
+	// will be considered non-SSAable and spilled up front.
+	// TODO(register args) Make liveness more fine-grained to that partial spilling is okay.
+	if f.OwnAux.ABIInfo().InRegistersUsed() != 0 && base.Flag.N == 0 {
+		// First, see if it is already spilled before it may be live. Look for a spill
+		// in the entry block up to the first safepoint.
+		type nameOff struct {
+			n   *ir.Name
+			off int64
+		}
+		partLiveArgsSpilled := make(map[nameOff]bool)
+		for _, v := range f.Entry.Values {
+			if v.Op.IsCall() {
+				break
+			}
+			if v.Op != ssa.OpStoreReg || v.Args[0].Op != ssa.OpArgIntReg {
+				continue
+			}
+			n, off := ssa.AutoVar(v)
+			if n.Class != ir.PPARAM || n.Addrtaken() || !TypeOK(n.Type()) || !s.partLiveArgs[n] {
+				continue
+			}
+			partLiveArgsSpilled[nameOff{n, off}] = true
+		}
+
+		// Then, insert code to spill registers if not already.
+		for _, a := range f.OwnAux.ABIInfo().InParams() {
+			n, ok := a.Name.(*ir.Name)
+			if !ok || n.Addrtaken() || !TypeOK(n.Type()) || !s.partLiveArgs[n] || len(a.Registers) <= 1 {
+				continue
+			}
+			rts, offs := a.RegisterTypesAndOffsets()
+			for i := range a.Registers {
+				if !rts[i].HasPointers() {
+					continue
+				}
+				if partLiveArgsSpilled[nameOff{n, offs[i]}] {
+					continue // already spilled
+				}
+				reg := ssa.ObjRegForAbiReg(a.Registers[i], f.Config)
+				p = Arch.SpillArgReg(pp, p, f, rts[i], reg, n, offs[i])
+			}
+		}
+	}
+
+	// Insert code to zero ambiguously live variables so that the
+	// garbage collector only sees initialized values when it
+	// looks for pointers.
+	var lo, hi int64
+
+	// Opaque state for backend to use. Current backends use it to
+	// keep track of which helper registers have been zeroed.
+	var state uint32
+
+	// Iterate through declarations. Autos are sorted in decreasing
+	// frame offset order.
+	for _, n := range e.curfn.Dcl {
+		if !n.Needzero() {
+			continue
+		}
+		if n.Class != ir.PAUTO {
+			e.Fatalf(n.Pos(), "needzero class %d", n.Class)
+		}
+		if n.Type().Size()%int64(types.PtrSize) != 0 || n.FrameOffset()%int64(types.PtrSize) != 0 || n.Type().Size() == 0 {
+			e.Fatalf(n.Pos(), "var %L has size %d offset %d", n, n.Type().Size(), n.Offset_)
+		}
+
+		if lo != hi && n.FrameOffset()+n.Type().Size() >= lo-int64(2*types.RegSize) {
+			// Merge with range we already have.
+			lo = n.FrameOffset()
+			continue
+		}
+
+		// Zero old range
+		p = Arch.ZeroRange(pp, p, frame+lo, hi-lo, &state)
+
+		// Set new range.
+		lo = n.FrameOffset()
+		hi = lo + n.Type().Size()
+	}
+
+	// Zero final range.
+	Arch.ZeroRange(pp, p, frame+lo, hi-lo, &state)
+}
+
+// For generating consecutive jump instructions to model a specific branching
+type IndexJump struct {
+	Jump  obj.As
+	Index int
+}
+
+func (s *State) oneJump(b *ssa.Block, jump *IndexJump) {
+	p := s.Br(jump.Jump, b.Succs[jump.Index].Block())
+	p.Pos = b.Pos
+}
+
+// CombJump generates combinational instructions (2 at present) for a block jump,
+// thereby the behaviour of non-standard condition codes could be simulated
+func (s *State) CombJump(b, next *ssa.Block, jumps *[2][2]IndexJump) {
+	switch next {
+	case b.Succs[0].Block():
+		s.oneJump(b, &jumps[0][0])
+		s.oneJump(b, &jumps[0][1])
+	case b.Succs[1].Block():
+		s.oneJump(b, &jumps[1][0])
+		s.oneJump(b, &jumps[1][1])
+	default:
+		var q *obj.Prog
+		if b.Likely != ssa.BranchUnlikely {
+			s.oneJump(b, &jumps[1][0])
+			s.oneJump(b, &jumps[1][1])
+			q = s.Br(obj.AJMP, b.Succs[1].Block())
+		} else {
+			s.oneJump(b, &jumps[0][0])
+			s.oneJump(b, &jumps[0][1])
+			q = s.Br(obj.AJMP, b.Succs[0].Block())
+		}
+		q.Pos = b.Pos
+	}
+}
+
+// AddAux adds the offset in the aux fields (AuxInt and Aux) of v to a.
+func AddAux(a *obj.Addr, v *ssa.Value) {
+	AddAux2(a, v, v.AuxInt)
+}
+func AddAux2(a *obj.Addr, v *ssa.Value, offset int64) {
+	if a.Type != obj.TYPE_MEM && a.Type != obj.TYPE_ADDR {
+		v.Fatalf("bad AddAux addr %v", a)
+	}
+	// add integer offset
+	a.Offset += offset
+
+	// If no additional symbol offset, we're done.
+	if v.Aux == nil {
+		return
+	}
+	// Add symbol's offset from its base register.
+	switch n := v.Aux.(type) {
+	case *ssa.AuxCall:
+		a.Name = obj.NAME_EXTERN
+		a.Sym = n.Fn
+	case *obj.LSym:
+		a.Name = obj.NAME_EXTERN
+		a.Sym = n
+	case *ir.Name:
+		if n.Class == ir.PPARAM || (n.Class == ir.PPARAMOUT && !n.IsOutputParamInRegisters()) {
+			a.Name = obj.NAME_PARAM
+			a.Sym = ir.Orig(n).(*ir.Name).Linksym()
+			a.Offset += n.FrameOffset()
+			break
+		}
+		a.Name = obj.NAME_AUTO
+		if n.Class == ir.PPARAMOUT {
+			a.Sym = ir.Orig(n).(*ir.Name).Linksym()
+		} else {
+			a.Sym = n.Linksym()
+		}
+		a.Offset += n.FrameOffset()
+	default:
+		v.Fatalf("aux in %s not implemented %#v", v, v.Aux)
+	}
+}
+
+// extendIndex extends v to a full int width.
+// panic with the given kind if v does not fit in an int (only on 32-bit archs).
+func (s *state) extendIndex(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value {
+	size := idx.Type.Size()
+	if size == s.config.PtrSize {
+		return idx
+	}
+	if size > s.config.PtrSize {
+		// truncate 64-bit indexes on 32-bit pointer archs. Test the
+		// high word and branch to out-of-bounds failure if it is not 0.
+		var lo *ssa.Value
+		if idx.Type.IsSigned() {
+			lo = s.newValue1(ssa.OpInt64Lo, types.Types[types.TINT], idx)
+		} else {
+			lo = s.newValue1(ssa.OpInt64Lo, types.Types[types.TUINT], idx)
+		}
+		if bounded || base.Flag.B != 0 {
+			return lo
+		}
+		bNext := s.f.NewBlock(ssa.BlockPlain)
+		bPanic := s.f.NewBlock(ssa.BlockExit)
+		hi := s.newValue1(ssa.OpInt64Hi, types.Types[types.TUINT32], idx)
+		cmp := s.newValue2(ssa.OpEq32, types.Types[types.TBOOL], hi, s.constInt32(types.Types[types.TUINT32], 0))
+		if !idx.Type.IsSigned() {
+			switch kind {
+			case ssa.BoundsIndex:
+				kind = ssa.BoundsIndexU
+			case ssa.BoundsSliceAlen:
+				kind = ssa.BoundsSliceAlenU
+			case ssa.BoundsSliceAcap:
+				kind = ssa.BoundsSliceAcapU
+			case ssa.BoundsSliceB:
+				kind = ssa.BoundsSliceBU
+			case ssa.BoundsSlice3Alen:
+				kind = ssa.BoundsSlice3AlenU
+			case ssa.BoundsSlice3Acap:
+				kind = ssa.BoundsSlice3AcapU
+			case ssa.BoundsSlice3B:
+				kind = ssa.BoundsSlice3BU
+			case ssa.BoundsSlice3C:
+				kind = ssa.BoundsSlice3CU
+			}
+		}
+		b := s.endBlock()
+		b.Kind = ssa.BlockIf
+		b.SetControl(cmp)
+		b.Likely = ssa.BranchLikely
+		b.AddEdgeTo(bNext)
+		b.AddEdgeTo(bPanic)
+
+		s.startBlock(bPanic)
+		mem := s.newValue4I(ssa.OpPanicExtend, types.TypeMem, int64(kind), hi, lo, len, s.mem())
+		s.endBlock().SetControl(mem)
+		s.startBlock(bNext)
+
+		return lo
+	}
+
+	// Extend value to the required size
+	var op ssa.Op
+	if idx.Type.IsSigned() {
+		switch 10*size + s.config.PtrSize {
+		case 14:
+			op = ssa.OpSignExt8to32
+		case 18:
+			op = ssa.OpSignExt8to64
+		case 24:
+			op = ssa.OpSignExt16to32
+		case 28:
+			op = ssa.OpSignExt16to64
+		case 48:
+			op = ssa.OpSignExt32to64
+		default:
+			s.Fatalf("bad signed index extension %s", idx.Type)
+		}
+	} else {
+		switch 10*size + s.config.PtrSize {
+		case 14:
+			op = ssa.OpZeroExt8to32
+		case 18:
+			op = ssa.OpZeroExt8to64
+		case 24:
+			op = ssa.OpZeroExt16to32
+		case 28:
+			op = ssa.OpZeroExt16to64
+		case 48:
+			op = ssa.OpZeroExt32to64
+		default:
+			s.Fatalf("bad unsigned index extension %s", idx.Type)
+		}
+	}
+	return s.newValue1(op, types.Types[types.TINT], idx)
+}
+
+// CheckLoweredPhi checks that regalloc and stackalloc correctly handled phi values.
+// Called during ssaGenValue.
+func CheckLoweredPhi(v *ssa.Value) {
+	if v.Op != ssa.OpPhi {
+		v.Fatalf("CheckLoweredPhi called with non-phi value: %v", v.LongString())
+	}
+	if v.Type.IsMemory() {
+		return
+	}
+	f := v.Block.Func
+	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 @ %s, but arg %v @ %s\n%s\n", v, loc, a, aloc, v.Block.Func)
+		}
+	}
+}
+
+// CheckLoweredGetClosurePtr checks that v is the first instruction in the function's entry block,
+// except for incoming in-register arguments.
+// The output of LoweredGetClosurePtr is generally hardwired to the correct register.
+// That register contains the closure pointer on closure entry.
+func CheckLoweredGetClosurePtr(v *ssa.Value) {
+	entry := v.Block.Func.Entry
+	if entry != v.Block {
+		base.Fatalf("in %s, badly placed LoweredGetClosurePtr: %v %v", v.Block.Func.Name, v.Block, v)
+	}
+	for _, w := range entry.Values {
+		if w == v {
+			break
+		}
+		switch w.Op {
+		case ssa.OpArgIntReg, ssa.OpArgFloatReg:
+			// okay
+		default:
+			base.Fatalf("in %s, badly placed LoweredGetClosurePtr: %v %v", v.Block.Func.Name, v.Block, v)
+		}
+	}
+}
+
+// CheckArgReg ensures that v is in the function's entry block.
+func CheckArgReg(v *ssa.Value) {
+	entry := v.Block.Func.Entry
+	if entry != v.Block {
+		base.Fatalf("in %s, badly placed ArgIReg or ArgFReg: %v %v", v.Block.Func.Name, v.Block, v)
+	}
+}
+
+func AddrAuto(a *obj.Addr, v *ssa.Value) {
+	n, off := ssa.AutoVar(v)
+	a.Type = obj.TYPE_MEM
+	a.Sym = n.Linksym()
+	a.Reg = int16(Arch.REGSP)
+	a.Offset = n.FrameOffset() + off
+	if n.Class == ir.PPARAM || (n.Class == ir.PPARAMOUT && !n.IsOutputParamInRegisters()) {
+		a.Name = obj.NAME_PARAM
+	} else {
+		a.Name = obj.NAME_AUTO
+	}
+}
+
+// Call returns a new CALL instruction for the SSA value v.
+// It uses PrepareCall to prepare the call.
+func (s *State) Call(v *ssa.Value) *obj.Prog {
+	pPosIsStmt := s.pp.Pos.IsStmt() // The statement-ness fo the call comes from ssaGenState
+	s.PrepareCall(v)
+
+	p := s.Prog(obj.ACALL)
+	if pPosIsStmt == src.PosIsStmt {
+		p.Pos = v.Pos.WithIsStmt()
+	} else {
+		p.Pos = v.Pos.WithNotStmt()
+	}
+	if sym, ok := v.Aux.(*ssa.AuxCall); ok && sym.Fn != nil {
+		p.To.Type = obj.TYPE_MEM
+		p.To.Name = obj.NAME_EXTERN
+		p.To.Sym = sym.Fn
+	} else {
+		// TODO(mdempsky): Can these differences be eliminated?
+		switch Arch.LinkArch.Family {
+		case sys.AMD64, sys.I386, sys.PPC64, sys.RISCV64, sys.S390X, sys.Wasm:
+			p.To.Type = obj.TYPE_REG
+		case sys.ARM, sys.ARM64, sys.MIPS, sys.MIPS64:
+			p.To.Type = obj.TYPE_MEM
+		default:
+			base.Fatalf("unknown indirect call family")
+		}
+		p.To.Reg = v.Args[0].Reg()
+	}
+	return p
+}
+
+// PrepareCall prepares to emit a CALL instruction for v and does call-related bookkeeping.
+// It must be called immediately before emitting the actual CALL instruction,
+// since it emits PCDATA for the stack map at the call (calls are safe points).
+func (s *State) PrepareCall(v *ssa.Value) {
+	idx := s.livenessMap.Get(v)
+	if !idx.StackMapValid() {
+		// See Liveness.hasStackMap.
+		if sym, ok := v.Aux.(*ssa.AuxCall); !ok || !(sym.Fn == ir.Syms.Typedmemclr || sym.Fn == ir.Syms.Typedmemmove) {
+			base.Fatalf("missing stack map index for %v", v.LongString())
+		}
+	}
+
+	call, ok := v.Aux.(*ssa.AuxCall)
+
+	if ok && call.Fn == ir.Syms.Deferreturn {
+		// Deferred calls will appear to be returning to
+		// the CALL deferreturn(SB) that we are about to emit.
+		// However, the stack trace code will show the line
+		// of the instruction byte before the return PC.
+		// To avoid that being an unrelated instruction,
+		// insert an actual hardware NOP that will have the right line number.
+		// This is different from obj.ANOP, which is a virtual no-op
+		// that doesn't make it into the instruction stream.
+		Arch.Ginsnopdefer(s.pp)
+	}
+
+	if ok {
+		// Record call graph information for nowritebarrierrec
+		// analysis.
+		if nowritebarrierrecCheck != nil {
+			nowritebarrierrecCheck.recordCall(s.pp.CurFunc, call.Fn, v.Pos)
+		}
+	}
+
+	if s.maxarg < v.AuxInt {
+		s.maxarg = v.AuxInt
+	}
+}
+
+// UseArgs records the fact that an instruction needs a certain amount of
+// callee args space for its use.
+func (s *State) UseArgs(n int64) {
+	if s.maxarg < n {
+		s.maxarg = n
+	}
+}
+
+// fieldIdx finds the index of the field referred to by the ODOT node n.
+func fieldIdx(n *ir.SelectorExpr) int {
+	t := n.X.Type()
+	if !t.IsStruct() {
+		panic("ODOT's LHS is not a struct")
+	}
+
+	for i, f := range t.Fields().Slice() {
+		if f.Sym == n.Sel {
+			if f.Offset != n.Offset() {
+				panic("field offset doesn't match")
+			}
+			return i
+		}
+	}
+	panic(fmt.Sprintf("can't find field in expr %v\n", n))
+
+	// TODO: keep the result of this function somewhere in the ODOT Node
+	// so we don't have to recompute it each time we need it.
+}
+
+// ssafn holds frontend information about a function that the backend is processing.
+// It also exports a bunch of compiler services for the ssa backend.
+type ssafn struct {
+	curfn      *ir.Func
+	strings    map[string]*obj.LSym // map from constant string to data symbols
+	stksize    int64                // stack size for current frame
+	stkptrsize int64                // prefix of stack containing pointers
+	log        bool                 // print ssa debug to the stdout
+}
+
+// StringData returns a symbol which
+// is the data component of a global string constant containing s.
+func (e *ssafn) StringData(s string) *obj.LSym {
+	if aux, ok := e.strings[s]; ok {
+		return aux
+	}
+	if e.strings == nil {
+		e.strings = make(map[string]*obj.LSym)
+	}
+	data := staticdata.StringSym(e.curfn.Pos(), s)
+	e.strings[s] = data
+	return data
+}
+
+func (e *ssafn) Auto(pos src.XPos, t *types.Type) *ir.Name {
+	return typecheck.TempAt(pos, e.curfn, t) // Note: adds new auto to e.curfn.Func.Dcl list
+}
+
+func (e *ssafn) DerefItab(it *obj.LSym, offset int64) *obj.LSym {
+	return reflectdata.ITabSym(it, offset)
+}
+
+// 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 {
+	node := parent.N
+
+	if node.Class != ir.PAUTO || node.Addrtaken() {
+		// addressed things and non-autos retain their parents (i.e., cannot truly be split)
+		return ssa.LocalSlot{N: node, Type: t, Off: parent.Off + offset}
+	}
+
+	s := &types.Sym{Name: node.Sym().Name + suffix, Pkg: types.LocalPkg}
+	n := ir.NewNameAt(parent.N.Pos(), s)
+	s.Def = n
+	ir.AsNode(s.Def).Name().SetUsed(true)
+	n.SetType(t)
+	n.Class = ir.PAUTO
+	n.SetEsc(ir.EscNever)
+	n.Curfn = e.curfn
+	e.curfn.Dcl = append(e.curfn.Dcl, n)
+	types.CalcSize(t)
+	return ssa.LocalSlot{N: n, Type: t, Off: 0, SplitOf: parent, SplitOffset: offset}
+}
+
+func (e *ssafn) CanSSA(t *types.Type) bool {
+	return TypeOK(t)
+}
+
+func (e *ssafn) Line(pos src.XPos) string {
+	return base.FmtPos(pos)
+}
+
+// Log logs a message from the compiler.
+func (e *ssafn) Logf(msg string, args ...interface{}) {
+	if e.log {
+		fmt.Printf(msg, args...)
+	}
+}
+
+func (e *ssafn) Log() bool {
+	return e.log
+}
+
+// Fatal reports a compiler error and exits.
+func (e *ssafn) Fatalf(pos src.XPos, msg string, args ...interface{}) {
+	base.Pos = pos
+	nargs := append([]interface{}{ir.FuncName(e.curfn)}, args...)
+	base.Fatalf("'%s': "+msg, nargs...)
+}
+
+// Warnl reports a "warning", which is usually flag-triggered
+// logging output for the benefit of tests.
+func (e *ssafn) Warnl(pos src.XPos, fmt_ string, args ...interface{}) {
+	base.WarnfAt(pos, fmt_, args...)
+}
+
+func (e *ssafn) Debug_checknil() bool {
+	return base.Debug.Nil != 0
+}
+
+func (e *ssafn) UseWriteBarrier() bool {
+	return base.Flag.WB
+}
+
+func (e *ssafn) Syslook(name string) *obj.LSym {
+	switch name {
+	case "goschedguarded":
+		return ir.Syms.Goschedguarded
+	case "writeBarrier":
+		return ir.Syms.WriteBarrier
+	case "gcWriteBarrier":
+		return ir.Syms.GCWriteBarrier
+	case "typedmemmove":
+		return ir.Syms.Typedmemmove
+	case "typedmemclr":
+		return ir.Syms.Typedmemclr
+	}
+	e.Fatalf(src.NoXPos, "unknown Syslook func %v", name)
+	return nil
+}
+
+func (e *ssafn) SetWBPos(pos src.XPos) {
+	e.curfn.SetWBPos(pos)
+}
+
+func (e *ssafn) MyImportPath() string {
+	return base.Ctxt.Pkgpath
+}
+
+func clobberBase(n ir.Node) ir.Node {
+	if n.Op() == ir.ODOT {
+		n := n.(*ir.SelectorExpr)
+		if n.X.Type().NumFields() == 1 {
+			return clobberBase(n.X)
+		}
+	}
+	if n.Op() == ir.OINDEX {
+		n := n.(*ir.IndexExpr)
+		if n.X.Type().IsArray() && n.X.Type().NumElem() == 1 {
+			return clobberBase(n.X)
+		}
+	}
+	return n
+}
+
+// callTargetLSym returns the correct LSym to call 'callee' using its ABI.
+func callTargetLSym(callee *ir.Name) *obj.LSym {
+	if callee.Func == nil {
+		// TODO(austin): This happens in a few cases of
+		// compiler-generated functions. These are all
+		// ABIInternal. It would be better if callee.Func was
+		// never nil and we didn't need this case.
+		return callee.Linksym()
+	}
+
+	return callee.LinksymABI(callee.Func.ABI)
+}
+
+func min8(a, b int8) int8 {
+	if a < b {
+		return a
+	}
+	return b
+}
+
+func max8(a, b int8) int8 {
+	if a > b {
+		return a
+	}
+	return b
+}
+
+// deferstruct makes a runtime._defer structure, with additional space for
+// stksize bytes of args.
+func deferstruct(stksize int64) *types.Type {
+	makefield := func(name string, typ *types.Type) *types.Field {
+		// Unlike the global makefield function, this one needs to set Pkg
+		// because these types might be compared (in SSA CSE sorting).
+		// TODO: unify this makefield and the global one above.
+		sym := &types.Sym{Name: name, Pkg: types.LocalPkg}
+		return types.NewField(src.NoXPos, sym, typ)
+	}
+	argtype := types.NewArray(types.Types[types.TUINT8], stksize)
+	argtype.Width = stksize
+	argtype.Align = 1
+	// These fields must match the ones in runtime/runtime2.go:_defer and
+	// cmd/compile/internal/gc/ssa.go:(*state).call.
+	fields := []*types.Field{
+		makefield("siz", types.Types[types.TUINT32]),
+		makefield("started", types.Types[types.TBOOL]),
+		makefield("heap", types.Types[types.TBOOL]),
+		makefield("openDefer", types.Types[types.TBOOL]),
+		makefield("sp", types.Types[types.TUINTPTR]),
+		makefield("pc", types.Types[types.TUINTPTR]),
+		// Note: the types here don't really matter. Defer structures
+		// are always scanned explicitly during stack copying and GC,
+		// so we make them uintptr type even though they are real pointers.
+		makefield("fn", types.Types[types.TUINTPTR]),
+		makefield("_panic", types.Types[types.TUINTPTR]),
+		makefield("link", types.Types[types.TUINTPTR]),
+		makefield("framepc", types.Types[types.TUINTPTR]),
+		makefield("varp", types.Types[types.TUINTPTR]),
+		makefield("fd", types.Types[types.TUINTPTR]),
+		makefield("args", argtype),
+	}
+
+	// build struct holding the above fields
+	s := types.NewStruct(types.NoPkg, fields)
+	s.SetNoalg(true)
+	types.CalcStructSize(s)
+	return s
+}
+
+// SlotAddr uses LocalSlot information to initialize an obj.Addr
+// The resulting addr is used in a non-standard context -- in the prologue
+// of a function, before the frame has been constructed, so the standard
+// addressing for the parameters will be wrong.
+func SpillSlotAddr(spill ssa.Spill, baseReg int16, extraOffset int64) obj.Addr {
+	return obj.Addr{
+		Name:   obj.NAME_NONE,
+		Type:   obj.TYPE_MEM,
+		Reg:    baseReg,
+		Offset: spill.Offset + extraOffset,
+	}
+}
+
+var (
+	BoundsCheckFunc [ssa.BoundsKindCount]*obj.LSym
+	ExtendCheckFunc [ssa.BoundsKindCount]*obj.LSym
+)
+
+// GCWriteBarrierReg maps from registers to gcWriteBarrier implementation LSyms.
+var GCWriteBarrierReg map[int16]*obj.LSym
diff --git a/src/cmd/compile/internal/staticdata/data.go b/src/cmd/compile/internal/staticdata/data.go
new file mode 100644
index 0000000..abb0bba
--- /dev/null
+++ b/src/cmd/compile/internal/staticdata/data.go
@@ -0,0 +1,372 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package staticdata
+
+import (
+	"crypto/sha256"
+	"fmt"
+	"go/constant"
+	"internal/buildcfg"
+	"io"
+	"io/ioutil"
+	"os"
+	"sort"
+	"strconv"
+	"sync"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/objabi"
+	"cmd/internal/src"
+)
+
+// InitAddrOffset writes the static name symbol lsym to n, it does not modify n.
+// It's the caller responsibility to make sure lsym is from ONAME/PEXTERN node.
+func InitAddrOffset(n *ir.Name, noff int64, lsym *obj.LSym, off int64) {
+	if n.Op() != ir.ONAME {
+		base.Fatalf("InitAddr n op %v", n.Op())
+	}
+	if n.Sym() == nil {
+		base.Fatalf("InitAddr nil n sym")
+	}
+	s := n.Linksym()
+	s.WriteAddr(base.Ctxt, noff, types.PtrSize, lsym, off)
+}
+
+// InitAddr is InitAddrOffset, with offset fixed to 0.
+func InitAddr(n *ir.Name, noff int64, lsym *obj.LSym) {
+	InitAddrOffset(n, noff, lsym, 0)
+}
+
+// InitSlice writes a static slice symbol {lsym, lencap, lencap} to n+noff, it does not modify n.
+// It's the caller responsibility to make sure lsym is from ONAME node.
+func InitSlice(n *ir.Name, noff int64, lsym *obj.LSym, lencap int64) {
+	s := n.Linksym()
+	s.WriteAddr(base.Ctxt, noff, types.PtrSize, lsym, 0)
+	s.WriteInt(base.Ctxt, noff+types.SliceLenOffset, types.PtrSize, lencap)
+	s.WriteInt(base.Ctxt, noff+types.SliceCapOffset, types.PtrSize, lencap)
+}
+
+func InitSliceBytes(nam *ir.Name, off int64, s string) {
+	if nam.Op() != ir.ONAME {
+		base.Fatalf("InitSliceBytes %v", nam)
+	}
+	InitSlice(nam, off, slicedata(nam.Pos(), s).Linksym(), int64(len(s)))
+}
+
+const (
+	stringSymPrefix  = "go.string."
+	stringSymPattern = ".gostring.%d.%x"
+)
+
+// StringSym returns a symbol containing the string s.
+// The symbol contains the string data, not a string header.
+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.
+		// Indulge in some paranoia by writing the length of s, too,
+		// as protection against length extension attacks.
+		// Same pattern is known to fileStringSym below.
+		h := sha256.New()
+		io.WriteString(h, s)
+		symname = fmt.Sprintf(stringSymPattern, len(s), h.Sum(nil))
+	} else {
+		// Small strings get named directly by their contents.
+		symname = strconv.Quote(s)
+	}
+
+	symdata := base.Ctxt.Lookup(stringSymPrefix + symname)
+	if !symdata.OnList() {
+		off := dstringdata(symdata, 0, s, pos, "string")
+		objw.Global(symdata, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL)
+		symdata.Set(obj.AttrContentAddressable, true)
+	}
+
+	return symdata
+}
+
+// fileStringSym returns a symbol for the contents and the size of file.
+// If readonly is true, the symbol shares storage with any literal string
+// or other file with the same content and is placed in a read-only section.
+// If readonly is false, the symbol is a read-write copy separate from any other,
+// for use as the backing store of a []byte.
+// The content hash of file is copied into hash. (If hash is nil, nothing is copied.)
+// The returned symbol contains the data itself, not a string header.
+func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj.LSym, int64, error) {
+	f, err := os.Open(file)
+	if err != nil {
+		return nil, 0, err
+	}
+	defer f.Close()
+	info, err := f.Stat()
+	if err != nil {
+		return nil, 0, err
+	}
+	if !info.Mode().IsRegular() {
+		return nil, 0, fmt.Errorf("not a regular file")
+	}
+	size := info.Size()
+	if size <= 1*1024 {
+		data, err := ioutil.ReadAll(f)
+		if err != nil {
+			return nil, 0, err
+		}
+		if int64(len(data)) != size {
+			return nil, 0, fmt.Errorf("file changed between reads")
+		}
+		var sym *obj.LSym
+		if readonly {
+			sym = StringSym(pos, string(data))
+		} else {
+			sym = slicedata(pos, string(data)).Linksym()
+		}
+		if len(hash) > 0 {
+			sum := sha256.Sum256(data)
+			copy(hash, sum[:])
+		}
+		return sym, size, nil
+	}
+	if size > 2e9 {
+		// ggloblsym takes an int32,
+		// and probably the rest of the toolchain
+		// can't handle such big symbols either.
+		// See golang.org/issue/9862.
+		return nil, 0, fmt.Errorf("file too large")
+	}
+
+	// File is too big to read and keep in memory.
+	// Compute hash if needed for read-only content hashing or if the caller wants it.
+	var sum []byte
+	if readonly || len(hash) > 0 {
+		h := sha256.New()
+		n, err := io.Copy(h, f)
+		if err != nil {
+			return nil, 0, err
+		}
+		if n != size {
+			return nil, 0, fmt.Errorf("file changed between reads")
+		}
+		sum = h.Sum(nil)
+		copy(hash, sum)
+	}
+
+	var symdata *obj.LSym
+	if readonly {
+		symname := fmt.Sprintf(stringSymPattern, size, sum)
+		symdata = base.Ctxt.Lookup(stringSymPrefix + symname)
+		if !symdata.OnList() {
+			info := symdata.NewFileInfo()
+			info.Name = file
+			info.Size = size
+			objw.Global(symdata, int32(size), obj.DUPOK|obj.RODATA|obj.LOCAL)
+			// Note: AttrContentAddressable cannot be set here,
+			// because the content-addressable-handling code
+			// does not know about file symbols.
+		}
+	} else {
+		// Emit a zero-length data symbol
+		// and then fix up length and content to use file.
+		symdata = slicedata(pos, "").Linksym()
+		symdata.Size = size
+		symdata.Type = objabi.SNOPTRDATA
+		info := symdata.NewFileInfo()
+		info.Name = file
+		info.Size = size
+	}
+
+	return symdata, size, nil
+}
+
+var slicedataGen int
+
+func slicedata(pos src.XPos, s string) *ir.Name {
+	slicedataGen++
+	symname := fmt.Sprintf(".gobytes.%d", slicedataGen)
+	sym := types.LocalPkg.Lookup(symname)
+	symnode := typecheck.NewName(sym)
+	sym.Def = symnode
+
+	lsym := symnode.Linksym()
+	off := dstringdata(lsym, 0, s, pos, "slice")
+	objw.Global(lsym, int32(off), obj.NOPTR|obj.LOCAL)
+
+	return symnode
+}
+
+func dstringdata(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 {
+		base.ErrorfAt(pos, "%v with length %v is too big", what, len(t))
+		return 0
+	}
+
+	s.WriteString(base.Ctxt, int64(off), len(t), t)
+	return off + len(t)
+}
+
+var (
+	funcsymsmu sync.Mutex // protects funcsyms and associated package lookups (see func funcsym)
+	funcsyms   []*ir.Name // functions that need function value symbols
+)
+
+// FuncLinksym returns n·f, the function value symbol for n.
+func FuncLinksym(n *ir.Name) *obj.LSym {
+	if n.Op() != ir.ONAME || n.Class != ir.PFUNC {
+		base.Fatalf("expected func name: %v", n)
+	}
+	s := n.Sym()
+
+	// funcsymsmu here serves to protect not just mutations of funcsyms (below),
+	// but also the package lookup of the func sym name,
+	// since this function gets called concurrently from the backend.
+	// There are no other concurrent package lookups in the backend,
+	// except for the types package, which is protected separately.
+	// Reusing funcsymsmu to also cover this package lookup
+	// avoids a general, broader, expensive package lookup mutex.
+	// Note NeedFuncSym also does package look-up of func sym names,
+	// but that it is only called serially, from the front end.
+	funcsymsmu.Lock()
+	sf, existed := s.Pkg.LookupOK(ir.FuncSymName(s))
+	// Don't export s·f when compiling for dynamic linking.
+	// When dynamically linking, the necessary function
+	// symbols will be created explicitly with NeedFuncSym.
+	// See the NeedFuncSym comment for details.
+	if !base.Ctxt.Flag_dynlink && !existed {
+		funcsyms = append(funcsyms, n)
+	}
+	funcsymsmu.Unlock()
+
+	return sf.Linksym()
+}
+
+func GlobalLinksym(n *ir.Name) *obj.LSym {
+	if n.Op() != ir.ONAME || n.Class != ir.PEXTERN {
+		base.Fatalf("expected global variable: %v", n)
+	}
+	return n.Linksym()
+}
+
+// NeedFuncSym ensures that fn·f is exported, if needed.
+// It is only used with -dynlink.
+// When not compiling for dynamic linking,
+// the funcsyms are created as needed by
+// the packages that use them.
+// Normally we emit the fn·f stubs as DUPOK syms,
+// but DUPOK doesn't work across shared library boundaries.
+// So instead, when dynamic linking, we only create
+// the fn·f stubs in fn's package.
+func NeedFuncSym(fn *ir.Func) {
+	if base.Ctxt.InParallel {
+		// The append below probably just needs to lock
+		// funcsymsmu, like in FuncSym.
+		base.Fatalf("NeedFuncSym must be called in serial")
+	}
+	if fn.ABI != obj.ABIInternal && buildcfg.Experiment.RegabiWrappers {
+		// Function values must always reference ABIInternal
+		// entry points, so it doesn't make sense to create a
+		// funcsym for other ABIs.
+		//
+		// (If we're using ABI aliases, it doesn't matter.)
+		base.Fatalf("expected ABIInternal: %v has %v", fn.Nname, fn.ABI)
+	}
+	if ir.IsBlank(fn.Nname) {
+		// Blank functions aren't unique, so we can't make a
+		// funcsym for them.
+		base.Fatalf("NeedFuncSym called for _")
+	}
+	if !base.Ctxt.Flag_dynlink {
+		return
+	}
+	s := fn.Nname.Sym()
+	if base.Flag.CompilingRuntime && (s.Name == "getg" || s.Name == "getclosureptr" || s.Name == "getcallerpc" || s.Name == "getcallersp") ||
+		(base.Ctxt.Pkgpath == "internal/abi" && (s.Name == "FuncPCABI0" || s.Name == "FuncPCABIInternal")) {
+		// runtime.getg(), getclosureptr(), getcallerpc(), getcallersp(),
+		// and internal/abi.FuncPCABIxxx() are not real functions and so
+		// do not get funcsyms.
+		return
+	}
+	funcsyms = append(funcsyms, fn.Nname)
+}
+
+func WriteFuncSyms() {
+	sort.Slice(funcsyms, func(i, j int) bool {
+		return funcsyms[i].Linksym().Name < funcsyms[j].Linksym().Name
+	})
+	for _, nam := range funcsyms {
+		s := nam.Sym()
+		sf := s.Pkg.Lookup(ir.FuncSymName(s)).Linksym()
+		// Function values must always reference ABIInternal
+		// entry points.
+		target := s.Linksym()
+		if target.ABI() != obj.ABIInternal {
+			base.Fatalf("expected ABIInternal: %v has %v", target, target.ABI())
+		}
+		objw.SymPtr(sf, 0, target, 0)
+		objw.Global(sf, int32(types.PtrSize), obj.DUPOK|obj.RODATA)
+	}
+}
+
+// InitConst writes the static literal c to n.
+// Neither n nor c is modified.
+func InitConst(n *ir.Name, noff int64, c ir.Node, wid int) {
+	if n.Op() != ir.ONAME {
+		base.Fatalf("InitConst n op %v", n.Op())
+	}
+	if n.Sym() == nil {
+		base.Fatalf("InitConst nil n sym")
+	}
+	if c.Op() == ir.ONIL {
+		return
+	}
+	if c.Op() != ir.OLITERAL {
+		base.Fatalf("InitConst c op %v", c.Op())
+	}
+	s := n.Linksym()
+	switch u := c.Val(); u.Kind() {
+	case constant.Bool:
+		i := int64(obj.Bool2int(constant.BoolVal(u)))
+		s.WriteInt(base.Ctxt, noff, wid, i)
+
+	case constant.Int:
+		s.WriteInt(base.Ctxt, noff, wid, ir.IntVal(c.Type(), u))
+
+	case constant.Float:
+		f, _ := constant.Float64Val(u)
+		switch c.Type().Kind() {
+		case types.TFLOAT32:
+			s.WriteFloat32(base.Ctxt, noff, float32(f))
+		case types.TFLOAT64:
+			s.WriteFloat64(base.Ctxt, noff, f)
+		}
+
+	case constant.Complex:
+		re, _ := constant.Float64Val(constant.Real(u))
+		im, _ := constant.Float64Val(constant.Imag(u))
+		switch c.Type().Kind() {
+		case types.TCOMPLEX64:
+			s.WriteFloat32(base.Ctxt, noff, float32(re))
+			s.WriteFloat32(base.Ctxt, noff+4, float32(im))
+		case types.TCOMPLEX128:
+			s.WriteFloat64(base.Ctxt, noff, re)
+			s.WriteFloat64(base.Ctxt, noff+8, im)
+		}
+
+	case constant.String:
+		i := constant.StringVal(u)
+		symdata := StringSym(n.Pos(), i)
+		s.WriteAddr(base.Ctxt, noff, types.PtrSize, symdata, 0)
+		s.WriteInt(base.Ctxt, noff+int64(types.PtrSize), types.PtrSize, int64(len(i)))
+
+	default:
+		base.Fatalf("InitConst unhandled OLITERAL %v", c)
+	}
+}
diff --git a/src/cmd/compile/internal/staticdata/embed.go b/src/cmd/compile/internal/staticdata/embed.go
new file mode 100644
index 0000000..8936c4f
--- /dev/null
+++ b/src/cmd/compile/internal/staticdata/embed.go
@@ -0,0 +1,181 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package staticdata
+
+import (
+	"path"
+	"sort"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+)
+
+const (
+	embedUnknown = iota
+	embedBytes
+	embedString
+	embedFiles
+)
+
+func embedFileList(v *ir.Name, kind int) []string {
+	// Build list of files to store.
+	have := make(map[string]bool)
+	var list []string
+	for _, e := range *v.Embed {
+		for _, pattern := range e.Patterns {
+			files, ok := base.Flag.Cfg.Embed.Patterns[pattern]
+			if !ok {
+				base.ErrorfAt(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern)
+			}
+			for _, file := range files {
+				if base.Flag.Cfg.Embed.Files[file] == "" {
+					base.ErrorfAt(e.Pos, "invalid go:embed: build system did not map file: %s", file)
+					continue
+				}
+				if !have[file] {
+					have[file] = true
+					list = append(list, file)
+				}
+				if kind == embedFiles {
+					for dir := path.Dir(file); dir != "." && !have[dir]; dir = path.Dir(dir) {
+						have[dir] = true
+						list = append(list, dir+"/")
+					}
+				}
+			}
+		}
+	}
+	sort.Slice(list, func(i, j int) bool {
+		return embedFileLess(list[i], list[j])
+	})
+
+	if kind == embedString || kind == embedBytes {
+		if len(list) > 1 {
+			base.ErrorfAt(v.Pos(), "invalid go:embed: multiple files for type %v", v.Type())
+			return nil
+		}
+	}
+
+	return list
+}
+
+// embedKind determines the kind of embedding variable.
+func embedKind(typ *types.Type) int {
+	if typ.Sym() != nil && typ.Sym().Name == "FS" && (typ.Sym().Pkg.Path == "embed" || (typ.Sym().Pkg == types.LocalPkg && base.Ctxt.Pkgpath == "embed")) {
+		return embedFiles
+	}
+	if typ.Kind() == types.TSTRING {
+		return embedString
+	}
+	if typ.Sym() == nil && typ.IsSlice() && typ.Elem().Kind() == types.TUINT8 {
+		return embedBytes
+	}
+	return embedUnknown
+}
+
+func embedFileNameSplit(name string) (dir, elem string, isDir bool) {
+	if name[len(name)-1] == '/' {
+		isDir = true
+		name = name[:len(name)-1]
+	}
+	i := len(name) - 1
+	for i >= 0 && name[i] != '/' {
+		i--
+	}
+	if i < 0 {
+		return ".", name, isDir
+	}
+	return name[:i], name[i+1:], isDir
+}
+
+// embedFileLess implements the sort order for a list of embedded files.
+// See the comment inside ../../../../embed/embed.go's Files struct for rationale.
+func embedFileLess(x, y string) bool {
+	xdir, xelem, _ := embedFileNameSplit(x)
+	ydir, yelem, _ := embedFileNameSplit(y)
+	return xdir < ydir || xdir == ydir && xelem < yelem
+}
+
+// WriteEmbed emits the init data for a //go:embed variable,
+// which is either a string, a []byte, or an embed.FS.
+func WriteEmbed(v *ir.Name) {
+	// TODO(mdempsky): User errors should be reported by the frontend.
+
+	commentPos := (*v.Embed)[0].Pos
+	if !types.AllowsGoVersion(types.LocalPkg, 1, 16) {
+		prevPos := base.Pos
+		base.Pos = commentPos
+		base.ErrorfVers("go1.16", "go:embed")
+		base.Pos = prevPos
+		return
+	}
+	if base.Flag.Cfg.Embed.Patterns == nil {
+		base.ErrorfAt(commentPos, "invalid go:embed: build system did not supply embed configuration")
+		return
+	}
+	kind := embedKind(v.Type())
+	if kind == embedUnknown {
+		base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())
+		return
+	}
+
+	files := embedFileList(v, kind)
+	switch kind {
+	case embedString, embedBytes:
+		file := files[0]
+		fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], kind == embedString, nil)
+		if err != nil {
+			base.ErrorfAt(v.Pos(), "embed %s: %v", file, err)
+		}
+		sym := v.Linksym()
+		off := 0
+		off = objw.SymPtr(sym, off, fsym, 0)       // data string
+		off = objw.Uintptr(sym, off, uint64(size)) // len
+		if kind == embedBytes {
+			objw.Uintptr(sym, off, uint64(size)) // cap for slice
+		}
+
+	case embedFiles:
+		slicedata := base.Ctxt.Lookup(`"".` + v.Sym().Name + `.files`)
+		off := 0
+		// []files pointed at by Files
+		off = objw.SymPtr(slicedata, off, slicedata, 3*types.PtrSize) // []file, pointing just past slice
+		off = objw.Uintptr(slicedata, off, uint64(len(files)))
+		off = objw.Uintptr(slicedata, off, uint64(len(files)))
+
+		// embed/embed.go type file is:
+		//	name string
+		//	data string
+		//	hash [16]byte
+		// Emit one of these per file in the set.
+		const hashSize = 16
+		hash := make([]byte, hashSize)
+		for _, file := range files {
+			off = objw.SymPtr(slicedata, off, StringSym(v.Pos(), file), 0) // file string
+			off = objw.Uintptr(slicedata, off, uint64(len(file)))
+			if strings.HasSuffix(file, "/") {
+				// entry for directory - no data
+				off = objw.Uintptr(slicedata, off, 0)
+				off = objw.Uintptr(slicedata, off, 0)
+				off += hashSize
+			} else {
+				fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], true, hash)
+				if err != nil {
+					base.ErrorfAt(v.Pos(), "embed %s: %v", file, err)
+				}
+				off = objw.SymPtr(slicedata, off, fsym, 0) // data string
+				off = objw.Uintptr(slicedata, off, uint64(size))
+				off = int(slicedata.WriteBytes(base.Ctxt, int64(off), hash))
+			}
+		}
+		objw.Global(slicedata, int32(off), obj.RODATA|obj.LOCAL)
+		sym := v.Linksym()
+		objw.SymPtr(sym, 0, slicedata, 0)
+	}
+}
diff --git a/src/cmd/compile/internal/staticinit/sched.go b/src/cmd/compile/internal/staticinit/sched.go
new file mode 100644
index 0000000..0c97b6d
--- /dev/null
+++ b/src/cmd/compile/internal/staticinit/sched.go
@@ -0,0 +1,609 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package staticinit
+
+import (
+	"fmt"
+	"go/constant"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/staticdata"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/src"
+)
+
+type Entry struct {
+	Xoffset int64   // struct, array only
+	Expr    ir.Node // bytes of run-time computed expressions
+}
+
+type Plan struct {
+	E []Entry
+}
+
+// An Schedule is used to decompose assignment statements into
+// static and dynamic initialization parts. Static initializations are
+// handled by populating variables' linker symbol data, while dynamic
+// initializations are accumulated to be executed in order.
+type Schedule struct {
+	// Out is the ordered list of dynamic initialization
+	// statements.
+	Out []ir.Node
+
+	Plans map[ir.Node]*Plan
+	Temps map[ir.Node]*ir.Name
+}
+
+func (s *Schedule) append(n ir.Node) {
+	s.Out = append(s.Out, n)
+}
+
+// StaticInit adds an initialization statement n to the schedule.
+func (s *Schedule) StaticInit(n ir.Node) {
+	if !s.tryStaticInit(n) {
+		if base.Flag.Percent != 0 {
+			ir.Dump("nonstatic", n)
+		}
+		s.append(n)
+	}
+}
+
+// tryStaticInit attempts to statically execute an initialization
+// statement and reports whether it succeeded.
+func (s *Schedule) tryStaticInit(nn ir.Node) bool {
+	// Only worry about simple "l = r" assignments. Multiple
+	// variable/expression OAS2 assignments have already been
+	// replaced by multiple simple OAS assignments, and the other
+	// OAS2* assignments mostly necessitate dynamic execution
+	// anyway.
+	if nn.Op() != ir.OAS {
+		return false
+	}
+	n := nn.(*ir.AssignStmt)
+	if ir.IsBlank(n.X) && !AnySideEffects(n.Y) {
+		// Discard.
+		return true
+	}
+	lno := ir.SetPos(n)
+	defer func() { base.Pos = lno }()
+	nam := n.X.(*ir.Name)
+	return s.StaticAssign(nam, 0, n.Y, nam.Type())
+}
+
+// like staticassign but we are copying an already
+// initialized value r.
+func (s *Schedule) staticcopy(l *ir.Name, loff int64, rn *ir.Name, typ *types.Type) bool {
+	if rn.Class == ir.PFUNC {
+		// TODO if roff != 0 { panic }
+		staticdata.InitAddr(l, loff, staticdata.FuncLinksym(rn))
+		return true
+	}
+	if rn.Class != ir.PEXTERN || rn.Sym().Pkg != types.LocalPkg {
+		return false
+	}
+	if rn.Defn.Op() != ir.OAS {
+		return false
+	}
+	if rn.Type().IsString() { // perhaps overwritten by cmd/link -X (#34675)
+		return false
+	}
+	if rn.Embed != nil {
+		return false
+	}
+	orig := rn
+	r := rn.Defn.(*ir.AssignStmt).Y
+	if r == nil {
+		// No explicit initialization value. Probably zeroed but perhaps
+		// supplied externally and of unknown value.
+		return false
+	}
+
+	for r.Op() == ir.OCONVNOP && !types.Identical(r.Type(), typ) {
+		r = r.(*ir.ConvExpr).X
+	}
+
+	switch r.Op() {
+	case ir.OMETHEXPR:
+		r = r.(*ir.SelectorExpr).FuncName()
+		fallthrough
+	case ir.ONAME:
+		r := r.(*ir.Name)
+		if s.staticcopy(l, loff, r, typ) {
+			return true
+		}
+		// We may have skipped past one or more OCONVNOPs, so
+		// use conv to ensure r is assignable to l (#13263).
+		dst := ir.Node(l)
+		if loff != 0 || !types.Identical(typ, l.Type()) {
+			dst = ir.NewNameOffsetExpr(base.Pos, l, loff, typ)
+		}
+		s.append(ir.NewAssignStmt(base.Pos, dst, typecheck.Conv(r, typ)))
+		return true
+
+	case ir.ONIL:
+		return true
+
+	case ir.OLITERAL:
+		if ir.IsZero(r) {
+			return true
+		}
+		staticdata.InitConst(l, loff, r, int(typ.Width))
+		return true
+
+	case ir.OADDR:
+		r := r.(*ir.AddrExpr)
+		if a, ok := r.X.(*ir.Name); ok && a.Op() == ir.ONAME {
+			staticdata.InitAddr(l, loff, staticdata.GlobalLinksym(a))
+			return true
+		}
+
+	case ir.OPTRLIT:
+		r := r.(*ir.AddrExpr)
+		switch r.X.Op() {
+		case ir.OARRAYLIT, ir.OSLICELIT, ir.OSTRUCTLIT, ir.OMAPLIT:
+			// copy pointer
+			staticdata.InitAddr(l, loff, staticdata.GlobalLinksym(s.Temps[r]))
+			return true
+		}
+
+	case ir.OSLICELIT:
+		r := r.(*ir.CompLitExpr)
+		// copy slice
+		staticdata.InitSlice(l, loff, staticdata.GlobalLinksym(s.Temps[r]), r.Len)
+		return true
+
+	case ir.OARRAYLIT, ir.OSTRUCTLIT:
+		r := r.(*ir.CompLitExpr)
+		p := s.Plans[r]
+		for i := range p.E {
+			e := &p.E[i]
+			typ := e.Expr.Type()
+			if e.Expr.Op() == ir.OLITERAL || e.Expr.Op() == ir.ONIL {
+				staticdata.InitConst(l, loff+e.Xoffset, e.Expr, int(typ.Width))
+				continue
+			}
+			x := e.Expr
+			if x.Op() == ir.OMETHEXPR {
+				x = x.(*ir.SelectorExpr).FuncName()
+			}
+			if x.Op() == ir.ONAME && s.staticcopy(l, loff+e.Xoffset, x.(*ir.Name), typ) {
+				continue
+			}
+			// Requires computation, but we're
+			// copying someone else's computation.
+			ll := ir.NewNameOffsetExpr(base.Pos, l, loff+e.Xoffset, typ)
+			rr := ir.NewNameOffsetExpr(base.Pos, orig, e.Xoffset, typ)
+			ir.SetPos(rr)
+			s.append(ir.NewAssignStmt(base.Pos, ll, rr))
+		}
+
+		return true
+	}
+
+	return false
+}
+
+func (s *Schedule) StaticAssign(l *ir.Name, loff int64, r ir.Node, typ *types.Type) bool {
+	if r == nil {
+		// No explicit initialization value. Either zero or supplied
+		// externally.
+		return true
+	}
+	for r.Op() == ir.OCONVNOP {
+		r = r.(*ir.ConvExpr).X
+	}
+
+	assign := func(pos src.XPos, a *ir.Name, aoff int64, v ir.Node) {
+		if s.StaticAssign(a, aoff, v, v.Type()) {
+			return
+		}
+		var lhs ir.Node
+		if ir.IsBlank(a) {
+			// Don't use NameOffsetExpr with blank (#43677).
+			lhs = ir.BlankNode
+		} else {
+			lhs = ir.NewNameOffsetExpr(pos, a, aoff, v.Type())
+		}
+		s.append(ir.NewAssignStmt(pos, lhs, v))
+	}
+
+	switch r.Op() {
+	case ir.ONAME:
+		r := r.(*ir.Name)
+		return s.staticcopy(l, loff, r, typ)
+
+	case ir.OMETHEXPR:
+		r := r.(*ir.SelectorExpr)
+		return s.staticcopy(l, loff, r.FuncName(), typ)
+
+	case ir.ONIL:
+		return true
+
+	case ir.OLITERAL:
+		if ir.IsZero(r) {
+			return true
+		}
+		staticdata.InitConst(l, loff, r, int(typ.Width))
+		return true
+
+	case ir.OADDR:
+		r := r.(*ir.AddrExpr)
+		if name, offset, ok := StaticLoc(r.X); ok && name.Class == ir.PEXTERN {
+			staticdata.InitAddrOffset(l, loff, name.Linksym(), offset)
+			return true
+		}
+		fallthrough
+
+	case ir.OPTRLIT:
+		r := r.(*ir.AddrExpr)
+		switch r.X.Op() {
+		case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT, ir.OSTRUCTLIT:
+			// Init pointer.
+			a := StaticName(r.X.Type())
+
+			s.Temps[r] = a
+			staticdata.InitAddr(l, loff, a.Linksym())
+
+			// Init underlying literal.
+			assign(base.Pos, a, 0, r.X)
+			return true
+		}
+		//dump("not static ptrlit", r);
+
+	case ir.OSTR2BYTES:
+		r := r.(*ir.ConvExpr)
+		if l.Class == ir.PEXTERN && r.X.Op() == ir.OLITERAL {
+			sval := ir.StringVal(r.X)
+			staticdata.InitSliceBytes(l, loff, sval)
+			return true
+		}
+
+	case ir.OSLICELIT:
+		r := r.(*ir.CompLitExpr)
+		s.initplan(r)
+		// Init slice.
+		ta := types.NewArray(r.Type().Elem(), r.Len)
+		ta.SetNoalg(true)
+		a := StaticName(ta)
+		s.Temps[r] = a
+		staticdata.InitSlice(l, loff, a.Linksym(), r.Len)
+		// Fall through to init underlying array.
+		l = a
+		loff = 0
+		fallthrough
+
+	case ir.OARRAYLIT, ir.OSTRUCTLIT:
+		r := r.(*ir.CompLitExpr)
+		s.initplan(r)
+
+		p := s.Plans[r]
+		for i := range p.E {
+			e := &p.E[i]
+			if e.Expr.Op() == ir.OLITERAL || e.Expr.Op() == ir.ONIL {
+				staticdata.InitConst(l, loff+e.Xoffset, e.Expr, int(e.Expr.Type().Width))
+				continue
+			}
+			ir.SetPos(e.Expr)
+			assign(base.Pos, l, loff+e.Xoffset, e.Expr)
+		}
+
+		return true
+
+	case ir.OMAPLIT:
+		break
+
+	case ir.OCLOSURE:
+		r := r.(*ir.ClosureExpr)
+		if ir.IsTrivialClosure(r) {
+			if base.Debug.Closure > 0 {
+				base.WarnfAt(r.Pos(), "closure converted to global")
+			}
+			// Closures with no captured variables are globals,
+			// so the assignment can be done at link time.
+			// TODO if roff != 0 { panic }
+			staticdata.InitAddr(l, loff, staticdata.FuncLinksym(r.Func.Nname))
+			return true
+		}
+		ir.ClosureDebugRuntimeCheck(r)
+
+	case ir.OCONVIFACE:
+		// This logic is mirrored in isStaticCompositeLiteral.
+		// If you change something here, change it there, and vice versa.
+
+		// Determine the underlying concrete type and value we are converting from.
+		r := r.(*ir.ConvExpr)
+		val := ir.Node(r)
+		for val.Op() == ir.OCONVIFACE {
+			val = val.(*ir.ConvExpr).X
+		}
+
+		if val.Type().IsInterface() {
+			// val is an interface type.
+			// If val is nil, we can statically initialize l;
+			// both words are zero and so there no work to do, so report success.
+			// If val is non-nil, we have no concrete type to record,
+			// and we won't be able to statically initialize its value, so report failure.
+			return val.Op() == ir.ONIL
+		}
+
+		reflectdata.MarkTypeUsedInInterface(val.Type(), l.Linksym())
+
+		var itab *ir.AddrExpr
+		if typ.IsEmptyInterface() {
+			itab = reflectdata.TypePtr(val.Type())
+		} else {
+			itab = reflectdata.ITabAddr(val.Type(), typ)
+		}
+
+		// Create a copy of l to modify while we emit data.
+
+		// Emit itab, advance offset.
+		staticdata.InitAddr(l, loff, itab.X.(*ir.LinksymOffsetExpr).Linksym)
+
+		// Emit data.
+		if types.IsDirectIface(val.Type()) {
+			if val.Op() == ir.ONIL {
+				// Nil is zero, nothing to do.
+				return true
+			}
+			// Copy val directly into n.
+			ir.SetPos(val)
+			assign(base.Pos, l, loff+int64(types.PtrSize), val)
+		} else {
+			// Construct temp to hold val, write pointer to temp into n.
+			a := StaticName(val.Type())
+			s.Temps[val] = a
+			assign(base.Pos, a, 0, val)
+			staticdata.InitAddr(l, loff+int64(types.PtrSize), a.Linksym())
+		}
+
+		return true
+	}
+
+	//dump("not static", r);
+	return false
+}
+
+func (s *Schedule) initplan(n ir.Node) {
+	if s.Plans[n] != nil {
+		return
+	}
+	p := new(Plan)
+	s.Plans[n] = p
+	switch n.Op() {
+	default:
+		base.Fatalf("initplan")
+
+	case ir.OARRAYLIT, ir.OSLICELIT:
+		n := n.(*ir.CompLitExpr)
+		var k int64
+		for _, a := range n.List {
+			if a.Op() == ir.OKEY {
+				kv := a.(*ir.KeyExpr)
+				k = typecheck.IndexConst(kv.Key)
+				if k < 0 {
+					base.Fatalf("initplan arraylit: invalid index %v", kv.Key)
+				}
+				a = kv.Value
+			}
+			s.addvalue(p, k*n.Type().Elem().Width, a)
+			k++
+		}
+
+	case ir.OSTRUCTLIT:
+		n := n.(*ir.CompLitExpr)
+		for _, a := range n.List {
+			if a.Op() != ir.OSTRUCTKEY {
+				base.Fatalf("initplan structlit")
+			}
+			a := a.(*ir.StructKeyExpr)
+			if a.Field.IsBlank() {
+				continue
+			}
+			s.addvalue(p, a.Offset, a.Value)
+		}
+
+	case ir.OMAPLIT:
+		n := n.(*ir.CompLitExpr)
+		for _, a := range n.List {
+			if a.Op() != ir.OKEY {
+				base.Fatalf("initplan maplit")
+			}
+			a := a.(*ir.KeyExpr)
+			s.addvalue(p, -1, a.Value)
+		}
+	}
+}
+
+func (s *Schedule) addvalue(p *Plan, xoffset int64, n ir.Node) {
+	// special case: zero can be dropped entirely
+	if ir.IsZero(n) {
+		return
+	}
+
+	// special case: inline struct and array (not slice) literals
+	if isvaluelit(n) {
+		s.initplan(n)
+		q := s.Plans[n]
+		for _, qe := range q.E {
+			// qe is a copy; we are not modifying entries in q.E
+			qe.Xoffset += xoffset
+			p.E = append(p.E, qe)
+		}
+		return
+	}
+
+	// add to plan
+	p.E = append(p.E, Entry{Xoffset: xoffset, Expr: n})
+}
+
+// from here down is the walk analysis
+// of composite literals.
+// most of the work is to generate
+// data statements for the constant
+// part of the composite literal.
+
+var statuniqgen int // name generator for static temps
+
+// StaticName returns a name backed by a (writable) static data symbol.
+// Use readonlystaticname for read-only node.
+func StaticName(t *types.Type) *ir.Name {
+	// Don't use LookupNum; it interns the resulting string, but these are all unique.
+	n := typecheck.NewName(typecheck.Lookup(fmt.Sprintf("%s%d", obj.StaticNamePref, statuniqgen)))
+	statuniqgen++
+	typecheck.Declare(n, ir.PEXTERN)
+	n.SetType(t)
+	return n
+}
+
+// StaticLoc returns the static address of n, if n has one, or else nil.
+func StaticLoc(n ir.Node) (name *ir.Name, offset int64, ok bool) {
+	if n == nil {
+		return nil, 0, false
+	}
+
+	switch n.Op() {
+	case ir.ONAME:
+		n := n.(*ir.Name)
+		return n, 0, true
+
+	case ir.OMETHEXPR:
+		n := n.(*ir.SelectorExpr)
+		return StaticLoc(n.FuncName())
+
+	case ir.ODOT:
+		n := n.(*ir.SelectorExpr)
+		if name, offset, ok = StaticLoc(n.X); !ok {
+			break
+		}
+		offset += n.Offset()
+		return name, offset, true
+
+	case ir.OINDEX:
+		n := n.(*ir.IndexExpr)
+		if n.X.Type().IsSlice() {
+			break
+		}
+		if name, offset, ok = StaticLoc(n.X); !ok {
+			break
+		}
+		l := getlit(n.Index)
+		if l < 0 {
+			break
+		}
+
+		// Check for overflow.
+		if n.Type().Width != 0 && types.MaxWidth/n.Type().Width <= int64(l) {
+			break
+		}
+		offset += int64(l) * n.Type().Width
+		return name, offset, true
+	}
+
+	return nil, 0, false
+}
+
+// AnySideEffects reports whether n contains any operations that could have observable side effects.
+func AnySideEffects(n ir.Node) bool {
+	return ir.Any(n, func(n ir.Node) bool {
+		switch n.Op() {
+		// Assume side effects unless we know otherwise.
+		default:
+			return true
+
+		// No side effects here (arguments are checked separately).
+		case ir.ONAME,
+			ir.ONONAME,
+			ir.OTYPE,
+			ir.OPACK,
+			ir.OLITERAL,
+			ir.ONIL,
+			ir.OADD,
+			ir.OSUB,
+			ir.OOR,
+			ir.OXOR,
+			ir.OADDSTR,
+			ir.OADDR,
+			ir.OANDAND,
+			ir.OBYTES2STR,
+			ir.ORUNES2STR,
+			ir.OSTR2BYTES,
+			ir.OSTR2RUNES,
+			ir.OCAP,
+			ir.OCOMPLIT,
+			ir.OMAPLIT,
+			ir.OSTRUCTLIT,
+			ir.OARRAYLIT,
+			ir.OSLICELIT,
+			ir.OPTRLIT,
+			ir.OCONV,
+			ir.OCONVIFACE,
+			ir.OCONVNOP,
+			ir.ODOT,
+			ir.OEQ,
+			ir.ONE,
+			ir.OLT,
+			ir.OLE,
+			ir.OGT,
+			ir.OGE,
+			ir.OKEY,
+			ir.OSTRUCTKEY,
+			ir.OLEN,
+			ir.OMUL,
+			ir.OLSH,
+			ir.ORSH,
+			ir.OAND,
+			ir.OANDNOT,
+			ir.ONEW,
+			ir.ONOT,
+			ir.OBITNOT,
+			ir.OPLUS,
+			ir.ONEG,
+			ir.OOROR,
+			ir.OPAREN,
+			ir.ORUNESTR,
+			ir.OREAL,
+			ir.OIMAG,
+			ir.OCOMPLEX:
+			return false
+
+		// Only possible side effect is division by zero.
+		case ir.ODIV, ir.OMOD:
+			n := n.(*ir.BinaryExpr)
+			if n.Y.Op() != ir.OLITERAL || constant.Sign(n.Y.Val()) == 0 {
+				return true
+			}
+
+		// Only possible side effect is panic on invalid size,
+		// but many makechan and makemap use size zero, which is definitely OK.
+		case ir.OMAKECHAN, ir.OMAKEMAP:
+			n := n.(*ir.MakeExpr)
+			if !ir.IsConst(n.Len, constant.Int) || constant.Sign(n.Len.Val()) != 0 {
+				return true
+			}
+
+		// Only possible side effect is panic on invalid size.
+		// TODO(rsc): Merge with previous case (probably breaks toolstash -cmp).
+		case ir.OMAKESLICE, ir.OMAKESLICECOPY:
+			return true
+		}
+		return false
+	})
+}
+
+func getlit(lit ir.Node) int {
+	if ir.IsSmallIntConst(lit) {
+		return int(ir.Int64Val(lit))
+	}
+	return -1
+}
+
+func isvaluelit(n ir.Node) bool {
+	return n.Op() == ir.OARRAYLIT || n.Op() == ir.OSTRUCTLIT
+}
diff --git a/src/cmd/compile/internal/syntax/dumper.go b/src/cmd/compile/internal/syntax/dumper.go
index 01453d5..d524788 100644
--- a/src/cmd/compile/internal/syntax/dumper.go
+++ b/src/cmd/compile/internal/syntax/dumper.go
@@ -26,7 +26,7 @@
 
 	defer func() {
 		if e := recover(); e != nil {
-			err = e.(localError).err // re-panics if it's not a localError
+			err = e.(writeError).err // re-panics if it's not a writeError
 		}
 	}()
 
@@ -82,16 +82,16 @@
 	return
 }
 
-// localError wraps locally caught errors so we can distinguish
+// writeError wraps locally caught write errors so we can distinguish
 // them from genuine panics which we don't want to return as errors.
-type localError struct {
+type writeError struct {
 	err error
 }
 
 // printf is a convenience wrapper that takes care of print errors.
 func (p *dumper) printf(format string, args ...interface{}) {
 	if _, err := fmt.Fprintf(p, format, args...); err != nil {
-		panic(localError{err})
+		panic(writeError{err})
 	}
 }
 
diff --git a/src/cmd/compile/internal/syntax/dumper_test.go b/src/cmd/compile/internal/syntax/dumper_test.go
index f84bd2d..22680dc 100644
--- a/src/cmd/compile/internal/syntax/dumper_test.go
+++ b/src/cmd/compile/internal/syntax/dumper_test.go
@@ -13,7 +13,7 @@
 		t.Skip("skipping test in short mode")
 	}
 
-	// provide a dummy error handler so parsing doesn't stop after first error
+	// provide a no-op error handler so parsing doesn't stop after first error
 	ast, err := ParseFile(*src_, func(error) {}, nil, CheckBranches)
 	if err != nil {
 		t.Error(err)
diff --git a/src/cmd/compile/internal/syntax/error_test.go b/src/cmd/compile/internal/syntax/error_test.go
index 72b1ad6..e4bedf5 100644
--- a/src/cmd/compile/internal/syntax/error_test.go
+++ b/src/cmd/compile/internal/syntax/error_test.go
@@ -128,6 +128,10 @@
 	}
 	defer f.Close()
 
+	var mode Mode
+	if strings.HasSuffix(filename, ".go2") {
+		mode = AllowGenerics
+	}
 	ParseFile(filename, func(err error) {
 		e, ok := err.(Error)
 		if !ok {
@@ -160,9 +164,9 @@
 			// we have a match - eliminate this error
 			delete(declared, pos)
 		} else {
-			t.Errorf("%s: unexpected error: %s", orig, e.Msg)
+			t.Errorf("%s:%s: unexpected error: %s", filename, orig, e.Msg)
 		}
-	}, nil, 0)
+	}, nil, mode)
 
 	if *print {
 		fmt.Println()
@@ -171,7 +175,7 @@
 
 	// report expected but not reported errors
 	for pos, pattern := range declared {
-		t.Errorf("%s: missing error: %s", pos, pattern)
+		t.Errorf("%s:%s: missing error: %s", filename, pos, pattern)
 	}
 }
 
diff --git a/src/cmd/compile/internal/syntax/nodes.go b/src/cmd/compile/internal/syntax/nodes.go
index 815630f..fb9786d 100644
--- a/src/cmd/compile/internal/syntax/nodes.go
+++ b/src/cmd/compile/internal/syntax/nodes.go
@@ -37,7 +37,7 @@
 	Pragma   Pragma
 	PkgName  *Name
 	DeclList []Decl
-	Lines    uint
+	EOF      Pos
 	node
 }
 
@@ -55,8 +55,8 @@
 	ImportDecl struct {
 		Group        *Group // nil means not part of a group
 		Pragma       Pragma
-		LocalPkgName *Name // including "."; nil means no rename present
-		Path         *BasicLit
+		LocalPkgName *Name     // including "."; nil means no rename present
+		Path         *BasicLit // Path.Bad || Path.Kind == StringLit; nil means no path
 		decl
 	}
 
@@ -74,11 +74,12 @@
 
 	// Name Type
 	TypeDecl struct {
-		Group  *Group // nil means not part of a group
-		Pragma Pragma
-		Name   *Name
-		Alias  bool
-		Type   Expr
+		Group      *Group // nil means not part of a group
+		Pragma     Pragma
+		Name       *Name
+		TParamList []*Field // nil means no type parameters
+		Alias      bool
+		Type       Expr
 		decl
 	}
 
@@ -99,11 +100,12 @@
 	// func Receiver Name Type { Body }
 	// func Receiver Name Type
 	FuncDecl struct {
-		Pragma Pragma
-		Recv   *Field // nil means regular function
-		Name   *Name
-		Type   *FuncType
-		Body   *BlockStmt // nil means no body (forward declaration)
+		Pragma     Pragma
+		Recv       *Field // nil means regular function
+		Name       *Name
+		TParamList []*Field // nil means no type parameters
+		Type       *FuncType
+		Body       *BlockStmt // nil means no body (forward declaration)
 		decl
 	}
 )
@@ -114,12 +116,19 @@
 
 // All declarations belonging to the same group point to the same Group node.
 type Group struct {
-	dummy int // not empty so we are guaranteed different Group instances
+	_ int // not empty so we are guaranteed different Group instances
 }
 
 // ----------------------------------------------------------------------------
 // Expressions
 
+func NewName(pos Pos, value string) *Name {
+	n := new(Name)
+	n.pos = pos
+	n.Value = value
+	return n
+}
+
 type (
 	Expr interface {
 		Node
@@ -182,6 +191,7 @@
 	}
 
 	// X[Index]
+	// X[T1, T2, ...] (with Ti = Index.(*ListExpr).ElemList[i])
 	IndexExpr struct {
 		X     Expr
 		Index Expr
@@ -272,7 +282,7 @@
 
 	// interface { MethodList[0]; MethodList[1]; ... }
 	InterfaceType struct {
-		MethodList []*Field
+		MethodList []*Field // a field named "type" means a type constraint
 		expr
 	}
 
@@ -357,7 +367,7 @@
 
 	AssignStmt struct {
 		Op       Operator // 0 means no operation
-		Lhs, Rhs Expr     // Rhs == ImplicitOne means Lhs++ (Op == Add) or Lhs-- (Op == Sub)
+		Lhs, Rhs Expr     // Rhs == nil means Lhs++ (Op == Add) or Lhs-- (Op == Sub)
 		simpleStmt
 	}
 
diff --git a/src/cmd/compile/internal/syntax/operator_string.go b/src/cmd/compile/internal/syntax/operator_string.go
index 3c759b2..f045d8c 100644
--- a/src/cmd/compile/internal/syntax/operator_string.go
+++ b/src/cmd/compile/internal/syntax/operator_string.go
@@ -1,12 +1,41 @@
-// Code generated by "stringer -type Operator -linecomment"; DO NOT EDIT.
+// Code generated by "stringer -type Operator -linecomment tokens.go"; DO NOT EDIT.
 
 package syntax
 
 import "strconv"
 
-const _Operator_name = ":!<-||&&==!=<<=>>=+-|^*/%&&^<<>>"
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[Def-1]
+	_ = x[Not-2]
+	_ = x[Recv-3]
+	_ = x[Tilde-4]
+	_ = x[OrOr-5]
+	_ = x[AndAnd-6]
+	_ = x[Eql-7]
+	_ = x[Neq-8]
+	_ = x[Lss-9]
+	_ = x[Leq-10]
+	_ = x[Gtr-11]
+	_ = x[Geq-12]
+	_ = x[Add-13]
+	_ = x[Sub-14]
+	_ = x[Or-15]
+	_ = x[Xor-16]
+	_ = x[Mul-17]
+	_ = x[Div-18]
+	_ = x[Rem-19]
+	_ = x[And-20]
+	_ = x[AndNot-21]
+	_ = x[Shl-22]
+	_ = x[Shr-23]
+}
 
-var _Operator_index = [...]uint8{0, 1, 2, 4, 6, 8, 10, 12, 13, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 30, 32}
+const _Operator_name = ":!<-~||&&==!=<<=>>=+-|^*/%&&^<<>>"
+
+var _Operator_index = [...]uint8{0, 1, 2, 4, 5, 7, 9, 11, 13, 14, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 31, 33}
 
 func (i Operator) String() string {
 	i -= 1
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index 1485b70..e7b8840 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -445,7 +445,7 @@
 	// p.tok == _EOF
 
 	p.clearPragma()
-	f.Lines = p.line
+	f.EOF = p.pos()
 
 	return f
 }
@@ -458,21 +458,22 @@
 // ----------------------------------------------------------------------------
 // Declarations
 
-// 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 parses a possibly empty, sep-separated list of elements, optionally
+// followed by sep, and closed by close (or EOF). sep must be one of _Comma
+// or _Semi, and close must be one of _Rparen, _Rbrace, or _Rbrack.
 //
-// list = "(" { f sep } ")" |
-//        "{" { f sep } "}" . // sep is optional before ")" or "}"
+// For each list element, f is called. Specifically, unless we're at close
+// (or EOF), f is called at least once. After f returns true, no more list
+// elements are accepted. list returns the position of the closing token.
 //
-func (p *parser) list(open, sep, close token, f func() bool) Pos {
-	p.want(open)
+// list = [ f { sep f } [sep] ] close .
+//
+func (p *parser) list(sep, close token, f func() bool) Pos {
+	if debug && (sep != _Comma && sep != _Semi || close != _Rparen && close != _Rbrace && close != _Rbrack) {
+		panic("invalid sep or close argument for list")
+	}
 
-	var done bool
+	done := false
 	for p.tok != _EOF && p.tok != close && !done {
 		done = f()
 		// sep is optional before close
@@ -496,22 +497,18 @@
 	if p.tok == _Lparen {
 		g := new(Group)
 		p.clearPragma()
-		p.list(_Lparen, _Semi, _Rparen, func() bool {
-			list = append(list, f(g))
+		p.next() // must consume "(" after calling clearPragma!
+		p.list(_Semi, _Rparen, func() bool {
+			if x := f(g); x != nil {
+				list = append(list, x)
+			}
 			return false
 		})
 	} else {
-		list = append(list, f(nil))
-	}
-
-	if debug {
-		for _, d := range list {
-			if d == nil {
-				panic("nil list entry")
-			}
+		if x := f(nil); x != nil {
+			list = append(list, x)
 		}
 	}
-
 	return list
 }
 
@@ -531,15 +528,20 @@
 	case _Name:
 		d.LocalPkgName = p.name()
 	case _Dot:
-		d.LocalPkgName = p.newName(".")
+		d.LocalPkgName = NewName(p.pos(), ".")
 		p.next()
 	}
 	d.Path = p.oliteral()
 	if d.Path == nil {
 		p.syntaxError("missing import path")
 		p.advance(_Semi, _Rparen)
-		return nil
+		return d
 	}
+	if !d.Path.Bad && d.Path.Kind != StringLit {
+		p.syntaxError("import path must be a string")
+		d.Path.Bad = true
+	}
+	// d.Path.Bad || d.Path.Kind == StringLit
 
 	return d
 }
@@ -566,7 +568,7 @@
 	return d
 }
 
-// TypeSpec = identifier [ "=" ] Type .
+// TypeSpec = identifier [ TypeParams ] [ "=" ] Type .
 func (p *parser) typeDecl(group *Group) Decl {
 	if trace {
 		defer p.trace("typeDecl")()
@@ -578,8 +580,42 @@
 	d.Pragma = p.takePragma()
 
 	d.Name = p.name()
-	d.Alias = p.gotAssign()
-	d.Type = p.typeOrNil()
+	if p.tok == _Lbrack {
+		// array/slice or generic type
+		pos := p.pos()
+		p.next()
+		switch p.tok {
+		case _Rbrack:
+			p.next()
+			d.Type = p.sliceType(pos)
+		case _Name:
+			// array or generic type
+			p.xnest++
+			x := p.expr()
+			p.xnest--
+			if name0, ok := x.(*Name); p.mode&AllowGenerics != 0 && ok && p.tok != _Rbrack {
+				// generic type
+				d.TParamList = p.paramList(name0, _Rbrack, true)
+				pos := p.pos()
+				if p.gotAssign() {
+					p.syntaxErrorAt(pos, "generic type cannot be alias")
+				}
+				d.Type = p.typeOrNil()
+			} else {
+				// x is the array length expression
+				if debug && x == nil {
+					panic("internal error: nil expression")
+				}
+				d.Type = p.arrayType(pos, x)
+			}
+		default:
+			d.Type = p.arrayType(pos, nil)
+		}
+	} else {
+		d.Alias = p.gotAssign()
+		d.Type = p.typeOrNil()
+	}
+
 	if d.Type == nil {
 		d.Type = p.badExpr()
 		p.syntaxError("in type declaration")
@@ -613,7 +649,7 @@
 	return d
 }
 
-// FunctionDecl = "func" FunctionName ( Function | Signature ) .
+// FunctionDecl = "func" FunctionName [ TypeParams ] ( Function | Signature ) .
 // FunctionName = identifier .
 // Function     = Signature FunctionBody .
 // MethodDecl   = "func" Receiver MethodName ( Function | Signature ) .
@@ -627,8 +663,8 @@
 	f.pos = p.pos()
 	f.Pragma = p.takePragma()
 
-	if p.tok == _Lparen {
-		rcvr := p.paramList()
+	if p.got(_Lparen) {
+		rcvr := p.paramList(nil, _Rparen, false)
 		switch len(rcvr) {
 		case 0:
 			p.error("method has no receiver")
@@ -647,6 +683,14 @@
 	}
 
 	f.Name = p.name()
+	if p.mode&AllowGenerics != 0 && p.got(_Lbrack) {
+		if p.tok == _Rbrack {
+			p.syntaxError("empty type parameter list")
+			p.next()
+		} else {
+			f.TParamList = p.paramList(nil, _Rbrack, true)
+		}
+	}
 	f.Type = p.funcType()
 	if p.tok == _Lbrace {
 		f.Body = p.funcBody()
@@ -691,9 +735,9 @@
 		t := new(Operation)
 		t.pos = p.pos()
 		t.Op = p.op
-		t.X = x
 		tprec := p.prec
 		p.next()
+		t.X = x
 		t.Y = p.binaryExpr(tprec)
 		x = t
 	}
@@ -850,13 +894,7 @@
 		// Optimization: Record presence of ()'s only where needed
 		// for error reporting. Don't bother in other cases; it is
 		// just a waste of memory and time.
-
-		// Parentheses are not permitted on lhs of := .
-		// switch x.Op {
-		// case ONAME, ONONAME, OPACK, OTYPE, OLITERAL, OTYPESW:
-		// 	keep_parens = true
-		// }
-
+		//
 		// Parentheses are not permitted around T in a composite
 		// literal T{}. If the next token is a {, assume x is a
 		// composite literal type T (it may not be, { could be
@@ -879,19 +917,19 @@
 	case _Func:
 		pos := p.pos()
 		p.next()
-		t := p.funcType()
+		ftyp := p.funcType()
 		if p.tok == _Lbrace {
 			p.xnest++
 
 			f := new(FuncLit)
 			f.pos = pos
-			f.Type = t
+			f.Type = ftyp
 			f.Body = p.funcBody()
 
 			p.xnest--
 			return f
 		}
-		return t
+		return ftyp
 
 	case _Lbrack, _Chan, _Map, _Struct, _Interface:
 		return p.type_() // othertype
@@ -971,29 +1009,52 @@
 
 		case _Lbrack:
 			p.next()
-			p.xnest++
+
+			if p.tok == _Rbrack {
+				// invalid empty instance, slice or index expression; accept but complain
+				p.syntaxError("expecting operand")
+				p.next()
+				break
+			}
 
 			var i Expr
 			if p.tok != _Colon {
-				i = p.expr()
-				if p.got(_Rbrack) {
-					// x[i]
-					t := new(IndexExpr)
-					t.pos = pos
-					t.X = x
-					t.Index = i
-					x = t
+				if p.mode&AllowGenerics == 0 {
+					p.xnest++
+					i = p.expr()
 					p.xnest--
-					break
+					if p.got(_Rbrack) {
+						// x[i]
+						t := new(IndexExpr)
+						t.pos = pos
+						t.X = x
+						t.Index = i
+						x = t
+						break
+					}
+				} else {
+					var comma bool
+					i, comma = p.typeList()
+					if comma || p.tok == _Rbrack {
+						p.want(_Rbrack)
+						// x[i,] or x[i, j, ...]
+						t := new(IndexExpr)
+						t.pos = pos
+						t.X = x
+						t.Index = i
+						x = t
+						break
+					}
 				}
 			}
 
 			// x[i:...
+			p.want(_Colon)
+			p.xnest++
 			t := new(SliceExpr)
 			t.pos = pos
 			t.X = x
 			t.Index[0] = i
-			p.want(_Colon)
 			if p.tok != _Colon && p.tok != _Rbrack {
 				// x[i:j...
 				t.Index[1] = p.expr()
@@ -1014,14 +1075,14 @@
 					t.Index[2] = p.badExpr()
 				}
 			}
-			p.want(_Rbrack)
-
-			x = t
 			p.xnest--
+			p.want(_Rbrack)
+			x = t
 
 		case _Lparen:
 			t := new(CallExpr)
 			t.pos = pos
+			p.next()
 			t.Fun = x
 			t.ArgList, t.HasDots = p.argList()
 			x = t
@@ -1035,7 +1096,12 @@
 			switch t.(type) {
 			case *Name, *SelectorExpr:
 				if p.xnest >= 0 {
-					// x is considered a composite literal type
+					// x is possibly a composite literal type
+					complit_ok = true
+				}
+			case *IndexExpr:
+				if p.xnest >= 0 {
+					// x is possibly a composite literal type
 					complit_ok = true
 				}
 			case *ArrayType, *SliceType, *StructType, *MapType:
@@ -1085,7 +1151,8 @@
 	x.pos = p.pos()
 
 	p.xnest++
-	x.Rbrace = p.list(_Lbrace, _Comma, _Rbrace, func() bool {
+	p.want(_Lbrace)
+	x.Rbrace = p.list(_Comma, _Rbrace, func() bool {
 		// value
 		e := p.bare_complitexpr()
 		if p.tok == _Colon {
@@ -1170,26 +1237,10 @@
 		// '[' oexpr ']' ntype
 		// '[' _DotDotDot ']' ntype
 		p.next()
-		p.xnest++
 		if p.got(_Rbrack) {
-			// []T
-			p.xnest--
-			t := new(SliceType)
-			t.pos = pos
-			t.Elem = p.type_()
-			return t
+			return p.sliceType(pos)
 		}
-
-		// [n]T
-		t := new(ArrayType)
-		t.pos = pos
-		if !p.got(_DotDotDot) {
-			t.Len = p.expr()
-		}
-		p.want(_Rbrack)
-		p.xnest--
-		t.Elem = p.type_()
-		return t
+		return p.arrayType(pos, nil)
 
 	case _Chan:
 		// _Chan non_recvchantype
@@ -1221,7 +1272,7 @@
 		return p.interfaceType()
 
 	case _Name:
-		return p.dotname(p.name())
+		return p.qualifiedName(nil)
 
 	case _Lparen:
 		p.next()
@@ -1233,6 +1284,26 @@
 	return nil
 }
 
+func (p *parser) typeInstance(typ Expr) Expr {
+	if trace {
+		defer p.trace("typeInstance")()
+	}
+
+	pos := p.pos()
+	p.want(_Lbrack)
+	x := new(IndexExpr)
+	x.pos = pos
+	x.X = typ
+	if p.tok == _Rbrack {
+		p.syntaxError("expecting type")
+		x.Index = p.badExpr()
+	} else {
+		x.Index, _ = p.typeList()
+	}
+	p.want(_Rbrack)
+	return x
+}
+
 func (p *parser) funcType() *FuncType {
 	if trace {
 		defer p.trace("funcType")()
@@ -1240,12 +1311,41 @@
 
 	typ := new(FuncType)
 	typ.pos = p.pos()
-	typ.ParamList = p.paramList()
+	p.want(_Lparen)
+	typ.ParamList = p.paramList(nil, _Rparen, false)
 	typ.ResultList = p.funcResult()
 
 	return typ
 }
 
+// "[" has already been consumed, and pos is its position.
+// If len != nil it is the already consumed array length.
+func (p *parser) arrayType(pos Pos, len Expr) Expr {
+	if trace {
+		defer p.trace("arrayType")()
+	}
+
+	if len == nil && !p.got(_DotDotDot) {
+		p.xnest++
+		len = p.expr()
+		p.xnest--
+	}
+	p.want(_Rbrack)
+	t := new(ArrayType)
+	t.pos = pos
+	t.Len = len
+	t.Elem = p.type_()
+	return t
+}
+
+// "[" and "]" have already been consumed, and pos is the position of "[".
+func (p *parser) sliceType(pos Pos) Expr {
+	t := new(SliceType)
+	t.pos = pos
+	t.Elem = p.type_()
+	return t
+}
+
 func (p *parser) chanElem() Expr {
 	if trace {
 		defer p.trace("chanElem")()
@@ -1261,22 +1361,6 @@
 	return typ
 }
 
-func (p *parser) dotname(name *Name) Expr {
-	if trace {
-		defer p.trace("dotname")()
-	}
-
-	if p.tok == _Dot {
-		s := new(SelectorExpr)
-		s.pos = p.pos()
-		p.next()
-		s.X = name
-		s.Sel = p.name()
-		return s
-	}
-	return name
-}
-
 // StructType = "struct" "{" { FieldDecl ";" } "}" .
 func (p *parser) structType() *StructType {
 	if trace {
@@ -1287,7 +1371,8 @@
 	typ.pos = p.pos()
 
 	p.want(_Struct)
-	p.list(_Lbrace, _Semi, _Rbrace, func() bool {
+	p.want(_Lbrace)
+	p.list(_Semi, _Rbrace, func() bool {
 		p.fieldDecl(typ)
 		return false
 	})
@@ -1295,7 +1380,9 @@
 	return typ
 }
 
-// InterfaceType = "interface" "{" { MethodSpec ";" } "}" .
+// InterfaceType = "interface" "{" { ( MethodDecl | EmbeddedElem | TypeList ) ";" } "}" .
+// TypeList      = "type" Type { "," Type } .
+// TODO(gri) remove TypeList syntax if we accept #45346
 func (p *parser) interfaceType() *InterfaceType {
 	if trace {
 		defer p.trace("interfaceType")()
@@ -1305,10 +1392,67 @@
 	typ.pos = p.pos()
 
 	p.want(_Interface)
-	p.list(_Lbrace, _Semi, _Rbrace, func() bool {
-		if m := p.methodDecl(); m != nil {
-			typ.MethodList = append(typ.MethodList, m)
+	p.want(_Lbrace)
+	p.list(_Semi, _Rbrace, func() bool {
+		switch p.tok {
+		case _Name:
+			f := p.methodDecl()
+			if f.Name == nil && p.mode&AllowGenerics != 0 {
+				f = p.embeddedElem(f)
+			}
+			typ.MethodList = append(typ.MethodList, f)
+			return false
+
+		case _Lparen:
+			// TODO(gri) Need to decide how to adjust this restriction.
+			p.syntaxError("cannot parenthesize embedded type")
+			f := new(Field)
+			f.pos = p.pos()
+			p.next()
+			f.Type = p.qualifiedName(nil)
+			p.want(_Rparen)
+			typ.MethodList = append(typ.MethodList, f)
+			return false
+
+		case _Operator:
+			if p.op == Tilde && p.mode&AllowGenerics != 0 {
+				typ.MethodList = append(typ.MethodList, p.embeddedElem(nil))
+				return false
+			}
+
+		case _Type:
+			// TODO(gri) remove TypeList syntax if we accept #45346
+			if p.mode&AllowGenerics != 0 {
+				type_ := NewName(p.pos(), "type") // cannot have a method named "type"
+				p.next()
+				if p.tok != _Semi && p.tok != _Rbrace {
+					f := new(Field)
+					f.pos = p.pos()
+					f.Name = type_
+					f.Type = p.type_()
+					typ.MethodList = append(typ.MethodList, f)
+					for p.got(_Comma) {
+						f := new(Field)
+						f.pos = p.pos()
+						f.Name = type_
+						f.Type = p.type_()
+						typ.MethodList = append(typ.MethodList, f)
+					}
+				} else {
+					p.syntaxError("expecting type")
+				}
+				return false
+			}
 		}
+
+		if p.mode&AllowGenerics != 0 {
+			p.syntaxError("expecting method, type list, or embedded element")
+			p.advance(_Semi, _Rbrace, _Type) // TODO(gri) remove _Type if we don't accept it anymore
+			return false
+		}
+
+		p.syntaxError("expecting method or interface name")
+		p.advance(_Semi, _Rbrace)
 		return false
 	})
 
@@ -1321,8 +1465,8 @@
 		defer p.trace("funcResult")()
 	}
 
-	if p.tok == _Lparen {
-		return p.paramList()
+	if p.got(_Lparen) {
+		return p.paramList(nil, _Rparen, false)
 	}
 
 	pos := p.pos()
@@ -1368,59 +1512,71 @@
 	case _Name:
 		name := p.name()
 		if p.tok == _Dot || p.tok == _Literal || p.tok == _Semi || p.tok == _Rbrace {
-			// embed oliteral
+			// embedded type
 			typ := p.qualifiedName(name)
 			tag := p.oliteral()
 			p.addField(styp, pos, nil, typ, tag)
-			return
+			break
 		}
 
-		// new_name_list ntype oliteral
+		// name1, name2, ... Type [ tag ]
 		names := p.nameList(name)
-		typ := p.type_()
+		var typ Expr
+
+		// Careful dance: We don't know if we have an embedded instantiated
+		// type T[P1, P2, ...] or a field T of array/slice type [P]E or []E.
+		if p.mode&AllowGenerics != 0 && len(names) == 1 && p.tok == _Lbrack {
+			typ = p.arrayOrTArgs()
+			if typ, ok := typ.(*IndexExpr); ok {
+				// embedded type T[P1, P2, ...]
+				typ.X = name // name == names[0]
+				tag := p.oliteral()
+				p.addField(styp, pos, nil, typ, tag)
+				break
+			}
+		} else {
+			// T P
+			typ = p.type_()
+		}
+
 		tag := p.oliteral()
 
 		for _, name := range names {
 			p.addField(styp, name.Pos(), name, typ, tag)
 		}
 
-	case _Lparen:
-		p.next()
-		if p.tok == _Star {
-			// '(' '*' embed ')' oliteral
-			pos := p.pos()
-			p.next()
-			typ := newIndirect(pos, p.qualifiedName(nil))
-			p.want(_Rparen)
-			tag := p.oliteral()
-			p.addField(styp, pos, nil, typ, tag)
-			p.syntaxError("cannot parenthesize embedded type")
-
-		} else {
-			// '(' embed ')' oliteral
-			typ := p.qualifiedName(nil)
-			p.want(_Rparen)
-			tag := p.oliteral()
-			p.addField(styp, pos, nil, typ, tag)
-			p.syntaxError("cannot parenthesize embedded type")
-		}
-
 	case _Star:
 		p.next()
-		if p.got(_Lparen) {
-			// '*' '(' embed ')' oliteral
-			typ := newIndirect(pos, p.qualifiedName(nil))
-			p.want(_Rparen)
-			tag := p.oliteral()
-			p.addField(styp, pos, nil, typ, tag)
+		var typ Expr
+		if p.tok == _Lparen {
+			// *(T)
 			p.syntaxError("cannot parenthesize embedded type")
-
+			p.next()
+			typ = p.qualifiedName(nil)
+			p.got(_Rparen) // no need to complain if missing
 		} else {
-			// '*' embed oliteral
-			typ := newIndirect(pos, p.qualifiedName(nil))
-			tag := p.oliteral()
-			p.addField(styp, pos, nil, typ, tag)
+			// *T
+			typ = p.qualifiedName(nil)
 		}
+		tag := p.oliteral()
+		p.addField(styp, pos, nil, newIndirect(pos, typ), tag)
+
+	case _Lparen:
+		p.syntaxError("cannot parenthesize embedded type")
+		p.next()
+		var typ Expr
+		if p.tok == _Star {
+			// (*T)
+			pos := p.pos()
+			p.next()
+			typ = newIndirect(pos, p.qualifiedName(nil))
+		} else {
+			// (T)
+			typ = p.qualifiedName(nil)
+		}
+		p.got(_Rparen) // no need to complain if missing
+		tag := p.oliteral()
+		p.addField(styp, pos, nil, typ, tag)
 
 	default:
 		p.syntaxError("expecting field name or embedded type")
@@ -1428,6 +1584,39 @@
 	}
 }
 
+func (p *parser) arrayOrTArgs() Expr {
+	if trace {
+		defer p.trace("arrayOrTArgs")()
+	}
+
+	pos := p.pos()
+	p.want(_Lbrack)
+	if p.got(_Rbrack) {
+		return p.sliceType(pos)
+	}
+
+	// x [n]E or x[n,], x[n1, n2], ...
+	n, comma := p.typeList()
+	p.want(_Rbrack)
+	if !comma {
+		if elem := p.typeOrNil(); elem != nil {
+			// x [n]E
+			t := new(ArrayType)
+			t.pos = pos
+			t.Len = n
+			t.Elem = elem
+			return t
+		}
+	}
+
+	// x[n,], x[n1, n2], ...
+	t := new(IndexExpr)
+	t.pos = pos
+	// t.X will be filled in by caller
+	t.Index = n
+	return t
+}
+
 func (p *parser) oliteral() *BasicLit {
 	if p.tok == _Literal {
 		b := new(BasicLit)
@@ -1449,51 +1638,165 @@
 		defer p.trace("methodDecl")()
 	}
 
+	f := new(Field)
+	f.pos = p.pos()
+	name := p.name()
+
+	// accept potential name list but complain
+	// TODO(gri) We probably don't need this special check anymore.
+	//           Nobody writes this kind of code. It's from ancient
+	//           Go beginnings.
+	hasNameList := false
+	for p.got(_Comma) {
+		p.name()
+		hasNameList = true
+	}
+	if hasNameList {
+		p.syntaxError("name list not allowed in interface type")
+		// already progressed, no need to advance
+	}
+
 	switch p.tok {
-	case _Name:
-		name := p.name()
-
-		// accept potential name list but complain
-		hasNameList := false
-		for p.got(_Comma) {
-			p.name()
-			hasNameList = true
-		}
-		if hasNameList {
-			p.syntaxError("name list not allowed in interface type")
-			// already progressed, no need to advance
-		}
-
-		f := new(Field)
-		f.pos = name.Pos()
-		if p.tok != _Lparen {
-			// packname
-			f.Type = p.qualifiedName(name)
-			return f
-		}
-
+	case _Lparen:
+		// method
 		f.Name = name
 		f.Type = p.funcType()
-		return f
 
-	case _Lparen:
-		p.syntaxError("cannot parenthesize embedded type")
-		f := new(Field)
-		f.pos = p.pos()
-		p.next()
-		f.Type = p.qualifiedName(nil)
-		p.want(_Rparen)
-		return f
+	case _Lbrack:
+		if p.mode&AllowGenerics != 0 {
+			// Careful dance: We don't know if we have a generic method m[T C](x T)
+			// or an embedded instantiated type T[P1, P2] (we accept generic methods
+			// for generality and robustness of parsing).
+			pos := p.pos()
+			p.next()
+
+			// Empty type parameter or argument lists are not permitted.
+			// Treat as if [] were absent.
+			if p.tok == _Rbrack {
+				// name[]
+				pos := p.pos()
+				p.next()
+				if p.tok == _Lparen {
+					// name[](
+					p.errorAt(pos, "empty type parameter list")
+					f.Name = name
+					f.Type = p.funcType()
+				} else {
+					p.errorAt(pos, "empty type argument list")
+					f.Type = name
+				}
+				break
+			}
+
+			// A type argument list looks like a parameter list with only
+			// types. Parse a parameter list and decide afterwards.
+			list := p.paramList(nil, _Rbrack, false)
+			if len(list) == 0 {
+				// The type parameter list is not [] but we got nothing
+				// due to other errors (reported by paramList). Treat
+				// as if [] were absent.
+				if p.tok == _Lparen {
+					f.Name = name
+					f.Type = p.funcType()
+				} else {
+					f.Type = name
+				}
+				break
+			}
+
+			// len(list) > 0
+			if list[0].Name != nil {
+				// generic method
+				f.Name = name
+				f.Type = p.funcType()
+				// TODO(gri) Record list as type parameter list with f.Type
+				//           if we want to type-check the generic method.
+				//           For now, report an error so this is not a silent event.
+				p.errorAt(pos, "interface method cannot have type parameters")
+				break
+			}
+
+			// embedded instantiated type
+			t := new(IndexExpr)
+			t.pos = pos
+			t.X = name
+			if len(list) == 1 {
+				t.Index = list[0].Type
+			} else {
+				// len(list) > 1
+				l := new(ListExpr)
+				l.pos = list[0].Pos()
+				l.ElemList = make([]Expr, len(list))
+				for i := range list {
+					l.ElemList[i] = list[i].Type
+				}
+				t.Index = l
+			}
+			f.Type = t
+			break
+		}
+		fallthrough
 
 	default:
-		p.syntaxError("expecting method or interface name")
-		p.advance(_Semi, _Rbrace)
-		return nil
+		// embedded type
+		f.Type = p.qualifiedName(name)
 	}
+
+	return f
+}
+
+// EmbeddedElem = MethodSpec | EmbeddedTerm { "|" EmbeddedTerm } .
+func (p *parser) embeddedElem(f *Field) *Field {
+	if trace {
+		defer p.trace("embeddedElem")()
+	}
+
+	if f == nil {
+		f = new(Field)
+		f.pos = p.pos()
+		f.Type = p.embeddedTerm()
+	}
+
+	for p.tok == _Operator && p.op == Or {
+		t := new(Operation)
+		t.pos = p.pos()
+		t.Op = Or
+		p.next()
+		t.X = f.Type
+		t.Y = p.embeddedTerm()
+		f.Type = t
+	}
+
+	return f
+}
+
+// EmbeddedTerm = [ "~" ] Type .
+func (p *parser) embeddedTerm() Expr {
+	if trace {
+		defer p.trace("embeddedTerm")()
+	}
+
+	if p.tok == _Operator && p.op == Tilde {
+		t := new(Operation)
+		t.pos = p.pos()
+		t.Op = Tilde
+		p.next()
+		t.X = p.type_()
+		return t
+	}
+
+	t := p.typeOrNil()
+	if t == nil {
+		t = p.badExpr()
+		p.syntaxError("expecting ~ term or type")
+		p.advance(_Operator, _Semi, _Rparen, _Rbrack, _Rbrace)
+	}
+
+	return t
 }
 
 // ParameterDecl = [ IdentifierList ] [ "..." ] Type .
-func (p *parser) paramDeclOrNil() *Field {
+func (p *parser) paramDeclOrNil(name *Name) *Field {
 	if trace {
 		defer p.trace("paramDecl")()
 	}
@@ -1501,73 +1804,68 @@
 	f := new(Field)
 	f.pos = p.pos()
 
-	switch p.tok {
-	case _Name:
-		f.Name = p.name()
-		switch p.tok {
-		case _Name, _Star, _Arrow, _Func, _Lbrack, _Chan, _Map, _Struct, _Interface, _Lparen:
-			// sym name_or_type
-			f.Type = p.type_()
-
-		case _DotDotDot:
-			// sym dotdotdot
-			f.Type = p.dotsType()
-
-		case _Dot:
-			// name_or_type
-			// from dotname
-			f.Type = p.dotname(f.Name)
-			f.Name = nil
+	if p.tok == _Name || name != nil {
+		if name == nil {
+			name = p.name()
 		}
 
-	case _Arrow, _Star, _Func, _Lbrack, _Chan, _Map, _Struct, _Interface, _Lparen:
-		// name_or_type
-		f.Type = p.type_()
+		if p.mode&AllowGenerics != 0 && p.tok == _Lbrack {
+			f.Type = p.arrayOrTArgs()
+			if typ, ok := f.Type.(*IndexExpr); ok {
+				typ.X = name
+			} else {
+				f.Name = name
+			}
+			return f
+		}
 
-	case _DotDotDot:
-		// dotdotdot
-		f.Type = p.dotsType()
+		if p.tok == _Dot {
+			// name_or_type
+			f.Type = p.qualifiedName(name)
+			return f
+		}
 
-	default:
-		p.syntaxError("expecting )")
-		p.advance(_Comma, _Rparen)
-		return nil
+		f.Name = name
 	}
 
-	return f
-}
-
-// ...Type
-func (p *parser) dotsType() *DotsType {
-	if trace {
-		defer p.trace("dotsType")()
+	if p.tok == _DotDotDot {
+		t := new(DotsType)
+		t.pos = p.pos()
+		p.next()
+		t.Elem = p.typeOrNil()
+		if t.Elem == nil {
+			t.Elem = p.badExpr()
+			p.syntaxError("... is missing type")
+		}
+		f.Type = t
+		return f
 	}
 
-	t := new(DotsType)
-	t.pos = p.pos()
-
-	p.want(_DotDotDot)
-	t.Elem = p.typeOrNil()
-	if t.Elem == nil {
-		t.Elem = p.badExpr()
-		p.syntaxError("final argument in variadic function missing type")
+	f.Type = p.typeOrNil()
+	if f.Name != nil || f.Type != nil {
+		return f
 	}
 
-	return t
+	p.syntaxError("expecting )")
+	p.advance(_Comma, _Rparen)
+	return nil
 }
 
 // Parameters    = "(" [ ParameterList [ "," ] ] ")" .
 // ParameterList = ParameterDecl { "," ParameterDecl } .
-func (p *parser) paramList() (list []*Field) {
+// "(" or "[" has already been consumed.
+// If name != nil, it is the first name after "(" or "[".
+// In the result list, either all fields have a name, or no field has a name.
+func (p *parser) paramList(name *Name, close token, requireNames bool) (list []*Field) {
 	if trace {
 		defer p.trace("paramList")()
 	}
 
-	pos := p.pos()
-
-	var named int // number of parameters that have an explicit name and type
-	p.list(_Lparen, _Comma, _Rparen, func() bool {
-		if par := p.paramDeclOrNil(); par != nil {
+	var named int // number of parameters that have an explicit name and type/bound
+	p.list(_Comma, close, func() bool {
+		par := p.paramDeclOrNil(name)
+		name = nil // 1st name was consumed if present
+		if par != nil {
 			if debug && par.Name == nil && par.Type == nil {
 				panic("parameter without name or type")
 			}
@@ -1579,7 +1877,11 @@
 		return false
 	})
 
-	// distribute parameter types
+	if len(list) == 0 {
+		return
+	}
+
+	// distribute parameter types (len(list) > 0)
 	if named == 0 {
 		// all unnamed => found names are named types
 		for _, par := range list {
@@ -1588,31 +1890,38 @@
 				par.Name = nil
 			}
 		}
+		if requireNames {
+			p.syntaxErrorAt(list[0].Type.Pos(), "type parameters must be named")
+		}
 	} else if named != len(list) {
-		// some named => all must be named
-		ok := true
+		// some named => all must have names and types
+		var pos Pos // left-most error position (or unknown)
 		var typ Expr
 		for i := len(list) - 1; i >= 0; i-- {
 			if par := list[i]; par.Type != nil {
 				typ = par.Type
 				if par.Name == nil {
-					ok = false
-					n := p.newName("_")
-					n.pos = typ.Pos() // correct position
-					par.Name = n
+					pos = typ.Pos()
+					par.Name = NewName(pos, "_")
 				}
 			} else if typ != nil {
 				par.Type = typ
 			} else {
 				// par.Type == nil && typ == nil => we only have a par.Name
-				ok = false
+				pos = par.Name.Pos()
 				t := p.badExpr()
-				t.pos = par.Name.Pos() // correct position
+				t.pos = pos // correct position
 				par.Type = t
 			}
 		}
-		if !ok {
-			p.syntaxErrorAt(pos, "mixed named and unnamed function parameters")
+		if pos.IsKnown() {
+			var msg string
+			if requireNames {
+				msg = "type parameters must be named"
+			} else {
+				msg = "mixed named and unnamed parameters"
+			}
+			p.syntaxErrorAt(pos, msg)
 		}
 	}
 
@@ -1628,10 +1937,6 @@
 // ----------------------------------------------------------------------------
 // Statements
 
-// We represent x++, x-- as assignments x += ImplicitOne, x -= ImplicitOne.
-// ImplicitOne should not be used elsewhere.
-var ImplicitOne = &BasicLit{Value: "1"}
-
 // SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .
 func (p *parser) simpleStmt(lhs Expr, keyword token) SimpleStmt {
 	if trace {
@@ -1664,7 +1969,7 @@
 			// lhs++ or lhs--
 			op := p.op
 			p.next()
-			return p.newAssignStmt(pos, op, lhs, ImplicitOne)
+			return p.newAssignStmt(pos, op, lhs, nil)
 
 		case _Arrow:
 			// lhs <- rhs
@@ -2208,14 +2513,18 @@
 	return
 }
 
-// Arguments = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" .
+// argList parses a possibly empty, comma-separated list of arguments,
+// optionally followed by a comma (if not empty), and closed by ")".
+// The last argument may be followed by "...".
+//
+// argList = [ arg { "," arg } [ "..." ] [ "," ] ] ")" .
 func (p *parser) argList() (list []Expr, hasDots bool) {
 	if trace {
 		defer p.trace("argList")()
 	}
 
 	p.xnest++
-	p.list(_Lparen, _Comma, _Rparen, func() bool {
+	p.list(_Comma, _Rparen, func() bool {
 		list = append(list, p.expr())
 		hasDots = p.got(_DotDotDot)
 		return hasDots
@@ -2228,23 +2537,16 @@
 // ----------------------------------------------------------------------------
 // Common productions
 
-func (p *parser) newName(value string) *Name {
-	n := new(Name)
-	n.pos = p.pos()
-	n.Value = value
-	return n
-}
-
 func (p *parser) name() *Name {
 	// no tracing to avoid overly verbose output
 
 	if p.tok == _Name {
-		n := p.newName(p.lit)
+		n := NewName(p.pos(), p.lit)
 		p.next()
 		return n
 	}
 
-	n := p.newName("_")
+	n := NewName(p.pos(), "_")
 	p.syntaxError("expecting name")
 	p.advance()
 	return n
@@ -2275,18 +2577,32 @@
 		defer p.trace("qualifiedName")()
 	}
 
+	var x Expr
 	switch {
 	case name != nil:
-		// name is provided
+		x = name
 	case p.tok == _Name:
-		name = p.name()
+		x = p.name()
 	default:
-		name = p.newName("_")
+		x = NewName(p.pos(), "_")
 		p.syntaxError("expecting name")
 		p.advance(_Dot, _Semi, _Rbrace)
 	}
 
-	return p.dotname(name)
+	if p.tok == _Dot {
+		s := new(SelectorExpr)
+		s.pos = p.pos()
+		p.next()
+		s.X = x
+		s.Sel = p.name()
+		x = s
+	}
+
+	if p.mode&AllowGenerics != 0 && p.tok == _Lbrack {
+		x = p.typeInstance(x)
+	}
+
+	return x
 }
 
 // ExpressionList = Expression { "," Expression } .
@@ -2309,6 +2625,41 @@
 	return x
 }
 
+// typeList parses a non-empty, comma-separated list of expressions,
+// optionally followed by a comma. The first list element may be any
+// expression, all other list elements must be type expressions.
+// If there is more than one argument, the result is a *ListExpr.
+// The comma result indicates whether there was a (separating or
+// trailing) comma.
+//
+// typeList = arg { "," arg } [ "," ] .
+func (p *parser) typeList() (x Expr, comma bool) {
+	if trace {
+		defer p.trace("typeList")()
+	}
+
+	p.xnest++
+	x = p.expr()
+	if p.got(_Comma) {
+		comma = true
+		if t := p.typeOrNil(); t != nil {
+			list := []Expr{x, t}
+			for p.got(_Comma) {
+				if t = p.typeOrNil(); t == nil {
+					break
+				}
+				list = append(list, t)
+			}
+			l := new(ListExpr)
+			l.pos = x.Pos() // == list[0].Pos()
+			l.ElemList = list
+			x = l
+		}
+	}
+	p.xnest--
+	return
+}
+
 // 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 81945fa..340ca6b 100644
--- a/src/cmd/compile/internal/syntax/parser_test.go
+++ b/src/cmd/compile/internal/syntax/parser_test.go
@@ -26,10 +26,35 @@
 )
 
 func TestParse(t *testing.T) {
-	ParseFile(*src_, func(err error) { t.Error(err) }, nil, 0)
+	ParseFile(*src_, func(err error) { t.Error(err) }, nil, AllowGenerics)
 }
 
-func TestStdLib(t *testing.T) {
+func TestVerify(t *testing.T) {
+	ast, err := ParseFile(*src_, func(err error) { t.Error(err) }, nil, AllowGenerics)
+	if err != nil {
+		return // error already reported
+	}
+	verifyPrint(t, *src_, ast)
+}
+
+func TestParseGo2(t *testing.T) {
+	dir := filepath.Join(testdata, "go2")
+	list, err := ioutil.ReadDir(dir)
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, fi := range list {
+		name := fi.Name()
+		if !fi.IsDir() && !strings.HasPrefix(name, ".") {
+			ParseFile(filepath.Join(dir, name), func(err error) { t.Error(err) }, nil, AllowGenerics)
+		}
+	}
+}
+
+func TestStdLib(t *testing.T)        { testStdLib(t, 0) }
+func TestStdLibGeneric(t *testing.T) { testStdLib(t, AllowGenerics) }
+
+func testStdLib(t *testing.T, mode Mode) {
 	if testing.Short() {
 		t.Skip("skipping test in short mode")
 	}
@@ -68,15 +93,15 @@
 				if debug {
 					fmt.Printf("parsing %s\n", filename)
 				}
-				ast, err := ParseFile(filename, nil, nil, 0)
+				ast, err := ParseFile(filename, nil, nil, mode)
 				if err != nil {
 					t.Error(err)
 					return
 				}
 				if *verify {
-					verifyPrint(filename, ast)
+					verifyPrint(t, filename, ast)
 				}
-				results <- parseResult{filename, ast.Lines}
+				results <- parseResult{filename, ast.EOF.Line()}
 			})
 		}
 	}()
@@ -142,12 +167,13 @@
 	}
 }
 
-func verifyPrint(filename string, ast1 *File) {
+func verifyPrint(t *testing.T, filename string, ast1 *File) {
 	var buf1 bytes.Buffer
-	_, err := Fprint(&buf1, ast1, true)
+	_, err := Fprint(&buf1, ast1, LineForm)
 	if err != nil {
 		panic(err)
 	}
+	bytes1 := buf1.Bytes()
 
 	ast2, err := Parse(NewFileBase(filename), &buf1, nil, nil, 0)
 	if err != nil {
@@ -155,20 +181,22 @@
 	}
 
 	var buf2 bytes.Buffer
-	_, err = Fprint(&buf2, ast2, true)
+	_, err = Fprint(&buf2, ast2, LineForm)
 	if err != nil {
 		panic(err)
 	}
+	bytes2 := buf2.Bytes()
 
-	if bytes.Compare(buf1.Bytes(), buf2.Bytes()) != 0 {
+	if bytes.Compare(bytes1, bytes2) != 0 {
 		fmt.Printf("--- %s ---\n", filename)
-		fmt.Printf("%s\n", buf1.Bytes())
+		fmt.Printf("%s\n", bytes1)
 		fmt.Println()
 
 		fmt.Printf("--- %s ---\n", filename)
-		fmt.Printf("%s\n", buf2.Bytes())
+		fmt.Printf("%s\n", bytes2)
 		fmt.Println()
-		panic("not equal")
+
+		t.Error("printed syntax trees do not match")
 	}
 }
 
diff --git a/src/cmd/compile/internal/syntax/pos.go b/src/cmd/compile/internal/syntax/pos.go
index c683c7f..baebcc9 100644
--- a/src/cmd/compile/internal/syntax/pos.go
+++ b/src/cmd/compile/internal/syntax/pos.go
@@ -26,6 +26,7 @@
 // TODO(gri) IsKnown makes an assumption about linebase < 1.
 //           Maybe we should check for Base() != nil instead.
 
+func (pos Pos) Pos() Pos       { return pos }
 func (pos Pos) IsKnown() bool  { return pos.line > 0 }
 func (pos Pos) Base() *PosBase { return pos.base }
 func (pos Pos) Line() uint     { return uint(pos.line) }
@@ -58,6 +59,45 @@
 	return pos.Col()
 }
 
+// Cmp compares the positions p and q and returns a result r as follows:
+//
+//	r <  0: p is before q
+//	r == 0: p and q are the same position (but may not be identical)
+//	r >  0: p is after q
+//
+// If p and q are in different files, p is before q if the filename
+// of p sorts lexicographically before the filename of q.
+func (p Pos) Cmp(q Pos) int {
+	pname := p.RelFilename()
+	qname := q.RelFilename()
+	switch {
+	case pname < qname:
+		return -1
+	case pname > qname:
+		return +1
+	}
+
+	pline := p.Line()
+	qline := q.Line()
+	switch {
+	case pline < qline:
+		return -1
+	case pline > qline:
+		return +1
+	}
+
+	pcol := p.Col()
+	qcol := q.Col()
+	switch {
+	case pcol < qcol:
+		return -1
+	case pcol > qcol:
+		return +1
+	}
+
+	return 0
+}
+
 func (pos Pos) String() string {
 	rel := position_{pos.RelFilename(), pos.RelLine(), pos.RelCol()}
 	abs := position_{pos.Base().Pos().RelFilename(), pos.Line(), pos.Col()}
diff --git a/src/cmd/compile/internal/syntax/positions.go b/src/cmd/compile/internal/syntax/positions.go
new file mode 100644
index 0000000..b00f86c
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/positions.go
@@ -0,0 +1,364 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements helper functions for scope position computations.
+
+package syntax
+
+// StartPos returns the start position of n.
+func StartPos(n Node) Pos {
+	// Cases for nodes which don't need a correction are commented out.
+	for m := n; ; {
+		switch n := m.(type) {
+		case nil:
+			panic("internal error: nil")
+
+		// packages
+		case *File:
+			// file block starts at the beginning of the file
+			return MakePos(n.Pos().Base(), 1, 1)
+
+		// declarations
+		// case *ImportDecl:
+		// case *ConstDecl:
+		// case *TypeDecl:
+		// case *VarDecl:
+		// case *FuncDecl:
+
+		// expressions
+		// case *BadExpr:
+		// case *Name:
+		// case *BasicLit:
+		case *CompositeLit:
+			if n.Type != nil {
+				m = n.Type
+				continue
+			}
+			return n.Pos()
+		// case *KeyValueExpr:
+		// case *FuncLit:
+		// case *ParenExpr:
+		case *SelectorExpr:
+			m = n.X
+		case *IndexExpr:
+			m = n.X
+		// case *SliceExpr:
+		case *AssertExpr:
+			m = n.X
+		case *TypeSwitchGuard:
+			if n.Lhs != nil {
+				m = n.Lhs
+				continue
+			}
+			m = n.X
+		case *Operation:
+			if n.Y != nil {
+				m = n.X
+				continue
+			}
+			return n.Pos()
+		case *CallExpr:
+			m = n.Fun
+		case *ListExpr:
+			if len(n.ElemList) > 0 {
+				m = n.ElemList[0]
+				continue
+			}
+			return n.Pos()
+		// types
+		// case *ArrayType:
+		// case *SliceType:
+		// case *DotsType:
+		// case *StructType:
+		// case *Field:
+		// case *InterfaceType:
+		// case *FuncType:
+		// case *MapType:
+		// case *ChanType:
+
+		// statements
+		// case *EmptyStmt:
+		// case *LabeledStmt:
+		// case *BlockStmt:
+		// case *ExprStmt:
+		case *SendStmt:
+			m = n.Chan
+		// case *DeclStmt:
+		case *AssignStmt:
+			m = n.Lhs
+		// case *BranchStmt:
+		// case *CallStmt:
+		// case *ReturnStmt:
+		// case *IfStmt:
+		// case *ForStmt:
+		// case *SwitchStmt:
+		// case *SelectStmt:
+
+		// helper nodes
+		case *RangeClause:
+			if n.Lhs != nil {
+				m = n.Lhs
+				continue
+			}
+			m = n.X
+		// case *CaseClause:
+		// case *CommClause:
+
+		default:
+			return n.Pos()
+		}
+	}
+}
+
+// EndPos returns the approximate end position of n in the source.
+// For some nodes (*Name, *BasicLit) it returns the position immediately
+// following the node; for others (*BlockStmt, *SwitchStmt, etc.) it
+// returns the position of the closing '}'; and for some (*ParenExpr)
+// the returned position is the end position of the last enclosed
+// expression.
+// Thus, EndPos should not be used for exact demarcation of the
+// end of a node in the source; it is mostly useful to determine
+// scope ranges where there is some leeway.
+func EndPos(n Node) Pos {
+	for m := n; ; {
+		switch n := m.(type) {
+		case nil:
+			panic("internal error: nil")
+
+		// packages
+		case *File:
+			return n.EOF
+
+		// declarations
+		case *ImportDecl:
+			m = n.Path
+		case *ConstDecl:
+			if n.Values != nil {
+				m = n.Values
+				continue
+			}
+			if n.Type != nil {
+				m = n.Type
+				continue
+			}
+			if l := len(n.NameList); l > 0 {
+				m = n.NameList[l-1]
+				continue
+			}
+			return n.Pos()
+		case *TypeDecl:
+			m = n.Type
+		case *VarDecl:
+			if n.Values != nil {
+				m = n.Values
+				continue
+			}
+			if n.Type != nil {
+				m = n.Type
+				continue
+			}
+			if l := len(n.NameList); l > 0 {
+				m = n.NameList[l-1]
+				continue
+			}
+			return n.Pos()
+		case *FuncDecl:
+			if n.Body != nil {
+				m = n.Body
+				continue
+			}
+			m = n.Type
+
+		// expressions
+		case *BadExpr:
+			return n.Pos()
+		case *Name:
+			p := n.Pos()
+			return MakePos(p.Base(), p.Line(), p.Col()+uint(len(n.Value)))
+		case *BasicLit:
+			p := n.Pos()
+			return MakePos(p.Base(), p.Line(), p.Col()+uint(len(n.Value)))
+		case *CompositeLit:
+			return n.Rbrace
+		case *KeyValueExpr:
+			m = n.Value
+		case *FuncLit:
+			m = n.Body
+		case *ParenExpr:
+			m = n.X
+		case *SelectorExpr:
+			m = n.Sel
+		case *IndexExpr:
+			m = n.Index
+		case *SliceExpr:
+			for i := len(n.Index) - 1; i >= 0; i-- {
+				if x := n.Index[i]; x != nil {
+					m = x
+					continue
+				}
+			}
+			m = n.X
+		case *AssertExpr:
+			m = n.Type
+		case *TypeSwitchGuard:
+			m = n.X
+		case *Operation:
+			if n.Y != nil {
+				m = n.Y
+				continue
+			}
+			m = n.X
+		case *CallExpr:
+			if l := lastExpr(n.ArgList); l != nil {
+				m = l
+				continue
+			}
+			m = n.Fun
+		case *ListExpr:
+			if l := lastExpr(n.ElemList); l != nil {
+				m = l
+				continue
+			}
+			return n.Pos()
+
+		// types
+		case *ArrayType:
+			m = n.Elem
+		case *SliceType:
+			m = n.Elem
+		case *DotsType:
+			m = n.Elem
+		case *StructType:
+			if l := lastField(n.FieldList); l != nil {
+				m = l
+				continue
+			}
+			return n.Pos()
+			// TODO(gri) need to take TagList into account
+		case *Field:
+			if n.Type != nil {
+				m = n.Type
+				continue
+			}
+			m = n.Name
+		case *InterfaceType:
+			if l := lastField(n.MethodList); l != nil {
+				m = l
+				continue
+			}
+			return n.Pos()
+		case *FuncType:
+			if l := lastField(n.ResultList); l != nil {
+				m = l
+				continue
+			}
+			if l := lastField(n.ParamList); l != nil {
+				m = l
+				continue
+			}
+			return n.Pos()
+		case *MapType:
+			m = n.Value
+		case *ChanType:
+			m = n.Elem
+
+		// statements
+		case *EmptyStmt:
+			return n.Pos()
+		case *LabeledStmt:
+			m = n.Stmt
+		case *BlockStmt:
+			return n.Rbrace
+		case *ExprStmt:
+			m = n.X
+		case *SendStmt:
+			m = n.Value
+		case *DeclStmt:
+			if l := lastDecl(n.DeclList); l != nil {
+				m = l
+				continue
+			}
+			return n.Pos()
+		case *AssignStmt:
+			m = n.Rhs
+			if m == nil {
+				p := EndPos(n.Lhs)
+				return MakePos(p.Base(), p.Line(), p.Col()+2)
+			}
+		case *BranchStmt:
+			if n.Label != nil {
+				m = n.Label
+				continue
+			}
+			return n.Pos()
+		case *CallStmt:
+			m = n.Call
+		case *ReturnStmt:
+			if n.Results != nil {
+				m = n.Results
+				continue
+			}
+			return n.Pos()
+		case *IfStmt:
+			if n.Else != nil {
+				m = n.Else
+				continue
+			}
+			m = n.Then
+		case *ForStmt:
+			m = n.Body
+		case *SwitchStmt:
+			return n.Rbrace
+		case *SelectStmt:
+			return n.Rbrace
+
+		// helper nodes
+		case *RangeClause:
+			m = n.X
+		case *CaseClause:
+			if l := lastStmt(n.Body); l != nil {
+				m = l
+				continue
+			}
+			return n.Colon
+		case *CommClause:
+			if l := lastStmt(n.Body); l != nil {
+				m = l
+				continue
+			}
+			return n.Colon
+
+		default:
+			return n.Pos()
+		}
+	}
+}
+
+func lastDecl(list []Decl) Decl {
+	if l := len(list); l > 0 {
+		return list[l-1]
+	}
+	return nil
+}
+
+func lastExpr(list []Expr) Expr {
+	if l := len(list); l > 0 {
+		return list[l-1]
+	}
+	return nil
+}
+
+func lastStmt(list []Stmt) Stmt {
+	if l := len(list); l > 0 {
+		return list[l-1]
+	}
+	return nil
+}
+
+func lastField(list []*Field) *Field {
+	if l := len(list); l > 0 {
+		return list[l-1]
+	}
+	return nil
+}
diff --git a/src/cmd/compile/internal/syntax/printer.go b/src/cmd/compile/internal/syntax/printer.go
index 8ff3bfa..e557f5d 100644
--- a/src/cmd/compile/internal/syntax/printer.go
+++ b/src/cmd/compile/internal/syntax/printer.go
@@ -13,19 +13,28 @@
 	"strings"
 )
 
-// TODO(gri) Consider removing the linebreaks flag from this signature.
-// Its likely rarely used in common cases.
+// Form controls print formatting.
+type Form uint
 
-func Fprint(w io.Writer, x Node, linebreaks bool) (n int, err error) {
+const (
+	_         Form = iota // default
+	LineForm              // use spaces instead of linebreaks where possible
+	ShortForm             // like LineForm but print "…" for non-empty function or composite literal bodies
+)
+
+// Fprint prints node x to w in the specified form.
+// It returns the number of bytes written, and whether there was an error.
+func Fprint(w io.Writer, x Node, form Form) (n int, err error) {
 	p := printer{
 		output:     w,
-		linebreaks: linebreaks,
+		form:       form,
+		linebreaks: form == 0,
 	}
 
 	defer func() {
 		n = p.written
 		if e := recover(); e != nil {
-			err = e.(localError).err // re-panics if it's not a localError
+			err = e.(writeError).err // re-panics if it's not a writeError
 		}
 	}()
 
@@ -35,11 +44,13 @@
 	return
 }
 
+// String is a convenience functions that prints n in ShortForm
+// and returns the printed string.
 func String(n Node) string {
 	var buf bytes.Buffer
-	_, err := Fprint(&buf, n, false)
+	_, err := Fprint(&buf, n, ShortForm)
 	if err != nil {
-		panic(err) // TODO(gri) print something sensible into buf instead
+		fmt.Fprintf(&buf, "<<< ERROR: %s", err)
 	}
 	return buf.String()
 }
@@ -65,7 +76,8 @@
 
 type printer struct {
 	output     io.Writer
-	written    int  // number of bytes written
+	written    int // number of bytes written
+	form       Form
 	linebreaks bool // print linebreaks instead of semis
 
 	indent  int // current indentation level
@@ -81,7 +93,7 @@
 	n, err := p.output.Write(data)
 	p.written += n
 	if err != nil {
-		panic(localError{err})
+		panic(writeError{err})
 	}
 }
 
@@ -355,17 +367,34 @@
 		p.print(_Name, n.Value) // _Name requires actual value following immediately
 
 	case *FuncLit:
-		p.print(n.Type, blank, n.Body)
+		p.print(n.Type, blank)
+		if n.Body != nil {
+			if p.form == ShortForm {
+				p.print(_Lbrace)
+				if len(n.Body.List) > 0 {
+					p.print(_Name, "…")
+				}
+				p.print(_Rbrace)
+			} else {
+				p.print(n.Body)
+			}
+		}
 
 	case *CompositeLit:
 		if n.Type != nil {
 			p.print(n.Type)
 		}
 		p.print(_Lbrace)
-		if n.NKeys > 0 && n.NKeys == len(n.ElemList) {
-			p.printExprLines(n.ElemList)
+		if p.form == ShortForm {
+			if len(n.ElemList) > 0 {
+				p.print(_Name, "…")
+			}
 		} else {
-			p.printExprList(n.ElemList)
+			if n.NKeys > 0 && n.NKeys == len(n.ElemList) {
+				p.printExprLines(n.ElemList)
+			} else {
+				p.printExprList(n.ElemList)
+			}
 		}
 		p.print(_Rbrace)
 
@@ -450,9 +479,13 @@
 		}
 		p.print(_Lbrace)
 		if len(n.FieldList) > 0 {
-			p.print(newline, indent)
-			p.printFieldList(n.FieldList, n.TagList)
-			p.print(outdent, newline)
+			if p.linebreaks {
+				p.print(newline, indent)
+				p.printFieldList(n.FieldList, n.TagList, _Semi)
+				p.print(outdent, newline)
+			} else {
+				p.printFieldList(n.FieldList, n.TagList, _Semi)
+			}
 		}
 		p.print(_Rbrace)
 
@@ -461,14 +494,38 @@
 		p.printSignature(n)
 
 	case *InterfaceType:
+		// separate type list and method list
+		var types []Expr
+		var methods []*Field
+		for _, f := range n.MethodList {
+			if f.Name != nil && f.Name.Value == "type" {
+				types = append(types, f.Type)
+			} else {
+				// method or embedded interface
+				methods = append(methods, f)
+			}
+		}
+
+		multiLine := len(n.MethodList) > 0 && p.linebreaks
 		p.print(_Interface)
-		if len(n.MethodList) > 0 && p.linebreaks {
+		if multiLine {
 			p.print(blank)
 		}
 		p.print(_Lbrace)
-		if len(n.MethodList) > 0 {
+		if multiLine {
 			p.print(newline, indent)
-			p.printMethodList(n.MethodList)
+		}
+		if len(types) > 0 {
+			p.print(_Type, blank)
+			p.printExprList(types)
+			if len(methods) > 0 {
+				p.print(_Semi, blank)
+			}
+		}
+		if len(methods) > 0 {
+			p.printMethodList(methods)
+		}
+		if multiLine {
 			p.print(outdent, newline)
 		}
 		p.print(_Rbrace)
@@ -484,7 +541,15 @@
 		if n.Dir == SendOnly {
 			p.print(_Arrow)
 		}
-		p.print(blank, n.Elem)
+		p.print(blank)
+		if e, _ := n.Elem.(*ChanType); n.Dir == 0 && e != nil && e.Dir == RecvOnly {
+			// don't print chan (<-chan T) as chan <-chan T
+			p.print(_Lparen)
+			p.print(n.Elem)
+			p.print(_Rparen)
+		} else {
+			p.print(n.Elem)
+		}
 
 	// statements
 	case *DeclStmt:
@@ -504,7 +569,7 @@
 
 	case *AssignStmt:
 		p.print(n.Lhs)
-		if n.Rhs == ImplicitOne {
+		if n.Rhs == nil {
 			// TODO(gri) This is going to break the mayCombine
 			//           check once we enable that again.
 			p.print(n.Op, n.Op) // ++ or --
@@ -622,7 +687,13 @@
 		if n.Group == nil {
 			p.print(_Type, blank)
 		}
-		p.print(n.Name, blank)
+		p.print(n.Name)
+		if n.TParamList != nil {
+			p.print(_Lbrack)
+			p.printFieldList(n.TParamList, nil, _Comma)
+			p.print(_Rbrack)
+		}
+		p.print(blank)
 		if n.Alias {
 			p.print(_Assign, blank)
 		}
@@ -651,6 +722,11 @@
 			p.print(_Rparen, blank)
 		}
 		p.print(n.Name)
+		if n.TParamList != nil {
+			p.print(_Lbrack)
+			p.printFieldList(n.TParamList, nil, _Comma)
+			p.print(_Rbrack)
+		}
 		p.printSignature(n.Type)
 		if n.Body != nil {
 			p.print(blank, n.Body)
@@ -701,14 +777,14 @@
 	}
 }
 
-func (p *printer) printFieldList(fields []*Field, tags []*BasicLit) {
+func (p *printer) printFieldList(fields []*Field, tags []*BasicLit, sep token) {
 	i0 := 0
 	var typ Expr
 	for i, f := range fields {
 		if f.Name == nil || f.Type != typ {
 			if i0 < i {
 				p.printFields(fields, tags, i0, i)
-				p.print(_Semi, newline)
+				p.print(sep, newline)
 				i0 = i
 			}
 			typ = f.Type
diff --git a/src/cmd/compile/internal/syntax/printer_test.go b/src/cmd/compile/internal/syntax/printer_test.go
index c3b9aca..ec4b1de 100644
--- a/src/cmd/compile/internal/syntax/printer_test.go
+++ b/src/cmd/compile/internal/syntax/printer_test.go
@@ -18,25 +18,83 @@
 		t.Skip("skipping test in short mode")
 	}
 
-	// provide a dummy error handler so parsing doesn't stop after first error
+	// provide a no-op error handler so parsing doesn't stop after first error
 	ast, err := ParseFile(*src_, func(error) {}, nil, 0)
 	if err != nil {
 		t.Error(err)
 	}
 
 	if ast != nil {
-		Fprint(testOut(), ast, true)
+		Fprint(testOut(), ast, LineForm)
 		fmt.Println()
 	}
 }
 
+type shortBuffer struct {
+	buf []byte
+}
+
+func (w *shortBuffer) Write(data []byte) (n int, err error) {
+	w.buf = append(w.buf, data...)
+	n = len(data)
+	if len(w.buf) > 10 {
+		err = io.ErrShortBuffer
+	}
+	return
+}
+
+func TestPrintError(t *testing.T) {
+	const src = "package p; var x int"
+	ast, err := Parse(nil, strings.NewReader(src), nil, nil, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var buf shortBuffer
+	_, err = Fprint(&buf, ast, 0)
+	if err == nil || err != io.ErrShortBuffer {
+		t.Errorf("got err = %s, want %s", err, io.ErrShortBuffer)
+	}
+}
+
+var stringTests = []string{
+	"package p",
+	"package p; type _ int; type T1 = struct{}; type ( _ *struct{}; T2 = float32 )",
+
+	// generic type declarations
+	"package p; type _[T any] struct{}",
+	"package p; type _[A, B, C interface{m()}] struct{}",
+	"package p; type _[T any, A, B, C interface{m()}, X, Y, Z interface{type int}] struct{}",
+
+	// generic function declarations
+	"package p; func _[T any]()",
+	"package p; func _[A, B, C interface{m()}]()",
+	"package p; func _[T any, A, B, C interface{m()}, X, Y, Z interface{type int}]()",
+
+	// methods with generic receiver types
+	"package p; func (R[T]) _()",
+	"package p; func (*R[A, B, C]) _()",
+	"package p; func (_ *R[A, B, C]) _()",
+
+	// channels
+	"package p; type _ chan chan int",
+	"package p; type _ chan (<-chan int)",
+	"package p; type _ chan chan<- int",
+
+	"package p; type _ <-chan chan int",
+	"package p; type _ <-chan <-chan int",
+	"package p; type _ <-chan chan<- int",
+
+	"package p; type _ chan<- chan int",
+	"package p; type _ chan<- <-chan int",
+	"package p; type _ chan<- chan<- int",
+
+	// TODO(gri) expand
+}
+
 func TestPrintString(t *testing.T) {
-	for _, want := range []string{
-		"package p",
-		"package p; type _ = int; type T1 = struct{}; type ( _ = *struct{}; T2 = float32 )",
-		// TODO(gri) expand
-	} {
-		ast, err := Parse(nil, strings.NewReader(want), nil, nil, 0)
+	for _, want := range stringTests {
+		ast, err := Parse(nil, strings.NewReader(want), nil, nil, AllowGenerics)
 		if err != nil {
 			t.Error(err)
 			continue
@@ -53,3 +111,117 @@
 	}
 	return ioutil.Discard
 }
+
+func dup(s string) [2]string { return [2]string{s, s} }
+
+var exprTests = [][2]string{
+	// basic type literals
+	dup("x"),
+	dup("true"),
+	dup("42"),
+	dup("3.1415"),
+	dup("2.71828i"),
+	dup(`'a'`),
+	dup(`"foo"`),
+	dup("`bar`"),
+
+	// func and composite literals
+	dup("func() {}"),
+	dup("[]int{}"),
+	{"func(x int) complex128 { return 0 }", "func(x int) complex128 {…}"},
+	{"[]int{1, 2, 3}", "[]int{…}"},
+
+	// type expressions
+	dup("[1 << 10]byte"),
+	dup("[]int"),
+	dup("*int"),
+	dup("struct{x int}"),
+	dup("func()"),
+	dup("func(int, float32) string"),
+	dup("interface{m()}"),
+	dup("interface{m() string; n(x int)}"),
+	dup("interface{type int}"),
+	dup("interface{type int, float64, string}"),
+	dup("interface{type int; m()}"),
+	dup("interface{type int, float64, string; m() string; n(x int)}"),
+	dup("map[string]int"),
+	dup("chan E"),
+	dup("<-chan E"),
+	dup("chan<- E"),
+
+	// new interfaces
+	dup("interface{int}"),
+	dup("interface{~int}"),
+	dup("interface{~int}"),
+	dup("interface{int | string}"),
+	dup("interface{~int | ~string; float64; m()}"),
+	dup("interface{type a, b, c; ~int | ~string; float64; m()}"),
+	dup("interface{~T[int, string] | string}"),
+
+	// non-type expressions
+	dup("(x)"),
+	dup("x.f"),
+	dup("a[i]"),
+
+	dup("s[:]"),
+	dup("s[i:]"),
+	dup("s[:j]"),
+	dup("s[i:j]"),
+	dup("s[:j:k]"),
+	dup("s[i:j:k]"),
+
+	dup("x.(T)"),
+
+	dup("x.([10]int)"),
+	dup("x.([...]int)"),
+
+	dup("x.(struct{})"),
+	dup("x.(struct{x int; y, z float32; E})"),
+
+	dup("x.(func())"),
+	dup("x.(func(x int))"),
+	dup("x.(func() int)"),
+	dup("x.(func(x, y int, z float32) (r int))"),
+	dup("x.(func(a, b, c int))"),
+	dup("x.(func(x ...T))"),
+
+	dup("x.(interface{})"),
+	dup("x.(interface{m(); n(x int); E})"),
+	dup("x.(interface{m(); n(x int) T; E; F})"),
+
+	dup("x.(map[K]V)"),
+
+	dup("x.(chan E)"),
+	dup("x.(<-chan E)"),
+	dup("x.(chan<- chan int)"),
+	dup("x.(chan<- <-chan int)"),
+	dup("x.(<-chan chan int)"),
+	dup("x.(chan (<-chan int))"),
+
+	dup("f()"),
+	dup("f(x)"),
+	dup("int(x)"),
+	dup("f(x, x + y)"),
+	dup("f(s...)"),
+	dup("f(a, s...)"),
+
+	dup("*x"),
+	dup("&x"),
+	dup("x + y"),
+	dup("x + y << (2 * s)"),
+}
+
+func TestShortString(t *testing.T) {
+	for _, test := range exprTests {
+		src := "package p; var _ = " + test[0]
+		ast, err := Parse(nil, strings.NewReader(src), nil, nil, AllowGenerics)
+		if err != nil {
+			t.Errorf("%s: %s", test[0], err)
+			continue
+		}
+		x := ast.DeclList[0].(*VarDecl).Values
+		if got := String(x); got != test[1] {
+			t.Errorf("%s: got %s, want %s", test[0], got, test[1])
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/syntax/scanner.go b/src/cmd/compile/internal/syntax/scanner.go
index 9fe4965..218bc24 100644
--- a/src/cmd/compile/internal/syntax/scanner.go
+++ b/src/cmd/compile/internal/syntax/scanner.go
@@ -343,6 +343,11 @@
 		s.op, s.prec = Not, 0
 		s.tok = _Operator
 
+	case '~':
+		s.nextch()
+		s.op, s.prec = Tilde, 0
+		s.tok = _Operator
+
 	default:
 		s.errorf("invalid character %#U", s.ch)
 		s.nextch()
diff --git a/src/cmd/compile/internal/syntax/scanner_test.go b/src/cmd/compile/internal/syntax/scanner_test.go
index 0433862..2deb3bb 100644
--- a/src/cmd/compile/internal/syntax/scanner_test.go
+++ b/src/cmd/compile/internal/syntax/scanner_test.go
@@ -232,6 +232,9 @@
 	{_Literal, "`\r`", 0, 0},
 
 	// operators
+	{_Operator, "!", Not, 0},
+	{_Operator, "~", Tilde, 0},
+
 	{_Operator, "||", OrOr, precOrOr},
 
 	{_Operator, "&&", AndAnd, precAndAnd},
@@ -547,7 +550,7 @@
 				t.Errorf("%q: got error but bad not set", test.src)
 			}
 
-			// compute lit where where s.lit is not defined
+			// compute lit where s.lit is not defined
 			var lit string
 			switch s.tok {
 			case _Name, _Literal:
@@ -601,7 +604,7 @@
 		{"\U0001d7d8" /* 𝟘 */, "identifier cannot begin with digit U+1D7D8 '𝟘'", 0, 0},
 		{"foo\U0001d7d8_½" /* foo𝟘_½ */, "invalid character U+00BD '½' in identifier", 0, 8 /* byte offset */},
 
-		{"x + ~y", "invalid character U+007E '~'", 0, 4},
+		{"x + #y", "invalid character U+0023 '#'", 0, 4},
 		{"foo$bar = 0", "invalid character U+0024 '$'", 0, 3},
 		{"0123456789", "invalid digit '8' in octal literal", 0, 8},
 		{"0123456789. /* foobar", "comment not terminated", 0, 12},   // valid float constant
diff --git a/src/cmd/compile/internal/syntax/syntax.go b/src/cmd/compile/internal/syntax/syntax.go
index e51b553..f3d4c09 100644
--- a/src/cmd/compile/internal/syntax/syntax.go
+++ b/src/cmd/compile/internal/syntax/syntax.go
@@ -16,6 +16,7 @@
 // Modes supported by the parser.
 const (
 	CheckBranches Mode = 1 << iota // check correct use of labels, break, continue, and goto statements
+	AllowGenerics
 )
 
 // Error describes a syntax error. Error implements the error interface.
diff --git a/src/cmd/compile/internal/syntax/testdata/go2/chans.go2 b/src/cmd/compile/internal/syntax/testdata/go2/chans.go2
new file mode 100644
index 0000000..fad2bce
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/go2/chans.go2
@@ -0,0 +1,62 @@
+package chans
+
+import "runtime"
+
+// Ranger returns a Sender and a Receiver. The Receiver provides a
+// Next method to retrieve values. The Sender provides a Send method
+// to send values and a Close method to stop sending values. The Next
+// method indicates when the Sender has been closed, and the Send
+// method indicates when the Receiver has been freed.
+//
+// This is a convenient way to exit a goroutine sending values when
+// the receiver stops reading them.
+func Ranger[T any]() (*Sender[T], *Receiver[T]) {
+	c := make(chan T)
+	d := make(chan bool)
+	s := &Sender[T]{values: c, done: d}
+	r := &Receiver[T]{values: c, done: d}
+	runtime.SetFinalizer(r, r.finalize)
+	return s, r
+}
+
+// A sender is used to send values to a Receiver.
+type Sender[T any] struct {
+	values chan<- T
+	done <-chan bool
+}
+
+// Send sends a value to the receiver. It returns whether any more
+// values may be sent; if it returns false the value was not sent.
+func (s *Sender[T]) Send(v T) bool {
+	select {
+	case s.values <- v:
+		return true
+	case <-s.done:
+		return false
+	}
+}
+
+// Close tells the receiver that no more values will arrive.
+// After Close is called, the Sender may no longer be used.
+func (s *Sender[T]) Close() {
+	close(s.values)
+}
+
+// A Receiver receives values from a Sender.
+type Receiver[T any] struct {
+	values <-chan T
+	done chan<- bool
+}
+
+// Next returns the next value from the channel. The bool result
+// indicates whether the value is valid, or whether the Sender has
+// been closed and no more values will be received.
+func (r *Receiver[T]) Next() (T, bool) {
+	v, ok := <-r.values
+	return v, ok
+}
+
+// finalize is a finalizer for the receiver.
+func (r *Receiver[T]) finalize() {
+	close(r.done)
+}
diff --git a/src/cmd/compile/internal/syntax/testdata/go2/linalg.go2 b/src/cmd/compile/internal/syntax/testdata/go2/linalg.go2
new file mode 100644
index 0000000..0d27603
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/go2/linalg.go2
@@ -0,0 +1,83 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package linalg
+
+import "math"
+
+// Numeric is type bound that matches any numeric type.
+// It would likely be in a constraints package in the standard library.
+type Numeric interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64,
+		complex64, complex128
+}
+
+func DotProduct[T Numeric](s1, s2 []T) T {
+	if len(s1) != len(s2) {
+		panic("DotProduct: slices of unequal length")
+	}
+	var r T
+	for i := range s1 {
+		r += s1[i] * s2[i]
+	}
+	return r
+}
+
+// NumericAbs matches numeric types with an Abs method.
+type NumericAbs[T any] interface {
+	Numeric
+
+	Abs() T
+}
+
+// AbsDifference computes the absolute value of the difference of
+// a and b, where the absolute value is determined by the Abs method.
+func AbsDifference[T NumericAbs[T]](a, b T) T {
+	d := a - b
+	return d.Abs()
+}
+
+// OrderedNumeric is a type bound that matches numeric types that support the < operator.
+type OrderedNumeric interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64
+}
+
+// Complex is a type bound that matches the two complex types, which do not have a < operator.
+type Complex interface {
+	type complex64, complex128
+}
+
+// OrderedAbs is a helper type that defines an Abs method for
+// ordered numeric types.
+type OrderedAbs[T OrderedNumeric] T
+
+func (a OrderedAbs[T]) Abs() OrderedAbs[T] {
+	if a < 0 {
+		return -a
+	}
+	return a
+}
+
+// ComplexAbs is a helper type that defines an Abs method for
+// complex types.
+type ComplexAbs[T Complex] T
+
+func (a ComplexAbs[T]) Abs() ComplexAbs[T] {
+	r := float64(real(a))
+	i := float64(imag(a))
+	d := math.Sqrt(r * r + i * i)
+	return ComplexAbs[T](complex(d, 0))
+}
+
+func OrderedAbsDifference[T OrderedNumeric](a, b T) T {
+	return T(AbsDifference(OrderedAbs[T](a), OrderedAbs[T](b)))
+}
+
+func ComplexAbsDifference[T Complex](a, b T) T {
+	return T(AbsDifference(ComplexAbs[T](a), ComplexAbs[T](b)))
+}
diff --git a/src/cmd/compile/internal/syntax/testdata/go2/map.go2 b/src/cmd/compile/internal/syntax/testdata/go2/map.go2
new file mode 100644
index 0000000..814d953
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/go2/map.go2
@@ -0,0 +1,113 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package orderedmap provides an ordered map, implemented as a binary tree.
+package orderedmap
+
+// TODO(gri) fix imports for tests
+import "chans" // ERROR could not import
+
+// Map is an ordered map.
+type Map[K, V any] struct {
+	root    *node[K, V]
+	compare func(K, K) int
+}
+
+// node is the type of a node in the binary tree.
+type node[K, V any] struct {
+	key         K
+	val         V
+	left, right *node[K, V]
+}
+
+// New returns a new map.
+func New[K, V any](compare func(K, K) int) *Map[K, V] {
+        return &Map[K, V]{compare: compare}
+}
+
+// find looks up key in the map, and returns either a pointer
+// to the node holding key, or a pointer to the location where
+// such a node would go.
+func (m *Map[K, V]) find(key K) **node[K, V] {
+	pn := &m.root
+	for *pn != nil {
+		switch cmp := m.compare(key, (*pn).key); {
+		case cmp < 0:
+			pn = &(*pn).left
+		case cmp > 0:
+			pn = &(*pn).right
+		default:
+			return pn
+		}
+	}
+	return pn
+}
+
+// Insert inserts a new key/value into the map.
+// If the key is already present, the value is replaced.
+// Returns true if this is a new key, false if already present.
+func (m *Map[K, V]) Insert(key K, val V) bool {
+	pn := m.find(key)
+	if *pn != nil {
+		(*pn).val = val
+		return false
+	}
+        *pn = &node[K, V]{key: key, val: val}
+	return true
+}
+
+// Find returns the value associated with a key, or zero if not present.
+// The found result reports whether the key was found.
+func (m *Map[K, V]) Find(key K) (V, bool) {
+	pn := m.find(key)
+	if *pn == nil {
+		var zero V // see the discussion of zero values, above
+		return zero, false
+	}
+	return (*pn).val, true
+}
+
+// keyValue is a pair of key and value used when iterating.
+type keyValue[K, V any] struct {
+	key K
+	val V
+}
+
+// InOrder returns an iterator that does an in-order traversal of the map.
+func (m *Map[K, V]) InOrder() *Iterator[K, V] {
+	sender, receiver := chans.Ranger[keyValue[K, V]]()
+	var f func(*node[K, V]) bool
+	f = func(n *node[K, V]) bool {
+		if n == nil {
+			return true
+		}
+		// Stop sending values if sender.Send returns false,
+		// meaning that nothing is listening at the receiver end.
+		return f(n.left) &&
+                        sender.Send(keyValue[K, V]{n.key, n.val}) &&
+			f(n.right)
+	}
+	go func() {
+		f(m.root)
+		sender.Close()
+	}()
+	return &Iterator[K, V]{receiver}
+}
+
+// Iterator is used to iterate over the map.
+type Iterator[K, V any] struct {
+	r *chans.Receiver[keyValue[K, V]]
+}
+
+// Next returns the next key and value pair, and a boolean indicating
+// whether they are valid or whether we have reached the end.
+func (it *Iterator[K, V]) Next() (K, V, bool) {
+	keyval, ok := it.r.Next()
+	if !ok {
+		var zerok K
+		var zerov V
+		return zerok, zerov, false
+	}
+	return keyval.key, keyval.val, true
+}
diff --git a/src/cmd/compile/internal/syntax/testdata/go2/map2.go2 b/src/cmd/compile/internal/syntax/testdata/go2/map2.go2
new file mode 100644
index 0000000..2833445
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/go2/map2.go2
@@ -0,0 +1,146 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is like map.go2, but instead if importing chans, it contains
+// the necessary functionality at the end of the file.
+
+// Package orderedmap provides an ordered map, implemented as a binary tree.
+package orderedmap
+
+// Map is an ordered map.
+type Map[K, V any] struct {
+	root    *node[K, V]
+	compare func(K, K) int
+}
+
+// node is the type of a node in the binary tree.
+type node[K, V any] struct {
+	key         K
+	val         V
+	left, right *node[K, V]
+}
+
+// New returns a new map.
+func New[K, V any](compare func(K, K) int) *Map[K, V] {
+        return &Map[K, V]{compare: compare}
+}
+
+// find looks up key in the map, and returns either a pointer
+// to the node holding key, or a pointer to the location where
+// such a node would go.
+func (m *Map[K, V]) find(key K) **node[K, V] {
+	pn := &m.root
+	for *pn != nil {
+		switch cmp := m.compare(key, (*pn).key); {
+		case cmp < 0:
+			pn = &(*pn).left
+		case cmp > 0:
+			pn = &(*pn).right
+		default:
+			return pn
+		}
+	}
+	return pn
+}
+
+// Insert inserts a new key/value into the map.
+// If the key is already present, the value is replaced.
+// Returns true if this is a new key, false if already present.
+func (m *Map[K, V]) Insert(key K, val V) bool {
+	pn := m.find(key)
+	if *pn != nil {
+		(*pn).val = val
+		return false
+	}
+	*pn = &node[K, V]{key: key, val: val}
+	return true
+}
+
+// Find returns the value associated with a key, or zero if not present.
+// The found result reports whether the key was found.
+func (m *Map[K, V]) Find(key K) (V, bool) {
+	pn := m.find(key)
+	if *pn == nil {
+		var zero V // see the discussion of zero values, above
+		return zero, false
+	}
+	return (*pn).val, true
+}
+
+// keyValue is a pair of key and value used when iterating.
+type keyValue[K, V any] struct {
+	key K
+	val V
+}
+
+// InOrder returns an iterator that does an in-order traversal of the map.
+func (m *Map[K, V]) InOrder() *Iterator[K, V] {
+	sender, receiver := chans_Ranger[keyValue[K, V]]()
+	var f func(*node[K, V]) bool
+	f = func(n *node[K, V]) bool {
+		if n == nil {
+			return true
+		}
+		// Stop sending values if sender.Send returns false,
+		// meaning that nothing is listening at the receiver end.
+		return f(n.left) &&
+                        sender.Send(keyValue[K, V]{n.key, n.val}) &&
+			f(n.right)
+	}
+	go func() {
+		f(m.root)
+		sender.Close()
+	}()
+	return &Iterator[K, V]{receiver}
+}
+
+// Iterator is used to iterate over the map.
+type Iterator[K, V any] struct {
+	r *chans_Receiver[keyValue[K, V]]
+}
+
+// Next returns the next key and value pair, and a boolean indicating
+// whether they are valid or whether we have reached the end.
+func (it *Iterator[K, V]) Next() (K, V, bool) {
+	keyval, ok := it.r.Next()
+	if !ok {
+		var zerok K
+		var zerov V
+		return zerok, zerov, false
+	}
+	return keyval.key, keyval.val, true
+}
+
+// chans
+
+func chans_Ranger[T any]() (*chans_Sender[T], *chans_Receiver[T])
+
+// A sender is used to send values to a Receiver.
+type chans_Sender[T any] struct {
+	values chan<- T
+	done <-chan bool
+}
+
+func (s *chans_Sender[T]) Send(v T) bool {
+	select {
+	case s.values <- v:
+		return true
+	case <-s.done:
+		return false
+	}
+}
+
+func (s *chans_Sender[T]) Close() {
+	close(s.values)
+}
+
+type chans_Receiver[T any] struct {
+	values <-chan T
+	done chan<- bool
+}
+
+func (r *chans_Receiver[T]) Next() (T, bool) {
+	v, ok := <-r.values
+	return v, ok
+}
\ No newline at end of file
diff --git a/src/cmd/compile/internal/syntax/testdata/go2/slices.go2 b/src/cmd/compile/internal/syntax/testdata/go2/slices.go2
new file mode 100644
index 0000000..2bacd1c
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/go2/slices.go2
@@ -0,0 +1,68 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package slices implements various slice algorithms.
+package slices
+
+// Map turns a []T1 to a []T2 using a mapping function.
+func Map[T1, T2 any](s []T1, f func(T1) T2) []T2 {
+	r := make([]T2, len(s))
+	for i, v := range s {
+		r[i] = f(v)
+	}
+	return r
+}
+
+// Reduce reduces a []T1 to a single value using a reduction function.
+func Reduce[T1, T2 any](s []T1, initializer T2, f func(T2, T1) T2) T2 {
+	r := initializer
+	for _, v := range s {
+		r = f(r, v)
+	}
+	return r
+}
+
+// Filter filters values from a slice using a filter function.
+func Filter[T any](s []T, f func(T) bool) []T {
+	var r []T
+	for _, v := range s {
+		if f(v) {
+			r = append(r, v)
+		}
+	}
+	return r
+}
+
+// Example uses
+
+func limiter(x int) byte {
+	switch {
+	case x < 0:
+		return 0
+	default:
+		return byte(x)
+	case x > 255:
+		return 255
+	}
+}
+
+var input = []int{-4, 68954, 7, 44, 0, -555, 6945}
+var limited1 = Map[int, byte](input, limiter)
+var limited2 = Map(input, limiter) // using type inference
+
+func reducer(x float64, y int) float64 {
+	return x + float64(y)
+}
+
+var reduced1 = Reduce[int, float64](input, 0, reducer)
+var reduced2 = Reduce(input, 1i /* ERROR overflows */, reducer) // using type inference
+var reduced3 = Reduce(input, 1, reducer) // using type inference
+
+func filter(x int) bool {
+	return x&1 != 0
+}
+
+var filtered1 = Filter[int](input, filter)
+var filtered2 = Filter(input, filter) // using type inference
+
diff --git a/src/cmd/compile/internal/syntax/testdata/go2/smoketest.go2 b/src/cmd/compile/internal/syntax/testdata/go2/smoketest.go2
new file mode 100644
index 0000000..e5cfba0
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/go2/smoketest.go2
@@ -0,0 +1,83 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains basic generic code snippets.
+
+package p
+
+// type parameter lists
+type B[P any] struct{}
+type _[P interface{}] struct{}
+type _[P B] struct{}
+type _[P B[P]] struct{}
+
+type _[A, B, C any] struct{}
+type _[A, B, C B] struct{}
+type _[A, B, C B[A, B, C]] struct{}
+type _[A1, A2 B1, A3 B2, A4, A5, A6 B3] struct{}
+
+type _[A interface{}] struct{}
+type _[A, B interface{ m() }] struct{}
+
+type _[A, B, C any] struct{}
+
+// in functions
+func _[P any]()
+func _[P interface{}]()
+func _[P B]()
+func _[P B[P]]()
+
+// in methods
+func (T) _[P any]()
+func (T) _[P interface{}]()
+func (T) _[P B]()
+func (T) _[P B[P]]()
+
+// type instantiations
+type _ T[int]
+
+// in expressions
+var _ = T[int]{}
+
+// in embedded types
+type _ struct{ T[int] }
+
+// interfaces
+type _ interface{
+	m()
+	type int
+}
+
+type _ interface{
+	type int, float, string
+	type complex128
+	underlying(underlying underlying) underlying
+}
+
+type _ interface{
+	T
+	T[int]
+}
+
+// tricky cases
+func _(T[P], T[P1, P2])
+func _(a [N]T)
+
+type _ struct{
+	T[P]
+	T[P1, P2]
+	f [N]
+}
+type _ interface{
+	m()
+
+	// generic methods - disabled for now
+	// m[] /* ERROR empty type parameter list */ ()
+	// m[ /* ERROR cannot have type parameters */ P any](P)
+
+	// instantiated types
+	// T[] /* ERROR empty type argument list */ 
+	T[P]
+	T[P1, P2]
+}
diff --git a/src/cmd/compile/internal/syntax/testdata/go2/typeinst.go2 b/src/cmd/compile/internal/syntax/testdata/go2/typeinst.go2
new file mode 100644
index 0000000..a422d5e
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/go2/typeinst.go2
@@ -0,0 +1,60 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type myInt int
+
+// Parameterized type declarations
+
+type T1[P any] P
+
+type T2[P any] struct {
+        f P
+        g int // int should still be in scope chain
+}
+
+type List[P any] []P
+
+// Alias type declarations cannot have type parameters. Syntax error.
+// TODO(gri) Disabled for now as we don't check syntax error here.
+// type A1[P any] = /* ERROR cannot be alias */ P
+
+// But an alias may refer to a generic, uninstantiated type.
+type A2 = List
+var _ A2[int]
+var _ A2 /* ERROR without instantiation */
+
+type A3 = List[int]
+var _ A3
+
+// Parameterized type instantiations
+
+var x int
+type _ x /* ERROR not a type */ [int]
+
+type _ int /* ERROR not a generic type */ [int]
+type _ myInt /* ERROR not a generic type */ [int]
+
+// TODO(gri) better error messages
+type _ T1[int]
+type _ T1[x /* ERROR not a type */ ]
+type _ T1 /* ERROR got 2 arguments but 1 type parameters */ [int, float32]
+
+var _ T2[int] = T2[int]{}
+
+var _ List[int] = []int{1, 2, 3}
+var _ List[[]int] = [][]int{{1, 2, 3}}
+var _ List[List[List[int]]]
+
+// Parameterized types containing parameterized types
+
+type T3[P any] List[P]
+
+var _ T3[int] = T3[int](List[int]{1, 2, 3})
+
+// Self-recursive generic types are not permitted
+
+type self1[P any] self1 /* ERROR illegal cycle */ [P]
+type self2[P any] *self2[P] // this is ok
diff --git a/src/cmd/compile/internal/syntax/testdata/go2/typeinst2.go2 b/src/cmd/compile/internal/syntax/testdata/go2/typeinst2.go2
new file mode 100644
index 0000000..6e2104a
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/go2/typeinst2.go2
@@ -0,0 +1,256 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type List[E any] []E
+var _ List[List[List[int]]]
+var _ List[List[List[int]]] = []List[List[int]]{}
+
+type (
+	T1[P1 any] struct {
+		f1 T2[P1, float32]
+	}
+
+	T2[P2, P3 any] struct {
+		f2 P2
+		f3 P3
+	}
+)
+
+func _() {
+	var x1 T1[int]
+	var x2 T2[int, float32]
+
+	x1.f1.f2 = 0
+	x1.f1 = x2
+}
+
+type T3[P any] T1[T2[P, P]]
+
+func _() {
+	var x1 T3[int]
+	var x2 T2[int, int]
+	x1.f1.f2 = x2
+}
+
+func f[P any] (x P) List[P] {
+	return List[P]{x}
+}
+
+var (
+	_ []int = f(0)
+	_ []float32 = f[float32](10)
+	_ List[complex128] = f(1i)
+	_ []List[int] = f(List[int]{})
+        _ List[List[int]] = []List[int]{}
+        _ = []List[int]{}
+)
+
+// Parameterized types with methods
+
+func (l List[E]) Head() (_ E, _ bool) {
+	if len(l) > 0 {
+		return l[0], true
+	}
+	return
+}
+
+// A test case for instantiating types with other types (extracted from map.go2)
+
+type Pair[K any] struct {
+	key K
+}
+
+type Receiver[T any] struct {
+	values T
+}
+
+type Iterator[K any] struct {
+	r Receiver[Pair[K]]
+}
+
+func Values [T any] (r Receiver[T]) T {
+        return r.values
+}
+
+func (it Iterator[K]) Next() K {
+        return Values[Pair[K]](it.r).key
+}
+
+// A more complex test case testing type bounds (extracted from linalg.go2 and reduced to essence)
+
+type NumericAbs[T any] interface {
+	Abs() T
+}
+
+func AbsDifference[T NumericAbs[T]](x T)
+
+type OrderedAbs[T any] T
+
+func (a OrderedAbs[T]) Abs() OrderedAbs[T]
+
+func OrderedAbsDifference[T any](x T) {
+	AbsDifference(OrderedAbs[T](x))
+}
+
+// same code, reduced to essence
+
+func g[P interface{ m() P }](x P)
+
+type T4[P any] P
+
+func (_ T4[P]) m() T4[P]
+
+func _[Q any](x Q) {
+	g(T4[Q](x))
+}
+
+// Another test case that caused  problems in the past
+
+type T5[_ interface { a() }, _ interface{}] struct{}
+
+type A[P any] struct{ x P }
+
+func (_ A[P]) a() {}
+
+var _ T5[A[int], int]
+
+// Invoking methods with parameterized receiver types uses
+// type inference to determine the actual type arguments matching
+// the receiver type parameters from the actual receiver argument.
+// Go does implicit address-taking and dereferenciation depending
+// on the actual receiver and the method's receiver type. To make
+// type inference work, the type-checker matches "pointer-ness"
+// of the actual receiver and the method's receiver type.
+// The following code tests this mechanism.
+
+type R1[A any] struct{}
+func (_ R1[A]) vm()
+func (_ *R1[A]) pm()
+
+func _[T any](r R1[T], p *R1[T]) {
+	r.vm()
+	r.pm()
+	p.vm()
+	p.pm()
+}
+
+type R2[A, B any] struct{}
+func (_ R2[A, B]) vm()
+func (_ *R2[A, B]) pm()
+
+func _[T any](r R2[T, int], p *R2[string, T]) {
+	r.vm()
+	r.pm()
+	p.vm()
+	p.pm()
+}
+
+// An interface can (explicitly) declare at most one type list.
+type _ interface {
+	m0()
+	type int, string, bool
+	type /* ERROR multiple type lists */ float32, float64
+	m1()
+	m2()
+	type /* ERROR multiple type lists */ complex64, complex128
+	type /* ERROR multiple type lists */ rune
+}
+
+// Interface type lists may contain each type at most once.
+// (If there are multiple lists, we assume the author intended
+// for them to be all in a single list, and we report the error
+// as well.)
+type _ interface {
+	type int, int /* ERROR duplicate type int */
+	type /* ERROR multiple type lists */ int /* ERROR duplicate type int */
+}
+
+type _ interface {
+	type struct{f int}, struct{g int}, struct /* ERROR duplicate type */ {f int}
+}
+
+// Interface type lists can contain any type, incl. *Named types.
+// Verify that we use the underlying type to compute the operational type.
+type MyInt int
+func add1[T interface{type MyInt}](x T) T {
+	return x + 1
+}
+
+type MyString string
+func double[T interface{type MyInt, MyString}](x T) T {
+	return x + x
+}
+
+// Embedding of interfaces with type lists leads to interfaces
+// with type lists that are the intersection of the embedded
+// type lists.
+
+type E0 interface {
+	type int, bool, string
+}
+
+type E1 interface {
+	type int, float64, string
+}
+
+type E2 interface {
+	type float64
+}
+
+type I0 interface {
+	E0
+}
+
+func f0[T I0]()
+var _ = f0[int]
+var _ = f0[bool]
+var _ = f0[string]
+var _ = f0[float64 /* ERROR does not satisfy I0 */ ]
+
+type I01 interface {
+	E0
+	E1
+}
+
+func f01[T I01]()
+var _ = f01[int]
+var _ = f01[bool /* ERROR does not satisfy I0 */ ]
+var _ = f01[string]
+var _ = f01[float64 /* ERROR does not satisfy I0 */ ]
+
+type I012 interface {
+	E0
+	E1
+	E2
+}
+
+func f012[T I012]()
+var _ = f012[int /* ERROR does not satisfy I012 */ ]
+var _ = f012[bool /* ERROR does not satisfy I012 */ ]
+var _ = f012[string /* ERROR does not satisfy I012 */ ]
+var _ = f012[float64 /* ERROR does not satisfy I012 */ ]
+
+type I12 interface {
+	E1
+	E2
+}
+
+func f12[T I12]()
+var _ = f12[int /* ERROR does not satisfy I12 */ ]
+var _ = f12[bool /* ERROR does not satisfy I12 */ ]
+var _ = f12[string /* ERROR does not satisfy I12 */ ]
+var _ = f12[float64]
+
+type I0_ interface {
+	E0
+	type int
+}
+
+func f0_[T I0_]()
+var _ = f0_[int]
+var _ = f0_[bool /* ERROR does not satisfy I0_ */ ]
+var _ = f0_[string /* ERROR does not satisfy I0_ */ ]
+var _ = f0_[float64 /* ERROR does not satisfy I0_ */ ]
diff --git a/src/cmd/compile/internal/syntax/testdata/go2/typeparams.go2 b/src/cmd/compile/internal/syntax/testdata/go2/typeparams.go2
new file mode 100644
index 0000000..f78037f
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/go2/typeparams.go2
@@ -0,0 +1,451 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// import "io" // for type assertion tests
+
+// The predeclared identifier "any" is only visible as a constraint
+// in a type parameter list.
+var _ any // ERROR undeclared
+func _[_ any /* ok here */ , _ interface{any /* ERROR undeclared */ }](any /* ERROR undeclared */ ) {
+        var _ any /* ERROR undeclared */
+}
+
+func identity[T any](x T) T { return x }
+
+func _[_ any](x int) int
+func _[T any](T /* ERROR redeclared */ T)()
+func _[T, T /* ERROR redeclared */ any]()
+
+func reverse[T any](list []T) []T {
+        rlist := make([]T, len(list))
+        i := len(list)
+        for _, x := range list {
+                i--
+                rlist[i] = x
+        }
+        return rlist
+}
+
+var _ = reverse /* ERROR cannot use generic function reverse */
+var _ = reverse[int, float32 /* ERROR got 2 type arguments */ ] ([]int{1, 2, 3})
+var _ = reverse[int]([ /* ERROR cannot use */ ]float32{1, 2, 3})
+var f = reverse[chan int]
+var _ = f(0 /* ERROR cannot convert 0 .* to \[\]chan int */ )
+
+func swap[A, B any](a A, b B) (B, A) { return b, a }
+
+var _ = swap /* ERROR single value is expected */ [int, float32](1, 2)
+var f32, i = swap[int, float32](swap(float32, int)(1, 2))
+var _ float32 = f32
+var _ int = i
+
+func swapswap[A, B any](a A, b B) (A, B) {
+        return swap[B, A](b, a)
+}
+
+type F[A, B any] func(A, B) (B, A)
+
+func min[T interface{ type int }](x, y T) T {
+        if x < y {
+                return x
+        }
+        return y
+}
+
+func _[T interface{type int, float32}](x, y T) bool { return x < y }
+func _[T any](x, y T) bool { return x /* ERROR cannot compare */ < y }
+func _[T interface{type int, float32, bool}](x, y T) bool { return x /* ERROR cannot compare */ < y }
+
+func _[T C1[T]](x, y T) bool { return x /* ERROR cannot compare */ < y }
+func _[T C2[T]](x, y T) bool { return x < y }
+
+type C1[T any] interface{}
+type C2[T any] interface{ type int, float32 }
+
+func new[T any]() *T {
+        var x T
+        return &x
+}
+
+var _ = new /* ERROR cannot use generic function new */
+var _ *int = new[int]()
+
+func _[T any](map[T /* ERROR invalid map key type T \(missing comparable constraint\) */]int) // w/o constraint we don't know if T is comparable
+
+func f1[T1 any](struct{T1}) int
+var _ = f1(int)(struct{T1}{})
+type T1 = int
+
+func f2[t1 any](struct{t1; x float32}) int
+var _ = f2(t1)(struct{t1; x float32}{})
+type t1 = int
+
+
+func f3[A, B, C any](A, struct{x B}, func(A, struct{x B}, *C)) int
+
+var _ = f3[int, rune, bool](1, struct{x rune}{}, nil)
+
+// indexing
+
+func _[T any] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+func _[T interface{ type int }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+func _[T interface{ type string }] (x T, i int) { _ = x[i] }
+func _[T interface{ type []int }] (x T, i int) { _ = x[i] }
+func _[T interface{ type [10]int, *[20]int, map[string]int }] (x T, i int) { _ = x[i] }
+func _[T interface{ type string, []byte }] (x T, i int) { _ = x[i] }
+func _[T interface{ type []int, [1]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+func _[T interface{ type string, []rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+
+// slicing
+// TODO(gri) implement this
+
+func _[T interface{ type string }] (x T, i, j, k int) { _ = x /* ERROR invalid operation */ [i:j:k] }
+
+// len/cap built-ins
+
+func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) }
+func _[T interface{ type int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
+func _[T interface{ type string, []byte, int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
+func _[T interface{ type string }](x T) { _ = len(x) }
+func _[T interface{ type [10]int }](x T) { _ = len(x) }
+func _[T interface{ type []byte }](x T) { _ = len(x) }
+func _[T interface{ type map[int]int }](x T) { _ = len(x) }
+func _[T interface{ type chan int }](x T) { _ = len(x) }
+func _[T interface{ type string, []byte, chan int }](x T) { _ = len(x) }
+
+func _[T any](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type string, []byte, int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type string }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type [10]int }](x T) { _ = cap(x) }
+func _[T interface{ type []byte }](x T) { _ = cap(x) }
+func _[T interface{ type map[int]int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type chan int }](x T) { _ = cap(x) }
+func _[T interface{ type []byte, chan int }](x T) { _ = cap(x) }
+
+// range iteration
+
+func _[T interface{}](x T) {
+        for range x /* ERROR cannot range */ {}
+}
+
+func _[T interface{ type string, []string }](x T) {
+        for range x {}
+        for i := range x { _ = i }
+        for i, _ := range x { _ = i }
+        for i, e := range x /* ERROR must have the same element type */ { _ = i }
+        for _, e := range x /* ERROR must have the same element type */ {}
+        var e rune
+        _ = e
+        for _, (e) = range x /* ERROR must have the same element type */ {}
+}
+
+
+func _[T interface{ type string, []rune, map[int]rune }](x T) {
+        for _, e := range x { _ = e }
+        for i, e := range x { _ = i; _ = e }
+}
+
+func _[T interface{ type string, []rune, map[string]rune }](x T) {
+        for _, e := range x { _ = e }
+        for i, e := range x /* ERROR must have the same key type */ { _ = e }
+}
+
+func _[T interface{ type string, chan int }](x T) {
+        for range x {}
+        for i := range x { _ = i }
+        for i, _ := range x { _ = i } // TODO(gri) should get an error here: channels only return one value
+}
+
+func _[T interface{ type string, chan<-int }](x T) {
+        for i := range x /* ERROR send-only channel */ { _ = i }
+}
+
+// type inference checks
+
+var _ = new() /* ERROR cannot infer T */
+
+func f4[A, B, C any](A, B) C
+
+var _ = f4(1, 2) /* ERROR cannot infer C */
+var _ = f4[int, float32, complex128](1, 2)
+
+func f5[A, B, C any](A, []*B, struct{f []C}) int
+
+var _ = f5[int, float32, complex128](0, nil, struct{f []complex128}{})
+var _ = f5(0, nil, struct{f []complex128}{}) // ERROR cannot infer
+var _ = f5(0, []*float32{new[float32]()}, struct{f []complex128}{})
+
+func f6[A any](A, []A) int
+
+var _ = f6(0, nil)
+
+func f6nil[A any](A) int
+
+var _ = f6nil(nil) // ERROR cannot infer
+
+// type inference with variadic functions
+
+func f7[T any](...T) T
+
+var _ int = f7() /* ERROR cannot infer T */
+var _ int = f7(1)
+var _ int = f7(1, 2)
+var _ int = f7([]int{}...)
+var _ int = f7 /* ERROR cannot use */ ([]float64{}...)
+var _ float64 = f7([]float64{}...)
+var _ = f7[float64](1, 2.3)
+var _ = f7(float64(1), 2.3)
+var _ = f7(1, 2.3 /* ERROR does not match */ )
+var _ = f7(1.2, 3 /* ERROR does not match */ )
+
+func f8[A, B any](A, B, ...B) int
+
+var _ = f8(1) /* ERROR not enough arguments */
+var _ = f8(1, 2.3)
+var _ = f8(1, 2.3, 3.4, 4.5)
+var _ = f8(1, 2.3, 3.4, 4 /* ERROR does not match */ )
+var _ = f8(int, float64)(1, 2.3, 3.4, 4)
+
+var _ = f8(int, float64)(0, 0, nil...) // test case for #18268
+
+// init functions cannot have type parameters
+
+func init() {}
+func init[/* ERROR func init must have no type parameters */ _ any]() {}
+func init[/* ERROR func init must have no type parameters */ P any]() {}
+
+type T struct {}
+
+func (T) m1() {}
+// The type checker accepts method type parameters if configured accordingly.
+func (T) m2[_ any]() {}
+func (T) m3[P any]() {}
+
+// type inference across parameterized types
+
+type S1[P any] struct { f P }
+
+func f9[P any](x S1[P])
+
+func _() {
+        f9[int](S1[int]{42})
+	f9(S1[int]{42})
+}
+
+type S2[A, B, C any] struct{}
+
+func f10[X, Y, Z any](a S2[X, int, Z], b S2[X, Y, bool])
+
+func _[P any]() {
+        f10[int, float32, string](S2[int, int, string]{}, S2[int, float32, bool]{})
+        f10(S2[int, int, string]{}, S2[int, float32, bool]{})
+        f10(S2[P, int, P]{}, S2[P, float32, bool]{})
+}
+
+// corner case for type inference
+// (was bug: after instanting f11, the type-checker didn't mark f11 as non-generic)
+
+func f11[T any]()
+
+func _() {
+	f11[int]()
+}
+
+// the previous example was extracted from
+
+func f12[T interface{m() T}]()
+
+type A[T any] T
+
+func (a A[T]) m() A[T]
+
+func _[T any]() {
+	f12(A[T])()
+}
+
+// method expressions
+
+func (_ S1[P]) m()
+
+func _() {
+	m := S1[int].m
+	m(struct { f int }{42})
+}
+
+func _[T any] (x T) {
+        m := S1[T].m
+        m(S1[T]{x})
+}
+
+// type parameters in methods (generalization)
+
+type R0 struct{}
+
+func (R0) _[T any](x T)
+func (R0 /* ERROR invalid receiver */ ) _[R0 any]() // scope of type parameters starts at "func"
+
+type R1[A, B any] struct{}
+
+func (_ R1[A, B]) m0(A, B)
+func (_ R1[A, B]) m1[T any](A, B, T) T
+func (_ R1 /* ERROR not a generic type */ [R1, _]) _()
+func (_ R1[A, B]) _[A /* ERROR redeclared */ any](B)
+
+func _() {
+        var r R1[int, string]
+        r.m1[rune](42, "foo", 'a')
+        r.m1[rune](42, "foo", 1.2 /* ERROR truncated to rune */)
+        r.m1(42, "foo", 1.2) // using type inference
+        var _ float64 = r.m1(42, "foo", 1.2)
+}
+
+type I1[A any] interface {
+        m1(A)
+}
+
+var _ I1[int] = r1[int]{}
+
+type r1[T any] struct{}
+
+func (_ r1[T]) m1(T)
+
+type I2[A, B any] interface {
+        m1(A)
+        m2(A) B
+}
+
+var _ I2[int, float32] = R2[int, float32]{}
+
+type R2[P, Q any] struct{}
+
+func (_ R2[X, Y]) m1(X)
+func (_ R2[X, Y]) m2(X) Y
+
+// type assertions and type switches over generic types
+// NOTE: These are currently disabled because it's unclear what the correct
+// approach is, and one can always work around by assigning the variable to
+// an interface first.
+
+// // ReadByte1 corresponds to the ReadByte example in the draft design.
+// func ReadByte1[T io.Reader](r T) (byte, error) {
+// 	if br, ok := r.(io.ByteReader); ok {
+// 		return br.ReadByte()
+// 	}
+// 	var b [1]byte
+// 	_, err := r.Read(b[:])
+// 	return b[0], err
+// }
+//
+// // ReadBytes2 is like ReadByte1 but uses a type switch instead.
+// func ReadByte2[T io.Reader](r T) (byte, error) {
+//         switch br := r.(type) {
+//         case io.ByteReader:
+//                 return br.ReadByte()
+//         }
+// 	var b [1]byte
+// 	_, err := r.Read(b[:])
+// 	return b[0], err
+// }
+//
+// // type assertions and type switches over generic types are strict
+// type I3 interface {
+//         m(int)
+// }
+//
+// type I4 interface {
+//         m() int // different signature from I3.m
+// }
+//
+// func _[T I3](x I3, p T) {
+//         // type assertions and type switches over interfaces are not strict
+//         _ = x.(I4)
+//         switch x.(type) {
+//         case I4:
+//         }
+// 
+//         // type assertions and type switches over generic types are strict
+//         _ = p /* ERROR cannot have dynamic type I4 */.(I4)
+//         switch p.(type) {
+//         case I4 /* ERROR cannot have dynamic type I4 */ :
+//         }
+// }
+
+// type assertions and type switches over generic types lead to errors for now
+
+func _[T any](x T) {
+	_ = x /* ERROR not an interface */ .(int)
+	switch x /* ERROR not an interface */ .(type) {
+	}
+
+	// work-around
+	var t interface{} = x
+	_ = t.(int)
+	switch t.(type) {
+	}
+}
+
+func _[T interface{type int}](x T) {
+	_ = x /* ERROR not an interface */ .(int)
+	switch x /* ERROR not an interface */ .(type) {
+	}
+
+	// work-around
+	var t interface{} = x
+	_ = t.(int)
+	switch t.(type) {
+	}
+}
+
+// error messages related to type bounds mention those bounds
+type C[P any] interface{}
+
+func _[P C[P]] (x P) {
+	x.m /* ERROR x.m undefined */ ()
+}
+
+type I interface {}
+
+func _[P I] (x P) {
+	x.m /* ERROR interface I has no method m */ ()
+}
+
+func _[P interface{}] (x P) {
+	x.m /* ERROR type bound for P has no method m */ ()
+}
+
+func _[P any] (x P) {
+	x.m /* ERROR type bound for P has no method m */ ()
+}
+
+// automatic distinguishing between array and generic types
+// NOTE: Disabled when using unified parameter list syntax.
+/*
+const P = 10
+type A1 [P]byte
+func _(a A1) {
+        assert(len(a) == 10)
+}
+
+type A2 [P]struct{
+        f [P]byte
+}
+func _(a A2) {
+        assert(len(a) == 10)
+        assert(len(a[0].f) == 10)
+}
+
+type A3 [P]func(x [P]A3)
+func _(a A3) {
+        assert(len(a) == 10)
+}
+
+type T2[P] struct{ P }
+var _ T2[int]
+
+type T3[P] func(P)
+var _ T3[int]
+*/
\ No newline at end of file
diff --git a/src/cmd/compile/internal/syntax/testdata/interface.go2 b/src/cmd/compile/internal/syntax/testdata/interface.go2
new file mode 100644
index 0000000..a817327
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/interface.go2
@@ -0,0 +1,36 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains test cases for interfaces containing
+// constraint elements.
+//
+// For now, we accept both ordinary type lists and the
+// more complex constraint elements.
+
+package p
+
+type _ interface {
+	m()
+	type int
+	type int, string
+	E
+}
+
+type _ interface {
+	m()
+	~int
+	int | string
+	int | ~string
+	~int | ~string
+}
+
+
+type _ interface {
+	m()
+	~int
+	T[int, string] | string
+	int | ~T[string, struct{}]
+	~int | ~string
+	type bool, int, float64
+}
diff --git a/src/cmd/compile/internal/syntax/testdata/issue43674.src b/src/cmd/compile/internal/syntax/testdata/issue43674.src
new file mode 100644
index 0000000..51c692a
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/issue43674.src
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _(... /* ERROR [.][.][.] is missing type */ )
+func _(... /* ERROR [.][.][.] is missing type */ , int)
+
+func _(a, b ... /* ERROR [.][.][.] is missing type */ )
+func _(a, b ... /* ERROR [.][.][.] is missing type */ , x int)
+
+func _()(... /* ERROR [.][.][.] is missing type */ )
diff --git a/src/cmd/compile/internal/syntax/testdata/tparams.go2 b/src/cmd/compile/internal/syntax/testdata/tparams.go2
new file mode 100644
index 0000000..42031c3
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/tparams.go2
@@ -0,0 +1,22 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type t[ /* ERROR type parameters must be named */ a, b] struct{}
+type t[a t, b t, /* ERROR type parameters must be named */ c] struct{}
+type t struct {
+	t [n]byte
+	t[a]
+	t[a, b]
+}
+type t interface {
+	t[a]
+	m /* ERROR method cannot have type parameters */ [_ _, /* ERROR mixed */ _]()
+	t[a, b]
+}
+
+func f[ /* ERROR empty type parameter list */ ]()
+func f[ /* ERROR type parameters must be named */ a, b]()
+func f[a t, b t, /* ERROR type parameters must be named */ c]()
diff --git a/src/cmd/compile/internal/syntax/testing.go b/src/cmd/compile/internal/syntax/testing.go
new file mode 100644
index 0000000..6a97dc0
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testing.go
@@ -0,0 +1,72 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements testing support.
+
+package syntax
+
+import (
+	"io"
+	"regexp"
+	"strings"
+)
+
+// CommentsDo parses the given source and calls the provided handler for each
+// comment or error. If the text provided to handler starts with a '/' it is
+// the comment text; otherwise it is the error message.
+func CommentsDo(src io.Reader, handler func(line, col uint, text string)) {
+	var s scanner
+	s.init(src, handler, comments)
+	for s.tok != _EOF {
+		s.next()
+	}
+}
+
+// ERROR comments must start with text `ERROR "msg"` or `ERROR msg`.
+// Space around "msg" or msg is ignored.
+var errRx = regexp.MustCompile(`^ *ERROR *"?([^"]*)"?`)
+
+// ErrorMap collects all comments with comment text of the form
+// `ERROR "msg"` or `ERROR msg` from the given src and returns them
+// as []Error lists in a map indexed by line number. The position
+// for each Error is the position of the token immediately preceding
+// the comment, the Error message is the message msg extracted from
+// the comment, with all errors that are on the same line collected
+// in a slice, in source order. If there is no preceding token (the
+// `ERROR` comment appears in the beginning of the file), then the
+// recorded position is unknown (line, col = 0, 0). If there are no
+// ERROR comments, the result is nil.
+func ErrorMap(src io.Reader) (errmap map[uint][]Error) {
+	// position of previous token
+	var base *PosBase
+	var prev struct{ line, col uint }
+
+	var s scanner
+	s.init(src, func(_, _ uint, text string) {
+		if text[0] != '/' {
+			return // error, ignore
+		}
+		if text[1] == '*' {
+			text = text[:len(text)-2] // strip trailing */
+		}
+		if s := errRx.FindStringSubmatch(text[2:]); len(s) == 2 {
+			pos := MakePos(base, prev.line, prev.col)
+			err := Error{pos, strings.TrimSpace(s[1])}
+			if errmap == nil {
+				errmap = make(map[uint][]Error)
+			}
+			errmap[prev.line] = append(errmap[prev.line], err)
+		}
+	}, comments)
+
+	for s.tok != _EOF {
+		s.next()
+		if s.tok == _Semi && s.lit != "semicolon" {
+			continue // ignore automatically inserted semicolons
+		}
+		prev.line, prev.col = s.line, s.col
+	}
+
+	return
+}
diff --git a/src/cmd/compile/internal/syntax/testing_test.go b/src/cmd/compile/internal/syntax/testing_test.go
new file mode 100644
index 0000000..d34e5ea
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testing_test.go
@@ -0,0 +1,45 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syntax
+
+import (
+	"fmt"
+	"strings"
+	"testing"
+)
+
+func TestErrorMap(t *testing.T) {
+	const src = `/* ERROR 0:0 */ /* ERROR "0:0" */ // ERROR 0:0
+// ERROR "0:0"
+x /* ERROR 3:1 */                // ignore automatically inserted semicolon here
+/* ERROR 3:1 */                  // position of x on previous line
+   x /* ERROR 5:4 */ ;           // do not ignore this semicolon
+/* ERROR 5:22 */                 // position of ; on previous line
+	package /* ERROR 7:2 */  // indented with tab
+        import  /* ERROR 8:9 */  // indented with blanks
+`
+	m := ErrorMap(strings.NewReader(src))
+	got := 0 // number of errors found
+	for line, errlist := range m {
+		for _, err := range errlist {
+			if err.Pos.Line() != line {
+				t.Errorf("%v: got map line %d; want %d", err, err.Pos.Line(), line)
+				continue
+			}
+			// err.Pos.Line() == line
+			msg := fmt.Sprintf("%d:%d", line, err.Pos.Col())
+			if err.Msg != msg {
+				t.Errorf("%v: got msg %q; want %q", err, err.Msg, msg)
+				continue
+			}
+		}
+		got += len(errlist)
+	}
+
+	want := strings.Count(src, "ERROR")
+	if got != want {
+		t.Errorf("ErrorMap got %d errors; want %d", got, want)
+	}
+}
diff --git a/src/cmd/compile/internal/syntax/token_string.go b/src/cmd/compile/internal/syntax/token_string.go
index 3cf5473..ef295eb 100644
--- a/src/cmd/compile/internal/syntax/token_string.go
+++ b/src/cmd/compile/internal/syntax/token_string.go
@@ -1,9 +1,62 @@
-// Code generated by "stringer -type token -linecomment"; DO NOT EDIT.
+// Code generated by "stringer -type token -linecomment tokens.go"; DO NOT EDIT.
 
 package syntax
 
 import "strconv"
 
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[_EOF-1]
+	_ = x[_Name-2]
+	_ = x[_Literal-3]
+	_ = x[_Operator-4]
+	_ = x[_AssignOp-5]
+	_ = x[_IncOp-6]
+	_ = x[_Assign-7]
+	_ = x[_Define-8]
+	_ = x[_Arrow-9]
+	_ = x[_Star-10]
+	_ = x[_Lparen-11]
+	_ = x[_Lbrack-12]
+	_ = x[_Lbrace-13]
+	_ = x[_Rparen-14]
+	_ = x[_Rbrack-15]
+	_ = x[_Rbrace-16]
+	_ = x[_Comma-17]
+	_ = x[_Semi-18]
+	_ = x[_Colon-19]
+	_ = x[_Dot-20]
+	_ = x[_DotDotDot-21]
+	_ = x[_Break-22]
+	_ = x[_Case-23]
+	_ = x[_Chan-24]
+	_ = x[_Const-25]
+	_ = x[_Continue-26]
+	_ = x[_Default-27]
+	_ = x[_Defer-28]
+	_ = x[_Else-29]
+	_ = x[_Fallthrough-30]
+	_ = x[_For-31]
+	_ = x[_Func-32]
+	_ = x[_Go-33]
+	_ = x[_Goto-34]
+	_ = x[_If-35]
+	_ = x[_Import-36]
+	_ = x[_Interface-37]
+	_ = x[_Map-38]
+	_ = x[_Package-39]
+	_ = x[_Range-40]
+	_ = x[_Return-41]
+	_ = x[_Select-42]
+	_ = x[_Struct-43]
+	_ = x[_Switch-44]
+	_ = x[_Type-45]
+	_ = x[_Var-46]
+	_ = x[tokenCount-47]
+}
+
 const _token_name = "EOFnameliteralopop=opop=:=<-*([{)]},;:....breakcasechanconstcontinuedefaultdeferelsefallthroughforfuncgogotoifimportinterfacemappackagerangereturnselectstructswitchtypevar"
 
 var _token_index = [...]uint8{0, 3, 7, 14, 16, 19, 23, 24, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 42, 47, 51, 55, 60, 68, 75, 80, 84, 95, 98, 102, 104, 108, 110, 116, 125, 128, 135, 140, 146, 152, 158, 164, 168, 171, 171}
diff --git a/src/cmd/compile/internal/syntax/tokens.go b/src/cmd/compile/internal/syntax/tokens.go
index 3b97cb6..60eae36 100644
--- a/src/cmd/compile/internal/syntax/tokens.go
+++ b/src/cmd/compile/internal/syntax/tokens.go
@@ -6,7 +6,7 @@
 
 type token uint
 
-//go:generate stringer -type token -linecomment
+//go:generate stringer -type token -linecomment tokens.go
 
 const (
 	_    token = iota
@@ -105,15 +105,16 @@
 
 type Operator uint
 
-//go:generate stringer -type Operator -linecomment
+//go:generate stringer -type Operator -linecomment tokens.go
 
 const (
 	_ Operator = iota
 
 	// Def is the : in :=
-	Def  // :
-	Not  // !
-	Recv // <-
+	Def   // :
+	Not   // !
+	Recv  // <-
+	Tilde // ~
 
 	// precOrOr
 	OrOr // ||
diff --git a/src/cmd/compile/internal/syntax/walk.go b/src/cmd/compile/internal/syntax/walk.go
new file mode 100644
index 0000000..c26e97a
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/walk.go
@@ -0,0 +1,318 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements syntax tree walking.
+
+package syntax
+
+import "fmt"
+
+// Walk traverses a syntax in pre-order: It starts by calling f(root);
+// root must not be nil. If f returns false (== "continue"), Walk calls
+// f recursively for each of the non-nil children of that node; if f
+// returns true (== "stop"), Walk does not traverse the respective node's
+// children.
+// Some nodes may be shared among multiple parent nodes (e.g., types in
+// field lists such as type T in "a, b, c T"). Such shared nodes are
+// walked multiple times.
+// TODO(gri) Revisit this design. It may make sense to walk those nodes
+//           only once. A place where this matters is types2.TestResolveIdents.
+func Walk(root Node, f func(Node) bool) {
+	w := walker{f}
+	w.node(root)
+}
+
+type walker struct {
+	f func(Node) bool
+}
+
+func (w *walker) node(n Node) {
+	if n == nil {
+		panic("invalid syntax tree: nil node")
+	}
+
+	if w.f(n) {
+		return
+	}
+
+	switch n := n.(type) {
+	// packages
+	case *File:
+		w.node(n.PkgName)
+		w.declList(n.DeclList)
+
+	// declarations
+	case *ImportDecl:
+		if n.LocalPkgName != nil {
+			w.node(n.LocalPkgName)
+		}
+		w.node(n.Path)
+
+	case *ConstDecl:
+		w.nameList(n.NameList)
+		if n.Type != nil {
+			w.node(n.Type)
+		}
+		if n.Values != nil {
+			w.node(n.Values)
+		}
+
+	case *TypeDecl:
+		w.node(n.Name)
+		w.fieldList(n.TParamList)
+		w.node(n.Type)
+
+	case *VarDecl:
+		w.nameList(n.NameList)
+		if n.Type != nil {
+			w.node(n.Type)
+		}
+		if n.Values != nil {
+			w.node(n.Values)
+		}
+
+	case *FuncDecl:
+		if n.Recv != nil {
+			w.node(n.Recv)
+		}
+		w.node(n.Name)
+		w.fieldList(n.TParamList)
+		w.node(n.Type)
+		if n.Body != nil {
+			w.node(n.Body)
+		}
+
+	// expressions
+	case *BadExpr: // nothing to do
+	case *Name: // nothing to do
+	case *BasicLit: // nothing to do
+
+	case *CompositeLit:
+		if n.Type != nil {
+			w.node(n.Type)
+		}
+		w.exprList(n.ElemList)
+
+	case *KeyValueExpr:
+		w.node(n.Key)
+		w.node(n.Value)
+
+	case *FuncLit:
+		w.node(n.Type)
+		w.node(n.Body)
+
+	case *ParenExpr:
+		w.node(n.X)
+
+	case *SelectorExpr:
+		w.node(n.X)
+		w.node(n.Sel)
+
+	case *IndexExpr:
+		w.node(n.X)
+		w.node(n.Index)
+
+	case *SliceExpr:
+		w.node(n.X)
+		for _, x := range n.Index {
+			if x != nil {
+				w.node(x)
+			}
+		}
+
+	case *AssertExpr:
+		w.node(n.X)
+		w.node(n.Type)
+
+	case *TypeSwitchGuard:
+		if n.Lhs != nil {
+			w.node(n.Lhs)
+		}
+		w.node(n.X)
+
+	case *Operation:
+		w.node(n.X)
+		if n.Y != nil {
+			w.node(n.Y)
+		}
+
+	case *CallExpr:
+		w.node(n.Fun)
+		w.exprList(n.ArgList)
+
+	case *ListExpr:
+		w.exprList(n.ElemList)
+
+	// types
+	case *ArrayType:
+		if n.Len != nil {
+			w.node(n.Len)
+		}
+		w.node(n.Elem)
+
+	case *SliceType:
+		w.node(n.Elem)
+
+	case *DotsType:
+		w.node(n.Elem)
+
+	case *StructType:
+		w.fieldList(n.FieldList)
+		for _, t := range n.TagList {
+			if t != nil {
+				w.node(t)
+			}
+		}
+
+	case *Field:
+		if n.Name != nil {
+			w.node(n.Name)
+		}
+		w.node(n.Type)
+
+	case *InterfaceType:
+		w.fieldList(n.MethodList)
+
+	case *FuncType:
+		w.fieldList(n.ParamList)
+		w.fieldList(n.ResultList)
+
+	case *MapType:
+		w.node(n.Key)
+		w.node(n.Value)
+
+	case *ChanType:
+		w.node(n.Elem)
+
+	// statements
+	case *EmptyStmt: // nothing to do
+
+	case *LabeledStmt:
+		w.node(n.Label)
+		w.node(n.Stmt)
+
+	case *BlockStmt:
+		w.stmtList(n.List)
+
+	case *ExprStmt:
+		w.node(n.X)
+
+	case *SendStmt:
+		w.node(n.Chan)
+		w.node(n.Value)
+
+	case *DeclStmt:
+		w.declList(n.DeclList)
+
+	case *AssignStmt:
+		w.node(n.Lhs)
+		if n.Rhs != nil {
+			w.node(n.Rhs)
+		}
+
+	case *BranchStmt:
+		if n.Label != nil {
+			w.node(n.Label)
+		}
+		// Target points to nodes elsewhere in the syntax tree
+
+	case *CallStmt:
+		w.node(n.Call)
+
+	case *ReturnStmt:
+		if n.Results != nil {
+			w.node(n.Results)
+		}
+
+	case *IfStmt:
+		if n.Init != nil {
+			w.node(n.Init)
+		}
+		w.node(n.Cond)
+		w.node(n.Then)
+		if n.Else != nil {
+			w.node(n.Else)
+		}
+
+	case *ForStmt:
+		if n.Init != nil {
+			w.node(n.Init)
+		}
+		if n.Cond != nil {
+			w.node(n.Cond)
+		}
+		if n.Post != nil {
+			w.node(n.Post)
+		}
+		w.node(n.Body)
+
+	case *SwitchStmt:
+		if n.Init != nil {
+			w.node(n.Init)
+		}
+		if n.Tag != nil {
+			w.node(n.Tag)
+		}
+		for _, s := range n.Body {
+			w.node(s)
+		}
+
+	case *SelectStmt:
+		for _, s := range n.Body {
+			w.node(s)
+		}
+
+	// helper nodes
+	case *RangeClause:
+		if n.Lhs != nil {
+			w.node(n.Lhs)
+		}
+		w.node(n.X)
+
+	case *CaseClause:
+		if n.Cases != nil {
+			w.node(n.Cases)
+		}
+		w.stmtList(n.Body)
+
+	case *CommClause:
+		if n.Comm != nil {
+			w.node(n.Comm)
+		}
+		w.stmtList(n.Body)
+
+	default:
+		panic(fmt.Sprintf("internal error: unknown node type %T", n))
+	}
+}
+
+func (w *walker) declList(list []Decl) {
+	for _, n := range list {
+		w.node(n)
+	}
+}
+
+func (w *walker) exprList(list []Expr) {
+	for _, n := range list {
+		w.node(n)
+	}
+}
+
+func (w *walker) stmtList(list []Stmt) {
+	for _, n := range list {
+		w.node(n)
+	}
+}
+
+func (w *walker) nameList(list []*Name) {
+	for _, n := range list {
+		w.node(n)
+	}
+}
+
+func (w *walker) fieldList(list []*Field) {
+	for _, n := range list {
+		w.node(n)
+	}
+}
diff --git a/src/cmd/compile/internal/test/abiutils_test.go b/src/cmd/compile/internal/test/abiutils_test.go
new file mode 100644
index 0000000..b752c48
--- /dev/null
+++ b/src/cmd/compile/internal/test/abiutils_test.go
@@ -0,0 +1,397 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test
+
+import (
+	"bufio"
+	"cmd/compile/internal/abi"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ssagen"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/obj/x86"
+	"cmd/internal/src"
+	"fmt"
+	"os"
+	"testing"
+)
+
+// AMD64 registers available:
+// - integer: RAX, RBX, RCX, RDI, RSI, R8, R9, r10, R11
+// - floating point: X0 - X14
+var configAMD64 = abi.NewABIConfig(9, 15, 0)
+
+func TestMain(m *testing.M) {
+	ssagen.Arch.LinkArch = &x86.Linkamd64
+	ssagen.Arch.REGSP = x86.REGSP
+	ssagen.Arch.MAXWIDTH = 1 << 50
+	types.MaxWidth = ssagen.Arch.MAXWIDTH
+	base.Ctxt = obj.Linknew(ssagen.Arch.LinkArch)
+	base.Ctxt.DiagFunc = base.Errorf
+	base.Ctxt.DiagFlush = base.FlushErrors
+	base.Ctxt.Bso = bufio.NewWriter(os.Stdout)
+	types.PtrSize = ssagen.Arch.LinkArch.PtrSize
+	types.RegSize = ssagen.Arch.LinkArch.RegSize
+	typecheck.InitUniverse()
+	os.Exit(m.Run())
+}
+
+func TestABIUtilsBasic1(t *testing.T) {
+
+	// func(x int32) int32
+	i32 := types.Types[types.TINT32]
+	ft := mkFuncType(nil, []*types.Type{i32}, []*types.Type{i32})
+
+	// expected results
+	exp := makeExpectedDump(`
+        IN 0: R{ I0 } spilloffset: 0 typ: int32
+        OUT 0: R{ I0 } spilloffset: -1 typ: int32
+        offsetToSpillArea: 0 spillAreaSize: 8
+`)
+
+	abitest(t, ft, exp)
+}
+
+func TestABIUtilsBasic2(t *testing.T) {
+	// func(p1 int8, p2 int16, p3 int32, p4 int64,
+	//      p5 float32, p6 float32, p7 float64, p8 float64,
+	//      p9 int8, p10 int16, p11 int32, p12 int64,
+	//      p13 float32, p14 float32, p15 float64, p16 float64,
+	//      p17 complex128, p18 complex128, p19 complex12, p20 complex128,
+	//      p21 complex64, p22 int8, p23 in16, p24 int32, p25 int64,
+	//      p26 int8, p27 in16, p28 int32, p29 int64)
+	//        (r1 int32, r2 float64, r3 float64) {
+	i8 := types.Types[types.TINT8]
+	i16 := types.Types[types.TINT16]
+	i32 := types.Types[types.TINT32]
+	i64 := types.Types[types.TINT64]
+	f32 := types.Types[types.TFLOAT32]
+	f64 := types.Types[types.TFLOAT64]
+	c64 := types.Types[types.TCOMPLEX64]
+	c128 := types.Types[types.TCOMPLEX128]
+	ft := mkFuncType(nil,
+		[]*types.Type{
+			i8, i16, i32, i64,
+			f32, f32, f64, f64,
+			i8, i16, i32, i64,
+			f32, f32, f64, f64,
+			c128, c128, c128, c128, c64,
+			i8, i16, i32, i64,
+			i8, i16, i32, i64},
+		[]*types.Type{i32, f64, f64})
+	exp := makeExpectedDump(`
+        IN 0: R{ I0 } spilloffset: 0 typ: int8
+        IN 1: R{ I1 } spilloffset: 2 typ: int16
+        IN 2: R{ I2 } spilloffset: 4 typ: int32
+        IN 3: R{ I3 } spilloffset: 8 typ: int64
+        IN 4: R{ F0 } spilloffset: 16 typ: float32
+        IN 5: R{ F1 } spilloffset: 20 typ: float32
+        IN 6: R{ F2 } spilloffset: 24 typ: float64
+        IN 7: R{ F3 } spilloffset: 32 typ: float64
+        IN 8: R{ I4 } spilloffset: 40 typ: int8
+        IN 9: R{ I5 } spilloffset: 42 typ: int16
+        IN 10: R{ I6 } spilloffset: 44 typ: int32
+        IN 11: R{ I7 } spilloffset: 48 typ: int64
+        IN 12: R{ F4 } spilloffset: 56 typ: float32
+        IN 13: R{ F5 } spilloffset: 60 typ: float32
+        IN 14: R{ F6 } spilloffset: 64 typ: float64
+        IN 15: R{ F7 } spilloffset: 72 typ: float64
+        IN 16: R{ F8 F9 } spilloffset: 80 typ: complex128
+        IN 17: R{ F10 F11 } spilloffset: 96 typ: complex128
+        IN 18: R{ F12 F13 } spilloffset: 112 typ: complex128
+        IN 19: R{ } offset: 0 typ: complex128
+        IN 20: R{ } offset: 16 typ: complex64
+        IN 21: R{ I8 } spilloffset: 128 typ: int8
+        IN 22: R{ } offset: 24 typ: int16
+        IN 23: R{ } offset: 28 typ: int32
+        IN 24: R{ } offset: 32 typ: int64
+        IN 25: R{ } offset: 40 typ: int8
+        IN 26: R{ } offset: 42 typ: int16
+        IN 27: R{ } offset: 44 typ: int32
+        IN 28: R{ } offset: 48 typ: int64
+        OUT 0: R{ I0 } spilloffset: -1 typ: int32
+        OUT 1: R{ F0 } spilloffset: -1 typ: float64
+        OUT 2: R{ F1 } spilloffset: -1 typ: float64
+        offsetToSpillArea: 56 spillAreaSize: 136
+`)
+
+	abitest(t, ft, exp)
+}
+
+func TestABIUtilsArrays(t *testing.T) {
+	// func(p1 [1]int32, p2 [0]int32, p3 [1][1]int32, p4 [2]int32)
+	//         (r1 [2]int32, r2 [1]int32, r3 [0]int32, r4 [1][1]int32) {
+	i32 := types.Types[types.TINT32]
+	ae := types.NewArray(i32, 0)
+	a1 := types.NewArray(i32, 1)
+	a2 := types.NewArray(i32, 2)
+	aa1 := types.NewArray(a1, 1)
+	ft := mkFuncType(nil, []*types.Type{a1, ae, aa1, a2},
+		[]*types.Type{a2, a1, ae, aa1})
+
+	exp := makeExpectedDump(`
+        IN 0: R{ I0 } spilloffset: 0 typ: [1]int32
+        IN 1: R{ } offset: 0 typ: [0]int32
+        IN 2: R{ I1 } spilloffset: 4 typ: [1][1]int32
+        IN 3: R{ } offset: 0 typ: [2]int32
+        OUT 0: R{ } offset: 8 typ: [2]int32
+        OUT 1: R{ I0 } spilloffset: -1 typ: [1]int32
+        OUT 2: R{ } offset: 16 typ: [0]int32
+        OUT 3: R{ I1 } spilloffset: -1 typ: [1][1]int32
+        offsetToSpillArea: 16 spillAreaSize: 8
+`)
+
+	abitest(t, ft, exp)
+}
+
+func TestABIUtilsStruct1(t *testing.T) {
+	// type s struct { f1 int8; f2 int8; f3 struct {}; f4 int8; f5 int16) }
+	// func(p1 int6, p2 s, p3 int64)
+	//   (r1 s, r2 int8, r3 int32) {
+	i8 := types.Types[types.TINT8]
+	i16 := types.Types[types.TINT16]
+	i32 := types.Types[types.TINT32]
+	i64 := types.Types[types.TINT64]
+	s := mkstruct([]*types.Type{i8, i8, mkstruct([]*types.Type{}), i8, i16})
+	ft := mkFuncType(nil, []*types.Type{i8, s, i64},
+		[]*types.Type{s, i8, i32})
+
+	exp := makeExpectedDump(`
+        IN 0: R{ I0 } spilloffset: 0 typ: int8
+        IN 1: R{ I1 I2 I3 I4 } spilloffset: 2 typ: struct { int8; int8; struct {}; int8; int16 }
+        IN 2: R{ I5 } spilloffset: 8 typ: int64
+        OUT 0: R{ I0 I1 I2 I3 } spilloffset: -1 typ: struct { int8; int8; struct {}; int8; int16 }
+        OUT 1: R{ I4 } spilloffset: -1 typ: int8
+        OUT 2: R{ I5 } spilloffset: -1 typ: int32
+        offsetToSpillArea: 0 spillAreaSize: 16
+`)
+
+	abitest(t, ft, exp)
+}
+
+func TestABIUtilsStruct2(t *testing.T) {
+	// type s struct { f1 int64; f2 struct { } }
+	// type fs struct { f1 float64; f2 s; f3 struct { } }
+	// func(p1 s, p2 s, p3 fs)
+	//    (r1 fs, r2 fs)
+	f64 := types.Types[types.TFLOAT64]
+	i64 := types.Types[types.TINT64]
+	s := mkstruct([]*types.Type{i64, mkstruct([]*types.Type{})})
+	fs := mkstruct([]*types.Type{f64, s, mkstruct([]*types.Type{})})
+	ft := mkFuncType(nil, []*types.Type{s, s, fs},
+		[]*types.Type{fs, fs})
+
+	exp := makeExpectedDump(`
+        IN 0: R{ I0 } spilloffset: 0 typ: struct { int64; struct {} }
+        IN 1: R{ I1 } spilloffset: 16 typ: struct { int64; struct {} }
+        IN 2: R{ F0 I2 } spilloffset: 32 typ: struct { float64; struct { int64; struct {} }; struct {} }
+        OUT 0: R{ F0 I0 } spilloffset: -1 typ: struct { float64; struct { int64; struct {} }; struct {} }
+        OUT 1: R{ F1 I1 } spilloffset: -1 typ: struct { float64; struct { int64; struct {} }; struct {} }
+        offsetToSpillArea: 0 spillAreaSize: 64
+`)
+
+	abitest(t, ft, exp)
+}
+
+// TestABIUtilsEmptyFieldAtEndOfStruct is testing to make sure
+// the abi code is doing the right thing for struct types that have
+// a trailing zero-sized field (where the we need to add padding).
+func TestABIUtilsEmptyFieldAtEndOfStruct(t *testing.T) {
+	// type s struct { f1 [2]int64; f2 struct { } }
+	// type s2 struct { f1 [3]int16; f2 struct { } }
+	// type fs struct { f1 float64; f s; f3 struct { } }
+	// func(p1 s, p2 s, p3 fs)  (r1 fs, r2 fs)
+	f64 := types.Types[types.TFLOAT64]
+	i64 := types.Types[types.TINT64]
+	i16 := types.Types[types.TINT16]
+	tb := types.Types[types.TBOOL]
+	ab2 := types.NewArray(tb, 2)
+	a2 := types.NewArray(i64, 2)
+	a3 := types.NewArray(i16, 3)
+	s := mkstruct([]*types.Type{a2, mkstruct([]*types.Type{})})
+	s2 := mkstruct([]*types.Type{a3, mkstruct([]*types.Type{})})
+	fs := mkstruct([]*types.Type{f64, s, mkstruct([]*types.Type{})})
+	ft := mkFuncType(nil, []*types.Type{s, ab2, s2, fs, fs},
+		[]*types.Type{fs, ab2, fs})
+
+	exp := makeExpectedDump(`
+        IN 0: R{ } offset: 0 typ: struct { [2]int64; struct {} }
+        IN 1: R{ } offset: 24 typ: [2]bool
+        IN 2: R{ } offset: 26 typ: struct { [3]int16; struct {} }
+        IN 3: R{ } offset: 40 typ: struct { float64; struct { [2]int64; struct {} }; struct {} }
+        IN 4: R{ } offset: 80 typ: struct { float64; struct { [2]int64; struct {} }; struct {} }
+        OUT 0: R{ } offset: 120 typ: struct { float64; struct { [2]int64; struct {} }; struct {} }
+        OUT 1: R{ } offset: 160 typ: [2]bool
+        OUT 2: R{ } offset: 168 typ: struct { float64; struct { [2]int64; struct {} }; struct {} }
+        offsetToSpillArea: 208 spillAreaSize: 0
+`)
+
+	abitest(t, ft, exp)
+
+	// Check to make sure that NumParamRegs yields 2 and not 3
+	// for struct "s" (e.g. that it handles the padding properly).
+	nps := configAMD64.NumParamRegs(s)
+	if nps != 2 {
+		t.Errorf("NumParams(%v) returned %d expected %d\n",
+			s, nps, 2)
+	}
+}
+
+func TestABIUtilsSliceString(t *testing.T) {
+	// func(p1 []int32, p2 int8, p3 []int32, p4 int8, p5 string,
+	//      p6 int64, p6 []intr32) (r1 string, r2 int64, r3 string, r4 []int32)
+	i32 := types.Types[types.TINT32]
+	sli32 := types.NewSlice(i32)
+	str := types.New(types.TSTRING)
+	i8 := types.Types[types.TINT8]
+	i64 := types.Types[types.TINT64]
+	ft := mkFuncType(nil, []*types.Type{sli32, i8, sli32, i8, str, i8, i64, sli32},
+		[]*types.Type{str, i64, str, sli32})
+
+	exp := makeExpectedDump(`
+        IN 0: R{ I0 I1 I2 } spilloffset: 0 typ: []int32
+        IN 1: R{ I3 } spilloffset: 24 typ: int8
+        IN 2: R{ I4 I5 I6 } spilloffset: 32 typ: []int32
+        IN 3: R{ I7 } spilloffset: 56 typ: int8
+        IN 4: R{ } offset: 0 typ: string
+        IN 5: R{ I8 } spilloffset: 57 typ: int8
+        IN 6: R{ } offset: 16 typ: int64
+        IN 7: R{ } offset: 24 typ: []int32
+        OUT 0: R{ I0 I1 } spilloffset: -1 typ: string
+        OUT 1: R{ I2 } spilloffset: -1 typ: int64
+        OUT 2: R{ I3 I4 } spilloffset: -1 typ: string
+        OUT 3: R{ I5 I6 I7 } spilloffset: -1 typ: []int32
+        offsetToSpillArea: 48 spillAreaSize: 64
+`)
+
+	abitest(t, ft, exp)
+}
+
+func TestABIUtilsMethod(t *testing.T) {
+	// type s1 struct { f1 int16; f2 int16; f3 int16 }
+	// func(p1 *s1, p2 [7]*s1, p3 float64, p4 int16, p5 int16, p6 int16)
+	//   (r1 [7]*s1, r2 float64, r3 int64)
+	i16 := types.Types[types.TINT16]
+	i64 := types.Types[types.TINT64]
+	f64 := types.Types[types.TFLOAT64]
+	s1 := mkstruct([]*types.Type{i16, i16, i16})
+	ps1 := types.NewPtr(s1)
+	a7 := types.NewArray(ps1, 7)
+	ft := mkFuncType(s1, []*types.Type{ps1, a7, f64, i16, i16, i16},
+		[]*types.Type{a7, f64, i64})
+
+	exp := makeExpectedDump(`
+        IN 0: R{ I0 I1 I2 } spilloffset: 0 typ: struct { int16; int16; int16 }
+        IN 1: R{ I3 } spilloffset: 8 typ: *struct { int16; int16; int16 }
+        IN 2: R{ } offset: 0 typ: [7]*struct { int16; int16; int16 }
+        IN 3: R{ F0 } spilloffset: 16 typ: float64
+        IN 4: R{ I4 } spilloffset: 24 typ: int16
+        IN 5: R{ I5 } spilloffset: 26 typ: int16
+        IN 6: R{ I6 } spilloffset: 28 typ: int16
+        OUT 0: R{ } offset: 56 typ: [7]*struct { int16; int16; int16 }
+        OUT 1: R{ F0 } spilloffset: -1 typ: float64
+        OUT 2: R{ I0 } spilloffset: -1 typ: int64
+        offsetToSpillArea: 112 spillAreaSize: 32
+`)
+
+	abitest(t, ft, exp)
+}
+
+func TestABIUtilsInterfaces(t *testing.T) {
+	// type s1 { f1 int16; f2 int16; f3 bool)
+	// type nei interface { ...() string }
+	// func(p1 s1, p2 interface{}, p3 interface{}, p4 nei,
+	//      p5 *interface{}, p6 nei, p7 int64)
+	//    (r1 interface{}, r2 nei, r3 bool)
+	ei := types.Types[types.TINTER] // interface{}
+	pei := types.NewPtr(ei)         // *interface{}
+	fldt := mkFuncType(types.FakeRecvType(), []*types.Type{},
+		[]*types.Type{types.UntypedString})
+	field := types.NewField(src.NoXPos, nil, fldt)
+	nei := types.NewInterface(types.LocalPkg, []*types.Field{field})
+	i16 := types.Types[types.TINT16]
+	tb := types.Types[types.TBOOL]
+	s1 := mkstruct([]*types.Type{i16, i16, tb})
+	ft := mkFuncType(nil, []*types.Type{s1, ei, ei, nei, pei, nei, i16},
+		[]*types.Type{ei, nei, pei})
+
+	exp := makeExpectedDump(`
+        IN 0: R{ I0 I1 I2 } spilloffset: 0 typ: struct { int16; int16; bool }
+        IN 1: R{ I3 I4 } spilloffset: 8 typ: interface {}
+        IN 2: R{ I5 I6 } spilloffset: 24 typ: interface {}
+        IN 3: R{ I7 I8 } spilloffset: 40 typ: interface { () untyped string }
+        IN 4: R{ } offset: 0 typ: *interface {}
+        IN 5: R{ } offset: 8 typ: interface { () untyped string }
+        IN 6: R{ } offset: 24 typ: int16
+        OUT 0: R{ I0 I1 } spilloffset: -1 typ: interface {}
+        OUT 1: R{ I2 I3 } spilloffset: -1 typ: interface { () untyped string }
+        OUT 2: R{ I4 } spilloffset: -1 typ: *interface {}
+        offsetToSpillArea: 32 spillAreaSize: 56
+`)
+
+	abitest(t, ft, exp)
+}
+
+func TestABINumParamRegs(t *testing.T) {
+	i8 := types.Types[types.TINT8]
+	i16 := types.Types[types.TINT16]
+	i32 := types.Types[types.TINT32]
+	i64 := types.Types[types.TINT64]
+	f32 := types.Types[types.TFLOAT32]
+	f64 := types.Types[types.TFLOAT64]
+	c64 := types.Types[types.TCOMPLEX64]
+	c128 := types.Types[types.TCOMPLEX128]
+
+	s := mkstruct([]*types.Type{i8, i8, mkstruct([]*types.Type{}), i8, i16})
+	a := types.NewArray(s, 3)
+
+	nrtest(t, i8, 1)
+	nrtest(t, i16, 1)
+	nrtest(t, i32, 1)
+	nrtest(t, i64, 1)
+	nrtest(t, f32, 1)
+	nrtest(t, f64, 1)
+	nrtest(t, c64, 2)
+	nrtest(t, c128, 2)
+	nrtest(t, s, 4)
+	nrtest(t, a, 12)
+
+}
+
+func TestABIUtilsComputePadding(t *testing.T) {
+	// type s1 { f1 int8; f2 int16; f3 struct{}; f4 int32; f5 int64 }
+	i8 := types.Types[types.TINT8]
+	i16 := types.Types[types.TINT16]
+	i32 := types.Types[types.TINT32]
+	i64 := types.Types[types.TINT64]
+	emptys := mkstruct([]*types.Type{})
+	s1 := mkstruct([]*types.Type{i8, i16, emptys, i32, i64})
+	// func (p1 int32, p2 s1, p3 emptys, p4 [1]int32)
+	a1 := types.NewArray(i32, 1)
+	ft := mkFuncType(nil, []*types.Type{i32, s1, emptys, a1}, []*types.Type{})
+
+	// Run abitest() just to document what we're expected to see.
+	exp := makeExpectedDump(`
+        IN 0: R{ I0 } spilloffset: 0 typ: int32
+        IN 1: R{ I1 I2 I3 I4 } spilloffset: 8 typ: struct { int8; int16; struct {}; int32; int64 }
+        IN 2: R{ } offset: 0 typ: struct {}
+        IN 3: R{ I5 } spilloffset: 24 typ: [1]int32
+        offsetToSpillArea: 0 spillAreaSize: 32
+`)
+	abitest(t, ft, exp)
+
+	// Analyze with full set of registers, then call ComputePadding
+	// on the second param, verifying the results.
+	regRes := configAMD64.ABIAnalyze(ft, false)
+	padding := make([]uint64, 32)
+	parm := regRes.InParams()[1]
+	padding = parm.ComputePadding(padding)
+	want := "[1 1 1 0]"
+	got := fmt.Sprintf("%+v", padding)
+	if got != want {
+		t.Errorf("padding mismatch: wanted %q got %q\n", got, want)
+	}
+}
diff --git a/src/cmd/compile/internal/test/abiutilsaux_test.go b/src/cmd/compile/internal/test/abiutilsaux_test.go
new file mode 100644
index 0000000..b945633
--- /dev/null
+++ b/src/cmd/compile/internal/test/abiutilsaux_test.go
@@ -0,0 +1,132 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test
+
+// This file contains utility routines and harness infrastructure used
+// by the ABI tests in "abiutils_test.go".
+
+import (
+	"cmd/compile/internal/abi"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+	"fmt"
+	"strings"
+	"testing"
+	"text/scanner"
+)
+
+func mkParamResultField(t *types.Type, s *types.Sym, which ir.Class) *types.Field {
+	field := types.NewField(src.NoXPos, s, t)
+	n := typecheck.NewName(s)
+	n.Class = which
+	field.Nname = n
+	n.SetType(t)
+	return field
+}
+
+// mkstruct is a helper routine to create a struct type with fields
+// of the types specified in 'fieldtypes'.
+func mkstruct(fieldtypes []*types.Type) *types.Type {
+	fields := make([]*types.Field, len(fieldtypes))
+	for k, t := range fieldtypes {
+		if t == nil {
+			panic("bad -- field has no type")
+		}
+		f := types.NewField(src.NoXPos, nil, t)
+		fields[k] = f
+	}
+	s := types.NewStruct(types.LocalPkg, fields)
+	return s
+}
+
+func mkFuncType(rcvr *types.Type, ins []*types.Type, outs []*types.Type) *types.Type {
+	q := typecheck.Lookup("?")
+	inf := []*types.Field{}
+	for _, it := range ins {
+		inf = append(inf, mkParamResultField(it, q, ir.PPARAM))
+	}
+	outf := []*types.Field{}
+	for _, ot := range outs {
+		outf = append(outf, mkParamResultField(ot, q, ir.PPARAMOUT))
+	}
+	var rf *types.Field
+	if rcvr != nil {
+		rf = mkParamResultField(rcvr, q, ir.PPARAM)
+	}
+	return types.NewSignature(types.LocalPkg, rf, nil, inf, outf)
+}
+
+type expectedDump struct {
+	dump string
+	file string
+	line int
+}
+
+func tokenize(src string) []string {
+	var s scanner.Scanner
+	s.Init(strings.NewReader(src))
+	res := []string{}
+	for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
+		res = append(res, s.TokenText())
+	}
+	return res
+}
+
+func verifyParamResultOffset(t *testing.T, f *types.Field, r abi.ABIParamAssignment, which string, idx int) int {
+	n := ir.AsNode(f.Nname).(*ir.Name)
+	if n.FrameOffset() != int64(r.Offset()) {
+		t.Errorf("%s %d: got offset %d wanted %d t=%v",
+			which, idx, r.Offset(), n.Offset_, f.Type)
+		return 1
+	}
+	return 0
+}
+
+func makeExpectedDump(e string) expectedDump {
+	return expectedDump{dump: e}
+}
+
+func difftokens(atoks []string, etoks []string) string {
+	if len(atoks) != len(etoks) {
+		return fmt.Sprintf("expected %d tokens got %d",
+			len(etoks), len(atoks))
+	}
+	for i := 0; i < len(etoks); i++ {
+		if etoks[i] == atoks[i] {
+			continue
+		}
+
+		return fmt.Sprintf("diff at token %d: expected %q got %q",
+			i, etoks[i], atoks[i])
+	}
+	return ""
+}
+
+func nrtest(t *testing.T, ft *types.Type, expected int) {
+	types.CalcSize(ft)
+	got := configAMD64.NumParamRegs(ft)
+	if got != expected {
+		t.Errorf("]\nexpected num regs = %d, got %d, type %v", expected, got, ft)
+	}
+}
+
+func abitest(t *testing.T, ft *types.Type, exp expectedDump) {
+
+	types.CalcSize(ft)
+
+	// Analyze with full set of registers.
+	regRes := configAMD64.ABIAnalyze(ft, false)
+	regResString := strings.TrimSpace(regRes.String())
+
+	// Check results.
+	reason := difftokens(tokenize(regResString), tokenize(exp.dump))
+	if reason != "" {
+		t.Errorf("\nexpected:\n%s\ngot:\n%s\nreason: %s",
+			strings.TrimSpace(exp.dump), regResString, reason)
+	}
+
+}
diff --git a/src/cmd/compile/internal/test/align_test.go b/src/cmd/compile/internal/test/align_test.go
new file mode 100644
index 0000000..32afc92
--- /dev/null
+++ b/src/cmd/compile/internal/test/align_test.go
@@ -0,0 +1,96 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test to make sure that equality functions (and hash
+// functions) don't do unaligned reads on architectures
+// that can't do unaligned reads. See issue 46283.
+
+package test
+
+import "testing"
+
+type T1 struct {
+	x          float32
+	a, b, c, d int16 // memequal64
+}
+type T2 struct {
+	x          float32
+	a, b, c, d int32 // memequal128
+}
+
+type A2 [2]byte // eq uses a 2-byte load
+type A4 [4]byte // eq uses a 4-byte load
+type A8 [8]byte // eq uses an 8-byte load
+
+//go:noinline
+func cmpT1(p, q *T1) {
+	if *p != *q {
+		panic("comparison test wrong")
+	}
+}
+
+//go:noinline
+func cmpT2(p, q *T2) {
+	if *p != *q {
+		panic("comparison test wrong")
+	}
+}
+
+//go:noinline
+func cmpA2(p, q *A2) {
+	if *p != *q {
+		panic("comparison test wrong")
+	}
+}
+
+//go:noinline
+func cmpA4(p, q *A4) {
+	if *p != *q {
+		panic("comparison test wrong")
+	}
+}
+
+//go:noinline
+func cmpA8(p, q *A8) {
+	if *p != *q {
+		panic("comparison test wrong")
+	}
+}
+
+func TestAlignEqual(t *testing.T) {
+	cmpT1(&T1{}, &T1{})
+	cmpT2(&T2{}, &T2{})
+
+	m1 := map[T1]bool{}
+	m1[T1{}] = true
+	m1[T1{}] = false
+	if len(m1) != 1 {
+		t.Fatalf("len(m1)=%d, want 1", len(m1))
+	}
+	m2 := map[T2]bool{}
+	m2[T2{}] = true
+	m2[T2{}] = false
+	if len(m2) != 1 {
+		t.Fatalf("len(m2)=%d, want 1", len(m2))
+	}
+
+	type X2 struct {
+		y byte
+		z A2
+	}
+	var x2 X2
+	cmpA2(&x2.z, &A2{})
+	type X4 struct {
+		y byte
+		z A4
+	}
+	var x4 X4
+	cmpA4(&x4.z, &A4{})
+	type X8 struct {
+		y byte
+		z A8
+	}
+	var x8 X8
+	cmpA8(&x8.z, &A8{})
+}
diff --git a/src/cmd/compile/internal/test/bench_test.go b/src/cmd/compile/internal/test/bench_test.go
new file mode 100644
index 0000000..4724600
--- /dev/null
+++ b/src/cmd/compile/internal/test/bench_test.go
@@ -0,0 +1,124 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test
+
+import "testing"
+
+var globl int64
+var globl32 int32
+
+func BenchmarkLoadAdd(b *testing.B) {
+	x := make([]int64, 1024)
+	y := make([]int64, 1024)
+	for i := 0; i < b.N; i++ {
+		var s int64
+		for i := range x {
+			s ^= x[i] + y[i]
+		}
+		globl = s
+	}
+}
+
+// Added for ppc64 extswsli on power9
+func BenchmarkExtShift(b *testing.B) {
+	x := make([]int32, 1024)
+	for i := 0; i < b.N; i++ {
+		var s int64
+		for i := range x {
+			s ^= int64(x[i]+32) * 8
+		}
+		globl = s
+	}
+}
+
+func BenchmarkModify(b *testing.B) {
+	a := make([]int64, 1024)
+	v := globl
+	for i := 0; i < b.N; i++ {
+		for j := range a {
+			a[j] += v
+		}
+	}
+}
+
+func BenchmarkMullImm(b *testing.B) {
+	x := make([]int32, 1024)
+	for i := 0; i < b.N; i++ {
+		var s int32
+		for i := range x {
+			s += x[i] * 100
+		}
+		globl32 = s
+	}
+}
+
+func BenchmarkConstModify(b *testing.B) {
+	a := make([]int64, 1024)
+	for i := 0; i < b.N; i++ {
+		for j := range a {
+			a[j] += 3
+		}
+	}
+}
+
+func BenchmarkBitSet(b *testing.B) {
+	const N = 64 * 8
+	a := make([]uint64, N/64)
+	for i := 0; i < b.N; i++ {
+		for j := uint64(0); j < N; j++ {
+			a[j/64] |= 1 << (j % 64)
+		}
+	}
+}
+
+func BenchmarkBitClear(b *testing.B) {
+	const N = 64 * 8
+	a := make([]uint64, N/64)
+	for i := 0; i < b.N; i++ {
+		for j := uint64(0); j < N; j++ {
+			a[j/64] &^= 1 << (j % 64)
+		}
+	}
+}
+
+func BenchmarkBitToggle(b *testing.B) {
+	const N = 64 * 8
+	a := make([]uint64, N/64)
+	for i := 0; i < b.N; i++ {
+		for j := uint64(0); j < N; j++ {
+			a[j/64] ^= 1 << (j % 64)
+		}
+	}
+}
+
+func BenchmarkBitSetConst(b *testing.B) {
+	const N = 64
+	a := make([]uint64, N)
+	for i := 0; i < b.N; i++ {
+		for j := range a {
+			a[j] |= 1 << 37
+		}
+	}
+}
+
+func BenchmarkBitClearConst(b *testing.B) {
+	const N = 64
+	a := make([]uint64, N)
+	for i := 0; i < b.N; i++ {
+		for j := range a {
+			a[j] &^= 1 << 37
+		}
+	}
+}
+
+func BenchmarkBitToggleConst(b *testing.B) {
+	const N = 64
+	a := make([]uint64, N)
+	for i := 0; i < b.N; i++ {
+		for j := range a {
+			a[j] ^= 1 << 37
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/test/clobberdead_test.go b/src/cmd/compile/internal/test/clobberdead_test.go
new file mode 100644
index 0000000..88b7d34
--- /dev/null
+++ b/src/cmd/compile/internal/test/clobberdead_test.go
@@ -0,0 +1,55 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test
+
+import (
+	"internal/testenv"
+	"io/ioutil"
+	"os/exec"
+	"path/filepath"
+	"testing"
+)
+
+const helloSrc = `
+package main
+import "fmt"
+func main() { fmt.Println("hello") }
+`
+
+func TestClobberDead(t *testing.T) {
+	// Test that clobberdead mode generates correct program.
+	runHello(t, "-clobberdead")
+}
+
+func TestClobberDeadReg(t *testing.T) {
+	// Test that clobberdeadreg mode generates correct program.
+	runHello(t, "-clobberdeadreg")
+}
+
+func runHello(t *testing.T, flag string) {
+	if testing.Short() {
+		// This test rebuilds the runtime with a special flag, which
+		// takes a while.
+		t.Skip("skip in short mode")
+	}
+	testenv.MustHaveGoRun(t)
+	t.Parallel()
+
+	tmpdir := t.TempDir()
+	src := filepath.Join(tmpdir, "x.go")
+	err := ioutil.WriteFile(src, []byte(helloSrc), 0644)
+	if err != nil {
+		t.Fatalf("write file failed: %v", err)
+	}
+
+	cmd := exec.Command(testenv.GoToolPath(t), "run", "-gcflags=all="+flag, src)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("go run failed: %v\n%s", err, out)
+	}
+	if string(out) != "hello\n" {
+		t.Errorf("wrong output: got %q, want %q", out, "hello\n")
+	}
+}
diff --git a/src/cmd/compile/internal/test/constFold_test.go b/src/cmd/compile/internal/test/constFold_test.go
new file mode 100644
index 0000000..7159f0e
--- /dev/null
+++ b/src/cmd/compile/internal/test/constFold_test.go
@@ -0,0 +1,18111 @@
+// run
+// Code generated by gen/constFoldGen.go. DO NOT EDIT.
+
+package test
+
+import "testing"
+
+func TestConstFolduint64add(t *testing.T) {
+	var x, y, r uint64
+	x = 0
+	y = 0
+	r = x + y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 1 {
+		t.Errorf("0 %s 1 = %d, want 1", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != 4294967296 {
+		t.Errorf("0 %s 4294967296 = %d, want 4294967296", "+", r)
+	}
+	y = 18446744073709551615
+	r = x + y
+	if r != 18446744073709551615 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 18446744073709551615", "+", r)
+	}
+	x = 1
+	y = 0
+	r = x + y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != 4294967297 {
+		t.Errorf("1 %s 4294967296 = %d, want 4294967297", "+", r)
+	}
+	y = 18446744073709551615
+	r = x + y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "+", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x + y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 4294967297 {
+		t.Errorf("4294967296 %s 1 = %d, want 4294967297", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != 8589934592 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 8589934592", "+", r)
+	}
+	y = 18446744073709551615
+	r = x + y
+	if r != 4294967295 {
+		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 4294967295", "+", r)
+	}
+	x = 18446744073709551615
+	y = 0
+	r = x + y
+	if r != 18446744073709551615 {
+		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 0", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != 4294967295 {
+		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 4294967295", "+", r)
+	}
+	y = 18446744073709551615
+	r = x + y
+	if r != 18446744073709551614 {
+		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 18446744073709551614", "+", r)
+	}
+}
+func TestConstFolduint64sub(t *testing.T) {
+	var x, y, r uint64
+	x = 0
+	y = 0
+	r = x - y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 18446744073709551615 {
+		t.Errorf("0 %s 1 = %d, want 18446744073709551615", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != 18446744069414584320 {
+		t.Errorf("0 %s 4294967296 = %d, want 18446744069414584320", "-", r)
+	}
+	y = 18446744073709551615
+	r = x - y
+	if r != 1 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 1", "-", r)
+	}
+	x = 1
+	y = 0
+	r = x - y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != 18446744069414584321 {
+		t.Errorf("1 %s 4294967296 = %d, want 18446744069414584321", "-", r)
+	}
+	y = 18446744073709551615
+	r = x - y
+	if r != 2 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 2", "-", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x - y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 4294967295 {
+		t.Errorf("4294967296 %s 1 = %d, want 4294967295", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "-", r)
+	}
+	y = 18446744073709551615
+	r = x - y
+	if r != 4294967297 {
+		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 4294967297", "-", r)
+	}
+	x = 18446744073709551615
+	y = 0
+	r = x - y
+	if r != 18446744073709551615 {
+		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 18446744073709551614 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551614", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != 18446744069414584319 {
+		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 18446744069414584319", "-", r)
+	}
+	y = 18446744073709551615
+	r = x - y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 0", "-", r)
+	}
+}
+func TestConstFolduint64div(t *testing.T) {
+	var x, y, r uint64
+	x = 0
+	y = 1
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "/", r)
+	}
+	y = 18446744073709551615
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "/", r)
+	}
+	x = 1
+	y = 1
+	r = x / y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", "/", r)
+	}
+	y = 18446744073709551615
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "/", r)
+	}
+	x = 4294967296
+	y = 1
+	r = x / y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 1 = %d, want 4294967296", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != 1 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 1", "/", r)
+	}
+	y = 18446744073709551615
+	r = x / y
+	if r != 0 {
+		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 0", "/", r)
+	}
+	x = 18446744073709551615
+	y = 1
+	r = x / y
+	if r != 18446744073709551615 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551615", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != 4294967295 {
+		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 4294967295", "/", r)
+	}
+	y = 18446744073709551615
+	r = x / y
+	if r != 1 {
+		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 1", "/", r)
+	}
+}
+func TestConstFolduint64mul(t *testing.T) {
+	var x, y, r uint64
+	x = 0
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "*", r)
+	}
+	y = 18446744073709551615
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "*", r)
+	}
+	x = 1
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("1 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != 4294967296 {
+		t.Errorf("1 %s 4294967296 = %d, want 4294967296", "*", r)
+	}
+	y = 18446744073709551615
+	r = x * y
+	if r != 18446744073709551615 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 18446744073709551615", "*", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("4294967296 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 1 = %d, want 4294967296", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "*", r)
+	}
+	y = 18446744073709551615
+	r = x * y
+	if r != 18446744069414584320 {
+		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 18446744069414584320", "*", r)
+	}
+	x = 18446744073709551615
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 18446744073709551615 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551615", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != 18446744069414584320 {
+		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 18446744069414584320", "*", r)
+	}
+	y = 18446744073709551615
+	r = x * y
+	if r != 1 {
+		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 1", "*", r)
+	}
+}
+func TestConstFolduint64mod(t *testing.T) {
+	var x, y, r uint64
+	x = 0
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "%", r)
+	}
+	y = 18446744073709551615
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "%", r)
+	}
+	x = 1
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 4294967296 = %d, want 1", "%", r)
+	}
+	y = 18446744073709551615
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 1", "%", r)
+	}
+	x = 4294967296
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("4294967296 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "%", r)
+	}
+	y = 18446744073709551615
+	r = x % y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 4294967296", "%", r)
+	}
+	x = 18446744073709551615
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != 4294967295 {
+		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 4294967295", "%", r)
+	}
+	y = 18446744073709551615
+	r = x % y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 0", "%", r)
+	}
+}
+func TestConstFoldint64add(t *testing.T) {
+	var x, y, r int64
+	x = -9223372036854775808
+	y = -9223372036854775808
+	r = x + y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s -9223372036854775808 = %d, want 0", "+", r)
+	}
+	y = -9223372036854775807
+	r = x + y
+	if r != 1 {
+		t.Errorf("-9223372036854775808 %s -9223372036854775807 = %d, want 1", "+", r)
+	}
+	y = -4294967296
+	r = x + y
+	if r != 9223372032559808512 {
+		t.Errorf("-9223372036854775808 %s -4294967296 = %d, want 9223372032559808512", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 9223372036854775807 {
+		t.Errorf("-9223372036854775808 %s -1 = %d, want 9223372036854775807", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want -9223372036854775807", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != -9223372032559808512 {
+		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want -9223372032559808512", "+", r)
+	}
+	y = 9223372036854775806
+	r = x + y
+	if r != -2 {
+		t.Errorf("-9223372036854775808 %s 9223372036854775806 = %d, want -2", "+", r)
+	}
+	y = 9223372036854775807
+	r = x + y
+	if r != -1 {
+		t.Errorf("-9223372036854775808 %s 9223372036854775807 = %d, want -1", "+", r)
+	}
+	x = -9223372036854775807
+	y = -9223372036854775808
+	r = x + y
+	if r != 1 {
+		t.Errorf("-9223372036854775807 %s -9223372036854775808 = %d, want 1", "+", r)
+	}
+	y = -9223372036854775807
+	r = x + y
+	if r != 2 {
+		t.Errorf("-9223372036854775807 %s -9223372036854775807 = %d, want 2", "+", r)
+	}
+	y = -4294967296
+	r = x + y
+	if r != 9223372032559808513 {
+		t.Errorf("-9223372036854775807 %s -4294967296 = %d, want 9223372032559808513", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775807 %s -1 = %d, want -9223372036854775808", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -9223372036854775806 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want -9223372036854775806", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != -9223372032559808511 {
+		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want -9223372032559808511", "+", r)
+	}
+	y = 9223372036854775806
+	r = x + y
+	if r != -1 {
+		t.Errorf("-9223372036854775807 %s 9223372036854775806 = %d, want -1", "+", r)
+	}
+	y = 9223372036854775807
+	r = x + y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s 9223372036854775807 = %d, want 0", "+", r)
+	}
+	x = -4294967296
+	y = -9223372036854775808
+	r = x + y
+	if r != 9223372032559808512 {
+		t.Errorf("-4294967296 %s -9223372036854775808 = %d, want 9223372032559808512", "+", r)
+	}
+	y = -9223372036854775807
+	r = x + y
+	if r != 9223372032559808513 {
+		t.Errorf("-4294967296 %s -9223372036854775807 = %d, want 9223372032559808513", "+", r)
+	}
+	y = -4294967296
+	r = x + y
+	if r != -8589934592 {
+		t.Errorf("-4294967296 %s -4294967296 = %d, want -8589934592", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -4294967297 {
+		t.Errorf("-4294967296 %s -1 = %d, want -4294967297", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -4294967295 {
+		t.Errorf("-4294967296 %s 1 = %d, want -4294967295", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != 0 {
+		t.Errorf("-4294967296 %s 4294967296 = %d, want 0", "+", r)
+	}
+	y = 9223372036854775806
+	r = x + y
+	if r != 9223372032559808510 {
+		t.Errorf("-4294967296 %s 9223372036854775806 = %d, want 9223372032559808510", "+", r)
+	}
+	y = 9223372036854775807
+	r = x + y
+	if r != 9223372032559808511 {
+		t.Errorf("-4294967296 %s 9223372036854775807 = %d, want 9223372032559808511", "+", r)
+	}
+	x = -1
+	y = -9223372036854775808
+	r = x + y
+	if r != 9223372036854775807 {
+		t.Errorf("-1 %s -9223372036854775808 = %d, want 9223372036854775807", "+", r)
+	}
+	y = -9223372036854775807
+	r = x + y
+	if r != -9223372036854775808 {
+		t.Errorf("-1 %s -9223372036854775807 = %d, want -9223372036854775808", "+", r)
+	}
+	y = -4294967296
+	r = x + y
+	if r != -4294967297 {
+		t.Errorf("-1 %s -4294967296 = %d, want -4294967297", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -2 {
+		t.Errorf("-1 %s -1 = %d, want -2", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 0 {
+		t.Errorf("-1 %s 1 = %d, want 0", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != 4294967295 {
+		t.Errorf("-1 %s 4294967296 = %d, want 4294967295", "+", r)
+	}
+	y = 9223372036854775806
+	r = x + y
+	if r != 9223372036854775805 {
+		t.Errorf("-1 %s 9223372036854775806 = %d, want 9223372036854775805", "+", r)
+	}
+	y = 9223372036854775807
+	r = x + y
+	if r != 9223372036854775806 {
+		t.Errorf("-1 %s 9223372036854775807 = %d, want 9223372036854775806", "+", r)
+	}
+	x = 0
+	y = -9223372036854775808
+	r = x + y
+	if r != -9223372036854775808 {
+		t.Errorf("0 %s -9223372036854775808 = %d, want -9223372036854775808", "+", r)
+	}
+	y = -9223372036854775807
+	r = x + y
+	if r != -9223372036854775807 {
+		t.Errorf("0 %s -9223372036854775807 = %d, want -9223372036854775807", "+", r)
+	}
+	y = -4294967296
+	r = x + y
+	if r != -4294967296 {
+		t.Errorf("0 %s -4294967296 = %d, want -4294967296", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -1 {
+		t.Errorf("0 %s -1 = %d, want -1", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 1 {
+		t.Errorf("0 %s 1 = %d, want 1", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != 4294967296 {
+		t.Errorf("0 %s 4294967296 = %d, want 4294967296", "+", r)
+	}
+	y = 9223372036854775806
+	r = x + y
+	if r != 9223372036854775806 {
+		t.Errorf("0 %s 9223372036854775806 = %d, want 9223372036854775806", "+", r)
+	}
+	y = 9223372036854775807
+	r = x + y
+	if r != 9223372036854775807 {
+		t.Errorf("0 %s 9223372036854775807 = %d, want 9223372036854775807", "+", r)
+	}
+	x = 1
+	y = -9223372036854775808
+	r = x + y
+	if r != -9223372036854775807 {
+		t.Errorf("1 %s -9223372036854775808 = %d, want -9223372036854775807", "+", r)
+	}
+	y = -9223372036854775807
+	r = x + y
+	if r != -9223372036854775806 {
+		t.Errorf("1 %s -9223372036854775807 = %d, want -9223372036854775806", "+", r)
+	}
+	y = -4294967296
+	r = x + y
+	if r != -4294967295 {
+		t.Errorf("1 %s -4294967296 = %d, want -4294967295", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 0 {
+		t.Errorf("1 %s -1 = %d, want 0", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != 4294967297 {
+		t.Errorf("1 %s 4294967296 = %d, want 4294967297", "+", r)
+	}
+	y = 9223372036854775806
+	r = x + y
+	if r != 9223372036854775807 {
+		t.Errorf("1 %s 9223372036854775806 = %d, want 9223372036854775807", "+", r)
+	}
+	y = 9223372036854775807
+	r = x + y
+	if r != -9223372036854775808 {
+		t.Errorf("1 %s 9223372036854775807 = %d, want -9223372036854775808", "+", r)
+	}
+	x = 4294967296
+	y = -9223372036854775808
+	r = x + y
+	if r != -9223372032559808512 {
+		t.Errorf("4294967296 %s -9223372036854775808 = %d, want -9223372032559808512", "+", r)
+	}
+	y = -9223372036854775807
+	r = x + y
+	if r != -9223372032559808511 {
+		t.Errorf("4294967296 %s -9223372036854775807 = %d, want -9223372032559808511", "+", r)
+	}
+	y = -4294967296
+	r = x + y
+	if r != 0 {
+		t.Errorf("4294967296 %s -4294967296 = %d, want 0", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 4294967295 {
+		t.Errorf("4294967296 %s -1 = %d, want 4294967295", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 4294967297 {
+		t.Errorf("4294967296 %s 1 = %d, want 4294967297", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != 8589934592 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 8589934592", "+", r)
+	}
+	y = 9223372036854775806
+	r = x + y
+	if r != -9223372032559808514 {
+		t.Errorf("4294967296 %s 9223372036854775806 = %d, want -9223372032559808514", "+", r)
+	}
+	y = 9223372036854775807
+	r = x + y
+	if r != -9223372032559808513 {
+		t.Errorf("4294967296 %s 9223372036854775807 = %d, want -9223372032559808513", "+", r)
+	}
+	x = 9223372036854775806
+	y = -9223372036854775808
+	r = x + y
+	if r != -2 {
+		t.Errorf("9223372036854775806 %s -9223372036854775808 = %d, want -2", "+", r)
+	}
+	y = -9223372036854775807
+	r = x + y
+	if r != -1 {
+		t.Errorf("9223372036854775806 %s -9223372036854775807 = %d, want -1", "+", r)
+	}
+	y = -4294967296
+	r = x + y
+	if r != 9223372032559808510 {
+		t.Errorf("9223372036854775806 %s -4294967296 = %d, want 9223372032559808510", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 9223372036854775805 {
+		t.Errorf("9223372036854775806 %s -1 = %d, want 9223372036854775805", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want 9223372036854775807", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != -9223372032559808514 {
+		t.Errorf("9223372036854775806 %s 4294967296 = %d, want -9223372032559808514", "+", r)
+	}
+	y = 9223372036854775806
+	r = x + y
+	if r != -4 {
+		t.Errorf("9223372036854775806 %s 9223372036854775806 = %d, want -4", "+", r)
+	}
+	y = 9223372036854775807
+	r = x + y
+	if r != -3 {
+		t.Errorf("9223372036854775806 %s 9223372036854775807 = %d, want -3", "+", r)
+	}
+	x = 9223372036854775807
+	y = -9223372036854775808
+	r = x + y
+	if r != -1 {
+		t.Errorf("9223372036854775807 %s -9223372036854775808 = %d, want -1", "+", r)
+	}
+	y = -9223372036854775807
+	r = x + y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s -9223372036854775807 = %d, want 0", "+", r)
+	}
+	y = -4294967296
+	r = x + y
+	if r != 9223372032559808511 {
+		t.Errorf("9223372036854775807 %s -4294967296 = %d, want 9223372032559808511", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775807 %s -1 = %d, want 9223372036854775806", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -9223372036854775808 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want -9223372036854775808", "+", r)
+	}
+	y = 4294967296
+	r = x + y
+	if r != -9223372032559808513 {
+		t.Errorf("9223372036854775807 %s 4294967296 = %d, want -9223372032559808513", "+", r)
+	}
+	y = 9223372036854775806
+	r = x + y
+	if r != -3 {
+		t.Errorf("9223372036854775807 %s 9223372036854775806 = %d, want -3", "+", r)
+	}
+	y = 9223372036854775807
+	r = x + y
+	if r != -2 {
+		t.Errorf("9223372036854775807 %s 9223372036854775807 = %d, want -2", "+", r)
+	}
+}
+func TestConstFoldint64sub(t *testing.T) {
+	var x, y, r int64
+	x = -9223372036854775808
+	y = -9223372036854775808
+	r = x - y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s -9223372036854775808 = %d, want 0", "-", r)
+	}
+	y = -9223372036854775807
+	r = x - y
+	if r != -1 {
+		t.Errorf("-9223372036854775808 %s -9223372036854775807 = %d, want -1", "-", r)
+	}
+	y = -4294967296
+	r = x - y
+	if r != -9223372032559808512 {
+		t.Errorf("-9223372036854775808 %s -4294967296 = %d, want -9223372032559808512", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775808 %s -1 = %d, want -9223372036854775807", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 9223372036854775807 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want 9223372036854775807", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != 9223372032559808512 {
+		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want 9223372032559808512", "-", r)
+	}
+	y = 9223372036854775806
+	r = x - y
+	if r != 2 {
+		t.Errorf("-9223372036854775808 %s 9223372036854775806 = %d, want 2", "-", r)
+	}
+	y = 9223372036854775807
+	r = x - y
+	if r != 1 {
+		t.Errorf("-9223372036854775808 %s 9223372036854775807 = %d, want 1", "-", r)
+	}
+	x = -9223372036854775807
+	y = -9223372036854775808
+	r = x - y
+	if r != 1 {
+		t.Errorf("-9223372036854775807 %s -9223372036854775808 = %d, want 1", "-", r)
+	}
+	y = -9223372036854775807
+	r = x - y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s -9223372036854775807 = %d, want 0", "-", r)
+	}
+	y = -4294967296
+	r = x - y
+	if r != -9223372032559808511 {
+		t.Errorf("-9223372036854775807 %s -4294967296 = %d, want -9223372032559808511", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -9223372036854775806 {
+		t.Errorf("-9223372036854775807 %s -1 = %d, want -9223372036854775806", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want -9223372036854775808", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != 9223372032559808513 {
+		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want 9223372032559808513", "-", r)
+	}
+	y = 9223372036854775806
+	r = x - y
+	if r != 3 {
+		t.Errorf("-9223372036854775807 %s 9223372036854775806 = %d, want 3", "-", r)
+	}
+	y = 9223372036854775807
+	r = x - y
+	if r != 2 {
+		t.Errorf("-9223372036854775807 %s 9223372036854775807 = %d, want 2", "-", r)
+	}
+	x = -4294967296
+	y = -9223372036854775808
+	r = x - y
+	if r != 9223372032559808512 {
+		t.Errorf("-4294967296 %s -9223372036854775808 = %d, want 9223372032559808512", "-", r)
+	}
+	y = -9223372036854775807
+	r = x - y
+	if r != 9223372032559808511 {
+		t.Errorf("-4294967296 %s -9223372036854775807 = %d, want 9223372032559808511", "-", r)
+	}
+	y = -4294967296
+	r = x - y
+	if r != 0 {
+		t.Errorf("-4294967296 %s -4294967296 = %d, want 0", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -4294967295 {
+		t.Errorf("-4294967296 %s -1 = %d, want -4294967295", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -4294967297 {
+		t.Errorf("-4294967296 %s 1 = %d, want -4294967297", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != -8589934592 {
+		t.Errorf("-4294967296 %s 4294967296 = %d, want -8589934592", "-", r)
+	}
+	y = 9223372036854775806
+	r = x - y
+	if r != 9223372032559808514 {
+		t.Errorf("-4294967296 %s 9223372036854775806 = %d, want 9223372032559808514", "-", r)
+	}
+	y = 9223372036854775807
+	r = x - y
+	if r != 9223372032559808513 {
+		t.Errorf("-4294967296 %s 9223372036854775807 = %d, want 9223372032559808513", "-", r)
+	}
+	x = -1
+	y = -9223372036854775808
+	r = x - y
+	if r != 9223372036854775807 {
+		t.Errorf("-1 %s -9223372036854775808 = %d, want 9223372036854775807", "-", r)
+	}
+	y = -9223372036854775807
+	r = x - y
+	if r != 9223372036854775806 {
+		t.Errorf("-1 %s -9223372036854775807 = %d, want 9223372036854775806", "-", r)
+	}
+	y = -4294967296
+	r = x - y
+	if r != 4294967295 {
+		t.Errorf("-1 %s -4294967296 = %d, want 4294967295", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 0 {
+		t.Errorf("-1 %s -1 = %d, want 0", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != -4294967297 {
+		t.Errorf("-1 %s 4294967296 = %d, want -4294967297", "-", r)
+	}
+	y = 9223372036854775806
+	r = x - y
+	if r != -9223372036854775807 {
+		t.Errorf("-1 %s 9223372036854775806 = %d, want -9223372036854775807", "-", r)
+	}
+	y = 9223372036854775807
+	r = x - y
+	if r != -9223372036854775808 {
+		t.Errorf("-1 %s 9223372036854775807 = %d, want -9223372036854775808", "-", r)
+	}
+	x = 0
+	y = -9223372036854775808
+	r = x - y
+	if r != -9223372036854775808 {
+		t.Errorf("0 %s -9223372036854775808 = %d, want -9223372036854775808", "-", r)
+	}
+	y = -9223372036854775807
+	r = x - y
+	if r != 9223372036854775807 {
+		t.Errorf("0 %s -9223372036854775807 = %d, want 9223372036854775807", "-", r)
+	}
+	y = -4294967296
+	r = x - y
+	if r != 4294967296 {
+		t.Errorf("0 %s -4294967296 = %d, want 4294967296", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 1 {
+		t.Errorf("0 %s -1 = %d, want 1", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -1 {
+		t.Errorf("0 %s 1 = %d, want -1", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != -4294967296 {
+		t.Errorf("0 %s 4294967296 = %d, want -4294967296", "-", r)
+	}
+	y = 9223372036854775806
+	r = x - y
+	if r != -9223372036854775806 {
+		t.Errorf("0 %s 9223372036854775806 = %d, want -9223372036854775806", "-", r)
+	}
+	y = 9223372036854775807
+	r = x - y
+	if r != -9223372036854775807 {
+		t.Errorf("0 %s 9223372036854775807 = %d, want -9223372036854775807", "-", r)
+	}
+	x = 1
+	y = -9223372036854775808
+	r = x - y
+	if r != -9223372036854775807 {
+		t.Errorf("1 %s -9223372036854775808 = %d, want -9223372036854775807", "-", r)
+	}
+	y = -9223372036854775807
+	r = x - y
+	if r != -9223372036854775808 {
+		t.Errorf("1 %s -9223372036854775807 = %d, want -9223372036854775808", "-", r)
+	}
+	y = -4294967296
+	r = x - y
+	if r != 4294967297 {
+		t.Errorf("1 %s -4294967296 = %d, want 4294967297", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 2 {
+		t.Errorf("1 %s -1 = %d, want 2", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != -4294967295 {
+		t.Errorf("1 %s 4294967296 = %d, want -4294967295", "-", r)
+	}
+	y = 9223372036854775806
+	r = x - y
+	if r != -9223372036854775805 {
+		t.Errorf("1 %s 9223372036854775806 = %d, want -9223372036854775805", "-", r)
+	}
+	y = 9223372036854775807
+	r = x - y
+	if r != -9223372036854775806 {
+		t.Errorf("1 %s 9223372036854775807 = %d, want -9223372036854775806", "-", r)
+	}
+	x = 4294967296
+	y = -9223372036854775808
+	r = x - y
+	if r != -9223372032559808512 {
+		t.Errorf("4294967296 %s -9223372036854775808 = %d, want -9223372032559808512", "-", r)
+	}
+	y = -9223372036854775807
+	r = x - y
+	if r != -9223372032559808513 {
+		t.Errorf("4294967296 %s -9223372036854775807 = %d, want -9223372032559808513", "-", r)
+	}
+	y = -4294967296
+	r = x - y
+	if r != 8589934592 {
+		t.Errorf("4294967296 %s -4294967296 = %d, want 8589934592", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 4294967297 {
+		t.Errorf("4294967296 %s -1 = %d, want 4294967297", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 4294967295 {
+		t.Errorf("4294967296 %s 1 = %d, want 4294967295", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "-", r)
+	}
+	y = 9223372036854775806
+	r = x - y
+	if r != -9223372032559808510 {
+		t.Errorf("4294967296 %s 9223372036854775806 = %d, want -9223372032559808510", "-", r)
+	}
+	y = 9223372036854775807
+	r = x - y
+	if r != -9223372032559808511 {
+		t.Errorf("4294967296 %s 9223372036854775807 = %d, want -9223372032559808511", "-", r)
+	}
+	x = 9223372036854775806
+	y = -9223372036854775808
+	r = x - y
+	if r != -2 {
+		t.Errorf("9223372036854775806 %s -9223372036854775808 = %d, want -2", "-", r)
+	}
+	y = -9223372036854775807
+	r = x - y
+	if r != -3 {
+		t.Errorf("9223372036854775806 %s -9223372036854775807 = %d, want -3", "-", r)
+	}
+	y = -4294967296
+	r = x - y
+	if r != -9223372032559808514 {
+		t.Errorf("9223372036854775806 %s -4294967296 = %d, want -9223372032559808514", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775806 %s -1 = %d, want 9223372036854775807", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 9223372036854775805 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want 9223372036854775805", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != 9223372032559808510 {
+		t.Errorf("9223372036854775806 %s 4294967296 = %d, want 9223372032559808510", "-", r)
+	}
+	y = 9223372036854775806
+	r = x - y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 9223372036854775806 = %d, want 0", "-", r)
+	}
+	y = 9223372036854775807
+	r = x - y
+	if r != -1 {
+		t.Errorf("9223372036854775806 %s 9223372036854775807 = %d, want -1", "-", r)
+	}
+	x = 9223372036854775807
+	y = -9223372036854775808
+	r = x - y
+	if r != -1 {
+		t.Errorf("9223372036854775807 %s -9223372036854775808 = %d, want -1", "-", r)
+	}
+	y = -9223372036854775807
+	r = x - y
+	if r != -2 {
+		t.Errorf("9223372036854775807 %s -9223372036854775807 = %d, want -2", "-", r)
+	}
+	y = -4294967296
+	r = x - y
+	if r != -9223372032559808513 {
+		t.Errorf("9223372036854775807 %s -4294967296 = %d, want -9223372032559808513", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -9223372036854775808 {
+		t.Errorf("9223372036854775807 %s -1 = %d, want -9223372036854775808", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want 9223372036854775806", "-", r)
+	}
+	y = 4294967296
+	r = x - y
+	if r != 9223372032559808511 {
+		t.Errorf("9223372036854775807 %s 4294967296 = %d, want 9223372032559808511", "-", r)
+	}
+	y = 9223372036854775806
+	r = x - y
+	if r != 1 {
+		t.Errorf("9223372036854775807 %s 9223372036854775806 = %d, want 1", "-", r)
+	}
+	y = 9223372036854775807
+	r = x - y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 9223372036854775807 = %d, want 0", "-", r)
+	}
+}
+func TestConstFoldint64div(t *testing.T) {
+	var x, y, r int64
+	x = -9223372036854775808
+	y = -9223372036854775808
+	r = x / y
+	if r != 1 {
+		t.Errorf("-9223372036854775808 %s -9223372036854775808 = %d, want 1", "/", r)
+	}
+	y = -9223372036854775807
+	r = x / y
+	if r != 1 {
+		t.Errorf("-9223372036854775808 %s -9223372036854775807 = %d, want 1", "/", r)
+	}
+	y = -4294967296
+	r = x / y
+	if r != 2147483648 {
+		t.Errorf("-9223372036854775808 %s -4294967296 = %d, want 2147483648", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s -1 = %d, want -9223372036854775808", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want -9223372036854775808", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != -2147483648 {
+		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want -2147483648", "/", r)
+	}
+	y = 9223372036854775806
+	r = x / y
+	if r != -1 {
+		t.Errorf("-9223372036854775808 %s 9223372036854775806 = %d, want -1", "/", r)
+	}
+	y = 9223372036854775807
+	r = x / y
+	if r != -1 {
+		t.Errorf("-9223372036854775808 %s 9223372036854775807 = %d, want -1", "/", r)
+	}
+	x = -9223372036854775807
+	y = -9223372036854775808
+	r = x / y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s -9223372036854775808 = %d, want 0", "/", r)
+	}
+	y = -9223372036854775807
+	r = x / y
+	if r != 1 {
+		t.Errorf("-9223372036854775807 %s -9223372036854775807 = %d, want 1", "/", r)
+	}
+	y = -4294967296
+	r = x / y
+	if r != 2147483647 {
+		t.Errorf("-9223372036854775807 %s -4294967296 = %d, want 2147483647", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s -1 = %d, want 9223372036854775807", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want -9223372036854775807", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != -2147483647 {
+		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want -2147483647", "/", r)
+	}
+	y = 9223372036854775806
+	r = x / y
+	if r != -1 {
+		t.Errorf("-9223372036854775807 %s 9223372036854775806 = %d, want -1", "/", r)
+	}
+	y = 9223372036854775807
+	r = x / y
+	if r != -1 {
+		t.Errorf("-9223372036854775807 %s 9223372036854775807 = %d, want -1", "/", r)
+	}
+	x = -4294967296
+	y = -9223372036854775808
+	r = x / y
+	if r != 0 {
+		t.Errorf("-4294967296 %s -9223372036854775808 = %d, want 0", "/", r)
+	}
+	y = -9223372036854775807
+	r = x / y
+	if r != 0 {
+		t.Errorf("-4294967296 %s -9223372036854775807 = %d, want 0", "/", r)
+	}
+	y = -4294967296
+	r = x / y
+	if r != 1 {
+		t.Errorf("-4294967296 %s -4294967296 = %d, want 1", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 4294967296 {
+		t.Errorf("-4294967296 %s -1 = %d, want 4294967296", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 1 = %d, want -4294967296", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != -1 {
+		t.Errorf("-4294967296 %s 4294967296 = %d, want -1", "/", r)
+	}
+	y = 9223372036854775806
+	r = x / y
+	if r != 0 {
+		t.Errorf("-4294967296 %s 9223372036854775806 = %d, want 0", "/", r)
+	}
+	y = 9223372036854775807
+	r = x / y
+	if r != 0 {
+		t.Errorf("-4294967296 %s 9223372036854775807 = %d, want 0", "/", r)
+	}
+	x = -1
+	y = -9223372036854775808
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s -9223372036854775808 = %d, want 0", "/", r)
+	}
+	y = -9223372036854775807
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s -9223372036854775807 = %d, want 0", "/", r)
+	}
+	y = -4294967296
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s -4294967296 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 1 {
+		t.Errorf("-1 %s -1 = %d, want 1", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s 4294967296 = %d, want 0", "/", r)
+	}
+	y = 9223372036854775806
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s 9223372036854775806 = %d, want 0", "/", r)
+	}
+	y = 9223372036854775807
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s 9223372036854775807 = %d, want 0", "/", r)
+	}
+	x = 0
+	y = -9223372036854775808
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -9223372036854775808 = %d, want 0", "/", r)
+	}
+	y = -9223372036854775807
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -9223372036854775807 = %d, want 0", "/", r)
+	}
+	y = -4294967296
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -4294967296 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -1 = %d, want 0", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "/", r)
+	}
+	y = 9223372036854775806
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 9223372036854775806 = %d, want 0", "/", r)
+	}
+	y = 9223372036854775807
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 9223372036854775807 = %d, want 0", "/", r)
+	}
+	x = 1
+	y = -9223372036854775808
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s -9223372036854775808 = %d, want 0", "/", r)
+	}
+	y = -9223372036854775807
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s -9223372036854775807 = %d, want 0", "/", r)
+	}
+	y = -4294967296
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s -4294967296 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -1 {
+		t.Errorf("1 %s -1 = %d, want -1", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", "/", r)
+	}
+	y = 9223372036854775806
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 9223372036854775806 = %d, want 0", "/", r)
+	}
+	y = 9223372036854775807
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 9223372036854775807 = %d, want 0", "/", r)
+	}
+	x = 4294967296
+	y = -9223372036854775808
+	r = x / y
+	if r != 0 {
+		t.Errorf("4294967296 %s -9223372036854775808 = %d, want 0", "/", r)
+	}
+	y = -9223372036854775807
+	r = x / y
+	if r != 0 {
+		t.Errorf("4294967296 %s -9223372036854775807 = %d, want 0", "/", r)
+	}
+	y = -4294967296
+	r = x / y
+	if r != -1 {
+		t.Errorf("4294967296 %s -4294967296 = %d, want -1", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -4294967296 {
+		t.Errorf("4294967296 %s -1 = %d, want -4294967296", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 1 = %d, want 4294967296", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != 1 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 1", "/", r)
+	}
+	y = 9223372036854775806
+	r = x / y
+	if r != 0 {
+		t.Errorf("4294967296 %s 9223372036854775806 = %d, want 0", "/", r)
+	}
+	y = 9223372036854775807
+	r = x / y
+	if r != 0 {
+		t.Errorf("4294967296 %s 9223372036854775807 = %d, want 0", "/", r)
+	}
+	x = 9223372036854775806
+	y = -9223372036854775808
+	r = x / y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s -9223372036854775808 = %d, want 0", "/", r)
+	}
+	y = -9223372036854775807
+	r = x / y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s -9223372036854775807 = %d, want 0", "/", r)
+	}
+	y = -4294967296
+	r = x / y
+	if r != -2147483647 {
+		t.Errorf("9223372036854775806 %s -4294967296 = %d, want -2147483647", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -9223372036854775806 {
+		t.Errorf("9223372036854775806 %s -1 = %d, want -9223372036854775806", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want 9223372036854775806", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != 2147483647 {
+		t.Errorf("9223372036854775806 %s 4294967296 = %d, want 2147483647", "/", r)
+	}
+	y = 9223372036854775806
+	r = x / y
+	if r != 1 {
+		t.Errorf("9223372036854775806 %s 9223372036854775806 = %d, want 1", "/", r)
+	}
+	y = 9223372036854775807
+	r = x / y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 9223372036854775807 = %d, want 0", "/", r)
+	}
+	x = 9223372036854775807
+	y = -9223372036854775808
+	r = x / y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s -9223372036854775808 = %d, want 0", "/", r)
+	}
+	y = -9223372036854775807
+	r = x / y
+	if r != -1 {
+		t.Errorf("9223372036854775807 %s -9223372036854775807 = %d, want -1", "/", r)
+	}
+	y = -4294967296
+	r = x / y
+	if r != -2147483647 {
+		t.Errorf("9223372036854775807 %s -4294967296 = %d, want -2147483647", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -9223372036854775807 {
+		t.Errorf("9223372036854775807 %s -1 = %d, want -9223372036854775807", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want 9223372036854775807", "/", r)
+	}
+	y = 4294967296
+	r = x / y
+	if r != 2147483647 {
+		t.Errorf("9223372036854775807 %s 4294967296 = %d, want 2147483647", "/", r)
+	}
+	y = 9223372036854775806
+	r = x / y
+	if r != 1 {
+		t.Errorf("9223372036854775807 %s 9223372036854775806 = %d, want 1", "/", r)
+	}
+	y = 9223372036854775807
+	r = x / y
+	if r != 1 {
+		t.Errorf("9223372036854775807 %s 9223372036854775807 = %d, want 1", "/", r)
+	}
+}
+func TestConstFoldint64mul(t *testing.T) {
+	var x, y, r int64
+	x = -9223372036854775808
+	y = -9223372036854775808
+	r = x * y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s -9223372036854775808 = %d, want 0", "*", r)
+	}
+	y = -9223372036854775807
+	r = x * y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s -9223372036854775807 = %d, want -9223372036854775808", "*", r)
+	}
+	y = -4294967296
+	r = x * y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s -4294967296 = %d, want 0", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s -1 = %d, want -9223372036854775808", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want -9223372036854775808", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want 0", "*", r)
+	}
+	y = 9223372036854775806
+	r = x * y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 9223372036854775806 = %d, want 0", "*", r)
+	}
+	y = 9223372036854775807
+	r = x * y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 9223372036854775807 = %d, want -9223372036854775808", "*", r)
+	}
+	x = -9223372036854775807
+	y = -9223372036854775808
+	r = x * y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775807 %s -9223372036854775808 = %d, want -9223372036854775808", "*", r)
+	}
+	y = -9223372036854775807
+	r = x * y
+	if r != 1 {
+		t.Errorf("-9223372036854775807 %s -9223372036854775807 = %d, want 1", "*", r)
+	}
+	y = -4294967296
+	r = x * y
+	if r != -4294967296 {
+		t.Errorf("-9223372036854775807 %s -4294967296 = %d, want -4294967296", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s -1 = %d, want 9223372036854775807", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want -9223372036854775807", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != 4294967296 {
+		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want 4294967296", "*", r)
+	}
+	y = 9223372036854775806
+	r = x * y
+	if r != 9223372036854775806 {
+		t.Errorf("-9223372036854775807 %s 9223372036854775806 = %d, want 9223372036854775806", "*", r)
+	}
+	y = 9223372036854775807
+	r = x * y
+	if r != -1 {
+		t.Errorf("-9223372036854775807 %s 9223372036854775807 = %d, want -1", "*", r)
+	}
+	x = -4294967296
+	y = -9223372036854775808
+	r = x * y
+	if r != 0 {
+		t.Errorf("-4294967296 %s -9223372036854775808 = %d, want 0", "*", r)
+	}
+	y = -9223372036854775807
+	r = x * y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s -9223372036854775807 = %d, want -4294967296", "*", r)
+	}
+	y = -4294967296
+	r = x * y
+	if r != 0 {
+		t.Errorf("-4294967296 %s -4294967296 = %d, want 0", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 4294967296 {
+		t.Errorf("-4294967296 %s -1 = %d, want 4294967296", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-4294967296 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 1 = %d, want -4294967296", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != 0 {
+		t.Errorf("-4294967296 %s 4294967296 = %d, want 0", "*", r)
+	}
+	y = 9223372036854775806
+	r = x * y
+	if r != 8589934592 {
+		t.Errorf("-4294967296 %s 9223372036854775806 = %d, want 8589934592", "*", r)
+	}
+	y = 9223372036854775807
+	r = x * y
+	if r != 4294967296 {
+		t.Errorf("-4294967296 %s 9223372036854775807 = %d, want 4294967296", "*", r)
+	}
+	x = -1
+	y = -9223372036854775808
+	r = x * y
+	if r != -9223372036854775808 {
+		t.Errorf("-1 %s -9223372036854775808 = %d, want -9223372036854775808", "*", r)
+	}
+	y = -9223372036854775807
+	r = x * y
+	if r != 9223372036854775807 {
+		t.Errorf("-1 %s -9223372036854775807 = %d, want 9223372036854775807", "*", r)
+	}
+	y = -4294967296
+	r = x * y
+	if r != 4294967296 {
+		t.Errorf("-1 %s -4294967296 = %d, want 4294967296", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 1 {
+		t.Errorf("-1 %s -1 = %d, want 1", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-1 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != -4294967296 {
+		t.Errorf("-1 %s 4294967296 = %d, want -4294967296", "*", r)
+	}
+	y = 9223372036854775806
+	r = x * y
+	if r != -9223372036854775806 {
+		t.Errorf("-1 %s 9223372036854775806 = %d, want -9223372036854775806", "*", r)
+	}
+	y = 9223372036854775807
+	r = x * y
+	if r != -9223372036854775807 {
+		t.Errorf("-1 %s 9223372036854775807 = %d, want -9223372036854775807", "*", r)
+	}
+	x = 0
+	y = -9223372036854775808
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -9223372036854775808 = %d, want 0", "*", r)
+	}
+	y = -9223372036854775807
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -9223372036854775807 = %d, want 0", "*", r)
+	}
+	y = -4294967296
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -4294967296 = %d, want 0", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -1 = %d, want 0", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "*", r)
+	}
+	y = 9223372036854775806
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 9223372036854775806 = %d, want 0", "*", r)
+	}
+	y = 9223372036854775807
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 9223372036854775807 = %d, want 0", "*", r)
+	}
+	x = 1
+	y = -9223372036854775808
+	r = x * y
+	if r != -9223372036854775808 {
+		t.Errorf("1 %s -9223372036854775808 = %d, want -9223372036854775808", "*", r)
+	}
+	y = -9223372036854775807
+	r = x * y
+	if r != -9223372036854775807 {
+		t.Errorf("1 %s -9223372036854775807 = %d, want -9223372036854775807", "*", r)
+	}
+	y = -4294967296
+	r = x * y
+	if r != -4294967296 {
+		t.Errorf("1 %s -4294967296 = %d, want -4294967296", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -1 {
+		t.Errorf("1 %s -1 = %d, want -1", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("1 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != 4294967296 {
+		t.Errorf("1 %s 4294967296 = %d, want 4294967296", "*", r)
+	}
+	y = 9223372036854775806
+	r = x * y
+	if r != 9223372036854775806 {
+		t.Errorf("1 %s 9223372036854775806 = %d, want 9223372036854775806", "*", r)
+	}
+	y = 9223372036854775807
+	r = x * y
+	if r != 9223372036854775807 {
+		t.Errorf("1 %s 9223372036854775807 = %d, want 9223372036854775807", "*", r)
+	}
+	x = 4294967296
+	y = -9223372036854775808
+	r = x * y
+	if r != 0 {
+		t.Errorf("4294967296 %s -9223372036854775808 = %d, want 0", "*", r)
+	}
+	y = -9223372036854775807
+	r = x * y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s -9223372036854775807 = %d, want 4294967296", "*", r)
+	}
+	y = -4294967296
+	r = x * y
+	if r != 0 {
+		t.Errorf("4294967296 %s -4294967296 = %d, want 0", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -4294967296 {
+		t.Errorf("4294967296 %s -1 = %d, want -4294967296", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("4294967296 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 1 = %d, want 4294967296", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "*", r)
+	}
+	y = 9223372036854775806
+	r = x * y
+	if r != -8589934592 {
+		t.Errorf("4294967296 %s 9223372036854775806 = %d, want -8589934592", "*", r)
+	}
+	y = 9223372036854775807
+	r = x * y
+	if r != -4294967296 {
+		t.Errorf("4294967296 %s 9223372036854775807 = %d, want -4294967296", "*", r)
+	}
+	x = 9223372036854775806
+	y = -9223372036854775808
+	r = x * y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s -9223372036854775808 = %d, want 0", "*", r)
+	}
+	y = -9223372036854775807
+	r = x * y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s -9223372036854775807 = %d, want 9223372036854775806", "*", r)
+	}
+	y = -4294967296
+	r = x * y
+	if r != 8589934592 {
+		t.Errorf("9223372036854775806 %s -4294967296 = %d, want 8589934592", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -9223372036854775806 {
+		t.Errorf("9223372036854775806 %s -1 = %d, want -9223372036854775806", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want 9223372036854775806", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != -8589934592 {
+		t.Errorf("9223372036854775806 %s 4294967296 = %d, want -8589934592", "*", r)
+	}
+	y = 9223372036854775806
+	r = x * y
+	if r != 4 {
+		t.Errorf("9223372036854775806 %s 9223372036854775806 = %d, want 4", "*", r)
+	}
+	y = 9223372036854775807
+	r = x * y
+	if r != -9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 9223372036854775807 = %d, want -9223372036854775806", "*", r)
+	}
+	x = 9223372036854775807
+	y = -9223372036854775808
+	r = x * y
+	if r != -9223372036854775808 {
+		t.Errorf("9223372036854775807 %s -9223372036854775808 = %d, want -9223372036854775808", "*", r)
+	}
+	y = -9223372036854775807
+	r = x * y
+	if r != -1 {
+		t.Errorf("9223372036854775807 %s -9223372036854775807 = %d, want -1", "*", r)
+	}
+	y = -4294967296
+	r = x * y
+	if r != 4294967296 {
+		t.Errorf("9223372036854775807 %s -4294967296 = %d, want 4294967296", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -9223372036854775807 {
+		t.Errorf("9223372036854775807 %s -1 = %d, want -9223372036854775807", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want 9223372036854775807", "*", r)
+	}
+	y = 4294967296
+	r = x * y
+	if r != -4294967296 {
+		t.Errorf("9223372036854775807 %s 4294967296 = %d, want -4294967296", "*", r)
+	}
+	y = 9223372036854775806
+	r = x * y
+	if r != -9223372036854775806 {
+		t.Errorf("9223372036854775807 %s 9223372036854775806 = %d, want -9223372036854775806", "*", r)
+	}
+	y = 9223372036854775807
+	r = x * y
+	if r != 1 {
+		t.Errorf("9223372036854775807 %s 9223372036854775807 = %d, want 1", "*", r)
+	}
+}
+func TestConstFoldint64mod(t *testing.T) {
+	var x, y, r int64
+	x = -9223372036854775808
+	y = -9223372036854775808
+	r = x % y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s -9223372036854775808 = %d, want 0", "%", r)
+	}
+	y = -9223372036854775807
+	r = x % y
+	if r != -1 {
+		t.Errorf("-9223372036854775808 %s -9223372036854775807 = %d, want -1", "%", r)
+	}
+	y = -4294967296
+	r = x % y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s -4294967296 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want 0", "%", r)
+	}
+	y = 9223372036854775806
+	r = x % y
+	if r != -2 {
+		t.Errorf("-9223372036854775808 %s 9223372036854775806 = %d, want -2", "%", r)
+	}
+	y = 9223372036854775807
+	r = x % y
+	if r != -1 {
+		t.Errorf("-9223372036854775808 %s 9223372036854775807 = %d, want -1", "%", r)
+	}
+	x = -9223372036854775807
+	y = -9223372036854775808
+	r = x % y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s -9223372036854775808 = %d, want -9223372036854775807", "%", r)
+	}
+	y = -9223372036854775807
+	r = x % y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s -9223372036854775807 = %d, want 0", "%", r)
+	}
+	y = -4294967296
+	r = x % y
+	if r != -4294967295 {
+		t.Errorf("-9223372036854775807 %s -4294967296 = %d, want -4294967295", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != -4294967295 {
+		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want -4294967295", "%", r)
+	}
+	y = 9223372036854775806
+	r = x % y
+	if r != -1 {
+		t.Errorf("-9223372036854775807 %s 9223372036854775806 = %d, want -1", "%", r)
+	}
+	y = 9223372036854775807
+	r = x % y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s 9223372036854775807 = %d, want 0", "%", r)
+	}
+	x = -4294967296
+	y = -9223372036854775808
+	r = x % y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s -9223372036854775808 = %d, want -4294967296", "%", r)
+	}
+	y = -9223372036854775807
+	r = x % y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s -9223372036854775807 = %d, want -4294967296", "%", r)
+	}
+	y = -4294967296
+	r = x % y
+	if r != 0 {
+		t.Errorf("-4294967296 %s -4294967296 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-4294967296 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-4294967296 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != 0 {
+		t.Errorf("-4294967296 %s 4294967296 = %d, want 0", "%", r)
+	}
+	y = 9223372036854775806
+	r = x % y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 9223372036854775806 = %d, want -4294967296", "%", r)
+	}
+	y = 9223372036854775807
+	r = x % y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 9223372036854775807 = %d, want -4294967296", "%", r)
+	}
+	x = -1
+	y = -9223372036854775808
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s -9223372036854775808 = %d, want -1", "%", r)
+	}
+	y = -9223372036854775807
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s -9223372036854775807 = %d, want -1", "%", r)
+	}
+	y = -4294967296
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s -4294967296 = %d, want -1", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-1 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-1 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s 4294967296 = %d, want -1", "%", r)
+	}
+	y = 9223372036854775806
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s 9223372036854775806 = %d, want -1", "%", r)
+	}
+	y = 9223372036854775807
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s 9223372036854775807 = %d, want -1", "%", r)
+	}
+	x = 0
+	y = -9223372036854775808
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -9223372036854775808 = %d, want 0", "%", r)
+	}
+	y = -9223372036854775807
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -9223372036854775807 = %d, want 0", "%", r)
+	}
+	y = -4294967296
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -4294967296 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "%", r)
+	}
+	y = 9223372036854775806
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 9223372036854775806 = %d, want 0", "%", r)
+	}
+	y = 9223372036854775807
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 9223372036854775807 = %d, want 0", "%", r)
+	}
+	x = 1
+	y = -9223372036854775808
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s -9223372036854775808 = %d, want 1", "%", r)
+	}
+	y = -9223372036854775807
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s -9223372036854775807 = %d, want 1", "%", r)
+	}
+	y = -4294967296
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s -4294967296 = %d, want 1", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("1 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 4294967296 = %d, want 1", "%", r)
+	}
+	y = 9223372036854775806
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 9223372036854775806 = %d, want 1", "%", r)
+	}
+	y = 9223372036854775807
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 9223372036854775807 = %d, want 1", "%", r)
+	}
+	x = 4294967296
+	y = -9223372036854775808
+	r = x % y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s -9223372036854775808 = %d, want 4294967296", "%", r)
+	}
+	y = -9223372036854775807
+	r = x % y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s -9223372036854775807 = %d, want 4294967296", "%", r)
+	}
+	y = -4294967296
+	r = x % y
+	if r != 0 {
+		t.Errorf("4294967296 %s -4294967296 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("4294967296 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("4294967296 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "%", r)
+	}
+	y = 9223372036854775806
+	r = x % y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 9223372036854775806 = %d, want 4294967296", "%", r)
+	}
+	y = 9223372036854775807
+	r = x % y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 9223372036854775807 = %d, want 4294967296", "%", r)
+	}
+	x = 9223372036854775806
+	y = -9223372036854775808
+	r = x % y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s -9223372036854775808 = %d, want 9223372036854775806", "%", r)
+	}
+	y = -9223372036854775807
+	r = x % y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s -9223372036854775807 = %d, want 9223372036854775806", "%", r)
+	}
+	y = -4294967296
+	r = x % y
+	if r != 4294967294 {
+		t.Errorf("9223372036854775806 %s -4294967296 = %d, want 4294967294", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != 4294967294 {
+		t.Errorf("9223372036854775806 %s 4294967296 = %d, want 4294967294", "%", r)
+	}
+	y = 9223372036854775806
+	r = x % y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 9223372036854775806 = %d, want 0", "%", r)
+	}
+	y = 9223372036854775807
+	r = x % y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 9223372036854775807 = %d, want 9223372036854775806", "%", r)
+	}
+	x = 9223372036854775807
+	y = -9223372036854775808
+	r = x % y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s -9223372036854775808 = %d, want 9223372036854775807", "%", r)
+	}
+	y = -9223372036854775807
+	r = x % y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s -9223372036854775807 = %d, want 0", "%", r)
+	}
+	y = -4294967296
+	r = x % y
+	if r != 4294967295 {
+		t.Errorf("9223372036854775807 %s -4294967296 = %d, want 4294967295", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967296
+	r = x % y
+	if r != 4294967295 {
+		t.Errorf("9223372036854775807 %s 4294967296 = %d, want 4294967295", "%", r)
+	}
+	y = 9223372036854775806
+	r = x % y
+	if r != 1 {
+		t.Errorf("9223372036854775807 %s 9223372036854775806 = %d, want 1", "%", r)
+	}
+	y = 9223372036854775807
+	r = x % y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 9223372036854775807 = %d, want 0", "%", r)
+	}
+}
+func TestConstFolduint32add(t *testing.T) {
+	var x, y, r uint32
+	x = 0
+	y = 0
+	r = x + y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 1 {
+		t.Errorf("0 %s 1 = %d, want 1", "+", r)
+	}
+	y = 4294967295
+	r = x + y
+	if r != 4294967295 {
+		t.Errorf("0 %s 4294967295 = %d, want 4294967295", "+", r)
+	}
+	x = 1
+	y = 0
+	r = x + y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "+", r)
+	}
+	y = 4294967295
+	r = x + y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", "+", r)
+	}
+	x = 4294967295
+	y = 0
+	r = x + y
+	if r != 4294967295 {
+		t.Errorf("4294967295 %s 0 = %d, want 4294967295", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 0 {
+		t.Errorf("4294967295 %s 1 = %d, want 0", "+", r)
+	}
+	y = 4294967295
+	r = x + y
+	if r != 4294967294 {
+		t.Errorf("4294967295 %s 4294967295 = %d, want 4294967294", "+", r)
+	}
+}
+func TestConstFolduint32sub(t *testing.T) {
+	var x, y, r uint32
+	x = 0
+	y = 0
+	r = x - y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 4294967295 {
+		t.Errorf("0 %s 1 = %d, want 4294967295", "-", r)
+	}
+	y = 4294967295
+	r = x - y
+	if r != 1 {
+		t.Errorf("0 %s 4294967295 = %d, want 1", "-", r)
+	}
+	x = 1
+	y = 0
+	r = x - y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "-", r)
+	}
+	y = 4294967295
+	r = x - y
+	if r != 2 {
+		t.Errorf("1 %s 4294967295 = %d, want 2", "-", r)
+	}
+	x = 4294967295
+	y = 0
+	r = x - y
+	if r != 4294967295 {
+		t.Errorf("4294967295 %s 0 = %d, want 4294967295", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 4294967294 {
+		t.Errorf("4294967295 %s 1 = %d, want 4294967294", "-", r)
+	}
+	y = 4294967295
+	r = x - y
+	if r != 0 {
+		t.Errorf("4294967295 %s 4294967295 = %d, want 0", "-", r)
+	}
+}
+func TestConstFolduint32div(t *testing.T) {
+	var x, y, r uint32
+	x = 0
+	y = 1
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "/", r)
+	}
+	y = 4294967295
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", "/", r)
+	}
+	x = 1
+	y = 1
+	r = x / y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "/", r)
+	}
+	y = 4294967295
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", "/", r)
+	}
+	x = 4294967295
+	y = 1
+	r = x / y
+	if r != 4294967295 {
+		t.Errorf("4294967295 %s 1 = %d, want 4294967295", "/", r)
+	}
+	y = 4294967295
+	r = x / y
+	if r != 1 {
+		t.Errorf("4294967295 %s 4294967295 = %d, want 1", "/", r)
+	}
+}
+func TestConstFolduint32mul(t *testing.T) {
+	var x, y, r uint32
+	x = 0
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "*", r)
+	}
+	y = 4294967295
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", "*", r)
+	}
+	x = 1
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("1 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "*", r)
+	}
+	y = 4294967295
+	r = x * y
+	if r != 4294967295 {
+		t.Errorf("1 %s 4294967295 = %d, want 4294967295", "*", r)
+	}
+	x = 4294967295
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("4294967295 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 4294967295 {
+		t.Errorf("4294967295 %s 1 = %d, want 4294967295", "*", r)
+	}
+	y = 4294967295
+	r = x * y
+	if r != 1 {
+		t.Errorf("4294967295 %s 4294967295 = %d, want 1", "*", r)
+	}
+}
+func TestConstFolduint32mod(t *testing.T) {
+	var x, y, r uint32
+	x = 0
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967295
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", "%", r)
+	}
+	x = 1
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967295
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 4294967295 = %d, want 1", "%", r)
+	}
+	x = 4294967295
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("4294967295 %s 1 = %d, want 0", "%", r)
+	}
+	y = 4294967295
+	r = x % y
+	if r != 0 {
+		t.Errorf("4294967295 %s 4294967295 = %d, want 0", "%", r)
+	}
+}
+func TestConstFoldint32add(t *testing.T) {
+	var x, y, r int32
+	x = -2147483648
+	y = -2147483648
+	r = x + y
+	if r != 0 {
+		t.Errorf("-2147483648 %s -2147483648 = %d, want 0", "+", r)
+	}
+	y = -2147483647
+	r = x + y
+	if r != 1 {
+		t.Errorf("-2147483648 %s -2147483647 = %d, want 1", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 2147483647 {
+		t.Errorf("-2147483648 %s -1 = %d, want 2147483647", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -2147483647 {
+		t.Errorf("-2147483648 %s 1 = %d, want -2147483647", "+", r)
+	}
+	y = 2147483647
+	r = x + y
+	if r != -1 {
+		t.Errorf("-2147483648 %s 2147483647 = %d, want -1", "+", r)
+	}
+	x = -2147483647
+	y = -2147483648
+	r = x + y
+	if r != 1 {
+		t.Errorf("-2147483647 %s -2147483648 = %d, want 1", "+", r)
+	}
+	y = -2147483647
+	r = x + y
+	if r != 2 {
+		t.Errorf("-2147483647 %s -2147483647 = %d, want 2", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -2147483648 {
+		t.Errorf("-2147483647 %s -1 = %d, want -2147483648", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -2147483646 {
+		t.Errorf("-2147483647 %s 1 = %d, want -2147483646", "+", r)
+	}
+	y = 2147483647
+	r = x + y
+	if r != 0 {
+		t.Errorf("-2147483647 %s 2147483647 = %d, want 0", "+", r)
+	}
+	x = -1
+	y = -2147483648
+	r = x + y
+	if r != 2147483647 {
+		t.Errorf("-1 %s -2147483648 = %d, want 2147483647", "+", r)
+	}
+	y = -2147483647
+	r = x + y
+	if r != -2147483648 {
+		t.Errorf("-1 %s -2147483647 = %d, want -2147483648", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -2 {
+		t.Errorf("-1 %s -1 = %d, want -2", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 0 {
+		t.Errorf("-1 %s 1 = %d, want 0", "+", r)
+	}
+	y = 2147483647
+	r = x + y
+	if r != 2147483646 {
+		t.Errorf("-1 %s 2147483647 = %d, want 2147483646", "+", r)
+	}
+	x = 0
+	y = -2147483648
+	r = x + y
+	if r != -2147483648 {
+		t.Errorf("0 %s -2147483648 = %d, want -2147483648", "+", r)
+	}
+	y = -2147483647
+	r = x + y
+	if r != -2147483647 {
+		t.Errorf("0 %s -2147483647 = %d, want -2147483647", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -1 {
+		t.Errorf("0 %s -1 = %d, want -1", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 1 {
+		t.Errorf("0 %s 1 = %d, want 1", "+", r)
+	}
+	y = 2147483647
+	r = x + y
+	if r != 2147483647 {
+		t.Errorf("0 %s 2147483647 = %d, want 2147483647", "+", r)
+	}
+	x = 1
+	y = -2147483648
+	r = x + y
+	if r != -2147483647 {
+		t.Errorf("1 %s -2147483648 = %d, want -2147483647", "+", r)
+	}
+	y = -2147483647
+	r = x + y
+	if r != -2147483646 {
+		t.Errorf("1 %s -2147483647 = %d, want -2147483646", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 0 {
+		t.Errorf("1 %s -1 = %d, want 0", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "+", r)
+	}
+	y = 2147483647
+	r = x + y
+	if r != -2147483648 {
+		t.Errorf("1 %s 2147483647 = %d, want -2147483648", "+", r)
+	}
+	x = 2147483647
+	y = -2147483648
+	r = x + y
+	if r != -1 {
+		t.Errorf("2147483647 %s -2147483648 = %d, want -1", "+", r)
+	}
+	y = -2147483647
+	r = x + y
+	if r != 0 {
+		t.Errorf("2147483647 %s -2147483647 = %d, want 0", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 2147483646 {
+		t.Errorf("2147483647 %s -1 = %d, want 2147483646", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s 0 = %d, want 2147483647", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -2147483648 {
+		t.Errorf("2147483647 %s 1 = %d, want -2147483648", "+", r)
+	}
+	y = 2147483647
+	r = x + y
+	if r != -2 {
+		t.Errorf("2147483647 %s 2147483647 = %d, want -2", "+", r)
+	}
+}
+func TestConstFoldint32sub(t *testing.T) {
+	var x, y, r int32
+	x = -2147483648
+	y = -2147483648
+	r = x - y
+	if r != 0 {
+		t.Errorf("-2147483648 %s -2147483648 = %d, want 0", "-", r)
+	}
+	y = -2147483647
+	r = x - y
+	if r != -1 {
+		t.Errorf("-2147483648 %s -2147483647 = %d, want -1", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -2147483647 {
+		t.Errorf("-2147483648 %s -1 = %d, want -2147483647", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 2147483647 {
+		t.Errorf("-2147483648 %s 1 = %d, want 2147483647", "-", r)
+	}
+	y = 2147483647
+	r = x - y
+	if r != 1 {
+		t.Errorf("-2147483648 %s 2147483647 = %d, want 1", "-", r)
+	}
+	x = -2147483647
+	y = -2147483648
+	r = x - y
+	if r != 1 {
+		t.Errorf("-2147483647 %s -2147483648 = %d, want 1", "-", r)
+	}
+	y = -2147483647
+	r = x - y
+	if r != 0 {
+		t.Errorf("-2147483647 %s -2147483647 = %d, want 0", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -2147483646 {
+		t.Errorf("-2147483647 %s -1 = %d, want -2147483646", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -2147483648 {
+		t.Errorf("-2147483647 %s 1 = %d, want -2147483648", "-", r)
+	}
+	y = 2147483647
+	r = x - y
+	if r != 2 {
+		t.Errorf("-2147483647 %s 2147483647 = %d, want 2", "-", r)
+	}
+	x = -1
+	y = -2147483648
+	r = x - y
+	if r != 2147483647 {
+		t.Errorf("-1 %s -2147483648 = %d, want 2147483647", "-", r)
+	}
+	y = -2147483647
+	r = x - y
+	if r != 2147483646 {
+		t.Errorf("-1 %s -2147483647 = %d, want 2147483646", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 0 {
+		t.Errorf("-1 %s -1 = %d, want 0", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "-", r)
+	}
+	y = 2147483647
+	r = x - y
+	if r != -2147483648 {
+		t.Errorf("-1 %s 2147483647 = %d, want -2147483648", "-", r)
+	}
+	x = 0
+	y = -2147483648
+	r = x - y
+	if r != -2147483648 {
+		t.Errorf("0 %s -2147483648 = %d, want -2147483648", "-", r)
+	}
+	y = -2147483647
+	r = x - y
+	if r != 2147483647 {
+		t.Errorf("0 %s -2147483647 = %d, want 2147483647", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 1 {
+		t.Errorf("0 %s -1 = %d, want 1", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -1 {
+		t.Errorf("0 %s 1 = %d, want -1", "-", r)
+	}
+	y = 2147483647
+	r = x - y
+	if r != -2147483647 {
+		t.Errorf("0 %s 2147483647 = %d, want -2147483647", "-", r)
+	}
+	x = 1
+	y = -2147483648
+	r = x - y
+	if r != -2147483647 {
+		t.Errorf("1 %s -2147483648 = %d, want -2147483647", "-", r)
+	}
+	y = -2147483647
+	r = x - y
+	if r != -2147483648 {
+		t.Errorf("1 %s -2147483647 = %d, want -2147483648", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 2 {
+		t.Errorf("1 %s -1 = %d, want 2", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "-", r)
+	}
+	y = 2147483647
+	r = x - y
+	if r != -2147483646 {
+		t.Errorf("1 %s 2147483647 = %d, want -2147483646", "-", r)
+	}
+	x = 2147483647
+	y = -2147483648
+	r = x - y
+	if r != -1 {
+		t.Errorf("2147483647 %s -2147483648 = %d, want -1", "-", r)
+	}
+	y = -2147483647
+	r = x - y
+	if r != -2 {
+		t.Errorf("2147483647 %s -2147483647 = %d, want -2", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -2147483648 {
+		t.Errorf("2147483647 %s -1 = %d, want -2147483648", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s 0 = %d, want 2147483647", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 2147483646 {
+		t.Errorf("2147483647 %s 1 = %d, want 2147483646", "-", r)
+	}
+	y = 2147483647
+	r = x - y
+	if r != 0 {
+		t.Errorf("2147483647 %s 2147483647 = %d, want 0", "-", r)
+	}
+}
+func TestConstFoldint32div(t *testing.T) {
+	var x, y, r int32
+	x = -2147483648
+	y = -2147483648
+	r = x / y
+	if r != 1 {
+		t.Errorf("-2147483648 %s -2147483648 = %d, want 1", "/", r)
+	}
+	y = -2147483647
+	r = x / y
+	if r != 1 {
+		t.Errorf("-2147483648 %s -2147483647 = %d, want 1", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s -1 = %d, want -2147483648", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 1 = %d, want -2147483648", "/", r)
+	}
+	y = 2147483647
+	r = x / y
+	if r != -1 {
+		t.Errorf("-2147483648 %s 2147483647 = %d, want -1", "/", r)
+	}
+	x = -2147483647
+	y = -2147483648
+	r = x / y
+	if r != 0 {
+		t.Errorf("-2147483647 %s -2147483648 = %d, want 0", "/", r)
+	}
+	y = -2147483647
+	r = x / y
+	if r != 1 {
+		t.Errorf("-2147483647 %s -2147483647 = %d, want 1", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 2147483647 {
+		t.Errorf("-2147483647 %s -1 = %d, want 2147483647", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s 1 = %d, want -2147483647", "/", r)
+	}
+	y = 2147483647
+	r = x / y
+	if r != -1 {
+		t.Errorf("-2147483647 %s 2147483647 = %d, want -1", "/", r)
+	}
+	x = -1
+	y = -2147483648
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s -2147483648 = %d, want 0", "/", r)
+	}
+	y = -2147483647
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s -2147483647 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 1 {
+		t.Errorf("-1 %s -1 = %d, want 1", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", "/", r)
+	}
+	y = 2147483647
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s 2147483647 = %d, want 0", "/", r)
+	}
+	x = 0
+	y = -2147483648
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -2147483648 = %d, want 0", "/", r)
+	}
+	y = -2147483647
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -2147483647 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -1 = %d, want 0", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "/", r)
+	}
+	y = 2147483647
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 2147483647 = %d, want 0", "/", r)
+	}
+	x = 1
+	y = -2147483648
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s -2147483648 = %d, want 0", "/", r)
+	}
+	y = -2147483647
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s -2147483647 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -1 {
+		t.Errorf("1 %s -1 = %d, want -1", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "/", r)
+	}
+	y = 2147483647
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 2147483647 = %d, want 0", "/", r)
+	}
+	x = 2147483647
+	y = -2147483648
+	r = x / y
+	if r != 0 {
+		t.Errorf("2147483647 %s -2147483648 = %d, want 0", "/", r)
+	}
+	y = -2147483647
+	r = x / y
+	if r != -1 {
+		t.Errorf("2147483647 %s -2147483647 = %d, want -1", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -2147483647 {
+		t.Errorf("2147483647 %s -1 = %d, want -2147483647", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s 1 = %d, want 2147483647", "/", r)
+	}
+	y = 2147483647
+	r = x / y
+	if r != 1 {
+		t.Errorf("2147483647 %s 2147483647 = %d, want 1", "/", r)
+	}
+}
+func TestConstFoldint32mul(t *testing.T) {
+	var x, y, r int32
+	x = -2147483648
+	y = -2147483648
+	r = x * y
+	if r != 0 {
+		t.Errorf("-2147483648 %s -2147483648 = %d, want 0", "*", r)
+	}
+	y = -2147483647
+	r = x * y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s -2147483647 = %d, want -2147483648", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s -1 = %d, want -2147483648", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-2147483648 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 1 = %d, want -2147483648", "*", r)
+	}
+	y = 2147483647
+	r = x * y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 2147483647 = %d, want -2147483648", "*", r)
+	}
+	x = -2147483647
+	y = -2147483648
+	r = x * y
+	if r != -2147483648 {
+		t.Errorf("-2147483647 %s -2147483648 = %d, want -2147483648", "*", r)
+	}
+	y = -2147483647
+	r = x * y
+	if r != 1 {
+		t.Errorf("-2147483647 %s -2147483647 = %d, want 1", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 2147483647 {
+		t.Errorf("-2147483647 %s -1 = %d, want 2147483647", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-2147483647 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s 1 = %d, want -2147483647", "*", r)
+	}
+	y = 2147483647
+	r = x * y
+	if r != -1 {
+		t.Errorf("-2147483647 %s 2147483647 = %d, want -1", "*", r)
+	}
+	x = -1
+	y = -2147483648
+	r = x * y
+	if r != -2147483648 {
+		t.Errorf("-1 %s -2147483648 = %d, want -2147483648", "*", r)
+	}
+	y = -2147483647
+	r = x * y
+	if r != 2147483647 {
+		t.Errorf("-1 %s -2147483647 = %d, want 2147483647", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 1 {
+		t.Errorf("-1 %s -1 = %d, want 1", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-1 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", "*", r)
+	}
+	y = 2147483647
+	r = x * y
+	if r != -2147483647 {
+		t.Errorf("-1 %s 2147483647 = %d, want -2147483647", "*", r)
+	}
+	x = 0
+	y = -2147483648
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -2147483648 = %d, want 0", "*", r)
+	}
+	y = -2147483647
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -2147483647 = %d, want 0", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -1 = %d, want 0", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "*", r)
+	}
+	y = 2147483647
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 2147483647 = %d, want 0", "*", r)
+	}
+	x = 1
+	y = -2147483648
+	r = x * y
+	if r != -2147483648 {
+		t.Errorf("1 %s -2147483648 = %d, want -2147483648", "*", r)
+	}
+	y = -2147483647
+	r = x * y
+	if r != -2147483647 {
+		t.Errorf("1 %s -2147483647 = %d, want -2147483647", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -1 {
+		t.Errorf("1 %s -1 = %d, want -1", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("1 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "*", r)
+	}
+	y = 2147483647
+	r = x * y
+	if r != 2147483647 {
+		t.Errorf("1 %s 2147483647 = %d, want 2147483647", "*", r)
+	}
+	x = 2147483647
+	y = -2147483648
+	r = x * y
+	if r != -2147483648 {
+		t.Errorf("2147483647 %s -2147483648 = %d, want -2147483648", "*", r)
+	}
+	y = -2147483647
+	r = x * y
+	if r != -1 {
+		t.Errorf("2147483647 %s -2147483647 = %d, want -1", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -2147483647 {
+		t.Errorf("2147483647 %s -1 = %d, want -2147483647", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("2147483647 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s 1 = %d, want 2147483647", "*", r)
+	}
+	y = 2147483647
+	r = x * y
+	if r != 1 {
+		t.Errorf("2147483647 %s 2147483647 = %d, want 1", "*", r)
+	}
+}
+func TestConstFoldint32mod(t *testing.T) {
+	var x, y, r int32
+	x = -2147483648
+	y = -2147483648
+	r = x % y
+	if r != 0 {
+		t.Errorf("-2147483648 %s -2147483648 = %d, want 0", "%", r)
+	}
+	y = -2147483647
+	r = x % y
+	if r != -1 {
+		t.Errorf("-2147483648 %s -2147483647 = %d, want -1", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-2147483648 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-2147483648 %s 1 = %d, want 0", "%", r)
+	}
+	y = 2147483647
+	r = x % y
+	if r != -1 {
+		t.Errorf("-2147483648 %s 2147483647 = %d, want -1", "%", r)
+	}
+	x = -2147483647
+	y = -2147483648
+	r = x % y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s -2147483648 = %d, want -2147483647", "%", r)
+	}
+	y = -2147483647
+	r = x % y
+	if r != 0 {
+		t.Errorf("-2147483647 %s -2147483647 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-2147483647 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-2147483647 %s 1 = %d, want 0", "%", r)
+	}
+	y = 2147483647
+	r = x % y
+	if r != 0 {
+		t.Errorf("-2147483647 %s 2147483647 = %d, want 0", "%", r)
+	}
+	x = -1
+	y = -2147483648
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s -2147483648 = %d, want -1", "%", r)
+	}
+	y = -2147483647
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s -2147483647 = %d, want -1", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-1 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-1 %s 1 = %d, want 0", "%", r)
+	}
+	y = 2147483647
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s 2147483647 = %d, want -1", "%", r)
+	}
+	x = 0
+	y = -2147483648
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -2147483648 = %d, want 0", "%", r)
+	}
+	y = -2147483647
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -2147483647 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "%", r)
+	}
+	y = 2147483647
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 2147483647 = %d, want 0", "%", r)
+	}
+	x = 1
+	y = -2147483648
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s -2147483648 = %d, want 1", "%", r)
+	}
+	y = -2147483647
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s -2147483647 = %d, want 1", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("1 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "%", r)
+	}
+	y = 2147483647
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 2147483647 = %d, want 1", "%", r)
+	}
+	x = 2147483647
+	y = -2147483648
+	r = x % y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s -2147483648 = %d, want 2147483647", "%", r)
+	}
+	y = -2147483647
+	r = x % y
+	if r != 0 {
+		t.Errorf("2147483647 %s -2147483647 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("2147483647 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("2147483647 %s 1 = %d, want 0", "%", r)
+	}
+	y = 2147483647
+	r = x % y
+	if r != 0 {
+		t.Errorf("2147483647 %s 2147483647 = %d, want 0", "%", r)
+	}
+}
+func TestConstFolduint16add(t *testing.T) {
+	var x, y, r uint16
+	x = 0
+	y = 0
+	r = x + y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 1 {
+		t.Errorf("0 %s 1 = %d, want 1", "+", r)
+	}
+	y = 65535
+	r = x + y
+	if r != 65535 {
+		t.Errorf("0 %s 65535 = %d, want 65535", "+", r)
+	}
+	x = 1
+	y = 0
+	r = x + y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "+", r)
+	}
+	y = 65535
+	r = x + y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", "+", r)
+	}
+	x = 65535
+	y = 0
+	r = x + y
+	if r != 65535 {
+		t.Errorf("65535 %s 0 = %d, want 65535", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 0 {
+		t.Errorf("65535 %s 1 = %d, want 0", "+", r)
+	}
+	y = 65535
+	r = x + y
+	if r != 65534 {
+		t.Errorf("65535 %s 65535 = %d, want 65534", "+", r)
+	}
+}
+func TestConstFolduint16sub(t *testing.T) {
+	var x, y, r uint16
+	x = 0
+	y = 0
+	r = x - y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 65535 {
+		t.Errorf("0 %s 1 = %d, want 65535", "-", r)
+	}
+	y = 65535
+	r = x - y
+	if r != 1 {
+		t.Errorf("0 %s 65535 = %d, want 1", "-", r)
+	}
+	x = 1
+	y = 0
+	r = x - y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "-", r)
+	}
+	y = 65535
+	r = x - y
+	if r != 2 {
+		t.Errorf("1 %s 65535 = %d, want 2", "-", r)
+	}
+	x = 65535
+	y = 0
+	r = x - y
+	if r != 65535 {
+		t.Errorf("65535 %s 0 = %d, want 65535", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 65534 {
+		t.Errorf("65535 %s 1 = %d, want 65534", "-", r)
+	}
+	y = 65535
+	r = x - y
+	if r != 0 {
+		t.Errorf("65535 %s 65535 = %d, want 0", "-", r)
+	}
+}
+func TestConstFolduint16div(t *testing.T) {
+	var x, y, r uint16
+	x = 0
+	y = 1
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "/", r)
+	}
+	y = 65535
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", "/", r)
+	}
+	x = 1
+	y = 1
+	r = x / y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "/", r)
+	}
+	y = 65535
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", "/", r)
+	}
+	x = 65535
+	y = 1
+	r = x / y
+	if r != 65535 {
+		t.Errorf("65535 %s 1 = %d, want 65535", "/", r)
+	}
+	y = 65535
+	r = x / y
+	if r != 1 {
+		t.Errorf("65535 %s 65535 = %d, want 1", "/", r)
+	}
+}
+func TestConstFolduint16mul(t *testing.T) {
+	var x, y, r uint16
+	x = 0
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "*", r)
+	}
+	y = 65535
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", "*", r)
+	}
+	x = 1
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("1 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "*", r)
+	}
+	y = 65535
+	r = x * y
+	if r != 65535 {
+		t.Errorf("1 %s 65535 = %d, want 65535", "*", r)
+	}
+	x = 65535
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("65535 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 65535 {
+		t.Errorf("65535 %s 1 = %d, want 65535", "*", r)
+	}
+	y = 65535
+	r = x * y
+	if r != 1 {
+		t.Errorf("65535 %s 65535 = %d, want 1", "*", r)
+	}
+}
+func TestConstFolduint16mod(t *testing.T) {
+	var x, y, r uint16
+	x = 0
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "%", r)
+	}
+	y = 65535
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", "%", r)
+	}
+	x = 1
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "%", r)
+	}
+	y = 65535
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 65535 = %d, want 1", "%", r)
+	}
+	x = 65535
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("65535 %s 1 = %d, want 0", "%", r)
+	}
+	y = 65535
+	r = x % y
+	if r != 0 {
+		t.Errorf("65535 %s 65535 = %d, want 0", "%", r)
+	}
+}
+func TestConstFoldint16add(t *testing.T) {
+	var x, y, r int16
+	x = -32768
+	y = -32768
+	r = x + y
+	if r != 0 {
+		t.Errorf("-32768 %s -32768 = %d, want 0", "+", r)
+	}
+	y = -32767
+	r = x + y
+	if r != 1 {
+		t.Errorf("-32768 %s -32767 = %d, want 1", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 32767 {
+		t.Errorf("-32768 %s -1 = %d, want 32767", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -32768 {
+		t.Errorf("-32768 %s 0 = %d, want -32768", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -32767 {
+		t.Errorf("-32768 %s 1 = %d, want -32767", "+", r)
+	}
+	y = 32766
+	r = x + y
+	if r != -2 {
+		t.Errorf("-32768 %s 32766 = %d, want -2", "+", r)
+	}
+	y = 32767
+	r = x + y
+	if r != -1 {
+		t.Errorf("-32768 %s 32767 = %d, want -1", "+", r)
+	}
+	x = -32767
+	y = -32768
+	r = x + y
+	if r != 1 {
+		t.Errorf("-32767 %s -32768 = %d, want 1", "+", r)
+	}
+	y = -32767
+	r = x + y
+	if r != 2 {
+		t.Errorf("-32767 %s -32767 = %d, want 2", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -32768 {
+		t.Errorf("-32767 %s -1 = %d, want -32768", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -32767 {
+		t.Errorf("-32767 %s 0 = %d, want -32767", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -32766 {
+		t.Errorf("-32767 %s 1 = %d, want -32766", "+", r)
+	}
+	y = 32766
+	r = x + y
+	if r != -1 {
+		t.Errorf("-32767 %s 32766 = %d, want -1", "+", r)
+	}
+	y = 32767
+	r = x + y
+	if r != 0 {
+		t.Errorf("-32767 %s 32767 = %d, want 0", "+", r)
+	}
+	x = -1
+	y = -32768
+	r = x + y
+	if r != 32767 {
+		t.Errorf("-1 %s -32768 = %d, want 32767", "+", r)
+	}
+	y = -32767
+	r = x + y
+	if r != -32768 {
+		t.Errorf("-1 %s -32767 = %d, want -32768", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -2 {
+		t.Errorf("-1 %s -1 = %d, want -2", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 0 {
+		t.Errorf("-1 %s 1 = %d, want 0", "+", r)
+	}
+	y = 32766
+	r = x + y
+	if r != 32765 {
+		t.Errorf("-1 %s 32766 = %d, want 32765", "+", r)
+	}
+	y = 32767
+	r = x + y
+	if r != 32766 {
+		t.Errorf("-1 %s 32767 = %d, want 32766", "+", r)
+	}
+	x = 0
+	y = -32768
+	r = x + y
+	if r != -32768 {
+		t.Errorf("0 %s -32768 = %d, want -32768", "+", r)
+	}
+	y = -32767
+	r = x + y
+	if r != -32767 {
+		t.Errorf("0 %s -32767 = %d, want -32767", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -1 {
+		t.Errorf("0 %s -1 = %d, want -1", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 1 {
+		t.Errorf("0 %s 1 = %d, want 1", "+", r)
+	}
+	y = 32766
+	r = x + y
+	if r != 32766 {
+		t.Errorf("0 %s 32766 = %d, want 32766", "+", r)
+	}
+	y = 32767
+	r = x + y
+	if r != 32767 {
+		t.Errorf("0 %s 32767 = %d, want 32767", "+", r)
+	}
+	x = 1
+	y = -32768
+	r = x + y
+	if r != -32767 {
+		t.Errorf("1 %s -32768 = %d, want -32767", "+", r)
+	}
+	y = -32767
+	r = x + y
+	if r != -32766 {
+		t.Errorf("1 %s -32767 = %d, want -32766", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 0 {
+		t.Errorf("1 %s -1 = %d, want 0", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "+", r)
+	}
+	y = 32766
+	r = x + y
+	if r != 32767 {
+		t.Errorf("1 %s 32766 = %d, want 32767", "+", r)
+	}
+	y = 32767
+	r = x + y
+	if r != -32768 {
+		t.Errorf("1 %s 32767 = %d, want -32768", "+", r)
+	}
+	x = 32766
+	y = -32768
+	r = x + y
+	if r != -2 {
+		t.Errorf("32766 %s -32768 = %d, want -2", "+", r)
+	}
+	y = -32767
+	r = x + y
+	if r != -1 {
+		t.Errorf("32766 %s -32767 = %d, want -1", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 32765 {
+		t.Errorf("32766 %s -1 = %d, want 32765", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 32766 {
+		t.Errorf("32766 %s 0 = %d, want 32766", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 32767 {
+		t.Errorf("32766 %s 1 = %d, want 32767", "+", r)
+	}
+	y = 32766
+	r = x + y
+	if r != -4 {
+		t.Errorf("32766 %s 32766 = %d, want -4", "+", r)
+	}
+	y = 32767
+	r = x + y
+	if r != -3 {
+		t.Errorf("32766 %s 32767 = %d, want -3", "+", r)
+	}
+	x = 32767
+	y = -32768
+	r = x + y
+	if r != -1 {
+		t.Errorf("32767 %s -32768 = %d, want -1", "+", r)
+	}
+	y = -32767
+	r = x + y
+	if r != 0 {
+		t.Errorf("32767 %s -32767 = %d, want 0", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 32766 {
+		t.Errorf("32767 %s -1 = %d, want 32766", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 32767 {
+		t.Errorf("32767 %s 0 = %d, want 32767", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -32768 {
+		t.Errorf("32767 %s 1 = %d, want -32768", "+", r)
+	}
+	y = 32766
+	r = x + y
+	if r != -3 {
+		t.Errorf("32767 %s 32766 = %d, want -3", "+", r)
+	}
+	y = 32767
+	r = x + y
+	if r != -2 {
+		t.Errorf("32767 %s 32767 = %d, want -2", "+", r)
+	}
+}
+func TestConstFoldint16sub(t *testing.T) {
+	var x, y, r int16
+	x = -32768
+	y = -32768
+	r = x - y
+	if r != 0 {
+		t.Errorf("-32768 %s -32768 = %d, want 0", "-", r)
+	}
+	y = -32767
+	r = x - y
+	if r != -1 {
+		t.Errorf("-32768 %s -32767 = %d, want -1", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -32767 {
+		t.Errorf("-32768 %s -1 = %d, want -32767", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -32768 {
+		t.Errorf("-32768 %s 0 = %d, want -32768", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 32767 {
+		t.Errorf("-32768 %s 1 = %d, want 32767", "-", r)
+	}
+	y = 32766
+	r = x - y
+	if r != 2 {
+		t.Errorf("-32768 %s 32766 = %d, want 2", "-", r)
+	}
+	y = 32767
+	r = x - y
+	if r != 1 {
+		t.Errorf("-32768 %s 32767 = %d, want 1", "-", r)
+	}
+	x = -32767
+	y = -32768
+	r = x - y
+	if r != 1 {
+		t.Errorf("-32767 %s -32768 = %d, want 1", "-", r)
+	}
+	y = -32767
+	r = x - y
+	if r != 0 {
+		t.Errorf("-32767 %s -32767 = %d, want 0", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -32766 {
+		t.Errorf("-32767 %s -1 = %d, want -32766", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -32767 {
+		t.Errorf("-32767 %s 0 = %d, want -32767", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -32768 {
+		t.Errorf("-32767 %s 1 = %d, want -32768", "-", r)
+	}
+	y = 32766
+	r = x - y
+	if r != 3 {
+		t.Errorf("-32767 %s 32766 = %d, want 3", "-", r)
+	}
+	y = 32767
+	r = x - y
+	if r != 2 {
+		t.Errorf("-32767 %s 32767 = %d, want 2", "-", r)
+	}
+	x = -1
+	y = -32768
+	r = x - y
+	if r != 32767 {
+		t.Errorf("-1 %s -32768 = %d, want 32767", "-", r)
+	}
+	y = -32767
+	r = x - y
+	if r != 32766 {
+		t.Errorf("-1 %s -32767 = %d, want 32766", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 0 {
+		t.Errorf("-1 %s -1 = %d, want 0", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "-", r)
+	}
+	y = 32766
+	r = x - y
+	if r != -32767 {
+		t.Errorf("-1 %s 32766 = %d, want -32767", "-", r)
+	}
+	y = 32767
+	r = x - y
+	if r != -32768 {
+		t.Errorf("-1 %s 32767 = %d, want -32768", "-", r)
+	}
+	x = 0
+	y = -32768
+	r = x - y
+	if r != -32768 {
+		t.Errorf("0 %s -32768 = %d, want -32768", "-", r)
+	}
+	y = -32767
+	r = x - y
+	if r != 32767 {
+		t.Errorf("0 %s -32767 = %d, want 32767", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 1 {
+		t.Errorf("0 %s -1 = %d, want 1", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -1 {
+		t.Errorf("0 %s 1 = %d, want -1", "-", r)
+	}
+	y = 32766
+	r = x - y
+	if r != -32766 {
+		t.Errorf("0 %s 32766 = %d, want -32766", "-", r)
+	}
+	y = 32767
+	r = x - y
+	if r != -32767 {
+		t.Errorf("0 %s 32767 = %d, want -32767", "-", r)
+	}
+	x = 1
+	y = -32768
+	r = x - y
+	if r != -32767 {
+		t.Errorf("1 %s -32768 = %d, want -32767", "-", r)
+	}
+	y = -32767
+	r = x - y
+	if r != -32768 {
+		t.Errorf("1 %s -32767 = %d, want -32768", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 2 {
+		t.Errorf("1 %s -1 = %d, want 2", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "-", r)
+	}
+	y = 32766
+	r = x - y
+	if r != -32765 {
+		t.Errorf("1 %s 32766 = %d, want -32765", "-", r)
+	}
+	y = 32767
+	r = x - y
+	if r != -32766 {
+		t.Errorf("1 %s 32767 = %d, want -32766", "-", r)
+	}
+	x = 32766
+	y = -32768
+	r = x - y
+	if r != -2 {
+		t.Errorf("32766 %s -32768 = %d, want -2", "-", r)
+	}
+	y = -32767
+	r = x - y
+	if r != -3 {
+		t.Errorf("32766 %s -32767 = %d, want -3", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 32767 {
+		t.Errorf("32766 %s -1 = %d, want 32767", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 32766 {
+		t.Errorf("32766 %s 0 = %d, want 32766", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 32765 {
+		t.Errorf("32766 %s 1 = %d, want 32765", "-", r)
+	}
+	y = 32766
+	r = x - y
+	if r != 0 {
+		t.Errorf("32766 %s 32766 = %d, want 0", "-", r)
+	}
+	y = 32767
+	r = x - y
+	if r != -1 {
+		t.Errorf("32766 %s 32767 = %d, want -1", "-", r)
+	}
+	x = 32767
+	y = -32768
+	r = x - y
+	if r != -1 {
+		t.Errorf("32767 %s -32768 = %d, want -1", "-", r)
+	}
+	y = -32767
+	r = x - y
+	if r != -2 {
+		t.Errorf("32767 %s -32767 = %d, want -2", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -32768 {
+		t.Errorf("32767 %s -1 = %d, want -32768", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 32767 {
+		t.Errorf("32767 %s 0 = %d, want 32767", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 32766 {
+		t.Errorf("32767 %s 1 = %d, want 32766", "-", r)
+	}
+	y = 32766
+	r = x - y
+	if r != 1 {
+		t.Errorf("32767 %s 32766 = %d, want 1", "-", r)
+	}
+	y = 32767
+	r = x - y
+	if r != 0 {
+		t.Errorf("32767 %s 32767 = %d, want 0", "-", r)
+	}
+}
+func TestConstFoldint16div(t *testing.T) {
+	var x, y, r int16
+	x = -32768
+	y = -32768
+	r = x / y
+	if r != 1 {
+		t.Errorf("-32768 %s -32768 = %d, want 1", "/", r)
+	}
+	y = -32767
+	r = x / y
+	if r != 1 {
+		t.Errorf("-32768 %s -32767 = %d, want 1", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -32768 {
+		t.Errorf("-32768 %s -1 = %d, want -32768", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -32768 {
+		t.Errorf("-32768 %s 1 = %d, want -32768", "/", r)
+	}
+	y = 32766
+	r = x / y
+	if r != -1 {
+		t.Errorf("-32768 %s 32766 = %d, want -1", "/", r)
+	}
+	y = 32767
+	r = x / y
+	if r != -1 {
+		t.Errorf("-32768 %s 32767 = %d, want -1", "/", r)
+	}
+	x = -32767
+	y = -32768
+	r = x / y
+	if r != 0 {
+		t.Errorf("-32767 %s -32768 = %d, want 0", "/", r)
+	}
+	y = -32767
+	r = x / y
+	if r != 1 {
+		t.Errorf("-32767 %s -32767 = %d, want 1", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 32767 {
+		t.Errorf("-32767 %s -1 = %d, want 32767", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -32767 {
+		t.Errorf("-32767 %s 1 = %d, want -32767", "/", r)
+	}
+	y = 32766
+	r = x / y
+	if r != -1 {
+		t.Errorf("-32767 %s 32766 = %d, want -1", "/", r)
+	}
+	y = 32767
+	r = x / y
+	if r != -1 {
+		t.Errorf("-32767 %s 32767 = %d, want -1", "/", r)
+	}
+	x = -1
+	y = -32768
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s -32768 = %d, want 0", "/", r)
+	}
+	y = -32767
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s -32767 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 1 {
+		t.Errorf("-1 %s -1 = %d, want 1", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", "/", r)
+	}
+	y = 32766
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s 32766 = %d, want 0", "/", r)
+	}
+	y = 32767
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s 32767 = %d, want 0", "/", r)
+	}
+	x = 0
+	y = -32768
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -32768 = %d, want 0", "/", r)
+	}
+	y = -32767
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -32767 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -1 = %d, want 0", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "/", r)
+	}
+	y = 32766
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 32766 = %d, want 0", "/", r)
+	}
+	y = 32767
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 32767 = %d, want 0", "/", r)
+	}
+	x = 1
+	y = -32768
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s -32768 = %d, want 0", "/", r)
+	}
+	y = -32767
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s -32767 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -1 {
+		t.Errorf("1 %s -1 = %d, want -1", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "/", r)
+	}
+	y = 32766
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 32766 = %d, want 0", "/", r)
+	}
+	y = 32767
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 32767 = %d, want 0", "/", r)
+	}
+	x = 32766
+	y = -32768
+	r = x / y
+	if r != 0 {
+		t.Errorf("32766 %s -32768 = %d, want 0", "/", r)
+	}
+	y = -32767
+	r = x / y
+	if r != 0 {
+		t.Errorf("32766 %s -32767 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -32766 {
+		t.Errorf("32766 %s -1 = %d, want -32766", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 32766 {
+		t.Errorf("32766 %s 1 = %d, want 32766", "/", r)
+	}
+	y = 32766
+	r = x / y
+	if r != 1 {
+		t.Errorf("32766 %s 32766 = %d, want 1", "/", r)
+	}
+	y = 32767
+	r = x / y
+	if r != 0 {
+		t.Errorf("32766 %s 32767 = %d, want 0", "/", r)
+	}
+	x = 32767
+	y = -32768
+	r = x / y
+	if r != 0 {
+		t.Errorf("32767 %s -32768 = %d, want 0", "/", r)
+	}
+	y = -32767
+	r = x / y
+	if r != -1 {
+		t.Errorf("32767 %s -32767 = %d, want -1", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -32767 {
+		t.Errorf("32767 %s -1 = %d, want -32767", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 32767 {
+		t.Errorf("32767 %s 1 = %d, want 32767", "/", r)
+	}
+	y = 32766
+	r = x / y
+	if r != 1 {
+		t.Errorf("32767 %s 32766 = %d, want 1", "/", r)
+	}
+	y = 32767
+	r = x / y
+	if r != 1 {
+		t.Errorf("32767 %s 32767 = %d, want 1", "/", r)
+	}
+}
+func TestConstFoldint16mul(t *testing.T) {
+	var x, y, r int16
+	x = -32768
+	y = -32768
+	r = x * y
+	if r != 0 {
+		t.Errorf("-32768 %s -32768 = %d, want 0", "*", r)
+	}
+	y = -32767
+	r = x * y
+	if r != -32768 {
+		t.Errorf("-32768 %s -32767 = %d, want -32768", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -32768 {
+		t.Errorf("-32768 %s -1 = %d, want -32768", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-32768 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -32768 {
+		t.Errorf("-32768 %s 1 = %d, want -32768", "*", r)
+	}
+	y = 32766
+	r = x * y
+	if r != 0 {
+		t.Errorf("-32768 %s 32766 = %d, want 0", "*", r)
+	}
+	y = 32767
+	r = x * y
+	if r != -32768 {
+		t.Errorf("-32768 %s 32767 = %d, want -32768", "*", r)
+	}
+	x = -32767
+	y = -32768
+	r = x * y
+	if r != -32768 {
+		t.Errorf("-32767 %s -32768 = %d, want -32768", "*", r)
+	}
+	y = -32767
+	r = x * y
+	if r != 1 {
+		t.Errorf("-32767 %s -32767 = %d, want 1", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 32767 {
+		t.Errorf("-32767 %s -1 = %d, want 32767", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-32767 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -32767 {
+		t.Errorf("-32767 %s 1 = %d, want -32767", "*", r)
+	}
+	y = 32766
+	r = x * y
+	if r != 32766 {
+		t.Errorf("-32767 %s 32766 = %d, want 32766", "*", r)
+	}
+	y = 32767
+	r = x * y
+	if r != -1 {
+		t.Errorf("-32767 %s 32767 = %d, want -1", "*", r)
+	}
+	x = -1
+	y = -32768
+	r = x * y
+	if r != -32768 {
+		t.Errorf("-1 %s -32768 = %d, want -32768", "*", r)
+	}
+	y = -32767
+	r = x * y
+	if r != 32767 {
+		t.Errorf("-1 %s -32767 = %d, want 32767", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 1 {
+		t.Errorf("-1 %s -1 = %d, want 1", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-1 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", "*", r)
+	}
+	y = 32766
+	r = x * y
+	if r != -32766 {
+		t.Errorf("-1 %s 32766 = %d, want -32766", "*", r)
+	}
+	y = 32767
+	r = x * y
+	if r != -32767 {
+		t.Errorf("-1 %s 32767 = %d, want -32767", "*", r)
+	}
+	x = 0
+	y = -32768
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -32768 = %d, want 0", "*", r)
+	}
+	y = -32767
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -32767 = %d, want 0", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -1 = %d, want 0", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "*", r)
+	}
+	y = 32766
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 32766 = %d, want 0", "*", r)
+	}
+	y = 32767
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 32767 = %d, want 0", "*", r)
+	}
+	x = 1
+	y = -32768
+	r = x * y
+	if r != -32768 {
+		t.Errorf("1 %s -32768 = %d, want -32768", "*", r)
+	}
+	y = -32767
+	r = x * y
+	if r != -32767 {
+		t.Errorf("1 %s -32767 = %d, want -32767", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -1 {
+		t.Errorf("1 %s -1 = %d, want -1", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("1 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "*", r)
+	}
+	y = 32766
+	r = x * y
+	if r != 32766 {
+		t.Errorf("1 %s 32766 = %d, want 32766", "*", r)
+	}
+	y = 32767
+	r = x * y
+	if r != 32767 {
+		t.Errorf("1 %s 32767 = %d, want 32767", "*", r)
+	}
+	x = 32766
+	y = -32768
+	r = x * y
+	if r != 0 {
+		t.Errorf("32766 %s -32768 = %d, want 0", "*", r)
+	}
+	y = -32767
+	r = x * y
+	if r != 32766 {
+		t.Errorf("32766 %s -32767 = %d, want 32766", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -32766 {
+		t.Errorf("32766 %s -1 = %d, want -32766", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("32766 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 32766 {
+		t.Errorf("32766 %s 1 = %d, want 32766", "*", r)
+	}
+	y = 32766
+	r = x * y
+	if r != 4 {
+		t.Errorf("32766 %s 32766 = %d, want 4", "*", r)
+	}
+	y = 32767
+	r = x * y
+	if r != -32766 {
+		t.Errorf("32766 %s 32767 = %d, want -32766", "*", r)
+	}
+	x = 32767
+	y = -32768
+	r = x * y
+	if r != -32768 {
+		t.Errorf("32767 %s -32768 = %d, want -32768", "*", r)
+	}
+	y = -32767
+	r = x * y
+	if r != -1 {
+		t.Errorf("32767 %s -32767 = %d, want -1", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -32767 {
+		t.Errorf("32767 %s -1 = %d, want -32767", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("32767 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 32767 {
+		t.Errorf("32767 %s 1 = %d, want 32767", "*", r)
+	}
+	y = 32766
+	r = x * y
+	if r != -32766 {
+		t.Errorf("32767 %s 32766 = %d, want -32766", "*", r)
+	}
+	y = 32767
+	r = x * y
+	if r != 1 {
+		t.Errorf("32767 %s 32767 = %d, want 1", "*", r)
+	}
+}
+func TestConstFoldint16mod(t *testing.T) {
+	var x, y, r int16
+	x = -32768
+	y = -32768
+	r = x % y
+	if r != 0 {
+		t.Errorf("-32768 %s -32768 = %d, want 0", "%", r)
+	}
+	y = -32767
+	r = x % y
+	if r != -1 {
+		t.Errorf("-32768 %s -32767 = %d, want -1", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-32768 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-32768 %s 1 = %d, want 0", "%", r)
+	}
+	y = 32766
+	r = x % y
+	if r != -2 {
+		t.Errorf("-32768 %s 32766 = %d, want -2", "%", r)
+	}
+	y = 32767
+	r = x % y
+	if r != -1 {
+		t.Errorf("-32768 %s 32767 = %d, want -1", "%", r)
+	}
+	x = -32767
+	y = -32768
+	r = x % y
+	if r != -32767 {
+		t.Errorf("-32767 %s -32768 = %d, want -32767", "%", r)
+	}
+	y = -32767
+	r = x % y
+	if r != 0 {
+		t.Errorf("-32767 %s -32767 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-32767 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-32767 %s 1 = %d, want 0", "%", r)
+	}
+	y = 32766
+	r = x % y
+	if r != -1 {
+		t.Errorf("-32767 %s 32766 = %d, want -1", "%", r)
+	}
+	y = 32767
+	r = x % y
+	if r != 0 {
+		t.Errorf("-32767 %s 32767 = %d, want 0", "%", r)
+	}
+	x = -1
+	y = -32768
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s -32768 = %d, want -1", "%", r)
+	}
+	y = -32767
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s -32767 = %d, want -1", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-1 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-1 %s 1 = %d, want 0", "%", r)
+	}
+	y = 32766
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s 32766 = %d, want -1", "%", r)
+	}
+	y = 32767
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s 32767 = %d, want -1", "%", r)
+	}
+	x = 0
+	y = -32768
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -32768 = %d, want 0", "%", r)
+	}
+	y = -32767
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -32767 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "%", r)
+	}
+	y = 32766
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 32766 = %d, want 0", "%", r)
+	}
+	y = 32767
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 32767 = %d, want 0", "%", r)
+	}
+	x = 1
+	y = -32768
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s -32768 = %d, want 1", "%", r)
+	}
+	y = -32767
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s -32767 = %d, want 1", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("1 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "%", r)
+	}
+	y = 32766
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 32766 = %d, want 1", "%", r)
+	}
+	y = 32767
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 32767 = %d, want 1", "%", r)
+	}
+	x = 32766
+	y = -32768
+	r = x % y
+	if r != 32766 {
+		t.Errorf("32766 %s -32768 = %d, want 32766", "%", r)
+	}
+	y = -32767
+	r = x % y
+	if r != 32766 {
+		t.Errorf("32766 %s -32767 = %d, want 32766", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("32766 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("32766 %s 1 = %d, want 0", "%", r)
+	}
+	y = 32766
+	r = x % y
+	if r != 0 {
+		t.Errorf("32766 %s 32766 = %d, want 0", "%", r)
+	}
+	y = 32767
+	r = x % y
+	if r != 32766 {
+		t.Errorf("32766 %s 32767 = %d, want 32766", "%", r)
+	}
+	x = 32767
+	y = -32768
+	r = x % y
+	if r != 32767 {
+		t.Errorf("32767 %s -32768 = %d, want 32767", "%", r)
+	}
+	y = -32767
+	r = x % y
+	if r != 0 {
+		t.Errorf("32767 %s -32767 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("32767 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("32767 %s 1 = %d, want 0", "%", r)
+	}
+	y = 32766
+	r = x % y
+	if r != 1 {
+		t.Errorf("32767 %s 32766 = %d, want 1", "%", r)
+	}
+	y = 32767
+	r = x % y
+	if r != 0 {
+		t.Errorf("32767 %s 32767 = %d, want 0", "%", r)
+	}
+}
+func TestConstFolduint8add(t *testing.T) {
+	var x, y, r uint8
+	x = 0
+	y = 0
+	r = x + y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 1 {
+		t.Errorf("0 %s 1 = %d, want 1", "+", r)
+	}
+	y = 255
+	r = x + y
+	if r != 255 {
+		t.Errorf("0 %s 255 = %d, want 255", "+", r)
+	}
+	x = 1
+	y = 0
+	r = x + y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "+", r)
+	}
+	y = 255
+	r = x + y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", "+", r)
+	}
+	x = 255
+	y = 0
+	r = x + y
+	if r != 255 {
+		t.Errorf("255 %s 0 = %d, want 255", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 0 {
+		t.Errorf("255 %s 1 = %d, want 0", "+", r)
+	}
+	y = 255
+	r = x + y
+	if r != 254 {
+		t.Errorf("255 %s 255 = %d, want 254", "+", r)
+	}
+}
+func TestConstFolduint8sub(t *testing.T) {
+	var x, y, r uint8
+	x = 0
+	y = 0
+	r = x - y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 255 {
+		t.Errorf("0 %s 1 = %d, want 255", "-", r)
+	}
+	y = 255
+	r = x - y
+	if r != 1 {
+		t.Errorf("0 %s 255 = %d, want 1", "-", r)
+	}
+	x = 1
+	y = 0
+	r = x - y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "-", r)
+	}
+	y = 255
+	r = x - y
+	if r != 2 {
+		t.Errorf("1 %s 255 = %d, want 2", "-", r)
+	}
+	x = 255
+	y = 0
+	r = x - y
+	if r != 255 {
+		t.Errorf("255 %s 0 = %d, want 255", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 254 {
+		t.Errorf("255 %s 1 = %d, want 254", "-", r)
+	}
+	y = 255
+	r = x - y
+	if r != 0 {
+		t.Errorf("255 %s 255 = %d, want 0", "-", r)
+	}
+}
+func TestConstFolduint8div(t *testing.T) {
+	var x, y, r uint8
+	x = 0
+	y = 1
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "/", r)
+	}
+	y = 255
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", "/", r)
+	}
+	x = 1
+	y = 1
+	r = x / y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "/", r)
+	}
+	y = 255
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", "/", r)
+	}
+	x = 255
+	y = 1
+	r = x / y
+	if r != 255 {
+		t.Errorf("255 %s 1 = %d, want 255", "/", r)
+	}
+	y = 255
+	r = x / y
+	if r != 1 {
+		t.Errorf("255 %s 255 = %d, want 1", "/", r)
+	}
+}
+func TestConstFolduint8mul(t *testing.T) {
+	var x, y, r uint8
+	x = 0
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "*", r)
+	}
+	y = 255
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", "*", r)
+	}
+	x = 1
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("1 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "*", r)
+	}
+	y = 255
+	r = x * y
+	if r != 255 {
+		t.Errorf("1 %s 255 = %d, want 255", "*", r)
+	}
+	x = 255
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("255 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 255 {
+		t.Errorf("255 %s 1 = %d, want 255", "*", r)
+	}
+	y = 255
+	r = x * y
+	if r != 1 {
+		t.Errorf("255 %s 255 = %d, want 1", "*", r)
+	}
+}
+func TestConstFolduint8mod(t *testing.T) {
+	var x, y, r uint8
+	x = 0
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "%", r)
+	}
+	y = 255
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", "%", r)
+	}
+	x = 1
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "%", r)
+	}
+	y = 255
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 255 = %d, want 1", "%", r)
+	}
+	x = 255
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("255 %s 1 = %d, want 0", "%", r)
+	}
+	y = 255
+	r = x % y
+	if r != 0 {
+		t.Errorf("255 %s 255 = %d, want 0", "%", r)
+	}
+}
+func TestConstFoldint8add(t *testing.T) {
+	var x, y, r int8
+	x = -128
+	y = -128
+	r = x + y
+	if r != 0 {
+		t.Errorf("-128 %s -128 = %d, want 0", "+", r)
+	}
+	y = -127
+	r = x + y
+	if r != 1 {
+		t.Errorf("-128 %s -127 = %d, want 1", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 127 {
+		t.Errorf("-128 %s -1 = %d, want 127", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -128 {
+		t.Errorf("-128 %s 0 = %d, want -128", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -127 {
+		t.Errorf("-128 %s 1 = %d, want -127", "+", r)
+	}
+	y = 126
+	r = x + y
+	if r != -2 {
+		t.Errorf("-128 %s 126 = %d, want -2", "+", r)
+	}
+	y = 127
+	r = x + y
+	if r != -1 {
+		t.Errorf("-128 %s 127 = %d, want -1", "+", r)
+	}
+	x = -127
+	y = -128
+	r = x + y
+	if r != 1 {
+		t.Errorf("-127 %s -128 = %d, want 1", "+", r)
+	}
+	y = -127
+	r = x + y
+	if r != 2 {
+		t.Errorf("-127 %s -127 = %d, want 2", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -128 {
+		t.Errorf("-127 %s -1 = %d, want -128", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -127 {
+		t.Errorf("-127 %s 0 = %d, want -127", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -126 {
+		t.Errorf("-127 %s 1 = %d, want -126", "+", r)
+	}
+	y = 126
+	r = x + y
+	if r != -1 {
+		t.Errorf("-127 %s 126 = %d, want -1", "+", r)
+	}
+	y = 127
+	r = x + y
+	if r != 0 {
+		t.Errorf("-127 %s 127 = %d, want 0", "+", r)
+	}
+	x = -1
+	y = -128
+	r = x + y
+	if r != 127 {
+		t.Errorf("-1 %s -128 = %d, want 127", "+", r)
+	}
+	y = -127
+	r = x + y
+	if r != -128 {
+		t.Errorf("-1 %s -127 = %d, want -128", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -2 {
+		t.Errorf("-1 %s -1 = %d, want -2", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 0 {
+		t.Errorf("-1 %s 1 = %d, want 0", "+", r)
+	}
+	y = 126
+	r = x + y
+	if r != 125 {
+		t.Errorf("-1 %s 126 = %d, want 125", "+", r)
+	}
+	y = 127
+	r = x + y
+	if r != 126 {
+		t.Errorf("-1 %s 127 = %d, want 126", "+", r)
+	}
+	x = 0
+	y = -128
+	r = x + y
+	if r != -128 {
+		t.Errorf("0 %s -128 = %d, want -128", "+", r)
+	}
+	y = -127
+	r = x + y
+	if r != -127 {
+		t.Errorf("0 %s -127 = %d, want -127", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != -1 {
+		t.Errorf("0 %s -1 = %d, want -1", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 1 {
+		t.Errorf("0 %s 1 = %d, want 1", "+", r)
+	}
+	y = 126
+	r = x + y
+	if r != 126 {
+		t.Errorf("0 %s 126 = %d, want 126", "+", r)
+	}
+	y = 127
+	r = x + y
+	if r != 127 {
+		t.Errorf("0 %s 127 = %d, want 127", "+", r)
+	}
+	x = 1
+	y = -128
+	r = x + y
+	if r != -127 {
+		t.Errorf("1 %s -128 = %d, want -127", "+", r)
+	}
+	y = -127
+	r = x + y
+	if r != -126 {
+		t.Errorf("1 %s -127 = %d, want -126", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 0 {
+		t.Errorf("1 %s -1 = %d, want 0", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "+", r)
+	}
+	y = 126
+	r = x + y
+	if r != 127 {
+		t.Errorf("1 %s 126 = %d, want 127", "+", r)
+	}
+	y = 127
+	r = x + y
+	if r != -128 {
+		t.Errorf("1 %s 127 = %d, want -128", "+", r)
+	}
+	x = 126
+	y = -128
+	r = x + y
+	if r != -2 {
+		t.Errorf("126 %s -128 = %d, want -2", "+", r)
+	}
+	y = -127
+	r = x + y
+	if r != -1 {
+		t.Errorf("126 %s -127 = %d, want -1", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 125 {
+		t.Errorf("126 %s -1 = %d, want 125", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 126 {
+		t.Errorf("126 %s 0 = %d, want 126", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != 127 {
+		t.Errorf("126 %s 1 = %d, want 127", "+", r)
+	}
+	y = 126
+	r = x + y
+	if r != -4 {
+		t.Errorf("126 %s 126 = %d, want -4", "+", r)
+	}
+	y = 127
+	r = x + y
+	if r != -3 {
+		t.Errorf("126 %s 127 = %d, want -3", "+", r)
+	}
+	x = 127
+	y = -128
+	r = x + y
+	if r != -1 {
+		t.Errorf("127 %s -128 = %d, want -1", "+", r)
+	}
+	y = -127
+	r = x + y
+	if r != 0 {
+		t.Errorf("127 %s -127 = %d, want 0", "+", r)
+	}
+	y = -1
+	r = x + y
+	if r != 126 {
+		t.Errorf("127 %s -1 = %d, want 126", "+", r)
+	}
+	y = 0
+	r = x + y
+	if r != 127 {
+		t.Errorf("127 %s 0 = %d, want 127", "+", r)
+	}
+	y = 1
+	r = x + y
+	if r != -128 {
+		t.Errorf("127 %s 1 = %d, want -128", "+", r)
+	}
+	y = 126
+	r = x + y
+	if r != -3 {
+		t.Errorf("127 %s 126 = %d, want -3", "+", r)
+	}
+	y = 127
+	r = x + y
+	if r != -2 {
+		t.Errorf("127 %s 127 = %d, want -2", "+", r)
+	}
+}
+func TestConstFoldint8sub(t *testing.T) {
+	var x, y, r int8
+	x = -128
+	y = -128
+	r = x - y
+	if r != 0 {
+		t.Errorf("-128 %s -128 = %d, want 0", "-", r)
+	}
+	y = -127
+	r = x - y
+	if r != -1 {
+		t.Errorf("-128 %s -127 = %d, want -1", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -127 {
+		t.Errorf("-128 %s -1 = %d, want -127", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -128 {
+		t.Errorf("-128 %s 0 = %d, want -128", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 127 {
+		t.Errorf("-128 %s 1 = %d, want 127", "-", r)
+	}
+	y = 126
+	r = x - y
+	if r != 2 {
+		t.Errorf("-128 %s 126 = %d, want 2", "-", r)
+	}
+	y = 127
+	r = x - y
+	if r != 1 {
+		t.Errorf("-128 %s 127 = %d, want 1", "-", r)
+	}
+	x = -127
+	y = -128
+	r = x - y
+	if r != 1 {
+		t.Errorf("-127 %s -128 = %d, want 1", "-", r)
+	}
+	y = -127
+	r = x - y
+	if r != 0 {
+		t.Errorf("-127 %s -127 = %d, want 0", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -126 {
+		t.Errorf("-127 %s -1 = %d, want -126", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -127 {
+		t.Errorf("-127 %s 0 = %d, want -127", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -128 {
+		t.Errorf("-127 %s 1 = %d, want -128", "-", r)
+	}
+	y = 126
+	r = x - y
+	if r != 3 {
+		t.Errorf("-127 %s 126 = %d, want 3", "-", r)
+	}
+	y = 127
+	r = x - y
+	if r != 2 {
+		t.Errorf("-127 %s 127 = %d, want 2", "-", r)
+	}
+	x = -1
+	y = -128
+	r = x - y
+	if r != 127 {
+		t.Errorf("-1 %s -128 = %d, want 127", "-", r)
+	}
+	y = -127
+	r = x - y
+	if r != 126 {
+		t.Errorf("-1 %s -127 = %d, want 126", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 0 {
+		t.Errorf("-1 %s -1 = %d, want 0", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "-", r)
+	}
+	y = 126
+	r = x - y
+	if r != -127 {
+		t.Errorf("-1 %s 126 = %d, want -127", "-", r)
+	}
+	y = 127
+	r = x - y
+	if r != -128 {
+		t.Errorf("-1 %s 127 = %d, want -128", "-", r)
+	}
+	x = 0
+	y = -128
+	r = x - y
+	if r != -128 {
+		t.Errorf("0 %s -128 = %d, want -128", "-", r)
+	}
+	y = -127
+	r = x - y
+	if r != 127 {
+		t.Errorf("0 %s -127 = %d, want 127", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 1 {
+		t.Errorf("0 %s -1 = %d, want 1", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != -1 {
+		t.Errorf("0 %s 1 = %d, want -1", "-", r)
+	}
+	y = 126
+	r = x - y
+	if r != -126 {
+		t.Errorf("0 %s 126 = %d, want -126", "-", r)
+	}
+	y = 127
+	r = x - y
+	if r != -127 {
+		t.Errorf("0 %s 127 = %d, want -127", "-", r)
+	}
+	x = 1
+	y = -128
+	r = x - y
+	if r != -127 {
+		t.Errorf("1 %s -128 = %d, want -127", "-", r)
+	}
+	y = -127
+	r = x - y
+	if r != -128 {
+		t.Errorf("1 %s -127 = %d, want -128", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 2 {
+		t.Errorf("1 %s -1 = %d, want 2", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "-", r)
+	}
+	y = 126
+	r = x - y
+	if r != -125 {
+		t.Errorf("1 %s 126 = %d, want -125", "-", r)
+	}
+	y = 127
+	r = x - y
+	if r != -126 {
+		t.Errorf("1 %s 127 = %d, want -126", "-", r)
+	}
+	x = 126
+	y = -128
+	r = x - y
+	if r != -2 {
+		t.Errorf("126 %s -128 = %d, want -2", "-", r)
+	}
+	y = -127
+	r = x - y
+	if r != -3 {
+		t.Errorf("126 %s -127 = %d, want -3", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != 127 {
+		t.Errorf("126 %s -1 = %d, want 127", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 126 {
+		t.Errorf("126 %s 0 = %d, want 126", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 125 {
+		t.Errorf("126 %s 1 = %d, want 125", "-", r)
+	}
+	y = 126
+	r = x - y
+	if r != 0 {
+		t.Errorf("126 %s 126 = %d, want 0", "-", r)
+	}
+	y = 127
+	r = x - y
+	if r != -1 {
+		t.Errorf("126 %s 127 = %d, want -1", "-", r)
+	}
+	x = 127
+	y = -128
+	r = x - y
+	if r != -1 {
+		t.Errorf("127 %s -128 = %d, want -1", "-", r)
+	}
+	y = -127
+	r = x - y
+	if r != -2 {
+		t.Errorf("127 %s -127 = %d, want -2", "-", r)
+	}
+	y = -1
+	r = x - y
+	if r != -128 {
+		t.Errorf("127 %s -1 = %d, want -128", "-", r)
+	}
+	y = 0
+	r = x - y
+	if r != 127 {
+		t.Errorf("127 %s 0 = %d, want 127", "-", r)
+	}
+	y = 1
+	r = x - y
+	if r != 126 {
+		t.Errorf("127 %s 1 = %d, want 126", "-", r)
+	}
+	y = 126
+	r = x - y
+	if r != 1 {
+		t.Errorf("127 %s 126 = %d, want 1", "-", r)
+	}
+	y = 127
+	r = x - y
+	if r != 0 {
+		t.Errorf("127 %s 127 = %d, want 0", "-", r)
+	}
+}
+func TestConstFoldint8div(t *testing.T) {
+	var x, y, r int8
+	x = -128
+	y = -128
+	r = x / y
+	if r != 1 {
+		t.Errorf("-128 %s -128 = %d, want 1", "/", r)
+	}
+	y = -127
+	r = x / y
+	if r != 1 {
+		t.Errorf("-128 %s -127 = %d, want 1", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -128 {
+		t.Errorf("-128 %s -1 = %d, want -128", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -128 {
+		t.Errorf("-128 %s 1 = %d, want -128", "/", r)
+	}
+	y = 126
+	r = x / y
+	if r != -1 {
+		t.Errorf("-128 %s 126 = %d, want -1", "/", r)
+	}
+	y = 127
+	r = x / y
+	if r != -1 {
+		t.Errorf("-128 %s 127 = %d, want -1", "/", r)
+	}
+	x = -127
+	y = -128
+	r = x / y
+	if r != 0 {
+		t.Errorf("-127 %s -128 = %d, want 0", "/", r)
+	}
+	y = -127
+	r = x / y
+	if r != 1 {
+		t.Errorf("-127 %s -127 = %d, want 1", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 127 {
+		t.Errorf("-127 %s -1 = %d, want 127", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -127 {
+		t.Errorf("-127 %s 1 = %d, want -127", "/", r)
+	}
+	y = 126
+	r = x / y
+	if r != -1 {
+		t.Errorf("-127 %s 126 = %d, want -1", "/", r)
+	}
+	y = 127
+	r = x / y
+	if r != -1 {
+		t.Errorf("-127 %s 127 = %d, want -1", "/", r)
+	}
+	x = -1
+	y = -128
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s -128 = %d, want 0", "/", r)
+	}
+	y = -127
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s -127 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 1 {
+		t.Errorf("-1 %s -1 = %d, want 1", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", "/", r)
+	}
+	y = 126
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s 126 = %d, want 0", "/", r)
+	}
+	y = 127
+	r = x / y
+	if r != 0 {
+		t.Errorf("-1 %s 127 = %d, want 0", "/", r)
+	}
+	x = 0
+	y = -128
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -128 = %d, want 0", "/", r)
+	}
+	y = -127
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -127 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s -1 = %d, want 0", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "/", r)
+	}
+	y = 126
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 126 = %d, want 0", "/", r)
+	}
+	y = 127
+	r = x / y
+	if r != 0 {
+		t.Errorf("0 %s 127 = %d, want 0", "/", r)
+	}
+	x = 1
+	y = -128
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s -128 = %d, want 0", "/", r)
+	}
+	y = -127
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s -127 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -1 {
+		t.Errorf("1 %s -1 = %d, want -1", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "/", r)
+	}
+	y = 126
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 126 = %d, want 0", "/", r)
+	}
+	y = 127
+	r = x / y
+	if r != 0 {
+		t.Errorf("1 %s 127 = %d, want 0", "/", r)
+	}
+	x = 126
+	y = -128
+	r = x / y
+	if r != 0 {
+		t.Errorf("126 %s -128 = %d, want 0", "/", r)
+	}
+	y = -127
+	r = x / y
+	if r != 0 {
+		t.Errorf("126 %s -127 = %d, want 0", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -126 {
+		t.Errorf("126 %s -1 = %d, want -126", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 126 {
+		t.Errorf("126 %s 1 = %d, want 126", "/", r)
+	}
+	y = 126
+	r = x / y
+	if r != 1 {
+		t.Errorf("126 %s 126 = %d, want 1", "/", r)
+	}
+	y = 127
+	r = x / y
+	if r != 0 {
+		t.Errorf("126 %s 127 = %d, want 0", "/", r)
+	}
+	x = 127
+	y = -128
+	r = x / y
+	if r != 0 {
+		t.Errorf("127 %s -128 = %d, want 0", "/", r)
+	}
+	y = -127
+	r = x / y
+	if r != -1 {
+		t.Errorf("127 %s -127 = %d, want -1", "/", r)
+	}
+	y = -1
+	r = x / y
+	if r != -127 {
+		t.Errorf("127 %s -1 = %d, want -127", "/", r)
+	}
+	y = 1
+	r = x / y
+	if r != 127 {
+		t.Errorf("127 %s 1 = %d, want 127", "/", r)
+	}
+	y = 126
+	r = x / y
+	if r != 1 {
+		t.Errorf("127 %s 126 = %d, want 1", "/", r)
+	}
+	y = 127
+	r = x / y
+	if r != 1 {
+		t.Errorf("127 %s 127 = %d, want 1", "/", r)
+	}
+}
+func TestConstFoldint8mul(t *testing.T) {
+	var x, y, r int8
+	x = -128
+	y = -128
+	r = x * y
+	if r != 0 {
+		t.Errorf("-128 %s -128 = %d, want 0", "*", r)
+	}
+	y = -127
+	r = x * y
+	if r != -128 {
+		t.Errorf("-128 %s -127 = %d, want -128", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -128 {
+		t.Errorf("-128 %s -1 = %d, want -128", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-128 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -128 {
+		t.Errorf("-128 %s 1 = %d, want -128", "*", r)
+	}
+	y = 126
+	r = x * y
+	if r != 0 {
+		t.Errorf("-128 %s 126 = %d, want 0", "*", r)
+	}
+	y = 127
+	r = x * y
+	if r != -128 {
+		t.Errorf("-128 %s 127 = %d, want -128", "*", r)
+	}
+	x = -127
+	y = -128
+	r = x * y
+	if r != -128 {
+		t.Errorf("-127 %s -128 = %d, want -128", "*", r)
+	}
+	y = -127
+	r = x * y
+	if r != 1 {
+		t.Errorf("-127 %s -127 = %d, want 1", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 127 {
+		t.Errorf("-127 %s -1 = %d, want 127", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-127 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -127 {
+		t.Errorf("-127 %s 1 = %d, want -127", "*", r)
+	}
+	y = 126
+	r = x * y
+	if r != 126 {
+		t.Errorf("-127 %s 126 = %d, want 126", "*", r)
+	}
+	y = 127
+	r = x * y
+	if r != -1 {
+		t.Errorf("-127 %s 127 = %d, want -1", "*", r)
+	}
+	x = -1
+	y = -128
+	r = x * y
+	if r != -128 {
+		t.Errorf("-1 %s -128 = %d, want -128", "*", r)
+	}
+	y = -127
+	r = x * y
+	if r != 127 {
+		t.Errorf("-1 %s -127 = %d, want 127", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 1 {
+		t.Errorf("-1 %s -1 = %d, want 1", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("-1 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", "*", r)
+	}
+	y = 126
+	r = x * y
+	if r != -126 {
+		t.Errorf("-1 %s 126 = %d, want -126", "*", r)
+	}
+	y = 127
+	r = x * y
+	if r != -127 {
+		t.Errorf("-1 %s 127 = %d, want -127", "*", r)
+	}
+	x = 0
+	y = -128
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -128 = %d, want 0", "*", r)
+	}
+	y = -127
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -127 = %d, want 0", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s -1 = %d, want 0", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "*", r)
+	}
+	y = 126
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 126 = %d, want 0", "*", r)
+	}
+	y = 127
+	r = x * y
+	if r != 0 {
+		t.Errorf("0 %s 127 = %d, want 0", "*", r)
+	}
+	x = 1
+	y = -128
+	r = x * y
+	if r != -128 {
+		t.Errorf("1 %s -128 = %d, want -128", "*", r)
+	}
+	y = -127
+	r = x * y
+	if r != -127 {
+		t.Errorf("1 %s -127 = %d, want -127", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -1 {
+		t.Errorf("1 %s -1 = %d, want -1", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("1 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 1 {
+		t.Errorf("1 %s 1 = %d, want 1", "*", r)
+	}
+	y = 126
+	r = x * y
+	if r != 126 {
+		t.Errorf("1 %s 126 = %d, want 126", "*", r)
+	}
+	y = 127
+	r = x * y
+	if r != 127 {
+		t.Errorf("1 %s 127 = %d, want 127", "*", r)
+	}
+	x = 126
+	y = -128
+	r = x * y
+	if r != 0 {
+		t.Errorf("126 %s -128 = %d, want 0", "*", r)
+	}
+	y = -127
+	r = x * y
+	if r != 126 {
+		t.Errorf("126 %s -127 = %d, want 126", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -126 {
+		t.Errorf("126 %s -1 = %d, want -126", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("126 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 126 {
+		t.Errorf("126 %s 1 = %d, want 126", "*", r)
+	}
+	y = 126
+	r = x * y
+	if r != 4 {
+		t.Errorf("126 %s 126 = %d, want 4", "*", r)
+	}
+	y = 127
+	r = x * y
+	if r != -126 {
+		t.Errorf("126 %s 127 = %d, want -126", "*", r)
+	}
+	x = 127
+	y = -128
+	r = x * y
+	if r != -128 {
+		t.Errorf("127 %s -128 = %d, want -128", "*", r)
+	}
+	y = -127
+	r = x * y
+	if r != -1 {
+		t.Errorf("127 %s -127 = %d, want -1", "*", r)
+	}
+	y = -1
+	r = x * y
+	if r != -127 {
+		t.Errorf("127 %s -1 = %d, want -127", "*", r)
+	}
+	y = 0
+	r = x * y
+	if r != 0 {
+		t.Errorf("127 %s 0 = %d, want 0", "*", r)
+	}
+	y = 1
+	r = x * y
+	if r != 127 {
+		t.Errorf("127 %s 1 = %d, want 127", "*", r)
+	}
+	y = 126
+	r = x * y
+	if r != -126 {
+		t.Errorf("127 %s 126 = %d, want -126", "*", r)
+	}
+	y = 127
+	r = x * y
+	if r != 1 {
+		t.Errorf("127 %s 127 = %d, want 1", "*", r)
+	}
+}
+func TestConstFoldint8mod(t *testing.T) {
+	var x, y, r int8
+	x = -128
+	y = -128
+	r = x % y
+	if r != 0 {
+		t.Errorf("-128 %s -128 = %d, want 0", "%", r)
+	}
+	y = -127
+	r = x % y
+	if r != -1 {
+		t.Errorf("-128 %s -127 = %d, want -1", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-128 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-128 %s 1 = %d, want 0", "%", r)
+	}
+	y = 126
+	r = x % y
+	if r != -2 {
+		t.Errorf("-128 %s 126 = %d, want -2", "%", r)
+	}
+	y = 127
+	r = x % y
+	if r != -1 {
+		t.Errorf("-128 %s 127 = %d, want -1", "%", r)
+	}
+	x = -127
+	y = -128
+	r = x % y
+	if r != -127 {
+		t.Errorf("-127 %s -128 = %d, want -127", "%", r)
+	}
+	y = -127
+	r = x % y
+	if r != 0 {
+		t.Errorf("-127 %s -127 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-127 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-127 %s 1 = %d, want 0", "%", r)
+	}
+	y = 126
+	r = x % y
+	if r != -1 {
+		t.Errorf("-127 %s 126 = %d, want -1", "%", r)
+	}
+	y = 127
+	r = x % y
+	if r != 0 {
+		t.Errorf("-127 %s 127 = %d, want 0", "%", r)
+	}
+	x = -1
+	y = -128
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s -128 = %d, want -1", "%", r)
+	}
+	y = -127
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s -127 = %d, want -1", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-1 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("-1 %s 1 = %d, want 0", "%", r)
+	}
+	y = 126
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s 126 = %d, want -1", "%", r)
+	}
+	y = 127
+	r = x % y
+	if r != -1 {
+		t.Errorf("-1 %s 127 = %d, want -1", "%", r)
+	}
+	x = 0
+	y = -128
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -128 = %d, want 0", "%", r)
+	}
+	y = -127
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -127 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "%", r)
+	}
+	y = 126
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 126 = %d, want 0", "%", r)
+	}
+	y = 127
+	r = x % y
+	if r != 0 {
+		t.Errorf("0 %s 127 = %d, want 0", "%", r)
+	}
+	x = 1
+	y = -128
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s -128 = %d, want 1", "%", r)
+	}
+	y = -127
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s -127 = %d, want 1", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("1 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", "%", r)
+	}
+	y = 126
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 126 = %d, want 1", "%", r)
+	}
+	y = 127
+	r = x % y
+	if r != 1 {
+		t.Errorf("1 %s 127 = %d, want 1", "%", r)
+	}
+	x = 126
+	y = -128
+	r = x % y
+	if r != 126 {
+		t.Errorf("126 %s -128 = %d, want 126", "%", r)
+	}
+	y = -127
+	r = x % y
+	if r != 126 {
+		t.Errorf("126 %s -127 = %d, want 126", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("126 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("126 %s 1 = %d, want 0", "%", r)
+	}
+	y = 126
+	r = x % y
+	if r != 0 {
+		t.Errorf("126 %s 126 = %d, want 0", "%", r)
+	}
+	y = 127
+	r = x % y
+	if r != 126 {
+		t.Errorf("126 %s 127 = %d, want 126", "%", r)
+	}
+	x = 127
+	y = -128
+	r = x % y
+	if r != 127 {
+		t.Errorf("127 %s -128 = %d, want 127", "%", r)
+	}
+	y = -127
+	r = x % y
+	if r != 0 {
+		t.Errorf("127 %s -127 = %d, want 0", "%", r)
+	}
+	y = -1
+	r = x % y
+	if r != 0 {
+		t.Errorf("127 %s -1 = %d, want 0", "%", r)
+	}
+	y = 1
+	r = x % y
+	if r != 0 {
+		t.Errorf("127 %s 1 = %d, want 0", "%", r)
+	}
+	y = 126
+	r = x % y
+	if r != 1 {
+		t.Errorf("127 %s 126 = %d, want 1", "%", r)
+	}
+	y = 127
+	r = x % y
+	if r != 0 {
+		t.Errorf("127 %s 127 = %d, want 0", "%", r)
+	}
+}
+func TestConstFolduint64uint64lsh(t *testing.T) {
+	var x, r uint64
+	var y uint64
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x << y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 8589934592 {
+		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 18446744073709551615
+	y = 0
+	r = x << y
+	if r != 18446744073709551615 {
+		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 18446744073709551614 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551614", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint64uint64rsh(t *testing.T) {
+	var x, r uint64
+	var y uint64
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x >> y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 2147483648 {
+		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 18446744073709551615
+	y = 0
+	r = x >> y
+	if r != 18446744073709551615 {
+		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 9223372036854775807 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 9223372036854775807", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint64uint32lsh(t *testing.T) {
+	var x, r uint64
+	var y uint32
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x << y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 8589934592 {
+		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 18446744073709551615
+	y = 0
+	r = x << y
+	if r != 18446744073709551615 {
+		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 18446744073709551614 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551614", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 4294967295 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint64uint32rsh(t *testing.T) {
+	var x, r uint64
+	var y uint32
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x >> y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 2147483648 {
+		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 18446744073709551615
+	y = 0
+	r = x >> y
+	if r != 18446744073709551615 {
+		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 9223372036854775807 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 9223372036854775807", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 4294967295 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint64uint16lsh(t *testing.T) {
+	var x, r uint64
+	var y uint16
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x << y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 8589934592 {
+		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967296 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 18446744073709551615
+	y = 0
+	r = x << y
+	if r != 18446744073709551615 {
+		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 18446744073709551614 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551614", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 65535 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint64uint16rsh(t *testing.T) {
+	var x, r uint64
+	var y uint16
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x >> y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 2147483648 {
+		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967296 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 18446744073709551615
+	y = 0
+	r = x >> y
+	if r != 18446744073709551615 {
+		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 9223372036854775807 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 9223372036854775807", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 65535 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint64uint8lsh(t *testing.T) {
+	var x, r uint64
+	var y uint8
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x << y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 8589934592 {
+		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967296 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 18446744073709551615
+	y = 0
+	r = x << y
+	if r != 18446744073709551615 {
+		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 18446744073709551614 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 18446744073709551614", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 255 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint64uint8rsh(t *testing.T) {
+	var x, r uint64
+	var y uint8
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x >> y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 2147483648 {
+		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967296 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 18446744073709551615
+	y = 0
+	r = x >> y
+	if r != 18446744073709551615 {
+		t.Errorf("18446744073709551615 %s 0 = %d, want 18446744073709551615", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 9223372036854775807 {
+		t.Errorf("18446744073709551615 %s 1 = %d, want 9223372036854775807", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("18446744073709551615 %s 255 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint64uint64lsh(t *testing.T) {
+	var x, r int64
+	var y uint64
+	x = -9223372036854775808
+	y = 0
+	r = x << y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = -9223372036854775807
+	y = 0
+	r = x << y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = -4294967296
+	y = 0
+	r = x << y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -8589934592 {
+		t.Errorf("-4294967296 %s 1 = %d, want -8589934592", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-4294967296 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-4294967296 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x << y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 8589934592 {
+		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 9223372036854775806
+	y = 0
+	r = x << y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -4 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want -4", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 9223372036854775807
+	y = 0
+	r = x << y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint64uint64rsh(t *testing.T) {
+	var x, r int64
+	var y uint64
+	x = -9223372036854775808
+	y = 0
+	r = x >> y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -4611686018427387904 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want -4611686018427387904", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-9223372036854775808 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-9223372036854775808 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = -9223372036854775807
+	y = 0
+	r = x >> y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -4611686018427387904 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want -4611686018427387904", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-9223372036854775807 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-9223372036854775807 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = -4294967296
+	y = 0
+	r = x >> y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -2147483648 {
+		t.Errorf("-4294967296 %s 1 = %d, want -2147483648", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-4294967296 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-4294967296 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x >> y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 2147483648 {
+		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967296 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 9223372036854775806
+	y = 0
+	r = x >> y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 4611686018427387903 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want 4611686018427387903", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 9223372036854775807
+	y = 0
+	r = x >> y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 4611686018427387903 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want 4611686018427387903", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint64uint32lsh(t *testing.T) {
+	var x, r int64
+	var y uint32
+	x = -9223372036854775808
+	y = 0
+	r = x << y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = -9223372036854775807
+	y = 0
+	r = x << y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = -4294967296
+	y = 0
+	r = x << y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -8589934592 {
+		t.Errorf("-4294967296 %s 1 = %d, want -8589934592", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-4294967296 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x << y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 8589934592 {
+		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 9223372036854775806
+	y = 0
+	r = x << y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -4 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want -4", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 9223372036854775807
+	y = 0
+	r = x << y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 4294967295 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint64uint32rsh(t *testing.T) {
+	var x, r int64
+	var y uint32
+	x = -9223372036854775808
+	y = 0
+	r = x >> y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -4611686018427387904 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want -4611686018427387904", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-9223372036854775808 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = -9223372036854775807
+	y = 0
+	r = x >> y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -4611686018427387904 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want -4611686018427387904", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-9223372036854775807 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = -4294967296
+	y = 0
+	r = x >> y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -2147483648 {
+		t.Errorf("-4294967296 %s 1 = %d, want -2147483648", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-4294967296 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x >> y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 2147483648 {
+		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967296 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 9223372036854775806
+	y = 0
+	r = x >> y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 4611686018427387903 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want 4611686018427387903", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 9223372036854775807
+	y = 0
+	r = x >> y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 4611686018427387903 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want 4611686018427387903", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 4294967295 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint64uint16lsh(t *testing.T) {
+	var x, r int64
+	var y uint16
+	x = -9223372036854775808
+	y = 0
+	r = x << y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = -9223372036854775807
+	y = 0
+	r = x << y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = -4294967296
+	y = 0
+	r = x << y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -8589934592 {
+		t.Errorf("-4294967296 %s 1 = %d, want -8589934592", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-4294967296 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x << y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 8589934592 {
+		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967296 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 9223372036854775806
+	y = 0
+	r = x << y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -4 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want -4", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 9223372036854775807
+	y = 0
+	r = x << y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 65535 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint64uint16rsh(t *testing.T) {
+	var x, r int64
+	var y uint16
+	x = -9223372036854775808
+	y = 0
+	r = x >> y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -4611686018427387904 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want -4611686018427387904", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-9223372036854775808 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = -9223372036854775807
+	y = 0
+	r = x >> y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -4611686018427387904 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want -4611686018427387904", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-9223372036854775807 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = -4294967296
+	y = 0
+	r = x >> y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -2147483648 {
+		t.Errorf("-4294967296 %s 1 = %d, want -2147483648", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-4294967296 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x >> y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 2147483648 {
+		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967296 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 9223372036854775806
+	y = 0
+	r = x >> y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 4611686018427387903 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want 4611686018427387903", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 9223372036854775807
+	y = 0
+	r = x >> y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 4611686018427387903 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want 4611686018427387903", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 65535 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint64uint8lsh(t *testing.T) {
+	var x, r int64
+	var y uint8
+	x = -9223372036854775808
+	y = 0
+	r = x << y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775808 %s 255 = %d, want 0", "<<", r)
+	}
+	x = -9223372036854775807
+	y = 0
+	r = x << y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-9223372036854775807 %s 255 = %d, want 0", "<<", r)
+	}
+	x = -4294967296
+	y = 0
+	r = x << y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -8589934592 {
+		t.Errorf("-4294967296 %s 1 = %d, want -8589934592", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-4294967296 %s 255 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x << y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 8589934592 {
+		t.Errorf("4294967296 %s 1 = %d, want 8589934592", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967296 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 9223372036854775806
+	y = 0
+	r = x << y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -4 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want -4", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 9223372036854775807
+	y = 0
+	r = x << y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 255 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint64uint8rsh(t *testing.T) {
+	var x, r int64
+	var y uint8
+	x = -9223372036854775808
+	y = 0
+	r = x >> y
+	if r != -9223372036854775808 {
+		t.Errorf("-9223372036854775808 %s 0 = %d, want -9223372036854775808", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -4611686018427387904 {
+		t.Errorf("-9223372036854775808 %s 1 = %d, want -4611686018427387904", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-9223372036854775808 %s 255 = %d, want -1", ">>", r)
+	}
+	x = -9223372036854775807
+	y = 0
+	r = x >> y
+	if r != -9223372036854775807 {
+		t.Errorf("-9223372036854775807 %s 0 = %d, want -9223372036854775807", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -4611686018427387904 {
+		t.Errorf("-9223372036854775807 %s 1 = %d, want -4611686018427387904", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-9223372036854775807 %s 255 = %d, want -1", ">>", r)
+	}
+	x = -4294967296
+	y = 0
+	r = x >> y
+	if r != -4294967296 {
+		t.Errorf("-4294967296 %s 0 = %d, want -4294967296", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -2147483648 {
+		t.Errorf("-4294967296 %s 1 = %d, want -2147483648", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-4294967296 %s 255 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 255 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 4294967296
+	y = 0
+	r = x >> y
+	if r != 4294967296 {
+		t.Errorf("4294967296 %s 0 = %d, want 4294967296", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 2147483648 {
+		t.Errorf("4294967296 %s 1 = %d, want 2147483648", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967296 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 9223372036854775806
+	y = 0
+	r = x >> y
+	if r != 9223372036854775806 {
+		t.Errorf("9223372036854775806 %s 0 = %d, want 9223372036854775806", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 4611686018427387903 {
+		t.Errorf("9223372036854775806 %s 1 = %d, want 4611686018427387903", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("9223372036854775806 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 9223372036854775807
+	y = 0
+	r = x >> y
+	if r != 9223372036854775807 {
+		t.Errorf("9223372036854775807 %s 0 = %d, want 9223372036854775807", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 4611686018427387903 {
+		t.Errorf("9223372036854775807 %s 1 = %d, want 4611686018427387903", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("9223372036854775807 %s 255 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint32uint64lsh(t *testing.T) {
+	var x, r uint32
+	var y uint64
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 4294967295
+	y = 0
+	r = x << y
+	if r != 4294967295 {
+		t.Errorf("4294967295 %s 0 = %d, want 4294967295", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 4294967294 {
+		t.Errorf("4294967295 %s 1 = %d, want 4294967294", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967295 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967295 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint32uint64rsh(t *testing.T) {
+	var x, r uint32
+	var y uint64
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 4294967295
+	y = 0
+	r = x >> y
+	if r != 4294967295 {
+		t.Errorf("4294967295 %s 0 = %d, want 4294967295", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 2147483647 {
+		t.Errorf("4294967295 %s 1 = %d, want 2147483647", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967295 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967295 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint32uint32lsh(t *testing.T) {
+	var x, r uint32
+	var y uint32
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 4294967295
+	y = 0
+	r = x << y
+	if r != 4294967295 {
+		t.Errorf("4294967295 %s 0 = %d, want 4294967295", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 4294967294 {
+		t.Errorf("4294967295 %s 1 = %d, want 4294967294", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967295 %s 4294967295 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint32uint32rsh(t *testing.T) {
+	var x, r uint32
+	var y uint32
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 4294967295
+	y = 0
+	r = x >> y
+	if r != 4294967295 {
+		t.Errorf("4294967295 %s 0 = %d, want 4294967295", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 2147483647 {
+		t.Errorf("4294967295 %s 1 = %d, want 2147483647", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967295 %s 4294967295 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint32uint16lsh(t *testing.T) {
+	var x, r uint32
+	var y uint16
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 4294967295
+	y = 0
+	r = x << y
+	if r != 4294967295 {
+		t.Errorf("4294967295 %s 0 = %d, want 4294967295", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 4294967294 {
+		t.Errorf("4294967295 %s 1 = %d, want 4294967294", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967295 %s 65535 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint32uint16rsh(t *testing.T) {
+	var x, r uint32
+	var y uint16
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 4294967295
+	y = 0
+	r = x >> y
+	if r != 4294967295 {
+		t.Errorf("4294967295 %s 0 = %d, want 4294967295", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 2147483647 {
+		t.Errorf("4294967295 %s 1 = %d, want 2147483647", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967295 %s 65535 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint32uint8lsh(t *testing.T) {
+	var x, r uint32
+	var y uint8
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 4294967295
+	y = 0
+	r = x << y
+	if r != 4294967295 {
+		t.Errorf("4294967295 %s 0 = %d, want 4294967295", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 4294967294 {
+		t.Errorf("4294967295 %s 1 = %d, want 4294967294", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("4294967295 %s 255 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint32uint8rsh(t *testing.T) {
+	var x, r uint32
+	var y uint8
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 4294967295
+	y = 0
+	r = x >> y
+	if r != 4294967295 {
+		t.Errorf("4294967295 %s 0 = %d, want 4294967295", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 2147483647 {
+		t.Errorf("4294967295 %s 1 = %d, want 2147483647", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("4294967295 %s 255 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint32uint64lsh(t *testing.T) {
+	var x, r int32
+	var y uint64
+	x = -2147483648
+	y = 0
+	r = x << y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483648 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483648 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483648 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = -2147483647
+	y = 0
+	r = x << y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-2147483647 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483647 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483647 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 2147483647
+	y = 0
+	r = x << y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s 0 = %d, want 2147483647", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("2147483647 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("2147483647 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("2147483647 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint32uint64rsh(t *testing.T) {
+	var x, r int32
+	var y uint64
+	x = -2147483648
+	y = 0
+	r = x >> y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1073741824 {
+		t.Errorf("-2147483648 %s 1 = %d, want -1073741824", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-2147483648 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-2147483648 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = -2147483647
+	y = 0
+	r = x >> y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1073741824 {
+		t.Errorf("-2147483647 %s 1 = %d, want -1073741824", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-2147483647 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-2147483647 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 2147483647
+	y = 0
+	r = x >> y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s 0 = %d, want 2147483647", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 1073741823 {
+		t.Errorf("2147483647 %s 1 = %d, want 1073741823", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("2147483647 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("2147483647 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint32uint32lsh(t *testing.T) {
+	var x, r int32
+	var y uint32
+	x = -2147483648
+	y = 0
+	r = x << y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483648 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483648 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = -2147483647
+	y = 0
+	r = x << y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-2147483647 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483647 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 2147483647
+	y = 0
+	r = x << y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s 0 = %d, want 2147483647", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("2147483647 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("2147483647 %s 4294967295 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint32uint32rsh(t *testing.T) {
+	var x, r int32
+	var y uint32
+	x = -2147483648
+	y = 0
+	r = x >> y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1073741824 {
+		t.Errorf("-2147483648 %s 1 = %d, want -1073741824", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-2147483648 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = -2147483647
+	y = 0
+	r = x >> y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1073741824 {
+		t.Errorf("-2147483647 %s 1 = %d, want -1073741824", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-2147483647 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 2147483647
+	y = 0
+	r = x >> y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s 0 = %d, want 2147483647", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 1073741823 {
+		t.Errorf("2147483647 %s 1 = %d, want 1073741823", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("2147483647 %s 4294967295 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint32uint16lsh(t *testing.T) {
+	var x, r int32
+	var y uint16
+	x = -2147483648
+	y = 0
+	r = x << y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483648 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483648 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = -2147483647
+	y = 0
+	r = x << y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-2147483647 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483647 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 2147483647
+	y = 0
+	r = x << y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s 0 = %d, want 2147483647", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("2147483647 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("2147483647 %s 65535 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint32uint16rsh(t *testing.T) {
+	var x, r int32
+	var y uint16
+	x = -2147483648
+	y = 0
+	r = x >> y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1073741824 {
+		t.Errorf("-2147483648 %s 1 = %d, want -1073741824", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-2147483648 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = -2147483647
+	y = 0
+	r = x >> y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1073741824 {
+		t.Errorf("-2147483647 %s 1 = %d, want -1073741824", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-2147483647 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 2147483647
+	y = 0
+	r = x >> y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s 0 = %d, want 2147483647", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 1073741823 {
+		t.Errorf("2147483647 %s 1 = %d, want 1073741823", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("2147483647 %s 65535 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint32uint8lsh(t *testing.T) {
+	var x, r int32
+	var y uint8
+	x = -2147483648
+	y = 0
+	r = x << y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483648 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483648 %s 255 = %d, want 0", "<<", r)
+	}
+	x = -2147483647
+	y = 0
+	r = x << y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-2147483647 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-2147483647 %s 255 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 2147483647
+	y = 0
+	r = x << y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s 0 = %d, want 2147483647", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("2147483647 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("2147483647 %s 255 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint32uint8rsh(t *testing.T) {
+	var x, r int32
+	var y uint8
+	x = -2147483648
+	y = 0
+	r = x >> y
+	if r != -2147483648 {
+		t.Errorf("-2147483648 %s 0 = %d, want -2147483648", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1073741824 {
+		t.Errorf("-2147483648 %s 1 = %d, want -1073741824", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-2147483648 %s 255 = %d, want -1", ">>", r)
+	}
+	x = -2147483647
+	y = 0
+	r = x >> y
+	if r != -2147483647 {
+		t.Errorf("-2147483647 %s 0 = %d, want -2147483647", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1073741824 {
+		t.Errorf("-2147483647 %s 1 = %d, want -1073741824", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-2147483647 %s 255 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 255 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 2147483647
+	y = 0
+	r = x >> y
+	if r != 2147483647 {
+		t.Errorf("2147483647 %s 0 = %d, want 2147483647", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 1073741823 {
+		t.Errorf("2147483647 %s 1 = %d, want 1073741823", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("2147483647 %s 255 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint16uint64lsh(t *testing.T) {
+	var x, r uint16
+	var y uint64
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 65535
+	y = 0
+	r = x << y
+	if r != 65535 {
+		t.Errorf("65535 %s 0 = %d, want 65535", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 65534 {
+		t.Errorf("65535 %s 1 = %d, want 65534", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("65535 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("65535 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint16uint64rsh(t *testing.T) {
+	var x, r uint16
+	var y uint64
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 65535
+	y = 0
+	r = x >> y
+	if r != 65535 {
+		t.Errorf("65535 %s 0 = %d, want 65535", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 32767 {
+		t.Errorf("65535 %s 1 = %d, want 32767", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("65535 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("65535 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint16uint32lsh(t *testing.T) {
+	var x, r uint16
+	var y uint32
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 65535
+	y = 0
+	r = x << y
+	if r != 65535 {
+		t.Errorf("65535 %s 0 = %d, want 65535", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 65534 {
+		t.Errorf("65535 %s 1 = %d, want 65534", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("65535 %s 4294967295 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint16uint32rsh(t *testing.T) {
+	var x, r uint16
+	var y uint32
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 65535
+	y = 0
+	r = x >> y
+	if r != 65535 {
+		t.Errorf("65535 %s 0 = %d, want 65535", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 32767 {
+		t.Errorf("65535 %s 1 = %d, want 32767", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("65535 %s 4294967295 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint16uint16lsh(t *testing.T) {
+	var x, r uint16
+	var y uint16
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 65535
+	y = 0
+	r = x << y
+	if r != 65535 {
+		t.Errorf("65535 %s 0 = %d, want 65535", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 65534 {
+		t.Errorf("65535 %s 1 = %d, want 65534", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("65535 %s 65535 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint16uint16rsh(t *testing.T) {
+	var x, r uint16
+	var y uint16
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 65535
+	y = 0
+	r = x >> y
+	if r != 65535 {
+		t.Errorf("65535 %s 0 = %d, want 65535", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 32767 {
+		t.Errorf("65535 %s 1 = %d, want 32767", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("65535 %s 65535 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint16uint8lsh(t *testing.T) {
+	var x, r uint16
+	var y uint8
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 65535
+	y = 0
+	r = x << y
+	if r != 65535 {
+		t.Errorf("65535 %s 0 = %d, want 65535", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 65534 {
+		t.Errorf("65535 %s 1 = %d, want 65534", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("65535 %s 255 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint16uint8rsh(t *testing.T) {
+	var x, r uint16
+	var y uint8
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 65535
+	y = 0
+	r = x >> y
+	if r != 65535 {
+		t.Errorf("65535 %s 0 = %d, want 65535", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 32767 {
+		t.Errorf("65535 %s 1 = %d, want 32767", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("65535 %s 255 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint16uint64lsh(t *testing.T) {
+	var x, r int16
+	var y uint64
+	x = -32768
+	y = 0
+	r = x << y
+	if r != -32768 {
+		t.Errorf("-32768 %s 0 = %d, want -32768", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32768 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32768 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32768 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = -32767
+	y = 0
+	r = x << y
+	if r != -32767 {
+		t.Errorf("-32767 %s 0 = %d, want -32767", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-32767 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32767 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32767 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 32766
+	y = 0
+	r = x << y
+	if r != 32766 {
+		t.Errorf("32766 %s 0 = %d, want 32766", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -4 {
+		t.Errorf("32766 %s 1 = %d, want -4", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("32766 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("32766 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 32767
+	y = 0
+	r = x << y
+	if r != 32767 {
+		t.Errorf("32767 %s 0 = %d, want 32767", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("32767 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("32767 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("32767 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint16uint64rsh(t *testing.T) {
+	var x, r int16
+	var y uint64
+	x = -32768
+	y = 0
+	r = x >> y
+	if r != -32768 {
+		t.Errorf("-32768 %s 0 = %d, want -32768", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -16384 {
+		t.Errorf("-32768 %s 1 = %d, want -16384", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-32768 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-32768 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = -32767
+	y = 0
+	r = x >> y
+	if r != -32767 {
+		t.Errorf("-32767 %s 0 = %d, want -32767", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -16384 {
+		t.Errorf("-32767 %s 1 = %d, want -16384", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-32767 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-32767 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 32766
+	y = 0
+	r = x >> y
+	if r != 32766 {
+		t.Errorf("32766 %s 0 = %d, want 32766", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 16383 {
+		t.Errorf("32766 %s 1 = %d, want 16383", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("32766 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("32766 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 32767
+	y = 0
+	r = x >> y
+	if r != 32767 {
+		t.Errorf("32767 %s 0 = %d, want 32767", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 16383 {
+		t.Errorf("32767 %s 1 = %d, want 16383", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("32767 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("32767 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint16uint32lsh(t *testing.T) {
+	var x, r int16
+	var y uint32
+	x = -32768
+	y = 0
+	r = x << y
+	if r != -32768 {
+		t.Errorf("-32768 %s 0 = %d, want -32768", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32768 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32768 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = -32767
+	y = 0
+	r = x << y
+	if r != -32767 {
+		t.Errorf("-32767 %s 0 = %d, want -32767", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-32767 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32767 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 32766
+	y = 0
+	r = x << y
+	if r != 32766 {
+		t.Errorf("32766 %s 0 = %d, want 32766", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -4 {
+		t.Errorf("32766 %s 1 = %d, want -4", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("32766 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 32767
+	y = 0
+	r = x << y
+	if r != 32767 {
+		t.Errorf("32767 %s 0 = %d, want 32767", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("32767 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("32767 %s 4294967295 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint16uint32rsh(t *testing.T) {
+	var x, r int16
+	var y uint32
+	x = -32768
+	y = 0
+	r = x >> y
+	if r != -32768 {
+		t.Errorf("-32768 %s 0 = %d, want -32768", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -16384 {
+		t.Errorf("-32768 %s 1 = %d, want -16384", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-32768 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = -32767
+	y = 0
+	r = x >> y
+	if r != -32767 {
+		t.Errorf("-32767 %s 0 = %d, want -32767", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -16384 {
+		t.Errorf("-32767 %s 1 = %d, want -16384", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-32767 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 32766
+	y = 0
+	r = x >> y
+	if r != 32766 {
+		t.Errorf("32766 %s 0 = %d, want 32766", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 16383 {
+		t.Errorf("32766 %s 1 = %d, want 16383", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("32766 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 32767
+	y = 0
+	r = x >> y
+	if r != 32767 {
+		t.Errorf("32767 %s 0 = %d, want 32767", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 16383 {
+		t.Errorf("32767 %s 1 = %d, want 16383", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("32767 %s 4294967295 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint16uint16lsh(t *testing.T) {
+	var x, r int16
+	var y uint16
+	x = -32768
+	y = 0
+	r = x << y
+	if r != -32768 {
+		t.Errorf("-32768 %s 0 = %d, want -32768", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32768 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32768 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = -32767
+	y = 0
+	r = x << y
+	if r != -32767 {
+		t.Errorf("-32767 %s 0 = %d, want -32767", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-32767 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32767 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 32766
+	y = 0
+	r = x << y
+	if r != 32766 {
+		t.Errorf("32766 %s 0 = %d, want 32766", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -4 {
+		t.Errorf("32766 %s 1 = %d, want -4", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("32766 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 32767
+	y = 0
+	r = x << y
+	if r != 32767 {
+		t.Errorf("32767 %s 0 = %d, want 32767", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("32767 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("32767 %s 65535 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint16uint16rsh(t *testing.T) {
+	var x, r int16
+	var y uint16
+	x = -32768
+	y = 0
+	r = x >> y
+	if r != -32768 {
+		t.Errorf("-32768 %s 0 = %d, want -32768", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -16384 {
+		t.Errorf("-32768 %s 1 = %d, want -16384", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-32768 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = -32767
+	y = 0
+	r = x >> y
+	if r != -32767 {
+		t.Errorf("-32767 %s 0 = %d, want -32767", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -16384 {
+		t.Errorf("-32767 %s 1 = %d, want -16384", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-32767 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 32766
+	y = 0
+	r = x >> y
+	if r != 32766 {
+		t.Errorf("32766 %s 0 = %d, want 32766", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 16383 {
+		t.Errorf("32766 %s 1 = %d, want 16383", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("32766 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 32767
+	y = 0
+	r = x >> y
+	if r != 32767 {
+		t.Errorf("32767 %s 0 = %d, want 32767", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 16383 {
+		t.Errorf("32767 %s 1 = %d, want 16383", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("32767 %s 65535 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint16uint8lsh(t *testing.T) {
+	var x, r int16
+	var y uint8
+	x = -32768
+	y = 0
+	r = x << y
+	if r != -32768 {
+		t.Errorf("-32768 %s 0 = %d, want -32768", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32768 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32768 %s 255 = %d, want 0", "<<", r)
+	}
+	x = -32767
+	y = 0
+	r = x << y
+	if r != -32767 {
+		t.Errorf("-32767 %s 0 = %d, want -32767", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-32767 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-32767 %s 255 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 32766
+	y = 0
+	r = x << y
+	if r != 32766 {
+		t.Errorf("32766 %s 0 = %d, want 32766", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -4 {
+		t.Errorf("32766 %s 1 = %d, want -4", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("32766 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 32767
+	y = 0
+	r = x << y
+	if r != 32767 {
+		t.Errorf("32767 %s 0 = %d, want 32767", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("32767 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("32767 %s 255 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint16uint8rsh(t *testing.T) {
+	var x, r int16
+	var y uint8
+	x = -32768
+	y = 0
+	r = x >> y
+	if r != -32768 {
+		t.Errorf("-32768 %s 0 = %d, want -32768", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -16384 {
+		t.Errorf("-32768 %s 1 = %d, want -16384", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-32768 %s 255 = %d, want -1", ">>", r)
+	}
+	x = -32767
+	y = 0
+	r = x >> y
+	if r != -32767 {
+		t.Errorf("-32767 %s 0 = %d, want -32767", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -16384 {
+		t.Errorf("-32767 %s 1 = %d, want -16384", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-32767 %s 255 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 255 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 32766
+	y = 0
+	r = x >> y
+	if r != 32766 {
+		t.Errorf("32766 %s 0 = %d, want 32766", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 16383 {
+		t.Errorf("32766 %s 1 = %d, want 16383", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("32766 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 32767
+	y = 0
+	r = x >> y
+	if r != 32767 {
+		t.Errorf("32767 %s 0 = %d, want 32767", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 16383 {
+		t.Errorf("32767 %s 1 = %d, want 16383", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("32767 %s 255 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint8uint64lsh(t *testing.T) {
+	var x, r uint8
+	var y uint64
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 255
+	y = 0
+	r = x << y
+	if r != 255 {
+		t.Errorf("255 %s 0 = %d, want 255", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 254 {
+		t.Errorf("255 %s 1 = %d, want 254", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("255 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("255 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint8uint64rsh(t *testing.T) {
+	var x, r uint8
+	var y uint64
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 255
+	y = 0
+	r = x >> y
+	if r != 255 {
+		t.Errorf("255 %s 0 = %d, want 255", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 127 {
+		t.Errorf("255 %s 1 = %d, want 127", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("255 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("255 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint8uint32lsh(t *testing.T) {
+	var x, r uint8
+	var y uint32
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 255
+	y = 0
+	r = x << y
+	if r != 255 {
+		t.Errorf("255 %s 0 = %d, want 255", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 254 {
+		t.Errorf("255 %s 1 = %d, want 254", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("255 %s 4294967295 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint8uint32rsh(t *testing.T) {
+	var x, r uint8
+	var y uint32
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 255
+	y = 0
+	r = x >> y
+	if r != 255 {
+		t.Errorf("255 %s 0 = %d, want 255", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 127 {
+		t.Errorf("255 %s 1 = %d, want 127", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("255 %s 4294967295 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint8uint16lsh(t *testing.T) {
+	var x, r uint8
+	var y uint16
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 255
+	y = 0
+	r = x << y
+	if r != 255 {
+		t.Errorf("255 %s 0 = %d, want 255", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 254 {
+		t.Errorf("255 %s 1 = %d, want 254", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("255 %s 65535 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint8uint16rsh(t *testing.T) {
+	var x, r uint8
+	var y uint16
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 255
+	y = 0
+	r = x >> y
+	if r != 255 {
+		t.Errorf("255 %s 0 = %d, want 255", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 127 {
+		t.Errorf("255 %s 1 = %d, want 127", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("255 %s 65535 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFolduint8uint8lsh(t *testing.T) {
+	var x, r uint8
+	var y uint8
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 255
+	y = 0
+	r = x << y
+	if r != 255 {
+		t.Errorf("255 %s 0 = %d, want 255", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 254 {
+		t.Errorf("255 %s 1 = %d, want 254", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("255 %s 255 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFolduint8uint8rsh(t *testing.T) {
+	var x, r uint8
+	var y uint8
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 255
+	y = 0
+	r = x >> y
+	if r != 255 {
+		t.Errorf("255 %s 0 = %d, want 255", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 127 {
+		t.Errorf("255 %s 1 = %d, want 127", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("255 %s 255 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint8uint64lsh(t *testing.T) {
+	var x, r int8
+	var y uint64
+	x = -128
+	y = 0
+	r = x << y
+	if r != -128 {
+		t.Errorf("-128 %s 0 = %d, want -128", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-128 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-128 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-128 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = -127
+	y = 0
+	r = x << y
+	if r != -127 {
+		t.Errorf("-127 %s 0 = %d, want -127", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-127 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-127 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-127 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 126
+	y = 0
+	r = x << y
+	if r != 126 {
+		t.Errorf("126 %s 0 = %d, want 126", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -4 {
+		t.Errorf("126 %s 1 = %d, want -4", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("126 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("126 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+	x = 127
+	y = 0
+	r = x << y
+	if r != 127 {
+		t.Errorf("127 %s 0 = %d, want 127", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("127 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967296
+	r = x << y
+	if r != 0 {
+		t.Errorf("127 %s 4294967296 = %d, want 0", "<<", r)
+	}
+	y = 18446744073709551615
+	r = x << y
+	if r != 0 {
+		t.Errorf("127 %s 18446744073709551615 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint8uint64rsh(t *testing.T) {
+	var x, r int8
+	var y uint64
+	x = -128
+	y = 0
+	r = x >> y
+	if r != -128 {
+		t.Errorf("-128 %s 0 = %d, want -128", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -64 {
+		t.Errorf("-128 %s 1 = %d, want -64", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-128 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-128 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = -127
+	y = 0
+	r = x >> y
+	if r != -127 {
+		t.Errorf("-127 %s 0 = %d, want -127", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -64 {
+		t.Errorf("-127 %s 1 = %d, want -64", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-127 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-127 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 4294967296 = %d, want -1", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 18446744073709551615 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 126
+	y = 0
+	r = x >> y
+	if r != 126 {
+		t.Errorf("126 %s 0 = %d, want 126", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 63 {
+		t.Errorf("126 %s 1 = %d, want 63", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("126 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("126 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+	x = 127
+	y = 0
+	r = x >> y
+	if r != 127 {
+		t.Errorf("127 %s 0 = %d, want 127", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 63 {
+		t.Errorf("127 %s 1 = %d, want 63", ">>", r)
+	}
+	y = 4294967296
+	r = x >> y
+	if r != 0 {
+		t.Errorf("127 %s 4294967296 = %d, want 0", ">>", r)
+	}
+	y = 18446744073709551615
+	r = x >> y
+	if r != 0 {
+		t.Errorf("127 %s 18446744073709551615 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint8uint32lsh(t *testing.T) {
+	var x, r int8
+	var y uint32
+	x = -128
+	y = 0
+	r = x << y
+	if r != -128 {
+		t.Errorf("-128 %s 0 = %d, want -128", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-128 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-128 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = -127
+	y = 0
+	r = x << y
+	if r != -127 {
+		t.Errorf("-127 %s 0 = %d, want -127", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-127 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-127 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 126
+	y = 0
+	r = x << y
+	if r != 126 {
+		t.Errorf("126 %s 0 = %d, want 126", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -4 {
+		t.Errorf("126 %s 1 = %d, want -4", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("126 %s 4294967295 = %d, want 0", "<<", r)
+	}
+	x = 127
+	y = 0
+	r = x << y
+	if r != 127 {
+		t.Errorf("127 %s 0 = %d, want 127", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("127 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 4294967295
+	r = x << y
+	if r != 0 {
+		t.Errorf("127 %s 4294967295 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint8uint32rsh(t *testing.T) {
+	var x, r int8
+	var y uint32
+	x = -128
+	y = 0
+	r = x >> y
+	if r != -128 {
+		t.Errorf("-128 %s 0 = %d, want -128", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -64 {
+		t.Errorf("-128 %s 1 = %d, want -64", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-128 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = -127
+	y = 0
+	r = x >> y
+	if r != -127 {
+		t.Errorf("-127 %s 0 = %d, want -127", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -64 {
+		t.Errorf("-127 %s 1 = %d, want -64", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-127 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 4294967295 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 126
+	y = 0
+	r = x >> y
+	if r != 126 {
+		t.Errorf("126 %s 0 = %d, want 126", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 63 {
+		t.Errorf("126 %s 1 = %d, want 63", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("126 %s 4294967295 = %d, want 0", ">>", r)
+	}
+	x = 127
+	y = 0
+	r = x >> y
+	if r != 127 {
+		t.Errorf("127 %s 0 = %d, want 127", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 63 {
+		t.Errorf("127 %s 1 = %d, want 63", ">>", r)
+	}
+	y = 4294967295
+	r = x >> y
+	if r != 0 {
+		t.Errorf("127 %s 4294967295 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint8uint16lsh(t *testing.T) {
+	var x, r int8
+	var y uint16
+	x = -128
+	y = 0
+	r = x << y
+	if r != -128 {
+		t.Errorf("-128 %s 0 = %d, want -128", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-128 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-128 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = -127
+	y = 0
+	r = x << y
+	if r != -127 {
+		t.Errorf("-127 %s 0 = %d, want -127", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-127 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-127 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 126
+	y = 0
+	r = x << y
+	if r != 126 {
+		t.Errorf("126 %s 0 = %d, want 126", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -4 {
+		t.Errorf("126 %s 1 = %d, want -4", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("126 %s 65535 = %d, want 0", "<<", r)
+	}
+	x = 127
+	y = 0
+	r = x << y
+	if r != 127 {
+		t.Errorf("127 %s 0 = %d, want 127", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("127 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 65535
+	r = x << y
+	if r != 0 {
+		t.Errorf("127 %s 65535 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint8uint16rsh(t *testing.T) {
+	var x, r int8
+	var y uint16
+	x = -128
+	y = 0
+	r = x >> y
+	if r != -128 {
+		t.Errorf("-128 %s 0 = %d, want -128", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -64 {
+		t.Errorf("-128 %s 1 = %d, want -64", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-128 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = -127
+	y = 0
+	r = x >> y
+	if r != -127 {
+		t.Errorf("-127 %s 0 = %d, want -127", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -64 {
+		t.Errorf("-127 %s 1 = %d, want -64", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-127 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 65535 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 126
+	y = 0
+	r = x >> y
+	if r != 126 {
+		t.Errorf("126 %s 0 = %d, want 126", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 63 {
+		t.Errorf("126 %s 1 = %d, want 63", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("126 %s 65535 = %d, want 0", ">>", r)
+	}
+	x = 127
+	y = 0
+	r = x >> y
+	if r != 127 {
+		t.Errorf("127 %s 0 = %d, want 127", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 63 {
+		t.Errorf("127 %s 1 = %d, want 63", ">>", r)
+	}
+	y = 65535
+	r = x >> y
+	if r != 0 {
+		t.Errorf("127 %s 65535 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldint8uint8lsh(t *testing.T) {
+	var x, r int8
+	var y uint8
+	x = -128
+	y = 0
+	r = x << y
+	if r != -128 {
+		t.Errorf("-128 %s 0 = %d, want -128", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("-128 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-128 %s 255 = %d, want 0", "<<", r)
+	}
+	x = -127
+	y = 0
+	r = x << y
+	if r != -127 {
+		t.Errorf("-127 %s 0 = %d, want -127", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("-127 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-127 %s 255 = %d, want 0", "<<", r)
+	}
+	x = -1
+	y = 0
+	r = x << y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("-1 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("-1 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 0
+	y = 0
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 1
+	y = 0
+	r = x << y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != 2 {
+		t.Errorf("1 %s 1 = %d, want 2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 126
+	y = 0
+	r = x << y
+	if r != 126 {
+		t.Errorf("126 %s 0 = %d, want 126", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -4 {
+		t.Errorf("126 %s 1 = %d, want -4", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("126 %s 255 = %d, want 0", "<<", r)
+	}
+	x = 127
+	y = 0
+	r = x << y
+	if r != 127 {
+		t.Errorf("127 %s 0 = %d, want 127", "<<", r)
+	}
+	y = 1
+	r = x << y
+	if r != -2 {
+		t.Errorf("127 %s 1 = %d, want -2", "<<", r)
+	}
+	y = 255
+	r = x << y
+	if r != 0 {
+		t.Errorf("127 %s 255 = %d, want 0", "<<", r)
+	}
+}
+func TestConstFoldint8uint8rsh(t *testing.T) {
+	var x, r int8
+	var y uint8
+	x = -128
+	y = 0
+	r = x >> y
+	if r != -128 {
+		t.Errorf("-128 %s 0 = %d, want -128", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -64 {
+		t.Errorf("-128 %s 1 = %d, want -64", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-128 %s 255 = %d, want -1", ">>", r)
+	}
+	x = -127
+	y = 0
+	r = x >> y
+	if r != -127 {
+		t.Errorf("-127 %s 0 = %d, want -127", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -64 {
+		t.Errorf("-127 %s 1 = %d, want -64", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-127 %s 255 = %d, want -1", ">>", r)
+	}
+	x = -1
+	y = 0
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 0 = %d, want -1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 1 = %d, want -1", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != -1 {
+		t.Errorf("-1 %s 255 = %d, want -1", ">>", r)
+	}
+	x = 0
+	y = 0
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 0 = %d, want 0", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("0 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 1
+	y = 0
+	r = x >> y
+	if r != 1 {
+		t.Errorf("1 %s 0 = %d, want 1", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 1 = %d, want 0", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("1 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 126
+	y = 0
+	r = x >> y
+	if r != 126 {
+		t.Errorf("126 %s 0 = %d, want 126", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 63 {
+		t.Errorf("126 %s 1 = %d, want 63", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("126 %s 255 = %d, want 0", ">>", r)
+	}
+	x = 127
+	y = 0
+	r = x >> y
+	if r != 127 {
+		t.Errorf("127 %s 0 = %d, want 127", ">>", r)
+	}
+	y = 1
+	r = x >> y
+	if r != 63 {
+		t.Errorf("127 %s 1 = %d, want 63", ">>", r)
+	}
+	y = 255
+	r = x >> y
+	if r != 0 {
+		t.Errorf("127 %s 255 = %d, want 0", ">>", r)
+	}
+}
+func TestConstFoldCompareuint64(t *testing.T) {
+	{
+		var x uint64 = 0
+		var y uint64 = 0
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint64 = 0
+		var y uint64 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint64 = 0
+		var y uint64 = 4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint64 = 0
+		var y uint64 = 18446744073709551615
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint64 = 1
+		var y uint64 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint64 = 1
+		var y uint64 = 1
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint64 = 1
+		var y uint64 = 4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint64 = 1
+		var y uint64 = 18446744073709551615
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint64 = 4294967296
+		var y uint64 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint64 = 4294967296
+		var y uint64 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint64 = 4294967296
+		var y uint64 = 4294967296
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint64 = 4294967296
+		var y uint64 = 18446744073709551615
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint64 = 18446744073709551615
+		var y uint64 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint64 = 18446744073709551615
+		var y uint64 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint64 = 18446744073709551615
+		var y uint64 = 4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint64 = 18446744073709551615
+		var y uint64 = 18446744073709551615
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+}
+func TestConstFoldCompareint64(t *testing.T) {
+	{
+		var x int64 = -9223372036854775808
+		var y int64 = -9223372036854775808
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775808
+		var y int64 = -9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775808
+		var y int64 = -4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775808
+		var y int64 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775808
+		var y int64 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775808
+		var y int64 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775808
+		var y int64 = 4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775808
+		var y int64 = 9223372036854775806
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775808
+		var y int64 = 9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775807
+		var y int64 = -9223372036854775808
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775807
+		var y int64 = -9223372036854775807
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775807
+		var y int64 = -4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775807
+		var y int64 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775807
+		var y int64 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775807
+		var y int64 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775807
+		var y int64 = 4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775807
+		var y int64 = 9223372036854775806
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -9223372036854775807
+		var y int64 = 9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -4294967296
+		var y int64 = -9223372036854775808
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = -4294967296
+		var y int64 = -9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = -4294967296
+		var y int64 = -4294967296
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = -4294967296
+		var y int64 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -4294967296
+		var y int64 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -4294967296
+		var y int64 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -4294967296
+		var y int64 = 4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -4294967296
+		var y int64 = 9223372036854775806
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -4294967296
+		var y int64 = 9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -1
+		var y int64 = -9223372036854775808
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = -1
+		var y int64 = -9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = -1
+		var y int64 = -4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = -1
+		var y int64 = -1
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = -1
+		var y int64 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -1
+		var y int64 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -1
+		var y int64 = 4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -1
+		var y int64 = 9223372036854775806
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = -1
+		var y int64 = 9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = 0
+		var y int64 = -9223372036854775808
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 0
+		var y int64 = -9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 0
+		var y int64 = -4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 0
+		var y int64 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 0
+		var y int64 = 0
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 0
+		var y int64 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = 0
+		var y int64 = 4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = 0
+		var y int64 = 9223372036854775806
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = 0
+		var y int64 = 9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = 1
+		var y int64 = -9223372036854775808
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 1
+		var y int64 = -9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 1
+		var y int64 = -4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 1
+		var y int64 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 1
+		var y int64 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 1
+		var y int64 = 1
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 1
+		var y int64 = 4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = 1
+		var y int64 = 9223372036854775806
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = 1
+		var y int64 = 9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = 4294967296
+		var y int64 = -9223372036854775808
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 4294967296
+		var y int64 = -9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 4294967296
+		var y int64 = -4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 4294967296
+		var y int64 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 4294967296
+		var y int64 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 4294967296
+		var y int64 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 4294967296
+		var y int64 = 4294967296
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 4294967296
+		var y int64 = 9223372036854775806
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = 4294967296
+		var y int64 = 9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775806
+		var y int64 = -9223372036854775808
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775806
+		var y int64 = -9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775806
+		var y int64 = -4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775806
+		var y int64 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775806
+		var y int64 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775806
+		var y int64 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775806
+		var y int64 = 4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775806
+		var y int64 = 9223372036854775806
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775806
+		var y int64 = 9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775807
+		var y int64 = -9223372036854775808
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775807
+		var y int64 = -9223372036854775807
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775807
+		var y int64 = -4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775807
+		var y int64 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775807
+		var y int64 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775807
+		var y int64 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775807
+		var y int64 = 4294967296
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775807
+		var y int64 = 9223372036854775806
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int64 = 9223372036854775807
+		var y int64 = 9223372036854775807
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+}
+func TestConstFoldCompareuint32(t *testing.T) {
+	{
+		var x uint32 = 0
+		var y uint32 = 0
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint32 = 0
+		var y uint32 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint32 = 0
+		var y uint32 = 4294967295
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint32 = 1
+		var y uint32 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint32 = 1
+		var y uint32 = 1
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint32 = 1
+		var y uint32 = 4294967295
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint32 = 4294967295
+		var y uint32 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint32 = 4294967295
+		var y uint32 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint32 = 4294967295
+		var y uint32 = 4294967295
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+}
+func TestConstFoldCompareint32(t *testing.T) {
+	{
+		var x int32 = -2147483648
+		var y int32 = -2147483648
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = -2147483648
+		var y int32 = -2147483647
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = -2147483648
+		var y int32 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = -2147483648
+		var y int32 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = -2147483648
+		var y int32 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = -2147483648
+		var y int32 = 2147483647
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = -2147483647
+		var y int32 = -2147483648
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = -2147483647
+		var y int32 = -2147483647
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = -2147483647
+		var y int32 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = -2147483647
+		var y int32 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = -2147483647
+		var y int32 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = -2147483647
+		var y int32 = 2147483647
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = -1
+		var y int32 = -2147483648
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = -1
+		var y int32 = -2147483647
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = -1
+		var y int32 = -1
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = -1
+		var y int32 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = -1
+		var y int32 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = -1
+		var y int32 = 2147483647
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = 0
+		var y int32 = -2147483648
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 0
+		var y int32 = -2147483647
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 0
+		var y int32 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 0
+		var y int32 = 0
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 0
+		var y int32 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = 0
+		var y int32 = 2147483647
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = 1
+		var y int32 = -2147483648
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 1
+		var y int32 = -2147483647
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 1
+		var y int32 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 1
+		var y int32 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 1
+		var y int32 = 1
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 1
+		var y int32 = 2147483647
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int32 = 2147483647
+		var y int32 = -2147483648
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 2147483647
+		var y int32 = -2147483647
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 2147483647
+		var y int32 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 2147483647
+		var y int32 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 2147483647
+		var y int32 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int32 = 2147483647
+		var y int32 = 2147483647
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+}
+func TestConstFoldCompareuint16(t *testing.T) {
+	{
+		var x uint16 = 0
+		var y uint16 = 0
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint16 = 0
+		var y uint16 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint16 = 0
+		var y uint16 = 65535
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint16 = 1
+		var y uint16 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint16 = 1
+		var y uint16 = 1
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint16 = 1
+		var y uint16 = 65535
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint16 = 65535
+		var y uint16 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint16 = 65535
+		var y uint16 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint16 = 65535
+		var y uint16 = 65535
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+}
+func TestConstFoldCompareint16(t *testing.T) {
+	{
+		var x int16 = -32768
+		var y int16 = -32768
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = -32768
+		var y int16 = -32767
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -32768
+		var y int16 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -32768
+		var y int16 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -32768
+		var y int16 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -32768
+		var y int16 = 32766
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -32768
+		var y int16 = 32767
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -32767
+		var y int16 = -32768
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = -32767
+		var y int16 = -32767
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = -32767
+		var y int16 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -32767
+		var y int16 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -32767
+		var y int16 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -32767
+		var y int16 = 32766
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -32767
+		var y int16 = 32767
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -1
+		var y int16 = -32768
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = -1
+		var y int16 = -32767
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = -1
+		var y int16 = -1
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = -1
+		var y int16 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -1
+		var y int16 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -1
+		var y int16 = 32766
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = -1
+		var y int16 = 32767
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = 0
+		var y int16 = -32768
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 0
+		var y int16 = -32767
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 0
+		var y int16 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 0
+		var y int16 = 0
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 0
+		var y int16 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = 0
+		var y int16 = 32766
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = 0
+		var y int16 = 32767
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = 1
+		var y int16 = -32768
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 1
+		var y int16 = -32767
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 1
+		var y int16 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 1
+		var y int16 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 1
+		var y int16 = 1
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 1
+		var y int16 = 32766
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = 1
+		var y int16 = 32767
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = 32766
+		var y int16 = -32768
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 32766
+		var y int16 = -32767
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 32766
+		var y int16 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 32766
+		var y int16 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 32766
+		var y int16 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 32766
+		var y int16 = 32766
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 32766
+		var y int16 = 32767
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int16 = 32767
+		var y int16 = -32768
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 32767
+		var y int16 = -32767
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 32767
+		var y int16 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 32767
+		var y int16 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 32767
+		var y int16 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 32767
+		var y int16 = 32766
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int16 = 32767
+		var y int16 = 32767
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+}
+func TestConstFoldCompareuint8(t *testing.T) {
+	{
+		var x uint8 = 0
+		var y uint8 = 0
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint8 = 0
+		var y uint8 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint8 = 0
+		var y uint8 = 255
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint8 = 1
+		var y uint8 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint8 = 1
+		var y uint8 = 1
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint8 = 1
+		var y uint8 = 255
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x uint8 = 255
+		var y uint8 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint8 = 255
+		var y uint8 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x uint8 = 255
+		var y uint8 = 255
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+}
+func TestConstFoldCompareint8(t *testing.T) {
+	{
+		var x int8 = -128
+		var y int8 = -128
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = -128
+		var y int8 = -127
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -128
+		var y int8 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -128
+		var y int8 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -128
+		var y int8 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -128
+		var y int8 = 126
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -128
+		var y int8 = 127
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -127
+		var y int8 = -128
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = -127
+		var y int8 = -127
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = -127
+		var y int8 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -127
+		var y int8 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -127
+		var y int8 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -127
+		var y int8 = 126
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -127
+		var y int8 = 127
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -1
+		var y int8 = -128
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = -1
+		var y int8 = -127
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = -1
+		var y int8 = -1
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = -1
+		var y int8 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -1
+		var y int8 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -1
+		var y int8 = 126
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = -1
+		var y int8 = 127
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = 0
+		var y int8 = -128
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 0
+		var y int8 = -127
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 0
+		var y int8 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 0
+		var y int8 = 0
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 0
+		var y int8 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = 0
+		var y int8 = 126
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = 0
+		var y int8 = 127
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = 1
+		var y int8 = -128
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 1
+		var y int8 = -127
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 1
+		var y int8 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 1
+		var y int8 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 1
+		var y int8 = 1
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 1
+		var y int8 = 126
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = 1
+		var y int8 = 127
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = 126
+		var y int8 = -128
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 126
+		var y int8 = -127
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 126
+		var y int8 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 126
+		var y int8 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 126
+		var y int8 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 126
+		var y int8 = 126
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 126
+		var y int8 = 127
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if !(x < y) {
+			t.Errorf("!(%d < %d)", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if x >= y {
+			t.Errorf("%d >= %d", x, y)
+		}
+	}
+	{
+		var x int8 = 127
+		var y int8 = -128
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 127
+		var y int8 = -127
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 127
+		var y int8 = -1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 127
+		var y int8 = 0
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 127
+		var y int8 = 1
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 127
+		var y int8 = 126
+		if x == y {
+			t.Errorf("%d == %d", x, y)
+		}
+		if !(x != y) {
+			t.Errorf("!(%d != %d)", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if !(x > y) {
+			t.Errorf("!(%d > %d)", x, y)
+		}
+		if x <= y {
+			t.Errorf("%d <= %d", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+	{
+		var x int8 = 127
+		var y int8 = 127
+		if !(x == y) {
+			t.Errorf("!(%d == %d)", x, y)
+		}
+		if x != y {
+			t.Errorf("%d != %d", x, y)
+		}
+		if x < y {
+			t.Errorf("%d < %d", x, y)
+		}
+		if x > y {
+			t.Errorf("%d > %d", x, y)
+		}
+		if !(x <= y) {
+			t.Errorf("!(%d <= %d)", x, y)
+		}
+		if !(x >= y) {
+			t.Errorf("!(%d >= %d)", x, y)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/test/dep_test.go b/src/cmd/compile/internal/test/dep_test.go
new file mode 100644
index 0000000..698a848
--- /dev/null
+++ b/src/cmd/compile/internal/test/dep_test.go
@@ -0,0 +1,30 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test
+
+import (
+	"internal/testenv"
+	"os/exec"
+	"strings"
+	"testing"
+)
+
+func TestDeps(t *testing.T) {
+	out, err := exec.Command(testenv.GoToolPath(t), "list", "-f", "{{.Deps}}", "cmd/compile/internal/gc").Output()
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, dep := range strings.Fields(strings.Trim(string(out), "[]")) {
+		switch dep {
+		case "go/build", "go/scanner":
+			// cmd/compile/internal/importer introduces a dependency
+			// on go/build and go/token; cmd/compile/internal/ uses
+			// go/constant which uses go/token in its API. Once we
+			// got rid of those dependencies, enable this check again.
+			// TODO(gri) fix this
+			// t.Errorf("undesired dependency on %q", dep)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/test/fixedbugs_test.go b/src/cmd/compile/internal/test/fixedbugs_test.go
new file mode 100644
index 0000000..376b45e
--- /dev/null
+++ b/src/cmd/compile/internal/test/fixedbugs_test.go
@@ -0,0 +1,92 @@
+// 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 test
+
+import (
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+type T struct {
+	x [2]int64 // field that will be clobbered. Also makes type not SSAable.
+	p *byte    // has a pointer
+}
+
+//go:noinline
+func makeT() T {
+	return T{}
+}
+
+var g T
+
+var sink interface{}
+
+func TestIssue15854(t *testing.T) {
+	for i := 0; i < 10000; i++ {
+		if g.x[0] != 0 {
+			t.Fatalf("g.x[0] clobbered with %x\n", g.x[0])
+		}
+		// The bug was in the following assignment. The return
+		// value of makeT() is not copied out of the args area of
+		// stack frame in a timely fashion. So when write barriers
+		// are enabled, the marshaling of the args for the write
+		// barrier call clobbers the result of makeT() before it is
+		// read by the write barrier code.
+		g = makeT()
+		sink = make([]byte, 1000) // force write barriers to eventually happen
+	}
+}
+func TestIssue15854b(t *testing.T) {
+	const N = 10000
+	a := make([]T, N)
+	for i := 0; i < N; i++ {
+		a = append(a, makeT())
+		sink = make([]byte, 1000) // force write barriers to eventually happen
+	}
+	for i, v := range a {
+		if v.x[0] != 0 {
+			t.Fatalf("a[%d].x[0] clobbered with %x\n", i, v.x[0])
+		}
+	}
+}
+
+// Test that the generated assembly has line numbers (Issue #16214).
+func TestIssue16214(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+	dir, err := ioutil.TempDir("", "TestLineNumber")
+	if err != nil {
+		t.Fatalf("could not create directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	src := filepath.Join(dir, "x.go")
+	err = ioutil.WriteFile(src, []byte(issue16214src), 0644)
+	if err != nil {
+		t.Fatalf("could not write file: %v", err)
+	}
+
+	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-S", "-o", filepath.Join(dir, "out.o"), src)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("go tool compile: %v\n%s", err, out)
+	}
+
+	if strings.Contains(string(out), "unknown line number") {
+		t.Errorf("line number missing in assembly:\n%s", out)
+	}
+}
+
+var issue16214src = `
+package main
+
+func Mod32(x uint32) uint32 {
+	return x % 3 // frontend rewrites it as HMUL with 2863311531, the LITERAL node has unknown Pos
+}
+`
diff --git a/src/cmd/compile/internal/test/float_test.go b/src/cmd/compile/internal/test/float_test.go
new file mode 100644
index 0000000..884a983
--- /dev/null
+++ b/src/cmd/compile/internal/test/float_test.go
@@ -0,0 +1,544 @@
+// 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 test
+
+import (
+	"math"
+	"testing"
+)
+
+//go:noinline
+func compare1(a, b float64) bool {
+	return a < b
+}
+
+//go:noinline
+func compare2(a, b float32) bool {
+	return a < b
+}
+
+func TestFloatCompare(t *testing.T) {
+	if !compare1(3, 5) {
+		t.Errorf("compare1 returned false")
+	}
+	if !compare2(3, 5) {
+		t.Errorf("compare2 returned false")
+	}
+}
+
+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")
+	}
+}
+
+//go:noinline
+func cvt1(a float64) uint64 {
+	return uint64(a)
+}
+
+//go:noinline
+func cvt2(a float64) uint32 {
+	return uint32(a)
+}
+
+//go:noinline
+func cvt3(a float32) uint64 {
+	return uint64(a)
+}
+
+//go:noinline
+func cvt4(a float32) uint32 {
+	return uint32(a)
+}
+
+//go:noinline
+func cvt5(a float64) int64 {
+	return int64(a)
+}
+
+//go:noinline
+func cvt6(a float64) int32 {
+	return int32(a)
+}
+
+//go:noinline
+func cvt7(a float32) int64 {
+	return int64(a)
+}
+
+//go:noinline
+func cvt8(a float32) int32 {
+	return int32(a)
+}
+
+// make sure to cover int, uint cases (issue #16738)
+//go:noinline
+func cvt9(a float64) int {
+	return int(a)
+}
+
+//go:noinline
+func cvt10(a float64) uint {
+	return uint(a)
+}
+
+//go:noinline
+func cvt11(a float32) int {
+	return int(a)
+}
+
+//go:noinline
+func cvt12(a float32) uint {
+	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)
+	}
+	if got := cvt2(3.5); got != 3 {
+		t.Errorf("cvt2 got %d, wanted 3", got)
+	}
+	if got := cvt3(3.5); got != 3 {
+		t.Errorf("cvt3 got %d, wanted 3", got)
+	}
+	if got := cvt4(3.5); got != 3 {
+		t.Errorf("cvt4 got %d, wanted 3", got)
+	}
+	if got := cvt5(3.5); got != 3 {
+		t.Errorf("cvt5 got %d, wanted 3", got)
+	}
+	if got := cvt6(3.5); got != 3 {
+		t.Errorf("cvt6 got %d, wanted 3", got)
+	}
+	if got := cvt7(3.5); got != 3 {
+		t.Errorf("cvt7 got %d, wanted 3", got)
+	}
+	if got := cvt8(3.5); got != 3 {
+		t.Errorf("cvt8 got %d, wanted 3", got)
+	}
+	if got := cvt9(3.5); got != 3 {
+		t.Errorf("cvt9 got %d, wanted 3", got)
+	}
+	if got := cvt10(3.5); got != 3 {
+		t.Errorf("cvt10 got %d, wanted 3", got)
+	}
+	if got := cvt11(3.5); got != 3 {
+		t.Errorf("cvt11 got %d, wanted 3", got)
+	}
+	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")
+	}
+}
+
+func TestFloat32StoreToLoadConstantFold(t *testing.T) {
+	// Test that math.Float32{,from}bits constant fold correctly.
+	// In particular we need to be careful that signaling NaN (sNaN) values
+	// are not converted to quiet NaN (qNaN) values during compilation.
+	// See issue #27193 for more information.
+
+	// signaling NaNs
+	{
+		const nan = uint32(0x7f800001) // sNaN
+		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
+			t.Errorf("got %#x, want %#x", x, nan)
+		}
+	}
+	{
+		const nan = uint32(0x7fbfffff) // sNaN
+		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
+			t.Errorf("got %#x, want %#x", x, nan)
+		}
+	}
+	{
+		const nan = uint32(0xff800001) // sNaN
+		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
+			t.Errorf("got %#x, want %#x", x, nan)
+		}
+	}
+	{
+		const nan = uint32(0xffbfffff) // sNaN
+		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
+			t.Errorf("got %#x, want %#x", x, nan)
+		}
+	}
+
+	// quiet NaNs
+	{
+		const nan = uint32(0x7fc00000) // qNaN
+		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
+			t.Errorf("got %#x, want %#x", x, nan)
+		}
+	}
+	{
+		const nan = uint32(0x7fffffff) // qNaN
+		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
+			t.Errorf("got %#x, want %#x", x, nan)
+		}
+	}
+	{
+		const nan = uint32(0x8fc00000) // qNaN
+		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
+			t.Errorf("got %#x, want %#x", x, nan)
+		}
+	}
+	{
+		const nan = uint32(0x8fffffff) // qNaN
+		if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
+			t.Errorf("got %#x, want %#x", x, nan)
+		}
+	}
+
+	// infinities
+	{
+		const inf = uint32(0x7f800000) // +∞
+		if x := math.Float32bits(math.Float32frombits(inf)); x != inf {
+			t.Errorf("got %#x, want %#x", x, inf)
+		}
+	}
+	{
+		const negInf = uint32(0xff800000) // -∞
+		if x := math.Float32bits(math.Float32frombits(negInf)); x != negInf {
+			t.Errorf("got %#x, want %#x", x, negInf)
+		}
+	}
+
+	// numbers
+	{
+		const zero = uint32(0) // +0.0
+		if x := math.Float32bits(math.Float32frombits(zero)); x != zero {
+			t.Errorf("got %#x, want %#x", x, zero)
+		}
+	}
+	{
+		const negZero = uint32(1 << 31) // -0.0
+		if x := math.Float32bits(math.Float32frombits(negZero)); x != negZero {
+			t.Errorf("got %#x, want %#x", x, negZero)
+		}
+	}
+	{
+		const one = uint32(0x3f800000) // 1.0
+		if x := math.Float32bits(math.Float32frombits(one)); x != one {
+			t.Errorf("got %#x, want %#x", x, one)
+		}
+	}
+	{
+		const negOne = uint32(0xbf800000) // -1.0
+		if x := math.Float32bits(math.Float32frombits(negOne)); x != negOne {
+			t.Errorf("got %#x, want %#x", x, negOne)
+		}
+	}
+	{
+		const frac = uint32(0x3fc00000) // +1.5
+		if x := math.Float32bits(math.Float32frombits(frac)); x != frac {
+			t.Errorf("got %#x, want %#x", x, frac)
+		}
+	}
+	{
+		const negFrac = uint32(0xbfc00000) // -1.5
+		if x := math.Float32bits(math.Float32frombits(negFrac)); x != negFrac {
+			t.Errorf("got %#x, want %#x", x, negFrac)
+		}
+	}
+}
+
+// Signaling NaN values as constants.
+const (
+	snan32bits uint32 = 0x7f800001
+	snan64bits uint64 = 0x7ff0000000000001
+)
+
+// Signaling NaNs as variables.
+var snan32bitsVar uint32 = snan32bits
+var snan64bitsVar uint64 = snan64bits
+
+func TestFloatSignalingNaN(t *testing.T) {
+	// Make sure we generate a signaling NaN from a constant properly.
+	// See issue 36400.
+	f32 := math.Float32frombits(snan32bits)
+	g32 := math.Float32frombits(snan32bitsVar)
+	x32 := math.Float32bits(f32)
+	y32 := math.Float32bits(g32)
+	if x32 != y32 {
+		t.Errorf("got %x, want %x (diff=%x)", x32, y32, x32^y32)
+	}
+
+	f64 := math.Float64frombits(snan64bits)
+	g64 := math.Float64frombits(snan64bitsVar)
+	x64 := math.Float64bits(f64)
+	y64 := math.Float64bits(g64)
+	if x64 != y64 {
+		t.Errorf("got %x, want %x (diff=%x)", x64, y64, x64^y64)
+	}
+}
+
+func TestFloatSignalingNaNConversion(t *testing.T) {
+	// Test to make sure when we convert a signaling NaN, we get a NaN.
+	// (Ideally we want a quiet NaN, but some platforms don't agree.)
+	// See issue 36399.
+	s32 := math.Float32frombits(snan32bitsVar)
+	if s32 == s32 {
+		t.Errorf("converting a NaN did not result in a NaN")
+	}
+	s64 := math.Float64frombits(snan64bitsVar)
+	if s64 == s64 {
+		t.Errorf("converting a NaN did not result in a NaN")
+	}
+}
+
+func TestFloatSignalingNaNConversionConst(t *testing.T) {
+	// Test to make sure when we convert a signaling NaN, it converts to a NaN.
+	// (Ideally we want a quiet NaN, but some platforms don't agree.)
+	// See issue 36399 and 36400.
+	s32 := math.Float32frombits(snan32bits)
+	if s32 == s32 {
+		t.Errorf("converting a NaN did not result in a NaN")
+	}
+	s64 := math.Float64frombits(snan64bits)
+	if s64 == s64 {
+		t.Errorf("converting a NaN did not result in a NaN")
+	}
+}
+
+var sinkFloat float64
+
+func BenchmarkMul2(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var m float64 = 1
+		for j := 0; j < 500; j++ {
+			m *= 2
+		}
+		sinkFloat = m
+	}
+}
+func BenchmarkMulNeg2(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var m float64 = 1
+		for j := 0; j < 500; j++ {
+			m *= -2
+		}
+		sinkFloat = m
+	}
+}
diff --git a/src/cmd/compile/internal/test/global_test.go b/src/cmd/compile/internal/test/global_test.go
new file mode 100644
index 0000000..93de894
--- /dev/null
+++ b/src/cmd/compile/internal/test/global_test.go
@@ -0,0 +1,116 @@
+// 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 test
+
+import (
+	"bytes"
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+// Make sure "hello world" does not link in all the
+// fmt.scanf routines. See issue 6853.
+func TestScanfRemoval(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+	t.Parallel()
+
+	// Make a directory to work in.
+	dir, err := ioutil.TempDir("", "issue6853a-")
+	if err != nil {
+		t.Fatalf("could not create directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	// Create source.
+	src := filepath.Join(dir, "test.go")
+	f, err := os.Create(src)
+	if err != nil {
+		t.Fatalf("could not create source file: %v", err)
+	}
+	f.Write([]byte(`
+package main
+import "fmt"
+func main() {
+	fmt.Println("hello world")
+}
+`))
+	f.Close()
+
+	// Name of destination.
+	dst := filepath.Join(dir, "test")
+
+	// Compile source.
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dst, src)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("could not build target: %v\n%s", err, out)
+	}
+
+	// Check destination to see if scanf code was included.
+	cmd = exec.Command(testenv.GoToolPath(t), "tool", "nm", dst)
+	out, err = cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("could not read target: %v", err)
+	}
+	if bytes.Contains(out, []byte("scanInt")) {
+		t.Fatalf("scanf code not removed from helloworld")
+	}
+}
+
+// Make sure -S prints assembly code. See issue 14515.
+func TestDashS(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+	t.Parallel()
+
+	// Make a directory to work in.
+	dir, err := ioutil.TempDir("", "issue14515-")
+	if err != nil {
+		t.Fatalf("could not create directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	// Create source.
+	src := filepath.Join(dir, "test.go")
+	f, err := os.Create(src)
+	if err != nil {
+		t.Fatalf("could not create source file: %v", err)
+	}
+	f.Write([]byte(`
+package main
+import "fmt"
+func main() {
+	fmt.Println("hello world")
+}
+`))
+	f.Close()
+
+	// Compile source.
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags", "-S", "-o", filepath.Join(dir, "test"), src)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("could not build target: %v\n%s", err, out)
+	}
+
+	patterns := []string{
+		// It is hard to look for actual instructions in an
+		// arch-independent way. So we'll just look for
+		// pseudo-ops that are arch-independent.
+		"\tTEXT\t",
+		"\tFUNCDATA\t",
+		"\tPCDATA\t",
+	}
+	outstr := string(out)
+	for _, p := range patterns {
+		if !strings.Contains(outstr, p) {
+			println(outstr)
+			panic("can't find pattern " + p)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/test/iface_test.go b/src/cmd/compile/internal/test/iface_test.go
new file mode 100644
index 0000000..ebc4f89
--- /dev/null
+++ b/src/cmd/compile/internal/test/iface_test.go
@@ -0,0 +1,126 @@
+// 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 test
+
+import "testing"
+
+// Test to make sure we make copies of the values we
+// put in interfaces.
+
+var x int
+
+func TestEfaceConv1(t *testing.T) {
+	a := 5
+	i := interface{}(a)
+	a += 2
+	if got := i.(int); got != 5 {
+		t.Errorf("wanted 5, got %d\n", got)
+	}
+}
+
+func TestEfaceConv2(t *testing.T) {
+	a := 5
+	sink = &a
+	i := interface{}(a)
+	a += 2
+	if got := i.(int); got != 5 {
+		t.Errorf("wanted 5, got %d\n", got)
+	}
+}
+
+func TestEfaceConv3(t *testing.T) {
+	x = 5
+	if got := e2int3(x); got != 5 {
+		t.Errorf("wanted 5, got %d\n", got)
+	}
+}
+
+//go:noinline
+func e2int3(i interface{}) int {
+	x = 7
+	return i.(int)
+}
+
+func TestEfaceConv4(t *testing.T) {
+	a := 5
+	if got := e2int4(a, &a); got != 5 {
+		t.Errorf("wanted 5, got %d\n", got)
+	}
+}
+
+//go:noinline
+func e2int4(i interface{}, p *int) int {
+	*p = 7
+	return i.(int)
+}
+
+type Int int
+
+var y Int
+
+type I interface {
+	foo()
+}
+
+func (i Int) foo() {
+}
+
+func TestIfaceConv1(t *testing.T) {
+	a := Int(5)
+	i := interface{}(a)
+	a += 2
+	if got := i.(Int); got != 5 {
+		t.Errorf("wanted 5, got %d\n", int(got))
+	}
+}
+
+func TestIfaceConv2(t *testing.T) {
+	a := Int(5)
+	sink = &a
+	i := interface{}(a)
+	a += 2
+	if got := i.(Int); got != 5 {
+		t.Errorf("wanted 5, got %d\n", int(got))
+	}
+}
+
+func TestIfaceConv3(t *testing.T) {
+	y = 5
+	if got := i2Int3(y); got != 5 {
+		t.Errorf("wanted 5, got %d\n", int(got))
+	}
+}
+
+//go:noinline
+func i2Int3(i I) Int {
+	y = 7
+	return i.(Int)
+}
+
+func TestIfaceConv4(t *testing.T) {
+	a := Int(5)
+	if got := i2Int4(a, &a); got != 5 {
+		t.Errorf("wanted 5, got %d\n", int(got))
+	}
+}
+
+//go:noinline
+func i2Int4(i I, p *Int) Int {
+	*p = 7
+	return i.(Int)
+}
+
+func BenchmarkEfaceInteger(b *testing.B) {
+	sum := 0
+	for i := 0; i < b.N; i++ {
+		sum += i2int(i)
+	}
+	sink = sum
+}
+
+//go:noinline
+func i2int(i interface{}) int {
+	return i.(int)
+}
diff --git a/src/cmd/compile/internal/test/inl_test.go b/src/cmd/compile/internal/test/inl_test.go
new file mode 100644
index 0000000..6f10003
--- /dev/null
+++ b/src/cmd/compile/internal/test/inl_test.go
@@ -0,0 +1,272 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test
+
+import (
+	"bufio"
+	"internal/testenv"
+	"io"
+	"math/bits"
+	"os/exec"
+	"regexp"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+// TestIntendedInlining tests that specific 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 inlinable. If they have no callers in their packages, they
+	// might not actually be inlined anywhere.
+	want := map[string][]string{
+		"runtime": {
+			"add",
+			"acquirem",
+			"add1",
+			"addb",
+			"adjustpanics",
+			"adjustpointer",
+			"alignDown",
+			"alignUp",
+			"bucketMask",
+			"bucketShift",
+			"chanbuf",
+			"deferArgs",
+			"deferclass",
+			"evacuated",
+			"fastlog2",
+			"fastrand",
+			"float64bits",
+			"funcPC",
+			"getArgInfoFast",
+			"getm",
+			"getMCache",
+			"isDirectIface",
+			"itabHashFunc",
+			"noescape",
+			"pcvalueCacheKey",
+			"readUnaligned32",
+			"readUnaligned64",
+			"releasem",
+			"roundupsize",
+			"stackmapdata",
+			"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",
+			"markBits.isMarked",
+			"muintptr.ptr",
+			"puintptr.ptr",
+			"spanOf",
+			"spanOfUnchecked",
+			"(*gcWork).putFast",
+			"(*gcWork).tryGetFast",
+			"(*guintptr).set",
+			"(*markBits).advance",
+			"(*mspan).allocBitsForIndex",
+			"(*mspan).base",
+			"(*mspan).markBitsForBase",
+			"(*mspan).markBitsForIndex",
+			"(*muintptr).set",
+			"(*puintptr).set",
+		},
+		"runtime/internal/sys": {},
+		"runtime/internal/math": {
+			"MulUintptr",
+		},
+		"bytes": {
+			"(*Buffer).Bytes",
+			"(*Buffer).Cap",
+			"(*Buffer).Len",
+			"(*Buffer).Grow",
+			"(*Buffer).Next",
+			"(*Buffer).Read",
+			"(*Buffer).ReadByte",
+			"(*Buffer).Reset",
+			"(*Buffer).String",
+			"(*Buffer).UnreadByte",
+			"(*Buffer).tryGrowByReslice",
+		},
+		"compress/flate": {
+			"byLiteral.Len",
+			"byLiteral.Less",
+			"byLiteral.Swap",
+			"(*dictDecoder).tryWriteCopy",
+		},
+		"encoding/base64": {
+			"assemble32",
+			"assemble64",
+		},
+		"unicode/utf8": {
+			"FullRune",
+			"FullRuneInString",
+			"RuneLen",
+			"ValidRune",
+		},
+		"reflect": {
+			"Value.CanAddr",
+			"Value.CanSet",
+			"Value.CanInterface",
+			"Value.IsValid",
+			"Value.pointer",
+			"add",
+			"align",
+			"flag.mustBe",
+			"flag.mustBeAssignable",
+			"flag.mustBeExported",
+			"flag.kind",
+			"flag.ro",
+		},
+		"regexp": {
+			"(*bitState).push",
+		},
+		"math/big": {
+			"bigEndianWord",
+			// The following functions require the math_big_pure_go build tag.
+			"addVW",
+			"subVW",
+		},
+		"math/rand": {
+			"(*rngSource).Int63",
+			"(*rngSource).Uint64",
+		},
+		"net": {
+			"(*UDPConn).ReadFromUDP",
+		},
+	}
+
+	if runtime.GOARCH != "386" && runtime.GOARCH != "mips64" && runtime.GOARCH != "mips64le" && runtime.GOARCH != "riscv64" {
+		// 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 and riscv64, 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")
+	}
+	if bits.UintSize == 64 {
+		// mix is only defined on 64-bit architectures
+		want["runtime"] = append(want["runtime"], "mix")
+	}
+
+	switch runtime.GOARCH {
+	case "386", "wasm", "arm":
+	default:
+		// TODO(mvdan): As explained in /test/inline_sync.go, some
+		// architectures don't have atomic intrinsics, so these go over
+		// the inlining budget. Move back to the main table once that
+		// problem is solved.
+		want["sync"] = []string{
+			"(*Mutex).Lock",
+			"(*Mutex).Unlock",
+			"(*RWMutex).RLock",
+			"(*RWMutex).RUnlock",
+			"(*Once).Do",
+		}
+	}
+
+	// Functions that must actually be inlined; they must have actual callers.
+	must := map[string]bool{
+		"compress/flate.byLiteral.Len":  true,
+		"compress/flate.byLiteral.Less": true,
+		"compress/flate.byLiteral.Swap": true,
+	}
+
+	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", "-tags=math_big_pure_go"}, 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 ([^ ]*)`)
+	haveInlined := regexp.MustCompile(`: inlining call to ([^ ]*)`)
+	cannotInline := regexp.MustCompile(`: cannot inline ([^ ]*): (.*)`)
+	for scanner.Scan() {
+		line := scanner.Text()
+		if strings.HasPrefix(line, "# ") {
+			curPkg = line[2:]
+			continue
+		}
+		if m := haveInlined.FindStringSubmatch(line); m != nil {
+			fname := m[1]
+			delete(notInlinedReason, curPkg+"."+fname)
+			continue
+		}
+		if m := canInline.FindStringSubmatch(line); m != nil {
+			fname := m[1]
+			fullname := curPkg + "." + fname
+			// If function must be inlined somewhere, being inlinable is not enough
+			if _, ok := must[fullname]; !ok {
+				delete(notInlinedReason, fullname)
+				continue
+			}
+		}
+		if m := cannotInline.FindStringSubmatch(line); m != nil {
+			fname, reason := m[1], m[2]
+			fullName := curPkg + "." + fname
+			if _, ok := notInlinedReason[fullName]; ok {
+				// cmd/compile gave us a reason why
+				notInlinedReason[fullName] = reason
+			}
+			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/test/lang_test.go b/src/cmd/compile/internal/test/lang_test.go
new file mode 100644
index 0000000..67c1551
--- /dev/null
+++ b/src/cmd/compile/internal/test/lang_test.go
@@ -0,0 +1,64 @@
+// 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 test
+
+import (
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"testing"
+)
+
+const aliasSrc = `
+package x
+
+type T = int
+`
+
+func TestInvalidLang(t *testing.T) {
+	t.Parallel()
+
+	testenv.MustHaveGoBuild(t)
+
+	dir, err := ioutil.TempDir("", "TestInvalidLang")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
+
+	src := filepath.Join(dir, "alias.go")
+	if err := ioutil.WriteFile(src, []byte(aliasSrc), 0644); err != nil {
+		t.Fatal(err)
+	}
+
+	outfile := filepath.Join(dir, "alias.o")
+
+	if testLang(t, "go9.99", src, outfile) == nil {
+		t.Error("compilation with -lang=go9.99 succeeded unexpectedly")
+	}
+
+	// This test will have to be adjusted if we ever reach 1.99 or 2.0.
+	if testLang(t, "go1.99", src, outfile) == nil {
+		t.Error("compilation with -lang=go1.99 succeeded unexpectedly")
+	}
+
+	if testLang(t, "go1.8", src, outfile) == nil {
+		t.Error("compilation with -lang=go1.8 succeeded unexpectedly")
+	}
+
+	if err := testLang(t, "go1.9", src, outfile); err != nil {
+		t.Errorf("compilation with -lang=go1.9 failed unexpectedly: %v", err)
+	}
+}
+
+func testLang(t *testing.T, lang, src, outfile string) error {
+	run := []string{testenv.GoToolPath(t), "tool", "compile", "-lang", lang, "-o", outfile, src}
+	t.Log(run)
+	out, err := exec.Command(run[0], run[1:]...).CombinedOutput()
+	t.Logf("%s", out)
+	return err
+}
diff --git a/src/cmd/compile/internal/test/logic_test.go b/src/cmd/compile/internal/test/logic_test.go
new file mode 100644
index 0000000..1d7043f
--- /dev/null
+++ b/src/cmd/compile/internal/test/logic_test.go
@@ -0,0 +1,289 @@
+package test
+
+import "testing"
+
+// Tests to make sure logic simplification rules are correct.
+
+func TestLogic64(t *testing.T) {
+	// test values to determine function equality
+	values := [...]int64{-1 << 63, 1<<63 - 1, -4, -3, -2, -1, 0, 1, 2, 3, 4}
+
+	// golden functions we use repeatedly
+	zero := func(x int64) int64 { return 0 }
+	id := func(x int64) int64 { return x }
+	or := func(x, y int64) int64 { return x | y }
+	and := func(x, y int64) int64 { return x & y }
+	y := func(x, y int64) int64 { return y }
+
+	for _, test := range [...]struct {
+		name   string
+		f      func(int64) int64
+		golden func(int64) int64
+	}{
+		{"x|x", func(x int64) int64 { return x | x }, id},
+		{"x|0", func(x int64) int64 { return x | 0 }, id},
+		{"x|-1", func(x int64) int64 { return x | -1 }, func(x int64) int64 { return -1 }},
+		{"x&x", func(x int64) int64 { return x & x }, id},
+		{"x&0", func(x int64) int64 { return x & 0 }, zero},
+		{"x&-1", func(x int64) int64 { return x & -1 }, id},
+		{"x^x", func(x int64) int64 { return x ^ x }, zero},
+		{"x^0", func(x int64) int64 { return x ^ 0 }, id},
+		{"x^-1", func(x int64) int64 { return x ^ -1 }, func(x int64) int64 { return ^x }},
+		{"x+0", func(x int64) int64 { return x + 0 }, id},
+		{"x-x", func(x int64) int64 { return x - x }, zero},
+		{"x*0", func(x int64) int64 { return x * 0 }, zero},
+		{"^^x", func(x int64) int64 { return ^^x }, id},
+	} {
+		for _, v := range values {
+			got := test.f(v)
+			want := test.golden(v)
+			if want != got {
+				t.Errorf("[%s](%d)=%d, want %d", test.name, v, got, want)
+			}
+		}
+	}
+	for _, test := range [...]struct {
+		name   string
+		f      func(int64, int64) int64
+		golden func(int64, int64) int64
+	}{
+		{"x|(x|y)", func(x, y int64) int64 { return x | (x | y) }, or},
+		{"x|(y|x)", func(x, y int64) int64 { return x | (y | x) }, or},
+		{"(x|y)|x", func(x, y int64) int64 { return (x | y) | x }, or},
+		{"(y|x)|x", func(x, y int64) int64 { return (y | x) | x }, or},
+		{"x&(x&y)", func(x, y int64) int64 { return x & (x & y) }, and},
+		{"x&(y&x)", func(x, y int64) int64 { return x & (y & x) }, and},
+		{"(x&y)&x", func(x, y int64) int64 { return (x & y) & x }, and},
+		{"(y&x)&x", func(x, y int64) int64 { return (y & x) & x }, and},
+		{"x^(x^y)", func(x, y int64) int64 { return x ^ (x ^ y) }, y},
+		{"x^(y^x)", func(x, y int64) int64 { return x ^ (y ^ x) }, y},
+		{"(x^y)^x", func(x, y int64) int64 { return (x ^ y) ^ x }, y},
+		{"(y^x)^x", func(x, y int64) int64 { return (y ^ x) ^ x }, y},
+		{"-(y-x)", func(x, y int64) int64 { return -(y - x) }, func(x, y int64) int64 { return x - y }},
+		{"(x+y)-x", func(x, y int64) int64 { return (x + y) - x }, y},
+		{"(y+x)-x", func(x, y int64) int64 { return (y + x) - x }, y},
+	} {
+		for _, v := range values {
+			for _, w := range values {
+				got := test.f(v, w)
+				want := test.golden(v, w)
+				if want != got {
+					t.Errorf("[%s](%d,%d)=%d, want %d", test.name, v, w, got, want)
+				}
+			}
+		}
+	}
+}
+
+func TestLogic32(t *testing.T) {
+	// test values to determine function equality
+	values := [...]int32{-1 << 31, 1<<31 - 1, -4, -3, -2, -1, 0, 1, 2, 3, 4}
+
+	// golden functions we use repeatedly
+	zero := func(x int32) int32 { return 0 }
+	id := func(x int32) int32 { return x }
+	or := func(x, y int32) int32 { return x | y }
+	and := func(x, y int32) int32 { return x & y }
+	y := func(x, y int32) int32 { return y }
+
+	for _, test := range [...]struct {
+		name   string
+		f      func(int32) int32
+		golden func(int32) int32
+	}{
+		{"x|x", func(x int32) int32 { return x | x }, id},
+		{"x|0", func(x int32) int32 { return x | 0 }, id},
+		{"x|-1", func(x int32) int32 { return x | -1 }, func(x int32) int32 { return -1 }},
+		{"x&x", func(x int32) int32 { return x & x }, id},
+		{"x&0", func(x int32) int32 { return x & 0 }, zero},
+		{"x&-1", func(x int32) int32 { return x & -1 }, id},
+		{"x^x", func(x int32) int32 { return x ^ x }, zero},
+		{"x^0", func(x int32) int32 { return x ^ 0 }, id},
+		{"x^-1", func(x int32) int32 { return x ^ -1 }, func(x int32) int32 { return ^x }},
+		{"x+0", func(x int32) int32 { return x + 0 }, id},
+		{"x-x", func(x int32) int32 { return x - x }, zero},
+		{"x*0", func(x int32) int32 { return x * 0 }, zero},
+		{"^^x", func(x int32) int32 { return ^^x }, id},
+	} {
+		for _, v := range values {
+			got := test.f(v)
+			want := test.golden(v)
+			if want != got {
+				t.Errorf("[%s](%d)=%d, want %d", test.name, v, got, want)
+			}
+		}
+	}
+	for _, test := range [...]struct {
+		name   string
+		f      func(int32, int32) int32
+		golden func(int32, int32) int32
+	}{
+		{"x|(x|y)", func(x, y int32) int32 { return x | (x | y) }, or},
+		{"x|(y|x)", func(x, y int32) int32 { return x | (y | x) }, or},
+		{"(x|y)|x", func(x, y int32) int32 { return (x | y) | x }, or},
+		{"(y|x)|x", func(x, y int32) int32 { return (y | x) | x }, or},
+		{"x&(x&y)", func(x, y int32) int32 { return x & (x & y) }, and},
+		{"x&(y&x)", func(x, y int32) int32 { return x & (y & x) }, and},
+		{"(x&y)&x", func(x, y int32) int32 { return (x & y) & x }, and},
+		{"(y&x)&x", func(x, y int32) int32 { return (y & x) & x }, and},
+		{"x^(x^y)", func(x, y int32) int32 { return x ^ (x ^ y) }, y},
+		{"x^(y^x)", func(x, y int32) int32 { return x ^ (y ^ x) }, y},
+		{"(x^y)^x", func(x, y int32) int32 { return (x ^ y) ^ x }, y},
+		{"(y^x)^x", func(x, y int32) int32 { return (y ^ x) ^ x }, y},
+		{"-(y-x)", func(x, y int32) int32 { return -(y - x) }, func(x, y int32) int32 { return x - y }},
+		{"(x+y)-x", func(x, y int32) int32 { return (x + y) - x }, y},
+		{"(y+x)-x", func(x, y int32) int32 { return (y + x) - x }, y},
+	} {
+		for _, v := range values {
+			for _, w := range values {
+				got := test.f(v, w)
+				want := test.golden(v, w)
+				if want != got {
+					t.Errorf("[%s](%d,%d)=%d, want %d", test.name, v, w, got, want)
+				}
+			}
+		}
+	}
+}
+
+func TestLogic16(t *testing.T) {
+	// test values to determine function equality
+	values := [...]int16{-1 << 15, 1<<15 - 1, -4, -3, -2, -1, 0, 1, 2, 3, 4}
+
+	// golden functions we use repeatedly
+	zero := func(x int16) int16 { return 0 }
+	id := func(x int16) int16 { return x }
+	or := func(x, y int16) int16 { return x | y }
+	and := func(x, y int16) int16 { return x & y }
+	y := func(x, y int16) int16 { return y }
+
+	for _, test := range [...]struct {
+		name   string
+		f      func(int16) int16
+		golden func(int16) int16
+	}{
+		{"x|x", func(x int16) int16 { return x | x }, id},
+		{"x|0", func(x int16) int16 { return x | 0 }, id},
+		{"x|-1", func(x int16) int16 { return x | -1 }, func(x int16) int16 { return -1 }},
+		{"x&x", func(x int16) int16 { return x & x }, id},
+		{"x&0", func(x int16) int16 { return x & 0 }, zero},
+		{"x&-1", func(x int16) int16 { return x & -1 }, id},
+		{"x^x", func(x int16) int16 { return x ^ x }, zero},
+		{"x^0", func(x int16) int16 { return x ^ 0 }, id},
+		{"x^-1", func(x int16) int16 { return x ^ -1 }, func(x int16) int16 { return ^x }},
+		{"x+0", func(x int16) int16 { return x + 0 }, id},
+		{"x-x", func(x int16) int16 { return x - x }, zero},
+		{"x*0", func(x int16) int16 { return x * 0 }, zero},
+		{"^^x", func(x int16) int16 { return ^^x }, id},
+	} {
+		for _, v := range values {
+			got := test.f(v)
+			want := test.golden(v)
+			if want != got {
+				t.Errorf("[%s](%d)=%d, want %d", test.name, v, got, want)
+			}
+		}
+	}
+	for _, test := range [...]struct {
+		name   string
+		f      func(int16, int16) int16
+		golden func(int16, int16) int16
+	}{
+		{"x|(x|y)", func(x, y int16) int16 { return x | (x | y) }, or},
+		{"x|(y|x)", func(x, y int16) int16 { return x | (y | x) }, or},
+		{"(x|y)|x", func(x, y int16) int16 { return (x | y) | x }, or},
+		{"(y|x)|x", func(x, y int16) int16 { return (y | x) | x }, or},
+		{"x&(x&y)", func(x, y int16) int16 { return x & (x & y) }, and},
+		{"x&(y&x)", func(x, y int16) int16 { return x & (y & x) }, and},
+		{"(x&y)&x", func(x, y int16) int16 { return (x & y) & x }, and},
+		{"(y&x)&x", func(x, y int16) int16 { return (y & x) & x }, and},
+		{"x^(x^y)", func(x, y int16) int16 { return x ^ (x ^ y) }, y},
+		{"x^(y^x)", func(x, y int16) int16 { return x ^ (y ^ x) }, y},
+		{"(x^y)^x", func(x, y int16) int16 { return (x ^ y) ^ x }, y},
+		{"(y^x)^x", func(x, y int16) int16 { return (y ^ x) ^ x }, y},
+		{"-(y-x)", func(x, y int16) int16 { return -(y - x) }, func(x, y int16) int16 { return x - y }},
+		{"(x+y)-x", func(x, y int16) int16 { return (x + y) - x }, y},
+		{"(y+x)-x", func(x, y int16) int16 { return (y + x) - x }, y},
+	} {
+		for _, v := range values {
+			for _, w := range values {
+				got := test.f(v, w)
+				want := test.golden(v, w)
+				if want != got {
+					t.Errorf("[%s](%d,%d)=%d, want %d", test.name, v, w, got, want)
+				}
+			}
+		}
+	}
+}
+
+func TestLogic8(t *testing.T) {
+	// test values to determine function equality
+	values := [...]int8{-1 << 7, 1<<7 - 1, -4, -3, -2, -1, 0, 1, 2, 3, 4}
+
+	// golden functions we use repeatedly
+	zero := func(x int8) int8 { return 0 }
+	id := func(x int8) int8 { return x }
+	or := func(x, y int8) int8 { return x | y }
+	and := func(x, y int8) int8 { return x & y }
+	y := func(x, y int8) int8 { return y }
+
+	for _, test := range [...]struct {
+		name   string
+		f      func(int8) int8
+		golden func(int8) int8
+	}{
+		{"x|x", func(x int8) int8 { return x | x }, id},
+		{"x|0", func(x int8) int8 { return x | 0 }, id},
+		{"x|-1", func(x int8) int8 { return x | -1 }, func(x int8) int8 { return -1 }},
+		{"x&x", func(x int8) int8 { return x & x }, id},
+		{"x&0", func(x int8) int8 { return x & 0 }, zero},
+		{"x&-1", func(x int8) int8 { return x & -1 }, id},
+		{"x^x", func(x int8) int8 { return x ^ x }, zero},
+		{"x^0", func(x int8) int8 { return x ^ 0 }, id},
+		{"x^-1", func(x int8) int8 { return x ^ -1 }, func(x int8) int8 { return ^x }},
+		{"x+0", func(x int8) int8 { return x + 0 }, id},
+		{"x-x", func(x int8) int8 { return x - x }, zero},
+		{"x*0", func(x int8) int8 { return x * 0 }, zero},
+		{"^^x", func(x int8) int8 { return ^^x }, id},
+	} {
+		for _, v := range values {
+			got := test.f(v)
+			want := test.golden(v)
+			if want != got {
+				t.Errorf("[%s](%d)=%d, want %d", test.name, v, got, want)
+			}
+		}
+	}
+	for _, test := range [...]struct {
+		name   string
+		f      func(int8, int8) int8
+		golden func(int8, int8) int8
+	}{
+		{"x|(x|y)", func(x, y int8) int8 { return x | (x | y) }, or},
+		{"x|(y|x)", func(x, y int8) int8 { return x | (y | x) }, or},
+		{"(x|y)|x", func(x, y int8) int8 { return (x | y) | x }, or},
+		{"(y|x)|x", func(x, y int8) int8 { return (y | x) | x }, or},
+		{"x&(x&y)", func(x, y int8) int8 { return x & (x & y) }, and},
+		{"x&(y&x)", func(x, y int8) int8 { return x & (y & x) }, and},
+		{"(x&y)&x", func(x, y int8) int8 { return (x & y) & x }, and},
+		{"(y&x)&x", func(x, y int8) int8 { return (y & x) & x }, and},
+		{"x^(x^y)", func(x, y int8) int8 { return x ^ (x ^ y) }, y},
+		{"x^(y^x)", func(x, y int8) int8 { return x ^ (y ^ x) }, y},
+		{"(x^y)^x", func(x, y int8) int8 { return (x ^ y) ^ x }, y},
+		{"(y^x)^x", func(x, y int8) int8 { return (y ^ x) ^ x }, y},
+		{"-(y-x)", func(x, y int8) int8 { return -(y - x) }, func(x, y int8) int8 { return x - y }},
+		{"(x+y)-x", func(x, y int8) int8 { return (x + y) - x }, y},
+		{"(y+x)-x", func(x, y int8) int8 { return (y + x) - x }, y},
+	} {
+		for _, v := range values {
+			for _, w := range values {
+				got := test.f(v, w)
+				want := test.golden(v, w)
+				if want != got {
+					t.Errorf("[%s](%d,%d)=%d, want %d", test.name, v, w, got, want)
+				}
+			}
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/test/reproduciblebuilds_test.go b/src/cmd/compile/internal/test/reproduciblebuilds_test.go
new file mode 100644
index 0000000..4d84f9c
--- /dev/null
+++ b/src/cmd/compile/internal/test/reproduciblebuilds_test.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.
+
+package test
+
+import (
+	"bytes"
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"testing"
+)
+
+func TestReproducibleBuilds(t *testing.T) {
+	tests := []string{
+		"issue20272.go",
+		"issue27013.go",
+		"issue30202.go",
+	}
+
+	testenv.MustHaveGoBuild(t)
+	iters := 10
+	if testing.Short() {
+		iters = 4
+	}
+	t.Parallel()
+	for _, test := range tests {
+		test := test
+		t.Run(test, func(t *testing.T) {
+			t.Parallel()
+			var want []byte
+			tmp, err := ioutil.TempFile("", "")
+			if err != nil {
+				t.Fatalf("temp file creation failed: %v", err)
+			}
+			defer os.Remove(tmp.Name())
+			defer tmp.Close()
+			for i := 0; i < iters; i++ {
+				// Note: use -c 2 to expose any nondeterminism which is the result
+				// of the runtime scheduler.
+				out, err := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-c", "2", "-o", tmp.Name(), filepath.Join("testdata", "reproducible", test)).CombinedOutput()
+				if err != nil {
+					t.Fatalf("failed to compile: %v\n%s", err, out)
+				}
+				obj, err := ioutil.ReadFile(tmp.Name())
+				if err != nil {
+					t.Fatalf("failed to read object file: %v", err)
+				}
+				if i == 0 {
+					want = obj
+				} else {
+					if !bytes.Equal(want, obj) {
+						t.Fatalf("builds produced different output after %d iters (%d bytes vs %d bytes)", i, len(want), len(obj))
+					}
+				}
+			}
+		})
+	}
+}
+
+func TestIssue38068(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+	t.Parallel()
+
+	// Compile a small package with and without the concurrent
+	// backend, then check to make sure that the resulting archives
+	// are identical.  Note: this uses "go tool compile" instead of
+	// "go build" since the latter will generate differnent build IDs
+	// if it sees different command line flags.
+	scenarios := []struct {
+		tag     string
+		args    string
+		libpath string
+	}{
+		{tag: "serial", args: "-c=1"},
+		{tag: "concurrent", args: "-c=2"}}
+
+	tmpdir, err := ioutil.TempDir("", "TestIssue38068")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	src := filepath.Join("testdata", "reproducible", "issue38068.go")
+	for i := range scenarios {
+		s := &scenarios[i]
+		s.libpath = filepath.Join(tmpdir, s.tag+".a")
+		// Note: use of "-p" required in order for DWARF to be generated.
+		cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-trimpath", "-p=issue38068", "-buildid=", s.args, "-o", s.libpath, src)
+		out, err := cmd.CombinedOutput()
+		if err != nil {
+			t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
+		}
+	}
+
+	readBytes := func(fn string) []byte {
+		payload, err := ioutil.ReadFile(fn)
+		if err != nil {
+			t.Fatalf("failed to read executable '%s': %v", fn, err)
+		}
+		return payload
+	}
+
+	b1 := readBytes(scenarios[0].libpath)
+	b2 := readBytes(scenarios[1].libpath)
+	if !bytes.Equal(b1, b2) {
+		t.Fatalf("concurrent and serial builds produced different output")
+	}
+}
diff --git a/src/cmd/compile/internal/test/shift_test.go b/src/cmd/compile/internal/test/shift_test.go
new file mode 100644
index 0000000..ea88f0a
--- /dev/null
+++ b/src/cmd/compile/internal/test/shift_test.go
@@ -0,0 +1,1031 @@
+// 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 test
+
+import (
+	"reflect"
+	"testing"
+)
+
+// Tests shifts of zero.
+
+//go:noinline
+func ofz64l64(n uint64) int64 {
+	var x int64
+	return x << n
+}
+
+//go:noinline
+func ofz64l32(n uint32) int64 {
+	var x int64
+	return x << n
+}
+
+//go:noinline
+func ofz64l16(n uint16) int64 {
+	var x int64
+	return x << n
+}
+
+//go:noinline
+func ofz64l8(n uint8) int64 {
+	var x int64
+	return x << n
+}
+
+//go:noinline
+func ofz64r64(n uint64) int64 {
+	var x int64
+	return x >> n
+}
+
+//go:noinline
+func ofz64r32(n uint32) int64 {
+	var x int64
+	return x >> n
+}
+
+//go:noinline
+func ofz64r16(n uint16) int64 {
+	var x int64
+	return x >> n
+}
+
+//go:noinline
+func ofz64r8(n uint8) int64 {
+	var x int64
+	return x >> n
+}
+
+//go:noinline
+func ofz64ur64(n uint64) uint64 {
+	var x uint64
+	return x >> n
+}
+
+//go:noinline
+func ofz64ur32(n uint32) uint64 {
+	var x uint64
+	return x >> n
+}
+
+//go:noinline
+func ofz64ur16(n uint16) uint64 {
+	var x uint64
+	return x >> n
+}
+
+//go:noinline
+func ofz64ur8(n uint8) uint64 {
+	var x uint64
+	return x >> n
+}
+
+//go:noinline
+func ofz32l64(n uint64) int32 {
+	var x int32
+	return x << n
+}
+
+//go:noinline
+func ofz32l32(n uint32) int32 {
+	var x int32
+	return x << n
+}
+
+//go:noinline
+func ofz32l16(n uint16) int32 {
+	var x int32
+	return x << n
+}
+
+//go:noinline
+func ofz32l8(n uint8) int32 {
+	var x int32
+	return x << n
+}
+
+//go:noinline
+func ofz32r64(n uint64) int32 {
+	var x int32
+	return x >> n
+}
+
+//go:noinline
+func ofz32r32(n uint32) int32 {
+	var x int32
+	return x >> n
+}
+
+//go:noinline
+func ofz32r16(n uint16) int32 {
+	var x int32
+	return x >> n
+}
+
+//go:noinline
+func ofz32r8(n uint8) int32 {
+	var x int32
+	return x >> n
+}
+
+//go:noinline
+func ofz32ur64(n uint64) uint32 {
+	var x uint32
+	return x >> n
+}
+
+//go:noinline
+func ofz32ur32(n uint32) uint32 {
+	var x uint32
+	return x >> n
+}
+
+//go:noinline
+func ofz32ur16(n uint16) uint32 {
+	var x uint32
+	return x >> n
+}
+
+//go:noinline
+func ofz32ur8(n uint8) uint32 {
+	var x uint32
+	return x >> n
+}
+
+//go:noinline
+func ofz16l64(n uint64) int16 {
+	var x int16
+	return x << n
+}
+
+//go:noinline
+func ofz16l32(n uint32) int16 {
+	var x int16
+	return x << n
+}
+
+//go:noinline
+func ofz16l16(n uint16) int16 {
+	var x int16
+	return x << n
+}
+
+//go:noinline
+func ofz16l8(n uint8) int16 {
+	var x int16
+	return x << n
+}
+
+//go:noinline
+func ofz16r64(n uint64) int16 {
+	var x int16
+	return x >> n
+}
+
+//go:noinline
+func ofz16r32(n uint32) int16 {
+	var x int16
+	return x >> n
+}
+
+//go:noinline
+func ofz16r16(n uint16) int16 {
+	var x int16
+	return x >> n
+}
+
+//go:noinline
+func ofz16r8(n uint8) int16 {
+	var x int16
+	return x >> n
+}
+
+//go:noinline
+func ofz16ur64(n uint64) uint16 {
+	var x uint16
+	return x >> n
+}
+
+//go:noinline
+func ofz16ur32(n uint32) uint16 {
+	var x uint16
+	return x >> n
+}
+
+//go:noinline
+func ofz16ur16(n uint16) uint16 {
+	var x uint16
+	return x >> n
+}
+
+//go:noinline
+func ofz16ur8(n uint8) uint16 {
+	var x uint16
+	return x >> n
+}
+
+//go:noinline
+func ofz8l64(n uint64) int8 {
+	var x int8
+	return x << n
+}
+
+//go:noinline
+func ofz8l32(n uint32) int8 {
+	var x int8
+	return x << n
+}
+
+//go:noinline
+func ofz8l16(n uint16) int8 {
+	var x int8
+	return x << n
+}
+
+//go:noinline
+func ofz8l8(n uint8) int8 {
+	var x int8
+	return x << n
+}
+
+//go:noinline
+func ofz8r64(n uint64) int8 {
+	var x int8
+	return x >> n
+}
+
+//go:noinline
+func ofz8r32(n uint32) int8 {
+	var x int8
+	return x >> n
+}
+
+//go:noinline
+func ofz8r16(n uint16) int8 {
+	var x int8
+	return x >> n
+}
+
+//go:noinline
+func ofz8r8(n uint8) int8 {
+	var x int8
+	return x >> n
+}
+
+//go:noinline
+func ofz8ur64(n uint64) uint8 {
+	var x uint8
+	return x >> n
+}
+
+//go:noinline
+func ofz8ur32(n uint32) uint8 {
+	var x uint8
+	return x >> n
+}
+
+//go:noinline
+func ofz8ur16(n uint16) uint8 {
+	var x uint8
+	return x >> n
+}
+
+//go:noinline
+func ofz8ur8(n uint8) uint8 {
+	var x uint8
+	return x >> n
+}
+
+func TestShiftOfZero(t *testing.T) {
+	if got := ofz64l64(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz64l32(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz64l16(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz64l8(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz64r64(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz64r32(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz64r16(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz64r8(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz64ur64(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+	if got := ofz64ur32(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+	if got := ofz64ur16(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+	if got := ofz64ur8(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+
+	if got := ofz32l64(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz32l32(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz32l16(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz32l8(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz32r64(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz32r32(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz32r16(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz32r8(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz32ur64(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+	if got := ofz32ur32(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+	if got := ofz32ur16(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+	if got := ofz32ur8(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+
+	if got := ofz16l64(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz16l32(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz16l16(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz16l8(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz16r64(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz16r32(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz16r16(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz16r8(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz16ur64(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+	if got := ofz16ur32(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+	if got := ofz16ur16(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+	if got := ofz16ur8(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+
+	if got := ofz8l64(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz8l32(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz8l16(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz8l8(5); got != 0 {
+		t.Errorf("0<<5 == %d, want 0", got)
+	}
+	if got := ofz8r64(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz8r32(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz8r16(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz8r8(5); got != 0 {
+		t.Errorf("0>>5 == %d, want 0", got)
+	}
+	if got := ofz8ur64(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+	if got := ofz8ur32(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+	if got := ofz8ur16(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+	if got := ofz8ur8(5); got != 0 {
+		t.Errorf("0>>>5 == %d, want 0", got)
+	}
+}
+
+//go:noinline
+func byz64l(n int64) int64 {
+	return n << 0
+}
+
+//go:noinline
+func byz64r(n int64) int64 {
+	return n >> 0
+}
+
+//go:noinline
+func byz64ur(n uint64) uint64 {
+	return n >> 0
+}
+
+//go:noinline
+func byz32l(n int32) int32 {
+	return n << 0
+}
+
+//go:noinline
+func byz32r(n int32) int32 {
+	return n >> 0
+}
+
+//go:noinline
+func byz32ur(n uint32) uint32 {
+	return n >> 0
+}
+
+//go:noinline
+func byz16l(n int16) int16 {
+	return n << 0
+}
+
+//go:noinline
+func byz16r(n int16) int16 {
+	return n >> 0
+}
+
+//go:noinline
+func byz16ur(n uint16) uint16 {
+	return n >> 0
+}
+
+//go:noinline
+func byz8l(n int8) int8 {
+	return n << 0
+}
+
+//go:noinline
+func byz8r(n int8) int8 {
+	return n >> 0
+}
+
+//go:noinline
+func byz8ur(n uint8) uint8 {
+	return n >> 0
+}
+
+func TestShiftByZero(t *testing.T) {
+	{
+		var n int64 = 0x5555555555555555
+		if got := byz64l(n); got != n {
+			t.Errorf("%x<<0 == %x, want %x", n, got, n)
+		}
+		if got := byz64r(n); got != n {
+			t.Errorf("%x>>0 == %x, want %x", n, got, n)
+		}
+	}
+	{
+		var n uint64 = 0xaaaaaaaaaaaaaaaa
+		if got := byz64ur(n); got != n {
+			t.Errorf("%x>>>0 == %x, want %x", n, got, n)
+		}
+	}
+
+	{
+		var n int32 = 0x55555555
+		if got := byz32l(n); got != n {
+			t.Errorf("%x<<0 == %x, want %x", n, got, n)
+		}
+		if got := byz32r(n); got != n {
+			t.Errorf("%x>>0 == %x, want %x", n, got, n)
+		}
+	}
+	{
+		var n uint32 = 0xaaaaaaaa
+		if got := byz32ur(n); got != n {
+			t.Errorf("%x>>>0 == %x, want %x", n, got, n)
+		}
+	}
+
+	{
+		var n int16 = 0x5555
+		if got := byz16l(n); got != n {
+			t.Errorf("%x<<0 == %x, want %x", n, got, n)
+		}
+		if got := byz16r(n); got != n {
+			t.Errorf("%x>>0 == %x, want %x", n, got, n)
+		}
+	}
+	{
+		var n uint16 = 0xaaaa
+		if got := byz16ur(n); got != n {
+			t.Errorf("%x>>>0 == %x, want %x", n, got, n)
+		}
+	}
+
+	{
+		var n int8 = 0x55
+		if got := byz8l(n); got != n {
+			t.Errorf("%x<<0 == %x, want %x", n, got, n)
+		}
+		if got := byz8r(n); got != n {
+			t.Errorf("%x>>0 == %x, want %x", n, got, n)
+		}
+	}
+	{
+		var n uint8 = 0x55
+		if got := byz8ur(n); got != n {
+			t.Errorf("%x>>>0 == %x, want %x", n, got, n)
+		}
+	}
+}
+
+//go:noinline
+func two64l(x int64) int64 {
+	return x << 1 << 1
+}
+
+//go:noinline
+func two64r(x int64) int64 {
+	return x >> 1 >> 1
+}
+
+//go:noinline
+func two64ur(x uint64) uint64 {
+	return x >> 1 >> 1
+}
+
+//go:noinline
+func two32l(x int32) int32 {
+	return x << 1 << 1
+}
+
+//go:noinline
+func two32r(x int32) int32 {
+	return x >> 1 >> 1
+}
+
+//go:noinline
+func two32ur(x uint32) uint32 {
+	return x >> 1 >> 1
+}
+
+//go:noinline
+func two16l(x int16) int16 {
+	return x << 1 << 1
+}
+
+//go:noinline
+func two16r(x int16) int16 {
+	return x >> 1 >> 1
+}
+
+//go:noinline
+func two16ur(x uint16) uint16 {
+	return x >> 1 >> 1
+}
+
+//go:noinline
+func two8l(x int8) int8 {
+	return x << 1 << 1
+}
+
+//go:noinline
+func two8r(x int8) int8 {
+	return x >> 1 >> 1
+}
+
+//go:noinline
+func two8ur(x uint8) uint8 {
+	return x >> 1 >> 1
+}
+
+func TestShiftCombine(t *testing.T) {
+	if got, want := two64l(4), int64(16); want != got {
+		t.Errorf("4<<1<<1 == %d, want %d", got, want)
+	}
+	if got, want := two64r(64), int64(16); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := two64ur(64), uint64(16); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := two32l(4), int32(16); want != got {
+		t.Errorf("4<<1<<1 == %d, want %d", got, want)
+	}
+	if got, want := two32r(64), int32(16); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := two32ur(64), uint32(16); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := two16l(4), int16(16); want != got {
+		t.Errorf("4<<1<<1 == %d, want %d", got, want)
+	}
+	if got, want := two16r(64), int16(16); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := two16ur(64), uint16(16); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := two8l(4), int8(16); want != got {
+		t.Errorf("4<<1<<1 == %d, want %d", got, want)
+	}
+	if got, want := two8r(64), int8(16); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := two8ur(64), uint8(16); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+
+}
+
+//go:noinline
+func three64l(x int64) int64 {
+	return x << 3 >> 1 << 2
+}
+
+//go:noinline
+func three64ul(x uint64) uint64 {
+	return x << 3 >> 1 << 2
+}
+
+//go:noinline
+func three64r(x int64) int64 {
+	return x >> 3 << 1 >> 2
+}
+
+//go:noinline
+func three64ur(x uint64) uint64 {
+	return x >> 3 << 1 >> 2
+}
+
+//go:noinline
+func three32l(x int32) int32 {
+	return x << 3 >> 1 << 2
+}
+
+//go:noinline
+func three32ul(x uint32) uint32 {
+	return x << 3 >> 1 << 2
+}
+
+//go:noinline
+func three32r(x int32) int32 {
+	return x >> 3 << 1 >> 2
+}
+
+//go:noinline
+func three32ur(x uint32) uint32 {
+	return x >> 3 << 1 >> 2
+}
+
+//go:noinline
+func three16l(x int16) int16 {
+	return x << 3 >> 1 << 2
+}
+
+//go:noinline
+func three16ul(x uint16) uint16 {
+	return x << 3 >> 1 << 2
+}
+
+//go:noinline
+func three16r(x int16) int16 {
+	return x >> 3 << 1 >> 2
+}
+
+//go:noinline
+func three16ur(x uint16) uint16 {
+	return x >> 3 << 1 >> 2
+}
+
+//go:noinline
+func three8l(x int8) int8 {
+	return x << 3 >> 1 << 2
+}
+
+//go:noinline
+func three8ul(x uint8) uint8 {
+	return x << 3 >> 1 << 2
+}
+
+//go:noinline
+func three8r(x int8) int8 {
+	return x >> 3 << 1 >> 2
+}
+
+//go:noinline
+func three8ur(x uint8) uint8 {
+	return x >> 3 << 1 >> 2
+}
+
+func TestShiftCombine3(t *testing.T) {
+	if got, want := three64l(4), int64(64); want != got {
+		t.Errorf("4<<1<<1 == %d, want %d", got, want)
+	}
+	if got, want := three64ul(4), uint64(64); want != got {
+		t.Errorf("4<<1<<1 == %d, want %d", got, want)
+	}
+	if got, want := three64r(64), int64(4); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := three64ur(64), uint64(4); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := three32l(4), int32(64); want != got {
+		t.Errorf("4<<1<<1 == %d, want %d", got, want)
+	}
+	if got, want := three32ul(4), uint32(64); want != got {
+		t.Errorf("4<<1<<1 == %d, want %d", got, want)
+	}
+	if got, want := three32r(64), int32(4); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := three32ur(64), uint32(4); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := three16l(4), int16(64); want != got {
+		t.Errorf("4<<1<<1 == %d, want %d", got, want)
+	}
+	if got, want := three16ul(4), uint16(64); want != got {
+		t.Errorf("4<<1<<1 == %d, want %d", got, want)
+	}
+	if got, want := three16r(64), int16(4); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := three16ur(64), uint16(4); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := three8l(4), int8(64); want != got {
+		t.Errorf("4<<1<<1 == %d, want %d", got, want)
+	}
+	if got, want := three8ul(4), uint8(64); want != got {
+		t.Errorf("4<<1<<1 == %d, want %d", got, want)
+	}
+	if got, want := three8r(64), int8(4); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+	if got, want := three8ur(64), uint8(4); want != got {
+		t.Errorf("64>>1>>1 == %d, want %d", got, want)
+	}
+}
+
+var (
+	one64  int64  = 1
+	one64u uint64 = 1
+	one32  int32  = 1
+	one32u uint32 = 1
+	one16  int16  = 1
+	one16u uint16 = 1
+	one8   int8   = 1
+	one8u  uint8  = 1
+)
+
+func TestShiftLargeCombine(t *testing.T) {
+	var N uint64 = 0x8000000000000000
+	if one64<<N<<N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one64>>N>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one64u>>N>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one32<<N<<N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one32>>N>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one32u>>N>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one16<<N<<N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one16>>N>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one16u>>N>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one8<<N<<N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one8>>N>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one8u>>N>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+}
+
+func TestShiftLargeCombine3(t *testing.T) {
+	var N uint64 = 0x8000000000000001
+	if one64<<N>>2<<N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one64u<<N>>2<<N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one64>>N<<2>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one64u>>N<<2>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one32<<N>>2<<N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one32u<<N>>2<<N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one32>>N<<2>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one32u>>N<<2>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one16<<N>>2<<N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one16u<<N>>2<<N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one16>>N<<2>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one16u>>N<<2>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one8<<N>>2<<N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one8u<<N>>2<<N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one8>>N<<2>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+	if one8u>>N<<2>>N == 1 {
+		t.Errorf("shift overflow mishandled")
+	}
+}
+
+func TestShiftGeneric(t *testing.T) {
+	for _, test := range [...]struct {
+		valueWidth int
+		signed     bool
+		shiftWidth int
+		left       bool
+		f          interface{}
+	}{
+		{64, true, 64, true, func(n int64, s uint64) int64 { return n << s }},
+		{64, true, 64, false, func(n int64, s uint64) int64 { return n >> s }},
+		{64, false, 64, false, func(n uint64, s uint64) uint64 { return n >> s }},
+		{64, true, 32, true, func(n int64, s uint32) int64 { return n << s }},
+		{64, true, 32, false, func(n int64, s uint32) int64 { return n >> s }},
+		{64, false, 32, false, func(n uint64, s uint32) uint64 { return n >> s }},
+		{64, true, 16, true, func(n int64, s uint16) int64 { return n << s }},
+		{64, true, 16, false, func(n int64, s uint16) int64 { return n >> s }},
+		{64, false, 16, false, func(n uint64, s uint16) uint64 { return n >> s }},
+		{64, true, 8, true, func(n int64, s uint8) int64 { return n << s }},
+		{64, true, 8, false, func(n int64, s uint8) int64 { return n >> s }},
+		{64, false, 8, false, func(n uint64, s uint8) uint64 { return n >> s }},
+
+		{32, true, 64, true, func(n int32, s uint64) int32 { return n << s }},
+		{32, true, 64, false, func(n int32, s uint64) int32 { return n >> s }},
+		{32, false, 64, false, func(n uint32, s uint64) uint32 { return n >> s }},
+		{32, true, 32, true, func(n int32, s uint32) int32 { return n << s }},
+		{32, true, 32, false, func(n int32, s uint32) int32 { return n >> s }},
+		{32, false, 32, false, func(n uint32, s uint32) uint32 { return n >> s }},
+		{32, true, 16, true, func(n int32, s uint16) int32 { return n << s }},
+		{32, true, 16, false, func(n int32, s uint16) int32 { return n >> s }},
+		{32, false, 16, false, func(n uint32, s uint16) uint32 { return n >> s }},
+		{32, true, 8, true, func(n int32, s uint8) int32 { return n << s }},
+		{32, true, 8, false, func(n int32, s uint8) int32 { return n >> s }},
+		{32, false, 8, false, func(n uint32, s uint8) uint32 { return n >> s }},
+
+		{16, true, 64, true, func(n int16, s uint64) int16 { return n << s }},
+		{16, true, 64, false, func(n int16, s uint64) int16 { return n >> s }},
+		{16, false, 64, false, func(n uint16, s uint64) uint16 { return n >> s }},
+		{16, true, 32, true, func(n int16, s uint32) int16 { return n << s }},
+		{16, true, 32, false, func(n int16, s uint32) int16 { return n >> s }},
+		{16, false, 32, false, func(n uint16, s uint32) uint16 { return n >> s }},
+		{16, true, 16, true, func(n int16, s uint16) int16 { return n << s }},
+		{16, true, 16, false, func(n int16, s uint16) int16 { return n >> s }},
+		{16, false, 16, false, func(n uint16, s uint16) uint16 { return n >> s }},
+		{16, true, 8, true, func(n int16, s uint8) int16 { return n << s }},
+		{16, true, 8, false, func(n int16, s uint8) int16 { return n >> s }},
+		{16, false, 8, false, func(n uint16, s uint8) uint16 { return n >> s }},
+
+		{8, true, 64, true, func(n int8, s uint64) int8 { return n << s }},
+		{8, true, 64, false, func(n int8, s uint64) int8 { return n >> s }},
+		{8, false, 64, false, func(n uint8, s uint64) uint8 { return n >> s }},
+		{8, true, 32, true, func(n int8, s uint32) int8 { return n << s }},
+		{8, true, 32, false, func(n int8, s uint32) int8 { return n >> s }},
+		{8, false, 32, false, func(n uint8, s uint32) uint8 { return n >> s }},
+		{8, true, 16, true, func(n int8, s uint16) int8 { return n << s }},
+		{8, true, 16, false, func(n int8, s uint16) int8 { return n >> s }},
+		{8, false, 16, false, func(n uint8, s uint16) uint8 { return n >> s }},
+		{8, true, 8, true, func(n int8, s uint8) int8 { return n << s }},
+		{8, true, 8, false, func(n int8, s uint8) int8 { return n >> s }},
+		{8, false, 8, false, func(n uint8, s uint8) uint8 { return n >> s }},
+	} {
+		fv := reflect.ValueOf(test.f)
+		var args [2]reflect.Value
+		for i := 0; i < test.valueWidth; i++ {
+			// Build value to be shifted.
+			var n int64 = 1
+			for j := 0; j < i; j++ {
+				n <<= 1
+			}
+			args[0] = reflect.ValueOf(n).Convert(fv.Type().In(0))
+			for s := 0; s <= test.shiftWidth; s++ {
+				args[1] = reflect.ValueOf(s).Convert(fv.Type().In(1))
+
+				// Compute desired result. We're testing variable shifts
+				// assuming constant shifts are correct.
+				r := n
+				var op string
+				switch {
+				case test.left:
+					op = "<<"
+					for j := 0; j < s; j++ {
+						r <<= 1
+					}
+					switch test.valueWidth {
+					case 32:
+						r = int64(int32(r))
+					case 16:
+						r = int64(int16(r))
+					case 8:
+						r = int64(int8(r))
+					}
+				case test.signed:
+					op = ">>"
+					switch test.valueWidth {
+					case 32:
+						r = int64(int32(r))
+					case 16:
+						r = int64(int16(r))
+					case 8:
+						r = int64(int8(r))
+					}
+					for j := 0; j < s; j++ {
+						r >>= 1
+					}
+				default:
+					op = ">>>"
+					for j := 0; j < s; j++ {
+						r = int64(uint64(r) >> 1)
+					}
+				}
+
+				// Call function.
+				res := fv.Call(args[:])[0].Convert(reflect.ValueOf(r).Type())
+
+				if res.Int() != r {
+					t.Errorf("%s%dx%d(%x,%x)=%x, want %x", op, test.valueWidth, test.shiftWidth, n, s, res.Int(), r)
+				}
+			}
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/test/ssa_test.go b/src/cmd/compile/internal/test/ssa_test.go
new file mode 100644
index 0000000..2f3e24c
--- /dev/null
+++ b/src/cmd/compile/internal/test/ssa_test.go
@@ -0,0 +1,191 @@
+// 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 test
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/token"
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+// 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) {
+	if testing.Short() {
+		t.Skip("not run in short mode.")
+	}
+	runGenTest(t, "flowgraph_generator1.go", "ssa_fg_tmp1")
+}
+
+// TestCode runs all the tests in the testdata directory as subtests.
+// These tests are special because we want to run them with different
+// compiler flags set (and thus they can't just be _test.go files in
+// this directory).
+func TestCode(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+	gotool := testenv.GoToolPath(t)
+
+	// Make a temporary directory to work in.
+	tmpdir, err := ioutil.TempDir("", "TestCode")
+	if err != nil {
+		t.Fatalf("Failed to create temporary directory: %v", err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	// Find all the test functions (and the files containing them).
+	var srcs []string // files containing Test functions
+	type test struct {
+		name      string // TestFoo
+		usesFloat bool   // might use float operations
+	}
+	var tests []test
+	files, err := ioutil.ReadDir("testdata")
+	if err != nil {
+		t.Fatalf("can't read testdata directory: %v", err)
+	}
+	for _, f := range files {
+		if !strings.HasSuffix(f.Name(), "_test.go") {
+			continue
+		}
+		text, err := ioutil.ReadFile(filepath.Join("testdata", f.Name()))
+		if err != nil {
+			t.Fatalf("can't read testdata/%s: %v", f.Name(), err)
+		}
+		fset := token.NewFileSet()
+		code, err := parser.ParseFile(fset, f.Name(), text, 0)
+		if err != nil {
+			t.Fatalf("can't parse testdata/%s: %v", f.Name(), err)
+		}
+		srcs = append(srcs, filepath.Join("testdata", f.Name()))
+		foundTest := false
+		for _, d := range code.Decls {
+			fd, ok := d.(*ast.FuncDecl)
+			if !ok {
+				continue
+			}
+			if !strings.HasPrefix(fd.Name.Name, "Test") {
+				continue
+			}
+			if fd.Recv != nil {
+				continue
+			}
+			if fd.Type.Results != nil {
+				continue
+			}
+			if len(fd.Type.Params.List) != 1 {
+				continue
+			}
+			p := fd.Type.Params.List[0]
+			if len(p.Names) != 1 {
+				continue
+			}
+			s, ok := p.Type.(*ast.StarExpr)
+			if !ok {
+				continue
+			}
+			sel, ok := s.X.(*ast.SelectorExpr)
+			if !ok {
+				continue
+			}
+			base, ok := sel.X.(*ast.Ident)
+			if !ok {
+				continue
+			}
+			if base.Name != "testing" {
+				continue
+			}
+			if sel.Sel.Name != "T" {
+				continue
+			}
+			// Found a testing function.
+			tests = append(tests, test{name: fd.Name.Name, usesFloat: bytes.Contains(text, []byte("float"))})
+			foundTest = true
+		}
+		if !foundTest {
+			t.Fatalf("test file testdata/%s has no tests in it", f.Name())
+		}
+	}
+
+	flags := []string{""}
+	if runtime.GOARCH == "arm" || runtime.GOARCH == "mips" || runtime.GOARCH == "mips64" {
+		flags = append(flags, ",softfloat")
+	}
+	for _, flag := range flags {
+		args := []string{"test", "-c", "-gcflags=-d=ssa/check/on" + flag, "-o", filepath.Join(tmpdir, "code.test")}
+		args = append(args, srcs...)
+		out, err := exec.Command(gotool, args...).CombinedOutput()
+		if err != nil || len(out) != 0 {
+			t.Fatalf("Build failed: %v\n%s\n", err, out)
+		}
+
+		// Now we have a test binary. Run it with all the tests as subtests of this one.
+		for _, test := range tests {
+			test := test
+			if flag == ",softfloat" && !test.usesFloat {
+				// No point in running the soft float version if the test doesn't use floats.
+				continue
+			}
+			t.Run(fmt.Sprintf("%s%s", test.name[4:], flag), func(t *testing.T) {
+				out, err := exec.Command(filepath.Join(tmpdir, "code.test"), "-test.run="+test.name).CombinedOutput()
+				if err != nil || string(out) != "PASS\n" {
+					t.Errorf("Failed:\n%s\n", out)
+				}
+			})
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/gc/testdata/addressed_test.go b/src/cmd/compile/internal/test/testdata/addressed_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/addressed_test.go
rename to src/cmd/compile/internal/test/testdata/addressed_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/append_test.go b/src/cmd/compile/internal/test/testdata/append_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/append_test.go
rename to src/cmd/compile/internal/test/testdata/append_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/arithBoundary_test.go b/src/cmd/compile/internal/test/testdata/arithBoundary_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/arithBoundary_test.go
rename to src/cmd/compile/internal/test/testdata/arithBoundary_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/arithConst_test.go b/src/cmd/compile/internal/test/testdata/arithConst_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/arithConst_test.go
rename to src/cmd/compile/internal/test/testdata/arithConst_test.go
diff --git a/src/cmd/compile/internal/test/testdata/arith_test.go b/src/cmd/compile/internal/test/testdata/arith_test.go
new file mode 100644
index 0000000..7d54a91
--- /dev/null
+++ b/src/cmd/compile/internal/test/testdata/arith_test.go
@@ -0,0 +1,1497 @@
+// 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 arithmetic expressions
+
+package main
+
+import (
+	"math"
+	"runtime"
+	"testing"
+)
+
+const (
+	y = 0x0fffFFFF
+)
+
+var (
+	g8  int8
+	g16 int16
+	g32 int32
+	g64 int64
+)
+
+//go:noinline
+func lshNop1(x uint64) uint64 {
+	// two outer shifts should be removed
+	return (((x << 5) >> 2) << 2)
+}
+
+//go:noinline
+func lshNop2(x uint64) uint64 {
+	return (((x << 5) >> 2) << 3)
+}
+
+//go:noinline
+func lshNop3(x uint64) uint64 {
+	return (((x << 5) >> 2) << 6)
+}
+
+//go:noinline
+func lshNotNop(x uint64) uint64 {
+	// outer shift can't be removed
+	return (((x << 5) >> 2) << 1)
+}
+
+//go:noinline
+func rshNop1(x uint64) uint64 {
+	return (((x >> 5) << 2) >> 2)
+}
+
+//go:noinline
+func rshNop2(x uint64) uint64 {
+	return (((x >> 5) << 2) >> 3)
+}
+
+//go:noinline
+func rshNop3(x uint64) uint64 {
+	return (((x >> 5) << 2) >> 6)
+}
+
+//go:noinline
+func rshNotNop(x uint64) uint64 {
+	return (((x >> 5) << 2) >> 1)
+}
+
+func testShiftRemoval(t *testing.T) {
+	allSet := ^uint64(0)
+	if want, got := uint64(0x7ffffffffffffff), rshNop1(allSet); want != got {
+		t.Errorf("testShiftRemoval rshNop1 failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint64(0x3ffffffffffffff), rshNop2(allSet); want != got {
+		t.Errorf("testShiftRemoval rshNop2 failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint64(0x7fffffffffffff), rshNop3(allSet); want != got {
+		t.Errorf("testShiftRemoval rshNop3 failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint64(0xffffffffffffffe), rshNotNop(allSet); want != got {
+		t.Errorf("testShiftRemoval rshNotNop failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint64(0xffffffffffffffe0), lshNop1(allSet); want != got {
+		t.Errorf("testShiftRemoval lshNop1 failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint64(0xffffffffffffffc0), lshNop2(allSet); want != got {
+		t.Errorf("testShiftRemoval lshNop2 failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint64(0xfffffffffffffe00), lshNop3(allSet); want != got {
+		t.Errorf("testShiftRemoval lshNop3 failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint64(0x7ffffffffffffff0), lshNotNop(allSet); want != got {
+		t.Errorf("testShiftRemoval lshNotNop failed, wanted %d got %d", want, got)
+	}
+}
+
+//go:noinline
+func parseLE64(b []byte) uint64 {
+	// skip the first two bytes, and parse the remaining 8 as a uint64
+	return uint64(b[2]) | uint64(b[3])<<8 | uint64(b[4])<<16 | uint64(b[5])<<24 |
+		uint64(b[6])<<32 | uint64(b[7])<<40 | uint64(b[8])<<48 | uint64(b[9])<<56
+}
+
+//go:noinline
+func parseLE32(b []byte) uint32 {
+	return uint32(b[2]) | uint32(b[3])<<8 | uint32(b[4])<<16 | uint32(b[5])<<24
+}
+
+//go:noinline
+func parseLE16(b []byte) uint16 {
+	return uint16(b[2]) | uint16(b[3])<<8
+}
+
+// testLoadCombine tests for issue #14694 where load combining didn't respect the pointer offset.
+func testLoadCombine(t *testing.T) {
+	testData := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}
+	if want, got := uint64(0x0908070605040302), parseLE64(testData); want != got {
+		t.Errorf("testLoadCombine failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint32(0x05040302), parseLE32(testData); want != got {
+		t.Errorf("testLoadCombine failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint16(0x0302), parseLE16(testData); want != got {
+		t.Errorf("testLoadCombine failed, wanted %d got %d", want, got)
+	}
+}
+
+var loadSymData = [...]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
+
+func testLoadSymCombine(t *testing.T) {
+	w2 := uint16(0x0201)
+	g2 := uint16(loadSymData[0]) | uint16(loadSymData[1])<<8
+	if g2 != w2 {
+		t.Errorf("testLoadSymCombine failed, wanted %d got %d", w2, g2)
+	}
+	w4 := uint32(0x04030201)
+	g4 := uint32(loadSymData[0]) | uint32(loadSymData[1])<<8 |
+		uint32(loadSymData[2])<<16 | uint32(loadSymData[3])<<24
+	if g4 != w4 {
+		t.Errorf("testLoadSymCombine failed, wanted %d got %d", w4, g4)
+	}
+	w8 := uint64(0x0807060504030201)
+	g8 := uint64(loadSymData[0]) | uint64(loadSymData[1])<<8 |
+		uint64(loadSymData[2])<<16 | uint64(loadSymData[3])<<24 |
+		uint64(loadSymData[4])<<32 | uint64(loadSymData[5])<<40 |
+		uint64(loadSymData[6])<<48 | uint64(loadSymData[7])<<56
+	if g8 != w8 {
+		t.Errorf("testLoadSymCombine failed, wanted %d got %d", w8, g8)
+	}
+}
+
+//go:noinline
+func invalidAdd_ssa(x uint32) uint32 {
+	return x + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y
+}
+
+//go:noinline
+func invalidSub_ssa(x uint32) uint32 {
+	return x - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y
+}
+
+//go:noinline
+func invalidMul_ssa(x uint32) uint32 {
+	return x * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y
+}
+
+// testLargeConst tests a situation where larger than 32 bit consts were passed to ADDL
+// causing an invalid instruction error.
+func testLargeConst(t *testing.T) {
+	if want, got := uint32(268435440), invalidAdd_ssa(1); want != got {
+		t.Errorf("testLargeConst add failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint32(4026531858), invalidSub_ssa(1); want != got {
+		t.Errorf("testLargeConst sub failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint32(268435455), invalidMul_ssa(1); want != got {
+		t.Errorf("testLargeConst mul failed, wanted %d got %d", want, got)
+	}
+}
+
+// testArithRshConst ensures that "const >> const" right shifts correctly perform
+// sign extension on the lhs constant
+func testArithRshConst(t *testing.T) {
+	wantu := uint64(0x4000000000000000)
+	if got := arithRshuConst_ssa(); got != wantu {
+		t.Errorf("arithRshuConst failed, wanted %d got %d", wantu, got)
+	}
+
+	wants := int64(-0x4000000000000000)
+	if got := arithRshConst_ssa(); got != wants {
+		t.Errorf("arithRshConst failed, wanted %d got %d", wants, got)
+	}
+}
+
+//go:noinline
+func arithRshuConst_ssa() uint64 {
+	y := uint64(0x8000000000000001)
+	z := uint64(1)
+	return uint64(y >> z)
+}
+
+//go:noinline
+func arithRshConst_ssa() int64 {
+	y := int64(-0x8000000000000000)
+	z := uint64(1)
+	return int64(y >> z)
+}
+
+//go:noinline
+func arithConstShift_ssa(x int64) int64 {
+	return x >> 100
+}
+
+// testArithConstShift tests that right shift by large constants preserve
+// the sign of the input.
+func testArithConstShift(t *testing.T) {
+	want := int64(-1)
+	if got := arithConstShift_ssa(-1); want != got {
+		t.Errorf("arithConstShift_ssa(-1) failed, wanted %d got %d", want, got)
+	}
+	want = 0
+	if got := arithConstShift_ssa(1); want != got {
+		t.Errorf("arithConstShift_ssa(1) failed, wanted %d got %d", want, got)
+	}
+}
+
+// overflowConstShift_ssa verifes that constant folding for shift
+// doesn't wrap (i.e. x << MAX_INT << 1 doesn't get folded to x << 0).
+//go:noinline
+func overflowConstShift64_ssa(x int64) int64 {
+	return x << uint64(0xffffffffffffffff) << uint64(1)
+}
+
+//go:noinline
+func overflowConstShift32_ssa(x int64) int32 {
+	return int32(x) << uint32(0xffffffff) << uint32(1)
+}
+
+//go:noinline
+func overflowConstShift16_ssa(x int64) int16 {
+	return int16(x) << uint16(0xffff) << uint16(1)
+}
+
+//go:noinline
+func overflowConstShift8_ssa(x int64) int8 {
+	return int8(x) << uint8(0xff) << uint8(1)
+}
+
+func testOverflowConstShift(t *testing.T) {
+	want := int64(0)
+	for x := int64(-127); x < int64(127); x++ {
+		got := overflowConstShift64_ssa(x)
+		if want != got {
+			t.Errorf("overflowShift64 failed, wanted %d got %d", want, got)
+		}
+		got = int64(overflowConstShift32_ssa(x))
+		if want != got {
+			t.Errorf("overflowShift32 failed, wanted %d got %d", want, got)
+		}
+		got = int64(overflowConstShift16_ssa(x))
+		if want != got {
+			t.Errorf("overflowShift16 failed, wanted %d got %d", want, got)
+		}
+		got = int64(overflowConstShift8_ssa(x))
+		if want != got {
+			t.Errorf("overflowShift8 failed, wanted %d got %d", want, got)
+		}
+	}
+}
+
+// test64BitConstMult tests that rewrite rules don't fold 64 bit constants
+// into multiply instructions.
+func test64BitConstMult(t *testing.T) {
+	want := int64(103079215109)
+	if got := test64BitConstMult_ssa(1, 2); want != got {
+		t.Errorf("test64BitConstMult failed, wanted %d got %d", want, got)
+	}
+}
+
+//go:noinline
+func test64BitConstMult_ssa(a, b int64) int64 {
+	return 34359738369*a + b*34359738370
+}
+
+// test64BitConstAdd tests that rewrite rules don't fold 64 bit constants
+// into add instructions.
+func test64BitConstAdd(t *testing.T) {
+	want := int64(3567671782835376650)
+	if got := test64BitConstAdd_ssa(1, 2); want != got {
+		t.Errorf("test64BitConstAdd failed, wanted %d got %d", want, got)
+	}
+}
+
+//go:noinline
+func test64BitConstAdd_ssa(a, b int64) int64 {
+	return a + 575815584948629622 + b + 2991856197886747025
+}
+
+// testRegallocCVSpill tests that regalloc spills a value whose last use is the
+// current value.
+func testRegallocCVSpill(t *testing.T) {
+	want := int8(-9)
+	if got := testRegallocCVSpill_ssa(1, 2, 3, 4); want != got {
+		t.Errorf("testRegallocCVSpill failed, wanted %d got %d", want, got)
+	}
+}
+
+//go:noinline
+func testRegallocCVSpill_ssa(a, b, c, d int8) int8 {
+	return a + -32 + b + 63*c*-87*d
+}
+
+func testBitwiseLogic(t *testing.T) {
+	a, b := uint32(57623283), uint32(1314713839)
+	if want, got := uint32(38551779), testBitwiseAnd_ssa(a, b); want != got {
+		t.Errorf("testBitwiseAnd failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint32(1333785343), testBitwiseOr_ssa(a, b); want != got {
+		t.Errorf("testBitwiseOr failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint32(1295233564), testBitwiseXor_ssa(a, b); want != got {
+		t.Errorf("testBitwiseXor failed, wanted %d got %d", want, got)
+	}
+	if want, got := int32(832), testBitwiseLsh_ssa(13, 4, 2); want != got {
+		t.Errorf("testBitwiseLsh failed, wanted %d got %d", want, got)
+	}
+	if want, got := int32(0), testBitwiseLsh_ssa(13, 25, 15); want != got {
+		t.Errorf("testBitwiseLsh failed, wanted %d got %d", want, got)
+	}
+	if want, got := int32(0), testBitwiseLsh_ssa(-13, 25, 15); want != got {
+		t.Errorf("testBitwiseLsh failed, wanted %d got %d", want, got)
+	}
+	if want, got := int32(-13), testBitwiseRsh_ssa(-832, 4, 2); want != got {
+		t.Errorf("testBitwiseRsh failed, wanted %d got %d", want, got)
+	}
+	if want, got := int32(0), testBitwiseRsh_ssa(13, 25, 15); want != got {
+		t.Errorf("testBitwiseRsh failed, wanted %d got %d", want, got)
+	}
+	if want, got := int32(-1), testBitwiseRsh_ssa(-13, 25, 15); want != got {
+		t.Errorf("testBitwiseRsh failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint32(0x3ffffff), testBitwiseRshU_ssa(0xffffffff, 4, 2); want != got {
+		t.Errorf("testBitwiseRshU failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint32(0), testBitwiseRshU_ssa(13, 25, 15); want != got {
+		t.Errorf("testBitwiseRshU failed, wanted %d got %d", want, got)
+	}
+	if want, got := uint32(0), testBitwiseRshU_ssa(0x8aaaaaaa, 25, 15); want != got {
+		t.Errorf("testBitwiseRshU failed, wanted %d got %d", want, got)
+	}
+}
+
+//go:noinline
+func testBitwiseAnd_ssa(a, b uint32) uint32 {
+	return a & b
+}
+
+//go:noinline
+func testBitwiseOr_ssa(a, b uint32) uint32 {
+	return a | b
+}
+
+//go:noinline
+func testBitwiseXor_ssa(a, b uint32) uint32 {
+	return a ^ b
+}
+
+//go:noinline
+func testBitwiseLsh_ssa(a int32, b, c uint32) int32 {
+	return a << b << c
+}
+
+//go:noinline
+func testBitwiseRsh_ssa(a int32, b, c uint32) int32 {
+	return a >> b >> c
+}
+
+//go:noinline
+func testBitwiseRshU_ssa(a uint32, b, c uint32) uint32 {
+	return a >> b >> c
+}
+
+//go:noinline
+func testShiftCX_ssa() int {
+	v1 := uint8(3)
+	v4 := (v1 * v1) ^ v1 | v1 - v1 - v1&v1 ^ uint8(3+2) + v1*1>>0 - v1 | 1 | v1<<(2*3|0-0*0^1)
+	v5 := v4>>(3-0-uint(3)) | v1 | v1 + v1 ^ v4<<(0+1|3&1)<<(uint64(1)<<0*2*0<<0) ^ v1
+	v6 := v5 ^ (v1+v1)*v1 | v1 | v1*v1>>(v1&v1)>>(uint(1)<<0*uint(3)>>1)*v1<<2*v1<<v1 - v1>>2 | (v4 - v1) ^ v1 + v1 ^ v1>>1 | v1 + v1 - v1 ^ v1
+	v7 := v6 & v5 << 0
+	v1++
+	v11 := 2&1 ^ 0 + 3 | int(0^0)<<1>>(1*0*3) ^ 0*0 ^ 3&0*3&3 ^ 3*3 ^ 1 ^ int(2)<<(2*3) + 2 | 2 | 2 ^ 2 + 1 | 3 | 0 ^ int(1)>>1 ^ 2 // int
+	v7--
+	return int(uint64(2*1)<<(3-2)<<uint(3>>v7)-2)&v11 | v11 - int(2)<<0>>(2-1)*(v11*0&v11<<1<<(uint8(2)+v4))
+}
+
+func testShiftCX(t *testing.T) {
+	want := 141
+	if got := testShiftCX_ssa(); want != got {
+		t.Errorf("testShiftCX failed, wanted %d got %d", want, got)
+	}
+}
+
+// testSubqToNegq ensures that the SUBQ -> NEGQ translation works correctly.
+func testSubqToNegq(t *testing.T) {
+	want := int64(-318294940372190156)
+	if got := testSubqToNegq_ssa(1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2); want != got {
+		t.Errorf("testSubqToNegq failed, wanted %d got %d", want, got)
+	}
+}
+
+//go:noinline
+func testSubqToNegq_ssa(a, b, c, d, e, f, g, h, i, j, k int64) int64 {
+	return a + 8207351403619448057 - b - 1779494519303207690 + c*8810076340510052032*d - 4465874067674546219 - e*4361839741470334295 - f + 8688847565426072650*g*8065564729145417479
+}
+
+func testOcom(t *testing.T) {
+	want1, want2 := int32(0x55555555), int32(-0x55555556)
+	if got1, got2 := testOcom_ssa(0x55555555, 0x55555555); want1 != got1 || want2 != got2 {
+		t.Errorf("testOcom failed, wanted %d and %d got %d and %d", want1, want2, got1, got2)
+	}
+}
+
+//go:noinline
+func testOcom_ssa(a, b int32) (int32, int32) {
+	return ^^^^a, ^^^^^b
+}
+
+func lrot1_ssa(w uint8, x uint16, y uint32, z uint64) (a uint8, b uint16, c uint32, d uint64) {
+	a = (w << 5) | (w >> 3)
+	b = (x << 13) | (x >> 3)
+	c = (y << 29) | (y >> 3)
+	d = (z << 61) | (z >> 3)
+	return
+}
+
+//go:noinline
+func lrot2_ssa(w, n uint32) uint32 {
+	// Want to be sure that a "rotate by 32" which
+	// is really 0 | (w >> 0) == w
+	// is correctly compiled.
+	return (w << n) | (w >> (32 - n))
+}
+
+//go:noinline
+func lrot3_ssa(w uint32) uint32 {
+	// Want to be sure that a "rotate by 32" which
+	// is really 0 | (w >> 0) == w
+	// is correctly compiled.
+	return (w << 32) | (w >> (32 - 32))
+}
+
+func testLrot(t *testing.T) {
+	wantA, wantB, wantC, wantD := uint8(0xe1), uint16(0xe001),
+		uint32(0xe0000001), uint64(0xe000000000000001)
+	a, b, c, d := lrot1_ssa(0xf, 0xf, 0xf, 0xf)
+	if a != wantA || b != wantB || c != wantC || d != wantD {
+		t.Errorf("lrot1_ssa(0xf, 0xf, 0xf, 0xf)=%d %d %d %d, got %d %d %d %d", wantA, wantB, wantC, wantD, a, b, c, d)
+	}
+	x := lrot2_ssa(0xb0000001, 32)
+	wantX := uint32(0xb0000001)
+	if x != wantX {
+		t.Errorf("lrot2_ssa(0xb0000001, 32)=%d, got %d", wantX, x)
+	}
+	x = lrot3_ssa(0xb0000001)
+	if x != wantX {
+		t.Errorf("lrot3_ssa(0xb0000001)=%d, got %d", wantX, x)
+	}
+
+}
+
+//go:noinline
+func sub1_ssa() uint64 {
+	v1 := uint64(3) // uint64
+	return v1*v1 - (v1&v1)&v1
+}
+
+//go:noinline
+func sub2_ssa() uint8 {
+	v1 := uint8(0)
+	v3 := v1 + v1 + v1 ^ v1 | 3 + v1 ^ v1 | v1 ^ v1
+	v1-- // dev.ssa doesn't see this one
+	return v1 ^ v1*v1 - v3
+}
+
+func testSubConst(t *testing.T) {
+	x1 := sub1_ssa()
+	want1 := uint64(6)
+	if x1 != want1 {
+		t.Errorf("sub1_ssa()=%d, got %d", want1, x1)
+	}
+	x2 := sub2_ssa()
+	want2 := uint8(251)
+	if x2 != want2 {
+		t.Errorf("sub2_ssa()=%d, got %d", want2, x2)
+	}
+}
+
+//go:noinline
+func orPhi_ssa(a bool, x int) int {
+	v := 0
+	if a {
+		v = -1
+	} else {
+		v = -1
+	}
+	return x | v
+}
+
+func testOrPhi(t *testing.T) {
+	if want, got := -1, orPhi_ssa(true, 4); got != want {
+		t.Errorf("orPhi_ssa(true, 4)=%d, want %d", got, want)
+	}
+	if want, got := -1, orPhi_ssa(false, 0); got != want {
+		t.Errorf("orPhi_ssa(false, 0)=%d, want %d", got, want)
+	}
+}
+
+//go:noinline
+func addshiftLL_ssa(a, b uint32) uint32 {
+	return a + b<<3
+}
+
+//go:noinline
+func subshiftLL_ssa(a, b uint32) uint32 {
+	return a - b<<3
+}
+
+//go:noinline
+func rsbshiftLL_ssa(a, b uint32) uint32 {
+	return a<<3 - b
+}
+
+//go:noinline
+func andshiftLL_ssa(a, b uint32) uint32 {
+	return a & (b << 3)
+}
+
+//go:noinline
+func orshiftLL_ssa(a, b uint32) uint32 {
+	return a | b<<3
+}
+
+//go:noinline
+func xorshiftLL_ssa(a, b uint32) uint32 {
+	return a ^ b<<3
+}
+
+//go:noinline
+func bicshiftLL_ssa(a, b uint32) uint32 {
+	return a &^ (b << 3)
+}
+
+//go:noinline
+func notshiftLL_ssa(a uint32) uint32 {
+	return ^(a << 3)
+}
+
+//go:noinline
+func addshiftRL_ssa(a, b uint32) uint32 {
+	return a + b>>3
+}
+
+//go:noinline
+func subshiftRL_ssa(a, b uint32) uint32 {
+	return a - b>>3
+}
+
+//go:noinline
+func rsbshiftRL_ssa(a, b uint32) uint32 {
+	return a>>3 - b
+}
+
+//go:noinline
+func andshiftRL_ssa(a, b uint32) uint32 {
+	return a & (b >> 3)
+}
+
+//go:noinline
+func orshiftRL_ssa(a, b uint32) uint32 {
+	return a | b>>3
+}
+
+//go:noinline
+func xorshiftRL_ssa(a, b uint32) uint32 {
+	return a ^ b>>3
+}
+
+//go:noinline
+func bicshiftRL_ssa(a, b uint32) uint32 {
+	return a &^ (b >> 3)
+}
+
+//go:noinline
+func notshiftRL_ssa(a uint32) uint32 {
+	return ^(a >> 3)
+}
+
+//go:noinline
+func addshiftRA_ssa(a, b int32) int32 {
+	return a + b>>3
+}
+
+//go:noinline
+func subshiftRA_ssa(a, b int32) int32 {
+	return a - b>>3
+}
+
+//go:noinline
+func rsbshiftRA_ssa(a, b int32) int32 {
+	return a>>3 - b
+}
+
+//go:noinline
+func andshiftRA_ssa(a, b int32) int32 {
+	return a & (b >> 3)
+}
+
+//go:noinline
+func orshiftRA_ssa(a, b int32) int32 {
+	return a | b>>3
+}
+
+//go:noinline
+func xorshiftRA_ssa(a, b int32) int32 {
+	return a ^ b>>3
+}
+
+//go:noinline
+func bicshiftRA_ssa(a, b int32) int32 {
+	return a &^ (b >> 3)
+}
+
+//go:noinline
+func notshiftRA_ssa(a int32) int32 {
+	return ^(a >> 3)
+}
+
+//go:noinline
+func addshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a + b<<s
+}
+
+//go:noinline
+func subshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a - b<<s
+}
+
+//go:noinline
+func rsbshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a<<s - b
+}
+
+//go:noinline
+func andshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a & (b << s)
+}
+
+//go:noinline
+func orshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a | b<<s
+}
+
+//go:noinline
+func xorshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a ^ b<<s
+}
+
+//go:noinline
+func bicshiftLLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a &^ (b << s)
+}
+
+//go:noinline
+func notshiftLLreg_ssa(a uint32, s uint8) uint32 {
+	return ^(a << s)
+}
+
+//go:noinline
+func addshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a + b>>s
+}
+
+//go:noinline
+func subshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a - b>>s
+}
+
+//go:noinline
+func rsbshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a>>s - b
+}
+
+//go:noinline
+func andshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a & (b >> s)
+}
+
+//go:noinline
+func orshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a | b>>s
+}
+
+//go:noinline
+func xorshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a ^ b>>s
+}
+
+//go:noinline
+func bicshiftRLreg_ssa(a, b uint32, s uint8) uint32 {
+	return a &^ (b >> s)
+}
+
+//go:noinline
+func notshiftRLreg_ssa(a uint32, s uint8) uint32 {
+	return ^(a >> s)
+}
+
+//go:noinline
+func addshiftRAreg_ssa(a, b int32, s uint8) int32 {
+	return a + b>>s
+}
+
+//go:noinline
+func subshiftRAreg_ssa(a, b int32, s uint8) int32 {
+	return a - b>>s
+}
+
+//go:noinline
+func rsbshiftRAreg_ssa(a, b int32, s uint8) int32 {
+	return a>>s - b
+}
+
+//go:noinline
+func andshiftRAreg_ssa(a, b int32, s uint8) int32 {
+	return a & (b >> s)
+}
+
+//go:noinline
+func orshiftRAreg_ssa(a, b int32, s uint8) int32 {
+	return a | b>>s
+}
+
+//go:noinline
+func xorshiftRAreg_ssa(a, b int32, s uint8) int32 {
+	return a ^ b>>s
+}
+
+//go:noinline
+func bicshiftRAreg_ssa(a, b int32, s uint8) int32 {
+	return a &^ (b >> s)
+}
+
+//go:noinline
+func notshiftRAreg_ssa(a int32, s uint8) int32 {
+	return ^(a >> s)
+}
+
+// test ARM shifted ops
+func testShiftedOps(t *testing.T) {
+	a, b := uint32(10), uint32(42)
+	if want, got := a+b<<3, addshiftLL_ssa(a, b); got != want {
+		t.Errorf("addshiftLL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := a-b<<3, subshiftLL_ssa(a, b); got != want {
+		t.Errorf("subshiftLL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := a<<3-b, rsbshiftLL_ssa(a, b); got != want {
+		t.Errorf("rsbshiftLL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := a&(b<<3), andshiftLL_ssa(a, b); got != want {
+		t.Errorf("andshiftLL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := a|b<<3, orshiftLL_ssa(a, b); got != want {
+		t.Errorf("orshiftLL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := a^b<<3, xorshiftLL_ssa(a, b); got != want {
+		t.Errorf("xorshiftLL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := a&^(b<<3), bicshiftLL_ssa(a, b); got != want {
+		t.Errorf("bicshiftLL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := ^(a << 3), notshiftLL_ssa(a); got != want {
+		t.Errorf("notshiftLL_ssa(10) = %d want %d", got, want)
+	}
+	if want, got := a+b>>3, addshiftRL_ssa(a, b); got != want {
+		t.Errorf("addshiftRL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := a-b>>3, subshiftRL_ssa(a, b); got != want {
+		t.Errorf("subshiftRL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := a>>3-b, rsbshiftRL_ssa(a, b); got != want {
+		t.Errorf("rsbshiftRL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := a&(b>>3), andshiftRL_ssa(a, b); got != want {
+		t.Errorf("andshiftRL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := a|b>>3, orshiftRL_ssa(a, b); got != want {
+		t.Errorf("orshiftRL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := a^b>>3, xorshiftRL_ssa(a, b); got != want {
+		t.Errorf("xorshiftRL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := a&^(b>>3), bicshiftRL_ssa(a, b); got != want {
+		t.Errorf("bicshiftRL_ssa(10, 42) = %d want %d", got, want)
+	}
+	if want, got := ^(a >> 3), notshiftRL_ssa(a); got != want {
+		t.Errorf("notshiftRL_ssa(10) = %d want %d", got, want)
+	}
+	c, d := int32(10), int32(-42)
+	if want, got := c+d>>3, addshiftRA_ssa(c, d); got != want {
+		t.Errorf("addshiftRA_ssa(10, -42) = %d want %d", got, want)
+	}
+	if want, got := c-d>>3, subshiftRA_ssa(c, d); got != want {
+		t.Errorf("subshiftRA_ssa(10, -42) = %d want %d", got, want)
+	}
+	if want, got := c>>3-d, rsbshiftRA_ssa(c, d); got != want {
+		t.Errorf("rsbshiftRA_ssa(10, -42) = %d want %d", got, want)
+	}
+	if want, got := c&(d>>3), andshiftRA_ssa(c, d); got != want {
+		t.Errorf("andshiftRA_ssa(10, -42) = %d want %d", got, want)
+	}
+	if want, got := c|d>>3, orshiftRA_ssa(c, d); got != want {
+		t.Errorf("orshiftRA_ssa(10, -42) = %d want %d", got, want)
+	}
+	if want, got := c^d>>3, xorshiftRA_ssa(c, d); got != want {
+		t.Errorf("xorshiftRA_ssa(10, -42) = %d want %d", got, want)
+	}
+	if want, got := c&^(d>>3), bicshiftRA_ssa(c, d); got != want {
+		t.Errorf("bicshiftRA_ssa(10, -42) = %d want %d", got, want)
+	}
+	if want, got := ^(d >> 3), notshiftRA_ssa(d); got != want {
+		t.Errorf("notshiftRA_ssa(-42) = %d want %d", got, want)
+	}
+	s := uint8(3)
+	if want, got := a+b<<s, addshiftLLreg_ssa(a, b, s); got != want {
+		t.Errorf("addshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := a-b<<s, subshiftLLreg_ssa(a, b, s); got != want {
+		t.Errorf("subshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := a<<s-b, rsbshiftLLreg_ssa(a, b, s); got != want {
+		t.Errorf("rsbshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := a&(b<<s), andshiftLLreg_ssa(a, b, s); got != want {
+		t.Errorf("andshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := a|b<<s, orshiftLLreg_ssa(a, b, s); got != want {
+		t.Errorf("orshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := a^b<<s, xorshiftLLreg_ssa(a, b, s); got != want {
+		t.Errorf("xorshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := a&^(b<<s), bicshiftLLreg_ssa(a, b, s); got != want {
+		t.Errorf("bicshiftLLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := ^(a << s), notshiftLLreg_ssa(a, s); got != want {
+		t.Errorf("notshiftLLreg_ssa(10) = %d want %d", got, want)
+	}
+	if want, got := a+b>>s, addshiftRLreg_ssa(a, b, s); got != want {
+		t.Errorf("addshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := a-b>>s, subshiftRLreg_ssa(a, b, s); got != want {
+		t.Errorf("subshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := a>>s-b, rsbshiftRLreg_ssa(a, b, s); got != want {
+		t.Errorf("rsbshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := a&(b>>s), andshiftRLreg_ssa(a, b, s); got != want {
+		t.Errorf("andshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := a|b>>s, orshiftRLreg_ssa(a, b, s); got != want {
+		t.Errorf("orshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := a^b>>s, xorshiftRLreg_ssa(a, b, s); got != want {
+		t.Errorf("xorshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := a&^(b>>s), bicshiftRLreg_ssa(a, b, s); got != want {
+		t.Errorf("bicshiftRLreg_ssa(10, 42, 3) = %d want %d", got, want)
+	}
+	if want, got := ^(a >> s), notshiftRLreg_ssa(a, s); got != want {
+		t.Errorf("notshiftRLreg_ssa(10) = %d want %d", got, want)
+	}
+	if want, got := c+d>>s, addshiftRAreg_ssa(c, d, s); got != want {
+		t.Errorf("addshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
+	}
+	if want, got := c-d>>s, subshiftRAreg_ssa(c, d, s); got != want {
+		t.Errorf("subshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
+	}
+	if want, got := c>>s-d, rsbshiftRAreg_ssa(c, d, s); got != want {
+		t.Errorf("rsbshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
+	}
+	if want, got := c&(d>>s), andshiftRAreg_ssa(c, d, s); got != want {
+		t.Errorf("andshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
+	}
+	if want, got := c|d>>s, orshiftRAreg_ssa(c, d, s); got != want {
+		t.Errorf("orshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
+	}
+	if want, got := c^d>>s, xorshiftRAreg_ssa(c, d, s); got != want {
+		t.Errorf("xorshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
+	}
+	if want, got := c&^(d>>s), bicshiftRAreg_ssa(c, d, s); got != want {
+		t.Errorf("bicshiftRAreg_ssa(10, -42, 3) = %d want %d", got, want)
+	}
+	if want, got := ^(d >> s), notshiftRAreg_ssa(d, s); got != want {
+		t.Errorf("notshiftRAreg_ssa(-42, 3) = %d want %d", got, want)
+	}
+}
+
+// TestArithmetic tests that both backends have the same result for arithmetic expressions.
+func TestArithmetic(t *testing.T) {
+	test64BitConstMult(t)
+	test64BitConstAdd(t)
+	testRegallocCVSpill(t)
+	testSubqToNegq(t)
+	testBitwiseLogic(t)
+	testOcom(t)
+	testLrot(t)
+	testShiftCX(t)
+	testSubConst(t)
+	testOverflowConstShift(t)
+	testArithConstShift(t)
+	testArithRshConst(t)
+	testLargeConst(t)
+	testLoadCombine(t)
+	testLoadSymCombine(t)
+	testShiftRemoval(t)
+	testShiftedOps(t)
+	testDivFixUp(t)
+	testDivisibleSignedPow2(t)
+	testDivisibility(t)
+}
+
+// testDivFixUp ensures that signed division fix-ups are being generated.
+func testDivFixUp(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			t.Error("testDivFixUp failed")
+			if e, ok := r.(runtime.Error); ok {
+				t.Logf("%v\n", e.Error())
+			}
+		}
+	}()
+	var w int8 = -128
+	var x int16 = -32768
+	var y int32 = -2147483648
+	var z int64 = -9223372036854775808
+
+	for i := -5; i < 0; i++ {
+		g8 = w / int8(i)
+		g16 = x / int16(i)
+		g32 = y / int32(i)
+		g64 = z / int64(i)
+		g8 = w % int8(i)
+		g16 = x % int16(i)
+		g32 = y % int32(i)
+		g64 = z % int64(i)
+	}
+}
+
+//go:noinline
+func divisible_int8_2to1(x int8) bool {
+	return x%(1<<1) == 0
+}
+
+//go:noinline
+func divisible_int8_2to2(x int8) bool {
+	return x%(1<<2) == 0
+}
+
+//go:noinline
+func divisible_int8_2to3(x int8) bool {
+	return x%(1<<3) == 0
+}
+
+//go:noinline
+func divisible_int8_2to4(x int8) bool {
+	return x%(1<<4) == 0
+}
+
+//go:noinline
+func divisible_int8_2to5(x int8) bool {
+	return x%(1<<5) == 0
+}
+
+//go:noinline
+func divisible_int8_2to6(x int8) bool {
+	return x%(1<<6) == 0
+}
+
+//go:noinline
+func divisible_int16_2to1(x int16) bool {
+	return x%(1<<1) == 0
+}
+
+//go:noinline
+func divisible_int16_2to2(x int16) bool {
+	return x%(1<<2) == 0
+}
+
+//go:noinline
+func divisible_int16_2to3(x int16) bool {
+	return x%(1<<3) == 0
+}
+
+//go:noinline
+func divisible_int16_2to4(x int16) bool {
+	return x%(1<<4) == 0
+}
+
+//go:noinline
+func divisible_int16_2to5(x int16) bool {
+	return x%(1<<5) == 0
+}
+
+//go:noinline
+func divisible_int16_2to6(x int16) bool {
+	return x%(1<<6) == 0
+}
+
+//go:noinline
+func divisible_int16_2to7(x int16) bool {
+	return x%(1<<7) == 0
+}
+
+//go:noinline
+func divisible_int16_2to8(x int16) bool {
+	return x%(1<<8) == 0
+}
+
+//go:noinline
+func divisible_int16_2to9(x int16) bool {
+	return x%(1<<9) == 0
+}
+
+//go:noinline
+func divisible_int16_2to10(x int16) bool {
+	return x%(1<<10) == 0
+}
+
+//go:noinline
+func divisible_int16_2to11(x int16) bool {
+	return x%(1<<11) == 0
+}
+
+//go:noinline
+func divisible_int16_2to12(x int16) bool {
+	return x%(1<<12) == 0
+}
+
+//go:noinline
+func divisible_int16_2to13(x int16) bool {
+	return x%(1<<13) == 0
+}
+
+//go:noinline
+func divisible_int16_2to14(x int16) bool {
+	return x%(1<<14) == 0
+}
+
+//go:noinline
+func divisible_int32_2to4(x int32) bool {
+	return x%(1<<4) == 0
+}
+
+//go:noinline
+func divisible_int32_2to15(x int32) bool {
+	return x%(1<<15) == 0
+}
+
+//go:noinline
+func divisible_int32_2to26(x int32) bool {
+	return x%(1<<26) == 0
+}
+
+//go:noinline
+func divisible_int64_2to4(x int64) bool {
+	return x%(1<<4) == 0
+}
+
+//go:noinline
+func divisible_int64_2to15(x int64) bool {
+	return x%(1<<15) == 0
+}
+
+//go:noinline
+func divisible_int64_2to26(x int64) bool {
+	return x%(1<<26) == 0
+}
+
+//go:noinline
+func divisible_int64_2to34(x int64) bool {
+	return x%(1<<34) == 0
+}
+
+//go:noinline
+func divisible_int64_2to48(x int64) bool {
+	return x%(1<<48) == 0
+}
+
+//go:noinline
+func divisible_int64_2to57(x int64) bool {
+	return x%(1<<57) == 0
+}
+
+// testDivisibleSignedPow2 confirms that x%(1<<k)==0 is rewritten correctly
+func testDivisibleSignedPow2(t *testing.T) {
+	var i int64
+	var pow2 = []int64{
+		1,
+		1 << 1,
+		1 << 2,
+		1 << 3,
+		1 << 4,
+		1 << 5,
+		1 << 6,
+		1 << 7,
+		1 << 8,
+		1 << 9,
+		1 << 10,
+		1 << 11,
+		1 << 12,
+		1 << 13,
+		1 << 14,
+	}
+	// exhaustive test for int8
+	for i = math.MinInt8; i <= math.MaxInt8; i++ {
+		if want, got := int8(i)%int8(pow2[1]) == 0, divisible_int8_2to1(int8(i)); got != want {
+			t.Errorf("divisible_int8_2to1(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int8(i)%int8(pow2[2]) == 0, divisible_int8_2to2(int8(i)); got != want {
+			t.Errorf("divisible_int8_2to2(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int8(i)%int8(pow2[3]) == 0, divisible_int8_2to3(int8(i)); got != want {
+			t.Errorf("divisible_int8_2to3(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int8(i)%int8(pow2[4]) == 0, divisible_int8_2to4(int8(i)); got != want {
+			t.Errorf("divisible_int8_2to4(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int8(i)%int8(pow2[5]) == 0, divisible_int8_2to5(int8(i)); got != want {
+			t.Errorf("divisible_int8_2to5(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int8(i)%int8(pow2[6]) == 0, divisible_int8_2to6(int8(i)); got != want {
+			t.Errorf("divisible_int8_2to6(%d) = %v want %v", i, got, want)
+		}
+	}
+	// exhaustive test for int16
+	for i = math.MinInt16; i <= math.MaxInt16; i++ {
+		if want, got := int16(i)%int16(pow2[1]) == 0, divisible_int16_2to1(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to1(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[2]) == 0, divisible_int16_2to2(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to2(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[3]) == 0, divisible_int16_2to3(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to3(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[4]) == 0, divisible_int16_2to4(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to4(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[5]) == 0, divisible_int16_2to5(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to5(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[6]) == 0, divisible_int16_2to6(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to6(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[7]) == 0, divisible_int16_2to7(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to7(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[8]) == 0, divisible_int16_2to8(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to8(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[9]) == 0, divisible_int16_2to9(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to9(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[10]) == 0, divisible_int16_2to10(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to10(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[11]) == 0, divisible_int16_2to11(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to11(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[12]) == 0, divisible_int16_2to12(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to12(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[13]) == 0, divisible_int16_2to13(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to13(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(pow2[14]) == 0, divisible_int16_2to14(int16(i)); got != want {
+			t.Errorf("divisible_int16_2to14(%d) = %v want %v", i, got, want)
+		}
+	}
+	// spot check for int32 and int64
+	var (
+		two4  int64 = 1 << 4
+		two15 int64 = 1 << 15
+		two26 int64 = 1 << 26
+		two34 int64 = 1 << 34
+		two48 int64 = 1 << 48
+		two57 int64 = 1 << 57
+	)
+	var xs = []int64{two4, two4 + 3, -3 * two4, -3*two4 + 1,
+		two15, two15 + 3, -3 * two15, -3*two15 + 1,
+		two26, two26 + 37, -5 * two26, -5*two26 + 2,
+		two34, two34 + 356, -7 * two34, -7*two34 + 13,
+		two48, two48 + 3000, -12 * two48, -12*two48 + 1111,
+		two57, two57 + 397654, -15 * two57, -15*two57 + 11234,
+	}
+	for _, x := range xs {
+		if int64(int32(x)) == x {
+			if want, got := int32(x)%int32(two4) == 0, divisible_int32_2to4(int32(x)); got != want {
+				t.Errorf("divisible_int32_2to4(%d) = %v want %v", x, got, want)
+			}
+
+			if want, got := int32(x)%int32(two15) == 0, divisible_int32_2to15(int32(x)); got != want {
+				t.Errorf("divisible_int32_2to15(%d) = %v want %v", x, got, want)
+			}
+
+			if want, got := int32(x)%int32(two26) == 0, divisible_int32_2to26(int32(x)); got != want {
+				t.Errorf("divisible_int32_2to26(%d) = %v want %v", x, got, want)
+			}
+		}
+		// spot check for int64
+		if want, got := x%two4 == 0, divisible_int64_2to4(x); got != want {
+			t.Errorf("divisible_int64_2to4(%d) = %v want %v", x, got, want)
+		}
+
+		if want, got := x%two15 == 0, divisible_int64_2to15(x); got != want {
+			t.Errorf("divisible_int64_2to15(%d) = %v want %v", x, got, want)
+		}
+
+		if want, got := x%two26 == 0, divisible_int64_2to26(x); got != want {
+			t.Errorf("divisible_int64_2to26(%d) = %v want %v", x, got, want)
+		}
+
+		if want, got := x%two34 == 0, divisible_int64_2to34(x); got != want {
+			t.Errorf("divisible_int64_2to34(%d) = %v want %v", x, got, want)
+		}
+
+		if want, got := x%two48 == 0, divisible_int64_2to48(x); got != want {
+			t.Errorf("divisible_int64_2to48(%d) = %v want %v", x, got, want)
+		}
+
+		if want, got := x%two57 == 0, divisible_int64_2to57(x); got != want {
+			t.Errorf("divisible_int64_2to57(%d) = %v want %v", x, got, want)
+		}
+	}
+}
+
+func div6_uint8(n uint8) bool {
+	return n%6 == 0
+}
+
+//go:noinline
+func div6_uint16(n uint16) bool {
+	return n%6 == 0
+}
+
+//go:noinline
+func div6_uint32(n uint32) bool {
+	return n%6 == 0
+}
+
+//go:noinline
+func div6_uint64(n uint64) bool {
+	return n%6 == 0
+}
+
+//go:noinline
+func div19_uint8(n uint8) bool {
+	return n%19 == 0
+}
+
+//go:noinline
+func div19_uint16(n uint16) bool {
+	return n%19 == 0
+}
+
+//go:noinline
+func div19_uint32(n uint32) bool {
+	return n%19 == 0
+}
+
+//go:noinline
+func div19_uint64(n uint64) bool {
+	return n%19 == 0
+}
+
+//go:noinline
+func div6_int8(n int8) bool {
+	return n%6 == 0
+}
+
+//go:noinline
+func div6_int16(n int16) bool {
+	return n%6 == 0
+}
+
+//go:noinline
+func div6_int32(n int32) bool {
+	return n%6 == 0
+}
+
+//go:noinline
+func div6_int64(n int64) bool {
+	return n%6 == 0
+}
+
+//go:noinline
+func div19_int8(n int8) bool {
+	return n%19 == 0
+}
+
+//go:noinline
+func div19_int16(n int16) bool {
+	return n%19 == 0
+}
+
+//go:noinline
+func div19_int32(n int32) bool {
+	return n%19 == 0
+}
+
+//go:noinline
+func div19_int64(n int64) bool {
+	return n%19 == 0
+}
+
+// testDivisibility confirms that rewrite rules x%c ==0 for c constant are correct.
+func testDivisibility(t *testing.T) {
+	// unsigned tests
+	// test an even and an odd divisor
+	var sixU, nineteenU uint64 = 6, 19
+	// test all inputs for uint8, uint16
+	for i := uint64(0); i <= math.MaxUint16; i++ {
+		if i <= math.MaxUint8 {
+			if want, got := uint8(i)%uint8(sixU) == 0, div6_uint8(uint8(i)); got != want {
+				t.Errorf("div6_uint8(%d) = %v want %v", i, got, want)
+			}
+			if want, got := uint8(i)%uint8(nineteenU) == 0, div19_uint8(uint8(i)); got != want {
+				t.Errorf("div6_uint19(%d) = %v want %v", i, got, want)
+			}
+		}
+		if want, got := uint16(i)%uint16(sixU) == 0, div6_uint16(uint16(i)); got != want {
+			t.Errorf("div6_uint16(%d) = %v want %v", i, got, want)
+		}
+		if want, got := uint16(i)%uint16(nineteenU) == 0, div19_uint16(uint16(i)); got != want {
+			t.Errorf("div19_uint16(%d) = %v want %v", i, got, want)
+		}
+	}
+	var maxU32, maxU64 uint64 = math.MaxUint32, math.MaxUint64
+	// spot check inputs for uint32 and uint64
+	xu := []uint64{
+		0, 1, 2, 3, 4, 5,
+		sixU, 2 * sixU, 3 * sixU, 5 * sixU, 12345 * sixU,
+		sixU + 1, 2*sixU - 5, 3*sixU + 3, 5*sixU + 4, 12345*sixU - 2,
+		nineteenU, 2 * nineteenU, 3 * nineteenU, 5 * nineteenU, 12345 * nineteenU,
+		nineteenU + 1, 2*nineteenU - 5, 3*nineteenU + 3, 5*nineteenU + 4, 12345*nineteenU - 2,
+		maxU32, maxU32 - 1, maxU32 - 2, maxU32 - 3, maxU32 - 4,
+		maxU32 - 5, maxU32 - 6, maxU32 - 7, maxU32 - 8,
+		maxU32 - 9, maxU32 - 10, maxU32 - 11, maxU32 - 12,
+		maxU32 - 13, maxU32 - 14, maxU32 - 15, maxU32 - 16,
+		maxU32 - 17, maxU32 - 18, maxU32 - 19, maxU32 - 20,
+		maxU64, maxU64 - 1, maxU64 - 2, maxU64 - 3, maxU64 - 4,
+		maxU64 - 5, maxU64 - 6, maxU64 - 7, maxU64 - 8,
+		maxU64 - 9, maxU64 - 10, maxU64 - 11, maxU64 - 12,
+		maxU64 - 13, maxU64 - 14, maxU64 - 15, maxU64 - 16,
+		maxU64 - 17, maxU64 - 18, maxU64 - 19, maxU64 - 20,
+	}
+	for _, x := range xu {
+		if x <= maxU32 {
+			if want, got := uint32(x)%uint32(sixU) == 0, div6_uint32(uint32(x)); got != want {
+				t.Errorf("div6_uint32(%d) = %v want %v", x, got, want)
+			}
+			if want, got := uint32(x)%uint32(nineteenU) == 0, div19_uint32(uint32(x)); got != want {
+				t.Errorf("div19_uint32(%d) = %v want %v", x, got, want)
+			}
+		}
+		if want, got := x%sixU == 0, div6_uint64(x); got != want {
+			t.Errorf("div6_uint64(%d) = %v want %v", x, got, want)
+		}
+		if want, got := x%nineteenU == 0, div19_uint64(x); got != want {
+			t.Errorf("div19_uint64(%d) = %v want %v", x, got, want)
+		}
+	}
+
+	// signed tests
+	// test an even and an odd divisor
+	var sixS, nineteenS int64 = 6, 19
+	// test all inputs for int8, int16
+	for i := int64(math.MinInt16); i <= math.MaxInt16; i++ {
+		if math.MinInt8 <= i && i <= math.MaxInt8 {
+			if want, got := int8(i)%int8(sixS) == 0, div6_int8(int8(i)); got != want {
+				t.Errorf("div6_int8(%d) = %v want %v", i, got, want)
+			}
+			if want, got := int8(i)%int8(nineteenS) == 0, div19_int8(int8(i)); got != want {
+				t.Errorf("div6_int19(%d) = %v want %v", i, got, want)
+			}
+		}
+		if want, got := int16(i)%int16(sixS) == 0, div6_int16(int16(i)); got != want {
+			t.Errorf("div6_int16(%d) = %v want %v", i, got, want)
+		}
+		if want, got := int16(i)%int16(nineteenS) == 0, div19_int16(int16(i)); got != want {
+			t.Errorf("div19_int16(%d) = %v want %v", i, got, want)
+		}
+	}
+	var minI32, maxI32, minI64, maxI64 int64 = math.MinInt32, math.MaxInt32, math.MinInt64, math.MaxInt64
+	// spot check inputs for int32 and int64
+	xs := []int64{
+		0, 1, 2, 3, 4, 5,
+		-1, -2, -3, -4, -5,
+		sixS, 2 * sixS, 3 * sixS, 5 * sixS, 12345 * sixS,
+		sixS + 1, 2*sixS - 5, 3*sixS + 3, 5*sixS + 4, 12345*sixS - 2,
+		-sixS, -2 * sixS, -3 * sixS, -5 * sixS, -12345 * sixS,
+		-sixS + 1, -2*sixS - 5, -3*sixS + 3, -5*sixS + 4, -12345*sixS - 2,
+		nineteenS, 2 * nineteenS, 3 * nineteenS, 5 * nineteenS, 12345 * nineteenS,
+		nineteenS + 1, 2*nineteenS - 5, 3*nineteenS + 3, 5*nineteenS + 4, 12345*nineteenS - 2,
+		-nineteenS, -2 * nineteenS, -3 * nineteenS, -5 * nineteenS, -12345 * nineteenS,
+		-nineteenS + 1, -2*nineteenS - 5, -3*nineteenS + 3, -5*nineteenS + 4, -12345*nineteenS - 2,
+		minI32, minI32 + 1, minI32 + 2, minI32 + 3, minI32 + 4,
+		minI32 + 5, minI32 + 6, minI32 + 7, minI32 + 8,
+		minI32 + 9, minI32 + 10, minI32 + 11, minI32 + 12,
+		minI32 + 13, minI32 + 14, minI32 + 15, minI32 + 16,
+		minI32 + 17, minI32 + 18, minI32 + 19, minI32 + 20,
+		maxI32, maxI32 - 1, maxI32 - 2, maxI32 - 3, maxI32 - 4,
+		maxI32 - 5, maxI32 - 6, maxI32 - 7, maxI32 - 8,
+		maxI32 - 9, maxI32 - 10, maxI32 - 11, maxI32 - 12,
+		maxI32 - 13, maxI32 - 14, maxI32 - 15, maxI32 - 16,
+		maxI32 - 17, maxI32 - 18, maxI32 - 19, maxI32 - 20,
+		minI64, minI64 + 1, minI64 + 2, minI64 + 3, minI64 + 4,
+		minI64 + 5, minI64 + 6, minI64 + 7, minI64 + 8,
+		minI64 + 9, minI64 + 10, minI64 + 11, minI64 + 12,
+		minI64 + 13, minI64 + 14, minI64 + 15, minI64 + 16,
+		minI64 + 17, minI64 + 18, minI64 + 19, minI64 + 20,
+		maxI64, maxI64 - 1, maxI64 - 2, maxI64 - 3, maxI64 - 4,
+		maxI64 - 5, maxI64 - 6, maxI64 - 7, maxI64 - 8,
+		maxI64 - 9, maxI64 - 10, maxI64 - 11, maxI64 - 12,
+		maxI64 - 13, maxI64 - 14, maxI64 - 15, maxI64 - 16,
+		maxI64 - 17, maxI64 - 18, maxI64 - 19, maxI64 - 20,
+	}
+	for _, x := range xs {
+		if minI32 <= x && x <= maxI32 {
+			if want, got := int32(x)%int32(sixS) == 0, div6_int32(int32(x)); got != want {
+				t.Errorf("div6_int32(%d) = %v want %v", x, got, want)
+			}
+			if want, got := int32(x)%int32(nineteenS) == 0, div19_int32(int32(x)); got != want {
+				t.Errorf("div19_int32(%d) = %v want %v", x, got, want)
+			}
+		}
+		if want, got := x%sixS == 0, div6_int64(x); got != want {
+			t.Errorf("div6_int64(%d) = %v want %v", x, got, want)
+		}
+		if want, got := x%nineteenS == 0, div19_int64(x); got != want {
+			t.Errorf("div19_int64(%d) = %v want %v", x, got, want)
+		}
+	}
+}
+
+//go:noinline
+func genREV16_1(c uint64) uint64 {
+	b := ((c & 0xff00ff00ff00ff00) >> 8) | ((c & 0x00ff00ff00ff00ff) << 8)
+	return b
+}
+
+//go:noinline
+func genREV16_2(c uint64) uint64 {
+	b := ((c & 0xff00ff00) >> 8) | ((c & 0x00ff00ff) << 8)
+	return b
+}
+
+//go:noinline
+func genREV16W(c uint32) uint32 {
+	b := ((c & 0xff00ff00) >> 8) | ((c & 0x00ff00ff) << 8)
+	return b
+}
+
+func TestREV16(t *testing.T) {
+	x := uint64(0x8f7f6f5f4f3f2f1f)
+	want1 := uint64(0x7f8f5f6f3f4f1f2f)
+	want2 := uint64(0x3f4f1f2f)
+
+	got1 := genREV16_1(x)
+	if got1 != want1 {
+		t.Errorf("genREV16_1(%#x) = %#x want %#x", x, got1, want1)
+	}
+	got2 := genREV16_2(x)
+	if got2 != want2 {
+		t.Errorf("genREV16_2(%#x) = %#x want %#x", x, got2, want2)
+	}
+}
+
+func TestREV16W(t *testing.T) {
+	x := uint32(0x4f3f2f1f)
+	want := uint32(0x3f4f1f2f)
+
+	got := genREV16W(x)
+	if got != want {
+		t.Errorf("genREV16W(%#x) = %#x want %#x", x, got, want)
+	}
+}
diff --git a/src/cmd/compile/internal/gc/testdata/array_test.go b/src/cmd/compile/internal/test/testdata/array_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/array_test.go
rename to src/cmd/compile/internal/test/testdata/array_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/assert_test.go b/src/cmd/compile/internal/test/testdata/assert_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/assert_test.go
rename to src/cmd/compile/internal/test/testdata/assert_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/break_test.go b/src/cmd/compile/internal/test/testdata/break_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/break_test.go
rename to src/cmd/compile/internal/test/testdata/break_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/chan_test.go b/src/cmd/compile/internal/test/testdata/chan_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/chan_test.go
rename to src/cmd/compile/internal/test/testdata/chan_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/closure_test.go b/src/cmd/compile/internal/test/testdata/closure_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/closure_test.go
rename to src/cmd/compile/internal/test/testdata/closure_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/cmpConst_test.go b/src/cmd/compile/internal/test/testdata/cmpConst_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/cmpConst_test.go
rename to src/cmd/compile/internal/test/testdata/cmpConst_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/cmp_test.go b/src/cmd/compile/internal/test/testdata/cmp_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/cmp_test.go
rename to src/cmd/compile/internal/test/testdata/cmp_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/compound_test.go b/src/cmd/compile/internal/test/testdata/compound_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/compound_test.go
rename to src/cmd/compile/internal/test/testdata/compound_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/copy_test.go b/src/cmd/compile/internal/test/testdata/copy_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/copy_test.go
rename to src/cmd/compile/internal/test/testdata/copy_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/ctl_test.go b/src/cmd/compile/internal/test/testdata/ctl_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/ctl_test.go
rename to src/cmd/compile/internal/test/testdata/ctl_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/deferNoReturn_test.go b/src/cmd/compile/internal/test/testdata/deferNoReturn_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/deferNoReturn_test.go
rename to src/cmd/compile/internal/test/testdata/deferNoReturn_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/divbyzero_test.go b/src/cmd/compile/internal/test/testdata/divbyzero_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/divbyzero_test.go
rename to src/cmd/compile/internal/test/testdata/divbyzero_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/dupLoad_test.go b/src/cmd/compile/internal/test/testdata/dupLoad_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/dupLoad_test.go
rename to src/cmd/compile/internal/test/testdata/dupLoad_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/flowgraph_generator1.go b/src/cmd/compile/internal/test/testdata/flowgraph_generator1.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/flowgraph_generator1.go
rename to src/cmd/compile/internal/test/testdata/flowgraph_generator1.go
diff --git a/src/cmd/compile/internal/gc/testdata/fp_test.go b/src/cmd/compile/internal/test/testdata/fp_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/fp_test.go
rename to src/cmd/compile/internal/test/testdata/fp_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/gen/arithBoundaryGen.go b/src/cmd/compile/internal/test/testdata/gen/arithBoundaryGen.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/gen/arithBoundaryGen.go
rename to src/cmd/compile/internal/test/testdata/gen/arithBoundaryGen.go
diff --git a/src/cmd/compile/internal/gc/testdata/gen/arithConstGen.go b/src/cmd/compile/internal/test/testdata/gen/arithConstGen.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/gen/arithConstGen.go
rename to src/cmd/compile/internal/test/testdata/gen/arithConstGen.go
diff --git a/src/cmd/compile/internal/gc/testdata/gen/cmpConstGen.go b/src/cmd/compile/internal/test/testdata/gen/cmpConstGen.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/gen/cmpConstGen.go
rename to src/cmd/compile/internal/test/testdata/gen/cmpConstGen.go
diff --git a/src/cmd/compile/internal/gc/testdata/gen/constFoldGen.go b/src/cmd/compile/internal/test/testdata/gen/constFoldGen.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/gen/constFoldGen.go
rename to src/cmd/compile/internal/test/testdata/gen/constFoldGen.go
diff --git a/src/cmd/compile/internal/gc/testdata/gen/copyGen.go b/src/cmd/compile/internal/test/testdata/gen/copyGen.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/gen/copyGen.go
rename to src/cmd/compile/internal/test/testdata/gen/copyGen.go
diff --git a/src/cmd/compile/internal/gc/testdata/gen/zeroGen.go b/src/cmd/compile/internal/test/testdata/gen/zeroGen.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/gen/zeroGen.go
rename to src/cmd/compile/internal/test/testdata/gen/zeroGen.go
diff --git a/src/cmd/compile/internal/gc/testdata/loadstore_test.go b/src/cmd/compile/internal/test/testdata/loadstore_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/loadstore_test.go
rename to src/cmd/compile/internal/test/testdata/loadstore_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/map_test.go b/src/cmd/compile/internal/test/testdata/map_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/map_test.go
rename to src/cmd/compile/internal/test/testdata/map_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/namedReturn_test.go b/src/cmd/compile/internal/test/testdata/namedReturn_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/namedReturn_test.go
rename to src/cmd/compile/internal/test/testdata/namedReturn_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/phi_test.go b/src/cmd/compile/internal/test/testdata/phi_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/phi_test.go
rename to src/cmd/compile/internal/test/testdata/phi_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/regalloc_test.go b/src/cmd/compile/internal/test/testdata/regalloc_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/regalloc_test.go
rename to src/cmd/compile/internal/test/testdata/regalloc_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/reproducible/issue20272.go b/src/cmd/compile/internal/test/testdata/reproducible/issue20272.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/reproducible/issue20272.go
rename to src/cmd/compile/internal/test/testdata/reproducible/issue20272.go
diff --git a/src/cmd/compile/internal/gc/testdata/reproducible/issue27013.go b/src/cmd/compile/internal/test/testdata/reproducible/issue27013.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/reproducible/issue27013.go
rename to src/cmd/compile/internal/test/testdata/reproducible/issue27013.go
diff --git a/src/cmd/compile/internal/gc/testdata/reproducible/issue30202.go b/src/cmd/compile/internal/test/testdata/reproducible/issue30202.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/reproducible/issue30202.go
rename to src/cmd/compile/internal/test/testdata/reproducible/issue30202.go
diff --git a/src/cmd/compile/internal/test/testdata/reproducible/issue38068.go b/src/cmd/compile/internal/test/testdata/reproducible/issue38068.go
new file mode 100644
index 0000000..b87daed
--- /dev/null
+++ b/src/cmd/compile/internal/test/testdata/reproducible/issue38068.go
@@ -0,0 +1,70 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue38068
+
+// A type with a couple of inlinable, non-pointer-receiver methods
+// that have params and local variables.
+type A struct {
+	s    string
+	next *A
+	prev *A
+}
+
+// Inlinable, value-received method with locals and parms.
+func (a A) double(x string, y int) string {
+	if y == 191 {
+		a.s = ""
+	}
+	q := a.s + "a"
+	r := a.s + "b"
+	return q + r
+}
+
+// Inlinable, value-received method with locals and parms.
+func (a A) triple(x string, y int) string {
+	q := a.s
+	if y == 998877 {
+		a.s = x
+	}
+	r := a.s + a.s
+	return q + r
+}
+
+type methods struct {
+	m1 func(a *A, x string, y int) string
+	m2 func(a *A, x string, y int) string
+}
+
+// Now a function that makes references to the methods via pointers,
+// which should trigger the wrapper generation.
+func P(a *A, ms *methods) {
+	if a != nil {
+		defer func() { println("done") }()
+	}
+	println(ms.m1(a, "a", 2))
+	println(ms.m2(a, "b", 3))
+}
+
+func G(x *A, n int) {
+	if n <= 0 {
+		println(n)
+		return
+	}
+	// Address-taken local of type A, which will insure that the
+	// compiler's writeType() routine will create a method wrapper.
+	var a, b A
+	a.next = x
+	a.prev = &b
+	x = &a
+	G(x, n-2)
+}
+
+var M methods
+
+func F() {
+	M.m1 = (*A).double
+	M.m2 = (*A).triple
+	G(nil, 100)
+}
diff --git a/src/cmd/compile/internal/gc/testdata/short_test.go b/src/cmd/compile/internal/test/testdata/short_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/short_test.go
rename to src/cmd/compile/internal/test/testdata/short_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/slice_test.go b/src/cmd/compile/internal/test/testdata/slice_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/slice_test.go
rename to src/cmd/compile/internal/test/testdata/slice_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/sqrtConst_test.go b/src/cmd/compile/internal/test/testdata/sqrtConst_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/sqrtConst_test.go
rename to src/cmd/compile/internal/test/testdata/sqrtConst_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/string_test.go b/src/cmd/compile/internal/test/testdata/string_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/string_test.go
rename to src/cmd/compile/internal/test/testdata/string_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/unsafe_test.go b/src/cmd/compile/internal/test/testdata/unsafe_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/unsafe_test.go
rename to src/cmd/compile/internal/test/testdata/unsafe_test.go
diff --git a/src/cmd/compile/internal/gc/testdata/zero_test.go b/src/cmd/compile/internal/test/testdata/zero_test.go
similarity index 100%
rename from src/cmd/compile/internal/gc/testdata/zero_test.go
rename to src/cmd/compile/internal/test/testdata/zero_test.go
diff --git a/src/cmd/compile/internal/test/truncconst_test.go b/src/cmd/compile/internal/test/truncconst_test.go
new file mode 100644
index 0000000..7705042
--- /dev/null
+++ b/src/cmd/compile/internal/test/truncconst_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.
+
+package test
+
+import "testing"
+
+var f52want float64 = 1.0 / (1 << 52)
+var f53want float64 = 1.0 / (1 << 53)
+
+func TestTruncFlt(t *testing.T) {
+	const f52 = 1 + 1.0/(1<<52)
+	const f53 = 1 + 1.0/(1<<53)
+
+	if got := f52 - 1; got != f52want {
+		t.Errorf("f52-1 = %g, want %g", got, f52want)
+	}
+	if got := float64(f52) - 1; got != f52want {
+		t.Errorf("float64(f52)-1 = %g, want %g", got, f52want)
+	}
+	if got := f53 - 1; got != f53want {
+		t.Errorf("f53-1 = %g, want %g", got, f53want)
+	}
+	if got := float64(f53) - 1; got != 0 {
+		t.Errorf("float64(f53)-1 = %g, want 0", got)
+	}
+}
+
+func TestTruncCmplx(t *testing.T) {
+	const r52 = complex(1+1.0/(1<<52), 0)
+	const r53 = complex(1+1.0/(1<<53), 0)
+
+	if got := real(r52 - 1); got != f52want {
+		t.Errorf("real(r52-1) = %g, want %g", got, f52want)
+	}
+	if got := real(complex128(r52) - 1); got != f52want {
+		t.Errorf("real(complex128(r52)-1) = %g, want %g", got, f52want)
+	}
+	if got := real(r53 - 1); got != f53want {
+		t.Errorf("real(r53-1) = %g, want %g", got, f53want)
+	}
+	if got := real(complex128(r53) - 1); got != 0 {
+		t.Errorf("real(complex128(r53)-1) = %g, want 0", got)
+	}
+
+	const i52 = complex(0, 1+1.0/(1<<52))
+	const i53 = complex(0, 1+1.0/(1<<53))
+
+	if got := imag(i52 - 1i); got != f52want {
+		t.Errorf("imag(i52-1i) = %g, want %g", got, f52want)
+	}
+	if got := imag(complex128(i52) - 1i); got != f52want {
+		t.Errorf("imag(complex128(i52)-1i) = %g, want %g", got, f52want)
+	}
+	if got := imag(i53 - 1i); got != f53want {
+		t.Errorf("imag(i53-1i) = %g, want %g", got, f53want)
+	}
+	if got := imag(complex128(i53) - 1i); got != 0 {
+		t.Errorf("imag(complex128(i53)-1i) = %g, want 0", got)
+	}
+
+}
diff --git a/src/cmd/compile/internal/test/zerorange_test.go b/src/cmd/compile/internal/test/zerorange_test.go
new file mode 100644
index 0000000..ec87136
--- /dev/null
+++ b/src/cmd/compile/internal/test/zerorange_test.go
@@ -0,0 +1,185 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test
+
+import (
+	"testing"
+)
+
+var glob = 3
+var globp *int64
+
+// Testing compilation of arch.ZeroRange of various sizes.
+
+// By storing a pointer to an int64 output param in a global, the compiler must
+// ensure that output param is allocated on the heap. Also, since there is a
+// defer, the pointer to each output param must be zeroed in the prologue (see
+// plive.go:epilogue()). So, we will get a block of one or more stack slots that
+// need to be zeroed. Hence, we are testing compilation completes successfully when
+// zerorange calls of various sizes (8-136 bytes) are generated. We are not
+// testing runtime correctness (which is hard to do for the current uses of
+// ZeroRange).
+
+func TestZeroRange(t *testing.T) {
+	testZeroRange8(t)
+	testZeroRange16(t)
+	testZeroRange32(t)
+	testZeroRange64(t)
+	testZeroRange136(t)
+}
+
+func testZeroRange8(t *testing.T) (r int64) {
+	defer func() {
+		glob = 4
+	}()
+	globp = &r
+	return
+}
+
+func testZeroRange16(t *testing.T) (r, s int64) {
+	defer func() {
+		glob = 4
+	}()
+	globp = &r
+	globp = &s
+	return
+}
+
+func testZeroRange32(t *testing.T) (r, s, t2, u int64) {
+	defer func() {
+		glob = 4
+	}()
+	globp = &r
+	globp = &s
+	globp = &t2
+	globp = &u
+	return
+}
+
+func testZeroRange64(t *testing.T) (r, s, t2, u, v, w, x, y int64) {
+	defer func() {
+		glob = 4
+	}()
+	globp = &r
+	globp = &s
+	globp = &t2
+	globp = &u
+	globp = &v
+	globp = &w
+	globp = &x
+	globp = &y
+	return
+}
+
+func testZeroRange136(t *testing.T) (r, s, t2, u, v, w, x, y, r1, s1, t1, u1, v1, w1, x1, y1, z1 int64) {
+	defer func() {
+		glob = 4
+	}()
+	globp = &r
+	globp = &s
+	globp = &t2
+	globp = &u
+	globp = &v
+	globp = &w
+	globp = &x
+	globp = &y
+	globp = &r1
+	globp = &s1
+	globp = &t1
+	globp = &u1
+	globp = &v1
+	globp = &w1
+	globp = &x1
+	globp = &y1
+	globp = &z1
+	return
+}
+
+type S struct {
+	x [2]uint64
+	p *uint64
+	y [2]uint64
+	q uint64
+}
+
+type M struct {
+	x [8]uint64
+	p *uint64
+	y [8]uint64
+	q uint64
+}
+
+type L struct {
+	x [4096]uint64
+	p *uint64
+	y [4096]uint64
+	q uint64
+}
+
+//go:noinline
+func triggerZerorangeLarge(f, g, h uint64) (rv0 uint64) {
+	ll := L{p: &f}
+	da := f
+	rv0 = f + g + h
+	defer func(dl L, i uint64) {
+		rv0 += dl.q + i
+	}(ll, da)
+	return rv0
+}
+
+//go:noinline
+func triggerZerorangeMedium(f, g, h uint64) (rv0 uint64) {
+	ll := M{p: &f}
+	rv0 = f + g + h
+	defer func(dm M, i uint64) {
+		rv0 += dm.q + i
+	}(ll, f)
+	return rv0
+}
+
+//go:noinline
+func triggerZerorangeSmall(f, g, h uint64) (rv0 uint64) {
+	ll := S{p: &f}
+	rv0 = f + g + h
+	defer func(ds S, i uint64) {
+		rv0 += ds.q + i
+	}(ll, f)
+	return rv0
+}
+
+// This test was created as a follow up to issue #45372, to help
+// improve coverage of the compiler's arch-specific "zerorange"
+// function, which is invoked to zero out ambiguously live portions of
+// the stack frame in certain specific circumstances.
+//
+// In the current compiler implementation, for zerorange to be
+// invoked, we need to have an ambiguously live variable that needs
+// zeroing. One way to trigger this is to have a function with an
+// open-coded defer, where the opendefer function has an argument that
+// contains a pointer (this is what's used below).
+//
+// At the moment this test doesn't do any specific checking for
+// code sequence, or verification that things were properly set to zero,
+// this seems as though it would be too tricky and would result
+// in a "brittle" test.
+//
+// The small/medium/large scenarios below are inspired by the amd64
+// implementation of zerorange, which generates different code
+// depending on the size of the thing that needs to be zeroed out
+// (I've verified at the time of the writing of this test that it
+// exercises the various cases).
+//
+func TestZerorange45372(t *testing.T) {
+	if r := triggerZerorangeLarge(101, 303, 505); r != 1010 {
+		t.Errorf("large: wanted %d got %d", 1010, r)
+	}
+	if r := triggerZerorangeMedium(101, 303, 505); r != 1010 {
+		t.Errorf("medium: wanted %d got %d", 1010, r)
+	}
+	if r := triggerZerorangeSmall(101, 303, 505); r != 1010 {
+		t.Errorf("small: wanted %d got %d", 1010, r)
+	}
+
+}
diff --git a/src/cmd/compile/internal/typebits/typebits.go b/src/cmd/compile/internal/typebits/typebits.go
new file mode 100644
index 0000000..1c1b077
--- /dev/null
+++ b/src/cmd/compile/internal/typebits/typebits.go
@@ -0,0 +1,87 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typebits
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/bitvec"
+	"cmd/compile/internal/types"
+)
+
+// 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 Set(t *types.Type, off int64, bv bitvec.BitVec) {
+	if t.Align > 0 && off&int64(t.Align-1) != 0 {
+		base.Fatalf("typebits.Set: invalid initial alignment: type %v has alignment %d, but offset is %v", t, t.Align, off)
+	}
+	if !t.HasPointers() {
+		// Note: this case ensures that pointers to go:notinheap types
+		// are not considered pointers by garbage collection and stack copying.
+		return
+	}
+
+	switch t.Kind() {
+	case types.TPTR, types.TUNSAFEPTR, types.TFUNC, types.TCHAN, types.TMAP:
+		if off&int64(types.PtrSize-1) != 0 {
+			base.Fatalf("typebits.Set: invalid alignment, %v", t)
+		}
+		bv.Set(int32(off / int64(types.PtrSize))) // pointer
+
+	case types.TSTRING:
+		// struct { byte *str; intgo len; }
+		if off&int64(types.PtrSize-1) != 0 {
+			base.Fatalf("typebits.Set: invalid alignment, %v", t)
+		}
+		bv.Set(int32(off / int64(types.PtrSize))) //pointer in first slot
+
+	case types.TINTER:
+		// struct { Itab *tab;	void *data; }
+		// or, when isnilinter(t)==true:
+		// struct { Type *type; void *data; }
+		if off&int64(types.PtrSize-1) != 0 {
+			base.Fatalf("typebits.Set: invalid alignment, %v", t)
+		}
+		// The first word of an interface is a pointer, but we don't
+		// treat it as such.
+		// 1. If it is a non-empty interface, the pointer points to an itab
+		//    which is always in persistentalloc space.
+		// 2. If it is an empty interface, the pointer points to a _type.
+		//   a. If it is a compile-time-allocated type, it points into
+		//      the read-only data section.
+		//   b. If it is a reflect-allocated type, it points into the Go heap.
+		//      Reflect is responsible for keeping a reference to
+		//      the underlying type so it won't be GCd.
+		// If we ever have a moving GC, we need to change this for 2b (as
+		// well as scan itabs to update their itab._type fields).
+		bv.Set(int32(off/int64(types.PtrSize) + 1)) // pointer in second slot
+
+	case types.TSLICE:
+		// struct { byte *array; uintgo len; uintgo cap; }
+		if off&int64(types.PtrSize-1) != 0 {
+			base.Fatalf("typebits.Set: invalid TARRAY alignment, %v", t)
+		}
+		bv.Set(int32(off / int64(types.PtrSize))) // pointer in first slot (BitsPointer)
+
+	case types.TARRAY:
+		elt := t.Elem()
+		if elt.Width == 0 {
+			// Short-circuit for #20739.
+			break
+		}
+		for i := int64(0); i < t.NumElem(); i++ {
+			Set(elt, off, bv)
+			off += elt.Width
+		}
+
+	case types.TSTRUCT:
+		for _, f := range t.Fields().Slice() {
+			Set(f.Type, off+f.Offset, bv)
+		}
+
+	default:
+		base.Fatalf("typebits.Set: unexpected type, %v", t)
+	}
+}
diff --git a/src/cmd/compile/internal/typecheck/bexport.go b/src/cmd/compile/internal/typecheck/bexport.go
new file mode 100644
index 0000000..4a84bb1
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/bexport.go
@@ -0,0 +1,102 @@
+// 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 typecheck
+
+import "cmd/compile/internal/types"
+
+// ----------------------------------------------------------------------------
+// Export format
+
+// Tags. Must be < 0.
+const (
+	// Objects
+	packageTag = -(iota + 1)
+	constTag
+	typeTag
+	varTag
+	funcTag
+	endTag
+
+	// Types
+	namedTag
+	arrayTag
+	sliceTag
+	dddTag
+	structTag
+	pointerTag
+	signatureTag
+	interfaceTag
+	mapTag
+	chanTag
+
+	// Values
+	falseTag
+	trueTag
+	int64Tag
+	floatTag
+	fractionTag // not used by gc
+	complexTag
+	stringTag
+	nilTag
+	unknownTag // not used by gc (only appears in packages with errors)
+
+	// Type aliases
+	aliasTag
+)
+
+var predecl []*types.Type // initialized lazily
+
+func predeclared() []*types.Type {
+	if predecl == nil {
+		// initialize lazily to be sure that all
+		// elements have been initialized before
+		predecl = []*types.Type{
+			// basic types
+			types.Types[types.TBOOL],
+			types.Types[types.TINT],
+			types.Types[types.TINT8],
+			types.Types[types.TINT16],
+			types.Types[types.TINT32],
+			types.Types[types.TINT64],
+			types.Types[types.TUINT],
+			types.Types[types.TUINT8],
+			types.Types[types.TUINT16],
+			types.Types[types.TUINT32],
+			types.Types[types.TUINT64],
+			types.Types[types.TUINTPTR],
+			types.Types[types.TFLOAT32],
+			types.Types[types.TFLOAT64],
+			types.Types[types.TCOMPLEX64],
+			types.Types[types.TCOMPLEX128],
+			types.Types[types.TSTRING],
+
+			// basic type aliases
+			types.ByteType,
+			types.RuneType,
+
+			// error
+			types.ErrorType,
+
+			// untyped types
+			types.UntypedBool,
+			types.UntypedInt,
+			types.UntypedRune,
+			types.UntypedFloat,
+			types.UntypedComplex,
+			types.UntypedString,
+			types.Types[types.TNIL],
+
+			// package unsafe
+			types.Types[types.TUNSAFEPTR],
+
+			// invalid type (package contains errors)
+			types.Types[types.Txxx],
+
+			// any type, for builtin export data
+			types.Types[types.TANY],
+		}
+	}
+	return predecl
+}
diff --git a/src/cmd/compile/internal/typecheck/builtin.go b/src/cmd/compile/internal/typecheck/builtin.go
new file mode 100644
index 0000000..833b17b
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/builtin.go
@@ -0,0 +1,374 @@
+// Code generated by mkbuiltin.go. DO NOT EDIT.
+
+package typecheck
+
+import (
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+var runtimeDecls = [...]struct {
+	name string
+	tag  int
+	typ  int
+}{
+	{"newobject", funcTag, 4},
+	{"mallocgc", funcTag, 8},
+	{"panicdivide", funcTag, 9},
+	{"panicshift", funcTag, 9},
+	{"panicmakeslicelen", funcTag, 9},
+	{"panicmakeslicecap", funcTag, 9},
+	{"throwinit", funcTag, 9},
+	{"panicwrap", funcTag, 9},
+	{"gopanic", funcTag, 11},
+	{"gorecover", funcTag, 14},
+	{"goschedguarded", funcTag, 9},
+	{"goPanicIndex", funcTag, 16},
+	{"goPanicIndexU", funcTag, 18},
+	{"goPanicSliceAlen", funcTag, 16},
+	{"goPanicSliceAlenU", funcTag, 18},
+	{"goPanicSliceAcap", funcTag, 16},
+	{"goPanicSliceAcapU", funcTag, 18},
+	{"goPanicSliceB", funcTag, 16},
+	{"goPanicSliceBU", funcTag, 18},
+	{"goPanicSlice3Alen", funcTag, 16},
+	{"goPanicSlice3AlenU", funcTag, 18},
+	{"goPanicSlice3Acap", funcTag, 16},
+	{"goPanicSlice3AcapU", funcTag, 18},
+	{"goPanicSlice3B", funcTag, 16},
+	{"goPanicSlice3BU", funcTag, 18},
+	{"goPanicSlice3C", funcTag, 16},
+	{"goPanicSlice3CU", funcTag, 18},
+	{"goPanicSliceConvert", funcTag, 16},
+	{"printbool", funcTag, 19},
+	{"printfloat", funcTag, 21},
+	{"printint", funcTag, 23},
+	{"printhex", funcTag, 25},
+	{"printuint", funcTag, 25},
+	{"printcomplex", funcTag, 27},
+	{"printstring", funcTag, 29},
+	{"printpointer", funcTag, 30},
+	{"printuintptr", funcTag, 31},
+	{"printiface", funcTag, 30},
+	{"printeface", funcTag, 30},
+	{"printslice", funcTag, 30},
+	{"printnl", funcTag, 9},
+	{"printsp", funcTag, 9},
+	{"printlock", funcTag, 9},
+	{"printunlock", funcTag, 9},
+	{"concatstring2", funcTag, 34},
+	{"concatstring3", funcTag, 35},
+	{"concatstring4", funcTag, 36},
+	{"concatstring5", funcTag, 37},
+	{"concatstrings", funcTag, 39},
+	{"cmpstring", funcTag, 40},
+	{"intstring", funcTag, 43},
+	{"slicebytetostring", funcTag, 44},
+	{"slicebytetostringtmp", funcTag, 45},
+	{"slicerunetostring", funcTag, 48},
+	{"stringtoslicebyte", funcTag, 50},
+	{"stringtoslicerune", funcTag, 53},
+	{"slicecopy", funcTag, 54},
+	{"decoderune", funcTag, 55},
+	{"countrunes", funcTag, 56},
+	{"convI2I", funcTag, 57},
+	{"convT16", funcTag, 59},
+	{"convT32", funcTag, 61},
+	{"convT64", funcTag, 62},
+	{"convTstring", funcTag, 63},
+	{"convTslice", funcTag, 66},
+	{"convT2E", funcTag, 67},
+	{"convT2Enoptr", funcTag, 67},
+	{"convT2I", funcTag, 67},
+	{"convT2Inoptr", funcTag, 67},
+	{"assertE2I", funcTag, 68},
+	{"assertE2I2", funcTag, 57},
+	{"assertI2I", funcTag, 68},
+	{"assertI2I2", funcTag, 57},
+	{"panicdottypeE", funcTag, 69},
+	{"panicdottypeI", funcTag, 69},
+	{"panicnildottype", funcTag, 70},
+	{"ifaceeq", funcTag, 72},
+	{"efaceeq", funcTag, 72},
+	{"fastrand", funcTag, 73},
+	{"makemap64", funcTag, 75},
+	{"makemap", funcTag, 76},
+	{"makemap_small", funcTag, 77},
+	{"mapaccess1", funcTag, 78},
+	{"mapaccess1_fast32", funcTag, 79},
+	{"mapaccess1_fast64", funcTag, 80},
+	{"mapaccess1_faststr", funcTag, 81},
+	{"mapaccess1_fat", funcTag, 82},
+	{"mapaccess2", funcTag, 83},
+	{"mapaccess2_fast32", funcTag, 84},
+	{"mapaccess2_fast64", funcTag, 85},
+	{"mapaccess2_faststr", funcTag, 86},
+	{"mapaccess2_fat", funcTag, 87},
+	{"mapassign", funcTag, 78},
+	{"mapassign_fast32", funcTag, 79},
+	{"mapassign_fast32ptr", funcTag, 88},
+	{"mapassign_fast64", funcTag, 80},
+	{"mapassign_fast64ptr", funcTag, 88},
+	{"mapassign_faststr", funcTag, 81},
+	{"mapiterinit", funcTag, 89},
+	{"mapdelete", funcTag, 89},
+	{"mapdelete_fast32", funcTag, 90},
+	{"mapdelete_fast64", funcTag, 91},
+	{"mapdelete_faststr", funcTag, 92},
+	{"mapiternext", funcTag, 93},
+	{"mapclear", funcTag, 94},
+	{"makechan64", funcTag, 96},
+	{"makechan", funcTag, 97},
+	{"chanrecv1", funcTag, 99},
+	{"chanrecv2", funcTag, 100},
+	{"chansend1", funcTag, 102},
+	{"closechan", funcTag, 30},
+	{"writeBarrier", varTag, 104},
+	{"typedmemmove", funcTag, 105},
+	{"typedmemclr", funcTag, 106},
+	{"typedslicecopy", funcTag, 107},
+	{"selectnbsend", funcTag, 108},
+	{"selectnbrecv", funcTag, 109},
+	{"selectsetpc", funcTag, 110},
+	{"selectgo", funcTag, 111},
+	{"block", funcTag, 9},
+	{"makeslice", funcTag, 112},
+	{"makeslice64", funcTag, 113},
+	{"makeslicecopy", funcTag, 114},
+	{"growslice", funcTag, 116},
+	{"unsafeslice", funcTag, 117},
+	{"unsafeslice64", funcTag, 118},
+	{"unsafeslicecheckptr", funcTag, 118},
+	{"memmove", funcTag, 119},
+	{"memclrNoHeapPointers", funcTag, 120},
+	{"memclrHasPointers", funcTag, 120},
+	{"memequal", funcTag, 121},
+	{"memequal0", funcTag, 122},
+	{"memequal8", funcTag, 122},
+	{"memequal16", funcTag, 122},
+	{"memequal32", funcTag, 122},
+	{"memequal64", funcTag, 122},
+	{"memequal128", funcTag, 122},
+	{"f32equal", funcTag, 123},
+	{"f64equal", funcTag, 123},
+	{"c64equal", funcTag, 123},
+	{"c128equal", funcTag, 123},
+	{"strequal", funcTag, 123},
+	{"interequal", funcTag, 123},
+	{"nilinterequal", funcTag, 123},
+	{"memhash", funcTag, 124},
+	{"memhash0", funcTag, 125},
+	{"memhash8", funcTag, 125},
+	{"memhash16", funcTag, 125},
+	{"memhash32", funcTag, 125},
+	{"memhash64", funcTag, 125},
+	{"memhash128", funcTag, 125},
+	{"f32hash", funcTag, 125},
+	{"f64hash", funcTag, 125},
+	{"c64hash", funcTag, 125},
+	{"c128hash", funcTag, 125},
+	{"strhash", funcTag, 125},
+	{"interhash", funcTag, 125},
+	{"nilinterhash", funcTag, 125},
+	{"int64div", funcTag, 126},
+	{"uint64div", funcTag, 127},
+	{"int64mod", funcTag, 126},
+	{"uint64mod", funcTag, 127},
+	{"float64toint64", funcTag, 128},
+	{"float64touint64", funcTag, 129},
+	{"float64touint32", funcTag, 130},
+	{"int64tofloat64", funcTag, 131},
+	{"uint64tofloat64", funcTag, 132},
+	{"uint32tofloat64", funcTag, 133},
+	{"complex128div", funcTag, 134},
+	{"getcallerpc", funcTag, 135},
+	{"getcallersp", funcTag, 135},
+	{"racefuncenter", funcTag, 31},
+	{"racefuncexit", funcTag, 9},
+	{"raceread", funcTag, 31},
+	{"racewrite", funcTag, 31},
+	{"racereadrange", funcTag, 136},
+	{"racewriterange", funcTag, 136},
+	{"msanread", funcTag, 136},
+	{"msanwrite", funcTag, 136},
+	{"msanmove", funcTag, 137},
+	{"checkptrAlignment", funcTag, 138},
+	{"checkptrArithmetic", funcTag, 140},
+	{"libfuzzerTraceCmp1", funcTag, 141},
+	{"libfuzzerTraceCmp2", funcTag, 142},
+	{"libfuzzerTraceCmp4", funcTag, 143},
+	{"libfuzzerTraceCmp8", funcTag, 144},
+	{"libfuzzerTraceConstCmp1", funcTag, 141},
+	{"libfuzzerTraceConstCmp2", funcTag, 142},
+	{"libfuzzerTraceConstCmp4", funcTag, 143},
+	{"libfuzzerTraceConstCmp8", funcTag, 144},
+	{"x86HasPOPCNT", varTag, 6},
+	{"x86HasSSE41", varTag, 6},
+	{"x86HasFMA", varTag, 6},
+	{"armHasVFPv4", varTag, 6},
+	{"arm64HasATOMICS", varTag, 6},
+}
+
+// Not inlining this function removes a significant chunk of init code.
+//go:noinline
+func newSig(params, results []*types.Field) *types.Type {
+	return types.NewSignature(types.NoPkg, nil, nil, params, results)
+}
+
+func params(tlist ...*types.Type) []*types.Field {
+	flist := make([]*types.Field, len(tlist))
+	for i, typ := range tlist {
+		flist[i] = types.NewField(src.NoXPos, nil, typ)
+	}
+	return flist
+}
+
+func runtimeTypes() []*types.Type {
+	var typs [145]*types.Type
+	typs[0] = types.ByteType
+	typs[1] = types.NewPtr(typs[0])
+	typs[2] = types.Types[types.TANY]
+	typs[3] = types.NewPtr(typs[2])
+	typs[4] = newSig(params(typs[1]), params(typs[3]))
+	typs[5] = types.Types[types.TUINTPTR]
+	typs[6] = types.Types[types.TBOOL]
+	typs[7] = types.Types[types.TUNSAFEPTR]
+	typs[8] = newSig(params(typs[5], typs[1], typs[6]), params(typs[7]))
+	typs[9] = newSig(nil, nil)
+	typs[10] = types.Types[types.TINTER]
+	typs[11] = newSig(params(typs[10]), nil)
+	typs[12] = types.Types[types.TINT32]
+	typs[13] = types.NewPtr(typs[12])
+	typs[14] = newSig(params(typs[13]), params(typs[10]))
+	typs[15] = types.Types[types.TINT]
+	typs[16] = newSig(params(typs[15], typs[15]), nil)
+	typs[17] = types.Types[types.TUINT]
+	typs[18] = newSig(params(typs[17], typs[15]), nil)
+	typs[19] = newSig(params(typs[6]), nil)
+	typs[20] = types.Types[types.TFLOAT64]
+	typs[21] = newSig(params(typs[20]), nil)
+	typs[22] = types.Types[types.TINT64]
+	typs[23] = newSig(params(typs[22]), nil)
+	typs[24] = types.Types[types.TUINT64]
+	typs[25] = newSig(params(typs[24]), nil)
+	typs[26] = types.Types[types.TCOMPLEX128]
+	typs[27] = newSig(params(typs[26]), nil)
+	typs[28] = types.Types[types.TSTRING]
+	typs[29] = newSig(params(typs[28]), nil)
+	typs[30] = newSig(params(typs[2]), nil)
+	typs[31] = newSig(params(typs[5]), nil)
+	typs[32] = types.NewArray(typs[0], 32)
+	typs[33] = types.NewPtr(typs[32])
+	typs[34] = newSig(params(typs[33], typs[28], typs[28]), params(typs[28]))
+	typs[35] = newSig(params(typs[33], typs[28], typs[28], typs[28]), params(typs[28]))
+	typs[36] = newSig(params(typs[33], typs[28], typs[28], typs[28], typs[28]), params(typs[28]))
+	typs[37] = newSig(params(typs[33], typs[28], typs[28], typs[28], typs[28], typs[28]), params(typs[28]))
+	typs[38] = types.NewSlice(typs[28])
+	typs[39] = newSig(params(typs[33], typs[38]), params(typs[28]))
+	typs[40] = newSig(params(typs[28], typs[28]), params(typs[15]))
+	typs[41] = types.NewArray(typs[0], 4)
+	typs[42] = types.NewPtr(typs[41])
+	typs[43] = newSig(params(typs[42], typs[22]), params(typs[28]))
+	typs[44] = newSig(params(typs[33], typs[1], typs[15]), params(typs[28]))
+	typs[45] = newSig(params(typs[1], typs[15]), params(typs[28]))
+	typs[46] = types.RuneType
+	typs[47] = types.NewSlice(typs[46])
+	typs[48] = newSig(params(typs[33], typs[47]), params(typs[28]))
+	typs[49] = types.NewSlice(typs[0])
+	typs[50] = newSig(params(typs[33], typs[28]), params(typs[49]))
+	typs[51] = types.NewArray(typs[46], 32)
+	typs[52] = types.NewPtr(typs[51])
+	typs[53] = newSig(params(typs[52], typs[28]), params(typs[47]))
+	typs[54] = newSig(params(typs[3], typs[15], typs[3], typs[15], typs[5]), params(typs[15]))
+	typs[55] = newSig(params(typs[28], typs[15]), params(typs[46], typs[15]))
+	typs[56] = newSig(params(typs[28]), params(typs[15]))
+	typs[57] = newSig(params(typs[1], typs[2]), params(typs[2]))
+	typs[58] = types.Types[types.TUINT16]
+	typs[59] = newSig(params(typs[58]), params(typs[7]))
+	typs[60] = types.Types[types.TUINT32]
+	typs[61] = newSig(params(typs[60]), params(typs[7]))
+	typs[62] = newSig(params(typs[24]), params(typs[7]))
+	typs[63] = newSig(params(typs[28]), params(typs[7]))
+	typs[64] = types.Types[types.TUINT8]
+	typs[65] = types.NewSlice(typs[64])
+	typs[66] = newSig(params(typs[65]), params(typs[7]))
+	typs[67] = newSig(params(typs[1], typs[3]), params(typs[2]))
+	typs[68] = newSig(params(typs[1], typs[1]), params(typs[1]))
+	typs[69] = newSig(params(typs[1], typs[1], typs[1]), nil)
+	typs[70] = newSig(params(typs[1]), nil)
+	typs[71] = types.NewPtr(typs[5])
+	typs[72] = newSig(params(typs[71], typs[7], typs[7]), params(typs[6]))
+	typs[73] = newSig(nil, params(typs[60]))
+	typs[74] = types.NewMap(typs[2], typs[2])
+	typs[75] = newSig(params(typs[1], typs[22], typs[3]), params(typs[74]))
+	typs[76] = newSig(params(typs[1], typs[15], typs[3]), params(typs[74]))
+	typs[77] = newSig(nil, params(typs[74]))
+	typs[78] = newSig(params(typs[1], typs[74], typs[3]), params(typs[3]))
+	typs[79] = newSig(params(typs[1], typs[74], typs[60]), params(typs[3]))
+	typs[80] = newSig(params(typs[1], typs[74], typs[24]), params(typs[3]))
+	typs[81] = newSig(params(typs[1], typs[74], typs[28]), params(typs[3]))
+	typs[82] = newSig(params(typs[1], typs[74], typs[3], typs[1]), params(typs[3]))
+	typs[83] = newSig(params(typs[1], typs[74], typs[3]), params(typs[3], typs[6]))
+	typs[84] = newSig(params(typs[1], typs[74], typs[60]), params(typs[3], typs[6]))
+	typs[85] = newSig(params(typs[1], typs[74], typs[24]), params(typs[3], typs[6]))
+	typs[86] = newSig(params(typs[1], typs[74], typs[28]), params(typs[3], typs[6]))
+	typs[87] = newSig(params(typs[1], typs[74], typs[3], typs[1]), params(typs[3], typs[6]))
+	typs[88] = newSig(params(typs[1], typs[74], typs[7]), params(typs[3]))
+	typs[89] = newSig(params(typs[1], typs[74], typs[3]), nil)
+	typs[90] = newSig(params(typs[1], typs[74], typs[60]), nil)
+	typs[91] = newSig(params(typs[1], typs[74], typs[24]), nil)
+	typs[92] = newSig(params(typs[1], typs[74], typs[28]), nil)
+	typs[93] = newSig(params(typs[3]), nil)
+	typs[94] = newSig(params(typs[1], typs[74]), nil)
+	typs[95] = types.NewChan(typs[2], types.Cboth)
+	typs[96] = newSig(params(typs[1], typs[22]), params(typs[95]))
+	typs[97] = newSig(params(typs[1], typs[15]), params(typs[95]))
+	typs[98] = types.NewChan(typs[2], types.Crecv)
+	typs[99] = newSig(params(typs[98], typs[3]), nil)
+	typs[100] = newSig(params(typs[98], typs[3]), params(typs[6]))
+	typs[101] = types.NewChan(typs[2], types.Csend)
+	typs[102] = newSig(params(typs[101], typs[3]), nil)
+	typs[103] = types.NewArray(typs[0], 3)
+	typs[104] = types.NewStruct(types.NoPkg, []*types.Field{types.NewField(src.NoXPos, Lookup("enabled"), typs[6]), types.NewField(src.NoXPos, Lookup("pad"), typs[103]), types.NewField(src.NoXPos, Lookup("needed"), typs[6]), types.NewField(src.NoXPos, Lookup("cgo"), typs[6]), types.NewField(src.NoXPos, Lookup("alignme"), typs[24])})
+	typs[105] = newSig(params(typs[1], typs[3], typs[3]), nil)
+	typs[106] = newSig(params(typs[1], typs[3]), nil)
+	typs[107] = newSig(params(typs[1], typs[3], typs[15], typs[3], typs[15]), params(typs[15]))
+	typs[108] = newSig(params(typs[101], typs[3]), params(typs[6]))
+	typs[109] = newSig(params(typs[3], typs[98]), params(typs[6], typs[6]))
+	typs[110] = newSig(params(typs[71]), nil)
+	typs[111] = newSig(params(typs[1], typs[1], typs[71], typs[15], typs[15], typs[6]), params(typs[15], typs[6]))
+	typs[112] = newSig(params(typs[1], typs[15], typs[15]), params(typs[7]))
+	typs[113] = newSig(params(typs[1], typs[22], typs[22]), params(typs[7]))
+	typs[114] = newSig(params(typs[1], typs[15], typs[15], typs[7]), params(typs[7]))
+	typs[115] = types.NewSlice(typs[2])
+	typs[116] = newSig(params(typs[1], typs[115], typs[15]), params(typs[115]))
+	typs[117] = newSig(params(typs[1], typs[7], typs[15]), nil)
+	typs[118] = newSig(params(typs[1], typs[7], typs[22]), nil)
+	typs[119] = newSig(params(typs[3], typs[3], typs[5]), nil)
+	typs[120] = newSig(params(typs[7], typs[5]), nil)
+	typs[121] = newSig(params(typs[3], typs[3], typs[5]), params(typs[6]))
+	typs[122] = newSig(params(typs[3], typs[3]), params(typs[6]))
+	typs[123] = newSig(params(typs[7], typs[7]), params(typs[6]))
+	typs[124] = newSig(params(typs[7], typs[5], typs[5]), params(typs[5]))
+	typs[125] = newSig(params(typs[7], typs[5]), params(typs[5]))
+	typs[126] = newSig(params(typs[22], typs[22]), params(typs[22]))
+	typs[127] = newSig(params(typs[24], typs[24]), params(typs[24]))
+	typs[128] = newSig(params(typs[20]), params(typs[22]))
+	typs[129] = newSig(params(typs[20]), params(typs[24]))
+	typs[130] = newSig(params(typs[20]), params(typs[60]))
+	typs[131] = newSig(params(typs[22]), params(typs[20]))
+	typs[132] = newSig(params(typs[24]), params(typs[20]))
+	typs[133] = newSig(params(typs[60]), params(typs[20]))
+	typs[134] = newSig(params(typs[26], typs[26]), params(typs[26]))
+	typs[135] = newSig(nil, params(typs[5]))
+	typs[136] = newSig(params(typs[5], typs[5]), nil)
+	typs[137] = newSig(params(typs[5], typs[5], typs[5]), nil)
+	typs[138] = newSig(params(typs[7], typs[1], typs[5]), nil)
+	typs[139] = types.NewSlice(typs[7])
+	typs[140] = newSig(params(typs[7], typs[139]), nil)
+	typs[141] = newSig(params(typs[64], typs[64]), nil)
+	typs[142] = newSig(params(typs[58], typs[58]), nil)
+	typs[143] = newSig(params(typs[60], typs[60]), nil)
+	typs[144] = newSig(params(typs[24], typs[24]), nil)
+	return typs[:]
+}
diff --git a/src/cmd/compile/internal/typecheck/builtin/runtime.go b/src/cmd/compile/internal/typecheck/builtin/runtime.go
new file mode 100644
index 0000000..2b29ea3
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/builtin/runtime.go
@@ -0,0 +1,271 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// NOTE: If you change this file you must run "go generate"
+// to update builtin.go. This is not done automatically
+// to avoid depending on having a working compiler binary.
+
+//go:build ignore
+// +build ignore
+
+package runtime
+
+// emitted by compiler, not referred to by go programs
+
+import "unsafe"
+
+func newobject(typ *byte) *any
+func mallocgc(size uintptr, typ *byte, needszero bool) unsafe.Pointer
+func panicdivide()
+func panicshift()
+func panicmakeslicelen()
+func panicmakeslicecap()
+func throwinit()
+func panicwrap()
+
+func gopanic(interface{})
+func gorecover(*int32) interface{}
+func goschedguarded()
+
+// Note: these declarations are just for wasm port.
+// Other ports call assembly stubs instead.
+func goPanicIndex(x int, y int)
+func goPanicIndexU(x uint, y int)
+func goPanicSliceAlen(x int, y int)
+func goPanicSliceAlenU(x uint, y int)
+func goPanicSliceAcap(x int, y int)
+func goPanicSliceAcapU(x uint, y int)
+func goPanicSliceB(x int, y int)
+func goPanicSliceBU(x uint, y int)
+func goPanicSlice3Alen(x int, y int)
+func goPanicSlice3AlenU(x uint, y int)
+func goPanicSlice3Acap(x int, y int)
+func goPanicSlice3AcapU(x uint, y int)
+func goPanicSlice3B(x int, y int)
+func goPanicSlice3BU(x uint, y int)
+func goPanicSlice3C(x int, y int)
+func goPanicSlice3CU(x uint, y int)
+func goPanicSliceConvert(x int, y int)
+
+func printbool(bool)
+func printfloat(float64)
+func printint(int64)
+func printhex(uint64)
+func printuint(uint64)
+func printcomplex(complex128)
+func printstring(string)
+func printpointer(any)
+func printuintptr(uintptr)
+func printiface(any)
+func printeface(any)
+func printslice(any)
+func printnl()
+func printsp()
+func printlock()
+func printunlock()
+
+func concatstring2(*[32]byte, string, string) string
+func concatstring3(*[32]byte, string, string, string) string
+func concatstring4(*[32]byte, string, string, string, string) string
+func concatstring5(*[32]byte, string, string, string, string, string) string
+func concatstrings(*[32]byte, []string) string
+
+func cmpstring(string, string) int
+func intstring(*[4]byte, int64) string
+func slicebytetostring(buf *[32]byte, ptr *byte, n int) string
+func slicebytetostringtmp(ptr *byte, n int) string
+func slicerunetostring(*[32]byte, []rune) string
+func stringtoslicebyte(*[32]byte, string) []byte
+func stringtoslicerune(*[32]rune, string) []rune
+func slicecopy(toPtr *any, toLen int, fromPtr *any, fromLen int, wid uintptr) int
+
+func decoderune(string, int) (retv rune, retk int)
+func countrunes(string) int
+
+// Non-empty-interface to non-empty-interface conversion.
+func convI2I(typ *byte, elem any) (ret any)
+
+// Specialized type-to-interface conversion.
+// These return only a data pointer.
+// These functions take concrete types in the runtime. But they may
+// be used for a wider range of types, which have the same memory
+// layout as the parameter type. The compiler converts the
+// to-be-converted type to the parameter type before calling the
+// runtime function. This way, the call is ABI-insensitive.
+func convT16(val uint16) unsafe.Pointer
+func convT32(val uint32) unsafe.Pointer
+func convT64(val uint64) unsafe.Pointer
+func convTstring(val string) unsafe.Pointer
+func convTslice(val []uint8) unsafe.Pointer
+
+// Type to empty-interface conversion.
+func convT2E(typ *byte, elem *any) (ret any)
+func convT2Enoptr(typ *byte, elem *any) (ret any)
+
+// Type to non-empty-interface conversion.
+func convT2I(tab *byte, elem *any) (ret any)
+func convT2Inoptr(tab *byte, elem *any) (ret any)
+
+// interface type assertions x.(T)
+func assertE2I(inter *byte, typ *byte) *byte
+func assertE2I2(inter *byte, eface any) (ret any)
+func assertI2I(inter *byte, tab *byte) *byte
+func assertI2I2(inter *byte, iface any) (ret any)
+func panicdottypeE(have, want, iface *byte)
+func panicdottypeI(have, want, iface *byte)
+func panicnildottype(want *byte)
+
+// interface equality. Type/itab pointers are already known to be equal, so
+// we only need to pass one.
+func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
+func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
+
+func fastrand() uint32
+
+// *byte is really *runtime.Type
+func makemap64(mapType *byte, hint int64, mapbuf *any) (hmap map[any]any)
+func makemap(mapType *byte, hint int, mapbuf *any) (hmap map[any]any)
+func makemap_small() (hmap map[any]any)
+func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
+func mapaccess1_fast32(mapType *byte, hmap map[any]any, key uint32) (val *any)
+func mapaccess1_fast64(mapType *byte, hmap map[any]any, key uint64) (val *any)
+func mapaccess1_faststr(mapType *byte, hmap map[any]any, key string) (val *any)
+func mapaccess1_fat(mapType *byte, hmap map[any]any, key *any, zero *byte) (val *any)
+func mapaccess2(mapType *byte, hmap map[any]any, key *any) (val *any, pres bool)
+func mapaccess2_fast32(mapType *byte, hmap map[any]any, key uint32) (val *any, pres bool)
+func mapaccess2_fast64(mapType *byte, hmap map[any]any, key uint64) (val *any, pres bool)
+func mapaccess2_faststr(mapType *byte, hmap map[any]any, key string) (val *any, pres bool)
+func mapaccess2_fat(mapType *byte, hmap map[any]any, key *any, zero *byte) (val *any, pres bool)
+func mapassign(mapType *byte, hmap map[any]any, key *any) (val *any)
+func mapassign_fast32(mapType *byte, hmap map[any]any, key uint32) (val *any)
+func mapassign_fast32ptr(mapType *byte, hmap map[any]any, key unsafe.Pointer) (val *any)
+func mapassign_fast64(mapType *byte, hmap map[any]any, key uint64) (val *any)
+func mapassign_fast64ptr(mapType *byte, hmap map[any]any, key unsafe.Pointer) (val *any)
+func mapassign_faststr(mapType *byte, hmap map[any]any, key string) (val *any)
+func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
+func mapdelete(mapType *byte, hmap map[any]any, key *any)
+func mapdelete_fast32(mapType *byte, hmap map[any]any, key uint32)
+func mapdelete_fast64(mapType *byte, hmap map[any]any, key uint64)
+func mapdelete_faststr(mapType *byte, hmap map[any]any, key string)
+func mapiternext(hiter *any)
+func mapclear(mapType *byte, hmap map[any]any)
+
+// *byte is really *runtime.Type
+func makechan64(chanType *byte, size int64) (hchan chan any)
+func makechan(chanType *byte, size int) (hchan chan any)
+func chanrecv1(hchan <-chan any, elem *any)
+func chanrecv2(hchan <-chan any, elem *any) bool
+func chansend1(hchan chan<- any, elem *any)
+func closechan(hchan any)
+
+var writeBarrier struct {
+	enabled bool
+	pad     [3]byte
+	needed  bool
+	cgo     bool
+	alignme uint64
+}
+
+// *byte is really *runtime.Type
+func typedmemmove(typ *byte, dst *any, src *any)
+func typedmemclr(typ *byte, dst *any)
+func typedslicecopy(typ *byte, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int
+
+func selectnbsend(hchan chan<- any, elem *any) bool
+func selectnbrecv(elem *any, hchan <-chan any) (bool, bool)
+
+func selectsetpc(pc *uintptr)
+func selectgo(cas0 *byte, order0 *byte, pc0 *uintptr, nsends int, nrecvs int, block bool) (int, bool)
+func block()
+
+func makeslice(typ *byte, len int, cap int) unsafe.Pointer
+func makeslice64(typ *byte, len int64, cap int64) unsafe.Pointer
+func makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer
+func growslice(typ *byte, old []any, cap int) (ary []any)
+func unsafeslice(typ *byte, ptr unsafe.Pointer, len int)
+func unsafeslice64(typ *byte, ptr unsafe.Pointer, len int64)
+func unsafeslicecheckptr(typ *byte, ptr unsafe.Pointer, len int64)
+
+func memmove(to *any, frm *any, length uintptr)
+func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
+func memclrHasPointers(ptr unsafe.Pointer, n uintptr)
+
+func memequal(x, y *any, size uintptr) bool
+func memequal0(x, y *any) bool
+func memequal8(x, y *any) bool
+func memequal16(x, y *any) bool
+func memequal32(x, y *any) bool
+func memequal64(x, y *any) bool
+func memequal128(x, y *any) bool
+func f32equal(p, q unsafe.Pointer) bool
+func f64equal(p, q unsafe.Pointer) bool
+func c64equal(p, q unsafe.Pointer) bool
+func c128equal(p, q unsafe.Pointer) bool
+func strequal(p, q unsafe.Pointer) bool
+func interequal(p, q unsafe.Pointer) bool
+func nilinterequal(p, q unsafe.Pointer) bool
+
+func memhash(p unsafe.Pointer, h uintptr, size uintptr) uintptr
+func memhash0(p unsafe.Pointer, h uintptr) uintptr
+func memhash8(p unsafe.Pointer, h uintptr) uintptr
+func memhash16(p unsafe.Pointer, h uintptr) uintptr
+func memhash32(p unsafe.Pointer, h uintptr) uintptr
+func memhash64(p unsafe.Pointer, h uintptr) uintptr
+func memhash128(p unsafe.Pointer, h uintptr) uintptr
+func f32hash(p unsafe.Pointer, h uintptr) uintptr
+func f64hash(p unsafe.Pointer, h uintptr) uintptr
+func c64hash(p unsafe.Pointer, h uintptr) uintptr
+func c128hash(p unsafe.Pointer, h uintptr) uintptr
+func strhash(a unsafe.Pointer, h uintptr) uintptr
+func interhash(p unsafe.Pointer, h uintptr) uintptr
+func nilinterhash(p unsafe.Pointer, h uintptr) uintptr
+
+// only used on 32-bit
+func int64div(int64, int64) int64
+func uint64div(uint64, uint64) uint64
+func int64mod(int64, int64) int64
+func uint64mod(uint64, uint64) uint64
+func float64toint64(float64) int64
+func float64touint64(float64) uint64
+func float64touint32(float64) uint32
+func int64tofloat64(int64) float64
+func uint64tofloat64(uint64) float64
+func uint32tofloat64(uint32) float64
+
+func complex128div(num complex128, den complex128) (quo complex128)
+
+func getcallerpc() uintptr
+func getcallersp() uintptr
+
+// race detection
+func racefuncenter(uintptr)
+func racefuncexit()
+func raceread(uintptr)
+func racewrite(uintptr)
+func racereadrange(addr, size uintptr)
+func racewriterange(addr, size uintptr)
+
+// memory sanitizer
+func msanread(addr, size uintptr)
+func msanwrite(addr, size uintptr)
+func msanmove(dst, src, size uintptr)
+
+func checkptrAlignment(unsafe.Pointer, *byte, uintptr)
+func checkptrArithmetic(unsafe.Pointer, []unsafe.Pointer)
+
+func libfuzzerTraceCmp1(uint8, uint8)
+func libfuzzerTraceCmp2(uint16, uint16)
+func libfuzzerTraceCmp4(uint32, uint32)
+func libfuzzerTraceCmp8(uint64, uint64)
+func libfuzzerTraceConstCmp1(uint8, uint8)
+func libfuzzerTraceConstCmp2(uint16, uint16)
+func libfuzzerTraceConstCmp4(uint32, uint32)
+func libfuzzerTraceConstCmp8(uint64, uint64)
+
+// architecture variants
+var x86HasPOPCNT bool
+var x86HasSSE41 bool
+var x86HasFMA bool
+var armHasVFPv4 bool
+var arm64HasATOMICS bool
diff --git a/src/cmd/compile/internal/typecheck/builtin_test.go b/src/cmd/compile/internal/typecheck/builtin_test.go
new file mode 100644
index 0000000..fb9d3e3
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/builtin_test.go
@@ -0,0 +1,32 @@
+// 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 typecheck
+
+import (
+	"bytes"
+	"internal/testenv"
+	"io/ioutil"
+	"os/exec"
+	"testing"
+)
+
+func TestBuiltin(t *testing.T) {
+	testenv.MustHaveGoRun(t)
+	t.Parallel()
+
+	old, err := ioutil.ReadFile("builtin.go")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	new, err := exec.Command(testenv.GoToolPath(t), "run", "mkbuiltin.go", "-stdout").Output()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if !bytes.Equal(old, new) {
+		t.Fatal("builtin.go out of date; run mkbuiltin.go")
+	}
+}
diff --git a/src/cmd/compile/internal/typecheck/const.go b/src/cmd/compile/internal/typecheck/const.go
new file mode 100644
index 0000000..761b043
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/const.go
@@ -0,0 +1,941 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typecheck
+
+import (
+	"fmt"
+	"go/constant"
+	"go/token"
+	"math"
+	"math/big"
+	"strings"
+	"unicode"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+func roundFloat(v constant.Value, sz int64) constant.Value {
+	switch sz {
+	case 4:
+		f, _ := constant.Float32Val(v)
+		return makeFloat64(float64(f))
+	case 8:
+		f, _ := constant.Float64Val(v)
+		return makeFloat64(f)
+	}
+	base.Fatalf("unexpected size: %v", sz)
+	panic("unreachable")
+}
+
+// truncate float literal fv to 32-bit or 64-bit precision
+// according to type; return truncated value.
+func truncfltlit(v constant.Value, t *types.Type) constant.Value {
+	if t.IsUntyped() || overflow(v, t) {
+		// If there was overflow, simply continuing would set the
+		// value to Inf which in turn would lead to spurious follow-on
+		// errors. Avoid this by returning the existing value.
+		return v
+	}
+
+	return roundFloat(v, t.Size())
+}
+
+// truncate Real and Imag parts of Mpcplx to 32-bit or 64-bit
+// precision, according to type; return truncated value. In case of
+// overflow, calls Errorf but does not truncate the input value.
+func trunccmplxlit(v constant.Value, t *types.Type) constant.Value {
+	if t.IsUntyped() || overflow(v, t) {
+		// If there was overflow, simply continuing would set the
+		// value to Inf which in turn would lead to spurious follow-on
+		// errors. Avoid this by returning the existing value.
+		return v
+	}
+
+	fsz := t.Size() / 2
+	return makeComplex(roundFloat(constant.Real(v), fsz), roundFloat(constant.Imag(v), fsz))
+}
+
+// TODO(mdempsky): Replace these with better APIs.
+func convlit(n ir.Node, t *types.Type) ir.Node    { return convlit1(n, t, false, nil) }
+func DefaultLit(n ir.Node, t *types.Type) ir.Node { return convlit1(n, t, false, nil) }
+
+// convlit1 converts an untyped expression n to type t. If n already
+// has a type, convlit1 has no effect.
+//
+// For explicit conversions, t must be non-nil, and integer-to-string
+// conversions are allowed.
+//
+// For implicit conversions (e.g., assignments), t may be nil; if so,
+// n is converted to its default type.
+//
+// If there's an error converting n to t, context is used in the error
+// message.
+func convlit1(n ir.Node, t *types.Type, explicit bool, context func() string) ir.Node {
+	if explicit && t == nil {
+		base.Fatalf("explicit conversion missing type")
+	}
+	if t != nil && t.IsUntyped() {
+		base.Fatalf("bad conversion to untyped: %v", t)
+	}
+
+	if n == nil || n.Type() == nil {
+		// Allow sloppy callers.
+		return n
+	}
+	if !n.Type().IsUntyped() {
+		// Already typed; nothing to do.
+		return n
+	}
+
+	// Nil is technically not a constant, so handle it specially.
+	if n.Type().Kind() == types.TNIL {
+		if n.Op() != ir.ONIL {
+			base.Fatalf("unexpected op: %v (%v)", n, n.Op())
+		}
+		n = ir.Copy(n)
+		if t == nil {
+			base.Errorf("use of untyped nil")
+			n.SetDiag(true)
+			n.SetType(nil)
+			return n
+		}
+
+		if !t.HasNil() {
+			// Leave for caller to handle.
+			return n
+		}
+
+		n.SetType(t)
+		return n
+	}
+
+	if t == nil || !ir.OKForConst[t.Kind()] {
+		t = defaultType(n.Type())
+	}
+
+	switch n.Op() {
+	default:
+		base.Fatalf("unexpected untyped expression: %v", n)
+
+	case ir.OLITERAL:
+		v := convertVal(n.Val(), t, explicit)
+		if v.Kind() == constant.Unknown {
+			n = ir.NewConstExpr(n.Val(), n)
+			break
+		}
+		n = ir.NewConstExpr(v, n)
+		n.SetType(t)
+		return n
+
+	case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.OREAL, ir.OIMAG:
+		ot := operandType(n.Op(), t)
+		if ot == nil {
+			n = DefaultLit(n, nil)
+			break
+		}
+
+		n := n.(*ir.UnaryExpr)
+		n.X = convlit(n.X, ot)
+		if n.X.Type() == nil {
+			n.SetType(nil)
+			return n
+		}
+		n.SetType(t)
+		return n
+
+	case ir.OADD, ir.OSUB, ir.OMUL, ir.ODIV, ir.OMOD, ir.OOR, ir.OXOR, ir.OAND, ir.OANDNOT, ir.OOROR, ir.OANDAND, ir.OCOMPLEX:
+		ot := operandType(n.Op(), t)
+		if ot == nil {
+			n = DefaultLit(n, nil)
+			break
+		}
+
+		var l, r ir.Node
+		switch n := n.(type) {
+		case *ir.BinaryExpr:
+			n.X = convlit(n.X, ot)
+			n.Y = convlit(n.Y, ot)
+			l, r = n.X, n.Y
+		case *ir.LogicalExpr:
+			n.X = convlit(n.X, ot)
+			n.Y = convlit(n.Y, ot)
+			l, r = n.X, n.Y
+		}
+
+		if l.Type() == nil || r.Type() == nil {
+			n.SetType(nil)
+			return n
+		}
+		if !types.Identical(l.Type(), r.Type()) {
+			base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type(), r.Type())
+			n.SetType(nil)
+			return n
+		}
+
+		n.SetType(t)
+		return n
+
+	case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
+		n := n.(*ir.BinaryExpr)
+		if !t.IsBoolean() {
+			break
+		}
+		n.SetType(t)
+		return n
+
+	case ir.OLSH, ir.ORSH:
+		n := n.(*ir.BinaryExpr)
+		n.X = convlit1(n.X, t, explicit, nil)
+		n.SetType(n.X.Type())
+		if n.Type() != nil && !n.Type().IsInteger() {
+			base.Errorf("invalid operation: %v (shift of type %v)", n, n.Type())
+			n.SetType(nil)
+		}
+		return n
+	}
+
+	if !n.Diag() {
+		if !t.Broke() {
+			if explicit {
+				base.Errorf("cannot convert %L to type %v", n, t)
+			} else if context != nil {
+				base.Errorf("cannot use %L as type %v in %s", n, t, context())
+			} else {
+				base.Errorf("cannot use %L as type %v", n, t)
+			}
+		}
+		n.SetDiag(true)
+	}
+	n.SetType(nil)
+	return n
+}
+
+func operandType(op ir.Op, t *types.Type) *types.Type {
+	switch op {
+	case ir.OCOMPLEX:
+		if t.IsComplex() {
+			return types.FloatForComplex(t)
+		}
+	case ir.OREAL, ir.OIMAG:
+		if t.IsFloat() {
+			return types.ComplexForFloat(t)
+		}
+	default:
+		if okfor[op][t.Kind()] {
+			return t
+		}
+	}
+	return nil
+}
+
+// convertVal converts v into a representation appropriate for t. If
+// no such representation exists, it returns Val{} instead.
+//
+// If explicit is true, then conversions from integer to string are
+// also allowed.
+func convertVal(v constant.Value, t *types.Type, explicit bool) constant.Value {
+	switch ct := v.Kind(); ct {
+	case constant.Bool:
+		if t.IsBoolean() {
+			return v
+		}
+
+	case constant.String:
+		if t.IsString() {
+			return v
+		}
+
+	case constant.Int:
+		if explicit && t.IsString() {
+			return tostr(v)
+		}
+		fallthrough
+	case constant.Float, constant.Complex:
+		switch {
+		case t.IsInteger():
+			v = toint(v)
+			overflow(v, t)
+			return v
+		case t.IsFloat():
+			v = toflt(v)
+			v = truncfltlit(v, t)
+			return v
+		case t.IsComplex():
+			v = tocplx(v)
+			v = trunccmplxlit(v, t)
+			return v
+		}
+	}
+
+	return constant.MakeUnknown()
+}
+
+func tocplx(v constant.Value) constant.Value {
+	return constant.ToComplex(v)
+}
+
+func toflt(v constant.Value) constant.Value {
+	if v.Kind() == constant.Complex {
+		if constant.Sign(constant.Imag(v)) != 0 {
+			base.Errorf("constant %v truncated to real", v)
+		}
+		v = constant.Real(v)
+	}
+
+	return constant.ToFloat(v)
+}
+
+func toint(v constant.Value) constant.Value {
+	if v.Kind() == constant.Complex {
+		if constant.Sign(constant.Imag(v)) != 0 {
+			base.Errorf("constant %v truncated to integer", v)
+		}
+		v = constant.Real(v)
+	}
+
+	if v := constant.ToInt(v); v.Kind() == constant.Int {
+		return v
+	}
+
+	// The value of v cannot be represented as an integer;
+	// so we need to print an error message.
+	// Unfortunately some float values cannot be
+	// reasonably formatted for inclusion in an error
+	// message (example: 1 + 1e-100), so first we try to
+	// format the float; if the truncation resulted in
+	// something that looks like an integer we omit the
+	// value from the error message.
+	// (See issue #11371).
+	f := ir.BigFloat(v)
+	if f.MantExp(nil) > 2*ir.ConstPrec {
+		base.Errorf("integer too large")
+	} else {
+		var t big.Float
+		t.Parse(fmt.Sprint(v), 0)
+		if t.IsInt() {
+			base.Errorf("constant truncated to integer")
+		} else {
+			base.Errorf("constant %v truncated to integer", v)
+		}
+	}
+
+	// Prevent follow-on errors.
+	// TODO(mdempsky): Use constant.MakeUnknown() instead.
+	return constant.MakeInt64(1)
+}
+
+// overflow reports whether constant value v is too large
+// to represent with type t, and emits an error message if so.
+func overflow(v constant.Value, t *types.Type) bool {
+	// v has already been converted
+	// to appropriate form for t.
+	if t.IsUntyped() {
+		return false
+	}
+	if v.Kind() == constant.Int && constant.BitLen(v) > ir.ConstPrec {
+		base.Errorf("integer too large")
+		return true
+	}
+	if ir.ConstOverflow(v, t) {
+		base.Errorf("constant %v overflows %v", types.FmtConst(v, false), t)
+		return true
+	}
+	return false
+}
+
+func tostr(v constant.Value) constant.Value {
+	if v.Kind() == constant.Int {
+		r := unicode.ReplacementChar
+		if x, ok := constant.Uint64Val(v); ok && x <= unicode.MaxRune {
+			r = rune(x)
+		}
+		v = constant.MakeString(string(r))
+	}
+	return v
+}
+
+var tokenForOp = [...]token.Token{
+	ir.OPLUS:   token.ADD,
+	ir.ONEG:    token.SUB,
+	ir.ONOT:    token.NOT,
+	ir.OBITNOT: token.XOR,
+
+	ir.OADD:    token.ADD,
+	ir.OSUB:    token.SUB,
+	ir.OMUL:    token.MUL,
+	ir.ODIV:    token.QUO,
+	ir.OMOD:    token.REM,
+	ir.OOR:     token.OR,
+	ir.OXOR:    token.XOR,
+	ir.OAND:    token.AND,
+	ir.OANDNOT: token.AND_NOT,
+	ir.OOROR:   token.LOR,
+	ir.OANDAND: token.LAND,
+
+	ir.OEQ: token.EQL,
+	ir.ONE: token.NEQ,
+	ir.OLT: token.LSS,
+	ir.OLE: token.LEQ,
+	ir.OGT: token.GTR,
+	ir.OGE: token.GEQ,
+
+	ir.OLSH: token.SHL,
+	ir.ORSH: token.SHR,
+}
+
+// EvalConst returns a constant-evaluated expression equivalent to n.
+// If n is not a constant, EvalConst returns n.
+// Otherwise, EvalConst returns a new OLITERAL with the same value as n,
+// and with .Orig pointing back to n.
+func EvalConst(n ir.Node) ir.Node {
+	// Pick off just the opcodes that can be constant evaluated.
+	switch n.Op() {
+	case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT:
+		n := n.(*ir.UnaryExpr)
+		nl := n.X
+		if nl.Op() == ir.OLITERAL {
+			var prec uint
+			if n.Type().IsUnsigned() {
+				prec = uint(n.Type().Size() * 8)
+			}
+			return OrigConst(n, constant.UnaryOp(tokenForOp[n.Op()], nl.Val(), prec))
+		}
+
+	case ir.OADD, ir.OSUB, ir.OMUL, ir.ODIV, ir.OMOD, ir.OOR, ir.OXOR, ir.OAND, ir.OANDNOT:
+		n := n.(*ir.BinaryExpr)
+		nl, nr := n.X, n.Y
+		if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
+			rval := nr.Val()
+
+			// check for divisor underflow in complex division (see issue 20227)
+			if n.Op() == ir.ODIV && n.Type().IsComplex() && constant.Sign(square(constant.Real(rval))) == 0 && constant.Sign(square(constant.Imag(rval))) == 0 {
+				base.Errorf("complex division by zero")
+				n.SetType(nil)
+				return n
+			}
+			if (n.Op() == ir.ODIV || n.Op() == ir.OMOD) && constant.Sign(rval) == 0 {
+				base.Errorf("division by zero")
+				n.SetType(nil)
+				return n
+			}
+
+			tok := tokenForOp[n.Op()]
+			if n.Op() == ir.ODIV && n.Type().IsInteger() {
+				tok = token.QUO_ASSIGN // integer division
+			}
+			return OrigConst(n, constant.BinaryOp(nl.Val(), tok, rval))
+		}
+
+	case ir.OOROR, ir.OANDAND:
+		n := n.(*ir.LogicalExpr)
+		nl, nr := n.X, n.Y
+		if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
+			return OrigConst(n, constant.BinaryOp(nl.Val(), tokenForOp[n.Op()], nr.Val()))
+		}
+
+	case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
+		n := n.(*ir.BinaryExpr)
+		nl, nr := n.X, n.Y
+		if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
+			return OrigBool(n, constant.Compare(nl.Val(), tokenForOp[n.Op()], nr.Val()))
+		}
+
+	case ir.OLSH, ir.ORSH:
+		n := n.(*ir.BinaryExpr)
+		nl, nr := n.X, n.Y
+		if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
+			// shiftBound from go/types; "so we can express smallestFloat64" (see issue #44057)
+			const shiftBound = 1023 - 1 + 52
+			s, ok := constant.Uint64Val(nr.Val())
+			if !ok || s > shiftBound {
+				base.Errorf("invalid shift count %v", nr)
+				n.SetType(nil)
+				break
+			}
+			return OrigConst(n, constant.Shift(toint(nl.Val()), tokenForOp[n.Op()], uint(s)))
+		}
+
+	case ir.OCONV, ir.ORUNESTR:
+		n := n.(*ir.ConvExpr)
+		nl := n.X
+		if ir.OKForConst[n.Type().Kind()] && nl.Op() == ir.OLITERAL {
+			return OrigConst(n, convertVal(nl.Val(), n.Type(), true))
+		}
+
+	case ir.OCONVNOP:
+		n := n.(*ir.ConvExpr)
+		nl := n.X
+		if ir.OKForConst[n.Type().Kind()] && nl.Op() == ir.OLITERAL {
+			// set so n.Orig gets OCONV instead of OCONVNOP
+			n.SetOp(ir.OCONV)
+			return OrigConst(n, nl.Val())
+		}
+
+	case ir.OADDSTR:
+		// Merge adjacent constants in the argument list.
+		n := n.(*ir.AddStringExpr)
+		s := n.List
+		need := 0
+		for i := 0; i < len(s); i++ {
+			if i == 0 || !ir.IsConst(s[i-1], constant.String) || !ir.IsConst(s[i], constant.String) {
+				// Can't merge s[i] into s[i-1]; need a slot in the list.
+				need++
+			}
+		}
+		if need == len(s) {
+			return n
+		}
+		if need == 1 {
+			var strs []string
+			for _, c := range s {
+				strs = append(strs, ir.StringVal(c))
+			}
+			return OrigConst(n, constant.MakeString(strings.Join(strs, "")))
+		}
+		newList := make([]ir.Node, 0, need)
+		for i := 0; i < len(s); i++ {
+			if ir.IsConst(s[i], constant.String) && i+1 < len(s) && ir.IsConst(s[i+1], constant.String) {
+				// merge from i up to but not including i2
+				var strs []string
+				i2 := i
+				for i2 < len(s) && ir.IsConst(s[i2], constant.String) {
+					strs = append(strs, ir.StringVal(s[i2]))
+					i2++
+				}
+
+				nl := ir.Copy(n).(*ir.AddStringExpr)
+				nl.List = s[i:i2]
+				newList = append(newList, OrigConst(nl, constant.MakeString(strings.Join(strs, ""))))
+				i = i2 - 1
+			} else {
+				newList = append(newList, s[i])
+			}
+		}
+
+		nn := ir.Copy(n).(*ir.AddStringExpr)
+		nn.List = newList
+		return nn
+
+	case ir.OCAP, ir.OLEN:
+		n := n.(*ir.UnaryExpr)
+		nl := n.X
+		switch nl.Type().Kind() {
+		case types.TSTRING:
+			if ir.IsConst(nl, constant.String) {
+				return OrigInt(n, int64(len(ir.StringVal(nl))))
+			}
+		case types.TARRAY:
+			if !anyCallOrChan(nl) {
+				return OrigInt(n, nl.Type().NumElem())
+			}
+		}
+
+	case ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
+		n := n.(*ir.UnaryExpr)
+		return OrigInt(n, evalunsafe(n))
+
+	case ir.OREAL:
+		n := n.(*ir.UnaryExpr)
+		nl := n.X
+		if nl.Op() == ir.OLITERAL {
+			return OrigConst(n, constant.Real(nl.Val()))
+		}
+
+	case ir.OIMAG:
+		n := n.(*ir.UnaryExpr)
+		nl := n.X
+		if nl.Op() == ir.OLITERAL {
+			return OrigConst(n, constant.Imag(nl.Val()))
+		}
+
+	case ir.OCOMPLEX:
+		n := n.(*ir.BinaryExpr)
+		nl, nr := n.X, n.Y
+		if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
+			return OrigConst(n, makeComplex(nl.Val(), nr.Val()))
+		}
+	}
+
+	return n
+}
+
+func makeFloat64(f float64) constant.Value {
+	if math.IsInf(f, 0) {
+		base.Fatalf("infinity is not a valid constant")
+	}
+	return constant.MakeFloat64(f)
+}
+
+func makeComplex(real, imag constant.Value) constant.Value {
+	return constant.BinaryOp(constant.ToFloat(real), token.ADD, constant.MakeImag(constant.ToFloat(imag)))
+}
+
+func square(x constant.Value) constant.Value {
+	return constant.BinaryOp(x, token.MUL, x)
+}
+
+// For matching historical "constant OP overflow" error messages.
+// TODO(mdempsky): Replace with error messages like go/types uses.
+var overflowNames = [...]string{
+	ir.OADD:    "addition",
+	ir.OSUB:    "subtraction",
+	ir.OMUL:    "multiplication",
+	ir.OLSH:    "shift",
+	ir.OXOR:    "bitwise XOR",
+	ir.OBITNOT: "bitwise complement",
+}
+
+// OrigConst returns an OLITERAL with orig n and value v.
+func OrigConst(n ir.Node, v constant.Value) ir.Node {
+	lno := ir.SetPos(n)
+	v = convertVal(v, n.Type(), false)
+	base.Pos = lno
+
+	switch v.Kind() {
+	case constant.Int:
+		if constant.BitLen(v) <= ir.ConstPrec {
+			break
+		}
+		fallthrough
+	case constant.Unknown:
+		what := overflowNames[n.Op()]
+		if what == "" {
+			base.Fatalf("unexpected overflow: %v", n.Op())
+		}
+		base.ErrorfAt(n.Pos(), "constant %v overflow", what)
+		n.SetType(nil)
+		return n
+	}
+
+	return ir.NewConstExpr(v, n)
+}
+
+func OrigBool(n ir.Node, v bool) ir.Node {
+	return OrigConst(n, constant.MakeBool(v))
+}
+
+func OrigInt(n ir.Node, v int64) ir.Node {
+	return OrigConst(n, constant.MakeInt64(v))
+}
+
+// DefaultLit on both nodes simultaneously;
+// if they're both ideal going in they better
+// get the same type going out.
+// force means must assign concrete (non-ideal) type.
+// The results of defaultlit2 MUST be assigned back to l and r, e.g.
+// 	n.Left, n.Right = defaultlit2(n.Left, n.Right, force)
+func defaultlit2(l ir.Node, r ir.Node, force bool) (ir.Node, ir.Node) {
+	if l.Type() == nil || r.Type() == nil {
+		return l, r
+	}
+
+	if !l.Type().IsInterface() && !r.Type().IsInterface() {
+		// Can't mix bool with non-bool, string with non-string.
+		if l.Type().IsBoolean() != r.Type().IsBoolean() {
+			return l, r
+		}
+		if l.Type().IsString() != r.Type().IsString() {
+			return l, r
+		}
+	}
+
+	if !l.Type().IsUntyped() {
+		r = convlit(r, l.Type())
+		return l, r
+	}
+
+	if !r.Type().IsUntyped() {
+		l = convlit(l, r.Type())
+		return l, r
+	}
+
+	if !force {
+		return l, r
+	}
+
+	// Can't mix nil with anything untyped.
+	if ir.IsNil(l) || ir.IsNil(r) {
+		return l, r
+	}
+	t := defaultType(mixUntyped(l.Type(), r.Type()))
+	l = convlit(l, t)
+	r = convlit(r, t)
+	return l, r
+}
+
+func mixUntyped(t1, t2 *types.Type) *types.Type {
+	if t1 == t2 {
+		return t1
+	}
+
+	rank := func(t *types.Type) int {
+		switch t {
+		case types.UntypedInt:
+			return 0
+		case types.UntypedRune:
+			return 1
+		case types.UntypedFloat:
+			return 2
+		case types.UntypedComplex:
+			return 3
+		}
+		base.Fatalf("bad type %v", t)
+		panic("unreachable")
+	}
+
+	if rank(t2) > rank(t1) {
+		return t2
+	}
+	return t1
+}
+
+func defaultType(t *types.Type) *types.Type {
+	if !t.IsUntyped() || t.Kind() == types.TNIL {
+		return t
+	}
+
+	switch t {
+	case types.UntypedBool:
+		return types.Types[types.TBOOL]
+	case types.UntypedString:
+		return types.Types[types.TSTRING]
+	case types.UntypedInt:
+		return types.Types[types.TINT]
+	case types.UntypedRune:
+		return types.RuneType
+	case types.UntypedFloat:
+		return types.Types[types.TFLOAT64]
+	case types.UntypedComplex:
+		return types.Types[types.TCOMPLEX128]
+	}
+
+	base.Fatalf("bad type %v", t)
+	return nil
+}
+
+// IndexConst checks if Node n contains a constant expression
+// representable as a non-negative int and returns its value.
+// If n is not a constant expression, not representable as an
+// integer, or negative, it returns -1. If n is too large, it
+// returns -2.
+func IndexConst(n ir.Node) int64 {
+	if n.Op() != ir.OLITERAL {
+		return -1
+	}
+	if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
+		return -1
+	}
+
+	v := toint(n.Val())
+	if v.Kind() != constant.Int || constant.Sign(v) < 0 {
+		return -1
+	}
+	if ir.ConstOverflow(v, types.Types[types.TINT]) {
+		return -2
+	}
+	return ir.IntVal(types.Types[types.TINT], v)
+}
+
+// anyCallOrChan reports whether n contains any calls or channel operations.
+func anyCallOrChan(n ir.Node) bool {
+	return ir.Any(n, func(n ir.Node) bool {
+		switch n.Op() {
+		case ir.OAPPEND,
+			ir.OCALL,
+			ir.OCALLFUNC,
+			ir.OCALLINTER,
+			ir.OCALLMETH,
+			ir.OCAP,
+			ir.OCLOSE,
+			ir.OCOMPLEX,
+			ir.OCOPY,
+			ir.ODELETE,
+			ir.OIMAG,
+			ir.OLEN,
+			ir.OMAKE,
+			ir.ONEW,
+			ir.OPANIC,
+			ir.OPRINT,
+			ir.OPRINTN,
+			ir.OREAL,
+			ir.ORECOVER,
+			ir.ORECV,
+			ir.OUNSAFEADD,
+			ir.OUNSAFESLICE:
+			return true
+		}
+		return false
+	})
+}
+
+// A constSet represents a set of Go constant expressions.
+type constSet struct {
+	m map[constSetKey]src.XPos
+}
+
+type constSetKey struct {
+	typ *types.Type
+	val interface{}
+}
+
+// add adds constant expression n to s. If a constant expression of
+// equal value and identical type has already been added, then add
+// reports an error about the duplicate value.
+//
+// pos provides position information for where expression n occurred
+// (in case n does not have its own position information). what and
+// where are used in the error message.
+//
+// n must not be an untyped constant.
+func (s *constSet) add(pos src.XPos, n ir.Node, what, where string) {
+	if conv := n; conv.Op() == ir.OCONVIFACE {
+		conv := conv.(*ir.ConvExpr)
+		if conv.Implicit() {
+			n = conv.X
+		}
+	}
+
+	if !ir.IsConstNode(n) || n.Type() == nil {
+		return
+	}
+	if n.Type().IsUntyped() {
+		base.Fatalf("%v is untyped", n)
+	}
+
+	// Consts are only duplicates if they have the same value and
+	// identical types.
+	//
+	// In general, we have to use types.Identical to test type
+	// identity, because == gives false negatives for anonymous
+	// types and the byte/uint8 and rune/int32 builtin type
+	// aliases.  However, this is not a problem here, because
+	// constant expressions are always untyped or have a named
+	// type, and we explicitly handle the builtin type aliases
+	// below.
+	//
+	// This approach may need to be revisited though if we fix
+	// #21866 by treating all type aliases like byte/uint8 and
+	// rune/int32.
+
+	typ := n.Type()
+	switch typ {
+	case types.ByteType:
+		typ = types.Types[types.TUINT8]
+	case types.RuneType:
+		typ = types.Types[types.TINT32]
+	}
+	k := constSetKey{typ, ir.ConstValue(n)}
+
+	if ir.HasUniquePos(n) {
+		pos = n.Pos()
+	}
+
+	if s.m == nil {
+		s.m = make(map[constSetKey]src.XPos)
+	}
+
+	if prevPos, isDup := s.m[k]; isDup {
+		base.ErrorfAt(pos, "duplicate %s %s in %s\n\tprevious %s at %v",
+			what, nodeAndVal(n), where,
+			what, base.FmtPos(prevPos))
+	} else {
+		s.m[k] = pos
+	}
+}
+
+// nodeAndVal reports both an expression and its constant value, if
+// the latter is non-obvious.
+//
+// TODO(mdempsky): This could probably be a fmt.go flag.
+func nodeAndVal(n ir.Node) string {
+	show := fmt.Sprint(n)
+	val := ir.ConstValue(n)
+	if s := fmt.Sprintf("%#v", val); show != s {
+		show += " (value " + s + ")"
+	}
+	return show
+}
+
+// evalunsafe evaluates a package unsafe operation and returns the result.
+func evalunsafe(n ir.Node) int64 {
+	switch n.Op() {
+	case ir.OALIGNOF, ir.OSIZEOF:
+		n := n.(*ir.UnaryExpr)
+		n.X = Expr(n.X)
+		n.X = DefaultLit(n.X, nil)
+		tr := n.X.Type()
+		if tr == nil {
+			return 0
+		}
+		types.CalcSize(tr)
+		if n.Op() == ir.OALIGNOF {
+			return int64(tr.Align)
+		}
+		return tr.Width
+
+	case ir.OOFFSETOF:
+		// must be a selector.
+		n := n.(*ir.UnaryExpr)
+		if n.X.Op() != ir.OXDOT {
+			base.Errorf("invalid expression %v", n)
+			return 0
+		}
+		sel := n.X.(*ir.SelectorExpr)
+
+		// Remember base of selector to find it back after dot insertion.
+		// Since r->left may be mutated by typechecking, check it explicitly
+		// first to track it correctly.
+		sel.X = Expr(sel.X)
+		sbase := sel.X
+
+		tsel := Expr(sel)
+		n.X = tsel
+		if tsel.Type() == nil {
+			return 0
+		}
+		switch tsel.Op() {
+		case ir.ODOT, ir.ODOTPTR:
+			break
+		case ir.OCALLPART:
+			base.Errorf("invalid expression %v: argument is a method value", n)
+			return 0
+		default:
+			base.Errorf("invalid expression %v", n)
+			return 0
+		}
+
+		// Sum offsets for dots until we reach sbase.
+		var v int64
+		var next ir.Node
+		for r := tsel; r != sbase; r = next {
+			switch r.Op() {
+			case ir.ODOTPTR:
+				// For Offsetof(s.f), s may itself be a pointer,
+				// but accessing f must not otherwise involve
+				// indirection via embedded pointer types.
+				r := r.(*ir.SelectorExpr)
+				if r.X != sbase {
+					base.Errorf("invalid expression %v: selector implies indirection of embedded %v", n, r.X)
+					return 0
+				}
+				fallthrough
+			case ir.ODOT:
+				r := r.(*ir.SelectorExpr)
+				v += r.Offset()
+				next = r.X
+			default:
+				ir.Dump("unsafenmagic", tsel)
+				base.Fatalf("impossible %v node after dot insertion", r.Op())
+			}
+		}
+		return v
+	}
+
+	base.Fatalf("unexpected op %v", n.Op())
+	return 0
+}
diff --git a/src/cmd/compile/internal/typecheck/dcl.go b/src/cmd/compile/internal/typecheck/dcl.go
new file mode 100644
index 0000000..5b771e3
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/dcl.go
@@ -0,0 +1,484 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typecheck
+
+import (
+	"fmt"
+	"strconv"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+var DeclContext ir.Class = ir.PEXTERN // PEXTERN/PAUTO
+
+func DeclFunc(sym *types.Sym, tfn ir.Ntype) *ir.Func {
+	if tfn.Op() != ir.OTFUNC {
+		base.Fatalf("expected OTFUNC node, got %v", tfn)
+	}
+
+	fn := ir.NewFunc(base.Pos)
+	fn.Nname = ir.NewNameAt(base.Pos, sym)
+	fn.Nname.Func = fn
+	fn.Nname.Defn = fn
+	fn.Nname.Ntype = tfn
+	ir.MarkFunc(fn.Nname)
+	StartFuncBody(fn)
+	fn.Nname.Ntype = typecheckNtype(fn.Nname.Ntype)
+	return fn
+}
+
+// Declare records that Node n declares symbol n.Sym in the specified
+// declaration context.
+func Declare(n *ir.Name, ctxt ir.Class) {
+	if ir.IsBlank(n) {
+		return
+	}
+
+	s := n.Sym()
+
+	// kludgy: TypecheckAllowed means we're past parsing. Eg reflectdata.methodWrapper may declare out of package names later.
+	if !inimport && !TypecheckAllowed && s.Pkg != types.LocalPkg {
+		base.ErrorfAt(n.Pos(), "cannot declare name %v", s)
+	}
+
+	if ctxt == ir.PEXTERN {
+		if s.Name == "init" {
+			base.ErrorfAt(n.Pos(), "cannot declare init - must be func")
+		}
+		if s.Name == "main" && s.Pkg.Name == "main" {
+			base.ErrorfAt(n.Pos(), "cannot declare main - must be func")
+		}
+		Target.Externs = append(Target.Externs, n)
+	} else {
+		if ir.CurFunc == nil && ctxt == ir.PAUTO {
+			base.Pos = n.Pos()
+			base.Fatalf("automatic outside function")
+		}
+		if ir.CurFunc != nil && ctxt != ir.PFUNC && n.Op() == ir.ONAME {
+			ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n)
+		}
+		types.Pushdcl(s)
+		n.Curfn = ir.CurFunc
+	}
+
+	if ctxt == ir.PAUTO {
+		n.SetFrameOffset(0)
+	}
+
+	if s.Block == types.Block {
+		// functype will print errors about duplicate function arguments.
+		// Don't repeat the error here.
+		if ctxt != ir.PPARAM && ctxt != ir.PPARAMOUT {
+			Redeclared(n.Pos(), s, "in this block")
+		}
+	}
+
+	s.Block = types.Block
+	s.Lastlineno = base.Pos
+	s.Def = n
+	n.Class = ctxt
+	if ctxt == ir.PFUNC {
+		n.Sym().SetFunc(true)
+	}
+
+	autoexport(n, ctxt)
+}
+
+// Export marks n for export (or reexport).
+func Export(n *ir.Name) {
+	if n.Sym().OnExportList() {
+		return
+	}
+	n.Sym().SetOnExportList(true)
+
+	if base.Flag.E != 0 {
+		fmt.Printf("export symbol %v\n", n.Sym())
+	}
+
+	Target.Exports = append(Target.Exports, n)
+}
+
+// Redeclared emits a diagnostic about symbol s being redeclared at pos.
+func Redeclared(pos src.XPos, s *types.Sym, where string) {
+	if !s.Lastlineno.IsKnown() {
+		var pkgName *ir.PkgName
+		if s.Def == nil {
+			for id, pkg := range DotImportRefs {
+				if id.Sym().Name == s.Name {
+					pkgName = pkg
+					break
+				}
+			}
+		} else {
+			pkgName = DotImportRefs[s.Def.(*ir.Ident)]
+		}
+		base.ErrorfAt(pos, "%v redeclared %s\n"+
+			"\t%v: previous declaration during import %q", s, where, base.FmtPos(pkgName.Pos()), pkgName.Pkg.Path)
+	} else {
+		prevPos := s.Lastlineno
+
+		// When an import and a declaration collide in separate files,
+		// present the import as the "redeclared", because the declaration
+		// is visible where the import is, but not vice versa.
+		// See issue 4510.
+		if s.Def == nil {
+			pos, prevPos = prevPos, pos
+		}
+
+		base.ErrorfAt(pos, "%v redeclared %s\n"+
+			"\t%v: previous declaration", s, where, base.FmtPos(prevPos))
+	}
+}
+
+// declare the function proper
+// and declare the arguments.
+// called in extern-declaration context
+// returns in auto-declaration context.
+func StartFuncBody(fn *ir.Func) {
+	// change the declaration context from extern to auto
+	funcStack = append(funcStack, funcStackEnt{ir.CurFunc, DeclContext})
+	ir.CurFunc = fn
+	DeclContext = ir.PAUTO
+
+	types.Markdcl()
+
+	if fn.Nname.Ntype != nil {
+		funcargs(fn.Nname.Ntype.(*ir.FuncType))
+	} else {
+		funcargs2(fn.Type())
+	}
+}
+
+// finish the body.
+// called in auto-declaration context.
+// returns in extern-declaration context.
+func FinishFuncBody() {
+	// change the declaration context from auto to previous context
+	types.Popdcl()
+	var e funcStackEnt
+	funcStack, e = funcStack[:len(funcStack)-1], funcStack[len(funcStack)-1]
+	ir.CurFunc, DeclContext = e.curfn, e.dclcontext
+}
+
+func CheckFuncStack() {
+	if len(funcStack) != 0 {
+		base.Fatalf("funcStack is non-empty: %v", len(funcStack))
+	}
+}
+
+// Add a method, declared as a function.
+// - msym is the method symbol
+// - t is function type (with receiver)
+// Returns a pointer to the existing or added Field; or nil if there's an error.
+func addmethod(n *ir.Func, msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
+	if msym == nil {
+		base.Fatalf("no method symbol")
+	}
+
+	// get parent type sym
+	rf := t.Recv() // ptr to this structure
+	if rf == nil {
+		base.Errorf("missing receiver")
+		return nil
+	}
+
+	mt := types.ReceiverBaseType(rf.Type)
+	if mt == nil || mt.Sym() == nil {
+		pa := rf.Type
+		t := pa
+		if t != nil && t.IsPtr() {
+			if t.Sym() != nil {
+				base.Errorf("invalid receiver type %v (%v is a pointer type)", pa, t)
+				return nil
+			}
+			t = t.Elem()
+		}
+
+		switch {
+		case t == nil || t.Broke():
+			// rely on typecheck having complained before
+		case t.Sym() == nil:
+			base.Errorf("invalid receiver type %v (%v is not a defined type)", pa, t)
+		case t.IsPtr():
+			base.Errorf("invalid receiver type %v (%v is a pointer type)", pa, t)
+		case t.IsInterface():
+			base.Errorf("invalid receiver type %v (%v is an interface type)", pa, t)
+		default:
+			// Should have picked off all the reasons above,
+			// but just in case, fall back to generic error.
+			base.Errorf("invalid receiver type %v (%L / %L)", pa, pa, t)
+		}
+		return nil
+	}
+
+	if local && mt.Sym().Pkg != types.LocalPkg {
+		base.Errorf("cannot define new methods on non-local type %v", mt)
+		return nil
+	}
+
+	if msym.IsBlank() {
+		return nil
+	}
+
+	if mt.IsStruct() {
+		for _, f := range mt.Fields().Slice() {
+			if f.Sym == msym {
+				base.Errorf("type %v has both field and method named %v", mt, msym)
+				f.SetBroke(true)
+				return nil
+			}
+		}
+	}
+
+	for _, f := range mt.Methods().Slice() {
+		if msym.Name != f.Sym.Name {
+			continue
+		}
+		// types.Identical only checks that incoming and result parameters match,
+		// so explicitly check that the receiver parameters match too.
+		if !types.Identical(t, f.Type) || !types.Identical(t.Recv().Type, f.Type.Recv().Type) {
+			base.Errorf("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
+		}
+		return f
+	}
+
+	f := types.NewField(base.Pos, msym, t)
+	f.Nname = n.Nname
+	f.SetNointerface(nointerface)
+
+	mt.Methods().Append(f)
+	return f
+}
+
+func autoexport(n *ir.Name, ctxt ir.Class) {
+	if n.Sym().Pkg != types.LocalPkg {
+		return
+	}
+	if (ctxt != ir.PEXTERN && ctxt != ir.PFUNC) || DeclContext != ir.PEXTERN {
+		return
+	}
+	if n.Type() != nil && n.Type().IsKind(types.TFUNC) && ir.IsMethod(n) {
+		return
+	}
+
+	if types.IsExported(n.Sym().Name) || n.Sym().Name == "init" {
+		Export(n)
+	}
+	if base.Flag.AsmHdr != "" && !n.Sym().Asm() {
+		n.Sym().SetAsm(true)
+		Target.Asms = append(Target.Asms, n)
+	}
+}
+
+// checkdupfields emits errors for duplicately named fields or methods in
+// a list of struct or interface types.
+func checkdupfields(what string, fss ...[]*types.Field) {
+	seen := make(map[*types.Sym]bool)
+	for _, fs := range fss {
+		for _, f := range fs {
+			if f.Sym == nil || f.Sym.IsBlank() {
+				continue
+			}
+			if seen[f.Sym] {
+				base.ErrorfAt(f.Pos, "duplicate %s %s", what, f.Sym.Name)
+				continue
+			}
+			seen[f.Sym] = true
+		}
+	}
+}
+
+// structs, functions, and methods.
+// they don't belong here, but where do they belong?
+func checkembeddedtype(t *types.Type) {
+	if t == nil {
+		return
+	}
+
+	if t.Sym() == nil && t.IsPtr() {
+		t = t.Elem()
+		if t.IsInterface() {
+			base.Errorf("embedded type cannot be a pointer to interface")
+		}
+	}
+
+	if t.IsPtr() || t.IsUnsafePtr() {
+		base.Errorf("embedded type cannot be a pointer")
+	} else if t.Kind() == types.TFORW && !t.ForwardType().Embedlineno.IsKnown() {
+		t.ForwardType().Embedlineno = base.Pos
+	}
+}
+
+// TODO(mdempsky): Move to package types.
+func FakeRecv() *types.Field {
+	return types.NewField(src.NoXPos, nil, types.FakeRecvType())
+}
+
+var fakeRecvField = FakeRecv
+
+var funcStack []funcStackEnt // stack of previous values of ir.CurFunc/DeclContext
+
+type funcStackEnt struct {
+	curfn      *ir.Func
+	dclcontext ir.Class
+}
+
+func funcarg(n *ir.Field, ctxt ir.Class) {
+	if n.Sym == nil {
+		return
+	}
+
+	name := ir.NewNameAt(n.Pos, n.Sym)
+	n.Decl = name
+	name.Ntype = n.Ntype
+	Declare(name, ctxt)
+}
+
+func funcarg2(f *types.Field, ctxt ir.Class) {
+	if f.Sym == nil {
+		return
+	}
+	n := ir.NewNameAt(f.Pos, f.Sym)
+	f.Nname = n
+	n.SetType(f.Type)
+	Declare(n, ctxt)
+}
+
+func funcargs(nt *ir.FuncType) {
+	if nt.Op() != ir.OTFUNC {
+		base.Fatalf("funcargs %v", nt.Op())
+	}
+
+	// declare the receiver and in arguments.
+	if nt.Recv != nil {
+		funcarg(nt.Recv, ir.PPARAM)
+	}
+	for _, n := range nt.Params {
+		funcarg(n, ir.PPARAM)
+	}
+
+	// declare the out arguments.
+	gen := len(nt.Params)
+	for _, n := range nt.Results {
+		if n.Sym == nil {
+			// Name so that escape analysis can track it. ~r stands for 'result'.
+			n.Sym = LookupNum("~r", gen)
+			gen++
+		}
+		if n.Sym.IsBlank() {
+			// Give it a name so we can assign to it during return. ~b stands for 'blank'.
+			// The name must be different from ~r above because if you have
+			//	func f() (_ int)
+			//	func g() int
+			// f is allowed to use a plain 'return' with no arguments, while g is not.
+			// So the two cases must be distinguished.
+			n.Sym = LookupNum("~b", gen)
+			gen++
+		}
+
+		funcarg(n, ir.PPARAMOUT)
+	}
+}
+
+// Same as funcargs, except run over an already constructed TFUNC.
+// This happens during import, where the hidden_fndcl rule has
+// used functype directly to parse the function's type.
+func funcargs2(t *types.Type) {
+	if t.Kind() != types.TFUNC {
+		base.Fatalf("funcargs2 %v", t)
+	}
+
+	for _, f := range t.Recvs().Fields().Slice() {
+		funcarg2(f, ir.PPARAM)
+	}
+	for _, f := range t.Params().Fields().Slice() {
+		funcarg2(f, ir.PPARAM)
+	}
+	for _, f := range t.Results().Fields().Slice() {
+		funcarg2(f, ir.PPARAMOUT)
+	}
+}
+
+func Temp(t *types.Type) *ir.Name {
+	return TempAt(base.Pos, ir.CurFunc, t)
+}
+
+// make a new Node off the books
+func TempAt(pos src.XPos, curfn *ir.Func, t *types.Type) *ir.Name {
+	if curfn == nil {
+		base.Fatalf("no curfn for TempAt")
+	}
+	if curfn.Op() == ir.OCLOSURE {
+		ir.Dump("TempAt", curfn)
+		base.Fatalf("adding TempAt to wrong closure function")
+	}
+	if t == nil {
+		base.Fatalf("TempAt called with nil type")
+	}
+	if t.Kind() == types.TFUNC && t.Recv() != nil {
+		base.Fatalf("misuse of method type: %v", t)
+	}
+
+	s := &types.Sym{
+		Name: autotmpname(len(curfn.Dcl)),
+		Pkg:  types.LocalPkg,
+	}
+	n := ir.NewNameAt(pos, s)
+	s.Def = n
+	n.SetType(t)
+	n.Class = ir.PAUTO
+	n.SetEsc(ir.EscNever)
+	n.Curfn = curfn
+	n.SetUsed(true)
+	n.SetAutoTemp(true)
+	curfn.Dcl = append(curfn.Dcl, n)
+
+	types.CalcSize(t)
+
+	return n
+}
+
+// autotmpname returns the name for an autotmp variable numbered n.
+func autotmpname(n int) string {
+	// Give each tmp a different name so that they can be registerized.
+	// Add a preceding . to avoid clashing with legal names.
+	const prefix = ".autotmp_"
+	// Start with a buffer big enough to hold a large n.
+	b := []byte(prefix + "      ")[:len(prefix)]
+	b = strconv.AppendInt(b, int64(n), 10)
+	return types.InternString(b)
+}
+
+// f is method type, with receiver.
+// return function type, receiver as first argument (or not).
+func NewMethodType(sig *types.Type, recv *types.Type) *types.Type {
+	nrecvs := 0
+	if recv != nil {
+		nrecvs++
+	}
+
+	// TODO(mdempsky): Move this function to types.
+	// TODO(mdempsky): Preserve positions, names, and package from sig+recv.
+
+	params := make([]*types.Field, nrecvs+sig.Params().Fields().Len())
+	if recv != nil {
+		params[0] = types.NewField(base.Pos, nil, recv)
+	}
+	for i, param := range sig.Params().Fields().Slice() {
+		d := types.NewField(base.Pos, nil, param.Type)
+		d.SetIsDDD(param.IsDDD())
+		params[nrecvs+i] = d
+	}
+
+	results := make([]*types.Field, sig.Results().Fields().Len())
+	for i, t := range sig.Results().Fields().Slice() {
+		results[i] = types.NewField(base.Pos, nil, t.Type)
+	}
+
+	return types.NewSignature(types.LocalPkg, nil, nil, params, results)
+}
diff --git a/src/cmd/compile/internal/typecheck/export.go b/src/cmd/compile/internal/typecheck/export.go
new file mode 100644
index 0000000..63d0a1e
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/export.go
@@ -0,0 +1,74 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typecheck
+
+import (
+	"go/constant"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// importalias declares symbol s as an imported type alias with type t.
+// ipkg is the package being imported
+func importalias(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) *ir.Name {
+	return importobj(ipkg, pos, s, ir.OTYPE, ir.PEXTERN, t)
+}
+
+// importconst declares symbol s as an imported constant with type t and value val.
+// ipkg is the package being imported
+func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val constant.Value) *ir.Name {
+	n := importobj(ipkg, pos, s, ir.OLITERAL, ir.PEXTERN, t)
+	n.SetVal(val)
+	return n
+}
+
+// importfunc declares symbol s as an imported function with type t.
+// ipkg is the package being imported
+func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) *ir.Name {
+	n := importobj(ipkg, pos, s, ir.ONAME, ir.PFUNC, t)
+	n.Func = ir.NewFunc(pos)
+	n.Func.Nname = n
+	return n
+}
+
+// importobj declares symbol s as an imported object representable by op.
+// ipkg is the package being imported
+func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op ir.Op, ctxt ir.Class, t *types.Type) *ir.Name {
+	n := importsym(ipkg, pos, s, op, ctxt)
+	n.SetType(t)
+	if ctxt == ir.PFUNC {
+		n.Sym().SetFunc(true)
+	}
+	return n
+}
+
+func importsym(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op ir.Op, ctxt ir.Class) *ir.Name {
+	if n := s.PkgDef(); n != nil {
+		base.Fatalf("importsym of symbol that already exists: %v", n)
+	}
+
+	n := ir.NewDeclNameAt(pos, op, s)
+	n.Class = ctxt // TODO(mdempsky): Move this into NewDeclNameAt too?
+	s.SetPkgDef(n)
+	return n
+}
+
+// importtype returns the named type declared by symbol s.
+// If no such type has been declared yet, a forward declaration is returned.
+// ipkg is the package being imported
+func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *ir.Name {
+	n := importsym(ipkg, pos, s, ir.OTYPE, ir.PEXTERN)
+	n.SetType(types.NewNamed(n))
+	return n
+}
+
+// importvar declares symbol s as an imported variable with type t.
+// ipkg is the package being imported
+func importvar(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) *ir.Name {
+	return importobj(ipkg, pos, s, ir.ONAME, ir.PEXTERN, t)
+}
diff --git a/src/cmd/compile/internal/typecheck/expr.go b/src/cmd/compile/internal/typecheck/expr.go
new file mode 100644
index 0000000..24d141e
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/expr.go
@@ -0,0 +1,881 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typecheck
+
+import (
+	"fmt"
+	"go/constant"
+	"go/token"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+)
+
+// tcAddr typechecks an OADDR node.
+func tcAddr(n *ir.AddrExpr) ir.Node {
+	n.X = Expr(n.X)
+	if n.X.Type() == nil {
+		n.SetType(nil)
+		return n
+	}
+
+	switch n.X.Op() {
+	case ir.OARRAYLIT, ir.OMAPLIT, ir.OSLICELIT, ir.OSTRUCTLIT:
+		n.SetOp(ir.OPTRLIT)
+
+	default:
+		checklvalue(n.X, "take the address of")
+		r := ir.OuterValue(n.X)
+		if r.Op() == ir.ONAME {
+			r := r.(*ir.Name)
+			if ir.Orig(r) != r {
+				base.Fatalf("found non-orig name node %v", r) // TODO(mdempsky): What does this mean?
+			}
+		}
+		n.X = DefaultLit(n.X, nil)
+		if n.X.Type() == nil {
+			n.SetType(nil)
+			return n
+		}
+	}
+
+	n.SetType(types.NewPtr(n.X.Type()))
+	return n
+}
+
+func tcShift(n, l, r ir.Node) (ir.Node, ir.Node, *types.Type) {
+	if l.Type() == nil || r.Type() == nil {
+		return l, r, nil
+	}
+
+	r = DefaultLit(r, types.Types[types.TUINT])
+	t := r.Type()
+	if !t.IsInteger() {
+		base.Errorf("invalid operation: %v (shift count type %v, must be integer)", n, r.Type())
+		return l, r, nil
+	}
+	if t.IsSigned() && !types.AllowsGoVersion(curpkg(), 1, 13) {
+		base.ErrorfVers("go1.13", "invalid operation: %v (signed shift count type %v)", n, r.Type())
+		return l, r, nil
+	}
+	t = l.Type()
+	if t != nil && t.Kind() != types.TIDEAL && !t.IsInteger() {
+		base.Errorf("invalid operation: %v (shift of type %v)", n, t)
+		return l, r, nil
+	}
+
+	// no DefaultLit for left
+	// the outer context gives the type
+	t = l.Type()
+	if (l.Type() == types.UntypedFloat || l.Type() == types.UntypedComplex) && r.Op() == ir.OLITERAL {
+		t = types.UntypedInt
+	}
+	return l, r, t
+}
+
+func IsCmp(op ir.Op) bool {
+	return iscmp[op]
+}
+
+// tcArith typechecks operands of a binary arithmetic expression.
+// The result of tcArith MUST be assigned back to original operands,
+// t is the type of the expression, and should be set by the caller. e.g:
+//     n.X, n.Y, t = tcArith(n, op, n.X, n.Y)
+//     n.SetType(t)
+func tcArith(n ir.Node, op ir.Op, l, r ir.Node) (ir.Node, ir.Node, *types.Type) {
+	l, r = defaultlit2(l, r, false)
+	if l.Type() == nil || r.Type() == nil {
+		return l, r, nil
+	}
+	t := l.Type()
+	if t.Kind() == types.TIDEAL {
+		t = r.Type()
+	}
+	aop := ir.OXXX
+	if iscmp[n.Op()] && t.Kind() != types.TIDEAL && !types.Identical(l.Type(), r.Type()) {
+		// comparison is okay as long as one side is
+		// assignable to the other.  convert so they have
+		// the same type.
+		//
+		// 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().Kind() != types.TBLANK {
+			aop, _ = Assignop(l.Type(), r.Type())
+			if aop != ir.OXXX {
+				if r.Type().IsInterface() && !l.Type().IsInterface() && !types.IsComparable(l.Type()) {
+					base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type()))
+					return l, r, nil
+				}
+
+				types.CalcSize(l.Type())
+				if r.Type().IsInterface() == l.Type().IsInterface() || l.Type().Width >= 1<<16 {
+					l = ir.NewConvExpr(base.Pos, aop, r.Type(), l)
+					l.SetTypecheck(1)
+				}
+
+				t = r.Type()
+				converted = true
+			}
+		}
+
+		if !converted && l.Type().Kind() != types.TBLANK {
+			aop, _ = Assignop(r.Type(), l.Type())
+			if aop != ir.OXXX {
+				if l.Type().IsInterface() && !r.Type().IsInterface() && !types.IsComparable(r.Type()) {
+					base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type()))
+					return l, r, nil
+				}
+
+				types.CalcSize(r.Type())
+				if r.Type().IsInterface() == l.Type().IsInterface() || r.Type().Width >= 1<<16 {
+					r = ir.NewConvExpr(base.Pos, aop, l.Type(), r)
+					r.SetTypecheck(1)
+				}
+
+				t = l.Type()
+			}
+		}
+	}
+
+	if t.Kind() != types.TIDEAL && !types.Identical(l.Type(), r.Type()) {
+		l, r = defaultlit2(l, r, true)
+		if l.Type() == nil || r.Type() == nil {
+			return l, r, nil
+		}
+		if l.Type().IsInterface() == r.Type().IsInterface() || aop == 0 {
+			base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type(), r.Type())
+			return l, r, nil
+		}
+	}
+
+	if t.Kind() == types.TIDEAL {
+		t = mixUntyped(l.Type(), r.Type())
+	}
+	if dt := defaultType(t); !okfor[op][dt.Kind()] {
+		base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(t))
+		return l, r, nil
+	}
+
+	// okfor allows any array == array, map == map, func == func.
+	// restrict to slice/map/func == nil and nil == slice/map/func.
+	if l.Type().IsArray() && !types.IsComparable(l.Type()) {
+		base.Errorf("invalid operation: %v (%v cannot be compared)", n, l.Type())
+		return l, r, nil
+	}
+
+	if l.Type().IsSlice() && !ir.IsNil(l) && !ir.IsNil(r) {
+		base.Errorf("invalid operation: %v (slice can only be compared to nil)", n)
+		return l, r, nil
+	}
+
+	if l.Type().IsMap() && !ir.IsNil(l) && !ir.IsNil(r) {
+		base.Errorf("invalid operation: %v (map can only be compared to nil)", n)
+		return l, r, nil
+	}
+
+	if l.Type().Kind() == types.TFUNC && !ir.IsNil(l) && !ir.IsNil(r) {
+		base.Errorf("invalid operation: %v (func can only be compared to nil)", n)
+		return l, r, nil
+	}
+
+	if l.Type().IsStruct() {
+		if f := types.IncomparableField(l.Type()); f != nil {
+			base.Errorf("invalid operation: %v (struct containing %v cannot be compared)", n, f.Type)
+			return l, r, nil
+		}
+	}
+
+	if (op == ir.ODIV || op == ir.OMOD) && ir.IsConst(r, constant.Int) {
+		if constant.Sign(r.Val()) == 0 {
+			base.Errorf("division by zero")
+			return l, r, nil
+		}
+	}
+
+	return l, r, t
+}
+
+// The result of tcCompLit MUST be assigned back to n, e.g.
+// 	n.Left = tcCompLit(n.Left)
+func tcCompLit(n *ir.CompLitExpr) (res ir.Node) {
+	if base.EnableTrace && base.Flag.LowerT {
+		defer tracePrint("tcCompLit", n)(&res)
+	}
+
+	lno := base.Pos
+	defer func() {
+		base.Pos = lno
+	}()
+
+	if n.Ntype == nil {
+		base.ErrorfAt(n.Pos(), "missing type in composite literal")
+		n.SetType(nil)
+		return n
+	}
+
+	// Save original node (including n.Right)
+	n.SetOrig(ir.Copy(n))
+
+	ir.SetPos(n.Ntype)
+
+	// Need to handle [...]T arrays specially.
+	if array, ok := n.Ntype.(*ir.ArrayType); ok && array.Elem != nil && array.Len == nil {
+		array.Elem = typecheckNtype(array.Elem)
+		elemType := array.Elem.Type()
+		if elemType == nil {
+			n.SetType(nil)
+			return n
+		}
+		length := typecheckarraylit(elemType, -1, n.List, "array literal")
+		n.SetOp(ir.OARRAYLIT)
+		n.SetType(types.NewArray(elemType, length))
+		n.Ntype = nil
+		return n
+	}
+
+	n.Ntype = typecheckNtype(n.Ntype)
+	t := n.Ntype.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+	n.SetType(t)
+
+	switch t.Kind() {
+	default:
+		base.Errorf("invalid composite literal type %v", t)
+		n.SetType(nil)
+
+	case types.TARRAY:
+		typecheckarraylit(t.Elem(), t.NumElem(), n.List, "array literal")
+		n.SetOp(ir.OARRAYLIT)
+		n.Ntype = nil
+
+	case types.TSLICE:
+		length := typecheckarraylit(t.Elem(), -1, n.List, "slice literal")
+		n.SetOp(ir.OSLICELIT)
+		n.Ntype = nil
+		n.Len = length
+
+	case types.TMAP:
+		var cs constSet
+		for i3, l := range n.List {
+			ir.SetPos(l)
+			if l.Op() != ir.OKEY {
+				n.List[i3] = Expr(l)
+				base.Errorf("missing key in map literal")
+				continue
+			}
+			l := l.(*ir.KeyExpr)
+
+			r := l.Key
+			r = pushtype(r, t.Key())
+			r = Expr(r)
+			l.Key = AssignConv(r, t.Key(), "map key")
+			cs.add(base.Pos, l.Key, "key", "map literal")
+
+			r = l.Value
+			r = pushtype(r, t.Elem())
+			r = Expr(r)
+			l.Value = AssignConv(r, t.Elem(), "map value")
+		}
+
+		n.SetOp(ir.OMAPLIT)
+		n.Ntype = nil
+
+	case types.TSTRUCT:
+		// Need valid field offsets for Xoffset below.
+		types.CalcSize(t)
+
+		errored := false
+		if len(n.List) != 0 && nokeys(n.List) {
+			// simple list of variables
+			ls := n.List
+			for i, n1 := range ls {
+				ir.SetPos(n1)
+				n1 = Expr(n1)
+				ls[i] = n1
+				if i >= t.NumFields() {
+					if !errored {
+						base.Errorf("too many values in %v", n)
+						errored = true
+					}
+					continue
+				}
+
+				f := t.Field(i)
+				s := f.Sym
+				if s != nil && !types.IsExported(s.Name) && s.Pkg != types.LocalPkg {
+					base.Errorf("implicit assignment of unexported field '%s' in %v literal", s.Name, t)
+				}
+				// No pushtype allowed here. Must name fields for that.
+				n1 = AssignConv(n1, f.Type, "field value")
+				sk := ir.NewStructKeyExpr(base.Pos, f.Sym, n1)
+				sk.Offset = f.Offset
+				ls[i] = sk
+			}
+			if len(ls) < t.NumFields() {
+				base.Errorf("too few values in %v", n)
+			}
+		} else {
+			hash := make(map[string]bool)
+
+			// keyed list
+			ls := n.List
+			for i, l := range ls {
+				ir.SetPos(l)
+
+				if l.Op() == ir.OKEY {
+					kv := l.(*ir.KeyExpr)
+					key := kv.Key
+
+					// Sym might have resolved to name in other top-level
+					// package, because of import dot. Redirect to correct sym
+					// before we do the lookup.
+					s := key.Sym()
+					if id, ok := key.(*ir.Ident); ok && DotImportRefs[id] != nil {
+						s = Lookup(s.Name)
+					}
+
+					// An OXDOT uses the Sym field to hold
+					// the field to the right of the dot,
+					// so s will be non-nil, but an OXDOT
+					// is never a valid struct literal key.
+					if s == nil || s.Pkg != types.LocalPkg || key.Op() == ir.OXDOT || s.IsBlank() {
+						base.Errorf("invalid field name %v in struct initializer", key)
+						continue
+					}
+
+					l = ir.NewStructKeyExpr(l.Pos(), s, kv.Value)
+					ls[i] = l
+				}
+
+				if l.Op() != ir.OSTRUCTKEY {
+					if !errored {
+						base.Errorf("mixture of field:value and value initializers")
+						errored = true
+					}
+					ls[i] = Expr(ls[i])
+					continue
+				}
+				l := l.(*ir.StructKeyExpr)
+
+				f := Lookdot1(nil, l.Field, t, t.Fields(), 0)
+				if f == nil {
+					if ci := Lookdot1(nil, l.Field, t, t.Fields(), 2); ci != nil { // Case-insensitive lookup.
+						if visible(ci.Sym) {
+							base.Errorf("unknown field '%v' in struct literal of type %v (but does have %v)", l.Field, t, ci.Sym)
+						} else if nonexported(l.Field) && l.Field.Name == ci.Sym.Name { // Ensure exactness before the suggestion.
+							base.Errorf("cannot refer to unexported field '%v' in struct literal of type %v", l.Field, t)
+						} else {
+							base.Errorf("unknown field '%v' in struct literal of type %v", l.Field, t)
+						}
+						continue
+					}
+					var f *types.Field
+					p, _ := dotpath(l.Field, t, &f, true)
+					if p == nil || f.IsMethod() {
+						base.Errorf("unknown field '%v' in struct literal of type %v", l.Field, t)
+						continue
+					}
+					// dotpath returns the parent embedded types in reverse order.
+					var ep []string
+					for ei := len(p) - 1; ei >= 0; ei-- {
+						ep = append(ep, p[ei].field.Sym.Name)
+					}
+					ep = append(ep, l.Field.Name)
+					base.Errorf("cannot use promoted field %v in struct literal of type %v", strings.Join(ep, "."), t)
+					continue
+				}
+				fielddup(f.Sym.Name, hash)
+				l.Offset = f.Offset
+
+				// No pushtype allowed here. Tried and rejected.
+				l.Value = Expr(l.Value)
+				l.Value = AssignConv(l.Value, f.Type, "field value")
+			}
+		}
+
+		n.SetOp(ir.OSTRUCTLIT)
+		n.Ntype = nil
+	}
+
+	return n
+}
+
+// tcConv typechecks an OCONV node.
+func tcConv(n *ir.ConvExpr) ir.Node {
+	types.CheckSize(n.Type()) // ensure width is calculated for backend
+	n.X = Expr(n.X)
+	n.X = convlit1(n.X, n.Type(), true, nil)
+	t := n.X.Type()
+	if t == nil || n.Type() == nil {
+		n.SetType(nil)
+		return n
+	}
+	op, why := Convertop(n.X.Op() == ir.OLITERAL, t, n.Type())
+	if op == ir.OXXX {
+		if !n.Diag() && !n.Type().Broke() && !n.X.Diag() {
+			base.Errorf("cannot convert %L to type %v%s", n.X, n.Type(), why)
+			n.SetDiag(true)
+		}
+		n.SetOp(ir.OCONV)
+		n.SetType(nil)
+		return n
+	}
+
+	n.SetOp(op)
+	switch n.Op() {
+	case ir.OCONVNOP:
+		if t.Kind() == n.Type().Kind() {
+			switch t.Kind() {
+			case types.TFLOAT32, types.TFLOAT64, types.TCOMPLEX64, types.TCOMPLEX128:
+				// Floating point casts imply rounding and
+				// so the conversion must be kept.
+				n.SetOp(ir.OCONV)
+			}
+		}
+
+	// do not convert to []byte literal. See CL 125796.
+	// generated code and compiler memory footprint is better without it.
+	case ir.OSTR2BYTES:
+		// ok
+
+	case ir.OSTR2RUNES:
+		if n.X.Op() == ir.OLITERAL {
+			return stringtoruneslit(n)
+		}
+	}
+	return n
+}
+
+// tcDot typechecks an OXDOT or ODOT node.
+func tcDot(n *ir.SelectorExpr, top int) ir.Node {
+	if n.Op() == ir.OXDOT {
+		n = AddImplicitDots(n)
+		n.SetOp(ir.ODOT)
+		if n.X == nil {
+			n.SetType(nil)
+			return n
+		}
+	}
+
+	n.X = typecheck(n.X, ctxExpr|ctxType)
+	n.X = DefaultLit(n.X, nil)
+
+	t := n.X.Type()
+	if t == nil {
+		base.UpdateErrorDot(ir.Line(n), fmt.Sprint(n.X), fmt.Sprint(n))
+		n.SetType(nil)
+		return n
+	}
+
+	if n.X.Op() == ir.OTYPE {
+		return typecheckMethodExpr(n)
+	}
+
+	if t.IsPtr() && !t.Elem().IsInterface() {
+		t = t.Elem()
+		if t == nil {
+			n.SetType(nil)
+			return n
+		}
+		n.SetOp(ir.ODOTPTR)
+		types.CheckSize(t)
+	}
+
+	if n.Sel.IsBlank() {
+		base.Errorf("cannot refer to blank field or method")
+		n.SetType(nil)
+		return n
+	}
+
+	if Lookdot(n, t, 0) == nil {
+		// Legitimate field or method lookup failed, try to explain the error
+		switch {
+		case t.IsEmptyInterface():
+			base.Errorf("%v undefined (type %v is interface with no methods)", n, n.X.Type())
+
+		case t.IsPtr() && t.Elem().IsInterface():
+			// Pointer to interface is almost always a mistake.
+			base.Errorf("%v undefined (type %v is pointer to interface, not interface)", n, n.X.Type())
+
+		case Lookdot(n, t, 1) != nil:
+			// Field or method matches by name, but it is not exported.
+			base.Errorf("%v undefined (cannot refer to unexported field or method %v)", n, n.Sel)
+
+		default:
+			if mt := Lookdot(n, t, 2); mt != nil && visible(mt.Sym) { // Case-insensitive lookup.
+				base.Errorf("%v undefined (type %v has no field or method %v, but does have %v)", n, n.X.Type(), n.Sel, mt.Sym)
+			} else {
+				base.Errorf("%v undefined (type %v has no field or method %v)", n, n.X.Type(), n.Sel)
+			}
+		}
+		n.SetType(nil)
+		return n
+	}
+
+	if (n.Op() == ir.ODOTINTER || n.Op() == ir.ODOTMETH) && top&ctxCallee == 0 {
+		n.SetOp(ir.OCALLPART)
+		n.SetType(MethodValueWrapper(n).Type())
+	}
+	return n
+}
+
+// tcDotType typechecks an ODOTTYPE node.
+func tcDotType(n *ir.TypeAssertExpr) ir.Node {
+	n.X = Expr(n.X)
+	n.X = DefaultLit(n.X, nil)
+	l := n.X
+	t := l.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+	if !t.IsInterface() {
+		base.Errorf("invalid type assertion: %v (non-interface type %v on left)", n, t)
+		n.SetType(nil)
+		return n
+	}
+
+	if n.Ntype != nil {
+		n.Ntype = typecheckNtype(n.Ntype)
+		n.SetType(n.Ntype.Type())
+		n.Ntype = nil
+		if n.Type() == nil {
+			return n
+		}
+	}
+
+	if n.Type() != nil && !n.Type().IsInterface() {
+		var missing, have *types.Field
+		var ptr int
+		if !implements(n.Type(), t, &missing, &have, &ptr) {
+			if have != nil && have.Sym == missing.Sym {
+				base.Errorf("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+
+					"\t\thave %v%S\n\t\twant %v%S", n.Type(), t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
+			} else if ptr != 0 {
+				base.Errorf("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", n.Type(), t, missing.Sym)
+			} else if have != nil {
+				base.Errorf("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+
+					"\t\thave %v%S\n\t\twant %v%S", n.Type(), t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
+			} else {
+				base.Errorf("impossible type assertion:\n\t%v does not implement %v (missing %v method)", n.Type(), t, missing.Sym)
+			}
+			n.SetType(nil)
+			return n
+		}
+	}
+	return n
+}
+
+// tcITab typechecks an OITAB node.
+func tcITab(n *ir.UnaryExpr) ir.Node {
+	n.X = Expr(n.X)
+	t := n.X.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+	if !t.IsInterface() {
+		base.Fatalf("OITAB of %v", t)
+	}
+	n.SetType(types.NewPtr(types.Types[types.TUINTPTR]))
+	return n
+}
+
+// tcIndex typechecks an OINDEX node.
+func tcIndex(n *ir.IndexExpr) ir.Node {
+	n.X = Expr(n.X)
+	n.X = DefaultLit(n.X, nil)
+	n.X = implicitstar(n.X)
+	l := n.X
+	n.Index = Expr(n.Index)
+	r := n.Index
+	t := l.Type()
+	if t == nil || r.Type() == nil {
+		n.SetType(nil)
+		return n
+	}
+	switch t.Kind() {
+	default:
+		base.Errorf("invalid operation: %v (type %v does not support indexing)", n, t)
+		n.SetType(nil)
+		return n
+
+	case types.TSTRING, types.TARRAY, types.TSLICE:
+		n.Index = indexlit(n.Index)
+		if t.IsString() {
+			n.SetType(types.ByteType)
+		} else {
+			n.SetType(t.Elem())
+		}
+		why := "string"
+		if t.IsArray() {
+			why = "array"
+		} else if t.IsSlice() {
+			why = "slice"
+		}
+
+		if n.Index.Type() != nil && !n.Index.Type().IsInteger() {
+			base.Errorf("non-integer %s index %v", why, n.Index)
+			return n
+		}
+
+		if !n.Bounded() && ir.IsConst(n.Index, constant.Int) {
+			x := n.Index.Val()
+			if constant.Sign(x) < 0 {
+				base.Errorf("invalid %s index %v (index must be non-negative)", why, n.Index)
+			} else if t.IsArray() && constant.Compare(x, token.GEQ, constant.MakeInt64(t.NumElem())) {
+				base.Errorf("invalid array index %v (out of bounds for %d-element array)", n.Index, t.NumElem())
+			} else if ir.IsConst(n.X, constant.String) && constant.Compare(x, token.GEQ, constant.MakeInt64(int64(len(ir.StringVal(n.X))))) {
+				base.Errorf("invalid string index %v (out of bounds for %d-byte string)", n.Index, len(ir.StringVal(n.X)))
+			} else if ir.ConstOverflow(x, types.Types[types.TINT]) {
+				base.Errorf("invalid %s index %v (index too large)", why, n.Index)
+			}
+		}
+
+	case types.TMAP:
+		n.Index = AssignConv(n.Index, t.Key(), "map index")
+		n.SetType(t.Elem())
+		n.SetOp(ir.OINDEXMAP)
+		n.Assigned = false
+	}
+	return n
+}
+
+// tcLenCap typechecks an OLEN or OCAP node.
+func tcLenCap(n *ir.UnaryExpr) ir.Node {
+	n.X = Expr(n.X)
+	n.X = DefaultLit(n.X, nil)
+	n.X = implicitstar(n.X)
+	l := n.X
+	t := l.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+
+	var ok bool
+	if n.Op() == ir.OLEN {
+		ok = okforlen[t.Kind()]
+	} else {
+		ok = okforcap[t.Kind()]
+	}
+	if !ok {
+		base.Errorf("invalid argument %L for %v", l, n.Op())
+		n.SetType(nil)
+		return n
+	}
+
+	n.SetType(types.Types[types.TINT])
+	return n
+}
+
+// tcRecv typechecks an ORECV node.
+func tcRecv(n *ir.UnaryExpr) ir.Node {
+	n.X = Expr(n.X)
+	n.X = DefaultLit(n.X, nil)
+	l := n.X
+	t := l.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+	if !t.IsChan() {
+		base.Errorf("invalid operation: %v (receive from non-chan type %v)", n, t)
+		n.SetType(nil)
+		return n
+	}
+
+	if !t.ChanDir().CanRecv() {
+		base.Errorf("invalid operation: %v (receive from send-only type %v)", n, t)
+		n.SetType(nil)
+		return n
+	}
+
+	n.SetType(t.Elem())
+	return n
+}
+
+// tcSPtr typechecks an OSPTR node.
+func tcSPtr(n *ir.UnaryExpr) ir.Node {
+	n.X = Expr(n.X)
+	t := n.X.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+	if !t.IsSlice() && !t.IsString() {
+		base.Fatalf("OSPTR of %v", t)
+	}
+	if t.IsString() {
+		n.SetType(types.NewPtr(types.Types[types.TUINT8]))
+	} else {
+		n.SetType(types.NewPtr(t.Elem()))
+	}
+	return n
+}
+
+// tcSlice typechecks an OSLICE or OSLICE3 node.
+func tcSlice(n *ir.SliceExpr) ir.Node {
+	n.X = DefaultLit(Expr(n.X), nil)
+	n.Low = indexlit(Expr(n.Low))
+	n.High = indexlit(Expr(n.High))
+	n.Max = indexlit(Expr(n.Max))
+	hasmax := n.Op().IsSlice3()
+	l := n.X
+	if l.Type() == nil {
+		n.SetType(nil)
+		return n
+	}
+	if l.Type().IsArray() {
+		if !ir.IsAddressable(n.X) {
+			base.Errorf("invalid operation %v (slice of unaddressable value)", n)
+			n.SetType(nil)
+			return n
+		}
+
+		addr := NodAddr(n.X)
+		addr.SetImplicit(true)
+		n.X = Expr(addr)
+		l = n.X
+	}
+	t := l.Type()
+	var tp *types.Type
+	if t.IsString() {
+		if hasmax {
+			base.Errorf("invalid operation %v (3-index slice of string)", n)
+			n.SetType(nil)
+			return n
+		}
+		n.SetType(t)
+		n.SetOp(ir.OSLICESTR)
+	} else if t.IsPtr() && t.Elem().IsArray() {
+		tp = t.Elem()
+		n.SetType(types.NewSlice(tp.Elem()))
+		types.CalcSize(n.Type())
+		if hasmax {
+			n.SetOp(ir.OSLICE3ARR)
+		} else {
+			n.SetOp(ir.OSLICEARR)
+		}
+	} else if t.IsSlice() {
+		n.SetType(t)
+	} else {
+		base.Errorf("cannot slice %v (type %v)", l, t)
+		n.SetType(nil)
+		return n
+	}
+
+	if n.Low != nil && !checksliceindex(l, n.Low, tp) {
+		n.SetType(nil)
+		return n
+	}
+	if n.High != nil && !checksliceindex(l, n.High, tp) {
+		n.SetType(nil)
+		return n
+	}
+	if n.Max != nil && !checksliceindex(l, n.Max, tp) {
+		n.SetType(nil)
+		return n
+	}
+	if !checksliceconst(n.Low, n.High) || !checksliceconst(n.Low, n.Max) || !checksliceconst(n.High, n.Max) {
+		n.SetType(nil)
+		return n
+	}
+	return n
+}
+
+// tcSliceHeader typechecks an OSLICEHEADER node.
+func tcSliceHeader(n *ir.SliceHeaderExpr) ir.Node {
+	// Errors here are Fatalf instead of Errorf because only the compiler
+	// can construct an OSLICEHEADER node.
+	// Components used in OSLICEHEADER that are supplied by parsed source code
+	// have already been typechecked in e.g. OMAKESLICE earlier.
+	t := n.Type()
+	if t == nil {
+		base.Fatalf("no type specified for OSLICEHEADER")
+	}
+
+	if !t.IsSlice() {
+		base.Fatalf("invalid type %v for OSLICEHEADER", n.Type())
+	}
+
+	if n.Ptr == nil || n.Ptr.Type() == nil || !n.Ptr.Type().IsUnsafePtr() {
+		base.Fatalf("need unsafe.Pointer for OSLICEHEADER")
+	}
+
+	n.Ptr = Expr(n.Ptr)
+	n.Len = DefaultLit(Expr(n.Len), types.Types[types.TINT])
+	n.Cap = DefaultLit(Expr(n.Cap), types.Types[types.TINT])
+
+	if ir.IsConst(n.Len, constant.Int) && ir.Int64Val(n.Len) < 0 {
+		base.Fatalf("len for OSLICEHEADER must be non-negative")
+	}
+
+	if ir.IsConst(n.Cap, constant.Int) && ir.Int64Val(n.Cap) < 0 {
+		base.Fatalf("cap for OSLICEHEADER must be non-negative")
+	}
+
+	if ir.IsConst(n.Len, constant.Int) && ir.IsConst(n.Cap, constant.Int) && constant.Compare(n.Len.Val(), token.GTR, n.Cap.Val()) {
+		base.Fatalf("len larger than cap for OSLICEHEADER")
+	}
+
+	return n
+}
+
+// tcStar typechecks an ODEREF node, which may be an expression or a type.
+func tcStar(n *ir.StarExpr, top int) ir.Node {
+	n.X = typecheck(n.X, ctxExpr|ctxType)
+	l := n.X
+	t := l.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+	if l.Op() == ir.OTYPE {
+		n.SetOTYPE(types.NewPtr(l.Type()))
+		// Ensure l.Type gets CalcSize'd for the backend. Issue 20174.
+		types.CheckSize(l.Type())
+		return n
+	}
+
+	if !t.IsPtr() {
+		if top&(ctxExpr|ctxStmt) != 0 {
+			base.Errorf("invalid indirect of %L", n.X)
+			n.SetType(nil)
+			return n
+		}
+		base.Errorf("%v is not a type", l)
+		return n
+	}
+
+	n.SetType(t.Elem())
+	return n
+}
+
+// tcUnaryArith typechecks a unary arithmetic expression.
+func tcUnaryArith(n *ir.UnaryExpr) ir.Node {
+	n.X = Expr(n.X)
+	l := n.X
+	t := l.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+	if !okfor[n.Op()][defaultType(t).Kind()] {
+		base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(t))
+		n.SetType(nil)
+		return n
+	}
+
+	n.SetType(t)
+	return n
+}
diff --git a/src/cmd/compile/internal/typecheck/func.go b/src/cmd/compile/internal/typecheck/func.go
new file mode 100644
index 0000000..fbcc784
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/func.go
@@ -0,0 +1,1035 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typecheck
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+
+	"fmt"
+	"go/constant"
+	"go/token"
+)
+
+// package all the arguments that match a ... T parameter into a []T.
+func MakeDotArgs(typ *types.Type, args []ir.Node) ir.Node {
+	var n ir.Node
+	if len(args) == 0 {
+		n = NodNil()
+		n.SetType(typ)
+	} else {
+		lit := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(typ), nil)
+		lit.List.Append(args...)
+		lit.SetImplicit(true)
+		n = lit
+	}
+
+	n = Expr(n)
+	if n.Type() == nil {
+		base.Fatalf("mkdotargslice: typecheck failed")
+	}
+	return n
+}
+
+// FixVariadicCall rewrites calls to variadic functions to use an
+// explicit ... argument if one is not already present.
+func FixVariadicCall(call *ir.CallExpr) {
+	fntype := call.X.Type()
+	if !fntype.IsVariadic() || call.IsDDD {
+		return
+	}
+
+	vi := fntype.NumParams() - 1
+	vt := fntype.Params().Field(vi).Type
+
+	args := call.Args
+	extra := args[vi:]
+	slice := MakeDotArgs(vt, extra)
+	for i := range extra {
+		extra[i] = nil // allow GC
+	}
+
+	call.Args = append(args[:vi], slice)
+	call.IsDDD = true
+}
+
+// ClosureType returns the struct type used to hold all the information
+// needed in the closure for clo (clo must be a OCLOSURE node).
+// The address of a variable of the returned type can be cast to a func.
+func ClosureType(clo *ir.ClosureExpr) *types.Type {
+	// Create closure in the form of a composite literal.
+	// supposing the closure captures an int i and a string s
+	// and has one float64 argument and no results,
+	// the generated code looks like:
+	//
+	//	clos = &struct{.F uintptr; i *int; s *string}{func.1, &i, &s}
+	//
+	// The use of the struct provides type information to the garbage
+	// collector so that it can walk the closure. We could use (in this case)
+	// [3]unsafe.Pointer instead, but that would leave the gc in the dark.
+	// The information appears in the binary in the form of type descriptors;
+	// the struct is unnamed so that closures in multiple packages with the
+	// same struct type can share the descriptor.
+	fields := []*types.Field{
+		types.NewField(base.Pos, Lookup(".F"), types.Types[types.TUINTPTR]),
+	}
+	for _, v := range clo.Func.ClosureVars {
+		typ := v.Type()
+		if !v.Byval() {
+			typ = types.NewPtr(typ)
+		}
+		fields = append(fields, types.NewField(base.Pos, v.Sym(), typ))
+	}
+	typ := types.NewStruct(types.NoPkg, fields)
+	typ.SetNoalg(true)
+	return typ
+}
+
+// PartialCallType returns the struct type used to hold all the information
+// needed in the closure for n (n must be a OCALLPART node).
+// The address of a variable of the returned type can be cast to a func.
+func PartialCallType(n *ir.SelectorExpr) *types.Type {
+	t := types.NewStruct(types.NoPkg, []*types.Field{
+		types.NewField(base.Pos, Lookup("F"), types.Types[types.TUINTPTR]),
+		types.NewField(base.Pos, Lookup("R"), n.X.Type()),
+	})
+	t.SetNoalg(true)
+	return t
+}
+
+// True if we are typechecking an inline body in ImportedBody below. We use this
+// flag to not create a new closure function in tcClosure when we are just
+// typechecking an inline body, as opposed to the body of a real function.
+var inTypeCheckInl bool
+
+// ImportedBody returns immediately if the inlining information for fn is
+// populated. Otherwise, fn must be an imported function. If so, ImportedBody
+// loads in the dcls and body for fn, and typechecks as needed.
+func ImportedBody(fn *ir.Func) {
+	if fn.Inl.Body != nil {
+		return
+	}
+	lno := ir.SetPos(fn.Nname)
+
+	// When we load an inlined body, we need to allow OADDR
+	// operations on untyped expressions. We will fix the
+	// addrtaken flags on all the arguments of the OADDR with the
+	// computeAddrtaken call below (after we typecheck the body).
+	// TODO: export/import types and addrtaken marks along with inlined bodies,
+	// so this will be unnecessary.
+	IncrementalAddrtaken = false
+	defer func() {
+		if DirtyAddrtaken {
+			ComputeAddrtaken(fn.Inl.Body) // compute addrtaken marks once types are available
+			DirtyAddrtaken = false
+		}
+		IncrementalAddrtaken = true
+	}()
+
+	ImportBody(fn)
+
+	// Stmts(fn.Inl.Body) below is only for imported functions;
+	// their bodies may refer to unsafe as long as the package
+	// was marked safe during import (which was checked then).
+	// the ->inl of a local function has been typechecked before CanInline copied it.
+	pkg := fnpkg(fn.Nname)
+
+	if pkg == types.LocalPkg || pkg == nil {
+		return // ImportedBody on local function
+	}
+
+	if base.Flag.LowerM > 2 || base.Debug.Export != 0 {
+		fmt.Printf("typecheck import [%v] %L { %v }\n", fn.Sym(), fn, ir.Nodes(fn.Inl.Body))
+	}
+
+	if !go117ExportTypes {
+		// If we didn't export & import types, typecheck the code here.
+		savefn := ir.CurFunc
+		ir.CurFunc = fn
+		if inTypeCheckInl {
+			base.Fatalf("inTypeCheckInl should not be set recursively")
+		}
+		inTypeCheckInl = true
+		Stmts(fn.Inl.Body)
+		inTypeCheckInl = false
+		ir.CurFunc = savefn
+	}
+
+	base.Pos = lno
+}
+
+// Get the function's package. For ordinary functions it's on the ->sym, but for imported methods
+// the ->sym can be re-used in the local package, so peel it off the receiver's type.
+func fnpkg(fn *ir.Name) *types.Pkg {
+	if ir.IsMethod(fn) {
+		// method
+		rcvr := fn.Type().Recv().Type
+
+		if rcvr.IsPtr() {
+			rcvr = rcvr.Elem()
+		}
+		if rcvr.Sym() == nil {
+			base.Fatalf("receiver with no sym: [%v] %L  (%v)", fn.Sym(), fn, rcvr)
+		}
+		return rcvr.Sym().Pkg
+	}
+
+	// non-method
+	return fn.Sym().Pkg
+}
+
+// ClosureName generates a new unique name for a closure within
+// outerfunc.
+func ClosureName(outerfunc *ir.Func) *types.Sym {
+	outer := "glob."
+	prefix := "func"
+	gen := &globClosgen
+
+	if outerfunc != nil {
+		if outerfunc.OClosure != nil {
+			prefix = ""
+		}
+
+		outer = ir.FuncName(outerfunc)
+
+		// There may be multiple functions named "_". In those
+		// cases, we can't use their individual Closgens as it
+		// would lead to name clashes.
+		if !ir.IsBlank(outerfunc.Nname) {
+			gen = &outerfunc.Closgen
+		}
+	}
+
+	*gen++
+	return Lookup(fmt.Sprintf("%s.%s%d", outer, prefix, *gen))
+}
+
+// globClosgen is like Func.Closgen, but for the global scope.
+var globClosgen int32
+
+// MethodValueWrapper returns the DCLFUNC node representing the
+// wrapper function (*-fm) needed for the given method value. If the
+// wrapper function hasn't already been created yet, it's created and
+// added to Target.Decls.
+//
+// TODO(mdempsky): Move into walk. This isn't part of type checking.
+func MethodValueWrapper(dot *ir.SelectorExpr) *ir.Func {
+	if dot.Op() != ir.OCALLPART {
+		base.Fatalf("MethodValueWrapper: unexpected %v (%v)", dot, dot.Op())
+	}
+
+	t0 := dot.Type()
+	meth := dot.Sel
+	rcvrtype := dot.X.Type()
+	sym := ir.MethodSymSuffix(rcvrtype, meth, "-fm")
+
+	if sym.Uniq() {
+		return sym.Def.(*ir.Func)
+	}
+	sym.SetUniq(true)
+
+	savecurfn := ir.CurFunc
+	saveLineNo := base.Pos
+	ir.CurFunc = nil
+
+	// Set line number equal to the line number where the method is declared.
+	if pos := dot.Selection.Pos; pos.IsKnown() {
+		base.Pos = pos
+	}
+	// Note: !dot.Selection.Pos.IsKnown() happens for method expressions where
+	// the method is implicitly declared. The Error method of the
+	// built-in error type is one such method.  We leave the line
+	// number at the use of the method expression in this
+	// case. See issue 29389.
+
+	tfn := ir.NewFuncType(base.Pos, nil,
+		NewFuncParams(t0.Params(), true),
+		NewFuncParams(t0.Results(), false))
+
+	fn := DeclFunc(sym, tfn)
+	fn.SetDupok(true)
+	fn.SetNeedctxt(true)
+	fn.SetWrapper(true)
+
+	// Declare and initialize variable holding receiver.
+	ptr := ir.NewNameAt(base.Pos, Lookup(".this"))
+	ptr.Class = ir.PAUTOHEAP
+	ptr.SetType(rcvrtype)
+	ptr.Curfn = fn
+	ptr.SetIsClosureVar(true)
+	ptr.SetByval(true)
+	fn.ClosureVars = append(fn.ClosureVars, ptr)
+
+	call := ir.NewCallExpr(base.Pos, ir.OCALL, ir.NewSelectorExpr(base.Pos, ir.OXDOT, ptr, meth), nil)
+	call.Args = ir.ParamNames(tfn.Type())
+	call.IsDDD = tfn.Type().IsVariadic()
+
+	var body ir.Node = call
+	if t0.NumResults() != 0 {
+		ret := ir.NewReturnStmt(base.Pos, nil)
+		ret.Results = []ir.Node{call}
+		body = ret
+	}
+
+	fn.Body = []ir.Node{body}
+	FinishFuncBody()
+
+	Func(fn)
+	// Need to typecheck the body of the just-generated wrapper.
+	// typecheckslice() requires that Curfn is set when processing an ORETURN.
+	ir.CurFunc = fn
+	Stmts(fn.Body)
+	sym.Def = fn
+	Target.Decls = append(Target.Decls, fn)
+	ir.CurFunc = savecurfn
+	base.Pos = saveLineNo
+
+	return fn
+}
+
+// tcClosure typechecks an OCLOSURE node. It also creates the named
+// function associated with the closure.
+// TODO: This creation of the named function should probably really be done in a
+// separate pass from type-checking.
+func tcClosure(clo *ir.ClosureExpr, top int) {
+	fn := clo.Func
+	// Set current associated iota value, so iota can be used inside
+	// function in ConstSpec, see issue #22344
+	if x := getIotaValue(); x >= 0 {
+		fn.Iota = x
+	}
+
+	fn.SetClosureCalled(top&ctxCallee != 0)
+
+	// Do not typecheck fn twice, otherwise, we will end up pushing
+	// fn to Target.Decls multiple times, causing InitLSym called twice.
+	// See #30709
+	if fn.Typecheck() == 1 {
+		clo.SetType(fn.Type())
+		return
+	}
+
+	// Don't give a name and add to Target.Decls if we are typechecking an inlined
+	// body in ImportedBody(), since we only want to create the named function
+	// when the closure is actually inlined (and then we force a typecheck
+	// explicitly in (*inlsubst).node()).
+	if !inTypeCheckInl {
+		fn.Nname.SetSym(ClosureName(ir.CurFunc))
+		ir.MarkFunc(fn.Nname)
+	}
+	Func(fn)
+	clo.SetType(fn.Type())
+
+	// Type check the body now, but only if we're inside a function.
+	// At top level (in a variable initialization: curfn==nil) we're not
+	// ready to type check code yet; we'll check it later, because the
+	// underlying closure function we create is added to Target.Decls.
+	if ir.CurFunc != nil && clo.Type() != nil {
+		oldfn := ir.CurFunc
+		ir.CurFunc = fn
+		Stmts(fn.Body)
+		ir.CurFunc = oldfn
+	}
+
+	out := 0
+	for _, v := range fn.ClosureVars {
+		if v.Type() == nil {
+			// If v.Type is nil, it means v looked like it was going to be
+			// used in the closure, but isn't. This happens in struct
+			// literals like s{f: x} where we can't distinguish whether f is
+			// a field identifier or expression until resolving s.
+			continue
+		}
+
+		// type check closed variables outside the closure, so that the
+		// outer frame also captures them.
+		Expr(v.Outer)
+
+		fn.ClosureVars[out] = v
+		out++
+	}
+	fn.ClosureVars = fn.ClosureVars[:out]
+
+	if base.Flag.W > 1 {
+		s := fmt.Sprintf("New closure func: %s", ir.FuncName(fn))
+		ir.Dump(s, fn)
+	}
+	if !inTypeCheckInl {
+		// Add function to Target.Decls once only when we give it a name
+		Target.Decls = append(Target.Decls, fn)
+	}
+}
+
+// type check function definition
+// To be called by typecheck, not directly.
+// (Call typecheck.Func instead.)
+func tcFunc(n *ir.Func) {
+	if base.EnableTrace && base.Flag.LowerT {
+		defer tracePrint("tcFunc", n)(nil)
+	}
+
+	n.Nname = AssignExpr(n.Nname).(*ir.Name)
+	t := n.Nname.Type()
+	if t == nil {
+		return
+	}
+	rcvr := t.Recv()
+	if rcvr != nil && n.Shortname != nil {
+		m := addmethod(n, n.Shortname, t, true, n.Pragma&ir.Nointerface != 0)
+		if m == nil {
+			return
+		}
+
+		n.Nname.SetSym(ir.MethodSym(rcvr.Type, n.Shortname))
+		Declare(n.Nname, ir.PFUNC)
+	}
+}
+
+// tcCall typechecks an OCALL node.
+func tcCall(n *ir.CallExpr, top int) ir.Node {
+	n.Use = ir.CallUseExpr
+	if top == ctxStmt {
+		n.Use = ir.CallUseStmt
+	}
+	Stmts(n.Init()) // imported rewritten f(g()) calls (#30907)
+	n.X = typecheck(n.X, ctxExpr|ctxType|ctxCallee)
+	if n.X.Diag() {
+		n.SetDiag(true)
+	}
+
+	l := n.X
+
+	if l.Op() == ir.ONAME && l.(*ir.Name).BuiltinOp != 0 {
+		l := l.(*ir.Name)
+		if n.IsDDD && l.BuiltinOp != ir.OAPPEND {
+			base.Errorf("invalid use of ... with builtin %v", l)
+		}
+
+		// builtin: OLEN, OCAP, etc.
+		switch l.BuiltinOp {
+		default:
+			base.Fatalf("unknown builtin %v", l)
+
+		case ir.OAPPEND, ir.ODELETE, ir.OMAKE, ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
+			n.SetOp(l.BuiltinOp)
+			n.X = nil
+			n.SetTypecheck(0) // re-typechecking new op is OK, not a loop
+			return typecheck(n, top)
+
+		case ir.OCAP, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.OPANIC, ir.OREAL:
+			typecheckargs(n)
+			fallthrough
+		case ir.ONEW, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
+			arg, ok := needOneArg(n, "%v", n.Op())
+			if !ok {
+				n.SetType(nil)
+				return n
+			}
+			u := ir.NewUnaryExpr(n.Pos(), l.BuiltinOp, arg)
+			return typecheck(ir.InitExpr(n.Init(), u), top) // typecheckargs can add to old.Init
+
+		case ir.OCOMPLEX, ir.OCOPY, ir.OUNSAFEADD, ir.OUNSAFESLICE:
+			typecheckargs(n)
+			arg1, arg2, ok := needTwoArgs(n)
+			if !ok {
+				n.SetType(nil)
+				return n
+			}
+			b := ir.NewBinaryExpr(n.Pos(), l.BuiltinOp, arg1, arg2)
+			return typecheck(ir.InitExpr(n.Init(), b), top) // typecheckargs can add to old.Init
+		}
+		panic("unreachable")
+	}
+
+	n.X = DefaultLit(n.X, nil)
+	l = n.X
+	if l.Op() == ir.OTYPE {
+		if n.IsDDD {
+			if !l.Type().Broke() {
+				base.Errorf("invalid use of ... in type conversion to %v", l.Type())
+			}
+			n.SetDiag(true)
+		}
+
+		// pick off before type-checking arguments
+		arg, ok := needOneArg(n, "conversion to %v", l.Type())
+		if !ok {
+			n.SetType(nil)
+			return n
+		}
+
+		n := ir.NewConvExpr(n.Pos(), ir.OCONV, nil, arg)
+		n.SetType(l.Type())
+		return tcConv(n)
+	}
+
+	typecheckargs(n)
+	t := l.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+	types.CheckSize(t)
+
+	switch l.Op() {
+	case ir.ODOTINTER:
+		n.SetOp(ir.OCALLINTER)
+
+	case ir.ODOTMETH:
+		l := l.(*ir.SelectorExpr)
+		n.SetOp(ir.OCALLMETH)
+
+		// typecheckaste was used here but there wasn't enough
+		// information further down the call chain to know if we
+		// were testing a method receiver for unexported fields.
+		// It isn't necessary, so just do a sanity check.
+		tp := t.Recv().Type
+
+		if l.X == nil || !types.Identical(l.X.Type(), tp) {
+			base.Fatalf("method receiver")
+		}
+
+	default:
+		n.SetOp(ir.OCALLFUNC)
+		if t.Kind() != types.TFUNC {
+			if o := ir.Orig(l); o.Name() != nil && types.BuiltinPkg.Lookup(o.Sym().Name).Def != nil {
+				// be more specific when the non-function
+				// name matches a predeclared function
+				base.Errorf("cannot call non-function %L, declared at %s",
+					l, base.FmtPos(o.Name().Pos()))
+			} else {
+				base.Errorf("cannot call non-function %L", l)
+			}
+			n.SetType(nil)
+			return n
+		}
+	}
+
+	typecheckaste(ir.OCALL, n.X, n.IsDDD, t.Params(), n.Args, func() string { return fmt.Sprintf("argument to %v", n.X) })
+	if t.NumResults() == 0 {
+		return n
+	}
+	if t.NumResults() == 1 {
+		n.SetType(l.Type().Results().Field(0).Type)
+
+		if n.Op() == ir.OCALLFUNC && n.X.Op() == ir.ONAME {
+			if sym := n.X.(*ir.Name).Sym(); types.IsRuntimePkg(sym.Pkg) && sym.Name == "getg" {
+				// Emit code for runtime.getg() directly instead of calling function.
+				// Most such rewrites (for example the similar one for math.Sqrt) should be done in walk,
+				// so that the ordering pass can make sure to preserve the semantics of the original code
+				// (in particular, the exact time of the function call) by introducing temporaries.
+				// In this case, we know getg() always returns the same result within a given function
+				// and we want to avoid the temporaries, so we do the rewrite earlier than is typical.
+				n.SetOp(ir.OGETG)
+			}
+		}
+		return n
+	}
+
+	// multiple return
+	if top&(ctxMultiOK|ctxStmt) == 0 {
+		base.Errorf("multiple-value %v() in single-value context", l)
+		return n
+	}
+
+	n.SetType(l.Type().Results())
+	return n
+}
+
+// tcAppend typechecks an OAPPEND node.
+func tcAppend(n *ir.CallExpr) ir.Node {
+	typecheckargs(n)
+	args := n.Args
+	if len(args) == 0 {
+		base.Errorf("missing arguments to append")
+		n.SetType(nil)
+		return n
+	}
+
+	t := args[0].Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+
+	n.SetType(t)
+	if !t.IsSlice() {
+		if ir.IsNil(args[0]) {
+			base.Errorf("first argument to append must be typed slice; have untyped nil")
+			n.SetType(nil)
+			return n
+		}
+
+		base.Errorf("first argument to append must be slice; have %L", t)
+		n.SetType(nil)
+		return n
+	}
+
+	if n.IsDDD {
+		if len(args) == 1 {
+			base.Errorf("cannot use ... on first argument to append")
+			n.SetType(nil)
+			return n
+		}
+
+		if len(args) != 2 {
+			base.Errorf("too many arguments to append")
+			n.SetType(nil)
+			return n
+		}
+
+		if t.Elem().IsKind(types.TUINT8) && args[1].Type().IsString() {
+			args[1] = DefaultLit(args[1], types.Types[types.TSTRING])
+			return n
+		}
+
+		args[1] = AssignConv(args[1], t.Underlying(), "append")
+		return n
+	}
+
+	as := args[1:]
+	for i, n := range as {
+		if n.Type() == nil {
+			continue
+		}
+		as[i] = AssignConv(n, t.Elem(), "append")
+		types.CheckSize(as[i].Type()) // ensure width is calculated for backend
+	}
+	return n
+}
+
+// tcClose typechecks an OCLOSE node.
+func tcClose(n *ir.UnaryExpr) ir.Node {
+	n.X = Expr(n.X)
+	n.X = DefaultLit(n.X, nil)
+	l := n.X
+	t := l.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+	if !t.IsChan() {
+		base.Errorf("invalid operation: %v (non-chan type %v)", n, t)
+		n.SetType(nil)
+		return n
+	}
+
+	if !t.ChanDir().CanSend() {
+		base.Errorf("invalid operation: %v (cannot close receive-only channel)", n)
+		n.SetType(nil)
+		return n
+	}
+	return n
+}
+
+// tcComplex typechecks an OCOMPLEX node.
+func tcComplex(n *ir.BinaryExpr) ir.Node {
+	l := Expr(n.X)
+	r := Expr(n.Y)
+	if l.Type() == nil || r.Type() == nil {
+		n.SetType(nil)
+		return n
+	}
+	l, r = defaultlit2(l, r, false)
+	if l.Type() == nil || r.Type() == nil {
+		n.SetType(nil)
+		return n
+	}
+	n.X = l
+	n.Y = r
+
+	if !types.Identical(l.Type(), r.Type()) {
+		base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type(), r.Type())
+		n.SetType(nil)
+		return n
+	}
+
+	var t *types.Type
+	switch l.Type().Kind() {
+	default:
+		base.Errorf("invalid operation: %v (arguments have type %v, expected floating-point)", n, l.Type())
+		n.SetType(nil)
+		return n
+
+	case types.TIDEAL:
+		t = types.UntypedComplex
+
+	case types.TFLOAT32:
+		t = types.Types[types.TCOMPLEX64]
+
+	case types.TFLOAT64:
+		t = types.Types[types.TCOMPLEX128]
+	}
+	n.SetType(t)
+	return n
+}
+
+// tcCopy typechecks an OCOPY node.
+func tcCopy(n *ir.BinaryExpr) ir.Node {
+	n.SetType(types.Types[types.TINT])
+	n.X = Expr(n.X)
+	n.X = DefaultLit(n.X, nil)
+	n.Y = Expr(n.Y)
+	n.Y = DefaultLit(n.Y, nil)
+	if n.X.Type() == nil || n.Y.Type() == nil {
+		n.SetType(nil)
+		return n
+	}
+
+	// copy([]byte, string)
+	if n.X.Type().IsSlice() && n.Y.Type().IsString() {
+		if types.Identical(n.X.Type().Elem(), types.ByteType) {
+			return n
+		}
+		base.Errorf("arguments to copy have different element types: %L and string", n.X.Type())
+		n.SetType(nil)
+		return n
+	}
+
+	if !n.X.Type().IsSlice() || !n.Y.Type().IsSlice() {
+		if !n.X.Type().IsSlice() && !n.Y.Type().IsSlice() {
+			base.Errorf("arguments to copy must be slices; have %L, %L", n.X.Type(), n.Y.Type())
+		} else if !n.X.Type().IsSlice() {
+			base.Errorf("first argument to copy should be slice; have %L", n.X.Type())
+		} else {
+			base.Errorf("second argument to copy should be slice or string; have %L", n.Y.Type())
+		}
+		n.SetType(nil)
+		return n
+	}
+
+	if !types.Identical(n.X.Type().Elem(), n.Y.Type().Elem()) {
+		base.Errorf("arguments to copy have different element types: %L and %L", n.X.Type(), n.Y.Type())
+		n.SetType(nil)
+		return n
+	}
+	return n
+}
+
+// tcDelete typechecks an ODELETE node.
+func tcDelete(n *ir.CallExpr) ir.Node {
+	typecheckargs(n)
+	args := n.Args
+	if len(args) == 0 {
+		base.Errorf("missing arguments to delete")
+		n.SetType(nil)
+		return n
+	}
+
+	if len(args) == 1 {
+		base.Errorf("missing second (key) argument to delete")
+		n.SetType(nil)
+		return n
+	}
+
+	if len(args) != 2 {
+		base.Errorf("too many arguments to delete")
+		n.SetType(nil)
+		return n
+	}
+
+	l := args[0]
+	r := args[1]
+	if l.Type() != nil && !l.Type().IsMap() {
+		base.Errorf("first argument to delete must be map; have %L", l.Type())
+		n.SetType(nil)
+		return n
+	}
+
+	args[1] = AssignConv(r, l.Type().Key(), "delete")
+	return n
+}
+
+// tcMake typechecks an OMAKE node.
+func tcMake(n *ir.CallExpr) ir.Node {
+	args := n.Args
+	if len(args) == 0 {
+		base.Errorf("missing argument to make")
+		n.SetType(nil)
+		return n
+	}
+
+	n.Args = nil
+	l := args[0]
+	l = typecheck(l, ctxType)
+	t := l.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+
+	i := 1
+	var nn ir.Node
+	switch t.Kind() {
+	default:
+		base.Errorf("cannot make type %v", t)
+		n.SetType(nil)
+		return n
+
+	case types.TSLICE:
+		if i >= len(args) {
+			base.Errorf("missing len argument to make(%v)", t)
+			n.SetType(nil)
+			return n
+		}
+
+		l = args[i]
+		i++
+		l = Expr(l)
+		var r ir.Node
+		if i < len(args) {
+			r = args[i]
+			i++
+			r = Expr(r)
+		}
+
+		if l.Type() == nil || (r != nil && r.Type() == nil) {
+			n.SetType(nil)
+			return n
+		}
+		if !checkmake(t, "len", &l) || r != nil && !checkmake(t, "cap", &r) {
+			n.SetType(nil)
+			return n
+		}
+		if ir.IsConst(l, constant.Int) && r != nil && ir.IsConst(r, constant.Int) && constant.Compare(l.Val(), token.GTR, r.Val()) {
+			base.Errorf("len larger than cap in make(%v)", t)
+			n.SetType(nil)
+			return n
+		}
+		nn = ir.NewMakeExpr(n.Pos(), ir.OMAKESLICE, l, r)
+
+	case types.TMAP:
+		if i < len(args) {
+			l = args[i]
+			i++
+			l = Expr(l)
+			l = DefaultLit(l, types.Types[types.TINT])
+			if l.Type() == nil {
+				n.SetType(nil)
+				return n
+			}
+			if !checkmake(t, "size", &l) {
+				n.SetType(nil)
+				return n
+			}
+		} else {
+			l = ir.NewInt(0)
+		}
+		nn = ir.NewMakeExpr(n.Pos(), ir.OMAKEMAP, l, nil)
+		nn.SetEsc(n.Esc())
+
+	case types.TCHAN:
+		l = nil
+		if i < len(args) {
+			l = args[i]
+			i++
+			l = Expr(l)
+			l = DefaultLit(l, types.Types[types.TINT])
+			if l.Type() == nil {
+				n.SetType(nil)
+				return n
+			}
+			if !checkmake(t, "buffer", &l) {
+				n.SetType(nil)
+				return n
+			}
+		} else {
+			l = ir.NewInt(0)
+		}
+		nn = ir.NewMakeExpr(n.Pos(), ir.OMAKECHAN, l, nil)
+	}
+
+	if i < len(args) {
+		base.Errorf("too many arguments to make(%v)", t)
+		n.SetType(nil)
+		return n
+	}
+
+	nn.SetType(t)
+	return nn
+}
+
+// tcMakeSliceCopy typechecks an OMAKESLICECOPY node.
+func tcMakeSliceCopy(n *ir.MakeExpr) ir.Node {
+	// Errors here are Fatalf instead of Errorf because only the compiler
+	// can construct an OMAKESLICECOPY node.
+	// Components used in OMAKESCLICECOPY that are supplied by parsed source code
+	// have already been typechecked in OMAKE and OCOPY earlier.
+	t := n.Type()
+
+	if t == nil {
+		base.Fatalf("no type specified for OMAKESLICECOPY")
+	}
+
+	if !t.IsSlice() {
+		base.Fatalf("invalid type %v for OMAKESLICECOPY", n.Type())
+	}
+
+	if n.Len == nil {
+		base.Fatalf("missing len argument for OMAKESLICECOPY")
+	}
+
+	if n.Cap == nil {
+		base.Fatalf("missing slice argument to copy for OMAKESLICECOPY")
+	}
+
+	n.Len = Expr(n.Len)
+	n.Cap = Expr(n.Cap)
+
+	n.Len = DefaultLit(n.Len, types.Types[types.TINT])
+
+	if !n.Len.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
+		base.Errorf("non-integer len argument in OMAKESLICECOPY")
+	}
+
+	if ir.IsConst(n.Len, constant.Int) {
+		if ir.ConstOverflow(n.Len.Val(), types.Types[types.TINT]) {
+			base.Fatalf("len for OMAKESLICECOPY too large")
+		}
+		if constant.Sign(n.Len.Val()) < 0 {
+			base.Fatalf("len for OMAKESLICECOPY must be non-negative")
+		}
+	}
+	return n
+}
+
+// tcNew typechecks an ONEW node.
+func tcNew(n *ir.UnaryExpr) ir.Node {
+	if n.X == nil {
+		// Fatalf because the OCALL above checked for us,
+		// so this must be an internally-generated mistake.
+		base.Fatalf("missing argument to new")
+	}
+	l := n.X
+	l = typecheck(l, ctxType)
+	t := l.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+	n.X = l
+	n.SetType(types.NewPtr(t))
+	return n
+}
+
+// tcPanic typechecks an OPANIC node.
+func tcPanic(n *ir.UnaryExpr) ir.Node {
+	n.X = Expr(n.X)
+	n.X = AssignConv(n.X, types.Types[types.TINTER], "argument to panic")
+	if n.X.Type() == nil {
+		n.SetType(nil)
+		return n
+	}
+	return n
+}
+
+// tcPrint typechecks an OPRINT or OPRINTN node.
+func tcPrint(n *ir.CallExpr) ir.Node {
+	typecheckargs(n)
+	ls := n.Args
+	for i1, n1 := range ls {
+		// Special case for print: int constant is int64, not int.
+		if ir.IsConst(n1, constant.Int) {
+			ls[i1] = DefaultLit(ls[i1], types.Types[types.TINT64])
+		} else {
+			ls[i1] = DefaultLit(ls[i1], nil)
+		}
+	}
+	return n
+}
+
+// tcRealImag typechecks an OREAL or OIMAG node.
+func tcRealImag(n *ir.UnaryExpr) ir.Node {
+	n.X = Expr(n.X)
+	l := n.X
+	t := l.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+
+	// Determine result type.
+	switch t.Kind() {
+	case types.TIDEAL:
+		n.SetType(types.UntypedFloat)
+	case types.TCOMPLEX64:
+		n.SetType(types.Types[types.TFLOAT32])
+	case types.TCOMPLEX128:
+		n.SetType(types.Types[types.TFLOAT64])
+	default:
+		base.Errorf("invalid argument %L for %v", l, n.Op())
+		n.SetType(nil)
+		return n
+	}
+	return n
+}
+
+// tcRecover typechecks an ORECOVER node.
+func tcRecover(n *ir.CallExpr) ir.Node {
+	if len(n.Args) != 0 {
+		base.Errorf("too many arguments to recover")
+		n.SetType(nil)
+		return n
+	}
+
+	n.SetType(types.Types[types.TINTER])
+	return n
+}
+
+// tcUnsafeAdd typechecks an OUNSAFEADD node.
+func tcUnsafeAdd(n *ir.BinaryExpr) *ir.BinaryExpr {
+	if !types.AllowsGoVersion(curpkg(), 1, 17) {
+		base.ErrorfVers("go1.17", "unsafe.Add")
+		n.SetType(nil)
+		return n
+	}
+
+	n.X = AssignConv(Expr(n.X), types.Types[types.TUNSAFEPTR], "argument to unsafe.Add")
+	n.Y = DefaultLit(Expr(n.Y), types.Types[types.TINT])
+	if n.X.Type() == nil || n.Y.Type() == nil {
+		n.SetType(nil)
+		return n
+	}
+	if !n.Y.Type().IsInteger() {
+		n.SetType(nil)
+		return n
+	}
+	n.SetType(n.X.Type())
+	return n
+}
+
+// tcUnsafeSlice typechecks an OUNSAFESLICE node.
+func tcUnsafeSlice(n *ir.BinaryExpr) *ir.BinaryExpr {
+	if !types.AllowsGoVersion(curpkg(), 1, 17) {
+		base.ErrorfVers("go1.17", "unsafe.Slice")
+		n.SetType(nil)
+		return n
+	}
+
+	n.X = Expr(n.X)
+	n.Y = Expr(n.Y)
+	if n.X.Type() == nil || n.Y.Type() == nil {
+		n.SetType(nil)
+		return n
+	}
+	t := n.X.Type()
+	if !t.IsPtr() {
+		base.Errorf("first argument to unsafe.Slice must be pointer; have %L", t)
+	} else if t.Elem().NotInHeap() {
+		// TODO(mdempsky): This can be relaxed, but should only affect the
+		// Go runtime itself. End users should only see //go:notinheap
+		// types due to incomplete C structs in cgo, and those types don't
+		// have a meaningful size anyway.
+		base.Errorf("unsafe.Slice of incomplete (or unallocatable) type not allowed")
+	}
+
+	if !checkunsafeslice(&n.Y) {
+		n.SetType(nil)
+		return n
+	}
+	n.SetType(types.NewSlice(t.Elem()))
+	return n
+}
diff --git a/src/cmd/compile/internal/typecheck/iexport.go b/src/cmd/compile/internal/typecheck/iexport.go
new file mode 100644
index 0000000..64d68ef
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/iexport.go
@@ -0,0 +1,1941 @@
+// 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.
+
+// Indexed package export.
+//
+// The indexed export data format is an evolution of the previous
+// binary export data format. Its chief contribution is introducing an
+// index table, which allows efficient random access of individual
+// declarations and inline function bodies. In turn, this allows
+// avoiding unnecessary work for compilation units that import large
+// packages.
+//
+//
+// The top-level data format is structured as:
+//
+//     Header struct {
+//         Tag        byte   // 'i'
+//         Version    uvarint
+//         StringSize uvarint
+//         DataSize   uvarint
+//     }
+//
+//     Strings [StringSize]byte
+//     Data    [DataSize]byte
+//
+//     MainIndex []struct{
+//         PkgPath   stringOff
+//         PkgName   stringOff
+//         PkgHeight uvarint
+//
+//         Decls []struct{
+//             Name   stringOff
+//             Offset declOff
+//         }
+//     }
+//
+//     Fingerprint [8]byte
+//
+// uvarint means a uint64 written out using uvarint encoding.
+//
+// []T means a uvarint followed by that many T objects. In other
+// words:
+//
+//     Len   uvarint
+//     Elems [Len]T
+//
+// stringOff means a uvarint that indicates an offset within the
+// Strings section. At that offset is another uvarint, followed by
+// that many bytes, which form the string value.
+//
+// declOff means a uvarint that indicates an offset within the Data
+// section where the associated declaration can be found.
+//
+//
+// There are five kinds of declarations, distinguished by their first
+// byte:
+//
+//     type Var struct {
+//         Tag  byte // 'V'
+//         Pos  Pos
+//         Type typeOff
+//     }
+//
+//     type Func struct {
+//         Tag       byte // 'F'
+//         Pos       Pos
+//         Signature Signature
+//     }
+//
+//     type Const struct {
+//         Tag   byte // 'C'
+//         Pos   Pos
+//         Value Value
+//     }
+//
+//     type Type struct {
+//         Tag        byte // 'T'
+//         Pos        Pos
+//         Underlying typeOff
+//
+//         Methods []struct{  // omitted if Underlying is an interface type
+//             Pos       Pos
+//             Name      stringOff
+//             Recv      Param
+//             Signature Signature
+//         }
+//     }
+//
+//     type Alias struct {
+//         Tag  byte // 'A'
+//         Pos  Pos
+//         Type typeOff
+//     }
+//
+//
+// typeOff means a uvarint that either indicates a predeclared type,
+// or an offset into the Data section. If the uvarint is less than
+// predeclReserved, then it indicates the index into the predeclared
+// types list (see predeclared in bexport.go for order). Otherwise,
+// subtracting predeclReserved yields the offset of a type descriptor.
+//
+// Value means a type and type-specific value. See
+// (*exportWriter).value for details.
+//
+//
+// There are nine kinds of type descriptors, distinguished by an itag:
+//
+//     type DefinedType struct {
+//         Tag     itag // definedType
+//         Name    stringOff
+//         PkgPath stringOff
+//     }
+//
+//     type PointerType struct {
+//         Tag  itag // pointerType
+//         Elem typeOff
+//     }
+//
+//     type SliceType struct {
+//         Tag  itag // sliceType
+//         Elem typeOff
+//     }
+//
+//     type ArrayType struct {
+//         Tag  itag // arrayType
+//         Len  uint64
+//         Elem typeOff
+//     }
+//
+//     type ChanType struct {
+//         Tag  itag   // chanType
+//         Dir  uint64 // 1 RecvOnly; 2 SendOnly; 3 SendRecv
+//         Elem typeOff
+//     }
+//
+//     type MapType struct {
+//         Tag  itag // mapType
+//         Key  typeOff
+//         Elem typeOff
+//     }
+//
+//     type FuncType struct {
+//         Tag       itag // signatureType
+//         PkgPath   stringOff
+//         Signature Signature
+//     }
+//
+//     type StructType struct {
+//         Tag     itag // structType
+//         PkgPath stringOff
+//         Fields []struct {
+//             Pos      Pos
+//             Name     stringOff
+//             Type     typeOff
+//             Embedded bool
+//             Note     stringOff
+//         }
+//     }
+//
+//     type InterfaceType struct {
+//         Tag     itag // interfaceType
+//         PkgPath stringOff
+//         Embeddeds []struct {
+//             Pos  Pos
+//             Type typeOff
+//         }
+//         Methods []struct {
+//             Pos       Pos
+//             Name      stringOff
+//             Signature Signature
+//         }
+//     }
+//
+//
+//     type Signature struct {
+//         Params   []Param
+//         Results  []Param
+//         Variadic bool  // omitted if Results is empty
+//     }
+//
+//     type Param struct {
+//         Pos  Pos
+//         Name stringOff
+//         Type typOff
+//     }
+//
+//
+// Pos encodes a file:line:column triple, incorporating a simple delta
+// encoding scheme within a data object. See exportWriter.pos for
+// details.
+//
+//
+// Compiler-specific details.
+//
+// cmd/compile writes out a second index for inline bodies and also
+// appends additional compiler-specific details after declarations.
+// Third-party tools are not expected to depend on these details and
+// they're expected to change much more rapidly, so they're omitted
+// here. See exportWriter's varExt/funcExt/etc methods for details.
+
+package typecheck
+
+import (
+	"bufio"
+	"bytes"
+	"crypto/md5"
+	"encoding/binary"
+	"fmt"
+	"go/constant"
+	"io"
+	"math/big"
+	"sort"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+	"cmd/internal/goobj"
+	"cmd/internal/src"
+)
+
+// Current indexed export format version. Increase with each format change.
+// 1: added column details to Pos
+// 0: Go1.11 encoding
+const iexportVersion = 1
+
+// predeclReserved is the number of type offsets reserved for types
+// implicitly declared in the universe block.
+const predeclReserved = 32
+
+// An itag distinguishes the kind of type that was written into the
+// indexed export format.
+type itag uint64
+
+const (
+	// Types
+	definedType itag = iota
+	pointerType
+	sliceType
+	arrayType
+	chanType
+	mapType
+	signatureType
+	structType
+	interfaceType
+)
+
+const (
+	debug = false
+	magic = 0x6742937dc293105
+)
+
+func WriteExports(out *bufio.Writer) {
+	p := iexporter{
+		allPkgs:     map[*types.Pkg]bool{},
+		stringIndex: map[string]uint64{},
+		declIndex:   map[*types.Sym]uint64{},
+		inlineIndex: map[*types.Sym]uint64{},
+		typIndex:    map[*types.Type]uint64{},
+	}
+
+	for i, pt := range predeclared() {
+		p.typIndex[pt] = uint64(i)
+	}
+	if len(p.typIndex) > predeclReserved {
+		base.Fatalf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)
+	}
+
+	// Initialize work queue with exported declarations.
+	for _, n := range Target.Exports {
+		p.pushDecl(n)
+	}
+
+	// Loop until no more work. We use a queue because while
+	// writing out inline bodies, we may discover additional
+	// declarations that are needed.
+	for !p.declTodo.Empty() {
+		p.doDecl(p.declTodo.PopLeft())
+	}
+
+	// Append indices to data0 section.
+	dataLen := uint64(p.data0.Len())
+	w := p.newWriter()
+	w.writeIndex(p.declIndex, true)
+	w.writeIndex(p.inlineIndex, false)
+	w.flush()
+
+	if *base.Flag.LowerV {
+		fmt.Printf("export: hdr strings %v, data %v, index %v\n", p.strings.Len(), dataLen, p.data0.Len())
+	}
+
+	// Assemble header.
+	var hdr intWriter
+	hdr.WriteByte('i')
+	hdr.uint64(iexportVersion)
+	hdr.uint64(uint64(p.strings.Len()))
+	hdr.uint64(dataLen)
+
+	// Flush output.
+	h := md5.New()
+	wr := io.MultiWriter(out, h)
+	io.Copy(wr, &hdr)
+	io.Copy(wr, &p.strings)
+	io.Copy(wr, &p.data0)
+
+	// Add fingerprint (used by linker object file).
+	// Attach this to the end, so tools (e.g. gcimporter) don't care.
+	copy(base.Ctxt.Fingerprint[:], h.Sum(nil)[:])
+	out.Write(base.Ctxt.Fingerprint[:])
+}
+
+// writeIndex writes out a symbol index. mainIndex indicates whether
+// we're writing out the main index, which is also read by
+// non-compiler tools and includes a complete package description
+// (i.e., name and height).
+func (w *exportWriter) writeIndex(index map[*types.Sym]uint64, mainIndex bool) {
+	// Build a map from packages to symbols from that package.
+	pkgSyms := map[*types.Pkg][]*types.Sym{}
+
+	// For the main index, make sure to include every package that
+	// we reference, even if we're not exporting (or reexporting)
+	// any symbols from it.
+	if mainIndex {
+		pkgSyms[types.LocalPkg] = nil
+		for pkg := range w.p.allPkgs {
+			pkgSyms[pkg] = nil
+		}
+	}
+
+	// Group symbols by package.
+	for sym := range index {
+		pkgSyms[sym.Pkg] = append(pkgSyms[sym.Pkg], sym)
+	}
+
+	// Sort packages by path.
+	var pkgs []*types.Pkg
+	for pkg := range pkgSyms {
+		pkgs = append(pkgs, pkg)
+	}
+	sort.Slice(pkgs, func(i, j int) bool {
+		return pkgs[i].Path < pkgs[j].Path
+	})
+
+	w.uint64(uint64(len(pkgs)))
+	for _, pkg := range pkgs {
+		w.string(pkg.Path)
+		if mainIndex {
+			w.string(pkg.Name)
+			w.uint64(uint64(pkg.Height))
+		}
+
+		// Sort symbols within a package by name.
+		syms := pkgSyms[pkg]
+		sort.Slice(syms, func(i, j int) bool {
+			return syms[i].Name < syms[j].Name
+		})
+
+		w.uint64(uint64(len(syms)))
+		for _, sym := range syms {
+			w.string(sym.Name)
+			w.uint64(index[sym])
+		}
+	}
+}
+
+type iexporter struct {
+	// allPkgs tracks all packages that have been referenced by
+	// the export data, so we can ensure to include them in the
+	// main index.
+	allPkgs map[*types.Pkg]bool
+
+	declTodo ir.NameQueue
+
+	strings     intWriter
+	stringIndex map[string]uint64
+
+	data0       intWriter
+	declIndex   map[*types.Sym]uint64
+	inlineIndex map[*types.Sym]uint64
+	typIndex    map[*types.Type]uint64
+}
+
+// stringOff returns the offset of s within the string section.
+// If not already present, it's added to the end.
+func (p *iexporter) stringOff(s string) uint64 {
+	off, ok := p.stringIndex[s]
+	if !ok {
+		off = uint64(p.strings.Len())
+		p.stringIndex[s] = off
+
+		if *base.Flag.LowerV {
+			fmt.Printf("export: str %v %.40q\n", off, s)
+		}
+
+		p.strings.uint64(uint64(len(s)))
+		p.strings.WriteString(s)
+	}
+	return off
+}
+
+// pushDecl adds n to the declaration work queue, if not already present.
+func (p *iexporter) pushDecl(n *ir.Name) {
+	if n.Sym() == nil || n.Sym().Def != n && n.Op() != ir.OTYPE {
+		base.Fatalf("weird Sym: %v, %v", n, n.Sym())
+	}
+
+	// Don't export predeclared declarations.
+	if n.Sym().Pkg == types.BuiltinPkg || n.Sym().Pkg == ir.Pkgs.Unsafe {
+		return
+	}
+
+	if _, ok := p.declIndex[n.Sym()]; ok {
+		return
+	}
+
+	p.declIndex[n.Sym()] = ^uint64(0) // mark n present in work queue
+	p.declTodo.PushRight(n)
+}
+
+// exportWriter handles writing out individual data section chunks.
+type exportWriter struct {
+	p *iexporter
+
+	data       intWriter
+	currPkg    *types.Pkg
+	prevFile   string
+	prevLine   int64
+	prevColumn int64
+
+	// dclIndex maps function-scoped declarations to an int used to refer to
+	// them later in the function. For local variables/params, the int is
+	// non-negative and in order of the appearance in the Func's Dcl list. For
+	// closure variables, the index is negative starting at -2.
+	dclIndex           map[*ir.Name]int
+	maxDclIndex        int
+	maxClosureVarIndex int
+}
+
+func (p *iexporter) doDecl(n *ir.Name) {
+	w := p.newWriter()
+	w.setPkg(n.Sym().Pkg, false)
+
+	switch n.Op() {
+	case ir.ONAME:
+		switch n.Class {
+		case ir.PEXTERN:
+			// Variable.
+			w.tag('V')
+			w.pos(n.Pos())
+			w.typ(n.Type())
+			w.varExt(n)
+
+		case ir.PFUNC:
+			if ir.IsMethod(n) {
+				base.Fatalf("unexpected method: %v", n)
+			}
+
+			// Function.
+			w.tag('F')
+			w.pos(n.Pos())
+			w.signature(n.Type())
+			w.funcExt(n)
+
+		default:
+			base.Fatalf("unexpected class: %v, %v", n, n.Class)
+		}
+
+	case ir.OLITERAL:
+		// TODO(mdempsky): Extend check to all declarations.
+		if n.Typecheck() == 0 {
+			base.FatalfAt(n.Pos(), "missed typecheck: %v", n)
+		}
+
+		// Constant.
+		w.tag('C')
+		w.pos(n.Pos())
+		w.value(n.Type(), n.Val())
+		w.constExt(n)
+
+	case ir.OTYPE:
+		if types.IsDotAlias(n.Sym()) {
+			// Alias.
+			w.tag('A')
+			w.pos(n.Pos())
+			w.typ(n.Type())
+			break
+		}
+
+		// Defined type.
+		w.tag('T')
+		w.pos(n.Pos())
+
+		underlying := n.Type().Underlying()
+		if underlying == types.ErrorType.Underlying() {
+			// For "type T error", use error as the
+			// underlying type instead of error's own
+			// underlying anonymous interface. This
+			// ensures consistency with how importers may
+			// declare error (e.g., go/types uses nil Pkg
+			// for predeclared objects).
+			underlying = types.ErrorType
+		}
+		w.typ(underlying)
+
+		t := n.Type()
+		if t.IsInterface() {
+			w.typeExt(t)
+			break
+		}
+
+		ms := t.Methods()
+		w.uint64(uint64(ms.Len()))
+		for _, m := range ms.Slice() {
+			w.pos(m.Pos)
+			w.selector(m.Sym)
+			w.param(m.Type.Recv())
+			w.signature(m.Type)
+		}
+
+		w.typeExt(t)
+		for _, m := range ms.Slice() {
+			w.methExt(m)
+		}
+
+	default:
+		base.Fatalf("unexpected node: %v", n)
+	}
+
+	w.finish("dcl", p.declIndex, n.Sym())
+}
+
+func (w *exportWriter) tag(tag byte) {
+	w.data.WriteByte(tag)
+}
+
+func (w *exportWriter) finish(what string, index map[*types.Sym]uint64, sym *types.Sym) {
+	off := w.flush()
+	if *base.Flag.LowerV {
+		fmt.Printf("export: %v %v %v\n", what, off, sym)
+	}
+	index[sym] = off
+}
+
+func (p *iexporter) doInline(f *ir.Name) {
+	w := p.newWriter()
+	w.setPkg(fnpkg(f), false)
+
+	w.dclIndex = make(map[*ir.Name]int, len(f.Func.Inl.Dcl))
+	w.funcBody(f.Func)
+
+	w.finish("inl", p.inlineIndex, f.Sym())
+}
+
+func (w *exportWriter) pos(pos src.XPos) {
+	p := base.Ctxt.PosTable.Pos(pos)
+	file := p.Base().AbsFilename()
+	line := int64(p.RelLine())
+	column := int64(p.RelCol())
+
+	// Encode position relative to the last position: column
+	// delta, then line delta, then file name. We reserve the
+	// bottom bit of the column and line deltas to encode whether
+	// the remaining fields are present.
+	//
+	// Note: Because data objects may be read out of order (or not
+	// at all), we can only apply delta encoding within a single
+	// object. This is handled implicitly by tracking prevFile,
+	// prevLine, and prevColumn as fields of exportWriter.
+
+	deltaColumn := (column - w.prevColumn) << 1
+	deltaLine := (line - w.prevLine) << 1
+
+	if file != w.prevFile {
+		deltaLine |= 1
+	}
+	if deltaLine != 0 {
+		deltaColumn |= 1
+	}
+
+	w.int64(deltaColumn)
+	if deltaColumn&1 != 0 {
+		w.int64(deltaLine)
+		if deltaLine&1 != 0 {
+			w.string(file)
+		}
+	}
+
+	w.prevFile = file
+	w.prevLine = line
+	w.prevColumn = column
+}
+
+func (w *exportWriter) pkg(pkg *types.Pkg) {
+	// TODO(mdempsky): Add flag to types.Pkg to mark pseudo-packages.
+	if pkg == ir.Pkgs.Go {
+		base.Fatalf("export of pseudo-package: %q", pkg.Path)
+	}
+
+	// Ensure any referenced packages are declared in the main index.
+	w.p.allPkgs[pkg] = true
+
+	w.string(pkg.Path)
+}
+
+func (w *exportWriter) qualifiedIdent(n *ir.Name) {
+	// Ensure any referenced declarations are written out too.
+	w.p.pushDecl(n)
+
+	s := n.Sym()
+	w.string(s.Name)
+	w.pkg(s.Pkg)
+}
+
+func (w *exportWriter) selector(s *types.Sym) {
+	if w.currPkg == nil {
+		base.Fatalf("missing currPkg")
+	}
+
+	// If the selector being written is unexported, it comes with a package qualifier.
+	// If the selector being written is exported, it is not package-qualified.
+	// See the spec: https://golang.org/ref/spec#Uniqueness_of_identifiers
+	// As an optimization, we don't actually write the package every time - instead we
+	// call setPkg before a group of selectors (all of which must have the same package qualifier).
+	pkg := w.currPkg
+	if types.IsExported(s.Name) {
+		pkg = types.LocalPkg
+	}
+	if s.Pkg != pkg {
+		base.Fatalf("package mismatch in selector: %v in package %q, but want %q", s, s.Pkg.Path, pkg.Path)
+	}
+
+	w.string(s.Name)
+}
+
+func (w *exportWriter) typ(t *types.Type) {
+	w.data.uint64(w.p.typOff(t))
+}
+
+// The "exotic" functions in this section encode a wider range of
+// items than the standard encoding functions above. These include
+// types that do not appear in declarations, only in code, such as
+// method types. These methods need to be separate from the standard
+// encoding functions because we don't want to modify the encoding
+// generated by the standard functions (because that exported
+// information is read by tools besides the compiler).
+
+// exoticType exports a type to the writer.
+func (w *exportWriter) exoticType(t *types.Type) {
+	switch {
+	case t == nil:
+		// Calls-as-statements have no type.
+		w.data.uint64(exoticTypeNil)
+	case t.IsStruct() && t.StructType().Funarg != types.FunargNone:
+		// These are weird structs for representing tuples of types returned
+		// by multi-return functions.
+		// They don't fit the standard struct type mold. For instance,
+		// they don't have any package info.
+		w.data.uint64(exoticTypeTuple)
+		w.uint64(uint64(t.StructType().Funarg))
+		w.uint64(uint64(t.NumFields()))
+		for _, f := range t.FieldSlice() {
+			w.pos(f.Pos)
+			s := f.Sym
+			if s == nil {
+				w.uint64(0)
+			} else if s.Pkg == nil {
+				w.uint64(exoticTypeSymNoPkg)
+				w.string(s.Name)
+			} else {
+				w.uint64(exoticTypeSymWithPkg)
+				w.pkg(s.Pkg)
+				w.string(s.Name)
+			}
+			w.typ(f.Type)
+			if f.Embedded != 0 || f.Note != "" {
+				panic("extra info in funarg struct field")
+			}
+		}
+	case t.Kind() == types.TFUNC && t.Recv() != nil:
+		w.data.uint64(exoticTypeRecv)
+		// interface method types have a fake receiver type.
+		isFakeRecv := t.Recv().Type == types.FakeRecvType()
+		w.bool(isFakeRecv)
+		if !isFakeRecv {
+			w.exoticParam(t.Recv())
+		}
+		w.exoticSignature(t)
+
+	default:
+		// A regular type.
+		w.data.uint64(exoticTypeRegular)
+		w.typ(t)
+	}
+}
+
+const (
+	exoticTypeNil = iota
+	exoticTypeTuple
+	exoticTypeRecv
+	exoticTypeRegular
+)
+const (
+	exoticTypeSymNil = iota
+	exoticTypeSymNoPkg
+	exoticTypeSymWithPkg
+)
+
+// Export a selector, but one whose package may not match
+// the package being compiled. This is a separate function
+// because the standard selector() serialization format is fixed
+// by the go/types reader. This one can only be used during
+// inline/generic body exporting.
+func (w *exportWriter) exoticSelector(s *types.Sym) {
+	pkg := w.currPkg
+	if types.IsExported(s.Name) {
+		pkg = types.LocalPkg
+	}
+
+	w.string(s.Name)
+	if s.Pkg == pkg {
+		w.uint64(0)
+	} else {
+		w.uint64(1)
+		w.pkg(s.Pkg)
+	}
+}
+
+func (w *exportWriter) exoticSignature(t *types.Type) {
+	hasPkg := t.Pkg() != nil
+	w.bool(hasPkg)
+	if hasPkg {
+		w.pkg(t.Pkg())
+	}
+	w.exoticParamList(t.Params().FieldSlice())
+	w.exoticParamList(t.Results().FieldSlice())
+}
+
+func (w *exportWriter) exoticParamList(fs []*types.Field) {
+	w.uint64(uint64(len(fs)))
+	for _, f := range fs {
+		w.exoticParam(f)
+	}
+
+}
+func (w *exportWriter) exoticParam(f *types.Field) {
+	w.pos(f.Pos)
+	w.exoticSym(f.Sym)
+	w.uint64(uint64(f.Offset))
+	w.exoticType(f.Type)
+	w.bool(f.IsDDD())
+}
+
+func (w *exportWriter) exoticField(f *types.Field) {
+	w.pos(f.Pos)
+	w.exoticSym(f.Sym)
+	w.uint64(uint64(f.Offset))
+	w.exoticType(f.Type)
+	w.string(f.Note)
+}
+
+func (w *exportWriter) exoticSym(s *types.Sym) {
+	if s == nil {
+		w.string("")
+		return
+	}
+	if s.Name == "" {
+		base.Fatalf("empty symbol name")
+	}
+	w.string(s.Name)
+	if !types.IsExported(s.Name) {
+		w.pkg(s.Pkg)
+	}
+}
+
+func (p *iexporter) newWriter() *exportWriter {
+	return &exportWriter{p: p}
+}
+
+func (w *exportWriter) flush() uint64 {
+	off := uint64(w.p.data0.Len())
+	io.Copy(&w.p.data0, &w.data)
+	return off
+}
+
+func (p *iexporter) typOff(t *types.Type) uint64 {
+	off, ok := p.typIndex[t]
+	if !ok {
+		w := p.newWriter()
+		w.doTyp(t)
+		rawOff := w.flush()
+		if *base.Flag.LowerV {
+			fmt.Printf("export: typ %v %v\n", rawOff, t)
+		}
+		off = predeclReserved + rawOff
+		p.typIndex[t] = off
+	}
+	return off
+}
+
+func (w *exportWriter) startType(k itag) {
+	w.data.uint64(uint64(k))
+}
+
+func (w *exportWriter) doTyp(t *types.Type) {
+	if t.Sym() != nil {
+		if t.Sym().Pkg == types.BuiltinPkg || t.Sym().Pkg == ir.Pkgs.Unsafe {
+			base.Fatalf("builtin type missing from typIndex: %v", t)
+		}
+
+		w.startType(definedType)
+		w.qualifiedIdent(t.Obj().(*ir.Name))
+		return
+	}
+
+	switch t.Kind() {
+	case types.TPTR:
+		w.startType(pointerType)
+		w.typ(t.Elem())
+
+	case types.TSLICE:
+		w.startType(sliceType)
+		w.typ(t.Elem())
+
+	case types.TARRAY:
+		w.startType(arrayType)
+		w.uint64(uint64(t.NumElem()))
+		w.typ(t.Elem())
+
+	case types.TCHAN:
+		w.startType(chanType)
+		w.uint64(uint64(t.ChanDir()))
+		w.typ(t.Elem())
+
+	case types.TMAP:
+		w.startType(mapType)
+		w.typ(t.Key())
+		w.typ(t.Elem())
+
+	case types.TFUNC:
+		w.startType(signatureType)
+		w.setPkg(t.Pkg(), true)
+		w.signature(t)
+
+	case types.TSTRUCT:
+		w.startType(structType)
+		w.setPkg(t.Pkg(), true)
+
+		w.uint64(uint64(t.NumFields()))
+		for _, f := range t.FieldSlice() {
+			w.pos(f.Pos)
+			w.selector(f.Sym)
+			w.typ(f.Type)
+			w.bool(f.Embedded != 0)
+			w.string(f.Note)
+		}
+
+	case types.TINTER:
+		var embeddeds, methods []*types.Field
+		for _, m := range t.Methods().Slice() {
+			if m.Sym != nil {
+				methods = append(methods, m)
+			} else {
+				embeddeds = append(embeddeds, m)
+			}
+		}
+
+		w.startType(interfaceType)
+		w.setPkg(t.Pkg(), true)
+
+		w.uint64(uint64(len(embeddeds)))
+		for _, f := range embeddeds {
+			w.pos(f.Pos)
+			w.typ(f.Type)
+		}
+
+		w.uint64(uint64(len(methods)))
+		for _, f := range methods {
+			w.pos(f.Pos)
+			w.selector(f.Sym)
+			w.signature(f.Type)
+		}
+
+	default:
+		base.Fatalf("unexpected type: %v", t)
+	}
+}
+
+func (w *exportWriter) setPkg(pkg *types.Pkg, write bool) {
+	if pkg == types.NoPkg {
+		base.Fatalf("missing pkg")
+	}
+
+	if write {
+		w.pkg(pkg)
+	}
+
+	w.currPkg = pkg
+}
+
+func (w *exportWriter) signature(t *types.Type) {
+	w.paramList(t.Params().FieldSlice())
+	w.paramList(t.Results().FieldSlice())
+	if n := t.Params().NumFields(); n > 0 {
+		w.bool(t.Params().Field(n - 1).IsDDD())
+	}
+}
+
+func (w *exportWriter) paramList(fs []*types.Field) {
+	w.uint64(uint64(len(fs)))
+	for _, f := range fs {
+		w.param(f)
+	}
+}
+
+func (w *exportWriter) param(f *types.Field) {
+	w.pos(f.Pos)
+	w.localIdent(types.OrigSym(f.Sym))
+	w.typ(f.Type)
+}
+
+func constTypeOf(typ *types.Type) constant.Kind {
+	switch typ {
+	case types.UntypedInt, types.UntypedRune:
+		return constant.Int
+	case types.UntypedFloat:
+		return constant.Float
+	case types.UntypedComplex:
+		return constant.Complex
+	}
+
+	switch typ.Kind() {
+	case types.TBOOL:
+		return constant.Bool
+	case types.TSTRING:
+		return constant.String
+	case types.TINT, types.TINT8, types.TINT16, types.TINT32, types.TINT64,
+		types.TUINT, types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64, types.TUINTPTR:
+		return constant.Int
+	case types.TFLOAT32, types.TFLOAT64:
+		return constant.Float
+	case types.TCOMPLEX64, types.TCOMPLEX128:
+		return constant.Complex
+	}
+
+	base.Fatalf("unexpected constant type: %v", typ)
+	return 0
+}
+
+func (w *exportWriter) value(typ *types.Type, v constant.Value) {
+	ir.AssertValidTypeForConst(typ, v)
+	w.typ(typ)
+
+	// Each type has only one admissible constant representation,
+	// so we could type switch directly on v.U here. However,
+	// switching on the type increases symmetry with import logic
+	// and provides a useful consistency check.
+
+	switch constTypeOf(typ) {
+	case constant.Bool:
+		w.bool(constant.BoolVal(v))
+	case constant.String:
+		w.string(constant.StringVal(v))
+	case constant.Int:
+		w.mpint(v, typ)
+	case constant.Float:
+		w.mpfloat(v, typ)
+	case constant.Complex:
+		w.mpfloat(constant.Real(v), typ)
+		w.mpfloat(constant.Imag(v), typ)
+	}
+}
+
+func intSize(typ *types.Type) (signed bool, maxBytes uint) {
+	if typ.IsUntyped() {
+		return true, ir.ConstPrec / 8
+	}
+
+	switch typ.Kind() {
+	case types.TFLOAT32, types.TCOMPLEX64:
+		return true, 3
+	case types.TFLOAT64, types.TCOMPLEX128:
+		return true, 7
+	}
+
+	signed = typ.IsSigned()
+	maxBytes = uint(typ.Size())
+
+	// The go/types API doesn't expose sizes to importers, so they
+	// don't know how big these types are.
+	switch typ.Kind() {
+	case types.TINT, types.TUINT, types.TUINTPTR:
+		maxBytes = 8
+	}
+
+	return
+}
+
+// mpint exports a multi-precision integer.
+//
+// For unsigned types, small values are written out as a single
+// byte. Larger values are written out as a length-prefixed big-endian
+// byte string, where the length prefix is encoded as its complement.
+// For example, bytes 0, 1, and 2 directly represent the integer
+// values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-,
+// 2-, and 3-byte big-endian string follow.
+//
+// Encoding for signed types use the same general approach as for
+// unsigned types, except small values use zig-zag encoding and the
+// bottom bit of length prefix byte for large values is reserved as a
+// sign bit.
+//
+// The exact boundary between small and large encodings varies
+// according to the maximum number of bytes needed to encode a value
+// of type typ. As a special case, 8-bit types are always encoded as a
+// single byte.
+func (w *exportWriter) mpint(x constant.Value, typ *types.Type) {
+	signed, maxBytes := intSize(typ)
+
+	negative := constant.Sign(x) < 0
+	if !signed && negative {
+		base.Fatalf("negative unsigned integer; type %v, value %v", typ, x)
+	}
+
+	b := constant.Bytes(x) // little endian
+	for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
+		b[i], b[j] = b[j], b[i]
+	}
+
+	if len(b) > 0 && b[0] == 0 {
+		base.Fatalf("leading zeros")
+	}
+	if uint(len(b)) > maxBytes {
+		base.Fatalf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)
+	}
+
+	maxSmall := 256 - maxBytes
+	if signed {
+		maxSmall = 256 - 2*maxBytes
+	}
+	if maxBytes == 1 {
+		maxSmall = 256
+	}
+
+	// Check if x can use small value encoding.
+	if len(b) <= 1 {
+		var ux uint
+		if len(b) == 1 {
+			ux = uint(b[0])
+		}
+		if signed {
+			ux <<= 1
+			if negative {
+				ux--
+			}
+		}
+		if ux < maxSmall {
+			w.data.WriteByte(byte(ux))
+			return
+		}
+	}
+
+	n := 256 - uint(len(b))
+	if signed {
+		n = 256 - 2*uint(len(b))
+		if negative {
+			n |= 1
+		}
+	}
+	if n < maxSmall || n >= 256 {
+		base.Fatalf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)
+	}
+
+	w.data.WriteByte(byte(n))
+	w.data.Write(b)
+}
+
+// mpfloat exports a multi-precision floating point number.
+//
+// The number's value is decomposed into mantissa × 2**exponent, where
+// mantissa is an integer. The value is written out as mantissa (as a
+// multi-precision integer) and then the exponent, except exponent is
+// omitted if mantissa is zero.
+func (w *exportWriter) mpfloat(v constant.Value, typ *types.Type) {
+	f := ir.BigFloat(v)
+	if f.IsInf() {
+		base.Fatalf("infinite constant")
+	}
+
+	// Break into f = mant × 2**exp, with 0.5 <= mant < 1.
+	var mant big.Float
+	exp := int64(f.MantExp(&mant))
+
+	// Scale so that mant is an integer.
+	prec := mant.MinPrec()
+	mant.SetMantExp(&mant, int(prec))
+	exp -= int64(prec)
+
+	manti, acc := mant.Int(nil)
+	if acc != big.Exact {
+		base.Fatalf("mantissa scaling failed for %f (%s)", f, acc)
+	}
+	w.mpint(constant.Make(manti), typ)
+	if manti.Sign() != 0 {
+		w.int64(exp)
+	}
+}
+
+func (w *exportWriter) mprat(v constant.Value) {
+	r, ok := constant.Val(v).(*big.Rat)
+	if !w.bool(ok) {
+		return
+	}
+	// TODO(mdempsky): Come up with a more efficient binary
+	// encoding before bumping iexportVersion to expose to
+	// gcimporter.
+	w.string(r.String())
+}
+
+func (w *exportWriter) bool(b bool) bool {
+	var x uint64
+	if b {
+		x = 1
+	}
+	w.uint64(x)
+	return b
+}
+
+func (w *exportWriter) int64(x int64)   { w.data.int64(x) }
+func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) }
+func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) }
+
+// Compiler-specific extensions.
+
+func (w *exportWriter) constExt(n *ir.Name) {
+	// Internally, we now represent untyped float and complex
+	// constants with infinite-precision rational numbers using
+	// go/constant, but the "public" export data format known to
+	// gcimporter only supports 512-bit floating point constants.
+	// In case rationals turn out to be a bad idea and we want to
+	// switch back to fixed-precision constants, for now we
+	// continue writing out the 512-bit truncation in the public
+	// data section, and write the exact, rational constant in the
+	// compiler's extension data. Also, we only need to worry
+	// about exporting rationals for declared constants, because
+	// constants that appear in an expression will already have
+	// been coerced to a concrete, fixed-precision type.
+	//
+	// Eventually, assuming we stick with using rationals, we
+	// should bump iexportVersion to support rationals, and do the
+	// whole gcimporter update song-and-dance.
+	//
+	// TODO(mdempsky): Prepare vocals for that.
+
+	switch n.Type() {
+	case types.UntypedFloat:
+		w.mprat(n.Val())
+	case types.UntypedComplex:
+		v := n.Val()
+		w.mprat(constant.Real(v))
+		w.mprat(constant.Imag(v))
+	}
+}
+
+func (w *exportWriter) varExt(n *ir.Name) {
+	w.linkname(n.Sym())
+	w.symIdx(n.Sym())
+}
+
+func (w *exportWriter) funcExt(n *ir.Name) {
+	w.linkname(n.Sym())
+	w.symIdx(n.Sym())
+
+	// Record definition ABI so cross-ABI calls can be direct.
+	// This is important for the performance of calling some
+	// common functions implemented in assembly (e.g., bytealg).
+	w.uint64(uint64(n.Func.ABI))
+
+	w.uint64(uint64(n.Func.Pragma))
+
+	// Escape analysis.
+	for _, fs := range &types.RecvsParams {
+		for _, f := range fs(n.Type()).FieldSlice() {
+			w.string(f.Note)
+		}
+	}
+
+	// Inline body.
+	if n.Func.Inl != nil {
+		w.uint64(1 + uint64(n.Func.Inl.Cost))
+		if n.Func.ExportInline() {
+			w.p.doInline(n)
+		}
+
+		// Endlineno for inlined function.
+		w.pos(n.Func.Endlineno)
+	} else {
+		w.uint64(0)
+	}
+}
+
+func (w *exportWriter) methExt(m *types.Field) {
+	w.bool(m.Nointerface())
+	w.funcExt(m.Nname.(*ir.Name))
+}
+
+func (w *exportWriter) linkname(s *types.Sym) {
+	w.string(s.Linkname)
+}
+
+func (w *exportWriter) symIdx(s *types.Sym) {
+	lsym := s.Linksym()
+	if lsym.PkgIdx > goobj.PkgIdxSelf || (lsym.PkgIdx == goobj.PkgIdxInvalid && !lsym.Indexed()) || s.Linkname != "" {
+		// Don't export index for non-package symbols, linkname'd symbols,
+		// and symbols without an index. They can only be referenced by
+		// name.
+		w.int64(-1)
+	} else {
+		// For a defined symbol, export its index.
+		// For re-exporting an imported symbol, pass its index through.
+		w.int64(int64(lsym.SymIdx))
+	}
+}
+
+func (w *exportWriter) typeExt(t *types.Type) {
+	// Export whether this type is marked notinheap.
+	w.bool(t.NotInHeap())
+	// For type T, export the index of type descriptor symbols of T and *T.
+	if i, ok := typeSymIdx[t]; ok {
+		w.int64(i[0])
+		w.int64(i[1])
+		return
+	}
+	w.symIdx(types.TypeSym(t))
+	w.symIdx(types.TypeSym(t.PtrTo()))
+}
+
+// Inline bodies.
+
+func (w *exportWriter) writeNames(dcl []*ir.Name) {
+	w.int64(int64(len(dcl)))
+	for i, n := range dcl {
+		w.pos(n.Pos())
+		w.localIdent(n.Sym())
+		w.typ(n.Type())
+		w.dclIndex[n] = w.maxDclIndex + i
+	}
+	w.maxDclIndex += len(dcl)
+}
+
+func (w *exportWriter) funcBody(fn *ir.Func) {
+	//fmt.Printf("Exporting %s\n", fn.Nname.Sym().Name)
+	w.writeNames(fn.Inl.Dcl)
+
+	w.stmtList(fn.Inl.Body)
+}
+
+func (w *exportWriter) stmtList(list []ir.Node) {
+	for _, n := range list {
+		w.node(n)
+	}
+	w.op(ir.OEND)
+}
+
+func (w *exportWriter) node(n ir.Node) {
+	if ir.OpPrec[n.Op()] < 0 {
+		w.stmt(n)
+	} else {
+		w.expr(n)
+	}
+}
+
+// Caution: stmt will emit more than one node for statement nodes n that have a non-empty
+// n.Ninit and where n cannot have a natural init section (such as in "if", "for", etc.).
+func (w *exportWriter) stmt(n ir.Node) {
+	if len(n.Init()) > 0 && !ir.StmtWithInit(n.Op()) {
+		// can't use stmtList here since we don't want the final OEND
+		for _, n := range n.Init() {
+			w.stmt(n)
+		}
+	}
+
+	switch n.Op() {
+	case ir.OBLOCK:
+		// No OBLOCK in export data.
+		// Inline content into this statement list,
+		// like the init list above.
+		// (At the moment neither the parser nor the typechecker
+		// generate OBLOCK nodes except to denote an empty
+		// function body, although that may change.)
+		n := n.(*ir.BlockStmt)
+		for _, n := range n.List {
+			w.stmt(n)
+		}
+
+	case ir.ODCL:
+		n := n.(*ir.Decl)
+		if ir.IsBlank(n.X) {
+			return // blank declarations not useful to importers
+		}
+		w.op(ir.ODCL)
+		w.localName(n.X)
+
+	case ir.OAS:
+		// Don't export "v = <N>" initializing statements, hope they're always
+		// preceded by the DCL which will be re-parsed and typecheck to reproduce
+		// the "v = <N>" again.
+		n := n.(*ir.AssignStmt)
+		if n.Y != nil {
+			w.op(ir.OAS)
+			w.pos(n.Pos())
+			w.expr(n.X)
+			w.expr(n.Y)
+		}
+
+	case ir.OASOP:
+		n := n.(*ir.AssignOpStmt)
+		w.op(ir.OASOP)
+		w.pos(n.Pos())
+		w.op(n.AsOp)
+		w.expr(n.X)
+		if w.bool(!n.IncDec) {
+			w.expr(n.Y)
+		}
+
+	case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
+		n := n.(*ir.AssignListStmt)
+		if go117ExportTypes {
+			w.op(n.Op())
+		} else {
+			w.op(ir.OAS2)
+		}
+		w.pos(n.Pos())
+		w.exprList(n.Lhs)
+		w.exprList(n.Rhs)
+
+	case ir.ORETURN:
+		n := n.(*ir.ReturnStmt)
+		w.op(ir.ORETURN)
+		w.pos(n.Pos())
+		w.exprList(n.Results)
+
+	// case ORETJMP:
+	// 	unreachable - generated by compiler for trampoline routines
+
+	case ir.OGO, ir.ODEFER:
+		n := n.(*ir.GoDeferStmt)
+		w.op(n.Op())
+		w.pos(n.Pos())
+		w.expr(n.Call)
+
+	case ir.OIF:
+		n := n.(*ir.IfStmt)
+		w.op(ir.OIF)
+		w.pos(n.Pos())
+		w.stmtList(n.Init())
+		w.expr(n.Cond)
+		w.stmtList(n.Body)
+		w.stmtList(n.Else)
+
+	case ir.OFOR:
+		n := n.(*ir.ForStmt)
+		w.op(ir.OFOR)
+		w.pos(n.Pos())
+		w.stmtList(n.Init())
+		w.exprsOrNil(n.Cond, n.Post)
+		w.stmtList(n.Body)
+
+	case ir.ORANGE:
+		n := n.(*ir.RangeStmt)
+		w.op(ir.ORANGE)
+		w.pos(n.Pos())
+		w.exprsOrNil(n.Key, n.Value)
+		w.expr(n.X)
+		w.stmtList(n.Body)
+
+	case ir.OSELECT:
+		n := n.(*ir.SelectStmt)
+		w.op(n.Op())
+		w.pos(n.Pos())
+		w.stmtList(n.Init())
+		w.commList(n.Cases)
+
+	case ir.OSWITCH:
+		n := n.(*ir.SwitchStmt)
+		w.op(n.Op())
+		w.pos(n.Pos())
+		w.stmtList(n.Init())
+		w.exprsOrNil(n.Tag, nil)
+		w.caseList(n.Cases, isNamedTypeSwitch(n.Tag))
+
+	// case OCASE:
+	//	handled by caseList
+
+	case ir.OFALL:
+		n := n.(*ir.BranchStmt)
+		w.op(ir.OFALL)
+		w.pos(n.Pos())
+
+	case ir.OBREAK, ir.OCONTINUE, ir.OGOTO, ir.OLABEL:
+		w.op(n.Op())
+		w.pos(n.Pos())
+		label := ""
+		if sym := n.Sym(); sym != nil {
+			label = sym.Name
+		}
+		w.string(label)
+
+	default:
+		base.Fatalf("exporter: CANNOT EXPORT: %v\nPlease notify gri@\n", n.Op())
+	}
+}
+
+func isNamedTypeSwitch(x ir.Node) bool {
+	guard, ok := x.(*ir.TypeSwitchGuard)
+	return ok && guard.Tag != nil
+}
+
+func (w *exportWriter) caseList(cases []*ir.CaseClause, namedTypeSwitch bool) {
+	w.uint64(uint64(len(cases)))
+	for _, cas := range cases {
+		w.pos(cas.Pos())
+		w.stmtList(cas.List)
+		if namedTypeSwitch {
+			w.localName(cas.Var)
+		}
+		w.stmtList(cas.Body)
+	}
+}
+
+func (w *exportWriter) commList(cases []*ir.CommClause) {
+	w.uint64(uint64(len(cases)))
+	for _, cas := range cases {
+		w.pos(cas.Pos())
+		w.node(cas.Comm)
+		w.stmtList(cas.Body)
+	}
+}
+
+func (w *exportWriter) exprList(list ir.Nodes) {
+	for _, n := range list {
+		w.expr(n)
+	}
+	w.op(ir.OEND)
+}
+
+func simplifyForExport(n ir.Node) ir.Node {
+	switch n.Op() {
+	case ir.OPAREN:
+		n := n.(*ir.ParenExpr)
+		return simplifyForExport(n.X)
+	}
+	return n
+}
+
+func (w *exportWriter) expr(n ir.Node) {
+	n = simplifyForExport(n)
+	switch n.Op() {
+	// expressions
+	// (somewhat closely following the structure of exprfmt in fmt.go)
+	case ir.ONIL:
+		n := n.(*ir.NilExpr)
+		if !n.Type().HasNil() {
+			base.Fatalf("unexpected type for nil: %v", n.Type())
+		}
+		w.op(ir.ONIL)
+		w.pos(n.Pos())
+		w.typ(n.Type())
+
+	case ir.OLITERAL:
+		w.op(ir.OLITERAL)
+		w.pos(n.Pos())
+		w.value(n.Type(), n.Val())
+
+	case ir.ONAME:
+		// Package scope name.
+		n := n.(*ir.Name)
+		if (n.Class == ir.PEXTERN || n.Class == ir.PFUNC) && !ir.IsBlank(n) {
+			w.op(ir.ONONAME)
+			w.qualifiedIdent(n)
+			if go117ExportTypes {
+				w.typ(n.Type())
+			}
+			break
+		}
+
+		// Function scope name.
+		// We don't need a type here, as the type will be provided at the
+		// declaration of n.
+		w.op(ir.ONAME)
+		w.localName(n)
+
+	// case OPACK, ONONAME:
+	// 	should have been resolved by typechecking - handled by default case
+
+	case ir.OTYPE:
+		w.op(ir.OTYPE)
+		w.typ(n.Type())
+
+	case ir.OTYPESW:
+		n := n.(*ir.TypeSwitchGuard)
+		w.op(ir.OTYPESW)
+		w.pos(n.Pos())
+		var s *types.Sym
+		if n.Tag != nil {
+			if n.Tag.Op() != ir.ONONAME {
+				base.Fatalf("expected ONONAME, got %v", n.Tag)
+			}
+			s = n.Tag.Sym()
+		}
+		w.localIdent(s) // declared pseudo-variable, if any
+		w.expr(n.X)
+
+	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
+	// 	should have been resolved by typechecking - handled by default case
+
+	case ir.OCLOSURE:
+		n := n.(*ir.ClosureExpr)
+		w.op(ir.OCLOSURE)
+		w.pos(n.Pos())
+		w.signature(n.Type())
+
+		// Write out id for the Outer of each conditional variable. The
+		// conditional variable itself for this closure will be re-created
+		// during import.
+		w.int64(int64(len(n.Func.ClosureVars)))
+		for i, cv := range n.Func.ClosureVars {
+			w.pos(cv.Pos())
+			w.localName(cv.Outer)
+			// Closure variable (which will be re-created during
+			// import) is given via a negative id, starting at -2,
+			// which is used to refer to it later in the function
+			// during export. -1 represents blanks.
+			w.dclIndex[cv] = -(i + 2) - w.maxClosureVarIndex
+		}
+		w.maxClosureVarIndex += len(n.Func.ClosureVars)
+
+		// like w.funcBody(n.Func), but not for .Inl
+		w.writeNames(n.Func.Dcl)
+		w.stmtList(n.Func.Body)
+
+	// case OCOMPLIT:
+	// 	should have been resolved by typechecking - handled by default case
+
+	case ir.OPTRLIT:
+		n := n.(*ir.AddrExpr)
+		if go117ExportTypes {
+			w.op(ir.OPTRLIT)
+		} else {
+			w.op(ir.OADDR)
+		}
+		w.pos(n.Pos())
+		w.expr(n.X)
+		if go117ExportTypes {
+			w.typ(n.Type())
+		}
+
+	case ir.OSTRUCTLIT:
+		n := n.(*ir.CompLitExpr)
+		w.op(ir.OSTRUCTLIT)
+		w.pos(n.Pos())
+		w.typ(n.Type())
+		w.fieldList(n.List) // special handling of field names
+
+	case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
+		n := n.(*ir.CompLitExpr)
+		if go117ExportTypes {
+			w.op(n.Op())
+		} else {
+			w.op(ir.OCOMPLIT)
+		}
+		w.pos(n.Pos())
+		w.typ(n.Type())
+		w.exprList(n.List)
+		if go117ExportTypes && n.Op() == ir.OSLICELIT {
+			w.uint64(uint64(n.Len))
+		}
+	case ir.OKEY:
+		n := n.(*ir.KeyExpr)
+		w.op(ir.OKEY)
+		w.pos(n.Pos())
+		w.expr(n.Key)
+		w.expr(n.Value)
+
+	// case OSTRUCTKEY:
+	//	unreachable - handled in case OSTRUCTLIT by elemList
+
+	case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH, ir.OCALLPART, ir.OMETHEXPR:
+		n := n.(*ir.SelectorExpr)
+		if go117ExportTypes {
+			if n.Op() == ir.OXDOT {
+				base.Fatalf("shouldn't encounter XDOT  in new exporter")
+			}
+			w.op(n.Op())
+		} else {
+			w.op(ir.OXDOT)
+		}
+		w.pos(n.Pos())
+		w.expr(n.X)
+		w.exoticSelector(n.Sel)
+		if go117ExportTypes {
+			w.exoticType(n.Type())
+			if n.Op() == ir.ODOT || n.Op() == ir.ODOTPTR || n.Op() == ir.ODOTINTER {
+				w.exoticField(n.Selection)
+			}
+			// n.Selection is not required for OMETHEXPR, ODOTMETH, and OCALLPART. It will
+			// be reconstructed during import.
+		}
+
+	case ir.ODOTTYPE, ir.ODOTTYPE2:
+		n := n.(*ir.TypeAssertExpr)
+		if go117ExportTypes {
+			w.op(n.Op())
+		} else {
+			w.op(ir.ODOTTYPE)
+		}
+		w.pos(n.Pos())
+		w.expr(n.X)
+		w.typ(n.Type())
+
+	case ir.OINDEX, ir.OINDEXMAP:
+		n := n.(*ir.IndexExpr)
+		if go117ExportTypes {
+			w.op(n.Op())
+		} else {
+			w.op(ir.OINDEX)
+		}
+		w.pos(n.Pos())
+		w.expr(n.X)
+		w.expr(n.Index)
+		if go117ExportTypes {
+			w.typ(n.Type())
+			if n.Op() == ir.OINDEXMAP {
+				w.bool(n.Assigned)
+			}
+		}
+
+	case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR:
+		n := n.(*ir.SliceExpr)
+		if go117ExportTypes {
+			w.op(n.Op())
+		} else {
+			w.op(ir.OSLICE)
+		}
+		w.pos(n.Pos())
+		w.expr(n.X)
+		w.exprsOrNil(n.Low, n.High)
+		if go117ExportTypes {
+			w.typ(n.Type())
+		}
+
+	case ir.OSLICE3, ir.OSLICE3ARR:
+		n := n.(*ir.SliceExpr)
+		if go117ExportTypes {
+			w.op(n.Op())
+		} else {
+			w.op(ir.OSLICE3)
+		}
+		w.pos(n.Pos())
+		w.expr(n.X)
+		w.exprsOrNil(n.Low, n.High)
+		w.expr(n.Max)
+		if go117ExportTypes {
+			w.typ(n.Type())
+		}
+
+	case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE:
+		// treated like other builtin calls (see e.g., OREAL)
+		n := n.(*ir.BinaryExpr)
+		w.op(n.Op())
+		w.pos(n.Pos())
+		w.expr(n.X)
+		w.expr(n.Y)
+		if go117ExportTypes {
+			w.typ(n.Type())
+		} else {
+			w.op(ir.OEND)
+		}
+
+	case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
+		n := n.(*ir.ConvExpr)
+		if go117ExportTypes {
+			w.op(n.Op())
+		} else {
+			w.op(ir.OCONV)
+		}
+		w.pos(n.Pos())
+		w.typ(n.Type())
+		w.expr(n.X)
+
+	case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
+		n := n.(*ir.UnaryExpr)
+		w.op(n.Op())
+		w.pos(n.Pos())
+		w.expr(n.X)
+		if go117ExportTypes {
+			if n.Op() != ir.OPANIC {
+				w.typ(n.Type())
+			}
+		} else {
+			w.op(ir.OEND)
+		}
+
+	case ir.OAPPEND, ir.ODELETE, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
+		n := n.(*ir.CallExpr)
+		w.op(n.Op())
+		w.pos(n.Pos())
+		w.exprList(n.Args) // emits terminating OEND
+		// only append() calls may contain '...' arguments
+		if n.Op() == ir.OAPPEND {
+			w.bool(n.IsDDD)
+		} else if n.IsDDD {
+			base.Fatalf("exporter: unexpected '...' with %v call", n.Op())
+		}
+		if go117ExportTypes {
+			if n.Op() != ir.ODELETE && n.Op() != ir.OPRINT && n.Op() != ir.OPRINTN {
+				w.typ(n.Type())
+			}
+		}
+
+	case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
+		n := n.(*ir.CallExpr)
+		if go117ExportTypes {
+			w.op(n.Op())
+		} else {
+			w.op(ir.OCALL)
+		}
+		w.pos(n.Pos())
+		w.stmtList(n.Init())
+		w.expr(n.X)
+		w.exprList(n.Args)
+		w.bool(n.IsDDD)
+		if go117ExportTypes {
+			w.exoticType(n.Type())
+			w.uint64(uint64(n.Use))
+		}
+
+	case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
+		n := n.(*ir.MakeExpr)
+		w.op(n.Op()) // must keep separate from OMAKE for importer
+		w.pos(n.Pos())
+		w.typ(n.Type())
+		switch {
+		default:
+			// empty list
+			w.op(ir.OEND)
+		case n.Cap != nil:
+			w.expr(n.Len)
+			w.expr(n.Cap)
+			w.op(ir.OEND)
+		case n.Len != nil && (n.Op() == ir.OMAKESLICE || !n.Len.Type().IsUntyped()):
+			// Note: the extra conditional exists because make(T) for
+			// T a map or chan type, gets an untyped zero added as
+			// an argument. Don't serialize that argument here.
+			w.expr(n.Len)
+			w.op(ir.OEND)
+		case n.Len != nil && go117ExportTypes:
+			w.expr(n.Len)
+			w.op(ir.OEND)
+		}
+
+	// unary expressions
+	case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV:
+		n := n.(*ir.UnaryExpr)
+		w.op(n.Op())
+		w.pos(n.Pos())
+		w.expr(n.X)
+		if go117ExportTypes {
+			w.typ(n.Type())
+		}
+
+	case ir.OADDR:
+		n := n.(*ir.AddrExpr)
+		w.op(n.Op())
+		w.pos(n.Pos())
+		w.expr(n.X)
+		if go117ExportTypes {
+			w.typ(n.Type())
+		}
+
+	case ir.ODEREF:
+		n := n.(*ir.StarExpr)
+		w.op(n.Op())
+		w.pos(n.Pos())
+		w.expr(n.X)
+		if go117ExportTypes {
+			w.typ(n.Type())
+		}
+
+	case ir.OSEND:
+		n := n.(*ir.SendStmt)
+		w.op(n.Op())
+		w.pos(n.Pos())
+		w.expr(n.Chan)
+		w.expr(n.Value)
+
+	// binary expressions
+	case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
+		ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR:
+		n := n.(*ir.BinaryExpr)
+		w.op(n.Op())
+		w.pos(n.Pos())
+		w.expr(n.X)
+		w.expr(n.Y)
+		if go117ExportTypes {
+			w.typ(n.Type())
+		}
+
+	case ir.OANDAND, ir.OOROR:
+		n := n.(*ir.LogicalExpr)
+		w.op(n.Op())
+		w.pos(n.Pos())
+		w.expr(n.X)
+		w.expr(n.Y)
+		if go117ExportTypes {
+			w.typ(n.Type())
+		}
+
+	case ir.OADDSTR:
+		n := n.(*ir.AddStringExpr)
+		w.op(ir.OADDSTR)
+		w.pos(n.Pos())
+		w.exprList(n.List)
+		if go117ExportTypes {
+			w.typ(n.Type())
+		}
+
+	case ir.ODCLCONST:
+		// if exporting, DCLCONST should just be removed as its usage
+		// has already been replaced with literals
+
+	default:
+		base.Fatalf("cannot export %v (%d) node\n"+
+			"\t==> please file an issue and assign to gri@", n.Op(), int(n.Op()))
+	}
+}
+
+func (w *exportWriter) op(op ir.Op) {
+	if debug {
+		w.uint64(magic)
+	}
+	w.uint64(uint64(op))
+}
+
+func (w *exportWriter) exprsOrNil(a, b ir.Node) {
+	ab := 0
+	if a != nil {
+		ab |= 1
+	}
+	if b != nil {
+		ab |= 2
+	}
+	w.uint64(uint64(ab))
+	if ab&1 != 0 {
+		w.expr(a)
+	}
+	if ab&2 != 0 {
+		w.node(b)
+	}
+}
+
+func (w *exportWriter) fieldList(list ir.Nodes) {
+	w.uint64(uint64(len(list)))
+	for _, n := range list {
+		n := n.(*ir.StructKeyExpr)
+		w.pos(n.Pos())
+		w.selector(n.Field)
+		w.expr(n.Value)
+		if go117ExportTypes {
+			w.uint64(uint64(n.Offset))
+		}
+	}
+}
+
+func (w *exportWriter) localName(n *ir.Name) {
+	if ir.IsBlank(n) {
+		w.int64(-1)
+		return
+	}
+
+	i, ok := w.dclIndex[n]
+	if !ok {
+		base.FatalfAt(n.Pos(), "missing from dclIndex: %+v", n)
+	}
+	w.int64(int64(i))
+}
+
+func (w *exportWriter) localIdent(s *types.Sym) {
+	if w.currPkg == nil {
+		base.Fatalf("missing currPkg")
+	}
+
+	// Anonymous parameters.
+	if s == nil {
+		w.string("")
+		return
+	}
+
+	name := s.Name
+	if name == "_" {
+		w.string("_")
+		return
+	}
+
+	// TODO(mdempsky): Fix autotmp hack.
+	if i := strings.LastIndex(name, "."); i >= 0 && !strings.HasPrefix(name, ".autotmp_") {
+		base.Fatalf("unexpected dot in identifier: %v", name)
+	}
+
+	if s.Pkg != w.currPkg {
+		base.Fatalf("weird package in name: %v => %v from %q, not %q", s, name, s.Pkg.Path, w.currPkg.Path)
+	}
+
+	w.string(name)
+}
+
+type intWriter struct {
+	bytes.Buffer
+}
+
+func (w *intWriter) int64(x int64) {
+	var buf [binary.MaxVarintLen64]byte
+	n := binary.PutVarint(buf[:], x)
+	w.Write(buf[:n])
+}
+
+func (w *intWriter) uint64(x uint64) {
+	var buf [binary.MaxVarintLen64]byte
+	n := binary.PutUvarint(buf[:], x)
+	w.Write(buf[:n])
+}
+
+// If go117ExportTypes is true, then we write type information when
+// exporting function bodies, so those function bodies don't need to
+// be re-typechecked on import.
+// This flag adds some other info to the serialized stream as well
+// which was previously recomputed during typechecking, like
+// specializing opcodes (e.g. OXDOT to ODOTPTR) and ancillary
+// information (e.g. length field for OSLICELIT).
+const go117ExportTypes = true
+const Go117ExportTypes = go117ExportTypes
diff --git a/src/cmd/compile/internal/typecheck/iimport.go b/src/cmd/compile/internal/typecheck/iimport.go
new file mode 100644
index 0000000..37f5a7b
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/iimport.go
@@ -0,0 +1,1546 @@
+// 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.
+
+// Indexed package import.
+// See iexport.go for the export data format.
+
+package typecheck
+
+import (
+	"encoding/binary"
+	"fmt"
+	"go/constant"
+	"io"
+	"math/big"
+	"os"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+	"cmd/internal/bio"
+	"cmd/internal/goobj"
+	"cmd/internal/obj"
+	"cmd/internal/src"
+)
+
+// An iimporterAndOffset identifies an importer and an offset within
+// its data section.
+type iimporterAndOffset struct {
+	p   *iimporter
+	off uint64
+}
+
+var (
+	// DeclImporter maps from imported identifiers to an importer
+	// and offset where that identifier's declaration can be read.
+	DeclImporter = map[*types.Sym]iimporterAndOffset{}
+
+	// inlineImporter is like DeclImporter, but for inline bodies
+	// for function and method symbols.
+	inlineImporter = map[*types.Sym]iimporterAndOffset{}
+)
+
+// expandDecl returns immediately if n is already a Name node. Otherwise, n should
+// be an Ident node, and expandDecl reads in the definition of the specified
+// identifier from the appropriate package.
+func expandDecl(n ir.Node) ir.Node {
+	if n, ok := n.(*ir.Name); ok {
+		return n
+	}
+
+	id := n.(*ir.Ident)
+	if n := id.Sym().PkgDef(); n != nil {
+		return n.(*ir.Name)
+	}
+
+	r := importReaderFor(id.Sym(), DeclImporter)
+	if r == nil {
+		// Can happen if user tries to reference an undeclared name.
+		return n
+	}
+
+	return r.doDecl(n.Sym())
+}
+
+// ImportBody reads in the dcls and body of an imported function (which should not
+// yet have been read in).
+func ImportBody(fn *ir.Func) {
+	if fn.Inl.Body != nil {
+		base.Fatalf("%v already has inline body", fn)
+	}
+
+	r := importReaderFor(fn.Nname.Sym(), inlineImporter)
+	if r == nil {
+		base.Fatalf("missing import reader for %v", fn)
+	}
+
+	if inimport {
+		base.Fatalf("recursive inimport")
+	}
+	inimport = true
+	r.doInline(fn)
+	inimport = false
+}
+
+func importReaderFor(sym *types.Sym, importers map[*types.Sym]iimporterAndOffset) *importReader {
+	x, ok := importers[sym]
+	if !ok {
+		return nil
+	}
+
+	return x.p.newReader(x.off, sym.Pkg)
+}
+
+type intReader struct {
+	*bio.Reader
+	pkg *types.Pkg
+}
+
+func (r *intReader) int64() int64 {
+	i, err := binary.ReadVarint(r.Reader)
+	if err != nil {
+		base.Errorf("import %q: read error: %v", r.pkg.Path, err)
+		base.ErrorExit()
+	}
+	return i
+}
+
+func (r *intReader) uint64() uint64 {
+	i, err := binary.ReadUvarint(r.Reader)
+	if err != nil {
+		base.Errorf("import %q: read error: %v", r.pkg.Path, err)
+		base.ErrorExit()
+	}
+	return i
+}
+
+func ReadImports(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintType) {
+	ird := &intReader{in, pkg}
+
+	version := ird.uint64()
+	if version != iexportVersion {
+		base.Errorf("import %q: unknown export format version %d", pkg.Path, version)
+		base.ErrorExit()
+	}
+
+	sLen := ird.uint64()
+	dLen := ird.uint64()
+
+	// Map string (and data) section into memory as a single large
+	// string. This reduces heap fragmentation and allows
+	// returning individual substrings very efficiently.
+	data, err := mapFile(in.File(), in.Offset(), int64(sLen+dLen))
+	if err != nil {
+		base.Errorf("import %q: mapping input: %v", pkg.Path, err)
+		base.ErrorExit()
+	}
+	stringData := data[:sLen]
+	declData := data[sLen:]
+
+	in.MustSeek(int64(sLen+dLen), os.SEEK_CUR)
+
+	p := &iimporter{
+		ipkg: pkg,
+
+		pkgCache:     map[uint64]*types.Pkg{},
+		posBaseCache: map[uint64]*src.PosBase{},
+		typCache:     map[uint64]*types.Type{},
+
+		stringData: stringData,
+		declData:   declData,
+	}
+
+	for i, pt := range predeclared() {
+		p.typCache[uint64(i)] = pt
+	}
+
+	// Declaration index.
+	for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
+		pkg := p.pkgAt(ird.uint64())
+		pkgName := p.stringAt(ird.uint64())
+		pkgHeight := int(ird.uint64())
+		if pkg.Name == "" {
+			pkg.Name = pkgName
+			pkg.Height = pkgHeight
+			types.NumImport[pkgName]++
+
+			// TODO(mdempsky): This belongs somewhere else.
+			pkg.Lookup("_").Def = ir.BlankNode
+		} else {
+			if pkg.Name != pkgName {
+				base.Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
+			}
+			if pkg.Height != pkgHeight {
+				base.Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path)
+			}
+		}
+
+		for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
+			s := pkg.Lookup(p.stringAt(ird.uint64()))
+			off := ird.uint64()
+
+			if _, ok := DeclImporter[s]; !ok {
+				DeclImporter[s] = iimporterAndOffset{p, off}
+			}
+		}
+	}
+
+	// Inline body index.
+	for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
+		pkg := p.pkgAt(ird.uint64())
+
+		for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
+			s := pkg.Lookup(p.stringAt(ird.uint64()))
+			off := ird.uint64()
+
+			if _, ok := inlineImporter[s]; !ok {
+				inlineImporter[s] = iimporterAndOffset{p, off}
+			}
+		}
+	}
+
+	// Fingerprint.
+	_, err = io.ReadFull(in, fingerprint[:])
+	if err != nil {
+		base.Errorf("import %s: error reading fingerprint", pkg.Path)
+		base.ErrorExit()
+	}
+	return fingerprint
+}
+
+type iimporter struct {
+	ipkg *types.Pkg
+
+	pkgCache     map[uint64]*types.Pkg
+	posBaseCache map[uint64]*src.PosBase
+	typCache     map[uint64]*types.Type
+
+	stringData string
+	declData   string
+}
+
+func (p *iimporter) stringAt(off uint64) string {
+	var x [binary.MaxVarintLen64]byte
+	n := copy(x[:], p.stringData[off:])
+
+	slen, n := binary.Uvarint(x[:n])
+	if n <= 0 {
+		base.Fatalf("varint failed")
+	}
+	spos := off + uint64(n)
+	return p.stringData[spos : spos+slen]
+}
+
+func (p *iimporter) posBaseAt(off uint64) *src.PosBase {
+	if posBase, ok := p.posBaseCache[off]; ok {
+		return posBase
+	}
+
+	file := p.stringAt(off)
+	posBase := src.NewFileBase(file, file)
+	p.posBaseCache[off] = posBase
+	return posBase
+}
+
+func (p *iimporter) pkgAt(off uint64) *types.Pkg {
+	if pkg, ok := p.pkgCache[off]; ok {
+		return pkg
+	}
+
+	pkg := p.ipkg
+	if pkgPath := p.stringAt(off); pkgPath != "" {
+		pkg = types.NewPkg(pkgPath, "")
+	}
+	p.pkgCache[off] = pkg
+	return pkg
+}
+
+// An importReader keeps state for reading an individual imported
+// object (declaration or inline body).
+type importReader struct {
+	strings.Reader
+	p *iimporter
+
+	currPkg    *types.Pkg
+	prevBase   *src.PosBase
+	prevLine   int64
+	prevColumn int64
+
+	// curfn is the current function we're importing into.
+	curfn *ir.Func
+	// Slice of all dcls for function, including any interior closures
+	allDcls        []*ir.Name
+	allClosureVars []*ir.Name
+}
+
+func (p *iimporter) newReader(off uint64, pkg *types.Pkg) *importReader {
+	r := &importReader{
+		p:       p,
+		currPkg: pkg,
+	}
+	// (*strings.Reader).Reset wasn't added until Go 1.7, and we
+	// need to build with Go 1.4.
+	r.Reader = *strings.NewReader(p.declData[off:])
+	return r
+}
+
+func (r *importReader) string() string        { return r.p.stringAt(r.uint64()) }
+func (r *importReader) posBase() *src.PosBase { return r.p.posBaseAt(r.uint64()) }
+func (r *importReader) pkg() *types.Pkg       { return r.p.pkgAt(r.uint64()) }
+
+func (r *importReader) setPkg() {
+	r.currPkg = r.pkg()
+}
+
+func (r *importReader) doDecl(sym *types.Sym) *ir.Name {
+	tag := r.byte()
+	pos := r.pos()
+
+	switch tag {
+	case 'A':
+		typ := r.typ()
+
+		return importalias(r.p.ipkg, pos, sym, typ)
+
+	case 'C':
+		typ := r.typ()
+		val := r.value(typ)
+
+		n := importconst(r.p.ipkg, pos, sym, typ, val)
+		r.constExt(n)
+		return n
+
+	case 'F':
+		typ := r.signature(nil)
+
+		n := importfunc(r.p.ipkg, pos, sym, typ)
+		r.funcExt(n)
+		return n
+
+	case 'T':
+		// Types can be recursive. We need to setup a stub
+		// declaration before recursing.
+		n := importtype(r.p.ipkg, pos, sym)
+		t := n.Type()
+
+		// We also need to defer width calculations until
+		// after the underlying type has been assigned.
+		types.DeferCheckSize()
+		underlying := r.typ()
+		t.SetUnderlying(underlying)
+		types.ResumeCheckSize()
+
+		if underlying.IsInterface() {
+			r.typeExt(t)
+			return n
+		}
+
+		ms := make([]*types.Field, r.uint64())
+		for i := range ms {
+			mpos := r.pos()
+			msym := r.selector()
+			recv := r.param()
+			mtyp := r.signature(recv)
+
+			// MethodSym already marked m.Sym as a function.
+			m := ir.NewNameAt(mpos, ir.MethodSym(recv.Type, msym))
+			m.Class = ir.PFUNC
+			m.SetType(mtyp)
+
+			m.Func = ir.NewFunc(mpos)
+			m.Func.Nname = m
+
+			f := types.NewField(mpos, msym, mtyp)
+			f.Nname = m
+			ms[i] = f
+		}
+		t.Methods().Set(ms)
+
+		r.typeExt(t)
+		for _, m := range ms {
+			r.methExt(m)
+		}
+		return n
+
+	case 'V':
+		typ := r.typ()
+
+		n := importvar(r.p.ipkg, pos, sym, typ)
+		r.varExt(n)
+		return n
+
+	default:
+		base.Fatalf("unexpected tag: %v", tag)
+		panic("unreachable")
+	}
+}
+
+func (p *importReader) value(typ *types.Type) constant.Value {
+	switch constTypeOf(typ) {
+	case constant.Bool:
+		return constant.MakeBool(p.bool())
+	case constant.String:
+		return constant.MakeString(p.string())
+	case constant.Int:
+		var i big.Int
+		p.mpint(&i, typ)
+		return constant.Make(&i)
+	case constant.Float:
+		return p.float(typ)
+	case constant.Complex:
+		return makeComplex(p.float(typ), p.float(typ))
+	}
+
+	base.Fatalf("unexpected value type: %v", typ)
+	panic("unreachable")
+}
+
+func (p *importReader) mpint(x *big.Int, typ *types.Type) {
+	signed, maxBytes := intSize(typ)
+
+	maxSmall := 256 - maxBytes
+	if signed {
+		maxSmall = 256 - 2*maxBytes
+	}
+	if maxBytes == 1 {
+		maxSmall = 256
+	}
+
+	n, _ := p.ReadByte()
+	if uint(n) < maxSmall {
+		v := int64(n)
+		if signed {
+			v >>= 1
+			if n&1 != 0 {
+				v = ^v
+			}
+		}
+		x.SetInt64(v)
+		return
+	}
+
+	v := -n
+	if signed {
+		v = -(n &^ 1) >> 1
+	}
+	if v < 1 || uint(v) > maxBytes {
+		base.Fatalf("weird decoding: %v, %v => %v", n, signed, v)
+	}
+	b := make([]byte, v)
+	p.Read(b)
+	x.SetBytes(b)
+	if signed && n&1 != 0 {
+		x.Neg(x)
+	}
+}
+
+func (p *importReader) float(typ *types.Type) constant.Value {
+	var mant big.Int
+	p.mpint(&mant, typ)
+	var f big.Float
+	f.SetInt(&mant)
+	if f.Sign() != 0 {
+		f.SetMantExp(&f, int(p.int64()))
+	}
+	return constant.Make(&f)
+}
+
+func (p *importReader) mprat(orig constant.Value) constant.Value {
+	if !p.bool() {
+		return orig
+	}
+	var rat big.Rat
+	rat.SetString(p.string())
+	return constant.Make(&rat)
+}
+
+func (r *importReader) ident(selector bool) *types.Sym {
+	name := r.string()
+	if name == "" {
+		return nil
+	}
+	pkg := r.currPkg
+	if selector && types.IsExported(name) {
+		pkg = types.LocalPkg
+	}
+	return pkg.Lookup(name)
+}
+
+func (r *importReader) localIdent() *types.Sym { return r.ident(false) }
+func (r *importReader) selector() *types.Sym   { return r.ident(true) }
+
+func (r *importReader) qualifiedIdent() *ir.Ident {
+	name := r.string()
+	pkg := r.pkg()
+	sym := pkg.Lookup(name)
+	return ir.NewIdent(src.NoXPos, sym)
+}
+
+func (r *importReader) pos() src.XPos {
+	delta := r.int64()
+	r.prevColumn += delta >> 1
+	if delta&1 != 0 {
+		delta = r.int64()
+		r.prevLine += delta >> 1
+		if delta&1 != 0 {
+			r.prevBase = r.posBase()
+		}
+	}
+
+	if (r.prevBase == nil || r.prevBase.AbsFilename() == "") && r.prevLine == 0 && r.prevColumn == 0 {
+		// TODO(mdempsky): Remove once we reliably write
+		// position information for all nodes.
+		return src.NoXPos
+	}
+
+	if r.prevBase == nil {
+		base.Fatalf("missing posbase")
+	}
+	pos := src.MakePos(r.prevBase, uint(r.prevLine), uint(r.prevColumn))
+	return base.Ctxt.PosTable.XPos(pos)
+}
+
+func (r *importReader) typ() *types.Type {
+	return r.p.typAt(r.uint64())
+}
+
+func (r *importReader) exoticType() *types.Type {
+	switch r.uint64() {
+	case exoticTypeNil:
+		return nil
+	case exoticTypeTuple:
+		funarg := types.Funarg(r.uint64())
+		n := r.uint64()
+		fs := make([]*types.Field, n)
+		for i := range fs {
+			pos := r.pos()
+			var sym *types.Sym
+			switch r.uint64() {
+			case exoticTypeSymNil:
+				sym = nil
+			case exoticTypeSymNoPkg:
+				sym = types.NoPkg.Lookup(r.string())
+			case exoticTypeSymWithPkg:
+				pkg := r.pkg()
+				sym = pkg.Lookup(r.string())
+			default:
+				base.Fatalf("unknown symbol kind")
+			}
+			typ := r.typ()
+			f := types.NewField(pos, sym, typ)
+			fs[i] = f
+		}
+		t := types.NewStruct(types.NoPkg, fs)
+		t.StructType().Funarg = funarg
+		return t
+	case exoticTypeRecv:
+		var rcvr *types.Field
+		if r.bool() { // isFakeRecv
+			rcvr = fakeRecvField()
+		} else {
+			rcvr = r.exoticParam()
+		}
+		return r.exoticSignature(rcvr)
+	case exoticTypeRegular:
+		return r.typ()
+	default:
+		base.Fatalf("bad kind of call type")
+		return nil
+	}
+}
+
+func (r *importReader) exoticSelector() *types.Sym {
+	name := r.string()
+	if name == "" {
+		return nil
+	}
+	pkg := r.currPkg
+	if types.IsExported(name) {
+		pkg = types.LocalPkg
+	}
+	if r.uint64() != 0 {
+		pkg = r.pkg()
+	}
+	return pkg.Lookup(name)
+}
+
+func (r *importReader) exoticSignature(recv *types.Field) *types.Type {
+	var pkg *types.Pkg
+	if r.bool() { // hasPkg
+		pkg = r.pkg()
+	}
+	params := r.exoticParamList()
+	results := r.exoticParamList()
+	return types.NewSignature(pkg, recv, nil, params, results)
+}
+
+func (r *importReader) exoticParamList() []*types.Field {
+	n := r.uint64()
+	fs := make([]*types.Field, n)
+	for i := range fs {
+		fs[i] = r.exoticParam()
+	}
+	return fs
+}
+
+func (r *importReader) exoticParam() *types.Field {
+	pos := r.pos()
+	sym := r.exoticSym()
+	off := r.uint64()
+	typ := r.exoticType()
+	ddd := r.bool()
+	f := types.NewField(pos, sym, typ)
+	f.Offset = int64(off)
+	if sym != nil {
+		f.Nname = ir.NewNameAt(pos, sym)
+	}
+	f.SetIsDDD(ddd)
+	return f
+}
+
+func (r *importReader) exoticField() *types.Field {
+	pos := r.pos()
+	sym := r.exoticSym()
+	off := r.uint64()
+	typ := r.exoticType()
+	note := r.string()
+	f := types.NewField(pos, sym, typ)
+	f.Offset = int64(off)
+	if sym != nil {
+		f.Nname = ir.NewNameAt(pos, sym)
+	}
+	f.Note = note
+	return f
+}
+
+func (r *importReader) exoticSym() *types.Sym {
+	name := r.string()
+	if name == "" {
+		return nil
+	}
+	var pkg *types.Pkg
+	if types.IsExported(name) {
+		pkg = types.LocalPkg
+	} else {
+		pkg = r.pkg()
+	}
+	return pkg.Lookup(name)
+}
+
+func (p *iimporter) typAt(off uint64) *types.Type {
+	t, ok := p.typCache[off]
+	if !ok {
+		if off < predeclReserved {
+			base.Fatalf("predeclared type missing from cache: %d", off)
+		}
+		t = p.newReader(off-predeclReserved, nil).typ1()
+		// Ensure size is calculated for imported types. Since CL 283313, the compiler
+		// does not compile the function immediately when it sees them. Instead, funtions
+		// are pushed to compile queue, then draining from the queue for compiling.
+		// During this process, the size calculation is disabled, so it is not safe for
+		// calculating size during SSA generation anymore. See issue #44732.
+		types.CheckSize(t)
+		p.typCache[off] = t
+	}
+	return t
+}
+
+func (r *importReader) typ1() *types.Type {
+	switch k := r.kind(); k {
+	default:
+		base.Fatalf("unexpected kind tag in %q: %v", r.p.ipkg.Path, k)
+		return nil
+
+	case definedType:
+		// We might be called from within doInline, in which
+		// case Sym.Def can point to declared parameters
+		// instead of the top-level types. Also, we don't
+		// support inlining functions with local defined
+		// types. Therefore, this must be a package-scope
+		// type.
+		n := expandDecl(r.qualifiedIdent())
+		if n.Op() != ir.OTYPE {
+			base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n)
+		}
+		return n.Type()
+	case pointerType:
+		return types.NewPtr(r.typ())
+	case sliceType:
+		return types.NewSlice(r.typ())
+	case arrayType:
+		n := r.uint64()
+		return types.NewArray(r.typ(), int64(n))
+	case chanType:
+		dir := types.ChanDir(r.uint64())
+		return types.NewChan(r.typ(), dir)
+	case mapType:
+		return types.NewMap(r.typ(), r.typ())
+
+	case signatureType:
+		r.setPkg()
+		return r.signature(nil)
+
+	case structType:
+		r.setPkg()
+
+		fs := make([]*types.Field, r.uint64())
+		for i := range fs {
+			pos := r.pos()
+			sym := r.selector()
+			typ := r.typ()
+			emb := r.bool()
+			note := r.string()
+
+			f := types.NewField(pos, sym, typ)
+			if emb {
+				f.Embedded = 1
+			}
+			f.Note = note
+			fs[i] = f
+		}
+
+		return types.NewStruct(r.currPkg, fs)
+
+	case interfaceType:
+		r.setPkg()
+
+		embeddeds := make([]*types.Field, r.uint64())
+		for i := range embeddeds {
+			pos := r.pos()
+			typ := r.typ()
+
+			embeddeds[i] = types.NewField(pos, nil, typ)
+		}
+
+		methods := make([]*types.Field, r.uint64())
+		for i := range methods {
+			pos := r.pos()
+			sym := r.selector()
+			typ := r.signature(fakeRecvField())
+
+			methods[i] = types.NewField(pos, sym, typ)
+		}
+
+		t := types.NewInterface(r.currPkg, append(embeddeds, methods...))
+
+		// Ensure we expand the interface in the frontend (#25055).
+		types.CheckSize(t)
+		return t
+	}
+}
+
+func (r *importReader) kind() itag {
+	return itag(r.uint64())
+}
+
+func (r *importReader) signature(recv *types.Field) *types.Type {
+	params := r.paramList()
+	results := r.paramList()
+	if n := len(params); n > 0 {
+		params[n-1].SetIsDDD(r.bool())
+	}
+	return types.NewSignature(r.currPkg, recv, nil, params, results)
+}
+
+func (r *importReader) paramList() []*types.Field {
+	fs := make([]*types.Field, r.uint64())
+	for i := range fs {
+		fs[i] = r.param()
+	}
+	return fs
+}
+
+func (r *importReader) param() *types.Field {
+	return types.NewField(r.pos(), r.localIdent(), r.typ())
+}
+
+func (r *importReader) bool() bool {
+	return r.uint64() != 0
+}
+
+func (r *importReader) int64() int64 {
+	n, err := binary.ReadVarint(r)
+	if err != nil {
+		base.Fatalf("readVarint: %v", err)
+	}
+	return n
+}
+
+func (r *importReader) uint64() uint64 {
+	n, err := binary.ReadUvarint(r)
+	if err != nil {
+		base.Fatalf("readVarint: %v", err)
+	}
+	return n
+}
+
+func (r *importReader) byte() byte {
+	x, err := r.ReadByte()
+	if err != nil {
+		base.Fatalf("declReader.ReadByte: %v", err)
+	}
+	return x
+}
+
+// Compiler-specific extensions.
+
+func (r *importReader) constExt(n *ir.Name) {
+	switch n.Type() {
+	case types.UntypedFloat:
+		n.SetVal(r.mprat(n.Val()))
+	case types.UntypedComplex:
+		v := n.Val()
+		re := r.mprat(constant.Real(v))
+		im := r.mprat(constant.Imag(v))
+		n.SetVal(makeComplex(re, im))
+	}
+}
+
+func (r *importReader) varExt(n *ir.Name) {
+	r.linkname(n.Sym())
+	r.symIdx(n.Sym())
+}
+
+func (r *importReader) funcExt(n *ir.Name) {
+	r.linkname(n.Sym())
+	r.symIdx(n.Sym())
+
+	n.Func.ABI = obj.ABI(r.uint64())
+
+	n.SetPragma(ir.PragmaFlag(r.uint64()))
+
+	// Escape analysis.
+	for _, fs := range &types.RecvsParams {
+		for _, f := range fs(n.Type()).FieldSlice() {
+			f.Note = r.string()
+		}
+	}
+
+	// Inline body.
+	if u := r.uint64(); u > 0 {
+		n.Func.Inl = &ir.Inline{
+			Cost: int32(u - 1),
+		}
+		n.Func.Endlineno = r.pos()
+	}
+}
+
+func (r *importReader) methExt(m *types.Field) {
+	if r.bool() {
+		m.SetNointerface(true)
+	}
+	r.funcExt(m.Nname.(*ir.Name))
+}
+
+func (r *importReader) linkname(s *types.Sym) {
+	s.Linkname = r.string()
+}
+
+func (r *importReader) symIdx(s *types.Sym) {
+	lsym := s.Linksym()
+	idx := int32(r.int64())
+	if idx != -1 {
+		if s.Linkname != "" {
+			base.Fatalf("bad index for linknamed symbol: %v %d\n", lsym, idx)
+		}
+		lsym.SymIdx = idx
+		lsym.Set(obj.AttrIndexed, true)
+	}
+}
+
+func (r *importReader) typeExt(t *types.Type) {
+	t.SetNotInHeap(r.bool())
+	i, pi := r.int64(), r.int64()
+	if i != -1 && pi != -1 {
+		typeSymIdx[t] = [2]int64{i, pi}
+	}
+}
+
+// Map imported type T to the index of type descriptor symbols of T and *T,
+// so we can use index to reference the symbol.
+var typeSymIdx = make(map[*types.Type][2]int64)
+
+func BaseTypeIndex(t *types.Type) int64 {
+	tbase := t
+	if t.IsPtr() && t.Sym() == nil && t.Elem().Sym() != nil {
+		tbase = t.Elem()
+	}
+	i, ok := typeSymIdx[tbase]
+	if !ok {
+		return -1
+	}
+	if t != tbase {
+		return i[1]
+	}
+	return i[0]
+}
+
+func (r *importReader) doInline(fn *ir.Func) {
+	if len(fn.Inl.Body) != 0 {
+		base.Fatalf("%v already has inline body", fn)
+	}
+
+	//fmt.Printf("Importing %s\n", fn.Nname.Sym().Name)
+	r.funcBody(fn)
+
+	importlist = append(importlist, fn)
+
+	if base.Flag.E > 0 && base.Flag.LowerM > 2 {
+		if base.Flag.LowerM > 3 {
+			fmt.Printf("inl body for %v %v: %+v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body))
+		} else {
+			fmt.Printf("inl body for %v %v: %v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body))
+		}
+	}
+}
+
+// ----------------------------------------------------------------------------
+// Inlined function bodies
+
+// Approach: Read nodes and use them to create/declare the same data structures
+// as done originally by the (hidden) parser by closely following the parser's
+// original code. In other words, "parsing" the import data (which happens to
+// be encoded in binary rather textual form) is the best way at the moment to
+// re-establish the syntax tree's invariants. At some future point we might be
+// able to avoid this round-about way and create the rewritten nodes directly,
+// possibly avoiding a lot of duplicate work (name resolution, type checking).
+//
+// Refined nodes (e.g., ODOTPTR as a refinement of OXDOT) are exported as their
+// unrefined nodes (since this is what the importer uses). The respective case
+// entries are unreachable in the importer.
+
+func (r *importReader) funcBody(fn *ir.Func) {
+	outerfn := r.curfn
+	r.curfn = fn
+
+	// Import local declarations.
+	fn.Inl.Dcl = r.readFuncDcls(fn)
+
+	// Import function body.
+	body := r.stmtList()
+	if body == nil {
+		// Make sure empty body is not interpreted as
+		// no inlineable body (see also parser.fnbody)
+		// (not doing so can cause significant performance
+		// degradation due to unnecessary calls to empty
+		// functions).
+		body = []ir.Node{}
+	}
+	if go117ExportTypes {
+		ir.VisitList(body, func(n ir.Node) {
+			n.SetTypecheck(1)
+		})
+	}
+	fn.Inl.Body = body
+
+	r.curfn = outerfn
+}
+
+func (r *importReader) readNames(fn *ir.Func) []*ir.Name {
+	dcls := make([]*ir.Name, r.int64())
+	for i := range dcls {
+		n := ir.NewDeclNameAt(r.pos(), ir.ONAME, r.localIdent())
+		n.Class = ir.PAUTO // overwritten below for parameters/results
+		n.Curfn = fn
+		n.SetType(r.typ())
+		dcls[i] = n
+	}
+	r.allDcls = append(r.allDcls, dcls...)
+	return dcls
+}
+
+func (r *importReader) readFuncDcls(fn *ir.Func) []*ir.Name {
+	dcls := r.readNames(fn)
+
+	// Fixup parameter classes and associate with their
+	// signature's type fields.
+	i := 0
+	fix := func(f *types.Field, class ir.Class) {
+		if class == ir.PPARAM && (f.Sym == nil || f.Sym.Name == "_") {
+			return
+		}
+		n := dcls[i]
+		n.Class = class
+		f.Nname = n
+		i++
+	}
+
+	typ := fn.Type()
+	if recv := typ.Recv(); recv != nil {
+		fix(recv, ir.PPARAM)
+	}
+	for _, f := range typ.Params().FieldSlice() {
+		fix(f, ir.PPARAM)
+	}
+	for _, f := range typ.Results().FieldSlice() {
+		fix(f, ir.PPARAMOUT)
+	}
+	return dcls
+}
+
+func (r *importReader) localName() *ir.Name {
+	i := r.int64()
+	if i == -1 {
+		return ir.BlankNode.(*ir.Name)
+	}
+	if i < 0 {
+		return r.allClosureVars[-i-2]
+	}
+	return r.allDcls[i]
+}
+
+func (r *importReader) stmtList() []ir.Node {
+	var list []ir.Node
+	for {
+		n := r.node()
+		if n == nil {
+			break
+		}
+		// OBLOCK nodes are not written to the import data directly,
+		// but the handling of ODCL calls liststmt, which creates one.
+		// Inline them into the statement list.
+		if n.Op() == ir.OBLOCK {
+			n := n.(*ir.BlockStmt)
+			list = append(list, n.List...)
+		} else {
+			list = append(list, n)
+		}
+
+	}
+	return list
+}
+
+func (r *importReader) caseList(switchExpr ir.Node) []*ir.CaseClause {
+	namedTypeSwitch := isNamedTypeSwitch(switchExpr)
+
+	cases := make([]*ir.CaseClause, r.uint64())
+	for i := range cases {
+		cas := ir.NewCaseStmt(r.pos(), nil, nil)
+		cas.List = r.stmtList()
+		if namedTypeSwitch {
+			cas.Var = r.localName()
+			cas.Var.Defn = switchExpr
+		}
+		cas.Body = r.stmtList()
+		cases[i] = cas
+	}
+	return cases
+}
+
+func (r *importReader) commList() []*ir.CommClause {
+	cases := make([]*ir.CommClause, r.uint64())
+	for i := range cases {
+		cases[i] = ir.NewCommStmt(r.pos(), r.node(), r.stmtList())
+	}
+	return cases
+}
+
+func (r *importReader) exprList() []ir.Node {
+	var list []ir.Node
+	for {
+		n := r.expr()
+		if n == nil {
+			break
+		}
+		list = append(list, n)
+	}
+	return list
+}
+
+func (r *importReader) expr() ir.Node {
+	n := r.node()
+	if n != nil && n.Op() == ir.OBLOCK {
+		n := n.(*ir.BlockStmt)
+		base.Fatalf("unexpected block node: %v", n)
+	}
+	return n
+}
+
+// TODO(gri) split into expr and stmt
+func (r *importReader) node() ir.Node {
+	op := r.op()
+	switch op {
+	// expressions
+	// case OPAREN:
+	// 	unreachable - unpacked by exporter
+
+	case ir.ONIL:
+		pos := r.pos()
+		typ := r.typ()
+
+		n := ir.NewNilExpr(pos)
+		n.SetType(typ)
+		return n
+
+	case ir.OLITERAL:
+		pos := r.pos()
+		typ := r.typ()
+
+		n := ir.NewBasicLit(pos, r.value(typ))
+		n.SetType(typ)
+		return n
+
+	case ir.ONONAME:
+		n := r.qualifiedIdent()
+		if go117ExportTypes {
+			n2 := Resolve(n)
+			typ := r.typ()
+			if n2.Type() == nil {
+				n2.SetType(typ)
+			}
+			return n2
+		}
+		return n
+
+	case ir.ONAME:
+		return r.localName()
+
+	// case OPACK, ONONAME:
+	// 	unreachable - should have been resolved by typechecking
+
+	case ir.OTYPE:
+		return ir.TypeNode(r.typ())
+
+	case ir.OTYPESW:
+		pos := r.pos()
+		var tag *ir.Ident
+		if s := r.localIdent(); s != nil {
+			tag = ir.NewIdent(pos, s)
+		}
+		return ir.NewTypeSwitchGuard(pos, tag, r.expr())
+
+	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
+	//      unreachable - should have been resolved by typechecking
+
+	case ir.OCLOSURE:
+		//println("Importing CLOSURE")
+		pos := r.pos()
+		typ := r.signature(nil)
+
+		// All the remaining code below is similar to (*noder).funcLit(), but
+		// with Dcls and ClosureVars lists already set up
+		fn := ir.NewFunc(pos)
+		fn.SetIsHiddenClosure(true)
+		fn.Nname = ir.NewNameAt(pos, ir.BlankNode.Sym())
+		fn.Nname.Func = fn
+		fn.Nname.Ntype = ir.TypeNode(typ)
+		fn.Nname.Defn = fn
+		fn.Nname.SetType(typ)
+
+		cvars := make([]*ir.Name, r.int64())
+		for i := range cvars {
+			cvars[i] = ir.CaptureName(r.pos(), fn, r.localName().Canonical())
+			if go117ExportTypes {
+				if cvars[i].Type() != nil || cvars[i].Defn == nil {
+					base.Fatalf("bad import of closure variable")
+				}
+				// Closure variable should have Defn set, which is its captured
+				// variable, and it gets the same type as the captured variable.
+				cvars[i].SetType(cvars[i].Defn.Type())
+			}
+		}
+		fn.ClosureVars = cvars
+		r.allClosureVars = append(r.allClosureVars, cvars...)
+
+		fn.Inl = &ir.Inline{}
+		// Read in the Dcls and Body of the closure after temporarily
+		// setting r.curfn to fn.
+		r.funcBody(fn)
+		fn.Dcl = fn.Inl.Dcl
+		fn.Body = fn.Inl.Body
+		if len(fn.Body) == 0 {
+			// An empty closure must be represented as a single empty
+			// block statement, else it will be dropped.
+			fn.Body = []ir.Node{ir.NewBlockStmt(src.NoXPos, nil)}
+		}
+		fn.Inl = nil
+
+		ir.FinishCaptureNames(pos, r.curfn, fn)
+
+		clo := ir.NewClosureExpr(pos, fn)
+		fn.OClosure = clo
+		if go117ExportTypes {
+			clo.SetType(typ)
+		}
+
+		return clo
+
+	case ir.OSTRUCTLIT:
+		if go117ExportTypes {
+			pos := r.pos()
+			typ := r.typ()
+			list := r.fieldList()
+			n := ir.NewCompLitExpr(pos, ir.OSTRUCTLIT, nil, list)
+			n.SetType(typ)
+			return n
+		}
+		return ir.NewCompLitExpr(r.pos(), ir.OCOMPLIT, ir.TypeNode(r.typ()), r.fieldList())
+
+	case ir.OCOMPLIT:
+		return ir.NewCompLitExpr(r.pos(), ir.OCOMPLIT, ir.TypeNode(r.typ()), r.exprList())
+
+	case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
+		if !go117ExportTypes {
+			// unreachable - mapped to OCOMPLIT by exporter
+			goto error
+		}
+		pos := r.pos()
+		typ := r.typ()
+		list := r.exprList()
+		n := ir.NewCompLitExpr(pos, op, ir.TypeNode(typ), list)
+		n.SetType(typ)
+		if op == ir.OSLICELIT {
+			n.Len = int64(r.uint64())
+		}
+		return n
+
+	case ir.OKEY:
+		return ir.NewKeyExpr(r.pos(), r.expr(), r.expr())
+
+	// case OSTRUCTKEY:
+	//	unreachable - handled in case OSTRUCTLIT by elemList
+
+	case ir.OXDOT:
+		// see parser.new_dotname
+		if go117ExportTypes {
+			base.Fatalf("shouldn't encounter XDOT in new importer")
+		}
+		return ir.NewSelectorExpr(r.pos(), ir.OXDOT, r.expr(), r.exoticSelector())
+
+	case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH, ir.OCALLPART, ir.OMETHEXPR:
+		if !go117ExportTypes {
+			// unreachable - mapped to case OXDOT by exporter
+			goto error
+		}
+		pos := r.pos()
+		expr := r.expr()
+		sel := r.exoticSelector()
+		n := ir.NewSelectorExpr(pos, op, expr, sel)
+		n.SetType(r.exoticType())
+		switch op {
+		case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER:
+			n.Selection = r.exoticField()
+		case ir.ODOTMETH, ir.OCALLPART, ir.OMETHEXPR:
+			// These require a Lookup to link to the correct declaration.
+			rcvrType := expr.Type()
+			typ := n.Type()
+			n.Selection = Lookdot(n, rcvrType, 1)
+			if op == ir.OCALLPART || op == ir.OMETHEXPR {
+				// Lookdot clobbers the opcode and type, undo that.
+				n.SetOp(op)
+				n.SetType(typ)
+			}
+		}
+		return n
+
+	case ir.ODOTTYPE, ir.ODOTTYPE2:
+		n := ir.NewTypeAssertExpr(r.pos(), r.expr(), nil)
+		n.SetType(r.typ())
+		if go117ExportTypes {
+			n.SetOp(op)
+		}
+		return n
+
+	case ir.OINDEX, ir.OINDEXMAP:
+		n := ir.NewIndexExpr(r.pos(), r.expr(), r.expr())
+		if go117ExportTypes {
+			n.SetOp(op)
+			n.SetType(r.typ())
+			if op == ir.OINDEXMAP {
+				n.Assigned = r.bool()
+			}
+		}
+		return n
+
+	case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR:
+		pos, x := r.pos(), r.expr()
+		low, high := r.exprsOrNil()
+		var max ir.Node
+		if op.IsSlice3() {
+			max = r.expr()
+		}
+		n := ir.NewSliceExpr(pos, op, x, low, high, max)
+		if go117ExportTypes {
+			n.SetType(r.typ())
+		}
+		return n
+
+	case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
+		if !go117ExportTypes && op != ir.OCONV {
+			// 	unreachable - mapped to OCONV case by exporter
+			goto error
+		}
+		return ir.NewConvExpr(r.pos(), op, r.typ(), r.expr())
+
+	case ir.OCOPY, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCAP, ir.OCLOSE, ir.ODELETE, ir.OLEN, ir.OMAKE, ir.ONEW, ir.OPANIC, ir.ORECOVER, ir.OPRINT, ir.OPRINTN, ir.OUNSAFEADD, ir.OUNSAFESLICE:
+		if go117ExportTypes {
+			switch op {
+			case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE:
+				n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
+				n.SetType(r.typ())
+				return n
+			case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
+				n := ir.NewUnaryExpr(r.pos(), op, r.expr())
+				if op != ir.OPANIC {
+					n.SetType(r.typ())
+				}
+				return n
+			case ir.OAPPEND, ir.ODELETE, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
+				n := ir.NewCallExpr(r.pos(), op, nil, r.exprList())
+				if op == ir.OAPPEND {
+					n.IsDDD = r.bool()
+				}
+				if op == ir.OAPPEND || op == ir.ORECOVER {
+					n.SetType(r.typ())
+				}
+				return n
+			}
+			// ir.OMAKE
+			goto error
+		}
+		n := builtinCall(r.pos(), op)
+		n.Args = r.exprList()
+		if op == ir.OAPPEND {
+			n.IsDDD = r.bool()
+		}
+		return n
+
+	case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
+		pos := r.pos()
+		init := r.stmtList()
+		n := ir.NewCallExpr(pos, ir.OCALL, r.expr(), r.exprList())
+		if go117ExportTypes {
+			n.SetOp(op)
+		}
+		*n.PtrInit() = init
+		n.IsDDD = r.bool()
+		if go117ExportTypes {
+			n.SetType(r.exoticType())
+			n.Use = ir.CallUse(r.uint64())
+		}
+		return n
+
+	case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
+		if go117ExportTypes {
+			pos := r.pos()
+			typ := r.typ()
+			list := r.exprList()
+			var len_, cap_ ir.Node
+			if len(list) > 0 {
+				len_ = list[0]
+			}
+			if len(list) > 1 {
+				cap_ = list[1]
+			}
+			n := ir.NewMakeExpr(pos, op, len_, cap_)
+			n.SetType(typ)
+			return n
+		}
+		n := builtinCall(r.pos(), ir.OMAKE)
+		n.Args.Append(ir.TypeNode(r.typ()))
+		n.Args.Append(r.exprList()...)
+		return n
+
+	// unary expressions
+	case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV:
+		n := ir.NewUnaryExpr(r.pos(), op, r.expr())
+		if go117ExportTypes {
+			n.SetType(r.typ())
+		}
+		return n
+
+	case ir.OADDR, ir.OPTRLIT:
+		n := NodAddrAt(r.pos(), r.expr())
+		if go117ExportTypes {
+			n.SetOp(op)
+			n.SetType(r.typ())
+		}
+		return n
+
+	case ir.ODEREF:
+		n := ir.NewStarExpr(r.pos(), r.expr())
+		if go117ExportTypes {
+			n.SetType(r.typ())
+		}
+		return n
+
+	// binary expressions
+	case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
+		ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR:
+		n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
+		if go117ExportTypes {
+			n.SetType(r.typ())
+		}
+		return n
+
+	case ir.OANDAND, ir.OOROR:
+		n := ir.NewLogicalExpr(r.pos(), op, r.expr(), r.expr())
+		if go117ExportTypes {
+			n.SetType(r.typ())
+		}
+		return n
+
+	case ir.OSEND:
+		return ir.NewSendStmt(r.pos(), r.expr(), r.expr())
+
+	case ir.OADDSTR:
+		pos := r.pos()
+		list := r.exprList()
+		if go117ExportTypes {
+			n := ir.NewAddStringExpr(pos, list)
+			n.SetType(r.typ())
+			return n
+		}
+		x := list[0]
+		for _, y := range list[1:] {
+			x = ir.NewBinaryExpr(pos, ir.OADD, x, y)
+		}
+		return x
+
+	// --------------------------------------------------------------------
+	// statements
+	case ir.ODCL:
+		var stmts ir.Nodes
+		n := r.localName()
+		stmts.Append(ir.NewDecl(n.Pos(), ir.ODCL, n))
+		stmts.Append(ir.NewAssignStmt(n.Pos(), n, nil))
+		return ir.NewBlockStmt(n.Pos(), stmts)
+
+	// case OASWB:
+	// 	unreachable - never exported
+
+	case ir.OAS:
+		return ir.NewAssignStmt(r.pos(), r.expr(), r.expr())
+
+	case ir.OASOP:
+		n := ir.NewAssignOpStmt(r.pos(), r.op(), r.expr(), nil)
+		if !r.bool() {
+			n.Y = ir.NewInt(1)
+			n.IncDec = true
+		} else {
+			n.Y = r.expr()
+		}
+		return n
+
+	case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
+		if !go117ExportTypes && op != ir.OAS2 {
+			// unreachable - mapped to case OAS2 by exporter
+			goto error
+		}
+		return ir.NewAssignListStmt(r.pos(), op, r.exprList(), r.exprList())
+
+	case ir.ORETURN:
+		return ir.NewReturnStmt(r.pos(), r.exprList())
+
+	// case ORETJMP:
+	// 	unreachable - generated by compiler for trampolin routines (not exported)
+
+	case ir.OGO, ir.ODEFER:
+		return ir.NewGoDeferStmt(r.pos(), op, r.expr())
+
+	case ir.OIF:
+		pos, init := r.pos(), r.stmtList()
+		n := ir.NewIfStmt(pos, r.expr(), r.stmtList(), r.stmtList())
+		*n.PtrInit() = init
+		return n
+
+	case ir.OFOR:
+		pos, init := r.pos(), r.stmtList()
+		cond, post := r.exprsOrNil()
+		n := ir.NewForStmt(pos, nil, cond, post, r.stmtList())
+		*n.PtrInit() = init
+		return n
+
+	case ir.ORANGE:
+		pos := r.pos()
+		k, v := r.exprsOrNil()
+		return ir.NewRangeStmt(pos, k, v, r.expr(), r.stmtList())
+
+	case ir.OSELECT:
+		pos := r.pos()
+		init := r.stmtList()
+		n := ir.NewSelectStmt(pos, r.commList())
+		*n.PtrInit() = init
+		return n
+
+	case ir.OSWITCH:
+		pos := r.pos()
+		init := r.stmtList()
+		x, _ := r.exprsOrNil()
+		n := ir.NewSwitchStmt(pos, x, r.caseList(x))
+		*n.PtrInit() = init
+		return n
+
+	// case OCASE:
+	//	handled by caseList
+
+	case ir.OFALL:
+		return ir.NewBranchStmt(r.pos(), ir.OFALL, nil)
+
+	// case OEMPTY:
+	// 	unreachable - not emitted by exporter
+
+	case ir.OBREAK, ir.OCONTINUE, ir.OGOTO:
+		pos := r.pos()
+		var sym *types.Sym
+		if label := r.string(); label != "" {
+			sym = Lookup(label)
+		}
+		return ir.NewBranchStmt(pos, op, sym)
+
+	case ir.OLABEL:
+		return ir.NewLabelStmt(r.pos(), Lookup(r.string()))
+
+	case ir.OEND:
+		return nil
+
+	default:
+		base.Fatalf("cannot import %v (%d) node\n"+
+			"\t==> please file an issue and assign to gri@", op, int(op))
+		panic("unreachable") // satisfy compiler
+	}
+error:
+	base.Fatalf("cannot import %v (%d) node\n"+
+		"\t==> please file an issue and assign to khr@", op, int(op))
+	panic("unreachable") // satisfy compiler
+}
+
+func (r *importReader) op() ir.Op {
+	if debug && r.uint64() != magic {
+		base.Fatalf("import stream has desynchronized")
+	}
+	return ir.Op(r.uint64())
+}
+
+func (r *importReader) fieldList() []ir.Node {
+	list := make([]ir.Node, r.uint64())
+	for i := range list {
+		x := ir.NewStructKeyExpr(r.pos(), r.selector(), r.expr())
+		if go117ExportTypes {
+			x.Offset = int64(r.uint64())
+		}
+		list[i] = x
+	}
+	return list
+}
+
+func (r *importReader) exprsOrNil() (a, b ir.Node) {
+	ab := r.uint64()
+	if ab&1 != 0 {
+		a = r.expr()
+	}
+	if ab&2 != 0 {
+		b = r.node()
+	}
+	return
+}
+
+func builtinCall(pos src.XPos, op ir.Op) *ir.CallExpr {
+	if go117ExportTypes {
+		// These should all be encoded as direct ops, not OCALL.
+		base.Fatalf("builtinCall should not be invoked when types are included in import/export")
+	}
+	return ir.NewCallExpr(pos, ir.OCALL, ir.NewIdent(base.Pos, types.BuiltinPkg.Lookup(ir.OpNames[op])), nil)
+}
diff --git a/src/cmd/compile/internal/typecheck/mapfile_mmap.go b/src/cmd/compile/internal/typecheck/mapfile_mmap.go
new file mode 100644
index 0000000..298b385
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/mapfile_mmap.go
@@ -0,0 +1,49 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd
+
+package typecheck
+
+import (
+	"os"
+	"reflect"
+	"syscall"
+	"unsafe"
+)
+
+// TODO(mdempsky): Is there a higher-level abstraction that still
+// works well for iimport?
+
+// mapFile returns length bytes from the file starting at the
+// specified offset as a string.
+func mapFile(f *os.File, offset, length int64) (string, error) {
+	// POSIX mmap: "The implementation may require that off is a
+	// multiple of the page size."
+	x := offset & int64(os.Getpagesize()-1)
+	offset -= x
+	length += x
+
+	buf, err := syscall.Mmap(int(f.Fd()), offset, int(length), syscall.PROT_READ, syscall.MAP_SHARED)
+	keepAlive(f)
+	if err != nil {
+		return "", err
+	}
+
+	buf = buf[x:]
+	pSlice := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
+
+	var res string
+	pString := (*reflect.StringHeader)(unsafe.Pointer(&res))
+
+	pString.Data = pSlice.Data
+	pString.Len = pSlice.Len
+
+	return res, nil
+}
+
+// keepAlive is a reimplementation of runtime.KeepAlive, which wasn't
+// added until Go 1.7, whereas we need to compile with Go 1.4.
+var keepAlive = func(interface{}) {}
diff --git a/src/cmd/compile/internal/typecheck/mapfile_read.go b/src/cmd/compile/internal/typecheck/mapfile_read.go
new file mode 100644
index 0000000..9637ab9
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/mapfile_read.go
@@ -0,0 +1,22 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd
+
+package typecheck
+
+import (
+	"io"
+	"os"
+)
+
+func mapFile(f *os.File, offset, length int64) (string, error) {
+	buf := make([]byte, length)
+	_, err := io.ReadFull(io.NewSectionReader(f, offset, length), buf)
+	if err != nil {
+		return "", err
+	}
+	return string(buf), nil
+}
diff --git a/src/cmd/compile/internal/typecheck/mkbuiltin.go b/src/cmd/compile/internal/typecheck/mkbuiltin.go
new file mode 100644
index 0000000..6dbd186
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/mkbuiltin.go
@@ -0,0 +1,249 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build ignore
+// +build ignore
+
+// Generate builtin.go from builtin/runtime.go.
+
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/format"
+	"go/parser"
+	"go/token"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+)
+
+var stdout = flag.Bool("stdout", false, "write to stdout instead of builtin.go")
+
+func main() {
+	flag.Parse()
+
+	var b bytes.Buffer
+	fmt.Fprintln(&b, "// Code generated by mkbuiltin.go. DO NOT EDIT.")
+	fmt.Fprintln(&b)
+	fmt.Fprintln(&b, "package typecheck")
+	fmt.Fprintln(&b)
+	fmt.Fprintln(&b, `import (`)
+	fmt.Fprintln(&b, `      "cmd/compile/internal/types"`)
+	fmt.Fprintln(&b, `      "cmd/internal/src"`)
+	fmt.Fprintln(&b, `)`)
+
+	mkbuiltin(&b, "runtime")
+
+	out, err := format.Source(b.Bytes())
+	if err != nil {
+		log.Fatal(err)
+	}
+	if *stdout {
+		_, err = os.Stdout.Write(out)
+	} else {
+		err = ioutil.WriteFile("builtin.go", out, 0666)
+	}
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func mkbuiltin(w io.Writer, name string) {
+	fset := token.NewFileSet()
+	f, err := parser.ParseFile(fset, filepath.Join("builtin", name+".go"), nil, 0)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	var interner typeInterner
+
+	fmt.Fprintf(w, "var %sDecls = [...]struct { name string; tag int; typ int }{\n", name)
+	for _, decl := range f.Decls {
+		switch decl := decl.(type) {
+		case *ast.FuncDecl:
+			if decl.Recv != nil {
+				log.Fatal("methods unsupported")
+			}
+			if decl.Body != nil {
+				log.Fatal("unexpected function body")
+			}
+			fmt.Fprintf(w, "{%q, funcTag, %d},\n", decl.Name.Name, interner.intern(decl.Type))
+		case *ast.GenDecl:
+			if decl.Tok == token.IMPORT {
+				if len(decl.Specs) != 1 || decl.Specs[0].(*ast.ImportSpec).Path.Value != "\"unsafe\"" {
+					log.Fatal("runtime cannot import other package")
+				}
+				continue
+			}
+			if decl.Tok != token.VAR {
+				log.Fatal("unhandled declaration kind", decl.Tok)
+			}
+			for _, spec := range decl.Specs {
+				spec := spec.(*ast.ValueSpec)
+				if len(spec.Values) != 0 {
+					log.Fatal("unexpected values")
+				}
+				typ := interner.intern(spec.Type)
+				for _, name := range spec.Names {
+					fmt.Fprintf(w, "{%q, varTag, %d},\n", name.Name, typ)
+				}
+			}
+		default:
+			log.Fatal("unhandled decl type", decl)
+		}
+	}
+	fmt.Fprintln(w, "}")
+
+	fmt.Fprintln(w, `
+// Not inlining this function removes a significant chunk of init code.
+//go:noinline
+func newSig(params, results []*types.Field) *types.Type {
+	return types.NewSignature(types.NoPkg, nil, nil, params, results)
+}
+
+func params(tlist ...*types.Type) []*types.Field {
+	flist := make([]*types.Field, len(tlist))
+	for i, typ := range tlist {
+		flist[i] = types.NewField(src.NoXPos, nil, typ)
+	}
+	return flist
+}`)
+
+	fmt.Fprintln(w)
+	fmt.Fprintf(w, "func %sTypes() []*types.Type {\n", name)
+	fmt.Fprintf(w, "var typs [%d]*types.Type\n", len(interner.typs))
+	for i, typ := range interner.typs {
+		fmt.Fprintf(w, "typs[%d] = %s\n", i, typ)
+	}
+	fmt.Fprintln(w, "return typs[:]")
+	fmt.Fprintln(w, "}")
+}
+
+// typeInterner maps Go type expressions to compiler code that
+// constructs the denoted type. It recognizes and reuses common
+// subtype expressions.
+type typeInterner struct {
+	typs []string
+	hash map[string]int
+}
+
+func (i *typeInterner) intern(t ast.Expr) int {
+	x := i.mktype(t)
+	v, ok := i.hash[x]
+	if !ok {
+		v = len(i.typs)
+		if i.hash == nil {
+			i.hash = make(map[string]int)
+		}
+		i.hash[x] = v
+		i.typs = append(i.typs, x)
+	}
+	return v
+}
+
+func (i *typeInterner) subtype(t ast.Expr) string {
+	return fmt.Sprintf("typs[%d]", i.intern(t))
+}
+
+func (i *typeInterner) mktype(t ast.Expr) string {
+	switch t := t.(type) {
+	case *ast.Ident:
+		switch t.Name {
+		case "byte":
+			return "types.ByteType"
+		case "rune":
+			return "types.RuneType"
+		}
+		return fmt.Sprintf("types.Types[types.T%s]", strings.ToUpper(t.Name))
+	case *ast.SelectorExpr:
+		if t.X.(*ast.Ident).Name != "unsafe" || t.Sel.Name != "Pointer" {
+			log.Fatalf("unhandled type: %#v", t)
+		}
+		return "types.Types[types.TUNSAFEPTR]"
+
+	case *ast.ArrayType:
+		if t.Len == nil {
+			return fmt.Sprintf("types.NewSlice(%s)", i.subtype(t.Elt))
+		}
+		return fmt.Sprintf("types.NewArray(%s, %d)", i.subtype(t.Elt), intconst(t.Len))
+	case *ast.ChanType:
+		dir := "types.Cboth"
+		switch t.Dir {
+		case ast.SEND:
+			dir = "types.Csend"
+		case ast.RECV:
+			dir = "types.Crecv"
+		}
+		return fmt.Sprintf("types.NewChan(%s, %s)", i.subtype(t.Value), dir)
+	case *ast.FuncType:
+		return fmt.Sprintf("newSig(%s, %s)", i.fields(t.Params, false), i.fields(t.Results, false))
+	case *ast.InterfaceType:
+		if len(t.Methods.List) != 0 {
+			log.Fatal("non-empty interfaces unsupported")
+		}
+		return "types.Types[types.TINTER]"
+	case *ast.MapType:
+		return fmt.Sprintf("types.NewMap(%s, %s)", i.subtype(t.Key), i.subtype(t.Value))
+	case *ast.StarExpr:
+		return fmt.Sprintf("types.NewPtr(%s)", i.subtype(t.X))
+	case *ast.StructType:
+		return fmt.Sprintf("types.NewStruct(types.NoPkg, %s)", i.fields(t.Fields, true))
+
+	default:
+		log.Fatalf("unhandled type: %#v", t)
+		panic("unreachable")
+	}
+}
+
+func (i *typeInterner) fields(fl *ast.FieldList, keepNames bool) string {
+	if fl == nil || len(fl.List) == 0 {
+		return "nil"
+	}
+
+	var res []string
+	for _, f := range fl.List {
+		typ := i.subtype(f.Type)
+		if len(f.Names) == 0 {
+			res = append(res, typ)
+		} else {
+			for _, name := range f.Names {
+				if keepNames {
+					res = append(res, fmt.Sprintf("types.NewField(src.NoXPos, Lookup(%q), %s)", name.Name, typ))
+				} else {
+					res = append(res, typ)
+				}
+			}
+		}
+	}
+
+	if keepNames {
+		return fmt.Sprintf("[]*types.Field{%s}", strings.Join(res, ", "))
+	}
+	return fmt.Sprintf("params(%s)", strings.Join(res, ", "))
+}
+
+func intconst(e ast.Expr) int64 {
+	switch e := e.(type) {
+	case *ast.BasicLit:
+		if e.Kind != token.INT {
+			log.Fatalf("expected INT, got %v", e.Kind)
+		}
+		x, err := strconv.ParseInt(e.Value, 0, 64)
+		if err != nil {
+			log.Fatal(err)
+		}
+		return x
+	default:
+		log.Fatalf("unhandled expr: %#v", e)
+		panic("unreachable")
+	}
+}
diff --git a/src/cmd/compile/internal/typecheck/stmt.go b/src/cmd/compile/internal/typecheck/stmt.go
new file mode 100644
index 0000000..922a01b
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/stmt.go
@@ -0,0 +1,681 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typecheck
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+func RangeExprType(t *types.Type) *types.Type {
+	if t.IsPtr() && t.Elem().IsArray() {
+		return t.Elem()
+	}
+	return t
+}
+
+func typecheckrangeExpr(n *ir.RangeStmt) {
+	n.X = Expr(n.X)
+	if n.X.Type() == nil {
+		return
+	}
+
+	t := RangeExprType(n.X.Type())
+	// delicate little dance.  see tcAssignList
+	if n.Key != nil && !ir.DeclaredBy(n.Key, n) {
+		n.Key = AssignExpr(n.Key)
+	}
+	if n.Value != nil && !ir.DeclaredBy(n.Value, n) {
+		n.Value = AssignExpr(n.Value)
+	}
+
+	var tk, tv *types.Type
+	toomany := false
+	switch t.Kind() {
+	default:
+		base.ErrorfAt(n.Pos(), "cannot range over %L", n.X)
+		return
+
+	case types.TARRAY, types.TSLICE:
+		tk = types.Types[types.TINT]
+		tv = t.Elem()
+
+	case types.TMAP:
+		tk = t.Key()
+		tv = t.Elem()
+
+	case types.TCHAN:
+		if !t.ChanDir().CanRecv() {
+			base.ErrorfAt(n.Pos(), "invalid operation: range %v (receive from send-only type %v)", n.X, n.X.Type())
+			return
+		}
+
+		tk = t.Elem()
+		tv = nil
+		if n.Value != nil {
+			toomany = true
+		}
+
+	case types.TSTRING:
+		tk = types.Types[types.TINT]
+		tv = types.RuneType
+	}
+
+	if toomany {
+		base.ErrorfAt(n.Pos(), "too many variables in range")
+	}
+
+	do := func(nn ir.Node, t *types.Type) {
+		if nn != nil {
+			if ir.DeclaredBy(nn, n) {
+				nn.SetType(t)
+			} else if nn.Type() != nil {
+				if op, why := Assignop(t, nn.Type()); op == ir.OXXX {
+					base.ErrorfAt(n.Pos(), "cannot assign type %v to %L in range%s", t, nn, why)
+				}
+			}
+			checkassign(n, nn)
+		}
+	}
+	do(n.Key, tk)
+	do(n.Value, tv)
+}
+
+// type check assignment.
+// if this assignment is the definition of a var on the left side,
+// fill in the var's type.
+func tcAssign(n *ir.AssignStmt) {
+	if base.EnableTrace && base.Flag.LowerT {
+		defer tracePrint("tcAssign", n)(nil)
+	}
+
+	if n.Y == nil {
+		n.X = AssignExpr(n.X)
+		return
+	}
+
+	lhs, rhs := []ir.Node{n.X}, []ir.Node{n.Y}
+	assign(n, lhs, rhs)
+	n.X, n.Y = lhs[0], rhs[0]
+
+	// TODO(mdempsky): This seems out of place.
+	if !ir.IsBlank(n.X) {
+		types.CheckSize(n.X.Type()) // ensure width is calculated for backend
+	}
+}
+
+func tcAssignList(n *ir.AssignListStmt) {
+	if base.EnableTrace && base.Flag.LowerT {
+		defer tracePrint("tcAssignList", n)(nil)
+	}
+
+	assign(n, n.Lhs, n.Rhs)
+}
+
+func assign(stmt ir.Node, lhs, rhs []ir.Node) {
+	// delicate little dance.
+	// the definition of lhs may refer to this assignment
+	// as its definition, in which case it will call tcAssign.
+	// in that case, do not call typecheck back, or it will cycle.
+	// if the variable has a type (ntype) then typechecking
+	// will not look at defn, so it is okay (and desirable,
+	// so that the conversion below happens).
+
+	checkLHS := func(i int, typ *types.Type) {
+		lhs[i] = Resolve(lhs[i])
+		if n := lhs[i]; typ != nil && ir.DeclaredBy(n, stmt) && n.Name().Ntype == nil {
+			if typ.Kind() != types.TNIL {
+				n.SetType(defaultType(typ))
+			} else {
+				base.Errorf("use of untyped nil")
+			}
+		}
+		if lhs[i].Typecheck() == 0 {
+			lhs[i] = AssignExpr(lhs[i])
+		}
+		checkassign(stmt, lhs[i])
+	}
+
+	assignType := func(i int, typ *types.Type) {
+		checkLHS(i, typ)
+		if typ != nil {
+			checkassignto(typ, lhs[i])
+		}
+	}
+
+	cr := len(rhs)
+	if len(rhs) == 1 {
+		rhs[0] = typecheck(rhs[0], ctxExpr|ctxMultiOK)
+		if rtyp := rhs[0].Type(); rtyp != nil && rtyp.IsFuncArgStruct() {
+			cr = rtyp.NumFields()
+		}
+	} else {
+		Exprs(rhs)
+	}
+
+	// x, ok = y
+assignOK:
+	for len(lhs) == 2 && cr == 1 {
+		stmt := stmt.(*ir.AssignListStmt)
+		r := rhs[0]
+
+		switch r.Op() {
+		case ir.OINDEXMAP:
+			stmt.SetOp(ir.OAS2MAPR)
+		case ir.ORECV:
+			stmt.SetOp(ir.OAS2RECV)
+		case ir.ODOTTYPE:
+			r := r.(*ir.TypeAssertExpr)
+			stmt.SetOp(ir.OAS2DOTTYPE)
+			r.SetOp(ir.ODOTTYPE2)
+		default:
+			break assignOK
+		}
+
+		assignType(0, r.Type())
+		assignType(1, types.UntypedBool)
+		return
+	}
+
+	if len(lhs) != cr {
+		if r, ok := rhs[0].(*ir.CallExpr); ok && len(rhs) == 1 {
+			if r.Type() != nil {
+				base.ErrorfAt(stmt.Pos(), "assignment mismatch: %d variable%s but %v returns %d value%s", len(lhs), plural(len(lhs)), r.X, cr, plural(cr))
+			}
+		} else {
+			base.ErrorfAt(stmt.Pos(), "assignment mismatch: %d variable%s but %v value%s", len(lhs), plural(len(lhs)), len(rhs), plural(len(rhs)))
+		}
+
+		for i := range lhs {
+			checkLHS(i, nil)
+		}
+		return
+	}
+
+	// x,y,z = f()
+	if cr > len(rhs) {
+		stmt := stmt.(*ir.AssignListStmt)
+		stmt.SetOp(ir.OAS2FUNC)
+		r := rhs[0].(*ir.CallExpr)
+		r.Use = ir.CallUseList
+		rtyp := r.Type()
+
+		mismatched := false
+		failed := false
+		for i := range lhs {
+			result := rtyp.Field(i).Type
+			assignType(i, result)
+
+			if lhs[i].Type() == nil || result == nil {
+				failed = true
+			} else if lhs[i] != ir.BlankNode && !types.Identical(lhs[i].Type(), result) {
+				mismatched = true
+			}
+		}
+		if mismatched && !failed {
+			rewriteMultiValueCall(stmt, r)
+		}
+		return
+	}
+
+	for i, r := range rhs {
+		checkLHS(i, r.Type())
+		if lhs[i].Type() != nil {
+			rhs[i] = AssignConv(r, lhs[i].Type(), "assignment")
+		}
+	}
+}
+
+func plural(n int) string {
+	if n == 1 {
+		return ""
+	}
+	return "s"
+}
+
+// tcFor typechecks an OFOR node.
+func tcFor(n *ir.ForStmt) ir.Node {
+	Stmts(n.Init())
+	n.Cond = Expr(n.Cond)
+	n.Cond = DefaultLit(n.Cond, nil)
+	if n.Cond != nil {
+		t := n.Cond.Type()
+		if t != nil && !t.IsBoolean() {
+			base.Errorf("non-bool %L used as for condition", n.Cond)
+		}
+	}
+	n.Post = Stmt(n.Post)
+	if n.Op() == ir.OFORUNTIL {
+		Stmts(n.Late)
+	}
+	Stmts(n.Body)
+	return n
+}
+
+func tcGoDefer(n *ir.GoDeferStmt) {
+	what := "defer"
+	if n.Op() == ir.OGO {
+		what = "go"
+	}
+
+	switch n.Call.Op() {
+	// ok
+	case ir.OCALLINTER,
+		ir.OCALLMETH,
+		ir.OCALLFUNC,
+		ir.OCLOSE,
+		ir.OCOPY,
+		ir.ODELETE,
+		ir.OPANIC,
+		ir.OPRINT,
+		ir.OPRINTN,
+		ir.ORECOVER:
+		return
+
+	case ir.OAPPEND,
+		ir.OCAP,
+		ir.OCOMPLEX,
+		ir.OIMAG,
+		ir.OLEN,
+		ir.OMAKE,
+		ir.OMAKESLICE,
+		ir.OMAKECHAN,
+		ir.OMAKEMAP,
+		ir.ONEW,
+		ir.OREAL,
+		ir.OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
+		if orig := ir.Orig(n.Call); orig.Op() == ir.OCONV {
+			break
+		}
+		base.ErrorfAt(n.Pos(), "%s discards result of %v", what, n.Call)
+		return
+	}
+
+	// type is broken or missing, most likely a method call on a broken type
+	// we will warn about the broken type elsewhere. no need to emit a potentially confusing error
+	if n.Call.Type() == nil || n.Call.Type().Broke() {
+		return
+	}
+
+	if !n.Diag() {
+		// The syntax made sure it was a call, so this must be
+		// a conversion.
+		n.SetDiag(true)
+		base.ErrorfAt(n.Pos(), "%s requires function call, not conversion", what)
+	}
+}
+
+// tcIf typechecks an OIF node.
+func tcIf(n *ir.IfStmt) ir.Node {
+	Stmts(n.Init())
+	n.Cond = Expr(n.Cond)
+	n.Cond = DefaultLit(n.Cond, nil)
+	if n.Cond != nil {
+		t := n.Cond.Type()
+		if t != nil && !t.IsBoolean() {
+			base.Errorf("non-bool %L used as if condition", n.Cond)
+		}
+	}
+	Stmts(n.Body)
+	Stmts(n.Else)
+	return n
+}
+
+// range
+func tcRange(n *ir.RangeStmt) {
+	// 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.
+	// 1. typecheck produced values,
+	//	this part can declare new vars and so it must be typechecked before body,
+	//	because body can contain a closure that captures the vars.
+	// 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)
+	if n.Key != nil && n.Key.Typecheck() == 0 {
+		n.Key = AssignExpr(n.Key)
+	}
+	if n.Value != nil && n.Value.Typecheck() == 0 {
+		n.Value = AssignExpr(n.Value)
+	}
+
+	Stmts(n.Body)
+}
+
+// tcReturn typechecks an ORETURN node.
+func tcReturn(n *ir.ReturnStmt) ir.Node {
+	typecheckargs(n)
+	if ir.CurFunc == nil {
+		base.Errorf("return outside function")
+		n.SetType(nil)
+		return n
+	}
+
+	if ir.HasNamedResults(ir.CurFunc) && len(n.Results) == 0 {
+		return n
+	}
+	typecheckaste(ir.ORETURN, nil, false, ir.CurFunc.Type().Results(), n.Results, func() string { return "return argument" })
+	return n
+}
+
+// select
+func tcSelect(sel *ir.SelectStmt) {
+	var def *ir.CommClause
+	lno := ir.SetPos(sel)
+	Stmts(sel.Init())
+	for _, ncase := range sel.Cases {
+		if ncase.Comm == nil {
+			// default
+			if def != nil {
+				base.ErrorfAt(ncase.Pos(), "multiple defaults in select (first at %v)", ir.Line(def))
+			} else {
+				def = ncase
+			}
+		} else {
+			n := Stmt(ncase.Comm)
+			ncase.Comm = n
+			oselrecv2 := func(dst, recv ir.Node, def bool) {
+				n := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
+				n.Def = def
+				n.SetTypecheck(1)
+				ncase.Comm = n
+			}
+			switch n.Op() {
+			default:
+				pos := n.Pos()
+				if n.Op() == ir.ONAME {
+					// We don't have the right position for ONAME nodes (see #15459 and
+					// others). Using ncase.Pos for now as it will provide the correct
+					// line number (assuming the expression follows the "case" keyword
+					// on the same line). This matches the approach before 1.10.
+					pos = ncase.Pos()
+				}
+				base.ErrorfAt(pos, "select case must be receive, send or assign recv")
+
+			case ir.OAS:
+				// convert x = <-c into x, _ = <-c
+				// remove implicit conversions; the eventual assignment
+				// will reintroduce them.
+				n := n.(*ir.AssignStmt)
+				if r := n.Y; r.Op() == ir.OCONVNOP || r.Op() == ir.OCONVIFACE {
+					r := r.(*ir.ConvExpr)
+					if r.Implicit() {
+						n.Y = r.X
+					}
+				}
+				if n.Y.Op() != ir.ORECV {
+					base.ErrorfAt(n.Pos(), "select assignment must have receive on right hand side")
+					break
+				}
+				oselrecv2(n.X, n.Y, n.Def)
+
+			case ir.OAS2RECV:
+				n := n.(*ir.AssignListStmt)
+				if n.Rhs[0].Op() != ir.ORECV {
+					base.ErrorfAt(n.Pos(), "select assignment must have receive on right hand side")
+					break
+				}
+				n.SetOp(ir.OSELRECV2)
+
+			case ir.ORECV:
+				// convert <-c into _, _ = <-c
+				n := n.(*ir.UnaryExpr)
+				oselrecv2(ir.BlankNode, n, false)
+
+			case ir.OSEND:
+				break
+			}
+		}
+
+		Stmts(ncase.Body)
+	}
+
+	base.Pos = lno
+}
+
+// tcSend typechecks an OSEND node.
+func tcSend(n *ir.SendStmt) ir.Node {
+	n.Chan = Expr(n.Chan)
+	n.Value = Expr(n.Value)
+	n.Chan = DefaultLit(n.Chan, nil)
+	t := n.Chan.Type()
+	if t == nil {
+		return n
+	}
+	if !t.IsChan() {
+		base.Errorf("invalid operation: %v (send to non-chan type %v)", n, t)
+		return n
+	}
+
+	if !t.ChanDir().CanSend() {
+		base.Errorf("invalid operation: %v (send to receive-only type %v)", n, t)
+		return n
+	}
+
+	n.Value = AssignConv(n.Value, t.Elem(), "send")
+	if n.Value.Type() == nil {
+		return n
+	}
+	return n
+}
+
+// tcSwitch typechecks a switch statement.
+func tcSwitch(n *ir.SwitchStmt) {
+	Stmts(n.Init())
+	if n.Tag != nil && n.Tag.Op() == ir.OTYPESW {
+		tcSwitchType(n)
+	} else {
+		tcSwitchExpr(n)
+	}
+}
+
+func tcSwitchExpr(n *ir.SwitchStmt) {
+	t := types.Types[types.TBOOL]
+	if n.Tag != nil {
+		n.Tag = Expr(n.Tag)
+		n.Tag = DefaultLit(n.Tag, nil)
+		t = n.Tag.Type()
+	}
+
+	var nilonly string
+	if t != nil {
+		switch {
+		case t.IsMap():
+			nilonly = "map"
+		case t.Kind() == types.TFUNC:
+			nilonly = "func"
+		case t.IsSlice():
+			nilonly = "slice"
+
+		case !types.IsComparable(t):
+			if t.IsStruct() {
+				base.ErrorfAt(n.Pos(), "cannot switch on %L (struct containing %v cannot be compared)", n.Tag, types.IncomparableField(t).Type)
+			} else {
+				base.ErrorfAt(n.Pos(), "cannot switch on %L", n.Tag)
+			}
+			t = nil
+		}
+	}
+
+	var defCase ir.Node
+	var cs constSet
+	for _, ncase := range n.Cases {
+		ls := ncase.List
+		if len(ls) == 0 { // default:
+			if defCase != nil {
+				base.ErrorfAt(ncase.Pos(), "multiple defaults in switch (first at %v)", ir.Line(defCase))
+			} else {
+				defCase = ncase
+			}
+		}
+
+		for i := range ls {
+			ir.SetPos(ncase)
+			ls[i] = Expr(ls[i])
+			ls[i] = DefaultLit(ls[i], t)
+			n1 := ls[i]
+			if t == nil || n1.Type() == nil {
+				continue
+			}
+
+			if nilonly != "" && !ir.IsNil(n1) {
+				base.ErrorfAt(ncase.Pos(), "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Tag)
+			} else if t.IsInterface() && !n1.Type().IsInterface() && !types.IsComparable(n1.Type()) {
+				base.ErrorfAt(ncase.Pos(), "invalid case %L in switch (incomparable type)", n1)
+			} else {
+				op1, _ := Assignop(n1.Type(), t)
+				op2, _ := Assignop(t, n1.Type())
+				if op1 == ir.OXXX && op2 == ir.OXXX {
+					if n.Tag != nil {
+						base.ErrorfAt(ncase.Pos(), "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Tag, n1.Type(), t)
+					} else {
+						base.ErrorfAt(ncase.Pos(), "invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type())
+					}
+				}
+			}
+
+			// Don't check for duplicate bools. Although the spec allows it,
+			// (1) the compiler hasn't checked it in the past, so compatibility mandates it, and
+			// (2) it would disallow useful things like
+			//       case GOARCH == "arm" && GOARM == "5":
+			//       case GOARCH == "arm":
+			//     which would both evaluate to false for non-ARM compiles.
+			if !n1.Type().IsBoolean() {
+				cs.add(ncase.Pos(), n1, "case", "switch")
+			}
+		}
+
+		Stmts(ncase.Body)
+	}
+}
+
+func tcSwitchType(n *ir.SwitchStmt) {
+	guard := n.Tag.(*ir.TypeSwitchGuard)
+	guard.X = Expr(guard.X)
+	t := guard.X.Type()
+	if t != nil && !t.IsInterface() {
+		base.ErrorfAt(n.Pos(), "cannot type switch on non-interface value %L", guard.X)
+		t = nil
+	}
+
+	// We don't actually declare the type switch's guarded
+	// declaration itself. So if there are no cases, we won't
+	// notice that it went unused.
+	if v := guard.Tag; v != nil && !ir.IsBlank(v) && len(n.Cases) == 0 {
+		base.ErrorfAt(v.Pos(), "%v declared but not used", v.Sym())
+	}
+
+	var defCase, nilCase ir.Node
+	var ts typeSet
+	for _, ncase := range n.Cases {
+		ls := ncase.List
+		if len(ls) == 0 { // default:
+			if defCase != nil {
+				base.ErrorfAt(ncase.Pos(), "multiple defaults in switch (first at %v)", ir.Line(defCase))
+			} else {
+				defCase = ncase
+			}
+		}
+
+		for i := range ls {
+			ls[i] = typecheck(ls[i], ctxExpr|ctxType)
+			n1 := ls[i]
+			if t == nil || n1.Type() == nil {
+				continue
+			}
+
+			var missing, have *types.Field
+			var ptr int
+			if ir.IsNil(n1) { // case nil:
+				if nilCase != nil {
+					base.ErrorfAt(ncase.Pos(), "multiple nil cases in type switch (first at %v)", ir.Line(nilCase))
+				} else {
+					nilCase = ncase
+				}
+				continue
+			}
+			if n1.Op() != ir.OTYPE {
+				base.ErrorfAt(ncase.Pos(), "%L is not a type", n1)
+				continue
+			}
+			if !n1.Type().IsInterface() && !implements(n1.Type(), t, &missing, &have, &ptr) && !missing.Broke() {
+				if have != nil && !have.Broke() {
+					base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v"+
+						" (wrong type for %v method)\n\thave %v%S\n\twant %v%S", guard.X, n1.Type(), missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
+				} else if ptr != 0 {
+					base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v"+
+						" (%v method has pointer receiver)", guard.X, n1.Type(), missing.Sym)
+				} else {
+					base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v"+
+						" (missing %v method)", guard.X, n1.Type(), missing.Sym)
+				}
+				continue
+			}
+
+			ts.add(ncase.Pos(), n1.Type())
+		}
+
+		if ncase.Var != nil {
+			// Assign the clause variable's type.
+			vt := t
+			if len(ls) == 1 {
+				if ls[0].Op() == ir.OTYPE {
+					vt = ls[0].Type()
+				} else if !ir.IsNil(ls[0]) {
+					// Invalid single-type case;
+					// mark variable as broken.
+					vt = nil
+				}
+			}
+
+			nvar := ncase.Var
+			nvar.SetType(vt)
+			if vt != nil {
+				nvar = AssignExpr(nvar).(*ir.Name)
+			} else {
+				// Clause variable is broken; prevent typechecking.
+				nvar.SetTypecheck(1)
+				nvar.SetWalkdef(1)
+			}
+			ncase.Var = nvar
+		}
+
+		Stmts(ncase.Body)
+	}
+}
+
+type typeSet struct {
+	m map[string][]typeSetEntry
+}
+
+type typeSetEntry struct {
+	pos src.XPos
+	typ *types.Type
+}
+
+func (s *typeSet) add(pos src.XPos, typ *types.Type) {
+	if s.m == nil {
+		s.m = make(map[string][]typeSetEntry)
+	}
+
+	// LongString does not uniquely identify types, so we need to
+	// disambiguate collisions with types.Identical.
+	// TODO(mdempsky): Add a method that *is* unique.
+	ls := typ.LongString()
+	prevs := s.m[ls]
+	for _, prev := range prevs {
+		if types.Identical(typ, prev.typ) {
+			base.ErrorfAt(pos, "duplicate case %v in type switch\n\tprevious case at %s", typ, base.FmtPos(prev.pos))
+			return
+		}
+	}
+	s.m[ls] = append(prevs, typeSetEntry{pos, typ})
+}
diff --git a/src/cmd/compile/internal/typecheck/subr.go b/src/cmd/compile/internal/typecheck/subr.go
new file mode 100644
index 0000000..9ee7a94
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/subr.go
@@ -0,0 +1,876 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typecheck
+
+import (
+	"fmt"
+	"sort"
+	"strconv"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+func AssignConv(n ir.Node, t *types.Type, context string) ir.Node {
+	return assignconvfn(n, t, func() string { return context })
+}
+
+// DotImportRefs maps idents introduced by importDot back to the
+// ir.PkgName they were dot-imported through.
+var DotImportRefs map[*ir.Ident]*ir.PkgName
+
+// LookupNum looks up the symbol starting with prefix and ending with
+// the decimal n. If prefix is too long, LookupNum panics.
+func LookupNum(prefix string, n int) *types.Sym {
+	var buf [20]byte // plenty long enough for all current users
+	copy(buf[:], prefix)
+	b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10)
+	return types.LocalPkg.LookupBytes(b)
+}
+
+// Given funarg struct list, return list of fn args.
+func NewFuncParams(tl *types.Type, mustname bool) []*ir.Field {
+	var args []*ir.Field
+	gen := 0
+	for _, t := range tl.Fields().Slice() {
+		s := t.Sym
+		if mustname && (s == nil || s.Name == "_") {
+			// invent a name so that we can refer to it in the trampoline
+			s = LookupNum(".anon", gen)
+			gen++
+		} else if s != nil && s.Pkg != types.LocalPkg {
+			// TODO(mdempsky): Preserve original position, name, and package.
+			s = Lookup(s.Name)
+		}
+		a := ir.NewField(base.Pos, s, nil, t.Type)
+		a.Pos = t.Pos
+		a.IsDDD = t.IsDDD()
+		args = append(args, a)
+	}
+
+	return args
+}
+
+// newname returns a new ONAME Node associated with symbol s.
+func NewName(s *types.Sym) *ir.Name {
+	n := ir.NewNameAt(base.Pos, s)
+	n.Curfn = ir.CurFunc
+	return n
+}
+
+// NodAddr returns a node representing &n at base.Pos.
+func NodAddr(n ir.Node) *ir.AddrExpr {
+	return NodAddrAt(base.Pos, n)
+}
+
+// nodAddrPos returns a node representing &n at position pos.
+func NodAddrAt(pos src.XPos, n ir.Node) *ir.AddrExpr {
+	n = markAddrOf(n)
+	return ir.NewAddrExpr(pos, n)
+}
+
+func markAddrOf(n ir.Node) ir.Node {
+	if IncrementalAddrtaken {
+		// We can only do incremental addrtaken computation when it is ok
+		// to typecheck the argument of the OADDR. That's only safe after the
+		// main typecheck has completed.
+		// The argument to OADDR needs to be typechecked because &x[i] takes
+		// the address of x if x is an array, but not if x is a slice.
+		// Note: OuterValue doesn't work correctly until n is typechecked.
+		n = typecheck(n, ctxExpr)
+		if x := ir.OuterValue(n); x.Op() == ir.ONAME {
+			x.Name().SetAddrtaken(true)
+		}
+	} else {
+		// Remember that we built an OADDR without computing the Addrtaken bit for
+		// its argument. We'll do that later in bulk using computeAddrtaken.
+		DirtyAddrtaken = true
+	}
+	return n
+}
+
+// If IncrementalAddrtaken is false, we do not compute Addrtaken for an OADDR Node
+// when it is built. The Addrtaken bits are set in bulk by computeAddrtaken.
+// If IncrementalAddrtaken is true, then when an OADDR Node is built the Addrtaken
+// field of its argument is updated immediately.
+var IncrementalAddrtaken = false
+
+// If DirtyAddrtaken is true, then there are OADDR whose corresponding arguments
+// have not yet been marked as Addrtaken.
+var DirtyAddrtaken = false
+
+func ComputeAddrtaken(top []ir.Node) {
+	for _, n := range top {
+		var doVisit func(n ir.Node)
+		doVisit = func(n ir.Node) {
+			if n.Op() == ir.OADDR {
+				if x := ir.OuterValue(n.(*ir.AddrExpr).X); x.Op() == ir.ONAME {
+					x.Name().SetAddrtaken(true)
+					if x.Name().IsClosureVar() {
+						// Mark the original variable as Addrtaken so that capturevars
+						// knows not to pass it by value.
+						x.Name().Defn.Name().SetAddrtaken(true)
+					}
+				}
+			}
+			if n.Op() == ir.OCLOSURE {
+				ir.VisitList(n.(*ir.ClosureExpr).Func.Body, doVisit)
+			}
+		}
+		ir.Visit(n, doVisit)
+	}
+}
+
+func NodNil() ir.Node {
+	n := ir.NewNilExpr(base.Pos)
+	n.SetType(types.Types[types.TNIL])
+	return n
+}
+
+// AddImplicitDots finds missing fields in obj.field that
+// will give the shortest unique addressing and
+// modifies the tree with missing field names.
+func AddImplicitDots(n *ir.SelectorExpr) *ir.SelectorExpr {
+	n.X = typecheck(n.X, ctxType|ctxExpr)
+	if n.X.Diag() {
+		n.SetDiag(true)
+	}
+	t := n.X.Type()
+	if t == nil {
+		return n
+	}
+
+	if n.X.Op() == ir.OTYPE {
+		return n
+	}
+
+	s := n.Sel
+	if s == nil {
+		return n
+	}
+
+	switch path, ambig := dotpath(s, t, nil, false); {
+	case path != nil:
+		// rebuild elided dots
+		for c := len(path) - 1; c >= 0; c-- {
+			dot := ir.NewSelectorExpr(base.Pos, ir.ODOT, n.X, path[c].field.Sym)
+			dot.SetImplicit(true)
+			dot.SetType(path[c].field.Type)
+			n.X = dot
+		}
+	case ambig:
+		base.Errorf("ambiguous selector %v", n)
+		n.X = nil
+	}
+
+	return n
+}
+
+func CalcMethods(t *types.Type) {
+	if t == nil || t.AllMethods().Len() != 0 {
+		return
+	}
+
+	// mark top-level method symbols
+	// so that expand1 doesn't consider them.
+	for _, f := range t.Methods().Slice() {
+		f.Sym.SetUniq(true)
+	}
+
+	// generate all reachable methods
+	slist = slist[:0]
+	expand1(t, true)
+
+	// check each method to be uniquely reachable
+	var ms []*types.Field
+	for i, sl := range slist {
+		slist[i].field = nil
+		sl.field.Sym.SetUniq(false)
+
+		var f *types.Field
+		path, _ := dotpath(sl.field.Sym, t, &f, false)
+		if path == nil {
+			continue
+		}
+
+		// dotpath may have dug out arbitrary fields, we only want methods.
+		if !f.IsMethod() {
+			continue
+		}
+
+		// add it to the base type method list
+		f = f.Copy()
+		f.Embedded = 1 // needs a trampoline
+		for _, d := range path {
+			if d.field.Type.IsPtr() {
+				f.Embedded = 2
+				break
+			}
+		}
+		ms = append(ms, f)
+	}
+
+	for _, f := range t.Methods().Slice() {
+		f.Sym.SetUniq(false)
+	}
+
+	ms = append(ms, t.Methods().Slice()...)
+	sort.Sort(types.MethodsByName(ms))
+	t.SetAllMethods(ms)
+}
+
+// adddot1 returns the number of fields or methods named s at depth d in Type t.
+// If exactly one exists, it will be returned in *save (if save is not nil),
+// and dotlist will contain the path of embedded fields traversed to find it,
+// in reverse order. If none exist, more will indicate whether t contains any
+// embedded fields at depth d, so callers can decide whether to retry at
+// a greater depth.
+func adddot1(s *types.Sym, t *types.Type, d int, save **types.Field, ignorecase bool) (c int, more bool) {
+	if t.Recur() {
+		return
+	}
+	t.SetRecur(true)
+	defer t.SetRecur(false)
+
+	var u *types.Type
+	d--
+	if d < 0 {
+		// We've reached our target depth. If t has any fields/methods
+		// named s, then we're done. Otherwise, we still need to check
+		// below for embedded fields.
+		c = lookdot0(s, t, save, ignorecase)
+		if c != 0 {
+			return c, false
+		}
+	}
+
+	u = t
+	if u.IsPtr() {
+		u = u.Elem()
+	}
+	if !u.IsStruct() && !u.IsInterface() {
+		return c, false
+	}
+
+	var fields *types.Fields
+	if u.IsStruct() {
+		fields = u.Fields()
+	} else {
+		fields = u.AllMethods()
+	}
+	for _, f := range fields.Slice() {
+		if f.Embedded == 0 || f.Sym == nil {
+			continue
+		}
+		if d < 0 {
+			// Found an embedded field at target depth.
+			return c, true
+		}
+		a, more1 := adddot1(s, f.Type, d, save, ignorecase)
+		if a != 0 && c == 0 {
+			dotlist[d].field = f
+		}
+		c += a
+		if more1 {
+			more = true
+		}
+	}
+
+	return c, more
+}
+
+// dotlist is used by adddot1 to record the path of embedded fields
+// used to access a target field or method.
+// Must be non-nil so that dotpath returns a non-nil slice even if d is zero.
+var dotlist = make([]dlist, 10)
+
+// Convert node n for assignment to type t.
+func assignconvfn(n ir.Node, t *types.Type, context func() string) ir.Node {
+	if n == nil || n.Type() == nil || n.Type().Broke() {
+		return n
+	}
+
+	if t.Kind() == types.TBLANK && n.Type().Kind() == types.TNIL {
+		base.Errorf("use of untyped nil")
+	}
+
+	n = convlit1(n, t, false, context)
+	if n.Type() == nil {
+		return n
+	}
+	if t.Kind() == types.TBLANK {
+		return n
+	}
+
+	// Convert ideal bool from comparison to plain bool
+	// if the next step is non-bool (like interface{}).
+	if n.Type() == types.UntypedBool && !t.IsBoolean() {
+		if n.Op() == ir.ONAME || n.Op() == ir.OLITERAL {
+			r := ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, n)
+			r.SetType(types.Types[types.TBOOL])
+			r.SetTypecheck(1)
+			r.SetImplicit(true)
+			n = r
+		}
+	}
+
+	if types.Identical(n.Type(), t) {
+		return n
+	}
+
+	op, why := Assignop(n.Type(), t)
+	if op == ir.OXXX {
+		base.Errorf("cannot use %L as type %v in %s%s", n, t, context(), why)
+		op = ir.OCONV
+	}
+
+	r := ir.NewConvExpr(base.Pos, op, t, n)
+	r.SetTypecheck(1)
+	r.SetImplicit(true)
+	return r
+}
+
+// Is type src assignment compatible to type dst?
+// If so, return op code to use in conversion.
+// If not, return OXXX. In this case, the string return parameter may
+// hold a reason why. In all other cases, it'll be the empty string.
+func Assignop(src, dst *types.Type) (ir.Op, string) {
+	if src == dst {
+		return ir.OCONVNOP, ""
+	}
+	if src == nil || dst == nil || src.Kind() == types.TFORW || dst.Kind() == types.TFORW || src.Underlying() == nil || dst.Underlying() == nil {
+		return ir.OXXX, ""
+	}
+
+	// 1. src type is identical to dst.
+	if types.Identical(src, dst) {
+		return ir.OCONVNOP, ""
+	}
+
+	// 2. src and dst have identical underlying types
+	// and either src or dst is not a named type or
+	// both are empty interface types.
+	// For assignable but different non-empty interface types,
+	// we want to recompute the itab. Recomputing the itab ensures
+	// that itabs are unique (thus an interface with a compile-time
+	// type I has an itab with interface type I).
+	if types.Identical(src.Underlying(), dst.Underlying()) {
+		if src.IsEmptyInterface() {
+			// Conversion between two empty interfaces
+			// requires no code.
+			return ir.OCONVNOP, ""
+		}
+		if (src.Sym() == nil || dst.Sym() == nil) && !src.IsInterface() {
+			// Conversion between two types, at least one unnamed,
+			// needs no conversion. The exception is nonempty interfaces
+			// which need to have their itab updated.
+			return ir.OCONVNOP, ""
+		}
+	}
+
+	// 3. dst is an interface type and src implements dst.
+	if dst.IsInterface() && src.Kind() != types.TNIL {
+		var missing, have *types.Field
+		var ptr int
+		if implements(src, dst, &missing, &have, &ptr) {
+			// Call NeedITab/ITabAddr so that (src, dst)
+			// gets added to itabs early, which allows
+			// us to de-virtualize calls through this
+			// type/interface pair later. See CompileITabs in reflect.go
+			if types.IsDirectIface(src) && !dst.IsEmptyInterface() {
+				NeedITab(src, dst)
+			}
+
+			return ir.OCONVIFACE, ""
+		}
+
+		// we'll have complained about this method anyway, suppress spurious messages.
+		if have != nil && have.Sym == missing.Sym && (have.Type.Broke() || missing.Type.Broke()) {
+			return ir.OCONVIFACE, ""
+		}
+
+		var why string
+		if isptrto(src, types.TINTER) {
+			why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src)
+		} else if have != nil && have.Sym == missing.Sym && have.Nointerface() {
+			why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym)
+		} else if have != nil && have.Sym == missing.Sym {
+			why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+
+				"\t\thave %v%S\n\t\twant %v%S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
+		} else if ptr != 0 {
+			why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym)
+		} else if have != nil {
+			why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)\n"+
+				"\t\thave %v%S\n\t\twant %v%S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
+		} else {
+			why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym)
+		}
+
+		return ir.OXXX, why
+	}
+
+	if isptrto(dst, types.TINTER) {
+		why := fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst)
+		return ir.OXXX, why
+	}
+
+	if src.IsInterface() && dst.Kind() != types.TBLANK {
+		var missing, have *types.Field
+		var ptr int
+		var why string
+		if implements(dst, src, &missing, &have, &ptr) {
+			why = ": need type assertion"
+		}
+		return ir.OXXX, why
+	}
+
+	// 4. src is a bidirectional channel value, dst is a channel type,
+	// src and dst have identical element types, and
+	// either src or dst is not a named type.
+	if src.IsChan() && src.ChanDir() == types.Cboth && dst.IsChan() {
+		if types.Identical(src.Elem(), dst.Elem()) && (src.Sym() == nil || dst.Sym() == nil) {
+			return ir.OCONVNOP, ""
+		}
+	}
+
+	// 5. src is the predeclared identifier nil and dst is a nillable type.
+	if src.Kind() == types.TNIL {
+		switch dst.Kind() {
+		case types.TPTR,
+			types.TFUNC,
+			types.TMAP,
+			types.TCHAN,
+			types.TINTER,
+			types.TSLICE:
+			return ir.OCONVNOP, ""
+		}
+	}
+
+	// 6. rule about untyped constants - already converted by DefaultLit.
+
+	// 7. Any typed value can be assigned to the blank identifier.
+	if dst.Kind() == types.TBLANK {
+		return ir.OCONVNOP, ""
+	}
+
+	return ir.OXXX, ""
+}
+
+// Can we convert a value of type src to a value of type dst?
+// If so, return op code to use in conversion (maybe OCONVNOP).
+// If not, return OXXX. In this case, the string return parameter may
+// hold a reason why. In all other cases, it'll be the empty string.
+// srcConstant indicates whether the value of type src is a constant.
+func Convertop(srcConstant bool, src, dst *types.Type) (ir.Op, string) {
+	if src == dst {
+		return ir.OCONVNOP, ""
+	}
+	if src == nil || dst == nil {
+		return ir.OXXX, ""
+	}
+
+	// Conversions from regular to go:notinheap are not allowed
+	// (unless it's unsafe.Pointer). These are runtime-specific
+	// rules.
+	// (a) Disallow (*T) to (*U) where T is go:notinheap but U isn't.
+	if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() {
+		why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable), but %v is not", dst.Elem(), src.Elem())
+		return ir.OXXX, why
+	}
+	// (b) Disallow string to []T where T is go:notinheap.
+	if src.IsString() && dst.IsSlice() && dst.Elem().NotInHeap() && (dst.Elem().Kind() == types.ByteType.Kind() || dst.Elem().Kind() == types.RuneType.Kind()) {
+		why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable)", dst.Elem())
+		return ir.OXXX, why
+	}
+
+	// 1. src can be assigned to dst.
+	op, why := Assignop(src, dst)
+	if op != ir.OXXX {
+		return op, why
+	}
+
+	// The rules for interfaces are no different in conversions
+	// than assignments. If interfaces are involved, stop now
+	// with the good message from assignop.
+	// Otherwise clear the error.
+	if src.IsInterface() || dst.IsInterface() {
+		return ir.OXXX, why
+	}
+
+	// 2. Ignoring struct tags, src and dst have identical underlying types.
+	if types.IdenticalIgnoreTags(src.Underlying(), dst.Underlying()) {
+		return ir.OCONVNOP, ""
+	}
+
+	// 3. src and dst are unnamed pointer types and, ignoring struct tags,
+	// their base types have identical underlying types.
+	if src.IsPtr() && dst.IsPtr() && src.Sym() == nil && dst.Sym() == nil {
+		if types.IdenticalIgnoreTags(src.Elem().Underlying(), dst.Elem().Underlying()) {
+			return ir.OCONVNOP, ""
+		}
+	}
+
+	// 4. src and dst are both integer or floating point types.
+	if (src.IsInteger() || src.IsFloat()) && (dst.IsInteger() || dst.IsFloat()) {
+		if types.SimType[src.Kind()] == types.SimType[dst.Kind()] {
+			return ir.OCONVNOP, ""
+		}
+		return ir.OCONV, ""
+	}
+
+	// 5. src and dst are both complex types.
+	if src.IsComplex() && dst.IsComplex() {
+		if types.SimType[src.Kind()] == types.SimType[dst.Kind()] {
+			return ir.OCONVNOP, ""
+		}
+		return ir.OCONV, ""
+	}
+
+	// Special case for constant conversions: any numeric
+	// conversion is potentially okay. We'll validate further
+	// within evconst. See #38117.
+	if srcConstant && (src.IsInteger() || src.IsFloat() || src.IsComplex()) && (dst.IsInteger() || dst.IsFloat() || dst.IsComplex()) {
+		return ir.OCONV, ""
+	}
+
+	// 6. src is an integer or has type []byte or []rune
+	// and dst is a string type.
+	if src.IsInteger() && dst.IsString() {
+		return ir.ORUNESTR, ""
+	}
+
+	if src.IsSlice() && dst.IsString() {
+		if src.Elem().Kind() == types.ByteType.Kind() {
+			return ir.OBYTES2STR, ""
+		}
+		if src.Elem().Kind() == types.RuneType.Kind() {
+			return ir.ORUNES2STR, ""
+		}
+	}
+
+	// 7. src is a string and dst is []byte or []rune.
+	// String to slice.
+	if src.IsString() && dst.IsSlice() {
+		if dst.Elem().Kind() == types.ByteType.Kind() {
+			return ir.OSTR2BYTES, ""
+		}
+		if dst.Elem().Kind() == types.RuneType.Kind() {
+			return ir.OSTR2RUNES, ""
+		}
+	}
+
+	// 8. src is a pointer or uintptr and dst is unsafe.Pointer.
+	if (src.IsPtr() || src.IsUintptr()) && dst.IsUnsafePtr() {
+		return ir.OCONVNOP, ""
+	}
+
+	// 9. src is unsafe.Pointer and dst is a pointer or uintptr.
+	if src.IsUnsafePtr() && (dst.IsPtr() || dst.IsUintptr()) {
+		return ir.OCONVNOP, ""
+	}
+
+	// 10. 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.Kind() == types.TMAP && dst.IsPtr() &&
+		src.MapType().Hmap == dst.Elem() {
+		return ir.OCONVNOP, ""
+	}
+
+	// 11. src is a slice and dst is a pointer-to-array.
+	// They must have same element type.
+	if src.IsSlice() && dst.IsPtr() && dst.Elem().IsArray() &&
+		types.Identical(src.Elem(), dst.Elem().Elem()) {
+		if !types.AllowsGoVersion(curpkg(), 1, 17) {
+			return ir.OXXX, ":\n\tconversion of slices to array pointers only supported as of -lang=go1.17"
+		}
+		return ir.OSLICE2ARRPTR, ""
+	}
+
+	return ir.OXXX, ""
+}
+
+// Code to resolve elided DOTs in embedded types.
+
+// A dlist stores a pointer to a TFIELD Type embedded within
+// a TSTRUCT or TINTER Type.
+type dlist struct {
+	field *types.Field
+}
+
+// dotpath computes the unique shortest explicit selector path to fully qualify
+// a selection expression x.f, where x is of type t and f is the symbol s.
+// If no such path exists, dotpath returns nil.
+// If there are multiple shortest paths to the same depth, ambig is true.
+func dotpath(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) (path []dlist, ambig bool) {
+	// The embedding of types within structs imposes a tree structure onto
+	// types: structs parent the types they embed, and types parent their
+	// fields or methods. Our goal here is to find the shortest path to
+	// a field or method named s in the subtree rooted at t. To accomplish
+	// that, we iteratively perform depth-first searches of increasing depth
+	// until we either find the named field/method or exhaust the tree.
+	for d := 0; ; d++ {
+		if d > len(dotlist) {
+			dotlist = append(dotlist, dlist{})
+		}
+		if c, more := adddot1(s, t, d, save, ignorecase); c == 1 {
+			return dotlist[:d], false
+		} else if c > 1 {
+			return nil, true
+		} else if !more {
+			return nil, false
+		}
+	}
+}
+
+func expand0(t *types.Type) {
+	u := t
+	if u.IsPtr() {
+		u = u.Elem()
+	}
+
+	if u.IsInterface() {
+		for _, f := range u.AllMethods().Slice() {
+			if f.Sym.Uniq() {
+				continue
+			}
+			f.Sym.SetUniq(true)
+			slist = append(slist, symlink{field: f})
+		}
+
+		return
+	}
+
+	u = types.ReceiverBaseType(t)
+	if u != nil {
+		for _, f := range u.Methods().Slice() {
+			if f.Sym.Uniq() {
+				continue
+			}
+			f.Sym.SetUniq(true)
+			slist = append(slist, symlink{field: f})
+		}
+	}
+}
+
+func expand1(t *types.Type, top bool) {
+	if t.Recur() {
+		return
+	}
+	t.SetRecur(true)
+
+	if !top {
+		expand0(t)
+	}
+
+	u := t
+	if u.IsPtr() {
+		u = u.Elem()
+	}
+
+	if u.IsStruct() || u.IsInterface() {
+		var fields *types.Fields
+		if u.IsStruct() {
+			fields = u.Fields()
+		} else {
+			fields = u.AllMethods()
+		}
+		for _, f := range fields.Slice() {
+			if f.Embedded == 0 {
+				continue
+			}
+			if f.Sym == nil {
+				continue
+			}
+			expand1(f.Type, false)
+		}
+	}
+
+	t.SetRecur(false)
+}
+
+func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) (m *types.Field, followptr bool) {
+	if t == nil {
+		return nil, false
+	}
+
+	path, ambig := dotpath(s, t, &m, ignorecase)
+	if path == nil {
+		if ambig {
+			base.Errorf("%v.%v is ambiguous", t, s)
+		}
+		return nil, false
+	}
+
+	for _, d := range path {
+		if d.field.Type.IsPtr() {
+			followptr = true
+			break
+		}
+	}
+
+	if !m.IsMethod() {
+		base.Errorf("%v.%v is a field, not a method", t, s)
+		return nil, followptr
+	}
+
+	return m, followptr
+}
+
+func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool {
+	t0 := t
+	if t == nil {
+		return false
+	}
+
+	if t.IsInterface() {
+		i := 0
+		tms := t.AllMethods().Slice()
+		for _, im := range iface.AllMethods().Slice() {
+			for i < len(tms) && tms[i].Sym != im.Sym {
+				i++
+			}
+			if i == len(tms) {
+				*m = im
+				*samename = nil
+				*ptr = 0
+				return false
+			}
+			tm := tms[i]
+			if !types.Identical(tm.Type, im.Type) {
+				*m = im
+				*samename = tm
+				*ptr = 0
+				return false
+			}
+		}
+
+		return true
+	}
+
+	t = types.ReceiverBaseType(t)
+	var tms []*types.Field
+	if t != nil {
+		CalcMethods(t)
+		tms = t.AllMethods().Slice()
+	}
+	i := 0
+	for _, im := range iface.AllMethods().Slice() {
+		if im.Broke() {
+			continue
+		}
+		for i < len(tms) && tms[i].Sym != im.Sym {
+			i++
+		}
+		if i == len(tms) {
+			*m = im
+			*samename, _ = ifacelookdot(im.Sym, t, true)
+			*ptr = 0
+			return false
+		}
+		tm := tms[i]
+		if tm.Nointerface() || !types.Identical(tm.Type, im.Type) {
+			*m = im
+			*samename = tm
+			*ptr = 0
+			return false
+		}
+		followptr := tm.Embedded == 2
+
+		// if pointer receiver in method,
+		// the method does not exist for value types.
+		rcvr := tm.Type.Recv().Type
+		if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !types.IsInterfaceMethod(tm.Type) {
+			if false && base.Flag.LowerR != 0 {
+				base.Errorf("interface pointer mismatch")
+			}
+
+			*m = im
+			*samename = nil
+			*ptr = 1
+			return false
+		}
+	}
+
+	return true
+}
+
+func isptrto(t *types.Type, et types.Kind) bool {
+	if t == nil {
+		return false
+	}
+	if !t.IsPtr() {
+		return false
+	}
+	t = t.Elem()
+	if t == nil {
+		return false
+	}
+	if t.Kind() != et {
+		return false
+	}
+	return true
+}
+
+// lookdot0 returns the number of fields or methods named s associated
+// with Type t. If exactly one exists, it will be returned in *save
+// (if save is not nil).
+func lookdot0(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) int {
+	u := t
+	if u.IsPtr() {
+		u = u.Elem()
+	}
+
+	c := 0
+	if u.IsStruct() || u.IsInterface() {
+		var fields *types.Fields
+		if u.IsStruct() {
+			fields = u.Fields()
+		} else {
+			fields = u.AllMethods()
+		}
+		for _, f := range fields.Slice() {
+			if f.Sym == s || (ignorecase && f.IsMethod() && strings.EqualFold(f.Sym.Name, s.Name)) {
+				if save != nil {
+					*save = f
+				}
+				c++
+			}
+		}
+	}
+
+	u = t
+	if t.Sym() != nil && t.IsPtr() && !t.Elem().IsPtr() {
+		// If t is a defined pointer type, then x.m is shorthand for (*x).m.
+		u = t.Elem()
+	}
+	u = types.ReceiverBaseType(u)
+	if u != nil {
+		for _, f := range u.Methods().Slice() {
+			if f.Embedded == 0 && (f.Sym == s || (ignorecase && strings.EqualFold(f.Sym.Name, s.Name))) {
+				if save != nil {
+					*save = f
+				}
+				c++
+			}
+		}
+	}
+
+	return c
+}
+
+var slist []symlink
+
+// Code to help generate trampoline functions for methods on embedded
+// types. These are approx the same as the corresponding AddImplicitDots
+// routines except that they expect to be called with unique tasks and
+// they return the actual methods.
+
+type symlink struct {
+	field *types.Field
+}
diff --git a/src/cmd/compile/internal/typecheck/syms.go b/src/cmd/compile/internal/typecheck/syms.go
new file mode 100644
index 0000000..f29af82
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/syms.go
@@ -0,0 +1,103 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typecheck
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/src"
+)
+
+func LookupRuntime(name string) *ir.Name {
+	s := ir.Pkgs.Runtime.Lookup(name)
+	if s == nil || s.Def == nil {
+		base.Fatalf("LookupRuntime: can't find runtime.%s", name)
+	}
+	return ir.AsNode(s.Def).(*ir.Name)
+}
+
+// SubstArgTypes substitutes the given list of types for
+// successive occurrences of the "any" placeholder in the
+// type syntax expression n.Type.
+// The result of SubstArgTypes MUST be assigned back to old, e.g.
+// 	n.Left = SubstArgTypes(n.Left, t1, t2)
+func SubstArgTypes(old *ir.Name, types_ ...*types.Type) *ir.Name {
+	for _, t := range types_ {
+		types.CalcSize(t)
+	}
+	n := ir.NewNameAt(old.Pos(), old.Sym())
+	n.Class = old.Class
+	n.SetType(types.SubstAny(old.Type(), &types_))
+	n.Func = old.Func
+	if len(types_) > 0 {
+		base.Fatalf("SubstArgTypes: too many argument types")
+	}
+	return n
+}
+
+// AutoLabel generates a new Name node for use with
+// an automatically generated label.
+// prefix is a short mnemonic (e.g. ".s" for switch)
+// to help with debugging.
+// It should begin with "." to avoid conflicts with
+// user labels.
+func AutoLabel(prefix string) *types.Sym {
+	if prefix[0] != '.' {
+		base.Fatalf("autolabel prefix must start with '.', have %q", prefix)
+	}
+	fn := ir.CurFunc
+	if ir.CurFunc == nil {
+		base.Fatalf("autolabel outside function")
+	}
+	n := fn.Label
+	fn.Label++
+	return LookupNum(prefix, int(n))
+}
+
+func Lookup(name string) *types.Sym {
+	return types.LocalPkg.Lookup(name)
+}
+
+// InitRuntime loads the definitions for the low-level runtime functions,
+// so that the compiler can generate calls to them,
+// but does not make them visible to user code.
+func InitRuntime() {
+	base.Timer.Start("fe", "loadsys")
+	types.Block = 1
+
+	typs := runtimeTypes()
+	for _, d := range &runtimeDecls {
+		sym := ir.Pkgs.Runtime.Lookup(d.name)
+		typ := typs[d.typ]
+		switch d.tag {
+		case funcTag:
+			importfunc(ir.Pkgs.Runtime, src.NoXPos, sym, typ)
+		case varTag:
+			importvar(ir.Pkgs.Runtime, src.NoXPos, sym, typ)
+		default:
+			base.Fatalf("unhandled declaration tag %v", d.tag)
+		}
+	}
+}
+
+// LookupRuntimeFunc looks up Go function name in package runtime. This function
+// must follow the internal calling convention.
+func LookupRuntimeFunc(name string) *obj.LSym {
+	return LookupRuntimeABI(name, obj.ABIInternal)
+}
+
+// LookupRuntimeVar looks up a variable (or assembly function) name in package
+// runtime. If this is a function, it may have a special calling
+// convention.
+func LookupRuntimeVar(name string) *obj.LSym {
+	return LookupRuntimeABI(name, obj.ABI0)
+}
+
+// LookupRuntimeABI looks up a name in package runtime using the given ABI.
+func LookupRuntimeABI(name string, abi obj.ABI) *obj.LSym {
+	return base.PkgLinksym("runtime", name, abi)
+}
diff --git a/src/cmd/compile/internal/typecheck/target.go b/src/cmd/compile/internal/typecheck/target.go
new file mode 100644
index 0000000..018614d
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/target.go
@@ -0,0 +1,12 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run mkbuiltin.go
+
+package typecheck
+
+import "cmd/compile/internal/ir"
+
+// Target is the package being compiled.
+var Target *ir.Package
diff --git a/src/cmd/compile/internal/typecheck/type.go b/src/cmd/compile/internal/typecheck/type.go
new file mode 100644
index 0000000..af694c2
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/type.go
@@ -0,0 +1,188 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typecheck
+
+import (
+	"go/constant"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+)
+
+// tcArrayType typechecks an OTARRAY node.
+func tcArrayType(n *ir.ArrayType) ir.Node {
+	n.Elem = typecheckNtype(n.Elem)
+	if n.Elem.Type() == nil {
+		return n
+	}
+	if n.Len == nil { // [...]T
+		if !n.Diag() {
+			n.SetDiag(true)
+			base.Errorf("use of [...] array outside of array literal")
+		}
+		return n
+	}
+	n.Len = indexlit(Expr(n.Len))
+	size := n.Len
+	if ir.ConstType(size) != constant.Int {
+		switch {
+		case size.Type() == nil:
+			// Error already reported elsewhere.
+		case size.Type().IsInteger() && size.Op() != ir.OLITERAL:
+			base.Errorf("non-constant array bound %v", size)
+		default:
+			base.Errorf("invalid array bound %v", size)
+		}
+		return n
+	}
+
+	v := size.Val()
+	if ir.ConstOverflow(v, types.Types[types.TINT]) {
+		base.Errorf("array bound is too large")
+		return n
+	}
+
+	if constant.Sign(v) < 0 {
+		base.Errorf("array bound must be non-negative")
+		return n
+	}
+
+	bound, _ := constant.Int64Val(v)
+	t := types.NewArray(n.Elem.Type(), bound)
+	n.SetOTYPE(t)
+	types.CheckSize(t)
+	return n
+}
+
+// tcChanType typechecks an OTCHAN node.
+func tcChanType(n *ir.ChanType) ir.Node {
+	n.Elem = typecheckNtype(n.Elem)
+	l := n.Elem
+	if l.Type() == nil {
+		return n
+	}
+	if l.Type().NotInHeap() {
+		base.Errorf("chan of incomplete (or unallocatable) type not allowed")
+	}
+	n.SetOTYPE(types.NewChan(l.Type(), n.Dir))
+	return n
+}
+
+// tcFuncType typechecks an OTFUNC node.
+func tcFuncType(n *ir.FuncType) ir.Node {
+	misc := func(f *types.Field, nf *ir.Field) {
+		f.SetIsDDD(nf.IsDDD)
+		if nf.Decl != nil {
+			nf.Decl.SetType(f.Type)
+			f.Nname = nf.Decl
+		}
+	}
+
+	lno := base.Pos
+
+	var recv *types.Field
+	if n.Recv != nil {
+		recv = tcField(n.Recv, misc)
+	}
+
+	t := types.NewSignature(types.LocalPkg, recv, nil, tcFields(n.Params, misc), tcFields(n.Results, misc))
+	checkdupfields("argument", t.Recvs().FieldSlice(), t.Params().FieldSlice(), t.Results().FieldSlice())
+
+	base.Pos = lno
+
+	n.SetOTYPE(t)
+	return n
+}
+
+// tcInterfaceType typechecks an OTINTER node.
+func tcInterfaceType(n *ir.InterfaceType) ir.Node {
+	if len(n.Methods) == 0 {
+		n.SetOTYPE(types.Types[types.TINTER])
+		return n
+	}
+
+	lno := base.Pos
+	methods := tcFields(n.Methods, nil)
+	base.Pos = lno
+
+	n.SetOTYPE(types.NewInterface(types.LocalPkg, methods))
+	return n
+}
+
+// tcMapType typechecks an OTMAP node.
+func tcMapType(n *ir.MapType) ir.Node {
+	n.Key = typecheckNtype(n.Key)
+	n.Elem = typecheckNtype(n.Elem)
+	l := n.Key
+	r := n.Elem
+	if l.Type() == nil || r.Type() == nil {
+		return n
+	}
+	if l.Type().NotInHeap() {
+		base.Errorf("incomplete (or unallocatable) map key not allowed")
+	}
+	if r.Type().NotInHeap() {
+		base.Errorf("incomplete (or unallocatable) map value not allowed")
+	}
+	n.SetOTYPE(types.NewMap(l.Type(), r.Type()))
+	mapqueue = append(mapqueue, n) // check map keys when all types are settled
+	return n
+}
+
+// tcSliceType typechecks an OTSLICE node.
+func tcSliceType(n *ir.SliceType) ir.Node {
+	n.Elem = typecheckNtype(n.Elem)
+	if n.Elem.Type() == nil {
+		return n
+	}
+	t := types.NewSlice(n.Elem.Type())
+	n.SetOTYPE(t)
+	types.CheckSize(t)
+	return n
+}
+
+// tcStructType typechecks an OTSTRUCT node.
+func tcStructType(n *ir.StructType) ir.Node {
+	lno := base.Pos
+
+	fields := tcFields(n.Fields, func(f *types.Field, nf *ir.Field) {
+		if nf.Embedded {
+			checkembeddedtype(f.Type)
+			f.Embedded = 1
+		}
+		f.Note = nf.Note
+	})
+	checkdupfields("field", fields)
+
+	base.Pos = lno
+	n.SetOTYPE(types.NewStruct(types.LocalPkg, fields))
+	return n
+}
+
+// tcField typechecks a generic Field.
+// misc can be provided to handle specialized typechecking.
+func tcField(n *ir.Field, misc func(*types.Field, *ir.Field)) *types.Field {
+	base.Pos = n.Pos
+	if n.Ntype != nil {
+		n.Type = typecheckNtype(n.Ntype).Type()
+		n.Ntype = nil
+	}
+	f := types.NewField(n.Pos, n.Sym, n.Type)
+	if misc != nil {
+		misc(f, n)
+	}
+	return f
+}
+
+// tcFields typechecks a slice of generic Fields.
+// misc can be provided to handle specialized typechecking.
+func tcFields(l []*ir.Field, misc func(*types.Field, *ir.Field)) []*types.Field {
+	fields := make([]*types.Field, len(l))
+	for i, n := range l {
+		fields[i] = tcField(n, misc)
+	}
+	return fields
+}
diff --git a/src/cmd/compile/internal/typecheck/typecheck.go b/src/cmd/compile/internal/typecheck/typecheck.go
new file mode 100644
index 0000000..359f662
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/typecheck.go
@@ -0,0 +1,2251 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typecheck
+
+import (
+	"fmt"
+	"go/constant"
+	"go/token"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+)
+
+// Function collecting autotmps generated during typechecking,
+// to be included in the package-level init function.
+var InitTodoFunc = ir.NewFunc(base.Pos)
+
+var inimport bool // set during import
+
+var TypecheckAllowed bool
+
+var (
+	NeedITab        = func(t, itype *types.Type) {}
+	NeedRuntimeType = func(*types.Type) {}
+)
+
+func AssignExpr(n ir.Node) ir.Node { return typecheck(n, ctxExpr|ctxAssign) }
+func Expr(n ir.Node) ir.Node       { return typecheck(n, ctxExpr) }
+func Stmt(n ir.Node) ir.Node       { return typecheck(n, ctxStmt) }
+
+func Exprs(exprs []ir.Node) { typecheckslice(exprs, ctxExpr) }
+func Stmts(stmts []ir.Node) { typecheckslice(stmts, ctxStmt) }
+
+func Call(call *ir.CallExpr) {
+	t := call.X.Type()
+	if t == nil {
+		panic("misuse of Call")
+	}
+	ctx := ctxStmt
+	if t.NumResults() > 0 {
+		ctx = ctxExpr | ctxMultiOK
+	}
+	if typecheck(call, ctx) != call {
+		panic("bad typecheck")
+	}
+}
+
+func Callee(n ir.Node) ir.Node {
+	return typecheck(n, ctxExpr|ctxCallee)
+}
+
+func FuncBody(n *ir.Func) {
+	ir.CurFunc = n
+	errorsBefore := base.Errors()
+	Stmts(n.Body)
+	CheckUnused(n)
+	CheckReturn(n)
+	if base.Errors() > errorsBefore {
+		n.Body = nil // type errors; do not compile
+	}
+}
+
+var importlist []*ir.Func
+
+// AllImportedBodies reads in the bodies of all imported functions and typechecks
+// them, if needed.
+func AllImportedBodies() {
+	for _, n := range importlist {
+		if n.Inl != nil {
+			ImportedBody(n)
+		}
+	}
+}
+
+var traceIndent []byte
+
+func tracePrint(title string, n ir.Node) func(np *ir.Node) {
+	indent := traceIndent
+
+	// guard against nil
+	var pos, op string
+	var tc uint8
+	if n != nil {
+		pos = base.FmtPos(n.Pos())
+		op = n.Op().String()
+		tc = n.Typecheck()
+	}
+
+	types.SkipSizeForTracing = true
+	defer func() { types.SkipSizeForTracing = false }()
+	fmt.Printf("%s: %s%s %p %s %v tc=%d\n", pos, indent, title, n, op, n, tc)
+	traceIndent = append(traceIndent, ". "...)
+
+	return func(np *ir.Node) {
+		traceIndent = traceIndent[:len(traceIndent)-2]
+
+		// if we have a result, use that
+		if np != nil {
+			n = *np
+		}
+
+		// guard against nil
+		// use outer pos, op so we don't get empty pos/op if n == nil (nicer output)
+		var tc uint8
+		var typ *types.Type
+		if n != nil {
+			pos = base.FmtPos(n.Pos())
+			op = n.Op().String()
+			tc = n.Typecheck()
+			typ = n.Type()
+		}
+
+		types.SkipSizeForTracing = true
+		defer func() { types.SkipSizeForTracing = false }()
+		fmt.Printf("%s: %s=> %p %s %v tc=%d type=%L\n", pos, indent, n, op, n, tc, typ)
+	}
+}
+
+const (
+	ctxStmt    = 1 << iota // evaluated at statement level
+	ctxExpr                // evaluated in value context
+	ctxType                // evaluated in type context
+	ctxCallee              // call-only expressions are ok
+	ctxMultiOK             // multivalue function returns are ok
+	ctxAssign              // assigning to expression
+)
+
+// type checks the whole tree of an expression.
+// calculates expression types.
+// evaluates compile time constants.
+// marks variables that escape the local frame.
+// rewrites n.Op to be more specific in some cases.
+
+var typecheckdefstack []*ir.Name
+
+// Resolve ONONAME to definition, if any.
+func Resolve(n ir.Node) (res ir.Node) {
+	if n == nil || n.Op() != ir.ONONAME {
+		return n
+	}
+
+	// only trace if there's work to do
+	if base.EnableTrace && base.Flag.LowerT {
+		defer tracePrint("resolve", n)(&res)
+	}
+
+	if sym := n.Sym(); sym.Pkg != types.LocalPkg {
+		// We might have an ir.Ident from oldname or importDot.
+		if id, ok := n.(*ir.Ident); ok {
+			if pkgName := DotImportRefs[id]; pkgName != nil {
+				pkgName.Used = true
+			}
+		}
+
+		return expandDecl(n)
+	}
+
+	r := ir.AsNode(n.Sym().Def)
+	if r == nil {
+		return n
+	}
+
+	if r.Op() == ir.OIOTA {
+		if x := getIotaValue(); x >= 0 {
+			return ir.NewInt(x)
+		}
+		return n
+	}
+
+	return r
+}
+
+func typecheckslice(l []ir.Node, top int) {
+	for i := range l {
+		l[i] = typecheck(l[i], top)
+	}
+}
+
+var _typekind = []string{
+	types.TINT:        "int",
+	types.TUINT:       "uint",
+	types.TINT8:       "int8",
+	types.TUINT8:      "uint8",
+	types.TINT16:      "int16",
+	types.TUINT16:     "uint16",
+	types.TINT32:      "int32",
+	types.TUINT32:     "uint32",
+	types.TINT64:      "int64",
+	types.TUINT64:     "uint64",
+	types.TUINTPTR:    "uintptr",
+	types.TCOMPLEX64:  "complex64",
+	types.TCOMPLEX128: "complex128",
+	types.TFLOAT32:    "float32",
+	types.TFLOAT64:    "float64",
+	types.TBOOL:       "bool",
+	types.TSTRING:     "string",
+	types.TPTR:        "pointer",
+	types.TUNSAFEPTR:  "unsafe.Pointer",
+	types.TSTRUCT:     "struct",
+	types.TINTER:      "interface",
+	types.TCHAN:       "chan",
+	types.TMAP:        "map",
+	types.TARRAY:      "array",
+	types.TSLICE:      "slice",
+	types.TFUNC:       "func",
+	types.TNIL:        "nil",
+	types.TIDEAL:      "untyped number",
+}
+
+func typekind(t *types.Type) string {
+	if t.IsUntyped() {
+		return fmt.Sprintf("%v", t)
+	}
+	et := t.Kind()
+	if int(et) < len(_typekind) {
+		s := _typekind[et]
+		if s != "" {
+			return s
+		}
+	}
+	return fmt.Sprintf("etype=%d", et)
+}
+
+func cycleFor(start ir.Node) []ir.Node {
+	// Find the start node in typecheck_tcstack.
+	// We know that it must exist because each time we mark
+	// a node with n.SetTypecheck(2) we push it on the stack,
+	// and each time we mark a node with n.SetTypecheck(2) we
+	// pop it from the stack. We hit a cycle when we encounter
+	// a node marked 2 in which case is must be on the stack.
+	i := len(typecheck_tcstack) - 1
+	for i > 0 && typecheck_tcstack[i] != start {
+		i--
+	}
+
+	// collect all nodes with same Op
+	var cycle []ir.Node
+	for _, n := range typecheck_tcstack[i:] {
+		if n.Op() == start.Op() {
+			cycle = append(cycle, n)
+		}
+	}
+
+	return cycle
+}
+
+func cycleTrace(cycle []ir.Node) string {
+	var s string
+	for i, n := range cycle {
+		s += fmt.Sprintf("\n\t%v: %v uses %v", ir.Line(n), n, cycle[(i+1)%len(cycle)])
+	}
+	return s
+}
+
+var typecheck_tcstack []ir.Node
+
+func Func(fn *ir.Func) {
+	new := Stmt(fn)
+	if new != fn {
+		base.Fatalf("typecheck changed func")
+	}
+}
+
+func typecheckNtype(n ir.Ntype) ir.Ntype {
+	return typecheck(n, ctxType).(ir.Ntype)
+}
+
+// typecheck type checks node n.
+// The result of typecheck MUST be assigned back to n, e.g.
+// 	n.Left = typecheck(n.Left, top)
+func typecheck(n ir.Node, top int) (res ir.Node) {
+	// cannot type check until all the source has been parsed
+	if !TypecheckAllowed {
+		base.Fatalf("early typecheck")
+	}
+
+	if n == nil {
+		return nil
+	}
+
+	// only trace if there's work to do
+	if base.EnableTrace && base.Flag.LowerT {
+		defer tracePrint("typecheck", n)(&res)
+	}
+
+	lno := ir.SetPos(n)
+
+	// Skip over parens.
+	for n.Op() == ir.OPAREN {
+		n = n.(*ir.ParenExpr).X
+	}
+
+	// Resolve definition of name and value of iota lazily.
+	n = Resolve(n)
+
+	// Skip typecheck if already done.
+	// But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
+	if n.Typecheck() == 1 || n.Typecheck() == 3 {
+		switch n.Op() {
+		case ir.ONAME, ir.OTYPE, ir.OLITERAL, ir.OPACK:
+			break
+
+		default:
+			base.Pos = lno
+			return n
+		}
+	}
+
+	if n.Typecheck() == 2 {
+		// Typechecking loop. Trying printing a meaningful message,
+		// otherwise a stack trace of typechecking.
+		switch n.Op() {
+		// We can already diagnose variables used as types.
+		case ir.ONAME:
+			n := n.(*ir.Name)
+			if top&(ctxExpr|ctxType) == ctxType {
+				base.Errorf("%v is not a type", n)
+			}
+
+		case ir.OTYPE:
+			// Only report a type cycle if we are expecting a type.
+			// Otherwise let other code report an error.
+			if top&ctxType == ctxType {
+				// A cycle containing only alias types is an error
+				// since it would expand indefinitely when aliases
+				// are substituted.
+				cycle := cycleFor(n)
+				for _, n1 := range cycle {
+					if n1.Name() != nil && !n1.Name().Alias() {
+						// Cycle is ok. But if n is an alias type and doesn't
+						// have a type yet, we have a recursive type declaration
+						// with aliases that we can't handle properly yet.
+						// Report an error rather than crashing later.
+						if n.Name() != nil && n.Name().Alias() && n.Type() == nil {
+							base.Pos = n.Pos()
+							base.Fatalf("cannot handle alias type declaration (issue #25838): %v", n)
+						}
+						base.Pos = lno
+						return n
+					}
+				}
+				base.ErrorfAt(n.Pos(), "invalid recursive type alias %v%s", n, cycleTrace(cycle))
+			}
+
+		case ir.OLITERAL:
+			if top&(ctxExpr|ctxType) == ctxType {
+				base.Errorf("%v is not a type", n)
+				break
+			}
+			base.ErrorfAt(n.Pos(), "constant definition loop%s", cycleTrace(cycleFor(n)))
+		}
+
+		if base.Errors() == 0 {
+			var trace string
+			for i := len(typecheck_tcstack) - 1; i >= 0; i-- {
+				x := typecheck_tcstack[i]
+				trace += fmt.Sprintf("\n\t%v %v", ir.Line(x), x)
+			}
+			base.Errorf("typechecking loop involving %v%s", n, trace)
+		}
+
+		base.Pos = lno
+		return n
+	}
+
+	typecheck_tcstack = append(typecheck_tcstack, n)
+
+	n.SetTypecheck(2)
+	n = typecheck1(n, top)
+	n.SetTypecheck(1)
+
+	last := len(typecheck_tcstack) - 1
+	typecheck_tcstack[last] = nil
+	typecheck_tcstack = typecheck_tcstack[:last]
+
+	_, isExpr := n.(ir.Expr)
+	_, isStmt := n.(ir.Stmt)
+	isMulti := false
+	switch n.Op() {
+	case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
+		n := n.(*ir.CallExpr)
+		if t := n.X.Type(); t != nil && t.Kind() == types.TFUNC {
+			nr := t.NumResults()
+			isMulti = nr > 1
+			if nr == 0 {
+				isExpr = false
+			}
+		}
+	case ir.OAPPEND:
+		// Must be used (and not BinaryExpr/UnaryExpr).
+		isStmt = false
+	case ir.OCLOSE, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN, ir.OVARKILL, ir.OVARLIVE:
+		// Must not be used.
+		isExpr = false
+		isStmt = true
+	case ir.OCOPY, ir.ORECOVER, ir.ORECV:
+		// Can be used or not.
+		isStmt = true
+	}
+
+	t := n.Type()
+	if t != nil && !t.IsFuncArgStruct() && n.Op() != ir.OTYPE {
+		switch t.Kind() {
+		case types.TFUNC, // might have TANY; wait until it's called
+			types.TANY, types.TFORW, types.TIDEAL, types.TNIL, types.TBLANK:
+			break
+
+		default:
+			types.CheckSize(t)
+		}
+	}
+	if t != nil {
+		n = EvalConst(n)
+		t = n.Type()
+	}
+
+	// TODO(rsc): Lots of the complexity here is because typecheck can
+	// see OTYPE, ONAME, and OLITERAL nodes multiple times.
+	// Once we make the IR a proper tree, we should be able to simplify
+	// this code a bit, especially the final case.
+	switch {
+	case top&(ctxStmt|ctxExpr) == ctxExpr && !isExpr && n.Op() != ir.OTYPE && !isMulti:
+		if !n.Diag() {
+			base.Errorf("%v used as value", n)
+			n.SetDiag(true)
+		}
+		if t != nil {
+			n.SetType(nil)
+		}
+
+	case top&ctxType == 0 && n.Op() == ir.OTYPE && t != nil:
+		if !n.Type().Broke() {
+			base.Errorf("type %v is not an expression", n.Type())
+			n.SetDiag(true)
+		}
+
+	case top&(ctxStmt|ctxExpr) == ctxStmt && !isStmt && t != nil:
+		if !n.Diag() {
+			base.Errorf("%v evaluated but not used", n)
+			n.SetDiag(true)
+		}
+		n.SetType(nil)
+
+	case top&(ctxType|ctxExpr) == ctxType && n.Op() != ir.OTYPE && n.Op() != ir.ONONAME && (t != nil || n.Op() == ir.ONAME):
+		base.Errorf("%v is not a type", n)
+		if t != nil {
+			if n.Op() == ir.ONAME {
+				t.SetBroke(true)
+			} else {
+				n.SetType(nil)
+			}
+		}
+
+	}
+
+	base.Pos = lno
+	return n
+}
+
+// indexlit implements typechecking of untyped values as
+// 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 ir.Node) ir.Node {
+	if n != nil && n.Type() != nil && n.Type().Kind() == types.TIDEAL {
+		return DefaultLit(n, types.Types[types.TINT])
+	}
+	return n
+}
+
+// typecheck1 should ONLY be called from typecheck.
+func typecheck1(n ir.Node, top int) ir.Node {
+	if n, ok := n.(*ir.Name); ok {
+		typecheckdef(n)
+	}
+
+	switch n.Op() {
+	default:
+		ir.Dump("typecheck", n)
+		base.Fatalf("typecheck %v", n.Op())
+		panic("unreachable")
+
+	case ir.OLITERAL:
+		if n.Sym() == nil && n.Type() == nil {
+			if !n.Diag() {
+				base.Fatalf("literal missing type: %v", n)
+			}
+		}
+		return n
+
+	case ir.ONIL:
+		return n
+
+	// names
+	case ir.ONONAME:
+		if !n.Diag() {
+			// Note: adderrorname looks for this string and
+			// adds context about the outer expression
+			base.ErrorfAt(n.Pos(), "undefined: %v", n.Sym())
+			n.SetDiag(true)
+		}
+		n.SetType(nil)
+		return n
+
+	case ir.ONAME:
+		n := n.(*ir.Name)
+		if n.BuiltinOp != 0 {
+			if top&ctxCallee == 0 {
+				base.Errorf("use of builtin %v not in function call", n.Sym())
+				n.SetType(nil)
+				return n
+			}
+			return n
+		}
+		if top&ctxAssign == 0 {
+			// not a write to the variable
+			if ir.IsBlank(n) {
+				base.Errorf("cannot use _ as value")
+				n.SetType(nil)
+				return n
+			}
+			n.SetUsed(true)
+		}
+		return n
+
+	case ir.OLINKSYMOFFSET:
+		// type already set
+		return n
+
+	case ir.OPACK:
+		n := n.(*ir.PkgName)
+		base.Errorf("use of package %v without selector", n.Sym())
+		n.SetDiag(true)
+		return n
+
+	// types (ODEREF is with exprs)
+	case ir.OTYPE:
+		return n
+
+	case ir.OTSLICE:
+		n := n.(*ir.SliceType)
+		return tcSliceType(n)
+
+	case ir.OTARRAY:
+		n := n.(*ir.ArrayType)
+		return tcArrayType(n)
+
+	case ir.OTMAP:
+		n := n.(*ir.MapType)
+		return tcMapType(n)
+
+	case ir.OTCHAN:
+		n := n.(*ir.ChanType)
+		return tcChanType(n)
+
+	case ir.OTSTRUCT:
+		n := n.(*ir.StructType)
+		return tcStructType(n)
+
+	case ir.OTINTER:
+		n := n.(*ir.InterfaceType)
+		return tcInterfaceType(n)
+
+	case ir.OTFUNC:
+		n := n.(*ir.FuncType)
+		return tcFuncType(n)
+	// type or expr
+	case ir.ODEREF:
+		n := n.(*ir.StarExpr)
+		return tcStar(n, top)
+
+	// x op= y
+	case ir.OASOP:
+		n := n.(*ir.AssignOpStmt)
+		n.X, n.Y = Expr(n.X), Expr(n.Y)
+		checkassign(n, n.X)
+		if n.IncDec && !okforarith[n.X.Type().Kind()] {
+			base.Errorf("invalid operation: %v (non-numeric type %v)", n, n.X.Type())
+			return n
+		}
+		switch n.AsOp {
+		case ir.OLSH, ir.ORSH:
+			n.X, n.Y, _ = tcShift(n, n.X, n.Y)
+		case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD, ir.OMUL, ir.OOR, ir.OSUB, ir.OXOR:
+			n.X, n.Y, _ = tcArith(n, n.AsOp, n.X, n.Y)
+		default:
+			base.Fatalf("invalid assign op: %v", n.AsOp)
+		}
+		return n
+
+	// logical operators
+	case ir.OANDAND, ir.OOROR:
+		n := n.(*ir.LogicalExpr)
+		n.X, n.Y = Expr(n.X), Expr(n.Y)
+		if n.X.Type() == nil || n.Y.Type() == nil {
+			n.SetType(nil)
+			return n
+		}
+		// For "x == x && len(s)", it's better to report that "len(s)" (type int)
+		// can't be used with "&&" than to report that "x == x" (type untyped bool)
+		// can't be converted to int (see issue #41500).
+		if !n.X.Type().IsBoolean() {
+			base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.X.Type()))
+			n.SetType(nil)
+			return n
+		}
+		if !n.Y.Type().IsBoolean() {
+			base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.Y.Type()))
+			n.SetType(nil)
+			return n
+		}
+		l, r, t := tcArith(n, n.Op(), n.X, n.Y)
+		n.X, n.Y = l, r
+		n.SetType(t)
+		return n
+
+	// shift operators
+	case ir.OLSH, ir.ORSH:
+		n := n.(*ir.BinaryExpr)
+		n.X, n.Y = Expr(n.X), Expr(n.Y)
+		l, r, t := tcShift(n, n.X, n.Y)
+		n.X, n.Y = l, r
+		n.SetType(t)
+		return n
+
+	// comparison operators
+	case ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT, ir.ONE:
+		n := n.(*ir.BinaryExpr)
+		n.X, n.Y = Expr(n.X), Expr(n.Y)
+		l, r, t := tcArith(n, n.Op(), n.X, n.Y)
+		if t != nil {
+			n.X, n.Y = l, r
+			n.SetType(types.UntypedBool)
+			if con := EvalConst(n); con.Op() == ir.OLITERAL {
+				return con
+			}
+			n.X, n.Y = defaultlit2(l, r, true)
+		}
+		return n
+
+	// binary operators
+	case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD, ir.OMUL, ir.OOR, ir.OSUB, ir.OXOR:
+		n := n.(*ir.BinaryExpr)
+		n.X, n.Y = Expr(n.X), Expr(n.Y)
+		l, r, t := tcArith(n, n.Op(), n.X, n.Y)
+		if t != nil && t.Kind() == types.TSTRING && n.Op() == ir.OADD {
+			// create or update OADDSTR node with list of strings in x + y + z + (w + v) + ...
+			var add *ir.AddStringExpr
+			if l.Op() == ir.OADDSTR {
+				add = l.(*ir.AddStringExpr)
+				add.SetPos(n.Pos())
+			} else {
+				add = ir.NewAddStringExpr(n.Pos(), []ir.Node{l})
+			}
+			if r.Op() == ir.OADDSTR {
+				r := r.(*ir.AddStringExpr)
+				add.List.Append(r.List.Take()...)
+			} else {
+				add.List.Append(r)
+			}
+			add.SetType(t)
+			return add
+		}
+		n.X, n.Y = l, r
+		n.SetType(t)
+		return n
+
+	case ir.OBITNOT, ir.ONEG, ir.ONOT, ir.OPLUS:
+		n := n.(*ir.UnaryExpr)
+		return tcUnaryArith(n)
+
+	// exprs
+	case ir.OADDR:
+		n := n.(*ir.AddrExpr)
+		return tcAddr(n)
+
+	case ir.OCOMPLIT:
+		return tcCompLit(n.(*ir.CompLitExpr))
+
+	case ir.OXDOT, ir.ODOT:
+		n := n.(*ir.SelectorExpr)
+		return tcDot(n, top)
+
+	case ir.ODOTTYPE:
+		n := n.(*ir.TypeAssertExpr)
+		return tcDotType(n)
+
+	case ir.OINDEX:
+		n := n.(*ir.IndexExpr)
+		return tcIndex(n)
+
+	case ir.ORECV:
+		n := n.(*ir.UnaryExpr)
+		return tcRecv(n)
+
+	case ir.OSEND:
+		n := n.(*ir.SendStmt)
+		return tcSend(n)
+
+	case ir.OSLICEHEADER:
+		n := n.(*ir.SliceHeaderExpr)
+		return tcSliceHeader(n)
+
+	case ir.OMAKESLICECOPY:
+		n := n.(*ir.MakeExpr)
+		return tcMakeSliceCopy(n)
+
+	case ir.OSLICE, ir.OSLICE3:
+		n := n.(*ir.SliceExpr)
+		return tcSlice(n)
+
+	// call and call like
+	case ir.OCALL:
+		n := n.(*ir.CallExpr)
+		return tcCall(n, top)
+
+	case ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
+		n := n.(*ir.UnaryExpr)
+		n.SetType(types.Types[types.TUINTPTR])
+		return n
+
+	case ir.OCAP, ir.OLEN:
+		n := n.(*ir.UnaryExpr)
+		return tcLenCap(n)
+
+	case ir.OREAL, ir.OIMAG:
+		n := n.(*ir.UnaryExpr)
+		return tcRealImag(n)
+
+	case ir.OCOMPLEX:
+		n := n.(*ir.BinaryExpr)
+		return tcComplex(n)
+
+	case ir.OCLOSE:
+		n := n.(*ir.UnaryExpr)
+		return tcClose(n)
+
+	case ir.ODELETE:
+		n := n.(*ir.CallExpr)
+		return tcDelete(n)
+
+	case ir.OAPPEND:
+		n := n.(*ir.CallExpr)
+		return tcAppend(n)
+
+	case ir.OCOPY:
+		n := n.(*ir.BinaryExpr)
+		return tcCopy(n)
+
+	case ir.OCONV:
+		n := n.(*ir.ConvExpr)
+		return tcConv(n)
+
+	case ir.OMAKE:
+		n := n.(*ir.CallExpr)
+		return tcMake(n)
+
+	case ir.ONEW:
+		n := n.(*ir.UnaryExpr)
+		return tcNew(n)
+
+	case ir.OPRINT, ir.OPRINTN:
+		n := n.(*ir.CallExpr)
+		return tcPrint(n)
+
+	case ir.OPANIC:
+		n := n.(*ir.UnaryExpr)
+		return tcPanic(n)
+
+	case ir.ORECOVER:
+		n := n.(*ir.CallExpr)
+		return tcRecover(n)
+
+	case ir.OUNSAFEADD:
+		n := n.(*ir.BinaryExpr)
+		return tcUnsafeAdd(n)
+
+	case ir.OUNSAFESLICE:
+		n := n.(*ir.BinaryExpr)
+		return tcUnsafeSlice(n)
+
+	case ir.OCLOSURE:
+		n := n.(*ir.ClosureExpr)
+		tcClosure(n, top)
+		if n.Type() == nil {
+			return n
+		}
+		return n
+
+	case ir.OITAB:
+		n := n.(*ir.UnaryExpr)
+		return tcITab(n)
+
+	case ir.OIDATA:
+		// Whoever creates the OIDATA node must know a priori the concrete type at that moment,
+		// usually by just having checked the OITAB.
+		n := n.(*ir.UnaryExpr)
+		base.Fatalf("cannot typecheck interface data %v", n)
+		panic("unreachable")
+
+	case ir.OSPTR:
+		n := n.(*ir.UnaryExpr)
+		return tcSPtr(n)
+
+	case ir.OCFUNC:
+		n := n.(*ir.UnaryExpr)
+		n.X = Expr(n.X)
+		n.SetType(types.Types[types.TUINTPTR])
+		return n
+
+	case ir.OCONVNOP:
+		n := n.(*ir.ConvExpr)
+		n.X = Expr(n.X)
+		return n
+
+	// statements
+	case ir.OAS:
+		n := n.(*ir.AssignStmt)
+		tcAssign(n)
+
+		// Code that creates temps does not bother to set defn, so do it here.
+		if n.X.Op() == ir.ONAME && ir.IsAutoTmp(n.X) {
+			n.X.Name().Defn = n
+		}
+		return n
+
+	case ir.OAS2:
+		tcAssignList(n.(*ir.AssignListStmt))
+		return n
+
+	case ir.OBREAK,
+		ir.OCONTINUE,
+		ir.ODCL,
+		ir.OGOTO,
+		ir.OFALL,
+		ir.OVARKILL,
+		ir.OVARLIVE:
+		return n
+
+	case ir.OBLOCK:
+		n := n.(*ir.BlockStmt)
+		Stmts(n.List)
+		return n
+
+	case ir.OLABEL:
+		if n.Sym().IsBlank() {
+			// Empty identifier is valid but useless.
+			// Eliminate now to simplify life later.
+			// See issues 7538, 11589, 11593.
+			n = ir.NewBlockStmt(n.Pos(), nil)
+		}
+		return n
+
+	case ir.ODEFER, ir.OGO:
+		n := n.(*ir.GoDeferStmt)
+		n.Call = typecheck(n.Call, ctxStmt|ctxExpr)
+		if !n.Call.Diag() {
+			tcGoDefer(n)
+		}
+		return n
+
+	case ir.OFOR, ir.OFORUNTIL:
+		n := n.(*ir.ForStmt)
+		return tcFor(n)
+
+	case ir.OIF:
+		n := n.(*ir.IfStmt)
+		return tcIf(n)
+
+	case ir.ORETURN:
+		n := n.(*ir.ReturnStmt)
+		return tcReturn(n)
+
+	case ir.OTAILCALL:
+		n := n.(*ir.TailCallStmt)
+		return n
+
+	case ir.OSELECT:
+		tcSelect(n.(*ir.SelectStmt))
+		return n
+
+	case ir.OSWITCH:
+		tcSwitch(n.(*ir.SwitchStmt))
+		return n
+
+	case ir.ORANGE:
+		tcRange(n.(*ir.RangeStmt))
+		return n
+
+	case ir.OTYPESW:
+		n := n.(*ir.TypeSwitchGuard)
+		base.Errorf("use of .(type) outside type switch")
+		n.SetDiag(true)
+		return n
+
+	case ir.ODCLFUNC:
+		tcFunc(n.(*ir.Func))
+		return n
+
+	case ir.ODCLCONST:
+		n := n.(*ir.Decl)
+		n.X = Expr(n.X).(*ir.Name)
+		return n
+
+	case ir.ODCLTYPE:
+		n := n.(*ir.Decl)
+		n.X = typecheck(n.X, ctxType).(*ir.Name)
+		types.CheckSize(n.X.Type())
+		return n
+	}
+
+	// No return n here!
+	// Individual cases can type-assert n, introducing a new one.
+	// Each must execute its own return n.
+}
+
+func typecheckargs(n ir.InitNode) {
+	var list []ir.Node
+	switch n := n.(type) {
+	default:
+		base.Fatalf("typecheckargs %+v", n.Op())
+	case *ir.CallExpr:
+		list = n.Args
+		if n.IsDDD {
+			Exprs(list)
+			return
+		}
+	case *ir.ReturnStmt:
+		list = n.Results
+	}
+	if len(list) != 1 {
+		Exprs(list)
+		return
+	}
+
+	typecheckslice(list, ctxExpr|ctxMultiOK)
+	t := list[0].Type()
+	if t == nil || !t.IsFuncArgStruct() {
+		return
+	}
+
+	// Save n as n.Orig for fmt.go.
+	if ir.Orig(n) == n {
+		n.(ir.OrigNode).SetOrig(ir.SepCopy(n))
+	}
+
+	// Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...).
+	rewriteMultiValueCall(n, list[0])
+}
+
+// rewriteMultiValueCall rewrites multi-valued f() to use temporaries,
+// so the backend wouldn't need to worry about tuple-valued expressions.
+func rewriteMultiValueCall(n ir.InitNode, call ir.Node) {
+	// If we're outside of function context, then this call will
+	// be executed during the generated init function. However,
+	// init.go hasn't yet created it. Instead, associate the
+	// temporary variables with  InitTodoFunc for now, and init.go
+	// will reassociate them later when it's appropriate.
+	static := ir.CurFunc == nil
+	if static {
+		ir.CurFunc = InitTodoFunc
+	}
+
+	as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, []ir.Node{call})
+	results := call.Type().FieldSlice()
+	list := make([]ir.Node, len(results))
+	for i, result := range results {
+		tmp := Temp(result.Type)
+		as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, tmp))
+		as.Lhs.Append(tmp)
+		list[i] = tmp
+	}
+	if static {
+		ir.CurFunc = nil
+	}
+
+	n.PtrInit().Append(Stmt(as))
+
+	switch n := n.(type) {
+	default:
+		base.Fatalf("rewriteMultiValueCall %+v", n.Op())
+	case *ir.CallExpr:
+		n.Args = list
+	case *ir.ReturnStmt:
+		n.Results = list
+	case *ir.AssignListStmt:
+		if n.Op() != ir.OAS2FUNC {
+			base.Fatalf("rewriteMultiValueCall: invalid op %v", n.Op())
+		}
+		as.SetOp(ir.OAS2FUNC)
+		n.SetOp(ir.OAS2)
+		n.Rhs = make([]ir.Node, len(list))
+		for i, tmp := range list {
+			n.Rhs[i] = AssignConv(tmp, n.Lhs[i].Type(), "assignment")
+		}
+	}
+}
+
+func checksliceindex(l ir.Node, r ir.Node, tp *types.Type) bool {
+	t := r.Type()
+	if t == nil {
+		return false
+	}
+	if !t.IsInteger() {
+		base.Errorf("invalid slice index %v (type %v)", r, t)
+		return false
+	}
+
+	if r.Op() == ir.OLITERAL {
+		x := r.Val()
+		if constant.Sign(x) < 0 {
+			base.Errorf("invalid slice index %v (index must be non-negative)", r)
+			return false
+		} else if tp != nil && tp.NumElem() >= 0 && constant.Compare(x, token.GTR, constant.MakeInt64(tp.NumElem())) {
+			base.Errorf("invalid slice index %v (out of bounds for %d-element array)", r, tp.NumElem())
+			return false
+		} else if ir.IsConst(l, constant.String) && constant.Compare(x, token.GTR, constant.MakeInt64(int64(len(ir.StringVal(l))))) {
+			base.Errorf("invalid slice index %v (out of bounds for %d-byte string)", r, len(ir.StringVal(l)))
+			return false
+		} else if ir.ConstOverflow(x, types.Types[types.TINT]) {
+			base.Errorf("invalid slice index %v (index too large)", r)
+			return false
+		}
+	}
+
+	return true
+}
+
+func checksliceconst(lo ir.Node, hi ir.Node) bool {
+	if lo != nil && hi != nil && lo.Op() == ir.OLITERAL && hi.Op() == ir.OLITERAL && constant.Compare(lo.Val(), token.GTR, hi.Val()) {
+		base.Errorf("invalid slice index: %v > %v", lo, hi)
+		return false
+	}
+
+	return true
+}
+
+// The result of implicitstar MUST be assigned back to n, e.g.
+// 	n.Left = implicitstar(n.Left)
+func implicitstar(n ir.Node) ir.Node {
+	// insert implicit * if needed for fixed array
+	t := n.Type()
+	if t == nil || !t.IsPtr() {
+		return n
+	}
+	t = t.Elem()
+	if t == nil {
+		return n
+	}
+	if !t.IsArray() {
+		return n
+	}
+	star := ir.NewStarExpr(base.Pos, n)
+	star.SetImplicit(true)
+	return Expr(star)
+}
+
+func needOneArg(n *ir.CallExpr, f string, args ...interface{}) (ir.Node, bool) {
+	if len(n.Args) == 0 {
+		p := fmt.Sprintf(f, args...)
+		base.Errorf("missing argument to %s: %v", p, n)
+		return nil, false
+	}
+
+	if len(n.Args) > 1 {
+		p := fmt.Sprintf(f, args...)
+		base.Errorf("too many arguments to %s: %v", p, n)
+		return n.Args[0], false
+	}
+
+	return n.Args[0], true
+}
+
+func needTwoArgs(n *ir.CallExpr) (ir.Node, ir.Node, bool) {
+	if len(n.Args) != 2 {
+		if len(n.Args) < 2 {
+			base.Errorf("not enough arguments in call to %v", n)
+		} else {
+			base.Errorf("too many arguments in call to %v", n)
+		}
+		return nil, nil, false
+	}
+	return n.Args[0], n.Args[1], true
+}
+
+// Lookdot1 looks up the specified method s in the list fs of methods, returning
+// the matching field or nil. If dostrcmp is 0, it matches the symbols. If
+// dostrcmp is 1, it matches by name exactly. If dostrcmp is 2, it matches names
+// with case folding.
+func Lookdot1(errnode ir.Node, s *types.Sym, t *types.Type, fs *types.Fields, dostrcmp int) *types.Field {
+	var r *types.Field
+	for _, f := range fs.Slice() {
+		if dostrcmp != 0 && f.Sym.Name == s.Name {
+			return f
+		}
+		if dostrcmp == 2 && strings.EqualFold(f.Sym.Name, s.Name) {
+			return f
+		}
+		if f.Sym != s {
+			continue
+		}
+		if r != nil {
+			if errnode != nil {
+				base.Errorf("ambiguous selector %v", errnode)
+			} else if t.IsPtr() {
+				base.Errorf("ambiguous selector (%v).%v", t, s)
+			} else {
+				base.Errorf("ambiguous selector %v.%v", t, s)
+			}
+			break
+		}
+
+		r = f
+	}
+
+	return r
+}
+
+// typecheckMethodExpr checks selector expressions (ODOT) where the
+// base expression is a type expression (OTYPE).
+func typecheckMethodExpr(n *ir.SelectorExpr) (res ir.Node) {
+	if base.EnableTrace && base.Flag.LowerT {
+		defer tracePrint("typecheckMethodExpr", n)(&res)
+	}
+
+	t := n.X.Type()
+
+	// Compute the method set for t.
+	var ms *types.Fields
+	if t.IsInterface() {
+		ms = t.AllMethods()
+	} else {
+		mt := types.ReceiverBaseType(t)
+		if mt == nil {
+			base.Errorf("%v undefined (type %v has no method %v)", n, t, n.Sel)
+			n.SetType(nil)
+			return n
+		}
+		CalcMethods(mt)
+		ms = mt.AllMethods()
+
+		// The method expression T.m requires a wrapper when T
+		// is different from m's declared receiver type. We
+		// normally generate these wrappers while writing out
+		// runtime type descriptors, which is always done for
+		// types declared at package scope. However, we need
+		// to make sure to generate wrappers for anonymous
+		// receiver types too.
+		if mt.Sym() == nil {
+			NeedRuntimeType(t)
+		}
+	}
+
+	s := n.Sel
+	m := Lookdot1(n, s, t, ms, 0)
+	if m == nil {
+		if Lookdot1(n, s, t, ms, 1) != nil {
+			base.Errorf("%v undefined (cannot refer to unexported method %v)", n, s)
+		} else if _, ambig := dotpath(s, t, nil, false); ambig {
+			base.Errorf("%v undefined (ambiguous selector)", n) // method or field
+		} else {
+			base.Errorf("%v undefined (type %v has no method %v)", n, t, s)
+		}
+		n.SetType(nil)
+		return n
+	}
+
+	if !types.IsMethodApplicable(t, m) {
+		base.Errorf("invalid method expression %v (needs pointer receiver: (*%v).%S)", n, t, s)
+		n.SetType(nil)
+		return n
+	}
+
+	n.SetOp(ir.OMETHEXPR)
+	n.Selection = m
+	n.SetType(NewMethodType(m.Type, n.X.Type()))
+	return n
+}
+
+func derefall(t *types.Type) *types.Type {
+	for t != nil && t.IsPtr() {
+		t = t.Elem()
+	}
+	return t
+}
+
+// Lookdot looks up field or method n.Sel in the type t and returns the matching
+// field. It transforms the op of node n to ODOTINTER or ODOTMETH, if appropriate.
+// It also may add a StarExpr node to n.X as needed for access to non-pointer
+// methods. If dostrcmp is 0, it matches the field/method with the exact symbol
+// as n.Sel (appropriate for exported fields). If dostrcmp is 1, it matches by name
+// exactly. If dostrcmp is 2, it matches names with case folding.
+func Lookdot(n *ir.SelectorExpr, t *types.Type, dostrcmp int) *types.Field {
+	s := n.Sel
+
+	types.CalcSize(t)
+	var f1 *types.Field
+	if t.IsStruct() {
+		f1 = Lookdot1(n, s, t, t.Fields(), dostrcmp)
+	} else if t.IsInterface() {
+		f1 = Lookdot1(n, s, t, t.AllMethods(), dostrcmp)
+	}
+
+	var f2 *types.Field
+	if n.X.Type() == t || n.X.Type().Sym() == nil {
+		mt := types.ReceiverBaseType(t)
+		if mt != nil {
+			f2 = Lookdot1(n, s, mt, mt.Methods(), dostrcmp)
+		}
+	}
+
+	if f1 != nil {
+		if dostrcmp > 1 || f1.Broke() {
+			// Already in the process of diagnosing an error.
+			return f1
+		}
+		if f2 != nil {
+			base.Errorf("%v is both field and method", n.Sel)
+		}
+		if f1.Offset == types.BADWIDTH {
+			base.Fatalf("Lookdot badwidth t=%v, f1=%v@%p", t, f1, f1)
+		}
+		n.Selection = f1
+		n.SetType(f1.Type)
+		if t.IsInterface() {
+			if n.X.Type().IsPtr() {
+				star := ir.NewStarExpr(base.Pos, n.X)
+				star.SetImplicit(true)
+				n.X = Expr(star)
+			}
+
+			n.SetOp(ir.ODOTINTER)
+		}
+		return f1
+	}
+
+	if f2 != nil {
+		if dostrcmp > 1 {
+			// Already in the process of diagnosing an error.
+			return f2
+		}
+		orig := n.X
+		tt := n.X.Type()
+		types.CalcSize(tt)
+		rcvr := f2.Type.Recv().Type
+		if !types.Identical(rcvr, tt) {
+			if rcvr.IsPtr() && types.Identical(rcvr.Elem(), tt) {
+				checklvalue(n.X, "call pointer method on")
+				addr := NodAddr(n.X)
+				addr.SetImplicit(true)
+				n.X = typecheck(addr, ctxType|ctxExpr)
+			} else if tt.IsPtr() && (!rcvr.IsPtr() || rcvr.IsPtr() && rcvr.Elem().NotInHeap()) && types.Identical(tt.Elem(), rcvr) {
+				star := ir.NewStarExpr(base.Pos, n.X)
+				star.SetImplicit(true)
+				n.X = typecheck(star, ctxType|ctxExpr)
+			} else if tt.IsPtr() && tt.Elem().IsPtr() && types.Identical(derefall(tt), derefall(rcvr)) {
+				base.Errorf("calling method %v with receiver %L requires explicit dereference", n.Sel, n.X)
+				for tt.IsPtr() {
+					// Stop one level early for method with pointer receiver.
+					if rcvr.IsPtr() && !tt.Elem().IsPtr() {
+						break
+					}
+					star := ir.NewStarExpr(base.Pos, n.X)
+					star.SetImplicit(true)
+					n.X = typecheck(star, ctxType|ctxExpr)
+					tt = tt.Elem()
+				}
+			} else {
+				base.Fatalf("method mismatch: %v for %v", rcvr, tt)
+			}
+		}
+
+		// Check that we haven't implicitly dereferenced any defined pointer types.
+		for x := n.X; ; {
+			var inner ir.Node
+			implicit := false
+			switch x := x.(type) {
+			case *ir.AddrExpr:
+				inner, implicit = x.X, x.Implicit()
+			case *ir.SelectorExpr:
+				inner, implicit = x.X, x.Implicit()
+			case *ir.StarExpr:
+				inner, implicit = x.X, x.Implicit()
+			}
+			if !implicit {
+				break
+			}
+			if inner.Type().Sym() != nil && (x.Op() == ir.ODEREF || x.Op() == ir.ODOTPTR) {
+				// Found an implicit dereference of a defined pointer type.
+				// Restore n.X for better error message.
+				n.X = orig
+				return nil
+			}
+			x = inner
+		}
+
+		n.Selection = f2
+		n.SetType(f2.Type)
+		n.SetOp(ir.ODOTMETH)
+
+		return f2
+	}
+
+	return nil
+}
+
+func nokeys(l ir.Nodes) bool {
+	for _, n := range l {
+		if n.Op() == ir.OKEY || n.Op() == ir.OSTRUCTKEY {
+			return false
+		}
+	}
+	return true
+}
+
+func hasddd(t *types.Type) bool {
+	for _, tl := range t.Fields().Slice() {
+		if tl.IsDDD() {
+			return true
+		}
+	}
+
+	return false
+}
+
+// typecheck assignment: type list = expression list
+func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl ir.Nodes, desc func() string) {
+	var t *types.Type
+	var i int
+
+	lno := base.Pos
+	defer func() { base.Pos = lno }()
+
+	if tstruct.Broke() {
+		return
+	}
+
+	var n ir.Node
+	if len(nl) == 1 {
+		n = nl[0]
+	}
+
+	n1 := tstruct.NumFields()
+	n2 := len(nl)
+	if !hasddd(tstruct) {
+		if isddd {
+			goto invalidddd
+		}
+		if n2 > n1 {
+			goto toomany
+		}
+		if n2 < n1 {
+			goto notenough
+		}
+	} else {
+		if !isddd {
+			if n2 < n1-1 {
+				goto notenough
+			}
+		} else {
+			if n2 > n1 {
+				goto toomany
+			}
+			if n2 < n1 {
+				goto notenough
+			}
+		}
+	}
+
+	i = 0
+	for _, tl := range tstruct.Fields().Slice() {
+		t = tl.Type
+		if tl.IsDDD() {
+			if isddd {
+				if i >= len(nl) {
+					goto notenough
+				}
+				if len(nl)-i > 1 {
+					goto toomany
+				}
+				n = nl[i]
+				ir.SetPos(n)
+				if n.Type() != nil {
+					nl[i] = assignconvfn(n, t, desc)
+				}
+				return
+			}
+
+			// TODO(mdempsky): Make into ... call with implicit slice.
+			for ; i < len(nl); i++ {
+				n = nl[i]
+				ir.SetPos(n)
+				if n.Type() != nil {
+					nl[i] = assignconvfn(n, t.Elem(), desc)
+				}
+			}
+			return
+		}
+
+		if i >= len(nl) {
+			goto notenough
+		}
+		n = nl[i]
+		ir.SetPos(n)
+		if n.Type() != nil {
+			nl[i] = assignconvfn(n, t, desc)
+		}
+		i++
+	}
+
+	if i < len(nl) {
+		goto toomany
+	}
+
+invalidddd:
+	if isddd {
+		if call != nil {
+			base.Errorf("invalid use of ... in call to %v", call)
+		} else {
+			base.Errorf("invalid use of ... in %v", op)
+		}
+	}
+	return
+
+notenough:
+	if n == nil || (!n.Diag() && n.Type() != nil) {
+		details := errorDetails(nl, tstruct, isddd)
+		if call != nil {
+			// 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() == ir.OMETHEXPR {
+				call := call.(*ir.SelectorExpr)
+				base.Errorf("not enough arguments in call to method expression %v%s", call, details)
+			} else {
+				base.Errorf("not enough arguments in call to %v%s", call, details)
+			}
+		} else {
+			base.Errorf("not enough arguments to %v%s", op, details)
+		}
+		if n != nil {
+			n.SetDiag(true)
+		}
+	}
+	return
+
+toomany:
+	details := errorDetails(nl, tstruct, isddd)
+	if call != nil {
+		base.Errorf("too many arguments in call to %v%s", call, details)
+	} else {
+		base.Errorf("too many arguments to %v%s", op, details)
+	}
+}
+
+func errorDetails(nl ir.Nodes, tstruct *types.Type, isddd bool) string {
+	// Suppress any return message signatures if:
+	//
+	// (1) We don't know any type at a call site (see #19012).
+	// (2) Any node has an unknown type.
+	// (3) Invalid type for variadic parameter (see #46957).
+	if tstruct == nil {
+		return "" // case 1
+	}
+
+	if isddd && !nl[len(nl)-1].Type().IsSlice() {
+		return "" // case 3
+	}
+
+	for _, n := range nl {
+		if n.Type() == nil {
+			return "" // case 2
+		}
+	}
+	return fmt.Sprintf("\n\thave %s\n\twant %v", fmtSignature(nl, isddd), tstruct)
+}
+
+// sigrepr is a type's representation to the outside world,
+// in string representations of return signatures
+// e.g in error messages about wrong arguments to return.
+func sigrepr(t *types.Type, isddd bool) string {
+	switch t {
+	case types.UntypedString:
+		return "string"
+	case types.UntypedBool:
+		return "bool"
+	}
+
+	if t.Kind() == types.TIDEAL {
+		// "untyped number" is not commonly used
+		// outside of the compiler, so let's use "number".
+		// TODO(mdempsky): Revisit this.
+		return "number"
+	}
+
+	// Turn []T... argument to ...T for clearer error message.
+	if isddd {
+		if !t.IsSlice() {
+			base.Fatalf("bad type for ... argument: %v", t)
+		}
+		return "..." + t.Elem().String()
+	}
+	return t.String()
+}
+
+// sigerr returns the signature of the types at the call or return.
+func fmtSignature(nl ir.Nodes, isddd bool) string {
+	if len(nl) < 1 {
+		return "()"
+	}
+
+	var typeStrings []string
+	for i, n := range nl {
+		isdddArg := isddd && i == len(nl)-1
+		typeStrings = append(typeStrings, sigrepr(n.Type(), isdddArg))
+	}
+
+	return fmt.Sprintf("(%s)", strings.Join(typeStrings, ", "))
+}
+
+// type check composite
+func fielddup(name string, hash map[string]bool) {
+	if hash[name] {
+		base.Errorf("duplicate field name in struct literal: %s", name)
+		return
+	}
+	hash[name] = true
+}
+
+// iscomptype reports whether type t is a composite literal type.
+func iscomptype(t *types.Type) bool {
+	switch t.Kind() {
+	case types.TARRAY, types.TSLICE, types.TSTRUCT, types.TMAP:
+		return true
+	default:
+		return false
+	}
+}
+
+// pushtype adds elided type information for composite literals if
+// appropriate, and returns the resulting expression.
+func pushtype(nn ir.Node, t *types.Type) ir.Node {
+	if nn == nil || nn.Op() != ir.OCOMPLIT {
+		return nn
+	}
+	n := nn.(*ir.CompLitExpr)
+	if n.Ntype != nil {
+		return n
+	}
+
+	switch {
+	case iscomptype(t):
+		// For T, return T{...}.
+		n.Ntype = ir.TypeNode(t)
+
+	case t.IsPtr() && iscomptype(t.Elem()):
+		// For *T, return &T{...}.
+		n.Ntype = ir.TypeNode(t.Elem())
+
+		addr := NodAddrAt(n.Pos(), n)
+		addr.SetImplicit(true)
+		return addr
+	}
+	return n
+}
+
+// typecheckarraylit type-checks a sequence of slice/array literal elements.
+func typecheckarraylit(elemType *types.Type, bound int64, elts []ir.Node, ctx string) int64 {
+	// If there are key/value pairs, create a map to keep seen
+	// keys so we can check for duplicate indices.
+	var indices map[int64]bool
+	for _, elt := range elts {
+		if elt.Op() == ir.OKEY {
+			indices = make(map[int64]bool)
+			break
+		}
+	}
+
+	var key, length int64
+	for i, elt := range elts {
+		ir.SetPos(elt)
+		r := elts[i]
+		var kv *ir.KeyExpr
+		if elt.Op() == ir.OKEY {
+			elt := elt.(*ir.KeyExpr)
+			elt.Key = Expr(elt.Key)
+			key = IndexConst(elt.Key)
+			if key < 0 {
+				if !elt.Key.Diag() {
+					if key == -2 {
+						base.Errorf("index too large")
+					} else {
+						base.Errorf("index must be non-negative integer constant")
+					}
+					elt.Key.SetDiag(true)
+				}
+				key = -(1 << 30) // stay negative for a while
+			}
+			kv = elt
+			r = elt.Value
+		}
+
+		r = pushtype(r, elemType)
+		r = Expr(r)
+		r = AssignConv(r, elemType, ctx)
+		if kv != nil {
+			kv.Value = r
+		} else {
+			elts[i] = r
+		}
+
+		if key >= 0 {
+			if indices != nil {
+				if indices[key] {
+					base.Errorf("duplicate index in %s: %d", ctx, key)
+				} else {
+					indices[key] = true
+				}
+			}
+
+			if bound >= 0 && key >= bound {
+				base.Errorf("array index %d out of bounds [0:%d]", key, bound)
+				bound = -1
+			}
+		}
+
+		key++
+		if key > length {
+			length = key
+		}
+	}
+
+	return length
+}
+
+// visible reports whether sym is exported or locally defined.
+func visible(sym *types.Sym) bool {
+	return sym != nil && (types.IsExported(sym.Name) || sym.Pkg == types.LocalPkg)
+}
+
+// nonexported reports whether sym is an unexported field.
+func nonexported(sym *types.Sym) bool {
+	return sym != nil && !types.IsExported(sym.Name)
+}
+
+func checklvalue(n ir.Node, verb string) {
+	if !ir.IsAddressable(n) {
+		base.Errorf("cannot %s %v", verb, n)
+	}
+}
+
+func checkassign(stmt ir.Node, n ir.Node) {
+	// have already complained about n being invalid
+	if n.Type() == nil {
+		if base.Errors() == 0 {
+			base.Fatalf("expected an error about %v", n)
+		}
+		return
+	}
+
+	if ir.IsAddressable(n) {
+		return
+	}
+	if n.Op() == ir.OINDEXMAP {
+		n := n.(*ir.IndexExpr)
+		n.Assigned = true
+		return
+	}
+
+	defer n.SetType(nil)
+	if n.Diag() {
+		return
+	}
+	switch {
+	case n.Op() == ir.ODOT && n.(*ir.SelectorExpr).X.Op() == ir.OINDEXMAP:
+		base.Errorf("cannot assign to struct field %v in map", n)
+	case (n.Op() == ir.OINDEX && n.(*ir.IndexExpr).X.Type().IsString()) || n.Op() == ir.OSLICESTR:
+		base.Errorf("cannot assign to %v (strings are immutable)", n)
+	case n.Op() == ir.OLITERAL && n.Sym() != nil && ir.IsConstNode(n):
+		base.Errorf("cannot assign to %v (declared const)", n)
+	default:
+		base.Errorf("cannot assign to %v", n)
+	}
+}
+
+func checkassignto(src *types.Type, dst ir.Node) {
+	// TODO(mdempsky): Handle all untyped types correctly.
+	if src == types.UntypedBool && dst.Type().IsBoolean() {
+		return
+	}
+
+	if op, why := Assignop(src, dst.Type()); op == ir.OXXX {
+		base.Errorf("cannot assign %v to %L in multiple assignment%s", src, dst, why)
+		return
+	}
+}
+
+// The result of stringtoruneslit MUST be assigned back to n, e.g.
+// 	n.Left = stringtoruneslit(n.Left)
+func stringtoruneslit(n *ir.ConvExpr) ir.Node {
+	if n.X.Op() != ir.OLITERAL || n.X.Val().Kind() != constant.String {
+		base.Fatalf("stringtoarraylit %v", n)
+	}
+
+	var l []ir.Node
+	i := 0
+	for _, r := range ir.StringVal(n.X) {
+		l = append(l, ir.NewKeyExpr(base.Pos, ir.NewInt(int64(i)), ir.NewInt(int64(r))))
+		i++
+	}
+
+	nn := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(n.Type()), nil)
+	nn.List = l
+	return Expr(nn)
+}
+
+var mapqueue []*ir.MapType
+
+func CheckMapKeys() {
+	for _, n := range mapqueue {
+		k := n.Type().MapType().Key
+		if !k.Broke() && !types.IsComparable(k) {
+			base.ErrorfAt(n.Pos(), "invalid map key type %v", k)
+		}
+	}
+	mapqueue = nil
+}
+
+// TypeGen tracks the number of function-scoped defined types that
+// have been declared. It's used to generate unique linker symbols for
+// their runtime type descriptors.
+var TypeGen int32
+
+func typecheckdeftype(n *ir.Name) {
+	if base.EnableTrace && base.Flag.LowerT {
+		defer tracePrint("typecheckdeftype", n)(nil)
+	}
+
+	t := types.NewNamed(n)
+	if n.Curfn != nil {
+		TypeGen++
+		t.Vargen = TypeGen
+	}
+
+	if n.Pragma()&ir.NotInHeap != 0 {
+		t.SetNotInHeap(true)
+	}
+
+	n.SetType(t)
+	n.SetTypecheck(1)
+	n.SetWalkdef(1)
+
+	types.DeferCheckSize()
+	errorsBefore := base.Errors()
+	n.Ntype = typecheckNtype(n.Ntype)
+	if underlying := n.Ntype.Type(); underlying != nil {
+		t.SetUnderlying(underlying)
+	} else {
+		n.SetDiag(true)
+		n.SetType(nil)
+	}
+	if t.Kind() == types.TFORW && base.Errors() > errorsBefore {
+		// Something went wrong during type-checking,
+		// but it was reported. Silence future errors.
+		t.SetBroke(true)
+	}
+	types.ResumeCheckSize()
+}
+
+func typecheckdef(n *ir.Name) {
+	if base.EnableTrace && base.Flag.LowerT {
+		defer tracePrint("typecheckdef", n)(nil)
+	}
+
+	if n.Walkdef() == 1 {
+		return
+	}
+
+	if n.Type() != nil { // builtin
+		// Mark as Walkdef so that if n.SetType(nil) is called later, we
+		// won't try walking again.
+		if got := n.Walkdef(); got != 0 {
+			base.Fatalf("unexpected walkdef: %v", got)
+		}
+		n.SetWalkdef(1)
+		return
+	}
+
+	lno := ir.SetPos(n)
+	typecheckdefstack = append(typecheckdefstack, n)
+	if n.Walkdef() == 2 {
+		base.FlushErrors()
+		fmt.Printf("typecheckdef loop:")
+		for i := len(typecheckdefstack) - 1; i >= 0; i-- {
+			n := typecheckdefstack[i]
+			fmt.Printf(" %v", n.Sym())
+		}
+		fmt.Printf("\n")
+		base.Fatalf("typecheckdef loop")
+	}
+
+	n.SetWalkdef(2)
+
+	switch n.Op() {
+	default:
+		base.Fatalf("typecheckdef %v", n.Op())
+
+	case ir.OLITERAL:
+		if n.Ntype != nil {
+			n.Ntype = typecheckNtype(n.Ntype)
+			n.SetType(n.Ntype.Type())
+			n.Ntype = nil
+			if n.Type() == nil {
+				n.SetDiag(true)
+				goto ret
+			}
+		}
+
+		e := n.Defn
+		n.Defn = nil
+		if e == nil {
+			ir.Dump("typecheckdef nil defn", n)
+			base.ErrorfAt(n.Pos(), "xxx")
+		}
+
+		e = Expr(e)
+		if e.Type() == nil {
+			goto ret
+		}
+		if !ir.IsConstNode(e) {
+			if !e.Diag() {
+				if e.Op() == ir.ONIL {
+					base.ErrorfAt(n.Pos(), "const initializer cannot be nil")
+				} else {
+					base.ErrorfAt(n.Pos(), "const initializer %v is not a constant", e)
+				}
+				e.SetDiag(true)
+			}
+			goto ret
+		}
+
+		t := n.Type()
+		if t != nil {
+			if !ir.OKForConst[t.Kind()] {
+				base.ErrorfAt(n.Pos(), "invalid constant type %v", t)
+				goto ret
+			}
+
+			if !e.Type().IsUntyped() && !types.Identical(t, e.Type()) {
+				base.ErrorfAt(n.Pos(), "cannot use %L as type %v in const initializer", e, t)
+				goto ret
+			}
+
+			e = convlit(e, t)
+		}
+
+		n.SetType(e.Type())
+		if n.Type() != nil {
+			n.SetVal(e.Val())
+		}
+
+	case ir.ONAME:
+		if n.Ntype != nil {
+			n.Ntype = typecheckNtype(n.Ntype)
+			n.SetType(n.Ntype.Type())
+			if n.Type() == nil {
+				n.SetDiag(true)
+				goto ret
+			}
+		}
+
+		if n.Type() != nil {
+			break
+		}
+		if n.Defn == nil {
+			if n.BuiltinOp != 0 { // like OPRINTN
+				break
+			}
+			if base.Errors() > 0 {
+				// Can have undefined variables in x := foo
+				// that make x have an n.name.Defn == nil.
+				// If there are other errors anyway, don't
+				// bother adding to the noise.
+				break
+			}
+
+			base.Fatalf("var without type, init: %v", n.Sym())
+		}
+
+		if n.Defn.Op() == ir.ONAME {
+			n.Defn = Expr(n.Defn)
+			n.SetType(n.Defn.Type())
+			break
+		}
+
+		n.Defn = Stmt(n.Defn) // fills in n.Type
+
+	case ir.OTYPE:
+		if n.Alias() {
+			// Type alias declaration: Simply use the rhs type - no need
+			// to create a new type.
+			// If we have a syntax error, name.Ntype may be nil.
+			if n.Ntype != nil {
+				n.Ntype = typecheckNtype(n.Ntype)
+				n.SetType(n.Ntype.Type())
+				if n.Type() == nil {
+					n.SetDiag(true)
+					goto ret
+				}
+				// For package-level type aliases, set n.Sym.Def so we can identify
+				// it as a type alias during export. See also #31959.
+				if n.Curfn == nil {
+					n.Sym().Def = n.Ntype
+				}
+			}
+			break
+		}
+
+		// regular type declaration
+		typecheckdeftype(n)
+	}
+
+ret:
+	if n.Op() != ir.OLITERAL && n.Type() != nil && n.Type().IsUntyped() {
+		base.Fatalf("got %v for %v", n.Type(), n)
+	}
+	last := len(typecheckdefstack) - 1
+	if typecheckdefstack[last] != n {
+		base.Fatalf("typecheckdefstack mismatch")
+	}
+	typecheckdefstack[last] = nil
+	typecheckdefstack = typecheckdefstack[:last]
+
+	base.Pos = lno
+	n.SetWalkdef(1)
+}
+
+func checkmake(t *types.Type, arg string, np *ir.Node) bool {
+	n := *np
+	if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
+		base.Errorf("non-integer %s argument in make(%v) - %v", arg, t, n.Type())
+		return false
+	}
+
+	// Do range checks for constants before DefaultLit
+	// to avoid redundant "constant NNN overflows int" errors.
+	if n.Op() == ir.OLITERAL {
+		v := toint(n.Val())
+		if constant.Sign(v) < 0 {
+			base.Errorf("negative %s argument in make(%v)", arg, t)
+			return false
+		}
+		if ir.ConstOverflow(v, types.Types[types.TINT]) {
+			base.Errorf("%s argument too large in make(%v)", arg, t)
+			return false
+		}
+	}
+
+	// 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[types.TINT])
+	*np = n
+
+	return true
+}
+
+// checkunsafeslice is like checkmake but for unsafe.Slice.
+func checkunsafeslice(np *ir.Node) bool {
+	n := *np
+	if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
+		base.Errorf("non-integer len argument in unsafe.Slice - %v", n.Type())
+		return false
+	}
+
+	// Do range checks for constants before DefaultLit
+	// to avoid redundant "constant NNN overflows int" errors.
+	if n.Op() == ir.OLITERAL {
+		v := toint(n.Val())
+		if constant.Sign(v) < 0 {
+			base.Errorf("negative len argument in unsafe.Slice")
+			return false
+		}
+		if ir.ConstOverflow(v, types.Types[types.TINT]) {
+			base.Errorf("len argument too large in unsafe.Slice")
+			return false
+		}
+	}
+
+	// DefaultLit is necessary for non-constants too: n might be 1.1<<k.
+	n = DefaultLit(n, types.Types[types.TINT])
+	*np = n
+
+	return true
+}
+
+// markBreak marks control statements containing break statements with SetHasBreak(true).
+func markBreak(fn *ir.Func) {
+	var labels map[*types.Sym]ir.Node
+	var implicit ir.Node
+
+	var mark func(ir.Node) bool
+	mark = func(n ir.Node) bool {
+		switch n.Op() {
+		default:
+			ir.DoChildren(n, mark)
+
+		case ir.OBREAK:
+			n := n.(*ir.BranchStmt)
+			if n.Label == nil {
+				setHasBreak(implicit)
+			} else {
+				setHasBreak(labels[n.Label])
+			}
+
+		case ir.OFOR, ir.OFORUNTIL, ir.OSWITCH, ir.OSELECT, ir.ORANGE:
+			old := implicit
+			implicit = n
+			var sym *types.Sym
+			switch n := n.(type) {
+			case *ir.ForStmt:
+				sym = n.Label
+			case *ir.RangeStmt:
+				sym = n.Label
+			case *ir.SelectStmt:
+				sym = n.Label
+			case *ir.SwitchStmt:
+				sym = n.Label
+			}
+			if sym != nil {
+				if labels == nil {
+					// Map creation delayed until we need it - most functions don't.
+					labels = make(map[*types.Sym]ir.Node)
+				}
+				labels[sym] = n
+			}
+			ir.DoChildren(n, mark)
+			if sym != nil {
+				delete(labels, sym)
+			}
+			implicit = old
+		}
+		return false
+	}
+
+	mark(fn)
+}
+
+func controlLabel(n ir.Node) *types.Sym {
+	switch n := n.(type) {
+	default:
+		base.Fatalf("controlLabel %+v", n.Op())
+		return nil
+	case *ir.ForStmt:
+		return n.Label
+	case *ir.RangeStmt:
+		return n.Label
+	case *ir.SelectStmt:
+		return n.Label
+	case *ir.SwitchStmt:
+		return n.Label
+	}
+}
+
+func setHasBreak(n ir.Node) {
+	switch n := n.(type) {
+	default:
+		base.Fatalf("setHasBreak %+v", n.Op())
+	case nil:
+		// ignore
+	case *ir.ForStmt:
+		n.HasBreak = true
+	case *ir.RangeStmt:
+		n.HasBreak = true
+	case *ir.SelectStmt:
+		n.HasBreak = true
+	case *ir.SwitchStmt:
+		n.HasBreak = true
+	}
+}
+
+// isTermNodes reports whether the Nodes list ends with a terminating statement.
+func isTermNodes(l ir.Nodes) bool {
+	s := l
+	c := len(s)
+	if c == 0 {
+		return false
+	}
+	return isTermNode(s[c-1])
+}
+
+// isTermNode reports whether the node n, the last one in a
+// statement list, is a terminating statement.
+func isTermNode(n ir.Node) bool {
+	switch n.Op() {
+	// NOTE: OLABEL is treated as a separate statement,
+	// not a separate prefix, so skipping to the last statement
+	// in the block handles the labeled statement case by
+	// skipping over the label. No case OLABEL here.
+
+	case ir.OBLOCK:
+		n := n.(*ir.BlockStmt)
+		return isTermNodes(n.List)
+
+	case ir.OGOTO, ir.ORETURN, ir.OTAILCALL, ir.OPANIC, ir.OFALL:
+		return true
+
+	case ir.OFOR, ir.OFORUNTIL:
+		n := n.(*ir.ForStmt)
+		if n.Cond != nil {
+			return false
+		}
+		if n.HasBreak {
+			return false
+		}
+		return true
+
+	case ir.OIF:
+		n := n.(*ir.IfStmt)
+		return isTermNodes(n.Body) && isTermNodes(n.Else)
+
+	case ir.OSWITCH:
+		n := n.(*ir.SwitchStmt)
+		if n.HasBreak {
+			return false
+		}
+		def := false
+		for _, cas := range n.Cases {
+			if !isTermNodes(cas.Body) {
+				return false
+			}
+			if len(cas.List) == 0 { // default
+				def = true
+			}
+		}
+		return def
+
+	case ir.OSELECT:
+		n := n.(*ir.SelectStmt)
+		if n.HasBreak {
+			return false
+		}
+		for _, cas := range n.Cases {
+			if !isTermNodes(cas.Body) {
+				return false
+			}
+		}
+		return true
+	}
+
+	return false
+}
+
+// CheckUnused checks for any declared variables that weren't used.
+func CheckUnused(fn *ir.Func) {
+	// Only report unused variables if we haven't seen any type-checking
+	// errors yet.
+	if base.Errors() != 0 {
+		return
+	}
+
+	// Propagate the used flag for typeswitch variables up to the NONAME in its definition.
+	for _, ln := range fn.Dcl {
+		if ln.Op() == ir.ONAME && ln.Class == ir.PAUTO && ln.Used() {
+			if guard, ok := ln.Defn.(*ir.TypeSwitchGuard); ok {
+				guard.Used = true
+			}
+		}
+	}
+
+	for _, ln := range fn.Dcl {
+		if ln.Op() != ir.ONAME || ln.Class != ir.PAUTO || ln.Used() {
+			continue
+		}
+		if defn, ok := ln.Defn.(*ir.TypeSwitchGuard); ok {
+			if defn.Used {
+				continue
+			}
+			base.ErrorfAt(defn.Tag.Pos(), "%v declared but not used", ln.Sym())
+			defn.Used = true // suppress repeats
+		} else {
+			base.ErrorfAt(ln.Pos(), "%v declared but not used", ln.Sym())
+		}
+	}
+}
+
+// CheckReturn makes sure that fn terminates appropriately.
+func CheckReturn(fn *ir.Func) {
+	if fn.Type() != nil && fn.Type().NumResults() != 0 && len(fn.Body) != 0 {
+		markBreak(fn)
+		if !isTermNodes(fn.Body) {
+			base.ErrorfAt(fn.Endlineno, "missing return at end of function")
+		}
+	}
+}
+
+// getIotaValue returns the current value for "iota",
+// or -1 if not within a ConstSpec.
+func getIotaValue() int64 {
+	if i := len(typecheckdefstack); i > 0 {
+		if x := typecheckdefstack[i-1]; x.Op() == ir.OLITERAL {
+			return x.Iota()
+		}
+	}
+
+	if ir.CurFunc != nil && ir.CurFunc.Iota >= 0 {
+		return ir.CurFunc.Iota
+	}
+
+	return -1
+}
+
+// curpkg returns the current package, based on Curfn.
+func curpkg() *types.Pkg {
+	fn := ir.CurFunc
+	if fn == nil {
+		// Initialization expressions for package-scope variables.
+		return types.LocalPkg
+	}
+	return fnpkg(fn.Nname)
+}
+
+func Conv(n ir.Node, t *types.Type) ir.Node {
+	if types.Identical(n.Type(), t) {
+		return n
+	}
+	n = ir.NewConvExpr(base.Pos, ir.OCONV, nil, n)
+	n.SetType(t)
+	n = Expr(n)
+	return n
+}
+
+// ConvNop converts node n to type t using the OCONVNOP op
+// and typechecks the result with ctxExpr.
+func ConvNop(n ir.Node, t *types.Type) ir.Node {
+	if types.Identical(n.Type(), t) {
+		return n
+	}
+	n = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, n)
+	n.SetType(t)
+	n = Expr(n)
+	return n
+}
diff --git a/src/cmd/compile/internal/typecheck/universe.go b/src/cmd/compile/internal/typecheck/universe.go
new file mode 100644
index 0000000..de185ab
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/universe.go
@@ -0,0 +1,359 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typecheck
+
+import (
+	"go/constant"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+var (
+	okfor [ir.OEND][]bool
+	iscmp [ir.OEND]bool
+)
+
+var (
+	okforeq    [types.NTYPE]bool
+	okforadd   [types.NTYPE]bool
+	okforand   [types.NTYPE]bool
+	okfornone  [types.NTYPE]bool
+	okforbool  [types.NTYPE]bool
+	okforcap   [types.NTYPE]bool
+	okforlen   [types.NTYPE]bool
+	okforarith [types.NTYPE]bool
+)
+
+var basicTypes = [...]struct {
+	name  string
+	etype types.Kind
+}{
+	{"int8", types.TINT8},
+	{"int16", types.TINT16},
+	{"int32", types.TINT32},
+	{"int64", types.TINT64},
+	{"uint8", types.TUINT8},
+	{"uint16", types.TUINT16},
+	{"uint32", types.TUINT32},
+	{"uint64", types.TUINT64},
+	{"float32", types.TFLOAT32},
+	{"float64", types.TFLOAT64},
+	{"complex64", types.TCOMPLEX64},
+	{"complex128", types.TCOMPLEX128},
+	{"bool", types.TBOOL},
+	{"string", types.TSTRING},
+}
+
+var typedefs = [...]struct {
+	name     string
+	etype    types.Kind
+	sameas32 types.Kind
+	sameas64 types.Kind
+}{
+	{"int", types.TINT, types.TINT32, types.TINT64},
+	{"uint", types.TUINT, types.TUINT32, types.TUINT64},
+	{"uintptr", types.TUINTPTR, types.TUINT32, types.TUINT64},
+}
+
+var builtinFuncs = [...]struct {
+	name string
+	op   ir.Op
+}{
+	{"append", ir.OAPPEND},
+	{"cap", ir.OCAP},
+	{"close", ir.OCLOSE},
+	{"complex", ir.OCOMPLEX},
+	{"copy", ir.OCOPY},
+	{"delete", ir.ODELETE},
+	{"imag", ir.OIMAG},
+	{"len", ir.OLEN},
+	{"make", ir.OMAKE},
+	{"new", ir.ONEW},
+	{"panic", ir.OPANIC},
+	{"print", ir.OPRINT},
+	{"println", ir.OPRINTN},
+	{"real", ir.OREAL},
+	{"recover", ir.ORECOVER},
+}
+
+var unsafeFuncs = [...]struct {
+	name string
+	op   ir.Op
+}{
+	{"Add", ir.OUNSAFEADD},
+	{"Alignof", ir.OALIGNOF},
+	{"Offsetof", ir.OOFFSETOF},
+	{"Sizeof", ir.OSIZEOF},
+	{"Slice", ir.OUNSAFESLICE},
+}
+
+// InitUniverse initializes the universe block.
+func InitUniverse() {
+	if types.PtrSize == 0 {
+		base.Fatalf("typeinit before betypeinit")
+	}
+
+	types.SlicePtrOffset = 0
+	types.SliceLenOffset = types.Rnd(types.SlicePtrOffset+int64(types.PtrSize), int64(types.PtrSize))
+	types.SliceCapOffset = types.Rnd(types.SliceLenOffset+int64(types.PtrSize), int64(types.PtrSize))
+	types.SliceSize = types.Rnd(types.SliceCapOffset+int64(types.PtrSize), int64(types.PtrSize))
+
+	// string is same as slice wo the cap
+	types.StringSize = types.Rnd(types.SliceLenOffset+int64(types.PtrSize), int64(types.PtrSize))
+
+	for et := types.Kind(0); et < types.NTYPE; et++ {
+		types.SimType[et] = et
+	}
+
+	types.Types[types.TANY] = types.New(types.TANY)
+	types.Types[types.TINTER] = types.NewInterface(types.LocalPkg, nil)
+
+	defBasic := func(kind types.Kind, pkg *types.Pkg, name string) *types.Type {
+		sym := pkg.Lookup(name)
+		n := ir.NewDeclNameAt(src.NoXPos, ir.OTYPE, sym)
+		t := types.NewBasic(kind, n)
+		n.SetType(t)
+		sym.Def = n
+		if kind != types.TANY {
+			types.CalcSize(t)
+		}
+		return t
+	}
+
+	for _, s := range &basicTypes {
+		types.Types[s.etype] = defBasic(s.etype, types.BuiltinPkg, s.name)
+	}
+
+	for _, s := range &typedefs {
+		sameas := s.sameas32
+		if types.PtrSize == 8 {
+			sameas = s.sameas64
+		}
+		types.SimType[s.etype] = sameas
+
+		types.Types[s.etype] = defBasic(s.etype, types.BuiltinPkg, s.name)
+	}
+
+	// We create separate byte and rune types for better error messages
+	// rather than just creating type alias *types.Sym's for the uint8 and
+	// int32 types. Hence, (bytetype|runtype).Sym.isAlias() is false.
+	// TODO(gri) Should we get rid of this special case (at the cost
+	// of less informative error messages involving bytes and runes)?
+	// (Alternatively, we could introduce an OTALIAS node representing
+	// type aliases, albeit at the cost of having to deal with it everywhere).
+	types.ByteType = defBasic(types.TUINT8, types.BuiltinPkg, "byte")
+	types.RuneType = defBasic(types.TINT32, types.BuiltinPkg, "rune")
+
+	// error type
+	s := types.BuiltinPkg.Lookup("error")
+	n := ir.NewDeclNameAt(src.NoXPos, ir.OTYPE, s)
+	types.ErrorType = types.NewNamed(n)
+	types.ErrorType.SetUnderlying(makeErrorInterface())
+	n.SetType(types.ErrorType)
+	s.Def = n
+	types.CalcSize(types.ErrorType)
+
+	types.Types[types.TUNSAFEPTR] = defBasic(types.TUNSAFEPTR, ir.Pkgs.Unsafe, "Pointer")
+
+	// simple aliases
+	types.SimType[types.TMAP] = types.TPTR
+	types.SimType[types.TCHAN] = types.TPTR
+	types.SimType[types.TFUNC] = types.TPTR
+	types.SimType[types.TUNSAFEPTR] = types.TPTR
+
+	for _, s := range &builtinFuncs {
+		s2 := types.BuiltinPkg.Lookup(s.name)
+		def := NewName(s2)
+		def.BuiltinOp = s.op
+		s2.Def = def
+	}
+
+	for _, s := range &unsafeFuncs {
+		s2 := ir.Pkgs.Unsafe.Lookup(s.name)
+		def := NewName(s2)
+		def.BuiltinOp = s.op
+		s2.Def = def
+	}
+
+	s = types.BuiltinPkg.Lookup("true")
+	s.Def = ir.NewConstAt(src.NoXPos, s, types.UntypedBool, constant.MakeBool(true))
+
+	s = types.BuiltinPkg.Lookup("false")
+	s.Def = ir.NewConstAt(src.NoXPos, s, types.UntypedBool, constant.MakeBool(false))
+
+	s = Lookup("_")
+	types.BlankSym = s
+	s.Block = -100
+	s.Def = NewName(s)
+	types.Types[types.TBLANK] = types.New(types.TBLANK)
+	ir.AsNode(s.Def).SetType(types.Types[types.TBLANK])
+	ir.BlankNode = ir.AsNode(s.Def)
+	ir.BlankNode.SetTypecheck(1)
+
+	s = types.BuiltinPkg.Lookup("_")
+	s.Block = -100
+	s.Def = NewName(s)
+	types.Types[types.TBLANK] = types.New(types.TBLANK)
+	ir.AsNode(s.Def).SetType(types.Types[types.TBLANK])
+
+	types.Types[types.TNIL] = types.New(types.TNIL)
+	s = types.BuiltinPkg.Lookup("nil")
+	nnil := NodNil()
+	nnil.(*ir.NilExpr).SetSym(s)
+	s.Def = nnil
+
+	s = types.BuiltinPkg.Lookup("iota")
+	s.Def = ir.NewIota(base.Pos, s)
+
+	for et := types.TINT8; et <= types.TUINT64; et++ {
+		types.IsInt[et] = true
+	}
+	types.IsInt[types.TINT] = true
+	types.IsInt[types.TUINT] = true
+	types.IsInt[types.TUINTPTR] = true
+
+	types.IsFloat[types.TFLOAT32] = true
+	types.IsFloat[types.TFLOAT64] = true
+
+	types.IsComplex[types.TCOMPLEX64] = true
+	types.IsComplex[types.TCOMPLEX128] = true
+
+	// initialize okfor
+	for et := types.Kind(0); et < types.NTYPE; et++ {
+		if types.IsInt[et] || et == types.TIDEAL {
+			okforeq[et] = true
+			types.IsOrdered[et] = true
+			okforarith[et] = true
+			okforadd[et] = true
+			okforand[et] = true
+			ir.OKForConst[et] = true
+			types.IsSimple[et] = true
+		}
+
+		if types.IsFloat[et] {
+			okforeq[et] = true
+			types.IsOrdered[et] = true
+			okforadd[et] = true
+			okforarith[et] = true
+			ir.OKForConst[et] = true
+			types.IsSimple[et] = true
+		}
+
+		if types.IsComplex[et] {
+			okforeq[et] = true
+			okforadd[et] = true
+			okforarith[et] = true
+			ir.OKForConst[et] = true
+			types.IsSimple[et] = true
+		}
+	}
+
+	types.IsSimple[types.TBOOL] = true
+
+	okforadd[types.TSTRING] = true
+
+	okforbool[types.TBOOL] = true
+
+	okforcap[types.TARRAY] = true
+	okforcap[types.TCHAN] = true
+	okforcap[types.TSLICE] = true
+
+	ir.OKForConst[types.TBOOL] = true
+	ir.OKForConst[types.TSTRING] = true
+
+	okforlen[types.TARRAY] = true
+	okforlen[types.TCHAN] = true
+	okforlen[types.TMAP] = true
+	okforlen[types.TSLICE] = true
+	okforlen[types.TSTRING] = true
+
+	okforeq[types.TPTR] = true
+	okforeq[types.TUNSAFEPTR] = true
+	okforeq[types.TINTER] = true
+	okforeq[types.TCHAN] = true
+	okforeq[types.TSTRING] = true
+	okforeq[types.TBOOL] = true
+	okforeq[types.TMAP] = true    // nil only; refined in typecheck
+	okforeq[types.TFUNC] = true   // nil only; refined in typecheck
+	okforeq[types.TSLICE] = true  // nil only; refined in typecheck
+	okforeq[types.TARRAY] = true  // only if element type is comparable; refined in typecheck
+	okforeq[types.TSTRUCT] = true // only if all struct fields are comparable; refined in typecheck
+
+	types.IsOrdered[types.TSTRING] = true
+
+	for i := range okfor {
+		okfor[i] = okfornone[:]
+	}
+
+	// binary
+	okfor[ir.OADD] = okforadd[:]
+	okfor[ir.OAND] = okforand[:]
+	okfor[ir.OANDAND] = okforbool[:]
+	okfor[ir.OANDNOT] = okforand[:]
+	okfor[ir.ODIV] = okforarith[:]
+	okfor[ir.OEQ] = okforeq[:]
+	okfor[ir.OGE] = types.IsOrdered[:]
+	okfor[ir.OGT] = types.IsOrdered[:]
+	okfor[ir.OLE] = types.IsOrdered[:]
+	okfor[ir.OLT] = types.IsOrdered[:]
+	okfor[ir.OMOD] = okforand[:]
+	okfor[ir.OMUL] = okforarith[:]
+	okfor[ir.ONE] = okforeq[:]
+	okfor[ir.OOR] = okforand[:]
+	okfor[ir.OOROR] = okforbool[:]
+	okfor[ir.OSUB] = okforarith[:]
+	okfor[ir.OXOR] = okforand[:]
+	okfor[ir.OLSH] = okforand[:]
+	okfor[ir.ORSH] = okforand[:]
+
+	// unary
+	okfor[ir.OBITNOT] = okforand[:]
+	okfor[ir.ONEG] = okforarith[:]
+	okfor[ir.ONOT] = okforbool[:]
+	okfor[ir.OPLUS] = okforarith[:]
+
+	// special
+	okfor[ir.OCAP] = okforcap[:]
+	okfor[ir.OLEN] = okforlen[:]
+
+	// comparison
+	iscmp[ir.OLT] = true
+	iscmp[ir.OGT] = true
+	iscmp[ir.OGE] = true
+	iscmp[ir.OLE] = true
+	iscmp[ir.OEQ] = true
+	iscmp[ir.ONE] = true
+}
+
+func makeErrorInterface() *types.Type {
+	sig := types.NewSignature(types.NoPkg, fakeRecvField(), nil, nil, []*types.Field{
+		types.NewField(src.NoXPos, nil, types.Types[types.TSTRING]),
+	})
+	method := types.NewField(src.NoXPos, Lookup("Error"), sig)
+	return types.NewInterface(types.NoPkg, []*types.Field{method})
+}
+
+// DeclareUniverse makes the universe block visible within the current package.
+func DeclareUniverse() {
+	// Operationally, this is similar to a dot import of builtinpkg, except
+	// that we silently skip symbols that are already declared in the
+	// package block rather than emitting a redeclared symbol error.
+
+	for _, s := range types.BuiltinPkg.Syms {
+		if s.Def == nil {
+			continue
+		}
+		s1 := Lookup(s.Name)
+		if s1.Def != nil {
+			continue
+		}
+
+		s1.Def = s.Def
+		s1.Block = s.Block
+	}
+}
diff --git a/src/cmd/compile/internal/types/alg.go b/src/cmd/compile/internal/types/alg.go
new file mode 100644
index 0000000..2c2700f
--- /dev/null
+++ b/src/cmd/compile/internal/types/alg.go
@@ -0,0 +1,173 @@
+// 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 types
+
+import "cmd/compile/internal/base"
+
+// AlgKind describes the kind of algorithms used for comparing and
+// hashing a Type.
+type AlgKind int
+
+//go:generate stringer -type AlgKind -trimprefix A alg.go
+
+const (
+	// These values are known by runtime.
+	ANOEQ AlgKind = iota
+	AMEM0
+	AMEM8
+	AMEM16
+	AMEM32
+	AMEM64
+	AMEM128
+	ASTRING
+	AINTER
+	ANILINTER
+	AFLOAT32
+	AFLOAT64
+	ACPLX64
+	ACPLX128
+
+	// Type can be compared/hashed as regular memory.
+	AMEM AlgKind = 100
+
+	// Type needs special comparison/hashing functions.
+	ASPECIAL AlgKind = -1
+)
+
+// AlgType returns the AlgKind used for comparing and hashing Type t.
+// If it returns ANOEQ, it also returns the component type of t that
+// makes it incomparable.
+func AlgType(t *Type) (AlgKind, *Type) {
+	if t.Broke() {
+		return AMEM, nil
+	}
+	if t.Noalg() {
+		return ANOEQ, t
+	}
+
+	switch t.Kind() {
+	case TANY, TFORW:
+		// will be defined later.
+		return ANOEQ, t
+
+	case TINT8, TUINT8, TINT16, TUINT16,
+		TINT32, TUINT32, TINT64, TUINT64,
+		TINT, TUINT, TUINTPTR,
+		TBOOL, TPTR,
+		TCHAN, TUNSAFEPTR:
+		return AMEM, nil
+
+	case TFUNC, TMAP:
+		return ANOEQ, t
+
+	case TFLOAT32:
+		return AFLOAT32, nil
+
+	case TFLOAT64:
+		return AFLOAT64, nil
+
+	case TCOMPLEX64:
+		return ACPLX64, nil
+
+	case TCOMPLEX128:
+		return ACPLX128, nil
+
+	case TSTRING:
+		return ASTRING, nil
+
+	case TINTER:
+		if t.IsEmptyInterface() {
+			return ANILINTER, nil
+		}
+		return AINTER, nil
+
+	case TSLICE:
+		return ANOEQ, t
+
+	case TARRAY:
+		a, bad := AlgType(t.Elem())
+		switch a {
+		case AMEM:
+			return AMEM, nil
+		case ANOEQ:
+			return ANOEQ, bad
+		}
+
+		switch t.NumElem() {
+		case 0:
+			// We checked above that the element type is comparable.
+			return AMEM, nil
+		case 1:
+			// Single-element array is same as its lone element.
+			return a, nil
+		}
+
+		return ASPECIAL, nil
+
+	case TSTRUCT:
+		fields := t.FieldSlice()
+
+		// One-field struct is same as that one field alone.
+		if len(fields) == 1 && !fields[0].Sym.IsBlank() {
+			return AlgType(fields[0].Type)
+		}
+
+		ret := AMEM
+		for i, f := range fields {
+			// All fields must be comparable.
+			a, bad := AlgType(f.Type)
+			if a == ANOEQ {
+				return ANOEQ, bad
+			}
+
+			// Blank fields, padded fields, fields with non-memory
+			// equality need special compare.
+			if a != AMEM || f.Sym.IsBlank() || IsPaddedField(t, i) {
+				ret = ASPECIAL
+			}
+		}
+
+		return ret, nil
+	}
+
+	base.Fatalf("AlgType: unexpected type %v", t)
+	return 0, nil
+}
+
+// TypeHasNoAlg reports whether t does not have any associated hash/eq
+// algorithms because t, or some component of t, is marked Noalg.
+func TypeHasNoAlg(t *Type) bool {
+	a, bad := AlgType(t)
+	return a == ANOEQ && bad.Noalg()
+}
+
+// IsComparable reports whether t is a comparable type.
+func IsComparable(t *Type) bool {
+	a, _ := AlgType(t)
+	return a != ANOEQ
+}
+
+// IncomparableField returns an incomparable Field of struct Type t, if any.
+func IncomparableField(t *Type) *Field {
+	for _, f := range t.FieldSlice() {
+		if !IsComparable(f.Type) {
+			return f
+		}
+	}
+	return nil
+}
+
+// IsPaddedField reports whether the i'th field of struct type t is followed
+// by padding.
+func IsPaddedField(t *Type, i int) bool {
+	if !t.IsStruct() {
+		base.Fatalf("IsPaddedField called non-struct %v", t)
+	}
+	end := t.Width
+	if i+1 < t.NumFields() {
+		end = t.Field(i + 1).Offset
+	}
+	return t.Field(i).End() != end
+}
diff --git a/src/cmd/compile/internal/types/algkind_string.go b/src/cmd/compile/internal/types/algkind_string.go
new file mode 100644
index 0000000..a1b518e
--- /dev/null
+++ b/src/cmd/compile/internal/types/algkind_string.go
@@ -0,0 +1,48 @@
+// Code generated by "stringer -type AlgKind -trimprefix A alg.go"; DO NOT EDIT.
+
+package types
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[ANOEQ-0]
+	_ = x[AMEM0-1]
+	_ = x[AMEM8-2]
+	_ = x[AMEM16-3]
+	_ = x[AMEM32-4]
+	_ = x[AMEM64-5]
+	_ = x[AMEM128-6]
+	_ = x[ASTRING-7]
+	_ = x[AINTER-8]
+	_ = x[ANILINTER-9]
+	_ = x[AFLOAT32-10]
+	_ = x[AFLOAT64-11]
+	_ = x[ACPLX64-12]
+	_ = x[ACPLX128-13]
+	_ = x[AMEM-100]
+	_ = x[ASPECIAL - -1]
+}
+
+const (
+	_AlgKind_name_0 = "SPECIALNOEQMEM0MEM8MEM16MEM32MEM64MEM128STRINGINTERNILINTERFLOAT32FLOAT64CPLX64CPLX128"
+	_AlgKind_name_1 = "MEM"
+)
+
+var (
+	_AlgKind_index_0 = [...]uint8{0, 7, 11, 15, 19, 24, 29, 34, 40, 46, 51, 59, 66, 73, 79, 86}
+)
+
+func (i AlgKind) String() string {
+	switch {
+	case -1 <= i && i <= 13:
+		i -= -1
+		return _AlgKind_name_0[_AlgKind_index_0[i]:_AlgKind_index_0[i+1]]
+	case i == 100:
+		return _AlgKind_name_1
+	default:
+		return "AlgKind(" + strconv.FormatInt(int64(i), 10) + ")"
+	}
+}
diff --git a/src/cmd/compile/internal/types/etype_string.go b/src/cmd/compile/internal/types/etype_string.go
deleted file mode 100644
index 14fd5b7..0000000
--- a/src/cmd/compile/internal/types/etype_string.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Code generated by "stringer -type EType -trimprefix T"; DO NOT EDIT.
-
-package types
-
-import "strconv"
-
-func _() {
-	// An "invalid array index" compiler error signifies that the constant values have changed.
-	// Re-run the stringer command to generate them again.
-	var x [1]struct{}
-	_ = x[Txxx-0]
-	_ = x[TINT8-1]
-	_ = x[TUINT8-2]
-	_ = x[TINT16-3]
-	_ = x[TUINT16-4]
-	_ = x[TINT32-5]
-	_ = x[TUINT32-6]
-	_ = x[TINT64-7]
-	_ = x[TUINT64-8]
-	_ = x[TINT-9]
-	_ = x[TUINT-10]
-	_ = x[TUINTPTR-11]
-	_ = x[TCOMPLEX64-12]
-	_ = x[TCOMPLEX128-13]
-	_ = x[TFLOAT32-14]
-	_ = x[TFLOAT64-15]
-	_ = x[TBOOL-16]
-	_ = x[TPTR-17]
-	_ = x[TFUNC-18]
-	_ = x[TSLICE-19]
-	_ = x[TARRAY-20]
-	_ = x[TSTRUCT-21]
-	_ = x[TCHAN-22]
-	_ = x[TMAP-23]
-	_ = x[TINTER-24]
-	_ = x[TFORW-25]
-	_ = x[TANY-26]
-	_ = x[TSTRING-27]
-	_ = x[TUNSAFEPTR-28]
-	_ = x[TIDEAL-29]
-	_ = x[TNIL-30]
-	_ = x[TBLANK-31]
-	_ = x[TFUNCARGS-32]
-	_ = x[TCHANARGS-33]
-	_ = x[TSSA-34]
-	_ = x[TTUPLE-35]
-	_ = x[TRESULTS-36]
-	_ = x[NTYPE-37]
-}
-
-const _EType_name = "xxxINT8UINT8INT16UINT16INT32UINT32INT64UINT64INTUINTUINTPTRCOMPLEX64COMPLEX128FLOAT32FLOAT64BOOLPTRFUNCSLICEARRAYSTRUCTCHANMAPINTERFORWANYSTRINGUNSAFEPTRIDEALNILBLANKFUNCARGSCHANARGSSSATUPLERESULTSNTYPE"
-
-var _EType_index = [...]uint8{0, 3, 7, 12, 17, 23, 28, 34, 39, 45, 48, 52, 59, 68, 78, 85, 92, 96, 99, 103, 108, 113, 119, 123, 126, 131, 135, 138, 144, 153, 158, 161, 166, 174, 182, 185, 190, 197, 202}
-
-func (i EType) String() string {
-	if i >= EType(len(_EType_index)-1) {
-		return "EType(" + strconv.FormatInt(int64(i), 10) + ")"
-	}
-	return _EType_name[_EType_index[i]:_EType_index[i+1]]
-}
diff --git a/src/cmd/compile/internal/types/fmt.go b/src/cmd/compile/internal/types/fmt.go
new file mode 100644
index 0000000..8b98895
--- /dev/null
+++ b/src/cmd/compile/internal/types/fmt.go
@@ -0,0 +1,679 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+	"bytes"
+	"crypto/md5"
+	"encoding/binary"
+	"fmt"
+	"go/constant"
+	"strconv"
+	"strings"
+	"sync"
+
+	"cmd/compile/internal/base"
+)
+
+// BuiltinPkg is a fake package that declares the universe block.
+var BuiltinPkg *Pkg
+
+// LocalPkg is the package being compiled.
+var LocalPkg *Pkg
+
+// BlankSym is the blank (_) symbol.
+var BlankSym *Sym
+
+// OrigSym returns the original symbol written by the user.
+func OrigSym(s *Sym) *Sym {
+	if s == nil {
+		return nil
+	}
+
+	if len(s.Name) > 1 && s.Name[0] == '~' {
+		switch s.Name[1] {
+		case 'r': // originally an unnamed result
+			return nil
+		case 'b': // originally the blank identifier _
+			// TODO(mdempsky): Does s.Pkg matter here?
+			return BlankSym
+		}
+		return s
+	}
+
+	if strings.HasPrefix(s.Name, ".anon") {
+		// originally an unnamed or _ name (see subr.go: NewFuncParams)
+		return nil
+	}
+
+	return s
+}
+
+// numImport tracks how often a package with a given name is imported.
+// It is used to provide a better error message (by using the package
+// path to disambiguate) if a package that appears multiple times with
+// the same name appears in an error message.
+var NumImport = make(map[string]int)
+
+// fmtMode represents the kind of printing being done.
+// The default is regular Go syntax (fmtGo).
+// fmtDebug is like fmtGo but for debugging dumps and prints the type kind too.
+// fmtTypeID and fmtTypeIDName are for generating various unique representations
+// of types used in hashes and the linker.
+type fmtMode int
+
+const (
+	fmtGo fmtMode = iota
+	fmtDebug
+	fmtTypeID
+	fmtTypeIDName
+)
+
+// Sym
+
+// Format implements formatting for a Sym.
+// The valid formats are:
+//
+//	%v	Go syntax: Name for symbols in the local package, PkgName.Name for imported symbols.
+//	%+v	Debug syntax: always include PkgName. prefix even for local names.
+//	%S	Short syntax: Name only, no matter what.
+//
+func (s *Sym) Format(f fmt.State, verb rune) {
+	mode := fmtGo
+	switch verb {
+	case 'v', 'S':
+		if verb == 'v' && f.Flag('+') {
+			mode = fmtDebug
+		}
+		fmt.Fprint(f, sconv(s, verb, mode))
+
+	default:
+		fmt.Fprintf(f, "%%!%c(*types.Sym=%p)", verb, s)
+	}
+}
+
+func (s *Sym) String() string {
+	return sconv(s, 0, fmtGo)
+}
+
+// See #16897 for details about performance implications
+// before changing the implementation of sconv.
+func sconv(s *Sym, verb rune, mode fmtMode) string {
+	if verb == 'L' {
+		panic("linksymfmt")
+	}
+
+	if s == nil {
+		return "<S>"
+	}
+
+	q := pkgqual(s.Pkg, verb, mode)
+	if q == "" {
+		return s.Name
+	}
+
+	buf := fmtBufferPool.Get().(*bytes.Buffer)
+	buf.Reset()
+	defer fmtBufferPool.Put(buf)
+
+	buf.WriteString(q)
+	buf.WriteByte('.')
+	buf.WriteString(s.Name)
+	return InternString(buf.Bytes())
+}
+
+func sconv2(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) {
+	if verb == 'L' {
+		panic("linksymfmt")
+	}
+	if s == nil {
+		b.WriteString("<S>")
+		return
+	}
+
+	symfmt(b, s, verb, mode)
+}
+
+func symfmt(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) {
+	if q := pkgqual(s.Pkg, verb, mode); q != "" {
+		b.WriteString(q)
+		b.WriteByte('.')
+	}
+	b.WriteString(s.Name)
+}
+
+// pkgqual returns the qualifier that should be used for printing
+// symbols from the given package in the given mode.
+// If it returns the empty string, no qualification is needed.
+func pkgqual(pkg *Pkg, verb rune, mode fmtMode) string {
+	if verb != 'S' {
+		switch mode {
+		case fmtGo: // This is for the user
+			if pkg == BuiltinPkg || pkg == LocalPkg {
+				return ""
+			}
+
+			// If the name was used by multiple packages, display the full path,
+			if pkg.Name != "" && NumImport[pkg.Name] > 1 {
+				return strconv.Quote(pkg.Path)
+			}
+			return pkg.Name
+
+		case fmtDebug:
+			return pkg.Name
+
+		case fmtTypeIDName:
+			// dcommontype, typehash
+			return pkg.Name
+
+		case fmtTypeID:
+			// (methodsym), typesym, weaksym
+			return pkg.Prefix
+		}
+	}
+
+	return ""
+}
+
+// Type
+
+var BasicTypeNames = []string{
+	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",
+	TANY:        "any",
+	TSTRING:     "string",
+	TNIL:        "nil",
+	TIDEAL:      "untyped number",
+	TBLANK:      "blank",
+}
+
+var fmtBufferPool = sync.Pool{
+	New: func() interface{} {
+		return new(bytes.Buffer)
+	},
+}
+
+// Format implements formatting for a Type.
+// The valid formats are:
+//
+//	%v	Go syntax
+//	%+v	Debug syntax: Go syntax with a KIND- prefix for all but builtins.
+//	%L	Go syntax for underlying type if t is named
+//	%S	short Go syntax: drop leading "func" in function type
+//	%-S	special case for method receiver symbol
+//
+func (t *Type) Format(s fmt.State, verb rune) {
+	mode := fmtGo
+	switch verb {
+	case 'v', 'S', 'L':
+		if verb == 'v' && s.Flag('+') { // %+v is debug format
+			mode = fmtDebug
+		}
+		if verb == 'S' && s.Flag('-') { // %-S is special case for receiver - short typeid format
+			mode = fmtTypeID
+		}
+		fmt.Fprint(s, tconv(t, verb, mode))
+	default:
+		fmt.Fprintf(s, "%%!%c(*Type=%p)", verb, t)
+	}
+}
+
+// String returns the Go syntax for the type t.
+func (t *Type) String() string {
+	return tconv(t, 0, fmtGo)
+}
+
+// ShortString generates a short description of t.
+// It is used in autogenerated method names, reflection,
+// and itab names.
+func (t *Type) ShortString() string {
+	return tconv(t, 0, fmtTypeID)
+}
+
+// LongString generates a complete description of t.
+// It is useful for reflection,
+// or when a unique fingerprint or hash of a type is required.
+func (t *Type) LongString() string {
+	return tconv(t, 0, fmtTypeIDName)
+}
+
+func tconv(t *Type, verb rune, mode fmtMode) string {
+	buf := fmtBufferPool.Get().(*bytes.Buffer)
+	buf.Reset()
+	defer fmtBufferPool.Put(buf)
+
+	tconv2(buf, t, verb, mode, nil)
+	return InternString(buf.Bytes())
+}
+
+// tconv2 writes a string representation of t to b.
+// flag and mode control exactly what is printed.
+// Any types x that are already in the visited map get printed as @%d where %d=visited[x].
+// See #16897 before changing the implementation of tconv.
+func tconv2(b *bytes.Buffer, t *Type, verb rune, mode fmtMode, visited map[*Type]int) {
+	if off, ok := visited[t]; ok {
+		// We've seen this type before, so we're trying to print it recursively.
+		// Print a reference to it instead.
+		fmt.Fprintf(b, "@%d", off)
+		return
+	}
+	if t == nil {
+		b.WriteString("<T>")
+		return
+	}
+	if t.Kind() == TSSA {
+		b.WriteString(t.Extra.(string))
+		return
+	}
+	if t.Kind() == TTUPLE {
+		b.WriteString(t.FieldType(0).String())
+		b.WriteByte(',')
+		b.WriteString(t.FieldType(1).String())
+		return
+	}
+
+	if t.Kind() == TRESULTS {
+		tys := t.Extra.(*Results).Types
+		for i, et := range tys {
+			if i > 0 {
+				b.WriteByte(',')
+			}
+			b.WriteString(et.String())
+		}
+		return
+	}
+
+	if t == ByteType || t == RuneType {
+		// in %-T mode collapse rune and byte with their originals.
+		switch mode {
+		case fmtTypeIDName, fmtTypeID:
+			t = Types[t.Kind()]
+		default:
+			sconv2(b, t.Sym(), 'S', mode)
+			return
+		}
+	}
+	if t == ErrorType {
+		b.WriteString("error")
+		return
+	}
+
+	// Unless the 'L' flag was specified, if the type has a name, just print that name.
+	if verb != 'L' && t.Sym() != nil && t != Types[t.Kind()] {
+		switch mode {
+		case fmtTypeID, fmtTypeIDName:
+			if verb == 'S' {
+				if t.Vargen != 0 {
+					sconv2(b, t.Sym(), 'S', mode)
+					fmt.Fprintf(b, "·%d", t.Vargen)
+					return
+				}
+				sconv2(b, t.Sym(), 'S', mode)
+				return
+			}
+
+			if mode == fmtTypeIDName {
+				sconv2(b, t.Sym(), 'v', fmtTypeIDName)
+				return
+			}
+
+			if t.Sym().Pkg == LocalPkg && t.Vargen != 0 {
+				sconv2(b, t.Sym(), 'v', mode)
+				fmt.Fprintf(b, "·%d", t.Vargen)
+				return
+			}
+		}
+
+		sconv2(b, t.Sym(), 'v', mode)
+		return
+	}
+
+	if int(t.Kind()) < len(BasicTypeNames) && BasicTypeNames[t.Kind()] != "" {
+		var name string
+		switch t {
+		case UntypedBool:
+			name = "untyped bool"
+		case UntypedString:
+			name = "untyped string"
+		case UntypedInt:
+			name = "untyped int"
+		case UntypedRune:
+			name = "untyped rune"
+		case UntypedFloat:
+			name = "untyped float"
+		case UntypedComplex:
+			name = "untyped complex"
+		default:
+			name = BasicTypeNames[t.Kind()]
+		}
+		b.WriteString(name)
+		return
+	}
+
+	if mode == fmtDebug {
+		b.WriteString(t.Kind().String())
+		b.WriteByte('-')
+		tconv2(b, t, 'v', fmtGo, visited)
+		return
+	}
+
+	// At this point, we might call tconv2 recursively. Add the current type to the visited list so we don't
+	// try to print it recursively.
+	// We record the offset in the result buffer where the type's text starts. This offset serves as a reference
+	// point for any later references to the same type.
+	// Note that we remove the type from the visited map as soon as the recursive call is done.
+	// This prevents encoding types like map[*int]*int as map[*int]@4. (That encoding would work,
+	// but I'd like to use the @ notation only when strictly necessary.)
+	if visited == nil {
+		visited = map[*Type]int{}
+	}
+	visited[t] = b.Len()
+	defer delete(visited, t)
+
+	switch t.Kind() {
+	case TPTR:
+		b.WriteByte('*')
+		switch mode {
+		case fmtTypeID, fmtTypeIDName:
+			if verb == 'S' {
+				tconv2(b, t.Elem(), 'S', mode, visited)
+				return
+			}
+		}
+		tconv2(b, t.Elem(), 'v', mode, visited)
+
+	case TARRAY:
+		b.WriteByte('[')
+		b.WriteString(strconv.FormatInt(t.NumElem(), 10))
+		b.WriteByte(']')
+		tconv2(b, t.Elem(), 0, mode, visited)
+
+	case TSLICE:
+		b.WriteString("[]")
+		tconv2(b, t.Elem(), 0, mode, visited)
+
+	case TCHAN:
+		switch t.ChanDir() {
+		case Crecv:
+			b.WriteString("<-chan ")
+			tconv2(b, t.Elem(), 0, mode, visited)
+		case Csend:
+			b.WriteString("chan<- ")
+			tconv2(b, t.Elem(), 0, mode, visited)
+		default:
+			b.WriteString("chan ")
+			if t.Elem() != nil && t.Elem().IsChan() && t.Elem().Sym() == nil && t.Elem().ChanDir() == Crecv {
+				b.WriteByte('(')
+				tconv2(b, t.Elem(), 0, mode, visited)
+				b.WriteByte(')')
+			} else {
+				tconv2(b, t.Elem(), 0, mode, visited)
+			}
+		}
+
+	case TMAP:
+		b.WriteString("map[")
+		tconv2(b, t.Key(), 0, mode, visited)
+		b.WriteByte(']')
+		tconv2(b, t.Elem(), 0, mode, visited)
+
+	case TINTER:
+		if t.IsEmptyInterface() {
+			b.WriteString("interface {}")
+			break
+		}
+		b.WriteString("interface {")
+		for i, f := range t.AllMethods().Slice() {
+			if i != 0 {
+				b.WriteByte(';')
+			}
+			b.WriteByte(' ')
+			switch {
+			case f.Sym == nil:
+				// Check first that a symbol is defined for this type.
+				// Wrong interface definitions may have types lacking a symbol.
+				break
+			case IsExported(f.Sym.Name):
+				sconv2(b, f.Sym, 'S', mode)
+			default:
+				if mode != fmtTypeIDName {
+					mode = fmtTypeID
+				}
+				sconv2(b, f.Sym, 'v', mode)
+			}
+			tconv2(b, f.Type, 'S', mode, visited)
+		}
+		if t.AllMethods().Len() != 0 {
+			b.WriteByte(' ')
+		}
+		b.WriteByte('}')
+
+	case TFUNC:
+		if verb == 'S' {
+			// no leading func
+		} else {
+			if t.Recv() != nil {
+				b.WriteString("method")
+				tconv2(b, t.Recvs(), 0, mode, visited)
+				b.WriteByte(' ')
+			}
+			b.WriteString("func")
+		}
+		if t.NumTParams() > 0 {
+			tconv2(b, t.TParams(), 0, mode, visited)
+		}
+		tconv2(b, t.Params(), 0, mode, visited)
+
+		switch t.NumResults() {
+		case 0:
+			// nothing to do
+
+		case 1:
+			b.WriteByte(' ')
+			tconv2(b, t.Results().Field(0).Type, 0, mode, visited) // struct->field->field's type
+
+		default:
+			b.WriteByte(' ')
+			tconv2(b, t.Results(), 0, mode, visited)
+		}
+
+	case TSTRUCT:
+		if m := t.StructType().Map; m != nil {
+			mt := m.MapType()
+			// Format the bucket struct for map[x]y as map.bucket[x]y.
+			// This avoids a recursive print that generates very long names.
+			switch t {
+			case mt.Bucket:
+				b.WriteString("map.bucket[")
+			case mt.Hmap:
+				b.WriteString("map.hdr[")
+			case mt.Hiter:
+				b.WriteString("map.iter[")
+			default:
+				base.Fatalf("unknown internal map type")
+			}
+			tconv2(b, m.Key(), 0, mode, visited)
+			b.WriteByte(']')
+			tconv2(b, m.Elem(), 0, mode, visited)
+			break
+		}
+
+		if funarg := t.StructType().Funarg; funarg != FunargNone {
+			open, close := '(', ')'
+			if funarg == FunargTparams {
+				open, close = '[', ']'
+			}
+			b.WriteByte(byte(open))
+			fieldVerb := 'v'
+			switch mode {
+			case fmtTypeID, fmtTypeIDName, fmtGo:
+				// no argument names on function signature, and no "noescape"/"nosplit" tags
+				fieldVerb = 'S'
+			}
+			for i, f := range t.Fields().Slice() {
+				if i != 0 {
+					b.WriteString(", ")
+				}
+				fldconv(b, f, fieldVerb, mode, visited, funarg)
+			}
+			b.WriteByte(byte(close))
+		} else {
+			b.WriteString("struct {")
+			for i, f := range t.Fields().Slice() {
+				if i != 0 {
+					b.WriteByte(';')
+				}
+				b.WriteByte(' ')
+				fldconv(b, f, 'L', mode, visited, funarg)
+			}
+			if t.NumFields() != 0 {
+				b.WriteByte(' ')
+			}
+			b.WriteByte('}')
+		}
+
+	case TFORW:
+		b.WriteString("undefined")
+		if t.Sym() != nil {
+			b.WriteByte(' ')
+			sconv2(b, t.Sym(), 'v', mode)
+		}
+
+	case TUNSAFEPTR:
+		b.WriteString("unsafe.Pointer")
+
+	case TTYPEPARAM:
+		if t.Sym() != nil {
+			sconv2(b, t.Sym(), 'v', mode)
+		} else {
+			b.WriteString("tp")
+			// Print out the pointer value for now to disambiguate type params
+			b.WriteString(fmt.Sprintf("%p", t))
+		}
+
+	case Txxx:
+		b.WriteString("Txxx")
+
+	default:
+		// Don't know how to handle - fall back to detailed prints
+		b.WriteString(t.Kind().String())
+		b.WriteString(" <")
+		sconv2(b, t.Sym(), 'v', mode)
+		b.WriteString(">")
+
+	}
+}
+
+func fldconv(b *bytes.Buffer, f *Field, verb rune, mode fmtMode, visited map[*Type]int, funarg Funarg) {
+	if f == nil {
+		b.WriteString("<T>")
+		return
+	}
+
+	var name string
+	if verb != 'S' {
+		s := f.Sym
+
+		// Take the name from the original.
+		if mode == fmtGo {
+			s = OrigSym(s)
+		}
+
+		if s != nil && f.Embedded == 0 {
+			if funarg != FunargNone {
+				name = fmt.Sprint(f.Nname)
+			} else if verb == 'L' {
+				name = s.Name
+				if name == ".F" {
+					name = "F" // Hack for toolstash -cmp.
+				}
+				if !IsExported(name) && mode != fmtTypeIDName {
+					name = sconv(s, 0, mode) // qualify non-exported names (used on structs, not on funarg)
+				}
+			} else {
+				name = sconv(s, 0, mode)
+			}
+		}
+	}
+
+	if name != "" {
+		b.WriteString(name)
+		b.WriteString(" ")
+	}
+
+	if f.IsDDD() {
+		var et *Type
+		if f.Type != nil {
+			et = f.Type.Elem()
+		}
+		b.WriteString("...")
+		tconv2(b, et, 0, mode, visited)
+	} else {
+		tconv2(b, f.Type, 0, mode, visited)
+	}
+
+	if verb != 'S' && funarg == FunargNone && f.Note != "" {
+		b.WriteString(" ")
+		b.WriteString(strconv.Quote(f.Note))
+	}
+}
+
+// Val
+
+func FmtConst(v constant.Value, sharp bool) string {
+	if !sharp && v.Kind() == constant.Complex {
+		real, imag := constant.Real(v), constant.Imag(v)
+
+		var re string
+		sre := constant.Sign(real)
+		if sre != 0 {
+			re = real.String()
+		}
+
+		var im string
+		sim := constant.Sign(imag)
+		if sim != 0 {
+			im = imag.String()
+		}
+
+		switch {
+		case sre == 0 && sim == 0:
+			return "0"
+		case sre == 0:
+			return im + "i"
+		case sim == 0:
+			return re
+		case sim < 0:
+			return fmt.Sprintf("(%s%si)", re, im)
+		default:
+			return fmt.Sprintf("(%s+%si)", re, im)
+		}
+	}
+
+	return v.String()
+}
+
+// TypeHash computes a hash value for type t to use in type switch statements.
+func TypeHash(t *Type) uint32 {
+	p := t.LongString()
+
+	// Using MD5 is overkill, but reduces accidental collisions.
+	h := md5.Sum([]byte(p))
+	return binary.LittleEndian.Uint32(h[:4])
+}
diff --git a/src/cmd/compile/internal/types/goversion.go b/src/cmd/compile/internal/types/goversion.go
new file mode 100644
index 0000000..1a324aa
--- /dev/null
+++ b/src/cmd/compile/internal/types/goversion.go
@@ -0,0 +1,94 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+	"fmt"
+	"internal/goversion"
+	"log"
+	"regexp"
+	"strconv"
+
+	"cmd/compile/internal/base"
+)
+
+// A lang is a language version broken into major and minor numbers.
+type lang struct {
+	major, minor int
+}
+
+// langWant is the desired language version set by the -lang flag.
+// If the -lang flag is not set, this is the zero value, meaning that
+// any language version is supported.
+var langWant lang
+
+// AllowsGoVersion reports whether a particular package
+// is allowed to use Go version major.minor.
+// We assume the imported packages have all been checked,
+// so we only have to check the local package against the -lang flag.
+func AllowsGoVersion(pkg *Pkg, major, minor int) bool {
+	if pkg == nil {
+		// TODO(mdempsky): Set Pkg for local types earlier.
+		pkg = LocalPkg
+	}
+	if pkg != LocalPkg {
+		// Assume imported packages passed type-checking.
+		return true
+	}
+	if langWant.major == 0 && langWant.minor == 0 {
+		return true
+	}
+	return langWant.major > major || (langWant.major == major && langWant.minor >= minor)
+}
+
+// ParseLangFlag verifies that the -lang flag holds a valid value, and
+// exits if not. It initializes data used by langSupported.
+func ParseLangFlag() {
+	if base.Flag.Lang == "" {
+		return
+	}
+
+	var err error
+	langWant, err = parseLang(base.Flag.Lang)
+	if err != nil {
+		log.Fatalf("invalid value %q for -lang: %v", base.Flag.Lang, err)
+	}
+
+	if def := currentLang(); base.Flag.Lang != def {
+		defVers, err := parseLang(def)
+		if err != nil {
+			log.Fatalf("internal error parsing default lang %q: %v", def, err)
+		}
+		if langWant.major > defVers.major || (langWant.major == defVers.major && langWant.minor > defVers.minor) {
+			log.Fatalf("invalid value %q for -lang: max known version is %q", base.Flag.Lang, def)
+		}
+	}
+}
+
+// parseLang parses a -lang option into a langVer.
+func parseLang(s string) (lang, error) {
+	matches := goVersionRE.FindStringSubmatch(s)
+	if matches == nil {
+		return lang{}, fmt.Errorf(`should be something like "go1.12"`)
+	}
+	major, err := strconv.Atoi(matches[1])
+	if err != nil {
+		return lang{}, err
+	}
+	minor, err := strconv.Atoi(matches[2])
+	if err != nil {
+		return lang{}, err
+	}
+	return lang{major: major, minor: minor}, nil
+}
+
+// currentLang returns the current language version.
+func currentLang() string {
+	return fmt.Sprintf("go1.%d", goversion.Version)
+}
+
+// goVersionRE is a regular expression that matches the valid
+// arguments to the -lang flag.
+var goVersionRE = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
diff --git a/src/cmd/compile/internal/types/identity.go b/src/cmd/compile/internal/types/identity.go
index a77f514..dde9f51 100644
--- a/src/cmd/compile/internal/types/identity.go
+++ b/src/cmd/compile/internal/types/identity.go
@@ -25,17 +25,17 @@
 	if t1 == t2 {
 		return true
 	}
-	if t1 == nil || t2 == nil || t1.Etype != t2.Etype || t1.Broke() || t2.Broke() {
+	if t1 == nil || t2 == nil || t1.kind != t2.kind || t1.Broke() || t2.Broke() {
 		return false
 	}
-	if t1.Sym != nil || t2.Sym != nil {
+	if t1.sym != nil || t2.sym != nil {
 		// Special case: we keep byte/uint8 and rune/int32
 		// separate for error messages. Treat them as equal.
-		switch t1.Etype {
+		switch t1.kind {
 		case TUINT8:
-			return (t1 == Types[TUINT8] || t1 == Bytetype) && (t2 == Types[TUINT8] || t2 == Bytetype)
+			return (t1 == Types[TUINT8] || t1 == ByteType) && (t2 == Types[TUINT8] || t2 == ByteType)
 		case TINT32:
-			return (t1 == Types[TINT32] || t1 == Runetype) && (t2 == Types[TINT32] || t2 == Runetype)
+			return (t1 == Types[TINT32] || t1 == RuneType) && (t2 == Types[TINT32] || t2 == RuneType)
 		default:
 			return false
 		}
@@ -52,7 +52,7 @@
 	}
 	assumedEqual[typePair{t1, t2}] = struct{}{}
 
-	switch t1.Etype {
+	switch t1.kind {
 	case TIDEAL:
 		// Historically, cmd/compile used a single "untyped
 		// number" type, so all untyped number types were
@@ -61,11 +61,11 @@
 		return true
 
 	case TINTER:
-		if t1.NumFields() != t2.NumFields() {
+		if t1.AllMethods().Len() != t2.AllMethods().Len() {
 			return false
 		}
-		for i, f1 := range t1.FieldSlice() {
-			f2 := t2.Field(i)
+		for i, f1 := range t1.AllMethods().Slice() {
+			f2 := t2.AllMethods().Index(i)
 			if f1.Sym != f2.Sym || !identical(f1.Type, f2.Type, cmpTags, assumedEqual) {
 				return false
 			}
diff --git a/src/cmd/compile/internal/types/kind_string.go b/src/cmd/compile/internal/types/kind_string.go
new file mode 100644
index 0000000..ae24a58
--- /dev/null
+++ b/src/cmd/compile/internal/types/kind_string.go
@@ -0,0 +1,61 @@
+// Code generated by "stringer -type Kind -trimprefix T type.go"; DO NOT EDIT.
+
+package types
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[Txxx-0]
+	_ = x[TINT8-1]
+	_ = x[TUINT8-2]
+	_ = x[TINT16-3]
+	_ = x[TUINT16-4]
+	_ = x[TINT32-5]
+	_ = x[TUINT32-6]
+	_ = x[TINT64-7]
+	_ = x[TUINT64-8]
+	_ = x[TINT-9]
+	_ = x[TUINT-10]
+	_ = x[TUINTPTR-11]
+	_ = x[TCOMPLEX64-12]
+	_ = x[TCOMPLEX128-13]
+	_ = x[TFLOAT32-14]
+	_ = x[TFLOAT64-15]
+	_ = x[TBOOL-16]
+	_ = x[TPTR-17]
+	_ = x[TFUNC-18]
+	_ = x[TSLICE-19]
+	_ = x[TARRAY-20]
+	_ = x[TSTRUCT-21]
+	_ = x[TCHAN-22]
+	_ = x[TMAP-23]
+	_ = x[TINTER-24]
+	_ = x[TFORW-25]
+	_ = x[TANY-26]
+	_ = x[TSTRING-27]
+	_ = x[TUNSAFEPTR-28]
+	_ = x[TTYPEPARAM-29]
+	_ = x[TIDEAL-30]
+	_ = x[TNIL-31]
+	_ = x[TBLANK-32]
+	_ = x[TFUNCARGS-33]
+	_ = x[TCHANARGS-34]
+	_ = x[TSSA-35]
+	_ = x[TTUPLE-36]
+	_ = x[TRESULTS-37]
+	_ = x[NTYPE-38]
+}
+
+const _Kind_name = "xxxINT8UINT8INT16UINT16INT32UINT32INT64UINT64INTUINTUINTPTRCOMPLEX64COMPLEX128FLOAT32FLOAT64BOOLPTRFUNCSLICEARRAYSTRUCTCHANMAPINTERFORWANYSTRINGUNSAFEPTRTYPEPARAMIDEALNILBLANKFUNCARGSCHANARGSSSATUPLERESULTSNTYPE"
+
+var _Kind_index = [...]uint8{0, 3, 7, 12, 17, 23, 28, 34, 39, 45, 48, 52, 59, 68, 78, 85, 92, 96, 99, 103, 108, 113, 119, 123, 126, 131, 135, 138, 144, 153, 162, 167, 170, 175, 183, 191, 194, 199, 206, 211}
+
+func (i Kind) String() string {
+	if i >= Kind(len(_Kind_index)-1) {
+		return "Kind(" + strconv.FormatInt(int64(i), 10) + ")"
+	}
+	return _Kind_name[_Kind_index[i]:_Kind_index[i+1]]
+}
diff --git a/src/cmd/compile/internal/types/pkg.go b/src/cmd/compile/internal/types/pkg.go
index bcc6789..a6d2e20 100644
--- a/src/cmd/compile/internal/types/pkg.go
+++ b/src/cmd/compile/internal/types/pkg.go
@@ -31,8 +31,7 @@
 	// height of their imported packages.
 	Height int
 
-	Imported bool // export data of this package was parsed
-	Direct   bool // imported directly
+	Direct bool // imported directly
 }
 
 // NewPkg returns a new Pkg for the given package path and name.
@@ -84,9 +83,6 @@
 	return s
 }
 
-// List of .inittask entries in imported packages, in source code order.
-var InitSyms []*Sym
-
 // LookupOK looks up name in pkg and reports whether it previously existed.
 func (pkg *Pkg) LookupOK(name string) (s *Sym, existed bool) {
 	// TODO(gri) remove this check in favor of specialized lookup
@@ -101,9 +97,6 @@
 		Name: name,
 		Pkg:  pkg,
 	}
-	if name == ".inittask" {
-		InitSyms = append(InitSyms, s)
-	}
 	pkg.Syms[name] = s
 	return s, false
 }
@@ -144,3 +137,7 @@
 	f()
 	pkgMap = saved
 }
+
+func IsDotAlias(sym *Sym) bool {
+	return sym.Def != nil && sym.Def.Sym() != sym
+}
diff --git a/src/cmd/compile/internal/types/scope.go b/src/cmd/compile/internal/types/scope.go
index 40d3d86..d7c454f 100644
--- a/src/cmd/compile/internal/types/scope.go
+++ b/src/cmd/compile/internal/types/scope.go
@@ -4,18 +4,21 @@
 
 package types
 
-import "cmd/internal/src"
+import (
+	"cmd/compile/internal/base"
+	"cmd/internal/src"
+)
 
 // Declaration stack & operations
 
 var blockgen int32 = 1 // max block number
-var Block int32        // current block number
+var Block int32 = 1    // 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
+	def        Object
 	block      int32
 	lastlineno src.XPos // last declaration for diagnostic
 }
@@ -56,7 +59,7 @@
 		d.sym = nil
 		d.def = nil
 	}
-	Fatalf("popdcl: no stack mark")
+	base.Fatalf("popdcl: no stack mark")
 }
 
 // Markdcl records the start of a new block scope for declarations.
@@ -69,7 +72,7 @@
 	Block = blockgen
 }
 
-func IsDclstackValid() bool {
+func isDclstackValid() bool {
 	for _, d := range dclstack {
 		if d.sym == nil {
 			return false
@@ -79,19 +82,20 @@
 }
 
 // PkgDef returns the definition associated with s at package scope.
-func (s *Sym) PkgDef() *Node {
+func (s *Sym) PkgDef() Object {
 	return *s.pkgDefPtr()
 }
 
 // SetPkgDef sets the definition associated with s at package scope.
-func (s *Sym) SetPkgDef(n *Node) {
+func (s *Sym) SetPkgDef(n Object) {
 	*s.pkgDefPtr() = n
 }
 
-func (s *Sym) pkgDefPtr() **Node {
+func (s *Sym) pkgDefPtr() *Object {
 	// Look for outermost saved declaration, which must be the
 	// package scope definition, if present.
-	for _, d := range dclstack {
+	for i := range dclstack {
+		d := &dclstack[i]
 		if s == d.sym {
 			return &d.def
 		}
@@ -101,3 +105,9 @@
 	// function scope.
 	return &s.Def
 }
+
+func CheckDclstack() {
+	if !isDclstackValid() {
+		base.Fatalf("mark left on the dclstack")
+	}
+}
diff --git a/src/cmd/compile/internal/types/size.go b/src/cmd/compile/internal/types/size.go
new file mode 100644
index 0000000..f0e695a
--- /dev/null
+++ b/src/cmd/compile/internal/types/size.go
@@ -0,0 +1,632 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+	"bytes"
+	"fmt"
+	"sort"
+
+	"cmd/compile/internal/base"
+	"cmd/internal/src"
+)
+
+var PtrSize int
+
+var RegSize int
+
+// Slices in the runtime are represented by three components:
+//
+// type slice struct {
+// 	ptr unsafe.Pointer
+// 	len int
+// 	cap int
+// }
+//
+// Strings in the runtime are represented by two components:
+//
+// type string struct {
+// 	ptr unsafe.Pointer
+// 	len int
+// }
+//
+// These variables are the offsets of fields and sizes of these structs.
+var (
+	SlicePtrOffset int64
+	SliceLenOffset int64
+	SliceCapOffset int64
+
+	SliceSize  int64
+	StringSize int64
+)
+
+var SkipSizeForTracing bool
+
+// typePos returns the position associated with t.
+// This is where t was declared or where it appeared as a type expression.
+func typePos(t *Type) src.XPos {
+	if pos := t.Pos(); pos.IsKnown() {
+		return pos
+	}
+	base.Fatalf("bad type: %v", t)
+	panic("unreachable")
+}
+
+// MaxWidth is the maximum size of a value on the target architecture.
+var MaxWidth int64
+
+// CalcSizeDisabled indicates whether it is safe
+// to calculate Types' widths and alignments. See CalcSize.
+var CalcSizeDisabled bool
+
+// machine size and rounding alignment is dictated around
+// the size of a pointer, set in betypeinit (see ../amd64/galign.go).
+var defercalc int
+
+func Rnd(o int64, r int64) int64 {
+	if r < 1 || r > 8 || r&(r-1) != 0 {
+		base.Fatalf("rnd %d", r)
+	}
+	return (o + r - 1) &^ (r - 1)
+}
+
+// expandiface computes the method set for interface type t by
+// expanding embedded interfaces.
+func expandiface(t *Type) {
+	seen := make(map[*Sym]*Field)
+	var methods []*Field
+
+	addMethod := func(m *Field, explicit bool) {
+		switch prev := seen[m.Sym]; {
+		case prev == nil:
+			seen[m.Sym] = m
+		case AllowsGoVersion(t.Pkg(), 1, 14) && !explicit && Identical(m.Type, prev.Type):
+			return
+		default:
+			base.ErrorfAt(m.Pos, "duplicate method %s", m.Sym.Name)
+		}
+		methods = append(methods, m)
+	}
+
+	for _, m := range t.Methods().Slice() {
+		if m.Sym == nil {
+			continue
+		}
+
+		CheckSize(m.Type)
+		addMethod(m, true)
+	}
+
+	for _, m := range t.Methods().Slice() {
+		if m.Sym != nil || m.Type == nil {
+			continue
+		}
+
+		if !m.Type.IsInterface() {
+			base.ErrorfAt(m.Pos, "interface contains embedded non-interface %v", m.Type)
+			m.SetBroke(true)
+			t.SetBroke(true)
+			// Add to fields so that error messages
+			// include the broken embedded type when
+			// printing t.
+			// TODO(mdempsky): Revisit this.
+			methods = append(methods, m)
+			continue
+		}
+
+		// Embedded interface: duplicate all methods
+		// (including broken ones, if any) and add to t's
+		// method set.
+		for _, t1 := range m.Type.AllMethods().Slice() {
+			// Use m.Pos rather than t1.Pos to preserve embedding position.
+			f := NewField(m.Pos, t1.Sym, t1.Type)
+			addMethod(f, false)
+		}
+	}
+
+	sort.Sort(MethodsByName(methods))
+
+	if int64(len(methods)) >= MaxWidth/int64(PtrSize) {
+		base.ErrorfAt(typePos(t), "interface too large")
+	}
+	for i, m := range methods {
+		m.Offset = int64(i) * int64(PtrSize)
+	}
+
+	t.SetAllMethods(methods)
+}
+
+func calcStructOffset(errtype *Type, t *Type, o int64, flag int) int64 {
+	// flag is 0 (receiver), 1 (actual struct), or RegSize (in/out parameters)
+	isStruct := flag == 1
+	starto := o
+	maxalign := int32(flag)
+	if maxalign < 1 {
+		maxalign = 1
+	}
+	lastzero := int64(0)
+	for _, f := range t.Fields().Slice() {
+		if f.Type == nil {
+			// broken field, just skip it so that other valid fields
+			// get a width.
+			continue
+		}
+
+		CalcSize(f.Type)
+		if int32(f.Type.Align) > maxalign {
+			maxalign = int32(f.Type.Align)
+		}
+		if f.Type.Align > 0 {
+			o = Rnd(o, int64(f.Type.Align))
+		}
+		if isStruct { // For receiver/args/results, do not set, it depends on ABI
+			f.Offset = o
+		}
+
+		w := f.Type.Width
+		if w < 0 {
+			base.Fatalf("invalid width %d", f.Type.Width)
+		}
+		if w == 0 {
+			lastzero = o
+		}
+		o += w
+		maxwidth := MaxWidth
+		// On 32-bit systems, reflect tables impose an additional constraint
+		// that each field start offset must fit in 31 bits.
+		if maxwidth < 1<<32 {
+			maxwidth = 1<<31 - 1
+		}
+		if o >= maxwidth {
+			base.ErrorfAt(typePos(errtype), "type %L too large", errtype)
+			o = 8 // small but nonzero
+		}
+	}
+
+	// For nonzero-sized structs which end in a zero-sized thing, we add
+	// an extra byte of padding to the type. This padding ensures that
+	// taking the address of the zero-sized thing can't manufacture a
+	// pointer to the next object in the heap. See issue 9401.
+	if flag == 1 && o > starto && o == lastzero {
+		o++
+	}
+
+	// final width is rounded
+	if flag != 0 {
+		o = Rnd(o, int64(maxalign))
+	}
+	t.Align = uint8(maxalign)
+
+	// type width only includes back to first field's offset
+	t.Width = o - starto
+
+	return o
+}
+
+// findTypeLoop searches for an invalid type declaration loop involving
+// type t and reports whether one is found. If so, path contains the
+// loop.
+//
+// path points to a slice used for tracking the sequence of types
+// visited. Using a pointer to a slice allows the slice capacity to
+// grow and limit reallocations.
+func findTypeLoop(t *Type, path *[]*Type) bool {
+	// We implement a simple DFS loop-finding algorithm. This
+	// could be faster, but type cycles are rare.
+
+	if t.Sym() != nil {
+		// Declared type. Check for loops and otherwise
+		// recurse on the type expression used in the type
+		// declaration.
+
+		// Type imported from package, so it can't be part of
+		// a type loop (otherwise that package should have
+		// failed to compile).
+		if t.Sym().Pkg != LocalPkg {
+			return false
+		}
+
+		for i, x := range *path {
+			if x == t {
+				*path = (*path)[i:]
+				return true
+			}
+		}
+
+		*path = append(*path, t)
+		if findTypeLoop(t.Obj().(TypeObject).TypeDefn(), path) {
+			return true
+		}
+		*path = (*path)[:len(*path)-1]
+	} else {
+		// Anonymous type. Recurse on contained types.
+
+		switch t.Kind() {
+		case TARRAY:
+			if findTypeLoop(t.Elem(), path) {
+				return true
+			}
+		case TSTRUCT:
+			for _, f := range t.Fields().Slice() {
+				if findTypeLoop(f.Type, path) {
+					return true
+				}
+			}
+		case TINTER:
+			for _, m := range t.Methods().Slice() {
+				if m.Type.IsInterface() { // embedded interface
+					if findTypeLoop(m.Type, path) {
+						return true
+					}
+				}
+			}
+		}
+	}
+
+	return false
+}
+
+func reportTypeLoop(t *Type) {
+	if t.Broke() {
+		return
+	}
+
+	var l []*Type
+	if !findTypeLoop(t, &l) {
+		base.Fatalf("failed to find type loop for: %v", t)
+	}
+
+	// Rotate loop so that the earliest type declaration is first.
+	i := 0
+	for j, t := range l[1:] {
+		if typePos(t).Before(typePos(l[i])) {
+			i = j + 1
+		}
+	}
+	l = append(l[i:], l[:i]...)
+
+	var msg bytes.Buffer
+	fmt.Fprintf(&msg, "invalid recursive type %v\n", l[0])
+	for _, t := range l {
+		fmt.Fprintf(&msg, "\t%v: %v refers to\n", base.FmtPos(typePos(t)), t)
+		t.SetBroke(true)
+	}
+	fmt.Fprintf(&msg, "\t%v: %v", base.FmtPos(typePos(l[0])), l[0])
+	base.ErrorfAt(typePos(l[0]), msg.String())
+}
+
+// CalcSize calculates and stores the size and alignment for t.
+// If CalcSizeDisabled is set, and the size/alignment
+// have not already been calculated, it calls Fatal.
+// This is used to prevent data races in the back end.
+func CalcSize(t *Type) {
+	// Calling CalcSize when typecheck tracing enabled is not safe.
+	// See issue #33658.
+	if base.EnableTrace && SkipSizeForTracing {
+		return
+	}
+	if PtrSize == 0 {
+		// Assume this is a test.
+		return
+	}
+
+	if t == nil {
+		return
+	}
+
+	if t.Width == -2 {
+		reportTypeLoop(t)
+		t.Width = 0
+		t.Align = 1
+		return
+	}
+
+	if t.WidthCalculated() {
+		return
+	}
+
+	if CalcSizeDisabled {
+		if t.Broke() {
+			// break infinite recursion from Fatal call below
+			return
+		}
+		t.SetBroke(true)
+		base.Fatalf("width not calculated: %v", t)
+	}
+
+	// break infinite recursion if the broken recursive type
+	// is referenced again
+	if t.Broke() && t.Width == 0 {
+		return
+	}
+
+	// defer CheckSize calls until after we're done
+	DeferCheckSize()
+
+	lno := base.Pos
+	if pos := t.Pos(); pos.IsKnown() {
+		base.Pos = pos
+	}
+
+	t.Width = -2
+	t.Align = 0 // 0 means use t.Width, below
+
+	et := t.Kind()
+	switch et {
+	case TFUNC, TCHAN, TMAP, TSTRING:
+		break
+
+	// SimType == 0 during bootstrap
+	default:
+		if SimType[t.Kind()] != 0 {
+			et = SimType[t.Kind()]
+		}
+	}
+
+	var w int64
+	switch et {
+	default:
+		base.Fatalf("CalcSize: unknown type: %v", t)
+
+	// compiler-specific stuff
+	case TINT8, TUINT8, TBOOL:
+		// bool is int8
+		w = 1
+
+	case TINT16, TUINT16:
+		w = 2
+
+	case TINT32, TUINT32, TFLOAT32:
+		w = 4
+
+	case TINT64, TUINT64, TFLOAT64:
+		w = 8
+		t.Align = uint8(RegSize)
+
+	case TCOMPLEX64:
+		w = 8
+		t.Align = 4
+
+	case TCOMPLEX128:
+		w = 16
+		t.Align = uint8(RegSize)
+
+	case TPTR:
+		w = int64(PtrSize)
+		CheckSize(t.Elem())
+
+	case TUNSAFEPTR:
+		w = int64(PtrSize)
+
+	case TINTER: // implemented as 2 pointers
+		w = 2 * int64(PtrSize)
+		t.Align = uint8(PtrSize)
+		expandiface(t)
+
+	case TCHAN: // implemented as pointer
+		w = int64(PtrSize)
+
+		CheckSize(t.Elem())
+
+		// make fake type to check later to
+		// trigger channel argument check.
+		t1 := NewChanArgs(t)
+		CheckSize(t1)
+
+	case TCHANARGS:
+		t1 := t.ChanArgs()
+		CalcSize(t1) // just in case
+		if t1.Elem().Width >= 1<<16 {
+			base.ErrorfAt(typePos(t1), "channel element type too large (>64kB)")
+		}
+		w = 1 // anything will do
+
+	case TMAP: // implemented as pointer
+		w = int64(PtrSize)
+		CheckSize(t.Elem())
+		CheckSize(t.Key())
+
+	case TFORW: // should have been filled in
+		reportTypeLoop(t)
+		w = 1 // anything will do
+
+	case TANY:
+		// not a real type; should be replaced before use.
+		base.Fatalf("CalcSize any")
+
+	case TSTRING:
+		if StringSize == 0 {
+			base.Fatalf("early CalcSize string")
+		}
+		w = StringSize
+		t.Align = uint8(PtrSize)
+
+	case TARRAY:
+		if t.Elem() == nil {
+			break
+		}
+
+		CalcSize(t.Elem())
+		if t.Elem().Width != 0 {
+			cap := (uint64(MaxWidth) - 1) / uint64(t.Elem().Width)
+			if uint64(t.NumElem()) > cap {
+				base.ErrorfAt(typePos(t), "type %L larger than address space", t)
+			}
+		}
+		w = t.NumElem() * t.Elem().Width
+		t.Align = t.Elem().Align
+
+	case TSLICE:
+		if t.Elem() == nil {
+			break
+		}
+		w = SliceSize
+		CheckSize(t.Elem())
+		t.Align = uint8(PtrSize)
+
+	case TSTRUCT:
+		if t.IsFuncArgStruct() {
+			base.Fatalf("CalcSize fn struct %v", t)
+		}
+		w = calcStructOffset(t, t, 0, 1)
+
+	// make fake type to check later to
+	// trigger function argument computation.
+	case TFUNC:
+		t1 := NewFuncArgs(t)
+		CheckSize(t1)
+		w = int64(PtrSize) // width of func type is pointer
+
+	// function is 3 cated structures;
+	// compute their widths as side-effect.
+	case TFUNCARGS:
+		t1 := t.FuncArgs()
+		w = calcStructOffset(t1, t1.Recvs(), 0, 0)
+		w = calcStructOffset(t1, t1.Params(), w, RegSize)
+		w = calcStructOffset(t1, t1.Results(), w, RegSize)
+		t1.Extra.(*Func).Argwid = w
+		if w%int64(RegSize) != 0 {
+			base.Warn("bad type %v %d\n", t1, w)
+		}
+		t.Align = 1
+
+	case TTYPEPARAM:
+		// TODO(danscales) - remove when we eliminate the need
+		// to do CalcSize in noder2 (which shouldn't be needed in the noder)
+		w = int64(PtrSize)
+	}
+
+	if PtrSize == 4 && w != int64(int32(w)) {
+		base.ErrorfAt(typePos(t), "type %v too large", t)
+	}
+
+	t.Width = w
+	if t.Align == 0 {
+		if w == 0 || w > 8 || w&(w-1) != 0 {
+			base.Fatalf("invalid alignment for %v", t)
+		}
+		t.Align = uint8(w)
+	}
+
+	base.Pos = lno
+
+	ResumeCheckSize()
+}
+
+// CalcStructSize calculates the size of s,
+// filling in s.Width and s.Align,
+// even if size calculation is otherwise disabled.
+func CalcStructSize(s *Type) {
+	s.Width = calcStructOffset(s, s, 0, 1) // sets align
+}
+
+// when a type's width should be known, we call CheckSize
+// to compute it.  during a declaration like
+//
+//	type T *struct { next T }
+//
+// it is necessary to defer the calculation of the struct width
+// until after T has been initialized to be a pointer to that struct.
+// similarly, during import processing structs may be used
+// before their definition.  in those situations, calling
+// DeferCheckSize() stops width calculations until
+// ResumeCheckSize() is called, at which point all the
+// CalcSizes that were deferred are executed.
+// CalcSize should only be called when the type's size
+// is needed immediately.  CheckSize makes sure the
+// size is evaluated eventually.
+
+var deferredTypeStack []*Type
+
+func CheckSize(t *Type) {
+	if t == nil {
+		return
+	}
+
+	// function arg structs should not be checked
+	// outside of the enclosing function.
+	if t.IsFuncArgStruct() {
+		base.Fatalf("CheckSize %v", t)
+	}
+
+	if defercalc == 0 {
+		CalcSize(t)
+		return
+	}
+
+	// if type has not yet been pushed on deferredTypeStack yet, do it now
+	if !t.Deferwidth() {
+		t.SetDeferwidth(true)
+		deferredTypeStack = append(deferredTypeStack, t)
+	}
+}
+
+func DeferCheckSize() {
+	defercalc++
+}
+
+func ResumeCheckSize() {
+	if defercalc == 1 {
+		for len(deferredTypeStack) > 0 {
+			t := deferredTypeStack[len(deferredTypeStack)-1]
+			deferredTypeStack = deferredTypeStack[:len(deferredTypeStack)-1]
+			t.SetDeferwidth(false)
+			CalcSize(t)
+		}
+	}
+
+	defercalc--
+}
+
+// PtrDataSize returns the length in bytes of the prefix of t
+// containing pointer data. Anything after this offset is scalar data.
+func PtrDataSize(t *Type) int64 {
+	if !t.HasPointers() {
+		return 0
+	}
+
+	switch t.Kind() {
+	case TPTR,
+		TUNSAFEPTR,
+		TFUNC,
+		TCHAN,
+		TMAP:
+		return int64(PtrSize)
+
+	case TSTRING:
+		// struct { byte *str; intgo len; }
+		return int64(PtrSize)
+
+	case TINTER:
+		// struct { Itab *tab;	void *data; } or
+		// struct { Type *type; void *data; }
+		// Note: see comment in typebits.Set
+		return 2 * int64(PtrSize)
+
+	case TSLICE:
+		// struct { byte *array; uintgo len; uintgo cap; }
+		return int64(PtrSize)
+
+	case TARRAY:
+		// haspointers already eliminated t.NumElem() == 0.
+		return (t.NumElem()-1)*t.Elem().Width + PtrDataSize(t.Elem())
+
+	case TSTRUCT:
+		// Find the last field that has pointers.
+		var lastPtrField *Field
+		fs := t.Fields().Slice()
+		for i := len(fs) - 1; i >= 0; i-- {
+			if fs[i].Type.HasPointers() {
+				lastPtrField = fs[i]
+				break
+			}
+		}
+		return lastPtrField.Offset + PtrDataSize(lastPtrField.Type)
+
+	default:
+		base.Fatalf("PtrDataSize: unexpected type, %v", t)
+		return 0
+	}
+}
diff --git a/src/cmd/compile/internal/types/sizeof_test.go b/src/cmd/compile/internal/types/sizeof_test.go
index ea947d8..7028938 100644
--- a/src/cmd/compile/internal/types/sizeof_test.go
+++ b/src/cmd/compile/internal/types/sizeof_test.go
@@ -20,13 +20,13 @@
 		_32bit uintptr     // size on 32bit platforms
 		_64bit uintptr     // size on 64bit platforms
 	}{
-		{Sym{}, 52, 88},
-		{Type{}, 52, 88},
+		{Sym{}, 44, 72},
+		{Type{}, 60, 104},
 		{Map{}, 20, 40},
 		{Forward{}, 20, 32},
-		{Func{}, 32, 56},
+		{Func{}, 28, 48},
 		{Struct{}, 16, 32},
-		{Interface{}, 8, 16},
+		{Interface{}, 4, 8},
 		{Chan{}, 8, 16},
 		{Array{}, 12, 16},
 		{FuncArgs{}, 4, 8},
diff --git a/src/cmd/compile/internal/types/sort.go b/src/cmd/compile/internal/types/sort.go
new file mode 100644
index 0000000..dc59b06
--- /dev/null
+++ b/src/cmd/compile/internal/types/sort.go
@@ -0,0 +1,14 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+// MethodsByName sorts methods by symbol.
+type MethodsByName []*Field
+
+func (x MethodsByName) Len() int { return len(x) }
+
+func (x MethodsByName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+func (x MethodsByName) Less(i, j int) bool { return x[i].Sym.Less(x[j].Sym) }
diff --git a/src/cmd/compile/internal/types/sym.go b/src/cmd/compile/internal/types/sym.go
index 07bce4d..534cf7e 100644
--- a/src/cmd/compile/internal/types/sym.go
+++ b/src/cmd/compile/internal/types/sym.go
@@ -5,6 +5,7 @@
 package types
 
 import (
+	"cmd/compile/internal/base"
 	"cmd/internal/obj"
 	"cmd/internal/src"
 	"unicode"
@@ -26,20 +27,21 @@
 // NOTE: In practice, things can be messier than the description above
 // for various reasons (historical, convenience).
 type Sym struct {
-	Importdef *Pkg   // where imported definition was found
-	Linkname  string // link name
+	Linkname string // link name
 
 	Pkg  *Pkg
 	Name string // object name
 
-	// saved and restored by dcopy
-	Def        *Node    // definition: ONAME OTYPE OPACK or OLITERAL
+	// Def, Block, and Lastlineno are saved and restored by Pushdcl/Popdcl.
+
+	// The unique ONAME, OTYPE, OPACK, or OLITERAL node that this symbol is
+	// bound to within the current scope. (Most parts of the compiler should
+	// prefer passing the Node directly, rather than relying on this field.)
+	Def        Object
 	Block      int32    // blocknumber to catch redeclaration
 	Lastlineno src.XPos // last declaration for diagnostic
 
-	flags   bitset8
-	Label   *Node // corresponding label (ephemeral)
-	Origpkg *Pkg  // original package for . import
+	flags bitset8
 }
 
 const (
@@ -47,7 +49,7 @@
 	symUniq
 	symSiggen // type symbol has been generated
 	symAsm    // on asmlist, for writing to -asmhdr
-	symFunc   // function symbol; uses internal ABI
+	symFunc   // function symbol
 )
 
 func (sym *Sym) OnExportList() bool { return sym.flags&symOnExportList != 0 }
@@ -66,32 +68,30 @@
 	return sym != nil && sym.Name == "_"
 }
 
-func (sym *Sym) LinksymName() string {
-	if sym.IsBlank() {
-		return "_"
+// Deprecated: This method should not be used directly. Instead, use a
+// higher-level abstraction that directly returns the linker symbol
+// for a named object. For example, reflectdata.TypeLinksym(t) instead
+// of reflectdata.TypeSym(t).Linksym().
+func (sym *Sym) Linksym() *obj.LSym {
+	abi := obj.ABI0
+	if sym.Func() {
+		abi = obj.ABIInternal
 	}
-	if sym.Linkname != "" {
-		return sym.Linkname
-	}
-	return sym.Pkg.Prefix + "." + sym.Name
+	return sym.LinksymABI(abi)
 }
 
-func (sym *Sym) Linksym() *obj.LSym {
+// Deprecated: This method should not be used directly. Instead, use a
+// higher-level abstraction that directly returns the linker symbol
+// for a named object. For example, (*ir.Name).LinksymABI(abi) instead
+// of (*ir.Name).Sym().LinksymABI(abi).
+func (sym *Sym) LinksymABI(abi obj.ABI) *obj.LSym {
 	if sym == nil {
-		return nil
+		base.Fatalf("nil symbol")
 	}
-	initPkg := func(r *obj.LSym) {
-		if sym.Linkname != "" {
-			r.Pkg = "_"
-		} else {
-			r.Pkg = sym.Pkg.Prefix
-		}
+	if sym.Linkname != "" {
+		return base.Linkname(sym.Linkname, abi)
 	}
-	if sym.Func() {
-		// This is a function symbol. Mark it as "internal ABI".
-		return Ctxt.LookupABIInit(sym.LinksymName(), obj.ABIInternal, initPkg)
-	}
-	return Ctxt.LookupInit(sym.LinksymName(), initPkg)
+	return base.PkgLinksym(sym.Pkg.Prefix, sym.Name, abi)
 }
 
 // Less reports whether symbol a is ordered before symbol b.
diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go
index 023ab9a..1a9aa69 100644
--- a/src/cmd/compile/internal/types/type.go
+++ b/src/cmd/compile/internal/types/type.go
@@ -5,23 +5,40 @@
 package types
 
 import (
-	"cmd/internal/obj"
+	"cmd/compile/internal/base"
 	"cmd/internal/src"
 	"fmt"
+	"sync"
 )
 
-// Dummy Node so we can refer to *Node without actually
-// having a gc.Node. Necessary to break import cycles.
-// TODO(gri) try to eliminate soon
-type Node struct{ _ int }
+// Object represents an ir.Node, but without needing to import cmd/compile/internal/ir,
+// which would cause an import cycle. The uses in other packages must type assert
+// values of type Object to ir.Node or a more specific type.
+type Object interface {
+	Pos() src.XPos
+	Sym() *Sym
+	Type() *Type
+}
 
-//go:generate stringer -type EType -trimprefix T
+// A TypeObject is an Object representing a named type.
+type TypeObject interface {
+	Object
+	TypeDefn() *Type // for "type T Defn", returns Defn
+}
 
-// EType describes a kind of type.
-type EType uint8
+// A VarObject is an Object representing a function argument, variable, or struct field.
+type VarObject interface {
+	Object
+	RecordFrameOffset(int64) // save frame offset
+}
+
+//go:generate stringer -type Kind -trimprefix T type.go
+
+// Kind describes a kind of type.
+type Kind uint8
 
 const (
-	Txxx EType = iota
+	Txxx Kind = iota
 
 	TINT8
 	TUINT8
@@ -55,6 +72,7 @@
 	TANY
 	TSTRING
 	TUNSAFEPTR
+	TTYPEPARAM
 
 	// pseudo-types for literals
 	TIDEAL // untyped numeric constants
@@ -90,7 +108,7 @@
 // Types stores pointers to predeclared named types.
 //
 // It also stores pointers to several special types:
-//   - Types[TANY] is the placeholder "any" type recognized by substArgTypes.
+//   - Types[TANY] is the placeholder "any" type recognized by SubstArgTypes.
 //   - Types[TBLANK] represents the blank variable's type.
 //   - Types[TNIL] represents the predeclared "nil" value's type.
 //   - Types[TUNSAFEPTR] is package unsafe's Pointer type.
@@ -98,15 +116,15 @@
 
 var (
 	// Predeclared alias types. Kept separate for better error messages.
-	Bytetype *Type
-	Runetype *Type
+	ByteType *Type
+	RuneType *Type
 
 	// Predeclared error interface type.
-	Errortype *Type
+	ErrorType *Type
 
 	// Types to represent untyped string and boolean constants.
-	UntypedString *Type
-	UntypedBool   *Type
+	UntypedString = New(TSTRING)
+	UntypedBool   = New(TBOOL)
 
 	// Types to represent untyped numeric constants.
 	UntypedInt     = New(TIDEAL)
@@ -133,38 +151,54 @@
 	// TARRAY: *Array
 	// TSLICE: Slice
 	// TSSA: string
+	// TTYPEPARAM:  *Interface (though we may not need to store/use the Interface info)
 	Extra interface{}
 
 	// Width is the width of this Type in bytes.
 	Width int64 // valid if Align > 0
 
-	methods    Fields
+	// list of base methods (excluding embedding)
+	methods Fields
+	// list of all methods (including embedding)
 	allMethods Fields
 
-	Nod  *Node // canonical OTYPE node
-	Orig *Type // original type (type literal or predefined type)
+	// canonical OTYPE node for a named type (should be an ir.Name node with same sym)
+	nod Object
+	// the underlying type (type literal or predeclared type) for a defined type
+	underlying *Type
 
 	// Cache of composite types, with this type being the element type.
-	Cache struct {
+	cache struct {
 		ptr   *Type // *T, or nil
 		slice *Type // []T, or nil
 	}
 
-	Sym    *Sym  // symbol containing name, for named types
+	sym    *Sym  // symbol containing name, for named types
 	Vargen int32 // unique name for OTYPE/ONAME
 
-	Etype EType // kind of type
+	kind  Kind  // kind of type
 	Align uint8 // the required alignment of this type, in bytes (0 means Width and Align have not yet been computed)
 
 	flags bitset8
+
+	// For defined (named) generic types, a pointer to the list of type params
+	// (in order) of this type that need to be instantiated. For
+	// fully-instantiated generic types, this is the targs used to instantiate
+	// them (which are used when generating the corresponding instantiated
+	// methods). rparams is only set for named types that are generic or are
+	// fully-instantiated from a generic type, and is otherwise set to nil.
+	rparams *[]*Type
 }
 
+func (*Type) CanBeAnSSAAux() {}
+
 const (
 	typeNotInHeap  = 1 << iota // type cannot be heap allocated
 	typeBroke                  // broken type definition
 	typeNoalg                  // suppress hash and eq algorithm generation
 	typeDeferwidth             // width computation has been deferred and type is on deferredTypeStack
 	typeRecur
+	typeHasTParam // there is a typeparam somewhere in the type (generic function or type)
 )
 
 func (t *Type) NotInHeap() bool  { return t.flags&typeNotInHeap != 0 }
@@ -172,12 +206,73 @@
 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) HasTParam() bool  { return t.flags&typeHasTParam != 0 }
 
 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) }
 func (t *Type) SetDeferwidth(b bool) { t.flags.set(typeDeferwidth, b) }
 func (t *Type) SetRecur(b bool)      { t.flags.set(typeRecur, b) }
+func (t *Type) SetHasTParam(b bool)  { t.flags.set(typeHasTParam, b) }
+
+// Kind returns the kind of type t.
+func (t *Type) Kind() Kind { return t.kind }
+
+// Sym returns the name of type t.
+func (t *Type) Sym() *Sym       { return t.sym }
+func (t *Type) SetSym(sym *Sym) { t.sym = sym }
+
+// Underlying returns the underlying type of type t.
+func (t *Type) Underlying() *Type { return t.underlying }
+
+// SetNod associates t with syntax node n.
+func (t *Type) SetNod(n Object) {
+	// t.nod can be non-nil already
+	// in the case of shared *Types, like []byte or interface{}.
+	if t.nod == nil {
+		t.nod = n
+	}
+}
+
+// Pos returns a position associated with t, if any.
+// This should only be used for diagnostics.
+func (t *Type) Pos() src.XPos {
+	if t.nod != nil {
+		return t.nod.Pos()
+	}
+	return src.NoXPos
+}
+
+func (t *Type) RParams() []*Type {
+	if t.rparams == nil {
+		return nil
+	}
+	return *t.rparams
+}
+
+func (t *Type) SetRParams(rparams []*Type) {
+	if len(rparams) == 0 {
+		base.Fatalf("Setting nil or zero-length rparams")
+	}
+	t.rparams = &rparams
+	if t.HasTParam() {
+		return
+	}
+	// HasTParam should be set if any rparam is or has a type param. This is
+	// to handle the case of a generic type which doesn't reference any of its
+	// type params (e.g. most commonly, an empty struct).
+	for _, rparam := range rparams {
+		if rparam.HasTParam() {
+			t.SetHasTParam(true)
+			break
+		}
+	}
+}
+
+// NoPkg is a nil *Pkg value for clarity.
+// It's intended for use when constructing types that aren't exported
+// and thus don't need to be associated with any package.
+var NoPkg *Pkg = nil
 
 // Pkg returns the package that t appeared in.
 //
@@ -186,7 +281,7 @@
 // cmd/compile itself, but we need to track it because it's exposed by
 // the go/types API.
 func (t *Type) Pkg() *Pkg {
-	switch t.Etype {
+	switch t.kind {
 	case TFUNC:
 		return t.Extra.(*Func).pkg
 	case TSTRUCT:
@@ -194,25 +289,11 @@
 	case TINTER:
 		return t.Extra.(*Interface).pkg
 	default:
-		Fatalf("Pkg: unexpected kind: %v", t)
+		base.Fatalf("Pkg: unexpected kind: %v", t)
 		return nil
 	}
 }
 
-// SetPkg sets the package that t appeared in.
-func (t *Type) SetPkg(pkg *Pkg) {
-	switch t.Etype {
-	case TFUNC:
-		t.Extra.(*Func).pkg = pkg
-	case TSTRUCT:
-		t.Extra.(*Struct).pkg = pkg
-	case TINTER:
-		t.Extra.(*Interface).pkg = pkg
-	default:
-		Fatalf("Pkg: unexpected kind: %v", t)
-	}
-}
-
 // Map contains Type fields specific to maps.
 type Map struct {
 	Key  *Type // Key type
@@ -246,16 +327,14 @@
 	Receiver *Type // function receiver
 	Results  *Type // function results
 	Params   *Type // function params
+	TParams  *Type // type params of receiver (if method) or function
 
-	Nname *Node
-	pkg   *Pkg
+	pkg *Pkg
 
 	// Argwid is the total width of the function receiver, params, and results.
 	// It gets calculated via a temporary TFUNCARGS type.
 	// Note that TFUNC's Width is Widthptr.
 	Argwid int64
-
-	Outnamed bool
 }
 
 // FuncType returns t's extra func-specific fields.
@@ -284,6 +363,7 @@
 	FunargRcvr           // receiver
 	FunargParams         // input parameters
 	FunargResults        // output results
+	FunargTparams        // type params
 )
 
 // StructType returns t's extra struct-specific fields.
@@ -294,8 +374,7 @@
 
 // Interface contains Type fields specific to interface types.
 type Interface struct {
-	Fields Fields
-	pkg    *Pkg
+	pkg *Pkg
 }
 
 // Ptr contains Type fields specific to pointer types.
@@ -347,8 +426,11 @@
 	Elem *Type // element type
 }
 
-// A Field represents a field in a struct or a method in an interface or
-// associated with a named type.
+// A Field is a (Sym, Type) pairing along with some other information, and,
+// depending on the context, is used to represent:
+//  - a field in a struct
+//  - a method in an interface or associated with a named type
+//  - a function parameter
 type Field struct {
 	flags bitset8
 
@@ -361,10 +443,11 @@
 
 	// For fields that represent function parameters, Nname points
 	// to the associated ONAME Node.
-	Nname *Node
+	Nname Object
 
 	// Offset in bytes of this field or method within its enclosing struct
-	// or interface Type.
+	// or interface Type.  Exception: if field is function receiver, arg or
+	// result, then this is BOGUS_FUNARG_OFFSET; types does not know the Abi.
 	Offset int64
 }
 
@@ -389,7 +472,7 @@
 
 // IsMethod reports whether f represents a method rather than a struct field.
 func (f *Field) IsMethod() bool {
-	return f.Type.Etype == TFUNC && f.Type.Recv() != nil
+	return f.Type.kind == TFUNC && f.Type.Recv() != nil
 }
 
 // Fields is a pointer to a slice of *Field.
@@ -444,14 +527,14 @@
 }
 
 // New returns a new Type of the specified kind.
-func New(et EType) *Type {
+func New(et Kind) *Type {
 	t := &Type{
-		Etype: et,
+		kind:  et,
 		Width: BADWIDTH,
 	}
-	t.Orig = t
+	t.underlying = t
 	// TODO(josharian): lazily initialize some of these?
-	switch t.Etype {
+	switch t.kind {
 	case TMAP:
 		t.Extra = new(Map)
 	case TFORW:
@@ -474,6 +557,8 @@
 		t.Extra = new(Tuple)
 	case TRESULTS:
 		t.Extra = new(Results)
+	case TTYPEPARAM:
+		t.Extra = new(Interface)
 	}
 	return t
 }
@@ -481,26 +566,32 @@
 // NewArray returns a new fixed-length array Type.
 func NewArray(elem *Type, bound int64) *Type {
 	if bound < 0 {
-		Fatalf("NewArray: invalid bound %v", bound)
+		base.Fatalf("NewArray: invalid bound %v", bound)
 	}
 	t := New(TARRAY)
 	t.Extra = &Array{Elem: elem, Bound: bound}
 	t.SetNotInHeap(elem.NotInHeap())
+	if elem.HasTParam() {
+		t.SetHasTParam(true)
+	}
 	return t
 }
 
 // NewSlice returns the slice Type with element type elem.
 func NewSlice(elem *Type) *Type {
-	if t := elem.Cache.slice; t != nil {
+	if t := elem.cache.slice; t != nil {
 		if t.Elem() != elem {
-			Fatalf("elem mismatch")
+			base.Fatalf("elem mismatch")
 		}
 		return t
 	}
 
 	t := New(TSLICE)
 	t.Extra = Slice{Elem: elem}
-	elem.Cache.slice = t
+	elem.cache.slice = t
+	if elem.HasTParam() {
+		t.SetHasTParam(true)
+	}
 	return t
 }
 
@@ -510,6 +601,9 @@
 	ct := t.ChanType()
 	ct.Elem = elem
 	ct.Dir = dir
+	if elem.HasTParam() {
+		t.SetHasTParam(true)
+	}
 	return t
 }
 
@@ -517,13 +611,23 @@
 	t := New(TTUPLE)
 	t.Extra.(*Tuple).first = t1
 	t.Extra.(*Tuple).second = t2
+	if t1.HasTParam() || t2.HasTParam() {
+		t.SetHasTParam(true)
+	}
+	return t
+}
+
+func newResults(types []*Type) *Type {
+	t := New(TRESULTS)
+	t.Extra.(*Results).Types = types
 	return t
 }
 
 func NewResults(types []*Type) *Type {
-	t := New(TRESULTS)
-	t.Extra.(*Results).Types = types
-	return t
+	if len(types) == 1 && types[0] == TypeMem {
+		return TypeResultMem
+	}
+	return newResults(types)
 }
 
 func newSSA(name string) *Type {
@@ -538,6 +642,9 @@
 	mt := t.MapType()
 	mt.Key = k
 	mt.Elem = v
+	if k.HasTParam() || v.HasTParam() {
+		t.SetHasTParam(true)
+	}
 	return t
 }
 
@@ -549,22 +656,31 @@
 // NewPtr returns the pointer type pointing to t.
 func NewPtr(elem *Type) *Type {
 	if elem == nil {
-		Fatalf("NewPtr: pointer to elem Type is nil")
+		base.Fatalf("NewPtr: pointer to elem Type is nil")
 	}
 
-	if t := elem.Cache.ptr; t != nil {
+	if t := elem.cache.ptr; t != nil {
 		if t.Elem() != elem {
-			Fatalf("NewPtr: elem mismatch")
+			base.Fatalf("NewPtr: elem mismatch")
+		}
+		if elem.HasTParam() {
+			// Extra check when reusing the cache, since the elem
+			// might have still been undetermined (i.e. a TFORW type)
+			// when this entry was cached.
+			t.SetHasTParam(true)
 		}
 		return t
 	}
 
 	t := New(TPTR)
 	t.Extra = Ptr{Elem: elem}
-	t.Width = int64(Widthptr)
-	t.Align = uint8(Widthptr)
+	t.Width = int64(PtrSize)
+	t.Align = uint8(PtrSize)
 	if NewPtrCacheEnabled {
-		elem.Cache.ptr = t
+		elem.cache.ptr = t
+	}
+	if elem.HasTParam() {
+		t.SetHasTParam(true)
 	}
 	return t
 }
@@ -583,10 +699,17 @@
 	return t
 }
 
-func NewField() *Field {
-	return &Field{
+func NewField(pos src.XPos, sym *Sym, typ *Type) *Field {
+	f := &Field{
+		Pos:    pos,
+		Sym:    sym,
+		Type:   typ,
 		Offset: BADWIDTH,
 	}
+	if typ == nil {
+		f.SetBroke(true)
+	}
+	return f
 }
 
 // SubstAny walks t, replacing instances of "any" with successive
@@ -596,13 +719,13 @@
 		return nil
 	}
 
-	switch t.Etype {
+	switch t.kind {
 	default:
 		// Leave the type unchanged.
 
 	case TANY:
 		if len(*types) == 0 {
-			Fatalf("substArgTypes: not enough argument types")
+			base.Fatalf("SubstArgTypes: not enough argument types")
 		}
 		t = (*types)[0]
 		*types = (*types)[1:]
@@ -680,7 +803,7 @@
 	}
 	nt := *t
 	// copy any *T Extra fields, to avoid aliasing
-	switch t.Etype {
+	switch t.kind {
 	case TMAP:
 		x := *t.Extra.(*Map)
 		nt.Extra = &x
@@ -703,11 +826,11 @@
 		x := *t.Extra.(*Array)
 		nt.Extra = &x
 	case TTUPLE, TSSA, TRESULTS:
-		Fatalf("ssa types cannot be copied")
+		base.Fatalf("ssa types cannot be copied")
 	}
 	// TODO(mdempsky): Find out why this is necessary and explain.
-	if t.Orig == t {
-		nt.Orig = &nt
+	if t.underlying == t {
+		nt.underlying = &nt
 	}
 	return &nt
 }
@@ -717,17 +840,19 @@
 	return &nf
 }
 
-func (t *Type) wantEtype(et EType) {
-	if t.Etype != et {
-		Fatalf("want %v, but have %v", et, t)
+func (t *Type) wantEtype(et Kind) {
+	if t.kind != et {
+		base.Fatalf("want %v, but have %v", et, t)
 	}
 }
 
 func (t *Type) Recvs() *Type   { return t.FuncType().Receiver }
+func (t *Type) TParams() *Type { return t.FuncType().TParams }
 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) NumTParams() int { return t.FuncType().TParams.NumFields() }
 func (t *Type) NumParams() int  { return t.FuncType().Params.NumFields() }
 func (t *Type) NumResults() int { return t.FuncType().Results.NumFields() }
 
@@ -772,7 +897,7 @@
 // Elem returns the type of elements of t.
 // Usable with pointers, channels, arrays, slices, and maps.
 func (t *Type) Elem() *Type {
-	switch t.Etype {
+	switch t.kind {
 	case TPTR:
 		return t.Extra.(Ptr).Elem
 	case TARRAY:
@@ -784,7 +909,7 @@
 	case TMAP:
 		return t.Extra.(*Map).Elem
 	}
-	Fatalf("Type.Elem %s", t.Etype)
+	base.Fatalf("Type.Elem %s", t.kind)
 	return nil
 }
 
@@ -800,65 +925,54 @@
 	return t.Extra.(FuncArgs).T
 }
 
-// Nname returns the associated function's nname.
-func (t *Type) Nname() *Node {
-	switch t.Etype {
-	case TFUNC:
-		return t.Extra.(*Func).Nname
-	}
-	Fatalf("Type.Nname %v %v", t.Etype, t)
-	return nil
-}
-
-// Nname sets the associated function's nname.
-func (t *Type) SetNname(n *Node) {
-	switch t.Etype {
-	case TFUNC:
-		t.Extra.(*Func).Nname = n
-	default:
-		Fatalf("Type.SetNname %v %v", t.Etype, t)
-	}
-}
-
 // IsFuncArgStruct reports whether t is a struct representing function parameters.
 func (t *Type) IsFuncArgStruct() bool {
-	return t.Etype == TSTRUCT && t.Extra.(*Struct).Funarg != FunargNone
+	return t.kind == TSTRUCT && t.Extra.(*Struct).Funarg != FunargNone
 }
 
+// Methods returns a pointer to the base methods (excluding embedding) for type t.
+// These can either be concrete methods (for non-interface types) or interface
+// methods (for interface types).
 func (t *Type) Methods() *Fields {
-	// TODO(mdempsky): Validate t?
 	return &t.methods
 }
 
+// AllMethods returns a pointer to all the methods (including embedding) for type t.
+// For an interface type, this is the set of methods that are typically iterated over.
 func (t *Type) AllMethods() *Fields {
-	// TODO(mdempsky): Validate t?
+	if t.kind == TINTER {
+		// Calculate the full method set of an interface type on the fly
+		// now, if not done yet.
+		CalcSize(t)
+	}
 	return &t.allMethods
 }
 
-func (t *Type) Fields() *Fields {
-	switch t.Etype {
-	case TSTRUCT:
-		return &t.Extra.(*Struct).fields
-	case TINTER:
-		Dowidth(t)
-		return &t.Extra.(*Interface).Fields
-	}
-	Fatalf("Fields: type %v does not have fields", t)
-	return nil
+// SetAllMethods sets the set of all methods (including embedding) for type t.
+// Use this method instead of t.AllMethods().Set(), which might call CalcSize() on
+// an uninitialized interface type.
+func (t *Type) SetAllMethods(fs []*Field) {
+	t.allMethods.Set(fs)
 }
 
-// Field returns the i'th field/method of struct/interface type t.
+// Fields returns the fields of struct type t.
+func (t *Type) Fields() *Fields {
+	t.wantEtype(TSTRUCT)
+	return &t.Extra.(*Struct).fields
+}
+
+// Field returns the i'th field of struct type t.
 func (t *Type) Field(i int) *Field {
 	return t.Fields().Slice()[i]
 }
 
-// FieldSlice returns a slice of containing all fields/methods of
-// struct/interface type t.
+// FieldSlice returns a slice of containing all fields of
+// a struct type t.
 func (t *Type) FieldSlice() []*Field {
 	return t.Fields().Slice()
 }
 
-// SetFields sets struct/interface type t's fields/methods to fields.
+// SetFields sets struct type t's fields to fields.
 func (t *Type) SetFields(fields []*Field) {
 	// If we've calculated the width of t before,
 	// then some other type such as a function signature
@@ -867,7 +981,7 @@
 	// enforce that SetFields cannot be called once
 	// t's width has been calculated.
 	if t.WidthCalculated() {
-		Fatalf("SetFields of %v: width previously calculated", t)
+		base.Fatalf("SetFields of %v: width previously calculated", t)
 	}
 	t.wantEtype(TSTRUCT)
 	for _, f := range fields {
@@ -884,6 +998,7 @@
 	t.Fields().Set(fields)
 }
 
+// SetInterface sets the base methods of an interface type t.
 func (t *Type) SetInterface(methods []*Field) {
 	t.wantEtype(TINTER)
 	t.Methods().Set(methods)
@@ -901,23 +1016,23 @@
 }
 
 func (t *Type) Size() int64 {
-	if t.Etype == TSSA {
+	if t.kind == TSSA {
 		if t == TypeInt128 {
 			return 16
 		}
 		return 0
 	}
-	Dowidth(t)
+	CalcSize(t)
 	return t.Width
 }
 
 func (t *Type) Alignment() int64 {
-	Dowidth(t)
+	CalcSize(t)
 	return int64(t.Align)
 }
 
 func (t *Type) SimpleString() string {
-	return t.Etype.String()
+	return t.kind.String()
 }
 
 // Cmp is a comparison between values a and b.
@@ -1001,31 +1116,31 @@
 		return CMPgt
 	}
 
-	if t.Etype != x.Etype {
-		return cmpForNe(t.Etype < x.Etype)
+	if t.kind != x.kind {
+		return cmpForNe(t.kind < x.kind)
 	}
 
-	if t.Sym != nil || x.Sym != nil {
+	if t.sym != nil || x.sym != nil {
 		// Special case: we keep byte and uint8 separate
 		// for error messages. Treat them as equal.
-		switch t.Etype {
+		switch t.kind {
 		case TUINT8:
-			if (t == Types[TUINT8] || t == Bytetype) && (x == Types[TUINT8] || x == Bytetype) {
+			if (t == Types[TUINT8] || t == ByteType) && (x == Types[TUINT8] || x == ByteType) {
 				return CMPeq
 			}
 
 		case TINT32:
-			if (t == Types[Runetype.Etype] || t == Runetype) && (x == Types[Runetype.Etype] || x == Runetype) {
+			if (t == Types[RuneType.kind] || t == RuneType) && (x == Types[RuneType.kind] || x == RuneType) {
 				return CMPeq
 			}
 		}
 	}
 
-	if c := t.Sym.cmpsym(x.Sym); c != CMPeq {
+	if c := t.sym.cmpsym(x.sym); c != CMPeq {
 		return c
 	}
 
-	if x.Sym != nil {
+	if x.sym != nil {
 		// Syms non-nil, if vargens match then equal.
 		if t.Vargen != x.Vargen {
 			return cmpForNe(t.Vargen < x.Vargen)
@@ -1034,7 +1149,7 @@
 	}
 	// both syms nil, look at structure below.
 
-	switch t.Etype {
+	switch t.kind {
 	case TBOOL, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TUNSAFEPTR, TUINTPTR,
 		TINT8, TINT16, TINT32, TINT64, TINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINT:
 		return CMPeq
@@ -1134,8 +1249,8 @@
 		return CMPeq
 
 	case TINTER:
-		tfs := t.FieldSlice()
-		xfs := x.FieldSlice()
+		tfs := t.AllMethods().Slice()
+		xfs := x.AllMethods().Slice()
 		for i := 0; i < len(tfs) && i < len(xfs); i++ {
 			t1, x1 := tfs[i], xfs[i]
 			if c := t1.Sym.cmpsym(x1.Sym); c != CMPeq {
@@ -1191,15 +1306,15 @@
 }
 
 // IsKind reports whether t is a Type of the specified kind.
-func (t *Type) IsKind(et EType) bool {
-	return t != nil && t.Etype == et
+func (t *Type) IsKind(et Kind) bool {
+	return t != nil && t.kind == et
 }
 
 func (t *Type) IsBoolean() bool {
-	return t.Etype == TBOOL
+	return t.kind == TBOOL
 }
 
-var unsignedEType = [...]EType{
+var unsignedEType = [...]Kind{
 	TINT8:    TUINT8,
 	TUINT8:   TUINT8,
 	TINT16:   TUINT16,
@@ -1216,54 +1331,62 @@
 // ToUnsigned returns the unsigned equivalent of integer type t.
 func (t *Type) ToUnsigned() *Type {
 	if !t.IsInteger() {
-		Fatalf("unsignedType(%v)", t)
+		base.Fatalf("unsignedType(%v)", t)
 	}
-	return Types[unsignedEType[t.Etype]]
+	return Types[unsignedEType[t.kind]]
 }
 
 func (t *Type) IsInteger() bool {
-	switch t.Etype {
+	switch t.kind {
 	case TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64, TUINT64, TINT, TUINT, TUINTPTR:
 		return true
 	}
-	return false
+	return t == UntypedInt || t == UntypedRune
 }
 
 func (t *Type) IsSigned() bool {
-	switch t.Etype {
+	switch t.kind {
 	case TINT8, TINT16, TINT32, TINT64, TINT:
 		return true
 	}
 	return false
 }
 
+func (t *Type) IsUnsigned() bool {
+	switch t.kind {
+	case TUINT8, TUINT16, TUINT32, TUINT64, TUINT, TUINTPTR:
+		return true
+	}
+	return false
+}
+
 func (t *Type) IsFloat() bool {
-	return t.Etype == TFLOAT32 || t.Etype == TFLOAT64
+	return t.kind == TFLOAT32 || t.kind == TFLOAT64 || t == UntypedFloat
 }
 
 func (t *Type) IsComplex() bool {
-	return t.Etype == TCOMPLEX64 || t.Etype == TCOMPLEX128
+	return t.kind == TCOMPLEX64 || t.kind == TCOMPLEX128 || t == UntypedComplex
 }
 
 // IsPtr reports whether t is a regular Go pointer type.
 // This does not include unsafe.Pointer.
 func (t *Type) IsPtr() bool {
-	return t.Etype == TPTR
+	return t.kind == TPTR
 }
 
 // IsPtrElem reports whether t is the element of a pointer (to t).
 func (t *Type) IsPtrElem() bool {
-	return t.Cache.ptr != nil
+	return t.cache.ptr != nil
 }
 
 // IsUnsafePtr reports whether t is an unsafe pointer.
 func (t *Type) IsUnsafePtr() bool {
-	return t.Etype == TUNSAFEPTR
+	return t.kind == TUNSAFEPTR
 }
 
 // IsUintptr reports whether t is an uintptr.
 func (t *Type) IsUintptr() bool {
-	return t.Etype == TUINTPTR
+	return t.kind == TUINTPTR
 }
 
 // IsPtrShaped reports whether t is represented by a single machine pointer.
@@ -1272,50 +1395,64 @@
 // that consist of a single pointer shaped type.
 // TODO(mdempsky): Should it? See golang.org/issue/15028.
 func (t *Type) IsPtrShaped() bool {
-	return t.Etype == TPTR || t.Etype == TUNSAFEPTR ||
-		t.Etype == TMAP || t.Etype == TCHAN || t.Etype == TFUNC
+	return t.kind == TPTR || t.kind == TUNSAFEPTR ||
+		t.kind == TMAP || t.kind == TCHAN || t.kind == TFUNC
 }
 
 // HasNil reports whether the set of values determined by t includes nil.
 func (t *Type) HasNil() bool {
-	switch t.Etype {
-	case TCHAN, TFUNC, TINTER, TMAP, TPTR, TSLICE, TUNSAFEPTR:
+	switch t.kind {
+	case TCHAN, TFUNC, TINTER, TMAP, TNIL, TPTR, TSLICE, TUNSAFEPTR:
 		return true
 	}
 	return false
 }
 
 func (t *Type) IsString() bool {
-	return t.Etype == TSTRING
+	return t.kind == TSTRING
 }
 
 func (t *Type) IsMap() bool {
-	return t.Etype == TMAP
+	return t.kind == TMAP
 }
 
 func (t *Type) IsChan() bool {
-	return t.Etype == TCHAN
+	return t.kind == TCHAN
 }
 
 func (t *Type) IsSlice() bool {
-	return t.Etype == TSLICE
+	return t.kind == TSLICE
 }
 
 func (t *Type) IsArray() bool {
-	return t.Etype == TARRAY
+	return t.kind == TARRAY
 }
 
 func (t *Type) IsStruct() bool {
-	return t.Etype == TSTRUCT
+	return t.kind == TSTRUCT
 }
 
 func (t *Type) IsInterface() bool {
-	return t.Etype == TINTER
+	return t.kind == TINTER
 }
 
 // IsEmptyInterface reports whether t is an empty interface type.
 func (t *Type) IsEmptyInterface() bool {
-	return t.IsInterface() && t.NumFields() == 0
+	return t.IsInterface() && t.AllMethods().Len() == 0
+}
+
+// IsScalar reports whether 't' is a scalar Go type, e.g.
+// bool/int/float/complex. Note that struct and array types consisting
+// of a single scalar element are not considered scalar, likewise
+// pointer types are also not considered scalar.
+func (t *Type) IsScalar() bool {
+	switch t.kind {
+	case TBOOL, TINT8, TUINT8, TINT16, TUINT16, TINT32,
+		TUINT32, TINT64, TUINT64, TINT, TUINT,
+		TUINTPTR, TCOMPLEX64, TCOMPLEX128, TFLOAT32, TFLOAT64:
+		return true
+	}
+	return false
 }
 
 func (t *Type) PtrTo() *Type {
@@ -1323,10 +1460,13 @@
 }
 
 func (t *Type) NumFields() int {
+	if t.kind == TRESULTS {
+		return len(t.Extra.(*Results).Types)
+	}
 	return t.Fields().Len()
 }
 func (t *Type) FieldType(i int) *Type {
-	if t.Etype == TTUPLE {
+	if t.kind == TTUPLE {
 		switch i {
 		case 0:
 			return t.Extra.(*Tuple).first
@@ -1336,7 +1476,7 @@
 			panic("bad tuple index")
 		}
 	}
-	if t.Etype == TRESULTS {
+	if t.kind == TRESULTS {
 		return t.Extra.(*Results).Types[i]
 	}
 	return t.Field(i).Type
@@ -1367,10 +1507,10 @@
 // (and their comprised elements) are excluded from the count.
 // struct { x, y [3]int } has six components; [10]struct{ x, y string } has twenty.
 func (t *Type) NumComponents(countBlank componentsIncludeBlankFields) int64 {
-	switch t.Etype {
+	switch t.kind {
 	case TSTRUCT:
 		if t.IsFuncArgStruct() {
-			Fatalf("NumComponents func arg struct")
+			base.Fatalf("NumComponents func arg struct")
 		}
 		var n int64
 		for _, f := range t.FieldSlice() {
@@ -1390,10 +1530,10 @@
 // if there is exactly one. Otherwise, it returns nil.
 // Components are counted as in NumComponents, including blank fields.
 func (t *Type) SoleComponent() *Type {
-	switch t.Etype {
+	switch t.kind {
 	case TSTRUCT:
 		if t.IsFuncArgStruct() {
-			Fatalf("SoleComponent func arg struct")
+			base.Fatalf("SoleComponent func arg struct")
 		}
 		if t.NumFields() != 1 {
 			return nil
@@ -1416,10 +1556,10 @@
 }
 
 func (t *Type) IsMemory() bool {
-	if t == TypeMem || t.Etype == TTUPLE && t.Extra.(*Tuple).second == TypeMem {
+	if t == TypeMem || t.kind == TTUPLE && t.Extra.(*Tuple).second == TypeMem {
 		return true
 	}
-	if t.Etype == TRESULTS {
+	if t.kind == TRESULTS {
 		if types := t.Extra.(*Results).Types; len(types) > 0 && types[len(types)-1] == TypeMem {
 			return true
 		}
@@ -1428,8 +1568,8 @@
 }
 func (t *Type) IsFlags() bool   { return t == TypeFlags }
 func (t *Type) IsVoid() bool    { return t == TypeVoid }
-func (t *Type) IsTuple() bool   { return t.Etype == TTUPLE }
-func (t *Type) IsResults() bool { return t.Etype == TRESULTS }
+func (t *Type) IsTuple() bool   { return t.kind == TTUPLE }
+func (t *Type) IsResults() bool { return t.kind == TRESULTS }
 
 // IsUntyped reports whether t is an untyped type.
 func (t *Type) IsUntyped() bool {
@@ -1439,7 +1579,7 @@
 	if t == UntypedString || t == UntypedBool {
 		return true
 	}
-	switch t.Etype {
+	switch t.kind {
 	case TNIL, TIDEAL:
 		return true
 	}
@@ -1449,7 +1589,7 @@
 // HasPointers reports whether t contains a heap pointer.
 // Note that this function ignores pointers to go:notinheap types.
 func (t *Type) HasPointers() bool {
-	switch t.Etype {
+	switch t.kind {
 	case TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64,
 		TUINT64, TUINTPTR, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TBOOL, TSSA:
 		return false
@@ -1488,10 +1628,6 @@
 	return true
 }
 
-func (t *Type) Symbol() *obj.LSym {
-	return TypeLinkSym(t)
-}
-
 // Tie returns 'T' if t is a concrete type,
 // 'I' if t is an interface type, and 'E' if t is an empty interface type.
 // It is used to build calls to the conv* and assert* runtime routines.
@@ -1517,9 +1653,394 @@
 
 var (
 	// TSSA types. HasPointers assumes these are pointer-free.
-	TypeInvalid = newSSA("invalid")
-	TypeMem     = newSSA("mem")
-	TypeFlags   = newSSA("flags")
-	TypeVoid    = newSSA("void")
-	TypeInt128  = newSSA("int128")
+	TypeInvalid   = newSSA("invalid")
+	TypeMem       = newSSA("mem")
+	TypeFlags     = newSSA("flags")
+	TypeVoid      = newSSA("void")
+	TypeInt128    = newSSA("int128")
+	TypeResultMem = newResults([]*Type{TypeMem})
 )
+
+// NewNamed returns a new named type for the given type name. obj should be an
+// ir.Name. The new type is incomplete (marked as TFORW kind), and the underlying
+// type should be set later via SetUnderlying(). References to the type are
+// maintained until the type is filled in, so those references can be updated when
+// the type is complete.
+func NewNamed(obj Object) *Type {
+	t := New(TFORW)
+	t.sym = obj.Sym()
+	t.nod = obj
+	return t
+}
+
+// Obj returns the canonical type name node for a named type t, nil for an unnamed type.
+func (t *Type) Obj() Object {
+	if t.sym != nil {
+		return t.nod
+	}
+	return nil
+}
+
+// SetUnderlying sets the underlying type. SetUnderlying automatically updates any
+// types that were waiting for this type to be completed.
+func (t *Type) SetUnderlying(underlying *Type) {
+	if underlying.kind == TFORW {
+		// This type isn't computed yet; when it is, update n.
+		underlying.ForwardType().Copyto = append(underlying.ForwardType().Copyto, t)
+		return
+	}
+
+	ft := t.ForwardType()
+
+	// TODO(mdempsky): Fix Type rekinding.
+	t.kind = underlying.kind
+	t.Extra = underlying.Extra
+	t.Width = underlying.Width
+	t.Align = underlying.Align
+	t.underlying = underlying.underlying
+
+	if underlying.NotInHeap() {
+		t.SetNotInHeap(true)
+	}
+	if underlying.Broke() {
+		t.SetBroke(true)
+	}
+	if underlying.HasTParam() {
+		t.SetHasTParam(true)
+	}
+
+	// spec: "The declared type does not inherit any methods bound
+	// to the existing type, but the method set of an interface
+	// type [...] remains unchanged."
+	if t.IsInterface() {
+		t.methods = underlying.methods
+		t.allMethods = underlying.allMethods
+	}
+
+	// Update types waiting on this type.
+	for _, w := range ft.Copyto {
+		w.SetUnderlying(t)
+	}
+
+	// Double-check use of type as embedded type.
+	if ft.Embedlineno.IsKnown() {
+		if t.IsPtr() || t.IsUnsafePtr() {
+			base.ErrorfAt(ft.Embedlineno, "embedded type cannot be a pointer")
+		}
+	}
+}
+
+func fieldsHasTParam(fields []*Field) bool {
+	for _, f := range fields {
+		if f.Type != nil && f.Type.HasTParam() {
+			return true
+		}
+	}
+	return false
+}
+
+// NewBasic returns a new basic type of the given kind.
+func NewBasic(kind Kind, obj Object) *Type {
+	t := New(kind)
+	t.sym = obj.Sym()
+	t.nod = obj
+	return t
+}
+
+// NewInterface returns a new interface for the given methods and
+// embedded types. Embedded types are specified as fields with no Sym.
+func NewInterface(pkg *Pkg, methods []*Field) *Type {
+	t := New(TINTER)
+	t.SetInterface(methods)
+	for _, f := range methods {
+		// f.Type could be nil for a broken interface declaration
+		if f.Type != nil && f.Type.HasTParam() {
+			t.SetHasTParam(true)
+			break
+		}
+	}
+	if anyBroke(methods) {
+		t.SetBroke(true)
+	}
+	t.Extra.(*Interface).pkg = pkg
+	return t
+}
+
+// NewTypeParam returns a new type param.
+func NewTypeParam(pkg *Pkg) *Type {
+	t := New(TTYPEPARAM)
+	t.Extra.(*Interface).pkg = pkg
+	t.SetHasTParam(true)
+	return t
+}
+
+const BOGUS_FUNARG_OFFSET = -1000000000
+
+func unzeroFieldOffsets(f []*Field) {
+	for i := range f {
+		f[i].Offset = BOGUS_FUNARG_OFFSET // This will cause an explosion if it is not corrected
+	}
+}
+
+// NewSignature returns a new function type for the given receiver,
+// parameters, results, and type parameters, any of which may be nil.
+func NewSignature(pkg *Pkg, recv *Field, tparams, params, results []*Field) *Type {
+	var recvs []*Field
+	if recv != nil {
+		recvs = []*Field{recv}
+	}
+
+	t := New(TFUNC)
+	ft := t.FuncType()
+
+	funargs := func(fields []*Field, funarg Funarg) *Type {
+		s := NewStruct(NoPkg, fields)
+		s.StructType().Funarg = funarg
+		if s.Broke() {
+			t.SetBroke(true)
+		}
+		return s
+	}
+
+	if recv != nil {
+		recv.Offset = BOGUS_FUNARG_OFFSET
+	}
+	unzeroFieldOffsets(params)
+	unzeroFieldOffsets(results)
+	ft.Receiver = funargs(recvs, FunargRcvr)
+	// TODO(danscales): just use nil here (save memory) if no tparams
+	ft.TParams = funargs(tparams, FunargTparams)
+	ft.Params = funargs(params, FunargParams)
+	ft.Results = funargs(results, FunargResults)
+	ft.pkg = pkg
+	if len(tparams) > 0 || fieldsHasTParam(recvs) || fieldsHasTParam(params) ||
+		fieldsHasTParam(results) {
+		t.SetHasTParam(true)
+	}
+
+	return t
+}
+
+// NewStruct returns a new struct with the given fields.
+func NewStruct(pkg *Pkg, fields []*Field) *Type {
+	t := New(TSTRUCT)
+	t.SetFields(fields)
+	if anyBroke(fields) {
+		t.SetBroke(true)
+	}
+	t.Extra.(*Struct).pkg = pkg
+	if fieldsHasTParam(fields) {
+		t.SetHasTParam(true)
+	}
+	return t
+}
+
+func anyBroke(fields []*Field) bool {
+	for _, f := range fields {
+		if f.Broke() {
+			return true
+		}
+	}
+	return false
+}
+
+var (
+	IsInt     [NTYPE]bool
+	IsFloat   [NTYPE]bool
+	IsComplex [NTYPE]bool
+	IsSimple  [NTYPE]bool
+)
+
+var IsOrdered [NTYPE]bool
+
+// IsReflexive reports whether t has a reflexive equality operator.
+// That is, if x==x for all x of type t.
+func IsReflexive(t *Type) bool {
+	switch t.Kind() {
+	case TBOOL,
+		TINT,
+		TUINT,
+		TINT8,
+		TUINT8,
+		TINT16,
+		TUINT16,
+		TINT32,
+		TUINT32,
+		TINT64,
+		TUINT64,
+		TUINTPTR,
+		TPTR,
+		TUNSAFEPTR,
+		TSTRING,
+		TCHAN:
+		return true
+
+	case TFLOAT32,
+		TFLOAT64,
+		TCOMPLEX64,
+		TCOMPLEX128,
+		TINTER:
+		return false
+
+	case TARRAY:
+		return IsReflexive(t.Elem())
+
+	case TSTRUCT:
+		for _, t1 := range t.Fields().Slice() {
+			if !IsReflexive(t1.Type) {
+				return false
+			}
+		}
+		return true
+
+	default:
+		base.Fatalf("bad type for map key: %v", t)
+		return false
+	}
+}
+
+// Can this type be stored directly in an interface word?
+// Yes, if the representation is a single pointer.
+func IsDirectIface(t *Type) bool {
+	if t.Broke() {
+		return false
+	}
+
+	switch t.Kind() {
+	case TPTR:
+		// Pointers to notinheap types must be stored indirectly. See issue 42076.
+		return !t.Elem().NotInHeap()
+	case TCHAN,
+		TMAP,
+		TFUNC,
+		TUNSAFEPTR:
+		return true
+
+	case TARRAY:
+		// Array of 1 direct iface type can be direct.
+		return t.NumElem() == 1 && IsDirectIface(t.Elem())
+
+	case TSTRUCT:
+		// Struct with 1 field of direct iface type can be direct.
+		return t.NumFields() == 1 && IsDirectIface(t.Field(0).Type)
+	}
+
+	return false
+}
+
+// IsInterfaceMethod reports whether (field) m is
+// an interface method. Such methods have the
+// special receiver type types.FakeRecvType().
+func IsInterfaceMethod(f *Type) bool {
+	return f.Recv().Type == FakeRecvType()
+}
+
+// IsMethodApplicable reports whether method m can be called on a
+// value of type t. This is necessary because we compute a single
+// method set for both T and *T, but some *T methods are not
+// applicable to T receivers.
+func IsMethodApplicable(t *Type, m *Field) bool {
+	return t.IsPtr() || !m.Type.Recv().Type.IsPtr() || IsInterfaceMethod(m.Type) || m.Embedded == 2
+}
+
+// IsRuntimePkg reports whether p is package runtime.
+func IsRuntimePkg(p *Pkg) bool {
+	if base.Flag.CompilingRuntime && p == LocalPkg {
+		return true
+	}
+	return p.Path == "runtime"
+}
+
+// IsReflectPkg reports whether p is package reflect.
+func IsReflectPkg(p *Pkg) bool {
+	if p == LocalPkg {
+		return base.Ctxt.Pkgpath == "reflect"
+	}
+	return p.Path == "reflect"
+}
+
+// ReceiverBaseType returns the underlying type, if any,
+// that owns methods with receiver parameter t.
+// The result is either a named type or an anonymous struct.
+func ReceiverBaseType(t *Type) *Type {
+	if t == nil {
+		return nil
+	}
+
+	// Strip away pointer if it's there.
+	if t.IsPtr() {
+		if t.Sym() != nil {
+			return nil
+		}
+		t = t.Elem()
+		if t == nil {
+			return nil
+		}
+	}
+
+	// Must be a named type or anonymous struct.
+	if t.Sym() == nil && !t.IsStruct() {
+		return nil
+	}
+
+	// Check types.
+	if IsSimple[t.Kind()] {
+		return t
+	}
+	switch t.Kind() {
+	case TARRAY, TCHAN, TFUNC, TMAP, TSLICE, TSTRING, TSTRUCT:
+		return t
+	}
+	return nil
+}
+
+func FloatForComplex(t *Type) *Type {
+	switch t.Kind() {
+	case TCOMPLEX64:
+		return Types[TFLOAT32]
+	case TCOMPLEX128:
+		return Types[TFLOAT64]
+	}
+	base.Fatalf("unexpected type: %v", t)
+	return nil
+}
+
+func ComplexForFloat(t *Type) *Type {
+	switch t.Kind() {
+	case TFLOAT32:
+		return Types[TCOMPLEX64]
+	case TFLOAT64:
+		return Types[TCOMPLEX128]
+	}
+	base.Fatalf("unexpected type: %v", t)
+	return nil
+}
+
+func TypeSym(t *Type) *Sym {
+	return TypeSymLookup(TypeSymName(t))
+}
+
+func TypeSymLookup(name string) *Sym {
+	typepkgmu.Lock()
+	s := typepkg.Lookup(name)
+	typepkgmu.Unlock()
+	return s
+}
+
+func TypeSymName(t *Type) string {
+	name := t.ShortString()
+	// Use a separate symbol name for Noalg types for #17752.
+	if TypeHasNoAlg(t) {
+		name = "noalg." + name
+	}
+	return name
+}
+
+// Fake package for runtime type info (headers)
+// Don't access directly, use typeLookup below.
+var (
+	typepkgmu sync.Mutex // protects typepkg lookups
+	typepkg   = NewPkg("type", "type")
+)
+
+var SimType [NTYPE]Kind
diff --git a/src/cmd/compile/internal/types/utils.go b/src/cmd/compile/internal/types/utils.go
index e8b1073..f9f629c 100644
--- a/src/cmd/compile/internal/types/utils.go
+++ b/src/cmd/compile/internal/types/utils.go
@@ -4,64 +4,8 @@
 
 package types
 
-import (
-	"cmd/internal/obj"
-	"fmt"
-)
-
 const BADWIDTH = -1000000000
 
-// The following variables must be initialized early by the frontend.
-// They are here to break import cycles.
-// TODO(gri) eliminate these dependencies.
-var (
-	Widthptr    int
-	Dowidth     func(*Type)
-	Fatalf      func(string, ...interface{})
-	Sconv       func(*Sym, int, int) string       // orig: func sconv(s *Sym, flag FmtFlag, mode fmtMode) string
-	Tconv       func(*Type, int, int) string      // orig: func tconv(t *Type, flag FmtFlag, mode fmtMode) string
-	FormatSym   func(*Sym, fmt.State, rune, int)  // orig: func symFormat(sym *Sym, s fmt.State, verb rune, mode fmtMode)
-	FormatType  func(*Type, fmt.State, rune, int) // orig: func typeFormat(t *Type, s fmt.State, verb rune, mode fmtMode)
-	TypeLinkSym func(*Type) *obj.LSym
-	Ctxt        *obj.Link
-
-	FmtLeft     int
-	FmtUnsigned int
-	FErr        int
-)
-
-func (s *Sym) String() string {
-	return Sconv(s, 0, FErr)
-}
-
-func (sym *Sym) Format(s fmt.State, verb rune) {
-	FormatSym(sym, s, verb, FErr)
-}
-
-func (t *Type) String() string {
-	// The implementation of tconv (including typefmt and fldconv)
-	// must handle recursive types correctly.
-	return Tconv(t, 0, FErr)
-}
-
-// ShortString generates a short description of t.
-// It is used in autogenerated method names, reflection,
-// and itab names.
-func (t *Type) ShortString() string {
-	return Tconv(t, FmtLeft, FErr)
-}
-
-// LongString generates a complete description of t.
-// It is useful for reflection,
-// or when a unique fingerprint or hash of a type is required.
-func (t *Type) LongString() string {
-	return Tconv(t, FmtLeft|FmtUnsigned, FErr)
-}
-
-func (t *Type) Format(s fmt.State, verb rune) {
-	FormatType(t, s, verb, FErr)
-}
-
 type bitset8 uint8
 
 func (f *bitset8) set(mask uint8, b bool) {
diff --git a/src/cmd/compile/internal/types2/api.go b/src/cmd/compile/internal/types2/api.go
new file mode 100644
index 0000000..2939dcc
--- /dev/null
+++ b/src/cmd/compile/internal/types2/api.go
@@ -0,0 +1,434 @@
+// 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 types declares the data types and implements
+// the algorithms for type-checking of Go packages. Use
+// Config.Check to invoke the type checker for a package.
+// Alternatively, create a new type checker with NewChecker
+// and invoke it incrementally by calling Checker.Files.
+//
+// Type-checking consists of several interdependent phases:
+//
+// Name resolution maps each identifier (syntax.Name) in the program to the
+// language object (Object) it denotes.
+// Use Info.{Defs,Uses,Implicits} for the results of name resolution.
+//
+// Constant folding computes the exact constant value (constant.Value)
+// for every expression (syntax.Expr) that is a compile-time constant.
+// Use Info.Types[expr].Value for the results of constant folding.
+//
+// Type inference computes the type (Type) of every expression (syntax.Expr)
+// and checks for compliance with the language specification.
+// Use Info.Types[expr].Type for the results of type inference.
+//
+package types2
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"go/constant"
+)
+
+// An Error describes a type-checking error; it implements the error interface.
+// A "soft" error is an error that still permits a valid interpretation of a
+// package (such as "unused variable"); "hard" errors may lead to unpredictable
+// behavior if ignored.
+type Error struct {
+	Pos  syntax.Pos // error position
+	Msg  string     // default error message, user-friendly
+	Full string     // full error message, for debugging (may contain internal details)
+	Soft bool       // if set, error is "soft"
+}
+
+// Error returns an error string formatted as follows:
+// filename:line:column: message
+func (err Error) Error() string {
+	return fmt.Sprintf("%s: %s", err.Pos, err.Msg)
+}
+
+// FullError returns an error string like Error, buy it may contain
+// type-checker internal details such as subscript indices for type
+// parameters and more. Useful for debugging.
+func (err Error) FullError() string {
+	return fmt.Sprintf("%s: %s", err.Pos, err.Full)
+}
+
+// An Importer resolves import paths to Packages.
+//
+// CAUTION: This interface does not support the import of locally
+// vendored packages. See https://golang.org/s/go15vendor.
+// If possible, external implementations should implement ImporterFrom.
+type Importer interface {
+	// Import returns the imported package for the given import path.
+	// The semantics is like for ImporterFrom.ImportFrom except that
+	// dir and mode are ignored (since they are not present).
+	Import(path string) (*Package, error)
+}
+
+// ImportMode is reserved for future use.
+type ImportMode int
+
+// An ImporterFrom resolves import paths to packages; it
+// supports vendoring per https://golang.org/s/go15vendor.
+// Use go/importer to obtain an ImporterFrom implementation.
+type ImporterFrom interface {
+	// Importer is present for backward-compatibility. Calling
+	// Import(path) is the same as calling ImportFrom(path, "", 0);
+	// i.e., locally vendored packages may not be found.
+	// The types package does not call Import if an ImporterFrom
+	// is present.
+	Importer
+
+	// ImportFrom returns the imported package for the given import
+	// path when imported by a package file located in dir.
+	// If the import failed, besides returning an error, ImportFrom
+	// is encouraged to cache and return a package anyway, if one
+	// was created. This will reduce package inconsistencies and
+	// follow-on type checker errors due to the missing package.
+	// The mode value must be 0; it is reserved for future use.
+	// Two calls to ImportFrom with the same path and dir must
+	// return the same package.
+	ImportFrom(path, dir string, mode ImportMode) (*Package, error)
+}
+
+// A Config specifies the configuration for type checking.
+// The zero value for Config is a ready-to-use default configuration.
+type Config struct {
+	// GoVersion describes the accepted Go language version. The string
+	// must follow the format "go%d.%d" (e.g. "go1.12") or ist must be
+	// empty; an empty string indicates the latest language version.
+	// If the format is invalid, invoking the type checker will cause a
+	// panic.
+	GoVersion string
+
+	// If IgnoreFuncBodies is set, function bodies are not
+	// type-checked.
+	IgnoreFuncBodies bool
+
+	// If FakeImportC is set, `import "C"` (for packages requiring Cgo)
+	// declares an empty "C" package and errors are omitted for qualified
+	// identifiers referring to package C (which won't find an object).
+	// This feature is intended for the standard library cmd/api tool.
+	//
+	// Caution: Effects may be unpredictable due to follow-on errors.
+	//          Do not use casually!
+	FakeImportC bool
+
+	// If IgnoreLabels is set, correct label use is not checked.
+	// TODO(gri) Consolidate label checking and remove this flag.
+	IgnoreLabels bool
+
+	// If CompilerErrorMessages is set, errors are reported using
+	// cmd/compile error strings to match $GOROOT/test errors.
+	// TODO(gri) Consolidate error messages and remove this flag.
+	CompilerErrorMessages bool
+
+	// If go115UsesCgo is set, the type checker expects the
+	// _cgo_gotypes.go file generated by running cmd/cgo to be
+	// provided as a package source file. Qualified identifiers
+	// referring to package C will be resolved to cgo-provided
+	// declarations within _cgo_gotypes.go.
+	//
+	// It is an error to set both FakeImportC and go115UsesCgo.
+	go115UsesCgo bool
+
+	// If Trace is set, a debug trace is printed to stdout.
+	Trace bool
+
+	// If Error != nil, it is called with each error found
+	// during type checking; err has dynamic type Error.
+	// Secondary errors (for instance, to enumerate all types
+	// involved in an invalid recursive type declaration) have
+	// error strings that start with a '\t' character.
+	// If Error == nil, type-checking stops with the first
+	// error found.
+	Error func(err error)
+
+	// An importer is used to import packages referred to from
+	// import declarations.
+	// If the installed importer implements ImporterFrom, the type
+	// checker calls ImportFrom instead of Import.
+	// The type checker reports an error if an importer is needed
+	// but none was installed.
+	Importer Importer
+
+	// If Sizes != nil, it provides the sizing functions for package unsafe.
+	// Otherwise SizesFor("gc", "amd64") is used instead.
+	Sizes Sizes
+
+	// If DisableUnusedImportCheck is set, packages are not checked
+	// for unused imports.
+	DisableUnusedImportCheck bool
+}
+
+func srcimporter_setUsesCgo(conf *Config) {
+	conf.go115UsesCgo = true
+}
+
+// Info holds result type information for a type-checked package.
+// Only the information for which a map is provided is collected.
+// If the package has type errors, the collected information may
+// be incomplete.
+type Info struct {
+	// Types maps expressions to their types, and for constant
+	// expressions, also their values. Invalid expressions are
+	// omitted.
+	//
+	// For (possibly parenthesized) identifiers denoting built-in
+	// functions, the recorded signatures are call-site specific:
+	// if the call result is not a constant, the recorded type is
+	// an argument-specific signature. Otherwise, the recorded type
+	// is invalid.
+	//
+	// The Types map does not record the type of every identifier,
+	// only those that appear where an arbitrary expression is
+	// permitted. For instance, the identifier f in a selector
+	// expression x.f is found only in the Selections map, the
+	// identifier z in a variable declaration 'var z int' is found
+	// only in the Defs map, and identifiers denoting packages in
+	// qualified identifiers are collected in the Uses map.
+	Types map[syntax.Expr]TypeAndValue
+
+	// Inferred maps calls of parameterized functions that use
+	// type inference to the inferred type arguments and signature
+	// of the function called. The recorded "call" expression may be
+	// an *ast.CallExpr (as in f(x)), or an *ast.IndexExpr (s in f[T]).
+	Inferred map[syntax.Expr]Inferred
+
+	// Defs maps identifiers to the objects they define (including
+	// package names, dots "." of dot-imports, and blank "_" identifiers).
+	// For identifiers that do not denote objects (e.g., the package name
+	// in package clauses, or symbolic variables t in t := x.(type) of
+	// type switch headers), the corresponding objects are nil.
+	//
+	// For an embedded field, Defs returns the field *Var it defines.
+	//
+	// Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos()
+	Defs map[*syntax.Name]Object
+
+	// Uses maps identifiers to the objects they denote.
+	//
+	// For an embedded field, Uses returns the *TypeName it denotes.
+	//
+	// Invariant: Uses[id].Pos() != id.Pos()
+	Uses map[*syntax.Name]Object
+
+	// Implicits maps nodes to their implicitly declared objects, if any.
+	// The following node and object types may appear:
+	//
+	//     node               declared object
+	//
+	//     *syntax.ImportDecl    *PkgName for imports without renames
+	//     *syntax.CaseClause    type-specific *Var for each type switch case clause (incl. default)
+	//     *syntax.Field         anonymous parameter *Var (incl. unnamed results)
+	//
+	Implicits map[syntax.Node]Object
+
+	// Selections maps selector expressions (excluding qualified identifiers)
+	// to their corresponding selections.
+	Selections map[*syntax.SelectorExpr]*Selection
+
+	// Scopes maps syntax.Nodes to the scopes they define. Package scopes are not
+	// associated with a specific node but with all files belonging to a package.
+	// Thus, the package scope can be found in the type-checked Package object.
+	// Scopes nest, with the Universe scope being the outermost scope, enclosing
+	// the package scope, which contains (one or more) files scopes, which enclose
+	// function scopes which in turn enclose statement and function literal scopes.
+	// Note that even though package-level functions are declared in the package
+	// scope, the function scopes are embedded in the file scope of the file
+	// containing the function declaration.
+	//
+	// The following node types may appear in Scopes:
+	//
+	//     *syntax.File
+	//     *syntax.FuncType
+	//     *syntax.BlockStmt
+	//     *syntax.IfStmt
+	//     *syntax.SwitchStmt
+	//     *syntax.CaseClause
+	//     *syntax.CommClause
+	//     *syntax.ForStmt
+	//
+	Scopes map[syntax.Node]*Scope
+
+	// InitOrder is the list of package-level initializers in the order in which
+	// they must be executed. Initializers referring to variables related by an
+	// initialization dependency appear in topological order, the others appear
+	// in source order. Variables without an initialization expression do not
+	// appear in this list.
+	InitOrder []*Initializer
+}
+
+// TypeOf returns the type of expression e, or nil if not found.
+// Precondition: the Types, Uses and Defs maps are populated.
+//
+func (info *Info) TypeOf(e syntax.Expr) Type {
+	if t, ok := info.Types[e]; ok {
+		return t.Type
+	}
+	if id, _ := e.(*syntax.Name); id != nil {
+		if obj := info.ObjectOf(id); obj != nil {
+			return obj.Type()
+		}
+	}
+	return nil
+}
+
+// ObjectOf returns the object denoted by the specified id,
+// or nil if not found.
+//
+// If id is an embedded struct field, ObjectOf returns the field (*Var)
+// it defines, not the type (*TypeName) it uses.
+//
+// Precondition: the Uses and Defs maps are populated.
+//
+func (info *Info) ObjectOf(id *syntax.Name) Object {
+	if obj := info.Defs[id]; obj != nil {
+		return obj
+	}
+	return info.Uses[id]
+}
+
+// TypeAndValue reports the type and value (for constants)
+// of the corresponding expression.
+type TypeAndValue struct {
+	mode  operandMode
+	Type  Type
+	Value constant.Value
+}
+
+// IsVoid reports whether the corresponding expression
+// is a function call without results.
+func (tv TypeAndValue) IsVoid() bool {
+	return tv.mode == novalue
+}
+
+// IsType reports whether the corresponding expression specifies a type.
+func (tv TypeAndValue) IsType() bool {
+	return tv.mode == typexpr
+}
+
+// IsBuiltin reports whether the corresponding expression denotes
+// a (possibly parenthesized) built-in function.
+func (tv TypeAndValue) IsBuiltin() bool {
+	return tv.mode == builtin
+}
+
+// IsValue reports whether the corresponding expression is a value.
+// Builtins are not considered values. Constant values have a non-
+// nil Value.
+func (tv TypeAndValue) IsValue() bool {
+	switch tv.mode {
+	case constant_, variable, mapindex, value, nilvalue, commaok, commaerr:
+		return true
+	}
+	return false
+}
+
+// IsNil reports whether the corresponding expression denotes the
+// predeclared value nil. Depending on context, it may have been
+// given a type different from UntypedNil.
+func (tv TypeAndValue) IsNil() bool {
+	return tv.mode == nilvalue
+}
+
+// Addressable reports whether the corresponding expression
+// is addressable (https://golang.org/ref/spec#Address_operators).
+func (tv TypeAndValue) Addressable() bool {
+	return tv.mode == variable
+}
+
+// Assignable reports whether the corresponding expression
+// is assignable to (provided a value of the right type).
+func (tv TypeAndValue) Assignable() bool {
+	return tv.mode == variable || tv.mode == mapindex
+}
+
+// HasOk reports whether the corresponding expression may be
+// used on the rhs of a comma-ok assignment.
+func (tv TypeAndValue) HasOk() bool {
+	return tv.mode == commaok || tv.mode == mapindex
+}
+
+// Inferred reports the inferred type arguments and signature
+// for a parameterized function call that uses type inference.
+type Inferred struct {
+	Targs []Type
+	Sig   *Signature
+}
+
+// An Initializer describes a package-level variable, or a list of variables in case
+// of a multi-valued initialization expression, and the corresponding initialization
+// expression.
+type Initializer struct {
+	Lhs []*Var // var Lhs = Rhs
+	Rhs syntax.Expr
+}
+
+func (init *Initializer) String() string {
+	var buf bytes.Buffer
+	for i, lhs := range init.Lhs {
+		if i > 0 {
+			buf.WriteString(", ")
+		}
+		buf.WriteString(lhs.Name())
+	}
+	buf.WriteString(" = ")
+	syntax.Fprint(&buf, init.Rhs, syntax.ShortForm)
+	return buf.String()
+}
+
+// Check type-checks a package and returns the resulting package object and
+// the first error if any. Additionally, if info != nil, Check populates each
+// of the non-nil maps in the Info struct.
+//
+// The package is marked as complete if no errors occurred, otherwise it is
+// incomplete. See Config.Error for controlling behavior in the presence of
+// errors.
+//
+// The package is specified by a list of *syntax.Files and corresponding
+// file set, and the package path the package is identified with.
+// The clean path must not be empty or dot (".").
+func (conf *Config) Check(path string, files []*syntax.File, info *Info) (*Package, error) {
+	pkg := NewPackage(path, "")
+	return pkg, NewChecker(conf, pkg, info).Files(files)
+}
+
+// AssertableTo reports whether a value of type V can be asserted to have type T.
+func AssertableTo(V *Interface, T Type) bool {
+	m, _ := (*Checker)(nil).assertableTo(V, T)
+	return m == nil
+}
+
+// AssignableTo reports whether a value of type V is assignable to a variable of type T.
+func AssignableTo(V, T Type) bool {
+	x := operand{mode: value, typ: V}
+	ok, _ := x.assignableTo(nil, T, nil) // check not needed for non-constant x
+	return ok
+}
+
+// ConvertibleTo reports whether a value of type V is convertible to a value of type T.
+func ConvertibleTo(V, T Type) bool {
+	x := operand{mode: value, typ: V}
+	return x.convertibleTo(nil, T) // check not needed for non-constant x
+}
+
+// Implements reports whether type V implements interface T.
+func Implements(V Type, T *Interface) bool {
+	f, _ := MissingMethod(V, T, true)
+	return f == nil
+}
+
+// Identical reports whether x and y are identical types.
+// Receivers of Signature types are ignored.
+func Identical(x, y Type) bool {
+	return (*Checker)(nil).identical(x, y)
+}
+
+// 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 (*Checker)(nil).identicalIgnoreTags(x, y)
+}
diff --git a/src/cmd/compile/internal/types2/api_test.go b/src/cmd/compile/internal/types2/api_test.go
new file mode 100644
index 0000000..873390c
--- /dev/null
+++ b/src/cmd/compile/internal/types2/api_test.go
@@ -0,0 +1,1849 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2_test
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"internal/testenv"
+	"reflect"
+	"regexp"
+	"strings"
+	"testing"
+
+	. "cmd/compile/internal/types2"
+)
+
+func unimplemented() {
+	panic("unimplemented")
+}
+
+// genericPkg is a source prefix for packages that contain generic code.
+const genericPkg = "package generic_"
+
+// brokenPkg is a source prefix for packages that are not expected to parse
+// or type-check cleanly. They are always parsed assuming that they contain
+// generic code.
+const brokenPkg = "package broken_"
+
+func parseSrc(path, src string) (*syntax.File, error) {
+	var mode syntax.Mode
+	if strings.HasPrefix(src, genericPkg) || strings.HasPrefix(src, brokenPkg) {
+		mode = syntax.AllowGenerics
+	}
+	errh := func(error) {} // dummy error handler so that parsing continues in presence of errors
+	return syntax.Parse(syntax.NewFileBase(path), strings.NewReader(src), errh, nil, mode)
+}
+
+func pkgFor(path, source string, info *Info) (*Package, error) {
+	f, err := parseSrc(path, source)
+	if err != nil {
+		return nil, err
+	}
+	conf := Config{Importer: defaultImporter()}
+	return conf.Check(f.PkgName.Value, []*syntax.File{f}, info)
+}
+
+func mustTypecheck(t *testing.T, path, source string, info *Info) string {
+	pkg, err := pkgFor(path, source, info)
+	if err != nil {
+		name := path
+		if pkg != nil {
+			name = "package " + pkg.Name()
+		}
+		t.Fatalf("%s: didn't type-check (%s)", name, err)
+	}
+	return pkg.Name()
+}
+
+func mayTypecheck(t *testing.T, path, source string, info *Info) (string, error) {
+	f, err := parseSrc(path, source)
+	if f == nil { // ignore errors unless f is nil
+		t.Fatalf("%s: unable to parse: %s", path, err)
+	}
+	conf := Config{
+		Error:    func(err error) {},
+		Importer: defaultImporter(),
+	}
+	pkg, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, info)
+	return pkg.Name(), err
+}
+
+func TestValuesInfo(t *testing.T) {
+	var tests = []struct {
+		src  string
+		expr string // constant expression
+		typ  string // constant type
+		val  string // constant value
+	}{
+		{`package a0; const _ = false`, `false`, `untyped bool`, `false`},
+		{`package a1; const _ = 0`, `0`, `untyped int`, `0`},
+		{`package a2; const _ = 'A'`, `'A'`, `untyped rune`, `65`},
+		{`package a3; const _ = 0.`, `0.`, `untyped float`, `0`},
+		{`package a4; const _ = 0i`, `0i`, `untyped complex`, `(0 + 0i)`},
+		{`package a5; const _ = "foo"`, `"foo"`, `untyped string`, `"foo"`},
+
+		{`package b0; var _ = false`, `false`, `bool`, `false`},
+		{`package b1; var _ = 0`, `0`, `int`, `0`},
+		{`package b2; var _ = 'A'`, `'A'`, `rune`, `65`},
+		{`package b3; var _ = 0.`, `0.`, `float64`, `0`},
+		{`package b4; var _ = 0i`, `0i`, `complex128`, `(0 + 0i)`},
+		{`package b5; var _ = "foo"`, `"foo"`, `string`, `"foo"`},
+
+		{`package c0a; var _ = bool(false)`, `false`, `bool`, `false`},
+		{`package c0b; var _ = bool(false)`, `bool(false)`, `bool`, `false`},
+		{`package c0c; type T bool; var _ = T(false)`, `T(false)`, `c0c.T`, `false`},
+
+		{`package c1a; var _ = int(0)`, `0`, `int`, `0`},
+		{`package c1b; var _ = int(0)`, `int(0)`, `int`, `0`},
+		{`package c1c; type T int; var _ = T(0)`, `T(0)`, `c1c.T`, `0`},
+
+		{`package c2a; var _ = rune('A')`, `'A'`, `rune`, `65`},
+		{`package c2b; var _ = rune('A')`, `rune('A')`, `rune`, `65`},
+		{`package c2c; type T rune; var _ = T('A')`, `T('A')`, `c2c.T`, `65`},
+
+		{`package c3a; var _ = float32(0.)`, `0.`, `float32`, `0`},
+		{`package c3b; var _ = float32(0.)`, `float32(0.)`, `float32`, `0`},
+		{`package c3c; type T float32; var _ = T(0.)`, `T(0.)`, `c3c.T`, `0`},
+
+		{`package c4a; var _ = complex64(0i)`, `0i`, `complex64`, `(0 + 0i)`},
+		{`package c4b; var _ = complex64(0i)`, `complex64(0i)`, `complex64`, `(0 + 0i)`},
+		{`package c4c; type T complex64; var _ = T(0i)`, `T(0i)`, `c4c.T`, `(0 + 0i)`},
+
+		{`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"`},
+		{`package d2; var _ = []byte(string("foo"))`, `string("foo")`, `string`, `"foo"`},
+		{`package d3; type T []byte; var _ = T("foo")`, `"foo"`, `string`, `"foo"`},
+
+		{`package e0; const _ = float32( 1e-200)`, `float32(1e-200)`, `float32`, `0`},
+		{`package e1; const _ = float32(-1e-200)`, `float32(-1e-200)`, `float32`, `0`},
+		{`package e2; const _ = float64( 1e-2000)`, `float64(1e-2000)`, `float64`, `0`},
+		{`package e3; const _ = float64(-1e-2000)`, `float64(-1e-2000)`, `float64`, `0`},
+		{`package e4; const _ = complex64( 1e-200)`, `complex64(1e-200)`, `complex64`, `(0 + 0i)`},
+		{`package e5; const _ = complex64(-1e-200)`, `complex64(-1e-200)`, `complex64`, `(0 + 0i)`},
+		{`package e6; const _ = complex128( 1e-2000)`, `complex128(1e-2000)`, `complex128`, `(0 + 0i)`},
+		{`package e7; const _ = complex128(-1e-2000)`, `complex128(-1e-2000)`, `complex128`, `(0 + 0i)`},
+
+		{`package f0 ; var _ float32 =  1e-200`, `1e-200`, `float32`, `0`},
+		{`package f1 ; var _ float32 = -1e-200`, `-1e-200`, `float32`, `0`},
+		{`package f2a; var _ float64 =  1e-2000`, `1e-2000`, `float64`, `0`},
+		{`package f3a; var _ float64 = -1e-2000`, `-1e-2000`, `float64`, `0`},
+		{`package f2b; var _         =  1e-2000`, `1e-2000`, `float64`, `0`},
+		{`package f3b; var _         = -1e-2000`, `-1e-2000`, `float64`, `0`},
+		{`package f4 ; var _ complex64  =  1e-200 `, `1e-200`, `complex64`, `(0 + 0i)`},
+		{`package f5 ; var _ complex64  = -1e-200 `, `-1e-200`, `complex64`, `(0 + 0i)`},
+		{`package f6a; var _ complex128 =  1e-2000i`, `1e-2000i`, `complex128`, `(0 + 0i)`},
+		{`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 {
+		info := Info{
+			Types: make(map[syntax.Expr]TypeAndValue),
+		}
+		name := mustTypecheck(t, "ValuesInfo", test.src, &info)
+
+		// look for expression
+		var expr syntax.Expr
+		for e := range info.Types {
+			if syntax.String(e) == test.expr {
+				expr = e
+				break
+			}
+		}
+		if expr == nil {
+			t.Errorf("package %s: no expression found for %s", name, test.expr)
+			continue
+		}
+		tv := info.Types[expr]
+
+		// check that type is correct
+		if got := tv.Type.String(); got != test.typ {
+			t.Errorf("package %s: got type %s; want %s", name, got, test.typ)
+			continue
+		}
+
+		// 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)
+			}
+		}
+	}
+}
+
+func TestTypesInfo(t *testing.T) {
+	var tests = []struct {
+		src  string
+		expr string // expression
+		typ  string // value type
+	}{
+		// single-valued expressions of untyped constants
+		{`package b0; var x interface{} = false`, `false`, `bool`},
+		{`package b1; var x interface{} = 0`, `0`, `int`},
+		{`package b2; var x interface{} = 0.`, `0.`, `float64`},
+		{`package b3; var x interface{} = 0i`, `0i`, `complex128`},
+		{`package b4; var x interface{} = "foo"`, `"foo"`, `string`},
+
+		// uses of nil
+		{`package n0; var _ *int = nil`, `nil`, `*int`},
+		{`package n1; var _ func() = nil`, `nil`, `func()`},
+		{`package n2; var _ []byte = nil`, `nil`, `[]byte`},
+		{`package n3; var _ map[int]int = nil`, `nil`, `map[int]int`},
+		{`package n4; var _ chan int = nil`, `nil`, `chan int`},
+		{`package n5a; var _ interface{} = (*int)(nil)`, `nil`, `*int`},
+		{`package n5b; var _ interface{m()} = nil`, `nil`, `interface{m()}`},
+		{`package n6; import "unsafe"; var _ unsafe.Pointer = nil`, `nil`, `unsafe.Pointer`},
+
+		{`package n10; var (x *int; _ = x == nil)`, `nil`, `*int`},
+		{`package n11; var (x func(); _ = x == nil)`, `nil`, `func()`},
+		{`package n12; var (x []byte; _ = x == nil)`, `nil`, `[]byte`},
+		{`package n13; var (x map[int]int; _ = x == nil)`, `nil`, `map[int]int`},
+		{`package n14; var (x chan int; _ = x == nil)`, `nil`, `chan int`},
+		{`package n15a; var (x interface{}; _ = x == (*int)(nil))`, `nil`, `*int`},
+		{`package n15b; var (x interface{m()}; _ = x == nil)`, `nil`, `interface{m()}`},
+		{`package n15; import "unsafe"; var (x unsafe.Pointer; _ = x == nil)`, `nil`, `unsafe.Pointer`},
+
+		{`package n20; var _ = (*int)(nil)`, `nil`, `*int`},
+		{`package n21; var _ = (func())(nil)`, `nil`, `func()`},
+		{`package n22; var _ = ([]byte)(nil)`, `nil`, `[]byte`},
+		{`package n23; var _ = (map[int]int)(nil)`, `nil`, `map[int]int`},
+		{`package n24; var _ = (chan int)(nil)`, `nil`, `chan int`},
+		{`package n25a; var _ = (interface{})((*int)(nil))`, `nil`, `*int`},
+		{`package n25b; var _ = (interface{m()})(nil)`, `nil`, `interface{m()}`},
+		{`package n26; import "unsafe"; var _ = unsafe.Pointer(nil)`, `nil`, `unsafe.Pointer`},
+
+		{`package n30; func f(*int) { f(nil) }`, `nil`, `*int`},
+		{`package n31; func f(func()) { f(nil) }`, `nil`, `func()`},
+		{`package n32; func f([]byte) { f(nil) }`, `nil`, `[]byte`},
+		{`package n33; func f(map[int]int) { f(nil) }`, `nil`, `map[int]int`},
+		{`package n34; func f(chan int) { f(nil) }`, `nil`, `chan int`},
+		{`package n35a; func f(interface{}) { f((*int)(nil)) }`, `nil`, `*int`},
+		{`package n35b; func f(interface{m()}) { f(nil) }`, `nil`, `interface{m()}`},
+		{`package n35; import "unsafe"; func f(unsafe.Pointer) { f(nil) }`, `nil`, `unsafe.Pointer`},
+
+		// comma-ok expressions
+		{`package p0; var x interface{}; var _, _ = x.(int)`,
+			`x.(int)`,
+			`(int, bool)`,
+		},
+		{`package p1; var x interface{}; func _() { _, _ = x.(int) }`,
+			`x.(int)`,
+			`(int, bool)`,
+		},
+		{`package p2a; type mybool bool; var m map[string]complex128; var b mybool; func _() { _, b = m["foo"] }`,
+			`m["foo"]`,
+			`(complex128, p2a.mybool)`,
+		},
+		{`package p2b; var m map[string]complex128; var b bool; func _() { _, b = m["foo"] }`,
+			`m["foo"]`,
+			`(complex128, bool)`,
+		},
+		{`package p3; var c chan string; var _, _ = <-c`,
+			`<-c`,
+			`(string, bool)`,
+		},
+
+		// issue 6796
+		{`package issue6796_a; var x interface{}; var _, _ = (x.(int))`,
+			`x.(int)`,
+			`(int, bool)`,
+		},
+		{`package issue6796_b; var c chan string; var _, _ = (<-c)`,
+			`(<-c)`,
+			`(string, bool)`,
+		},
+		{`package issue6796_c; var c chan string; var _, _ = (<-c)`,
+			`<-c`,
+			`(string, bool)`,
+		},
+		{`package issue6796_d; var c chan string; var _, _ = ((<-c))`,
+			`(<-c)`,
+			`(string, bool)`,
+		},
+		{`package issue6796_e; func f(c chan string) { _, _ = ((<-c)) }`,
+			`(<-c)`,
+			`(string, bool)`,
+		},
+
+		// issue 7060
+		{`package issue7060_a; var ( m map[int]string; x, ok = m[0] )`,
+			`m[0]`,
+			`(string, bool)`,
+		},
+		{`package issue7060_b; var ( m map[int]string; x, ok interface{} = m[0] )`,
+			`m[0]`,
+			`(string, bool)`,
+		},
+		{`package issue7060_c; func f(x interface{}, ok bool, m map[int]string) { x, ok = m[0] }`,
+			`m[0]`,
+			`(string, bool)`,
+		},
+		{`package issue7060_d; var ( ch chan string; x, ok = <-ch )`,
+			`<-ch`,
+			`(string, bool)`,
+		},
+		{`package issue7060_e; var ( ch chan string; x, ok interface{} = <-ch )`,
+			`<-ch`,
+			`(string, bool)`,
+		},
+		{`package issue7060_f; func f(x interface{}, ok bool, ch chan string) { x, ok = <-ch }`,
+			`<-ch`,
+			`(string, bool)`,
+		},
+
+		// issue 28277
+		{`package issue28277_a; func f(...int)`,
+			`...int`,
+			`[]int`,
+		},
+		{`package issue28277_b; func f(a, b int, c ...[]struct{})`,
+			`...[]struct{}`,
+			`[][]struct{}`,
+		},
+
+		// tests for broken code that doesn't parse or type-check
+		{brokenPkg + `x0; func _() { var x struct {f string}; x.f := 0 }`, `x.f`, `string`},
+		{brokenPkg + `x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}`, `z`, `string`},
+		{brokenPkg + `x2; func _() { var a, b string; type x struct {f string}; z := &x{f: a, f: b,}}`, `b`, `string`},
+		{brokenPkg + `x3; var x = panic("");`, `panic`, `func(interface{})`},
+		{`package x4; func _() { panic("") }`, `panic`, `func(interface{})`},
+		{brokenPkg + `x5; func _() { var x map[string][...]int; x = map[string][...]int{"": {1,2,3}} }`, `x`, `map[string]invalid type`},
+
+		// parameterized functions
+		{genericPkg + `p0; func f[T any](T); var _ = f[int]`, `f`, `func[T₁ interface{}](T₁)`},
+		{genericPkg + `p1; func f[T any](T); var _ = f[int]`, `f[int]`, `func(int)`},
+		{genericPkg + `p2; func f[T any](T); func _() { f(42) }`, `f`, `func[T₁ interface{}](T₁)`},
+		{genericPkg + `p3; func f[T any](T); func _() { f(42) }`, `f(42)`, `()`},
+
+		// type parameters
+		{genericPkg + `t0; type t[] int; var _ t`, `t`, `generic_t0.t`}, // t[] is a syntax error that is ignored in this test in favor of t
+		{genericPkg + `t1; type t[P any] int; var _ t[int]`, `t`, `generic_t1.t[P₁ interface{}]`},
+		{genericPkg + `t2; type t[P interface{}] int; var _ t[int]`, `t`, `generic_t2.t[P₁ interface{}]`},
+		{genericPkg + `t3; type t[P, Q interface{}] int; var _ t[int, int]`, `t`, `generic_t3.t[P₁, Q₂ interface{}]`},
+		{brokenPkg + `t4; type t[P, Q interface{ m() }] int; var _ t[int, int]`, `t`, `broken_t4.t[P₁, Q₂ interface{m()}]`},
+
+		// instantiated types must be sanitized
+		{genericPkg + `g0; type t[P any] int; var x struct{ f t[int] }; var _ = x.f`, `x.f`, `generic_g0.t[int]`},
+
+		// issue 45096
+		{genericPkg + `issue45096; func _[T interface{ type int8, int16, int32  }](x T) { _ = x < 0 }`, `0`, `T₁`},
+	}
+
+	for _, test := range tests {
+		ResetId() // avoid renumbering of type parameter ids when adding tests
+		info := Info{Types: make(map[syntax.Expr]TypeAndValue)}
+		var name string
+		if strings.HasPrefix(test.src, brokenPkg) {
+			var err error
+			name, err = mayTypecheck(t, "TypesInfo", test.src, &info)
+			if err == nil {
+				t.Errorf("package %s: expected to fail but passed", name)
+				continue
+			}
+		} else {
+			name = mustTypecheck(t, "TypesInfo", test.src, &info)
+		}
+
+		// look for expression type
+		var typ Type
+		for e, tv := range info.Types {
+			if syntax.String(e) == test.expr {
+				typ = tv.Type
+				break
+			}
+		}
+		if typ == nil {
+			t.Errorf("package %s: no type found for %s", name, test.expr)
+			continue
+		}
+
+		// check that type is correct
+		if got := typ.String(); got != test.typ {
+			t.Errorf("package %s: got %s; want %s", name, got, test.typ)
+		}
+	}
+}
+
+func TestInferredInfo(t *testing.T) {
+	var tests = []struct {
+		src   string
+		fun   string
+		targs []string
+		sig   string
+	}{
+		{genericPkg + `p0; func f[T any](T); func _() { f(42) }`,
+			`f`,
+			[]string{`int`},
+			`func(int)`,
+		},
+		{genericPkg + `p1; func f[T any](T) T; func _() { f('@') }`,
+			`f`,
+			[]string{`rune`},
+			`func(rune) rune`,
+		},
+		{genericPkg + `p2; func f[T any](...T) T; func _() { f(0i) }`,
+			`f`,
+			[]string{`complex128`},
+			`func(...complex128) complex128`,
+		},
+		{genericPkg + `p3; func f[A, B, C any](A, *B, []C); func _() { f(1.2, new(string), []byte{}) }`,
+			`f`,
+			[]string{`float64`, `string`, `byte`},
+			`func(float64, *string, []byte)`,
+		},
+		{genericPkg + `p4; func f[A, B any](A, *B, ...[]B); func _() { f(1.2, new(byte)) }`,
+			`f`,
+			[]string{`float64`, `byte`},
+			`func(float64, *byte, ...[]byte)`,
+		},
+
+		// we don't know how to translate these but we can type-check them
+		{genericPkg + `q0; type T struct{}; func (T) m[P any](P); func _(x T) { x.m(42) }`,
+			`x.m`,
+			[]string{`int`},
+			`func(int)`,
+		},
+		{genericPkg + `q1; type T struct{}; func (T) m[P any](P) P; func _(x T) { x.m(42) }`,
+			`x.m`,
+			[]string{`int`},
+			`func(int) int`,
+		},
+		{genericPkg + `q2; type T struct{}; func (T) m[P any](...P) P; func _(x T) { x.m(42) }`,
+			`x.m`,
+			[]string{`int`},
+			`func(...int) int`,
+		},
+		{genericPkg + `q3; type T struct{}; func (T) m[A, B, C any](A, *B, []C); func _(x T) { x.m(1.2, new(string), []byte{}) }`,
+			`x.m`,
+			[]string{`float64`, `string`, `byte`},
+			`func(float64, *string, []byte)`,
+		},
+		{genericPkg + `q4; type T struct{}; func (T) m[A, B any](A, *B, ...[]B); func _(x T) { x.m(1.2, new(byte)) }`,
+			`x.m`,
+			[]string{`float64`, `byte`},
+			`func(float64, *byte, ...[]byte)`,
+		},
+
+		{genericPkg + `r0; type T[P any] struct{}; func (_ T[P]) m[Q any](Q); func _[P any](x T[P]) { x.m(42) }`,
+			`x.m`,
+			[]string{`int`},
+			`func(int)`,
+		},
+		// TODO(gri) record method type parameters in syntax.FuncType so we can check this
+		// {genericPkg + `r1; type T interface{ m[P any](P) }; func _(x T) { x.m(4.2) }`,
+		// 	`x.m`,
+		// 	[]string{`float64`},
+		// 	`func(float64)`,
+		// },
+
+		{genericPkg + `s1; func f[T any, P interface{type *T}](x T); func _(x string) { f(x) }`,
+			`f`,
+			[]string{`string`, `*string`},
+			`func(x string)`,
+		},
+		{genericPkg + `s2; func f[T any, P interface{type *T}](x []T); func _(x []int) { f(x) }`,
+			`f`,
+			[]string{`int`, `*int`},
+			`func(x []int)`,
+		},
+		{genericPkg + `s3; type C[T any] interface{type chan<- T}; func f[T any, P C[T]](x []T); func _(x []int) { f(x) }`,
+			`f`,
+			[]string{`int`, `chan<- int`},
+			`func(x []int)`,
+		},
+		{genericPkg + `s4; type C[T any] interface{type chan<- T}; func f[T any, P C[T], Q C[[]*P]](x []T); func _(x []int) { f(x) }`,
+			`f`,
+			[]string{`int`, `chan<- int`, `chan<- []*chan<- int`},
+			`func(x []int)`,
+		},
+
+		{genericPkg + `t1; func f[T any, P interface{type *T}]() T; func _() { _ = f[string] }`,
+			`f`,
+			[]string{`string`, `*string`},
+			`func() string`,
+		},
+		{genericPkg + `t2; type C[T any] interface{type chan<- T}; func f[T any, P C[T]]() []T; func _() { _ = f[int] }`,
+			`f`,
+			[]string{`int`, `chan<- int`},
+			`func() []int`,
+		},
+		{genericPkg + `t3; type C[T any] interface{type chan<- T}; func f[T any, P C[T], Q C[[]*P]]() []T; func _() { _ = f[int] }`,
+			`f`,
+			[]string{`int`, `chan<- int`, `chan<- []*chan<- int`},
+			`func() []int`,
+		},
+	}
+
+	for _, test := range tests {
+		info := Info{Inferred: make(map[syntax.Expr]Inferred)}
+		name, err := mayTypecheck(t, "InferredInfo", test.src, &info)
+		if err != nil {
+			t.Errorf("package %s: %v", name, err)
+			continue
+		}
+
+		// look for inferred type arguments and signature
+		var targs []Type
+		var sig *Signature
+		for call, inf := range info.Inferred {
+			var fun syntax.Expr
+			switch x := call.(type) {
+			case *syntax.CallExpr:
+				fun = x.Fun
+			case *syntax.IndexExpr:
+				fun = x.X
+			default:
+				panic(fmt.Sprintf("unexpected call expression type %T", call))
+			}
+			if syntax.String(fun) == test.fun {
+				targs = inf.Targs
+				sig = inf.Sig
+				break
+			}
+		}
+		if targs == nil {
+			t.Errorf("package %s: no inferred information found for %s", name, test.fun)
+			continue
+		}
+
+		// check that type arguments are correct
+		if len(targs) != len(test.targs) {
+			t.Errorf("package %s: got %d type arguments; want %d", name, len(targs), len(test.targs))
+			continue
+		}
+		for i, targ := range targs {
+			if got := targ.String(); got != test.targs[i] {
+				t.Errorf("package %s, %d. type argument: got %s; want %s", name, i, got, test.targs[i])
+				continue
+			}
+		}
+
+		// check that signature is correct
+		if got := sig.String(); got != test.sig {
+			t.Errorf("package %s: got %s; want %s", name, got, test.sig)
+		}
+	}
+}
+
+func TestDefsInfo(t *testing.T) {
+	var tests = []struct {
+		src  string
+		obj  string
+		want string
+	}{
+		{`package p0; const x = 42`, `x`, `const p0.x untyped int`},
+		{`package p1; const x int = 42`, `x`, `const p1.x int`},
+		{`package p2; var x int`, `x`, `var p2.x int`},
+		{`package p3; type x int`, `x`, `type p3.x int`},
+		{`package p4; func f()`, `f`, `func p4.f()`},
+		{`package p5; func f() int { x, _ := 1, 2; return x }`, `_`, `var _ int`},
+
+		// generic types must be sanitized
+		// (need to use sufficiently nested types to provoke unexpanded types)
+		{genericPkg + `g0; type t[P any] P; const x = t[int](42)`, `x`, `const generic_g0.x generic_g0.t[int]`},
+		{genericPkg + `g1; type t[P any] P; var x = t[int](42)`, `x`, `var generic_g1.x generic_g1.t[int]`},
+		{genericPkg + `g2; type t[P any] P; type x struct{ f t[int] }`, `x`, `type generic_g2.x struct{f generic_g2.t[int]}`},
+		{genericPkg + `g3; type t[P any] P; func f(x struct{ f t[string] }); var g = f`, `g`, `var generic_g3.g func(x struct{f generic_g3.t[string]})`},
+	}
+
+	for _, test := range tests {
+		info := Info{
+			Defs: make(map[*syntax.Name]Object),
+		}
+		name := mustTypecheck(t, "DefsInfo", test.src, &info)
+
+		// find object
+		var def Object
+		for id, obj := range info.Defs {
+			if id.Value == test.obj {
+				def = obj
+				break
+			}
+		}
+		if def == nil {
+			t.Errorf("package %s: %s not found", name, test.obj)
+			continue
+		}
+
+		if got := def.String(); got != test.want {
+			t.Errorf("package %s: got %s; want %s", name, got, test.want)
+		}
+	}
+}
+
+func TestUsesInfo(t *testing.T) {
+	var tests = []struct {
+		src  string
+		obj  string
+		want string
+	}{
+		{`package p0; func _() { _ = x }; const x = 42`, `x`, `const p0.x untyped int`},
+		{`package p1; func _() { _ = x }; const x int = 42`, `x`, `const p1.x int`},
+		{`package p2; func _() { _ = x }; var x int`, `x`, `var p2.x int`},
+		{`package p3; func _() { type _ x }; type x int`, `x`, `type p3.x int`},
+		{`package p4; func _() { _ = f }; func f()`, `f`, `func p4.f()`},
+
+		// generic types must be sanitized
+		// (need to use sufficiently nested types to provoke unexpanded types)
+		{genericPkg + `g0; func _() { _ = x }; type t[P any] P; const x = t[int](42)`, `x`, `const generic_g0.x generic_g0.t[int]`},
+		{genericPkg + `g1; func _() { _ = x }; type t[P any] P; var x = t[int](42)`, `x`, `var generic_g1.x generic_g1.t[int]`},
+		{genericPkg + `g2; func _() { type _ x }; type t[P any] P; type x struct{ f t[int] }`, `x`, `type generic_g2.x struct{f generic_g2.t[int]}`},
+		{genericPkg + `g3; func _() { _ = f }; type t[P any] P; func f(x struct{ f t[string] })`, `f`, `func generic_g3.f(x struct{f generic_g3.t[string]})`},
+	}
+
+	for _, test := range tests {
+		info := Info{
+			Uses: make(map[*syntax.Name]Object),
+		}
+		name := mustTypecheck(t, "UsesInfo", test.src, &info)
+
+		// find object
+		var use Object
+		for id, obj := range info.Uses {
+			if id.Value == test.obj {
+				use = obj
+				break
+			}
+		}
+		if use == nil {
+			t.Errorf("package %s: %s not found", name, test.obj)
+			continue
+		}
+
+		if got := use.String(); got != test.want {
+			t.Errorf("package %s: got %s; want %s", name, got, test.want)
+		}
+	}
+}
+
+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[syntax.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 *syntax.ImportDecl:
+				got = "importSpec"
+			case *syntax.CaseClause:
+				got = "caseClause"
+			case *syntax.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) {
+		if b {
+			if buf.Len() > 0 {
+				buf.WriteString(", ")
+			}
+			buf.WriteString(s)
+		}
+	}
+
+	pred(tv.IsVoid(), "void")
+	pred(tv.IsType(), "type")
+	pred(tv.IsBuiltin(), "builtin")
+	pred(tv.IsValue() && tv.Value != nil, "const")
+	pred(tv.IsValue() && tv.Value == nil, "value")
+	pred(tv.IsNil(), "nil")
+	pred(tv.Addressable(), "addressable")
+	pred(tv.Assignable(), "assignable")
+	pred(tv.HasOk(), "hasOk")
+
+	if buf.Len() == 0 {
+		return "invalid"
+	}
+	return buf.String()
+}
+
+func TestPredicatesInfo(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	var tests = []struct {
+		src  string
+		expr string
+		pred string
+	}{
+		// void
+		{`package n0; func f() { f() }`, `f()`, `void`},
+
+		// types
+		{`package t0; type _ int`, `int`, `type`},
+		{`package t1; type _ []int`, `[]int`, `type`},
+		{`package t2; type _ func()`, `func()`, `type`},
+		{`package t3; type _ func(int)`, `int`, `type`},
+		{`package t3; type _ func(...int)`, `...int`, `type`},
+
+		// built-ins
+		{`package b0; var _ = len("")`, `len`, `builtin`},
+		{`package b1; var _ = (len)("")`, `(len)`, `builtin`},
+
+		// constants
+		{`package c0; var _ = 42`, `42`, `const`},
+		{`package c1; var _ = "foo" + "bar"`, `"foo" + "bar"`, `const`},
+		{`package c2; const (i = 1i; _ = i)`, `i`, `const`},
+
+		// values
+		{`package v0; var (a, b int; _ = a + b)`, `a + b`, `value`},
+		{`package v1; var _ = &[]int{1}`, `[]int{…}`, `value`},
+		{`package v2; var _ = func(){}`, `func() {}`, `value`},
+		{`package v4; func f() { _ = f }`, `f`, `value`},
+		{`package v3; var _ *int = nil`, `nil`, `value, nil`},
+		{`package v3; var _ *int = (nil)`, `(nil)`, `value, nil`},
+
+		// addressable (and thus assignable) operands
+		{`package a0; var (x int; _ = x)`, `x`, `value, addressable, assignable`},
+		{`package a1; var (p *int; _ = *p)`, `*p`, `value, addressable, assignable`},
+		{`package a2; var (s []int; _ = s[0])`, `s[0]`, `value, addressable, assignable`},
+		{`package a3; var (s struct{f int}; _ = s.f)`, `s.f`, `value, addressable, assignable`},
+		{`package a4; var (a [10]int; _ = a[0])`, `a[0]`, `value, addressable, assignable`},
+		{`package a5; func _(x int) { _ = x }`, `x`, `value, addressable, assignable`},
+		{`package a6; func _()(x int) { _ = x; return }`, `x`, `value, addressable, assignable`},
+		{`package a7; type T int; func (x T) _() { _ = x }`, `x`, `value, addressable, assignable`},
+		// composite literals are not addressable
+
+		// assignable but not addressable values
+		{`package s0; var (m map[int]int; _ = m[0])`, `m[0]`, `value, assignable, hasOk`},
+		{`package s1; var (m map[int]int; _, _ = m[0])`, `m[0]`, `value, assignable, hasOk`},
+
+		// hasOk expressions
+		{`package k0; var (ch chan int; _ = <-ch)`, `<-ch`, `value, hasOk`},
+		{`package k1; var (ch chan int; _, _ = <-ch)`, `<-ch`, `value, hasOk`},
+
+		// missing entries
+		// - package names are collected in the Uses map
+		// - identifiers being declared are collected in the Defs map
+		{`package m0; import "os"; func _() { _ = os.Stdout }`, `os`, `<missing>`},
+		{`package m1; import p "os"; func _() { _ = p.Stdout }`, `p`, `<missing>`},
+		{`package m2; const c = 0`, `c`, `<missing>`},
+		{`package m3; type T int`, `T`, `<missing>`},
+		{`package m4; var v int`, `v`, `<missing>`},
+		{`package m5; func f() {}`, `f`, `<missing>`},
+		{`package m6; func _(x int) {}`, `x`, `<missing>`},
+		{`package m6; func _()(x int) { return }`, `x`, `<missing>`},
+		{`package m6; type T int; func (x T) _() {}`, `x`, `<missing>`},
+	}
+
+	for _, test := range tests {
+		info := Info{Types: make(map[syntax.Expr]TypeAndValue)}
+		name := mustTypecheck(t, "PredicatesInfo", test.src, &info)
+
+		// look for expression predicates
+		got := "<missing>"
+		for e, tv := range info.Types {
+			//println(name, syntax.String(e))
+			if syntax.String(e) == test.expr {
+				got = predString(tv)
+				break
+			}
+		}
+
+		if got != test.pred {
+			t.Errorf("package %s: got %s; want %s", name, got, test.pred)
+		}
+	}
+}
+
+func TestScopesInfo(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	var tests = []struct {
+		src    string
+		scopes []string // list of scope descriptors of the form kind:varlist
+	}{
+		{`package p0`, []string{
+			"file:",
+		}},
+		{`package p1; import ( "fmt"; m "math"; _ "os" ); var ( _ = fmt.Println; _ = m.Pi )`, []string{
+			"file:fmt m",
+		}},
+		{`package p2; func _() {}`, []string{
+			"file:", "func:",
+		}},
+		{`package p3; func _(x, y int) {}`, []string{
+			"file:", "func:x y",
+		}},
+		{`package p4; func _(x, y int) { x, z := 1, 2; _ = z }`, []string{
+			"file:", "func:x y z", // redeclaration of x
+		}},
+		{`package p5; func _(x, y int) (u, _ int) { return }`, []string{
+			"file:", "func:u x y",
+		}},
+		{`package p6; func _() { { var x int; _ = x } }`, []string{
+			"file:", "func:", "block:x",
+		}},
+		{`package p7; func _() { if true {} }`, []string{
+			"file:", "func:", "if:", "block:",
+		}},
+		{`package p8; func _() { if x := 0; x < 0 { y := x; _ = y } }`, []string{
+			"file:", "func:", "if:x", "block:y",
+		}},
+		{`package p9; func _() { switch x := 0; x {} }`, []string{
+			"file:", "func:", "switch:x",
+		}},
+		{`package p10; func _() { switch x := 0; x { case 1: y := x; _ = y; default: }}`, []string{
+			"file:", "func:", "switch:x", "case:y", "case:",
+		}},
+		{`package p11; func _(t interface{}) { switch t.(type) {} }`, []string{
+			"file:", "func:t", "switch:",
+		}},
+		{`package p12; func _(t interface{}) { switch t := t; t.(type) {} }`, []string{
+			"file:", "func:t", "switch:t",
+		}},
+		{`package p13; func _(t interface{}) { switch x := t.(type) { case int: _ = x } }`, []string{
+			"file:", "func:t", "switch:", "case:x", // x implicitly declared
+		}},
+		{`package p14; func _() { select{} }`, []string{
+			"file:", "func:",
+		}},
+		{`package p15; func _(c chan int) { select{ case <-c: } }`, []string{
+			"file:", "func:c", "comm:",
+		}},
+		{`package p16; func _(c chan int) { select{ case i := <-c: x := i; _ = x} }`, []string{
+			"file:", "func:c", "comm:i x",
+		}},
+		{`package p17; func _() { for{} }`, []string{
+			"file:", "func:", "for:", "block:",
+		}},
+		{`package p18; func _(n int) { for i := 0; i < n; i++ { _ = i } }`, []string{
+			"file:", "func:n", "for:i", "block:",
+		}},
+		{`package p19; func _(a []int) { for i := range a { _ = i} }`, []string{
+			"file:", "func:a", "for:i", "block:",
+		}},
+		{`package p20; var s int; func _(a []int) { for i, x := range a { s += x; _ = i } }`, []string{
+			"file:", "func:a", "for:i x", "block:",
+		}},
+	}
+
+	for _, test := range tests {
+		info := Info{Scopes: make(map[syntax.Node]*Scope)}
+		name := mustTypecheck(t, "ScopesInfo", test.src, &info)
+
+		// number of scopes must match
+		if len(info.Scopes) != len(test.scopes) {
+			t.Errorf("package %s: got %d scopes; want %d", name, len(info.Scopes), len(test.scopes))
+		}
+
+		// scope descriptions must match
+		for node, scope := range info.Scopes {
+			var kind string
+			switch node.(type) {
+			case *syntax.File:
+				kind = "file"
+			case *syntax.FuncType:
+				kind = "func"
+			case *syntax.BlockStmt:
+				kind = "block"
+			case *syntax.IfStmt:
+				kind = "if"
+			case *syntax.SwitchStmt:
+				kind = "switch"
+			case *syntax.SelectStmt:
+				kind = "select"
+			case *syntax.CaseClause:
+				kind = "case"
+			case *syntax.CommClause:
+				kind = "comm"
+			case *syntax.ForStmt:
+				kind = "for"
+			default:
+				kind = fmt.Sprintf("%T", node)
+			}
+
+			// look for matching scope description
+			desc := kind + ":" + strings.Join(scope.Names(), " ")
+			found := false
+			for _, d := range test.scopes {
+				if desc == d {
+					found = true
+					break
+				}
+			}
+			if !found {
+				t.Errorf("package %s: no matching scope found for %s", name, desc)
+			}
+		}
+	}
+}
+
+func TestInitOrderInfo(t *testing.T) {
+	var tests = []struct {
+		src   string
+		inits []string
+	}{
+		{`package p0; var (x = 1; y = x)`, []string{
+			"x = 1", "y = x",
+		}},
+		{`package p1; var (a = 1; b = 2; c = 3)`, []string{
+			"a = 1", "b = 2", "c = 3",
+		}},
+		{`package p2; var (a, b, c = 1, 2, 3)`, []string{
+			"a = 1", "b = 2", "c = 3",
+		}},
+		{`package p3; var _ = f(); func f() int { return 1 }`, []string{
+			"_ = f()", // blank var
+		}},
+		{`package p4; var (a = 0; x = y; y = z; z = 0)`, []string{
+			"a = 0", "z = 0", "y = z", "x = y",
+		}},
+		{`package p5; var (a, _ = m[0]; m map[int]string)`, []string{
+			"a, _ = m[0]", // blank var
+		}},
+		{`package p6; var a, b = f(); func f() (_, _ int) { return z, z }; var z = 0`, []string{
+			"z = 0", "a, b = f()",
+		}},
+		{`package p7; var (a = func() int { return b }(); b = 1)`, []string{
+			"b = 1", "a = func() int {…}()",
+		}},
+		{`package p8; var (a, b = func() (_, _ int) { return c, c }(); c = 1)`, []string{
+			"c = 1", "a, b = func() (_, _ int) {…}()",
+		}},
+		{`package p9; type T struct{}; func (T) m() int { _ = y; return 0 }; var x, y = T.m, 1`, []string{
+			"y = 1", "x = T.m",
+		}},
+		{`package p10; var (d = c + b; a = 0; b = 0; c = 0)`, []string{
+			"a = 0", "b = 0", "c = 0", "d = c + b",
+		}},
+		{`package p11; var (a = e + c; b = d + c; c = 0; d = 0; e = 0)`, []string{
+			"c = 0", "d = 0", "b = d + c", "e = 0", "a = e + c",
+		}},
+		// emit an initializer for n:1 initializations only once (not for each node
+		// on the lhs which may appear in different order in the dependency graph)
+		{`package p12; var (a = x; b = 0; x, y = m[0]; m map[int]int)`, []string{
+			"b = 0", "x, y = m[0]", "a = x",
+		}},
+		// test case from spec section on package initialization
+		{`package p12
+
+		var (
+			a = c + b
+			b = f()
+			c = f()
+			d = 3
+		)
+
+		func f() int {
+			d++
+			return d
+		}`, []string{
+			"d = 3", "b = f()", "c = f()", "a = c + b",
+		}},
+		// test case for issue 7131
+		{`package main
+
+		var counter int
+		func next() int { counter++; return counter }
+
+		var _ = makeOrder()
+		func makeOrder() []int { return []int{f, b, d, e, c, a} }
+
+		var a       = next()
+		var b, c    = next(), next()
+		var d, e, f = next(), next(), next()
+		`, []string{
+			"a = next()", "b = next()", "c = next()", "d = next()", "e = next()", "f = next()", "_ = makeOrder()",
+		}},
+		// test case for issue 10709
+		{`package p13
+
+		var (
+		    v = t.m()
+		    t = makeT(0)
+		)
+
+		type T struct{}
+
+		func (T) m() int { return 0 }
+
+		func makeT(n int) T {
+		    if n > 0 {
+		        return makeT(n-1)
+		    }
+		    return T{}
+		}`, []string{
+			"t = makeT(0)", "v = t.m()",
+		}},
+		// test case for issue 10709: same as test before, but variable decls swapped
+		{`package p14
+
+		var (
+		    t = makeT(0)
+		    v = t.m()
+		)
+
+		type T struct{}
+
+		func (T) m() int { return 0 }
+
+		func makeT(n int) T {
+		    if n > 0 {
+		        return makeT(n-1)
+		    }
+		    return T{}
+		}`, []string{
+			"t = makeT(0)", "v = t.m()",
+		}},
+		// another candidate possibly causing problems with issue 10709
+		{`package p15
+
+		var y1 = f1()
+
+		func f1() int { return g1() }
+		func g1() int { f1(); return x1 }
+
+		var x1 = 0
+
+		var y2 = f2()
+
+		func f2() int { return g2() }
+		func g2() int { return x2 }
+
+		var x2 = 0`, []string{
+			"x1 = 0", "y1 = f1()", "x2 = 0", "y2 = f2()",
+		}},
+	}
+
+	for _, test := range tests {
+		info := Info{}
+		name := mustTypecheck(t, "InitOrderInfo", test.src, &info)
+
+		// number of initializers must match
+		if len(info.InitOrder) != len(test.inits) {
+			t.Errorf("package %s: got %d initializers; want %d", name, len(info.InitOrder), len(test.inits))
+			continue
+		}
+
+		// initializers must match
+		for i, want := range test.inits {
+			got := info.InitOrder[i].String()
+			if got != want {
+				t.Errorf("package %s, init %d: got %s; want %s", name, i, got, want)
+				continue
+			}
+		}
+	}
+}
+
+func TestMultiFileInitOrder(t *testing.T) {
+	mustParse := func(src string) *syntax.File {
+		f, err := parseSrc("main", src)
+		if err != nil {
+			t.Fatal(err)
+		}
+		return f
+	}
+
+	fileA := mustParse(`package main; var a = 1`)
+	fileB := mustParse(`package main; var b = 2`)
+
+	// The initialization order must not depend on the parse
+	// order of the files, only on the presentation order to
+	// the type-checker.
+	for _, test := range []struct {
+		files []*syntax.File
+		want  string
+	}{
+		{[]*syntax.File{fileA, fileB}, "[a = 1 b = 2]"},
+		{[]*syntax.File{fileB, fileA}, "[b = 2 a = 1]"},
+	} {
+		var info Info
+		if _, err := new(Config).Check("main", test.files, &info); err != nil {
+			t.Fatal(err)
+		}
+		if got := fmt.Sprint(info.InitOrder); got != test.want {
+			t.Fatalf("got %s; want %s", got, test.want)
+		}
+	}
+}
+
+func TestFiles(t *testing.T) {
+	var sources = []string{
+		"package p; type T struct{}; func (T) m1() {}",
+		"package p; func (T) m2() {}; var x interface{ m1(); m2() } = T{}",
+		"package p; func (T) m3() {}; var y interface{ m1(); m2(); m3() } = T{}",
+		"package p",
+	}
+
+	var conf Config
+	pkg := NewPackage("p", "p")
+	var info Info
+	check := NewChecker(&conf, pkg, &info)
+
+	for i, src := range sources {
+		filename := fmt.Sprintf("sources%d", i)
+		f, err := parseSrc(filename, src)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if err := check.Files([]*syntax.File{f}); err != nil {
+			t.Error(err)
+		}
+	}
+
+	// check InitOrder is [x y]
+	var vars []string
+	for _, init := range info.InitOrder {
+		for _, v := range init.Lhs {
+			vars = append(vars, v.Name())
+		}
+	}
+	if got, want := fmt.Sprint(vars), "[x y]"; got != want {
+		t.Errorf("InitOrder == %s, want %s", got, want)
+	}
+}
+
+type testImporter map[string]*Package
+
+func (m testImporter) Import(path string) (*Package, error) {
+	if pkg := m[path]; pkg != nil {
+		return pkg, nil
+	}
+	return nil, fmt.Errorf("package %q not found", path)
+}
+
+func TestSelection(t *testing.T) {
+	t.Skip("requires fixes around source positions")
+
+	selections := make(map[*syntax.SelectorExpr]*Selection)
+
+	imports := make(testImporter)
+	conf := Config{Importer: imports}
+	makePkg := func(path, src string) {
+		f, err := parseSrc(path+".go", src)
+		if err != nil {
+			t.Fatal(err)
+		}
+		pkg, err := conf.Check(path, []*syntax.File{f}, &Info{Selections: selections})
+		if err != nil {
+			t.Fatal(err)
+		}
+		imports[path] = pkg
+	}
+
+	const libSrc = `
+package lib
+type T float64
+const C T = 3
+var V T
+func F() {}
+func (T) M() {}
+`
+	const mainSrc = `
+package main
+import "lib"
+
+type A struct {
+	*B
+	C
+}
+
+type B struct {
+	b int
+}
+
+func (B) f(int)
+
+type C struct {
+	c int
+}
+
+func (C) g()
+func (*C) h()
+
+func main() {
+	// qualified identifiers
+	var _ lib.T
+        _ = lib.C
+        _ = lib.F
+        _ = lib.V
+	_ = lib.T.M
+
+	// fields
+	_ = A{}.B
+	_ = new(A).B
+
+	_ = A{}.C
+	_ = new(A).C
+
+	_ = A{}.b
+	_ = new(A).b
+
+	_ = A{}.c
+	_ = new(A).c
+
+	// methods
+        _ = A{}.f
+        _ = new(A).f
+        _ = A{}.g
+        _ = new(A).g
+        _ = new(A).h
+
+        _ = B{}.f
+        _ = new(B).f
+
+        _ = C{}.g
+        _ = new(C).g
+        _ = new(C).h
+
+	// method expressions
+        _ = A.f
+        _ = (*A).f
+        _ = B.f
+        _ = (*B).f
+}`
+
+	wantOut := map[string][2]string{
+		"lib.T.M": {"method expr (lib.T) M(lib.T)", ".[0]"},
+
+		"A{}.B":    {"field (main.A) B *main.B", ".[0]"},
+		"new(A).B": {"field (*main.A) B *main.B", "->[0]"},
+		"A{}.C":    {"field (main.A) C main.C", ".[1]"},
+		"new(A).C": {"field (*main.A) C main.C", "->[1]"},
+		"A{}.b":    {"field (main.A) b int", "->[0 0]"},
+		"new(A).b": {"field (*main.A) b int", "->[0 0]"},
+		"A{}.c":    {"field (main.A) c int", ".[1 0]"},
+		"new(A).c": {"field (*main.A) c int", "->[1 0]"},
+
+		"A{}.f":    {"method (main.A) f(int)", "->[0 0]"},
+		"new(A).f": {"method (*main.A) f(int)", "->[0 0]"},
+		"A{}.g":    {"method (main.A) g()", ".[1 0]"},
+		"new(A).g": {"method (*main.A) g()", "->[1 0]"},
+		"new(A).h": {"method (*main.A) h()", "->[1 1]"}, // TODO(gri) should this report .[1 1] ?
+		"B{}.f":    {"method (main.B) f(int)", ".[0]"},
+		"new(B).f": {"method (*main.B) f(int)", "->[0]"},
+		"C{}.g":    {"method (main.C) g()", ".[0]"},
+		"new(C).g": {"method (*main.C) g()", "->[0]"},
+		"new(C).h": {"method (*main.C) h()", "->[1]"}, // TODO(gri) should this report .[1] ?
+
+		"A.f":    {"method expr (main.A) f(main.A, int)", "->[0 0]"},
+		"(*A).f": {"method expr (*main.A) f(*main.A, int)", "->[0 0]"},
+		"B.f":    {"method expr (main.B) f(main.B, int)", ".[0]"},
+		"(*B).f": {"method expr (*main.B) f(*main.B, int)", "->[0]"},
+	}
+
+	makePkg("lib", libSrc)
+	makePkg("main", mainSrc)
+
+	for e, sel := range selections {
+		_ = sel.String() // assertion: must not panic
+
+		unimplemented()
+		_ = e
+		// start := fset.Position(e.Pos()).Offset
+		// end := fset.Position(e.End()).Offset
+		// syntax := mainSrc[start:end] // (all SelectorExprs are in main, not lib)
+
+		direct := "."
+		if sel.Indirect() {
+			direct = "->"
+		}
+		got := [2]string{
+			sel.String(),
+			fmt.Sprintf("%s%v", direct, sel.Index()),
+		}
+		unimplemented()
+		_ = got
+		// want := wantOut[syntax]
+		// if want != got {
+		// 	t.Errorf("%s: got %q; want %q", syntax, got, want)
+		// }
+		// delete(wantOut, syntax)
+
+		// We must explicitly assert properties of the
+		// Signature's receiver since it doesn't participate
+		// in Identical() or String().
+		sig, _ := sel.Type().(*Signature)
+		if sel.Kind() == MethodVal {
+			got := sig.Recv().Type()
+			want := sel.Recv()
+			if !Identical(got, want) {
+				unimplemented()
+				// t.Errorf("%s: Recv() = %s, want %s", syntax, got, want)
+			}
+		} else if sig != nil && sig.Recv() != nil {
+			t.Errorf("%s: signature has receiver %s", sig, sig.Recv().Type())
+		}
+	}
+	// Assert that all wantOut entries were used exactly once.
+	for syntax := range wantOut {
+		t.Errorf("no syntax.Selection found with syntax %q", syntax)
+	}
+}
+
+func TestIssue8518(t *testing.T) {
+	imports := make(testImporter)
+	conf := Config{
+		Error:    func(err error) { t.Log(err) }, // don't exit after first error
+		Importer: imports,
+	}
+	makePkg := func(path, src string) {
+		f, err := parseSrc(path, src)
+		if err != nil {
+			t.Fatal(err)
+		}
+		pkg, _ := conf.Check(path, []*syntax.File{f}, nil) // errors logged via conf.Error
+		imports[path] = pkg
+	}
+
+	const libSrc = `
+package a
+import "missing"
+const C1 = foo
+const C2 = missing.C
+`
+
+	const mainSrc = `
+package main
+import "a"
+var _ = a.C1
+var _ = a.C2
+`
+
+	makePkg("a", libSrc)
+	makePkg("main", mainSrc) // don't crash when type-checking this package
+}
+
+func TestLookupFieldOrMethod(t *testing.T) {
+	// Test cases assume a lookup of the form a.f or x.f, where a stands for an
+	// addressable value, and x for a non-addressable value (even though a variable
+	// for ease of test case writing).
+	var tests = []struct {
+		src      string
+		found    bool
+		index    []int
+		indirect bool
+	}{
+		// field lookups
+		{"var x T; type T struct{}", false, nil, false},
+		{"var x T; type T struct{ f int }", true, []int{0}, false},
+		{"var x T; type T struct{ a, b, f, c int }", true, []int{2}, false},
+
+		// method lookups
+		{"var a T; type T struct{}; func (T) f() {}", true, []int{0}, false},
+		{"var a *T; type T struct{}; func (T) f() {}", true, []int{0}, true},
+		{"var a T; type T struct{}; func (*T) f() {}", true, []int{0}, false},
+		{"var a *T; type T struct{}; func (*T) f() {}", true, []int{0}, true}, // TODO(gri) should this report indirect = false?
+
+		// collisions
+		{"type ( E1 struct{ f int }; E2 struct{ f int }; x struct{ E1; *E2 })", false, []int{1, 0}, false},
+		{"type ( E1 struct{ f int }; E2 struct{}; x struct{ E1; *E2 }); func (E2) f() {}", false, []int{1, 0}, false},
+
+		// outside methodset
+		// (*T).f method exists, but value of type T is not addressable
+		{"var x T; type T struct{}; func (*T) f() {}", false, nil, true},
+	}
+
+	for _, test := range tests {
+		pkg, err := pkgFor("test", "package p;"+test.src, nil)
+		if err != nil {
+			t.Errorf("%s: incorrect test case: %s", test.src, err)
+			continue
+		}
+
+		obj := pkg.Scope().Lookup("a")
+		if obj == nil {
+			if obj = pkg.Scope().Lookup("x"); obj == nil {
+				t.Errorf("%s: incorrect test case - no object a or x", test.src)
+				continue
+			}
+		}
+
+		f, index, indirect := LookupFieldOrMethod(obj.Type(), obj.Name() == "a", pkg, "f")
+		if (f != nil) != test.found {
+			if f == nil {
+				t.Errorf("%s: got no object; want one", test.src)
+			} else {
+				t.Errorf("%s: got object = %v; want none", test.src, f)
+			}
+		}
+		if !sameSlice(index, test.index) {
+			t.Errorf("%s: got index = %v; want %v", test.src, index, test.index)
+		}
+		if indirect != test.indirect {
+			t.Errorf("%s: got indirect = %v; want %v", test.src, indirect, test.indirect)
+		}
+	}
+}
+
+func sameSlice(a, b []int) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for i, x := range a {
+		if x != b[i] {
+			return false
+		}
+	}
+	return true
+}
+
+// TestScopeLookupParent ensures that (*Scope).LookupParent returns
+// the correct result at various positions within the source.
+func TestScopeLookupParent(t *testing.T) {
+	imports := make(testImporter)
+	conf := Config{Importer: imports}
+	var info Info
+	makePkg := func(path, src string) {
+		f, err := parseSrc(path, src)
+		if err != nil {
+			t.Fatal(err)
+		}
+		imports[path], err = conf.Check(path, []*syntax.File{f}, &info)
+		if err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	makePkg("lib", "package lib; var X int")
+	// Each /*name=kind:line*/ comment makes the test look up the
+	// name at that point and checks that it resolves to a decl of
+	// the specified kind and line number.  "undef" means undefined.
+	mainSrc := `
+/*lib=pkgname:5*/ /*X=var:1*/ /*Pi=const:8*/ /*T=typename:9*/ /*Y=var:10*/ /*F=func:12*/
+package main
+
+import "lib"
+import . "lib"
+
+const Pi = 3.1415
+type T struct{}
+var Y, _ = lib.X, X
+
+func F(){
+	const pi, e = 3.1415, /*pi=undef*/ 2.71828 /*pi=const:13*/ /*e=const:13*/
+	type /*t=undef*/ t /*t=typename:14*/ *t
+	print(Y) /*Y=var:10*/
+	x, Y := Y, /*x=undef*/ /*Y=var:10*/ Pi /*x=var:16*/ /*Y=var:16*/ ; _ = x; _ = Y
+	var F = /*F=func:12*/ F /*F=var:17*/ ; _ = F
+
+	var a []int
+	for i, x := range /*i=undef*/ /*x=var:16*/ a /*i=var:20*/ /*x=var:20*/ { _ = i; _ = x }
+
+	var i interface{}
+	switch y := i.(type) { /*y=undef*/
+	case /*y=undef*/ int /*y=var:23*/ :
+	case float32, /*y=undef*/ float64 /*y=var:23*/ :
+	default /*y=var:23*/:
+		println(y)
+	}
+	/*y=undef*/
+
+        switch int := i.(type) {
+        case /*int=typename:0*/ int /*int=var:31*/ :
+        	println(int)
+        default /*int=var:31*/ :
+        }
+}
+/*main=undef*/
+`
+
+	info.Uses = make(map[*syntax.Name]Object)
+	makePkg("main", mainSrc)
+	mainScope := imports["main"].Scope()
+
+	rx := regexp.MustCompile(`^/\*(\w*)=([\w:]*)\*/$`)
+
+	base := syntax.NewFileBase("main")
+	syntax.CommentsDo(strings.NewReader(mainSrc), func(line, col uint, text string) {
+		pos := syntax.MakePos(base, line, col)
+
+		// Syntax errors are not comments.
+		if text[0] != '/' {
+			t.Errorf("%s: %s", pos, text)
+			return
+		}
+
+		// Parse the assertion in the comment.
+		m := rx.FindStringSubmatch(text)
+		if m == nil {
+			t.Errorf("%s: bad comment: %s", pos, text)
+			return
+		}
+		name, want := m[1], m[2]
+
+		// Look up the name in the innermost enclosing scope.
+		inner := mainScope.Innermost(pos)
+		if inner == nil {
+			t.Errorf("%s: at %s: can't find innermost scope", pos, text)
+			return
+		}
+		got := "undef"
+		if _, obj := inner.LookupParent(name, pos); obj != nil {
+			kind := strings.ToLower(strings.TrimPrefix(reflect.TypeOf(obj).String(), "*types2."))
+			got = fmt.Sprintf("%s:%d", kind, obj.Pos().Line())
+		}
+		if got != want {
+			t.Errorf("%s: at %s: %s resolved to %s, want %s", pos, text, name, got, want)
+		}
+	})
+
+	// Check that for each referring identifier,
+	// a lookup of its name on the innermost
+	// enclosing scope returns the correct object.
+
+	for id, wantObj := range info.Uses {
+		inner := mainScope.Innermost(id.Pos())
+		if inner == nil {
+			t.Errorf("%s: can't find innermost scope enclosing %q", id.Pos(), id.Value)
+			continue
+		}
+
+		// Exclude selectors and qualified identifiers---lexical
+		// refs only.  (Ideally, we'd see if the AST parent is a
+		// SelectorExpr, but that requires PathEnclosingInterval
+		// from golang.org/x/tools/go/ast/astutil.)
+		if id.Value == "X" {
+			continue
+		}
+
+		_, gotObj := inner.LookupParent(id.Value, id.Pos())
+		if gotObj != wantObj {
+			t.Errorf("%s: got %v, want %v", id.Pos(), gotObj, wantObj)
+			continue
+		}
+	}
+}
+
+func TestConvertibleTo(t *testing.T) {
+	for _, test := range []struct {
+		v, t Type
+		want bool
+	}{
+		{Typ[Int], Typ[Int], true},
+		{Typ[Int], Typ[Float32], true},
+		{newDefined(Typ[Int]), Typ[Int], true},
+		{newDefined(new(Struct)), new(Struct), true},
+		{newDefined(Typ[Int]), new(Struct), false},
+		{Typ[UntypedInt], Typ[Int], true},
+		{NewSlice(Typ[Int]), NewPointer(NewArray(Typ[Int], 10)), true},
+		{NewSlice(Typ[Int]), NewArray(Typ[Int], 10), false},
+		{NewSlice(Typ[Int]), NewPointer(NewArray(Typ[Uint], 10)), false},
+		// Untyped string values are not permitted by the spec, so the below
+		// behavior is undefined.
+		{Typ[UntypedString], Typ[String], true},
+	} {
+		if got := ConvertibleTo(test.v, test.t); got != test.want {
+			t.Errorf("ConvertibleTo(%v, %v) = %t, want %t", test.v, test.t, got, test.want)
+		}
+	}
+}
+
+func TestAssignableTo(t *testing.T) {
+	for _, test := range []struct {
+		v, t Type
+		want bool
+	}{
+		{Typ[Int], Typ[Int], true},
+		{Typ[Int], Typ[Float32], false},
+		{newDefined(Typ[Int]), Typ[Int], false},
+		{newDefined(new(Struct)), new(Struct), true},
+		{Typ[UntypedBool], Typ[Bool], true},
+		{Typ[UntypedString], Typ[Bool], false},
+		// Neither untyped string nor untyped numeric assignments arise during
+		// normal type checking, so the below behavior is technically undefined by
+		// the spec.
+		{Typ[UntypedString], Typ[String], true},
+		{Typ[UntypedInt], Typ[Int], true},
+	} {
+		if got := AssignableTo(test.v, test.t); got != test.want {
+			t.Errorf("AssignableTo(%v, %v) = %t, want %t", test.v, test.t, got, test.want)
+		}
+	}
+}
+
+func TestIdentical_issue15173(t *testing.T) {
+	// Identical should allow nil arguments and be symmetric.
+	for _, test := range []struct {
+		x, y Type
+		want bool
+	}{
+		{Typ[Int], Typ[Int], true},
+		{Typ[Int], nil, false},
+		{nil, Typ[Int], false},
+		{nil, nil, true},
+	} {
+		if got := Identical(test.x, test.y); got != test.want {
+			t.Errorf("Identical(%v, %v) = %t", test.x, test.y, got)
+		}
+	}
+}
+
+func TestIssue15305(t *testing.T) {
+	const src = "package p; func f() int16; var _ = f(undef)"
+	f, err := parseSrc("issue15305.go", src)
+	if err != nil {
+		t.Fatal(err)
+	}
+	conf := Config{
+		Error: func(err error) {}, // allow errors
+	}
+	info := &Info{
+		Types: make(map[syntax.Expr]TypeAndValue),
+	}
+	conf.Check("p", []*syntax.File{f}, info) // ignore result
+	for e, tv := range info.Types {
+		if _, ok := e.(*syntax.CallExpr); ok {
+			if tv.Type != Typ[Int16] {
+				t.Errorf("CallExpr has type %v, want int16", tv.Type)
+			}
+			return
+		}
+	}
+	t.Errorf("CallExpr has no type")
+}
+
+// TestCompositeLitTypes verifies that Info.Types registers the correct
+// types for composite literal expressions and composite literal type
+// expressions.
+func TestCompositeLitTypes(t *testing.T) {
+	for _, test := range []struct {
+		lit, typ string
+	}{
+		{`[16]byte{}`, `[16]byte`},
+		{`[...]byte{}`, `[0]byte`},                // test for issue #14092
+		{`[...]int{1, 2, 3}`, `[3]int`},           // test for issue #14092
+		{`[...]int{90: 0, 98: 1, 2}`, `[100]int`}, // test for issue #14092
+		{`[]int{}`, `[]int`},
+		{`map[string]bool{"foo": true}`, `map[string]bool`},
+		{`struct{}{}`, `struct{}`},
+		{`struct{x, y int; z complex128}{}`, `struct{x int; y int; z complex128}`},
+	} {
+		f, err := parseSrc(test.lit, "package p; var _ = "+test.lit)
+		if err != nil {
+			t.Fatalf("%s: %v", test.lit, err)
+		}
+
+		info := &Info{
+			Types: make(map[syntax.Expr]TypeAndValue),
+		}
+		if _, err = new(Config).Check("p", []*syntax.File{f}, info); err != nil {
+			t.Fatalf("%s: %v", test.lit, err)
+		}
+
+		cmptype := func(x syntax.Expr, want string) {
+			tv, ok := info.Types[x]
+			if !ok {
+				t.Errorf("%s: no Types entry found", test.lit)
+				return
+			}
+			if tv.Type == nil {
+				t.Errorf("%s: type is nil", test.lit)
+				return
+			}
+			if got := tv.Type.String(); got != want {
+				t.Errorf("%s: got %v, want %s", test.lit, got, want)
+			}
+		}
+
+		// test type of composite literal expression
+		rhs := f.DeclList[0].(*syntax.VarDecl).Values
+		cmptype(rhs, test.typ)
+
+		// test type of composite literal type expression
+		cmptype(rhs.(*syntax.CompositeLit).Type, test.typ)
+	}
+}
+
+// TestObjectParents verifies that objects have parent scopes or not
+// as specified by the Object interface.
+func TestObjectParents(t *testing.T) {
+	const src = `
+package p
+
+const C = 0
+
+type T1 struct {
+	a, b int
+	T2
+}
+
+type T2 interface {
+	im1()
+	im2()
+}
+
+func (T1) m1() {}
+func (*T1) m2() {}
+
+func f(x int) { y := x; print(y) }
+`
+
+	f, err := parseSrc("src", src)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	info := &Info{
+		Defs: make(map[*syntax.Name]Object),
+	}
+	if _, err = new(Config).Check("p", []*syntax.File{f}, info); err != nil {
+		t.Fatal(err)
+	}
+
+	for ident, obj := range info.Defs {
+		if obj == nil {
+			// only package names and implicit vars have a nil object
+			// (in this test we only need to handle the package name)
+			if ident.Value != "p" {
+				t.Errorf("%v has nil object", ident)
+			}
+			continue
+		}
+
+		// struct fields, type-associated and interface methods
+		// have no parent scope
+		wantParent := true
+		switch obj := obj.(type) {
+		case *Var:
+			if obj.IsField() {
+				wantParent = false
+			}
+		case *Func:
+			if obj.Type().(*Signature).Recv() != nil { // method
+				wantParent = false
+			}
+		}
+
+		gotParent := obj.Parent() != nil
+		switch {
+		case gotParent && !wantParent:
+			t.Errorf("%v: want no parent, got %s", ident, obj.Parent())
+		case !gotParent && wantParent:
+			t.Errorf("%v: no parent found", ident)
+		}
+	}
+}
+
+// TestFailedImport tests that we don't get follow-on errors
+// elsewhere in a package due to failing to import a package.
+func TestFailedImport(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	const src = `
+package p
+
+import foo "go/types/thisdirectorymustnotexistotherwisethistestmayfail/foo" // should only see an error here
+
+const c = foo.C
+type T = foo.T
+var v T = c
+func f(x T) T { return foo.F(x) }
+`
+	f, err := parseSrc("src", src)
+	if err != nil {
+		t.Fatal(err)
+	}
+	files := []*syntax.File{f}
+
+	// type-check using all possible importers
+	for _, compiler := range []string{"gc", "gccgo", "source"} {
+		errcount := 0
+		conf := Config{
+			Error: func(err error) {
+				// we should only see the import error
+				if errcount > 0 || !strings.Contains(err.Error(), "could not import") {
+					t.Errorf("for %s importer, got unexpected error: %v", compiler, err)
+				}
+				errcount++
+			},
+			//Importer: importer.For(compiler, nil),
+		}
+
+		info := &Info{
+			Uses: make(map[*syntax.Name]Object),
+		}
+		pkg, _ := conf.Check("p", files, info)
+		if pkg == nil {
+			t.Errorf("for %s importer, type-checking failed to return a package", compiler)
+			continue
+		}
+
+		imports := pkg.Imports()
+		if len(imports) != 1 {
+			t.Errorf("for %s importer, got %d imports, want 1", compiler, len(imports))
+			continue
+		}
+		imp := imports[0]
+		if imp.Name() != "foo" {
+			t.Errorf(`for %s importer, got %q, want "foo"`, compiler, imp.Name())
+			continue
+		}
+
+		// verify that all uses of foo refer to the imported package foo (imp)
+		for ident, obj := range info.Uses {
+			if ident.Value == "foo" {
+				if obj, ok := obj.(*PkgName); ok {
+					if obj.Imported() != imp {
+						t.Errorf("%s resolved to %v; want %v", ident.Value, obj.Imported(), imp)
+					}
+				} else {
+					t.Errorf("%s resolved to %v; want package name", ident.Value, obj)
+				}
+			}
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/types2/assignments.go b/src/cmd/compile/internal/types2/assignments.go
new file mode 100644
index 0000000..583118c
--- /dev/null
+++ b/src/cmd/compile/internal/types2/assignments.go
@@ -0,0 +1,407 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements initialization and assignment checks.
+
+package types2
+
+import "cmd/compile/internal/syntax"
+
+// assignment reports whether x can be assigned to a variable of type T,
+// if necessary by attempting to convert untyped values to the appropriate
+// type. context describes the context in which the assignment takes place.
+// Use T == nil to indicate assignment to an untyped blank identifier.
+// x.mode is set to invalid if the assignment failed.
+func (check *Checker) assignment(x *operand, T Type, context string) {
+	check.singleValue(x)
+
+	switch x.mode {
+	case invalid:
+		return // error reported before
+	case constant_, variable, mapindex, value, nilvalue, commaok, commaerr:
+		// ok
+	default:
+		// we may get here because of other problems (issue #39634, crash 12)
+		check.errorf(x, "cannot assign %s to %s in %s", x, T, context)
+		return
+	}
+
+	if isUntyped(x.typ) {
+		target := T
+		// spec: "If an untyped constant is assigned to a variable of interface
+		// type or the blank identifier, the constant is first converted to type
+		// bool, rune, int, float64, complex128 or string respectively, depending
+		// on whether the value is a boolean, rune, integer, floating-point,
+		// complex, or string constant."
+		if x.isNil() {
+			if T == nil {
+				check.errorf(x, "use of untyped nil in %s", context)
+				x.mode = invalid
+				return
+			}
+		} else if T == nil || IsInterface(T) {
+			target = Default(x.typ)
+		}
+		newType, val, code := check.implicitTypeAndValue(x, target)
+		if code != 0 {
+			msg := check.sprintf("cannot use %s as %s value in %s", x, target, context)
+			switch code {
+			case _TruncatedFloat:
+				msg += " (truncated)"
+			case _NumericOverflow:
+				msg += " (overflows)"
+			}
+			check.error(x, msg)
+			x.mode = invalid
+			return
+		}
+		if val != nil {
+			x.val = val
+			check.updateExprVal(x.expr, val)
+		}
+		if newType != x.typ {
+			x.typ = newType
+			check.updateExprType(x.expr, newType, false)
+		}
+	}
+	// x.typ is typed
+
+	// A generic (non-instantiated) function value cannot be assigned to a variable.
+	if sig := asSignature(x.typ); sig != nil && len(sig.tparams) > 0 {
+		check.errorf(x, "cannot use generic function %s without instantiation in %s", x, context)
+	}
+
+	// spec: "If a left-hand side is the blank identifier, any typed or
+	// non-constant value except for the predeclared identifier nil may
+	// be assigned to it."
+	if T == nil {
+		return
+	}
+
+	reason := ""
+	if ok, _ := x.assignableTo(check, T, &reason); !ok {
+		if check.conf.CompilerErrorMessages {
+			check.errorf(x, "incompatible type: cannot use %s as %s value", x, T)
+		} else {
+			if reason != "" {
+				check.errorf(x, "cannot use %s as %s value in %s: %s", x, T, context, reason)
+			} else {
+				check.errorf(x, "cannot use %s as %s value in %s", x, T, context)
+			}
+		}
+		x.mode = invalid
+	}
+}
+
+func (check *Checker) initConst(lhs *Const, x *operand) {
+	if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
+		if lhs.typ == nil {
+			lhs.typ = Typ[Invalid]
+		}
+		return
+	}
+
+	// rhs must be a constant
+	if x.mode != constant_ {
+		check.errorf(x, "%s is not constant", x)
+		if lhs.typ == nil {
+			lhs.typ = Typ[Invalid]
+		}
+		return
+	}
+	assert(isConstType(x.typ))
+
+	// If the lhs doesn't have a type yet, use the type of x.
+	if lhs.typ == nil {
+		lhs.typ = x.typ
+	}
+
+	check.assignment(x, lhs.typ, "constant declaration")
+	if x.mode == invalid {
+		return
+	}
+
+	lhs.val = x.val
+}
+
+func (check *Checker) initVar(lhs *Var, x *operand, context string) Type {
+	if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
+		if lhs.typ == nil {
+			lhs.typ = Typ[Invalid]
+		}
+		// Note: This was reverted in go/types (https://golang.org/cl/292751).
+		// TODO(gri): decide what to do (also affects test/run.go exclusion list)
+		lhs.used = true // avoid follow-on "declared but not used" errors
+		return nil
+	}
+
+	// If the lhs doesn't have a type yet, use the type of x.
+	if lhs.typ == nil {
+		typ := x.typ
+		if isUntyped(typ) {
+			// convert untyped types to default types
+			if typ == Typ[UntypedNil] {
+				check.errorf(x, "use of untyped nil in %s", context)
+				lhs.typ = Typ[Invalid]
+				return nil
+			}
+			typ = Default(typ)
+		}
+		lhs.typ = typ
+	}
+
+	check.assignment(x, lhs.typ, context)
+	if x.mode == invalid {
+		return nil
+	}
+
+	return x.typ
+}
+
+func (check *Checker) assignVar(lhs syntax.Expr, x *operand) Type {
+	if x.mode == invalid || x.typ == Typ[Invalid] {
+		check.useLHS(lhs)
+		return nil
+	}
+
+	// Determine if the lhs is a (possibly parenthesized) identifier.
+	ident, _ := unparen(lhs).(*syntax.Name)
+
+	// Don't evaluate lhs if it is the blank identifier.
+	if ident != nil && ident.Value == "_" {
+		check.recordDef(ident, nil)
+		check.assignment(x, nil, "assignment to _ identifier")
+		if x.mode == invalid {
+			return nil
+		}
+		return x.typ
+	}
+
+	// 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.expr.
+	var v *Var
+	var v_used bool
+	if ident != nil {
+		if obj := check.lookup(ident.Value); 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
+			}
+		}
+	}
+
+	var z operand
+	check.expr(&z, lhs)
+	if v != nil {
+		v.used = v_used // restore v.used
+	}
+
+	if z.mode == invalid || z.typ == Typ[Invalid] {
+		return nil
+	}
+
+	// spec: "Each left-hand side operand must be addressable, a map index
+	// expression, or the blank identifier. Operands may be parenthesized."
+	switch z.mode {
+	case invalid:
+		return nil
+	case variable, mapindex:
+		// ok
+	case nilvalue:
+		check.error(&z, "cannot assign to nil") // default would print "untyped nil"
+		return nil
+	default:
+		if sel, ok := z.expr.(*syntax.SelectorExpr); ok {
+			var op operand
+			check.expr(&op, sel.X)
+			if op.mode == mapindex {
+				check.errorf(&z, "cannot assign to struct field %s in map", syntax.String(z.expr))
+				return nil
+			}
+		}
+		check.errorf(&z, "cannot assign to %s", &z)
+		return nil
+	}
+
+	check.assignment(x, z.typ, "assignment")
+	if x.mode == invalid {
+		return nil
+	}
+
+	return x.typ
+}
+
+// If returnPos is valid, initVars is called to type-check the assignment of
+// return expressions, and returnPos is the position of the return statement.
+func (check *Checker) initVars(lhs []*Var, orig_rhs []syntax.Expr, returnPos syntax.Pos) {
+	rhs, commaOk := check.exprList(orig_rhs, len(lhs) == 2 && !returnPos.IsKnown())
+
+	if len(lhs) != len(rhs) {
+		// invalidate lhs
+		for _, obj := range lhs {
+			if obj.typ == nil {
+				obj.typ = Typ[Invalid]
+			}
+		}
+		// don't report an error if we already reported one
+		for _, x := range rhs {
+			if x.mode == invalid {
+				return
+			}
+		}
+		if returnPos.IsKnown() {
+			check.errorf(returnPos, "wrong number of return values (want %d, got %d)", len(lhs), len(rhs))
+			return
+		}
+		check.errorf(rhs[0], "cannot initialize %d variables with %d values", len(lhs), len(rhs))
+		return
+	}
+
+	context := "assignment"
+	if returnPos.IsKnown() {
+		context = "return statement"
+	}
+
+	if commaOk {
+		var a [2]Type
+		for i := range a {
+			a[i] = check.initVar(lhs[i], rhs[i], context)
+		}
+		check.recordCommaOkTypes(orig_rhs[0], a)
+		return
+	}
+
+	for i, lhs := range lhs {
+		check.initVar(lhs, rhs[i], context)
+	}
+}
+
+func (check *Checker) assignVars(lhs, orig_rhs []syntax.Expr) {
+	rhs, commaOk := check.exprList(orig_rhs, len(lhs) == 2)
+
+	if len(lhs) != len(rhs) {
+		check.useLHS(lhs...)
+		// don't report an error if we already reported one
+		for _, x := range rhs {
+			if x.mode == invalid {
+				return
+			}
+		}
+		check.errorf(rhs[0], "cannot assign %d values to %d variables", len(rhs), len(lhs))
+		return
+	}
+
+	if commaOk {
+		var a [2]Type
+		for i := range a {
+			a[i] = check.assignVar(lhs[i], rhs[i])
+		}
+		check.recordCommaOkTypes(orig_rhs[0], a)
+		return
+	}
+
+	for i, lhs := range lhs {
+		check.assignVar(lhs, rhs[i])
+	}
+}
+
+// unpack unpacks a *syntax.ListExpr into a list of syntax.Expr.
+// Helper introduced for the go/types -> types2 port.
+// TODO(gri) Should find a more efficient solution that doesn't
+//           require introduction of a new slice for simple
+//           expressions.
+func unpackExpr(x syntax.Expr) []syntax.Expr {
+	if x, _ := x.(*syntax.ListExpr); x != nil {
+		return x.ElemList
+	}
+	if x != nil {
+		return []syntax.Expr{x}
+	}
+	return nil
+}
+
+func (check *Checker) shortVarDecl(pos syntax.Pos, lhs, rhs []syntax.Expr) {
+	top := len(check.delayed)
+	scope := check.scope
+
+	// collect lhs variables
+	seen := make(map[string]bool, len(lhs))
+	lhsVars := make([]*Var, len(lhs))
+	newVars := make([]*Var, 0, len(lhs))
+	hasErr := false
+	for i, lhs := range lhs {
+		ident, _ := lhs.(*syntax.Name)
+		if ident == nil {
+			check.useLHS(lhs)
+			check.errorf(lhs, "non-name %s on left side of :=", lhs)
+			hasErr = true
+			continue
+		}
+
+		name := ident.Value
+		if name != "_" {
+			if seen[name] {
+				check.errorf(lhs, "%s repeated on left side of :=", lhs)
+				hasErr = true
+				continue
+			}
+			seen[name] = true
+		}
+
+		// Use the correct obj if the ident is redeclared. The
+		// variable's scope starts after the declaration; so we
+		// must use Scope.Lookup here and call Scope.Insert
+		// (via check.declare) later.
+		if alt := scope.Lookup(name); alt != nil {
+			check.recordUse(ident, alt)
+			// redeclared object must be a variable
+			if obj, _ := alt.(*Var); obj != nil {
+				lhsVars[i] = obj
+			} else {
+				check.errorf(lhs, "cannot assign to %s", lhs)
+				hasErr = true
+			}
+			continue
+		}
+
+		// declare new variable
+		obj := NewVar(ident.Pos(), check.pkg, name, nil)
+		lhsVars[i] = obj
+		if name != "_" {
+			newVars = append(newVars, obj)
+		}
+		check.recordDef(ident, obj)
+	}
+
+	// create dummy variables where the lhs is invalid
+	for i, obj := range lhsVars {
+		if obj == nil {
+			lhsVars[i] = NewVar(lhs[i].Pos(), check.pkg, "_", nil)
+		}
+	}
+
+	check.initVars(lhsVars, rhs, nopos)
+
+	// process function literals in rhs expressions before scope changes
+	check.processDelayed(top)
+
+	if len(newVars) == 0 && !hasErr {
+		check.softErrorf(pos, "no new variables on left side of :=")
+		return
+	}
+
+	// declare new variables
+	// spec: "The scope of a constant or variable identifier declared inside
+	// a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
+	// for short variable declarations) and ends at the end of the innermost
+	// containing block."
+	scopePos := syntax.EndPos(rhs[len(rhs)-1])
+	for _, obj := range newVars {
+		check.declare(scope, nil, obj, scopePos) // id = nil: recordDef already called
+	}
+}
diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go
new file mode 100644
index 0000000..f90e06f
--- /dev/null
+++ b/src/cmd/compile/internal/types2/builtins.go
@@ -0,0 +1,827 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements typechecking of builtin function calls.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"go/constant"
+	"go/token"
+)
+
+// builtin type-checks a call to the built-in specified by id and
+// reports whether the call is valid, with *x holding the result;
+// but x.expr is not set. If the call is invalid, the result is
+// false, and *x is undefined.
+//
+func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (_ bool) {
+	// append is the only built-in that permits the use of ... for the last argument
+	bin := predeclaredFuncs[id]
+	if call.HasDots && id != _Append {
+		//check.errorf(call.Ellipsis, invalidOp + "invalid use of ... with built-in %s", bin.name)
+		check.errorf(call, invalidOp+"invalid use of ... with built-in %s", bin.name)
+		check.use(call.ArgList...)
+		return
+	}
+
+	// For len(x) and cap(x) we need to know if x contains any function calls or
+	// receive operations. Save/restore current setting and set hasCallOrRecv to
+	// false for the evaluation of x so that we can check it afterwards.
+	// Note: We must do this _before_ calling exprList because exprList evaluates
+	//       all arguments.
+	if id == _Len || id == _Cap {
+		defer func(b bool) {
+			check.hasCallOrRecv = b
+		}(check.hasCallOrRecv)
+		check.hasCallOrRecv = false
+	}
+
+	// determine actual arguments
+	var arg func(*operand, int) // TODO(gri) remove use of arg getter in favor of using xlist directly
+	nargs := len(call.ArgList)
+	switch id {
+	default:
+		// make argument getter
+		xlist, _ := check.exprList(call.ArgList, false)
+		arg = func(x *operand, i int) { *x = *xlist[i]; x.typ = expand(x.typ) }
+		nargs = len(xlist)
+		// evaluate first argument, if present
+		if nargs > 0 {
+			arg(x, 0)
+			if x.mode == invalid {
+				return
+			}
+		}
+	case _Make, _New, _Offsetof, _Trace:
+		// arguments require special handling
+	}
+
+	// check argument count
+	{
+		msg := ""
+		if nargs < bin.nargs {
+			msg = "not enough"
+		} else if !bin.variadic && nargs > bin.nargs {
+			msg = "too many"
+		}
+		if msg != "" {
+			check.errorf(call, invalidOp+"%s arguments for %v (expected %d, found %d)", msg, call, bin.nargs, nargs)
+			return
+		}
+	}
+
+	switch id {
+	case _Append:
+		// append(s S, x ...T) S, where T is the element type of S
+		// spec: "The variadic function append appends zero or more values x to s of type
+		// S, which must be a slice type, and returns the resulting slice, also of type S.
+		// The values x are passed to a parameter of type ...T where T is the element type
+		// of S and the respective parameter passing rules apply."
+		S := x.typ
+		var T Type
+		if s := asSlice(S); s != nil {
+			T = s.elem
+		} else {
+			check.errorf(x, invalidArg+"%s is not a slice", x)
+			return
+		}
+
+		// remember arguments that have been evaluated already
+		alist := []operand{*x}
+
+		// spec: "As a special case, append also accepts a first argument assignable
+		// to type []byte with a second argument of string type followed by ... .
+		// This form appends the bytes of the string.
+		if nargs == 2 && call.HasDots {
+			if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
+				arg(x, 1)
+				if x.mode == invalid {
+					return
+				}
+				if isString(x.typ) {
+					if check.Types != nil {
+						sig := makeSig(S, S, x.typ)
+						sig.variadic = true
+						check.recordBuiltinType(call.Fun, sig)
+					}
+					x.mode = value
+					x.typ = S
+					break
+				}
+				alist = append(alist, *x)
+				// fallthrough
+			}
+		}
+
+		// check general case by creating custom signature
+		sig := makeSig(S, S, NewSlice(T)) // []T required for variadic signature
+		sig.variadic = true
+		var xlist []*operand
+		// convert []operand to []*operand
+		for i := range alist {
+			xlist = append(xlist, &alist[i])
+		}
+		for i := len(alist); i < nargs; i++ {
+			var x operand
+			arg(&x, i)
+			xlist = append(xlist, &x)
+		}
+		check.arguments(call, sig, nil, xlist) // discard result (we know the result type)
+		// ok to continue even if check.arguments reported errors
+
+		x.mode = value
+		x.typ = S
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, sig)
+		}
+
+	case _Cap, _Len:
+		// cap(x)
+		// len(x)
+		mode := invalid
+		var typ Type
+		var val constant.Value
+		switch typ = implicitArrayDeref(optype(x.typ)); t := typ.(type) {
+		case *Basic:
+			if isString(t) && id == _Len {
+				if x.mode == constant_ {
+					mode = constant_
+					val = constant.MakeInt64(int64(len(constant.StringVal(x.val))))
+				} else {
+					mode = value
+				}
+			}
+
+		case *Array:
+			mode = value
+			// spec: "The expressions len(s) and cap(s) are constants
+			// if the type of s is an array or pointer to an array and
+			// the expression s does not contain channel receives or
+			// function calls; in this case s is not evaluated."
+			if !check.hasCallOrRecv {
+				mode = constant_
+				if t.len >= 0 {
+					val = constant.MakeInt64(t.len)
+				} else {
+					val = constant.MakeUnknown()
+				}
+			}
+
+		case *Slice, *Chan:
+			mode = value
+
+		case *Map:
+			if id == _Len {
+				mode = value
+			}
+
+		case *Sum:
+			if t.is(func(t Type) bool {
+				switch t := under(t).(type) {
+				case *Basic:
+					if isString(t) && id == _Len {
+						return true
+					}
+				case *Array, *Slice, *Chan:
+					return true
+				case *Map:
+					if id == _Len {
+						return true
+					}
+				}
+				return false
+			}) {
+				mode = value
+			}
+		}
+
+		if mode == invalid && typ != Typ[Invalid] {
+			check.errorf(x, invalidArg+"%s for %s", x, bin.name)
+			return
+		}
+
+		x.mode = mode
+		x.typ = Typ[Int]
+		x.val = val
+		if check.Types != nil && mode != constant_ {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, typ))
+		}
+
+	case _Close:
+		// close(c)
+		c := asChan(x.typ)
+		if c == nil {
+			check.errorf(x, invalidArg+"%s is not a channel", x)
+			return
+		}
+		if c.dir == RecvOnly {
+			check.errorf(x, invalidArg+"%s must not be a receive-only channel", x)
+			return
+		}
+
+		x.mode = novalue
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(nil, c))
+		}
+
+	case _Complex:
+		// complex(x, y floatT) complexT
+		var y operand
+		arg(&y, 1)
+		if y.mode == invalid {
+			return
+		}
+
+		// convert or check untyped arguments
+		d := 0
+		if isUntyped(x.typ) {
+			d |= 1
+		}
+		if isUntyped(y.typ) {
+			d |= 2
+		}
+		switch d {
+		case 0:
+			// x and y are typed => nothing to do
+		case 1:
+			// only x is untyped => convert to type of y
+			check.convertUntyped(x, y.typ)
+		case 2:
+			// only y is untyped => convert to type of x
+			check.convertUntyped(&y, x.typ)
+		case 3:
+			// x and y are untyped =>
+			// 1) if both are constants, convert them to untyped
+			//    floating-point numbers if possible,
+			// 2) if one of them is not constant (possible because
+			//    it contains a shift that is yet untyped), convert
+			//    both of them to float64 since they must have the
+			//    same type to succeed (this will result in an error
+			//    because shifts of floats are not permitted)
+			if x.mode == constant_ && y.mode == constant_ {
+				toFloat := func(x *operand) {
+					if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
+						x.typ = Typ[UntypedFloat]
+					}
+				}
+				toFloat(x)
+				toFloat(&y)
+			} else {
+				check.convertUntyped(x, Typ[Float64])
+				check.convertUntyped(&y, Typ[Float64])
+				// x and y should be invalid now, but be conservative
+				// and check below
+			}
+		}
+		if x.mode == invalid || y.mode == invalid {
+			return
+		}
+
+		// both argument types must be identical
+		if !check.identical(x.typ, y.typ) {
+			check.errorf(x, invalidOp+"%v (mismatched types %s and %s)", call, x.typ, y.typ)
+			return
+		}
+
+		// the argument types must be of floating-point type
+		f := func(x Type) Type {
+			if t := asBasic(x); t != nil {
+				switch t.kind {
+				case Float32:
+					return Typ[Complex64]
+				case Float64:
+					return Typ[Complex128]
+				case UntypedFloat:
+					return Typ[UntypedComplex]
+				}
+			}
+			return nil
+		}
+		resTyp := check.applyTypeFunc(f, x.typ)
+		if resTyp == nil {
+			check.errorf(x, invalidArg+"arguments have type %s, expected floating-point", x.typ)
+			return
+		}
+
+		// if both arguments are constants, the result is a constant
+		if x.mode == constant_ && y.mode == constant_ {
+			x.val = constant.BinaryOp(constant.ToFloat(x.val), token.ADD, constant.MakeImag(constant.ToFloat(y.val)))
+		} else {
+			x.mode = value
+		}
+
+		if check.Types != nil && x.mode != constant_ {
+			check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
+		}
+
+		x.typ = resTyp
+
+	case _Copy:
+		// copy(x, y []T) int
+		var dst Type
+		if t := asSlice(x.typ); t != nil {
+			dst = t.elem
+		}
+
+		var y operand
+		arg(&y, 1)
+		if y.mode == invalid {
+			return
+		}
+		var src Type
+		switch t := optype(y.typ).(type) {
+		case *Basic:
+			if isString(y.typ) {
+				src = universeByte
+			}
+		case *Slice:
+			src = t.elem
+		}
+
+		if dst == nil || src == nil {
+			check.errorf(x, invalidArg+"copy expects slice arguments; found %s and %s", x, &y)
+			return
+		}
+
+		if !check.identical(dst, src) {
+			check.errorf(x, invalidArg+"arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src)
+			return
+		}
+
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
+		}
+		x.mode = value
+		x.typ = Typ[Int]
+
+	case _Delete:
+		// delete(m, k)
+		m := asMap(x.typ)
+		if m == nil {
+			check.errorf(x, invalidArg+"%s is not a map", x)
+			return
+		}
+		arg(x, 1) // k
+		if x.mode == invalid {
+			return
+		}
+
+		check.assignment(x, m.key, "argument to delete")
+		if x.mode == invalid {
+			return
+		}
+
+		x.mode = novalue
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(nil, m, m.key))
+		}
+
+	case _Imag, _Real:
+		// imag(complexT) floatT
+		// real(complexT) floatT
+
+		// convert or check untyped argument
+		if isUntyped(x.typ) {
+			if x.mode == constant_ {
+				// an untyped constant number can always be considered
+				// as a complex constant
+				if isNumeric(x.typ) {
+					x.typ = Typ[UntypedComplex]
+				}
+			} else {
+				// an untyped non-constant argument may appear if
+				// it contains a (yet untyped non-constant) shift
+				// expression: convert it to complex128 which will
+				// result in an error (shift of complex value)
+				check.convertUntyped(x, Typ[Complex128])
+				// x should be invalid now, but be conservative and check
+				if x.mode == invalid {
+					return
+				}
+			}
+		}
+
+		// the argument must be of complex type
+		f := func(x Type) Type {
+			if t := asBasic(x); t != nil {
+				switch t.kind {
+				case Complex64:
+					return Typ[Float32]
+				case Complex128:
+					return Typ[Float64]
+				case UntypedComplex:
+					return Typ[UntypedFloat]
+				}
+			}
+			return nil
+		}
+		resTyp := check.applyTypeFunc(f, x.typ)
+		if resTyp == nil {
+			check.errorf(x, invalidArg+"argument has type %s, expected complex type", x.typ)
+			return
+		}
+
+		// if the argument is a constant, the result is a constant
+		if x.mode == constant_ {
+			if id == _Real {
+				x.val = constant.Real(x.val)
+			} else {
+				x.val = constant.Imag(x.val)
+			}
+		} else {
+			x.mode = value
+		}
+
+		if check.Types != nil && x.mode != constant_ {
+			check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
+		}
+
+		x.typ = resTyp
+
+	case _Make:
+		// make(T, n)
+		// make(T, n, m)
+		// (no argument evaluated yet)
+		arg0 := call.ArgList[0]
+		T := check.varType(arg0)
+		if T == Typ[Invalid] {
+			return
+		}
+
+		min, max := -1, 10
+		var valid func(t Type) bool
+		valid = func(t Type) bool {
+			var m int
+			switch t := optype(t).(type) {
+			case *Slice:
+				m = 2
+			case *Map, *Chan:
+				m = 1
+			case *Sum:
+				return t.is(valid)
+			default:
+				return false
+			}
+			if m > min {
+				min = m
+			}
+			if m+1 < max {
+				max = m + 1
+			}
+			return true
+		}
+
+		if !valid(T) {
+			check.errorf(arg0, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
+			return
+		}
+		if nargs < min || max < nargs {
+			if min == max {
+				check.errorf(call, "%v expects %d arguments; found %d", call, min, nargs)
+			} else {
+				check.errorf(call, "%v expects %d or %d arguments; found %d", call, min, max, nargs)
+			}
+			return
+		}
+
+		types := []Type{T}
+		var sizes []int64 // constant integer arguments, if any
+		for _, arg := range call.ArgList[1:] {
+			typ, size := check.index(arg, -1) // ok to continue with typ == Typ[Invalid]
+			types = append(types, typ)
+			if size >= 0 {
+				sizes = append(sizes, size)
+			}
+		}
+		if len(sizes) == 2 && sizes[0] > sizes[1] {
+			check.error(call.ArgList[1], invalidArg+"length and capacity swapped")
+			// safe to continue
+		}
+		x.mode = value
+		x.typ = T
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
+		}
+
+	case _New:
+		// new(T)
+		// (no argument evaluated yet)
+		T := check.varType(call.ArgList[0])
+		if T == Typ[Invalid] {
+			return
+		}
+
+		x.mode = value
+		x.typ = &Pointer{base: T}
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
+		}
+
+	case _Panic:
+		// panic(x)
+		// record panic call if inside a function with result parameters
+		// (for use in Checker.isTerminating)
+		if check.sig != nil && check.sig.results.Len() > 0 {
+			// function has result parameters
+			p := check.isPanic
+			if p == nil {
+				// allocate lazily
+				p = make(map[*syntax.CallExpr]bool)
+				check.isPanic = p
+			}
+			p[call] = true
+		}
+
+		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, &emptyInterface))
+		}
+
+	case _Print, _Println:
+		// print(x, y, ...)
+		// println(x, y, ...)
+		var params []Type
+		if nargs > 0 {
+			params = make([]Type, nargs)
+			for i := 0; i < nargs; i++ {
+				if i > 0 {
+					arg(x, i) // first argument already evaluated
+				}
+				check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name)
+				if x.mode == invalid {
+					// TODO(gri) "use" all arguments?
+					return
+				}
+				params[i] = x.typ
+			}
+		}
+
+		x.mode = novalue
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(nil, params...))
+		}
+
+	case _Recover:
+		// recover() interface{}
+		x.mode = value
+		x.typ = &emptyInterface
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ))
+		}
+
+	case _Add:
+		// unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer
+		if !check.allowVersion(check.pkg, 1, 17) {
+			check.error(call.Fun, "unsafe.Add requires go1.17 or later")
+			return
+		}
+
+		check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
+		if x.mode == invalid {
+			return
+		}
+
+		var y operand
+		arg(&y, 1)
+		if !check.isValidIndex(&y, "length", true) {
+			return
+		}
+
+		x.mode = value
+		x.typ = Typ[UnsafePointer]
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, x.typ, y.typ))
+		}
+
+	case _Alignof:
+		// unsafe.Alignof(x T) uintptr
+		if asTypeParam(x.typ) != nil {
+			check.errorf(call, invalidOp+"unsafe.Alignof undefined for %s", x)
+			return
+		}
+		check.assignment(x, nil, "argument to unsafe.Alignof")
+		if x.mode == invalid {
+			return
+		}
+
+		x.mode = constant_
+		x.val = constant.MakeInt64(check.conf.alignof(x.typ))
+		x.typ = Typ[Uintptr]
+		// result is constant - no need to record signature
+
+	case _Offsetof:
+		// unsafe.Offsetof(x T) uintptr, where x must be a selector
+		// (no argument evaluated yet)
+		arg0 := call.ArgList[0]
+		selx, _ := unparen(arg0).(*syntax.SelectorExpr)
+		if selx == nil {
+			check.errorf(arg0, invalidArg+"%s is not a selector expression", arg0)
+			check.use(arg0)
+			return
+		}
+
+		check.expr(x, selx.X)
+		if x.mode == invalid {
+			return
+		}
+
+		base := derefStructPtr(x.typ)
+		sel := selx.Sel.Value
+		obj, index, indirect := check.lookupFieldOrMethod(base, false, check.pkg, sel)
+		switch obj.(type) {
+		case nil:
+			check.errorf(x, invalidArg+"%s has no single field %s", base, sel)
+			return
+		case *Func:
+			// TODO(gri) Using derefStructPtr may result in methods being found
+			// that don't actually exist. An error either way, but the error
+			// message is confusing. See: https://play.golang.org/p/al75v23kUy ,
+			// but go/types reports: "invalid argument: x.m is a method value".
+			check.errorf(arg0, invalidArg+"%s is a method value", arg0)
+			return
+		}
+		if indirect {
+			check.errorf(x, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
+			return
+		}
+
+		// TODO(gri) Should we pass x.typ instead of base (and indirect report if derefStructPtr indirected)?
+		check.recordSelection(selx, FieldVal, base, obj, index, false)
+
+		offs := check.conf.offsetof(base, index)
+		x.mode = constant_
+		x.val = constant.MakeInt64(offs)
+		x.typ = Typ[Uintptr]
+		// result is constant - no need to record signature
+
+	case _Sizeof:
+		// unsafe.Sizeof(x T) uintptr
+		if asTypeParam(x.typ) != nil {
+			check.errorf(call, invalidOp+"unsafe.Sizeof undefined for %s", x)
+			return
+		}
+		check.assignment(x, nil, "argument to unsafe.Sizeof")
+		if x.mode == invalid {
+			return
+		}
+
+		x.mode = constant_
+		x.val = constant.MakeInt64(check.conf.sizeof(x.typ))
+		x.typ = Typ[Uintptr]
+		// result is constant - no need to record signature
+
+	case _Slice:
+		// unsafe.Slice(ptr *T, len IntegerType) []T
+		if !check.allowVersion(check.pkg, 1, 17) {
+			check.error(call.Fun, "unsafe.Slice requires go1.17 or later")
+			return
+		}
+
+		typ := asPointer(x.typ)
+		if typ == nil {
+			check.errorf(x, invalidArg+"%s is not a pointer", x)
+			return
+		}
+
+		var y operand
+		arg(&y, 1)
+		if !check.isValidIndex(&y, "length", false) {
+			return
+		}
+
+		x.mode = value
+		x.typ = NewSlice(typ.base)
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, typ, y.typ))
+		}
+
+	case _Assert:
+		// assert(pred) causes a typechecker error if pred is false.
+		// The result of assert is the value of pred if there is no error.
+		// Note: assert is only available in self-test mode.
+		if x.mode != constant_ || !isBoolean(x.typ) {
+			check.errorf(x, invalidArg+"%s is not a boolean constant", x)
+			return
+		}
+		if x.val.Kind() != constant.Bool {
+			check.errorf(x, "internal error: value of %s should be a boolean constant", x)
+			return
+		}
+		if !constant.BoolVal(x.val) {
+			check.errorf(call, "%v failed", call)
+			// compile-time assertion failure - safe to continue
+		}
+		// result is constant - no need to record signature
+
+	case _Trace:
+		// trace(x, y, z, ...) dumps the positions, expressions, and
+		// values of its arguments. The result of trace is the value
+		// of the first argument.
+		// Note: trace is only available in self-test mode.
+		// (no argument evaluated yet)
+		if nargs == 0 {
+			check.dump("%v: trace() without arguments", posFor(call))
+			x.mode = novalue
+			break
+		}
+		var t operand
+		x1 := x
+		for _, arg := range call.ArgList {
+			check.rawExpr(x1, arg, nil) // permit trace for types, e.g.: new(trace(T))
+			check.dump("%v: %s", posFor(x1), x1)
+			x1 = &t // use incoming x only for first argument
+		}
+		// trace is only available in test mode - no need to record signature
+
+	default:
+		unreachable()
+	}
+
+	return true
+}
+
+// applyTypeFunc applies f to x. If x is a type parameter,
+// the result is a type parameter constrained by an new
+// interface bound. The type bounds for that interface
+// are computed by applying f to each of the type bounds
+// of x. If any of these applications of f return nil,
+// applyTypeFunc returns nil.
+// If x is not a type parameter, the result is f(x).
+func (check *Checker) applyTypeFunc(f func(Type) Type, x Type) Type {
+	if tp := asTypeParam(x); tp != nil {
+		// Test if t satisfies the requirements for the argument
+		// type and collect possible result types at the same time.
+		var rtypes []Type
+		if !tp.Bound().is(func(x Type) bool {
+			if r := f(x); r != nil {
+				rtypes = append(rtypes, r)
+				return true
+			}
+			return false
+		}) {
+			return nil
+		}
+
+		// TODO(gri) Would it be ok to return just the one type
+		//           if len(rtypes) == 1? What about top-level
+		//           uses of real() where the result is used to
+		//           define type and initialize a variable?
+
+		// construct a suitable new type parameter
+		tpar := NewTypeName(nopos, nil /* = Universe pkg */, "<type parameter>", nil)
+		ptyp := check.NewTypeParam(tpar, 0, &emptyInterface) // assigns type to tpar as a side-effect
+		tsum := NewSum(rtypes)
+		ptyp.bound = &Interface{types: tsum, allMethods: markComplete, allTypes: tsum}
+
+		return ptyp
+	}
+
+	return f(x)
+}
+
+// makeSig makes a signature for the given argument and result types.
+// Default types are used for untyped arguments, and res may be nil.
+func makeSig(res Type, args ...Type) *Signature {
+	list := make([]*Var, len(args))
+	for i, param := range args {
+		list[i] = NewVar(nopos, nil, "", Default(param))
+	}
+	params := NewTuple(list...)
+	var result *Tuple
+	if res != nil {
+		assert(!isUntyped(res))
+		result = NewTuple(NewVar(nopos, nil, "", res))
+	}
+	return &Signature{params: params, results: result}
+}
+
+// implicitArrayDeref returns A if typ is of the form *A and A is an array;
+// otherwise it returns typ.
+//
+func implicitArrayDeref(typ Type) Type {
+	if p, ok := typ.(*Pointer); ok {
+		if a := asArray(p.base); a != nil {
+			return a
+		}
+	}
+	return typ
+}
+
+// unparen returns e with any enclosing parentheses stripped.
+func unparen(e syntax.Expr) syntax.Expr {
+	for {
+		p, ok := e.(*syntax.ParenExpr)
+		if !ok {
+			return e
+		}
+		e = p.X
+	}
+}
diff --git a/src/cmd/compile/internal/types2/builtins_test.go b/src/cmd/compile/internal/types2/builtins_test.go
new file mode 100644
index 0000000..82c786b
--- /dev/null
+++ b/src/cmd/compile/internal/types2/builtins_test.go
@@ -0,0 +1,228 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2_test
+
+import (
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"testing"
+
+	. "cmd/compile/internal/types2"
+)
+
+var builtinCalls = []struct {
+	name, src, sig string
+}{
+	{"append", `var s []int; _ = append(s)`, `func([]int, ...int) []int`},
+	{"append", `var s []int; _ = append(s, 0)`, `func([]int, ...int) []int`},
+	{"append", `var s []int; _ = (append)(s, 0)`, `func([]int, ...int) []int`},
+	{"append", `var s []byte; _ = ((append))(s, 0)`, `func([]byte, ...byte) []byte`},
+	{"append", `var s []byte; _ = append(s, "foo"...)`, `func([]byte, string...) []byte`},
+	{"append", `type T []byte; var s T; var str string; _ = append(s, str...)`, `func(p.T, string...) p.T`},
+	{"append", `type T []byte; type U string; var s T; var str U; _ = append(s, str...)`, `func(p.T, p.U...) p.T`},
+
+	{"cap", `var s [10]int; _ = cap(s)`, `invalid type`},  // constant
+	{"cap", `var s [10]int; _ = cap(&s)`, `invalid type`}, // constant
+	{"cap", `var s []int64; _ = cap(s)`, `func([]int64) int`},
+	{"cap", `var c chan<-bool; _ = cap(c)`, `func(chan<- bool) int`},
+
+	{"len", `_ = len("foo")`, `invalid type`}, // constant
+	{"len", `var s string; _ = len(s)`, `func(string) int`},
+	{"len", `var s [10]int; _ = len(s)`, `invalid type`},  // constant
+	{"len", `var s [10]int; _ = len(&s)`, `invalid type`}, // constant
+	{"len", `var s []int64; _ = len(s)`, `func([]int64) int`},
+	{"len", `var c chan<-bool; _ = len(c)`, `func(chan<- bool) int`},
+	{"len", `var m map[string]float32; _ = len(m)`, `func(map[string]float32) int`},
+
+	{"close", `var c chan int; close(c)`, `func(chan int)`},
+	{"close", `var c chan<- chan string; close(c)`, `func(chan<- chan string)`},
+
+	{"complex", `_ = complex(1, 0)`, `invalid type`}, // constant
+	{"complex", `var re float32; _ = complex(re, 1.0)`, `func(float32, float32) complex64`},
+	{"complex", `var im float64; _ = complex(1, im)`, `func(float64, float64) complex128`},
+	{"complex", `type F32 float32; var re, im F32; _ = complex(re, im)`, `func(p.F32, p.F32) complex64`},
+	{"complex", `type F64 float64; var re, im F64; _ = complex(re, im)`, `func(p.F64, p.F64) complex128`},
+
+	{"copy", `var src, dst []byte; copy(dst, src)`, `func([]byte, []byte) int`},
+	{"copy", `type T [][]int; var src, dst T; _ = copy(dst, src)`, `func(p.T, p.T) int`},
+	{"copy", `var src string; var dst []byte; copy(dst, src)`, `func([]byte, string) int`},
+	{"copy", `type T string; type U []byte; var src T; var dst U; copy(dst, src)`, `func(p.U, p.T) int`},
+	{"copy", `var dst []byte; copy(dst, "hello")`, `func([]byte, string) int`},
+
+	{"delete", `var m map[string]bool; delete(m, "foo")`, `func(map[string]bool, string)`},
+	{"delete", `type (K string; V int); var m map[K]V; delete(m, "foo")`, `func(map[p.K]p.V, p.K)`},
+
+	{"imag", `_ = imag(1i)`, `invalid type`}, // constant
+	{"imag", `var c complex64; _ = imag(c)`, `func(complex64) float32`},
+	{"imag", `var c complex128; _ = imag(c)`, `func(complex128) float64`},
+	{"imag", `type C64 complex64; var c C64; _ = imag(c)`, `func(p.C64) float32`},
+	{"imag", `type C128 complex128; var c C128; _ = imag(c)`, `func(p.C128) float64`},
+
+	{"real", `_ = real(1i)`, `invalid type`}, // constant
+	{"real", `var c complex64; _ = real(c)`, `func(complex64) float32`},
+	{"real", `var c complex128; _ = real(c)`, `func(complex128) float64`},
+	{"real", `type C64 complex64; var c C64; _ = real(c)`, `func(p.C64) float32`},
+	{"real", `type C128 complex128; var c C128; _ = real(c)`, `func(p.C128) float64`},
+
+	{"make", `_ = make([]int, 10)`, `func([]int, int) []int`},
+	{"make", `type T []byte; _ = make(T, 10, 20)`, `func(p.T, int, int) p.T`},
+
+	// issue #37349
+	{"make", `              _ = make([]int, 0   )`, `func([]int, int) []int`},
+	{"make", `var l    int; _ = make([]int, l   )`, `func([]int, int) []int`},
+	{"make", `              _ = make([]int, 0, 0)`, `func([]int, int, int) []int`},
+	{"make", `var l    int; _ = make([]int, l, 0)`, `func([]int, int, int) []int`},
+	{"make", `var    c int; _ = make([]int, 0, c)`, `func([]int, int, int) []int`},
+	{"make", `var l, c int; _ = make([]int, l, c)`, `func([]int, int, int) []int`},
+
+	// issue #37393
+	{"make", `                _ = make([]int       , 0   )`, `func([]int, int) []int`},
+	{"make", `var l    byte ; _ = make([]int8      , l   )`, `func([]int8, byte) []int8`},
+	{"make", `                _ = make([]int16     , 0, 0)`, `func([]int16, int, int) []int16`},
+	{"make", `var l    int16; _ = make([]string    , l, 0)`, `func([]string, int16, int) []string`},
+	{"make", `var    c int32; _ = make([]float64   , 0, c)`, `func([]float64, int, int32) []float64`},
+	{"make", `var l, c uint ; _ = make([]complex128, l, c)`, `func([]complex128, uint, uint) []complex128`},
+
+	// issue #45667
+	{"make", `const l uint = 1; _ = make([]int, l)`, `func([]int, uint) []int`},
+
+	{"new", `_ = new(int)`, `func(int) *int`},
+	{"new", `type T struct{}; _ = new(T)`, `func(p.T) *p.T`},
+
+	{"panic", `panic(0)`, `func(interface{})`},
+	{"panic", `panic("foo")`, `func(interface{})`},
+
+	{"print", `print()`, `func()`},
+	{"print", `print(0)`, `func(int)`},
+	{"print", `print(1, 2.0, "foo", true)`, `func(int, float64, string, bool)`},
+
+	{"println", `println()`, `func()`},
+	{"println", `println(0)`, `func(int)`},
+	{"println", `println(1, 2.0, "foo", true)`, `func(int, float64, string, bool)`},
+
+	{"recover", `recover()`, `func() interface{}`},
+	{"recover", `_ = recover()`, `func() interface{}`},
+
+	{"Add", `var p unsafe.Pointer; _ = unsafe.Add(p, -1.0)`, `func(unsafe.Pointer, int) unsafe.Pointer`},
+	{"Add", `var p unsafe.Pointer; var n uintptr; _ = unsafe.Add(p, n)`, `func(unsafe.Pointer, uintptr) unsafe.Pointer`},
+	{"Add", `_ = unsafe.Add(nil, 0)`, `func(unsafe.Pointer, int) unsafe.Pointer`},
+
+	{"Alignof", `_ = unsafe.Alignof(0)`, `invalid type`},                 // constant
+	{"Alignof", `var x struct{}; _ = unsafe.Alignof(x)`, `invalid type`}, // constant
+
+	{"Offsetof", `var x struct{f bool}; _ = unsafe.Offsetof(x.f)`, `invalid type`},           // constant
+	{"Offsetof", `var x struct{_ int; f bool}; _ = unsafe.Offsetof((&x).f)`, `invalid type`}, // constant
+
+	{"Sizeof", `_ = unsafe.Sizeof(0)`, `invalid type`},                 // constant
+	{"Sizeof", `var x struct{}; _ = unsafe.Sizeof(x)`, `invalid type`}, // constant
+
+	{"Slice", `var p *int; _ = unsafe.Slice(p, 1)`, `func(*int, int) []int`},
+	{"Slice", `var p *byte; var n uintptr; _ = unsafe.Slice(p, n)`, `func(*byte, uintptr) []byte`},
+
+	{"assert", `assert(true)`, `invalid type`},                                    // constant
+	{"assert", `type B bool; const pred B = 1 < 2; assert(pred)`, `invalid type`}, // constant
+
+	// no tests for trace since it produces output as a side-effect
+}
+
+func TestBuiltinSignatures(t *testing.T) {
+	DefPredeclaredTestFuncs()
+
+	seen := map[string]bool{"trace": true} // no test for trace built-in; add it manually
+	for _, call := range builtinCalls {
+		testBuiltinSignature(t, call.name, call.src, call.sig)
+		seen[call.name] = true
+	}
+
+	// make sure we didn't miss one
+	for _, name := range Universe.Names() {
+		if _, ok := Universe.Lookup(name).(*Builtin); ok && !seen[name] {
+			t.Errorf("missing test for %s", name)
+		}
+	}
+	for _, name := range Unsafe.Scope().Names() {
+		if _, ok := Unsafe.Scope().Lookup(name).(*Builtin); ok && !seen[name] {
+			t.Errorf("missing test for unsafe.%s", name)
+		}
+	}
+}
+
+func testBuiltinSignature(t *testing.T, name, src0, want string) {
+	src := fmt.Sprintf(`package p; import "unsafe"; type _ unsafe.Pointer /* use unsafe */; func _() { %s }`, src0)
+	f, err := parseSrc("", src)
+	if err != nil {
+		t.Errorf("%s: %s", src0, err)
+		return
+	}
+
+	conf := Config{Importer: defaultImporter()}
+	uses := make(map[*syntax.Name]Object)
+	types := make(map[syntax.Expr]TypeAndValue)
+	_, err = conf.Check(f.PkgName.Value, []*syntax.File{f}, &Info{Uses: uses, Types: types})
+	if err != nil {
+		t.Errorf("%s: %s", src0, err)
+		return
+	}
+
+	// find called function
+	n := 0
+	var fun syntax.Expr
+	for x := range types {
+		if call, _ := x.(*syntax.CallExpr); call != nil {
+			fun = call.Fun
+			n++
+		}
+	}
+	if n != 1 {
+		t.Errorf("%s: got %d CallExprs; want 1", src0, n)
+		return
+	}
+
+	// check recorded types for fun and descendents (may be parenthesized)
+	for {
+		// the recorded type for the built-in must match the wanted signature
+		typ := types[fun].Type
+		if typ == nil {
+			t.Errorf("%s: no type recorded for %s", src0, syntax.String(fun))
+			return
+		}
+		if got := typ.String(); got != want {
+			t.Errorf("%s: got type %s; want %s", src0, got, want)
+			return
+		}
+
+		// called function must be a (possibly parenthesized, qualified)
+		// identifier denoting the expected built-in
+		switch p := fun.(type) {
+		case *syntax.Name:
+			obj := uses[p]
+			if obj == nil {
+				t.Errorf("%s: no object found for %s", src0, p.Value)
+				return
+			}
+			bin, _ := obj.(*Builtin)
+			if bin == nil {
+				t.Errorf("%s: %s does not denote a built-in", src0, p.Value)
+				return
+			}
+			if bin.Name() != name {
+				t.Errorf("%s: got built-in %s; want %s", src0, bin.Name(), name)
+				return
+			}
+			return // we're done
+
+		case *syntax.ParenExpr:
+			fun = p.X // unpack
+
+		case *syntax.SelectorExpr:
+			// built-in from package unsafe - ignore details
+			return // we're done
+
+		default:
+			t.Errorf("%s: invalid function call", src0)
+			return
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/types2/call.go b/src/cmd/compile/internal/types2/call.go
new file mode 100644
index 0000000..6d14934
--- /dev/null
+++ b/src/cmd/compile/internal/types2/call.go
@@ -0,0 +1,696 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements typechecking of call and selector expressions.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"strings"
+	"unicode"
+)
+
+// funcInst type-checks a function instantiation inst and returns the result in x.
+// The operand x must be the evaluation of inst.X and its type must be a signature.
+func (check *Checker) funcInst(x *operand, inst *syntax.IndexExpr) {
+	xlist := unpackExpr(inst.Index)
+	targs := check.typeList(xlist)
+	if targs == nil {
+		x.mode = invalid
+		x.expr = inst
+		return
+	}
+	assert(len(targs) == len(xlist))
+
+	// check number of type arguments (got) vs number of type parameters (want)
+	sig := x.typ.(*Signature)
+	got, want := len(targs), len(sig.tparams)
+	if !useConstraintTypeInference && got != want || got > want {
+		check.errorf(xlist[got-1], "got %d type arguments but want %d", got, want)
+		x.mode = invalid
+		x.expr = inst
+		return
+	}
+
+	// if we don't have enough type arguments, try type inference
+	inferred := false
+	if got < want {
+		targs = check.infer(inst.Pos(), sig.tparams, targs, nil, nil, true)
+		if targs == nil {
+			// error was already reported
+			x.mode = invalid
+			x.expr = inst
+			return
+		}
+		got = len(targs)
+		inferred = true
+	}
+	assert(got == want)
+
+	// determine argument positions (for error reporting)
+	poslist := make([]syntax.Pos, len(xlist))
+	for i, x := range xlist {
+		poslist[i] = syntax.StartPos(x)
+	}
+
+	// instantiate function signature
+	res := check.instantiate(x.Pos(), sig, targs, poslist).(*Signature)
+	assert(res.tparams == nil) // signature is not generic anymore
+	if inferred {
+		check.recordInferred(inst, targs, res)
+	}
+	x.typ = res
+	x.mode = value
+	x.expr = inst
+}
+
+func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
+	var inst *syntax.IndexExpr // function instantiation, if any
+	if iexpr, _ := call.Fun.(*syntax.IndexExpr); iexpr != nil {
+		if check.indexExpr(x, iexpr) {
+			// Delay function instantiation to argument checking,
+			// where we combine type and value arguments for type
+			// inference.
+			assert(x.mode == value)
+			inst = iexpr
+		}
+		x.expr = iexpr
+		check.record(x)
+	} else {
+		check.exprOrType(x, call.Fun)
+	}
+
+	switch x.mode {
+	case invalid:
+		check.use(call.ArgList...)
+		x.expr = call
+		return statement
+
+	case typexpr:
+		// conversion
+		T := x.typ
+		x.mode = invalid
+		switch n := len(call.ArgList); n {
+		case 0:
+			check.errorf(call, "missing argument in conversion to %s", T)
+		case 1:
+			check.expr(x, call.ArgList[0])
+			if x.mode != invalid {
+				if t := asInterface(T); t != nil {
+					check.completeInterface(nopos, t)
+					if t.IsConstraint() {
+						check.errorf(call, "cannot use interface %s in conversion (contains type list or is comparable)", T)
+						break
+					}
+				}
+				if call.HasDots {
+					check.errorf(call.ArgList[0], "invalid use of ... in type conversion to %s", T)
+					break
+				}
+				check.conversion(x, T)
+			}
+		default:
+			check.use(call.ArgList...)
+			check.errorf(call.ArgList[n-1], "too many arguments in conversion to %s", T)
+		}
+		x.expr = call
+		return conversion
+
+	case builtin:
+		id := x.id
+		if !check.builtin(x, call, id) {
+			x.mode = invalid
+		}
+		x.expr = call
+		// a non-constant result implies a function call
+		if x.mode != invalid && x.mode != constant_ {
+			check.hasCallOrRecv = true
+		}
+		return predeclaredFuncs[id].kind
+	}
+
+	// ordinary function/method call
+	cgocall := x.mode == cgofunc
+
+	sig := asSignature(x.typ)
+	if sig == nil {
+		check.errorf(x, invalidOp+"cannot call non-function %s", x)
+		x.mode = invalid
+		x.expr = call
+		return statement
+	}
+
+	// evaluate type arguments, if any
+	var targs []Type
+	if inst != nil {
+		xlist := unpackExpr(inst.Index)
+		targs = check.typeList(xlist)
+		if targs == nil {
+			check.use(call.ArgList...)
+			x.mode = invalid
+			x.expr = call
+			return statement
+		}
+		assert(len(targs) == len(xlist))
+
+		// check number of type arguments (got) vs number of type parameters (want)
+		got, want := len(targs), len(sig.tparams)
+		if got > want {
+			check.errorf(xlist[want], "got %d type arguments but want %d", got, want)
+			check.use(call.ArgList...)
+			x.mode = invalid
+			x.expr = call
+			return statement
+		}
+	}
+
+	// evaluate arguments
+	args, _ := check.exprList(call.ArgList, false)
+	sig = check.arguments(call, sig, targs, args)
+
+	// determine result
+	switch sig.results.Len() {
+	case 0:
+		x.mode = novalue
+	case 1:
+		if cgocall {
+			x.mode = commaerr
+		} else {
+			x.mode = value
+		}
+		x.typ = sig.results.vars[0].typ // unpack tuple
+	default:
+		x.mode = value
+		x.typ = sig.results
+	}
+	x.expr = call
+	check.hasCallOrRecv = true
+
+	// if type inference failed, a parametrized result must be invalidated
+	// (operands cannot have a parametrized type)
+	if x.mode == value && len(sig.tparams) > 0 && isParameterized(sig.tparams, x.typ) {
+		x.mode = invalid
+	}
+
+	return statement
+}
+
+func (check *Checker) exprList(elist []syntax.Expr, allowCommaOk bool) (xlist []*operand, commaOk bool) {
+	switch len(elist) {
+	case 0:
+		// nothing to do
+
+	case 1:
+		// single (possibly comma-ok) value, or function returning multiple values
+		e := elist[0]
+		var x operand
+		check.multiExpr(&x, e)
+		if t, ok := x.typ.(*Tuple); ok && x.mode != invalid {
+			// multiple values
+			xlist = make([]*operand, t.Len())
+			for i, v := range t.vars {
+				xlist[i] = &operand{mode: value, expr: e, typ: v.typ}
+			}
+			break
+		}
+
+		// exactly one (possibly invalid or comma-ok) value
+		xlist = []*operand{&x}
+		if allowCommaOk && (x.mode == mapindex || x.mode == commaok || x.mode == commaerr) {
+			x.mode = value
+			xlist = append(xlist, &operand{mode: value, expr: e, typ: Typ[UntypedBool]})
+			commaOk = true
+		}
+
+	default:
+		// multiple (possibly invalid) values
+		xlist = make([]*operand, len(elist))
+		for i, e := range elist {
+			var x operand
+			check.expr(&x, e)
+			xlist[i] = &x
+		}
+	}
+
+	return
+}
+
+func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []Type, args []*operand) (rsig *Signature) {
+	rsig = sig
+
+	// TODO(gri) try to eliminate this extra verification loop
+	for _, a := range args {
+		switch a.mode {
+		case typexpr:
+			check.errorf(a, "%s used as value", a)
+			return
+		case invalid:
+			return
+		}
+	}
+
+	// Function call argument/parameter count requirements
+	//
+	//               | standard call    | dotdotdot call |
+	// --------------+------------------+----------------+
+	// standard func | nargs == npars   | invalid        |
+	// --------------+------------------+----------------+
+	// variadic func | nargs >= npars-1 | nargs == npars |
+	// --------------+------------------+----------------+
+
+	nargs := len(args)
+	npars := sig.params.Len()
+	ddd := call.HasDots
+
+	// set up parameters
+	sigParams := sig.params // adjusted for variadic functions (may be nil for empty parameter lists!)
+	adjusted := false       // indicates if sigParams is different from t.params
+	if sig.variadic {
+		if ddd {
+			// variadic_func(a, b, c...)
+			if len(call.ArgList) == 1 && nargs > 1 {
+				// f()... is not permitted if f() is multi-valued
+				//check.errorf(call.Ellipsis, "cannot use ... with %d-valued %s", nargs, call.ArgList[0])
+				check.errorf(call, "cannot use ... with %d-valued %s", nargs, call.ArgList[0])
+				return
+			}
+		} else {
+			// variadic_func(a, b, c)
+			if nargs >= npars-1 {
+				// Create custom parameters for arguments: keep
+				// the first npars-1 parameters and add one for
+				// each argument mapping to the ... parameter.
+				vars := make([]*Var, npars-1) // npars > 0 for variadic functions
+				copy(vars, sig.params.vars)
+				last := sig.params.vars[npars-1]
+				typ := last.typ.(*Slice).elem
+				for len(vars) < nargs {
+					vars = append(vars, NewParam(last.pos, last.pkg, last.name, typ))
+				}
+				sigParams = NewTuple(vars...) // possibly nil!
+				adjusted = true
+				npars = nargs
+			} else {
+				// nargs < npars-1
+				npars-- // for correct error message below
+			}
+		}
+	} else {
+		if ddd {
+			// standard_func(a, b, c...)
+			//check.errorf(call.Ellipsis, "cannot use ... in call to non-variadic %s", call.Fun)
+			check.errorf(call, "cannot use ... in call to non-variadic %s", call.Fun)
+			return
+		}
+		// standard_func(a, b, c)
+	}
+
+	// check argument count
+	switch {
+	case nargs < npars:
+		check.errorf(call, "not enough arguments in call to %s", call.Fun)
+		return
+	case nargs > npars:
+		check.errorf(args[npars], "too many arguments in call to %s", call.Fun) // report at first extra argument
+		return
+	}
+
+	// infer type arguments and instantiate signature if necessary
+	if len(sig.tparams) > 0 {
+		// TODO(gri) provide position information for targs so we can feed
+		//           it to the instantiate call for better error reporting
+		targs = check.infer(call.Pos(), sig.tparams, targs, sigParams, args, true)
+		if targs == nil {
+			return // error already reported
+		}
+
+		// compute result signature
+		rsig = check.instantiate(call.Pos(), sig, targs, nil).(*Signature)
+		assert(rsig.tparams == nil) // signature is not generic anymore
+		check.recordInferred(call, targs, rsig)
+
+		// Optimization: Only if the parameter list was adjusted do we
+		// need to compute it from the adjusted list; otherwise we can
+		// simply use the result signature's parameter list.
+		if adjusted {
+			sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(sig.tparams, targs)).(*Tuple)
+		} else {
+			sigParams = rsig.params
+		}
+	}
+
+	// check arguments
+	for i, a := range args {
+		check.assignment(a, sigParams.vars[i].typ, check.sprintf("argument to %s", call.Fun))
+	}
+
+	return
+}
+
+var cgoPrefixes = [...]string{
+	"_Ciconst_",
+	"_Cfconst_",
+	"_Csconst_",
+	"_Ctype_",
+	"_Cvar_", // actually a pointer to the var
+	"_Cfpvar_fp_",
+	"_Cfunc_",
+	"_Cmacro_", // function to evaluate the expanded expression
+}
+
+func (check *Checker) selector(x *operand, e *syntax.SelectorExpr) {
+	// these must be declared before the "goto Error" statements
+	var (
+		obj      Object
+		index    []int
+		indirect bool
+	)
+
+	sel := e.Sel.Value
+	// If the identifier refers to a package, handle everything here
+	// so we don't need a "package" mode for operands: package names
+	// can only appear in qualified identifiers which are mapped to
+	// selector expressions.
+	if ident, ok := e.X.(*syntax.Name); ok {
+		obj := check.lookup(ident.Value)
+		if pname, _ := obj.(*PkgName); pname != nil {
+			assert(pname.pkg == check.pkg)
+			check.recordUse(ident, pname)
+			pname.used = true
+			pkg := pname.imported
+
+			var exp Object
+			funcMode := value
+			if pkg.cgo {
+				// cgo special cases C.malloc: it's
+				// rewritten to _CMalloc and does not
+				// support two-result calls.
+				if sel == "malloc" {
+					sel = "_CMalloc"
+				} else {
+					funcMode = cgofunc
+				}
+				for _, prefix := range cgoPrefixes {
+					// cgo objects are part of the current package (in file
+					// _cgo_gotypes.go). Use regular lookup.
+					_, exp = check.scope.LookupParent(prefix+sel, check.pos)
+					if exp != nil {
+						break
+					}
+				}
+				if exp == nil {
+					check.errorf(e.Sel, "%s not declared by package C", sel)
+					goto Error
+				}
+				check.objDecl(exp, nil)
+			} else {
+				exp = pkg.scope.Lookup(sel)
+				if exp == nil {
+					if !pkg.fake {
+						if check.conf.CompilerErrorMessages {
+							check.errorf(e.Sel, "undefined: %s.%s", pkg.name, sel)
+						} else {
+							check.errorf(e.Sel, "%s not declared by package %s", sel, pkg.name)
+						}
+					}
+					goto Error
+				}
+				if !exp.Exported() {
+					check.errorf(e.Sel, "%s not exported by package %s", sel, pkg.name)
+					// ok to continue
+				}
+			}
+			check.recordUse(e.Sel, exp)
+
+			// Simplified version of the code for *syntax.Names:
+			// - imported objects are always fully initialized
+			switch exp := exp.(type) {
+			case *Const:
+				assert(exp.Val() != nil)
+				x.mode = constant_
+				x.typ = exp.typ
+				x.val = exp.val
+			case *TypeName:
+				x.mode = typexpr
+				x.typ = exp.typ
+			case *Var:
+				x.mode = variable
+				x.typ = exp.typ
+				if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") {
+					x.typ = x.typ.(*Pointer).base
+				}
+			case *Func:
+				x.mode = funcMode
+				x.typ = exp.typ
+				if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") {
+					x.mode = value
+					x.typ = x.typ.(*Signature).results.vars[0].typ
+				}
+			case *Builtin:
+				x.mode = builtin
+				x.typ = exp.typ
+				x.id = exp.id
+			default:
+				check.dump("%v: unexpected object %v", posFor(e.Sel), exp)
+				unreachable()
+			}
+			x.expr = e
+			return
+		}
+	}
+
+	check.exprOrType(x, e.X)
+	if x.mode == invalid {
+		goto Error
+	}
+
+	check.instantiatedOperand(x)
+
+	obj, index, indirect = check.lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
+	if obj == nil {
+		switch {
+		case index != nil:
+			// TODO(gri) should provide actual type where the conflict happens
+			check.errorf(e.Sel, "ambiguous selector %s.%s", x.expr, sel)
+		case indirect:
+			check.errorf(e.Sel, "cannot call pointer method %s on %s", sel, x.typ)
+		default:
+			var why string
+			if tpar := asTypeParam(x.typ); tpar != nil {
+				// Type parameter bounds don't specify fields, so don't mention "field".
+				switch obj := tpar.Bound().obj.(type) {
+				case nil:
+					why = check.sprintf("type bound for %s has no method %s", x.typ, sel)
+				case *TypeName:
+					why = check.sprintf("interface %s has no method %s", obj.name, sel)
+				}
+			} else {
+				why = check.sprintf("type %s has no field or method %s", x.typ, sel)
+			}
+
+			// Check if capitalization of sel matters and provide better error message in that case.
+			if len(sel) > 0 {
+				var changeCase string
+				if r := rune(sel[0]); unicode.IsUpper(r) {
+					changeCase = string(unicode.ToLower(r)) + sel[1:]
+				} else {
+					changeCase = string(unicode.ToUpper(r)) + sel[1:]
+				}
+				if obj, _, _ = check.lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, changeCase); obj != nil {
+					why += ", but does have " + changeCase
+				}
+			}
+
+			check.errorf(e.Sel, "%s.%s undefined (%s)", x.expr, sel, why)
+
+		}
+		goto Error
+	}
+
+	// methods may not have a fully set up signature yet
+	if m, _ := obj.(*Func); m != nil {
+		// check.dump("### found method %s", m)
+		check.objDecl(m, nil)
+		// If m has a parameterized receiver type, infer the type arguments from
+		// the actual receiver provided and then substitute the type parameters in
+		// the signature accordingly.
+		// TODO(gri) factor this code out
+		sig := m.typ.(*Signature)
+		if len(sig.rparams) > 0 {
+			// For inference to work, we must use the receiver type
+			// matching the receiver in the actual method declaration.
+			// If the method is embedded, the matching receiver is the
+			// embedded struct or interface that declared the method.
+			// Traverse the embedding to find that type (issue #44688).
+			recv := x.typ
+			for i := 0; i < len(index)-1; i++ {
+				// The embedded type is either a struct or a pointer to
+				// a struct except for the last one (which we don't need).
+				recv = asStruct(derefStructPtr(recv)).Field(index[i]).typ
+			}
+			//check.dump("### recv = %s", recv)
+			//check.dump("### method = %s rparams = %s tparams = %s", m, sig.rparams, sig.tparams)
+			// The method may have a pointer receiver, but the actually provided receiver
+			// may be a (hopefully addressable) non-pointer value, or vice versa. Here we
+			// only care about inferring receiver type parameters; to make the inference
+			// work, match up pointer-ness of receiver and argument.
+			if ptrRecv := isPointer(sig.recv.typ); ptrRecv != isPointer(recv) {
+				if ptrRecv {
+					recv = NewPointer(recv)
+				} else {
+					recv = recv.(*Pointer).base
+				}
+			}
+			// Disable reporting of errors during inference below. If we're unable to infer
+			// the receiver type arguments here, the receiver must be be otherwise invalid
+			// and an error has been reported elsewhere.
+			arg := operand{mode: variable, expr: x.expr, typ: recv}
+			targs := check.infer(m.pos, sig.rparams, nil, NewTuple(sig.recv), []*operand{&arg}, false /* no error reporting */)
+			//check.dump("### inferred targs = %s", targs)
+			if targs == nil {
+				// We may reach here if there were other errors (see issue #40056).
+				goto Error
+			}
+			// Don't modify m. Instead - for now - make a copy of m and use that instead.
+			// (If we modify m, some tests will fail; possibly because the m is in use.)
+			// TODO(gri) investigate and provide a correct explanation here
+			copy := *m
+			copy.typ = check.subst(e.Pos(), m.typ, makeSubstMap(sig.rparams, targs))
+			obj = &copy
+		}
+		// TODO(gri) we also need to do substitution for parameterized interface methods
+		//           (this breaks code in testdata/linalg.go2 at the moment)
+		//           12/20/2019: Is this TODO still correct?
+	}
+
+	if x.mode == typexpr {
+		// method expression
+		m, _ := obj.(*Func)
+		if m == nil {
+			// TODO(gri) should check if capitalization of sel matters and provide better error message in that case
+			check.errorf(e.Sel, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
+			goto Error
+		}
+
+		check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
+
+		// the receiver type becomes the type of the first function
+		// argument of the method expression's function type
+		var params []*Var
+		sig := m.typ.(*Signature)
+		if sig.params != nil {
+			params = sig.params.vars
+		}
+		x.mode = value
+		x.typ = &Signature{
+			tparams:  sig.tparams,
+			params:   NewTuple(append([]*Var{NewVar(nopos, check.pkg, "_", x.typ)}, params...)...),
+			results:  sig.results,
+			variadic: sig.variadic,
+		}
+
+		check.addDeclDep(m)
+
+	} else {
+		// regular selector
+		switch obj := obj.(type) {
+		case *Var:
+			check.recordSelection(e, FieldVal, x.typ, obj, index, indirect)
+			if x.mode == variable || indirect {
+				x.mode = variable
+			} else {
+				x.mode = value
+			}
+			x.typ = obj.typ
+
+		case *Func:
+			// TODO(gri) If we needed to take into account the receiver's
+			// addressability, should we report the type &(x.typ) instead?
+			check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
+
+			x.mode = value
+
+			// remove receiver
+			sig := *obj.typ.(*Signature)
+			sig.recv = nil
+			x.typ = &sig
+
+			check.addDeclDep(obj)
+
+		default:
+			unreachable()
+		}
+	}
+
+	// everything went well
+	x.expr = e
+	return
+
+Error:
+	x.mode = invalid
+	x.expr = e
+}
+
+// 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.
+// TODO(gri) make this accept a []syntax.Expr and use an unpack function when we have a ListExpr?
+func (check *Checker) use(arg ...syntax.Expr) {
+	var x operand
+	for _, e := range arg {
+		// Certain AST fields may legally be nil (e.g., the ast.SliceExpr.High field).
+		if e == nil {
+			continue
+		}
+		if l, _ := e.(*syntax.ListExpr); l != nil {
+			check.use(l.ElemList...)
+			continue
+		}
+		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 ...syntax.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).(*syntax.Name); ident != nil {
+			// never type-check the blank name on the lhs
+			if ident.Value == "_" {
+				continue
+			}
+			if _, obj := check.scope.LookupParent(ident.Value, 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
+		}
+	}
+}
+
+// instantiatedOperand reports an error of x is an uninstantiated (generic) type and sets x.typ to Typ[Invalid].
+func (check *Checker) instantiatedOperand(x *operand) {
+	if x.mode == typexpr && isGeneric(x.typ) {
+		check.errorf(x, "cannot use generic type %s without instantiation", x.typ)
+		x.typ = Typ[Invalid]
+	}
+}
diff --git a/src/cmd/compile/internal/types2/check.go b/src/cmd/compile/internal/types2/check.go
new file mode 100644
index 0000000..8d6cd1e
--- /dev/null
+++ b/src/cmd/compile/internal/types2/check.go
@@ -0,0 +1,466 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements the Check function, which drives type-checking.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"errors"
+	"fmt"
+	"go/constant"
+)
+
+var nopos syntax.Pos
+
+// debugging/development support
+const debug = false // leave on during development
+
+// If forceStrict is set, the type-checker enforces additional
+// rules not specified by the Go 1 spec, but which will
+// catch guaranteed run-time errors if the respective
+// code is executed. In other words, programs passing in
+// strict mode are Go 1 compliant, but not all Go 1 programs
+// will pass in strict mode. The additional rules are:
+//
+// - A type assertion x.(T) where T is an interface type
+//   is invalid if any (statically known) method that exists
+//   for both x and T have different signatures.
+//
+const forceStrict = false
+
+// exprInfo stores information about an untyped expression.
+type exprInfo struct {
+	isLhs bool // expression is lhs operand of a shift with delayed type-check
+	mode  operandMode
+	typ   *Basic
+	val   constant.Value // constant value; or nil (if not a constant)
+}
+
+// A context represents the context within which an object is type-checked.
+type context struct {
+	decl          *declInfo                 // package-level declaration whose init expression/function body is checked
+	scope         *Scope                    // top-most scope for lookups
+	pos           syntax.Pos                // if valid, identifiers are looked up as if at position pos (used by Eval)
+	iota          constant.Value            // value of iota in a constant declaration; nil otherwise
+	errpos        syntax.Pos                // if valid, identifier position of a constant with inherited initializer
+	sig           *Signature                // function signature if inside a function; nil otherwise
+	isPanic       map[*syntax.CallExpr]bool // set of panic call expressions (used for termination check)
+	hasLabel      bool                      // set if a function makes use of labels (only ~1% of functions); unused outside functions
+	hasCallOrRecv bool                      // set if an expression contains a function call or channel receive operation
+}
+
+// lookup looks up name in the current context and returns the matching object, or nil.
+func (ctxt *context) lookup(name string) Object {
+	_, obj := ctxt.scope.LookupParent(name, ctxt.pos)
+	return obj
+}
+
+// An importKey identifies an imported package by import path and source directory
+// (directory containing the file containing the import). In practice, the directory
+// may always be the same, or may not matter. Given an (import path, directory), an
+// importer must always return the same package (but given two different import paths,
+// an importer may still return the same package by mapping them to the same package
+// paths).
+type importKey struct {
+	path, dir string
+}
+
+// A dotImportKey describes a dot-imported object in the given scope.
+type dotImportKey struct {
+	scope *Scope
+	obj   Object
+}
+
+// A Checker maintains the state of the type checker.
+// It must be created with NewChecker.
+type Checker struct {
+	// package information
+	// (initialized by NewChecker, valid for the life-time of checker)
+	conf *Config
+	pkg  *Package
+	*Info
+	version version                     // accepted language version
+	objMap  map[Object]*declInfo        // maps package-level objects and (non-interface) methods to declaration info
+	impMap  map[importKey]*Package      // maps (import path, source directory) to (complete or fake) package
+	posMap  map[*Interface][]syntax.Pos // maps interface types to lists of embedded interface positions
+	typMap  map[string]*Named           // maps an instantiated named type hash to a *Named type
+
+	// pkgPathMap maps package names to the set of distinct import paths we've
+	// seen for that name, anywhere in the import graph. It is used for
+	// disambiguating package names in error messages.
+	//
+	// pkgPathMap is allocated lazily, so that we don't pay the price of building
+	// it on the happy path. seenPkgMap tracks the packages that we've already
+	// walked.
+	pkgPathMap map[string]map[string]bool
+	seenPkgMap map[*Package]bool
+
+	// information collected during type-checking of a set of package files
+	// (initialized by Files, valid only for the duration of check.Files;
+	// maps and lists are allocated on demand)
+	files        []*syntax.File            // list of package files
+	imports      []*PkgName                // list of imported packages
+	dotImportMap map[dotImportKey]*PkgName // maps dot-imported objects to the package they were dot-imported through
+
+	firstErr error                    // first error encountered
+	methods  map[*TypeName][]*Func    // maps package scope type names to associated non-blank (non-interface) methods
+	untyped  map[syntax.Expr]exprInfo // map of expressions without final type
+	delayed  []func()                 // stack of delayed action segments; segments are processed in FIFO order
+	objPath  []Object                 // path of object dependencies during type inference (for cycle reporting)
+
+	// context within which the current object is type-checked
+	// (valid only for the duration of type-checking a specific object)
+	context
+
+	// debugging
+	indent int // indentation for tracing
+}
+
+// addDeclDep adds the dependency edge (check.decl -> to) if check.decl exists
+func (check *Checker) addDeclDep(to Object) {
+	from := check.decl
+	if from == nil {
+		return // not in a package-level init expression
+	}
+	if _, found := check.objMap[to]; !found {
+		return // to is not a package-level object
+	}
+	from.addDep(to)
+}
+
+func (check *Checker) rememberUntyped(e syntax.Expr, lhs bool, mode operandMode, typ *Basic, val constant.Value) {
+	m := check.untyped
+	if m == nil {
+		m = make(map[syntax.Expr]exprInfo)
+		check.untyped = m
+	}
+	m[e] = exprInfo{lhs, mode, typ, val}
+}
+
+// later pushes f on to the stack of actions that will be processed later;
+// either at the end of the current statement, or in case of a local constant
+// or variable declaration, before the constant or variable is in scope
+// (so that f still sees the scope before any new declarations).
+func (check *Checker) later(f func()) {
+	check.delayed = append(check.delayed, f)
+}
+
+// push pushes obj onto the object path and returns its index in the path.
+func (check *Checker) push(obj Object) int {
+	check.objPath = append(check.objPath, obj)
+	return len(check.objPath) - 1
+}
+
+// pop pops and returns the topmost object from the object path.
+func (check *Checker) pop() Object {
+	i := len(check.objPath) - 1
+	obj := check.objPath[i]
+	check.objPath[i] = nil
+	check.objPath = check.objPath[:i]
+	return obj
+}
+
+// NewChecker returns a new Checker instance for a given package.
+// Package files may be added incrementally via checker.Files.
+func NewChecker(conf *Config, pkg *Package, info *Info) *Checker {
+	// make sure we have a configuration
+	if conf == nil {
+		conf = new(Config)
+	}
+
+	// make sure we have an info struct
+	if info == nil {
+		info = new(Info)
+	}
+
+	version, err := parseGoVersion(conf.GoVersion)
+	if err != nil {
+		panic(fmt.Sprintf("invalid Go version %q (%v)", conf.GoVersion, err))
+	}
+
+	return &Checker{
+		conf:    conf,
+		pkg:     pkg,
+		Info:    info,
+		version: version,
+		objMap:  make(map[Object]*declInfo),
+		impMap:  make(map[importKey]*Package),
+		posMap:  make(map[*Interface][]syntax.Pos),
+		typMap:  make(map[string]*Named),
+	}
+}
+
+// initFiles initializes the files-specific portion of checker.
+// The provided files must all belong to the same package.
+func (check *Checker) initFiles(files []*syntax.File) {
+	// start with a clean slate (check.Files may be called multiple times)
+	check.files = nil
+	check.imports = nil
+	check.dotImportMap = nil
+
+	check.firstErr = nil
+	check.methods = nil
+	check.untyped = nil
+	check.delayed = nil
+
+	// determine package name and collect valid files
+	pkg := check.pkg
+	for _, file := range files {
+		switch name := file.PkgName.Value; pkg.name {
+		case "":
+			if name != "_" {
+				pkg.name = name
+			} else {
+				check.error(file.PkgName, "invalid package name _")
+			}
+			fallthrough
+
+		case name:
+			check.files = append(check.files, file)
+
+		default:
+			check.errorf(file, "package %s; expected %s", name, pkg.name)
+			// ignore this file
+		}
+	}
+}
+
+// A bailout panic is used for early termination.
+type bailout struct{}
+
+func (check *Checker) handleBailout(err *error) {
+	switch p := recover().(type) {
+	case nil, bailout:
+		// normal return or early exit
+		*err = check.firstErr
+	default:
+		// re-panic
+		panic(p)
+	}
+}
+
+// Files checks the provided files as part of the checker's package.
+func (check *Checker) Files(files []*syntax.File) error { return check.checkFiles(files) }
+
+var errBadCgo = errors.New("cannot use FakeImportC and go115UsesCgo together")
+
+func (check *Checker) checkFiles(files []*syntax.File) (err error) {
+	if check.conf.FakeImportC && check.conf.go115UsesCgo {
+		return errBadCgo
+	}
+
+	defer check.handleBailout(&err)
+
+	print := func(msg string) {
+		if check.conf.Trace {
+			fmt.Println(msg)
+		}
+	}
+
+	print("== initFiles ==")
+	check.initFiles(files)
+
+	print("== collectObjects ==")
+	check.collectObjects()
+
+	print("== packageObjects ==")
+	check.packageObjects()
+
+	print("== processDelayed ==")
+	check.processDelayed(0) // incl. all functions
+
+	print("== initOrder ==")
+	check.initOrder()
+
+	if !check.conf.DisableUnusedImportCheck {
+		print("== unusedImports ==")
+		check.unusedImports()
+	}
+
+	print("== recordUntyped ==")
+	check.recordUntyped()
+
+	if check.Info != nil {
+		print("== sanitizeInfo ==")
+		sanitizeInfo(check.Info)
+	}
+
+	check.pkg.complete = true
+
+	// no longer needed - release memory
+	check.imports = nil
+	check.dotImportMap = nil
+	check.pkgPathMap = nil
+	check.seenPkgMap = nil
+
+	// TODO(gri) There's more memory we should release at this point.
+
+	return
+}
+
+// processDelayed processes all delayed actions pushed after top.
+func (check *Checker) processDelayed(top int) {
+	// If each delayed action pushes a new action, the
+	// stack will continue to grow during this loop.
+	// However, it is only processing functions (which
+	// are processed in a delayed fashion) that may
+	// add more actions (such as nested functions), so
+	// this is a sufficiently bounded process.
+	for i := top; i < len(check.delayed); i++ {
+		check.delayed[i]() // may append to check.delayed
+	}
+	assert(top <= len(check.delayed)) // stack must not have shrunk
+	check.delayed = check.delayed[:top]
+}
+
+func (check *Checker) record(x *operand) {
+	// convert x into a user-friendly set of values
+	// TODO(gri) this code can be simplified
+	var typ Type
+	var val constant.Value
+	switch x.mode {
+	case invalid:
+		typ = Typ[Invalid]
+	case novalue:
+		typ = (*Tuple)(nil)
+	case constant_:
+		typ = x.typ
+		val = x.val
+	default:
+		typ = x.typ
+	}
+	assert(x.expr != nil && typ != nil)
+
+	if isUntyped(typ) {
+		// delay type and value recording until we know the type
+		// or until the end of type checking
+		check.rememberUntyped(x.expr, false, x.mode, typ.(*Basic), val)
+	} else {
+		check.recordTypeAndValue(x.expr, x.mode, typ, val)
+	}
+}
+
+func (check *Checker) recordUntyped() {
+	if !debug && check.Types == nil {
+		return // nothing to do
+	}
+
+	for x, info := range check.untyped {
+		if debug && isTyped(info.typ) {
+			check.dump("%v: %s (type %s) is typed", posFor(x), x, info.typ)
+			unreachable()
+		}
+		check.recordTypeAndValue(x, info.mode, info.typ, info.val)
+	}
+}
+
+func (check *Checker) recordTypeAndValue(x syntax.Expr, mode operandMode, typ Type, val constant.Value) {
+	assert(x != nil)
+	assert(typ != nil)
+	if mode == invalid {
+		return // omit
+	}
+	if mode == constant_ {
+		assert(val != nil)
+		// We check is(typ, IsConstType) here as constant expressions may be
+		// recorded as type parameters.
+		assert(typ == Typ[Invalid] || is(typ, IsConstType))
+	}
+	if m := check.Types; m != nil {
+		m[x] = TypeAndValue{mode, typ, val}
+	}
+}
+
+func (check *Checker) recordBuiltinType(f syntax.Expr, sig *Signature) {
+	// f must be a (possibly parenthesized, possibly qualified)
+	// identifier denoting a built-in (including unsafe's non-constant
+	// functions Add and Slice): record the signature for f and possible
+	// children.
+	for {
+		check.recordTypeAndValue(f, builtin, sig, nil)
+		switch p := f.(type) {
+		case *syntax.Name, *syntax.SelectorExpr:
+			return // we're done
+		case *syntax.ParenExpr:
+			f = p.X
+		default:
+			unreachable()
+		}
+	}
+}
+
+func (check *Checker) recordCommaOkTypes(x syntax.Expr, a [2]Type) {
+	assert(x != nil)
+	if a[0] == nil || a[1] == nil {
+		return
+	}
+	assert(isTyped(a[0]) && isTyped(a[1]) && (isBoolean(a[1]) || a[1] == universeError))
+	if m := check.Types; m != nil {
+		for {
+			tv := m[x]
+			assert(tv.Type != nil) // should have been recorded already
+			pos := x.Pos()
+			tv.Type = NewTuple(
+				NewVar(pos, check.pkg, "", a[0]),
+				NewVar(pos, check.pkg, "", a[1]),
+			)
+			m[x] = tv
+			// if x is a parenthesized expression (p.X), update p.X
+			p, _ := x.(*syntax.ParenExpr)
+			if p == nil {
+				break
+			}
+			x = p.X
+		}
+	}
+}
+
+func (check *Checker) recordInferred(call syntax.Expr, targs []Type, sig *Signature) {
+	assert(call != nil)
+	assert(sig != nil)
+	if m := check.Inferred; m != nil {
+		m[call] = Inferred{targs, sig}
+	}
+}
+
+func (check *Checker) recordDef(id *syntax.Name, obj Object) {
+	assert(id != nil)
+	if m := check.Defs; m != nil {
+		m[id] = obj
+	}
+}
+
+func (check *Checker) recordUse(id *syntax.Name, obj Object) {
+	assert(id != nil)
+	assert(obj != nil)
+	if m := check.Uses; m != nil {
+		m[id] = obj
+	}
+}
+
+func (check *Checker) recordImplicit(node syntax.Node, obj Object) {
+	assert(node != nil)
+	assert(obj != nil)
+	if m := check.Implicits; m != nil {
+		m[node] = obj
+	}
+}
+
+func (check *Checker) recordSelection(x *syntax.SelectorExpr, kind SelectionKind, recv Type, obj Object, index []int, indirect bool) {
+	assert(obj != nil && (recv == nil || len(index) > 0))
+	check.recordUse(x.Sel, obj)
+	if m := check.Selections; m != nil {
+		m[x] = &Selection{kind, recv, obj, index, indirect}
+	}
+}
+
+func (check *Checker) recordScope(node syntax.Node, scope *Scope) {
+	assert(node != nil)
+	assert(scope != nil)
+	if m := check.Scopes; m != nil {
+		m[node] = scope
+	}
+}
diff --git a/src/cmd/compile/internal/types2/check_test.go b/src/cmd/compile/internal/types2/check_test.go
new file mode 100644
index 0000000..41b0c54
--- /dev/null
+++ b/src/cmd/compile/internal/types2/check_test.go
@@ -0,0 +1,326 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements a typechecker test harness. The packages specified
+// in tests are typechecked. Error messages reported by the typechecker are
+// compared against the error messages expected in the test files.
+//
+// Expected errors are indicated in the test files by putting a comment
+// of the form /* ERROR "rx" */ immediately following an offending token.
+// The harness will verify that an error matching the regular expression
+// rx is reported at that source position. Consecutive comments may be
+// used to indicate multiple errors for the same token position.
+//
+// For instance, the following test file indicates that a "not declared"
+// error should be reported for the undeclared variable x:
+//
+//	package p
+//	func f() {
+//		_ = x /* ERROR "not declared" */ + 1
+//	}
+
+// TODO(gri) Also collect strict mode errors of the form /* STRICT ... */
+//           and test against strict mode.
+
+package types2_test
+
+import (
+	"cmd/compile/internal/syntax"
+	"flag"
+	"internal/testenv"
+	"os"
+	"path/filepath"
+	"regexp"
+	"sort"
+	"strings"
+	"testing"
+
+	. "cmd/compile/internal/types2"
+)
+
+var (
+	haltOnError  = flag.Bool("halt", false, "halt on error")
+	verifyErrors = flag.Bool("verify", false, "verify errors (rather than list them) in TestManual")
+	goVersion    = flag.String("lang", "", "Go language version (e.g. \"go1.12\")")
+)
+
+func parseFiles(t *testing.T, filenames []string, mode syntax.Mode) ([]*syntax.File, []error) {
+	var files []*syntax.File
+	var errlist []error
+	errh := func(err error) { errlist = append(errlist, err) }
+	for _, filename := range filenames {
+		file, err := syntax.ParseFile(filename, errh, nil, mode)
+		if file == nil {
+			t.Fatalf("%s: %s", filename, err)
+		}
+		files = append(files, file)
+	}
+	return files, errlist
+}
+
+func unpackError(err error) syntax.Error {
+	switch err := err.(type) {
+	case syntax.Error:
+		return err
+	case Error:
+		return syntax.Error{Pos: err.Pos, Msg: err.Msg}
+	default:
+		return syntax.Error{Msg: err.Error()}
+	}
+}
+
+// delta returns the absolute difference between x and y.
+func delta(x, y uint) uint {
+	switch {
+	case x < y:
+		return y - x
+	case x > y:
+		return x - y
+	default:
+		return 0
+	}
+}
+
+// goVersionRx matches a Go version string using '_', e.g. "go1_12".
+var goVersionRx = regexp.MustCompile(`^go[1-9][0-9]*_(0|[1-9][0-9]*)$`)
+
+// asGoVersion returns a regular Go language version string
+// if s is a Go version string using '_' rather than '.' to
+// separate the major and minor version numbers (e.g. "go1_12").
+// Otherwise it returns the empty string.
+func asGoVersion(s string) string {
+	if goVersionRx.MatchString(s) {
+		return strings.Replace(s, "_", ".", 1)
+	}
+	return ""
+}
+
+func testFiles(t *testing.T, filenames []string, colDelta uint, manual bool) {
+	if len(filenames) == 0 {
+		t.Fatal("no source files")
+	}
+
+	var mode syntax.Mode
+	if strings.HasSuffix(filenames[0], ".go2") {
+		mode |= syntax.AllowGenerics
+	}
+	// parse files and collect parser errors
+	files, errlist := parseFiles(t, filenames, mode)
+
+	pkgName := "<no package>"
+	if len(files) > 0 {
+		pkgName = files[0].PkgName.Value
+	}
+
+	// if no Go version is given, consider the package name
+	goVersion := *goVersion
+	if goVersion == "" {
+		goVersion = asGoVersion(pkgName)
+	}
+
+	listErrors := manual && !*verifyErrors
+	if listErrors && len(errlist) > 0 {
+		t.Errorf("--- %s:", pkgName)
+		for _, err := range errlist {
+			t.Error(err)
+		}
+	}
+
+	// typecheck and collect typechecker errors
+	var conf Config
+	conf.GoVersion = goVersion
+	// special case for importC.src
+	if len(filenames) == 1 && strings.HasSuffix(filenames[0], "importC.src") {
+		conf.FakeImportC = true
+	}
+	conf.Trace = manual && testing.Verbose()
+	conf.Importer = defaultImporter()
+	conf.Error = func(err error) {
+		if *haltOnError {
+			defer panic(err)
+		}
+		if listErrors {
+			t.Error(err)
+			return
+		}
+		errlist = append(errlist, err)
+	}
+	conf.Check(pkgName, files, nil)
+
+	if listErrors {
+		return
+	}
+
+	// sort errlist in source order
+	sort.Slice(errlist, func(i, j int) bool {
+		pi := unpackError(errlist[i]).Pos
+		pj := unpackError(errlist[j]).Pos
+		return pi.Cmp(pj) < 0
+	})
+
+	// collect expected errors
+	errmap := make(map[string]map[uint][]syntax.Error)
+	for _, filename := range filenames {
+		f, err := os.Open(filename)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		if m := syntax.ErrorMap(f); len(m) > 0 {
+			errmap[filename] = m
+		}
+		f.Close()
+	}
+
+	// match against found errors
+	for _, err := range errlist {
+		got := unpackError(err)
+
+		// find list of errors for the respective error line
+		filename := got.Pos.Base().Filename()
+		filemap := errmap[filename]
+		line := got.Pos.Line()
+		var list []syntax.Error
+		if filemap != nil {
+			list = filemap[line]
+		}
+		// list may be nil
+
+		// one of errors in list should match the current error
+		index := -1 // list index of matching message, if any
+		for i, want := range list {
+			rx, err := regexp.Compile(want.Msg)
+			if err != nil {
+				t.Errorf("%s:%d:%d: %v", filename, line, want.Pos.Col(), err)
+				continue
+			}
+			if rx.MatchString(got.Msg) {
+				index = i
+				break
+			}
+		}
+		if index < 0 {
+			t.Errorf("%s: no error expected: %q", got.Pos, got.Msg)
+			continue
+		}
+
+		// column position must be within expected colDelta
+		want := list[index]
+		if delta(got.Pos.Col(), want.Pos.Col()) > colDelta {
+			t.Errorf("%s: got col = %d; want %d", got.Pos, got.Pos.Col(), want.Pos.Col())
+		}
+
+		// eliminate from list
+		if n := len(list) - 1; n > 0 {
+			// not the last entry - slide entries down (don't reorder)
+			copy(list[index:], list[index+1:])
+			filemap[line] = list[:n]
+		} else {
+			// last entry - remove list from filemap
+			delete(filemap, line)
+		}
+
+		// if filemap is empty, eliminate from errmap
+		if len(filemap) == 0 {
+			delete(errmap, filename)
+		}
+	}
+
+	// there should be no expected errors left
+	if len(errmap) > 0 {
+		t.Errorf("--- %s: unreported errors:", pkgName)
+		for filename, filemap := range errmap {
+			for line, list := range filemap {
+				for _, err := range list {
+					t.Errorf("%s:%d:%d: %s", filename, line, err.Pos.Col(), err.Msg)
+				}
+			}
+		}
+	}
+}
+
+// TestManual is for manual testing of a package - either provided
+// as a list of filenames belonging to the package, or a directory
+// name containing the package files - after the test arguments
+// (and a separating "--"). For instance, to test the package made
+// of the files foo.go and bar.go, use:
+//
+// 	go test -run Manual -- foo.go bar.go
+//
+// If no source arguments are provided, the file testdata/manual.go2
+// is used instead.
+// Provide the -verify flag to verify errors against ERROR comments
+// in the input files rather than having a list of errors reported.
+// The accepted Go language version can be controlled with the -lang
+// flag.
+func TestManual(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	filenames := flag.Args()
+	if len(filenames) == 0 {
+		filenames = []string{filepath.FromSlash("testdata/manual.go2")}
+	}
+
+	info, err := os.Stat(filenames[0])
+	if err != nil {
+		t.Fatalf("TestManual: %v", err)
+	}
+
+	DefPredeclaredTestFuncs()
+	if info.IsDir() {
+		if len(filenames) > 1 {
+			t.Fatal("TestManual: must have only one directory argument")
+		}
+		testDir(t, filenames[0], 0, true)
+	} else {
+		testFiles(t, filenames, 0, true)
+	}
+}
+
+// TODO(gri) go/types has extra TestLongConstants and TestIndexRepresentability tests
+
+func TestCheck(t *testing.T)     { DefPredeclaredTestFuncs(); testDirFiles(t, "testdata/check", 75, false) } // TODO(gri) narrow column tolerance
+func TestExamples(t *testing.T)  { testDirFiles(t, "testdata/examples", 0, false) }
+func TestFixedbugs(t *testing.T) { testDirFiles(t, "testdata/fixedbugs", 0, false) }
+
+func testDirFiles(t *testing.T, dir string, colDelta uint, manual bool) {
+	testenv.MustHaveGoBuild(t)
+	dir = filepath.FromSlash(dir)
+
+	fis, err := os.ReadDir(dir)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	for _, fi := range fis {
+		path := filepath.Join(dir, fi.Name())
+
+		// If fi is a directory, its files make up a single package.
+		if fi.IsDir() {
+			testDir(t, path, colDelta, manual)
+		} else {
+			t.Run(filepath.Base(path), func(t *testing.T) {
+				testFiles(t, []string{path}, colDelta, manual)
+			})
+		}
+	}
+}
+
+func testDir(t *testing.T, dir string, colDelta uint, manual bool) {
+	fis, err := os.ReadDir(dir)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	var filenames []string
+	for _, fi := range fis {
+		filenames = append(filenames, filepath.Join(dir, fi.Name()))
+	}
+
+	t.Run(filepath.Base(dir), func(t *testing.T) {
+		testFiles(t, filenames, colDelta, manual)
+	})
+}
diff --git a/src/cmd/compile/internal/types2/conversions.go b/src/cmd/compile/internal/types2/conversions.go
new file mode 100644
index 0000000..30201e2
--- /dev/null
+++ b/src/cmd/compile/internal/types2/conversions.go
@@ -0,0 +1,188 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements typechecking of conversions.
+
+package types2
+
+import (
+	"go/constant"
+	"unicode"
+)
+
+// Conversion type-checks the conversion T(x).
+// The result is in x.
+func (check *Checker) conversion(x *operand, T Type) {
+	constArg := x.mode == constant_
+
+	var ok bool
+	switch {
+	case constArg && isConstType(T):
+		// constant conversion
+		switch t := asBasic(T); {
+		case representableConst(x.val, check, t, &x.val):
+			ok = true
+		case isInteger(x.typ) && isString(t):
+			codepoint := unicode.ReplacementChar
+			if i, ok := constant.Uint64Val(x.val); ok && i <= unicode.MaxRune {
+				codepoint = rune(i)
+			}
+			x.val = constant.MakeString(string(codepoint))
+			ok = true
+		}
+	case x.convertibleTo(check, T):
+		// non-constant conversion
+		x.mode = value
+		ok = true
+	}
+
+	if !ok {
+		if x.mode != invalid {
+			check.errorf(x, "cannot convert %s to %s", x, T)
+			x.mode = invalid
+		}
+		return
+	}
+
+	// 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,...".
+	if isUntyped(x.typ) {
+		final := T
+		// - For conversions to interfaces, except for untyped nil arguments,
+		//   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").
+		// - For integer to string conversions, keep the argument type.
+		//   (See also the TODO below.)
+		if x.typ == Typ[UntypedNil] {
+			// ok
+		} else 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)
+	}
+
+	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.)
+
+// convertibleTo reports whether T(x) is valid.
+// The check parameter may be nil if convertibleTo is invoked through an
+// exported API call, i.e., when all methods have been type-checked.
+func (x *operand) convertibleTo(check *Checker, T Type) bool {
+	// "x is assignable to T"
+	if ok, _ := x.assignableTo(check, T, nil); ok {
+		return true
+	}
+
+	// "x's type and T have identical underlying types if tags are ignored"
+	V := x.typ
+	Vu := under(V)
+	Tu := under(T)
+	if check.identicalIgnoreTags(Vu, Tu) {
+		return true
+	}
+
+	// "x's type and T are unnamed pointer types and their pointer base types
+	// have identical underlying types if tags are ignored"
+	if V, ok := V.(*Pointer); ok {
+		if T, ok := T.(*Pointer); ok {
+			if check.identicalIgnoreTags(under(V.base), under(T.base)) {
+				return true
+			}
+		}
+	}
+
+	// "x's type and T are both integer or floating point types"
+	if isIntegerOrFloat(V) && isIntegerOrFloat(T) {
+		return true
+	}
+
+	// "x's type and T are both complex types"
+	if isComplex(V) && isComplex(T) {
+		return true
+	}
+
+	// "x is an integer or a slice of bytes or runes and T is a string type"
+	if (isInteger(V) || isBytesOrRunes(Vu)) && isString(T) {
+		return true
+	}
+
+	// "x is a string and T is a slice of bytes or runes"
+	if isString(V) && isBytesOrRunes(Tu) {
+		return true
+	}
+
+	// package unsafe:
+	// "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
+	if (isPointer(Vu) || isUintptr(Vu)) && isUnsafePointer(T) {
+		return true
+	}
+	// "and vice versa"
+	if isUnsafePointer(V) && (isPointer(Tu) || isUintptr(Tu)) {
+		return true
+	}
+
+	// "x is a slice, T is a pointer-to-array type,
+	// and the slice and array types have identical element types."
+	if s := asSlice(V); s != nil {
+		if p := asPointer(T); p != nil {
+			if a := asArray(p.Elem()); a != nil {
+				if check.identical(s.Elem(), a.Elem()) {
+					if check == nil || check.allowVersion(check.pkg, 1, 17) {
+						return true
+					}
+					// check != nil
+					if check.conf.CompilerErrorMessages {
+						check.error(x, "conversion of slices to array pointers only supported as of -lang=go1.17")
+					} else {
+						check.error(x, "conversion of slices to array pointers requires go1.17 or later")
+					}
+					x.mode = invalid // avoid follow-up error
+				}
+			}
+		}
+	}
+
+	return false
+}
+
+func isUintptr(typ Type) bool {
+	t := asBasic(typ)
+	return t != nil && t.kind == Uintptr
+}
+
+func isUnsafePointer(typ Type) bool {
+	// TODO(gri): Is this asBasic(typ) instead of typ.(*Basic) correct?
+	//            (The former calls under(), while the latter doesn't.)
+	//            The spec does not say so, but gc claims it is. See also
+	//            issue 6326.
+	t := asBasic(typ)
+	return t != nil && t.kind == UnsafePointer
+}
+
+func isPointer(typ Type) bool {
+	return asPointer(typ) != nil
+}
+
+func isBytesOrRunes(typ Type) bool {
+	if s := asSlice(typ); s != nil {
+		t := asBasic(s.elem)
+		return t != nil && (t.kind == Byte || t.kind == Rune)
+	}
+	return false
+}
diff --git a/src/cmd/compile/internal/types2/decl.go b/src/cmd/compile/internal/types2/decl.go
new file mode 100644
index 0000000..1333e4c
--- /dev/null
+++ b/src/cmd/compile/internal/types2/decl.go
@@ -0,0 +1,953 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"go/constant"
+)
+
+func (err *error_) recordAltDecl(obj Object) {
+	if pos := obj.Pos(); pos.IsKnown() {
+		// We use "other" rather than "previous" here because
+		// the first declaration seen may not be textually
+		// earlier in the source.
+		err.errorf(pos, "other declaration of %s", obj.Name())
+	}
+}
+
+func (check *Checker) declare(scope *Scope, id *syntax.Name, obj Object, pos syntax.Pos) {
+	// spec: "The blank identifier, represented by the underscore
+	// character _, may be used in a declaration like any other
+	// identifier but the declaration does not introduce a new
+	// binding."
+	if obj.Name() != "_" {
+		if alt := scope.Insert(obj); alt != nil {
+			var err error_
+			err.errorf(obj, "%s redeclared in this block", obj.Name())
+			err.recordAltDecl(alt)
+			check.report(&err)
+			return
+		}
+		obj.setScopePos(pos)
+	}
+	if id != nil {
+		check.recordDef(id, obj)
+	}
+}
+
+// pathString returns a string of the form a->b-> ... ->g for a path [a, b, ... g].
+func pathString(path []Object) string {
+	var s string
+	for i, p := range path {
+		if i > 0 {
+			s += "->"
+		}
+		s += p.Name()
+	}
+	return s
+}
+
+// objDecl type-checks the declaration of obj in its respective (file) context.
+// For the meaning of def, see Checker.definedType, in typexpr.go.
+func (check *Checker) objDecl(obj Object, def *Named) {
+	if check.conf.Trace && obj.Type() == nil {
+		if check.indent == 0 {
+			fmt.Println() // empty line between top-level objects for readability
+		}
+		check.trace(obj.Pos(), "-- checking %s (%s, objPath = %s)", obj, obj.color(), pathString(check.objPath))
+		check.indent++
+		defer func() {
+			check.indent--
+			check.trace(obj.Pos(), "=> %s (%s)", obj, obj.color())
+		}()
+	}
+
+	// Checking the declaration of obj means inferring its type
+	// (and possibly its value, for constants).
+	// An object's type (and thus the object) may be in one of
+	// three states which are expressed by colors:
+	//
+	// - an object whose type is not yet known is painted white (initial color)
+	// - an object whose type is in the process of being inferred is painted grey
+	// - an object whose type is fully inferred is painted black
+	//
+	// During type inference, an object's color changes from white to grey
+	// to black (pre-declared objects are painted black from the start).
+	// A black object (i.e., its type) can only depend on (refer to) other black
+	// ones. White and grey objects may depend on white and black objects.
+	// A dependency on a grey object indicates a cycle which may or may not be
+	// valid.
+	//
+	// When objects turn grey, they are pushed on the object path (a stack);
+	// they are popped again when they turn black. Thus, if a grey object (a
+	// cycle) is encountered, it is on the object path, and all the objects
+	// it depends on are the remaining objects on that path. Color encoding
+	// is such that the color value of a grey object indicates the index of
+	// that object in the object path.
+
+	// During type-checking, white objects may be assigned a type without
+	// traversing through objDecl; e.g., when initializing constants and
+	// variables. Update the colors of those objects here (rather than
+	// everywhere where we set the type) to satisfy the color invariants.
+	if obj.color() == white && obj.Type() != nil {
+		obj.setColor(black)
+		return
+	}
+
+	switch obj.color() {
+	case white:
+		assert(obj.Type() == nil)
+		// All color values other than white and black are considered grey.
+		// Because black and white are < grey, all values >= grey are grey.
+		// Use those values to encode the object's index into the object path.
+		obj.setColor(grey + color(check.push(obj)))
+		defer func() {
+			check.pop().setColor(black)
+		}()
+
+	case black:
+		assert(obj.Type() != nil)
+		return
+
+	default:
+		// Color values other than white or black are considered grey.
+		fallthrough
+
+	case grey:
+		// We have a cycle.
+		// In the existing code, this is marked by a non-nil type
+		// for the object except for constants and variables whose
+		// type may be non-nil (known), or nil if it depends on the
+		// not-yet known initialization value.
+		// In the former case, set the type to Typ[Invalid] because
+		// we have an initialization cycle. The cycle error will be
+		// reported later, when determining initialization order.
+		// TODO(gri) Report cycle here and simplify initialization
+		// order code.
+		switch obj := obj.(type) {
+		case *Const:
+			if check.cycle(obj) || obj.typ == nil {
+				obj.typ = Typ[Invalid]
+			}
+
+		case *Var:
+			if check.cycle(obj) || obj.typ == nil {
+				obj.typ = Typ[Invalid]
+			}
+
+		case *TypeName:
+			if check.cycle(obj) {
+				// break cycle
+				// (without this, calling underlying()
+				// below may lead to an endless loop
+				// if we have a cycle for a defined
+				// (*Named) type)
+				obj.typ = Typ[Invalid]
+			}
+
+		case *Func:
+			if check.cycle(obj) {
+				// Don't set obj.typ to Typ[Invalid] here
+				// because plenty of code type-asserts that
+				// functions have a *Signature type. Grey
+				// functions have their type set to an empty
+				// signature which makes it impossible to
+				// initialize a variable with the function.
+			}
+
+		default:
+			unreachable()
+		}
+		assert(obj.Type() != nil)
+		return
+	}
+
+	d := check.objMap[obj]
+	if d == nil {
+		check.dump("%v: %s should have been declared", obj.Pos(), obj)
+		unreachable()
+	}
+
+	// save/restore current context and setup object context
+	defer func(ctxt context) {
+		check.context = ctxt
+	}(check.context)
+	check.context = context{
+		scope: d.file,
+	}
+
+	// Const and var declarations must not have initialization
+	// cycles. We track them by remembering the current declaration
+	// in check.decl. Initialization expressions depending on other
+	// consts, vars, or functions, add dependencies to the current
+	// check.decl.
+	switch obj := obj.(type) {
+	case *Const:
+		check.decl = d // new package-level const decl
+		check.constDecl(obj, d.vtyp, d.init, d.inherited)
+	case *Var:
+		check.decl = d // new package-level var decl
+		check.varDecl(obj, d.lhs, d.vtyp, d.init)
+	case *TypeName:
+		// invalid recursive types are detected via path
+		check.typeDecl(obj, d.tdecl, def)
+		check.collectMethods(obj) // methods can only be added to top-level types
+	case *Func:
+		// functions may be recursive - no need to track dependencies
+		check.funcDecl(obj, d)
+	default:
+		unreachable()
+	}
+}
+
+// cycle checks if the cycle starting with obj is valid and
+// reports an error if it is not.
+func (check *Checker) cycle(obj Object) (isCycle bool) {
+	// The object map contains the package scope objects and the non-interface methods.
+	if debug {
+		info := check.objMap[obj]
+		inObjMap := info != nil && (info.fdecl == nil || info.fdecl.Recv == nil) // exclude methods
+		isPkgObj := obj.Parent() == check.pkg.scope
+		if isPkgObj != inObjMap {
+			check.dump("%v: inconsistent object map for %s (isPkgObj = %v, inObjMap = %v)", obj.Pos(), obj, isPkgObj, inObjMap)
+			unreachable()
+		}
+	}
+
+	// Count cycle objects.
+	assert(obj.color() >= grey)
+	start := obj.color() - grey // index of obj in objPath
+	cycle := check.objPath[start:]
+	nval := 0 // number of (constant or variable) values in the cycle
+	ndef := 0 // number of type definitions in the cycle
+	for _, obj := range cycle {
+		switch obj := obj.(type) {
+		case *Const, *Var:
+			nval++
+		case *TypeName:
+			// Determine if the type name is an alias or not. For
+			// package-level objects, use the object map which
+			// provides syntactic information (which doesn't rely
+			// on the order in which the objects are set up). For
+			// local objects, we can rely on the order, so use
+			// the object's predicate.
+			// TODO(gri) It would be less fragile to always access
+			// the syntactic information. We should consider storing
+			// this information explicitly in the object.
+			var alias bool
+			if d := check.objMap[obj]; d != nil {
+				alias = d.tdecl.Alias // package-level object
+			} else {
+				alias = obj.IsAlias() // function local object
+			}
+			if !alias {
+				ndef++
+			}
+		case *Func:
+			// ignored for now
+		default:
+			unreachable()
+		}
+	}
+
+	if check.conf.Trace {
+		check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", pathString(cycle), obj.Name(), len(cycle))
+		check.trace(obj.Pos(), "## cycle contains: %d values, %d type definitions", nval, ndef)
+		defer func() {
+			if isCycle {
+				check.trace(obj.Pos(), "=> error: cycle is invalid")
+			}
+		}()
+	}
+
+	// A cycle involving only constants and variables is invalid but we
+	// ignore them here because they are reported via the initialization
+	// cycle check.
+	if nval == len(cycle) {
+		return false
+	}
+
+	// A cycle involving only types (and possibly functions) must have at least
+	// one type definition to be permitted: If there is no type definition, we
+	// have a sequence of alias type names which will expand ad infinitum.
+	if nval == 0 && ndef > 0 {
+		return false // cycle is permitted
+	}
+
+	check.cycleError(cycle)
+
+	return true
+}
+
+type typeInfo uint
+
+// validType verifies that the given type does not "expand" infinitely
+// producing a cycle in the type graph. Cycles are detected by marking
+// defined types.
+// (Cycles involving alias types, as in "type A = [10]A" are detected
+// earlier, via the objDecl cycle detection mechanism.)
+func (check *Checker) validType(typ Type, path []Object) typeInfo {
+	const (
+		unknown typeInfo = iota
+		marked
+		valid
+		invalid
+	)
+
+	switch t := typ.(type) {
+	case *Array:
+		return check.validType(t.elem, path)
+
+	case *Struct:
+		for _, f := range t.fields {
+			if check.validType(f.typ, path) == invalid {
+				return invalid
+			}
+		}
+
+	case *Interface:
+		for _, etyp := range t.embeddeds {
+			if check.validType(etyp, path) == invalid {
+				return invalid
+			}
+		}
+
+	case *Named:
+		// don't touch the type if it is from a different package or the Universe scope
+		// (doing so would lead to a race condition - was issue #35049)
+		if t.obj.pkg != check.pkg {
+			return valid
+		}
+
+		// don't report a 2nd error if we already know the type is invalid
+		// (e.g., if a cycle was detected earlier, via under).
+		if t.underlying == Typ[Invalid] {
+			t.info = invalid
+			return invalid
+		}
+
+		switch t.info {
+		case unknown:
+			t.info = marked
+			t.info = check.validType(t.fromRHS, append(path, t.obj)) // only types of current package added to path
+		case marked:
+			// cycle detected
+			for i, tn := range path {
+				if t.obj.pkg != check.pkg {
+					panic("internal error: type cycle via package-external type")
+				}
+				if tn == t.obj {
+					check.cycleError(path[i:])
+					t.info = invalid
+					return t.info
+				}
+			}
+			panic("internal error: cycle start not found")
+		}
+		return t.info
+
+	case *instance:
+		return check.validType(t.expand(), path)
+	}
+
+	return valid
+}
+
+// cycleError reports a declaration cycle starting with
+// the object in cycle that is "first" in the source.
+func (check *Checker) cycleError(cycle []Object) {
+	// TODO(gri) Should we start with the last (rather than the first) object in the cycle
+	//           since that is the earliest point in the source where we start seeing the
+	//           cycle? That would be more consistent with other error messages.
+	i := firstInSrc(cycle)
+	obj := cycle[i]
+	var err error_
+	if check.conf.CompilerErrorMessages {
+		err.errorf(obj, "invalid recursive type %s", obj.Name())
+	} else {
+		err.errorf(obj, "illegal cycle in declaration of %s", obj.Name())
+	}
+	for range cycle {
+		err.errorf(obj, "%s refers to", obj.Name())
+		i++
+		if i >= len(cycle) {
+			i = 0
+		}
+		obj = cycle[i]
+	}
+	err.errorf(obj, "%s", obj.Name())
+	check.report(&err)
+}
+
+// firstInSrc reports the index of the object with the "smallest"
+// source position in path. path must not be empty.
+func firstInSrc(path []Object) int {
+	fst, pos := 0, path[0].Pos()
+	for i, t := range path[1:] {
+		if t.Pos().Cmp(pos) < 0 {
+			fst, pos = i+1, t.Pos()
+		}
+	}
+	return fst
+}
+
+func (check *Checker) constDecl(obj *Const, typ, init syntax.Expr, inherited bool) {
+	assert(obj.typ == nil)
+
+	// use the correct value of iota and errpos
+	defer func(iota constant.Value, errpos syntax.Pos) {
+		check.iota = iota
+		check.errpos = errpos
+	}(check.iota, check.errpos)
+	check.iota = obj.val
+	check.errpos = nopos
+
+	// provide valid constant value under all circumstances
+	obj.val = constant.MakeUnknown()
+
+	// determine type, if any
+	if typ != nil {
+		t := check.typ(typ)
+		if !isConstType(t) {
+			// don't report an error if the type is an invalid C (defined) type
+			// (issue #22090)
+			if under(t) != Typ[Invalid] {
+				check.errorf(typ, "invalid constant type %s", t)
+			}
+			obj.typ = Typ[Invalid]
+			return
+		}
+		obj.typ = t
+	}
+
+	// check initialization
+	var x operand
+	if init != nil {
+		if inherited {
+			// The initialization expression is inherited from a previous
+			// constant declaration, and (error) positions refer to that
+			// expression and not the current constant declaration. Use
+			// the constant identifier position for any errors during
+			// init expression evaluation since that is all we have
+			// (see issues #42991, #42992).
+			check.errpos = obj.pos
+		}
+		check.expr(&x, init)
+	}
+	check.initConst(obj, &x)
+}
+
+func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init syntax.Expr) {
+	assert(obj.typ == nil)
+
+	// If we have undefined variable types due to errors,
+	// mark variables as used to avoid follow-on errors.
+	// Matches compiler behavior.
+	defer func() {
+		if obj.typ == Typ[Invalid] {
+			obj.used = true
+		}
+		for _, lhs := range lhs {
+			if lhs.typ == Typ[Invalid] {
+				lhs.used = true
+			}
+		}
+	}()
+
+	// determine type, if any
+	if typ != nil {
+		obj.typ = check.varType(typ)
+		// We cannot spread the type to all lhs variables if there
+		// are more than one since that would mark them as checked
+		// (see Checker.objDecl) and the assignment of init exprs,
+		// if any, would not be checked.
+		//
+		// TODO(gri) If we have no init expr, we should distribute
+		// a given type otherwise we need to re-evalate the type
+		// expr for each lhs variable, leading to duplicate work.
+	}
+
+	// check initialization
+	if init == nil {
+		if typ == nil {
+			// error reported before by arityMatch
+			obj.typ = Typ[Invalid]
+		}
+		return
+	}
+
+	if lhs == nil || len(lhs) == 1 {
+		assert(lhs == nil || lhs[0] == obj)
+		var x operand
+		check.expr(&x, init)
+		check.initVar(obj, &x, "variable declaration")
+		return
+	}
+
+	if debug {
+		// obj must be one of lhs
+		found := false
+		for _, lhs := range lhs {
+			if obj == lhs {
+				found = true
+				break
+			}
+		}
+		if !found {
+			panic("inconsistent lhs")
+		}
+	}
+
+	// We have multiple variables on the lhs and one init expr.
+	// Make sure all variables have been given the same type if
+	// one was specified, otherwise they assume the type of the
+	// init expression values (was issue #15755).
+	if typ != nil {
+		for _, lhs := range lhs {
+			lhs.typ = obj.typ
+		}
+	}
+
+	check.initVars(lhs, []syntax.Expr{init}, nopos)
+}
+
+// under returns the expanded underlying type of n0; possibly by following
+// forward chains of named types. If an underlying type is found, resolve
+// the chain by setting the underlying type for each defined type in the
+// chain before returning it. If no underlying type is found or a cycle
+// is detected, the result is Typ[Invalid]. If a cycle is detected and
+// n0.check != nil, the cycle is reported.
+func (n0 *Named) under() Type {
+	u := n0.underlying
+	if u == nil {
+		return Typ[Invalid]
+	}
+
+	// If the underlying type of a defined type is not a defined
+	// type, then that is the desired underlying type.
+	n := asNamed(u)
+	if n == nil {
+		return u // common case
+	}
+
+	// Otherwise, follow the forward chain.
+	seen := map[*Named]int{n0: 0}
+	path := []Object{n0.obj}
+	for {
+		u = n.underlying
+		if u == nil {
+			u = Typ[Invalid]
+			break
+		}
+		n1 := asNamed(u)
+		if n1 == nil {
+			break // end of chain
+		}
+
+		seen[n] = len(seen)
+		path = append(path, n.obj)
+		n = n1
+
+		if i, ok := seen[n]; ok {
+			// cycle
+			// TODO(gri) revert this to a method on Checker. Having a possibly
+			// nil Checker on Named and TypeParam is too subtle.
+			if n0.check != nil {
+				n0.check.cycleError(path[i:])
+			}
+			u = Typ[Invalid]
+			break
+		}
+	}
+
+	for n := range seen {
+		// We should never have to update the underlying type of an imported type;
+		// those underlying types should have been resolved during the import.
+		// Also, doing so would lead to a race condition (was issue #31749).
+		// Do this check always, not just in debug more (it's cheap).
+		if n0.check != nil && n.obj.pkg != n0.check.pkg {
+			panic("internal error: imported type with unresolved underlying type")
+		}
+		n.underlying = u
+	}
+
+	return u
+}
+
+func (n *Named) setUnderlying(typ Type) {
+	if n != nil {
+		n.underlying = typ
+	}
+}
+
+func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named) {
+	assert(obj.typ == nil)
+
+	check.later(func() {
+		check.validType(obj.typ, nil)
+	})
+
+	alias := tdecl.Alias
+	if alias && tdecl.TParamList != nil {
+		// The parser will ensure this but we may still get an invalid AST.
+		// Complain and continue as regular type definition.
+		check.error(tdecl, "generic type cannot be alias")
+		alias = false
+	}
+
+	if alias {
+		// type alias declaration
+		if !check.allowVersion(check.pkg, 1, 9) {
+			if check.conf.CompilerErrorMessages {
+				check.error(tdecl, "type aliases only supported as of -lang=go1.9")
+			} else {
+				check.error(tdecl, "type aliases requires go1.9 or later")
+			}
+		}
+
+		obj.typ = Typ[Invalid]
+		obj.typ = check.anyType(tdecl.Type)
+
+	} else {
+		// defined type declaration
+
+		named := check.newNamed(obj, nil, nil, nil, nil)
+		def.setUnderlying(named)
+
+		if tdecl.TParamList != nil {
+			check.openScope(tdecl, "type parameters")
+			defer check.closeScope()
+			named.tparams = check.collectTypeParams(tdecl.TParamList)
+		}
+
+		// determine underlying type of named
+		named.fromRHS = check.definedType(tdecl.Type, named)
+
+		// The underlying type of named may be itself a named type that is
+		// incomplete:
+		//
+		//	type (
+		//		A B
+		//		B *C
+		//		C A
+		//	)
+		//
+		// The type of C is the (named) type of A which is incomplete,
+		// and which has as its underlying type the named type B.
+		// Determine the (final, unnamed) underlying type by resolving
+		// any forward chain.
+		// TODO(gri) Investigate if we can just use named.fromRHS here
+		//           and rely on lazy computation of the underlying type.
+		named.underlying = under(named)
+	}
+
+}
+
+func (check *Checker) collectTypeParams(list []*syntax.Field) (tparams []*TypeName) {
+	// Type parameter lists should not be empty. The parser will
+	// complain but we still may get an incorrect AST: ignore it.
+	if len(list) == 0 {
+		return
+	}
+
+	// Declare type parameters up-front, with empty interface as type bound.
+	// The scope of type parameters starts at the beginning of the type parameter
+	// list (so we can have mutually recursive parameterized interfaces).
+	for _, f := range list {
+		tparams = check.declareTypeParam(tparams, f.Name)
+	}
+
+	var bound Type
+	for i, j := 0, 0; i < len(list); i = j {
+		f := list[i]
+
+		// determine the range of type parameters list[i:j] with identical type bound
+		// (declared as in (type a, b, c B))
+		j = i + 1
+		for j < len(list) && list[j].Type == f.Type {
+			j++
+		}
+
+		// this should never be the case, but be careful
+		if f.Type == nil {
+			continue
+		}
+
+		// The predeclared identifier "any" is visible only as a constraint
+		// in a type parameter list. Look for it before general constraint
+		// resolution.
+		if tident, _ := unparen(f.Type).(*syntax.Name); tident != nil && tident.Value == "any" && check.lookup("any") == nil {
+			bound = universeAny
+		} else {
+			bound = check.typ(f.Type)
+		}
+
+		// type bound must be an interface
+		// TODO(gri) We should delay the interface check because
+		//           we may not have a complete interface yet:
+		//           type C(type T C) interface {}
+		//           (issue #39724).
+		if _, ok := under(bound).(*Interface); ok {
+			// set the type bounds
+			for i < j {
+				tparams[i].typ.(*TypeParam).bound = bound
+				i++
+			}
+		} else if bound != Typ[Invalid] {
+			check.errorf(f.Type, "%s is not an interface", bound)
+		}
+	}
+
+	return
+}
+
+func (check *Checker) declareTypeParam(tparams []*TypeName, name *syntax.Name) []*TypeName {
+	tpar := NewTypeName(name.Pos(), check.pkg, name.Value, nil)
+	check.NewTypeParam(tpar, len(tparams), &emptyInterface) // assigns type to tpar as a side-effect
+	check.declare(check.scope, name, tpar, check.scope.pos) // TODO(gri) check scope position
+	tparams = append(tparams, tpar)
+
+	if check.conf.Trace {
+		check.trace(name.Pos(), "type param = %v", tparams[len(tparams)-1])
+	}
+
+	return tparams
+}
+
+func (check *Checker) collectMethods(obj *TypeName) {
+	// get associated methods
+	// (Checker.collectObjects only collects methods with non-blank names;
+	// Checker.resolveBaseTypeName ensures that obj is not an alias name
+	// if it has attached methods.)
+	methods := check.methods[obj]
+	if methods == nil {
+		return
+	}
+	delete(check.methods, obj)
+	assert(!check.objMap[obj].tdecl.Alias) // don't use TypeName.IsAlias (requires fully set up object)
+
+	// use an objset to check for name conflicts
+	var mset objset
+
+	// spec: "If the base type is a struct type, the non-blank method
+	// and field names must be distinct."
+	base := asNamed(obj.typ) // shouldn't fail but be conservative
+	if base != nil {
+		if t, _ := base.underlying.(*Struct); t != nil {
+			for _, fld := range t.fields {
+				if fld.name != "_" {
+					assert(mset.insert(fld) == nil)
+				}
+			}
+		}
+
+		// Checker.Files may be called multiple times; additional package files
+		// may add methods to already type-checked types. Add pre-existing methods
+		// so that we can detect redeclarations.
+		for _, m := range base.methods {
+			assert(m.name != "_")
+			assert(mset.insert(m) == nil)
+		}
+	}
+
+	// add valid methods
+	for _, m := range methods {
+		// spec: "For a base type, the non-blank names of methods bound
+		// to it must be unique."
+		assert(m.name != "_")
+		if alt := mset.insert(m); alt != nil {
+			var err error_
+			switch alt.(type) {
+			case *Var:
+				err.errorf(m.pos, "field and method with the same name %s", m.name)
+			case *Func:
+				if check.conf.CompilerErrorMessages {
+					err.errorf(m.pos, "%s.%s redeclared in this block", obj.Name(), m.name)
+				} else {
+					err.errorf(m.pos, "method %s already declared for %s", m.name, obj)
+				}
+			default:
+				unreachable()
+			}
+			err.recordAltDecl(alt)
+			check.report(&err)
+			continue
+		}
+
+		if base != nil {
+			base.methods = append(base.methods, m)
+		}
+	}
+}
+
+func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
+	assert(obj.typ == nil)
+
+	// func declarations cannot use iota
+	assert(check.iota == nil)
+
+	sig := new(Signature)
+	obj.typ = sig // guard against cycles
+
+	// Avoid cycle error when referring to method while type-checking the signature.
+	// This avoids a nuisance in the best case (non-parameterized receiver type) and
+	// since the method is not a type, we get an error. If we have a parameterized
+	// receiver type, instantiating the receiver type leads to the instantiation of
+	// its methods, and we don't want a cycle error in that case.
+	// TODO(gri) review if this is correct and/or whether we still need this?
+	saved := obj.color_
+	obj.color_ = black
+	fdecl := decl.fdecl
+	check.funcType(sig, fdecl.Recv, fdecl.TParamList, fdecl.Type)
+	obj.color_ = saved
+
+	// function body must be type-checked after global declarations
+	// (functions implemented elsewhere have no body)
+	if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
+		check.later(func() {
+			check.funcBody(decl, obj.name, sig, fdecl.Body, nil)
+		})
+	}
+}
+
+func (check *Checker) declStmt(list []syntax.Decl) {
+	pkg := check.pkg
+
+	first := -1                // index of first ConstDecl in the current group, or -1
+	var last *syntax.ConstDecl // last ConstDecl with init expressions, or nil
+	for index, decl := range list {
+		if _, ok := decl.(*syntax.ConstDecl); !ok {
+			first = -1 // we're not in a constant declaration
+		}
+
+		switch s := decl.(type) {
+		case *syntax.ConstDecl:
+			top := len(check.delayed)
+
+			// iota is the index of the current constDecl within the group
+			if first < 0 || list[index-1].(*syntax.ConstDecl).Group != s.Group {
+				first = index
+				last = nil
+			}
+			iota := constant.MakeInt64(int64(index - first))
+
+			// determine which initialization expressions to use
+			inherited := true
+			switch {
+			case s.Type != nil || s.Values != nil:
+				last = s
+				inherited = false
+			case last == nil:
+				last = new(syntax.ConstDecl) // make sure last exists
+				inherited = false
+			}
+
+			// declare all constants
+			lhs := make([]*Const, len(s.NameList))
+			values := unpackExpr(last.Values)
+			for i, name := range s.NameList {
+				obj := NewConst(name.Pos(), pkg, name.Value, nil, iota)
+				lhs[i] = obj
+
+				var init syntax.Expr
+				if i < len(values) {
+					init = values[i]
+				}
+
+				check.constDecl(obj, last.Type, init, inherited)
+			}
+
+			// Constants must always have init values.
+			check.arity(s.Pos(), s.NameList, values, true, inherited)
+
+			// process function literals in init expressions before scope changes
+			check.processDelayed(top)
+
+			// spec: "The scope of a constant or variable identifier declared
+			// inside a function begins at the end of the ConstSpec or VarSpec
+			// (ShortVarDecl for short variable declarations) and ends at the
+			// end of the innermost containing block."
+			scopePos := syntax.EndPos(s)
+			for i, name := range s.NameList {
+				check.declare(check.scope, name, lhs[i], scopePos)
+			}
+
+		case *syntax.VarDecl:
+			top := len(check.delayed)
+
+			lhs0 := make([]*Var, len(s.NameList))
+			for i, name := range s.NameList {
+				lhs0[i] = NewVar(name.Pos(), pkg, name.Value, nil)
+			}
+
+			// initialize all variables
+			values := unpackExpr(s.Values)
+			for i, obj := range lhs0 {
+				var lhs []*Var
+				var init syntax.Expr
+				switch len(values) {
+				case len(s.NameList):
+					// lhs and rhs match
+					init = values[i]
+				case 1:
+					// rhs is expected to be a multi-valued expression
+					lhs = lhs0
+					init = values[0]
+				default:
+					if i < len(values) {
+						init = values[i]
+					}
+				}
+				check.varDecl(obj, lhs, s.Type, init)
+				if len(values) == 1 {
+					// If we have a single lhs variable we are done either way.
+					// If we have a single rhs expression, it must be a multi-
+					// valued expression, in which case handling the first lhs
+					// variable will cause all lhs variables to have a type
+					// assigned, and we are done as well.
+					if debug {
+						for _, obj := range lhs0 {
+							assert(obj.typ != nil)
+						}
+					}
+					break
+				}
+			}
+
+			// If we have no type, we must have values.
+			if s.Type == nil || values != nil {
+				check.arity(s.Pos(), s.NameList, values, false, false)
+			}
+
+			// process function literals in init expressions before scope changes
+			check.processDelayed(top)
+
+			// declare all variables
+			// (only at this point are the variable scopes (parents) set)
+			scopePos := syntax.EndPos(s) // see constant declarations
+			for i, name := range s.NameList {
+				// see constant declarations
+				check.declare(check.scope, name, lhs0[i], scopePos)
+			}
+
+		case *syntax.TypeDecl:
+			obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Value, nil)
+			// spec: "The scope of a type identifier declared inside a function
+			// begins at the identifier in the TypeSpec and ends at the end of
+			// the innermost containing block."
+			scopePos := s.Name.Pos()
+			check.declare(check.scope, s.Name, obj, scopePos)
+			// mark and unmark type before calling typeDecl; its type is still nil (see Checker.objDecl)
+			obj.setColor(grey + color(check.push(obj)))
+			check.typeDecl(obj, s, nil)
+			check.pop().setColor(black)
+
+		default:
+			check.errorf(s, invalidAST+"unknown syntax.Decl node %T", s)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/types2/errorcalls_test.go b/src/cmd/compile/internal/types2/errorcalls_test.go
new file mode 100644
index 0000000..28bb33a
--- /dev/null
+++ b/src/cmd/compile/internal/types2/errorcalls_test.go
@@ -0,0 +1,49 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE ast.
+
+package types2_test
+
+import (
+	"cmd/compile/internal/syntax"
+	"testing"
+)
+
+// TestErrorCalls makes sure that check.errorf calls have at
+// least 3 arguments (otherwise we should be using check.error).
+func TestErrorCalls(t *testing.T) {
+	files, err := pkgFiles(".")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	for _, file := range files {
+		syntax.Walk(file, func(n syntax.Node) bool {
+			call, _ := n.(*syntax.CallExpr)
+			if call == nil {
+				return false
+			}
+			selx, _ := call.Fun.(*syntax.SelectorExpr)
+			if selx == nil {
+				return false
+			}
+			if !(isName(selx.X, "check") && isName(selx.Sel, "errorf")) {
+				return false
+			}
+			// check.errorf calls should have more than 2 arguments:
+			// position, format string, and arguments to format
+			if n := len(call.ArgList); n <= 2 {
+				t.Errorf("%s: got %d arguments, want > 2", call.Pos(), n)
+				return true
+			}
+			return false
+		})
+	}
+}
+
+func isName(n syntax.Node, name string) bool {
+	if n, ok := n.(*syntax.Name); ok {
+		return n.Value == name
+	}
+	return false
+}
diff --git a/src/cmd/compile/internal/types2/errors.go b/src/cmd/compile/internal/types2/errors.go
new file mode 100644
index 0000000..af4ecb2
--- /dev/null
+++ b/src/cmd/compile/internal/types2/errors.go
@@ -0,0 +1,257 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements various error reporters.
+
+package types2
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+func unimplemented() {
+	panic("unimplemented")
+}
+
+func assert(p bool) {
+	if !p {
+		panic("assertion failed")
+	}
+}
+
+func unreachable() {
+	panic("unreachable")
+}
+
+// An error_ represents a type-checking error.
+// To report an error_, call Checker.report.
+type error_ struct {
+	desc []errorDesc
+	soft bool // TODO(gri) eventually determine this from an error code
+}
+
+// An errorDesc describes part of a type-checking error.
+type errorDesc struct {
+	pos    syntax.Pos
+	format string
+	args   []interface{}
+}
+
+func (err *error_) empty() bool {
+	return err.desc == nil
+}
+
+func (err *error_) pos() syntax.Pos {
+	if err.empty() {
+		return nopos
+	}
+	return err.desc[0].pos
+}
+
+func (err *error_) msg(qf Qualifier) string {
+	if err.empty() {
+		return "no error"
+	}
+	var buf bytes.Buffer
+	for i := range err.desc {
+		p := &err.desc[i]
+		if i > 0 {
+			fmt.Fprintf(&buf, "\n\t%s: ", p.pos)
+		}
+		buf.WriteString(sprintf(qf, p.format, p.args...))
+	}
+	return buf.String()
+}
+
+// String is for testing.
+func (err *error_) String() string {
+	if err.empty() {
+		return "no error"
+	}
+	return fmt.Sprintf("%s: %s", err.pos(), err.msg(nil))
+}
+
+// errorf adds formatted error information to err.
+// It may be called multiple times to provide additional information.
+func (err *error_) errorf(at poser, format string, args ...interface{}) {
+	err.desc = append(err.desc, errorDesc{posFor(at), format, args})
+}
+
+func sprintf(qf Qualifier, format string, args ...interface{}) string {
+	for i, arg := range args {
+		switch a := arg.(type) {
+		case nil:
+			arg = "<nil>"
+		case operand:
+			panic("internal error: should always pass *operand")
+		case *operand:
+			arg = operandString(a, qf)
+		case syntax.Pos:
+			arg = a.String()
+		case syntax.Expr:
+			arg = syntax.String(a)
+		case Object:
+			arg = ObjectString(a, qf)
+		case Type:
+			arg = TypeString(a, qf)
+		}
+		args[i] = arg
+	}
+	return fmt.Sprintf(format, args...)
+}
+
+func (check *Checker) qualifier(pkg *Package) string {
+	// Qualify the package unless it's the package being type-checked.
+	if pkg != check.pkg {
+		if check.pkgPathMap == nil {
+			check.pkgPathMap = make(map[string]map[string]bool)
+			check.seenPkgMap = make(map[*Package]bool)
+			check.markImports(pkg)
+		}
+		// If the same package name was used by multiple packages, display the full path.
+		if len(check.pkgPathMap[pkg.name]) > 1 {
+			return strconv.Quote(pkg.path)
+		}
+		return pkg.name
+	}
+	return ""
+}
+
+// markImports recursively walks pkg and its imports, to record unique import
+// paths in pkgPathMap.
+func (check *Checker) markImports(pkg *Package) {
+	if check.seenPkgMap[pkg] {
+		return
+	}
+	check.seenPkgMap[pkg] = true
+
+	forName, ok := check.pkgPathMap[pkg.name]
+	if !ok {
+		forName = make(map[string]bool)
+		check.pkgPathMap[pkg.name] = forName
+	}
+	forName[pkg.path] = true
+
+	for _, imp := range pkg.imports {
+		check.markImports(imp)
+	}
+}
+
+func (check *Checker) sprintf(format string, args ...interface{}) string {
+	return sprintf(check.qualifier, format, args...)
+}
+
+func (check *Checker) report(err *error_) {
+	if err.empty() {
+		panic("internal error: reporting no error")
+	}
+	check.err(err.pos(), err.msg(check.qualifier), err.soft)
+}
+
+func (check *Checker) trace(pos syntax.Pos, format string, args ...interface{}) {
+	fmt.Printf("%s:\t%s%s\n",
+		pos,
+		strings.Repeat(".  ", check.indent),
+		check.sprintf(format, args...),
+	)
+}
+
+// dump is only needed for debugging
+func (check *Checker) dump(format string, args ...interface{}) {
+	fmt.Println(check.sprintf(format, args...))
+}
+
+func (check *Checker) err(at poser, msg string, soft bool) {
+	// Cheap trick: Don't report errors with messages containing
+	// "invalid operand" or "invalid type" as those tend to be
+	// follow-on errors which don't add useful information. Only
+	// exclude them if these strings are not at the beginning,
+	// and only if we have at least one error already reported.
+	if check.firstErr != nil && (strings.Index(msg, "invalid operand") > 0 || strings.Index(msg, "invalid type") > 0) {
+		return
+	}
+
+	pos := posFor(at)
+
+	// If we are encountering an error while evaluating an inherited
+	// constant initialization expression, pos is the position of in
+	// the original expression, and not of the currently declared
+	// constant identifier. Use the provided errpos instead.
+	// TODO(gri) We may also want to augment the error message and
+	// refer to the position (pos) in the original expression.
+	if check.errpos.IsKnown() {
+		assert(check.iota != nil)
+		pos = check.errpos
+	}
+
+	err := Error{pos, stripAnnotations(msg), msg, soft}
+	if check.firstErr == nil {
+		check.firstErr = err
+	}
+
+	if check.conf.Trace {
+		check.trace(pos, "ERROR: %s", msg)
+	}
+
+	f := check.conf.Error
+	if f == nil {
+		panic(bailout{}) // report only first error
+	}
+	f(err)
+}
+
+const (
+	invalidAST = "invalid AST: "
+	invalidArg = "invalid argument: "
+	invalidOp  = "invalid operation: "
+)
+
+type poser interface {
+	Pos() syntax.Pos
+}
+
+func (check *Checker) error(at poser, msg string) {
+	check.err(at, msg, false)
+}
+
+func (check *Checker) errorf(at poser, format string, args ...interface{}) {
+	check.err(at, check.sprintf(format, args...), false)
+}
+
+func (check *Checker) softErrorf(at poser, format string, args ...interface{}) {
+	check.err(at, check.sprintf(format, args...), true)
+}
+
+// posFor reports the left (= start) position of at.
+func posFor(at poser) syntax.Pos {
+	switch x := at.(type) {
+	case *operand:
+		if x.expr != nil {
+			return syntax.StartPos(x.expr)
+		}
+	case syntax.Node:
+		return syntax.StartPos(x)
+	}
+	return at.Pos()
+}
+
+// stripAnnotations removes internal (type) annotations from s.
+func stripAnnotations(s string) string {
+	// Would like to use strings.Builder but it's not available in Go 1.4.
+	var b bytes.Buffer
+	for _, r := range s {
+		// strip #'s and subscript digits
+		if r != instanceMarker && !('₀' <= r && r < '₀'+10) { // '₀' == U+2080
+			b.WriteRune(r)
+		}
+	}
+	if b.Len() < len(s) {
+		return b.String()
+	}
+	return s
+}
diff --git a/src/cmd/compile/internal/types2/errors_test.go b/src/cmd/compile/internal/types2/errors_test.go
new file mode 100644
index 0000000..e1f0e83
--- /dev/null
+++ b/src/cmd/compile/internal/types2/errors_test.go
@@ -0,0 +1,45 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+import "testing"
+
+func TestError(t *testing.T) {
+	var err error_
+	want := "no error"
+	if got := err.String(); got != want {
+		t.Errorf("empty error: got %q, want %q", got, want)
+	}
+
+	want = "<unknown position>: foo 42"
+	err.errorf(nopos, "foo %d", 42)
+	if got := err.String(); got != want {
+		t.Errorf("simple error: got %q, want %q", got, want)
+	}
+
+	want = "<unknown position>: foo 42\n\t<unknown position>: bar 43"
+	err.errorf(nopos, "bar %d", 43)
+	if got := err.String(); got != want {
+		t.Errorf("simple error: got %q, want %q", got, want)
+	}
+}
+
+func TestStripAnnotations(t *testing.T) {
+	for _, test := range []struct {
+		in, want string
+	}{
+		{"", ""},
+		{"   ", "   "},
+		{"foo", "foo"},
+		{"foo₀", "foo"},
+		{"foo(T₀)", "foo(T)"},
+		{"#foo(T₀)", "foo(T)"},
+	} {
+		got := stripAnnotations(test.in)
+		if got != test.want {
+			t.Errorf("%q: got %q; want %q", test.in, got, test.want)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/types2/example_test.go b/src/cmd/compile/internal/types2/example_test.go
new file mode 100644
index 0000000..714bf77
--- /dev/null
+++ b/src/cmd/compile/internal/types2/example_test.go
@@ -0,0 +1,269 @@
+// 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.
+
+// Only run where builders (build.golang.org) have
+// access to compiled packages for import.
+//
+//go:build !arm && !arm64
+// +build !arm,!arm64
+
+package types2_test
+
+// This file shows examples of basic usage of the go/types API.
+//
+// To locate a Go package, use (*go/build.Context).Import.
+// To load, parse, and type-check a complete Go program
+// from source, use golang.org/x/tools/go/loader.
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/types2"
+	"fmt"
+	"log"
+	"regexp"
+	"sort"
+	"strings"
+)
+
+// ExampleScope prints the tree of Scopes of a package created from a
+// set of parsed files.
+func ExampleScope() {
+	// Parse the source files for a package.
+	var files []*syntax.File
+	for _, file := range []struct{ name, input string }{
+		{"main.go", `
+package main
+import "fmt"
+func main() {
+	freezing := FToC(-18)
+	fmt.Println(freezing, Boiling) }
+`},
+		{"celsius.go", `
+package main
+import "fmt"
+type Celsius float64
+func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) }
+func FToC(f float64) Celsius { return Celsius(f - 32 / 9 * 5) }
+const Boiling Celsius = 100
+func Unused() { {}; {{ var x int; _ = x }} } // make sure empty block scopes get printed
+`},
+	} {
+		f, err := parseSrc(file.name, file.input)
+		if err != nil {
+			log.Fatal(err)
+		}
+		files = append(files, f)
+	}
+
+	// Type-check a package consisting of these files.
+	// Type information for the imported "fmt" package
+	// comes from $GOROOT/pkg/$GOOS_$GOOARCH/fmt.a.
+	conf := types2.Config{Importer: defaultImporter()}
+	pkg, err := conf.Check("temperature", files, nil)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Print the tree of scopes.
+	// For determinism, we redact addresses.
+	var buf bytes.Buffer
+	pkg.Scope().WriteTo(&buf, 0, true)
+	rx := regexp.MustCompile(` 0x[a-fA-F0-9]*`)
+	fmt.Println(rx.ReplaceAllString(buf.String(), ""))
+
+	// Output:
+	// package "temperature" scope {
+	// .  const temperature.Boiling temperature.Celsius
+	// .  type temperature.Celsius float64
+	// .  func temperature.FToC(f float64) temperature.Celsius
+	// .  func temperature.Unused()
+	// .  func temperature.main()
+	// .  main.go scope {
+	// .  .  package fmt
+	// .  .  function scope {
+	// .  .  .  var freezing temperature.Celsius
+	// .  .  }
+	// .  }
+	// .  celsius.go scope {
+	// .  .  package fmt
+	// .  .  function scope {
+	// .  .  .  var c temperature.Celsius
+	// .  .  }
+	// .  .  function scope {
+	// .  .  .  var f float64
+	// .  .  }
+	// .  .  function scope {
+	// .  .  .  block scope {
+	// .  .  .  }
+	// .  .  .  block scope {
+	// .  .  .  .  block scope {
+	// .  .  .  .  .  var x int
+	// .  .  .  .  }
+	// .  .  .  }
+	// .  .  }
+	// .  }
+	// }
+}
+
+// ExampleInfo prints various facts recorded by the type checker in a
+// types2.Info struct: definitions of and references to each named object,
+// and the type, value, and mode of every expression in the package.
+func ExampleInfo() {
+	// Parse a single source file.
+	const input = `
+package fib
+
+type S string
+
+var a, b, c = len(b), S(c), "hello"
+
+func fib(x int) int {
+	if x < 2 {
+		return x
+	}
+	return fib(x-1) - fib(x-2)
+}`
+	f, err := parseSrc("fib.go", input)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Type-check the package.
+	// We create an empty map for each kind of input
+	// we're interested in, and Check populates them.
+	info := types2.Info{
+		Types: make(map[syntax.Expr]types2.TypeAndValue),
+		Defs:  make(map[*syntax.Name]types2.Object),
+		Uses:  make(map[*syntax.Name]types2.Object),
+	}
+	var conf types2.Config
+	pkg, err := conf.Check("fib", []*syntax.File{f}, &info)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// Print package-level variables in initialization order.
+	fmt.Printf("InitOrder: %v\n\n", info.InitOrder)
+
+	// For each named object, print the line and
+	// column of its definition and each of its uses.
+	fmt.Println("Defs and Uses of each named object:")
+	usesByObj := make(map[types2.Object][]string)
+	for id, obj := range info.Uses {
+		posn := id.Pos()
+		lineCol := fmt.Sprintf("%d:%d", posn.Line(), posn.Col())
+		usesByObj[obj] = append(usesByObj[obj], lineCol)
+	}
+	var items []string
+	for obj, uses := range usesByObj {
+		sort.Strings(uses)
+		item := fmt.Sprintf("%s:\n  defined at %s\n  used at %s",
+			types2.ObjectString(obj, types2.RelativeTo(pkg)),
+			obj.Pos(),
+			strings.Join(uses, ", "))
+		items = append(items, item)
+	}
+	sort.Strings(items) // sort by line:col, in effect
+	fmt.Println(strings.Join(items, "\n"))
+	fmt.Println()
+
+	// TODO(gri) Enable once positions are updated/verified
+	// fmt.Println("Types and Values of each expression:")
+	// items = nil
+	// for expr, tv := range info.Types {
+	// 	var buf bytes.Buffer
+	// 	posn := expr.Pos()
+	// 	tvstr := tv.Type.String()
+	// 	if tv.Value != nil {
+	// 		tvstr += " = " + tv.Value.String()
+	// 	}
+	// 	// line:col | expr | mode : type = value
+	// 	fmt.Fprintf(&buf, "%2d:%2d | %-19s | %-7s : %s",
+	// 		posn.Line(), posn.Col(), types2.ExprString(expr),
+	// 		mode(tv), tvstr)
+	// 	items = append(items, buf.String())
+	// }
+	// sort.Strings(items)
+	// fmt.Println(strings.Join(items, "\n"))
+
+	// Output:
+	// InitOrder: [c = "hello" b = S(c) a = len(b)]
+	//
+	// Defs and Uses of each named object:
+	// builtin len:
+	//   defined at <unknown position>
+	//   used at 6:15
+	// func fib(x int) int:
+	//   defined at fib.go:8:6
+	//   used at 12:20, 12:9
+	// type S string:
+	//   defined at fib.go:4:6
+	//   used at 6:23
+	// type int:
+	//   defined at <unknown position>
+	//   used at 8:12, 8:17
+	// type string:
+	//   defined at <unknown position>
+	//   used at 4:8
+	// var b S:
+	//   defined at fib.go:6:8
+	//   used at 6:19
+	// var c string:
+	//   defined at fib.go:6:11
+	//   used at 6:25
+	// var x int:
+	//   defined at fib.go:8:10
+	//   used at 10:10, 12:13, 12:24, 9:5
+
+	// TODO(gri) Enable once positions are updated/verified
+	// Types and Values of each expression:
+	//  4: 8 | string              | type    : string
+	//  6:15 | len                 | builtin : func(string) int
+	//  6:15 | len(b)              | value   : int
+	//  6:19 | b                   | var     : fib.S
+	//  6:23 | S                   | type    : fib.S
+	//  6:23 | S(c)                | value   : fib.S
+	//  6:25 | c                   | var     : string
+	//  6:29 | "hello"             | value   : string = "hello"
+	//  8:12 | int                 | type    : int
+	//  8:17 | int                 | type    : int
+	//  9: 5 | x                   | var     : int
+	//  9: 5 | x < 2               | value   : untyped bool
+	//  9: 9 | 2                   | value   : int = 2
+	// 10:10 | x                   | var     : int
+	// 12: 9 | fib                 | value   : func(x int) int
+	// 12: 9 | fib(x - 1)          | value   : int
+	// 12: 9 | fib(x - 1) - fib(x - 2) | value   : int
+	// 12:13 | x                   | var     : int
+	// 12:13 | x - 1               | value   : int
+	// 12:15 | 1                   | value   : int = 1
+	// 12:20 | fib                 | value   : func(x int) int
+	// 12:20 | fib(x - 2)          | value   : int
+	// 12:24 | x                   | var     : int
+	// 12:24 | x - 2               | value   : int
+	// 12:26 | 2                   | value   : int = 2
+}
+
+func mode(tv types2.TypeAndValue) string {
+	switch {
+	case tv.IsVoid():
+		return "void"
+	case tv.IsType():
+		return "type"
+	case tv.IsBuiltin():
+		return "builtin"
+	case tv.IsNil():
+		return "nil"
+	case tv.Assignable():
+		if tv.Addressable() {
+			return "var"
+		}
+		return "mapindex"
+	case tv.IsValue():
+		return "value"
+	default:
+		return "unknown"
+	}
+}
diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go
new file mode 100644
index 0000000..23b7965
--- /dev/null
+++ b/src/cmd/compile/internal/types2/expr.go
@@ -0,0 +1,1655 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements typechecking of expressions.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"go/constant"
+	"go/token"
+	"math"
+)
+
+/*
+Basic algorithm:
+
+Expressions are checked recursively, top down. Expression checker functions
+are generally of the form:
+
+  func f(x *operand, e *syntax.Expr, ...)
+
+where e is the expression to be checked, and x is the result of the check.
+The check performed by f may fail in which case x.mode == invalid, and
+related error messages will have been issued by f.
+
+If a hint argument is present, it is the composite literal element type
+of an outer composite literal; it is used to type-check composite literal
+elements that have no explicit type specification in the source
+(e.g.: []T{{...}, {...}}, the hint is the type T in this case).
+
+All expressions are checked via rawExpr, which dispatches according
+to expression kind. Upon returning, rawExpr is recording the types and
+constant values for all expressions that have an untyped type (those types
+may change on the way up in the expression tree). Usually these are constants,
+but the results of comparisons or non-constant shifts of untyped constants
+may also be untyped, but not constant.
+
+Untyped expressions may eventually become fully typed (i.e., not untyped),
+typically when the value is assigned to a variable, or is used otherwise.
+The updateExprType method is used to record this final type and update
+the recorded types: the type-checked expression tree is again traversed down,
+and the new type is propagated as needed. Untyped constant expression values
+that become fully typed must now be representable by the full type (constant
+sub-expression trees are left alone except for their roots). This mechanism
+ensures that a client sees the actual (run-time) type an untyped value would
+have. It also permits type-checking of lhs shift operands "as if the shift
+were not present": when updateExprType visits an untyped lhs shift operand
+and assigns it it's final type, that type must be an integer type, and a
+constant lhs must be representable as an integer.
+
+When an expression gets its final type, either on the way out from rawExpr,
+on the way down in updateExprType, or at the end of the type checker run,
+the type (and constant value, if any) is recorded via Info.Types, if present.
+*/
+
+type opPredicates map[syntax.Operator]func(Type) bool
+
+var unaryOpPredicates opPredicates
+
+func init() {
+	// Setting unaryOpPredicates in init avoids declaration cycles.
+	unaryOpPredicates = opPredicates{
+		syntax.Add: isNumeric,
+		syntax.Sub: isNumeric,
+		syntax.Xor: isInteger,
+		syntax.Not: isBoolean,
+	}
+}
+
+func (check *Checker) op(m opPredicates, x *operand, op syntax.Operator) bool {
+	if pred := m[op]; pred != nil {
+		if !pred(x.typ) {
+			if check.conf.CompilerErrorMessages {
+				check.errorf(x, invalidOp+"operator %s not defined on %s", op, x)
+			} else {
+				check.errorf(x, invalidOp+"operator %s not defined for %s", op, x)
+			}
+			return false
+		}
+	} else {
+		check.errorf(x, invalidAST+"unknown operator %s", op)
+		return false
+	}
+	return true
+}
+
+// overflow checks that the constant x is representable by its type.
+// For untyped constants, it checks that the value doesn't become
+// arbitrarily large.
+func (check *Checker) overflow(x *operand) {
+	assert(x.mode == constant_)
+
+	// If the corresponding expression is an operation, use the
+	// operator position rather than the start of the expression
+	// as error position.
+	pos := syntax.StartPos(x.expr)
+	what := "" // operator description, if any
+	if op, _ := x.expr.(*syntax.Operation); op != nil {
+		pos = op.Pos()
+		what = opName(op)
+	}
+
+	if x.val.Kind() == constant.Unknown {
+		// TODO(gri) We should report exactly what went wrong. At the
+		//           moment we don't have the (go/constant) API for that.
+		//           See also TODO in go/constant/value.go.
+		check.error(pos, "constant result is not representable")
+		return
+	}
+
+	// Typed constants must be representable in
+	// their type after each constant operation.
+	if isTyped(x.typ) {
+		check.representable(x, asBasic(x.typ))
+		return
+	}
+
+	// Untyped integer values must not grow arbitrarily.
+	const prec = 512 // 512 is the constant precision
+	if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
+		check.errorf(pos, "constant %s overflow", what)
+		x.val = constant.MakeUnknown()
+	}
+}
+
+// opName returns the name of an operation, or the empty string.
+// For now, only operations that might overflow are handled.
+// TODO(gri) Expand this to a general mechanism giving names to
+//           nodes?
+func opName(e *syntax.Operation) string {
+	op := int(e.Op)
+	if e.Y == nil {
+		if op < len(op2str1) {
+			return op2str1[op]
+		}
+	} else {
+		if op < len(op2str2) {
+			return op2str2[op]
+		}
+	}
+	return ""
+}
+
+var op2str1 = [...]string{
+	syntax.Xor: "bitwise complement",
+}
+
+// This is only used for operations that may cause overflow.
+var op2str2 = [...]string{
+	syntax.Add: "addition",
+	syntax.Sub: "subtraction",
+	syntax.Xor: "bitwise XOR",
+	syntax.Mul: "multiplication",
+	syntax.Shl: "shift",
+}
+
+func (check *Checker) unary(x *operand, e *syntax.Operation) {
+	check.expr(x, e.X)
+	if x.mode == invalid {
+		return
+	}
+
+	switch e.Op {
+	case syntax.And:
+		// spec: "As an exception to the addressability
+		// requirement x may also be a composite literal."
+		if _, ok := unparen(e.X).(*syntax.CompositeLit); !ok && x.mode != variable {
+			check.errorf(x, invalidOp+"cannot take address of %s", x)
+			x.mode = invalid
+			return
+		}
+		x.mode = value
+		x.typ = &Pointer{base: x.typ}
+		return
+
+	case syntax.Recv:
+		typ := asChan(x.typ)
+		if typ == nil {
+			check.errorf(x, invalidOp+"cannot receive from non-channel %s", x)
+			x.mode = invalid
+			return
+		}
+		if typ.dir == SendOnly {
+			check.errorf(x, invalidOp+"cannot receive from send-only channel %s", x)
+			x.mode = invalid
+			return
+		}
+		x.mode = commaok
+		x.typ = typ.elem
+		check.hasCallOrRecv = true
+		return
+	}
+
+	if !check.op(unaryOpPredicates, x, e.Op) {
+		x.mode = invalid
+		return
+	}
+
+	if x.mode == constant_ {
+		if x.val.Kind() == constant.Unknown {
+			// nothing to do (and don't cause an error below in the overflow check)
+			return
+		}
+		var prec uint
+		if isUnsigned(x.typ) {
+			prec = uint(check.conf.sizeof(x.typ) * 8)
+		}
+		x.val = constant.UnaryOp(op2tok[e.Op], x.val, prec)
+		x.expr = e
+		check.overflow(x)
+		return
+	}
+
+	x.mode = value
+	// x.typ remains unchanged
+}
+
+func isShift(op syntax.Operator) bool {
+	return op == syntax.Shl || op == syntax.Shr
+}
+
+func isComparison(op syntax.Operator) bool {
+	// Note: tokens are not ordered well to make this much easier
+	switch op {
+	case syntax.Eql, syntax.Neq, syntax.Lss, syntax.Leq, syntax.Gtr, syntax.Geq:
+		return true
+	}
+	return false
+}
+
+func fitsFloat32(x constant.Value) bool {
+	f32, _ := constant.Float32Val(x)
+	f := float64(f32)
+	return !math.IsInf(f, 0)
+}
+
+func roundFloat32(x constant.Value) constant.Value {
+	f32, _ := constant.Float32Val(x)
+	f := float64(f32)
+	if !math.IsInf(f, 0) {
+		return constant.MakeFloat64(f)
+	}
+	return nil
+}
+
+func fitsFloat64(x constant.Value) bool {
+	f, _ := constant.Float64Val(x)
+	return !math.IsInf(f, 0)
+}
+
+func roundFloat64(x constant.Value) constant.Value {
+	f, _ := constant.Float64Val(x)
+	if !math.IsInf(f, 0) {
+		return constant.MakeFloat64(f)
+	}
+	return nil
+}
+
+// representableConst reports whether x can be represented as
+// value of the given basic type and for the configuration
+// provided (only needed for int/uint sizes).
+//
+// If rounded != nil, *rounded is set to the rounded value of x for
+// representable floating-point and complex values, and to an Int
+// value for integer values; it is left alone otherwise.
+// It is ok to provide the addressof the first argument for rounded.
+//
+// The check parameter may be nil if representableConst is invoked
+// (indirectly) through an exported API call (AssignableTo, ConvertibleTo)
+// because we don't need the Checker's config for those calls.
+func representableConst(x constant.Value, check *Checker, typ *Basic, rounded *constant.Value) bool {
+	if x.Kind() == constant.Unknown {
+		return true // avoid follow-up errors
+	}
+
+	var conf *Config
+	if check != nil {
+		conf = check.conf
+	}
+
+	switch {
+	case isInteger(typ):
+		x := constant.ToInt(x)
+		if x.Kind() != constant.Int {
+			return false
+		}
+		if rounded != nil {
+			*rounded = x
+		}
+		if x, ok := constant.Int64Val(x); ok {
+			switch typ.kind {
+			case Int:
+				var s = uint(conf.sizeof(typ)) * 8
+				return int64(-1)<<(s-1) <= x && x <= int64(1)<<(s-1)-1
+			case Int8:
+				const s = 8
+				return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+			case Int16:
+				const s = 16
+				return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+			case Int32:
+				const s = 32
+				return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+			case Int64, UntypedInt:
+				return true
+			case Uint, Uintptr:
+				if s := uint(conf.sizeof(typ)) * 8; s < 64 {
+					return 0 <= x && x <= int64(1)<<s-1
+				}
+				return 0 <= x
+			case Uint8:
+				const s = 8
+				return 0 <= x && x <= 1<<s-1
+			case Uint16:
+				const s = 16
+				return 0 <= x && x <= 1<<s-1
+			case Uint32:
+				const s = 32
+				return 0 <= x && x <= 1<<s-1
+			case Uint64:
+				return 0 <= x
+			default:
+				unreachable()
+			}
+		}
+		// x does not fit into int64
+		switch n := constant.BitLen(x); typ.kind {
+		case Uint, Uintptr:
+			var s = uint(conf.sizeof(typ)) * 8
+			return constant.Sign(x) >= 0 && n <= int(s)
+		case Uint64:
+			return constant.Sign(x) >= 0 && n <= 64
+		case UntypedInt:
+			return true
+		}
+
+	case isFloat(typ):
+		x := constant.ToFloat(x)
+		if x.Kind() != constant.Float {
+			return false
+		}
+		switch typ.kind {
+		case Float32:
+			if rounded == nil {
+				return fitsFloat32(x)
+			}
+			r := roundFloat32(x)
+			if r != nil {
+				*rounded = r
+				return true
+			}
+		case Float64:
+			if rounded == nil {
+				return fitsFloat64(x)
+			}
+			r := roundFloat64(x)
+			if r != nil {
+				*rounded = r
+				return true
+			}
+		case UntypedFloat:
+			return true
+		default:
+			unreachable()
+		}
+
+	case isComplex(typ):
+		x := constant.ToComplex(x)
+		if x.Kind() != constant.Complex {
+			return false
+		}
+		switch typ.kind {
+		case Complex64:
+			if rounded == nil {
+				return fitsFloat32(constant.Real(x)) && fitsFloat32(constant.Imag(x))
+			}
+			re := roundFloat32(constant.Real(x))
+			im := roundFloat32(constant.Imag(x))
+			if re != nil && im != nil {
+				*rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+				return true
+			}
+		case Complex128:
+			if rounded == nil {
+				return fitsFloat64(constant.Real(x)) && fitsFloat64(constant.Imag(x))
+			}
+			re := roundFloat64(constant.Real(x))
+			im := roundFloat64(constant.Imag(x))
+			if re != nil && im != nil {
+				*rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+				return true
+			}
+		case UntypedComplex:
+			return true
+		default:
+			unreachable()
+		}
+
+	case isString(typ):
+		return x.Kind() == constant.String
+
+	case isBoolean(typ):
+		return x.Kind() == constant.Bool
+	}
+
+	return false
+}
+
+// An errorCode is a (constant) value uniquely identifing a specific error.
+type errorCode int
+
+// The following error codes are "borrowed" from go/types which codes for
+// all errors. Here we list the few codes currently needed by the various
+// conversion checking functions.
+// Eventually we will switch to reporting codes for all errors, using a
+// an error code table shared between types2 and go/types.
+const (
+	_ = errorCode(iota)
+	_TruncatedFloat
+	_NumericOverflow
+	_InvalidConstVal
+	_InvalidUntypedConversion
+
+	// The following error codes are only returned by operand.assignableTo
+	// and none of its callers use the error. Still, we keep returning the
+	// error codes to make the transition to reporting error codes all the
+	// time easier in the future.
+	_IncompatibleAssign
+	_InvalidIfaceAssign
+	_InvalidChanAssign
+)
+
+// representable checks that a constant operand is representable in the given
+// basic type.
+func (check *Checker) representable(x *operand, typ *Basic) {
+	v, code := check.representation(x, typ)
+	if code != 0 {
+		check.invalidConversion(code, x, typ)
+		x.mode = invalid
+		return
+	}
+	assert(v != nil)
+	x.val = v
+}
+
+// representation returns the representation of the constant operand x as the
+// basic type typ.
+//
+// If no such representation is possible, it returns a non-zero error code.
+func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, errorCode) {
+	assert(x.mode == constant_)
+	v := x.val
+	if !representableConst(x.val, check, typ, &v) {
+		if isNumeric(x.typ) && isNumeric(typ) {
+			// numeric conversion : error msg
+			//
+			// integer -> integer : overflows
+			// integer -> float   : overflows (actually not possible)
+			// float   -> integer : truncated
+			// float   -> float   : overflows
+			//
+			if !isInteger(x.typ) && isInteger(typ) {
+				return nil, _TruncatedFloat
+			} else {
+				return nil, _NumericOverflow
+			}
+		}
+		return nil, _InvalidConstVal
+	}
+	return v, 0
+}
+
+func (check *Checker) invalidConversion(code errorCode, x *operand, target Type) {
+	msg := "cannot convert %s to %s"
+	switch code {
+	case _TruncatedFloat:
+		msg = "%s truncated to %s"
+	case _NumericOverflow:
+		msg = "%s overflows %s"
+	}
+	check.errorf(x, msg, x, target)
+}
+
+// updateExprType updates the type of x to typ and invokes itself
+// recursively for the operands of x, depending on expression kind.
+// If typ is still an untyped and not the final type, updateExprType
+// only updates the recorded untyped type for x and possibly its
+// operands. Otherwise (i.e., typ is not an untyped type anymore,
+// or it is the final type for x), the type and value are recorded.
+// Also, if x is a constant, it must be representable as a value of typ,
+// and if x is the (formerly untyped) lhs operand of a non-constant
+// shift, it must be an integer value.
+//
+func (check *Checker) updateExprType(x syntax.Expr, typ Type, final bool) {
+	old, found := check.untyped[x]
+	if !found {
+		return // nothing to do
+	}
+
+	// update operands of x if necessary
+	switch x := x.(type) {
+	case *syntax.BadExpr,
+		*syntax.FuncLit,
+		*syntax.CompositeLit,
+		*syntax.IndexExpr,
+		*syntax.SliceExpr,
+		*syntax.AssertExpr,
+		*syntax.ListExpr,
+		//*syntax.StarExpr,
+		*syntax.KeyValueExpr,
+		*syntax.ArrayType,
+		*syntax.StructType,
+		*syntax.FuncType,
+		*syntax.InterfaceType,
+		*syntax.MapType,
+		*syntax.ChanType:
+		// These expression are never untyped - nothing to do.
+		// The respective sub-expressions got their final types
+		// upon assignment or use.
+		if debug {
+			check.dump("%v: found old type(%s): %s (new: %s)", posFor(x), x, old.typ, typ)
+			unreachable()
+		}
+		return
+
+	case *syntax.CallExpr:
+		// Resulting in an untyped constant (e.g., built-in complex).
+		// The respective calls take care of calling updateExprType
+		// for the arguments if necessary.
+
+	case *syntax.Name, *syntax.BasicLit, *syntax.SelectorExpr:
+		// An identifier denoting a constant, a constant literal,
+		// or a qualified identifier (imported untyped constant).
+		// No operands to take care of.
+
+	case *syntax.ParenExpr:
+		check.updateExprType(x.X, typ, final)
+
+	// case *syntax.UnaryExpr:
+	// 	// If x is a constant, the operands were constants.
+	// 	// 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
+	// 	}
+	// 	check.updateExprType(x.X, typ, final)
+
+	case *syntax.Operation:
+		if x.Y == nil {
+			// unary expression
+			if x.Op == syntax.Mul {
+				// see commented out code for StarExpr above
+				// TODO(gri) needs cleanup
+				if debug {
+					unimplemented()
+				}
+				return
+			}
+			// If x is a constant, the operands were constants.
+			// 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
+			}
+			check.updateExprType(x.X, typ, final)
+			break
+		}
+
+		// binary expression
+		if old.val != nil {
+			break // see comment for unary expressions
+		}
+		if isComparison(x.Op) {
+			// The result type is independent of operand types
+			// and the operand types must have final types.
+		} else if isShift(x.Op) {
+			// The result type depends only on lhs operand.
+			// The rhs type was updated when checking the shift.
+			check.updateExprType(x.X, typ, final)
+		} else {
+			// The operand types match the result type.
+			check.updateExprType(x.X, typ, final)
+			check.updateExprType(x.Y, typ, final)
+		}
+
+	default:
+		unreachable()
+	}
+
+	// If the new type is not final and still untyped, just
+	// update the recorded type.
+	if !final && isUntyped(typ) {
+		old.typ = asBasic(typ)
+		check.untyped[x] = old
+		return
+	}
+
+	// Otherwise we have the final (typed or untyped type).
+	// Remove it from the map of yet untyped expressions.
+	delete(check.untyped, x)
+
+	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.errorf(x, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
+			return
+		}
+		// Even if we have an integer, if the value is a constant we
+		// still must check that it is representable as the specific
+		// int type requested (was issue #22969). Fall through here.
+	}
+	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.
+	check.recordTypeAndValue(x, old.mode, typ, old.val)
+}
+
+// updateExprVal updates the value of x to val.
+func (check *Checker) updateExprVal(x syntax.Expr, val constant.Value) {
+	if info, ok := check.untyped[x]; ok {
+		info.val = val
+		check.untyped[x] = info
+	}
+}
+
+// convertUntyped attempts to set the type of an untyped value to the target type.
+func (check *Checker) convertUntyped(x *operand, target Type) {
+	newType, val, code := check.implicitTypeAndValue(x, target)
+	if code != 0 {
+		check.invalidConversion(code, x, target.Underlying())
+		x.mode = invalid
+		return
+	}
+	if val != nil {
+		x.val = val
+		check.updateExprVal(x.expr, val)
+	}
+	if newType != x.typ {
+		x.typ = newType
+		check.updateExprType(x.expr, newType, false)
+	}
+}
+
+// implicitTypeAndValue returns the implicit type of x when used in a context
+// where the target type is expected. If no such implicit conversion is
+// possible, it returns a nil Type and non-zero error code.
+//
+// If x is a constant operand, the returned constant.Value will be the
+// representation of x in this context.
+func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, errorCode) {
+	target = expand(target)
+	if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
+		return x.typ, nil, 0
+	}
+
+	if isUntyped(target) {
+		// both x and target are untyped
+		xkind := x.typ.(*Basic).kind
+		tkind := target.(*Basic).kind
+		if isNumeric(x.typ) && isNumeric(target) {
+			if xkind < tkind {
+				return target, nil, 0
+			}
+		} else if xkind != tkind {
+			return nil, nil, _InvalidUntypedConversion
+		}
+		return x.typ, nil, 0
+	}
+
+	if x.isNil() {
+		assert(isUntyped(x.typ))
+		if hasNil(target) {
+			return target, nil, 0
+		}
+		return nil, nil, _InvalidUntypedConversion
+	}
+
+	switch t := optype(target).(type) {
+	case *Basic:
+		if x.mode == constant_ {
+			v, code := check.representation(x, t)
+			if code != 0 {
+				return nil, nil, code
+			}
+			return target, v, code
+		}
+		// Non-constant untyped values may appear as the
+		// result of comparisons (untyped bool), intermediate
+		// (delayed-checked) rhs operands of shifts, and as
+		// the value nil.
+		switch x.typ.(*Basic).kind {
+		case UntypedBool:
+			if !isBoolean(target) {
+				return nil, nil, _InvalidUntypedConversion
+			}
+		case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
+			if !isNumeric(target) {
+				return nil, nil, _InvalidUntypedConversion
+			}
+		case UntypedString:
+			// Non-constant untyped string values are not permitted by the spec and
+			// should not occur during normal typechecking passes, but this path is
+			// reachable via the AssignableTo API.
+			if !isString(target) {
+				return nil, nil, _InvalidUntypedConversion
+			}
+		default:
+			return nil, nil, _InvalidUntypedConversion
+		}
+	case *Sum:
+		ok := t.is(func(t Type) bool {
+			target, _, _ := check.implicitTypeAndValue(x, t)
+			return target != nil
+		})
+		if !ok {
+			return nil, nil, _InvalidUntypedConversion
+		}
+	case *Interface:
+		// Update operand types to the default type rather than the target
+		// (interface) type: values must have concrete dynamic types.
+		// Untyped nil was handled upfront.
+		check.completeInterface(nopos, t)
+		if !t.Empty() {
+			return nil, nil, _InvalidUntypedConversion // cannot assign untyped values to non-empty interfaces
+		}
+		return Default(x.typ), nil, 0 // default type for nil is nil
+	default:
+		return nil, nil, _InvalidUntypedConversion
+	}
+	return target, nil, 0
+}
+
+func (check *Checker) comparison(x, y *operand, op syntax.Operator) {
+	// spec: "In any comparison, the first operand must be assignable
+	// to the type of the second operand, or vice versa."
+	err := ""
+	xok, _ := x.assignableTo(check, y.typ, nil)
+	yok, _ := y.assignableTo(check, x.typ, nil)
+	if xok || yok {
+		defined := false
+		switch op {
+		case syntax.Eql, syntax.Neq:
+			// spec: "The equality operators == and != apply to operands that are comparable."
+			defined = Comparable(x.typ) && Comparable(y.typ) || x.isNil() && hasNil(y.typ) || y.isNil() && hasNil(x.typ)
+		case syntax.Lss, syntax.Leq, syntax.Gtr, syntax.Geq:
+			// spec: The ordering operators <, <=, >, and >= apply to operands that are ordered."
+			defined = isOrdered(x.typ) && isOrdered(y.typ)
+		default:
+			unreachable()
+		}
+		if !defined {
+			typ := x.typ
+			if x.isNil() {
+				typ = y.typ
+			}
+			if check.conf.CompilerErrorMessages {
+				err = check.sprintf("operator %s not defined on %s", op, typ)
+			} else {
+				err = check.sprintf("operator %s not defined for %s", op, typ)
+			}
+		}
+	} else {
+		err = check.sprintf("mismatched types %s and %s", x.typ, y.typ)
+	}
+
+	if err != "" {
+		// TODO(gri) better error message for cases where one can only compare against nil
+		check.errorf(x, invalidOp+"cannot compare %s %s %s (%s)", x.expr, op, y.expr, err)
+		x.mode = invalid
+		return
+	}
+
+	if x.mode == constant_ && y.mode == constant_ {
+		x.val = constant.MakeBool(constant.Compare(x.val, op2tok[op], y.val))
+		// The operands are never materialized; no need to update
+		// their types.
+	} else {
+		x.mode = value
+		// The operands have now their final types, which at run-
+		// time will be materialized. Update the expression trees.
+		// If the current types are untyped, the materialized type
+		// is the respective default type.
+		check.updateExprType(x.expr, Default(x.typ), true)
+		check.updateExprType(y.expr, Default(y.typ), true)
+	}
+
+	// spec: "Comparison operators compare two operands and yield
+	//        an untyped boolean value."
+	x.typ = Typ[UntypedBool]
+}
+
+// If e != nil, it must be the shift expression; it may be nil for non-constant shifts.
+func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
+	// TODO(gri) This function seems overly complex. Revisit.
+
+	var xval constant.Value
+	if x.mode == constant_ {
+		xval = constant.ToInt(x.val)
+	}
+
+	if isInteger(x.typ) || isUntyped(x.typ) && xval != nil && xval.Kind() == constant.Int {
+		// The lhs is of integer type or an untyped constant representable
+		// as an integer. Nothing to do.
+	} else {
+		// shift has no chance
+		check.errorf(x, invalidOp+"shifted operand %s must be integer", x)
+		x.mode = invalid
+		return
+	}
+
+	// spec: "The right operand in a shift expression must have integer type
+	// or be an untyped constant representable by a value of type uint."
+
+	// Provide a good error message for negative shift counts.
+	if y.mode == constant_ {
+		yval := constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
+		if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
+			check.errorf(y, invalidOp+"negative shift count %s", y)
+			x.mode = invalid
+			return
+		}
+	}
+
+	// Caution: Check for isUntyped first because isInteger includes untyped
+	//          integers (was bug #43697).
+	if isUntyped(y.typ) {
+		check.convertUntyped(y, Typ[Uint])
+		if y.mode == invalid {
+			x.mode = invalid
+			return
+		}
+	} else if !isInteger(y.typ) {
+		check.errorf(y, invalidOp+"shift count %s must be integer", y)
+		x.mode = invalid
+		return
+	} else if !isUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
+		check.errorf(y, invalidOp+"signed shift count %s requires go1.13 or later", y)
+		x.mode = invalid
+		return
+	}
+
+	if x.mode == constant_ {
+		if y.mode == constant_ {
+			// if either x or y has an unknown value, the result is unknown
+			if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
+				x.val = constant.MakeUnknown()
+				// ensure the correct type - see comment below
+				if !isInteger(x.typ) {
+					x.typ = Typ[UntypedInt]
+				}
+				return
+			}
+			// rhs must be within reasonable bounds in constant shifts
+			const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 (see issue #44057)
+			s, ok := constant.Uint64Val(y.val)
+			if !ok || s > shiftBound {
+				check.errorf(y, invalidOp+"invalid shift count %s", y)
+				x.mode = invalid
+				return
+			}
+			// The lhs is representable as an integer but may not be an integer
+			// (e.g., 2.0, an untyped float) - this can only happen for untyped
+			// non-integer numeric constants. Correct the type so that the shift
+			// result is of integer type.
+			if !isInteger(x.typ) {
+				x.typ = Typ[UntypedInt]
+			}
+			// x is a constant so xval != nil and it must be of Int kind.
+			x.val = constant.Shift(xval, op2tok[op], uint(s))
+			x.expr = e
+			check.overflow(x)
+			return
+		}
+
+		// non-constant shift with constant lhs
+		if isUntyped(x.typ) {
+			// spec: "If the left operand of a non-constant shift
+			// expression is an untyped constant, the type of the
+			// constant is what it would be if the shift expression
+			// were replaced by its left operand alone.".
+			//
+			// Delay operand checking until we know the final type
+			// by marking the lhs expression as lhs shift operand.
+			//
+			// Usually (in correct programs), the lhs expression
+			// is in the untyped map. However, it is possible to
+			// create incorrect programs where the same expression
+			// is evaluated twice (via a declaration cycle) such
+			// that the lhs expression type is determined in the
+			// first round and thus deleted from the map, and then
+			// not found in the second round (double insertion of
+			// the same expr node still just leads to one entry for
+			// that node, and it can only be deleted once).
+			// Be cautious and check for presence of entry.
+			// Example: var e, f = int(1<<""[f]) // issue 11347
+			if info, found := check.untyped[x.expr]; found {
+				info.isLhs = true
+				check.untyped[x.expr] = info
+			}
+			// keep x's type
+			x.mode = value
+			return
+		}
+	}
+
+	// non-constant shift - lhs must be an integer
+	if !isInteger(x.typ) {
+		check.errorf(x, invalidOp+"shifted operand %s must be integer", x)
+		x.mode = invalid
+		return
+	}
+
+	x.mode = value
+}
+
+var binaryOpPredicates opPredicates
+
+func init() {
+	// Setting binaryOpPredicates in init avoids declaration cycles.
+	binaryOpPredicates = opPredicates{
+		syntax.Add: isNumericOrString,
+		syntax.Sub: isNumeric,
+		syntax.Mul: isNumeric,
+		syntax.Div: isNumeric,
+		syntax.Rem: isInteger,
+
+		syntax.And:    isInteger,
+		syntax.Or:     isInteger,
+		syntax.Xor:    isInteger,
+		syntax.AndNot: isInteger,
+
+		syntax.AndAnd: isBoolean,
+		syntax.OrOr:   isBoolean,
+	}
+}
+
+// If e != nil, it must be the binary expression; it may be nil for non-constant expressions
+// (when invoked for an assignment operation where the binary expression is implicit).
+func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op syntax.Operator) {
+	var y operand
+
+	check.expr(x, lhs)
+	check.expr(&y, rhs)
+
+	if x.mode == invalid {
+		return
+	}
+	if y.mode == invalid {
+		x.mode = invalid
+		x.expr = y.expr
+		return
+	}
+
+	if isShift(op) {
+		check.shift(x, &y, e, op)
+		return
+	}
+
+	check.convertUntyped(x, y.typ)
+	if x.mode == invalid {
+		return
+	}
+	check.convertUntyped(&y, x.typ)
+	if y.mode == invalid {
+		x.mode = invalid
+		return
+	}
+
+	if isComparison(op) {
+		check.comparison(x, &y, op)
+		return
+	}
+
+	if !check.identical(x.typ, y.typ) {
+		// only report an error if we have valid types
+		// (otherwise we had an error reported elsewhere already)
+		if x.typ != Typ[Invalid] && y.typ != Typ[Invalid] {
+			check.errorf(x, invalidOp+"mismatched types %s and %s", x.typ, y.typ)
+		}
+		x.mode = invalid
+		return
+	}
+
+	if !check.op(binaryOpPredicates, x, op) {
+		x.mode = invalid
+		return
+	}
+
+	if op == syntax.Div || op == syntax.Rem {
+		// check for zero divisor
+		if (x.mode == constant_ || isInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 {
+			check.error(&y, invalidOp+"division by zero")
+			x.mode = invalid
+			return
+		}
+
+		// check for divisor underflow in complex division (see issue 20227)
+		if x.mode == constant_ && y.mode == constant_ && isComplex(x.typ) {
+			re, im := constant.Real(y.val), constant.Imag(y.val)
+			re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
+			if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
+				check.error(&y, invalidOp+"division by zero")
+				x.mode = invalid
+				return
+			}
+		}
+	}
+
+	if x.mode == constant_ && y.mode == constant_ {
+		// if either x or y has an unknown value, the result is unknown
+		if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
+			x.val = constant.MakeUnknown()
+			// x.typ is unchanged
+			return
+		}
+		// force integer division for integer operands
+		tok := op2tok[op]
+		if op == syntax.Div && isInteger(x.typ) {
+			tok = token.QUO_ASSIGN
+		}
+		x.val = constant.BinaryOp(x.val, tok, y.val)
+		x.expr = e
+		check.overflow(x)
+		return
+	}
+
+	x.mode = value
+	// x.typ is unchanged
+}
+
+// exprKind describes the kind of an expression; the kind
+// determines if an expression is valid in 'statement context'.
+type exprKind int
+
+const (
+	conversion exprKind = iota
+	expression
+	statement
+)
+
+// rawExpr typechecks expression e and initializes x with the expression
+// value or type. If an error occurred, x.mode is set to invalid.
+// If hint != nil, it is the type of a composite literal element.
+//
+func (check *Checker) rawExpr(x *operand, e syntax.Expr, hint Type) exprKind {
+	if check.conf.Trace {
+		check.trace(e.Pos(), "expr %s", e)
+		check.indent++
+		defer func() {
+			check.indent--
+			check.trace(e.Pos(), "=> %s", x)
+		}()
+	}
+
+	kind := check.exprInternal(x, e, hint)
+	check.record(x)
+
+	return kind
+}
+
+// exprInternal contains the core of type checking of expressions.
+// Must only be called by rawExpr.
+//
+func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKind {
+	// make sure x has a valid state in case of bailout
+	// (was issue 5770)
+	x.mode = invalid
+	x.typ = Typ[Invalid]
+
+	switch e := e.(type) {
+	case nil:
+		unreachable()
+
+	case *syntax.BadExpr:
+		goto Error // error was reported before
+
+	case *syntax.Name:
+		check.ident(x, e, nil, false)
+
+	case *syntax.DotsType:
+		// dots are handled explicitly where they are legal
+		// (array composite literals and parameter lists)
+		check.error(e, "invalid use of '...'")
+		goto Error
+
+	case *syntax.BasicLit:
+		if e.Bad {
+			goto Error // error reported during parsing
+		}
+		switch e.Kind {
+		case syntax.IntLit, syntax.FloatLit, syntax.ImagLit:
+			check.langCompat(e)
+			// The max. mantissa precision for untyped numeric values
+			// is 512 bits, or 4048 bits for each of the two integer
+			// parts of a fraction for floating-point numbers that are
+			// represented accurately in the go/constant package.
+			// Constant literals that are longer than this many bits
+			// are not meaningful; and excessively long constants may
+			// consume a lot of space and time for a useless conversion.
+			// Cap constant length with a generous upper limit that also
+			// allows for separators between all digits.
+			const limit = 10000
+			if len(e.Value) > limit {
+				check.errorf(e, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
+				goto Error
+			}
+		}
+		x.setConst(e.Kind, e.Value)
+		if x.mode == invalid {
+			// The parser already establishes syntactic correctness.
+			// If we reach here it's because of number under-/overflow.
+			// TODO(gri) setConst (and in turn the go/constant package)
+			// should return an error describing the issue.
+			check.errorf(e, "malformed constant: %s", e.Value)
+			goto Error
+		}
+
+	case *syntax.FuncLit:
+		if sig, ok := check.typ(e.Type).(*Signature); ok {
+			if !check.conf.IgnoreFuncBodies && e.Body != nil {
+				// Anonymous functions are considered part of the
+				// init expression/func declaration which contains
+				// them: use existing package-level declaration info.
+				decl := check.decl // capture for use in closure below
+				iota := check.iota // capture for use in closure below (#22345)
+				// Don't type-check right away because the function may
+				// be part of a type definition to which the function
+				// body refers. Instead, type-check as soon as possible,
+				// but before the enclosing scope contents changes (#22992).
+				check.later(func() {
+					check.funcBody(decl, "<function literal>", sig, e.Body, iota)
+				})
+			}
+			x.mode = value
+			x.typ = sig
+		} else {
+			check.errorf(e, invalidAST+"invalid function literal %v", e)
+			goto Error
+		}
+
+	case *syntax.CompositeLit:
+		var typ, base Type
+
+		switch {
+		case e.Type != nil:
+			// composite literal type present - use it
+			// [...]T array types may only appear with composite literals.
+			// Check for them here so we don't have to handle ... in general.
+			if atyp, _ := e.Type.(*syntax.ArrayType); atyp != nil && atyp.Len == nil {
+				// We have an "open" [...]T array type.
+				// Create a new ArrayType with unknown length (-1)
+				// and finish setting it up after analyzing the literal.
+				typ = &Array{len: -1, elem: check.varType(atyp.Elem)}
+				base = typ
+				break
+			}
+			typ = check.typ(e.Type)
+			base = typ
+
+		case hint != nil:
+			// no composite literal type present - use hint (element type of enclosing type)
+			typ = hint
+			base, _ = deref(under(typ)) // *T implies &T{}
+
+		default:
+			// TODO(gri) provide better error messages depending on context
+			check.error(e, "missing type in composite literal")
+			goto Error
+		}
+
+		switch utyp := optype(base).(type) {
+		case *Struct:
+			if len(e.ElemList) == 0 {
+				break
+			}
+			fields := utyp.fields
+			if _, ok := e.ElemList[0].(*syntax.KeyValueExpr); ok {
+				// all elements must have keys
+				visited := make([]bool, len(fields))
+				for _, e := range e.ElemList {
+					kv, _ := e.(*syntax.KeyValueExpr)
+					if kv == nil {
+						check.error(e, "mixture of field:value and value elements in struct literal")
+						continue
+					}
+					key, _ := kv.Key.(*syntax.Name)
+					// do all possible checks early (before exiting due to errors)
+					// so we don't drop information on the floor
+					check.expr(x, kv.Value)
+					if key == nil {
+						check.errorf(kv, "invalid field name %s in struct literal", kv.Key)
+						continue
+					}
+					i := fieldIndex(utyp.fields, check.pkg, key.Value)
+					if i < 0 {
+						if check.conf.CompilerErrorMessages {
+							check.errorf(kv.Key, "unknown field '%s' in struct literal of type %s", key.Value, base)
+						} else {
+							check.errorf(kv.Key, "unknown field %s in struct literal", key.Value)
+						}
+						continue
+					}
+					fld := fields[i]
+					check.recordUse(key, fld)
+					etyp := fld.typ
+					check.assignment(x, etyp, "struct literal")
+					// 0 <= i < len(fields)
+					if visited[i] {
+						check.errorf(kv, "duplicate field name %s in struct literal", key.Value)
+						continue
+					}
+					visited[i] = true
+				}
+			} else {
+				// no element must have a key
+				for i, e := range e.ElemList {
+					if kv, _ := e.(*syntax.KeyValueExpr); kv != nil {
+						check.error(kv, "mixture of field:value and value elements in struct literal")
+						continue
+					}
+					check.expr(x, e)
+					if i >= len(fields) {
+						check.error(x, "too many values in struct literal")
+						break // cannot continue
+					}
+					// i < len(fields)
+					fld := fields[i]
+					if !fld.Exported() && fld.pkg != check.pkg {
+						check.errorf(x, "implicit assignment to unexported field %s in %s literal", fld.name, typ)
+						continue
+					}
+					etyp := fld.typ
+					check.assignment(x, etyp, "struct literal")
+				}
+				if len(e.ElemList) < len(fields) {
+					check.error(e.Rbrace, "too few values in struct literal")
+					// ok to continue
+				}
+			}
+
+		case *Array:
+			// Prevent crash if the array referred to is not yet set up. Was issue #18643.
+			// This is a stop-gap solution. Should use Checker.objPath to report entire
+			// path starting with earliest declaration in the source. TODO(gri) fix this.
+			if utyp.elem == nil {
+				check.error(e, "illegal cycle in type declaration")
+				goto Error
+			}
+			n := check.indexedElts(e.ElemList, utyp.elem, utyp.len)
+			// If we have an array of unknown length (usually [...]T arrays, but also
+			// arrays [n]T where n is invalid) set the length now that we know it and
+			// record the type for the array (usually done by check.typ which is not
+			// called for [...]T). We handle [...]T arrays and arrays with invalid
+			// length the same here because it makes sense to "guess" the length for
+			// the latter if we have a composite literal; e.g. for [n]int{1, 2, 3}
+			// where n is invalid for some reason, it seems fair to assume it should
+			// be 3 (see also Checked.arrayLength and issue #27346).
+			if utyp.len < 0 {
+				utyp.len = n
+				// e.Type is missing if we have a composite literal element
+				// that is itself a composite literal with omitted type. In
+				// that case there is nothing to record (there is no type in
+				// the source at that point).
+				if e.Type != nil {
+					check.recordTypeAndValue(e.Type, typexpr, utyp, nil)
+				}
+			}
+
+		case *Slice:
+			// Prevent crash if the slice referred to is not yet set up.
+			// See analogous comment for *Array.
+			if utyp.elem == nil {
+				check.error(e, "illegal cycle in type declaration")
+				goto Error
+			}
+			check.indexedElts(e.ElemList, utyp.elem, -1)
+
+		case *Map:
+			// Prevent crash if the map referred to is not yet set up.
+			// See analogous comment for *Array.
+			if utyp.key == nil || utyp.elem == nil {
+				check.error(e, "illegal cycle in type declaration")
+				goto Error
+			}
+			visited := make(map[interface{}][]Type, len(e.ElemList))
+			for _, e := range e.ElemList {
+				kv, _ := e.(*syntax.KeyValueExpr)
+				if kv == nil {
+					check.error(e, "missing key in map literal")
+					continue
+				}
+				check.exprWithHint(x, kv.Key, utyp.key)
+				check.assignment(x, utyp.key, "map literal")
+				if x.mode == invalid {
+					continue
+				}
+				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 asInterface(utyp.key) != nil {
+						for _, vtyp := range visited[xkey] {
+							if check.identical(vtyp, x.typ) {
+								duplicate = true
+								break
+							}
+						}
+						visited[xkey] = append(visited[xkey], x.typ)
+					} else {
+						_, duplicate = visited[xkey]
+						visited[xkey] = nil
+					}
+					if duplicate {
+						check.errorf(x, "duplicate key %s in map literal", x.val)
+						continue
+					}
+				}
+				check.exprWithHint(x, kv.Value, utyp.elem)
+				check.assignment(x, utyp.elem, "map literal")
+			}
+
+		default:
+			// when "using" all elements unpack KeyValueExpr
+			// explicitly because check.use doesn't accept them
+			for _, e := range e.ElemList {
+				if kv, _ := e.(*syntax.KeyValueExpr); kv != nil {
+					// Ideally, we should also "use" kv.Key but we can't know
+					// if it's an externally defined struct key or not. Going
+					// forward anyway can lead to other errors. Give up instead.
+					e = kv.Value
+				}
+				check.use(e)
+			}
+			// if utyp is invalid, an error was reported before
+			if utyp != Typ[Invalid] {
+				check.errorf(e, "invalid composite literal type %s", typ)
+				goto Error
+			}
+		}
+
+		x.mode = value
+		x.typ = typ
+
+	case *syntax.ParenExpr:
+		kind := check.rawExpr(x, e.X, nil)
+		x.expr = e
+		return kind
+
+	case *syntax.SelectorExpr:
+		check.selector(x, e)
+
+	case *syntax.IndexExpr:
+		if check.indexExpr(x, e) {
+			check.funcInst(x, e)
+		}
+		if x.mode == invalid {
+			goto Error
+		}
+
+	case *syntax.SliceExpr:
+		check.sliceExpr(x, e)
+		if x.mode == invalid {
+			goto Error
+		}
+
+	case *syntax.AssertExpr:
+		check.expr(x, e.X)
+		if x.mode == invalid {
+			goto Error
+		}
+		xtyp, _ := under(x.typ).(*Interface)
+		if xtyp == nil {
+			check.errorf(x, "%s is not an interface type", x)
+			goto Error
+		}
+		check.ordinaryType(x.Pos(), xtyp)
+		// x.(type) expressions are encoded via TypeSwitchGuards
+		if e.Type == nil {
+			check.error(e, invalidAST+"invalid use of AssertExpr")
+			goto Error
+		}
+		T := check.varType(e.Type)
+		if T == Typ[Invalid] {
+			goto Error
+		}
+		check.typeAssertion(posFor(x), x, xtyp, T)
+		x.mode = commaok
+		x.typ = T
+
+	case *syntax.TypeSwitchGuard:
+		// x.(type) expressions are handled explicitly in type switches
+		check.error(e, invalidAST+"use of .(type) outside type switch")
+		goto Error
+
+	case *syntax.CallExpr:
+		return check.callExpr(x, e)
+
+	case *syntax.ListExpr:
+		// catch-all for unexpected expression lists
+		check.error(e, "unexpected list of expressions")
+		goto Error
+
+	// case *syntax.UnaryExpr:
+	// 	check.expr(x, e.X)
+	// 	if x.mode == invalid {
+	// 		goto Error
+	// 	}
+	// 	check.unary(x, e, e.Op)
+	// 	if x.mode == invalid {
+	// 		goto Error
+	// 	}
+	// 	if e.Op == token.ARROW {
+	// 		x.expr = e
+	// 		return statement // receive operations may appear in statement context
+	// 	}
+
+	// case *syntax.BinaryExpr:
+	// 	check.binary(x, e, e.X, e.Y, e.Op)
+	// 	if x.mode == invalid {
+	// 		goto Error
+	// 	}
+
+	case *syntax.Operation:
+		if e.Y == nil {
+			// unary expression
+			if e.Op == syntax.Mul {
+				// pointer indirection
+				check.exprOrType(x, e.X)
+				switch x.mode {
+				case invalid:
+					goto Error
+				case typexpr:
+					x.typ = &Pointer{base: x.typ}
+				default:
+					if typ := asPointer(x.typ); typ != nil {
+						x.mode = variable
+						x.typ = typ.base
+					} else {
+						check.errorf(x, invalidOp+"cannot indirect %s", x)
+						goto Error
+					}
+				}
+				break
+			}
+
+			check.unary(x, e)
+			if x.mode == invalid {
+				goto Error
+			}
+			if e.Op == syntax.Recv {
+				x.expr = e
+				return statement // receive operations may appear in statement context
+			}
+			break
+		}
+
+		// binary expression
+		check.binary(x, e, e.X, e.Y, e.Op)
+		if x.mode == invalid {
+			goto Error
+		}
+
+	case *syntax.KeyValueExpr:
+		// key:value expressions are handled in composite literals
+		check.error(e, invalidAST+"no key:value expected")
+		goto Error
+
+	case *syntax.ArrayType, *syntax.SliceType, *syntax.StructType, *syntax.FuncType,
+		*syntax.InterfaceType, *syntax.MapType, *syntax.ChanType:
+		x.mode = typexpr
+		x.typ = check.typ(e)
+		// Note: rawExpr (caller of exprInternal) will call check.recordTypeAndValue
+		// even though check.typ has already called it. This is fine as both
+		// times the same expression and type are recorded. It is also not a
+		// performance issue because we only reach here for composite literal
+		// types, which are comparatively rare.
+
+	default:
+		panic(fmt.Sprintf("%s: unknown expression type %T", posFor(e), e))
+	}
+
+	// everything went well
+	x.expr = e
+	return expression
+
+Error:
+	x.mode = invalid
+	x.expr = e
+	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 syntax.Pos, x *operand, xtyp *Interface, T Type) {
+	method, wrongType := check.assertableTo(xtyp, T)
+	if method == nil {
+		return
+	}
+	var msg string
+	if wrongType != nil {
+		if check.identical(method.typ, wrongType.typ) {
+			msg = fmt.Sprintf("missing method %s (%s has pointer receiver)", method.name, method.name)
+		} else {
+			msg = fmt.Sprintf("wrong type for method %s (have %s, want %s)", method.name, wrongType.typ, method.typ)
+		}
+	} else {
+		msg = "missing method " + method.name
+	}
+	if check.conf.CompilerErrorMessages {
+		check.errorf(pos, "impossible type assertion: %s (%s)", x, msg)
+	} else {
+		check.errorf(pos, "%s cannot have dynamic type %s (%s)", x, T, msg)
+	}
+}
+
+// expr typechecks expression e and initializes x with the expression value.
+// The result must be a single value.
+// If an error occurred, x.mode is set to invalid.
+//
+func (check *Checker) expr(x *operand, e syntax.Expr) {
+	check.rawExpr(x, e, nil)
+	check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
+	check.singleValue(x)
+}
+
+// multiExpr is like expr but the result may also be a multi-value.
+func (check *Checker) multiExpr(x *operand, e syntax.Expr) {
+	check.rawExpr(x, e, nil)
+	check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
+}
+
+// exprWithHint typechecks expression e and initializes x with the expression value;
+// hint is the type of a composite literal element.
+// If an error occurred, x.mode is set to invalid.
+//
+func (check *Checker) exprWithHint(x *operand, e syntax.Expr, hint Type) {
+	assert(hint != nil)
+	check.rawExpr(x, e, hint)
+	check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
+	check.singleValue(x)
+}
+
+// exprOrType typechecks expression or type e and initializes x with the expression value or type.
+// If an error occurred, x.mode is set to invalid.
+//
+func (check *Checker) exprOrType(x *operand, e syntax.Expr) {
+	check.rawExpr(x, e, nil)
+	check.exclude(x, 1<<novalue)
+	check.singleValue(x)
+}
+
+// exclude reports an error if x.mode is in modeset and sets x.mode to invalid.
+// The modeset may contain any of 1<<novalue, 1<<builtin, 1<<typexpr.
+func (check *Checker) exclude(x *operand, modeset uint) {
+	if modeset&(1<<x.mode) != 0 {
+		var msg string
+		switch x.mode {
+		case novalue:
+			if modeset&(1<<typexpr) != 0 {
+				msg = "%s used as value"
+			} else {
+				msg = "%s used as value or type"
+			}
+		case builtin:
+			msg = "%s must be called"
+		case typexpr:
+			msg = "%s is not an expression"
+		default:
+			unreachable()
+		}
+		check.errorf(x, msg, x)
+		x.mode = invalid
+	}
+}
+
+// singleValue reports an error if x describes a tuple and sets x.mode to invalid.
+func (check *Checker) singleValue(x *operand) {
+	if x.mode == value {
+		// tuple types are never named - no need for underlying type below
+		if t, ok := x.typ.(*Tuple); ok {
+			assert(t.Len() != 1)
+			check.errorf(x, "%d-valued %s where single value is expected", t.Len(), x)
+			x.mode = invalid
+		}
+	}
+}
+
+// op2tok translates syntax.Operators into token.Tokens.
+var op2tok = [...]token.Token{
+	syntax.Def:  token.ILLEGAL,
+	syntax.Not:  token.NOT,
+	syntax.Recv: token.ILLEGAL,
+
+	syntax.OrOr:   token.LOR,
+	syntax.AndAnd: token.LAND,
+
+	syntax.Eql: token.EQL,
+	syntax.Neq: token.NEQ,
+	syntax.Lss: token.LSS,
+	syntax.Leq: token.LEQ,
+	syntax.Gtr: token.GTR,
+	syntax.Geq: token.GEQ,
+
+	syntax.Add: token.ADD,
+	syntax.Sub: token.SUB,
+	syntax.Or:  token.OR,
+	syntax.Xor: token.XOR,
+
+	syntax.Mul:    token.MUL,
+	syntax.Div:    token.QUO,
+	syntax.Rem:    token.REM,
+	syntax.And:    token.AND,
+	syntax.AndNot: token.AND_NOT,
+	syntax.Shl:    token.SHL,
+	syntax.Shr:    token.SHR,
+}
diff --git a/src/cmd/compile/internal/types2/gccgosizes.go b/src/cmd/compile/internal/types2/gccgosizes.go
new file mode 100644
index 0000000..05aba53
--- /dev/null
+++ b/src/cmd/compile/internal/types2/gccgosizes.go
@@ -0,0 +1,40 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This is a copy of the file generated during the gccgo build process.
+// Last update 2019-01-22.
+
+package types2
+
+var gccgoArchSizes = map[string]*StdSizes{
+	"386":         {4, 4},
+	"alpha":       {8, 8},
+	"amd64":       {8, 8},
+	"amd64p32":    {4, 8},
+	"arm":         {4, 8},
+	"armbe":       {4, 8},
+	"arm64":       {8, 8},
+	"arm64be":     {8, 8},
+	"ia64":        {8, 8},
+	"m68k":        {4, 2},
+	"mips":        {4, 8},
+	"mipsle":      {4, 8},
+	"mips64":      {8, 8},
+	"mips64le":    {8, 8},
+	"mips64p32":   {4, 8},
+	"mips64p32le": {4, 8},
+	"nios2":       {4, 8},
+	"ppc":         {4, 8},
+	"ppc64":       {8, 8},
+	"ppc64le":     {8, 8},
+	"riscv":       {4, 8},
+	"riscv64":     {8, 8},
+	"s390":        {4, 8},
+	"s390x":       {8, 8},
+	"sh":          {4, 8},
+	"shbe":        {4, 8},
+	"sparc":       {4, 8},
+	"sparc64":     {8, 8},
+	"wasm":        {8, 8},
+}
diff --git a/src/cmd/compile/internal/types2/hilbert_test.go b/src/cmd/compile/internal/types2/hilbert_test.go
new file mode 100644
index 0000000..9f9dad6
--- /dev/null
+++ b/src/cmd/compile/internal/types2/hilbert_test.go
@@ -0,0 +1,219 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2_test
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"testing"
+
+	. "cmd/compile/internal/types2"
+)
+
+var (
+	H   = flag.Int("H", 5, "Hilbert matrix size")
+	out = flag.String("out", "", "write generated program to out")
+)
+
+func TestHilbert(t *testing.T) {
+	// generate source
+	src := program(*H, *out)
+	if *out != "" {
+		ioutil.WriteFile(*out, src, 0666)
+		return
+	}
+
+	// parse source
+	// TODO(gri) get rid of []bytes to string conversion below
+	f, err := parseSrc("hilbert.go", string(src))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// type-check file
+	DefPredeclaredTestFuncs() // define assert built-in
+	conf := Config{Importer: defaultImporter()}
+	_, err = conf.Check(f.PkgName.Value, []*syntax.File{f}, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func program(n int, out string) []byte {
+	var g gen
+
+	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
+// be the identity matrix.
+package main
+
+func main() {
+	if !ok {
+		printProduct()
+		return
+	}
+	println("PASS")
+}
+
+`, n, out)
+	g.hilbert(n)
+	g.inverse(n)
+	g.product(n)
+	g.verify(n)
+	g.printProduct(n)
+	g.binomials(2*n - 1)
+	g.factorials(2*n - 1)
+
+	return g.Bytes()
+}
+
+type gen struct {
+	bytes.Buffer
+}
+
+func (g *gen) p(format string, args ...interface{}) {
+	fmt.Fprintf(&g.Buffer, format, args...)
+}
+
+func (g *gen) hilbert(n int) {
+	g.p(`// Hilbert matrix, n = %d
+const (
+`, n)
+	for i := 0; i < n; i++ {
+		g.p("\t")
+		for j := 0; j < n; j++ {
+			if j > 0 {
+				g.p(", ")
+			}
+			g.p("h%d_%d", i, j)
+		}
+		if i == 0 {
+			g.p(" = ")
+			for j := 0; j < n; j++ {
+				if j > 0 {
+					g.p(", ")
+				}
+				g.p("1.0/(iota + %d)", j+1)
+			}
+		}
+		g.p("\n")
+	}
+	g.p(")\n\n")
+}
+
+func (g *gen) inverse(n int) {
+	g.p(`// Inverse Hilbert matrix
+const (
+`)
+	for i := 0; i < n; i++ {
+		for j := 0; j < n; j++ {
+			s := "+"
+			if (i+j)&1 != 0 {
+				s = "-"
+			}
+			g.p("\ti%d_%d = %s%d * b%d_%d * b%d_%d * b%d_%d * b%d_%d\n",
+				i, j, s, i+j+1, n+i, n-j-1, n+j, n-i-1, i+j, i, i+j, i)
+		}
+		g.p("\n")
+	}
+	g.p(")\n\n")
+}
+
+func (g *gen) product(n int) {
+	g.p(`// Product matrix
+const (
+`)
+	for i := 0; i < n; i++ {
+		for j := 0; j < n; j++ {
+			g.p("\tp%d_%d = ", i, j)
+			for k := 0; k < n; k++ {
+				if k > 0 {
+					g.p(" + ")
+				}
+				g.p("h%d_%d*i%d_%d", i, k, k, j)
+			}
+			g.p("\n")
+		}
+		g.p("\n")
+	}
+	g.p(")\n\n")
+}
+
+func (g *gen) verify(n int) {
+	g.p(`// Verify that product is the identity matrix
+const ok =
+`)
+	for i := 0; i < n; i++ {
+		for j := 0; j < n; j++ {
+			if j == 0 {
+				g.p("\t")
+			} else {
+				g.p(" && ")
+			}
+			v := 0
+			if i == j {
+				v = 1
+			}
+			g.p("p%d_%d == %d", i, j, v)
+		}
+		g.p(" &&\n")
+	}
+	g.p("\ttrue\n\n")
+
+	// verify ok at type-check time
+	if *out == "" {
+		g.p("const _ = assert(ok)\n\n")
+	}
+}
+
+func (g *gen) printProduct(n int) {
+	g.p("func printProduct() {\n")
+	for i := 0; i < n; i++ {
+		g.p("\tprintln(")
+		for j := 0; j < n; j++ {
+			if j > 0 {
+				g.p(", ")
+			}
+			g.p("p%d_%d", i, j)
+		}
+		g.p(")\n")
+	}
+	g.p("}\n\n")
+}
+
+func (g *gen) binomials(n int) {
+	g.p(`// Binomials
+const (
+`)
+	for j := 0; j <= n; j++ {
+		if j > 0 {
+			g.p("\n")
+		}
+		for k := 0; k <= j; k++ {
+			g.p("\tb%d_%d = f%d / (f%d*f%d)\n", j, k, j, k, j-k)
+		}
+	}
+	g.p(")\n\n")
+}
+
+func (g *gen) factorials(n int) {
+	g.p(`// Factorials
+const (
+	f0 = 1
+	f1 = 1
+`)
+	for i := 2; i <= n; i++ {
+		g.p("\tf%d = f%d * %d\n", i, i-1, i)
+	}
+	g.p(")\n\n")
+}
diff --git a/src/cmd/compile/internal/types2/importer_test.go b/src/cmd/compile/internal/types2/importer_test.go
new file mode 100644
index 0000000..6b9b500
--- /dev/null
+++ b/src/cmd/compile/internal/types2/importer_test.go
@@ -0,0 +1,35 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements the (temporary) plumbing to get importing to work.
+
+package types2_test
+
+import (
+	gcimporter "cmd/compile/internal/importer"
+	"cmd/compile/internal/types2"
+	"io"
+)
+
+func defaultImporter() types2.Importer {
+	return &gcimports{
+		packages: make(map[string]*types2.Package),
+	}
+}
+
+type gcimports struct {
+	packages map[string]*types2.Package
+	lookup   func(path string) (io.ReadCloser, error)
+}
+
+func (m *gcimports) Import(path string) (*types2.Package, error) {
+	return m.ImportFrom(path, "" /* no vendoring */, 0)
+}
+
+func (m *gcimports) ImportFrom(path, srcDir string, mode types2.ImportMode) (*types2.Package, error) {
+	if mode != 0 {
+		panic("mode must be 0")
+	}
+	return gcimporter.Import(m.packages, path, srcDir, m.lookup)
+}
diff --git a/src/cmd/compile/internal/types2/index.go b/src/cmd/compile/internal/types2/index.go
new file mode 100644
index 0000000..c94017a
--- /dev/null
+++ b/src/cmd/compile/internal/types2/index.go
@@ -0,0 +1,452 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements typechecking of index/slice expressions.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"go/constant"
+)
+
+// If e is a valid function instantiation, indexExpr returns true.
+// In that case x represents the uninstantiated function value and
+// it is the caller's responsibility to instantiate the function.
+func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst bool) {
+	check.exprOrType(x, e.X)
+
+	switch x.mode {
+	case invalid:
+		check.use(e.Index)
+		return false
+
+	case typexpr:
+		// type instantiation
+		x.mode = invalid
+		x.typ = check.varType(e)
+		if x.typ != Typ[Invalid] {
+			x.mode = typexpr
+		}
+		return false
+
+	case value:
+		if sig := asSignature(x.typ); sig != nil && len(sig.tparams) > 0 {
+			// function instantiation
+			return true
+		}
+	}
+
+	// ordinary index expression
+	valid := false
+	length := int64(-1) // valid if >= 0
+	switch typ := optype(x.typ).(type) {
+	case *Basic:
+		if isString(typ) {
+			valid = true
+			if x.mode == constant_ {
+				length = int64(len(constant.StringVal(x.val)))
+			}
+			// an indexed string always yields a byte value
+			// (not a constant) even if the string and the
+			// index are constant
+			x.mode = value
+			x.typ = universeByte // use 'byte' name
+		}
+
+	case *Array:
+		valid = true
+		length = typ.len
+		if x.mode != variable {
+			x.mode = value
+		}
+		x.typ = typ.elem
+
+	case *Pointer:
+		if typ := asArray(typ.base); typ != nil {
+			valid = true
+			length = typ.len
+			x.mode = variable
+			x.typ = typ.elem
+		}
+
+	case *Slice:
+		valid = true
+		x.mode = variable
+		x.typ = typ.elem
+
+	case *Map:
+		index := check.singleIndex(e)
+		if index == nil {
+			x.mode = invalid
+			return
+		}
+		var key operand
+		check.expr(&key, index)
+		check.assignment(&key, typ.key, "map index")
+		// ok to continue even if indexing failed - map element type is known
+		x.mode = mapindex
+		x.typ = typ.elem
+		x.expr = e
+		return
+
+	case *Sum:
+		// A sum type can be indexed if all of the sum's types
+		// support indexing and have the same index and element
+		// type. Special rules apply for maps in the sum type.
+		var tkey, telem Type // key is for map types only
+		nmaps := 0           // number of map types in sum type
+		if typ.is(func(t Type) bool {
+			var e Type
+			switch t := under(t).(type) {
+			case *Basic:
+				if isString(t) {
+					e = universeByte
+				}
+			case *Array:
+				e = t.elem
+			case *Pointer:
+				if t := asArray(t.base); t != nil {
+					e = t.elem
+				}
+			case *Slice:
+				e = t.elem
+			case *Map:
+				// If there are multiple maps in the sum type,
+				// they must have identical key types.
+				// TODO(gri) We may be able to relax this rule
+				// but it becomes complicated very quickly.
+				if tkey != nil && !Identical(t.key, tkey) {
+					return false
+				}
+				tkey = t.key
+				e = t.elem
+				nmaps++
+			case *TypeParam:
+				check.errorf(x, "type of %s contains a type parameter - cannot index (implementation restriction)", x)
+			case *instance:
+				panic("unimplemented")
+			}
+			if e == nil || telem != nil && !Identical(e, telem) {
+				return false
+			}
+			telem = e
+			return true
+		}) {
+			// If there are maps, the index expression must be assignable
+			// to the map key type (as for simple map index expressions).
+			if nmaps > 0 {
+				index := check.singleIndex(e)
+				if index == nil {
+					x.mode = invalid
+					return
+				}
+				var key operand
+				check.expr(&key, index)
+				check.assignment(&key, tkey, "map index")
+				// ok to continue even if indexing failed - map element type is known
+
+				// If there are only maps, we are done.
+				if nmaps == len(typ.types) {
+					x.mode = mapindex
+					x.typ = telem
+					x.expr = e
+					return
+				}
+
+				// Otherwise we have mix of maps and other types. For
+				// now we require that the map key be an integer type.
+				// TODO(gri) This is probably not good enough.
+				valid = isInteger(tkey)
+				// avoid 2nd indexing error if indexing failed above
+				if !valid && key.mode == invalid {
+					x.mode = invalid
+					return
+				}
+				x.mode = value // map index expressions are not addressable
+			} else {
+				// no maps
+				valid = true
+				x.mode = variable
+			}
+			x.typ = telem
+		}
+	}
+
+	if !valid {
+		check.errorf(x, invalidOp+"cannot index %s", x)
+		x.mode = invalid
+		return
+	}
+
+	index := check.singleIndex(e)
+	if index == nil {
+		x.mode = invalid
+		return
+	}
+
+	// In pathological (invalid) cases (e.g.: type T1 [][[]T1{}[0][0]]T0)
+	// the element type may be accessed before it's set. Make sure we have
+	// a valid type.
+	if x.typ == nil {
+		x.typ = Typ[Invalid]
+	}
+
+	check.index(index, length)
+	return false
+}
+
+func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
+	check.expr(x, e.X)
+	if x.mode == invalid {
+		check.use(e.Index[:]...)
+		return
+	}
+
+	valid := false
+	length := int64(-1) // valid if >= 0
+	switch typ := optype(x.typ).(type) {
+	case *Basic:
+		if isString(typ) {
+			if e.Full {
+				check.error(x, invalidOp+"3-index slice of string")
+				x.mode = invalid
+				return
+			}
+			valid = true
+			if x.mode == constant_ {
+				length = int64(len(constant.StringVal(x.val)))
+			}
+			// spec: "For untyped string operands the result
+			// is a non-constant value of type string."
+			if typ.kind == UntypedString {
+				x.typ = Typ[String]
+			}
+		}
+
+	case *Array:
+		valid = true
+		length = typ.len
+		if x.mode != variable {
+			check.errorf(x, invalidOp+"%s (slice of unaddressable value)", x)
+			x.mode = invalid
+			return
+		}
+		x.typ = &Slice{elem: typ.elem}
+
+	case *Pointer:
+		if typ := asArray(typ.base); typ != nil {
+			valid = true
+			length = typ.len
+			x.typ = &Slice{elem: typ.elem}
+		}
+
+	case *Slice:
+		valid = true
+		// x.typ doesn't change
+
+	case *Sum, *TypeParam:
+		check.error(x, "generic slice expressions not yet implemented")
+		x.mode = invalid
+		return
+	}
+
+	if !valid {
+		check.errorf(x, invalidOp+"cannot slice %s", x)
+		x.mode = invalid
+		return
+	}
+
+	x.mode = value
+
+	// spec: "Only the first index may be omitted; it defaults to 0."
+	if e.Full && (e.Index[1] == nil || e.Index[2] == nil) {
+		check.error(e, invalidAST+"2nd and 3rd index required in 3-index slice")
+		x.mode = invalid
+		return
+	}
+
+	// check indices
+	var ind [3]int64
+	for i, expr := range e.Index {
+		x := int64(-1)
+		switch {
+		case expr != nil:
+			// The "capacity" is only known statically for strings, arrays,
+			// and pointers to arrays, and it is the same as the length for
+			// those types.
+			max := int64(-1)
+			if length >= 0 {
+				max = length + 1
+			}
+			if _, v := check.index(expr, max); v >= 0 {
+				x = v
+			}
+		case i == 0:
+			// default is 0 for the first index
+			x = 0
+		case length >= 0:
+			// default is length (== capacity) otherwise
+			x = length
+		}
+		ind[i] = x
+	}
+
+	// constant indices must be in range
+	// (check.index already checks that existing indices >= 0)
+L:
+	for i, x := range ind[:len(ind)-1] {
+		if x > 0 {
+			for _, y := range ind[i+1:] {
+				if y >= 0 && x > y {
+					check.errorf(e, "invalid slice indices: %d > %d", x, y)
+					break L // only report one error, ok to continue
+				}
+			}
+		}
+	}
+}
+
+// singleIndex returns the (single) index from the index expression e.
+// If the index is missing, or if there are multiple indices, an error
+// is reported and the result is nil.
+func (check *Checker) singleIndex(e *syntax.IndexExpr) syntax.Expr {
+	index := e.Index
+	if index == nil {
+		check.errorf(e, invalidAST+"missing index for %s", e.X)
+		return nil
+	}
+	if l, _ := index.(*syntax.ListExpr); l != nil {
+		if n := len(l.ElemList); n <= 1 {
+			check.errorf(e, invalidAST+"invalid use of ListExpr for index expression %v with %d indices", e, n)
+			return nil
+		}
+		// len(l.ElemList) > 1
+		check.error(l.ElemList[1], invalidOp+"more than one index")
+		index = l.ElemList[0] // continue with first index
+	}
+	return index
+}
+
+// index checks an index expression for validity.
+// If max >= 0, it is the upper bound for index.
+// If the result typ is != Typ[Invalid], index is valid and typ is its (possibly named) integer type.
+// If the result val >= 0, index is valid and val is its constant int value.
+func (check *Checker) index(index syntax.Expr, max int64) (typ Type, val int64) {
+	typ = Typ[Invalid]
+	val = -1
+
+	var x operand
+	check.expr(&x, index)
+	if !check.isValidIndex(&x, "index", false) {
+		return
+	}
+
+	if x.mode != constant_ {
+		return x.typ, -1
+	}
+
+	if x.val.Kind() == constant.Unknown {
+		return
+	}
+
+	v, ok := constant.Int64Val(x.val)
+	assert(ok)
+	if max >= 0 && v >= max {
+		if check.conf.CompilerErrorMessages {
+			check.errorf(&x, invalidArg+"array index %s out of bounds [0:%d]", x.val.String(), max)
+		} else {
+			check.errorf(&x, invalidArg+"index %s is out of bounds", &x)
+		}
+		return
+	}
+
+	// 0 <= v [ && v < max ]
+	return x.typ, v
+}
+
+// isValidIndex checks whether operand x satisfies the criteria for integer
+// index values. If allowNegative is set, a constant operand may be negative.
+// If the operand is not valid, an error is reported (using what as context)
+// and the result is false.
+func (check *Checker) isValidIndex(x *operand, what string, allowNegative bool) bool {
+	if x.mode == invalid {
+		return false
+	}
+
+	// spec: "a constant index that is untyped is given type int"
+	check.convertUntyped(x, Typ[Int])
+	if x.mode == invalid {
+		return false
+	}
+
+	// spec: "the index x must be of integer type or an untyped constant"
+	if !isInteger(x.typ) {
+		check.errorf(x, invalidArg+"%s %s must be integer", what, x)
+		return false
+	}
+
+	if x.mode == constant_ {
+		// spec: "a constant index must be non-negative ..."
+		if !allowNegative && constant.Sign(x.val) < 0 {
+			check.errorf(x, invalidArg+"%s %s must not be negative", what, x)
+			return false
+		}
+
+		// spec: "... and representable by a value of type int"
+		if !representableConst(x.val, check, Typ[Int], &x.val) {
+			check.errorf(x, invalidArg+"%s %s overflows int", what, x)
+			return false
+		}
+	}
+
+	return true
+}
+
+// indexElts checks the elements (elts) of an array or slice composite literal
+// against the literal's element type (typ), and the element indices against
+// the literal length if known (length >= 0). It returns the length of the
+// literal (maximum index value + 1).
+func (check *Checker) indexedElts(elts []syntax.Expr, typ Type, length int64) int64 {
+	visited := make(map[int64]bool, len(elts))
+	var index, max int64
+	for _, e := range elts {
+		// determine and check index
+		validIndex := false
+		eval := e
+		if kv, _ := e.(*syntax.KeyValueExpr); kv != nil {
+			if typ, i := check.index(kv.Key, length); typ != Typ[Invalid] {
+				if i >= 0 {
+					index = i
+					validIndex = true
+				} else {
+					check.errorf(e, "index %s must be integer constant", kv.Key)
+				}
+			}
+			eval = kv.Value
+		} else if length >= 0 && index >= length {
+			check.errorf(e, "index %d is out of bounds (>= %d)", index, length)
+		} else {
+			validIndex = true
+		}
+
+		// if we have a valid index, check for duplicate entries
+		if validIndex {
+			if visited[index] {
+				check.errorf(e, "duplicate index %d in array or slice literal", index)
+			}
+			visited[index] = true
+		}
+		index++
+		if index > max {
+			max = index
+		}
+
+		// check element against composite literal element type
+		var x operand
+		check.exprWithHint(&x, eval, typ)
+		check.assignment(&x, typ, "array or slice literal")
+	}
+	return max
+}
diff --git a/src/cmd/compile/internal/types2/infer.go b/src/cmd/compile/internal/types2/infer.go
new file mode 100644
index 0000000..f37d7f6
--- /dev/null
+++ b/src/cmd/compile/internal/types2/infer.go
@@ -0,0 +1,487 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements type parameter inference.
+
+package types2
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+)
+
+const useConstraintTypeInference = true
+
+// infer attempts to infer the complete set of type arguments for generic function instantiation/call
+// based on the given type parameters tparams, type arguments targs, function parameters params, and
+// function arguments args, if any. There must be at least one type parameter, no more type arguments
+// than type parameters, and params and args must match in number (incl. zero).
+// If successful, infer returns the complete list of type arguments, one for each type parameter.
+// Otherwise the result is nil and appropriate errors will be reported unless report is set to false.
+//
+// Inference proceeds in 3 steps:
+//
+//   1) Start with given type arguments.
+//   2) Infer type arguments from typed function arguments.
+//   3) Infer type arguments from untyped function arguments.
+//
+// Constraint type inference is used after each step to expand the set of type arguments.
+//
+func (check *Checker) infer(pos syntax.Pos, tparams []*TypeName, targs []Type, params *Tuple, args []*operand, report bool) (result []Type) {
+	if debug {
+		defer func() {
+			assert(result == nil || len(result) == len(tparams))
+			for _, targ := range result {
+				assert(targ != nil)
+			}
+			//check.dump("### inferred targs = %s", result)
+		}()
+	}
+
+	// There must be at least one type parameter, and no more type arguments than type parameters.
+	n := len(tparams)
+	assert(n > 0 && len(targs) <= n)
+
+	// Function parameters and arguments must match in number.
+	assert(params.Len() == len(args))
+
+	// --- 0 ---
+	// If we already have all type arguments, we're done.
+	if len(targs) == n {
+		return targs
+	}
+	// len(targs) < n
+
+	// --- 1 ---
+	// Explicitly provided type arguments take precedence over any inferred types;
+	// and types inferred via constraint type inference take precedence over types
+	// inferred from function arguments.
+	// If we have type arguments, see how far we get with constraint type inference.
+	if len(targs) > 0 && useConstraintTypeInference {
+		var index int
+		targs, index = check.inferB(tparams, targs, report)
+		if targs == nil || index < 0 {
+			return targs
+		}
+	}
+
+	// Continue with the type arguments we have now. Avoid matching generic
+	// parameters that already have type arguments against function arguments:
+	// It may fail because matching uses type identity while parameter passing
+	// uses assignment rules. Instantiate the parameter list with the type
+	// arguments we have, and continue with that parameter list.
+
+	// First, make sure we have a "full" list of type arguments, so of which
+	// may be nil (unknown).
+	if len(targs) < n {
+		targs2 := make([]Type, n)
+		copy(targs2, targs)
+		targs = targs2
+	}
+	// len(targs) == n
+
+	// Substitute type arguments for their respective type parameters in params,
+	// if any. Note that nil targs entries are ignored by check.subst.
+	// TODO(gri) Can we avoid this (we're setting known type argumemts below,
+	//           but that doesn't impact the isParameterized check for now).
+	if params.Len() > 0 {
+		smap := makeSubstMap(tparams, targs)
+		params = check.subst(nopos, params, smap).(*Tuple)
+	}
+
+	// --- 2 ---
+	// Unify parameter and argument types for generic parameters with typed arguments
+	// and collect the indices of generic parameters with untyped arguments.
+	// Terminology: generic parameter = function parameter with a type-parameterized type
+	u := newUnifier(check, false)
+	u.x.init(tparams)
+
+	// Set the type arguments which we know already.
+	for i, targ := range targs {
+		if targ != nil {
+			u.x.set(i, targ)
+		}
+	}
+
+	errorf := func(kind string, tpar, targ Type, arg *operand) {
+		if !report {
+			return
+		}
+		// provide a better error message if we can
+		targs, index := u.x.types()
+		if index == 0 {
+			// The first type parameter couldn't be inferred.
+			// If none of them could be inferred, don't try
+			// to provide the inferred type in the error msg.
+			allFailed := true
+			for _, targ := range targs {
+				if targ != nil {
+					allFailed = false
+					break
+				}
+			}
+			if allFailed {
+				check.errorf(arg, "%s %s of %s does not match %s (cannot infer %s)", kind, targ, arg.expr, tpar, typeNamesString(tparams))
+				return
+			}
+		}
+		smap := makeSubstMap(tparams, targs)
+		inferred := check.subst(arg.Pos(), tpar, smap)
+		if inferred != tpar {
+			check.errorf(arg, "%s %s of %s does not match inferred type %s for %s", kind, targ, arg.expr, inferred, tpar)
+		} else {
+			check.errorf(arg, "%s %s of %s does not match %s", kind, targ, arg.expr, tpar)
+		}
+	}
+
+	// indices of the generic parameters with untyped arguments - save for later
+	var indices []int
+	for i, arg := range args {
+		par := params.At(i)
+		// If we permit bidirectional unification, this conditional code needs to be
+		// executed even if par.typ is not parameterized since the argument may be a
+		// generic function (for which we want to infer its type arguments).
+		if isParameterized(tparams, par.typ) {
+			if arg.mode == invalid {
+				// An error was reported earlier. Ignore this targ
+				// and continue, we may still be able to infer all
+				// targs resulting in fewer follon-on errors.
+				continue
+			}
+			if targ := arg.typ; isTyped(targ) {
+				// If we permit bidirectional unification, and targ is
+				// a generic function, we need to initialize u.y with
+				// the respective type parameters of targ.
+				if !u.unify(par.typ, targ) {
+					errorf("type", par.typ, targ, arg)
+					return nil
+				}
+			} else {
+				indices = append(indices, i)
+			}
+		}
+	}
+
+	// If we've got all type arguments, we're done.
+	var index int
+	targs, index = u.x.types()
+	if index < 0 {
+		return targs
+	}
+
+	// See how far we get with constraint type inference.
+	// Note that even if we don't have any type arguments, constraint type inference
+	// may produce results for constraints that explicitly specify a type.
+	if useConstraintTypeInference {
+		targs, index = check.inferB(tparams, targs, report)
+		if targs == nil || index < 0 {
+			return targs
+		}
+	}
+
+	// --- 3 ---
+	// Use any untyped arguments to infer additional type arguments.
+	// Some generic parameters with untyped arguments may have been given
+	// a type by now, we can ignore them.
+	for _, i := range indices {
+		par := params.At(i)
+		// Since untyped types are all basic (i.e., non-composite) types, an
+		// untyped argument will never match a composite parameter type; the
+		// only parameter type it can possibly match against is a *TypeParam.
+		// Thus, only consider untyped arguments for generic parameters that
+		// are not of composite types and which don't have a type inferred yet.
+		if tpar, _ := par.typ.(*TypeParam); tpar != nil && targs[tpar.index] == nil {
+			arg := args[i]
+			targ := Default(arg.typ)
+			// The default type for an untyped nil is untyped nil. We must not
+			// infer an untyped nil type as type parameter type. Ignore untyped
+			// nil by making sure all default argument types are typed.
+			if isTyped(targ) && !u.unify(par.typ, targ) {
+				errorf("default type", par.typ, targ, arg)
+				return nil
+			}
+		}
+	}
+
+	// If we've got all type arguments, we're done.
+	targs, index = u.x.types()
+	if index < 0 {
+		return targs
+	}
+
+	// Again, follow up with constraint type inference.
+	if useConstraintTypeInference {
+		targs, index = check.inferB(tparams, targs, report)
+		if targs == nil || index < 0 {
+			return targs
+		}
+	}
+
+	// At least one type argument couldn't be inferred.
+	assert(targs != nil && index >= 0 && targs[index] == nil)
+	tpar := tparams[index]
+	if report {
+		check.errorf(pos, "cannot infer %s (%s) (%s)", tpar.name, tpar.pos, targs)
+	}
+	return nil
+}
+
+// typeNamesString produces a string containing all the
+// type names in list suitable for human consumption.
+func typeNamesString(list []*TypeName) string {
+	// common cases
+	n := len(list)
+	switch n {
+	case 0:
+		return ""
+	case 1:
+		return list[0].name
+	case 2:
+		return list[0].name + " and " + list[1].name
+	}
+
+	// general case (n > 2)
+	// Would like to use strings.Builder but it's not available in Go 1.4.
+	var b bytes.Buffer
+	for i, tname := range list[:n-1] {
+		if i > 0 {
+			b.WriteString(", ")
+		}
+		b.WriteString(tname.name)
+	}
+	b.WriteString(", and ")
+	b.WriteString(list[n-1].name)
+	return b.String()
+}
+
+// IsParameterized reports whether typ contains any of the type parameters of tparams.
+func isParameterized(tparams []*TypeName, typ Type) bool {
+	w := tpWalker{
+		seen:    make(map[Type]bool),
+		tparams: tparams,
+	}
+	return w.isParameterized(typ)
+}
+
+type tpWalker struct {
+	seen    map[Type]bool
+	tparams []*TypeName
+}
+
+func (w *tpWalker) isParameterized(typ Type) (res bool) {
+	// detect cycles
+	if x, ok := w.seen[typ]; ok {
+		return x
+	}
+	w.seen[typ] = false
+	defer func() {
+		w.seen[typ] = res
+	}()
+
+	switch t := typ.(type) {
+	case nil, *Basic: // TODO(gri) should nil be handled here?
+		break
+
+	case *Array:
+		return w.isParameterized(t.elem)
+
+	case *Slice:
+		return w.isParameterized(t.elem)
+
+	case *Struct:
+		for _, fld := range t.fields {
+			if w.isParameterized(fld.typ) {
+				return true
+			}
+		}
+
+	case *Pointer:
+		return w.isParameterized(t.base)
+
+	case *Tuple:
+		n := t.Len()
+		for i := 0; i < n; i++ {
+			if w.isParameterized(t.At(i).typ) {
+				return true
+			}
+		}
+
+	case *Sum:
+		return w.isParameterizedList(t.types)
+
+	case *Signature:
+		// t.tparams may not be nil if we are looking at a signature
+		// of a generic function type (or an interface method) that is
+		// part of the type we're testing. We don't care about these type
+		// parameters.
+		// Similarly, the receiver of a method may declare (rather then
+		// use) type parameters, we don't care about those either.
+		// Thus, we only need to look at the input and result parameters.
+		return w.isParameterized(t.params) || w.isParameterized(t.results)
+
+	case *Interface:
+		if t.allMethods != nil {
+			// interface is complete - quick test
+			for _, m := range t.allMethods {
+				if w.isParameterized(m.typ) {
+					return true
+				}
+			}
+			return w.isParameterizedList(unpack(t.allTypes))
+		}
+
+		return t.iterate(func(t *Interface) bool {
+			for _, m := range t.methods {
+				if w.isParameterized(m.typ) {
+					return true
+				}
+			}
+			return w.isParameterizedList(unpack(t.types))
+		}, nil)
+
+	case *Map:
+		return w.isParameterized(t.key) || w.isParameterized(t.elem)
+
+	case *Chan:
+		return w.isParameterized(t.elem)
+
+	case *Named:
+		return w.isParameterizedList(t.targs)
+
+	case *TypeParam:
+		// t must be one of w.tparams
+		return t.index < len(w.tparams) && w.tparams[t.index].typ == t
+
+	case *instance:
+		return w.isParameterizedList(t.targs)
+
+	default:
+		unreachable()
+	}
+
+	return false
+}
+
+func (w *tpWalker) isParameterizedList(list []Type) bool {
+	for _, t := range list {
+		if w.isParameterized(t) {
+			return true
+		}
+	}
+	return false
+}
+
+// inferB returns the list of actual type arguments inferred from the type parameters'
+// bounds and an initial set of type arguments. If type inference is impossible because
+// unification fails, an error is reported if report is set to true, the resulting types
+// list is nil, and index is 0.
+// Otherwise, types is the list of inferred type arguments, and index is the index of the
+// first type argument in that list that couldn't be inferred (and thus is nil). If all
+// type arguments were inferred successfully, index is < 0. The number of type arguments
+// provided may be less than the number of type parameters, but there must be at least one.
+func (check *Checker) inferB(tparams []*TypeName, targs []Type, report bool) (types []Type, index int) {
+	assert(len(tparams) >= len(targs) && len(targs) > 0)
+
+	// Setup bidirectional unification between those structural bounds
+	// and the corresponding type arguments (which may be nil!).
+	u := newUnifier(check, false)
+	u.x.init(tparams)
+	u.y = u.x // type parameters between LHS and RHS of unification are identical
+
+	// Set the type arguments which we know already.
+	for i, targ := range targs {
+		if targ != nil {
+			u.x.set(i, targ)
+		}
+	}
+
+	// Unify type parameters with their structural constraints, if any.
+	for _, tpar := range tparams {
+		typ := tpar.typ.(*TypeParam)
+		sbound := check.structuralType(typ.bound)
+		if sbound != nil {
+			if !u.unify(typ, sbound) {
+				if report {
+					check.errorf(tpar, "%s does not match %s", tpar, sbound)
+				}
+				return nil, 0
+			}
+		}
+	}
+
+	// u.x.types() now contains the incoming type arguments plus any additional type
+	// arguments for which there were structural constraints. The newly inferred non-
+	// nil entries may still contain references to other type parameters. For instance,
+	// for [A any, B interface{type []C}, C interface{type *A}], if A == int
+	// was given, unification produced the type list [int, []C, *A]. We eliminate the
+	// remaining type parameters by substituting the type parameters in this type list
+	// until nothing changes anymore.
+	types, _ = u.x.types()
+	if debug {
+		for i, targ := range targs {
+			assert(targ == nil || types[i] == targ)
+		}
+	}
+
+	// dirty tracks the indices of all types that may still contain type parameters.
+	// We know that nil type entries and entries corresponding to provided (non-nil)
+	// type arguments are clean, so exclude them from the start.
+	var dirty []int
+	for i, typ := range types {
+		if typ != nil && (i >= len(targs) || targs[i] == nil) {
+			dirty = append(dirty, i)
+		}
+	}
+
+	for len(dirty) > 0 {
+		// TODO(gri) Instead of creating a new substMap for each iteration,
+		// provide an update operation for substMaps and only change when
+		// needed. Optimization.
+		smap := makeSubstMap(tparams, types)
+		n := 0
+		for _, index := range dirty {
+			t0 := types[index]
+			if t1 := check.subst(nopos, t0, smap); t1 != t0 {
+				types[index] = t1
+				dirty[n] = index
+				n++
+			}
+		}
+		dirty = dirty[:n]
+	}
+
+	// Once nothing changes anymore, we may still have type parameters left;
+	// e.g., a structural constraint *P may match a type parameter Q but we
+	// don't have any type arguments to fill in for *P or Q (issue #45548).
+	// Don't let such inferences escape, instead nil them out.
+	for i, typ := range types {
+		if typ != nil && isParameterized(tparams, typ) {
+			types[i] = nil
+		}
+	}
+
+	// update index
+	index = -1
+	for i, typ := range types {
+		if typ == nil {
+			index = i
+			break
+		}
+	}
+
+	return
+}
+
+// structuralType returns the structural type of a constraint, if any.
+func (check *Checker) structuralType(constraint Type) Type {
+	if iface, _ := under(constraint).(*Interface); iface != nil {
+		check.completeInterface(nopos, iface)
+		types := unpack(iface.allTypes)
+		if len(types) == 1 {
+			return types[0]
+		}
+		return nil
+	}
+	return constraint
+}
diff --git a/src/cmd/compile/internal/types2/initorder.go b/src/cmd/compile/internal/types2/initorder.go
new file mode 100644
index 0000000..4081627
--- /dev/null
+++ b/src/cmd/compile/internal/types2/initorder.go
@@ -0,0 +1,303 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+import (
+	"container/heap"
+	"fmt"
+)
+
+// initOrder computes the Info.InitOrder for package variables.
+func (check *Checker) initOrder() {
+	// An InitOrder may already have been computed if a package is
+	// built from several calls to (*Checker).Files. Clear it.
+	check.Info.InitOrder = check.Info.InitOrder[:0]
+
+	// Compute the object dependency graph and initialize
+	// a priority queue with the list of graph nodes.
+	pq := nodeQueue(dependencyGraph(check.objMap))
+	heap.Init(&pq)
+
+	const debug = false
+	if debug {
+		fmt.Printf("Computing initialization order for %s\n\n", check.pkg)
+		fmt.Println("Object dependency graph:")
+		for obj, d := range check.objMap {
+			// only print objects that may appear in the dependency graph
+			if obj, _ := obj.(dependency); obj != nil {
+				if len(d.deps) > 0 {
+					fmt.Printf("\t%s depends on\n", obj.Name())
+					for dep := range d.deps {
+						fmt.Printf("\t\t%s\n", dep.Name())
+					}
+				} else {
+					fmt.Printf("\t%s has no dependencies\n", obj.Name())
+				}
+			}
+		}
+		fmt.Println()
+
+		fmt.Println("Transposed object dependency graph (functions eliminated):")
+		for _, n := range pq {
+			fmt.Printf("\t%s depends on %d nodes\n", n.obj.Name(), n.ndeps)
+			for p := range n.pred {
+				fmt.Printf("\t\t%s is dependent\n", p.obj.Name())
+			}
+		}
+		fmt.Println()
+
+		fmt.Println("Processing nodes:")
+	}
+
+	// Determine initialization order by removing the highest priority node
+	// (the one with the fewest dependencies) and its edges from the graph,
+	// repeatedly, until there are no nodes left.
+	// In a valid Go program, those nodes always have zero dependencies (after
+	// removing all incoming dependencies), otherwise there are initialization
+	// cycles.
+	emitted := make(map[*declInfo]bool)
+	for len(pq) > 0 {
+		// get the next node
+		n := heap.Pop(&pq).(*graphNode)
+
+		if debug {
+			fmt.Printf("\t%s (src pos %d) depends on %d nodes now\n",
+				n.obj.Name(), n.obj.order(), n.ndeps)
+		}
+
+		// if n still depends on other nodes, we have a cycle
+		if n.ndeps > 0 {
+			cycle := findPath(check.objMap, n.obj, n.obj, make(map[Object]bool))
+			// If n.obj is not part of the cycle (e.g., n.obj->b->c->d->c),
+			// cycle will be nil. Don't report anything in that case since
+			// the cycle is reported when the algorithm gets to an object
+			// in the cycle.
+			// Furthermore, once an object in the cycle is encountered,
+			// the cycle will be broken (dependency count will be reduced
+			// below), and so the remaining nodes in the cycle don't trigger
+			// another error (unless they are part of multiple cycles).
+			if cycle != nil {
+				check.reportCycle(cycle)
+			}
+			// Ok to continue, but the variable initialization order
+			// will be incorrect at this point since it assumes no
+			// cycle errors.
+		}
+
+		// reduce dependency count of all dependent nodes
+		// and update priority queue
+		for p := range n.pred {
+			p.ndeps--
+			heap.Fix(&pq, p.index)
+		}
+
+		// record the init order for variables with initializers only
+		v, _ := n.obj.(*Var)
+		info := check.objMap[v]
+		if v == nil || !info.hasInitializer() {
+			continue
+		}
+
+		// n:1 variable declarations such as: a, b = f()
+		// introduce a node for each lhs variable (here: a, b);
+		// but they all have the same initializer - emit only
+		// one, for the first variable seen
+		if emitted[info] {
+			continue // initializer already emitted, if any
+		}
+		emitted[info] = true
+
+		infoLhs := info.lhs // possibly nil (see declInfo.lhs field comment)
+		if infoLhs == nil {
+			infoLhs = []*Var{v}
+		}
+		init := &Initializer{infoLhs, info.init}
+		check.Info.InitOrder = append(check.Info.InitOrder, init)
+	}
+
+	if debug {
+		fmt.Println()
+		fmt.Println("Initialization order:")
+		for _, init := range check.Info.InitOrder {
+			fmt.Printf("\t%s\n", init)
+		}
+		fmt.Println()
+	}
+}
+
+// findPath returns the (reversed) list of objects []Object{to, ... from}
+// such that there is a path of object dependencies from 'from' to 'to'.
+// If there is no such path, the result is nil.
+func findPath(objMap map[Object]*declInfo, from, to Object, seen map[Object]bool) []Object {
+	if seen[from] {
+		return nil
+	}
+	seen[from] = true
+
+	for d := range objMap[from].deps {
+		if d == to {
+			return []Object{d}
+		}
+		if P := findPath(objMap, d, to, seen); P != nil {
+			return append(P, d)
+		}
+	}
+
+	return nil
+}
+
+// reportCycle reports an error for the given cycle.
+func (check *Checker) reportCycle(cycle []Object) {
+	obj := cycle[0]
+	var err error_
+	if check.conf.CompilerErrorMessages {
+		err.errorf(obj, "initialization loop for %s", obj.Name())
+	} else {
+		err.errorf(obj, "initialization cycle for %s", obj.Name())
+	}
+	// subtle loop: print cycle[i] for i = 0, n-1, n-2, ... 1 for len(cycle) = n
+	for i := len(cycle) - 1; i >= 0; i-- {
+		err.errorf(obj, "%s refers to", obj.Name())
+		obj = cycle[i]
+	}
+	// print cycle[0] again to close the cycle
+	err.errorf(obj, "%s", obj.Name())
+	check.report(&err)
+}
+
+// ----------------------------------------------------------------------------
+// Object dependency graph
+
+// A dependency is an object that may be a dependency in an initialization
+// expression. Only constants, variables, and functions can be dependencies.
+// Constants are here because constant expression cycles are reported during
+// initialization order computation.
+type dependency interface {
+	Object
+	isDependency()
+}
+
+// A graphNode represents a node in the object dependency graph.
+// Each node p in n.pred represents an edge p->n, and each node
+// s in n.succ represents an edge n->s; with a->b indicating that
+// a depends on b.
+type graphNode struct {
+	obj        dependency // object represented by this node
+	pred, succ nodeSet    // consumers and dependencies of this node (lazily initialized)
+	index      int        // node index in graph slice/priority queue
+	ndeps      int        // number of outstanding dependencies before this object can be initialized
+}
+
+type nodeSet map[*graphNode]bool
+
+func (s *nodeSet) add(p *graphNode) {
+	if *s == nil {
+		*s = make(nodeSet)
+	}
+	(*s)[p] = true
+}
+
+// dependencyGraph computes the object dependency graph from the given objMap,
+// with any function nodes removed. The resulting graph contains only constants
+// and variables.
+func dependencyGraph(objMap map[Object]*declInfo) []*graphNode {
+	// M is the dependency (Object) -> graphNode mapping
+	M := make(map[dependency]*graphNode)
+	for obj := range objMap {
+		// only consider nodes that may be an initialization dependency
+		if obj, _ := obj.(dependency); obj != nil {
+			M[obj] = &graphNode{obj: obj}
+		}
+	}
+
+	// compute edges for graph M
+	// (We need to include all nodes, even isolated ones, because they still need
+	// to be scheduled for initialization in correct order relative to other nodes.)
+	for obj, n := range M {
+		// for each dependency obj -> d (= deps[i]), create graph edges n->s and s->n
+		for d := range objMap[obj].deps {
+			// only consider nodes that may be an initialization dependency
+			if d, _ := d.(dependency); d != nil {
+				d := M[d]
+				n.succ.add(d)
+				d.pred.add(n)
+			}
+		}
+	}
+
+	// remove function nodes and collect remaining graph nodes in G
+	// (Mutually recursive functions may introduce cycles among themselves
+	// which are permitted. Yet such cycles may incorrectly inflate the dependency
+	// count for variables which in turn may not get scheduled for initialization
+	// in correct order.)
+	var G []*graphNode
+	for obj, n := range M {
+		if _, ok := obj.(*Func); ok {
+			// connect each predecessor p of n with each successor s
+			// and drop the function node (don't collect it in G)
+			for p := range n.pred {
+				// ignore self-cycles
+				if p != n {
+					// Each successor s of n becomes a successor of p, and
+					// each predecessor p of n becomes a predecessor of s.
+					for s := range n.succ {
+						// ignore self-cycles
+						if s != n {
+							p.succ.add(s)
+							s.pred.add(p)
+							delete(s.pred, n) // remove edge to n
+						}
+					}
+					delete(p.succ, n) // remove edge to n
+				}
+			}
+		} else {
+			// collect non-function nodes
+			G = append(G, n)
+		}
+	}
+
+	// fill in index and ndeps fields
+	for i, n := range G {
+		n.index = i
+		n.ndeps = len(n.succ)
+	}
+
+	return G
+}
+
+// ----------------------------------------------------------------------------
+// Priority queue
+
+// nodeQueue implements the container/heap interface;
+// a nodeQueue may be used as a priority queue.
+type nodeQueue []*graphNode
+
+func (a nodeQueue) Len() int { return len(a) }
+
+func (a nodeQueue) Swap(i, j int) {
+	x, y := a[i], a[j]
+	a[i], a[j] = y, x
+	x.index, y.index = j, i
+}
+
+func (a nodeQueue) Less(i, j int) bool {
+	x, y := a[i], a[j]
+	// nodes are prioritized by number of incoming dependencies (1st key)
+	// and source order (2nd key)
+	return x.ndeps < y.ndeps || x.ndeps == y.ndeps && x.obj.order() < y.obj.order()
+}
+
+func (a *nodeQueue) Push(x interface{}) {
+	panic("unreachable")
+}
+
+func (a *nodeQueue) Pop() interface{} {
+	n := len(*a)
+	x := (*a)[n-1]
+	x.index = -1 // for safety
+	*a = (*a)[:n-1]
+	return x
+}
diff --git a/src/cmd/compile/internal/types2/instantiate.go b/src/cmd/compile/internal/types2/instantiate.go
new file mode 100644
index 0000000..0df52e8
--- /dev/null
+++ b/src/cmd/compile/internal/types2/instantiate.go
@@ -0,0 +1,63 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"fmt"
+)
+
+// Instantiate instantiates the type typ with the given type arguments.
+// typ must be a *Named or a *Signature type, it must be generic, and
+// its number of type parameters must match the number of provided type
+// arguments. The result is a new, instantiated (not generic) type of
+// the same kind (either a *Named or a *Signature). The type arguments
+// are not checked against the constraints of the type parameters.
+// Any methods attached to a *Named are simply copied; they are not
+// instantiated.
+func Instantiate(pos syntax.Pos, typ Type, targs []Type) (res Type) {
+	// TODO(gri) This code is basically identical to the prolog
+	//           in Checker.instantiate. Factor.
+	var tparams []*TypeName
+	switch t := typ.(type) {
+	case *Named:
+		tparams = t.tparams
+	case *Signature:
+		tparams = t.tparams
+		defer func() {
+			// If we had an unexpected failure somewhere don't panic below when
+			// asserting res.(*Signature). Check for *Signature in case Typ[Invalid]
+			// is returned.
+			if _, ok := res.(*Signature); !ok {
+				return
+			}
+			// If the signature doesn't use its type parameters, subst
+			// will not make a copy. In that case, make a copy now (so
+			// we can set tparams to nil w/o causing side-effects).
+			if t == res {
+				copy := *t
+				res = &copy
+			}
+			// After instantiating a generic signature, it is not generic
+			// anymore; we need to set tparams to nil.
+			res.(*Signature).tparams = nil
+		}()
+
+	default:
+		panic(fmt.Sprintf("%v: cannot instantiate %v", pos, typ))
+	}
+
+	// the number of supplied types must match the number of type parameters
+	if len(targs) != len(tparams) {
+		panic(fmt.Sprintf("%v: got %d arguments but %d type parameters", pos, len(targs), len(tparams)))
+	}
+
+	if len(tparams) == 0 {
+		return typ // nothing to do (minor optimization)
+	}
+
+	smap := makeSubstMap(tparams, targs)
+	return (*Checker)(nil).subst(pos, typ, smap)
+}
diff --git a/src/cmd/compile/internal/types2/issues_test.go b/src/cmd/compile/internal/types2/issues_test.go
new file mode 100644
index 0000000..e716a48
--- /dev/null
+++ b/src/cmd/compile/internal/types2/issues_test.go
@@ -0,0 +1,612 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements tests for various issues.
+
+package types2_test
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"internal/testenv"
+	"sort"
+	"strings"
+	"testing"
+
+	. "cmd/compile/internal/types2"
+)
+
+func mustParse(t *testing.T, src string) *syntax.File {
+	f, err := parseSrc("", src)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return f
+}
+func TestIssue5770(t *testing.T) {
+	f := mustParse(t, `package p; type S struct{T}`)
+	var conf Config
+	_, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, nil) // do not crash
+	want := "undeclared name: T"
+	if err == nil || !strings.Contains(err.Error(), want) {
+		t.Errorf("got: %v; want: %s", err, want)
+	}
+}
+
+func TestIssue5849(t *testing.T) {
+	src := `
+package p
+var (
+	s uint
+	_ = uint8(8)
+	_ = uint16(16) << s
+	_ = uint32(32 << s)
+	_ = uint64(64 << s + s)
+	_ = (interface{})("foo")
+	_ = (interface{})(nil)
+)`
+	f := mustParse(t, src)
+
+	var conf Config
+	types := make(map[syntax.Expr]TypeAndValue)
+	_, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, &Info{Types: types})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	for x, tv := range types {
+		var want Type
+		switch x := x.(type) {
+		case *syntax.BasicLit:
+			switch x.Value {
+			case `8`:
+				want = Typ[Uint8]
+			case `16`:
+				want = Typ[Uint16]
+			case `32`:
+				want = Typ[Uint32]
+			case `64`:
+				want = Typ[Uint] // because of "+ s", s is of type uint
+			case `"foo"`:
+				want = Typ[String]
+			}
+		case *syntax.Name:
+			if x.Value == "nil" {
+				want = NewInterfaceType(nil, nil) // interface{} (for now, go/types types this as "untyped nil")
+			}
+		}
+		if want != nil && !Identical(tv.Type, want) {
+			t.Errorf("got %s; want %s", tv.Type, want)
+		}
+	}
+}
+
+func TestIssue6413(t *testing.T) {
+	src := `
+package p
+func f() int {
+	defer f()
+	go f()
+	return 0
+}
+`
+	f := mustParse(t, src)
+
+	var conf Config
+	types := make(map[syntax.Expr]TypeAndValue)
+	_, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, &Info{Types: types})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := Typ[Int]
+	n := 0
+	for x, tv := range types {
+		if _, ok := x.(*syntax.CallExpr); ok {
+			if tv.Type != want {
+				t.Errorf("%s: got %s; want %s", x.Pos(), tv.Type, want)
+			}
+			n++
+		}
+	}
+
+	if n != 2 {
+		t.Errorf("got %d CallExprs; want 2", n)
+	}
+}
+
+func TestIssue7245(t *testing.T) {
+	src := `
+package p
+func (T) m() (res bool) { return }
+type T struct{} // receiver type after method declaration
+`
+	f := mustParse(t, src)
+
+	var conf Config
+	defs := make(map[*syntax.Name]Object)
+	_, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, &Info{Defs: defs})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	m := f.DeclList[0].(*syntax.FuncDecl)
+	res1 := defs[m.Name].(*Func).Type().(*Signature).Results().At(0)
+	res2 := defs[m.Type.ResultList[0].Name].(*Var)
+
+	if res1 != res2 {
+		t.Errorf("got %s (%p) != %s (%p)", res1, res2, res1, res2)
+	}
+}
+
+// This tests that uses of existing vars on the LHS of an assignment
+// are Uses, not Defs; and also that the (illegal) use of a non-var on
+// the LHS of an assignment is a Use nonetheless.
+func TestIssue7827(t *testing.T) {
+	const src = `
+package p
+func _() {
+	const w = 1        // defs w
+        x, y := 2, 3       // defs x, y
+        w, x, z := 4, 5, 6 // uses w, x, defs z; error: cannot assign to w
+        _, _, _ = x, y, z  // uses x, y, z
+}
+`
+	f := mustParse(t, src)
+
+	const want = `L3 defs func p._()
+L4 defs const w untyped int
+L5 defs var x int
+L5 defs var y int
+L6 defs var z int
+L6 uses const w untyped int
+L6 uses var x int
+L7 uses var x int
+L7 uses var y int
+L7 uses var z int`
+
+	// don't abort at the first error
+	conf := Config{Error: func(err error) { t.Log(err) }}
+	defs := make(map[*syntax.Name]Object)
+	uses := make(map[*syntax.Name]Object)
+	_, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, &Info{Defs: defs, Uses: uses})
+	if s := fmt.Sprint(err); !strings.HasSuffix(s, "cannot assign to w") {
+		t.Errorf("Check: unexpected error: %s", s)
+	}
+
+	var facts []string
+	for id, obj := range defs {
+		if obj != nil {
+			fact := fmt.Sprintf("L%d defs %s", id.Pos().Line(), obj)
+			facts = append(facts, fact)
+		}
+	}
+	for id, obj := range uses {
+		fact := fmt.Sprintf("L%d uses %s", id.Pos().Line(), obj)
+		facts = append(facts, fact)
+	}
+	sort.Strings(facts)
+
+	got := strings.Join(facts, "\n")
+	if got != want {
+		t.Errorf("Unexpected defs/uses\ngot:\n%s\nwant:\n%s", got, want)
+	}
+}
+
+// This tests that the package associated with the types2.Object.Pkg method
+// is the type's package independent of the order in which the imports are
+// listed in the sources src1, src2 below.
+// The actual issue is in go/internal/gcimporter which has a corresponding
+// test; we leave this test here to verify correct behavior at the go/types
+// level.
+func TestIssue13898(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	const src0 = `
+package main
+
+import "go/types"
+
+func main() {
+	var info types.Info
+	for _, obj := range info.Uses {
+		_ = obj.Pkg()
+	}
+}
+`
+	// like src0, but also imports go/importer
+	const src1 = `
+package main
+
+import (
+	"go/types"
+	_ "go/importer"
+)
+
+func main() {
+	var info types.Info
+	for _, obj := range info.Uses {
+		_ = obj.Pkg()
+	}
+}
+`
+	// like src1 but with different import order
+	// (used to fail with this issue)
+	const src2 = `
+package main
+
+import (
+	_ "go/importer"
+	"go/types"
+)
+
+func main() {
+	var info types.Info
+	for _, obj := range info.Uses {
+		_ = obj.Pkg()
+	}
+}
+`
+	f := func(test, src string) {
+		f := mustParse(t, src)
+		conf := Config{Importer: defaultImporter()}
+		info := Info{Uses: make(map[*syntax.Name]Object)}
+		_, err := conf.Check("main", []*syntax.File{f}, &info)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		var pkg *Package
+		count := 0
+		for id, obj := range info.Uses {
+			if id.Value == "Pkg" {
+				pkg = obj.Pkg()
+				count++
+			}
+		}
+		if count != 1 {
+			t.Fatalf("%s: got %d entries named Pkg; want 1", test, count)
+		}
+		if pkg.Name() != "types" {
+			t.Fatalf("%s: got %v; want package types2", test, pkg)
+		}
+	}
+
+	f("src0", src0)
+	f("src1", src1)
+	f("src2", src2)
+}
+
+func TestIssue22525(t *testing.T) {
+	f := mustParse(t, `package p; func f() { var a, b, c, d, e int }`)
+
+	got := "\n"
+	conf := Config{Error: func(err error) { got += err.Error() + "\n" }}
+	conf.Check(f.PkgName.Value, []*syntax.File{f}, nil) // do not crash
+	want := `
+:1:27: a declared but not used
+:1:30: b declared but not used
+:1:33: c declared but not used
+:1:36: d declared but not used
+:1:39: e declared but not used
+`
+	if got != want {
+		t.Errorf("got: %swant: %s", got, want)
+	}
+}
+
+func TestIssue25627(t *testing.T) {
+	const prefix = `package p; import "unsafe"; type P *struct{}; type I interface{}; type T `
+	// The src strings (without prefix) are constructed such that the number of semicolons
+	// plus one corresponds to the number of fields expected in the respective struct.
+	for _, src := range []string{
+		`struct { x Missing }`,
+		`struct { Missing }`,
+		`struct { *Missing }`,
+		`struct { unsafe.Pointer }`,
+		`struct { P }`,
+		`struct { *I }`,
+		`struct { a int; b Missing; *Missing }`,
+	} {
+		f := mustParse(t, prefix+src)
+
+		conf := Config{Importer: defaultImporter(), Error: func(err error) {}}
+		info := &Info{Types: make(map[syntax.Expr]TypeAndValue)}
+		_, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, info)
+		if err != nil {
+			if _, ok := err.(Error); !ok {
+				t.Fatal(err)
+			}
+		}
+
+		syntax.Walk(f, func(n syntax.Node) bool {
+			if decl, _ := n.(*syntax.TypeDecl); decl != nil {
+				if tv, ok := info.Types[decl.Type]; ok && decl.Name.Value == "T" {
+					want := strings.Count(src, ";") + 1
+					if got := tv.Type.(*Struct).NumFields(); got != want {
+						t.Errorf("%s: got %d fields; want %d", src, got, want)
+					}
+				}
+			}
+			return false
+		})
+	}
+}
+
+func TestIssue28005(t *testing.T) {
+	// method names must match defining interface name for this test
+	// (see last comment in this function)
+	sources := [...]string{
+		"package p; type A interface{ A() }",
+		"package p; type B interface{ B() }",
+		"package p; type X interface{ A; B }",
+	}
+
+	// compute original file ASTs
+	var orig [len(sources)]*syntax.File
+	for i, src := range sources {
+		orig[i] = mustParse(t, src)
+	}
+
+	// run the test for all order permutations of the incoming files
+	for _, perm := range [][len(sources)]int{
+		{0, 1, 2},
+		{0, 2, 1},
+		{1, 0, 2},
+		{1, 2, 0},
+		{2, 0, 1},
+		{2, 1, 0},
+	} {
+		// create file order permutation
+		files := make([]*syntax.File, len(sources))
+		for i := range perm {
+			files[i] = orig[perm[i]]
+		}
+
+		// type-check package with given file order permutation
+		var conf Config
+		info := &Info{Defs: make(map[*syntax.Name]Object)}
+		_, err := conf.Check("", files, info)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		// look for interface object X
+		var obj Object
+		for name, def := range info.Defs {
+			if name.Value == "X" {
+				obj = def
+				break
+			}
+		}
+		if obj == nil {
+			t.Fatal("object X not found")
+		}
+		iface := obj.Type().Underlying().(*Interface) // object X must be an interface
+
+		// Each iface method m is embedded; and m's receiver base type name
+		// must match the method's name per the choice in the source file.
+		for i := 0; i < iface.NumMethods(); i++ {
+			m := iface.Method(i)
+			recvName := m.Type().(*Signature).Recv().Type().(*Named).Obj().Name()
+			if recvName != m.Name() {
+				t.Errorf("perm %v: got recv %s; want %s", perm, recvName, m.Name())
+			}
+		}
+	}
+}
+
+func TestIssue28282(t *testing.T) {
+	// create type interface { error }
+	et := Universe.Lookup("error").Type()
+	it := NewInterfaceType(nil, []Type{et})
+	it.Complete()
+	// verify that after completing the interface, the embedded method remains unchanged
+	want := et.Underlying().(*Interface).Method(0)
+	got := it.Method(0)
+	if got != want {
+		t.Fatalf("%s.Method(0): got %q (%p); want %q (%p)", it, got, got, want, want)
+	}
+	// verify that lookup finds the same method in both interfaces (redundant check)
+	obj, _, _ := LookupFieldOrMethod(et, false, nil, "Error")
+	if obj != want {
+		t.Fatalf("%s.Lookup: got %q (%p); want %q (%p)", et, obj, obj, want, want)
+	}
+	obj, _, _ = LookupFieldOrMethod(it, false, nil, "Error")
+	if obj != want {
+		t.Fatalf("%s.Lookup: got %q (%p); want %q (%p)", it, obj, obj, want, want)
+	}
+}
+
+func TestIssue29029(t *testing.T) {
+	f1 := mustParse(t, `package p; type A interface { M() }`)
+	f2 := mustParse(t, `package p; var B interface { A }`)
+
+	// printInfo prints the *Func definitions recorded in info, one *Func per line.
+	printInfo := func(info *Info) string {
+		var buf bytes.Buffer
+		for _, obj := range info.Defs {
+			if fn, ok := obj.(*Func); ok {
+				fmt.Fprintln(&buf, fn)
+			}
+		}
+		return buf.String()
+	}
+
+	// The *Func (method) definitions for package p must be the same
+	// independent on whether f1 and f2 are type-checked together, or
+	// incrementally.
+
+	// type-check together
+	var conf Config
+	info := &Info{Defs: make(map[*syntax.Name]Object)}
+	check := NewChecker(&conf, NewPackage("", "p"), info)
+	if err := check.Files([]*syntax.File{f1, f2}); err != nil {
+		t.Fatal(err)
+	}
+	want := printInfo(info)
+
+	// type-check incrementally
+	info = &Info{Defs: make(map[*syntax.Name]Object)}
+	check = NewChecker(&conf, NewPackage("", "p"), info)
+	if err := check.Files([]*syntax.File{f1}); err != nil {
+		t.Fatal(err)
+	}
+	if err := check.Files([]*syntax.File{f2}); err != nil {
+		t.Fatal(err)
+	}
+	got := printInfo(info)
+
+	if got != want {
+		t.Errorf("\ngot : %swant: %s", got, want)
+	}
+}
+
+func TestIssue34151(t *testing.T) {
+	const asrc = `package a; type I interface{ M() }; type T struct { F interface { I } }`
+	const bsrc = `package b; import "a"; type T struct { F interface { a.I } }; var _ = a.T(T{})`
+
+	a, err := pkgFor("a", asrc, nil)
+	if err != nil {
+		t.Fatalf("package %s failed to typecheck: %v", a.Name(), err)
+	}
+
+	bast := mustParse(t, bsrc)
+	conf := Config{Importer: importHelper{pkg: a}}
+	b, err := conf.Check(bast.PkgName.Value, []*syntax.File{bast}, nil)
+	if err != nil {
+		t.Errorf("package %s failed to typecheck: %v", b.Name(), err)
+	}
+}
+
+type importHelper struct {
+	pkg      *Package
+	fallback Importer
+}
+
+func (h importHelper) Import(path string) (*Package, error) {
+	if path == h.pkg.Path() {
+		return h.pkg, nil
+	}
+	if h.fallback == nil {
+		return nil, fmt.Errorf("got package path %q; want %q", path, h.pkg.Path())
+	}
+	return h.fallback.Import(path)
+}
+
+// TestIssue34921 verifies that we don't update an imported type's underlying
+// type when resolving an underlying type. Specifically, when determining the
+// underlying type of b.T (which is the underlying type of a.T, which is int)
+// we must not set the underlying type of a.T again since that would lead to
+// a race condition if package b is imported elsewhere, in a package that is
+// concurrently type-checked.
+func TestIssue34921(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			t.Error(r)
+		}
+	}()
+
+	var sources = []string{
+		`package a; type T int`,
+		`package b; import "a"; type T a.T`,
+	}
+
+	var pkg *Package
+	for _, src := range sources {
+		f := mustParse(t, src)
+		conf := Config{Importer: importHelper{pkg: pkg}}
+		res, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, nil)
+		if err != nil {
+			t.Errorf("%q failed to typecheck: %v", src, err)
+		}
+		pkg = res // res is imported by the next package in this test
+	}
+}
+
+func TestIssue43088(t *testing.T) {
+	// type T1 struct {
+	//         _ T2
+	// }
+	//
+	// type T2 struct {
+	//         _ struct {
+	//                 _ T2
+	//         }
+	// }
+	n1 := NewTypeName(syntax.Pos{}, nil, "T1", nil)
+	T1 := NewNamed(n1, nil, nil)
+	n2 := NewTypeName(syntax.Pos{}, nil, "T2", nil)
+	T2 := NewNamed(n2, nil, nil)
+	s1 := NewStruct([]*Var{NewField(syntax.Pos{}, nil, "_", T2, false)}, nil)
+	T1.SetUnderlying(s1)
+	s2 := NewStruct([]*Var{NewField(syntax.Pos{}, nil, "_", T2, false)}, nil)
+	s3 := NewStruct([]*Var{NewField(syntax.Pos{}, nil, "_", s2, false)}, nil)
+	T2.SetUnderlying(s3)
+
+	// These calls must terminate (no endless recursion).
+	Comparable(T1)
+	Comparable(T2)
+}
+
+func TestIssue44515(t *testing.T) {
+	typ := Unsafe.Scope().Lookup("Pointer").Type()
+
+	got := TypeString(typ, nil)
+	want := "unsafe.Pointer"
+	if got != want {
+		t.Errorf("got %q; want %q", got, want)
+	}
+
+	qf := func(pkg *Package) string {
+		if pkg == Unsafe {
+			return "foo"
+		}
+		return ""
+	}
+	got = TypeString(typ, qf)
+	want = "foo.Pointer"
+	if got != want {
+		t.Errorf("got %q; want %q", got, want)
+	}
+}
+
+func TestIssue43124(t *testing.T) {
+	// All involved packages have the same name (template). Error messages should
+	// disambiguate between text/template and html/template by printing the full
+	// path.
+	const (
+		asrc = `package a; import "text/template"; func F(template.Template) {}; func G(int) {}`
+		bsrc = `package b; import ("a"; "html/template"); func _() { a.F(template.Template{}) }`
+		csrc = `package c; import ("a"; "html/template"); func _() { a.G(template.Template{}) }`
+	)
+
+	a, err := pkgFor("a", asrc, nil)
+	if err != nil {
+		t.Fatalf("package a failed to typecheck: %v", err)
+	}
+	conf := Config{Importer: importHelper{pkg: a, fallback: defaultImporter()}}
+
+	// Packages should be fully qualified when there is ambiguity within the
+	// error string itself.
+	bast := mustParse(t, bsrc)
+	_, err = conf.Check(bast.PkgName.Value, []*syntax.File{bast}, nil)
+	if err == nil {
+		t.Fatal("package b had no errors")
+	}
+	if !strings.Contains(err.Error(), "text/template") || !strings.Contains(err.Error(), "html/template") {
+		t.Errorf("type checking error for b does not disambiguate package template: %q", err)
+	}
+
+	// ...and also when there is any ambiguity in reachable packages.
+	cast := mustParse(t, csrc)
+	_, err = conf.Check(cast.PkgName.Value, []*syntax.File{cast}, nil)
+	if err == nil {
+		t.Fatal("package c had no errors")
+	}
+	if !strings.Contains(err.Error(), "html/template") {
+		t.Errorf("type checking error for c does not disambiguate package template: %q", err)
+	}
+}
diff --git a/src/cmd/compile/internal/types2/labels.go b/src/cmd/compile/internal/types2/labels.go
new file mode 100644
index 0000000..d320698
--- /dev/null
+++ b/src/cmd/compile/internal/types2/labels.go
@@ -0,0 +1,262 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+)
+
+// labels checks correct label use in body.
+func (check *Checker) labels(body *syntax.BlockStmt) {
+	// set of all labels in this body
+	all := NewScope(nil, body.Pos(), syntax.EndPos(body), "label")
+
+	fwdJumps := check.blockBranches(all, nil, nil, body.List)
+
+	// If there are any forward jumps left, no label was found for
+	// the corresponding goto statements. Either those labels were
+	// never defined, or they are inside blocks and not reachable
+	// for the respective gotos.
+	for _, jmp := range fwdJumps {
+		var msg string
+		name := jmp.Label.Value
+		if alt := all.Lookup(name); alt != nil {
+			msg = "goto %s jumps into block"
+			alt.(*Label).used = true // avoid another error
+		} else {
+			msg = "label %s not declared"
+		}
+		check.errorf(jmp.Label, msg, name)
+	}
+
+	// spec: "It is illegal to define a label that is never used."
+	for _, obj := range all.elems {
+		if lbl := obj.(*Label); !lbl.used {
+			check.softErrorf(lbl.pos, "label %s declared but not used", lbl.name)
+		}
+	}
+}
+
+// A block tracks label declarations in a block and its enclosing blocks.
+type block struct {
+	parent *block                         // enclosing block
+	lstmt  *syntax.LabeledStmt            // labeled statement to which this block belongs, or nil
+	labels map[string]*syntax.LabeledStmt // allocated lazily
+}
+
+// insert records a new label declaration for the current block.
+// The label must not have been declared before in any block.
+func (b *block) insert(s *syntax.LabeledStmt) {
+	name := s.Label.Value
+	if debug {
+		assert(b.gotoTarget(name) == nil)
+	}
+	labels := b.labels
+	if labels == nil {
+		labels = make(map[string]*syntax.LabeledStmt)
+		b.labels = labels
+	}
+	labels[name] = s
+}
+
+// gotoTarget returns the labeled statement in the current
+// or an enclosing block with the given label name, or nil.
+func (b *block) gotoTarget(name string) *syntax.LabeledStmt {
+	for s := b; s != nil; s = s.parent {
+		if t := s.labels[name]; t != nil {
+			return t
+		}
+	}
+	return nil
+}
+
+// enclosingTarget returns the innermost enclosing labeled
+// statement with the given label name, or nil.
+func (b *block) enclosingTarget(name string) *syntax.LabeledStmt {
+	for s := b; s != nil; s = s.parent {
+		if t := s.lstmt; t != nil && t.Label.Value == name {
+			return t
+		}
+	}
+	return nil
+}
+
+// blockBranches processes a block's statement list and returns the set of outgoing forward jumps.
+// all is the scope of all declared labels, parent the set of labels declared in the immediately
+// enclosing block, and lstmt is the labeled statement this block is associated with (or nil).
+func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *syntax.LabeledStmt, list []syntax.Stmt) []*syntax.BranchStmt {
+	b := &block{parent, lstmt, nil}
+
+	var (
+		varDeclPos         syntax.Pos
+		fwdJumps, badJumps []*syntax.BranchStmt
+	)
+
+	// All forward jumps jumping over a variable declaration are possibly
+	// invalid (they may still jump out of the block and be ok).
+	// recordVarDecl records them for the given position.
+	recordVarDecl := func(pos syntax.Pos) {
+		varDeclPos = pos
+		badJumps = append(badJumps[:0], fwdJumps...) // copy fwdJumps to badJumps
+	}
+
+	jumpsOverVarDecl := func(jmp *syntax.BranchStmt) bool {
+		if varDeclPos.IsKnown() {
+			for _, bad := range badJumps {
+				if jmp == bad {
+					return true
+				}
+			}
+		}
+		return false
+	}
+
+	var stmtBranches func(syntax.Stmt)
+	stmtBranches = func(s syntax.Stmt) {
+		switch s := s.(type) {
+		case *syntax.DeclStmt:
+			for _, d := range s.DeclList {
+				if d, _ := d.(*syntax.VarDecl); d != nil {
+					recordVarDecl(d.Pos())
+				}
+			}
+
+		case *syntax.LabeledStmt:
+			// declare non-blank label
+			if name := s.Label.Value; name != "_" {
+				lbl := NewLabel(s.Label.Pos(), check.pkg, name)
+				if alt := all.Insert(lbl); alt != nil {
+					var err error_
+					err.soft = true
+					err.errorf(lbl.pos, "label %s already declared", name)
+					err.recordAltDecl(alt)
+					check.report(&err)
+					// ok to continue
+				} else {
+					b.insert(s)
+					check.recordDef(s.Label, lbl)
+				}
+				// resolve matching forward jumps and remove them from fwdJumps
+				i := 0
+				for _, jmp := range fwdJumps {
+					if jmp.Label.Value == name {
+						// match
+						lbl.used = true
+						check.recordUse(jmp.Label, lbl)
+						if jumpsOverVarDecl(jmp) {
+							check.softErrorf(
+								jmp.Label,
+								"goto %s jumps over variable declaration at line %d",
+								name,
+								varDeclPos.Line(),
+							)
+							// ok to continue
+						}
+					} else {
+						// no match - record new forward jump
+						fwdJumps[i] = jmp
+						i++
+					}
+				}
+				fwdJumps = fwdJumps[:i]
+				lstmt = s
+			}
+			stmtBranches(s.Stmt)
+
+		case *syntax.BranchStmt:
+			if s.Label == nil {
+				return // checked in 1st pass (check.stmt)
+			}
+
+			// determine and validate target
+			name := s.Label.Value
+			switch s.Tok {
+			case syntax.Break:
+				// spec: "If there is a label, it must be that of an enclosing
+				// "for", "switch", or "select" statement, and that is the one
+				// whose execution terminates."
+				valid := false
+				if t := b.enclosingTarget(name); t != nil {
+					switch t.Stmt.(type) {
+					case *syntax.SwitchStmt, *syntax.SelectStmt, *syntax.ForStmt:
+						valid = true
+					}
+				}
+				if !valid {
+					check.errorf(s.Label, "invalid break label %s", name)
+					return
+				}
+
+			case syntax.Continue:
+				// spec: "If there is a label, it must be that of an enclosing
+				// "for" statement, and that is the one whose execution advances."
+				valid := false
+				if t := b.enclosingTarget(name); t != nil {
+					switch t.Stmt.(type) {
+					case *syntax.ForStmt:
+						valid = true
+					}
+				}
+				if !valid {
+					check.errorf(s.Label, "invalid continue label %s", name)
+					return
+				}
+
+			case syntax.Goto:
+				if b.gotoTarget(name) == nil {
+					// label may be declared later - add branch to forward jumps
+					fwdJumps = append(fwdJumps, s)
+					return
+				}
+
+			default:
+				check.errorf(s, invalidAST+"branch statement: %s %s", s.Tok, name)
+				return
+			}
+
+			// record label use
+			obj := all.Lookup(name)
+			obj.(*Label).used = true
+			check.recordUse(s.Label, obj)
+
+		case *syntax.AssignStmt:
+			if s.Op == syntax.Def {
+				recordVarDecl(s.Pos())
+			}
+
+		case *syntax.BlockStmt:
+			// Unresolved forward jumps inside the nested block
+			// become forward jumps in the current block.
+			fwdJumps = append(fwdJumps, check.blockBranches(all, b, lstmt, s.List)...)
+
+		case *syntax.IfStmt:
+			stmtBranches(s.Then)
+			if s.Else != nil {
+				stmtBranches(s.Else)
+			}
+
+		case *syntax.SwitchStmt:
+			b := &block{b, lstmt, nil}
+			for _, s := range s.Body {
+				fwdJumps = append(fwdJumps, check.blockBranches(all, b, nil, s.Body)...)
+			}
+
+		case *syntax.SelectStmt:
+			b := &block{b, lstmt, nil}
+			for _, s := range s.Body {
+				fwdJumps = append(fwdJumps, check.blockBranches(all, b, nil, s.Body)...)
+			}
+
+		case *syntax.ForStmt:
+			stmtBranches(s.Body)
+		}
+	}
+
+	for _, s := range list {
+		stmtBranches(s)
+	}
+
+	return fwdJumps
+}
diff --git a/src/cmd/compile/internal/types2/lookup.go b/src/cmd/compile/internal/types2/lookup.go
new file mode 100644
index 0000000..7829950
--- /dev/null
+++ b/src/cmd/compile/internal/types2/lookup.go
@@ -0,0 +1,511 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements various field and method lookup functions.
+
+package types2
+
+// LookupFieldOrMethod looks up a field or method with given package and name
+// in T and returns the corresponding *Var or *Func, an index sequence, and a
+// bool indicating if there were any pointer indirections on the path to the
+// field or method. If addressable is set, T is the type of an addressable
+// variable (only matters for method lookups).
+//
+// The last index entry is the field or method index in the (possibly embedded)
+// type where the entry was found, either:
+//
+//	1) the list of declared methods of a named type; or
+//	2) the list of all methods (method set) of an interface type; or
+//	3) the list of fields of a struct type.
+//
+// The earlier index entries are the indices of the embedded struct fields
+// traversed to get to the found entry, starting at depth 0.
+//
+// If no entry is found, a nil object is returned. In this case, the returned
+// index and indirect values have the following meaning:
+//
+//	- If index != nil, the index sequence points to an ambiguous entry
+//	(the same name appeared more than once at the same embedding level).
+//
+//	- If indirect is set, a method with a pointer receiver type was found
+//      but there was no pointer on the path from the actual receiver type to
+//	the method's formal receiver base type, nor was the receiver addressable.
+//
+func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
+	return (*Checker)(nil).lookupFieldOrMethod(T, addressable, pkg, name)
+}
+
+// Internal use of Checker.lookupFieldOrMethod: If the obj result is a method
+// associated with a concrete (non-interface) type, the method's signature
+// may not be fully set up. Call Checker.objDecl(obj, nil) before accessing
+// the method's type.
+// TODO(gri) Now that we provide the *Checker, we can probably remove this
+// caveat by calling Checker.objDecl from lookupFieldOrMethod. Investigate.
+
+// lookupFieldOrMethod is like the external version but completes interfaces
+// as necessary.
+func (check *Checker) lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
+	// Methods cannot be associated to a named pointer type
+	// (spec: "The type denoted by T is called the receiver base type;
+	// it must not be a pointer or interface type and it must be declared
+	// in the same package as the method.").
+	// Thus, if we have a named pointer type, proceed with the underlying
+	// pointer type but discard the result if it is a method since we would
+	// not have found it for T (see also issue 8590).
+	if t := asNamed(T); t != nil {
+		if p, _ := t.underlying.(*Pointer); p != nil {
+			obj, index, indirect = check.rawLookupFieldOrMethod(p, false, pkg, name)
+			if _, ok := obj.(*Func); ok {
+				return nil, nil, false
+			}
+			return
+		}
+	}
+
+	return check.rawLookupFieldOrMethod(T, addressable, pkg, name)
+}
+
+// TODO(gri) The named type consolidation and seen maps below must be
+//           indexed by unique keys for a given type. Verify that named
+//           types always have only one representation (even when imported
+//           indirectly via different packages.)
+
+// rawLookupFieldOrMethod should only be called by lookupFieldOrMethod and missingMethod.
+func (check *Checker) rawLookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
+	// WARNING: The code in this function is extremely subtle - do not modify casually!
+	//          This function and NewMethodSet should be kept in sync.
+
+	if name == "_" {
+		return // blank fields/methods are never found
+	}
+
+	typ, isPtr := deref(T)
+
+	// *typ where typ is an interface has no methods.
+	// Be cautious: typ may be nil (issue 39634, crash #3).
+	if typ == nil || isPtr && IsInterface(typ) {
+		return
+	}
+
+	// Start with typ as single entry at shallowest depth.
+	current := []embeddedType{{typ, nil, isPtr, false}}
+
+	// Named types that we have seen already, allocated lazily.
+	// Used to avoid endless searches in case of recursive types.
+	// Since only Named types can be used for recursive types, we
+	// only need to track those.
+	// (If we ever allow type aliases to construct recursive types,
+	// we must use type identity rather than pointer equality for
+	// the map key comparison, as we do in consolidateMultiples.)
+	var seen map[*Named]bool
+
+	// search current depth
+	for len(current) > 0 {
+		var next []embeddedType // embedded types found at current depth
+
+		// look for (pkg, name) in all types at current depth
+		var tpar *TypeParam // set if obj receiver is a type parameter
+		for _, e := range current {
+			typ := e.typ
+
+			// If we have a named type, we may have associated methods.
+			// Look for those first.
+			if named := asNamed(typ); named != nil {
+				if seen[named] {
+					// We have seen this type before, at a more shallow depth
+					// (note that multiples of this type at the current depth
+					// were consolidated before). The type at that depth shadows
+					// this same type at the current depth, so we can ignore
+					// this one.
+					continue
+				}
+				if seen == nil {
+					seen = make(map[*Named]bool)
+				}
+				seen[named] = true
+
+				// look for a matching attached method
+				if i, m := lookupMethod(named.methods, pkg, name); m != nil {
+					// potential match
+					// caution: method may not have a proper signature yet
+					index = concat(e.index, i)
+					if obj != nil || e.multiples {
+						return nil, index, false // collision
+					}
+					obj = m
+					indirect = e.indirect
+					continue // we can't have a matching field or interface method
+				}
+
+				// continue with underlying type, but only if it's not a type parameter
+				// TODO(gri) is this what we want to do for type parameters? (spec question)
+				typ = named.under()
+				if asTypeParam(typ) != nil {
+					continue
+				}
+			}
+
+			tpar = nil
+			switch t := typ.(type) {
+			case *Struct:
+				// look for a matching field and collect embedded types
+				for i, f := range t.fields {
+					if f.sameId(pkg, name) {
+						assert(f.typ != nil)
+						index = concat(e.index, i)
+						if obj != nil || e.multiples {
+							return nil, index, false // collision
+						}
+						obj = f
+						indirect = e.indirect
+						continue // we can't have a matching interface method
+					}
+					// Collect embedded struct fields for searching the next
+					// lower depth, but only if we have not seen a match yet
+					// (if we have a match it is either the desired field or
+					// we have a name collision on the same depth; in either
+					// case we don't need to look further).
+					// Embedded fields are always of the form T or *T where
+					// T is a type name. If e.typ appeared multiple times at
+					// this depth, f.typ appears multiple times at the next
+					// depth.
+					if obj == nil && f.embedded {
+						typ, isPtr := deref(f.typ)
+						// TODO(gri) optimization: ignore types that can't
+						// have fields or methods (only Named, Struct, and
+						// Interface types need to be considered).
+						next = append(next, embeddedType{typ, concat(e.index, i), e.indirect || isPtr, e.multiples})
+					}
+				}
+
+			case *Interface:
+				// look for a matching method
+				// TODO(gri) t.allMethods is sorted - use binary search
+				check.completeInterface(nopos, t)
+				if i, m := lookupMethod(t.allMethods, pkg, name); m != nil {
+					assert(m.typ != nil)
+					index = concat(e.index, i)
+					if obj != nil || e.multiples {
+						return nil, index, false // collision
+					}
+					obj = m
+					indirect = e.indirect
+				}
+
+			case *TypeParam:
+				if i, m := lookupMethod(t.Bound().allMethods, pkg, name); m != nil {
+					assert(m.typ != nil)
+					index = concat(e.index, i)
+					if obj != nil || e.multiples {
+						return nil, index, false // collision
+					}
+					tpar = t
+					obj = m
+					indirect = e.indirect
+				}
+				if obj == nil {
+					// At this point we're not (yet) looking into methods
+					// that any underlying type of the types in the type list
+					// might have.
+					// TODO(gri) Do we want to specify the language that way?
+				}
+			}
+		}
+
+		if obj != nil {
+			// found a potential match
+			// spec: "A method call x.m() is valid if the method set of (the type of) x
+			//        contains m and the argument list can be assigned to the parameter
+			//        list of m. If x is addressable and &x's method set contains m, x.m()
+			//        is shorthand for (&x).m()".
+			if f, _ := obj.(*Func); f != nil {
+				// determine if method has a pointer receiver
+				hasPtrRecv := tpar == nil && ptrRecv(f)
+				if hasPtrRecv && !indirect && !addressable {
+					return nil, nil, true // pointer/addressable receiver required
+				}
+			}
+			return
+		}
+
+		current = check.consolidateMultiples(next)
+	}
+
+	return nil, nil, false // not found
+}
+
+// embeddedType represents an embedded type
+type embeddedType struct {
+	typ       Type
+	index     []int // embedded field indices, starting with index at depth 0
+	indirect  bool  // if set, there was a pointer indirection on the path to this field
+	multiples bool  // if set, typ appears multiple times at this depth
+}
+
+// consolidateMultiples collects multiple list entries with the same type
+// into a single entry marked as containing multiples. The result is the
+// consolidated list.
+func (check *Checker) consolidateMultiples(list []embeddedType) []embeddedType {
+	if len(list) <= 1 {
+		return list // at most one entry - nothing to do
+	}
+
+	n := 0                     // number of entries w/ unique type
+	prev := make(map[Type]int) // index at which type was previously seen
+	for _, e := range list {
+		if i, found := check.lookupType(prev, e.typ); found {
+			list[i].multiples = true
+			// ignore this entry
+		} else {
+			prev[e.typ] = n
+			list[n] = e
+			n++
+		}
+	}
+	return list[:n]
+}
+
+func (check *Checker) lookupType(m map[Type]int, typ Type) (int, bool) {
+	// fast path: maybe the types are equal
+	if i, found := m[typ]; found {
+		return i, true
+	}
+
+	for t, i := range m {
+		if check.identical(t, typ) {
+			return i, true
+		}
+	}
+
+	return 0, false
+}
+
+// MissingMethod returns (nil, false) if V implements T, otherwise it
+// returns a missing method required by T and whether it is missing or
+// just has the wrong type.
+//
+// For non-interface types V, or if static is set, V implements T if all
+// methods of T are present in V. Otherwise (V is an interface and static
+// is not set), MissingMethod only checks that methods of T which are also
+// present in V have matching types (e.g., for a type assertion x.(T) where
+// x is of interface type V).
+//
+func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) {
+	m, typ := (*Checker)(nil).missingMethod(V, T, static)
+	return m, typ != nil
+}
+
+// missingMethod is like MissingMethod but accepts a *Checker as
+// receiver and an addressable flag.
+// The receiver may be nil if missingMethod is invoked through
+// an exported API call (such as MissingMethod), i.e., when all
+// methods have been type-checked.
+// If the type has the correctly named method, but with the wrong
+// signature, the existing method is returned as well.
+// To improve error messages, also report the wrong signature
+// when the method exists on *V instead of V.
+func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, wrongType *Func) {
+	check.completeInterface(nopos, T)
+
+	// fast path for common case
+	if T.Empty() {
+		return
+	}
+
+	if ityp := asInterface(V); ityp != nil {
+		check.completeInterface(nopos, ityp)
+		// TODO(gri) allMethods is sorted - can do this more efficiently
+		for _, m := range T.allMethods {
+			_, f := lookupMethod(ityp.allMethods, m.pkg, m.name)
+
+			if f == nil {
+				// if m is the magic method == we're ok (interfaces are comparable)
+				if m.name == "==" || !static {
+					continue
+				}
+				return m, f
+			}
+
+			// both methods must have the same number of type parameters
+			ftyp := f.typ.(*Signature)
+			mtyp := m.typ.(*Signature)
+			if len(ftyp.tparams) != len(mtyp.tparams) {
+				return m, f
+			}
+
+			// If the methods have type parameters we don't care whether they
+			// are the same or not, as long as they match up. Use unification
+			// to see if they can be made to match.
+			// TODO(gri) is this always correct? what about type bounds?
+			// (Alternative is to rename/subst type parameters and compare.)
+			u := newUnifier(check, true)
+			u.x.init(ftyp.tparams)
+			if !u.unify(ftyp, mtyp) {
+				return m, f
+			}
+		}
+
+		return
+	}
+
+	// A concrete type implements T if it implements all methods of T.
+	Vd, _ := deref(V)
+	Vn := asNamed(Vd)
+	for _, m := range T.allMethods {
+		// TODO(gri) should this be calling lookupFieldOrMethod instead (and why not)?
+		obj, _, _ := check.rawLookupFieldOrMethod(V, false, m.pkg, m.name)
+
+		// Check if *V implements this method of T.
+		if obj == nil {
+			ptr := NewPointer(V)
+			obj, _, _ = check.rawLookupFieldOrMethod(ptr, false, m.pkg, m.name)
+			if obj != nil {
+				return m, obj.(*Func)
+			}
+		}
+
+		// we must have a method (not a field of matching function type)
+		f, _ := obj.(*Func)
+		if f == nil {
+			// if m is the magic method == and V is comparable, we're ok
+			if m.name == "==" && Comparable(V) {
+				continue
+			}
+			return m, nil
+		}
+
+		// methods may not have a fully set up signature yet
+		if check != nil {
+			check.objDecl(f, nil)
+		}
+
+		// both methods must have the same number of type parameters
+		ftyp := f.typ.(*Signature)
+		mtyp := m.typ.(*Signature)
+		if len(ftyp.tparams) != len(mtyp.tparams) {
+			return m, f
+		}
+
+		// If V is a (instantiated) generic type, its methods are still
+		// parameterized using the original (declaration) receiver type
+		// parameters (subst simply copies the existing method list, it
+		// does not instantiate the methods).
+		// In order to compare the signatures, substitute the receiver
+		// type parameters of ftyp with V's instantiation type arguments.
+		// This lazily instantiates the signature of method f.
+		if Vn != nil && len(Vn.tparams) > 0 {
+			// Be careful: The number of type arguments may not match
+			// the number of receiver parameters. If so, an error was
+			// reported earlier but the length discrepancy is still
+			// here. Exit early in this case to prevent an assertion
+			// failure in makeSubstMap.
+			// TODO(gri) Can we avoid this check by fixing the lengths?
+			if len(ftyp.rparams) != len(Vn.targs) {
+				return
+			}
+			ftyp = check.subst(nopos, ftyp, makeSubstMap(ftyp.rparams, Vn.targs)).(*Signature)
+		}
+
+		// If the methods have type parameters we don't care whether they
+		// are the same or not, as long as they match up. Use unification
+		// to see if they can be made to match.
+		// TODO(gri) is this always correct? what about type bounds?
+		// (Alternative is to rename/subst type parameters and compare.)
+		u := newUnifier(check, true)
+		u.x.init(ftyp.tparams)
+		if !u.unify(ftyp, mtyp) {
+			return m, f
+		}
+	}
+
+	return
+}
+
+// assertableTo reports whether a value of type V can be asserted to have type T.
+// It returns (nil, false) as affirmative answer. Otherwise it returns a missing
+// method required by V and whether it is missing or just has the wrong type.
+// The receiver may be nil if assertableTo is invoked through an exported API call
+// (such as AssertableTo), i.e., when all methods have been type-checked.
+// If the global constant forceStrict is set, assertions that are known to fail
+// are not permitted.
+func (check *Checker) assertableTo(V *Interface, T Type) (method, wrongType *Func) {
+	// no static check is required if T is an interface
+	// spec: "If T is an interface type, x.(T) asserts that the
+	//        dynamic type of x implements the interface T."
+	if asInterface(T) != nil && !forceStrict {
+		return
+	}
+	return check.missingMethod(T, V, false)
+}
+
+// deref dereferences typ if it is a *Pointer and returns its base and true.
+// Otherwise it returns (typ, false).
+func deref(typ Type) (Type, bool) {
+	if p, _ := typ.(*Pointer); p != nil {
+		return p.base, true
+	}
+	return typ, false
+}
+
+// derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a
+// (named or unnamed) struct and returns its base. Otherwise it returns typ.
+func derefStructPtr(typ Type) Type {
+	if p := asPointer(typ); p != nil {
+		if asStruct(p.base) != nil {
+			return p.base
+		}
+	}
+	return typ
+}
+
+// concat returns the result of concatenating list and i.
+// The result does not share its underlying array with list.
+func concat(list []int, i int) []int {
+	var t []int
+	t = append(t, list...)
+	return append(t, i)
+}
+
+// fieldIndex returns the index for the field with matching package and name, or a value < 0.
+func fieldIndex(fields []*Var, pkg *Package, name string) int {
+	if name != "_" {
+		for i, f := range fields {
+			if f.sameId(pkg, name) {
+				return i
+			}
+		}
+	}
+	return -1
+}
+
+// lookupMethod returns the index of and method with matching package and name, or (-1, nil).
+func lookupMethod(methods []*Func, pkg *Package, name string) (int, *Func) {
+	if name != "_" {
+		for i, m := range methods {
+			if m.sameId(pkg, name) {
+				return i, m
+			}
+		}
+	}
+	return -1, nil
+}
+
+// ptrRecv reports whether the receiver is of the form *T.
+func ptrRecv(f *Func) bool {
+	// If a method's receiver type is set, use that as the source of truth for the receiver.
+	// Caution: Checker.funcDecl (decl.go) marks a function by setting its type to an empty
+	// signature. We may reach here before the signature is fully set up: we must explicitly
+	// check if the receiver is set (we cannot just look for non-nil f.typ).
+	if sig, _ := f.typ.(*Signature); sig != nil && sig.recv != nil {
+		_, isPtr := deref(sig.recv.typ)
+		return isPtr
+	}
+
+	// If a method's type is not set it may be a method/function that is:
+	// 1) client-supplied (via NewFunc with no signature), or
+	// 2) internally created but not yet type-checked.
+	// For case 1) we can't do anything; the client must know what they are doing.
+	// For case 2) we can use the information gathered by the resolver.
+	return f.hasPtrRecv
+}
diff --git a/src/cmd/compile/internal/types2/object.go b/src/cmd/compile/internal/types2/object.go
new file mode 100644
index 0000000..844bc34
--- /dev/null
+++ b/src/cmd/compile/internal/types2/object.go
@@ -0,0 +1,527 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"go/constant"
+	"unicode"
+	"unicode/utf8"
+)
+
+// 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.
+//
+type Object interface {
+	Parent() *Scope  // scope in which this object is declared; nil for methods and struct fields
+	Pos() syntax.Pos // position of object identifier in declaration
+	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
+	Id() string      // object name if exported, qualified name if not exported (see func Id)
+
+	// String returns a human-readable string of the object.
+	String() string
+
+	// order reflects a package-level object's source order: if object
+	// a is before object b in the source, then a.order() < b.order().
+	// order returns a value > 0 for package-level objects; it returns
+	// 0 for all other objects (including objects in file scopes).
+	order() uint32
+
+	// color returns the object's color.
+	color() color
+
+	// setType sets the type of the object.
+	setType(Type)
+
+	// setOrder sets the order number of the object. It must be > 0.
+	setOrder(uint32)
+
+	// setColor sets the object's color. It must not be white.
+	setColor(color color)
+
+	// setParent sets the parent scope of the object.
+	setParent(*Scope)
+
+	// sameId reports whether obj.Id() and Id(pkg, name) are the same.
+	sameId(pkg *Package, name string) bool
+
+	// scopePos returns the start position of the scope of this Object
+	scopePos() syntax.Pos
+
+	// setScopePos sets the start position of the scope for this Object.
+	setScopePos(pos syntax.Pos)
+}
+
+func isExported(name string) bool {
+	ch, _ := utf8.DecodeRuneInString(name)
+	return unicode.IsUpper(ch)
+}
+
+// Id returns name if it is exported, otherwise it
+// returns the name qualified with the package path.
+func Id(pkg *Package, name string) string {
+	if isExported(name) {
+		return name
+	}
+	// unexported names need the package path for differentiation
+	// (if there's no package, make sure we don't start with '.'
+	// as that may change the order of methods between a setup
+	// inside a package and outside a package - which breaks some
+	// tests)
+	path := "_"
+	// pkg is nil for objects in Universe scope and possibly types
+	// introduced via Eval (see also comment in object.sameId)
+	if pkg != nil && pkg.path != "" {
+		path = pkg.path
+	}
+	return path + "." + name
+}
+
+// An object implements the common parts of an Object.
+type object struct {
+	parent    *Scope
+	pos       syntax.Pos
+	pkg       *Package
+	name      string
+	typ       Type
+	order_    uint32
+	color_    color
+	scopePos_ syntax.Pos
+}
+
+// color encodes the color of an object (see Checker.objDecl for details).
+type color uint32
+
+// An object may be painted in one of three colors.
+// Color values other than white or black are considered grey.
+const (
+	white color = iota
+	black
+	grey // must be > white and black
+)
+
+func (c color) String() string {
+	switch c {
+	case white:
+		return "white"
+	case black:
+		return "black"
+	default:
+		return "grey"
+	}
+}
+
+// colorFor returns the (initial) color for an object depending on
+// whether its type t is known or not.
+func colorFor(t Type) color {
+	if t != nil {
+		return black
+	}
+	return white
+}
+
+// Parent returns the scope in which the object is declared.
+// The result is nil for methods and struct fields.
+func (obj *object) Parent() *Scope { return obj.parent }
+
+// Pos returns the declaration position of the object's identifier.
+func (obj *object) Pos() syntax.Pos { return obj.pos }
+
+// Pkg returns the package to which the object belongs.
+// The result is nil for labels and objects in the Universe scope.
+func (obj *object) Pkg() *Package { return obj.pkg }
+
+// Name returns the object's (package-local, unqualified) name.
+func (obj *object) Name() string { return obj.name }
+
+// Type returns the object's type.
+func (obj *object) Type() Type { return obj.typ }
+
+// Exported reports whether the object is exported (starts with a capital letter).
+// It doesn't take into account whether the object is in a local (function) scope
+// or not.
+func (obj *object) Exported() bool { return isExported(obj.name) }
+
+// Id is a wrapper for Id(obj.Pkg(), obj.Name()).
+func (obj *object) Id() string { return Id(obj.pkg, obj.name) }
+
+func (obj *object) String() string       { panic("abstract") }
+func (obj *object) order() uint32        { return obj.order_ }
+func (obj *object) color() color         { return obj.color_ }
+func (obj *object) scopePos() syntax.Pos { return obj.scopePos_ }
+
+func (obj *object) setParent(parent *Scope)    { obj.parent = parent }
+func (obj *object) setType(typ Type)           { obj.typ = typ }
+func (obj *object) setOrder(order uint32)      { assert(order > 0); obj.order_ = order }
+func (obj *object) setColor(color color)       { assert(color != white); obj.color_ = color }
+func (obj *object) setScopePos(pos syntax.Pos) { obj.scopePos_ = pos }
+
+func (obj *object) sameId(pkg *Package, name string) bool {
+	// spec:
+	// "Two identifiers are different if they are spelled differently,
+	// or if they appear in different packages and are not exported.
+	// Otherwise, they are the same."
+	if name != obj.name {
+		return false
+	}
+	// obj.Name == name
+	if obj.Exported() {
+		return true
+	}
+	// not exported, so packages must be the same (pkg == nil for
+	// fields in Universe scope; this can only happen for types
+	// introduced via Eval)
+	if pkg == nil || obj.pkg == nil {
+		return pkg == obj.pkg
+	}
+	// pkg != nil && obj.pkg != nil
+	return pkg.path == obj.pkg.path
+}
+
+// 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 syntax.Pos, pkg *Package, name string, imported *Package) *PkgName {
+	return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, nopos}, imported, false}
+}
+
+// Imported returns the package that was imported.
+// It is distinct from Pkg(), which is the package containing the import statement.
+func (obj *PkgName) Imported() *Package { return obj.imported }
+
+// A Const represents a declared constant.
+type Const struct {
+	object
+	val constant.Value
+}
+
+// NewConst returns a new constant with value val.
+// The remaining arguments set the attributes found with all Objects.
+func NewConst(pos syntax.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
+	return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, val}
+}
+
+// Val returns the constant's value.
+func (obj *Const) Val() constant.Value { return obj.val }
+
+func (*Const) isDependency() {} // a constant may be a dependency of an initialization expression
+
+// A TypeName represents a name for a (defined or alias) type.
+type TypeName struct {
+	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 syntax.Pos, pkg *Package, name string, typ Type) *TypeName {
+	return &TypeName{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
+}
+
+// IsAlias reports whether obj is an alias name for a type.
+func (obj *TypeName) IsAlias() bool {
+	switch t := obj.typ.(type) {
+	case nil:
+		return false
+	case *Basic:
+		// unsafe.Pointer is not an alias.
+		if obj.pkg == Unsafe {
+			return false
+		}
+		// Any user-defined type name for a basic type is an alias for a
+		// basic type (because basic types are pre-declared in the Universe
+		// scope, outside any package scope), and so is any type name with
+		// a different name than the name of the basic type it refers to.
+		// Additionally, we need to look for "byte" and "rune" because they
+		// are aliases but have the same names (for better error messages).
+		return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune
+	case *Named:
+		return obj != t.obj
+	default:
+		return true
+	}
+}
+
+// A Variable represents a declared variable (including function parameters and results, and struct fields).
+type Var struct {
+	object
+	embedded bool // if set, the variable is an embedded struct field, and name is the type name
+	isField  bool // var is struct field
+	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 syntax.Pos, pkg *Package, name string, typ Type) *Var {
+	return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
+}
+
+// NewParam returns a new variable representing a function parameter.
+func NewParam(pos syntax.Pos, pkg *Package, name string, typ Type) *Var {
+	return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, used: true} // parameters are always 'used'
+}
+
+// NewField returns a new variable representing a struct field.
+// For embedded fields, the name is the unqualified type name
+/// under which the field is accessible.
+func NewField(pos syntax.Pos, pkg *Package, name string, typ Type, embedded bool) *Var {
+	return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, embedded: embedded, isField: true}
+}
+
+// Anonymous reports whether the variable is an embedded field.
+// Same as Embedded; only present for backward-compatibility.
+func (obj *Var) Anonymous() bool { return obj.embedded }
+
+// Embedded reports whether the variable is an embedded field.
+func (obj *Var) Embedded() bool { return obj.embedded }
+
+// 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.
+// An abstract method may belong to many interfaces due to embedding.
+type Func struct {
+	object
+	hasPtrRecv bool // only valid for methods that don't have a type yet
+}
+
+// NewFunc returns a new function with the given signature, representing
+// the function's type.
+func NewFunc(pos syntax.Pos, pkg *Package, name string, sig *Signature) *Func {
+	// don't store a (typed) nil signature
+	var typ Type
+	if sig != nil {
+		typ = sig
+	}
+	return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, false}
+}
+
+// FullName returns the package- or receiver-type-qualified name of
+// function or method obj.
+func (obj *Func) FullName() string {
+	var buf bytes.Buffer
+	writeFuncName(&buf, obj, nil)
+	return buf.String()
+}
+
+// Scope returns the scope of the function's body block.
+func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
+
+// Less reports whether function a is ordered before function b.
+//
+// Functions are ordered exported before non-exported, then by name,
+// and finally (for non-exported functions) by package path.
+//
+// TODO(gri) The compiler also sorts by package height before package
+//           path for non-exported names.
+func (a *Func) less(b *Func) bool {
+	if a == b {
+		return false
+	}
+
+	// Exported functions before non-exported.
+	ea := isExported(a.name)
+	eb := isExported(b.name)
+	if ea != eb {
+		return ea
+	}
+
+	// Order by name and then (for non-exported names) by package.
+	if a.name != b.name {
+		return a.name < b.name
+	}
+	if !ea {
+		return a.pkg.path < b.pkg.path
+	}
+
+	return false
+}
+
+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 syntax.Pos, pkg *Package, name string) *Label {
+	return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid], color_: black}, false}
+}
+
+// A Builtin represents a built-in function.
+// Builtins don't have a valid type.
+type Builtin struct {
+	object
+	id builtinId
+}
+
+func newBuiltin(id builtinId) *Builtin {
+	return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid], color_: black}, id}
+}
+
+// Nil represents the predeclared value nil.
+type Nil struct {
+	object
+}
+
+func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
+	var tname *TypeName
+	typ := obj.Type()
+
+	switch obj := obj.(type) {
+	case *PkgName:
+		fmt.Fprintf(buf, "package %s", obj.Name())
+		if path := obj.imported.path; path != "" && path != obj.name {
+			fmt.Fprintf(buf, " (%q)", path)
+		}
+		return
+
+	case *Const:
+		buf.WriteString("const")
+
+	case *TypeName:
+		tname = obj
+		buf.WriteString("type")
+
+	case *Var:
+		if obj.isField {
+			buf.WriteString("field")
+		} else {
+			buf.WriteString("var")
+		}
+
+	case *Func:
+		buf.WriteString("func ")
+		writeFuncName(buf, obj, qf)
+		if typ != nil {
+			WriteSignature(buf, typ.(*Signature), qf)
+		}
+		return
+
+	case *Label:
+		buf.WriteString("label")
+		typ = nil
+
+	case *Builtin:
+		buf.WriteString("builtin")
+		typ = nil
+
+	case *Nil:
+		buf.WriteString("nil")
+		return
+
+	default:
+		panic(fmt.Sprintf("writeObject(%T)", obj))
+	}
+
+	buf.WriteByte(' ')
+
+	// For package-level objects, qualify the name.
+	if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
+		writePackage(buf, obj.Pkg(), qf)
+	}
+	buf.WriteString(obj.Name())
+
+	if typ == nil {
+		return
+	}
+
+	if tname != nil {
+		// We have a type object: Don't print anything more for
+		// basic types since there's no more information (names
+		// are the same; see also comment in TypeName.IsAlias).
+		if _, ok := typ.(*Basic); ok {
+			return
+		}
+		if tname.IsAlias() {
+			buf.WriteString(" =")
+		} else {
+			typ = under(typ)
+		}
+	}
+
+	buf.WriteByte(' ')
+	WriteType(buf, typ, qf)
+}
+
+func writePackage(buf *bytes.Buffer, pkg *Package, qf Qualifier) {
+	if pkg == nil {
+		return
+	}
+	var s string
+	if qf != nil {
+		s = qf(pkg)
+	} else {
+		s = pkg.Path()
+	}
+	if s != "" {
+		buf.WriteString(s)
+		buf.WriteByte('.')
+	}
+}
+
+// ObjectString returns the string form of obj.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func ObjectString(obj Object, qf Qualifier) string {
+	var buf bytes.Buffer
+	writeObject(&buf, obj, qf)
+	return buf.String()
+}
+
+func (obj *PkgName) String() string  { return ObjectString(obj, nil) }
+func (obj *Const) String() string    { return ObjectString(obj, nil) }
+func (obj *TypeName) String() string { return ObjectString(obj, nil) }
+func (obj *Var) String() string      { return ObjectString(obj, nil) }
+func (obj *Func) String() string     { return ObjectString(obj, nil) }
+func (obj *Label) String() string    { return ObjectString(obj, nil) }
+func (obj *Builtin) String() string  { return ObjectString(obj, nil) }
+func (obj *Nil) String() string      { return ObjectString(obj, nil) }
+
+func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
+	if f.typ != nil {
+		sig := f.typ.(*Signature)
+		if recv := sig.Recv(); recv != nil {
+			buf.WriteByte('(')
+			if _, ok := recv.Type().(*Interface); ok {
+				// gcimporter creates abstract methods of
+				// named interfaces using the interface type
+				// (not the named type) as the receiver.
+				// Don't print it in full.
+				buf.WriteString("interface")
+			} else {
+				WriteType(buf, recv.Type(), qf)
+			}
+			buf.WriteByte(')')
+			buf.WriteByte('.')
+		} else if f.pkg != nil {
+			writePackage(buf, f.pkg, qf)
+		}
+	}
+	buf.WriteString(f.name)
+}
diff --git a/src/cmd/compile/internal/types2/object_test.go b/src/cmd/compile/internal/types2/object_test.go
new file mode 100644
index 0000000..7f63c79
--- /dev/null
+++ b/src/cmd/compile/internal/types2/object_test.go
@@ -0,0 +1,88 @@
+// 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 types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"strings"
+	"testing"
+)
+
+func parseSrc(path, src string) (*syntax.File, error) {
+	return syntax.Parse(syntax.NewFileBase(path), strings.NewReader(src), nil, nil, 0)
+}
+
+func TestIsAlias(t *testing.T) {
+	check := func(obj *TypeName, want bool) {
+		if got := obj.IsAlias(); got != want {
+			t.Errorf("%v: got IsAlias = %v; want %v", obj, got, want)
+		}
+	}
+
+	// predeclared types
+	check(Unsafe.Scope().Lookup("Pointer").(*TypeName), false)
+	for _, name := range Universe.Names() {
+		if obj, _ := Universe.Lookup(name).(*TypeName); obj != nil {
+			check(obj, name == "byte" || name == "rune")
+		}
+	}
+
+	// various other types
+	pkg := NewPackage("p", "p")
+	t1 := NewTypeName(nopos, pkg, "t1", nil)
+	n1 := NewNamed(t1, new(Struct), nil)
+	for _, test := range []struct {
+		name  *TypeName
+		alias bool
+	}{
+		{NewTypeName(nopos, nil, "t0", nil), false}, // no type yet
+		{NewTypeName(nopos, pkg, "t0", nil), false}, // no type yet
+		{t1, false}, // type name refers to named type and vice versa
+		{NewTypeName(nopos, nil, "t2", &emptyInterface), true}, // type name refers to unnamed type
+		{NewTypeName(nopos, pkg, "t3", n1), true},              // type name refers to named type with different type name
+		{NewTypeName(nopos, nil, "t4", Typ[Int32]), true},      // type name refers to basic type with different name
+		{NewTypeName(nopos, nil, "int32", Typ[Int32]), false},  // type name refers to basic type with same name
+		{NewTypeName(nopos, pkg, "int32", Typ[Int32]), true},   // type name is declared in user-defined package (outside Universe)
+		{NewTypeName(nopos, nil, "rune", Typ[Rune]), true},     // type name refers to basic type rune which is an alias already
+	} {
+		check(test.name, test.alias)
+	}
+}
+
+// TestEmbeddedMethod checks that an embedded method is represented by
+// the same Func Object as the original method. See also issue #34421.
+func TestEmbeddedMethod(t *testing.T) {
+	const src = `package p; type I interface { error }`
+
+	// type-check src
+	f, err := parseSrc("", src)
+	if err != nil {
+		t.Fatalf("parse failed: %s", err)
+	}
+	var conf Config
+	pkg, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, nil)
+	if err != nil {
+		t.Fatalf("typecheck failed: %s", err)
+	}
+
+	// get original error.Error method
+	eface := Universe.Lookup("error")
+	orig, _, _ := LookupFieldOrMethod(eface.Type(), false, nil, "Error")
+	if orig == nil {
+		t.Fatalf("original error.Error not found")
+	}
+
+	// get embedded error.Error method
+	iface := pkg.Scope().Lookup("I")
+	embed, _, _ := LookupFieldOrMethod(iface.Type(), false, nil, "Error")
+	if embed == nil {
+		t.Fatalf("embedded error.Error not found")
+	}
+
+	// original and embedded Error object should be identical
+	if orig != embed {
+		t.Fatalf("%s (%p) != %s (%p)", orig, orig, embed, embed)
+	}
+}
diff --git a/src/cmd/compile/internal/types2/objset.go b/src/cmd/compile/internal/types2/objset.go
new file mode 100644
index 0000000..88ff0af
--- /dev/null
+++ b/src/cmd/compile/internal/types2/objset.go
@@ -0,0 +1,31 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements objsets.
+//
+// An objset is similar to a Scope but objset elements
+// are identified by their unique id, instead of their
+// object name.
+
+package types2
+
+// An objset is a set of objects identified by their unique id.
+// The zero value for objset is a ready-to-use empty objset.
+type objset map[string]Object // initialized lazily
+
+// insert attempts to insert an object obj into objset s.
+// If s already contains an alternative object alt with
+// the same name, insert leaves s unchanged and returns alt.
+// Otherwise it inserts obj and returns nil.
+func (s *objset) insert(obj Object) Object {
+	id := obj.Id()
+	if alt := (*s)[id]; alt != nil {
+		return alt
+	}
+	if *s == nil {
+		*s = make(map[string]Object)
+	}
+	(*s)[id] = obj
+	return nil
+}
diff --git a/src/cmd/compile/internal/types2/operand.go b/src/cmd/compile/internal/types2/operand.go
new file mode 100644
index 0000000..455d8b5
--- /dev/null
+++ b/src/cmd/compile/internal/types2/operand.go
@@ -0,0 +1,318 @@
+// 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 defines operands and associated operations.
+
+package types2
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"go/constant"
+	"go/token"
+)
+
+// An operandMode specifies the (addressing) mode of an operand.
+type operandMode byte
+
+const (
+	invalid   operandMode = iota // operand is invalid
+	novalue                      // operand represents no value (result of a function call w/o result)
+	builtin                      // operand is a built-in function
+	typexpr                      // operand is a type
+	constant_                    // operand is a constant; the operand's typ is a Basic type
+	variable                     // operand is an addressable variable
+	mapindex                     // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
+	value                        // operand is a computed value
+	nilvalue                     // operand is the nil value
+	commaok                      // like value, but operand may be used in a comma,ok expression
+	commaerr                     // like commaok, but second value is error, not boolean
+	cgofunc                      // operand is a cgo function
+)
+
+var operandModeString = [...]string{
+	invalid:   "invalid operand",
+	novalue:   "no value",
+	builtin:   "built-in",
+	typexpr:   "type",
+	constant_: "constant",
+	variable:  "variable",
+	mapindex:  "map index expression",
+	value:     "value",
+	nilvalue:  "nil",
+	commaok:   "comma, ok expression",
+	commaerr:  "comma, error expression",
+	cgofunc:   "cgo function",
+}
+
+// An operand represents an intermediate value during type checking.
+// Operands have an (addressing) mode, the expression evaluating to
+// the operand, the operand's type, a value for constants, and an id
+// for built-in functions.
+// The zero value of operand is a ready to use invalid operand.
+//
+type operand struct {
+	mode operandMode
+	expr syntax.Expr
+	typ  Type
+	val  constant.Value
+	id   builtinId
+}
+
+// Pos returns the position of the expression corresponding to x.
+// If x is invalid the position is nopos.
+//
+func (x *operand) Pos() syntax.Pos {
+	// x.expr may not be set if x is invalid
+	if x.expr == nil {
+		return nopos
+	}
+	return x.expr.Pos()
+}
+
+// Operand string formats
+// (not all "untyped" cases can appear due to the type system,
+// but they fall out naturally here)
+//
+// mode       format
+//
+// invalid    <expr> (               <mode>                    )
+// novalue    <expr> (               <mode>                    )
+// builtin    <expr> (               <mode>                    )
+// typexpr    <expr> (               <mode>                    )
+//
+// constant   <expr> (<untyped kind> <mode>                    )
+// constant   <expr> (               <mode>       of type <typ>)
+// constant   <expr> (<untyped kind> <mode> <val>              )
+// constant   <expr> (               <mode> <val> of type <typ>)
+//
+// variable   <expr> (<untyped kind> <mode>                    )
+// variable   <expr> (               <mode>       of type <typ>)
+//
+// mapindex   <expr> (<untyped kind> <mode>                    )
+// mapindex   <expr> (               <mode>       of type <typ>)
+//
+// value      <expr> (<untyped kind> <mode>                    )
+// value      <expr> (               <mode>       of type <typ>)
+//
+// nilvalue   untyped nil
+// nilvalue   nil    (                            of type <typ>)
+//
+// commaok    <expr> (<untyped kind> <mode>                    )
+// commaok    <expr> (               <mode>       of type <typ>)
+//
+// commaerr   <expr> (<untyped kind> <mode>                    )
+// commaerr   <expr> (               <mode>       of type <typ>)
+//
+// cgofunc    <expr> (<untyped kind> <mode>                    )
+// cgofunc    <expr> (               <mode>       of type <typ>)
+//
+func operandString(x *operand, qf Qualifier) string {
+	// special-case nil
+	if x.mode == nilvalue {
+		switch x.typ {
+		case nil, Typ[Invalid]:
+			return "nil (with invalid type)"
+		case Typ[UntypedNil]:
+			return "untyped nil"
+		default:
+			return fmt.Sprintf("nil (of type %s)", TypeString(x.typ, qf))
+		}
+	}
+
+	var buf bytes.Buffer
+
+	var expr string
+	if x.expr != nil {
+		expr = syntax.String(x.expr)
+	} else {
+		switch x.mode {
+		case builtin:
+			expr = predeclaredFuncs[x.id].name
+		case typexpr:
+			expr = TypeString(x.typ, qf)
+		case constant_:
+			expr = x.val.String()
+		}
+	}
+
+	// <expr> (
+	if expr != "" {
+		buf.WriteString(expr)
+		buf.WriteString(" (")
+	}
+
+	// <untyped kind>
+	hasType := false
+	switch x.mode {
+	case invalid, novalue, builtin, typexpr:
+		// no type
+	default:
+		// should have a type, but be cautious (don't crash during printing)
+		if x.typ != nil {
+			if isUntyped(x.typ) {
+				buf.WriteString(x.typ.(*Basic).name)
+				buf.WriteByte(' ')
+				break
+			}
+			hasType = true
+		}
+	}
+
+	// <mode>
+	buf.WriteString(operandModeString[x.mode])
+
+	// <val>
+	if x.mode == constant_ {
+		if s := x.val.String(); s != expr {
+			buf.WriteByte(' ')
+			buf.WriteString(s)
+		}
+	}
+
+	// <typ>
+	if hasType {
+		if x.typ != Typ[Invalid] {
+			var intro string
+			switch {
+			case isGeneric(x.typ):
+				intro = " of generic type "
+			case asTypeParam(x.typ) != nil:
+				intro = " of type parameter type "
+			default:
+				intro = " of type "
+			}
+			buf.WriteString(intro)
+			WriteType(&buf, x.typ, qf)
+		} else {
+			buf.WriteString(" with invalid type")
+		}
+	}
+
+	// )
+	if expr != "" {
+		buf.WriteByte(')')
+	}
+
+	return buf.String()
+}
+
+func (x *operand) String() string {
+	return operandString(x, nil)
+}
+
+// setConst sets x to the untyped constant for literal lit.
+func (x *operand) setConst(k syntax.LitKind, lit string) {
+	var kind BasicKind
+	switch k {
+	case syntax.IntLit:
+		kind = UntypedInt
+	case syntax.FloatLit:
+		kind = UntypedFloat
+	case syntax.ImagLit:
+		kind = UntypedComplex
+	case syntax.RuneLit:
+		kind = UntypedRune
+	case syntax.StringLit:
+		kind = UntypedString
+	default:
+		unreachable()
+	}
+
+	val := constant.MakeFromLiteral(lit, kind2tok[k], 0)
+	if val.Kind() == constant.Unknown {
+		x.mode = invalid
+		x.typ = Typ[Invalid]
+		return
+	}
+	x.mode = constant_
+	x.typ = Typ[kind]
+	x.val = val
+}
+
+// isNil reports whether x is a typed or the untyped nil value.
+func (x *operand) isNil() bool { return x.mode == nilvalue }
+
+// assignableTo reports whether x is assignable to a variable of type T. If the
+// result is false and a non-nil reason is provided, it may be set to a more
+// detailed explanation of the failure (result != ""). The returned error code
+// is only valid if the (first) result is false. The check parameter may be nil
+// if assignableTo is invoked through an exported API call, i.e., when all
+// methods have been type-checked.
+func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, errorCode) {
+	if x.mode == invalid || T == Typ[Invalid] {
+		return true, 0 // avoid spurious errors
+	}
+
+	V := x.typ
+
+	// x's type is identical to T
+	if check.identical(V, T) {
+		return true, 0
+	}
+
+	Vu := optype(V)
+	Tu := optype(T)
+
+	// x is an untyped value representable by a value of type T.
+	if isUntyped(Vu) {
+		if t, ok := Tu.(*Sum); ok {
+			return t.is(func(t Type) bool {
+				// TODO(gri) this could probably be more efficient
+				ok, _ := x.assignableTo(check, t, reason)
+				return ok
+			}), _IncompatibleAssign
+		}
+		newType, _, _ := check.implicitTypeAndValue(x, Tu)
+		return newType != nil, _IncompatibleAssign
+	}
+	// Vu is typed
+
+	// x's type V and T have identical underlying types
+	// and at least one of V or T is not a named type
+	if check.identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) {
+		return true, 0
+	}
+
+	// T is an interface type and x implements T
+	if Ti, ok := Tu.(*Interface); ok {
+		if m, wrongType := check.missingMethod(V, Ti, true); m != nil /* Implements(V, Ti) */ {
+			if reason != nil {
+				if wrongType != nil {
+					if check.identical(m.typ, wrongType.typ) {
+						*reason = fmt.Sprintf("missing method %s (%s has pointer receiver)", m.name, m.name)
+					} else {
+						*reason = fmt.Sprintf("wrong type for method %s (have %s, want %s)", m.Name(), wrongType.typ, m.typ)
+					}
+
+				} else {
+					*reason = "missing method " + m.Name()
+				}
+			}
+			return false, _InvalidIfaceAssign
+		}
+		return true, 0
+	}
+
+	// x is a bidirectional channel value, T is a channel
+	// type, x's type V and T have identical element types,
+	// and at least one of V or T is not a named type
+	if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv {
+		if Tc, ok := Tu.(*Chan); ok && check.identical(Vc.elem, Tc.elem) {
+			return !isNamed(V) || !isNamed(T), _InvalidChanAssign
+		}
+	}
+
+	return false, _IncompatibleAssign
+}
+
+// kind2tok translates syntax.LitKinds into token.Tokens.
+var kind2tok = [...]token.Token{
+	syntax.IntLit:    token.INT,
+	syntax.FloatLit:  token.FLOAT,
+	syntax.ImagLit:   token.IMAG,
+	syntax.RuneLit:   token.CHAR,
+	syntax.StringLit: token.STRING,
+}
diff --git a/src/cmd/compile/internal/types2/package.go b/src/cmd/compile/internal/types2/package.go
new file mode 100644
index 0000000..31b1e71
--- /dev/null
+++ b/src/cmd/compile/internal/types2/package.go
@@ -0,0 +1,64 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+import (
+	"fmt"
+)
+
+// A Package describes a Go package.
+type Package struct {
+	path     string
+	name     string
+	scope    *Scope
+	complete bool
+	imports  []*Package
+	fake     bool // scope lookup errors are silently dropped if package is fake (internal use only)
+	cgo      bool // uses of this package will be rewritten into uses of declarations from _cgo_gotypes.go
+}
+
+// NewPackage returns a new Package for the given package path and name.
+// The package is not complete and contains no explicit imports.
+func NewPackage(path, name string) *Package {
+	scope := NewScope(Universe, nopos, nopos, fmt.Sprintf("package %q", path))
+	return &Package{path: path, name: name, scope: scope}
+}
+
+// Path returns the package path.
+func (pkg *Package) Path() string { return pkg.path }
+
+// Name returns the package name.
+func (pkg *Package) Name() string { return pkg.name }
+
+// SetName sets the package name.
+func (pkg *Package) SetName(name string) { pkg.name = name }
+
+// Scope returns the (complete or incomplete) package scope
+// holding the objects declared at package level (TypeNames,
+// Consts, Vars, and Funcs).
+func (pkg *Package) Scope() *Scope { return pkg.scope }
+
+// A package is complete if its scope contains (at least) all
+// exported objects; otherwise it is incomplete.
+func (pkg *Package) Complete() bool { return pkg.complete }
+
+// MarkComplete marks a package as complete.
+func (pkg *Package) MarkComplete() { pkg.complete = true }
+
+// Imports returns the list of packages directly imported by
+// pkg; the list is in source order.
+//
+// If pkg was loaded from export data, Imports includes packages that
+// provide package-level objects referenced by pkg. This may be more or
+// less than the set of packages directly imported by pkg's source code.
+func (pkg *Package) Imports() []*Package { return pkg.imports }
+
+// SetImports sets the list of explicitly imported packages to list.
+// It is the caller's responsibility to make sure list elements are unique.
+func (pkg *Package) SetImports(list []*Package) { pkg.imports = list }
+
+func (pkg *Package) String() string {
+	return fmt.Sprintf("package %s (%q)", pkg.name, pkg.path)
+}
diff --git a/src/cmd/compile/internal/types2/predicates.go b/src/cmd/compile/internal/types2/predicates.go
new file mode 100644
index 0000000..ae186a0
--- /dev/null
+++ b/src/cmd/compile/internal/types2/predicates.go
@@ -0,0 +1,425 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements commonly used type predicates.
+
+package types2
+
+// isNamed reports whether typ has a name.
+// isNamed may be called with types that are not fully set up.
+func isNamed(typ Type) bool {
+	switch typ.(type) {
+	case *Basic, *Named, *TypeParam, *instance:
+		return true
+	}
+	return false
+}
+
+// isGeneric reports whether a type is a generic, uninstantiated type (generic
+// signatures are not included).
+func isGeneric(typ Type) bool {
+	// A parameterized type is only instantiated if it doesn't have an instantiation already.
+	named, _ := typ.(*Named)
+	return named != nil && named.obj != nil && named.tparams != nil && named.targs == nil
+}
+
+func is(typ Type, what BasicInfo) bool {
+	switch t := optype(typ).(type) {
+	case *Basic:
+		return t.info&what != 0
+	case *Sum:
+		return t.is(func(typ Type) bool { return is(typ, what) })
+	}
+	return false
+}
+
+func isBoolean(typ Type) bool  { return is(typ, IsBoolean) }
+func isInteger(typ Type) bool  { return is(typ, IsInteger) }
+func isUnsigned(typ Type) bool { return is(typ, IsUnsigned) }
+func isFloat(typ Type) bool    { return is(typ, IsFloat) }
+func isComplex(typ Type) bool  { return is(typ, IsComplex) }
+func isNumeric(typ Type) bool  { return is(typ, IsNumeric) }
+func isString(typ Type) bool   { return is(typ, IsString) }
+
+// Note that if typ is a type parameter, isInteger(typ) || isFloat(typ) does not
+// produce the expected result because a type list that contains both an integer
+// and a floating-point type is neither (all) integers, nor (all) floats.
+// Use isIntegerOrFloat instead.
+func isIntegerOrFloat(typ Type) bool { return is(typ, IsInteger|IsFloat) }
+
+// isNumericOrString is the equivalent of isIntegerOrFloat for isNumeric(typ) || isString(typ).
+func isNumericOrString(typ Type) bool { return is(typ, IsNumeric|IsString) }
+
+// isTyped reports whether typ is typed; i.e., not an untyped
+// constant or boolean. isTyped may be called with types that
+// are not fully set up.
+func isTyped(typ Type) bool {
+	// isTyped is called with types that are not fully
+	// set up. Must not call Basic()!
+	// A *Named or *instance type is always typed, so
+	// we only need to check if we have a true *Basic
+	// type.
+	t, _ := typ.(*Basic)
+	return t == nil || t.info&IsUntyped == 0
+}
+
+// isUntyped(typ) is the same as !isTyped(typ).
+func isUntyped(typ Type) bool {
+	return !isTyped(typ)
+}
+
+func isOrdered(typ Type) bool { return is(typ, IsOrdered) }
+
+func isConstType(typ Type) bool {
+	// Type parameters are never const types.
+	t, _ := under(typ).(*Basic)
+	return t != nil && t.info&IsConstType != 0
+}
+
+// IsInterface reports whether typ is an interface type.
+func IsInterface(typ Type) bool {
+	return asInterface(typ) != nil
+}
+
+// Comparable reports whether values of type T are comparable.
+func Comparable(T Type) bool {
+	return comparable(T, nil)
+}
+
+func comparable(T Type, seen map[Type]bool) bool {
+	if seen[T] {
+		return true
+	}
+	if seen == nil {
+		seen = make(map[Type]bool)
+	}
+	seen[T] = true
+
+	// If T is a type parameter not constrained by any type
+	// list (i.e., it's underlying type is the top type),
+	// T is comparable if it has the == method. Otherwise,
+	// the underlying type "wins". For instance
+	//
+	//     interface{ comparable; type []byte }
+	//
+	// is not comparable because []byte is not comparable.
+	if t := asTypeParam(T); t != nil && optype(t) == theTop {
+		return t.Bound().IsComparable()
+	}
+
+	switch t := optype(T).(type) {
+	case *Basic:
+		// assume invalid types to be comparable
+		// to avoid follow-up errors
+		return t.kind != UntypedNil
+	case *Pointer, *Interface, *Chan:
+		return true
+	case *Struct:
+		for _, f := range t.fields {
+			if !comparable(f.typ, seen) {
+				return false
+			}
+		}
+		return true
+	case *Array:
+		return comparable(t.elem, seen)
+	case *Sum:
+		pred := func(t Type) bool {
+			return comparable(t, seen)
+		}
+		return t.is(pred)
+	case *TypeParam:
+		return t.Bound().IsComparable()
+	}
+	return false
+}
+
+// hasNil reports whether a type includes the nil value.
+func hasNil(typ Type) bool {
+	switch t := optype(typ).(type) {
+	case *Basic:
+		return t.kind == UnsafePointer
+	case *Slice, *Pointer, *Signature, *Interface, *Map, *Chan:
+		return true
+	case *Sum:
+		return t.is(hasNil)
+	}
+	return false
+}
+
+// identical reports whether x and y are identical types.
+// Receivers of Signature types are ignored.
+func (check *Checker) identical(x, y Type) bool {
+	return check.identical0(x, y, true, nil)
+}
+
+// identicalIgnoreTags reports whether x and y are identical types if tags are ignored.
+// Receivers of Signature types are ignored.
+func (check *Checker) identicalIgnoreTags(x, y Type) bool {
+	return check.identical0(x, y, false, nil)
+}
+
+// An ifacePair is a node in a stack of interface type pairs compared for identity.
+type ifacePair struct {
+	x, y *Interface
+	prev *ifacePair
+}
+
+func (p *ifacePair) identical(q *ifacePair) bool {
+	return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
+}
+
+// For changes to this code the corresponding changes should be made to unifier.nify.
+func (check *Checker) identical0(x, y Type, cmpTags bool, p *ifacePair) bool {
+	// types must be expanded for comparison
+	x = expandf(x)
+	y = expandf(y)
+
+	if x == y {
+		return true
+	}
+
+	switch x := x.(type) {
+	case *Basic:
+		// Basic types are singletons except for the rune and byte
+		// aliases, thus we cannot solely rely on the x == y check
+		// above. See also comment in TypeName.IsAlias.
+		if y, ok := y.(*Basic); ok {
+			return x.kind == y.kind
+		}
+
+	case *Array:
+		// Two array types are identical if they have identical element types
+		// and the same array length.
+		if y, ok := y.(*Array); ok {
+			// If one or both array lengths are unknown (< 0) due to some error,
+			// assume they are the same to avoid spurious follow-on errors.
+			return (x.len < 0 || y.len < 0 || x.len == y.len) && check.identical0(x.elem, y.elem, cmpTags, p)
+		}
+
+	case *Slice:
+		// Two slice types are identical if they have identical element types.
+		if y, ok := y.(*Slice); ok {
+			return check.identical0(x.elem, y.elem, cmpTags, p)
+		}
+
+	case *Struct:
+		// Two struct types are identical if they have the same sequence of fields,
+		// and if corresponding fields have the same names, and identical types,
+		// and identical tags. Two embedded fields are considered to have the same
+		// name. Lower-case field names from different packages are always different.
+		if y, ok := y.(*Struct); ok {
+			if x.NumFields() == y.NumFields() {
+				for i, f := range x.fields {
+					g := y.fields[i]
+					if f.embedded != g.embedded ||
+						cmpTags && x.Tag(i) != y.Tag(i) ||
+						!f.sameId(g.pkg, g.name) ||
+						!check.identical0(f.typ, g.typ, cmpTags, p) {
+						return false
+					}
+				}
+				return true
+			}
+		}
+
+	case *Pointer:
+		// Two pointer types are identical if they have identical base types.
+		if y, ok := y.(*Pointer); ok {
+			return check.identical0(x.base, y.base, cmpTags, p)
+		}
+
+	case *Tuple:
+		// Two tuples types are identical if they have the same number of elements
+		// and corresponding elements have identical types.
+		if y, ok := y.(*Tuple); ok {
+			if x.Len() == y.Len() {
+				if x != nil {
+					for i, v := range x.vars {
+						w := y.vars[i]
+						if !check.identical0(v.typ, w.typ, cmpTags, p) {
+							return false
+						}
+					}
+				}
+				return true
+			}
+		}
+
+	case *Signature:
+		// Two function types are identical if they have the same number of parameters
+		// and result values, corresponding parameter and result types are identical,
+		// and either both functions are variadic or neither is. Parameter and result
+		// names are not required to match.
+		// Generic functions must also have matching type parameter lists, but for the
+		// parameter names.
+		if y, ok := y.(*Signature); ok {
+			return x.variadic == y.variadic &&
+				check.identicalTParams(x.tparams, y.tparams, cmpTags, p) &&
+				check.identical0(x.params, y.params, cmpTags, p) &&
+				check.identical0(x.results, y.results, cmpTags, p)
+		}
+
+	case *Sum:
+		// Two sum types are identical if they contain the same types.
+		// (Sum types always consist of at least two types. Also, the
+		// the set (list) of types in a sum type consists of unique
+		// types - each type appears exactly once. Thus, two sum types
+		// must contain the same number of types to have chance of
+		// being equal.
+		if y, ok := y.(*Sum); ok && len(x.types) == len(y.types) {
+			// Every type in x.types must be in y.types.
+			// Quadratic algorithm, but probably good enough for now.
+			// TODO(gri) we need a fast quick type ID/hash for all types.
+		L:
+			for _, x := range x.types {
+				for _, y := range y.types {
+					if Identical(x, y) {
+						continue L // x is in y.types
+					}
+				}
+				return false // x is not in y.types
+			}
+			return true
+		}
+
+	case *Interface:
+		// Two interface types are identical if they have the same set of methods with
+		// the same names and identical function types. Lower-case method names from
+		// different packages are always different. The order of the methods is irrelevant.
+		if y, ok := y.(*Interface); ok {
+			// If identical0 is called (indirectly) via an external API entry point
+			// (such as Identical, IdenticalIgnoreTags, etc.), check is nil. But in
+			// that case, interfaces are expected to be complete and lazy completion
+			// here is not needed.
+			if check != nil {
+				check.completeInterface(nopos, x)
+				check.completeInterface(nopos, y)
+			}
+			a := x.allMethods
+			b := y.allMethods
+			if len(a) == len(b) {
+				// Interface types are the only types where cycles can occur
+				// that are not "terminated" via named types; and such cycles
+				// can only be created via method parameter types that are
+				// anonymous interfaces (directly or indirectly) embedding
+				// the current interface. Example:
+				//
+				//    type T interface {
+				//        m() interface{T}
+				//    }
+				//
+				// If two such (differently named) interfaces are compared,
+				// endless recursion occurs if the cycle is not detected.
+				//
+				// If x and y were compared before, they must be equal
+				// (if they were not, the recursion would have stopped);
+				// search the ifacePair stack for the same pair.
+				//
+				// This is a quadratic algorithm, but in practice these stacks
+				// are extremely short (bounded by the nesting depth of interface
+				// type declarations that recur via parameter types, an extremely
+				// rare occurrence). An alternative implementation might use a
+				// "visited" map, but that is probably less efficient overall.
+				q := &ifacePair{x, y, p}
+				for p != nil {
+					if p.identical(q) {
+						return true // same pair was compared before
+					}
+					p = p.prev
+				}
+				if debug {
+					assertSortedMethods(a)
+					assertSortedMethods(b)
+				}
+				for i, f := range a {
+					g := b[i]
+					if f.Id() != g.Id() || !check.identical0(f.typ, g.typ, cmpTags, q) {
+						return false
+					}
+				}
+				return true
+			}
+		}
+
+	case *Map:
+		// Two map types are identical if they have identical key and value types.
+		if y, ok := y.(*Map); ok {
+			return check.identical0(x.key, y.key, cmpTags, p) && check.identical0(x.elem, y.elem, cmpTags, p)
+		}
+
+	case *Chan:
+		// Two channel types are identical if they have identical value types
+		// and the same direction.
+		if y, ok := y.(*Chan); ok {
+			return x.dir == y.dir && check.identical0(x.elem, y.elem, cmpTags, p)
+		}
+
+	case *Named:
+		// Two named types are identical if their type names originate
+		// in the same type declaration.
+		if y, ok := y.(*Named); ok {
+			// TODO(gri) Why is x == y not sufficient? And if it is,
+			//           we can just return false here because x == y
+			//           is caught in the very beginning of this function.
+			return x.obj == y.obj
+		}
+
+	case *TypeParam:
+		// nothing to do (x and y being equal is caught in the very beginning of this function)
+
+	// case *instance:
+	//	unreachable since types are expanded
+
+	case *bottom, *top:
+		// Either both types are theBottom, or both are theTop in which
+		// case the initial x == y check will have caught them. Otherwise
+		// they are not identical.
+
+	case nil:
+		// avoid a crash in case of nil type
+
+	default:
+		unreachable()
+	}
+
+	return false
+}
+
+func (check *Checker) identicalTParams(x, y []*TypeName, cmpTags bool, p *ifacePair) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, x := range x {
+		y := y[i]
+		if !check.identical0(x.typ.(*TypeParam).bound, y.typ.(*TypeParam).bound, cmpTags, p) {
+			return false
+		}
+	}
+	return true
+}
+
+// Default returns the default "typed" type for an "untyped" type;
+// it returns the incoming type for all other types. The default type
+// for untyped nil is untyped nil.
+//
+func Default(typ Type) Type {
+	if t, ok := typ.(*Basic); ok {
+		switch t.kind {
+		case UntypedBool:
+			return Typ[Bool]
+		case UntypedInt:
+			return Typ[Int]
+		case UntypedRune:
+			return universeRune // use 'rune' name
+		case UntypedFloat:
+			return Typ[Float64]
+		case UntypedComplex:
+			return Typ[Complex128]
+		case UntypedString:
+			return Typ[String]
+		}
+	}
+	return typ
+}
diff --git a/src/cmd/compile/internal/types2/resolver.go b/src/cmd/compile/internal/types2/resolver.go
new file mode 100644
index 0000000..fa30650
--- /dev/null
+++ b/src/cmd/compile/internal/types2/resolver.go
@@ -0,0 +1,732 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"go/constant"
+	"sort"
+	"strconv"
+	"strings"
+	"unicode"
+)
+
+// A declInfo describes a package-level const, type, var, or func declaration.
+type declInfo struct {
+	file      *Scope           // scope of file containing this declaration
+	lhs       []*Var           // lhs of n:1 variable declarations, or nil
+	vtyp      syntax.Expr      // type, or nil (for const and var declarations only)
+	init      syntax.Expr      // init/orig expression, or nil (for const and var declarations only)
+	inherited bool             // if set, the init expression is inherited from a previous constant declaration
+	tdecl     *syntax.TypeDecl // type declaration, or nil
+	fdecl     *syntax.FuncDecl // func declaration, or nil
+
+	// The deps field tracks initialization expression dependencies.
+	deps map[Object]bool // lazily initialized
+}
+
+// hasInitializer reports whether the declared object has an initialization
+// expression or function body.
+func (d *declInfo) hasInitializer() bool {
+	return d.init != nil || d.fdecl != nil && d.fdecl.Body != nil
+}
+
+// addDep adds obj to the set of objects d's init expression depends on.
+func (d *declInfo) addDep(obj Object) {
+	m := d.deps
+	if m == nil {
+		m = make(map[Object]bool)
+		d.deps = m
+	}
+	m[obj] = true
+}
+
+// arity checks that the lhs and rhs of a const or var decl
+// have a matching number of names and initialization values.
+// If inherited is set, the initialization values are from
+// another (constant) declaration.
+func (check *Checker) arity(pos syntax.Pos, names []*syntax.Name, inits []syntax.Expr, constDecl, inherited bool) {
+	l := len(names)
+	r := len(inits)
+
+	switch {
+	case l < r:
+		n := inits[l]
+		if inherited {
+			check.errorf(pos, "extra init expr at %s", n.Pos())
+		} else {
+			check.errorf(n, "extra init expr %s", n)
+		}
+	case l > r && (constDecl || r != 1): // if r == 1 it may be a multi-valued function and we can't say anything yet
+		n := names[r]
+		check.errorf(n, "missing init expr for %s", n.Value)
+	}
+}
+
+func validatedImportPath(path string) (string, error) {
+	s, err := strconv.Unquote(path)
+	if err != nil {
+		return "", err
+	}
+	if s == "" {
+		return "", fmt.Errorf("empty string")
+	}
+	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
+	for _, r := range s {
+		if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
+			return s, fmt.Errorf("invalid character %#U", r)
+		}
+	}
+	return s, nil
+}
+
+// declarePkgObj declares obj in the package scope, records its ident -> obj mapping,
+// and updates check.objMap. The object must not be a function or method.
+func (check *Checker) declarePkgObj(ident *syntax.Name, obj Object, d *declInfo) {
+	assert(ident.Value == obj.Name())
+
+	// spec: "A package-scope or file-scope identifier with name init
+	// may only be declared to be a function with this (func()) signature."
+	if ident.Value == "init" {
+		check.error(ident, "cannot declare init - must be func")
+		return
+	}
+
+	// spec: "The main package must have package name main and declare
+	// a function main that takes no arguments and returns no value."
+	if ident.Value == "main" && check.pkg.name == "main" {
+		check.error(ident, "cannot declare main - must be func")
+		return
+	}
+
+	check.declare(check.pkg.scope, ident, obj, nopos)
+	check.objMap[obj] = d
+	obj.setOrder(uint32(len(check.objMap)))
+}
+
+// filename returns a filename suitable for debugging output.
+func (check *Checker) filename(fileNo int) string {
+	file := check.files[fileNo]
+	if pos := file.Pos(); pos.IsKnown() {
+		// return check.fset.File(pos).Name()
+		// TODO(gri) do we need the actual file name here?
+		return pos.RelFilename()
+	}
+	return fmt.Sprintf("file[%d]", fileNo)
+}
+
+func (check *Checker) importPackage(pos syntax.Pos, path, dir string) *Package {
+	// If we already have a package for the given (path, dir)
+	// pair, use it instead of doing a full import.
+	// Checker.impMap only caches packages that are marked Complete
+	// or fake (dummy packages for failed imports). Incomplete but
+	// non-fake packages do require an import to complete them.
+	key := importKey{path, dir}
+	imp := check.impMap[key]
+	if imp != nil {
+		return imp
+	}
+
+	// no package yet => import it
+	if path == "C" && (check.conf.FakeImportC || check.conf.go115UsesCgo) {
+		imp = NewPackage("C", "C")
+		imp.fake = true // package scope is not populated
+		imp.cgo = check.conf.go115UsesCgo
+	} else {
+		// ordinary import
+		var err error
+		if importer := check.conf.Importer; importer == nil {
+			err = fmt.Errorf("Config.Importer not installed")
+		} else if importerFrom, ok := importer.(ImporterFrom); ok {
+			imp, err = importerFrom.ImportFrom(path, dir, 0)
+			if imp == nil && err == nil {
+				err = fmt.Errorf("Config.Importer.ImportFrom(%s, %s, 0) returned nil but no error", path, dir)
+			}
+		} else {
+			imp, err = importer.Import(path)
+			if imp == nil && err == nil {
+				err = fmt.Errorf("Config.Importer.Import(%s) returned nil but no error", path)
+			}
+		}
+		// make sure we have a valid package name
+		// (errors here can only happen through manipulation of packages after creation)
+		if err == nil && imp != nil && (imp.name == "_" || imp.name == "") {
+			err = fmt.Errorf("invalid package name: %q", imp.name)
+			imp = nil // create fake package below
+		}
+		if err != nil {
+			check.errorf(pos, "could not import %s (%s)", path, err)
+			if imp == nil {
+				// create a new fake package
+				// come up with a sensible package name (heuristic)
+				name := path
+				if i := len(name); i > 0 && name[i-1] == '/' {
+					name = name[:i-1]
+				}
+				if i := strings.LastIndex(name, "/"); i >= 0 {
+					name = name[i+1:]
+				}
+				imp = NewPackage(path, name)
+			}
+			// continue to use the package as best as we can
+			imp.fake = true // avoid follow-up lookup failures
+		}
+	}
+
+	// package should be complete or marked fake, but be cautious
+	if imp.complete || imp.fake {
+		check.impMap[key] = imp
+		// Once we've formatted an error message once, keep the pkgPathMap
+		// up-to-date on subsequent imports.
+		if check.pkgPathMap != nil {
+			check.markImports(imp)
+		}
+		return imp
+	}
+
+	// something went wrong (importer may have returned incomplete package without error)
+	return nil
+}
+
+// collectObjects collects all file and package objects and inserts them
+// into their respective scopes. It also performs imports and associates
+// methods with receiver base type names.
+func (check *Checker) collectObjects() {
+	pkg := check.pkg
+
+	// pkgImports is the set of packages already imported by any package file seen
+	// so far. Used to avoid duplicate entries in pkg.imports. Allocate and populate
+	// it (pkg.imports may not be empty if we are checking test files incrementally).
+	// Note that pkgImports is keyed by package (and thus package path), not by an
+	// importKey value. Two different importKey values may map to the same package
+	// which is why we cannot use the check.impMap here.
+	var pkgImports = make(map[*Package]bool)
+	for _, imp := range pkg.imports {
+		pkgImports[imp] = true
+	}
+
+	type methodInfo struct {
+		obj  *Func        // method
+		ptr  bool         // true if pointer receiver
+		recv *syntax.Name // receiver type name
+	}
+	var methods []methodInfo // collected methods with valid receivers and non-blank _ names
+	var fileScopes []*Scope
+	for fileNo, file := range check.files {
+		// The package identifier denotes the current package,
+		// but there is no corresponding package object.
+		check.recordDef(file.PkgName, nil)
+
+		fileScope := NewScope(check.pkg.scope, syntax.StartPos(file), syntax.EndPos(file), check.filename(fileNo))
+		fileScopes = append(fileScopes, fileScope)
+		check.recordScope(file, fileScope)
+
+		// determine file directory, necessary to resolve imports
+		// FileName may be "" (typically for tests) in which case
+		// we get "." as the directory which is what we would want.
+		fileDir := dir(file.PkgName.Pos().RelFilename()) // TODO(gri) should this be filename?
+
+		first := -1                // index of first ConstDecl in the current group, or -1
+		var last *syntax.ConstDecl // last ConstDecl with init expressions, or nil
+		for index, decl := range file.DeclList {
+			if _, ok := decl.(*syntax.ConstDecl); !ok {
+				first = -1 // we're not in a constant declaration
+			}
+
+			switch s := decl.(type) {
+			case *syntax.ImportDecl:
+				// import package
+				if s.Path == nil || s.Path.Bad {
+					continue // error reported during parsing
+				}
+				path, err := validatedImportPath(s.Path.Value)
+				if err != nil {
+					check.errorf(s.Path, "invalid import path (%s)", err)
+					continue
+				}
+
+				imp := check.importPackage(s.Path.Pos(), path, fileDir)
+				if imp == nil {
+					continue
+				}
+
+				// local name overrides imported package name
+				name := imp.name
+				if s.LocalPkgName != nil {
+					name = s.LocalPkgName.Value
+					if path == "C" {
+						// match cmd/compile (not prescribed by spec)
+						check.error(s.LocalPkgName, `cannot rename import "C"`)
+						continue
+					}
+				}
+
+				if name == "init" {
+					check.error(s.LocalPkgName, "cannot import package as init - init must be a func")
+					continue
+				}
+
+				// add package to list of explicit imports
+				// (this functionality is provided as a convenience
+				// for clients; it is not needed for type-checking)
+				if !pkgImports[imp] {
+					pkgImports[imp] = true
+					pkg.imports = append(pkg.imports, imp)
+				}
+
+				pkgName := NewPkgName(s.Pos(), pkg, name, imp)
+				if s.LocalPkgName != nil {
+					// in a dot-import, the dot represents the package
+					check.recordDef(s.LocalPkgName, pkgName)
+				} else {
+					check.recordImplicit(s, pkgName)
+				}
+
+				if path == "C" {
+					// match cmd/compile (not prescribed by spec)
+					pkgName.used = true
+				}
+
+				// add import to file scope
+				check.imports = append(check.imports, pkgName)
+				if name == "." {
+					// dot-import
+					if check.dotImportMap == nil {
+						check.dotImportMap = make(map[dotImportKey]*PkgName)
+					}
+					// merge imported scope with file scope
+					for _, obj := range imp.scope.elems {
+						// A package scope may contain non-exported objects,
+						// do not import them!
+						if obj.Exported() {
+							// declare dot-imported object
+							// (Do not use check.declare because it modifies the object
+							// via Object.setScopePos, which leads to a race condition;
+							// the object may be imported into more than one file scope
+							// concurrently. See issue #32154.)
+							if alt := fileScope.Insert(obj); alt != nil {
+								var err error_
+								err.errorf(s.LocalPkgName, "%s redeclared in this block", obj.Name())
+								err.recordAltDecl(alt)
+								check.report(&err)
+							} else {
+								check.dotImportMap[dotImportKey{fileScope, obj}] = pkgName
+							}
+						}
+					}
+				} else {
+					// declare imported package object in file scope
+					// (no need to provide s.LocalPkgName since we called check.recordDef earlier)
+					check.declare(fileScope, nil, pkgName, nopos)
+				}
+
+			case *syntax.ConstDecl:
+				// iota is the index of the current constDecl within the group
+				if first < 0 || file.DeclList[index-1].(*syntax.ConstDecl).Group != s.Group {
+					first = index
+					last = nil
+				}
+				iota := constant.MakeInt64(int64(index - first))
+
+				// determine which initialization expressions to use
+				inherited := true
+				switch {
+				case s.Type != nil || s.Values != nil:
+					last = s
+					inherited = false
+				case last == nil:
+					last = new(syntax.ConstDecl) // make sure last exists
+					inherited = false
+				}
+
+				// declare all constants
+				values := unpackExpr(last.Values)
+				for i, name := range s.NameList {
+					obj := NewConst(name.Pos(), pkg, name.Value, nil, iota)
+
+					var init syntax.Expr
+					if i < len(values) {
+						init = values[i]
+					}
+
+					d := &declInfo{file: fileScope, vtyp: last.Type, init: init, inherited: inherited}
+					check.declarePkgObj(name, obj, d)
+				}
+
+				// Constants must always have init values.
+				check.arity(s.Pos(), s.NameList, values, true, inherited)
+
+			case *syntax.VarDecl:
+				lhs := make([]*Var, len(s.NameList))
+				// If there's exactly one rhs initializer, use
+				// the same declInfo d1 for all lhs variables
+				// so that each lhs variable depends on the same
+				// rhs initializer (n:1 var declaration).
+				var d1 *declInfo
+				if _, ok := s.Values.(*syntax.ListExpr); !ok {
+					// The lhs elements are only set up after the for loop below,
+					// but that's ok because declarePkgObj only collects the declInfo
+					// for a later phase.
+					d1 = &declInfo{file: fileScope, lhs: lhs, vtyp: s.Type, init: s.Values}
+				}
+
+				// declare all variables
+				values := unpackExpr(s.Values)
+				for i, name := range s.NameList {
+					obj := NewVar(name.Pos(), pkg, name.Value, nil)
+					lhs[i] = obj
+
+					d := d1
+					if d == nil {
+						// individual assignments
+						var init syntax.Expr
+						if i < len(values) {
+							init = values[i]
+						}
+						d = &declInfo{file: fileScope, vtyp: s.Type, init: init}
+					}
+
+					check.declarePkgObj(name, obj, d)
+				}
+
+				// If we have no type, we must have values.
+				if s.Type == nil || values != nil {
+					check.arity(s.Pos(), s.NameList, values, false, false)
+				}
+
+			case *syntax.TypeDecl:
+				obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Value, nil)
+				check.declarePkgObj(s.Name, obj, &declInfo{file: fileScope, tdecl: s})
+
+			case *syntax.FuncDecl:
+				d := s // TODO(gri) get rid of this
+				name := d.Name.Value
+				obj := NewFunc(d.Name.Pos(), pkg, name, nil)
+				if d.Recv == nil {
+					// regular function
+					if name == "init" || name == "main" && pkg.name == "main" {
+						if d.TParamList != nil {
+							check.softErrorf(d, "func %s must have no type parameters", name)
+						}
+						if t := d.Type; len(t.ParamList) != 0 || len(t.ResultList) != 0 {
+							check.softErrorf(d, "func %s must have no arguments and no return values", name)
+						}
+					}
+					// don't declare init functions in the package scope - they are invisible
+					if name == "init" {
+						obj.parent = pkg.scope
+						check.recordDef(d.Name, obj)
+						// init functions must have a body
+						if d.Body == nil {
+							// TODO(gri) make this error message consistent with the others above
+							check.softErrorf(obj.pos, "missing function body")
+						}
+					} else {
+						check.declare(pkg.scope, d.Name, obj, nopos)
+					}
+				} else {
+					// method
+					// d.Recv != nil
+					if !acceptMethodTypeParams && len(d.TParamList) != 0 {
+						//check.error(d.TParamList.Pos(), invalidAST + "method must have no type parameters")
+						check.error(d, invalidAST+"method must have no type parameters")
+					}
+					ptr, recv, _ := check.unpackRecv(d.Recv.Type, false)
+					// (Methods with invalid receiver cannot be associated to a type, and
+					// methods with blank _ names are never found; no need to collect any
+					// of them. They will still be type-checked with all the other functions.)
+					if recv != nil && name != "_" {
+						methods = append(methods, methodInfo{obj, ptr, recv})
+					}
+					check.recordDef(d.Name, obj)
+				}
+				info := &declInfo{file: fileScope, fdecl: d}
+				// Methods are not package-level objects but we still track them in the
+				// object map so that we can handle them like regular functions (if the
+				// receiver is invalid); also we need their fdecl info when associating
+				// them with their receiver base type, below.
+				check.objMap[obj] = info
+				obj.setOrder(uint32(len(check.objMap)))
+
+			default:
+				check.errorf(s, invalidAST+"unknown syntax.Decl node %T", s)
+			}
+		}
+	}
+
+	// verify that objects in package and file scopes have different names
+	for _, scope := range fileScopes {
+		for _, obj := range scope.elems {
+			if alt := pkg.scope.Lookup(obj.Name()); alt != nil {
+				var err error_
+				if pkg, ok := obj.(*PkgName); ok {
+					err.errorf(alt, "%s already declared through import of %s", alt.Name(), pkg.Imported())
+					err.recordAltDecl(pkg)
+				} else {
+					err.errorf(alt, "%s already declared through dot-import of %s", alt.Name(), obj.Pkg())
+					// TODO(gri) dot-imported objects don't have a position; recordAltDecl won't print anything
+					err.recordAltDecl(obj)
+				}
+				check.report(&err)
+			}
+		}
+	}
+
+	// Now that we have all package scope objects and all methods,
+	// associate methods with receiver base type name where possible.
+	// Ignore methods that have an invalid receiver. They will be
+	// type-checked later, with regular functions.
+	if methods != nil {
+		check.methods = make(map[*TypeName][]*Func)
+		for i := range methods {
+			m := &methods[i]
+			// Determine the receiver base type and associate m with it.
+			ptr, base := check.resolveBaseTypeName(m.ptr, m.recv)
+			if base != nil {
+				m.obj.hasPtrRecv = ptr
+				check.methods[base] = append(check.methods[base], m.obj)
+			}
+		}
+	}
+}
+
+// unpackRecv unpacks a receiver type and returns its components: ptr indicates whether
+// rtyp is a pointer receiver, rname is the receiver type name, and tparams are its
+// type parameters, if any. The type parameters are only unpacked if unpackParams is
+// set. If rname is nil, the receiver is unusable (i.e., the source has a bug which we
+// cannot easily work around).
+func (check *Checker) unpackRecv(rtyp syntax.Expr, unpackParams bool) (ptr bool, rname *syntax.Name, tparams []*syntax.Name) {
+L: // unpack receiver type
+	// This accepts invalid receivers such as ***T and does not
+	// work for other invalid receivers, but we don't care. The
+	// validity of receiver expressions is checked elsewhere.
+	for {
+		switch t := rtyp.(type) {
+		case *syntax.ParenExpr:
+			rtyp = t.X
+		// case *ast.StarExpr:
+		//      ptr = true
+		// 	rtyp = t.X
+		case *syntax.Operation:
+			if t.Op != syntax.Mul || t.Y != nil {
+				break
+			}
+			ptr = true
+			rtyp = t.X
+		default:
+			break L
+		}
+	}
+
+	// unpack type parameters, if any
+	if ptyp, _ := rtyp.(*syntax.IndexExpr); ptyp != nil {
+		rtyp = ptyp.X
+		if unpackParams {
+			for _, arg := range unpackExpr(ptyp.Index) {
+				var par *syntax.Name
+				switch arg := arg.(type) {
+				case *syntax.Name:
+					par = arg
+				case *syntax.BadExpr:
+					// ignore - error already reported by parser
+				case nil:
+					check.error(ptyp, invalidAST+"parameterized receiver contains nil parameters")
+				default:
+					check.errorf(arg, "receiver type parameter %s must be an identifier", arg)
+				}
+				if par == nil {
+					par = syntax.NewName(arg.Pos(), "_")
+				}
+				tparams = append(tparams, par)
+			}
+
+		}
+	}
+
+	// unpack receiver name
+	if name, _ := rtyp.(*syntax.Name); name != nil {
+		rname = name
+	}
+
+	return
+}
+
+// resolveBaseTypeName returns the non-alias base type name for typ, and whether
+// there was a pointer indirection to get to it. The base type name must be declared
+// in package scope, and there can be at most one pointer indirection. If no such type
+// name exists, the returned base is nil.
+func (check *Checker) resolveBaseTypeName(seenPtr bool, typ syntax.Expr) (ptr bool, base *TypeName) {
+	// Algorithm: Starting from a type expression, which may be a name,
+	// we follow that type through alias declarations until we reach a
+	// non-alias type name. If we encounter anything but pointer types or
+	// parentheses we're done. If we encounter more than one pointer type
+	// we're done.
+	ptr = seenPtr
+	var seen map[*TypeName]bool
+	for {
+		typ = unparen(typ)
+
+		// check if we have a pointer type
+		// if pexpr, _ := typ.(*ast.StarExpr); pexpr != nil {
+		if pexpr, _ := typ.(*syntax.Operation); pexpr != nil && pexpr.Op == syntax.Mul && pexpr.Y == nil {
+			// if we've already seen a pointer, we're done
+			if ptr {
+				return false, nil
+			}
+			ptr = true
+			typ = unparen(pexpr.X) // continue with pointer base type
+		}
+
+		// typ must be a name
+		name, _ := typ.(*syntax.Name)
+		if name == nil {
+			return false, nil
+		}
+
+		// name must denote an object found in the current package scope
+		// (note that dot-imported objects are not in the package scope!)
+		obj := check.pkg.scope.Lookup(name.Value)
+		if obj == nil {
+			return false, nil
+		}
+
+		// the object must be a type name...
+		tname, _ := obj.(*TypeName)
+		if tname == nil {
+			return false, nil
+		}
+
+		// ... which we have not seen before
+		if seen[tname] {
+			return false, nil
+		}
+
+		// we're done if tdecl defined tname as a new type
+		// (rather than an alias)
+		tdecl := check.objMap[tname].tdecl // must exist for objects in package scope
+		if !tdecl.Alias {
+			return ptr, tname
+		}
+
+		// otherwise, continue resolving
+		typ = tdecl.Type
+		if seen == nil {
+			seen = make(map[*TypeName]bool)
+		}
+		seen[tname] = true
+	}
+}
+
+// packageObjects typechecks all package objects, but not function bodies.
+func (check *Checker) packageObjects() {
+	// process package objects in source order for reproducible results
+	objList := make([]Object, len(check.objMap))
+	i := 0
+	for obj := range check.objMap {
+		objList[i] = obj
+		i++
+	}
+	sort.Sort(inSourceOrder(objList))
+
+	// add new methods to already type-checked types (from a prior Checker.Files call)
+	for _, obj := range objList {
+		if obj, _ := obj.(*TypeName); obj != nil && obj.typ != nil {
+			check.collectMethods(obj)
+		}
+	}
+
+	// We process non-alias declarations first, in order to avoid situations where
+	// the type of an alias declaration is needed before it is available. In general
+	// this is still not enough, as it is possible to create sufficiently convoluted
+	// recursive type definitions that will cause a type alias to be needed before it
+	// is available (see issue #25838 for examples).
+	// As an aside, the cmd/compiler suffers from the same problem (#25838).
+	var aliasList []*TypeName
+	// phase 1
+	for _, obj := range objList {
+		// If we have a type alias, collect it for the 2nd phase.
+		if tname, _ := obj.(*TypeName); tname != nil && check.objMap[tname].tdecl.Alias {
+			aliasList = append(aliasList, tname)
+			continue
+		}
+
+		check.objDecl(obj, nil)
+	}
+	// phase 2
+	for _, obj := range aliasList {
+		check.objDecl(obj, nil)
+	}
+
+	// At this point we may have a non-empty check.methods map; this means that not all
+	// entries were deleted at the end of typeDecl because the respective receiver base
+	// types were not found. In that case, an error was reported when declaring those
+	// methods. We can now safely discard this map.
+	check.methods = nil
+}
+
+// inSourceOrder implements the sort.Sort interface.
+type inSourceOrder []Object
+
+func (a inSourceOrder) Len() int           { return len(a) }
+func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() }
+func (a inSourceOrder) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+
+// unusedImports checks for unused imports.
+func (check *Checker) unusedImports() {
+	// if function bodies are not checked, packages' uses are likely missing - don't check
+	if check.conf.IgnoreFuncBodies {
+		return
+	}
+
+	// spec: "It is illegal (...) to directly import a package without referring to
+	// any of its exported identifiers. To import a package solely for its side-effects
+	// (initialization), use the blank identifier as explicit package name."
+
+	for _, obj := range check.imports {
+		if !obj.used && obj.name != "_" {
+			check.errorUnusedPkg(obj)
+		}
+	}
+}
+
+func (check *Checker) errorUnusedPkg(obj *PkgName) {
+	// If the package was imported with a name other than the final
+	// import path element, show it explicitly in the error message.
+	// Note that this handles both renamed imports and imports of
+	// packages containing unconventional package declarations.
+	// Note that this uses / always, even on Windows, because Go import
+	// paths always use forward slashes.
+	path := obj.imported.path
+	elem := path
+	if i := strings.LastIndex(elem, "/"); i >= 0 {
+		elem = elem[i+1:]
+	}
+	if obj.name == "" || obj.name == "." || obj.name == elem {
+		if check.conf.CompilerErrorMessages {
+			check.softErrorf(obj, "imported and not used: %q", path)
+		} else {
+			check.softErrorf(obj, "%q imported but not used", path)
+		}
+	} else {
+		if check.conf.CompilerErrorMessages {
+			check.softErrorf(obj, "imported and not used: %q as %s", path, obj.name)
+		} else {
+			check.softErrorf(obj, "%q imported but not used as %s", path, obj.name)
+		}
+	}
+}
+
+// dir makes a good-faith attempt to return the directory
+// portion of path. If path is empty, the result is ".".
+// (Per the go/build package dependency tests, we cannot import
+// path/filepath and simply use filepath.Dir.)
+func dir(path string) string {
+	if i := strings.LastIndexAny(path, `/\`); i > 0 {
+		return path[:i]
+	}
+	// i <= 0
+	return "."
+}
diff --git a/src/cmd/compile/internal/types2/resolver_test.go b/src/cmd/compile/internal/types2/resolver_test.go
new file mode 100644
index 0000000..aee435f
--- /dev/null
+++ b/src/cmd/compile/internal/types2/resolver_test.go
@@ -0,0 +1,222 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2_test
+
+import (
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"internal/testenv"
+	"sort"
+	"testing"
+
+	. "cmd/compile/internal/types2"
+)
+
+type resolveTestImporter struct {
+	importer ImporterFrom
+	imported map[string]bool
+}
+
+func (imp *resolveTestImporter) Import(string) (*Package, error) {
+	panic("should not be called")
+}
+
+func (imp *resolveTestImporter) ImportFrom(path, srcDir string, mode ImportMode) (*Package, error) {
+	if mode != 0 {
+		panic("mode must be 0")
+	}
+	if imp.importer == nil {
+		imp.importer = defaultImporter().(ImporterFrom)
+		imp.imported = make(map[string]bool)
+	}
+	pkg, err := imp.importer.ImportFrom(path, srcDir, mode)
+	if err != nil {
+		return nil, err
+	}
+	imp.imported[path] = true
+	return pkg, nil
+}
+
+func TestResolveIdents(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	sources := []string{
+		`
+		package p
+		import "fmt"
+		import "math"
+		const pi = math.Pi
+		func sin(x float64) float64 {
+			return math.Sin(x)
+		}
+		var Println = fmt.Println
+		`,
+		`
+		package p
+		import "fmt"
+		type errorStringer struct { fmt.Stringer; error }
+		func f() string {
+			_ = "foo"
+			return fmt.Sprintf("%d", g())
+		}
+		func g() (x int) { return }
+		`,
+		`
+		package p
+		import . "go/parser"
+		import "sync"
+		func h() Mode { return ImportsOnly }
+		var _, x int = 1, 2
+		func init() {}
+		type T struct{ *sync.Mutex; a, b, c int}
+		type I interface{ m() }
+		var _ = T{a: 1, b: 2, c: 3}
+		func (_ T) m() {}
+		func (T) _() {}
+		var i I
+		var _ = i.m
+		func _(s []int) { for i, x := range s { _, _ = i, x } }
+		func _(x interface{}) {
+			switch x := x.(type) {
+			case int:
+				_ = x
+			}
+			switch {} // implicit 'true' tag
+		}
+		`,
+		`
+		package p
+		type S struct{}
+		func (T) _() {}
+		func (T) _() {}
+		`,
+		`
+		package p
+		func _() {
+		L0:
+		L1:
+			goto L0
+			for {
+				goto L1
+			}
+			if true {
+				goto L2
+			}
+		L2:
+		}
+		`,
+	}
+
+	pkgnames := []string{
+		"fmt",
+		"math",
+	}
+
+	// parse package files
+	var files []*syntax.File
+	for i, src := range sources {
+		f, err := parseSrc(fmt.Sprintf("sources[%d]", i), src)
+		if err != nil {
+			t.Fatal(err)
+		}
+		files = append(files, f)
+	}
+
+	// resolve and type-check package AST
+	importer := new(resolveTestImporter)
+	conf := Config{Importer: importer}
+	uses := make(map[*syntax.Name]Object)
+	defs := make(map[*syntax.Name]Object)
+	_, err := conf.Check("testResolveIdents", files, &Info{Defs: defs, Uses: uses})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// check that all packages were imported
+	for _, name := range pkgnames {
+		if !importer.imported[name] {
+			t.Errorf("package %s not imported", name)
+		}
+	}
+
+	// check that qualified identifiers are resolved
+	for _, f := range files {
+		syntax.Walk(f, func(n syntax.Node) bool {
+			if s, ok := n.(*syntax.SelectorExpr); ok {
+				if x, ok := s.X.(*syntax.Name); ok {
+					obj := uses[x]
+					if obj == nil {
+						t.Errorf("%s: unresolved qualified identifier %s", x.Pos(), x.Value)
+						return true
+					}
+					if _, ok := obj.(*PkgName); ok && uses[s.Sel] == nil {
+						t.Errorf("%s: unresolved selector %s", s.Sel.Pos(), s.Sel.Value)
+						return true
+					}
+					return true
+				}
+				return true
+			}
+			return false
+		})
+	}
+
+	for id, obj := range uses {
+		if obj == nil {
+			t.Errorf("%s: Uses[%s] == nil", id.Pos(), id.Value)
+		}
+	}
+
+	// Check that each identifier in the source is found in uses or defs or both.
+	// We need the foundUses/Defs maps (rather then just deleting the found objects
+	// from the uses and defs maps) because syntax.Walk traverses shared nodes multiple
+	// times (e.g. types in field lists such as "a, b, c int").
+	foundUses := make(map[*syntax.Name]bool)
+	foundDefs := make(map[*syntax.Name]bool)
+	var both []string
+	for _, f := range files {
+		syntax.Walk(f, func(n syntax.Node) bool {
+			if x, ok := n.(*syntax.Name); ok {
+				var objects int
+				if _, found := uses[x]; found {
+					objects |= 1
+					foundUses[x] = true
+				}
+				if _, found := defs[x]; found {
+					objects |= 2
+					foundDefs[x] = true
+				}
+				switch objects {
+				case 0:
+					t.Errorf("%s: unresolved identifier %s", x.Pos(), x.Value)
+				case 3:
+					both = append(both, x.Value)
+				}
+				return true
+			}
+			return false
+		})
+	}
+
+	// check the expected set of idents that are simultaneously uses and defs
+	sort.Strings(both)
+	if got, want := fmt.Sprint(both), "[Mutex Stringer error]"; got != want {
+		t.Errorf("simultaneous uses/defs = %s, want %s", got, want)
+	}
+
+	// any left-over identifiers didn't exist in the source
+	for x := range uses {
+		if !foundUses[x] {
+			t.Errorf("%s: identifier %s not present in source", x.Pos(), x.Value)
+		}
+	}
+	for x := range defs {
+		if !foundDefs[x] {
+			t.Errorf("%s: identifier %s not present in source", x.Pos(), x.Value)
+		}
+	}
+
+	// TODO(gri) add tests to check ImplicitObj callbacks
+}
diff --git a/src/cmd/compile/internal/types2/return.go b/src/cmd/compile/internal/types2/return.go
new file mode 100644
index 0000000..204e456
--- /dev/null
+++ b/src/cmd/compile/internal/types2/return.go
@@ -0,0 +1,179 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements isTerminating.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+)
+
+// isTerminating reports if s is a terminating statement.
+// If s is labeled, label is the label name; otherwise s
+// is "".
+func (check *Checker) isTerminating(s syntax.Stmt, label string) bool {
+	switch s := s.(type) {
+	default:
+		unreachable()
+
+	case *syntax.DeclStmt, *syntax.EmptyStmt, *syntax.SendStmt,
+		*syntax.AssignStmt, *syntax.CallStmt:
+		// no chance
+
+	case *syntax.LabeledStmt:
+		return check.isTerminating(s.Stmt, s.Label.Value)
+
+	case *syntax.ExprStmt:
+		// calling the predeclared (possibly parenthesized) panic() function is terminating
+		if call, ok := unparen(s.X).(*syntax.CallExpr); ok && check.isPanic[call] {
+			return true
+		}
+
+	case *syntax.ReturnStmt:
+		return true
+
+	case *syntax.BranchStmt:
+		if s.Tok == syntax.Goto || s.Tok == syntax.Fallthrough {
+			return true
+		}
+
+	case *syntax.BlockStmt:
+		return check.isTerminatingList(s.List, "")
+
+	case *syntax.IfStmt:
+		if s.Else != nil &&
+			check.isTerminating(s.Then, "") &&
+			check.isTerminating(s.Else, "") {
+			return true
+		}
+
+	case *syntax.SwitchStmt:
+		return check.isTerminatingSwitch(s.Body, label)
+
+	case *syntax.SelectStmt:
+		for _, cc := range s.Body {
+			if !check.isTerminatingList(cc.Body, "") || hasBreakList(cc.Body, label, true) {
+				return false
+			}
+
+		}
+		return true
+
+	case *syntax.ForStmt:
+		if s.Cond == nil && !hasBreak(s.Body, label, true) {
+			return true
+		}
+	}
+
+	return false
+}
+
+func (check *Checker) isTerminatingList(list []syntax.Stmt, label string) bool {
+	// trailing empty statements are permitted - skip them
+	for i := len(list) - 1; i >= 0; i-- {
+		if _, ok := list[i].(*syntax.EmptyStmt); !ok {
+			return check.isTerminating(list[i], label)
+		}
+	}
+	return false // all statements are empty
+}
+
+func (check *Checker) isTerminatingSwitch(body []*syntax.CaseClause, label string) bool {
+	hasDefault := false
+	for _, cc := range body {
+		if cc.Cases == nil {
+			hasDefault = true
+		}
+		if !check.isTerminatingList(cc.Body, "") || hasBreakList(cc.Body, label, true) {
+			return false
+		}
+	}
+	return hasDefault
+}
+
+// TODO(gri) For nested breakable statements, the current implementation of hasBreak
+//	     will traverse the same subtree repeatedly, once for each label. Replace
+//           with a single-pass label/break matching phase.
+
+// hasBreak reports if s is or contains a break statement
+// referring to the label-ed statement or implicit-ly the
+// closest outer breakable statement.
+func hasBreak(s syntax.Stmt, label string, implicit bool) bool {
+	switch s := s.(type) {
+	default:
+		unreachable()
+
+	case *syntax.DeclStmt, *syntax.EmptyStmt, *syntax.ExprStmt,
+		*syntax.SendStmt, *syntax.AssignStmt, *syntax.CallStmt,
+		*syntax.ReturnStmt:
+		// no chance
+
+	case *syntax.LabeledStmt:
+		return hasBreak(s.Stmt, label, implicit)
+
+	case *syntax.BranchStmt:
+		if s.Tok == syntax.Break {
+			if s.Label == nil {
+				return implicit
+			}
+			if s.Label.Value == label {
+				return true
+			}
+		}
+
+	case *syntax.BlockStmt:
+		return hasBreakList(s.List, label, implicit)
+
+	case *syntax.IfStmt:
+		if hasBreak(s.Then, label, implicit) ||
+			s.Else != nil && hasBreak(s.Else, label, implicit) {
+			return true
+		}
+
+	case *syntax.SwitchStmt:
+		if label != "" && hasBreakCaseList(s.Body, label, false) {
+			return true
+		}
+
+	case *syntax.SelectStmt:
+		if label != "" && hasBreakCommList(s.Body, label, false) {
+			return true
+		}
+
+	case *syntax.ForStmt:
+		if label != "" && hasBreak(s.Body, label, false) {
+			return true
+		}
+	}
+
+	return false
+}
+
+func hasBreakList(list []syntax.Stmt, label string, implicit bool) bool {
+	for _, s := range list {
+		if hasBreak(s, label, implicit) {
+			return true
+		}
+	}
+	return false
+}
+
+func hasBreakCaseList(list []*syntax.CaseClause, label string, implicit bool) bool {
+	for _, s := range list {
+		if hasBreakList(s.Body, label, implicit) {
+			return true
+		}
+	}
+	return false
+}
+
+func hasBreakCommList(list []*syntax.CommClause, label string, implicit bool) bool {
+	for _, s := range list {
+		if hasBreakList(s.Body, label, implicit) {
+			return true
+		}
+	}
+	return false
+}
diff --git a/src/cmd/compile/internal/types2/sanitize.go b/src/cmd/compile/internal/types2/sanitize.go
new file mode 100644
index 0000000..64a2ded
--- /dev/null
+++ b/src/cmd/compile/internal/types2/sanitize.go
@@ -0,0 +1,202 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+// sanitizeInfo walks the types contained in info to ensure that all instances
+// are expanded.
+//
+// This includes some objects that may be shared across concurrent
+// type-checking passes (such as those in the universe scope), so we are
+// careful here not to write types that are already sanitized. This avoids a
+// data race as any shared types should already be sanitized.
+func sanitizeInfo(info *Info) {
+	var s sanitizer = make(map[Type]Type)
+
+	// Note: Some map entries are not references.
+	// If modified, they must be assigned back.
+
+	for e, tv := range info.Types {
+		if typ := s.typ(tv.Type); typ != tv.Type {
+			tv.Type = typ
+			info.Types[e] = tv
+		}
+	}
+
+	for e, inf := range info.Inferred {
+		changed := false
+		for i, targ := range inf.Targs {
+			if typ := s.typ(targ); typ != targ {
+				inf.Targs[i] = typ
+				changed = true
+			}
+		}
+		if typ := s.typ(inf.Sig); typ != inf.Sig {
+			inf.Sig = typ.(*Signature)
+			changed = true
+		}
+		if changed {
+			info.Inferred[e] = inf
+		}
+	}
+
+	for _, obj := range info.Defs {
+		if obj != nil {
+			if typ := s.typ(obj.Type()); typ != obj.Type() {
+				obj.setType(typ)
+			}
+		}
+	}
+
+	for _, obj := range info.Uses {
+		if obj != nil {
+			if typ := s.typ(obj.Type()); typ != obj.Type() {
+				obj.setType(typ)
+			}
+		}
+	}
+
+	// TODO(gri) sanitize as needed
+	// - info.Implicits
+	// - info.Selections
+	// - info.Scopes
+	// - info.InitOrder
+}
+
+type sanitizer map[Type]Type
+
+func (s sanitizer) typ(typ Type) Type {
+	if typ == nil {
+		return nil
+	}
+
+	if t, found := s[typ]; found {
+		return t
+	}
+	s[typ] = typ
+
+	switch t := typ.(type) {
+	case *Basic, *bottom, *top:
+		// nothing to do
+
+	case *Array:
+		if elem := s.typ(t.elem); elem != t.elem {
+			t.elem = elem
+		}
+
+	case *Slice:
+		if elem := s.typ(t.elem); elem != t.elem {
+			t.elem = elem
+		}
+
+	case *Struct:
+		s.varList(t.fields)
+
+	case *Pointer:
+		if base := s.typ(t.base); base != t.base {
+			t.base = base
+		}
+
+	case *Tuple:
+		s.tuple(t)
+
+	case *Signature:
+		s.var_(t.recv)
+		s.tuple(t.params)
+		s.tuple(t.results)
+
+	case *Sum:
+		s.typeList(t.types)
+
+	case *Interface:
+		s.funcList(t.methods)
+		if types := s.typ(t.types); types != t.types {
+			t.types = types
+		}
+		s.typeList(t.embeddeds)
+		s.funcList(t.allMethods)
+		if allTypes := s.typ(t.allTypes); allTypes != t.allTypes {
+			t.allTypes = allTypes
+		}
+
+	case *Map:
+		if key := s.typ(t.key); key != t.key {
+			t.key = key
+		}
+		if elem := s.typ(t.elem); elem != t.elem {
+			t.elem = elem
+		}
+
+	case *Chan:
+		if elem := s.typ(t.elem); elem != t.elem {
+			t.elem = elem
+		}
+
+	case *Named:
+		if orig := s.typ(t.fromRHS); orig != t.fromRHS {
+			t.fromRHS = orig
+		}
+		if under := s.typ(t.underlying); under != t.underlying {
+			t.underlying = under
+		}
+		s.typeList(t.targs)
+		s.funcList(t.methods)
+
+	case *TypeParam:
+		if bound := s.typ(t.bound); bound != t.bound {
+			t.bound = bound
+		}
+
+	case *instance:
+		typ = t.expand()
+		s[t] = typ
+
+	default:
+		panic("unimplemented")
+	}
+
+	return typ
+}
+
+func (s sanitizer) var_(v *Var) {
+	if v != nil {
+		if typ := s.typ(v.typ); typ != v.typ {
+			v.typ = typ
+		}
+	}
+}
+
+func (s sanitizer) varList(list []*Var) {
+	for _, v := range list {
+		s.var_(v)
+	}
+}
+
+func (s sanitizer) tuple(t *Tuple) {
+	if t != nil {
+		s.varList(t.vars)
+	}
+}
+
+func (s sanitizer) func_(f *Func) {
+	if f != nil {
+		if typ := s.typ(f.typ); typ != f.typ {
+			f.typ = typ
+		}
+	}
+}
+
+func (s sanitizer) funcList(list []*Func) {
+	for _, f := range list {
+		s.func_(f)
+	}
+}
+
+func (s sanitizer) typeList(list []Type) {
+	for i, t := range list {
+		if typ := s.typ(t); typ != t {
+			list[i] = typ
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/types2/scope.go b/src/cmd/compile/internal/types2/scope.go
new file mode 100644
index 0000000..ade0a79
--- /dev/null
+++ b/src/cmd/compile/internal/types2/scope.go
@@ -0,0 +1,216 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements Scopes.
+
+package types2
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"io"
+	"sort"
+	"strings"
+)
+
+// A Scope maintains a set of objects and links to its containing
+// (parent) and contained (children) scopes. Objects may be inserted
+// and looked up by name. The zero value for Scope is a ready-to-use
+// empty scope.
+type Scope struct {
+	parent   *Scope
+	children []*Scope
+	elems    map[string]Object // lazily allocated
+	pos, end syntax.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 syntax.Pos, comment string) *Scope {
+	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)
+	}
+	return s
+}
+
+// Parent returns the scope's containing (parent) scope.
+func (s *Scope) Parent() *Scope { return s.parent }
+
+// Len returns the number of scope elements.
+func (s *Scope) Len() int { return len(s.elems) }
+
+// Names returns the scope's element names in sorted order.
+func (s *Scope) Names() []string {
+	names := make([]string, len(s.elems))
+	i := 0
+	for name := range s.elems {
+		names[i] = name
+		i++
+	}
+	sort.Strings(names)
+	return names
+}
+
+// NumChildren returns the number of scopes nested in s.
+func (s *Scope) NumChildren() int { return len(s.children) }
+
+// Child returns the i'th child scope for 0 <= i < NumChildren().
+func (s *Scope) Child(i int) *Scope { return s.children[i] }
+
+// Lookup returns the object in scope s with the given name if such an
+// object exists; otherwise the result is nil.
+func (s *Scope) Lookup(name string) Object {
+	return s.elems[name]
+}
+
+// LookupParent follows the parent chain of scopes starting with s until
+// it finds a scope where Lookup(name) returns a non-nil object, and then
+// returns that scope and object. If a valid position pos is provided,
+// only objects that were declared at or before pos are considered.
+// If no such scope and object exists, the result is (nil, nil).
+//
+// Note that obj.Parent() may be different from the returned scope if the
+// object was inserted into the scope and already had a parent at that
+// time (see Insert). This can only happen for dot-imported objects
+// whose scope is the scope of the package that exported them.
+func (s *Scope) LookupParent(name string, pos syntax.Pos) (*Scope, Object) {
+	for ; s != nil; s = s.parent {
+		if obj := s.elems[name]; obj != nil && (!pos.IsKnown() || obj.scopePos().Cmp(pos) <= 0) {
+			return s, obj
+		}
+	}
+	return nil, nil
+}
+
+// Insert attempts to insert an object obj into scope s.
+// If s already contains an alternative object alt with
+// the same name, Insert leaves s unchanged and returns alt.
+// Otherwise it inserts obj, sets the object's parent scope
+// if not already set, and returns nil.
+func (s *Scope) Insert(obj Object) Object {
+	name := obj.Name()
+	if alt := s.elems[name]; alt != nil {
+		return alt
+	}
+	if s.elems == nil {
+		s.elems = make(map[string]Object)
+	}
+	s.elems[name] = obj
+	if obj.Parent() == nil {
+		obj.setParent(s)
+	}
+	return nil
+}
+
+// Squash merges s with its parent scope p by adding all
+// objects of s to p, adding all children of s to the
+// children of p, and removing s from p's children.
+// The function f is called for each object obj in s which
+// has an object alt in p. s should be discarded after
+// having been squashed.
+func (s *Scope) Squash(err func(obj, alt Object)) {
+	p := s.parent
+	assert(p != nil)
+	for _, obj := range s.elems {
+		obj.setParent(nil)
+		if alt := p.Insert(obj); alt != nil {
+			err(obj, alt)
+		}
+	}
+
+	j := -1 // index of s in p.children
+	for i, ch := range p.children {
+		if ch == s {
+			j = i
+			break
+		}
+	}
+	assert(j >= 0)
+	k := len(p.children) - 1
+	p.children[j] = p.children[k]
+	p.children = p.children[:k]
+
+	p.children = append(p.children, s.children...)
+
+	s.children = nil
+	s.elems = nil
+}
+
+// Pos and End describe the scope's source code extent [pos, end).
+// The results are guaranteed to be valid only if the type-checked
+// AST has complete position information. The extent is undefined
+// for Universe and package scopes.
+func (s *Scope) Pos() syntax.Pos { return s.pos }
+func (s *Scope) End() syntax.Pos { return s.end }
+
+// Contains reports whether pos is within the scope's extent.
+// The result is guaranteed to be valid only if the type-checked
+// AST has complete position information.
+func (s *Scope) Contains(pos syntax.Pos) bool {
+	return s.pos.Cmp(pos) <= 0 && pos.Cmp(s.end) < 0
+}
+
+// Innermost returns the innermost (child) scope containing
+// pos. If pos is not within any scope, the result is nil.
+// The result is also nil for the Universe scope.
+// The result is guaranteed to be valid only if the type-checked
+// AST has complete position information.
+func (s *Scope) Innermost(pos syntax.Pos) *Scope {
+	// Package scopes do not have extents since they may be
+	// discontiguous, so iterate over the package's files.
+	if s.parent == Universe {
+		for _, s := range s.children {
+			if inner := s.Innermost(pos); inner != nil {
+				return inner
+			}
+		}
+	}
+
+	if s.Contains(pos) {
+		for _, s := range s.children {
+			if s.Contains(pos) {
+				return s.Innermost(pos)
+			}
+		}
+		return s
+	}
+	return nil
+}
+
+// WriteTo writes a string representation of the scope to w,
+// with the scope elements sorted by name.
+// The level of indentation is controlled by n >= 0, with
+// n == 0 for no indentation.
+// If recurse is set, it also writes nested (children) scopes.
+func (s *Scope) WriteTo(w io.Writer, n int, recurse bool) {
+	const ind = ".  "
+	indn := strings.Repeat(ind, n)
+
+	fmt.Fprintf(w, "%s%s scope %p {\n", indn, s.comment, s)
+
+	indn1 := indn + ind
+	for _, name := range s.Names() {
+		fmt.Fprintf(w, "%s%s\n", indn1, s.elems[name])
+	}
+
+	if recurse {
+		for _, s := range s.children {
+			s.WriteTo(w, n+1, recurse)
+		}
+	}
+
+	fmt.Fprintf(w, "%s}\n", indn)
+}
+
+// String returns a string representation of the scope, for debugging.
+func (s *Scope) String() string {
+	var buf bytes.Buffer
+	s.WriteTo(&buf, 0, false)
+	return buf.String()
+}
diff --git a/src/cmd/compile/internal/types2/selection.go b/src/cmd/compile/internal/types2/selection.go
new file mode 100644
index 0000000..8128aee
--- /dev/null
+++ b/src/cmd/compile/internal/types2/selection.go
@@ -0,0 +1,143 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements Selections.
+
+package types2
+
+import (
+	"bytes"
+	"fmt"
+)
+
+// SelectionKind describes the kind of a selector expression x.f
+// (excluding qualified identifiers).
+type SelectionKind int
+
+const (
+	FieldVal   SelectionKind = iota // x.f is a struct field selector
+	MethodVal                       // x.f is a method selector
+	MethodExpr                      // x.f is a method expression
+)
+
+// A Selection describes a selector expression x.f.
+// For the declarations:
+//
+//	type T struct{ x int; E }
+//	type E struct{}
+//	func (e E) m() {}
+//	var p *T
+//
+// the following relations exist:
+//
+//	Selector    Kind          Recv    Obj    Type       Index     Indirect
+//
+//	p.x         FieldVal      T       x      int        {0}       true
+//	p.m         MethodVal     *T      m      func()     {1, 0}    true
+//	T.m         MethodExpr    T       m      func(T)    {1, 0}    false
+//
+type Selection struct {
+	kind     SelectionKind
+	recv     Type   // type of x
+	obj      Object // object denoted by x.f
+	index    []int  // path from x to x.f
+	indirect bool   // set if there was any pointer indirection on the path
+}
+
+// Kind returns the selection kind.
+func (s *Selection) Kind() SelectionKind { return s.kind }
+
+// Recv returns the type of x in x.f.
+func (s *Selection) Recv() Type { return s.recv }
+
+// Obj returns the object denoted by x.f; a *Var for
+// a field selection, and a *Func in all other cases.
+func (s *Selection) Obj() Object { return s.obj }
+
+// Type returns the type of x.f, which may be different from the type of f.
+// See Selection for more information.
+func (s *Selection) Type() Type {
+	switch s.kind {
+	case MethodVal:
+		// The type of x.f is a method with its receiver type set
+		// to the type of x.
+		sig := *s.obj.(*Func).typ.(*Signature)
+		recv := *sig.recv
+		recv.typ = s.recv
+		sig.recv = &recv
+		return &sig
+
+	case MethodExpr:
+		// The type of x.f is a function (without receiver)
+		// and an additional first argument with the same type as x.
+		// TODO(gri) Similar code is already in call.go - factor!
+		// TODO(gri) Compute this eagerly to avoid allocations.
+		sig := *s.obj.(*Func).typ.(*Signature)
+		arg0 := *sig.recv
+		sig.recv = nil
+		arg0.typ = s.recv
+		var params []*Var
+		if sig.params != nil {
+			params = sig.params.vars
+		}
+		sig.params = NewTuple(append([]*Var{&arg0}, params...)...)
+		return &sig
+	}
+
+	// In all other cases, the type of x.f is the type of x.
+	return s.obj.Type()
+}
+
+// Index describes the path from x to f in x.f.
+// The last index entry is the field or method index of the type declaring f;
+// either:
+//
+//	1) the list of declared methods of a named type; or
+//	2) the list of methods of an interface type; or
+//	3) the list of fields of a struct type.
+//
+// The earlier index entries are the indices of the embedded fields implicitly
+// traversed to get from (the type of) x to f, starting at embedding depth 0.
+func (s *Selection) Index() []int { return s.index }
+
+// Indirect reports whether any pointer indirection was required to get from
+// x to f in x.f.
+func (s *Selection) Indirect() bool { return s.indirect }
+
+func (s *Selection) String() string { return SelectionString(s, nil) }
+
+// SelectionString returns the string form of s.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+//
+// Examples:
+//	"field (T) f int"
+//	"method (T) f(X) Y"
+//	"method expr (T) f(X) Y"
+//
+func SelectionString(s *Selection, qf Qualifier) string {
+	var k string
+	switch s.kind {
+	case FieldVal:
+		k = "field "
+	case MethodVal:
+		k = "method "
+	case MethodExpr:
+		k = "method expr "
+	default:
+		unreachable()
+	}
+	var buf bytes.Buffer
+	buf.WriteString(k)
+	buf.WriteByte('(')
+	WriteType(&buf, s.Recv(), qf)
+	fmt.Fprintf(&buf, ") %s", s.obj.Name())
+	if T := s.Type(); s.kind == FieldVal {
+		buf.WriteByte(' ')
+		WriteType(&buf, T, qf)
+	} else {
+		WriteSignature(&buf, T.(*Signature), qf)
+	}
+	return buf.String()
+}
diff --git a/src/cmd/compile/internal/types2/self_test.go b/src/cmd/compile/internal/types2/self_test.go
new file mode 100644
index 0000000..4722fec
--- /dev/null
+++ b/src/cmd/compile/internal/types2/self_test.go
@@ -0,0 +1,117 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2_test
+
+import (
+	"cmd/compile/internal/syntax"
+	"path"
+	"path/filepath"
+	"runtime"
+	"testing"
+	"time"
+
+	. "cmd/compile/internal/types2"
+)
+
+func TestSelf(t *testing.T) {
+	files, err := pkgFiles(".")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	conf := Config{Importer: defaultImporter()}
+	_, err = conf.Check("cmd/compile/internal/types2", files, nil)
+	if err != nil {
+		// Importing go/constant doesn't work in the
+		// build dashboard environment. Don't report an error
+		// for now so that the build remains green.
+		// TODO(gri) fix this
+		t.Log(err) // replace w/ t.Fatal eventually
+		return
+	}
+}
+
+func BenchmarkCheck(b *testing.B) {
+	for _, p := range []string{
+		filepath.Join("src", "net", "http"),
+		filepath.Join("src", "go", "parser"),
+		filepath.Join("src", "go", "constant"),
+		filepath.Join("src", "go", "internal", "gcimporter"),
+	} {
+		b.Run(path.Base(p), func(b *testing.B) {
+			path := filepath.Join(runtime.GOROOT(), p)
+			for _, ignoreFuncBodies := range []bool{false, true} {
+				name := "funcbodies"
+				if ignoreFuncBodies {
+					name = "nofuncbodies"
+				}
+				b.Run(name, func(b *testing.B) {
+					b.Run("info", func(b *testing.B) {
+						runbench(b, path, ignoreFuncBodies, true)
+					})
+					b.Run("noinfo", func(b *testing.B) {
+						runbench(b, path, ignoreFuncBodies, false)
+					})
+				})
+			}
+		})
+	}
+}
+
+func runbench(b *testing.B, path string, ignoreFuncBodies, writeInfo bool) {
+	files, err := pkgFiles(path)
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	// determine line count
+	var lines uint
+	for _, f := range files {
+		lines += f.EOF.Line()
+	}
+
+	b.ResetTimer()
+	start := time.Now()
+	for i := 0; i < b.N; i++ {
+		conf := Config{
+			IgnoreFuncBodies: ignoreFuncBodies,
+			Importer:         defaultImporter(),
+		}
+		var info *Info
+		if writeInfo {
+			info = &Info{
+				Types:      make(map[syntax.Expr]TypeAndValue),
+				Defs:       make(map[*syntax.Name]Object),
+				Uses:       make(map[*syntax.Name]Object),
+				Implicits:  make(map[syntax.Node]Object),
+				Selections: make(map[*syntax.SelectorExpr]*Selection),
+				Scopes:     make(map[syntax.Node]*Scope),
+			}
+		}
+		if _, err := conf.Check(path, files, info); err != nil {
+			b.Fatal(err)
+		}
+	}
+	b.StopTimer()
+	b.ReportMetric(float64(lines)*float64(b.N)/time.Since(start).Seconds(), "lines/s")
+}
+
+func pkgFiles(path string) ([]*syntax.File, error) {
+	filenames, err := pkgFilenames(path) // from stdlib_test.go
+	if err != nil {
+		return nil, err
+	}
+
+	var files []*syntax.File
+	for _, filename := range filenames {
+		file, err := syntax.ParseFile(filename, nil, nil, 0)
+		if err != nil {
+			return nil, err
+		}
+		files = append(files, file)
+	}
+
+	return files, nil
+}
diff --git a/src/cmd/compile/internal/types2/sizeof_test.go b/src/cmd/compile/internal/types2/sizeof_test.go
new file mode 100644
index 0000000..236feb0
--- /dev/null
+++ b/src/cmd/compile/internal/types2/sizeof_test.go
@@ -0,0 +1,65 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+import (
+	"reflect"
+	"testing"
+)
+
+// Signal size changes of important structures.
+
+func TestSizeof(t *testing.T) {
+	const _64bit = ^uint(0)>>32 != 0
+
+	var tests = []struct {
+		val    interface{} // type as a value
+		_32bit uintptr     // size on 32bit platforms
+		_64bit uintptr     // size on 64bit platforms
+	}{
+		// Types
+		{Basic{}, 16, 32},
+		{Array{}, 16, 24},
+		{Slice{}, 8, 16},
+		{Struct{}, 24, 48},
+		{Pointer{}, 8, 16},
+		{Tuple{}, 12, 24},
+		{Signature{}, 44, 88},
+		{Sum{}, 12, 24},
+		{Interface{}, 60, 120},
+		{Map{}, 16, 32},
+		{Chan{}, 12, 24},
+		{Named{}, 68, 136},
+		{TypeParam{}, 28, 48},
+		{instance{}, 52, 96},
+		{bottom{}, 0, 0},
+		{top{}, 0, 0},
+
+		// Objects
+		{PkgName{}, 64, 104},
+		{Const{}, 64, 104},
+		{TypeName{}, 56, 88},
+		{Var{}, 60, 96},
+		{Func{}, 60, 96},
+		{Label{}, 60, 96},
+		{Builtin{}, 60, 96},
+		{Nil{}, 56, 88},
+
+		// Misc
+		{Scope{}, 56, 96},
+		{Package{}, 40, 80},
+	}
+
+	for _, test := range tests {
+		got := reflect.TypeOf(test.val).Size()
+		want := test._32bit
+		if _64bit {
+			want = test._64bit
+		}
+		if got != want {
+			t.Errorf("unsafe.Sizeof(%T) = %d, want %d", test.val, got, want)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/types2/sizes.go b/src/cmd/compile/internal/types2/sizes.go
new file mode 100644
index 0000000..aa0fbf4
--- /dev/null
+++ b/src/cmd/compile/internal/types2/sizes.go
@@ -0,0 +1,265 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements Sizes.
+
+package types2
+
+// Sizes defines the sizing functions for package unsafe.
+type Sizes interface {
+	// Alignof returns the alignment of a variable of type T.
+	// Alignof must implement the alignment guarantees required by the spec.
+	Alignof(T Type) int64
+
+	// Offsetsof returns the offsets of the given struct fields, in bytes.
+	// Offsetsof must implement the offset guarantees required by the spec.
+	Offsetsof(fields []*Var) []int64
+
+	// Sizeof returns the size of a variable of type T.
+	// Sizeof must implement the size guarantees required by the spec.
+	Sizeof(T Type) int64
+}
+
+// StdSizes is a convenience type for creating commonly used Sizes.
+// It makes the following simplifying assumptions:
+//
+//	- The size of explicitly sized basic types (int16, etc.) is the
+//	  specified size.
+//	- The size of strings and interfaces is 2*WordSize.
+//	- The size of slices is 3*WordSize.
+//	- The size of an array of n elements corresponds to the size of
+//	  a struct of n consecutive fields of the array's element type.
+//      - The size of a struct is the offset of the last field plus that
+//	  field's size. As with all element types, if the struct is used
+//	  in an array its size must first be aligned to a multiple of the
+//	  struct's alignment.
+//	- All other types have size WordSize.
+//	- Arrays and structs are aligned per spec definition; all other
+//	  types are naturally aligned with a maximum alignment MaxAlign.
+//
+// *StdSizes implements Sizes.
+//
+type StdSizes struct {
+	WordSize int64 // word size in bytes - must be >= 4 (32bits)
+	MaxAlign int64 // maximum alignment in bytes - must be >= 1
+}
+
+func (s *StdSizes) Alignof(T Type) int64 {
+	// For arrays and structs, alignment is defined in terms
+	// of alignment of the elements and fields, respectively.
+	switch t := optype(T).(type) {
+	case *Array:
+		// spec: "For a variable x of array type: unsafe.Alignof(x)
+		// is the same as unsafe.Alignof(x[0]), but at least 1."
+		return s.Alignof(t.elem)
+	case *Struct:
+		// spec: "For a variable x of struct type: unsafe.Alignof(x)
+		// is the largest of the values unsafe.Alignof(x.f) for each
+		// field f of x, but at least 1."
+		max := int64(1)
+		for _, f := range t.fields {
+			if a := s.Alignof(f.typ); a > max {
+				max = a
+			}
+		}
+		return max
+	case *Slice, *Interface:
+		// Multiword data structures are effectively structs
+		// in which each element has size WordSize.
+		return s.WordSize
+	case *Basic:
+		// Strings are like slices and interfaces.
+		if t.Info()&IsString != 0 {
+			return s.WordSize
+		}
+	}
+	a := s.Sizeof(T) // may be 0
+	// spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
+	if a < 1 {
+		return 1
+	}
+	// complex{64,128} are aligned like [2]float{32,64}.
+	if isComplex(T) {
+		a /= 2
+	}
+	if a > s.MaxAlign {
+		return s.MaxAlign
+	}
+	return a
+}
+
+func (s *StdSizes) Offsetsof(fields []*Var) []int64 {
+	offsets := make([]int64, len(fields))
+	var o int64
+	for i, f := range fields {
+		a := s.Alignof(f.typ)
+		o = align(o, a)
+		offsets[i] = o
+		o += s.Sizeof(f.typ)
+	}
+	return offsets
+}
+
+var basicSizes = [...]byte{
+	Bool:       1,
+	Int8:       1,
+	Int16:      2,
+	Int32:      4,
+	Int64:      8,
+	Uint8:      1,
+	Uint16:     2,
+	Uint32:     4,
+	Uint64:     8,
+	Float32:    4,
+	Float64:    8,
+	Complex64:  8,
+	Complex128: 16,
+}
+
+func (s *StdSizes) Sizeof(T Type) int64 {
+	switch t := optype(T).(type) {
+	case *Basic:
+		assert(isTyped(T))
+		k := t.kind
+		if int(k) < len(basicSizes) {
+			if s := basicSizes[k]; s > 0 {
+				return int64(s)
+			}
+		}
+		if k == String {
+			return s.WordSize * 2
+		}
+	case *Array:
+		n := t.len
+		if n <= 0 {
+			return 0
+		}
+		// n > 0
+		a := s.Alignof(t.elem)
+		z := s.Sizeof(t.elem)
+		return align(z, a)*(n-1) + z
+	case *Slice:
+		return s.WordSize * 3
+	case *Struct:
+		n := t.NumFields()
+		if n == 0 {
+			return 0
+		}
+		offsets := s.Offsetsof(t.fields)
+		return offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
+	case *Sum:
+		panic("Sizeof unimplemented for type sum")
+	case *Interface:
+		return s.WordSize * 2
+	}
+	return s.WordSize // catch-all
+}
+
+// common architecture word sizes and alignments
+var gcArchSizes = map[string]*StdSizes{
+	"386":      {4, 4},
+	"arm":      {4, 4},
+	"arm64":    {8, 8},
+	"amd64":    {8, 8},
+	"amd64p32": {4, 8},
+	"mips":     {4, 4},
+	"mipsle":   {4, 4},
+	"mips64":   {8, 8},
+	"mips64le": {8, 8},
+	"ppc64":    {8, 8},
+	"ppc64le":  {8, 8},
+	"riscv64":  {8, 8},
+	"s390x":    {8, 8},
+	"sparc64":  {8, 8},
+	"wasm":     {8, 8},
+	// When adding more architectures here,
+	// update the doc string of SizesFor below.
+}
+
+// SizesFor returns the Sizes used by a compiler for an architecture.
+// The result is nil if a compiler/architecture pair is not known.
+//
+// Supported architectures for compiler "gc":
+// "386", "arm", "arm64", "amd64", "amd64p32", "mips", "mipsle",
+// "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x", "sparc64", "wasm".
+func SizesFor(compiler, arch string) Sizes {
+	var m map[string]*StdSizes
+	switch compiler {
+	case "gc":
+		m = gcArchSizes
+	case "gccgo":
+		m = gccgoArchSizes
+	default:
+		return nil
+	}
+	s, ok := m[arch]
+	if !ok {
+		return nil
+	}
+	return s
+}
+
+// stdSizes is used if Config.Sizes == nil.
+var stdSizes = SizesFor("gc", "amd64")
+
+func (conf *Config) alignof(T Type) int64 {
+	if s := conf.Sizes; s != nil {
+		if a := s.Alignof(T); a >= 1 {
+			return a
+		}
+		panic("Config.Sizes.Alignof returned an alignment < 1")
+	}
+	return stdSizes.Alignof(T)
+}
+
+func (conf *Config) offsetsof(T *Struct) []int64 {
+	var offsets []int64
+	if T.NumFields() > 0 {
+		// compute offsets on demand
+		if s := conf.Sizes; s != nil {
+			offsets = s.Offsetsof(T.fields)
+			// sanity checks
+			if len(offsets) != T.NumFields() {
+				panic("Config.Sizes.Offsetsof returned the wrong number of offsets")
+			}
+			for _, o := range offsets {
+				if o < 0 {
+					panic("Config.Sizes.Offsetsof returned an offset < 0")
+				}
+			}
+		} else {
+			offsets = stdSizes.Offsetsof(T.fields)
+		}
+	}
+	return offsets
+}
+
+// offsetof returns the offset of the field specified via
+// the index sequence relative to typ. All embedded fields
+// must be structs (rather than pointer to structs).
+func (conf *Config) offsetof(typ Type, index []int) int64 {
+	var o int64
+	for _, i := range index {
+		s := asStruct(typ)
+		o += conf.offsetsof(s)[i]
+		typ = s.fields[i].typ
+	}
+	return o
+}
+
+func (conf *Config) sizeof(T Type) int64 {
+	if s := conf.Sizes; s != nil {
+		if z := s.Sizeof(T); z >= 0 {
+			return z
+		}
+		panic("Config.Sizes.Sizeof returned a size < 0")
+	}
+	return stdSizes.Sizeof(T)
+}
+
+// align returns the smallest y >= x such that y % a == 0.
+func align(x, a int64) int64 {
+	y := x + a - 1
+	return y - y%a
+}
diff --git a/src/cmd/compile/internal/types2/sizes_test.go b/src/cmd/compile/internal/types2/sizes_test.go
new file mode 100644
index 0000000..c9a4942
--- /dev/null
+++ b/src/cmd/compile/internal/types2/sizes_test.go
@@ -0,0 +1,107 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains tests for sizes.
+
+package types2_test
+
+import (
+	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/types2"
+	"testing"
+)
+
+// findStructType typechecks src and returns the first struct type encountered.
+func findStructType(t *testing.T, src string) *types2.Struct {
+	f, err := parseSrc("x.go", src)
+	if err != nil {
+		t.Fatal(err)
+	}
+	info := types2.Info{Types: make(map[syntax.Expr]types2.TypeAndValue)}
+	var conf types2.Config
+	_, err = conf.Check("x", []*syntax.File{f}, &info)
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, tv := range info.Types {
+		if ts, ok := tv.Type.(*types2.Struct); ok {
+			return ts
+		}
+	}
+	t.Fatalf("failed to find a struct type in src:\n%s\n", src)
+	return nil
+}
+
+// Issue 16316
+func TestMultipleSizeUse(t *testing.T) {
+	const src = `
+package main
+
+type S struct {
+    i int
+    b bool
+    s string
+    n int
+}
+`
+	ts := findStructType(t, src)
+	sizes := types2.StdSizes{WordSize: 4, MaxAlign: 4}
+	if got := sizes.Sizeof(ts); got != 20 {
+		t.Errorf("Sizeof(%v) with WordSize 4 = %d want 20", ts, got)
+	}
+	sizes = types2.StdSizes{WordSize: 8, MaxAlign: 8}
+	if got := sizes.Sizeof(ts); got != 40 {
+		t.Errorf("Sizeof(%v) with WordSize 8 = %d want 40", ts, got)
+	}
+}
+
+// Issue 16464
+func TestAlignofNaclSlice(t *testing.T) {
+	const src = `
+package main
+
+var s struct {
+	x *int
+	y []byte
+}
+`
+	ts := findStructType(t, src)
+	sizes := &types2.StdSizes{WordSize: 4, MaxAlign: 8}
+	var fields []*types2.Var
+	// Make a copy manually :(
+	for i := 0; i < ts.NumFields(); i++ {
+		fields = append(fields, ts.Field(i))
+	}
+	offsets := sizes.Offsetsof(fields)
+	if offsets[0] != 0 || offsets[1] != 4 {
+		t.Errorf("OffsetsOf(%v) = %v want %v", ts, offsets, []int{0, 4})
+	}
+}
+
+func TestIssue16902(t *testing.T) {
+	const src = `
+package a
+
+import "unsafe"
+
+const _ = unsafe.Offsetof(struct{ x int64 }{}.x)
+`
+	f, err := parseSrc("x.go", src)
+	if err != nil {
+		t.Fatal(err)
+	}
+	info := types2.Info{Types: make(map[syntax.Expr]types2.TypeAndValue)}
+	conf := types2.Config{
+		Importer: defaultImporter(),
+		Sizes:    &types2.StdSizes{WordSize: 8, MaxAlign: 8},
+	}
+	_, err = conf.Check("x", []*syntax.File{f}, &info)
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, tv := range info.Types {
+		_ = conf.Sizes.Sizeof(tv.Type)
+		_ = conf.Sizes.Alignof(tv.Type)
+	}
+}
diff --git a/src/cmd/compile/internal/types2/stdlib_test.go b/src/cmd/compile/internal/types2/stdlib_test.go
new file mode 100644
index 0000000..cde35c1
--- /dev/null
+++ b/src/cmd/compile/internal/types2/stdlib_test.go
@@ -0,0 +1,326 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file tests types2.Check by using it to
+// typecheck the standard library and tests.
+
+package types2_test
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"go/build"
+	"internal/testenv"
+	"os"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+	"time"
+
+	. "cmd/compile/internal/types2"
+)
+
+var stdLibImporter = defaultImporter()
+
+func TestStdlib(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	pkgCount := 0
+	duration := walkPkgDirs(filepath.Join(runtime.GOROOT(), "src"), func(dir string, filenames []string) {
+		typecheck(t, dir, filenames)
+		pkgCount++
+	}, t.Error)
+
+	if testing.Verbose() {
+		fmt.Println(pkgCount, "packages typechecked in", duration)
+	}
+}
+
+// firstComment returns the contents of the first non-empty comment in
+// the given file, "skip", or the empty string. No matter the present
+// comments, if any of them contains a build tag, the result is always
+// "skip". Only comments within the first 4K of the file are considered.
+// TODO(gri) should only read until we see "package" token.
+func firstComment(filename string) (first string) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return ""
+	}
+	defer f.Close()
+
+	// read at most 4KB
+	var buf [4 << 10]byte
+	n, _ := f.Read(buf[:])
+	src := bytes.NewBuffer(buf[:n])
+
+	// TODO(gri) we need a better way to terminate CommentsDo
+	defer func() {
+		if p := recover(); p != nil {
+			if s, ok := p.(string); ok {
+				first = s
+			}
+		}
+	}()
+
+	syntax.CommentsDo(src, func(_, _ uint, text string) {
+		if text[0] != '/' {
+			return // not a comment
+		}
+
+		// extract comment text
+		if text[1] == '*' {
+			text = text[:len(text)-2]
+		}
+		text = strings.TrimSpace(text[2:])
+
+		if strings.HasPrefix(text, "+build ") {
+			panic("skip")
+		}
+		if first == "" {
+			first = text // text may be "" but that's ok
+		}
+		// continue as we may still see build tags
+	})
+
+	return
+}
+
+func testTestDir(t *testing.T, path string, ignore ...string) {
+	files, err := os.ReadDir(path)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	excluded := make(map[string]bool)
+	for _, filename := range ignore {
+		excluded[filename] = true
+	}
+
+	for _, f := range files {
+		// filter directory contents
+		if f.IsDir() || !strings.HasSuffix(f.Name(), ".go") || excluded[f.Name()] {
+			continue
+		}
+
+		// get per-file instructions
+		expectErrors := false
+		filename := filepath.Join(path, f.Name())
+		goVersion := ""
+		if comment := firstComment(filename); comment != "" {
+			fields := strings.Fields(comment)
+			switch fields[0] {
+			case "skip", "compiledir":
+				continue // ignore this file
+			case "errorcheck":
+				expectErrors = true
+				for _, arg := range fields[1:] {
+					if arg == "-0" || arg == "-+" || arg == "-std" {
+						// Marked explicitly as not expecting errors (-0),
+						// or marked as compiling runtime/stdlib, which is only done
+						// to trigger runtime/stdlib-only error output.
+						// In both cases, the code should typecheck.
+						expectErrors = false
+						break
+					}
+					const prefix = "-lang="
+					if strings.HasPrefix(arg, prefix) {
+						goVersion = arg[len(prefix):]
+					}
+				}
+			}
+		}
+
+		// parse and type-check file
+		if testing.Verbose() {
+			fmt.Println("\t", filename)
+		}
+		file, err := syntax.ParseFile(filename, nil, nil, 0)
+		if err == nil {
+			conf := Config{GoVersion: goVersion, Importer: stdLibImporter}
+			_, err = conf.Check(filename, []*syntax.File{file}, nil)
+		}
+
+		if expectErrors {
+			if err == nil {
+				t.Errorf("expected errors but found none in %s", filename)
+			}
+		} else {
+			if err != nil {
+				t.Error(err)
+			}
+		}
+	}
+}
+
+func TestStdTest(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	if testing.Short() && testenv.Builder() == "" {
+		t.Skip("skipping in short mode")
+	}
+
+	testTestDir(t, filepath.Join(runtime.GOROOT(), "test"),
+		"cmplxdivide.go", // also needs file cmplxdivide1.go - ignore
+		"directive.go",   // tests compiler rejection of bad directive placement - ignore
+		"embedfunc.go",   // tests //go:embed
+		"embedvers.go",   // tests //go:embed
+		"linkname2.go",   // types2 doesn't check validity of //go:xxx directives
+	)
+}
+
+func TestStdFixed(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	if testing.Short() && testenv.Builder() == "" {
+		t.Skip("skipping in short mode")
+	}
+
+	testTestDir(t, filepath.Join(runtime.GOROOT(), "test", "fixedbugs"),
+		"bug248.go", "bug302.go", "bug369.go", // complex test instructions - ignore
+		"issue6889.go",   // gc-specific test
+		"issue11362.go",  // canonical import path check
+		"issue16369.go",  // types2 handles this correctly - not an issue
+		"issue18459.go",  // types2 doesn't check validity of //go:xxx directives
+		"issue18882.go",  // types2 doesn't check validity of //go:xxx directives
+		"issue20529.go",  // types2 does not have constraints on stack size
+		"issue22200.go",  // types2 does not have constraints on stack size
+		"issue22200b.go", // types2 does not have constraints on stack size
+		"issue25507.go",  // types2 does not have constraints on stack size
+		"issue20780.go",  // types2 does not have constraints on stack size
+		"issue42058a.go", // types2 does not have constraints on channel element size
+		"issue42058b.go", // types2 does not have constraints on channel element size
+	)
+}
+
+func TestStdKen(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	testTestDir(t, filepath.Join(runtime.GOROOT(), "test", "ken"))
+}
+
+// Package paths of excluded packages.
+var excluded = map[string]bool{
+	"builtin": true,
+
+	// See #46027: some imports are missing for this submodule.
+	"crypto/ed25519/internal/edwards25519/field/_asm": true,
+}
+
+// typecheck typechecks the given package files.
+func typecheck(t *testing.T, path string, filenames []string) {
+	// parse package files
+	var files []*syntax.File
+	for _, filename := range filenames {
+		errh := func(err error) { t.Error(err) }
+		file, err := syntax.ParseFile(filename, errh, nil, 0)
+		if err != nil {
+			return
+		}
+
+		if testing.Verbose() {
+			if len(files) == 0 {
+				fmt.Println("package", file.PkgName.Value)
+			}
+			fmt.Println("\t", filename)
+		}
+
+		files = append(files, file)
+	}
+
+	// typecheck package files
+	conf := Config{
+		Error:    func(err error) { t.Error(err) },
+		Importer: stdLibImporter,
+	}
+	info := Info{Uses: make(map[*syntax.Name]Object)}
+	conf.Check(path, files, &info)
+
+	// Perform checks of API invariants.
+
+	// All Objects have a package, except predeclared ones.
+	errorError := Universe.Lookup("error").Type().Underlying().(*Interface).ExplicitMethod(0) // (error).Error
+	for id, obj := range info.Uses {
+		predeclared := obj == Universe.Lookup(obj.Name()) || obj == errorError
+		if predeclared == (obj.Pkg() != nil) {
+			posn := id.Pos()
+			if predeclared {
+				t.Errorf("%s: predeclared object with package: %s", posn, obj)
+			} else {
+				t.Errorf("%s: user-defined object without package: %s", posn, obj)
+			}
+		}
+	}
+}
+
+// pkgFilenames returns the list of package filenames for the given directory.
+func pkgFilenames(dir string) ([]string, error) {
+	ctxt := build.Default
+	ctxt.CgoEnabled = false
+	pkg, err := ctxt.ImportDir(dir, 0)
+	if err != nil {
+		if _, nogo := err.(*build.NoGoError); nogo {
+			return nil, nil // no *.go files, not an error
+		}
+		return nil, err
+	}
+	if excluded[pkg.ImportPath] {
+		return nil, nil
+	}
+	var filenames []string
+	for _, name := range pkg.GoFiles {
+		filenames = append(filenames, filepath.Join(pkg.Dir, name))
+	}
+	for _, name := range pkg.TestGoFiles {
+		filenames = append(filenames, filepath.Join(pkg.Dir, name))
+	}
+	return filenames, nil
+}
+
+func walkPkgDirs(dir string, pkgh func(dir string, filenames []string), errh func(args ...interface{})) time.Duration {
+	w := walker{time.Now(), 10 * time.Millisecond, pkgh, errh}
+	w.walk(dir)
+	return time.Since(w.start)
+}
+
+type walker struct {
+	start time.Time
+	dmax  time.Duration
+	pkgh  func(dir string, filenames []string)
+	errh  func(args ...interface{})
+}
+
+func (w *walker) walk(dir string) {
+	// limit run time for short tests
+	if testing.Short() && time.Since(w.start) >= w.dmax {
+		return
+	}
+
+	files, err := os.ReadDir(dir)
+	if err != nil {
+		w.errh(err)
+		return
+	}
+
+	// apply pkgh to the files in directory dir
+	// but ignore files directly under $GOROOT/src (might be temporary test files).
+	if dir != filepath.Join(runtime.GOROOT(), "src") {
+		files, err := pkgFilenames(dir)
+		if err != nil {
+			w.errh(err)
+			return
+		}
+		if files != nil {
+			w.pkgh(dir, files)
+		}
+	}
+
+	// traverse subdirectories, but don't walk into testdata
+	for _, f := range files {
+		if f.IsDir() && f.Name() != "testdata" {
+			w.walk(filepath.Join(dir, f.Name()))
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/types2/stmt.go b/src/cmd/compile/internal/types2/stmt.go
new file mode 100644
index 0000000..c3e646c
--- /dev/null
+++ b/src/cmd/compile/internal/types2/stmt.go
@@ -0,0 +1,943 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements typechecking of statements.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"go/constant"
+	"sort"
+)
+
+func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body *syntax.BlockStmt, iota constant.Value) {
+	if check.conf.IgnoreFuncBodies {
+		panic("internal error: function body not ignored")
+	}
+
+	if check.conf.Trace {
+		check.trace(body.Pos(), "--- %s: %s", name, sig)
+		defer func() {
+			check.trace(syntax.EndPos(body), "--- <end>")
+		}()
+	}
+
+	// set function scope extent
+	sig.scope.pos = body.Pos()
+	sig.scope.end = syntax.EndPos(body)
+
+	// save/restore current context and setup function context
+	// (and use 0 indentation at function start)
+	defer func(ctxt context, indent int) {
+		check.context = ctxt
+		check.indent = indent
+	}(check.context, check.indent)
+	check.context = context{
+		decl:  decl,
+		scope: sig.scope,
+		iota:  iota,
+		sig:   sig,
+	}
+	check.indent = 0
+
+	check.stmtList(0, body.List)
+
+	if check.hasLabel && !check.conf.IgnoreLabels {
+		check.labels(body)
+	}
+
+	if sig.results.Len() > 0 && !check.isTerminating(body, "") {
+		check.error(body.Rbrace, "missing return")
+	}
+
+	// TODO(gri) Should we make it an error to declare generic functions
+	//           where the type parameters are not used?
+	// 12/19/2018: Probably not - it can make sense to have an API with
+	//           all functions uniformly sharing the same type parameters.
+
+	// spec: "Implementation restriction: A compiler may make it illegal to
+	// declare a variable inside a function body if the variable is never used."
+	check.usage(sig.scope)
+}
+
+func (check *Checker) usage(scope *Scope) {
+	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.Cmp(unused[j].pos) < 0
+	})
+	for _, v := range unused {
+		check.softErrorf(v.pos, "%s declared but not used", v.name)
+	}
+
+	for _, scope := range scope.children {
+		// Don't go inside function literal scopes a second time;
+		// they are handled explicitly by funcBody.
+		if !scope.isFunc {
+			check.usage(scope)
+		}
+	}
+}
+
+// stmtContext is a bitset describing which
+// control-flow statements are permissible,
+// and provides additional context information
+// for better error messages.
+type stmtContext uint
+
+const (
+	// permissible control-flow statements
+	breakOk stmtContext = 1 << iota
+	continueOk
+	fallthroughOk
+
+	// additional context information
+	finalSwitchCase
+)
+
+func (check *Checker) simpleStmt(s syntax.Stmt) {
+	if s != nil {
+		check.stmt(0, s)
+	}
+}
+
+func trimTrailingEmptyStmts(list []syntax.Stmt) []syntax.Stmt {
+	for i := len(list); i > 0; i-- {
+		if _, ok := list[i-1].(*syntax.EmptyStmt); !ok {
+			return list[:i]
+		}
+	}
+	return nil
+}
+
+func (check *Checker) stmtList(ctxt stmtContext, list []syntax.Stmt) {
+	ok := ctxt&fallthroughOk != 0
+	inner := ctxt &^ fallthroughOk
+	list = trimTrailingEmptyStmts(list) // trailing empty statements are "invisible" to fallthrough analysis
+	for i, s := range list {
+		inner := inner
+		if ok && i+1 == len(list) {
+			inner |= fallthroughOk
+		}
+		check.stmt(inner, s)
+	}
+}
+
+func (check *Checker) multipleSwitchDefaults(list []*syntax.CaseClause) {
+	var first *syntax.CaseClause
+	for _, c := range list {
+		if c.Cases == nil {
+			if first != nil {
+				check.errorf(c, "multiple defaults (first at %s)", first.Pos())
+				// TODO(gri) probably ok to bail out after first error (and simplify this code)
+			} else {
+				first = c
+			}
+		}
+	}
+}
+
+func (check *Checker) multipleSelectDefaults(list []*syntax.CommClause) {
+	var first *syntax.CommClause
+	for _, c := range list {
+		if c.Comm == nil {
+			if first != nil {
+				check.errorf(c, "multiple defaults (first at %s)", first.Pos())
+				// TODO(gri) probably ok to bail out after first error (and simplify this code)
+			} else {
+				first = c
+			}
+		}
+	}
+}
+
+func (check *Checker) openScope(node syntax.Node, comment string) {
+	check.openScopeUntil(node, syntax.EndPos(node), comment)
+}
+
+func (check *Checker) openScopeUntil(node syntax.Node, end syntax.Pos, comment string) {
+	scope := NewScope(check.scope, node.Pos(), end, comment)
+	check.recordScope(node, scope)
+	check.scope = scope
+}
+
+func (check *Checker) closeScope() {
+	check.scope = check.scope.Parent()
+}
+
+func (check *Checker) suspendedCall(keyword string, call *syntax.CallExpr) {
+	var x operand
+	var msg string
+	switch check.rawExpr(&x, call, nil) {
+	case conversion:
+		msg = "requires function call, not conversion"
+	case expression:
+		msg = "discards result of"
+	case statement:
+		return
+	default:
+		unreachable()
+	}
+	check.errorf(&x, "%s %s %s", keyword, msg, &x)
+}
+
+// goVal returns the Go value for val, or nil.
+func goVal(val constant.Value) interface{} {
+	// val should exist, but be conservative and check
+	if val == nil {
+		return nil
+	}
+	// Match implementation restriction of other compilers.
+	// gc only checks duplicates for integer, floating-point
+	// and string values, so only create Go values for these
+	// types.
+	switch val.Kind() {
+	case constant.Int:
+		if x, ok := constant.Int64Val(val); ok {
+			return x
+		}
+		if x, ok := constant.Uint64Val(val); ok {
+			return x
+		}
+	case constant.Float:
+		if x, ok := constant.Float64Val(val); ok {
+			return x
+		}
+	case constant.String:
+		return constant.StringVal(val)
+	}
+	return nil
+}
+
+// A valueMap maps a case value (of a basic Go type) to a list of positions
+// where the same case value appeared, together with the corresponding case
+// types.
+// Since two case values may have the same "underlying" value but different
+// types we need to also check the value's types (e.g., byte(1) vs myByte(1))
+// when the switch expression is of interface type.
+type (
+	valueMap  map[interface{}][]valueType // underlying Go value -> valueType
+	valueType struct {
+		pos syntax.Pos
+		typ Type
+	}
+)
+
+func (check *Checker) caseValues(x *operand, values []syntax.Expr, seen valueMap) {
+L:
+	for _, e := range values {
+		var v operand
+		check.expr(&v, e)
+		if x.mode == invalid || v.mode == invalid {
+			continue L
+		}
+		check.convertUntyped(&v, x.typ)
+		if v.mode == invalid {
+			continue L
+		}
+		// Order matters: By comparing v against x, error positions are at the case values.
+		res := v // keep original v unchanged
+		check.comparison(&res, x, syntax.Eql)
+		if res.mode == invalid {
+			continue L
+		}
+		if v.mode != constant_ {
+			continue L // we're done
+		}
+		// look for duplicate values
+		if val := goVal(v.val); val != nil {
+			// look for duplicate types for a given value
+			// (quadratic algorithm, but these lists tend to be very short)
+			for _, vt := range seen[val] {
+				if check.identical(v.typ, vt.typ) {
+					var err error_
+					err.errorf(&v, "duplicate case %s in expression switch", &v)
+					err.errorf(vt.pos, "previous case")
+					check.report(&err)
+					continue L
+				}
+			}
+			seen[val] = append(seen[val], valueType{v.Pos(), v.typ})
+		}
+	}
+}
+
+func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []syntax.Expr, seen map[Type]syntax.Expr) (T Type) {
+L:
+	for _, e := range types {
+		T = check.typOrNil(e)
+		if T == Typ[Invalid] {
+			continue L
+		}
+		if T != nil {
+			check.ordinaryType(e.Pos(), T)
+		}
+		// look for duplicate types
+		// (quadratic algorithm, but type switches tend to be reasonably small)
+		for t, other := range seen {
+			if T == nil && t == nil || T != nil && t != nil && check.identical(T, t) {
+				// talk about "case" rather than "type" because of nil case
+				Ts := "nil"
+				if T != nil {
+					Ts = T.String()
+				}
+				var err error_
+				err.errorf(e, "duplicate case %s in type switch", Ts)
+				err.errorf(other, "previous case")
+				check.report(&err)
+				continue L
+			}
+		}
+		seen[T] = e
+		if T != nil {
+			check.typeAssertion(e.Pos(), x, xtyp, T)
+		}
+	}
+	return
+}
+
+// stmt typechecks statement s.
+func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
+	// statements must end with the same top scope as they started with
+	if debug {
+		defer func(scope *Scope) {
+			// don't check if code is panicking
+			if p := recover(); p != nil {
+				panic(p)
+			}
+			assert(scope == check.scope)
+		}(check.scope)
+	}
+
+	// process collected function literals before scope changes
+	defer check.processDelayed(len(check.delayed))
+
+	inner := ctxt &^ (fallthroughOk | finalSwitchCase)
+	switch s := s.(type) {
+	case *syntax.EmptyStmt:
+		// ignore
+
+	case *syntax.DeclStmt:
+		check.declStmt(s.DeclList)
+
+	case *syntax.LabeledStmt:
+		check.hasLabel = true
+		check.stmt(ctxt, s.Stmt)
+
+	case *syntax.ExprStmt:
+		// spec: "With the exception of specific built-in functions,
+		// function and method calls and receive operations can appear
+		// in statement context. Such statements may be parenthesized."
+		var x operand
+		kind := check.rawExpr(&x, s.X, nil)
+		var msg string
+		switch x.mode {
+		default:
+			if kind == statement {
+				return
+			}
+			msg = "is not used"
+		case builtin:
+			msg = "must be called"
+		case typexpr:
+			msg = "is not an expression"
+		}
+		check.errorf(&x, "%s %s", &x, msg)
+
+	case *syntax.SendStmt:
+		var ch, x operand
+		check.expr(&ch, s.Chan)
+		check.expr(&x, s.Value)
+		if ch.mode == invalid || x.mode == invalid {
+			return
+		}
+
+		tch := asChan(ch.typ)
+		if tch == nil {
+			check.errorf(s, invalidOp+"cannot send to non-chan type %s", ch.typ)
+			return
+		}
+
+		if tch.dir == RecvOnly {
+			check.errorf(s, invalidOp+"cannot send to receive-only type %s", tch)
+			return
+		}
+
+		check.assignment(&x, tch.elem, "send")
+
+	case *syntax.AssignStmt:
+		lhs := unpackExpr(s.Lhs)
+		if s.Rhs == nil {
+			// x++ or x--
+			if len(lhs) != 1 {
+				check.errorf(s, invalidAST+"%s%s requires one operand", s.Op, s.Op)
+				return
+			}
+			var x operand
+			check.expr(&x, lhs[0])
+			if x.mode == invalid {
+				return
+			}
+			if !isNumeric(x.typ) {
+				check.errorf(lhs[0], invalidOp+"%s%s%s (non-numeric type %s)", lhs[0], s.Op, s.Op, x.typ)
+				return
+			}
+			check.assignVar(lhs[0], &x)
+			return
+		}
+
+		rhs := unpackExpr(s.Rhs)
+		switch s.Op {
+		case 0:
+			check.assignVars(lhs, rhs)
+			return
+		case syntax.Def:
+			check.shortVarDecl(s.Pos(), lhs, rhs)
+			return
+		}
+
+		// assignment operations
+		if len(lhs) != 1 || len(rhs) != 1 {
+			check.errorf(s, "assignment operation %s requires single-valued expressions", s.Op)
+			return
+		}
+
+		var x operand
+		check.binary(&x, nil, lhs[0], rhs[0], s.Op)
+		check.assignVar(lhs[0], &x)
+
+	case *syntax.CallStmt:
+		// TODO(gri) get rid of this conversion to string
+		kind := "go"
+		if s.Tok == syntax.Defer {
+			kind = "defer"
+		}
+		check.suspendedCall(kind, s.Call)
+
+	case *syntax.ReturnStmt:
+		res := check.sig.results
+		results := unpackExpr(s.Results)
+		if res.Len() > 0 {
+			// function returns results
+			// (if one, say the first, result parameter is named, all of them are named)
+			if len(results) == 0 && res.vars[0].name != "" {
+				// spec: "Implementation restriction: A compiler may disallow an empty expression
+				// list in a "return" statement if a different entity (constant, type, or variable)
+				// with the same name as a result parameter is in scope at the place of the return."
+				for _, obj := range res.vars {
+					if alt := check.lookup(obj.name); alt != nil && alt != obj {
+						var err error_
+						err.errorf(s, "result parameter %s not in scope at return", obj.name)
+						err.errorf(alt, "inner declaration of %s", obj)
+						check.report(&err)
+						// ok to continue
+					}
+				}
+			} else {
+				// return has results or result parameters are unnamed
+				check.initVars(res.vars, results, s.Pos())
+			}
+		} else if len(results) > 0 {
+			check.error(results[0], "no result values expected")
+			check.use(results...)
+		}
+
+	case *syntax.BranchStmt:
+		if s.Label != nil {
+			check.hasLabel = true
+			break // checked in 2nd pass (check.labels)
+		}
+		switch s.Tok {
+		case syntax.Break:
+			if ctxt&breakOk == 0 {
+				if check.conf.CompilerErrorMessages {
+					check.error(s, "break is not in a loop, switch, or select statement")
+				} else {
+					check.error(s, "break not in for, switch, or select statement")
+				}
+			}
+		case syntax.Continue:
+			if ctxt&continueOk == 0 {
+				if check.conf.CompilerErrorMessages {
+					check.error(s, "continue is not in a loop")
+				} else {
+					check.error(s, "continue not in for statement")
+				}
+			}
+		case syntax.Fallthrough:
+			if ctxt&fallthroughOk == 0 {
+				msg := "fallthrough statement out of place"
+				if ctxt&finalSwitchCase != 0 {
+					msg = "cannot fallthrough final case in switch"
+				}
+				check.error(s, msg)
+			}
+		case syntax.Goto:
+			// goto's must have labels, should have been caught above
+			fallthrough
+		default:
+			check.errorf(s, invalidAST+"branch statement: %s", s.Tok)
+		}
+
+	case *syntax.BlockStmt:
+		check.openScope(s, "block")
+		defer check.closeScope()
+
+		check.stmtList(inner, s.List)
+
+	case *syntax.IfStmt:
+		check.openScope(s, "if")
+		defer check.closeScope()
+
+		check.simpleStmt(s.Init)
+		var x operand
+		check.expr(&x, s.Cond)
+		if x.mode != invalid && !isBoolean(x.typ) {
+			check.error(s.Cond, "non-boolean condition in if statement")
+		}
+		check.stmt(inner, s.Then)
+		// The parser produces a correct AST but if it was modified
+		// elsewhere the else branch may be invalid. Check again.
+		switch s.Else.(type) {
+		case nil:
+			// valid or error already reported
+		case *syntax.IfStmt, *syntax.BlockStmt:
+			check.stmt(inner, s.Else)
+		default:
+			check.error(s.Else, "invalid else branch in if statement")
+		}
+
+	case *syntax.SwitchStmt:
+		inner |= breakOk
+		check.openScope(s, "switch")
+		defer check.closeScope()
+
+		check.simpleStmt(s.Init)
+
+		if g, _ := s.Tag.(*syntax.TypeSwitchGuard); g != nil {
+			check.typeSwitchStmt(inner, s, g)
+		} else {
+			check.switchStmt(inner, s)
+		}
+
+	case *syntax.SelectStmt:
+		inner |= breakOk
+
+		check.multipleSelectDefaults(s.Body)
+
+		for i, clause := range s.Body {
+			if clause == nil {
+				continue // error reported before
+			}
+
+			// clause.Comm must be a SendStmt, RecvStmt, or default case
+			valid := false
+			var rhs syntax.Expr // rhs of RecvStmt, or nil
+			switch s := clause.Comm.(type) {
+			case nil, *syntax.SendStmt:
+				valid = true
+			case *syntax.AssignStmt:
+				if _, ok := s.Rhs.(*syntax.ListExpr); !ok {
+					rhs = s.Rhs
+				}
+			case *syntax.ExprStmt:
+				rhs = s.X
+			}
+
+			// if present, rhs must be a receive operation
+			if rhs != nil {
+				if x, _ := unparen(rhs).(*syntax.Operation); x != nil && x.Y == nil && x.Op == syntax.Recv {
+					valid = true
+				}
+			}
+
+			if !valid {
+				check.error(clause.Comm, "select case must be send or receive (possibly with assignment)")
+				continue
+			}
+			end := s.Rbrace
+			if i+1 < len(s.Body) {
+				end = s.Body[i+1].Pos()
+			}
+			check.openScopeUntil(clause, end, "case")
+			if clause.Comm != nil {
+				check.stmt(inner, clause.Comm)
+			}
+			check.stmtList(inner, clause.Body)
+			check.closeScope()
+		}
+
+	case *syntax.ForStmt:
+		inner |= breakOk | continueOk
+		check.openScope(s, "for")
+		defer check.closeScope()
+
+		if rclause, _ := s.Init.(*syntax.RangeClause); rclause != nil {
+			check.rangeStmt(inner, s, rclause)
+			break
+		}
+
+		check.simpleStmt(s.Init)
+		if s.Cond != nil {
+			var x operand
+			check.expr(&x, s.Cond)
+			if x.mode != invalid && !isBoolean(x.typ) {
+				check.error(s.Cond, "non-boolean condition in for statement")
+			}
+		}
+		check.simpleStmt(s.Post)
+		// spec: "The init statement may be a short variable
+		// declaration, but the post statement must not."
+		if s, _ := s.Post.(*syntax.AssignStmt); s != nil && s.Op == syntax.Def {
+			// The parser already reported an error.
+			// 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)
+
+	default:
+		check.error(s, "invalid statement")
+	}
+}
+
+func (check *Checker) switchStmt(inner stmtContext, s *syntax.SwitchStmt) {
+	// init statement already handled
+
+	var x operand
+	if s.Tag != nil {
+		check.expr(&x, s.Tag)
+		// By checking assignment of x to an invisible temporary
+		// (as a compiler would), we get all the relevant checks.
+		check.assignment(&x, nil, "switch expression")
+		if x.mode != invalid && !Comparable(x.typ) && !hasNil(x.typ) {
+			check.errorf(&x, "cannot switch on %s (%s is not comparable)", &x, x.typ)
+			x.mode = invalid
+		}
+	} else {
+		// spec: "A missing switch expression is
+		// equivalent to the boolean value true."
+		x.mode = constant_
+		x.typ = Typ[Bool]
+		x.val = constant.MakeBool(true)
+		// TODO(gri) should have a better position here
+		pos := s.Rbrace
+		if len(s.Body) > 0 {
+			pos = s.Body[0].Pos()
+		}
+		x.expr = syntax.NewName(pos, "true")
+	}
+
+	check.multipleSwitchDefaults(s.Body)
+
+	seen := make(valueMap) // map of seen case values to positions and types
+	for i, clause := range s.Body {
+		if clause == nil {
+			check.error(clause, invalidAST+"incorrect expression switch case")
+			continue
+		}
+		end := s.Rbrace
+		inner := inner
+		if i+1 < len(s.Body) {
+			end = s.Body[i+1].Pos()
+			inner |= fallthroughOk
+		} else {
+			inner |= finalSwitchCase
+		}
+		check.caseValues(&x, unpackExpr(clause.Cases), seen)
+		check.openScopeUntil(clause, end, "case")
+		check.stmtList(inner, clause.Body)
+		check.closeScope()
+	}
+}
+
+func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, guard *syntax.TypeSwitchGuard) {
+	// init statement already handled
+
+	// A type switch guard must be of the form:
+	//
+	//     TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
+	//                          \__lhs__/        \___rhs___/
+
+	// check lhs, if any
+	lhs := guard.Lhs
+	if lhs != nil {
+		if lhs.Value == "_" {
+			// _ := x.(type) is an invalid short variable declaration
+			check.softErrorf(lhs, "no new variable on left side of :=")
+			lhs = nil // avoid declared but not used error below
+		} else {
+			check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause
+		}
+	}
+
+	// check rhs
+	var x operand
+	check.expr(&x, guard.X)
+	if x.mode == invalid {
+		return
+	}
+	// Caution: We're not using asInterface here because we don't want
+	//          to switch on a suitably constrained type parameter (for
+	//          now).
+	// TODO(gri) Need to revisit this.
+	xtyp, _ := under(x.typ).(*Interface)
+	if xtyp == nil {
+		check.errorf(&x, "%s is not an interface type", &x)
+		return
+	}
+	check.ordinaryType(x.Pos(), xtyp)
+
+	check.multipleSwitchDefaults(s.Body)
+
+	var lhsVars []*Var                 // list of implicitly declared lhs variables
+	seen := make(map[Type]syntax.Expr) // map of seen types to positions
+	for i, clause := range s.Body {
+		if clause == nil {
+			check.error(s, invalidAST+"incorrect type switch case")
+			continue
+		}
+		end := s.Rbrace
+		if i+1 < len(s.Body) {
+			end = s.Body[i+1].Pos()
+		}
+		// Check each type in this type switch case.
+		cases := unpackExpr(clause.Cases)
+		T := check.caseTypes(&x, xtyp, cases, seen)
+		check.openScopeUntil(clause, end, "case")
+		// If lhs exists, declare a corresponding variable in the case-local scope.
+		if lhs != nil {
+			// spec: "The TypeSwitchGuard may include a short variable declaration.
+			// When that form is used, the variable is declared at the beginning of
+			// the implicit block in each clause. In clauses with a case listing
+			// exactly one type, the variable has that type; otherwise, the variable
+			// has the type of the expression in the TypeSwitchGuard."
+			if len(cases) != 1 || T == nil {
+				T = x.typ
+			}
+			obj := NewVar(lhs.Pos(), check.pkg, lhs.Value, T)
+			// TODO(mdempsky): Just use clause.Colon? Why did I even suggest
+			// "at the end of the TypeSwitchCase" in #16794 instead?
+			scopePos := clause.Pos() // for default clause (len(List) == 0)
+			if n := len(cases); n > 0 {
+				scopePos = syntax.EndPos(cases[n-1])
+			}
+			check.declare(check.scope, nil, obj, scopePos)
+			check.recordImplicit(clause, obj)
+			// For the "declared but not used" error, all lhs variables act as
+			// one; i.e., if any one of them is 'used', all of them are 'used'.
+			// Collect them for later analysis.
+			lhsVars = append(lhsVars, obj)
+		}
+		check.stmtList(inner, clause.Body)
+		check.closeScope()
+	}
+
+	// If lhs exists, we must have at least one lhs variable that was used.
+	// (We can't use check.usage because that only looks at one scope; and
+	// we don't want to use the same variable for all scopes and change the
+	// variable type underfoot.)
+	if lhs != nil {
+		var used bool
+		for _, v := range lhsVars {
+			if v.used {
+				used = true
+			}
+			v.used = true // avoid usage error when checking entire function
+		}
+		if !used {
+			check.softErrorf(lhs, "%s declared but not used", lhs.Value)
+		}
+	}
+}
+
+func (check *Checker) rangeStmt(inner stmtContext, s *syntax.ForStmt, rclause *syntax.RangeClause) {
+	// scope already opened
+
+	// check expression to iterate over
+	var x operand
+	check.expr(&x, rclause.X)
+
+	// determine lhs, if any
+	sKey := rclause.Lhs // possibly nil
+	var sValue syntax.Expr
+	if p, _ := sKey.(*syntax.ListExpr); p != nil {
+		if len(p.ElemList) != 2 {
+			check.error(s, invalidAST+"invalid lhs in range clause")
+			return
+		}
+		sKey = p.ElemList[0]
+		sValue = p.ElemList[1]
+	}
+
+	// determine key/value types
+	var key, val Type
+	if x.mode != invalid {
+		typ := optype(x.typ)
+		if _, ok := typ.(*Chan); ok && sValue != nil {
+			// TODO(gri) this also needs to happen for channels in generic variables
+			check.softErrorf(sValue, "range over %s permits only one iteration variable", &x)
+			// ok to continue
+		}
+		var msg string
+		key, val, msg = rangeKeyVal(typ, isVarName(sKey), isVarName(sValue))
+		if key == nil || msg != "" {
+			if msg != "" {
+				msg = ": " + msg
+			}
+			check.softErrorf(&x, "cannot range over %s%s", &x, msg)
+			// ok to continue
+		}
+	}
+
+	// check assignment to/declaration of iteration variables
+	// (irregular assignment, cannot easily map to existing assignment checks)
+
+	// lhs expressions and initialization value (rhs) types
+	lhs := [2]syntax.Expr{sKey, sValue}
+	rhs := [2]Type{key, val} // key, val may be nil
+
+	if rclause.Def {
+		// short variable declaration; variable scope starts after the range clause
+		// (the for loop opens a new scope, so variables on the lhs never redeclare
+		// previously declared variables)
+		var vars []*Var
+		for i, lhs := range lhs {
+			if lhs == nil {
+				continue
+			}
+
+			// determine lhs variable
+			var obj *Var
+			if ident, _ := lhs.(*syntax.Name); ident != nil {
+				// declare new variable
+				name := ident.Value
+				obj = NewVar(ident.Pos(), check.pkg, name, nil)
+				check.recordDef(ident, obj)
+				// _ variables don't count as new variables
+				if name != "_" {
+					vars = append(vars, obj)
+				}
+			} else {
+				check.errorf(lhs, "cannot declare %s", lhs)
+				obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
+			}
+
+			// initialize lhs variable
+			if typ := rhs[i]; typ != nil {
+				x.mode = value
+				x.expr = lhs // we don't have a better rhs expression to use here
+				x.typ = typ
+				check.initVar(obj, &x, "range clause")
+			} else {
+				obj.typ = Typ[Invalid]
+				obj.used = true // don't complain about unused variable
+			}
+		}
+
+		// declare variables
+		if len(vars) > 0 {
+			scopePos := syntax.EndPos(rclause.X) // TODO(gri) should this just be s.Body.Pos (spec clarification)?
+			for _, obj := range vars {
+				// spec: "The scope of a constant or variable identifier declared inside
+				// a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
+				// for short variable declarations) and ends at the end of the innermost
+				// containing block."
+				check.declare(check.scope, nil /* recordDef already called */, obj, scopePos)
+			}
+		} else {
+			check.error(s, "no new variables on left side of :=")
+		}
+	} else {
+		// ordinary assignment
+		for i, lhs := range lhs {
+			if lhs == nil {
+				continue
+			}
+			if typ := rhs[i]; typ != nil {
+				x.mode = value
+				x.expr = lhs // we don't have a better rhs expression to use here
+				x.typ = typ
+				check.assignVar(lhs, &x)
+			}
+		}
+	}
+
+	check.stmt(inner, s.Body)
+}
+
+// isVarName reports whether x is a non-nil, non-blank (_) expression.
+func isVarName(x syntax.Expr) bool {
+	if x == nil {
+		return false
+	}
+	ident, _ := unparen(x).(*syntax.Name)
+	return ident == nil || ident.Value != "_"
+}
+
+// rangeKeyVal returns the key and value type produced by a range clause
+// over an expression of type typ, and possibly an error message. If the
+// range clause is not permitted the returned key is nil or msg is not
+// empty (in that case we still may have a non-nil key type which can be
+// used to reduce the chance for follow-on errors).
+// The wantKey, wantVal, and hasVal flags indicate which of the iteration
+// variables are used or present; this matters if we range over a generic
+// type where not all keys or values are of the same type.
+func rangeKeyVal(typ Type, wantKey, wantVal bool) (Type, Type, string) {
+	switch typ := typ.(type) {
+	case *Basic:
+		if isString(typ) {
+			return Typ[Int], universeRune, "" // use 'rune' name
+		}
+	case *Array:
+		return Typ[Int], typ.elem, ""
+	case *Slice:
+		return Typ[Int], typ.elem, ""
+	case *Pointer:
+		if typ := asArray(typ.base); typ != nil {
+			return Typ[Int], typ.elem, ""
+		}
+	case *Map:
+		return typ.key, typ.elem, ""
+	case *Chan:
+		var msg string
+		if typ.dir == SendOnly {
+			msg = "receive from send-only channel"
+		}
+		return typ.elem, Typ[Invalid], msg
+	case *Sum:
+		first := true
+		var key, val Type
+		var msg string
+		typ.is(func(t Type) bool {
+			k, v, m := rangeKeyVal(under(t), wantKey, wantVal)
+			if k == nil || m != "" {
+				key, val, msg = k, v, m
+				return false
+			}
+			if first {
+				key, val, msg = k, v, m
+				first = false
+				return true
+			}
+			if wantKey && !Identical(key, k) {
+				key, val, msg = nil, nil, "all possible values must have the same key type"
+				return false
+			}
+			if wantVal && !Identical(val, v) {
+				key, val, msg = nil, nil, "all possible values must have the same element type"
+				return false
+			}
+			return true
+		})
+		return key, val, msg
+	}
+	return nil, nil, ""
+}
diff --git a/src/cmd/compile/internal/types2/subst.go b/src/cmd/compile/internal/types2/subst.go
new file mode 100644
index 0000000..c8e428c
--- /dev/null
+++ b/src/cmd/compile/internal/types2/subst.go
@@ -0,0 +1,547 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements instantiation of generic types
+// through substitution of type parameters by actual
+// types.
+
+package types2
+
+import (
+	"bytes"
+	"cmd/compile/internal/syntax"
+	"fmt"
+)
+
+type substMap struct {
+	// The targs field is currently needed for *Named type substitution.
+	// TODO(gri) rewrite that code, get rid of this field, and make this
+	//           struct just the map (proj)
+	targs []Type
+	proj  map[*TypeParam]Type
+}
+
+// makeSubstMap creates a new substitution map mapping tpars[i] to targs[i].
+// If targs[i] is nil, tpars[i] is not substituted.
+func makeSubstMap(tpars []*TypeName, targs []Type) *substMap {
+	assert(len(tpars) == len(targs))
+	proj := make(map[*TypeParam]Type, len(tpars))
+	for i, tpar := range tpars {
+		// We must expand type arguments otherwise *instance
+		// types end up as components in composite types.
+		// TODO(gri) explain why this causes problems, if it does
+		targ := expand(targs[i]) // possibly nil
+		targs[i] = targ
+		proj[tpar.typ.(*TypeParam)] = targ
+	}
+	return &substMap{targs, proj}
+}
+
+func (m *substMap) String() string {
+	return fmt.Sprintf("%s", m.proj)
+}
+
+func (m *substMap) empty() bool {
+	return len(m.proj) == 0
+}
+
+func (m *substMap) lookup(tpar *TypeParam) Type {
+	if t := m.proj[tpar]; t != nil {
+		return t
+	}
+	return tpar
+}
+
+func (check *Checker) instantiate(pos syntax.Pos, typ Type, targs []Type, poslist []syntax.Pos) (res Type) {
+	if check.conf.Trace {
+		check.trace(pos, "-- instantiating %s with %s", typ, typeListString(targs))
+		check.indent++
+		defer func() {
+			check.indent--
+			var under Type
+			if res != nil {
+				// Calling under() here may lead to endless instantiations.
+				// Test case: type T[P any] T[P]
+				// TODO(gri) investigate if that's a bug or to be expected.
+				under = res.Underlying()
+			}
+			check.trace(pos, "=> %s (under = %s)", res, under)
+		}()
+	}
+
+	assert(len(poslist) <= len(targs))
+
+	// TODO(gri) What is better here: work with TypeParams, or work with TypeNames?
+	var tparams []*TypeName
+	switch t := typ.(type) {
+	case *Named:
+		tparams = t.tparams
+	case *Signature:
+		tparams = t.tparams
+		defer func() {
+			// If we had an unexpected failure somewhere don't panic below when
+			// asserting res.(*Signature). Check for *Signature in case Typ[Invalid]
+			// is returned.
+			if _, ok := res.(*Signature); !ok {
+				return
+			}
+			// If the signature doesn't use its type parameters, subst
+			// will not make a copy. In that case, make a copy now (so
+			// we can set tparams to nil w/o causing side-effects).
+			if t == res {
+				copy := *t
+				res = &copy
+			}
+			// After instantiating a generic signature, it is not generic
+			// anymore; we need to set tparams to nil.
+			res.(*Signature).tparams = nil
+		}()
+
+	default:
+		check.dump("%v: cannot instantiate %v", pos, typ)
+		unreachable() // only defined types and (defined) functions can be generic
+
+	}
+
+	// the number of supplied types must match the number of type parameters
+	if len(targs) != len(tparams) {
+		// TODO(gri) provide better error message
+		check.errorf(pos, "got %d arguments but %d type parameters", len(targs), len(tparams))
+		return Typ[Invalid]
+	}
+
+	if len(tparams) == 0 {
+		return typ // nothing to do (minor optimization)
+	}
+
+	smap := makeSubstMap(tparams, targs)
+
+	// check bounds
+	for i, tname := range tparams {
+		tpar := tname.typ.(*TypeParam)
+		iface := tpar.Bound()
+		if iface.Empty() {
+			continue // no type bound
+		}
+
+		targ := targs[i]
+
+		// best position for error reporting
+		pos := pos
+		if i < len(poslist) {
+			pos = poslist[i]
+		}
+
+		// The type parameter bound is parameterized with the same type parameters
+		// as the instantiated type; before we can use it for bounds checking we
+		// need to instantiate it with the type arguments with which we instantiate
+		// the parameterized type.
+		iface = check.subst(pos, iface, smap).(*Interface)
+
+		// targ must implement iface (methods)
+		// - check only if we have methods
+		check.completeInterface(nopos, iface)
+		if len(iface.allMethods) > 0 {
+			// If the type argument is a pointer to a type parameter, the type argument's
+			// method set is empty.
+			// TODO(gri) is this what we want? (spec question)
+			if base, isPtr := deref(targ); isPtr && asTypeParam(base) != nil {
+				check.errorf(pos, "%s has no methods", targ)
+				break
+			}
+			if m, wrong := check.missingMethod(targ, iface, true); m != nil {
+				// TODO(gri) needs to print updated name to avoid major confusion in error message!
+				//           (print warning for now)
+				// Old warning:
+				// check.softErrorf(pos, "%s does not satisfy %s (warning: name not updated) = %s (missing method %s)", targ, tpar.bound, iface, m)
+				if m.name == "==" {
+					// We don't want to report "missing method ==".
+					check.softErrorf(pos, "%s does not satisfy comparable", targ)
+				} else if wrong != nil {
+					// TODO(gri) This can still report uninstantiated types which makes the error message
+					//           more difficult to read then necessary.
+					check.softErrorf(pos,
+						"%s does not satisfy %s: wrong method signature\n\tgot  %s\n\twant %s",
+						targ, tpar.bound, wrong, m,
+					)
+				} else {
+					check.softErrorf(pos, "%s does not satisfy %s (missing method %s)", targ, tpar.bound, m.name)
+				}
+				break
+			}
+		}
+
+		// targ's underlying type must also be one of the interface types listed, if any
+		if iface.allTypes == nil {
+			continue // nothing to do
+		}
+
+		// If targ is itself a type parameter, each of its possible types, but at least one, must be in the
+		// list of iface types (i.e., the targ type list must be a non-empty subset of the iface types).
+		if targ := asTypeParam(targ); targ != nil {
+			targBound := targ.Bound()
+			if targBound.allTypes == nil {
+				check.softErrorf(pos, "%s does not satisfy %s (%s has no type constraints)", targ, tpar.bound, targ)
+				break
+			}
+			for _, t := range unpack(targBound.allTypes) {
+				if !iface.isSatisfiedBy(t) {
+					// TODO(gri) match this error message with the one below (or vice versa)
+					check.softErrorf(pos, "%s does not satisfy %s (%s type constraint %s not found in %s)", targ, tpar.bound, targ, t, iface.allTypes)
+					break
+				}
+			}
+			break
+		}
+
+		// Otherwise, targ's type or underlying type must also be one of the interface types listed, if any.
+		if !iface.isSatisfiedBy(targ) {
+			check.softErrorf(pos, "%s does not satisfy %s (%s not found in %s)", targ, tpar.bound, under(targ), iface.allTypes)
+			break
+		}
+	}
+
+	return check.subst(pos, typ, smap)
+}
+
+// subst returns the type typ with its type parameters tpars replaced by
+// the corresponding type arguments targs, recursively.
+// subst is functional in the sense that it doesn't modify the incoming
+// type. If a substitution took place, the result type is different from
+// from the incoming type.
+func (check *Checker) subst(pos syntax.Pos, typ Type, smap *substMap) Type {
+	if smap.empty() {
+		return typ
+	}
+
+	// common cases
+	switch t := typ.(type) {
+	case *Basic:
+		return typ // nothing to do
+	case *TypeParam:
+		return smap.lookup(t)
+	}
+
+	// general case
+	subst := subster{check, pos, make(map[Type]Type), smap}
+	return subst.typ(typ)
+}
+
+type subster struct {
+	check *Checker
+	pos   syntax.Pos
+	cache map[Type]Type
+	smap  *substMap
+}
+
+func (subst *subster) typ(typ Type) Type {
+	switch t := typ.(type) {
+	case nil:
+		// Call typOrNil if it's possible that typ is nil.
+		panic("nil typ")
+
+	case *Basic, *bottom, *top:
+		// nothing to do
+
+	case *Array:
+		elem := subst.typOrNil(t.elem)
+		if elem != t.elem {
+			return &Array{len: t.len, elem: elem}
+		}
+
+	case *Slice:
+		elem := subst.typOrNil(t.elem)
+		if elem != t.elem {
+			return &Slice{elem: elem}
+		}
+
+	case *Struct:
+		if fields, copied := subst.varList(t.fields); copied {
+			return &Struct{fields: fields, tags: t.tags}
+		}
+
+	case *Pointer:
+		base := subst.typ(t.base)
+		if base != t.base {
+			return &Pointer{base: base}
+		}
+
+	case *Tuple:
+		return subst.tuple(t)
+
+	case *Signature:
+		// TODO(gri) rethink the recv situation with respect to methods on parameterized types
+		// recv := subst.var_(t.recv) // TODO(gri) this causes a stack overflow - explain
+		recv := t.recv
+		params := subst.tuple(t.params)
+		results := subst.tuple(t.results)
+		if recv != t.recv || params != t.params || results != t.results {
+			return &Signature{
+				rparams: t.rparams,
+				// TODO(gri) Why can't we nil out tparams here, rather than in
+				//           instantiate above?
+				tparams:  t.tparams,
+				scope:    t.scope,
+				recv:     recv,
+				params:   params,
+				results:  results,
+				variadic: t.variadic,
+			}
+		}
+
+	case *Sum:
+		types, copied := subst.typeList(t.types)
+		if copied {
+			// Don't do it manually, with a Sum literal: the new
+			// types list may not be unique and NewSum may remove
+			// duplicates.
+			return NewSum(types)
+		}
+
+	case *Interface:
+		methods, mcopied := subst.funcList(t.methods)
+		types := t.types
+		if t.types != nil {
+			types = subst.typ(t.types)
+		}
+		embeddeds, ecopied := subst.typeList(t.embeddeds)
+		if mcopied || types != t.types || ecopied {
+			iface := &Interface{methods: methods, types: types, embeddeds: embeddeds}
+			if subst.check == nil {
+				panic("internal error: cannot instantiate interfaces yet")
+			}
+			subst.check.posMap[iface] = subst.check.posMap[t] // satisfy completeInterface requirement
+			subst.check.completeInterface(nopos, iface)
+			return iface
+		}
+
+	case *Map:
+		key := subst.typ(t.key)
+		elem := subst.typ(t.elem)
+		if key != t.key || elem != t.elem {
+			return &Map{key: key, elem: elem}
+		}
+
+	case *Chan:
+		elem := subst.typ(t.elem)
+		if elem != t.elem {
+			return &Chan{dir: t.dir, elem: elem}
+		}
+
+	case *Named:
+		// dump is for debugging
+		dump := func(string, ...interface{}) {}
+		if subst.check != nil && subst.check.conf.Trace {
+			subst.check.indent++
+			defer func() {
+				subst.check.indent--
+			}()
+			dump = func(format string, args ...interface{}) {
+				subst.check.trace(subst.pos, format, args...)
+			}
+		}
+
+		if t.tparams == nil {
+			dump(">>> %s is not parameterized", t)
+			return t // type is not parameterized
+		}
+
+		var new_targs []Type
+
+		if len(t.targs) > 0 {
+			// already instantiated
+			dump(">>> %s already instantiated", t)
+			assert(len(t.targs) == len(t.tparams))
+			// For each (existing) type argument targ, determine if it needs
+			// to be substituted; i.e., if it is or contains a type parameter
+			// that has a type argument for it.
+			for i, targ := range t.targs {
+				dump(">>> %d targ = %s", i, targ)
+				new_targ := subst.typ(targ)
+				if new_targ != targ {
+					dump(">>> substituted %d targ %s => %s", i, targ, new_targ)
+					if new_targs == nil {
+						new_targs = make([]Type, len(t.tparams))
+						copy(new_targs, t.targs)
+					}
+					new_targs[i] = new_targ
+				}
+			}
+
+			if new_targs == nil {
+				dump(">>> nothing to substitute in %s", t)
+				return t // nothing to substitute
+			}
+		} else {
+			// not yet instantiated
+			dump(">>> first instantiation of %s", t)
+			new_targs = subst.smap.targs
+		}
+
+		// before creating a new named type, check if we have this one already
+		h := instantiatedHash(t, new_targs)
+		dump(">>> new type hash: %s", h)
+		if subst.check != nil {
+			if named, found := subst.check.typMap[h]; found {
+				dump(">>> found %s", named)
+				subst.cache[t] = named
+				return named
+			}
+		}
+
+		// create a new named type and populate caches to avoid endless recursion
+		tname := NewTypeName(subst.pos, t.obj.pkg, t.obj.name, nil)
+		named := subst.check.newNamed(tname, t, t.underlying, t.tparams, t.methods) // method signatures are updated lazily
+		named.targs = new_targs
+		if subst.check != nil {
+			subst.check.typMap[h] = named
+		}
+		subst.cache[t] = named
+
+		// do the substitution
+		dump(">>> subst %s with %s (new: %s)", t.underlying, subst.smap, new_targs)
+		named.underlying = subst.typOrNil(t.underlying)
+		named.fromRHS = named.underlying // for cycle detection (Checker.validType)
+
+		return named
+
+	case *TypeParam:
+		return subst.smap.lookup(t)
+
+	case *instance:
+		// TODO(gri) can we avoid the expansion here and just substitute the type parameters?
+		return subst.typ(t.expand())
+
+	default:
+		unimplemented()
+	}
+
+	return typ
+}
+
+// TODO(gri) Eventually, this should be more sophisticated.
+//           It won't work correctly for locally declared types.
+func instantiatedHash(typ *Named, targs []Type) string {
+	var buf bytes.Buffer
+	writeTypeName(&buf, typ.obj, nil)
+	buf.WriteByte('[')
+	writeTypeList(&buf, targs, nil, nil)
+	buf.WriteByte(']')
+
+	// With respect to the represented type, whether a
+	// type is fully expanded or stored as instance
+	// does not matter - they are the same types.
+	// Remove the instanceMarkers printed for instances.
+	res := buf.Bytes()
+	i := 0
+	for _, b := range res {
+		if b != instanceMarker {
+			res[i] = b
+			i++
+		}
+	}
+
+	return string(res[:i])
+}
+
+func typeListString(list []Type) string {
+	var buf bytes.Buffer
+	writeTypeList(&buf, list, nil, nil)
+	return buf.String()
+}
+
+// typOrNil is like typ but if the argument is nil it is replaced with Typ[Invalid].
+// A nil type may appear in pathological cases such as type T[P any] []func(_ T([]_))
+// where an array/slice element is accessed before it is set up.
+func (subst *subster) typOrNil(typ Type) Type {
+	if typ == nil {
+		return Typ[Invalid]
+	}
+	return subst.typ(typ)
+}
+
+func (subst *subster) var_(v *Var) *Var {
+	if v != nil {
+		if typ := subst.typ(v.typ); typ != v.typ {
+			copy := *v
+			copy.typ = typ
+			return &copy
+		}
+	}
+	return v
+}
+
+func (subst *subster) tuple(t *Tuple) *Tuple {
+	if t != nil {
+		if vars, copied := subst.varList(t.vars); copied {
+			return &Tuple{vars: vars}
+		}
+	}
+	return t
+}
+
+func (subst *subster) varList(in []*Var) (out []*Var, copied bool) {
+	out = in
+	for i, v := range in {
+		if w := subst.var_(v); w != v {
+			if !copied {
+				// first variable that got substituted => allocate new out slice
+				// and copy all variables
+				new := make([]*Var, len(in))
+				copy(new, out)
+				out = new
+				copied = true
+			}
+			out[i] = w
+		}
+	}
+	return
+}
+
+func (subst *subster) func_(f *Func) *Func {
+	if f != nil {
+		if typ := subst.typ(f.typ); typ != f.typ {
+			copy := *f
+			copy.typ = typ
+			return &copy
+		}
+	}
+	return f
+}
+
+func (subst *subster) funcList(in []*Func) (out []*Func, copied bool) {
+	out = in
+	for i, f := range in {
+		if g := subst.func_(f); g != f {
+			if !copied {
+				// first function that got substituted => allocate new out slice
+				// and copy all functions
+				new := make([]*Func, len(in))
+				copy(new, out)
+				out = new
+				copied = true
+			}
+			out[i] = g
+		}
+	}
+	return
+}
+
+func (subst *subster) typeList(in []Type) (out []Type, copied bool) {
+	out = in
+	for i, t := range in {
+		if u := subst.typ(t); u != t {
+			if !copied {
+				// first function that got substituted => allocate new out slice
+				// and copy all functions
+				new := make([]Type, len(in))
+				copy(new, out)
+				out = new
+				copied = true
+			}
+			out[i] = u
+		}
+	}
+	return
+}
diff --git a/src/go/types/testdata/blank.src b/src/cmd/compile/internal/types2/testdata/check/blank.src
similarity index 100%
copy from src/go/types/testdata/blank.src
copy to src/cmd/compile/internal/types2/testdata/check/blank.src
diff --git a/src/cmd/compile/internal/types2/testdata/check/builtins.go2 b/src/cmd/compile/internal/types2/testdata/check/builtins.go2
new file mode 100644
index 0000000..3918d83
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/builtins.go2
@@ -0,0 +1,53 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file tests built-in calls on generic types.
+
+package builtins
+
+type Bmc interface {
+	type map[rune]string, chan int
+}
+
+type Bms interface {
+	type map[string]int, []int
+}
+
+type Bcs interface {
+	type chan bool, []float64
+}
+
+type Bss interface {
+	type []int, []string
+}
+
+func _[T any] () {
+	_ = make(T /* ERROR invalid argument */ )
+	_ = make(T /* ERROR invalid argument */ , 10)
+	_ = make(T /* ERROR invalid argument */ , 10, 20)
+}
+
+func _[T Bmc] () {
+	_ = make(T)
+	_ = make(T, 10)
+	_ = make /* ERROR expects 1 or 2 arguments */ (T, 10, 20)
+}
+
+func _[T Bms] () {
+	_ = make /* ERROR expects 2 arguments */ (T)
+	_ = make(T, 10)
+	_ = make /* ERROR expects 2 arguments */ (T, 10, 20)
+}
+
+func _[T Bcs] () {
+	_ = make /* ERROR expects 2 arguments */ (T)
+	_ = make(T, 10)
+	_ = make /* ERROR expects 2 arguments */ (T, 10, 20)
+}
+
+func _[T Bss] () {
+	_ = make /* ERROR expects 2 or 3 arguments */ (T)
+	_ = make(T, 10)
+	_ = make(T, 10, 20)
+}
diff --git a/src/cmd/compile/internal/types2/testdata/check/builtins.src b/src/cmd/compile/internal/types2/testdata/check/builtins.src
new file mode 100644
index 0000000..6d1f471
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/builtins.src
@@ -0,0 +1,902 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// builtin calls
+
+package builtins
+
+import "unsafe"
+
+func f0() {}
+
+func append1() {
+	var b byte
+	var x int
+	var s []byte
+	_ = append() // ERROR not enough arguments
+	_ = append("foo" /* ERROR not a slice */ )
+	_ = append(nil /* ERROR not a slice */ , s)
+	_ = append(x /* ERROR not a slice */ , s)
+	_ = append(s)
+	_ = append(s, nil...)
+	append /* ERROR not used */ (s)
+
+	_ = append(s, b)
+	_ = append(s, x /* ERROR cannot use x */ )
+	_ = append(s, s /* ERROR cannot use s */ )
+	_ = append(s... ) /* ERROR not enough arguments */
+	_ = append(s, b, s /* ERROR too many arguments */ ... )
+	_ = append(s, 1, 2, 3)
+	_ = append(s, 1, 2, 3, x /* ERROR cannot use x */ , 5, 6, 6)
+	_ = append(s, 1, 2 /* ERROR too many arguments */ , s... )
+	_ = append([]interface{}(nil), 1, 2, "foo", x, 3.1425, false)
+
+	type S []byte
+	type T string
+	var t T
+	_ = append(s, "foo" /* ERROR cannot use .* in argument to append */ )
+	_ = append(s, "foo"...)
+	_ = append(S(s), "foo" /* ERROR cannot use .* in argument to append */ )
+	_ = append(S(s), "foo"...)
+	_ = append(s, t /* ERROR cannot use t */ )
+	_ = append(s, t...)
+	_ = append(s, T("foo")...)
+	_ = append(S(s), t /* ERROR cannot use t */ )
+	_ = append(S(s), t...)
+	_ = append(S(s), T("foo")...)
+	_ = append([]string{}, t /* ERROR cannot use t */ , "foo")
+	_ = append([]T{}, t, "foo")
+}
+
+// from the spec
+func append2() {
+	s0 := []int{0, 0}
+	s1 := append(s0, 2)                // append a single element     s1 == []int{0, 0, 2}
+	s2 := append(s1, 3, 5, 7)          // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
+	s3 := append(s2, s0...)            // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
+	s4 := append(s3[3:6], s3[2:]...)   // append overlapping slice    s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
+
+	var t []interface{}
+	t = append(t, 42, 3.1415, "foo")   //                             t == []interface{}{42, 3.1415, "foo"}
+
+	var b []byte
+	b = append(b, "bar"...)            // append string contents      b == []byte{'b', 'a', 'r' }
+
+	_ = s4
+}
+
+func append3() {
+	f1 := func() (s []int) { return }
+	f2 := func() (s []int, x int) { return }
+	f3 := func() (s []int, x, y int) { return }
+	f5 := func() (s []interface{}, x int, y float32, z string, b bool) { return }
+	ff := func() (int, float32) { return 0, 0 }
+	_ = append(f0 /* ERROR used as value */ ())
+	_ = append(f1())
+	_ = append(f2())
+	_ = append(f3())
+	_ = append(f5())
+	_ = append(ff /* ERROR not a slice */ ()) // TODO(gri) better error message
+}
+
+func cap1() {
+	var a [10]bool
+	var p *[20]int
+	var c chan string
+	_ = cap() // ERROR not enough arguments
+	_ = cap(1, 2) // ERROR too many arguments
+	_ = cap(42 /* ERROR invalid */)
+	const _3 = cap(a)
+	assert(_3 == 10)
+	const _4 = cap(p)
+	assert(_4 == 20)
+	_ = cap(c)
+	cap /* ERROR not used */ (c)
+
+	// issue 4744
+	type T struct{ a [10]int }
+	const _ = cap(((*T)(nil)).a)
+
+	var s [][]byte
+	_ = cap(s)
+	_ = cap(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func cap2() {
+	f1a := func() (a [10]int) { return }
+	f1s := func() (s []int) { return }
+	f2 := func() (s []int, x int) { return }
+	_ = cap(f0 /* ERROR used as value */ ())
+	_ = cap(f1a())
+	_ = cap(f1s())
+	_ = cap(f2()) // ERROR too many arguments
+}
+
+// test cases for issue 7387
+func cap3() {
+	var f = func() int { return 0 }
+	var x = f()
+	const (
+		_ = cap([4]int{})
+		_ = cap([4]int{x})
+		_ = cap /* ERROR not constant */ ([4]int{f()})
+		_ = cap /* ERROR not constant */ ([4]int{cap([]int{})})
+		_ = cap([4]int{cap([4]int{})})
+	)
+	var y float64
+	var z complex128
+	const (
+		_ = cap([4]float64{})
+		_ = cap([4]float64{y})
+		_ = cap([4]float64{real(2i)})
+		_ = cap /* ERROR not constant */ ([4]float64{real(z)})
+	)
+	var ch chan [10]int
+	const (
+		_ = cap /* ERROR not constant */ (<-ch)
+		_ = cap /* ERROR not constant */ ([4]int{(<-ch)[0]})
+	)
+}
+
+func close1() {
+	var c chan int
+	var r <-chan int
+	close() // ERROR not enough arguments
+	close(1, 2) // ERROR too many arguments
+	close(42 /* ERROR not a channel */)
+	close(r /* ERROR receive-only channel */)
+	close(c)
+	_ = close /* ERROR used as value */ (c)
+
+	var s []chan int
+	close(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func close2() {
+	f1 := func() (ch chan int) { return }
+	f2 := func() (ch chan int, x int) { return }
+	close(f0 /* ERROR used as value */ ())
+	close(f1())
+	close(f2()) // ERROR too many arguments
+}
+
+func complex1() {
+	var i32 int32
+	var f32 float32
+	var f64 float64
+	var c64 complex64
+	var c128 complex128
+	_ = complex() // ERROR not enough arguments
+	_ = complex(1) // ERROR not enough arguments
+	_ = complex(true /* ERROR mismatched types */ , 0)
+	_ = complex(i32 /* ERROR expected floating-point */ , 0)
+	_ = complex("foo" /* ERROR mismatched types */ , 0)
+	_ = complex(c64 /* ERROR expected floating-point */ , 0)
+	_ = complex(0 /* ERROR mismatched types */ , true)
+	_ = complex(0 /* ERROR expected floating-point */ , i32)
+	_ = complex(0 /* ERROR mismatched types */ , "foo")
+	_ = complex(0 /* ERROR expected floating-point */ , c64)
+	_ = complex(f32, f32)
+	_ = complex(f32, 1)
+	_ = complex(f32, 1.0)
+	_ = complex(f32, 'a')
+	_ = complex(f64, f64)
+	_ = complex(f64, 1)
+	_ = complex(f64, 1.0)
+	_ = complex(f64, 'a')
+	_ = complex(f32 /* ERROR mismatched types */ , f64)
+	_ = complex(f64 /* ERROR mismatched types */ , f32)
+	_ = complex(1, 1)
+	_ = complex(1, 1.1)
+	_ = complex(1, 'a')
+	complex /* ERROR not used */ (1, 2)
+
+	var _ complex64 = complex(f32, f32)
+	var _ complex64 = complex /* ERROR cannot use .* in variable declaration */ (f64, f64)
+
+	var _ complex128 = complex /* ERROR cannot use .* in variable declaration */ (f32, f32)
+	var _ complex128 = complex(f64, f64)
+
+	// untyped constants
+	const _ int = complex(1, 0)
+	const _ float32 = complex(1, 0)
+	const _ complex64 = complex(1, 0)
+	const _ complex128 = complex(1, 0)
+	const _ = complex(0i, 0i)
+	const _ = complex(0i, 0)
+	const _ int = 1.0 + complex(1, 0i)
+
+	const _ int = complex /* ERROR int */ (1.1, 0)
+	const _ float32 = complex /* ERROR float32 */ (1, 2)
+
+	// untyped values
+	var s uint
+	_ = complex(1 /* ERROR integer */ <<s, 0)
+	const _ = complex /* ERROR not constant */ (1 /* ERROR integer */ <<s, 0)
+	var _ int = complex /* ERROR cannot use .* in variable declaration */ (1 /* ERROR integer */ <<s, 0)
+
+	// floating-point argument types must be identical
+	type F32 float32
+	type F64 float64
+	var x32 F32
+	var x64 F64
+	c64 = complex(x32, x32)
+	_ = complex(x32 /* ERROR mismatched types */ , f32)
+	_ = complex(f32 /* ERROR mismatched types */ , x32)
+	c128 = complex(x64, x64)
+	_ = c128
+	_ = complex(x64 /* ERROR mismatched types */ , f64)
+	_ = complex(f64 /* ERROR mismatched types */ , x64)
+
+	var t []float32
+	_ = complex(t... /* ERROR invalid use of \.\.\. */ )
+}
+
+func complex2() {
+	f1 := func() (x float32) { return }
+	f2 := func() (x, y float32) { return }
+	f3 := func() (x, y, z float32) { return }
+	_ = complex(f0 /* ERROR used as value */ ())
+	_ = complex(f1()) // ERROR not enough arguments
+	_ = complex(f2())
+	_ = complex(f3()) // ERROR too many arguments
+}
+
+func copy1() {
+	copy() // ERROR not enough arguments
+	copy("foo") // ERROR not enough arguments
+	copy([ /* ERROR copy expects slice arguments */ ...]int{}, []int{})
+	copy([ /* ERROR copy expects slice arguments */ ]int{}, [...]int{})
+	copy([ /* ERROR different element types */ ]int8{}, "foo")
+
+	// spec examples
+	var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
+	var s = make([]int, 6)
+	var b = make([]byte, 5)
+	n1 := copy(s, a[0:])            // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
+	n2 := copy(s, s[2:])            // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
+	n3 := copy(b, "Hello, World!")  // n3 == 5, b == []byte("Hello")
+	_, _, _ = n1, n2, n3
+
+	var t [][]int
+	copy(t, t)
+	copy(t /* ERROR copy expects slice arguments */ , nil)
+	copy(nil /* ERROR copy expects slice arguments */ , t)
+	copy(nil /* ERROR copy expects slice arguments */ , nil)
+	copy(t... /* ERROR invalid use of \.\.\. */ )
+}
+
+func copy2() {
+	f1 := func() (a []int) { return }
+	f2 := func() (a, b []int) { return }
+	f3 := func() (a, b, c []int) { return }
+	copy(f0 /* ERROR used as value */ ())
+	copy(f1()) // ERROR not enough arguments
+	copy(f2())
+	copy(f3()) // ERROR too many arguments
+}
+
+func delete1() {
+	var m map[string]int
+	var s string
+	delete() // ERROR not enough arguments
+	delete(1) // ERROR not enough arguments
+	delete(1, 2, 3) // ERROR too many arguments
+	delete(m, 0 /* ERROR cannot use */)
+	delete(m, s)
+	_ = delete /* ERROR used as value */ (m, s)
+
+	var t []map[string]string
+	delete(t... /* ERROR invalid use of \.\.\. */ )
+}
+
+func delete2() {
+	f1 := func() (m map[string]int) { return }
+	f2 := func() (m map[string]int, k string) { return }
+	f3 := func() (m map[string]int, k string, x float32) { return }
+	delete(f0 /* ERROR used as value */ ())
+	delete(f1()) // ERROR not enough arguments
+	delete(f2())
+	delete(f3()) // ERROR too many arguments
+}
+
+func imag1() {
+	var f32 float32
+	var f64 float64
+	var c64 complex64
+	var c128 complex128
+	_ = imag() // ERROR not enough arguments
+	_ = imag(1, 2) // ERROR too many arguments
+	_ = imag(10)
+	_ = imag(2.7182818)
+	_ = imag("foo" /* ERROR expected complex */)
+	_ = imag('a')
+	const _5 = imag(1 + 2i)
+	assert(_5 == 2)
+	f32 = _5
+	f64 = _5
+	const _6 = imag(0i)
+	assert(_6 == 0)
+	f32 = imag(c64)
+	f64 = imag(c128)
+	f32 = imag /* ERROR cannot use .* in assignment */ (c128)
+	f64 = imag /* ERROR cannot use .* in assignment */ (c64)
+	imag /* ERROR not used */ (c64)
+	_, _ = f32, f64
+
+	// complex type may not be predeclared
+	type C64 complex64
+	type C128 complex128
+	var x64 C64
+	var x128 C128
+	f32 = imag(x64)
+	f64 = imag(x128)
+
+	var a []complex64
+	_ = imag(a... /* ERROR invalid use of \.\.\. */ )
+
+	// if argument is untyped, result is untyped
+	const _ byte = imag(1.2 + 3i)
+	const _ complex128 = imag(1.2 + 3i)
+
+	// lhs constant shift operands are typed as complex128
+	var s uint
+	_ = imag(1 /* ERROR must be integer */ << s)
+}
+
+func imag2() {
+	f1 := func() (x complex128) { return }
+	f2 := func() (x, y complex128) { return }
+	_ = imag(f0 /* ERROR used as value */ ())
+	_ = imag(f1())
+	_ = imag(f2()) // ERROR too many arguments
+}
+
+func len1() {
+	const c = "foobar"
+	var a [10]bool
+	var p *[20]int
+	var m map[string]complex128
+	_ = len() // ERROR not enough arguments
+	_ = len(1, 2) // ERROR too many arguments
+	_ = len(42 /* ERROR invalid */)
+	const _3 = len(c)
+	assert(_3 == 6)
+	const _4 = len(a)
+	assert(_4 == 10)
+	const _5 = len(p)
+	assert(_5 == 20)
+	_ = len(m)
+	len /* ERROR not used */ (c)
+
+	// esoteric case
+	var t string
+	var hash map[interface{}][]*[10]int
+	const n = len /* ERROR not constant */ (hash[recover()][len(t)])
+	assert(n == 10) // ok because n has unknown value and no error is reported
+	var ch <-chan int
+	const nn = len /* ERROR not constant */ (hash[<-ch][len(t)])
+
+	// issue 4744
+	type T struct{ a [10]int }
+	const _ = len(((*T)(nil)).a)
+
+	var s [][]byte
+	_ = len(s)
+	_ = len(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func len2() {
+	f1 := func() (x []int) { return }
+	f2 := func() (x, y []int) { return }
+	_ = len(f0 /* ERROR used as value */ ())
+	_ = len(f1())
+	_ = len(f2()) // ERROR too many arguments
+}
+
+// test cases for issue 7387
+func len3() {
+	var f = func() int { return 0 }
+	var x = f()
+	const (
+		_ = len([4]int{})
+		_ = len([4]int{x})
+		_ = len /* ERROR not constant */ ([4]int{f()})
+		_ = len /* ERROR not constant */ ([4]int{len([]int{})})
+		_ = len([4]int{len([4]int{})})
+	)
+	var y float64
+	var z complex128
+	const (
+		_ = len([4]float64{})
+		_ = len([4]float64{y})
+		_ = len([4]float64{real(2i)})
+		_ = len /* ERROR not constant */ ([4]float64{real(z)})
+	)
+	var ch chan [10]int
+	const (
+		_ = len /* ERROR not constant */ (<-ch)
+		_ = len /* ERROR not constant */ ([4]int{(<-ch)[0]})
+	)
+}
+
+func make1() {
+	var n int
+	var m float32
+	var s uint
+
+	_ = make() // ERROR not enough arguments
+	_ = make(1 /* ERROR not a type */)
+	_ = make(int /* ERROR cannot make */)
+
+	// slices
+	_ = make/* ERROR arguments */ ([]int)
+	_ = make/* ERROR arguments */ ([]int, 2, 3, 4)
+	_ = make([]int, int /* ERROR not an expression */)
+	_ = make([]int, 10, float32 /* ERROR not an expression */)
+	_ = make([]int, "foo" /* ERROR cannot convert */)
+	_ = make([]int, 10, 2.3 /* ERROR truncated */)
+	_ = make([]int, 5, 10.0)
+	_ = make([]int, 0i)
+	_ = make([]int, 1.0)
+	_ = make([]int, 1.0<<s)
+	_ = make([]int, 1.1 /* ERROR int */ <<s)
+	_ = make([]int, - /* ERROR must not be negative */ 1, 10)
+	_ = make([]int, 0, - /* ERROR must not be negative */ 1)
+	_ = make([]int, - /* ERROR must not be negative */ 1, - /* ERROR must not be negative */ 1)
+	_ = make([]int, 1 /* ERROR overflows */ <<100, 1 /* ERROR overflows */ <<100)
+	_ = make([]int, 10 /* ERROR length and capacity swapped */ , 9)
+	_ = make([]int, 1 /* ERROR overflows */ <<100, 12345)
+	_ = make([]int, m /* ERROR must be integer */ )
+        _ = &make /* ERROR cannot take address */ ([]int, 0)
+
+	// maps
+	_ = make /* ERROR arguments */ (map[int]string, 10, 20)
+	_ = make(map[int]float32, int /* ERROR not an expression */)
+	_ = make(map[int]float32, "foo" /* ERROR cannot convert */)
+	_ = make(map[int]float32, 10)
+	_ = make(map[int]float32, n)
+	_ = make(map[int]float32, int64(n))
+	_ = make(map[string]bool, 10.0)
+	_ = make(map[string]bool, 10.0<<s)
+        _ = &make /* ERROR cannot take address */ (map[string]bool)
+
+	// channels
+	_ = make /* ERROR arguments */ (chan int, 10, 20)
+	_ = make(chan int, int /* ERROR not an expression */)
+	_ = make(chan<- int, "foo" /* ERROR cannot convert */)
+	_ = make(chan int, - /* ERROR must not be negative */ 10)
+	_ = make(<-chan float64, 10)
+	_ = make(chan chan int, n)
+	_ = make(chan string, int64(n))
+	_ = make(chan bool, 10.0)
+	_ = make(chan bool, 10.0<<s)
+        _ = &make /* ERROR cannot take address */ (chan bool)
+
+	make /* ERROR not used */ ([]int, 10)
+
+	var t []int
+	_ = make([]int, t[0], t[1])
+	_ = make([]int, t... /* ERROR invalid use of \.\.\. */ )
+}
+
+func make2() {
+	f1 := func() (x []int) { return }
+	_ = make(f0 /* ERROR not a type */ ())
+	_ = make(f1 /* ERROR not a type */ ())
+}
+
+func new1() {
+	_ = new() // ERROR not enough arguments
+	_ = new(1, 2) // ERROR too many arguments
+	_ = new("foo" /* ERROR not a type */)
+	p := new(float64)
+	_ = new(struct{ x, y int })
+	q := new(*float64)
+	_ = *p == **q
+	new /* ERROR not used */ (int)
+        _ = &new /* ERROR cannot take address */ (int)
+
+	_ = new(int... /* ERROR invalid use of \.\.\. */ )
+}
+
+func new2() {
+	f1 := func() (x []int) { return }
+	_ = new(f0 /* ERROR not a type */ ())
+	_ = new(f1 /* ERROR not a type */ ())
+}
+
+func panic1() {
+	panic() // ERROR not enough arguments
+	panic(1, 2) // ERROR too many arguments
+	panic(0)
+	panic("foo")
+	panic(false)
+	panic(1<<10)
+	panic(1 << /* ERROR constant shift overflow */ 1000)
+	_ = panic /* ERROR used as value */ (0)
+
+	var s []byte
+	panic(s)
+	panic(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func panic2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x, y int) { return }
+	panic(f0 /* ERROR used as value */ ())
+	panic(f1())
+	panic(f2()) // ERROR too many arguments
+}
+
+func print1() {
+	print()
+	print(1)
+	print(1, 2)
+	print("foo")
+	print(2.718281828)
+	print(false)
+	print(1<<10)
+	print(1 << /* ERROR constant shift overflow */ 1000)
+	println(nil /* ERROR untyped nil */ )
+
+	var s []int
+	print(s... /* ERROR invalid use of \.\.\. */ )
+	_ = print /* ERROR used as value */ ()
+}
+
+func print2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x, y int) { return }
+	f3 := func() (x int, y float32, z string) { return }
+	print(f0 /* ERROR used as value */ ())
+	print(f1())
+	print(f2())
+	print(f3())
+}
+
+func println1() {
+	println()
+	println(1)
+	println(1, 2)
+	println("foo")
+	println(2.718281828)
+	println(false)
+	println(1<<10)
+	println(1 << /* ERROR constant shift overflow */ 1000)
+	println(nil /* ERROR untyped nil */ )
+
+	var s []int
+	println(s... /* ERROR invalid use of \.\.\. */ )
+	_ = println /* ERROR used as value */ ()
+}
+
+func println2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x, y int) { return }
+	f3 := func() (x int, y float32, z string) { return }
+	println(f0 /* ERROR used as value */ ())
+	println(f1())
+	println(f2())
+	println(f3())
+}
+
+func real1() {
+	var f32 float32
+	var f64 float64
+	var c64 complex64
+	var c128 complex128
+	_ = real() // ERROR not enough arguments
+	_ = real(1, 2) // ERROR too many arguments
+	_ = real(10)
+	_ = real(2.7182818)
+	_ = real("foo" /* ERROR expected complex */)
+	const _5 = real(1 + 2i)
+	assert(_5 == 1)
+	f32 = _5
+	f64 = _5
+	const _6 = real(0i)
+	assert(_6 == 0)
+	f32 = real(c64)
+	f64 = real(c128)
+	f32 = real /* ERROR cannot use .* in assignment */ (c128)
+	f64 = real /* ERROR cannot use .* in assignment */ (c64)
+	real /* ERROR not used */ (c64)
+
+	// complex type may not be predeclared
+	type C64 complex64
+	type C128 complex128
+	var x64 C64
+	var x128 C128
+	f32 = imag(x64)
+	f64 = imag(x128)
+	_, _ = f32, f64
+
+	var a []complex64
+	_ = real(a... /* ERROR invalid use of \.\.\. */ )
+
+	// if argument is untyped, result is untyped
+	const _ byte = real(1 + 2.3i)
+	const _ complex128 = real(1 + 2.3i)
+
+	// lhs constant shift operands are typed as complex128
+	var s uint
+	_ = real(1 /* ERROR must be integer */ << s)
+}
+
+func real2() {
+	f1 := func() (x complex128) { return }
+	f2 := func() (x, y complex128) { return }
+	_ = real(f0 /* ERROR used as value */ ())
+	_ = real(f1())
+	_ = real(f2()) // ERROR too many arguments
+}
+
+func recover1() {
+	_ = recover()
+	_ = recover(10) // ERROR too many arguments
+	recover()
+
+	var s []int
+	recover(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func recover2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x, y int) { return }
+	_ = recover(f0 /* ERROR used as value */ ())
+	_ = recover(f1()) // ERROR too many arguments
+	_ = recover(f2()) // ERROR too many arguments
+}
+
+// assuming types.DefaultPtrSize == 8
+type S0 struct{      // offset
+	a bool       //  0
+	b rune       //  4
+	c *int       //  8
+	d bool       // 16
+	e complex128 // 24
+}                    // 40
+
+type S1 struct{   // offset
+	x float32 //  0
+	y string  //  8
+	z *S1     // 24
+	S0        // 32
+}                 // 72
+
+type S2 struct{ // offset
+	*S1     //  0
+}               //  8
+
+type S3 struct { // offset
+	a int64  //  0
+	b int32  //  8
+}                // 12
+
+type S4 struct { // offset
+	S3       //  0
+	int32    // 12
+}                // 16
+
+type S5 struct {   // offset
+	a [3]int32 //  0
+	b int32    // 12
+}                  // 16
+
+func (S2) m() {}
+
+func Alignof1() {
+	var x int
+	_ = unsafe.Alignof() // ERROR not enough arguments
+	_ = unsafe.Alignof(1, 2) // ERROR too many arguments
+	_ = unsafe.Alignof(int /* ERROR not an expression */)
+	_ = unsafe.Alignof(42)
+	_ = unsafe.Alignof(new(struct{}))
+	_ = unsafe.Alignof(1<<10)
+	_ = unsafe.Alignof(1 << /* ERROR constant shift overflow */ 1000)
+	_ = unsafe.Alignof(nil /* ERROR "untyped nil */ )
+	unsafe /* ERROR not used */ .Alignof(x)
+
+	var y S0
+	assert(unsafe.Alignof(y.a) == 1)
+	assert(unsafe.Alignof(y.b) == 4)
+	assert(unsafe.Alignof(y.c) == 8)
+	assert(unsafe.Alignof(y.d) == 1)
+	assert(unsafe.Alignof(y.e) == 8)
+
+	var s []byte
+	_ = unsafe.Alignof(s)
+	_ = unsafe.Alignof(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func Alignof2() {
+	f1 := func() (x int32) { return }
+	f2 := func() (x, y int32) { return }
+	_ = unsafe.Alignof(f0 /* ERROR used as value */ ())
+	assert(unsafe.Alignof(f1()) == 4)
+	_ = unsafe.Alignof(f2()) // ERROR too many arguments
+}
+
+func Offsetof1() {
+	var x struct{ f int }
+	_ = unsafe.Offsetof() // ERROR not enough arguments
+	_ = unsafe.Offsetof(1, 2) // ERROR too many arguments
+	_ = unsafe.Offsetof(int /* ERROR not a selector expression */ )
+	_ = unsafe.Offsetof(x /* ERROR not a selector expression */ )
+	_ = unsafe.Offsetof(nil /* ERROR not a selector expression */ )
+	_ = unsafe.Offsetof(x.f)
+	_ = unsafe.Offsetof((x.f))
+	_ = unsafe.Offsetof((((((((x))).f)))))
+	unsafe /* ERROR not used */ .Offsetof(x.f)
+
+	var y0 S0
+	assert(unsafe.Offsetof(y0.a) == 0)
+	assert(unsafe.Offsetof(y0.b) == 4)
+	assert(unsafe.Offsetof(y0.c) == 8)
+	assert(unsafe.Offsetof(y0.d) == 16)
+	assert(unsafe.Offsetof(y0.e) == 24)
+
+	var y1 S1
+	assert(unsafe.Offsetof(y1.x) == 0)
+	assert(unsafe.Offsetof(y1.y) == 8)
+	assert(unsafe.Offsetof(y1.z) == 24)
+	assert(unsafe.Offsetof(y1.S0) == 32)
+
+	assert(unsafe.Offsetof(y1.S0.a) == 0) // relative to S0
+	assert(unsafe.Offsetof(y1.a) == 32)   // relative to S1
+	assert(unsafe.Offsetof(y1.b) == 36)   // relative to S1
+	assert(unsafe.Offsetof(y1.c) == 40)   // relative to S1
+	assert(unsafe.Offsetof(y1.d) == 48)   // relative to S1
+	assert(unsafe.Offsetof(y1.e) == 56)   // relative to S1
+
+	var y1p *S1
+	assert(unsafe.Offsetof(y1p.S0) == 32)
+
+	type P *S1
+	var p P = y1p
+	assert(unsafe.Offsetof(p.S0) == 32)
+
+	var y2 S2
+	assert(unsafe.Offsetof(y2.S1) == 0)
+	_ = unsafe.Offsetof(y2 /* ERROR embedded via a pointer */ .x)
+	_ = unsafe.Offsetof(y2 /* ERROR method value */ .m)
+
+	var s []byte
+	_ = unsafe.Offsetof(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func Offsetof2() {
+	f1 := func() (x int32) { return }
+	f2 := func() (x, y int32) { return }
+	_ = unsafe.Offsetof(f0 /* ERROR not a selector expression */ ())
+	_ = unsafe.Offsetof(f1 /* ERROR not a selector expression */ ())
+	_ = unsafe.Offsetof(f2 /* ERROR not a selector expression */ ())
+}
+
+func Sizeof1() {
+	var x int
+	_ = unsafe.Sizeof() // ERROR not enough arguments
+	_ = unsafe.Sizeof(1, 2) // ERROR too many arguments
+	_ = unsafe.Sizeof(int /* ERROR not an expression */)
+	_ = unsafe.Sizeof(42)
+	_ = unsafe.Sizeof(new(complex128))
+	_ = unsafe.Sizeof(1<<10)
+	_ = unsafe.Sizeof(1 << /* ERROR constant shift overflow */ 1000)
+	_ = unsafe.Sizeof(nil /* ERROR untyped nil */ )
+	unsafe /* ERROR not used */ .Sizeof(x)
+
+	// basic types have size guarantees
+	assert(unsafe.Sizeof(byte(0)) == 1)
+	assert(unsafe.Sizeof(uint8(0)) == 1)
+	assert(unsafe.Sizeof(int8(0)) == 1)
+	assert(unsafe.Sizeof(uint16(0)) == 2)
+	assert(unsafe.Sizeof(int16(0)) == 2)
+	assert(unsafe.Sizeof(uint32(0)) == 4)
+	assert(unsafe.Sizeof(int32(0)) == 4)
+	assert(unsafe.Sizeof(float32(0)) == 4)
+	assert(unsafe.Sizeof(uint64(0)) == 8)
+	assert(unsafe.Sizeof(int64(0)) == 8)
+	assert(unsafe.Sizeof(float64(0)) == 8)
+	assert(unsafe.Sizeof(complex64(0)) == 8)
+	assert(unsafe.Sizeof(complex128(0)) == 16)
+
+	var y0 S0
+	assert(unsafe.Sizeof(y0.a) == 1)
+	assert(unsafe.Sizeof(y0.b) == 4)
+	assert(unsafe.Sizeof(y0.c) == 8)
+	assert(unsafe.Sizeof(y0.d) == 1)
+	assert(unsafe.Sizeof(y0.e) == 16)
+	assert(unsafe.Sizeof(y0) == 40)
+
+	var y1 S1
+	assert(unsafe.Sizeof(y1) == 72)
+
+	var y2 S2
+	assert(unsafe.Sizeof(y2) == 8)
+
+	var y3 S3
+	assert(unsafe.Sizeof(y3) == 12)
+
+	var y4 S4
+	assert(unsafe.Sizeof(y4) == 16)
+
+	var y5 S5
+	assert(unsafe.Sizeof(y5) == 16)
+
+	var a3 [10]S3
+	assert(unsafe.Sizeof(a3) == 156)
+
+	// test case for issue 5670
+	type T struct {
+		a int32
+		_ int32
+		c int32
+	}
+	assert(unsafe.Sizeof(T{}) == 12)
+
+	var s []byte
+	_ = unsafe.Sizeof(s)
+	_ = unsafe.Sizeof(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func Sizeof2() {
+	f1 := func() (x int64) { return }
+	f2 := func() (x, y int64) { return }
+	_ = unsafe.Sizeof(f0 /* ERROR used as value */ ())
+	assert(unsafe.Sizeof(f1()) == 8)
+	_ = unsafe.Sizeof(f2()) // ERROR too many arguments
+}
+
+// self-testing only
+func assert1() {
+	var x int
+	assert() /* ERROR not enough arguments */
+	assert(1, 2) /* ERROR too many arguments */
+	assert("foo" /* ERROR boolean constant */ )
+	assert(x /* ERROR boolean constant */)
+	assert(true)
+	assert /* ERROR failed */ (false)
+	_ = assert(true)
+
+	var s []byte
+	assert(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func assert2() {
+	f1 := func() (x bool) { return }
+	f2 := func() (x bool) { return }
+	assert(f0 /* ERROR used as value */ ())
+	assert(f1 /* ERROR boolean constant */ ())
+	assert(f2 /* ERROR boolean constant */ ())
+}
+
+// self-testing only
+func trace1() {
+	// Uncomment the code below to test trace - will produce console output
+	// _ = trace /* ERROR no value */ ()
+	// _ = trace(1)
+	// _ = trace(true, 1.2, '\'', "foo", 42i, "foo" <= "bar")
+
+	var s []byte
+	trace(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func trace2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x int, y string) { return }
+	f3 := func() (x int, y string, z []int) { return }
+	_ = f1
+	_ = f2
+	_ = f3
+	// Uncomment the code below to test trace - will produce console output
+	// trace(f0())
+	// trace(f1())
+	// trace(f2())
+	// trace(f3())
+	// trace(f0(), 1)
+	// trace(f1(), 1, 2)
+	// trace(f2(), 1, 2, 3)
+	// trace(f3(), 1, 2, 3, 4)
+}
diff --git a/src/cmd/compile/internal/types2/testdata/check/chans.go2 b/src/cmd/compile/internal/types2/testdata/check/chans.go2
new file mode 100644
index 0000000..fad2bce
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/chans.go2
@@ -0,0 +1,62 @@
+package chans
+
+import "runtime"
+
+// Ranger returns a Sender and a Receiver. The Receiver provides a
+// Next method to retrieve values. The Sender provides a Send method
+// to send values and a Close method to stop sending values. The Next
+// method indicates when the Sender has been closed, and the Send
+// method indicates when the Receiver has been freed.
+//
+// This is a convenient way to exit a goroutine sending values when
+// the receiver stops reading them.
+func Ranger[T any]() (*Sender[T], *Receiver[T]) {
+	c := make(chan T)
+	d := make(chan bool)
+	s := &Sender[T]{values: c, done: d}
+	r := &Receiver[T]{values: c, done: d}
+	runtime.SetFinalizer(r, r.finalize)
+	return s, r
+}
+
+// A sender is used to send values to a Receiver.
+type Sender[T any] struct {
+	values chan<- T
+	done <-chan bool
+}
+
+// Send sends a value to the receiver. It returns whether any more
+// values may be sent; if it returns false the value was not sent.
+func (s *Sender[T]) Send(v T) bool {
+	select {
+	case s.values <- v:
+		return true
+	case <-s.done:
+		return false
+	}
+}
+
+// Close tells the receiver that no more values will arrive.
+// After Close is called, the Sender may no longer be used.
+func (s *Sender[T]) Close() {
+	close(s.values)
+}
+
+// A Receiver receives values from a Sender.
+type Receiver[T any] struct {
+	values <-chan T
+	done chan<- bool
+}
+
+// Next returns the next value from the channel. The bool result
+// indicates whether the value is valid, or whether the Sender has
+// been closed and no more values will be received.
+func (r *Receiver[T]) Next() (T, bool) {
+	v, ok := <-r.values
+	return v, ok
+}
+
+// finalize is a finalizer for the receiver.
+func (r *Receiver[T]) finalize() {
+	close(r.done)
+}
diff --git a/src/cmd/compile/internal/types2/testdata/check/const0.src b/src/cmd/compile/internal/types2/testdata/check/const0.src
new file mode 100644
index 0000000..5608b15
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/const0.src
@@ -0,0 +1,363 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// constant declarations
+
+package const0
+
+import "unsafe"
+
+// constants declarations must be initialized by constants
+var x = 0
+const c0 = x /* ERROR "not constant" */
+
+// typed constants must have constant types
+const _ interface /* ERROR invalid constant type */ {} = 0
+
+func _ () {
+	const _ interface /* ERROR invalid constant type */ {} = 0
+	for i := 0; i < 10; i++ {} // don't crash with non-nil iota here
+}
+
+// untyped constants
+const (
+	// boolean values
+	ub0 = false
+	ub1 = true
+	ub2 = 2 < 1
+	ub3 = ui1 == uf1
+	ub4 = true /* ERROR "cannot convert" */ == 0
+
+	// integer values
+	ui0 = 0
+	ui1 = 1
+	ui2 = 42
+	ui3 = 3141592653589793238462643383279502884197169399375105820974944592307816406286
+	ui4 = -10
+
+	ui5 = ui0 + ui1
+	ui6 = ui1 - ui1
+	ui7 = ui2 * ui1
+	ui8 = ui3 / ui3
+	ui9 = ui3 % ui3
+
+	ui10 = 1 / 0 /* ERROR "division by zero" */
+	ui11 = ui1 / 0 /* ERROR "division by zero" */
+	ui12 = ui3 / ui0 /* ERROR "division by zero" */
+	ui13 = 1 % 0 /* ERROR "division by zero" */
+	ui14 = ui1 % 0 /* ERROR "division by zero" */
+	ui15 = ui3 % ui0 /* ERROR "division by zero" */
+
+	ui16 = ui2 & ui3
+	ui17 = ui2 | ui3
+	ui18 = ui2 ^ ui3
+	ui19 = 1 /* ERROR "invalid operation" */ % 1.0
+
+	// floating point values
+	uf0 = 0.
+	uf1 = 1.
+	uf2 = 4.2e1
+	uf3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286
+	uf4 = 1e-1
+
+	uf5 = uf0 + uf1
+	uf6 = uf1 - uf1
+	uf7 = uf2 * uf1
+	uf8 = uf3 / uf3
+	uf9 = uf3 /* ERROR "not defined" */ % uf3
+
+	uf10 = 1 / 0 /* ERROR "division by zero" */
+	uf11 = uf1 / 0 /* ERROR "division by zero" */
+	uf12 = uf3 / uf0 /* ERROR "division by zero" */
+
+	uf16 = uf2 /* ERROR "not defined" */ & uf3
+	uf17 = uf2 /* ERROR "not defined" */ | uf3
+	uf18 = uf2 /* ERROR "not defined" */ ^ uf3
+
+	// complex values
+	uc0 = 0.i
+	uc1 = 1.i
+	uc2 = 4.2e1i
+	uc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i
+	uc4 = 1e-1i
+
+	uc5 = uc0 + uc1
+	uc6 = uc1 - uc1
+	uc7 = uc2 * uc1
+	uc8 = uc3 / uc3
+	uc9 = uc3 /* ERROR "not defined" */ % uc3
+
+	uc10 = 1 / 0 /* ERROR "division by zero" */
+	uc11 = uc1 / 0 /* ERROR "division by zero" */
+	uc12 = uc3 / uc0 /* ERROR "division by zero" */
+
+	uc16 = uc2 /* ERROR "not defined" */ & uc3
+	uc17 = uc2 /* ERROR "not defined" */ | uc3
+	uc18 = uc2 /* ERROR "not defined" */ ^ uc3
+)
+
+type (
+	mybool bool
+	myint int
+	myfloat float64
+	mycomplex complex128
+)
+
+// typed constants
+const (
+	// boolean values
+	tb0 bool = false
+	tb1 bool = true
+	tb2 mybool = 2 < 1
+	tb3 mybool = ti1 /* ERROR "mismatched types" */ == tf1
+
+	// integer values
+	ti0 int8 = ui0
+	ti1 int32 = ui1
+	ti2 int64 = ui2
+	ti3 myint = ui3 /* ERROR "overflows" */
+	ti4 myint = ui4
+
+	ti5 = ti0 /* ERROR "mismatched types" */ + ti1
+	ti6 = ti1 - ti1
+	ti7 = ti2 /* ERROR "mismatched types" */ * ti1
+	ti8 = ti3 / ti3
+	ti9 = ti3 % ti3
+
+	ti10 = 1 / 0 /* ERROR "division by zero" */
+	ti11 = ti1 / 0 /* ERROR "division by zero" */
+	ti12 = ti3 /* ERROR "mismatched types" */ / ti0
+	ti13 = 1 % 0 /* ERROR "division by zero" */
+	ti14 = ti1 % 0 /* ERROR "division by zero" */
+	ti15 = ti3 /* ERROR "mismatched types" */ % ti0
+
+	ti16 = ti2 /* ERROR "mismatched types" */ & ti3
+	ti17 = ti2 /* ERROR "mismatched types" */ | ti4
+	ti18 = ti2 ^ ti5 // no mismatched types error because the type of ti5 is unknown
+
+	// floating point values
+	tf0 float32 = 0.
+	tf1 float32 = 1.
+	tf2 float64 = 4.2e1
+	tf3 myfloat = 3.141592653589793238462643383279502884197169399375105820974944592307816406286
+	tf4 myfloat = 1e-1
+
+	tf5 = tf0 + tf1
+	tf6 = tf1 - tf1
+	tf7 = tf2 /* ERROR "mismatched types" */ * tf1
+	tf8 = tf3 / tf3
+	tf9 = tf3 /* ERROR "not defined" */ % tf3
+
+	tf10 = 1 / 0 /* ERROR "division by zero" */
+	tf11 = tf1 / 0 /* ERROR "division by zero" */
+	tf12 = tf3 /* ERROR "mismatched types" */ / tf0
+
+	tf16 = tf2 /* ERROR "mismatched types" */ & tf3
+	tf17 = tf2 /* ERROR "mismatched types" */ | tf3
+	tf18 = tf2 /* ERROR "mismatched types" */ ^ tf3
+
+	// complex values
+	tc0 = 0.i
+	tc1 = 1.i
+	tc2 = 4.2e1i
+	tc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i
+	tc4 = 1e-1i
+
+	tc5 = tc0 + tc1
+	tc6 = tc1 - tc1
+	tc7 = tc2 * tc1
+	tc8 = tc3 / tc3
+	tc9 = tc3 /* ERROR "not defined" */ % tc3
+
+	tc10 = 1 / 0 /* ERROR "division by zero" */
+	tc11 = tc1 / 0 /* ERROR "division by zero" */
+	tc12 = tc3 / tc0 /* ERROR "division by zero" */
+
+	tc16 = tc2 /* ERROR "not defined" */ & tc3
+	tc17 = tc2 /* ERROR "not defined" */ | tc3
+	tc18 = tc2 /* ERROR "not defined" */ ^ tc3
+)
+
+// initialization cycles
+const (
+	a /* ERROR "initialization cycle" */ = a
+	b /* ERROR "initialization cycle" */ , c /* ERROR "initialization cycle" */, d, e = e, d, c, b // TODO(gri) should only have one cycle error
+	f float64 = d
+)
+
+// multiple initialization
+const (
+	a1, a2, a3 = 7, 3.1415926, "foo"
+	b1, b2, b3 = b3, b1, 42
+	c1, c2, c3  /* ERROR "missing init expr for c3" */ = 1, 2
+	d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */
+	_p0 = assert(a1 == 7)
+	_p1 = assert(a2 == 3.1415926)
+	_p2 = assert(a3 == "foo")
+	_p3 = assert(b1 == 42)
+	_p4 = assert(b2 == 42)
+	_p5 = assert(b3 == 42)
+)
+
+func _() {
+	const (
+		a1, a2, a3 = 7, 3.1415926, "foo"
+		b1, b2, b3 = b3, b1, 42
+		c1, c2, c3  /* ERROR "missing init expr for c3" */ = 1, 2
+		d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */
+		_p0 = assert(a1 == 7)
+		_p1 = assert(a2 == 3.1415926)
+		_p2 = assert(a3 == "foo")
+		_p3 = assert(b1 == 42)
+		_p4 = assert(b2 == 42)
+		_p5 = assert(b3 == 42)
+	)
+}
+
+// iota
+const (
+	iota0 = iota
+	iota1 = iota
+	iota2 = iota*2
+	_a0 = assert(iota0 == 0)
+	_a1 = assert(iota1 == 1)
+	_a2 = assert(iota2 == 4)
+	iota6 = iota*3
+
+	iota7
+	iota8
+	_a3 = assert(iota7 == 21)
+	_a4 = assert(iota8 == 24)
+)
+
+const (
+	_b0 = iota
+	_b1 = assert(iota + iota2 == 5)
+	_b2 = len([iota]int{}) // iota may appear in a type!
+	_b3 = assert(_b2 == 2)
+	_b4 = len(A{})
+)
+
+type A [iota /* ERROR "cannot use iota" */ ]int
+
+// constant expressions with operands across different
+// constant declarations must use the right iota values
+const (
+	_c0 = iota
+	_c1
+	_c2
+	_x = _c2 + _d1 + _e0 // 3
+)
+
+const (
+	_d0 = iota
+	_d1
+)
+
+const (
+	_e0 = iota
+)
+
+var _ = assert(_x == 3)
+
+// special cases
+const (
+	_n0 = nil /* ERROR "not constant" */
+	_n1 = [ /* ERROR "not constant" */ ]int{}
+)
+
+// iotas must not be usable in expressions outside constant declarations
+type _ [iota /* ERROR "iota outside constant decl" */ ]byte
+var _ = iota /* ERROR "iota outside constant decl" */
+func _() {
+	_ = iota /* ERROR "iota outside constant decl" */
+	const _ = iota
+	_ = iota /* ERROR "iota outside constant decl" */
+}
+
+func _() {
+	iota := 123
+	const x = iota /* ERROR "is not constant" */
+	var y = iota
+	_ = y
+}
+
+// iotas are usable inside closures in constant declarations (#22345)
+const (
+	_ = iota
+	_ = len([iota]byte{})
+	_ = unsafe.Sizeof(iota)
+	_ = unsafe.Sizeof(func() { _ = iota })
+	_ = unsafe.Sizeof(func() { var _ = iota })
+	_ = unsafe.Sizeof(func() { const _ = iota })
+	_ = unsafe.Sizeof(func() { type _ [iota]byte })
+	_ = unsafe.Sizeof(func() { func() int { return iota }() })
+)
+
+// verify inner and outer const declarations have distinct iotas
+const (
+	zero = iota
+	one  = iota
+	_    = unsafe.Sizeof(func() {
+		var x [iota]int // [2]int
+		const (
+			Zero = iota
+			One
+			Two
+			_ = unsafe.Sizeof([iota-1]int{} == x) // assert types are equal
+			_ = unsafe.Sizeof([Two]int{} == x)    // assert types are equal
+		)
+		var z [iota]int                           // [2]int
+		_ = unsafe.Sizeof([2]int{} == z)          // assert types are equal
+	})
+	three = iota // the sequence continues
+)
+var _ [three]int = [3]int{} // assert 'three' has correct value
+
+var (
+	_ = iota /* ERROR "iota outside constant decl" */
+	_ = unsafe.Sizeof(iota  /* ERROR "iota outside constant decl" */ )
+	_ = unsafe.Sizeof(func() { _ = iota /* ERROR "iota outside constant decl" */ })
+	_ = unsafe.Sizeof(func() { var _ = iota /* ERROR "iota outside constant decl" */ })
+	_ = unsafe.Sizeof(func() { type _ [iota /* ERROR "iota outside constant decl" */ ]byte })
+	_ = unsafe.Sizeof(func() { func() int { return iota /* ERROR "iota outside constant decl" */ }() })
+)
+
+// constant arithmetic precision and rounding must lead to expected (integer) results
+var _ = []int64{
+	0.0005 * 1e9,
+	0.001 * 1e9,
+	0.005 * 1e9,
+	0.01 * 1e9,
+	0.05 * 1e9,
+	0.1 * 1e9,
+	0.5 * 1e9,
+	1 * 1e9,
+	5 * 1e9,
+}
+
+const _ = unsafe.Sizeof(func() {
+	const _ = 0
+	_ = iota
+
+	const (
+	   zero = iota
+	   one
+	)
+	assert(one == 1)
+	assert(iota == 0)
+})
+
+// untyped constants must not get arbitrarily large
+const prec = 512 // internal maximum precision for integers
+const maxInt = (1<<(prec/2) - 1) * (1<<(prec/2) + 1) // == 1<<prec - 1
+
+const _ = maxInt + /* ERROR constant addition overflow */ 1
+const _ = -maxInt - /* ERROR constant subtraction overflow */ 1
+const _ = maxInt ^ /* ERROR constant bitwise XOR overflow */ -1
+const _ = maxInt * /* ERROR constant multiplication overflow */ 2
+const _ = maxInt << /* ERROR constant shift overflow */ 2
+const _ = 1 << /* ERROR constant shift overflow */ prec
+
+const _ = ^ /* ERROR constant bitwise complement overflow */ maxInt
diff --git a/src/cmd/compile/internal/types2/testdata/check/const1.src b/src/cmd/compile/internal/types2/testdata/check/const1.src
new file mode 100644
index 0000000..c912801
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/const1.src
@@ -0,0 +1,334 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// constant conversions
+
+package const1
+
+import "math"
+
+const(
+	mi = ^int(0)
+	mu = ^uint(0)
+	mp = ^uintptr(0)
+
+	logSizeofInt     = uint(mi>>8&1 + mi>>16&1 + mi>>32&1)
+	logSizeofUint    = uint(mu>>8&1 + mu>>16&1 + mu>>32&1)
+	logSizeofUintptr = uint(mp>>8&1 + mp>>16&1 + mp>>32&1)
+)
+
+const (
+	minInt8 = -1<<(8<<iota - 1)
+	minInt16
+	minInt32
+	minInt64
+	minInt = -1<<(8<<logSizeofInt - 1)
+)
+
+const (
+	maxInt8 = 1<<(8<<iota - 1) - 1
+	maxInt16
+	maxInt32
+	maxInt64
+	maxInt = 1<<(8<<logSizeofInt - 1) - 1
+)
+
+const (
+	maxUint8 = 1<<(8<<iota) - 1
+	maxUint16
+	maxUint32
+	maxUint64
+	maxUint    = 1<<(8<<logSizeofUint) - 1
+	maxUintptr = 1<<(8<<logSizeofUintptr) - 1
+)
+
+const (
+	smallestFloat32 = 1.0 / (1<<(127 - 1 + 23))
+	// TODO(gri) The compiler limits integers to 512 bit and thus
+	//           we cannot compute the value (1<<(1023 - 1 + 52))
+	//           without overflow. For now we match the compiler.
+	//           See also issue #44057.
+	// smallestFloat64 = 1.0 / (1<<(1023 - 1 + 52))
+	smallestFloat64 = math.SmallestNonzeroFloat64
+)
+
+const (
+	_ = assert(smallestFloat32 > 0)
+	_ = assert(smallestFloat64 > 0)
+)
+
+const (
+	maxFloat32 = 1<<127 * (1<<24 - 1) / (1.0<<23)
+	// TODO(gri) The compiler limits integers to 512 bit and thus
+	//           we cannot compute the value 1<<1023
+	//           without overflow. For now we match the compiler.
+	//           See also issue #44057.
+	// maxFloat64 = 1<<1023 * (1<<53 - 1) / (1.0<<52)
+	maxFloat64 = math.MaxFloat64
+)
+
+const (
+	_ int8 = minInt8 /* ERROR "overflows" */ - 1
+	_ int8 = minInt8
+	_ int8 = maxInt8
+	_ int8 = maxInt8 /* ERROR "overflows" */ + 1
+	_ int8 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = int8(minInt8 /* ERROR "cannot convert" */ - 1)
+	_ = int8(minInt8)
+	_ = int8(maxInt8)
+	_ = int8(maxInt8 /* ERROR "cannot convert" */ + 1)
+	_ = int8(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ int16 = minInt16 /* ERROR "overflows" */ - 1
+	_ int16 = minInt16
+	_ int16 = maxInt16
+	_ int16 = maxInt16 /* ERROR "overflows" */ + 1
+	_ int16 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = int16(minInt16 /* ERROR "cannot convert" */ - 1)
+	_ = int16(minInt16)
+	_ = int16(maxInt16)
+	_ = int16(maxInt16 /* ERROR "cannot convert" */ + 1)
+	_ = int16(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ int32 = minInt32 /* ERROR "overflows" */ - 1
+	_ int32 = minInt32
+	_ int32 = maxInt32
+	_ int32 = maxInt32 /* ERROR "overflows" */ + 1
+	_ int32 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = int32(minInt32 /* ERROR "cannot convert" */ - 1)
+	_ = int32(minInt32)
+	_ = int32(maxInt32)
+	_ = int32(maxInt32 /* ERROR "cannot convert" */ + 1)
+	_ = int32(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ int64 = minInt64 /* ERROR "overflows" */ - 1
+	_ int64 = minInt64
+	_ int64 = maxInt64
+	_ int64 = maxInt64 /* ERROR "overflows" */ + 1
+	_ int64 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = int64(minInt64 /* ERROR "cannot convert" */ - 1)
+	_ = int64(minInt64)
+	_ = int64(maxInt64)
+	_ = int64(maxInt64 /* ERROR "cannot convert" */ + 1)
+	_ = int64(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ int = minInt /* ERROR "overflows" */ - 1
+	_ int = minInt
+	_ int = maxInt
+	_ int = maxInt /* ERROR "overflows" */ + 1
+	_ int = smallestFloat64 /* ERROR "truncated" */
+
+	_ = int(minInt /* ERROR "cannot convert" */ - 1)
+	_ = int(minInt)
+	_ = int(maxInt)
+	_ = int(maxInt /* ERROR "cannot convert" */ + 1)
+	_ = int(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ uint8 = 0 /* ERROR "overflows" */ - 1
+	_ uint8 = 0
+	_ uint8 = maxUint8
+	_ uint8 = maxUint8 /* ERROR "overflows" */ + 1
+	_ uint8 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = uint8(0 /* ERROR "cannot convert" */ - 1)
+	_ = uint8(0)
+	_ = uint8(maxUint8)
+	_ = uint8(maxUint8 /* ERROR "cannot convert" */ + 1)
+	_ = uint8(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ uint16 = 0 /* ERROR "overflows" */ - 1
+	_ uint16 = 0
+	_ uint16 = maxUint16
+	_ uint16 = maxUint16 /* ERROR "overflows" */ + 1
+	_ uint16 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = uint16(0 /* ERROR "cannot convert" */ - 1)
+	_ = uint16(0)
+	_ = uint16(maxUint16)
+	_ = uint16(maxUint16 /* ERROR "cannot convert" */ + 1)
+	_ = uint16(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ uint32 = 0 /* ERROR "overflows" */ - 1
+	_ uint32 = 0
+	_ uint32 = maxUint32
+	_ uint32 = maxUint32 /* ERROR "overflows" */ + 1
+	_ uint32 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = uint32(0 /* ERROR "cannot convert" */ - 1)
+	_ = uint32(0)
+	_ = uint32(maxUint32)
+	_ = uint32(maxUint32 /* ERROR "cannot convert" */ + 1)
+	_ = uint32(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ uint64 = 0 /* ERROR "overflows" */ - 1
+	_ uint64 = 0
+	_ uint64 = maxUint64
+	_ uint64 = maxUint64 /* ERROR "overflows" */ + 1
+	_ uint64 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = uint64(0 /* ERROR "cannot convert" */ - 1)
+	_ = uint64(0)
+	_ = uint64(maxUint64)
+	_ = uint64(maxUint64 /* ERROR "cannot convert" */ + 1)
+	_ = uint64(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ uint = 0 /* ERROR "overflows" */ - 1
+	_ uint = 0
+	_ uint = maxUint
+	_ uint = maxUint /* ERROR "overflows" */ + 1
+	_ uint = smallestFloat64 /* ERROR "truncated" */
+
+	_ = uint(0 /* ERROR "cannot convert" */ - 1)
+	_ = uint(0)
+	_ = uint(maxUint)
+	_ = uint(maxUint /* ERROR "cannot convert" */ + 1)
+	_ = uint(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ uintptr = 0 /* ERROR "overflows" */ - 1
+	_ uintptr = 0
+	_ uintptr = maxUintptr
+	_ uintptr = maxUintptr /* ERROR "overflows" */ + 1
+	_ uintptr = smallestFloat64 /* ERROR "truncated" */
+
+	_ = uintptr(0 /* ERROR "cannot convert" */ - 1)
+	_ = uintptr(0)
+	_ = uintptr(maxUintptr)
+	_ = uintptr(maxUintptr /* ERROR "cannot convert" */ + 1)
+	_ = uintptr(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ float32 = minInt64
+	_ float64 = minInt64
+	_ complex64 = minInt64
+	_ complex128 = minInt64
+
+	_ = float32(minInt64)
+	_ = float64(minInt64)
+	_ = complex64(minInt64)
+	_ = complex128(minInt64)
+)
+
+const (
+	_ float32 = maxUint64
+	_ float64 = maxUint64
+	_ complex64 = maxUint64
+	_ complex128 = maxUint64
+
+	_ = float32(maxUint64)
+	_ = float64(maxUint64)
+	_ = complex64(maxUint64)
+	_ = complex128(maxUint64)
+)
+
+// TODO(gri) find smaller deltas below
+
+const delta32 = maxFloat32/(1 << 23)
+
+const (
+	_ float32 = - /* ERROR "overflow" */ (maxFloat32 + delta32)
+	_ float32 = -maxFloat32
+	_ float32 = maxFloat32
+	_ float32 = maxFloat32 /* ERROR "overflow" */ + delta32
+
+	_ = float32(- /* ERROR "cannot convert" */ (maxFloat32 + delta32))
+	_ = float32(-maxFloat32)
+	_ = float32(maxFloat32)
+	_ = float32(maxFloat32 /* ERROR "cannot convert" */ + delta32)
+
+	_ = assert(float32(smallestFloat32) == smallestFloat32)
+	_ = assert(float32(smallestFloat32/2) == 0)
+	_ = assert(float32(smallestFloat64) == 0)
+	_ = assert(float32(smallestFloat64/2) == 0)
+)
+
+const delta64 = maxFloat64/(1 << 52)
+
+const (
+	_ float64 = - /* ERROR "overflow" */ (maxFloat64 + delta64)
+	_ float64 = -maxFloat64
+	_ float64 = maxFloat64
+	_ float64 = maxFloat64 /* ERROR "overflow" */ + delta64
+
+	_ = float64(- /* ERROR "cannot convert" */ (maxFloat64 + delta64))
+	_ = float64(-maxFloat64)
+	_ = float64(maxFloat64)
+	_ = float64(maxFloat64 /* ERROR "cannot convert" */ + delta64)
+
+	_ = assert(float64(smallestFloat32) == smallestFloat32)
+	_ = assert(float64(smallestFloat32/2) == smallestFloat32/2)
+	_ = assert(float64(smallestFloat64) == smallestFloat64)
+	_ = assert(float64(smallestFloat64/2) == 0)
+)
+
+const (
+	_ complex64 = - /* ERROR "overflow" */ (maxFloat32 + delta32)
+	_ complex64 = -maxFloat32
+	_ complex64 = maxFloat32
+	_ complex64 = maxFloat32 /* ERROR "overflow" */ + delta32
+
+	_ = complex64(- /* ERROR "cannot convert" */ (maxFloat32 + delta32))
+	_ = complex64(-maxFloat32)
+	_ = complex64(maxFloat32)
+	_ = complex64(maxFloat32 /* ERROR "cannot convert" */ + delta32)
+)
+
+const (
+	_ complex128 = - /* ERROR "overflow" */ (maxFloat64 + delta64)
+	_ complex128 = -maxFloat64
+	_ complex128 = maxFloat64
+	_ complex128 = maxFloat64 /* ERROR "overflow" */ + delta64
+
+	_ = complex128(- /* ERROR "cannot convert" */ (maxFloat64 + delta64))
+	_ = complex128(-maxFloat64)
+	_ = complex128(maxFloat64)
+	_ = complex128(maxFloat64 /* ERROR "cannot convert" */ + delta64)
+)
+
+// Initialization of typed constant and conversion are the same:
+const (
+	f32 = 1 + smallestFloat32
+	x32 float32 = f32
+	y32 = float32(f32)
+	_ = assert(x32 - y32 == 0)
+)
+
+const (
+	f64 = 1 + smallestFloat64
+	x64 float64 = f64
+	y64 = float64(f64)
+	_ = assert(x64 - y64 == 0)
+)
+
+const (
+	_ = int8(-1) << 7
+	_ = int8 /* ERROR "overflows" */ (-1) << 8
+
+	_ = uint32(1) << 31
+	_ = uint32 /* ERROR "overflows" */ (1) << 32
+)
diff --git a/src/cmd/compile/internal/types2/testdata/check/constdecl.src b/src/cmd/compile/internal/types2/testdata/check/constdecl.src
new file mode 100644
index 0000000..cb155ab
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/constdecl.src
@@ -0,0 +1,138 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package constdecl
+
+import "math"
+import "unsafe"
+
+var v int
+
+// Const decls must be initialized by constants.
+const _ = v /* ERROR "not constant" */
+const _ = math /* ERROR "not constant" */ .Sin(0)
+const _ = int /* ERROR "not an expression" */
+
+func _() {
+	const _ = v /* ERROR "not constant" */
+	const _ = math /* ERROR "not constant" */ .Sin(0)
+	const _ = int /* ERROR "not an expression" */
+}
+
+// Identifier and expression arity must match.
+const _ /* ERROR "missing init expr for _" */
+const _ = 1, 2 /* ERROR "extra init expr 2" */
+
+const _ /* ERROR "missing init expr for _" */ int
+const _ int = 1, 2 /* ERROR "extra init expr 2" */
+
+const (
+	_ /* ERROR "missing init expr for _" */
+	_ = 1, 2 /* ERROR "extra init expr 2" */
+
+	_ /* ERROR "missing init expr for _" */ int
+	_ int = 1, 2 /* ERROR "extra init expr 2" */
+)
+
+const (
+	_ = 1
+	_
+	_, _ /* ERROR "missing init expr for _" */
+	_
+)
+
+const (
+	_, _ = 1, 2
+	_, _
+	_ /* ERROR "extra init expr at" */
+	_, _
+	_, _, _ /* ERROR "missing init expr for _" */
+	_, _
+)
+
+func _() {
+	const _ /* ERROR "missing init expr for _" */
+	const _ = 1, 2 /* ERROR "extra init expr 2" */
+
+	const _ /* ERROR "missing init expr for _" */ int
+	const _ int = 1, 2 /* ERROR "extra init expr 2" */
+
+	const (
+		_ /* ERROR "missing init expr for _" */
+		_ = 1, 2 /* ERROR "extra init expr 2" */
+
+		_ /* ERROR "missing init expr for _" */ int
+		_ int = 1, 2 /* ERROR "extra init expr 2" */
+	)
+
+	const (
+		_ = 1
+		_
+		_, _ /* ERROR "missing init expr for _" */
+		_
+	)
+
+	const (
+		_, _ = 1, 2
+		_, _
+		_ /* ERROR "extra init expr at" */
+		_, _
+		_, _, _ /* ERROR "missing init expr for _" */
+		_, _
+	)
+}
+
+// Test case for constant with invalid initialization.
+// Caused panic because the constant value was not set up (gri - 7/8/2014).
+func _() {
+	const (
+	    x string = missing /* ERROR "undeclared name" */
+	    y = x + ""
+	)
+}
+
+// Test case for constants depending on function literals (see also #22992).
+const A /* ERROR initialization cycle */ = unsafe.Sizeof(func() { _ = A })
+
+func _() {
+	// The function literal below must not see a.
+	const a = unsafe.Sizeof(func() { _ = a /* ERROR "undeclared name" */ })
+	const b = unsafe.Sizeof(func() { _ = a })
+
+	// The function literal below must not see x, y, or z.
+	const x, y, z = 0, 1, unsafe.Sizeof(func() { _ = x /* ERROR "undeclared name" */ + y /* ERROR "undeclared name" */ + z /* ERROR "undeclared name" */ })
+}
+
+// Test cases for errors in inherited constant initialization expressions.
+// Errors related to inherited initialization expressions must appear at
+// the constant identifier being declared, not at the original expression
+// (issues #42991, #42992).
+const (
+	_ byte = 255 + iota
+	/* some gap */
+	_ // ERROR overflows
+	/* some gap */
+	/* some gap */ _ /* ERROR overflows */; _ /* ERROR overflows */
+	/* some gap */
+	_ = 255 + iota
+	_ = byte /* ERROR overflows */ (255) + iota
+	_ /* ERROR overflows */
+)
+
+// Test cases from issue.
+const (
+	ok = byte(iota + 253)
+	bad
+	barn
+	bard // ERROR cannot convert
+)
+
+const (
+	c = len([1 - iota]int{})
+	d
+	e // ERROR invalid array length
+	f // ERROR invalid array length
+)
+
+// TODO(gri) move extra tests from testdata/const0.src into here
diff --git a/src/go/types/testdata/conversions.src b/src/cmd/compile/internal/types2/testdata/check/conversions.src
similarity index 100%
copy from src/go/types/testdata/conversions.src
copy to src/cmd/compile/internal/types2/testdata/check/conversions.src
diff --git a/src/go/types/testdata/conversions2.src b/src/cmd/compile/internal/types2/testdata/check/conversions2.src
similarity index 100%
copy from src/go/types/testdata/conversions2.src
copy to src/cmd/compile/internal/types2/testdata/check/conversions2.src
diff --git a/src/cmd/compile/internal/types2/testdata/check/cycles.src b/src/cmd/compile/internal/types2/testdata/check/cycles.src
new file mode 100644
index 0000000..b2ee8ec
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/cycles.src
@@ -0,0 +1,174 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cycles
+
+import "unsafe"
+
+type (
+	T0 int
+	T1 /* ERROR cycle */ T1
+	T2 *T2
+
+	T3 /* ERROR cycle */ T4
+	T4 T5
+	T5 T3
+
+	T6 T7
+	T7 *T8
+	T8 T6
+
+	// arrays
+	A0 /* ERROR cycle */ [10]A0
+	A1 [10]*A1
+
+	A2 /* ERROR cycle */ [10]A3
+	A3 [10]A4
+	A4 A2
+
+	A5 [10]A6
+	A6 *A5
+
+	// slices
+	L0 []L0
+
+	// structs
+	S0 /* ERROR cycle */ struct{ _ S0 }
+	S1 /* ERROR cycle */ struct{ S1 }
+	S2 struct{ _ *S2 }
+	S3 struct{ *S3 }
+
+	S4 /* ERROR cycle */ struct{ S5 }
+	S5 struct{ S6 }
+	S6 S4
+
+	// pointers
+	P0 *P0
+
+	// functions
+	F0 func(F0)
+	F1 func() F1
+	F2 func(F2) F2
+
+	// interfaces
+	I0 /* ERROR cycle */ interface{ I0 }
+
+	I1 /* ERROR cycle */ interface{ I2 }
+	I2 interface{ I3 }
+	I3 interface{ I1 }
+
+	I4 interface{ f(I4) }
+
+	// testcase for issue 5090
+	I5 interface{ f(I6) }
+	I6 interface{ I5 }
+
+	// maps
+	M0 map[M0 /* ERROR invalid map key */ ]M0
+
+	// channels
+	C0 chan C0
+)
+
+// test case for issue #34771
+type (
+	AA /* ERROR cycle */ B
+	B C
+	C [10]D
+	D E
+	E AA
+)
+
+func _() {
+	type (
+		t1 /* ERROR cycle */ t1
+		t2 *t2
+
+		t3 t4 /* ERROR undeclared */
+		t4 t5 /* ERROR undeclared */
+		t5 t3
+
+		// arrays
+		a0 /* ERROR cycle */ [10]a0
+		a1 [10]*a1
+
+		// slices
+		l0 []l0
+
+		// structs
+		s0 /* ERROR cycle */ struct{ _ s0 }
+		s1 /* ERROR cycle */ struct{ s1 }
+		s2 struct{ _ *s2 }
+		s3 struct{ *s3 }
+
+		// pointers
+		p0 *p0
+
+		// functions
+		f0 func(f0)
+		f1 func() f1
+		f2 func(f2) f2
+
+		// interfaces
+		i0 /* ERROR cycle */ interface{ i0 }
+
+		// maps
+		m0 map[m0 /* ERROR invalid map key */ ]m0
+
+		// channels
+		c0 chan c0
+	)
+}
+
+// test cases for issue 6667
+
+type A [10]map[A /* ERROR invalid map key */ ]bool
+
+type S struct {
+	m map[S /* ERROR invalid map key */ ]bool
+}
+
+// test cases for issue 7236
+// (cycle detection must not be dependent on starting point of resolution)
+
+type (
+	P1 *T9
+	T9 /* ERROR cycle */ T9
+
+	T10 /* ERROR cycle */ T10
+	P2 *T10
+)
+
+func (T11) m() {}
+
+type T11 /* ERROR cycle */ struct{ T11 }
+
+type T12 /* ERROR cycle */ struct{ T12 }
+
+func (*T12) m() {}
+
+type (
+	P3 *T13
+	T13 /* ERROR cycle */ T13
+)
+
+// test cases for issue 18643
+// (type cycle detection when non-type expressions are involved)
+type (
+	T14 [len(T14 /* ERROR cycle */ {})]int
+	T15 [][len(T15 /* ERROR cycle */ {})]int
+	T16 map[[len(T16 /* ERROR cycle */ {1:2})]int]int
+	T17 map[int][len(T17 /* ERROR cycle */ {1:2})]int
+)
+
+// Test case for types depending on function literals (see also #22992).
+type T20 chan [unsafe.Sizeof(func(ch T20){ _ = <-ch })]byte
+type T22 = chan [unsafe.Sizeof(func(ch T20){ _ = <-ch })]byte
+
+func _() {
+	type T0 func(T0)
+	type T1 /* ERROR cycle */ = func(T1)
+	type T2 chan [unsafe.Sizeof(func(ch T2){ _ = <-ch })]byte
+	type T3 /* ERROR cycle */ = chan [unsafe.Sizeof(func(ch T3){ _ = <-ch })]byte
+}
diff --git a/src/go/types/testdata/cycles1.src b/src/cmd/compile/internal/types2/testdata/check/cycles1.src
similarity index 100%
copy from src/go/types/testdata/cycles1.src
copy to src/cmd/compile/internal/types2/testdata/check/cycles1.src
diff --git a/src/go/types/testdata/cycles2.src b/src/cmd/compile/internal/types2/testdata/check/cycles2.src
similarity index 100%
copy from src/go/types/testdata/cycles2.src
copy to src/cmd/compile/internal/types2/testdata/check/cycles2.src
diff --git a/src/go/types/testdata/cycles3.src b/src/cmd/compile/internal/types2/testdata/check/cycles3.src
similarity index 100%
copy from src/go/types/testdata/cycles3.src
copy to src/cmd/compile/internal/types2/testdata/check/cycles3.src
diff --git a/src/go/types/testdata/cycles4.src b/src/cmd/compile/internal/types2/testdata/check/cycles4.src
similarity index 100%
copy from src/go/types/testdata/cycles4.src
copy to src/cmd/compile/internal/types2/testdata/check/cycles4.src
diff --git a/src/go/types/testdata/cycles5.src b/src/cmd/compile/internal/types2/testdata/check/cycles5.src
similarity index 100%
copy from src/go/types/testdata/cycles5.src
copy to src/cmd/compile/internal/types2/testdata/check/cycles5.src
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls0.src b/src/cmd/compile/internal/types2/testdata/check/decls0.src
new file mode 100644
index 0000000..e78d886
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/decls0.src
@@ -0,0 +1,206 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// type declarations
+
+package decls0
+
+import "unsafe"
+
+const pi = 3.1415
+
+type (
+	N undeclared /* ERROR "undeclared" */
+	B bool
+	I int32
+	A [10]P
+	T struct {
+		x, y P
+	}
+	P *T
+	R (*R)
+	F func(A) I
+	Y interface {
+		f(A) I
+	}
+	S [](((P)))
+	M map[I]F
+	C chan<- I
+
+	// blank types must be typechecked
+	_ pi /* ERROR "not a type" */
+	_ struct{}
+	_ struct{ pi /* ERROR "not a type" */ }
+)
+
+
+// declarations of init
+const _, init /* ERROR "cannot declare init" */ , _ = 0, 1, 2
+type init /* ERROR "cannot declare init" */ struct{}
+var _, init /* ERROR "cannot declare init" */ int
+
+func init() {}
+func init /* ERROR "missing function body" */ ()
+
+func _() { const init = 0 }
+func _() { type init int }
+func _() { var init int; _ = init }
+
+// invalid array types
+type (
+	iA0 [... /* ERROR "invalid use of \[...\] array" */ ]byte
+	// The error message below could be better. At the moment
+	// we believe an integer that is too large is not an integer.
+	// But at least we get an error.
+	iA1 [1 /* ERROR "must be integer" */ <<100]int
+	iA2 [- /* ERROR "invalid array length" */ 1]complex128
+	iA3 ["foo" /* ERROR "must be integer" */ ]string
+	iA4 [float64 /* ERROR "must be integer" */ (0)]int
+)
+
+
+type (
+	p1 pi.foo /* ERROR "no field or method foo" */
+	p2 unsafe.Pointer
+)
+
+
+type (
+	Pi pi /* ERROR "not a type" */
+
+	a /* ERROR "illegal cycle" */ a
+	a /* ERROR "redeclared" */ int
+
+	b /* ERROR "illegal cycle" */ c
+	c d
+	d e
+	e b
+
+	t *t
+
+	U V
+	V *W
+	W U
+
+	P1 *S2
+	P2 P1
+
+	S0 struct {
+	}
+	S1 struct {
+		a, b, c int
+		u, v, a /* ERROR "redeclared" */ float32
+	}
+	S2 struct {
+		S0 // embedded field
+		S0 /* ERROR "redeclared" */ int
+	}
+	S3 struct {
+		x S2
+	}
+	S4/* ERROR "illegal cycle" */ struct {
+		S4
+	}
+	S5 /* ERROR "illegal cycle" */ struct {
+		S6
+	}
+	S6 struct {
+		field S7
+	}
+	S7 struct {
+		S5
+	}
+
+	L1 []L1
+	L2 []int
+
+	A1 [10.0]int
+	A2 /* ERROR "illegal cycle" */ [10]A2
+	A3 /* ERROR "illegal cycle" */ [10]struct {
+		x A4
+	}
+	A4 [10]A3
+
+	F1 func()
+	F2 func(x, y, z float32)
+	F3 func(x, y, x /* ERROR "redeclared" */ float32)
+	F4 func() (x, y, x /* ERROR "redeclared" */ float32)
+	F5 func(x int) (x /* ERROR "redeclared" */ float32)
+	F6 func(x ...int)
+
+	I1 interface{}
+	I2 interface {
+		m1()
+	}
+	I3 interface {
+		m1()
+		m1 /* ERROR "duplicate method" */ ()
+	}
+	I4 interface {
+		m1(x, y, x /* ERROR "redeclared" */ float32)
+		m2() (x, y, x /* ERROR "redeclared" */ float32)
+		m3(x int) (x /* ERROR "redeclared" */ float32)
+	}
+	I5 interface {
+		m1(I5)
+	}
+	I6 interface {
+		S0 /* ERROR "not an interface" */
+	}
+	I7 interface {
+		I1
+		I1
+	}
+	I8 /* ERROR "illegal cycle" */ interface {
+		I8
+	}
+	I9 /* ERROR "illegal cycle" */ interface {
+		I10
+	}
+	I10 interface {
+		I11
+	}
+	I11 interface {
+		I9
+	}
+
+	C1 chan int
+	C2 <-chan int
+	C3 chan<- C3
+	C4 chan C5
+	C5 chan C6
+	C6 chan C4
+
+	M1 map[Last]string
+	M2 map[string]M2
+
+	Last int
+)
+
+// cycles in function/method declarations
+// (test cases for issues #5217, #25790 and variants)
+func f1(x f1 /* ERROR "not a type" */ ) {}
+func f2(x *f2 /* ERROR "not a type" */ ) {}
+func f3() (x f3 /* ERROR "not a type" */ ) { return }
+func f4() (x *f4 /* ERROR "not a type" */ ) { return }
+
+func (S0) m1(x S0 /* ERROR value .* is not a type */ .m1) {}
+func (S0) m2(x *S0 /* ERROR value .* is not a type */ .m2) {}
+func (S0) m3() (x S0 /* ERROR value .* is not a type */ .m3) { return }
+func (S0) m4() (x *S0 /* ERROR value .* is not a type */ .m4) { return }
+
+// interfaces may not have any blank methods
+type BlankI interface {
+	_ /* ERROR "invalid method name" */ ()
+	_ /* ERROR "invalid method name" */ (float32) int
+	m()
+}
+
+// non-interface types may have multiple blank methods
+type BlankT struct{}
+
+func (BlankT) _() {}
+func (BlankT) _(int) {}
+func (BlankT) _() int { return 0 }
+func (BlankT) _(int) int { return 0}
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls1.src b/src/cmd/compile/internal/types2/testdata/check/decls1.src
new file mode 100644
index 0000000..e6beb78
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/decls1.src
@@ -0,0 +1,144 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// variable declarations
+
+package decls1
+
+import (
+	"math"
+)
+
+// Global variables without initialization
+var (
+	a, b bool
+	c byte
+	d uint8
+	r rune
+	i int
+	j, k, l int
+	x, y float32
+	xx, yy float64
+	u, v complex64
+	uu, vv complex128
+	s, t string
+	array []byte
+	iface interface{}
+
+	blank _ /* ERROR "cannot use _" */
+)
+
+// Global variables with initialization
+var (
+	s1 = i + j
+	s2 = i /* ERROR "mismatched types" */ + x
+	s3 = c + d
+	s4 = s + t
+	s5 = s /* ERROR "invalid operation" */ / t
+	s6 = array[t1]
+	s7 = array[x /* ERROR "integer" */]
+	s8 = &a
+	s10 = &42 /* ERROR "cannot take address" */
+	s11 = &v
+	s12 = -(u + *t11) / *&v
+	s13 = a /* ERROR "shifted operand" */ << d
+	s14 = i << j
+	s18 = math.Pi * 10.0
+	s19 = s1 /* ERROR "cannot call" */ ()
+ 	s20 = f0 /* ERROR "no value" */ ()
+	s21 = f6(1, s1, i)
+	s22 = f6(1, s1, uu /* ERROR "cannot use .* in argument" */ )
+
+	t1 int = i + j
+	t2 int = i /* ERROR "mismatched types" */ + x
+	t3 int = c /* ERROR "cannot use .* variable declaration" */ + d
+	t4 string = s + t
+	t5 string = s /* ERROR "invalid operation" */ / t
+	t6 byte = array[t1]
+	t7 byte = array[x /* ERROR "must be integer" */]
+	t8 *int = & /* ERROR "cannot use .* variable declaration" */ a
+	t10 *int = &42 /* ERROR "cannot take address" */
+	t11 *complex64 = &v
+	t12 complex64 = -(u + *t11) / *&v
+	t13 int = a /* ERROR "shifted operand" */ << d
+	t14 int = i << j
+	t15 math /* ERROR "not in selector" */
+	t16 math.xxx /* ERROR "not declared" */
+	t17 math /* ERROR "not a type" */ .Pi
+	t18 float64 = math.Pi * 10.0
+	t19 int = t1 /* ERROR "cannot call" */ ()
+	t20 int = f0 /* ERROR "no value" */ ()
+	t21 int = a /* ERROR "cannot use .* variable declaration" */
+)
+
+// Various more complex expressions
+var (
+	u1 = x /* ERROR "not an interface" */ .(int)
+	u2 = iface.([]int)
+	u3 = iface.(a /* ERROR "not a type" */ )
+	u4, ok = iface.(int)
+	u5, ok2, ok3 = iface /* ERROR "cannot initialize" */ .(int)
+)
+
+// Constant expression initializations
+var (
+	v1 = 1 /* ERROR "cannot convert" */ + "foo"
+	v2 = c + 255
+	v3 = c + 256 /* ERROR "overflows" */
+	v4 = r + 2147483647
+	v5 = r + 2147483648 /* ERROR "overflows" */
+	v6 = 42
+	v7 = v6 + 9223372036854775807
+	v8 = v6 + 9223372036854775808 /* ERROR "overflows" */
+	v9 = i + 1 << 10
+	v10 byte = 1024 /* ERROR "overflows" */
+	v11 = xx/yy*yy - xx
+	v12 = true && false
+	v13 = nil /* ERROR "use of untyped nil" */
+)
+
+// Multiple assignment expressions
+var (
+	m1a, m1b = 1, 2
+	m2a, m2b, m2c /* ERROR "missing init expr for m2c" */ = 1, 2
+	m3a, m3b = 1, 2, 3 /* ERROR "extra init expr 3" */
+)
+
+func _() {
+	var (
+		m1a, m1b = 1, 2
+		m2a, m2b, m2c /* ERROR "missing init expr for m2c" */ = 1, 2
+		m3a, m3b = 1, 2, 3 /* ERROR "extra init expr 3" */
+	)
+
+	_, _ = m1a, m1b
+	_, _, _ = m2a, m2b, m2c
+	_, _ = m3a, m3b
+}
+
+// Declaration of parameters and results
+func f0() {}
+func f1(a /* ERROR "not a type" */) {}
+func f2(a, b, c d /* ERROR "not a type" */) {}
+
+func f3() int { return 0 }
+func f4() a /* ERROR "not a type" */ { return 0 }
+func f5() (a, b, c d /* ERROR "not a type" */) { return }
+
+func f6(a, b, c int) complex128 { return 0 }
+
+// Declaration of receivers
+type T struct{}
+
+func (T) m0() {}
+func (*T) m1() {}
+func (x T) m2() {}
+func (x *T) m3() {}
+
+// Initialization functions
+func init() {}
+func /* ERROR "no arguments and no return values" */ init(int) {}
+func /* ERROR "no arguments and no return values" */ init() int { return 0 }
+func /* ERROR "no arguments and no return values" */ init(int) int { return 0 }
+func (T) init(int) int { return 0 }
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls2/decls2a.src b/src/cmd/compile/internal/types2/testdata/check/decls2/decls2a.src
new file mode 100644
index 0000000..d077db5
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/decls2/decls2a.src
@@ -0,0 +1,111 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// method declarations
+
+package decls2
+
+import "time"
+import "unsafe"
+
+// T1 declared before its methods.
+type T1 struct{
+	f int
+}
+
+func (T1) m() {}
+func (T1) m /* ERROR "already declared" */ () {}
+func (x *T1) f /* ERROR "field and method" */ () {}
+
+// Conflict between embedded field and method name,
+// with the embedded field being a basic type.
+type T1b struct {
+	int
+}
+
+func (T1b) int /* ERROR "field and method" */ () {}
+
+type T1c struct {
+	time.Time
+}
+
+func (T1c) Time /* ERROR "field and method" */ () int { return 0 }
+
+// Disabled for now: LookupFieldOrMethod will find Pointer even though
+// it's double-declared (it would cost extra in the common case to verify
+// this). But the MethodSet computation will not find it due to the name
+// collision caused by the double-declaration, leading to an internal
+// inconsistency while we are verifying one computation against the other.
+// var _ = T1c{}.Pointer
+
+// T2's method declared before the type.
+func (*T2) f /* ERROR "field and method" */ () {}
+
+type T2 struct {
+	f int
+}
+
+// Methods declared without a declared type.
+func (undeclared /* ERROR "undeclared" */) m() {}
+func (x *undeclared /* ERROR "undeclared" */) m() {}
+
+func (pi /* ERROR "not a type" */) m1() {}
+func (x pi /* ERROR "not a type" */) m2() {}
+func (x *pi /* ERROR "not a type" */ ) m3() {}
+
+// Blank types.
+type _ struct { m int }
+type _ struct { m int }
+
+func (_ /* ERROR "cannot use _" */) m() {}
+func m(_ /* ERROR "cannot use _" */) {}
+
+// Methods with receiver base type declared in another file.
+func (T3) m1() {}
+func (*T3) m2() {}
+func (x T3) m3() {}
+func (x *T3) f /* ERROR "field and method" */ () {}
+
+// Methods of non-struct type.
+type T4 func()
+
+func (self T4) m() func() { return self }
+
+// Methods associated with an interface.
+type T5 interface {
+	m() int
+}
+
+func (T5 /* ERROR "invalid receiver" */ ) m1() {}
+func (T5 /* ERROR "invalid receiver" */ ) m2() {}
+
+// Methods associated with a named pointer type.
+type ptr *int
+func (ptr /* ERROR "invalid receiver" */ ) _() {}
+func (* /* ERROR "invalid receiver" */ ptr) _() {}
+
+// Methods with zero or multiple receivers.
+func ( /* ERROR "no receiver" */ ) _() {}
+func (T3, * /* ERROR "multiple receivers" */ T3) _() {}
+func (T3, T3, T3 /* ERROR "multiple receivers" */ ) _() {}
+func (a, b /* ERROR "multiple receivers" */ T3) _() {}
+func (a, b, c /* ERROR "multiple receivers" */ T3) _() {}
+
+// Methods associated with non-local or unnamed types.
+func (int /* ERROR "invalid receiver" */ ) m() {}
+func ([ /* ERROR "invalid receiver" */ ]int) m() {}
+func (time /* ERROR "invalid receiver" */ .Time) m() {}
+func (* /* ERROR "invalid receiver" */ time.Time) m() {}
+func (x /* ERROR "invalid receiver" */ interface{}) m() {}
+
+// Unsafe.Pointer is treated like a pointer when used as receiver type.
+type UP unsafe.Pointer
+func (UP /* ERROR "invalid" */ ) m1() {}
+func (* /* ERROR "invalid" */ UP) m2() {}
+
+// Double declarations across package files
+const c_double = 0
+type t_double int
+var v_double int
+func f_double() {}
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls2/decls2b.src b/src/cmd/compile/internal/types2/testdata/check/decls2/decls2b.src
new file mode 100644
index 0000000..7b3229c
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/decls2/decls2b.src
@@ -0,0 +1,75 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// method declarations
+
+package decls2
+
+import "io"
+
+const pi = 3.1415
+
+func (T1) m /* ERROR "already declared" */ () {}
+func (T2) m(io.Writer) {}
+
+type T3 struct {
+	f *T3
+}
+
+type T6 struct {
+	x int
+}
+
+func (t *T6) m1() int {
+	return t.x
+}
+
+func f() {
+	var t *T6
+	t.m1()
+}
+
+// Double declarations across package files
+const c_double /* ERROR "redeclared" */ = 0
+type t_double  /* ERROR "redeclared" */ int
+var v_double /* ERROR "redeclared" */ int
+func f_double /* ERROR "redeclared" */ () {}
+
+// Blank methods need to be type-checked.
+// Verify by checking that errors are reported.
+func (T /* ERROR "undeclared" */ ) _() {}
+func (T1) _(undeclared /* ERROR "undeclared" */ ) {}
+func (T1) _() int { return "foo" /* ERROR "cannot use .* in return statement" */ }
+
+// Methods with undeclared receiver type can still be checked.
+// Verify by checking that errors are reported.
+func (Foo /* ERROR "undeclared" */ ) m() {}
+func (Foo /* ERROR "undeclared" */ ) m(undeclared /* ERROR "undeclared" */ ) {}
+func (Foo /* ERROR "undeclared" */ ) m() int { return "foo" /* ERROR "cannot use .* in return statement" */ }
+
+func (Foo /* ERROR "undeclared" */ ) _() {}
+func (Foo /* ERROR "undeclared" */ ) _(undeclared /* ERROR "undeclared" */ ) {}
+func (Foo /* ERROR "undeclared" */ ) _() int { return "foo" /* ERROR "cannot use .* in return statement" */ }
+
+// Receiver declarations are regular parameter lists;
+// receiver types may use parentheses, and the list
+// may have a trailing comma.
+type T7 struct {}
+
+func (T7) m1() {}
+func ((T7)) m2() {}
+func ((*T7)) m3() {}
+func (x *(T7),) m4() {}
+func (x (*(T7)),) m5() {}
+func (x ((*((T7)))),) m6() {}
+
+// Check that methods with parenthesized receiver are actually present (issue #23130).
+var (
+	_ = T7.m1
+	_ = T7.m2
+	_ = (*T7).m3
+	_ = (*T7).m4
+	_ = (*T7).m5
+	_ = (*T7).m6
+)
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls3.src b/src/cmd/compile/internal/types2/testdata/check/decls3.src
new file mode 100644
index 0000000..d7a0c44
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/decls3.src
@@ -0,0 +1,309 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// embedded types
+
+package decls3
+
+import "unsafe"
+import "fmt"
+
+// fields with the same name at the same level cancel each other out
+
+func _() {
+	type (
+		T1 struct { X int }
+		T2 struct { X int }
+		T3 struct { T1; T2 } // X is embedded twice at the same level via T1->X, T2->X
+	)
+
+	var t T3
+	_ = t.X /* ERROR "ambiguous selector t.X" */
+}
+
+func _() {
+	type (
+		T1 struct { X int }
+		T2 struct { T1 }
+		T3 struct { T1 }
+		T4 struct { T2; T3 } // X is embedded twice at the same level via T2->T1->X, T3->T1->X
+	)
+
+	var t T4
+	_ = t.X /* ERROR "ambiguous selector t.X" */
+}
+
+func issue4355() {
+	type (
+	    T1 struct {X int}
+	    T2 struct {T1}
+	    T3 struct {T2}
+	    T4 struct {T2}
+	    T5 struct {T3; T4} // X is embedded twice at the same level via T3->T2->T1->X, T4->T2->T1->X
+	)
+
+	var t T5
+	_ = t.X /* ERROR "ambiguous selector t.X" */
+}
+
+func _() {
+	type State int
+	type A struct{ State }
+	type B struct{ fmt.State }
+	type T struct{ A; B }
+
+	var t T
+	_ = t.State /* ERROR "ambiguous selector t.State" */
+}
+
+// Embedded fields can be predeclared types.
+
+func _() {
+	type T0 struct{
+		int
+		float32
+		f int
+	}
+	var x T0
+	_ = x.int
+	_ = x.float32
+	_ = x.f
+
+	type T1 struct{
+		T0
+	}
+	var y T1
+	_ = y.int
+	_ = y.float32
+	_ = y.f
+}
+
+// Restrictions on embedded field types.
+
+func _() {
+	type I1 interface{}
+	type I2 interface{}
+	type P1 *int
+	type P2 *int
+	type UP unsafe.Pointer
+
+	type T1 struct {
+		I1
+		* /* ERROR "cannot be a pointer to an interface" */ I2
+		* /* ERROR "cannot be a pointer to an interface" */ error
+		P1 /* ERROR "cannot be a pointer" */
+		* /* ERROR "cannot be a pointer" */ P2
+	}
+
+	// unsafe.Pointers are treated like regular pointers when embedded
+	type T2 struct {
+		unsafe /* ERROR "cannot be unsafe.Pointer" */ .Pointer
+		*/* ERROR "cannot be unsafe.Pointer" */ /* ERROR "Pointer redeclared" */ unsafe.Pointer
+		UP /* ERROR "cannot be unsafe.Pointer" */
+		* /* ERROR "cannot be unsafe.Pointer" */  /* ERROR "UP redeclared" */ UP
+	}
+}
+
+// Named types that are pointers.
+
+type S struct{ x int }
+func (*S) m() {}
+type P *S
+
+func _() {
+	var s *S
+	_ = s.x
+	_ = s.m
+
+	var p P
+	_ = p.x
+	_ = p.m /* ERROR "no field or method" */
+	_ = P.m /* ERROR "no field or method" */
+}
+
+// Borrowed from the FieldByName test cases in reflect/all_test.go.
+
+type D1 struct {
+	d int
+}
+type D2 struct {
+	d int
+}
+
+type S0 struct {
+	A, B, C int
+	D1
+	D2
+}
+
+type S1 struct {
+	B int
+	S0
+}
+
+type S2 struct {
+	A int
+	*S1
+}
+
+type S1x struct {
+	S1
+}
+
+type S1y struct {
+	S1
+}
+
+type S3 struct {
+	S1x
+	S2
+	D, E int
+	*S1y
+}
+
+type S4 struct {
+	*S4
+	A int
+}
+
+// The X in S6 and S7 annihilate, but they also block the X in S8.S9.
+type S5 struct {
+	S6
+	S7
+	S8
+}
+
+type S6 struct {
+	X int
+}
+
+type S7 S6
+
+type S8 struct {
+	S9
+}
+
+type S9 struct {
+	X int
+	Y int
+}
+
+// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
+type S10 struct {
+	S11
+	S12
+	S13
+}
+
+type S11 struct {
+	S6
+}
+
+type S12 struct {
+	S6
+}
+
+type S13 struct {
+	S8
+}
+
+func _() {
+	_ = struct{}{}.Foo /* ERROR "no field or method" */
+	_ = S0{}.A
+	_ = S0{}.D /* ERROR "no field or method" */
+	_ = S1{}.A
+	_ = S1{}.B
+	_ = S1{}.S0
+	_ = S1{}.C
+	_ = S2{}.A
+	_ = S2{}.S1
+	_ = S2{}.B
+	_ = S2{}.C
+	_ = S2{}.D /* ERROR "no field or method" */
+	_ = S3{}.S1 /* ERROR "ambiguous selector S3\{\}.S1" */
+	_ = S3{}.A
+	_ = S3{}.B /* ERROR "ambiguous selector" S3\{\}.B */
+	_ = S3{}.D
+	_ = S3{}.E
+	_ = S4{}.A
+	_ = S4{}.B /* ERROR "no field or method" */
+	_ = S5{}.X /* ERROR "ambiguous selector S5\{\}.X" */
+	_ = S5{}.Y
+	_ = S10{}.X /* ERROR "ambiguous selector S10\{\}.X" */
+	_ = S10{}.Y
+}
+
+// Borrowed from the FieldByName benchmark in reflect/all_test.go.
+
+type R0 struct {
+	*R1
+	*R2
+	*R3
+	*R4
+}
+
+type R1 struct {
+	*R5
+	*R6
+	*R7
+	*R8
+}
+
+type R2 R1
+type R3 R1
+type R4 R1
+
+type R5 struct {
+	*R9
+	*R10
+	*R11
+	*R12
+}
+
+type R6 R5
+type R7 R5
+type R8 R5
+
+type R9 struct {
+	*R13
+	*R14
+	*R15
+	*R16
+}
+
+type R10 R9
+type R11 R9
+type R12 R9
+
+type R13 struct {
+	*R17
+	*R18
+	*R19
+	*R20
+}
+
+type R14 R13
+type R15 R13
+type R16 R13
+
+type R17 struct {
+	*R21
+	*R22
+	*R23
+	*R24
+}
+
+type R18 R17
+type R19 R17
+type R20 R17
+
+type R21 struct {
+	X int
+}
+
+type R22 R21
+type R23 R21
+type R24 R21
+
+var _ = R0{}.X /* ERROR "ambiguous selector R0\{\}.X" */
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls4.src b/src/cmd/compile/internal/types2/testdata/check/decls4.src
new file mode 100644
index 0000000..eb08421
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/decls4.src
@@ -0,0 +1,199 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// type aliases
+
+package decls4
+
+type (
+	T0 [10]int
+	T1 []byte
+	T2 struct {
+		x int
+	}
+	T3 interface{
+		m() T2
+	}
+	T4 func(int, T0) chan T2
+)
+
+type (
+	Ai = int
+	A0 = T0
+	A1 = T1
+	A2 = T2
+	A3 = T3
+	A4 = T4
+
+	A10 = [10]int
+	A11 = []byte
+	A12 = struct {
+		x int
+	}
+	A13 = interface{
+		m() A2
+	}
+	A14 = func(int, A0) chan A2
+)
+
+// check assignment compatibility due to equality of types
+var (
+	xi_ int
+	ai Ai = xi_
+
+	x0 T0
+	a0 A0 = x0
+
+	x1 T1
+	a1 A1 = x1
+
+	x2 T2
+	a2 A2 = x2
+
+	x3 T3
+	a3 A3 = x3
+
+	x4 T4
+	a4 A4 = x4
+)
+
+// alias receiver types
+func (Ai /* ERROR "invalid receiver" */) m1() {}
+func (T0) m1() {}
+func (A0) m1 /* ERROR already declared */ () {}
+func (A0) m2 () {}
+func (A3 /* ERROR invalid receiver */ ) m1 () {}
+func (A10 /* ERROR invalid receiver */ ) m1() {}
+
+// x0 has methods m1, m2 declared via receiver type names T0 and A0
+var _ interface{ m1(); m2() } = x0
+
+// alias receiver types (test case for issue #23042)
+type T struct{}
+
+var (
+	_ = T.m
+	_ = T{}.m
+	_ interface{m()} = T{}
+)
+
+var (
+	_ = T.n
+	_ = T{}.n
+	_ interface{m(); n()} = T{}
+)
+
+type U = T
+func (U) m() {}
+
+// alias receiver types (long type declaration chains)
+type (
+	V0 = V1
+	V1 = (V2)
+	V2 = ((V3))
+	V3 = T
+)
+
+func (V0) m /* ERROR already declared */ () {}
+func (V1) n() {}
+
+// alias receiver types (invalid due to cycles)
+type (
+	W0 /* ERROR illegal cycle */ = W1
+	W1 = (W2)
+	W2 = ((W0))
+)
+
+func (W0) m() {} // no error expected (due to above cycle error)
+func (W1) n() {}
+
+// alias receiver types (invalid due to builtin underlying type)
+type (
+	B0 = B1
+	B1 = B2
+	B2 = int
+)
+
+func (B0 /* ERROR invalid receiver */ ) m() {}
+func (B1 /* ERROR invalid receiver */ ) n() {}
+
+// cycles
+type (
+	C2 /* ERROR illegal cycle */ = C2
+	C3 /* ERROR illegal cycle */ = C4
+	C4 = C3
+	C5 struct {
+		f *C6
+	}
+	C6 = C5
+	C7 /* ERROR illegal cycle */  struct {
+		f C8
+	}
+	C8 = C7
+)
+
+// embedded fields
+var (
+	s0 struct { T0 }
+	s1 struct { A0 } = s0 /* ERROR cannot use */ // embedded field names are different
+)
+
+// embedding and lookup of fields and methods
+func _(s struct{A0}) { s.A0 = x0 }
+
+type eX struct{xf int}
+
+func (eX) xm()
+
+type eY = struct{eX} // field/method set of eY includes xf, xm
+
+type eZ = *struct{eX} // field/method set of eZ includes xf, xm
+
+type eA struct {
+	eX // eX contributes xf, xm to eA
+}
+
+type eA2 struct {
+	*eX // *eX contributes xf, xm to eA
+}
+
+type eB struct {
+	eY // eY contributes xf, xm to eB
+}
+
+type eB2 struct {
+	*eY // *eY contributes xf, xm to eB
+}
+
+type eC struct {
+	eZ // eZ contributes xf, xm to eC
+}
+
+var (
+	_ = eA{}.xf
+	_ = eA{}.xm
+	_ = eA2{}.xf
+	_ = eA2{}.xm
+	_ = eB{}.xf
+	_ = eB{}.xm
+	_ = eB2{}.xf
+	_ = eB2{}.xm
+	_ = eC{}.xf
+	_ = eC{}.xm
+)
+
+// ambiguous selectors due to embedding via type aliases
+type eD struct {
+	eY
+	eZ
+}
+
+var (
+	_ = eD{}.xf /* ERROR ambiguous selector eD\{\}.xf */
+	_ = eD{}.xm /* ERROR ambiguous selector eD\{\}.xm */
+)
+
+var (
+	_ interface{ xm() } = eD /* ERROR missing method xm */ {}
+)
\ No newline at end of file
diff --git a/src/go/types/testdata/decls5.src b/src/cmd/compile/internal/types2/testdata/check/decls5.src
similarity index 100%
copy from src/go/types/testdata/decls5.src
copy to src/cmd/compile/internal/types2/testdata/check/decls5.src
diff --git a/src/go/types/testdata/errors.src b/src/cmd/compile/internal/types2/testdata/check/errors.src
similarity index 100%
copy from src/go/types/testdata/errors.src
copy to src/cmd/compile/internal/types2/testdata/check/errors.src
diff --git a/src/go/types/testdata/expr0.src b/src/cmd/compile/internal/types2/testdata/check/expr0.src
similarity index 100%
copy from src/go/types/testdata/expr0.src
copy to src/cmd/compile/internal/types2/testdata/check/expr0.src
diff --git a/src/go/types/testdata/expr1.src b/src/cmd/compile/internal/types2/testdata/check/expr1.src
similarity index 100%
copy from src/go/types/testdata/expr1.src
copy to src/cmd/compile/internal/types2/testdata/check/expr1.src
diff --git a/src/go/types/testdata/expr2.src b/src/cmd/compile/internal/types2/testdata/check/expr2.src
similarity index 100%
copy from src/go/types/testdata/expr2.src
copy to src/cmd/compile/internal/types2/testdata/check/expr2.src
diff --git a/src/cmd/compile/internal/types2/testdata/check/expr3.src b/src/cmd/compile/internal/types2/testdata/check/expr3.src
new file mode 100644
index 0000000..eab3f72
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/expr3.src
@@ -0,0 +1,565 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package expr3
+
+import "time"
+
+func indexes() {
+	var x int
+	_ = 1 /* ERROR "cannot index" */ [0]
+	_ = x /* ERROR "cannot index" */ [0]
+	_ = ( /* ERROR "cannot slice" */ 12 + 3)[1:2]
+
+	var a [10]int
+	_ = a[true /* ERROR "cannot convert" */ ]
+	_ = a["foo" /* ERROR "cannot convert" */ ]
+	_ = a[1.1 /* ERROR "truncated" */ ]
+	_ = a[1.0]
+	_ = a[- /* ERROR "negative" */ 1]
+	_ = a[- /* ERROR "negative" */ 1 :]
+	_ = a[: - /* ERROR "negative" */ 1]
+	_ = a[: /* ERROR "middle index required" */ : /* ERROR "final index required" */ ]
+	_ = a[0: /* ERROR "middle index required" */ : /* ERROR "final index required" */ ]
+	_ = a[0: /* ERROR "middle index required" */ :10]
+	_ = a[:10:10]
+
+	var a0 int
+	a0 = a[0]
+	_ = a0
+	var a1 int32
+	a1 = a /* ERROR "cannot use .* in assignment" */ [1]
+	_ = a1
+
+	_ = a[9]
+	_ = a[10 /* ERROR "index .* out of bounds" */ ]
+	_ = a[1 /* ERROR "overflows" */ <<100]
+	_ = a[1<< /* ERROR "constant shift overflow" */ 1000] // no out-of-bounds follow-on error
+	_ = a[10:]
+	_ = a[:10]
+	_ = a[10:10]
+	_ = a[11 /* ERROR "index .* out of bounds" */ :]
+	_ = a[: 11 /* ERROR "index .* out of bounds" */ ]
+	_ = a[: 1 /* ERROR "overflows" */ <<100]
+	_ = a[:10:10]
+	_ = a[:11 /* ERROR "index .* out of bounds" */ :10]
+	_ = a[:10:11 /* ERROR "index .* out of bounds" */ ]
+	_ = a[10:0:10] /* ERROR "invalid slice indices" */
+	_ = a[0:10:0] /* ERROR "invalid slice indices" */
+	_ = a[10:0:0] /* ERROR "invalid slice indices" */
+	_ = &a /* ERROR "cannot take address" */ [:10]
+
+	pa := &a
+	_ = pa[9]
+	_ = pa[10 /* ERROR "index .* out of bounds" */ ]
+	_ = pa[1 /* ERROR "overflows" */ <<100]
+	_ = pa[10:]
+	_ = pa[:10]
+	_ = pa[10:10]
+	_ = pa[11 /* ERROR "index .* out of bounds" */ :]
+	_ = pa[: 11 /* ERROR "index .* out of bounds" */ ]
+	_ = pa[: 1 /* ERROR "overflows" */ <<100]
+	_ = pa[:10:10]
+	_ = pa[:11 /* ERROR "index .* out of bounds" */ :10]
+	_ = pa[:10:11 /* ERROR "index .* out of bounds" */ ]
+	_ = pa[10:0:10] /* ERROR "invalid slice indices" */
+	_ = pa[0:10:0] /* ERROR "invalid slice indices" */
+	_ = pa[10:0:0] /* ERROR "invalid slice indices" */
+	_ = &pa /* ERROR "cannot take address" */ [:10]
+
+	var b [0]int
+	_ = b[0 /* ERROR "index .* out of bounds" */ ]
+	_ = b[:]
+	_ = b[0:]
+	_ = b[:0]
+	_ = b[0:0]
+	_ = b[0:0:0]
+	_ = b[1 /* ERROR "index .* out of bounds" */ :0:0]
+
+	var s []int
+	_ = s[- /* ERROR "negative" */ 1]
+	_ = s[- /* ERROR "negative" */ 1 :]
+	_ = s[: - /* ERROR "negative" */ 1]
+	_ = s[0]
+	_ = s[1:2]
+	_ = s[2:1] /* ERROR "invalid slice indices" */
+	_ = s[2:]
+	_ = s[: 1 /* ERROR "overflows" */ <<100]
+	_ = s[1 /* ERROR "overflows" */ <<100 :]
+	_ = s[1 /* ERROR "overflows" */ <<100 : 1 /* ERROR "overflows" */ <<100]
+	_ = s[: /* ERROR "middle index required" */ :  /* ERROR "final index required" */ ]
+	_ = s[:10:10]
+	_ = s[10:0:10] /* ERROR "invalid slice indices" */
+	_ = s[0:10:0] /* ERROR "invalid slice indices" */
+	_ = s[10:0:0] /* ERROR "invalid slice indices" */
+	_ = &s /* ERROR "cannot take address" */ [:10]
+
+	var m map[string]int
+	_ = m[0 /* ERROR "cannot use .* in map index" */ ]
+	_ = m /* ERROR "cannot slice" */ ["foo" : "bar"]
+	_ = m["foo"]
+	// ok is of type bool
+	type mybool bool
+	var ok mybool
+	_, ok = m["bar"]
+	_ = ok
+	_ = m[0 /* ERROR "cannot use 0" */ ] + "foo" // ERROR "cannot convert"
+
+	var t string
+	_ = t[- /* ERROR "negative" */ 1]
+	_ = t[- /* ERROR "negative" */ 1 :]
+	_ = t[: - /* ERROR "negative" */ 1]
+	_ = t /* ERROR "3-index slice of string" */ [1:2:3]
+	_ = "foo" /* ERROR "3-index slice of string" */ [1:2:3]
+	var t0 byte
+	t0 = t[0]
+	_ = t0
+	var t1 rune
+	t1 = t /* ERROR "cannot use .* in assignment" */ [2]
+	_ = t1
+	_ = ("foo" + "bar")[5]
+	_ = ("foo" + "bar")[6 /* ERROR "index .* out of bounds" */ ]
+
+	const c = "foo"
+	_ = c[- /* ERROR "negative" */ 1]
+	_ = c[- /* ERROR "negative" */ 1 :]
+	_ = c[: - /* ERROR "negative" */ 1]
+	var c0 byte
+	c0 = c[0]
+	_ = c0
+	var c2 float32
+	c2 = c /* ERROR "cannot use .* in assignment" */ [2]
+	_ = c[3 /* ERROR "index .* out of bounds" */ ]
+	_ = ""[0 /* ERROR "index .* out of bounds" */ ]
+	_ = c2
+
+	_ = s[1<<30] // no compile-time error here
+
+	// issue 4913
+	type mystring string
+	var ss string
+	var ms mystring
+	var i, j int
+	ss = "foo"[1:2]
+	ss = "foo"[i:j]
+	ms = "foo" /* ERROR "cannot use .* in assignment" */ [1:2]
+	ms = "foo" /* ERROR "cannot use .* in assignment" */ [i:j]
+	_, _ = ss, ms
+}
+
+type T struct {
+	x int
+	y func()
+}
+
+func (*T) m() {}
+
+func method_expressions() {
+	_ = T.a /* ERROR "no field or method" */
+	_ = T.x /* ERROR "has no method" */
+	_ = T.m /* ERROR "cannot call pointer method m on T" */
+	_ = (*T).m
+
+	var f func(*T) = T.m /* ERROR "cannot call pointer method m on T" */
+	var g func(*T) = (*T).m
+	_, _ = f, g
+
+	_ = T.y /* ERROR "has no method" */
+	_ = (*T).y /* ERROR "has no method" */
+}
+
+func struct_literals() {
+	type T0 struct {
+		a, b, c int
+	}
+
+	type T1 struct {
+		T0
+		a, b int
+		u float64
+		s string
+	}
+
+	// keyed elements
+	_ = T1{}
+	_ = T1{a: 0, 1 /* ERROR "mixture of .* elements" */ }
+	_ = T1{aa /* ERROR "unknown field" */ : 0}
+	_ = T1{1 /* ERROR "invalid field name" */ : 0}
+	_ = T1{a: 0, s: "foo", u: 0, a /* ERROR "duplicate field" */: 10}
+	_ = T1{a: "foo" /* ERROR "cannot use .* in struct literal" */ }
+	_ = T1{c /* ERROR "unknown field" */ : 0}
+	_ = T1{T0: { /* ERROR "missing type" */ }} // struct literal element type may not be elided
+	_ = T1{T0: T0{}}
+	_ = T1{T0 /* ERROR "invalid field name" */ .a: 0}
+
+	// unkeyed elements
+	_ = T0{1, 2, 3}
+	_ = T0{1, b /* ERROR "mixture" */ : 2, 3}
+	_ = T0{1, 2} /* ERROR "too few values" */
+	_ = T0{1, 2, 3, 4  /* ERROR "too many values" */ }
+	_ = T0{1, "foo" /* ERROR "cannot use .* in struct literal" */, 3.4  /* ERROR "cannot use .*\(truncated\)" */}
+
+	// invalid type
+	type P *struct{
+		x int
+	}
+	_ = P /* ERROR "invalid composite literal type" */ {}
+
+	// unexported fields
+	_ = time.Time{}
+	_ = time.Time{sec /* ERROR "unknown field" */ : 0}
+	_ = time.Time{
+		0 /* ERROR implicit assignment to unexported field wall in time.Time literal */,
+		0 /* ERROR implicit assignment */ ,
+		nil /* ERROR implicit assignment */ ,
+	}
+}
+
+func array_literals() {
+	type A0 [0]int
+	_ = A0{}
+	_ = A0{0 /* ERROR "index .* out of bounds" */}
+	_ = A0{0 /* ERROR "index .* out of bounds" */ : 0}
+
+	type A1 [10]int
+	_ = A1{}
+	_ = A1{0, 1, 2}
+	_ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+	_ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /* ERROR "index .* out of bounds" */ }
+	_ = A1{- /* ERROR "negative" */ 1: 0}
+	_ = A1{8: 8, 9}
+	_ = A1{8: 8, 9, 10 /* ERROR "index .* out of bounds" */ }
+	_ = A1{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
+	_ = A1{5: 5, 6, 7, 3: 3, 4}
+	_ = A1{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ }
+	_ = A1{10 /* ERROR "index .* out of bounds" */ : 10, 10 /* ERROR "index .* out of bounds" */ : 10}
+	_ = A1{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ }
+	_ = A1{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4}
+	_ = A1{2.0}
+	_ = A1{2.1 /* ERROR "truncated" */ }
+	_ = A1{"foo" /* ERROR "cannot use .* in array or slice literal" */ }
+
+	// indices must be integer constants
+	i := 1
+	const f = 2.1
+	const s = "foo"
+	_ = A1{i /* ERROR "index i must be integer constant" */ : 0}
+	_ = A1{f /* ERROR "truncated" */ : 0}
+	_ = A1{s /* ERROR "cannot convert" */ : 0}
+
+	a0 := [...]int{}
+	assert(len(a0) == 0)
+
+	a1 := [...]int{0, 1, 2}
+	assert(len(a1) == 3)
+	var a13 [3]int
+	var a14 [4]int
+	a13 = a1
+	a14 = a1 /* ERROR "cannot use .* in assignment" */
+	_, _ = a13, a14
+
+	a2 := [...]int{- /* ERROR "negative" */ 1: 0}
+	_ = a2
+
+	a3 := [...]int{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
+	assert(len(a3) == 5) // somewhat arbitrary
+
+	a4 := [...]complex128{0, 1, 2, 1<<10-2: -1i, 1i, 400: 10, 12, 14}
+	assert(len(a4) == 1024)
+
+	// composite literal element types may be elided
+	type T []int
+	_ = [10]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
+	a6 := [...]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
+	assert(len(a6) == 8)
+
+	// recursively so
+	_ = [10][10]T{{}, [10]T{{}}, {{1, 2, 3}}}
+
+	// from the spec
+	type Point struct { x, y float32 }
+	_ = [...]Point{Point{1.5, -3.5}, Point{0, 0}}
+	_ = [...]Point{{1.5, -3.5}, {0, 0}}
+	_ = [][]int{[]int{1, 2, 3}, []int{4, 5}}
+	_ = [][]int{{1, 2, 3}, {4, 5}}
+	_ = [...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}
+	_ = [...]*Point{{1.5, -3.5}, {0, 0}}
+}
+
+func slice_literals() {
+	type S0 []int
+	_ = S0{}
+	_ = S0{0, 1, 2}
+	_ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+	_ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
+	_ = S0{- /* ERROR "negative" */ 1: 0}
+	_ = S0{8: 8, 9}
+	_ = S0{8: 8, 9, 10}
+	_ = S0{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
+	_ = S0{5: 5, 6, 7, 3: 3, 4}
+	_ = S0{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ }
+	_ = S0{10: 10, 10 /* ERROR "duplicate index" */ : 10}
+	_ = S0{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ }
+	_ = S0{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4}
+	_ = S0{2.0}
+	_ = S0{2.1 /* ERROR "truncated" */ }
+	_ = S0{"foo" /* ERROR "cannot use .* in array or slice literal" */ }
+
+	// indices must be resolved correctly
+	const index1 = 1
+	_ = S0{index1: 1}
+	_ = S0{index2: 2}
+	_ = S0{index3 /* ERROR "undeclared name" */ : 3}
+
+	// indices must be integer constants
+	i := 1
+	const f = 2.1
+	const s = "foo"
+	_ = S0{i /* ERROR "index i must be integer constant" */ : 0}
+	_ = S0{f /* ERROR "truncated" */ : 0}
+	_ = S0{s /* ERROR "cannot convert" */ : 0}
+
+	// composite literal element types may be elided
+	type T []int
+	_ = []T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
+	_ = [][]int{{1, 2, 3}, {4, 5}}
+
+	// recursively so
+	_ = [][]T{{}, []T{{}}, {{1, 2, 3}}}
+
+	// issue 17954
+	type T0 *struct { s string }
+	_ = []T0{{}}
+	_ = []T0{{"foo"}}
+
+	type T1 *struct{ int }
+	_ = []T1{}
+	_ = []T1{{0}, {1}, {2}}
+
+	type T2 T1
+	_ = []T2{}
+	_ = []T2{{0}, {1}, {2}}
+
+	_ = map[T0]T2{}
+	_ = map[T0]T2{{}: {}}
+}
+
+const index2 int = 2
+
+type N int
+func (N) f() {}
+
+func map_literals() {
+	type M0 map[string]int
+	type M1 map[bool]int
+	type M2 map[*int]int
+
+	_ = M0{}
+	_ = M0{1 /* ERROR "missing key" */ }
+	_ = M0{1 /* ERROR "cannot use .* in map literal" */ : 2}
+	_ = M0{"foo": "bar" /* ERROR "cannot use .* in map literal" */ }
+	_ = M0{"foo": 1, "bar": 2, "foo" /* ERROR "duplicate key" */ : 3 }
+
+	_ = map[interface{}]int{2: 1, 2 /* ERROR "duplicate key" */ : 1}
+	_ = map[interface{}]int{int(2): 1, int16(2): 1}
+	_ = map[interface{}]int{int16(2): 1, int16 /* ERROR "duplicate key" */ (2): 1}
+
+	type S string
+
+	_ = map[interface{}]int{"a": 1, "a" /* ERROR "duplicate key" */ : 1}
+	_ = map[interface{}]int{"a": 1, S("a"): 1}
+	_ = map[interface{}]int{S("a"): 1, S /* ERROR "duplicate key" */ ("a"): 1}
+	_ = map[interface{}]int{1.0: 1, 1.0 /* ERROR "duplicate key" */: 1}
+	_ = map[interface{}]int{int64(-1): 1, int64 /* ERROR "duplicate key" */ (-1) : 1}
+	_ = map[interface{}]int{^uint64(0): 1, ^ /* ERROR "duplicate key" */ uint64(0): 1}
+	_ = map[interface{}]int{complex(1,2): 1, complex /* ERROR "duplicate key" */ (1,2) : 1}
+
+	type I interface {
+		f()
+	}
+
+	_ = map[I]int{N(0): 1, N(2): 1}
+	_ = map[I]int{N(2): 1, N /* ERROR "duplicate key" */ (2): 1}
+
+	// map keys must be resolved correctly
+	key1 := "foo"
+	_ = M0{key1: 1}
+	_ = M0{key2: 2}
+	_ = M0{key3 /* ERROR "undeclared name" */ : 2}
+
+	var value int
+	_ = M1{true: 1, false: 0}
+	_ = M2{nil: 0, &value: 1}
+
+	// composite literal element types may be elided
+	type T [2]int
+	_ = map[int]T{0: T{3, 4}, 1: {5, 6}}
+
+	// recursively so
+	_ = map[int][]T{0: {}, 1: {{}, T{1, 2}}}
+
+	// composite literal key types may be elided
+	_ = map[T]int{T{3, 4}: 0, {5, 6}: 1}
+
+	// recursively so
+	_ = map[[2]T]int{{}: 0, {{}}: 1, [2]T{{}}: 2, {T{1, 2}}: 3}
+
+	// composite literal element and key types may be elided
+	_ = map[T]T{{}: {}, {1, 2}: T{3, 4}, T{4, 5}: {}}
+	_ = map[T]M0{{} : {}, T{1, 2}: M0{"foo": 0}, {1, 3}: {"foo": 1}}
+
+	// recursively so
+	_ = map[[2]T][]T{{}: {}, {{}}: {{}, T{1, 2}}, [2]T{{}}: nil, {T{1, 2}}: {{}, {}}}
+
+	// from the spec
+	type Point struct { x, y float32 }
+	_ = map[string]Point{"orig": {0, 0}}
+	_ = map[*Point]string{{0, 0}: "orig"}
+
+	// issue 17954
+	type T0 *struct{ s string }
+	type T1 *struct{ int }
+	type T2 T1
+
+	_ = map[T0]T2{}
+	_ = map[T0]T2{{}: {}}
+}
+
+var key2 string = "bar"
+
+type I interface {
+	m()
+}
+
+type I2 interface {
+	m(int)
+}
+
+type T1 struct{}
+type T2 struct{}
+
+func (T2) m(int) {}
+
+type mybool bool
+
+func type_asserts() {
+	var x int
+	_ = x /* ERROR "not an interface" */ .(int)
+
+	var e interface{}
+	var ok bool
+	x, ok = e.(int)
+	_ = ok
+
+	// ok value is of type bool
+	var myok mybool
+	_, myok = e.(int)
+	_ = myok
+
+	var t I
+	_ = t /* ERROR "use of .* outside type switch" */ .(type)
+	_ = t /* ERROR "missing method m" */ .(T)
+	_ = t.(*T)
+	_ = t /* ERROR "missing method m" */ .(T1)
+	_ = t /* ERROR "wrong type for method m" */ .(T2)
+	_ = t /* STRICT "wrong type for method m" */ .(I2) // only an error in strict mode (issue 8561)
+
+	// e doesn't statically have an m, but may have one dynamically.
+	_ = e.(I2)
+}
+
+func f0() {}
+func f1(x int) {}
+func f2(u float32, s string) {}
+func fs(s []byte) {}
+func fv(x ...int) {}
+func fi(x ... interface{}) {}
+func (T) fm(x ...int)
+
+func g0() {}
+func g1() int { return 0}
+func g2() (u float32, s string) { return }
+func gs() []byte { return nil }
+
+func _calls() {
+	var x int
+	var y float32
+	var s []int
+
+	f0()
+	_ = f0 /* ERROR "used as value" */ ()
+	f0(g0 /* ERROR "too many arguments" */ )
+
+	f1(0)
+	f1(x)
+	f1(10.0)
+	f1() /* ERROR "not enough arguments" */
+	f1(x, y /* ERROR "too many arguments" */ )
+	f1(s /* ERROR "cannot use .* in argument" */ )
+	f1(x ... /* ERROR "cannot use ..." */ )
+	f1(g0 /* ERROR "used as value" */ ())
+	f1(g1())
+	f1(g2 /* ERROR "too many arguments" */ ())
+
+	f2() /* ERROR "not enough arguments" */
+	f2(3.14) /* ERROR "not enough arguments" */
+	f2(3.14, "foo")
+	f2(x /* ERROR "cannot use .* in argument" */ , "foo")
+	f2(g0 /* ERROR "used as value" */ ())
+	f2(g1()) /* ERROR "not enough arguments" */
+	f2(g2())
+
+	fs() /* ERROR "not enough arguments" */
+	fs(g0 /* ERROR "used as value" */ ())
+	fs(g1 /* ERROR "cannot use .* in argument" */ ())
+	fs(g2 /* ERROR "too many arguments" */ ())
+	fs(gs())
+
+	fv()
+	fv(1, 2.0, x)
+	fv(s /* ERROR "cannot use .* in argument" */ )
+	fv(s...)
+	fv(x /* ERROR "cannot use" */ ...)
+	fv(1, s /* ERROR "too many arguments" */ ... )
+	fv(gs /* ERROR "cannot use .* in argument" */ ())
+	fv(gs /* ERROR "cannot use .* in argument" */ ()...)
+
+	var t T
+	t.fm()
+	t.fm(1, 2.0, x)
+	t.fm(s /* ERROR "cannot use .* in argument" */ )
+	t.fm(g1())
+	t.fm(1, s /* ERROR "too many arguments" */ ... )
+	t.fm(gs /* ERROR "cannot use .* in argument" */ ())
+	t.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
+
+	T.fm(t, )
+	T.fm(t, 1, 2.0, x)
+	T.fm(t, s /* ERROR "cannot use .* in argument" */ )
+	T.fm(t, g1())
+	T.fm(t, 1, s /* ERROR "too many arguments" */ ... )
+	T.fm(t, gs /* ERROR "cannot use .* in argument" */ ())
+	T.fm(t, gs /* ERROR "cannot use .* in argument" */ ()...)
+
+	var i interface{ fm(x ...int) } = t
+	i.fm()
+	i.fm(1, 2.0, x)
+	i.fm(s /* ERROR "cannot use .* in argument" */ )
+	i.fm(g1())
+	i.fm(1, s /* ERROR "too many arguments" */ ... )
+	i.fm(gs /* ERROR "cannot use .* in argument" */ ())
+	i.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
+
+	fi()
+	fi(1, 2.0, x, 3.14, "foo")
+	fi(g2())
+	fi(0, g2)
+	fi(0, g2 /* ERROR "2-valued g2" */ ())
+}
+
+func issue6344() {
+	type T []interface{}
+	var x T
+	fi(x...) // ... applies also to named slices
+}
diff --git a/src/cmd/compile/internal/types2/testdata/check/go1_12.src b/src/cmd/compile/internal/types2/testdata/check/go1_12.src
new file mode 100644
index 0000000..75a602b
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/go1_12.src
@@ -0,0 +1,34 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check Go language version-specific errors.
+
+package go1_12 // go1.12
+
+// numeric literals
+const (
+	_ = 1_000 // ERROR "underscores in numeric literals requires go1.13 or later"
+	_ = 0b111 // ERROR "binary literals requires go1.13 or later"
+	_ = 0o567 // ERROR "0o/0O-style octal literals requires go1.13 or later"
+	_ = 0xabc // ok
+	_ = 0x0p1 // ERROR "hexadecimal floating-point literals requires go1.13 or later"
+
+	_ = 0B111 // ERROR "binary"
+	_ = 0O567 // ERROR "octal"
+	_ = 0Xabc // ok
+	_ = 0X0P1 // ERROR "hexadecimal floating-point"
+
+	_ = 1_000i // ERROR "underscores"
+	_ = 0b111i // ERROR "binary"
+	_ = 0o567i // ERROR "octal"
+	_ = 0xabci // ERROR "hexadecimal floating-point"
+	_ = 0x0p1i // ERROR "hexadecimal floating-point"
+)
+
+// signed shift counts
+var (
+	s int
+	_ = 1 << s // ERROR "invalid operation: signed shift count s \(variable of type int\) requires go1.13 or later"
+	_ = 1 >> s // ERROR "signed shift count"
+)
diff --git a/src/cmd/compile/internal/types2/testdata/check/go1_13.src b/src/cmd/compile/internal/types2/testdata/check/go1_13.src
new file mode 100644
index 0000000..93cb4c7
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/go1_13.src
@@ -0,0 +1,21 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check Go language version-specific errors.
+
+package go1_13 // go1.13
+
+// interface embedding
+
+type I interface { m() }
+
+type _ interface {
+	m()
+	I // ERROR "duplicate method m"
+}
+
+type _ interface {
+	I
+	I // ERROR "duplicate method m"
+}
diff --git a/src/cmd/compile/internal/types2/testdata/check/go1_16.src b/src/cmd/compile/internal/types2/testdata/check/go1_16.src
new file mode 100644
index 0000000..fdf5c99
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/go1_16.src
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check Go language version-specific errors.
+
+package go1_16 // go1.16
+
+type Slice []byte
+type Array [8]byte
+
+var s Slice
+var p = (*Array)(s /* ERROR requires go1.17 or later */ )
diff --git a/src/cmd/compile/internal/types2/testdata/check/go1_8.src b/src/cmd/compile/internal/types2/testdata/check/go1_8.src
new file mode 100644
index 0000000..0f3ba94
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/go1_8.src
@@ -0,0 +1,10 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check Go language version-specific errors.
+
+package go1_8 // go1.8
+
+// type alias declarations
+type any /* ERROR type aliases requires go1.9 or later */ = interface{}
diff --git a/src/go/types/testdata/gotos.src b/src/cmd/compile/internal/types2/testdata/check/gotos.src
similarity index 100%
copy from src/go/types/testdata/gotos.src
copy to src/cmd/compile/internal/types2/testdata/check/gotos.src
diff --git a/src/go/types/testdata/importC.src b/src/cmd/compile/internal/types2/testdata/check/importC.src
similarity index 100%
copy from src/go/types/testdata/importC.src
copy to src/cmd/compile/internal/types2/testdata/check/importC.src
diff --git a/src/cmd/compile/internal/types2/testdata/check/importdecl0/importdecl0a.src b/src/cmd/compile/internal/types2/testdata/check/importdecl0/importdecl0a.src
new file mode 100644
index 0000000..5ceb96e
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/importdecl0/importdecl0a.src
@@ -0,0 +1,53 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package importdecl0
+
+import ()
+
+import (
+	// we can have multiple blank imports (was bug)
+	_ "math"
+	_ "net/rpc"
+	init /* ERROR "cannot import package as init" */ "fmt"
+	// reflect defines a type "flag" which shows up in the gc export data
+	"reflect"
+	. /* ERROR "imported but not used" */ "reflect"
+)
+
+import "math" /* ERROR "imported but not used" */
+import m /* ERROR "imported but not used as m" */ "math"
+import _ "math"
+
+import (
+	"math/big" /* ERROR "imported but not used" */
+	b /* ERROR "imported but not used" */ "math/big"
+	_ "math/big"
+)
+
+import "fmt"
+import f1 "fmt"
+import f2 "fmt"
+
+// reflect.flag must not be visible in this package
+type flag int
+type _ reflect.flag /* ERROR "not exported" */
+
+// imported package name may conflict with local objects
+type reflect /* ERROR "reflect already declared" */ int
+
+// dot-imported exported objects may conflict with local objects
+type Value /* ERROR "Value already declared through dot-import of package reflect" */ struct{}
+
+var _ = fmt.Println // use "fmt"
+
+func _() {
+	f1.Println() // use "fmt"
+}
+
+func _() {
+	_ = func() {
+		f2.Println() // use "fmt"
+	}
+}
diff --git a/src/cmd/compile/internal/types2/testdata/check/importdecl0/importdecl0b.src b/src/cmd/compile/internal/types2/testdata/check/importdecl0/importdecl0b.src
new file mode 100644
index 0000000..19b55af
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/importdecl0/importdecl0b.src
@@ -0,0 +1,30 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package importdecl0
+
+import "math"
+import m "math"
+
+import . "testing" // declares T in file scope
+import . /* ERROR .unsafe. imported but not used */ "unsafe"
+import . "fmt"     // declares Println in file scope
+
+import (
+	"" /* ERROR invalid import path */
+	"a!b" /* ERROR invalid import path */
+	"abc\xffdef" /* ERROR invalid import path */
+)
+
+// using "math" in this file doesn't affect its use in other files
+const Pi0 = math.Pi
+const Pi1 = m.Pi
+
+type _ T // use "testing"
+
+func _() func() interface{} {
+	return func() interface{} {
+		return Println // use "fmt"
+	}
+}
diff --git a/src/go/types/testdata/importdecl1a.src b/src/cmd/compile/internal/types2/testdata/check/importdecl1/importdecl1a.src
similarity index 100%
copy from src/go/types/testdata/importdecl1a.src
copy to src/cmd/compile/internal/types2/testdata/check/importdecl1/importdecl1a.src
diff --git a/src/cmd/compile/internal/types2/testdata/check/importdecl1/importdecl1b.src b/src/cmd/compile/internal/types2/testdata/check/importdecl1/importdecl1b.src
new file mode 100644
index 0000000..43a7bcd
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/importdecl1/importdecl1b.src
@@ -0,0 +1,11 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package importdecl1
+
+import . /* ERROR .unsafe. imported but not used */ "unsafe"
+
+type B interface {
+	A
+}
diff --git a/src/go/types/testdata/init0.src b/src/cmd/compile/internal/types2/testdata/check/init0.src
similarity index 100%
copy from src/go/types/testdata/init0.src
copy to src/cmd/compile/internal/types2/testdata/check/init0.src
diff --git a/src/go/types/testdata/init1.src b/src/cmd/compile/internal/types2/testdata/check/init1.src
similarity index 100%
copy from src/go/types/testdata/init1.src
copy to src/cmd/compile/internal/types2/testdata/check/init1.src
diff --git a/src/go/types/testdata/init2.src b/src/cmd/compile/internal/types2/testdata/check/init2.src
similarity index 100%
copy from src/go/types/testdata/init2.src
copy to src/cmd/compile/internal/types2/testdata/check/init2.src
diff --git a/src/go/types/testdata/issue25008a.src b/src/cmd/compile/internal/types2/testdata/check/issue25008/issue25008a.src
similarity index 100%
copy from src/go/types/testdata/issue25008a.src
copy to src/cmd/compile/internal/types2/testdata/check/issue25008/issue25008a.src
diff --git a/src/go/types/testdata/issue25008b.src b/src/cmd/compile/internal/types2/testdata/check/issue25008/issue25008b.src
similarity index 100%
copy from src/go/types/testdata/issue25008b.src
copy to src/cmd/compile/internal/types2/testdata/check/issue25008/issue25008b.src
diff --git a/src/cmd/compile/internal/types2/testdata/check/issues.go2 b/src/cmd/compile/internal/types2/testdata/check/issues.go2
new file mode 100644
index 0000000..1c73b5d
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/issues.go2
@@ -0,0 +1,249 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains regression tests for bugs found.
+
+package p
+
+import "io"
+import "context"
+
+// Interfaces are always comparable (though the comparison may panic at runtime).
+func eql[T comparable](x, y T) bool {
+	return x == y
+}
+
+func _() {
+	var x interface{}
+	var y interface{ m() }
+	eql(x, y /* ERROR does not match */ ) // interfaces of different types
+	eql(x, x)
+	eql(y, y)
+	eql(y, nil)
+	eql[io.Reader](nil, nil)
+}
+
+// If we have a receiver of pointer type (below: *T) we must ignore
+// the pointer in the implementation of the method lookup because
+// the type bound of T is an interface and pointer to interface types
+// have no methods and then the lookup would fail.
+type C[T any] interface {
+    m()
+}
+
+// using type bound C
+func _[T C[T]](x *T) {
+	x.m()
+}
+
+// using an interface literal as bound
+func _[T interface{ m() }](x *T) {
+	x.m()
+}
+
+func f2[_ interface{ m1(); m2() }]()
+
+type T struct{}
+func (T) m1()
+func (*T) m2()
+
+func _() {
+	f2[T /* ERROR wrong method signature */ ]()
+	f2[*T]()
+}
+
+// When a type parameter is used as an argument to instantiate a parameterized
+// type with a type list constraint, all of the type argument's types in its
+// bound, but at least one (!), must be in the type list of the bound of the
+// corresponding parameterized type's type parameter.
+type T1[P interface{type uint}] struct{}
+
+func _[P any]() {
+    _ = T1[P /* ERROR P has no type constraints */ ]{}
+}
+
+// This is the original (simplified) program causing the same issue.
+type Unsigned interface {
+	type uint
+}
+
+type T2[U Unsigned] struct {
+    s U
+}
+
+func (u T2[U]) Add1() U {
+    return u.s + 1
+}
+
+func NewT2[U any]() T2[U /* ERROR U has no type constraints */ ] {
+    return T2[U /* ERROR U has no type constraints */ ]{}
+}
+
+func _() {
+    u := NewT2[string]()
+    _ = u.Add1()
+}
+
+// When we encounter an instantiated type such as Elem[T] we must
+// not "expand" the instantiation when the type to be instantiated
+// (Elem in this case) is not yet fully set up.
+type Elem[T any] struct {
+	next *Elem[T]
+	list *List[T]
+}
+
+type List[T any] struct {
+	root Elem[T]
+}
+
+func (l *List[T]) Init() {
+	l.root.next = &l.root
+}
+
+// This is the original program causing the same issue.
+type Element2[TElem any] struct {
+	next, prev *Element2[TElem]
+	list *List2[TElem]
+	Value TElem
+}
+
+type List2[TElem any] struct {
+	root Element2[TElem]
+	len  int
+}
+
+func (l *List2[TElem]) Init() *List2[TElem] {
+	l.root.next = &l.root
+	l.root.prev = &l.root
+	l.len = 0
+	return l
+}
+
+// Self-recursive instantiations must work correctly.
+type A[P any] struct { _ *A[P] }
+
+type AB[P any] struct { _ *BA[P] }
+type BA[P any] struct { _ *AB[P] }
+
+// And a variation that also caused a problem with an
+// unresolved underlying type.
+type Element3[TElem any] struct {
+	next, prev *Element3[TElem]
+	list *List3[TElem]
+	Value TElem
+}
+
+func (e *Element3[TElem]) Next() *Element3[TElem] {
+	if p := e.next; e.list != nil && p != &e.list.root {
+		return p
+	}
+	return nil
+}
+
+type List3[TElem any] struct {
+	root Element3[TElem]
+	len  int
+}
+
+// Infinite generic type declarations must lead to an error.
+type inf1[T any] struct{ _ inf1 /* ERROR illegal cycle */ [T] }
+type inf2[T any] struct{ inf2 /* ERROR illegal cycle */ [T] }
+
+// The implementation of conversions T(x) between integers and floating-point
+// numbers checks that both T and x have either integer or floating-point
+// type. When the type of T or x is a type parameter, the respective simple
+// predicate disjunction in the implementation was wrong because if a type list
+// contains both an integer and a floating-point type, the type parameter is
+// neither an integer or a floating-point number.
+func convert[T1, T2 interface{type int, uint, float32}](v T1) T2 {
+	return T2(v)
+}
+
+func _() {
+	convert[int, uint](5)
+}
+
+// When testing binary operators, for +, the operand types must either be
+// both numeric, or both strings. The implementation had the same problem
+// with this check as the conversion issue above (issue #39623).
+
+func issue39623[T interface{type int, string}](x, y T) T {
+	return x + y
+}
+
+// Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI:
+func Sum[T interface{type int, string}](s []T) (sum T) {
+	for _, v := range s {
+		sum += v
+	}
+	return
+}
+
+// Assignability of an unnamed pointer type to a type parameter that
+// has a matching underlying type.
+func _[T interface{}, PT interface{type *T}] (x T) PT {
+    return &x
+}
+
+// Indexing of generic types containing type parameters in their type list:
+func at[T interface{ type []E }, E interface{}](x T, i int) E {
+        return x[i]
+}
+
+// A generic type inside a function acts like a named type. Its underlying
+// type is itself, its "operational type" is defined by the type list in
+// the tybe bound, if any.
+func _[T interface{type int}](x T) {
+	type myint int
+	var _ int = int(x)
+	var _ T = 42
+	var _ T = T(myint(42))
+}
+
+// Indexing a generic type with an array type bound checks length.
+// (Example by mdempsky@.)
+func _[T interface { type [10]int }](x T) {
+	_ = x[9] // ok
+	_ = x[20 /* ERROR out of bounds */ ]
+}
+
+// Pointer indirection of a generic type.
+func _[T interface{ type *int }](p T) int {
+	return *p
+}
+
+// Channel sends and receives on generic types.
+func _[T interface{ type chan int }](ch T) int {
+	ch <- 0
+	return <- ch
+}
+
+// Calling of a generic variable.
+func _[T interface{ type func() }](f T) {
+	f()
+	go f()
+}
+
+// We must compare against the underlying type of type list entries
+// when checking if a constraint is satisfied by a type. The under-
+// lying type of each type list entry must be computed after the
+// interface has been instantiated as its typelist may contain a
+// type parameter that was substituted with a defined type.
+// Test case from an (originally) failing example.
+
+type sliceOf[E any] interface{ type []E }
+
+func append[T interface{}, S sliceOf[T], T2 interface{ type T }](s S, t ...T2) S
+
+var f           func()
+var cancelSlice []context.CancelFunc
+var _ = append[context.CancelFunc, []context.CancelFunc, context.CancelFunc](cancelSlice, f)
+
+// A generic function must be instantiated with a type, not a value.
+
+func g[T any](T) T
+
+var _ = g[int]
+var _ = g[nil /* ERROR is not a type */ ]
+var _ = g(0)
diff --git a/src/cmd/compile/internal/types2/testdata/check/issues.src b/src/cmd/compile/internal/types2/testdata/check/issues.src
new file mode 100644
index 0000000..21aa208
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/issues.src
@@ -0,0 +1,371 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issues
+
+import (
+	"fmt"
+	syn "cmd/compile/internal/syntax"
+	t1 "text/template"
+	t2 "html/template"
+)
+
+func issue7035() {
+	type T struct{ X int }
+	_ = func() {
+		fmt.Println() // must refer to imported fmt rather than the fmt below
+	}
+	fmt := new(T)
+	_ = fmt.X
+}
+
+func issue8066() {
+	const (
+		_ = float32(340282356779733661637539395458142568447)
+		_ = float32(340282356779733661637539395458142568448 /* ERROR cannot convert */ )
+	)
+}
+
+// Check that a missing identifier doesn't lead to a spurious error cascade.
+func issue8799a() {
+	x, ok := missing /* ERROR undeclared */ ()
+	_ = !ok
+	_ = x
+}
+
+func issue8799b(x int, ok bool) {
+	x, ok = missing /* ERROR undeclared */ ()
+	_ = !ok
+	_ = x
+}
+
+func issue9182() {
+	type Point C /* ERROR undeclared */ .Point
+	// no error for composite literal based on unknown type
+	_ = Point{x: 1, y: 2}
+}
+
+func f0() (a []int)         { return }
+func f1() (a []int, b int)  { return }
+func f2() (a, b []int)      { return }
+
+func append_([]int, ...int) {}
+
+func issue9473(a []int, b ...int) {
+	// variadic builtin function
+	_ = append(f0())
+	_ = append(f0(), f0()...)
+	_ = append(f1())
+	_ = append(f2 /* ERROR cannot use .* in argument */ ())
+	_ = append(f2()... /* ERROR cannot use ... */ )
+	_ = append(f0(), f1 /* ERROR 2-valued f1 */ ())
+	_ = append(f0(), f2 /* ERROR 2-valued f2 */ ())
+	_ = append(f0(), f1 /* ERROR 2-valued f1 */ ()...)
+	_ = append(f0(), f2 /* ERROR 2-valued f2 */ ()...)
+
+	// variadic user-defined function
+	append_(f0())
+	append_(f0(), f0()...)
+	append_(f1())
+	append_(f2 /* ERROR cannot use .* in argument */ ())
+	append_(f2()... /* ERROR cannot use ... */ )
+	append_(f0(), f1 /* ERROR 2-valued f1 */ ())
+	append_(f0(), f2 /* ERROR 2-valued f2 */ ())
+	append_(f0(), f1 /* ERROR 2-valued f1 */ ()...)
+	append_(f0(), f2 /* ERROR 2-valued f2 */ ()...)
+}
+
+// Check that embedding a non-interface type in an interface results in a good error message.
+func issue10979() {
+	type _ interface {
+		int /* ERROR int is not an interface */
+	}
+	type T struct{}
+	type _ interface {
+		T /* ERROR T is not an interface */
+	}
+	type _ interface {
+		nosuchtype /* ERROR undeclared name: nosuchtype */
+	}
+	type _ interface {
+		fmt.Nosuchtype /* ERROR Nosuchtype not declared by package fmt */
+	}
+	type _ interface {
+		nosuchpkg /* ERROR undeclared name: nosuchpkg */ .Nosuchtype
+	}
+	type I interface {
+		I.m /* ERROR no field or method m */
+		m()
+	}
+}
+
+// issue11347
+// These should not crash.
+var a1, b1 /* ERROR cycle */ , c1 /* ERROR cycle */ b1 = 0 > 0<<""[""[c1]]>c1
+var a2, b2 /* ERROR cycle */ = 0 /* ERROR cannot initialize */ /* ERROR cannot initialize */ > 0<<""[b2]
+var a3, b3 /* ERROR cycle */ = int /* ERROR cannot initialize */ /* ERROR cannot initialize */ (1<<""[b3])
+
+// issue10260
+// Check that error messages explain reason for interface assignment failures.
+type (
+	I0 interface{}
+	I1 interface{ foo() }
+	I2 interface{ foo(x int) }
+	T0 struct{}
+	T1 struct{}
+	T2 struct{}
+)
+
+func (*T1) foo() {}
+func (*T2) foo(x int) {}
+
+func issue10260() {
+	var (
+		i0 I0
+		i1 I1
+		i2 I2
+		t0 *T0
+		t1 *T1
+		t2 *T2
+	)
+
+	var x I1
+	x = T1 /* ERROR cannot use .*: missing method foo \(foo has pointer receiver\) */ {}
+	_ = x /* ERROR .* cannot have dynamic type T1 \(missing method foo \(foo has pointer receiver\)\) */ .(T1)
+
+	T1{}.foo /* ERROR cannot call pointer method foo on T1 */ ()
+	x.Foo /* ERROR "x.Foo undefined \(type I1 has no field or method Foo, but does have foo\)" */ ()
+
+	_ = i2 /* ERROR i2 .* cannot have dynamic type \*T1 \(wrong type for method foo \(have func\(\), want func\(x int\)\)\) */ .(*T1)
+
+	i1 = i0 /* ERROR cannot use .* missing method foo */
+	i1 = t0 /* ERROR cannot use .* missing method foo */
+	i1 = i2 /* ERROR cannot use .* wrong type for method foo */
+	i1 = t2 /* ERROR cannot use .* wrong type for method foo */
+	i2 = i1 /* ERROR cannot use .* wrong type for method foo */
+	i2 = t1 /* ERROR cannot use .* wrong type for method foo */
+
+	_ = func() I1 { return i0 /* ERROR cannot use .* missing method foo */ }
+	_ = func() I1 { return t0 /* ERROR cannot use .* missing method foo */ }
+	_ = func() I1 { return i2 /* ERROR cannot use .* wrong type for method foo */ }
+	_ = func() I1 { return t2 /* ERROR cannot use .* wrong type for method foo */ }
+	_ = func() I2 { return i1 /* ERROR cannot use .* wrong type for method foo */ }
+	_ = func() I2 { return t1 /* ERROR cannot use .* wrong type for method foo */ }
+
+	// a few more - less exhaustive now
+
+	f := func(I1, I2){}
+	f(i0 /* ERROR cannot use .* missing method foo */ , i1 /* ERROR cannot use .* wrong type for method foo \(have func\(\), want func\(x int\)\) */ )
+
+	_ = [...]I1{i0 /* ERROR cannot use .* missing method foo */ }
+	_ = [...]I1{i2 /* ERROR cannot use .* wrong type for method foo */ }
+	_ = []I1{i0 /* ERROR cannot use .* missing method foo */ }
+	_ = []I1{i2 /* ERROR cannot use .* wrong type for method foo */ }
+	_ = map[int]I1{0: i0 /* ERROR cannot use .* missing method foo */ }
+	_ = map[int]I1{0: i2 /* ERROR cannot use .* wrong type for method foo */ }
+
+	make(chan I1) <- i0 /* ERROR cannot use .* in send: missing method foo */
+	make(chan I1) <- i2 /* ERROR cannot use .* in send: wrong type for method foo */
+}
+
+// Check that constants representable as integers are in integer form
+// before being used in operations that are only defined on integers.
+func issue14229() {
+	// from the issue
+	const _ = int64(-1<<63) % 1e6
+
+	// related
+	const (
+		a int = 3
+		b = 4.0
+		_ = a / b
+		_ = a % b
+		_ = b / a
+		_ = b % a
+	)
+}
+
+// Check that in a n:1 variable declaration with type and initialization
+// expression the type is distributed to all variables of the lhs before
+// the initialization expression assignment is checked.
+func issue15755() {
+	// from issue
+	var i interface{}
+	type b bool
+	var x, y b = i.(b)
+	_ = x == y
+
+	// related: we should see an error since the result of f1 is ([]int, int)
+	var u, v []int = f1 /* ERROR cannot use f1 */ ()
+	_ = u
+	_ = v
+}
+
+// Test that we don't get "declared but not used"
+// errors in the context of invalid/C objects.
+func issue20358() {
+	var F C /* ERROR "undeclared" */ .F
+	var A C /* ERROR "undeclared" */ .A
+	var S C /* ERROR "undeclared" */ .S
+	type T C /* ERROR "undeclared" */ .T
+	type P C /* ERROR "undeclared" */ .P
+
+	// these variables must be "used" even though
+	// the LHS expressions/types below in which
+	// context they are used are unknown/invalid
+	var f, a, s1, s2, s3, t, p int
+
+	_ = F(f)
+	_ = A[a]
+	_ = S[s1:s2:s3]
+	_ = T{t}
+	_ = P{f: p}
+}
+
+// Test that we don't declare lhs variables in short variable
+// declarations before we type-check function literals on the
+// rhs.
+func issue24026() {
+	f := func() int { f(0) /* must refer to outer f */; return 0 }
+	_ = f
+
+	_ = func() {
+		f := func() { _ = f() /* must refer to outer f */ }
+		_ = f
+	}
+
+	// b and c must not be visible inside function literal
+	a := 0
+	a, b, c := func() (int, int, int) {
+		return a, b /* ERROR undeclared */ , c /* ERROR undeclared */
+	}()
+	_, _ = b, c
+}
+
+func f(int) {} // for issue24026
+
+// Test that we don't report a "missing return statement" error
+// (due to incorrect context when type-checking interfaces).
+func issue24140(x interface{}) int {
+        switch x.(type) {
+        case interface{}:
+                return 0
+        default:
+                panic(0)
+        }
+}
+
+// Test that we don't crash when the 'if' condition is missing.
+func issue25438() {
+	if { /* ERROR missing condition */ }
+	if x := 0; /* ERROR missing condition */ { _ = x }
+	if
+	{ /* ERROR missing condition */ }
+}
+
+// Test that we can embed alias type names in interfaces.
+type issue25301 interface {
+	E
+}
+
+type E = interface {
+	m()
+}
+
+// Test case from issue.
+// cmd/compile reports a cycle as well.
+type issue25301b /* ERROR cycle */ = interface {
+	m() interface{ issue25301b }
+}
+
+type issue25301c interface {
+	notE // ERROR struct\{\} is not an interface
+}
+
+type notE = struct{}
+
+// Test that method declarations don't introduce artificial cycles
+// (issue #26124).
+const CC TT = 1
+type TT int
+func (TT) MM() [CC]TT
+
+// Reduced test case from issue #26124.
+const preloadLimit LNumber = 128
+type LNumber float64
+func (LNumber) assertFunction() *LFunction
+type LFunction struct {
+	GFunction LGFunction
+}
+type LGFunction func(*LState)
+type LState struct {
+	reg *registry
+}
+type registry struct {
+	alloc *allocator
+}
+type allocator struct {
+	_ [int(preloadLimit)]int
+}
+
+// Test that we don't crash when type-checking composite literals
+// containing errors in the type.
+var issue27346 = [][n /* ERROR undeclared */ ]int{
+	0: {},
+}
+
+var issue22467 = map[int][... /* ERROR invalid use of ... */ ]int{0: {}}
+
+// Test that invalid use of ... in parameter lists is recognized
+// (issue #28281).
+func issue28281a(int, int, ...int)
+func issue28281b(a, b int, c ...int)
+func issue28281c(a, b, c ... /* ERROR can only use ... with final parameter */ int)
+func issue28281d(... /* ERROR can only use ... with final parameter */ int, int)
+func issue28281e(a, b, c  ... /* ERROR can only use ... with final parameter */ int, d int)
+func issue28281f(... /* ERROR can only use ... with final parameter */ int, ... /* ERROR can only use ... with final parameter */ int, int)
+func (... /* ERROR can only use ... with final parameter in list */ TT) f()
+func issue28281g() (... /* ERROR can only use ... with final parameter in list */ TT)
+
+// Issue #26234: Make various field/method lookup errors easier to read by matching cmd/compile's output
+func issue26234a(f *syn.File) {
+	// The error message below should refer to the actual package name (syntax)
+	// not the local package name (syn).
+	f.foo /* ERROR f.foo undefined \(type \*syntax.File has no field or method foo\) */
+}
+
+type T struct {
+	x int
+	E1
+	E2
+}
+
+type E1 struct{ f int }
+type E2 struct{ f int }
+
+func issue26234b(x T) {
+	_ = x.f /* ERROR ambiguous selector x.f */
+}
+
+func issue26234c() {
+	T.x /* ERROR T.x undefined \(type T has no method x\) */ ()
+}
+
+func issue35895() {
+	// T is defined in this package, don't qualify its name with the package name.
+	var _ T = 0 // ERROR cannot use 0 \(untyped int constant\) as T
+
+	// There is only one package with name syntax imported, only use the (global) package name in error messages.
+	var _ *syn.File = 0 // ERROR cannot use 0 \(untyped int constant\) as \*syntax.File
+
+	// Because both t1 and t2 have the same global package name (template),
+	// qualify packages with full path name in this case.
+	var _ t1.Template = t2 /* ERROR cannot use .* \(value of type "html/template".Template\) as "text/template".Template */ .Template{}
+}
+
+func issue42989(s uint) {
+	var m map[int]string
+	delete(m, 1<<s)
+	delete(m, 1.<<s)
+}
diff --git a/src/go/types/testdata/labels.src b/src/cmd/compile/internal/types2/testdata/check/labels.src
similarity index 100%
copy from src/go/types/testdata/labels.src
copy to src/cmd/compile/internal/types2/testdata/check/labels.src
diff --git a/src/cmd/compile/internal/types2/testdata/check/linalg.go2 b/src/cmd/compile/internal/types2/testdata/check/linalg.go2
new file mode 100644
index 0000000..0d27603
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/linalg.go2
@@ -0,0 +1,83 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package linalg
+
+import "math"
+
+// Numeric is type bound that matches any numeric type.
+// It would likely be in a constraints package in the standard library.
+type Numeric interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64,
+		complex64, complex128
+}
+
+func DotProduct[T Numeric](s1, s2 []T) T {
+	if len(s1) != len(s2) {
+		panic("DotProduct: slices of unequal length")
+	}
+	var r T
+	for i := range s1 {
+		r += s1[i] * s2[i]
+	}
+	return r
+}
+
+// NumericAbs matches numeric types with an Abs method.
+type NumericAbs[T any] interface {
+	Numeric
+
+	Abs() T
+}
+
+// AbsDifference computes the absolute value of the difference of
+// a and b, where the absolute value is determined by the Abs method.
+func AbsDifference[T NumericAbs[T]](a, b T) T {
+	d := a - b
+	return d.Abs()
+}
+
+// OrderedNumeric is a type bound that matches numeric types that support the < operator.
+type OrderedNumeric interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64
+}
+
+// Complex is a type bound that matches the two complex types, which do not have a < operator.
+type Complex interface {
+	type complex64, complex128
+}
+
+// OrderedAbs is a helper type that defines an Abs method for
+// ordered numeric types.
+type OrderedAbs[T OrderedNumeric] T
+
+func (a OrderedAbs[T]) Abs() OrderedAbs[T] {
+	if a < 0 {
+		return -a
+	}
+	return a
+}
+
+// ComplexAbs is a helper type that defines an Abs method for
+// complex types.
+type ComplexAbs[T Complex] T
+
+func (a ComplexAbs[T]) Abs() ComplexAbs[T] {
+	r := float64(real(a))
+	i := float64(imag(a))
+	d := math.Sqrt(r * r + i * i)
+	return ComplexAbs[T](complex(d, 0))
+}
+
+func OrderedAbsDifference[T OrderedNumeric](a, b T) T {
+	return T(AbsDifference(OrderedAbs[T](a), OrderedAbs[T](b)))
+}
+
+func ComplexAbsDifference[T Complex](a, b T) T {
+	return T(AbsDifference(ComplexAbs[T](a), ComplexAbs[T](b)))
+}
diff --git a/src/go/types/testdata/literals.src b/src/cmd/compile/internal/types2/testdata/check/literals.src
similarity index 100%
copy from src/go/types/testdata/literals.src
copy to src/cmd/compile/internal/types2/testdata/check/literals.src
diff --git a/src/cmd/compile/internal/types2/testdata/check/main.go2 b/src/cmd/compile/internal/types2/testdata/check/main.go2
new file mode 100644
index 0000000..b7ddeaa
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/main.go2
@@ -0,0 +1,7 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func /* ERROR "func main must have no type parameters" */ main[T any]() {}
diff --git a/src/cmd/compile/internal/types2/testdata/check/main.src b/src/cmd/compile/internal/types2/testdata/check/main.src
new file mode 100644
index 0000000..f892938
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/main.src
@@ -0,0 +1,9 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main()
+func /* ERROR "no arguments and no return values" */ main /* ERROR redeclared */ (int)
+func /* ERROR "no arguments and no return values" */ main /* ERROR redeclared */ () int
diff --git a/src/cmd/compile/internal/types2/testdata/check/map.go2 b/src/cmd/compile/internal/types2/testdata/check/map.go2
new file mode 100644
index 0000000..814d953
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/map.go2
@@ -0,0 +1,113 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package orderedmap provides an ordered map, implemented as a binary tree.
+package orderedmap
+
+// TODO(gri) fix imports for tests
+import "chans" // ERROR could not import
+
+// Map is an ordered map.
+type Map[K, V any] struct {
+	root    *node[K, V]
+	compare func(K, K) int
+}
+
+// node is the type of a node in the binary tree.
+type node[K, V any] struct {
+	key         K
+	val         V
+	left, right *node[K, V]
+}
+
+// New returns a new map.
+func New[K, V any](compare func(K, K) int) *Map[K, V] {
+        return &Map[K, V]{compare: compare}
+}
+
+// find looks up key in the map, and returns either a pointer
+// to the node holding key, or a pointer to the location where
+// such a node would go.
+func (m *Map[K, V]) find(key K) **node[K, V] {
+	pn := &m.root
+	for *pn != nil {
+		switch cmp := m.compare(key, (*pn).key); {
+		case cmp < 0:
+			pn = &(*pn).left
+		case cmp > 0:
+			pn = &(*pn).right
+		default:
+			return pn
+		}
+	}
+	return pn
+}
+
+// Insert inserts a new key/value into the map.
+// If the key is already present, the value is replaced.
+// Returns true if this is a new key, false if already present.
+func (m *Map[K, V]) Insert(key K, val V) bool {
+	pn := m.find(key)
+	if *pn != nil {
+		(*pn).val = val
+		return false
+	}
+        *pn = &node[K, V]{key: key, val: val}
+	return true
+}
+
+// Find returns the value associated with a key, or zero if not present.
+// The found result reports whether the key was found.
+func (m *Map[K, V]) Find(key K) (V, bool) {
+	pn := m.find(key)
+	if *pn == nil {
+		var zero V // see the discussion of zero values, above
+		return zero, false
+	}
+	return (*pn).val, true
+}
+
+// keyValue is a pair of key and value used when iterating.
+type keyValue[K, V any] struct {
+	key K
+	val V
+}
+
+// InOrder returns an iterator that does an in-order traversal of the map.
+func (m *Map[K, V]) InOrder() *Iterator[K, V] {
+	sender, receiver := chans.Ranger[keyValue[K, V]]()
+	var f func(*node[K, V]) bool
+	f = func(n *node[K, V]) bool {
+		if n == nil {
+			return true
+		}
+		// Stop sending values if sender.Send returns false,
+		// meaning that nothing is listening at the receiver end.
+		return f(n.left) &&
+                        sender.Send(keyValue[K, V]{n.key, n.val}) &&
+			f(n.right)
+	}
+	go func() {
+		f(m.root)
+		sender.Close()
+	}()
+	return &Iterator[K, V]{receiver}
+}
+
+// Iterator is used to iterate over the map.
+type Iterator[K, V any] struct {
+	r *chans.Receiver[keyValue[K, V]]
+}
+
+// Next returns the next key and value pair, and a boolean indicating
+// whether they are valid or whether we have reached the end.
+func (it *Iterator[K, V]) Next() (K, V, bool) {
+	keyval, ok := it.r.Next()
+	if !ok {
+		var zerok K
+		var zerov V
+		return zerok, zerov, false
+	}
+	return keyval.key, keyval.val, true
+}
diff --git a/src/cmd/compile/internal/types2/testdata/check/map2.go2 b/src/cmd/compile/internal/types2/testdata/check/map2.go2
new file mode 100644
index 0000000..2833445
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/map2.go2
@@ -0,0 +1,146 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is like map.go2, but instead if importing chans, it contains
+// the necessary functionality at the end of the file.
+
+// Package orderedmap provides an ordered map, implemented as a binary tree.
+package orderedmap
+
+// Map is an ordered map.
+type Map[K, V any] struct {
+	root    *node[K, V]
+	compare func(K, K) int
+}
+
+// node is the type of a node in the binary tree.
+type node[K, V any] struct {
+	key         K
+	val         V
+	left, right *node[K, V]
+}
+
+// New returns a new map.
+func New[K, V any](compare func(K, K) int) *Map[K, V] {
+        return &Map[K, V]{compare: compare}
+}
+
+// find looks up key in the map, and returns either a pointer
+// to the node holding key, or a pointer to the location where
+// such a node would go.
+func (m *Map[K, V]) find(key K) **node[K, V] {
+	pn := &m.root
+	for *pn != nil {
+		switch cmp := m.compare(key, (*pn).key); {
+		case cmp < 0:
+			pn = &(*pn).left
+		case cmp > 0:
+			pn = &(*pn).right
+		default:
+			return pn
+		}
+	}
+	return pn
+}
+
+// Insert inserts a new key/value into the map.
+// If the key is already present, the value is replaced.
+// Returns true if this is a new key, false if already present.
+func (m *Map[K, V]) Insert(key K, val V) bool {
+	pn := m.find(key)
+	if *pn != nil {
+		(*pn).val = val
+		return false
+	}
+	*pn = &node[K, V]{key: key, val: val}
+	return true
+}
+
+// Find returns the value associated with a key, or zero if not present.
+// The found result reports whether the key was found.
+func (m *Map[K, V]) Find(key K) (V, bool) {
+	pn := m.find(key)
+	if *pn == nil {
+		var zero V // see the discussion of zero values, above
+		return zero, false
+	}
+	return (*pn).val, true
+}
+
+// keyValue is a pair of key and value used when iterating.
+type keyValue[K, V any] struct {
+	key K
+	val V
+}
+
+// InOrder returns an iterator that does an in-order traversal of the map.
+func (m *Map[K, V]) InOrder() *Iterator[K, V] {
+	sender, receiver := chans_Ranger[keyValue[K, V]]()
+	var f func(*node[K, V]) bool
+	f = func(n *node[K, V]) bool {
+		if n == nil {
+			return true
+		}
+		// Stop sending values if sender.Send returns false,
+		// meaning that nothing is listening at the receiver end.
+		return f(n.left) &&
+                        sender.Send(keyValue[K, V]{n.key, n.val}) &&
+			f(n.right)
+	}
+	go func() {
+		f(m.root)
+		sender.Close()
+	}()
+	return &Iterator[K, V]{receiver}
+}
+
+// Iterator is used to iterate over the map.
+type Iterator[K, V any] struct {
+	r *chans_Receiver[keyValue[K, V]]
+}
+
+// Next returns the next key and value pair, and a boolean indicating
+// whether they are valid or whether we have reached the end.
+func (it *Iterator[K, V]) Next() (K, V, bool) {
+	keyval, ok := it.r.Next()
+	if !ok {
+		var zerok K
+		var zerov V
+		return zerok, zerov, false
+	}
+	return keyval.key, keyval.val, true
+}
+
+// chans
+
+func chans_Ranger[T any]() (*chans_Sender[T], *chans_Receiver[T])
+
+// A sender is used to send values to a Receiver.
+type chans_Sender[T any] struct {
+	values chan<- T
+	done <-chan bool
+}
+
+func (s *chans_Sender[T]) Send(v T) bool {
+	select {
+	case s.values <- v:
+		return true
+	case <-s.done:
+		return false
+	}
+}
+
+func (s *chans_Sender[T]) Close() {
+	close(s.values)
+}
+
+type chans_Receiver[T any] struct {
+	values <-chan T
+	done chan<- bool
+}
+
+func (r *chans_Receiver[T]) Next() (T, bool) {
+	v, ok := <-r.values
+	return v, ok
+}
\ No newline at end of file
diff --git a/src/go/types/testdata/methodsets.src b/src/cmd/compile/internal/types2/testdata/check/methodsets.src
similarity index 100%
copy from src/go/types/testdata/methodsets.src
copy to src/cmd/compile/internal/types2/testdata/check/methodsets.src
diff --git a/src/cmd/compile/internal/types2/testdata/check/mtypeparams.go2 b/src/cmd/compile/internal/types2/testdata/check/mtypeparams.go2
new file mode 100644
index 0000000..c2f282b
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/mtypeparams.go2
@@ -0,0 +1,52 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// If types2.Config.AcceptMethodTypeParams is set,
+// the type checker accepts methods that have their
+// own type parameter list.
+
+package p
+
+type S struct{}
+
+func (S) m[T any](v T)
+
+// TODO(gri) Once we collect interface method type parameters
+//           in the parser, we can enable these tests again.
+/*
+type I interface {
+   m[T any](v T)
+}
+
+type J interface {
+   m[T any](v T)
+}
+
+var _ I = S{}
+var _ I = J(nil)
+
+type C interface{ n() }
+
+type Sc struct{}
+
+func (Sc) m[T C](v T)
+
+type Ic interface {
+   m[T C](v T)
+}
+
+type Jc interface {
+   m[T C](v T)
+}
+
+var _ Ic = Sc{}
+var _ Ic = Jc(nil)
+
+// TODO(gri) These should fail because the constraints don't match.
+var _ I = Sc{}
+var _ I = Jc(nil)
+
+var _ Ic = S{}
+var _ Ic = J(nil)
+*/
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/check/shifts.src b/src/cmd/compile/internal/types2/testdata/check/shifts.src
new file mode 100644
index 0000000..60db731
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/shifts.src
@@ -0,0 +1,398 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package shifts
+
+func shifts0() {
+	// basic constant shifts
+	const (
+		s = 10
+		_ = 0<<0
+		_ = 1<<s
+		_ = 1<<- /* ERROR "negative shift count" */ 1
+		// For the test below we may decide to convert to int
+		// rather than uint and then report a negative shift
+		// count instead, which might be a better error. The
+		// (minor) difference is that this would restrict the
+		// shift count range by half (from all uint values to
+		// the positive int values).
+		// This depends on the exact spec wording which is not
+		// done yet.
+		// TODO(gri) revisit and adjust when spec change is done
+		_ = 1<<- /* ERROR "negative shift count" */ 1.0
+		_ = 1<<1075 /* ERROR "invalid shift" */
+		_ = 2.0<<1
+		_ = 1<<1.0
+		_ = 1<<(1+0i)
+
+		_ int = 2<<s
+		_ float32 = 2<<s
+		_ complex64 = 2<<s
+
+		_ int = 2.0<<s
+		_ float32 = 2.0<<s
+		_ complex64 = 2.0<<s
+
+		_ int = 'a'<<s
+		_ float32 = 'a'<<s
+		_ complex64 = 'a'<<s
+	)
+}
+
+func shifts1() {
+	// basic non-constant shifts
+	var (
+		i int
+		u uint
+
+		_ = 1<<0
+		_ = 1<<i
+		_ = 1<<u
+		_ = 1<<"foo" /* ERROR "cannot convert" */
+		_ = i<<0
+		_ = i<<- /* ERROR "negative shift count" */ 1
+		_ = i<<1.0
+		_ = 1<<(1+0i)
+		_ = 1 /* ERROR "overflows" */ <<100
+
+		_ uint = 1 << 0
+		_ uint = 1 << u
+		_ float32 = 1 /* ERROR "must be integer" */ << u
+
+		// issue #14822
+		_ = 1<<( /* ERROR "overflows uint" */ 1<<64)
+		_ = 1<<( /* ERROR "invalid shift count" */ 1<<64-1)
+
+		// issue #43697
+		_ = u<<( /* ERROR "overflows uint" */ 1<<64)
+		_ = u<<(1<<64-1)
+	)
+}
+
+func shifts2() {
+	// from the spec
+	var (
+		s uint = 33
+		i = 1<<s           // 1 has type int
+		j int32 = 1<<s     // 1 has type int32; j == 0
+		k = uint64(1<<s)   // 1 has type uint64; k == 1<<33
+		m int = 1.0<<s     // 1.0 has type int
+		n = 1.0<<s != i    // 1.0 has type int; n == false if ints are 32bits in size
+		o = 1<<s == 2<<s   // 1 and 2 have type int; o == true if ints are 32bits in size
+		p = 1<<s == 1<<33  // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int
+		u = 1.0 /* ERROR "must be integer" */ <<s         // illegal: 1.0 has type float64, cannot shift
+		u1 = 1.0 /* ERROR "must be integer" */ <<s != 0   // illegal: 1.0 has type float64, cannot shift
+		u2 = 1 /* ERROR "must be integer" */ <<s != 1.0   // illegal: 1 has type float64, cannot shift
+		v float32 = 1 /* ERROR "must be integer" */ <<s   // illegal: 1 has type float32, cannot shift
+		w int64 = 1.0<<33  // 1.0<<33 is a constant shift expression
+	)
+	_, _, _, _, _, _, _, _, _, _, _, _ = i, j, k, m, n, o, p, u, u1, u2, v, w
+}
+
+func shifts3(a int16, b float32) {
+	// random tests
+	var (
+		s uint = 11
+		u = 1 /* ERROR "must be integer" */ <<s + 1.0
+		v complex128 = 1 /* ERROR "must be integer" */ << s + 1.0 /* ERROR "must be integer" */ << s + 1
+	)
+	x := 1.0 /* ERROR "must be integer" */ <<s + 1
+	shifts3(1.0 << s, 1 /* ERROR "must be integer" */ >> s)
+	_, _, _ = u, v, x
+}
+
+func shifts4() {
+	// shifts in comparisons w/ untyped operands
+	var s uint
+
+	_ = 1<<s == 1
+	_ = 1 /* ERROR "integer" */ <<s == 1.
+	_ = 1. /* ERROR "integer" */ <<s == 1
+	_ = 1. /* ERROR "integer" */ <<s == 1.
+
+	_ = 1<<s + 1 == 1
+	_ = 1 /* ERROR "integer" */ <<s + 1 == 1.
+	_ = 1 /* ERROR "integer" */ <<s + 1. == 1
+	_ = 1 /* ERROR "integer" */ <<s + 1. == 1.
+	_ = 1. /* ERROR "integer" */ <<s + 1 == 1
+	_ = 1. /* ERROR "integer" */ <<s + 1 == 1.
+	_ = 1. /* ERROR "integer" */ <<s + 1. == 1
+	_ = 1. /* ERROR "integer" */ <<s + 1. == 1.
+
+	_ = 1<<s == 1<<s
+	_ = 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s
+
+	_ = 1<<s + 1<<s == 1
+	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1.
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1.
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1.
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1.
+
+	_ = 1<<s + 1<<s == 1<<s + 1<<s
+	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+}
+
+func shifts5() {
+	// shifts in comparisons w/ typed operands
+	var s uint
+	var x int
+
+	_ = 1<<s == x
+	_ = 1.<<s == x
+	_ = 1.1 /* ERROR "int" */ <<s == x
+
+	_ = 1<<s + x == 1
+	_ = 1<<s + x == 1.
+	_ = 1<<s + x == 1.1 /* ERROR "int" */
+	_ = 1.<<s + x == 1
+	_ = 1.<<s + x == 1.
+	_ = 1.<<s + x == 1.1 /* ERROR "int" */
+	_ = 1.1 /* ERROR "int" */ <<s + x == 1
+	_ = 1.1 /* ERROR "int" */ <<s + x == 1.
+	_ = 1.1 /* ERROR "int" */ <<s + x == 1.1
+
+	_ = 1<<s == x<<s
+	_ = 1.<<s == x<<s
+	_ = 1.1  /* ERROR "int" */ <<s == x<<s
+}
+
+func shifts6() {
+	// shifts as operands in non-arithmetic operations and as arguments
+	var a [10]int
+	var s uint
+
+	_ = a[1<<s]
+	_ = a[1.0]
+	_ = a[1.0<<s]
+
+	_ = make([]int, 1.0)
+	_ = make([]int, 1.0<<s)
+	_ = make([]int, 1.1 /* ERROR "must be integer" */ <<s)
+
+	_ = float32(1)
+	_ = float32(1 /* ERROR "must be integer" */ <<s)
+	_ = float32(1.0)
+	_ = float32(1.0 /* ERROR "must be integer" */ <<s)
+	_ = float32(1.1 /* ERROR "must be integer" */ <<s)
+
+	// TODO(gri) port fixes from go/types
+	// _ = int32(0x80000000 /* ERROR "overflows int32" */ << s)
+	// TODO(rfindley) Eliminate the redundant error here.
+	// _ = int32(( /* ERROR "truncated to int32" */ 0x80000000 /* ERROR "truncated to int32" */ + 0i) << s)
+
+	_ = int(1+0i<<0)
+	// _ = int((1+0i)<<s)
+	// _ = int(1.0<<s)
+	// _ = int(complex(1, 0)<<s)
+	_ = int(float32/* ERROR "must be integer" */(1.0) <<s)
+	_ = int(1.1 /* ERROR must be integer */ <<s)
+	_ = int(( /* ERROR "must be integer" */ 1+1i)  <<s)
+
+	_ = complex(1 /* ERROR "must be integer" */ <<s, 0)
+
+	var b []int
+	_ = append(b, 1<<s)
+	_ = append(b, 1.0<<s)
+	_ = append(b, (1+0i)<<s)
+	_ = append(b, 1.1 /* ERROR "must be integer" */ <<s)
+	_ = append(b, (1 + 0i) <<s)
+	_ = append(b, ( /* ERROR "must be integer" */ 1 + 1i)  <<s)
+
+	_ = complex(1.0 /* ERROR "must be integer" */ <<s, 0)
+	_ = complex(1.1 /* ERROR "must be integer" */ <<s, 0)
+	_ = complex(0, 1.0 /* ERROR "must be integer" */ <<s)
+	_ = complex(0, 1.1 /* ERROR "must be integer" */ <<s)
+
+	// TODO(gri) The delete below is not type-checked correctly yet.
+	// var m1 map[int]string
+	// delete(m1, 1<<s)
+}
+
+func shifts7() {
+	// shifts of shifts
+	var s uint
+	var x int
+	_ = x
+
+	_ = 1<<(1<<s)
+	_ = 1<<(1.<<s)
+	_ = 1. /* ERROR "integer" */ <<(1<<s)
+	_ = 1. /* ERROR "integer" */ <<(1.<<s)
+
+	x = 1<<(1<<s)
+	x = 1<<(1.<<s)
+	x = 1.<<(1<<s)
+	x = 1.<<(1.<<s)
+
+	_ = (1<<s)<<(1<<s)
+	_ = (1<<s)<<(1.<<s)
+	_ = ( /* ERROR "integer" */ 1.<<s)<<(1<<s)
+	_ = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s)
+
+	x = (1<<s)<<(1<<s)
+	x = (1<<s)<<(1.<<s)
+	x = ( /* ERROR "integer" */ 1.<<s)<<(1<<s)
+	x = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s)
+}
+
+func shifts8() {
+	// shift examples from shift discussion: better error messages
+	var s uint
+	_ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1
+	_ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1.0
+	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s == 1.0
+	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.0 == 1
+	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.1 == 1
+	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1 == 1.0
+
+	// additional cases
+	_ = complex(1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s, 1)
+	_ = complex(1.0, 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s)
+
+	_ = int(1.<<s)
+	_ = int(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
+	_ = float32(1 /* ERROR "shifted operand .* must be integer" */ <<s)
+	_ = float32(1. /* ERROR "shifted operand .* must be integer" */ <<s)
+	_ = float32(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
+	// TODO(gri) the error messages for these two are incorrect - disabled for now
+	// _ = complex64(1<<s)
+	// _ = complex64(1.<<s)
+	_ = complex64(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
+}
+
+func shifts9() {
+	// various originally failing snippets of code from the std library
+	// from src/compress/lzw/reader.go:90
+	{
+		var d struct {
+			bits     uint32
+			width    uint
+		}
+		_ = uint16(d.bits & (1<<d.width - 1))
+	}
+
+	// from src/debug/dwarf/buf.go:116
+	{
+		var ux uint64
+		var bits uint
+		x := int64(ux)
+		if x&(1<<(bits-1)) != 0 {}
+	}
+
+	// from src/encoding/asn1/asn1.go:160
+	{
+		var bytes []byte
+		if bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {}
+	}
+
+	// from src/math/big/rat.go:140
+	{
+		var exp int
+		var mantissa uint64
+		shift := uint64(-1022 - (exp - 1)) // [1..53)
+		_ = mantissa & (1<<shift - 1)
+	}
+
+	// from src/net/interface.go:51
+	{
+		type Flags uint
+		var f Flags
+		var i int
+		if f&(1<<uint(i)) != 0 {}
+	}
+
+	// from src/runtime/softfloat64.go:234
+	{
+		var gm uint64
+		var shift uint
+		_ = gm & (1<<shift - 1)
+	}
+
+	// from src/strconv/atof.go:326
+	{
+		var mant uint64
+		var mantbits uint
+		if mant == 2<<mantbits {}
+	}
+
+	// from src/route_bsd.go:82
+	{
+		var Addrs int32
+		const rtaRtMask = 1
+		var i uint
+		if Addrs&rtaRtMask&(1<<i) == 0 {}
+	}
+
+	// from src/text/scanner/scanner.go:540
+	{
+		var s struct { Whitespace uint64 }
+		var ch rune
+		for s.Whitespace&(1<<uint(ch)) != 0 {}
+	}
+}
+
+func issue5895() {
+	var x = 'a' << 1 // type of x must be rune
+	var _ rune = x
+}
+
+func issue11325() {
+	var _ = 0 >> 1.1 /* ERROR "truncated to uint" */ // example from issue 11325
+	_ = 0 >> 1.1 /* ERROR "truncated to uint" */
+	_ = 0 << 1.1 /* ERROR "truncated to uint" */
+	_ = 0 >> 1.
+	_ = 1 >> 1.1 /* ERROR "truncated to uint" */
+	_ = 1 >> 1.
+	_ = 1. >> 1
+	_ = 1. >> 1.
+	_ = 1.1 /* ERROR "must be integer" */ >> 1
+}
+
+func issue11594() {
+	var _ = complex64 /* ERROR "must be integer" */ (1) << 2 // example from issue 11594
+	_ = float32 /* ERROR "must be integer" */ (0) << 1
+	_ = float64 /* ERROR "must be integer" */ (0) >> 2
+	_ = complex64 /* ERROR "must be integer" */ (0) << 3
+	_ = complex64 /* ERROR "must be integer" */ (0) >> 4
+}
+
+func issue21727() {
+	var s uint
+	var a = make([]int, 1<<s + 1.2 /* ERROR "truncated to int" */ )
+	var _ = a[1<<s - 2.3 /* ERROR "truncated to int" */ ]
+	var _ int = 1<<s + 3.4 /* ERROR "truncated to int" */
+	var _ = string(1 << s)
+	var _ = string(1.0 /* ERROR "cannot convert" */ << s)
+}
+
+func issue22969() {
+	var s uint
+	var a []byte
+	_ = a[0xffffffffffffffff /* ERROR "overflows int" */ <<s] // example from issue 22969
+	_ = make([]int, 0xffffffffffffffff /* ERROR "overflows int" */ << s)
+	_ = make([]int, 0, 0xffffffffffffffff /* ERROR "overflows int" */ << s)
+	var _ byte = 0x100 /* ERROR "overflows byte" */ << s
+	var _ int8 = 0xff /* ERROR "overflows int8" */ << s
+	var _ int16 = 0xffff /* ERROR "overflows int16" */ << s
+	var _ int32 = 0x80000000 /* ERROR "overflows int32" */ << s
+}
diff --git a/src/cmd/compile/internal/types2/testdata/check/slices.go2 b/src/cmd/compile/internal/types2/testdata/check/slices.go2
new file mode 100644
index 0000000..2bacd1c
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/slices.go2
@@ -0,0 +1,68 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package slices implements various slice algorithms.
+package slices
+
+// Map turns a []T1 to a []T2 using a mapping function.
+func Map[T1, T2 any](s []T1, f func(T1) T2) []T2 {
+	r := make([]T2, len(s))
+	for i, v := range s {
+		r[i] = f(v)
+	}
+	return r
+}
+
+// Reduce reduces a []T1 to a single value using a reduction function.
+func Reduce[T1, T2 any](s []T1, initializer T2, f func(T2, T1) T2) T2 {
+	r := initializer
+	for _, v := range s {
+		r = f(r, v)
+	}
+	return r
+}
+
+// Filter filters values from a slice using a filter function.
+func Filter[T any](s []T, f func(T) bool) []T {
+	var r []T
+	for _, v := range s {
+		if f(v) {
+			r = append(r, v)
+		}
+	}
+	return r
+}
+
+// Example uses
+
+func limiter(x int) byte {
+	switch {
+	case x < 0:
+		return 0
+	default:
+		return byte(x)
+	case x > 255:
+		return 255
+	}
+}
+
+var input = []int{-4, 68954, 7, 44, 0, -555, 6945}
+var limited1 = Map[int, byte](input, limiter)
+var limited2 = Map(input, limiter) // using type inference
+
+func reducer(x float64, y int) float64 {
+	return x + float64(y)
+}
+
+var reduced1 = Reduce[int, float64](input, 0, reducer)
+var reduced2 = Reduce(input, 1i /* ERROR overflows */, reducer) // using type inference
+var reduced3 = Reduce(input, 1, reducer) // using type inference
+
+func filter(x int) bool {
+	return x&1 != 0
+}
+
+var filtered1 = Filter[int](input, filter)
+var filtered2 = Filter(input, filter) // using type inference
+
diff --git a/src/cmd/compile/internal/types2/testdata/check/stmt0.src b/src/cmd/compile/internal/types2/testdata/check/stmt0.src
new file mode 100644
index 0000000..bedcbe5
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/stmt0.src
@@ -0,0 +1,980 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// statements
+
+package stmt0
+
+func assignments0() (int, int) {
+	var a, b, c int
+	var ch chan int
+	f0 := func() {}
+	f1 := func() int { return 1 }
+	f2 := func() (int, int) { return 1, 2 }
+	f3 := func() (int, int, int) { return 1, 2, 3 }
+
+	a, b, c = 1, 2, 3
+	a, b, c = 1 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ , 2
+	a, b, c = 1 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ , 2, 3, 4
+	_, _, _ = a, b, c
+
+	a = f0 /* ERROR "used as value" */ ()
+	a = f1()
+	a = f2 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
+	a, b = f2()
+	a, b, c = f2 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
+	a, b, c = f3()
+	a, b = f3 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
+
+	a, b, c = <- /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ch
+
+	return /* ERROR "wrong number of return values" */
+	return /* ERROR "wrong number of return values" */ 1
+	return 1, 2
+	return /* ERROR "wrong number of return values" */ 1, 2, 3
+}
+
+func assignments1() {
+	b, i, f, c, s := false, 1, 1.0, 1i, "foo"
+	b = i /* ERROR "cannot use .* in assignment" */
+	i = f /* ERROR "cannot use .* in assignment" */
+	f = c /* ERROR "cannot use .* in assignment" */
+	c = s /* ERROR "cannot use .* in assignment" */
+	s = b /* ERROR "cannot use .* in assignment" */
+
+	v0, v1, v2 := 1 /* ERROR "cannot initialize" */ , 2, 3, 4
+	_, _, _ = v0, v1, v2
+
+	b = true
+
+	i += 1
+	i += "foo" /* ERROR "cannot convert.*int" */
+
+	f -= 1
+	f /= 0
+	f = float32(0)/0 /* ERROR "division by zero" */
+	f -= "foo" /* ERROR "cannot convert.*float64" */
+
+	c *= 1
+	c /= 0
+
+	s += "bar"
+	s += 1 /* ERROR "cannot convert.*string" */
+
+	var u64 uint64
+	u64 += 1<<u64
+
+	undeclared /* ERROR "undeclared" */ = 991
+
+	// test cases for issue 5800
+	var (
+		_ int = nil /* ERROR "untyped nil" */
+		_ [10]int = nil /* ERROR "untyped nil" */
+		_ []byte = nil
+		_ struct{} = nil /* ERROR "untyped nil" */
+		_ func() = nil
+		_ map[int]string = nil
+		_ chan int = nil
+	)
+
+	// test cases for issue 5500
+	_ = func() (int, bool) {
+		var m map[int]int
+		return /* ERROR "wrong number of return values" */ m[0]
+	}
+
+	g := func(int, bool){}
+	var m map[int]int
+	g(m[0]) /* ERROR "not enough arguments" */
+
+	// assignments to _
+	_ = nil /* ERROR "use of untyped nil" */
+	_ = 1 /* ERROR overflow */ <<1000
+	(_) = 0
+}
+
+func assignments2() {
+	type mybool bool
+	var m map[string][]bool
+	var s []bool
+	var b bool
+	var d mybool
+	_ = s
+	_ = b
+	_ = d
+
+	// assignments to map index expressions are ok
+	s, b = m["foo"]
+	_, d = m["bar"]
+	m["foo"] = nil
+	m["foo"] = nil /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
+	_ = append(m["foo"])
+	_ = append(m["foo"], true)
+
+	var c chan int
+	_, b = <-c
+	_, d = <-c
+	<- /* ERROR cannot assign */ c = 0
+	<-c = 0 /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
+
+	var x interface{}
+	_, b = x.(int)
+	x /* ERROR cannot assign */ .(int) = 0
+	x.(int) = 0 /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
+
+	assignments2 /* ERROR used as value */ () = nil
+	int /* ERROR not an expression */ = 0
+}
+
+func issue6487() {
+	type S struct{x int}
+	_ = &S /* ERROR "cannot take address" */ {}.x
+	_ = &( /* ERROR "cannot take address" */ S{}.x)
+	_ = (&S{}).x
+	S /* ERROR "cannot assign" */ {}.x = 0
+	(&S{}).x = 0
+
+	type M map[string]S
+	var m M
+	m /* ERROR "cannot assign to struct field" */ ["foo"].x = 0
+	_ = &( /* ERROR "cannot take address" */ m["foo"].x)
+	_ = &m /* ERROR "cannot take address" */ ["foo"].x
+}
+
+func issue6766a() {
+	a, a /* ERROR a repeated on left side of := */ := 1, 2
+	_ = a
+	a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3
+	_ = b
+	c, c /* ERROR c repeated on left side of := */, b := 1, 2, 3
+	_ = c
+	a, b := /* ERROR no new variables */ 1, 2
+}
+
+func shortVarDecls1() {
+	const c = 0
+	type d int
+	a, b, c /* ERROR "cannot assign" */ , d /* ERROR "cannot assign" */  := 1, "zwei", 3.0, 4
+	var _ int = a // a is of type int
+	var _ string = b // b is of type string
+}
+
+func incdecs() {
+	const c = 3.14
+	c /* ERROR "cannot assign" */ ++
+	s := "foo"
+	s /* ERROR "invalid operation" */ --
+	3.14 /* ERROR "cannot assign" */ ++
+	var (
+		x int
+		y float32
+		z complex128
+	)
+	x++
+	y--
+	z++
+}
+
+func sends() {
+	var ch chan int
+	var rch <-chan int
+	var x int
+	x <- /* ERROR "cannot send" */ x
+	rch <- /* ERROR "cannot send" */ x
+	ch <- "foo" /* ERROR "cannot use .* in send" */
+	ch <- x
+}
+
+func selects() {
+	select {}
+	var (
+		ch chan int
+		sc chan <- bool
+	)
+	select {
+	case <-ch:
+	case (<-ch):
+	case t := <-ch:
+		_ = t
+	case t := (<-ch):
+		_ = t
+	case t, ok := <-ch:
+		_, _ = t, ok
+	case t, ok := (<-ch):
+		_, _ = t, ok
+	case <-sc /* ERROR "cannot receive from send-only channel" */ :
+	}
+	select {
+	default:
+	default /* ERROR "multiple defaults" */ :
+	}
+	select {
+	case a, b := <-ch:
+		_, b = a, b
+	case x /* ERROR send or receive */ :
+	case a /* ERROR send or receive */ := ch:
+	}
+
+	// test for issue 9570: ch2 in second case falsely resolved to
+	// ch2 declared in body of first case
+	ch1 := make(chan int)
+	ch2 := make(chan int)
+	select {
+	case <-ch1:
+		var ch2 /* ERROR ch2 declared but not used */ chan bool
+	case i := <-ch2:
+		print(i + 1)
+	}
+}
+
+func gos() {
+	go 1 /* ERROR must be function call */ /* ERROR cannot call non-function */
+	go int /* ERROR "go requires function call, not conversion" */ (0)
+	go gos()
+	var c chan int
+	go close(c)
+	go len /* ERROR "go discards result" */ (c)
+}
+
+func defers() {
+	defer 1 /* ERROR must be function call */ /* ERROR cannot call non-function */
+	defer int /* ERROR "defer requires function call, not conversion" */ (0)
+	defer defers()
+	var c chan int
+	defer close(c)
+	defer len /* ERROR "defer discards result" */ (c)
+}
+
+func breaks() {
+	var x, y int
+
+	break /* ERROR "break" */
+	{
+		break /* ERROR "break" */
+	}
+	if x < y {
+		break /* ERROR "break" */
+	}
+
+	switch x {
+	case 0:
+		break
+	case 1:
+		if x == y {
+			break
+		}
+	default:
+		break
+		break
+	}
+
+	var z interface{}
+	switch z.(type) {
+	case int:
+		break
+	}
+
+	for {
+		break
+	}
+
+	var a []int
+	for _ = range a {
+		break
+	}
+
+	for {
+		if x == y {
+			break
+		}
+	}
+
+	var ch chan int
+	select {
+	case <-ch:
+		break
+	}
+
+	select {
+	case <-ch:
+		if x == y {
+			break
+		}
+	default:
+		break
+	}
+}
+
+func continues() {
+	var x, y int
+
+	continue /* ERROR "continue" */
+	{
+		continue /* ERROR "continue" */
+	}
+
+	if x < y {
+		continue /* ERROR "continue" */
+	}
+
+	switch x {
+	case 0:
+		continue /* ERROR "continue" */
+	}
+
+	var z interface{}
+	switch z.(type) {
+	case int:
+		continue /* ERROR "continue" */
+	}
+
+	var ch chan int
+	select {
+	case <-ch:
+		continue /* ERROR "continue" */
+	}
+
+	for i := 0; i < 10; i++ {
+		continue
+		if x < y {
+			continue
+			break
+		}
+		switch x {
+		case y:
+			continue
+		default:
+			break
+		}
+		select {
+		case <-ch:
+			continue
+		}
+	}
+
+	var a []int
+	for _ = range a {
+		continue
+		if x < y {
+			continue
+			break
+		}
+		switch x {
+		case y:
+			continue
+		default:
+			break
+		}
+		select {
+		case <-ch:
+			continue
+		}
+	}
+}
+
+func returns0() {
+	return
+	return 0 /* ERROR no result values expected */
+}
+
+func returns1(x float64) (int, *float64) {
+	return 0, &x
+	return /* ERROR wrong number of return values */
+	return "foo" /* ERROR "cannot .* in return statement" */, x /* ERROR "cannot use .* in return statement" */
+	return /* ERROR wrong number of return values */ 0, &x, 1
+}
+
+func returns2() (a, b int) {
+	return
+	return 1, "foo" /* ERROR cannot use .* in return statement */
+	return /* ERROR wrong number of return values */ 1, 2, 3
+	{
+		type a int
+		return 1, 2
+		return /* ERROR a not in scope at return */
+	}
+}
+
+func returns3() (_ int) {
+	return
+	{
+		var _ int // blank (_) identifiers never shadow since they are in no scope
+		return
+	}
+}
+
+func switches0() {
+	var x int
+
+	switch x {
+	}
+
+	switch x {
+	default:
+	default /* ERROR "multiple defaults" */ :
+	}
+
+	switch {
+	case 1  /* ERROR "cannot convert" */ :
+	}
+
+	true := "false"
+	_ = true
+	// A tagless switch is equivalent to the bool
+        // constant true, not the identifier 'true'.
+	switch {
+	case "false" /* ERROR "cannot convert" */:
+	}
+
+	switch int32(x) {
+	case 1, 2:
+	case x /* ERROR "cannot compare" */ :
+	}
+
+	switch x {
+	case 1 /* ERROR "overflows" */ << 100:
+	}
+
+	switch x {
+	case 1:
+	case 1 /* ERROR "duplicate case" */ :
+	case ( /* ERROR "duplicate case" */ 1):
+	case 2, 3, 4:
+	case 5, 1 /* ERROR "duplicate case" */ :
+	}
+
+	switch uint64(x) {
+	case 1<<64 - 1:
+	case 1 /* ERROR duplicate case */ <<64 - 1:
+	case 2, 3, 4:
+	case 5, 1 /* ERROR duplicate case */ <<64 - 1:
+	}
+
+	var y32 float32
+	switch y32 {
+	case 1.1:
+	case 11/10: // integer division!
+	case 11. /* ERROR duplicate case */ /10:
+	case 2, 3.0, 4.1:
+	case 5.2, 1.10 /* ERROR duplicate case */ :
+	}
+
+	var y64 float64
+	switch y64 {
+	case 1.1:
+	case 11/10: // integer division!
+	case 11. /* ERROR duplicate case */ /10:
+	case 2, 3.0, 4.1:
+	case 5.2, 1.10 /* ERROR duplicate case */ :
+	}
+
+	var s string
+	switch s {
+	case "foo":
+	case "foo" /* ERROR duplicate case */ :
+	case "f" /* ERROR duplicate case */ + "oo":
+	case "abc", "def", "ghi":
+	case "jkl", "foo" /* ERROR duplicate case */ :
+	}
+
+	type T int
+	type F float64
+	type S string
+	type B bool
+	var i interface{}
+	switch i {
+	case nil:
+	case nil: // no duplicate detection
+	case (*int)(nil):
+	case (*int)(nil): // do duplicate detection
+	case 1:
+	case byte(1):
+	case int /* ERROR duplicate case */ (1):
+	case T(1):
+	case 1.0:
+	case F(1.0):
+	case F /* ERROR duplicate case */ (1.0):
+	case "hello":
+	case S("hello"):
+	case S /* ERROR duplicate case */ ("hello"):
+	case 1==1, B(false):
+	case false, B(2==2):
+	}
+
+	// switch on array
+	var a [3]int
+	switch a {
+	case [3]int{1, 2, 3}:
+	case [3]int{1, 2, 3}: // no duplicate detection
+	case [ /* ERROR "mismatched types */ 4]int{4, 5, 6}:
+	}
+
+	// switch on channel
+	var c1, c2 chan int
+	switch c1 {
+	case nil:
+	case c1:
+	case c2:
+	case c1, c2: // no duplicate detection
+	}
+}
+
+func switches1() {
+	fallthrough /* ERROR "fallthrough statement out of place" */
+
+	var x int
+	switch x {
+	case 0:
+		fallthrough /* ERROR "fallthrough statement out of place" */
+		break
+	case 1:
+		fallthrough
+	case 2:
+		fallthrough; ; ; // trailing empty statements are ok
+	case 3:
+	default:
+		fallthrough; ;
+	case 4:
+		fallthrough /* ERROR "cannot fallthrough final case in switch" */
+	}
+
+	var y interface{}
+	switch y.(type) {
+	case int:
+		fallthrough /* ERROR "fallthrough statement out of place" */ ; ; ;
+	default:
+	}
+
+	switch x {
+	case 0:
+		if x == 0 {
+			fallthrough /* ERROR "fallthrough statement out of place" */
+		}
+	}
+
+	switch x {
+	case 0:
+		goto L1
+		L1: fallthrough; ;
+	case 1:
+		goto L2
+		goto L3
+		goto L4
+		L2: L3: L4: fallthrough
+	default:
+	}
+
+	switch x {
+	case 0:
+		goto L5
+		L5: fallthrough
+	default:
+		goto L6
+		goto L7
+		goto L8
+		L6: L7: L8: fallthrough /* ERROR "cannot fallthrough final case in switch" */
+	}
+
+	switch x {
+	case 0:
+		fallthrough; ;
+	case 1:
+		{
+			fallthrough /* ERROR "fallthrough statement out of place" */
+		}
+	case 2:
+		fallthrough
+	case 3:
+		fallthrough /* ERROR "fallthrough statement out of place" */
+		{ /* empty block is not an empty statement */ }; ;
+	default:
+		fallthrough /* ERROR "cannot fallthrough final case in switch" */
+	}
+
+	switch x {
+	case 0:
+		{
+			fallthrough /* ERROR "fallthrough statement out of place" */
+		}
+	}
+}
+
+func switches2() {
+	// untyped nil is not permitted as switch expression
+	switch nil /* ERROR "use of untyped nil" */ {
+	case 1, 2, "foo": // don't report additional errors here
+	}
+
+	// untyped constants are converted to default types
+	switch 1<<63-1 {
+	}
+	switch 1 /* ERROR "cannot use .* as int value.*\(overflows\)" */ << 63 {
+	}
+	var x int
+	switch 1.0 {
+	case 1.0, 2.0, x /* ERROR "mismatched types int and float64" */ :
+	}
+	switch x {
+	case 1.0:
+	}
+
+	// untyped bools become of type bool
+	type B bool
+	var b B = true
+	switch x == x {
+	case b /* ERROR "mismatched types B and bool" */ :
+	}
+	switch {
+	case b /* ERROR "mismatched types B and bool" */ :
+	}
+}
+
+func issue11667() {
+	switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ {
+	}
+	switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ {
+	case 9223372036854775808:
+	}
+	var x int
+	switch x {
+	case 9223372036854775808 /* ERROR "overflows int" */ :
+	}
+	var y float64
+	switch y {
+	case 9223372036854775808:
+	}
+}
+
+func issue11687() {
+	f := func() (_, _ int) { return }
+	switch f /* ERROR "2-valued f" */ () {
+	}
+	var x int
+	switch f /* ERROR "2-valued f" */ () {
+	case x:
+	}
+	switch x {
+	case f /* ERROR "2-valued f" */ ():
+	}
+}
+
+type I interface {
+	m()
+}
+
+type I2 interface {
+	m(int)
+}
+
+type T struct{}
+type T1 struct{}
+type T2 struct{}
+
+func (T) m() {}
+func (T2) m(int) {}
+
+func typeswitches() {
+	var i int
+	var x interface{}
+
+	switch x.(type) {}
+	switch (x /* ERROR "outside type switch" */ .(type)) {}
+
+	switch x.(type) {
+	default:
+	default /* ERROR "multiple defaults" */ :
+	}
+
+	switch x /* ERROR "declared but not used" */ := x.(type) {}
+	switch _ /* ERROR "no new variable on left side of :=" */ := x.(type) {}
+
+	switch x := x.(type) {
+	case int:
+		var y int = x
+		_ = y
+	}
+
+	switch x := i /* ERROR "not an interface" */ .(type) {}
+
+	switch t := x.(type) {
+	case nil:
+		var v bool = t /* ERROR "cannot use .* in variable declaration" */
+		_ = v
+	case int:
+		var v int = t
+		_ = v
+	case float32, complex64:
+		var v float32 = t /* ERROR "cannot use .* in variable declaration" */
+		_ = v
+	default:
+		var v float32 = t /* ERROR "cannot use .* in variable declaration" */
+		_ = v
+	}
+
+	var t I
+	switch t.(type) {
+	case T:
+	case T1 /* ERROR "missing method m" */ :
+	case T2 /* ERROR "wrong type for method m" */ :
+	case I2 /* STRICT "wrong type for method m" */ : // only an error in strict mode (issue 8561)
+	}
+}
+
+// Test that each case clause uses the correct type of the variable
+// declared by the type switch (issue 5504).
+func typeswitch0() {
+	switch y := interface{}(nil).(type) {
+	case int:
+		func() int { return y + 0 }()
+	case float32:
+		func() float32 { return y }()
+	}
+}
+
+// Test correct scope setup.
+// (no redeclaration errors expected in the type switch)
+func typeswitch1() {
+	var t I
+	switch t := t; t := t.(type) {
+	case nil:
+		var _ I = t
+	case T:
+		var _ T = t
+	default:
+		var _ I = t
+	}
+}
+
+// Test correct typeswitch against interface types.
+type A interface { a() }
+type B interface { b() }
+type C interface { a(int) }
+
+func typeswitch2() {
+	switch A(nil).(type) {
+	case A:
+	case B:
+	case C /* STRICT "cannot have dynamic type" */: // only an error in strict mode (issue 8561)
+	}
+}
+
+func typeswitch3(x interface{}) {
+	switch x.(type) {
+	case int:
+	case float64:
+	case int /* ERROR duplicate case */ :
+	}
+
+	switch x.(type) {
+	case nil:
+	case int:
+	case nil /* ERROR duplicate case */ , nil /* ERROR duplicate case */ :
+	}
+
+	type F func(int)
+	switch x.(type) {
+	case nil:
+	case int, func(int):
+	case float32, func /* ERROR duplicate case */ (x int):
+	case F:
+	}
+}
+
+func fors1() {
+	for {}
+	var i string
+	_ = i
+	for i := 0; i < 10; i++ {}
+	for i := 0; i < 10; j /* ERROR cannot declare */ := 0 {}
+}
+
+func rangeloops1() {
+	var (
+		x int
+		a [10]float32
+		b []string
+		p *[10]complex128
+		pp **[10]complex128
+		s string
+		m map[int]bool
+		c chan int
+		sc chan<- int
+		rc <-chan int
+	)
+
+	for range x /* ERROR "cannot range over" */ {}
+	for _ = range x /* ERROR "cannot range over" */ {}
+	for i := range x /* ERROR "cannot range over" */ {}
+
+	for range a {}
+	for i := range a {
+		var ii int
+		ii = i
+		_ = ii
+	}
+	for i, x := range a {
+		var ii int
+		ii = i
+		_ = ii
+		var xx float64
+		xx = x /* ERROR "cannot use .* in assignment" */
+		_ = xx
+	}
+	var ii int
+	var xx float32
+	for ii, xx = range a {}
+	_, _ = ii, xx
+
+	for range b {}
+	for i := range b {
+		var ii int
+		ii = i
+		_ = ii
+	}
+	for i, x := range b {
+		var ii int
+		ii = i
+		_ = ii
+		var xx string
+		xx = x
+		_ = xx
+	}
+
+	for range s {}
+	for i := range s {
+		var ii int
+		ii = i
+		_ = ii
+	}
+	for i, x := range s {
+		var ii int
+		ii = i
+		_ = ii
+		var xx rune
+		xx = x
+		_ = xx
+	}
+
+	for range p {}
+	for _, x := range p {
+		var xx complex128
+		xx = x
+		_ = xx
+	}
+
+	for range pp /* ERROR "cannot range over" */ {}
+	for _, x := range pp /* ERROR "cannot range over" */ {}
+
+	for range m {}
+	for k := range m {
+		var kk int32
+		kk = k /* ERROR "cannot use .* in assignment" */
+		_ = kk
+	}
+	for k, v := range m {
+		var kk int
+		kk = k
+		_ = kk
+		if v {}
+	}
+
+	for range c {}
+	for _, _ /* ERROR "only one iteration variable" */ = range c {}
+	for e := range c {
+		var ee int
+		ee = e
+		_ = ee
+	}
+	for _ = range sc /* ERROR "send-only channel" */ {}
+	for _ = range rc {}
+
+	// constant strings
+	const cs = "foo"
+	for range cs {}
+	for range "" {}
+	for i, x := range cs { _, _ = i, x }
+	for i, x := range "" {
+		var ii int
+		ii = i
+		_ = ii
+		var xx rune
+		xx = x
+		_ = xx
+	}
+}
+
+func rangeloops2() {
+	type I int
+	type R rune
+
+	var a [10]int
+	var i I
+	_ = i
+	for i /* ERROR cannot use .* in assignment */ = range a {}
+	for i /* ERROR cannot use .* in assignment */ = range &a {}
+	for i /* ERROR cannot use .* in assignment */ = range a[:] {}
+
+	var s string
+	var r R
+	_ = r
+	for i /* ERROR cannot use .* in assignment */ = range s {}
+	for i /* ERROR cannot use .* in assignment */ = range "foo" {}
+	for _, r /* ERROR cannot use .* in assignment */ = range s {}
+	for _, r /* ERROR cannot use .* in assignment */ = range "foo" {}
+}
+
+func issue6766b() {
+	for _ := /* ERROR no new variables */ range "" {}
+	for a, a /* ERROR redeclared */ := range "" { _ = a }
+	var a int
+	_ = a
+	for a, a /* ERROR redeclared */ := range []int{1, 2, 3} { _ = a }
+}
+
+// Test that despite errors in the range clause,
+// the loop body is still type-checked (and thus
+// errors reported).
+func issue10148() {
+	for y /* ERROR declared but not used */ := range "" {
+		_ = "" /* ERROR cannot convert */ + 1
+	}
+	for range 1 /* ERROR cannot range over 1 */ {
+		_ = "" /* ERROR cannot convert */ + 1
+	}
+	for y := range 1 /* ERROR cannot range over 1 */ {
+		_ = "" /* ERROR cannot convert */ + 1
+	}
+}
+
+func labels0() {
+	goto L0
+	goto L1
+	L0:
+	L1:
+	L1 /* ERROR "already declared" */ :
+	if true {
+		goto L2
+		L2:
+		L0 /* ERROR "already declared" */ :
+	}
+	_ = func() {
+		goto L0
+		goto L1
+		goto L2
+		L0:
+		L1:
+		L2:
+	}
+}
+
+func expression_statements(ch chan int) {
+	expression_statements(ch)
+	<-ch
+	println()
+
+	0 /* ERROR "not used" */
+	1 /* ERROR "not used" */ +2
+	cap /* ERROR "not used" */ (ch)
+	println /* ERROR "must be called" */
+}
diff --git a/src/go/types/testdata/stmt1.src b/src/cmd/compile/internal/types2/testdata/check/stmt1.src
similarity index 100%
copy from src/go/types/testdata/stmt1.src
copy to src/cmd/compile/internal/types2/testdata/check/stmt1.src
diff --git a/src/cmd/compile/internal/types2/testdata/check/tinference.go2 b/src/cmd/compile/internal/types2/testdata/check/tinference.go2
new file mode 100644
index 0000000..a53fde0
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/tinference.go2
@@ -0,0 +1,105 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tinferenceB
+
+import "strconv"
+
+type any interface{}
+
+func f0[A any, B interface{type C}, C interface{type D}, D interface{type A}](A, B, C, D)
+func _() {
+	f := f0[string]
+	f("a", "b", "c", "d")
+	f0("a", "b", "c", "d")
+}
+
+func f1[A any, B interface{type A}](A, B)
+func _() {
+	f := f1[int]
+	f(int(0), int(0))
+	f1(int(0), int(0))
+}
+
+func f2[A any, B interface{type []A}](A, B)
+func _() {
+	f := f2[byte]
+	f(byte(0), []byte{})
+	f2(byte(0), []byte{})
+}
+
+func f3[A any, B interface{type C}, C interface{type *A}](A, B, C)
+func _() {
+	f := f3[int]
+	var x int
+	f(x, &x, &x)
+	f3(x, &x, &x)
+}
+
+func f4[A any, B interface{type []C}, C interface{type *A}](A, B, C)
+func _() {
+	f := f4[int]
+	var x int
+	f(x, []*int{}, &x)
+	f4(x, []*int{}, &x)
+}
+
+func f5[A interface{type struct{b B; c C}}, B any, C interface{type *B}](x B) A
+func _() {
+	x := f5(1.2)
+	var _ float64 = x.b
+	var _ float64 = *x.c
+}
+
+func f6[A any, B interface{type struct{f []A}}](B) A
+func _() {
+	x := f6(struct{f []string}{})
+	var _ string = x
+}
+
+// TODO(gri) Need to flag invalid recursive constraints. At the
+// moment these cause infinite recursions and stack overflow.
+// func f7[A interface{type B}, B interface{type A}]()
+
+// More realistic examples
+
+func Double[S interface{ type []E }, E interface{ type int, int8, int16, int32, int64 }](s S) S {
+	r := make(S, len(s))
+	for i, v := range s {
+		r[i] = v + v
+	}
+	return r
+}
+
+type MySlice []int
+
+var _ = Double(MySlice{1})
+
+// From the draft design.
+
+type Setter[B any] interface {
+	Set(string)
+	type *B
+}
+
+func FromStrings[T interface{}, PT Setter[T]](s []string) []T {
+	result := make([]T, len(s))
+	for i, v := range s {
+		// The type of &result[i] is *T which is in the type list
+		// of Setter2, so we can convert it to PT.
+		p := PT(&result[i])
+		// PT has a Set method.
+		p.Set(v)
+	}
+	return result
+}
+
+type Settable int
+
+func (p *Settable) Set(s string) {
+	i, _ := strconv.Atoi(s) // real code should not ignore the error
+	*p = Settable(i)
+}
+
+var _ = FromStrings[Settable]([]string{"1", "2"})
diff --git a/src/cmd/compile/internal/types2/testdata/check/typeinst.go2 b/src/cmd/compile/internal/types2/testdata/check/typeinst.go2
new file mode 100644
index 0000000..0d628cb
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/typeinst.go2
@@ -0,0 +1,59 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type myInt int
+
+// Parameterized type declarations
+
+type T1[P any] P
+
+type T2[P any] struct {
+        f P
+        g int // int should still be in scope chain
+}
+
+type List[P any] []P
+
+// Alias type declarations cannot have type parameters. Syntax error.
+type A1[P any] = /* ERROR cannot be alias */ P
+
+// But an alias may refer to a generic, uninstantiated type.
+type A2 = List
+var _ A2[int]
+var _ A2 /* ERROR without instantiation */
+
+type A3 = List[int]
+var _ A3
+
+// Parameterized type instantiations
+
+var x int
+type _ x /* ERROR not a type */ [int]
+
+type _ int /* ERROR not a generic type */ [] // ERROR expecting type
+type _ myInt /* ERROR not a generic type */ [] // ERROR expecting type
+
+// TODO(gri) better error messages
+type _ T1[] // ERROR expecting type
+type _ T1[x /* ERROR not a type */ ]
+type _ T1 /* ERROR got 2 arguments but 1 type parameters */ [int, float32]
+
+var _ T2[int] = T2[int]{}
+
+var _ List[int] = []int{1, 2, 3}
+var _ List[[]int] = [][]int{{1, 2, 3}}
+var _ List[List[List[int]]]
+
+// Parameterized types containing parameterized types
+
+type T3[P any] List[P]
+
+var _ T3[int] = T3[int](List[int]{1, 2, 3})
+
+// Self-recursive generic types are not permitted
+
+type self1[P any] self1 /* ERROR illegal cycle */ [P]
+type self2[P any] *self2[P] // this is ok
diff --git a/src/cmd/compile/internal/types2/testdata/check/typeinst2.go2 b/src/cmd/compile/internal/types2/testdata/check/typeinst2.go2
new file mode 100644
index 0000000..6e2104a
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/typeinst2.go2
@@ -0,0 +1,256 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type List[E any] []E
+var _ List[List[List[int]]]
+var _ List[List[List[int]]] = []List[List[int]]{}
+
+type (
+	T1[P1 any] struct {
+		f1 T2[P1, float32]
+	}
+
+	T2[P2, P3 any] struct {
+		f2 P2
+		f3 P3
+	}
+)
+
+func _() {
+	var x1 T1[int]
+	var x2 T2[int, float32]
+
+	x1.f1.f2 = 0
+	x1.f1 = x2
+}
+
+type T3[P any] T1[T2[P, P]]
+
+func _() {
+	var x1 T3[int]
+	var x2 T2[int, int]
+	x1.f1.f2 = x2
+}
+
+func f[P any] (x P) List[P] {
+	return List[P]{x}
+}
+
+var (
+	_ []int = f(0)
+	_ []float32 = f[float32](10)
+	_ List[complex128] = f(1i)
+	_ []List[int] = f(List[int]{})
+        _ List[List[int]] = []List[int]{}
+        _ = []List[int]{}
+)
+
+// Parameterized types with methods
+
+func (l List[E]) Head() (_ E, _ bool) {
+	if len(l) > 0 {
+		return l[0], true
+	}
+	return
+}
+
+// A test case for instantiating types with other types (extracted from map.go2)
+
+type Pair[K any] struct {
+	key K
+}
+
+type Receiver[T any] struct {
+	values T
+}
+
+type Iterator[K any] struct {
+	r Receiver[Pair[K]]
+}
+
+func Values [T any] (r Receiver[T]) T {
+        return r.values
+}
+
+func (it Iterator[K]) Next() K {
+        return Values[Pair[K]](it.r).key
+}
+
+// A more complex test case testing type bounds (extracted from linalg.go2 and reduced to essence)
+
+type NumericAbs[T any] interface {
+	Abs() T
+}
+
+func AbsDifference[T NumericAbs[T]](x T)
+
+type OrderedAbs[T any] T
+
+func (a OrderedAbs[T]) Abs() OrderedAbs[T]
+
+func OrderedAbsDifference[T any](x T) {
+	AbsDifference(OrderedAbs[T](x))
+}
+
+// same code, reduced to essence
+
+func g[P interface{ m() P }](x P)
+
+type T4[P any] P
+
+func (_ T4[P]) m() T4[P]
+
+func _[Q any](x Q) {
+	g(T4[Q](x))
+}
+
+// Another test case that caused  problems in the past
+
+type T5[_ interface { a() }, _ interface{}] struct{}
+
+type A[P any] struct{ x P }
+
+func (_ A[P]) a() {}
+
+var _ T5[A[int], int]
+
+// Invoking methods with parameterized receiver types uses
+// type inference to determine the actual type arguments matching
+// the receiver type parameters from the actual receiver argument.
+// Go does implicit address-taking and dereferenciation depending
+// on the actual receiver and the method's receiver type. To make
+// type inference work, the type-checker matches "pointer-ness"
+// of the actual receiver and the method's receiver type.
+// The following code tests this mechanism.
+
+type R1[A any] struct{}
+func (_ R1[A]) vm()
+func (_ *R1[A]) pm()
+
+func _[T any](r R1[T], p *R1[T]) {
+	r.vm()
+	r.pm()
+	p.vm()
+	p.pm()
+}
+
+type R2[A, B any] struct{}
+func (_ R2[A, B]) vm()
+func (_ *R2[A, B]) pm()
+
+func _[T any](r R2[T, int], p *R2[string, T]) {
+	r.vm()
+	r.pm()
+	p.vm()
+	p.pm()
+}
+
+// An interface can (explicitly) declare at most one type list.
+type _ interface {
+	m0()
+	type int, string, bool
+	type /* ERROR multiple type lists */ float32, float64
+	m1()
+	m2()
+	type /* ERROR multiple type lists */ complex64, complex128
+	type /* ERROR multiple type lists */ rune
+}
+
+// Interface type lists may contain each type at most once.
+// (If there are multiple lists, we assume the author intended
+// for them to be all in a single list, and we report the error
+// as well.)
+type _ interface {
+	type int, int /* ERROR duplicate type int */
+	type /* ERROR multiple type lists */ int /* ERROR duplicate type int */
+}
+
+type _ interface {
+	type struct{f int}, struct{g int}, struct /* ERROR duplicate type */ {f int}
+}
+
+// Interface type lists can contain any type, incl. *Named types.
+// Verify that we use the underlying type to compute the operational type.
+type MyInt int
+func add1[T interface{type MyInt}](x T) T {
+	return x + 1
+}
+
+type MyString string
+func double[T interface{type MyInt, MyString}](x T) T {
+	return x + x
+}
+
+// Embedding of interfaces with type lists leads to interfaces
+// with type lists that are the intersection of the embedded
+// type lists.
+
+type E0 interface {
+	type int, bool, string
+}
+
+type E1 interface {
+	type int, float64, string
+}
+
+type E2 interface {
+	type float64
+}
+
+type I0 interface {
+	E0
+}
+
+func f0[T I0]()
+var _ = f0[int]
+var _ = f0[bool]
+var _ = f0[string]
+var _ = f0[float64 /* ERROR does not satisfy I0 */ ]
+
+type I01 interface {
+	E0
+	E1
+}
+
+func f01[T I01]()
+var _ = f01[int]
+var _ = f01[bool /* ERROR does not satisfy I0 */ ]
+var _ = f01[string]
+var _ = f01[float64 /* ERROR does not satisfy I0 */ ]
+
+type I012 interface {
+	E0
+	E1
+	E2
+}
+
+func f012[T I012]()
+var _ = f012[int /* ERROR does not satisfy I012 */ ]
+var _ = f012[bool /* ERROR does not satisfy I012 */ ]
+var _ = f012[string /* ERROR does not satisfy I012 */ ]
+var _ = f012[float64 /* ERROR does not satisfy I012 */ ]
+
+type I12 interface {
+	E1
+	E2
+}
+
+func f12[T I12]()
+var _ = f12[int /* ERROR does not satisfy I12 */ ]
+var _ = f12[bool /* ERROR does not satisfy I12 */ ]
+var _ = f12[string /* ERROR does not satisfy I12 */ ]
+var _ = f12[float64]
+
+type I0_ interface {
+	E0
+	type int
+}
+
+func f0_[T I0_]()
+var _ = f0_[int]
+var _ = f0_[bool /* ERROR does not satisfy I0_ */ ]
+var _ = f0_[string /* ERROR does not satisfy I0_ */ ]
+var _ = f0_[float64 /* ERROR does not satisfy I0_ */ ]
diff --git a/src/cmd/compile/internal/types2/testdata/check/typeparams.go2 b/src/cmd/compile/internal/types2/testdata/check/typeparams.go2
new file mode 100644
index 0000000..badda01
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/typeparams.go2
@@ -0,0 +1,434 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// import "io" // for type assertion tests
+
+// The predeclared identifier "any" is only visible as a constraint
+// in a type parameter list.
+var _ any // ERROR undeclared
+func _[_ any /* ok here */ , _ interface{any /* ERROR undeclared */ }](any /* ERROR undeclared */ ) {
+        var _ any /* ERROR undeclared */
+}
+
+func identity[T any](x T) T { return x }
+
+func _[_ any](x int) int
+func _[T any](T /* ERROR redeclared */ T)()
+func _[T, T /* ERROR redeclared */ any]()
+
+// Constraints (incl. any) may be parenthesized.
+func _[_ (any)]() {}
+func _[_ (interface{})]() {}
+
+func reverse[T any](list []T) []T {
+        rlist := make([]T, len(list))
+        i := len(list)
+        for _, x := range list {
+                i--
+                rlist[i] = x
+        }
+        return rlist
+}
+
+var _ = reverse /* ERROR cannot use generic function reverse */
+var _ = reverse[int, float32 /* ERROR got 2 type arguments */ ] ([]int{1, 2, 3})
+var _ = reverse[int]([ /* ERROR cannot use */ ]float32{1, 2, 3})
+var f = reverse[chan int]
+var _ = f(0 /* ERROR cannot use 0 .* as \[\]chan int */ )
+
+func swap[A, B any](a A, b B) (B, A) { return b, a }
+
+var _ = swap /* ERROR single value is expected */ [int, float32](1, 2)
+var f32, i = swap[int, float32](swap[float32, int](1, 2))
+var _ float32 = f32
+var _ int = i
+
+func swapswap[A, B any](a A, b B) (A, B) {
+        return swap[B, A](b, a)
+}
+
+type F[A, B any] func(A, B) (B, A)
+
+func min[T interface{ type int }](x, y T) T {
+        if x < y {
+                return x
+        }
+        return y
+}
+
+func _[T interface{type int, float32}](x, y T) bool { return x < y }
+func _[T any](x, y T) bool { return x /* ERROR cannot compare */ < y }
+func _[T interface{type int, float32, bool}](x, y T) bool { return x /* ERROR cannot compare */ < y }
+
+func _[T C1[T]](x, y T) bool { return x /* ERROR cannot compare */ < y }
+func _[T C2[T]](x, y T) bool { return x < y }
+
+type C1[T any] interface{}
+type C2[T any] interface{ type int, float32 }
+
+func new[T any]() *T {
+        var x T
+        return &x
+}
+
+var _ = new /* ERROR cannot use generic function new */
+var _ *int = new[int]()
+
+func _[T any](map[T /* ERROR invalid map key type T \(missing comparable constraint\) */]int) // w/o constraint we don't know if T is comparable
+
+func f1[T1 any](struct{T1}) int
+var _ = f1[int](struct{T1}{})
+type T1 = int
+
+func f2[t1 any](struct{t1; x float32}) int
+var _ = f2[t1](struct{t1; x float32}{})
+type t1 = int
+
+
+func f3[A, B, C any](A, struct{x B}, func(A, struct{x B}, *C)) int
+
+var _ = f3[int, rune, bool](1, struct{x rune}{}, nil)
+
+// indexing
+
+func _[T any] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+func _[T interface{ type int }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+func _[T interface{ type string }] (x T, i int) { _ = x[i] }
+func _[T interface{ type []int }] (x T, i int) { _ = x[i] }
+func _[T interface{ type [10]int, *[20]int, map[int]int }] (x T, i int) { _ = x[i] }
+func _[T interface{ type string, []byte }] (x T, i int) { _ = x[i] }
+func _[T interface{ type []int, [1]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+func _[T interface{ type string, []rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+
+// indexing with various combinations of map types in type lists (see issue #42616)
+func _[T interface{ type []E, map[int]E }, E any](x T, i int) { _ = x[i] }
+func _[T interface{ type []E }, E any](x T, i int) { _ = &x[i] }
+func _[T interface{ type map[int]E }, E any](x T, i int) { _, _ = x[i] } // comma-ok permitted
+func _[T interface{ type []E, map[int]E }, E any](x T, i int) { _ = &x /* ERROR cannot take address */ [i] }
+func _[T interface{ type []E, map[int]E, map[uint]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // different map element types
+func _[T interface{ type []E, map[string]E }, E any](x T, i int) { _ = x[i /* ERROR cannot use i */ ] }
+
+// slicing
+// TODO(gri) implement this
+
+func _[T interface{ type string }] (x T, i, j, k int) { _ = x /* ERROR invalid operation */ [i:j:k] }
+
+// len/cap built-ins
+
+func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) }
+func _[T interface{ type int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
+func _[T interface{ type string, []byte, int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
+func _[T interface{ type string }](x T) { _ = len(x) }
+func _[T interface{ type [10]int }](x T) { _ = len(x) }
+func _[T interface{ type []byte }](x T) { _ = len(x) }
+func _[T interface{ type map[int]int }](x T) { _ = len(x) }
+func _[T interface{ type chan int }](x T) { _ = len(x) }
+func _[T interface{ type string, []byte, chan int }](x T) { _ = len(x) }
+
+func _[T any](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type string, []byte, int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type string }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type [10]int }](x T) { _ = cap(x) }
+func _[T interface{ type []byte }](x T) { _ = cap(x) }
+func _[T interface{ type map[int]int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type chan int }](x T) { _ = cap(x) }
+func _[T interface{ type []byte, chan int }](x T) { _ = cap(x) }
+
+// range iteration
+
+func _[T interface{}](x T) {
+        for range x /* ERROR cannot range */ {}
+}
+
+func _[T interface{ type string, []string }](x T) {
+        for range x {}
+        for i := range x { _ = i }
+        for i, _ := range x { _ = i }
+        for i, e := range x /* ERROR must have the same element type */ { _ = i }
+        for _, e := range x /* ERROR must have the same element type */ {}
+        var e rune
+        _ = e
+        for _, (e) = range x /* ERROR must have the same element type */ {}
+}
+
+
+func _[T interface{ type string, []rune, map[int]rune }](x T) {
+        for _, e := range x { _ = e }
+        for i, e := range x { _ = i; _ = e }
+}
+
+func _[T interface{ type string, []rune, map[string]rune }](x T) {
+        for _, e := range x { _ = e }
+        for i, e := range x /* ERROR must have the same key type */ { _ = e }
+}
+
+func _[T interface{ type string, chan int }](x T) {
+        for range x {}
+        for i := range x { _ = i }
+        for i, _ := range x { _ = i } // TODO(gri) should get an error here: channels only return one value
+}
+
+func _[T interface{ type string, chan<-int }](x T) {
+        for i := range x /* ERROR send-only channel */ { _ = i }
+}
+
+// type inference checks
+
+var _ = new() /* ERROR cannot infer T */
+
+func f4[A, B, C any](A, B) C
+
+var _ = f4(1, 2) /* ERROR cannot infer C */
+var _ = f4[int, float32, complex128](1, 2)
+
+func f5[A, B, C any](A, []*B, struct{f []C}) int
+
+var _ = f5[int, float32, complex128](0, nil, struct{f []complex128}{})
+var _ = f5(0, nil, struct{f []complex128}{}) // ERROR cannot infer
+var _ = f5(0, []*float32{new[float32]()}, struct{f []complex128}{})
+
+func f6[A any](A, []A) int
+
+var _ = f6(0, nil)
+
+func f6nil[A any](A) int
+
+var _ = f6nil(nil) // ERROR cannot infer
+
+// type inference with variadic functions
+
+func f7[T any](...T) T
+
+var _ int = f7() /* ERROR cannot infer T */
+var _ int = f7(1)
+var _ int = f7(1, 2)
+var _ int = f7([]int{}...)
+var _ int = f7 /* ERROR cannot use */ ([]float64{}...)
+var _ float64 = f7([]float64{}...)
+var _ = f7[float64](1, 2.3)
+var _ = f7(float64(1), 2.3)
+var _ = f7(1, 2.3 /* ERROR does not match */ )
+var _ = f7(1.2, 3 /* ERROR does not match */ )
+
+func f8[A, B any](A, B, ...B) int
+
+var _ = f8(1) /* ERROR not enough arguments */
+var _ = f8(1, 2.3)
+var _ = f8(1, 2.3, 3.4, 4.5)
+var _ = f8(1, 2.3, 3.4, 4 /* ERROR does not match */ )
+var _ = f8[int, float64](1, 2.3, 3.4, 4)
+
+var _ = f8[int, float64](0, 0, nil...) // test case for #18268
+
+// init functions cannot have type parameters
+
+func init() {}
+func init[/* ERROR func init must have no type parameters */ _ any]() {}
+func init[/* ERROR func init must have no type parameters */ P any]() {}
+
+type T struct {}
+
+func (T) m1() {}
+// The type checker accepts method type parameters if configured accordingly.
+func (T) m2[_ any]() {}
+func (T) m3[P any]() {}
+
+// type inference across parameterized types
+
+type S1[P any] struct { f P }
+
+func f9[P any](x S1[P])
+
+func _() {
+        f9[int](S1[int]{42})
+	f9(S1[int]{42})
+}
+
+type S2[A, B, C any] struct{}
+
+func f10[X, Y, Z any](a S2[X, int, Z], b S2[X, Y, bool])
+
+func _[P any]() {
+        f10[int, float32, string](S2[int, int, string]{}, S2[int, float32, bool]{})
+        f10(S2[int, int, string]{}, S2[int, float32, bool]{})
+        f10(S2[P, int, P]{}, S2[P, float32, bool]{})
+}
+
+// corner case for type inference
+// (was bug: after instanting f11, the type-checker didn't mark f11 as non-generic)
+
+func f11[T any]()
+
+func _() {
+	f11[int]()
+}
+
+// the previous example was extracted from
+
+func f12[T interface{m() T}]()
+
+type A[T any] T
+
+func (a A[T]) m() A[T]
+
+func _[T any]() {
+	f12[A[T]]()
+}
+
+// method expressions
+
+func (_ S1[P]) m()
+
+func _() {
+	m := S1[int].m
+	m(struct { f int }{42})
+}
+
+func _[T any] (x T) {
+        m := S1[T].m
+        m(S1[T]{x})
+}
+
+// type parameters in methods (generalization)
+
+type R0 struct{}
+
+func (R0) _[T any](x T)
+func (R0 /* ERROR invalid receiver */ ) _[R0 any]() // scope of type parameters starts at "func"
+
+type R1[A, B any] struct{}
+
+func (_ R1[A, B]) m0(A, B)
+func (_ R1[A, B]) m1[T any](A, B, T) T
+func (_ R1 /* ERROR not a generic type */ [R1, _]) _()
+func (_ R1[A, B]) _[A /* ERROR redeclared */ any](B)
+
+func _() {
+        var r R1[int, string]
+        r.m1[rune](42, "foo", 'a')
+        r.m1[rune](42, "foo", 1.2 /* ERROR cannot use .* as rune .* \(truncated\) */)
+        r.m1(42, "foo", 1.2) // using type inference
+        var _ float64 = r.m1(42, "foo", 1.2)
+}
+
+type I1[A any] interface {
+        m1(A)
+}
+
+var _ I1[int] = r1[int]{}
+
+type r1[T any] struct{}
+
+func (_ r1[T]) m1(T)
+
+type I2[A, B any] interface {
+        m1(A)
+        m2(A) B
+}
+
+var _ I2[int, float32] = R2[int, float32]{}
+
+type R2[P, Q any] struct{}
+
+func (_ R2[X, Y]) m1(X)
+func (_ R2[X, Y]) m2(X) Y
+
+// type assertions and type switches over generic types
+// NOTE: These are currently disabled because it's unclear what the correct
+// approach is, and one can always work around by assigning the variable to
+// an interface first.
+
+// // ReadByte1 corresponds to the ReadByte example in the draft design.
+// func ReadByte1[T io.Reader](r T) (byte, error) {
+// 	if br, ok := r.(io.ByteReader); ok {
+// 		return br.ReadByte()
+// 	}
+// 	var b [1]byte
+// 	_, err := r.Read(b[:])
+// 	return b[0], err
+// }
+//
+// // ReadBytes2 is like ReadByte1 but uses a type switch instead.
+// func ReadByte2[T io.Reader](r T) (byte, error) {
+//         switch br := r.(type) {
+//         case io.ByteReader:
+//                 return br.ReadByte()
+//         }
+// 	var b [1]byte
+// 	_, err := r.Read(b[:])
+// 	return b[0], err
+// }
+//
+// // type assertions and type switches over generic types are strict
+// type I3 interface {
+//         m(int)
+// }
+//
+// type I4 interface {
+//         m() int // different signature from I3.m
+// }
+//
+// func _[T I3](x I3, p T) {
+//         // type assertions and type switches over interfaces are not strict
+//         _ = x.(I4)
+//         switch x.(type) {
+//         case I4:
+//         }
+//
+//         // type assertions and type switches over generic types are strict
+//         _ = p /* ERROR cannot have dynamic type I4 */.(I4)
+//         switch p.(type) {
+//         case I4 /* ERROR cannot have dynamic type I4 */ :
+//         }
+// }
+
+// type assertions and type switches over generic types lead to errors for now
+
+func _[T any](x T) {
+	_ = x /* ERROR not an interface */ .(int)
+	switch x /* ERROR not an interface */ .(type) {
+	}
+
+	// work-around
+	var t interface{} = x
+	_ = t.(int)
+	switch t.(type) {
+	}
+}
+
+func _[T interface{type int}](x T) {
+	_ = x /* ERROR not an interface */ .(int)
+	switch x /* ERROR not an interface */ .(type) {
+	}
+
+	// work-around
+	var t interface{} = x
+	_ = t.(int)
+	switch t.(type) {
+	}
+}
+
+// error messages related to type bounds mention those bounds
+type C[P any] interface{}
+
+func _[P C[P]] (x P) {
+	x.m /* ERROR x.m undefined */ ()
+}
+
+type I interface {}
+
+func _[P I] (x P) {
+	x.m /* ERROR interface I has no method m */ ()
+}
+
+func _[P interface{}] (x P) {
+	x.m /* ERROR type bound for P has no method m */ ()
+}
+
+func _[P any] (x P) {
+	x.m /* ERROR type bound for P has no method m */ ()
+}
diff --git a/src/cmd/compile/internal/types2/testdata/check/vardecl.src b/src/cmd/compile/internal/types2/testdata/check/vardecl.src
new file mode 100644
index 0000000..9e48cdf
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/check/vardecl.src
@@ -0,0 +1,214 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vardecl
+
+// Prerequisites.
+import "math"
+func f() {}
+func g() (x, y int) { return }
+var m map[string]int
+
+// Var decls must have a type or an initializer.
+var _ int
+var _, _ int
+
+var _ /* ERROR "expecting type" */
+var _, _ /* ERROR "expecting type" */
+var _, _, _ /* ERROR "expecting type" */
+
+// The initializer must be an expression.
+var _ = int /* ERROR "not an expression" */
+var _ = f /* ERROR "used as value" */ ()
+
+// Identifier and expression arity must match.
+var _, _ = 1, 2
+var _ = 1, 2 /* ERROR "extra init expr 2" */
+var _, _ = 1 /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */
+var _, _, _ /* ERROR "missing init expr for _" */ = 1, 2
+
+var _ = g /* ERROR "2-valued g" */ ()
+var _, _ = g()
+var _, _, _ = g /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */ ()
+
+var _ = m["foo"]
+var _, _ = m["foo"]
+var _, _, _ = m  /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */ ["foo"]
+
+var _, _ int = 1, 2
+var _ int = 1, 2 /* ERROR "extra init expr 2" */
+var _, _ int = 1 /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */
+var _, _, _ /* ERROR "missing init expr for _" */ int = 1, 2
+
+var (
+	_, _ = 1, 2
+	_ = 1, 2 /* ERROR "extra init expr 2" */
+	_, _ = 1 /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */
+	_, _, _ /* ERROR "missing init expr for _" */ = 1, 2
+
+	_ = g /* ERROR "2-valued g" */ ()
+	_, _ = g()
+	_, _, _ = g /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */ ()
+
+	_ = m["foo"]
+	_, _ = m["foo"]
+	_, _, _ = m /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */ ["foo"]
+
+	_, _ int = 1, 2
+	_ int = 1, 2 /* ERROR "extra init expr 2" */
+	_, _ int = 1 /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */
+	_, _, _ /* ERROR "missing init expr for _" */ int = 1, 2
+)
+
+// Variables declared in function bodies must be 'used'.
+type T struct{}
+func (r T) _(a, b, c int) (u, v, w int) {
+	var x1 /* ERROR "declared but not used" */ int
+	var x2 /* ERROR "declared but not used" */ int
+	x1 = 1
+	(x2) = 2
+
+	y1 /* ERROR "declared but not used" */ := 1
+	y2 /* ERROR "declared but not used" */ := 2
+	y1 = 1
+	(y1) = 2
+
+	{
+		var x1 /* ERROR "declared but not used" */ int
+		var x2 /* ERROR "declared but not used" */ int
+		x1 = 1
+		(x2) = 2
+
+		y1 /* ERROR "declared but not used" */ := 1
+		y2 /* ERROR "declared but not used" */ := 2
+		y1 = 1
+		(y1) = 2
+	}
+
+	if x /* ERROR "declared but not used" */ := 0; a < b {}
+
+	switch x /* ERROR "declared but not used" */, y := 0, 1; a {
+	case 0:
+		_ = y
+	case 1:
+		x /* ERROR "declared but not used" */ := 0
+	}
+
+	var t interface{}
+	switch t /* ERROR "declared but not used" */ := t.(type) {}
+
+	switch t /* ERROR "declared but not used" */ := t.(type) {
+	case int:
+	}
+
+	switch t /* ERROR "declared but not used" */ := t.(type) {
+	case int:
+	case float32, complex64:
+		t = nil
+	}
+
+	switch t := t.(type) {
+	case int:
+	case float32, complex64:
+		_ = t
+	}
+
+	switch t := t.(type) {
+	case int:
+	case float32:
+	case string:
+		_ = func() string {
+			return t
+		}
+	}
+
+	switch t := t; t /* ERROR "declared but not used" */ := t.(type) {}
+
+	var z1 /* ERROR "declared but not used" */ int
+	var z2 int
+	_ = func(a, b, c int) (u, v, w int) {
+		z1 = a
+		(z1) = b
+		a = z2
+		return
+	}
+
+	var s []int
+	var i /* ERROR "declared but not used" */ , j int
+	for i, j = range s {
+		_ = j
+	}
+
+	for i, j /* ERROR "declared but not used" */ := range s {
+		_ = func() int {
+			return i
+		}
+	}
+	return
+}
+
+// Unused variables in function literals must lead to only one error (issue #22524).
+func _() {
+	_ = func() {
+		var x /* ERROR declared but not used */ int
+	}
+}
+
+// Invalid variable declarations must not lead to "declared but not used errors".
+func _() {
+	var a x                        // ERROR undeclared name: x
+	var b = x                      // ERROR undeclared name: x
+	var c int = x                  // ERROR undeclared name: x
+	var d, e, f x                  /* ERROR x */ /* ERROR x */ /* ERROR x */
+	var g, h, i = x, x, x          /* ERROR x */ /* ERROR x */ /* ERROR x */
+	var j, k, l float32 = x, x, x  /* ERROR x */ /* ERROR x */ /* ERROR x */
+	// but no "declared but not used" errors
+}
+
+// Invalid (unused) expressions must not lead to spurious "declared but not used errors".
+func _() {
+	var a, b, c int
+	var x, y int
+	x, y = a /* ERROR cannot assign [0-9]+ values to [0-9]+ variables */ , b, c
+	_ = x
+	_ = y
+}
+
+func _() {
+	var x int
+	return x /* ERROR no result values expected */
+	return math /* ERROR no result values expected */ .Sin(0)
+}
+
+func _() int {
+	var x, y int
+	return /* ERROR wrong number of return values */ x, y
+}
+
+// Short variable declarations must declare at least one new non-blank variable.
+func _() {
+	_ := /* ERROR no new variables */ 0
+	_, a := 0, 1
+	_, a := /* ERROR no new variables */ 0, 1
+	_, a, b := 0, 1, 2
+	_, _, _ := /* ERROR no new variables */ 0, 1, 2
+
+	_ = a
+	_ = b
+}
+
+// Test case for variables depending on function literals (see also #22992).
+var A /* ERROR initialization cycle */ = func() int { return A }()
+
+func _() {
+	// The function literal below must not see a.
+	var a = func() int { return a /* ERROR "undeclared name" */ }()
+	var _ = func() int { return a }()
+
+	// The function literal below must not see x, y, or z.
+	var x, y, z = 0, 1, func() int { return x /* ERROR "undeclared name" */ + y /* ERROR "undeclared name" */ + z /* ERROR "undeclared name" */ }()
+	_, _, _ = x, y, z
+}
+
+// TODO(gri) consolidate other var decl checks in this file
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/examples/functions.go2 b/src/cmd/compile/internal/types2/testdata/examples/functions.go2
new file mode 100644
index 0000000..0c2a408
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/examples/functions.go2
@@ -0,0 +1,215 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file shows some examples of type-parameterized functions.
+
+package p
+
+// Reverse is a generic function that takes a []T argument and
+// reverses that slice in place.
+func Reverse[T any](list []T) {
+	i := 0
+	j := len(list)-1
+	for i < j {
+		list[i], list[j] = list[j], list[i]
+		i++
+		j--
+	}
+}
+
+func _() {
+	// Reverse can be called with an explicit type argument.
+	Reverse[int](nil)
+	Reverse[string]([]string{"foo", "bar"})
+	Reverse[struct{x, y int}]([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})
+
+	// Since the type parameter is used for an incoming argument,
+	// it can be inferred from the provided argument's type.
+	Reverse([]string{"foo", "bar"})
+	Reverse([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})
+
+	// But the incoming argument must have a type, even if it's a
+	// default type. An untyped nil won't work.
+	// Reverse(nil) // this won't type-check
+
+	// A typed nil will work, though.
+	Reverse([]int(nil))
+}
+
+// Certain functions, such as the built-in `new` could be written using
+// type parameters.
+func new[T any]() *T {
+	var x T
+	return &x
+}
+
+// When calling our own `new`, we need to pass the type parameter
+// explicitly since there is no (value) argument from which the
+// result type could be inferred. We don't try to infer the
+// result type from the assignment to keep things simple and
+// easy to understand.
+var _ = new[int]()
+var _ *float64 = new[float64]() // the result type is indeed *float64
+
+// A function may have multiple type parameters, of course.
+func foo[A, B, C any](a A, b []B, c *C) B {
+	// do something here
+	return b[0]
+}
+
+// As before, we can pass type parameters explicitly.
+var s = foo[int, string, float64](1, []string{"first"}, new[float64]())
+
+// Or we can use type inference.
+var _ float64 = foo(42, []float64{1.0}, &s)
+
+// Type inference works in a straight-forward manner even
+// for variadic functions.
+func variadic[A, B any](A, B, ...B) int
+
+// var _ = variadic(1) // ERROR not enough arguments
+var _ = variadic(1, 2.3)
+var _ = variadic(1, 2.3, 3.4, 4.5)
+var _ = variadic[int, float64](1, 2.3, 3.4, 4)
+
+// Type inference also works in recursive function calls where
+// the inferred type is the type parameter of the caller.
+func f1[T any](x T) {
+	f1(x)
+}
+
+func f2a[T any](x, y T) {
+	f2a(x, y)
+}
+
+func f2b[T any](x, y T) {
+	f2b(y, x)
+}
+
+func g2a[P, Q any](x P, y Q) {
+	g2a(x, y)
+}
+
+func g2b[P, Q any](x P, y Q) {
+	g2b(y, x)
+}
+
+// Here's an example of a recursive function call with variadic
+// arguments and type inference inferring the type parameter of
+// the caller (i.e., itself).
+func max[T interface{ type int }](x ...T) T {
+	var x0 T
+	if len(x) > 0 {
+		x0 = x[0]
+	}
+	if len(x) > 1 {
+		x1 := max(x[1:]...)
+		if x1 > x0 {
+			return x1
+		}
+	}
+	return x0
+}
+
+// When inferring channel types, the channel direction is ignored
+// for the purpose of type inference. Once the type has been in-
+// fered, the usual parameter passing rules are applied.
+// Thus even if a type can be inferred successfully, the function
+// call may not be valid.
+
+func fboth[T any](chan T)
+func frecv[T any](<-chan T)
+func fsend[T any](chan<- T)
+
+func _() {
+	var both chan int
+	var recv <-chan int
+	var send chan<-int
+
+	fboth(both)
+	fboth(recv /* ERROR cannot use */ )
+	fboth(send /* ERROR cannot use */ )
+
+	frecv(both)
+	frecv(recv)
+	frecv(send /* ERROR cannot use */ )
+
+	fsend(both)
+	fsend(recv /* ERROR cannot use */)
+	fsend(send)
+}
+
+func ffboth[T any](func(chan T))
+func ffrecv[T any](func(<-chan T))
+func ffsend[T any](func(chan<- T))
+
+func _() {
+	var both func(chan int)
+	var recv func(<-chan int)
+	var send func(chan<- int)
+
+	ffboth(both)
+	ffboth(recv /* ERROR cannot use */ )
+	ffboth(send /* ERROR cannot use */ )
+
+	ffrecv(both /* ERROR cannot use */ )
+	ffrecv(recv)
+	ffrecv(send /* ERROR cannot use */ )
+
+	ffsend(both /* ERROR cannot use */ )
+	ffsend(recv /* ERROR cannot use */ )
+	ffsend(send)
+}
+
+// When inferring elements of unnamed composite parameter types,
+// if the arguments are defined types, use their underlying types.
+// Even though the matching types are not exactly structurally the
+// same (one is a type literal, the other a named type), because
+// assignment is permitted, parameter passing is permitted as well,
+// so type inference should be able to handle these cases well.
+
+func g1[T any]([]T)
+func g2[T any]([]T, T)
+func g3[T any](*T, ...T)
+
+func _() {
+	type intSlize []int
+	g1([]int{})
+	g1(intSlize{})
+	g2(nil, 0)
+
+	type myString string
+	var s1 string
+	g3(nil, "1", myString("2"), "3")
+	g3(&s1, "1", myString /* ERROR does not match */ ("2"), "3")
+	_ = s1
+
+	type myStruct struct{x int}
+	var s2 myStruct
+	g3(nil, struct{x int}{}, myStruct{})
+	g3(&s2, struct{x int}{}, myStruct{})
+	g3(nil, myStruct{}, struct{x int}{})
+	g3(&s2, myStruct{}, struct{x int}{})
+}
+
+// Here's a realistic example.
+
+func append[T any](s []T, t ...T) []T
+
+func _() {
+	var f func()
+	type Funcs []func()
+	var funcs Funcs
+	_ = append(funcs, f)
+}
+
+// Generic type declarations cannot have empty type parameter lists
+// (that would indicate a slice type). Thus, generic functions cannot
+// have empty type parameter lists, either. This is a syntax error.
+
+func h[] /* ERROR empty type parameter list */ ()
+
+func _() {
+	h[] /* ERROR operand */ ()
+}
diff --git a/src/cmd/compile/internal/types2/testdata/examples/inference.go2 b/src/cmd/compile/internal/types2/testdata/examples/inference.go2
new file mode 100644
index 0000000..b47ce75
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/examples/inference.go2
@@ -0,0 +1,101 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file shows some examples of type inference.
+
+package p
+
+type Ordered interface {
+	type int, float64, string
+}
+
+func min[T Ordered](x, y T) T
+
+func _() {
+	// min can be called with explicit instantiation.
+	_ = min[int](1, 2)
+
+	// Alternatively, the type argument can be inferred from
+	// one of the arguments. Untyped arguments will be considered
+	// last.
+	var x int
+	_ = min(x, x)
+	_ = min(x, 1)
+	_ = min(x, 1.0)
+	_ = min(1, 2)
+	_ = min(1, 2.3 /* ERROR default type float64 .* does not match */ )
+
+	var y float64
+	_ = min(1, y)
+	_ = min(1.2, y)
+	_ = min(1.2, 3.4)
+	_ = min(1.2, 3 /* ERROR default type int .* does not match */ )
+
+	var s string
+	_ = min(s, "foo")
+	_ = min("foo", "bar")
+}
+
+func mixed[T1, T2, T3 any](T1, T2, T3)
+
+func _() {
+	// mixed can be called with explicit instantiation.
+	mixed[int, string, bool](0, "", false)
+
+	// Alternatively, partial type arguments may be provided
+	// (from left to right), and the other may be inferred.
+	mixed[int, string](0, "", false)
+	mixed[int](0, "", false)
+	mixed(0, "", false)
+
+	// Provided type arguments always take precedence over
+	// inferred types.
+	mixed[int, string](1.1 /* ERROR cannot use 1.1 */ , "", false)
+}
+
+func related1[Slice interface{type []Elem}, Elem any](s Slice, e Elem)
+
+func _() {
+	// related1 can be called with explicit instantiation.
+	var si []int
+	related1[[]int, int](si, 0)
+
+	// Alternatively, the 2nd type argument can be inferred
+	// from the first one through constraint type inference.
+	var ss []string
+	_ = related1[[]string]
+	related1[[]string](ss, "foo")
+
+	// A type argument inferred from another explicitly provided
+	// type argument overrides whatever value argument type is given.
+	related1[[]string](ss, 0 /* ERROR cannot use 0 */ )
+
+	// A type argument may be inferred from a value argument
+	// and then help infer another type argument via constraint
+	// type inference.
+	related1(si, 0)
+	related1(si, "foo" /* ERROR cannot use "foo" */ )
+}
+
+func related2[Elem any, Slice interface{type []Elem}](e Elem, s Slice)
+
+func _() {
+	// related2 can be called with explicit instantiation.
+	var si []int
+	related2[int, []int](0, si)
+
+	// Alternatively, the 2nd type argument can be inferred
+	// from the first one through constraint type inference.
+	var ss []string
+	_ = related2[string]
+	related2[string]("foo", ss)
+
+	// A type argument may be inferred from a value argument
+	// and then help infer another type argument via constraint
+	// type inference. Untyped arguments are always considered
+	// last.
+	related2(1.2, []float64{})
+	related2(1.0, []int{})
+	related2( /* ERROR does not satisfy */ float64(1.0), []int{}) // TODO(gri) fix error position
+}
diff --git a/src/cmd/compile/internal/types2/testdata/examples/methods.go2 b/src/cmd/compile/internal/types2/testdata/examples/methods.go2
new file mode 100644
index 0000000..76c6539
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/examples/methods.go2
@@ -0,0 +1,96 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file shows some examples of methods on type-parameterized types.
+
+package p
+
+// Parameterized types may have methods.
+type T1[A any] struct{ a A }
+
+// When declaring a method for a parameterized type, the "instantiated"
+// receiver type acts as an implicit declaration of the type parameters
+// for the receiver type. In the example below, method m1 on type T1 has
+// the receiver type T1[A] which declares the type parameter A for use
+// with this method. That is, within the method m1, A stands for the
+// actual type argument provided to an instantiated T1.
+func (t T1[A]) m1() A { return t.a }
+
+// For instance, if T1 is instantiated with the type int, the type
+// parameter A in m1 assumes that type (int) as well and we can write
+// code like this:
+var x T1[int]
+var _ int = x.m1()
+
+// Because the type parameter provided to a parameterized receiver type
+// is declared through that receiver declaration, it must be an identifier.
+// It cannot possibly be some other type because the receiver type is not
+// instantiated with concrete types, it is standing for the parameterized
+// receiver type.
+func (t T1[[ /* ERROR must be an identifier */ ]int]) m2() {}
+
+// Note that using what looks like a predeclared identifier, say int,
+// as type parameter in this situation is deceptive and considered bad
+// style. In m3 below, int is the name of the local receiver type parameter
+// and it shadows the predeclared identifier int which then cannot be used
+// anymore as expected.
+// This is no different from locally redelaring a predeclared identifier
+// and usually should be avoided. There are some notable exceptions; e.g.,
+// sometimes it makes sense to use the identifier "copy" which happens to
+// also be the name of a predeclared built-in function.
+func (t T1[int]) m3() { var _ int = 42 /* ERROR cannot use 42 .* as int */ }
+
+// The names of the type parameters used in a parameterized receiver
+// type don't have to match the type parameter names in the declaration
+// of the type used for the receiver. In our example, even though T1 is
+// declared with type parameter named A, methods using that receiver type
+// are free to use their own name for that type parameter. That is, the
+// name of type parameters is always local to the declaration where they
+// are introduced. In our example we can write a method m2 and use the
+// name X instead of A for the type parameter w/o any difference.
+func (t T1[X]) m4() X { return t.a }
+
+// If the receiver type is parameterized, type parameters must always be
+// provided: this simply follows from the general rule that a parameterized
+// type must be instantiated before it can be used. A method receiver
+// declaration using a parameterized receiver type is no exception. It is
+// simply that such receiver type expressions perform two tasks simultaneously:
+// they declare the (local) type parameters and then use them to instantiate
+// the receiver type. Forgetting to provide a type parameter leads to an error.
+func (t T1 /* ERROR generic type .* without instantiation */ ) m5() {}
+
+// However, sometimes we don't need the type parameter, and thus it is
+// inconvenient to have to choose a name. Since the receiver type expression
+// serves as a declaration for its type parameters, we are free to choose the
+// blank identifier:
+func (t T1[_]) m6() {}
+
+// Naturally, these rules apply to any number of type parameters on the receiver
+// type. Here are some more complex examples.
+type T2[A, B, C any] struct {
+        a A
+        b B
+        c C
+}
+
+// Naming of the type parameters is local and has no semantic impact:
+func (t T2[A, B, C]) m1() (A, B, C) { return t.a, t.b, t.c }
+func (t T2[C, B, A]) m2() (C, B, A) { return t.a, t.b, t.c }
+func (t T2[X, Y, Z]) m3() (X, Y, Z) { return t.a, t.b, t.c }
+
+// Type parameters may be left blank if they are not needed:
+func (t T2[A, _, C]) m4() (A, C) { return t.a, t.c }
+func (t T2[_, _, X]) m5() X { return t.c }
+func (t T2[_, _, _]) m6() {}
+
+// As usual, blank names may be used for any object which we don't care about
+// using later. For instance, we may write an unnamed method with a receiver
+// that cannot be accessed:
+func (_ T2[_, _, _]) _() int { return 42 }
+
+// Because a receiver parameter list is simply a parameter list, we can
+// leave the receiver argument away for receiver types.
+type T0 struct{}
+func (T0) _() {}
+func (T1[A]) _() {}
diff --git a/src/cmd/compile/internal/types2/testdata/examples/types.go2 b/src/cmd/compile/internal/types2/testdata/examples/types.go2
new file mode 100644
index 0000000..a7825ed
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/examples/types.go2
@@ -0,0 +1,279 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file shows some examples of generic types.
+
+package p
+
+// List is just what it says - a slice of E elements.
+type List[E any] []E
+
+// A generic (parameterized) type must always be instantiated
+// before it can be used to designate the type of a variable
+// (including a struct field, or function parameter); though
+// for the latter cases, the provided type may be another type
+// parameter. So:
+var _ List[byte] = []byte{}
+
+// A generic binary tree might be declared as follows.
+type Tree[E any] struct {
+	left, right *Tree[E]
+	payload E
+}
+
+// A simple instantiation of Tree:
+var root1 Tree[int]
+
+// The actual type parameter provided may be a generic type itself:
+var root2 Tree[List[int]]
+
+// A couple of more complex examples.
+// We don't need extra parentheses around the element type of the slices on
+// the right (unlike when we use ()'s rather than []'s for type parameters).
+var _ List[List[int]] = []List[int]{}
+var _ List[List[List[Tree[int]]]] = []List[List[Tree[int]]]{}
+
+// Type parameters act like type aliases when used in generic types
+// in the sense that we can "emulate" a specific type instantiation
+// with type aliases.
+type T1[P any] struct {
+	f P
+}
+
+type T2[P any] struct {
+	f struct {
+		g P
+	}
+}
+
+var x1 T1[struct{ g int }]
+var x2 T2[int]
+
+func _() {
+	// This assignment is invalid because the types of x1, x2 are T1(...)
+	// and T2(...) respectively, which are two different defined types.
+	x1 = x2 // ERROR assignment
+
+	// This assignment is valid because the types of x1.f and x2.f are
+	// both struct { g int }; the type parameters act like type aliases
+	// and their actual names don't come into play here.
+	x1.f = x2.f
+}
+
+// We can verify this behavior using type aliases instead:
+type T1a struct {
+	f A1
+}
+type A1 = struct { g int }
+
+type T2a struct {
+	f struct {
+		g A2
+	}
+}
+type A2 = int
+
+var x1a T1a
+var x2a T2a
+
+func _() {
+	x1a = x2a // ERROR assignment
+	x1a.f = x2a.f
+}
+
+// Another interesting corner case are generic types that don't use
+// their type arguments. For instance:
+type T[P any] struct{}
+
+var xint T[int]
+var xbool T[bool]
+
+// Are these two variables of the same type? After all, their underlying
+// types are identical. We consider them to be different because each type
+// instantiation creates a new named type, in this case T<int> and T<bool>
+// even if their underlying types are identical. This is sensible because
+// we might still have methods that have different signatures or behave
+// differently depending on the type arguments, and thus we can't possibly
+// consider such types identical. Consequently:
+func _() {
+	xint = xbool // ERROR assignment
+}
+
+// Generic types cannot be used without instantiation.
+var _ T // ERROR cannot use generic type T
+
+// In type context, generic (parameterized) types cannot be parenthesized before
+// being instantiated. See also NOTES entry from 12/4/2019.
+var _ (T /* ERROR cannot use generic type T */ )[ /* ERROR unexpected \[ */ int]
+
+// All types may be parameterized, including interfaces.
+type I1[T any] interface{
+	m1(T)
+}
+
+// There is no such thing as a variadic generic type.
+type _[T ... /* ERROR invalid use of ... */ interface{}] struct{}
+
+// Generic interfaces may be embedded as one would expect.
+type I2 interface {
+	I1(int)     // method!
+	I1[string]  // embedded I1
+}
+
+func _() {
+	var x I2
+	x.I1(0)
+	x.m1("foo")
+}
+
+type I0 interface {
+	m0()
+}
+
+type I3 interface {
+	I0
+	I1[bool]
+	m(string)
+}
+
+func _() {
+	var x I3
+	x.m0()
+	x.m1(true)
+	x.m("foo")
+}
+
+type _ struct {
+	( /* ERROR cannot parenthesize */ int8)
+	( /* ERROR cannot parenthesize */ *int16)
+	*( /* ERROR cannot parenthesize */ int32)
+	List[int]
+
+	int8 /* ERROR int8 redeclared */
+	* /* ERROR int16 redeclared */ int16
+	List /* ERROR List redeclared */ [int]
+}
+
+// It's possible to declare local types whose underlying types
+// are type parameters. As with ordinary type definitions, the
+// types underlying properties are "inherited" but the methods
+// are not.
+func _[T interface{ m(); type int }]() {
+	type L T
+	var x L
+
+	// m is not defined on L (it is not "inherited" from
+	// its underlying type).
+	x.m /* ERROR x.m undefined */ ()
+
+	// But the properties of T, such that as that it supports
+	// the operations of the types given by its type bound,
+	// are also the properties of L.
+	x++
+	_ = x - x
+
+	// On the other hand, if we define a local alias for T,
+	// that alias stands for T as expected.
+	type A = T
+	var y A
+	y.m()
+	_ = y < 0
+}
+
+// As a special case, an explicit type argument may be omitted
+// from a type parameter bound if the type bound expects exactly
+// one type argument. In that case, the type argument is the
+// respective type parameter to which the type bound applies.
+// Note: We may not permit this syntactic sugar at first.
+// Note: This is now disabled. All examples below are adjusted.
+type Adder[T any] interface {
+	Add(T) T
+}
+
+// We don't need to explicitly instantiate the Adder bound
+// if we have exactly one type parameter.
+func Sum[T Adder[T]](list []T) T {
+	var sum T
+	for _, x := range list {
+		sum = sum.Add(x)
+	}
+	return sum
+}
+
+// Valid and invalid variations.
+type B0 interface {}
+type B1[_ any] interface{}
+type B2[_, _ any] interface{}
+
+func _[T1 B0]()
+func _[T1 B1[T1]]()
+func _[T1 B2 /* ERROR cannot use generic type .* without instantiation */ ]()
+
+func _[T1, T2 B0]()
+func _[T1 B1[T1], T2 B1[T2]]()
+func _[T1, T2 B2 /* ERROR cannot use generic type .* without instantiation */ ]()
+
+func _[T1 B0, T2 B1[T2]]() // here B1 applies to T2
+
+// When the type argument is left away, the type bound is
+// instantiated for each type parameter with that type
+// parameter.
+// Note: We may not permit this syntactic sugar at first.
+func _[A Adder[A], B Adder[B], C Adder[A]]() {
+	var a A // A's type bound is Adder[A]
+	a = a.Add(a)
+	var b B // B's type bound is Adder[B]
+	b = b.Add(b)
+	var c C // C's type bound is Adder[A]
+	a = c.Add(a)
+}
+
+// The type of variables (incl. parameters and return values) cannot
+// be an interface with type constraints or be/embed comparable.
+type I interface {
+	type int
+}
+
+var (
+	_ interface /* ERROR contains type constraints */ {type int}
+	_ I /* ERROR contains type constraints */
+)
+
+func _(I /* ERROR contains type constraints */ )
+func _(x, y, z I /* ERROR contains type constraints */ )
+func _() I /* ERROR contains type constraints */
+
+func _() {
+	var _ I /* ERROR contains type constraints */
+}
+
+type C interface {
+	comparable
+}
+
+var _ comparable /* ERROR comparable */
+var _ C /* ERROR comparable */
+
+func _(_ comparable /* ERROR comparable */ , _ C /* ERROR comparable */ )
+
+func _() {
+	var _ comparable /* ERROR comparable */
+	var _ C /* ERROR comparable */
+}
+
+// Type parameters are never const types, i.e., it's
+// not possible to declare a constant of type parameter type.
+// (If a type list contains just a single const type, we could
+// allow it, but such type lists don't make much sense in the
+// first place.)
+func _[T interface { type int, float64 }]() {
+	// not valid
+	const _ = T /* ERROR not constant */ (0)
+	const _ T /* ERROR invalid constant type T */ = 1
+
+	// valid
+	var _ = T(0)
+	var _ T = 1
+	_ = T(0)
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue20583.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue20583.src
new file mode 100644
index 0000000..85f11ec
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue20583.src
@@ -0,0 +1,12 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue20583
+const (
+	_ = 6e886451608 /* ERROR malformed constant */ /2
+	_ = 6e886451608i /* ERROR malformed constant */ /2
+	_ = 0 * 1e+1000000000 // ERROR malformed constant
+	x = 1e100000000
+	_ = x*x*x*x*x*x* /* ERROR not representable */ x
+)
diff --git a/src/go/types/fixedbugs/issue23203a.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue23203a.src
similarity index 100%
copy from src/go/types/fixedbugs/issue23203a.src
copy to src/cmd/compile/internal/types2/testdata/fixedbugs/issue23203a.src
diff --git a/src/go/types/fixedbugs/issue23203b.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue23203b.src
similarity index 100%
copy from src/go/types/fixedbugs/issue23203b.src
copy to src/cmd/compile/internal/types2/testdata/fixedbugs/issue23203b.src
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue26390.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue26390.src
new file mode 100644
index 0000000..b8e67e9
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue26390.src
@@ -0,0 +1,11 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue26390
+
+type A = T
+
+func (t *T) m() *A { return t }
+
+type T struct{}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue28251.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue28251.src
new file mode 100644
index 0000000..ef5e61d
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue28251.src
@@ -0,0 +1,65 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains test cases for various forms of
+// method receiver declarations, per the spec clarification
+// https://golang.org/cl/142757.
+
+package issue28251
+
+// test case from issue28251
+type T struct{}
+
+type T0 = *T
+
+func (T0) m() {}
+
+func _() { (&T{}).m() }
+
+// various alternative forms
+type (
+        T1 = (((T)))
+)
+
+func ((*(T1))) m1() {}
+func _() { (T{}).m2() }
+func _() { (&T{}).m2() }
+
+type (
+        T2 = (((T3)))
+        T3 = T
+)
+
+func (T2) m2() {}
+func _() { (T{}).m2() }
+func _() { (&T{}).m2() }
+
+type (
+        T4 = ((*(T5)))
+        T5 = T
+)
+
+func (T4) m4() {}
+func _() { (T{}).m4 /* ERROR "cannot call pointer method m4 on T" */ () }
+func _() { (&T{}).m4() }
+
+type (
+        T6 = (((T7)))
+        T7 = (*(T8))
+        T8 = T
+)
+
+func (T6) m6() {}
+func _() { (T{}).m6 /* ERROR "cannot call pointer method m6 on T" */ () }
+func _() { (&T{}).m6() }
+
+type (
+        T9 = *T10
+        T10 = *T11
+        T11 = T
+)
+
+func (T9 /* ERROR invalid receiver type \*\*T */ ) m9() {}
+func _() { (T{}).m9 /* ERROR has no field or method m9 */ () }
+func _() { (&T{}).m9 /* ERROR has no field or method m9 */ () }
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39634.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39634.go2
new file mode 100644
index 0000000..2c1299f
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39634.go2
@@ -0,0 +1,91 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Examples adjusted to match new [T any] syntax for type parameters.
+// Also, previously permitted empty type parameter lists and instantiations
+// are now syntax errors.
+
+package p
+
+// crash 1
+type nt1[_ any]interface{g /* ERROR undeclared name */ }
+type ph1[e nt1[e],g(d /* ERROR undeclared name */ )]s /* ERROR undeclared name */
+func(*ph1[e,e /* ERROR redeclared */ ])h(d /* ERROR undeclared name */ )
+
+// crash 2
+// Disabled: empty []'s are now syntax errors. This example leads to too many follow-on errors.
+// type Numeric2 interface{t2 /* ERROR not a type */ }
+// func t2[T Numeric2](s[]T){0 /* ERROR not a type */ []{s /* ERROR cannot index */ [0][0]}}
+
+// crash 3
+type t3 *interface{ t3.p /* ERROR no field or method p */ }
+
+// crash 4
+type Numeric4 interface{t4 /* ERROR not a type */ }
+func t4[T Numeric4](s[]T){if( /* ERROR non-boolean */ 0){*s /* ERROR cannot indirect */ [0]}}
+
+// crash 7
+type foo7 interface { bar() }
+type x7[A any] struct{ foo7 }
+func main7() { var _ foo7 = x7[int]{} }
+
+// crash 8
+type foo8[A any] interface { type A }
+func bar8[A foo8[A]](a A) {}
+func main8() {}
+
+// crash 9
+type foo9[A any] interface { type foo9 /* ERROR interface contains type constraints */ [A] }
+func _() { var _ = new(foo9 /* ERROR interface contains type constraints */ [int]) }
+
+// crash 12
+var u /* ERROR cycle */ , i [func /* ERROR used as value */ /* ERROR used as value */ (u, c /* ERROR undeclared */ /* ERROR undeclared */ ) {}(0, len /* ERROR must be called */ /* ERROR must be called */ )]c /* ERROR undeclared */ /* ERROR undeclared */
+
+// crash 15
+func y15() { var a /* ERROR declared but not used */ interface{ p() } = G15[string]{} }
+type G15[X any] s /* ERROR undeclared name */
+func (G15 /* ERROR generic type .* without instantiation */ ) p()
+
+// crash 16
+type Foo16[T any] r16 /* ERROR not a type */
+func r16[T any]() Foo16[Foo16[T]]
+
+// crash 17
+type Y17 interface{ c() }
+type Z17 interface {
+	c() Y17
+	Y17 /* ERROR duplicate method */
+}
+func F17[T Z17](T)
+
+// crash 18
+type o18[T any] []func(_ o18[[]_ /* ERROR cannot use _ */ ])
+
+// crash 19
+type Z19 [][[]Z19{}[0][0]]c19 /* ERROR undeclared */
+
+// crash 20
+type Z20 /* ERROR illegal cycle */ interface{ Z20 }
+func F20[t Z20]() { F20(t /* ERROR invalid composite literal type */ {}) }
+
+// crash 21
+type Z21 /* ERROR illegal cycle */ interface{ Z21 }
+func F21[T Z21]() { ( /* ERROR not used */ F21[Z21]) }
+
+// crash 24
+type T24[P any] P
+func (r T24[P]) m() { T24 /* ERROR without instantiation */ .m() }
+
+// crash 25
+type T25[A any] int
+func (t T25[A]) m1() {}
+var x T25 /* ERROR without instantiation */ .m1
+
+// crash 26
+type T26 = interface{ F26[ /* ERROR cannot have type parameters */ Z any]() }
+func F26[Z any]() T26 { return F26 /* ERROR without instantiation */ /* ERROR missing method */ [] /* ERROR operand */ }
+
+// crash 27
+func e27[T any]() interface{ x27 /* ERROR not a type */ }
+func x27() { e27( /* ERROR cannot infer T */ ) }
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39664.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39664.go2
new file mode 100644
index 0000000..3b3ec56
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39664.go2
@@ -0,0 +1,15 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T[_ any] struct {}
+
+func (T /* ERROR instantiation */ ) m()
+
+func _() {
+	var x interface { m() }
+	x = T[int]{}
+	_ = x
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39680.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39680.go2
new file mode 100644
index 0000000..9bc26f3
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39680.go2
@@ -0,0 +1,27 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "fmt"
+
+// Minimal test case.
+func _[T interface{type T}](x T) T{
+	return x
+}
+
+// Test case from issue.
+type constr[T any] interface {
+	type T
+}
+
+func Print[T constr[T]](s []T) {
+	for _, v := range s {
+		fmt.Print(v)
+	}
+}
+
+func f() {
+	Print([]string{"Hello, ", "playground\n"})
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39693.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39693.go2
new file mode 100644
index 0000000..316ab19
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39693.go2
@@ -0,0 +1,14 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type Number interface {
+	int     /* ERROR int is not an interface */
+	float64 /* ERROR float64 is not an interface */
+}
+
+func Add[T Number](a, b T) T {
+	return a /* ERROR not defined */ + b
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39699.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39699.go2
new file mode 100644
index 0000000..75491e7
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39699.go2
@@ -0,0 +1,29 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T0 interface{
+}
+
+type T1 interface{
+	type int
+}
+
+type T2 interface{
+	comparable
+}
+
+type T3 interface {
+	T0
+	T1
+	T2
+}
+
+func _() {
+	_ = T0(0)
+	_ = T1 /* ERROR cannot use interface T1 in conversion */ (1)
+	_ = T2 /* ERROR cannot use interface T2 in conversion */ (2)
+	_ = T3 /* ERROR cannot use interface T3 in conversion */ (3)
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39711.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39711.go2
new file mode 100644
index 0000000..df621a4
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39711.go2
@@ -0,0 +1,11 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// Do not report a duplicate type error for this type list.
+// (Check types after interfaces have been completed.)
+type _ interface {
+	type interface{ Error() string }, interface{ String() string }
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39723.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39723.go2
new file mode 100644
index 0000000..55464e6
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39723.go2
@@ -0,0 +1,9 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// A constraint must be an interface; it cannot
+// be a type parameter, for instance.
+func _[A interface{ type interface{} }, B A /* ERROR not an interface */ ]()
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39725.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39725.go2
new file mode 100644
index 0000000..e19b677
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39725.go2
@@ -0,0 +1,16 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f1[T1, T2 any](T1, T2, struct{a T1; b T2})
+func _() {
+	f1(42, string("foo"), struct /* ERROR does not match inferred type struct\{a int; b string\} */ {a, b int}{})
+}
+
+// simplified test case from issue
+func f2[T any](_ []T, _ func(T))
+func _() {
+	f2([]string{}, func /* ERROR does not match inferred type func\(string\) */ (f []byte) {})
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39754.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39754.go2
new file mode 100644
index 0000000..f70b8d0
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39754.go2
@@ -0,0 +1,23 @@
+// Copyright 2020 The Go Authors. All rights reserved.

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

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

+

+package p

+

+type Optional[T any] struct {}

+

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

+

+type Box[T any] interface {

+	Val() (T, bool)

+}

+

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

+

+func _() {

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

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

+	// TODO(gri) Provide better position information here.

+	//           See TODO in call.go, Checker.arguments.

+	f[int, Optional[int], Optional[string]]( /* ERROR does not satisfy Box */ )

+}

diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39755.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39755.go2
new file mode 100644
index 0000000..b7ab688
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39755.go2
@@ -0,0 +1,23 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _[T interface{type map[string]int}](x T) {
+	_ = x == nil
+}
+
+// simplified test case from issue
+
+type PathParamsConstraint interface {
+        type map[string]string, []struct{key, value string}
+}
+
+type PathParams[T PathParamsConstraint] struct {
+	t T
+}
+
+func (pp *PathParams[T]) IsNil() bool {
+	return pp.t == nil // this must succeed
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39768.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39768.go2
new file mode 100644
index 0000000..abac141
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39768.go2
@@ -0,0 +1,20 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T[P any] P
+type A = T
+var x A[int]
+var _ A /* ERROR cannot use generic type */
+
+type B = T[int]
+var y B = x
+var _ B /* ERROR not a generic type */ [int]
+
+// test case from issue
+
+type Vector[T any] []T
+type VectorAlias = Vector
+var v Vector[int]
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39938.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39938.go2
new file mode 100644
index 0000000..76e7e36
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39938.go2
@@ -0,0 +1,50 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check "infinite expansion" cycle errors across instantiated types.
+
+package p
+
+type E0[P any] P
+type E1[P any] *P
+type E2[P any] struct{ P }
+type E3[P any] struct{ *P }
+
+type T0 /* ERROR illegal cycle */ struct {
+        _ E0[T0]
+}
+
+type T0_ /* ERROR illegal cycle */ struct {
+        E0[T0_]
+}
+
+type T1 struct {
+        _ E1[T1]
+}
+
+type T2 /* ERROR illegal cycle */ struct {
+        _ E2[T2]
+}
+
+type T3 struct {
+        _ E3[T3]
+}
+
+// some more complex cases
+
+type T4 /* ERROR illegal cycle */ struct {
+	_ E0[E2[T4]]
+}
+
+type T5 struct {
+	_ E0[E2[E0[E1[E2[[10]T5]]]]]
+}
+
+type T6 /* ERROR illegal cycle */ struct {
+	_ E0[[10]E2[E0[E2[E2[T6]]]]]
+}
+
+type T7 struct {
+	_ E0[[]E2[E0[E2[E2[T6]]]]]
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go2
new file mode 100644
index 0000000..c2b4609
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go2
@@ -0,0 +1,9 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T[P any] interface{
+	P // ERROR P is a type parameter, not an interface
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39976.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39976.go2
new file mode 100644
index 0000000..3db4eae
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39976.go2
@@ -0,0 +1,16 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type policy[K, V any] interface{}
+type LRU[K, V any] struct{}
+
+func NewCache[K, V any](p policy[K, V])
+
+func _() {
+	var lru LRU[int, string]
+	NewCache[int, string](&lru)
+	NewCache(& /* ERROR does not match policy\[K, V\] \(cannot infer K and V\) */ lru)
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39982.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39982.go2
new file mode 100644
index 0000000..9810b63
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39982.go2
@@ -0,0 +1,36 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type (
+	T[_ any] struct{}
+	S[_ any] struct {
+		data T[*T[int]]
+	}
+)
+
+func _() {
+	_ = S[int]{
+		data: T[*T[int]]{},
+	}
+}
+
+// full test case from issue
+
+type (
+	Element[TElem any] struct{}
+
+	entry[K comparable] struct{}
+
+	Cache[K comparable] struct {
+		data map[K]*Element[*entry[K]]
+	}
+)
+
+func _() {
+	_ = Cache[int]{
+		data: make(map[int](*Element[*entry[int]])),
+	}
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40038.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40038.go2
new file mode 100644
index 0000000..8948d61
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40038.go2
@@ -0,0 +1,15 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type A[T any] int
+
+func (A[T]) m(A[T])
+
+func f[P interface{m(P)}]()
+
+func _() {
+	_ = f[A[int]]
+}
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40056.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40056.go2
new file mode 100644
index 0000000..747aab4
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40056.go2
@@ -0,0 +1,15 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _() {
+	NewS( /* ERROR cannot infer T */ ) .M()
+}
+
+type S struct {}
+
+func NewS[T any]() *S
+
+func (_ *S /* ERROR S is not a generic type */ [T]) M()
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40057.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40057.go2
new file mode 100644
index 0000000..fdc8fb1
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40057.go2
@@ -0,0 +1,17 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _() {
+	var x interface{}
+	switch t := x.(type) {
+	case S /* ERROR cannot use generic type */ :
+		t.m()
+	}
+}
+
+type S[T any] struct {}
+
+func (_ S[T]) m()
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40301.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40301.go2
new file mode 100644
index 0000000..5d97855
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40301.go2
@@ -0,0 +1,12 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "unsafe"
+
+func _[T any](x T) {
+	_ = unsafe /* ERROR undefined */ .Alignof(x)
+	_ = unsafe /* ERROR undefined */ .Sizeof(x)
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40684.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40684.go2
new file mode 100644
index 0000000..0269c3a
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40684.go2
@@ -0,0 +1,15 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T[_ any] int
+
+func f[_ any]()
+func g[_, _ any]()
+
+func _() {
+	_ = f[T /* ERROR without instantiation */ ]
+	_ = g[T /* ERROR without instantiation */ , T /* ERROR without instantiation */ ]
+}
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue41124.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue41124.go2
new file mode 100644
index 0000000..61f766b
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue41124.go2
@@ -0,0 +1,91 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// Test case from issue.
+
+type Nat interface {
+	type Zero, Succ
+}
+
+type Zero struct{}
+type Succ struct{
+	Nat // ERROR interface contains type constraints
+}
+
+// Struct tests.
+
+type I1 interface {
+	comparable
+}
+
+type I2 interface {
+	type int
+}
+
+type I3 interface {
+	I1
+	I2
+}
+
+type _ struct {
+	f I1 // ERROR interface is .* comparable
+}
+
+type _ struct {
+	comparable // ERROR interface is .* comparable
+}
+
+type _ struct{
+	I1 // ERROR interface is .* comparable
+}
+
+type _ struct{
+	I2 // ERROR interface contains type constraints
+}
+
+type _ struct{
+	I3 // ERROR interface contains type constraints
+}
+
+// General composite types.
+
+type (
+	_ [10]I1 // ERROR interface is .* comparable
+	_ [10]I2 // ERROR interface contains type constraints
+
+	_ []I1 // ERROR interface is .* comparable
+	_ []I2 // ERROR interface contains type constraints
+
+	_ *I3 // ERROR interface contains type constraints
+	_ map[I1 /* ERROR interface is .* comparable */ ]I2 // ERROR interface contains type constraints
+	_ chan I3 // ERROR interface contains type constraints
+	_ func(I1 /* ERROR interface is .* comparable */ )
+	_ func() I2 // ERROR interface contains type constraints
+)
+
+// Other cases.
+
+var _ = [...]I3 /* ERROR interface contains type constraints */ {}
+
+func _(x interface{}) {
+	_ = x.(I3 /* ERROR interface contains type constraints */ )
+}
+
+type T1[_ any] struct{}
+type T3[_, _, _ any] struct{}
+var _ T1[I2 /* ERROR interface contains type constraints */ ]
+var _ T3[int, I2 /* ERROR interface contains type constraints */ , float32]
+
+func f1[_ any]() int
+var _ = f1[I2 /* ERROR interface contains type constraints */ ]()
+func f3[_, _, _ any]() int
+var _ = f3[int, I2 /* ERROR interface contains type constraints */ , float32]()
+
+func _(x interface{}) {
+	switch x.(type) {
+	case I2 /* ERROR interface contains type constraints */ :
+	}
+}
diff --git a/src/go/types/fixedbugs/issue42695.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42695.src
similarity index 100%
copy from src/go/types/fixedbugs/issue42695.src
copy to src/cmd/compile/internal/types2/testdata/fixedbugs/issue42695.src
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42758.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42758.go2
new file mode 100644
index 0000000..698cb8a
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42758.go2
@@ -0,0 +1,33 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _[T any](x interface{}){
+	switch x.(type) {
+	case T: // ok to use a type parameter
+	case int:
+	}
+
+	switch x.(type) {
+	case T:
+	case T /* ERROR duplicate case */ :
+	}
+}
+
+type constraint interface {
+	type int
+}
+
+func _[T constraint](x interface{}){
+	switch x.(type) {
+	case T: // ok to use a type parameter even if type list contains int
+	case int:
+	}
+}
+
+func _(x constraint /* ERROR contains type constraints */ ) {
+	switch x /* ERROR contains type constraints */ .(type) {
+	}
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42987.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42987.src
new file mode 100644
index 0000000..8aa3544
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42987.src
@@ -0,0 +1,8 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check that there is only one error (no follow-on errors).
+
+package p
+var _ = [ /* ERROR invalid use of .* array */ ...]byte("foo")
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43087.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43087.src
new file mode 100644
index 0000000..85d4450
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43087.src
@@ -0,0 +1,43 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _() {
+	a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3
+	_ = a
+	_ = b
+}
+
+func _() {
+	a, _, _ := 1, 2, 3 // multiple _'s ok
+	_ = a
+}
+
+func _() {
+	var b int
+	a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3
+	_ = a
+	_ = b
+}
+
+func _() {
+	var a []int
+	a /* ERROR non-name .* on left side of := */ [0], b := 1, 2
+	_ = a
+	_ = b
+}
+
+func _() {
+	var a int
+	a, a /* ERROR a repeated on left side of := */ := 1, 2
+	_ = a
+}
+
+func _() {
+	var a, b int
+	a, b := /* ERROR no new variables on left side of := */ 1, 2
+	_ = a
+	_ = b
+}
diff --git a/src/go/types/fixedbugs/issue43110.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43110.src
similarity index 100%
copy from src/go/types/fixedbugs/issue43110.src
copy to src/cmd/compile/internal/types2/testdata/fixedbugs/issue43110.src
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43124.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43124.src
new file mode 100644
index 0000000..7e48c22
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43124.src
@@ -0,0 +1,16 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+var _ = int(0 /* ERROR invalid use of \.\.\. in type conversion */ ...)
+
+// test case from issue
+
+type M []string
+
+var (
+	x = []string{"a", "b"}
+	_ = M(x /* ERROR invalid use of \.\.\. in type conversion */ ...)
+)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43125.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43125.src
new file mode 100644
index 0000000..c2bd970
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43125.src
@@ -0,0 +1,8 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+var _ = new(- /* ERROR not a type */ 1)
+var _ = new(1 /* ERROR not a type */ + 1)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43190.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43190.src
new file mode 100644
index 0000000..ae42719
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43190.src
@@ -0,0 +1,19 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import ; // ERROR missing import path
+import
+var /* ERROR missing import path */ _ int
+import .; // ERROR missing import path
+
+import ()
+import (.) // ERROR missing import path
+import (
+	"fmt"
+	.
+) // ERROR missing import path
+
+var _ = fmt.Println // avoid imported but not used error
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue44688.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue44688.go2
new file mode 100644
index 0000000..512bfcc
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue44688.go2
@@ -0,0 +1,83 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package P
+
+type A1[T any] struct{}
+
+func (*A1[T]) m1(T) {}
+
+type A2[T any] interface {
+	m2(T)
+}
+
+type B1[T any] struct {
+	filler int
+	*A1[T]
+	A2[T]
+}
+
+type B2[T any] interface {
+	A2[T]
+}
+
+type C[T any] struct {
+	filler1 int
+	filler2 int
+	B1[T]
+}
+
+type D[T any] struct {
+	filler1 int
+	filler2 int
+	filler3 int
+	C[T]
+}
+
+func _() {
+	// calling embedded methods
+	var b1 B1[string]
+
+	b1.A1.m1("")
+	b1.m1("")
+
+	b1.A2.m2("")
+	b1.m2("")
+
+	var b2 B2[string]
+	b2.m2("")
+
+	// a deeper nesting
+	var d D[string]
+	d.m1("")
+	d.m2("")
+
+	// calling method expressions
+	m1x := B1[string].m1
+	m1x(b1, "")
+	m2x := B2[string].m2
+	m2x(b2, "")
+
+	// calling method values
+	m1v := b1.m1
+	m1v("")
+	m2v := b1.m2
+	m2v("")
+	b2v := b2.m2
+	b2v("")
+}
+
+// actual test case from issue
+
+type A[T any] struct{}
+
+func (*A[T]) f(T) {}
+
+type B[T any] struct{ A[T] }
+
+func _() {
+	var b B[string]
+	b.A.f("")
+	b.f("")
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue44799.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue44799.go2
new file mode 100644
index 0000000..9e528a7
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue44799.go2
@@ -0,0 +1,19 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func Map[F, T any](s []F, f func(F) T) []T { return nil }
+
+func Reduce[Elem1, Elem2 any](s []Elem1, initializer Elem2, f func(Elem2, Elem1) Elem2) Elem2 { var x Elem2; return x }
+
+func main() {
+	var s []int
+	var f1 func(int) float64
+	var f2 func(float64, int) float64
+	_ = Map[int](s, f1)
+	_ = Map(s, f1)
+	_ = Reduce[int](s, 0, f2)
+	_ = Reduce(s, 0, f2)
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45548.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45548.go2
new file mode 100644
index 0000000..b1e4249
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45548.go2
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f[F interface{type *Q}, G interface{type *R}, Q, R any](q Q, r R) {}
+
+func _() {
+	f[*float64, *int](1, 2)
+	f[*float64](1, 2)
+	f(1, 2)
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45635.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45635.go2
new file mode 100644
index 0000000..65662cd
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45635.go2
@@ -0,0 +1,32 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main() {
+	some /* ERROR "undeclared name" */ [int, int]()
+}
+
+type N[T any] struct{}
+
+var _ N[] /* ERROR expecting type */
+
+type I interface {
+	type map[int]int, []int
+}
+
+func _[T I](i, j int) {
+	var m map[int]int
+	_ = m[i, j /* ERROR more than one index */ ]
+
+	var a [3]int
+	_ = a[i, j /* ERROR more than one index */ ]
+
+	var s []int
+	_ = s[i, j /* ERROR more than one index */ ]
+
+	var t T
+	// TODO(gri) fix multiple error below
+	_ = t[i, j /* ERROR more than one index */ /* ERROR more than one index */ ]
+}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45985.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45985.go2
new file mode 100644
index 0000000..7678e34
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45985.go2
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue45985
+
+// TODO(gri): this error should be on app[int] below.
+func app[S /* ERROR "type S = S does not match" */ interface{ type []T }, T any](s S, e T) S {
+    return append(s, e)
+}
+
+func _() {
+	_ = app[int]
+}
diff --git a/src/go/types/fixedbugs/issue6977.src b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue6977.src
similarity index 100%
copy from src/go/types/fixedbugs/issue6977.src
copy to src/cmd/compile/internal/types2/testdata/fixedbugs/issue6977.src
diff --git a/src/cmd/compile/internal/types2/testdata/manual.go2 b/src/cmd/compile/internal/types2/testdata/manual.go2
new file mode 100644
index 0000000..efe13cf
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/manual.go2
@@ -0,0 +1,8 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is tested when running "go test -run Manual"
+// without source arguments. Use for one-off debugging.
+
+package p
diff --git a/src/cmd/compile/internal/types2/type.go b/src/cmd/compile/internal/types2/type.go
new file mode 100644
index 0000000..e6c260f
--- /dev/null
+++ b/src/cmd/compile/internal/types2/type.go
@@ -0,0 +1,993 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"sync/atomic"
+)
+
+// A Type represents a type of Go.
+// All types implement the Type interface.
+type Type interface {
+	// Underlying returns the underlying type of a type
+	// w/o following forwarding chains. Only used by
+	// client packages (here for backward-compatibility).
+	Underlying() Type
+
+	// String returns a string representation of a type.
+	String() string
+}
+
+// BasicKind describes the kind of basic type.
+type BasicKind int
+
+const (
+	Invalid BasicKind = iota // type is invalid
+
+	// predeclared types
+	Bool
+	Int
+	Int8
+	Int16
+	Int32
+	Int64
+	Uint
+	Uint8
+	Uint16
+	Uint32
+	Uint64
+	Uintptr
+	Float32
+	Float64
+	Complex64
+	Complex128
+	String
+	UnsafePointer
+
+	// types for untyped values
+	UntypedBool
+	UntypedInt
+	UntypedRune
+	UntypedFloat
+	UntypedComplex
+	UntypedString
+	UntypedNil
+
+	// aliases
+	Byte = Uint8
+	Rune = Int32
+)
+
+// BasicInfo is a set of flags describing properties of a basic type.
+type BasicInfo int
+
+// Properties of basic types.
+const (
+	IsBoolean BasicInfo = 1 << iota
+	IsInteger
+	IsUnsigned
+	IsFloat
+	IsComplex
+	IsString
+	IsUntyped
+
+	IsOrdered   = IsInteger | IsFloat | IsString
+	IsNumeric   = IsInteger | IsFloat | IsComplex
+	IsConstType = IsBoolean | IsNumeric | IsString
+)
+
+// A Basic represents a basic type.
+type Basic struct {
+	kind BasicKind
+	info BasicInfo
+	name string
+}
+
+// Kind returns the kind of basic type b.
+func (b *Basic) Kind() BasicKind { return b.kind }
+
+// Info returns information about properties of basic type b.
+func (b *Basic) Info() BasicInfo { return b.info }
+
+// Name returns the name of basic type b.
+func (b *Basic) Name() string { return b.name }
+
+// An Array represents an array type.
+type Array struct {
+	len  int64
+	elem Type
+}
+
+// NewArray returns a new array type for the given element type and length.
+// A negative length indicates an unknown length.
+func NewArray(elem Type, len int64) *Array { return &Array{len: len, elem: elem} }
+
+// Len returns the length of array a.
+// A negative result indicates an unknown length.
+func (a *Array) Len() int64 { return a.len }
+
+// Elem returns element type of array a.
+func (a *Array) Elem() Type { return a.elem }
+
+// A Slice represents a slice type.
+type Slice struct {
+	elem Type
+}
+
+// NewSlice returns a new slice type for the given element type.
+func NewSlice(elem Type) *Slice { return &Slice{elem: elem} }
+
+// Elem returns the element type of slice s.
+func (s *Slice) Elem() Type { return s.elem }
+
+// A Struct represents a struct type.
+type Struct struct {
+	fields []*Var
+	tags   []string // field tags; nil if there are no tags
+}
+
+// NewStruct returns a new struct with the given fields and corresponding field tags.
+// If a field with index i has a tag, tags[i] must be that tag, but len(tags) may be
+// only as long as required to hold the tag with the largest index i. Consequently,
+// if no field has a tag, tags may be nil.
+func NewStruct(fields []*Var, tags []string) *Struct {
+	var fset objset
+	for _, f := range fields {
+		if f.name != "_" && fset.insert(f) != nil {
+			panic("multiple fields with the same name")
+		}
+	}
+	if len(tags) > len(fields) {
+		panic("more tags than fields")
+	}
+	return &Struct{fields: fields, tags: tags}
+}
+
+// NumFields returns the number of fields in the struct (including blank and embedded fields).
+func (s *Struct) NumFields() int { return len(s.fields) }
+
+// Field returns the i'th field for 0 <= i < NumFields().
+func (s *Struct) Field(i int) *Var { return s.fields[i] }
+
+// Tag returns the i'th field tag for 0 <= i < NumFields().
+func (s *Struct) Tag(i int) string {
+	if i < len(s.tags) {
+		return s.tags[i]
+	}
+	return ""
+}
+
+// A Pointer represents a pointer type.
+type Pointer struct {
+	base Type // element type
+}
+
+// NewPointer returns a new pointer type for the given element (base) type.
+func NewPointer(elem Type) *Pointer { return &Pointer{base: elem} }
+
+// Elem returns the element type for the given pointer p.
+func (p *Pointer) Elem() Type { return p.base }
+
+// A Tuple represents an ordered list of variables; a nil *Tuple is a valid (empty) tuple.
+// Tuples are used as components of signatures and to represent the type of multiple
+// assignments; they are not first class types of Go.
+type Tuple struct {
+	vars []*Var
+}
+
+// NewTuple returns a new tuple for the given variables.
+func NewTuple(x ...*Var) *Tuple {
+	if len(x) > 0 {
+		return &Tuple{vars: x}
+	}
+	// TODO(gri) Don't represent empty tuples with a (*Tuple)(nil) pointer;
+	//           it's too subtle and causes problems.
+	return nil
+}
+
+// Len returns the number variables of tuple t.
+func (t *Tuple) Len() int {
+	if t != nil {
+		return len(t.vars)
+	}
+	return 0
+}
+
+// At returns the i'th variable of tuple t.
+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
+	// literal we call the general type checker which returns a general Type.
+	// We then unpack the *Signature and use the scope for the literal body.
+	rparams  []*TypeName // receiver type parameters from left to right; or nil
+	tparams  []*TypeName // type parameters from left to right; or nil
+	scope    *Scope      // function scope, present for package-local signatures
+	recv     *Var        // nil if not a method
+	params   *Tuple      // (incoming) parameters from left to right; or nil
+	results  *Tuple      // (outgoing) results from left to right; or nil
+	variadic bool        // true if the last parameter's type is of the form ...T (or string, for append built-in only)
+}
+
+// NewSignature returns a new function type for the given receiver, parameters,
+// and results, either of which may be nil. If variadic is set, the function
+// is variadic, it must have at least one parameter, and the last parameter
+// must be of unnamed slice type.
+func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature {
+	if variadic {
+		n := params.Len()
+		if n == 0 {
+			panic("types2.NewSignature: variadic function must have at least one parameter")
+		}
+		if _, ok := params.At(n - 1).typ.(*Slice); !ok {
+			panic("types2.NewSignature: variadic parameter must be of unnamed slice type")
+		}
+	}
+	return &Signature{recv: recv, params: params, results: results, variadic: variadic}
+}
+
+// Recv returns the receiver of signature s (if a method), or nil if a
+// 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
+// contain methods whose receiver type is a different interface.
+func (s *Signature) Recv() *Var { return s.recv }
+
+// TParams returns the type parameters of signature s, or nil.
+func (s *Signature) TParams() []*TypeName { return s.tparams }
+
+// RParams returns the receiver type params of signature s, or nil.
+func (s *Signature) RParams() []*TypeName { return s.rparams }
+
+// SetTParams sets the type parameters of signature s.
+func (s *Signature) SetTParams(tparams []*TypeName) { s.tparams = tparams }
+
+// Params returns the parameters of signature s, or nil.
+func (s *Signature) Params() *Tuple { return s.params }
+
+// Results returns the results of signature s, or nil.
+func (s *Signature) Results() *Tuple { return s.results }
+
+// Variadic reports whether the signature s is variadic.
+func (s *Signature) Variadic() bool { return s.variadic }
+
+// A Sum represents a set of possible types.
+// Sums are currently used to represent type lists of interfaces
+// and thus the underlying types of type parameters; they are not
+// first class types of Go.
+type Sum struct {
+	types []Type // types are unique
+}
+
+// NewSum returns a new Sum type consisting of the provided
+// types if there are more than one. If there is exactly one
+// type, it returns that type. If the list of types is empty
+// the result is nil.
+func NewSum(types []Type) Type {
+	if len(types) == 0 {
+		return nil
+	}
+
+	// What should happen if types contains a sum type?
+	// Do we flatten the types list? For now we check
+	// and panic. This should not be possible for the
+	// current use case of type lists.
+	// TODO(gri) Come up with the rules for sum types.
+	for _, t := range types {
+		if _, ok := t.(*Sum); ok {
+			panic("sum type contains sum type - unimplemented")
+		}
+	}
+
+	if len(types) == 1 {
+		return types[0]
+	}
+	return &Sum{types: types}
+}
+
+// is reports whether all types in t satisfy pred.
+func (s *Sum) is(pred func(Type) bool) bool {
+	if s == nil {
+		return false
+	}
+	for _, t := range s.types {
+		if !pred(t) {
+			return false
+		}
+	}
+	return true
+}
+
+// An Interface represents an interface type.
+type Interface struct {
+	methods   []*Func // ordered list of explicitly declared methods
+	types     Type    // (possibly a Sum) type declared with a type list (TODO(gri) need better field name)
+	embeddeds []Type  // ordered list of explicitly embedded types
+
+	allMethods []*Func // ordered list of methods declared with or embedded in this interface (TODO(gri): replace with mset)
+	allTypes   Type    // intersection of all embedded and locally declared types  (TODO(gri) need better field name)
+
+	obj Object // type declaration defining this interface; or nil (for better error messages)
+}
+
+// unpack unpacks a type into a list of types.
+// TODO(gri) Try to eliminate the need for this function.
+func unpack(typ Type) []Type {
+	if typ == nil {
+		return nil
+	}
+	if sum := asSum(typ); sum != nil {
+		return sum.types
+	}
+	return []Type{typ}
+}
+
+// is reports whether interface t represents types that all satisfy pred.
+func (t *Interface) is(pred func(Type) bool) bool {
+	if t.allTypes == nil {
+		return false // we must have at least one type! (was bug)
+	}
+	for _, t := range unpack(t.allTypes) {
+		if !pred(t) {
+			return false
+		}
+	}
+	return true
+}
+
+// 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.
+// Each embedded type must have an underlying type of interface type.
+// NewInterface takes ownership of the provided methods and may modify their types by setting
+// missing receivers. To compute the method set of the interface, Complete must be called.
+//
+// Deprecated: Use NewInterfaceType instead which allows any (even non-defined) interface types
+// to be embedded. This is necessary for interfaces that embed alias type names referring to
+// non-defined (literal) interface types.
+func NewInterface(methods []*Func, embeddeds []*Named) *Interface {
+	tnames := make([]Type, len(embeddeds))
+	for i, t := range embeddeds {
+		tnames[i] = t
+	}
+	return NewInterfaceType(methods, tnames)
+}
+
+// NewInterfaceType returns a new (incomplete) interface for the given methods and embedded types.
+// Each embedded type must have an underlying type of interface type (this property is not
+// verified for defined types, which may be in the process of being set up and which don't
+// have a valid underlying type yet).
+// NewInterfaceType takes ownership of the provided methods and may modify their types by setting
+// missing receivers. To compute the method set of the interface, Complete must be called.
+func NewInterfaceType(methods []*Func, embeddeds []Type) *Interface {
+	if len(methods) == 0 && len(embeddeds) == 0 {
+		return &emptyInterface
+	}
+
+	// set method receivers if necessary
+	typ := new(Interface)
+	for _, m := range methods {
+		if sig := m.typ.(*Signature); sig.recv == nil {
+			sig.recv = NewVar(m.pos, m.pkg, "", typ)
+		}
+	}
+
+	// All embedded types should be interfaces; however, defined types
+	// may not yet be fully resolved. Only verify that non-defined types
+	// are interfaces. This matches the behavior of the code before the
+	// fix for #25301 (issue #25596).
+	for _, t := range embeddeds {
+		if _, ok := t.(*Named); !ok && !IsInterface(t) {
+			panic("embedded type is not an interface")
+		}
+	}
+
+	// sort for API stability
+	sortMethods(methods)
+	sortTypes(embeddeds)
+
+	typ.methods = methods
+	typ.embeddeds = embeddeds
+	return typ
+}
+
+// NumExplicitMethods returns the number of explicitly declared methods of interface t.
+func (t *Interface) NumExplicitMethods() int { return len(t.methods) }
+
+// ExplicitMethod returns the i'th explicitly declared method of interface t for 0 <= i < t.NumExplicitMethods().
+// The methods are ordered by their unique Id.
+func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] }
+
+// NumEmbeddeds returns the number of embedded types in interface t.
+func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) }
+
+// Embedded returns the i'th embedded defined (*Named) type of interface t for 0 <= i < t.NumEmbeddeds().
+// The result is nil if the i'th embedded type is not a defined type.
+//
+// Deprecated: Use EmbeddedType which is not restricted to defined (*Named) types.
+func (t *Interface) Embedded(i int) *Named { tname, _ := t.embeddeds[i].(*Named); return tname }
+
+// EmbeddedType returns the i'th embedded type of interface t for 0 <= i < t.NumEmbeddeds().
+func (t *Interface) EmbeddedType(i int) Type { return t.embeddeds[i] }
+
+// NumMethods returns the total number of methods of interface t.
+// The interface must have been completed.
+func (t *Interface) NumMethods() int { t.assertCompleteness(); return len(t.allMethods) }
+
+func (t *Interface) assertCompleteness() {
+	if t.allMethods == nil {
+		panic("interface is incomplete")
+	}
+}
+
+// Method returns the i'th method of interface t for 0 <= i < t.NumMethods().
+// The methods are ordered by their unique Id.
+// The interface must have been completed.
+func (t *Interface) Method(i int) *Func { t.assertCompleteness(); return t.allMethods[i] }
+
+// Empty reports whether t is the empty interface.
+func (t *Interface) Empty() bool {
+	if t.allMethods != nil {
+		// interface is complete - quick test
+		// A non-nil allTypes may still be empty and represents the bottom type.
+		return len(t.allMethods) == 0 && t.allTypes == nil
+	}
+	return !t.iterate(func(t *Interface) bool {
+		return len(t.methods) > 0 || t.types != nil
+	}, nil)
+}
+
+// HasTypeList reports whether interface t has a type list, possibly from an embedded type.
+func (t *Interface) HasTypeList() bool {
+	if t.allMethods != nil {
+		// interface is complete - quick test
+		return t.allTypes != nil
+	}
+
+	return t.iterate(func(t *Interface) bool {
+		return t.types != nil
+	}, nil)
+}
+
+// IsComparable reports whether interface t is or embeds the predeclared interface "comparable".
+func (t *Interface) IsComparable() bool {
+	if t.allMethods != nil {
+		// interface is complete - quick test
+		_, m := lookupMethod(t.allMethods, nil, "==")
+		return m != nil
+	}
+
+	return t.iterate(func(t *Interface) bool {
+		_, m := lookupMethod(t.methods, nil, "==")
+		return m != nil
+	}, nil)
+}
+
+// IsConstraint reports t.HasTypeList() || t.IsComparable().
+func (t *Interface) IsConstraint() bool {
+	if t.allMethods != nil {
+		// interface is complete - quick test
+		if t.allTypes != nil {
+			return true
+		}
+		_, m := lookupMethod(t.allMethods, nil, "==")
+		return m != nil
+	}
+
+	return t.iterate(func(t *Interface) bool {
+		if t.types != nil {
+			return true
+		}
+		_, m := lookupMethod(t.methods, nil, "==")
+		return m != nil
+	}, nil)
+}
+
+// iterate calls f with t and then with any embedded interface of t, recursively, until f returns true.
+// iterate reports whether any call to f returned true.
+func (t *Interface) iterate(f func(*Interface) bool, seen map[*Interface]bool) bool {
+	if f(t) {
+		return true
+	}
+	for _, e := range t.embeddeds {
+		// e should be an interface but be careful (it may be invalid)
+		if e := asInterface(e); e != nil {
+			// Cyclic interfaces such as "type E interface { E }" are not permitted
+			// but they are still constructed and we need to detect such cycles.
+			if seen[e] {
+				continue
+			}
+			if seen == nil {
+				seen = make(map[*Interface]bool)
+			}
+			seen[e] = true
+			if e.iterate(f, seen) {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// isSatisfiedBy reports whether interface t's type list is satisfied by the type typ.
+// If the type list is empty (absent), typ trivially satisfies the interface.
+// TODO(gri) This is not a great name. Eventually, we should have a more comprehensive
+//           "implements" predicate.
+func (t *Interface) isSatisfiedBy(typ Type) bool {
+	t.Complete()
+	if t.allTypes == nil {
+		return true
+	}
+	types := unpack(t.allTypes)
+	return includes(types, typ) || includes(types, under(typ))
+}
+
+// Complete computes the interface's method set. It must be called by users of
+// NewInterfaceType and NewInterface after the interface's embedded types are
+// fully defined and before using the interface type in any way other than to
+// form other types. The interface must not contain duplicate methods or a
+// panic occurs. Complete returns the receiver.
+func (t *Interface) Complete() *Interface {
+	// TODO(gri) consolidate this method with Checker.completeInterface
+	if t.allMethods != nil {
+		return t
+	}
+
+	t.allMethods = markComplete // avoid infinite recursion
+
+	var todo []*Func
+	var methods []*Func
+	var seen objset
+	addMethod := func(m *Func, explicit bool) {
+		switch other := seen.insert(m); {
+		case other == nil:
+			methods = append(methods, m)
+		case explicit:
+			panic("duplicate method " + m.name)
+		default:
+			// check method signatures after all locally embedded interfaces are computed
+			todo = append(todo, m, other.(*Func))
+		}
+	}
+
+	for _, m := range t.methods {
+		addMethod(m, true)
+	}
+
+	allTypes := t.types
+
+	for _, typ := range t.embeddeds {
+		utyp := under(typ)
+		etyp := asInterface(utyp)
+		if etyp == nil {
+			if utyp != Typ[Invalid] {
+				panic(fmt.Sprintf("%s is not an interface", typ))
+			}
+			continue
+		}
+		etyp.Complete()
+		for _, m := range etyp.allMethods {
+			addMethod(m, false)
+		}
+		allTypes = intersect(allTypes, etyp.allTypes)
+	}
+
+	for i := 0; i < len(todo); i += 2 {
+		m := todo[i]
+		other := todo[i+1]
+		if !Identical(m.typ, other.typ) {
+			panic("duplicate method " + m.name)
+		}
+	}
+
+	if methods != nil {
+		sortMethods(methods)
+		t.allMethods = methods
+	}
+	t.allTypes = allTypes
+
+	return t
+}
+
+// A Map represents a map type.
+type Map struct {
+	key, elem Type
+}
+
+// NewMap returns a new map for the given key and element types.
+func NewMap(key, elem Type) *Map {
+	return &Map{key: key, elem: elem}
+}
+
+// Key returns the key type of map m.
+func (m *Map) Key() Type { return m.key }
+
+// Elem returns the element type of map m.
+func (m *Map) Elem() Type { return m.elem }
+
+// A Chan represents a channel type.
+type Chan struct {
+	dir  ChanDir
+	elem Type
+}
+
+// A ChanDir value indicates a channel direction.
+type ChanDir int
+
+// The direction of a channel is indicated by one of these constants.
+const (
+	SendRecv ChanDir = iota
+	SendOnly
+	RecvOnly
+)
+
+// NewChan returns a new channel type for the given direction and element type.
+func NewChan(dir ChanDir, elem Type) *Chan {
+	return &Chan{dir: dir, elem: elem}
+}
+
+// Dir returns the direction of channel c.
+func (c *Chan) Dir() ChanDir { return c.dir }
+
+// Elem returns the element type of channel c.
+func (c *Chan) Elem() Type { return c.elem }
+
+// TODO(gri) Clean up Named struct below; specifically the fromRHS field (can we use underlying?).
+
+// A Named represents a named (defined) type.
+type Named struct {
+	check      *Checker    // for Named.under implementation
+	info       typeInfo    // for cycle detection
+	obj        *TypeName   // corresponding declared object
+	orig       *Named      // original, uninstantiated type
+	fromRHS    Type        // type (on RHS of declaration) this *Named type is derived from (for cycle reporting)
+	underlying Type        // possibly a *Named during setup; never a *Named once set up completely
+	tparams    []*TypeName // type parameters, or nil
+	targs      []Type      // type arguments (after instantiation), or nil
+	methods    []*Func     // methods declared for this type (not the method set of this type); signatures are type-checked lazily
+}
+
+// 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 {
+		panic("types2.NewNamed: underlying type must not be *Named")
+	}
+	return (*Checker)(nil).newNamed(obj, nil, underlying, nil, methods)
+}
+
+// newNamed is like NewNamed but with a *Checker receiver and additional orig argument.
+func (check *Checker) newNamed(obj *TypeName, orig *Named, underlying Type, tparams []*TypeName, methods []*Func) *Named {
+	typ := &Named{check: check, obj: obj, orig: orig, fromRHS: underlying, underlying: underlying, tparams: tparams, methods: methods}
+	if typ.orig == nil {
+		typ.orig = typ
+	}
+	if obj.typ == nil {
+		obj.typ = typ
+	}
+	return typ
+}
+
+// Obj returns the type name for the named type t.
+func (t *Named) Obj() *TypeName { return t.obj }
+
+// Orig returns the original generic type an instantiated type is derived from.
+// If t is not an instantiated type, the result is t.
+func (t *Named) Orig() *Named { return t.orig }
+
+// TODO(gri) Come up with a better representation and API to distinguish
+//           between parameterized instantiated and non-instantiated types.
+
+// TParams returns the type parameters of the named type t, or nil.
+// The result is non-nil for an (originally) parameterized type even if it is instantiated.
+func (t *Named) TParams() []*TypeName { return t.tparams }
+
+// SetTParams sets the type parameters of the named type t.
+func (t *Named) SetTParams(tparams []*TypeName) { t.tparams = tparams }
+
+// TArgs returns the type arguments after instantiation of the named type t, or nil if not instantiated.
+func (t *Named) TArgs() []Type { return t.targs }
+
+// SetTArgs sets the type arguments of the named type t.
+func (t *Named) SetTArgs(args []Type) { t.targs = args }
+
+// NumMethods returns the number of explicit methods whose receiver is named type t.
+func (t *Named) NumMethods() int { return len(t.methods) }
+
+// Method returns the i'th method of named type t for 0 <= i < t.NumMethods().
+func (t *Named) Method(i int) *Func { return t.methods[i] }
+
+// SetUnderlying sets the underlying type and marks t as complete.
+func (t *Named) SetUnderlying(underlying Type) {
+	if underlying == nil {
+		panic("types2.Named.SetUnderlying: underlying type must not be nil")
+	}
+	if _, ok := underlying.(*Named); ok {
+		panic("types2.Named.SetUnderlying: underlying type must not be *Named")
+	}
+	t.underlying = underlying
+}
+
+// AddMethod adds method m unless it is already in the method list.
+func (t *Named) AddMethod(m *Func) {
+	if i, _ := lookupMethod(t.methods, m.pkg, m.name); i < 0 {
+		t.methods = append(t.methods, m)
+	}
+}
+
+// Note: This is a uint32 rather than a uint64 because the
+// respective 64 bit atomic instructions are not available
+// on all platforms.
+var lastId uint32
+
+// nextId returns a value increasing monotonically by 1 with
+// each call, starting with 1. It may be called concurrently.
+func nextId() uint64 { return uint64(atomic.AddUint32(&lastId, 1)) }
+
+// A TypeParam represents a type parameter type.
+type TypeParam struct {
+	check *Checker  // for lazy type bound completion
+	id    uint64    // unique id, for debugging only
+	obj   *TypeName // corresponding type name
+	index int       // type parameter index in source order, starting at 0
+	bound Type      // *Named or *Interface; underlying type is always *Interface
+}
+
+// Obj returns the type name for the type parameter t.
+func (t *TypeParam) Obj() *TypeName { return t.obj }
+
+// NewTypeParam returns a new TypeParam.
+func (check *Checker) NewTypeParam(obj *TypeName, index int, bound Type) *TypeParam {
+	assert(bound != nil)
+	typ := &TypeParam{check: check, id: nextId(), obj: obj, index: index, bound: bound}
+	if obj.typ == nil {
+		obj.typ = typ
+	}
+	return typ
+}
+
+func (t *TypeParam) Bound() *Interface {
+	iface := asInterface(t.bound)
+	// use the type bound position if we have one
+	pos := nopos
+	if n, _ := t.bound.(*Named); n != nil {
+		pos = n.obj.pos
+	}
+	// TODO(gri) switch this to an unexported method on Checker.
+	t.check.completeInterface(pos, iface)
+	return iface
+}
+
+// optype returns a type's operational type. Except for
+// type parameters, the operational type is the same
+// as the underlying type (as returned by under). For
+// Type parameters, the operational type is determined
+// by the corresponding type bound's type list. The
+// result may be the bottom or top type, but it is never
+// the incoming type parameter.
+func optype(typ Type) Type {
+	if t := asTypeParam(typ); t != nil {
+		// If the optype is typ, return the top type as we have
+		// no information. It also prevents infinite recursion
+		// via the asTypeParam converter function. This can happen
+		// for a type parameter list of the form:
+		// (type T interface { type T }).
+		// See also issue #39680.
+		if u := t.Bound().allTypes; u != nil && u != typ {
+			// u != typ and u is a type parameter => under(u) != typ, so this is ok
+			return under(u)
+		}
+		return theTop
+	}
+	return under(typ)
+}
+
+// An instance represents an instantiated generic type syntactically
+// (without expanding the instantiation). Type instances appear only
+// during type-checking and are replaced by their fully instantiated
+// (expanded) types before the end of type-checking.
+type instance struct {
+	check   *Checker     // for lazy instantiation
+	pos     syntax.Pos   // position of type instantiation; for error reporting only
+	base    *Named       // parameterized type to be instantiated
+	targs   []Type       // type arguments
+	poslist []syntax.Pos // position of each targ; for error reporting only
+	value   Type         // base(targs...) after instantiation or Typ[Invalid]; nil if not yet set
+}
+
+// expand returns the instantiated (= expanded) type of t.
+// The result is either an instantiated *Named type, or
+// Typ[Invalid] if there was an error.
+func (t *instance) expand() Type {
+	v := t.value
+	if v == nil {
+		v = t.check.instantiate(t.pos, t.base, t.targs, t.poslist)
+		if v == nil {
+			v = Typ[Invalid]
+		}
+		t.value = v
+	}
+	// After instantiation we must have an invalid or a *Named type.
+	if debug && v != Typ[Invalid] {
+		_ = v.(*Named)
+	}
+	return v
+}
+
+// expand expands a type instance into its instantiated
+// type and leaves all other types alone. expand does
+// not recurse.
+func expand(typ Type) Type {
+	if t, _ := typ.(*instance); t != nil {
+		return t.expand()
+	}
+	return typ
+}
+
+// expandf is set to expand.
+// Call expandf when calling expand causes compile-time cycle error.
+var expandf func(Type) Type
+
+func init() { expandf = expand }
+
+// bottom represents the bottom of the type lattice.
+// It is the underlying type of a type parameter that
+// cannot be satisfied by any type, usually because
+// the intersection of type constraints left nothing).
+type bottom struct{}
+
+// theBottom is the singleton bottom type.
+var theBottom = &bottom{}
+
+// top represents the top of the type lattice.
+// It is the underlying type of a type parameter that
+// can be satisfied by any type (ignoring methods),
+// usually because the type constraint has no type
+// list.
+type top struct{}
+
+// theTop is the singleton top type.
+var theTop = &top{}
+
+// Type-specific implementations of Underlying.
+func (t *Basic) Underlying() Type     { return t }
+func (t *Array) Underlying() Type     { return t }
+func (t *Slice) Underlying() Type     { return t }
+func (t *Struct) Underlying() Type    { return t }
+func (t *Pointer) Underlying() Type   { return t }
+func (t *Tuple) Underlying() Type     { return t }
+func (t *Signature) Underlying() Type { return t }
+func (t *Sum) Underlying() Type       { return t }
+func (t *Interface) Underlying() Type { return t }
+func (t *Map) Underlying() Type       { return t }
+func (t *Chan) Underlying() Type      { return t }
+func (t *Named) Underlying() Type     { return t.underlying }
+func (t *TypeParam) Underlying() Type { return t }
+func (t *instance) Underlying() Type  { return t }
+func (t *bottom) Underlying() Type    { return t }
+func (t *top) Underlying() Type       { return t }
+
+// Type-specific implementations of String.
+func (t *Basic) String() string     { return TypeString(t, nil) }
+func (t *Array) String() string     { return TypeString(t, nil) }
+func (t *Slice) String() string     { return TypeString(t, nil) }
+func (t *Struct) String() string    { return TypeString(t, nil) }
+func (t *Pointer) String() string   { return TypeString(t, nil) }
+func (t *Tuple) String() string     { return TypeString(t, nil) }
+func (t *Signature) String() string { return TypeString(t, nil) }
+func (t *Sum) String() string       { return TypeString(t, nil) }
+func (t *Interface) String() string { return TypeString(t, nil) }
+func (t *Map) String() string       { return TypeString(t, nil) }
+func (t *Chan) String() string      { return TypeString(t, nil) }
+func (t *Named) String() string     { return TypeString(t, nil) }
+func (t *TypeParam) String() string { return TypeString(t, nil) }
+func (t *instance) String() string  { return TypeString(t, nil) }
+func (t *bottom) String() string    { return TypeString(t, nil) }
+func (t *top) String() string       { return TypeString(t, nil) }
+
+// under returns the true expanded underlying type.
+// If it doesn't exist, the result is Typ[Invalid].
+// under must only be called when a type is known
+// to be fully set up.
+func under(t Type) Type {
+	// TODO(gri) is this correct for *Sum?
+	if n := asNamed(t); n != nil {
+		return n.under()
+	}
+	return t
+}
+
+// Converters
+//
+// A converter must only be called when a type is
+// known to be fully set up. A converter returns
+// a type's operational type (see comment for optype)
+// or nil if the type argument is not of the
+// respective type.
+
+func asBasic(t Type) *Basic {
+	op, _ := optype(t).(*Basic)
+	return op
+}
+
+func asArray(t Type) *Array {
+	op, _ := optype(t).(*Array)
+	return op
+}
+
+func asSlice(t Type) *Slice {
+	op, _ := optype(t).(*Slice)
+	return op
+}
+
+func asStruct(t Type) *Struct {
+	op, _ := optype(t).(*Struct)
+	return op
+}
+
+func asPointer(t Type) *Pointer {
+	op, _ := optype(t).(*Pointer)
+	return op
+}
+
+// asTuple is not needed - not provided
+
+func asSignature(t Type) *Signature {
+	op, _ := optype(t).(*Signature)
+	return op
+}
+
+func asSum(t Type) *Sum {
+	op, _ := optype(t).(*Sum)
+	return op
+}
+
+func asInterface(t Type) *Interface {
+	op, _ := optype(t).(*Interface)
+	return op
+}
+
+func asMap(t Type) *Map {
+	op, _ := optype(t).(*Map)
+	return op
+}
+
+func asChan(t Type) *Chan {
+	op, _ := optype(t).(*Chan)
+	return op
+}
+
+// If the argument to asNamed and asTypeParam is of the respective types
+// (possibly after expanding an instance type), these methods return that type.
+// Otherwise the result is nil.
+
+func asNamed(t Type) *Named {
+	e, _ := expand(t).(*Named)
+	return e
+}
+
+func asTypeParam(t Type) *TypeParam {
+	u, _ := under(t).(*TypeParam)
+	return u
+}
+
+// Exported for the compiler.
+
+func AsPointer(t Type) *Pointer     { return asPointer(t) }
+func AsNamed(t Type) *Named         { return asNamed(t) }
+func AsSignature(t Type) *Signature { return asSignature(t) }
+func AsInterface(t Type) *Interface { return asInterface(t) }
diff --git a/src/cmd/compile/internal/types2/types_test.go b/src/cmd/compile/internal/types2/types_test.go
new file mode 100644
index 0000000..0964021
--- /dev/null
+++ b/src/cmd/compile/internal/types2/types_test.go
@@ -0,0 +1,17 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+import "sync/atomic"
+
+func init() {
+	acceptMethodTypeParams = true
+}
+
+// Upon calling ResetId, nextId starts with 1 again.
+// It may be called concurrently. This is only needed
+// for tests where we may want to have a consistent
+// numbering for each individual test case.
+func ResetId() { atomic.StoreUint32(&lastId, 0) }
diff --git a/src/cmd/compile/internal/types2/typestring.go b/src/cmd/compile/internal/types2/typestring.go
new file mode 100644
index 0000000..4001669
--- /dev/null
+++ b/src/cmd/compile/internal/types2/typestring.go
@@ -0,0 +1,441 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements printing of types.
+
+package types2
+
+import (
+	"bytes"
+	"fmt"
+	"unicode/utf8"
+)
+
+// A Qualifier controls how named package-level objects are printed in
+// calls to TypeString, ObjectString, and SelectionString.
+//
+// These three formatting routines call the Qualifier for each
+// package-level object O, and if the Qualifier returns a non-empty
+// string p, the object is printed in the form p.O.
+// If it returns an empty string, only the object name O is printed.
+//
+// Using a nil Qualifier is equivalent to using (*Package).Path: the
+// object is qualified by the import path, e.g., "encoding/json.Marshal".
+//
+type Qualifier func(*Package) string
+
+// RelativeTo returns a Qualifier that fully qualifies members of
+// all packages other than pkg.
+func RelativeTo(pkg *Package) Qualifier {
+	if pkg == nil {
+		return nil
+	}
+	return func(other *Package) string {
+		if pkg == other {
+			return "" // same package; unqualified
+		}
+		return other.Path()
+	}
+}
+
+// If gcCompatibilityMode is set, printing of types is modified
+// to match the representation of some types in the gc compiler:
+//
+//	- byte and rune lose their alias name and simply stand for
+//	  uint8 and int32 respectively
+//	- embedded interfaces get flattened (the embedding info is lost,
+//	  and certain recursive interface types cannot be printed anymore)
+//
+// This makes it easier to compare packages computed with the type-
+// checker vs packages imported from gc export data.
+//
+// Caution: This flag affects all uses of WriteType, globally.
+// It is only provided for testing in conjunction with
+// gc-generated data.
+//
+// This flag is exported in the x/tools/go/types package. We don't
+// need it at the moment in the std repo and so we don't export it
+// anymore. We should eventually try to remove it altogether.
+// TODO(gri) remove this
+var gcCompatibilityMode bool
+
+// TypeString returns the string representation of typ.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func TypeString(typ Type, qf Qualifier) string {
+	var buf bytes.Buffer
+	WriteType(&buf, typ, qf)
+	return buf.String()
+}
+
+// WriteType writes the string representation of typ to buf.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func WriteType(buf *bytes.Buffer, typ Type, qf Qualifier) {
+	writeType(buf, typ, qf, make([]Type, 0, 8))
+}
+
+// instanceMarker is the prefix for an instantiated type
+// in "non-evaluated" instance form.
+const instanceMarker = '#'
+
+func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
+	// Theoretically, this is a quadratic lookup algorithm, but in
+	// practice deeply nested composite types with unnamed component
+	// types are uncommon. This code is likely more efficient than
+	// using a map.
+	for _, t := range visited {
+		if t == typ {
+			fmt.Fprintf(buf, "○%T", goTypeName(typ)) // cycle to typ
+			return
+		}
+	}
+	visited = append(visited, typ)
+
+	switch t := typ.(type) {
+	case nil:
+		buf.WriteString("<nil>")
+
+	case *Basic:
+		// exported basic types go into package unsafe
+		// (currently this is just unsafe.Pointer)
+		if isExported(t.name) {
+			if obj, _ := Unsafe.scope.Lookup(t.name).(*TypeName); obj != nil {
+				writeTypeName(buf, obj, qf)
+				break
+			}
+		}
+
+		if gcCompatibilityMode {
+			// forget the alias names
+			switch t.kind {
+			case Byte:
+				t = Typ[Uint8]
+			case Rune:
+				t = Typ[Int32]
+			}
+		}
+		buf.WriteString(t.name)
+
+	case *Array:
+		fmt.Fprintf(buf, "[%d]", t.len)
+		writeType(buf, t.elem, qf, visited)
+
+	case *Slice:
+		buf.WriteString("[]")
+		writeType(buf, t.elem, qf, visited)
+
+	case *Struct:
+		buf.WriteString("struct{")
+		for i, f := range t.fields {
+			if i > 0 {
+				buf.WriteString("; ")
+			}
+			// This doesn't do the right thing for embedded type
+			// aliases where we should print the alias name, not
+			// the aliased type (see issue #44410).
+			if !f.embedded {
+				buf.WriteString(f.name)
+				buf.WriteByte(' ')
+			}
+			writeType(buf, f.typ, qf, visited)
+			if tag := t.Tag(i); tag != "" {
+				fmt.Fprintf(buf, " %q", tag)
+			}
+		}
+		buf.WriteByte('}')
+
+	case *Pointer:
+		buf.WriteByte('*')
+		writeType(buf, t.base, qf, visited)
+
+	case *Tuple:
+		writeTuple(buf, t, false, qf, visited)
+
+	case *Signature:
+		buf.WriteString("func")
+		writeSignature(buf, t, qf, visited)
+
+	case *Sum:
+		for i, t := range t.types {
+			if i > 0 {
+				buf.WriteString(", ")
+			}
+			writeType(buf, t, qf, visited)
+		}
+
+	case *Interface:
+		// We write the source-level methods and embedded types rather
+		// than the actual method set since resolved method signatures
+		// may have non-printable cycles if parameters have embedded
+		// interface types that (directly or indirectly) embed the
+		// current interface. For instance, consider the result type
+		// of m:
+		//
+		//     type T interface{
+		//         m() interface{ T }
+		//     }
+		//
+		buf.WriteString("interface{")
+		empty := true
+		if gcCompatibilityMode {
+			// print flattened interface
+			// (useful to compare against gc-generated interfaces)
+			for i, m := range t.allMethods {
+				if i > 0 {
+					buf.WriteString("; ")
+				}
+				buf.WriteString(m.name)
+				writeSignature(buf, m.typ.(*Signature), qf, visited)
+				empty = false
+			}
+			if !empty && t.allTypes != nil {
+				buf.WriteString("; ")
+			}
+			if t.allTypes != nil {
+				buf.WriteString("type ")
+				writeType(buf, t.allTypes, qf, visited)
+			}
+		} else {
+			// print explicit interface methods and embedded types
+			for i, m := range t.methods {
+				if i > 0 {
+					buf.WriteString("; ")
+				}
+				buf.WriteString(m.name)
+				writeSignature(buf, m.typ.(*Signature), qf, visited)
+				empty = false
+			}
+			if !empty && t.types != nil {
+				buf.WriteString("; ")
+			}
+			if t.types != nil {
+				buf.WriteString("type ")
+				writeType(buf, t.types, qf, visited)
+				empty = false
+			}
+			if !empty && len(t.embeddeds) > 0 {
+				buf.WriteString("; ")
+			}
+			for i, typ := range t.embeddeds {
+				if i > 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:
+		buf.WriteString("map[")
+		writeType(buf, t.key, qf, visited)
+		buf.WriteByte(']')
+		writeType(buf, t.elem, qf, visited)
+
+	case *Chan:
+		var s string
+		var parens bool
+		switch t.dir {
+		case SendRecv:
+			s = "chan "
+			// chan (<-chan T) requires parentheses
+			if c, _ := t.elem.(*Chan); c != nil && c.dir == RecvOnly {
+				parens = true
+			}
+		case SendOnly:
+			s = "chan<- "
+		case RecvOnly:
+			s = "<-chan "
+		default:
+			panic("unreachable")
+		}
+		buf.WriteString(s)
+		if parens {
+			buf.WriteByte('(')
+		}
+		writeType(buf, t.elem, qf, visited)
+		if parens {
+			buf.WriteByte(')')
+		}
+
+	case *Named:
+		writeTypeName(buf, t.obj, qf)
+		if t.targs != nil {
+			// instantiated type
+			buf.WriteByte('[')
+			writeTypeList(buf, t.targs, qf, visited)
+			buf.WriteByte(']')
+		} else if t.tparams != nil {
+			// parameterized type
+			writeTParamList(buf, t.tparams, qf, visited)
+		}
+
+	case *TypeParam:
+		s := "?"
+		if t.obj != nil {
+			s = t.obj.name
+		}
+		buf.WriteString(s + subscript(t.id))
+
+	case *instance:
+		buf.WriteByte(instanceMarker) // indicate "non-evaluated" syntactic instance
+		writeTypeName(buf, t.base.obj, qf)
+		buf.WriteByte('[')
+		writeTypeList(buf, t.targs, qf, visited)
+		buf.WriteByte(']')
+
+	case *bottom:
+		buf.WriteString("⊥")
+
+	case *top:
+		buf.WriteString("⊤")
+
+	default:
+		// For externally defined implementations of Type.
+		buf.WriteString(t.String())
+	}
+}
+
+func writeTypeList(buf *bytes.Buffer, list []Type, qf Qualifier, visited []Type) {
+	for i, typ := range list {
+		if i > 0 {
+			buf.WriteString(", ")
+		}
+		writeType(buf, typ, qf, visited)
+	}
+}
+
+func writeTParamList(buf *bytes.Buffer, list []*TypeName, qf Qualifier, visited []Type) {
+	buf.WriteString("[")
+	var prev Type
+	for i, p := range list {
+		// TODO(gri) support 'any' sugar here.
+		var b Type = &emptyInterface
+		if t, _ := p.typ.(*TypeParam); t != nil && t.bound != nil {
+			b = t.bound
+		}
+		if i > 0 {
+			if b != prev {
+				// type bound changed - write previous one before advancing
+				buf.WriteByte(' ')
+				writeType(buf, prev, qf, visited)
+			}
+			buf.WriteString(", ")
+		}
+		prev = b
+
+		if t, _ := p.typ.(*TypeParam); t != nil {
+			writeType(buf, t, qf, visited)
+		} else {
+			buf.WriteString(p.name)
+		}
+	}
+	if prev != nil {
+		buf.WriteByte(' ')
+		writeType(buf, prev, qf, visited)
+	}
+	buf.WriteByte(']')
+}
+
+func writeTypeName(buf *bytes.Buffer, obj *TypeName, qf Qualifier) {
+	s := "<Named w/o object>"
+	if obj != nil {
+		if obj.pkg != nil {
+			writePackage(buf, obj.pkg, qf)
+		}
+		// TODO(gri): function-local named types should be displayed
+		// differently from named types at package level to avoid
+		// ambiguity.
+		s = obj.name
+	}
+	buf.WriteString(s)
+}
+
+func writeTuple(buf *bytes.Buffer, tup *Tuple, variadic bool, qf Qualifier, visited []Type) {
+	buf.WriteByte('(')
+	if tup != nil {
+		for i, v := range tup.vars {
+			if i > 0 {
+				buf.WriteString(", ")
+			}
+			if v.name != "" {
+				buf.WriteString(v.name)
+				buf.WriteByte(' ')
+			}
+			typ := v.typ
+			if variadic && i == len(tup.vars)-1 {
+				if s, ok := typ.(*Slice); ok {
+					buf.WriteString("...")
+					typ = s.elem
+				} else {
+					// special case:
+					// append(s, "foo"...) leads to signature func([]byte, string...)
+					if t := asBasic(typ); t == nil || t.kind != String {
+						panic("internal error: string type expected")
+					}
+					writeType(buf, typ, qf, visited)
+					buf.WriteString("...")
+					continue
+				}
+			}
+			writeType(buf, typ, qf, visited)
+		}
+	}
+	buf.WriteByte(')')
+}
+
+// WriteSignature writes the representation of the signature sig to buf,
+// without a leading "func" keyword.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
+	writeSignature(buf, sig, qf, make([]Type, 0, 8))
+}
+
+func writeSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier, visited []Type) {
+	if sig.tparams != nil {
+		writeTParamList(buf, sig.tparams, qf, visited)
+	}
+
+	writeTuple(buf, sig.params, sig.variadic, qf, visited)
+
+	n := sig.results.Len()
+	if n == 0 {
+		// no result
+		return
+	}
+
+	buf.WriteByte(' ')
+	if n == 1 && sig.results.vars[0].name == "" {
+		// single unnamed result
+		writeType(buf, sig.results.vars[0].typ, qf, visited)
+		return
+	}
+
+	// multiple or named result(s)
+	writeTuple(buf, sig.results, false, qf, visited)
+}
+
+// subscript returns the decimal (utf8) representation of x using subscript digits.
+func subscript(x uint64) string {
+	const w = len("₀") // all digits 0...9 have the same utf8 width
+	var buf [32 * w]byte
+	i := len(buf)
+	for {
+		i -= w
+		utf8.EncodeRune(buf[i:], '₀'+rune(x%10)) // '₀' == U+2080
+		x /= 10
+		if x == 0 {
+			break
+		}
+	}
+	return string(buf[i:])
+}
diff --git a/src/cmd/compile/internal/types2/typestring_test.go b/src/cmd/compile/internal/types2/typestring_test.go
new file mode 100644
index 0000000..d98e9a5
--- /dev/null
+++ b/src/cmd/compile/internal/types2/typestring_test.go
@@ -0,0 +1,220 @@
+// 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 types2_test
+
+import (
+	"internal/testenv"
+	"testing"
+
+	"cmd/compile/internal/syntax"
+	. "cmd/compile/internal/types2"
+)
+
+const filename = "<src>"
+
+func makePkg(src string) (*Package, error) {
+	file, err := parseSrc(filename, src)
+	if err != nil {
+		return nil, err
+	}
+	// use the package name as package path
+	conf := Config{Importer: defaultImporter()}
+	return conf.Check(file.PkgName.Value, []*syntax.File{file}, nil)
+}
+
+type testEntry struct {
+	src, str string
+}
+
+// dup returns a testEntry where both src and str are the same.
+func dup(s string) testEntry {
+	return testEntry{s, s}
+}
+
+// types that don't depend on any other type declarations
+var independentTestTypes = []testEntry{
+	// basic types
+	dup("int"),
+	dup("float32"),
+	dup("string"),
+
+	// arrays
+	dup("[10]int"),
+
+	// slices
+	dup("[]int"),
+	dup("[][]int"),
+
+	// structs
+	dup("struct{}"),
+	dup("struct{x int}"),
+	{`struct {
+		x, y int
+		z float32 "foo"
+	}`, `struct{x int; y int; z float32 "foo"}`},
+	{`struct {
+		string
+		elems []complex128
+	}`, `struct{string; elems []complex128}`},
+
+	// pointers
+	dup("*int"),
+	dup("***struct{}"),
+	dup("*struct{a int; b float32}"),
+
+	// functions
+	dup("func()"),
+	dup("func(x int)"),
+	{"func(x, y int)", "func(x int, y int)"},
+	{"func(x, y int, z string)", "func(x int, y int, z string)"},
+	dup("func(int)"),
+	{"func(int, string, byte)", "func(int, string, byte)"},
+
+	dup("func() int"),
+	{"func() (string)", "func() string"},
+	dup("func() (u int)"),
+	{"func() (u, v int, w string)", "func() (u int, v int, w string)"},
+
+	dup("func(int) string"),
+	dup("func(x int) string"),
+	dup("func(x int) (u string)"),
+	{"func(x, y int) (u string)", "func(x int, y int) (u string)"},
+
+	dup("func(...int) string"),
+	dup("func(x ...int) string"),
+	dup("func(x ...int) (u string)"),
+	{"func(x int, y ...int) (u string)", "func(x int, y ...int) (u string)"},
+
+	// interfaces
+	dup("interface{}"),
+	dup("interface{m()}"),
+	dup(`interface{String() string; m(int) float32}`),
+	dup(`interface{type int, float32, complex128}`),
+
+	// maps
+	dup("map[string]int"),
+	{"map[struct{x, y int}][]byte", "map[struct{x int; y int}][]byte"},
+
+	// channels
+	dup("chan<- chan int"),
+	dup("chan<- <-chan int"),
+	dup("<-chan <-chan int"),
+	dup("chan (<-chan int)"),
+	dup("chan<- func()"),
+	dup("<-chan []func() int"),
+}
+
+// types that depend on other type declarations (src in TestTypes)
+var dependentTestTypes = []testEntry{
+	// interfaces
+	dup(`interface{io.Reader; io.Writer}`),
+	dup(`interface{m() int; io.Writer}`),
+	{`interface{m() interface{T}}`, `interface{m() interface{generic_p.T}}`},
+}
+
+func TestTypeString(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	var tests []testEntry
+	tests = append(tests, independentTestTypes...)
+	tests = append(tests, dependentTestTypes...)
+
+	for _, test := range tests {
+		src := `package generic_p; import "io"; type _ io.Writer; type T ` + test.src
+		pkg, err := makePkg(src)
+		if err != nil {
+			t.Errorf("%s: %s", src, err)
+			continue
+		}
+		typ := pkg.Scope().Lookup("T").Type().Underlying()
+		if got := typ.String(); got != test.str {
+			t.Errorf("%s: got %s, want %s", test.src, got, test.str)
+		}
+	}
+}
+
+var nopos syntax.Pos
+
+func TestIncompleteInterfaces(t *testing.T) {
+	sig := NewSignature(nil, nil, nil, false)
+	m := NewFunc(nopos, nil, "m", sig)
+	for _, test := range []struct {
+		typ  *Interface
+		want string
+	}{
+		{new(Interface), "interface{/* incomplete */}"},
+		{new(Interface).Complete(), "interface{}"},
+
+		{NewInterface(nil, nil), "interface{}"},
+		{NewInterface(nil, nil).Complete(), "interface{}"},
+		{NewInterface([]*Func{}, nil), "interface{}"},
+		{NewInterface([]*Func{}, nil).Complete(), "interface{}"},
+		{NewInterface(nil, []*Named{}), "interface{}"},
+		{NewInterface(nil, []*Named{}).Complete(), "interface{}"},
+		{NewInterface([]*Func{m}, nil), "interface{m() /* incomplete */}"},
+		{NewInterface([]*Func{m}, nil).Complete(), "interface{m()}"},
+		{NewInterface(nil, []*Named{newDefined(new(Interface).Complete())}), "interface{T /* incomplete */}"},
+		{NewInterface(nil, []*Named{newDefined(new(Interface).Complete())}).Complete(), "interface{T}"},
+		{NewInterface(nil, []*Named{newDefined(NewInterface([]*Func{m}, nil))}), "interface{T /* incomplete */}"},
+		{NewInterface(nil, []*Named{newDefined(NewInterface([]*Func{m}, nil).Complete())}), "interface{T /* incomplete */}"},
+		{NewInterface(nil, []*Named{newDefined(NewInterface([]*Func{m}, nil).Complete())}).Complete(), "interface{T}"},
+
+		{NewInterfaceType(nil, nil), "interface{}"},
+		{NewInterfaceType(nil, nil).Complete(), "interface{}"},
+		{NewInterfaceType([]*Func{}, nil), "interface{}"},
+		{NewInterfaceType([]*Func{}, nil).Complete(), "interface{}"},
+		{NewInterfaceType(nil, []Type{}), "interface{}"},
+		{NewInterfaceType(nil, []Type{}).Complete(), "interface{}"},
+		{NewInterfaceType([]*Func{m}, nil), "interface{m() /* incomplete */}"},
+		{NewInterfaceType([]*Func{m}, nil).Complete(), "interface{m()}"},
+		{NewInterfaceType(nil, []Type{new(Interface).Complete()}), "interface{interface{} /* incomplete */}"},
+		{NewInterfaceType(nil, []Type{new(Interface).Complete()}).Complete(), "interface{interface{}}"},
+		{NewInterfaceType(nil, []Type{NewInterfaceType([]*Func{m}, nil)}), "interface{interface{m() /* incomplete */} /* incomplete */}"},
+		{NewInterfaceType(nil, []Type{NewInterfaceType([]*Func{m}, nil).Complete()}), "interface{interface{m()} /* incomplete */}"},
+		{NewInterfaceType(nil, []Type{NewInterfaceType([]*Func{m}, nil).Complete()}).Complete(), "interface{interface{m()}}"},
+	} {
+		got := test.typ.String()
+		if got != test.want {
+			t.Errorf("got: %s, want: %s", got, test.want)
+		}
+	}
+}
+
+// newDefined creates a new defined type named T with the given underlying type.
+// Helper function for use with TestIncompleteInterfaces only.
+func newDefined(underlying Type) *Named {
+	tname := NewTypeName(nopos, nil, "T", nil)
+	return NewNamed(tname, underlying, nil)
+}
+
+func TestQualifiedTypeString(t *testing.T) {
+	p, _ := pkgFor("p.go", "package p; type T int", nil)
+	q, _ := pkgFor("q.go", "package q", nil)
+
+	pT := p.Scope().Lookup("T").Type()
+	for _, test := range []struct {
+		typ  Type
+		this *Package
+		want string
+	}{
+		{nil, nil, "<nil>"},
+		{pT, nil, "p.T"},
+		{pT, p, "T"},
+		{pT, q, "p.T"},
+		{NewPointer(pT), p, "*T"},
+		{NewPointer(pT), q, "*p.T"},
+	} {
+		qualifier := func(pkg *Package) string {
+			if pkg != test.this {
+				return pkg.Name()
+			}
+			return ""
+		}
+		if got := TypeString(test.typ, qualifier); got != test.want {
+			t.Errorf("TypeString(%s, %s) = %s, want %s",
+				test.this, test.typ, got, test.want)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go
new file mode 100644
index 0000000..e64d804
--- /dev/null
+++ b/src/cmd/compile/internal/types2/typexpr.go
@@ -0,0 +1,1268 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements type-checking of identifiers and type expressions.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"go/constant"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+// Disabled by default, but enabled when running tests (via types_test.go).
+var acceptMethodTypeParams bool
+
+// ident type-checks identifier e and initializes x with the value or type of e.
+// If an error occurred, x.mode is set to invalid.
+// For the meaning of def, see Checker.definedType, below.
+// If wantType is set, the identifier e is expected to denote a type.
+//
+func (check *Checker) ident(x *operand, e *syntax.Name, def *Named, wantType bool) {
+	x.mode = invalid
+	x.expr = e
+
+	// Note that we cannot use check.lookup here because the returned scope
+	// may be different from obj.Parent(). See also Scope.LookupParent doc.
+	scope, obj := check.scope.LookupParent(e.Value, check.pos)
+	if obj == nil {
+		if e.Value == "_" {
+			check.error(e, "cannot use _ as value or type")
+		} else {
+			if check.conf.CompilerErrorMessages {
+				check.errorf(e, "undefined: %s", e.Value)
+			} else {
+				check.errorf(e, "undeclared name: %s", e.Value)
+			}
+		}
+		return
+	}
+	check.recordUse(e, obj)
+
+	// Type-check the object.
+	// Only call Checker.objDecl if the object doesn't have a type yet
+	// (in which case we must actually determine it) or the object is a
+	// TypeName and we also want a type (in which case we might detect
+	// a cycle which needs to be reported). Otherwise we can skip the
+	// call and avoid a possible cycle error in favor of the more
+	// informative "not a type/value" error that this function's caller
+	// will issue (see issue #25790).
+	typ := obj.Type()
+	if _, gotType := obj.(*TypeName); typ == nil || gotType && wantType {
+		check.objDecl(obj, def)
+		typ = obj.Type() // type must have been assigned by Checker.objDecl
+	}
+	assert(typ != nil)
+
+	// The object may have been dot-imported.
+	// If so, mark the respective package as used.
+	// (This code is only needed for dot-imports. Without them,
+	// we only have to mark variables, see *Var case below).
+	if pkgName := check.dotImportMap[dotImportKey{scope, obj}]; pkgName != nil {
+		pkgName.used = true
+	}
+
+	switch obj := obj.(type) {
+	case *PkgName:
+		check.errorf(e, "use of package %s not in selector", obj.name)
+		return
+
+	case *Const:
+		check.addDeclDep(obj)
+		if typ == Typ[Invalid] {
+			return
+		}
+		if obj == universeIota {
+			if check.iota == nil {
+				check.error(e, "cannot use iota outside constant declaration")
+				return
+			}
+			x.val = check.iota
+		} else {
+			x.val = obj.val
+		}
+		assert(x.val != nil)
+		x.mode = constant_
+
+	case *TypeName:
+		x.mode = typexpr
+
+	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
+		}
+		check.addDeclDep(obj)
+		if typ == Typ[Invalid] {
+			return
+		}
+		x.mode = variable
+
+	case *Func:
+		check.addDeclDep(obj)
+		x.mode = value
+
+	case *Builtin:
+		x.id = obj.id
+		x.mode = builtin
+
+	case *Nil:
+		x.mode = nilvalue
+
+	default:
+		unreachable()
+	}
+
+	x.typ = typ
+}
+
+// typ type-checks the type expression e and returns its type, or Typ[Invalid].
+// The type must not be an (uninstantiated) generic type.
+func (check *Checker) typ(e syntax.Expr) Type {
+	return check.definedType(e, nil)
+}
+
+// varType type-checks the type expression e and returns its type, or Typ[Invalid].
+// The type must not be an (uninstantiated) generic type and it must be ordinary
+// (see ordinaryType).
+func (check *Checker) varType(e syntax.Expr) Type {
+	typ := check.definedType(e, nil)
+	check.ordinaryType(syntax.StartPos(e), typ)
+	return typ
+}
+
+// ordinaryType reports an error if typ is an interface type containing
+// type lists or is (or embeds) the predeclared type comparable.
+func (check *Checker) ordinaryType(pos syntax.Pos, typ Type) {
+	// We don't want to call under() (via Interface) or complete interfaces while we
+	// are in the middle of type-checking parameter declarations that might belong to
+	// interface methods. Delay this check to the end of type-checking.
+	check.later(func() {
+		if t := asInterface(typ); t != nil {
+			check.completeInterface(pos, t) // TODO(gri) is this the correct position?
+			if t.allTypes != nil {
+				check.softErrorf(pos, "interface contains type constraints (%s)", t.allTypes)
+				return
+			}
+			if t.IsComparable() {
+				check.softErrorf(pos, "interface is (or embeds) comparable")
+			}
+		}
+	})
+}
+
+// anyType type-checks the type expression e and returns its type, or Typ[Invalid].
+// The type may be generic or instantiated.
+func (check *Checker) anyType(e syntax.Expr) Type {
+	typ := check.typInternal(e, nil)
+	assert(isTyped(typ))
+	check.recordTypeAndValue(e, typexpr, typ, nil)
+	return typ
+}
+
+// definedType is like typ but also accepts a type name def.
+// If def != nil, e is the type specification for the defined type def, declared
+// in a type declaration, and def.underlying will be set to the type of e before
+// any components of e are type-checked.
+//
+func (check *Checker) definedType(e syntax.Expr, def *Named) Type {
+	typ := check.typInternal(e, def)
+	assert(isTyped(typ))
+	if isGeneric(typ) {
+		check.errorf(e, "cannot use generic type %s without instantiation", typ)
+		typ = Typ[Invalid]
+	}
+	check.recordTypeAndValue(e, typexpr, typ, nil)
+	return typ
+}
+
+// genericType is like typ but the type must be an (uninstantiated) generic type.
+func (check *Checker) genericType(e syntax.Expr, reportErr bool) Type {
+	typ := check.typInternal(e, nil)
+	assert(isTyped(typ))
+	if typ != Typ[Invalid] && !isGeneric(typ) {
+		if reportErr {
+			check.errorf(e, "%s is not a generic type", typ)
+		}
+		typ = Typ[Invalid]
+	}
+	// TODO(gri) what is the correct call below?
+	check.recordTypeAndValue(e, typexpr, typ, nil)
+	return typ
+}
+
+// isubst returns an x with identifiers substituted per the substitution map smap.
+// isubst only handles the case of (valid) method receiver type expressions correctly.
+func isubst(x syntax.Expr, smap map[*syntax.Name]*syntax.Name) syntax.Expr {
+	switch n := x.(type) {
+	case *syntax.Name:
+		if alt := smap[n]; alt != nil {
+			return alt
+		}
+	// case *syntax.StarExpr:
+	// 	X := isubst(n.X, smap)
+	// 	if X != n.X {
+	// 		new := *n
+	// 		new.X = X
+	// 		return &new
+	// 	}
+	case *syntax.Operation:
+		if n.Op == syntax.Mul && n.Y == nil {
+			X := isubst(n.X, smap)
+			if X != n.X {
+				new := *n
+				new.X = X
+				return &new
+			}
+		}
+	case *syntax.IndexExpr:
+		Index := isubst(n.Index, smap)
+		if Index != n.Index {
+			new := *n
+			new.Index = Index
+			return &new
+		}
+	case *syntax.ListExpr:
+		var elems []syntax.Expr
+		for i, elem := range n.ElemList {
+			new := isubst(elem, smap)
+			if new != elem {
+				if elems == nil {
+					elems = make([]syntax.Expr, len(n.ElemList))
+					copy(elems, n.ElemList)
+				}
+				elems[i] = new
+			}
+		}
+		if elems != nil {
+			new := *n
+			new.ElemList = elems
+			return &new
+		}
+	case *syntax.ParenExpr:
+		return isubst(n.X, smap) // no need to keep parentheses
+	default:
+		// Other receiver type expressions are invalid.
+		// It's fine to ignore those here as they will
+		// be checked elsewhere.
+	}
+	return x
+}
+
+// funcType type-checks a function or method type.
+func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []*syntax.Field, ftyp *syntax.FuncType) {
+	check.openScope(ftyp, "function")
+	check.scope.isFunc = true
+	check.recordScope(ftyp, check.scope)
+	sig.scope = check.scope
+	defer check.closeScope()
+
+	var recvTyp syntax.Expr // rewritten receiver type; valid if != nil
+	if recvPar != nil {
+		// collect generic receiver type parameters, if any
+		// - a receiver type parameter is like any other type parameter, except that it is declared implicitly
+		// - the receiver specification acts as local declaration for its type parameters, which may be blank
+		_, rname, rparams := check.unpackRecv(recvPar.Type, true)
+		if len(rparams) > 0 {
+			// Blank identifiers don't get declared and regular type-checking of the instantiated
+			// parameterized receiver type expression fails in Checker.collectParams of receiver.
+			// Identify blank type parameters and substitute each with a unique new identifier named
+			// "n_" (where n is the parameter index) and which cannot conflict with any user-defined
+			// name.
+			var smap map[*syntax.Name]*syntax.Name // substitution map from "_" to "!n" identifiers
+			for i, p := range rparams {
+				if p.Value == "_" {
+					new := *p
+					new.Value = fmt.Sprintf("%d_", i)
+					rparams[i] = &new // use n_ identifier instead of _ so it can be looked up
+					if smap == nil {
+						smap = make(map[*syntax.Name]*syntax.Name)
+					}
+					smap[p] = &new
+				}
+			}
+			if smap != nil {
+				// blank identifiers were found => use rewritten receiver type
+				recvTyp = isubst(recvPar.Type, smap)
+			}
+			// TODO(gri) rework declareTypeParams
+			sig.rparams = nil
+			for _, rparam := range rparams {
+				sig.rparams = check.declareTypeParam(sig.rparams, rparam)
+			}
+			// determine receiver type to get its type parameters
+			// and the respective type parameter bounds
+			var recvTParams []*TypeName
+			if rname != nil {
+				// recv should be a Named type (otherwise an error is reported elsewhere)
+				// Also: Don't report an error via genericType since it will be reported
+				//       again when we type-check the signature.
+				// TODO(gri) maybe the receiver should be marked as invalid instead?
+				if recv := asNamed(check.genericType(rname, false)); recv != nil {
+					recvTParams = recv.tparams
+				}
+			}
+			// provide type parameter bounds
+			// - only do this if we have the right number (otherwise an error is reported elsewhere)
+			if len(sig.rparams) == len(recvTParams) {
+				// We have a list of *TypeNames but we need a list of Types.
+				list := make([]Type, len(sig.rparams))
+				for i, t := range sig.rparams {
+					list[i] = t.typ
+				}
+				smap := makeSubstMap(recvTParams, list)
+				for i, tname := range sig.rparams {
+					bound := recvTParams[i].typ.(*TypeParam).bound
+					// bound is (possibly) parameterized in the context of the
+					// receiver type declaration. Substitute parameters for the
+					// current context.
+					// TODO(gri) should we assume now that bounds always exist?
+					//           (no bound == empty interface)
+					if bound != nil {
+						bound = check.subst(tname.pos, bound, smap)
+						tname.typ.(*TypeParam).bound = bound
+					}
+				}
+			}
+		}
+	}
+
+	if tparams != nil {
+		sig.tparams = check.collectTypeParams(tparams)
+		// Always type-check method type parameters but complain if they are not enabled.
+		// (A separate check is needed when type-checking interface method signatures because
+		// they don't have a receiver specification.)
+		if recvPar != nil && !acceptMethodTypeParams {
+			check.error(ftyp, "methods cannot have type parameters")
+		}
+	}
+
+	// Value (non-type) parameters' scope starts in the function body. Use a temporary scope for their
+	// declarations and then squash that scope into the parent scope (and report any redeclarations at
+	// that time).
+	scope := NewScope(check.scope, nopos, nopos, "function body (temp. scope)")
+	var recvList []*Var // TODO(gri) remove the need for making a list here
+	if recvPar != nil {
+		recvList, _ = check.collectParams(scope, []*syntax.Field{recvPar}, recvTyp, false) // use rewritten receiver type, if any
+	}
+	params, variadic := check.collectParams(scope, ftyp.ParamList, nil, true)
+	results, _ := check.collectParams(scope, ftyp.ResultList, nil, false)
+	scope.Squash(func(obj, alt Object) {
+		var err error_
+		err.errorf(obj, "%s redeclared in this block", obj.Name())
+		err.recordAltDecl(alt)
+		check.report(&err)
+	})
+
+	if recvPar != nil {
+		// recv parameter list present (may be empty)
+		// spec: "The receiver is specified via an extra parameter section preceding the
+		// method name. That parameter section must declare a single parameter, the receiver."
+		var recv *Var
+		switch len(recvList) {
+		case 0:
+			// error reported by resolver
+			recv = NewParam(nopos, nil, "", Typ[Invalid]) // ignore recv below
+		default:
+			// more than one receiver
+			check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver")
+			fallthrough // continue with first receiver
+		case 1:
+			recv = recvList[0]
+		}
+
+		// TODO(gri) We should delay rtyp expansion to when we actually need the
+		//           receiver; thus all checks here should be delayed to later.
+		rtyp, _ := deref(recv.typ)
+		rtyp = expand(rtyp)
+
+		// spec: "The receiver type must be of the form T or *T where T is a type name."
+		// (ignore invalid types - error was reported before)
+		if t := rtyp; t != Typ[Invalid] {
+			var err string
+			if T := asNamed(t); T != nil {
+				// spec: "The type denoted by T is called the receiver base type; it must not
+				// be a pointer or interface type and it must be declared in the same package
+				// as the method."
+				if T.obj.pkg != check.pkg {
+					err = "type not defined in this package"
+					if check.conf.CompilerErrorMessages {
+						check.errorf(recv.pos, "cannot define new methods on non-local type %s", recv.typ)
+						err = ""
+					}
+				} else {
+					switch u := optype(T).(type) {
+					case *Basic:
+						// unsafe.Pointer is treated like a regular pointer
+						if u.kind == UnsafePointer {
+							err = "unsafe.Pointer"
+						}
+					case *Pointer, *Interface:
+						err = "pointer or interface type"
+					}
+				}
+			} else if T := asBasic(t); T != nil {
+				err = "basic or unnamed type"
+				if check.conf.CompilerErrorMessages {
+					check.errorf(recv.pos, "cannot define new methods on non-local type %s", recv.typ)
+					err = ""
+				}
+			} else {
+				check.errorf(recv.pos, "invalid receiver type %s", recv.typ)
+			}
+			if err != "" {
+				check.errorf(recv.pos, "invalid receiver type %s (%s)", recv.typ, err)
+				// ok to continue
+			}
+		}
+		sig.recv = recv
+	}
+
+	sig.params = NewTuple(params...)
+	sig.results = NewTuple(results...)
+	sig.variadic = variadic
+}
+
+// goTypeName returns the Go type name for typ and
+// removes any occurrences of "types2." from that name.
+func goTypeName(typ Type) string {
+	return strings.Replace(fmt.Sprintf("%T", typ), "types2.", "", -1) // strings.ReplaceAll is not available in Go 1.4
+}
+
+// typInternal drives type checking of types.
+// Must only be called by definedType or genericType.
+//
+func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
+	if check.conf.Trace {
+		check.trace(e0.Pos(), "type %s", e0)
+		check.indent++
+		defer func() {
+			check.indent--
+			var under Type
+			if T != nil {
+				// Calling under() here may lead to endless instantiations.
+				// Test case: type T[P any] *T[P]
+				// TODO(gri) investigate if that's a bug or to be expected
+				// (see also analogous comment in Checker.instantiate).
+				under = T.Underlying()
+			}
+			if T == under {
+				check.trace(e0.Pos(), "=> %s // %s", T, goTypeName(T))
+			} else {
+				check.trace(e0.Pos(), "=> %s (under = %s) // %s", T, under, goTypeName(T))
+			}
+		}()
+	}
+
+	switch e := e0.(type) {
+	case *syntax.BadExpr:
+		// ignore - error reported before
+
+	case *syntax.Name:
+		var x operand
+		check.ident(&x, e, def, true)
+
+		switch x.mode {
+		case typexpr:
+			typ := x.typ
+			def.setUnderlying(typ)
+			return typ
+		case invalid:
+			// ignore - error reported before
+		case novalue:
+			check.errorf(&x, "%s used as type", &x)
+		default:
+			check.errorf(&x, "%s is not a type", &x)
+		}
+
+	case *syntax.SelectorExpr:
+		var x operand
+		check.selector(&x, e)
+
+		switch x.mode {
+		case typexpr:
+			typ := x.typ
+			def.setUnderlying(typ)
+			return typ
+		case invalid:
+			// ignore - error reported before
+		case novalue:
+			check.errorf(&x, "%s used as type", &x)
+		default:
+			check.errorf(&x, "%s is not a type", &x)
+		}
+
+	case *syntax.IndexExpr:
+		return check.instantiatedType(e.X, unpackExpr(e.Index), def)
+
+	case *syntax.ParenExpr:
+		// Generic types must be instantiated before they can be used in any form.
+		// Consequently, generic types cannot be parenthesized.
+		return check.definedType(e.X, def)
+
+	case *syntax.ArrayType:
+		typ := new(Array)
+		def.setUnderlying(typ)
+		if e.Len != nil {
+			typ.len = check.arrayLength(e.Len)
+		} else {
+			// [...]array
+			check.error(e, "invalid use of [...] array (outside a composite literal)")
+			typ.len = -1
+		}
+		typ.elem = check.varType(e.Elem)
+		if typ.len >= 0 {
+			return typ
+		}
+		// report error if we encountered [...]
+
+	case *syntax.SliceType:
+		typ := new(Slice)
+		def.setUnderlying(typ)
+		typ.elem = check.varType(e.Elem)
+		return typ
+
+	case *syntax.DotsType:
+		// dots are handled explicitly where they are legal
+		// (array composite literals and parameter lists)
+		check.error(e, "invalid use of '...'")
+		check.use(e.Elem)
+
+	case *syntax.StructType:
+		typ := new(Struct)
+		def.setUnderlying(typ)
+		check.structType(typ, e)
+		return typ
+
+	case *syntax.Operation:
+		if e.Op == syntax.Mul && e.Y == nil {
+			typ := new(Pointer)
+			def.setUnderlying(typ)
+			typ.base = check.varType(e.X)
+			return typ
+		}
+
+		check.errorf(e0, "%s is not a type", e0)
+		check.use(e0)
+
+	case *syntax.FuncType:
+		typ := new(Signature)
+		def.setUnderlying(typ)
+		check.funcType(typ, nil, nil, e)
+		return typ
+
+	case *syntax.InterfaceType:
+		typ := new(Interface)
+		def.setUnderlying(typ)
+		if def != nil {
+			typ.obj = def.obj
+		}
+		check.interfaceType(typ, e, def)
+		return typ
+
+	case *syntax.MapType:
+		typ := new(Map)
+		def.setUnderlying(typ)
+
+		typ.key = check.varType(e.Key)
+		typ.elem = check.varType(e.Value)
+
+		// spec: "The comparison operators == and != must be fully defined
+		// for operands of the key type; thus the key type must not be a
+		// function, map, or slice."
+		//
+		// Delay this check because it requires fully setup types;
+		// it is safe to continue in any case (was issue 6667).
+		check.later(func() {
+			if !Comparable(typ.key) {
+				var why string
+				if asTypeParam(typ.key) != nil {
+					why = " (missing comparable constraint)"
+				}
+				check.errorf(e.Key, "invalid map key type %s%s", typ.key, why)
+			}
+		})
+
+		return typ
+
+	case *syntax.ChanType:
+		typ := new(Chan)
+		def.setUnderlying(typ)
+
+		dir := SendRecv
+		switch e.Dir {
+		case 0:
+			// nothing to do
+		case syntax.SendOnly:
+			dir = SendOnly
+		case syntax.RecvOnly:
+			dir = RecvOnly
+		default:
+			check.errorf(e, invalidAST+"unknown channel direction %d", e.Dir)
+			// ok to continue
+		}
+
+		typ.dir = dir
+		typ.elem = check.varType(e.Elem)
+		return typ
+
+	default:
+		check.errorf(e0, "%s is not a type", e0)
+		check.use(e0)
+	}
+
+	typ := Typ[Invalid]
+	def.setUnderlying(typ)
+	return typ
+}
+
+// typeOrNil type-checks the type expression (or nil value) e
+// and returns the type of e, or nil. If e is a type, it must
+// not be an (uninstantiated) generic type.
+// If e is neither a type nor nil, typeOrNil returns Typ[Invalid].
+// TODO(gri) should we also disallow non-var types?
+func (check *Checker) typOrNil(e syntax.Expr) Type {
+	var x operand
+	check.rawExpr(&x, e, nil)
+	switch x.mode {
+	case invalid:
+		// ignore - error reported before
+	case novalue:
+		check.errorf(&x, "%s used as type", &x)
+	case typexpr:
+		check.instantiatedOperand(&x)
+		return x.typ
+	case nilvalue:
+		return nil
+	default:
+		check.errorf(&x, "%s is not a type", &x)
+	}
+	return Typ[Invalid]
+}
+
+func (check *Checker) instantiatedType(x syntax.Expr, targs []syntax.Expr, def *Named) Type {
+	b := check.genericType(x, true) // TODO(gri) what about cycles?
+	if b == Typ[Invalid] {
+		return b // error already reported
+	}
+	base := asNamed(b)
+	if base == nil {
+		unreachable() // should have been caught by genericType
+	}
+
+	// create a new type instance rather than instantiate the type
+	// TODO(gri) should do argument number check here rather than
+	//           when instantiating the type?
+	typ := new(instance)
+	def.setUnderlying(typ)
+
+	typ.check = check
+	typ.pos = x.Pos()
+	typ.base = base
+
+	// evaluate arguments (always)
+	typ.targs = check.typeList(targs)
+	if typ.targs == nil {
+		def.setUnderlying(Typ[Invalid]) // avoid later errors due to lazy instantiation
+		return Typ[Invalid]
+	}
+
+	// determine argument positions (for error reporting)
+	typ.poslist = make([]syntax.Pos, len(targs))
+	for i, arg := range targs {
+		typ.poslist[i] = syntax.StartPos(arg)
+	}
+
+	// make sure we check instantiation works at least once
+	// and that the resulting type is valid
+	check.later(func() {
+		t := typ.expand()
+		check.validType(t, nil)
+	})
+
+	return typ
+}
+
+// arrayLength type-checks the array length expression e
+// and returns the constant length >= 0, or a value < 0
+// to indicate an error (and thus an unknown length).
+func (check *Checker) arrayLength(e syntax.Expr) int64 {
+	var x operand
+	check.expr(&x, e)
+	if x.mode != constant_ {
+		if x.mode != invalid {
+			check.errorf(&x, "array length %s must be constant", &x)
+		}
+		return -1
+	}
+	if isUntyped(x.typ) || isInteger(x.typ) {
+		if val := constant.ToInt(x.val); val.Kind() == constant.Int {
+			if representableConst(val, check, Typ[Int], nil) {
+				if n, ok := constant.Int64Val(val); ok && n >= 0 {
+					return n
+				}
+				check.errorf(&x, "invalid array length %s", &x)
+				return -1
+			}
+		}
+	}
+	check.errorf(&x, "array length %s must be integer", &x)
+	return -1
+}
+
+// typeList provides the list of types corresponding to the incoming expression list.
+// If an error occurred, the result is nil, but all list elements were type-checked.
+func (check *Checker) typeList(list []syntax.Expr) []Type {
+	res := make([]Type, len(list)) // res != nil even if len(list) == 0
+	for i, x := range list {
+		t := check.varType(x)
+		if t == Typ[Invalid] {
+			res = nil
+		}
+		if res != nil {
+			res[i] = t
+		}
+	}
+	return res
+}
+
+// collectParams declares the parameters of list in scope and returns the corresponding
+// variable list. If type0 != nil, it is used instead of the first type in list.
+func (check *Checker) collectParams(scope *Scope, list []*syntax.Field, type0 syntax.Expr, variadicOk bool) (params []*Var, variadic bool) {
+	if list == nil {
+		return
+	}
+
+	var named, anonymous bool
+
+	var typ Type
+	var prev syntax.Expr
+	for i, field := range list {
+		ftype := field.Type
+		// type-check type of grouped fields only once
+		if ftype != prev {
+			prev = ftype
+			if i == 0 && type0 != nil {
+				ftype = type0
+			}
+			if t, _ := ftype.(*syntax.DotsType); t != nil {
+				ftype = t.Elem
+				if variadicOk && i == len(list)-1 {
+					variadic = true
+				} else {
+					check.softErrorf(t, "can only use ... with final parameter in list")
+					// ignore ... and continue
+				}
+			}
+			typ = check.varType(ftype)
+		}
+		// The parser ensures that f.Tag is nil and we don't
+		// care if a constructed AST contains a non-nil tag.
+		if field.Name != nil {
+			// named parameter
+			name := field.Name.Value
+			if name == "" {
+				check.error(field.Name, invalidAST+"anonymous parameter")
+				// ok to continue
+			}
+			par := NewParam(field.Name.Pos(), check.pkg, name, typ)
+			check.declare(scope, field.Name, par, scope.pos)
+			params = append(params, par)
+			named = true
+		} else {
+			// anonymous parameter
+			par := NewParam(ftype.Pos(), check.pkg, "", typ)
+			check.recordImplicit(field, par)
+			params = append(params, par)
+			anonymous = true
+		}
+	}
+
+	if named && anonymous {
+		check.error(list[0], invalidAST+"list contains both named and anonymous parameters")
+		// ok to continue
+	}
+
+	// For a variadic function, change the last parameter's type from T to []T.
+	// Since we type-checked T rather than ...T, we also need to retro-actively
+	// record the type for ...T.
+	if variadic {
+		last := params[len(params)-1]
+		last.typ = &Slice{elem: last.typ}
+		check.recordTypeAndValue(list[len(list)-1].Type, typexpr, last.typ, nil)
+	}
+
+	return
+}
+
+func (check *Checker) declareInSet(oset *objset, pos syntax.Pos, obj Object) bool {
+	if alt := oset.insert(obj); alt != nil {
+		var err error_
+		err.errorf(pos, "%s redeclared", obj.Name())
+		err.recordAltDecl(alt)
+		check.report(&err)
+		return false
+	}
+	return true
+}
+
+func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType, def *Named) {
+	var tname *syntax.Name // most recent "type" name
+	var types []syntax.Expr
+	for _, f := range iface.MethodList {
+		if f.Name != nil {
+			// We have a method with name f.Name, or a type
+			// of a type list (f.Name.Value == "type").
+			name := f.Name.Value
+			if name == "_" {
+				if check.conf.CompilerErrorMessages {
+					check.error(f.Name, "methods must have a unique non-blank name")
+				} else {
+					check.error(f.Name, "invalid method name _")
+				}
+				continue // ignore
+			}
+
+			if name == "type" {
+				// Always collect all type list entries, even from
+				// different type lists, under the assumption that
+				// the author intended to include all types.
+				types = append(types, f.Type)
+				if tname != nil && tname != f.Name {
+					check.error(f.Name, "cannot have multiple type lists in an interface")
+				}
+				tname = f.Name
+				continue
+			}
+
+			typ := check.typ(f.Type)
+			sig, _ := typ.(*Signature)
+			if sig == nil {
+				if typ != Typ[Invalid] {
+					check.errorf(f.Type, invalidAST+"%s is not a method signature", typ)
+				}
+				continue // ignore
+			}
+
+			// Always type-check method type parameters but complain if they are not enabled.
+			// (This extra check is needed here because interface method signatures don't have
+			// a receiver specification.)
+			if sig.tparams != nil && !acceptMethodTypeParams {
+				check.error(f.Type, "methods cannot have type parameters")
+			}
+
+			// use named receiver type if available (for better error messages)
+			var recvTyp Type = ityp
+			if def != nil {
+				recvTyp = def
+			}
+			sig.recv = NewVar(f.Name.Pos(), check.pkg, "", recvTyp)
+
+			m := NewFunc(f.Name.Pos(), check.pkg, name, sig)
+			check.recordDef(f.Name, m)
+			ityp.methods = append(ityp.methods, m)
+		} else {
+			// We have an embedded type. completeInterface will
+			// eventually verify that we have an interface.
+			ityp.embeddeds = append(ityp.embeddeds, check.typ(f.Type))
+			check.posMap[ityp] = append(check.posMap[ityp], f.Type.Pos())
+		}
+	}
+
+	// type constraints
+	ityp.types = NewSum(check.collectTypeConstraints(iface.Pos(), types))
+
+	if len(ityp.methods) == 0 && ityp.types == nil && len(ityp.embeddeds) == 0 {
+		// empty interface
+		ityp.allMethods = markComplete
+		return
+	}
+
+	// sort for API stability
+	sortMethods(ityp.methods)
+	sortTypes(ityp.embeddeds)
+
+	check.later(func() { check.completeInterface(iface.Pos(), ityp) })
+}
+
+func (check *Checker) completeInterface(pos syntax.Pos, ityp *Interface) {
+	if ityp.allMethods != nil {
+		return
+	}
+
+	// completeInterface may be called via the LookupFieldOrMethod,
+	// MissingMethod, Identical, or IdenticalIgnoreTags external API
+	// in which case check will be nil. In this case, type-checking
+	// must be finished and all interfaces should have been completed.
+	if check == nil {
+		panic("internal error: incomplete interface")
+	}
+
+	if check.conf.Trace {
+		// Types don't generally have position information.
+		// If we don't have a valid pos provided, try to use
+		// one close enough.
+		if !pos.IsKnown() && len(ityp.methods) > 0 {
+			pos = ityp.methods[0].pos
+		}
+
+		check.trace(pos, "complete %s", ityp)
+		check.indent++
+		defer func() {
+			check.indent--
+			check.trace(pos, "=> %s (methods = %v, types = %v)", ityp, ityp.allMethods, ityp.allTypes)
+		}()
+	}
+
+	// An infinitely expanding interface (due to a cycle) is detected
+	// elsewhere (Checker.validType), so here we simply assume we only
+	// have valid interfaces. Mark the interface as complete to avoid
+	// infinite recursion if the validType check occurs later for some
+	// reason.
+	ityp.allMethods = markComplete
+
+	// Methods of embedded interfaces are collected unchanged; i.e., the identity
+	// of a method I.m's Func Object of an interface I is the same as that of
+	// the method m in an interface that embeds interface I. On the other hand,
+	// if a method is embedded via multiple overlapping embedded interfaces, we
+	// don't provide a guarantee which "original m" got chosen for the embedding
+	// interface. See also issue #34421.
+	//
+	// If we don't care to provide this identity guarantee anymore, instead of
+	// reusing the original method in embeddings, we can clone the method's Func
+	// Object and give it the position of a corresponding embedded interface. Then
+	// we can get rid of the mpos map below and simply use the cloned method's
+	// position.
+
+	var seen objset
+	var methods []*Func
+	mpos := make(map[*Func]syntax.Pos) // method specification or method embedding position, for good error messages
+	addMethod := func(pos syntax.Pos, m *Func, explicit bool) {
+		switch other := seen.insert(m); {
+		case other == nil:
+			methods = append(methods, m)
+			mpos[m] = pos
+		case explicit:
+			var err error_
+			err.errorf(pos, "duplicate method %s", m.name)
+			err.errorf(mpos[other.(*Func)], "other declaration of %s", m.name)
+			check.report(&err)
+		default:
+			// We have a duplicate method name in an embedded (not explicitly declared) method.
+			// Check method signatures after all types are computed (issue #33656).
+			// If we're pre-go1.14 (overlapping embeddings are not permitted), report that
+			// error here as well (even though we could do it eagerly) because it's the same
+			// error message.
+			check.later(func() {
+				if !check.allowVersion(m.pkg, 1, 14) || !check.identical(m.typ, other.Type()) {
+					var err error_
+					err.errorf(pos, "duplicate method %s", m.name)
+					err.errorf(mpos[other.(*Func)], "other declaration of %s", m.name)
+					check.report(&err)
+				}
+			})
+		}
+	}
+
+	for _, m := range ityp.methods {
+		addMethod(m.pos, m, true)
+	}
+
+	// collect types
+	allTypes := ityp.types
+
+	posList := check.posMap[ityp]
+	for i, typ := range ityp.embeddeds {
+		pos := posList[i] // embedding position
+		utyp := under(typ)
+		etyp := asInterface(utyp)
+		if etyp == nil {
+			if utyp != Typ[Invalid] {
+				var format string
+				if _, ok := utyp.(*TypeParam); ok {
+					format = "%s is a type parameter, not an interface"
+				} else {
+					format = "%s is not an interface"
+				}
+				check.errorf(pos, format, typ)
+			}
+			continue
+		}
+		check.completeInterface(pos, etyp)
+		for _, m := range etyp.allMethods {
+			addMethod(pos, m, false) // use embedding position pos rather than m.pos
+		}
+		allTypes = intersect(allTypes, etyp.allTypes)
+	}
+
+	if methods != nil {
+		sortMethods(methods)
+		ityp.allMethods = methods
+	}
+	ityp.allTypes = allTypes
+}
+
+// intersect computes the intersection of the types x and y.
+// Note: A incomming nil type stands for the top type. A top
+// type result is returned as nil.
+func intersect(x, y Type) (r Type) {
+	defer func() {
+		if r == theTop {
+			r = nil
+		}
+	}()
+
+	switch {
+	case x == theBottom || y == theBottom:
+		return theBottom
+	case x == nil || x == theTop:
+		return y
+	case y == nil || x == theTop:
+		return x
+	}
+
+	xtypes := unpack(x)
+	ytypes := unpack(y)
+	// Compute the list rtypes which includes only
+	// types that are in both xtypes and ytypes.
+	// Quadratic algorithm, but good enough for now.
+	// TODO(gri) fix this
+	var rtypes []Type
+	for _, x := range xtypes {
+		if includes(ytypes, x) {
+			rtypes = append(rtypes, x)
+		}
+	}
+
+	if rtypes == nil {
+		return theBottom
+	}
+	return NewSum(rtypes)
+}
+
+func sortTypes(list []Type) {
+	sort.Stable(byUniqueTypeName(list))
+}
+
+// byUniqueTypeName named type lists can be sorted by their unique type names.
+type byUniqueTypeName []Type
+
+func (a byUniqueTypeName) Len() int           { return len(a) }
+func (a byUniqueTypeName) Less(i, j int) bool { return sortName(a[i]) < sortName(a[j]) }
+func (a byUniqueTypeName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+
+func sortName(t Type) string {
+	if named := asNamed(t); named != nil {
+		return named.obj.Id()
+	}
+	return ""
+}
+
+func sortMethods(list []*Func) {
+	sort.Sort(byUniqueMethodName(list))
+}
+
+func assertSortedMethods(list []*Func) {
+	if !debug {
+		panic("internal error: assertSortedMethods called outside debug mode")
+	}
+	if !sort.IsSorted(byUniqueMethodName(list)) {
+		panic("internal error: methods not sorted")
+	}
+}
+
+// byUniqueMethodName method lists can be sorted by their unique method names.
+type byUniqueMethodName []*Func
+
+func (a byUniqueMethodName) Len() int           { return len(a) }
+func (a byUniqueMethodName) Less(i, j int) bool { return a[i].less(a[j]) }
+func (a byUniqueMethodName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+
+func (check *Checker) tag(t *syntax.BasicLit) string {
+	// If t.Bad, an error was reported during parsing.
+	if t != nil && !t.Bad {
+		if t.Kind == syntax.StringLit {
+			if val, err := strconv.Unquote(t.Value); err == nil {
+				return val
+			}
+		}
+		check.errorf(t, invalidAST+"incorrect tag syntax: %q", t.Value)
+	}
+	return ""
+}
+
+func (check *Checker) structType(styp *Struct, e *syntax.StructType) {
+	if e.FieldList == nil {
+		return
+	}
+
+	// struct fields and tags
+	var fields []*Var
+	var tags []string
+
+	// for double-declaration checks
+	var fset objset
+
+	// current field typ and tag
+	var typ Type
+	var tag string
+	add := func(ident *syntax.Name, embedded bool, pos syntax.Pos) {
+		if tag != "" && tags == nil {
+			tags = make([]string, len(fields))
+		}
+		if tags != nil {
+			tags = append(tags, tag)
+		}
+
+		name := ident.Value
+		fld := NewField(pos, check.pkg, name, typ, embedded)
+		// spec: "Within a struct, non-blank field names must be unique."
+		if name == "_" || check.declareInSet(&fset, pos, fld) {
+			fields = append(fields, fld)
+			check.recordDef(ident, fld)
+		}
+	}
+
+	// addInvalid adds an embedded field of invalid type to the struct for
+	// fields with errors; this keeps the number of struct fields in sync
+	// with the source as long as the fields are _ or have different names
+	// (issue #25627).
+	addInvalid := func(ident *syntax.Name, pos syntax.Pos) {
+		typ = Typ[Invalid]
+		tag = ""
+		add(ident, true, pos)
+	}
+
+	var prev syntax.Expr
+	for i, f := range e.FieldList {
+		// Fields declared syntactically with the same type (e.g.: a, b, c T)
+		// share the same type expression. Only check type if it's a new type.
+		if i == 0 || f.Type != prev {
+			typ = check.varType(f.Type)
+			prev = f.Type
+		}
+		tag = ""
+		if i < len(e.TagList) {
+			tag = check.tag(e.TagList[i])
+		}
+		if f.Name != nil {
+			// named field
+			add(f.Name, false, f.Name.Pos())
+		} else {
+			// embedded field
+			// spec: "An embedded type must be specified as a type name T or as a
+			// pointer to a non-interface type name *T, and T itself may not be a
+			// pointer type."
+			pos := syntax.StartPos(f.Type)
+			name := embeddedFieldIdent(f.Type)
+			if name == nil {
+				check.errorf(pos, "invalid embedded field type %s", f.Type)
+				name = &syntax.Name{Value: "_"} // TODO(gri) need to set position to pos
+				addInvalid(name, pos)
+				continue
+			}
+			add(name, true, pos)
+
+			// Because we have a name, typ must be of the form T or *T, where T is the name
+			// of a (named or alias) type, and t (= deref(typ)) must be the type of T.
+			// We must delay this check to the end because we don't want to instantiate
+			// (via under(t)) a possibly incomplete type.
+			embeddedTyp := typ // for closure below
+			embeddedPos := pos
+			check.later(func() {
+				t, isPtr := deref(embeddedTyp)
+				switch t := optype(t).(type) {
+				case *Basic:
+					if t == Typ[Invalid] {
+						// error was reported before
+						return
+					}
+					// unsafe.Pointer is treated like a regular pointer
+					if t.kind == UnsafePointer {
+						check.error(embeddedPos, "embedded field type cannot be unsafe.Pointer")
+					}
+				case *Pointer:
+					check.error(embeddedPos, "embedded field type cannot be a pointer")
+				case *Interface:
+					if isPtr {
+						check.error(embeddedPos, "embedded field type cannot be a pointer to an interface")
+					}
+				}
+			})
+		}
+	}
+
+	styp.fields = fields
+	styp.tags = tags
+}
+
+func embeddedFieldIdent(e syntax.Expr) *syntax.Name {
+	switch e := e.(type) {
+	case *syntax.Name:
+		return e
+	case *syntax.Operation:
+		if base := ptrBase(e); base != nil {
+			// *T is valid, but **T is not
+			if op, _ := base.(*syntax.Operation); op == nil || ptrBase(op) == nil {
+				return embeddedFieldIdent(e.X)
+			}
+		}
+	case *syntax.SelectorExpr:
+		return e.Sel
+	case *syntax.IndexExpr:
+		return embeddedFieldIdent(e.X)
+	}
+	return nil // invalid embedded field
+}
+
+func (check *Checker) collectTypeConstraints(pos syntax.Pos, types []syntax.Expr) []Type {
+	list := make([]Type, 0, len(types)) // assume all types are correct
+	for _, texpr := range types {
+		if texpr == nil {
+			check.error(pos, invalidAST+"missing type constraint")
+			continue
+		}
+		list = append(list, check.varType(texpr))
+	}
+
+	// Ensure that each type is only present once in the type list.  Types may be
+	// interfaces, which may not be complete yet. It's ok to do this check at the
+	// end because it's not a requirement for correctness of the code.
+	// Note: This is a quadratic algorithm, but type lists tend to be short.
+	check.later(func() {
+		for i, t := range list {
+			if t := asInterface(t); t != nil {
+				check.completeInterface(types[i].Pos(), t)
+			}
+			if includes(list[:i], t) {
+				check.softErrorf(types[i], "duplicate type %s in type list", t)
+			}
+		}
+	})
+
+	return list
+}
+
+// includes reports whether typ is in list
+func includes(list []Type, typ Type) bool {
+	for _, e := range list {
+		if Identical(typ, e) {
+			return true
+		}
+	}
+	return false
+}
+
+func ptrBase(x *syntax.Operation) syntax.Expr {
+	if x.Op == syntax.Mul && x.Y == nil {
+		return x.X
+	}
+	return nil
+}
diff --git a/src/cmd/compile/internal/types2/unify.go b/src/cmd/compile/internal/types2/unify.go
new file mode 100644
index 0000000..e1832bb
--- /dev/null
+++ b/src/cmd/compile/internal/types2/unify.go
@@ -0,0 +1,469 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements type unification.
+
+package types2
+
+import "bytes"
+
+// The unifier maintains two separate sets of type parameters x and y
+// which are used to resolve type parameters in the x and y arguments
+// provided to the unify call. For unidirectional unification, only
+// one of these sets (say x) is provided, and then type parameters are
+// only resolved for the x argument passed to unify, not the y argument
+// (even if that also contains possibly the same type parameters). This
+// is crucial to infer the type parameters of self-recursive calls:
+//
+//	func f[P any](a P) { f(a) }
+//
+// For the call f(a) we want to infer that the type argument for P is P.
+// During unification, the parameter type P must be resolved to the type
+// parameter P ("x" side), but the argument type P must be left alone so
+// that unification resolves the type parameter P to P.
+//
+// For bidirection unification, both sets are provided. This enables
+// unification to go from argument to parameter type and vice versa.
+// For constraint type inference, we use bidirectional unification
+// where both the x and y type parameters are identical. This is done
+// by setting up one of them (using init) and then assigning its value
+// to the other.
+
+// A unifier maintains the current type parameters for x and y
+// and the respective types inferred for each type parameter.
+// A unifier is created by calling newUnifier.
+type unifier struct {
+	check *Checker
+	exact bool
+	x, y  tparamsList // x and y must initialized via tparamsList.init
+	types []Type      // inferred types, shared by x and y
+}
+
+// newUnifier returns a new unifier.
+// If exact is set, unification requires unified types to match
+// exactly. If exact is not set, a named type's underlying type
+// is considered if unification would fail otherwise, and the
+// direction of channels is ignored.
+func newUnifier(check *Checker, exact bool) *unifier {
+	u := &unifier{check: check, exact: exact}
+	u.x.unifier = u
+	u.y.unifier = u
+	return u
+}
+
+// unify attempts to unify x and y and reports whether it succeeded.
+func (u *unifier) unify(x, y Type) bool {
+	return u.nify(x, y, nil)
+}
+
+// A tparamsList describes a list of type parameters and the types inferred for them.
+type tparamsList struct {
+	unifier *unifier
+	tparams []*TypeName
+	// For each tparams element, there is a corresponding type slot index in indices.
+	// index  < 0: unifier.types[-index-1] == nil
+	// index == 0: no type slot allocated yet
+	// index  > 0: unifier.types[index-1] == typ
+	// Joined tparams elements share the same type slot and thus have the same index.
+	// By using a negative index for nil types we don't need to check unifier.types
+	// to see if we have a type or not.
+	indices []int // len(d.indices) == len(d.tparams)
+}
+
+// String returns a string representation for a tparamsList. For debugging.
+func (d *tparamsList) String() string {
+	var buf bytes.Buffer
+	buf.WriteByte('[')
+	for i, tname := range d.tparams {
+		if i > 0 {
+			buf.WriteString(", ")
+		}
+		writeType(&buf, tname.typ, nil, nil)
+		buf.WriteString(": ")
+		writeType(&buf, d.at(i), nil, nil)
+	}
+	buf.WriteByte(']')
+	return buf.String()
+}
+
+// init initializes d with the given type parameters.
+// The type parameters must be in the order in which they appear in their declaration
+// (this ensures that the tparams indices match the respective type parameter index).
+func (d *tparamsList) init(tparams []*TypeName) {
+	if len(tparams) == 0 {
+		return
+	}
+	if debug {
+		for i, tpar := range tparams {
+			assert(i == tpar.typ.(*TypeParam).index)
+		}
+	}
+	d.tparams = tparams
+	d.indices = make([]int, len(tparams))
+}
+
+// join unifies the i'th type parameter of x with the j'th type parameter of y.
+// If both type parameters already have a type associated with them and they are
+// not joined, join fails and return false.
+func (u *unifier) join(i, j int) bool {
+	ti := u.x.indices[i]
+	tj := u.y.indices[j]
+	switch {
+	case ti == 0 && tj == 0:
+		// Neither type parameter has a type slot associated with them.
+		// Allocate a new joined nil type slot (negative index).
+		u.types = append(u.types, nil)
+		u.x.indices[i] = -len(u.types)
+		u.y.indices[j] = -len(u.types)
+	case ti == 0:
+		// The type parameter for x has no type slot yet. Use slot of y.
+		u.x.indices[i] = tj
+	case tj == 0:
+		// The type parameter for y has no type slot yet. Use slot of x.
+		u.y.indices[j] = ti
+
+	// Both type parameters have a slot: ti != 0 && tj != 0.
+	case ti == tj:
+		// Both type parameters already share the same slot. Nothing to do.
+		break
+	case ti > 0 && tj > 0:
+		// Both type parameters have (possibly different) inferred types. Cannot join.
+		return false
+	case ti > 0:
+		// Only the type parameter for x has an inferred type. Use x slot for y.
+		u.y.setIndex(j, ti)
+	// This case is handled like the default case.
+	// case tj > 0:
+	// 	// Only the type parameter for y has an inferred type. Use y slot for x.
+	// 	u.x.setIndex(i, tj)
+	default:
+		// Neither type parameter has an inferred type. Use y slot for x
+		// (or x slot for y, it doesn't matter).
+		u.x.setIndex(i, tj)
+	}
+	return true
+}
+
+// If typ is a type parameter of d, index returns the type parameter index.
+// Otherwise, the result is < 0.
+func (d *tparamsList) index(typ Type) int {
+	if t, ok := typ.(*TypeParam); ok {
+		if i := t.index; i < len(d.tparams) && d.tparams[i].typ == t {
+			return i
+		}
+	}
+	return -1
+}
+
+// setIndex sets the type slot index for the i'th type parameter
+// (and all its joined parameters) to tj. The type parameter
+// must have a (possibly nil) type slot associated with it.
+func (d *tparamsList) setIndex(i, tj int) {
+	ti := d.indices[i]
+	assert(ti != 0 && tj != 0)
+	for k, tk := range d.indices {
+		if tk == ti {
+			d.indices[k] = tj
+		}
+	}
+}
+
+// at returns the type set for the i'th type parameter; or nil.
+func (d *tparamsList) at(i int) Type {
+	if ti := d.indices[i]; ti > 0 {
+		return d.unifier.types[ti-1]
+	}
+	return nil
+}
+
+// set sets the type typ for the i'th type parameter;
+// typ must not be nil and it must not have been set before.
+func (d *tparamsList) set(i int, typ Type) {
+	assert(typ != nil)
+	u := d.unifier
+	switch ti := d.indices[i]; {
+	case ti < 0:
+		u.types[-ti-1] = typ
+		d.setIndex(i, -ti)
+	case ti == 0:
+		u.types = append(u.types, typ)
+		d.indices[i] = len(u.types)
+	default:
+		panic("type already set")
+	}
+}
+
+// types returns the list of inferred types (via unification) for the type parameters
+// described by d, and an index. If all types were inferred, the returned index is < 0.
+// Otherwise, it is the index of the first type parameter which couldn't be inferred;
+// i.e., for which list[index] is nil.
+func (d *tparamsList) types() (list []Type, index int) {
+	list = make([]Type, len(d.tparams))
+	index = -1
+	for i := range d.tparams {
+		t := d.at(i)
+		list[i] = t
+		if index < 0 && t == nil {
+			index = i
+		}
+	}
+	return
+}
+
+func (u *unifier) nifyEq(x, y Type, p *ifacePair) bool {
+	return x == y || u.nify(x, y, p)
+}
+
+// nify implements the core unification algorithm which is an
+// adapted version of Checker.identical0. For changes to that
+// code the corresponding changes should be made here.
+// Must not be called directly from outside the unifier.
+func (u *unifier) nify(x, y Type, p *ifacePair) bool {
+	// types must be expanded for comparison
+	x = expand(x)
+	y = expand(y)
+
+	if !u.exact {
+		// If exact unification is known to fail because we attempt to
+		// match a type name against an unnamed type literal, consider
+		// the underlying type of the named type.
+		// (Subtle: We use isNamed to include any type with a name (incl.
+		// basic types and type parameters. We use asNamed because we only
+		// want *Named types.)
+		switch {
+		case !isNamed(x) && y != nil && asNamed(y) != nil:
+			return u.nify(x, under(y), p)
+		case x != nil && asNamed(x) != nil && !isNamed(y):
+			return u.nify(under(x), y, p)
+		}
+	}
+
+	// Cases where at least one of x or y is a type parameter.
+	switch i, j := u.x.index(x), u.y.index(y); {
+	case i >= 0 && j >= 0:
+		// both x and y are type parameters
+		if u.join(i, j) {
+			return true
+		}
+		// both x and y have an inferred type - they must match
+		return u.nifyEq(u.x.at(i), u.y.at(j), p)
+
+	case i >= 0:
+		// x is a type parameter, y is not
+		if tx := u.x.at(i); tx != nil {
+			return u.nifyEq(tx, y, p)
+		}
+		// otherwise, infer type from y
+		u.x.set(i, y)
+		return true
+
+	case j >= 0:
+		// y is a type parameter, x is not
+		if ty := u.y.at(j); ty != nil {
+			return u.nifyEq(x, ty, p)
+		}
+		// otherwise, infer type from x
+		u.y.set(j, x)
+		return true
+	}
+
+	// For type unification, do not shortcut (x == y) for identical
+	// types. Instead keep comparing them element-wise to unify the
+	// matching (and equal type parameter types). A simple test case
+	// where this matters is: func f[P any](a P) { f(a) } .
+
+	switch x := x.(type) {
+	case *Basic:
+		// Basic types are singletons except for the rune and byte
+		// aliases, thus we cannot solely rely on the x == y check
+		// above. See also comment in TypeName.IsAlias.
+		if y, ok := y.(*Basic); ok {
+			return x.kind == y.kind
+		}
+
+	case *Array:
+		// Two array types are identical if they have identical element types
+		// and the same array length.
+		if y, ok := y.(*Array); ok {
+			// If one or both array lengths are unknown (< 0) due to some error,
+			// assume they are the same to avoid spurious follow-on errors.
+			return (x.len < 0 || y.len < 0 || x.len == y.len) && u.nify(x.elem, y.elem, p)
+		}
+
+	case *Slice:
+		// Two slice types are identical if they have identical element types.
+		if y, ok := y.(*Slice); ok {
+			return u.nify(x.elem, y.elem, p)
+		}
+
+	case *Struct:
+		// Two struct types are identical if they have the same sequence of fields,
+		// and if corresponding fields have the same names, and identical types,
+		// and identical tags. Two embedded fields are considered to have the same
+		// name. Lower-case field names from different packages are always different.
+		if y, ok := y.(*Struct); ok {
+			if x.NumFields() == y.NumFields() {
+				for i, f := range x.fields {
+					g := y.fields[i]
+					if f.embedded != g.embedded ||
+						x.Tag(i) != y.Tag(i) ||
+						!f.sameId(g.pkg, g.name) ||
+						!u.nify(f.typ, g.typ, p) {
+						return false
+					}
+				}
+				return true
+			}
+		}
+
+	case *Pointer:
+		// Two pointer types are identical if they have identical base types.
+		if y, ok := y.(*Pointer); ok {
+			return u.nify(x.base, y.base, p)
+		}
+
+	case *Tuple:
+		// Two tuples types are identical if they have the same number of elements
+		// and corresponding elements have identical types.
+		if y, ok := y.(*Tuple); ok {
+			if x.Len() == y.Len() {
+				if x != nil {
+					for i, v := range x.vars {
+						w := y.vars[i]
+						if !u.nify(v.typ, w.typ, p) {
+							return false
+						}
+					}
+				}
+				return true
+			}
+		}
+
+	case *Signature:
+		// Two function types are identical if they have the same number of parameters
+		// and result values, corresponding parameter and result types are identical,
+		// and either both functions are variadic or neither is. Parameter and result
+		// names are not required to match.
+		// TODO(gri) handle type parameters or document why we can ignore them.
+		if y, ok := y.(*Signature); ok {
+			return x.variadic == y.variadic &&
+				u.nify(x.params, y.params, p) &&
+				u.nify(x.results, y.results, p)
+		}
+
+	case *Sum:
+		// This should not happen with the current internal use of sum types.
+		panic("type inference across sum types not implemented")
+
+	case *Interface:
+		// Two interface types are identical if they have the same set of methods with
+		// the same names and identical function types. Lower-case method names from
+		// different packages are always different. The order of the methods is irrelevant.
+		if y, ok := y.(*Interface); ok {
+			// If identical0 is called (indirectly) via an external API entry point
+			// (such as Identical, IdenticalIgnoreTags, etc.), check is nil. But in
+			// that case, interfaces are expected to be complete and lazy completion
+			// here is not needed.
+			if u.check != nil {
+				u.check.completeInterface(nopos, x)
+				u.check.completeInterface(nopos, y)
+			}
+			a := x.allMethods
+			b := y.allMethods
+			if len(a) == len(b) {
+				// Interface types are the only types where cycles can occur
+				// that are not "terminated" via named types; and such cycles
+				// can only be created via method parameter types that are
+				// anonymous interfaces (directly or indirectly) embedding
+				// the current interface. Example:
+				//
+				//    type T interface {
+				//        m() interface{T}
+				//    }
+				//
+				// If two such (differently named) interfaces are compared,
+				// endless recursion occurs if the cycle is not detected.
+				//
+				// If x and y were compared before, they must be equal
+				// (if they were not, the recursion would have stopped);
+				// search the ifacePair stack for the same pair.
+				//
+				// This is a quadratic algorithm, but in practice these stacks
+				// are extremely short (bounded by the nesting depth of interface
+				// type declarations that recur via parameter types, an extremely
+				// rare occurrence). An alternative implementation might use a
+				// "visited" map, but that is probably less efficient overall.
+				q := &ifacePair{x, y, p}
+				for p != nil {
+					if p.identical(q) {
+						return true // same pair was compared before
+					}
+					p = p.prev
+				}
+				if debug {
+					assertSortedMethods(a)
+					assertSortedMethods(b)
+				}
+				for i, f := range a {
+					g := b[i]
+					if f.Id() != g.Id() || !u.nify(f.typ, g.typ, q) {
+						return false
+					}
+				}
+				return true
+			}
+		}
+
+	case *Map:
+		// Two map types are identical if they have identical key and value types.
+		if y, ok := y.(*Map); ok {
+			return u.nify(x.key, y.key, p) && u.nify(x.elem, y.elem, p)
+		}
+
+	case *Chan:
+		// Two channel types are identical if they have identical value types.
+		if y, ok := y.(*Chan); ok {
+			return (!u.exact || x.dir == y.dir) && u.nify(x.elem, y.elem, p)
+		}
+
+	case *Named:
+		// Two named types are identical if their type names originate
+		// in the same type declaration.
+		// if y, ok := y.(*Named); ok {
+		// 	return x.obj == y.obj
+		// }
+		if y, ok := y.(*Named); ok {
+			// TODO(gri) This is not always correct: two types may have the same names
+			//           in the same package if one of them is nested in a function.
+			//           Extremely unlikely but we need an always correct solution.
+			if x.obj.pkg == y.obj.pkg && x.obj.name == y.obj.name {
+				assert(len(x.targs) == len(y.targs))
+				for i, x := range x.targs {
+					if !u.nify(x, y.targs[i], p) {
+						return false
+					}
+				}
+				return true
+			}
+		}
+
+	case *TypeParam:
+		// Two type parameters (which are not part of the type parameters of the
+		// enclosing type as those are handled in the beginning of this function)
+		// are identical if they originate in the same declaration.
+		return x == y
+
+	// case *instance:
+	//	unreachable since types are expanded
+
+	case nil:
+		// avoid a crash in case of nil type
+
+	default:
+		u.check.dump("### u.nify(%s, %s), u.x.tparams = %s", x, y, u.x.tparams)
+		unreachable()
+	}
+
+	return false
+}
diff --git a/src/cmd/compile/internal/types2/universe.go b/src/cmd/compile/internal/types2/universe.go
new file mode 100644
index 0000000..76d4e55
--- /dev/null
+++ b/src/cmd/compile/internal/types2/universe.go
@@ -0,0 +1,282 @@
+// Copyright 2011 The Go 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 sets up the universe scope and the unsafe package.
+
+package types2
+
+import (
+	"go/constant"
+	"strings"
+)
+
+// The Universe scope contains all predeclared objects of Go.
+// It is the outermost scope of any chain of nested scopes.
+var Universe *Scope
+
+// The Unsafe package is the package returned by an importer
+// for the import path "unsafe".
+var Unsafe *Package
+
+var (
+	universeIota  *Const
+	universeByte  *Basic // uint8 alias, but has name "byte"
+	universeRune  *Basic // int32 alias, but has name "rune"
+	universeAny   *Interface
+	universeError *Named
+)
+
+// 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"},
+
+	Bool:          {Bool, IsBoolean, "bool"},
+	Int:           {Int, IsInteger, "int"},
+	Int8:          {Int8, IsInteger, "int8"},
+	Int16:         {Int16, IsInteger, "int16"},
+	Int32:         {Int32, IsInteger, "int32"},
+	Int64:         {Int64, IsInteger, "int64"},
+	Uint:          {Uint, IsInteger | IsUnsigned, "uint"},
+	Uint8:         {Uint8, IsInteger | IsUnsigned, "uint8"},
+	Uint16:        {Uint16, IsInteger | IsUnsigned, "uint16"},
+	Uint32:        {Uint32, IsInteger | IsUnsigned, "uint32"},
+	Uint64:        {Uint64, IsInteger | IsUnsigned, "uint64"},
+	Uintptr:       {Uintptr, IsInteger | IsUnsigned, "uintptr"},
+	Float32:       {Float32, IsFloat, "float32"},
+	Float64:       {Float64, IsFloat, "float64"},
+	Complex64:     {Complex64, IsComplex, "complex64"},
+	Complex128:    {Complex128, IsComplex, "complex128"},
+	String:        {String, IsString, "string"},
+	UnsafePointer: {UnsafePointer, 0, "Pointer"},
+
+	UntypedBool:    {UntypedBool, IsBoolean | IsUntyped, "untyped bool"},
+	UntypedInt:     {UntypedInt, IsInteger | IsUntyped, "untyped int"},
+	UntypedRune:    {UntypedRune, IsInteger | IsUntyped, "untyped rune"},
+	UntypedFloat:   {UntypedFloat, IsFloat | IsUntyped, "untyped float"},
+	UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"},
+	UntypedString:  {UntypedString, IsString | IsUntyped, "untyped string"},
+	UntypedNil:     {UntypedNil, IsUntyped, "untyped nil"},
+}
+
+var aliases = [...]*Basic{
+	{Byte, IsInteger | IsUnsigned, "byte"},
+	{Rune, IsInteger, "rune"},
+}
+
+func defPredeclaredTypes() {
+	for _, t := range Typ {
+		def(NewTypeName(nopos, nil, t.name, t))
+	}
+	for _, t := range aliases {
+		def(NewTypeName(nopos, nil, t.name, t))
+	}
+
+	// any
+	// (Predeclared and entered into universe scope so we do all the
+	// usual checks; but removed again from scope later since it's
+	// only visible as constraint in a type parameter list.)
+	def(NewTypeName(nopos, nil, "any", &emptyInterface))
+
+	// Error has a nil package in its qualified name since it is in no package
+	{
+		res := NewVar(nopos, nil, "", Typ[String])
+		sig := &Signature{results: NewTuple(res)}
+		err := NewFunc(nopos, nil, "Error", sig)
+		typ := &Named{underlying: NewInterfaceType([]*Func{err}, nil).Complete()}
+		sig.recv = NewVar(nopos, nil, "", typ)
+		def(NewTypeName(nopos, nil, "error", typ))
+	}
+}
+
+var predeclaredConsts = [...]struct {
+	name string
+	kind BasicKind
+	val  constant.Value
+}{
+	{"true", UntypedBool, constant.MakeBool(true)},
+	{"false", UntypedBool, constant.MakeBool(false)},
+	{"iota", UntypedInt, constant.MakeInt64(0)},
+}
+
+func defPredeclaredConsts() {
+	for _, c := range predeclaredConsts {
+		def(NewConst(nopos, nil, c.name, Typ[c.kind], c.val))
+	}
+}
+
+func defPredeclaredNil() {
+	def(&Nil{object{name: "nil", typ: Typ[UntypedNil], color_: black}})
+}
+
+// A builtinId is the id of a builtin function.
+type builtinId int
+
+const (
+	// universe scope
+	_Append builtinId = iota
+	_Cap
+	_Close
+	_Complex
+	_Copy
+	_Delete
+	_Imag
+	_Len
+	_Make
+	_New
+	_Panic
+	_Print
+	_Println
+	_Real
+	_Recover
+
+	// package unsafe
+	_Add
+	_Alignof
+	_Offsetof
+	_Sizeof
+	_Slice
+
+	// testing support
+	_Assert
+	_Trace
+)
+
+var predeclaredFuncs = [...]struct {
+	name     string
+	nargs    int
+	variadic bool
+	kind     exprKind
+}{
+	_Append:  {"append", 1, true, expression},
+	_Cap:     {"cap", 1, false, expression},
+	_Close:   {"close", 1, false, statement},
+	_Complex: {"complex", 2, false, expression},
+	_Copy:    {"copy", 2, false, statement},
+	_Delete:  {"delete", 2, false, statement},
+	_Imag:    {"imag", 1, false, expression},
+	_Len:     {"len", 1, false, expression},
+	_Make:    {"make", 1, true, expression},
+	_New:     {"new", 1, false, expression},
+	_Panic:   {"panic", 1, false, statement},
+	_Print:   {"print", 0, true, statement},
+	_Println: {"println", 0, true, statement},
+	_Real:    {"real", 1, false, expression},
+	_Recover: {"recover", 0, false, statement},
+
+	_Add:      {"Add", 2, false, expression},
+	_Alignof:  {"Alignof", 1, false, expression},
+	_Offsetof: {"Offsetof", 1, false, expression},
+	_Sizeof:   {"Sizeof", 1, false, expression},
+	_Slice:    {"Slice", 2, false, expression},
+
+	_Assert: {"assert", 1, false, statement},
+	_Trace:  {"trace", 0, true, statement},
+}
+
+func defPredeclaredFuncs() {
+	for i := range predeclaredFuncs {
+		id := builtinId(i)
+		if id == _Assert || id == _Trace {
+			continue // only define these in testing environment
+		}
+		def(newBuiltin(id))
+	}
+}
+
+// DefPredeclaredTestFuncs defines the assert and trace built-ins.
+// These built-ins are intended for debugging and testing of this
+// package only.
+func DefPredeclaredTestFuncs() {
+	if Universe.Lookup("assert") != nil {
+		return // already defined
+	}
+	def(newBuiltin(_Assert))
+	def(newBuiltin(_Trace))
+}
+
+func defPredeclaredComparable() {
+	// The "comparable" interface can be imagined as defined like
+	//
+	// type comparable interface {
+	//         == () untyped bool
+	//         != () untyped bool
+	// }
+	//
+	// == and != cannot be user-declared but we can declare
+	// a magic method == and check for its presence when needed.
+
+	// Define interface { == () }. We don't care about the signature
+	// for == so leave it empty except for the receiver, which is
+	// set up later to match the usual interface method assumptions.
+	sig := new(Signature)
+	eql := NewFunc(nopos, nil, "==", sig)
+	iface := NewInterfaceType([]*Func{eql}, nil).Complete()
+
+	// set up the defined type for the interface
+	obj := NewTypeName(nopos, nil, "comparable", nil)
+	named := NewNamed(obj, iface, nil)
+	obj.color_ = black
+	sig.recv = NewVar(nopos, nil, "", named) // complete == signature
+
+	def(obj)
+}
+
+func init() {
+	Universe = NewScope(nil, nopos, nopos, "universe")
+	Unsafe = NewPackage("unsafe", "unsafe")
+	Unsafe.complete = true
+
+	defPredeclaredTypes()
+	defPredeclaredConsts()
+	defPredeclaredNil()
+	defPredeclaredFuncs()
+	defPredeclaredComparable()
+
+	universeIota = Universe.Lookup("iota").(*Const)
+	universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic)
+	universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic)
+	universeAny = Universe.Lookup("any").(*TypeName).typ.(*Interface)
+	universeError = Universe.Lookup("error").(*TypeName).typ.(*Named)
+
+	// "any" is only visible as constraint in a type parameter list
+	delete(Universe.elems, "any")
+}
+
+// Objects with names containing blanks are internal and not entered into
+// a scope. Objects with exported names are inserted in the unsafe package
+// scope; other objects are inserted in the universe scope.
+//
+func def(obj Object) {
+	assert(obj.color() == black)
+	name := obj.Name()
+	if strings.Contains(name, " ") {
+		return // nothing to do
+	}
+	// fix Obj link for named types
+	if typ := asNamed(obj.Type()); typ != nil {
+		typ.obj = obj.(*TypeName)
+	}
+	// exported identifiers go into package unsafe
+	scope := Universe
+	if obj.Exported() {
+		scope = Unsafe.scope
+		// set Pkg field
+		switch obj := obj.(type) {
+		case *TypeName:
+			obj.pkg = Unsafe
+		case *Builtin:
+			obj.pkg = Unsafe
+		default:
+			unreachable()
+		}
+	}
+	if scope.Insert(obj) != nil {
+		panic("internal error: double declaration")
+	}
+}
diff --git a/src/cmd/compile/internal/types2/version.go b/src/cmd/compile/internal/types2/version.go
new file mode 100644
index 0000000..d9d18b6
--- /dev/null
+++ b/src/cmd/compile/internal/types2/version.go
@@ -0,0 +1,81 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2
+
+import (
+	"cmd/compile/internal/syntax"
+	"fmt"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+// langCompat reports an error if the representation of a numeric
+// literal is not compatible with the current language version.
+func (check *Checker) langCompat(lit *syntax.BasicLit) {
+	s := lit.Value
+	if len(s) <= 2 || check.allowVersion(check.pkg, 1, 13) {
+		return
+	}
+	// len(s) > 2
+	if strings.Contains(s, "_") {
+		check.error(lit, "underscores in numeric literals requires go1.13 or later")
+		return
+	}
+	if s[0] != '0' {
+		return
+	}
+	radix := s[1]
+	if radix == 'b' || radix == 'B' {
+		check.error(lit, "binary literals requires go1.13 or later")
+		return
+	}
+	if radix == 'o' || radix == 'O' {
+		check.error(lit, "0o/0O-style octal literals requires go1.13 or later")
+		return
+	}
+	if lit.Kind != syntax.IntLit && (radix == 'x' || radix == 'X') {
+		check.error(lit, "hexadecimal floating-point literals requires go1.13 or later")
+	}
+}
+
+// allowVersion reports whether the given package
+// is allowed to use version major.minor.
+func (check *Checker) allowVersion(pkg *Package, major, minor int) bool {
+	// We assume that imported packages have all been checked,
+	// so we only have to check for the local package.
+	if pkg != check.pkg {
+		return true
+	}
+	ma, mi := check.version.major, check.version.minor
+	return ma == 0 && mi == 0 || ma > major || ma == major && mi >= minor
+}
+
+type version struct {
+	major, minor int
+}
+
+// parseGoVersion parses a Go version string (such as "go1.12")
+// and returns the version, or an error. If s is the empty
+// string, the version is 0.0.
+func parseGoVersion(s string) (v version, err error) {
+	if s == "" {
+		return
+	}
+	matches := goVersionRx.FindStringSubmatch(s)
+	if matches == nil {
+		err = fmt.Errorf(`should be something like "go1.12"`)
+		return
+	}
+	v.major, err = strconv.Atoi(matches[1])
+	if err != nil {
+		return
+	}
+	v.minor, err = strconv.Atoi(matches[2])
+	return
+}
+
+// goVersionRx matches a Go version string, e.g. "go1.12".
+var goVersionRx = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
diff --git a/src/cmd/compile/internal/walk/assign.go b/src/cmd/compile/internal/walk/assign.go
new file mode 100644
index 0000000..6d697a5
--- /dev/null
+++ b/src/cmd/compile/internal/walk/assign.go
@@ -0,0 +1,718 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"go/constant"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// walkAssign walks an OAS (AssignExpr) or OASOP (AssignOpExpr) node.
+func walkAssign(init *ir.Nodes, n ir.Node) ir.Node {
+	init.Append(ir.TakeInit(n)...)
+
+	var left, right ir.Node
+	switch n.Op() {
+	case ir.OAS:
+		n := n.(*ir.AssignStmt)
+		left, right = n.X, n.Y
+	case ir.OASOP:
+		n := n.(*ir.AssignOpStmt)
+		left, right = n.X, n.Y
+	}
+
+	// Recognize m[k] = append(m[k], ...) so we can reuse
+	// the mapassign call.
+	var mapAppend *ir.CallExpr
+	if left.Op() == ir.OINDEXMAP && right.Op() == ir.OAPPEND {
+		left := left.(*ir.IndexExpr)
+		mapAppend = right.(*ir.CallExpr)
+		if !ir.SameSafeExpr(left, mapAppend.Args[0]) {
+			base.Fatalf("not same expressions: %v != %v", left, mapAppend.Args[0])
+		}
+	}
+
+	left = walkExpr(left, init)
+	left = safeExpr(left, init)
+	if mapAppend != nil {
+		mapAppend.Args[0] = left
+	}
+
+	if n.Op() == ir.OASOP {
+		// Rewrite x op= y into x = x op y.
+		n = ir.NewAssignStmt(base.Pos, left, typecheck.Expr(ir.NewBinaryExpr(base.Pos, n.(*ir.AssignOpStmt).AsOp, left, right)))
+	} else {
+		n.(*ir.AssignStmt).X = left
+	}
+	as := n.(*ir.AssignStmt)
+
+	if oaslit(as, init) {
+		return ir.NewBlockStmt(as.Pos(), nil)
+	}
+
+	if as.Y == nil {
+		// TODO(austin): Check all "implicit zeroing"
+		return as
+	}
+
+	if !base.Flag.Cfg.Instrumenting && ir.IsZero(as.Y) {
+		return as
+	}
+
+	switch as.Y.Op() {
+	default:
+		as.Y = walkExpr(as.Y, init)
+
+	case ir.ORECV:
+		// x = <-c; as.Left is x, as.Right.Left is c.
+		// order.stmt made sure x is addressable.
+		recv := as.Y.(*ir.UnaryExpr)
+		recv.X = walkExpr(recv.X, init)
+
+		n1 := typecheck.NodAddr(as.X)
+		r := recv.X // the channel
+		return mkcall1(chanfn("chanrecv1", 2, r.Type()), nil, init, r, n1)
+
+	case ir.OAPPEND:
+		// x = append(...)
+		call := as.Y.(*ir.CallExpr)
+		if call.Type().Elem().NotInHeap() {
+			base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", call.Type().Elem())
+		}
+		var r ir.Node
+		switch {
+		case isAppendOfMake(call):
+			// x = append(y, make([]T, y)...)
+			r = extendSlice(call, init)
+		case call.IsDDD:
+			r = appendSlice(call, init) // also works for append(slice, string).
+		default:
+			r = walkAppend(call, init, as)
+		}
+		as.Y = r
+		if r.Op() == ir.OAPPEND {
+			// Left in place for back end.
+			// Do not add a new write barrier.
+			// Set up address of type for back end.
+			r.(*ir.CallExpr).X = reflectdata.TypePtr(r.Type().Elem())
+			return as
+		}
+		// Otherwise, lowered for race detector.
+		// Treat as ordinary assignment.
+	}
+
+	if as.X != nil && as.Y != nil {
+		return convas(as, init)
+	}
+	return as
+}
+
+// walkAssignDotType walks an OAS2DOTTYPE node.
+func walkAssignDotType(n *ir.AssignListStmt, init *ir.Nodes) ir.Node {
+	walkExprListSafe(n.Lhs, init)
+	n.Rhs[0] = walkExpr(n.Rhs[0], init)
+	return n
+}
+
+// walkAssignFunc walks an OAS2FUNC node.
+func walkAssignFunc(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
+	init.Append(ir.TakeInit(n)...)
+
+	r := n.Rhs[0]
+	walkExprListSafe(n.Lhs, init)
+	r = walkExpr(r, init)
+
+	if ir.IsIntrinsicCall(r.(*ir.CallExpr)) {
+		n.Rhs = []ir.Node{r}
+		return n
+	}
+	init.Append(r)
+
+	ll := ascompatet(n.Lhs, r.Type())
+	return ir.NewBlockStmt(src.NoXPos, ll)
+}
+
+// walkAssignList walks an OAS2 node.
+func walkAssignList(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
+	init.Append(ir.TakeInit(n)...)
+	return ir.NewBlockStmt(src.NoXPos, ascompatee(ir.OAS, n.Lhs, n.Rhs))
+}
+
+// walkAssignMapRead walks an OAS2MAPR node.
+func walkAssignMapRead(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
+	init.Append(ir.TakeInit(n)...)
+
+	r := n.Rhs[0].(*ir.IndexExpr)
+	walkExprListSafe(n.Lhs, init)
+	r.X = walkExpr(r.X, init)
+	r.Index = walkExpr(r.Index, init)
+	t := r.X.Type()
+
+	fast := mapfast(t)
+	key := mapKeyArg(fast, r, r.Index)
+
+	// from:
+	//   a,b = m[i]
+	// to:
+	//   var,b = mapaccess2*(t, m, i)
+	//   a = *var
+	a := n.Lhs[0]
+
+	var call *ir.CallExpr
+	if w := t.Elem().Width; w <= zeroValSize {
+		fn := mapfn(mapaccess2[fast], t, false)
+		call = mkcall1(fn, fn.Type().Results(), init, reflectdata.TypePtr(t), r.X, key)
+	} else {
+		fn := mapfn("mapaccess2_fat", t, true)
+		z := reflectdata.ZeroAddr(w)
+		call = mkcall1(fn, fn.Type().Results(), init, reflectdata.TypePtr(t), r.X, key, z)
+	}
+
+	// mapaccess2* returns a typed bool, but due to spec changes,
+	// the boolean result of i.(T) is now untyped so we make it the
+	// same type as the variable on the lhs.
+	if ok := n.Lhs[1]; !ir.IsBlank(ok) && ok.Type().IsBoolean() {
+		call.Type().Field(1).Type = ok.Type()
+	}
+	n.Rhs = []ir.Node{call}
+	n.SetOp(ir.OAS2FUNC)
+
+	// don't generate a = *var if a is _
+	if ir.IsBlank(a) {
+		return walkExpr(typecheck.Stmt(n), init)
+	}
+
+	var_ := typecheck.Temp(types.NewPtr(t.Elem()))
+	var_.SetTypecheck(1)
+	var_.MarkNonNil() // mapaccess always returns a non-nil pointer
+
+	n.Lhs[0] = var_
+	init.Append(walkExpr(n, init))
+
+	as := ir.NewAssignStmt(base.Pos, a, ir.NewStarExpr(base.Pos, var_))
+	return walkExpr(typecheck.Stmt(as), init)
+}
+
+// walkAssignRecv walks an OAS2RECV node.
+func walkAssignRecv(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
+	init.Append(ir.TakeInit(n)...)
+
+	r := n.Rhs[0].(*ir.UnaryExpr) // recv
+	walkExprListSafe(n.Lhs, init)
+	r.X = walkExpr(r.X, init)
+	var n1 ir.Node
+	if ir.IsBlank(n.Lhs[0]) {
+		n1 = typecheck.NodNil()
+	} else {
+		n1 = typecheck.NodAddr(n.Lhs[0])
+	}
+	fn := chanfn("chanrecv2", 2, r.X.Type())
+	ok := n.Lhs[1]
+	call := mkcall1(fn, types.Types[types.TBOOL], init, r.X, n1)
+	return typecheck.Stmt(ir.NewAssignStmt(base.Pos, ok, call))
+}
+
+// walkReturn walks an ORETURN node.
+func walkReturn(n *ir.ReturnStmt) ir.Node {
+	fn := ir.CurFunc
+
+	fn.NumReturns++
+	if len(n.Results) == 0 {
+		return n
+	}
+
+	results := fn.Type().Results().FieldSlice()
+	dsts := make([]ir.Node, len(results))
+	for i, v := range results {
+		// TODO(mdempsky): typecheck should have already checked the result variables.
+		dsts[i] = typecheck.AssignExpr(v.Nname.(*ir.Name))
+	}
+
+	n.Results = ascompatee(n.Op(), dsts, n.Results)
+	return n
+}
+
+// check assign type list to
+// an expression list. called in
+//	expr-list = func()
+func ascompatet(nl ir.Nodes, nr *types.Type) []ir.Node {
+	if len(nl) != nr.NumFields() {
+		base.Fatalf("ascompatet: assignment count mismatch: %d = %d", len(nl), nr.NumFields())
+	}
+
+	var nn ir.Nodes
+	for i, l := range nl {
+		if ir.IsBlank(l) {
+			continue
+		}
+		r := nr.Field(i)
+
+		// Order should have created autotemps of the appropriate type for
+		// us to store results into.
+		if tmp, ok := l.(*ir.Name); !ok || !tmp.AutoTemp() || !types.Identical(tmp.Type(), r.Type) {
+			base.FatalfAt(l.Pos(), "assigning %v to %+v", r.Type, l)
+		}
+
+		res := ir.NewResultExpr(base.Pos, nil, types.BADWIDTH)
+		res.Index = int64(i)
+		res.SetType(r.Type)
+		res.SetTypecheck(1)
+
+		nn.Append(ir.NewAssignStmt(base.Pos, l, res))
+	}
+	return nn
+}
+
+// check assign expression list to
+// an expression list. called in
+//	expr-list = expr-list
+func ascompatee(op ir.Op, nl, nr []ir.Node) []ir.Node {
+	// cannot happen: should have been rejected during type checking
+	if len(nl) != len(nr) {
+		base.Fatalf("assignment operands mismatch: %+v / %+v", ir.Nodes(nl), ir.Nodes(nr))
+	}
+
+	var assigned ir.NameSet
+	var memWrite, deferResultWrite bool
+
+	// affected reports whether expression n could be affected by
+	// the assignments applied so far.
+	affected := func(n ir.Node) bool {
+		if deferResultWrite {
+			return true
+		}
+		return ir.Any(n, func(n ir.Node) bool {
+			if n.Op() == ir.ONAME && assigned.Has(n.(*ir.Name)) {
+				return true
+			}
+			if memWrite && readsMemory(n) {
+				return true
+			}
+			return false
+		})
+	}
+
+	// If a needed expression may be affected by an
+	// earlier assignment, make an early copy of that
+	// expression and use the copy instead.
+	var early ir.Nodes
+	save := func(np *ir.Node) {
+		if n := *np; affected(n) {
+			*np = copyExpr(n, n.Type(), &early)
+		}
+	}
+
+	var late ir.Nodes
+	for i, lorig := range nl {
+		l, r := lorig, nr[i]
+
+		// Do not generate 'x = x' during return. See issue 4014.
+		if op == ir.ORETURN && ir.SameSafeExpr(l, r) {
+			continue
+		}
+
+		// Save subexpressions needed on left side.
+		// Drill through non-dereferences.
+		for {
+			// If an expression has init statements, they must be evaluated
+			// before any of its saved sub-operands (#45706).
+			// TODO(mdempsky): Disallow init statements on lvalues.
+			init := ir.TakeInit(l)
+			walkStmtList(init)
+			early.Append(init...)
+
+			switch ll := l.(type) {
+			case *ir.IndexExpr:
+				if ll.X.Type().IsArray() {
+					save(&ll.Index)
+					l = ll.X
+					continue
+				}
+			case *ir.ParenExpr:
+				l = ll.X
+				continue
+			case *ir.SelectorExpr:
+				if ll.Op() == ir.ODOT {
+					l = ll.X
+					continue
+				}
+			}
+			break
+		}
+
+		var name *ir.Name
+		switch l.Op() {
+		default:
+			base.Fatalf("unexpected lvalue %v", l.Op())
+		case ir.ONAME:
+			name = l.(*ir.Name)
+		case ir.OINDEX, ir.OINDEXMAP:
+			l := l.(*ir.IndexExpr)
+			save(&l.X)
+			save(&l.Index)
+		case ir.ODEREF:
+			l := l.(*ir.StarExpr)
+			save(&l.X)
+		case ir.ODOTPTR:
+			l := l.(*ir.SelectorExpr)
+			save(&l.X)
+		}
+
+		// Save expression on right side.
+		save(&r)
+
+		appendWalkStmt(&late, convas(ir.NewAssignStmt(base.Pos, lorig, r), &late))
+
+		// Check for reasons why we may need to compute later expressions
+		// before this assignment happens.
+
+		if name == nil {
+			// Not a direct assignment to a declared variable.
+			// Conservatively assume any memory access might alias.
+			memWrite = true
+			continue
+		}
+
+		if name.Class == ir.PPARAMOUT && ir.CurFunc.HasDefer() {
+			// Assignments to a result parameter in a function with defers
+			// becomes visible early if evaluation of any later expression
+			// panics (#43835).
+			deferResultWrite = true
+			continue
+		}
+
+		if sym := types.OrigSym(name.Sym()); sym == nil || sym.IsBlank() {
+			// We can ignore assignments to blank or anonymous result parameters.
+			// These can't appear in expressions anyway.
+			continue
+		}
+
+		if name.Addrtaken() || !name.OnStack() {
+			// Global variable, heap escaped, or just addrtaken.
+			// Conservatively assume any memory access might alias.
+			memWrite = true
+			continue
+		}
+
+		// Local, non-addrtaken variable.
+		// Assignments can only alias with direct uses of this variable.
+		assigned.Add(name)
+	}
+
+	early.Append(late.Take()...)
+	return early
+}
+
+// readsMemory reports whether the evaluation n directly reads from
+// memory that might be written to indirectly.
+func readsMemory(n ir.Node) bool {
+	switch n.Op() {
+	case ir.ONAME:
+		n := n.(*ir.Name)
+		if n.Class == ir.PFUNC {
+			return false
+		}
+		return n.Addrtaken() || !n.OnStack()
+
+	case ir.OADD,
+		ir.OAND,
+		ir.OANDAND,
+		ir.OANDNOT,
+		ir.OBITNOT,
+		ir.OCONV,
+		ir.OCONVIFACE,
+		ir.OCONVNOP,
+		ir.ODIV,
+		ir.ODOT,
+		ir.ODOTTYPE,
+		ir.OLITERAL,
+		ir.OLSH,
+		ir.OMOD,
+		ir.OMUL,
+		ir.ONEG,
+		ir.ONIL,
+		ir.OOR,
+		ir.OOROR,
+		ir.OPAREN,
+		ir.OPLUS,
+		ir.ORSH,
+		ir.OSUB,
+		ir.OXOR:
+		return false
+	}
+
+	// Be conservative.
+	return true
+}
+
+// expand append(l1, l2...) to
+//   init {
+//     s := l1
+//     n := len(s) + len(l2)
+//     // Compare as uint so growslice can panic on overflow.
+//     if uint(n) > uint(cap(s)) {
+//       s = growslice(s, n)
+//     }
+//     s = s[:n]
+//     memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
+//   }
+//   s
+//
+// l2 is allowed to be a string.
+func appendSlice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
+	walkAppendArgs(n, init)
+
+	l1 := n.Args[0]
+	l2 := n.Args[1]
+	l2 = cheapExpr(l2, init)
+	n.Args[1] = l2
+
+	var nodes ir.Nodes
+
+	// var s []T
+	s := typecheck.Temp(l1.Type())
+	nodes.Append(ir.NewAssignStmt(base.Pos, s, l1)) // s = l1
+
+	elemtype := s.Type().Elem()
+
+	// n := len(s) + len(l2)
+	nn := typecheck.Temp(types.Types[types.TINT])
+	nodes.Append(ir.NewAssignStmt(base.Pos, nn, ir.NewBinaryExpr(base.Pos, ir.OADD, ir.NewUnaryExpr(base.Pos, ir.OLEN, s), ir.NewUnaryExpr(base.Pos, ir.OLEN, l2))))
+
+	// if uint(n) > uint(cap(s))
+	nif := ir.NewIfStmt(base.Pos, nil, nil, nil)
+	nuint := typecheck.Conv(nn, types.Types[types.TUINT])
+	scapuint := typecheck.Conv(ir.NewUnaryExpr(base.Pos, ir.OCAP, s), types.Types[types.TUINT])
+	nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OGT, nuint, scapuint)
+
+	// instantiate growslice(typ *type, []any, int) []any
+	fn := typecheck.LookupRuntime("growslice")
+	fn = typecheck.SubstArgTypes(fn, elemtype, elemtype)
+
+	// s = growslice(T, s, n)
+	nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, s, mkcall1(fn, s.Type(), nif.PtrInit(), reflectdata.TypePtr(elemtype), s, nn))}
+	nodes.Append(nif)
+
+	// s = s[:n]
+	nt := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, nil, nn, nil)
+	nt.SetBounded(true)
+	nodes.Append(ir.NewAssignStmt(base.Pos, s, nt))
+
+	var ncopy ir.Node
+	if elemtype.HasPointers() {
+		// copy(s[len(l1):], l2)
+		slice := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, ir.NewUnaryExpr(base.Pos, ir.OLEN, l1), nil, nil)
+		slice.SetType(s.Type())
+
+		ir.CurFunc.SetWBPos(n.Pos())
+
+		// instantiate typedslicecopy(typ *type, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int
+		fn := typecheck.LookupRuntime("typedslicecopy")
+		fn = typecheck.SubstArgTypes(fn, l1.Type().Elem(), l2.Type().Elem())
+		ptr1, len1 := backingArrayPtrLen(cheapExpr(slice, &nodes))
+		ptr2, len2 := backingArrayPtrLen(l2)
+		ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, reflectdata.TypePtr(elemtype), ptr1, len1, ptr2, len2)
+	} else if base.Flag.Cfg.Instrumenting && !base.Flag.CompilingRuntime {
+		// rely on runtime to instrument:
+		//  copy(s[len(l1):], l2)
+		// l2 can be a slice or string.
+		slice := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, ir.NewUnaryExpr(base.Pos, ir.OLEN, l1), nil, nil)
+		slice.SetType(s.Type())
+
+		ptr1, len1 := backingArrayPtrLen(cheapExpr(slice, &nodes))
+		ptr2, len2 := backingArrayPtrLen(l2)
+
+		fn := typecheck.LookupRuntime("slicecopy")
+		fn = typecheck.SubstArgTypes(fn, ptr1.Type().Elem(), ptr2.Type().Elem())
+		ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, ptr1, len1, ptr2, len2, ir.NewInt(elemtype.Width))
+	} else {
+		// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
+		ix := ir.NewIndexExpr(base.Pos, s, ir.NewUnaryExpr(base.Pos, ir.OLEN, l1))
+		ix.SetBounded(true)
+		addr := typecheck.NodAddr(ix)
+
+		sptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, l2)
+
+		nwid := cheapExpr(typecheck.Conv(ir.NewUnaryExpr(base.Pos, ir.OLEN, l2), types.Types[types.TUINTPTR]), &nodes)
+		nwid = ir.NewBinaryExpr(base.Pos, ir.OMUL, nwid, ir.NewInt(elemtype.Width))
+
+		// instantiate func memmove(to *any, frm *any, length uintptr)
+		fn := typecheck.LookupRuntime("memmove")
+		fn = typecheck.SubstArgTypes(fn, elemtype, elemtype)
+		ncopy = mkcall1(fn, nil, &nodes, addr, sptr, nwid)
+	}
+	ln := append(nodes, ncopy)
+
+	typecheck.Stmts(ln)
+	walkStmtList(ln)
+	init.Append(ln...)
+	return s
+}
+
+// isAppendOfMake reports whether n is of the form append(x, make([]T, y)...).
+// isAppendOfMake assumes n has already been typechecked.
+func isAppendOfMake(n ir.Node) bool {
+	if base.Flag.N != 0 || base.Flag.Cfg.Instrumenting {
+		return false
+	}
+
+	if n.Typecheck() == 0 {
+		base.Fatalf("missing typecheck: %+v", n)
+	}
+
+	if n.Op() != ir.OAPPEND {
+		return false
+	}
+	call := n.(*ir.CallExpr)
+	if !call.IsDDD || len(call.Args) != 2 || call.Args[1].Op() != ir.OMAKESLICE {
+		return false
+	}
+
+	mk := call.Args[1].(*ir.MakeExpr)
+	if mk.Cap != nil {
+		return false
+	}
+
+	// y must be either an integer constant or the largest possible positive value
+	// of variable y needs to fit into an uint.
+
+	// typecheck made sure that constant arguments to make are not negative and fit into an int.
+
+	// The care of overflow of the len argument to make will be handled by an explicit check of int(len) < 0 during runtime.
+	y := mk.Len
+	if !ir.IsConst(y, constant.Int) && y.Type().Size() > types.Types[types.TUINT].Size() {
+		return false
+	}
+
+	return true
+}
+
+// extendSlice rewrites append(l1, make([]T, l2)...) to
+//   init {
+//     if l2 >= 0 { // Empty if block here for more meaningful node.SetLikely(true)
+//     } else {
+//       panicmakeslicelen()
+//     }
+//     s := l1
+//     n := len(s) + l2
+//     // Compare n and s as uint so growslice can panic on overflow of len(s) + l2.
+//     // cap is a positive int and n can become negative when len(s) + l2
+//     // overflows int. Interpreting n when negative as uint makes it larger
+//     // than cap(s). growslice will check the int n arg and panic if n is
+//     // negative. This prevents the overflow from being undetected.
+//     if uint(n) > uint(cap(s)) {
+//       s = growslice(T, s, n)
+//     }
+//     s = s[:n]
+//     lptr := &l1[0]
+//     sptr := &s[0]
+//     if lptr == sptr || !T.HasPointers() {
+//       // growslice did not clear the whole underlying array (or did not get called)
+//       hp := &s[len(l1)]
+//       hn := l2 * sizeof(T)
+//       memclr(hp, hn)
+//     }
+//   }
+//   s
+func extendSlice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
+	// isAppendOfMake made sure all possible positive values of l2 fit into an uint.
+	// The case of l2 overflow when converting from e.g. uint to int is handled by an explicit
+	// check of l2 < 0 at runtime which is generated below.
+	l2 := typecheck.Conv(n.Args[1].(*ir.MakeExpr).Len, types.Types[types.TINT])
+	l2 = typecheck.Expr(l2)
+	n.Args[1] = l2 // walkAppendArgs expects l2 in n.List.Second().
+
+	walkAppendArgs(n, init)
+
+	l1 := n.Args[0]
+	l2 = n.Args[1] // re-read l2, as it may have been updated by walkAppendArgs
+
+	var nodes []ir.Node
+
+	// if l2 >= 0 (likely happens), do nothing
+	nifneg := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OGE, l2, ir.NewInt(0)), nil, nil)
+	nifneg.Likely = true
+
+	// else panicmakeslicelen()
+	nifneg.Else = []ir.Node{mkcall("panicmakeslicelen", nil, init)}
+	nodes = append(nodes, nifneg)
+
+	// s := l1
+	s := typecheck.Temp(l1.Type())
+	nodes = append(nodes, ir.NewAssignStmt(base.Pos, s, l1))
+
+	elemtype := s.Type().Elem()
+
+	// n := len(s) + l2
+	nn := typecheck.Temp(types.Types[types.TINT])
+	nodes = append(nodes, ir.NewAssignStmt(base.Pos, nn, ir.NewBinaryExpr(base.Pos, ir.OADD, ir.NewUnaryExpr(base.Pos, ir.OLEN, s), l2)))
+
+	// if uint(n) > uint(cap(s))
+	nuint := typecheck.Conv(nn, types.Types[types.TUINT])
+	capuint := typecheck.Conv(ir.NewUnaryExpr(base.Pos, ir.OCAP, s), types.Types[types.TUINT])
+	nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OGT, nuint, capuint), nil, nil)
+
+	// instantiate growslice(typ *type, old []any, newcap int) []any
+	fn := typecheck.LookupRuntime("growslice")
+	fn = typecheck.SubstArgTypes(fn, elemtype, elemtype)
+
+	// s = growslice(T, s, n)
+	nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, s, mkcall1(fn, s.Type(), nif.PtrInit(), reflectdata.TypePtr(elemtype), s, nn))}
+	nodes = append(nodes, nif)
+
+	// s = s[:n]
+	nt := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, nil, nn, nil)
+	nt.SetBounded(true)
+	nodes = append(nodes, ir.NewAssignStmt(base.Pos, s, nt))
+
+	// lptr := &l1[0]
+	l1ptr := typecheck.Temp(l1.Type().Elem().PtrTo())
+	tmp := ir.NewUnaryExpr(base.Pos, ir.OSPTR, l1)
+	nodes = append(nodes, ir.NewAssignStmt(base.Pos, l1ptr, tmp))
+
+	// sptr := &s[0]
+	sptr := typecheck.Temp(elemtype.PtrTo())
+	tmp = ir.NewUnaryExpr(base.Pos, ir.OSPTR, s)
+	nodes = append(nodes, ir.NewAssignStmt(base.Pos, sptr, tmp))
+
+	// hp := &s[len(l1)]
+	ix := ir.NewIndexExpr(base.Pos, s, ir.NewUnaryExpr(base.Pos, ir.OLEN, l1))
+	ix.SetBounded(true)
+	hp := typecheck.ConvNop(typecheck.NodAddr(ix), types.Types[types.TUNSAFEPTR])
+
+	// hn := l2 * sizeof(elem(s))
+	hn := typecheck.Conv(ir.NewBinaryExpr(base.Pos, ir.OMUL, l2, ir.NewInt(elemtype.Width)), types.Types[types.TUINTPTR])
+
+	clrname := "memclrNoHeapPointers"
+	hasPointers := elemtype.HasPointers()
+	if hasPointers {
+		clrname = "memclrHasPointers"
+		ir.CurFunc.SetWBPos(n.Pos())
+	}
+
+	var clr ir.Nodes
+	clrfn := mkcall(clrname, nil, &clr, hp, hn)
+	clr.Append(clrfn)
+
+	if hasPointers {
+		// if l1ptr == sptr
+		nifclr := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OEQ, l1ptr, sptr), nil, nil)
+		nifclr.Body = clr
+		nodes = append(nodes, nifclr)
+	} else {
+		nodes = append(nodes, clr...)
+	}
+
+	typecheck.Stmts(nodes)
+	walkStmtList(nodes)
+	init.Append(nodes...)
+	return s
+}
diff --git a/src/cmd/compile/internal/walk/builtin.go b/src/cmd/compile/internal/walk/builtin.go
new file mode 100644
index 0000000..14efc05
--- /dev/null
+++ b/src/cmd/compile/internal/walk/builtin.go
@@ -0,0 +1,718 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"fmt"
+	"go/constant"
+	"go/token"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/escape"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+)
+
+// Rewrite append(src, x, y, z) so that any side effects in
+// x, y, z (including runtime panics) are evaluated in
+// initialization statements before the append.
+// For normal code generation, stop there and leave the
+// rest to cgen_append.
+//
+// For race detector, expand append(src, a [, b]* ) to
+//
+//   init {
+//     s := src
+//     const argc = len(args) - 1
+//     if cap(s) - len(s) < argc {
+//	    s = growslice(s, len(s)+argc)
+//     }
+//     n := len(s)
+//     s = s[:n+argc]
+//     s[n] = a
+//     s[n+1] = b
+//     ...
+//   }
+//   s
+func walkAppend(n *ir.CallExpr, init *ir.Nodes, dst ir.Node) ir.Node {
+	if !ir.SameSafeExpr(dst, n.Args[0]) {
+		n.Args[0] = safeExpr(n.Args[0], init)
+		n.Args[0] = walkExpr(n.Args[0], init)
+	}
+	walkExprListSafe(n.Args[1:], init)
+
+	nsrc := n.Args[0]
+
+	// walkExprListSafe will leave OINDEX (s[n]) alone if both s
+	// and n are name or literal, but those may index the slice we're
+	// modifying here. Fix explicitly.
+	// Using cheapExpr also makes sure that the evaluation
+	// of all arguments (and especially any panics) happen
+	// before we begin to modify the slice in a visible way.
+	ls := n.Args[1:]
+	for i, n := range ls {
+		n = cheapExpr(n, init)
+		if !types.Identical(n.Type(), nsrc.Type().Elem()) {
+			n = typecheck.AssignConv(n, nsrc.Type().Elem(), "append")
+			n = walkExpr(n, init)
+		}
+		ls[i] = n
+	}
+
+	argc := len(n.Args) - 1
+	if argc < 1 {
+		return nsrc
+	}
+
+	// General case, with no function calls left as arguments.
+	// Leave for gen, except that instrumentation requires old form.
+	if !base.Flag.Cfg.Instrumenting || base.Flag.CompilingRuntime {
+		return n
+	}
+
+	var l []ir.Node
+
+	ns := typecheck.Temp(nsrc.Type())
+	l = append(l, ir.NewAssignStmt(base.Pos, ns, nsrc)) // s = src
+
+	na := ir.NewInt(int64(argc))                 // const argc
+	nif := ir.NewIfStmt(base.Pos, nil, nil, nil) // if cap(s) - len(s) < argc
+	nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, ir.NewBinaryExpr(base.Pos, ir.OSUB, ir.NewUnaryExpr(base.Pos, ir.OCAP, ns), ir.NewUnaryExpr(base.Pos, ir.OLEN, ns)), na)
+
+	fn := typecheck.LookupRuntime("growslice") //   growslice(<type>, old []T, mincap int) (ret []T)
+	fn = typecheck.SubstArgTypes(fn, ns.Type().Elem(), ns.Type().Elem())
+
+	nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, ns, mkcall1(fn, ns.Type(), nif.PtrInit(), reflectdata.TypePtr(ns.Type().Elem()), ns,
+		ir.NewBinaryExpr(base.Pos, ir.OADD, ir.NewUnaryExpr(base.Pos, ir.OLEN, ns), na)))}
+
+	l = append(l, nif)
+
+	nn := typecheck.Temp(types.Types[types.TINT])
+	l = append(l, ir.NewAssignStmt(base.Pos, nn, ir.NewUnaryExpr(base.Pos, ir.OLEN, ns))) // n = len(s)
+
+	slice := ir.NewSliceExpr(base.Pos, ir.OSLICE, ns, nil, ir.NewBinaryExpr(base.Pos, ir.OADD, nn, na), nil) // ...s[:n+argc]
+	slice.SetBounded(true)
+	l = append(l, ir.NewAssignStmt(base.Pos, ns, slice)) // s = s[:n+argc]
+
+	ls = n.Args[1:]
+	for i, n := range ls {
+		ix := ir.NewIndexExpr(base.Pos, ns, nn) // s[n] ...
+		ix.SetBounded(true)
+		l = append(l, ir.NewAssignStmt(base.Pos, ix, n)) // s[n] = arg
+		if i+1 < len(ls) {
+			l = append(l, ir.NewAssignStmt(base.Pos, nn, ir.NewBinaryExpr(base.Pos, ir.OADD, nn, ir.NewInt(1)))) // n = n + 1
+		}
+	}
+
+	typecheck.Stmts(l)
+	walkStmtList(l)
+	init.Append(l...)
+	return ns
+}
+
+// walkClose walks an OCLOSE node.
+func walkClose(n *ir.UnaryExpr, init *ir.Nodes) ir.Node {
+	// cannot use chanfn - closechan takes any, not chan any
+	fn := typecheck.LookupRuntime("closechan")
+	fn = typecheck.SubstArgTypes(fn, n.X.Type())
+	return mkcall1(fn, nil, init, n.X)
+}
+
+// Lower copy(a, b) to a memmove call or a runtime call.
+//
+// init {
+//   n := len(a)
+//   if n > len(b) { n = len(b) }
+//   if a.ptr != b.ptr { memmove(a.ptr, b.ptr, n*sizeof(elem(a))) }
+// }
+// n;
+//
+// Also works if b is a string.
+//
+func walkCopy(n *ir.BinaryExpr, init *ir.Nodes, runtimecall bool) ir.Node {
+	if n.X.Type().Elem().HasPointers() {
+		ir.CurFunc.SetWBPos(n.Pos())
+		fn := writebarrierfn("typedslicecopy", n.X.Type().Elem(), n.Y.Type().Elem())
+		n.X = cheapExpr(n.X, init)
+		ptrL, lenL := backingArrayPtrLen(n.X)
+		n.Y = cheapExpr(n.Y, init)
+		ptrR, lenR := backingArrayPtrLen(n.Y)
+		return mkcall1(fn, n.Type(), init, reflectdata.TypePtr(n.X.Type().Elem()), ptrL, lenL, ptrR, lenR)
+	}
+
+	if runtimecall {
+		// rely on runtime to instrument:
+		//  copy(n.Left, n.Right)
+		// n.Right can be a slice or string.
+
+		n.X = cheapExpr(n.X, init)
+		ptrL, lenL := backingArrayPtrLen(n.X)
+		n.Y = cheapExpr(n.Y, init)
+		ptrR, lenR := backingArrayPtrLen(n.Y)
+
+		fn := typecheck.LookupRuntime("slicecopy")
+		fn = typecheck.SubstArgTypes(fn, ptrL.Type().Elem(), ptrR.Type().Elem())
+
+		return mkcall1(fn, n.Type(), init, ptrL, lenL, ptrR, lenR, ir.NewInt(n.X.Type().Elem().Width))
+	}
+
+	n.X = walkExpr(n.X, init)
+	n.Y = walkExpr(n.Y, init)
+	nl := typecheck.Temp(n.X.Type())
+	nr := typecheck.Temp(n.Y.Type())
+	var l []ir.Node
+	l = append(l, ir.NewAssignStmt(base.Pos, nl, n.X))
+	l = append(l, ir.NewAssignStmt(base.Pos, nr, n.Y))
+
+	nfrm := ir.NewUnaryExpr(base.Pos, ir.OSPTR, nr)
+	nto := ir.NewUnaryExpr(base.Pos, ir.OSPTR, nl)
+
+	nlen := typecheck.Temp(types.Types[types.TINT])
+
+	// n = len(to)
+	l = append(l, ir.NewAssignStmt(base.Pos, nlen, ir.NewUnaryExpr(base.Pos, ir.OLEN, nl)))
+
+	// if n > len(frm) { n = len(frm) }
+	nif := ir.NewIfStmt(base.Pos, nil, nil, nil)
+
+	nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OGT, nlen, ir.NewUnaryExpr(base.Pos, ir.OLEN, nr))
+	nif.Body.Append(ir.NewAssignStmt(base.Pos, nlen, ir.NewUnaryExpr(base.Pos, ir.OLEN, nr)))
+	l = append(l, nif)
+
+	// if to.ptr != frm.ptr { memmove( ... ) }
+	ne := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.ONE, nto, nfrm), nil, nil)
+	ne.Likely = true
+	l = append(l, ne)
+
+	fn := typecheck.LookupRuntime("memmove")
+	fn = typecheck.SubstArgTypes(fn, nl.Type().Elem(), nl.Type().Elem())
+	nwid := ir.Node(typecheck.Temp(types.Types[types.TUINTPTR]))
+	setwid := ir.NewAssignStmt(base.Pos, nwid, typecheck.Conv(nlen, types.Types[types.TUINTPTR]))
+	ne.Body.Append(setwid)
+	nwid = ir.NewBinaryExpr(base.Pos, ir.OMUL, nwid, ir.NewInt(nl.Type().Elem().Width))
+	call := mkcall1(fn, nil, init, nto, nfrm, nwid)
+	ne.Body.Append(call)
+
+	typecheck.Stmts(l)
+	walkStmtList(l)
+	init.Append(l...)
+	return nlen
+}
+
+// walkDelete walks an ODELETE node.
+func walkDelete(init *ir.Nodes, n *ir.CallExpr) ir.Node {
+	init.Append(ir.TakeInit(n)...)
+	map_ := n.Args[0]
+	key := n.Args[1]
+	map_ = walkExpr(map_, init)
+	key = walkExpr(key, init)
+
+	t := map_.Type()
+	fast := mapfast(t)
+	key = mapKeyArg(fast, n, key)
+	return mkcall1(mapfndel(mapdelete[fast], t), nil, init, reflectdata.TypePtr(t), map_, key)
+}
+
+// walkLenCap walks an OLEN or OCAP node.
+func walkLenCap(n *ir.UnaryExpr, init *ir.Nodes) ir.Node {
+	if isRuneCount(n) {
+		// Replace len([]rune(string)) with runtime.countrunes(string).
+		return mkcall("countrunes", n.Type(), init, typecheck.Conv(n.X.(*ir.ConvExpr).X, types.Types[types.TSTRING]))
+	}
+
+	n.X = walkExpr(n.X, init)
+
+	// replace len(*[10]int) with 10.
+	// delayed until now to preserve side effects.
+	t := n.X.Type()
+
+	if t.IsPtr() {
+		t = t.Elem()
+	}
+	if t.IsArray() {
+		safeExpr(n.X, init)
+		con := typecheck.OrigInt(n, t.NumElem())
+		con.SetTypecheck(1)
+		return con
+	}
+	return n
+}
+
+// walkMakeChan walks an OMAKECHAN node.
+func walkMakeChan(n *ir.MakeExpr, init *ir.Nodes) ir.Node {
+	// When size fits into int, use makechan instead of
+	// makechan64, which is faster and shorter on 32 bit platforms.
+	size := n.Len
+	fnname := "makechan64"
+	argtype := types.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(types.TIDEAL) || size.Type().Size() <= types.Types[types.TUINT].Size() {
+		fnname = "makechan"
+		argtype = types.Types[types.TINT]
+	}
+
+	return mkcall1(chanfn(fnname, 1, n.Type()), n.Type(), init, reflectdata.TypePtr(n.Type()), typecheck.Conv(size, argtype))
+}
+
+// walkMakeMap walks an OMAKEMAP node.
+func walkMakeMap(n *ir.MakeExpr, init *ir.Nodes) ir.Node {
+	t := n.Type()
+	hmapType := reflectdata.MapType(t)
+	hint := n.Len
+
+	// var h *hmap
+	var h ir.Node
+	if n.Esc() == ir.EscNone {
+		// Allocate hmap on stack.
+
+		// var hv hmap
+		// h = &hv
+		h = stackTempAddr(init, hmapType)
+
+		// 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 elem size is 128 bytes, larger objects
+		// are stored with an indirection. So max bucket size is 2048+eps.
+		if !ir.IsConst(hint, constant.Int) ||
+			constant.Compare(hint.Val(), token.LEQ, constant.MakeInt64(reflectdata.BUCKETSIZE)) {
+
+			// In case hint is larger than BUCKETSIZE runtime.makemap
+			// will allocate the buckets on the heap, see #20184
+			//
+			// if hint <= BUCKETSIZE {
+			//     var bv bmap
+			//     b = &bv
+			//     h.buckets = b
+			// }
+
+			nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLE, hint, ir.NewInt(reflectdata.BUCKETSIZE)), nil, nil)
+			nif.Likely = true
+
+			// var bv bmap
+			// b = &bv
+			b := stackTempAddr(&nif.Body, reflectdata.MapBucketType(t))
+
+			// h.buckets = b
+			bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap
+			na := ir.NewAssignStmt(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, h, bsym), b)
+			nif.Body.Append(na)
+			appendWalkStmt(init, nif)
+		}
+	}
+
+	if ir.IsConst(hint, constant.Int) && constant.Compare(hint.Val(), token.LEQ, constant.MakeInt64(reflectdata.BUCKETSIZE)) {
+		// 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() == ir.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[types.TUINT32], init)
+			hashsym := hmapType.Field(4).Sym // hmap.hash0 see reflect.go:hmap
+			appendWalkStmt(init, ir.NewAssignStmt(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, h, hashsym), rand))
+			return typecheck.ConvNop(h, t)
+		}
+		// Call runtime.makehmap to allocate an
+		// hmap on the heap and initialize hmap's hash0 field.
+		fn := typecheck.LookupRuntime("makemap_small")
+		fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem())
+		return mkcall1(fn, n.Type(), init)
+	}
+
+	if n.Esc() != ir.EscNone {
+		h = typecheck.NodNil()
+	}
+	// Map initialization with a variable or large hint is
+	// more complicated. We therefore generate a call to
+	// runtime.makemap to initialize 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[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(types.TIDEAL) || hint.Type().Size() <= types.Types[types.TUINT].Size() {
+		fnname = "makemap"
+		argtype = types.Types[types.TINT]
+	}
+
+	fn := typecheck.LookupRuntime(fnname)
+	fn = typecheck.SubstArgTypes(fn, hmapType, t.Key(), t.Elem())
+	return mkcall1(fn, n.Type(), init, reflectdata.TypePtr(n.Type()), typecheck.Conv(hint, argtype), h)
+}
+
+// walkMakeSlice walks an OMAKESLICE node.
+func walkMakeSlice(n *ir.MakeExpr, init *ir.Nodes) ir.Node {
+	l := n.Len
+	r := n.Cap
+	if r == nil {
+		r = safeExpr(l, init)
+		l = r
+	}
+	t := n.Type()
+	if t.Elem().NotInHeap() {
+		base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem())
+	}
+	if n.Esc() == ir.EscNone {
+		if why := escape.HeapAllocReason(n); why != "" {
+			base.Fatalf("%v has EscNone, but %v", n, why)
+		}
+		// var arr [r]T
+		// n = arr[:l]
+		i := typecheck.IndexConst(r)
+		if i < 0 {
+			base.Fatalf("walkExpr: invalid index %v", r)
+		}
+
+		// cap is constrained to [0,2^31) or [0,2^63) depending on whether
+		// we're in 32-bit or 64-bit systems. So it's safe to do:
+		//
+		// if uint64(len) > cap {
+		//     if len < 0 { panicmakeslicelen() }
+		//     panicmakeslicecap()
+		// }
+		nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OGT, typecheck.Conv(l, types.Types[types.TUINT64]), ir.NewInt(i)), nil, nil)
+		niflen := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLT, l, ir.NewInt(0)), nil, nil)
+		niflen.Body = []ir.Node{mkcall("panicmakeslicelen", nil, init)}
+		nif.Body.Append(niflen, mkcall("panicmakeslicecap", nil, init))
+		init.Append(typecheck.Stmt(nif))
+
+		t = types.NewArray(t.Elem(), i) // [r]T
+		var_ := typecheck.Temp(t)
+		appendWalkStmt(init, ir.NewAssignStmt(base.Pos, var_, nil))  // zero temp
+		r := ir.NewSliceExpr(base.Pos, ir.OSLICE, var_, nil, l, nil) // arr[:l]
+		// The conv is necessary in case n.Type is named.
+		return walkExpr(typecheck.Expr(typecheck.Conv(r, n.Type())), init)
+	}
+
+	// n escapes; set up a call to makeslice.
+	// When len and cap can fit into int, use makeslice instead of
+	// makeslice64, which is faster and shorter on 32 bit platforms.
+
+	len, cap := l, r
+
+	fnname := "makeslice64"
+	argtype := types.Types[types.TINT64]
+
+	// 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(types.TIDEAL) || len.Type().Size() <= types.Types[types.TUINT].Size()) &&
+		(cap.Type().IsKind(types.TIDEAL) || cap.Type().Size() <= types.Types[types.TUINT].Size()) {
+		fnname = "makeslice"
+		argtype = types.Types[types.TINT]
+	}
+	fn := typecheck.LookupRuntime(fnname)
+	ptr := mkcall1(fn, types.Types[types.TUNSAFEPTR], init, reflectdata.TypePtr(t.Elem()), typecheck.Conv(len, argtype), typecheck.Conv(cap, argtype))
+	ptr.MarkNonNil()
+	len = typecheck.Conv(len, types.Types[types.TINT])
+	cap = typecheck.Conv(cap, types.Types[types.TINT])
+	sh := ir.NewSliceHeaderExpr(base.Pos, t, ptr, len, cap)
+	return walkExpr(typecheck.Expr(sh), init)
+}
+
+// walkMakeSliceCopy walks an OMAKESLICECOPY node.
+func walkMakeSliceCopy(n *ir.MakeExpr, init *ir.Nodes) ir.Node {
+	if n.Esc() == ir.EscNone {
+		base.Fatalf("OMAKESLICECOPY with EscNone: %v", n)
+	}
+
+	t := n.Type()
+	if t.Elem().NotInHeap() {
+		base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem())
+	}
+
+	length := typecheck.Conv(n.Len, types.Types[types.TINT])
+	copylen := ir.NewUnaryExpr(base.Pos, ir.OLEN, n.Cap)
+	copyptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, n.Cap)
+
+	if !t.Elem().HasPointers() && n.Bounded() {
+		// When len(to)==len(from) and elements have no pointers:
+		// replace make+copy with runtime.mallocgc+runtime.memmove.
+
+		// We do not check for overflow of len(to)*elem.Width here
+		// since len(from) is an existing checked slice capacity
+		// with same elem.Width for the from slice.
+		size := ir.NewBinaryExpr(base.Pos, ir.OMUL, typecheck.Conv(length, types.Types[types.TUINTPTR]), typecheck.Conv(ir.NewInt(t.Elem().Width), types.Types[types.TUINTPTR]))
+
+		// instantiate mallocgc(size uintptr, typ *byte, needszero bool) unsafe.Pointer
+		fn := typecheck.LookupRuntime("mallocgc")
+		ptr := mkcall1(fn, types.Types[types.TUNSAFEPTR], init, size, typecheck.NodNil(), ir.NewBool(false))
+		ptr.MarkNonNil()
+		sh := ir.NewSliceHeaderExpr(base.Pos, t, ptr, length, length)
+
+		s := typecheck.Temp(t)
+		r := typecheck.Stmt(ir.NewAssignStmt(base.Pos, s, sh))
+		r = walkExpr(r, init)
+		init.Append(r)
+
+		// instantiate memmove(to *any, frm *any, size uintptr)
+		fn = typecheck.LookupRuntime("memmove")
+		fn = typecheck.SubstArgTypes(fn, t.Elem(), t.Elem())
+		ncopy := mkcall1(fn, nil, init, ir.NewUnaryExpr(base.Pos, ir.OSPTR, s), copyptr, size)
+		init.Append(walkExpr(typecheck.Stmt(ncopy), init))
+
+		return s
+	}
+	// Replace make+copy with runtime.makeslicecopy.
+	// instantiate makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer
+	fn := typecheck.LookupRuntime("makeslicecopy")
+	ptr := mkcall1(fn, types.Types[types.TUNSAFEPTR], init, reflectdata.TypePtr(t.Elem()), length, copylen, typecheck.Conv(copyptr, types.Types[types.TUNSAFEPTR]))
+	ptr.MarkNonNil()
+	sh := ir.NewSliceHeaderExpr(base.Pos, t, ptr, length, length)
+	return walkExpr(typecheck.Expr(sh), init)
+}
+
+// walkNew walks an ONEW node.
+func walkNew(n *ir.UnaryExpr, init *ir.Nodes) ir.Node {
+	t := n.Type().Elem()
+	if t.NotInHeap() {
+		base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type().Elem())
+	}
+	if n.Esc() == ir.EscNone {
+		if t.Size() > ir.MaxImplicitStackVarSize {
+			base.Fatalf("large ONEW with EscNone: %v", n)
+		}
+		return stackTempAddr(init, t)
+	}
+	types.CalcSize(t)
+	n.MarkNonNil()
+	return n
+}
+
+// generate code for print
+func walkPrint(nn *ir.CallExpr, init *ir.Nodes) ir.Node {
+	// Hoist all the argument evaluation up before the lock.
+	walkExprListCheap(nn.Args, init)
+
+	// For println, add " " between elements and "\n" at the end.
+	if nn.Op() == ir.OPRINTN {
+		s := nn.Args
+		t := make([]ir.Node, 0, len(s)*2)
+		for i, n := range s {
+			if i != 0 {
+				t = append(t, ir.NewString(" "))
+			}
+			t = append(t, n)
+		}
+		t = append(t, ir.NewString("\n"))
+		nn.Args = t
+	}
+
+	// Collapse runs of constant strings.
+	s := nn.Args
+	t := make([]ir.Node, 0, len(s))
+	for i := 0; i < len(s); {
+		var strs []string
+		for i < len(s) && ir.IsConst(s[i], constant.String) {
+			strs = append(strs, ir.StringVal(s[i]))
+			i++
+		}
+		if len(strs) > 0 {
+			t = append(t, ir.NewString(strings.Join(strs, "")))
+		}
+		if i < len(s) {
+			t = append(t, s[i])
+			i++
+		}
+	}
+	nn.Args = t
+
+	calls := []ir.Node{mkcall("printlock", nil, init)}
+	for i, n := range nn.Args {
+		if n.Op() == ir.OLITERAL {
+			if n.Type() == types.UntypedRune {
+				n = typecheck.DefaultLit(n, types.RuneType)
+			}
+
+			switch n.Val().Kind() {
+			case constant.Int:
+				n = typecheck.DefaultLit(n, types.Types[types.TINT64])
+
+			case constant.Float:
+				n = typecheck.DefaultLit(n, types.Types[types.TFLOAT64])
+			}
+		}
+
+		if n.Op() != ir.OLITERAL && n.Type() != nil && n.Type().Kind() == types.TIDEAL {
+			n = typecheck.DefaultLit(n, types.Types[types.TINT64])
+		}
+		n = typecheck.DefaultLit(n, nil)
+		nn.Args[i] = n
+		if n.Type() == nil || n.Type().Kind() == types.TFORW {
+			continue
+		}
+
+		var on *ir.Name
+		switch n.Type().Kind() {
+		case types.TINTER:
+			if n.Type().IsEmptyInterface() {
+				on = typecheck.LookupRuntime("printeface")
+			} else {
+				on = typecheck.LookupRuntime("printiface")
+			}
+			on = typecheck.SubstArgTypes(on, n.Type()) // any-1
+		case types.TPTR:
+			if n.Type().Elem().NotInHeap() {
+				on = typecheck.LookupRuntime("printuintptr")
+				n = ir.NewConvExpr(base.Pos, ir.OCONV, nil, n)
+				n.SetType(types.Types[types.TUNSAFEPTR])
+				n = ir.NewConvExpr(base.Pos, ir.OCONV, nil, n)
+				n.SetType(types.Types[types.TUINTPTR])
+				break
+			}
+			fallthrough
+		case types.TCHAN, types.TMAP, types.TFUNC, types.TUNSAFEPTR:
+			on = typecheck.LookupRuntime("printpointer")
+			on = typecheck.SubstArgTypes(on, n.Type()) // any-1
+		case types.TSLICE:
+			on = typecheck.LookupRuntime("printslice")
+			on = typecheck.SubstArgTypes(on, n.Type()) // any-1
+		case types.TUINT, types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64, types.TUINTPTR:
+			if types.IsRuntimePkg(n.Type().Sym().Pkg) && n.Type().Sym().Name == "hex" {
+				on = typecheck.LookupRuntime("printhex")
+			} else {
+				on = typecheck.LookupRuntime("printuint")
+			}
+		case types.TINT, types.TINT8, types.TINT16, types.TINT32, types.TINT64:
+			on = typecheck.LookupRuntime("printint")
+		case types.TFLOAT32, types.TFLOAT64:
+			on = typecheck.LookupRuntime("printfloat")
+		case types.TCOMPLEX64, types.TCOMPLEX128:
+			on = typecheck.LookupRuntime("printcomplex")
+		case types.TBOOL:
+			on = typecheck.LookupRuntime("printbool")
+		case types.TSTRING:
+			cs := ""
+			if ir.IsConst(n, constant.String) {
+				cs = ir.StringVal(n)
+			}
+			switch cs {
+			case " ":
+				on = typecheck.LookupRuntime("printsp")
+			case "\n":
+				on = typecheck.LookupRuntime("printnl")
+			default:
+				on = typecheck.LookupRuntime("printstring")
+			}
+		default:
+			badtype(ir.OPRINT, n.Type(), nil)
+			continue
+		}
+
+		r := ir.NewCallExpr(base.Pos, ir.OCALL, on, nil)
+		if params := on.Type().Params().FieldSlice(); len(params) > 0 {
+			t := params[0].Type
+			if !types.Identical(t, n.Type()) {
+				n = ir.NewConvExpr(base.Pos, ir.OCONV, nil, n)
+				n.SetType(t)
+			}
+			r.Args.Append(n)
+		}
+		calls = append(calls, r)
+	}
+
+	calls = append(calls, mkcall("printunlock", nil, init))
+
+	typecheck.Stmts(calls)
+	walkExprList(calls, init)
+
+	r := ir.NewBlockStmt(base.Pos, nil)
+	r.List = calls
+	return walkStmt(typecheck.Stmt(r))
+}
+
+// walkRecover walks an ORECOVER node.
+func walkRecover(nn *ir.CallExpr, init *ir.Nodes) ir.Node {
+	// Call gorecover with the FP of this frame.
+	// FP is equal to caller's SP plus FixedFrameSize().
+	var fp ir.Node = mkcall("getcallersp", types.Types[types.TUINTPTR], init)
+	if off := base.Ctxt.FixedFrameSize(); off != 0 {
+		fp = ir.NewBinaryExpr(fp.Pos(), ir.OADD, fp, ir.NewInt(off))
+	}
+	fp = ir.NewConvExpr(fp.Pos(), ir.OCONVNOP, types.NewPtr(types.Types[types.TINT32]), fp)
+	return mkcall("gorecover", nn.Type(), init, fp)
+}
+
+func walkUnsafeSlice(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
+	ptr := safeExpr(n.X, init)
+	len := safeExpr(n.Y, init)
+
+	fnname := "unsafeslice64"
+	lenType := types.Types[types.TINT64]
+
+	// 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 unsafeslice during runtime.
+	if ir.ShouldCheckPtr(ir.CurFunc, 1) {
+		fnname = "unsafeslicecheckptr"
+		// for simplicity, unsafeslicecheckptr always uses int64
+	} else if len.Type().IsKind(types.TIDEAL) || len.Type().Size() <= types.Types[types.TUINT].Size() {
+		fnname = "unsafeslice"
+		lenType = types.Types[types.TINT]
+	}
+
+	t := n.Type()
+
+	// Call runtime.unsafeslice{,64,checkptr} to check ptr and len.
+	fn := typecheck.LookupRuntime(fnname)
+	init.Append(mkcall1(fn, nil, init, reflectdata.TypePtr(t.Elem()), typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR]), typecheck.Conv(len, lenType)))
+
+	h := ir.NewSliceHeaderExpr(n.Pos(), t,
+		typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR]),
+		typecheck.Conv(len, types.Types[types.TINT]),
+		typecheck.Conv(len, types.Types[types.TINT]))
+	return walkExpr(typecheck.Expr(h), init)
+}
+
+func badtype(op ir.Op, tl, tr *types.Type) {
+	var s string
+	if tl != nil {
+		s += fmt.Sprintf("\n\t%v", tl)
+	}
+	if tr != nil {
+		s += fmt.Sprintf("\n\t%v", tr)
+	}
+
+	// common mistake: *struct and *interface.
+	if tl != nil && tr != nil && tl.IsPtr() && tr.IsPtr() {
+		if tl.Elem().IsStruct() && tr.Elem().IsInterface() {
+			s += "\n\t(*struct vs *interface)"
+		} else if tl.Elem().IsInterface() && tr.Elem().IsStruct() {
+			s += "\n\t(*interface vs *struct)"
+		}
+	}
+
+	base.Errorf("illegal types for operand: %v%s", op, s)
+}
+
+func writebarrierfn(name string, l *types.Type, r *types.Type) ir.Node {
+	fn := typecheck.LookupRuntime(name)
+	fn = typecheck.SubstArgTypes(fn, l, r)
+	return fn
+}
+
+// isRuneCount reports whether n is of the form len([]rune(string)).
+// These are optimized into a call to runtime.countrunes.
+func isRuneCount(n ir.Node) bool {
+	return base.Flag.N == 0 && !base.Flag.Cfg.Instrumenting && n.Op() == ir.OLEN && n.(*ir.UnaryExpr).X.Op() == ir.OSTR2RUNES
+}
diff --git a/src/cmd/compile/internal/walk/closure.go b/src/cmd/compile/internal/walk/closure.go
new file mode 100644
index 0000000..2194e1c
--- /dev/null
+++ b/src/cmd/compile/internal/walk/closure.go
@@ -0,0 +1,207 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// directClosureCall rewrites a direct call of a function literal into
+// a normal function call with closure variables passed as arguments.
+// This avoids allocation of a closure object.
+//
+// For illustration, the following call:
+//
+//	func(a int) {
+//		println(byval)
+//		byref++
+//	}(42)
+//
+// becomes:
+//
+//	func(byval int, &byref *int, a int) {
+//		println(byval)
+//		(*&byref)++
+//	}(byval, &byref, 42)
+func directClosureCall(n *ir.CallExpr) {
+	clo := n.X.(*ir.ClosureExpr)
+	clofn := clo.Func
+
+	if ir.IsTrivialClosure(clo) {
+		return // leave for walkClosure to handle
+	}
+
+	// If wrapGoDefer() in the order phase has flagged this call,
+	// avoid eliminating the closure even if there is a direct call to
+	// (the closure is needed to simplify the register ABI). See
+	// wrapGoDefer for more details.
+	if n.PreserveClosure {
+		return
+	}
+
+	// We are going to insert captured variables before input args.
+	var params []*types.Field
+	var decls []*ir.Name
+	for _, v := range clofn.ClosureVars {
+		if !v.Byval() {
+			// If v of type T is captured by reference,
+			// we introduce function param &v *T
+			// and v remains PAUTOHEAP with &v heapaddr
+			// (accesses will implicitly deref &v).
+
+			addr := ir.NewNameAt(clofn.Pos(), typecheck.Lookup("&"+v.Sym().Name))
+			addr.Curfn = clofn
+			addr.SetType(types.NewPtr(v.Type()))
+			v.Heapaddr = addr
+			v = addr
+		}
+
+		v.Class = ir.PPARAM
+		decls = append(decls, v)
+
+		fld := types.NewField(src.NoXPos, v.Sym(), v.Type())
+		fld.Nname = v
+		params = append(params, fld)
+	}
+
+	// f is ONAME of the actual function.
+	f := clofn.Nname
+	typ := f.Type()
+
+	// Create new function type with parameters prepended, and
+	// then update type and declarations.
+	typ = types.NewSignature(typ.Pkg(), nil, nil, append(params, typ.Params().FieldSlice()...), typ.Results().FieldSlice())
+	f.SetType(typ)
+	clofn.Dcl = append(decls, clofn.Dcl...)
+
+	// Rewrite call.
+	n.X = f
+	n.Args.Prepend(closureArgs(clo)...)
+
+	// Update the call expression's type. We need to do this
+	// because typecheck gave it the result type of the OCLOSURE
+	// node, but we only rewrote the ONAME node's type. Logically,
+	// they're the same, but the stack offsets probably changed.
+	if typ.NumResults() == 1 {
+		n.SetType(typ.Results().Field(0).Type)
+	} else {
+		n.SetType(typ.Results())
+	}
+
+	// Add to Closures for enqueueFunc. It's no longer a proper
+	// closure, but we may have already skipped over it in the
+	// functions list as a non-trivial closure, so this just
+	// ensures it's compiled.
+	ir.CurFunc.Closures = append(ir.CurFunc.Closures, clofn)
+}
+
+func walkClosure(clo *ir.ClosureExpr, init *ir.Nodes) ir.Node {
+	clofn := clo.Func
+
+	// If no closure vars, don't bother wrapping.
+	if ir.IsTrivialClosure(clo) {
+		if base.Debug.Closure > 0 {
+			base.WarnfAt(clo.Pos(), "closure converted to global")
+		}
+		return clofn.Nname
+	}
+
+	// The closure is not trivial or directly called, so it's going to stay a closure.
+	ir.ClosureDebugRuntimeCheck(clo)
+	clofn.SetNeedctxt(true)
+	ir.CurFunc.Closures = append(ir.CurFunc.Closures, clofn)
+
+	typ := typecheck.ClosureType(clo)
+
+	clos := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(typ), nil)
+	clos.SetEsc(clo.Esc())
+	clos.List = append([]ir.Node{ir.NewUnaryExpr(base.Pos, ir.OCFUNC, clofn.Nname)}, closureArgs(clo)...)
+
+	addr := typecheck.NodAddr(clos)
+	addr.SetEsc(clo.Esc())
+
+	// Force type conversion from *struct to the func type.
+	cfn := typecheck.ConvNop(addr, clo.Type())
+
+	// non-escaping temp to use, if any.
+	if x := clo.Prealloc; x != nil {
+		if !types.Identical(typ, x.Type()) {
+			panic("closure type does not match order's assigned type")
+		}
+		addr.Prealloc = x
+		clo.Prealloc = nil
+	}
+
+	return walkExpr(cfn, init)
+}
+
+// closureArgs returns a slice of expressions that an be used to
+// initialize the given closure's free variables. These correspond
+// one-to-one with the variables in clo.Func.ClosureVars, and will be
+// either an ONAME node (if the variable is captured by value) or an
+// OADDR-of-ONAME node (if not).
+func closureArgs(clo *ir.ClosureExpr) []ir.Node {
+	fn := clo.Func
+
+	args := make([]ir.Node, len(fn.ClosureVars))
+	for i, v := range fn.ClosureVars {
+		var outer ir.Node
+		outer = v.Outer
+		if !v.Byval() {
+			outer = typecheck.NodAddrAt(fn.Pos(), outer)
+		}
+		args[i] = typecheck.Expr(outer)
+	}
+	return args
+}
+
+func walkCallPart(n *ir.SelectorExpr, init *ir.Nodes) ir.Node {
+	// Create closure in the form of a composite literal.
+	// For x.M with receiver (x) type T, the generated code looks like:
+	//
+	//	clos = &struct{F uintptr; R T}{T.M·f, x}
+	//
+	// Like walkClosure above.
+
+	if n.X.Type().IsInterface() {
+		// Trigger panic for method on nil interface now.
+		// Otherwise it happens in the wrapper and is confusing.
+		n.X = cheapExpr(n.X, init)
+		n.X = walkExpr(n.X, nil)
+
+		tab := typecheck.Expr(ir.NewUnaryExpr(base.Pos, ir.OITAB, n.X))
+
+		c := ir.NewUnaryExpr(base.Pos, ir.OCHECKNIL, tab)
+		c.SetTypecheck(1)
+		init.Append(c)
+	}
+
+	typ := typecheck.PartialCallType(n)
+
+	clos := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(typ), nil)
+	clos.SetEsc(n.Esc())
+	clos.List = []ir.Node{ir.NewUnaryExpr(base.Pos, ir.OCFUNC, typecheck.MethodValueWrapper(n).Nname), n.X}
+
+	addr := typecheck.NodAddr(clos)
+	addr.SetEsc(n.Esc())
+
+	// Force type conversion from *struct to the func type.
+	cfn := typecheck.ConvNop(addr, n.Type())
+
+	// non-escaping temp to use, if any.
+	if x := n.Prealloc; x != nil {
+		if !types.Identical(typ, x.Type()) {
+			panic("partial call type does not match order's assigned type")
+		}
+		addr.Prealloc = x
+		n.Prealloc = nil
+	}
+
+	return walkExpr(cfn, init)
+}
diff --git a/src/cmd/compile/internal/walk/compare.go b/src/cmd/compile/internal/walk/compare.go
new file mode 100644
index 0000000..b18615f
--- /dev/null
+++ b/src/cmd/compile/internal/walk/compare.go
@@ -0,0 +1,508 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"encoding/binary"
+	"go/constant"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/ssagen"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/sys"
+)
+
+// The result of walkCompare MUST be assigned back to n, e.g.
+// 	n.Left = walkCompare(n.Left, init)
+func walkCompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
+	if n.X.Type().IsInterface() && n.Y.Type().IsInterface() && n.X.Op() != ir.ONIL && n.Y.Op() != ir.ONIL {
+		return walkCompareInterface(n, init)
+	}
+
+	if n.X.Type().IsString() && n.Y.Type().IsString() {
+		return walkCompareString(n, init)
+	}
+
+	n.X = walkExpr(n.X, init)
+	n.Y = walkExpr(n.Y, init)
+
+	// Given mixed interface/concrete comparison,
+	// rewrite into types-equal && data-equal.
+	// This is efficient, avoids allocations, and avoids runtime calls.
+	if n.X.Type().IsInterface() != n.Y.Type().IsInterface() {
+		// Preserve side-effects in case of short-circuiting; see #32187.
+		l := cheapExpr(n.X, init)
+		r := cheapExpr(n.Y, init)
+		// Swap so that l is the interface value and r is the concrete value.
+		if n.Y.Type().IsInterface() {
+			l, r = r, l
+		}
+
+		// Handle both == and !=.
+		eq := n.Op()
+		andor := ir.OOROR
+		if eq == ir.OEQ {
+			andor = ir.OANDAND
+		}
+		// Check for types equal.
+		// For empty interface, this is:
+		//   l.tab == type(r)
+		// For non-empty interface, this is:
+		//   l.tab != nil && l.tab._type == type(r)
+		var eqtype ir.Node
+		tab := ir.NewUnaryExpr(base.Pos, ir.OITAB, l)
+		rtyp := reflectdata.TypePtr(r.Type())
+		if l.Type().IsEmptyInterface() {
+			tab.SetType(types.NewPtr(types.Types[types.TUINT8]))
+			tab.SetTypecheck(1)
+			eqtype = ir.NewBinaryExpr(base.Pos, eq, tab, rtyp)
+		} else {
+			nonnil := ir.NewBinaryExpr(base.Pos, brcom(eq), typecheck.NodNil(), tab)
+			match := ir.NewBinaryExpr(base.Pos, eq, itabType(tab), rtyp)
+			eqtype = ir.NewLogicalExpr(base.Pos, andor, nonnil, match)
+		}
+		// Check for data equal.
+		eqdata := ir.NewBinaryExpr(base.Pos, eq, ifaceData(n.Pos(), l, r.Type()), r)
+		// Put it all together.
+		expr := ir.NewLogicalExpr(base.Pos, andor, eqtype, eqdata)
+		return finishCompare(n, expr, init)
+	}
+
+	// Must be comparison of array or struct.
+	// Otherwise back end handles it.
+	// While we're here, decide whether to
+	// inline or call an eq alg.
+	t := n.X.Type()
+	var inline bool
+
+	maxcmpsize := int64(4)
+	unalignedLoad := canMergeLoads()
+	if unalignedLoad {
+		// Keep this low enough to generate less code than a function call.
+		maxcmpsize = 2 * int64(ssagen.Arch.LinkArch.RegSize)
+	}
+
+	switch t.Kind() {
+	default:
+		if base.Debug.Libfuzzer != 0 && t.IsInteger() {
+			n.X = cheapExpr(n.X, init)
+			n.Y = cheapExpr(n.Y, init)
+
+			// If exactly one comparison operand is
+			// constant, invoke the constcmp functions
+			// instead, and arrange for the constant
+			// operand to be the first argument.
+			l, r := n.X, n.Y
+			if r.Op() == ir.OLITERAL {
+				l, r = r, l
+			}
+			constcmp := l.Op() == ir.OLITERAL && r.Op() != ir.OLITERAL
+
+			var fn string
+			var paramType *types.Type
+			switch t.Size() {
+			case 1:
+				fn = "libfuzzerTraceCmp1"
+				if constcmp {
+					fn = "libfuzzerTraceConstCmp1"
+				}
+				paramType = types.Types[types.TUINT8]
+			case 2:
+				fn = "libfuzzerTraceCmp2"
+				if constcmp {
+					fn = "libfuzzerTraceConstCmp2"
+				}
+				paramType = types.Types[types.TUINT16]
+			case 4:
+				fn = "libfuzzerTraceCmp4"
+				if constcmp {
+					fn = "libfuzzerTraceConstCmp4"
+				}
+				paramType = types.Types[types.TUINT32]
+			case 8:
+				fn = "libfuzzerTraceCmp8"
+				if constcmp {
+					fn = "libfuzzerTraceConstCmp8"
+				}
+				paramType = types.Types[types.TUINT64]
+			default:
+				base.Fatalf("unexpected integer size %d for %v", t.Size(), t)
+			}
+			init.Append(mkcall(fn, nil, init, tracecmpArg(l, paramType, init), tracecmpArg(r, paramType, init)))
+		}
+		return n
+	case types.TARRAY:
+		// We can compare several elements at once with 2/4/8 byte integer compares
+		inline = t.NumElem() <= 1 || (types.IsSimple[t.Elem().Kind()] && (t.NumElem() <= 4 || t.Elem().Width*t.NumElem() <= maxcmpsize))
+	case types.TSTRUCT:
+		inline = t.NumComponents(types.IgnoreBlankFields) <= 4
+	}
+
+	cmpl := n.X
+	for cmpl != nil && cmpl.Op() == ir.OCONVNOP {
+		cmpl = cmpl.(*ir.ConvExpr).X
+	}
+	cmpr := n.Y
+	for cmpr != nil && cmpr.Op() == ir.OCONVNOP {
+		cmpr = cmpr.(*ir.ConvExpr).X
+	}
+
+	// Chose not to inline. Call equality function directly.
+	if !inline {
+		// eq algs take pointers; cmpl and cmpr must be addressable
+		if !ir.IsAddressable(cmpl) || !ir.IsAddressable(cmpr) {
+			base.Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
+		}
+
+		fn, needsize := eqFor(t)
+		call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, nil)
+		call.Args.Append(typecheck.NodAddr(cmpl))
+		call.Args.Append(typecheck.NodAddr(cmpr))
+		if needsize {
+			call.Args.Append(ir.NewInt(t.Width))
+		}
+		res := ir.Node(call)
+		if n.Op() != ir.OEQ {
+			res = ir.NewUnaryExpr(base.Pos, ir.ONOT, res)
+		}
+		return finishCompare(n, res, init)
+	}
+
+	// inline: build boolean expression comparing element by element
+	andor := ir.OANDAND
+	if n.Op() == ir.ONE {
+		andor = ir.OOROR
+	}
+	var expr ir.Node
+	compare := func(el, er ir.Node) {
+		a := ir.NewBinaryExpr(base.Pos, n.Op(), el, er)
+		if expr == nil {
+			expr = a
+		} else {
+			expr = ir.NewLogicalExpr(base.Pos, andor, expr, a)
+		}
+	}
+	cmpl = safeExpr(cmpl, init)
+	cmpr = safeExpr(cmpr, init)
+	if t.IsStruct() {
+		for _, f := range t.Fields().Slice() {
+			sym := f.Sym
+			if sym.IsBlank() {
+				continue
+			}
+			compare(
+				ir.NewSelectorExpr(base.Pos, ir.OXDOT, cmpl, sym),
+				ir.NewSelectorExpr(base.Pos, ir.OXDOT, cmpr, sym),
+			)
+		}
+	} else {
+		step := int64(1)
+		remains := t.NumElem() * t.Elem().Width
+		combine64bit := unalignedLoad && types.RegSize == 8 && t.Elem().Width <= 4 && t.Elem().IsInteger()
+		combine32bit := unalignedLoad && t.Elem().Width <= 2 && t.Elem().IsInteger()
+		combine16bit := unalignedLoad && t.Elem().Width == 1 && t.Elem().IsInteger()
+		for i := int64(0); remains > 0; {
+			var convType *types.Type
+			switch {
+			case remains >= 8 && combine64bit:
+				convType = types.Types[types.TINT64]
+				step = 8 / t.Elem().Width
+			case remains >= 4 && combine32bit:
+				convType = types.Types[types.TUINT32]
+				step = 4 / t.Elem().Width
+			case remains >= 2 && combine16bit:
+				convType = types.Types[types.TUINT16]
+				step = 2 / t.Elem().Width
+			default:
+				step = 1
+			}
+			if step == 1 {
+				compare(
+					ir.NewIndexExpr(base.Pos, cmpl, ir.NewInt(i)),
+					ir.NewIndexExpr(base.Pos, cmpr, ir.NewInt(i)),
+				)
+				i++
+				remains -= t.Elem().Width
+			} else {
+				elemType := t.Elem().ToUnsigned()
+				cmplw := ir.Node(ir.NewIndexExpr(base.Pos, cmpl, ir.NewInt(i)))
+				cmplw = typecheck.Conv(cmplw, elemType) // convert to unsigned
+				cmplw = typecheck.Conv(cmplw, convType) // widen
+				cmprw := ir.Node(ir.NewIndexExpr(base.Pos, cmpr, ir.NewInt(i)))
+				cmprw = typecheck.Conv(cmprw, elemType)
+				cmprw = typecheck.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 := ir.Node(ir.NewIndexExpr(base.Pos, cmpl, ir.NewInt(i+offset)))
+					lb = typecheck.Conv(lb, elemType)
+					lb = typecheck.Conv(lb, convType)
+					lb = ir.NewBinaryExpr(base.Pos, ir.OLSH, lb, ir.NewInt(8*t.Elem().Width*offset))
+					cmplw = ir.NewBinaryExpr(base.Pos, ir.OOR, cmplw, lb)
+					rb := ir.Node(ir.NewIndexExpr(base.Pos, cmpr, ir.NewInt(i+offset)))
+					rb = typecheck.Conv(rb, elemType)
+					rb = typecheck.Conv(rb, convType)
+					rb = ir.NewBinaryExpr(base.Pos, ir.OLSH, rb, ir.NewInt(8*t.Elem().Width*offset))
+					cmprw = ir.NewBinaryExpr(base.Pos, ir.OOR, cmprw, rb)
+				}
+				compare(cmplw, cmprw)
+				i += step
+				remains -= step * t.Elem().Width
+			}
+		}
+	}
+	if expr == nil {
+		expr = ir.NewBool(n.Op() == ir.OEQ)
+		// We still need to use cmpl and cmpr, in case they contain
+		// an expression which might panic. See issue 23837.
+		t := typecheck.Temp(cmpl.Type())
+		a1 := typecheck.Stmt(ir.NewAssignStmt(base.Pos, t, cmpl))
+		a2 := typecheck.Stmt(ir.NewAssignStmt(base.Pos, t, cmpr))
+		init.Append(a1, a2)
+	}
+	return finishCompare(n, expr, init)
+}
+
+func walkCompareInterface(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
+	n.Y = cheapExpr(n.Y, init)
+	n.X = cheapExpr(n.X, init)
+	eqtab, eqdata := reflectdata.EqInterface(n.X, n.Y)
+	var cmp ir.Node
+	if n.Op() == ir.OEQ {
+		cmp = ir.NewLogicalExpr(base.Pos, ir.OANDAND, eqtab, eqdata)
+	} else {
+		eqtab.SetOp(ir.ONE)
+		cmp = ir.NewLogicalExpr(base.Pos, ir.OOROR, eqtab, ir.NewUnaryExpr(base.Pos, ir.ONOT, eqdata))
+	}
+	return finishCompare(n, cmp, init)
+}
+
+func walkCompareString(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
+	// Rewrite comparisons to short constant strings as length+byte-wise comparisons.
+	var cs, ncs ir.Node // const string, non-const string
+	switch {
+	case ir.IsConst(n.X, constant.String) && ir.IsConst(n.Y, constant.String):
+		// ignore; will be constant evaluated
+	case ir.IsConst(n.X, constant.String):
+		cs = n.X
+		ncs = n.Y
+	case ir.IsConst(n.Y, constant.String):
+		cs = n.Y
+		ncs = n.X
+	}
+	if cs != nil {
+		cmp := n.Op()
+		// Our comparison below assumes that the non-constant string
+		// is on the left hand side, so rewrite "" cmp x to x cmp "".
+		// See issue 24817.
+		if ir.IsConst(n.X, constant.String) {
+			cmp = brrev(cmp)
+		}
+
+		// maxRewriteLen was chosen empirically.
+		// It is the value that minimizes cmd/go file size
+		// across most architectures.
+		// See the commit description for CL 26758 for details.
+		maxRewriteLen := 6
+		// Some architectures can load unaligned byte sequence as 1 word.
+		// So we can cover longer strings with the same amount of code.
+		canCombineLoads := canMergeLoads()
+		combine64bit := false
+		if canCombineLoads {
+			// Keep this low enough to generate less code than a function call.
+			maxRewriteLen = 2 * ssagen.Arch.LinkArch.RegSize
+			combine64bit = ssagen.Arch.LinkArch.RegSize >= 8
+		}
+
+		var and ir.Op
+		switch cmp {
+		case ir.OEQ:
+			and = ir.OANDAND
+		case ir.ONE:
+			and = ir.OOROR
+		default:
+			// Don't do byte-wise comparisons for <, <=, etc.
+			// They're fairly complicated.
+			// Length-only checks are ok, though.
+			maxRewriteLen = 0
+		}
+		if s := ir.StringVal(cs); len(s) <= maxRewriteLen {
+			if len(s) > 0 {
+				ncs = safeExpr(ncs, init)
+			}
+			r := ir.Node(ir.NewBinaryExpr(base.Pos, cmp, ir.NewUnaryExpr(base.Pos, ir.OLEN, ncs), ir.NewInt(int64(len(s)))))
+			remains := len(s)
+			for i := 0; remains > 0; {
+				if remains == 1 || !canCombineLoads {
+					cb := ir.NewInt(int64(s[i]))
+					ncb := ir.NewIndexExpr(base.Pos, ncs, ir.NewInt(int64(i)))
+					r = ir.NewLogicalExpr(base.Pos, and, r, ir.NewBinaryExpr(base.Pos, cmp, ncb, cb))
+					remains--
+					i++
+					continue
+				}
+				var step int
+				var convType *types.Type
+				switch {
+				case remains >= 8 && combine64bit:
+					convType = types.Types[types.TINT64]
+					step = 8
+				case remains >= 4:
+					convType = types.Types[types.TUINT32]
+					step = 4
+				case remains >= 2:
+					convType = types.Types[types.TUINT16]
+					step = 2
+				}
+				ncsubstr := typecheck.Conv(ir.NewIndexExpr(base.Pos, ncs, ir.NewInt(int64(i))), convType)
+				csubstr := int64(s[i])
+				// Calculate large constant from bytes as sequence of shifts and ors.
+				// Like this:  uint32(s[0]) | uint32(s[1])<<8 | uint32(s[2])<<16 ...
+				// ssa will combine this into a single large load.
+				for offset := 1; offset < step; offset++ {
+					b := typecheck.Conv(ir.NewIndexExpr(base.Pos, ncs, ir.NewInt(int64(i+offset))), convType)
+					b = ir.NewBinaryExpr(base.Pos, ir.OLSH, b, ir.NewInt(int64(8*offset)))
+					ncsubstr = ir.NewBinaryExpr(base.Pos, ir.OOR, ncsubstr, b)
+					csubstr |= int64(s[i+offset]) << uint8(8*offset)
+				}
+				csubstrPart := ir.NewInt(csubstr)
+				// Compare "step" bytes as once
+				r = ir.NewLogicalExpr(base.Pos, and, r, ir.NewBinaryExpr(base.Pos, cmp, csubstrPart, ncsubstr))
+				remains -= step
+				i += step
+			}
+			return finishCompare(n, r, init)
+		}
+	}
+
+	var r ir.Node
+	if n.Op() == ir.OEQ || n.Op() == ir.ONE {
+		// prepare for rewrite below
+		n.X = cheapExpr(n.X, init)
+		n.Y = cheapExpr(n.Y, init)
+		eqlen, eqmem := reflectdata.EqString(n.X, n.Y)
+		// quick check of len before full compare for == or !=.
+		// memequal then tests equality up to length len.
+		if n.Op() == ir.OEQ {
+			// len(left) == len(right) && memequal(left, right, len)
+			r = ir.NewLogicalExpr(base.Pos, ir.OANDAND, eqlen, eqmem)
+		} else {
+			// len(left) != len(right) || !memequal(left, right, len)
+			eqlen.SetOp(ir.ONE)
+			r = ir.NewLogicalExpr(base.Pos, ir.OOROR, eqlen, ir.NewUnaryExpr(base.Pos, ir.ONOT, eqmem))
+		}
+	} else {
+		// sys_cmpstring(s1, s2) :: 0
+		r = mkcall("cmpstring", types.Types[types.TINT], init, typecheck.Conv(n.X, types.Types[types.TSTRING]), typecheck.Conv(n.Y, types.Types[types.TSTRING]))
+		r = ir.NewBinaryExpr(base.Pos, n.Op(), r, ir.NewInt(0))
+	}
+
+	return finishCompare(n, r, init)
+}
+
+// The result of finishCompare MUST be assigned back to n, e.g.
+// 	n.Left = finishCompare(n.Left, x, r, init)
+func finishCompare(n *ir.BinaryExpr, r ir.Node, init *ir.Nodes) ir.Node {
+	r = typecheck.Expr(r)
+	r = typecheck.Conv(r, n.Type())
+	r = walkExpr(r, init)
+	return r
+}
+
+func eqFor(t *types.Type) (n ir.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
+	// is handled by walkCompare.
+	switch a, _ := types.AlgType(t); a {
+	case types.AMEM:
+		n := typecheck.LookupRuntime("memequal")
+		n = typecheck.SubstArgTypes(n, t, t)
+		return n, true
+	case types.ASPECIAL:
+		sym := reflectdata.TypeSymPrefix(".eq", t)
+		// TODO(austin): This creates an ir.Name with a nil Func.
+		n := typecheck.NewName(sym)
+		ir.MarkFunc(n)
+		n.SetType(types.NewSignature(types.NoPkg, nil, nil, []*types.Field{
+			types.NewField(base.Pos, nil, types.NewPtr(t)),
+			types.NewField(base.Pos, nil, types.NewPtr(t)),
+		}, []*types.Field{
+			types.NewField(base.Pos, nil, types.Types[types.TBOOL]),
+		}))
+		return n, false
+	}
+	base.Fatalf("eqFor %v", t)
+	return nil, false
+}
+
+// brcom returns !(op).
+// For example, brcom(==) is !=.
+func brcom(op ir.Op) ir.Op {
+	switch op {
+	case ir.OEQ:
+		return ir.ONE
+	case ir.ONE:
+		return ir.OEQ
+	case ir.OLT:
+		return ir.OGE
+	case ir.OGT:
+		return ir.OLE
+	case ir.OLE:
+		return ir.OGT
+	case ir.OGE:
+		return ir.OLT
+	}
+	base.Fatalf("brcom: no com for %v\n", op)
+	return op
+}
+
+// brrev returns reverse(op).
+// For example, Brrev(<) is >.
+func brrev(op ir.Op) ir.Op {
+	switch op {
+	case ir.OEQ:
+		return ir.OEQ
+	case ir.ONE:
+		return ir.ONE
+	case ir.OLT:
+		return ir.OGT
+	case ir.OGT:
+		return ir.OLT
+	case ir.OLE:
+		return ir.OGE
+	case ir.OGE:
+		return ir.OLE
+	}
+	base.Fatalf("brrev: no rev for %v\n", op)
+	return op
+}
+
+func tracecmpArg(n ir.Node, t *types.Type, init *ir.Nodes) ir.Node {
+	// Ugly hack to avoid "constant -1 overflows uintptr" errors, etc.
+	if n.Op() == ir.OLITERAL && n.Type().IsSigned() && ir.Int64Val(n) < 0 {
+		n = copyExpr(n, n.Type(), init)
+	}
+
+	return typecheck.Conv(n, t)
+}
+
+// canMergeLoads reports whether the backend optimization passes for
+// the current architecture can combine adjacent loads into a single
+// larger, possibly unaligned, load. Note that currently the
+// optimizations must be able to handle little endian byte order.
+func canMergeLoads() bool {
+	switch ssagen.Arch.LinkArch.Family {
+	case sys.ARM64, sys.AMD64, sys.I386, sys.S390X:
+		return true
+	case sys.PPC64:
+		// Load combining only supported on ppc64le.
+		return ssagen.Arch.LinkArch.ByteOrder == binary.LittleEndian
+	}
+	return false
+}
diff --git a/src/cmd/compile/internal/walk/complit.go b/src/cmd/compile/internal/walk/complit.go
new file mode 100644
index 0000000..abd920d
--- /dev/null
+++ b/src/cmd/compile/internal/walk/complit.go
@@ -0,0 +1,670 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/ssagen"
+	"cmd/compile/internal/staticdata"
+	"cmd/compile/internal/staticinit"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+)
+
+// walkCompLit walks a composite literal node:
+// OARRAYLIT, OSLICELIT, OMAPLIT, OSTRUCTLIT (all CompLitExpr), or OPTRLIT (AddrExpr).
+func walkCompLit(n ir.Node, init *ir.Nodes) ir.Node {
+	if isStaticCompositeLiteral(n) && !ssagen.TypeOK(n.Type()) {
+		n := n.(*ir.CompLitExpr) // not OPTRLIT
+		// n can be directly represented in the read-only data section.
+		// Make direct reference to the static data. See issue 12841.
+		vstat := readonlystaticname(n.Type())
+		fixedlit(inInitFunction, initKindStatic, n, vstat, init)
+		return typecheck.Expr(vstat)
+	}
+	var_ := typecheck.Temp(n.Type())
+	anylit(n, var_, init)
+	return var_
+}
+
+// initContext is the context in which static data is populated.
+// It is either in an init function or in any other function.
+// Static data populated in an init function will be written either
+// zero times (as a readonly, static data symbol) or
+// one time (during init function execution).
+// Either way, there is no opportunity for races or further modification,
+// so the data can be written to a (possibly readonly) data symbol.
+// Static data populated in any other function needs to be local to
+// that function to allow multiple instances of that function
+// to execute concurrently without clobbering each others' data.
+type initContext uint8
+
+const (
+	inInitFunction initContext = iota
+	inNonInitFunction
+)
+
+func (c initContext) String() string {
+	if c == inInitFunction {
+		return "inInitFunction"
+	}
+	return "inNonInitFunction"
+}
+
+// readonlystaticname returns a name backed by a read-only static data symbol.
+func readonlystaticname(t *types.Type) *ir.Name {
+	n := staticinit.StaticName(t)
+	n.MarkReadonly()
+	n.Linksym().Set(obj.AttrContentAddressable, true)
+	n.Linksym().Set(obj.AttrLocal, true)
+	return n
+}
+
+func isSimpleName(nn ir.Node) bool {
+	if nn.Op() != ir.ONAME || ir.IsBlank(nn) {
+		return false
+	}
+	n := nn.(*ir.Name)
+	return n.OnStack()
+}
+
+func litas(l ir.Node, r ir.Node, init *ir.Nodes) {
+	appendWalkStmt(init, ir.NewAssignStmt(base.Pos, l, r))
+}
+
+// initGenType is a bitmap indicating the types of generation that will occur for a static value.
+type initGenType uint8
+
+const (
+	initDynamic initGenType = 1 << iota // contains some dynamic values, for which init code will be generated
+	initConst                           // contains some constant values, which may be written into data symbols
+)
+
+// getdyn calculates the initGenType for n.
+// If top is false, getdyn is recursing.
+func getdyn(n ir.Node, top bool) initGenType {
+	switch n.Op() {
+	default:
+		if ir.IsConstNode(n) {
+			return initConst
+		}
+		return initDynamic
+
+	case ir.OSLICELIT:
+		n := n.(*ir.CompLitExpr)
+		if !top {
+			return initDynamic
+		}
+		if n.Len/4 > int64(len(n.List)) {
+			// <25% of entries have explicit values.
+			// Very rough estimation, it takes 4 bytes of instructions
+			// to initialize 1 byte of result. So don't use a static
+			// initializer if the dynamic initialization code would be
+			// smaller than the static value.
+			// See issue 23780.
+			return initDynamic
+		}
+
+	case ir.OARRAYLIT, ir.OSTRUCTLIT:
+	}
+	lit := n.(*ir.CompLitExpr)
+
+	var mode initGenType
+	for _, n1 := range lit.List {
+		switch n1.Op() {
+		case ir.OKEY:
+			n1 = n1.(*ir.KeyExpr).Value
+		case ir.OSTRUCTKEY:
+			n1 = n1.(*ir.StructKeyExpr).Value
+		}
+		mode |= getdyn(n1, false)
+		if mode == initDynamic|initConst {
+			break
+		}
+	}
+	return mode
+}
+
+// isStaticCompositeLiteral reports whether n is a compile-time constant.
+func isStaticCompositeLiteral(n ir.Node) bool {
+	switch n.Op() {
+	case ir.OSLICELIT:
+		return false
+	case ir.OARRAYLIT:
+		n := n.(*ir.CompLitExpr)
+		for _, r := range n.List {
+			if r.Op() == ir.OKEY {
+				r = r.(*ir.KeyExpr).Value
+			}
+			if !isStaticCompositeLiteral(r) {
+				return false
+			}
+		}
+		return true
+	case ir.OSTRUCTLIT:
+		n := n.(*ir.CompLitExpr)
+		for _, r := range n.List {
+			r := r.(*ir.StructKeyExpr)
+			if !isStaticCompositeLiteral(r.Value) {
+				return false
+			}
+		}
+		return true
+	case ir.OLITERAL, ir.ONIL:
+		return true
+	case ir.OCONVIFACE:
+		// See staticassign's OCONVIFACE case for comments.
+		n := n.(*ir.ConvExpr)
+		val := ir.Node(n)
+		for val.Op() == ir.OCONVIFACE {
+			val = val.(*ir.ConvExpr).X
+		}
+		if val.Type().IsInterface() {
+			return val.Op() == ir.ONIL
+		}
+		if types.IsDirectIface(val.Type()) && val.Op() == ir.ONIL {
+			return true
+		}
+		return isStaticCompositeLiteral(val)
+	}
+	return false
+}
+
+// initKind is a kind of static initialization: static, dynamic, or local.
+// Static initialization represents literals and
+// literal components of composite literals.
+// Dynamic initialization represents non-literals and
+// non-literal components of composite literals.
+// LocalCode initialization represents initialization
+// that occurs purely in generated code local to the function of use.
+// Initialization code is sometimes generated in passes,
+// first static then dynamic.
+type initKind uint8
+
+const (
+	initKindStatic initKind = iota + 1
+	initKindDynamic
+	initKindLocalCode
+)
+
+// fixedlit handles struct, array, and slice literals.
+// TODO: expand documentation.
+func fixedlit(ctxt initContext, kind initKind, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes) {
+	isBlank := var_ == ir.BlankNode
+	var splitnode func(ir.Node) (a ir.Node, value ir.Node)
+	switch n.Op() {
+	case ir.OARRAYLIT, ir.OSLICELIT:
+		var k int64
+		splitnode = func(r ir.Node) (ir.Node, ir.Node) {
+			if r.Op() == ir.OKEY {
+				kv := r.(*ir.KeyExpr)
+				k = typecheck.IndexConst(kv.Key)
+				if k < 0 {
+					base.Fatalf("fixedlit: invalid index %v", kv.Key)
+				}
+				r = kv.Value
+			}
+			a := ir.NewIndexExpr(base.Pos, var_, ir.NewInt(k))
+			k++
+			if isBlank {
+				return ir.BlankNode, r
+			}
+			return a, r
+		}
+	case ir.OSTRUCTLIT:
+		splitnode = func(rn ir.Node) (ir.Node, ir.Node) {
+			r := rn.(*ir.StructKeyExpr)
+			if r.Field.IsBlank() || isBlank {
+				return ir.BlankNode, r.Value
+			}
+			ir.SetPos(r)
+			return ir.NewSelectorExpr(base.Pos, ir.ODOT, var_, r.Field), r.Value
+		}
+	default:
+		base.Fatalf("fixedlit bad op: %v", n.Op())
+	}
+
+	for _, r := range n.List {
+		a, value := splitnode(r)
+		if a == ir.BlankNode && !staticinit.AnySideEffects(value) {
+			// Discard.
+			continue
+		}
+
+		switch value.Op() {
+		case ir.OSLICELIT:
+			value := value.(*ir.CompLitExpr)
+			if (kind == initKindStatic && ctxt == inNonInitFunction) || (kind == initKindDynamic && ctxt == inInitFunction) {
+				slicelit(ctxt, value, a, init)
+				continue
+			}
+
+		case ir.OARRAYLIT, ir.OSTRUCTLIT:
+			value := value.(*ir.CompLitExpr)
+			fixedlit(ctxt, kind, value, a, init)
+			continue
+		}
+
+		islit := ir.IsConstNode(value)
+		if (kind == initKindStatic && !islit) || (kind == initKindDynamic && islit) {
+			continue
+		}
+
+		// build list of assignments: var[index] = expr
+		ir.SetPos(a)
+		as := ir.NewAssignStmt(base.Pos, a, value)
+		as = typecheck.Stmt(as).(*ir.AssignStmt)
+		switch kind {
+		case initKindStatic:
+			genAsStatic(as)
+		case initKindDynamic, initKindLocalCode:
+			a = orderStmtInPlace(as, map[string][]*ir.Name{})
+			a = walkStmt(a)
+			init.Append(a)
+		default:
+			base.Fatalf("fixedlit: bad kind %d", kind)
+		}
+
+	}
+}
+
+func isSmallSliceLit(n *ir.CompLitExpr) bool {
+	if n.Op() != ir.OSLICELIT {
+		return false
+	}
+
+	return n.Type().Elem().Width == 0 || n.Len <= ir.MaxSmallArraySize/n.Type().Elem().Width
+}
+
+func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes) {
+	// make an array type corresponding the number of elements we have
+	t := types.NewArray(n.Type().Elem(), n.Len)
+	types.CalcSize(t)
+
+	if ctxt == inNonInitFunction {
+		// put everything into static array
+		vstat := staticinit.StaticName(t)
+
+		fixedlit(ctxt, initKindStatic, n, vstat, init)
+		fixedlit(ctxt, initKindDynamic, n, vstat, init)
+
+		// copy static to slice
+		var_ = typecheck.AssignExpr(var_)
+		name, offset, ok := staticinit.StaticLoc(var_)
+		if !ok || name.Class != ir.PEXTERN {
+			base.Fatalf("slicelit: %v", var_)
+		}
+		staticdata.InitSlice(name, offset, vstat.Linksym(), t.NumElem())
+		return
+	}
+
+	// recipe for var = []t{...}
+	// 1. make a static array
+	//	var vstat [...]t
+	// 2. assign (data statements) the constant part
+	//	vstat = constpart{}
+	// 3. make an auto pointer to array and allocate heap to it
+	//	var vauto *[...]t = new([...]t)
+	// 4. copy the static array to the auto array
+	//	*vauto = vstat
+	// 5. for each dynamic part assign to the array
+	//	vauto[i] = dynamic part
+	// 6. assign slice of allocated heap to var
+	//	var = vauto[:]
+	//
+	// an optimization is done if there is no constant part
+	//	3. var vauto *[...]t = new([...]t)
+	//	5. vauto[i] = dynamic part
+	//	6. var = vauto[:]
+
+	// if the literal contains constants,
+	// make static initialized array (1),(2)
+	var vstat ir.Node
+
+	mode := getdyn(n, true)
+	if mode&initConst != 0 && !isSmallSliceLit(n) {
+		if ctxt == inInitFunction {
+			vstat = readonlystaticname(t)
+		} else {
+			vstat = staticinit.StaticName(t)
+		}
+		fixedlit(ctxt, initKindStatic, n, vstat, init)
+	}
+
+	// make new auto *array (3 declare)
+	vauto := typecheck.Temp(types.NewPtr(t))
+
+	// set auto to point at new temp or heap (3 assign)
+	var a ir.Node
+	if x := n.Prealloc; x != nil {
+		// temp allocated during order.go for dddarg
+		if !types.Identical(t, x.Type()) {
+			panic("dotdotdot base type does not match order's assigned type")
+		}
+		a = initStackTemp(init, x, vstat)
+	} else if n.Esc() == ir.EscNone {
+		a = initStackTemp(init, typecheck.Temp(t), vstat)
+	} else {
+		a = ir.NewUnaryExpr(base.Pos, ir.ONEW, ir.TypeNode(t))
+	}
+	appendWalkStmt(init, ir.NewAssignStmt(base.Pos, vauto, a))
+
+	if vstat != nil && n.Prealloc == nil && n.Esc() != ir.EscNone {
+		// If we allocated on the heap with ONEW, copy the static to the
+		// heap (4). We skip this for stack temporaries, because
+		// initStackTemp already handled the copy.
+		a = ir.NewStarExpr(base.Pos, vauto)
+		appendWalkStmt(init, ir.NewAssignStmt(base.Pos, a, vstat))
+	}
+
+	// put dynamics into array (5)
+	var index int64
+	for _, value := range n.List {
+		if value.Op() == ir.OKEY {
+			kv := value.(*ir.KeyExpr)
+			index = typecheck.IndexConst(kv.Key)
+			if index < 0 {
+				base.Fatalf("slicelit: invalid index %v", kv.Key)
+			}
+			value = kv.Value
+		}
+		a := ir.NewIndexExpr(base.Pos, vauto, ir.NewInt(index))
+		a.SetBounded(true)
+		index++
+
+		// TODO need to check bounds?
+
+		switch value.Op() {
+		case ir.OSLICELIT:
+			break
+
+		case ir.OARRAYLIT, ir.OSTRUCTLIT:
+			value := value.(*ir.CompLitExpr)
+			k := initKindDynamic
+			if vstat == nil {
+				// Generate both static and dynamic initializations.
+				// See issue #31987.
+				k = initKindLocalCode
+			}
+			fixedlit(ctxt, k, value, a, init)
+			continue
+		}
+
+		if vstat != nil && ir.IsConstNode(value) { // already set by copy from static value
+			continue
+		}
+
+		// build list of vauto[c] = expr
+		ir.SetPos(value)
+		as := typecheck.Stmt(ir.NewAssignStmt(base.Pos, a, value))
+		as = orderStmtInPlace(as, map[string][]*ir.Name{})
+		as = walkStmt(as)
+		init.Append(as)
+	}
+
+	// make slice out of heap (6)
+	a = ir.NewAssignStmt(base.Pos, var_, ir.NewSliceExpr(base.Pos, ir.OSLICE, vauto, nil, nil, nil))
+
+	a = typecheck.Stmt(a)
+	a = orderStmtInPlace(a, map[string][]*ir.Name{})
+	a = walkStmt(a)
+	init.Append(a)
+}
+
+func maplit(n *ir.CompLitExpr, m ir.Node, init *ir.Nodes) {
+	// make the map var
+	a := ir.NewCallExpr(base.Pos, ir.OMAKE, nil, nil)
+	a.SetEsc(n.Esc())
+	a.Args = []ir.Node{ir.TypeNode(n.Type()), ir.NewInt(int64(len(n.List)))}
+	litas(m, a, init)
+
+	entries := n.List
+
+	// The order pass already removed any dynamic (runtime-computed) entries.
+	// All remaining entries are static. Double-check that.
+	for _, r := range entries {
+		r := r.(*ir.KeyExpr)
+		if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
+			base.Fatalf("maplit: entry is not a literal: %v", r)
+		}
+	}
+
+	if len(entries) > 25 {
+		// For a large number of entries, put them in an array and loop.
+
+		// build types [count]Tindex and [count]Tvalue
+		tk := types.NewArray(n.Type().Key(), int64(len(entries)))
+		te := types.NewArray(n.Type().Elem(), int64(len(entries)))
+
+		tk.SetNoalg(true)
+		te.SetNoalg(true)
+
+		types.CalcSize(tk)
+		types.CalcSize(te)
+
+		// make and initialize static arrays
+		vstatk := readonlystaticname(tk)
+		vstate := readonlystaticname(te)
+
+		datak := ir.NewCompLitExpr(base.Pos, ir.OARRAYLIT, nil, nil)
+		datae := ir.NewCompLitExpr(base.Pos, ir.OARRAYLIT, nil, nil)
+		for _, r := range entries {
+			r := r.(*ir.KeyExpr)
+			datak.List.Append(r.Key)
+			datae.List.Append(r.Value)
+		}
+		fixedlit(inInitFunction, initKindStatic, datak, vstatk, init)
+		fixedlit(inInitFunction, initKindStatic, datae, vstate, init)
+
+		// loop adding structure elements to map
+		// for i = 0; i < len(vstatk); i++ {
+		//	map[vstatk[i]] = vstate[i]
+		// }
+		i := typecheck.Temp(types.Types[types.TINT])
+		rhs := ir.NewIndexExpr(base.Pos, vstate, i)
+		rhs.SetBounded(true)
+
+		kidx := ir.NewIndexExpr(base.Pos, vstatk, i)
+		kidx.SetBounded(true)
+		lhs := ir.NewIndexExpr(base.Pos, m, kidx)
+
+		zero := ir.NewAssignStmt(base.Pos, i, ir.NewInt(0))
+		cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, ir.NewInt(tk.NumElem()))
+		incr := ir.NewAssignStmt(base.Pos, i, ir.NewBinaryExpr(base.Pos, ir.OADD, i, ir.NewInt(1)))
+
+		var body ir.Node = ir.NewAssignStmt(base.Pos, lhs, rhs)
+		body = typecheck.Stmt(body) // typechecker rewrites OINDEX to OINDEXMAP
+		body = orderStmtInPlace(body, map[string][]*ir.Name{})
+
+		loop := ir.NewForStmt(base.Pos, nil, cond, incr, nil)
+		loop.Body = []ir.Node{body}
+		*loop.PtrInit() = []ir.Node{zero}
+
+		appendWalkStmt(init, loop)
+		return
+	}
+	// For a small number of entries, just add them directly.
+
+	// Build list of var[c] = expr.
+	// Use temporaries so that mapassign1 can have addressable key, elem.
+	// TODO(josharian): avoid map key temporaries for mapfast_* assignments with literal keys.
+	tmpkey := typecheck.Temp(m.Type().Key())
+	tmpelem := typecheck.Temp(m.Type().Elem())
+
+	for _, r := range entries {
+		r := r.(*ir.KeyExpr)
+		index, elem := r.Key, r.Value
+
+		ir.SetPos(index)
+		appendWalkStmt(init, ir.NewAssignStmt(base.Pos, tmpkey, index))
+
+		ir.SetPos(elem)
+		appendWalkStmt(init, ir.NewAssignStmt(base.Pos, tmpelem, elem))
+
+		ir.SetPos(tmpelem)
+		var a ir.Node = ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, tmpkey), tmpelem)
+		a = typecheck.Stmt(a) // typechecker rewrites OINDEX to OINDEXMAP
+		a = orderStmtInPlace(a, map[string][]*ir.Name{})
+		appendWalkStmt(init, a)
+	}
+
+	appendWalkStmt(init, ir.NewUnaryExpr(base.Pos, ir.OVARKILL, tmpkey))
+	appendWalkStmt(init, ir.NewUnaryExpr(base.Pos, ir.OVARKILL, tmpelem))
+}
+
+func anylit(n ir.Node, var_ ir.Node, init *ir.Nodes) {
+	t := n.Type()
+	switch n.Op() {
+	default:
+		base.Fatalf("anylit: not lit, op=%v node=%v", n.Op(), n)
+
+	case ir.ONAME:
+		n := n.(*ir.Name)
+		appendWalkStmt(init, ir.NewAssignStmt(base.Pos, var_, n))
+
+	case ir.OMETHEXPR:
+		n := n.(*ir.SelectorExpr)
+		anylit(n.FuncName(), var_, init)
+
+	case ir.OPTRLIT:
+		n := n.(*ir.AddrExpr)
+		if !t.IsPtr() {
+			base.Fatalf("anylit: not ptr")
+		}
+
+		var r ir.Node
+		if n.Prealloc != nil {
+			// n.Prealloc is stack temporary used as backing store.
+			r = initStackTemp(init, n.Prealloc, nil)
+		} else {
+			r = ir.NewUnaryExpr(base.Pos, ir.ONEW, ir.TypeNode(n.X.Type()))
+			r.SetEsc(n.Esc())
+		}
+		appendWalkStmt(init, ir.NewAssignStmt(base.Pos, var_, r))
+
+		var_ = ir.NewStarExpr(base.Pos, var_)
+		var_ = typecheck.AssignExpr(var_)
+		anylit(n.X, var_, init)
+
+	case ir.OSTRUCTLIT, ir.OARRAYLIT:
+		n := n.(*ir.CompLitExpr)
+		if !t.IsStruct() && !t.IsArray() {
+			base.Fatalf("anylit: not struct/array")
+		}
+
+		if isSimpleName(var_) && len(n.List) > 4 {
+			// lay out static data
+			vstat := readonlystaticname(t)
+
+			ctxt := inInitFunction
+			if n.Op() == ir.OARRAYLIT {
+				ctxt = inNonInitFunction
+			}
+			fixedlit(ctxt, initKindStatic, n, vstat, init)
+
+			// copy static to var
+			appendWalkStmt(init, ir.NewAssignStmt(base.Pos, var_, vstat))
+
+			// add expressions to automatic
+			fixedlit(inInitFunction, initKindDynamic, n, var_, init)
+			break
+		}
+
+		var components int64
+		if n.Op() == ir.OARRAYLIT {
+			components = t.NumElem()
+		} else {
+			components = int64(t.NumFields())
+		}
+		// initialization of an array or struct with unspecified components (missing fields or arrays)
+		if isSimpleName(var_) || int64(len(n.List)) < components {
+			appendWalkStmt(init, ir.NewAssignStmt(base.Pos, var_, nil))
+		}
+
+		fixedlit(inInitFunction, initKindLocalCode, n, var_, init)
+
+	case ir.OSLICELIT:
+		n := n.(*ir.CompLitExpr)
+		slicelit(inInitFunction, n, var_, init)
+
+	case ir.OMAPLIT:
+		n := n.(*ir.CompLitExpr)
+		if !t.IsMap() {
+			base.Fatalf("anylit: not map")
+		}
+		maplit(n, var_, init)
+	}
+}
+
+// oaslit handles special composite literal assignments.
+// It returns true if n's effects have been added to init,
+// in which case n should be dropped from the program by the caller.
+func oaslit(n *ir.AssignStmt, init *ir.Nodes) bool {
+	if n.X == nil || n.Y == nil {
+		// not a special composite literal assignment
+		return false
+	}
+	if n.X.Type() == nil || n.Y.Type() == nil {
+		// not a special composite literal assignment
+		return false
+	}
+	if !isSimpleName(n.X) {
+		// not a special composite literal assignment
+		return false
+	}
+	x := n.X.(*ir.Name)
+	if !types.Identical(n.X.Type(), n.Y.Type()) {
+		// not a special composite literal assignment
+		return false
+	}
+
+	switch n.Y.Op() {
+	default:
+		// not a special composite literal assignment
+		return false
+
+	case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
+		if ir.Any(n.Y, func(y ir.Node) bool { return ir.Uses(y, x) }) {
+			// not a special composite literal assignment
+			return false
+		}
+		anylit(n.Y, n.X, init)
+	}
+
+	return true
+}
+
+func genAsStatic(as *ir.AssignStmt) {
+	if as.X.Type() == nil {
+		base.Fatalf("genAsStatic as.Left not typechecked")
+	}
+
+	name, offset, ok := staticinit.StaticLoc(as.X)
+	if !ok || (name.Class != ir.PEXTERN && as.X != ir.BlankNode) {
+		base.Fatalf("genAsStatic: lhs %v", as.X)
+	}
+
+	switch r := as.Y; r.Op() {
+	case ir.OLITERAL:
+		staticdata.InitConst(name, offset, r, int(r.Type().Width))
+		return
+	case ir.OMETHEXPR:
+		r := r.(*ir.SelectorExpr)
+		staticdata.InitAddr(name, offset, staticdata.FuncLinksym(r.FuncName()))
+		return
+	case ir.ONAME:
+		r := r.(*ir.Name)
+		if r.Offset_ != 0 {
+			base.Fatalf("genAsStatic %+v", as)
+		}
+		if r.Class == ir.PFUNC {
+			staticdata.InitAddr(name, offset, staticdata.FuncLinksym(r))
+			return
+		}
+	}
+	base.Fatalf("genAsStatic: rhs %v", as.Y)
+}
diff --git a/src/cmd/compile/internal/walk/convert.go b/src/cmd/compile/internal/walk/convert.go
new file mode 100644
index 0000000..26e17a1
--- /dev/null
+++ b/src/cmd/compile/internal/walk/convert.go
@@ -0,0 +1,510 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"encoding/binary"
+	"go/constant"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/ssagen"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/sys"
+)
+
+// walkConv walks an OCONV or OCONVNOP (but not OCONVIFACE) node.
+func walkConv(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+	n.X = walkExpr(n.X, init)
+	if n.Op() == ir.OCONVNOP && n.Type() == n.X.Type() {
+		return n.X
+	}
+	if n.Op() == ir.OCONVNOP && ir.ShouldCheckPtr(ir.CurFunc, 1) {
+		if n.Type().IsPtr() && n.X.Type().IsUnsafePtr() { // unsafe.Pointer to *T
+			return walkCheckPtrAlignment(n, init, nil)
+		}
+		if n.Type().IsUnsafePtr() && n.X.Type().IsUintptr() { // uintptr to unsafe.Pointer
+			return walkCheckPtrArithmetic(n, init)
+		}
+	}
+	param, result := rtconvfn(n.X.Type(), n.Type())
+	if param == types.Txxx {
+		return n
+	}
+	fn := types.BasicTypeNames[param] + "to" + types.BasicTypeNames[result]
+	return typecheck.Conv(mkcall(fn, types.Types[result], init, typecheck.Conv(n.X, types.Types[param])), n.Type())
+}
+
+// walkConvInterface walks an OCONVIFACE node.
+func walkConvInterface(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+	n.X = walkExpr(n.X, init)
+
+	fromType := n.X.Type()
+	toType := n.Type()
+
+	if !fromType.IsInterface() && !ir.IsBlank(ir.CurFunc.Nname) { // skip unnamed functions (func _())
+		reflectdata.MarkTypeUsedInInterface(fromType, ir.CurFunc.LSym)
+	}
+
+	// typeword generates the type word of the interface value.
+	typeword := func() ir.Node {
+		if toType.IsEmptyInterface() {
+			return reflectdata.TypePtr(fromType)
+		}
+		return reflectdata.ITabAddr(fromType, toType)
+	}
+
+	// Optimize convT2E or convT2I as a two-word copy when T is pointer-shaped.
+	if types.IsDirectIface(fromType) {
+		l := ir.NewBinaryExpr(base.Pos, ir.OEFACE, typeword(), n.X)
+		l.SetType(toType)
+		l.SetTypecheck(n.Typecheck())
+		return l
+	}
+
+	// Optimize convT2{E,I} for many cases in which T is not pointer-shaped,
+	// by using an existing addressable value identical to n.Left
+	// or creating one on the stack.
+	var value ir.Node
+	switch {
+	case fromType.Size() == 0:
+		// n.Left is zero-sized. Use zerobase.
+		cheapExpr(n.X, init) // Evaluate n.Left for side-effects. See issue 19246.
+		value = ir.NewLinksymExpr(base.Pos, ir.Syms.Zerobase, types.Types[types.TUINTPTR])
+	case fromType.IsBoolean() || (fromType.Size() == 1 && fromType.IsInteger()):
+		// n.Left is a bool/byte. Use staticuint64s[n.Left * 8] on little-endian
+		// and staticuint64s[n.Left * 8 + 7] on big-endian.
+		n.X = cheapExpr(n.X, init)
+		// byteindex widens n.Left so that the multiplication doesn't overflow.
+		index := ir.NewBinaryExpr(base.Pos, ir.OLSH, byteindex(n.X), ir.NewInt(3))
+		if ssagen.Arch.LinkArch.ByteOrder == binary.BigEndian {
+			index = ir.NewBinaryExpr(base.Pos, ir.OADD, index, ir.NewInt(7))
+		}
+		// The actual type is [256]uint64, but we use [256*8]uint8 so we can address
+		// individual bytes.
+		staticuint64s := ir.NewLinksymExpr(base.Pos, ir.Syms.Staticuint64s, types.NewArray(types.Types[types.TUINT8], 256*8))
+		xe := ir.NewIndexExpr(base.Pos, staticuint64s, index)
+		xe.SetBounded(true)
+		value = xe
+	case n.X.Op() == ir.ONAME && n.X.(*ir.Name).Class == ir.PEXTERN && n.X.(*ir.Name).Readonly():
+		// n.Left is a readonly global; use it directly.
+		value = n.X
+	case !fromType.IsInterface() && n.Esc() == ir.EscNone && fromType.Width <= 1024:
+		// n.Left does not escape. Use a stack temporary initialized to n.Left.
+		value = typecheck.Temp(fromType)
+		init.Append(typecheck.Stmt(ir.NewAssignStmt(base.Pos, value, n.X)))
+	}
+
+	if value != nil {
+		// Value is identical to n.Left.
+		// Construct the interface directly: {type/itab, &value}.
+		l := ir.NewBinaryExpr(base.Pos, ir.OEFACE, typeword(), typecheck.Expr(typecheck.NodAddr(value)))
+		l.SetType(toType)
+		l.SetTypecheck(n.Typecheck())
+		return l
+	}
+
+	// Implement interface to empty interface conversion.
+	// tmp = i.itab
+	// if tmp != nil {
+	//    tmp = tmp.type
+	// }
+	// e = iface{tmp, i.data}
+	if toType.IsEmptyInterface() && fromType.IsInterface() && !fromType.IsEmptyInterface() {
+		// Evaluate the input interface.
+		c := typecheck.Temp(fromType)
+		init.Append(ir.NewAssignStmt(base.Pos, c, n.X))
+
+		// Get the itab out of the interface.
+		tmp := typecheck.Temp(types.NewPtr(types.Types[types.TUINT8]))
+		init.Append(ir.NewAssignStmt(base.Pos, tmp, typecheck.Expr(ir.NewUnaryExpr(base.Pos, ir.OITAB, c))))
+
+		// Get the type out of the itab.
+		nif := ir.NewIfStmt(base.Pos, typecheck.Expr(ir.NewBinaryExpr(base.Pos, ir.ONE, tmp, typecheck.NodNil())), nil, nil)
+		nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, tmp, itabType(tmp))}
+		init.Append(nif)
+
+		// Build the result.
+		e := ir.NewBinaryExpr(base.Pos, ir.OEFACE, tmp, ifaceData(n.Pos(), c, types.NewPtr(types.Types[types.TUINT8])))
+		e.SetType(toType) // assign type manually, typecheck doesn't understand OEFACE.
+		e.SetTypecheck(1)
+		return e
+	}
+
+	fnname, argType, needsaddr := convFuncName(fromType, toType)
+
+	if !needsaddr && !fromType.IsInterface() {
+		// Use a specialized conversion routine that only returns a data pointer.
+		// ptr = convT2X(val)
+		// e = iface{typ/tab, ptr}
+		fn := typecheck.LookupRuntime(fnname)
+		types.CalcSize(fromType)
+
+		arg := n.X
+		switch {
+		case fromType == argType:
+			// already in the right type, nothing to do
+		case fromType.Kind() == argType.Kind(),
+			fromType.IsPtrShaped() && argType.IsPtrShaped():
+			// can directly convert (e.g. named type to underlying type, or one pointer to another)
+			arg = ir.NewConvExpr(n.Pos(), ir.OCONVNOP, argType, arg)
+		case fromType.IsInteger() && argType.IsInteger():
+			// can directly convert (e.g. int32 to uint32)
+			arg = ir.NewConvExpr(n.Pos(), ir.OCONV, argType, arg)
+		default:
+			// unsafe cast through memory
+			arg = copyExpr(arg, arg.Type(), init)
+			var addr ir.Node = typecheck.NodAddr(arg)
+			addr = ir.NewConvExpr(n.Pos(), ir.OCONVNOP, argType.PtrTo(), addr)
+			arg = ir.NewStarExpr(n.Pos(), addr)
+			arg.SetType(argType)
+		}
+
+		call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, nil)
+		call.Args = []ir.Node{arg}
+		e := ir.NewBinaryExpr(base.Pos, ir.OEFACE, typeword(), safeExpr(walkExpr(typecheck.Expr(call), init), init))
+		e.SetType(toType)
+		e.SetTypecheck(1)
+		return e
+	}
+
+	var tab ir.Node
+	if fromType.IsInterface() {
+		// convI2I
+		tab = reflectdata.TypePtr(toType)
+	} else {
+		// convT2x
+		tab = typeword()
+	}
+
+	v := n.X
+	if needsaddr {
+		// Types of large or unknown size are passed by reference.
+		// Orderexpr arranged for n.Left to be a temporary for all
+		// the conversions it could see. Comparison of an interface
+		// with a non-interface, especially in a switch on interface value
+		// with non-interface cases, is not visible to order.stmt, so we
+		// have to fall back on allocating a temp here.
+		if !ir.IsAddressable(v) {
+			v = copyExpr(v, v.Type(), init)
+		}
+		v = typecheck.NodAddr(v)
+	}
+
+	types.CalcSize(fromType)
+	fn := typecheck.LookupRuntime(fnname)
+	fn = typecheck.SubstArgTypes(fn, fromType, toType)
+	types.CalcSize(fn.Type())
+	call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, nil)
+	call.Args = []ir.Node{tab, v}
+	return walkExpr(typecheck.Expr(call), init)
+}
+
+// walkBytesRunesToString walks an OBYTES2STR or ORUNES2STR node.
+func walkBytesRunesToString(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+	a := typecheck.NodNil()
+	if n.Esc() == ir.EscNone {
+		// Create temporary buffer for string on stack.
+		a = stackBufAddr(tmpstringbufsize, types.Types[types.TUINT8])
+	}
+	if n.Op() == ir.ORUNES2STR {
+		// slicerunetostring(*[32]byte, []rune) string
+		return mkcall("slicerunetostring", n.Type(), init, a, n.X)
+	}
+	// slicebytetostring(*[32]byte, ptr *byte, n int) string
+	n.X = cheapExpr(n.X, init)
+	ptr, len := backingArrayPtrLen(n.X)
+	return mkcall("slicebytetostring", n.Type(), init, a, ptr, len)
+}
+
+// walkBytesToStringTemp walks an OBYTES2STRTMP node.
+func walkBytesToStringTemp(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+	n.X = walkExpr(n.X, init)
+	if !base.Flag.Cfg.Instrumenting {
+		// Let the backend handle OBYTES2STRTMP directly
+		// to avoid a function call to slicebytetostringtmp.
+		return n
+	}
+	// slicebytetostringtmp(ptr *byte, n int) string
+	n.X = cheapExpr(n.X, init)
+	ptr, len := backingArrayPtrLen(n.X)
+	return mkcall("slicebytetostringtmp", n.Type(), init, ptr, len)
+}
+
+// walkRuneToString walks an ORUNESTR node.
+func walkRuneToString(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+	a := typecheck.NodNil()
+	if n.Esc() == ir.EscNone {
+		a = stackBufAddr(4, types.Types[types.TUINT8])
+	}
+	// intstring(*[4]byte, rune)
+	return mkcall("intstring", n.Type(), init, a, typecheck.Conv(n.X, types.Types[types.TINT64]))
+}
+
+// walkStringToBytes walks an OSTR2BYTES node.
+func walkStringToBytes(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+	s := n.X
+	if ir.IsConst(s, constant.String) {
+		sc := ir.StringVal(s)
+
+		// Allocate a [n]byte of the right size.
+		t := types.NewArray(types.Types[types.TUINT8], int64(len(sc)))
+		var a ir.Node
+		if n.Esc() == ir.EscNone && len(sc) <= int(ir.MaxImplicitStackVarSize) {
+			a = stackBufAddr(t.NumElem(), t.Elem())
+		} else {
+			types.CalcSize(t)
+			a = ir.NewUnaryExpr(base.Pos, ir.ONEW, nil)
+			a.SetType(types.NewPtr(t))
+			a.SetTypecheck(1)
+			a.MarkNonNil()
+		}
+		p := typecheck.Temp(t.PtrTo()) // *[n]byte
+		init.Append(typecheck.Stmt(ir.NewAssignStmt(base.Pos, p, a)))
+
+		// Copy from the static string data to the [n]byte.
+		if len(sc) > 0 {
+			as := ir.NewAssignStmt(base.Pos, ir.NewStarExpr(base.Pos, p), ir.NewStarExpr(base.Pos, typecheck.ConvNop(ir.NewUnaryExpr(base.Pos, ir.OSPTR, s), t.PtrTo())))
+			appendWalkStmt(init, as)
+		}
+
+		// Slice the [n]byte to a []byte.
+		slice := ir.NewSliceExpr(n.Pos(), ir.OSLICEARR, p, nil, nil, nil)
+		slice.SetType(n.Type())
+		slice.SetTypecheck(1)
+		return walkExpr(slice, init)
+	}
+
+	a := typecheck.NodNil()
+	if n.Esc() == ir.EscNone {
+		// Create temporary buffer for slice on stack.
+		a = stackBufAddr(tmpstringbufsize, types.Types[types.TUINT8])
+	}
+	// stringtoslicebyte(*32[byte], string) []byte
+	return mkcall("stringtoslicebyte", n.Type(), init, a, typecheck.Conv(s, types.Types[types.TSTRING]))
+}
+
+// walkStringToBytesTemp walks an OSTR2BYTESTMP node.
+func walkStringToBytesTemp(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+	// []byte(string) conversion that creates a slice
+	// referring to the actual string bytes.
+	// This conversion is handled later by the backend and
+	// is only for use by internal compiler optimizations
+	// that know that the slice won't be mutated.
+	// The only such case today is:
+	// for i, c := range []byte(string)
+	n.X = walkExpr(n.X, init)
+	return n
+}
+
+// walkStringToRunes walks an OSTR2RUNES node.
+func walkStringToRunes(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+	a := typecheck.NodNil()
+	if n.Esc() == ir.EscNone {
+		// Create temporary buffer for slice on stack.
+		a = stackBufAddr(tmpstringbufsize, types.Types[types.TINT32])
+	}
+	// stringtoslicerune(*[32]rune, string) []rune
+	return mkcall("stringtoslicerune", n.Type(), init, a, typecheck.Conv(n.X, types.Types[types.TSTRING]))
+}
+
+// convFuncName builds the runtime function name for interface conversion.
+// It also returns the argument type that the runtime function takes, and
+// whether the function expects the data by address.
+// Not all names are possible. For example, we never generate convE2E or convE2I.
+func convFuncName(from, to *types.Type) (fnname string, argType *types.Type, needsaddr bool) {
+	tkind := to.Tie()
+	switch from.Tie() {
+	case 'I':
+		if tkind == 'I' {
+			return "convI2I", types.Types[types.TINTER], false
+		}
+	case 'T':
+		switch {
+		case from.Size() == 2 && from.Align == 2:
+			return "convT16", types.Types[types.TUINT16], false
+		case from.Size() == 4 && from.Align == 4 && !from.HasPointers():
+			return "convT32", types.Types[types.TUINT32], false
+		case from.Size() == 8 && from.Align == types.Types[types.TUINT64].Align && !from.HasPointers():
+			return "convT64", types.Types[types.TUINT64], false
+		}
+		if sc := from.SoleComponent(); sc != nil {
+			switch {
+			case sc.IsString():
+				return "convTstring", types.Types[types.TSTRING], false
+			case sc.IsSlice():
+				return "convTslice", types.NewSlice(types.Types[types.TUINT8]), false // the element type doesn't matter
+			}
+		}
+
+		switch tkind {
+		case 'E':
+			if !from.HasPointers() {
+				return "convT2Enoptr", types.Types[types.TUNSAFEPTR], true
+			}
+			return "convT2E", types.Types[types.TUNSAFEPTR], true
+		case 'I':
+			if !from.HasPointers() {
+				return "convT2Inoptr", types.Types[types.TUNSAFEPTR], true
+			}
+			return "convT2I", types.Types[types.TUNSAFEPTR], true
+		}
+	}
+	base.Fatalf("unknown conv func %c2%c", from.Tie(), to.Tie())
+	panic("unreachable")
+}
+
+// rtconvfn returns the parameter and result types that will be used by a
+// runtime function to convert from type src to type dst. The runtime function
+// name can be derived from the names of the returned types.
+//
+// If no such function is necessary, it returns (Txxx, Txxx).
+func rtconvfn(src, dst *types.Type) (param, result types.Kind) {
+	if ssagen.Arch.SoftFloat {
+		return types.Txxx, types.Txxx
+	}
+
+	switch ssagen.Arch.LinkArch.Family {
+	case sys.ARM, sys.MIPS:
+		if src.IsFloat() {
+			switch dst.Kind() {
+			case types.TINT64, types.TUINT64:
+				return types.TFLOAT64, dst.Kind()
+			}
+		}
+		if dst.IsFloat() {
+			switch src.Kind() {
+			case types.TINT64, types.TUINT64:
+				return src.Kind(), types.TFLOAT64
+			}
+		}
+
+	case sys.I386:
+		if src.IsFloat() {
+			switch dst.Kind() {
+			case types.TINT64, types.TUINT64:
+				return types.TFLOAT64, dst.Kind()
+			case types.TUINT32, types.TUINT, types.TUINTPTR:
+				return types.TFLOAT64, types.TUINT32
+			}
+		}
+		if dst.IsFloat() {
+			switch src.Kind() {
+			case types.TINT64, types.TUINT64:
+				return src.Kind(), types.TFLOAT64
+			case types.TUINT32, types.TUINT, types.TUINTPTR:
+				return types.TUINT32, types.TFLOAT64
+			}
+		}
+	}
+	return types.Txxx, types.Txxx
+}
+
+// byteindex converts n, which is byte-sized, to an int used to index into an array.
+// We cannot use conv, because we allow converting bool to int here,
+// which is forbidden in user code.
+func byteindex(n ir.Node) ir.Node {
+	// We cannot convert from bool to int directly.
+	// While converting from int8 to int is possible, it would yield
+	// the wrong result for negative values.
+	// Reinterpreting the value as an unsigned byte solves both cases.
+	if !types.Identical(n.Type(), types.Types[types.TUINT8]) {
+		n = ir.NewConvExpr(base.Pos, ir.OCONV, nil, n)
+		n.SetType(types.Types[types.TUINT8])
+		n.SetTypecheck(1)
+	}
+	n = ir.NewConvExpr(base.Pos, ir.OCONV, nil, n)
+	n.SetType(types.Types[types.TINT])
+	n.SetTypecheck(1)
+	return n
+}
+
+func walkCheckPtrAlignment(n *ir.ConvExpr, init *ir.Nodes, count ir.Node) ir.Node {
+	if !n.Type().IsPtr() {
+		base.Fatalf("expected pointer type: %v", n.Type())
+	}
+	elem := n.Type().Elem()
+	if count != nil {
+		if !elem.IsArray() {
+			base.Fatalf("expected array type: %v", elem)
+		}
+		elem = elem.Elem()
+	}
+
+	size := elem.Size()
+	if elem.Alignment() == 1 && (size == 0 || size == 1 && count == nil) {
+		return n
+	}
+
+	if count == nil {
+		count = ir.NewInt(1)
+	}
+
+	n.X = cheapExpr(n.X, init)
+	init.Append(mkcall("checkptrAlignment", nil, init, typecheck.ConvNop(n.X, types.Types[types.TUNSAFEPTR]), reflectdata.TypePtr(elem), typecheck.Conv(count, types.Types[types.TUINTPTR])))
+	return n
+}
+
+func walkCheckPtrArithmetic(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+	// Calling cheapExpr(n, init) below leads to a recursive call to
+	// walkExpr, which leads us back here again. Use n.Checkptr to
+	// prevent infinite loops.
+	if n.CheckPtr() {
+		return n
+	}
+	n.SetCheckPtr(true)
+	defer n.SetCheckPtr(false)
+
+	// TODO(mdempsky): Make stricter. We only need to exempt
+	// reflect.Value.Pointer and reflect.Value.UnsafeAddr.
+	switch n.X.Op() {
+	case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
+		return n
+	}
+
+	if n.X.Op() == ir.ODOTPTR && ir.IsReflectHeaderDataField(n.X) {
+		return n
+	}
+
+	// Find original unsafe.Pointer operands involved in this
+	// arithmetic expression.
+	//
+	// "It is valid both to add and to subtract offsets from a
+	// pointer in this way. It is also valid to use &^ to round
+	// pointers, usually for alignment."
+	var originals []ir.Node
+	var walk func(n ir.Node)
+	walk = func(n ir.Node) {
+		switch n.Op() {
+		case ir.OADD:
+			n := n.(*ir.BinaryExpr)
+			walk(n.X)
+			walk(n.Y)
+		case ir.OSUB, ir.OANDNOT:
+			n := n.(*ir.BinaryExpr)
+			walk(n.X)
+		case ir.OCONVNOP:
+			n := n.(*ir.ConvExpr)
+			if n.X.Type().IsUnsafePtr() {
+				n.X = cheapExpr(n.X, init)
+				originals = append(originals, typecheck.ConvNop(n.X, types.Types[types.TUNSAFEPTR]))
+			}
+		}
+	}
+	walk(n.X)
+
+	cheap := cheapExpr(n, init)
+
+	slice := typecheck.MakeDotArgs(types.NewSlice(types.Types[types.TUNSAFEPTR]), originals)
+	slice.SetEsc(ir.EscNone)
+
+	init.Append(mkcall("checkptrArithmetic", nil, init, typecheck.ConvNop(cheap, types.Types[types.TUNSAFEPTR]), slice))
+	// TODO(khr): Mark backing store of slice as dead. This will allow us to reuse
+	// the backing store for multiple calls to checkptrArithmetic.
+
+	return cheap
+}
diff --git a/src/cmd/compile/internal/walk/expr.go b/src/cmd/compile/internal/walk/expr.go
new file mode 100644
index 0000000..2fb9077
--- /dev/null
+++ b/src/cmd/compile/internal/walk/expr.go
@@ -0,0 +1,1030 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"fmt"
+	"go/constant"
+	"internal/buildcfg"
+	"strings"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/staticdata"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+)
+
+// The result of walkExpr MUST be assigned back to n, e.g.
+// 	n.Left = walkExpr(n.Left, init)
+func walkExpr(n ir.Node, init *ir.Nodes) ir.Node {
+	if n == nil {
+		return n
+	}
+
+	if n, ok := n.(ir.InitNode); ok && init == n.PtrInit() {
+		// not okay to use n->ninit when walking n,
+		// because we might replace n with some other node
+		// and would lose the init list.
+		base.Fatalf("walkExpr init == &n->ninit")
+	}
+
+	if len(n.Init()) != 0 {
+		walkStmtList(n.Init())
+		init.Append(ir.TakeInit(n)...)
+	}
+
+	lno := ir.SetPos(n)
+
+	if base.Flag.LowerW > 1 {
+		ir.Dump("before walk expr", n)
+	}
+
+	if n.Typecheck() != 1 {
+		base.Fatalf("missed typecheck: %+v", n)
+	}
+
+	if n.Type().IsUntyped() {
+		base.Fatalf("expression has untyped type: %+v", n)
+	}
+
+	n = walkExpr1(n, init)
+
+	// Eagerly compute sizes of all expressions for the back end.
+	if typ := n.Type(); typ != nil && typ.Kind() != types.TBLANK && !typ.IsFuncArgStruct() {
+		types.CheckSize(typ)
+	}
+	if n, ok := n.(*ir.Name); ok && n.Heapaddr != nil {
+		types.CheckSize(n.Heapaddr.Type())
+	}
+	if ir.IsConst(n, constant.String) {
+		// Emit string symbol now to avoid emitting
+		// any concurrently during the backend.
+		_ = staticdata.StringSym(n.Pos(), constant.StringVal(n.Val()))
+	}
+
+	if base.Flag.LowerW != 0 && n != nil {
+		ir.Dump("after walk expr", n)
+	}
+
+	base.Pos = lno
+	return n
+}
+
+func walkExpr1(n ir.Node, init *ir.Nodes) ir.Node {
+	switch n.Op() {
+	default:
+		ir.Dump("walk", n)
+		base.Fatalf("walkExpr: switch 1 unknown op %+v", n.Op())
+		panic("unreachable")
+
+	case ir.ONONAME, ir.OGETG:
+		return n
+
+	case ir.OTYPE, ir.ONAME, ir.OLITERAL, ir.ONIL, ir.OLINKSYMOFFSET:
+		// TODO(mdempsky): Just return n; see discussion on CL 38655.
+		// Perhaps refactor to use Node.mayBeShared for these instead.
+		// If these return early, make sure to still call
+		// StringSym for constant strings.
+		return n
+
+	case ir.OMETHEXPR:
+		// TODO(mdempsky): Do this right after type checking.
+		n := n.(*ir.SelectorExpr)
+		return n.FuncName()
+
+	case ir.ONOT, ir.ONEG, ir.OPLUS, ir.OBITNOT, ir.OREAL, ir.OIMAG, ir.OSPTR, ir.OITAB, ir.OIDATA:
+		n := n.(*ir.UnaryExpr)
+		n.X = walkExpr(n.X, init)
+		return n
+
+	case ir.ODOTMETH, ir.ODOTINTER:
+		n := n.(*ir.SelectorExpr)
+		n.X = walkExpr(n.X, init)
+		return n
+
+	case ir.OADDR:
+		n := n.(*ir.AddrExpr)
+		n.X = walkExpr(n.X, init)
+		return n
+
+	case ir.ODEREF:
+		n := n.(*ir.StarExpr)
+		n.X = walkExpr(n.X, init)
+		return n
+
+	case ir.OEFACE, ir.OAND, ir.OANDNOT, ir.OSUB, ir.OMUL, ir.OADD, ir.OOR, ir.OXOR, ir.OLSH, ir.ORSH,
+		ir.OUNSAFEADD:
+		n := n.(*ir.BinaryExpr)
+		n.X = walkExpr(n.X, init)
+		n.Y = walkExpr(n.Y, init)
+		return n
+
+	case ir.OUNSAFESLICE:
+		n := n.(*ir.BinaryExpr)
+		return walkUnsafeSlice(n, init)
+
+	case ir.ODOT, ir.ODOTPTR:
+		n := n.(*ir.SelectorExpr)
+		return walkDot(n, init)
+
+	case ir.ODOTTYPE, ir.ODOTTYPE2:
+		n := n.(*ir.TypeAssertExpr)
+		return walkDotType(n, init)
+
+	case ir.OLEN, ir.OCAP:
+		n := n.(*ir.UnaryExpr)
+		return walkLenCap(n, init)
+
+	case ir.OCOMPLEX:
+		n := n.(*ir.BinaryExpr)
+		n.X = walkExpr(n.X, init)
+		n.Y = walkExpr(n.Y, init)
+		return n
+
+	case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
+		n := n.(*ir.BinaryExpr)
+		return walkCompare(n, init)
+
+	case ir.OANDAND, ir.OOROR:
+		n := n.(*ir.LogicalExpr)
+		return walkLogical(n, init)
+
+	case ir.OPRINT, ir.OPRINTN:
+		return walkPrint(n.(*ir.CallExpr), init)
+
+	case ir.OPANIC:
+		n := n.(*ir.UnaryExpr)
+		return mkcall("gopanic", nil, init, n.X)
+
+	case ir.ORECOVER:
+		return walkRecover(n.(*ir.CallExpr), init)
+
+	case ir.OCFUNC:
+		return n
+
+	case ir.OCALLINTER, ir.OCALLFUNC, ir.OCALLMETH:
+		n := n.(*ir.CallExpr)
+		return walkCall(n, init)
+
+	case ir.OAS, ir.OASOP:
+		return walkAssign(init, n)
+
+	case ir.OAS2:
+		n := n.(*ir.AssignListStmt)
+		return walkAssignList(init, n)
+
+	// a,b,... = fn()
+	case ir.OAS2FUNC:
+		n := n.(*ir.AssignListStmt)
+		return walkAssignFunc(init, n)
+
+	// x, y = <-c
+	// order.stmt made sure x is addressable or blank.
+	case ir.OAS2RECV:
+		n := n.(*ir.AssignListStmt)
+		return walkAssignRecv(init, n)
+
+	// a,b = m[i]
+	case ir.OAS2MAPR:
+		n := n.(*ir.AssignListStmt)
+		return walkAssignMapRead(init, n)
+
+	case ir.ODELETE:
+		n := n.(*ir.CallExpr)
+		return walkDelete(init, n)
+
+	case ir.OAS2DOTTYPE:
+		n := n.(*ir.AssignListStmt)
+		return walkAssignDotType(n, init)
+
+	case ir.OCONVIFACE:
+		n := n.(*ir.ConvExpr)
+		return walkConvInterface(n, init)
+
+	case ir.OCONV, ir.OCONVNOP:
+		n := n.(*ir.ConvExpr)
+		return walkConv(n, init)
+
+	case ir.OSLICE2ARRPTR:
+		n := n.(*ir.ConvExpr)
+		n.X = walkExpr(n.X, init)
+		return n
+
+	case ir.ODIV, ir.OMOD:
+		n := n.(*ir.BinaryExpr)
+		return walkDivMod(n, init)
+
+	case ir.OINDEX:
+		n := n.(*ir.IndexExpr)
+		return walkIndex(n, init)
+
+	case ir.OINDEXMAP:
+		n := n.(*ir.IndexExpr)
+		return walkIndexMap(n, init)
+
+	case ir.ORECV:
+		base.Fatalf("walkExpr ORECV") // should see inside OAS only
+		panic("unreachable")
+
+	case ir.OSLICEHEADER:
+		n := n.(*ir.SliceHeaderExpr)
+		return walkSliceHeader(n, init)
+
+	case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR:
+		n := n.(*ir.SliceExpr)
+		return walkSlice(n, init)
+
+	case ir.ONEW:
+		n := n.(*ir.UnaryExpr)
+		return walkNew(n, init)
+
+	case ir.OADDSTR:
+		return walkAddString(n.(*ir.AddStringExpr), init)
+
+	case ir.OAPPEND:
+		// order should make sure we only see OAS(node, OAPPEND), which we handle above.
+		base.Fatalf("append outside assignment")
+		panic("unreachable")
+
+	case ir.OCOPY:
+		return walkCopy(n.(*ir.BinaryExpr), init, base.Flag.Cfg.Instrumenting && !base.Flag.CompilingRuntime)
+
+	case ir.OCLOSE:
+		n := n.(*ir.UnaryExpr)
+		return walkClose(n, init)
+
+	case ir.OMAKECHAN:
+		n := n.(*ir.MakeExpr)
+		return walkMakeChan(n, init)
+
+	case ir.OMAKEMAP:
+		n := n.(*ir.MakeExpr)
+		return walkMakeMap(n, init)
+
+	case ir.OMAKESLICE:
+		n := n.(*ir.MakeExpr)
+		return walkMakeSlice(n, init)
+
+	case ir.OMAKESLICECOPY:
+		n := n.(*ir.MakeExpr)
+		return walkMakeSliceCopy(n, init)
+
+	case ir.ORUNESTR:
+		n := n.(*ir.ConvExpr)
+		return walkRuneToString(n, init)
+
+	case ir.OBYTES2STR, ir.ORUNES2STR:
+		n := n.(*ir.ConvExpr)
+		return walkBytesRunesToString(n, init)
+
+	case ir.OBYTES2STRTMP:
+		n := n.(*ir.ConvExpr)
+		return walkBytesToStringTemp(n, init)
+
+	case ir.OSTR2BYTES:
+		n := n.(*ir.ConvExpr)
+		return walkStringToBytes(n, init)
+
+	case ir.OSTR2BYTESTMP:
+		n := n.(*ir.ConvExpr)
+		return walkStringToBytesTemp(n, init)
+
+	case ir.OSTR2RUNES:
+		n := n.(*ir.ConvExpr)
+		return walkStringToRunes(n, init)
+
+	case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT, ir.OSTRUCTLIT, ir.OPTRLIT:
+		return walkCompLit(n, init)
+
+	case ir.OSEND:
+		n := n.(*ir.SendStmt)
+		return walkSend(n, init)
+
+	case ir.OCLOSURE:
+		return walkClosure(n.(*ir.ClosureExpr), init)
+
+	case ir.OCALLPART:
+		return walkCallPart(n.(*ir.SelectorExpr), init)
+	}
+
+	// No return! Each case must return (or panic),
+	// to avoid confusion about what gets returned
+	// in the presence of type assertions.
+}
+
+// walk the whole tree of the body of an
+// expression or simple statement.
+// the types expressions are calculated.
+// compile-time constants are evaluated.
+// complex side effects like statements are appended to init
+func walkExprList(s []ir.Node, init *ir.Nodes) {
+	for i := range s {
+		s[i] = walkExpr(s[i], init)
+	}
+}
+
+func walkExprListCheap(s []ir.Node, init *ir.Nodes) {
+	for i, n := range s {
+		s[i] = cheapExpr(n, init)
+		s[i] = walkExpr(s[i], init)
+	}
+}
+
+func walkExprListSafe(s []ir.Node, init *ir.Nodes) {
+	for i, n := range s {
+		s[i] = safeExpr(n, init)
+		s[i] = walkExpr(s[i], init)
+	}
+}
+
+// return side-effect free and cheap n, appending side effects to init.
+// result may not be assignable.
+func cheapExpr(n ir.Node, init *ir.Nodes) ir.Node {
+	switch n.Op() {
+	case ir.ONAME, ir.OLITERAL, ir.ONIL:
+		return n
+	}
+
+	return copyExpr(n, n.Type(), init)
+}
+
+// return side effect-free n, appending side effects to init.
+// result is assignable if n is.
+func safeExpr(n ir.Node, init *ir.Nodes) ir.Node {
+	if n == nil {
+		return nil
+	}
+
+	if len(n.Init()) != 0 {
+		walkStmtList(n.Init())
+		init.Append(ir.TakeInit(n)...)
+	}
+
+	switch n.Op() {
+	case ir.ONAME, ir.OLITERAL, ir.ONIL, ir.OLINKSYMOFFSET:
+		return n
+
+	case ir.OLEN, ir.OCAP:
+		n := n.(*ir.UnaryExpr)
+		l := safeExpr(n.X, init)
+		if l == n.X {
+			return n
+		}
+		a := ir.Copy(n).(*ir.UnaryExpr)
+		a.X = l
+		return walkExpr(typecheck.Expr(a), init)
+
+	case ir.ODOT, ir.ODOTPTR:
+		n := n.(*ir.SelectorExpr)
+		l := safeExpr(n.X, init)
+		if l == n.X {
+			return n
+		}
+		a := ir.Copy(n).(*ir.SelectorExpr)
+		a.X = l
+		return walkExpr(typecheck.Expr(a), init)
+
+	case ir.ODEREF:
+		n := n.(*ir.StarExpr)
+		l := safeExpr(n.X, init)
+		if l == n.X {
+			return n
+		}
+		a := ir.Copy(n).(*ir.StarExpr)
+		a.X = l
+		return walkExpr(typecheck.Expr(a), init)
+
+	case ir.OINDEX, ir.OINDEXMAP:
+		n := n.(*ir.IndexExpr)
+		l := safeExpr(n.X, init)
+		r := safeExpr(n.Index, init)
+		if l == n.X && r == n.Index {
+			return n
+		}
+		a := ir.Copy(n).(*ir.IndexExpr)
+		a.X = l
+		a.Index = r
+		return walkExpr(typecheck.Expr(a), init)
+
+	case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT:
+		n := n.(*ir.CompLitExpr)
+		if isStaticCompositeLiteral(n) {
+			return n
+		}
+	}
+
+	// make a copy; must not be used as an lvalue
+	if ir.IsAddressable(n) {
+		base.Fatalf("missing lvalue case in safeExpr: %v", n)
+	}
+	return cheapExpr(n, init)
+}
+
+func copyExpr(n ir.Node, t *types.Type, init *ir.Nodes) ir.Node {
+	l := typecheck.Temp(t)
+	appendWalkStmt(init, ir.NewAssignStmt(base.Pos, l, n))
+	return l
+}
+
+func walkAddString(n *ir.AddStringExpr, init *ir.Nodes) ir.Node {
+	c := len(n.List)
+
+	if c < 2 {
+		base.Fatalf("walkAddString count %d too small", c)
+	}
+
+	buf := typecheck.NodNil()
+	if n.Esc() == ir.EscNone {
+		sz := int64(0)
+		for _, n1 := range n.List {
+			if n1.Op() == ir.OLITERAL {
+				sz += int64(len(ir.StringVal(n1)))
+			}
+		}
+
+		// Don't allocate the buffer if the result won't fit.
+		if sz < tmpstringbufsize {
+			// Create temporary buffer for result string on stack.
+			buf = stackBufAddr(tmpstringbufsize, types.Types[types.TUINT8])
+		}
+	}
+
+	// build list of string arguments
+	args := []ir.Node{buf}
+	for _, n2 := range n.List {
+		args = append(args, typecheck.Conv(n2, types.Types[types.TSTRING]))
+	}
+
+	var fn string
+	if c <= 5 {
+		// small numbers of strings use direct runtime helpers.
+		// note: order.expr knows this cutoff too.
+		fn = fmt.Sprintf("concatstring%d", c)
+	} else {
+		// large numbers of strings are passed to the runtime as a slice.
+		fn = "concatstrings"
+
+		t := types.NewSlice(types.Types[types.TSTRING])
+		// args[1:] to skip buf arg
+		slice := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(t), args[1:])
+		slice.Prealloc = n.Prealloc
+		args = []ir.Node{buf, slice}
+		slice.SetEsc(ir.EscNone)
+	}
+
+	cat := typecheck.LookupRuntime(fn)
+	r := ir.NewCallExpr(base.Pos, ir.OCALL, cat, nil)
+	r.Args = args
+	r1 := typecheck.Expr(r)
+	r1 = walkExpr(r1, init)
+	r1.SetType(n.Type())
+
+	return r1
+}
+
+// walkCall walks an OCALLFUNC, OCALLINTER, or OCALLMETH node.
+func walkCall(n *ir.CallExpr, init *ir.Nodes) ir.Node {
+	if n.Op() == ir.OCALLINTER || n.Op() == ir.OCALLMETH {
+		// We expect both interface call reflect.Type.Method and concrete
+		// call reflect.(*rtype).Method.
+		usemethod(n)
+	}
+	if n.Op() == ir.OCALLINTER {
+		reflectdata.MarkUsedIfaceMethod(n)
+	}
+
+	if n.Op() == ir.OCALLFUNC && n.X.Op() == ir.OCLOSURE {
+		directClosureCall(n)
+	}
+
+	if isFuncPCIntrinsic(n) {
+		// For internal/abi.FuncPCABIxxx(fn), if fn is a defined function, rewrite
+		// it to the address of the function of the ABI fn is defined.
+		name := n.X.(*ir.Name).Sym().Name
+		arg := n.Args[0]
+		var wantABI obj.ABI
+		switch name {
+		case "FuncPCABI0":
+			wantABI = obj.ABI0
+		case "FuncPCABIInternal":
+			wantABI = obj.ABIInternal
+		}
+		if isIfaceOfFunc(arg) {
+			fn := arg.(*ir.ConvExpr).X.(*ir.Name)
+			abi := fn.Func.ABI
+			if abi != wantABI {
+				base.ErrorfAt(n.Pos(), "internal/abi.%s expects an %v function, %s is defined as %v", name, wantABI, fn.Sym().Name, abi)
+			}
+			var e ir.Node = ir.NewLinksymExpr(n.Pos(), fn.Sym().LinksymABI(abi), types.Types[types.TUINTPTR])
+			e = ir.NewAddrExpr(n.Pos(), e)
+			e.SetType(types.Types[types.TUINTPTR].PtrTo())
+			e = ir.NewConvExpr(n.Pos(), ir.OCONVNOP, n.Type(), e)
+			return e
+		}
+		// fn is not a defined function. It must be ABIInternal.
+		// Read the address from func value, i.e. *(*uintptr)(idata(fn)).
+		if wantABI != obj.ABIInternal {
+			base.ErrorfAt(n.Pos(), "internal/abi.%s does not accept func expression, which is ABIInternal", name)
+		}
+		arg = walkExpr(arg, init)
+		var e ir.Node = ir.NewUnaryExpr(n.Pos(), ir.OIDATA, arg)
+		e.SetType(n.Type().PtrTo())
+		e = ir.NewStarExpr(n.Pos(), e)
+		e.SetType(n.Type())
+		return e
+	}
+
+	walkCall1(n, init)
+	return n
+}
+
+func walkCall1(n *ir.CallExpr, init *ir.Nodes) {
+	if n.Walked() {
+		return // already walked
+	}
+	n.SetWalked(true)
+
+	// If this is a method call t.M(...),
+	// rewrite into a function call T.M(t, ...).
+	// TODO(mdempsky): Do this right after type checking.
+	if n.Op() == ir.OCALLMETH {
+		withRecv := make([]ir.Node, len(n.Args)+1)
+		dot := n.X.(*ir.SelectorExpr)
+		withRecv[0] = dot.X
+		copy(withRecv[1:], n.Args)
+		n.Args = withRecv
+
+		dot = ir.NewSelectorExpr(dot.Pos(), ir.OXDOT, ir.TypeNode(dot.X.Type()), dot.Selection.Sym)
+
+		n.SetOp(ir.OCALLFUNC)
+		n.X = typecheck.Expr(dot)
+	}
+
+	args := n.Args
+	params := n.X.Type().Params()
+
+	n.X = walkExpr(n.X, init)
+	walkExprList(args, init)
+
+	for i, arg := range args {
+		// Validate argument and parameter types match.
+		param := params.Field(i)
+		if !types.Identical(arg.Type(), param.Type) {
+			base.FatalfAt(n.Pos(), "assigning %L to parameter %v (type %v)", arg, param.Sym, param.Type)
+		}
+
+		// For any argument whose evaluation might require a function call,
+		// store that argument into a temporary variable,
+		// to prevent that calls from clobbering arguments already on the stack.
+		if mayCall(arg) {
+			// assignment of arg to Temp
+			tmp := typecheck.Temp(param.Type)
+			init.Append(convas(typecheck.Stmt(ir.NewAssignStmt(base.Pos, tmp, arg)).(*ir.AssignStmt), init))
+			// replace arg with temp
+			args[i] = tmp
+		}
+	}
+
+	n.Args = args
+}
+
+// walkDivMod walks an ODIV or OMOD node.
+func walkDivMod(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
+	n.X = walkExpr(n.X, init)
+	n.Y = walkExpr(n.Y, init)
+
+	// rewrite complex div into function call.
+	et := n.X.Type().Kind()
+
+	if types.IsComplex[et] && n.Op() == ir.ODIV {
+		t := n.Type()
+		call := mkcall("complex128div", types.Types[types.TCOMPLEX128], init, typecheck.Conv(n.X, types.Types[types.TCOMPLEX128]), typecheck.Conv(n.Y, types.Types[types.TCOMPLEX128]))
+		return typecheck.Conv(call, t)
+	}
+
+	// Nothing to do for float divisions.
+	if types.IsFloat[et] {
+		return n
+	}
+
+	// rewrite 64-bit div and mod on 32-bit architectures.
+	// TODO: Remove this code once we can introduce
+	// runtime calls late in SSA processing.
+	if types.RegSize < 8 && (et == types.TINT64 || et == types.TUINT64) {
+		if n.Y.Op() == ir.OLITERAL {
+			// Leave div/mod by constant powers of 2 or small 16-bit constants.
+			// The SSA backend will handle those.
+			switch et {
+			case types.TINT64:
+				c := ir.Int64Val(n.Y)
+				if c < 0 {
+					c = -c
+				}
+				if c != 0 && c&(c-1) == 0 {
+					return n
+				}
+			case types.TUINT64:
+				c := ir.Uint64Val(n.Y)
+				if c < 1<<16 {
+					return n
+				}
+				if c != 0 && c&(c-1) == 0 {
+					return n
+				}
+			}
+		}
+		var fn string
+		if et == types.TINT64 {
+			fn = "int64"
+		} else {
+			fn = "uint64"
+		}
+		if n.Op() == ir.ODIV {
+			fn += "div"
+		} else {
+			fn += "mod"
+		}
+		return mkcall(fn, n.Type(), init, typecheck.Conv(n.X, types.Types[et]), typecheck.Conv(n.Y, types.Types[et]))
+	}
+	return n
+}
+
+// walkDot walks an ODOT or ODOTPTR node.
+func walkDot(n *ir.SelectorExpr, init *ir.Nodes) ir.Node {
+	usefield(n)
+	n.X = walkExpr(n.X, init)
+	return n
+}
+
+// walkDotType walks an ODOTTYPE or ODOTTYPE2 node.
+func walkDotType(n *ir.TypeAssertExpr, init *ir.Nodes) ir.Node {
+	n.X = walkExpr(n.X, init)
+	// Set up interface type addresses for back end.
+	if !n.Type().IsInterface() && !n.X.Type().IsEmptyInterface() {
+		n.Itab = reflectdata.ITabAddr(n.Type(), n.X.Type())
+	}
+	return n
+}
+
+// walkIndex walks an OINDEX node.
+func walkIndex(n *ir.IndexExpr, init *ir.Nodes) ir.Node {
+	n.X = walkExpr(n.X, init)
+
+	// save the original node for bounds checking elision.
+	// If it was a ODIV/OMOD walk might rewrite it.
+	r := n.Index
+
+	n.Index = walkExpr(n.Index, init)
+
+	// if range of type cannot exceed static array bound,
+	// disable bounds check.
+	if n.Bounded() {
+		return n
+	}
+	t := n.X.Type()
+	if t != nil && t.IsPtr() {
+		t = t.Elem()
+	}
+	if t.IsArray() {
+		n.SetBounded(bounded(r, t.NumElem()))
+		if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Index, constant.Int) {
+			base.Warn("index bounds check elided")
+		}
+		if ir.IsSmallIntConst(n.Index) && !n.Bounded() {
+			base.Errorf("index out of bounds")
+		}
+	} else if ir.IsConst(n.X, constant.String) {
+		n.SetBounded(bounded(r, int64(len(ir.StringVal(n.X)))))
+		if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Index, constant.Int) {
+			base.Warn("index bounds check elided")
+		}
+		if ir.IsSmallIntConst(n.Index) && !n.Bounded() {
+			base.Errorf("index out of bounds")
+		}
+	}
+
+	if ir.IsConst(n.Index, constant.Int) {
+		if v := n.Index.Val(); constant.Sign(v) < 0 || ir.ConstOverflow(v, types.Types[types.TINT]) {
+			base.Errorf("index out of bounds")
+		}
+	}
+	return n
+}
+
+// mapKeyArg returns an expression for key that is suitable to be passed
+// as the key argument for mapaccess and mapdelete functions.
+// n is is the map indexing or delete Node (to provide Pos).
+// Note: this is not used for mapassign, which does distinguish pointer vs.
+// integer key.
+func mapKeyArg(fast int, n, key ir.Node) ir.Node {
+	switch fast {
+	case mapslow:
+		// standard version takes key by reference.
+		// order.expr made sure key is addressable.
+		return typecheck.NodAddr(key)
+	case mapfast32ptr:
+		// mapaccess and mapdelete don't distinguish pointer vs. integer key.
+		return ir.NewConvExpr(n.Pos(), ir.OCONVNOP, types.Types[types.TUINT32], key)
+	case mapfast64ptr:
+		// mapaccess and mapdelete don't distinguish pointer vs. integer key.
+		return ir.NewConvExpr(n.Pos(), ir.OCONVNOP, types.Types[types.TUINT64], key)
+	default:
+		// fast version takes key by value.
+		return key
+	}
+}
+
+// walkIndexMap walks an OINDEXMAP node.
+func walkIndexMap(n *ir.IndexExpr, init *ir.Nodes) ir.Node {
+	// Replace m[k] with *map{access1,assign}(maptype, m, &k)
+	n.X = walkExpr(n.X, init)
+	n.Index = walkExpr(n.Index, init)
+	map_ := n.X
+	key := n.Index
+	t := map_.Type()
+	var call *ir.CallExpr
+	if n.Assigned {
+		// This m[k] expression is on the left-hand side of an assignment.
+		fast := mapfast(t)
+		if fast == mapslow {
+			// standard version takes key by reference.
+			// order.expr made sure key is addressable.
+			key = typecheck.NodAddr(key)
+		}
+		call = mkcall1(mapfn(mapassign[fast], t, false), nil, init, reflectdata.TypePtr(t), map_, key)
+	} else {
+		// m[k] is not the target of an assignment.
+		fast := mapfast(t)
+		key = mapKeyArg(fast, n, key)
+		if w := t.Elem().Width; w <= zeroValSize {
+			call = mkcall1(mapfn(mapaccess1[fast], t, false), types.NewPtr(t.Elem()), init, reflectdata.TypePtr(t), map_, key)
+		} else {
+			z := reflectdata.ZeroAddr(w)
+			call = mkcall1(mapfn("mapaccess1_fat", t, true), types.NewPtr(t.Elem()), init, reflectdata.TypePtr(t), map_, key, z)
+		}
+	}
+	call.SetType(types.NewPtr(t.Elem()))
+	call.MarkNonNil() // mapaccess1* and mapassign always return non-nil pointers.
+	star := ir.NewStarExpr(base.Pos, call)
+	star.SetType(t.Elem())
+	star.SetTypecheck(1)
+	return star
+}
+
+// walkLogical walks an OANDAND or OOROR node.
+func walkLogical(n *ir.LogicalExpr, init *ir.Nodes) ir.Node {
+	n.X = walkExpr(n.X, init)
+
+	// cannot put side effects from n.Right on init,
+	// because they cannot run before n.Left is checked.
+	// save elsewhere and store on the eventual n.Right.
+	var ll ir.Nodes
+
+	n.Y = walkExpr(n.Y, &ll)
+	n.Y = ir.InitExpr(ll, n.Y)
+	return n
+}
+
+// walkSend walks an OSEND node.
+func walkSend(n *ir.SendStmt, init *ir.Nodes) ir.Node {
+	n1 := n.Value
+	n1 = typecheck.AssignConv(n1, n.Chan.Type().Elem(), "chan send")
+	n1 = walkExpr(n1, init)
+	n1 = typecheck.NodAddr(n1)
+	return mkcall1(chanfn("chansend1", 2, n.Chan.Type()), nil, init, n.Chan, n1)
+}
+
+// walkSlice walks an OSLICE, OSLICEARR, OSLICESTR, OSLICE3, or OSLICE3ARR node.
+func walkSlice(n *ir.SliceExpr, init *ir.Nodes) ir.Node {
+
+	checkSlice := ir.ShouldCheckPtr(ir.CurFunc, 1) && n.Op() == ir.OSLICE3ARR && n.X.Op() == ir.OCONVNOP && n.X.(*ir.ConvExpr).X.Type().IsUnsafePtr()
+	if checkSlice {
+		conv := n.X.(*ir.ConvExpr)
+		conv.X = walkExpr(conv.X, init)
+	} else {
+		n.X = walkExpr(n.X, init)
+	}
+
+	n.Low = walkExpr(n.Low, init)
+	if n.Low != nil && ir.IsZero(n.Low) {
+		// Reduce x[0:j] to x[:j] and x[0:j:k] to x[:j:k].
+		n.Low = nil
+	}
+	n.High = walkExpr(n.High, init)
+	n.Max = walkExpr(n.Max, init)
+	if checkSlice {
+		n.X = walkCheckPtrAlignment(n.X.(*ir.ConvExpr), init, n.Max)
+	}
+
+	if n.Op().IsSlice3() {
+		if n.Max != nil && n.Max.Op() == ir.OCAP && ir.SameSafeExpr(n.X, n.Max.(*ir.UnaryExpr).X) {
+			// Reduce x[i:j:cap(x)] to x[i:j].
+			if n.Op() == ir.OSLICE3 {
+				n.SetOp(ir.OSLICE)
+			} else {
+				n.SetOp(ir.OSLICEARR)
+			}
+			return reduceSlice(n)
+		}
+		return n
+	}
+	return reduceSlice(n)
+}
+
+// walkSliceHeader walks an OSLICEHEADER node.
+func walkSliceHeader(n *ir.SliceHeaderExpr, init *ir.Nodes) ir.Node {
+	n.Ptr = walkExpr(n.Ptr, init)
+	n.Len = walkExpr(n.Len, init)
+	n.Cap = walkExpr(n.Cap, init)
+	return n
+}
+
+// TODO(josharian): combine this with its caller and simplify
+func reduceSlice(n *ir.SliceExpr) ir.Node {
+	if n.High != nil && n.High.Op() == ir.OLEN && ir.SameSafeExpr(n.X, n.High.(*ir.UnaryExpr).X) {
+		// Reduce x[i:len(x)] to x[i:].
+		n.High = nil
+	}
+	if (n.Op() == ir.OSLICE || n.Op() == ir.OSLICESTR) && n.Low == nil && n.High == nil {
+		// Reduce x[:] to x.
+		if base.Debug.Slice > 0 {
+			base.Warn("slice: omit slice operation")
+		}
+		return n.X
+	}
+	return n
+}
+
+// return 1 if integer n must be in range [0, max), 0 otherwise
+func bounded(n ir.Node, max int64) bool {
+	if n.Type() == nil || !n.Type().IsInteger() {
+		return false
+	}
+
+	sign := n.Type().IsSigned()
+	bits := int32(8 * n.Type().Width)
+
+	if ir.IsSmallIntConst(n) {
+		v := ir.Int64Val(n)
+		return 0 <= v && v < max
+	}
+
+	switch n.Op() {
+	case ir.OAND, ir.OANDNOT:
+		n := n.(*ir.BinaryExpr)
+		v := int64(-1)
+		switch {
+		case ir.IsSmallIntConst(n.X):
+			v = ir.Int64Val(n.X)
+		case ir.IsSmallIntConst(n.Y):
+			v = ir.Int64Val(n.Y)
+			if n.Op() == ir.OANDNOT {
+				v = ^v
+				if !sign {
+					v &= 1<<uint(bits) - 1
+				}
+			}
+		}
+		if 0 <= v && v < max {
+			return true
+		}
+
+	case ir.OMOD:
+		n := n.(*ir.BinaryExpr)
+		if !sign && ir.IsSmallIntConst(n.Y) {
+			v := ir.Int64Val(n.Y)
+			if 0 <= v && v <= max {
+				return true
+			}
+		}
+
+	case ir.ODIV:
+		n := n.(*ir.BinaryExpr)
+		if !sign && ir.IsSmallIntConst(n.Y) {
+			v := ir.Int64Val(n.Y)
+			for bits > 0 && v >= 2 {
+				bits--
+				v >>= 1
+			}
+		}
+
+	case ir.ORSH:
+		n := n.(*ir.BinaryExpr)
+		if !sign && ir.IsSmallIntConst(n.Y) {
+			v := ir.Int64Val(n.Y)
+			if v > int64(bits) {
+				return true
+			}
+			bits -= int32(v)
+		}
+	}
+
+	if !sign && bits <= 62 && 1<<uint(bits) <= max {
+		return true
+	}
+
+	return false
+}
+
+// usemethod checks interface method calls for uses of reflect.Type.Method.
+func usemethod(n *ir.CallExpr) {
+	t := n.X.Type()
+
+	// Looking for either of:
+	//	Method(int) reflect.Method
+	//	MethodByName(string) (reflect.Method, bool)
+	//
+	// TODO(crawshaw): improve precision of match by working out
+	//                 how to check the method name.
+	if n := t.NumParams(); n != 1 {
+		return
+	}
+	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.NumResults() == 2 {
+		res1 = t.Results().Field(1)
+	}
+
+	if res1 == nil {
+		if p0.Type.Kind() != types.TINT {
+			return
+		}
+	} else {
+		if !p0.Type.IsString() {
+			return
+		}
+		if !res1.Type.IsBoolean() {
+			return
+		}
+	}
+
+	// Don't mark reflect.(*rtype).Method, etc. themselves in the reflect package.
+	// Those functions may be alive via the itab, which should not cause all methods
+	// alive. We only want to mark their callers.
+	if base.Ctxt.Pkgpath == "reflect" {
+		switch ir.CurFunc.Nname.Sym().Name { // TODO: is there a better way than hardcoding the names?
+		case "(*rtype).Method", "(*rtype).MethodByName", "(*interfaceType).Method", "(*interfaceType).MethodByName":
+			return
+		}
+	}
+
+	// Note: Don't rely on res0.Type.String() since its formatting depends on multiple factors
+	//       (including global variables such as numImports - was issue #19028).
+	// Also need to check for reflect package itself (see Issue #38515).
+	if s := res0.Type.Sym(); s != nil && s.Name == "Method" && types.IsReflectPkg(s.Pkg) {
+		ir.CurFunc.SetReflectMethod(true)
+		// The LSym is initialized at this point. We need to set the attribute on the LSym.
+		ir.CurFunc.LSym.Set(obj.AttrReflectMethod, true)
+	}
+}
+
+func usefield(n *ir.SelectorExpr) {
+	if !buildcfg.Experiment.FieldTrack {
+		return
+	}
+
+	switch n.Op() {
+	default:
+		base.Fatalf("usefield %v", n.Op())
+
+	case ir.ODOT, ir.ODOTPTR:
+		break
+	}
+
+	field := n.Selection
+	if field == nil {
+		base.Fatalf("usefield %v %v without paramfld", n.X.Type(), n.Sel)
+	}
+	if field.Sym != n.Sel {
+		base.Fatalf("field inconsistency: %v != %v", field.Sym, n.Sel)
+	}
+	if !strings.Contains(field.Note, "go:\"track\"") {
+		return
+	}
+
+	outer := n.X.Type()
+	if outer.IsPtr() {
+		outer = outer.Elem()
+	}
+	if outer.Sym() == nil {
+		base.Errorf("tracked field must be in named struct type")
+	}
+	if !types.IsExported(field.Sym.Name) {
+		base.Errorf("tracked field must be exported (upper case)")
+	}
+
+	sym := reflectdata.TrackSym(outer, field)
+	if ir.CurFunc.FieldTrack == nil {
+		ir.CurFunc.FieldTrack = make(map[*obj.LSym]struct{})
+	}
+	ir.CurFunc.FieldTrack[sym] = struct{}{}
+}
diff --git a/src/cmd/compile/internal/walk/order.go b/src/cmd/compile/internal/walk/order.go
new file mode 100644
index 0000000..b733d3a
--- /dev/null
+++ b/src/cmd/compile/internal/walk/order.go
@@ -0,0 +1,1821 @@
+// 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 walk
+
+import (
+	"fmt"
+	"go/constant"
+	"internal/buildcfg"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/escape"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/staticinit"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// Rewrite tree to use separate statements to enforce
+// order of evaluation. Makes walk easier, because it
+// can (after this runs) reorder at will within an expression.
+//
+// Rewrite m[k] op= r into m[k] = m[k] op r if op is / or %.
+//
+// Introduce temporaries as needed by runtime routines.
+// For example, the map runtime routines take the map key
+// by reference, so make sure all map keys are addressable
+// by copying them to temporaries as needed.
+// The same is true for channel operations.
+//
+// Arrange that map index expressions only appear in direct
+// assignments x = m[k] or m[k] = x, never in larger expressions.
+//
+// Arrange that receive expressions only appear in direct assignments
+// x = <-c or as standalone statements <-c, never in larger expressions.
+
+// TODO(rsc): The temporary introduction during multiple assignments
+// should be moved into this file, so that the temporaries can be cleaned
+// and so that conversions implicit in the OAS2FUNC and OAS2RECV
+// nodes can be made explicit and then have their temporaries cleaned.
+
+// TODO(rsc): Goto and multilevel break/continue can jump over
+// inserted VARKILL annotations. Work out a way to handle these.
+// The current implementation is safe, in that it will execute correctly.
+// But it won't reuse temporaries as aggressively as it might, and
+// it can result in unnecessary zeroing of those variables in the function
+// prologue.
+
+// orderState holds state during the ordering process.
+type orderState struct {
+	out  []ir.Node             // list of generated statements
+	temp []*ir.Name            // stack of temporary variables
+	free map[string][]*ir.Name // free list of unused temporaries, by type.LongString().
+	edit func(ir.Node) ir.Node // cached closure of o.exprNoLHS
+}
+
+// Order rewrites fn.Nbody to apply the ordering constraints
+// described in the comment at the top of the file.
+func order(fn *ir.Func) {
+	if base.Flag.W > 1 {
+		s := fmt.Sprintf("\nbefore order %v", fn.Sym())
+		ir.DumpList(s, fn.Body)
+	}
+
+	orderBlock(&fn.Body, map[string][]*ir.Name{})
+}
+
+// append typechecks stmt and appends it to out.
+func (o *orderState) append(stmt ir.Node) {
+	o.out = append(o.out, typecheck.Stmt(stmt))
+}
+
+// newTemp allocates a new temporary with the given type,
+// pushes it onto the temp stack, and returns it.
+// If clear is true, newTemp emits code to zero the temporary.
+func (o *orderState) newTemp(t *types.Type, clear bool) *ir.Name {
+	var v *ir.Name
+	// Note: LongString is close to the type equality we want,
+	// but not exactly. We still need to double-check with types.Identical.
+	key := t.LongString()
+	a := o.free[key]
+	for i, n := range a {
+		if types.Identical(t, n.Type()) {
+			v = a[i]
+			a[i] = a[len(a)-1]
+			a = a[:len(a)-1]
+			o.free[key] = a
+			break
+		}
+	}
+	if v == nil {
+		v = typecheck.Temp(t)
+	}
+	if clear {
+		o.append(ir.NewAssignStmt(base.Pos, v, nil))
+	}
+
+	o.temp = append(o.temp, v)
+	return v
+}
+
+// copyExpr behaves like newTemp but also emits
+// code to initialize the temporary to the value n.
+func (o *orderState) copyExpr(n ir.Node) *ir.Name {
+	return o.copyExpr1(n, false)
+}
+
+// copyExprClear is like copyExpr but clears the temp before assignment.
+// It is provided for use when the evaluation of tmp = n turns into
+// a function call that is passed a pointer to the temporary as the output space.
+// If the call blocks before tmp has been written,
+// the garbage collector will still treat the temporary as live,
+// so we must zero it before entering that call.
+// Today, this only happens for channel receive operations.
+// (The other candidate would be map access, but map access
+// returns a pointer to the result data instead of taking a pointer
+// to be filled in.)
+func (o *orderState) copyExprClear(n ir.Node) *ir.Name {
+	return o.copyExpr1(n, true)
+}
+
+func (o *orderState) copyExpr1(n ir.Node, clear bool) *ir.Name {
+	t := n.Type()
+	v := o.newTemp(t, clear)
+	o.append(ir.NewAssignStmt(base.Pos, v, n))
+	return v
+}
+
+// cheapExpr returns a cheap version of n.
+// The definition of cheap is that n is a variable or constant.
+// If not, cheapExpr allocates a new tmp, emits tmp = n,
+// and then returns tmp.
+func (o *orderState) cheapExpr(n ir.Node) ir.Node {
+	if n == nil {
+		return nil
+	}
+
+	switch n.Op() {
+	case ir.ONAME, ir.OLITERAL, ir.ONIL:
+		return n
+	case ir.OLEN, ir.OCAP:
+		n := n.(*ir.UnaryExpr)
+		l := o.cheapExpr(n.X)
+		if l == n.X {
+			return n
+		}
+		a := ir.SepCopy(n).(*ir.UnaryExpr)
+		a.X = l
+		return typecheck.Expr(a)
+	}
+
+	return o.copyExpr(n)
+}
+
+// safeExpr returns a safe version of n.
+// The definition of safe is that n can appear multiple times
+// without violating the semantics of the original program,
+// and that assigning to the safe version has the same effect
+// as assigning to the original n.
+//
+// The intended use is to apply to x when rewriting x += y into x = x + y.
+func (o *orderState) safeExpr(n ir.Node) ir.Node {
+	switch n.Op() {
+	case ir.ONAME, ir.OLITERAL, ir.ONIL:
+		return n
+
+	case ir.OLEN, ir.OCAP:
+		n := n.(*ir.UnaryExpr)
+		l := o.safeExpr(n.X)
+		if l == n.X {
+			return n
+		}
+		a := ir.SepCopy(n).(*ir.UnaryExpr)
+		a.X = l
+		return typecheck.Expr(a)
+
+	case ir.ODOT:
+		n := n.(*ir.SelectorExpr)
+		l := o.safeExpr(n.X)
+		if l == n.X {
+			return n
+		}
+		a := ir.SepCopy(n).(*ir.SelectorExpr)
+		a.X = l
+		return typecheck.Expr(a)
+
+	case ir.ODOTPTR:
+		n := n.(*ir.SelectorExpr)
+		l := o.cheapExpr(n.X)
+		if l == n.X {
+			return n
+		}
+		a := ir.SepCopy(n).(*ir.SelectorExpr)
+		a.X = l
+		return typecheck.Expr(a)
+
+	case ir.ODEREF:
+		n := n.(*ir.StarExpr)
+		l := o.cheapExpr(n.X)
+		if l == n.X {
+			return n
+		}
+		a := ir.SepCopy(n).(*ir.StarExpr)
+		a.X = l
+		return typecheck.Expr(a)
+
+	case ir.OINDEX, ir.OINDEXMAP:
+		n := n.(*ir.IndexExpr)
+		var l ir.Node
+		if n.X.Type().IsArray() {
+			l = o.safeExpr(n.X)
+		} else {
+			l = o.cheapExpr(n.X)
+		}
+		r := o.cheapExpr(n.Index)
+		if l == n.X && r == n.Index {
+			return n
+		}
+		a := ir.SepCopy(n).(*ir.IndexExpr)
+		a.X = l
+		a.Index = r
+		return typecheck.Expr(a)
+
+	default:
+		base.Fatalf("order.safeExpr %v", n.Op())
+		return nil // not reached
+	}
+}
+
+// isaddrokay reports whether it is okay to pass n's address to runtime routines.
+// Taking the address of a variable makes the liveness and optimization analyses
+// lose track of where the variable's lifetime ends. To avoid hurting the analyses
+// of ordinary stack variables, those are not 'isaddrokay'. Temporaries are okay,
+// because we emit explicit VARKILL instructions marking the end of those
+// temporaries' lifetimes.
+func isaddrokay(n ir.Node) bool {
+	return ir.IsAddressable(n) && (n.Op() != ir.ONAME || n.(*ir.Name).Class == ir.PEXTERN || ir.IsAutoTmp(n))
+}
+
+// addrTemp ensures that n is okay to pass by address to runtime routines.
+// If the original argument n is not okay, addrTemp creates a tmp, emits
+// tmp = n, and then returns tmp.
+// The result of addrTemp MUST be assigned back to n, e.g.
+// 	n.Left = o.addrTemp(n.Left)
+func (o *orderState) addrTemp(n ir.Node) ir.Node {
+	if n.Op() == ir.OLITERAL || n.Op() == ir.ONIL {
+		// TODO: expand this to all static composite literal nodes?
+		n = typecheck.DefaultLit(n, nil)
+		types.CalcSize(n.Type())
+		vstat := readonlystaticname(n.Type())
+		var s staticinit.Schedule
+		s.StaticAssign(vstat, 0, n, n.Type())
+		if s.Out != nil {
+			base.Fatalf("staticassign of const generated code: %+v", n)
+		}
+		vstat = typecheck.Expr(vstat).(*ir.Name)
+		return vstat
+	}
+	if isaddrokay(n) {
+		return n
+	}
+	return o.copyExpr(n)
+}
+
+// mapKeyTemp prepares n to be a key in a map runtime call and returns n.
+// It should only be used for map runtime calls which have *_fast* versions.
+func (o *orderState) mapKeyTemp(t *types.Type, n ir.Node) ir.Node {
+	// Most map calls need to take the address of the key.
+	// Exception: map*_fast* calls. See golang.org/issue/19015.
+	alg := mapfast(t)
+	if alg == mapslow {
+		return o.addrTemp(n)
+	}
+	var kt *types.Type
+	switch alg {
+	case mapfast32:
+		kt = types.Types[types.TUINT32]
+	case mapfast64:
+		kt = types.Types[types.TUINT64]
+	case mapfast32ptr, mapfast64ptr:
+		kt = types.Types[types.TUNSAFEPTR]
+	case mapfaststr:
+		kt = types.Types[types.TSTRING]
+	}
+	nt := n.Type()
+	switch {
+	case nt == kt:
+		return n
+	case nt.Kind() == kt.Kind(), nt.IsPtrShaped() && kt.IsPtrShaped():
+		// can directly convert (e.g. named type to underlying type, or one pointer to another)
+		return typecheck.Expr(ir.NewConvExpr(n.Pos(), ir.OCONVNOP, kt, n))
+	case nt.IsInteger() && kt.IsInteger():
+		// can directly convert (e.g. int32 to uint32)
+		if n.Op() == ir.OLITERAL && nt.IsSigned() {
+			// avoid constant overflow error
+			n = ir.NewConstExpr(constant.MakeUint64(uint64(ir.Int64Val(n))), n)
+			n.SetType(kt)
+			return n
+		}
+		return typecheck.Expr(ir.NewConvExpr(n.Pos(), ir.OCONV, kt, n))
+	default:
+		// Unsafe cast through memory.
+		// We'll need to do a load with type kt. Create a temporary of type kt to
+		// ensure sufficient alignment. nt may be under-aligned.
+		if kt.Align < nt.Align {
+			base.Fatalf("mapKeyTemp: key type is not sufficiently aligned, kt=%v nt=%v", kt, nt)
+		}
+		tmp := o.newTemp(kt, true)
+		// *(*nt)(&tmp) = n
+		var e ir.Node = typecheck.NodAddr(tmp)
+		e = ir.NewConvExpr(n.Pos(), ir.OCONVNOP, nt.PtrTo(), e)
+		e = ir.NewStarExpr(n.Pos(), e)
+		o.append(ir.NewAssignStmt(base.Pos, e, n))
+		return tmp
+	}
+}
+
+// mapKeyReplaceStrConv replaces OBYTES2STR by OBYTES2STRTMP
+// in n to avoid string allocations for keys in map lookups.
+// Returns a bool that signals if a modification was made.
+//
+// For:
+//  x = m[string(k)]
+//  x = m[T1{... Tn{..., string(k), ...}]
+// where k is []byte, T1 to Tn is a nesting of struct and array literals,
+// the allocation of backing bytes for the string can be avoided
+// by reusing the []byte backing array. These are special cases
+// for avoiding allocations when converting byte slices to strings.
+// It would be nice to handle these generally, but because
+// []byte keys are not allowed in maps, the use of string(k)
+// comes up in important cases in practice. See issue 3512.
+func mapKeyReplaceStrConv(n ir.Node) bool {
+	var replaced bool
+	switch n.Op() {
+	case ir.OBYTES2STR:
+		n := n.(*ir.ConvExpr)
+		n.SetOp(ir.OBYTES2STRTMP)
+		replaced = true
+	case ir.OSTRUCTLIT:
+		n := n.(*ir.CompLitExpr)
+		for _, elem := range n.List {
+			elem := elem.(*ir.StructKeyExpr)
+			if mapKeyReplaceStrConv(elem.Value) {
+				replaced = true
+			}
+		}
+	case ir.OARRAYLIT:
+		n := n.(*ir.CompLitExpr)
+		for _, elem := range n.List {
+			if elem.Op() == ir.OKEY {
+				elem = elem.(*ir.KeyExpr).Value
+			}
+			if mapKeyReplaceStrConv(elem) {
+				replaced = true
+			}
+		}
+	}
+	return replaced
+}
+
+type ordermarker int
+
+// markTemp returns the top of the temporary variable stack.
+func (o *orderState) markTemp() ordermarker {
+	return ordermarker(len(o.temp))
+}
+
+// popTemp pops temporaries off the stack until reaching the mark,
+// which must have been returned by markTemp.
+func (o *orderState) popTemp(mark ordermarker) {
+	for _, n := range o.temp[mark:] {
+		key := n.Type().LongString()
+		o.free[key] = append(o.free[key], n)
+	}
+	o.temp = o.temp[:mark]
+}
+
+// cleanTempNoPop emits VARKILL instructions to *out
+// for each temporary above the mark on the temporary stack.
+// It does not pop the temporaries from the stack.
+func (o *orderState) cleanTempNoPop(mark ordermarker) []ir.Node {
+	var out []ir.Node
+	for i := len(o.temp) - 1; i >= int(mark); i-- {
+		n := o.temp[i]
+		out = append(out, typecheck.Stmt(ir.NewUnaryExpr(base.Pos, ir.OVARKILL, n)))
+	}
+	return out
+}
+
+// cleanTemp emits VARKILL instructions for each temporary above the
+// mark on the temporary stack and removes them from the stack.
+func (o *orderState) cleanTemp(top ordermarker) {
+	o.out = append(o.out, o.cleanTempNoPop(top)...)
+	o.popTemp(top)
+}
+
+// stmtList orders each of the statements in the list.
+func (o *orderState) stmtList(l ir.Nodes) {
+	s := l
+	for i := range s {
+		orderMakeSliceCopy(s[i:])
+		o.stmt(s[i])
+	}
+}
+
+// orderMakeSliceCopy matches the pattern:
+//  m = OMAKESLICE([]T, x); OCOPY(m, s)
+// and rewrites it to:
+//  m = OMAKESLICECOPY([]T, x, s); nil
+func orderMakeSliceCopy(s []ir.Node) {
+	if base.Flag.N != 0 || base.Flag.Cfg.Instrumenting {
+		return
+	}
+	if len(s) < 2 || s[0] == nil || s[0].Op() != ir.OAS || s[1] == nil || s[1].Op() != ir.OCOPY {
+		return
+	}
+
+	as := s[0].(*ir.AssignStmt)
+	cp := s[1].(*ir.BinaryExpr)
+	if as.Y == nil || as.Y.Op() != ir.OMAKESLICE || ir.IsBlank(as.X) ||
+		as.X.Op() != ir.ONAME || cp.X.Op() != ir.ONAME || cp.Y.Op() != ir.ONAME ||
+		as.X.Name() != cp.X.Name() || cp.X.Name() == cp.Y.Name() {
+		// The line above this one is correct with the differing equality operators:
+		// we want as.X and cp.X to be the same name,
+		// but we want the initial data to be coming from a different name.
+		return
+	}
+
+	mk := as.Y.(*ir.MakeExpr)
+	if mk.Esc() == ir.EscNone || mk.Len == nil || mk.Cap != nil {
+		return
+	}
+	mk.SetOp(ir.OMAKESLICECOPY)
+	mk.Cap = cp.Y
+	// Set bounded when m = OMAKESLICE([]T, len(s)); OCOPY(m, s)
+	mk.SetBounded(mk.Len.Op() == ir.OLEN && ir.SameSafeExpr(mk.Len.(*ir.UnaryExpr).X, cp.Y))
+	as.Y = typecheck.Expr(mk)
+	s[1] = nil // remove separate copy call
+}
+
+// edge inserts coverage instrumentation for libfuzzer.
+func (o *orderState) edge() {
+	if base.Debug.Libfuzzer == 0 {
+		return
+	}
+
+	// Create a new uint8 counter to be allocated in section
+	// __libfuzzer_extra_counters.
+	counter := staticinit.StaticName(types.Types[types.TUINT8])
+	counter.SetLibfuzzerExtraCounter(true)
+
+	// counter += 1
+	incr := ir.NewAssignOpStmt(base.Pos, ir.OADD, counter, ir.NewInt(1))
+	o.append(incr)
+}
+
+// orderBlock orders the block of statements in n into a new slice,
+// and then replaces the old slice in n with the new slice.
+// free is a map that can be used to obtain temporary variables by type.
+func orderBlock(n *ir.Nodes, free map[string][]*ir.Name) {
+	var order orderState
+	order.free = free
+	mark := order.markTemp()
+	order.edge()
+	order.stmtList(*n)
+	order.cleanTemp(mark)
+	*n = order.out
+}
+
+// exprInPlace orders the side effects in *np and
+// leaves them as the init list of the final *np.
+// The result of exprInPlace MUST be assigned back to n, e.g.
+// 	n.Left = o.exprInPlace(n.Left)
+func (o *orderState) exprInPlace(n ir.Node) ir.Node {
+	var order orderState
+	order.free = o.free
+	n = order.expr(n, nil)
+	n = ir.InitExpr(order.out, n)
+
+	// insert new temporaries from order
+	// at head of outer list.
+	o.temp = append(o.temp, order.temp...)
+	return n
+}
+
+// orderStmtInPlace orders the side effects of the single statement *np
+// and replaces it with the resulting statement list.
+// The result of orderStmtInPlace MUST be assigned back to n, e.g.
+// 	n.Left = orderStmtInPlace(n.Left)
+// free is a map that can be used to obtain temporary variables by type.
+func orderStmtInPlace(n ir.Node, free map[string][]*ir.Name) ir.Node {
+	var order orderState
+	order.free = free
+	mark := order.markTemp()
+	order.stmt(n)
+	order.cleanTemp(mark)
+	return ir.NewBlockStmt(src.NoXPos, order.out)
+}
+
+// init moves n's init list to o.out.
+func (o *orderState) init(n ir.Node) {
+	if ir.MayBeShared(n) {
+		// For concurrency safety, don't mutate potentially shared nodes.
+		// First, ensure that no work is required here.
+		if len(n.Init()) > 0 {
+			base.Fatalf("order.init shared node with ninit")
+		}
+		return
+	}
+	o.stmtList(ir.TakeInit(n))
+}
+
+// call orders the call expression n.
+// n.Op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY.
+func (o *orderState) call(nn ir.Node) {
+	if len(nn.Init()) > 0 {
+		// Caller should have already called o.init(nn).
+		base.Fatalf("%v with unexpected ninit", nn.Op())
+	}
+
+	// Builtin functions.
+	if nn.Op() != ir.OCALLFUNC && nn.Op() != ir.OCALLMETH && nn.Op() != ir.OCALLINTER {
+		switch n := nn.(type) {
+		default:
+			base.Fatalf("unexpected call: %+v", n)
+		case *ir.UnaryExpr:
+			n.X = o.expr(n.X, nil)
+		case *ir.ConvExpr:
+			n.X = o.expr(n.X, nil)
+		case *ir.BinaryExpr:
+			n.X = o.expr(n.X, nil)
+			n.Y = o.expr(n.Y, nil)
+		case *ir.MakeExpr:
+			n.Len = o.expr(n.Len, nil)
+			n.Cap = o.expr(n.Cap, nil)
+		case *ir.CallExpr:
+			o.exprList(n.Args)
+		}
+		return
+	}
+
+	n := nn.(*ir.CallExpr)
+	typecheck.FixVariadicCall(n)
+
+	if isFuncPCIntrinsic(n) && isIfaceOfFunc(n.Args[0]) {
+		// For internal/abi.FuncPCABIxxx(fn), if fn is a defined function,
+		// do not introduce temporaries here, so it is easier to rewrite it
+		// to symbol address reference later in walk.
+		return
+	}
+
+	n.X = o.expr(n.X, nil)
+	o.exprList(n.Args)
+
+	if n.Op() == ir.OCALLINTER {
+		return
+	}
+	keepAlive := func(arg ir.Node) {
+		// If the argument is really a pointer being converted to uintptr,
+		// arrange for the pointer to be kept alive until the call returns,
+		// by copying it into a temp and marking that temp
+		// still alive when we pop the temp stack.
+		if arg.Op() == ir.OCONVNOP {
+			arg := arg.(*ir.ConvExpr)
+			if arg.X.Type().IsUnsafePtr() {
+				x := o.copyExpr(arg.X)
+				arg.X = x
+				x.SetAddrtaken(true) // ensure SSA keeps the x variable
+				n.KeepAlive = append(n.KeepAlive, x)
+			}
+		}
+	}
+
+	// Check for "unsafe-uintptr" tag provided by escape analysis.
+	for i, param := range n.X.Type().Params().FieldSlice() {
+		if param.Note == escape.UnsafeUintptrNote || param.Note == escape.UintptrEscapesNote {
+			if arg := n.Args[i]; arg.Op() == ir.OSLICELIT {
+				arg := arg.(*ir.CompLitExpr)
+				for _, elt := range arg.List {
+					keepAlive(elt)
+				}
+			} else {
+				keepAlive(arg)
+			}
+		}
+	}
+}
+
+// mapAssign appends n to o.out.
+func (o *orderState) mapAssign(n ir.Node) {
+	switch n.Op() {
+	default:
+		base.Fatalf("order.mapAssign %v", n.Op())
+
+	case ir.OAS:
+		n := n.(*ir.AssignStmt)
+		if n.X.Op() == ir.OINDEXMAP {
+			n.Y = o.safeMapRHS(n.Y)
+		}
+		o.out = append(o.out, n)
+	case ir.OASOP:
+		n := n.(*ir.AssignOpStmt)
+		if n.X.Op() == ir.OINDEXMAP {
+			n.Y = o.safeMapRHS(n.Y)
+		}
+		o.out = append(o.out, n)
+	}
+}
+
+func (o *orderState) safeMapRHS(r ir.Node) ir.Node {
+	// Make sure we evaluate the RHS before starting the map insert.
+	// We need to make sure the RHS won't panic.  See issue 22881.
+	if r.Op() == ir.OAPPEND {
+		r := r.(*ir.CallExpr)
+		s := r.Args[1:]
+		for i, n := range s {
+			s[i] = o.cheapExpr(n)
+		}
+		return r
+	}
+	return o.cheapExpr(r)
+}
+
+// stmt orders the statement n, appending to o.out.
+// Temporaries created during the statement are cleaned
+// up using VARKILL instructions as possible.
+func (o *orderState) stmt(n ir.Node) {
+	if n == nil {
+		return
+	}
+
+	lno := ir.SetPos(n)
+	o.init(n)
+
+	switch n.Op() {
+	default:
+		base.Fatalf("order.stmt %v", n.Op())
+
+	case ir.OVARKILL, ir.OVARLIVE, ir.OINLMARK:
+		o.out = append(o.out, n)
+
+	case ir.OAS:
+		n := n.(*ir.AssignStmt)
+		t := o.markTemp()
+		n.X = o.expr(n.X, nil)
+		n.Y = o.expr(n.Y, n.X)
+		o.mapAssign(n)
+		o.cleanTemp(t)
+
+	case ir.OASOP:
+		n := n.(*ir.AssignOpStmt)
+		t := o.markTemp()
+		n.X = o.expr(n.X, nil)
+		n.Y = o.expr(n.Y, nil)
+
+		if base.Flag.Cfg.Instrumenting || n.X.Op() == ir.OINDEXMAP && (n.AsOp == ir.ODIV || n.AsOp == ir.OMOD) {
+			// Rewrite m[k] op= r into m[k] = m[k] op r so
+			// that we can ensure that if op panics
+			// because r is zero, the panic happens before
+			// the map assignment.
+			// DeepCopy is a big hammer here, but safeExpr
+			// makes sure there is nothing too deep being copied.
+			l1 := o.safeExpr(n.X)
+			l2 := ir.DeepCopy(src.NoXPos, l1)
+			if l2.Op() == ir.OINDEXMAP {
+				l2 := l2.(*ir.IndexExpr)
+				l2.Assigned = false
+			}
+			l2 = o.copyExpr(l2)
+			r := o.expr(typecheck.Expr(ir.NewBinaryExpr(n.Pos(), n.AsOp, l2, n.Y)), nil)
+			as := typecheck.Stmt(ir.NewAssignStmt(n.Pos(), l1, r))
+			o.mapAssign(as)
+			o.cleanTemp(t)
+			return
+		}
+
+		o.mapAssign(n)
+		o.cleanTemp(t)
+
+	case ir.OAS2:
+		n := n.(*ir.AssignListStmt)
+		t := o.markTemp()
+		o.exprList(n.Lhs)
+		o.exprList(n.Rhs)
+		o.out = append(o.out, n)
+		o.cleanTemp(t)
+
+	// Special: avoid copy of func call n.Right
+	case ir.OAS2FUNC:
+		n := n.(*ir.AssignListStmt)
+		t := o.markTemp()
+		o.exprList(n.Lhs)
+		o.init(n.Rhs[0])
+		o.call(n.Rhs[0])
+		o.as2func(n)
+		o.cleanTemp(t)
+
+	// Special: use temporary variables to hold result,
+	// so that runtime can take address of temporary.
+	// No temporary for blank assignment.
+	//
+	// OAS2MAPR: make sure key is addressable if needed,
+	//           and make sure OINDEXMAP is not copied out.
+	case ir.OAS2DOTTYPE, ir.OAS2RECV, ir.OAS2MAPR:
+		n := n.(*ir.AssignListStmt)
+		t := o.markTemp()
+		o.exprList(n.Lhs)
+
+		switch r := n.Rhs[0]; r.Op() {
+		case ir.ODOTTYPE2:
+			r := r.(*ir.TypeAssertExpr)
+			r.X = o.expr(r.X, nil)
+		case ir.ORECV:
+			r := r.(*ir.UnaryExpr)
+			r.X = o.expr(r.X, nil)
+		case ir.OINDEXMAP:
+			r := r.(*ir.IndexExpr)
+			r.X = o.expr(r.X, nil)
+			r.Index = o.expr(r.Index, nil)
+			// See similar conversion for OINDEXMAP below.
+			_ = mapKeyReplaceStrConv(r.Index)
+			r.Index = o.mapKeyTemp(r.X.Type(), r.Index)
+		default:
+			base.Fatalf("order.stmt: %v", r.Op())
+		}
+
+		o.as2ok(n)
+		o.cleanTemp(t)
+
+	// Special: does not save n onto out.
+	case ir.OBLOCK:
+		n := n.(*ir.BlockStmt)
+		o.stmtList(n.List)
+
+	// Special: n->left is not an expression; save as is.
+	case ir.OBREAK,
+		ir.OCONTINUE,
+		ir.ODCL,
+		ir.ODCLCONST,
+		ir.ODCLTYPE,
+		ir.OFALL,
+		ir.OGOTO,
+		ir.OLABEL,
+		ir.OTAILCALL:
+		o.out = append(o.out, n)
+
+	// Special: handle call arguments.
+	case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
+		n := n.(*ir.CallExpr)
+		t := o.markTemp()
+		o.call(n)
+		o.out = append(o.out, n)
+		o.cleanTemp(t)
+
+	case ir.OCLOSE, ir.ORECV:
+		n := n.(*ir.UnaryExpr)
+		t := o.markTemp()
+		n.X = o.expr(n.X, nil)
+		o.out = append(o.out, n)
+		o.cleanTemp(t)
+
+	case ir.OCOPY:
+		n := n.(*ir.BinaryExpr)
+		t := o.markTemp()
+		n.X = o.expr(n.X, nil)
+		n.Y = o.expr(n.Y, nil)
+		o.out = append(o.out, n)
+		o.cleanTemp(t)
+
+	case ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
+		n := n.(*ir.CallExpr)
+		t := o.markTemp()
+		o.exprList(n.Args)
+		o.out = append(o.out, n)
+		o.cleanTemp(t)
+
+	// Special: order arguments to inner call but not call itself.
+	case ir.ODEFER, ir.OGO:
+		n := n.(*ir.GoDeferStmt)
+		t := o.markTemp()
+		o.init(n.Call)
+		o.call(n.Call)
+		if n.Call.Op() == ir.ORECOVER {
+			// Special handling of "defer recover()". We need to evaluate the FP
+			// argument before wrapping.
+			var init ir.Nodes
+			n.Call = walkRecover(n.Call.(*ir.CallExpr), &init)
+			o.stmtList(init)
+		}
+		if buildcfg.Experiment.RegabiDefer {
+			o.wrapGoDefer(n)
+		}
+		o.out = append(o.out, n)
+		o.cleanTemp(t)
+
+	case ir.ODELETE:
+		n := n.(*ir.CallExpr)
+		t := o.markTemp()
+		n.Args[0] = o.expr(n.Args[0], nil)
+		n.Args[1] = o.expr(n.Args[1], nil)
+		n.Args[1] = o.mapKeyTemp(n.Args[0].Type(), n.Args[1])
+		o.out = append(o.out, n)
+		o.cleanTemp(t)
+
+	// Clean temporaries from condition evaluation at
+	// beginning of loop body and after for statement.
+	case ir.OFOR:
+		n := n.(*ir.ForStmt)
+		t := o.markTemp()
+		n.Cond = o.exprInPlace(n.Cond)
+		n.Body.Prepend(o.cleanTempNoPop(t)...)
+		orderBlock(&n.Body, o.free)
+		n.Post = orderStmtInPlace(n.Post, o.free)
+		o.out = append(o.out, n)
+		o.cleanTemp(t)
+
+	// Clean temporaries from condition at
+	// beginning of both branches.
+	case ir.OIF:
+		n := n.(*ir.IfStmt)
+		t := o.markTemp()
+		n.Cond = o.exprInPlace(n.Cond)
+		n.Body.Prepend(o.cleanTempNoPop(t)...)
+		n.Else.Prepend(o.cleanTempNoPop(t)...)
+		o.popTemp(t)
+		orderBlock(&n.Body, o.free)
+		orderBlock(&n.Else, o.free)
+		o.out = append(o.out, n)
+
+	case ir.OPANIC:
+		n := n.(*ir.UnaryExpr)
+		t := o.markTemp()
+		n.X = o.expr(n.X, nil)
+		if !n.X.Type().IsEmptyInterface() {
+			base.FatalfAt(n.Pos(), "bad argument to panic: %L", n.X)
+		}
+		o.out = append(o.out, n)
+		o.cleanTemp(t)
+
+	case ir.ORANGE:
+		// n.Right is the expression being ranged over.
+		// order it, and then make a copy if we need one.
+		// We almost always do, to ensure that we don't
+		// see any value changes made during the loop.
+		// Usually the copy is cheap (e.g., array pointer,
+		// chan, slice, string are all tiny).
+		// The exception is ranging over an array value
+		// (not a slice, not a pointer to array),
+		// which must make a copy to avoid seeing updates made during
+		// the range body. Ranging over an array value is uncommon though.
+
+		// Mark []byte(str) range expression to reuse string backing storage.
+		// It is safe because the storage cannot be mutated.
+		n := n.(*ir.RangeStmt)
+		if n.X.Op() == ir.OSTR2BYTES {
+			n.X.(*ir.ConvExpr).SetOp(ir.OSTR2BYTESTMP)
+		}
+
+		t := o.markTemp()
+		n.X = o.expr(n.X, nil)
+
+		orderBody := true
+		xt := typecheck.RangeExprType(n.X.Type())
+		switch xt.Kind() {
+		default:
+			base.Fatalf("order.stmt range %v", n.Type())
+
+		case types.TARRAY, types.TSLICE:
+			if n.Value == nil || ir.IsBlank(n.Value) {
+				// for i := range x will only use x once, to compute len(x).
+				// No need to copy it.
+				break
+			}
+			fallthrough
+
+		case types.TCHAN, types.TSTRING:
+			// chan, string, slice, array ranges use value multiple times.
+			// make copy.
+			r := n.X
+
+			if r.Type().IsString() && r.Type() != types.Types[types.TSTRING] {
+				r = ir.NewConvExpr(base.Pos, ir.OCONV, nil, r)
+				r.SetType(types.Types[types.TSTRING])
+				r = typecheck.Expr(r)
+			}
+
+			n.X = o.copyExpr(r)
+
+		case types.TMAP:
+			if isMapClear(n) {
+				// Preserve the body of the map clear pattern so it can
+				// be detected during walk. The loop body will not be used
+				// when optimizing away the range loop to a runtime call.
+				orderBody = false
+				break
+			}
+
+			// copy the map value in case it is a map literal.
+			// TODO(rsc): Make tmp = literal expressions reuse tmp.
+			// For maps tmp is just one word so it hardly matters.
+			r := n.X
+			n.X = o.copyExpr(r)
+
+			// n.Prealloc is the temp for the iterator.
+			// MapIterType contains pointers and needs to be zeroed.
+			n.Prealloc = o.newTemp(reflectdata.MapIterType(xt), true)
+		}
+		n.Key = o.exprInPlace(n.Key)
+		n.Value = o.exprInPlace(n.Value)
+		if orderBody {
+			orderBlock(&n.Body, o.free)
+		}
+		o.out = append(o.out, n)
+		o.cleanTemp(t)
+
+	case ir.ORETURN:
+		n := n.(*ir.ReturnStmt)
+		o.exprList(n.Results)
+		o.out = append(o.out, n)
+
+	// Special: clean case temporaries in each block entry.
+	// Select must enter one of its blocks, so there is no
+	// need for a cleaning at the end.
+	// Doubly special: evaluation order for select is stricter
+	// than ordinary expressions. Even something like p.c
+	// has to be hoisted into a temporary, so that it cannot be
+	// reordered after the channel evaluation for a different
+	// case (if p were nil, then the timing of the fault would
+	// give this away).
+	case ir.OSELECT:
+		n := n.(*ir.SelectStmt)
+		t := o.markTemp()
+		for _, ncas := range n.Cases {
+			r := ncas.Comm
+			ir.SetPos(ncas)
+
+			// Append any new body prologue to ninit.
+			// The next loop will insert ninit into nbody.
+			if len(ncas.Init()) != 0 {
+				base.Fatalf("order select ninit")
+			}
+			if r == nil {
+				continue
+			}
+			switch r.Op() {
+			default:
+				ir.Dump("select case", r)
+				base.Fatalf("unknown op in select %v", r.Op())
+
+			case ir.OSELRECV2:
+				// case x, ok = <-c
+				r := r.(*ir.AssignListStmt)
+				recv := r.Rhs[0].(*ir.UnaryExpr)
+				recv.X = o.expr(recv.X, nil)
+				if !ir.IsAutoTmp(recv.X) {
+					recv.X = o.copyExpr(recv.X)
+				}
+				init := ir.TakeInit(r)
+
+				colas := r.Def
+				do := func(i int, t *types.Type) {
+					n := r.Lhs[i]
+					if ir.IsBlank(n) {
+						return
+					}
+					// If this is case x := <-ch or case x, y := <-ch, the case has
+					// the ODCL nodes to declare x and y. We want to delay that
+					// declaration (and possible allocation) until inside the case body.
+					// Delete the ODCL nodes here and recreate them inside the body below.
+					if colas {
+						if len(init) > 0 && init[0].Op() == ir.ODCL && init[0].(*ir.Decl).X == n {
+							init = init[1:]
+						}
+						dcl := typecheck.Stmt(ir.NewDecl(base.Pos, ir.ODCL, n.(*ir.Name)))
+						ncas.PtrInit().Append(dcl)
+					}
+					tmp := o.newTemp(t, t.HasPointers())
+					as := typecheck.Stmt(ir.NewAssignStmt(base.Pos, n, typecheck.Conv(tmp, n.Type())))
+					ncas.PtrInit().Append(as)
+					r.Lhs[i] = tmp
+				}
+				do(0, recv.X.Type().Elem())
+				do(1, types.Types[types.TBOOL])
+				if len(init) != 0 {
+					ir.DumpList("ninit", r.Init())
+					base.Fatalf("ninit on select recv")
+				}
+				orderBlock(ncas.PtrInit(), o.free)
+
+			case ir.OSEND:
+				r := r.(*ir.SendStmt)
+				if len(r.Init()) != 0 {
+					ir.DumpList("ninit", r.Init())
+					base.Fatalf("ninit on select send")
+				}
+
+				// case c <- x
+				// r->left is c, r->right is x, both are always evaluated.
+				r.Chan = o.expr(r.Chan, nil)
+
+				if !ir.IsAutoTmp(r.Chan) {
+					r.Chan = o.copyExpr(r.Chan)
+				}
+				r.Value = o.expr(r.Value, nil)
+				if !ir.IsAutoTmp(r.Value) {
+					r.Value = o.copyExpr(r.Value)
+				}
+			}
+		}
+		// Now that we have accumulated all the temporaries, clean them.
+		// Also insert any ninit queued during the previous loop.
+		// (The temporary cleaning must follow that ninit work.)
+		for _, cas := range n.Cases {
+			orderBlock(&cas.Body, o.free)
+			cas.Body.Prepend(o.cleanTempNoPop(t)...)
+
+			// TODO(mdempsky): Is this actually necessary?
+			// walkSelect appears to walk Ninit.
+			cas.Body.Prepend(ir.TakeInit(cas)...)
+		}
+
+		o.out = append(o.out, n)
+		o.popTemp(t)
+
+	// Special: value being sent is passed as a pointer; make it addressable.
+	case ir.OSEND:
+		n := n.(*ir.SendStmt)
+		t := o.markTemp()
+		n.Chan = o.expr(n.Chan, nil)
+		n.Value = o.expr(n.Value, nil)
+		if base.Flag.Cfg.Instrumenting {
+			// Force copying to the stack so that (chan T)(nil) <- x
+			// is still instrumented as a read of x.
+			n.Value = o.copyExpr(n.Value)
+		} else {
+			n.Value = o.addrTemp(n.Value)
+		}
+		o.out = append(o.out, n)
+		o.cleanTemp(t)
+
+	// TODO(rsc): Clean temporaries more aggressively.
+	// Note that because walkSwitch will rewrite some of the
+	// switch into a binary search, this is not as easy as it looks.
+	// (If we ran that code here we could invoke order.stmt on
+	// the if-else chain instead.)
+	// For now just clean all the temporaries at the end.
+	// In practice that's fine.
+	case ir.OSWITCH:
+		n := n.(*ir.SwitchStmt)
+		if base.Debug.Libfuzzer != 0 && !hasDefaultCase(n) {
+			// Add empty "default:" case for instrumentation.
+			n.Cases = append(n.Cases, ir.NewCaseStmt(base.Pos, nil, nil))
+		}
+
+		t := o.markTemp()
+		n.Tag = o.expr(n.Tag, nil)
+		for _, ncas := range n.Cases {
+			o.exprListInPlace(ncas.List)
+			orderBlock(&ncas.Body, o.free)
+		}
+
+		o.out = append(o.out, n)
+		o.cleanTemp(t)
+	}
+
+	base.Pos = lno
+}
+
+func hasDefaultCase(n *ir.SwitchStmt) bool {
+	for _, ncas := range n.Cases {
+		if len(ncas.List) == 0 {
+			return true
+		}
+	}
+	return false
+}
+
+// exprList orders the expression list l into o.
+func (o *orderState) exprList(l ir.Nodes) {
+	s := l
+	for i := range s {
+		s[i] = o.expr(s[i], nil)
+	}
+}
+
+// exprListInPlace orders the expression list l but saves
+// the side effects on the individual expression ninit lists.
+func (o *orderState) exprListInPlace(l ir.Nodes) {
+	s := l
+	for i := range s {
+		s[i] = o.exprInPlace(s[i])
+	}
+}
+
+func (o *orderState) exprNoLHS(n ir.Node) ir.Node {
+	return o.expr(n, nil)
+}
+
+// expr orders a single expression, appending side
+// effects to o.out as needed.
+// If this is part of an assignment lhs = *np, lhs is given.
+// Otherwise lhs == nil. (When lhs != nil it may be possible
+// to avoid copying the result of the expression to a temporary.)
+// The result of expr MUST be assigned back to n, e.g.
+// 	n.Left = o.expr(n.Left, lhs)
+func (o *orderState) expr(n, lhs ir.Node) ir.Node {
+	if n == nil {
+		return n
+	}
+	lno := ir.SetPos(n)
+	n = o.expr1(n, lhs)
+	base.Pos = lno
+	return n
+}
+
+func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
+	o.init(n)
+
+	switch n.Op() {
+	default:
+		if o.edit == nil {
+			o.edit = o.exprNoLHS // create closure once
+		}
+		ir.EditChildren(n, o.edit)
+		return n
+
+	// Addition of strings turns into a function call.
+	// Allocate a temporary to hold the strings.
+	// Fewer than 5 strings use direct runtime helpers.
+	case ir.OADDSTR:
+		n := n.(*ir.AddStringExpr)
+		o.exprList(n.List)
+
+		if len(n.List) > 5 {
+			t := types.NewArray(types.Types[types.TSTRING], int64(len(n.List)))
+			n.Prealloc = o.newTemp(t, false)
+		}
+
+		// Mark string(byteSlice) arguments to reuse byteSlice backing
+		// buffer during conversion. String concatenation does not
+		// memorize the strings for later use, so it is safe.
+		// However, we can do it only if there is at least one non-empty string literal.
+		// Otherwise if all other arguments are empty strings,
+		// concatstrings will return the reference to the temp string
+		// to the caller.
+		hasbyte := false
+
+		haslit := false
+		for _, n1 := range n.List {
+			hasbyte = hasbyte || n1.Op() == ir.OBYTES2STR
+			haslit = haslit || n1.Op() == ir.OLITERAL && len(ir.StringVal(n1)) != 0
+		}
+
+		if haslit && hasbyte {
+			for _, n2 := range n.List {
+				if n2.Op() == ir.OBYTES2STR {
+					n2 := n2.(*ir.ConvExpr)
+					n2.SetOp(ir.OBYTES2STRTMP)
+				}
+			}
+		}
+		return n
+
+	case ir.OINDEXMAP:
+		n := n.(*ir.IndexExpr)
+		n.X = o.expr(n.X, nil)
+		n.Index = o.expr(n.Index, nil)
+		needCopy := false
+
+		if !n.Assigned {
+			// Enforce that any []byte slices we are not copying
+			// can not be changed before the map index by forcing
+			// the map index to happen immediately following the
+			// conversions. See copyExpr a few lines below.
+			needCopy = mapKeyReplaceStrConv(n.Index)
+
+			if base.Flag.Cfg.Instrumenting {
+				// Race detector needs the copy.
+				needCopy = true
+			}
+		}
+
+		// key must be addressable
+		n.Index = o.mapKeyTemp(n.X.Type(), n.Index)
+		if needCopy {
+			return o.copyExpr(n)
+		}
+		return n
+
+	// concrete type (not interface) argument might need an addressable
+	// temporary to pass to the runtime conversion routine.
+	case ir.OCONVIFACE:
+		n := n.(*ir.ConvExpr)
+		n.X = o.expr(n.X, nil)
+		if n.X.Type().IsInterface() {
+			return n
+		}
+		if _, _, needsaddr := convFuncName(n.X.Type(), n.Type()); needsaddr || isStaticCompositeLiteral(n.X) {
+			// Need a temp if we need to pass the address to the conversion function.
+			// We also process static composite literal node here, making a named static global
+			// whose address we can put directly in an interface (see OCONVIFACE case in walk).
+			n.X = o.addrTemp(n.X)
+		}
+		return n
+
+	case ir.OCONVNOP:
+		n := n.(*ir.ConvExpr)
+		if n.Type().IsKind(types.TUNSAFEPTR) && n.X.Type().IsKind(types.TUINTPTR) && (n.X.Op() == ir.OCALLFUNC || n.X.Op() == ir.OCALLINTER || n.X.Op() == ir.OCALLMETH) {
+			call := n.X.(*ir.CallExpr)
+			// When reordering unsafe.Pointer(f()) into a separate
+			// statement, the conversion and function call must stay
+			// together. See golang.org/issue/15329.
+			o.init(call)
+			o.call(call)
+			if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
+				return o.copyExpr(n)
+			}
+		} else {
+			n.X = o.expr(n.X, nil)
+		}
+		return n
+
+	case ir.OANDAND, ir.OOROR:
+		// ... = LHS && RHS
+		//
+		// var r bool
+		// r = LHS
+		// if r {       // or !r, for OROR
+		//     r = RHS
+		// }
+		// ... = r
+
+		n := n.(*ir.LogicalExpr)
+		r := o.newTemp(n.Type(), false)
+
+		// Evaluate left-hand side.
+		lhs := o.expr(n.X, nil)
+		o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, lhs)))
+
+		// Evaluate right-hand side, save generated code.
+		saveout := o.out
+		o.out = nil
+		t := o.markTemp()
+		o.edge()
+		rhs := o.expr(n.Y, nil)
+		o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, rhs)))
+		o.cleanTemp(t)
+		gen := o.out
+		o.out = saveout
+
+		// If left-hand side doesn't cause a short-circuit, issue right-hand side.
+		nif := ir.NewIfStmt(base.Pos, r, nil, nil)
+		if n.Op() == ir.OANDAND {
+			nif.Body = gen
+		} else {
+			nif.Else = gen
+		}
+		o.out = append(o.out, nif)
+		return r
+
+	case ir.OCALLFUNC,
+		ir.OCALLINTER,
+		ir.OCALLMETH,
+		ir.OCAP,
+		ir.OCOMPLEX,
+		ir.OCOPY,
+		ir.OIMAG,
+		ir.OLEN,
+		ir.OMAKECHAN,
+		ir.OMAKEMAP,
+		ir.OMAKESLICE,
+		ir.OMAKESLICECOPY,
+		ir.ONEW,
+		ir.OREAL,
+		ir.ORECOVER,
+		ir.OSTR2BYTES,
+		ir.OSTR2BYTESTMP,
+		ir.OSTR2RUNES:
+
+		if isRuneCount(n) {
+			// len([]rune(s)) is rewritten to runtime.countrunes(s) later.
+			conv := n.(*ir.UnaryExpr).X.(*ir.ConvExpr)
+			conv.X = o.expr(conv.X, nil)
+		} else {
+			o.call(n)
+		}
+
+		if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
+			return o.copyExpr(n)
+		}
+		return n
+
+	case ir.OAPPEND:
+		// Check for append(x, make([]T, y)...) .
+		n := n.(*ir.CallExpr)
+		if isAppendOfMake(n) {
+			n.Args[0] = o.expr(n.Args[0], nil) // order x
+			mk := n.Args[1].(*ir.MakeExpr)
+			mk.Len = o.expr(mk.Len, nil) // order y
+		} else {
+			o.exprList(n.Args)
+		}
+
+		if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.Args[0]) {
+			return o.copyExpr(n)
+		}
+		return n
+
+	case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR:
+		n := n.(*ir.SliceExpr)
+		n.X = o.expr(n.X, nil)
+		n.Low = o.cheapExpr(o.expr(n.Low, nil))
+		n.High = o.cheapExpr(o.expr(n.High, nil))
+		n.Max = o.cheapExpr(o.expr(n.Max, nil))
+		if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.X) {
+			return o.copyExpr(n)
+		}
+		return n
+
+	case ir.OCLOSURE:
+		n := n.(*ir.ClosureExpr)
+		if n.Transient() && len(n.Func.ClosureVars) > 0 {
+			n.Prealloc = o.newTemp(typecheck.ClosureType(n), false)
+		}
+		return n
+
+	case ir.OCALLPART:
+		n := n.(*ir.SelectorExpr)
+		n.X = o.expr(n.X, nil)
+		if n.Transient() {
+			t := typecheck.PartialCallType(n)
+			n.Prealloc = o.newTemp(t, false)
+		}
+		return n
+
+	case ir.OSLICELIT:
+		n := n.(*ir.CompLitExpr)
+		o.exprList(n.List)
+		if n.Transient() {
+			t := types.NewArray(n.Type().Elem(), n.Len)
+			n.Prealloc = o.newTemp(t, false)
+		}
+		return n
+
+	case ir.ODOTTYPE, ir.ODOTTYPE2:
+		n := n.(*ir.TypeAssertExpr)
+		n.X = o.expr(n.X, nil)
+		if !types.IsDirectIface(n.Type()) || base.Flag.Cfg.Instrumenting {
+			return o.copyExprClear(n)
+		}
+		return n
+
+	case ir.ORECV:
+		n := n.(*ir.UnaryExpr)
+		n.X = o.expr(n.X, nil)
+		return o.copyExprClear(n)
+
+	case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
+		n := n.(*ir.BinaryExpr)
+		n.X = o.expr(n.X, nil)
+		n.Y = o.expr(n.Y, nil)
+
+		t := n.X.Type()
+		switch {
+		case t.IsString():
+			// Mark string(byteSlice) arguments to reuse byteSlice backing
+			// buffer during conversion. String comparison does not
+			// memorize the strings for later use, so it is safe.
+			if n.X.Op() == ir.OBYTES2STR {
+				n.X.(*ir.ConvExpr).SetOp(ir.OBYTES2STRTMP)
+			}
+			if n.Y.Op() == ir.OBYTES2STR {
+				n.Y.(*ir.ConvExpr).SetOp(ir.OBYTES2STRTMP)
+			}
+
+		case t.IsStruct() || t.IsArray():
+			// for complex comparisons, we need both args to be
+			// addressable so we can pass them to the runtime.
+			n.X = o.addrTemp(n.X)
+			n.Y = o.addrTemp(n.Y)
+		}
+		return n
+
+	case ir.OMAPLIT:
+		// Order map by converting:
+		//   map[int]int{
+		//     a(): b(),
+		//     c(): d(),
+		//     e(): f(),
+		//   }
+		// to
+		//   m := map[int]int{}
+		//   m[a()] = b()
+		//   m[c()] = d()
+		//   m[e()] = f()
+		// Then order the result.
+		// Without this special case, order would otherwise compute all
+		// the keys and values before storing any of them to the map.
+		// See issue 26552.
+		n := n.(*ir.CompLitExpr)
+		entries := n.List
+		statics := entries[:0]
+		var dynamics []*ir.KeyExpr
+		for _, r := range entries {
+			r := r.(*ir.KeyExpr)
+
+			if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
+				dynamics = append(dynamics, r)
+				continue
+			}
+
+			// Recursively ordering some static entries can change them to dynamic;
+			// e.g., OCONVIFACE nodes. See #31777.
+			r = o.expr(r, nil).(*ir.KeyExpr)
+			if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
+				dynamics = append(dynamics, r)
+				continue
+			}
+
+			statics = append(statics, r)
+		}
+		n.List = statics
+
+		if len(dynamics) == 0 {
+			return n
+		}
+
+		// Emit the creation of the map (with all its static entries).
+		m := o.newTemp(n.Type(), false)
+		as := ir.NewAssignStmt(base.Pos, m, n)
+		typecheck.Stmt(as)
+		o.stmt(as)
+
+		// Emit eval+insert of dynamic entries, one at a time.
+		for _, r := range dynamics {
+			as := ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, r.Key), r.Value)
+			typecheck.Stmt(as) // Note: this converts the OINDEX to an OINDEXMAP
+			o.stmt(as)
+		}
+		return m
+	}
+
+	// No return - type-assertions above. Each case must return for itself.
+}
+
+// as2func orders OAS2FUNC nodes. It creates temporaries to ensure left-to-right assignment.
+// The caller should order the right-hand side of the assignment before calling order.as2func.
+// It rewrites,
+//	a, b, a = ...
+// as
+//	tmp1, tmp2, tmp3 = ...
+//	a, b, a = tmp1, tmp2, tmp3
+// This is necessary to ensure left to right assignment order.
+func (o *orderState) as2func(n *ir.AssignListStmt) {
+	results := n.Rhs[0].Type()
+	as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
+	for i, nl := range n.Lhs {
+		if !ir.IsBlank(nl) {
+			typ := results.Field(i).Type
+			tmp := o.newTemp(typ, typ.HasPointers())
+			n.Lhs[i] = tmp
+			as.Lhs = append(as.Lhs, nl)
+			as.Rhs = append(as.Rhs, tmp)
+		}
+	}
+
+	o.out = append(o.out, n)
+	o.stmt(typecheck.Stmt(as))
+}
+
+// as2ok orders OAS2XXX with ok.
+// Just like as2func, this also adds temporaries to ensure left-to-right assignment.
+func (o *orderState) as2ok(n *ir.AssignListStmt) {
+	as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
+
+	do := func(i int, typ *types.Type) {
+		if nl := n.Lhs[i]; !ir.IsBlank(nl) {
+			var tmp ir.Node = o.newTemp(typ, typ.HasPointers())
+			n.Lhs[i] = tmp
+			as.Lhs = append(as.Lhs, nl)
+			if i == 1 {
+				// The "ok" result is an untyped boolean according to the Go
+				// spec. We need to explicitly convert it to the LHS type in
+				// case the latter is a defined boolean type (#8475).
+				tmp = typecheck.Conv(tmp, nl.Type())
+			}
+			as.Rhs = append(as.Rhs, tmp)
+		}
+	}
+
+	do(0, n.Rhs[0].Type())
+	do(1, types.Types[types.TBOOL])
+
+	o.out = append(o.out, n)
+	o.stmt(typecheck.Stmt(as))
+}
+
+var wrapGoDefer_prgen int
+
+// wrapGoDefer wraps the target of a "go" or "defer" statement with a
+// new "function with no arguments" closure. Specifically, it converts
+//
+//   defer f(x, y)
+//
+// to
+//
+//   x1, y1 := x, y
+//   defer func() { f(x1, y1) }()
+//
+// This is primarily to enable a quicker bringup of defers under the
+// new register ABI; by doing this conversion, we can simplify the
+// code in the runtime that invokes defers on the panic path.
+func (o *orderState) wrapGoDefer(n *ir.GoDeferStmt) {
+	call := n.Call
+
+	var callX ir.Node        // thing being called
+	var callArgs []ir.Node   // call arguments
+	var keepAlive []*ir.Name // KeepAlive list from call, if present
+
+	// A helper to recreate the call within the closure.
+	var mkNewCall func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node
+
+	// Defer calls come in many shapes and sizes; not all of them
+	// are ir.CallExpr's. Examine the type to see what we're dealing with.
+	switch x := call.(type) {
+	case *ir.CallExpr:
+		callX = x.X
+		callArgs = x.Args
+		keepAlive = x.KeepAlive
+		mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
+			newcall := ir.NewCallExpr(pos, op, fun, args)
+			newcall.IsDDD = x.IsDDD
+			return ir.Node(newcall)
+		}
+	case *ir.UnaryExpr: // ex: OCLOSE
+		callArgs = []ir.Node{x.X}
+		mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
+			if len(args) != 1 {
+				panic("internal error, expecting single arg")
+			}
+			return ir.Node(ir.NewUnaryExpr(pos, op, args[0]))
+		}
+	case *ir.BinaryExpr: // ex: OCOPY
+		callArgs = []ir.Node{x.X, x.Y}
+		mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
+			if len(args) != 2 {
+				panic("internal error, expecting two args")
+			}
+			return ir.Node(ir.NewBinaryExpr(pos, op, args[0], args[1]))
+		}
+	default:
+		panic("unhandled op")
+	}
+
+	// No need to wrap if called func has no args, no receiver, and no results.
+	// However in the case of "defer func() { ... }()" we need to
+	// protect against the possibility of directClosureCall rewriting
+	// things so that the call does have arguments.
+	//
+	// Do wrap method calls (OCALLMETH, OCALLINTER), because it has
+	// a receiver.
+	//
+	// Also do wrap builtin functions, because they may be expanded to
+	// calls with arguments (e.g. ORECOVER).
+	//
+	// TODO: maybe not wrap if the called function has no arguments and
+	// only in-register results?
+	if len(callArgs) == 0 && call.Op() == ir.OCALLFUNC && callX.Type().NumResults() == 0 {
+		if c, ok := call.(*ir.CallExpr); ok && callX != nil && callX.Op() == ir.OCLOSURE {
+			cloFunc := callX.(*ir.ClosureExpr).Func
+			cloFunc.SetClosureCalled(false)
+			c.PreserveClosure = true
+		}
+		return
+	}
+
+	if c, ok := call.(*ir.CallExpr); ok {
+		// To simplify things, turn f(a, b, []T{c, d, e}...) back
+		// into f(a, b, c, d, e) -- when the final call is run through the
+		// type checker below, it will rebuild the proper slice literal.
+		undoVariadic(c)
+		callX = c.X
+		callArgs = c.Args
+	}
+
+	// This is set to true if the closure we're generating escapes
+	// (needs heap allocation).
+	cloEscapes := func() bool {
+		if n.Op() == ir.OGO {
+			// For "go", assume that all closures escape.
+			return true
+		}
+		// For defer, just use whatever result escape analysis
+		// has determined for the defer.
+		return n.Esc() != ir.EscNever
+	}()
+
+	// A helper for making a copy of an argument. Note that it is
+	// not safe to use o.copyExpr(arg) if we're putting a
+	// reference to the temp into the closure (as opposed to
+	// copying it in by value), since in the by-reference case we
+	// need a temporary whose lifetime extends to the end of the
+	// function (as opposed to being local to the current block or
+	// statement being ordered).
+	mkArgCopy := func(arg ir.Node) *ir.Name {
+		t := arg.Type()
+		byval := t.Size() <= 128 || cloEscapes
+		var argCopy *ir.Name
+		if byval {
+			argCopy = o.copyExpr(arg)
+		} else {
+			argCopy = typecheck.Temp(t)
+			o.append(ir.NewAssignStmt(base.Pos, argCopy, arg))
+		}
+		// The value of 128 below is meant to be consistent with code
+		// in escape analysis that picks byval/byaddr based on size.
+		argCopy.SetByval(byval)
+		return argCopy
+	}
+
+	// getUnsafeArg looks for an unsafe.Pointer arg that has been
+	// previously captured into the call's keepalive list, returning
+	// the name node for it if found.
+	getUnsafeArg := func(arg ir.Node) *ir.Name {
+		// Look for uintptr(unsafe.Pointer(name))
+		if arg.Op() != ir.OCONVNOP {
+			return nil
+		}
+		if !arg.Type().IsUintptr() {
+			return nil
+		}
+		if !arg.(*ir.ConvExpr).X.Type().IsUnsafePtr() {
+			return nil
+		}
+		arg = arg.(*ir.ConvExpr).X
+		argname, ok := arg.(*ir.Name)
+		if !ok {
+			return nil
+		}
+		for i := range keepAlive {
+			if argname == keepAlive[i] {
+				return argname
+			}
+		}
+		return nil
+	}
+
+	// Copy the arguments to the function into temps.
+	//
+	// For calls with uintptr(unsafe.Pointer(...)) args that are being
+	// kept alive (see code in (*orderState).call that does this), use
+	// the existing arg copy instead of creating a new copy.
+	unsafeArgs := make([]*ir.Name, len(callArgs))
+	origArgs := callArgs
+	var newNames []*ir.Name
+	for i := range callArgs {
+		arg := callArgs[i]
+		var argname *ir.Name
+		unsafeArgName := getUnsafeArg(arg)
+		if unsafeArgName != nil {
+			// arg has been copied already, use keepalive copy
+			argname = unsafeArgName
+			unsafeArgs[i] = unsafeArgName
+		} else {
+			argname = mkArgCopy(arg)
+		}
+		newNames = append(newNames, argname)
+	}
+
+	// Deal with cases where the function expression (what we're
+	// calling) is not a simple function symbol.
+	var fnExpr *ir.Name
+	var methSelectorExpr *ir.SelectorExpr
+	if callX != nil {
+		switch {
+		case callX.Op() == ir.ODOTMETH || callX.Op() == ir.ODOTINTER:
+			// Handle defer of a method call, e.g. "defer v.MyMethod(x, y)"
+			n := callX.(*ir.SelectorExpr)
+			n.X = mkArgCopy(n.X)
+			methSelectorExpr = n
+			if callX.Op() == ir.ODOTINTER {
+				// Currently for "defer i.M()" if i is nil it panics at the
+				// point of defer statement, not when deferred function is called.
+				// (I think there is an issue discussing what is the intended
+				// behavior but I cannot find it.)
+				// We need to do the nil check outside of the wrapper.
+				tab := typecheck.Expr(ir.NewUnaryExpr(base.Pos, ir.OITAB, n.X))
+				c := ir.NewUnaryExpr(n.Pos(), ir.OCHECKNIL, tab)
+				c.SetTypecheck(1)
+				o.append(c)
+			}
+		case !(callX.Op() == ir.ONAME && callX.(*ir.Name).Class == ir.PFUNC):
+			// Deal with "defer returnsafunc()(x, y)" (for
+			// example) by copying the callee expression.
+			fnExpr = mkArgCopy(callX)
+			if callX.Op() == ir.OCLOSURE {
+				// For "defer func(...)", in addition to copying the
+				// closure into a temp, mark it as no longer directly
+				// called.
+				callX.(*ir.ClosureExpr).Func.SetClosureCalled(false)
+			}
+		}
+	}
+
+	// Create a new no-argument function that we'll hand off to defer.
+	var noFuncArgs []*ir.Field
+	noargst := ir.NewFuncType(base.Pos, nil, noFuncArgs, nil)
+	wrapGoDefer_prgen++
+	outerfn := ir.CurFunc
+	wrapname := fmt.Sprintf("%v·dwrap·%d", outerfn, wrapGoDefer_prgen)
+	sym := types.LocalPkg.Lookup(wrapname)
+	fn := typecheck.DeclFunc(sym, noargst)
+	fn.SetIsHiddenClosure(true)
+	fn.SetWrapper(true)
+
+	// helper for capturing reference to a var declared in an outer scope.
+	capName := func(pos src.XPos, fn *ir.Func, n *ir.Name) *ir.Name {
+		t := n.Type()
+		cv := ir.CaptureName(pos, fn, n)
+		cv.SetType(t)
+		return typecheck.Expr(cv).(*ir.Name)
+	}
+
+	// Call args (x1, y1) need to be captured as part of the newly
+	// created closure.
+	newCallArgs := []ir.Node{}
+	for i := range newNames {
+		var arg ir.Node
+		arg = capName(callArgs[i].Pos(), fn, newNames[i])
+		if unsafeArgs[i] != nil {
+			arg = ir.NewConvExpr(arg.Pos(), origArgs[i].Op(), origArgs[i].Type(), arg)
+		}
+		newCallArgs = append(newCallArgs, arg)
+	}
+	// Also capture the function or method expression (if needed) into
+	// the closure.
+	if fnExpr != nil {
+		callX = capName(callX.Pos(), fn, fnExpr)
+	}
+	if methSelectorExpr != nil {
+		methSelectorExpr.X = capName(callX.Pos(), fn, methSelectorExpr.X.(*ir.Name))
+	}
+	ir.FinishCaptureNames(n.Pos(), outerfn, fn)
+
+	// This flags a builtin as opposed to a regular call.
+	irregular := (call.Op() != ir.OCALLFUNC &&
+		call.Op() != ir.OCALLMETH &&
+		call.Op() != ir.OCALLINTER)
+
+	// Construct new function body:  f(x1, y1)
+	op := ir.OCALL
+	if irregular {
+		op = call.Op()
+	}
+	newcall := mkNewCall(call.Pos(), op, callX, newCallArgs)
+
+	// Type-check the result.
+	if !irregular {
+		typecheck.Call(newcall.(*ir.CallExpr))
+	} else {
+		typecheck.Stmt(newcall)
+	}
+
+	// Finalize body, register function on the main decls list.
+	fn.Body = []ir.Node{newcall}
+	typecheck.FinishFuncBody()
+	typecheck.Func(fn)
+	typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
+
+	// Create closure expr
+	clo := ir.NewClosureExpr(n.Pos(), fn)
+	fn.OClosure = clo
+	clo.SetType(fn.Type())
+
+	// Set escape properties for closure.
+	if n.Op() == ir.OGO {
+		// For "go", assume that the closure is going to escape
+		// (with an exception for the runtime, which doesn't
+		// permit heap-allocated closures).
+		if base.Ctxt.Pkgpath != "runtime" {
+			clo.SetEsc(ir.EscHeap)
+		}
+	} else {
+		// For defer, just use whatever result escape analysis
+		// has determined for the defer.
+		if n.Esc() == ir.EscNever {
+			clo.SetTransient(true)
+			clo.SetEsc(ir.EscNone)
+		}
+	}
+
+	// Create new top level call to closure over argless function.
+	topcall := ir.NewCallExpr(n.Pos(), ir.OCALL, clo, []ir.Node{})
+	typecheck.Call(topcall)
+
+	// Tag the call to insure that directClosureCall doesn't undo our work.
+	topcall.PreserveClosure = true
+
+	fn.SetClosureCalled(false)
+
+	// Finally, point the defer statement at the newly generated call.
+	n.Call = topcall
+}
+
+// isFuncPCIntrinsic returns whether n is a direct call of internal/abi.FuncPCABIxxx functions.
+func isFuncPCIntrinsic(n *ir.CallExpr) bool {
+	if n.Op() != ir.OCALLFUNC || n.X.Op() != ir.ONAME {
+		return false
+	}
+	fn := n.X.(*ir.Name).Sym()
+	return (fn.Name == "FuncPCABI0" || fn.Name == "FuncPCABIInternal") &&
+		(fn.Pkg.Path == "internal/abi" || fn.Pkg == types.LocalPkg && base.Ctxt.Pkgpath == "internal/abi")
+}
+
+// isIfaceOfFunc returns whether n is an interface conversion from a direct reference of a func.
+func isIfaceOfFunc(n ir.Node) bool {
+	return n.Op() == ir.OCONVIFACE && n.(*ir.ConvExpr).X.Op() == ir.ONAME && n.(*ir.ConvExpr).X.(*ir.Name).Class == ir.PFUNC
+}
diff --git a/src/cmd/compile/internal/walk/race.go b/src/cmd/compile/internal/walk/race.go
new file mode 100644
index 0000000..859e5c5
--- /dev/null
+++ b/src/cmd/compile/internal/walk/race.go
@@ -0,0 +1,34 @@
+// 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 walk
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+func instrument(fn *ir.Func) {
+	if fn.Pragma&ir.Norace != 0 || (fn.Linksym() != nil && fn.Linksym().ABIWrapper()) {
+		return
+	}
+
+	if !base.Flag.Race || !base.Compiling(base.NoRacePkgs) {
+		fn.SetInstrumentBody(true)
+	}
+
+	if base.Flag.Race {
+		lno := base.Pos
+		base.Pos = src.NoXPos
+		var init ir.Nodes
+		fn.Enter.Prepend(mkcallstmt("racefuncenter", mkcall("getcallerpc", types.Types[types.TUINTPTR], &init)))
+		if len(init) != 0 {
+			base.Fatalf("race walk: unexpected init for getcallerpc")
+		}
+		fn.Exit.Append(mkcallstmt("racefuncexit"))
+		base.Pos = lno
+	}
+}
diff --git a/src/cmd/compile/internal/walk/range.go b/src/cmd/compile/internal/walk/range.go
new file mode 100644
index 0000000..b1169fd
--- /dev/null
+++ b/src/cmd/compile/internal/walk/range.go
@@ -0,0 +1,475 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"unicode/utf8"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/ssagen"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/sys"
+)
+
+func cheapComputableIndex(width int64) bool {
+	switch ssagen.Arch.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
+		}
+	}
+	return false
+}
+
+// walkRange transforms various forms of ORANGE into
+// simpler forms.  The result must be assigned back to n.
+// Node n may also be modified in place, and may also be
+// the returned node.
+func walkRange(nrange *ir.RangeStmt) ir.Node {
+	if isMapClear(nrange) {
+		m := nrange.X
+		lno := ir.SetPos(m)
+		n := mapClear(m)
+		base.Pos = lno
+		return n
+	}
+
+	nfor := ir.NewForStmt(nrange.Pos(), nil, nil, nil, nil)
+	nfor.SetInit(nrange.Init())
+	nfor.Label = nrange.Label
+
+	// variable name conventions:
+	//	ohv1, hv1, hv2: hidden (old) val 1, 2
+	//	ha, hit: hidden aggregate, iterator
+	//	hn, hp: hidden len, pointer
+	//	hb: hidden bool
+	//	a, v1, v2: not hidden aggregate, val 1, 2
+
+	a := nrange.X
+	t := typecheck.RangeExprType(a.Type())
+	lno := ir.SetPos(a)
+
+	v1, v2 := nrange.Key, nrange.Value
+
+	if ir.IsBlank(v2) {
+		v2 = nil
+	}
+
+	if ir.IsBlank(v1) && v2 == nil {
+		v1 = nil
+	}
+
+	if v1 == nil && v2 != nil {
+		base.Fatalf("walkRange: v2 != nil while v1 == nil")
+	}
+
+	var ifGuard *ir.IfStmt
+
+	var body []ir.Node
+	var init []ir.Node
+	switch t.Kind() {
+	default:
+		base.Fatalf("walkRange")
+
+	case types.TARRAY, types.TSLICE:
+		if nn := arrayClear(nrange, v1, v2, a); nn != nil {
+			base.Pos = lno
+			return nn
+		}
+
+		// order.stmt arranged for a copy of the array/slice variable if needed.
+		ha := a
+
+		hv1 := typecheck.Temp(types.Types[types.TINT])
+		hn := typecheck.Temp(types.Types[types.TINT])
+
+		init = append(init, ir.NewAssignStmt(base.Pos, hv1, nil))
+		init = append(init, ir.NewAssignStmt(base.Pos, hn, ir.NewUnaryExpr(base.Pos, ir.OLEN, ha)))
+
+		nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, hv1, hn)
+		nfor.Post = ir.NewAssignStmt(base.Pos, hv1, ir.NewBinaryExpr(base.Pos, ir.OADD, hv1, ir.NewInt(1)))
+
+		// for range ha { body }
+		if v1 == nil {
+			break
+		}
+
+		// for v1 := range ha { body }
+		if v2 == nil {
+			body = []ir.Node{ir.NewAssignStmt(base.Pos, v1, hv1)}
+			break
+		}
+
+		// for v1, v2 := range ha { body }
+		if cheapComputableIndex(t.Elem().Width) {
+			// v1, v2 = hv1, ha[hv1]
+			tmp := ir.NewIndexExpr(base.Pos, ha, hv1)
+			tmp.SetBounded(true)
+			// Use OAS2 to correctly handle assignments
+			// of the form "v1, a[v1] := range".
+			a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{v1, v2}, []ir.Node{hv1, tmp})
+			body = []ir.Node{a}
+			break
+		}
+
+		// TODO(austin): OFORUNTIL is a strange beast, but is
+		// necessary for expressing the control flow we need
+		// while also making "break" and "continue" work. It
+		// would be nice to just lower ORANGE during SSA, but
+		// racewalk needs to see many of the operations
+		// involved in ORANGE's implementation. If racewalk
+		// moves into SSA, consider moving ORANGE into SSA and
+		// eliminating OFORUNTIL.
+
+		// TODO(austin): OFORUNTIL inhibits bounds-check
+		// elimination on the index variable (see #20711).
+		// Enhance the prove pass to understand this.
+		ifGuard = ir.NewIfStmt(base.Pos, nil, nil, nil)
+		ifGuard.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, hv1, hn)
+		nfor.SetOp(ir.OFORUNTIL)
+
+		hp := typecheck.Temp(types.NewPtr(t.Elem()))
+		tmp := ir.NewIndexExpr(base.Pos, ha, ir.NewInt(0))
+		tmp.SetBounded(true)
+		init = append(init, ir.NewAssignStmt(base.Pos, hp, typecheck.NodAddr(tmp)))
+
+		// Use OAS2 to correctly handle assignments
+		// of the form "v1, a[v1] := range".
+		a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{v1, v2}, []ir.Node{hv1, ir.NewStarExpr(base.Pos, hp)})
+		body = append(body, a)
+
+		// Advance pointer as part of the late increment.
+		//
+		// This runs *after* the condition check, so we know
+		// advancing the pointer is safe and won't go past the
+		// end of the allocation.
+		as := ir.NewAssignStmt(base.Pos, hp, addptr(hp, t.Elem().Width))
+		nfor.Late = []ir.Node{typecheck.Stmt(as)}
+
+	case types.TMAP:
+		// order.stmt allocated the iterator for us.
+		// we only use a once, so no copy needed.
+		ha := a
+
+		hit := nrange.Prealloc
+		th := hit.Type()
+		// depends on layout of iterator struct.
+		// See cmd/compile/internal/reflectdata/reflect.go:MapIterType
+		keysym := th.Field(0).Sym
+		elemsym := th.Field(1).Sym // ditto
+
+		fn := typecheck.LookupRuntime("mapiterinit")
+
+		fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), th)
+		init = append(init, mkcallstmt1(fn, reflectdata.TypePtr(t), ha, typecheck.NodAddr(hit)))
+		nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, ir.NewSelectorExpr(base.Pos, ir.ODOT, hit, keysym), typecheck.NodNil())
+
+		fn = typecheck.LookupRuntime("mapiternext")
+		fn = typecheck.SubstArgTypes(fn, th)
+		nfor.Post = mkcallstmt1(fn, typecheck.NodAddr(hit))
+
+		key := ir.NewStarExpr(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, hit, keysym))
+		if v1 == nil {
+			body = nil
+		} else if v2 == nil {
+			body = []ir.Node{ir.NewAssignStmt(base.Pos, v1, key)}
+		} else {
+			elem := ir.NewStarExpr(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, hit, elemsym))
+			a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{v1, v2}, []ir.Node{key, elem})
+			body = []ir.Node{a}
+		}
+
+	case types.TCHAN:
+		// order.stmt arranged for a copy of the channel variable.
+		ha := a
+
+		hv1 := typecheck.Temp(t.Elem())
+		hv1.SetTypecheck(1)
+		if t.Elem().HasPointers() {
+			init = append(init, ir.NewAssignStmt(base.Pos, hv1, nil))
+		}
+		hb := typecheck.Temp(types.Types[types.TBOOL])
+
+		nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, hb, ir.NewBool(false))
+		lhs := []ir.Node{hv1, hb}
+		rhs := []ir.Node{ir.NewUnaryExpr(base.Pos, ir.ORECV, ha)}
+		a := ir.NewAssignListStmt(base.Pos, ir.OAS2RECV, lhs, rhs)
+		a.SetTypecheck(1)
+		nfor.Cond = ir.InitExpr([]ir.Node{a}, nfor.Cond)
+		if v1 == nil {
+			body = nil
+		} else {
+			body = []ir.Node{ir.NewAssignStmt(base.Pos, v1, hv1)}
+		}
+		// Zero hv1. This prevents hv1 from being the sole, inaccessible
+		// reference to an otherwise GC-able value during the next channel receive.
+		// See issue 15281.
+		body = append(body, ir.NewAssignStmt(base.Pos, hv1, nil))
+
+	case types.TSTRING:
+		// Transform string range statements like "for v1, v2 = range a" into
+		//
+		// ha := a
+		// for hv1 := 0; hv1 < len(ha); {
+		//   hv1t := hv1
+		//   hv2 := rune(ha[hv1])
+		//   if hv2 < utf8.RuneSelf {
+		//      hv1++
+		//   } else {
+		//      hv2, hv1 = decoderune(ha, hv1)
+		//   }
+		//   v1, v2 = hv1t, hv2
+		//   // original body
+		// }
+
+		// order.stmt arranged for a copy of the string variable.
+		ha := a
+
+		hv1 := typecheck.Temp(types.Types[types.TINT])
+		hv1t := typecheck.Temp(types.Types[types.TINT])
+		hv2 := typecheck.Temp(types.RuneType)
+
+		// hv1 := 0
+		init = append(init, ir.NewAssignStmt(base.Pos, hv1, nil))
+
+		// hv1 < len(ha)
+		nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, hv1, ir.NewUnaryExpr(base.Pos, ir.OLEN, ha))
+
+		if v1 != nil {
+			// hv1t = hv1
+			body = append(body, ir.NewAssignStmt(base.Pos, hv1t, hv1))
+		}
+
+		// hv2 := rune(ha[hv1])
+		nind := ir.NewIndexExpr(base.Pos, ha, hv1)
+		nind.SetBounded(true)
+		body = append(body, ir.NewAssignStmt(base.Pos, hv2, typecheck.Conv(nind, types.RuneType)))
+
+		// if hv2 < utf8.RuneSelf
+		nif := ir.NewIfStmt(base.Pos, nil, nil, nil)
+		nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, hv2, ir.NewInt(utf8.RuneSelf))
+
+		// hv1++
+		nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, hv1, ir.NewBinaryExpr(base.Pos, ir.OADD, hv1, ir.NewInt(1)))}
+
+		// } else {
+		// hv2, hv1 = decoderune(ha, hv1)
+		fn := typecheck.LookupRuntime("decoderune")
+		call := mkcall1(fn, fn.Type().Results(), &nif.Else, ha, hv1)
+		a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{hv2, hv1}, []ir.Node{call})
+		nif.Else.Append(a)
+
+		body = append(body, nif)
+
+		if v1 != nil {
+			if v2 != nil {
+				// v1, v2 = hv1t, hv2
+				a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{v1, v2}, []ir.Node{hv1t, hv2})
+				body = append(body, a)
+			} else {
+				// v1 = hv1t
+				body = append(body, ir.NewAssignStmt(base.Pos, v1, hv1t))
+			}
+		}
+	}
+
+	typecheck.Stmts(init)
+
+	if ifGuard != nil {
+		ifGuard.PtrInit().Append(init...)
+		ifGuard = typecheck.Stmt(ifGuard).(*ir.IfStmt)
+	} else {
+		nfor.PtrInit().Append(init...)
+	}
+
+	typecheck.Stmts(nfor.Cond.Init())
+
+	nfor.Cond = typecheck.Expr(nfor.Cond)
+	nfor.Cond = typecheck.DefaultLit(nfor.Cond, nil)
+	nfor.Post = typecheck.Stmt(nfor.Post)
+	typecheck.Stmts(body)
+	nfor.Body.Append(body...)
+	nfor.Body.Append(nrange.Body...)
+
+	var n ir.Node = nfor
+	if ifGuard != nil {
+		ifGuard.Body = []ir.Node{n}
+		n = ifGuard
+	}
+
+	n = walkStmt(n)
+
+	base.Pos = lno
+	return n
+}
+
+// isMapClear checks if n is of the form:
+//
+// for k := range m {
+//   delete(m, k)
+// }
+//
+// where == for keys of map m is reflexive.
+func isMapClear(n *ir.RangeStmt) bool {
+	if base.Flag.N != 0 || base.Flag.Cfg.Instrumenting {
+		return false
+	}
+
+	t := n.X.Type()
+	if n.Op() != ir.ORANGE || t.Kind() != types.TMAP || n.Key == nil || n.Value != nil {
+		return false
+	}
+
+	k := n.Key
+	// Require k to be a new variable name.
+	if !ir.DeclaredBy(k, n) {
+		return false
+	}
+
+	if len(n.Body) != 1 {
+		return false
+	}
+
+	stmt := n.Body[0] // only stmt in body
+	if stmt == nil || stmt.Op() != ir.ODELETE {
+		return false
+	}
+
+	m := n.X
+	if delete := stmt.(*ir.CallExpr); !ir.SameSafeExpr(delete.Args[0], m) || !ir.SameSafeExpr(delete.Args[1], k) {
+		return false
+	}
+
+	// Keys where equality is not reflexive can not be deleted from maps.
+	if !types.IsReflexive(t.Key()) {
+		return false
+	}
+
+	return true
+}
+
+// mapClear constructs a call to runtime.mapclear for the map m.
+func mapClear(m ir.Node) ir.Node {
+	t := m.Type()
+
+	// instantiate mapclear(typ *type, hmap map[any]any)
+	fn := typecheck.LookupRuntime("mapclear")
+	fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem())
+	n := mkcallstmt1(fn, reflectdata.TypePtr(t), m)
+	return walkStmt(typecheck.Stmt(n))
+}
+
+// Lower n into runtime·memclr if possible, for
+// fast zeroing of slices and arrays (issue 5373).
+// Look for instances of
+//
+// for i := range a {
+// 	a[i] = zero
+// }
+//
+// in which the evaluation of a is side-effect-free.
+//
+// Parameters are as in walkRange: "for v1, v2 = range a".
+func arrayClear(loop *ir.RangeStmt, v1, v2, a ir.Node) ir.Node {
+	if base.Flag.N != 0 || base.Flag.Cfg.Instrumenting {
+		return nil
+	}
+
+	if v1 == nil || v2 != nil {
+		return nil
+	}
+
+	if len(loop.Body) != 1 || loop.Body[0] == nil {
+		return nil
+	}
+
+	stmt1 := loop.Body[0] // only stmt in body
+	if stmt1.Op() != ir.OAS {
+		return nil
+	}
+	stmt := stmt1.(*ir.AssignStmt)
+	if stmt.X.Op() != ir.OINDEX {
+		return nil
+	}
+	lhs := stmt.X.(*ir.IndexExpr)
+
+	if !ir.SameSafeExpr(lhs.X, a) || !ir.SameSafeExpr(lhs.Index, v1) {
+		return nil
+	}
+
+	elemsize := typecheck.RangeExprType(loop.X.Type()).Elem().Width
+	if elemsize <= 0 || !ir.IsZero(stmt.Y) {
+		return nil
+	}
+
+	// Convert to
+	// if len(a) != 0 {
+	// 	hp = &a[0]
+	// 	hn = len(a)*sizeof(elem(a))
+	// 	memclr{NoHeap,Has}Pointers(hp, hn)
+	// 	i = len(a) - 1
+	// }
+	n := ir.NewIfStmt(base.Pos, nil, nil, nil)
+	n.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), ir.NewInt(0))
+
+	// hp = &a[0]
+	hp := typecheck.Temp(types.Types[types.TUNSAFEPTR])
+
+	ix := ir.NewIndexExpr(base.Pos, a, ir.NewInt(0))
+	ix.SetBounded(true)
+	addr := typecheck.ConvNop(typecheck.NodAddr(ix), types.Types[types.TUNSAFEPTR])
+	n.Body.Append(ir.NewAssignStmt(base.Pos, hp, addr))
+
+	// hn = len(a) * sizeof(elem(a))
+	hn := typecheck.Temp(types.Types[types.TUINTPTR])
+	mul := typecheck.Conv(ir.NewBinaryExpr(base.Pos, ir.OMUL, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), ir.NewInt(elemsize)), types.Types[types.TUINTPTR])
+	n.Body.Append(ir.NewAssignStmt(base.Pos, hn, mul))
+
+	var fn ir.Node
+	if a.Type().Elem().HasPointers() {
+		// memclrHasPointers(hp, hn)
+		ir.CurFunc.SetWBPos(stmt.Pos())
+		fn = mkcallstmt("memclrHasPointers", hp, hn)
+	} else {
+		// memclrNoHeapPointers(hp, hn)
+		fn = mkcallstmt("memclrNoHeapPointers", hp, hn)
+	}
+
+	n.Body.Append(fn)
+
+	// i = len(a) - 1
+	v1 = ir.NewAssignStmt(base.Pos, v1, ir.NewBinaryExpr(base.Pos, ir.OSUB, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), ir.NewInt(1)))
+
+	n.Body.Append(v1)
+
+	n.Cond = typecheck.Expr(n.Cond)
+	n.Cond = typecheck.DefaultLit(n.Cond, nil)
+	typecheck.Stmts(n.Body)
+	return walkStmt(n)
+}
+
+// addptr returns (*T)(uintptr(p) + n).
+func addptr(p ir.Node, n int64) ir.Node {
+	t := p.Type()
+
+	p = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, p)
+	p.SetType(types.Types[types.TUINTPTR])
+
+	p = ir.NewBinaryExpr(base.Pos, ir.OADD, p, ir.NewInt(n))
+
+	p = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, p)
+	p.SetType(t)
+
+	return p
+}
diff --git a/src/cmd/compile/internal/walk/select.go b/src/cmd/compile/internal/walk/select.go
new file mode 100644
index 0000000..d2b67dd
--- /dev/null
+++ b/src/cmd/compile/internal/walk/select.go
@@ -0,0 +1,291 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+)
+
+func walkSelect(sel *ir.SelectStmt) {
+	lno := ir.SetPos(sel)
+	if sel.Walked() {
+		base.Fatalf("double walkSelect")
+	}
+	sel.SetWalked(true)
+
+	init := ir.TakeInit(sel)
+
+	init = append(init, walkSelectCases(sel.Cases)...)
+	sel.Cases = nil
+
+	sel.Compiled = init
+	walkStmtList(sel.Compiled)
+
+	base.Pos = lno
+}
+
+func walkSelectCases(cases []*ir.CommClause) []ir.Node {
+	ncas := len(cases)
+	sellineno := base.Pos
+
+	// optimization: zero-case select
+	if ncas == 0 {
+		return []ir.Node{mkcallstmt("block")}
+	}
+
+	// optimization: one-case select: single op.
+	if ncas == 1 {
+		cas := cases[0]
+		ir.SetPos(cas)
+		l := cas.Init()
+		if cas.Comm != nil { // not default:
+			n := cas.Comm
+			l = append(l, ir.TakeInit(n)...)
+			switch n.Op() {
+			default:
+				base.Fatalf("select %v", n.Op())
+
+			case ir.OSEND:
+				// already ok
+
+			case ir.OSELRECV2:
+				r := n.(*ir.AssignListStmt)
+				if ir.IsBlank(r.Lhs[0]) && ir.IsBlank(r.Lhs[1]) {
+					n = r.Rhs[0]
+					break
+				}
+				r.SetOp(ir.OAS2RECV)
+			}
+
+			l = append(l, n)
+		}
+
+		l = append(l, cas.Body...)
+		l = append(l, ir.NewBranchStmt(base.Pos, ir.OBREAK, nil))
+		return l
+	}
+
+	// convert case value arguments to addresses.
+	// this rewrite is used by both the general code and the next optimization.
+	var dflt *ir.CommClause
+	for _, cas := range cases {
+		ir.SetPos(cas)
+		n := cas.Comm
+		if n == nil {
+			dflt = cas
+			continue
+		}
+		switch n.Op() {
+		case ir.OSEND:
+			n := n.(*ir.SendStmt)
+			n.Value = typecheck.NodAddr(n.Value)
+			n.Value = typecheck.Expr(n.Value)
+
+		case ir.OSELRECV2:
+			n := n.(*ir.AssignListStmt)
+			if !ir.IsBlank(n.Lhs[0]) {
+				n.Lhs[0] = typecheck.NodAddr(n.Lhs[0])
+				n.Lhs[0] = typecheck.Expr(n.Lhs[0])
+			}
+		}
+	}
+
+	// optimization: two-case select but one is default: single non-blocking op.
+	if ncas == 2 && dflt != nil {
+		cas := cases[0]
+		if cas == dflt {
+			cas = cases[1]
+		}
+
+		n := cas.Comm
+		ir.SetPos(n)
+		r := ir.NewIfStmt(base.Pos, nil, nil, nil)
+		*r.PtrInit() = cas.Init()
+		var cond ir.Node
+		switch n.Op() {
+		default:
+			base.Fatalf("select %v", n.Op())
+
+		case ir.OSEND:
+			// if selectnbsend(c, v) { body } else { default body }
+			n := n.(*ir.SendStmt)
+			ch := n.Chan
+			cond = mkcall1(chanfn("selectnbsend", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), ch, n.Value)
+
+		case ir.OSELRECV2:
+			n := n.(*ir.AssignListStmt)
+			recv := n.Rhs[0].(*ir.UnaryExpr)
+			ch := recv.X
+			elem := n.Lhs[0]
+			if ir.IsBlank(elem) {
+				elem = typecheck.NodNil()
+			}
+			cond = typecheck.Temp(types.Types[types.TBOOL])
+			fn := chanfn("selectnbrecv", 2, ch.Type())
+			call := mkcall1(fn, fn.Type().Results(), r.PtrInit(), elem, ch)
+			as := ir.NewAssignListStmt(r.Pos(), ir.OAS2, []ir.Node{cond, n.Lhs[1]}, []ir.Node{call})
+			r.PtrInit().Append(typecheck.Stmt(as))
+		}
+
+		r.Cond = typecheck.Expr(cond)
+		r.Body = cas.Body
+		r.Else = append(dflt.Init(), dflt.Body...)
+		return []ir.Node{r, ir.NewBranchStmt(base.Pos, ir.OBREAK, nil)}
+	}
+
+	if dflt != nil {
+		ncas--
+	}
+	casorder := make([]*ir.CommClause, ncas)
+	nsends, nrecvs := 0, 0
+
+	var init []ir.Node
+
+	// generate sel-struct
+	base.Pos = sellineno
+	selv := typecheck.Temp(types.NewArray(scasetype(), int64(ncas)))
+	init = append(init, typecheck.Stmt(ir.NewAssignStmt(base.Pos, selv, nil)))
+
+	// No initialization for order; runtime.selectgo is responsible for that.
+	order := typecheck.Temp(types.NewArray(types.Types[types.TUINT16], 2*int64(ncas)))
+
+	var pc0, pcs ir.Node
+	if base.Flag.Race {
+		pcs = typecheck.Temp(types.NewArray(types.Types[types.TUINTPTR], int64(ncas)))
+		pc0 = typecheck.Expr(typecheck.NodAddr(ir.NewIndexExpr(base.Pos, pcs, ir.NewInt(0))))
+	} else {
+		pc0 = typecheck.NodNil()
+	}
+
+	// register cases
+	for _, cas := range cases {
+		ir.SetPos(cas)
+
+		init = append(init, ir.TakeInit(cas)...)
+
+		n := cas.Comm
+		if n == nil { // default:
+			continue
+		}
+
+		var i int
+		var c, elem ir.Node
+		switch n.Op() {
+		default:
+			base.Fatalf("select %v", n.Op())
+		case ir.OSEND:
+			n := n.(*ir.SendStmt)
+			i = nsends
+			nsends++
+			c = n.Chan
+			elem = n.Value
+		case ir.OSELRECV2:
+			n := n.(*ir.AssignListStmt)
+			nrecvs++
+			i = ncas - nrecvs
+			recv := n.Rhs[0].(*ir.UnaryExpr)
+			c = recv.X
+			elem = n.Lhs[0]
+		}
+
+		casorder[i] = cas
+
+		setField := func(f string, val ir.Node) {
+			r := ir.NewAssignStmt(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, ir.NewIndexExpr(base.Pos, selv, ir.NewInt(int64(i))), typecheck.Lookup(f)), val)
+			init = append(init, typecheck.Stmt(r))
+		}
+
+		c = typecheck.ConvNop(c, types.Types[types.TUNSAFEPTR])
+		setField("c", c)
+		if !ir.IsBlank(elem) {
+			elem = typecheck.ConvNop(elem, types.Types[types.TUNSAFEPTR])
+			setField("elem", elem)
+		}
+
+		// TODO(mdempsky): There should be a cleaner way to
+		// handle this.
+		if base.Flag.Race {
+			r := mkcallstmt("selectsetpc", typecheck.NodAddr(ir.NewIndexExpr(base.Pos, pcs, ir.NewInt(int64(i)))))
+			init = append(init, r)
+		}
+	}
+	if nsends+nrecvs != ncas {
+		base.Fatalf("walkSelectCases: miscount: %v + %v != %v", nsends, nrecvs, ncas)
+	}
+
+	// run the select
+	base.Pos = sellineno
+	chosen := typecheck.Temp(types.Types[types.TINT])
+	recvOK := typecheck.Temp(types.Types[types.TBOOL])
+	r := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil)
+	r.Lhs = []ir.Node{chosen, recvOK}
+	fn := typecheck.LookupRuntime("selectgo")
+	var fnInit ir.Nodes
+	r.Rhs = []ir.Node{mkcall1(fn, fn.Type().Results(), &fnInit, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), pc0, ir.NewInt(int64(nsends)), ir.NewInt(int64(nrecvs)), ir.NewBool(dflt == nil))}
+	init = append(init, fnInit...)
+	init = append(init, typecheck.Stmt(r))
+
+	// selv and order are no longer alive after selectgo.
+	init = append(init, ir.NewUnaryExpr(base.Pos, ir.OVARKILL, selv))
+	init = append(init, ir.NewUnaryExpr(base.Pos, ir.OVARKILL, order))
+	if base.Flag.Race {
+		init = append(init, ir.NewUnaryExpr(base.Pos, ir.OVARKILL, pcs))
+	}
+
+	// dispatch cases
+	dispatch := func(cond ir.Node, cas *ir.CommClause) {
+		cond = typecheck.Expr(cond)
+		cond = typecheck.DefaultLit(cond, nil)
+
+		r := ir.NewIfStmt(base.Pos, cond, nil, nil)
+
+		if n := cas.Comm; n != nil && n.Op() == ir.OSELRECV2 {
+			n := n.(*ir.AssignListStmt)
+			if !ir.IsBlank(n.Lhs[1]) {
+				x := ir.NewAssignStmt(base.Pos, n.Lhs[1], recvOK)
+				r.Body.Append(typecheck.Stmt(x))
+			}
+		}
+
+		r.Body.Append(cas.Body.Take()...)
+		r.Body.Append(ir.NewBranchStmt(base.Pos, ir.OBREAK, nil))
+		init = append(init, r)
+	}
+
+	if dflt != nil {
+		ir.SetPos(dflt)
+		dispatch(ir.NewBinaryExpr(base.Pos, ir.OLT, chosen, ir.NewInt(0)), dflt)
+	}
+	for i, cas := range casorder {
+		ir.SetPos(cas)
+		dispatch(ir.NewBinaryExpr(base.Pos, ir.OEQ, chosen, ir.NewInt(int64(i))), cas)
+	}
+
+	return init
+}
+
+// bytePtrToIndex returns a Node representing "(*byte)(&n[i])".
+func bytePtrToIndex(n ir.Node, i int64) ir.Node {
+	s := typecheck.NodAddr(ir.NewIndexExpr(base.Pos, n, ir.NewInt(i)))
+	t := types.NewPtr(types.Types[types.TUINT8])
+	return typecheck.ConvNop(s, t)
+}
+
+var scase *types.Type
+
+// Keep in sync with src/runtime/select.go.
+func scasetype() *types.Type {
+	if scase == nil {
+		scase = types.NewStruct(types.NoPkg, []*types.Field{
+			types.NewField(base.Pos, typecheck.Lookup("c"), types.Types[types.TUNSAFEPTR]),
+			types.NewField(base.Pos, typecheck.Lookup("elem"), types.Types[types.TUNSAFEPTR]),
+		})
+		scase.SetNoalg(true)
+	}
+	return scase
+}
diff --git a/src/cmd/compile/internal/walk/stmt.go b/src/cmd/compile/internal/walk/stmt.go
new file mode 100644
index 0000000..0bf7668
--- /dev/null
+++ b/src/cmd/compile/internal/walk/stmt.go
@@ -0,0 +1,337 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+)
+
+// The result of walkStmt MUST be assigned back to n, e.g.
+// 	n.Left = walkStmt(n.Left)
+func walkStmt(n ir.Node) ir.Node {
+	if n == nil {
+		return n
+	}
+
+	ir.SetPos(n)
+
+	walkStmtList(n.Init())
+
+	switch n.Op() {
+	default:
+		if n.Op() == ir.ONAME {
+			n := n.(*ir.Name)
+			base.Errorf("%v is not a top level statement", n.Sym())
+		} else {
+			base.Errorf("%v is not a top level statement", n.Op())
+		}
+		ir.Dump("nottop", n)
+		return n
+
+	case ir.OAS,
+		ir.OASOP,
+		ir.OAS2,
+		ir.OAS2DOTTYPE,
+		ir.OAS2RECV,
+		ir.OAS2FUNC,
+		ir.OAS2MAPR,
+		ir.OCLOSE,
+		ir.OCOPY,
+		ir.OCALLMETH,
+		ir.OCALLINTER,
+		ir.OCALL,
+		ir.OCALLFUNC,
+		ir.ODELETE,
+		ir.OSEND,
+		ir.OPRINT,
+		ir.OPRINTN,
+		ir.OPANIC,
+		ir.ORECOVER,
+		ir.OGETG:
+		if n.Typecheck() == 0 {
+			base.Fatalf("missing typecheck: %+v", n)
+		}
+		init := ir.TakeInit(n)
+		n = walkExpr(n, &init)
+		if n.Op() == ir.ONAME {
+			// copy rewrote to a statement list and a temp for the length.
+			// Throw away the temp to avoid plain values as statements.
+			n = ir.NewBlockStmt(n.Pos(), init)
+			init = nil
+		}
+		if len(init) > 0 {
+			switch n.Op() {
+			case ir.OAS, ir.OAS2, ir.OBLOCK:
+				n.(ir.InitNode).PtrInit().Prepend(init...)
+
+			default:
+				init.Append(n)
+				n = ir.NewBlockStmt(n.Pos(), init)
+			}
+		}
+		return n
+
+	// special case for a receive where we throw away
+	// the value received.
+	case ir.ORECV:
+		n := n.(*ir.UnaryExpr)
+		return walkRecv(n)
+
+	case ir.OBREAK,
+		ir.OCONTINUE,
+		ir.OFALL,
+		ir.OGOTO,
+		ir.OLABEL,
+		ir.ODCL,
+		ir.ODCLCONST,
+		ir.ODCLTYPE,
+		ir.OCHECKNIL,
+		ir.OVARDEF,
+		ir.OVARKILL,
+		ir.OVARLIVE:
+		return n
+
+	case ir.OBLOCK:
+		n := n.(*ir.BlockStmt)
+		walkStmtList(n.List)
+		return n
+
+	case ir.OCASE:
+		base.Errorf("case statement out of place")
+		panic("unreachable")
+
+	case ir.ODEFER:
+		n := n.(*ir.GoDeferStmt)
+		ir.CurFunc.SetHasDefer(true)
+		ir.CurFunc.NumDefers++
+		if ir.CurFunc.NumDefers > maxOpenDefers {
+			// Don't allow open-coded defers if there are more than
+			// 8 defers in the function, since we use a single
+			// byte to record active defers.
+			ir.CurFunc.SetOpenCodedDeferDisallowed(true)
+		}
+		if n.Esc() != ir.EscNever {
+			// If n.Esc is not EscNever, then this defer occurs in a loop,
+			// so open-coded defers cannot be used in this function.
+			ir.CurFunc.SetOpenCodedDeferDisallowed(true)
+		}
+		fallthrough
+	case ir.OGO:
+		n := n.(*ir.GoDeferStmt)
+		return walkGoDefer(n)
+
+	case ir.OFOR, ir.OFORUNTIL:
+		n := n.(*ir.ForStmt)
+		return walkFor(n)
+
+	case ir.OIF:
+		n := n.(*ir.IfStmt)
+		return walkIf(n)
+
+	case ir.ORETURN:
+		n := n.(*ir.ReturnStmt)
+		return walkReturn(n)
+
+	case ir.OTAILCALL:
+		n := n.(*ir.TailCallStmt)
+		return n
+
+	case ir.OINLMARK:
+		n := n.(*ir.InlineMarkStmt)
+		return n
+
+	case ir.OSELECT:
+		n := n.(*ir.SelectStmt)
+		walkSelect(n)
+		return n
+
+	case ir.OSWITCH:
+		n := n.(*ir.SwitchStmt)
+		walkSwitch(n)
+		return n
+
+	case ir.ORANGE:
+		n := n.(*ir.RangeStmt)
+		return walkRange(n)
+	}
+
+	// No return! Each case must return (or panic),
+	// to avoid confusion about what gets returned
+	// in the presence of type assertions.
+}
+
+func walkStmtList(s []ir.Node) {
+	for i := range s {
+		s[i] = walkStmt(s[i])
+	}
+}
+
+// walkFor walks an OFOR or OFORUNTIL node.
+func walkFor(n *ir.ForStmt) ir.Node {
+	if n.Cond != nil {
+		init := ir.TakeInit(n.Cond)
+		walkStmtList(init)
+		n.Cond = walkExpr(n.Cond, &init)
+		n.Cond = ir.InitExpr(init, n.Cond)
+	}
+
+	n.Post = walkStmt(n.Post)
+	if n.Op() == ir.OFORUNTIL {
+		walkStmtList(n.Late)
+	}
+	walkStmtList(n.Body)
+	return n
+}
+
+// walkGoDefer walks an OGO or ODEFER node.
+func walkGoDefer(n *ir.GoDeferStmt) ir.Node {
+	var init ir.Nodes
+	switch call := n.Call; call.Op() {
+	case ir.OPRINT, ir.OPRINTN:
+		call := call.(*ir.CallExpr)
+		n.Call = wrapCall(call, &init)
+
+	case ir.ODELETE:
+		call := call.(*ir.CallExpr)
+		n.Call = wrapCall(call, &init)
+
+	case ir.OCOPY:
+		call := call.(*ir.BinaryExpr)
+		n.Call = walkCopy(call, &init, true)
+
+	case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
+		call := call.(*ir.CallExpr)
+		if len(call.KeepAlive) > 0 {
+			n.Call = wrapCall(call, &init)
+		} else {
+			n.Call = walkExpr(call, &init)
+		}
+
+	default:
+		n.Call = walkExpr(call, &init)
+	}
+	if len(init) > 0 {
+		init.Append(n)
+		return ir.NewBlockStmt(n.Pos(), init)
+	}
+	return n
+}
+
+// walkIf walks an OIF node.
+func walkIf(n *ir.IfStmt) ir.Node {
+	n.Cond = walkExpr(n.Cond, n.PtrInit())
+	walkStmtList(n.Body)
+	walkStmtList(n.Else)
+	return n
+}
+
+// Rewrite
+//	go builtin(x, y, z)
+// into
+//	go func(a1, a2, a3) {
+//		builtin(a1, a2, a3)
+//	}(x, y, z)
+// for print, println, and delete.
+//
+// Rewrite
+//	go f(x, y, uintptr(unsafe.Pointer(z)))
+// into
+//	go func(a1, a2, a3) {
+//		f(a1, a2, uintptr(a3))
+//	}(x, y, unsafe.Pointer(z))
+// for function contains unsafe-uintptr arguments.
+
+var wrapCall_prgen int
+
+// The result of wrapCall MUST be assigned back to n, e.g.
+// 	n.Left = wrapCall(n.Left, init)
+func wrapCall(n *ir.CallExpr, init *ir.Nodes) ir.Node {
+	if len(n.Init()) != 0 {
+		walkStmtList(n.Init())
+		init.Append(ir.TakeInit(n)...)
+	}
+
+	isBuiltinCall := n.Op() != ir.OCALLFUNC && n.Op() != ir.OCALLMETH && n.Op() != ir.OCALLINTER
+
+	// Turn f(a, b, []T{c, d, e}...) back into f(a, b, c, d, e).
+	if !isBuiltinCall && n.IsDDD {
+		undoVariadic(n)
+	}
+
+	wrapArgs := n.Args
+	// If there's a receiver argument, it needs to be passed through the wrapper too.
+	if n.Op() == ir.OCALLMETH || n.Op() == ir.OCALLINTER {
+		recv := n.X.(*ir.SelectorExpr).X
+		wrapArgs = append([]ir.Node{recv}, wrapArgs...)
+	}
+
+	// origArgs keeps track of what argument is uintptr-unsafe/unsafe-uintptr conversion.
+	origArgs := make([]ir.Node, len(wrapArgs))
+	var funcArgs []*ir.Field
+	for i, arg := range wrapArgs {
+		s := typecheck.LookupNum("a", i)
+		if !isBuiltinCall && arg.Op() == ir.OCONVNOP && arg.Type().IsUintptr() && arg.(*ir.ConvExpr).X.Type().IsUnsafePtr() {
+			origArgs[i] = arg
+			arg = arg.(*ir.ConvExpr).X
+			wrapArgs[i] = arg
+		}
+		funcArgs = append(funcArgs, ir.NewField(base.Pos, s, nil, arg.Type()))
+	}
+	t := ir.NewFuncType(base.Pos, nil, funcArgs, nil)
+
+	wrapCall_prgen++
+	sym := typecheck.LookupNum("wrap·", wrapCall_prgen)
+	fn := typecheck.DeclFunc(sym, t)
+
+	args := ir.ParamNames(t.Type())
+	for i, origArg := range origArgs {
+		if origArg == nil {
+			continue
+		}
+		args[i] = ir.NewConvExpr(base.Pos, origArg.Op(), origArg.Type(), args[i])
+	}
+	if n.Op() == ir.OCALLMETH || n.Op() == ir.OCALLINTER {
+		// Move wrapped receiver argument back to its appropriate place.
+		recv := typecheck.Expr(args[0])
+		n.X.(*ir.SelectorExpr).X = recv
+		args = args[1:]
+	}
+	call := ir.NewCallExpr(base.Pos, n.Op(), n.X, args)
+	if !isBuiltinCall {
+		call.SetOp(ir.OCALL)
+		call.IsDDD = n.IsDDD
+	}
+	fn.Body = []ir.Node{call}
+
+	typecheck.FinishFuncBody()
+
+	typecheck.Func(fn)
+	typecheck.Stmts(fn.Body)
+	typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
+
+	call = ir.NewCallExpr(base.Pos, ir.OCALL, fn.Nname, wrapArgs)
+	return walkExpr(typecheck.Stmt(call), init)
+}
+
+// undoVariadic turns a call to a variadic function of the form
+//
+//      f(a, b, []T{c, d, e}...)
+//
+// back into
+//
+//      f(a, b, c, d, e)
+//
+func undoVariadic(call *ir.CallExpr) {
+	if call.IsDDD {
+		last := len(call.Args) - 1
+		if va := call.Args[last]; va.Op() == ir.OSLICELIT {
+			va := va.(*ir.CompLitExpr)
+			call.Args = append(call.Args[:last], va.List...)
+			call.IsDDD = false
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/walk/switch.go b/src/cmd/compile/internal/walk/switch.go
new file mode 100644
index 0000000..162de01
--- /dev/null
+++ b/src/cmd/compile/internal/walk/switch.go
@@ -0,0 +1,568 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"go/constant"
+	"go/token"
+	"sort"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// walkSwitch walks a switch statement.
+func walkSwitch(sw *ir.SwitchStmt) {
+	// Guard against double walk, see #25776.
+	if sw.Walked() {
+		return // Was fatal, but eliminating every possible source of double-walking is hard
+	}
+	sw.SetWalked(true)
+
+	if sw.Tag != nil && sw.Tag.Op() == ir.OTYPESW {
+		walkSwitchType(sw)
+	} else {
+		walkSwitchExpr(sw)
+	}
+}
+
+// walkSwitchExpr generates an AST implementing sw.  sw is an
+// expression switch.
+func walkSwitchExpr(sw *ir.SwitchStmt) {
+	lno := ir.SetPos(sw)
+
+	cond := sw.Tag
+	sw.Tag = nil
+
+	// convert switch {...} to switch true {...}
+	if cond == nil {
+		cond = ir.NewBool(true)
+		cond = typecheck.Expr(cond)
+		cond = typecheck.DefaultLit(cond, nil)
+	}
+
+	// Given "switch string(byteslice)",
+	// with all cases being side-effect free,
+	// use a zero-cost alias of the byte slice.
+	// Do this before calling walkExpr on cond,
+	// because walkExpr will lower the string
+	// conversion into a runtime call.
+	// See issue 24937 for more discussion.
+	if cond.Op() == ir.OBYTES2STR && allCaseExprsAreSideEffectFree(sw) {
+		cond := cond.(*ir.ConvExpr)
+		cond.SetOp(ir.OBYTES2STRTMP)
+	}
+
+	cond = walkExpr(cond, sw.PtrInit())
+	if cond.Op() != ir.OLITERAL && cond.Op() != ir.ONIL {
+		cond = copyExpr(cond, cond.Type(), &sw.Compiled)
+	}
+
+	base.Pos = lno
+
+	s := exprSwitch{
+		exprname: cond,
+	}
+
+	var defaultGoto ir.Node
+	var body ir.Nodes
+	for _, ncase := range sw.Cases {
+		label := typecheck.AutoLabel(".s")
+		jmp := ir.NewBranchStmt(ncase.Pos(), ir.OGOTO, label)
+
+		// Process case dispatch.
+		if len(ncase.List) == 0 {
+			if defaultGoto != nil {
+				base.Fatalf("duplicate default case not detected during typechecking")
+			}
+			defaultGoto = jmp
+		}
+
+		for _, n1 := range ncase.List {
+			s.Add(ncase.Pos(), n1, jmp)
+		}
+
+		// Process body.
+		body.Append(ir.NewLabelStmt(ncase.Pos(), label))
+		body.Append(ncase.Body...)
+		if fall, pos := endsInFallthrough(ncase.Body); !fall {
+			br := ir.NewBranchStmt(base.Pos, ir.OBREAK, nil)
+			br.SetPos(pos)
+			body.Append(br)
+		}
+	}
+	sw.Cases = nil
+
+	if defaultGoto == nil {
+		br := ir.NewBranchStmt(base.Pos, ir.OBREAK, nil)
+		br.SetPos(br.Pos().WithNotStmt())
+		defaultGoto = br
+	}
+
+	s.Emit(&sw.Compiled)
+	sw.Compiled.Append(defaultGoto)
+	sw.Compiled.Append(body.Take()...)
+	walkStmtList(sw.Compiled)
+}
+
+// An exprSwitch walks an expression switch.
+type exprSwitch struct {
+	exprname ir.Node // value being switched on
+
+	done    ir.Nodes
+	clauses []exprClause
+}
+
+type exprClause struct {
+	pos    src.XPos
+	lo, hi ir.Node
+	jmp    ir.Node
+}
+
+func (s *exprSwitch) Add(pos src.XPos, expr, jmp ir.Node) {
+	c := exprClause{pos: pos, lo: expr, hi: expr, jmp: jmp}
+	if types.IsOrdered[s.exprname.Type().Kind()] && expr.Op() == ir.OLITERAL {
+		s.clauses = append(s.clauses, c)
+		return
+	}
+
+	s.flush()
+	s.clauses = append(s.clauses, c)
+	s.flush()
+}
+
+func (s *exprSwitch) Emit(out *ir.Nodes) {
+	s.flush()
+	out.Append(s.done.Take()...)
+}
+
+func (s *exprSwitch) flush() {
+	cc := s.clauses
+	s.clauses = nil
+	if len(cc) == 0 {
+		return
+	}
+
+	// Caution: If len(cc) == 1, then cc[0] might not an OLITERAL.
+	// The code below is structured to implicitly handle this case
+	// (e.g., sort.Slice doesn't need to invoke the less function
+	// when there's only a single slice element).
+
+	if s.exprname.Type().IsString() && len(cc) >= 2 {
+		// Sort strings by length and then by value. It is
+		// much cheaper to compare lengths than values, and
+		// all we need here is consistency. We respect this
+		// sorting below.
+		sort.Slice(cc, func(i, j int) bool {
+			si := ir.StringVal(cc[i].lo)
+			sj := ir.StringVal(cc[j].lo)
+			if len(si) != len(sj) {
+				return len(si) < len(sj)
+			}
+			return si < sj
+		})
+
+		// runLen returns the string length associated with a
+		// particular run of exprClauses.
+		runLen := func(run []exprClause) int64 { return int64(len(ir.StringVal(run[0].lo))) }
+
+		// Collapse runs of consecutive strings with the same length.
+		var runs [][]exprClause
+		start := 0
+		for i := 1; i < len(cc); i++ {
+			if runLen(cc[start:]) != runLen(cc[i:]) {
+				runs = append(runs, cc[start:i])
+				start = i
+			}
+		}
+		runs = append(runs, cc[start:])
+
+		// Perform two-level binary search.
+		binarySearch(len(runs), &s.done,
+			func(i int) ir.Node {
+				return ir.NewBinaryExpr(base.Pos, ir.OLE, ir.NewUnaryExpr(base.Pos, ir.OLEN, s.exprname), ir.NewInt(runLen(runs[i-1])))
+			},
+			func(i int, nif *ir.IfStmt) {
+				run := runs[i]
+				nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, ir.NewUnaryExpr(base.Pos, ir.OLEN, s.exprname), ir.NewInt(runLen(run)))
+				s.search(run, &nif.Body)
+			},
+		)
+		return
+	}
+
+	sort.Slice(cc, func(i, j int) bool {
+		return constant.Compare(cc[i].lo.Val(), token.LSS, cc[j].lo.Val())
+	})
+
+	// Merge consecutive integer cases.
+	if s.exprname.Type().IsInteger() {
+		consecutive := func(last, next constant.Value) bool {
+			delta := constant.BinaryOp(next, token.SUB, last)
+			return constant.Compare(delta, token.EQL, constant.MakeInt64(1))
+		}
+
+		merged := cc[:1]
+		for _, c := range cc[1:] {
+			last := &merged[len(merged)-1]
+			if last.jmp == c.jmp && consecutive(last.hi.Val(), c.lo.Val()) {
+				last.hi = c.lo
+			} else {
+				merged = append(merged, c)
+			}
+		}
+		cc = merged
+	}
+
+	s.search(cc, &s.done)
+}
+
+func (s *exprSwitch) search(cc []exprClause, out *ir.Nodes) {
+	binarySearch(len(cc), out,
+		func(i int) ir.Node {
+			return ir.NewBinaryExpr(base.Pos, ir.OLE, s.exprname, cc[i-1].hi)
+		},
+		func(i int, nif *ir.IfStmt) {
+			c := &cc[i]
+			nif.Cond = c.test(s.exprname)
+			nif.Body = []ir.Node{c.jmp}
+		},
+	)
+}
+
+func (c *exprClause) test(exprname ir.Node) ir.Node {
+	// Integer range.
+	if c.hi != c.lo {
+		low := ir.NewBinaryExpr(c.pos, ir.OGE, exprname, c.lo)
+		high := ir.NewBinaryExpr(c.pos, ir.OLE, exprname, c.hi)
+		return ir.NewLogicalExpr(c.pos, ir.OANDAND, low, high)
+	}
+
+	// Optimize "switch true { ...}" and "switch false { ... }".
+	if ir.IsConst(exprname, constant.Bool) && !c.lo.Type().IsInterface() {
+		if ir.BoolVal(exprname) {
+			return c.lo
+		} else {
+			return ir.NewUnaryExpr(c.pos, ir.ONOT, c.lo)
+		}
+	}
+
+	return ir.NewBinaryExpr(c.pos, ir.OEQ, exprname, c.lo)
+}
+
+func allCaseExprsAreSideEffectFree(sw *ir.SwitchStmt) bool {
+	// In theory, we could be more aggressive, allowing any
+	// side-effect-free expressions in cases, but it's a bit
+	// tricky because some of that information is unavailable due
+	// to the introduction of temporaries during order.
+	// Restricting to constants is simple and probably powerful
+	// enough.
+
+	for _, ncase := range sw.Cases {
+		for _, v := range ncase.List {
+			if v.Op() != ir.OLITERAL {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// endsInFallthrough reports whether stmts ends with a "fallthrough" statement.
+func endsInFallthrough(stmts []ir.Node) (bool, src.XPos) {
+	// Search backwards for the index of the fallthrough
+	// statement. Do not assume it'll be in the last
+	// position, since in some cases (e.g. when the statement
+	// list contains autotmp_ variables), one or more OVARKILL
+	// nodes will be at the end of the list.
+
+	i := len(stmts) - 1
+	for i >= 0 && stmts[i].Op() == ir.OVARKILL {
+		i--
+	}
+	if i < 0 {
+		return false, src.NoXPos
+	}
+	return stmts[i].Op() == ir.OFALL, stmts[i].Pos()
+}
+
+// walkSwitchType generates an AST that implements sw, where sw is a
+// type switch.
+func walkSwitchType(sw *ir.SwitchStmt) {
+	var s typeSwitch
+	s.facename = sw.Tag.(*ir.TypeSwitchGuard).X
+	sw.Tag = nil
+
+	s.facename = walkExpr(s.facename, sw.PtrInit())
+	s.facename = copyExpr(s.facename, s.facename.Type(), &sw.Compiled)
+	s.okname = typecheck.Temp(types.Types[types.TBOOL])
+
+	// Get interface descriptor word.
+	// For empty interfaces this will be the type.
+	// For non-empty interfaces this will be the itab.
+	itab := ir.NewUnaryExpr(base.Pos, ir.OITAB, s.facename)
+
+	// For empty interfaces, do:
+	//     if e._type == nil {
+	//         do nil case if it exists, otherwise default
+	//     }
+	//     h := e._type.hash
+	// Use a similar strategy for non-empty interfaces.
+	ifNil := ir.NewIfStmt(base.Pos, nil, nil, nil)
+	ifNil.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, itab, typecheck.NodNil())
+	base.Pos = base.Pos.WithNotStmt() // disable statement marks after the first check.
+	ifNil.Cond = typecheck.Expr(ifNil.Cond)
+	ifNil.Cond = typecheck.DefaultLit(ifNil.Cond, nil)
+	// ifNil.Nbody assigned at end.
+	sw.Compiled.Append(ifNil)
+
+	// Load hash from type or itab.
+	dotHash := typeHashFieldOf(base.Pos, itab)
+	s.hashname = copyExpr(dotHash, dotHash.Type(), &sw.Compiled)
+
+	br := ir.NewBranchStmt(base.Pos, ir.OBREAK, nil)
+	var defaultGoto, nilGoto ir.Node
+	var body ir.Nodes
+	for _, ncase := range sw.Cases {
+		caseVar := ncase.Var
+
+		// For single-type cases with an interface type,
+		// we initialize the case variable as part of the type assertion.
+		// In other cases, we initialize it in the body.
+		var singleType *types.Type
+		if len(ncase.List) == 1 && ncase.List[0].Op() == ir.OTYPE {
+			singleType = ncase.List[0].Type()
+		}
+		caseVarInitialized := false
+
+		label := typecheck.AutoLabel(".s")
+		jmp := ir.NewBranchStmt(ncase.Pos(), ir.OGOTO, label)
+
+		if len(ncase.List) == 0 { // default:
+			if defaultGoto != nil {
+				base.Fatalf("duplicate default case not detected during typechecking")
+			}
+			defaultGoto = jmp
+		}
+
+		for _, n1 := range ncase.List {
+			if ir.IsNil(n1) { // case nil:
+				if nilGoto != nil {
+					base.Fatalf("duplicate nil case not detected during typechecking")
+				}
+				nilGoto = jmp
+				continue
+			}
+
+			if singleType != nil && singleType.IsInterface() {
+				s.Add(ncase.Pos(), n1.Type(), caseVar, jmp)
+				caseVarInitialized = true
+			} else {
+				s.Add(ncase.Pos(), n1.Type(), nil, jmp)
+			}
+		}
+
+		body.Append(ir.NewLabelStmt(ncase.Pos(), label))
+		if caseVar != nil && !caseVarInitialized {
+			val := s.facename
+			if singleType != nil {
+				// We have a single concrete type. Extract the data.
+				if singleType.IsInterface() {
+					base.Fatalf("singleType interface should have been handled in Add")
+				}
+				val = ifaceData(ncase.Pos(), s.facename, singleType)
+			}
+			l := []ir.Node{
+				ir.NewDecl(ncase.Pos(), ir.ODCL, caseVar),
+				ir.NewAssignStmt(ncase.Pos(), caseVar, val),
+			}
+			typecheck.Stmts(l)
+			body.Append(l...)
+		}
+		body.Append(ncase.Body...)
+		body.Append(br)
+	}
+	sw.Cases = nil
+
+	if defaultGoto == nil {
+		defaultGoto = br
+	}
+	if nilGoto == nil {
+		nilGoto = defaultGoto
+	}
+	ifNil.Body = []ir.Node{nilGoto}
+
+	s.Emit(&sw.Compiled)
+	sw.Compiled.Append(defaultGoto)
+	sw.Compiled.Append(body.Take()...)
+
+	walkStmtList(sw.Compiled)
+}
+
+// typeHashFieldOf returns an expression to select the type hash field
+// from an interface's descriptor word (whether a *runtime._type or
+// *runtime.itab pointer).
+func typeHashFieldOf(pos src.XPos, itab *ir.UnaryExpr) *ir.SelectorExpr {
+	if itab.Op() != ir.OITAB {
+		base.Fatalf("expected OITAB, got %v", itab.Op())
+	}
+	var hashField *types.Field
+	if itab.X.Type().IsEmptyInterface() {
+		// runtime._type's hash field
+		if rtypeHashField == nil {
+			rtypeHashField = runtimeField("hash", int64(2*types.PtrSize), types.Types[types.TUINT32])
+		}
+		hashField = rtypeHashField
+	} else {
+		// runtime.itab's hash field
+		if itabHashField == nil {
+			itabHashField = runtimeField("hash", int64(2*types.PtrSize), types.Types[types.TUINT32])
+		}
+		hashField = itabHashField
+	}
+	return boundedDotPtr(pos, itab, hashField)
+}
+
+var rtypeHashField, itabHashField *types.Field
+
+// A typeSwitch walks a type switch.
+type typeSwitch struct {
+	// Temporary variables (i.e., ONAMEs) used by type switch dispatch logic:
+	facename ir.Node // value being type-switched on
+	hashname ir.Node // type hash of the value being type-switched on
+	okname   ir.Node // boolean used for comma-ok type assertions
+
+	done    ir.Nodes
+	clauses []typeClause
+}
+
+type typeClause struct {
+	hash uint32
+	body ir.Nodes
+}
+
+func (s *typeSwitch) Add(pos src.XPos, typ *types.Type, caseVar *ir.Name, jmp ir.Node) {
+	var body ir.Nodes
+	if caseVar != nil {
+		l := []ir.Node{
+			ir.NewDecl(pos, ir.ODCL, caseVar),
+			ir.NewAssignStmt(pos, caseVar, nil),
+		}
+		typecheck.Stmts(l)
+		body.Append(l...)
+	} else {
+		caseVar = ir.BlankNode.(*ir.Name)
+	}
+
+	// cv, ok = iface.(type)
+	as := ir.NewAssignListStmt(pos, ir.OAS2, nil, nil)
+	as.Lhs = []ir.Node{caseVar, s.okname} // cv, ok =
+	dot := ir.NewTypeAssertExpr(pos, s.facename, nil)
+	dot.SetType(typ) // iface.(type)
+	as.Rhs = []ir.Node{dot}
+	appendWalkStmt(&body, as)
+
+	// if ok { goto label }
+	nif := ir.NewIfStmt(pos, nil, nil, nil)
+	nif.Cond = s.okname
+	nif.Body = []ir.Node{jmp}
+	body.Append(nif)
+
+	if !typ.IsInterface() {
+		s.clauses = append(s.clauses, typeClause{
+			hash: types.TypeHash(typ),
+			body: body,
+		})
+		return
+	}
+
+	s.flush()
+	s.done.Append(body.Take()...)
+}
+
+func (s *typeSwitch) Emit(out *ir.Nodes) {
+	s.flush()
+	out.Append(s.done.Take()...)
+}
+
+func (s *typeSwitch) flush() {
+	cc := s.clauses
+	s.clauses = nil
+	if len(cc) == 0 {
+		return
+	}
+
+	sort.Slice(cc, func(i, j int) bool { return cc[i].hash < cc[j].hash })
+
+	// Combine adjacent cases with the same hash.
+	merged := cc[:1]
+	for _, c := range cc[1:] {
+		last := &merged[len(merged)-1]
+		if last.hash == c.hash {
+			last.body.Append(c.body.Take()...)
+		} else {
+			merged = append(merged, c)
+		}
+	}
+	cc = merged
+
+	binarySearch(len(cc), &s.done,
+		func(i int) ir.Node {
+			return ir.NewBinaryExpr(base.Pos, ir.OLE, s.hashname, ir.NewInt(int64(cc[i-1].hash)))
+		},
+		func(i int, nif *ir.IfStmt) {
+			// TODO(mdempsky): Omit hash equality check if
+			// there's only one type.
+			c := cc[i]
+			nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, s.hashname, ir.NewInt(int64(c.hash)))
+			nif.Body.Append(c.body.Take()...)
+		},
+	)
+}
+
+// binarySearch constructs a binary search tree for handling n cases,
+// and appends it to out. It's used for efficiently implementing
+// switch statements.
+//
+// less(i) should return a boolean expression. If it evaluates true,
+// then cases before i will be tested; otherwise, cases i and later.
+//
+// leaf(i, nif) should setup nif (an OIF node) to test case i. In
+// particular, it should set nif.Left and nif.Nbody.
+func binarySearch(n int, out *ir.Nodes, less func(i int) ir.Node, leaf func(i int, nif *ir.IfStmt)) {
+	const binarySearchMin = 4 // minimum number of cases for binary search
+
+	var do func(lo, hi int, out *ir.Nodes)
+	do = func(lo, hi int, out *ir.Nodes) {
+		n := hi - lo
+		if n < binarySearchMin {
+			for i := lo; i < hi; i++ {
+				nif := ir.NewIfStmt(base.Pos, nil, nil, nil)
+				leaf(i, nif)
+				base.Pos = base.Pos.WithNotStmt()
+				nif.Cond = typecheck.Expr(nif.Cond)
+				nif.Cond = typecheck.DefaultLit(nif.Cond, nil)
+				out.Append(nif)
+				out = &nif.Else
+			}
+			return
+		}
+
+		half := lo + n/2
+		nif := ir.NewIfStmt(base.Pos, nil, nil, nil)
+		nif.Cond = less(half)
+		base.Pos = base.Pos.WithNotStmt()
+		nif.Cond = typecheck.Expr(nif.Cond)
+		nif.Cond = typecheck.DefaultLit(nif.Cond, nil)
+		do(lo, half, &nif.Body)
+		do(half, hi, &nif.Else)
+		out.Append(nif)
+	}
+
+	do(0, n, out)
+}
diff --git a/src/cmd/compile/internal/walk/temp.go b/src/cmd/compile/internal/walk/temp.go
new file mode 100644
index 0000000..9879a6c
--- /dev/null
+++ b/src/cmd/compile/internal/walk/temp.go
@@ -0,0 +1,40 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+)
+
+// initStackTemp appends statements to init to initialize the given
+// temporary variable to val, and then returns the expression &tmp.
+func initStackTemp(init *ir.Nodes, tmp *ir.Name, val ir.Node) *ir.AddrExpr {
+	if val != nil && !types.Identical(tmp.Type(), val.Type()) {
+		base.Fatalf("bad initial value for %L: %L", tmp, val)
+	}
+	appendWalkStmt(init, ir.NewAssignStmt(base.Pos, tmp, val))
+	return typecheck.Expr(typecheck.NodAddr(tmp)).(*ir.AddrExpr)
+}
+
+// stackTempAddr returns the expression &tmp, where tmp is a newly
+// allocated temporary variable of the given type. Statements to
+// zero-initialize tmp are appended to init.
+func stackTempAddr(init *ir.Nodes, typ *types.Type) *ir.AddrExpr {
+	return initStackTemp(init, typecheck.Temp(typ), nil)
+}
+
+// stackBufAddr returns thte expression &tmp, where tmp is a newly
+// allocated temporary variable of type [len]elem. This variable is
+// initialized, and elem must not contain pointers.
+func stackBufAddr(len int64, elem *types.Type) *ir.AddrExpr {
+	if elem.HasPointers() {
+		base.FatalfAt(base.Pos, "%v has pointers", elem)
+	}
+	tmp := typecheck.Temp(types.NewArray(elem, len))
+	return typecheck.Expr(typecheck.NodAddr(tmp)).(*ir.AddrExpr)
+}
diff --git a/src/cmd/compile/internal/walk/walk.go b/src/cmd/compile/internal/walk/walk.go
new file mode 100644
index 0000000..26da6e3
--- /dev/null
+++ b/src/cmd/compile/internal/walk/walk.go
@@ -0,0 +1,403 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package walk
+
+import (
+	"errors"
+	"fmt"
+
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/ssagen"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+// The constant is known to runtime.
+const tmpstringbufsize = 32
+const zeroValSize = 1024 // must match value of runtime/map.go:maxZero
+
+func Walk(fn *ir.Func) {
+	ir.CurFunc = fn
+	errorsBefore := base.Errors()
+	order(fn)
+	if base.Errors() > errorsBefore {
+		return
+	}
+
+	if base.Flag.W != 0 {
+		s := fmt.Sprintf("\nbefore walk %v", ir.CurFunc.Sym())
+		ir.DumpList(s, ir.CurFunc.Body)
+	}
+
+	lno := base.Pos
+
+	base.Pos = lno
+	if base.Errors() > errorsBefore {
+		return
+	}
+	walkStmtList(ir.CurFunc.Body)
+	if base.Flag.W != 0 {
+		s := fmt.Sprintf("after walk %v", ir.CurFunc.Sym())
+		ir.DumpList(s, ir.CurFunc.Body)
+	}
+
+	if base.Flag.Cfg.Instrumenting {
+		instrument(fn)
+	}
+
+	// Eagerly compute sizes of all variables for SSA.
+	for _, n := range fn.Dcl {
+		types.CalcSize(n.Type())
+	}
+}
+
+// walkRecv walks an ORECV node.
+func walkRecv(n *ir.UnaryExpr) ir.Node {
+	if n.Typecheck() == 0 {
+		base.Fatalf("missing typecheck: %+v", n)
+	}
+	init := ir.TakeInit(n)
+
+	n.X = walkExpr(n.X, &init)
+	call := walkExpr(mkcall1(chanfn("chanrecv1", 2, n.X.Type()), nil, &init, n.X, typecheck.NodNil()), &init)
+	return ir.InitExpr(init, call)
+}
+
+func convas(n *ir.AssignStmt, init *ir.Nodes) *ir.AssignStmt {
+	if n.Op() != ir.OAS {
+		base.Fatalf("convas: not OAS %v", n.Op())
+	}
+	n.SetTypecheck(1)
+
+	if n.X == nil || n.Y == nil {
+		return n
+	}
+
+	lt := n.X.Type()
+	rt := n.Y.Type()
+	if lt == nil || rt == nil {
+		return n
+	}
+
+	if ir.IsBlank(n.X) {
+		n.Y = typecheck.DefaultLit(n.Y, nil)
+		return n
+	}
+
+	if !types.Identical(lt, rt) {
+		n.Y = typecheck.AssignConv(n.Y, lt, "assignment")
+		n.Y = walkExpr(n.Y, init)
+	}
+	types.CalcSize(n.Y.Type())
+
+	return n
+}
+
+var stop = errors.New("stop")
+
+func vmkcall(fn ir.Node, t *types.Type, init *ir.Nodes, va []ir.Node) *ir.CallExpr {
+	if init == nil {
+		base.Fatalf("mkcall with nil init: %v", fn)
+	}
+	if fn.Type() == nil || fn.Type().Kind() != types.TFUNC {
+		base.Fatalf("mkcall %v %v", fn, fn.Type())
+	}
+
+	n := fn.Type().NumParams()
+	if n != len(va) {
+		base.Fatalf("vmkcall %v needs %v args got %v", fn, n, len(va))
+	}
+
+	call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, va)
+	typecheck.Call(call)
+	call.SetType(t)
+	return walkExpr(call, init).(*ir.CallExpr)
+}
+
+func mkcall(name string, t *types.Type, init *ir.Nodes, args ...ir.Node) *ir.CallExpr {
+	return vmkcall(typecheck.LookupRuntime(name), t, init, args)
+}
+
+func mkcallstmt(name string, args ...ir.Node) ir.Node {
+	return mkcallstmt1(typecheck.LookupRuntime(name), args...)
+}
+
+func mkcall1(fn ir.Node, t *types.Type, init *ir.Nodes, args ...ir.Node) *ir.CallExpr {
+	return vmkcall(fn, t, init, args)
+}
+
+func mkcallstmt1(fn ir.Node, args ...ir.Node) ir.Node {
+	var init ir.Nodes
+	n := vmkcall(fn, nil, &init, args)
+	if len(init) == 0 {
+		return n
+	}
+	init.Append(n)
+	return ir.NewBlockStmt(n.Pos(), init)
+}
+
+func chanfn(name string, n int, t *types.Type) ir.Node {
+	if !t.IsChan() {
+		base.Fatalf("chanfn %v", t)
+	}
+	fn := typecheck.LookupRuntime(name)
+	switch n {
+	default:
+		base.Fatalf("chanfn %d", n)
+	case 1:
+		fn = typecheck.SubstArgTypes(fn, t.Elem())
+	case 2:
+		fn = typecheck.SubstArgTypes(fn, t.Elem(), t.Elem())
+	}
+	return fn
+}
+
+func mapfn(name string, t *types.Type, isfat bool) ir.Node {
+	if !t.IsMap() {
+		base.Fatalf("mapfn %v", t)
+	}
+	fn := typecheck.LookupRuntime(name)
+	if mapfast(t) == mapslow || isfat {
+		fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), t.Key(), t.Elem())
+	} else {
+		fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), t.Elem())
+	}
+	return fn
+}
+
+func mapfndel(name string, t *types.Type) ir.Node {
+	if !t.IsMap() {
+		base.Fatalf("mapfn %v", t)
+	}
+	fn := typecheck.LookupRuntime(name)
+	if mapfast(t) == mapslow {
+		fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), t.Key())
+	} else {
+		fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem())
+	}
+	return fn
+}
+
+const (
+	mapslow = iota
+	mapfast32
+	mapfast32ptr
+	mapfast64
+	mapfast64ptr
+	mapfaststr
+	nmapfast
+)
+
+type mapnames [nmapfast]string
+
+func mkmapnames(base string, ptr string) mapnames {
+	return mapnames{base, base + "_fast32", base + "_fast32" + ptr, base + "_fast64", base + "_fast64" + ptr, base + "_faststr"}
+}
+
+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/map.go:maxElemSize before changing.
+	if t.Elem().Width > 128 {
+		return mapslow
+	}
+	switch reflectdata.AlgType(t.Key()) {
+	case types.AMEM32:
+		if !t.Key().HasPointers() {
+			return mapfast32
+		}
+		if types.PtrSize == 4 {
+			return mapfast32ptr
+		}
+		base.Fatalf("small pointer %v", t.Key())
+	case types.AMEM64:
+		if !t.Key().HasPointers() {
+			return mapfast64
+		}
+		if types.PtrSize == 8 {
+			return mapfast64ptr
+		}
+		// Two-word object, at least one of which is a pointer.
+		// Use the slow path.
+	case types.ASTRING:
+		return mapfaststr
+	}
+	return mapslow
+}
+
+func walkAppendArgs(n *ir.CallExpr, init *ir.Nodes) {
+	walkExprListSafe(n.Args, init)
+
+	// walkExprListSafe will leave OINDEX (s[n]) alone if both s
+	// and n are name or literal, but those may index the slice we're
+	// modifying here. Fix explicitly.
+	ls := n.Args
+	for i1, n1 := range ls {
+		ls[i1] = cheapExpr(n1, init)
+	}
+}
+
+// appendWalkStmt typechecks and walks stmt and then appends it to init.
+func appendWalkStmt(init *ir.Nodes, stmt ir.Node) {
+	op := stmt.Op()
+	n := typecheck.Stmt(stmt)
+	if op == ir.OAS || op == ir.OAS2 {
+		// If the assignment has side effects, walkExpr will append them
+		// directly to init for us, while walkStmt will wrap it in an OBLOCK.
+		// We need to append them directly.
+		// TODO(rsc): Clean this up.
+		n = walkExpr(n, init)
+	} else {
+		n = walkStmt(n)
+	}
+	init.Append(n)
+}
+
+// The max number of defers in a function using open-coded defers. We enforce this
+// limit because the deferBits bitmask is currently a single byte (to minimize code size)
+const maxOpenDefers = 8
+
+// backingArrayPtrLen extracts the pointer and length from a slice or string.
+// This constructs two nodes referring to n, so n must be a cheapExpr.
+func backingArrayPtrLen(n ir.Node) (ptr, length ir.Node) {
+	var init ir.Nodes
+	c := cheapExpr(n, &init)
+	if c != n || len(init) != 0 {
+		base.Fatalf("backingArrayPtrLen not cheap: %v", n)
+	}
+	ptr = ir.NewUnaryExpr(base.Pos, ir.OSPTR, n)
+	if n.Type().IsString() {
+		ptr.SetType(types.Types[types.TUINT8].PtrTo())
+	} else {
+		ptr.SetType(n.Type().Elem().PtrTo())
+	}
+	length = ir.NewUnaryExpr(base.Pos, ir.OLEN, n)
+	length.SetType(types.Types[types.TINT])
+	return ptr, length
+}
+
+// mayCall reports whether evaluating expression n may require
+// function calls, which could clobber function call arguments/results
+// currently on the stack.
+func mayCall(n ir.Node) bool {
+	// When instrumenting, any expression might require function calls.
+	if base.Flag.Cfg.Instrumenting {
+		return true
+	}
+
+	isSoftFloat := func(typ *types.Type) bool {
+		return types.IsFloat[typ.Kind()] || types.IsComplex[typ.Kind()]
+	}
+
+	return ir.Any(n, func(n ir.Node) bool {
+		// walk should have already moved any Init blocks off of
+		// expressions.
+		if len(n.Init()) != 0 {
+			base.FatalfAt(n.Pos(), "mayCall %+v", n)
+		}
+
+		switch n.Op() {
+		default:
+			base.FatalfAt(n.Pos(), "mayCall %+v", n)
+
+		case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER,
+			ir.OUNSAFEADD, ir.OUNSAFESLICE:
+			return true
+
+		case ir.OINDEX, ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR, ir.OSLICESTR,
+			ir.ODEREF, ir.ODOTPTR, ir.ODOTTYPE, ir.ODIV, ir.OMOD, ir.OSLICE2ARRPTR:
+			// These ops might panic, make sure they are done
+			// before we start marshaling args for a call. See issue 16760.
+			return true
+
+		case ir.OANDAND, ir.OOROR:
+			n := n.(*ir.LogicalExpr)
+			// The RHS expression may have init statements that
+			// should only execute conditionally, and so cannot be
+			// pulled out to the top-level init list. We could try
+			// to be more precise here.
+			return len(n.Y.Init()) != 0
+
+		// When using soft-float, these ops might be rewritten to function calls
+		// so we ensure they are evaluated first.
+		case ir.OADD, ir.OSUB, ir.OMUL, ir.ONEG:
+			return ssagen.Arch.SoftFloat && isSoftFloat(n.Type())
+		case ir.OLT, ir.OEQ, ir.ONE, ir.OLE, ir.OGE, ir.OGT:
+			n := n.(*ir.BinaryExpr)
+			return ssagen.Arch.SoftFloat && isSoftFloat(n.X.Type())
+		case ir.OCONV:
+			n := n.(*ir.ConvExpr)
+			return ssagen.Arch.SoftFloat && (isSoftFloat(n.Type()) || isSoftFloat(n.X.Type()))
+
+		case ir.OLITERAL, ir.ONIL, ir.ONAME, ir.OLINKSYMOFFSET, ir.OMETHEXPR,
+			ir.OAND, ir.OANDNOT, ir.OLSH, ir.OOR, ir.ORSH, ir.OXOR, ir.OCOMPLEX, ir.OEFACE,
+			ir.OADDR, ir.OBITNOT, ir.ONOT, ir.OPLUS,
+			ir.OCAP, ir.OIMAG, ir.OLEN, ir.OREAL,
+			ir.OCONVNOP, ir.ODOT,
+			ir.OCFUNC, ir.OIDATA, ir.OITAB, ir.OSPTR,
+			ir.OBYTES2STRTMP, ir.OGETG, ir.OSLICEHEADER:
+			// ok: operations that don't require function calls.
+			// Expand as needed.
+		}
+
+		return false
+	})
+}
+
+// itabType loads the _type field from a runtime.itab struct.
+func itabType(itab ir.Node) ir.Node {
+	if itabTypeField == nil {
+		// runtime.itab's _type field
+		itabTypeField = runtimeField("_type", int64(types.PtrSize), types.NewPtr(types.Types[types.TUINT8]))
+	}
+	return boundedDotPtr(base.Pos, itab, itabTypeField)
+}
+
+var itabTypeField *types.Field
+
+// boundedDotPtr returns a selector expression representing ptr.field
+// and omits nil-pointer checks for ptr.
+func boundedDotPtr(pos src.XPos, ptr ir.Node, field *types.Field) *ir.SelectorExpr {
+	sel := ir.NewSelectorExpr(pos, ir.ODOTPTR, ptr, field.Sym)
+	sel.Selection = field
+	sel.SetType(field.Type)
+	sel.SetTypecheck(1)
+	sel.SetBounded(true) // guaranteed not to fault
+	return sel
+}
+
+func runtimeField(name string, offset int64, typ *types.Type) *types.Field {
+	f := types.NewField(src.NoXPos, ir.Pkgs.Runtime.Lookup(name), typ)
+	f.Offset = offset
+	return f
+}
+
+// ifaceData loads the data field from an interface.
+// The concrete type must be known to have type t.
+// It follows the pointer if !IsDirectIface(t).
+func ifaceData(pos src.XPos, n ir.Node, t *types.Type) ir.Node {
+	if t.IsInterface() {
+		base.Fatalf("ifaceData interface: %v", t)
+	}
+	ptr := ir.NewUnaryExpr(pos, ir.OIDATA, n)
+	if types.IsDirectIface(t) {
+		ptr.SetType(t)
+		ptr.SetTypecheck(1)
+		return ptr
+	}
+	ptr.SetType(types.NewPtr(t))
+	ptr.SetTypecheck(1)
+	ind := ir.NewStarExpr(pos, ptr)
+	ind.SetType(t)
+	ind.SetTypecheck(1)
+	ind.SetBounded(true)
+	return ind
+}
diff --git a/src/cmd/compile/internal/wasm/ssa.go b/src/cmd/compile/internal/wasm/ssa.go
index 9c9f6ed..31b0901 100644
--- a/src/cmd/compile/internal/wasm/ssa.go
+++ b/src/cmd/compile/internal/wasm/ssa.go
@@ -5,16 +5,19 @@
 package wasm
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/logopt"
+	"cmd/compile/internal/objw"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/wasm"
-	"cmd/internal/objabi"
+	"internal/buildcfg"
 )
 
-func Init(arch *gc.Arch) {
+func Init(arch *ssagen.ArchInfo) {
 	arch.LinkArch = &wasm.Linkwasm
 	arch.REGSP = wasm.REG_SP
 	arch.MAXWIDTH = 1 << 50
@@ -28,31 +31,31 @@
 	arch.SSAGenBlock = ssaGenBlock
 }
 
-func zeroRange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Prog {
+func zeroRange(pp *objw.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Prog {
 	if cnt == 0 {
 		return p
 	}
 	if cnt%8 != 0 {
-		gc.Fatalf("zerorange count not a multiple of widthptr %d", cnt)
+		base.Fatalf("zerorange count not a multiple of widthptr %d", cnt)
 	}
 
 	for i := int64(0); i < cnt; i += 8 {
-		p = pp.Appendpp(p, wasm.AGet, obj.TYPE_REG, wasm.REG_SP, 0, 0, 0, 0)
-		p = pp.Appendpp(p, wasm.AI64Const, obj.TYPE_CONST, 0, 0, 0, 0, 0)
-		p = pp.Appendpp(p, wasm.AI64Store, 0, 0, 0, obj.TYPE_CONST, 0, off+i)
+		p = pp.Append(p, wasm.AGet, obj.TYPE_REG, wasm.REG_SP, 0, 0, 0, 0)
+		p = pp.Append(p, wasm.AI64Const, obj.TYPE_CONST, 0, 0, 0, 0, 0)
+		p = pp.Append(p, wasm.AI64Store, 0, 0, 0, obj.TYPE_CONST, 0, off+i)
 	}
 
 	return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
 	return pp.Prog(wasm.ANop)
 }
 
-func ssaMarkMoves(s *gc.SSAGenState, b *ssa.Block) {
+func ssaMarkMoves(s *ssagen.State, b *ssa.Block) {
 }
 
-func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
+func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
 	switch b.Kind {
 	case ssa.BlockPlain:
 		if next != b.Succs[0].Block() {
@@ -118,11 +121,11 @@
 	}
 }
 
-func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
+func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 	switch v.Op {
 	case ssa.OpWasmLoweredStaticCall, ssa.OpWasmLoweredClosureCall, ssa.OpWasmLoweredInterCall:
 		s.PrepareCall(v)
-		if call, ok := v.Aux.(*ssa.AuxCall); ok && call.Fn == gc.Deferreturn {
+		if call, ok := v.Aux.(*ssa.AuxCall); ok && call.Fn == ir.Syms.Deferreturn {
 			// add a resume point before call to deferreturn so it can be called again via jmpdefer
 			s.Prog(wasm.ARESUMEPOINT)
 		}
@@ -147,26 +150,26 @@
 		getValue32(s, v.Args[1])
 		i32Const(s, int32(v.AuxInt))
 		p := s.Prog(wasm.ACall)
-		p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: gc.WasmMove}
+		p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: ir.Syms.WasmMove}
 
 	case ssa.OpWasmLoweredZero:
 		getValue32(s, v.Args[0])
 		i32Const(s, int32(v.AuxInt))
 		p := s.Prog(wasm.ACall)
-		p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: gc.WasmZero}
+		p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: ir.Syms.WasmZero}
 
 	case ssa.OpWasmLoweredNilCheck:
 		getValue64(s, v.Args[0])
 		s.Prog(wasm.AI64Eqz)
 		s.Prog(wasm.AIf)
 		p := s.Prog(wasm.ACALLNORESUME)
-		p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: gc.SigPanic}
+		p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: ir.Syms.SigPanic}
 		s.Prog(wasm.AEnd)
 		if logopt.Enabled() {
 			logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
 		}
-		if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
-			gc.Warnl(v.Pos, "generated nil check")
+		if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
+			base.WarnfAt(v.Pos, "generated nil check")
 		}
 
 	case ssa.OpWasmLoweredWB:
@@ -185,7 +188,10 @@
 		getReg(s, wasm.REG_SP)
 		getValue64(s, v.Args[0])
 		p := s.Prog(storeOp(v.Type))
-		gc.AddrAuto(&p.To, v)
+		ssagen.AddrAuto(&p.To, v)
+
+	case ssa.OpClobber, ssa.OpClobberReg:
+		// TODO: implement for clobberdead experiment. Nop is ok for now.
 
 	default:
 		if v.Type.IsMemory() {
@@ -205,7 +211,7 @@
 	}
 }
 
-func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) {
+func ssaGenValueOnStack(s *ssagen.State, v *ssa.Value, extend bool) {
 	switch v.Op {
 	case ssa.OpWasmLoweredGetClosurePtr:
 		getReg(s, wasm.REG_CTXT)
@@ -240,10 +246,10 @@
 		p.From.Type = obj.TYPE_ADDR
 		switch v.Aux.(type) {
 		case *obj.LSym:
-			gc.AddAux(&p.From, v)
-		case *gc.Node:
+			ssagen.AddAux(&p.From, v)
+		case *ir.Name:
 			p.From.Reg = v.Args[0].Reg()
-			gc.AddAux(&p.From, v)
+			ssagen.AddAux(&p.From, v)
 		default:
 			panic("wasm: bad LoweredAddr")
 		}
@@ -312,33 +318,33 @@
 		if v.Type.Size() == 8 {
 			// Division of int64 needs helper function wasmDiv to handle the MinInt64 / -1 case.
 			p := s.Prog(wasm.ACall)
-			p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: gc.WasmDiv}
+			p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: ir.Syms.WasmDiv}
 			break
 		}
 		s.Prog(wasm.AI64DivS)
 
 	case ssa.OpWasmI64TruncSatF32S, ssa.OpWasmI64TruncSatF64S:
 		getValue64(s, v.Args[0])
-		if objabi.GOWASM.SatConv {
+		if buildcfg.GOWASM.SatConv {
 			s.Prog(v.Op.Asm())
 		} else {
 			if v.Op == ssa.OpWasmI64TruncSatF32S {
 				s.Prog(wasm.AF64PromoteF32)
 			}
 			p := s.Prog(wasm.ACall)
-			p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: gc.WasmTruncS}
+			p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: ir.Syms.WasmTruncS}
 		}
 
 	case ssa.OpWasmI64TruncSatF32U, ssa.OpWasmI64TruncSatF64U:
 		getValue64(s, v.Args[0])
-		if objabi.GOWASM.SatConv {
+		if buildcfg.GOWASM.SatConv {
 			s.Prog(v.Op.Asm())
 		} else {
 			if v.Op == ssa.OpWasmI64TruncSatF32U {
 				s.Prog(wasm.AF64PromoteF32)
 			}
 			p := s.Prog(wasm.ACall)
-			p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: gc.WasmTruncU}
+			p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: ir.Syms.WasmTruncU}
 		}
 
 	case ssa.OpWasmF32DemoteF64:
@@ -360,7 +366,7 @@
 
 	case ssa.OpLoadReg:
 		p := s.Prog(loadOp(v.Type))
-		gc.AddrAuto(&p.From, v.Args[0])
+		ssagen.AddrAuto(&p.From, v.Args[0])
 
 	case ssa.OpCopy:
 		getValue64(s, v.Args[0])
@@ -382,7 +388,7 @@
 	}
 }
 
-func getValue32(s *gc.SSAGenState, v *ssa.Value) {
+func getValue32(s *ssagen.State, v *ssa.Value) {
 	if v.OnWasmStack {
 		s.OnWasmStackSkipped--
 		ssaGenValueOnStack(s, v, false)
@@ -399,7 +405,7 @@
 	}
 }
 
-func getValue64(s *gc.SSAGenState, v *ssa.Value) {
+func getValue64(s *ssagen.State, v *ssa.Value) {
 	if v.OnWasmStack {
 		s.OnWasmStackSkipped--
 		ssaGenValueOnStack(s, v, true)
@@ -413,32 +419,32 @@
 	}
 }
 
-func i32Const(s *gc.SSAGenState, val int32) {
+func i32Const(s *ssagen.State, val int32) {
 	p := s.Prog(wasm.AI32Const)
 	p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(val)}
 }
 
-func i64Const(s *gc.SSAGenState, val int64) {
+func i64Const(s *ssagen.State, val int64) {
 	p := s.Prog(wasm.AI64Const)
 	p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: val}
 }
 
-func f32Const(s *gc.SSAGenState, val float64) {
+func f32Const(s *ssagen.State, val float64) {
 	p := s.Prog(wasm.AF32Const)
 	p.From = obj.Addr{Type: obj.TYPE_FCONST, Val: val}
 }
 
-func f64Const(s *gc.SSAGenState, val float64) {
+func f64Const(s *ssagen.State, val float64) {
 	p := s.Prog(wasm.AF64Const)
 	p.From = obj.Addr{Type: obj.TYPE_FCONST, Val: val}
 }
 
-func getReg(s *gc.SSAGenState, reg int16) {
+func getReg(s *ssagen.State, reg int16) {
 	p := s.Prog(wasm.AGet)
 	p.From = obj.Addr{Type: obj.TYPE_REG, Reg: reg}
 }
 
-func setReg(s *gc.SSAGenState, reg int16) {
+func setReg(s *ssagen.State, reg int16) {
 	p := s.Prog(wasm.ASet)
 	p.To = obj.Addr{Type: obj.TYPE_REG, Reg: reg}
 }
diff --git a/src/cmd/compile/internal/x86/galign.go b/src/cmd/compile/internal/x86/galign.go
index e137daa..00a20e4 100644
--- a/src/cmd/compile/internal/x86/galign.go
+++ b/src/cmd/compile/internal/x86/galign.go
@@ -5,29 +5,30 @@
 package x86
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ssagen"
 	"cmd/internal/obj/x86"
-	"cmd/internal/objabi"
 	"fmt"
+	"internal/buildcfg"
 	"os"
 )
 
-func Init(arch *gc.Arch) {
+func Init(arch *ssagen.ArchInfo) {
 	arch.LinkArch = &x86.Link386
 	arch.REGSP = x86.REGSP
 	arch.SSAGenValue = ssaGenValue
 	arch.SSAGenBlock = ssaGenBlock
 	arch.MAXWIDTH = (1 << 32) - 1
-	switch v := objabi.GO386; v {
+	switch v := buildcfg.GO386; v {
 	case "sse2":
 	case "softfloat":
 		arch.SoftFloat = true
 	case "387":
 		fmt.Fprintf(os.Stderr, "unsupported setting GO386=387. Consider using GO386=softfloat instead.\n")
-		gc.Exit(1)
+		base.Exit(1)
 	default:
 		fmt.Fprintf(os.Stderr, "unsupported setting GO386=%s\n", v)
-		gc.Exit(1)
+		base.Exit(1)
 
 	}
 
diff --git a/src/cmd/compile/internal/x86/ggen.go b/src/cmd/compile/internal/x86/ggen.go
index a33ddc8..3ca4797 100644
--- a/src/cmd/compile/internal/x86/ggen.go
+++ b/src/cmd/compile/internal/x86/ggen.go
@@ -5,39 +5,41 @@
 package x86
 
 import (
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
+	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/x86"
 )
 
-func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, ax *uint32) *obj.Prog {
+func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, ax *uint32) *obj.Prog {
 	if cnt == 0 {
 		return p
 	}
 	if *ax == 0 {
-		p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
+		p = pp.Append(p, x86.AMOVL, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
 		*ax = 1
 	}
 
-	if cnt <= int64(4*gc.Widthreg) {
-		for i := int64(0); i < cnt; i += int64(gc.Widthreg) {
-			p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off+i)
+	if cnt <= int64(4*types.RegSize) {
+		for i := int64(0); i < cnt; i += int64(types.RegSize) {
+			p = pp.Append(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off+i)
 		}
-	} else if cnt <= int64(128*gc.Widthreg) {
-		p = pp.Appendpp(p, x86.ALEAL, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
-		p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, 1*(128-cnt/int64(gc.Widthreg)))
-		p.To.Sym = gc.Duffzero
+	} else if cnt <= int64(128*types.RegSize) {
+		p = pp.Append(p, x86.ALEAL, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
+		p = pp.Append(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, 1*(128-cnt/int64(types.RegSize)))
+		p.To.Sym = ir.Syms.Duffzero
 	} else {
-		p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_CONST, 0, cnt/int64(gc.Widthreg), obj.TYPE_REG, x86.REG_CX, 0)
-		p = pp.Appendpp(p, x86.ALEAL, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
-		p = pp.Appendpp(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
-		p = pp.Appendpp(p, x86.ASTOSL, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
+		p = pp.Append(p, x86.AMOVL, obj.TYPE_CONST, 0, cnt/int64(types.RegSize), obj.TYPE_REG, x86.REG_CX, 0)
+		p = pp.Append(p, x86.ALEAL, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
+		p = pp.Append(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
+		p = pp.Append(p, x86.ASTOSL, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
 	}
 
 	return p
 }
 
-func ginsnop(pp *gc.Progs) *obj.Prog {
+func ginsnop(pp *objw.Progs) *obj.Prog {
 	// See comment in ../amd64/ggen.go.
 	p := pp.Prog(x86.AXCHGL)
 	p.From.Type = obj.TYPE_REG
diff --git a/src/cmd/compile/internal/x86/ssa.go b/src/cmd/compile/internal/x86/ssa.go
index fbf76d0..a06fdbc 100644
--- a/src/cmd/compile/internal/x86/ssa.go
+++ b/src/cmd/compile/internal/x86/ssa.go
@@ -8,16 +8,18 @@
 	"fmt"
 	"math"
 
-	"cmd/compile/internal/gc"
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
 	"cmd/compile/internal/logopt"
 	"cmd/compile/internal/ssa"
+	"cmd/compile/internal/ssagen"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/x86"
 )
 
 // markMoves marks any MOVXconst ops that need to avoid clobbering flags.
-func ssaMarkMoves(s *gc.SSAGenState, b *ssa.Block) {
+func ssaMarkMoves(s *ssagen.State, b *ssa.Block) {
 	flive := b.FlagsLiveAtEnd
 	for _, c := range b.ControlValues() {
 		flive = c.Type.IsFlags() || flive
@@ -107,7 +109,7 @@
 //     dest := dest(To) op src(From)
 // and also returns the created obj.Prog so it
 // may be further adjusted (offset, scale, etc).
-func opregreg(s *gc.SSAGenState, op obj.As, dest, src int16) *obj.Prog {
+func opregreg(s *ssagen.State, op obj.As, dest, src int16) *obj.Prog {
 	p := s.Prog(op)
 	p.From.Type = obj.TYPE_REG
 	p.To.Type = obj.TYPE_REG
@@ -116,7 +118,7 @@
 	return p
 }
 
-func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
+func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 	switch v.Op {
 	case ssa.Op386ADDL:
 		r := v.Reg()
@@ -159,31 +161,19 @@
 		ssa.Op386PXOR,
 		ssa.Op386ADCL,
 		ssa.Op386SBBL:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
-		opregreg(s, v.Op.Asm(), r, v.Args[1].Reg())
+		opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
 
 	case ssa.Op386ADDLcarry, ssa.Op386SUBLcarry:
 		// output 0 is carry/borrow, output 1 is the low 32 bits.
-		r := v.Reg0()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output[0] not in same register %s", v.LongString())
-		}
-		opregreg(s, v.Op.Asm(), r, v.Args[1].Reg())
+		opregreg(s, v.Op.Asm(), v.Reg0(), v.Args[1].Reg())
 
 	case ssa.Op386ADDLconstcarry, ssa.Op386SUBLconstcarry:
 		// output 0 is carry/borrow, output 1 is the low 32 bits.
-		r := v.Reg0()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output[0] not in same register %s", v.LongString())
-		}
 		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 = r
+		p.To.Reg = v.Reg0()
 
 	case ssa.Op386DIVL, ssa.Op386DIVW,
 		ssa.Op386DIVLU, ssa.Op386DIVWU,
@@ -304,20 +294,16 @@
 		// compute (x+y)/2 unsigned.
 		// Do a 32-bit add, the overflow goes into the carry.
 		// Shift right once and pull the carry back into the 31st bit.
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		p := s.Prog(x86.AADDL)
 		p.From.Type = obj.TYPE_REG
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
+		p.To.Reg = v.Reg()
 		p.From.Reg = v.Args[1].Reg()
 		p = s.Prog(x86.ARCRL)
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = 1
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
+		p.To.Reg = v.Reg()
 
 	case ssa.Op386ADDLconst:
 		r := v.Reg()
@@ -356,7 +342,7 @@
 		p.From.Offset = v.AuxInt
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = r
-		p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[0].Reg()})
+		p.SetFrom3Reg(v.Args[0].Reg())
 
 	case ssa.Op386SUBLconst,
 		ssa.Op386ADCLconst,
@@ -368,15 +354,11 @@
 		ssa.Op386SHRLconst, ssa.Op386SHRWconst, ssa.Op386SHRBconst,
 		ssa.Op386SARLconst, ssa.Op386SARWconst, ssa.Op386SARBconst,
 		ssa.Op386ROLLconst, ssa.Op386ROLWconst, ssa.Op386ROLBconst:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		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 = r
+		p.To.Reg = v.Reg()
 	case ssa.Op386SBBLcarrymask:
 		r := v.Reg()
 		p := s.Prog(v.Op.Asm())
@@ -404,14 +386,14 @@
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = r
 		p.From.Index = i
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.Op386LEAL:
 		p := s.Prog(x86.ALEAL)
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.Op386CMPL, ssa.Op386CMPW, ssa.Op386CMPB,
@@ -437,7 +419,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Args[1].Reg()
 	case ssa.Op386CMPLconstload, ssa.Op386CMPWconstload, ssa.Op386CMPBconstload:
@@ -445,9 +427,9 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux2(&p.From, v, sc.Off())
+		ssagen.AddAux2(&p.From, v, sc.Off64())
 		p.To.Type = obj.TYPE_CONST
-		p.To.Offset = sc.Val()
+		p.To.Offset = sc.Val64()
 	case ssa.Op386MOVLconst:
 		x := v.Reg()
 
@@ -480,9 +462,9 @@
 		p.From.Name = obj.NAME_EXTERN
 		f := math.Float64frombits(uint64(v.AuxInt))
 		if v.Op == ssa.Op386MOVSDconst1 {
-			p.From.Sym = gc.Ctxt.Float64Sym(f)
+			p.From.Sym = base.Ctxt.Float64Sym(f)
 		} else {
-			p.From.Sym = gc.Ctxt.Float32Sym(float32(f))
+			p.From.Sym = base.Ctxt.Float32Sym(float32(f))
 		}
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
@@ -497,7 +479,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.Op386MOVBloadidx1, ssa.Op386MOVWloadidx1, ssa.Op386MOVLloadidx1, ssa.Op386MOVSSloadidx1, ssa.Op386MOVSDloadidx1,
@@ -521,7 +503,7 @@
 		}
 		p.From.Reg = r
 		p.From.Index = i
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 	case ssa.Op386ADDLloadidx4, ssa.Op386SUBLloadidx4, ssa.Op386MULLloadidx4,
@@ -531,12 +513,9 @@
 		p.From.Reg = v.Args[1].Reg()
 		p.From.Index = v.Args[2].Reg()
 		p.From.Scale = 4
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 	case ssa.Op386ADDLload, ssa.Op386SUBLload, ssa.Op386MULLload,
 		ssa.Op386ANDLload, ssa.Op386ORLload, ssa.Op386XORLload,
 		ssa.Op386ADDSDload, ssa.Op386ADDSSload, ssa.Op386SUBSDload, ssa.Op386SUBSSload,
@@ -544,12 +523,9 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = v.Args[1].Reg()
-		gc.AddAux(&p.From, v)
+		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 	case ssa.Op386MOVSSstore, ssa.Op386MOVSDstore, ssa.Op386MOVLstore, ssa.Op386MOVWstore, ssa.Op386MOVBstore,
 		ssa.Op386ADDLmodify, ssa.Op386SUBLmodify, ssa.Op386ANDLmodify, ssa.Op386ORLmodify, ssa.Op386XORLmodify:
 		p := s.Prog(v.Op.Asm())
@@ -557,7 +533,7 @@
 		p.From.Reg = v.Args[1].Reg()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.Op386ADDLconstmodify:
 		sc := v.AuxValAndOff()
 		val := sc.Val()
@@ -568,23 +544,23 @@
 			} else {
 				p = s.Prog(x86.ADECL)
 			}
-			off := sc.Off()
+			off := sc.Off64()
 			p.To.Type = obj.TYPE_MEM
 			p.To.Reg = v.Args[0].Reg()
-			gc.AddAux2(&p.To, v, off)
+			ssagen.AddAux2(&p.To, v, off)
 			break
 		}
 		fallthrough
 	case ssa.Op386ANDLconstmodify, ssa.Op386ORLconstmodify, ssa.Op386XORLconstmodify:
 		sc := v.AuxValAndOff()
-		off := sc.Off()
-		val := sc.Val()
+		off := sc.Off64()
+		val := sc.Val64()
 		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)
+		ssagen.AddAux2(&p.To, v, off)
 	case ssa.Op386MOVBstoreidx1, ssa.Op386MOVWstoreidx1, ssa.Op386MOVLstoreidx1, ssa.Op386MOVSSstoreidx1, ssa.Op386MOVSDstoreidx1,
 		ssa.Op386MOVSDstoreidx8, ssa.Op386MOVSSstoreidx4, ssa.Op386MOVLstoreidx4, ssa.Op386MOVWstoreidx2,
 		ssa.Op386ADDLmodifyidx4, ssa.Op386SUBLmodifyidx4, ssa.Op386ANDLmodifyidx4, ssa.Op386ORLmodifyidx4, ssa.Op386XORLmodifyidx4:
@@ -610,15 +586,15 @@
 		}
 		p.To.Reg = r
 		p.To.Index = i
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 	case ssa.Op386MOVLstoreconst, ssa.Op386MOVWstoreconst, ssa.Op386MOVBstoreconst:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_CONST
 		sc := v.AuxValAndOff()
-		p.From.Offset = sc.Val()
+		p.From.Offset = sc.Val64()
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux2(&p.To, v, sc.Off())
+		ssagen.AddAux2(&p.To, v, sc.Off64())
 	case ssa.Op386ADDLconstmodifyidx4:
 		sc := v.AuxValAndOff()
 		val := sc.Val()
@@ -629,12 +605,12 @@
 			} else {
 				p = s.Prog(x86.ADECL)
 			}
-			off := sc.Off()
+			off := sc.Off64()
 			p.To.Type = obj.TYPE_MEM
 			p.To.Reg = v.Args[0].Reg()
 			p.To.Scale = 4
 			p.To.Index = v.Args[1].Reg()
-			gc.AddAux2(&p.To, v, off)
+			ssagen.AddAux2(&p.To, v, off)
 			break
 		}
 		fallthrough
@@ -643,7 +619,7 @@
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_CONST
 		sc := v.AuxValAndOff()
-		p.From.Offset = sc.Val()
+		p.From.Offset = sc.Val64()
 		r := v.Args[0].Reg()
 		i := v.Args[1].Reg()
 		switch v.Op {
@@ -661,7 +637,7 @@
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = r
 		p.To.Index = i
-		gc.AddAux2(&p.To, v, sc.Off())
+		ssagen.AddAux2(&p.To, v, sc.Off64())
 	case ssa.Op386MOVWLSX, ssa.Op386MOVBLSX, ssa.Op386MOVWLZX, ssa.Op386MOVBLZX,
 		ssa.Op386CVTSL2SS, ssa.Op386CVTSL2SD,
 		ssa.Op386CVTTSS2SL, ssa.Op386CVTTSD2SL,
@@ -670,12 +646,12 @@
 	case ssa.Op386DUFFZERO:
 		p := s.Prog(obj.ADUFFZERO)
 		p.To.Type = obj.TYPE_ADDR
-		p.To.Sym = gc.Duffzero
+		p.To.Sym = ir.Syms.Duffzero
 		p.To.Offset = v.AuxInt
 	case ssa.Op386DUFFCOPY:
 		p := s.Prog(obj.ADUFFCOPY)
 		p.To.Type = obj.TYPE_ADDR
-		p.To.Sym = gc.Duffcopy
+		p.To.Sym = ir.Syms.Duffcopy
 		p.To.Offset = v.AuxInt
 
 	case ssa.OpCopy: // TODO: use MOVLreg for reg->reg copies instead of OpCopy?
@@ -693,7 +669,7 @@
 			return
 		}
 		p := s.Prog(loadByType(v.Type))
-		gc.AddrAuto(&p.From, v.Args[0])
+		ssagen.AddrAuto(&p.From, v.Args[0])
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 
@@ -705,15 +681,15 @@
 		p := s.Prog(storeByType(v.Type))
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
-		gc.AddrAuto(&p.To, v)
+		ssagen.AddrAuto(&p.To, v)
 	case ssa.Op386LoweredGetClosurePtr:
 		// Closure pointer is DX.
-		gc.CheckLoweredGetClosurePtr(v)
+		ssagen.CheckLoweredGetClosurePtr(v)
 	case ssa.Op386LoweredGetG:
 		r := v.Reg()
 		// See the comments in cmd/internal/obj/x86/obj6.go
 		// near CanUse1InsnTLS for a detailed explanation of these instructions.
-		if x86.CanUse1InsnTLS(gc.Ctxt) {
+		if x86.CanUse1InsnTLS(base.Ctxt) {
 			// MOVL (TLS), r
 			p := s.Prog(x86.AMOVL)
 			p.From.Type = obj.TYPE_MEM
@@ -749,7 +725,7 @@
 		// 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.Offset = -base.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()
@@ -764,14 +740,14 @@
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+		p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
 		s.UseArgs(8) // space used in callee args area by assembly stubs
 
 	case ssa.Op386LoweredPanicExtendA, ssa.Op386LoweredPanicExtendB, ssa.Op386LoweredPanicExtendC:
 		p := s.Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM
 		p.To.Name = obj.NAME_EXTERN
-		p.To.Sym = gc.ExtendCheckFunc[v.AuxInt]
+		p.To.Sym = ssagen.ExtendCheckFunc[v.AuxInt]
 		s.UseArgs(12) // space used in callee args area by assembly stubs
 
 	case ssa.Op386CALLstatic, ssa.Op386CALLclosure, ssa.Op386CALLinter:
@@ -779,16 +755,12 @@
 	case ssa.Op386NEGL,
 		ssa.Op386BSWAPL,
 		ssa.Op386NOTL:
-		r := v.Reg()
-		if r != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		p := s.Prog(v.Op.Asm())
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = r
+		p.To.Reg = v.Reg()
 	case ssa.Op386BSFL, ssa.Op386BSFW,
 		ssa.Op386BSRL, ssa.Op386BSRW,
-		ssa.Op386SQRTSD:
+		ssa.Op386SQRTSS, ssa.Op386SQRTSD:
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
@@ -846,12 +818,12 @@
 		p.From.Reg = x86.REG_AX
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
 		if logopt.Enabled() {
 			logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
 		}
-		if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
-			gc.Warnl(v.Pos, "generated nil check")
+		if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
+			base.WarnfAt(v.Pos, "generated nil check")
 		}
 	case ssa.OpClobber:
 		p := s.Prog(x86.AMOVL)
@@ -859,7 +831,9 @@
 		p.From.Offset = 0xdeaddead
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = x86.REG_SP
-		gc.AddAux(&p.To, v)
+		ssagen.AddAux(&p.To, v)
+	case ssa.OpClobberReg:
+		// TODO: implement for clobberdead experiment. Nop is ok for now.
 	default:
 		v.Fatalf("genValue not implemented: %s", v.LongString())
 	}
@@ -884,22 +858,22 @@
 	ssa.Block386NAN: {x86.AJPS, x86.AJPC},
 }
 
-var eqfJumps = [2][2]gc.IndexJump{
+var eqfJumps = [2][2]ssagen.IndexJump{
 	{{Jump: x86.AJNE, Index: 1}, {Jump: x86.AJPS, Index: 1}}, // next == b.Succs[0]
 	{{Jump: x86.AJNE, Index: 1}, {Jump: x86.AJPC, Index: 0}}, // next == b.Succs[1]
 }
-var nefJumps = [2][2]gc.IndexJump{
+var nefJumps = [2][2]ssagen.IndexJump{
 	{{Jump: x86.AJNE, Index: 0}, {Jump: x86.AJPC, Index: 1}}, // next == b.Succs[0]
 	{{Jump: x86.AJNE, Index: 0}, {Jump: x86.AJPS, Index: 0}}, // next == b.Succs[1]
 }
 
-func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
+func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
 	switch b.Kind {
 	case ssa.BlockPlain:
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 	case ssa.BlockDefer:
 		// defer returns in rax:
@@ -912,11 +886,11 @@
 		p.To.Reg = x86.REG_AX
 		p = s.Prog(x86.AJNE)
 		p.To.Type = obj.TYPE_BRANCH
-		s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+		s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[1].Block()})
 		if b.Succs[0].Block() != next {
 			p := s.Prog(obj.AJMP)
 			p.To.Type = obj.TYPE_BRANCH
-			s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+			s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()})
 		}
 	case ssa.BlockExit:
 	case ssa.BlockRet:
diff --git a/src/cmd/compile/main.go b/src/cmd/compile/main.go
index 3aa64a5..3af1e1f 100644
--- a/src/cmd/compile/main.go
+++ b/src/cmd/compile/main.go
@@ -8,21 +8,23 @@
 	"cmd/compile/internal/amd64"
 	"cmd/compile/internal/arm"
 	"cmd/compile/internal/arm64"
+	"cmd/compile/internal/base"
 	"cmd/compile/internal/gc"
 	"cmd/compile/internal/mips"
 	"cmd/compile/internal/mips64"
 	"cmd/compile/internal/ppc64"
 	"cmd/compile/internal/riscv64"
 	"cmd/compile/internal/s390x"
+	"cmd/compile/internal/ssagen"
 	"cmd/compile/internal/wasm"
 	"cmd/compile/internal/x86"
-	"cmd/internal/objabi"
 	"fmt"
+	"internal/buildcfg"
 	"log"
 	"os"
 )
 
-var archInits = map[string]func(*gc.Arch){
+var archInits = map[string]func(*ssagen.ArchInfo){
 	"386":      x86.Init,
 	"amd64":    amd64.Init,
 	"arm":      arm.Init,
@@ -43,12 +45,13 @@
 	log.SetFlags(0)
 	log.SetPrefix("compile: ")
 
-	archInit, ok := archInits[objabi.GOARCH]
+	buildcfg.Check()
+	archInit, ok := archInits[buildcfg.GOARCH]
 	if !ok {
-		fmt.Fprintf(os.Stderr, "compile: unknown architecture %q\n", objabi.GOARCH)
+		fmt.Fprintf(os.Stderr, "compile: unknown architecture %q\n", buildcfg.GOARCH)
 		os.Exit(2)
 	}
 
 	gc.Main(archInit)
-	gc.Exit(0)
+	base.Exit(0)
 }
diff --git a/src/cmd/cover/func.go b/src/cmd/cover/func.go
index ce7c771..76a16b3 100644
--- a/src/cmd/cover/func.go
+++ b/src/cmd/cover/func.go
@@ -23,6 +23,8 @@
 	"runtime"
 	"strings"
 	"text/tabwriter"
+
+	"golang.org/x/tools/cover"
 )
 
 // funcOutput takes two file names as arguments, a coverage profile to read as input and an output
@@ -38,7 +40,7 @@
 //	total:		(statements)			91.9%
 
 func funcOutput(profile, outputFile string) error {
-	profiles, err := ParseProfiles(profile)
+	profiles, err := cover.ParseProfiles(profile)
 	if err != nil {
 		return err
 	}
@@ -144,7 +146,7 @@
 }
 
 // coverage returns the fraction of the statements in the function that were covered, as a numerator and denominator.
-func (f *FuncExtent) coverage(profile *Profile) (num, den int64) {
+func (f *FuncExtent) coverage(profile *cover.Profile) (num, den int64) {
 	// We could avoid making this n^2 overall by doing a single scan and annotating the functions,
 	// but the sizes of the data structures is never very large and the scan is almost instantaneous.
 	var covered, total int64
@@ -175,7 +177,7 @@
 	}
 }
 
-func findPkgs(profiles []*Profile) (map[string]*Pkg, error) {
+func findPkgs(profiles []*cover.Profile) (map[string]*Pkg, error) {
 	// Run go list to find the location of every package we care about.
 	pkgs := make(map[string]*Pkg)
 	var list []string
diff --git a/src/cmd/cover/html.go b/src/cmd/cover/html.go
index b2865c4..3c1d17e 100644
--- a/src/cmd/cover/html.go
+++ b/src/cmd/cover/html.go
@@ -15,13 +15,15 @@
 	"os"
 	"path/filepath"
 	"strings"
+
+	"golang.org/x/tools/cover"
 )
 
 // htmlOutput reads the profile data from profile and generates an HTML
 // coverage report, writing it to outfile. If outfile is empty,
 // it writes the report to a temporary file and opens it in a web browser.
 func htmlOutput(profile, outfile string) error {
-	profiles, err := ParseProfiles(profile)
+	profiles, err := cover.ParseProfiles(profile)
 	if err != nil {
 		return err
 	}
@@ -92,7 +94,7 @@
 // percentCovered returns, as a percentage, the fraction of the statements in
 // the profile covered by the test run.
 // In effect, it reports the coverage of a given source file.
-func percentCovered(p *Profile) float64 {
+func percentCovered(p *cover.Profile) float64 {
 	var total, covered int64
 	for _, b := range p.Blocks {
 		total += int64(b.NumStmt)
@@ -108,7 +110,7 @@
 
 // htmlGen generates an HTML coverage report with the provided filename,
 // source code, and tokens, and writes it to the given Writer.
-func htmlGen(w io.Writer, src []byte, boundaries []Boundary) error {
+func htmlGen(w io.Writer, src []byte, boundaries []cover.Boundary) error {
 	dst := bufio.NewWriter(w)
 	for i := range src {
 		for len(boundaries) > 0 && boundaries[0].Offset == i {
diff --git a/src/cmd/cover/profile.go b/src/cmd/cover/profile.go
deleted file mode 100644
index 656c862..0000000
--- a/src/cmd/cover/profile.go
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file provides support for parsing coverage profiles
-// generated by "go test -coverprofile=cover.out".
-// It is a copy of golang.org/x/tools/cover/profile.go.
-
-package main
-
-import (
-	"bufio"
-	"fmt"
-	"math"
-	"os"
-	"regexp"
-	"sort"
-	"strconv"
-	"strings"
-)
-
-// Profile represents the profiling data for a specific file.
-type Profile struct {
-	FileName string
-	Mode     string
-	Blocks   []ProfileBlock
-}
-
-// ProfileBlock represents a single block of profiling data.
-type ProfileBlock struct {
-	StartLine, StartCol int
-	EndLine, EndCol     int
-	NumStmt, Count      int
-}
-
-type byFileName []*Profile
-
-func (p byFileName) Len() int           { return len(p) }
-func (p byFileName) Less(i, j int) bool { return p[i].FileName < p[j].FileName }
-func (p byFileName) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-// ParseProfiles parses profile data in the specified file and returns a
-// Profile for each source file described therein.
-func ParseProfiles(fileName string) ([]*Profile, error) {
-	pf, err := os.Open(fileName)
-	if err != nil {
-		return nil, err
-	}
-	defer pf.Close()
-
-	files := make(map[string]*Profile)
-	buf := bufio.NewReader(pf)
-	// First line is "mode: foo", where foo is "set", "count", or "atomic".
-	// Rest of file is in the format
-	//	encoding/base64/base64.go:34.44,37.40 3 1
-	// where the fields are: name.go:line.column,line.column numberOfStatements count
-	s := bufio.NewScanner(buf)
-	mode := ""
-	for s.Scan() {
-		line := s.Text()
-		if mode == "" {
-			const p = "mode: "
-			if !strings.HasPrefix(line, p) || line == p {
-				return nil, fmt.Errorf("bad mode line: %v", line)
-			}
-			mode = line[len(p):]
-			continue
-		}
-		m := lineRe.FindStringSubmatch(line)
-		if m == nil {
-			return nil, fmt.Errorf("line %q doesn't match expected format: %v", m, lineRe)
-		}
-		fn := m[1]
-		p := files[fn]
-		if p == nil {
-			p = &Profile{
-				FileName: fn,
-				Mode:     mode,
-			}
-			files[fn] = p
-		}
-		p.Blocks = append(p.Blocks, ProfileBlock{
-			StartLine: toInt(m[2]),
-			StartCol:  toInt(m[3]),
-			EndLine:   toInt(m[4]),
-			EndCol:    toInt(m[5]),
-			NumStmt:   toInt(m[6]),
-			Count:     toInt(m[7]),
-		})
-	}
-	if err := s.Err(); err != nil {
-		return nil, err
-	}
-	for _, p := range files {
-		sort.Sort(blocksByStart(p.Blocks))
-		// Merge samples from the same location.
-		j := 1
-		for i := 1; i < len(p.Blocks); i++ {
-			b := p.Blocks[i]
-			last := p.Blocks[j-1]
-			if b.StartLine == last.StartLine &&
-				b.StartCol == last.StartCol &&
-				b.EndLine == last.EndLine &&
-				b.EndCol == last.EndCol {
-				if b.NumStmt != last.NumStmt {
-					return nil, fmt.Errorf("inconsistent NumStmt: changed from %d to %d", last.NumStmt, b.NumStmt)
-				}
-				if mode == "set" {
-					p.Blocks[j-1].Count |= b.Count
-				} else {
-					p.Blocks[j-1].Count += b.Count
-				}
-				continue
-			}
-			p.Blocks[j] = b
-			j++
-		}
-		p.Blocks = p.Blocks[:j]
-	}
-	// Generate a sorted slice.
-	profiles := make([]*Profile, 0, len(files))
-	for _, profile := range files {
-		profiles = append(profiles, profile)
-	}
-	sort.Sort(byFileName(profiles))
-	return profiles, nil
-}
-
-type blocksByStart []ProfileBlock
-
-func (b blocksByStart) Len() int      { return len(b) }
-func (b blocksByStart) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
-func (b blocksByStart) Less(i, j int) bool {
-	bi, bj := b[i], b[j]
-	return bi.StartLine < bj.StartLine || bi.StartLine == bj.StartLine && bi.StartCol < bj.StartCol
-}
-
-var lineRe = regexp.MustCompile(`^(.+):([0-9]+).([0-9]+),([0-9]+).([0-9]+) ([0-9]+) ([0-9]+)$`)
-
-func toInt(s string) int {
-	i, err := strconv.Atoi(s)
-	if err != nil {
-		panic(err)
-	}
-	return i
-}
-
-// Boundary represents the position in a source file of the beginning or end of a
-// block as reported by the coverage profile. In HTML mode, it will correspond to
-// the opening or closing of a <span> tag and will be used to colorize the source
-type Boundary struct {
-	Offset int     // Location as a byte offset in the source file.
-	Start  bool    // Is this the start of a block?
-	Count  int     // Event count from the cover profile.
-	Norm   float64 // Count normalized to [0..1].
-	Index  int     // Order in input file.
-}
-
-// Boundaries returns a Profile as a set of Boundary objects within the provided src.
-func (p *Profile) Boundaries(src []byte) (boundaries []Boundary) {
-	// Find maximum count.
-	max := 0
-	for _, b := range p.Blocks {
-		if b.Count > max {
-			max = b.Count
-		}
-	}
-	// Divisor for normalization.
-	divisor := math.Log(float64(max))
-
-	// boundary returns a Boundary, populating the Norm field with a normalized Count.
-	index := 0
-	boundary := func(offset int, start bool, count int) Boundary {
-		b := Boundary{Offset: offset, Start: start, Count: count, Index: index}
-		index++
-		if !start || count == 0 {
-			return b
-		}
-		if max <= 1 {
-			b.Norm = 0.8 // Profile is in "set" mode; we want a heat map. Use cov8 in the CSS.
-		} else if count > 0 {
-			b.Norm = math.Log(float64(count)) / divisor
-		}
-		return b
-	}
-
-	line, col := 1, 2 // TODO: Why is this 2?
-	for si, bi := 0, 0; si < len(src) && bi < len(p.Blocks); {
-		b := p.Blocks[bi]
-		if b.StartLine == line && b.StartCol == col {
-			boundaries = append(boundaries, boundary(si, true, b.Count))
-		}
-		if b.EndLine == line && b.EndCol == col || line > b.EndLine {
-			boundaries = append(boundaries, boundary(si, false, 0))
-			bi++
-			continue // Don't advance through src; maybe the next block starts here.
-		}
-		if src[si] == '\n' {
-			line++
-			col = 0
-		}
-		col++
-		si++
-	}
-	sort.Sort(boundariesByPos(boundaries))
-	return
-}
-
-type boundariesByPos []Boundary
-
-func (b boundariesByPos) Len() int      { return len(b) }
-func (b boundariesByPos) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
-func (b boundariesByPos) Less(i, j int) bool {
-	if b[i].Offset == b[j].Offset {
-		// Boundaries at the same offset should be ordered according to
-		// their original position.
-		return b[i].Index < b[j].Index
-	}
-	return b[i].Offset < b[j].Offset
-}
diff --git a/src/cmd/cover/testdata/toolexec.go b/src/cmd/cover/testdata/toolexec.go
index 386de79..458adae 100644
--- a/src/cmd/cover/testdata/toolexec.go
+++ b/src/cmd/cover/testdata/toolexec.go
@@ -15,8 +15,8 @@
 package main
 
 import (
-	"os"
 	exec "internal/execabs"
+	"os"
 	"strings"
 )
 
diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
index c8c3212..bec1769 100644
--- a/src/cmd/dist/build.go
+++ b/src/cmd/dist/build.go
@@ -14,6 +14,7 @@
 	"os"
 	"os/exec"
 	"path/filepath"
+	"regexp"
 	"sort"
 	"strings"
 	"sync"
@@ -39,6 +40,7 @@
 	goextlinkenabled string
 	gogcflags        string // For running built compiler
 	goldflags        string
+	goexperiment     string
 	workdir          string
 	tooldir          string
 	oldgoos          string
@@ -111,9 +113,6 @@
 		fatalf("$GOROOT must be set")
 	}
 	goroot = filepath.Clean(b)
-	if modRoot := findModuleRoot(goroot); modRoot != "" {
-		fatalf("found go.mod file in %s: $GOROOT must not be inside a module", modRoot)
-	}
 
 	b = os.Getenv("GOROOT_FINAL")
 	if b == "" {
@@ -197,6 +196,9 @@
 		goextlinkenabled = b
 	}
 
+	goexperiment = os.Getenv("GOEXPERIMENT")
+	// TODO(mdempsky): Validate known experiments?
+
 	gogcflags = os.Getenv("BOOT_GO_GCFLAGS")
 	goldflags = os.Getenv("BOOT_GO_LDFLAGS")
 
@@ -241,6 +243,9 @@
 	os.Setenv("LANGUAGE", "en_US.UTF8")
 
 	workdir = xworkdir()
+	if err := ioutil.WriteFile(pathf("%s/go.mod", workdir), []byte("module bootstrap"), 0666); err != nil {
+		fatalf("cannot write stub go.mod: %s", err)
+	}
 	xatexit(rmworkdir)
 
 	tooldir = pathf("%s/pkg/tool/%s_%s", goroot, gohostos, gohostarch)
@@ -401,8 +406,22 @@
 	}
 
 	if !precise {
-		// Tag does not point at HEAD; add hash and date to version.
-		tag += chomp(run(goroot, CheckExit, "git", "log", "-n", "1", "--format=format: +%h %cd", "HEAD"))
+		// Tag does not point at HEAD; add 1.x base version, hash, and date to version.
+		//
+		// Note that we lightly parse internal/goversion/goversion.go to
+		// obtain the base version. We can't just import the package,
+		// because cmd/dist is built with a bootstrap GOROOT which could
+		// be an entirely different version of Go, like 1.4. We assume
+		// that the file contains "const Version = <Integer>".
+
+		goversionSource := readfile(pathf("%s/src/internal/goversion/goversion.go", goroot))
+		m := regexp.MustCompile(`(?m)^const Version = (\d+)`).FindStringSubmatch(goversionSource)
+		if m == nil {
+			fatalf("internal/goversion/goversion.go does not contain 'const Version = ...'")
+		}
+		tag += fmt.Sprintf(" go1.%s-", m[1])
+
+		tag += chomp(run(goroot, CheckExit, "git", "log", "-n", "1", "--format=format:%h %cd", "HEAD"))
 	}
 
 	// Cache version.
@@ -834,18 +853,6 @@
 	goasmh := pathf("%s/go_asm.h", workdir)
 	if IsRuntimePackagePath(pkg) {
 		asmArgs = append(asmArgs, "-compiling-runtime")
-		if os.Getenv("GOEXPERIMENT") == "regabi" {
-			// In order to make it easier to port runtime assembly
-			// to the register ABI, we introduce a macro
-			// indicating the experiment is enabled.
-			//
-			// Note: a similar change also appears in
-			// cmd/go/internal/work/gc.go.
-			//
-			// TODO(austin): Remove this once we commit to the
-			// register ABI (#40724).
-			asmArgs = append(asmArgs, "-D=GOEXPERIMENT_REGABI=1")
-		}
 	}
 
 	// Collect symabis from assembly code.
@@ -1256,14 +1263,19 @@
 	timelog("start", "dist bootstrap")
 	defer timelog("end", "dist bootstrap")
 
-	var noBanner bool
+	var noBanner, noClean 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")
+	flag.BoolVar(&noClean, "no-clean", noClean, "print deprecation warning")
 
 	xflagparse(0)
 
+	if noClean {
+		xprintf("warning: --no-clean is deprecated and has no effect; use 'go install std cmd' instead\n")
+	}
+
 	// Set GOPATH to an internal directory. We shouldn't actually
 	// need to store files here, since the toolchain won't
 	// depend on modules outside of vendor directories, but if
@@ -1271,6 +1283,20 @@
 	// go tool may complain.
 	os.Setenv("GOPATH", pathf("%s/pkg/obj/gopath", goroot))
 
+	// Disable GOEXPERIMENT when building toolchain1 and
+	// go_bootstrap. We don't need any experiments for the
+	// bootstrap toolchain, and this lets us avoid duplicating the
+	// GOEXPERIMENT-related build logic from cmd/go here. If the
+	// bootstrap toolchain is < Go 1.17, it will ignore this
+	// anyway since GOEXPERIMENT is baked in; otherwise it will
+	// pick it up from the environment we set here. Once we're
+	// using toolchain1 with dist as the build system, we need to
+	// override this to keep the experiments assumed by the
+	// toolchain and by dist consistent. Once go_bootstrap takes
+	// over the build process, we'll set this back to the original
+	// GOEXPERIMENT.
+	os.Setenv("GOEXPERIMENT", "none")
+
 	if debug {
 		// cmd/buildid is used in debug mode.
 		toolchain = append(toolchain, "cmd/buildid")
@@ -1348,6 +1374,8 @@
 	}
 	xprintf("Building Go toolchain2 using go_bootstrap and Go toolchain1.\n")
 	os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
+	// Now that cmd/go is in charge of the build process, enable GOEXPERIMENT.
+	os.Setenv("GOEXPERIMENT", goexperiment)
 	goInstall(goBootstrap, append([]string{"-i"}, toolchain...)...)
 	if debug {
 		run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
@@ -1500,11 +1528,11 @@
 		goCmd = append(goCmd, "-p=1")
 	}
 
-	run(goroot, ShowOutput|CheckExit, append(goCmd, args...)...)
+	run(workdir, ShowOutput|CheckExit, append(goCmd, args...)...)
 }
 
 func checkNotStale(goBinary string, targets ...string) {
-	out := run(goroot, CheckExit,
+	out := run(workdir, CheckExit,
 		append([]string{
 			goBinary,
 			"list", "-gcflags=all=" + gogcflags, "-ldflags=all=" + goldflags,
@@ -1514,11 +1542,11 @@
 		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)
+				run(workdir, 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)
+		fatalf("unexpected stale targets reported by %s list -gcflags=\"%s\" -ldflags=\"%s\" for %v (consider rerunning with GOMAXPROCS=1 GODEBUG=gocachehash=1):\n%s", goBinary, gogcflags, goldflags, targets, out)
 	}
 }
 
@@ -1567,7 +1595,7 @@
 	"openbsd/amd64":   true,
 	"openbsd/arm":     true,
 	"openbsd/arm64":   true,
-	"openbsd/mips64":  false,
+	"openbsd/mips64":  true,
 	"plan9/386":       false,
 	"plan9/amd64":     false,
 	"plan9/arm":       false,
@@ -1575,6 +1603,7 @@
 	"windows/386":     true,
 	"windows/amd64":   true,
 	"windows/arm":     false,
+	"windows/arm64":   true,
 }
 
 // List of platforms which are supported but not complete yet. These get
@@ -1583,6 +1612,18 @@
 	"linux/sparc64": true,
 }
 
+// List of platforms which are first class ports. See golang.org/issue/38874.
+var firstClass = map[string]bool{
+	"darwin/amd64":  true,
+	"darwin/arm64":  true,
+	"linux/386":     true,
+	"linux/amd64":   true,
+	"linux/arm":     true,
+	"linux/arm64":   true,
+	"windows/386":   true,
+	"windows/amd64": true,
+}
+
 func needCC() bool {
 	switch os.Getenv("CGO_ENABLED") {
 	case "1":
@@ -1609,20 +1650,6 @@
 	}
 }
 
-func findModuleRoot(dir string) (root string) {
-	for {
-		if fi, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() {
-			return dir
-		}
-		d := filepath.Dir(dir)
-		if d == dir {
-			break
-		}
-		dir = d
-	}
-	return ""
-}
-
 func defaulttarg() string {
 	// xgetwd might return a path with symlinks fully resolved, and if
 	// there happens to be symlinks in goroot, then the hasprefix test
@@ -1733,6 +1760,7 @@
 		GOOS         string
 		GOARCH       string
 		CgoSupported bool
+		FirstClass   bool
 	}
 	var results []jsonResult
 	for _, p := range plats {
@@ -1740,7 +1768,8 @@
 		results = append(results, jsonResult{
 			GOOS:         fields[0],
 			GOARCH:       fields[1],
-			CgoSupported: cgoEnabled[p]})
+			CgoSupported: cgoEnabled[p],
+			FirstClass:   firstClass[p]})
 	}
 	out, err := json.MarshalIndent(results, "", "\t")
 	if err != nil {
@@ -1754,8 +1783,9 @@
 // IsRuntimePackagePath examines 'pkgpath' and returns TRUE if it
 // belongs to the collection of "runtime-related" packages, including
 // "runtime" itself, "reflect", "syscall", and the
-// "runtime/internal/*" packages. See also the function of the same
-// name in cmd/internal/objabi/path.go.
+// "runtime/internal/*" packages.
+//
+// Keep in sync with cmd/internal/objabi/path.go:IsRuntimePackagePath.
 func IsRuntimePackagePath(pkgpath string) bool {
 	rval := false
 	switch pkgpath {
@@ -1765,6 +1795,8 @@
 		rval = true
 	case "syscall":
 		rval = true
+	case "internal/bytealg":
+		rval = true
 	default:
 		rval = strings.HasPrefix(pkgpath, "runtime/internal")
 	}
diff --git a/src/cmd/dist/buildruntime.go b/src/cmd/dist/buildruntime.go
index 2744951..54e935a 100644
--- a/src/cmd/dist/buildruntime.go
+++ b/src/cmd/dist/buildruntime.go
@@ -19,8 +19,6 @@
 //
 //	package sys
 //
-//	const TheVersion = <version>
-//	const Goexperiment = <goexperiment>
 //	const StackGuardMultiplier = <multiplier value>
 //
 func mkzversion(dir, file string) {
@@ -29,29 +27,20 @@
 	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 StackGuardMultiplierDefault = %d\n", stackGuardMultiplierDefault())
 
 	writefile(buf.String(), file, writeSkipSame)
 }
 
-// mkzbootstrap writes cmd/internal/objabi/zbootstrap.go:
+// mkbuildcfg writes internal/buildcfg/zbootstrap.go:
 //
-//	package objabi
+//	package buildcfg
 //
 //	const defaultGOROOT = <goroot>
 //	const defaultGO386 = <go386>
-//	const defaultGOARM = <goarm>
-//	const defaultGOMIPS = <gomips>
-//	const defaultGOMIPS64 = <gomips64>
-//	const defaultGOPPC64 = <goppc64>
+//	...
 //	const defaultGOOS = runtime.GOOS
 //	const defaultGOARCH = runtime.GOARCH
-//	const defaultGO_EXTLINK_ENABLED = <goextlinkenabled>
-//	const version = <version>
-//	const stackGuardMultiplierDefault = <multiplier value>
-//	const goexperiment = <goexperiment>
 //
 // The use of runtime.GOOS and runtime.GOARCH makes sure that
 // a cross-compiled compiler expects to compile for its own target
@@ -62,11 +51,11 @@
 // the resulting compiler will default to generating linux/ppc64 object files.
 // This is more useful than having it default to generating objects for the
 // original target (in this example, a Mac).
-func mkzbootstrap(file string) {
+func mkbuildcfg(file string) {
 	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.Fprintf(&buf, "package buildcfg\n")
 	fmt.Fprintln(&buf)
 	fmt.Fprintf(&buf, "import \"runtime\"\n")
 	fmt.Fprintln(&buf)
@@ -75,13 +64,29 @@
 	fmt.Fprintf(&buf, "const defaultGOMIPS = `%s`\n", gomips)
 	fmt.Fprintf(&buf, "const defaultGOMIPS64 = `%s`\n", gomips64)
 	fmt.Fprintf(&buf, "const defaultGOPPC64 = `%s`\n", goppc64)
-	fmt.Fprintf(&buf, "const defaultGOOS = runtime.GOOS\n")
-	fmt.Fprintf(&buf, "const defaultGOARCH = runtime.GOARCH\n")
+	fmt.Fprintf(&buf, "const defaultGOEXPERIMENT = `%s`\n", goexperiment)
 	fmt.Fprintf(&buf, "const defaultGO_EXTLINK_ENABLED = `%s`\n", goextlinkenabled)
 	fmt.Fprintf(&buf, "const defaultGO_LDSO = `%s`\n", defaultldso)
 	fmt.Fprintf(&buf, "const version = `%s`\n", findgoversion())
+	fmt.Fprintf(&buf, "const defaultGOOS = runtime.GOOS\n")
+	fmt.Fprintf(&buf, "const defaultGOARCH = runtime.GOARCH\n")
+
+	writefile(buf.String(), file, writeSkipSame)
+}
+
+// mkobjabi writes cmd/internal/objabi/zbootstrap.go:
+//
+//	package objabi
+//
+//	const stackGuardMultiplierDefault = <multiplier value>
+//
+func mkobjabi(file string) {
+	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, "const stackGuardMultiplierDefault = %d\n", stackGuardMultiplierDefault())
-	fmt.Fprintf(&buf, "const goexperiment = `%s`\n", os.Getenv("GOEXPERIMENT"))
 
 	writefile(buf.String(), file, writeSkipSame)
 }
diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go
index cf85f2a..26b33e3 100644
--- a/src/cmd/dist/buildtool.go
+++ b/src/cmd/dist/buildtool.go
@@ -23,80 +23,43 @@
 // compiled with a Go 1.4 toolchain to produce the bootstrapTargets.
 // All directories in this list are relative to and must be below $GOROOT/src.
 //
-// The list has have two kinds of entries: names beginning with cmd/ with
+// The list has two kinds of entries: names beginning with cmd/ with
 // no other slashes, which are commands, and other paths, which are packages
 // supporting the commands. Packages in the standard library can be listed
 // if a newer copy needs to be substituted for the Go 1.4 copy when used
-// by the command packages.
+// by the command packages. Paths ending with /... automatically
+// include all packages within subdirectories as well.
 // These will be imported during bootstrap as bootstrap/name, like bootstrap/math/big.
 var bootstrapDirs = []string{
 	"cmd/asm",
-	"cmd/asm/internal/arch",
-	"cmd/asm/internal/asm",
-	"cmd/asm/internal/flags",
-	"cmd/asm/internal/lex",
+	"cmd/asm/internal/...",
 	"cmd/cgo",
 	"cmd/compile",
-	"cmd/compile/internal/amd64",
-	"cmd/compile/internal/arm",
-	"cmd/compile/internal/arm64",
-	"cmd/compile/internal/gc",
-	"cmd/compile/internal/logopt",
-	"cmd/compile/internal/mips",
-	"cmd/compile/internal/mips64",
-	"cmd/compile/internal/ppc64",
-	"cmd/compile/internal/riscv64",
-	"cmd/compile/internal/s390x",
-	"cmd/compile/internal/ssa",
-	"cmd/compile/internal/syntax",
-	"cmd/compile/internal/types",
-	"cmd/compile/internal/x86",
-	"cmd/compile/internal/wasm",
+	"cmd/compile/internal/...",
+	"cmd/internal/archive",
 	"cmd/internal/bio",
 	"cmd/internal/codesign",
-	"cmd/internal/gcprog",
 	"cmd/internal/dwarf",
 	"cmd/internal/edit",
+	"cmd/internal/gcprog",
 	"cmd/internal/goobj",
+	"cmd/internal/obj/...",
 	"cmd/internal/objabi",
-	"cmd/internal/obj",
-	"cmd/internal/obj/arm",
-	"cmd/internal/obj/arm64",
-	"cmd/internal/obj/mips",
-	"cmd/internal/obj/ppc64",
-	"cmd/internal/obj/riscv",
-	"cmd/internal/obj/s390x",
-	"cmd/internal/obj/x86",
-	"cmd/internal/obj/wasm",
 	"cmd/internal/pkgpath",
 	"cmd/internal/src",
 	"cmd/internal/sys",
 	"cmd/link",
-	"cmd/link/internal/amd64",
-	"cmd/link/internal/arm",
-	"cmd/link/internal/arm64",
-	"cmd/link/internal/benchmark",
-	"cmd/link/internal/ld",
-	"cmd/link/internal/loadelf",
-	"cmd/link/internal/loader",
-	"cmd/link/internal/loadmacho",
-	"cmd/link/internal/loadpe",
-	"cmd/link/internal/loadxcoff",
-	"cmd/link/internal/mips",
-	"cmd/link/internal/mips64",
-	"cmd/link/internal/ppc64",
-	"cmd/link/internal/riscv64",
-	"cmd/link/internal/s390x",
-	"cmd/link/internal/sym",
-	"cmd/link/internal/x86",
+	"cmd/link/internal/...",
 	"compress/flate",
 	"compress/zlib",
-	"cmd/link/internal/wasm",
 	"container/heap",
 	"debug/dwarf",
 	"debug/elf",
 	"debug/macho",
 	"debug/pe",
+	"go/constant",
+	"internal/buildcfg",
+	"internal/goexperiment",
 	"internal/goversion",
 	"internal/race",
 	"internal/unsafeheader",
@@ -104,6 +67,7 @@
 	"math/big",
 	"math/bits",
 	"sort",
+	"strconv",
 }
 
 // File prefixes that are ignored by go/build anyway, and cause
@@ -111,6 +75,7 @@
 var ignorePrefixes = []string{
 	".",
 	"_",
+	"#",
 }
 
 // File suffixes that use build tags introduced since Go 1.4.
@@ -124,6 +89,7 @@
 	"_wasm.s",
 	"_wasm.go",
 	"_test.s",
+	"_test.go",
 }
 
 func bootstrapBuildTools() {
@@ -133,7 +99,8 @@
 	}
 	xprintf("Building Go toolchain1 using %s.\n", goroot_bootstrap)
 
-	mkzbootstrap(pathf("%s/src/cmd/internal/objabi/zbootstrap.go", goroot))
+	mkbuildcfg(pathf("%s/src/internal/buildcfg/zbootstrap.go", goroot))
+	mkobjabi(pathf("%s/src/cmd/internal/objabi/zbootstrap.go", goroot))
 
 	// Use $GOROOT/pkg/bootstrap as the bootstrap workspace root.
 	// We use a subdirectory of $GOROOT/pkg because that's the
@@ -149,31 +116,47 @@
 	// Copy source code into $GOROOT/pkg/bootstrap and rewrite import paths.
 	writefile("module bootstrap\n", pathf("%s/%s", base, "go.mod"), 0)
 	for _, dir := range bootstrapDirs {
-		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) {
+		recurse := strings.HasSuffix(dir, "/...")
+		dir = strings.TrimSuffix(dir, "/...")
+		filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
+			if err != nil {
+				fatalf("walking bootstrap dirs failed: %v: %v", path, err)
+			}
+
+			name := filepath.Base(path)
+			src := pathf("%s/src/%s", goroot, path)
+			dst := pathf("%s/%s", base, path)
+
+			if info.IsDir() {
+				if !recurse && path != dir || name == "testdata" {
+					return filepath.SkipDir
+				}
+
+				xmkdirall(dst)
+				if path == "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))
+					mkzdefaultcc("", pathf("%s/zdefaultcc.go", dst))
+				}
+				return nil
+			}
+
 			for _, pre := range ignorePrefixes {
 				if strings.HasPrefix(name, pre) {
-					continue Dir
+					return nil
 				}
 			}
 			for _, suf := range ignoreSuffixes {
 				if strings.HasSuffix(name, suf) {
-					continue Dir
+					return nil
 				}
 			}
-			srcFile := pathf("%s/%s", src, name)
-			dstFile := pathf("%s/%s", dst, name)
-			text := bootstrapRewriteFile(srcFile)
-			writefile(text, dstFile, 0)
-		}
+
+			text := bootstrapRewriteFile(src)
+			writefile(text, dst, 0)
+			return nil
+		})
 	}
 
 	// Set up environment for invoking Go 1.4 go command.
diff --git a/src/cmd/dist/sys_default.go b/src/cmd/dist/sys_default.go
index 821dc27..e87c84c 100644
--- a/src/cmd/dist/sys_default.go
+++ b/src/cmd/dist/sys_default.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows
 // +build !windows
 
 package main
diff --git a/src/cmd/dist/sys_windows.go b/src/cmd/dist/sys_windows.go
index 2f6a1b0..265f729 100644
--- a/src/cmd/dist/sys_windows.go
+++ b/src/cmd/dist/sys_windows.go
@@ -29,10 +29,13 @@
 	wProcessorRevision          uint16
 }
 
+// See https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info
 const (
 	PROCESSOR_ARCHITECTURE_AMD64 = 9
 	PROCESSOR_ARCHITECTURE_INTEL = 0
 	PROCESSOR_ARCHITECTURE_ARM   = 5
+	PROCESSOR_ARCHITECTURE_ARM64 = 12
+	PROCESSOR_ARCHITECTURE_IA64  = 6
 )
 
 var sysinfo systeminfo
@@ -46,6 +49,8 @@
 		gohostarch = "386"
 	case PROCESSOR_ARCHITECTURE_ARM:
 		gohostarch = "arm"
+	case PROCESSOR_ARCHITECTURE_ARM64:
+		gohostarch = "arm64"
 	default:
 		fatalf("unknown processor architecture")
 	}
diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go
index 4f081c9..f40fa92 100644
--- a/src/cmd/dist/test.go
+++ b/src/cmd/dist/test.go
@@ -42,6 +42,7 @@
 	if noRebuild {
 		t.rebuild = false
 	}
+
 	t.run()
 }
 
@@ -117,6 +118,21 @@
 		}
 	}
 
+	// Set GOTRACEBACK to system if the user didn't set a level explicitly.
+	// Since we're running tests for Go, we want as much detail as possible
+	// if something goes wrong.
+	//
+	// Set it before running any commands just in case something goes wrong.
+	if ok := isEnvSet("GOTRACEBACK"); !ok {
+		if err := os.Setenv("GOTRACEBACK", "system"); err != nil {
+			if t.keepGoing {
+				log.Printf("Failed to set GOTRACEBACK: %v", err)
+			} else {
+				fatalf("Failed to set GOTRACEBACK: %v", err)
+			}
+		}
+	}
+
 	if t.rebuild {
 		t.out("Building packages and commands.")
 		// Force rebuild the whole toolchain.
@@ -309,14 +325,24 @@
 	benchMatches []string
 )
 
-func (t *tester) registerStdTest(pkg string) {
-	testName := "go_test:" + pkg
+func (t *tester) registerStdTest(pkg string, useG3 bool) {
+	heading := "Testing packages."
+	testPrefix := "go_test:"
+	gcflags := gogcflags
+	if useG3 {
+		heading = "Testing packages with -G=3."
+		testPrefix = "go_test_g3:"
+		gcflags += " -G=3"
+	}
+
+	testName := testPrefix + pkg
 	if t.runRx == nil || t.runRx.MatchString(testName) == t.runRxWant {
 		stdMatches = append(stdMatches, pkg)
 	}
+
 	t.tests = append(t.tests, distTest{
 		name:    testName,
-		heading: "Testing packages.",
+		heading: heading,
 		fn: func(dt *distTest) error {
 			if ranGoTest {
 				return nil
@@ -343,7 +369,7 @@
 				"-short=" + short(),
 				t.tags(),
 				t.timeout(timeoutSec),
-				"-gcflags=all=" + gogcflags,
+				"-gcflags=all=" + gcflags,
 			}
 			if t.race {
 				args = append(args, "-race")
@@ -408,7 +434,10 @@
 	if len(t.runNames) > 0 {
 		for _, name := range t.runNames {
 			if strings.HasPrefix(name, "go_test:") {
-				t.registerStdTest(strings.TrimPrefix(name, "go_test:"))
+				t.registerStdTest(strings.TrimPrefix(name, "go_test:"), false)
+			}
+			if strings.HasPrefix(name, "go_test_g3:") {
+				t.registerStdTest(strings.TrimPrefix(name, "go_test_g3:"), true)
 			}
 			if strings.HasPrefix(name, "go_test_bench:") {
 				t.registerRaceBenchTest(strings.TrimPrefix(name, "go_test_bench:"))
@@ -431,8 +460,15 @@
 			fatalf("Error running go list std cmd: %v:\n%s", err, cmd.Stderr)
 		}
 		pkgs := strings.Fields(string(all))
+		if false {
+			// Disable -G=3 option for standard tests for now, since
+			// they are flaky on the builder.
+			for _, pkg := range pkgs {
+				t.registerStdTest(pkg, true /* -G=3 flag */)
+			}
+		}
 		for _, pkg := range pkgs {
-			t.registerStdTest(pkg)
+			t.registerStdTest(pkg, false)
 		}
 		if t.race {
 			for _, pkg := range pkgs {
@@ -455,6 +491,19 @@
 		})
 	}
 
+	// Test go/... cmd/gofmt with type parameters enabled.
+	if !t.compileOnly {
+		t.tests = append(t.tests, distTest{
+			name:    "tyepparams",
+			heading: "go/... and cmd/gofmt tests with tag typeparams",
+			fn: func(dt *distTest) error {
+				t.addCmd(dt, "src", t.goTest(), t.timeout(300), "-tags=typeparams", "go/...")
+				t.addCmd(dt, "src", t.goTest(), t.timeout(300), "-tags=typeparams", "cmd/gofmt")
+				return nil
+			},
+		})
+	}
+
 	if t.iOS() && !t.compileOnly {
 		t.tests = append(t.tests, distTest{
 			name:    "x509omitbundledroots",
@@ -673,14 +722,29 @@
 				},
 			})
 			if t.hasCxx() {
-				t.tests = append(t.tests, distTest{
-					name:    "swig_callback",
-					heading: "../misc/swig/callback",
-					fn: func(dt *distTest) error {
-						t.addCmd(dt, "misc/swig/callback", t.goTest())
-						return nil
+				t.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
+						},
 					},
-				})
+					distTest{
+						name:    "swig_callback_lto",
+						heading: "../misc/swig/callback",
+						fn: func(dt *distTest) error {
+							cmd := t.addCmd(dt, "misc/swig/callback", t.goTest())
+							cmd.Env = append(os.Environ(),
+								"CGO_CFLAGS=-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option",
+								"CGO_CXXFLAGS=-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option",
+								"CGO_LDFLAGS=-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option",
+							)
+							return nil
+						},
+					},
+				)
 			}
 		}
 	}
@@ -716,8 +780,10 @@
 		if gohostos == "linux" && goarch == "amd64" {
 			t.registerTest("testasan", "../misc/cgo/testasan", "go", "run", ".")
 		}
-		if mSanSupported(goos, goarch) {
-			t.registerHostTest("testsanitizers/msan", "../misc/cgo/testsanitizers", "misc/cgo/testsanitizers", ".")
+		if goos == "linux" && goarch != "ppc64le" {
+			// because syscall.SysProcAttr struct used in misc/cgo/testsanitizers is only built on linux.
+			// Some inconsistent failures happen on ppc64le so disable for now.
+			t.registerHostTest("testsanitizers", "../misc/cgo/testsanitizers", "misc/cgo/testsanitizers", ".")
 		}
 		if t.hasBash() && goos != "android" && !t.iOS() && gohostos != "windows" {
 			t.registerHostTest("cgo_errors", "../misc/cgo/errors", "misc/cgo/errors", ".")
@@ -942,6 +1008,9 @@
 	if goos == "ios" {
 		return false
 	}
+	if goos == "windows" && goarch == "arm64" {
+		return false
+	}
 	// Internally linking cgo is incomplete on some architectures.
 	// https://golang.org/issue/10373
 	// https://golang.org/issue/14449
@@ -988,7 +1057,7 @@
 			"darwin-amd64", "darwin-arm64",
 			"freebsd-amd64",
 			"android-arm", "android-arm64", "android-386",
-			"windows-amd64", "windows-386":
+			"windows-amd64", "windows-386", "windows-arm64":
 			return true
 		}
 		return false
@@ -1074,8 +1143,7 @@
 	cmd := t.addCmd(dt, "misc/cgo/test", t.goTest())
 	cmd.Env = append(os.Environ(), "GOFLAGS=-ldflags=-linkmode=auto")
 
-	// Skip internal linking cases on arm64 to support GCC-9.4 and above,
-	// only for linux, conservatively.
+	// Skip internal linking cases on linux/arm64 to support GCC-9.4 and above.
 	// See issue #39466.
 	skipInternalLink := goarch == "arm64" && goos == "linux"
 
@@ -1613,24 +1681,13 @@
 		return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64"
 	case "darwin":
 		return goarch == "amd64" || goarch == "arm64"
-	case "freebsd", "netbsd", "windows":
+	case "freebsd", "netbsd", "openbsd", "windows":
 		return goarch == "amd64"
 	default:
 		return false
 	}
 }
 
-// mSanSupported is a copy of the function cmd/internal/sys.MSanSupported,
-// which can't be used here because cmd/dist has to be buildable by Go 1.4.
-func mSanSupported(goos, goarch string) bool {
-	switch goos {
-	case "linux":
-		return goarch == "amd64" || goarch == "arm64"
-	default:
-		return false
-	}
-}
-
 // isUnsupportedVMASize reports whether the failure is caused by an unsupported
 // VMA for the race detector (for example, running the race detector on an
 // arm64 machine configured with 39-bit VMA)
@@ -1638,3 +1695,15 @@
 	unsupportedVMA := []byte("unsupported VMA range")
 	return w.dt.name == "race" && bytes.Contains(w.out, unsupportedVMA)
 }
+
+// isEnvSet reports whether the environment variable evar is
+// set in the environment.
+func isEnvSet(evar string) bool {
+	evarEq := evar + "="
+	for _, e := range os.Environ() {
+		if strings.HasPrefix(e, evarEq) {
+			return true
+		}
+	}
+	return false
+}
diff --git a/src/cmd/dist/test_linux.go b/src/cmd/dist/test_linux.go
index b6d0aed..43d28dc 100644
--- a/src/cmd/dist/test_linux.go
+++ b/src/cmd/dist/test_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux
 // +build linux
 
 package main
diff --git a/src/cmd/dist/util.go b/src/cmd/dist/util.go
index 0a419e4..df60145 100644
--- a/src/cmd/dist/util.go
+++ b/src/cmd/dist/util.go
@@ -249,6 +249,7 @@
 	if flag&writeExec != 0 {
 		mode = 0777
 	}
+	xremove(file) // in case of symlink tricks by misc/reboot test
 	err := ioutil.WriteFile(file, new, mode)
 	if err != nil {
 		fatalf("%v", err)
@@ -389,6 +390,10 @@
 		// sense to auto-detect the setting.
 		return "7"
 	}
+	if goos == "windows" {
+		// windows/arm only works with ARMv7 executables.
+		return "7"
+	}
 	if gohostarch != "arm" || goos != gohostos {
 		// Conservative default for cross-compilation.
 		return "5"
diff --git a/src/cmd/dist/util_gc.go b/src/cmd/dist/util_gc.go
index 17a0e6f..875784d 100644
--- a/src/cmd/dist/util_gc.go
+++ b/src/cmd/dist/util_gc.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo
+//go:build gc
+// +build gc
 
 package main
 
diff --git a/src/cmd/dist/util_gccgo.go b/src/cmd/dist/util_gccgo.go
index dc89723..3255b80 100644
--- a/src/cmd/dist/util_gccgo.go
+++ b/src/cmd/dist/util_gccgo.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gccgo
 // +build gccgo
 
 package main
diff --git a/src/cmd/dist/vfp_arm.s b/src/cmd/dist/vfp_arm.s
index d571f8b..525ee9b 100644
--- a/src/cmd/dist/vfp_arm.s
+++ b/src/cmd/dist/vfp_arm.s
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build gc,arm
+//go:build gc
+// +build gc
 
 #include "textflag.h"
 
diff --git a/src/cmd/dist/vfp_default.s b/src/cmd/dist/vfp_default.s
index 84829be..0c1e16b 100644
--- a/src/cmd/dist/vfp_default.s
+++ b/src/cmd/dist/vfp_default.s
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !arm,gc
+//go:build gc && !arm
+// +build gc,!arm
 
 #include "textflag.h"
 
diff --git a/src/cmd/doc/doc_test.go b/src/cmd/doc/doc_test.go
index 39530e3..af77931 100644
--- a/src/cmd/doc/doc_test.go
+++ b/src/cmd/doc/doc_test.go
@@ -579,7 +579,7 @@
 		[]string{
 			`Comment about exported interface`, // Include comment.
 			`type ExportedInterface interface`, // Interface definition.
-			`Comment before exported method.*\n.*ExportedMethod\(\)` +
+			`Comment before exported method.\n.*//\n.*//	// Code block showing how to use ExportedMethod\n.*//	func DoSomething\(\) error {\n.*//		ExportedMethod\(\)\n.*//		return nil\n.*//	}\n.*//.*\n.*ExportedMethod\(\)` +
 				`.*Comment on line with exported method`,
 			`io.Reader.*Comment on line with embedded Reader`,
 			`error.*Comment on line with embedded error`,
@@ -599,8 +599,7 @@
 		[]string{
 			`Comment about exported interface`, // Include comment.
 			`type ExportedInterface interface`, // Interface definition.
-			`Comment before exported method.*\n.*ExportedMethod\(\)` +
-				`.*Comment on line with exported method`,
+			`Comment before exported method.\n.*//\n.*//	// Code block showing how to use ExportedMethod\n.*//	func DoSomething\(\) error {\n.*//		ExportedMethod\(\)\n.*//		return nil\n.*//	}\n.*//.*\n.*ExportedMethod\(\)` + `.*Comment on line with exported method`,
 			`unexportedMethod\(\).*Comment on line with unexported method`,
 			`io.Reader.*Comment on line with embedded Reader`,
 			`error.*Comment on line with embedded error`,
@@ -615,7 +614,7 @@
 		"interface method",
 		[]string{p, `ExportedInterface.ExportedMethod`},
 		[]string{
-			`Comment before exported method.*\n.*ExportedMethod\(\)` +
+			`Comment before exported method.\n.*//\n.*//	// Code block showing how to use ExportedMethod\n.*//	func DoSomething\(\) error {\n.*//		ExportedMethod\(\)\n.*//		return nil\n.*//	}\n.*//.*\n.*ExportedMethod\(\)` +
 				`.*Comment on line with exported method`,
 		},
 		[]string{
diff --git a/src/cmd/doc/pkg.go b/src/cmd/doc/pkg.go
index c2e06eb..587f0bd 100644
--- a/src/cmd/doc/pkg.go
+++ b/src/cmd/doc/pkg.go
@@ -950,6 +950,9 @@
 			// Not an interface type.
 			continue
 		}
+
+		// Collect and print only the methods that match.
+		var methods []*ast.Field
 		for _, iMethod := range inter.Methods.List {
 			// This is an interface, so there can be only one name.
 			// TODO: Anonymous methods (embedding)
@@ -958,22 +961,21 @@
 			}
 			name := iMethod.Names[0].Name
 			if match(method, name) {
-				if iMethod.Doc != nil {
-					for _, comment := range iMethod.Doc.List {
-						doc.ToText(&pkg.buf, comment.Text, "", indent, indentedWidth)
-					}
-				}
-				s := pkg.oneLineNode(iMethod.Type)
-				// Hack: s starts "func" but there is no name present.
-				// We could instead build a FuncDecl but it's not worthwhile.
-				lineComment := ""
-				if iMethod.Comment != nil {
-					lineComment = fmt.Sprintf("  %s", iMethod.Comment.List[0].Text)
-				}
-				pkg.Printf("func %s%s%s\n", name, s[4:], lineComment)
+				methods = append(methods, iMethod)
 				found = true
 			}
 		}
+		if found {
+			pkg.Printf("type %s ", spec.Name)
+			inter.Methods.List, methods = methods, inter.Methods.List
+			err := format.Node(&pkg.buf, pkg.fs, inter)
+			if err != nil {
+				log.Fatal(err)
+			}
+			pkg.newlines(1)
+			// Restore the original methods.
+			inter.Methods.List = methods
+		}
 	}
 	return found
 }
diff --git a/src/cmd/doc/testdata/pkg.go b/src/cmd/doc/testdata/pkg.go
index d695bdf..5ece832 100644
--- a/src/cmd/doc/testdata/pkg.go
+++ b/src/cmd/doc/testdata/pkg.go
@@ -111,6 +111,13 @@
 // Comment about exported interface.
 type ExportedInterface interface {
 	// Comment before exported method.
+	//
+	//	// Code block showing how to use ExportedMethod
+	//	func DoSomething() error {
+	//		ExportedMethod()
+	//		return nil
+	//	}
+	//
 	ExportedMethod()   // Comment on line with exported method.
 	unexportedMethod() // Comment on line with unexported method.
 	io.Reader          // Comment on line with embedded Reader.
diff --git a/src/cmd/go.mod b/src/cmd/go.mod
index 70b1b06..cd03968 100644
--- a/src/cmd/go.mod
+++ b/src/cmd/go.mod
@@ -1,12 +1,15 @@
 module cmd
 
-go 1.16
+go 1.17
 
 require (
-	github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2
-	golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
-	golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
-	golang.org/x/mod v0.4.2-0.20210325185522-dbbbf8a3c6ea
-	golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
-	golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff
+	github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a
+	github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 // indirect
+	golang.org/x/arch v0.0.0-20210502124803-cbf565b21d1e
+	golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e // indirect
+	golang.org/x/mod v0.4.3-0.20210608190319-0f08993efd8a
+	golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 // indirect
+	golang.org/x/term v0.0.0-20210503060354-a79de5458b56
+	golang.org/x/tools v0.1.2-0.20210519160823-49064d2332f9
+	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
 )
diff --git a/src/cmd/go.sum b/src/cmd/go.sum
index edda18b..d728aca 100644
--- a/src/cmd/go.sum
+++ b/src/cmd/go.sum
@@ -1,38 +1,43 @@
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2 h1:HyOHhUtuB/Ruw/L5s5pG2D0kckkN2/IzBs9OClGHnHI=
-github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a h1:jmAp/2PZAScNd62lTD3Mcb0Ey9FvIIJtLohPhtxZJ+Q=
+github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff h1:XmKBi9R6duxOB3lfc72wyrwiOY7X2Jl1wuI+RFOyMDE=
-golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+golang.org/x/arch v0.0.0-20210502124803-cbf565b21d1e h1:pv3V0NlNSh5Q6AX/StwGLBjcLS7UN4m4Gq+V+uSecqM=
+golang.org/x/arch v0.0.0-20210502124803-cbf565b21d1e/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
-golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2-0.20210325185522-dbbbf8a3c6ea h1:zAn46O7Vmm6KdLXx+635hPZSArrt/wNctv4Ab70Jw3k=
-golang.org/x/mod v0.4.2-0.20210325185522-dbbbf8a3c6ea/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e h1:8foAy0aoO5GkqCvAEJ4VC4P3zksTg4X4aJCDpZzmgQI=
+golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.3-0.20210608190319-0f08993efd8a h1:e8qnjKz4EE6OjRki9wTadWSIogINvq10sMcuBRORxMY=
+golang.org/x/mod v0.4.3-0.20210608190319-0f08993efd8a/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso=
-golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 h1:yhBbb4IRs2HS9PPlAg6DMC6mUOKexJBNsLf4Z+6En1Q=
+golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=
+golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff h1:6EkB024TP1fu6cmQqeCNw685zYDVt5g8N1BXh755SQM=
-golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.2-0.20210519160823-49064d2332f9 h1:2XlR/j4I4xz5GQZI7zBjqTfezYyRIE2jD5IMousB2rg=
+golang.org/x/tools v0.1.2-0.20210519160823-49064d2332f9/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index 84f89c9..7f88d32 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -111,7 +111,7 @@
 // 	-p n
 // 		the number of programs, such as build commands or
 // 		test binaries, that can be run in parallel.
-// 		The default is the number of CPUs available.
+// 		The default is GOMAXPROCS, normally the number of CPUs available.
 // 	-race
 // 		enable data race detection.
 // 		Supported only on linux/amd64, freebsd/amd64, darwin/amd64, windows/amd64,
@@ -174,8 +174,8 @@
 // 		a build will run as if the disk file path exists with the contents
 // 		given by the backing file paths, or as if the disk file path does not
 // 		exist if its backing file path is empty. Support for the -overlay flag
-// 		has some limitations:importantly, cgo files included from outside the
-// 		include path must be  in the same directory as the Go package they are
+// 		has some limitations: importantly, cgo files included from outside the
+// 		include path must be in the same directory as the Go package they are
 // 		included from, and overlays will not appear when binaries and tests are
 // 		run through go run and go test respectively.
 // 	-pkgdir dir
@@ -198,6 +198,8 @@
 // 		a program to use to invoke toolchain programs like vet and asm.
 // 		For example, instead of running asm, the go command will run
 // 		'cmd args /path/to/asm <arguments for asm>'.
+// 		The TOOLEXEC_IMPORTPATH environment variable will be set,
+// 		matching 'go list -f {{.ImportPath}}' for the package being built.
 //
 // The -asmflags, -gccgoflags, -gcflags, and -ldflags flags accept a
 // space-separated list of arguments to pass to an underlying tool
@@ -291,7 +293,7 @@
 //
 // Usage:
 //
-// 	go doc [-u] [-c] [package|[package.]symbol[.methodOrField]]
+// 	go doc [doc flags] [package|[package.]symbol[.methodOrField]]
 //
 // Doc prints the documentation comments associated with the item identified by its
 // arguments (a package, const, func, type, var, method, or struct field)
@@ -596,7 +598,7 @@
 //
 // Usage:
 //
-// 	go get [-d] [-t] [-u] [-v] [-insecure] [build flags] [packages]
+// 	go get [-d] [-t] [-u] [-v] [build flags] [packages]
 //
 // Get resolves its command-line arguments to packages at specific module versions,
 // updates go.mod to require those versions, downloads source code into the
@@ -641,14 +643,6 @@
 // When the -t and -u flags are used together, get will update
 // test dependencies as well.
 //
-// The -insecure flag permits fetching from repositories and resolving
-// custom domains using insecure schemes such as HTTP, and also bypassess
-// module sum validation using the checksum database. Use with caution.
-// This flag is deprecated and will be removed in a future version of go.
-// To permit the use of insecure schemes, use the GOINSECURE environment
-// variable instead. To bypass module sum validation, use GOPRIVATE or
-// GONOSUMDB. See 'go help environment' for details.
-//
 // The -d flag instructs get not to build or install packages. get will only
 // update go.mod and download source code needed to build packages.
 //
@@ -849,6 +843,7 @@
 //         UseAllFiles   bool     // use files regardless of +build lines, file names
 //         Compiler      string   // compiler to assume when computing target paths
 //         BuildTags     []string // build constraints to match in +build lines
+//         ToolTags      []string // toolchain-specific build constraints
 //         ReleaseTags   []string // releases the current release is compatible with
 //         InstallSuffix string   // suffix to use in the name of the install dir
 //     }
@@ -1083,7 +1078,7 @@
 //
 // Usage:
 //
-// 	go mod edit [editing flags] [go.mod]
+// 	go mod edit [editing flags] [-fmt|-print|-json] [go.mod]
 //
 // Edit provides a command-line interface for editing go.mod,
 // for use primarily by tools or scripts. It reads only go.mod;
@@ -1142,12 +1137,12 @@
 // writing it back to go.mod. The JSON output corresponds to these Go types:
 //
 // 	type Module struct {
-// 		Path string
+// 		Path    string
 // 		Version string
 // 	}
 //
 // 	type GoMod struct {
-// 		Module  Module
+// 		Module  ModPath
 // 		Go      string
 // 		Require []Require
 // 		Exclude []Module
@@ -1155,6 +1150,11 @@
 // 		Retract []Retract
 // 	}
 //
+// 	type ModPath struct {
+// 		Path       string
+// 		Deprecated string
+// 	}
+//
 // 	type Require struct {
 // 		Path string
 // 		Version string
@@ -1186,13 +1186,17 @@
 //
 // Usage:
 //
-// 	go mod graph
+// 	go mod graph [-go=version]
 //
 // Graph prints the module requirement graph (with replacements applied)
 // in text form. Each line in the output has two space-separated fields: a module
 // and one of its requirements. Each module is identified as a string of the form
 // path@version, except for the main module, which has no @version suffix.
 //
+// The -go flag causes graph to report the module graph as loaded by the
+// given Go version, instead of the version indicated by the 'go' directive
+// in the go.mod file.
+//
 // See https://golang.org/ref/mod#go-mod-graph for more about 'go mod graph'.
 //
 //
@@ -1200,7 +1204,7 @@
 //
 // Usage:
 //
-// 	go mod init [module]
+// 	go mod init [module-path]
 //
 // Init initializes and writes a new go.mod file in the current directory, in
 // effect creating a new module rooted at the current directory. The go.mod file
@@ -1221,7 +1225,7 @@
 //
 // Usage:
 //
-// 	go mod tidy [-e] [-v]
+// 	go mod tidy [-e] [-v] [-go=version] [-compat=version]
 //
 // Tidy makes sure go.mod matches the source code in the module.
 // It adds any missing modules necessary to build the current module's
@@ -1235,6 +1239,20 @@
 // The -e flag causes tidy to attempt to proceed despite errors
 // encountered while loading packages.
 //
+// The -go flag causes tidy to update the 'go' directive in the go.mod
+// file to the given version, which may change which module dependencies
+// are retained as explicit requirements in the go.mod file.
+// (Go versions 1.17 and higher retain more requirements in order to
+// support lazy module loading.)
+//
+// The -compat flag preserves any additional checksums needed for the
+// 'go' command from the indicated major Go release to successfully load
+// the module graph, and causes tidy to error out if that version of the
+// 'go' command would load any imported package from a different module
+// version. By default, tidy acts as if the -compat flag were set to the
+// version prior to the one indicated by the 'go' directive in the go.mod
+// file.
+//
 // See https://golang.org/ref/mod#go-mod-tidy for more about 'go mod tidy'.
 //
 //
@@ -1318,10 +1336,21 @@
 // 	go run [build flags] [-exec xprog] package [arguments...]
 //
 // Run compiles and runs the named main Go package.
-// Typically the package is specified as a list of .go source files from a single directory,
-// but it may also be an import path, file system path, or pattern
+// Typically the package is specified as a list of .go source files from a single
+// directory, but it may also be an import path, file system path, or pattern
 // matching a single known package, as in 'go run .' or 'go run my/cmd'.
 //
+// If the package argument has a version suffix (like @latest or @v1.0.0),
+// "go run" builds the program in module-aware mode, ignoring the go.mod file in
+// the current directory or any parent directory, if there is one. This is useful
+// for running programs without affecting the dependencies of the main module.
+//
+// If the package argument doesn't have a version suffix, "go run" may run in
+// module-aware mode or GOPATH mode, depending on the GO111MODULE environment
+// variable and the presence of a go.mod file. See 'go help modules' for details.
+// If module-aware mode is enabled, "go run" runs in the context of the main
+// module.
+//
 // By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
 // If the -exec flag is given, 'go run' invokes the binary using xprog:
 // 	'xprog a.out arguments...'.
@@ -1416,8 +1445,8 @@
 //
 // 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
+// restricted set of 'cacheable' test flags, defined as -benchtime, -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
@@ -1543,7 +1572,7 @@
 //
 // A build constraint, also known as a build tag, is a line comment that begins
 //
-// 	// +build
+// 	//go:build
 //
 // that lists the conditions under which a file should be included in the package.
 // Constraints may appear in any kind of source file (not just Go), but
@@ -1551,30 +1580,20 @@
 // only by blank lines and other line comments. These rules mean that in Go
 // files a build constraint must appear before the package clause.
 //
-// To distinguish build constraints from package documentation, a series of
-// build constraints must be followed by a blank line.
+// To distinguish build constraints from package documentation,
+// a build constraint should be followed by a blank line.
 //
-// A build constraint is evaluated as the OR of space-separated options.
-// Each option evaluates as the AND of its comma-separated terms.
-// Each term consists of letters, digits, underscores, and dots.
-// A term may be negated with a preceding !.
-// For example, the build constraint:
+// A build constraint is evaluated as an expression containing options
+// combined by ||, &&, and ! operators and parentheses. Operators have
+// the same meaning as in Go.
 //
-// 	// +build linux,386 darwin,!cgo
+// For example, the following build constraint constrains a file to
+// build when the "linux" and "386" constraints are satisfied, or when
+// "darwin" is satisfied and "cgo" is not:
 //
-// corresponds to the boolean formula:
+// 	//go:build (linux && 386) || (darwin && !cgo)
 //
-// 	(linux AND 386) OR (darwin AND (NOT cgo))
-//
-// A file may have multiple build constraints. The overall constraint is the AND
-// of the individual constraints. That is, the build constraints:
-//
-// 	// +build linux darwin
-// 	// +build amd64
-//
-// corresponds to the boolean formula:
-//
-// 	(linux OR darwin) AND amd64
+// It is an error for a file to have more than one //go:build line.
 //
 // During a particular build, the following words are satisfied:
 //
@@ -1612,24 +1631,28 @@
 //
 // To keep a file from being considered for the build:
 //
-// 	// +build ignore
+// 	//go:build ignore
 //
 // (any other unsatisfied word will work as well, but "ignore" is conventional.)
 //
 // To build a file only when using cgo, and only on Linux and OS X:
 //
-// 	// +build linux,cgo darwin,cgo
+// 	//go:build cgo && (linux || darwin)
 //
 // Such a file is usually paired with another file implementing the
 // default functionality for other systems, which in this case would
 // carry the constraint:
 //
-// 	// +build !linux,!darwin !cgo
+// 	//go:build !(cgo && (linux || darwin))
 //
 // Naming a file dns_windows.go will cause it to be included only when
 // building the package for Windows; similarly, math_386.s will be included
 // only when building the package for 32-bit x86.
 //
+// Go versions 1.16 and earlier used a different syntax for build constraints,
+// with a "// +build" prefix. The gofmt command will add an equivalent //go:build
+// constraint when encountering the older syntax.
+//
 //
 // Build modes
 //
@@ -1787,9 +1810,8 @@
 // 		Comma-separated list of glob patterns (in the syntax of Go's path.Match)
 // 		of module path prefixes that should always be fetched in an insecure
 // 		manner. Only applies to dependencies that are being fetched directly.
-// 		Unlike the -insecure flag on 'go get', GOINSECURE does not disable
-// 		checksum database validation. GOPRIVATE or GONOSUMDB may be used
-// 		to achieve that.
+// 		GOINSECURE does not disable checksum database validation. GOPRIVATE or
+// 		GONOSUMDB may be used to achieve that.
 // 	GOOS
 // 		The operating system for which to compile code.
 // 		Examples are linux, darwin, windows, netbsd.
@@ -1869,6 +1891,9 @@
 // 	GOMIPS64
 // 		For GOARCH=mips64{,le}, whether to use floating point instructions.
 // 		Valid values are hardfloat (default), softfloat.
+// 	GOPPC64
+// 		For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture).
+// 		Valid values are power8 (default), power9.
 // 	GOWASM
 // 		For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use.
 // 		Valid values are satconv, signext.
@@ -1878,6 +1903,12 @@
 // 	GCCGOTOOLDIR
 // 		If set, where to find gccgo tools, such as cgo.
 // 		The default is based on how gccgo was configured.
+// 	GOEXPERIMENT
+// 		Comma-separated list of toolchain experiments to enable or disable.
+// 		The list of available experiments may change arbitrarily over time.
+// 		See src/internal/goexperiment/flags.go for currently valid values.
+// 		Warning: This variable is provided for the development and testing
+// 		of the Go toolchain itself. Use beyond that purpose is unsupported.
 // 	GOROOT_FINAL
 // 		The root of the installed Go tree, when it is
 // 		installed in a location other than where it is built.
@@ -1961,7 +1992,7 @@
 // The go.mod file format is described in detail at
 // https://golang.org/ref/mod#go-mod-file.
 //
-// To create a new go.mod file, use 'go help init'. For details see
+// To create a new go.mod file, use 'go mod init'. For details see
 // 'go help mod init' or https://golang.org/ref/mod#go-mod-init.
 //
 // To add missing module requirements or remove unneeded requirements,
@@ -2139,7 +2170,7 @@
 // This help text, accessible as 'go help gopath-get' even in module-aware mode,
 // describes 'go get' as it operates in legacy GOPATH mode.
 //
-// Usage: go get [-d] [-f] [-t] [-u] [-v] [-fix] [-insecure] [build flags] [packages]
+// Usage: go get [-d] [-f] [-t] [-u] [-v] [-fix] [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'.
@@ -2155,13 +2186,6 @@
 // The -fix flag instructs get to run the fix tool on the downloaded packages
 // before resolving dependencies or building the code.
 //
-// The -insecure flag permits fetching from repositories and resolving
-// custom domains using insecure schemes such as HTTP. Use with caution.
-// This flag is deprecated and will be removed in a future version of go.
-// The GOINSECURE environment variable should be used instead, since it
-// provides control over which packages may be retrieved using an insecure
-// scheme. See 'go help environment' for details.
-//
 // The -t flag instructs get to also download the packages required to build
 // the tests for the specified packages.
 //
@@ -2346,7 +2370,7 @@
 // will result in the following requests:
 //
 // 	https://example.org/pkg/foo?go-get=1 (preferred)
-// 	http://example.org/pkg/foo?go-get=1  (fallback, only with -insecure)
+// 	http://example.org/pkg/foo?go-get=1  (fallback, only with use of correctly set GOINSECURE)
 //
 // If that page contains the meta tag
 //
@@ -2664,6 +2688,13 @@
 // 	    the Go tree can run a sanity check but not spend time running
 // 	    exhaustive tests.
 //
+// 	-shuffle off,on,N
+// 		Randomize the execution order of tests and benchmarks.
+// 		It is off by default. If -shuffle is set to on, then it will seed
+// 		the randomizer using the system clock. If -shuffle is set to an
+// 		integer N, then N will be used as the seed value. In both cases,
+// 		the seed will be reported for reproducibility.
+//
 // 	-timeout d
 // 	    If a test binary runs longer than duration d, panic.
 // 	    If d is 0, the timeout is disabled.
diff --git a/src/cmd/go/go11.go b/src/cmd/go/go11.go
index 7e383f4..a1f2727 100644
--- a/src/cmd/go/go11.go
+++ b/src/cmd/go/go11.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.1
 // +build go1.1
 
 package main
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 3ce3238..6ce2765 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -72,7 +72,6 @@
 // (temp) directory.
 var testGOROOT string
 
-var testCC string
 var testGOCACHE string
 
 var testGo string
@@ -179,13 +178,6 @@
 			os.Exit(2)
 		}
 
-		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)
-		}
-		testCC = strings.TrimSpace(string(out))
-
 		cmd := exec.Command(testGo, "env", "CGO_ENABLED")
 		cmd.Stderr = new(strings.Builder)
 		if out, err := cmd.Output(); err != nil {
@@ -811,8 +803,10 @@
 	// so that we can change files.
 	for _, copydir := range []string{
 		"src/runtime",
+		"src/internal/abi",
 		"src/internal/bytealg",
 		"src/internal/cpu",
+		"src/internal/goexperiment",
 		"src/math/bits",
 		"src/unsafe",
 		filepath.Join("pkg", runtime.GOOS+"_"+runtime.GOARCH),
@@ -2183,7 +2177,7 @@
 			// See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
 			section := f.Section(".edata")
 			if section == nil {
-				t.Fatalf(".edata section is not present")
+				t.Skip(".edata section is not present")
 			}
 			// TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
 			type IMAGE_EXPORT_DIRECTORY struct {
@@ -2830,3 +2824,59 @@
 	tg.grepStderrNot("no packages being tested depend on matches", "bad match message")
 	tg.grepStdout("coverage: 100", "no coverage")
 }
+
+// Regression test for golang.org/issue/34499: version command should not crash
+// when executed in a deleted directory on Linux.
+func TestExecInDeletedDir(t *testing.T) {
+	switch runtime.GOOS {
+	case "windows", "plan9",
+		"aix",                // Fails with "device busy".
+		"solaris", "illumos": // Fails with "invalid argument".
+		t.Skipf("%v does not support removing the current working directory", runtime.GOOS)
+	}
+	tg := testgo(t)
+	defer tg.cleanup()
+
+	wd, err := os.Getwd()
+	tg.check(err)
+	tg.makeTempdir()
+	tg.check(os.Chdir(tg.tempdir))
+	defer func() { tg.check(os.Chdir(wd)) }()
+
+	tg.check(os.Remove(tg.tempdir))
+
+	// `go version` should not fail
+	tg.run("version")
+}
+
+// A missing C compiler should not force the net package to be stale.
+// Issue 47215.
+func TestMissingCC(t *testing.T) {
+	if !canCgo {
+		t.Skip("test is only meaningful on systems with cgo")
+	}
+	cc := os.Getenv("CC")
+	if cc == "" {
+		cc = "gcc"
+	}
+	if filepath.IsAbs(cc) {
+		t.Skipf(`"CC" (%s) is an absolute path`, cc)
+	}
+	_, err := exec.LookPath(cc)
+	if err != nil {
+		t.Skipf(`"CC" (%s) not on PATH`, cc)
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	netStale, _ := tg.isStale("net")
+	if netStale {
+		t.Skip(`skipping test because "net" package is currently stale`)
+	}
+
+	tg.setenv("PATH", "") // No C compiler on PATH.
+	netStale, _ = tg.isStale("net")
+	if netStale {
+		t.Error(`clearing "PATH" causes "net" to be stale`)
+	}
+}
diff --git a/src/cmd/go/go_unix_test.go b/src/cmd/go/go_unix_test.go
index f6e10ca..7d5ff9b 100644
--- a/src/cmd/go/go_unix_test.go
+++ b/src/cmd/go/go_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package main_test
diff --git a/src/cmd/go/internal/base/path.go b/src/cmd/go/internal/base/path.go
index 7a51181..4d8715e 100644
--- a/src/cmd/go/internal/base/path.go
+++ b/src/cmd/go/internal/base/path.go
@@ -8,21 +8,27 @@
 	"os"
 	"path/filepath"
 	"strings"
+	"sync"
 )
 
-func getwd() string {
-	wd, err := os.Getwd()
-	if err != nil {
-		Fatalf("cannot determine current directory: %v", err)
-	}
-	return wd
-}
+var cwd string
+var cwdOnce sync.Once
 
-var Cwd = getwd()
+// Cwd returns the current working directory at the time of the first call.
+func Cwd() string {
+	cwdOnce.Do(func() {
+		var err error
+		cwd, err = os.Getwd()
+		if err != nil {
+			Fatalf("cannot determine current directory: %v", err)
+		}
+	})
+	return cwd
+}
 
 // ShortPath returns an absolute or relative name for path, whatever is shorter.
 func ShortPath(path string) string {
-	if rel, err := filepath.Rel(Cwd, path); err == nil && len(rel) < len(path) {
+	if rel, err := filepath.Rel(Cwd(), path); err == nil && len(rel) < len(path) {
 		return rel
 	}
 	return path
@@ -32,10 +38,8 @@
 // made relative to the current directory if they would be shorter.
 func RelPaths(paths []string) []string {
 	var out []string
-	// TODO(rsc): Can this use Cwd from above?
-	pwd, _ := os.Getwd()
 	for _, p := range paths {
-		rel, err := filepath.Rel(pwd, p)
+		rel, err := filepath.Rel(Cwd(), p)
 		if err == nil && len(rel) < len(p) {
 			p = rel
 		}
diff --git a/src/cmd/go/internal/base/signal_notunix.go b/src/cmd/go/internal/base/signal_notunix.go
index 9e869b0..5cc0b0f 100644
--- a/src/cmd/go/internal/base/signal_notunix.go
+++ b/src/cmd/go/internal/base/signal_notunix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build plan9 || windows
 // +build plan9 windows
 
 package base
diff --git a/src/cmd/go/internal/base/signal_unix.go b/src/cmd/go/internal/base/signal_unix.go
index 342775a..cdc2658 100644
--- a/src/cmd/go/internal/base/signal_unix.go
+++ b/src/cmd/go/internal/base/signal_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || js || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js linux netbsd openbsd solaris
 
 package base
diff --git a/src/cmd/go/internal/bug/bug.go b/src/cmd/go/internal/bug/bug.go
index 4aa08b4..307527c 100644
--- a/src/cmd/go/internal/bug/bug.go
+++ b/src/cmd/go/internal/bug/bug.go
@@ -20,6 +20,7 @@
 
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
+	"cmd/go/internal/envcmd"
 	"cmd/go/internal/web"
 )
 
@@ -81,7 +82,7 @@
 	fmt.Fprintf(w, "### What version of Go are you using (`go version`)?\n\n")
 	fmt.Fprintf(w, "<pre>\n")
 	fmt.Fprintf(w, "$ go version\n")
-	printCmdOut(w, "", "go", "version")
+	fmt.Fprintf(w, "go version %s %s/%s\n", runtime.Version(), runtime.GOOS, runtime.GOARCH)
 	fmt.Fprintf(w, "</pre>\n")
 	fmt.Fprintf(w, "\n")
 }
@@ -90,13 +91,20 @@
 	fmt.Fprintf(w, "### What operating system and processor architecture are you using (`go env`)?\n\n")
 	fmt.Fprintf(w, "<details><summary><code>go env</code> Output</summary><br><pre>\n")
 	fmt.Fprintf(w, "$ go env\n")
-	printCmdOut(w, "", "go", "env")
+	printGoEnv(w)
 	printGoDetails(w)
 	printOSDetails(w)
 	printCDetails(w)
 	fmt.Fprintf(w, "</pre></details>\n\n")
 }
 
+func printGoEnv(w io.Writer) {
+	env := envcmd.MkEnv()
+	env = append(env, envcmd.ExtraEnvVars()...)
+	env = append(env, envcmd.ExtraEnvVarsCostly()...)
+	envcmd.PrintEnv(w, env)
+}
+
 func printGoDetails(w io.Writer) {
 	printCmdOut(w, "GOROOT/bin/go version: ", filepath.Join(runtime.GOROOT(), "bin/go"), "version")
 	printCmdOut(w, "GOROOT/bin/go tool compile -V: ", filepath.Join(runtime.GOROOT(), "bin/go"), "tool", "compile", "-V")
diff --git a/src/cmd/go/internal/cache/cache.go b/src/cmd/go/internal/cache/cache.go
index 41f9216..d592d70 100644
--- a/src/cmd/go/internal/cache/cache.go
+++ b/src/cmd/go/internal/cache/cache.go
@@ -19,7 +19,7 @@
 	"strings"
 	"time"
 
-	"cmd/go/internal/renameio"
+	"cmd/go/internal/lockedfile"
 )
 
 // An ActionID is a cache action key, the hash of a complete description of a
@@ -294,10 +294,17 @@
 	// 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, _ := renameio.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
+	// If the trim file is corrupt, detected if the file can't be parsed, or the
+	// trim time is too far in the future, attempt the trim anyway. It's possible that
+	// the cache was full when the corruption happened. Attempting a trim on
+	// an empty cache is cheap, so there wouldn't be a big performance hit in that case.
+	if data, err := lockedfile.Read(filepath.Join(c.dir, "trim.txt")); err == nil {
+		if t, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64); err == nil {
+			lastTrim := time.Unix(t, 0)
+			if d := now.Sub(lastTrim); d < trimInterval && d > -mtimeInterval {
+				return
+			}
+		}
 	}
 
 	// Trim each of the 256 subdirectories.
@@ -311,7 +318,11 @@
 
 	// Ignore errors from here: if we don't write the complete timestamp, the
 	// cache will appear older than it is, and we'll trim it again next time.
-	renameio.WriteFile(filepath.Join(c.dir, "trim.txt"), []byte(fmt.Sprintf("%d", now.Unix())), 0666)
+	var b bytes.Buffer
+	fmt.Fprintf(&b, "%d", now.Unix())
+	if err := lockedfile.Write(filepath.Join(c.dir, "trim.txt"), &b, 0666); err != nil {
+		return
+	}
 }
 
 // trimSubdir trims a single cache subdirectory.
diff --git a/src/cmd/go/internal/cache/hash.go b/src/cmd/go/internal/cache/hash.go
index e4bb2a3..4f79c31 100644
--- a/src/cmd/go/internal/cache/hash.go
+++ b/src/cmd/go/internal/cache/hash.go
@@ -12,6 +12,7 @@
 	"io"
 	"os"
 	"runtime"
+	"strings"
 	"sync"
 )
 
@@ -36,7 +37,22 @@
 // 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())
+//
+// We strip any GOEXPERIMENTs the go tool was built with from this
+// version string on the assumption that they shouldn't affect go tool
+// execution. This allows bootstrapping to converge faster: dist builds
+// go_bootstrap without any experiments, so by stripping experiments
+// go_bootstrap and the final go binary will use the same salt.
+var hashSalt = []byte(stripExperiment(runtime.Version()))
+
+// stripExperiment strips any GOEXPERIMENT configuration from the Go
+// version string.
+func stripExperiment(version string) string {
+	if i := strings.Index(version, " X:"); i >= 0 {
+		return version[:i]
+	}
+	return version
+}
 
 // Subkey returns an action ID corresponding to mixing a parent
 // action ID with a string description of the subkey.
diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go
index c48904e..57a3c1f 100644
--- a/src/cmd/go/internal/cfg/cfg.go
+++ b/src/cmd/go/internal/cfg/cfg.go
@@ -10,6 +10,7 @@
 	"bytes"
 	"fmt"
 	"go/build"
+	"internal/buildcfg"
 	"internal/cfg"
 	"io"
 	"os"
@@ -19,8 +20,6 @@
 	"sync"
 
 	"cmd/go/internal/fsys"
-
-	"cmd/internal/objabi"
 )
 
 // These are general "build flags" used by build and other commands.
@@ -28,18 +27,18 @@
 	BuildA                 bool   // -a flag
 	BuildBuildmode         string // -buildmode flag
 	BuildContext           = defaultContext()
-	BuildMod               string             // -mod flag
-	BuildModExplicit       bool               // whether -mod was set explicitly
-	BuildModReason         string             // reason -mod was set, if set by default
-	BuildI                 bool               // -i flag
-	BuildLinkshared        bool               // -linkshared flag
-	BuildMSan              bool               // -msan flag
-	BuildN                 bool               // -n flag
-	BuildO                 string             // -o flag
-	BuildP                 = runtime.NumCPU() // -p flag
-	BuildPkgdir            string             // -pkgdir flag
-	BuildRace              bool               // -race flag
-	BuildToolexec          []string           // -toolexec flag
+	BuildMod               string                  // -mod flag
+	BuildModExplicit       bool                    // whether -mod was set explicitly
+	BuildModReason         string                  // reason -mod was set, if set by default
+	BuildI                 bool                    // -i flag
+	BuildLinkshared        bool                    // -linkshared flag
+	BuildMSan              bool                    // -msan flag
+	BuildN                 bool                    // -n flag
+	BuildO                 string                  // -o flag
+	BuildP                 = runtime.GOMAXPROCS(0) // -p flag
+	BuildPkgdir            string                  // -pkgdir flag
+	BuildRace              bool                    // -race flag
+	BuildToolexec          []string                // -toolexec flag
 	BuildToolchainName     string
 	BuildToolchainCompiler func() string
 	BuildToolchainLinker   func() string
@@ -51,8 +50,6 @@
 	ModCacheRW bool   // -modcacherw flag
 	ModFile    string // -modfile flag
 
-	Insecure bool // -insecure flag
-
 	CmdName string // "build", "install", "list", "mod tidy", etc.
 
 	DebugActiongraph string // -debug-actiongraph flag (undocumented, unstable)
@@ -80,6 +77,14 @@
 	ctxt.GOOS = envOr("GOOS", ctxt.GOOS)
 	ctxt.GOARCH = envOr("GOARCH", ctxt.GOARCH)
 
+	// The experiments flags are based on GOARCH, so they may
+	// need to change.  TODO: This should be cleaned up.
+	buildcfg.UpdateExperiments(ctxt.GOOS, ctxt.GOARCH, envOr("GOEXPERIMENT", buildcfg.DefaultGOEXPERIMENT))
+	ctxt.ToolTags = nil
+	for _, exp := range buildcfg.EnabledExperiments() {
+		ctxt.ToolTags = append(ctxt.ToolTags, "goexperiment."+exp)
+	}
+
 	// The go/build rule for whether cgo is enabled is:
 	//	1. If $CGO_ENABLED is set, respect it.
 	//	2. Otherwise, if this is a cross-compile, disable cgo.
@@ -254,12 +259,12 @@
 	GOMODCACHE   = envOr("GOMODCACHE", gopathDir("pkg/mod"))
 
 	// Used in envcmd.MkEnv and build ID computations.
-	GOARM    = envOr("GOARM", fmt.Sprint(objabi.GOARM))
-	GO386    = envOr("GO386", objabi.GO386)
-	GOMIPS   = envOr("GOMIPS", objabi.GOMIPS)
-	GOMIPS64 = envOr("GOMIPS64", objabi.GOMIPS64)
-	GOPPC64  = envOr("GOPPC64", fmt.Sprintf("%s%d", "power", objabi.GOPPC64))
-	GOWASM   = envOr("GOWASM", fmt.Sprint(objabi.GOWASM))
+	GOARM    = envOr("GOARM", fmt.Sprint(buildcfg.GOARM))
+	GO386    = envOr("GO386", buildcfg.GO386)
+	GOMIPS   = envOr("GOMIPS", buildcfg.GOMIPS)
+	GOMIPS64 = envOr("GOMIPS64", buildcfg.GOMIPS64)
+	GOPPC64  = envOr("GOPPC64", fmt.Sprintf("%s%d", "power", buildcfg.GOPPC64))
+	GOWASM   = envOr("GOWASM", fmt.Sprint(buildcfg.GOWASM))
 
 	GOPROXY    = envOr("GOPROXY", "https://proxy.golang.org,direct")
 	GOSUMDB    = envOr("GOSUMDB", "sum.golang.org")
diff --git a/src/cmd/go/internal/cfg/zosarch.go b/src/cmd/go/internal/cfg/zosarch.go
index e6243f4..c31763a 100644
--- a/src/cmd/go/internal/cfg/zosarch.go
+++ b/src/cmd/go/internal/cfg/zosarch.go
@@ -40,7 +40,7 @@
 	"openbsd/amd64": true,
 	"openbsd/arm": true,
 	"openbsd/arm64": true,
-	"openbsd/mips64": false,
+	"openbsd/mips64": true,
 	"plan9/386": false,
 	"plan9/amd64": false,
 	"plan9/arm": false,
@@ -48,4 +48,5 @@
 	"windows/386": true,
 	"windows/amd64": true,
 	"windows/arm": false,
+	"windows/arm64": true,
 }
diff --git a/src/cmd/go/internal/clean/clean.go b/src/cmd/go/internal/clean/clean.go
index b1d40fe..fd4cb20 100644
--- a/src/cmd/go/internal/clean/clean.go
+++ b/src/cmd/go/internal/clean/clean.go
@@ -117,7 +117,7 @@
 	}
 
 	if cleanPkg {
-		for _, pkg := range load.PackagesAndErrors(ctx, args) {
+		for _, pkg := range load.PackagesAndErrors(ctx, load.PackageOpts{}, args) {
 			clean(pkg)
 		}
 	}
diff --git a/src/cmd/go/internal/doc/doc.go b/src/cmd/go/internal/doc/doc.go
index 67f76e2..8580a5d 100644
--- a/src/cmd/go/internal/doc/doc.go
+++ b/src/cmd/go/internal/doc/doc.go
@@ -13,7 +13,7 @@
 
 var CmdDoc = &base.Command{
 	Run:         runDoc,
-	UsageLine:   "go doc [-u] [-c] [package|[package.]symbol[.methodOrField]]",
+	UsageLine:   "go doc [doc flags] [package|[package.]symbol[.methodOrField]]",
 	CustomFlags: true,
 	Short:       "show documentation for package or symbol",
 	Long: `
diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go
index 6937187..1553d26 100644
--- a/src/cmd/go/internal/envcmd/env.go
+++ b/src/cmd/go/internal/envcmd/env.go
@@ -10,6 +10,8 @@
 	"encoding/json"
 	"fmt"
 	"go/build"
+	"internal/buildcfg"
+	"io"
 	"os"
 	"path/filepath"
 	"runtime"
@@ -71,6 +73,7 @@
 		{Name: "GOCACHE", Value: cache.DefaultDir()},
 		{Name: "GOENV", Value: envFile},
 		{Name: "GOEXE", Value: cfg.ExeSuffix},
+		{Name: "GOEXPERIMENT", Value: buildcfg.GOEXPERIMENT()},
 		{Name: "GOFLAGS", Value: cfg.Getenv("GOFLAGS")},
 		{Name: "GOHOSTARCH", Value: runtime.GOARCH},
 		{Name: "GOHOSTOS", Value: runtime.GOOS},
@@ -196,23 +199,31 @@
 	if *envU && *envW {
 		base.Fatalf("go env: cannot use -u with -w")
 	}
+
+	// Handle 'go env -w' and 'go env -u' before calling buildcfg.Check,
+	// so they can be used to recover from an invalid configuration.
+	if *envW {
+		runEnvW(args)
+		return
+	}
+
+	if *envU {
+		runEnvU(args)
+		return
+	}
+
+	buildcfg.Check()
+
 	env := cfg.CmdEnv
 	env = append(env, ExtraEnvVars()...)
 
-	if err := fsys.Init(base.Cwd); err != nil {
+	if err := fsys.Init(base.Cwd()); err != nil {
 		base.Fatalf("go: %v", err)
 	}
 
 	// Do we need to call ExtraEnvVarsCostly, which is a bit expensive?
 	needCostly := false
-	if *envU || *envW {
-		// We're overwriting or removing default settings,
-		// so it doesn't really matter what the existing settings are.
-		//
-		// Moreover, we haven't validated the new settings yet, so it is
-		// important that we NOT perform any actions based on them,
-		// such as initializing the builder to compute other variables.
-	} else if len(args) == 0 {
+	if len(args) == 0 {
 		// We're listing all environment variables ("go env"),
 		// including the expensive ones.
 		needCostly = true
@@ -237,95 +248,6 @@
 		env = append(env, ExtraEnvVarsCostly()...)
 	}
 
-	if *envW {
-		// Process and sanity-check command line.
-		if len(args) == 0 {
-			base.Fatalf("go env -w: no KEY=VALUE arguments given")
-		}
-		osEnv := make(map[string]string)
-		for _, e := range cfg.OrigEnv {
-			if i := strings.Index(e, "="); i >= 0 {
-				osEnv[e[:i]] = e[i+1:]
-			}
-		}
-		add := make(map[string]string)
-		for _, arg := range args {
-			i := strings.Index(arg, "=")
-			if i < 0 {
-				base.Fatalf("go env -w: arguments must be KEY=VALUE: invalid argument: %s", arg)
-			}
-			key, val := arg[:i], arg[i+1:]
-			if err := checkEnvWrite(key, val); err != nil {
-				base.Fatalf("go env -w: %v", err)
-			}
-			if _, ok := add[key]; ok {
-				base.Fatalf("go env -w: multiple values for key: %s", key)
-			}
-			add[key] = val
-			if osVal := osEnv[key]; osVal != "" && osVal != val {
-				fmt.Fprintf(os.Stderr, "warning: go env -w %s=... does not override conflicting OS environment variable\n", key)
-			}
-		}
-
-		goos, okGOOS := add["GOOS"]
-		goarch, okGOARCH := add["GOARCH"]
-		if okGOOS || okGOARCH {
-			if !okGOOS {
-				goos = cfg.Goos
-			}
-			if !okGOARCH {
-				goarch = cfg.Goarch
-			}
-			if err := work.CheckGOOSARCHPair(goos, goarch); err != nil {
-				base.Fatalf("go env -w: %v", err)
-			}
-		}
-
-		gotmp, okGOTMP := add["GOTMPDIR"]
-		if okGOTMP {
-			if !filepath.IsAbs(gotmp) && gotmp != "" {
-				base.Fatalf("go env -w: GOTMPDIR must be an absolute path")
-			}
-		}
-
-		updateEnvFile(add, nil)
-		return
-	}
-
-	if *envU {
-		// Process and sanity-check command line.
-		if len(args) == 0 {
-			base.Fatalf("go env -u: no arguments given")
-		}
-		del := make(map[string]bool)
-		for _, arg := range args {
-			if err := checkEnvWrite(arg, ""); err != nil {
-				base.Fatalf("go env -u: %v", err)
-			}
-			del[arg] = true
-		}
-		if del["GOOS"] || del["GOARCH"] {
-			goos, goarch := cfg.Goos, cfg.Goarch
-			if del["GOOS"] {
-				goos = getOrigEnv("GOOS")
-				if goos == "" {
-					goos = build.Default.GOOS
-				}
-			}
-			if del["GOARCH"] {
-				goarch = getOrigEnv("GOARCH")
-				if goarch == "" {
-					goarch = build.Default.GOARCH
-				}
-			}
-			if err := work.CheckGOOSARCHPair(goos, goarch); err != nil {
-				base.Fatalf("go env -u: %v", err)
-			}
-		}
-		updateEnvFile(nil, del)
-		return
-	}
-
 	if len(args) > 0 {
 		if *envJson {
 			var es []cfg.EnvVar
@@ -347,27 +269,135 @@
 		return
 	}
 
+	PrintEnv(os.Stdout, env)
+}
+
+func runEnvW(args []string) {
+	// Process and sanity-check command line.
+	if len(args) == 0 {
+		base.Fatalf("go env -w: no KEY=VALUE arguments given")
+	}
+	osEnv := make(map[string]string)
+	for _, e := range cfg.OrigEnv {
+		if i := strings.Index(e, "="); i >= 0 {
+			osEnv[e[:i]] = e[i+1:]
+		}
+	}
+	add := make(map[string]string)
+	for _, arg := range args {
+		i := strings.Index(arg, "=")
+		if i < 0 {
+			base.Fatalf("go env -w: arguments must be KEY=VALUE: invalid argument: %s", arg)
+		}
+		key, val := arg[:i], arg[i+1:]
+		if err := checkEnvWrite(key, val); err != nil {
+			base.Fatalf("go env -w: %v", err)
+		}
+		if _, ok := add[key]; ok {
+			base.Fatalf("go env -w: multiple values for key: %s", key)
+		}
+		add[key] = val
+		if osVal := osEnv[key]; osVal != "" && osVal != val {
+			fmt.Fprintf(os.Stderr, "warning: go env -w %s=... does not override conflicting OS environment variable\n", key)
+		}
+	}
+
+	if err := checkBuildConfig(add, nil); err != nil {
+		base.Fatalf("go env -w: %v", err)
+	}
+
+	gotmp, okGOTMP := add["GOTMPDIR"]
+	if okGOTMP {
+		if !filepath.IsAbs(gotmp) && gotmp != "" {
+			base.Fatalf("go env -w: GOTMPDIR must be an absolute path")
+		}
+	}
+
+	updateEnvFile(add, nil)
+}
+
+func runEnvU(args []string) {
+	// Process and sanity-check command line.
+	if len(args) == 0 {
+		base.Fatalf("go env -u: no arguments given")
+	}
+	del := make(map[string]bool)
+	for _, arg := range args {
+		if err := checkEnvWrite(arg, ""); err != nil {
+			base.Fatalf("go env -u: %v", err)
+		}
+		del[arg] = true
+	}
+
+	if err := checkBuildConfig(nil, del); err != nil {
+		base.Fatalf("go env -u: %v", err)
+	}
+
+	updateEnvFile(nil, del)
+}
+
+// checkBuildConfig checks whether the build configuration is valid
+// after the specified configuration environment changes are applied.
+func checkBuildConfig(add map[string]string, del map[string]bool) error {
+	// get returns the value for key after applying add and del and
+	// reports whether it changed. cur should be the current value
+	// (i.e., before applying changes) and def should be the default
+	// value (i.e., when no environment variables are provided at all).
+	get := func(key, cur, def string) (string, bool) {
+		if val, ok := add[key]; ok {
+			return val, true
+		}
+		if del[key] {
+			val := getOrigEnv(key)
+			if val == "" {
+				val = def
+			}
+			return val, true
+		}
+		return cur, false
+	}
+
+	goos, okGOOS := get("GOOS", cfg.Goos, build.Default.GOOS)
+	goarch, okGOARCH := get("GOARCH", cfg.Goarch, build.Default.GOARCH)
+	if okGOOS || okGOARCH {
+		if err := work.CheckGOOSARCHPair(goos, goarch); err != nil {
+			return err
+		}
+	}
+
+	goexperiment, okGOEXPERIMENT := get("GOEXPERIMENT", buildcfg.GOEXPERIMENT(), "")
+	if okGOEXPERIMENT {
+		if _, _, err := buildcfg.ParseGOEXPERIMENT(goos, goarch, goexperiment); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// PrintEnv prints the environment variables to w.
+func PrintEnv(w io.Writer, env []cfg.EnvVar) {
 	for _, e := range env {
 		if e.Name != "TERM" {
 			switch runtime.GOOS {
 			default:
-				fmt.Printf("%s=\"%s\"\n", e.Name, e.Value)
+				fmt.Fprintf(w, "%s=\"%s\"\n", e.Name, e.Value)
 			case "plan9":
 				if strings.IndexByte(e.Value, '\x00') < 0 {
-					fmt.Printf("%s='%s'\n", e.Name, strings.ReplaceAll(e.Value, "'", "''"))
+					fmt.Fprintf(w, "%s='%s'\n", e.Name, strings.ReplaceAll(e.Value, "'", "''"))
 				} else {
 					v := strings.Split(e.Value, "\x00")
-					fmt.Printf("%s=(", e.Name)
+					fmt.Fprintf(w, "%s=(", e.Name)
 					for x, s := range v {
 						if x > 0 {
-							fmt.Printf(" ")
+							fmt.Fprintf(w, " ")
 						}
-						fmt.Printf("%s", s)
+						fmt.Fprintf(w, "%s", s)
 					}
-					fmt.Printf(")\n")
+					fmt.Fprintf(w, ")\n")
 				}
 			case "windows":
-				fmt.Printf("set %s=%s\n", e.Name, e.Value)
+				fmt.Fprintf(w, "set %s=%s\n", e.Name, e.Value)
 			}
 		}
 	}
@@ -428,7 +458,7 @@
 			return fmt.Errorf("GOPATH entry is relative; must be absolute path: %q", val)
 		}
 	// Make sure CC and CXX are absolute paths
-	case "CC", "CXX":
+	case "CC", "CXX", "GOMODCACHE":
 		if !filepath.IsAbs(val) && val != "" && val != filepath.Base(val) {
 			return fmt.Errorf("%s entry is relative; must be absolute path: %q", key, val)
 		}
diff --git a/src/cmd/go/internal/fix/fix.go b/src/cmd/go/internal/fix/fix.go
index c7588c6..988d45e 100644
--- a/src/cmd/go/internal/fix/fix.go
+++ b/src/cmd/go/internal/fix/fix.go
@@ -33,7 +33,7 @@
 }
 
 func runFix(ctx context.Context, cmd *base.Command, args []string) {
-	pkgs := load.PackagesAndErrors(ctx, args)
+	pkgs := load.PackagesAndErrors(ctx, load.PackageOpts{}, args)
 	w := 0
 	for _, pkg := range pkgs {
 		if pkg.Error != nil {
diff --git a/src/cmd/go/internal/fmtcmd/fmt.go b/src/cmd/go/internal/fmtcmd/fmt.go
index 6b98f0c..8a04008 100644
--- a/src/cmd/go/internal/fmtcmd/fmt.go
+++ b/src/cmd/go/internal/fmtcmd/fmt.go
@@ -65,7 +65,7 @@
 			}
 		}()
 	}
-	for _, pkg := range load.PackagesAndErrors(ctx, args) {
+	for _, pkg := range load.PackagesAndErrors(ctx, load.PackageOpts{}, args) {
 		if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main {
 			if !printed {
 				fmt.Fprintf(os.Stderr, "go: not formatting packages in dependency modules\n")
diff --git a/src/cmd/go/internal/fsys/fsys.go b/src/cmd/go/internal/fsys/fsys.go
index 7b06c3c..0b80602 100644
--- a/src/cmd/go/internal/fsys/fsys.go
+++ b/src/cmd/go/internal/fsys/fsys.go
@@ -44,7 +44,7 @@
 
 // TODO(matloob): encapsulate these in an io/fs-like interface
 var overlay map[string]*node // path -> file or directory node
-var cwd string               // copy of base.Cwd to avoid dependency
+var cwd string               // copy of base.Cwd() to avoid dependency
 
 // Canonicalize a path for looking it up in the overlay.
 // Important: filepath.Join(cwd, path) doesn't always produce
@@ -100,7 +100,7 @@
 }
 
 func initFromJSON(overlayJSON OverlayJSON) error {
-	// Canonicalize the paths in in the overlay map.
+	// Canonicalize the paths in the overlay map.
 	// Use reverseCanonicalized to check for collisions:
 	// no two 'from' paths should canonicalize to the same path.
 	overlay = make(map[string]*node)
diff --git a/src/cmd/go/internal/generate/generate.go b/src/cmd/go/internal/generate/generate.go
index a48311d..80ea32b 100644
--- a/src/cmd/go/internal/generate/generate.go
+++ b/src/cmd/go/internal/generate/generate.go
@@ -161,8 +161,6 @@
 }
 
 func runGenerate(ctx context.Context, cmd *base.Command, args []string) {
-	load.IgnoreImports = true
-
 	if generateRunFlag != "" {
 		var err error
 		generateRunRE, err = regexp.Compile(generateRunFlag)
@@ -175,7 +173,8 @@
 
 	// Even if the arguments are .go files, this loop suffices.
 	printed := false
-	for _, pkg := range load.PackagesAndErrors(ctx, args) {
+	pkgOpts := load.PackageOpts{IgnoreImports: true}
+	for _, pkg := range load.PackagesAndErrors(ctx, pkgOpts, args) {
 		if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main {
 			if !printed {
 				fmt.Fprintf(os.Stderr, "go: not generating in packages in dependency modules\n")
@@ -334,6 +333,7 @@
 		"GOPACKAGE=" + g.pkg,
 		"DOLLAR=" + "$",
 	}
+	g.env = base.AppendPWD(g.env, g.dir)
 }
 
 // split breaks the line into words, evaluating quoted
diff --git a/src/cmd/go/internal/get/get.go b/src/cmd/go/internal/get/get.go
index 329a2f5..3c16dc3 100644
--- a/src/cmd/go/internal/get/get.go
+++ b/src/cmd/go/internal/get/get.go
@@ -26,7 +26,7 @@
 )
 
 var CmdGet = &base.Command{
-	UsageLine: "go get [-d] [-f] [-t] [-u] [-v] [-fix] [-insecure] [build flags] [packages]",
+	UsageLine: "go get [-d] [-f] [-t] [-u] [-v] [-fix] [build flags] [packages]",
 	Short:     "download and install packages and dependencies",
 	Long: `
 Get downloads the packages named by the import paths, along with their
@@ -43,13 +43,6 @@
 The -fix flag instructs get to run the fix tool on the downloaded packages
 before resolving dependencies or building the code.
 
-The -insecure flag permits fetching from repositories and resolving
-custom domains using insecure schemes such as HTTP. Use with caution.
-This flag is deprecated and will be removed in a future version of go.
-The GOINSECURE environment variable should be used instead, since it
-provides control over which packages may be retrieved using an insecure
-scheme. See 'go help environment' for details.
-
 The -t flag instructs get to also download the packages required to build
 the tests for the specified packages.
 
@@ -105,17 +98,17 @@
 }
 
 var (
-	getD   = CmdGet.Flag.Bool("d", false, "")
-	getF   = CmdGet.Flag.Bool("f", false, "")
-	getT   = CmdGet.Flag.Bool("t", false, "")
-	getU   = CmdGet.Flag.Bool("u", false, "")
-	getFix = CmdGet.Flag.Bool("fix", false, "")
+	getD        = CmdGet.Flag.Bool("d", false, "")
+	getF        = CmdGet.Flag.Bool("f", false, "")
+	getT        = CmdGet.Flag.Bool("t", false, "")
+	getU        = CmdGet.Flag.Bool("u", false, "")
+	getFix      = CmdGet.Flag.Bool("fix", false, "")
+	getInsecure = CmdGet.Flag.Bool("insecure", false, "")
 )
 
 func init() {
 	work.AddBuildFlags(CmdGet, work.OmitModFlag|work.OmitModCommonFlags)
 	CmdGet.Run = runGet // break init loop
-	CmdGet.Flag.BoolVar(&cfg.Insecure, "insecure", cfg.Insecure, "")
 }
 
 func runGet(ctx context.Context, cmd *base.Command, args []string) {
@@ -129,11 +122,11 @@
 	if *getF && !*getU {
 		base.Fatalf("go get: cannot use -f flag without -u")
 	}
-	if cfg.Insecure {
-		fmt.Fprintf(os.Stderr, "go get: -insecure flag is deprecated; see 'go help get' for details\n")
+	if *getInsecure {
+		base.Fatalf("go get: -insecure flag is no longer supported; use GOINSECURE instead")
 	}
 
-	// Disable any prompting for passwords by Git.
+	// Disable any prompting for passwords by Git itself.
 	// Only has an effect for 2.3.0 or later, but avoiding
 	// the prompt in earlier versions is just too hard.
 	// If user has explicitly set GIT_TERMINAL_PROMPT=1, keep
@@ -143,7 +136,10 @@
 		os.Setenv("GIT_TERMINAL_PROMPT", "0")
 	}
 
-	// Disable any ssh connection pooling by Git.
+	// Also disable prompting for passwords by the 'ssh' subprocess spawned by
+	// Git, because apparently GIT_TERMINAL_PROMPT isn't sufficient to do that.
+	// Adding '-o BatchMode=yes' should do the trick.
+	//
 	// If a Git subprocess forks a child into the background to cache a new connection,
 	// that child keeps stdout/stderr open. After the Git subprocess exits,
 	// os /exec expects to be able to read from the stdout/stderr pipe
@@ -157,7 +153,14 @@
 	// assume they know what they are doing and don't step on it.
 	// But default to turning off ControlMaster.
 	if os.Getenv("GIT_SSH") == "" && os.Getenv("GIT_SSH_COMMAND") == "" {
-		os.Setenv("GIT_SSH_COMMAND", "ssh -o ControlMaster=no")
+		os.Setenv("GIT_SSH_COMMAND", "ssh -o ControlMaster=no -o BatchMode=yes")
+	}
+
+	// And one more source of Git prompts: the Git Credential Manager Core for Windows.
+	//
+	// See https://github.com/microsoft/Git-Credential-Manager-Core/blob/master/docs/environment.md#gcm_interactive.
+	if os.Getenv("GCM_INTERACTIVE") == "" {
+		os.Setenv("GCM_INTERACTIVE", "never")
 	}
 
 	// Phase 1. Download/update.
@@ -180,7 +183,7 @@
 	// everything.
 	load.ClearPackageCache()
 
-	pkgs := load.PackagesAndErrors(ctx, args)
+	pkgs := load.PackagesAndErrors(ctx, load.PackageOpts{}, args)
 	load.CheckPackageErrors(pkgs)
 
 	// Phase 3. Install.
@@ -255,9 +258,9 @@
 	load1 := func(path string, mode int) *load.Package {
 		if parent == nil {
 			mode := 0 // don't do module or vendor resolution
-			return load.LoadImport(context.TODO(), path, base.Cwd, nil, stk, nil, mode)
+			return load.LoadImport(context.TODO(), load.PackageOpts{}, path, base.Cwd(), nil, stk, nil, mode)
 		}
-		return load.LoadImport(context.TODO(), path, parent.Dir, parent, stk, nil, mode|load.ResolveModule)
+		return load.LoadImport(context.TODO(), load.PackageOpts{}, path, parent.Dir, parent, stk, nil, mode|load.ResolveModule)
 	}
 
 	p := load1(arg, mode)
@@ -435,7 +438,7 @@
 		return fmt.Errorf("%s: invalid import path: %v", p.ImportPath, err)
 	}
 	security := web.SecureOnly
-	if cfg.Insecure || module.MatchPrefixPatterns(cfg.GOINSECURE, importPrefix) {
+	if module.MatchPrefixPatterns(cfg.GOINSECURE, importPrefix) {
 		security = web.Insecure
 	}
 
diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go
index 57cee4f..490ff1f 100644
--- a/src/cmd/go/internal/help/helpdoc.go
+++ b/src/cmd/go/internal/help/helpdoc.go
@@ -251,7 +251,7 @@
 will result in the following requests:
 
 	https://example.org/pkg/foo?go-get=1 (preferred)
-	http://example.org/pkg/foo?go-get=1  (fallback, only with -insecure)
+	http://example.org/pkg/foo?go-get=1  (fallback, only with use of correctly set GOINSECURE)
 
 If that page contains the meta tag
 
@@ -517,9 +517,8 @@
 		Comma-separated list of glob patterns (in the syntax of Go's path.Match)
 		of module path prefixes that should always be fetched in an insecure
 		manner. Only applies to dependencies that are being fetched directly.
-		Unlike the -insecure flag on 'go get', GOINSECURE does not disable
-		checksum database validation. GOPRIVATE or GONOSUMDB may be used
-		to achieve that.
+		GOINSECURE does not disable checksum database validation. GOPRIVATE or
+		GONOSUMDB may be used to achieve that.
 	GOOS
 		The operating system for which to compile code.
 		Examples are linux, darwin, windows, netbsd.
@@ -599,6 +598,9 @@
 	GOMIPS64
 		For GOARCH=mips64{,le}, whether to use floating point instructions.
 		Valid values are hardfloat (default), softfloat.
+	GOPPC64
+		For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture).
+		Valid values are power8 (default), power9.
 	GOWASM
 		For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use.
 		Valid values are satconv, signext.
@@ -608,6 +610,12 @@
 	GCCGOTOOLDIR
 		If set, where to find gccgo tools, such as cgo.
 		The default is based on how gccgo was configured.
+	GOEXPERIMENT
+		Comma-separated list of toolchain experiments to enable or disable.
+		The list of available experiments may change arbitrarily over time.
+		See src/internal/goexperiment/flags.go for currently valid values.
+		Warning: This variable is provided for the development and testing
+		of the Go toolchain itself. Use beyond that purpose is unsupported.
 	GOROOT_FINAL
 		The root of the installed Go tree, when it is
 		installed in a location other than where it is built.
@@ -785,7 +793,7 @@
 	Long: `
 A build constraint, also known as a build tag, is a line comment that begins
 
-	// +build
+	//go:build
 
 that lists the conditions under which a file should be included in the package.
 Constraints may appear in any kind of source file (not just Go), but
@@ -793,30 +801,20 @@
 only by blank lines and other line comments. These rules mean that in Go
 files a build constraint must appear before the package clause.
 
-To distinguish build constraints from package documentation, a series of
-build constraints must be followed by a blank line.
+To distinguish build constraints from package documentation,
+a build constraint should be followed by a blank line.
 
-A build constraint is evaluated as the OR of space-separated options.
-Each option evaluates as the AND of its comma-separated terms.
-Each term consists of letters, digits, underscores, and dots.
-A term may be negated with a preceding !.
-For example, the build constraint:
+A build constraint is evaluated as an expression containing options
+combined by ||, &&, and ! operators and parentheses. Operators have
+the same meaning as in Go.
 
-	// +build linux,386 darwin,!cgo
+For example, the following build constraint constrains a file to
+build when the "linux" and "386" constraints are satisfied, or when
+"darwin" is satisfied and "cgo" is not:
 
-corresponds to the boolean formula:
+	//go:build (linux && 386) || (darwin && !cgo)
 
-	(linux AND 386) OR (darwin AND (NOT cgo))
-
-A file may have multiple build constraints. The overall constraint is the AND
-of the individual constraints. That is, the build constraints:
-
-	// +build linux darwin
-	// +build amd64
-
-corresponds to the boolean formula:
-
-	(linux OR darwin) AND amd64
+It is an error for a file to have more than one //go:build line.
 
 During a particular build, the following words are satisfied:
 
@@ -854,22 +852,26 @@
 
 To keep a file from being considered for the build:
 
-	// +build ignore
+	//go:build ignore
 
 (any other unsatisfied word will work as well, but "ignore" is conventional.)
 
 To build a file only when using cgo, and only on Linux and OS X:
 
-	// +build linux,cgo darwin,cgo
+	//go:build cgo && (linux || darwin)
 
 Such a file is usually paired with another file implementing the
 default functionality for other systems, which in this case would
 carry the constraint:
 
-	// +build !linux,!darwin !cgo
+	//go:build !(cgo && (linux || darwin))
 
 Naming a file dns_windows.go will cause it to be included only when
 building the package for Windows; similarly, math_386.s will be included
 only when building the package for 32-bit x86.
+
+Go versions 1.16 and earlier used a different syntax for build constraints,
+with a "// +build" prefix. The gofmt command will add an equivalent //go:build
+constraint when encountering the older syntax.
 `,
 }
diff --git a/src/cmd/go/internal/imports/read.go b/src/cmd/go/internal/imports/read.go
index 5e27078..70d5190 100644
--- a/src/cmd/go/internal/imports/read.go
+++ b/src/cmd/go/internal/imports/read.go
@@ -8,6 +8,7 @@
 
 import (
 	"bufio"
+	"bytes"
 	"errors"
 	"io"
 	"unicode/utf8"
@@ -22,6 +23,19 @@
 	nerr int
 }
 
+var bom = []byte{0xef, 0xbb, 0xbf}
+
+func newImportReader(b *bufio.Reader) *importReader {
+	// Remove leading UTF-8 BOM.
+	// Per https://golang.org/ref/spec#Source_code_representation:
+	// a compiler may ignore a UTF-8-encoded byte order mark (U+FEFF)
+	// if it is the first Unicode code point in the source text.
+	if leadingBytes, err := b.Peek(3); err == nil && bytes.Equal(leadingBytes, bom) {
+		b.Discard(3)
+	}
+	return &importReader{b: b}
+}
+
 func isIdent(c byte) bool {
 	return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c >= utf8.RuneSelf
 }
@@ -201,7 +215,7 @@
 // ReadComments is like io.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 := newImportReader(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.
@@ -213,7 +227,7 @@
 // ReadImports is like io.ReadAll, except that it expects a Go file as input
 // and stops reading the input once the imports have completed.
 func ReadImports(f io.Reader, reportSyntaxError bool, imports *[]string) ([]byte, error) {
-	r := &importReader{b: bufio.NewReader(f)}
+	r := newImportReader(bufio.NewReader(f))
 
 	r.readKeyword("package")
 	r.readIdent()
diff --git a/src/cmd/go/internal/imports/read_test.go b/src/cmd/go/internal/imports/read_test.go
index 6ea356f..6a1a652 100644
--- a/src/cmd/go/internal/imports/read_test.go
+++ b/src/cmd/go/internal/imports/read_test.go
@@ -66,6 +66,10 @@
 		`,
 		"",
 	},
+	{
+		"\ufeff𝔻" + `package p; import "x";ℙvar x = 1`,
+		"",
+	},
 }
 
 var readCommentsTests = []readTest{
@@ -82,6 +86,10 @@
 		"",
 	},
 	{
+		"\ufeff𝔻" + `ℙpackage p; import . "x"`,
+		"",
+	},
+	{
 		`// foo
 
 		/* bar */
@@ -94,6 +102,19 @@
 		ℙHello, world`,
 		"",
 	},
+	{
+		"\ufeff𝔻" + `// foo
+
+		/* bar */
+
+		/* quux */ // baz
+
+		/*/ zot */
+
+		// asdf
+		ℙHello, world`,
+		"",
+	},
 }
 
 func testRead(t *testing.T, tests []readTest, read func(io.Reader) ([]byte, error)) {
@@ -107,6 +128,11 @@
 			in = tt.in[:j] + tt.in[j+len("ℙ"):]
 			testOut = tt.in[:j]
 		}
+		d := strings.Index(tt.in, "𝔻")
+		if d >= 0 {
+			in = in[:d] + in[d+len("𝔻"):]
+			testOut = testOut[d+len("𝔻"):]
+		}
 		r := strings.NewReader(in)
 		buf, err := read(r)
 		if err != nil {
diff --git a/src/cmd/go/internal/list/context.go b/src/cmd/go/internal/list/context.go
index 68d691e..2dc6376 100644
--- a/src/cmd/go/internal/list/context.go
+++ b/src/cmd/go/internal/list/context.go
@@ -17,6 +17,7 @@
 	UseAllFiles   bool     `json:",omitempty"` // use files regardless of +build lines, file names
 	Compiler      string   `json:",omitempty"` // compiler to assume when computing target paths
 	BuildTags     []string `json:",omitempty"` // build constraints to match in +build lines
+	ToolTags      []string `json:",omitempty"` // toolchain-specific build constraints
 	ReleaseTags   []string `json:",omitempty"` // releases the current release is compatible with
 	InstallSuffix string   `json:",omitempty"` // suffix to use in the name of the install dir
 }
@@ -31,6 +32,7 @@
 		UseAllFiles:   c.UseAllFiles,
 		Compiler:      c.Compiler,
 		BuildTags:     c.BuildTags,
+		ToolTags:      c.ToolTags,
 		ReleaseTags:   c.ReleaseTags,
 		InstallSuffix: c.InstallSuffix,
 	}
diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go
index b4d82d9..7cb9ec6 100644
--- a/src/cmd/go/internal/list/list.go
+++ b/src/cmd/go/internal/list/list.go
@@ -148,6 +148,7 @@
         UseAllFiles   bool     // use files regardless of +build lines, file names
         Compiler      string   // compiler to assume when computing target paths
         BuildTags     []string // build constraints to match in +build lines
+        ToolTags      []string // toolchain-specific build constraints
         ReleaseTags   []string // releases the current release is compatible with
         InstallSuffix string   // suffix to use in the name of the install dir
     }
@@ -335,7 +336,10 @@
 var nl = []byte{'\n'}
 
 func runList(ctx context.Context, cmd *base.Command, args []string) {
-	load.ModResolveTests = *listTest
+	if *listFmt != "" && *listJson == true {
+		base.Fatalf("go list -f cannot be used with -json")
+	}
+
 	work.BuildInit()
 	out := newTrackingWriter(os.Stdout)
 	defer out.w.Flush()
@@ -344,7 +348,7 @@
 		if *listM {
 			*listFmt = "{{.String}}"
 			if *listVersions {
-				*listFmt = `{{.Path}}{{range .Versions}} {{.}}{{end}}`
+				*listFmt = `{{.Path}}{{range .Versions}} {{.}}{{end}}{{if .Deprecated}} (deprecated){{end}}`
 			}
 		} else {
 			*listFmt = "{{.ImportPath}}"
@@ -423,7 +427,7 @@
 			base.Fatalf("go list -m: not using modules")
 		}
 
-		modload.LoadModFile(ctx) // Parses go.mod and sets cfg.BuildMod.
+		modload.LoadModFile(ctx) // Sets cfg.BuildMod as a side-effect.
 		if cfg.BuildMod == "vendor" {
 			const actionDisabledFormat = "go list -m: can't %s using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)"
 
@@ -447,13 +451,29 @@
 			}
 		}
 
-		mods := modload.ListModules(ctx, args, *listU, *listVersions, *listRetracted)
+		var mode modload.ListMode
+		if *listU {
+			mode |= modload.ListU | modload.ListRetracted | modload.ListDeprecated
+		}
+		if *listRetracted {
+			mode |= modload.ListRetracted
+		}
+		if *listVersions {
+			mode |= modload.ListVersions
+			if *listRetracted {
+				mode |= modload.ListRetractedVersions
+			}
+		}
+		mods, err := modload.ListModules(ctx, args, mode)
 		if !*listE {
 			for _, m := range mods {
 				if m.Error != nil {
 					base.Errorf("go list -m: %v", m.Error.Err)
 				}
 			}
+			if err != nil {
+				base.Errorf("go list -m: %v", err)
+			}
 			base.ExitIfErrors()
 		}
 		for _, m := range mods {
@@ -478,8 +498,11 @@
 		base.Fatalf("go list -test cannot be used with -find")
 	}
 
-	load.IgnoreImports = *listFind
-	pkgs := load.PackagesAndErrors(ctx, args)
+	pkgOpts := load.PackageOpts{
+		IgnoreImports:   *listFind,
+		ModResolveTests: *listTest,
+	}
+	pkgs := load.PackagesAndErrors(ctx, pkgOpts, args)
 	if !*listE {
 		w := 0
 		for _, pkg := range pkgs {
@@ -516,9 +539,9 @@
 				var pmain, ptest, pxtest *load.Package
 				var err error
 				if *listE {
-					pmain, ptest, pxtest = load.TestPackagesAndErrors(ctx, p, nil)
+					pmain, ptest, pxtest = load.TestPackagesAndErrors(ctx, pkgOpts, p, nil)
 				} else {
-					pmain, ptest, pxtest, err = load.TestPackagesFor(ctx, p, nil)
+					pmain, ptest, pxtest, err = load.TestPackagesFor(ctx, pkgOpts, p, nil)
 					if err != nil {
 						base.Errorf("can't load test package: %s", err)
 					}
@@ -605,7 +628,7 @@
 		old := make(map[string]string)
 		for _, p := range all {
 			if p.ForTest != "" {
-				new := p.ImportPath + " [" + p.ForTest + ".test]"
+				new := p.Desc()
 				old[new] = p.ImportPath
 				p.ImportPath = new
 			}
@@ -679,9 +702,14 @@
 		}
 
 		if len(args) > 0 {
-			listU := false
-			listVersions := false
-			rmods := modload.ListModules(ctx, args, listU, listVersions, *listRetracted)
+			var mode modload.ListMode
+			if *listRetracted {
+				mode |= modload.ListRetracted
+			}
+			rmods, err := modload.ListModules(ctx, args, mode)
+			if err != nil && !*listE {
+				base.Errorf("go list -retracted: %v", err)
+			}
 			for i, arg := range args {
 				rmod := rmods[i]
 				for _, mod := range argToMods[arg] {
@@ -696,8 +724,18 @@
 
 	// Record non-identity import mappings in p.ImportMap.
 	for _, p := range pkgs {
-		for i, srcPath := range p.Internal.RawImports {
-			path := p.Imports[i]
+		nRaw := len(p.Internal.RawImports)
+		for i, path := range p.Imports {
+			var srcPath string
+			if i < nRaw {
+				srcPath = p.Internal.RawImports[i]
+			} else {
+				// This path is not within the raw imports, so it must be an import
+				// found only within CompiledGoFiles. Those paths are found in
+				// CompiledImports.
+				srcPath = p.Internal.CompiledImports[i-nRaw]
+			}
+
 			if path != srcPath {
 				if p.ImportMap == nil {
 					p.ImportMap = make(map[string]string)
diff --git a/src/cmd/go/internal/load/flag.go b/src/cmd/go/internal/load/flag.go
index 7534e65..440cb86 100644
--- a/src/cmd/go/internal/load/flag.go
+++ b/src/cmd/go/internal/load/flag.go
@@ -34,7 +34,7 @@
 
 // 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)
+	return f.set(v, base.Cwd())
 }
 
 // set is the implementation of Set, taking a cwd (current working directory) for easier testing.
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 8b12faf..a83cc9a 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -14,6 +14,7 @@
 	"go/build"
 	"go/scanner"
 	"go/token"
+	"internal/goroot"
 	"io/fs"
 	"os"
 	"path"
@@ -29,6 +30,8 @@
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/fsys"
+	"cmd/go/internal/imports"
+	"cmd/go/internal/modfetch"
 	"cmd/go/internal/modinfo"
 	"cmd/go/internal/modload"
 	"cmd/go/internal/par"
@@ -37,11 +40,10 @@
 	"cmd/go/internal/trace"
 	"cmd/internal/sys"
 
+	"golang.org/x/mod/modfile"
 	"golang.org/x/mod/module"
 )
 
-var IgnoreImports bool // control whether we ignore imports in packages
-
 // A Package describes a single package found in a directory.
 type Package struct {
 	PackagePublic                 // visible in 'go list'
@@ -85,6 +87,7 @@
 	CgoFiles          []string `json:",omitempty"` // .go source files that import "C"
 	CompiledGoFiles   []string `json:",omitempty"` // .go output from running cgo on CgoFiles
 	IgnoredGoFiles    []string `json:",omitempty"` // .go source files ignored due to build constraints
+	InvalidGoFiles    []string `json:",omitempty"` // .go source files with detected problems (parse error, wrong package name, and so on)
 	IgnoredOtherFiles []string `json:",omitempty"` // non-.go source files ignored due to build constraints
 	CFiles            []string `json:",omitempty"` // .c source files
 	CXXFiles          []string `json:",omitempty"` // .cc, .cpp and .cxx source files
@@ -142,6 +145,7 @@
 		p.CgoFiles,
 		// no p.CompiledGoFiles, because they are from GoFiles or generated by us
 		p.IgnoredGoFiles,
+		// no p.InvalidGoFiles, because they are from GoFiles
 		p.IgnoredOtherFiles,
 		p.CFiles,
 		p.CXXFiles,
@@ -190,8 +194,8 @@
 	// Unexported fields are not part of the public API.
 	Build             *build.Package
 	Imports           []*Package           // this package's direct imports
-	CompiledImports   []string             // additional Imports necessary when using CompiledGoFiles (all from standard library)
-	RawImports        []string             // this package's original imports as they appear in the text of the program
+	CompiledImports   []string             // additional Imports necessary when using CompiledGoFiles (all from standard library); 1:1 with the end of PackagePublic.Imports
+	RawImports        []string             // this package's original imports as they appear in the text of the program; 1:1 with the end of PackagePublic.Imports
 	ForceLibrary      bool                 // this package is a library (even if named "main")
 	CmdlineFiles      bool                 // package built from files listed on command line
 	CmdlinePkg        bool                 // package listed on command line
@@ -206,6 +210,7 @@
 	BuildInfo         string               // add this info to package main
 	TestmainGo        *[]byte              // content for _testmain.go
 	Embed             map[string][]string  // //go:embed comment mapping
+	OrigImportPath    string               // original import path before adding '_test' suffix
 
 	Asmflags   []string // -asmflags for this package
 	Gcflags    []string // -gcflags for this package
@@ -343,7 +348,7 @@
 	Var  string // name of count struct
 }
 
-func (p *Package) copyBuild(pp *build.Package) {
+func (p *Package) copyBuild(opts PackageOpts, pp *build.Package) {
 	p.Internal.Build = pp
 
 	if pp.PkgTargetRoot != "" && cfg.BuildPkgdir != "" {
@@ -368,6 +373,7 @@
 	p.GoFiles = pp.GoFiles
 	p.CgoFiles = pp.CgoFiles
 	p.IgnoredGoFiles = pp.IgnoredGoFiles
+	p.InvalidGoFiles = pp.InvalidGoFiles
 	p.IgnoredOtherFiles = pp.IgnoredOtherFiles
 	p.CFiles = pp.CFiles
 	p.CXXFiles = pp.CXXFiles
@@ -392,7 +398,7 @@
 	p.TestImports = pp.TestImports
 	p.XTestGoFiles = pp.XTestGoFiles
 	p.XTestImports = pp.XTestImports
-	if IgnoreImports {
+	if opts.IgnoreImports {
 		p.Imports = nil
 		p.Internal.RawImports = nil
 		p.TestImports = nil
@@ -401,6 +407,7 @@
 	p.EmbedPatterns = pp.EmbedPatterns
 	p.TestEmbedPatterns = pp.TestEmbedPatterns
 	p.XTestEmbedPatterns = pp.XTestEmbedPatterns
+	p.Internal.OrigImportPath = pp.ImportPath
 }
 
 // A PackageError describes an error loading information about a package.
@@ -476,8 +483,10 @@
 
 var (
 	_ ImportPathError = (*importError)(nil)
+	_ ImportPathError = (*mainPackageError)(nil)
 	_ ImportPathError = (*modload.ImportMissingError)(nil)
 	_ ImportPathError = (*modload.ImportMissingSumError)(nil)
+	_ ImportPathError = (*modload.DirectImportFromImplicitDependencyError)(nil)
 )
 
 type importError struct {
@@ -597,7 +606,7 @@
 		})
 		packageDataCache.Delete(p.ImportPath)
 	}
-	return LoadImport(context.TODO(), arg, base.Cwd, nil, stk, nil, 0)
+	return LoadImport(context.TODO(), PackageOpts{}, arg, base.Cwd(), nil, stk, nil, 0)
 }
 
 // dirToImportPath returns the pseudo-import path we use for a package
@@ -649,11 +658,11 @@
 // LoadImport does not set tool flags and should only be used by
 // this package, as part of a bigger load operation, and by GOPATH-based "go get".
 // TODO(rsc): When GOPATH-based "go get" is removed, unexport this function.
-func LoadImport(ctx context.Context, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
-	return loadImport(ctx, nil, path, srcDir, parent, stk, importPos, mode)
+func LoadImport(ctx context.Context, opts PackageOpts, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
+	return loadImport(ctx, opts, nil, path, srcDir, parent, stk, importPos, mode)
 }
 
-func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
+func loadImport(ctx context.Context, opts PackageOpts, pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
 	if path == "" {
 		panic("LoadImport called with empty package path")
 	}
@@ -665,25 +674,30 @@
 		parentRoot = parent.Root
 		parentIsStd = parent.Standard
 	}
-	bp, loaded, err := loadPackageData(path, parentPath, srcDir, parentRoot, parentIsStd, mode)
-	if loaded && pre != nil && !IgnoreImports {
-		pre.preloadImports(bp.Imports, bp)
+	bp, loaded, err := loadPackageData(ctx, path, parentPath, srcDir, parentRoot, parentIsStd, mode)
+	if loaded && pre != nil && !opts.IgnoreImports {
+		pre.preloadImports(ctx, opts, bp.Imports, bp)
 	}
 	if bp == nil {
+		p := &Package{
+			PackagePublic: PackagePublic{
+				ImportPath: path,
+				Incomplete: true,
+			},
+		}
 		if importErr, ok := err.(ImportPathError); !ok || importErr.ImportPath() != path {
-			// Only add path to the error's import stack if it's not already present on the error.
+			// Only add path to the error's import stack if it's not already present
+			// in the error.
+			//
+			// TODO(bcmills): setLoadPackageDataError itself has a similar Push / Pop
+			// sequence that empirically doesn't trigger for these errors, guarded by
+			// a somewhat complex condition. Figure out how to generalize that
+			// condition and eliminate the explicit calls here.
 			stk.Push(path)
 			defer stk.Pop()
 		}
-		return &Package{
-			PackagePublic: PackagePublic{
-				ImportPath: path,
-				Error: &PackageError{
-					ImportStack: stk.Copy(),
-					Err:         err,
-				},
-			},
-		}
+		p.setLoadPackageDataError(err, path, stk, nil)
+		return p
 	}
 
 	importPath := bp.ImportPath
@@ -701,7 +715,7 @@
 		// Load package.
 		// loadPackageData may return bp != nil even if an error occurs,
 		// in order to return partial information.
-		p.load(ctx, path, stk, importPos, bp, err)
+		p.load(ctx, opts, path, stk, importPos, bp, err)
 
 		if !cfg.ModulesEnabled && path != cleanImport(path) {
 			p.Error = &PackageError{
@@ -714,7 +728,7 @@
 	}
 
 	// Checked on every import because the rules depend on the code doing the importing.
-	if perr := disallowInternal(srcDir, parent, parentPath, p, stk); perr != p {
+	if perr := disallowInternal(ctx, srcDir, parent, parentPath, p, stk); perr != p {
 		perr.Error.setPos(importPos)
 		return perr
 	}
@@ -763,7 +777,7 @@
 //
 // loadPackageData returns a boolean, loaded, which is true if this is the
 // first time the package was loaded. Callers may preload imports in this case.
-func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd bool, mode int) (bp *build.Package, loaded bool, err error) {
+func loadPackageData(ctx context.Context, path, parentPath, parentDir, parentRoot string, parentIsStd bool, mode int) (bp *build.Package, loaded bool, err error) {
 	if path == "" {
 		panic("loadPackageData called with empty package path")
 	}
@@ -835,11 +849,34 @@
 				buildMode = build.ImportComment
 			}
 			data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode)
-			if data.p.Root == "" && cfg.ModulesEnabled {
-				if info := modload.PackageModuleInfo(path); info != nil {
+			if cfg.ModulesEnabled {
+				// Override data.p.Root, since ImportDir sets it to $GOPATH, if
+				// the module is inside $GOPATH/src.
+				if info := modload.PackageModuleInfo(ctx, path); info != nil {
 					data.p.Root = info.Dir
 				}
 			}
+			if r.err != nil {
+				if data.err != nil {
+					// ImportDir gave us one error, and the module loader gave us another.
+					// We arbitrarily choose to keep the error from ImportDir because
+					// that's what our tests already expect, and it seems to provide a bit
+					// more detail in most cases.
+				} else if errors.Is(r.err, imports.ErrNoGo) {
+					// ImportDir said there were files in the package, but the module
+					// loader said there weren't. Which one is right?
+					// Without this special-case hack, the TestScript/test_vet case fails
+					// on the vetfail/p1 package (added in CL 83955).
+					// Apparently, imports.ShouldBuild biases toward rejecting files
+					// with invalid build constraints, whereas ImportDir biases toward
+					// accepting them.
+					//
+					// TODO(#41410: Figure out how this actually ought to work and fix
+					// this mess.
+				} else {
+					data.err = r.err
+				}
+			}
 		} else if r.err != nil {
 			data.p = new(build.Package)
 			data.err = r.err
@@ -950,7 +987,7 @@
 // preloadMatches loads data for package paths matched by patterns.
 // When preloadMatches returns, some packages may not be loaded yet, but
 // loadPackageData and loadImport are always safe to call.
-func (pre *preload) preloadMatches(matches []*search.Match) {
+func (pre *preload) preloadMatches(ctx context.Context, opts PackageOpts, matches []*search.Match) {
 	for _, m := range matches {
 		for _, pkg := range m.Pkgs {
 			select {
@@ -959,10 +996,10 @@
 			case pre.sema <- struct{}{}:
 				go func(pkg string) {
 					mode := 0 // don't use vendoring or module import resolution
-					bp, loaded, err := loadPackageData(pkg, "", base.Cwd, "", false, mode)
+					bp, loaded, err := loadPackageData(ctx, pkg, "", base.Cwd(), "", false, mode)
 					<-pre.sema
-					if bp != nil && loaded && err == nil && !IgnoreImports {
-						pre.preloadImports(bp.Imports, bp)
+					if bp != nil && loaded && err == nil && !opts.IgnoreImports {
+						pre.preloadImports(ctx, opts, bp.Imports, bp)
 					}
 				}(pkg)
 			}
@@ -973,7 +1010,7 @@
 // preloadImports queues a list of imports for preloading.
 // When preloadImports returns, some packages may not be loaded yet,
 // but loadPackageData and loadImport are always safe to call.
-func (pre *preload) preloadImports(imports []string, parent *build.Package) {
+func (pre *preload) preloadImports(ctx context.Context, opts PackageOpts, imports []string, parent *build.Package) {
 	parentIsStd := parent.Goroot && parent.ImportPath != "" && search.IsStandardImportPath(parent.ImportPath)
 	for _, path := range imports {
 		if path == "C" || path == "unsafe" {
@@ -984,10 +1021,10 @@
 			return
 		case pre.sema <- struct{}{}:
 			go func(path string) {
-				bp, loaded, err := loadPackageData(path, parent.ImportPath, parent.Dir, parent.Root, parentIsStd, ResolveImport)
+				bp, loaded, err := loadPackageData(ctx, path, parent.ImportPath, parent.Dir, parent.Root, parentIsStd, ResolveImport)
 				<-pre.sema
-				if bp != nil && loaded && err == nil && !IgnoreImports {
-					pre.preloadImports(bp.Imports, bp)
+				if bp != nil && loaded && err == nil && !opts.IgnoreImports {
+					pre.preloadImports(ctx, opts, bp.Imports, bp)
 				}
 			}(path)
 		}
@@ -1323,6 +1360,11 @@
 				Err:           errors.New("import cycle not allowed"),
 				IsImportCycle: true,
 			}
+		} else if !p.Error.IsImportCycle {
+			// If the error is already set, but it does not indicate that
+			// we are in an import cycle, set IsImportCycle so that we don't
+			// end up stuck in a loop down the road.
+			p.Error.IsImportCycle = true
 		}
 		p.Incomplete = true
 	}
@@ -1338,7 +1380,7 @@
 // is allowed to import p.
 // If the import is allowed, disallowInternal returns the original package p.
 // If not, it returns a new package containing just an appropriate error.
-func disallowInternal(srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *Package {
+func disallowInternal(ctx context.Context, srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *Package {
 	// golang.org/s/go14internal:
 	// An import of a path containing the element “internal”
 	// is disallowed if the importing code is outside the tree
@@ -1410,7 +1452,7 @@
 			// directory containing them.
 			// If the directory is outside the main module, this will resolve to ".",
 			// which is not a prefix of any valid module.
-			importerPath = modload.DirImportPath(importer.Dir)
+			importerPath = modload.DirImportPath(ctx, importer.Dir)
 		}
 		parentOfInternal := p.ImportPath[:i]
 		if str.HasPathPrefix(importerPath, parentOfInternal) {
@@ -1632,8 +1674,8 @@
 // load populates p using information from bp, err, which should
 // be the result of calling build.Context.Import.
 // stk contains the import stack, not including path itself.
-func (p *Package) load(ctx context.Context, path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) {
-	p.copyBuild(bp)
+func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) {
+	p.copyBuild(opts, bp)
 
 	// The localPrefix is the path we interpret ./ imports relative to.
 	// Synthesized main packages sometimes override this.
@@ -1757,35 +1799,37 @@
 		}
 	}
 
-	// Cgo translation adds imports of "unsafe", "runtime/cgo" and "syscall",
-	// except for certain packages, to avoid circular dependencies.
-	if p.UsesCgo() {
-		addImport("unsafe", true)
-	}
-	if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" {
-		addImport("runtime/cgo", true)
-	}
-	if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
-		addImport("syscall", true)
-	}
-
-	// SWIG adds imports of some standard packages.
-	if p.UsesSwig() {
-		addImport("unsafe", true)
-		if cfg.BuildContext.Compiler != "gccgo" {
+	if !opts.IgnoreImports {
+		// Cgo translation adds imports of "unsafe", "runtime/cgo" and "syscall",
+		// except for certain packages, to avoid circular dependencies.
+		if p.UsesCgo() {
+			addImport("unsafe", true)
+		}
+		if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" {
 			addImport("runtime/cgo", true)
 		}
-		addImport("syscall", true)
-		addImport("sync", true)
+		if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
+			addImport("syscall", true)
+		}
 
-		// TODO: The .swig and .swigcxx files can use
-		// %go_import directives to import other packages.
-	}
+		// SWIG adds imports of some standard packages.
+		if p.UsesSwig() {
+			addImport("unsafe", true)
+			if cfg.BuildContext.Compiler != "gccgo" {
+				addImport("runtime/cgo", true)
+			}
+			addImport("syscall", true)
+			addImport("sync", true)
 
-	// The linker loads implicit dependencies.
-	if p.Name == "main" && !p.Internal.ForceLibrary {
-		for _, dep := range LinkerDeps(p) {
-			addImport(dep, false)
+			// 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, false)
+			}
 		}
 	}
 
@@ -1809,6 +1853,14 @@
 	stk.Push(path)
 	defer stk.Pop()
 
+	pkgPath := p.ImportPath
+	if p.Internal.CmdlineFiles {
+		pkgPath = "command-line-arguments"
+	}
+	if cfg.ModulesEnabled {
+		p.Module = modload.PackageModuleInfo(ctx, pkgPath)
+	}
+
 	p.EmbedFiles, p.Internal.Embed, err = resolveEmbed(p.Dir, p.EmbedPatterns)
 	if err != nil {
 		p.Incomplete = true
@@ -1852,7 +1904,7 @@
 		if path == "C" {
 			continue
 		}
-		p1 := LoadImport(ctx, path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport)
+		p1 := LoadImport(ctx, opts, path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport)
 
 		path = p1.ImportPath
 		importPaths[i] = path
@@ -1868,6 +1920,10 @@
 	p.Internal.Imports = imports
 	p.collectDeps()
 
+	if cfg.ModulesEnabled && p.Error == nil && p.Name == "main" && len(p.DepsErrors) == 0 {
+		p.Internal.BuildInfo = modload.PackageBuildInfo(pkgPath, p.Deps)
+	}
+
 	// unsafe is a fake package.
 	if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") {
 		p.Target = ""
@@ -1907,17 +1963,6 @@
 		setError(fmt.Errorf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " ")))
 		return
 	}
-
-	if cfg.ModulesEnabled && p.Error == nil {
-		mainPath := p.ImportPath
-		if p.Internal.CmdlineFiles {
-			mainPath = "command-line-arguments"
-		}
-		p.Module = modload.PackageModuleInfo(mainPath)
-		if p.Name == "main" && len(p.DepsErrors) == 0 {
-			p.Internal.BuildInfo = modload.PackageBuildInfo(mainPath, p.Deps)
-		}
-	}
 }
 
 // An EmbedError indicates a problem with a go:embed directive.
@@ -2299,7 +2344,7 @@
 // TestPackageList returns the list of packages in the dag rooted at roots
 // as visited in a depth-first post-order traversal, including the test
 // imports of the roots. This ignores errors in test packages.
-func TestPackageList(ctx context.Context, roots []*Package) []*Package {
+func TestPackageList(ctx context.Context, opts PackageOpts, roots []*Package) []*Package {
 	seen := map[*Package]bool{}
 	all := []*Package{}
 	var walk func(*Package)
@@ -2315,7 +2360,7 @@
 	}
 	walkTest := func(root *Package, path string) {
 		var stk ImportStack
-		p1 := LoadImport(ctx, path, root.Dir, root, &stk, root.Internal.Build.TestImportPos[path], ResolveImport)
+		p1 := LoadImport(ctx, opts, path, root.Dir, root, &stk, root.Internal.Build.TestImportPos[path], ResolveImport)
 		if p1.Error == nil {
 			walk(p1)
 		}
@@ -2338,22 +2383,35 @@
 // TODO(jayconrod): delete this function and set flags automatically
 // in LoadImport instead.
 func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
-	p := LoadImport(context.TODO(), path, srcDir, parent, stk, importPos, mode)
+	p := LoadImport(context.TODO(), PackageOpts{}, path, srcDir, parent, stk, importPos, mode)
 	setToolFlags(p)
 	return p
 }
 
-// ModResolveTests indicates whether calls to the module loader should also
-// resolve test dependencies of the requested packages.
-//
-// If ModResolveTests is true, then the module loader needs to resolve test
-// dependencies at the same time as packages; otherwise, the test dependencies
-// of those packages could be missing, and resolving those missing dependencies
-// could change the selected versions of modules that provide other packages.
-//
-// TODO(#40775): Change this from a global variable to an explicit function
-// argument where needed.
-var ModResolveTests bool
+// PackageOpts control the behavior of PackagesAndErrors and other package
+// loading functions.
+type PackageOpts struct {
+	// IgnoreImports controls whether we ignore explicit and implicit imports
+	// when loading packages.  Implicit imports are added when supporting Cgo
+	// or SWIG and when linking main packages.
+	IgnoreImports bool
+
+	// ModResolveTests indicates whether calls to the module loader should also
+	// resolve test dependencies of the requested packages.
+	//
+	// If ModResolveTests is true, then the module loader needs to resolve test
+	// dependencies at the same time as packages; otherwise, the test dependencies
+	// of those packages could be missing, and resolving those missing dependencies
+	// could change the selected versions of modules that provide other packages.
+	ModResolveTests bool
+
+	// MainOnly is true if the caller only wants to load main packages.
+	// For a literal argument matching a non-main package, a stub may be returned
+	// with an error. For a non-literal argument (with "..."), non-main packages
+	// are not be matched, and their dependencies may not be loaded. A warning
+	// may be printed for non-literal arguments that match no main packages.
+	MainOnly bool
+}
 
 // PackagesAndErrors returns the packages named by the command line arguments
 // 'patterns'. If a named package cannot be loaded, PackagesAndErrors returns
@@ -2363,7 +2421,7 @@
 //
 // To obtain a flat list of packages, use PackageList.
 // To report errors loading packages, use ReportPackageErrors.
-func PackagesAndErrors(ctx context.Context, patterns []string) []*Package {
+func PackagesAndErrors(ctx context.Context, opts PackageOpts, patterns []string) []*Package {
 	ctx, span := trace.StartSpan(ctx, "load.PackagesAndErrors")
 	defer span.Done()
 
@@ -2375,19 +2433,19 @@
 			// We need to test whether the path is an actual Go file and not a
 			// package path or pattern ending in '.go' (see golang.org/issue/34653).
 			if fi, err := fsys.Stat(p); err == nil && !fi.IsDir() {
-				return []*Package{GoFilesPackage(ctx, patterns)}
+				return []*Package{GoFilesPackage(ctx, opts, patterns)}
 			}
 		}
 	}
 
 	var matches []*search.Match
 	if modload.Init(); cfg.ModulesEnabled {
-		loadOpts := modload.PackageOpts{
+		modOpts := modload.PackageOpts{
 			ResolveMissingImports: true,
-			LoadTests:             ModResolveTests,
-			SilenceErrors:         true,
+			LoadTests:             opts.ModResolveTests,
+			SilencePackageErrors:  true,
 		}
-		matches, _ = modload.LoadPackages(ctx, loadOpts, patterns...)
+		matches, _ = modload.LoadPackages(ctx, modOpts, patterns...)
 	} else {
 		matches = search.ImportPaths(patterns)
 	}
@@ -2400,14 +2458,14 @@
 
 	pre := newPreload()
 	defer pre.flush()
-	pre.preloadMatches(matches)
+	pre.preloadMatches(ctx, opts, matches)
 
 	for _, m := range matches {
 		for _, pkg := range m.Pkgs {
 			if pkg == "" {
 				panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern()))
 			}
-			p := loadImport(ctx, pre, pkg, base.Cwd, nil, &stk, nil, 0)
+			p := loadImport(ctx, opts, pre, pkg, base.Cwd(), nil, &stk, nil, 0)
 			p.Match = append(p.Match, m.Pattern())
 			p.Internal.CmdlinePkg = true
 			if m.IsLiteral() {
@@ -2443,6 +2501,10 @@
 		}
 	}
 
+	if opts.MainOnly {
+		pkgs = mainPackagesOnly(pkgs, matches)
+	}
+
 	// Now that CmdlinePkg is set correctly,
 	// compute the effective flags for all loaded packages
 	// (not just the ones matching the patterns but also
@@ -2491,6 +2553,80 @@
 	base.ExitIfErrors()
 }
 
+// mainPackagesOnly filters out non-main packages matched only by arguments
+// containing "..." and returns the remaining main packages.
+//
+// Packages with missing, invalid, or ambiguous names may be treated as
+// possibly-main packages.
+//
+// mainPackagesOnly sets a non-main package's Error field and returns it if it
+// is named by a literal argument.
+//
+// mainPackagesOnly prints warnings for non-literal arguments that only match
+// non-main packages.
+func mainPackagesOnly(pkgs []*Package, matches []*search.Match) []*Package {
+	treatAsMain := map[string]bool{}
+	for _, m := range matches {
+		if m.IsLiteral() {
+			for _, path := range m.Pkgs {
+				treatAsMain[path] = true
+			}
+		}
+	}
+
+	var mains []*Package
+	for _, pkg := range pkgs {
+		if pkg.Name == "main" {
+			treatAsMain[pkg.ImportPath] = true
+			mains = append(mains, pkg)
+			continue
+		}
+
+		if len(pkg.InvalidGoFiles) > 0 { // TODO(#45999): && pkg.Name == "", but currently go/build sets pkg.Name arbitrarily if it is ambiguous.
+			// The package has (or may have) conflicting names, and we can't easily
+			// tell whether one of them is "main". So assume that it could be, and
+			// report an error for the package.
+			treatAsMain[pkg.ImportPath] = true
+		}
+		if treatAsMain[pkg.ImportPath] {
+			if pkg.Error == nil {
+				pkg.Error = &PackageError{Err: &mainPackageError{importPath: pkg.ImportPath}}
+			}
+			mains = append(mains, pkg)
+		}
+	}
+
+	for _, m := range matches {
+		if m.IsLiteral() || len(m.Pkgs) == 0 {
+			continue
+		}
+		foundMain := false
+		for _, path := range m.Pkgs {
+			if treatAsMain[path] {
+				foundMain = true
+				break
+			}
+		}
+		if !foundMain {
+			fmt.Fprintf(os.Stderr, "go: warning: %q matched only non-main packages\n", m.Pattern())
+		}
+	}
+
+	return mains
+}
+
+type mainPackageError struct {
+	importPath string
+}
+
+func (e *mainPackageError) Error() string {
+	return fmt.Sprintf("package %s is not a main package", e.importPath)
+}
+
+func (e *mainPackageError) ImportPath() string {
+	return e.importPath
+}
+
 func setToolFlags(pkgs ...*Package) {
 	for _, p := range PackageList(pkgs) {
 		p.Internal.Asmflags = BuildAsmflags.For(p)
@@ -2503,7 +2639,7 @@
 // GoFilesPackage creates a package for building a collection of Go files
 // (typically named on the command line). The target is named p.a for
 // package p or named after the first Go file for package main.
-func GoFilesPackage(ctx context.Context, gofiles []string) *Package {
+func GoFilesPackage(ctx context.Context, opts PackageOpts, gofiles []string) *Package {
 	modload.Init()
 
 	for _, f := range gofiles {
@@ -2556,7 +2692,7 @@
 
 	var err error
 	if dir == "" {
-		dir = base.Cwd
+		dir = base.Cwd()
 	}
 	dir, err = filepath.Abs(dir)
 	if err != nil {
@@ -2567,7 +2703,7 @@
 	pkg := new(Package)
 	pkg.Internal.Local = true
 	pkg.Internal.CmdlineFiles = true
-	pkg.load(ctx, "command-line-arguments", &stk, nil, bp, err)
+	pkg.load(ctx, opts, "command-line-arguments", &stk, nil, bp, err)
 	pkg.Internal.LocalPrefix = dirToImportPath(dir)
 	pkg.ImportPath = "command-line-arguments"
 	pkg.Target = ""
@@ -2583,7 +2719,138 @@
 		}
 	}
 
+	if opts.MainOnly && pkg.Name != "main" && pkg.Error == nil {
+		pkg.Error = &PackageError{Err: &mainPackageError{importPath: pkg.ImportPath}}
+	}
 	setToolFlags(pkg)
 
 	return pkg
 }
+
+// PackagesAndErrorsOutsideModule is like PackagesAndErrors but runs in
+// module-aware mode and ignores the go.mod file in the current directory or any
+// parent directory, if there is one. This is used in the implementation of 'go
+// install pkg@version' and other commands that support similar forms.
+//
+// modload.ForceUseModules must be true, and modload.RootMode must be NoRoot
+// before calling this function.
+//
+// PackagesAndErrorsOutsideModule imposes several constraints to avoid
+// ambiguity. All arguments must have the same version suffix (not just a suffix
+// that resolves to the same version). They must refer to packages in the same
+// module, which must not be std or cmd. That module is not considered the main
+// module, but its go.mod file (if it has one) must not contain directives that
+// would cause it to be interpreted differently if it were the main module
+// (replace, exclude).
+func PackagesAndErrorsOutsideModule(ctx context.Context, opts PackageOpts, args []string) ([]*Package, error) {
+	if !modload.ForceUseModules {
+		panic("modload.ForceUseModules must be true")
+	}
+	if modload.RootMode != modload.NoRoot {
+		panic("modload.RootMode must be NoRoot")
+	}
+
+	// Check that the arguments satisfy syntactic constraints.
+	var version string
+	for _, arg := range args {
+		if i := strings.Index(arg, "@"); i >= 0 {
+			version = arg[i+1:]
+			if version == "" {
+				return nil, fmt.Errorf("%s: version must not be empty", arg)
+			}
+			break
+		}
+	}
+	patterns := make([]string, len(args))
+	for i, arg := range args {
+		if !strings.HasSuffix(arg, "@"+version) {
+			return nil, fmt.Errorf("%s: all arguments must have the same version (@%s)", arg, version)
+		}
+		p := arg[:len(arg)-len(version)-1]
+		switch {
+		case build.IsLocalImport(p):
+			return nil, fmt.Errorf("%s: argument must be a package path, not a relative path", arg)
+		case filepath.IsAbs(p):
+			return nil, fmt.Errorf("%s: argument must be a package path, not an absolute path", arg)
+		case search.IsMetaPackage(p):
+			return nil, fmt.Errorf("%s: argument must be a package path, not a meta-package", arg)
+		case path.Clean(p) != p:
+			return nil, fmt.Errorf("%s: argument must be a clean package path", arg)
+		case !strings.Contains(p, "...") && search.IsStandardImportPath(p) && goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, p):
+			return nil, fmt.Errorf("%s: argument must not be a package in the standard library", arg)
+		default:
+			patterns[i] = p
+		}
+	}
+
+	// Query the module providing the first argument, load its go.mod file, and
+	// check that it doesn't contain directives that would cause it to be
+	// interpreted differently if it were the main module.
+	//
+	// If multiple modules match the first argument, accept the longest match
+	// (first result). It's possible this module won't provide packages named by
+	// later arguments, and other modules would. Let's not try to be too
+	// magical though.
+	allowed := modload.CheckAllowed
+	if modload.IsRevisionQuery(version) {
+		// Don't check for retractions if a specific revision is requested.
+		allowed = nil
+	}
+	noneSelected := func(path string) (version string) { return "none" }
+	qrs, err := modload.QueryPackages(ctx, patterns[0], version, noneSelected, allowed)
+	if err != nil {
+		return nil, fmt.Errorf("%s: %w", args[0], err)
+	}
+	rootMod := qrs[0].Mod
+	data, err := modfetch.GoMod(rootMod.Path, rootMod.Version)
+	if err != nil {
+		return nil, fmt.Errorf("%s: %w", args[0], err)
+	}
+	f, err := modfile.Parse("go.mod", data, nil)
+	if err != nil {
+		return nil, fmt.Errorf("%s (in %s): %w", args[0], rootMod, err)
+	}
+	directiveFmt := "%s (in %s):\n" +
+		"\tThe go.mod file for the module providing named packages contains one or\n" +
+		"\tmore %s directives. It must not contain directives that would cause\n" +
+		"\tit to be interpreted differently than if it were the main module."
+	if len(f.Replace) > 0 {
+		return nil, fmt.Errorf(directiveFmt, args[0], rootMod, "replace")
+	}
+	if len(f.Exclude) > 0 {
+		return nil, fmt.Errorf(directiveFmt, args[0], rootMod, "exclude")
+	}
+
+	// Since we are in NoRoot mode, the build list initially contains only
+	// the dummy command-line-arguments module. Add a requirement on the
+	// module that provides the packages named on the command line.
+	if _, err := modload.EditBuildList(ctx, nil, []module.Version{rootMod}); err != nil {
+		return nil, fmt.Errorf("%s: %w", args[0], err)
+	}
+
+	// Load packages for all arguments.
+	pkgs := PackagesAndErrors(ctx, opts, patterns)
+
+	// Check that named packages are all provided by the same module.
+	for _, pkg := range pkgs {
+		var pkgErr error
+		if pkg.Module == nil {
+			// Packages in std, cmd, and their vendored dependencies
+			// don't have this field set.
+			pkgErr = fmt.Errorf("package %s not provided by module %s", pkg.ImportPath, rootMod)
+		} else if pkg.Module.Path != rootMod.Path || pkg.Module.Version != rootMod.Version {
+			pkgErr = fmt.Errorf("package %s provided by module %s@%s\n\tAll packages must be provided by the same module (%s).", pkg.ImportPath, pkg.Module.Path, pkg.Module.Version, rootMod)
+		}
+		if pkgErr != nil && pkg.Error == nil {
+			pkg.Error = &PackageError{Err: pkgErr}
+		}
+	}
+
+	matchers := make([]func(string) bool, len(patterns))
+	for i, p := range patterns {
+		if strings.Contains(p, "...") {
+			matchers[i] = search.MatchPattern(p)
+		}
+	}
+	return pkgs, nil
+}
diff --git a/src/cmd/go/internal/load/test.go b/src/cmd/go/internal/load/test.go
index eb8aef3..c828296 100644
--- a/src/cmd/go/internal/load/test.go
+++ b/src/cmd/go/internal/load/test.go
@@ -21,6 +21,7 @@
 	"unicode"
 	"unicode/utf8"
 
+	"cmd/go/internal/fsys"
 	"cmd/go/internal/str"
 	"cmd/go/internal/trace"
 )
@@ -45,8 +46,8 @@
 // TestPackagesFor is like TestPackagesAndErrors but it returns
 // an error if the test packages or their dependencies have errors.
 // Only test packages without errors are returned.
-func TestPackagesFor(ctx context.Context, p *Package, cover *TestCover) (pmain, ptest, pxtest *Package, err error) {
-	pmain, ptest, pxtest = TestPackagesAndErrors(ctx, p, cover)
+func TestPackagesFor(ctx context.Context, opts PackageOpts, p *Package, cover *TestCover) (pmain, ptest, pxtest *Package, err error) {
+	pmain, ptest, pxtest = TestPackagesAndErrors(ctx, opts, p, cover)
 	for _, p1 := range []*Package{ptest, pxtest, pmain} {
 		if p1 == nil {
 			// pxtest may be nil
@@ -92,7 +93,7 @@
 //
 // The caller is expected to have checked that len(p.TestGoFiles)+len(p.XTestGoFiles) > 0,
 // or else there's no point in any of this.
-func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (pmain, ptest, pxtest *Package) {
+func TestPackagesAndErrors(ctx context.Context, opts PackageOpts, p *Package, cover *TestCover) (pmain, ptest, pxtest *Package) {
 	ctx, span := trace.StartSpan(ctx, "load.TestPackagesAndErrors")
 	defer span.Done()
 
@@ -100,7 +101,7 @@
 	defer pre.flush()
 	allImports := append([]string{}, p.TestImports...)
 	allImports = append(allImports, p.XTestImports...)
-	pre.preloadImports(allImports, p.Internal.Build)
+	pre.preloadImports(ctx, opts, allImports, p.Internal.Build)
 
 	var ptestErr, pxtestErr *PackageError
 	var imports, ximports []*Package
@@ -109,13 +110,13 @@
 	stk.Push(p.ImportPath + " (test)")
 	rawTestImports := str.StringList(p.TestImports)
 	for i, path := range p.TestImports {
-		p1 := loadImport(ctx, pre, path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], ResolveImport)
+		p1 := loadImport(ctx, opts, pre, path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], ResolveImport)
 		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.
 			ptestErr = &PackageError{
-				ImportStack:   testImportStack(stk[0], p1, p.ImportPath),
+				ImportStack:   importCycleStack(p1, p.ImportPath),
 				Err:           errors.New("import cycle not allowed in test"),
 				IsImportCycle: true,
 			}
@@ -139,7 +140,7 @@
 	pxtestNeedsPtest := false
 	rawXTestImports := str.StringList(p.XTestImports)
 	for i, path := range p.XTestImports {
-		p1 := loadImport(ctx, pre, path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], ResolveImport)
+		p1 := loadImport(ctx, opts, pre, path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], ResolveImport)
 		if p1.ImportPath == p.ImportPath {
 			pxtestNeedsPtest = true
 		} else {
@@ -203,6 +204,7 @@
 		}
 		ptest.Internal.Embed = testEmbed
 		ptest.EmbedFiles = str.StringList(p.EmbedFiles, p.TestEmbedFiles)
+		ptest.Internal.OrigImportPath = p.Internal.OrigImportPath
 		ptest.collectDeps()
 	} else {
 		ptest = p
@@ -232,11 +234,12 @@
 				Imports:    ximports,
 				RawImports: rawXTestImports,
 
-				Asmflags:   p.Internal.Asmflags,
-				Gcflags:    p.Internal.Gcflags,
-				Ldflags:    p.Internal.Ldflags,
-				Gccgoflags: p.Internal.Gccgoflags,
-				Embed:      xtestEmbed,
+				Asmflags:       p.Internal.Asmflags,
+				Gcflags:        p.Internal.Gcflags,
+				Ldflags:        p.Internal.Ldflags,
+				Gccgoflags:     p.Internal.Gccgoflags,
+				Embed:          xtestEmbed,
+				OrigImportPath: p.Internal.OrigImportPath,
 			},
 		}
 		if pxtestNeedsPtest {
@@ -257,12 +260,13 @@
 			Module:     p.Module,
 		},
 		Internal: PackageInternal{
-			Build:      &build.Package{Name: "main"},
-			BuildInfo:  p.Internal.BuildInfo,
-			Asmflags:   p.Internal.Asmflags,
-			Gcflags:    p.Internal.Gcflags,
-			Ldflags:    p.Internal.Ldflags,
-			Gccgoflags: p.Internal.Gccgoflags,
+			Build:          &build.Package{Name: "main"},
+			BuildInfo:      p.Internal.BuildInfo,
+			Asmflags:       p.Internal.Asmflags,
+			Gcflags:        p.Internal.Gcflags,
+			Ldflags:        p.Internal.Ldflags,
+			Gccgoflags:     p.Internal.Gccgoflags,
+			OrigImportPath: p.Internal.OrigImportPath,
 		},
 	}
 
@@ -277,7 +281,7 @@
 		if dep == ptest.ImportPath {
 			pmain.Internal.Imports = append(pmain.Internal.Imports, ptest)
 		} else {
-			p1 := loadImport(ctx, pre, dep, "", nil, &stk, nil, 0)
+			p1 := loadImport(ctx, opts, pre, dep, "", nil, &stk, nil, 0)
 			pmain.Internal.Imports = append(pmain.Internal.Imports, p1)
 		}
 	}
@@ -290,10 +294,12 @@
 			seen[p1] = true
 		}
 		for _, p1 := range cover.Pkgs {
-			if !seen[p1] {
-				seen[p1] = true
-				pmain.Internal.Imports = append(pmain.Internal.Imports, p1)
+			if seen[p1] {
+				// Don't add duplicate imports.
+				continue
 			}
+			seen[p1] = true
+			pmain.Internal.Imports = append(pmain.Internal.Imports, p1)
 		}
 	}
 
@@ -369,22 +375,44 @@
 	return pmain, ptest, pxtest
 }
 
-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
+// importCycleStack returns an import stack from p to the package whose import
+// path is target.
+func importCycleStack(p *Package, target string) []string {
+	// importerOf maps each import path to its importer nearest to p.
+	importerOf := map[string]string{p.ImportPath: ""}
+
+	// q is a breadth-first queue of packages to search for target.
+	// Every package added to q has a corresponding entry in pathTo.
+	//
+	// We search breadth-first for two reasons:
+	//
+	// 	1. We want to report the shortest cycle.
+	//
+	// 	2. If p contains multiple cycles, the first cycle we encounter might not
+	// 	   contain target. To ensure termination, we have to break all cycles
+	// 	   other than the first.
+	q := []*Package{p}
+
+	for len(q) > 0 {
+		p := q[0]
+		q = q[1:]
+		if path := p.ImportPath; path == target {
+			var stk []string
+			for path != "" {
+				stk = append(stk, path)
+				path = importerOf[path]
+			}
+			return stk
+		}
+		for _, dep := range p.Internal.Imports {
+			if _, ok := importerOf[dep.ImportPath]; !ok {
+				importerOf[dep.ImportPath] = p.ImportPath
+				q = append(q, dep)
 			}
 		}
-		// Can't happen, but in case it does...
-		stk = append(stk, "<lost path to cycle>")
-		break
 	}
-	return stk
+
+	panic("lost path to cycle")
 }
 
 // recompileForTest copies and replaces certain packages in pmain's dependency
@@ -576,7 +604,13 @@
 var testFileSet = token.NewFileSet()
 
 func (t *testFuncs) load(filename, pkg string, doImport, seen *bool) error {
-	f, err := parser.ParseFile(testFileSet, filename, nil, parser.ParseComments)
+	// Pass in the overlaid source if we have an overlay for this file.
+	src, err := fsys.Open(filename)
+	if err != nil {
+		return err
+	}
+	defer src.Close()
+	f, err := parser.ParseFile(testFileSet, filename, src, parser.ParseComments)
 	if err != nil {
 		return err
 	}
diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go
index 1fa4327..a37b2ad 100644
--- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go
+++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || (solaris && !illumos)
 // +build aix solaris,!illumos
 
 // This code implements the filelock API using POSIX 'fcntl' locks, which attach
diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go
index bc48034..70f5d7a 100644
--- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go
+++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !plan9 && !solaris && !windows
 // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!plan9,!solaris,!windows
 
 package filelock
diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go
index 0798ee4..908afb6 100644
--- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go
+++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build plan9
 // +build plan9
 
 package filelock
diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go
index 2ac2052..640d440 100644
--- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go
+++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js && !plan9
 // +build !js,!plan9
 
 package filelock_test
diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go
index ed07bac..878a1e7 100644
--- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go
+++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || illumos || linux || netbsd || openbsd
 // +build darwin dragonfly freebsd illumos linux netbsd openbsd
 
 package filelock
diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go
index 19de27e..dd27ce9 100644
--- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go
+++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build windows
 // +build windows
 
 package filelock
diff --git a/src/cmd/go/internal/lockedfile/lockedfile_filelock.go b/src/cmd/go/internal/lockedfile/lockedfile_filelock.go
index efc6646..e4923f6 100644
--- a/src/cmd/go/internal/lockedfile/lockedfile_filelock.go
+++ b/src/cmd/go/internal/lockedfile/lockedfile_filelock.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !plan9
 // +build !plan9
 
 package lockedfile
@@ -10,7 +11,6 @@
 	"io/fs"
 	"os"
 
-	"cmd/go/internal/fsys"
 	"cmd/go/internal/lockedfile/internal/filelock"
 )
 
@@ -20,7 +20,7 @@
 	// calls for Linux and Windows anyway, so it's simpler to use that approach
 	// consistently.
 
-	f, err := fsys.OpenFile(name, flag&^os.O_TRUNC, perm)
+	f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/cmd/go/internal/lockedfile/lockedfile_plan9.go b/src/cmd/go/internal/lockedfile/lockedfile_plan9.go
index 70d6edd..979118b 100644
--- a/src/cmd/go/internal/lockedfile/lockedfile_plan9.go
+++ b/src/cmd/go/internal/lockedfile/lockedfile_plan9.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build plan9
 // +build plan9
 
 package lockedfile
@@ -12,8 +13,6 @@
 	"os"
 	"strings"
 	"time"
-
-	"cmd/go/internal/fsys"
 )
 
 // Opening an exclusive-use file returns an error.
@@ -58,7 +57,7 @@
 	// If the file was unpacked or created by some other program, it might not
 	// have the ModeExclusive bit set. Set it before we call OpenFile, so that we
 	// can be confident that a successful OpenFile implies exclusive use.
-	if fi, err := fsys.Stat(name); err == nil {
+	if fi, err := os.Stat(name); err == nil {
 		if fi.Mode()&fs.ModeExclusive == 0 {
 			if err := os.Chmod(name, fi.Mode()|fs.ModeExclusive); err != nil {
 				return nil, err
@@ -71,7 +70,7 @@
 	nextSleep := 1 * time.Millisecond
 	const maxSleep = 500 * time.Millisecond
 	for {
-		f, err := fsys.OpenFile(name, flag, perm|fs.ModeExclusive)
+		f, err := os.OpenFile(name, flag, perm|fs.ModeExclusive)
 		if err == nil {
 			return f, nil
 		}
diff --git a/src/cmd/go/internal/lockedfile/lockedfile_test.go b/src/cmd/go/internal/lockedfile/lockedfile_test.go
index 34327dd..3acc669 100644
--- a/src/cmd/go/internal/lockedfile/lockedfile_test.go
+++ b/src/cmd/go/internal/lockedfile/lockedfile_test.go
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // js does not support inter-process file locking.
+//go:build !js
 // +build !js
 
 package lockedfile_test
diff --git a/src/cmd/go/internal/lockedfile/transform_test.go b/src/cmd/go/internal/lockedfile/transform_test.go
index 407d48e..b753346 100644
--- a/src/cmd/go/internal/lockedfile/transform_test.go
+++ b/src/cmd/go/internal/lockedfile/transform_test.go
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // js does not support inter-process file locking.
+//go:build !js
 // +build !js
 
 package lockedfile_test
diff --git a/src/cmd/go/internal/modcmd/download.go b/src/cmd/go/internal/modcmd/download.go
index e7d3d86..0e5af85 100644
--- a/src/cmd/go/internal/modcmd/download.go
+++ b/src/cmd/go/internal/modcmd/download.go
@@ -86,9 +86,11 @@
 	if !modload.HasModRoot() && len(args) == 0 {
 		base.Fatalf("go mod download: no modules specified (see 'go help mod download')")
 	}
-	if len(args) == 0 {
+	haveExplicitArgs := len(args) > 0
+	if !haveExplicitArgs {
 		args = []string{"all"}
-	} else if modload.HasModRoot() {
+	}
+	if modload.HasModRoot() {
 		modload.LoadModFile(ctx) // to fill Target
 		targetAtUpgrade := modload.Target.Path + "@upgrade"
 		targetAtPatch := modload.Target.Path + "@patch"
@@ -132,12 +134,22 @@
 	}
 
 	var mods []*moduleJSON
-	listU := false
-	listVersions := false
-	listRetractions := false
 	type token struct{}
 	sem := make(chan token, runtime.GOMAXPROCS(0))
-	for _, info := range modload.ListModules(ctx, args, listU, listVersions, listRetractions) {
+	infos, infosErr := modload.ListModules(ctx, args, 0)
+	if !haveExplicitArgs {
+		// 'go mod download' is sometimes run without arguments to pre-populate the
+		// module cache. It may fetch modules that aren't needed to build packages
+		// in the main mdoule. This is usually not intended, so don't save sums for
+		// downloaded modules (golang.org/issue/45332).
+		// TODO(golang.org/issue/45551): For now, in ListModules, save sums needed
+		// to load the build list (same as 1.15 behavior). In the future, report an
+		// error if go.mod or go.sum need to be updated after loading the build
+		// list.
+		modload.DisallowWriteGoMod()
+	}
+
+	for _, info := range infos {
 		if info.Replace != nil {
 			info = info.Replace
 		}
@@ -187,6 +199,20 @@
 		base.ExitIfErrors()
 	}
 
-	// Update go.mod and especially go.sum if needed.
-	modload.WriteGoMod()
+	// If there were explicit arguments, update go.mod and especially go.sum.
+	// 'go mod download mod@version' is a useful way to add a sum without using
+	// 'go get mod@version', which may have other side effects. We print this in
+	// some error message hints.
+	//
+	// Don't save sums for 'go mod download' without arguments; see comment above.
+	if haveExplicitArgs {
+		modload.WriteGoMod(ctx)
+	}
+
+	// If there was an error matching some of the requested packages, emit it now
+	// (after we've written the checksums for the modules that were downloaded
+	// successfully).
+	if infosErr != nil {
+		base.Errorf("go mod download: %v", infosErr)
+	}
 }
diff --git a/src/cmd/go/internal/modcmd/edit.go b/src/cmd/go/internal/modcmd/edit.go
index 1df104e..bb3d521 100644
--- a/src/cmd/go/internal/modcmd/edit.go
+++ b/src/cmd/go/internal/modcmd/edit.go
@@ -25,7 +25,7 @@
 )
 
 var cmdEdit = &base.Command{
-	UsageLine: "go mod edit [editing flags] [go.mod]",
+	UsageLine: "go mod edit [editing flags] [-fmt|-print|-json] [go.mod]",
 	Short:     "edit go.mod from tools or scripts",
 	Long: `
 Edit provides a command-line interface for editing go.mod,
@@ -85,12 +85,12 @@
 writing it back to go.mod. The JSON output corresponds to these Go types:
 
 	type Module struct {
-		Path string
+		Path    string
 		Version string
 	}
 
 	type GoMod struct {
-		Module  Module
+		Module  ModPath
 		Go      string
 		Require []Require
 		Exclude []Module
@@ -98,6 +98,11 @@
 		Retract []Retract
 	}
 
+	type ModPath struct {
+		Path       string
+		Deprecated string
+	}
+
 	type Require struct {
 		Path string
 		Version string
@@ -191,7 +196,7 @@
 
 	if *editGo != "" {
 		if !modfile.GoVersionRE.MatchString(*editGo) {
-			base.Fatalf(`go mod: invalid -go option; expecting something like "-go 1.12"`)
+			base.Fatalf(`go mod: invalid -go option; expecting something like "-go %s"`, modload.LatestGoVersion())
 		}
 	}
 
@@ -450,7 +455,7 @@
 
 // fileJSON is the -json output data structure.
 type fileJSON struct {
-	Module  module.Version
+	Module  editModuleJSON
 	Go      string `json:",omitempty"`
 	Require []requireJSON
 	Exclude []module.Version
@@ -458,6 +463,11 @@
 	Retract []retractJSON
 }
 
+type editModuleJSON struct {
+	Path       string
+	Deprecated string `json:",omitempty"`
+}
+
 type requireJSON struct {
 	Path     string
 	Version  string `json:",omitempty"`
@@ -479,7 +489,10 @@
 func editPrintJSON(modFile *modfile.File) {
 	var f fileJSON
 	if modFile.Module != nil {
-		f.Module = modFile.Module.Mod
+		f.Module = editModuleJSON{
+			Path:       modFile.Module.Mod.Path,
+			Deprecated: modFile.Module.Deprecated,
+		}
 	}
 	if modFile.Go != nil {
 		f.Go = modFile.Go.Version
diff --git a/src/cmd/go/internal/modcmd/graph.go b/src/cmd/go/internal/modcmd/graph.go
index a88e9ef..ac81f26 100644
--- a/src/cmd/go/internal/modcmd/graph.go
+++ b/src/cmd/go/internal/modcmd/graph.go
@@ -10,7 +10,6 @@
 	"bufio"
 	"context"
 	"os"
-	"sort"
 
 	"cmd/go/internal/base"
 	"cmd/go/internal/modload"
@@ -19,7 +18,7 @@
 )
 
 var cmdGraph = &base.Command{
-	UsageLine: "go mod graph",
+	UsageLine: "go mod graph [-go=version]",
 	Short:     "print module requirement graph",
 	Long: `
 Graph prints the module requirement graph (with replacements applied)
@@ -27,12 +26,21 @@
 and one of its requirements. Each module is identified as a string of the form
 path@version, except for the main module, which has no @version suffix.
 
+The -go flag causes graph to report the module graph as loaded by the
+given Go version, instead of the version indicated by the 'go' directive
+in the go.mod file.
+
 See https://golang.org/ref/mod#go-mod-graph for more about 'go mod graph'.
 	`,
 	Run: runGraph,
 }
 
+var (
+	graphGo goVersionFlag
+)
+
 func init() {
+	cmdGraph.Flag.Var(&graphGo, "go", "")
 	base.AddModCommonFlags(&cmdGraph.Flag)
 }
 
@@ -42,43 +50,26 @@
 	}
 	modload.ForceUseModules = true
 	modload.RootMode = modload.NeedRoot
-	modload.LoadAllModules(ctx)
-
-	reqs := modload.MinReqs()
-	format := func(m module.Version) string {
-		if m.Version == "" {
-			return m.Path
-		}
-		return m.Path + "@" + m.Version
-	}
-
-	var out []string
-	var deps int // index in out where deps start
-	seen := map[module.Version]bool{modload.Target: true}
-	queue := []module.Version{modload.Target}
-	for len(queue) > 0 {
-		var m module.Version
-		m, queue = queue[0], queue[1:]
-		list, _ := reqs.Required(m)
-		for _, r := range list {
-			if !seen[r] {
-				queue = append(queue, r)
-				seen[r] = true
-			}
-			out = append(out, format(m)+" "+format(r)+"\n")
-		}
-		if m == modload.Target {
-			deps = len(out)
-		}
-	}
-
-	sort.Slice(out[deps:], func(i, j int) bool {
-		return out[deps+i][0] < out[deps+j][0]
-	})
+	mg := modload.LoadModGraph(ctx, graphGo.String())
 
 	w := bufio.NewWriter(os.Stdout)
-	for _, line := range out {
-		w.WriteString(line)
+	defer w.Flush()
+
+	format := func(m module.Version) {
+		w.WriteString(m.Path)
+		if m.Version != "" {
+			w.WriteString("@")
+			w.WriteString(m.Version)
+		}
 	}
-	w.Flush()
+
+	mg.WalkBreadthFirst(func(m module.Version) {
+		reqs, _ := mg.RequiredBy(m)
+		for _, r := range reqs {
+			format(m)
+			w.WriteByte(' ')
+			format(r)
+			w.WriteByte('\n')
+		}
+	})
 }
diff --git a/src/cmd/go/internal/modcmd/init.go b/src/cmd/go/internal/modcmd/init.go
index 73cc282..958c306 100644
--- a/src/cmd/go/internal/modcmd/init.go
+++ b/src/cmd/go/internal/modcmd/init.go
@@ -13,7 +13,7 @@
 )
 
 var cmdInit = &base.Command{
-	UsageLine: "go mod init [module]",
+	UsageLine: "go mod init [module-path]",
 	Short:     "initialize new module in current directory",
 	Long: `
 Init initializes and writes a new go.mod file in the current directory, in
diff --git a/src/cmd/go/internal/modcmd/tidy.go b/src/cmd/go/internal/modcmd/tidy.go
index 8bc9ed5..fe25507 100644
--- a/src/cmd/go/internal/modcmd/tidy.go
+++ b/src/cmd/go/internal/modcmd/tidy.go
@@ -12,10 +12,14 @@
 	"cmd/go/internal/imports"
 	"cmd/go/internal/modload"
 	"context"
+	"fmt"
+
+	"golang.org/x/mod/modfile"
+	"golang.org/x/mod/semver"
 )
 
 var cmdTidy = &base.Command{
-	UsageLine: "go mod tidy [-e] [-v]",
+	UsageLine: "go mod tidy [-e] [-v] [-go=version] [-compat=version]",
 	Short:     "add missing and remove unused modules",
 	Long: `
 Tidy makes sure go.mod matches the source code in the module.
@@ -30,19 +34,65 @@
 The -e flag causes tidy to attempt to proceed despite errors
 encountered while loading packages.
 
+The -go flag causes tidy to update the 'go' directive in the go.mod
+file to the given version, which may change which module dependencies
+are retained as explicit requirements in the go.mod file.
+(Go versions 1.17 and higher retain more requirements in order to
+support lazy module loading.)
+
+The -compat flag preserves any additional checksums needed for the
+'go' command from the indicated major Go release to successfully load
+the module graph, and causes tidy to error out if that version of the
+'go' command would load any imported package from a different module
+version. By default, tidy acts as if the -compat flag were set to the
+version prior to the one indicated by the 'go' directive in the go.mod
+file.
+
 See https://golang.org/ref/mod#go-mod-tidy for more about 'go mod tidy'.
 	`,
 	Run: runTidy,
 }
 
-var tidyE bool // if true, report errors but proceed anyway.
+var (
+	tidyE      bool          // if true, report errors but proceed anyway.
+	tidyGo     goVersionFlag // go version to write to the tidied go.mod file (toggles lazy loading)
+	tidyCompat goVersionFlag // go version for which the tidied go.mod and go.sum files should be “compatible”
+)
 
 func init() {
 	cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "")
 	cmdTidy.Flag.BoolVar(&tidyE, "e", false, "")
+	cmdTidy.Flag.Var(&tidyGo, "go", "")
+	cmdTidy.Flag.Var(&tidyCompat, "compat", "")
 	base.AddModCommonFlags(&cmdTidy.Flag)
 }
 
+// A goVersionFlag is a flag.Value representing a supported Go version.
+//
+// (Note that the -go argument to 'go mod edit' is *not* a goVersionFlag.
+// It intentionally allows newer-than-supported versions as arguments.)
+type goVersionFlag struct {
+	v string
+}
+
+func (f *goVersionFlag) String() string   { return f.v }
+func (f *goVersionFlag) Get() interface{} { return f.v }
+
+func (f *goVersionFlag) Set(s string) error {
+	if s != "" {
+		latest := modload.LatestGoVersion()
+		if !modfile.GoVersionRE.MatchString(s) {
+			return fmt.Errorf("expecting a Go version like %q", latest)
+		}
+		if semver.Compare("v"+s, "v"+latest) > 0 {
+			return fmt.Errorf("maximum supported Go version is %s", latest)
+		}
+	}
+
+	f.v = s
+	return nil
+}
+
 func runTidy(ctx context.Context, cmd *base.Command, args []string) {
 	if len(args) > 0 {
 		base.Fatalf("go mod tidy: no arguments allowed")
@@ -62,14 +112,14 @@
 	modload.RootMode = modload.NeedRoot
 
 	modload.LoadPackages(ctx, modload.PackageOpts{
+		GoVersion:                tidyGo.String(),
 		Tags:                     imports.AnyTags(),
+		Tidy:                     true,
+		TidyCompatibleVersion:    tidyCompat.String(),
+		VendorModulesInGOROOTSrc: true,
 		ResolveMissingImports:    true,
 		LoadTests:                true,
 		AllowErrors:              tidyE,
 		SilenceMissingStdImports: true,
 	}, "all")
-
-	modload.TidyBuildList()
-	modload.TrimGoSum()
-	modload.WriteGoMod()
 }
diff --git a/src/cmd/go/internal/modcmd/vendor.go b/src/cmd/go/internal/modcmd/vendor.go
index ac1fb77..713d5f9 100644
--- a/src/cmd/go/internal/modcmd/vendor.go
+++ b/src/cmd/go/internal/modcmd/vendor.go
@@ -13,6 +13,7 @@
 	"io"
 	"io/fs"
 	"os"
+	"path"
 	"path/filepath"
 	"sort"
 	"strings"
@@ -65,6 +66,7 @@
 
 	loadOpts := modload.PackageOpts{
 		Tags:                     imports.AnyTags(),
+		VendorModulesInGOROOTSrc: true,
 		ResolveMissingImports:    true,
 		UseVendorAll:             true,
 		AllowErrors:              vendorE,
@@ -87,15 +89,23 @@
 	}
 
 	includeAllReplacements := false
+	includeGoVersions := false
 	isExplicit := map[module.Version]bool{}
-	if gv := modload.ModFile().Go; gv != nil && semver.Compare("v"+gv.Version, "v1.14") >= 0 {
-		// If the Go version is at least 1.14, annotate all explicit 'require' and
-		// 'replace' targets found in the go.mod file so that we can perform a
-		// stronger consistency check when -mod=vendor is set.
-		for _, r := range modload.ModFile().Require {
-			isExplicit[r.Mod] = true
+	if gv := modload.ModFile().Go; gv != nil {
+		if semver.Compare("v"+gv.Version, "v1.14") >= 0 {
+			// If the Go version is at least 1.14, annotate all explicit 'require' and
+			// 'replace' targets found in the go.mod file so that we can perform a
+			// stronger consistency check when -mod=vendor is set.
+			for _, r := range modload.ModFile().Require {
+				isExplicit[r.Mod] = true
+			}
+			includeAllReplacements = true
 		}
-		includeAllReplacements = true
+		if semver.Compare("v"+gv.Version, "v1.17") >= 0 {
+			// If the Go version is at least 1.17, annotate all modules with their
+			// 'go' version directives.
+			includeGoVersions = true
+		}
 	}
 
 	var vendorMods []module.Version
@@ -109,26 +119,35 @@
 	}
 	module.Sort(vendorMods)
 
-	var buf bytes.Buffer
+	var (
+		buf bytes.Buffer
+		w   io.Writer = &buf
+	)
+	if cfg.BuildV {
+		w = io.MultiWriter(&buf, os.Stderr)
+	}
+
 	for _, m := range vendorMods {
 		line := moduleLine(m, modload.Replacement(m))
-		buf.WriteString(line)
-		if cfg.BuildV {
-			os.Stderr.WriteString(line)
+		io.WriteString(w, line)
+
+		goVersion := ""
+		if includeGoVersions {
+			goVersion = modload.ModuleInfo(ctx, m.Path).GoVersion
 		}
-		if isExplicit[m] {
-			buf.WriteString("## explicit\n")
-			if cfg.BuildV {
-				os.Stderr.WriteString("## explicit\n")
-			}
+		switch {
+		case isExplicit[m] && goVersion != "":
+			fmt.Fprintf(w, "## explicit; go %s\n", goVersion)
+		case isExplicit[m]:
+			io.WriteString(w, "## explicit\n")
+		case goVersion != "":
+			fmt.Fprintf(w, "## go %s\n", goVersion)
 		}
+
 		pkgs := modpkgs[m]
 		sort.Strings(pkgs)
 		for _, pkg := range pkgs {
-			fmt.Fprintf(&buf, "%s\n", pkg)
-			if cfg.BuildV {
-				fmt.Fprintf(os.Stderr, "%s\n", pkg)
-			}
+			fmt.Fprintf(w, "%s\n", pkg)
 			vendorPkg(vdir, pkg)
 		}
 	}
@@ -281,7 +300,7 @@
 		if modPath == pkg {
 			break
 		}
-		pkg = filepath.Dir(pkg)
+		pkg = path.Dir(pkg)
 		dst = filepath.Dir(dst)
 		src = filepath.Dir(src)
 	}
@@ -322,6 +341,15 @@
 	if strings.HasSuffix(info.Name(), "_test.go") {
 		return false
 	}
+	if info.Name() == "go.mod" || info.Name() == "go.sum" {
+		if gv := modload.ModFile().Go; gv != nil && semver.Compare("v"+gv.Version, "v1.17") >= 0 {
+			// As of Go 1.17, we strip go.mod and go.sum files from dependency modules.
+			// Otherwise, 'go' commands invoked within the vendor subtree may misidentify
+			// an arbitrary directory within the vendor tree as a module root.
+			// (See https://golang.org/issue/42970.)
+			return false
+		}
+	}
 	if strings.HasSuffix(info.Name(), ".go") {
 		f, err := fsys.Open(filepath.Join(dir, info.Name()))
 		if err != nil {
diff --git a/src/cmd/go/internal/modcmd/verify.go b/src/cmd/go/internal/modcmd/verify.go
index 8321429..5a6eca3 100644
--- a/src/cmd/go/internal/modcmd/verify.go
+++ b/src/cmd/go/internal/modcmd/verify.go
@@ -54,7 +54,8 @@
 	sem := make(chan token, runtime.GOMAXPROCS(0))
 
 	// Use a slice of result channels, so that the output is deterministic.
-	mods := modload.LoadAllModules(ctx)[1:]
+	const defaultGoVersion = ""
+	mods := modload.LoadModGraph(ctx, defaultGoVersion).BuildList()[1:]
 	errsChans := make([]<-chan []error, len(mods))
 
 	for i, mod := range mods {
diff --git a/src/cmd/go/internal/modcmd/why.go b/src/cmd/go/internal/modcmd/why.go
index a5f3e8a..3b14b27 100644
--- a/src/cmd/go/internal/modcmd/why.go
+++ b/src/cmd/go/internal/modcmd/why.go
@@ -68,22 +68,25 @@
 	modload.RootMode = modload.NeedRoot
 
 	loadOpts := modload.PackageOpts{
-		Tags:          imports.AnyTags(),
-		LoadTests:     !*whyVendor,
-		SilenceErrors: true,
-		UseVendorAll:  *whyVendor,
+		Tags:                     imports.AnyTags(),
+		VendorModulesInGOROOTSrc: true,
+		LoadTests:                !*whyVendor,
+		SilencePackageErrors:     true,
+		UseVendorAll:             *whyVendor,
 	}
 
 	if *whyM {
-		listU := false
-		listVersions := false
-		listRetractions := false
 		for _, arg := range args {
 			if strings.Contains(arg, "@") {
 				base.Fatalf("go mod why: module query not allowed")
 			}
 		}
-		mods := modload.ListModules(ctx, args, listU, listVersions, listRetractions)
+
+		mods, err := modload.ListModules(ctx, args, 0)
+		if err != nil {
+			base.Fatalf("go mod why: %v", err)
+		}
+
 		byModule := make(map[module.Version][]string)
 		_, pkgs := modload.LoadPackages(ctx, loadOpts, "all")
 		for _, path := range pkgs {
diff --git a/src/cmd/go/internal/modconv/convert.go b/src/cmd/go/internal/modconv/convert.go
index 5d4165c..9c861f8 100644
--- a/src/cmd/go/internal/modconv/convert.go
+++ b/src/cmd/go/internal/modconv/convert.go
@@ -12,7 +12,6 @@
 	"strings"
 
 	"cmd/go/internal/base"
-	"cmd/go/internal/modfetch"
 
 	"golang.org/x/mod/modfile"
 	"golang.org/x/mod/module"
@@ -21,7 +20,7 @@
 
 // ConvertLegacyConfig converts legacy config to modfile.
 // The file argument is slash-delimited.
-func ConvertLegacyConfig(f *modfile.File, file string, data []byte) error {
+func ConvertLegacyConfig(f *modfile.File, file string, data []byte, queryPackage func(path, rev string) (module.Version, error)) error {
 	i := strings.LastIndex(file, "/")
 	j := -2
 	if i >= 0 {
@@ -62,15 +61,13 @@
 		sem <- token{}
 		go func(i int, m module.Version) {
 			defer func() { <-sem }()
-			repo, info, err := modfetch.ImportRepoRev(m.Path, m.Version)
+			version, err := queryPackage(m.Path, m.Version)
 			if err != nil {
 				fmt.Fprintf(os.Stderr, "go: converting %s: stat %s@%s: %v\n", base.ShortPath(file), m.Path, m.Version, err)
 				return
 			}
 
-			path := repo.ModulePath()
-			versions[i].Path = path
-			versions[i].Version = info.Version
+			versions[i] = version
 		}(i, m)
 	}
 	// Fill semaphore channel to wait for all tasks to finish.
diff --git a/src/cmd/go/internal/modconv/convert_test.go b/src/cmd/go/internal/modconv/convert_test.go
deleted file mode 100644
index 66b9ff4..0000000
--- a/src/cmd/go/internal/modconv/convert_test.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package modconv
-
-import (
-	"bytes"
-	"context"
-	"fmt"
-	"internal/testenv"
-	"log"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"strings"
-	"testing"
-
-	"cmd/go/internal/cfg"
-	"cmd/go/internal/modfetch"
-
-	"golang.org/x/mod/modfile"
-	"golang.org/x/mod/module"
-)
-
-func TestMain(m *testing.M) {
-	os.Exit(testMain(m))
-}
-
-func testMain(m *testing.M) int {
-	cfg.GOPROXY = "direct"
-
-	if _, err := exec.LookPath("git"); err != nil {
-		fmt.Fprintln(os.Stderr, "skipping because git binary not found")
-		fmt.Println("PASS")
-		return 0
-	}
-
-	dir, err := os.MkdirTemp("", "modconv-test-")
-	if err != nil {
-		log.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
-	cfg.GOMODCACHE = filepath.Join(dir, "pkg/mod")
-
-	return m.Run()
-}
-
-func TestConvertLegacyConfig(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-
-	if testing.Verbose() {
-		old := cfg.BuildX
-		defer func() {
-			cfg.BuildX = old
-		}()
-		cfg.BuildX = true
-	}
-
-	var tests = []struct {
-		path  string
-		vers  string
-		gomod string
-	}{
-		/*
-			Different versions of git seem to find or not find
-			github.com/Masterminds/semver's a93e51b5a57e,
-			which is an unmerged pull request.
-			We'd rather not provide access to unmerged pull requests,
-			so the line is removed from the golden file here,
-			but some git commands still find it somehow.
-
-			{
-				// Gopkg.lock parsing.
-				"github.com/golang/dep", "v0.4.0",
-				`module github.com/golang/dep
-
-				require (
-					github.com/Masterminds/vcs v1.11.1
-					github.com/armon/go-radix v0.0.0-20160115234725-4239b77079c7
-					github.com/boltdb/bolt v1.3.1
-					github.com/go-yaml/yaml v0.0.0-20170407172122-cd8b52f8269e
-					github.com/golang/protobuf v0.0.0-20170901042739-5afd06f9d81a
-					github.com/jmank88/nuts v0.3.0
-					github.com/nightlyone/lockfile v0.0.0-20170707060451-e83dc5e7bba0
-					github.com/pelletier/go-toml v0.0.0-20171218135716-b8b5e7696574
-					github.com/pkg/errors v0.8.0
-					github.com/sdboyer/constext v0.0.0-20170321163424-836a14457353
-					golang.org/x/net v0.0.0-20170828231752-66aacef3dd8a
-					golang.org/x/sync v0.0.0-20170517211232-f52d1811a629
-					golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea
-				)`,
-			},
-		*/
-
-		// TODO: https://github.com/docker/distribution uses vendor.conf
-
-		{
-			// Godeps.json parsing.
-			// TODO: Should v2.0.0 work here too?
-			"github.com/docker/distribution", "v0.0.0-20150410205453-85de3967aa93",
-			`module github.com/docker/distribution
-
-			require (
-				github.com/AdRoll/goamz v0.0.0-20150130162828-d3664b76d905
-				github.com/MSOpenTech/azure-sdk-for-go v0.0.0-20150323223030-d90753bcad2e
-				github.com/Sirupsen/logrus v0.7.3
-				github.com/bugsnag/bugsnag-go v1.0.3-0.20141110184014-b1d153021fcd
-				github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b
-				github.com/bugsnag/panicwrap v0.0.0-20141110184334-e5f9854865b9
-				github.com/codegangsta/cli v1.4.2-0.20150131031259-6086d7927ec3
-				github.com/docker/docker v1.4.2-0.20150204013315-165ea5c158cf
-				github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1
-				github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7
-				github.com/gorilla/context v0.0.0-20140604161150-14f550f51af5
-				github.com/gorilla/handlers v0.0.0-20140825150757-0e84b7d810c1
-				github.com/gorilla/mux v0.0.0-20140926153814-e444e69cbd2e
-				github.com/jlhawn/go-crypto v0.0.0-20150401213827-cd738dde20f0
-				github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43
-				github.com/yvasiyarov/gorelic v0.0.7-0.20141212073537-a9bba5b9ab50
-				github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f
-				golang.org/x/net v0.0.0-20150202051010-1dfe7915deaf
-				gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789
-				gopkg.in/yaml.v2 v2.0.0-20150116202057-bef53efd0c76
-			)`,
-		},
-
-		{
-			// golang.org/issue/24585 - confusion about v2.0.0 tag in legacy non-v2 module
-			"github.com/fishy/gcsbucket", "v0.0.0-20180217031846-618d60fe84e0",
-			`module github.com/fishy/gcsbucket
-
-			require (
-				cloud.google.com/go v0.18.0
-				github.com/fishy/fsdb v0.0.0-20180217030800-5527ded01371
-				github.com/golang/protobuf v1.0.0
-				github.com/googleapis/gax-go v2.0.0+incompatible
-				golang.org/x/net v0.0.0-20180216171745-136a25c244d3
-				golang.org/x/oauth2 v0.0.0-20180207181906-543e37812f10
-				golang.org/x/text v0.3.1-0.20180208041248-4e4a3210bb54
-				google.golang.org/api v0.0.0-20180217000815-c7a403bb5fe1
-				google.golang.org/appengine v1.0.0
-				google.golang.org/genproto v0.0.0-20180206005123-2b5a72b8730b
-				google.golang.org/grpc v1.10.0
-			)`,
-		},
-	}
-
-	ctx := context.Background()
-
-	for _, tt := range tests {
-		t.Run(strings.ReplaceAll(tt.path, "/", "_")+"_"+tt.vers, func(t *testing.T) {
-			f, err := modfile.Parse("golden", []byte(tt.gomod), nil)
-			if err != nil {
-				t.Fatal(err)
-			}
-			want, err := f.Format()
-			if err != nil {
-				t.Fatal(err)
-			}
-
-			dir, err := modfetch.Download(ctx, module.Version{Path: tt.path, Version: tt.vers})
-			if err != nil {
-				t.Fatal(err)
-			}
-
-			for name := range Converters {
-				file := filepath.Join(dir, name)
-				data, err := os.ReadFile(file)
-				if err == nil {
-					f := new(modfile.File)
-					f.AddModuleStmt(tt.path)
-					if err := ConvertLegacyConfig(f, filepath.ToSlash(file), data); err != nil {
-						t.Fatal(err)
-					}
-					out, err := f.Format()
-					if err != nil {
-						t.Fatalf("format after conversion: %v", err)
-					}
-					if !bytes.Equal(out, want) {
-						t.Fatalf("final go.mod:\n%s\n\nwant:\n%s", out, want)
-					}
-					return
-				}
-			}
-			t.Fatalf("no converter found for %s@%s", tt.path, tt.vers)
-		})
-	}
-}
diff --git a/src/cmd/go/internal/modfetch/bootstrap.go b/src/cmd/go/internal/modfetch/bootstrap.go
index e4020b0..ed69458 100644
--- a/src/cmd/go/internal/modfetch/bootstrap.go
+++ b/src/cmd/go/internal/modfetch/bootstrap.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cmd_go_bootstrap
 // +build cmd_go_bootstrap
 
 package modfetch
diff --git a/src/cmd/go/internal/modfetch/cache.go b/src/cmd/go/internal/modfetch/cache.go
index 07e046c..b01b467 100644
--- a/src/cmd/go/internal/modfetch/cache.go
+++ b/src/cmd/go/internal/modfetch/cache.go
@@ -11,8 +11,10 @@
 	"fmt"
 	"io"
 	"io/fs"
+	"math/rand"
 	"os"
 	"path/filepath"
+	"strconv"
 	"strings"
 	"sync"
 
@@ -21,17 +23,15 @@
 	"cmd/go/internal/lockedfile"
 	"cmd/go/internal/modfetch/codehost"
 	"cmd/go/internal/par"
-	"cmd/go/internal/renameio"
+	"cmd/go/internal/robustio"
 
 	"golang.org/x/mod/module"
 	"golang.org/x/mod/semver"
 )
 
 func cacheDir(path string) (string, error) {
-	if cfg.GOMODCACHE == "" {
-		// modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE
-		// is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen.
-		return "", fmt.Errorf("internal error: cfg.GOMODCACHE not set")
+	if err := checkCacheDir(); err != nil {
+		return "", err
 	}
 	enc, err := module.EscapePath(path)
 	if err != nil {
@@ -64,10 +64,8 @@
 // along with the directory if the directory does not exist or if the directory
 // is not completely populated.
 func DownloadDir(m module.Version) (string, error) {
-	if cfg.GOMODCACHE == "" {
-		// modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE
-		// is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen.
-		return "", fmt.Errorf("internal error: cfg.GOMODCACHE not set")
+	if err := checkCacheDir(); err != nil {
+		return "", err
 	}
 	enc, err := module.EscapePath(m.Path)
 	if err != nil {
@@ -108,7 +106,9 @@
 
 	// Check if a .ziphash file exists. It should be created before the
 	// zip is extracted, but if it was deleted (by another program?), we need
-	// to re-calculate it.
+	// to re-calculate it. Note that checkMod will repopulate the ziphash
+	// file if it doesn't exist, but if the module is excluded by checks
+	// through GONOSUMDB or GOPRIVATE, that check and repopulation won't happen.
 	ziphashPath, err := CachePath(m, "ziphash")
 	if err != nil {
 		return dir, err
@@ -146,15 +146,13 @@
 	return lockedfile.MutexAt(path).Lock()
 }
 
-// SideLock locks a file within the module cache that that previously guarded
+// SideLock locks a file within the module cache that previously guarded
 // edits to files outside the cache, such as go.sum and go.mod files in the
 // user's working directory.
 // If err is nil, the caller MUST eventually call the unlock function.
 func SideLock() (unlock func(), err error) {
-	if cfg.GOMODCACHE == "" {
-		// modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE
-		// is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen.
-		base.Fatalf("go: internal error: cfg.GOMODCACHE not set")
+	if err := checkCacheDir(); err != nil {
+		return nil, err
 	}
 
 	path := filepath.Join(cfg.GOMODCACHE, "cache", "lock")
@@ -332,7 +330,7 @@
 	}
 
 	// Stat should have populated the disk cache for us.
-	file, _, err := readDiskStat(path, version)
+	file, err := CachePath(module.Version{Path: path, Version: version}, "info")
 	if err != nil {
 		return "", err
 	}
@@ -349,6 +347,9 @@
 		if _, info, err := readDiskStat(path, rev); err == nil {
 			rev = info.Version
 		} else {
+			if errors.Is(err, statCacheErr) {
+				return nil, err
+			}
 			err := TryProxies(func(proxy string) error {
 				info, err := Lookup(proxy, path).Stat(rev)
 				if err == nil {
@@ -384,7 +385,7 @@
 		return "", err
 	}
 	// GoMod should have populated the disk cache for us.
-	file, _, err := readDiskGoMod(path, version)
+	file, err := CachePath(module.Version{Path: path, Version: version}, "mod")
 	if err != nil {
 		return "", err
 	}
@@ -499,7 +500,7 @@
 	for _, name := range names {
 		if strings.HasSuffix(name, suffix) {
 			v := strings.TrimSuffix(name, ".info")
-			if IsPseudoVersion(v) && semver.Compare(v, maxVersion) > 0 {
+			if module.IsPseudoVersion(v) && semver.Compare(v, maxVersion) > 0 {
 				maxVersion = v
 				file, info, err = readDiskStat(path, strings.TrimSuffix(name, ".info"))
 			}
@@ -547,7 +548,7 @@
 	if err != nil {
 		return "", nil, errNotCached
 	}
-	data, err = renameio.ReadFile(file)
+	data, err = robustio.ReadFile(file)
 	if err != nil {
 		return file, nil, errNotCached
 	}
@@ -584,7 +585,29 @@
 		return err
 	}
 
-	if err := renameio.WriteFile(file, data, 0666); err != nil {
+	// Write the file to a temporary location, and then rename it to its final
+	// path to reduce the likelihood of a corrupt file existing at that final path.
+	f, err := tempFile(filepath.Dir(file), filepath.Base(file), 0666)
+	if err != nil {
+		return err
+	}
+	defer func() {
+		// Only call os.Remove on f.Name() if we failed to rename it: otherwise,
+		// some other process may have created a new file with the same name after
+		// the rename completed.
+		if err != nil {
+			f.Close()
+			os.Remove(f.Name())
+		}
+	}()
+
+	if _, err := f.Write(data); err != nil {
+		return err
+	}
+	if err := f.Close(); err != nil {
+		return err
+	}
+	if err := robustio.Rename(f.Name(), file); err != nil {
 		return err
 	}
 
@@ -594,29 +617,49 @@
 	return nil
 }
 
+// tempFile creates a new temporary file with given permission bits.
+func tempFile(dir, prefix string, perm fs.FileMode) (f *os.File, err error) {
+	for i := 0; i < 10000; i++ {
+		name := filepath.Join(dir, prefix+strconv.Itoa(rand.Intn(1000000000))+".tmp")
+		f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm)
+		if os.IsExist(err) {
+			continue
+		}
+		break
+	}
+	return
+}
+
 // rewriteVersionList rewrites the version list in dir
 // after a new *.mod file has been written.
-func rewriteVersionList(dir string) {
+func rewriteVersionList(dir string) (err error) {
 	if filepath.Base(dir) != "@v" {
 		base.Fatalf("go: internal error: misuse of rewriteVersionList")
 	}
 
 	listFile := filepath.Join(dir, "list")
 
-	// We use a separate lockfile here instead of locking listFile itself because
-	// we want to use Rename to write the file atomically. The list may be read by
-	// a GOPROXY HTTP server, and if we crash midway through a rewrite (or if the
-	// HTTP server ignores our locking and serves the file midway through a
-	// rewrite) it's better to serve a stale list than a truncated one.
-	unlock, err := lockedfile.MutexAt(listFile + ".lock").Lock()
+	// Lock listfile when writing to it to try to avoid corruption to the file.
+	// Under rare circumstances, for instance, if the system loses power in the
+	// middle of a write it is possible for corrupt data to be written. This is
+	// not a problem for the go command itself, but may be an issue if the the
+	// cache is being served by a GOPROXY HTTP server. This will be corrected
+	// the next time a new version of the module is fetched and the file is rewritten.
+	// TODO(matloob): golang.org/issue/43313 covers adding a go mod verify
+	// command that removes module versions that fail checksums. It should also
+	// remove list files that are detected to be corrupt.
+	f, err := lockedfile.Edit(listFile)
 	if err != nil {
-		base.Fatalf("go: can't lock version list lockfile: %v", err)
+		return err
 	}
-	defer unlock()
-
+	defer func() {
+		if cerr := f.Close(); cerr != nil && err == nil {
+			err = cerr
+		}
+	}()
 	infos, err := os.ReadDir(dir)
 	if err != nil {
-		return
+		return err
 	}
 	var list []string
 	for _, info := range infos {
@@ -634,19 +677,74 @@
 			}
 		}
 	}
-	SortVersions(list)
+	semver.Sort(list)
 
 	var buf bytes.Buffer
 	for _, v := range list {
 		buf.WriteString(v)
 		buf.WriteString("\n")
 	}
-	old, _ := renameio.ReadFile(listFile)
-	if bytes.Equal(buf.Bytes(), old) {
-		return
+	if fi, err := f.Stat(); err == nil && int(fi.Size()) == buf.Len() {
+		old := make([]byte, buf.Len()+1)
+		if n, err := f.ReadAt(old, 0); err == io.EOF && n == buf.Len() && bytes.Equal(buf.Bytes(), old) {
+			return nil // No edit needed.
+		}
+	}
+	// Remove existing contents, so that when we truncate to the actual size it will zero-fill,
+	// and we will be able to detect (some) incomplete writes as files containing trailing NUL bytes.
+	if err := f.Truncate(0); err != nil {
+		return err
+	}
+	// Reserve the final size and zero-fill.
+	if err := f.Truncate(int64(buf.Len())); err != nil {
+		return err
+	}
+	// Write the actual contents. If this fails partway through,
+	// the remainder of the file should remain as zeroes.
+	if _, err := f.Write(buf.Bytes()); err != nil {
+		f.Truncate(0)
+		return err
 	}
 
-	if err := renameio.WriteFile(listFile, buf.Bytes(), 0666); err != nil {
-		base.Fatalf("go: failed to write version list: %v", err)
+	return nil
+}
+
+var (
+	statCacheOnce sync.Once
+	statCacheErr  error
+)
+
+// checkCacheDir checks if the directory specified by GOMODCACHE exists. An
+// error is returned if it does not.
+func checkCacheDir() error {
+	if cfg.GOMODCACHE == "" {
+		// modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE
+		// is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen.
+		return fmt.Errorf("internal error: cfg.GOMODCACHE not set")
 	}
+	if !filepath.IsAbs(cfg.GOMODCACHE) {
+		return fmt.Errorf("GOMODCACHE entry is relative; must be absolute path: %q.\n", cfg.GOMODCACHE)
+	}
+
+	// os.Stat is slow on Windows, so we only call it once to prevent unnecessary
+	// I/O every time this function is called.
+	statCacheOnce.Do(func() {
+		fi, err := os.Stat(cfg.GOMODCACHE)
+		if err != nil {
+			if !os.IsNotExist(err) {
+				statCacheErr = fmt.Errorf("could not create module cache: %w", err)
+				return
+			}
+			if err := os.MkdirAll(cfg.GOMODCACHE, 0777); err != nil {
+				statCacheErr = fmt.Errorf("could not create module cache: %w", err)
+				return
+			}
+			return
+		}
+		if !fi.IsDir() {
+			statCacheErr = fmt.Errorf("could not create module cache: %q is not a directory", cfg.GOMODCACHE)
+			return
+		}
+	})
+	return statCacheErr
 }
diff --git a/src/cmd/go/internal/modfetch/codehost/git.go b/src/cmd/go/internal/modfetch/codehost/git.go
index 72005e2..4d4964e 100644
--- a/src/cmd/go/internal/modfetch/codehost/git.go
+++ b/src/cmd/go/internal/modfetch/codehost/git.go
@@ -296,6 +296,9 @@
 	// Or maybe it's the prefix of a hash of a named ref.
 	// Try to resolve to both a ref (git name) and full (40-hex-digit) commit hash.
 	r.refsOnce.Do(r.loadRefs)
+	// loadRefs may return an error if git fails, for example segfaults, or
+	// could not load a private repo, but defer checking to the else block
+	// below, in case we already have the rev in question in the local cache.
 	var ref, hash string
 	if r.refs["refs/tags/"+rev] != "" {
 		ref = "refs/tags/" + rev
@@ -332,6 +335,9 @@
 			hash = rev
 		}
 	} else {
+		if r.refsErr != nil {
+			return nil, r.refsErr
+		}
 		return nil, &UnknownRevisionError{Rev: rev}
 	}
 
diff --git a/src/cmd/go/internal/modfetch/codehost/git_test.go b/src/cmd/go/internal/modfetch/codehost/git_test.go
index 89a73ba..a684fa1 100644
--- a/src/cmd/go/internal/modfetch/codehost/git_test.go
+++ b/src/cmd/go/internal/modfetch/codehost/git_test.go
@@ -8,7 +8,6 @@
 	"archive/zip"
 	"bytes"
 	"flag"
-	"fmt"
 	"internal/testenv"
 	"io"
 	"io/fs"
@@ -47,12 +46,6 @@
 var localGitRepo string
 
 func testMain(m *testing.M) int {
-	if _, err := exec.LookPath("git"); err != nil {
-		fmt.Fprintln(os.Stderr, "skipping because git binary not found")
-		fmt.Println("PASS")
-		return 0
-	}
-
 	dir, err := os.MkdirTemp("", "gitrepo-test-")
 	if err != nil {
 		log.Fatal(err)
@@ -60,23 +53,25 @@
 	defer os.RemoveAll(dir)
 
 	if testenv.HasExternalNetwork() && testenv.HasExec() {
-		// Clone gitrepo1 into a local directory.
-		// If we use a file:// URL to access the local directory,
-		// then git starts up all the usual protocol machinery,
-		// which will let us test remote git archive invocations.
-		localGitRepo = filepath.Join(dir, "gitrepo2")
-		if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
-			log.Fatal(err)
-		}
-		if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
-			log.Fatal(err)
+		if _, err := exec.LookPath("git"); err == nil {
+			// Clone gitrepo1 into a local directory.
+			// If we use a file:// URL to access the local directory,
+			// then git starts up all the usual protocol machinery,
+			// which will let us test remote git archive invocations.
+			localGitRepo = filepath.Join(dir, "gitrepo2")
+			if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
+				log.Fatal(err)
+			}
+			if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
+				log.Fatal(err)
+			}
 		}
 	}
 
 	return m.Run()
 }
 
-func testRepo(remote string) (Repo, error) {
+func testRepo(t *testing.T, remote string) (Repo, error) {
 	if remote == "localGitRepo" {
 		// Convert absolute path to file URL. LocalGitRepo will not accept
 		// Windows absolute paths because they look like a host:path remote.
@@ -87,15 +82,17 @@
 		} else {
 			url = "file:///" + filepath.ToSlash(localGitRepo)
 		}
+		testenv.MustHaveExecPath(t, "git")
 		return LocalGitRepo(url)
 	}
-	kind := "git"
+	vcs := "git"
 	for _, k := range []string{"hg"} {
 		if strings.Contains(remote, "/"+k+"/") {
-			kind = k
+			vcs = k
 		}
 	}
-	return NewRepo(kind, remote)
+	testenv.MustHaveExecPath(t, vcs)
+	return NewRepo(vcs, remote)
 }
 
 var tagsTests = []struct {
@@ -116,7 +113,7 @@
 
 	for _, tt := range tagsTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -168,7 +165,7 @@
 
 	for _, tt := range latestTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -221,7 +218,7 @@
 
 	for _, tt := range readFileTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -412,7 +409,7 @@
 
 	for _, tt := range readZipTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -581,7 +578,7 @@
 
 	for _, tt := range statTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
diff --git a/src/cmd/go/internal/modfetch/codehost/shell.go b/src/cmd/go/internal/modfetch/codehost/shell.go
index ce8b501..0e9f381 100644
--- a/src/cmd/go/internal/modfetch/codehost/shell.go
+++ b/src/cmd/go/internal/modfetch/codehost/shell.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // Interactive debugging shell for codehost.Repo implementations.
diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go
index 2dcbb99..dfef9f7 100644
--- a/src/cmd/go/internal/modfetch/coderepo.go
+++ b/src/cmd/go/internal/modfetch/coderepo.go
@@ -159,7 +159,7 @@
 		if r.codeDir != "" {
 			v = v[len(r.codeDir)+1:]
 		}
-		if v == "" || v != module.CanonicalVersion(v) || IsPseudoVersion(v) {
+		if v == "" || v != module.CanonicalVersion(v) || module.IsPseudoVersion(v) {
 			continue
 		}
 
@@ -172,8 +172,8 @@
 
 		list = append(list, v)
 	}
-	SortVersions(list)
-	SortVersions(incompatible)
+	semver.Sort(list)
+	semver.Sort(incompatible)
 
 	return r.appendIncompatibleVersions(list, incompatible)
 }
@@ -385,7 +385,7 @@
 	if statVers != "" && statVers == module.CanonicalVersion(statVers) {
 		info2.Version = statVers
 
-		if IsPseudoVersion(info2.Version) {
+		if module.IsPseudoVersion(info2.Version) {
 			if err := r.validatePseudoVersion(info, info2.Version); err != nil {
 				return nil, err
 			}
@@ -433,7 +433,7 @@
 		}
 		trimmed := tag[len(tagPrefix):]
 		// Tags that look like pseudo-versions would be confusing. Ignore them.
-		if IsPseudoVersion(tag) {
+		if module.IsPseudoVersion(tag) {
 			return "", false
 		}
 
@@ -531,7 +531,7 @@
 		pseudoBase, _ = tagToVersion(tag) // empty if the tag is invalid
 	}
 
-	info2.Version = PseudoVersion(r.pseudoMajor, pseudoBase, info.Time, info.Short)
+	info2.Version = module.PseudoVersion(r.pseudoMajor, pseudoBase, info.Time, info.Short)
 	return checkGoMod()
 }
 
@@ -560,7 +560,7 @@
 		return err
 	}
 
-	rev, err := PseudoVersionRev(version)
+	rev, err := module.PseudoVersionRev(version)
 	if err != nil {
 		return err
 	}
@@ -575,12 +575,12 @@
 		}
 	}
 
-	t, err := PseudoVersionTime(version)
+	t, err := module.PseudoVersionTime(version)
 	if err != nil {
 		return err
 	}
 	if !t.Equal(info.Time.Truncate(time.Second)) {
-		return fmt.Errorf("does not match version-control timestamp (expected %s)", info.Time.UTC().Format(pseudoVersionTimestampFormat))
+		return fmt.Errorf("does not match version-control timestamp (expected %s)", info.Time.UTC().Format(module.PseudoVersionTimestampFormat))
 	}
 
 	tagPrefix := ""
@@ -604,7 +604,7 @@
 	// not enforce that property when resolving existing pseudo-versions: we don't
 	// know when the parent tags were added, and the highest-tagged parent may not
 	// have existed when the pseudo-version was first resolved.
-	base, err := PseudoVersionBase(strings.TrimSuffix(version, "+incompatible"))
+	base, err := module.PseudoVersionBase(strings.TrimSuffix(version, "+incompatible"))
 	if err != nil {
 		return err
 	}
@@ -661,7 +661,7 @@
 		if err != nil {
 			return err
 		}
-		rev, err := PseudoVersionRev(version)
+		rev, err := module.PseudoVersionRev(version)
 		if err != nil {
 			return fmt.Errorf("not a descendent of preceding tag (%s)", lastTag)
 		}
@@ -672,8 +672,8 @@
 
 func (r *codeRepo) revToRev(rev string) string {
 	if semver.IsValid(rev) {
-		if IsPseudoVersion(rev) {
-			r, _ := PseudoVersionRev(rev)
+		if module.IsPseudoVersion(rev) {
+			r, _ := module.PseudoVersionRev(rev)
 			return r
 		}
 		if semver.Build(rev) == "+incompatible" {
@@ -843,7 +843,7 @@
 		return nil, fmt.Errorf("version %s is not canonical", version)
 	}
 
-	if IsPseudoVersion(version) {
+	if module.IsPseudoVersion(version) {
 		// findDir ignores the metadata encoded in a pseudo-version,
 		// only using the revision at the end.
 		// Invoke Stat to verify the metadata explicitly so we don't return
@@ -864,22 +864,25 @@
 	data, err = r.code.ReadFile(rev, path.Join(dir, "go.mod"), codehost.MaxGoMod)
 	if err != nil {
 		if os.IsNotExist(err) {
-			return r.legacyGoMod(rev, dir), nil
+			return LegacyGoMod(r.modPath), nil
 		}
 		return nil, err
 	}
 	return data, nil
 }
 
-func (r *codeRepo) legacyGoMod(rev, dir string) []byte {
-	// We used to try to build a go.mod reflecting pre-existing
-	// package management metadata files, but the conversion
-	// was inherently imperfect (because those files don't have
-	// exactly the same semantics as go.mod) and, when done
-	// for dependencies in the middle of a build, impossible to
-	// correct. So we stopped.
-	// Return a fake go.mod that simply declares the module path.
-	return []byte(fmt.Sprintf("module %s\n", modfile.AutoQuote(r.modPath)))
+// LegacyGoMod generates a fake go.mod file for a module that doesn't have one.
+// The go.mod file contains a module directive and nothing else: no go version,
+// no requirements.
+//
+// We used to try to build a go.mod reflecting pre-existing
+// package management metadata files, but the conversion
+// was inherently imperfect (because those files don't have
+// exactly the same semantics as go.mod) and, when done
+// for dependencies in the middle of a build, impossible to
+// correct. So we stopped.
+func LegacyGoMod(modPath string) []byte {
+	return []byte(fmt.Sprintf("module %s\n", modfile.AutoQuote(modPath)))
 }
 
 func (r *codeRepo) modPrefix(rev string) string {
@@ -942,7 +945,7 @@
 		return fmt.Errorf("version %s is not canonical", version)
 	}
 
-	if IsPseudoVersion(version) {
+	if module.IsPseudoVersion(version) {
 		// findDir ignores the metadata encoded in a pseudo-version,
 		// only using the revision at the end.
 		// Invoke Stat to verify the metadata explicitly so we don't return
diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go
index eb7d30e..d3d30d9 100644
--- a/src/cmd/go/internal/modfetch/fetch.go
+++ b/src/cmd/go/internal/modfetch/fetch.go
@@ -8,6 +8,8 @@
 	"archive/zip"
 	"bytes"
 	"context"
+	"crypto/sha256"
+	"encoding/base64"
 	"errors"
 	"fmt"
 	"io"
@@ -20,9 +22,9 @@
 
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
+	"cmd/go/internal/fsys"
 	"cmd/go/internal/lockedfile"
 	"cmd/go/internal/par"
-	"cmd/go/internal/renameio"
 	"cmd/go/internal/robustio"
 	"cmd/go/internal/trace"
 
@@ -37,10 +39,8 @@
 // local download cache and returns the name of the directory
 // corresponding to the root of the module's file tree.
 func Download(ctx context.Context, mod module.Version) (dir string, err error) {
-	if cfg.GOMODCACHE == "" {
-		// modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE
-		// is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen.
-		base.Fatalf("go: internal error: cfg.GOMODCACHE not set")
+	if err := checkCacheDir(); err != nil {
+		base.Fatalf("go: %v", err)
 	}
 
 	// The par.Cache here avoids duplicate work.
@@ -223,11 +223,10 @@
 	// Clean up any remaining tempfiles from previous runs.
 	// This is only safe to do because the lock file ensures that their
 	// writers are no longer active.
-	for _, base := range []string{zipfile, zipfile + "hash"} {
-		if old, err := filepath.Glob(renameio.Pattern(base)); err == nil {
-			for _, path := range old {
-				os.Remove(path) // best effort
-			}
+	tmpPattern := filepath.Base(zipfile) + "*.tmp"
+	if old, err := filepath.Glob(filepath.Join(filepath.Dir(zipfile), tmpPattern)); err == nil {
+		for _, path := range old {
+			os.Remove(path) // best effort
 		}
 	}
 
@@ -242,7 +241,7 @@
 	// contents of the file (by hashing it) before we commit it. Because the file
 	// is zip-compressed, we need an actual file — or at least an io.ReaderAt — to
 	// validate it: we can't just tee the stream as we write it.
-	f, err := os.CreateTemp(filepath.Dir(zipfile), filepath.Base(renameio.Pattern(zipfile)))
+	f, err := os.CreateTemp(filepath.Dir(zipfile), tmpPattern)
 	if err != nil {
 		return err
 	}
@@ -298,12 +297,6 @@
 		}
 	}
 
-	// Sync the file before renaming it: otherwise, after a crash the reader may
-	// observe a 0-length file instead of the actual contents.
-	// See https://golang.org/issue/22397#issuecomment-380831736.
-	if err := f.Sync(); err != nil {
-		return err
-	}
 	if err := f.Close(); err != nil {
 		return err
 	}
@@ -334,7 +327,21 @@
 	if err := checkModSum(mod, hash); err != nil {
 		return err
 	}
-	return renameio.WriteFile(ziphashfile, []byte(hash), 0666)
+	hf, err := lockedfile.Create(ziphashfile)
+	if err != nil {
+		return err
+	}
+	if err := hf.Truncate(int64(len(hash))); err != nil {
+		return err
+	}
+	if _, err := hf.WriteAt([]byte(hash), 0); err != nil {
+		return err
+	}
+	if err := hf.Close(); err != nil {
+		return err
+	}
+
+	return nil
 }
 
 // makeDirsReadOnly makes a best-effort attempt to remove write permissions for dir
@@ -410,7 +417,18 @@
 
 	goSum.m = make(map[module.Version][]string)
 	goSum.status = make(map[modSum]modSumStatus)
-	data, err := lockedfile.Read(GoSumFile)
+	var (
+		data []byte
+		err  error
+	)
+	if actualSumFile, ok := fsys.OverlayPath(GoSumFile); ok {
+		// Don't lock go.sum if it's part of the overlay.
+		// On Plan 9, locking requires chmod, and we don't want to modify any file
+		// in the overlay. See #44700.
+		data, err = os.ReadFile(actualSumFile)
+	} else {
+		data, err = lockedfile.Read(GoSumFile)
+	}
 	if err != nil && !os.IsNotExist(err) {
 		return false, err
 	}
@@ -485,11 +503,24 @@
 	if err != nil {
 		base.Fatalf("verifying %v", module.VersionError(mod, err))
 	}
-	data, err := renameio.ReadFile(ziphash)
+	data, err := lockedfile.Read(ziphash)
 	if err != nil {
 		base.Fatalf("verifying %v", module.VersionError(mod, err))
 	}
-	h := strings.TrimSpace(string(data))
+	data = bytes.TrimSpace(data)
+	if !isValidSum(data) {
+		// Recreate ziphash file from zip file and use that to check the mod sum.
+		zip, err := CachePath(mod, "zip")
+		if err != nil {
+			base.Fatalf("verifying %v", module.VersionError(mod, err))
+		}
+		err = hashZip(mod, zip, ziphash)
+		if err != nil {
+			base.Fatalf("verifying %v", module.VersionError(mod, err))
+		}
+		return
+	}
+	h := string(data)
 	if !strings.HasPrefix(h, "h1:") {
 		base.Fatalf("verifying %v", module.VersionError(mod, fmt.Errorf("unexpected ziphash: %q", h)))
 	}
@@ -634,11 +665,32 @@
 	if err != nil {
 		return ""
 	}
-	data, err := renameio.ReadFile(ziphash)
+	data, err := lockedfile.Read(ziphash)
 	if err != nil {
 		return ""
 	}
-	return strings.TrimSpace(string(data))
+	data = bytes.TrimSpace(data)
+	if !isValidSum(data) {
+		return ""
+	}
+	return string(data)
+}
+
+// isValidSum returns true if data is the valid contents of a zip hash file.
+// Certain critical files are written to disk by first truncating
+// then writing the actual bytes, so that if the write fails
+// the corrupt file should contain at least one of the null
+// bytes written by the truncate operation.
+func isValidSum(data []byte) bool {
+	if bytes.IndexByte(data, '\000') >= 0 {
+		return false
+	}
+
+	if len(data) != len("h1:")+base64.StdEncoding.EncodedLen(sha256.Size) {
+		return false
+	}
+
+	return true
 }
 
 // WriteGoSum writes the go.sum file if it needs to be updated.
@@ -676,6 +728,9 @@
 	if cfg.BuildMod == "readonly" {
 		base.Fatalf("go: updates to go.sum needed, disabled by -mod=readonly")
 	}
+	if _, ok := fsys.OverlayPath(GoSumFile); ok {
+		base.Fatalf("go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay")
+	}
 
 	// Make a best-effort attempt to acquire the side lock, only to exclude
 	// previous versions of the 'go' command from making simultaneous edits.
diff --git a/src/cmd/go/internal/modfetch/insecure.go b/src/cmd/go/internal/modfetch/insecure.go
deleted file mode 100644
index 012d05f..0000000
--- a/src/cmd/go/internal/modfetch/insecure.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package modfetch
-
-import (
-	"cmd/go/internal/cfg"
-
-	"golang.org/x/mod/module"
-)
-
-// allowInsecure reports whether we are allowed to fetch this path in an insecure manner.
-func allowInsecure(path string) bool {
-	return cfg.Insecure || module.MatchPrefixPatterns(cfg.GOINSECURE, path)
-}
diff --git a/src/cmd/go/internal/modfetch/proxy.go b/src/cmd/go/internal/modfetch/proxy.go
index 6c86d8d..31d453c 100644
--- a/src/cmd/go/internal/modfetch/proxy.go
+++ b/src/cmd/go/internal/modfetch/proxy.go
@@ -228,7 +228,7 @@
 			Path: p.path,
 			Err: &module.InvalidVersionError{
 				Version: version,
-				Pseudo:  IsPseudoVersion(version),
+				Pseudo:  module.IsPseudoVersion(version),
 				Err:     err,
 			},
 		}
@@ -276,11 +276,11 @@
 	var list []string
 	for _, line := range strings.Split(string(data), "\n") {
 		f := strings.Fields(line)
-		if len(f) >= 1 && semver.IsValid(f[0]) && strings.HasPrefix(f[0], prefix) && !IsPseudoVersion(f[0]) {
+		if len(f) >= 1 && semver.IsValid(f[0]) && strings.HasPrefix(f[0], prefix) && !module.IsPseudoVersion(f[0]) {
 			list = append(list, f[0])
 		}
 	}
-	SortVersions(list)
+	semver.Sort(list)
 	return list, nil
 }
 
@@ -307,8 +307,8 @@
 			)
 			if len(f) >= 2 {
 				ft, _ = time.Parse(time.RFC3339, f[1])
-			} else if IsPseudoVersion(f[0]) {
-				ft, _ = PseudoVersionTime(f[0])
+			} else if module.IsPseudoVersion(f[0]) {
+				ft, _ = module.PseudoVersionTime(f[0])
 				ftIsFromPseudo = true
 			} else {
 				// Repo.Latest promises that this method is only called where there are
diff --git a/src/cmd/go/internal/modfetch/pseudo.go b/src/cmd/go/internal/modfetch/pseudo.go
deleted file mode 100644
index 93eb0fa..0000000
--- a/src/cmd/go/internal/modfetch/pseudo.go
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Pseudo-versions
-//
-// Code authors are expected to tag the revisions they want users to use,
-// including prereleases. However, not all authors tag versions at all,
-// and not all commits a user might want to try will have tags.
-// A pseudo-version is a version with a special form that allows us to
-// address an untagged commit and order that version with respect to
-// other versions we might encounter.
-//
-// A pseudo-version takes one of the general forms:
-//
-//	(1) vX.0.0-yyyymmddhhmmss-abcdef123456
-//	(2) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456
-//	(3) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible
-//	(4) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456
-//	(5) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible
-//
-// If there is no recently tagged version with the right major version vX,
-// then form (1) is used, creating a space of pseudo-versions at the bottom
-// of the vX version range, less than any tagged version, including the unlikely v0.0.0.
-//
-// If the most recent tagged version before the target commit is vX.Y.Z or vX.Y.Z+incompatible,
-// then the pseudo-version uses form (2) or (3), making it a prerelease for the next
-// possible semantic version after vX.Y.Z. The leading 0 segment in the prerelease string
-// ensures that the pseudo-version compares less than possible future explicit prereleases
-// like vX.Y.(Z+1)-rc1 or vX.Y.(Z+1)-1.
-//
-// If the most recent tagged version before the target commit is vX.Y.Z-pre or vX.Y.Z-pre+incompatible,
-// then the pseudo-version uses form (4) or (5), making it a slightly later prerelease.
-
-package modfetch
-
-import (
-	"errors"
-	"fmt"
-	"strings"
-	"time"
-
-	"internal/lazyregexp"
-
-	"golang.org/x/mod/module"
-	"golang.org/x/mod/semver"
-)
-
-var pseudoVersionRE = lazyregexp.New(`^v[0-9]+\.(0\.0-|\d+\.\d+-([^+]*\.)?0\.)\d{14}-[A-Za-z0-9]+(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$`)
-
-const pseudoVersionTimestampFormat = "20060102150405"
-
-// PseudoVersion returns a pseudo-version for the given major version ("v1")
-// preexisting older tagged version ("" or "v1.2.3" or "v1.2.3-pre"), revision time,
-// and revision identifier (usually a 12-byte commit hash prefix).
-func PseudoVersion(major, older string, t time.Time, rev string) string {
-	if major == "" {
-		major = "v0"
-	}
-	segment := fmt.Sprintf("%s-%s", t.UTC().Format(pseudoVersionTimestampFormat), rev)
-	build := semver.Build(older)
-	older = semver.Canonical(older)
-	if older == "" {
-		return major + ".0.0-" + segment // form (1)
-	}
-	if semver.Prerelease(older) != "" {
-		return older + ".0." + segment + build // form (4), (5)
-	}
-
-	// Form (2), (3).
-	// Extract patch from vMAJOR.MINOR.PATCH
-	i := strings.LastIndex(older, ".") + 1
-	v, patch := older[:i], older[i:]
-
-	// Reassemble.
-	return v + incDecimal(patch) + "-0." + segment + build
-}
-
-// ZeroPseudoVersion returns a pseudo-version with a zero timestamp and
-// revision, which may be used as a placeholder.
-func ZeroPseudoVersion(major string) string {
-	return PseudoVersion(major, "", time.Time{}, "000000000000")
-}
-
-// incDecimal returns the decimal string incremented by 1.
-func incDecimal(decimal string) string {
-	// Scan right to left turning 9s to 0s until you find a digit to increment.
-	digits := []byte(decimal)
-	i := len(digits) - 1
-	for ; i >= 0 && digits[i] == '9'; i-- {
-		digits[i] = '0'
-	}
-	if i >= 0 {
-		digits[i]++
-	} else {
-		// digits is all zeros
-		digits[0] = '1'
-		digits = append(digits, '0')
-	}
-	return string(digits)
-}
-
-// decDecimal returns the decimal string decremented by 1, or the empty string
-// if the decimal is all zeroes.
-func decDecimal(decimal string) string {
-	// Scan right to left turning 0s to 9s until you find a digit to decrement.
-	digits := []byte(decimal)
-	i := len(digits) - 1
-	for ; i >= 0 && digits[i] == '0'; i-- {
-		digits[i] = '9'
-	}
-	if i < 0 {
-		// decimal is all zeros
-		return ""
-	}
-	if i == 0 && digits[i] == '1' && len(digits) > 1 {
-		digits = digits[1:]
-	} else {
-		digits[i]--
-	}
-	return string(digits)
-}
-
-// IsPseudoVersion reports whether v is a pseudo-version.
-func IsPseudoVersion(v string) bool {
-	return strings.Count(v, "-") >= 2 && semver.IsValid(v) && pseudoVersionRE.MatchString(v)
-}
-
-// IsZeroPseudoVersion returns whether v is a pseudo-version with a zero base,
-// timestamp, and revision, as returned by ZeroPseudoVersion.
-func IsZeroPseudoVersion(v string) bool {
-	return v == ZeroPseudoVersion(semver.Major(v))
-}
-
-// PseudoVersionTime returns the time stamp of the pseudo-version v.
-// It returns an error if v is not a pseudo-version or if the time stamp
-// embedded in the pseudo-version is not a valid time.
-func PseudoVersionTime(v string) (time.Time, error) {
-	_, timestamp, _, _, err := parsePseudoVersion(v)
-	if err != nil {
-		return time.Time{}, err
-	}
-	t, err := time.Parse("20060102150405", timestamp)
-	if err != nil {
-		return time.Time{}, &module.InvalidVersionError{
-			Version: v,
-			Pseudo:  true,
-			Err:     fmt.Errorf("malformed time %q", timestamp),
-		}
-	}
-	return t, nil
-}
-
-// PseudoVersionRev returns the revision identifier of the pseudo-version v.
-// It returns an error if v is not a pseudo-version.
-func PseudoVersionRev(v string) (rev string, err error) {
-	_, _, rev, _, err = parsePseudoVersion(v)
-	return
-}
-
-// PseudoVersionBase returns the canonical parent version, if any, upon which
-// the pseudo-version v is based.
-//
-// If v has no parent version (that is, if it is "vX.0.0-[…]"),
-// PseudoVersionBase returns the empty string and a nil error.
-func PseudoVersionBase(v string) (string, error) {
-	base, _, _, build, err := parsePseudoVersion(v)
-	if err != nil {
-		return "", err
-	}
-
-	switch pre := semver.Prerelease(base); pre {
-	case "":
-		// vX.0.0-yyyymmddhhmmss-abcdef123456 → ""
-		if build != "" {
-			// Pseudo-versions of the form vX.0.0-yyyymmddhhmmss-abcdef123456+incompatible
-			// are nonsensical: the "vX.0.0-" prefix implies that there is no parent tag,
-			// but the "+incompatible" suffix implies that the major version of
-			// the parent tag is not compatible with the module's import path.
-			//
-			// There are a few such entries in the index generated by proxy.golang.org,
-			// but we believe those entries were generated by the proxy itself.
-			return "", &module.InvalidVersionError{
-				Version: v,
-				Pseudo:  true,
-				Err:     fmt.Errorf("lacks base version, but has build metadata %q", build),
-			}
-		}
-		return "", nil
-
-	case "-0":
-		// vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z
-		// vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z+incompatible
-		base = strings.TrimSuffix(base, pre)
-		i := strings.LastIndexByte(base, '.')
-		if i < 0 {
-			panic("base from parsePseudoVersion missing patch number: " + base)
-		}
-		patch := decDecimal(base[i+1:])
-		if patch == "" {
-			// vX.0.0-0 is invalid, but has been observed in the wild in the index
-			// generated by requests to proxy.golang.org.
-			//
-			// NOTE(bcmills): I cannot find a historical bug that accounts for
-			// pseudo-versions of this form, nor have I seen such versions in any
-			// actual go.mod files. If we find actual examples of this form and a
-			// reasonable theory of how they came into existence, it seems fine to
-			// treat them as equivalent to vX.0.0 (especially since the invalid
-			// pseudo-versions have lower precedence than the real ones). For now, we
-			// reject them.
-			return "", &module.InvalidVersionError{
-				Version: v,
-				Pseudo:  true,
-				Err:     fmt.Errorf("version before %s would have negative patch number", base),
-			}
-		}
-		return base[:i+1] + patch + build, nil
-
-	default:
-		// vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z-pre
-		// vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z-pre+incompatible
-		if !strings.HasSuffix(base, ".0") {
-			panic(`base from parsePseudoVersion missing ".0" before date: ` + base)
-		}
-		return strings.TrimSuffix(base, ".0") + build, nil
-	}
-}
-
-var errPseudoSyntax = errors.New("syntax error")
-
-func parsePseudoVersion(v string) (base, timestamp, rev, build string, err error) {
-	if !IsPseudoVersion(v) {
-		return "", "", "", "", &module.InvalidVersionError{
-			Version: v,
-			Pseudo:  true,
-			Err:     errPseudoSyntax,
-		}
-	}
-	build = semver.Build(v)
-	v = strings.TrimSuffix(v, build)
-	j := strings.LastIndex(v, "-")
-	v, rev = v[:j], v[j+1:]
-	i := strings.LastIndex(v, "-")
-	if j := strings.LastIndex(v, "."); j > i {
-		base = v[:j] // "vX.Y.Z-pre.0" or "vX.Y.(Z+1)-0"
-		timestamp = v[j+1:]
-	} else {
-		base = v[:i] // "vX.0.0"
-		timestamp = v[i+1:]
-	}
-	return base, timestamp, rev, build, nil
-}
diff --git a/src/cmd/go/internal/modfetch/pseudo_test.go b/src/cmd/go/internal/modfetch/pseudo_test.go
deleted file mode 100644
index 4483f8e..0000000
--- a/src/cmd/go/internal/modfetch/pseudo_test.go
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package modfetch
-
-import (
-	"testing"
-	"time"
-)
-
-var pseudoTests = []struct {
-	major   string
-	older   string
-	version string
-}{
-	{"", "", "v0.0.0-20060102150405-hash"},
-	{"v0", "", "v0.0.0-20060102150405-hash"},
-	{"v1", "", "v1.0.0-20060102150405-hash"},
-	{"v2", "", "v2.0.0-20060102150405-hash"},
-	{"unused", "v0.0.0", "v0.0.1-0.20060102150405-hash"},
-	{"unused", "v1.2.3", "v1.2.4-0.20060102150405-hash"},
-	{"unused", "v1.2.99999999999999999", "v1.2.100000000000000000-0.20060102150405-hash"},
-	{"unused", "v1.2.3-pre", "v1.2.3-pre.0.20060102150405-hash"},
-	{"unused", "v1.3.0-pre", "v1.3.0-pre.0.20060102150405-hash"},
-	{"unused", "v0.0.0--", "v0.0.0--.0.20060102150405-hash"},
-	{"unused", "v1.0.0+metadata", "v1.0.1-0.20060102150405-hash+metadata"},
-	{"unused", "v2.0.0+incompatible", "v2.0.1-0.20060102150405-hash+incompatible"},
-	{"unused", "v2.3.0-pre+incompatible", "v2.3.0-pre.0.20060102150405-hash+incompatible"},
-}
-
-var pseudoTime = time.Date(2006, 1, 2, 15, 4, 5, 0, time.UTC)
-
-func TestPseudoVersion(t *testing.T) {
-	for _, tt := range pseudoTests {
-		v := PseudoVersion(tt.major, tt.older, pseudoTime, "hash")
-		if v != tt.version {
-			t.Errorf("PseudoVersion(%q, %q, ...) = %v, want %v", tt.major, tt.older, v, tt.version)
-		}
-	}
-}
-
-func TestIsPseudoVersion(t *testing.T) {
-	for _, tt := range pseudoTests {
-		if !IsPseudoVersion(tt.version) {
-			t.Errorf("IsPseudoVersion(%q) = false, want true", tt.version)
-		}
-		if IsPseudoVersion(tt.older) {
-			t.Errorf("IsPseudoVersion(%q) = true, want false", tt.older)
-		}
-	}
-}
-
-func TestPseudoVersionTime(t *testing.T) {
-	for _, tt := range pseudoTests {
-		tm, err := PseudoVersionTime(tt.version)
-		if tm != pseudoTime || err != nil {
-			t.Errorf("PseudoVersionTime(%q) = %v, %v, want %v, nil", tt.version, tm.Format(time.RFC3339), err, pseudoTime.Format(time.RFC3339))
-		}
-		tm, err = PseudoVersionTime(tt.older)
-		if tm != (time.Time{}) || err == nil {
-			t.Errorf("PseudoVersionTime(%q) = %v, %v, want %v, error", tt.older, tm.Format(time.RFC3339), err, time.Time{}.Format(time.RFC3339))
-		}
-	}
-}
-
-func TestInvalidPseudoVersionTime(t *testing.T) {
-	const v = "---"
-	if _, err := PseudoVersionTime(v); err == nil {
-		t.Error("expected error, got nil instead")
-	}
-}
-
-func TestPseudoVersionRev(t *testing.T) {
-	for _, tt := range pseudoTests {
-		rev, err := PseudoVersionRev(tt.version)
-		if rev != "hash" || err != nil {
-			t.Errorf("PseudoVersionRev(%q) = %q, %v, want %q, nil", tt.older, rev, err, "hash")
-		}
-		rev, err = PseudoVersionRev(tt.older)
-		if rev != "" || err == nil {
-			t.Errorf("PseudoVersionRev(%q) = %q, %v, want %q, error", tt.older, rev, err, "")
-		}
-	}
-}
-
-func TestPseudoVersionBase(t *testing.T) {
-	for _, tt := range pseudoTests {
-		base, err := PseudoVersionBase(tt.version)
-		if err != nil {
-			t.Errorf("PseudoVersionBase(%q): %v", tt.version, err)
-		} else if base != tt.older {
-			t.Errorf("PseudoVersionBase(%q) = %q; want %q", tt.version, base, tt.older)
-		}
-	}
-}
-
-func TestInvalidPseudoVersionBase(t *testing.T) {
-	for _, in := range []string{
-		"v0.0.0",
-		"v0.0.0-",                                 // malformed: empty prerelease
-		"v0.0.0-0.20060102150405-hash",            // Z+1 == 0
-		"v0.1.0-0.20060102150405-hash",            // Z+1 == 0
-		"v1.0.0-0.20060102150405-hash",            // Z+1 == 0
-		"v0.0.0-20060102150405-hash+incompatible", // "+incompatible without base version
-		"v0.0.0-20060102150405-hash+metadata",     // other metadata without base version
-	} {
-		base, err := PseudoVersionBase(in)
-		if err == nil || base != "" {
-			t.Errorf(`PseudoVersionBase(%q) = %q, %v; want "", error`, in, base, err)
-		}
-	}
-}
-
-func TestIncDecimal(t *testing.T) {
-	cases := []struct {
-		in, want string
-	}{
-		{"0", "1"},
-		{"1", "2"},
-		{"99", "100"},
-		{"100", "101"},
-		{"101", "102"},
-	}
-
-	for _, tc := range cases {
-		got := incDecimal(tc.in)
-		if got != tc.want {
-			t.Fatalf("incDecimal(%q) = %q; want %q", tc.in, tc.want, got)
-		}
-	}
-}
-
-func TestDecDecimal(t *testing.T) {
-	cases := []struct {
-		in, want string
-	}{
-		{"", ""},
-		{"0", ""},
-		{"00", ""},
-		{"1", "0"},
-		{"2", "1"},
-		{"99", "98"},
-		{"100", "99"},
-		{"101", "100"},
-	}
-
-	for _, tc := range cases {
-		got := decDecimal(tc.in)
-		if got != tc.want {
-			t.Fatalf("decDecimal(%q) = %q; want %q", tc.in, tc.want, got)
-		}
-	}
-}
diff --git a/src/cmd/go/internal/modfetch/repo.go b/src/cmd/go/internal/modfetch/repo.go
index af9e24c..0bffa55 100644
--- a/src/cmd/go/internal/modfetch/repo.go
+++ b/src/cmd/go/internal/modfetch/repo.go
@@ -9,7 +9,6 @@
 	"io"
 	"io/fs"
 	"os"
-	"sort"
 	"strconv"
 	"time"
 
@@ -20,7 +19,6 @@
 	web "cmd/go/internal/web"
 
 	"golang.org/x/mod/module"
-	"golang.org/x/mod/semver"
 )
 
 const traceRepo = false // trace all repo actions, for debugging
@@ -35,7 +33,7 @@
 	// Pseudo-versions are not included.
 	//
 	// Versions should be returned sorted in semver order
-	// (implementations can use SortVersions).
+	// (implementations can use semver.Sort).
 	//
 	// Versions returns a non-nil error only if there was a problem
 	// fetching the list of versions: it may return an empty list
@@ -171,15 +169,6 @@
 // and it can check that the path can be resolved to a target repository.
 // To avoid version control access except when absolutely necessary,
 // Lookup does not attempt to connect to the repository itself.
-//
-// The ImportRepoRev function is a variant of Import which is limited
-// to code in a source code repository at a particular revision identifier
-// (usually a commit hash or source code repository tag, not necessarily
-// a module version).
-// ImportRepoRev is used when converting legacy dependency requirements
-// from older systems into go.mod files. Those older systems worked
-// at either package or repository granularity, and most of the time they
-// recorded commit hashes, not tagged versions.
 
 var lookupCache par.Cache
 
@@ -194,7 +183,8 @@
 // from its origin, and "noproxy" indicates that the patch should be fetched
 // directly only if GONOPROXY matches the given path.
 //
-// For the distinguished proxy "off", Lookup always returns a non-nil error.
+// For the distinguished proxy "off", Lookup always returns a Repo that returns
+// a non-nil error for every method call.
 //
 // A successful return does not guarantee that the module
 // has any defined versions.
@@ -267,7 +257,7 @@
 func lookupDirect(path string) (Repo, error) {
 	security := web.SecureOnly
 
-	if allowInsecure(path) {
+	if module.MatchPrefixPatterns(cfg.GOINSECURE, path) {
 		security = web.Insecure
 	}
 	rr, err := vcs.RepoRootForImportPath(path, vcs.PreferMod, security)
@@ -299,63 +289,6 @@
 	return code, nil
 }
 
-// ImportRepoRev returns the module and version to use to access
-// the given import path loaded from the source code repository that
-// the original "go get" would have used, at the specific repository revision
-// (typically a commit hash, but possibly also a source control tag).
-func ImportRepoRev(path, rev string) (Repo, *RevInfo, error) {
-	if cfg.BuildMod == "vendor" || cfg.BuildMod == "readonly" {
-		return nil, nil, fmt.Errorf("repo version lookup disabled by -mod=%s", cfg.BuildMod)
-	}
-
-	// Note: Because we are converting a code reference from a legacy
-	// version control system, we ignore meta tags about modules
-	// and use only direct source control entries (get.IgnoreMod).
-	security := web.SecureOnly
-	if allowInsecure(path) {
-		security = web.Insecure
-	}
-	rr, err := vcs.RepoRootForImportPath(path, vcs.IgnoreMod, security)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	code, err := lookupCodeRepo(rr)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	revInfo, err := code.Stat(rev)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// TODO: Look in repo to find path, check for go.mod files.
-	// For now we're just assuming rr.Root is the module path,
-	// which is true in the absence of go.mod files.
-
-	repo, err := newCodeRepo(code, rr.Root, rr.Root)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	info, err := repo.(*codeRepo).convert(revInfo, rev)
-	if err != nil {
-		return nil, nil, err
-	}
-	return repo, info, nil
-}
-
-func SortVersions(list []string) {
-	sort.Slice(list, func(i, j int) bool {
-		cmp := semver.Compare(list[i], list[j])
-		if cmp != 0 {
-			return cmp < 0
-		}
-		return list[i] < list[j]
-	})
-}
-
 // A loggingRepo is a wrapper around an underlying Repo
 // that prints a log message at the start and end of each call.
 // It can be inserted when debugging.
diff --git a/src/cmd/go/internal/modfetch/sumdb.go b/src/cmd/go/internal/modfetch/sumdb.go
index 4fbc54d..f233cba 100644
--- a/src/cmd/go/internal/modfetch/sumdb.go
+++ b/src/cmd/go/internal/modfetch/sumdb.go
@@ -4,6 +4,7 @@
 
 // Go checksum database lookup
 
+//go:build !cmd_go_bootstrap
 // +build !cmd_go_bootstrap
 
 package modfetch
@@ -33,7 +34,7 @@
 
 // useSumDB reports whether to use the Go checksum database for the given module.
 func useSumDB(mod module.Version) bool {
-	return cfg.GOSUMDB != "off" && !cfg.Insecure && !module.MatchPrefixPatterns(cfg.GONOSUMDB, mod.Path)
+	return cfg.GOSUMDB != "off" && !module.MatchPrefixPatterns(cfg.GONOSUMDB, mod.Path)
 }
 
 // lookupSumDB returns the Go checksum database's go.sum lines for the given module,
@@ -184,7 +185,7 @@
 		}
 	})
 	if errors.Is(err, fs.ErrNotExist) {
-		// No proxies, or all proxies failed (with 404, 410, or were were allowed
+		// No proxies, or all proxies failed (with 404, 410, or were allowed
 		// to fall back), or we reached an explicit "direct" or "off".
 		c.base = c.direct
 	} else if err != nil {
diff --git a/src/cmd/go/internal/modget/get.go b/src/cmd/go/internal/modget/get.go
index 5a98408..9672e55 100644
--- a/src/cmd/go/internal/modget/get.go
+++ b/src/cmd/go/internal/modget/get.go
@@ -30,16 +30,15 @@
 	"fmt"
 	"os"
 	"path/filepath"
-	"reflect"
 	"runtime"
 	"sort"
 	"strings"
 	"sync"
 
 	"cmd/go/internal/base"
-	"cmd/go/internal/cfg"
 	"cmd/go/internal/imports"
 	"cmd/go/internal/load"
+	"cmd/go/internal/modfetch"
 	"cmd/go/internal/modload"
 	"cmd/go/internal/par"
 	"cmd/go/internal/search"
@@ -53,7 +52,7 @@
 var CmdGet = &base.Command{
 	// Note: -d -u are listed explicitly because they are the most common get flags.
 	// Do not send CLs removing them because they're covered by [get flags].
-	UsageLine: "go get [-d] [-t] [-u] [-v] [-insecure] [build flags] [packages]",
+	UsageLine: "go get [-d] [-t] [-u] [-v] [build flags] [packages]",
 	Short:     "add dependencies to current module and install them",
 	Long: `
 Get resolves its command-line arguments to packages at specific module versions,
@@ -99,14 +98,6 @@
 When the -t and -u flags are used together, get will update
 test dependencies as well.
 
-The -insecure flag permits fetching from repositories and resolving
-custom domains using insecure schemes such as HTTP, and also bypassess
-module sum validation using the checksum database. Use with caution.
-This flag is deprecated and will be removed in a future version of go.
-To permit the use of insecure schemes, use the GOINSECURE environment
-variable instead. To bypass module sum validation, use GOPRIVATE or
-GONOSUMDB. See 'go help environment' for details.
-
 The -d flag instructs get not to build or install packages. get will only
 update go.mod and download source code needed to build packages.
 
@@ -227,13 +218,13 @@
 }
 
 var (
-	getD   = CmdGet.Flag.Bool("d", false, "")
-	getF   = CmdGet.Flag.Bool("f", false, "")
-	getFix = CmdGet.Flag.Bool("fix", false, "")
-	getM   = CmdGet.Flag.Bool("m", false, "")
-	getT   = CmdGet.Flag.Bool("t", false, "")
-	getU   upgradeFlag
-	// -insecure is cfg.Insecure
+	getD        = CmdGet.Flag.Bool("d", false, "")
+	getF        = CmdGet.Flag.Bool("f", false, "")
+	getFix      = CmdGet.Flag.Bool("fix", false, "")
+	getM        = CmdGet.Flag.Bool("m", false, "")
+	getT        = CmdGet.Flag.Bool("t", false, "")
+	getU        upgradeFlag
+	getInsecure = CmdGet.Flag.Bool("insecure", false, "")
 	// -v is cfg.BuildV
 )
 
@@ -264,7 +255,6 @@
 func init() {
 	work.AddBuildFlags(CmdGet, work.OmitModFlag)
 	CmdGet.Run = runGet // break init loop
-	CmdGet.Flag.BoolVar(&cfg.Insecure, "insecure", cfg.Insecure, "")
 	CmdGet.Flag.Var(&getU, "u", "")
 }
 
@@ -284,10 +274,9 @@
 	if *getM {
 		base.Fatalf("go get: -m flag is no longer supported; consider -d to skip building packages")
 	}
-	if cfg.Insecure {
-		fmt.Fprintf(os.Stderr, "go get: -insecure flag is deprecated; see 'go help get' for details\n")
+	if *getInsecure {
+		base.Fatalf("go get: -insecure flag is no longer supported; use GOINSECURE instead")
 	}
-	load.ModResolveTests = *getT
 
 	// Do not allow any updating of go.mod until we've applied
 	// all the requested changes and checked that the result matches
@@ -298,8 +287,6 @@
 	// 'go get' is expected to do this, unlike other commands.
 	modload.AllowMissingModuleImports()
 
-	modload.LoadModFile(ctx) // Initializes modload.Target.
-
 	queries := parseArgs(ctx, args)
 
 	r := newResolver(ctx, queries)
@@ -310,7 +297,7 @@
 		r.performWildcardQueries(ctx)
 		r.performPatternAllQueries(ctx)
 
-		if changed := r.resolveCandidates(ctx, queries, nil); changed {
+		if changed := r.resolveQueries(ctx, queries); changed {
 			// 'go get' arguments can be (and often are) package patterns rather than
 			// (just) modules. A package can be provided by any module with a prefix
 			// of its import path, and a wildcard can even match packages in modules
@@ -347,12 +334,12 @@
 		// - ambiguous import errors.
 		//   TODO(#27899): Try to resolve ambiguous import errors automatically.
 		upgrades := r.findAndUpgradeImports(ctx, queries)
-		if changed := r.resolveCandidates(ctx, nil, upgrades); changed {
+		if changed := r.applyUpgrades(ctx, upgrades); changed {
 			continue
 		}
 
 		r.findMissingWildcards(ctx)
-		if changed := r.resolveCandidates(ctx, r.wildcardQueries, nil); changed {
+		if changed := r.resolveQueries(ctx, r.wildcardQueries); changed {
 			continue
 		}
 
@@ -367,7 +354,7 @@
 			pkgPatterns = append(pkgPatterns, q.pattern)
 		}
 	}
-	r.checkPackagesAndRetractions(ctx, pkgPatterns)
+	r.checkPackageProblems(ctx, pkgPatterns)
 
 	// We've already downloaded modules (and identified direct and indirect
 	// dependencies) by loading packages in findAndUpgradeImports.
@@ -380,12 +367,51 @@
 	// directory.
 	if !*getD && len(pkgPatterns) > 0 {
 		work.BuildInit()
-		pkgs := load.PackagesAndErrors(ctx, pkgPatterns)
+
+		pkgOpts := load.PackageOpts{ModResolveTests: *getT}
+		var pkgs []*load.Package
+		for _, pkg := range load.PackagesAndErrors(ctx, pkgOpts, pkgPatterns) {
+			if pkg.Error != nil {
+				var noGo *load.NoGoError
+				if errors.As(pkg.Error.Err, &noGo) {
+					if m := modload.PackageModule(pkg.ImportPath); m.Path == pkg.ImportPath {
+						// pkg is at the root of a module, and doesn't exist with the current
+						// build tags. Probably the user just wanted to change the version of
+						// that module — not also build the package — so suppress the error.
+						// (See https://golang.org/issue/33526.)
+						continue
+					}
+				}
+			}
+			pkgs = append(pkgs, pkg)
+		}
 		load.CheckPackageErrors(pkgs)
+
+		haveExternalExe := false
+		for _, pkg := range pkgs {
+			if pkg.Name == "main" && pkg.Module != nil && pkg.Module.Path != modload.Target.Path {
+				haveExternalExe = true
+				break
+			}
+		}
+		if haveExternalExe {
+			fmt.Fprint(os.Stderr, "go get: installing executables with 'go get' in module mode is deprecated.")
+			var altMsg string
+			if modload.HasModRoot() {
+				altMsg = `
+	To adjust and download dependencies of the current module, use 'go get -d'.
+	To install using requirements of the current module, use 'go install'.
+	To install ignoring the current module, use 'go install' with a version,
+	like 'go install example.com/cmd@latest'.
+`
+			} else {
+				altMsg = "\n\tUse 'go install pkg@version' instead.\n"
+			}
+			fmt.Fprint(os.Stderr, altMsg)
+			fmt.Fprintf(os.Stderr, "\tFor more information, see https://golang.org/doc/go-get-install-deprecation\n\tor run 'go help get' or 'go help install'.\n")
+		}
+
 		work.InstallPackages(ctx, pkgPatterns, pkgs)
-		// TODO(#40276): After Go 1.16, print a deprecation notice when building and
-		// installing main packages. 'go install pkg' or 'go install pkg@version'
-		// should be used instead. Give the specific argument to use if possible.
 	}
 
 	if !modload.HasModRoot() {
@@ -396,7 +422,7 @@
 	oldReqs := reqsFromGoMod(modload.ModFile())
 
 	modload.AllowWriteGoMod()
-	modload.WriteGoMod()
+	modload.WriteGoMod(ctx)
 	modload.DisallowWriteGoMod()
 
 	newReqs := reqsFromGoMod(modload.ModFile())
@@ -460,9 +486,8 @@
 	// that resolved the module to that version (the “reason”).
 	resolvedVersion map[string]versionReason
 
-	buildList                 []module.Version
-	buildListResolvedVersions int               // len(resolvedVersion) when buildList was computed
-	buildListVersion          map[string]string // index of buildList (module path → version)
+	buildList        []module.Version
+	buildListVersion map[string]string // index of buildList (module path → version)
 
 	initialVersion map[string]string // index of the initial build list at the start of 'go get'
 
@@ -479,7 +504,12 @@
 }
 
 func newResolver(ctx context.Context, queries []*query) *resolver {
-	buildList := modload.LoadAllModules(ctx)
+	// LoadModGraph also sets modload.Target, which is needed by various resolver
+	// methods.
+	const defaultGoVersion = ""
+	mg := modload.LoadModGraph(ctx, defaultGoVersion)
+
+	buildList := mg.BuildList()
 	initialVersion := make(map[string]string, len(buildList))
 	for _, m := range buildList {
 		initialVersion[m.Path] = m.Version
@@ -688,7 +718,7 @@
 
 			// Absolute paths like C:\foo and relative paths like ../foo... are
 			// restricted to matching packages in the main module.
-			pkgPattern := modload.DirImportPath(q.pattern)
+			pkgPattern := modload.DirImportPath(ctx, q.pattern)
 			if pkgPattern == "." {
 				return errSet(fmt.Errorf("%s%s is not within module rooted at %s", q.pattern, absDetail, modload.ModRoot()))
 			}
@@ -1121,9 +1151,11 @@
 // build list.
 func (r *resolver) loadPackages(ctx context.Context, patterns []string, findPackage func(ctx context.Context, path string, m module.Version) (versionOk bool)) {
 	opts := modload.PackageOpts{
-		Tags:          imports.AnyTags(),
-		LoadTests:     *getT,
-		SilenceErrors: true, // May be fixed by subsequent upgrades or downgrades.
+		Tags:                     imports.AnyTags(),
+		VendorModulesInGOROOTSrc: true,
+		LoadTests:                *getT,
+		AssumeRootsImported:      true, // After 'go get foo', imports of foo should build.
+		SilencePackageErrors:     true, // May be fixed by subsequent upgrades or downgrades.
 	}
 
 	opts.AllowPackage = func(ctx context.Context, path string, m module.Version) error {
@@ -1176,24 +1208,19 @@
 // to be updated before its dependencies can be loaded.
 var errVersionChange = errors.New("version change needed")
 
-// resolveCandidates resolves candidates sets that are attached to the given
+// resolveQueries resolves candidate sets that are attached to the given
 // queries and/or needed to provide the given missing-package dependencies.
 //
-// resolveCandidates starts by resolving one module version from each
+// resolveQueries starts by resolving one module version from each
 // unambiguous pathSet attached to the given queries.
 //
 // If no unambiguous query results in a change to the build list,
-// resolveCandidates modifies the build list by adding one module version from
-// each pathSet in missing, but does not mark those versions as resolved
-// (so they can still be modified by other queries).
-//
-// If that still does not result in any changes to the build list,
-// resolveCandidates revisits the ambiguous query candidates and resolves them
+// resolveQueries revisits the ambiguous query candidates and resolves them
 // arbitrarily in order to guarantee forward progress.
 //
 // If all pathSets are resolved without any changes to the build list,
-// resolveCandidates returns with changed=false.
-func (r *resolver) resolveCandidates(ctx context.Context, queries []*query, upgrades []pathSet) (changed bool) {
+// resolveQueries returns with changed=false.
+func (r *resolver) resolveQueries(ctx context.Context, queries []*query) (changed bool) {
 	defer base.ExitIfErrors()
 
 	// Note: this is O(N²) with the number of pathSets in the worst case.
@@ -1247,13 +1274,53 @@
 		}
 	}
 
-	if changed := r.updateBuildList(ctx, nil); changed {
-		// The build list has changed, so disregard any missing packages: they might
-		// now be determined by requirements in the build list, which we would
-		// prefer to use instead of arbitrary "latest" versions.
-		return true
+	if resolved > 0 {
+		if changed = r.updateBuildList(ctx, nil); changed {
+			// The build list has changed, so disregard any remaining ambiguous queries:
+			// they might now be determined by requirements in the build list, which we
+			// would prefer to use instead of arbitrary versions.
+			return true
+		}
 	}
 
+	// The build list will be the same on the next iteration as it was on this
+	// iteration, so any ambiguous queries will remain so. In order to make
+	// progress, resolve them arbitrarily but deterministically.
+	//
+	// If that results in conflicting versions, the user can re-run 'go get'
+	// with additional explicit versions for the conflicting packages or
+	// modules.
+	resolvedArbitrarily := 0
+	for _, q := range queries {
+		for _, cs := range q.candidates {
+			isPackage, m := r.chooseArbitrarily(cs)
+			if isPackage {
+				q.matchesPackages = true
+			}
+			r.resolve(q, m)
+			resolvedArbitrarily++
+		}
+	}
+	if resolvedArbitrarily > 0 {
+		changed = r.updateBuildList(ctx, nil)
+	}
+	return changed
+}
+
+// applyUpgrades disambiguates candidate sets that are needed to upgrade (or
+// provide) transitive dependencies imported by previously-resolved packages.
+//
+// applyUpgrades modifies the build list by adding one module version from each
+// pathSet in upgrades, then downgrading (or further upgrading) those modules as
+// needed to maintain any already-resolved versions of other modules.
+// applyUpgrades does not mark the new versions as resolved, so they can still
+// be further modified by other queries (such as wildcards).
+//
+// If all pathSets are resolved without any changes to the build list,
+// applyUpgrades returns with changed=false.
+func (r *resolver) applyUpgrades(ctx context.Context, upgrades []pathSet) (changed bool) {
+	defer base.ExitIfErrors()
+
 	// Arbitrarily add a "latest" version that provides each missing package, but
 	// do not mark the version as resolved: we still want to allow the explicit
 	// queries to modify the resulting versions.
@@ -1276,27 +1343,9 @@
 		tentative = append(tentative, m)
 	}
 	base.ExitIfErrors()
-	if changed := r.updateBuildList(ctx, tentative); changed {
-		return true
-	}
 
-	// The build list will be the same on the next iteration as it was on this
-	// iteration, so any ambiguous queries will remain so. In order to make
-	// progress, resolve them arbitrarily but deterministically.
-	//
-	// If that results in conflicting versions, the user can re-run 'go get'
-	// with additional explicit versions for the conflicting packages or
-	// modules.
-	for _, q := range queries {
-		for _, cs := range q.candidates {
-			isPackage, m := r.chooseArbitrarily(cs)
-			if isPackage {
-				q.matchesPackages = true
-			}
-			r.resolve(q, m)
-		}
-	}
-	return r.updateBuildList(ctx, nil)
+	changed = r.updateBuildList(ctx, tentative)
+	return changed
 }
 
 // disambiguate eliminates candidates from cs that conflict with other module
@@ -1417,25 +1466,33 @@
 	return false, cs.mod
 }
 
-// checkPackagesAndRetractions reloads packages for the given patterns and
-// reports missing and ambiguous package errors. It also reports loads and
-// reports retractions for resolved modules and modules needed to build
-// named packages.
+// checkPackageProblems reloads packages for the given patterns and reports
+// missing and ambiguous package errors. It also reports retractions and
+// deprecations for resolved modules and modules needed to build named packages.
+// It also adds a sum for each updated module in the build list if we had one
+// before and didn't get one while loading packages.
 //
 // We skip missing-package errors earlier in the process, since we want to
 // resolve pathSets ourselves, but at that point, we don't have enough context
 // to log the package-import chains leading to each error.
-func (r *resolver) checkPackagesAndRetractions(ctx context.Context, pkgPatterns []string) {
+func (r *resolver) checkPackageProblems(ctx context.Context, pkgPatterns []string) {
 	defer base.ExitIfErrors()
 
-	// Build a list of modules to load retractions for. Start with versions
-	// selected based on command line queries.
-	//
-	// This is a subset of the build list. If the main module has a lot of
-	// dependencies, loading retractions for the entire build list would be slow.
-	relevantMods := make(map[module.Version]struct{})
+	// Gather information about modules we might want to load retractions and
+	// deprecations for. Loading this metadata requires at least one version
+	// lookup per module, and we don't want to load information that's neither
+	// relevant nor actionable.
+	type modFlags int
+	const (
+		resolved modFlags = 1 << iota // version resolved by 'go get'
+		named                         // explicitly named on command line or provides a named package
+		hasPkg                        // needed to build named packages
+		direct                        // provides a direct dependency of the main module
+	)
+	relevantMods := make(map[module.Version]modFlags)
 	for path, reason := range r.resolvedVersion {
-		relevantMods[module.Version{Path: path, Version: reason.version}] = struct{}{}
+		m := module.Version{Path: path, Version: reason.version}
+		relevantMods[m] |= resolved
 	}
 
 	// Reload packages, reporting errors for missing and ambiguous imports.
@@ -1443,9 +1500,11 @@
 		// LoadPackages will print errors (since it has more context) but will not
 		// exit, since we need to load retractions later.
 		pkgOpts := modload.PackageOpts{
-			LoadTests:             *getT,
-			ResolveMissingImports: false,
-			AllowErrors:           true,
+			VendorModulesInGOROOTSrc: true,
+			LoadTests:                *getT,
+			ResolveMissingImports:    false,
+			AllowErrors:              true,
+			SilenceNoGoErrors:        true,
 		}
 		matches, pkgs := modload.LoadPackages(ctx, pkgOpts, pkgPatterns...)
 		for _, m := range matches {
@@ -1461,53 +1520,141 @@
 					// associated with either the package or its test — ErrNoGo must
 					// indicate that none of those source files happen to apply in this
 					// configuration. If we are actually building the package (no -d
-					// flag), the compiler will report the problem; otherwise, assume that
-					// the user is going to build or test it in some other configuration
-					// and suppress the error.
+					// flag), we will report the problem then; otherwise, assume that the
+					// user is going to build or test this package in some other
+					// configuration and suppress the error.
 					continue
 				}
 
 				base.SetExitStatus(1)
 				if ambiguousErr := (*modload.AmbiguousImportError)(nil); errors.As(err, &ambiguousErr) {
 					for _, m := range ambiguousErr.Modules {
-						relevantMods[m] = struct{}{}
+						relevantMods[m] |= hasPkg
 					}
 				}
 			}
 			if m := modload.PackageModule(pkg); m.Path != "" {
-				relevantMods[m] = struct{}{}
+				relevantMods[m] |= hasPkg
+			}
+		}
+		for _, match := range matches {
+			for _, pkg := range match.Pkgs {
+				m := modload.PackageModule(pkg)
+				relevantMods[m] |= named
 			}
 		}
 	}
 
-	// Load and report retractions.
-	type retraction struct {
-		m   module.Version
-		err error
-	}
-	retractions := make([]retraction, 0, len(relevantMods))
+	reqs := modload.LoadModFile(ctx)
 	for m := range relevantMods {
-		retractions = append(retractions, retraction{m: m})
+		if reqs.IsDirect(m.Path) {
+			relevantMods[m] |= direct
+		}
 	}
-	sort.Slice(retractions, func(i, j int) bool {
-		return retractions[i].m.Path < retractions[j].m.Path
-	})
-	for i := 0; i < len(retractions); i++ {
+
+	// Load retractions for modules mentioned on the command line and modules
+	// needed to build named packages. We care about retractions of indirect
+	// dependencies, since we might be able to upgrade away from them.
+	type modMessage struct {
+		m       module.Version
+		message string
+	}
+	retractions := make([]modMessage, 0, len(relevantMods))
+	for m, flags := range relevantMods {
+		if flags&(resolved|named|hasPkg) != 0 {
+			retractions = append(retractions, modMessage{m: m})
+		}
+	}
+	sort.Slice(retractions, func(i, j int) bool { return retractions[i].m.Path < retractions[j].m.Path })
+	for i := range retractions {
 		i := i
 		r.work.Add(func() {
 			err := modload.CheckRetractions(ctx, retractions[i].m)
 			if retractErr := (*modload.ModuleRetractedError)(nil); errors.As(err, &retractErr) {
-				retractions[i].err = err
+				retractions[i].message = err.Error()
 			}
 		})
 	}
+
+	// Load deprecations for modules mentioned on the command line. Only load
+	// deprecations for indirect dependencies if they're also direct dependencies
+	// of the main module. Deprecations of purely indirect dependencies are
+	// not actionable.
+	deprecations := make([]modMessage, 0, len(relevantMods))
+	for m, flags := range relevantMods {
+		if flags&(resolved|named) != 0 || flags&(hasPkg|direct) == hasPkg|direct {
+			deprecations = append(deprecations, modMessage{m: m})
+		}
+	}
+	sort.Slice(deprecations, func(i, j int) bool { return deprecations[i].m.Path < deprecations[j].m.Path })
+	for i := range deprecations {
+		i := i
+		r.work.Add(func() {
+			deprecation, err := modload.CheckDeprecation(ctx, deprecations[i].m)
+			if err != nil || deprecation == "" {
+				return
+			}
+			deprecations[i].message = modload.ShortMessage(deprecation, "")
+		})
+	}
+
+	// Load sums for updated modules that had sums before. When we update a
+	// module, we may update another module in the build list that provides a
+	// package in 'all' that wasn't loaded as part of this 'go get' command.
+	// If we don't add a sum for that module, builds may fail later.
+	// Note that an incidentally updated package could still import packages
+	// from unknown modules or from modules in the build list that we didn't
+	// need previously. We can't handle that case without loading 'all'.
+	sumErrs := make([]error, len(r.buildList))
+	for i := range r.buildList {
+		i := i
+		m := r.buildList[i]
+		mActual := m
+		if mRepl := modload.Replacement(m); mRepl.Path != "" {
+			mActual = mRepl
+		}
+		old := module.Version{Path: m.Path, Version: r.initialVersion[m.Path]}
+		if old.Version == "" {
+			continue
+		}
+		oldActual := old
+		if oldRepl := modload.Replacement(old); oldRepl.Path != "" {
+			oldActual = oldRepl
+		}
+		if mActual == oldActual || mActual.Version == "" || !modfetch.HaveSum(oldActual) {
+			continue
+		}
+		r.work.Add(func() {
+			if _, err := modfetch.DownloadZip(ctx, mActual); err != nil {
+				verb := "upgraded"
+				if semver.Compare(m.Version, old.Version) < 0 {
+					verb = "downgraded"
+				}
+				replaced := ""
+				if mActual != m {
+					replaced = fmt.Sprintf(" (replaced by %s)", mActual)
+				}
+				err = fmt.Errorf("%s %s %s => %s%s: error finding sum for %s: %v", verb, m.Path, old.Version, m.Version, replaced, mActual, err)
+				sumErrs[i] = err
+			}
+		})
+	}
+
 	<-r.work.Idle()
+
+	// Report deprecations, then retractions, then errors fetching sums.
+	// Only errors fetching sums are hard errors.
+	for _, mm := range deprecations {
+		if mm.message != "" {
+			fmt.Fprintf(os.Stderr, "go: module %s is deprecated: %s\n", mm.m.Path, mm.message)
+		}
+	}
 	var retractPath string
-	for _, r := range retractions {
-		if r.err != nil {
-			fmt.Fprintf(os.Stderr, "go: warning: %v\n", r.err)
+	for _, mm := range retractions {
+		if mm.message != "" {
+			fmt.Fprintf(os.Stderr, "go: warning: %v\n", mm.message)
 			if retractPath == "" {
-				retractPath = r.m.Path
+				retractPath = mm.m.Path
 			} else {
 				retractPath = "<module>"
 			}
@@ -1516,6 +1663,12 @@
 	if retractPath != "" {
 		fmt.Fprintf(os.Stderr, "go: to switch to the latest unretracted version, run:\n\tgo get %s@latest\n", retractPath)
 	}
+	for _, err := range sumErrs {
+		if err != nil {
+			base.Errorf("go: %v", err)
+		}
+	}
+	base.ExitIfErrors()
 }
 
 // reportChanges logs version changes to os.Stderr.
@@ -1614,11 +1767,10 @@
 //
 // If the additional modules conflict with the resolved versions, they will be
 // downgraded to a non-conflicting version (possibly "none").
+//
+// If the resulting build list is the same as the one resulting from the last
+// call to updateBuildList, updateBuildList returns with changed=false.
 func (r *resolver) updateBuildList(ctx context.Context, additions []module.Version) (changed bool) {
-	if len(additions) == 0 && len(r.resolvedVersion) == r.buildListResolvedVersions {
-		return false
-	}
-
 	defer base.ExitIfErrors()
 
 	resolved := make([]module.Version, 0, len(r.resolvedVersion))
@@ -1628,7 +1780,8 @@
 		}
 	}
 
-	if err := modload.EditBuildList(ctx, additions, resolved); err != nil {
+	changed, err := modload.EditBuildList(ctx, additions, resolved)
+	if err != nil {
 		var constraint *modload.ConstraintError
 		if !errors.As(err, &constraint) {
 			base.Errorf("go get: %v", err)
@@ -1647,13 +1800,12 @@
 		}
 		return false
 	}
-
-	buildList := modload.LoadAllModules(ctx)
-	r.buildListResolvedVersions = len(r.resolvedVersion)
-	if reflect.DeepEqual(r.buildList, buildList) {
+	if !changed {
 		return false
 	}
-	r.buildList = buildList
+
+	const defaultGoVersion = ""
+	r.buildList = modload.LoadModGraph(ctx, defaultGoVersion).BuildList()
 	r.buildListVersion = make(map[string]string, len(r.buildList))
 	for _, m := range r.buildList {
 		r.buildListVersion[m.Path] = m.Version
diff --git a/src/cmd/go/internal/modinfo/info.go b/src/cmd/go/internal/modinfo/info.go
index 897be56..1908835 100644
--- a/src/cmd/go/internal/modinfo/info.go
+++ b/src/cmd/go/internal/modinfo/info.go
@@ -10,19 +10,20 @@
 // and the fields are documented in the help text in ../list/list.go
 
 type ModulePublic struct {
-	Path      string        `json:",omitempty"` // module path
-	Version   string        `json:",omitempty"` // module version
-	Versions  []string      `json:",omitempty"` // available module versions
-	Replace   *ModulePublic `json:",omitempty"` // replaced by this module
-	Time      *time.Time    `json:",omitempty"` // time version was created
-	Update    *ModulePublic `json:",omitempty"` // available update (with -u)
-	Main      bool          `json:",omitempty"` // is this the main module?
-	Indirect  bool          `json:",omitempty"` // module is only indirectly needed by main module
-	Dir       string        `json:",omitempty"` // directory holding local copy of files, if any
-	GoMod     string        `json:",omitempty"` // path to go.mod file describing module, if any
-	GoVersion string        `json:",omitempty"` // go version used in module
-	Retracted []string      `json:",omitempty"` // retraction information, if any (with -retracted or -u)
-	Error     *ModuleError  `json:",omitempty"` // error loading module
+	Path       string        `json:",omitempty"` // module path
+	Version    string        `json:",omitempty"` // module version
+	Versions   []string      `json:",omitempty"` // available module versions
+	Replace    *ModulePublic `json:",omitempty"` // replaced by this module
+	Time       *time.Time    `json:",omitempty"` // time version was created
+	Update     *ModulePublic `json:",omitempty"` // available update (with -u)
+	Main       bool          `json:",omitempty"` // is this the main module?
+	Indirect   bool          `json:",omitempty"` // module is only indirectly needed by main module
+	Dir        string        `json:",omitempty"` // directory holding local copy of files, if any
+	GoMod      string        `json:",omitempty"` // path to go.mod file describing module, if any
+	GoVersion  string        `json:",omitempty"` // go version used in module
+	Retracted  []string      `json:",omitempty"` // retraction information, if any (with -retracted or -u)
+	Deprecated string        `json:",omitempty"` // deprecation message, if any (with -u)
+	Error      *ModuleError  `json:",omitempty"` // error loading module
 }
 
 type ModuleError struct {
@@ -45,6 +46,9 @@
 			s += " [" + versionString(m.Update) + "]"
 		}
 	}
+	if m.Deprecated != "" {
+		s += " (deprecated)"
+	}
 	if m.Replace != nil {
 		s += " => " + m.Replace.Path
 		if m.Replace.Version != "" {
@@ -53,6 +57,9 @@
 				s += " [" + versionString(m.Replace.Update) + "]"
 			}
 		}
+		if m.Replace.Deprecated != "" {
+			s += " (deprecated)"
+		}
 	}
 	return s
 }
diff --git a/src/cmd/go/internal/modload/build.go b/src/cmd/go/internal/modload/build.go
index 8ad5f83..76e1ad5 100644
--- a/src/cmd/go/internal/modload/build.go
+++ b/src/cmd/go/internal/modload/build.go
@@ -11,6 +11,7 @@
 	"errors"
 	"fmt"
 	"internal/goroot"
+	"io/fs"
 	"os"
 	"path/filepath"
 	"strings"
@@ -50,17 +51,17 @@
 // a given package. If modules are not enabled or if the package is in the
 // standard library or if the package was not successfully loaded with
 // LoadPackages or ImportFromFiles, nil is returned.
-func PackageModuleInfo(pkgpath string) *modinfo.ModulePublic {
+func PackageModuleInfo(ctx context.Context, pkgpath string) *modinfo.ModulePublic {
 	if isStandardImportPath(pkgpath) || !Enabled() {
 		return nil
 	}
-	m, ok := findModule(pkgpath)
+	m, ok := findModule(loaded, pkgpath)
 	if !ok {
 		return nil
 	}
-	fromBuildList := true
-	listRetracted := false
-	return moduleInfo(context.TODO(), m, fromBuildList, listRetracted)
+
+	rs := LoadModFile(ctx)
+	return moduleInfo(ctx, rs, m, 0)
 }
 
 func ModuleInfo(ctx context.Context, path string) *modinfo.ModulePublic {
@@ -68,26 +69,38 @@
 		return nil
 	}
 
-	listRetracted := false
 	if i := strings.Index(path, "@"); i >= 0 {
 		m := module.Version{Path: path[:i], Version: path[i+1:]}
-		fromBuildList := false
-		return moduleInfo(ctx, m, fromBuildList, listRetracted)
+		return moduleInfo(ctx, nil, m, 0)
 	}
 
-	for _, m := range buildList {
-		if m.Path == path {
-			fromBuildList := true
-			return moduleInfo(ctx, m, fromBuildList, listRetracted)
+	rs := LoadModFile(ctx)
+
+	var (
+		v  string
+		ok bool
+	)
+	if rs.depth == lazy {
+		v, ok = rs.rootSelected(path)
+	}
+	if !ok {
+		mg, err := rs.Graph(ctx)
+		if err != nil {
+			base.Fatalf("go: %v", err)
+		}
+		v = mg.Selected(path)
+	}
+
+	if v == "none" {
+		return &modinfo.ModulePublic{
+			Path: path,
+			Error: &modinfo.ModuleError{
+				Err: "module not in current build",
+			},
 		}
 	}
 
-	return &modinfo.ModulePublic{
-		Path: path,
-		Error: &modinfo.ModuleError{
-			Err: "module not in current build",
-		},
-	}
+	return moduleInfo(ctx, rs, module.Version{Path: path, Version: v}, 0)
 }
 
 // addUpdate fills in m.Update if an updated version is available.
@@ -96,7 +109,26 @@
 		return
 	}
 
-	if info, err := Query(ctx, m.Path, "upgrade", m.Version, CheckAllowed); err == nil && semver.Compare(info.Version, m.Version) > 0 {
+	info, err := Query(ctx, m.Path, "upgrade", m.Version, CheckAllowed)
+	var noVersionErr *NoMatchingVersionError
+	if errors.Is(err, fs.ErrNotExist) || errors.As(err, &noVersionErr) {
+		// Ignore "not found" and "no matching version" errors.
+		// This means the proxy has no matching version or no versions at all.
+		//
+		// We should report other errors though. An attacker that controls the
+		// network shouldn't be able to hide versions by interfering with
+		// the HTTPS connection. An attacker that controls the proxy may still
+		// hide versions, since the "list" and "latest" endpoints are not
+		// authenticated.
+		return
+	} else if err != nil {
+		if m.Error == nil {
+			m.Error = &modinfo.ModuleError{Err: err.Error()}
+		}
+		return
+	}
+
+	if semver.Compare(info.Version, m.Version) > 0 {
 		m.Update = &modinfo.ModulePublic{
 			Path:    m.Path,
 			Version: info.Version,
@@ -113,7 +145,11 @@
 	if listRetracted {
 		allowed = CheckExclusions
 	}
-	m.Versions, _ = versions(ctx, m.Path, allowed)
+	var err error
+	m.Versions, err = versions(ctx, m.Path, allowed)
+	if err != nil && m.Error == nil {
+		m.Error = &modinfo.ModuleError{Err: err.Error()}
+	}
 }
 
 // addRetraction fills in m.Retracted if the module was retracted by its author.
@@ -124,31 +160,72 @@
 	}
 
 	err := CheckRetractions(ctx, module.Version{Path: m.Path, Version: m.Version})
-	var rerr *ModuleRetractedError
-	if errors.As(err, &rerr) {
-		if len(rerr.Rationale) == 0 {
+	var noVersionErr *NoMatchingVersionError
+	var retractErr *ModuleRetractedError
+	if err == nil || errors.Is(err, fs.ErrNotExist) || errors.As(err, &noVersionErr) {
+		// Ignore "not found" and "no matching version" errors.
+		// This means the proxy has no matching version or no versions at all.
+		//
+		// We should report other errors though. An attacker that controls the
+		// network shouldn't be able to hide versions by interfering with
+		// the HTTPS connection. An attacker that controls the proxy may still
+		// hide versions, since the "list" and "latest" endpoints are not
+		// authenticated.
+		return
+	} else if errors.As(err, &retractErr) {
+		if len(retractErr.Rationale) == 0 {
 			m.Retracted = []string{"retracted by module author"}
 		} else {
-			m.Retracted = rerr.Rationale
+			m.Retracted = retractErr.Rationale
 		}
-	} else if err != nil && m.Error == nil {
+	} else if m.Error == nil {
 		m.Error = &modinfo.ModuleError{Err: err.Error()}
 	}
 }
 
-func moduleInfo(ctx context.Context, m module.Version, fromBuildList, listRetracted bool) *modinfo.ModulePublic {
+// addDeprecation fills in m.Deprecated if the module was deprecated by its
+// author. m.Error is set if there's an error loading deprecation information.
+func addDeprecation(ctx context.Context, m *modinfo.ModulePublic) {
+	deprecation, err := CheckDeprecation(ctx, module.Version{Path: m.Path, Version: m.Version})
+	var noVersionErr *NoMatchingVersionError
+	if errors.Is(err, fs.ErrNotExist) || errors.As(err, &noVersionErr) {
+		// Ignore "not found" and "no matching version" errors.
+		// This means the proxy has no matching version or no versions at all.
+		//
+		// We should report other errors though. An attacker that controls the
+		// network shouldn't be able to hide versions by interfering with
+		// the HTTPS connection. An attacker that controls the proxy may still
+		// hide versions, since the "list" and "latest" endpoints are not
+		// authenticated.
+		return
+	}
+	if err != nil {
+		if m.Error == nil {
+			m.Error = &modinfo.ModuleError{Err: err.Error()}
+		}
+		return
+	}
+	m.Deprecated = deprecation
+}
+
+// moduleInfo returns information about module m, loaded from the requirements
+// in rs (which may be nil to indicate that m was not loaded from a requirement
+// graph).
+func moduleInfo(ctx context.Context, rs *Requirements, m module.Version, mode ListMode) *modinfo.ModulePublic {
 	if m == Target {
 		info := &modinfo.ModulePublic{
 			Path:    m.Path,
 			Version: m.Version,
 			Main:    true,
 		}
+		if v, ok := rawGoVersion.Load(Target); ok {
+			info.GoVersion = v.(string)
+		} else {
+			panic("internal error: GoVersion not set for main module")
+		}
 		if HasModRoot() {
 			info.Dir = ModRoot()
 			info.GoMod = ModFilePath()
-			if modFile.Go != nil {
-				info.GoVersion = modFile.Go.Version
-			}
 		}
 		return info
 	}
@@ -156,7 +233,7 @@
 	info := &modinfo.ModulePublic{
 		Path:     m.Path,
 		Version:  m.Version,
-		Indirect: fromBuildList && loaded != nil && !loaded.direct[m.Path],
+		Indirect: rs != nil && !rs.direct[m.Path],
 	}
 	if v, ok := rawGoVersion.Load(m); ok {
 		info.GoVersion = v.(string)
@@ -164,7 +241,10 @@
 
 	// completeFromModCache fills in the extra fields in m using the module cache.
 	completeFromModCache := func(m *modinfo.ModulePublic) {
-		mod := module.Version{Path: m.Path, Version: m.Version}
+		checksumOk := func(suffix string) bool {
+			return rs == nil || m.Version == "" || cfg.BuildMod == "mod" ||
+				modfetch.HaveSum(module.Version{Path: m.Path, Version: m.Version + suffix})
+		}
 
 		if m.Version != "" {
 			if q, err := Query(ctx, m.Path, m.Version, "", nil); err != nil {
@@ -173,31 +253,40 @@
 				m.Version = q.Version
 				m.Time = &q.Time
 			}
+		}
+		mod := module.Version{Path: m.Path, Version: m.Version}
 
-			gomod, err := modfetch.CachePath(mod, "mod")
-			if err == nil {
-				if info, err := os.Stat(gomod); err == nil && info.Mode().IsRegular() {
-					m.GoMod = gomod
-				}
-			}
-			dir, err := modfetch.DownloadDir(mod)
-			if err == nil {
-				m.Dir = dir
-			}
-
-			if listRetracted {
-				addRetraction(ctx, m)
+		if m.GoVersion == "" && checksumOk("/go.mod") {
+			// Load the go.mod file to determine the Go version, since it hasn't
+			// already been populated from rawGoVersion.
+			if summary, err := rawGoModSummary(mod); err == nil && summary.goVersion != "" {
+				m.GoVersion = summary.goVersion
 			}
 		}
 
-		if m.GoVersion == "" {
-			if summary, err := rawGoModSummary(mod); err == nil && summary.goVersionV != "" {
-				m.GoVersion = summary.goVersionV[1:]
+		if m.Version != "" {
+			if checksumOk("/go.mod") {
+				gomod, err := modfetch.CachePath(mod, "mod")
+				if err == nil {
+					if info, err := os.Stat(gomod); err == nil && info.Mode().IsRegular() {
+						m.GoMod = gomod
+					}
+				}
+			}
+			if checksumOk("") {
+				dir, err := modfetch.DownloadDir(mod)
+				if err == nil {
+					m.Dir = dir
+				}
+			}
+
+			if mode&ListRetracted != 0 {
+				addRetraction(ctx, m)
 			}
 		}
 	}
 
-	if !fromBuildList {
+	if rs == nil {
 		// If this was an explicitly-versioned argument to 'go mod download' or
 		// 'go list -m', report the actual requested version, not its replacement.
 		completeFromModCache(info) // Will set m.Error in vendor mode.
@@ -255,11 +344,11 @@
 		return ""
 	}
 
-	target := mustFindModule(path, path)
+	target := mustFindModule(loaded, path, path)
 	mdeps := make(map[module.Version]bool)
 	for _, dep := range deps {
 		if !isStandardImportPath(dep) {
-			mdeps[mustFindModule(path, dep)] = true
+			mdeps[mustFindModule(loaded, path, dep)] = true
 		}
 	}
 	var mods []module.Version
@@ -298,8 +387,8 @@
 //
 // TODO(jayconrod): remove this. Callers should use findModule and return
 // errors instead of relying on base.Fatalf.
-func mustFindModule(target, path string) module.Version {
-	pkg, ok := loaded.pkgCache.Get(path).(*loadPkg)
+func mustFindModule(ld *loader, target, path string) module.Version {
+	pkg, ok := ld.pkgCache.Get(path).(*loadPkg)
 	if ok {
 		if pkg.err != nil {
 			base.Fatalf("build %v: cannot load %v: %v", target, path, pkg.err)
@@ -318,8 +407,8 @@
 // findModule searches for the module that contains the package at path.
 // If the package was loaded, its containing module and true are returned.
 // Otherwise, module.Version{} and false are returend.
-func findModule(path string) (module.Version, bool) {
-	if pkg, ok := loaded.pkgCache.Get(path).(*loadPkg); ok {
+func findModule(ld *loader, path string) (module.Version, bool) {
+	if pkg, ok := ld.pkgCache.Get(path).(*loadPkg); ok {
 		return pkg.mod, pkg.mod != module.Version{}
 	}
 	if path == "command-line-arguments" {
diff --git a/src/cmd/go/internal/modload/buildlist.go b/src/cmd/go/internal/modload/buildlist.go
index 45f220a..bf69567 100644
--- a/src/cmd/go/internal/modload/buildlist.go
+++ b/src/cmd/go/internal/modload/buildlist.go
@@ -7,66 +7,489 @@
 import (
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
-	"cmd/go/internal/imports"
 	"cmd/go/internal/mvs"
+	"cmd/go/internal/par"
 	"context"
 	"fmt"
 	"os"
+	"reflect"
+	"runtime"
+	"runtime/debug"
 	"strings"
+	"sync"
+	"sync/atomic"
 
 	"golang.org/x/mod/module"
+	"golang.org/x/mod/semver"
 )
 
-// buildList is the list of modules to use for building packages.
-// It is initialized by calling LoadPackages or ImportFromFiles,
-// each of which uses loaded.load.
-//
-// Ideally, exactly ONE of those functions would be called,
-// and exactly once. Most of the time, that's true.
-// During "go get" it may not be. TODO(rsc): Figure out if
-// that restriction can be established, or else document why not.
-//
-var buildList []module.Version
-
-// additionalExplicitRequirements is a list of modules paths for which
-// WriteGoMod should record explicit requirements, even if they would be
-// selected without those requirements. Each path must also appear in buildList.
-var additionalExplicitRequirements []string
-
 // capVersionSlice returns s with its cap reduced to its length.
 func capVersionSlice(s []module.Version) []module.Version {
 	return s[:len(s):len(s)]
 }
 
-// LoadAllModules loads and returns the list of modules matching the "all"
-// module pattern, starting with the Target module and in a deterministic
-// (stable) order, without loading any packages.
-//
-// Modules are loaded automatically (and lazily) in LoadPackages:
-// LoadAllModules need only be called if LoadPackages is not,
-// typically in commands that care about modules but no particular package.
-//
-// The caller must not modify the returned list, but may append to it.
-func LoadAllModules(ctx context.Context) []module.Version {
-	LoadModFile(ctx)
-	ReloadBuildList()
-	WriteGoMod()
-	return capVersionSlice(buildList)
+// A Requirements represents a logically-immutable set of root module requirements.
+type Requirements struct {
+	// depth is the depth at which the requirement graph is computed.
+	//
+	// If eager, the graph includes all transitive requirements regardless of depth.
+	//
+	// If lazy, the graph includes only the root modules, the explicit
+	// requirements of those root modules, and the transitive requirements of only
+	// the *non-lazy* root modules.
+	depth modDepth
+
+	// rootModules is the set of module versions explicitly required by the main
+	// module, sorted and capped to length. It may contain duplicates, and may
+	// contain multiple versions for a given module path.
+	rootModules    []module.Version
+	maxRootVersion map[string]string
+
+	// direct is the set of module paths for which we believe the module provides
+	// a package directly imported by a package or test in the main module.
+	//
+	// The "direct" map controls which modules are annotated with "// indirect"
+	// comments in the go.mod file, and may impact which modules are listed as
+	// explicit roots (vs. indirect-only dependencies). However, it should not
+	// have a semantic effect on the build list overall.
+	//
+	// The initial direct map is populated from the existing "// indirect"
+	// comments (or lack thereof) in the go.mod file. It is updated by the
+	// package loader: dependencies may be promoted to direct if new
+	// direct imports are observed, and may be demoted to indirect during
+	// 'go mod tidy' or 'go mod vendor'.
+	//
+	// The direct map is keyed by module paths, not module versions. When a
+	// module's selected version changes, we assume that it remains direct if the
+	// previous version was a direct dependency. That assumption might not hold in
+	// rare cases (such as if a dependency splits out a nested module, or merges a
+	// nested module back into a parent module).
+	direct map[string]bool
+
+	graphOnce sync.Once    // guards writes to (but not reads from) graph
+	graph     atomic.Value // cachedGraph
 }
 
-// Selected returns the selected version of the module with the given path, or
-// the empty string if the given module has no selected version
-// (either because it is not required or because it is the Target module).
-func Selected(path string) (version string) {
-	if path == Target.Path {
-		return ""
-	}
-	for _, m := range buildList {
-		if m.Path == path {
-			return m.Version
+// A cachedGraph is a non-nil *ModuleGraph, together with any error discovered
+// while loading that graph.
+type cachedGraph struct {
+	mg  *ModuleGraph
+	err error // If err is non-nil, mg may be incomplete (but must still be non-nil).
+}
+
+// requirements is the requirement graph for the main module.
+//
+// It is always non-nil if the main module's go.mod file has been loaded.
+//
+// This variable should only be read from the loadModFile function, and should
+// only be written in the loadModFile and commitRequirements functions.
+// All other functions that need or produce a *Requirements should
+// accept and/or return an explicit parameter.
+var requirements *Requirements
+
+// newRequirements returns a new requirement set with the given root modules.
+// The dependencies of the roots will be loaded lazily at the first call to the
+// Graph method.
+//
+// The rootModules slice must be sorted according to module.Sort.
+// The caller must not modify the rootModules slice or direct map after passing
+// them to newRequirements.
+//
+// If vendoring is in effect, the caller must invoke initVendor on the returned
+// *Requirements before any other method.
+func newRequirements(depth modDepth, rootModules []module.Version, direct map[string]bool) *Requirements {
+	for i, m := range rootModules {
+		if m == Target {
+			panic(fmt.Sprintf("newRequirements called with untrimmed build list: rootModules[%v] is Target", i))
+		}
+		if m.Path == "" || m.Version == "" {
+			panic(fmt.Sprintf("bad requirement: rootModules[%v] = %v", i, m))
+		}
+		if i > 0 {
+			prev := rootModules[i-1]
+			if prev.Path > m.Path || (prev.Path == m.Path && semver.Compare(prev.Version, m.Version) > 0) {
+				panic(fmt.Sprintf("newRequirements called with unsorted roots: %v", rootModules))
+			}
 		}
 	}
-	return ""
+
+	rs := &Requirements{
+		depth:          depth,
+		rootModules:    capVersionSlice(rootModules),
+		maxRootVersion: make(map[string]string, len(rootModules)),
+		direct:         direct,
+	}
+
+	for _, m := range rootModules {
+		if v, ok := rs.maxRootVersion[m.Path]; ok && cmpVersion(v, m.Version) >= 0 {
+			continue
+		}
+		rs.maxRootVersion[m.Path] = m.Version
+	}
+	return rs
+}
+
+// initVendor initializes rs.graph from the given list of vendored module
+// dependencies, overriding the graph that would normally be loaded from module
+// requirements.
+func (rs *Requirements) initVendor(vendorList []module.Version) {
+	rs.graphOnce.Do(func() {
+		mg := &ModuleGraph{
+			g: mvs.NewGraph(cmpVersion, []module.Version{Target}),
+		}
+
+		if rs.depth == lazy {
+			// The roots of a lazy module should already include every module in the
+			// vendor list, because the vendored modules are the same as those
+			// maintained as roots by the lazy loading “import invariant”.
+			//
+			// Just to be sure, we'll double-check that here.
+			inconsistent := false
+			for _, m := range vendorList {
+				if v, ok := rs.rootSelected(m.Path); !ok || v != m.Version {
+					base.Errorf("go: vendored module %v should be required explicitly in go.mod", m)
+					inconsistent = true
+				}
+			}
+			if inconsistent {
+				base.Fatalf("go: %v", errGoModDirty)
+			}
+
+			// Now we can treat the rest of the module graph as effectively “pruned
+			// out”, like a more aggressive version of lazy loading: in vendor mode,
+			// the root requirements *are* the complete module graph.
+			mg.g.Require(Target, rs.rootModules)
+		} else {
+			// The transitive requirements of the main module are not in general available
+			// from the vendor directory, and we don't actually know how we got from
+			// the roots to the final build list.
+			//
+			// Instead, we'll inject a fake "vendor/modules.txt" module that provides
+			// those transitive dependencies, and mark it as a dependency of the main
+			// module. That allows us to elide the actual structure of the module
+			// graph, but still distinguishes between direct and indirect
+			// dependencies.
+			vendorMod := module.Version{Path: "vendor/modules.txt", Version: ""}
+			mg.g.Require(Target, append(rs.rootModules, vendorMod))
+			mg.g.Require(vendorMod, vendorList)
+		}
+
+		rs.graph.Store(cachedGraph{mg, nil})
+	})
+}
+
+// rootSelected returns the version of the root dependency with the given module
+// path, or the zero module.Version and ok=false if the module is not a root
+// dependency.
+func (rs *Requirements) rootSelected(path string) (version string, ok bool) {
+	if path == Target.Path {
+		return Target.Version, true
+	}
+	if v, ok := rs.maxRootVersion[path]; ok {
+		return v, true
+	}
+	return "", false
+}
+
+// hasRedundantRoot returns true if the root list contains multiple requirements
+// of the same module or a requirement on any version of the main module.
+// Redundant requirements should be pruned, but they may influence version
+// selection.
+func (rs *Requirements) hasRedundantRoot() bool {
+	for i, m := range rs.rootModules {
+		if m.Path == Target.Path || (i > 0 && m.Path == rs.rootModules[i-1].Path) {
+			return true
+		}
+	}
+	return false
+}
+
+// Graph returns the graph of module requirements loaded from the current
+// root modules (as reported by RootModules).
+//
+// Graph always makes a best effort to load the requirement graph despite any
+// errors, and always returns a non-nil *ModuleGraph.
+//
+// If the requirements of any relevant module fail to load, Graph also
+// returns a non-nil error of type *mvs.BuildListError.
+func (rs *Requirements) Graph(ctx context.Context) (*ModuleGraph, error) {
+	rs.graphOnce.Do(func() {
+		mg, mgErr := readModGraph(ctx, rs.depth, rs.rootModules)
+		rs.graph.Store(cachedGraph{mg, mgErr})
+	})
+	cached := rs.graph.Load().(cachedGraph)
+	return cached.mg, cached.err
+}
+
+// IsDirect returns whether the given module provides a package directly
+// imported by a package or test in the main module.
+func (rs *Requirements) IsDirect(path string) bool {
+	return rs.direct[path]
+}
+
+// A ModuleGraph represents the complete graph of module dependencies
+// of a main module.
+//
+// If the main module is lazily loaded, the graph does not include
+// transitive dependencies of non-root (implicit) dependencies.
+type ModuleGraph struct {
+	g         *mvs.Graph
+	loadCache par.Cache // module.Version → summaryError
+
+	buildListOnce sync.Once
+	buildList     []module.Version
+}
+
+// A summaryError is either a non-nil modFileSummary or a non-nil error
+// encountered while reading or parsing that summary.
+type summaryError struct {
+	summary *modFileSummary
+	err     error
+}
+
+var readModGraphDebugOnce sync.Once
+
+// readModGraph reads and returns the module dependency graph starting at the
+// given roots.
+//
+// Unlike LoadModGraph, readModGraph does not attempt to diagnose or update
+// inconsistent roots.
+func readModGraph(ctx context.Context, depth modDepth, roots []module.Version) (*ModuleGraph, error) {
+	if depth == lazy {
+		readModGraphDebugOnce.Do(func() {
+			for _, f := range strings.Split(os.Getenv("GODEBUG"), ",") {
+				switch f {
+				case "lazymod=log":
+					debug.PrintStack()
+					fmt.Fprintf(os.Stderr, "go: read full module graph.\n")
+				case "lazymod=strict":
+					debug.PrintStack()
+					base.Fatalf("go: read full module graph (forbidden by GODEBUG=lazymod=strict).")
+				}
+			}
+		})
+	}
+
+	var (
+		mu       sync.Mutex // guards mg.g and hasError during loading
+		hasError bool
+		mg       = &ModuleGraph{
+			g: mvs.NewGraph(cmpVersion, []module.Version{Target}),
+		}
+	)
+	mg.g.Require(Target, roots)
+
+	var (
+		loadQueue    = par.NewQueue(runtime.GOMAXPROCS(0))
+		loadingEager sync.Map // module.Version → nil; the set of modules that have been or are being loaded via eager roots
+	)
+
+	// loadOne synchronously loads the explicit requirements for module m.
+	// It does not load the transitive requirements of m even if the go version in
+	// m's go.mod file indicates eager loading.
+	loadOne := func(m module.Version) (*modFileSummary, error) {
+		cached := mg.loadCache.Do(m, func() interface{} {
+			summary, err := goModSummary(m)
+
+			mu.Lock()
+			if err == nil {
+				mg.g.Require(m, summary.require)
+			} else {
+				hasError = true
+			}
+			mu.Unlock()
+
+			return summaryError{summary, err}
+		}).(summaryError)
+
+		return cached.summary, cached.err
+	}
+
+	var enqueue func(m module.Version, depth modDepth)
+	enqueue = func(m module.Version, depth modDepth) {
+		if m.Version == "none" {
+			return
+		}
+
+		if depth == eager {
+			if _, dup := loadingEager.LoadOrStore(m, nil); dup {
+				// m has already been enqueued for loading. Since eager loading may
+				// follow cycles in the the requirement graph, we need to return early
+				// to avoid making the load queue infinitely long.
+				return
+			}
+		}
+
+		loadQueue.Add(func() {
+			summary, err := loadOne(m)
+			if err != nil {
+				return // findError will report the error later.
+			}
+
+			// If the version in m's go.mod file implies eager loading, then we cannot
+			// assume that the explicit requirements of m (added by loadOne) are
+			// sufficient to build the packages it contains. We must load its full
+			// transitive dependency graph to be sure that we see all relevant
+			// dependencies.
+			if depth == eager || summary.depth == eager {
+				for _, r := range summary.require {
+					enqueue(r, eager)
+				}
+			}
+		})
+	}
+
+	for _, m := range roots {
+		enqueue(m, depth)
+	}
+	<-loadQueue.Idle()
+
+	if hasError {
+		return mg, mg.findError()
+	}
+	return mg, nil
+}
+
+// RequiredBy returns the dependencies required by module m in the graph,
+// or ok=false if module m's dependencies are not relevant (such as if they
+// are pruned out by lazy loading).
+//
+// The caller must not modify the returned slice, but may safely append to it
+// and may rely on it not to be modified.
+func (mg *ModuleGraph) RequiredBy(m module.Version) (reqs []module.Version, ok bool) {
+	return mg.g.RequiredBy(m)
+}
+
+// Selected returns the selected version of the module with the given path.
+//
+// If no version is selected, Selected returns version "none".
+func (mg *ModuleGraph) Selected(path string) (version string) {
+	return mg.g.Selected(path)
+}
+
+// WalkBreadthFirst invokes f once, in breadth-first order, for each module
+// version other than "none" that appears in the graph, regardless of whether
+// that version is selected.
+func (mg *ModuleGraph) WalkBreadthFirst(f func(m module.Version)) {
+	mg.g.WalkBreadthFirst(f)
+}
+
+// BuildList returns the selected versions of all modules present in the graph,
+// beginning with Target.
+//
+// The order of the remaining elements in the list is deterministic
+// but arbitrary.
+//
+// The caller must not modify the returned list, but may safely append to it
+// and may rely on it not to be modified.
+func (mg *ModuleGraph) BuildList() []module.Version {
+	mg.buildListOnce.Do(func() {
+		mg.buildList = capVersionSlice(mg.g.BuildList())
+	})
+	return mg.buildList
+}
+
+func (mg *ModuleGraph) findError() error {
+	errStack := mg.g.FindPath(func(m module.Version) bool {
+		cached := mg.loadCache.Get(m)
+		return cached != nil && cached.(summaryError).err != nil
+	})
+	if len(errStack) > 0 {
+		err := mg.loadCache.Get(errStack[len(errStack)-1]).(summaryError).err
+		var noUpgrade func(from, to module.Version) bool
+		return mvs.NewBuildListError(err, errStack, noUpgrade)
+	}
+
+	return nil
+}
+
+func (mg *ModuleGraph) allRootsSelected() bool {
+	roots, _ := mg.g.RequiredBy(Target)
+	for _, m := range roots {
+		if mg.Selected(m.Path) != m.Version {
+			return false
+		}
+	}
+	return true
+}
+
+// LoadModGraph loads and returns the graph of module dependencies of the main module,
+// without loading any packages.
+//
+// If the goVersion string is non-empty, the returned graph is the graph
+// as interpreted by the given Go version (instead of the version indicated
+// in the go.mod file).
+//
+// Modules are loaded automatically (and lazily) in LoadPackages:
+// LoadModGraph need only be called if LoadPackages is not,
+// typically in commands that care about modules but no particular package.
+func LoadModGraph(ctx context.Context, goVersion string) *ModuleGraph {
+	rs := LoadModFile(ctx)
+
+	if goVersion != "" {
+		depth := modDepthFromGoVersion(goVersion)
+		if depth == eager && rs.depth != eager {
+			// Use newRequirements instead of convertDepth because convertDepth
+			// also updates roots; here, we want to report the unmodified roots
+			// even though they may seem inconsistent.
+			rs = newRequirements(eager, rs.rootModules, rs.direct)
+		}
+
+		mg, err := rs.Graph(ctx)
+		if err != nil {
+			base.Fatalf("go: %v", err)
+		}
+		return mg
+	}
+
+	rs, mg, err := expandGraph(ctx, rs)
+	if err != nil {
+		base.Fatalf("go: %v", err)
+	}
+
+	commitRequirements(ctx, modFileGoVersion(), rs)
+	return mg
+}
+
+// expandGraph loads the complete module graph from rs.
+//
+// If the complete graph reveals that some root of rs is not actually the
+// selected version of its path, expandGraph computes a new set of roots that
+// are consistent. (When lazy loading is implemented, this may result in
+// upgrades to other modules due to requirements that were previously pruned
+// out.)
+//
+// expandGraph returns the updated roots, along with the module graph loaded
+// from those roots and any error encountered while loading that graph.
+// expandGraph returns non-nil requirements and a non-nil graph regardless of
+// errors. On error, the roots might not be updated to be consistent.
+func expandGraph(ctx context.Context, rs *Requirements) (*Requirements, *ModuleGraph, error) {
+	mg, mgErr := rs.Graph(ctx)
+	if mgErr != nil {
+		// Without the graph, we can't update the roots: we don't know which
+		// versions of transitive dependencies would be selected.
+		return rs, mg, mgErr
+	}
+
+	if !mg.allRootsSelected() {
+		// The roots of rs are not consistent with the rest of the graph. Update
+		// them. In an eager module this is a no-op for the build list as a whole —
+		// it just promotes what were previously transitive requirements to be
+		// roots — but in a lazy module it may pull in previously-irrelevant
+		// transitive dependencies.
+
+		newRS, rsErr := updateRoots(ctx, rs.direct, rs, nil, nil, false)
+		if rsErr != nil {
+			// Failed to update roots, perhaps because of an error in a transitive
+			// dependency needed for the update. Return the original Requirements
+			// instead.
+			return rs, mg, rsErr
+		}
+		rs = newRS
+		mg, mgErr = rs.Graph(ctx)
+	}
+
+	return rs, mg, mgErr
 }
 
 // EditBuildList edits the global build list by first adding every module in add
@@ -81,111 +504,17 @@
 // If the versions listed in mustSelect are mutually incompatible (due to one of
 // the listed modules requiring a higher version of another), EditBuildList
 // returns a *ConstraintError and leaves the build list in its previous state.
-func EditBuildList(ctx context.Context, add, mustSelect []module.Version) error {
-	var upgraded = capVersionSlice(buildList)
-	if len(add) > 0 {
-		// First, upgrade the build list with any additions.
-		// In theory we could just append the additions to the build list and let
-		// mvs.Downgrade take care of resolving the upgrades too, but the
-		// diagnostics from Upgrade are currently much better in case of errors.
-		var err error
-		upgraded, err = mvs.Upgrade(Target, &mvsReqs{buildList: upgraded}, add...)
-		if err != nil {
-			return err
-		}
-	}
-
-	downgraded, err := mvs.Downgrade(Target, &mvsReqs{buildList: append(upgraded, mustSelect...)}, mustSelect...)
+//
+// On success, EditBuildList reports whether the selected version of any module
+// in the build list may have been changed (possibly to or from "none") as a
+// result.
+func EditBuildList(ctx context.Context, add, mustSelect []module.Version) (changed bool, err error) {
+	rs, changed, err := editRequirements(ctx, LoadModFile(ctx), add, mustSelect)
 	if err != nil {
-		return err
+		return false, err
 	}
-
-	final, err := mvs.Upgrade(Target, &mvsReqs{buildList: downgraded}, mustSelect...)
-	if err != nil {
-		return err
-	}
-
-	selected := make(map[string]module.Version, len(final))
-	for _, m := range final {
-		selected[m.Path] = m
-	}
-	inconsistent := false
-	for _, m := range mustSelect {
-		s, ok := selected[m.Path]
-		if !ok {
-			if m.Version != "none" {
-				panic(fmt.Sprintf("internal error: mvs.BuildList lost %v", m))
-			}
-			continue
-		}
-		if s.Version != m.Version {
-			inconsistent = true
-			break
-		}
-	}
-
-	if !inconsistent {
-		buildList = final
-		additionalExplicitRequirements = make([]string, 0, len(mustSelect))
-		for _, m := range mustSelect {
-			if m.Version != "none" {
-				additionalExplicitRequirements = append(additionalExplicitRequirements, m.Path)
-			}
-		}
-		return nil
-	}
-
-	// We overshot one or more of the modules in mustSelected, which means that
-	// Downgrade removed something in mustSelect because it conflicted with
-	// something else in mustSelect.
-	//
-	// Walk the requirement graph to find the conflict.
-	//
-	// TODO(bcmills): Ideally, mvs.Downgrade (or a replacement for it) would do
-	// this directly.
-
-	reqs := &mvsReqs{buildList: final}
-	reason := map[module.Version]module.Version{}
-	for _, m := range mustSelect {
-		reason[m] = m
-	}
-	queue := mustSelect[:len(mustSelect):len(mustSelect)]
-	for len(queue) > 0 {
-		var m module.Version
-		m, queue = queue[0], queue[1:]
-		required, err := reqs.Required(m)
-		if err != nil {
-			return err
-		}
-		for _, r := range required {
-			if _, ok := reason[r]; !ok {
-				reason[r] = reason[m]
-				queue = append(queue, r)
-			}
-		}
-	}
-
-	var conflicts []Conflict
-	for _, m := range mustSelect {
-		s, ok := selected[m.Path]
-		if !ok {
-			if m.Version != "none" {
-				panic(fmt.Sprintf("internal error: mvs.BuildList lost %v", m))
-			}
-			continue
-		}
-		if s.Version != m.Version {
-			conflicts = append(conflicts, Conflict{
-				Source:     reason[s],
-				Dep:        s,
-				Constraint: m,
-			})
-		}
-	}
-
-	return &ConstraintError{
-		Conflicts: conflicts,
-	}
+	commitRequirements(ctx, modFileGoVersion(), rs)
+	return changed, err
 }
 
 // A ConstraintError describes inconsistent constraints in EditBuildList
@@ -213,66 +542,580 @@
 	Constraint module.Version
 }
 
-// ReloadBuildList resets the state of loaded packages, then loads and returns
-// the build list set by EditBuildList.
-func ReloadBuildList() []module.Version {
-	loaded = loadFromRoots(loaderParams{
-		PackageOpts: PackageOpts{
-			Tags: imports.Tags(),
-		},
-		listRoots:          func() []string { return nil },
-		allClosesOverTests: index.allPatternClosesOverTests(), // but doesn't matter because the root list is empty.
-	})
-	return capVersionSlice(buildList)
+// tidyRoots trims the root dependencies to the minimal requirements needed to
+// both retain the same versions of all packages in pkgs and satisfy the
+// lazy loading invariants (if applicable).
+func tidyRoots(ctx context.Context, rs *Requirements, pkgs []*loadPkg) (*Requirements, error) {
+	if rs.depth == eager {
+		return tidyEagerRoots(ctx, rs.direct, pkgs)
+	}
+	return tidyLazyRoots(ctx, rs.direct, pkgs)
 }
 
-// TidyBuildList trims the build list to the minimal requirements needed to
-// retain the same versions of all packages from the preceding call to
-// LoadPackages.
-func TidyBuildList() {
-	used := map[module.Version]bool{Target: true}
-	for _, pkg := range loaded.pkgs {
-		used[pkg.mod] = true
+func updateRoots(ctx context.Context, direct map[string]bool, rs *Requirements, pkgs []*loadPkg, add []module.Version, rootsImported bool) (*Requirements, error) {
+	if rs.depth == eager {
+		return updateEagerRoots(ctx, direct, rs, add)
 	}
-
-	keep := []module.Version{Target}
-	var direct []string
-	for _, m := range buildList[1:] {
-		if used[m] {
-			keep = append(keep, m)
-			if loaded.direct[m.Path] {
-				direct = append(direct, m.Path)
-			}
-		} else if cfg.BuildV {
-			if _, ok := index.require[m]; ok {
-				fmt.Fprintf(os.Stderr, "unused %s\n", m.Path)
-			}
-		}
-	}
-
-	min, err := mvs.Req(Target, direct, &mvsReqs{buildList: keep})
-	if err != nil {
-		base.Fatalf("go: %v", err)
-	}
-	buildList = append([]module.Version{Target}, min...)
+	return updateLazyRoots(ctx, direct, rs, pkgs, add, rootsImported)
 }
 
-// checkMultiplePaths verifies that a given module path is used as itself
-// or as a replacement for another module, but not both at the same time.
+// tidyLazyRoots returns a minimal set of root requirements that maintains the
+// "lazy loading" invariants of the go.mod file for the given packages:
 //
-// (See https://golang.org/issue/26607 and https://golang.org/issue/34650.)
-func checkMultiplePaths() {
-	firstPath := make(map[module.Version]string, len(buildList))
-	for _, mod := range buildList {
-		src := mod
-		if rep := Replacement(mod); rep.Path != "" {
-			src = rep
+// 	1. For each package marked with pkgInAll, the module path that provided that
+// 	   package is included as a root.
+// 	2. For all packages, the module that provided that package either remains
+// 	   selected at the same version or is upgraded by the dependencies of a
+// 	   root.
+//
+// If any module that provided a package has been upgraded above its previous,
+// version, the caller may need to reload and recompute the package graph.
+//
+// To ensure that the loading process eventually converges, the caller should
+// add any needed roots from the tidy root set (without removing existing untidy
+// roots) until the set of roots has converged.
+func tidyLazyRoots(ctx context.Context, direct map[string]bool, pkgs []*loadPkg) (*Requirements, error) {
+	var (
+		roots        []module.Version
+		pathIncluded = map[string]bool{Target.Path: true}
+	)
+	// We start by adding roots for every package in "all".
+	//
+	// Once that is done, we may still need to add more roots to cover upgraded or
+	// otherwise-missing test dependencies for packages in "all". For those test
+	// dependencies, we prefer to add roots for packages with shorter import
+	// stacks first, on the theory that the module requirements for those will
+	// tend to fill in the requirements for their transitive imports (which have
+	// deeper import stacks). So we add the missing dependencies for one depth at
+	// a time, starting with the packages actually in "all" and expanding outwards
+	// until we have scanned every package that was loaded.
+	var (
+		queue  []*loadPkg
+		queued = map[*loadPkg]bool{}
+	)
+	for _, pkg := range pkgs {
+		if !pkg.flags.has(pkgInAll) {
+			continue
 		}
-		if prev, ok := firstPath[src]; !ok {
-			firstPath[src] = mod.Path
-		} else if prev != mod.Path {
-			base.Errorf("go: %s@%s used for two different module paths (%s and %s)", src.Path, src.Version, prev, mod.Path)
+		if pkg.fromExternalModule() && !pathIncluded[pkg.mod.Path] {
+			roots = append(roots, pkg.mod)
+			pathIncluded[pkg.mod.Path] = true
+		}
+		queue = append(queue, pkg)
+		queued[pkg] = true
+	}
+	module.Sort(roots)
+	tidy := newRequirements(lazy, roots, direct)
+
+	for len(queue) > 0 {
+		roots = tidy.rootModules
+		mg, err := tidy.Graph(ctx)
+		if err != nil {
+			return nil, err
+		}
+
+		prevQueue := queue
+		queue = nil
+		for _, pkg := range prevQueue {
+			m := pkg.mod
+			if m.Path == "" {
+				continue
+			}
+			for _, dep := range pkg.imports {
+				if !queued[dep] {
+					queue = append(queue, dep)
+					queued[dep] = true
+				}
+			}
+			if pkg.test != nil && !queued[pkg.test] {
+				queue = append(queue, pkg.test)
+				queued[pkg.test] = true
+			}
+			if !pathIncluded[m.Path] {
+				if s := mg.Selected(m.Path); cmpVersion(s, m.Version) < 0 {
+					roots = append(roots, m)
+				}
+				pathIncluded[m.Path] = true
+			}
+		}
+
+		if len(roots) > len(tidy.rootModules) {
+			module.Sort(roots)
+			tidy = newRequirements(lazy, roots, tidy.direct)
 		}
 	}
-	base.ExitIfErrors()
+
+	_, err := tidy.Graph(ctx)
+	if err != nil {
+		return nil, err
+	}
+	return tidy, nil
+}
+
+// updateLazyRoots returns a set of root requirements that maintains the “lazy
+// loading” invariants of the go.mod file:
+//
+// 	1. The selected version of the module providing each package marked with
+// 	   either pkgInAll or pkgIsRoot is included as a root.
+// 	   Note that certain root patterns (such as '...') may explode the root set
+// 	   to contain every module that provides any package imported (or merely
+// 	   required) by any other module.
+// 	2. Each root appears only once, at the selected version of its path
+// 	   (if rs.graph is non-nil) or at the highest version otherwise present as a
+// 	   root (otherwise).
+// 	3. Every module path that appears as a root in rs remains a root.
+// 	4. Every version in add is selected at its given version unless upgraded by
+// 	   (the dependencies of) an existing root or another module in add.
+//
+// The packages in pkgs are assumed to have been loaded from either the roots of
+// rs or the modules selected in the graph of rs.
+//
+// The above invariants together imply the “lazy loading” invariants for the
+// go.mod file:
+//
+// 	1. (The import invariant.) Every module that provides a package transitively
+// 	   imported by any package or test in the main module is included as a root.
+// 	   This follows by induction from (1) and (3) above. Transitively-imported
+// 	   packages loaded during this invocation are marked with pkgInAll (1),
+// 	   and by hypothesis any transitively-imported packages loaded in previous
+// 	   invocations were already roots in rs (3).
+//
+// 	2. (The argument invariant.) Every module that provides a package matching
+// 	   an explicit package pattern is included as a root. This follows directly
+// 	   from (1): packages matching explicit package patterns are marked with
+// 	   pkgIsRoot.
+//
+// 	3. (The completeness invariant.) Every module that contributed any package
+// 	   to the build is required by either the main module or one of the modules
+// 	   it requires explicitly. This invariant is left up to the caller, who must
+// 	   not load packages from outside the module graph but may add roots to the
+// 	   graph, but is facilited by (3). If the caller adds roots to the graph in
+// 	   order to resolve missing packages, then updateLazyRoots will retain them,
+// 	   the selected versions of those roots cannot regress, and they will
+// 	   eventually be written back to the main module's go.mod file.
+//
+// (See https://golang.org/design/36460-lazy-module-loading#invariants for more
+// detail.)
+func updateLazyRoots(ctx context.Context, direct map[string]bool, rs *Requirements, pkgs []*loadPkg, add []module.Version, rootsImported bool) (*Requirements, error) {
+	roots := rs.rootModules
+	rootsUpgraded := false
+
+	spotCheckRoot := map[module.Version]bool{}
+
+	// “The selected version of the module providing each package marked with
+	// either pkgInAll or pkgIsRoot is included as a root.”
+	needSort := false
+	for _, pkg := range pkgs {
+		if !pkg.fromExternalModule() {
+			// pkg was not loaded from a module dependency, so we don't need
+			// to do anything special to maintain that dependency.
+			continue
+		}
+
+		switch {
+		case pkg.flags.has(pkgInAll):
+			// pkg is transitively imported by a package or test in the main module.
+			// We need to promote the module that maintains it to a root: if some
+			// other module depends on the main module, and that other module also
+			// uses lazy loading, it will expect to find all of our transitive
+			// dependencies by reading just our go.mod file, not the go.mod files of
+			// everything we depend on.
+			//
+			// (This is the “import invariant” that makes lazy loading possible.)
+
+		case rootsImported && pkg.flags.has(pkgFromRoot):
+			// pkg is a transitive dependency of some root, and we are treating the
+			// roots as if they are imported by the main module (as in 'go get').
+
+		case pkg.flags.has(pkgIsRoot):
+			// pkg is a root of the package-import graph. (Generally this means that
+			// it matches a command-line argument.) We want future invocations of the
+			// 'go' command — such as 'go test' on the same package — to continue to
+			// use the same versions of its dependencies that we are using right now.
+			// So we need to bring this package's dependencies inside the lazy-loading
+			// horizon.
+			//
+			// Making the module containing this package a root of the module graph
+			// does exactly that: if the module containing the package is lazy it
+			// should satisfy the import invariant itself, so all of its dependencies
+			// should be in its go.mod file, and if the module containing the package
+			// is eager then if we make it a root we will load all of its transitive
+			// dependencies into the module graph.
+			//
+			// (This is the “argument invariant” of lazy loading, and is important for
+			// reproducibility.)
+
+		default:
+			// pkg is a dependency of some other package outside of the main module.
+			// As far as we know it's not relevant to the main module (and thus not
+			// relevant to consumers of the main module either), and its dependencies
+			// should already be in the module graph — included in the dependencies of
+			// the package that imported it.
+			continue
+		}
+
+		if _, ok := rs.rootSelected(pkg.mod.Path); ok {
+			// It is possible that the main module's go.mod file is incomplete or
+			// otherwise erroneous — for example, perhaps the author forgot to 'git
+			// add' their updated go.mod file after adding a new package import, or
+			// perhaps they made an edit to the go.mod file using a third-party tool
+			// ('git merge'?) that doesn't maintain consistency for module
+			// dependencies. If that happens, ideally we want to detect the missing
+			// requirements and fix them up here.
+			//
+			// However, we also need to be careful not to be too aggressive. For
+			// transitive dependencies of external tests, the go.mod file for the
+			// module containing the test itself is expected to provide all of the
+			// relevant dependencies, and we explicitly don't want to pull in
+			// requirements on *irrelevant* requirements that happen to occur in the
+			// go.mod files for these transitive-test-only dependencies. (See the test
+			// in mod_lazy_test_horizon.txt for a concrete example.
+			//
+			// The “goldilocks zone” seems to be to spot-check exactly the same
+			// modules that we promote to explicit roots: namely, those that provide
+			// packages transitively imported by the main module, and those that
+			// provide roots of the package-import graph. That will catch erroneous
+			// edits to the main module's go.mod file and inconsistent requirements in
+			// dependencies that provide imported packages, but will ignore erroneous
+			// or misleading requirements in dependencies that aren't obviously
+			// relevant to the packages in the main module.
+			spotCheckRoot[pkg.mod] = true
+		} else {
+			roots = append(roots, pkg.mod)
+			rootsUpgraded = true
+			// The roots slice was initially sorted because rs.rootModules was sorted,
+			// but the root we just added could be out of order.
+			needSort = true
+		}
+	}
+
+	for _, m := range add {
+		if v, ok := rs.rootSelected(m.Path); !ok || cmpVersion(v, m.Version) < 0 {
+			roots = append(roots, m)
+			rootsUpgraded = true
+			needSort = true
+		}
+	}
+	if needSort {
+		module.Sort(roots)
+	}
+
+	// "Each root appears only once, at the selected version of its path ….”
+	for {
+		var mg *ModuleGraph
+		if rootsUpgraded {
+			// We've added or upgraded one or more roots, so load the full module
+			// graph so that we can update those roots to be consistent with other
+			// requirements.
+			if cfg.BuildMod != "mod" {
+				// Our changes to the roots may have moved dependencies into or out of
+				// the lazy-loading horizon, which could in turn change the selected
+				// versions of other modules. (Unlike for eager modules, for lazy
+				// modules adding or removing an explicit root is a semantic change, not
+				// just a cosmetic one.)
+				return rs, errGoModDirty
+			}
+
+			rs = newRequirements(lazy, roots, direct)
+			var err error
+			mg, err = rs.Graph(ctx)
+			if err != nil {
+				return rs, err
+			}
+		} else {
+			// Since none of the roots have been upgraded, we have no reason to
+			// suspect that they are inconsistent with the requirements of any other
+			// roots. Only look at the full module graph if we've already loaded it;
+			// otherwise, just spot-check the explicit requirements of the roots from
+			// which we loaded packages.
+			if rs.graph.Load() != nil {
+				// We've already loaded the full module graph, which includes the
+				// requirements of all of the root modules — even the transitive
+				// requirements, if they are eager!
+				mg, _ = rs.Graph(ctx)
+			} else if cfg.BuildMod == "vendor" {
+				// We can't spot-check the requirements of other modules because we
+				// don't in general have their go.mod files available in the vendor
+				// directory. (Fortunately this case is impossible, because mg.graph is
+				// always non-nil in vendor mode!)
+				panic("internal error: rs.graph is unexpectedly nil with -mod=vendor")
+			} else if !spotCheckRoots(ctx, rs, spotCheckRoot) {
+				// We spot-checked the explicit requirements of the roots that are
+				// relevant to the packages we've loaded. Unfortunately, they're
+				// inconsistent in some way; we need to load the full module graph
+				// so that we can fix the roots properly.
+				var err error
+				mg, err = rs.Graph(ctx)
+				if err != nil {
+					return rs, err
+				}
+			}
+		}
+
+		roots = make([]module.Version, 0, len(rs.rootModules))
+		rootsUpgraded = false
+		inRootPaths := make(map[string]bool, len(rs.rootModules)+1)
+		inRootPaths[Target.Path] = true
+		for _, m := range rs.rootModules {
+			if inRootPaths[m.Path] {
+				// This root specifies a redundant path. We already retained the
+				// selected version of this path when we saw it before, so omit the
+				// redundant copy regardless of its version.
+				//
+				// When we read the full module graph, we include the dependencies of
+				// every root even if that root is redundant. That better preserves
+				// reproducibility if, say, some automated tool adds a redundant
+				// 'require' line and then runs 'go mod tidy' to try to make everything
+				// consistent, since the requirements of the older version are carried
+				// over.
+				//
+				// So omitting a root that was previously present may *reduce* the
+				// selected versions of non-roots, but merely removing a requirement
+				// cannot *increase* the selected versions of other roots as a result —
+				// we don't need to mark this change as an upgrade. (This particular
+				// change cannot invalidate any other roots.)
+				continue
+			}
+
+			var v string
+			if mg == nil {
+				v, _ = rs.rootSelected(m.Path)
+			} else {
+				v = mg.Selected(m.Path)
+			}
+			roots = append(roots, module.Version{Path: m.Path, Version: v})
+			inRootPaths[m.Path] = true
+			if v != m.Version {
+				rootsUpgraded = true
+			}
+		}
+		// Note that rs.rootModules was already sorted by module path and version,
+		// and we appended to the roots slice in the same order and guaranteed that
+		// each path has only one version, so roots is also sorted by module path
+		// and (trivially) version.
+
+		if !rootsUpgraded {
+			if cfg.BuildMod != "mod" {
+				// The only changes to the root set (if any) were to remove duplicates.
+				// The requirements are consistent (if perhaps redundant), so keep the
+				// original rs to preserve its ModuleGraph.
+				return rs, nil
+			}
+			// The root set has converged: every root going into this iteration was
+			// already at its selected version, although we have have removed other
+			// (redundant) roots for the same path.
+			break
+		}
+	}
+
+	if rs.depth == lazy && reflect.DeepEqual(roots, rs.rootModules) && reflect.DeepEqual(direct, rs.direct) {
+		// The root set is unchanged and rs was already lazy, so keep rs to
+		// preserve its cached ModuleGraph (if any).
+		return rs, nil
+	}
+	return newRequirements(lazy, roots, direct), nil
+}
+
+// spotCheckRoots reports whether the versions of the roots in rs satisfy the
+// explicit requirements of the modules in mods.
+func spotCheckRoots(ctx context.Context, rs *Requirements, mods map[module.Version]bool) bool {
+	ctx, cancel := context.WithCancel(ctx)
+	defer cancel()
+
+	work := par.NewQueue(runtime.GOMAXPROCS(0))
+	for m := range mods {
+		m := m
+		work.Add(func() {
+			if ctx.Err() != nil {
+				return
+			}
+
+			summary, err := goModSummary(m)
+			if err != nil {
+				cancel()
+				return
+			}
+
+			for _, r := range summary.require {
+				if v, ok := rs.rootSelected(r.Path); ok && cmpVersion(v, r.Version) < 0 {
+					cancel()
+					return
+				}
+			}
+		})
+	}
+	<-work.Idle()
+
+	if ctx.Err() != nil {
+		// Either we failed a spot-check, or the caller no longer cares about our
+		// answer anyway.
+		return false
+	}
+
+	return true
+}
+
+// tidyEagerRoots returns a minimal set of root requirements that maintains the
+// selected version of every module that provided a package in pkgs, and
+// includes the selected version of every such module in direct as a root.
+func tidyEagerRoots(ctx context.Context, direct map[string]bool, pkgs []*loadPkg) (*Requirements, error) {
+	var (
+		keep     []module.Version
+		keptPath = map[string]bool{}
+	)
+	var (
+		rootPaths   []string // module paths that should be included as roots
+		inRootPaths = map[string]bool{}
+	)
+	for _, pkg := range pkgs {
+		if !pkg.fromExternalModule() {
+			continue
+		}
+		if m := pkg.mod; !keptPath[m.Path] {
+			keep = append(keep, m)
+			keptPath[m.Path] = true
+			if direct[m.Path] && !inRootPaths[m.Path] {
+				rootPaths = append(rootPaths, m.Path)
+				inRootPaths[m.Path] = true
+			}
+		}
+	}
+
+	min, err := mvs.Req(Target, rootPaths, &mvsReqs{roots: keep})
+	if err != nil {
+		return nil, err
+	}
+	return newRequirements(eager, min, direct), nil
+}
+
+// updateEagerRoots returns a set of root requirements that includes the selected
+// version of every module path in direct as a root, and maintains the selected
+// version of every module selected in the graph of rs.
+//
+// The roots are updated such that:
+//
+// 	1. The selected version of every module path in direct is included as a root
+// 	   (if it is not "none").
+// 	2. Each root is the selected version of its path. (We say that such a root
+// 	   set is “consistent”.)
+// 	3. Every version selected in the graph of rs remains selected unless upgraded
+// 	   by a dependency in add.
+// 	4. Every version in add is selected at its given version unless upgraded by
+// 	   (the dependencies of) an existing root or another module in add.
+func updateEagerRoots(ctx context.Context, direct map[string]bool, rs *Requirements, add []module.Version) (*Requirements, error) {
+	mg, err := rs.Graph(ctx)
+	if err != nil {
+		// We can't ignore errors in the module graph even if the user passed the -e
+		// flag to try to push past them. If we can't load the complete module
+		// dependencies, then we can't reliably compute a minimal subset of them.
+		return rs, err
+	}
+
+	if cfg.BuildMod != "mod" {
+		// Instead of actually updating the requirements, just check that no updates
+		// are needed.
+		if rs == nil {
+			// We're being asked to reconstruct the requirements from scratch,
+			// but we aren't even allowed to modify them.
+			return rs, errGoModDirty
+		}
+		for _, m := range rs.rootModules {
+			if m.Version != mg.Selected(m.Path) {
+				// The root version v is misleading: the actual selected version is higher.
+				return rs, errGoModDirty
+			}
+		}
+		for _, m := range add {
+			if m.Version != mg.Selected(m.Path) {
+				return rs, errGoModDirty
+			}
+		}
+		for mPath := range direct {
+			if _, ok := rs.rootSelected(mPath); !ok {
+				// Module m is supposed to be listed explicitly, but isn't.
+				//
+				// Note that this condition is also detected (and logged with more
+				// detail) earlier during package loading, so it shouldn't actually be
+				// possible at this point — this is just a defense in depth.
+				return rs, errGoModDirty
+			}
+		}
+
+		// No explicit roots are missing and all roots are already at the versions
+		// we want to keep. Any other changes we would make are purely cosmetic,
+		// such as pruning redundant indirect dependencies. Per issue #34822, we
+		// ignore cosmetic changes when we cannot update the go.mod file.
+		return rs, nil
+	}
+
+	var (
+		rootPaths   []string // module paths that should be included as roots
+		inRootPaths = map[string]bool{}
+	)
+	for _, root := range rs.rootModules {
+		// If the selected version of the root is the same as what was already
+		// listed in the go.mod file, retain it as a root (even if redundant) to
+		// avoid unnecessary churn. (See https://golang.org/issue/34822.)
+		//
+		// We do this even for indirect requirements, since we don't know why they
+		// were added and they could become direct at any time.
+		if !inRootPaths[root.Path] && mg.Selected(root.Path) == root.Version {
+			rootPaths = append(rootPaths, root.Path)
+			inRootPaths[root.Path] = true
+		}
+	}
+
+	// “The selected version of every module path in direct is included as a root.”
+	//
+	// This is only for convenience and clarity for end users: in an eager module,
+	// the choice of explicit vs. implicit dependency has no impact on MVS
+	// selection (for itself or any other module).
+	keep := append(mg.BuildList()[1:], add...)
+	for _, m := range keep {
+		if direct[m.Path] && !inRootPaths[m.Path] {
+			rootPaths = append(rootPaths, m.Path)
+			inRootPaths[m.Path] = true
+		}
+	}
+
+	min, err := mvs.Req(Target, rootPaths, &mvsReqs{roots: keep})
+	if err != nil {
+		return rs, err
+	}
+	if rs.depth == eager && reflect.DeepEqual(min, rs.rootModules) && reflect.DeepEqual(direct, rs.direct) {
+		// The root set is unchanged and rs was already eager, so keep rs to
+		// preserve its cached ModuleGraph (if any).
+		return rs, nil
+	}
+	return newRequirements(eager, min, direct), nil
+}
+
+// convertDepth returns a version of rs with the given depth.
+// If rs already has the given depth, convertDepth returns rs unmodified.
+func convertDepth(ctx context.Context, rs *Requirements, depth modDepth) (*Requirements, error) {
+	if rs.depth == depth {
+		return rs, nil
+	}
+
+	if depth == eager {
+		// We are converting a lazy module to an eager one. The roots of an eager
+		// module graph are a superset of the roots of a lazy graph, so we don't
+		// need to add any new roots — we just need to prune away the ones that are
+		// redundant given eager loading, which is exactly what updateEagerRoots
+		// does.
+		return updateEagerRoots(ctx, rs.direct, rs, nil)
+	}
+
+	// We are converting an eager module to a lazy one. The module graph of an
+	// eager module includes the transitive dependencies of every module in the
+	// build list.
+	//
+	// Hey, we can express that as a lazy root set! “Include the transitive
+	// dependencies of every module in the build list” is exactly what happens in
+	// a lazy module if we promote every module in the build list to a root!
+	mg, err := rs.Graph(ctx)
+	if err != nil {
+		return rs, err
+	}
+	return newRequirements(lazy, mg.BuildList()[1:], rs.direct), nil
 }
diff --git a/src/cmd/go/internal/modload/edit.go b/src/cmd/go/internal/modload/edit.go
new file mode 100644
index 0000000..c350b9d
--- /dev/null
+++ b/src/cmd/go/internal/modload/edit.go
@@ -0,0 +1,569 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package modload
+
+import (
+	"cmd/go/internal/mvs"
+	"context"
+	"reflect"
+	"sort"
+
+	"golang.org/x/mod/module"
+	"golang.org/x/mod/semver"
+)
+
+// editRequirements returns an edited version of rs such that:
+//
+// 	1. Each module version in mustSelect is selected.
+//
+// 	2. Each module version in tryUpgrade is upgraded toward the indicated
+// 	   version as far as can be done without violating (1).
+//
+// 	3. Each module version in rs.rootModules (or rs.graph, if rs.depth is eager)
+// 	   is downgraded from its original version only to the extent needed to
+// 	   satisfy (1), or upgraded only to the extent needed to satisfy (1) and
+// 	   (2).
+//
+// 	4. No module is upgraded above the maximum version of its path found in the
+// 	   dependency graph of rs, the combined dependency graph of the versions in
+// 	   mustSelect, or the dependencies of each individual module version in
+// 	   tryUpgrade.
+//
+// Generally, the module versions in mustSelect are due to the module or a
+// package within the module matching an explicit command line argument to 'go
+// get', and the versions in tryUpgrade are transitive dependencies that are
+// either being upgraded by 'go get -u' or being added to satisfy some
+// otherwise-missing package import.
+func editRequirements(ctx context.Context, rs *Requirements, tryUpgrade, mustSelect []module.Version) (edited *Requirements, changed bool, err error) {
+	limiter, err := limiterForEdit(ctx, rs, tryUpgrade, mustSelect)
+	if err != nil {
+		return rs, false, err
+	}
+
+	var conflicts []Conflict
+	for _, m := range mustSelect {
+		conflict, err := limiter.Select(m)
+		if err != nil {
+			return rs, false, err
+		}
+		if conflict.Path != "" {
+			conflicts = append(conflicts, Conflict{
+				Source: m,
+				Dep:    conflict,
+				Constraint: module.Version{
+					Path:    conflict.Path,
+					Version: limiter.max[conflict.Path],
+				},
+			})
+		}
+	}
+	if len(conflicts) > 0 {
+		return rs, false, &ConstraintError{Conflicts: conflicts}
+	}
+
+	mods, changed, err := selectPotentiallyImportedModules(ctx, limiter, rs, tryUpgrade)
+	if err != nil {
+		return rs, false, err
+	}
+
+	var roots []module.Version
+	if rs.depth == eager {
+		// In an eager module, modules that provide packages imported by the main
+		// module may either be explicit roots or implicit transitive dependencies.
+		// We promote the modules in mustSelect to be explicit requirements.
+		var rootPaths []string
+		for _, m := range mustSelect {
+			if m.Version != "none" && m.Path != Target.Path {
+				rootPaths = append(rootPaths, m.Path)
+			}
+		}
+		if !changed && len(rootPaths) == 0 {
+			// The build list hasn't changed and we have no new roots to add.
+			// We don't need to recompute the minimal roots for the module.
+			return rs, false, nil
+		}
+
+		for _, m := range mods {
+			if v, ok := rs.rootSelected(m.Path); ok && (v == m.Version || rs.direct[m.Path]) {
+				// m.Path was formerly a root, and either its version hasn't changed or
+				// we believe that it provides a package directly imported by a package
+				// or test in the main module. For now we'll assume that it is still
+				// relevant enough to remain a root. If we actually load all of the
+				// packages and tests in the main module (which we are not doing here),
+				// we can revise the explicit roots at that point.
+				rootPaths = append(rootPaths, m.Path)
+			}
+		}
+
+		roots, err = mvs.Req(Target, rootPaths, &mvsReqs{roots: mods})
+		if err != nil {
+			return nil, false, err
+		}
+	} else {
+		// In a lazy module, every module that provides a package imported by the
+		// main module must be retained as a root.
+		roots = mods
+		if !changed {
+			// Because the roots we just computed are unchanged, the entire graph must
+			// be the same as it was before. Save the original rs, since we have
+			// probably already loaded its requirement graph.
+			return rs, false, nil
+		}
+	}
+
+	// A module that is not even in the build list necessarily cannot provide
+	// any imported packages. Mark as direct only the direct modules that are
+	// still in the build list.
+	//
+	// TODO(bcmills): Would it make more sense to leave the direct map as-is
+	// but allow it to refer to modules that are no longer in the build list?
+	// That might complicate updateRoots, but it may be cleaner in other ways.
+	direct := make(map[string]bool, len(rs.direct))
+	for _, m := range roots {
+		if rs.direct[m.Path] {
+			direct[m.Path] = true
+		}
+	}
+	return newRequirements(rs.depth, roots, direct), changed, nil
+}
+
+// limiterForEdit returns a versionLimiter with its max versions set such that
+// the max version for every module path in mustSelect is the version listed
+// there, and the max version for every other module path is the maximum version
+// of its path found in the dependency graph of rs, the combined dependency
+// graph of the versions in mustSelect, or the dependencies of each individual
+// module version in tryUpgrade.
+func limiterForEdit(ctx context.Context, rs *Requirements, tryUpgrade, mustSelect []module.Version) (*versionLimiter, error) {
+	mg, err := rs.Graph(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	maxVersion := map[string]string{} // module path → version
+	restrictTo := func(m module.Version) {
+		v, ok := maxVersion[m.Path]
+		if !ok || cmpVersion(v, m.Version) > 0 {
+			maxVersion[m.Path] = m.Version
+		}
+	}
+
+	if rs.depth == eager {
+		// Eager go.mod files don't indicate which transitive dependencies are
+		// actually relevant to the main module, so we have to assume that any module
+		// that could have provided any package — that is, any module whose selected
+		// version was not "none" — may be relevant.
+		for _, m := range mg.BuildList() {
+			restrictTo(m)
+		}
+	} else {
+		// The go.mod file explicitly records every module that provides a package
+		// imported by the main module.
+		//
+		// If we need to downgrade an existing root or a new root found in
+		// tryUpgrade, we don't want to allow that downgrade to incidentally upgrade
+		// a module imported by the main module to some arbitrary version.
+		// However, we don't particularly care about arbitrary upgrades to modules
+		// that are (at best) only providing packages imported by tests of
+		// dependencies outside the main module.
+		for _, m := range rs.rootModules {
+			restrictTo(module.Version{
+				Path:    m.Path,
+				Version: mg.Selected(m.Path),
+			})
+		}
+	}
+
+	if err := raiseLimitsForUpgrades(ctx, maxVersion, rs.depth, tryUpgrade, mustSelect); err != nil {
+		return nil, err
+	}
+
+	// The versions in mustSelect override whatever we would naively select —
+	// we will downgrade other modules as needed in order to meet them.
+	for _, m := range mustSelect {
+		restrictTo(m)
+	}
+
+	return newVersionLimiter(rs.depth, maxVersion), nil
+}
+
+// raiseLimitsForUpgrades increases the module versions in maxVersions to the
+// versions that would be needed to allow each of the modules in tryUpgrade
+// (individually) and all of the modules in mustSelect (simultaneously) to be
+// added as roots.
+//
+// Versions not present in maxVersion are unrestricted, and it is assumed that
+// they will not be promoted to root requirements (and thus will not contribute
+// their own dependencies if the main module is lazy).
+//
+// These limits provide an upper bound on how far a module may be upgraded as
+// part of an incidental downgrade, if downgrades are needed in order to select
+// the versions in mustSelect.
+func raiseLimitsForUpgrades(ctx context.Context, maxVersion map[string]string, depth modDepth, tryUpgrade []module.Version, mustSelect []module.Version) error {
+	// allow raises the limit for m.Path to at least m.Version.
+	// If m.Path was already unrestricted, it remains unrestricted.
+	allow := func(m module.Version) {
+		v, ok := maxVersion[m.Path]
+		if !ok {
+			return // m.Path is unrestricted.
+		}
+		if cmpVersion(v, m.Version) < 0 {
+			maxVersion[m.Path] = m.Version
+		}
+	}
+
+	var eagerUpgrades []module.Version
+	if depth == eager {
+		eagerUpgrades = tryUpgrade
+	} else {
+		for _, m := range tryUpgrade {
+			if m.Path == Target.Path {
+				// Target is already considered to be higher than any possible m, so we
+				// won't be upgrading to it anyway and there is no point scanning its
+				// dependencies.
+				continue
+			}
+
+			summary, err := goModSummary(m)
+			if err != nil {
+				return err
+			}
+			if summary.depth == eager {
+				// For efficiency, we'll load all of the eager upgrades as one big
+				// graph, rather than loading the (potentially-overlapping) subgraph for
+				// each upgrade individually.
+				eagerUpgrades = append(eagerUpgrades, m)
+				continue
+			}
+
+			for _, r := range summary.require {
+				allow(r)
+			}
+		}
+	}
+
+	if len(eagerUpgrades) > 0 {
+		// Compute the max versions for eager upgrades all together.
+		// Since these modules are eager, we'll end up scanning all of their
+		// transitive dependencies no matter which versions end up selected,
+		// and since we have a large dependency graph to scan we might get
+		// a significant benefit from not revisiting dependencies that are at
+		// common versions among multiple upgrades.
+		upgradeGraph, err := readModGraph(ctx, eager, eagerUpgrades)
+		if err != nil {
+			if go117LazyTODO {
+				// Compute the requirement path from a module path in tryUpgrade to the
+				// error, and the requirement path (if any) from rs.rootModules to the
+				// tryUpgrade module path. Return a *mvs.BuildListError showing the
+				// concatenation of the paths (with an upgrade in the middle).
+			}
+			return err
+		}
+
+		for _, r := range upgradeGraph.BuildList() {
+			// Upgrading to m would upgrade to r, and the caller requested that we
+			// try to upgrade to m, so it's ok to upgrade to r.
+			allow(r)
+		}
+	}
+
+	if len(mustSelect) > 0 {
+		mustGraph, err := readModGraph(ctx, depth, mustSelect)
+		if err != nil {
+			return err
+		}
+
+		for _, r := range mustGraph.BuildList() {
+			// Some module in mustSelect requires r, so we must allow at least r.Version
+			// unless it conflicts with an entry in mustSelect.
+			allow(r)
+		}
+	}
+
+	return nil
+}
+
+// selectPotentiallyImportedModules increases the limiter-selected version of
+// every module in rs that potentially provides a package imported (directly or
+// indirectly) by the main module, and every module in tryUpgrade, toward the
+// highest version seen in rs or tryUpgrade, but not above the maximums enforced
+// by the limiter.
+//
+// It returns the list of module versions selected by the limiter, sorted by
+// path, along with a boolean indicating whether that list is different from the
+// list of modules read from rs.
+func selectPotentiallyImportedModules(ctx context.Context, limiter *versionLimiter, rs *Requirements, tryUpgrade []module.Version) (mods []module.Version, changed bool, err error) {
+	for _, m := range tryUpgrade {
+		if err := limiter.UpgradeToward(ctx, m); err != nil {
+			return nil, false, err
+		}
+	}
+
+	var initial []module.Version
+	if rs.depth == eager {
+		mg, err := rs.Graph(ctx)
+		if err != nil {
+			return nil, false, err
+		}
+		initial = mg.BuildList()[1:]
+	} else {
+		initial = rs.rootModules
+	}
+	for _, m := range initial {
+		if err := limiter.UpgradeToward(ctx, m); err != nil {
+			return nil, false, err
+		}
+	}
+
+	mods = make([]module.Version, 0, len(limiter.selected))
+	for path, v := range limiter.selected {
+		if v != "none" && path != Target.Path {
+			mods = append(mods, module.Version{Path: path, Version: v})
+		}
+	}
+
+	// We've identified acceptable versions for each of the modules, but those
+	// versions are not necessarily consistent with each other: one upgraded or
+	// downgraded module may require a higher (but still allowed) version of
+	// another. The lower version may require extraneous dependencies that aren't
+	// actually relevant, so we need to compute the actual selected versions.
+	mg, err := readModGraph(ctx, rs.depth, mods)
+	if err != nil {
+		return nil, false, err
+	}
+	mods = make([]module.Version, 0, len(limiter.selected))
+	for path, _ := range limiter.selected {
+		if path != Target.Path {
+			if v := mg.Selected(path); v != "none" {
+				mods = append(mods, module.Version{Path: path, Version: v})
+			}
+		}
+	}
+	module.Sort(mods)
+
+	changed = !reflect.DeepEqual(mods, initial)
+
+	return mods, changed, err
+}
+
+// A versionLimiter tracks the versions that may be selected for each module
+// subject to constraints on the maximum versions of transitive dependencies.
+type versionLimiter struct {
+	// depth is the depth at which the dependencies of the modules passed to
+	// Select and UpgradeToward are loaded.
+	depth modDepth
+
+	// max maps each module path to the maximum version that may be selected for
+	// that path.
+	//
+	// Paths with no entry are unrestricted, and we assume that they will not be
+	// promoted to root dependencies (so will not contribute dependencies if the
+	// main module is lazy).
+	max map[string]string
+
+	// selected maps each module path to a version of that path (if known) whose
+	// transitive dependencies do not violate any max version. The version kept
+	// is the highest one found during any call to UpgradeToward for the given
+	// module path.
+	//
+	// If a higher acceptable version is found during a call to UpgradeToward for
+	// some *other* module path, that does not update the selected version.
+	// Ignoring those versions keeps the downgrades computed for two modules
+	// together close to the individual downgrades that would be computed for each
+	// module in isolation. (The only way one module can affect another is if the
+	// final downgraded version of the one module explicitly requires a higher
+	// version of the other.)
+	//
+	// Version "none" of every module is always known not to violate any max
+	// version, so paths at version "none" are omitted.
+	selected map[string]string
+
+	// dqReason records whether and why each each encountered version is
+	// disqualified.
+	dqReason map[module.Version]dqState
+
+	// requiring maps each not-yet-disqualified module version to the versions
+	// that directly require it. If that version becomes disqualified, the
+	// disqualification will be propagated to all of the versions in the list.
+	requiring map[module.Version][]module.Version
+}
+
+// A dqState indicates whether and why a module version is “disqualified” from
+// being used in a way that would incorporate its requirements.
+//
+// The zero dqState indicates that the module version is not known to be
+// disqualified, either because it is ok or because we are currently traversing
+// a cycle that includes it.
+type dqState struct {
+	err      error          // if non-nil, disqualified because the requirements of the module could not be read
+	conflict module.Version // disqualified because the module (transitively) requires dep, which exceeds the maximum version constraint for its path
+}
+
+func (dq dqState) isDisqualified() bool {
+	return dq != dqState{}
+}
+
+// newVersionLimiter returns a versionLimiter that restricts the module paths
+// that appear as keys in max.
+//
+// max maps each module path to its maximum version; paths that are not present
+// in the map are unrestricted. The limiter assumes that unrestricted paths will
+// not be promoted to root dependencies.
+//
+// If depth is lazy, then if a module passed to UpgradeToward or Select is
+// itself lazy, its unrestricted dependencies are skipped when scanning
+// requirements.
+func newVersionLimiter(depth modDepth, max map[string]string) *versionLimiter {
+	return &versionLimiter{
+		depth:     depth,
+		max:       max,
+		selected:  map[string]string{Target.Path: Target.Version},
+		dqReason:  map[module.Version]dqState{},
+		requiring: map[module.Version][]module.Version{},
+	}
+}
+
+// UpgradeToward attempts to upgrade the selected version of m.Path as close as
+// possible to m.Version without violating l's maximum version limits.
+//
+// If depth is lazy and m itself is lazy, the the dependencies of unrestricted
+// dependencies of m will not be followed.
+func (l *versionLimiter) UpgradeToward(ctx context.Context, m module.Version) error {
+	selected, ok := l.selected[m.Path]
+	if ok {
+		if cmpVersion(selected, m.Version) >= 0 {
+			// The selected version is already at least m, so no upgrade is needed.
+			return nil
+		}
+	} else {
+		selected = "none"
+	}
+
+	if l.check(m, l.depth).isDisqualified() {
+		candidates, err := versions(ctx, m.Path, CheckAllowed)
+		if err != nil {
+			// This is likely a transient error reaching the repository,
+			// rather than a permanent error with the retrieved version.
+			//
+			// TODO(golang.org/issue/31730, golang.org/issue/30134):
+			// decode what to do based on the actual error.
+			return err
+		}
+
+		// Skip to candidates < m.Version.
+		i := sort.Search(len(candidates), func(i int) bool {
+			return semver.Compare(candidates[i], m.Version) >= 0
+		})
+		candidates = candidates[:i]
+
+		for l.check(m, l.depth).isDisqualified() {
+			n := len(candidates)
+			if n == 0 || cmpVersion(selected, candidates[n-1]) >= 0 {
+				// We couldn't find a suitable candidate above the already-selected version.
+				// Retain that version unmodified.
+				return nil
+			}
+			m.Version, candidates = candidates[n-1], candidates[:n-1]
+		}
+	}
+
+	l.selected[m.Path] = m.Version
+	return nil
+}
+
+// Select attempts to set the selected version of m.Path to exactly m.Version.
+func (l *versionLimiter) Select(m module.Version) (conflict module.Version, err error) {
+	dq := l.check(m, l.depth)
+	if !dq.isDisqualified() {
+		l.selected[m.Path] = m.Version
+	}
+	return dq.conflict, dq.err
+}
+
+// check determines whether m (or its transitive dependencies) would violate l's
+// maximum version limits if added to the module requirement graph.
+//
+// If depth is lazy and m itself is lazy, then the dependencies of unrestricted
+// dependencies of m will not be followed. If the lazy loading invariants hold
+// for the main module up to this point, the packages in those modules are at
+// best only imported by tests of dependencies that are themselves loaded from
+// outside modules. Although we would like to keep 'go test all' as reproducible
+// as is feasible, we don't want to retain test dependencies that are only
+// marginally relevant at best.
+func (l *versionLimiter) check(m module.Version, depth modDepth) dqState {
+	if m.Version == "none" || m == Target {
+		// version "none" has no requirements, and the dependencies of Target are
+		// tautological.
+		return dqState{}
+	}
+
+	if dq, seen := l.dqReason[m]; seen {
+		return dq
+	}
+	l.dqReason[m] = dqState{}
+
+	if max, ok := l.max[m.Path]; ok && cmpVersion(m.Version, max) > 0 {
+		return l.disqualify(m, dqState{conflict: m})
+	}
+
+	summary, err := goModSummary(m)
+	if err != nil {
+		// If we can't load the requirements, we couldn't load the go.mod file.
+		// There are a number of reasons this can happen, but this usually
+		// means an older version of the module had a missing or invalid
+		// go.mod file. For example, if example.com/mod released v2.0.0 before
+		// migrating to modules (v2.0.0+incompatible), then added a valid go.mod
+		// in v2.0.1, downgrading from v2.0.1 would cause this error.
+		//
+		// TODO(golang.org/issue/31730, golang.org/issue/30134): if the error
+		// is transient (we couldn't download go.mod), return the error from
+		// Downgrade. Currently, we can't tell what kind of error it is.
+		return l.disqualify(m, dqState{err: err})
+	}
+
+	if summary.depth == eager {
+		depth = eager
+	}
+	for _, r := range summary.require {
+		if depth == lazy {
+			if _, restricted := l.max[r.Path]; !restricted {
+				// r.Path is unrestricted, so we don't care at what version it is
+				// selected. We assume that r.Path will not become a root dependency, so
+				// since m is lazy, r's dependencies won't be followed.
+				continue
+			}
+		}
+
+		if dq := l.check(r, depth); dq.isDisqualified() {
+			return l.disqualify(m, dq)
+		}
+
+		// r and its dependencies are (perhaps provisionally) ok.
+		//
+		// However, if there are cycles in the requirement graph, we may have only
+		// checked a portion of the requirement graph so far, and r (and thus m) may
+		// yet be disqualified by some path we have not yet visited. Remember this edge
+		// so that we can disqualify m and its dependents if that occurs.
+		l.requiring[r] = append(l.requiring[r], m)
+	}
+
+	return dqState{}
+}
+
+// disqualify records that m (or one of its transitive dependencies)
+// violates l's maximum version limits.
+func (l *versionLimiter) disqualify(m module.Version, dq dqState) dqState {
+	if dq := l.dqReason[m]; dq.isDisqualified() {
+		return dq
+	}
+	l.dqReason[m] = dq
+
+	for _, p := range l.requiring[m] {
+		l.disqualify(p, dqState{conflict: m})
+	}
+	// Now that we have disqualified the modules that depend on m, we can forget
+	// about them — we won't need to disqualify them again.
+	delete(l.requiring, m)
+	return dq
+}
diff --git a/src/cmd/go/internal/modload/help.go b/src/cmd/go/internal/modload/help.go
index fd39ddd..886ad62 100644
--- a/src/cmd/go/internal/modload/help.go
+++ b/src/cmd/go/internal/modload/help.go
@@ -46,7 +46,7 @@
 The go.mod file format is described in detail at
 https://golang.org/ref/mod#go-mod-file.
 
-To create a new go.mod file, use 'go help init'. For details see
+To create a new go.mod file, use 'go mod init'. For details see
 'go help mod init' or https://golang.org/ref/mod#go-mod-init.
 
 To add missing module requirements or remove unneeded requirements,
diff --git a/src/cmd/go/internal/modload/import.go b/src/cmd/go/internal/modload/import.go
index 995641c..d2bbe5c 100644
--- a/src/cmd/go/internal/modload/import.go
+++ b/src/cmd/go/internal/modload/import.go
@@ -12,6 +12,7 @@
 	"internal/goroot"
 	"io/fs"
 	"os"
+	pathpkg "path"
 	"path/filepath"
 	"sort"
 	"strings"
@@ -60,7 +61,7 @@
 
 		if e.replaced.Path != "" {
 			suggestArg := e.replaced.Path
-			if !modfetch.IsZeroPseudoVersion(e.replaced.Version) {
+			if !module.IsZeroPseudoVersion(e.replaced.Version) {
 				suggestArg = e.replaced.String()
 			}
 			return fmt.Sprintf("module %s provides package %s and is replaced but not required; to add it:\n\tgo get %s", e.replaced.Path, e.Path, suggestArg)
@@ -127,6 +128,23 @@
 	return buf.String()
 }
 
+// A DirectImportFromImplicitDependencyError indicates a package directly
+// imported by a package or test in the main module that is satisfied by a
+// dependency that is not explicit in the main module's go.mod file.
+type DirectImportFromImplicitDependencyError struct {
+	ImporterPath string
+	ImportedPath string
+	Module       module.Version
+}
+
+func (e *DirectImportFromImplicitDependencyError) Error() string {
+	return fmt.Sprintf("package %s imports %s from implicitly required module; to add missing requirements, run:\n\tgo get %s@%s", e.ImporterPath, e.ImportedPath, e.Module.Path, e.Module.Version)
+}
+
+func (e *DirectImportFromImplicitDependencyError) ImportPath() string {
+	return e.ImporterPath
+}
+
 // ImportMissingSumError is reported in readonly mode when we need to check
 // if a module contains a package, but we don't have a sum for its .zip file.
 // We might need sums for multiple modules to verify the package is unique.
@@ -160,11 +178,13 @@
 		// Importing package is unknown, or the missing package was named on the
 		// command line. Recommend 'go mod download' for the modules that could
 		// provide the package, since that shouldn't change go.mod.
-		args := make([]string, len(e.mods))
-		for i, mod := range e.mods {
-			args[i] = mod.Path
+		if len(e.mods) > 0 {
+			args := make([]string, len(e.mods))
+			for i, mod := range e.mods {
+				args[i] = mod.Path
+			}
+			hint = fmt.Sprintf("; to add:\n\tgo mod download %s", strings.Join(args, " "))
 		}
-		hint = fmt.Sprintf("; to add:\n\tgo mod download %s", strings.Join(args, " "))
 	} else {
 		// Importing package is known (common case). Recommend 'go get' on the
 		// current version of the importing package.
@@ -202,28 +222,31 @@
 	return e.err
 }
 
-// importFromBuildList finds the module and directory in the build list
-// containing the package with the given import path. The answer must be unique:
-// importFromBuildList returns an error if multiple modules attempt to provide
-// the same package.
+// importFromModules finds the module and directory in the dependency graph of
+// rs containing the package with the given import path. If mg is nil,
+// importFromModules attempts to locate the module using only the main module
+// and the roots of rs before it loads the full graph.
 //
-// importFromBuildList can return a module with an empty m.Path, for packages in
+// The answer must be unique: importFromModules returns an error if multiple
+// modules are observed to provide the same package.
+//
+// importFromModules can return a module with an empty m.Path, for packages in
 // the standard library.
 //
-// importFromBuildList can return an empty directory string, for fake packages
+// importFromModules can return an empty directory string, for fake packages
 // like "C" and "unsafe".
 //
-// If the package cannot be found in buildList,
-// importFromBuildList returns an *ImportMissingError.
-func importFromBuildList(ctx context.Context, path string, buildList []module.Version) (m module.Version, dir string, err error) {
+// If the package is not present in any module selected from the requirement
+// graph, importFromModules returns an *ImportMissingError.
+func importFromModules(ctx context.Context, path string, rs *Requirements, mg *ModuleGraph) (m module.Version, dir string, err error) {
 	if strings.Contains(path, "@") {
 		return module.Version{}, "", fmt.Errorf("import path should not have @version")
 	}
 	if build.IsLocalImport(path) {
 		return module.Version{}, "", fmt.Errorf("relative import not supported")
 	}
-	if path == "C" || path == "unsafe" {
-		// There's no directory for import "C" or import "unsafe".
+	if path == "C" {
+		// There's no directory for import "C".
 		return module.Version{}, "", nil
 	}
 	// Before any further lookup, check that the path is valid.
@@ -269,58 +292,114 @@
 	// Check each module on the build list.
 	var dirs []string
 	var mods []module.Version
-	var sumErrMods []module.Version
-	for _, m := range buildList {
-		if !maybeInModule(path, m.Path) {
-			// Avoid possibly downloading irrelevant modules.
-			continue
-		}
-		needSum := true
-		root, isLocal, err := fetch(ctx, m, needSum)
-		if err != nil {
-			if sumErr := (*sumMissingError)(nil); errors.As(err, &sumErr) {
-				// We are missing a sum needed to fetch a module in the build list.
-				// We can't verify that the package is unique, and we may not find
-				// the package at all. Keep checking other modules to decide which
-				// error to report. Multiple sums may be missing if we need to look in
-				// multiple nested modules to resolve the import.
-				sumErrMods = append(sumErrMods, m)
+
+	// Iterate over possible modules for the path, not all selected modules.
+	// Iterating over selected modules would make the overall loading time
+	// O(M × P) for M modules providing P imported packages, whereas iterating
+	// over path prefixes is only O(P × k) with maximum path depth k. For
+	// large projects both M and P may be very large (note that M ≤ P), but k
+	// will tend to remain smallish (if for no other reason than filesystem
+	// path limitations).
+	//
+	// We perform this iteration either one or two times. If mg is initially nil,
+	// then we first attempt to load the package using only the main module and
+	// its root requirements. If that does not identify the package, or if mg is
+	// already non-nil, then we attempt to load the package using the full
+	// requirements in mg.
+	for {
+		var sumErrMods []module.Version
+		for prefix := path; prefix != "."; prefix = pathpkg.Dir(prefix) {
+			var (
+				v  string
+				ok bool
+			)
+			if mg == nil {
+				v, ok = rs.rootSelected(prefix)
+			} else {
+				v, ok = mg.Selected(prefix), true
+			}
+			if !ok || v == "none" {
 				continue
 			}
-			// Report fetch error.
-			// Note that we don't know for sure this module is necessary,
-			// but it certainly _could_ provide the package, and even if we
-			// continue the loop and find the package in some other module,
-			// we need to look at this module to make sure the import is
-			// not ambiguous.
-			return module.Version{}, "", err
-		}
-		if dir, ok, err := dirInModule(path, m.Path, root, isLocal); err != nil {
-			return module.Version{}, "", err
-		} else if ok {
-			mods = append(mods, m)
-			dirs = append(dirs, dir)
-		}
-	}
-	if len(mods) > 1 {
-		return module.Version{}, "", &AmbiguousImportError{importPath: path, Dirs: dirs, Modules: mods}
-	}
-	if len(sumErrMods) > 0 {
-		return module.Version{}, "", &ImportMissingSumError{
-			importPath: path,
-			mods:       sumErrMods,
-			found:      len(mods) > 0,
-		}
-	}
-	if len(mods) == 1 {
-		return mods[0], dirs[0], nil
-	}
+			m := module.Version{Path: prefix, Version: v}
 
-	var queryErr error
-	if !HasModRoot() {
-		queryErr = ErrNoModRoot
+			needSum := true
+			root, isLocal, err := fetch(ctx, m, needSum)
+			if err != nil {
+				if sumErr := (*sumMissingError)(nil); errors.As(err, &sumErr) {
+					// We are missing a sum needed to fetch a module in the build list.
+					// We can't verify that the package is unique, and we may not find
+					// the package at all. Keep checking other modules to decide which
+					// error to report. Multiple sums may be missing if we need to look in
+					// multiple nested modules to resolve the import; we'll report them all.
+					sumErrMods = append(sumErrMods, m)
+					continue
+				}
+				// Report fetch error.
+				// Note that we don't know for sure this module is necessary,
+				// but it certainly _could_ provide the package, and even if we
+				// continue the loop and find the package in some other module,
+				// we need to look at this module to make sure the import is
+				// not ambiguous.
+				return module.Version{}, "", err
+			}
+			if dir, ok, err := dirInModule(path, m.Path, root, isLocal); err != nil {
+				return module.Version{}, "", err
+			} else if ok {
+				mods = append(mods, m)
+				dirs = append(dirs, dir)
+			}
+		}
+
+		if len(mods) > 1 {
+			// We produce the list of directories from longest to shortest candidate
+			// module path, but the AmbiguousImportError should report them from
+			// shortest to longest. Reverse them now.
+			for i := 0; i < len(mods)/2; i++ {
+				j := len(mods) - 1 - i
+				mods[i], mods[j] = mods[j], mods[i]
+				dirs[i], dirs[j] = dirs[j], dirs[i]
+			}
+			return module.Version{}, "", &AmbiguousImportError{importPath: path, Dirs: dirs, Modules: mods}
+		}
+
+		if len(sumErrMods) > 0 {
+			for i := 0; i < len(sumErrMods)/2; i++ {
+				j := len(sumErrMods) - 1 - i
+				sumErrMods[i], sumErrMods[j] = sumErrMods[j], sumErrMods[i]
+			}
+			return module.Version{}, "", &ImportMissingSumError{
+				importPath: path,
+				mods:       sumErrMods,
+				found:      len(mods) > 0,
+			}
+		}
+
+		if len(mods) == 1 {
+			return mods[0], dirs[0], nil
+		}
+
+		if mg != nil {
+			// We checked the full module graph and still didn't find the
+			// requested package.
+			var queryErr error
+			if !HasModRoot() {
+				queryErr = ErrNoModRoot
+			}
+			return module.Version{}, "", &ImportMissingError{Path: path, QueryErr: queryErr, isStd: pathIsStd}
+		}
+
+		// So far we've checked the root dependencies.
+		// Load the full module graph and try again.
+		mg, err = rs.Graph(ctx)
+		if err != nil {
+			// We might be missing one or more transitive (implicit) dependencies from
+			// the module graph, so we can't return an ImportMissingError here — one
+			// of the missing modules might actually contain the package in question,
+			// in which case we shouldn't go looking for it in some new dependency.
+			return module.Version{}, "", err
+		}
 	}
-	return module.Version{}, "", &ImportMissingError{Path: path, QueryErr: queryErr, isStd: pathIsStd}
 }
 
 // queryImport attempts to locate a module that can be added to the current
@@ -328,7 +407,7 @@
 //
 // Unlike QueryPattern, queryImport prefers to add a replaced version of a
 // module *before* checking the proxies for a version to add.
-func queryImport(ctx context.Context, path string) (module.Version, error) {
+func queryImport(ctx context.Context, path string, rs *Requirements) (module.Version, error) {
 	// To avoid spurious remote fetches, try the latest replacement for each
 	// module (golang.org/issue/26241).
 	if index != nil {
@@ -344,11 +423,20 @@
 				// used from within some other module, the user will be able to upgrade
 				// the requirement to any real version they choose.
 				if _, pathMajor, ok := module.SplitPathVersion(mp); ok && len(pathMajor) > 0 {
-					mv = modfetch.ZeroPseudoVersion(pathMajor[1:])
+					mv = module.ZeroPseudoVersion(pathMajor[1:])
 				} else {
-					mv = modfetch.ZeroPseudoVersion("v0")
+					mv = module.ZeroPseudoVersion("v0")
 				}
 			}
+			mg, err := rs.Graph(ctx)
+			if err != nil {
+				return module.Version{}, err
+			}
+			if cmpVersion(mg.Selected(mp), mv) >= 0 {
+				// We can't resolve the import by adding mp@mv to the module graph,
+				// because the selected version of mp is already at least mv.
+				continue
+			}
 			mods = append(mods, module.Version{Path: mp, Version: mv})
 		}
 
@@ -417,7 +505,12 @@
 	// and return m, dir, ImpportMissingError.
 	fmt.Fprintf(os.Stderr, "go: finding module for package %s\n", path)
 
-	candidates, err := QueryPackages(ctx, path, "latest", Selected, CheckAllowed)
+	mg, err := rs.Graph(ctx)
+	if err != nil {
+		return module.Version{}, err
+	}
+
+	candidates, err := QueryPackages(ctx, path, "latest", mg.Selected, CheckAllowed)
 	if err != nil {
 		if errors.Is(err, fs.ErrNotExist) {
 			// Return "cannot find module providing package […]" instead of whatever
@@ -430,28 +523,21 @@
 
 	candidate0MissingVersion := ""
 	for i, c := range candidates {
-		cm := c.Mod
-		canAdd := true
-		for _, bm := range buildList {
-			if bm.Path == cm.Path && semver.Compare(bm.Version, cm.Version) > 0 {
-				// QueryPattern proposed that we add module cm to provide the package,
-				// but we already depend on a newer version of that module (and we don't
-				// have the package).
-				//
-				// This typically happens when a package is present at the "@latest"
-				// version (e.g., v1.0.0) of a module, but we have a newer version
-				// of the same module in the build list (e.g., v1.0.1-beta), and
-				// the package is not present there.
-				canAdd = false
-				if i == 0 {
-					candidate0MissingVersion = bm.Version
-				}
-				break
+		if v := mg.Selected(c.Mod.Path); semver.Compare(v, c.Mod.Version) > 0 {
+			// QueryPattern proposed that we add module c.Mod to provide the package,
+			// but we already depend on a newer version of that module (and that
+			// version doesn't have the package).
+			//
+			// This typically happens when a package is present at the "@latest"
+			// version (e.g., v1.0.0) of a module, but we have a newer version
+			// of the same module in the build list (e.g., v1.0.1-beta), and
+			// the package is not present there.
+			if i == 0 {
+				candidate0MissingVersion = v
 			}
+			continue
 		}
-		if canAdd {
-			return cm, nil
-		}
+		return c.Mod, nil
 	}
 	return module.Version{}, &ImportMissingError{
 		Path:              path,
diff --git a/src/cmd/go/internal/modload/import_test.go b/src/cmd/go/internal/modload/import_test.go
index 9420dc5..9814588 100644
--- a/src/cmd/go/internal/modload/import_test.go
+++ b/src/cmd/go/internal/modload/import_test.go
@@ -69,11 +69,12 @@
 	RootMode = NoRoot
 
 	ctx := context.Background()
+	rs := newRequirements(eager, nil, nil)
 
 	for _, tt := range importTests {
 		t.Run(strings.ReplaceAll(tt.path, "/", "_"), func(t *testing.T) {
 			// Note that there is no build list, so Import should always fail.
-			m, err := queryImport(ctx, tt.path)
+			m, err := queryImport(ctx, tt.path, rs)
 
 			if tt.err == "" {
 				if err != nil {
diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
index 8ec1c86..45f724d 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -15,10 +15,8 @@
 	"os"
 	"path"
 	"path/filepath"
-	"sort"
 	"strconv"
 	"strings"
-	"sync"
 
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
@@ -26,32 +24,17 @@
 	"cmd/go/internal/lockedfile"
 	"cmd/go/internal/modconv"
 	"cmd/go/internal/modfetch"
-	"cmd/go/internal/mvs"
 	"cmd/go/internal/search"
-	"cmd/go/internal/str"
 
 	"golang.org/x/mod/modfile"
 	"golang.org/x/mod/module"
 	"golang.org/x/mod/semver"
 )
 
+// Variables set by other packages.
+//
+// TODO(#40775): See if these can be plumbed as explicit parameters.
 var (
-	initialized bool
-
-	modRoot string
-	Target  module.Version
-
-	// targetPrefix is the path prefix for packages in Target, without a trailing
-	// slash. For most modules, targetPrefix is just Target.Path, but the
-	// standard-library module "std" has an empty prefix.
-	targetPrefix string
-
-	// targetInGorootSrc caches whether modRoot is within GOROOT/src.
-	// The "std" module is special within GOROOT/src, but not otherwise.
-	targetInGorootSrc bool
-
-	gopath string
-
 	// RootMode determines whether a module root is needed.
 	RootMode Root
 
@@ -62,12 +45,33 @@
 	allowMissingModuleImports bool
 )
 
+// Variables set in Init.
+var (
+	initialized bool
+	modRoot     string
+	gopath      string
+)
+
+// Variables set in initTarget (during {Load,Create}ModFile).
+var (
+	Target module.Version
+
+	// targetPrefix is the path prefix for packages in Target, without a trailing
+	// slash. For most modules, targetPrefix is just Target.Path, but the
+	// standard-library module "std" has an empty prefix.
+	targetPrefix string
+
+	// targetInGorootSrc caches whether modRoot is within GOROOT/src.
+	// The "std" module is special within GOROOT/src, but not otherwise.
+	targetInGorootSrc bool
+)
+
 type Root int
 
 const (
 	// AutoRoot is the default for most commands. modload.Init will look for
 	// a go.mod file in the current directory or any parent. If none is found,
-	// modules may be disabled (GO111MODULE=on) or commands may run in a
+	// modules may be disabled (GO111MODULE=auto) or commands may run in a
 	// limited module mode.
 	AutoRoot Root = iota
 
@@ -82,7 +86,7 @@
 
 // ModFile returns the parsed go.mod file.
 //
-// Note that after calling LoadPackages or LoadAllModules,
+// Note that after calling LoadPackages or LoadModGraph,
 // the require statements in the modfile.File are no longer
 // the source of truth and will be ignored: edits made directly
 // will be lost at the next call to WriteGoMod.
@@ -131,7 +135,7 @@
 		return
 	}
 
-	if err := fsys.Init(base.Cwd); err != nil {
+	if err := fsys.Init(base.Cwd()); err != nil {
 		base.Fatalf("go: %v", err)
 	}
 
@@ -159,7 +163,11 @@
 	// assume they know what they are doing and don't step on it.
 	// But default to turning off ControlMaster.
 	if os.Getenv("GIT_SSH") == "" && os.Getenv("GIT_SSH_COMMAND") == "" {
-		os.Setenv("GIT_SSH_COMMAND", "ssh -o ControlMaster=no")
+		os.Setenv("GIT_SSH_COMMAND", "ssh -o ControlMaster=no -o BatchMode=yes")
+	}
+
+	if os.Getenv("GCM_INTERACTIVE") == "" {
+		os.Setenv("GCM_INTERACTIVE", "never")
 	}
 
 	if modRoot != "" {
@@ -171,7 +179,7 @@
 		}
 		modRoot = ""
 	} else {
-		modRoot = findModuleRoot(base.Cwd)
+		modRoot = findModuleRoot(base.Cwd())
 		if modRoot == "" {
 			if cfg.ModFile != "" {
 				base.Fatalf("go: cannot find main module, but -modfile was set.\n\t-modfile cannot be used to set the module root directory.")
@@ -268,7 +276,7 @@
 		return false
 	}
 
-	if modRoot := findModuleRoot(base.Cwd); modRoot == "" {
+	if modRoot := findModuleRoot(base.Cwd()); modRoot == "" {
 		// GO111MODULE is 'auto', and we can't find a module root.
 		// Stay in GOPATH mode.
 		return false
@@ -327,8 +335,8 @@
 	if cfg.Getenv("GO111MODULE") == "off" {
 		base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'")
 	}
-	if dir, name := findAltConfig(base.Cwd); dir != "" {
-		rel, err := filepath.Rel(base.Cwd, dir)
+	if dir, name := findAltConfig(base.Cwd()); dir != "" {
+		rel, err := filepath.Rel(base.Cwd(), dir)
 		if err != nil {
 			rel = dir
 		}
@@ -343,30 +351,77 @@
 
 var ErrNoModRoot = errors.New("go.mod file not found in current directory or any parent directory; see 'go help modules'")
 
+type goModDirtyError struct{}
+
+func (goModDirtyError) Error() string {
+	if cfg.BuildModExplicit {
+		return fmt.Sprintf("updates to go.mod needed, disabled by -mod=%v; to update it:\n\tgo mod tidy", cfg.BuildMod)
+	}
+	if cfg.BuildModReason != "" {
+		return fmt.Sprintf("updates to go.mod needed, disabled by -mod=%s\n\t(%s)\n\tto update it:\n\tgo mod tidy", cfg.BuildMod, cfg.BuildModReason)
+	}
+	return "updates to go.mod needed; to update it:\n\tgo mod tidy"
+}
+
+var errGoModDirty error = goModDirtyError{}
+
 // LoadModFile sets Target and, if there is a main module, parses the initial
 // build list from its go.mod file.
 //
 // LoadModFile may make changes in memory, like adding a go directive and
-// ensuring requirements are consistent. WriteGoMod should be called later to
-// write changes out to disk or report errors in readonly mode.
+// ensuring requirements are consistent, and will write those changes back to
+// disk unless DisallowWriteGoMod is in effect.
 //
 // As a side-effect, LoadModFile may change cfg.BuildMod to "vendor" if
 // -mod wasn't set explicitly and automatic vendoring should be enabled.
-func LoadModFile(ctx context.Context) {
-	if len(buildList) > 0 {
-		return
+//
+// If LoadModFile or CreateModFile has already been called, LoadModFile returns
+// the existing in-memory requirements (rather than re-reading them from disk).
+//
+// LoadModFile checks the roots of the module graph for consistency with each
+// other, but unlike LoadModGraph does not load the full module graph or check
+// it for global consistency. Most callers outside of the modload package should
+// use LoadModGraph instead.
+func LoadModFile(ctx context.Context) *Requirements {
+	rs, needCommit := loadModFile(ctx)
+	if needCommit {
+		commitRequirements(ctx, modFileGoVersion(), rs)
+	}
+	return rs
+}
+
+// loadModFile is like LoadModFile, but does not implicitly commit the
+// requirements back to disk after fixing inconsistencies.
+//
+// If needCommit is true, after the caller makes any other needed changes to the
+// returned requirements they should invoke commitRequirements to fix any
+// inconsistencies that may be present in the on-disk go.mod file.
+func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) {
+	if requirements != nil {
+		return requirements, false
 	}
 
 	Init()
 	if modRoot == "" {
 		Target = module.Version{Path: "command-line-arguments"}
 		targetPrefix = "command-line-arguments"
-		buildList = []module.Version{Target}
-		return
+		goVersion := LatestGoVersion()
+		rawGoVersion.Store(Target, goVersion)
+		requirements = newRequirements(modDepthFromGoVersion(goVersion), nil, nil)
+		return requirements, false
 	}
 
 	gomod := ModFilePath()
-	data, err := lockedfile.Read(gomod)
+	var data []byte
+	var err error
+	if gomodActual, ok := fsys.OverlayPath(gomod); ok {
+		// Don't lock go.mod if it's part of the overlay.
+		// On Plan 9, locking requires chmod, and we don't want to modify any file
+		// in the overlay. See #44700.
+		data, err = os.ReadFile(gomodActual)
+	} else {
+		data, err = lockedfile.Read(gomodActual)
+	}
 	if err != nil {
 		base.Fatalf("go: %v", err)
 	}
@@ -377,24 +432,62 @@
 		// Errors returned by modfile.Parse begin with file:line.
 		base.Fatalf("go: errors parsing go.mod:\n%s\n", err)
 	}
-	modFile = f
-	index = indexModFile(data, f, fixed)
-
 	if f.Module == nil {
 		// No module declaration. Must add module path.
 		base.Fatalf("go: no module declaration in go.mod. To specify the module path:\n\tgo mod edit -module=example.com/mod")
 	}
 
-	if err := checkModulePathLax(f.Module.Mod.Path); err != nil {
+	modFile = f
+	initTarget(f.Module.Mod)
+	index = indexModFile(data, f, fixed)
+
+	if err := module.CheckImportPath(f.Module.Mod.Path); err != nil {
+		if pathErr, ok := err.(*module.InvalidPathError); ok {
+			pathErr.Kind = "module"
+		}
 		base.Fatalf("go: %v", err)
 	}
 
 	setDefaultBuildMod() // possibly enable automatic vendoring
-	modFileToBuildList()
+	rs = requirementsFromModFile()
 	if cfg.BuildMod == "vendor" {
 		readVendorList()
 		checkVendorConsistency()
+		rs.initVendor(vendorList)
 	}
+	if rs.hasRedundantRoot() {
+		// If any module path appears more than once in the roots, we know that the
+		// go.mod file needs to be updated even though we have not yet loaded any
+		// transitive dependencies.
+		rs, err = updateRoots(ctx, rs.direct, rs, nil, nil, false)
+		if err != nil {
+			base.Fatalf("go: %v", err)
+		}
+	}
+
+	if index.goVersionV == "" {
+		// TODO(#45551): Do something more principled instead of checking
+		// cfg.CmdName directly here.
+		if cfg.BuildMod == "mod" && cfg.CmdName != "mod graph" && cfg.CmdName != "mod why" {
+			addGoStmt(LatestGoVersion())
+			if go117EnableLazyLoading {
+				// We need to add a 'go' version to the go.mod file, but we must assume
+				// that its existing contents match something between Go 1.11 and 1.16.
+				// Go 1.11 through 1.16 have eager requirements, but the latest Go
+				// version uses lazy requirements instead — so we need to cnvert the
+				// requirements to be lazy.
+				rs, err = convertDepth(ctx, rs, lazy)
+				if err != nil {
+					base.Fatalf("go: %v", err)
+				}
+			}
+		} else {
+			rawGoVersion.Store(Target, modFileGoVersion())
+		}
+	}
+
+	requirements = rs
+	return requirements, true
 }
 
 // CreateModFile initializes a new module by creating a go.mod file.
@@ -407,7 +500,7 @@
 // exactly the same as in the legacy configuration (for example, we can't get
 // packages at multiple versions from the same module).
 func CreateModFile(ctx context.Context, modPath string) {
-	modRoot = base.Cwd
+	modRoot = base.Cwd()
 	Init()
 	modFilePath := ModFilePath()
 	if _, err := fsys.Stat(modFilePath); err == nil {
@@ -420,14 +513,23 @@
 		if err != nil {
 			base.Fatalf("go: %v", err)
 		}
-	} else if err := checkModulePathLax(modPath); err != nil {
+	} else if err := module.CheckImportPath(modPath); err != nil {
+		if pathErr, ok := err.(*module.InvalidPathError); ok {
+			pathErr.Kind = "module"
+			// Same as build.IsLocalPath()
+			if pathErr.Path == "." || pathErr.Path == ".." ||
+				strings.HasPrefix(pathErr.Path, "./") || strings.HasPrefix(pathErr.Path, "../") {
+				pathErr.Err = errors.New("is a local import path")
+			}
+		}
 		base.Fatalf("go: %v", err)
 	}
 
 	fmt.Fprintf(os.Stderr, "go: creating new go.mod: module %s\n", modPath)
 	modFile = new(modfile.File)
 	modFile.AddModuleStmt(modPath)
-	addGoStmt() // Add the go directive before converted module requirements.
+	initTarget(modFile.Module.Mod)
+	addGoStmt(LatestGoVersion()) // Add the go directive before converted module requirements.
 
 	convertedFrom, err := convertLegacyConfig(modPath)
 	if convertedFrom != "" {
@@ -437,8 +539,12 @@
 		base.Fatalf("go: %v", err)
 	}
 
-	modFileToBuildList()
-	WriteGoMod()
+	rs := requirementsFromModFile()
+	rs, err = updateRoots(ctx, rs.direct, rs, nil, nil, false)
+	if err != nil {
+		base.Fatalf("go: %v", err)
+	}
+	commitRequirements(ctx, modFileGoVersion(), rs)
 
 	// Suggest running 'go mod tidy' unless the project is empty. Even if we
 	// imported all the correct requirements above, we're probably missing
@@ -464,49 +570,6 @@
 	}
 }
 
-// checkModulePathLax checks that the path meets some minimum requirements
-// to avoid confusing users or the module cache. The requirements are weaker
-// than those of module.CheckPath to allow room for weakening module path
-// requirements in the future, but strong enough to help users avoid significant
-// problems.
-func checkModulePathLax(p string) error {
-	// TODO(matloob): Replace calls of this function in this CL with calls
-	// to module.CheckImportPath once it's been laxened, if it becomes laxened.
-	// See golang.org/issue/29101 for a discussion about whether to make CheckImportPath
-	// more lax or more strict.
-
-	errorf := func(format string, args ...interface{}) error {
-		return fmt.Errorf("invalid module path %q: %s", p, fmt.Sprintf(format, args...))
-	}
-
-	// Disallow shell characters " ' * < > ? ` | to avoid triggering bugs
-	// with file systems and subcommands. Disallow file path separators : and \
-	// because path separators other than / will confuse the module cache.
-	// See fileNameOK in golang.org/x/mod/module/module.go.
-	shellChars := "`" + `\"'*<>?|`
-	fsChars := `\:`
-	if i := strings.IndexAny(p, shellChars); i >= 0 {
-		return errorf("contains disallowed shell character %q", p[i])
-	}
-	if i := strings.IndexAny(p, fsChars); i >= 0 {
-		return errorf("contains disallowed path separator character %q", p[i])
-	}
-
-	// Ensure path.IsAbs and build.IsLocalImport are false, and that the path is
-	// invariant under path.Clean, also to avoid confusing the module cache.
-	if path.IsAbs(p) {
-		return errorf("is an absolute path")
-	}
-	if build.IsLocalImport(p) {
-		return errorf("is a local import path")
-	}
-	if path.Clean(p) != p {
-		return errorf("is not clean")
-	}
-
-	return nil
-}
-
 // fixVersion returns a modfile.VersionFixer implemented using the Query function.
 //
 // It resolves commit hashes and branch names to versions,
@@ -559,22 +622,42 @@
 // when there is no module root. Normally, this is forbidden because it's slow
 // and there's no way to make the result reproducible, but some commands
 // like 'go get' are expected to do this.
+//
+// This function affects the default cfg.BuildMod when outside of a module,
+// so it can only be called prior to Init.
 func AllowMissingModuleImports() {
+	if initialized {
+		panic("AllowMissingModuleImports after Init")
+	}
 	allowMissingModuleImports = true
 }
 
-// modFileToBuildList initializes buildList from the modFile.
-func modFileToBuildList() {
-	Target = modFile.Module.Mod
-	targetPrefix = Target.Path
-	if rel := search.InDir(base.Cwd, cfg.GOROOTsrc); rel != "" {
+// initTarget sets Target and associated variables according to modFile,
+func initTarget(m module.Version) {
+	Target = m
+	targetPrefix = m.Path
+
+	if rel := search.InDir(base.Cwd(), cfg.GOROOTsrc); rel != "" {
 		targetInGorootSrc = true
-		if Target.Path == "std" {
+		if m.Path == "std" {
+			// The "std" module in GOROOT/src is the Go standard library. Unlike other
+			// modules, the packages in the "std" module have no import-path prefix.
+			//
+			// Modules named "std" outside of GOROOT/src do not receive this special
+			// treatment, so it is possible to run 'go test .' in other GOROOTs to
+			// test individual packages using a combination of the modified package
+			// and the ordinary standard library.
+			// (See https://golang.org/issue/30756.)
 			targetPrefix = ""
 		}
 	}
+}
 
-	list := []module.Version{Target}
+// requirementsFromModFile returns the set of non-excluded requirements from
+// the global modFile.
+func requirementsFromModFile() *Requirements {
+	roots := make([]module.Version, 0, len(modFile.Require))
+	direct := map[string]bool{}
 	for _, r := range modFile.Require {
 		if index != nil && index.exclude[r.Mod] {
 			if cfg.BuildMod == "mod" {
@@ -582,11 +665,17 @@
 			} else {
 				fmt.Fprintf(os.Stderr, "go: ignoring requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version)
 			}
-		} else {
-			list = append(list, r.Mod)
+			continue
+		}
+
+		roots = append(roots, r.Mod)
+		if !r.Indirect {
+			direct[r.Mod.Path] = true
 		}
 	}
-	buildList = list
+	module.Sort(roots)
+	rs := newRequirements(modDepthFromGoVersion(modFileGoVersion()), roots, direct)
+	return rs
 }
 
 // setDefaultBuildMod sets a default value for cfg.BuildMod if the -mod flag
@@ -605,7 +694,11 @@
 		return
 	}
 	if modRoot == "" {
-		cfg.BuildMod = "readonly"
+		if allowMissingModuleImports {
+			cfg.BuildMod = "mod"
+		} else {
+			cfg.BuildMod = "readonly"
+		}
 		return
 	}
 
@@ -634,6 +727,17 @@
 // convertLegacyConfig imports module requirements from a legacy vendoring
 // configuration file, if one is present.
 func convertLegacyConfig(modPath string) (from string, err error) {
+	noneSelected := func(path string) (version string) { return "none" }
+	queryPackage := func(path, rev string) (module.Version, error) {
+		pkgMods, modOnly, err := QueryPattern(context.Background(), path, rev, noneSelected, nil)
+		if err != nil {
+			return module.Version{}, err
+		}
+		if len(pkgMods) > 0 {
+			return pkgMods[0].Mod, nil
+		}
+		return modOnly.Mod, nil
+	}
 	for _, name := range altConfigs {
 		cfg := filepath.Join(modRoot, name)
 		data, err := os.ReadFile(cfg)
@@ -643,27 +747,57 @@
 				return "", nil
 			}
 			cfg = filepath.ToSlash(cfg)
-			err := modconv.ConvertLegacyConfig(modFile, cfg, data)
+			err := modconv.ConvertLegacyConfig(modFile, cfg, data, queryPackage)
 			return name, err
 		}
 	}
 	return "", nil
 }
 
-// addGoStmt adds a go directive to the go.mod file if it does not already include one.
-// The 'go' version added, if any, is the latest version supported by this toolchain.
-func addGoStmt() {
+// addGoStmt adds a go directive to the go.mod file if it does not already
+// include one. The 'go' version added, if any, is the latest version supported
+// by this toolchain.
+func addGoStmt(v string) {
 	if modFile.Go != nil && modFile.Go.Version != "" {
 		return
 	}
+	if err := modFile.AddGoStmt(v); err != nil {
+		base.Fatalf("go: internal error: %v", err)
+	}
+	rawGoVersion.Store(Target, v)
+}
+
+// LatestGoVersion returns the latest version of the Go language supported by
+// this toolchain, like "1.17".
+func LatestGoVersion() string {
 	tags := build.Default.ReleaseTags
 	version := tags[len(tags)-1]
 	if !strings.HasPrefix(version, "go") || !modfile.GoVersionRE.MatchString(version[2:]) {
-		base.Fatalf("go: unrecognized default version %q", version)
+		base.Fatalf("go: internal error: unrecognized default version %q", version)
 	}
-	if err := modFile.AddGoStmt(version[2:]); err != nil {
-		base.Fatalf("go: internal error: %v", err)
+	return version[2:]
+}
+
+// priorGoVersion returns the Go major release immediately preceding v,
+// or v itself if v is the first Go major release (1.0) or not a supported
+// Go version.
+func priorGoVersion(v string) string {
+	vTag := "go" + v
+	tags := build.Default.ReleaseTags
+	for i, tag := range tags {
+		if tag == vTag {
+			if i == 0 {
+				return v
+			}
+
+			version := tags[i-1]
+			if !strings.HasPrefix(version, "go") || !modfile.GoVersionRE.MatchString(version[2:]) {
+				base.Fatalf("go: internal error: unrecognized version %q", version)
+			}
+			return version[2:]
+		}
 	}
+	return v
 }
 
 var altConfigs = []string{
@@ -780,14 +914,8 @@
 		}
 		if rel := search.InDir(dir, filepath.Join(gpdir, "src")); rel != "" && rel != "." {
 			path := filepath.ToSlash(rel)
-			// TODO(matloob): replace this with module.CheckImportPath
-			// once it's been laxened.
-			// Only checkModulePathLax here. There are some unpublishable
-			// module names that are compatible with checkModulePathLax
-			// but they already work in GOPATH so don't break users
-			// trying to do a build with modules. gorelease will alert users
-			// publishing their modules to fix their paths.
-			if err := checkModulePathLax(path); err != nil {
+			// gorelease will alert users publishing their modules to fix their paths.
+			if err := module.CheckImportPath(path); err != nil {
 				badPathErr = err
 				break
 			}
@@ -847,71 +975,51 @@
 	allowWriteGoMod = true
 }
 
-// MinReqs returns a Reqs with minimal additional dependencies of Target,
-// as will be written to go.mod.
-func MinReqs() mvs.Reqs {
-	retain := append([]string{}, additionalExplicitRequirements...)
-	for _, m := range buildList[1:] {
-		_, explicit := index.require[m]
-		if explicit || loaded.direct[m.Path] {
-			retain = append(retain, m.Path)
-		}
+// WriteGoMod writes the current build list back to go.mod.
+func WriteGoMod(ctx context.Context) {
+	if !allowWriteGoMod {
+		panic("WriteGoMod called while disallowed")
 	}
-	sort.Strings(retain)
-	str.Uniq(&retain)
-	min, err := mvs.Req(Target, retain, &mvsReqs{buildList: buildList})
-	if err != nil {
-		base.Fatalf("go: %v", err)
-	}
-	return &mvsReqs{buildList: append([]module.Version{Target}, min...)}
+	commitRequirements(ctx, modFileGoVersion(), LoadModFile(ctx))
 }
 
-// WriteGoMod writes the current build list back to go.mod.
-func WriteGoMod() {
-	// If we're using -mod=vendor we basically ignored
-	// go.mod, so definitely don't try to write back our
-	// incomplete view of the world.
-	if !allowWriteGoMod || cfg.BuildMod == "vendor" {
+// commitRequirements writes sets the global requirements variable to rs and
+// writes its contents back to the go.mod file on disk.
+func commitRequirements(ctx context.Context, goVersion string, rs *Requirements) {
+	requirements = rs
+
+	if !allowWriteGoMod {
+		// Some package outside of modload promised to update the go.mod file later.
 		return
 	}
 
-	// If we aren't in a module, we don't have anywhere to write a go.mod file.
 	if modRoot == "" {
+		// We aren't in a module, so we don't have anywhere to write a go.mod file.
 		return
 	}
 
-	if cfg.BuildMod != "readonly" {
-		addGoStmt()
+	var list []*modfile.Require
+	for _, m := range rs.rootModules {
+		list = append(list, &modfile.Require{
+			Mod:      m,
+			Indirect: !rs.direct[m.Path],
+		})
 	}
-
-	if loaded != nil {
-		reqs := MinReqs()
-		min, err := reqs.Required(Target)
-		if err != nil {
-			base.Fatalf("go: %v", err)
-		}
-		var list []*modfile.Require
-		for _, m := range min {
-			list = append(list, &modfile.Require{
-				Mod:      m,
-				Indirect: !loaded.direct[m.Path],
-			})
-		}
+	if goVersion != "" {
+		modFile.AddGoStmt(goVersion)
+	}
+	if semver.Compare("v"+modFileGoVersion(), separateIndirectVersionV) < 0 {
 		modFile.SetRequire(list)
+	} else {
+		modFile.SetRequireSeparateIndirect(list)
 	}
 	modFile.Cleanup()
 
 	dirty := index.modFileIsDirty(modFile)
-	if dirty && cfg.BuildMod == "readonly" {
+	if dirty && cfg.BuildMod != "mod" {
 		// If we're about to fail due to -mod=readonly,
 		// prefer to report a dirty go.mod over a dirty go.sum
-		if cfg.BuildModExplicit {
-			base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly")
-		} else if cfg.BuildModReason != "" {
-			base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly\n\t(%s)", cfg.BuildModReason)
-		} else {
-			base.Fatalf("go: updates to go.mod needed; to update it:\n\tgo mod tidy")
-		}
+		base.Fatalf("go: %v", errGoModDirty)
 	}
 
 	if !dirty && cfg.CmdName != "mod tidy" {
@@ -920,7 +1028,14 @@
 		// Don't write go.mod, but write go.sum in case we added or trimmed sums.
 		// 'go mod init' shouldn't write go.sum, since it will be incomplete.
 		if cfg.CmdName != "mod init" {
-			modfetch.WriteGoSum(keepSums(true))
+			modfetch.WriteGoSum(keepSums(ctx, loaded, rs, addBuildListZipSums))
+		}
+		return
+	}
+	gomod := ModFilePath()
+	if _, ok := fsys.OverlayPath(gomod); ok {
+		if dirty {
+			base.Fatalf("go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay")
 		}
 		return
 	}
@@ -936,7 +1051,7 @@
 		// Update go.sum after releasing the side lock and refreshing the index.
 		// 'go mod init' shouldn't write go.sum, since it will be incomplete.
 		if cfg.CmdName != "mod init" {
-			modfetch.WriteGoSum(keepSums(true))
+			modfetch.WriteGoSum(keepSums(ctx, loaded, rs, addBuildListZipSums))
 		}
 	}()
 
@@ -973,100 +1088,99 @@
 	}
 }
 
-// keepSums returns a set of module sums to preserve in go.sum. The set
-// includes entries for all modules used to load packages (according to
-// the last load function such as LoadPackages or ImportFromFiles).
-// It also contains entries for go.mod files needed for MVS (the version
-// of these entries ends with "/go.mod").
-//
-// If keepBuildListZips is true, the set also includes sums for zip files for
-// all modules in the build list with replacements applied. 'go get' and
-// 'go mod download' may add sums to this set when adding a requirement on a
-// module without a root package or when downloading a direct or indirect
-// dependency.
-func keepSums(keepBuildListZips bool) map[module.Version]bool {
-	// Re-derive the build list using the current list of direct requirements.
-	// Keep the sum for the go.mod of each visited module version (or its
-	// replacement).
-	modkey := func(m module.Version) module.Version {
-		return module.Version{Path: m.Path, Version: m.Version + "/go.mod"}
-	}
+// keepSums returns the set of modules (and go.mod file entries) for which
+// checksums would be needed in order to reload the same set of packages
+// loaded by the most recent call to LoadPackages or ImportFromFiles,
+// including any go.mod files needed to reconstruct the MVS result,
+// in addition to the checksums for every module in keepMods.
+func keepSums(ctx context.Context, ld *loader, rs *Requirements, which whichSums) map[module.Version]bool {
+	// Every module in the full module graph contributes its requirements,
+	// so in order to ensure that the build list itself is reproducible,
+	// we need sums for every go.mod in the graph (regardless of whether
+	// that version is selected).
 	keep := make(map[module.Version]bool)
-	var mu sync.Mutex
-	reqs := &keepSumReqs{
-		Reqs: &mvsReqs{buildList: buildList},
-		visit: func(m module.Version) {
-			// If we build using a replacement module, keep the sum for the replacement,
-			// since that's the code we'll actually use during a build.
-			mu.Lock()
-			r := Replacement(m)
-			if r.Path == "" {
-				keep[modkey(m)] = true
-			} else {
-				keep[modkey(r)] = true
-			}
-			mu.Unlock()
-		},
-	}
-	buildList, err := mvs.BuildList(Target, reqs)
-	if err != nil {
-		panic(fmt.Sprintf("unexpected error reloading build list: %v", err))
-	}
-
-	actualMods := make(map[string]module.Version)
-	for _, m := range buildList[1:] {
-		if r := Replacement(m); r.Path != "" {
-			actualMods[m.Path] = r
-		} else {
-			actualMods[m.Path] = m
-		}
-	}
 
 	// Add entries for modules in the build list with paths that are prefixes of
-	// paths of loaded packages. We need to retain sums for modules needed to
-	// report ambiguous import errors. We use our re-derived build list,
-	// since the global build list may have been tidied.
-	if loaded != nil {
-		for _, pkg := range loaded.pkgs {
-			if pkg.testOf != nil || pkg.inStd || module.CheckImportPath(pkg.path) != nil {
+	// paths of loaded packages. We need to retain sums for all of these modules —
+	// not just the modules containing the actual packages — in order to rule out
+	// ambiguous import errors the next time we load the package.
+	if ld != nil {
+		for _, pkg := range ld.pkgs {
+			// We check pkg.mod.Path here instead of pkg.inStd because the
+			// pseudo-package "C" is not in std, but not provided by any module (and
+			// shouldn't force loading the whole module graph).
+			if pkg.testOf != nil || (pkg.mod.Path == "" && pkg.err == nil) || module.CheckImportPath(pkg.path) != nil {
 				continue
 			}
+
+			if rs.depth == lazy && pkg.mod.Path != "" {
+				if v, ok := rs.rootSelected(pkg.mod.Path); ok && v == pkg.mod.Version {
+					// pkg was loaded from a root module, and because the main module is
+					// lazy we do not check non-root modules for conflicts for packages
+					// that can be found in roots. So we only need the checksums for the
+					// root modules that may contain pkg, not all possible modules.
+					for prefix := pkg.path; prefix != "."; prefix = path.Dir(prefix) {
+						if v, ok := rs.rootSelected(prefix); ok && v != "none" {
+							m := module.Version{Path: prefix, Version: v}
+							keep[resolveReplacement(m)] = true
+						}
+					}
+					continue
+				}
+			}
+
+			mg, _ := rs.Graph(ctx)
 			for prefix := pkg.path; prefix != "."; prefix = path.Dir(prefix) {
-				if m, ok := actualMods[prefix]; ok {
-					keep[m] = true
+				if v := mg.Selected(prefix); v != "none" {
+					m := module.Version{Path: prefix, Version: v}
+					keep[resolveReplacement(m)] = true
 				}
 			}
 		}
 	}
 
-	// Add entries for the zip of each module in the build list.
-	// We might not need all of these (tidy does not add them), but they may be
-	// added by a specific 'go get' or 'go mod download' command to resolve
-	// missing import sum errors.
-	if keepBuildListZips {
-		for _, m := range actualMods {
-			keep[m] = true
+	if rs.graph.Load() == nil {
+		// The module graph was not loaded, possibly because the main module is lazy
+		// or possibly because we haven't needed to load the graph yet.
+		// Save sums for the root modules (or their replacements), but don't
+		// incur the cost of loading the graph just to find and retain the sums.
+		for _, m := range rs.rootModules {
+			r := resolveReplacement(m)
+			keep[modkey(r)] = true
+			if which == addBuildListZipSums {
+				keep[r] = true
+			}
+		}
+	} else {
+		mg, _ := rs.Graph(ctx)
+		mg.WalkBreadthFirst(func(m module.Version) {
+			if _, ok := mg.RequiredBy(m); ok {
+				// The requirements from m's go.mod file are present in the module graph,
+				// so they are relevant to the MVS result regardless of whether m was
+				// actually selected.
+				keep[modkey(resolveReplacement(m))] = true
+			}
+		})
+
+		if which == addBuildListZipSums {
+			for _, m := range mg.BuildList() {
+				keep[resolveReplacement(m)] = true
+			}
 		}
 	}
 
 	return keep
 }
 
-// keepSumReqs embeds another Reqs implementation. The Required method
-// calls visit for each version in the module graph.
-type keepSumReqs struct {
-	mvs.Reqs
-	visit func(module.Version)
-}
+type whichSums int8
 
-func (r *keepSumReqs) Required(m module.Version) ([]module.Version, error) {
-	r.visit(m)
-	return r.Reqs.Required(m)
-}
+const (
+	loadedZipSumsOnly = whichSums(iota)
+	addBuildListZipSums
+)
 
-func TrimGoSum() {
-	// Don't retain sums for the zip file of every module in the build list.
-	// We may not need them all to build the main module's packages.
-	keepBuildListZips := false
-	modfetch.TrimGoSum(keepSums(keepBuildListZips))
+// modKey returns the module.Version under which the checksum for m's go.mod
+// file is stored in the go.sum file.
+func modkey(m module.Version) module.Version {
+	return module.Version{Path: m.Path, Version: m.Version + "/go.mod"}
 }
diff --git a/src/cmd/go/internal/modload/list.go b/src/cmd/go/internal/modload/list.go
index 7b1aa7f..ccdeb9b 100644
--- a/src/cmd/go/internal/modload/list.go
+++ b/src/cmd/go/internal/modload/list.go
@@ -20,25 +20,42 @@
 	"golang.org/x/mod/module"
 )
 
-func ListModules(ctx context.Context, args []string, listU, listVersions, listRetracted bool) []*modinfo.ModulePublic {
-	mods := listModules(ctx, args, listVersions, listRetracted)
+type ListMode int
+
+const (
+	ListU ListMode = 1 << iota
+	ListRetracted
+	ListDeprecated
+	ListVersions
+	ListRetractedVersions
+)
+
+// ListModules returns a description of the modules matching args, if known,
+// along with any error preventing additional matches from being identified.
+//
+// The returned slice can be nonempty even if the error is non-nil.
+func ListModules(ctx context.Context, args []string, mode ListMode) ([]*modinfo.ModulePublic, error) {
+	rs, mods, err := listModules(ctx, LoadModFile(ctx), args, mode)
 
 	type token struct{}
 	sem := make(chan token, runtime.GOMAXPROCS(0))
-	if listU || listVersions || listRetracted {
+	if mode != 0 {
 		for _, m := range mods {
 			add := func(m *modinfo.ModulePublic) {
 				sem <- token{}
 				go func() {
-					if listU {
+					if mode&ListU != 0 {
 						addUpdate(ctx, m)
 					}
-					if listVersions {
-						addVersions(ctx, m, listRetracted)
+					if mode&ListVersions != 0 {
+						addVersions(ctx, m, mode&ListRetractedVersions != 0)
 					}
-					if listRetracted || listU {
+					if mode&ListRetracted != 0 {
 						addRetraction(ctx, m)
 					}
+					if mode&ListDeprecated != 0 {
+						addDeprecation(ctx, m)
+					}
 					<-sem
 				}()
 			}
@@ -54,17 +71,18 @@
 		sem <- token{}
 	}
 
-	return mods
+	if err == nil {
+		commitRequirements(ctx, modFileGoVersion(), rs)
+	}
+	return mods, err
 }
 
-func listModules(ctx context.Context, args []string, listVersions, listRetracted bool) []*modinfo.ModulePublic {
-	LoadAllModules(ctx)
+func listModules(ctx context.Context, rs *Requirements, args []string, mode ListMode) (_ *Requirements, mods []*modinfo.ModulePublic, mgErr error) {
 	if len(args) == 0 {
-		return []*modinfo.ModulePublic{moduleInfo(ctx, buildList[0], true, listRetracted)}
+		return rs, []*modinfo.ModulePublic{moduleInfo(ctx, rs, Target, mode)}, nil
 	}
 
-	var mods []*modinfo.ModulePublic
-	matchedBuildList := make([]bool, len(buildList))
+	needFullGraph := false
 	for _, arg := range args {
 		if strings.Contains(arg, `\`) {
 			base.Fatalf("go: module paths never use backslash")
@@ -72,22 +90,62 @@
 		if search.IsRelativePath(arg) {
 			base.Fatalf("go: cannot use relative path %s to specify module", arg)
 		}
-		if !HasModRoot() && (arg == "all" || strings.Contains(arg, "...")) {
-			base.Fatalf("go: cannot match %q: %v", arg, ErrNoModRoot)
+		if arg == "all" || strings.Contains(arg, "...") {
+			needFullGraph = true
+			if !HasModRoot() {
+				base.Fatalf("go: cannot match %q: %v", arg, ErrNoModRoot)
+			}
+			continue
 		}
 		if i := strings.Index(arg, "@"); i >= 0 {
 			path := arg[:i]
 			vers := arg[i+1:]
+			if vers == "upgrade" || vers == "patch" {
+				if _, ok := rs.rootSelected(path); !ok || rs.depth == eager {
+					needFullGraph = true
+					if !HasModRoot() {
+						base.Fatalf("go: cannot match %q: %v", arg, ErrNoModRoot)
+					}
+				}
+			}
+			continue
+		}
+		if _, ok := rs.rootSelected(arg); !ok || rs.depth == eager {
+			needFullGraph = true
+			if mode&ListVersions == 0 && !HasModRoot() {
+				base.Fatalf("go: cannot match %q without -versions or an explicit version: %v", arg, ErrNoModRoot)
+			}
+		}
+	}
+
+	var mg *ModuleGraph
+	if needFullGraph {
+		rs, mg, mgErr = expandGraph(ctx, rs)
+	}
+
+	matchedModule := map[module.Version]bool{}
+	for _, arg := range args {
+		if i := strings.Index(arg, "@"); i >= 0 {
+			path := arg[:i]
+			vers := arg[i+1:]
+
 			var current string
-			for _, m := range buildList {
-				if m.Path == path {
-					current = m.Version
-					break
+			if mg == nil {
+				current, _ = rs.rootSelected(path)
+			} else {
+				current = mg.Selected(path)
+			}
+			if current == "none" && mgErr != nil {
+				if vers == "upgrade" || vers == "patch" {
+					// The module graph is incomplete, so we don't know what version we're
+					// actually upgrading from.
+					// mgErr is already set, so just skip this module.
+					continue
 				}
 			}
 
 			allowed := CheckAllowed
-			if IsRevisionQuery(vers) || listRetracted {
+			if IsRevisionQuery(vers) || mode&ListRetracted != 0 {
 				// Allow excluded and retracted versions if the user asked for a
 				// specific revision or used 'go list -retracted'.
 				allowed = nil
@@ -101,75 +159,79 @@
 				})
 				continue
 			}
-			mod := moduleInfo(ctx, module.Version{Path: path, Version: info.Version}, false, listRetracted)
+
+			// Indicate that m was resolved from outside of rs by passing a nil
+			// *Requirements instead.
+			var noRS *Requirements
+
+			mod := moduleInfo(ctx, noRS, module.Version{Path: path, Version: info.Version}, mode)
 			mods = append(mods, mod)
 			continue
 		}
 
 		// Module path or pattern.
 		var match func(string) bool
-		var literal bool
 		if arg == "all" {
 			match = func(string) bool { return true }
 		} else if strings.Contains(arg, "...") {
 			match = search.MatchPattern(arg)
 		} else {
-			match = func(p string) bool { return arg == p }
-			literal = true
-		}
-		matched := false
-		for i, m := range buildList {
-			if i == 0 && !HasModRoot() {
-				// The root module doesn't actually exist: omit it.
+			var v string
+			if mg == nil {
+				var ok bool
+				v, ok = rs.rootSelected(arg)
+				if !ok {
+					// We checked rootSelected(arg) in the earlier args loop, so if there
+					// is no such root we should have loaded a non-nil mg.
+					panic(fmt.Sprintf("internal error: root requirement expected but not found for %v", arg))
+				}
+			} else {
+				v = mg.Selected(arg)
+			}
+			if v == "none" && mgErr != nil {
+				// mgErr is already set, so just skip this module.
 				continue
 			}
+			if v != "none" {
+				mods = append(mods, moduleInfo(ctx, rs, module.Version{Path: arg, Version: v}, mode))
+			} else if cfg.BuildMod == "vendor" {
+				// In vendor mode, we can't determine whether a missing module is “a
+				// known dependency” because the module graph is incomplete.
+				// Give a more explicit error message.
+				mods = append(mods, &modinfo.ModulePublic{
+					Path:  arg,
+					Error: modinfoError(arg, "", errors.New("can't resolve module using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)")),
+				})
+			} else if mode&ListVersions != 0 {
+				// Don't make the user provide an explicit '@latest' when they're
+				// explicitly asking what the available versions are. Instead, return a
+				// module with version "none", to which we can add the requested list.
+				mods = append(mods, &modinfo.ModulePublic{Path: arg})
+			} else {
+				mods = append(mods, &modinfo.ModulePublic{
+					Path:  arg,
+					Error: modinfoError(arg, "", errors.New("not a known dependency")),
+				})
+			}
+			continue
+		}
+
+		matched := false
+		for _, m := range mg.BuildList() {
 			if match(m.Path) {
 				matched = true
-				if !matchedBuildList[i] {
-					matchedBuildList[i] = true
-					mods = append(mods, moduleInfo(ctx, m, true, listRetracted))
+				if !matchedModule[m] {
+					matchedModule[m] = true
+					mods = append(mods, moduleInfo(ctx, rs, m, mode))
 				}
 			}
 		}
 		if !matched {
-			if literal {
-				if listVersions {
-					// Don't make the user provide an explicit '@latest' when they're
-					// explicitly asking what the available versions are.
-					// Instead, resolve the module, even if it isn't an existing dependency.
-					info, err := Query(ctx, arg, "latest", "", nil)
-					if err == nil {
-						mod := moduleInfo(ctx, module.Version{Path: arg, Version: info.Version}, false, listRetracted)
-						mods = append(mods, mod)
-					} else {
-						mods = append(mods, &modinfo.ModulePublic{
-							Path:  arg,
-							Error: modinfoError(arg, "", err),
-						})
-					}
-					continue
-				}
-				if cfg.BuildMod == "vendor" {
-					// In vendor mode, we can't determine whether a missing module is “a
-					// known dependency” because the module graph is incomplete.
-					// Give a more explicit error message.
-					mods = append(mods, &modinfo.ModulePublic{
-						Path:  arg,
-						Error: modinfoError(arg, "", errors.New("can't resolve module using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)")),
-					})
-				} else {
-					mods = append(mods, &modinfo.ModulePublic{
-						Path:  arg,
-						Error: modinfoError(arg, "", errors.New("not a known dependency")),
-					})
-				}
-			} else {
-				fmt.Fprintf(os.Stderr, "warning: pattern %q matched no module dependencies\n", arg)
-			}
+			fmt.Fprintf(os.Stderr, "warning: pattern %q matched no module dependencies\n", arg)
 		}
 	}
 
-	return mods
+	return rs, mods, mgErr
 }
 
 // modinfoError wraps an error to create an error message in
diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go
index 154fc3c..bce9ad8 100644
--- a/src/cmd/go/internal/modload/load.go
+++ b/src/cmd/go/internal/modload/load.go
@@ -49,7 +49,7 @@
 // Because "go mod vendor" prunes out the tests of vendored packages, the
 // behavior of the "all" pattern with -mod=vendor in Go 1.11–1.15 is the same
 // as the "all" pattern (regardless of the -mod flag) in 1.16+.
-// The allClosesOverTests parameter to the loader indicates whether the "all"
+// The loader uses the GoVersion parameter to determine whether the "all"
 // pattern should close over tests (as in Go 1.11–1.15) or stop at only those
 // packages transitively imported by the packages and tests in the main module
 // ("all" in Go 1.16+ and "go mod vendor" in Go 1.11+).
@@ -121,19 +121,49 @@
 	"cmd/go/internal/str"
 
 	"golang.org/x/mod/module"
+	"golang.org/x/mod/semver"
 )
 
 // loaded is the most recently-used package loader.
 // It holds details about individual packages.
+//
+// This variable should only be accessed directly in top-level exported
+// functions. All other functions that require or produce a *loader should pass
+// or return it as an explicit parameter.
 var loaded *loader
 
 // PackageOpts control the behavior of the LoadPackages function.
 type PackageOpts struct {
+	// GoVersion is the Go version to which the go.mod file should be updated
+	// after packages have been loaded.
+	//
+	// An empty GoVersion means to use the Go version already specified in the
+	// main module's go.mod file, or the latest Go version if there is no main
+	// module.
+	GoVersion string
+
 	// Tags are the build tags in effect (as interpreted by the
 	// cmd/go/internal/imports package).
 	// If nil, treated as equivalent to imports.Tags().
 	Tags map[string]bool
 
+	// Tidy, if true, requests that the build list and go.sum file be reduced to
+	// the minimial dependencies needed to reproducibly reload the requested
+	// packages.
+	Tidy bool
+
+	// TidyCompatibleVersion is the oldest Go version that must be able to
+	// reproducibly reload the requested packages.
+	//
+	// If empty, the compatible version is the Go version immediately prior to the
+	// 'go' version listed in the go.mod file.
+	TidyCompatibleVersion string
+
+	// VendorModulesInGOROOTSrc indicates that if we are within a module in
+	// GOROOT/src, packages in the module's vendor directory should be resolved as
+	// actual module dependencies (instead of standard-library packages).
+	VendorModulesInGOROOTSrc bool
+
 	// ResolveMissingImports indicates that we should attempt to add module
 	// dependencies as needed to resolve imports of packages that are not found.
 	//
@@ -141,6 +171,11 @@
 	// if the flag is set to "readonly" (the default) or "vendor".
 	ResolveMissingImports bool
 
+	// AssumeRootsImported indicates that the transitive dependencies of the root
+	// packages should be treated as if those roots will be imported by the main
+	// module.
+	AssumeRootsImported bool
+
 	// AllowPackage, if non-nil, is called after identifying the module providing
 	// each package. If AllowPackage returns a non-nil error, that error is set
 	// for the package, and the imports and test of that package will not be
@@ -166,9 +201,16 @@
 	// an error occurs.
 	AllowErrors bool
 
-	// SilenceErrors indicates that LoadPackages should not print errors
-	// that occur while loading packages. SilenceErrors implies AllowErrors.
-	SilenceErrors bool
+	// SilencePackageErrors indicates that LoadPackages should not print errors
+	// that occur while matching or loading packages, and should not terminate the
+	// process if such an error occurs.
+	//
+	// Errors encountered in the module graph will still be reported.
+	//
+	// The caller may retrieve the silenced package errors using the Lookup
+	// function, and matching errors are still populated in the Errs field of the
+	// associated search.Match.)
+	SilencePackageErrors bool
 
 	// SilenceMissingStdImports indicates that LoadPackages should not print
 	// errors or terminate the process if an imported package is missing, and the
@@ -176,6 +218,15 @@
 	// future version).
 	SilenceMissingStdImports bool
 
+	// SilenceNoGoErrors indicates that LoadPackages should not print
+	// imports.ErrNoGo errors.
+	// This allows the caller to invoke LoadPackages (and report other errors)
+	// without knowing whether the requested packages exist for the given tags.
+	//
+	// Note that if a requested package does not exist *at all*, it will fail
+	// during module resolution and the error will not be suppressed.
+	SilenceNoGoErrors bool
+
 	// SilenceUnmatchedWarnings suppresses the warnings normally emitted for
 	// patterns that did not match any packages.
 	SilenceUnmatchedWarnings bool
@@ -184,7 +235,6 @@
 // LoadPackages identifies the set of packages matching the given patterns and
 // loads the packages in the import graph rooted at that set.
 func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (matches []*search.Match, loadedPackages []string) {
-	LoadModFile(ctx)
 	if opts.Tags == nil {
 		opts.Tags = imports.Tags()
 	}
@@ -199,13 +249,13 @@
 		}
 	}
 
-	updateMatches := func(ld *loader) {
+	updateMatches := func(rs *Requirements, ld *loader) {
 		for _, m := range matches {
 			switch {
 			case m.IsLocal():
 				// Evaluate list of file system directories on first iteration.
 				if m.Dirs == nil {
-					matchLocalDirs(m)
+					matchLocalDirs(ctx, m, rs)
 				}
 
 				// Make a copy of the directory list and translate to import paths.
@@ -216,7 +266,7 @@
 				// the loader iterations.
 				m.Pkgs = m.Pkgs[:0]
 				for _, dir := range m.Dirs {
-					pkg, err := resolveLocalPackage(dir)
+					pkg, err := resolveLocalPackage(ctx, dir, rs)
 					if err != nil {
 						if !m.IsLiteral() && (err == errPkgIsBuiltin || err == errPkgIsGorootSrc) {
 							continue // Don't include "builtin" or GOROOT/src in wildcard patterns.
@@ -239,7 +289,17 @@
 
 			case strings.Contains(m.Pattern(), "..."):
 				m.Errs = m.Errs[:0]
-				matchPackages(ctx, m, opts.Tags, includeStd, buildList)
+				mg, err := rs.Graph(ctx)
+				if err != nil {
+					// The module graph is (or may be) incomplete — perhaps we failed to
+					// load the requirements of some module. This is an error in matching
+					// the patterns to packages, because we may be missing some packages
+					// or we may erroneously match packages in the wrong versions of
+					// modules. However, for cases like 'go list -e', the error should not
+					// necessarily prevent us from loading the packages we could find.
+					m.Errs = append(m.Errs, err)
+				}
+				matchPackages(ctx, m, opts.Tags, includeStd, mg.BuildList())
 
 			case m.Pattern() == "all":
 				if ld == nil {
@@ -264,14 +324,16 @@
 		}
 	}
 
-	loaded = loadFromRoots(loaderParams{
-		PackageOpts: opts,
+	initialRS, _ := loadModFile(ctx) // Ignore needCommit — we're going to commit at the end regardless.
 
-		allClosesOverTests: index.allPatternClosesOverTests() && !opts.UseVendorAll,
-		allPatternIsRoot:   allPatternIsRoot,
+	ld := loadFromRoots(ctx, loaderParams{
+		PackageOpts:  opts,
+		requirements: initialRS,
 
-		listRoots: func() (roots []string) {
-			updateMatches(nil)
+		allPatternIsRoot: allPatternIsRoot,
+
+		listRoots: func(rs *Requirements) (roots []string) {
+			updateMatches(rs, nil)
 			for _, m := range matches {
 				roots = append(roots, m.Pkgs...)
 			}
@@ -280,47 +342,14 @@
 	})
 
 	// One last pass to finalize wildcards.
-	updateMatches(loaded)
+	updateMatches(ld.requirements, ld)
 
-	// Report errors, if any.
-	checkMultiplePaths()
-	for _, pkg := range loaded.pkgs {
-		if pkg.err != nil {
-			if sumErr := (*ImportMissingSumError)(nil); errors.As(pkg.err, &sumErr) {
-				if importer := pkg.stack; importer != nil {
-					sumErr.importer = importer.path
-					sumErr.importerVersion = importer.mod.Version
-					sumErr.importerIsTest = importer.testOf != nil
-				}
-			}
-			silence := opts.SilenceErrors
-			if stdErr := (*ImportMissingError)(nil); errors.As(pkg.err, &stdErr) &&
-				stdErr.isStd && opts.SilenceMissingStdImports {
-				silence = true
-			}
-
-			if !silence {
-				if opts.AllowErrors {
-					fmt.Fprintf(os.Stderr, "%s: %v\n", pkg.stackText(), pkg.err)
-				} else {
-					base.Errorf("%s: %v", pkg.stackText(), pkg.err)
-				}
-			}
-		}
-		if !pkg.isTest() {
-			loadedPackages = append(loadedPackages, pkg.path)
-		}
-	}
-	if !opts.SilenceErrors {
-		// Also list errors in matching patterns (such as directory permission
-		// errors for wildcard patterns).
+	// List errors in matching patterns (such as directory permission
+	// errors for wildcard patterns).
+	if !ld.SilencePackageErrors {
 		for _, match := range matches {
 			for _, err := range match.Errs {
-				if opts.AllowErrors {
-					fmt.Fprintf(os.Stderr, "%v\n", err)
-				} else {
-					base.Errorf("%v", err)
-				}
+				ld.errorf("%v\n", err)
 			}
 		}
 	}
@@ -330,15 +359,68 @@
 		search.WarnUnmatched(matches)
 	}
 
-	// Success! Update go.mod (if needed) and return the results.
-	WriteGoMod()
+	if opts.Tidy {
+		if cfg.BuildV {
+			mg, _ := ld.requirements.Graph(ctx)
+
+			for _, m := range initialRS.rootModules {
+				var unused bool
+				if ld.requirements.depth == eager {
+					// m is unused if it was dropped from the module graph entirely. If it
+					// was only demoted from direct to indirect, it may still be in use via
+					// a transitive import.
+					unused = mg.Selected(m.Path) == "none"
+				} else {
+					// m is unused if it was dropped from the roots. If it is still present
+					// as a transitive dependency, that transitive dependency is not needed
+					// by any package or test in the main module.
+					_, ok := ld.requirements.rootSelected(m.Path)
+					unused = !ok
+				}
+				if unused {
+					fmt.Fprintf(os.Stderr, "unused %s\n", m.Path)
+				}
+			}
+		}
+
+		keep := keepSums(ctx, ld, ld.requirements, loadedZipSumsOnly)
+		if compatDepth := modDepthFromGoVersion(ld.TidyCompatibleVersion); compatDepth != ld.requirements.depth {
+			compatRS := newRequirements(compatDepth, ld.requirements.rootModules, ld.requirements.direct)
+			ld.checkTidyCompatibility(ctx, compatRS)
+
+			for m := range keepSums(ctx, ld, compatRS, loadedZipSumsOnly) {
+				keep[m] = true
+			}
+		}
+
+		if allowWriteGoMod {
+			modfetch.TrimGoSum(keep)
+
+			// commitRequirements below will also call WriteGoSum, but the "keep" map
+			// we have here could be strictly larger: commitRequirements only commits
+			// loaded.requirements, but here we may have also loaded (and want to
+			// preserve checksums for) additional entities from compatRS, which are
+			// only needed for compatibility with ld.TidyCompatibleVersion.
+			modfetch.WriteGoSum(keep)
+		}
+	}
+
+	// Success! Update go.mod and go.sum (if needed) and return the results.
+	loaded = ld
+	commitRequirements(ctx, loaded.GoVersion, loaded.requirements)
+
+	for _, pkg := range ld.pkgs {
+		if !pkg.isTest() {
+			loadedPackages = append(loadedPackages, pkg.path)
+		}
+	}
 	sort.Strings(loadedPackages)
 	return matches, loadedPackages
 }
 
 // matchLocalDirs is like m.MatchDirs, but tries to avoid scanning directories
 // outside of the standard library and active modules.
-func matchLocalDirs(m *search.Match) {
+func matchLocalDirs(ctx context.Context, m *search.Match, rs *Requirements) {
 	if !m.IsLocal() {
 		panic(fmt.Sprintf("internal error: resolveLocalDirs on non-local pattern %s", m.Pattern()))
 	}
@@ -352,9 +434,9 @@
 		dir := filepath.Dir(filepath.Clean(m.Pattern()[:i+3]))
 		absDir := dir
 		if !filepath.IsAbs(dir) {
-			absDir = filepath.Join(base.Cwd, dir)
+			absDir = filepath.Join(base.Cwd(), dir)
 		}
-		if search.InDir(absDir, cfg.GOROOTsrc) == "" && search.InDir(absDir, ModRoot()) == "" && pathInModuleCache(absDir) == "" {
+		if search.InDir(absDir, cfg.GOROOTsrc) == "" && search.InDir(absDir, ModRoot()) == "" && pathInModuleCache(ctx, absDir, rs) == "" {
 			m.Dirs = []string{}
 			m.AddError(fmt.Errorf("directory prefix %s outside available modules", base.ShortPath(absDir)))
 			return
@@ -365,12 +447,12 @@
 }
 
 // resolveLocalPackage resolves a filesystem path to a package path.
-func resolveLocalPackage(dir string) (string, error) {
+func resolveLocalPackage(ctx context.Context, dir string, rs *Requirements) (string, error) {
 	var absDir string
 	if filepath.IsAbs(dir) {
 		absDir = filepath.Clean(dir)
 	} else {
-		absDir = filepath.Join(base.Cwd, dir)
+		absDir = filepath.Join(base.Cwd(), dir)
 	}
 
 	bp, err := cfg.BuildContext.ImportDir(absDir, 0)
@@ -456,7 +538,7 @@
 		return pkg, nil
 	}
 
-	pkg := pathInModuleCache(absDir)
+	pkg := pathInModuleCache(ctx, absDir, rs)
 	if pkg == "" {
 		return "", fmt.Errorf("directory %s outside available modules", base.ShortPath(absDir))
 	}
@@ -471,7 +553,7 @@
 
 // pathInModuleCache returns the import path of the directory dir,
 // if dir is in the module cache copy of a module in our build list.
-func pathInModuleCache(dir string) string {
+func pathInModuleCache(ctx context.Context, dir string, rs *Requirements) string {
 	tryMod := func(m module.Version) (string, bool) {
 		var root string
 		var err error
@@ -501,20 +583,48 @@
 		return path.Join(m.Path, filepath.ToSlash(sub)), true
 	}
 
-	for _, m := range buildList[1:] {
-		if importPath, ok := tryMod(m); ok {
-			// checkMultiplePaths ensures that a module can be used for at most one
-			// requirement, so this must be it.
-			return importPath
+	if rs.depth == lazy {
+		for _, m := range rs.rootModules {
+			if v, _ := rs.rootSelected(m.Path); v != m.Version {
+				continue // m is a root, but we have a higher root for the same path.
+			}
+			if importPath, ok := tryMod(m); ok {
+				// checkMultiplePaths ensures that a module can be used for at most one
+				// requirement, so this must be it.
+				return importPath
+			}
 		}
 	}
-	return ""
+
+	// None of the roots contained dir, or we're in eager mode and want to load
+	// the full module graph more aggressively. Either way, check the full graph
+	// to see if the directory is a non-root dependency.
+	//
+	// If the roots are not consistent with the full module graph, the selected
+	// versions of root modules may differ from what we already checked above.
+	// Re-check those paths too.
+
+	mg, _ := rs.Graph(ctx)
+	var importPath string
+	for _, m := range mg.BuildList() {
+		var found bool
+		importPath, found = tryMod(m)
+		if found {
+			break
+		}
+	}
+	return importPath
 }
 
 // ImportFromFiles adds modules to the build list as needed
 // to satisfy the imports in the named Go source files.
+//
+// Errors in missing dependencies are silenced.
+//
+// TODO(bcmills): Silencing errors seems off. Take a closer look at this and
+// figure out what the error-reporting actually ought to be.
 func ImportFromFiles(ctx context.Context, gofiles []string) {
-	LoadModFile(ctx)
+	rs := LoadModFile(ctx)
 
 	tags := imports.Tags()
 	imports, testImports, err := imports.ScanFiles(gofiles, tags)
@@ -522,31 +632,32 @@
 		base.Fatalf("go: %v", err)
 	}
 
-	loaded = loadFromRoots(loaderParams{
+	loaded = loadFromRoots(ctx, loaderParams{
 		PackageOpts: PackageOpts{
 			Tags:                  tags,
 			ResolveMissingImports: true,
+			SilencePackageErrors:  true,
 		},
-		allClosesOverTests: index.allPatternClosesOverTests(),
-		listRoots: func() (roots []string) {
+		requirements: rs,
+		listRoots: func(*Requirements) (roots []string) {
 			roots = append(roots, imports...)
 			roots = append(roots, testImports...)
 			return roots
 		},
 	})
-	WriteGoMod()
+	commitRequirements(ctx, loaded.GoVersion, loaded.requirements)
 }
 
 // DirImportPath returns the effective import path for dir,
 // provided it is within the main module, or else returns ".".
-func DirImportPath(dir string) string {
+func DirImportPath(ctx context.Context, dir string) string {
 	if !HasModRoot() {
 		return "."
 	}
-	LoadModFile(context.TODO())
+	LoadModFile(ctx) // Sets targetPrefix.
 
 	if !filepath.IsAbs(dir) {
-		dir = filepath.Join(base.Cwd, dir)
+		dir = filepath.Join(base.Cwd(), dir)
 	} else {
 		dir = filepath.Clean(dir)
 	}
@@ -564,20 +675,6 @@
 	return "."
 }
 
-// TargetPackages returns the list of packages in the target (top-level) module
-// matching pattern, which may be relative to the working directory, under all
-// build tag settings.
-func TargetPackages(ctx context.Context, pattern string) *search.Match {
-	// TargetPackages is relative to the main module, so ensure that the main
-	// module is a thing that can contain packages.
-	LoadModFile(ctx)
-	ModRoot()
-
-	m := search.NewMatch(pattern)
-	matchPackages(ctx, m, imports.AnyTags(), omitStd, []module.Version{Target})
-	return m
-}
-
 // ImportMap returns the actual package import path
 // for an import path found in source code.
 // If the given import path does not appear in the source code
@@ -609,29 +706,6 @@
 	return pkg.mod
 }
 
-// PackageImports returns the imports for the package named by the import path.
-// Test imports will be returned as well if tests were loaded for the package
-// (i.e., if "all" was loaded or if LoadTests was set and the path was matched
-// by a command line argument). PackageImports will return nil for
-// unknown package paths.
-func PackageImports(path string) (imports, testImports []string) {
-	pkg, ok := loaded.pkgCache.Get(path).(*loadPkg)
-	if !ok {
-		return nil, nil
-	}
-	imports = make([]string, len(pkg.imports))
-	for i, p := range pkg.imports {
-		imports[i] = p.path
-	}
-	if pkg.test != nil {
-		testImports = make([]string, len(pkg.test.imports))
-		for i, p := range pkg.test.imports {
-			testImports[i] = p.path
-		}
-	}
-	return imports, testImports
-}
-
 // Lookup returns the source directory, import path, and any loading error for
 // the package at path as imported from the package in parentDir.
 // Lookup requires that one of the Load functions in this package has already
@@ -670,26 +744,29 @@
 type loader struct {
 	loaderParams
 
+	// allClosesOverTests indicates whether the "all" pattern includes
+	// dependencies of tests outside the main module (as in Go 1.11–1.15).
+	// (Otherwise — as in Go 1.16+ — the "all" pattern includes only the packages
+	// transitively *imported by* the packages and tests in the main module.)
+	allClosesOverTests bool
+
 	work *par.Queue
 
 	// reset on each iteration
 	roots    []*loadPkg
 	pkgCache *par.Cache // package path (string) → *loadPkg
 	pkgs     []*loadPkg // transitive closure of loaded packages and tests; populated in buildStacks
-
-	// computed at end of iterations
-	direct map[string]bool // imported directly by main module
 }
 
 // loaderParams configure the packages loaded by, and the properties reported
 // by, a loader instance.
 type loaderParams struct {
 	PackageOpts
+	requirements *Requirements
 
-	allClosesOverTests bool // Does the "all" pattern include the transitive closure of tests of packages in "all"?
-	allPatternIsRoot   bool // Is the "all" pattern an additional root?
+	allPatternIsRoot bool // Is the "all" pattern an additional root?
 
-	listRoots func() []string
+	listRoots func(rs *Requirements) []string
 }
 
 func (ld *loader) reset() {
@@ -704,6 +781,16 @@
 	ld.pkgs = nil
 }
 
+// errorf reports an error via either os.Stderr or base.Errorf,
+// according to whether ld.AllowErrors is set.
+func (ld *loader) errorf(format string, args ...interface{}) {
+	if ld.AllowErrors {
+		fmt.Fprintf(os.Stderr, format, args...)
+	} else {
+		base.Errorf(format, args...)
+	}
+}
+
 // A loadPkg records information about a single loaded package.
 type loadPkg struct {
 	// Populated at construction time:
@@ -756,6 +843,11 @@
 	// are also roots (and must be marked pkgIsRoot).
 	pkgIsRoot
 
+	// pkgFromRoot indicates that the package is in the transitive closure of
+	// imports starting at the roots. (Note that every package marked as pkgIsRoot
+	// is also trivially marked pkgFromRoot.)
+	pkgFromRoot
+
 	// pkgImportsLoaded indicates that the imports and testImports fields of a
 	// loadPkg have been populated.
 	pkgImportsLoaded
@@ -796,6 +888,18 @@
 	return pkg.testOf != nil
 }
 
+// fromExternalModule reports whether pkg was loaded from a module other than
+// the main module.
+func (pkg *loadPkg) fromExternalModule() bool {
+	if pkg.mod.Path == "" {
+		return false // loaded from the standard library, not a module
+	}
+	if pkg.mod.Path == Target.Path {
+		return false // loaded from the main module.
+	}
+	return true
+}
+
 var errMissing = errors.New("cannot find package")
 
 // loadFromRoots attempts to load the build graph needed to process a set of
@@ -804,20 +908,52 @@
 // The set of root packages is returned by the params.listRoots function, and
 // expanded to the full set of packages by tracing imports (and possibly tests)
 // as needed.
-func loadFromRoots(params loaderParams) *loader {
+func loadFromRoots(ctx context.Context, params loaderParams) *loader {
 	ld := &loader{
 		loaderParams: params,
 		work:         par.NewQueue(runtime.GOMAXPROCS(0)),
 	}
 
-	var err error
-	reqs := &mvsReqs{buildList: buildList}
-	buildList, err = mvs.BuildList(Target, reqs)
-	if err != nil {
-		base.Fatalf("go: %v", err)
+	if ld.GoVersion == "" {
+		ld.GoVersion = modFileGoVersion()
+
+		if ld.Tidy && semver.Compare("v"+ld.GoVersion, "v"+LatestGoVersion()) > 0 {
+			ld.errorf("go mod tidy: go.mod file indicates go %s, but maximum supported version is %s\n", ld.GoVersion, LatestGoVersion())
+			base.ExitIfErrors()
+		}
 	}
 
-	addedModuleFor := make(map[string]bool)
+	if ld.Tidy {
+		if ld.TidyCompatibleVersion == "" {
+			ld.TidyCompatibleVersion = priorGoVersion(ld.GoVersion)
+		} else if semver.Compare("v"+ld.TidyCompatibleVersion, "v"+ld.GoVersion) > 0 {
+			// Each version of the Go toolchain knows how to interpret go.mod and
+			// go.sum files produced by all previous versions, so a compatibility
+			// version higher than the go.mod version adds nothing.
+			ld.TidyCompatibleVersion = ld.GoVersion
+		}
+	}
+
+	if semver.Compare("v"+ld.GoVersion, narrowAllVersionV) < 0 && !ld.UseVendorAll {
+		// The module's go version explicitly predates the change in "all" for lazy
+		// loading, so continue to use the older interpretation.
+		ld.allClosesOverTests = true
+	}
+
+	var err error
+	ld.requirements, err = convertDepth(ctx, ld.requirements, modDepthFromGoVersion(ld.GoVersion))
+	if err != nil {
+		ld.errorf("go: %v\n", err)
+	}
+
+	if ld.requirements.depth == eager {
+		var err error
+		ld.requirements, _, err = expandGraph(ctx, ld.requirements)
+		if err != nil {
+			ld.errorf("go: %v\n", err)
+		}
+	}
+
 	for {
 		ld.reset()
 
@@ -825,9 +961,29 @@
 		// Note: the returned roots can change on each iteration,
 		// since the expansion of package patterns depends on the
 		// build list we're using.
+		rootPkgs := ld.listRoots(ld.requirements)
+
+		if ld.requirements.depth == lazy && cfg.BuildMod == "mod" {
+			// Before we start loading transitive imports of packages, locate all of
+			// the root packages and promote their containing modules to root modules
+			// dependencies. If their go.mod files are tidy (the common case) and the
+			// set of root packages does not change then we can select the correct
+			// versions of all transitive imports on the first try and complete
+			// loading in a single iteration.
+			changedBuildList := ld.preloadRootModules(ctx, rootPkgs)
+			if changedBuildList {
+				// The build list has changed, so the set of root packages may have also
+				// changed. Start over to pick up the changes. (Preloading roots is much
+				// cheaper than loading the full import graph, so we would rather pay
+				// for an extra iteration of preloading than potentially end up
+				// discarding the result of a full iteration of loading.)
+				continue
+			}
+		}
+
 		inRoots := map[*loadPkg]bool{}
-		for _, path := range ld.listRoots() {
-			root := ld.pkg(path, pkgIsRoot)
+		for _, path := range rootPkgs {
+			root := ld.pkg(ctx, path, pkgIsRoot)
 			if !inRoots[root] {
 				ld.roots = append(ld.roots, root)
 				inRoots[root] = true
@@ -843,77 +999,314 @@
 
 		ld.buildStacks()
 
+		changed, err := ld.updateRequirements(ctx)
+		if err != nil {
+			ld.errorf("go: %v\n", err)
+			break
+		}
+		if changed {
+			// Don't resolve missing imports until the module graph have stabilized.
+			// If the roots are still changing, they may turn out to specify a
+			// requirement on the missing package(s), and we would rather use a
+			// version specified by a new root than add a new dependency on an
+			// unrelated version.
+			continue
+		}
+
 		if !ld.ResolveMissingImports || (!HasModRoot() && !allowMissingModuleImports) {
 			// We've loaded as much as we can without resolving missing imports.
 			break
 		}
-		modAddedBy := ld.resolveMissingImports(addedModuleFor)
+
+		modAddedBy := ld.resolveMissingImports(ctx)
 		if len(modAddedBy) == 0 {
+			// The roots are stable, and we've resolved all of the missing packages
+			// that we can.
 			break
 		}
 
-		// Recompute buildList with all our additions.
-		reqs = &mvsReqs{buildList: buildList}
-		buildList, err = mvs.BuildList(Target, reqs)
+		toAdd := make([]module.Version, 0, len(modAddedBy))
+		for m, _ := range modAddedBy {
+			toAdd = append(toAdd, m)
+		}
+		module.Sort(toAdd) // to make errors deterministic
+
+		// We ran updateRequirements before resolving missing imports and it didn't
+		// make any changes, so we know that the requirement graph is already
+		// consistent with ld.pkgs: we don't need to pass ld.pkgs to updateRoots
+		// again. (That would waste time looking for changes that we have already
+		// applied.)
+		var noPkgs []*loadPkg
+		// We also know that we're going to call updateRequirements again next
+		// iteration so we don't need to also update it here. (That would waste time
+		// computing a "direct" map that we'll have to recompute later anyway.)
+		direct := ld.requirements.direct
+		rs, err := updateRoots(ctx, direct, ld.requirements, noPkgs, toAdd, ld.AssumeRootsImported)
 		if err != nil {
 			// If an error was found in a newly added module, report the package
 			// import stack instead of the module requirement stack. Packages
 			// are more descriptive.
 			if err, ok := err.(*mvs.BuildListError); ok {
 				if pkg := modAddedBy[err.Module()]; pkg != nil {
-					base.Fatalf("go: %s: %v", pkg.stackText(), err.Err)
+					ld.errorf("go: %s: %v\n", pkg.stackText(), err.Err)
+					break
 				}
 			}
-			base.Fatalf("go: %v", err)
+			ld.errorf("go: %v\n", err)
+			break
 		}
+		if reflect.DeepEqual(rs.rootModules, ld.requirements.rootModules) {
+			// Something is deeply wrong. resolveMissingImports gave us a non-empty
+			// set of modules to add to the graph, but adding those modules had no
+			// effect — either they were already in the graph, or updateRoots did not
+			// add them as requested.
+			panic(fmt.Sprintf("internal error: adding %v to module graph had no effect on root requirements (%v)", toAdd, rs.rootModules))
+		}
+		ld.requirements = rs
 	}
-	base.ExitIfErrors()
+	base.ExitIfErrors() // TODO(bcmills): Is this actually needed?
 
-	// Compute directly referenced dependency modules.
-	ld.direct = make(map[string]bool)
+	// Tidy the build list, if applicable, before we report errors.
+	// (The process of tidying may remove errors from irrelevant dependencies.)
+	if ld.Tidy {
+		rs, err := tidyRoots(ctx, ld.requirements, ld.pkgs)
+		if err != nil {
+			ld.errorf("go: %v\n", err)
+		}
+
+		if ld.requirements.depth == lazy {
+			// We continuously add tidy roots to ld.requirements during loading, so at
+			// this point the tidy roots should be a subset of the roots of
+			// ld.requirements, ensuring that no new dependencies are brought inside
+			// the lazy-loading horizon.
+			// If that is not the case, there is a bug in the loading loop above.
+			for _, m := range rs.rootModules {
+				if v, ok := ld.requirements.rootSelected(m.Path); !ok || v != m.Version {
+					ld.errorf("go mod tidy: internal error: a requirement on %v is needed but was not added during package loading\n", m)
+					base.ExitIfErrors()
+				}
+			}
+		}
+		ld.requirements = rs
+	}
+
+	// Report errors, if any.
 	for _, pkg := range ld.pkgs {
-		if pkg.mod == Target {
-			for _, dep := range pkg.imports {
-				if dep.mod.Path != "" && dep.mod.Path != Target.Path && index != nil {
-					_, explicit := index.require[dep.mod]
-					if allowWriteGoMod && cfg.BuildMod == "readonly" && !explicit {
-						// TODO(#40775): attach error to package instead of using
-						// base.Errorf. Ideally, 'go list' should not fail because of this,
-						// but today, LoadPackages calls WriteGoMod unconditionally, which
-						// would fail with a less clear message.
-						base.Errorf("go: %[1]s: package %[2]s imported from implicitly required module; to add missing requirements, run:\n\tgo get %[2]s@%[3]s", pkg.path, dep.path, dep.mod.Version)
-					}
-					ld.direct[dep.mod.Path] = true
-				}
+		if pkg.err == nil {
+			continue
+		}
+
+		// Add importer information to checksum errors.
+		if sumErr := (*ImportMissingSumError)(nil); errors.As(pkg.err, &sumErr) {
+			if importer := pkg.stack; importer != nil {
+				sumErr.importer = importer.path
+				sumErr.importerVersion = importer.mod.Version
+				sumErr.importerIsTest = importer.testOf != nil
 			}
 		}
-	}
-	base.ExitIfErrors()
 
-	// If we didn't scan all of the imports from the main module, or didn't use
-	// imports.AnyTags, then we didn't necessarily load every package that
-	// contributes “direct” imports — so we can't safely mark existing
-	// dependencies as indirect-only.
-	// Conservatively mark those dependencies as direct.
-	if modFile != nil && (!ld.allPatternIsRoot || !reflect.DeepEqual(ld.Tags, imports.AnyTags())) {
-		for _, r := range modFile.Require {
-			if !r.Indirect {
-				ld.direct[r.Mod.Path] = true
-			}
+		if ld.SilencePackageErrors {
+			continue
 		}
+		if stdErr := (*ImportMissingError)(nil); errors.As(pkg.err, &stdErr) &&
+			stdErr.isStd && ld.SilenceMissingStdImports {
+			continue
+		}
+		if ld.SilenceNoGoErrors && errors.Is(pkg.err, imports.ErrNoGo) {
+			continue
+		}
+
+		ld.errorf("%s: %v\n", pkg.stackText(), pkg.err)
 	}
 
+	ld.checkMultiplePaths()
 	return ld
 }
 
-// resolveMissingImports adds module dependencies to the global build list
-// in order to resolve missing packages from pkgs.
+// updateRequirements ensures that ld.requirements is consistent with the
+// information gained from ld.pkgs and includes the modules in add as roots at
+// at least the given versions.
+//
+// In particular:
+//
+// 	- Modules that provide packages directly imported from the main module are
+// 	  marked as direct, and are promoted to explicit roots. If a needed root
+// 	  cannot be promoted due to -mod=readonly or -mod=vendor, the importing
+// 	  package is marked with an error.
+//
+// 	- If ld scanned the "all" pattern independent of build constraints, it is
+// 	  guaranteed to have seen every direct import. Module dependencies that did
+// 	  not provide any directly-imported package are then marked as indirect.
+//
+// 	- Root dependencies are updated to their selected versions.
+//
+// The "changed" return value reports whether the update changed the selected
+// version of any module that either provided a loaded package or may now
+// provide a package that was previously unresolved.
+func (ld *loader) updateRequirements(ctx context.Context) (changed bool, err error) {
+	rs := ld.requirements
+
+	// direct contains the set of modules believed to provide packages directly
+	// imported by the main module.
+	var direct map[string]bool
+
+	// If we didn't scan all of the imports from the main module, or didn't use
+	// imports.AnyTags, then we didn't necessarily load every package that
+	// contributes “direct” imports — so we can't safely mark existing direct
+	// dependencies in ld.requirements as indirect-only. Propagate them as direct.
+	loadedDirect := ld.allPatternIsRoot && reflect.DeepEqual(ld.Tags, imports.AnyTags())
+	if loadedDirect {
+		direct = make(map[string]bool)
+	} else {
+		// TODO(bcmills): It seems like a shame to allocate and copy a map here when
+		// it will only rarely actually vary from rs.direct. Measure this cost and
+		// maybe avoid the copy.
+		direct = make(map[string]bool, len(rs.direct))
+		for mPath := range rs.direct {
+			direct[mPath] = true
+		}
+	}
+
+	for _, pkg := range ld.pkgs {
+		if pkg.mod != Target {
+			continue
+		}
+		for _, dep := range pkg.imports {
+			if !dep.fromExternalModule() {
+				continue
+			}
+
+			if pkg.err == nil && cfg.BuildMod != "mod" {
+				if v, ok := rs.rootSelected(dep.mod.Path); !ok || v != dep.mod.Version {
+					// dep.mod is not an explicit dependency, but needs to be.
+					// Because we are not in "mod" mode, we will not be able to update it.
+					// Instead, mark the importing package with an error.
+					//
+					// TODO(#41688): The resulting error message fails to include the file
+					// position of the import statement (because that information is not
+					// tracked by the module loader). Figure out how to plumb the import
+					// position through.
+					pkg.err = &DirectImportFromImplicitDependencyError{
+						ImporterPath: pkg.path,
+						ImportedPath: dep.path,
+						Module:       dep.mod,
+					}
+					// cfg.BuildMod does not allow us to change dep.mod to be a direct
+					// dependency, so don't mark it as such.
+					continue
+				}
+			}
+
+			// dep is a package directly imported by a package or test in the main
+			// module and loaded from some other module (not the standard library).
+			// Mark its module as a direct dependency.
+			direct[dep.mod.Path] = true
+		}
+	}
+
+	var addRoots []module.Version
+	if ld.Tidy {
+		// When we are tidying a lazy module, we may need to add roots to preserve
+		// the versions of indirect, test-only dependencies that are upgraded
+		// above or otherwise missing from the go.mod files of direct
+		// dependencies. (For example, the direct dependency might be a very
+		// stable codebase that predates modules and thus lacks a go.mod file, or
+		// the author of the direct dependency may have forgotten to commit a
+		// change to the go.mod file, or may have made an erroneous hand-edit that
+		// causes it to be untidy.)
+		//
+		// Promoting an indirect dependency to a root adds the next layer of its
+		// dependencies to the module graph, which may increase the selected
+		// versions of other modules from which we have already loaded packages.
+		// So after we promote an indirect dependency to a root, we need to reload
+		// packages, which means another iteration of loading.
+		//
+		// As an extra wrinkle, the upgrades due to promoting a root can cause
+		// previously-resolved packages to become unresolved. For example, the
+		// module providing an unstable package might be upgraded to a version
+		// that no longer contains that package. If we then resolve the missing
+		// package, we might add yet another root that upgrades away some other
+		// dependency. (The tests in mod_tidy_convergence*.txt illustrate some
+		// particularly worrisome cases.)
+		//
+		// To ensure that this process of promoting, adding, and upgrading roots
+		// eventually terminates, during iteration we only ever add modules to the
+		// root set — we only remove irrelevant roots at the very end of
+		// iteration, after we have already added every root that we plan to need
+		// in the (eventual) tidy root set.
+		//
+		// Since we do not remove any roots during iteration, even if they no
+		// longer provide any imported packages, the selected versions of the
+		// roots can only increase and the set of roots can only expand. The set
+		// of extant root paths is finite and the set of versions of each path is
+		// finite, so the iteration *must* reach a stable fixed-point.
+		tidy, err := tidyRoots(ctx, rs, ld.pkgs)
+		if err != nil {
+			return false, err
+		}
+		addRoots = tidy.rootModules
+	}
+
+	rs, err = updateRoots(ctx, direct, rs, ld.pkgs, addRoots, ld.AssumeRootsImported)
+	if err != nil {
+		// We don't actually know what even the root requirements are supposed to be,
+		// so we can't proceed with loading. Return the error to the caller
+		return false, err
+	}
+
+	if rs != ld.requirements && !reflect.DeepEqual(rs.rootModules, ld.requirements.rootModules) {
+		// The roots of the module graph have changed in some way (not just the
+		// "direct" markings). Check whether the changes affected any of the loaded
+		// packages.
+		mg, err := rs.Graph(ctx)
+		if err != nil {
+			return false, err
+		}
+		for _, pkg := range ld.pkgs {
+			if pkg.fromExternalModule() && mg.Selected(pkg.mod.Path) != pkg.mod.Version {
+				changed = true
+				break
+			}
+			if pkg.err != nil {
+				// Promoting a module to a root may resolve an import that was
+				// previously missing (by pulling in a previously-prune dependency that
+				// provides it) or ambiguous (by promoting exactly one of the
+				// alternatives to a root and ignoring the second-level alternatives) or
+				// otherwise errored out (by upgrading from a version that cannot be
+				// fetched to one that can be).
+				//
+				// Instead of enumerating all of the possible errors, we'll just check
+				// whether importFromModules returns nil for the package.
+				// False-positives are ok: if we have a false-positive here, we'll do an
+				// extra iteration of package loading this time, but we'll still
+				// converge when the root set stops changing.
+				//
+				// In some sense, we can think of this as ‘upgraded the module providing
+				// pkg.path from "none" to a version higher than "none"’.
+				if _, _, err = importFromModules(ctx, pkg.path, rs, nil); err == nil {
+					changed = true
+					break
+				}
+			}
+		}
+	}
+
+	ld.requirements = rs
+	return changed, nil
+}
+
+// resolveMissingImports returns a set of modules that could be added as
+// dependencies in order to resolve missing packages from pkgs.
 //
 // The newly-resolved packages are added to the addedModuleFor map, and
-// resolveMissingImports returns a map from each newly-added module version to
-// the first package for which that module was added.
-func (ld *loader) resolveMissingImports(addedModuleFor map[string]bool) (modAddedBy map[module.Version]*loadPkg) {
-	var needPkgs []*loadPkg
+// resolveMissingImports returns a map from each new module version to
+// the first missing package that module would resolve.
+func (ld *loader) resolveMissingImports(ctx context.Context) (modAddedBy map[module.Version]*loadPkg) {
+	type pkgMod struct {
+		pkg *loadPkg
+		mod *module.Version
+	}
+	var pkgMods []pkgMod
 	for _, pkg := range ld.pkgs {
 		if pkg.err == nil {
 			continue
@@ -928,30 +1321,47 @@
 			continue
 		}
 
-		needPkgs = append(needPkgs, pkg)
-
 		pkg := pkg
+		var mod module.Version
 		ld.work.Add(func() {
-			pkg.mod, pkg.err = queryImport(context.TODO(), pkg.path)
+			var err error
+			mod, err = queryImport(ctx, pkg.path, ld.requirements)
+			if err != nil {
+				// pkg.err was already non-nil, so we can reasonably attribute the error
+				// for pkg to either the original error or the one returned by
+				// queryImport. The existing error indicates only that we couldn't find
+				// the package, whereas the query error also explains why we didn't fix
+				// the problem — so we prefer the latter.
+				pkg.err = err
+			}
+
+			// err is nil, but we intentionally leave pkg.err non-nil and pkg.mod
+			// unset: we still haven't satisfied other invariants of a
+			// successfully-loaded package, such as scanning and loading the imports
+			// of that package. If we succeed in resolving the new dependency graph,
+			// the caller can reload pkg and update the error at that point.
+			//
+			// Even then, the package might not be loaded from the version we've
+			// identified here. The module may be upgraded by some other dependency,
+			// or by a transitive dependency of mod itself, or — less likely — the
+			// package may be rejected by an AllowPackage hook or rendered ambiguous
+			// by some other newly-added or newly-upgraded dependency.
 		})
+
+		pkgMods = append(pkgMods, pkgMod{pkg: pkg, mod: &mod})
 	}
 	<-ld.work.Idle()
 
 	modAddedBy = map[module.Version]*loadPkg{}
-	for _, pkg := range needPkgs {
-		if pkg.err != nil {
+	for _, pm := range pkgMods {
+		pkg, mod := pm.pkg, *pm.mod
+		if mod.Path == "" {
 			continue
 		}
 
-		fmt.Fprintf(os.Stderr, "go: found %s in %s %s\n", pkg.path, pkg.mod.Path, pkg.mod.Version)
-		if addedModuleFor[pkg.path] {
-			// TODO(bcmills): This should only be an error if pkg.mod is the same
-			// version we already tried to add previously.
-			base.Fatalf("go: %s: looping trying to add package", pkg.stackText())
-		}
-		if modAddedBy[pkg.mod] == nil {
-			modAddedBy[pkg.mod] = pkg
-			buildList = append(buildList, pkg.mod)
+		fmt.Fprintf(os.Stderr, "go: found %s in %s %s\n", pkg.path, mod.Path, mod.Version)
+		if modAddedBy[mod] == nil {
+			modAddedBy[mod] = pkg
 		}
 	}
 
@@ -965,7 +1375,7 @@
 // ld.work queue, and its test (if requested) will also be populated once
 // imports have been resolved. When ld.work goes idle, all transitive imports of
 // the requested package (and its test, if requested) will have been loaded.
-func (ld *loader) pkg(path string, flags loadPkgFlags) *loadPkg {
+func (ld *loader) pkg(ctx context.Context, path string, flags loadPkgFlags) *loadPkg {
 	if flags.has(pkgImportsLoaded) {
 		panic("internal error: (*loader).pkg called with pkgImportsLoaded flag set")
 	}
@@ -974,20 +1384,20 @@
 		pkg := &loadPkg{
 			path: path,
 		}
-		ld.applyPkgFlags(pkg, flags)
+		ld.applyPkgFlags(ctx, pkg, flags)
 
-		ld.work.Add(func() { ld.load(pkg) })
+		ld.work.Add(func() { ld.load(ctx, pkg) })
 		return pkg
 	}).(*loadPkg)
 
-	ld.applyPkgFlags(pkg, flags)
+	ld.applyPkgFlags(ctx, pkg, flags)
 	return pkg
 }
 
 // applyPkgFlags updates pkg.flags to set the given flags and propagate the
 // (transitive) effects of those flags, possibly loading or enqueueing further
 // packages as a result.
-func (ld *loader) applyPkgFlags(pkg *loadPkg, flags loadPkgFlags) {
+func (ld *loader) applyPkgFlags(ctx context.Context, pkg *loadPkg, flags loadPkgFlags) {
 	if flags == 0 {
 		return
 	}
@@ -996,6 +1406,9 @@
 		// This package matches a root pattern by virtue of being in "all".
 		flags |= pkgIsRoot
 	}
+	if flags.has(pkgIsRoot) {
+		flags |= pkgFromRoot
+	}
 
 	old := pkg.flags.update(flags)
 	new := old | flags
@@ -1039,7 +1452,7 @@
 				// of packages in "all" if "all" closes over test dependencies.
 				testFlags |= pkgInAll
 			}
-			ld.pkgTest(pkg, testFlags)
+			ld.pkgTest(ctx, pkg, testFlags)
 		}
 	}
 
@@ -1047,13 +1460,100 @@
 		// We have just marked pkg with pkgInAll, or we have just loaded its
 		// imports, or both. Now is the time to propagate pkgInAll to the imports.
 		for _, dep := range pkg.imports {
-			ld.applyPkgFlags(dep, pkgInAll)
+			ld.applyPkgFlags(ctx, dep, pkgInAll)
+		}
+	}
+
+	if new.has(pkgFromRoot) && !old.has(pkgFromRoot|pkgImportsLoaded) {
+		for _, dep := range pkg.imports {
+			ld.applyPkgFlags(ctx, dep, pkgFromRoot)
 		}
 	}
 }
 
+// preloadRootModules loads the module requirements needed to identify the
+// selected version of each module providing a package in rootPkgs,
+// adding new root modules to the module graph if needed.
+func (ld *loader) preloadRootModules(ctx context.Context, rootPkgs []string) (changedBuildList bool) {
+	needc := make(chan map[module.Version]bool, 1)
+	needc <- map[module.Version]bool{}
+	for _, path := range rootPkgs {
+		path := path
+		ld.work.Add(func() {
+			// First, try to identify the module containing the package using only roots.
+			//
+			// If the main module is tidy and the package is in "all" — or if we're
+			// lucky — we can identify all of its imports without actually loading the
+			// full module graph.
+			m, _, err := importFromModules(ctx, path, ld.requirements, nil)
+			if err != nil {
+				var missing *ImportMissingError
+				if errors.As(err, &missing) && ld.ResolveMissingImports {
+					// This package isn't provided by any selected module.
+					// If we can find it, it will be a new root dependency.
+					m, err = queryImport(ctx, path, ld.requirements)
+				}
+				if err != nil {
+					// We couldn't identify the root module containing this package.
+					// Leave it unresolved; we will report it during loading.
+					return
+				}
+			}
+			if m.Path == "" {
+				// The package is in std or cmd. We don't need to change the root set.
+				return
+			}
+
+			v, ok := ld.requirements.rootSelected(m.Path)
+			if !ok || v != m.Version {
+				// We found the requested package in m, but m is not a root, so
+				// loadModGraph will not load its requirements. We need to promote the
+				// module to a root to ensure that any other packages this package
+				// imports are resolved from correct dependency versions.
+				//
+				// (This is the “argument invariant” from the lazy loading design.)
+				need := <-needc
+				need[m] = true
+				needc <- need
+			}
+		})
+	}
+	<-ld.work.Idle()
+
+	need := <-needc
+	if len(need) == 0 {
+		return false // No roots to add.
+	}
+
+	toAdd := make([]module.Version, 0, len(need))
+	for m := range need {
+		toAdd = append(toAdd, m)
+	}
+	module.Sort(toAdd)
+
+	rs, err := updateRoots(ctx, ld.requirements.direct, ld.requirements, nil, toAdd, ld.AssumeRootsImported)
+	if err != nil {
+		// We are missing some root dependency, and for some reason we can't load
+		// enough of the module dependency graph to add the missing root. Package
+		// loading is doomed to fail, so fail quickly.
+		ld.errorf("go: %v\n", err)
+		base.ExitIfErrors()
+		return false
+	}
+	if reflect.DeepEqual(rs.rootModules, ld.requirements.rootModules) {
+		// Something is deeply wrong. resolveMissingImports gave us a non-empty
+		// set of modules to add to the graph, but adding those modules had no
+		// effect — either they were already in the graph, or updateRoots did not
+		// add them as requested.
+		panic(fmt.Sprintf("internal error: adding %v to module graph had no effect on root requirements (%v)", toAdd, rs.rootModules))
+	}
+
+	ld.requirements = rs
+	return true
+}
+
 // load loads an individual package.
-func (ld *loader) load(pkg *loadPkg) {
+func (ld *loader) load(ctx context.Context, pkg *loadPkg) {
 	if strings.Contains(pkg.path, "@") {
 		// Leave for error during load.
 		return
@@ -1072,7 +1572,24 @@
 		return
 	}
 
-	pkg.mod, pkg.dir, pkg.err = importFromBuildList(context.TODO(), pkg.path, buildList)
+	var mg *ModuleGraph
+	if ld.requirements.depth == eager {
+		var err error
+		mg, err = ld.requirements.Graph(ctx)
+		if err != nil {
+			// We already checked the error from Graph in loadFromRoots and/or
+			// updateRequirements, so we ignored the error on purpose and we should
+			// keep trying to push past it.
+			//
+			// However, because mg may be incomplete (and thus may select inaccurate
+			// versions), we shouldn't use it to load packages. Instead, we pass a nil
+			// *ModuleGraph, which will cause mg to first try loading from only the
+			// main module and root dependencies.
+			mg = nil
+		}
+	}
+
+	pkg.mod, pkg.dir, pkg.err = importFromModules(ctx, pkg.path, ld.requirements, mg)
 	if pkg.dir == "" {
 		return
 	}
@@ -1086,10 +1603,10 @@
 		// about (by reducing churn on the flag bits of dependencies), and costs
 		// essentially nothing (these atomic flag ops are essentially free compared
 		// to scanning source code for imports).
-		ld.applyPkgFlags(pkg, pkgInAll)
+		ld.applyPkgFlags(ctx, pkg, pkgInAll)
 	}
 	if ld.AllowPackage != nil {
-		if err := ld.AllowPackage(context.TODO(), pkg.path, pkg.mod); err != nil {
+		if err := ld.AllowPackage(ctx, pkg.path, pkg.mod); err != nil {
 			pkg.err = err
 		}
 	}
@@ -1120,11 +1637,11 @@
 			// GOROOT/src/vendor even when "std" is not the main module.
 			path = ld.stdVendor(pkg.path, path)
 		}
-		pkg.imports = append(pkg.imports, ld.pkg(path, importFlags))
+		pkg.imports = append(pkg.imports, ld.pkg(ctx, path, importFlags))
 	}
 	pkg.testImports = testImports
 
-	ld.applyPkgFlags(pkg, pkgImportsLoaded)
+	ld.applyPkgFlags(ctx, pkg, pkgImportsLoaded)
 }
 
 // pkgTest locates the test of pkg, creating it if needed, and updates its state
@@ -1132,7 +1649,7 @@
 //
 // pkgTest requires that the imports of pkg have already been loaded (flagged
 // with pkgImportsLoaded).
-func (ld *loader) pkgTest(pkg *loadPkg, testFlags loadPkgFlags) *loadPkg {
+func (ld *loader) pkgTest(ctx context.Context, pkg *loadPkg, testFlags loadPkgFlags) *loadPkg {
 	if pkg.isTest() {
 		panic("pkgTest called on a test package")
 	}
@@ -1147,7 +1664,7 @@
 			err:    pkg.err,
 			inStd:  pkg.inStd,
 		}
-		ld.applyPkgFlags(pkg.test, testFlags)
+		ld.applyPkgFlags(ctx, pkg.test, testFlags)
 		createdTest = true
 	})
 
@@ -1162,12 +1679,12 @@
 			if pkg.inStd {
 				path = ld.stdVendor(test.path, path)
 			}
-			test.imports = append(test.imports, ld.pkg(path, importFlags))
+			test.imports = append(test.imports, ld.pkg(ctx, path, importFlags))
 		}
 		pkg.testImports = nil
-		ld.applyPkgFlags(test, pkgImportsLoaded)
+		ld.applyPkgFlags(ctx, test, pkgImportsLoaded)
 	} else {
-		ld.applyPkgFlags(test, testFlags)
+		ld.applyPkgFlags(ctx, test, testFlags)
 	}
 
 	return test
@@ -1181,13 +1698,13 @@
 	}
 
 	if str.HasPathPrefix(parentPath, "cmd") {
-		if Target.Path != "cmd" {
+		if !ld.VendorModulesInGOROOTSrc || Target.Path != "cmd" {
 			vendorPath := pathpkg.Join("cmd", "vendor", path)
 			if _, err := os.Stat(filepath.Join(cfg.GOROOTsrc, filepath.FromSlash(vendorPath))); err == nil {
 				return vendorPath
 			}
 		}
-	} else if Target.Path != "std" || str.HasPathPrefix(parentPath, "vendor") {
+	} else if !ld.VendorModulesInGOROOTSrc || Target.Path != "std" || str.HasPathPrefix(parentPath, "vendor") {
 		// If we are outside of the 'std' module, resolve imports from within 'std'
 		// to the vendor directory.
 		//
@@ -1222,6 +1739,242 @@
 	return all
 }
 
+// checkMultiplePaths verifies that a given module path is used as itself
+// or as a replacement for another module, but not both at the same time.
+//
+// (See https://golang.org/issue/26607 and https://golang.org/issue/34650.)
+func (ld *loader) checkMultiplePaths() {
+	mods := ld.requirements.rootModules
+	if cached := ld.requirements.graph.Load(); cached != nil {
+		if mg := cached.(cachedGraph).mg; mg != nil {
+			mods = mg.BuildList()
+		}
+	}
+
+	firstPath := map[module.Version]string{}
+	for _, mod := range mods {
+		src := resolveReplacement(mod)
+		if prev, ok := firstPath[src]; !ok {
+			firstPath[src] = mod.Path
+		} else if prev != mod.Path {
+			ld.errorf("go: %s@%s used for two different module paths (%s and %s)\n", src.Path, src.Version, prev, mod.Path)
+		}
+	}
+}
+
+// checkTidyCompatibility emits an error if any package would be loaded from a
+// different module under rs than under ld.requirements.
+func (ld *loader) checkTidyCompatibility(ctx context.Context, rs *Requirements) {
+	suggestUpgrade := false
+	suggestEFlag := false
+	suggestFixes := func() {
+		if ld.AllowErrors {
+			// The user is explicitly ignoring these errors, so don't bother them with
+			// other options.
+			return
+		}
+
+		// We print directly to os.Stderr because this information is advice about
+		// how to fix errors, not actually an error itself.
+		// (The actual errors should have been logged already.)
+
+		fmt.Fprintln(os.Stderr)
+
+		goFlag := ""
+		if ld.GoVersion != modFileGoVersion() {
+			goFlag = " -go=" + ld.GoVersion
+		}
+
+		compatFlag := ""
+		if ld.TidyCompatibleVersion != priorGoVersion(ld.GoVersion) {
+			compatFlag = " -compat=" + ld.TidyCompatibleVersion
+		}
+		if suggestUpgrade {
+			eDesc := ""
+			eFlag := ""
+			if suggestEFlag {
+				eDesc = ", leaving some packages unresolved"
+				eFlag = " -e"
+			}
+			fmt.Fprintf(os.Stderr, "To upgrade to the versions selected by go %s%s:\n\tgo mod tidy%s -go=%s && go mod tidy%s -go=%s%s\n", ld.TidyCompatibleVersion, eDesc, eFlag, ld.TidyCompatibleVersion, eFlag, ld.GoVersion, compatFlag)
+		} else if suggestEFlag {
+			// If some packages are missing but no package is upgraded, then we
+			// shouldn't suggest upgrading to the Go 1.16 versions explicitly — that
+			// wouldn't actually fix anything for Go 1.16 users, and *would* break
+			// something for Go 1.17 users.
+			fmt.Fprintf(os.Stderr, "To proceed despite packages unresolved in go %s:\n\tgo mod tidy -e%s%s\n", ld.TidyCompatibleVersion, goFlag, compatFlag)
+		}
+
+		fmt.Fprintf(os.Stderr, "If reproducibility with go %s is not needed:\n\tgo mod tidy%s -compat=%s\n", ld.TidyCompatibleVersion, goFlag, ld.GoVersion)
+
+		// TODO(#46141): Populate the linked wiki page.
+		fmt.Fprintf(os.Stderr, "For other options, see:\n\thttps://golang.org/doc/modules/pruning\n")
+	}
+
+	mg, err := rs.Graph(ctx)
+	if err != nil {
+		ld.errorf("go mod tidy: error loading go %s module graph: %v\n", ld.TidyCompatibleVersion, err)
+		suggestFixes()
+		return
+	}
+
+	// Re-resolve packages in parallel.
+	//
+	// We re-resolve each package — rather than just checking versions — to ensure
+	// that we have fetched module source code (and, importantly, checksums for
+	// that source code) for all modules that are necessary to ensure that imports
+	// are unambiguous. That also produces clearer diagnostics, since we can say
+	// exactly what happened to the package if it became ambiguous or disappeared
+	// entirely.
+	//
+	// We re-resolve the packages in parallel because this process involves disk
+	// I/O to check for package sources, and because the process of checking for
+	// ambiguous imports may require us to download additional modules that are
+	// otherwise pruned out in Go 1.17 — we don't want to block progress on other
+	// packages while we wait for a single new download.
+	type mismatch struct {
+		mod module.Version
+		err error
+	}
+	mismatchMu := make(chan map[*loadPkg]mismatch, 1)
+	mismatchMu <- map[*loadPkg]mismatch{}
+	for _, pkg := range ld.pkgs {
+		if pkg.mod.Path == "" && pkg.err == nil {
+			// This package is from the standard library (which does not vary based on
+			// the module graph).
+			continue
+		}
+
+		pkg := pkg
+		ld.work.Add(func() {
+			mod, _, err := importFromModules(ctx, pkg.path, rs, mg)
+			if mod != pkg.mod {
+				mismatches := <-mismatchMu
+				mismatches[pkg] = mismatch{mod: mod, err: err}
+				mismatchMu <- mismatches
+			}
+		})
+	}
+	<-ld.work.Idle()
+
+	mismatches := <-mismatchMu
+	if len(mismatches) == 0 {
+		// Since we're running as part of 'go mod tidy', the roots of the module
+		// graph should contain only modules that are relevant to some package in
+		// the package graph. We checked every package in the package graph and
+		// didn't find any mismatches, so that must mean that all of the roots of
+		// the module graph are also consistent.
+		//
+		// If we're wrong, Go 1.16 in -mod=readonly mode will error out with
+		// "updates to go.mod needed", which would be very confusing. So instead,
+		// we'll double-check that our reasoning above actually holds — if it
+		// doesn't, we'll emit an internal error and hopefully the user will report
+		// it as a bug.
+		for _, m := range ld.requirements.rootModules {
+			if v := mg.Selected(m.Path); v != m.Version {
+				fmt.Fprintln(os.Stderr)
+				base.Fatalf("go: internal error: failed to diagnose selected-version mismatch for module %s: go %s selects %s, but go %s selects %s\n\tPlease report this at https://golang.org/issue.", m.Path, ld.GoVersion, m.Version, ld.TidyCompatibleVersion, v)
+			}
+		}
+		return
+	}
+
+	// Iterate over the packages (instead of the mismatches map) to emit errors in
+	// deterministic order.
+	for _, pkg := range ld.pkgs {
+		mismatch, ok := mismatches[pkg]
+		if !ok {
+			continue
+		}
+
+		if pkg.isTest() {
+			// We already did (or will) report an error for the package itself,
+			// so don't report a duplicate (and more vebose) error for its test.
+			if _, ok := mismatches[pkg.testOf]; !ok {
+				base.Fatalf("go: internal error: mismatch recorded for test %s, but not its non-test package", pkg.path)
+			}
+			continue
+		}
+
+		switch {
+		case mismatch.err != nil:
+			// pkg resolved successfully, but errors out using the requirements in rs.
+			//
+			// This could occur because the import is provided by a single lazy root
+			// (and is thus unambiguous in lazy mode) and also one or more
+			// transitive dependencies (and is ambiguous in eager mode).
+			//
+			// It could also occur because some transitive dependency upgrades the
+			// module that previously provided the package to a version that no
+			// longer does, or to a version for which the module source code (but
+			// not the go.mod file in isolation) has a checksum error.
+			if missing := (*ImportMissingError)(nil); errors.As(mismatch.err, &missing) {
+				selected := module.Version{
+					Path:    pkg.mod.Path,
+					Version: mg.Selected(pkg.mod.Path),
+				}
+				ld.errorf("%s loaded from %v,\n\tbut go %s would fail to locate it in %s\n", pkg.stackText(), pkg.mod, ld.TidyCompatibleVersion, selected)
+			} else {
+				if ambiguous := (*AmbiguousImportError)(nil); errors.As(mismatch.err, &ambiguous) {
+					// TODO: Is this check needed?
+				}
+				ld.errorf("%s loaded from %v,\n\tbut go %s would fail to locate it:\n\t%v\n", pkg.stackText(), pkg.mod, ld.TidyCompatibleVersion, mismatch.err)
+			}
+
+			suggestEFlag = true
+
+			// Even if we press ahead with the '-e' flag, the older version will
+			// error out in readonly mode if it thinks the go.mod file contains
+			// any *explicit* dependency that is not at its selected version,
+			// even if that dependency is not relevant to any package being loaded.
+			//
+			// We check for that condition here. If all of the roots are consistent
+			// the '-e' flag suffices, but otherwise we need to suggest an upgrade.
+			if !suggestUpgrade {
+				for _, m := range ld.requirements.rootModules {
+					if v := mg.Selected(m.Path); v != m.Version {
+						suggestUpgrade = true
+						break
+					}
+				}
+			}
+
+		case pkg.err != nil:
+			// pkg had an error in lazy mode (presumably suppressed with the -e flag),
+			// but not in eager mode.
+			//
+			// This is possible, if, say, the import is unresolved in lazy mode
+			// (because the "latest" version of each candidate module either is
+			// unavailable or does not contain the package), but is resolved in
+			// eager mode due to a newer-than-latest dependency that is normally
+			// runed out of the module graph.
+			//
+			// This could also occur if the source code for the module providing the
+			// package in lazy mode has a checksum error, but eager mode upgrades
+			// that module to a version with a correct checksum.
+			//
+			// pkg.err should have already been logged elsewhere — along with a
+			// stack trace — so log only the import path and non-error info here.
+			suggestUpgrade = true
+			ld.errorf("%s failed to load from any module,\n\tbut go %s would load it from %v\n", pkg.path, ld.TidyCompatibleVersion, mismatch.mod)
+
+		case pkg.mod != mismatch.mod:
+			// The package is loaded successfully by both Go versions, but from a
+			// different module in each. This could lead to subtle (and perhaps even
+			// unnoticed!) variations in behavior between builds with different
+			// toolchains.
+			suggestUpgrade = true
+			ld.errorf("%s loaded from %v,\n\tbut go %s would select %v\n", pkg.stackText(), pkg.mod, ld.TidyCompatibleVersion, mismatch.mod.Version)
+
+		default:
+			base.Fatalf("go: internal error: mismatch recorded for package %s, but no differences found", pkg.path)
+		}
+	}
+
+	suggestFixes()
+	base.ExitIfErrors()
+}
+
 // scanDir is like imports.ScanDir but elides known magic imports from the list,
 // so that we do not go looking for packages that don't really exist.
 //
diff --git a/src/cmd/go/internal/modload/modfile.go b/src/cmd/go/internal/modload/modfile.go
index c6667d0..03e02e7 100644
--- a/src/cmd/go/internal/modload/modfile.go
+++ b/src/cmd/go/internal/modload/modfile.go
@@ -8,6 +8,7 @@
 	"context"
 	"errors"
 	"fmt"
+	"os"
 	"path/filepath"
 	"strings"
 	"sync"
@@ -15,6 +16,7 @@
 
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
+	"cmd/go/internal/fsys"
 	"cmd/go/internal/lockedfile"
 	"cmd/go/internal/modfetch"
 	"cmd/go/internal/par"
@@ -25,14 +27,58 @@
 	"golang.org/x/mod/semver"
 )
 
-// narrowAllVersionV is the Go version (plus leading "v") at which the
-// module-module "all" pattern no longer closes over the dependencies of
-// tests outside of the main module.
-const narrowAllVersionV = "v1.16"
-const go116EnableNarrowAll = true
+const (
+	// narrowAllVersionV is the Go version (plus leading "v") at which the
+	// module-module "all" pattern no longer closes over the dependencies of
+	// tests outside of the main module.
+	narrowAllVersionV = "v1.16"
+
+	// lazyLoadingVersionV is the Go version (plus leading "v") at which a
+	// module's go.mod file is expected to list explicit requirements on every
+	// module that provides any package transitively imported by that module.
+	lazyLoadingVersionV = "v1.17"
+
+	// separateIndirectVersionV is the Go version (plus leading "v") at which
+	// "// indirect" dependencies are added in a block separate from the direct
+	// ones. See https://golang.org/issue/45965.
+	separateIndirectVersionV = "v1.17"
+)
+
+const (
+	// go117EnableLazyLoading toggles whether lazy-loading code paths should be
+	// active. It will be removed once the lazy loading implementation is stable
+	// and well-tested.
+	go117EnableLazyLoading = true
+
+	// go1117LazyTODO is a constant that exists only until lazy loading is
+	// implemented. Its use indicates a condition that will need to change if the
+	// main module is lazy.
+	go117LazyTODO = false
+)
 
 var modFile *modfile.File
 
+// modFileGoVersion returns the (non-empty) Go version at which the requirements
+// in modFile are intepreted, or the latest Go version if modFile is nil.
+func modFileGoVersion() string {
+	if modFile == nil {
+		return LatestGoVersion()
+	}
+	if modFile.Go == nil || modFile.Go.Version == "" {
+		// The main module necessarily has a go.mod file, and that file lacks a
+		// 'go' directive. The 'go' command has been adding that directive
+		// automatically since Go 1.12, so this module either dates to Go 1.11 or
+		// has been erroneously hand-edited.
+		//
+		// The semantics of the go.mod file are more-or-less the same from Go 1.11
+		// through Go 1.16, changing at 1.17 for lazy loading. So even though a
+		// go.mod file without a 'go' directive is theoretically a Go 1.11 file,
+		// scripts may assume that it ends up as a Go 1.16 module.
+		return "1.16"
+	}
+	return modFile.Go.Version
+}
+
 // A modFileIndex is an index of data corresponding to a modFile
 // at a specific point in time.
 type modFileIndex struct {
@@ -53,6 +99,24 @@
 	indirect bool
 }
 
+// A modDepth indicates which dependencies should be loaded for a go.mod file.
+type modDepth uint8
+
+const (
+	lazy  modDepth = iota // load dependencies only as needed
+	eager                 // load all transitive dependencies eagerly
+)
+
+func modDepthFromGoVersion(goVersion string) modDepth {
+	if !go117EnableLazyLoading {
+		return eager
+	}
+	if semver.Compare("v"+goVersion, lazyLoadingVersionV) < 0 {
+		return eager
+	}
+	return lazy
+}
+
 // CheckAllowed returns an error equivalent to ErrDisallowed if m is excluded by
 // the main module's go.mod or retracted by its author. Most version queries use
 // this to filter out versions that should not be used.
@@ -88,76 +152,53 @@
 
 // CheckRetractions returns an error if module m has been retracted by
 // its author.
-func CheckRetractions(ctx context.Context, m module.Version) error {
+func CheckRetractions(ctx context.Context, m module.Version) (err error) {
+	defer func() {
+		if retractErr := (*ModuleRetractedError)(nil); err == nil || errors.As(err, &retractErr) {
+			return
+		}
+		// Attribute the error to the version being checked, not the version from
+		// which the retractions were to be loaded.
+		if mErr := (*module.ModuleError)(nil); errors.As(err, &mErr) {
+			err = mErr.Err
+		}
+		err = &retractionLoadingError{m: m, err: err}
+	}()
+
 	if m.Version == "" {
 		// Main module, standard library, or file replacement module.
 		// Cannot be retracted.
 		return nil
 	}
-
-	// Look up retraction information from the latest available version of
-	// the module. Cache retraction information so we don't parse the go.mod
-	// file repeatedly.
-	type entry struct {
-		retract []retraction
-		err     error
+	if repl := Replacement(module.Version{Path: m.Path}); repl.Path != "" {
+		// All versions of the module were replaced.
+		// Don't load retractions, since we'd just load the replacement.
+		return nil
 	}
-	path := m.Path
-	e := retractCache.Do(path, func() (v interface{}) {
-		ctx, span := trace.StartSpan(ctx, "checkRetractions "+path)
-		defer span.Done()
 
-		if repl := Replacement(module.Version{Path: m.Path}); repl.Path != "" {
-			// All versions of the module were replaced with a local directory.
-			// Don't load retractions.
-			return &entry{nil, nil}
-		}
-
-		// Find the latest version of the module.
-		// Ignore exclusions from the main module's go.mod.
-		const ignoreSelected = ""
-		var allowAll AllowedFunc
-		rev, err := Query(ctx, path, "latest", ignoreSelected, allowAll)
-		if err != nil {
-			return &entry{nil, err}
-		}
-
-		// Load go.mod for that version.
-		// If the version is replaced, we'll load retractions from the replacement.
-		//
-		// If there's an error loading the go.mod, we'll return it here.
-		// These errors should generally be ignored by callers of checkRetractions,
-		// since they happen frequently when we're offline. These errors are not
-		// equivalent to ErrDisallowed, so they may be distinguished from
-		// retraction errors.
-		//
-		// We load the raw file here: the go.mod file may have a different module
-		// path that we expect if the module or its repository was renamed.
-		// We still want to apply retractions to other aliases of the module.
-		rm := module.Version{Path: path, Version: rev.Version}
-		if repl := Replacement(rm); repl.Path != "" {
-			rm = repl
-		}
-		summary, err := rawGoModSummary(rm)
-		if err != nil {
-			return &entry{nil, err}
-		}
-		return &entry{summary.retract, nil}
-	}).(*entry)
-
-	if err := e.err; err != nil {
-		// Attribute the error to the version being checked, not the version from
-		// which the retractions were to be loaded.
-		var mErr *module.ModuleError
-		if errors.As(err, &mErr) {
-			err = mErr.Err
-		}
-		return &retractionLoadingError{m: m, err: err}
+	// Find the latest available version of the module, and load its go.mod. If
+	// the latest version is replaced, we'll load the replacement.
+	//
+	// If there's an error loading the go.mod, we'll return it here. These errors
+	// should generally be ignored by callers since they happen frequently when
+	// we're offline. These errors are not equivalent to ErrDisallowed, so they
+	// may be distinguished from retraction errors.
+	//
+	// We load the raw file here: the go.mod file may have a different module
+	// path that we expect if the module or its repository was renamed.
+	// We still want to apply retractions to other aliases of the module.
+	rm, err := queryLatestVersionIgnoringRetractions(ctx, m.Path)
+	if err != nil {
+		return err
+	}
+	summary, err := rawGoModSummary(rm)
+	if err != nil {
+		return err
 	}
 
 	var rationale []string
 	isRetracted := false
-	for _, r := range e.retract {
+	for _, r := range summary.retract {
 		if semver.Compare(r.Low, m.Version) <= 0 && semver.Compare(m.Version, r.High) <= 0 {
 			isRetracted = true
 			if r.Rationale != "" {
@@ -171,8 +212,6 @@
 	return nil
 }
 
-var retractCache par.Cache
-
 type ModuleRetractedError struct {
 	Rationale []string
 }
@@ -182,7 +221,7 @@
 	if len(e.Rationale) > 0 {
 		// This is meant to be a short error printed on a terminal, so just
 		// print the first rationale.
-		msg += ": " + ShortRetractionRationale(e.Rationale[0])
+		msg += ": " + ShortMessage(e.Rationale[0], "retracted by module author")
 	}
 	return msg
 }
@@ -204,28 +243,67 @@
 	return e.err
 }
 
-// ShortRetractionRationale returns a retraction rationale string that is safe
-// to print in a terminal. It returns hard-coded strings if the rationale
-// is empty, too long, or contains non-printable characters.
-func ShortRetractionRationale(rationale string) string {
-	const maxRationaleBytes = 500
-	if i := strings.Index(rationale, "\n"); i >= 0 {
-		rationale = rationale[:i]
+// ShortMessage returns a string from go.mod (for example, a retraction
+// rationale or deprecation message) that is safe to print in a terminal.
+//
+// If the given string is empty, ShortMessage returns the given default. If the
+// given string is too long or contains non-printable characters, ShortMessage
+// returns a hard-coded string.
+func ShortMessage(message, emptyDefault string) string {
+	const maxLen = 500
+	if i := strings.Index(message, "\n"); i >= 0 {
+		message = message[:i]
 	}
-	rationale = strings.TrimSpace(rationale)
-	if rationale == "" {
-		return "retracted by module author"
+	message = strings.TrimSpace(message)
+	if message == "" {
+		return emptyDefault
 	}
-	if len(rationale) > maxRationaleBytes {
-		return "(rationale omitted: too long)"
+	if len(message) > maxLen {
+		return "(message omitted: too long)"
 	}
-	for _, r := range rationale {
+	for _, r := range message {
 		if !unicode.IsGraphic(r) && !unicode.IsSpace(r) {
-			return "(rationale omitted: contains non-printable characters)"
+			return "(message omitted: contains non-printable characters)"
 		}
 	}
 	// NOTE: the go.mod parser rejects invalid UTF-8, so we don't check that here.
-	return rationale
+	return message
+}
+
+// CheckDeprecation returns a deprecation message from the go.mod file of the
+// latest version of the given module. Deprecation messages are comments
+// before or on the same line as the module directives that start with
+// "Deprecated:" and run until the end of the paragraph.
+//
+// CheckDeprecation returns an error if the message can't be loaded.
+// CheckDeprecation returns "", nil if there is no deprecation message.
+func CheckDeprecation(ctx context.Context, m module.Version) (deprecation string, err error) {
+	defer func() {
+		if err != nil {
+			err = fmt.Errorf("loading deprecation for %s: %w", m.Path, err)
+		}
+	}()
+
+	if m.Version == "" {
+		// Main module, standard library, or file replacement module.
+		// Don't look up deprecation.
+		return "", nil
+	}
+	if repl := Replacement(module.Version{Path: m.Path}); repl.Path != "" {
+		// All versions of the module were replaced.
+		// We'll look up deprecation separately for the replacement.
+		return "", nil
+	}
+
+	latest, err := queryLatestVersionIgnoringRetractions(ctx, m.Path)
+	if err != nil {
+		return "", err
+	}
+	summary, err := rawGoModSummary(latest)
+	if err != nil {
+		return "", err
+	}
+	return summary.deprecated, nil
 }
 
 // Replacement returns the replacement for mod, if any, from go.mod.
@@ -243,6 +321,15 @@
 	return module.Version{}
 }
 
+// resolveReplacement returns the module actually used to load the source code
+// for m: either m itself, or the replacement for m (iff m is replaced).
+func resolveReplacement(m module.Version) module.Version {
+	if r := Replacement(m); r.Path != "" {
+		return r
+	}
+	return m
+}
+
 // indexModFile rebuilds the index of modFile.
 // If modFile has been changed since it was first read,
 // modFile.Cleanup must be called before indexModFile.
@@ -257,10 +344,13 @@
 	}
 
 	i.goVersionV = ""
-	if modFile.Go != nil {
+	if modFile.Go == nil {
+		rawGoVersion.Store(Target, "")
+	} else {
 		// We're going to use the semver package to compare Go versions, so go ahead
 		// and add the "v" prefix it expects once instead of every time.
 		i.goVersionV = "v" + modFile.Go.Version
+		rawGoVersion.Store(Target, modFile.Go.Version)
 	}
 
 	i.require = make(map[module.Version]requireMeta, len(modFile.Require))
@@ -292,23 +382,6 @@
 	return i
 }
 
-// allPatternClosesOverTests reports whether the "all" pattern includes
-// dependencies of tests outside the main module (as in Go 1.11–1.15).
-// (Otherwise — as in Go 1.16+ — the "all" pattern includes only the packages
-// transitively *imported by* the packages and tests in the main module.)
-func (i *modFileIndex) allPatternClosesOverTests() bool {
-	if !go116EnableNarrowAll {
-		return true
-	}
-	if i != nil && semver.Compare(i.goVersionV, narrowAllVersionV) < 0 {
-		// The module explicitly predates the change in "all" for lazy loading, so
-		// continue to use the older interpretation. (If i == nil, we not in any
-		// module at all and should use the latest semantics.)
-		return true
-	}
-	return false
-}
-
 // modFileIsDirty reports whether the go.mod file differs meaningfully
 // from what was indexed.
 // If modFile has been changed (even cosmetically) since it was first read,
@@ -335,7 +408,7 @@
 			return true
 		}
 	} else if "v"+modFile.Go.Version != i.goVersionV {
-		if i.goVersionV == "" && cfg.BuildMod == "readonly" {
+		if i.goVersionV == "" && cfg.BuildMod != "mod" {
 			// go.mod files did not always require a 'go' version, so do not error out
 			// if one is missing — we may be inside an older module in the module
 			// cache, and should bias toward providing useful behavior.
@@ -391,9 +464,11 @@
 // module.
 type modFileSummary struct {
 	module     module.Version
-	goVersionV string // GoVersion with "v" prefix
+	goVersion  string
+	depth      modDepth
 	require    []module.Version
 	retract    []retraction
+	deprecated string
 }
 
 // A retraction consists of a retracted version interval and rationale.
@@ -433,19 +508,13 @@
 		// return the full list of modules from modules.txt.
 		readVendorList()
 
-		// TODO(#36876): Load the "go" version from vendor/modules.txt and store it
-		// in rawGoVersion with the appropriate key.
-
 		// We don't know what versions the vendored module actually relies on,
 		// so assume that it requires everything.
 		summary.require = vendorList
 		return summary, nil
 	}
 
-	actual := Replacement(m)
-	if actual.Path == "" {
-		actual = m
-	}
+	actual := resolveReplacement(m)
 	if HasModRoot() && cfg.BuildMod == "readonly" && actual.Version != "" {
 		key := module.Version{Path: actual.Path, Version: actual.Version + "/go.mod"}
 		if !modfetch.HaveSum(key) {
@@ -526,45 +595,24 @@
 	}
 	c := rawGoModSummaryCache.Do(m, func() interface{} {
 		summary := new(modFileSummary)
-		var f *modfile.File
-		if m.Version == "" {
-			// m is a replacement module with only a file path.
-			dir := m.Path
-			if !filepath.IsAbs(dir) {
-				dir = filepath.Join(ModRoot(), dir)
-			}
-			gomod := filepath.Join(dir, "go.mod")
-
-			data, err := lockedfile.Read(gomod)
-			if err != nil {
-				return cached{nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))}
-			}
-			f, err = modfile.ParseLax(gomod, data, nil)
-			if err != nil {
-				return cached{nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err))}
-			}
-		} else {
-			if !semver.IsValid(m.Version) {
-				// Disallow the broader queries supported by fetch.Lookup.
-				base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version)
-			}
-
-			data, err := modfetch.GoMod(m.Path, m.Version)
-			if err != nil {
-				return cached{nil, err}
-			}
-			f, err = modfile.ParseLax("go.mod", data, nil)
-			if err != nil {
-				return cached{nil, module.VersionError(m, fmt.Errorf("parsing go.mod: %v", err))}
-			}
+		name, data, err := rawGoModData(m)
+		if err != nil {
+			return cached{nil, err}
 		}
-
+		f, err := modfile.ParseLax(name, data, nil)
+		if err != nil {
+			return cached{nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(name), err))}
+		}
 		if f.Module != nil {
 			summary.module = f.Module.Mod
+			summary.deprecated = f.Module.Deprecated
 		}
 		if f.Go != nil && f.Go.Version != "" {
 			rawGoVersion.LoadOrStore(m, f.Go.Version)
-			summary.goVersionV = "v" + f.Go.Version
+			summary.goVersion = f.Go.Version
+			summary.depth = modDepthFromGoVersion(f.Go.Version)
+		} else {
+			summary.depth = eager
 		}
 		if len(f.Require) > 0 {
 			summary.require = make([]module.Version, 0, len(f.Require))
@@ -589,3 +637,84 @@
 }
 
 var rawGoModSummaryCache par.Cache // module.Version → rawGoModSummary result
+
+// rawGoModData returns the content of the go.mod file for module m, ignoring
+// all replacements that may apply to m.
+//
+// rawGoModData cannot be used on the Target module.
+//
+// Unlike rawGoModSummary, rawGoModData does not cache its results in memory.
+// Use rawGoModSummary instead unless you specifically need these bytes.
+func rawGoModData(m module.Version) (name string, data []byte, err error) {
+	if m.Version == "" {
+		// m is a replacement module with only a file path.
+		dir := m.Path
+		if !filepath.IsAbs(dir) {
+			dir = filepath.Join(ModRoot(), dir)
+		}
+		name = filepath.Join(dir, "go.mod")
+		if gomodActual, ok := fsys.OverlayPath(name); ok {
+			// Don't lock go.mod if it's part of the overlay.
+			// On Plan 9, locking requires chmod, and we don't want to modify any file
+			// in the overlay. See #44700.
+			data, err = os.ReadFile(gomodActual)
+		} else {
+			data, err = lockedfile.Read(gomodActual)
+		}
+		if err != nil {
+			return "", nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(name), err))
+		}
+	} else {
+		if !semver.IsValid(m.Version) {
+			// Disallow the broader queries supported by fetch.Lookup.
+			base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version)
+		}
+		name = "go.mod"
+		data, err = modfetch.GoMod(m.Path, m.Version)
+	}
+	return name, data, err
+}
+
+// queryLatestVersionIgnoringRetractions looks up the latest version of the
+// module with the given path without considering retracted or excluded
+// versions.
+//
+// If all versions of the module are replaced,
+// queryLatestVersionIgnoringRetractions returns the replacement without making
+// a query.
+//
+// If the queried latest version is replaced,
+// queryLatestVersionIgnoringRetractions returns the replacement.
+func queryLatestVersionIgnoringRetractions(ctx context.Context, path string) (latest module.Version, err error) {
+	type entry struct {
+		latest module.Version
+		err    error
+	}
+	e := latestVersionIgnoringRetractionsCache.Do(path, func() interface{} {
+		ctx, span := trace.StartSpan(ctx, "queryLatestVersionIgnoringRetractions "+path)
+		defer span.Done()
+
+		if repl := Replacement(module.Version{Path: path}); repl.Path != "" {
+			// All versions of the module were replaced.
+			// No need to query.
+			return &entry{latest: repl}
+		}
+
+		// Find the latest version of the module.
+		// Ignore exclusions from the main module's go.mod.
+		const ignoreSelected = ""
+		var allowAll AllowedFunc
+		rev, err := Query(ctx, path, "latest", ignoreSelected, allowAll)
+		if err != nil {
+			return &entry{err: err}
+		}
+		latest := module.Version{Path: path, Version: rev.Version}
+		if repl := resolveReplacement(latest); repl.Path != "" {
+			latest = repl
+		}
+		return &entry{latest: latest}
+	}).(*entry)
+	return e.latest, e.err
+}
+
+var latestVersionIgnoringRetractionsCache par.Cache // path → queryLatestVersionIgnoringRetractions result
diff --git a/src/cmd/go/internal/modload/mvs.go b/src/cmd/go/internal/modload/mvs.go
index 3101519..87619b4 100644
--- a/src/cmd/go/internal/modload/mvs.go
+++ b/src/cmd/go/internal/modload/mvs.go
@@ -16,17 +16,36 @@
 	"golang.org/x/mod/semver"
 )
 
+// cmpVersion implements the comparison for versions in the module loader.
+//
+// It is consistent with semver.Compare except that as a special case,
+// the version "" is considered higher than all other versions.
+// The main module (also known as the target) has no version and must be chosen
+// over other versions of the same module in the module dependency graph.
+func cmpVersion(v1, v2 string) int {
+	if v2 == "" {
+		if v1 == "" {
+			return 0
+		}
+		return -1
+	}
+	if v1 == "" {
+		return 1
+	}
+	return semver.Compare(v1, v2)
+}
+
 // mvsReqs implements mvs.Reqs for module semantic versions,
 // with any exclusions or replacements applied internally.
 type mvsReqs struct {
-	buildList []module.Version
+	roots []module.Version
 }
 
 func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) {
 	if mod == Target {
 		// Use the build list as it existed when r was constructed, not the current
 		// global build list.
-		return r.buildList[1:], nil
+		return r.roots, nil
 	}
 
 	if mod.Version == "none" {
@@ -47,7 +66,7 @@
 // be chosen over other versions of the same module in the module dependency
 // graph.
 func (*mvsReqs) Max(v1, v2 string) string {
-	if v1 != "" && (v2 == "" || semver.Compare(v1, v2) == -1) {
+	if cmpVersion(v1, v2) < 0 {
 		return v2
 	}
 	return v1
@@ -86,12 +105,12 @@
 	return versions, err
 }
 
-// Previous returns the tagged version of m.Path immediately prior to
+// previousVersion returns the tagged version of m.Path immediately prior to
 // m.Version, or version "none" if no prior version is tagged.
 //
 // Since the version of Target is not found in the version list,
 // it has no previous version.
-func (*mvsReqs) Previous(m module.Version) (module.Version, error) {
+func previousVersion(m module.Version) (module.Version, error) {
 	// TODO(golang.org/issue/38714): thread tracing context through MVS.
 
 	if m == Target {
@@ -111,3 +130,7 @@
 	}
 	return module.Version{Path: m.Path, Version: "none"}, nil
 }
+
+func (*mvsReqs) Previous(m module.Version) (module.Version, error) {
+	return previousVersion(m)
+}
diff --git a/src/cmd/go/internal/modload/query.go b/src/cmd/go/internal/modload/query.go
index 8affd17..e737ca9 100644
--- a/src/cmd/go/internal/modload/query.go
+++ b/src/cmd/go/internal/modload/query.go
@@ -5,13 +5,13 @@
 package modload
 
 import (
+	"bytes"
 	"context"
 	"errors"
 	"fmt"
 	"io/fs"
 	"os"
 	pathpkg "path"
-	"path/filepath"
 	"sort"
 	"strings"
 	"sync"
@@ -177,7 +177,7 @@
 			return nil, err
 		}
 
-		if (query == "upgrade" || query == "patch") && modfetch.IsPseudoVersion(current) && !rev.Time.IsZero() {
+		if (query == "upgrade" || query == "patch") && module.IsPseudoVersion(current) && !rev.Time.IsZero() {
 			// Don't allow "upgrade" or "patch" to move from a pseudo-version
 			// to a chronologically older version or pseudo-version.
 			//
@@ -196,7 +196,7 @@
 			// newer but v1.1.0 is still an “upgrade”; or v1.0.2 might be a revert of
 			// an unsuccessful fix in v1.0.1, in which case the v1.0.2 commit may be
 			// older than the v1.0.1 commit despite the tag itself being newer.)
-			currentTime, err := modfetch.PseudoVersionTime(current)
+			currentTime, err := module.PseudoVersionTime(current)
 			if err == nil && rev.Time.Before(currentTime) {
 				if err := allowed(ctx, module.Version{Path: path, Version: current}); errors.Is(err, ErrDisallowed) {
 					return nil, err
@@ -325,18 +325,18 @@
 		if current == "" || current == "none" {
 			qm.mayUseLatest = true
 		} else {
-			qm.mayUseLatest = modfetch.IsPseudoVersion(current)
+			qm.mayUseLatest = module.IsPseudoVersion(current)
 			qm.filter = func(mv string) bool { return semver.Compare(mv, current) >= 0 }
 		}
 
 	case query == "patch":
-		if current == "none" {
+		if current == "" || current == "none" {
 			return nil, &NoPatchBaseError{path}
 		}
 		if current == "" {
 			qm.mayUseLatest = true
 		} else {
-			qm.mayUseLatest = modfetch.IsPseudoVersion(current)
+			qm.mayUseLatest = module.IsPseudoVersion(current)
 			qm.prefix = semver.MajorMinor(current) + "."
 			qm.filter = func(mv string) bool { return semver.Compare(mv, current) >= 0 }
 		}
@@ -695,7 +695,9 @@
 
 // modulePrefixesExcludingTarget returns all prefixes of path that may plausibly
 // exist as a module, excluding targetPrefix but otherwise including path
-// itself, sorted by descending length.
+// itself, sorted by descending length. Prefixes that are not valid module paths
+// but are valid package paths (like "m" or "example.com/.gen") are included,
+// since they might be replaced.
 func modulePrefixesExcludingTarget(path string) []string {
 	prefixes := make([]string, 0, strings.Count(path, "/")+1)
 
@@ -747,6 +749,7 @@
 		noPackage   *PackageNotInModuleError
 		noVersion   *NoMatchingVersionError
 		noPatchBase *NoPatchBaseError
+		invalidPath *module.InvalidPathError // see comment in case below
 		notExistErr error
 	)
 	for _, r := range results {
@@ -767,6 +770,17 @@
 			if noPatchBase == nil {
 				noPatchBase = rErr
 			}
+		case *module.InvalidPathError:
+			// The prefix was not a valid module path, and there was no replacement.
+			// Prefixes like this may appear in candidateModules, since we handle
+			// replaced modules that weren't required in the repo lookup process
+			// (see lookupRepo).
+			//
+			// A shorter prefix may be a valid module path and may contain a valid
+			// import path, so this is a low-priority error.
+			if invalidPath == nil {
+				invalidPath = rErr
+			}
 		default:
 			if errors.Is(rErr, fs.ErrNotExist) {
 				if notExistErr == nil {
@@ -800,6 +814,8 @@
 			err = noVersion
 		case noPatchBase != nil:
 			err = noPatchBase
+		case invalidPath != nil:
+			err = invalidPath
 		case notExistErr != nil:
 			err = notExistErr
 		default:
@@ -904,8 +920,8 @@
 	return ""
 }
 
-// ModuleHasRootPackage returns whether module m contains a package m.Path.
-func ModuleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
+// moduleHasRootPackage returns whether module m contains a package m.Path.
+func moduleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
 	needSum := false
 	root, isLocal, err := fetch(ctx, m, needSum)
 	if err != nil {
@@ -915,14 +931,32 @@
 	return ok, err
 }
 
-func versionHasGoMod(ctx context.Context, m module.Version) (bool, error) {
-	needSum := false
-	root, _, err := fetch(ctx, m, needSum)
+// versionHasGoMod returns whether a version has a go.mod file.
+//
+// versionHasGoMod fetches the go.mod file (possibly a fake) and true if it
+// contains anything other than a module directive with the same path. When a
+// module does not have a real go.mod file, the go command acts as if it had one
+// that only contained a module directive. Normal go.mod files created after
+// 1.12 at least have a go directive.
+//
+// This function is a heuristic, since it's possible to commit a file that would
+// pass this test. However, we only need a heurstic for determining whether
+// +incompatible versions may be "latest", which is what this function is used
+// for.
+//
+// This heuristic is useful for two reasons: first, when using a proxy,
+// this lets us fetch from the .mod endpoint which is much faster than the .zip
+// endpoint. The .mod file is used anyway, even if the .zip file contains a
+// go.mod with different content. Second, if we don't fetch the .zip, then
+// we don't need to verify it in go.sum. This makes 'go list -m -u' faster
+// and simpler.
+func versionHasGoMod(_ context.Context, m module.Version) (bool, error) {
+	_, data, err := rawGoModData(m)
 	if err != nil {
 		return false, err
 	}
-	fi, err := os.Stat(filepath.Join(root, "go.mod"))
-	return err == nil && !fi.IsDir(), nil
+	isFake := bytes.Equal(data, modfetch.LegacyGoMod(m.Path))
+	return !isFake, nil
 }
 
 // A versionRepo is a subset of modfetch.Repo that can report information about
@@ -993,7 +1027,7 @@
 	if index != nil && len(index.replace) > 0 {
 		path := rr.ModulePath()
 		for m, _ := range index.replace {
-			if m.Path == path && strings.HasPrefix(m.Version, prefix) && m.Version != "" && !modfetch.IsPseudoVersion(m.Version) {
+			if m.Path == path && strings.HasPrefix(m.Version, prefix) && m.Version != "" && !module.IsPseudoVersion(m.Version) {
 				versions = append(versions, m.Version)
 			}
 		}
@@ -1050,9 +1084,9 @@
 				// used from within some other module, the user will be able to upgrade
 				// the requirement to any real version they choose.
 				if _, pathMajor, ok := module.SplitPathVersion(path); ok && len(pathMajor) > 0 {
-					v = modfetch.PseudoVersion(pathMajor[1:], "", time.Time{}, "000000000000")
+					v = module.PseudoVersion(pathMajor[1:], "", time.Time{}, "000000000000")
 				} else {
-					v = modfetch.PseudoVersion("v0", "", time.Time{}, "000000000000")
+					v = module.PseudoVersion("v0", "", time.Time{}, "000000000000")
 				}
 			}
 
@@ -1067,9 +1101,9 @@
 
 func (rr *replacementRepo) replacementStat(v string) (*modfetch.RevInfo, error) {
 	rev := &modfetch.RevInfo{Version: v}
-	if modfetch.IsPseudoVersion(v) {
-		rev.Time, _ = modfetch.PseudoVersionTime(v)
-		rev.Short, _ = modfetch.PseudoVersionRev(v)
+	if module.IsPseudoVersion(v) {
+		rev.Time, _ = module.PseudoVersionTime(v)
+		rev.Short, _ = module.PseudoVersionRev(v)
 	}
 	return rev, nil
 }
diff --git a/src/cmd/go/internal/modload/query_test.go b/src/cmd/go/internal/modload/query_test.go
index e225a0e..a3f2f84 100644
--- a/src/cmd/go/internal/modload/query_test.go
+++ b/src/cmd/go/internal/modload/query_test.go
@@ -106,7 +106,7 @@
 	{path: queryRepo, query: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"},
 	{path: queryRepo, query: "ed5ffdaa", vers: "v1.9.10-pre2.0.20191220134614-ed5ffdaa1f5e"},
 
-	// golang.org/issue/29262: The major version for for a module without a suffix
+	// golang.org/issue/29262: The major version for a module without a suffix
 	// should be based on the most recent tag (v1 as appropriate, not v0
 	// unconditionally).
 	{path: queryRepo, query: "42abcb6df8ee", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"},
@@ -122,7 +122,7 @@
 	{path: queryRepo, query: "upgrade", allow: "NOMATCH", err: `no matching versions for query "upgrade"`},
 	{path: queryRepo, query: "upgrade", current: "v1.9.9", allow: "NOMATCH", err: `vcs-test.golang.org/git/querytest.git@v1.9.9: disallowed module version`},
 	{path: queryRepo, query: "upgrade", current: "v1.99.99", err: `vcs-test.golang.org/git/querytest.git@v1.99.99: invalid version: unknown revision v1.99.99`},
-	{path: queryRepo, query: "patch", current: "", vers: "v1.9.9"},
+	{path: queryRepo, query: "patch", current: "", err: `can't query version "patch" of module vcs-test.golang.org/git/querytest.git: no existing version is required`},
 	{path: queryRepo, query: "patch", current: "v0.1.0", vers: "v0.1.2"},
 	{path: queryRepo, query: "patch", current: "v1.9.0", vers: "v1.9.9"},
 	{path: queryRepo, query: "patch", current: "v1.9.10-pre1", vers: "v1.9.10-pre1"},
diff --git a/src/cmd/go/internal/modload/search.go b/src/cmd/go/internal/modload/search.go
index 1fe742d..658fc6f 100644
--- a/src/cmd/go/internal/modload/search.go
+++ b/src/cmd/go/internal/modload/search.go
@@ -86,7 +86,7 @@
 			}
 
 			if !fi.IsDir() {
-				if fi.Mode()&fs.ModeSymlink != 0 && want {
+				if fi.Mode()&fs.ModeSymlink != 0 && want && strings.Contains(m.Pattern(), "...") {
 					if target, err := fsys.Stat(path); err == nil && target.IsDir() {
 						fmt.Fprintf(os.Stderr, "warning: ignoring symlink %s\n", path)
 					}
@@ -187,7 +187,7 @@
 		matchPackages(ctx, match, tags, includeStd, nil)
 	}
 
-	LoadModFile(ctx)
+	LoadModFile(ctx) // Sets Target, needed by fetch and matchPackages.
 
 	if !match.IsLiteral() {
 		matchPackages(ctx, match, tags, omitStd, []module.Version{m})
diff --git a/src/cmd/go/internal/modload/stat_openfile.go b/src/cmd/go/internal/modload/stat_openfile.go
index 5842b85..368f893 100644
--- a/src/cmd/go/internal/modload/stat_openfile.go
+++ b/src/cmd/go/internal/modload/stat_openfile.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (js && wasm) || plan9
 // +build js,wasm plan9
 
 // On plan9, per http://9p.io/magic/man2html/2/access: “Since file permissions
diff --git a/src/cmd/go/internal/modload/stat_unix.go b/src/cmd/go/internal/modload/stat_unix.go
index f49278e..e079d73 100644
--- a/src/cmd/go/internal/modload/stat_unix.go
+++ b/src/cmd/go/internal/modload/stat_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package modload
diff --git a/src/cmd/go/internal/modload/stat_windows.go b/src/cmd/go/internal/modload/stat_windows.go
index 0ac2391..825e60b 100644
--- a/src/cmd/go/internal/modload/stat_windows.go
+++ b/src/cmd/go/internal/modload/stat_windows.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build windows
 // +build windows
 
 package modload
diff --git a/src/cmd/go/internal/modload/vendor.go b/src/cmd/go/internal/modload/vendor.go
index d8fd91f..80713b0 100644
--- a/src/cmd/go/internal/modload/vendor.go
+++ b/src/cmd/go/internal/modload/vendor.go
@@ -31,6 +31,7 @@
 type vendorMetadata struct {
 	Explicit    bool
 	Replacement module.Version
+	GoVersion   string
 }
 
 // readVendorList reads the list of vendored modules from vendor/modules.txt.
@@ -104,6 +105,10 @@
 					if entry == "explicit" {
 						meta.Explicit = true
 					}
+					if strings.HasPrefix(entry, "go ") {
+						meta.GoVersion = strings.TrimPrefix(entry, "go ")
+						rawGoVersion.Store(mod, meta.GoVersion)
+					}
 					// All other tokens are reserved for future use.
 				}
 				vendorMeta[mod] = meta
diff --git a/src/cmd/go/internal/mvs/errors.go b/src/cmd/go/internal/mvs/errors.go
index 5564965..bf183ce 100644
--- a/src/cmd/go/internal/mvs/errors.go
+++ b/src/cmd/go/internal/mvs/errors.go
@@ -31,13 +31,15 @@
 // occurred at a module found along the given path of requirements and/or
 // upgrades, which must be non-empty.
 //
-// The isUpgrade function reports whether a path step is due to an upgrade.
-// A nil isUpgrade function indicates that none of the path steps are due to upgrades.
-func NewBuildListError(err error, path []module.Version, isUpgrade func(from, to module.Version) bool) *BuildListError {
+// The isVersionChange function reports whether a path step is due to an
+// explicit upgrade or downgrade (as opposed to an existing requirement in a
+// go.mod file). A nil isVersionChange function indicates that none of the path
+// steps are due to explicit version changes.
+func NewBuildListError(err error, path []module.Version, isVersionChange func(from, to module.Version) bool) *BuildListError {
 	stack := make([]buildListErrorElem, 0, len(path))
 	for len(path) > 1 {
 		reason := "requires"
-		if isUpgrade != nil && isUpgrade(path[0], path[1]) {
+		if isVersionChange != nil && isVersionChange(path[0], path[1]) {
 			reason = "updating to"
 		}
 		stack = append(stack, buildListErrorElem{
diff --git a/src/cmd/go/internal/mvs/graph.go b/src/cmd/go/internal/mvs/graph.go
new file mode 100644
index 0000000..c5de486
--- /dev/null
+++ b/src/cmd/go/internal/mvs/graph.go
@@ -0,0 +1,223 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package mvs
+
+import (
+	"fmt"
+
+	"golang.org/x/mod/module"
+)
+
+// Graph implements an incremental version of the MVS algorithm, with the
+// requirements pushed by the caller instead of pulled by the MVS traversal.
+type Graph struct {
+	cmp   func(v1, v2 string) int
+	roots []module.Version
+
+	required map[module.Version][]module.Version
+
+	isRoot   map[module.Version]bool // contains true for roots and false for reachable non-roots
+	selected map[string]string       // path → version
+}
+
+// NewGraph returns an incremental MVS graph containing only a set of root
+// dependencies and using the given max function for version strings.
+//
+// The caller must ensure that the root slice is not modified while the Graph
+// may be in use.
+func NewGraph(cmp func(v1, v2 string) int, roots []module.Version) *Graph {
+	g := &Graph{
+		cmp:      cmp,
+		roots:    roots[:len(roots):len(roots)],
+		required: make(map[module.Version][]module.Version),
+		isRoot:   make(map[module.Version]bool),
+		selected: make(map[string]string),
+	}
+
+	for _, m := range roots {
+		g.isRoot[m] = true
+		if g.cmp(g.Selected(m.Path), m.Version) < 0 {
+			g.selected[m.Path] = m.Version
+		}
+	}
+
+	return g
+}
+
+// Require adds the information that module m requires all modules in reqs.
+// The reqs slice must not be modified after it is passed to Require.
+//
+// m must be reachable by some existing chain of requirements from g's target,
+// and Require must not have been called for it already.
+//
+// If any of the modules in reqs has the same path as g's target,
+// the target must have higher precedence than the version in req.
+func (g *Graph) Require(m module.Version, reqs []module.Version) {
+	// To help catch disconnected-graph bugs, enforce that all required versions
+	// are actually reachable from the roots (and therefore should affect the
+	// selected versions of the modules they name).
+	if _, reachable := g.isRoot[m]; !reachable {
+		panic(fmt.Sprintf("%v is not reachable from any root", m))
+	}
+
+	// Truncate reqs to its capacity to avoid aliasing bugs if it is later
+	// returned from RequiredBy and appended to.
+	reqs = reqs[:len(reqs):len(reqs)]
+
+	if _, dup := g.required[m]; dup {
+		panic(fmt.Sprintf("requirements of %v have already been set", m))
+	}
+	g.required[m] = reqs
+
+	for _, dep := range reqs {
+		// Mark dep reachable, regardless of whether it is selected.
+		if _, ok := g.isRoot[dep]; !ok {
+			g.isRoot[dep] = false
+		}
+
+		if g.cmp(g.Selected(dep.Path), dep.Version) < 0 {
+			g.selected[dep.Path] = dep.Version
+		}
+	}
+}
+
+// RequiredBy returns the slice of requirements passed to Require for m, if any,
+// with its capacity reduced to its length.
+// If Require has not been called for m, RequiredBy(m) returns ok=false.
+//
+// The caller must not modify the returned slice, but may safely append to it
+// and may rely on it not to be modified.
+func (g *Graph) RequiredBy(m module.Version) (reqs []module.Version, ok bool) {
+	reqs, ok = g.required[m]
+	return reqs, ok
+}
+
+// Selected returns the selected version of the given module path.
+//
+// If no version is selected, Selected returns version "none".
+func (g *Graph) Selected(path string) (version string) {
+	v, ok := g.selected[path]
+	if !ok {
+		return "none"
+	}
+	return v
+}
+
+// BuildList returns the selected versions of all modules present in the Graph,
+// beginning with the selected versions of each module path in the roots of g.
+//
+// The order of the remaining elements in the list is deterministic
+// but arbitrary.
+func (g *Graph) BuildList() []module.Version {
+	seenRoot := make(map[string]bool, len(g.roots))
+
+	var list []module.Version
+	for _, r := range g.roots {
+		if seenRoot[r.Path] {
+			// Multiple copies of the same root, with the same or different versions,
+			// are a bit of a degenerate case: we will take the transitive
+			// requirements of both roots into account, but only the higher one can
+			// possibly be selected. However — especially given that we need the
+			// seenRoot map for later anyway — it is simpler to support this
+			// degenerate case than to forbid it.
+			continue
+		}
+
+		if v := g.Selected(r.Path); v != "none" {
+			list = append(list, module.Version{Path: r.Path, Version: v})
+		}
+		seenRoot[r.Path] = true
+	}
+	uniqueRoots := list
+
+	for path, version := range g.selected {
+		if !seenRoot[path] {
+			list = append(list, module.Version{Path: path, Version: version})
+		}
+	}
+	module.Sort(list[len(uniqueRoots):])
+
+	return list
+}
+
+// WalkBreadthFirst invokes f once, in breadth-first order, for each module
+// version other than "none" that appears in the graph, regardless of whether
+// that version is selected.
+func (g *Graph) WalkBreadthFirst(f func(m module.Version)) {
+	var queue []module.Version
+	enqueued := make(map[module.Version]bool)
+	for _, m := range g.roots {
+		if m.Version != "none" {
+			queue = append(queue, m)
+			enqueued[m] = true
+		}
+	}
+
+	for len(queue) > 0 {
+		m := queue[0]
+		queue = queue[1:]
+
+		f(m)
+
+		reqs, _ := g.RequiredBy(m)
+		for _, r := range reqs {
+			if !enqueued[r] && r.Version != "none" {
+				queue = append(queue, r)
+				enqueued[r] = true
+			}
+		}
+	}
+}
+
+// FindPath reports a shortest requirement path starting at one of the roots of
+// the graph and ending at a module version m for which f(m) returns true, or
+// nil if no such path exists.
+func (g *Graph) FindPath(f func(module.Version) bool) []module.Version {
+	// firstRequires[a] = b means that in a breadth-first traversal of the
+	// requirement graph, the module version a was first required by b.
+	firstRequires := make(map[module.Version]module.Version)
+
+	queue := g.roots
+	for _, m := range g.roots {
+		firstRequires[m] = module.Version{}
+	}
+
+	for len(queue) > 0 {
+		m := queue[0]
+		queue = queue[1:]
+
+		if f(m) {
+			// Construct the path reversed (because we're starting from the far
+			// endpoint), then reverse it.
+			path := []module.Version{m}
+			for {
+				m = firstRequires[m]
+				if m.Path == "" {
+					break
+				}
+				path = append(path, m)
+			}
+
+			i, j := 0, len(path)-1
+			for i < j {
+				path[i], path[j] = path[j], path[i]
+				i++
+				j--
+			}
+
+			return path
+		}
+
+		reqs, _ := g.RequiredBy(m)
+		for _, r := range reqs {
+			if _, seen := firstRequires[r]; !seen {
+				queue = append(queue, r)
+				firstRequires[r] = m
+			}
+		}
+	}
+
+	return nil
+}
diff --git a/src/cmd/go/internal/mvs/mvs.go b/src/cmd/go/internal/mvs/mvs.go
index b630b61..6969f90 100644
--- a/src/cmd/go/internal/mvs/mvs.go
+++ b/src/cmd/go/internal/mvs/mvs.go
@@ -10,7 +10,6 @@
 	"fmt"
 	"sort"
 	"sync"
-	"sync/atomic"
 
 	"cmd/go/internal/par"
 
@@ -41,6 +40,11 @@
 	// Note that v1 < v2 can be written Max(v1, v2) != v1
 	// and similarly v1 <= v2 can be written Max(v1, v2) == v2.
 	Max(v1, v2 string) string
+}
+
+// An UpgradeReqs is a Reqs that can also identify available upgrades.
+type UpgradeReqs interface {
+	Reqs
 
 	// Upgrade returns the upgraded version of m,
 	// for use during an UpgradeAll operation.
@@ -54,6 +58,11 @@
 	// TODO(rsc): Upgrade must be able to return errors,
 	// but should "no latest version" just return m instead?
 	Upgrade(m module.Version) (module.Version, error)
+}
+
+// A DowngradeReqs is a Reqs that can also identify available downgrades.
+type DowngradeReqs interface {
+	Reqs
 
 	// Previous returns the version of m.Path immediately prior to m.Version,
 	// or "none" if no such version is known.
@@ -81,151 +90,91 @@
 }
 
 func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (module.Version, error)) ([]module.Version, error) {
-	// Explore work graph in parallel in case reqs.Required
-	// does high-latency network operations.
-	type modGraphNode struct {
-		m        module.Version
-		required []module.Version
-		upgrade  module.Version
-		err      error
-	}
-	var (
-		mu       sync.Mutex
-		modGraph = map[module.Version]*modGraphNode{}
-		min      = map[string]string{} // maps module path to minimum required version
-		haveErr  int32
-	)
-	setErr := func(n *modGraphNode, err error) {
-		n.err = err
-		atomic.StoreInt32(&haveErr, 1)
+	cmp := func(v1, v2 string) int {
+		if reqs.Max(v1, v2) != v1 {
+			return -1
+		}
+		if reqs.Max(v2, v1) != v2 {
+			return 1
+		}
+		return 0
 	}
 
+	var (
+		mu       sync.Mutex
+		g        = NewGraph(cmp, []module.Version{target})
+		upgrades = map[module.Version]module.Version{}
+		errs     = map[module.Version]error{} // (non-nil errors only)
+	)
+
+	// Explore work graph in parallel in case reqs.Required
+	// does high-latency network operations.
 	var work par.Work
 	work.Add(target)
 	work.Do(10, func(item interface{}) {
 		m := item.(module.Version)
 
-		node := &modGraphNode{m: m}
-		mu.Lock()
-		modGraph[m] = node
+		var required []module.Version
+		var err error
 		if m.Version != "none" {
-			if v, ok := min[m.Path]; !ok || reqs.Max(v, m.Version) != v {
-				min[m.Path] = m.Version
+			required, err = reqs.Required(m)
+		}
+
+		u := m
+		if upgrade != nil {
+			upgradeTo, upErr := upgrade(m)
+			if upErr == nil {
+				u = upgradeTo
+			} else if err == nil {
+				err = upErr
 			}
 		}
+
+		mu.Lock()
+		if err != nil {
+			errs[m] = err
+		}
+		if u != m {
+			upgrades[m] = u
+			required = append([]module.Version{u}, required...)
+		}
+		g.Require(m, required)
 		mu.Unlock()
 
-		if m.Version != "none" {
-			required, err := reqs.Required(m)
-			if err != nil {
-				setErr(node, err)
-				return
-			}
-			node.required = required
-			for _, r := range node.required {
-				work.Add(r)
-			}
-		}
-
-		if upgrade != nil {
-			u, err := upgrade(m)
-			if err != nil {
-				setErr(node, err)
-				return
-			}
-			if u != m {
-				node.upgrade = u
-				work.Add(u)
-			}
+		for _, r := range required {
+			work.Add(r)
 		}
 	})
 
 	// If there was an error, find the shortest path from the target to the
 	// node where the error occurred so we can report a useful error message.
-	if haveErr != 0 {
-		// neededBy[a] = b means a was added to the module graph by b.
-		neededBy := make(map[*modGraphNode]*modGraphNode)
-		q := make([]*modGraphNode, 0, len(modGraph))
-		q = append(q, modGraph[target])
-		for len(q) > 0 {
-			node := q[0]
-			q = q[1:]
-
-			if node.err != nil {
-				pathUpgrade := map[module.Version]module.Version{}
-
-				// Construct the error path reversed (from the error to the main module),
-				// then reverse it to obtain the usual order (from the main module to
-				// the error).
-				errPath := []module.Version{node.m}
-				for n, prev := neededBy[node], node; n != nil; n, prev = neededBy[n], n {
-					if n.upgrade == prev.m {
-						pathUpgrade[n.m] = prev.m
-					}
-					errPath = append(errPath, n.m)
-				}
-				i, j := 0, len(errPath)-1
-				for i < j {
-					errPath[i], errPath[j] = errPath[j], errPath[i]
-					i++
-					j--
-				}
-
-				isUpgrade := func(from, to module.Version) bool {
-					return pathUpgrade[from] == to
-				}
-
-				return nil, NewBuildListError(node.err, errPath, isUpgrade)
-			}
-
-			neighbors := node.required
-			if node.upgrade.Path != "" {
-				neighbors = append(neighbors, node.upgrade)
-			}
-			for _, neighbor := range neighbors {
-				nn := modGraph[neighbor]
-				if neededBy[nn] != nil {
-					continue
-				}
-				neededBy[nn] = node
-				q = append(q, nn)
-			}
+	if len(errs) > 0 {
+		errPath := g.FindPath(func(m module.Version) bool {
+			return errs[m] != nil
+		})
+		if len(errPath) == 0 {
+			panic("internal error: could not reconstruct path to module with error")
 		}
+
+		err := errs[errPath[len(errPath)-1]]
+		isUpgrade := func(from, to module.Version) bool {
+			if u, ok := upgrades[from]; ok {
+				return u == to
+			}
+			return false
+		}
+		return nil, NewBuildListError(err.(error), errPath, isUpgrade)
 	}
 
 	// The final list is the minimum version of each module found in the graph.
-
-	if v := min[target.Path]; v != target.Version {
+	list := g.BuildList()
+	if v := list[0]; v != target {
 		// target.Version will be "" for modload, the main client of MVS.
 		// "" denotes the main module, which has no version. However, MVS treats
 		// version strings as opaque, so "" is not a special value here.
 		// See golang.org/issue/31491, golang.org/issue/29773.
-		panic(fmt.Sprintf("mistake: chose version %q instead of target %+v", v, target)) // TODO: Don't panic.
+		panic(fmt.Sprintf("mistake: chose version %q instead of target %+v", v, target))
 	}
-
-	list := []module.Version{target}
-	for path, vers := range min {
-		if path != target.Path {
-			list = append(list, module.Version{Path: path, Version: vers})
-		}
-
-		n := modGraph[module.Version{Path: path, Version: vers}]
-		required := n.required
-		for _, r := range required {
-			if r.Version == "none" {
-				continue
-			}
-			v := min[r.Path]
-			if r.Path != target.Path && reqs.Max(v, r.Version) != v {
-				panic(fmt.Sprintf("mistake: version %q does not satisfy requirement %+v", v, r)) // TODO: Don't panic.
-			}
-		}
-	}
-
-	tail := list[1:]
-	sort.Slice(tail, func(i, j int) bool {
-		return tail[i].Path < tail[j].Path
-	})
 	return list, nil
 }
 
@@ -293,10 +242,15 @@
 	}
 	// First walk the base modules that must be listed.
 	var min []module.Version
+	haveBase := map[string]bool{}
 	for _, path := range base {
+		if haveBase[path] {
+			continue
+		}
 		m := module.Version{Path: path, Version: max[path]}
 		min = append(min, m)
 		walk(m)
+		haveBase[path] = true
 	}
 	// Now the reverse postorder to bring in anything else.
 	for i := len(postorder) - 1; i >= 0; i-- {
@@ -318,7 +272,7 @@
 
 // UpgradeAll returns a build list for the target module
 // in which every module is upgraded to its latest version.
-func UpgradeAll(target module.Version, reqs Reqs) ([]module.Version, error) {
+func UpgradeAll(target module.Version, reqs UpgradeReqs) ([]module.Version, error) {
 	return buildList(target, reqs, func(m module.Version) (module.Version, error) {
 		if m.Path == target.Path {
 			return target, nil
@@ -330,7 +284,7 @@
 
 // Upgrade returns a build list for the target module
 // in which the given additional modules are upgraded.
-func Upgrade(target module.Version, reqs Reqs, upgrade ...module.Version) ([]module.Version, error) {
+func Upgrade(target module.Version, reqs UpgradeReqs, upgrade ...module.Version) ([]module.Version, error) {
 	list, err := reqs.Required(target)
 	if err != nil {
 		return nil, err
@@ -369,11 +323,20 @@
 // The versions to be downgraded may be unreachable from reqs.Latest and
 // reqs.Previous, but the methods of reqs must otherwise handle such versions
 // correctly.
-func Downgrade(target module.Version, reqs Reqs, downgrade ...module.Version) ([]module.Version, error) {
-	list, err := reqs.Required(target)
+func Downgrade(target module.Version, reqs DowngradeReqs, downgrade ...module.Version) ([]module.Version, error) {
+	// Per https://research.swtch.com/vgo-mvs#algorithm_4:
+	// “To avoid an unnecessary downgrade to E 1.1, we must also add a new
+	// requirement on E 1.2. We can apply Algorithm R to find the minimal set of
+	// new requirements to write to go.mod.”
+	//
+	// In order to generate those new requirements, we need to identify versions
+	// for every module in the build list — not just reqs.Required(target).
+	list, err := BuildList(target, reqs)
 	if err != nil {
 		return nil, err
 	}
+	list = list[1:] // remove target
+
 	max := make(map[string]string)
 	for _, r := range list {
 		max[r.Path] = r.Version
@@ -406,6 +369,9 @@
 		}
 		added[m] = true
 		if v, ok := max[m.Path]; ok && reqs.Max(m.Version, v) != v {
+			// m would upgrade an existing dependency — it is not a strict downgrade,
+			// and because it was already present as a dependency, it could affect the
+			// behavior of other relevant packages.
 			exclude(m)
 			return
 		}
@@ -422,6 +388,7 @@
 			// is transient (we couldn't download go.mod), return the error from
 			// Downgrade. Currently, we can't tell what kind of error it is.
 			exclude(m)
+			return
 		}
 		for _, r := range list {
 			add(r)
@@ -433,8 +400,8 @@
 		}
 	}
 
-	var out []module.Version
-	out = append(out, target)
+	downgraded := make([]module.Version, 0, len(list)+1)
+	downgraded = append(downgraded, target)
 List:
 	for _, r := range list {
 		add(r)
@@ -461,10 +428,49 @@
 			add(p)
 			r = p
 		}
-		out = append(out, r)
+		downgraded = append(downgraded, r)
 	}
 
-	return out, nil
+	// The downgrades we computed above only downgrade to versions enumerated by
+	// reqs.Previous. However, reqs.Previous omits some versions — such as
+	// pseudo-versions and retracted versions — that may be selected as transitive
+	// requirements of other modules.
+	//
+	// If one of those requirements pulls the version back up above the version
+	// identified by reqs.Previous, then the transitive dependencies of that that
+	// initially-downgraded version should no longer matter — in particular, we
+	// should not add new dependencies on module paths that nothing else in the
+	// updated module graph even requires.
+	//
+	// In order to eliminate those spurious dependencies, we recompute the build
+	// list with the actual versions of the downgraded modules as selected by MVS,
+	// instead of our initial downgrades.
+	// (See the downhiddenartifact and downhiddencross test cases).
+	actual, err := BuildList(target, &override{
+		target: target,
+		list:   downgraded,
+		Reqs:   reqs,
+	})
+	if err != nil {
+		return nil, err
+	}
+	actualVersion := make(map[string]string, len(actual))
+	for _, m := range actual {
+		actualVersion[m.Path] = m.Version
+	}
+
+	downgraded = downgraded[:0]
+	for _, m := range list {
+		if v, ok := actualVersion[m.Path]; ok {
+			downgraded = append(downgraded, module.Version{Path: m.Path, Version: v})
+		}
+	}
+
+	return BuildList(target, &override{
+		target: target,
+		list:   downgraded,
+		Reqs:   reqs,
+	})
 }
 
 type override struct {
diff --git a/src/cmd/go/internal/mvs/mvs_test.go b/src/cmd/go/internal/mvs/mvs_test.go
index 721cd96..598ed66 100644
--- a/src/cmd/go/internal/mvs/mvs_test.go
+++ b/src/cmd/go/internal/mvs/mvs_test.go
@@ -28,10 +28,11 @@
 D5: E2
 G1: C4
 A2: B1 C4 D4
-build A: A B1 C2 D4 E2 F1
-upgrade* A: A B1 C4 D5 E2 F1 G1
-upgrade A C4: A B1 C4 D4 E2 F1 G1
-downgrade A2 D2: A2 C4 D2
+build A:       A B1 C2 D4 E2 F1
+upgrade* A:    A B1 C4 D5 E2 F1 G1
+upgrade A C4:  A B1 C4 D4 E2 F1 G1
+build A2:     A2 B1 C4 D4 E2 F1 G1
+downgrade A2 D2: A2 C4 D2 E2 F1 G1
 
 name: trim
 A: B1 C2
@@ -68,7 +69,7 @@
 C: D2
 D1: E2
 D2: E1
-build A: A B1 C D2 E1
+build A:      A B1 C D2 E1
 upgrade A B2: A B2 C D2 E2
 
 name: cross1R
@@ -136,17 +137,17 @@
 A: D1
 D1: E2
 D2: E1
-build A: A D1 E2
-upgrade* A: A D2 E2
-upgrade A D2: A D2 E2
+build A:       A D1 E2
+upgrade* A:    A D2 E2
+upgrade A D2:  A D2 E2
 upgradereq A D2: D2 E2
 
 name: cross6
 A: D2
 D1: E2
 D2: E1
-build A: A D2 E1
-upgrade* A: A D2 E2
+build A:      A D2 E1
+upgrade* A:   A D2 E2
 upgrade A E2: A D2 E2
 
 name: cross7
@@ -175,7 +176,7 @@
 B2:
 C2:
 D2:
-build A: A B1 C1 D1
+build A:    A B1 C1 D1
 upgrade* A: A B2 C2 D2
 
 name: simplify
@@ -194,7 +195,7 @@
 B5.hidden:
 C2:
 C3:
-build A: A B1 C1
+build A:    A B1 C1
 upgrade* A: A B4 C3
 
 name: up2
@@ -206,15 +207,15 @@
 B5.hidden:
 C2:
 C3:
-build A: A B5.hidden C1
+build A:    A B5.hidden C1
 upgrade* A: A B5.hidden C3
 
 name: down1
 A: B2
 B1: C1
 B2: C2
-build A: A B2 C2
-downgrade A C1: A B1
+build A:        A B2 C2
+downgrade A C1: A B1 C1
 
 name: down2
 A: B2 E2
@@ -227,19 +228,113 @@
 E2: D2
 E1:
 F1:
-downgrade A F1: A B1 E1
+build A:        A B2 C2 D2 E2 F2
+downgrade A F1: A B1 C1 D1 E1 F1
+
+# https://research.swtch.com/vgo-mvs#algorithm_4:
+# “[D]owngrades are constrained to only downgrade packages, not also upgrade
+# them; if an upgrade before downgrade is needed, the user must ask for it
+# explicitly.”
+#
+# Here, downgrading B2 to B1 upgrades C1 to C2, and C2 does not depend on D2.
+# However, C2 would be an upgrade — not a downgrade — so B1 must also be
+# rejected.
+name: downcross1
+A: B2 C1
+B1: C2
+B2: C1
+C1: D2
+C2:
+D1:
+D2:
+build A:        A B2 C1 D2
+downgrade A D1: A       D1
+
+# https://research.swtch.com/vgo-mvs#algorithm_4:
+# “Unlike upgrades, downgrades must work by removing requirements, not adding
+# them.”
+#
+# However, downgrading a requirement may introduce a new requirement on a
+# previously-unrequired module. If each dependency's requirements are complete
+# (“tidy”), that can't change the behavior of any other package whose version is
+# not also being downgraded, so we should allow it.
+name: downcross2
+A: B2
+B1: C1
+B2: D2
+C1:
+D1:
+D2:
+build A:        A B2    D2
+downgrade A D1: A B1 C1 D1
 
 name: downcycle
 A: A B2
 B2: A
 B1:
+build A:        A B2
 downgrade A B1: A B1
 
+# Both B3 and C2 require D2.
+# If we downgrade D to D1, then in isolation B3 would downgrade to B1,
+# because B2 is hidden — B1 is the next-highest version that is not hidden.
+# However, if we downgrade D, we will also downgrade C to C1.
+# And C1 requires B2.hidden, and B2.hidden also meets our requirements:
+# it is compatible with D1 and a strict downgrade from B3.
+#
+# Since neither the initial nor the final build list includes B1,
+# and the nothing in the final downgraded build list requires E at all,
+# no dependency on E1 (required by only B1) should be introduced.
+#
+name: downhiddenartifact
+A: B3 C2
+A1: B3
+B1: E1
+B2.hidden:
+B3: D2
+C1: B2.hidden
+C2: D2
+D1:
+D2:
+build A1: A1 B3 D2
+downgrade A1 D1: A1 B1 D1 E1
+build A: A B3 C2 D2
+downgrade A D1: A B2.hidden C1 D1
+
+# Both B3 and C3 require D2.
+# If we downgrade D to D1, then in isolation B3 would downgrade to B1,
+# and C3 would downgrade to C1.
+# But C1 requires B2.hidden, and B1 requires C2.hidden, so we can't
+# downgrade to either of those without pulling the other back up a little.
+#
+# B2.hidden and C2.hidden are both compatible with D1, so that still
+# meets our requirements — but then we're in an odd state in which
+# B and C have both been downgraded to hidden versions, without any
+# remaining requirements to explain how those hidden versions got there.
+#
+# TODO(bcmills): Would it be better to force downgrades to land on non-hidden
+# versions?
+# In this case, that would remove the dependencies on B and C entirely.
+#
+name: downhiddencross
+A: B3 C3
+B1: C2.hidden
+B2.hidden:
+B3: D2
+C1: B2.hidden
+C2.hidden:
+C3: D2
+D1:
+D2:
+build A: A B3 C3 D2
+downgrade A D1: A B2.hidden C2.hidden D1
+
 # golang.org/issue/25542.
 name: noprev1
 A: B4 C2
 B2.hidden:
 C2:
+build A:               A B4        C2
 downgrade A B2.hidden: A B2.hidden C2
 
 name: noprev2
@@ -247,6 +342,7 @@
 B2.hidden:
 B1:
 C2:
+build A:               A B4        C2
 downgrade A B2.hidden: A B2.hidden C2
 
 name: noprev3
@@ -254,6 +350,7 @@
 B3:
 B2.hidden:
 C2:
+build A:               A B4        C2
 downgrade A B2.hidden: A B2.hidden C2
 
 # Cycles involving the target.
@@ -264,9 +361,9 @@
 B1: A1
 B2: A2
 B3: A3
-build A: A B1
+build A:      A B1
 upgrade A B2: A B2
-upgrade* A: A B3
+upgrade* A:   A B3
 
 # golang.org/issue/29773:
 # Requirements of older versions of the target
@@ -280,7 +377,7 @@
 C1: A2
 C2:
 D2:
-build A: A B1 C1 D1
+build A:    A B1 C1 D1
 upgrade* A: A B2 C2 D2
 
 # Cycles with multiple possible solutions.
@@ -293,23 +390,23 @@
 C1:
 C2: B2
 build M: M A1 B2 C2
-req M: A1 B2
-req M A: A1 B2
-req M C: A1 C2
+req M:     A1 B2
+req M A:   A1 B2
+req M C:   A1 C2
 
 # Requirement minimization.
 
 name: req1
 A: B1 C1 D1 E1 F1
 B1: C1 E1 F1
-req A: B1 D1
+req A:   B1    D1
 req A C: B1 C1 D1
 
 name: req2
 A: G1 H1
 G1: H1
 H1: G1
-req A: G1
+req A:   G1
 req A G: G1
 req A H: H1
 
@@ -326,7 +423,20 @@
 B1: Cnone D1
 E1: Fnone
 build M: M B1 D1 E1
-req M: B1 E1
+req M:     B1    E1
+
+name: reqdup
+M: A1 B1
+A1: B1
+B1:
+req M A A: A1
+
+name: reqcross
+M: A1 B1 C1
+A1: B1 C1
+B1: C1
+C1:
+req M A B: A1 B1
 `
 
 func Test(t *testing.T) {
diff --git a/src/cmd/go/internal/renameio/renameio.go b/src/cmd/go/internal/renameio/renameio.go
deleted file mode 100644
index 9788171..0000000
--- a/src/cmd/go/internal/renameio/renameio.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package renameio writes files atomically by renaming temporary files.
-package renameio
-
-import (
-	"bytes"
-	"io"
-	"io/fs"
-	"math/rand"
-	"os"
-	"path/filepath"
-	"strconv"
-
-	"cmd/go/internal/robustio"
-)
-
-const patternSuffix = ".tmp"
-
-// Pattern returns a glob pattern that matches the unrenamed temporary files
-// created when writing to filename.
-func Pattern(filename string) string {
-	return filepath.Join(filepath.Dir(filename), filepath.Base(filename)+patternSuffix)
-}
-
-// WriteFile is like os.WriteFile, but first writes data to an arbitrary
-// file in the same directory as filename, then renames it atomically to the
-// final name.
-//
-// That ensures that the final location, if it exists, is always a complete file.
-func WriteFile(filename string, data []byte, perm fs.FileMode) (err error) {
-	return WriteToFile(filename, bytes.NewReader(data), perm)
-}
-
-// WriteToFile is a variant of WriteFile that accepts the data as an io.Reader
-// instead of a slice.
-func WriteToFile(filename string, data io.Reader, perm fs.FileMode) (err error) {
-	f, err := tempFile(filepath.Dir(filename), filepath.Base(filename), perm)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		// Only call os.Remove on f.Name() if we failed to rename it: otherwise,
-		// some other process may have created a new file with the same name after
-		// that.
-		if err != nil {
-			f.Close()
-			os.Remove(f.Name())
-		}
-	}()
-
-	if _, err := io.Copy(f, data); err != nil {
-		return err
-	}
-	// Sync the file before renaming it: otherwise, after a crash the reader may
-	// observe a 0-length file instead of the actual contents.
-	// See https://golang.org/issue/22397#issuecomment-380831736.
-	if err := f.Sync(); err != nil {
-		return err
-	}
-	if err := f.Close(); err != nil {
-		return err
-	}
-
-	return robustio.Rename(f.Name(), filename)
-}
-
-// ReadFile is like os.ReadFile, but on Windows retries spurious errors that
-// may occur if the file is concurrently replaced.
-//
-// Errors are classified heuristically and retries are bounded, so even this
-// function may occasionally return a spurious error on Windows.
-// If so, the error will likely wrap one of:
-// 	- syscall.ERROR_ACCESS_DENIED
-// 	- syscall.ERROR_FILE_NOT_FOUND
-// 	- internal/syscall/windows.ERROR_SHARING_VIOLATION
-func ReadFile(filename string) ([]byte, error) {
-	return robustio.ReadFile(filename)
-}
-
-// tempFile creates a new temporary file with given permission bits.
-func tempFile(dir, prefix string, perm fs.FileMode) (f *os.File, err error) {
-	for i := 0; i < 10000; i++ {
-		name := filepath.Join(dir, prefix+strconv.Itoa(rand.Intn(1000000000))+patternSuffix)
-		f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm)
-		if os.IsExist(err) {
-			continue
-		}
-		break
-	}
-	return
-}
diff --git a/src/cmd/go/internal/renameio/renameio_test.go b/src/cmd/go/internal/renameio/renameio_test.go
deleted file mode 100644
index 5b2ed83..0000000
--- a/src/cmd/go/internal/renameio/renameio_test.go
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !plan9
-
-package renameio
-
-import (
-	"encoding/binary"
-	"errors"
-	"internal/testenv"
-	"math/rand"
-	"os"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"sync"
-	"sync/atomic"
-	"syscall"
-	"testing"
-	"time"
-
-	"cmd/go/internal/robustio"
-)
-
-func TestConcurrentReadsAndWrites(t *testing.T) {
-	if runtime.GOOS == "darwin" && strings.HasSuffix(testenv.Builder(), "-10_14") {
-		testenv.SkipFlaky(t, 33041)
-	}
-
-	dir, err := os.MkdirTemp("", "renameio")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
-	path := filepath.Join(dir, "blob.bin")
-
-	const chunkWords = 8 << 10
-	buf := make([]byte, 2*chunkWords*8)
-	for i := uint64(0); i < 2*chunkWords; i++ {
-		binary.LittleEndian.PutUint64(buf[i*8:], i)
-	}
-
-	var attempts int64 = 128
-	if !testing.Short() {
-		attempts *= 16
-	}
-	const parallel = 32
-
-	var sem = make(chan bool, parallel)
-
-	var (
-		writeSuccesses, readSuccesses int64 // atomic
-		writeErrnoSeen, readErrnoSeen sync.Map
-	)
-
-	for n := attempts; n > 0; n-- {
-		sem <- true
-		go func() {
-			defer func() { <-sem }()
-
-			time.Sleep(time.Duration(rand.Intn(100)) * time.Microsecond)
-			offset := rand.Intn(chunkWords)
-			chunk := buf[offset*8 : (offset+chunkWords)*8]
-			if err := WriteFile(path, chunk, 0666); err == nil {
-				atomic.AddInt64(&writeSuccesses, 1)
-			} else if robustio.IsEphemeralError(err) {
-				var (
-					errno syscall.Errno
-					dup   bool
-				)
-				if errors.As(err, &errno) {
-					_, dup = writeErrnoSeen.LoadOrStore(errno, true)
-				}
-				if !dup {
-					t.Logf("ephemeral error: %v", err)
-				}
-			} else {
-				t.Errorf("unexpected error: %v", err)
-			}
-
-			time.Sleep(time.Duration(rand.Intn(100)) * time.Microsecond)
-			data, err := ReadFile(path)
-			if err == nil {
-				atomic.AddInt64(&readSuccesses, 1)
-			} else if robustio.IsEphemeralError(err) {
-				var (
-					errno syscall.Errno
-					dup   bool
-				)
-				if errors.As(err, &errno) {
-					_, dup = readErrnoSeen.LoadOrStore(errno, true)
-				}
-				if !dup {
-					t.Logf("ephemeral error: %v", err)
-				}
-				return
-			} else {
-				t.Errorf("unexpected error: %v", err)
-				return
-			}
-
-			if len(data) != 8*chunkWords {
-				t.Errorf("read %d bytes, but each write is a %d-byte file", len(data), 8*chunkWords)
-				return
-			}
-
-			u := binary.LittleEndian.Uint64(data)
-			for i := 1; i < chunkWords; i++ {
-				next := binary.LittleEndian.Uint64(data[i*8:])
-				if next != u+1 {
-					t.Errorf("wrote sequential integers, but read integer out of sequence at offset %d", i)
-					return
-				}
-				u = next
-			}
-		}()
-	}
-
-	for n := parallel; n > 0; n-- {
-		sem <- true
-	}
-
-	var minWriteSuccesses int64 = attempts
-	if runtime.GOOS == "windows" {
-		// Windows produces frequent "Access is denied" errors under heavy rename load.
-		// As long as those are the only errors and *some* of the writes succeed, we're happy.
-		minWriteSuccesses = attempts / 4
-	}
-
-	if writeSuccesses < minWriteSuccesses {
-		t.Errorf("%d (of %d) writes succeeded; want ≥ %d", writeSuccesses, attempts, minWriteSuccesses)
-	} else {
-		t.Logf("%d (of %d) writes succeeded (ok: ≥ %d)", writeSuccesses, attempts, minWriteSuccesses)
-	}
-
-	var minReadSuccesses int64 = attempts
-
-	switch runtime.GOOS {
-	case "windows":
-		// Windows produces frequent "Access is denied" errors under heavy rename load.
-		// As long as those are the only errors and *some* of the reads succeed, we're happy.
-		minReadSuccesses = attempts / 4
-
-	case "darwin", "ios":
-		// The filesystem on certain versions of macOS (10.14) and iOS (affected
-		// versions TBD) occasionally fail with "no such file or directory" errors.
-		// See https://golang.org/issue/33041 and https://golang.org/issue/42066.
-		// The flake rate is fairly low, so ensure that at least 75% of attempts
-		// succeed.
-		minReadSuccesses = attempts - (attempts / 4)
-	}
-
-	if readSuccesses < minReadSuccesses {
-		t.Errorf("%d (of %d) reads succeeded; want ≥ %d", readSuccesses, attempts, minReadSuccesses)
-	} else {
-		t.Logf("%d (of %d) reads succeeded (ok: ≥ %d)", readSuccesses, attempts, minReadSuccesses)
-	}
-}
diff --git a/src/cmd/go/internal/renameio/umask_test.go b/src/cmd/go/internal/renameio/umask_test.go
deleted file mode 100644
index 65e4fa5..0000000
--- a/src/cmd/go/internal/renameio/umask_test.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !plan9,!windows,!js
-
-package renameio
-
-import (
-	"io/fs"
-	"os"
-	"path/filepath"
-	"syscall"
-	"testing"
-)
-
-func TestWriteFileModeAppliesUmask(t *testing.T) {
-	dir, err := os.MkdirTemp("", "renameio")
-	if err != nil {
-		t.Fatalf("Failed to create temporary directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
-
-	const mode = 0644
-	const umask = 0007
-	defer syscall.Umask(syscall.Umask(umask))
-
-	file := filepath.Join(dir, "testWrite")
-	err = WriteFile(file, []byte("go-build"), mode)
-	if err != nil {
-		t.Fatalf("Failed to write file: %v", err)
-	}
-
-	fi, err := os.Stat(file)
-	if err != nil {
-		t.Fatalf("Stat %q (looking for mode %#o): %s", file, mode, err)
-	}
-
-	if fi.Mode()&fs.ModePerm != 0640 {
-		t.Errorf("Stat %q: mode %#o want %#o", file, fi.Mode()&fs.ModePerm, 0640)
-	}
-}
diff --git a/src/cmd/go/internal/robustio/robustio_flaky.go b/src/cmd/go/internal/robustio/robustio_flaky.go
index 5bd44bd..d5c2418 100644
--- a/src/cmd/go/internal/robustio/robustio_flaky.go
+++ b/src/cmd/go/internal/robustio/robustio_flaky.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build windows || darwin
 // +build windows darwin
 
 package robustio
diff --git a/src/cmd/go/internal/robustio/robustio_other.go b/src/cmd/go/internal/robustio/robustio_other.go
index 6fe7b7e..3a20cac 100644
--- a/src/cmd/go/internal/robustio/robustio_other.go
+++ b/src/cmd/go/internal/robustio/robustio_other.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows && !darwin
 // +build !windows,!darwin
 
 package robustio
diff --git a/src/cmd/go/internal/run/run.go b/src/cmd/go/internal/run/run.go
index 666b1a0..784f716 100644
--- a/src/cmd/go/internal/run/run.go
+++ b/src/cmd/go/internal/run/run.go
@@ -8,13 +8,16 @@
 import (
 	"context"
 	"fmt"
+	"go/build"
 	"os"
 	"path"
+	"path/filepath"
 	"strings"
 
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/load"
+	"cmd/go/internal/modload"
 	"cmd/go/internal/str"
 	"cmd/go/internal/work"
 )
@@ -24,10 +27,21 @@
 	Short:     "compile and run Go program",
 	Long: `
 Run compiles and runs the named main Go package.
-Typically the package is specified as a list of .go source files from a single directory,
-but it may also be an import path, file system path, or pattern
+Typically the package is specified as a list of .go source files from a single
+directory, but it may also be an import path, file system path, or pattern
 matching a single known package, as in 'go run .' or 'go run my/cmd'.
 
+If the package argument has a version suffix (like @latest or @v1.0.0),
+"go run" builds the program in module-aware mode, ignoring the go.mod file in
+the current directory or any parent directory, if there is one. This is useful
+for running programs without affecting the dependencies of the main module.
+
+If the package argument doesn't have a version suffix, "go run" may run in
+module-aware mode or GOPATH mode, depending on the GO111MODULE environment
+variable and the presence of a go.mod file. See 'go help modules' for details.
+If module-aware mode is enabled, "go run" runs in the context of the main
+module.
+
 By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
 If the -exec flag is given, 'go run' invokes the binary using xprog:
 	'xprog a.out arguments...'.
@@ -59,14 +73,26 @@
 }
 
 func runRun(ctx context.Context, cmd *base.Command, args []string) {
+	if shouldUseOutsideModuleMode(args) {
+		// Set global module flags for 'go run cmd@version'.
+		// This must be done before modload.Init, but we need to call work.BuildInit
+		// before loading packages, since it affects package locations, e.g.,
+		// for -race and -msan.
+		modload.ForceUseModules = true
+		modload.RootMode = modload.NoRoot
+		modload.AllowMissingModuleImports()
+		modload.Init()
+	}
 	work.BuildInit()
 	var b work.Builder
 	b.Init()
 	b.Print = printStderr
+
 	i := 0
 	for i < len(args) && strings.HasSuffix(args[i], ".go") {
 		i++
 	}
+	pkgOpts := load.PackageOpts{MainOnly: true}
 	var p *load.Package
 	if i > 0 {
 		files := args[:i]
@@ -77,18 +103,29 @@
 				base.Fatalf("go run: cannot run *_test.go files (%s)", file)
 			}
 		}
-		p = load.GoFilesPackage(ctx, files)
+		p = load.GoFilesPackage(ctx, pkgOpts, files)
 	} else if len(args) > 0 && !strings.HasPrefix(args[0], "-") {
-		pkgs := load.PackagesAndErrors(ctx, args[:1])
+		arg := args[0]
+		var pkgs []*load.Package
+		if strings.Contains(arg, "@") && !build.IsLocalImport(arg) && !filepath.IsAbs(arg) {
+			var err error
+			pkgs, err = load.PackagesAndErrorsOutsideModule(ctx, pkgOpts, args[:1])
+			if err != nil {
+				base.Fatalf("go run: %v", err)
+			}
+		} else {
+			pkgs = load.PackagesAndErrors(ctx, pkgOpts, args[:1])
+		}
+
 		if len(pkgs) == 0 {
-			base.Fatalf("go run: no packages loaded from %s", args[0])
+			base.Fatalf("go run: no packages loaded from %s", arg)
 		}
 		if len(pkgs) > 1 {
 			var names []string
 			for _, p := range pkgs {
 				names = append(names, p.ImportPath)
 			}
-			base.Fatalf("go run: pattern %s matches multiple packages:\n\t%s", args[0], strings.Join(names, "\n\t"))
+			base.Fatalf("go run: pattern %s matches multiple packages:\n\t%s", arg, strings.Join(names, "\n\t"))
 		}
 		p = pkgs[0]
 		i++
@@ -98,9 +135,6 @@
 	cmdArgs := args[i:]
 	load.CheckPackageErrors([]*load.Package{p})
 
-	if p.Name != "main" {
-		base.Fatalf("go run: cannot run non-main package")
-	}
 	p.Internal.OmitDebug = true
 	p.Target = "" // must build - not up to date
 	if p.Internal.CmdlineFiles {
@@ -123,11 +157,34 @@
 	} else {
 		p.Internal.ExeName = path.Base(p.ImportPath)
 	}
+
 	a1 := b.LinkAction(work.ModeBuild, work.ModeBuild, p)
 	a := &work.Action{Mode: "go run", Func: buildRunProgram, Args: cmdArgs, Deps: []*work.Action{a1}}
 	b.Do(ctx, a)
 }
 
+// shouldUseOutsideModuleMode returns whether 'go run' will load packages in
+// module-aware mode, ignoring the go.mod file in the current directory. It
+// returns true if the first argument contains "@", does not begin with "-"
+// (resembling a flag) or end with ".go" (a file). The argument must not be a
+// local or absolute file path.
+//
+// These rules are slightly different than other commands. Whether or not
+// 'go run' uses this mode, it interprets arguments ending with ".go" as files
+// and uses arguments up to the last ".go" argument to comprise the package.
+// If there are no ".go" arguments, only the first argument is interpreted
+// as a package path, since there can be only one package.
+func shouldUseOutsideModuleMode(args []string) bool {
+	// NOTE: "@" not allowed in import paths, but it is allowed in non-canonical
+	// versions.
+	return len(args) > 0 &&
+		!strings.HasSuffix(args[0], ".go") &&
+		!strings.HasPrefix(args[0], "-") &&
+		strings.Contains(args[0], "@") &&
+		!build.IsLocalImport(args[0]) &&
+		!filepath.IsAbs(args[0])
+}
+
 // buildRunProgram is the action for running a binary that has already
 // been compiled. We ignore exit status.
 func buildRunProgram(b *work.Builder, ctx context.Context, a *work.Action) error {
diff --git a/src/cmd/go/internal/search/search.go b/src/cmd/go/internal/search/search.go
index 18738cf..a0c806a 100644
--- a/src/cmd/go/internal/search/search.go
+++ b/src/cmd/go/internal/search/search.go
@@ -155,7 +155,7 @@
 			}
 
 			if !fi.IsDir() {
-				if fi.Mode()&fs.ModeSymlink != 0 && want {
+				if fi.Mode()&fs.ModeSymlink != 0 && want && strings.Contains(m.pattern, "...") {
 					if target, err := fsys.Stat(path); err == nil && target.IsDir() {
 						fmt.Fprintf(os.Stderr, "warning: ignoring symlink %s\n", path)
 					}
@@ -445,7 +445,7 @@
 			for i, dir := range m.Dirs {
 				absDir := dir
 				if !filepath.IsAbs(dir) {
-					absDir = filepath.Join(base.Cwd, dir)
+					absDir = filepath.Join(base.Cwd(), dir)
 				}
 				if bp, _ := cfg.BuildContext.ImportDir(absDir, build.FindOnly); bp.ImportPath != "" && bp.ImportPath != "." {
 					m.Pkgs[i] = bp.ImportPath
@@ -571,7 +571,6 @@
 // If so, InDir returns an equivalent path relative to dir.
 // If not, InDir returns an empty string.
 // InDir makes some effort to succeed even in the presence of symbolic links.
-// TODO(rsc): Replace internal/test.inDir with a call to this function for Go 1.12.
 func InDir(path, dir string) string {
 	if rel := inDirLex(path, dir); rel != "" {
 		return rel
diff --git a/src/cmd/go/internal/test/cover.go b/src/cmd/go/internal/test/cover.go
index 9841791..657d22a 100644
--- a/src/cmd/go/internal/test/cover.go
+++ b/src/cmd/go/internal/test/cover.go
@@ -26,8 +26,8 @@
 	if testCoverProfile == "" || testC {
 		return
 	}
-	if !filepath.IsAbs(testCoverProfile) && testOutputDir != "" {
-		testCoverProfile = filepath.Join(testOutputDir, testCoverProfile)
+	if !filepath.IsAbs(testCoverProfile) {
+		testCoverProfile = filepath.Join(testOutputDir.getAbs(), testCoverProfile)
 	}
 
 	// No mutex - caller's responsibility to call with no racing goroutines.
diff --git a/src/cmd/go/internal/test/flagdefs.go b/src/cmd/go/internal/test/flagdefs.go
index 8a0a076..37ac81c 100644
--- a/src/cmd/go/internal/test/flagdefs.go
+++ b/src/cmd/go/internal/test/flagdefs.go
@@ -28,6 +28,7 @@
 	"parallel":             true,
 	"run":                  true,
 	"short":                true,
+	"shuffle":              true,
 	"timeout":              true,
 	"trace":                true,
 	"v":                    true,
diff --git a/src/cmd/go/internal/test/genflags.go b/src/cmd/go/internal/test/genflags.go
index 30334b0..9277de7 100644
--- a/src/cmd/go/internal/test/genflags.go
+++ b/src/cmd/go/internal/test/genflags.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 package main
diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go
index 7fc9e8f..59ea1ef 100644
--- a/src/cmd/go/internal/test/test.go
+++ b/src/cmd/go/internal/test/test.go
@@ -29,6 +29,7 @@
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/load"
 	"cmd/go/internal/lockedfile"
+	"cmd/go/internal/search"
 	"cmd/go/internal/str"
 	"cmd/go/internal/trace"
 	"cmd/go/internal/work"
@@ -117,8 +118,8 @@
 
 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
+restricted set of 'cacheable' test flags, defined as -benchtime, -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
@@ -271,6 +272,13 @@
 	    the Go tree can run a sanity check but not spend time running
 	    exhaustive tests.
 
+	-shuffle off,on,N
+		Randomize the execution order of tests and benchmarks.
+		It is off by default. If -shuffle is set to on, then it will seed
+		the randomizer using the system clock. If -shuffle is set to an
+		integer N, then N will be used as the seed value. In both cases,
+		the seed will be reported for reproducibility.
+
 	-timeout d
 	    If a test binary runs longer than duration d, panic.
 	    If d is 0, the timeout is disabled.
@@ -478,7 +486,8 @@
 	testJSON         bool                              // -json flag
 	testList         string                            // -list flag
 	testO            string                            // -o flag
-	testOutputDir    = base.Cwd                        // -outputdir flag
+	testOutputDir    outputdirFlag                     // -outputdir flag
+	testShuffle      shuffleFlag                       // -shuffle flag
 	testTimeout      time.Duration                     // -timeout flag
 	testV            bool                              // -v flag
 	testVet          = vetFlag{flags: defaultVetFlags} // -vet flag
@@ -568,8 +577,6 @@
 }
 
 func runTest(ctx context.Context, cmd *base.Command, args []string) {
-	load.ModResolveTests = true
-
 	pkgArgs, testArgs = testFlags(args)
 
 	if cfg.DebugTrace != "" {
@@ -595,7 +602,8 @@
 	work.VetFlags = testVet.flags
 	work.VetExplicit = testVet.explicit
 
-	pkgs = load.PackagesAndErrors(ctx, pkgArgs)
+	pkgOpts := load.PackageOpts{ModResolveTests: true}
+	pkgs = load.PackagesAndErrors(ctx, pkgOpts, pkgArgs)
 	load.CheckPackageErrors(pkgs)
 	if len(pkgs) == 0 {
 		base.Fatalf("no packages to test")
@@ -679,7 +687,7 @@
 		sort.Strings(all)
 
 		a := &work.Action{Mode: "go test -i"}
-		pkgs := load.PackagesAndErrors(ctx, all)
+		pkgs := load.PackagesAndErrors(ctx, pkgOpts, all)
 		load.CheckPackageErrors(pkgs)
 		for _, p := range pkgs {
 			if cfg.BuildToolchainName == "gccgo" && p.Standard {
@@ -702,11 +710,11 @@
 		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)
+			match[i] = load.MatchPackage(testCoverPaths[i], base.Cwd())
 		}
 
 		// Select for coverage all dependencies matching the testCoverPaths patterns.
-		for _, p := range load.TestPackageList(ctx, pkgs) {
+		for _, p := range load.TestPackageList(ctx, pkgOpts, pkgs) {
 			haveMatch := false
 			for i := range testCoverPaths {
 				if match[i](p) {
@@ -715,6 +723,12 @@
 				}
 			}
 
+			// A package which only has test files can't be imported
+			// as a dependency, nor can it be instrumented for coverage.
+			if len(p.GoFiles)+len(p.CgoFiles) == 0 {
+				continue
+			}
+
 			// Silently ignore attempts to run coverage on
 			// sync/atomic when using atomic coverage mode.
 			// Atomic coverage mode uses sync/atomic, so
@@ -768,7 +782,7 @@
 			ensureImport(p, "sync/atomic")
 		}
 
-		buildTest, runTest, printTest, err := builderTest(&b, ctx, p)
+		buildTest, runTest, printTest, err := builderTest(&b, ctx, pkgOpts, p)
 		if err != nil {
 			str := err.Error()
 			str = strings.TrimPrefix(str, "\n")
@@ -835,7 +849,7 @@
 	"update",
 }
 
-func builderTest(b *work.Builder, ctx context.Context, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) {
+func builderTest(b *work.Builder, ctx context.Context, pkgOpts load.PackageOpts, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) {
 	if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
 		build := b.CompileAction(work.ModeBuild, work.ModeBuild, p)
 		run := &work.Action{Mode: "test run", Package: p, Deps: []*work.Action{build}}
@@ -858,7 +872,7 @@
 			DeclVars: declareCoverVars,
 		}
 	}
-	pmain, ptest, pxtest, err := load.TestPackagesFor(ctx, p, cover)
+	pmain, ptest, pxtest, err := load.TestPackagesFor(ctx, pkgOpts, p, cover)
 	if err != nil {
 		return nil, nil, nil, err
 	}
@@ -931,11 +945,11 @@
 	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)
+		target := filepath.Join(base.Cwd(), testBinary+cfg.ExeSuffix)
 		if testO != "" {
 			target = testO
 			if !filepath.IsAbs(target) {
-				target = filepath.Join(base.Cwd, target)
+				target = filepath.Join(base.Cwd(), target)
 			}
 		}
 		if target == os.DevNull {
@@ -1326,7 +1340,8 @@
 			return false
 		}
 		switch arg[:i] {
-		case "-test.cpu",
+		case "-test.benchtime",
+			"-test.cpu",
 			"-test.list",
 			"-test.parallel",
 			"-test.run",
@@ -1499,7 +1514,7 @@
 			if !filepath.IsAbs(name) {
 				name = filepath.Join(pwd, name)
 			}
-			if a.Package.Root == "" || !inDir(name, a.Package.Root) {
+			if a.Package.Root == "" || search.InDir(name, a.Package.Root) == "" {
 				// Do not recheck files outside the module, GOPATH, or GOROOT root.
 				break
 			}
@@ -1508,7 +1523,7 @@
 			if !filepath.IsAbs(name) {
 				name = filepath.Join(pwd, name)
 			}
-			if a.Package.Root == "" || !inDir(name, a.Package.Root) {
+			if a.Package.Root == "" || search.InDir(name, a.Package.Root) == "" {
 				// Do not recheck files outside the module, GOPATH, or GOROOT root.
 				break
 			}
@@ -1526,18 +1541,6 @@
 	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)
diff --git a/src/cmd/go/internal/test/testflag.go b/src/cmd/go/internal/test/testflag.go
index 10e6604..08f1efa 100644
--- a/src/cmd/go/internal/test/testflag.go
+++ b/src/cmd/go/internal/test/testflag.go
@@ -10,6 +10,7 @@
 	"fmt"
 	"os"
 	"path/filepath"
+	"strconv"
 	"strings"
 	"time"
 
@@ -61,15 +62,16 @@
 	cf.String("memprofilerate", "", "")
 	cf.StringVar(&testMutexProfile, "mutexprofile", "", "")
 	cf.String("mutexprofilefraction", "", "")
-	cf.Var(outputdirFlag{&testOutputDir}, "outputdir", "")
+	cf.Var(&testOutputDir, "outputdir", "")
 	cf.Int("parallel", 0, "")
 	cf.String("run", "", "")
 	cf.Bool("short", false, "")
 	cf.DurationVar(&testTimeout, "timeout", 10*time.Minute, "")
 	cf.StringVar(&testTrace, "trace", "", "")
 	cf.BoolVar(&testV, "v", false, "")
+	cf.Var(&testShuffle, "shuffle", "")
 
-	for name, _ := range passFlagToTest {
+	for name := range passFlagToTest {
 		cf.Var(cf.Lookup(name).Value, "test."+name, "")
 	}
 }
@@ -126,19 +128,26 @@
 // outputdirFlag implements the -outputdir flag.
 // It interprets an empty value as the working directory of the 'go' command.
 type outputdirFlag struct {
-	resolved *string
+	abs string
 }
 
-func (f outputdirFlag) String() string { return *f.resolved }
-func (f outputdirFlag) Set(value string) (err error) {
+func (f *outputdirFlag) String() string {
+	return f.abs
+}
+func (f *outputdirFlag) Set(value string) (err error) {
 	if value == "" {
-		// The empty string implies the working directory of the 'go' command.
-		*f.resolved = base.Cwd
+		f.abs = ""
 	} else {
-		*f.resolved, err = filepath.Abs(value)
+		f.abs, err = filepath.Abs(value)
 	}
 	return err
 }
+func (f *outputdirFlag) getAbs() string {
+	if f.abs == "" {
+		return base.Cwd()
+	}
+	return f.abs
+}
 
 // vetFlag implements the special parsing logic for the -vet flag:
 // a comma-separated list, with a distinguished value "off" and
@@ -194,6 +203,41 @@
 	return nil
 }
 
+type shuffleFlag struct {
+	on   bool
+	seed *int64
+}
+
+func (f *shuffleFlag) String() string {
+	if !f.on {
+		return "off"
+	}
+	if f.seed == nil {
+		return "on"
+	}
+	return fmt.Sprintf("%d", *f.seed)
+}
+
+func (f *shuffleFlag) Set(value string) error {
+	if value == "off" {
+		*f = shuffleFlag{on: false}
+		return nil
+	}
+
+	if value == "on" {
+		*f = shuffleFlag{on: true}
+		return nil
+	}
+
+	seed, err := strconv.ParseInt(value, 10, 64)
+	if err != nil {
+		return fmt.Errorf(`-shuffle argument must be "on", "off", or an int64: %v`, err)
+	}
+
+	*f = shuffleFlag{on: true, seed: &seed}
+	return nil
+}
+
 // testFlags processes the command line, grabbing -x and -c, rewriting known flags
 // to have "test" before them, and reading the command line for the test binary.
 // Unfortunately for us, we need to do our own flag processing because go test
@@ -367,7 +411,7 @@
 	// command. Set it explicitly if it is needed due to some other flag that
 	// requests output.
 	if testProfile() != "" && !outputDirSet {
-		injectedFlags = append(injectedFlags, "-test.outputdir="+testOutputDir)
+		injectedFlags = append(injectedFlags, "-test.outputdir="+testOutputDir.getAbs())
 	}
 
 	// If the user is explicitly passing -help or -h, show output
diff --git a/src/cmd/go/internal/vcs/vcs.go b/src/cmd/go/internal/vcs/vcs.go
index 9feffe0..91485f6 100644
--- a/src/cmd/go/internal/vcs/vcs.go
+++ b/src/cmd/go/internal/vcs/vcs.go
@@ -1176,7 +1176,7 @@
 // and import paths referring to a fully-qualified importPath
 // containing a VCS type (foo.com/repo.git/dir)
 var vcsPaths = []*vcsPath{
-	// Github
+	// GitHub
 	{
 		pathPrefix: "github.com",
 		regexp:     lazyregexp.New(`^(?P<root>github\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`),
diff --git a/src/cmd/go/internal/vet/vet.go b/src/cmd/go/internal/vet/vet.go
index 4257c90..1d419dd 100644
--- a/src/cmd/go/internal/vet/vet.go
+++ b/src/cmd/go/internal/vet/vet.go
@@ -53,8 +53,6 @@
 }
 
 func runVet(ctx context.Context, cmd *base.Command, args []string) {
-	load.ModResolveTests = true
-
 	vetFlags, pkgArgs := vetFlags(args)
 
 	if cfg.DebugTrace != "" {
@@ -87,7 +85,8 @@
 		}
 	}
 
-	pkgs := load.PackagesAndErrors(ctx, pkgArgs)
+	pkgOpts := load.PackageOpts{ModResolveTests: true}
+	pkgs := load.PackagesAndErrors(ctx, pkgOpts, pkgArgs)
 	load.CheckPackageErrors(pkgs)
 	if len(pkgs) == 0 {
 		base.Fatalf("no packages to vet")
@@ -98,7 +97,7 @@
 
 	root := &work.Action{Mode: "go vet"}
 	for _, p := range pkgs {
-		_, ptest, pxtest, err := load.TestPackagesFor(ctx, p, nil)
+		_, ptest, pxtest, err := load.TestPackagesFor(ctx, pkgOpts, p, nil)
 		if err != nil {
 			base.Errorf("%v", err)
 			continue
diff --git a/src/cmd/go/internal/web/bootstrap.go b/src/cmd/go/internal/web/bootstrap.go
index 7817021..08686cd 100644
--- a/src/cmd/go/internal/web/bootstrap.go
+++ b/src/cmd/go/internal/web/bootstrap.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cmd_go_bootstrap
 // +build cmd_go_bootstrap
 
 // This code is compiled only into the bootstrap 'go' binary.
diff --git a/src/cmd/go/internal/web/http.go b/src/cmd/go/internal/web/http.go
index 72fa2b2..f177278 100644
--- a/src/cmd/go/internal/web/http.go
+++ b/src/cmd/go/internal/web/http.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !cmd_go_bootstrap
 // +build !cmd_go_bootstrap
 
 // This code is compiled into the real 'go' binary, but it is not
@@ -27,7 +28,7 @@
 	"cmd/internal/browser"
 )
 
-// impatientInsecureHTTPClient is used in -insecure mode,
+// impatientInsecureHTTPClient is used with GOINSECURE,
 // when we're connecting to https servers that might not be there
 // or might be using self-signed certificates.
 var impatientInsecureHTTPClient = &http.Client{
diff --git a/src/cmd/go/internal/web/url_other.go b/src/cmd/go/internal/web/url_other.go
index 2641ee6..453af40 100644
--- a/src/cmd/go/internal/web/url_other.go
+++ b/src/cmd/go/internal/web/url_other.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows
 // +build !windows
 
 package web
diff --git a/src/cmd/go/internal/web/url_other_test.go b/src/cmd/go/internal/web/url_other_test.go
index aa56633..4d6ed2e 100644
--- a/src/cmd/go/internal/web/url_other_test.go
+++ b/src/cmd/go/internal/web/url_other_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows
 // +build !windows
 
 package web
diff --git a/src/cmd/go/internal/work/action.go b/src/cmd/go/internal/work/action.go
index 9d141ae..69940cb 100644
--- a/src/cmd/go/internal/work/action.go
+++ b/src/cmd/go/internal/work/action.go
@@ -344,7 +344,7 @@
 			if strings.HasPrefix(t, "pkgpath ") {
 				t = strings.TrimPrefix(t, "pkgpath ")
 				t = strings.TrimSuffix(t, ";")
-				pkgs = append(pkgs, load.LoadImportWithFlags(t, base.Cwd, nil, &stk, nil, 0))
+				pkgs = append(pkgs, load.LoadImportWithFlags(t, base.Cwd(), nil, &stk, nil, 0))
 			}
 		}
 	} else {
@@ -355,7 +355,7 @@
 		scanner := bufio.NewScanner(bytes.NewBuffer(pkglistbytes))
 		for scanner.Scan() {
 			t := scanner.Text()
-			pkgs = append(pkgs, load.LoadImportWithFlags(t, base.Cwd, nil, &stk, nil, 0))
+			pkgs = append(pkgs, load.LoadImportWithFlags(t, base.Cwd(), nil, &stk, nil, 0))
 		}
 	}
 	return
@@ -776,7 +776,7 @@
 					}
 				}
 				var stk load.ImportStack
-				p := load.LoadImportWithFlags(pkg, base.Cwd, nil, &stk, nil, 0)
+				p := load.LoadImportWithFlags(pkg, base.Cwd(), nil, &stk, nil, 0)
 				if p.Error != nil {
 					base.Fatalf("load %s: %v", pkg, p.Error)
 				}
diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go
index f024b07..0ed2389 100644
--- a/src/cmd/go/internal/work/build.go
+++ b/src/cmd/go/internal/work/build.go
@@ -10,9 +10,7 @@
 	"fmt"
 	"go/build"
 	exec "internal/execabs"
-	"internal/goroot"
 	"os"
-	"path"
 	"path/filepath"
 	"runtime"
 	"strings"
@@ -21,13 +19,9 @@
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/fsys"
 	"cmd/go/internal/load"
-	"cmd/go/internal/modfetch"
 	"cmd/go/internal/modload"
 	"cmd/go/internal/search"
 	"cmd/go/internal/trace"
-
-	"golang.org/x/mod/modfile"
-	"golang.org/x/mod/module"
 )
 
 var CmdBuild = &base.Command{
@@ -71,7 +65,7 @@
 	-p n
 		the number of programs, such as build commands or
 		test binaries, that can be run in parallel.
-		The default is the number of CPUs available.
+		The default is GOMAXPROCS, normally the number of CPUs available.
 	-race
 		enable data race detection.
 		Supported only on linux/amd64, freebsd/amd64, darwin/amd64, windows/amd64,
@@ -134,8 +128,8 @@
 		a build will run as if the disk file path exists with the contents
 		given by the backing file paths, or as if the disk file path does not
 		exist if its backing file path is empty. Support for the -overlay flag
-		has some limitations:importantly, cgo files included from outside the
-		include path must be  in the same directory as the Go package they are
+		has some limitations: importantly, cgo files included from outside the
+		include path must be in the same directory as the Go package they are
 		included from, and overlays will not appear when binaries and tests are
 		run through go run and go test respectively.
 	-pkgdir dir
@@ -158,6 +152,8 @@
 		a program to use to invoke toolchain programs like vet and asm.
 		For example, instead of running asm, the go command will run
 		'cmd args /path/to/asm <arguments for asm>'.
+		The TOOLEXEC_IMPORTPATH environment variable will be set,
+		matching 'go list -f {{.ImportPath}}' for the package being built.
 
 The -asmflags, -gccgoflags, -gcflags, and -ldflags flags accept a
 space-separated list of arguments to pass to an underlying tool
@@ -372,7 +368,7 @@
 	var b Builder
 	b.Init()
 
-	pkgs := load.PackagesAndErrors(ctx, args)
+	pkgs := load.PackagesAndErrors(ctx, load.PackageOpts{}, args)
 	load.CheckPackageErrors(pkgs)
 
 	explicitO := len(cfg.BuildO) > 0
@@ -592,7 +588,7 @@
 	}
 
 	BuildInit()
-	pkgs := load.PackagesAndErrors(ctx, args)
+	pkgs := load.PackagesAndErrors(ctx, load.PackageOpts{}, args)
 	if cfg.ModulesEnabled && !modload.HasModRoot() {
 		haveErrors := false
 		allMissingErrors := true
@@ -762,145 +758,27 @@
 	modload.RootMode = modload.NoRoot
 	modload.AllowMissingModuleImports()
 	modload.Init()
-
-	// Check that the arguments satisfy syntactic constraints.
-	var version string
-	for _, arg := range args {
-		if i := strings.Index(arg, "@"); i >= 0 {
-			version = arg[i+1:]
-			if version == "" {
-				base.Fatalf("go install %s: version must not be empty", arg)
-			}
-			break
-		}
-	}
-	patterns := make([]string, len(args))
-	for i, arg := range args {
-		if !strings.HasSuffix(arg, "@"+version) {
-			base.Errorf("go install %s: all arguments must have the same version (@%s)", arg, version)
-			continue
-		}
-		p := arg[:len(arg)-len(version)-1]
-		switch {
-		case build.IsLocalImport(p):
-			base.Errorf("go install %s: argument must be a package path, not a relative path", arg)
-		case filepath.IsAbs(p):
-			base.Errorf("go install %s: argument must be a package path, not an absolute path", arg)
-		case search.IsMetaPackage(p):
-			base.Errorf("go install %s: argument must be a package path, not a meta-package", arg)
-		case path.Clean(p) != p:
-			base.Errorf("go install %s: argument must be a clean package path", arg)
-		case !strings.Contains(p, "...") && search.IsStandardImportPath(p) && goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, p):
-			base.Errorf("go install %s: argument must not be a package in the standard library", arg)
-		default:
-			patterns[i] = p
-		}
-	}
-	base.ExitIfErrors()
 	BuildInit()
 
-	// Query the module providing the first argument, load its go.mod file, and
-	// check that it doesn't contain directives that would cause it to be
-	// interpreted differently if it were the main module.
-	//
-	// If multiple modules match the first argument, accept the longest match
-	// (first result). It's possible this module won't provide packages named by
-	// later arguments, and other modules would. Let's not try to be too
-	// magical though.
-	allowed := modload.CheckAllowed
-	if modload.IsRevisionQuery(version) {
-		// Don't check for retractions if a specific revision is requested.
-		allowed = nil
-	}
-	noneSelected := func(path string) (version string) { return "none" }
-	qrs, err := modload.QueryPackages(ctx, patterns[0], version, noneSelected, allowed)
-	if err != nil {
-		base.Fatalf("go install %s: %v", args[0], err)
-	}
-	installMod := qrs[0].Mod
-	data, err := modfetch.GoMod(installMod.Path, installMod.Version)
-	if err != nil {
-		base.Fatalf("go install %s: %v", args[0], err)
-	}
-	f, err := modfile.Parse("go.mod", data, nil)
-	if err != nil {
-		base.Fatalf("go install %s: %s: %v", args[0], installMod, err)
-	}
-	directiveFmt := "go install %s: %s\n" +
-		"\tThe go.mod file for the module providing named packages contains one or\n" +
-		"\tmore %s directives. It must not contain directives that would cause\n" +
-		"\tit to be interpreted differently than if it were the main module."
-	if len(f.Replace) > 0 {
-		base.Fatalf(directiveFmt, args[0], installMod, "replace")
-	}
-	if len(f.Exclude) > 0 {
-		base.Fatalf(directiveFmt, args[0], installMod, "exclude")
-	}
-
-	// Since we are in NoRoot mode, the build list initially contains only
-	// the dummy command-line-arguments module. Add a requirement on the
-	// module that provides the packages named on the command line.
-	if err := modload.EditBuildList(ctx, nil, []module.Version{installMod}); err != nil {
-		base.Fatalf("go install %s: %v", args[0], err)
-	}
-
-	// Load packages for all arguments. Ignore non-main packages.
+	// Load packages. Ignore non-main packages.
 	// Print a warning if an argument contains "..." and matches no main packages.
 	// PackagesAndErrors already prints warnings for patterns that don't match any
 	// packages, so be careful not to double print.
-	matchers := make([]func(string) bool, len(patterns))
-	for i, p := range patterns {
-		if strings.Contains(p, "...") {
-			matchers[i] = search.MatchPattern(p)
-		}
-	}
-
 	// TODO(golang.org/issue/40276): don't report errors loading non-main packages
 	// matched by a pattern.
-	pkgs := load.PackagesAndErrors(ctx, patterns)
+	pkgOpts := load.PackageOpts{MainOnly: true}
+	pkgs, err := load.PackagesAndErrorsOutsideModule(ctx, pkgOpts, args)
+	if err != nil {
+		base.Fatalf("go install: %v", err)
+	}
 	load.CheckPackageErrors(pkgs)
-	mainPkgs := make([]*load.Package, 0, len(pkgs))
-	mainCount := make([]int, len(patterns))
-	nonMainCount := make([]int, len(patterns))
-	for _, pkg := range pkgs {
-		if pkg.Name == "main" {
-			mainPkgs = append(mainPkgs, pkg)
-			for i := range patterns {
-				if matchers[i] != nil && matchers[i](pkg.ImportPath) {
-					mainCount[i]++
-				}
-			}
-		} else {
-			for i := range patterns {
-				if matchers[i] == nil && patterns[i] == pkg.ImportPath {
-					base.Errorf("go install: package %s is not a main package", pkg.ImportPath)
-				} else if matchers[i] != nil && matchers[i](pkg.ImportPath) {
-					nonMainCount[i]++
-				}
-			}
-		}
+	patterns := make([]string, len(args))
+	for i, arg := range args {
+		patterns[i] = arg[:strings.Index(arg, "@")]
 	}
-	base.ExitIfErrors()
-	for i, p := range patterns {
-		if matchers[i] != nil && mainCount[i] == 0 && nonMainCount[i] > 0 {
-			fmt.Fprintf(os.Stderr, "go: warning: %q matched no main packages\n", p)
-		}
-	}
-
-	// Check that named packages are all provided by the same module.
-	for _, pkg := range mainPkgs {
-		if pkg.Module == nil {
-			// Packages in std, cmd, and their vendored dependencies
-			// don't have this field set.
-			base.Errorf("go install: package %s not provided by module %s", pkg.ImportPath, installMod)
-		} else if pkg.Module.Path != installMod.Path || pkg.Module.Version != installMod.Version {
-			base.Errorf("go install: package %s provided by module %s@%s\n\tAll packages must be provided by the same module (%s).", pkg.ImportPath, pkg.Module.Path, pkg.Module.Version, installMod)
-		}
-	}
-	base.ExitIfErrors()
 
 	// Build and install the packages.
-	InstallPackages(ctx, patterns, mainPkgs)
+	InstallPackages(ctx, patterns, pkgs)
 }
 
 // ExecCmd is the command to use to run user binaries.
diff --git a/src/cmd/go/internal/work/build_test.go b/src/cmd/go/internal/work/build_test.go
index eaf2639..600fc30 100644
--- a/src/cmd/go/internal/work/build_test.go
+++ b/src/cmd/go/internal/work/build_test.go
@@ -173,10 +173,11 @@
 				if err != nil {
 					t.Fatal(err)
 				}
+				cwd := base.Cwd()
 				oldGopath := cfg.BuildContext.GOPATH
 				defer func() {
 					cfg.BuildContext.GOPATH = oldGopath
-					os.Chdir(base.Cwd)
+					os.Chdir(cwd)
 					err := os.RemoveAll(tmpGopath)
 					if err != nil {
 						t.Error(err)
diff --git a/src/cmd/go/internal/work/buildid.go b/src/cmd/go/internal/work/buildid.go
index c555d4a..4e9189a 100644
--- a/src/cmd/go/internal/work/buildid.go
+++ b/src/cmd/go/internal/work/buildid.go
@@ -204,7 +204,7 @@
 // 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) {
+func (b *Builder) gccToolID(name, language string) (string, error) {
 	key := name + "." + language
 	b.id.Lock()
 	id := b.toolIDCache[key]
diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
index 422e83c..5a225fb 100644
--- a/src/cmd/go/internal/work/exec.go
+++ b/src/cmd/go/internal/work/exec.go
@@ -8,11 +8,11 @@
 
 import (
 	"bytes"
-	"cmd/go/internal/fsys"
 	"context"
 	"encoding/json"
 	"errors"
 	"fmt"
+	"internal/buildcfg"
 	exec "internal/execabs"
 	"internal/lazyregexp"
 	"io"
@@ -31,6 +31,7 @@
 	"cmd/go/internal/base"
 	"cmd/go/internal/cache"
 	"cmd/go/internal/cfg"
+	"cmd/go/internal/fsys"
 	"cmd/go/internal/load"
 	"cmd/go/internal/modload"
 	"cmd/go/internal/str"
@@ -245,17 +246,37 @@
 	if p.Internal.ForceLibrary {
 		fmt.Fprintf(h, "forcelibrary\n")
 	}
-	if len(p.CgoFiles)+len(p.SwigFiles) > 0 {
+	if len(p.CgoFiles)+len(p.SwigFiles)+len(p.SwigCXXFiles) > 0 {
 		fmt.Fprintf(h, "cgo %q\n", b.toolID("cgo"))
 		cppflags, cflags, cxxflags, fflags, ldflags, _ := b.CFlags(p)
-		fmt.Fprintf(h, "CC=%q %q %q %q\n", b.ccExe(), cppflags, cflags, ldflags)
-		if len(p.CXXFiles)+len(p.SwigFiles) > 0 {
-			fmt.Fprintf(h, "CXX=%q %q\n", b.cxxExe(), cxxflags)
+
+		ccExe := b.ccExe()
+		fmt.Fprintf(h, "CC=%q %q %q %q\n", ccExe, cppflags, cflags, ldflags)
+		// Include the C compiler tool ID so that if the C
+		// compiler changes we rebuild the package.
+		// But don't do that for standard library packages like net,
+		// so that the prebuilt .a files from a Go binary install
+		// don't need to be rebuilt with the local compiler.
+		if !p.Standard {
+			if ccID, err := b.gccToolID(ccExe[0], "c"); err == nil {
+				fmt.Fprintf(h, "CC ID=%q\n", ccID)
+			}
+		}
+		if len(p.CXXFiles)+len(p.SwigCXXFiles) > 0 {
+			cxxExe := b.cxxExe()
+			fmt.Fprintf(h, "CXX=%q %q\n", cxxExe, cxxflags)
+			if cxxID, err := b.gccToolID(cxxExe[0], "c++"); err == nil {
+				fmt.Fprintf(h, "CXX ID=%q\n", cxxID)
+			}
 		}
 		if len(p.FFiles) > 0 {
-			fmt.Fprintf(h, "FC=%q %q\n", b.fcExe(), fflags)
+			fcExe := b.fcExe()
+			fmt.Fprintf(h, "FC=%q %q\n", fcExe, fflags)
+			if fcID, err := b.gccToolID(fcExe[0], "f95"); err == nil {
+				fmt.Fprintf(h, "FC ID=%q\n", fcID)
+			}
 		}
-		// TODO(rsc): Should we include the SWIG version or Fortran/GCC/G++/Objective-C compiler versions?
+		// TODO(rsc): Should we include the SWIG version?
 	}
 	if p.Internal.CoverMode != "" {
 		fmt.Fprintf(h, "cover %q %q\n", p.Internal.CoverMode, b.toolID("cover"))
@@ -276,6 +297,10 @@
 		key, val := cfg.GetArchEnv()
 		fmt.Fprintf(h, "%s=%s\n", key, val)
 
+		if goexperiment := buildcfg.GOEXPERIMENT(); goexperiment != "" {
+			fmt.Fprintf(h, "GOEXPERIMENT=%q\n", goexperiment)
+		}
+
 		// TODO(rsc): Convince compiler team not to add more magic environment variables,
 		// or perhaps restrict the environment variables passed to subprocesses.
 		// Because these are clumsy, undocumented special-case hacks
@@ -284,7 +309,7 @@
 		magic := []string{
 			"GOCLOBBERDEADHASH",
 			"GOSSAFUNC",
-			"GO_SSA_PHI_LOC_CUTOFF",
+			"GOSSADIR",
 			"GOSSAHASH",
 		}
 		for _, env := range magic {
@@ -311,7 +336,7 @@
 		}
 
 	case "gccgo":
-		id, err := b.gccgoToolID(BuildToolchain.compiler(), "go")
+		id, err := b.gccToolID(BuildToolchain.compiler(), "go")
 		if err != nil {
 			base.Fatalf("%v", err)
 		}
@@ -319,7 +344,7 @@
 		fmt.Fprintf(h, "pkgpath %s\n", gccgoPkgpath(p))
 		fmt.Fprintf(h, "ar %q\n", BuildToolchain.(gccgoToolchain).ar())
 		if len(p.SFiles) > 0 {
-			id, _ = b.gccgoToolID(BuildToolchain.compiler(), "assembler-with-cpp")
+			id, _ = b.gccToolID(BuildToolchain.compiler(), "assembler-with-cpp")
 			// Ignore error; different assembler versions
 			// are unlikely to make any difference anyhow.
 			fmt.Fprintf(h, "asm %q\n", id)
@@ -649,6 +674,10 @@
 		}
 
 		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)
+
+		// The files in cxxfiles have now been handled by b.cgo.
+		cxxfiles = nil
+
 		if err != nil {
 			return err
 		}
@@ -1246,6 +1275,10 @@
 		key, val := cfg.GetArchEnv()
 		fmt.Fprintf(h, "%s=%s\n", key, val)
 
+		if goexperiment := buildcfg.GOEXPERIMENT(); goexperiment != "" {
+			fmt.Fprintf(h, "GOEXPERIMENT=%q\n", goexperiment)
+		}
+
 		// The linker writes source file paths that say GOROOT_FINAL, but
 		// only if -trimpath is not specified (see ld() in gc.go).
 		gorootFinal := cfg.GOROOT_FINAL
@@ -1261,7 +1294,7 @@
 		// Or external linker settings and flags?
 
 	case "gccgo":
-		id, err := b.gccgoToolID(BuildToolchain.linker(), "go")
+		id, err := b.gccToolID(BuildToolchain.linker(), "go")
 		if err != nil {
 			base.Fatalf("%v", err)
 		}
@@ -1841,6 +1874,7 @@
 	{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
+	{0x4d, 0x5a, 0x78, 0x00, 0x01, 0x00},      // PE (Windows) as generated by llvm for dll
 	{0x00, 0x00, 0x01, 0xEB},                  // Plan 9 i386
 	{0x00, 0x00, 0x8a, 0x97},                  // Plan 9 amd64
 	{0x00, 0x00, 0x06, 0x47},                  // Plan 9 arm
@@ -2057,8 +2091,11 @@
 
 	// Add the TOOLEXEC_IMPORTPATH environment variable for -toolexec tools.
 	// It doesn't really matter if -toolexec isn't being used.
+	// Note that a.Package.Desc is not really an import path,
+	// but this is consistent with 'go list -f {{.ImportPath}}'.
+	// Plus, it is useful to uniquely identify packages in 'go list -json'.
 	if a != nil && a.Package != nil {
-		cmd.Env = append(cmd.Env, "TOOLEXEC_IMPORTPATH="+a.Package.ImportPath)
+		cmd.Env = append(cmd.Env, "TOOLEXEC_IMPORTPATH="+a.Package.Desc())
 	}
 
 	cmd.Env = append(cmd.Env, env...)
@@ -2347,7 +2384,7 @@
 
 	cmdargs := []interface{}{cmd, "-o", outfile, objs, flags}
 	dir := p.Dir
-	out, err := b.runOut(a, base.Cwd, b.cCompilerEnv(), cmdargs...)
+	out, err := b.runOut(a, base.Cwd(), b.cCompilerEnv(), cmdargs...)
 
 	if len(out) > 0 {
 		// Filter out useless linker warnings caused by bugs outside Go.
@@ -2598,9 +2635,19 @@
 	case "s390x":
 		return []string{"-m64", "-march=z196"}
 	case "mips64", "mips64le":
-		return []string{"-mabi=64"}
+		args := []string{"-mabi=64"}
+		if cfg.GOMIPS64 == "hardfloat" {
+			return append(args, "-mhard-float")
+		} else if cfg.GOMIPS64 == "softfloat" {
+			return append(args, "-msoft-float")
+		}
 	case "mips", "mipsle":
-		return []string{"-mabi=32", "-march=mips32"}
+		args := []string{"-mabi=32", "-march=mips32"}
+		if cfg.GOMIPS == "hardfloat" {
+			return append(args, "-mhard-float", "-mfp32", "-mno-odd-spreg")
+		} else if cfg.GOMIPS == "softfloat" {
+			return append(args, "-msoft-float")
+		}
 	case "ppc64":
 		if cfg.Goos == "aix" {
 			return []string{"-maix64"}
@@ -2951,7 +2998,7 @@
 	if p.Standard && p.ImportPath == "runtime/cgo" {
 		cgoflags = []string{"-dynlinker"} // record path to dynamic linker
 	}
-	return b.run(a, base.Cwd, p.ImportPath, b.cCompilerEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
+	return b.run(a, base.Cwd(), p.ImportPath, b.cCompilerEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
 }
 
 // Run SWIG on all SWIG input files.
@@ -3085,7 +3132,7 @@
 	}
 	srcs := []string{src}
 
-	p := load.GoFilesPackage(context.TODO(), srcs)
+	p := load.GoFilesPackage(context.TODO(), load.PackageOpts{}, srcs)
 
 	if _, _, e := BuildToolchain.gc(b, &Action{Mode: "swigDoIntSize", Package: p, Objdir: objdir}, "", nil, nil, "", false, srcs); e != nil {
 		return "32", nil
diff --git a/src/cmd/go/internal/work/gc.go b/src/cmd/go/internal/work/gc.go
index cc4e2b2..85da4f8 100644
--- a/src/cmd/go/internal/work/gc.go
+++ b/src/cmd/go/internal/work/gc.go
@@ -8,6 +8,7 @@
 	"bufio"
 	"bytes"
 	"fmt"
+	"internal/buildcfg"
 	"io"
 	"log"
 	"os"
@@ -63,15 +64,33 @@
 
 	pkgpath := pkgPath(a)
 	gcargs := []string{"-p", pkgpath}
-	if p.Module != nil && p.Module.GoVersion != "" && allowedVersion(p.Module.GoVersion) {
-		gcargs = append(gcargs, "-lang=go"+p.Module.GoVersion)
+	if p.Module != nil {
+		v := p.Module.GoVersion
+		if v == "" {
+			// We started adding a 'go' directive to the go.mod file unconditionally
+			// as of Go 1.12, so any module that still lacks such a directive must
+			// either have been authored before then, or have a hand-edited go.mod
+			// file that hasn't been updated by cmd/go since that edit.
+			//
+			// Unfortunately, through at least Go 1.16 we didn't add versions to
+			// vendor/modules.txt. So this could also be a vendored 1.16 dependency.
+			//
+			// Fortunately, there were no breaking changes to the language between Go
+			// 1.11 and 1.16, so if we assume Go 1.16 semantics we will not introduce
+			// any spurious errors — we will only mask errors, and not particularly
+			// important ones at that.
+			v = "1.16"
+		}
+		if allowedVersion(v) {
+			gcargs = append(gcargs, "-lang=go"+v)
+		}
 	}
 	if p.Standard {
 		gcargs = append(gcargs, "-std")
 	}
 	compilingRuntime := p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal"))
 	// The runtime package imports a couple of general internal packages.
-	if p.Standard && (p.ImportPath == "internal/cpu" || p.ImportPath == "internal/bytealg") {
+	if p.Standard && (p.ImportPath == "internal/cpu" || p.ImportPath == "internal/bytealg" || p.ImportPath == "internal/abi") {
 		compilingRuntime = true
 	}
 	if compilingRuntime {
@@ -129,7 +148,11 @@
 		}
 	}
 
-	args := []interface{}{cfg.BuildToolexec, base.Tool("compile"), "-o", ofile, "-trimpath", a.trimpath(), gcflags, gcargs, "-D", p.Internal.LocalPrefix}
+	args := []interface{}{cfg.BuildToolexec, base.Tool("compile"), "-o", ofile, "-trimpath", a.trimpath(), gcflags, gcargs}
+	if p.Internal.LocalPrefix != "" {
+		// Workaround #43883.
+		args = append(args, "-D", p.Internal.LocalPrefix)
+	}
 	if importcfg != nil {
 		if err := b.writeFile(objdir+"importcfg", importcfg); err != nil {
 			return "", nil, err
@@ -174,7 +197,7 @@
 		args = append(args, f)
 	}
 
-	output, err = b.runOut(a, base.Cwd, nil, args...)
+	output, err = b.runOut(a, base.Cwd(), nil, args...)
 	return ofile, output, err
 }
 
@@ -209,7 +232,7 @@
 	}
 
 	// TODO: Test and delete these conditions.
-	if objabi.Fieldtrack_enabled != 0 || objabi.Preemptibleloops_enabled != 0 {
+	if buildcfg.Experiment.FieldTrack || buildcfg.Experiment.PreemptibleLoops {
 		canDashC = false
 	}
 
@@ -235,16 +258,19 @@
 	//   - 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.
+	// and in such a case, set c to runtime.GOMAXPROCS(0).
+	// By default this is the same as runtime.NumCPU.
 	// We do this now when p==1.
+	// To limit parallelism, set GOMAXPROCS below numCPU; this may be useful
+	// on a low-memory builder, or if a deterministic build order is required.
+	c := runtime.GOMAXPROCS(0)
 	if cfg.BuildP == 1 {
-		// No process parallelism. Max out c.
-		return runtime.NumCPU()
+		// No process parallelism, do not cap compiler parallelism.
+		return c
 	}
-	// Some process parallelism. Set c to min(4, numcpu).
-	c := 4
-	if ncpu := runtime.NumCPU(); ncpu < c {
-		c = ncpu
+	// Some process parallelism. Set c to min(4, maxprocs).
+	if c > 4 {
+		c = 4
 	}
 	return c
 }
@@ -265,10 +291,11 @@
 
 	rewriteDir := a.Package.Dir
 	if cfg.BuildTrimpath {
+		importPath := a.Package.Internal.OrigImportPath
 		if m := a.Package.Module; m != nil && m.Version != "" {
-			rewriteDir = m.Path + "@" + m.Version + strings.TrimPrefix(a.Package.ImportPath, m.Path)
+			rewriteDir = m.Path + "@" + m.Version + strings.TrimPrefix(importPath, m.Path)
 		} else {
-			rewriteDir = a.Package.ImportPath
+			rewriteDir = importPath
 		}
 		rewrite += a.Package.Dir + "=>" + rewriteDir + ";"
 	}
@@ -336,18 +363,6 @@
 	}
 	if objabi.IsRuntimePackagePath(pkgpath) {
 		args = append(args, "-compiling-runtime")
-		if objabi.Regabi_enabled != 0 {
-			// In order to make it easier to port runtime assembly
-			// to the register ABI, we introduce a macro
-			// indicating the experiment is enabled.
-			//
-			// Note: a similar change also appears in
-			// cmd/dist/build.go.
-			//
-			// TODO(austin): Remove this once we commit to the
-			// register ABI (#40724).
-			args = append(args, "-D=GOEXPERIMENT_REGABI=1")
-		}
 	}
 
 	if cfg.Goarch == "mips" || cfg.Goarch == "mipsle" {
diff --git a/src/cmd/go/internal/work/gccgo.go b/src/cmd/go/internal/work/gccgo.go
index b58c8aa..1499536 100644
--- a/src/cmd/go/internal/work/gccgo.go
+++ b/src/cmd/go/internal/work/gccgo.go
@@ -102,7 +102,7 @@
 
 	if b.gccSupportsFlag(args[:1], "-ffile-prefix-map=a=b") {
 		if cfg.BuildTrimpath {
-			args = append(args, "-ffile-prefix-map="+base.Cwd+"=.")
+			args = append(args, "-ffile-prefix-map="+base.Cwd()+"=.")
 			args = append(args, "-ffile-prefix-map="+b.WorkDir+"=/tmp/go-build")
 		}
 		if fsys.OverlayFile != "" {
@@ -114,9 +114,9 @@
 				}
 				toPath := absPath
 				// gccgo only applies the last matching rule, so also handle the case where
-				// BuildTrimpath is true and the path is relative to base.Cwd.
-				if cfg.BuildTrimpath && str.HasFilePathPrefix(toPath, base.Cwd) {
-					toPath = "." + toPath[len(base.Cwd):]
+				// BuildTrimpath is true and the path is relative to base.Cwd().
+				if cfg.BuildTrimpath && str.HasFilePathPrefix(toPath, base.Cwd()) {
+					toPath = "." + toPath[len(base.Cwd()):]
 				}
 				args = append(args, "-ffile-prefix-map="+overlayPath+"="+toPath)
 			}
@@ -572,7 +572,7 @@
 	}
 	defs = tools.maybePIC(defs)
 	if b.gccSupportsFlag(compiler, "-ffile-prefix-map=a=b") {
-		defs = append(defs, "-ffile-prefix-map="+base.Cwd+"=.")
+		defs = append(defs, "-ffile-prefix-map="+base.Cwd()+"=.")
 		defs = append(defs, "-ffile-prefix-map="+b.WorkDir+"=/tmp/go-build")
 	} else if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") {
 		defs = append(defs, "-fdebug-prefix-map="+b.WorkDir+"=/tmp/go-build")
diff --git a/src/cmd/go/internal/work/init.go b/src/cmd/go/internal/work/init.go
index ba7c7c2..37a3e2d 100644
--- a/src/cmd/go/internal/work/init.go
+++ b/src/cmd/go/internal/work/init.go
@@ -11,21 +11,19 @@
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/fsys"
 	"cmd/go/internal/modload"
-	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"flag"
 	"fmt"
 	"os"
 	"path/filepath"
 	"runtime"
-	"strings"
 )
 
 func BuildInit() {
 	modload.Init()
 	instrumentInit()
 	buildModeInit()
-	if err := fsys.Init(base.Cwd); err != nil {
+	if err := fsys.Init(base.Cwd()); err != nil {
 		base.Fatalf("go: %v", err)
 	}
 
@@ -47,20 +45,6 @@
 			base.Fatalf("go %s: %s environment variable is relative; must be absolute path: %s\n", flag.Args()[0], key, path)
 		}
 	}
-
-	// For each experiment that has been enabled in the toolchain, define a
-	// build tag with the same name but prefixed by "goexperiment." which can be
-	// used for compiling alternative files for the experiment. This allows
-	// changes for the experiment, like extra struct fields in the runtime,
-	// without affecting the base non-experiment code at all. [2:] strips the
-	// leading "X:" from objabi.Expstring().
-	exp := objabi.Expstring()[2:]
-	if exp != "none" {
-		experiments := strings.Split(exp, ",")
-		for _, expt := range experiments {
-			cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "goexperiment."+expt)
-		}
-	}
 }
 
 func instrumentInit() {
diff --git a/src/cmd/go/internal/work/security.go b/src/cmd/go/internal/work/security.go
index 36bbab3..e9b9f6c 100644
--- a/src/cmd/go/internal/work/security.go
+++ b/src/cmd/go/internal/work/security.go
@@ -208,8 +208,8 @@
 	re(`-Wl,-z,(no)?execstack`),
 	re(`-Wl,-z,relro`),
 
-	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)
-	re(`\./.*\.(a|o|obj|dll|dylib|so)`),
+	re(`[a-zA-Z0-9_/].*\.(a|o|obj|dll|dylib|so|tbd)`), // direct linker inputs: x.o or libfoo.so (but not -foo.o or @foo.o)
+	re(`\./.*\.(a|o|obj|dll|dylib|so|tbd)`),
 }
 
 var validLinkerFlagsWithNextArg = []string{
diff --git a/src/cmd/go/internal/work/security_test.go b/src/cmd/go/internal/work/security_test.go
index 4f2e0eb..8d4be0a 100644
--- a/src/cmd/go/internal/work/security_test.go
+++ b/src/cmd/go/internal/work/security_test.go
@@ -164,6 +164,8 @@
 	{"-Wl,-framework", "-Wl,Chocolate"},
 	{"-Wl,-framework,Chocolate"},
 	{"-Wl,-unresolved-symbols=ignore-all"},
+	{"libcgotbdtest.tbd"},
+	{"./libcgotbdtest.tbd"},
 }
 
 var badLinkerFlags = [][]string{
diff --git a/src/cmd/go/internal/work/testgo.go b/src/cmd/go/internal/work/testgo.go
index 931f49a..8b77871 100644
--- a/src/cmd/go/internal/work/testgo.go
+++ b/src/cmd/go/internal/work/testgo.go
@@ -4,6 +4,7 @@
 
 // This file contains extra hooks for testing the go command.
 
+//go:build testgo
 // +build testgo
 
 package work
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index 9cc44da..16361e0 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -10,6 +10,7 @@
 	"context"
 	"flag"
 	"fmt"
+	"internal/buildcfg"
 	"log"
 	"os"
 	"path/filepath"
@@ -144,19 +145,6 @@
 		os.Exit(2)
 	}
 
-	// Set environment (GOOS, GOARCH, etc) explicitly.
-	// In theory all the commands we invoke should have
-	// the same default computation of these as we do,
-	// but in practice there might be skew
-	// This makes sure we all agree.
-	cfg.OrigEnv = os.Environ()
-	cfg.CmdEnv = envcmd.MkEnv()
-	for _, env := range cfg.CmdEnv {
-		if os.Getenv(env.Name) != env.Value {
-			os.Setenv(env.Name, env.Value)
-		}
-	}
-
 BigCmdLoop:
 	for bigCmd := base.Go; ; {
 		for _, cmd := range bigCmd.Commands {
@@ -182,18 +170,7 @@
 			if !cmd.Runnable() {
 				continue
 			}
-			cmd.Flag.Usage = func() { cmd.Usage() }
-			if cmd.CustomFlags {
-				args = args[1:]
-			} else {
-				base.SetFromGOFLAGS(&cmd.Flag)
-				cmd.Flag.Parse(args[1:])
-				args = cmd.Flag.Args()
-			}
-			ctx := maybeStartTrace(context.Background())
-			ctx, span := trace.StartSpan(ctx, fmt.Sprint("Running ", cmd.Name(), " command"))
-			cmd.Run(ctx, cmd, args)
-			span.Done()
+			invoke(cmd, args)
 			base.Exit()
 			return
 		}
@@ -207,6 +184,39 @@
 	}
 }
 
+func invoke(cmd *base.Command, args []string) {
+	// 'go env' handles checking the build config
+	if cmd != envcmd.CmdEnv {
+		buildcfg.Check()
+	}
+
+	// Set environment (GOOS, GOARCH, etc) explicitly.
+	// In theory all the commands we invoke should have
+	// the same default computation of these as we do,
+	// but in practice there might be skew
+	// This makes sure we all agree.
+	cfg.OrigEnv = os.Environ()
+	cfg.CmdEnv = envcmd.MkEnv()
+	for _, env := range cfg.CmdEnv {
+		if os.Getenv(env.Name) != env.Value {
+			os.Setenv(env.Name, env.Value)
+		}
+	}
+
+	cmd.Flag.Usage = func() { cmd.Usage() }
+	if cmd.CustomFlags {
+		args = args[1:]
+	} else {
+		base.SetFromGOFLAGS(&cmd.Flag)
+		cmd.Flag.Parse(args[1:])
+		args = cmd.Flag.Args()
+	}
+	ctx := maybeStartTrace(context.Background())
+	ctx, span := trace.StartSpan(ctx, fmt.Sprint("Running ", cmd.Name(), " command"))
+	cmd.Run(ctx, cmd, args)
+	span.Done()
+}
+
 func init() {
 	base.Usage = mainUsage
 }
diff --git a/src/cmd/go/proxy_test.go b/src/cmd/go/proxy_test.go
index e390c73..74bfecc 100644
--- a/src/cmd/go/proxy_test.go
+++ b/src/cmd/go/proxy_test.go
@@ -23,7 +23,6 @@
 	"sync"
 	"testing"
 
-	"cmd/go/internal/modfetch"
 	"cmd/go/internal/modfetch/codehost"
 	"cmd/go/internal/par"
 	"cmd/go/internal/txtar"
@@ -229,7 +228,7 @@
 			if m.Path != modPath {
 				continue
 			}
-			if modfetch.IsPseudoVersion(m.Version) && (latestPseudo == "" || semver.Compare(latestPseudo, m.Version) > 0) {
+			if module.IsPseudoVersion(m.Version) && (latestPseudo == "" || semver.Compare(latestPseudo, m.Version) > 0) {
 				latestPseudo = m.Version
 			} else if semver.Prerelease(m.Version) != "" && (latestPrerelease == "" || semver.Compare(latestPrerelease, m.Version) > 0) {
 				latestPrerelease = m.Version
@@ -282,7 +281,7 @@
 				continue
 			}
 			found = true
-			if !modfetch.IsPseudoVersion(m.Version) {
+			if !module.IsPseudoVersion(m.Version) {
 				if err := module.Check(m.Path, m.Version); err == nil {
 					fmt.Fprintf(w, "%s\n", m.Version)
 				}
@@ -315,7 +314,7 @@
 		for _, m := range modList {
 			if m.Path == path && semver.Compare(best, m.Version) < 0 {
 				var hash string
-				if modfetch.IsPseudoVersion(m.Version) {
+				if module.IsPseudoVersion(m.Version) {
 					hash = m.Version[strings.LastIndex(m.Version, "-")+1:]
 				} else {
 					hash = findHash(m)
@@ -362,7 +361,7 @@
 			var buf bytes.Buffer
 			z := zip.NewWriter(&buf)
 			for _, f := range a.Files {
-				if strings.HasPrefix(f.Name, ".") {
+				if f.Name == ".info" || f.Name == ".mod" || f.Name == ".zip" {
 					continue
 				}
 				var zipName string
diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go
index dfaa405..639e907 100644
--- a/src/cmd/go/script_test.go
+++ b/src/cmd/go/script_test.go
@@ -32,7 +32,6 @@
 	"cmd/go/internal/robustio"
 	"cmd/go/internal/txtar"
 	"cmd/go/internal/work"
-	"cmd/internal/objabi"
 	"cmd/internal/sys"
 )
 
@@ -41,6 +40,33 @@
 	testenv.MustHaveGoBuild(t)
 	testenv.SkipIfShortAndSlow(t)
 
+	var (
+		ctx         = context.Background()
+		gracePeriod = 100 * time.Millisecond
+	)
+	if deadline, ok := t.Deadline(); ok {
+		timeout := time.Until(deadline)
+
+		// If time allows, increase the termination grace period to 5% of the
+		// remaining time.
+		if gp := timeout / 20; gp > gracePeriod {
+			gracePeriod = gp
+		}
+
+		// When we run commands that execute subprocesses, we want to reserve two
+		// grace periods to clean up. We will send the first termination signal when
+		// the context expires, then wait one grace period for the process to
+		// produce whatever useful output it can (such as a stack trace). After the
+		// first grace period expires, we'll escalate to os.Kill, leaving the second
+		// grace period for the test function to record its output before the test
+		// process itself terminates.
+		timeout -= 2 * gracePeriod
+
+		var cancel context.CancelFunc
+		ctx, cancel = context.WithTimeout(ctx, timeout)
+		t.Cleanup(cancel)
+	}
+
 	files, err := filepath.Glob("testdata/script/*.txt")
 	if err != nil {
 		t.Fatal(err)
@@ -50,40 +76,51 @@
 		name := strings.TrimSuffix(filepath.Base(file), ".txt")
 		t.Run(name, func(t *testing.T) {
 			t.Parallel()
-			ts := &testScript{t: t, name: name, file: file}
+			ctx, cancel := context.WithCancel(ctx)
+			ts := &testScript{
+				t:           t,
+				ctx:         ctx,
+				cancel:      cancel,
+				gracePeriod: gracePeriod,
+				name:        name,
+				file:        file,
+			}
 			ts.setup()
 			if !*testWork {
 				defer removeAll(ts.workdir)
 			}
 			ts.run()
+			cancel()
 		})
 	}
 }
 
 // A testScript holds execution state for a single test script.
 type testScript struct {
-	t          *testing.T
-	workdir    string            // temporary work dir ($WORK)
-	log        bytes.Buffer      // test execution log (printed at end of test)
-	mark       int               // offset of next log truncation
-	cd         string            // current directory during test execution; initially $WORK/gopath/src
-	name       string            // short name of test ("foo")
-	file       string            // full file name ("testdata/script/foo.txt")
-	lineno     int               // line number currently executing
-	line       string            // line currently executing
-	env        []string          // environment list (for os/exec)
-	envMap     map[string]string // environment mapping (matches env)
-	stdout     string            // standard output from last 'go' command; for 'stdout' command
-	stderr     string            // standard error from last 'go' command; for 'stderr' command
-	stopped    bool              // test wants to stop early
-	start      time.Time         // time phase started
-	background []*backgroundCmd  // backgrounded 'exec' and 'go' commands
+	t           *testing.T
+	ctx         context.Context
+	cancel      context.CancelFunc
+	gracePeriod time.Duration
+	workdir     string            // temporary work dir ($WORK)
+	log         bytes.Buffer      // test execution log (printed at end of test)
+	mark        int               // offset of next log truncation
+	cd          string            // current directory during test execution; initially $WORK/gopath/src
+	name        string            // short name of test ("foo")
+	file        string            // full file name ("testdata/script/foo.txt")
+	lineno      int               // line number currently executing
+	line        string            // line currently executing
+	env         []string          // environment list (for os/exec)
+	envMap      map[string]string // environment mapping (matches env)
+	stdout      string            // standard output from last 'go' command; for 'stdout' command
+	stderr      string            // standard error from last 'go' command; for 'stderr' command
+	stopped     bool              // test wants to stop early
+	start       time.Time         // time phase started
+	background  []*backgroundCmd  // backgrounded 'exec' and 'go' commands
 }
 
 type backgroundCmd struct {
 	want           simpleStatus
 	args           []string
-	cancel         context.CancelFunc
 	done           <-chan struct{}
 	err            error
 	stdout, stderr strings.Builder
@@ -109,6 +146,10 @@
 
 // setup sets up the test execution temporary directory and environment.
 func (ts *testScript) setup() {
+	if err := ts.ctx.Err(); err != nil {
+		ts.t.Fatalf("test interrupted during setup: %v", err)
+	}
+
 	StartProxy()
 	ts.workdir = filepath.Join(testTmpDir, "script-"+ts.name)
 	ts.check(os.MkdirAll(filepath.Join(ts.workdir, "tmp"), 0777))
@@ -123,13 +164,13 @@
 		"GOCACHE=" + testGOCACHE,
 		"GODEBUG=" + os.Getenv("GODEBUG"),
 		"GOEXE=" + cfg.ExeSuffix,
-		"GOEXPSTRING=" + objabi.Expstring()[2:],
 		"GOOS=" + runtime.GOOS,
 		"GOPATH=" + filepath.Join(ts.workdir, "gopath"),
 		"GOPROXY=" + proxyURL,
 		"GOPRIVATE=",
 		"GOROOT=" + testGOROOT,
 		"GOROOT_FINAL=" + os.Getenv("GOROOT_FINAL"), // causes spurious rebuilds and breaks the "stale" built-in if not propagated
+		"GOTRACEBACK=system",
 		"TESTGO_GOROOT=" + testGOROOT,
 		"GOSUMDB=" + testSumDBVerifierKey,
 		"GONOPROXY=",
@@ -200,9 +241,7 @@
 		// On a normal exit from the test loop, background processes are cleaned up
 		// before we print PASS. If we return early (e.g., due to a test failure),
 		// don't print anything about the processes that were still running.
-		for _, bg := range ts.background {
-			bg.cancel()
-		}
+		ts.cancel()
 		for _, bg := range ts.background {
 			<-bg.done
 		}
@@ -275,6 +314,10 @@
 		fmt.Fprintf(&ts.log, "> %s\n", line)
 
 		for _, cond := range parsed.conds {
+			if err := ts.ctx.Err(); err != nil {
+				ts.fatalf("test interrupted: %v", err)
+			}
+
 			// Known conds are: $GOOS, $GOARCH, runtime.Compiler, and 'short' (for testing.Short).
 			//
 			// NOTE: If you make changes here, update testdata/script/README too!
@@ -356,9 +399,7 @@
 		}
 	}
 
-	for _, bg := range ts.background {
-		bg.cancel()
-	}
+	ts.cancel()
 	ts.cmdWait(success, nil)
 
 	// Final phase ended.
@@ -476,7 +517,7 @@
 		ts.fatalf("usage: cd dir")
 	}
 
-	dir := args[0]
+	dir := filepath.FromSlash(args[0])
 	if !filepath.IsAbs(dir) {
 		dir = filepath.Join(ts.cd, dir)
 	}
@@ -798,9 +839,7 @@
 
 	// Before we mark the test as skipped, shut down any background processes and
 	// make sure they have returned the correct status.
-	for _, bg := range ts.background {
-		bg.cancel()
-	}
+	ts.cancel()
 	ts.cmdWait(success, nil)
 
 	if len(args) == 1 {
@@ -1065,38 +1104,9 @@
 func (ts *testScript) startBackground(want simpleStatus, command string, args ...string) (*backgroundCmd, error) {
 	done := make(chan struct{})
 	bg := &backgroundCmd{
-		want:   want,
-		args:   append([]string{command}, args...),
-		done:   done,
-		cancel: func() {},
-	}
-
-	ctx := context.Background()
-	gracePeriod := 100 * time.Millisecond
-	if deadline, ok := ts.t.Deadline(); ok {
-		timeout := time.Until(deadline)
-		// If time allows, increase the termination grace period to 5% of the
-		// remaining time.
-		if gp := timeout / 20; gp > gracePeriod {
-			gracePeriod = gp
-		}
-
-		// Send the first termination signal with two grace periods remaining.
-		// If it still hasn't finished after the first period has elapsed,
-		// we'll escalate to os.Kill with a second period remaining until the
-		// test deadline..
-		timeout -= 2 * gracePeriod
-
-		if timeout <= 0 {
-			// The test has less than the grace period remaining. There is no point in
-			// even starting the command, because it will be terminated immediately.
-			// Save the expense of starting it in the first place.
-			bg.err = context.DeadlineExceeded
-			close(done)
-			return bg, nil
-		}
-
-		ctx, bg.cancel = context.WithTimeout(ctx, timeout)
+		want: want,
+		args: append([]string{command}, args...),
+		done: done,
 	}
 
 	cmd := exec.Command(command, args...)
@@ -1105,29 +1115,16 @@
 	cmd.Stdout = &bg.stdout
 	cmd.Stderr = &bg.stderr
 	if err := cmd.Start(); err != nil {
-		bg.cancel()
 		return nil, err
 	}
 
 	go func() {
-		bg.err = waitOrStop(ctx, cmd, stopSignal(), gracePeriod)
+		bg.err = waitOrStop(ts.ctx, cmd, quitSignal(), ts.gracePeriod)
 		close(done)
 	}()
 	return bg, nil
 }
 
-// stopSignal returns the appropriate signal to use to request that a process
-// stop execution.
-func stopSignal() os.Signal {
-	if runtime.GOOS == "windows" {
-		// Per https://golang.org/pkg/os/#Signal, “Interrupt is not implemented on
-		// Windows; using it with os.Process.Signal will return an error.”
-		// Fall back to Kill instead.
-		return os.Kill
-	}
-	return os.Interrupt
-}
-
 // waitOrStop waits for the already-started command cmd by calling its Wait method.
 //
 // If cmd does not return before ctx is done, waitOrStop sends it the given interrupt signal.
diff --git a/src/cmd/go/stop_other_test.go b/src/cmd/go/stop_other_test.go
new file mode 100644
index 0000000..e1cc6cf
--- /dev/null
+++ b/src/cmd/go/stop_other_test.go
@@ -0,0 +1,33 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !(aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris)
+// +build !aix
+// +build !darwin
+// +build !dragonfly
+// +build !freebsd
+// +build !js !wasm
+// +build !linux
+// +build !netbsd
+// +build !openbsd
+// +build !solaris
+
+package main_test
+
+import (
+	"os"
+	"runtime"
+)
+
+// quitSignal returns the appropriate signal to use to request that a process
+// quit execution.
+func quitSignal() os.Signal {
+	if runtime.GOOS == "windows" {
+		// Per https://golang.org/pkg/os/#Signal, “Interrupt is not implemented on
+		// Windows; using it with os.Process.Signal will return an error.”
+		// Fall back to Kill instead.
+		return os.Kill
+	}
+	return os.Interrupt
+}
diff --git a/src/cmd/go/stop_unix_test.go b/src/cmd/go/stop_unix_test.go
new file mode 100644
index 0000000..ac35b24
--- /dev/null
+++ b/src/cmd/go/stop_unix_test.go
@@ -0,0 +1,17 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
+// +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
+
+package main_test
+
+import (
+	"os"
+	"syscall"
+)
+
+func quitSignal() os.Signal {
+	return syscall.SIGQUIT
+}
diff --git a/src/cmd/go/testdata/addmod.go b/src/cmd/go/testdata/addmod.go
index 09fc8e7..03869e6 100644
--- a/src/cmd/go/testdata/addmod.go
+++ b/src/cmd/go/testdata/addmod.go
@@ -22,10 +22,10 @@
 	"bytes"
 	"flag"
 	"fmt"
+	exec "internal/execabs"
 	"io/fs"
 	"log"
 	"os"
-	exec "internal/execabs"
 	"path/filepath"
 	"strings"
 
diff --git a/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0.txt
index ee43938..c198139 100644
--- a/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0.txt
+++ b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0.txt
@@ -16,11 +16,15 @@
 -- a/a.go --
 package main
 
-func main() {}
+import "fmt"
+
+func main() { fmt.Println("a@v1.0.0") }
 -- b/b.go --
 package main
 
-func main() {}
+import "fmt"
+
+func main() { fmt.Println("b@v1.0.0") }
 -- err/err.go --
 package err
 
diff --git a/src/cmd/go/testdata/mod/example.com_deprecated_a_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_deprecated_a_v1.0.0.txt
new file mode 100644
index 0000000..7c29621
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_deprecated_a_v1.0.0.txt
@@ -0,0 +1,12 @@
+-- .info --
+{"Version":"v1.0.0"}
+-- .mod --
+module example.com/deprecated/a
+
+go 1.17
+-- go.mod --
+module example.com/deprecated/a
+
+go 1.17
+-- a.go --
+package a
diff --git a/src/cmd/go/testdata/mod/example.com_deprecated_a_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_deprecated_a_v1.9.0.txt
new file mode 100644
index 0000000..0613389
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_deprecated_a_v1.9.0.txt
@@ -0,0 +1,14 @@
+-- .info --
+{"Version":"v1.9.0"}
+-- .mod --
+// Deprecated: in example.com/deprecated/a@v1.9.0
+module example.com/deprecated/a
+
+go 1.17
+-- go.mod --
+// Deprecated: in example.com/deprecated/a@v1.9.0
+module example.com/deprecated/a
+
+go 1.17
+-- a.go --
+package a
diff --git a/src/cmd/go/testdata/mod/example.com_deprecated_b_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_deprecated_b_v1.0.0.txt
new file mode 100644
index 0000000..50006ae
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_deprecated_b_v1.0.0.txt
@@ -0,0 +1,12 @@
+-- .info --
+{"Version":"v1.0.0"}
+-- .mod --
+module example.com/deprecated/b
+
+go 1.17
+-- go.mod --
+module example.com/deprecated/b
+
+go 1.17
+-- b.go --
+package b
diff --git a/src/cmd/go/testdata/mod/example.com_deprecated_b_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_deprecated_b_v1.9.0.txt
new file mode 100644
index 0000000..163d6b5
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_deprecated_b_v1.9.0.txt
@@ -0,0 +1,14 @@
+-- .info --
+{"Version":"v1.9.0"}
+-- .mod --
+// Deprecated: in example.com/deprecated/b@v1.9.0
+module example.com/deprecated/b
+
+go 1.17
+-- go.mod --
+// Deprecated: in example.com/deprecated/b@v1.9.0
+module example.com/deprecated/b
+
+go 1.17
+-- b.go --
+package b
diff --git a/src/cmd/go/testdata/mod/example.com_dotname_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_dotname_v1.0.0.txt
new file mode 100644
index 0000000..2ada3a3
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_dotname_v1.0.0.txt
@@ -0,0 +1,12 @@
+-- .info --
+{"Version":"v1.0.0"}
+-- .mod --
+module example.com/dotname
+
+go 1.16
+-- go.mod --
+module example.com/dotname
+
+go 1.16
+-- .dot/dot.go --
+package dot
diff --git a/src/cmd/go/testdata/mod/example.com_split-incompatible_subpkg_v0.1.0.txt b/src/cmd/go/testdata/mod/example.com_split-incompatible_subpkg_v0.1.0.txt
index 8f9e491..edf5d48 100644
--- a/src/cmd/go/testdata/mod/example.com_split-incompatible_subpkg_v0.1.0.txt
+++ b/src/cmd/go/testdata/mod/example.com_split-incompatible_subpkg_v0.1.0.txt
@@ -1,6 +1,6 @@
 Written by hand.
 Test case for getting a package that has been moved to a nested module,
-with a +incompatible verison (and thus no go.mod file) at the root module.
+with a +incompatible version (and thus no go.mod file) at the root module.
 
 -- .mod --
 module example.com/split-incompatible/subpkg
diff --git a/src/cmd/go/testdata/mod/example.com_undeprecated_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_undeprecated_v1.0.0.txt
new file mode 100644
index 0000000..a68588e
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_undeprecated_v1.0.0.txt
@@ -0,0 +1,14 @@
+-- .info --
+{"Version":"v1.0.0"}
+-- .mod --
+// Deprecated: in v1.0.0
+module example.com/undeprecated
+
+go 1.17
+-- go.mod --
+// Deprecated: in v1.0.0
+module example.com/undeprecated
+
+go 1.17
+-- undeprecated.go --
+package undeprecated
diff --git a/src/cmd/go/testdata/mod/example.com_undeprecated_v1.0.1.txt b/src/cmd/go/testdata/mod/example.com_undeprecated_v1.0.1.txt
new file mode 100644
index 0000000..ecabf32
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_undeprecated_v1.0.1.txt
@@ -0,0 +1,14 @@
+-- .info --
+{"Version":"v1.0.1"}
+-- .mod --
+// no longer deprecated
+module example.com/undeprecated
+
+go 1.17
+-- go.mod --
+// no longer deprecated
+module example.com/undeprecated
+
+go 1.17
+-- undeprecated.go --
+package undeprecated
diff --git a/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt
index 00b71bf..7982ccc 100644
--- a/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt
+++ b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt
@@ -5,7 +5,7 @@
 
 require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c
 -- .info --
-{"Version":"v1.2.1","Name":"cac3af4f8a0ab40054fa6f8d423108a63a1255bb","Short":"cac3af4f8a0a","Time":"2018-02-13T18:16:22Z"}EOF
+{"Version":"v1.2.1","Name":"cac3af4f8a0ab40054fa6f8d423108a63a1255bb","Short":"cac3af4f8a0a","Time":"2018-02-13T18:16:22Z"}
 -- hello.go --
 // Copyright 2018 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/src/cmd/go/testdata/script/README b/src/cmd/go/testdata/script/README
index d658ceb..48e4055 100644
--- a/src/cmd/go/testdata/script/README
+++ b/src/cmd/go/testdata/script/README
@@ -29,7 +29,6 @@
 	GOARCH=<target GOARCH>
 	GOCACHE=<actual GOCACHE being used outside the test>
 	GOEXE=<executable file suffix: .exe on Windows, empty on other systems>
-	GOEXPSTRING=<value of objabi.Expstring(), from GOEXPERIMENT when toolchain built>
 	GOOS=<target GOOS>
 	GOPATH=$WORK/gopath
 	GOPROXY=<local module proxy serving from cmd/go/testdata/mod>
@@ -103,6 +102,7 @@
 
 - cd dir
   Change to the given directory for future commands.
+  The directory must use slashes as path separator.
 
 - chmod perm path...
   Change the permissions of the files or directories named by the path arguments
diff --git a/src/cmd/go/testdata/script/badgo.txt b/src/cmd/go/testdata/script/badgo.txt
new file mode 100644
index 0000000..cf4e258
--- /dev/null
+++ b/src/cmd/go/testdata/script/badgo.txt
@@ -0,0 +1,50 @@
+go get example.net/badgo@v1.0.0
+go get example.net/badgo@v1.1.0
+go get example.net/badgo@v1.2.0
+go get example.net/badgo@v1.3.0
+go get example.net/badgo@v1.4.0
+go get example.net/badgo@v1.5.0
+! go get example.net/badgo@v1.6.0
+stderr 'invalid go version .X.Y.: must match format 1.23'
+
+-- go.mod --
+module m
+
+replace (
+	example.net/badgo v1.0.0 => ./v1.0.0
+	example.net/badgo v1.1.0 => ./v1.1.0
+	example.net/badgo v1.2.0 => ./v1.2.0
+	example.net/badgo v1.3.0 => ./v1.3.0
+	example.net/badgo v1.4.0 => ./v1.4.0
+	example.net/badgo v1.5.0 => ./v1.5.0
+	example.net/badgo v1.6.0 => ./v1.6.0
+)
+
+-- v1.0.0/go.mod --
+module example.net/badgo
+go 1.17.0
+
+-- v1.1.0/go.mod --
+module example.net/badgo
+go 1.17rc2
+
+-- v1.2.0/go.mod --
+module example.net/badgo
+go 1.17.1
+
+-- v1.3.0/go.mod --
+module example.net/badgo
+go v1.17.0
+
+-- v1.4.0/go.mod --
+module example.net/badgo
+go v1.17.0-rc.2
+
+-- v1.5.0/go.mod --
+module example.net/badgo
+go v1.17.1
+
+-- v1.6.0/go.mod --
+module example.net/badgo
+go X.Y
+
diff --git a/src/cmd/go/testdata/script/bug.txt b/src/cmd/go/testdata/script/bug.txt
index b9bbaaa..571d507 100644
--- a/src/cmd/go/testdata/script/bug.txt
+++ b/src/cmd/go/testdata/script/bug.txt
@@ -1,9 +1,11 @@
 # Verify that go bug creates the appropriate URL issue body
 
 [!linux] skip
+[short] skip
 
 go install
-env BROWSER=$GOPATH/bin/browser
+go build -o $TMPDIR/go ./go
+env BROWSER=$GOPATH/bin/browser PATH=$TMPDIR:$PATH
 go bug
 exists $TMPDIR/browser
 grep '^go version' $TMPDIR/browser
@@ -44,3 +46,13 @@
 	}
 }
 
+-- go/main.go --
+package main
+
+import (
+    "os"
+)
+
+func main() {
+    os.Exit(1)
+}
diff --git a/src/cmd/go/testdata/script/build_ignore_leading_bom.txt b/src/cmd/go/testdata/script/build_ignore_leading_bom.txt
new file mode 100644
index 0000000..37141f3
--- /dev/null
+++ b/src/cmd/go/testdata/script/build_ignore_leading_bom.txt
@@ -0,0 +1,27 @@
+# Per https://golang.org/ref/spec#Source_code_representation:
+# a compiler may ignore a UTF-8-encoded byte order mark (U+FEFF)
+# if it is the first Unicode code point in the source text.
+
+go list -f 'Imports: {{.Imports}} EmbedFiles: {{.EmbedFiles}}' .
+stdout '^Imports: \[embed m/hello\] EmbedFiles: \[.*file\]$'
+
+-- go.mod --
+module m
+
+go 1.16
+-- m.go --
+package main
+
+import (
+	_ "embed"
+
+	"m/hello"
+)
+
+//go:embed file
+var s string
+
+-- hello/hello.go --
+package hello
+
+-- file --
diff --git a/src/cmd/go/testdata/script/build_overlay.txt b/src/cmd/go/testdata/script/build_overlay.txt
index b11cd96..2932b94 100644
--- a/src/cmd/go/testdata/script/build_overlay.txt
+++ b/src/cmd/go/testdata/script/build_overlay.txt
@@ -238,7 +238,7 @@
 
 void say_hello() { puts("hello cgo\n"); fflush(stdout); }
 -- m/overlay/asm_gc.s --
-// +build !gccgo
+// +build gc
 
 TEXT ·foo(SB),0,$0
 	RET
diff --git a/src/cmd/go/testdata/script/build_package_not_stale_trailing_slash.txt b/src/cmd/go/testdata/script/build_package_not_stale_trailing_slash.txt
deleted file mode 100644
index 38a151e..0000000
--- a/src/cmd/go/testdata/script/build_package_not_stale_trailing_slash.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-# Tests Issue #12690
-
-[gccgo] skip 'gccgo does not have GOROOT'
-
-! stale runtime
-! stale os
-! stale io
-
-env GOROOT=$GOROOT'/'
-
-! stale runtime
-! stale os
-! stale io
\ No newline at end of file
diff --git a/src/cmd/go/testdata/script/build_tag_goexperiment.txt b/src/cmd/go/testdata/script/build_tag_goexperiment.txt
index 26ad029..bee218f 100644
--- a/src/cmd/go/testdata/script/build_tag_goexperiment.txt
+++ b/src/cmd/go/testdata/script/build_tag_goexperiment.txt
@@ -1,85 +1,20 @@
-# compile_ext will fail if the buildtags that are enabled (or not enabled) for the
-# framepointer and fieldtrack experiments are not consistent with the value of
-# GOEXPSTRING (which comes from objabi.Expstring()).
-
 [short] skip
+# Reset all experiments so fieldtrack is definitely off.
+env GOEXPERIMENT=none
 go run m
-
--- expt_main.go --
-package main
-
-import (
-	"os"
-	"strings"
-)
-
-func main() {
-  fp()
-  ft()
-}
-
-func hasExpEntry(s string) bool {
-	// script_test.go defines GOEXPSTRING to be the value of
-	// objabi.Expstring(), which gives the enabled experiments baked into the
-	// toolchain.
-	g := os.Getenv("GOEXPSTRING")
-	for _, f := range strings.Split(g, ",") {
-		if f == s {
-			return true
-		}
-	}
-	return false
-}
-
--- fp_off.go --
-// +build !goexperiment.framepointer
-
-package main
-
-import (
-	"fmt"
-	"os"
-)
-
-func fp() {
-	if hasExpEntry("framepointer") {
-		fmt.Println("in !framepointer build, but objabi.Expstring() has 'framepointer'")
-		os.Exit(1)
-	}
-}
-
--- fp_on.go --
-// +build goexperiment.framepointer
-
-package main
-
-import (
-	"fmt"
-	"os"
-)
-
-func fp() {
-	if !hasExpEntry("framepointer") {
-		fmt.Println("in framepointer build, but objabi.Expstring() does not have 'framepointer', is", os.Getenv("GOEXPSTRING"))
-		os.Exit(1)
-	}
-}
+stderr 'fieldtrack off'
+# Turn fieldtrack on.
+env GOEXPERIMENT=none,fieldtrack
+go run m
+stderr 'fieldtrack on'
 
 -- ft_off.go --
 // +build !goexperiment.fieldtrack
 
 package main
 
-import (
-	"fmt"
-	"os"
-)
-
-func ft() {
-	if hasExpEntry("fieldtrack") {
-		fmt.Println("in !fieldtrack build, but objabi.Expstring() has 'fieldtrack'")
-		os.Exit(1)
-	}
+func main() {
+	println("fieldtrack off")
 }
 
 -- ft_on.go --
@@ -87,16 +22,8 @@
 
 package main
 
-import (
-	"fmt"
-	"os"
-)
-
-func ft() {
-	if !hasExpEntry("fieldtrack") {
-		fmt.Println("in fieldtrack build, but objabi.Expstring() does not have 'fieldtrack', is", os.Getenv("GOEXPSTRING"))
-		os.Exit(1)
-	}
+func main() {
+	println("fieldtrack on")
 }
 
 -- go.mod --
diff --git a/src/cmd/go/testdata/script/cgo_stale.txt b/src/cmd/go/testdata/script/cgo_stale.txt
new file mode 100644
index 0000000..9e46855
--- /dev/null
+++ b/src/cmd/go/testdata/script/cgo_stale.txt
@@ -0,0 +1,39 @@
+# golang.org/issue/46347: a stale runtime/cgo should only force a single rebuild
+
+[!cgo] skip
+[short] skip
+
+
+# If we set a unique CGO_CFLAGS, the installed copy of runtime/cgo
+# should be reported as stale.
+
+env CGO_CFLAGS=-DTestScript_cgo_stale=true
+stale runtime/cgo
+
+
+# If we then build a package that uses cgo, runtime/cgo should be rebuilt and
+# cached with the new flag, but not installed to GOROOT (and thus still stale).
+
+env GOCACHE=$WORK/cache  # Use a fresh cache to avoid interference between runs.
+
+go build -x .
+stderr '[/\\]cgo'$GOEXE'["]? .* -importpath runtime/cgo'
+stale runtime/cgo
+
+
+# After runtime/cgo has been rebuilt and cached, it should not be rebuilt again
+# even though it is still reported as stale.
+
+go build -x .
+! stderr '[/\\]cgo'$GOEXE'["]? .* -importpath runtime/cgo'
+stale runtime/cgo
+
+
+-- go.mod --
+module example.com/m
+
+go 1.17
+-- m.go --
+package m
+
+import "C"
diff --git a/src/cmd/go/testdata/script/cover_pkgall_imports.txt b/src/cmd/go/testdata/script/cover_pkgall_imports.txt
new file mode 100644
index 0000000..4e51726
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_pkgall_imports.txt
@@ -0,0 +1,48 @@
+# This test checks that -coverpkg=all can be used
+# when the package pattern includes packages
+# which only have tests.
+# Verifies golang.org/issue/27333, golang.org/issue/43242.
+
+[short] skip
+cd $GOPATH/src/example.com/cov
+
+env GO111MODULE=on
+go test -coverpkg=all ./...
+
+env GO111MODULE=off
+go test -coverpkg=all ./...
+
+-- $GOPATH/src/example.com/cov/go.mod --
+module example.com/cov
+
+-- $GOPATH/src/example.com/cov/notest/notest.go --
+package notest
+
+func Foo() {}
+
+-- $GOPATH/src/example.com/cov/onlytest/onlytest_test.go --
+package onlytest_test
+
+import (
+	"testing"
+
+	"example.com/cov/notest"
+)
+
+func TestFoo(t *testing.T) {
+	notest.Foo()
+}
+
+-- $GOPATH/src/example.com/cov/withtest/withtest.go --
+package withtest
+
+func Bar() {}
+
+-- $GOPATH/src/example.com/cov/withtest/withtest_test.go --
+package withtest
+
+import "testing"
+
+func TestBar(t *testing.T) {
+	Bar()
+}
diff --git a/src/cmd/go/testdata/script/embed.txt b/src/cmd/go/testdata/script/embed.txt
index 6ad42e9..04b17cd 100644
--- a/src/cmd/go/testdata/script/embed.txt
+++ b/src/cmd/go/testdata/script/embed.txt
@@ -107,3 +107,4 @@
 -- go.mod --
 module m
 
+go 1.16
diff --git a/src/cmd/go/testdata/script/env_cross_build.txt b/src/cmd/go/testdata/script/env_cross_build.txt
new file mode 100644
index 0000000..3feeba6
--- /dev/null
+++ b/src/cmd/go/testdata/script/env_cross_build.txt
@@ -0,0 +1,29 @@
+# Test that the corect default GOEXPERIMENT is used when cross
+# building with GOENV (#46815).
+
+# Unset variables set by the TestScript harness. Users typically won't
+# explicitly configure these, and #46815 doesn't repro if they are.
+env GOOS=
+env GOARCH=
+env GOEXPERIMENT=
+
+env GOENV=windows-amd64
+go build internal/abi
+
+env GOENV=ios-arm64
+go build internal/abi
+
+env GOENV=linux-mips
+go build internal/abi
+
+-- windows-amd64 --
+GOOS=windows
+GOARCH=amd64
+
+-- ios-arm64 --
+GOOS=ios
+GOARCH=arm64
+
+-- linux-mips --
+GOOS=linux
+GOARCH=mips
diff --git a/src/cmd/go/testdata/script/env_exp.txt b/src/cmd/go/testdata/script/env_exp.txt
new file mode 100644
index 0000000..681512d
--- /dev/null
+++ b/src/cmd/go/testdata/script/env_exp.txt
@@ -0,0 +1,17 @@
+# Test GOEXPERIMENT variable
+
+# go env shows default empty GOEXPERIMENT
+go env
+stdout GOEXPERIMENT=
+
+# go env shows valid experiments
+env GOEXPERIMENT=fieldtrack,staticlockranking
+go env GOEXPERIMENT
+stdout '.*fieldtrack.*staticlockranking.*'
+go env
+stdout 'GOEXPERIMENT=.*fieldtrack.*staticlockranking.*'
+
+# go env rejects unknown experiments
+env GOEXPERIMENT=bad
+! go env GOEXPERIMENT
+stderr 'unknown GOEXPERIMENT bad'
diff --git a/src/cmd/go/testdata/script/env_unset.txt b/src/cmd/go/testdata/script/env_unset.txt
new file mode 100644
index 0000000..4e0f249
--- /dev/null
+++ b/src/cmd/go/testdata/script/env_unset.txt
@@ -0,0 +1,30 @@
+# Test that we can unset variables, even if initially invalid,
+# as long as resulting config is valid.
+
+env GOENV=badenv
+env GOOS=
+env GOARCH=
+env GOEXPERIMENT=
+
+! go env
+stderr '^go(\.exe)?: unknown GOEXPERIMENT badexp$'
+
+go env -u GOEXPERIMENT
+
+! go env
+stderr '^cmd/go: unsupported GOOS/GOARCH pair bados/badarch$'
+
+! go env -u GOOS
+stderr '^go env -u: unsupported GOOS/GOARCH pair \w+/badarch$'
+
+! go env -u GOARCH
+stderr '^go env -u: unsupported GOOS/GOARCH pair bados/\w+$'
+
+go env -u GOOS GOARCH
+
+go env
+
+-- badenv --
+GOOS=bados
+GOARCH=badarch
+GOEXPERIMENT=badexp
diff --git a/src/cmd/go/testdata/script/env_write.txt b/src/cmd/go/testdata/script/env_write.txt
index bda1e57..b5e9739 100644
--- a/src/cmd/go/testdata/script/env_write.txt
+++ b/src/cmd/go/testdata/script/env_write.txt
@@ -173,3 +173,15 @@
 env GOOS=windows
 ! go env -u GOOS
 stderr 'unsupported GOOS/GOARCH.*windows/mips$'
+
+# go env -w should reject relative paths in GOMODCACHE environment.
+! go env -w GOMODCACHE=~/test
+stderr 'go env -w: GOMODCACHE entry is relative; must be absolute path: "~/test"'
+! go env -w GOMODCACHE=./test
+stderr 'go env -w: GOMODCACHE entry is relative; must be absolute path: "./test"'
+
+# go env -w checks validity of GOEXPERIMENT
+env GOEXPERIMENT=
+! go env -w GOEXPERIMENT=badexp
+stderr 'unknown GOEXPERIMENT badexp'
+go env -w GOEXPERIMENT=fieldtrack
diff --git a/src/cmd/go/testdata/script/fmt_load_errors.txt b/src/cmd/go/testdata/script/fmt_load_errors.txt
index 297ec0f..84bf41c 100644
--- a/src/cmd/go/testdata/script/fmt_load_errors.txt
+++ b/src/cmd/go/testdata/script/fmt_load_errors.txt
@@ -6,6 +6,17 @@
 stdout 'exclude[/\\]x\.go'
 stdout 'exclude[/\\]x_linux\.go'
 
+# Test edge cases with gofmt.
+# Note that this execs GOROOT/bin/gofmt.
+
+! exec gofmt does-not-exist
+
+exec gofmt gofmt-dir/no-extension
+stdout 'package x'
+
+exec gofmt gofmt-dir
+! stdout 'package x'
+
 -- exclude/empty/x.txt --
 -- exclude/ignore/_x.go --
 package x
@@ -17,3 +28,5 @@
 // +build windows
 
 package x
+-- gofmt-dir/no-extension --
+package x
diff --git a/src/cmd/go/testdata/script/generate.txt b/src/cmd/go/testdata/script/generate.txt
index c3c563e..73f5bbd 100644
--- a/src/cmd/go/testdata/script/generate.txt
+++ b/src/cmd/go/testdata/script/generate.txt
@@ -26,6 +26,10 @@
 go generate './generate/env_test.go'
 stdout 'main_test'
 
+# Test go generate provides the right "$PWD"
+go generate './generate/env_pwd.go'
+stdout $WORK'[/\\]gopath[/\\]src[/\\]generate'
+
 -- echo.go --
 package main
 
@@ -88,4 +92,8 @@
 -- generate/env_test.go --
 package main_test
 
-//go:generate echo $GOPACKAGE
\ No newline at end of file
+//go:generate echo $GOPACKAGE
+-- generate/env_pwd.go --
+package p
+
+//go:generate echo $PWD
diff --git a/src/cmd/go/testdata/script/get_404_meta.txt b/src/cmd/go/testdata/script/get_404_meta.txt
index b71cc7f..ec4f8d3 100644
--- a/src/cmd/go/testdata/script/get_404_meta.txt
+++ b/src/cmd/go/testdata/script/get_404_meta.txt
@@ -3,9 +3,10 @@
 [!net] skip
 [!exec:git] skip
 
+env GONOSUMDB=bazil.org,github.com,golang.org
 env GO111MODULE=off
-go get -d -insecure bazil.org/fuse/fs/fstestutil
+go get -d bazil.org/fuse/fs/fstestutil
 
 env GO111MODULE=on
 env GOPROXY=direct
-go get -d -insecure bazil.org/fuse/fs/fstestutil
+go get -d bazil.org/fuse/fs/fstestutil
diff --git a/src/cmd/go/testdata/script/get_insecure.txt b/src/cmd/go/testdata/script/get_insecure.txt
index 36ad2c0..69930f7 100644
--- a/src/cmd/go/testdata/script/get_insecure.txt
+++ b/src/cmd/go/testdata/script/get_insecure.txt
@@ -12,10 +12,12 @@
 # GOPATH: Try go get -d of HTTP-only repo (should fail).
 ! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p
 
-# GOPATH: Try again with -insecure (should succeed).
-go get -d -insecure insecure.go-get-issue-15410.appspot.com/pkg/p
+# GOPATH: Try again with GOINSECURE (should succeed).
+env GOINSECURE=insecure.go-get-issue-15410.appspot.com
+go get -d insecure.go-get-issue-15410.appspot.com/pkg/p
 
-# GOPATH: Try updating without -insecure (should fail).
+# GOPATH: Try updating without GOINSECURE (should fail).
+env GOINSECURE=''
 ! go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p
 
 # Modules: Set up
@@ -29,10 +31,14 @@
 # Modules: Try go get -d of HTTP-only repo (should fail).
 ! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p
 
-# Modules: Try again with -insecure (should succeed).
-go get -d -insecure insecure.go-get-issue-15410.appspot.com/pkg/p
+# Modules: Try again with GOINSECURE (should succeed).
+env GOINSECURE=insecure.go-get-issue-15410.appspot.com
+env GONOSUMDB=insecure.go-get-issue-15410.appspot.com
+go get -d insecure.go-get-issue-15410.appspot.com/pkg/p
 
-# Modules: Try updating without -insecure (should fail).
+# Modules: Try updating without GOINSECURE (should fail).
+env GOINSECURE=''
+env GONOSUMDB=''
 ! go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p
 
 go list -m ...
@@ -48,4 +54,4 @@
 	os.Exit(1)
 }
 -- module_file --
-module m
\ No newline at end of file
+module m
diff --git a/src/cmd/go/testdata/script/get_insecure_custom_domain.txt b/src/cmd/go/testdata/script/get_insecure_custom_domain.txt
index a4a6fd4..7eba42e 100644
--- a/src/cmd/go/testdata/script/get_insecure_custom_domain.txt
+++ b/src/cmd/go/testdata/script/get_insecure_custom_domain.txt
@@ -3,4 +3,6 @@
 env GO111MODULE=off
 
 ! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p
-go get -d -insecure insecure.go-get-issue-15410.appspot.com/pkg/p
+
+env GOINSECURE=insecure.go-get-issue-15410.appspot.com
+go get -d insecure.go-get-issue-15410.appspot.com/pkg/p
diff --git a/src/cmd/go/testdata/script/get_insecure_deprecated.txt b/src/cmd/go/testdata/script/get_insecure_deprecated.txt
deleted file mode 100644
index 7f5f5c7..0000000
--- a/src/cmd/go/testdata/script/get_insecure_deprecated.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-# GOPATH: Set up
-env GO111MODULE=off
-
-# GOPATH: Fetch without insecure, no warning
-! go get test
-! stderr 'go get: -insecure flag is deprecated; see ''go help get'' for details'
-
-# GOPATH: Fetch with insecure, should warn
-! go get -insecure test
-stderr 'go get: -insecure flag is deprecated; see ''go help get'' for details'
-
-# Modules: Set up
-env GO111MODULE=on
-
-# Modules: Fetch without insecure, no warning
-! go get test
-! stderr 'go get: -insecure flag is deprecated; see ''go help get'' for details'
-
-# Modules: Fetch with insecure, should warn
-! go get -insecure test
-stderr 'go get: -insecure flag is deprecated; see ''go help get'' for details'
diff --git a/src/cmd/go/testdata/script/get_insecure_no_longer_supported.txt b/src/cmd/go/testdata/script/get_insecure_no_longer_supported.txt
new file mode 100644
index 0000000..2517664
--- /dev/null
+++ b/src/cmd/go/testdata/script/get_insecure_no_longer_supported.txt
@@ -0,0 +1,13 @@
+# GOPATH: Set up
+env GO111MODULE=off
+
+# GOPATH: Fetch with insecure, should error
+! go get -insecure test
+stderr 'go get: -insecure flag is no longer supported; use GOINSECURE instead'
+
+# Modules: Set up
+env GO111MODULE=on
+
+# Modules: Fetch with insecure, should error
+! go get -insecure test
+stderr 'go get: -insecure flag is no longer supported; use GOINSECURE instead'
diff --git a/src/cmd/go/testdata/script/get_insecure_redirect.txt b/src/cmd/go/testdata/script/get_insecure_redirect.txt
index 0478d1f..fb5f269 100644
--- a/src/cmd/go/testdata/script/get_insecure_redirect.txt
+++ b/src/cmd/go/testdata/script/get_insecure_redirect.txt
@@ -1,4 +1,4 @@
-# golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure.
+# golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure (now replaced by GOINSECURE).
 # golang.org/issue/34049: 'go get' would panic in case of an insecure redirect in GOPATH mode
 
 [!net] skip
@@ -9,4 +9,5 @@
 ! go get -d vcs-test.golang.org/insecure/go/insecure
 stderr 'redirected .* to insecure URL'
 
-go get -d -insecure vcs-test.golang.org/insecure/go/insecure
+env GOINSECURE=vcs-test.golang.org/insecure/go/insecure
+go get -d vcs-test.golang.org/insecure/go/insecure
diff --git a/src/cmd/go/testdata/script/get_insecure_update.txt b/src/cmd/go/testdata/script/get_insecure_update.txt
index 4511c98..e1a1a23 100644
--- a/src/cmd/go/testdata/script/get_insecure_update.txt
+++ b/src/cmd/go/testdata/script/get_insecure_update.txt
@@ -5,8 +5,10 @@
 # Clone the repo via HTTP manually.
 exec git clone -q http://github.com/golang/example github.com/golang/example
 
-# Update without -insecure should fail.
-# Update with -insecure should succeed.
+# Update without GOINSECURE should fail.
 # We need -f to ignore import comments.
 ! go get -d -u -f github.com/golang/example/hello
-go get -d -u -f -insecure github.com/golang/example/hello
+
+# Update with GOINSECURE should succeed.
+env GOINSECURE=github.com/golang/example/hello
+go get -d -u -f github.com/golang/example/hello
diff --git a/src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt b/src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt
new file mode 100644
index 0000000..3d68ef3
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt
@@ -0,0 +1,38 @@
+# Regression test for https://golang.org/issue/46462.
+#
+# The "runtime/cgo" import found in synthesized .go files (reported in
+# the CompiledGoFiles field) should have a corresponding entry in the
+# ImportMap field when a runtime/cgo variant (such as a test variant)
+# will be used.
+
+[short] skip  # -compiled can be slow (because it compiles things)
+[!cgo] skip
+
+env CGO_ENABLED=1
+env GOFLAGS=-tags=netcgo  # Force net to use cgo even on Windows.
+
+
+# "runtime/cgo [runtime.test]" appears in the the test dependencies of "runtime",
+# because "runtime/cgo" itself depends on "runtime"
+
+go list -deps -test -compiled -f '{{if eq .ImportPath "net [runtime.test]"}}{{printf "%q" .Imports}}{{end}}' runtime
+
+	# Control case: the explicitly-imported package "sync" is a test variant,
+	# because "sync" depends on "runtime".
+stdout '"sync \[runtime\.test\]"'
+! stdout '"sync"'
+
+	# Experiment: the implicitly-imported package "runtime/cgo" is also a test variant,
+	# because "runtime/cgo" also depends on "runtime".
+stdout '"runtime/cgo \[runtime\.test\]"'
+! stdout '"runtime/cgo"'
+
+
+# Because the import of "runtime/cgo" in the cgo-generated file actually refers
+# to "runtime/cgo [runtime.test]", the latter should be listed in the ImportMap.
+# BUG(#46462): Today, it is not.
+
+go list -deps -test -compiled -f '{{if eq .ImportPath "net [runtime.test]"}}{{printf "%q" .ImportMap}}{{end}}' runtime
+
+stdout '"sync":"sync \[runtime\.test\]"'                # control
+stdout '"runtime/cgo":"runtime/cgo \[runtime\.test\]"'  # experiment
diff --git a/src/cmd/go/testdata/script/list_err_cycle.txt b/src/cmd/go/testdata/script/list_err_cycle.txt
new file mode 100644
index 0000000..44b82a6
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_err_cycle.txt
@@ -0,0 +1,15 @@
+# Check that we don't get infinite recursion when loading a package with
+# an import cycle and another error. Verifies #25830.
+! go list
+stderr 'found packages a \(a.go\) and b \(b.go\)'
+
+-- go.mod --
+module errcycle
+
+go 1.16
+-- a.go --
+package a
+
+import _ "errcycle"
+-- b.go --
+package b
\ No newline at end of file
diff --git a/src/cmd/go/testdata/script/list_find_nodeps.txt b/src/cmd/go/testdata/script/list_find_nodeps.txt
new file mode 100644
index 0000000..e08ce78
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_find_nodeps.txt
@@ -0,0 +1,49 @@
+# Issue #46092
+# go list -find should always return a package with an empty Deps list
+
+# The linker loads implicit dependencies
+go list -find -f {{.Deps}} ./cmd
+stdout '\[\]'
+
+# Cgo translation may add imports of "unsafe", "runtime/cgo" and "syscall"
+go list -find -f {{.Deps}} ./cgo
+stdout '\[\]'
+
+# SWIG adds imports of some standard packages
+go list -find -f {{.Deps}} ./swig
+stdout '\[\]'
+
+-- go.mod --
+module listfind
+
+-- cmd/main.go --
+package main
+
+func main() {}
+
+-- cgo/pkg.go --
+package cgopkg
+
+/*
+#include <limits.h>
+*/
+import "C"
+
+func F() {
+    println(C.INT_MAX)
+}
+
+-- cgo/pkg_notcgo.go --
+//go:build !cgo
+// +build !cgo
+
+package cgopkg
+
+func F() {
+    println(0)
+}
+
+-- swig/pkg.go --
+package swigpkg
+
+-- swig/a.swigcxx --
diff --git a/src/cmd/go/testdata/script/list_gomod_in_gopath.txt b/src/cmd/go/testdata/script/list_gomod_in_gopath.txt
new file mode 100644
index 0000000..064f33a
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_gomod_in_gopath.txt
@@ -0,0 +1,23 @@
+# Issue 46119
+
+# When a module is inside a GOPATH workspace, Package.Root should be set to
+# Module.Dir instead of $GOPATH/src.
+
+env GOPATH=$WORK/tmp
+cd $WORK/tmp/src/test
+
+go list -f {{.Root}}
+stdout ^$PWD$
+
+# Were we really inside a GOPATH workspace?
+env GO111MODULE=off
+go list -f {{.Root}}
+stdout ^$WORK/tmp$
+
+-- $WORK/tmp/src/test/go.mod --
+module test
+
+-- $WORK/tmp/src/test/main.go --
+package main
+
+func main() {}
diff --git a/src/cmd/go/testdata/script/list_json_with_f.txt b/src/cmd/go/testdata/script/list_json_with_f.txt
new file mode 100644
index 0000000..2011a6e
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_json_with_f.txt
@@ -0,0 +1,20 @@
+[short] skip
+
+# list -json should generate output on stdout
+go list -json ./...
+stdout .
+# list -f should generate output on stdout
+go list -f '{{.}}' ./...
+stdout .
+
+# test passing first -json then -f
+! go list -json -f '{{.}}' ./...
+stderr '^go list -f cannot be used with -json$'
+
+# test passing first -f then -json
+! go list -f '{{.}}' -json ./...
+stderr '^go list -f cannot be used with -json$'
+-- go.mod --
+module m
+-- list_test.go --
+package list_test
diff --git a/src/cmd/go/testdata/script/list_load_err.txt b/src/cmd/go/testdata/script/list_load_err.txt
index b3b7271..0cfa7fb 100644
--- a/src/cmd/go/testdata/script/list_load_err.txt
+++ b/src/cmd/go/testdata/script/list_load_err.txt
@@ -2,26 +2,42 @@
 # other files in the same package cause go/build.Import to return an error.
 # Verfifies golang.org/issue/38568
 
-
 go list -e -deps ./scan
 stdout m/want
 
-
 go list -e -deps ./multi
 stdout m/want
 
-
 go list -e -deps ./constraint
 stdout m/want
 
-
 [cgo] go list -e -test -deps ./cgotest
 [cgo] stdout m/want
 
-
 [cgo] go list -e -deps ./cgoflag
 [cgo] stdout m/want
 
+
+# go list -e should include files with errors in GoFiles, TestGoFiles, and
+# other lists, assuming they match constraints.
+# Verifies golang.org/issue/39986
+go list -e -f '{{range .GoFiles}}{{.}},{{end}}' ./scan
+stdout '^good.go,scan.go,$'
+
+go list -e -f '{{range .GoFiles}}{{.}},{{end}}' ./multi
+stdout '^a.go,b.go,$'
+
+go list -e -f '{{range .GoFiles}}{{.}},{{end}}' ./constraint
+stdout '^good.go,$'
+go list -e -f '{{range .IgnoredGoFiles}}{{.}},{{end}}' ./constraint
+stdout '^constraint.go,$'
+
+[cgo] go list -e -f '{{range .XTestGoFiles}}{{.}},{{end}}' ./cgotest
+[cgo] stdout '^cgo_test.go,$'
+
+[cgo] go list -e -f '{{range .GoFiles}}{{.}},{{end}}' ./cgoflag
+[cgo] stdout '^cgoflag.go,$'
+
 -- go.mod --
 module m
 
diff --git a/src/cmd/go/testdata/script/list_module_when_error.txt b/src/cmd/go/testdata/script/list_module_when_error.txt
new file mode 100644
index 0000000..844164c
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_module_when_error.txt
@@ -0,0 +1,19 @@
+# The Module field should be populated even if there is an error loading the package.
+
+env GO111MODULE=on
+
+go list -e -f {{.Module}}
+stdout '^mod.com$'
+
+-- go.mod --
+module mod.com
+
+go 1.16
+
+-- blah.go --
+package blah
+
+import _ "embed"
+
+//go:embed README.md
+var readme string
diff --git a/src/cmd/go/testdata/script/list_std_vendor.txt b/src/cmd/go/testdata/script/list_std_vendor.txt
new file mode 100644
index 0000000..8f27cc1
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_std_vendor.txt
@@ -0,0 +1,32 @@
+# https://golang.org/issue/44725: packages in std should have the same
+# dependencies regardless of whether they are listed from within or outside
+# GOROOT/src.
+
+# Control case: net, viewed from outside the 'std' module,
+# should depend on vendor/golang.org/… instead of golang.org/….
+
+go list -deps net
+stdout '^vendor/golang.org/x/net'
+! stdout '^golang.org/x/net'
+cp stdout $WORK/net-deps.txt
+
+
+# It should still report the same package dependencies when viewed from
+# within GOROOT/src.
+
+cd $GOROOT/src
+
+go list -deps net
+stdout '^vendor/golang.org/x/net'
+! stdout '^golang.org/x/net'
+cmp stdout $WORK/net-deps.txt
+
+
+# However, 'go mod' and 'go get' subcommands should report the original module
+# dependencies, not the vendored packages.
+
+[!net] stop
+
+env GOPROXY=
+go mod why -m golang.org/x/net
+stdout '^# golang.org/x/net\nnet\ngolang.org/x/net'
diff --git a/src/cmd/go/testdata/script/list_swigcxx.txt b/src/cmd/go/testdata/script/list_swigcxx.txt
new file mode 100644
index 0000000..c6acd9e
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_swigcxx.txt
@@ -0,0 +1,27 @@
+# go list should not report SWIG-generated C++ files in CompiledGoFiles.
+
+[!exec:swig] skip
+[!exec:g++] skip
+
+# CompiledGoFiles should contain 4 files:
+#  a.go
+#  a.swigcxx.go
+#  _cgo_gotypes.go
+#  a.cgo1.go
+
+go list -f '{{.CompiledGoFiles}}' -compiled=true example/swig
+
+# These names we see here, other than a.go, will be from the build cache,
+# so we just count them.
+stdout a\.go
+stdout -count=3 $GOCACHE
+
+-- go.mod --
+module example
+
+go 1.16
+
+-- swig/a.go --
+package swig
+
+-- swig/a.swigcxx --
diff --git a/src/cmd/go/testdata/script/list_symlink_issue35941.txt b/src/cmd/go/testdata/script/list_symlink_issue35941.txt
new file mode 100644
index 0000000..eb12bde
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_symlink_issue35941.txt
@@ -0,0 +1,18 @@
+[!symlink] skip
+env GO111MODULE=off
+
+# Issue 35941: suppress symlink warnings when running 'go list all'.
+symlink goproj/css -> $GOPATH/src/css
+
+go list all
+! stderr 'warning: ignoring symlink'
+
+# Show symlink warnings when patterns contain '...'.
+go list goproj/...
+stderr 'warning: ignoring symlink'
+
+-- goproj/a.go --
+package a
+
+-- css/index.css --
+body {}
diff --git a/src/cmd/go/testdata/script/mod_all.txt b/src/cmd/go/testdata/script/mod_all.txt
index aac6629..090eeee 100644
--- a/src/cmd/go/testdata/script/mod_all.txt
+++ b/src/cmd/go/testdata/script/mod_all.txt
@@ -189,19 +189,22 @@
 
 rm vendor
 
-# Convert all modules to go 1.16 to enable lazy loading.
-go mod edit -go=1.16 a/go.mod
-go mod edit -go=1.16 b/go.mod
-go mod edit -go=1.16 c/go.mod
-go mod edit -go=1.16 d/go.mod
-go mod edit -go=1.16 q/go.mod
-go mod edit -go=1.16 r/go.mod
-go mod edit -go=1.16 s/go.mod
-go mod edit -go=1.16 t/go.mod
-go mod edit -go=1.16 u/go.mod
-go mod edit -go=1.16 w/go.mod
-go mod edit -go=1.16 x/go.mod
-go mod edit -go=1.16
+# Convert all modules to go 1.17 to enable lazy loading.
+go mod edit -go=1.17 a/go.mod
+go mod edit -go=1.17 b/go.mod
+go mod edit -go=1.17 c/go.mod
+go mod edit -go=1.17 d/go.mod
+go mod edit -go=1.17 q/go.mod
+go mod edit -go=1.17 r/go.mod
+go mod edit -go=1.17 s/go.mod
+go mod edit -go=1.17 t/go.mod
+go mod edit -go=1.17 u/go.mod
+go mod edit -go=1.17 w/go.mod
+go mod edit -go=1.17 x/go.mod
+go mod edit -go=1.17
+cp go.mod go.mod.orig
+go mod tidy
+cmp go.mod go.mod.orig
 
 # With lazy loading, 'go list all' with neither -mod=vendor nor -test should
 # match -mod=vendor without -test in 1.15.
@@ -282,20 +285,41 @@
 stdout '^example.com/u.test$'
 stdout '^example.com/u_test \[example.com/u.test\]$'
 
+# 'go list -m all' should cover all of the modules providing packages in
+# 'go list -test -deps all', but should exclude modules d and x,
+# which are not relevant to the main module and are outside of the
+# lazy-loading horizon.
 
-# TODO(#36460):
-# 'go list -m all' should exactly cover the packages in 'go list -test all'.
+go list -m -f $MODFMT all
+stdout -count=10 '^.'
+stdout '^example.com/a$'
+stdout '^example.com/b$'
+stdout '^example.com/c$'
+! stdout '^example.com/d$'
+stdout '^example.com/main$'
+stdout '^example.com/q$'
+stdout '^example.com/r$'
+stdout '^example.com/s$'
+stdout '^example.com/t$'
+stdout '^example.com/u$'
+stdout '^example.com/w$'
+! stdout '^example.com/x$'
 
 -- go.mod --
 module example.com/main
 
+// Note: this go.mod file initially specifies go 1.15,
+// but includes some redundant roots so that it
+// also already obeys the 1.17 lazy loading invariants.
 go 1.15
 
 require (
 	example.com/a v0.1.0
 	example.com/b v0.1.0
 	example.com/q v0.1.0
+	example.com/r v0.1.0 // indirect
 	example.com/t v0.1.0
+	example.com/u v0.1.0 // indirect
 )
 
 replace (
diff --git a/src/cmd/go/testdata/script/mod_cache_dir.txt b/src/cmd/go/testdata/script/mod_cache_dir.txt
new file mode 100644
index 0000000..7284ccf
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_cache_dir.txt
@@ -0,0 +1,11 @@
+env GO111MODULE=on
+
+# Go should reject relative paths in GOMODCACHE environment.
+
+env GOMODCACHE="~/test"
+! go get example.com/tools/cmd/hello
+stderr 'must be absolute path'
+
+env GOMODCACHE="./test"
+! go get example.com/tools/cmd/hello
+stderr 'must be absolute path'
diff --git a/src/cmd/go/testdata/script/mod_convert.txt b/src/cmd/go/testdata/script/mod_convert.txt
new file mode 100644
index 0000000..f60fe87
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_convert.txt
@@ -0,0 +1,66 @@
+[short] skip
+[!net] skip
+[!exec:git] skip
+
+env GO111MODULE=on
+env GOPROXY=
+env GOSUMDB=
+
+go mod download github.com/docker/distribution@v0.0.0-20150410205453-85de3967aa93
+mkdir x/Godeps
+cp $GOPATH/pkg/mod/github.com/docker/distribution@v0.0.0-20150410205453-85de3967aa93/Godeps/Godeps.json x/Godeps
+cd x
+go mod init github.com/docker/distribution
+cmpenv go.mod go.mod.want
+
+go mod download github.com/fishy/gcsbucket@v0.0.0-20180217031846-618d60fe84e0
+cp $GOPATH/pkg/mod/github.com/fishy/gcsbucket@v0.0.0-20180217031846-618d60fe84e0/Gopkg.lock ../y
+cd ../y
+go mod init github.com/fishy/gcsbucket
+cmpenv go.mod go.mod.want
+
+-- x/go.mod.want --
+module github.com/docker/distribution
+
+go $goversion
+
+require (
+	github.com/AdRoll/goamz v0.0.0-20150130162828-d3664b76d905
+	github.com/MSOpenTech/azure-sdk-for-go v0.0.0-20150323223030-d90753bcad2e
+	github.com/Sirupsen/logrus v0.7.3
+	github.com/bugsnag/bugsnag-go v1.0.3-0.20141110184014-b1d153021fcd
+	github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b
+	github.com/bugsnag/panicwrap v0.0.0-20141110184334-e5f9854865b9
+	github.com/codegangsta/cli v1.4.2-0.20150131031259-6086d7927ec3
+	github.com/docker/docker v1.4.2-0.20150204013315-165ea5c158cf
+	github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1
+	github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7
+	github.com/gorilla/context v0.0.0-20140604161150-14f550f51af5
+	github.com/gorilla/handlers v0.0.0-20140825150757-0e84b7d810c1
+	github.com/gorilla/mux v0.0.0-20140926153814-e444e69cbd2e
+	github.com/jlhawn/go-crypto v0.0.0-20150401213827-cd738dde20f0
+	github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43
+	github.com/yvasiyarov/gorelic v0.0.7-0.20141212073537-a9bba5b9ab50
+	github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f
+	golang.org/x/net v0.0.0-20150202051010-1dfe7915deaf
+	gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789
+	gopkg.in/yaml.v2 v2.0.0-20150116202057-bef53efd0c76
+)
+-- y/go.mod.want --
+module github.com/fishy/gcsbucket
+
+go $goversion
+
+require (
+	cloud.google.com/go v0.18.0
+	github.com/fishy/fsdb v0.0.0-20180217030800-5527ded01371
+	github.com/golang/protobuf v1.0.0
+	github.com/googleapis/gax-go v2.0.0+incompatible
+	golang.org/x/net v0.0.0-20180216171745-136a25c244d3
+	golang.org/x/oauth2 v0.0.0-20180207181906-543e37812f10
+	golang.org/x/text v0.3.1-0.20180208041248-4e4a3210bb54
+	google.golang.org/api v0.0.0-20180217000815-c7a403bb5fe1
+	google.golang.org/appengine v1.0.0
+	google.golang.org/genproto v0.0.0-20180206005123-2b5a72b8730b
+	google.golang.org/grpc v1.10.0
+)
diff --git a/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt b/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt
index ddb0c08..283e2d9 100644
--- a/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt
+++ b/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt
@@ -1,4 +1,6 @@
 env GO111MODULE=on
+env GOPROXY=direct
+env GOSUMDB=off
 
 [!net] skip
 [!exec:git] skip
diff --git a/src/cmd/go/testdata/script/mod_deprecate_message.txt b/src/cmd/go/testdata/script/mod_deprecate_message.txt
new file mode 100644
index 0000000..5670279
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_deprecate_message.txt
@@ -0,0 +1,73 @@
+# When there is a short single-line message, 'go get' should print it all.
+go get -d short
+stderr '^go: module short is deprecated: short$'
+go list -m -u -f '{{.Deprecated}}' short
+stdout '^short$'
+
+# When there is a multi-line message, 'go get' should print the first line.
+go get -d multiline
+stderr '^go: module multiline is deprecated: first line$'
+! stderr 'second line'
+go list -m -u -f '{{.Deprecated}}' multiline
+stdout '^first line\nsecond line.$'
+
+# When there is a long message, 'go get' should print a placeholder.
+go get -d long
+stderr '^go: module long is deprecated: \(message omitted: too long\)$'
+go list -m -u -f '{{.Deprecated}}' long
+stdout '^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$'
+
+# When a message contains unprintable chracters, 'go get' should say that
+# without printing the message.
+go get -d unprintable
+stderr '^go: module unprintable is deprecated: \(message omitted: contains non-printable characters\)$'
+go list -m -u -f '{{.Deprecated}}' unprintable
+stdout '^message contains ASCII BEL\x07$'
+
+-- go.mod --
+module use
+
+go 1.16
+
+require (
+	short v0.0.0
+	multiline v0.0.0
+	long v0.0.0
+	unprintable v0.0.0
+)
+
+replace (
+	short v0.0.0 => ./short
+	multiline v0.0.0 => ./multiline
+	long v0.0.0 => ./long
+	unprintable v0.0.0 => ./unprintable
+)
+-- short/go.mod --
+// Deprecated: short
+module short
+
+go 1.16
+-- short/short.go --
+package short
+-- multiline/go.mod --
+// Deprecated: first line
+// second line.
+module multiline
+
+go 1.16
+-- multiline/multiline.go --
+package multiline
+-- long/go.mod --
+// Deprecated: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+module long
+
+go 1.16
+-- long/long.go --
+package long
+-- unprintable/go.mod --
+// Deprecated: message contains ASCII BEL
+module unprintable
+
+go 1.16
+-- unprintable/unprintable.go --
+package unprintable
diff --git a/src/cmd/go/testdata/script/mod_download.txt b/src/cmd/go/testdata/script/mod_download.txt
index 8a9faff..c2b72b2 100644
--- a/src/cmd/go/testdata/script/mod_download.txt
+++ b/src/cmd/go/testdata/script/mod_download.txt
@@ -107,13 +107,28 @@
 ! go mod download m@latest
 stderr '^go mod download: m@latest: malformed module path "m": missing dot in first path element$'
 
-# download updates go.mod and populates go.sum
+# download without arguments updates go.mod and go.sum after loading the
+# build list, but does not save sums for downloaded zips.
 cd update
+cp go.mod.orig go.mod
 ! exists go.sum
 go mod download
+cmp go.mod.update go.mod
+cmp go.sum.update go.sum
+cp go.mod.orig go.mod
+rm go.sum
+
+# download with arguments (even "all") does update go.mod and go.sum.
+go mod download rsc.io/sampler
+cmp go.mod.update go.mod
 grep '^rsc.io/sampler v1.3.0 ' go.sum
-go list -m rsc.io/sampler
-stdout '^rsc.io/sampler v1.3.0$'
+cp go.mod.orig go.mod
+rm go.sum
+
+go mod download all
+cmp go.mod.update go.mod
+grep '^rsc.io/sampler v1.3.0 ' go.sum
+cd ..
 
 # allow go mod download without go.mod
 env GO111MODULE=auto
@@ -131,7 +146,7 @@
 -- go.mod --
 module m
 
--- update/go.mod --
+-- update/go.mod.orig --
 module m
 
 go 1.16
@@ -140,3 +155,16 @@
 	rsc.io/quote v1.5.2
 	rsc.io/sampler v1.2.1 // older version than in build list
 )
+-- update/go.mod.update --
+module m
+
+go 1.16
+
+require (
+	rsc.io/quote v1.5.2
+	rsc.io/sampler v1.3.0 // older version than in build list
+)
+-- update/go.sum.update --
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/src/cmd/go/testdata/script/mod_edit.txt b/src/cmd/go/testdata/script/mod_edit.txt
index 9da6930..5aa5ca1 100644
--- a/src/cmd/go/testdata/script/mod_edit.txt
+++ b/src/cmd/go/testdata/script/mod_edit.txt
@@ -46,6 +46,10 @@
 go mod edit -json $WORK/go.mod.retractrationale
 cmp stdout $WORK/go.mod.retractrationale.json
 
+# go mod edit -json (deprecation)
+go mod edit -json $WORK/go.mod.deprecation
+cmp stdout $WORK/go.mod.deprecation.json
+
 # go mod edit -json (empty mod file)
 go mod edit -json $WORK/go.mod.empty
 cmp stdout $WORK/go.mod.empty.json
@@ -290,6 +294,20 @@
 		}
 	]
 }
+-- $WORK/go.mod.deprecation --
+// Deprecated: and the new one is not ready yet
+module m
+-- $WORK/go.mod.deprecation.json --
+{
+	"Module": {
+		"Path": "m",
+		"Deprecated": "and the new one is not ready yet"
+	},
+	"Require": null,
+	"Exclude": null,
+	"Replace": null,
+	"Retract": null
+}
 -- $WORK/go.mod.empty --
 -- $WORK/go.mod.empty.json --
 {
diff --git a/src/cmd/go/testdata/script/mod_edit_no_modcache.txt b/src/cmd/go/testdata/script/mod_edit_no_modcache.txt
new file mode 100644
index 0000000..ced15bb
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_edit_no_modcache.txt
@@ -0,0 +1,15 @@
+# 'go mod edit' opportunistically locks the side-lock file in the module cache,
+# for compatibility with older versions of the 'go' command.
+# It does not otherwise depend on the module cache, so it should not
+# fail if the module cache directory cannot be created.
+
+[root] skip
+
+mkdir $WORK/readonly
+chmod 0555 $WORK/readonly
+env GOPATH=$WORK/readonly/nonexist
+
+go mod edit -go=1.17
+
+-- go.mod --
+module example.com/m
diff --git a/src/cmd/go/testdata/script/mod_empty_err.txt b/src/cmd/go/testdata/script/mod_empty_err.txt
index 982e6b2..c4359bc 100644
--- a/src/cmd/go/testdata/script/mod_empty_err.txt
+++ b/src/cmd/go/testdata/script/mod_empty_err.txt
@@ -1,4 +1,4 @@
-# This test checks error messages for non-existant packages in module mode.
+# This test checks error messages for non-existent packages in module mode.
 # Veries golang.org/issue/35414
 env GO111MODULE=on
 cd $WORK
diff --git a/src/cmd/go/testdata/script/mod_get_deprecate_install.txt b/src/cmd/go/testdata/script/mod_get_deprecate_install.txt
new file mode 100644
index 0000000..63cd27a
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_get_deprecate_install.txt
@@ -0,0 +1,39 @@
+[short] skip
+
+env GO111MODULE=on
+
+# 'go get' outside a module with an executable prints a deprecation message.
+go get example.com/cmd/a
+stderr '^go get: installing executables with ''go get'' in module mode is deprecated.$'
+stderr 'Use ''go install pkg@version'' instead.'
+
+cp go.mod.orig go.mod
+
+# 'go get' inside a module with a non-main package does not print a message.
+# This will stop building in the future, but it's the command we want to use.
+go get rsc.io/quote
+! stderr deprecated
+cp go.mod.orig go.mod
+
+# 'go get' inside a module with an executable prints a different
+# deprecation message.
+go get example.com/cmd/a
+stderr '^go get: installing executables with ''go get'' in module mode is deprecated.$'
+stderr 'To adjust and download dependencies of the current module, use ''go get -d'''
+cp go.mod.orig go.mod
+
+# 'go get' should not print a warning for a main package inside the main module.
+# The intent is most likely to update the dependencies of that package.
+# 'go install' would be used otherwise.
+go get m
+! stderr .
+cp go.mod.orig go.mod
+
+-- go.mod.orig --
+module m
+
+go 1.17
+-- main.go --
+package main
+
+func main() {}
diff --git a/src/cmd/go/testdata/script/mod_get_deprecated.txt b/src/cmd/go/testdata/script/mod_get_deprecated.txt
new file mode 100644
index 0000000..7bdd7a5
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_get_deprecated.txt
@@ -0,0 +1,66 @@
+# 'go get pkg' should not show a deprecation message for an unrelated module.
+go get -d ./use/nothing
+! stderr 'module.*is deprecated'
+
+# 'go get pkg' should show a deprecation message for the module providing pkg.
+go get -d example.com/deprecated/a
+stderr '^go: module example.com/deprecated/a is deprecated: in example.com/deprecated/a@v1.9.0$'
+go get -d example.com/deprecated/a@v1.0.0
+stderr '^go: module example.com/deprecated/a is deprecated: in example.com/deprecated/a@v1.9.0$'
+
+# 'go get pkg' should show a deprecation message for a module providing
+# packages directly imported by pkg.
+go get -d ./use/a
+stderr '^go: module example.com/deprecated/a is deprecated: in example.com/deprecated/a@v1.9.0$'
+
+# 'go get pkg' may show a deprecation message for an indirectly required module
+# if it provides a package named on the command line.
+go get -d ./use/b
+! stderr 'module.*is deprecated'
+go get -d local/use
+! stderr 'module.*is deprecated'
+go get -d example.com/deprecated/b
+stderr '^go: module example.com/deprecated/b is deprecated: in example.com/deprecated/b@v1.9.0$'
+
+# 'go get pkg' does not show a deprecation message for a module providing a
+# directly imported package if the module is no longer deprecated in its
+# latest version, even if the module is deprecated in its current version.
+go get -d ./use/undeprecated
+! stderr 'module.*is deprecated'
+
+-- go.mod --
+module m
+
+go 1.17
+
+require (
+	example.com/deprecated/a v1.0.0
+	example.com/undeprecated v1.0.0
+	local v0.0.0
+)
+
+replace local v0.0.0 => ./local
+-- use/nothing/nothing.go --
+package nothing
+-- use/a/a.go --
+package a
+
+import _ "example.com/deprecated/a"
+-- use/b/b.go --
+package b
+
+import _ "local/use"
+-- use/undeprecated/undeprecated.go --
+package undeprecated
+
+import _ "example.com/undeprecated"
+-- local/go.mod --
+module local
+
+go 1.17
+
+require example.com/deprecated/b v1.0.0
+-- local/use/use.go --
+package use
+
+import _ "example.com/deprecated/b"
diff --git a/src/cmd/go/testdata/script/mod_get_downadd_indirect.txt b/src/cmd/go/testdata/script/mod_get_downadd_indirect.txt
new file mode 100644
index 0000000..efc38f7
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_get_downadd_indirect.txt
@@ -0,0 +1,81 @@
+# This test illustrates a case where downgrading one module may upgrade another.
+# Compare to the downcross2 test case in cmd/go/internal/mvs/mvs_test.go.
+
+# The initial package import graph used in this test looks like:
+#
+# a ---- b ---- d
+#
+# The module dependency graph originally looks like:
+#
+# a ---- b.2 ---- d.2
+#
+# b.1 ---- c.1
+#
+# If we downgrade module d to version 1, we must downgrade b as well.
+# If that downgrade selects b version 1, we will add a new dependency on module c.
+
+cp go.mod go.mod.orig
+go mod tidy
+cmp go.mod.orig go.mod
+
+go get -d example.com/d@v0.1.0
+go list -m all
+stdout '^example.com/b v0.1.0 '
+stdout '^example.com/c v0.1.0 '
+stdout '^example.com/d v0.1.0 '
+
+-- go.mod --
+module example.com/a
+
+go 1.15
+
+require example.com/b v0.2.0
+
+replace (
+	example.com/b v0.1.0 => ./b1
+	example.com/b v0.2.0 => ./b2
+	example.com/c v0.1.0 => ./c
+	example.com/d v0.1.0 => ./d
+	example.com/d v0.2.0 => ./d
+)
+-- a.go --
+package a
+
+import _ "example.com/b"
+
+-- b1/go.mod --
+module example.com/b
+
+go 1.15
+
+require example.com/c v0.1.0
+-- b1/b.go --
+package b
+
+import _ "example.com/c"
+
+-- b2/go.mod --
+module example.com/b
+
+go 1.15
+
+require example.com/d v0.2.0
+-- b2/b.go --
+package b
+
+import _ "example.com/d"
+
+-- c/go.mod --
+module example.com/c
+
+go 1.15
+
+-- c/c.go --
+package c
+
+-- d/go.mod --
+module example.com/d
+
+go 1.15
+-- d/d.go --
+package d
diff --git a/src/cmd/go/testdata/script/mod_get_downgrade.txt b/src/cmd/go/testdata/script/mod_get_downgrade.txt
index a954c10..c26c5e1 100644
--- a/src/cmd/go/testdata/script/mod_get_downgrade.txt
+++ b/src/cmd/go/testdata/script/mod_get_downgrade.txt
@@ -20,8 +20,8 @@
 stdout 'rsc.io/sampler v1.3.0'
 
 ! go get -d rsc.io/sampler@v1.0.0 rsc.io/quote@v1.5.2 golang.org/x/text@none
+stderr -count=1 '^go get:'
 stderr '^go get: rsc.io/quote@v1.5.2 requires rsc.io/sampler@v1.3.0, not rsc.io/sampler@v1.0.0$'
-stderr '^go get: rsc.io/quote@v1.5.2 requires golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c, not golang.org/x/text@none$'
 
 go list -m all
 stdout 'rsc.io/quote v1.5.1'
diff --git a/src/cmd/go/testdata/script/mod_get_downup_artifact.txt b/src/cmd/go/testdata/script/mod_get_downup_artifact.txt
new file mode 100644
index 0000000..c20583b
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_get_downup_artifact.txt
@@ -0,0 +1,159 @@
+# This test illustrates a case where an upgrade–downgrade–upgrade cycle can
+# result in upgrades of otherwise-irrelevant dependencies.
+#
+# This case has no corresponding test in the mvs package, because it is an
+# artifact that results from the composition of *multiple* MVS operations.
+
+# The initial package import graph used in the test looks like:
+#
+# m ---- a
+# |      |
+# +----- b
+# |      |
+# +----- c
+# |
+# +----- d
+#
+# b version 2 adds its own import of package d.
+#
+# The module dependency graph initially looks like:
+#
+# m ---- a.1
+# |       |
+# +----- b.1
+# |       |
+# +----- c.1
+# |
+# +----- d.1
+#
+# b.2 ---- c.2
+#  |
+#  +------ d.2
+#  |
+#  +------ e.1
+#
+# If we upgrade module b to version 2, we will upgrade c and d and add a new
+# dependency on e. If b version 2 is disallowed because of any of those
+# dependencies, the other dependencies should not be upgraded as a side-effect.
+
+cp go.mod go.mod.orig
+go mod tidy
+cmp go.mod go.mod.orig
+
+go list -m all
+stdout '^example.com/a v0.1.0 '
+stdout '^example.com/b v0.1.0 '
+stdout '^example.com/c v0.1.0 '
+stdout '^example.com/d v0.1.0 '
+! stdout '^example.com/e '
+
+# b is imported by a, so the -u flag would normally upgrade it to v0.2.0.
+# However, that would conflict with the explicit c@v0.1.0 constraint,
+# so b must remain at v0.1.0.
+#
+# If we're not careful, we might temporarily add b@v0.2.0 and pull in its
+# upgrades of module d and addition of module e, which are not relevant to
+# b@v0.1.0 and should not be added to the main module's dependencies.
+
+go get -u -d example.com/a@latest example.com/c@v0.1.0
+
+go list -m all
+stdout '^example.com/a v0.1.0 '
+stdout '^example.com/b v0.1.0 '
+stdout '^example.com/c v0.1.0 '
+stdout '^example.com/d v0.1.0 '
+! stdout '^example.com/e '
+
+-- go.mod --
+module example.com/m
+
+go 1.16
+
+require (
+	example.com/a v0.1.0
+	example.com/b v0.1.0
+	example.com/c v0.1.0
+	example.com/d v0.1.0
+)
+
+replace (
+	example.com/a v0.1.0 => ./a1
+	example.com/b v0.1.0 => ./b1
+	example.com/b v0.2.0 => ./b2
+	example.com/c v0.1.0 => ./c
+	example.com/c v0.2.0 => ./c
+	example.com/d v0.1.0 => ./d
+	example.com/d v0.2.0 => ./d
+	example.com/e v0.1.0 => ./e
+)
+-- m.go --
+package m
+
+import (
+	_ "example.com/a"
+	_ "example.com/b"
+	_ "example.com/c"
+	_ "example.com/d"
+)
+
+-- a1/go.mod --
+module example.com/a
+
+go 1.16
+
+require example.com/b v0.1.0
+-- a1/a.go --
+package a
+
+import _ "example.com/b"
+
+-- b1/go.mod --
+module example.com/b
+
+go 1.16
+
+require example.com/c v0.1.0
+-- b1/b.go --
+package b
+
+import _ "example.com/c"
+
+-- b2/go.mod --
+module example.com/b
+
+go 1.16
+
+require (
+	example.com/c v0.2.0
+	example.com/d v0.2.0
+	example.com/e v0.1.0
+)
+-- b2/b.go --
+package b
+
+import (
+	"example.com/c"
+	"example.com/d"
+	"example.com/e"
+)
+
+-- c/go.mod --
+module example.com/c
+
+go 1.16
+-- c/c.go --
+package c
+
+-- d/go.mod --
+module example.com/d
+
+go 1.16
+-- d/d.go --
+package d
+
+-- e/go.mod --
+module example.com/e
+
+go 1.16
+-- e/e.go --
+package e
diff --git a/src/cmd/go/testdata/script/mod_get_downup_indirect.txt b/src/cmd/go/testdata/script/mod_get_downup_indirect.txt
new file mode 100644
index 0000000..ced1dcd
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_get_downup_indirect.txt
@@ -0,0 +1,101 @@
+# This test illustrates a case where downgrading one module may upgrade another.
+# Compare to the downcross1 test case in cmd/go/internal/mvs/mvs_test.go.
+
+# The package import graph used in this test looks like:
+#
+# a ---- b
+#   \     \
+#    \     \
+#     ----- c ---- d
+#
+# The module dependency graph originally looks like:
+#
+# a ---- b.2
+#   \      \
+#    \      \
+#     ----- c.1 ---- d.2
+#
+# b.1 ---- c.2
+#
+# If we downgrade module d to version 1, we must downgrade b as well.
+# If that downgrade selects b version 1, we will upgrade module c to version 2.
+# So 'go get d@1' should instead downgrade both b and c to "none".
+
+cp go.mod go.mod.orig
+go mod tidy
+cmp go.mod.orig go.mod
+
+go get -d example.com/d@v0.1.0
+go list -m all
+! stdout '^example.com/b '
+! stdout '^example.com/c '
+stdout '^example.com/d v0.1.0 '
+
+-- go.mod --
+module example.com/a
+
+go 1.15
+
+require (
+	example.com/b v0.2.0
+	example.com/c v0.1.0
+)
+
+replace (
+	example.com/b v0.1.0 => ./b1
+	example.com/b v0.2.0 => ./b2
+	example.com/c v0.1.0 => ./c1
+	example.com/c v0.2.0 => ./c2
+	example.com/d v0.1.0 => ./d
+	example.com/d v0.2.0 => ./d
+)
+-- a.go --
+package a
+
+import (
+	_ "example.com/b"
+	_ "example.com/c"
+)
+
+-- b1/go.mod --
+module example.com/b
+
+go 1.15
+
+require example.com/c v0.2.0
+-- b1/b.go --
+package b
+
+import _ "example.com/c"
+
+-- b2/go.mod --
+module example.com/b
+
+go 1.15
+
+require example.com/c v0.1.0
+-- b2/b.go --
+package b
+
+import _ "example.com/c"
+
+-- c1/go.mod --
+module example.com/c
+
+go 1.15
+
+require example.com/d v0.2.0
+-- c1/c.go --
+package c
+
+-- c2/go.mod --
+module example.com/c
+
+go 1.15
+-- c2/c.go --
+package c
+
+-- d/go.mod --
+module example.com/d
+
+go 1.15
diff --git a/src/cmd/go/testdata/script/mod_get_downup_pseudo_artifact.txt b/src/cmd/go/testdata/script/mod_get_downup_pseudo_artifact.txt
new file mode 100644
index 0000000..c49615c
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_get_downup_pseudo_artifact.txt
@@ -0,0 +1,129 @@
+# This test illustrates a case where an upgrade–downgrade–upgrade cycle could
+# add extraneous dependencies due to another module depending on an
+# otherwise-unlisted version (such as a pseudo-version).
+#
+# This case corresponds to the "downhiddenartifact" test in the mvs package.
+
+# The initial package import graph used in the test looks like:
+#
+# a --- b
+#  \     \
+#   \     \
+#    c --- d
+#
+# The module dependency graph initially looks like:
+#
+# a --- b.3
+#  \      \
+#   \      \
+#   c.2 --- d.2
+#
+# c.1 --- b.2 (pseudo)
+#
+# b.1 --- e.1
+
+cp go.mod go.mod.orig
+go mod tidy
+cmp go.mod.orig go.mod
+
+# When we downgrade d.2 to d.1, no dependency on e should be added
+# because nothing else in the module or import graph requires it.
+go get -d example.net/d@v0.1.0
+
+go list -m all
+stdout '^example.net/b v0.2.1-0.20210219000000-000000000000 '
+stdout '^example.net/c v0.1.0 '
+stdout '^example.net/d v0.1.0 '
+! stdout '^example.net/e '
+
+-- go.mod --
+module example.net/a
+
+go 1.16
+
+require (
+	example.net/b v0.3.0
+	example.net/c v0.2.0
+)
+
+replace (
+	example.net/b v0.1.0 => ./b1
+	example.net/b v0.2.1-0.20210219000000-000000000000 => ./b2
+	example.net/b v0.3.0 => ./b3
+	example.net/c v0.1.0 => ./c1
+	example.net/c v0.2.0 => ./c2
+	example.net/d v0.1.0 => ./d
+	example.net/d v0.2.0 => ./d
+	example.net/e v0.1.0 => ./e
+)
+-- a.go --
+package a
+
+import (
+	_ "example.net/b"
+	_ "example.net/c"
+)
+
+-- b1/go.mod --
+module example.net/b
+
+go 1.16
+
+require example.net/e v0.1.0
+-- b1/b.go --
+package b
+
+import _ "example.net/e"
+
+-- b2/go.mod --
+module example.net/b
+
+go 1.16
+-- b2/b.go --
+package b
+
+-- b3/go.mod --
+module example.net/b
+
+go 1.16
+
+require example.net/d v0.2.0
+-- b3/b.go --
+package b
+
+import _ "example.net/d"
+-- c1/go.mod --
+module example.net/c
+
+go 1.16
+
+require example.net/b v0.2.1-0.20210219000000-000000000000
+-- c1/c.go --
+package c
+
+import _ "example.net/b"
+
+-- c2/go.mod --
+module example.net/c
+
+go 1.16
+
+require example.net/d v0.2.0
+-- c2/c.go --
+package c
+
+import _ "example.net/d"
+
+-- d/go.mod --
+module example.net/d
+
+go 1.16
+-- d/d.go --
+package d
+
+-- e/go.mod --
+module example.net/e
+
+go 1.16
+-- e/e.go --
+package e
diff --git a/src/cmd/go/testdata/script/mod_get_insecure_redirect.txt b/src/cmd/go/testdata/script/mod_get_insecure_redirect.txt
index 3755f17..2e12834 100644
--- a/src/cmd/go/testdata/script/mod_get_insecure_redirect.txt
+++ b/src/cmd/go/testdata/script/mod_get_insecure_redirect.txt
@@ -1,4 +1,4 @@
-# golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure.
+# golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure (now replaced by GOINSECURE).
 
 [!net] skip
 [!exec:git] skip
@@ -10,8 +10,6 @@
 ! go get -d vcs-test.golang.org/insecure/go/insecure
 stderr 'redirected .* to insecure URL'
 
-go get -d -insecure vcs-test.golang.org/insecure/go/insecure
-
 # insecure host
 env GOINSECURE=vcs-test.golang.org
 go clean -modcache
diff --git a/src/cmd/go/testdata/script/mod_get_lazy_indirect.txt b/src/cmd/go/testdata/script/mod_get_lazy_indirect.txt
new file mode 100644
index 0000000..1cef9d1
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_get_lazy_indirect.txt
@@ -0,0 +1,44 @@
+# https://golang.org/issue/45979: after 'go get' on a package,
+# that package should be importable without error.
+
+
+# We start out with an unresolved dependency.
+# 'go list' suggests that we run 'go get' on that dependency.
+
+! go list -deps .
+stderr '^m.go:3:8: no required module provides package rsc\.io/quote; to add it:\n\tgo get rsc.io/quote$'
+
+
+# When we run the suggested 'go get' command, the new dependency can be used
+# immediately.
+#
+# 'go get' marks the new dependency as 'indirect', because it doesn't scan
+# enough source code to know whether it is direct, and it is easier and less
+# invasive to remove an incorrect indirect mark (e.g. using 'go get') than to
+# add one that is missing ('go mod tidy' or 'go mod vendor').
+
+go get rsc.io/quote
+grep 'rsc.io/quote v\d+\.\d+\.\d+ // indirect$' go.mod
+! grep 'rsc.io/quote v\d+\.\d+\.\d+$' go.mod
+
+go list -deps .
+! stderr .
+[!short] go build .
+[!short] ! stderr .
+
+
+# 'go get .' (or 'go mod tidy') removes the indirect mark.
+
+go get .
+grep 'rsc.io/quote v\d+\.\d+\.\d+$' go.mod
+! grep 'rsc.io/quote v\d+\.\d+\.\d+ // indirect$' go.mod
+
+
+-- go.mod --
+module example.com/m
+
+go 1.17
+-- m.go --
+package m
+
+import _ "rsc.io/quote"
diff --git a/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt b/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt
index 8f6793e..789d42d 100644
--- a/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt
+++ b/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt
@@ -29,7 +29,7 @@
 -- go.mod --
 module use
 
-go 1.17
+go 1.16
 
 require rsc.io/quote v1.5.2
 -- go.sum.tidy --
diff --git a/src/cmd/go/testdata/script/mod_get_pkgtags.txt b/src/cmd/go/testdata/script/mod_get_pkgtags.txt
index c0a57f3..0c79ec7 100644
--- a/src/cmd/go/testdata/script/mod_get_pkgtags.txt
+++ b/src/cmd/go/testdata/script/mod_get_pkgtags.txt
@@ -16,6 +16,7 @@
 # error out if dependencies of tag-guarded files are missing.
 
 go get -d example.net/tools@v0.1.0
+! stderr 'no Go source files'
 
 ! go list example.net/tools
 stderr '^package example.net/tools: build constraints exclude all Go files in .*[/\\]tools$'
@@ -30,6 +31,19 @@
 stderr '^no required module provides package example.net/missing; to add it:\n\tgo get example.net/missing$'
 
 
+# https://golang.org/issue/33526: 'go get' without '-d' should succeed
+# for a module whose root is a constrained-out package.
+#
+# Ideally it should silently succeed, but today it logs the "no Go source files"
+# error and succeeds anyway.
+
+go get example.net/tools@v0.1.0
+! stderr .
+
+! go build example.net/tools
+stderr '^package example.net/tools: build constraints exclude all Go files in .*[/\\]tools$'
+
+
 # https://golang.org/issue/29268
 # 'go get' should fetch modules whose roots contain test-only packages, but
 # without the -t flag shouldn't error out if the test has missing dependencies.
diff --git a/src/cmd/go/testdata/script/mod_get_private_vcs.txt b/src/cmd/go/testdata/script/mod_get_private_vcs.txt
index 514b0a7..75c776a 100644
--- a/src/cmd/go/testdata/script/mod_get_private_vcs.txt
+++ b/src/cmd/go/testdata/script/mod_get_private_vcs.txt
@@ -9,3 +9,35 @@
 stderr 'Confirm the import path was entered correctly.'
 stderr 'If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.'
 ! stdout .
+
+# Fetching a nonexistent commit should return an "unknown revision"
+# error message.
+! go get github.com/golang/term@86186f3aba07ed0212cfb944f3398997d2d07c6b
+stderr '^go get: github.com/golang/term@86186f3aba07ed0212cfb944f3398997d2d07c6b: invalid version: unknown revision 86186f3aba07ed0212cfb944f3398997d2d07c6b$'
+! stdout .
+
+! go get github.com/golang/nonexist@master
+stderr '^Confirm the import path was entered correctly.$'
+stderr '^If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.$'
+! stderr 'unknown revision'
+! stdout .
+
+[!linux] stop  # Needs XDG_CONFIG_HOME.
+[!exec:false] stop
+
+# Test that Git clone errors will be shown to the user instead of a generic
+# "unknown revision" error. To do this we want to force git ls-remote to return
+# an error we don't already have special handling for. See golang/go#42751.
+#
+# Set XDG_CONFIG_HOME to tell Git where to look for the git config file listed
+# below, which turns on ssh.
+env XDG_CONFIG_HOME=$TMPDIR
+env GIT_SSH_COMMAND=false
+! go install github.com/golang/nonexist@master
+stderr 'fatal: Could not read from remote repository.'
+! stderr 'unknown revision'
+! stdout .
+
+-- $TMPDIR/git/config --
+[url "git@github.com:"]
+    insteadOf = https://github.com/
diff --git a/src/cmd/go/testdata/script/mod_get_promote_implicit.txt b/src/cmd/go/testdata/script/mod_get_promote_implicit.txt
index 10ca659..9eec201 100644
--- a/src/cmd/go/testdata/script/mod_get_promote_implicit.txt
+++ b/src/cmd/go/testdata/script/mod_get_promote_implicit.txt
@@ -6,7 +6,7 @@
 go list -m indirect-with-pkg
 stdout '^indirect-with-pkg v1.0.0 => ./indirect-with-pkg$'
 ! go list ./use-indirect
-stderr '^go: m/use-indirect: package indirect-with-pkg imported from implicitly required module; to add missing requirements, run:\n\tgo get indirect-with-pkg@v1.0.0$'
+stderr '^package m/use-indirect imports indirect-with-pkg from implicitly required module; to add missing requirements, run:\n\tgo get indirect-with-pkg@v1.0.0$'
 
 # We can promote the implicit requirement by getting the importing package.
 # NOTE: the hint recommends getting the imported package (tested below) since
diff --git a/src/cmd/go/testdata/script/mod_get_trailing_slash.txt b/src/cmd/go/testdata/script/mod_get_trailing_slash.txt
index 3b38d8b..c536693 100644
--- a/src/cmd/go/testdata/script/mod_get_trailing_slash.txt
+++ b/src/cmd/go/testdata/script/mod_get_trailing_slash.txt
@@ -1,6 +1,3 @@
-# Populate go.sum
-go mod download
-
 # go list should succeed to load a package ending with ".go" if the path does
 # not correspond to an existing local file. Listing a pattern ending with
 # ".go/" should try to list a package regardless of whether a file exists at the
@@ -31,3 +28,10 @@
 go 1.13
 
 require example.com/dotgo.go v1.0.0
+-- go.sum --
+example.com/dotgo.go v1.0.0 h1:XKJfs0V8x2PvY2tX8bJBCEbCDLnt15ma2onwhVpew/I=
+example.com/dotgo.go v1.0.0/go.mod h1:Qi6z/X3AC5vHiuMt6HF2ICx3KhIBGrMdrA7YoPDKqR0=
+-- use.go --
+package use
+
+import _ "example.com/dotgo.go"
diff --git a/src/cmd/go/testdata/script/mod_get_update_unrelated_sum.txt b/src/cmd/go/testdata/script/mod_get_update_unrelated_sum.txt
new file mode 100644
index 0000000..0093c0e
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_get_update_unrelated_sum.txt
@@ -0,0 +1,120 @@
+# Check that 'go get' adds sums for updated modules if we had sums before,
+# even if we didn't load packages from them.
+# Verifies #44129.
+
+env fmt='{{.ImportPath}}: {{if .Error}}{{.Error.Err}}{{else}}ok{{end}}'
+
+# Control case: before upgrading, we have the sums we need.
+# go list -deps -e -f $fmt .
+# stdout '^rsc.io/quote: ok$'
+# ! stdout rsc.io/sampler  # not imported by quote in this version
+cp go.mod.orig go.mod
+cp go.sum.orig go.sum
+go mod tidy
+cmp go.mod.orig go.mod
+cmp go.sum.orig go.sum
+
+
+# Upgrade a module. This also upgrades rsc.io/quote, and though we didn't load
+# a package from it, we had the sum for its old version, so we need the
+# sum for the new version, too.
+go get -d example.com/upgrade@v0.0.2
+grep '^rsc.io/quote v1.5.2 ' go.sum
+
+# The upgrade still breaks the build because the new version of quote imports
+# rsc.io/sampler, and we don't have its zip sum.
+go list -deps -e -f $fmt
+stdout 'rsc.io/quote: ok'
+stdout 'rsc.io/sampler: missing go.sum entry for module providing package rsc.io/sampler'
+cp go.mod.orig go.mod
+cp go.sum.orig go.sum
+
+
+# Replace the old version with a directory before upgrading.
+# We didn't need a sum for it before (even though we had one), so we won't
+# fetch a new sum.
+go mod edit -replace rsc.io/quote@v1.0.0=./dummy
+go get -d example.com/upgrade@v0.0.2
+! grep '^rsc.io/quote v1.5.2 ' go.sum
+cp go.mod.orig go.mod
+cp go.sum.orig go.sum
+
+
+# Replace the new version with a directory before upgrading.
+# We can't get a sum for a directory.
+go mod edit -replace rsc.io/quote@v1.5.2=./dummy
+go get -d example.com/upgrade@v0.0.2
+! grep '^rsc.io/quote v1.5.2 ' go.sum
+cp go.mod.orig go.mod
+cp go.sum.orig go.sum
+
+
+# Replace the new version with a different version.
+# We should get a sum for that version.
+go mod edit -replace rsc.io/quote@v1.5.2=rsc.io/quote@v1.5.1
+go get -d example.com/upgrade@v0.0.2
+! grep '^rsc.io/quote v1.5.2 ' go.sum
+grep '^rsc.io/quote v1.5.1 ' go.sum
+cp go.mod.orig go.mod
+cp go.sum.orig go.sum
+
+
+# Delete the new version's zip (but not mod) from the cache and go offline.
+# 'go get' should fail when fetching the zip.
+rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip
+env GOPROXY=off
+! go get -d example.com/upgrade@v0.0.2
+stderr '^go: upgraded rsc.io/quote v1.0.0 => v1.5.2: error finding sum for rsc.io/quote@v1.5.2: module lookup disabled by GOPROXY=off$'
+
+-- go.mod.orig --
+module m
+
+go 1.16
+
+require (
+	example.com/upgrade v0.0.1
+	rsc.io/quote v1.0.0
+)
+
+replace (
+	example.com/upgrade v0.0.1 => ./upgrade1
+	example.com/upgrade v0.0.2 => ./upgrade2
+)
+-- go.sum.orig --
+rsc.io/quote v1.0.0 h1:kQ3IZQzPTiDJxSZI98YaWgxFEhlNdYASHvh+MplbViw=
+rsc.io/quote v1.0.0/go.mod h1:v83Ri/njykPcgJltBc/gEkJTmjTsNgtO1Y7vyIK1CQA=
+-- go.sum.want --
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+rsc.io/quote v1.0.0 h1:kQ3IZQzPTiDJxSZI98YaWgxFEhlNdYASHvh+MplbViw=
+rsc.io/quote v1.0.0/go.mod h1:v83Ri/njykPcgJltBc/gEkJTmjTsNgtO1Y7vyIK1CQA=
+rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0=
+rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+-- use.go --
+package use
+
+import (
+	_ "example.com/upgrade"
+	_ "rsc.io/quote"
+)
+-- upgrade1/go.mod --
+module example.com/upgrade
+
+go 1.16
+-- upgrade1/upgrade.go --
+package upgrade
+-- upgrade2/go.mod --
+module example.com/upgrade
+
+go 1.16
+
+require rsc.io/quote v1.5.2 // indirect
+-- upgrade2/upgrade.go --
+package upgrade
+-- dummy/go.mod --
+module rsc.io/quote
+
+go 1.16
+-- dummy/quote.go --
+package quote
+
diff --git a/src/cmd/go/testdata/script/mod_go_version_missing.txt b/src/cmd/go/testdata/script/mod_go_version_missing.txt
new file mode 100644
index 0000000..d704816
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_go_version_missing.txt
@@ -0,0 +1,122 @@
+cp go.mod go.mod.orig
+
+# For modules whose go.mod file does not include a 'go' directive,
+# we assume the language and dependency semantics of Go 1.16,
+# but do not trigger “automatic vendoring” mode (-mod=vendor),
+# which was added in Go 1.14 and was not triggered
+# under the same conditions in Go 1.16 (which would instead
+# default to -mod=readonly when no 'go' directive is present).
+
+# For Go 1.16 modules, 'all' should prune out dependencies of tests,
+# even if the 'go' directive is missing.
+
+go list -mod=readonly all
+stdout '^example.com/dep$'
+! stdout '^example.com/testdep$'
+cp stdout list-1.txt
+cmp go.mod go.mod.orig
+
+# We should only default to -mod=vendor if the 'go' directive is explicit in the
+# go.mod file. Otherwise, we don't actually know whether the module was written
+# against Go 1.11 or 1.16. We would have to update the go.mod file to clarify,
+# and as of Go 1.16 we don't update the go.mod file by default.
+#
+# If we set -mod=vendor explicitly, we shouldn't apply the Go 1.14
+# consistency check, because — again — we don't know whether we're in a 1.11
+# module or a bad-script-edited 1.16 module.
+
+! go list -mod=vendor all
+! stderr '^go: inconsistent vendoring'
+stderr 'cannot find package "\." in:\n\t.*[/\\]vendor[/\\]example.com[/\\]badedit$'
+
+# When we set -mod=mod, the go version should be updated immediately,
+# to the current version, converting the requirements from eager to lazy.
+#
+# Since we don't know which requirements are actually relevant to the main
+# module, all requirements are added as roots, making the requirements untidy.
+
+go list -mod=mod all
+! stdout '^example.com/testdep$'
+cmp stdout list-1.txt
+cmpenv go.mod go.mod.untidy
+
+go mod tidy
+cmpenv go.mod go.mod.tidy
+
+# On the other hand, if we jump straight to 'go mod tidy',
+# the requirements remain tidy from the start.
+
+cp go.mod.orig go.mod
+go mod tidy
+cmpenv go.mod go.mod.tidy
+
+
+# The updated version should have been written back to go.mod, so now the 'go'
+# directive is explicit. -mod=vendor should trigger by default, and the stronger
+# Go 1.14 consistency check should apply.
+! go list all
+stderr '^go: inconsistent vendoring'
+! stderr badedit
+
+
+-- go.mod --
+module example.com/m
+
+require example.com/dep v0.1.0
+
+replace (
+	example.com/dep v0.1.0 => ./dep
+	example.com/testdep v0.1.0 => ./testdep
+)
+-- go.mod.untidy --
+module example.com/m
+
+go $goversion
+
+require example.com/dep v0.1.0
+
+require example.com/testdep v0.1.0 // indirect
+
+replace (
+	example.com/dep v0.1.0 => ./dep
+	example.com/testdep v0.1.0 => ./testdep
+)
+-- go.mod.tidy --
+module example.com/m
+
+go $goversion
+
+require example.com/dep v0.1.0
+
+replace (
+	example.com/dep v0.1.0 => ./dep
+	example.com/testdep v0.1.0 => ./testdep
+)
+-- vendor/example.com/dep/dep.go --
+package dep
+import _ "example.com/badedit"
+-- vendor/modules.txt --
+HAHAHA this is broken.
+
+-- m.go --
+package m
+
+import _ "example.com/dep"
+
+const x = 1_000
+
+-- dep/go.mod --
+module example.com/dep
+
+require example.com/testdep v0.1.0
+-- dep/dep.go --
+package dep
+-- dep/dep_test.go --
+package dep_test
+
+import _ "example.com/testdep"
+
+-- testdep/go.mod --
+module example.com/testdep
+-- testdep/testdep.go --
+package testdep
diff --git a/src/cmd/go/testdata/script/mod_gomodcache.txt b/src/cmd/go/testdata/script/mod_gomodcache.txt
index b2143e2..74a3c79 100644
--- a/src/cmd/go/testdata/script/mod_gomodcache.txt
+++ b/src/cmd/go/testdata/script/mod_gomodcache.txt
@@ -47,6 +47,11 @@
 go mod download rsc.io/quote@v1.0.0
 exists $WORK/modcache/cache/download/rsc.io/quote/@v/v1.0.0.info
 
+# Test error when cannot create GOMODCACHE directory
+env GOMODCACHE=$WORK/modcachefile
+! go install example.com/cmd/a@v1.0.0
+stderr 'go: could not create module cache'
+
 # Test that the following work even with GO111MODULE=off
 env GO111MODULE=off
 
@@ -58,3 +63,5 @@
 
 -- go.mod --
 module m
+
+-- $WORK/modcachefile --
diff --git a/src/cmd/go/testdata/script/mod_graph_version.txt b/src/cmd/go/testdata/script/mod_graph_version.txt
new file mode 100644
index 0000000..f9a73f4
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_graph_version.txt
@@ -0,0 +1,101 @@
+# For this module, Go 1.17 prunes out a (transitive and otherwise-irrelevant)
+# requirement on a retracted higher version of a dependency.
+# However, when Go 1.16 reads the same requirements from the go.mod file,
+# it does not prune out that requirement, and selects the retracted version.
+#
+# The Go 1.16 module graph looks like:
+#
+# m ---- lazy v0.1.0 ---- requireincompatible v0.1.0 ---- incompatible v2.0.0+incompatible
+# |        |
+# + -------+------------- incompatible v1.0.0
+#
+# The Go 1.17 module graph is the same except that the dependencies of
+# requireincompatible are pruned out (because the module that requires
+# it — lazy v0.1.0 — specifies 'go 1.17', and it is not otherwise relevant to
+# the main module).
+
+cp go.mod go.mod.orig
+
+go mod graph
+cp stdout graph-1.17.txt
+stdout '^example\.com/m example\.com/retract/incompatible@v1\.0\.0$'
+stdout '^example\.net/lazy@v0\.1\.0 example\.com/retract/incompatible@v1\.0\.0$'
+! stdout 'example\.com/retract/incompatible@v2\.0\.0\+incompatible'
+
+go mod graph -go=1.17
+cmp stdout graph-1.17.txt
+
+cmp go.mod go.mod.orig
+
+
+# Setting -go=1.16 should report the graph as viewed by Go 1.16,
+# but should not edit the go.mod file.
+
+go mod graph -go=1.16
+cp stdout graph-1.16.txt
+stdout '^example\.com/m example\.com/retract/incompatible@v1\.0\.0$'
+stdout '^example\.net/lazy@v0\.1\.0 example.com/retract/incompatible@v1\.0\.0$'
+stdout '^example.net/requireincompatible@v0.1.0 example.com/retract/incompatible@v2\.0\.0\+incompatible$'
+
+cmp go.mod go.mod.orig
+
+
+# If we actually update the go.mod file to the requested go version,
+# we should get the same selected versions, but the roots of the graph
+# may be updated.
+#
+# TODO(#45551): The roots should not be updated.
+
+go mod edit -go=1.16
+go mod graph
+! stdout '^example\.com/m example\.com/retract/incompatible@v1\.0\.0$'
+stdout '^example\.net/lazy@v0.1.0 example.com/retract/incompatible@v1\.0\.0$'
+stdout '^example.net/requireincompatible@v0.1.0 example.com/retract/incompatible@v2\.0\.0\+incompatible$'
+	# TODO(#45551): cmp stdout graph-1.16.txt
+
+
+# Unsupported go versions should be rejected, since we don't know
+# what versions they would report.
+! go mod graph -go=1.99999999999
+stderr '^invalid value "1\.99999999999" for flag -go: maximum supported Go version is '$goversion'\nusage: go mod graph \[-go=version\]\nRun ''go help mod graph'' for details.$'
+
+
+-- go.mod --
+// Module m indirectly imports a package from
+// example.com/retract/incompatible. Its selected version of
+// that module is lower under Go 1.17 semantics than under Go 1.16.
+module example.com/m
+
+go 1.17
+
+replace (
+	example.net/lazy v0.1.0 => ./lazy
+	example.net/requireincompatible v0.1.0 => ./requireincompatible
+)
+
+require (
+	example.com/retract/incompatible v1.0.0 // indirect
+	example.net/lazy v0.1.0
+)
+-- lazy/go.mod --
+// Module lazy requires example.com/retract/incompatible v1.0.0.
+//
+// When viewed from the outside it also has a transitive dependency
+// on v2.0.0+incompatible, but in lazy mode that transitive dependency
+// is pruned out.
+module example.net/lazy
+
+go 1.17
+
+exclude example.com/retract/incompatible v2.0.0+incompatible
+
+require (
+	example.com/retract/incompatible v1.0.0
+	example.net/requireincompatible v0.1.0
+)
+-- requireincompatible/go.mod --
+module example.net/requireincompatible
+
+go 1.15
+
+require example.com/retract/incompatible v2.0.0+incompatible
diff --git a/src/cmd/go/testdata/script/mod_indirect_nospace.txt b/src/cmd/go/testdata/script/mod_indirect_nospace.txt
new file mode 100644
index 0000000..f4fb6a8
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_indirect_nospace.txt
@@ -0,0 +1,32 @@
+# https://golang.org/issue/45932: "indirect" comments missing spaces
+# should not be corrupted when the comment is removed.
+
+go mod tidy
+cmp go.mod go.mod.direct
+
+-- go.mod --
+module example.net/m
+
+go 1.16
+
+require example.net/x v0.1.0 //indirect
+
+replace example.net/x v0.1.0 => ./x
+-- go.mod.direct --
+module example.net/m
+
+go 1.16
+
+require example.net/x v0.1.0
+
+replace example.net/x v0.1.0 => ./x
+-- m.go --
+package m
+import _ "example.net/x"
+
+-- x/go.mod --
+module example.net/x
+
+go 1.16
+-- x/x.go --
+package x
diff --git a/src/cmd/go/testdata/script/mod_init_dep.txt b/src/cmd/go/testdata/script/mod_init_dep.txt
index f8cf1d5..76b4867 100644
--- a/src/cmd/go/testdata/script/mod_init_dep.txt
+++ b/src/cmd/go/testdata/script/mod_init_dep.txt
@@ -1,10 +1,6 @@
 env GO111MODULE=on
 env GOFLAGS=-mod=mod
 
-# modconv uses git directly to examine what old 'go get' would
-[!net] skip
-[!exec:git] skip
-
 # go mod init should populate go.mod from Gopkg.lock
 go mod init x
 stderr 'copying requirements from Gopkg.lock'
diff --git a/src/cmd/go/testdata/script/mod_init_glide.txt b/src/cmd/go/testdata/script/mod_init_glide.txt
index a351a6a..373810c 100644
--- a/src/cmd/go/testdata/script/mod_init_glide.txt
+++ b/src/cmd/go/testdata/script/mod_init_glide.txt
@@ -3,6 +3,7 @@
 
 env GO111MODULE=on
 env GOPROXY=direct
+env GOSUMDB=
 
 # Regression test for golang.org/issue/32161:
 # 'go mod init' did not locate tags when resolving a commit to a pseudo-version.
diff --git a/src/cmd/go/testdata/script/mod_init_path.txt b/src/cmd/go/testdata/script/mod_init_path.txt
index ccdfc92..e5fd4dd 100644
--- a/src/cmd/go/testdata/script/mod_init_path.txt
+++ b/src/cmd/go/testdata/script/mod_init_path.txt
@@ -1,7 +1,7 @@
 env GO111MODULE=on
 
 ! go mod init .
-stderr '^go: invalid module path "\.": is a local import path$'
+stderr '^go: malformed module path ".": is a local import path$'
 
 cd x
 go mod init example.com/x
diff --git a/src/cmd/go/testdata/script/mod_install_hint.txt b/src/cmd/go/testdata/script/mod_install_hint.txt
new file mode 100644
index 0000000..ab02840
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_install_hint.txt
@@ -0,0 +1,5 @@
+# Module is replaced but not required. No hint appears as no module is suggested.

+go mod init m

+go mod edit -replace=github.com/notrequired@v0.5.0=github.com/doesnotexist@v0.5.0

+! go install github.com/notrequired

+! stderr 'to add it:'
\ No newline at end of file
diff --git a/src/cmd/go/testdata/script/mod_install_pkg_version.txt b/src/cmd/go/testdata/script/mod_install_pkg_version.txt
index 6ed600f..fd02392 100644
--- a/src/cmd/go/testdata/script/mod_install_pkg_version.txt
+++ b/src/cmd/go/testdata/script/mod_install_pkg_version.txt
@@ -16,7 +16,7 @@
 cd m
 cp go.mod go.mod.orig
 ! go list -m all
-stderr '^go: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry; to add it:\n\tgo mod download example.com/cmd$'
+stderr '^go list -m: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry; to add it:\n\tgo mod download example.com/cmd$'
 go install example.com/cmd/a@latest
 cmp go.mod go.mod.orig
 exists $GOPATH/bin/a$GOEXE
@@ -67,9 +67,9 @@
 go mod init tmp
 go mod edit -require=rsc.io/fortune@v1.0.0
 ! go install -mod=readonly $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0
-stderr '^go: rsc.io/fortune@v1.0.0: missing go.sum entry; to add it:\n\tgo mod download rsc.io/fortune$'
+stderr '^missing go\.sum entry for module providing package rsc\.io/fortune; to add:\n\tgo mod download rsc\.io/fortune$'
 ! go install -mod=readonly ../../pkg/mod/rsc.io/fortune@v1.0.0
-stderr '^go: rsc.io/fortune@v1.0.0: missing go.sum entry; to add it:\n\tgo mod download rsc.io/fortune$'
+stderr '^missing go\.sum entry for module providing package rsc\.io/fortune; to add:\n\tgo mod download rsc\.io/fortune$'
 go get -d rsc.io/fortune@v1.0.0
 go install -mod=readonly $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0
 exists $GOPATH/bin/fortune$GOEXE
@@ -81,17 +81,17 @@
 # 'go install pkg@version' reports errors for meta packages, std packages,
 # and directories.
 ! go install std@v1.0.0
-stderr '^go install std@v1.0.0: argument must be a package path, not a meta-package$'
+stderr '^go install: std@v1.0.0: argument must be a package path, not a meta-package$'
 ! go install fmt@v1.0.0
-stderr '^go install fmt@v1.0.0: argument must not be a package in the standard library$'
+stderr '^go install: fmt@v1.0.0: argument must not be a package in the standard library$'
 ! go install example.com//cmd/a@v1.0.0
-stderr '^go install example.com//cmd/a@v1.0.0: argument must be a clean package path$'
+stderr '^go install: example.com//cmd/a@v1.0.0: argument must be a clean package path$'
 ! go install example.com/cmd/a@v1.0.0 ./x@v1.0.0
-stderr '^go install ./x@v1.0.0: argument must be a package path, not a relative path$'
+stderr '^go install: ./x@v1.0.0: argument must be a package path, not a relative path$'
 ! go install example.com/cmd/a@v1.0.0 $GOPATH/src/x@v1.0.0
-stderr '^go install '$WORK'[/\\]gopath/src/x@v1.0.0: argument must be a package path, not an absolute path$'
+stderr '^go install: '$WORK'[/\\]gopath/src/x@v1.0.0: argument must be a package path, not an absolute path$'
 ! go install example.com/cmd/a@v1.0.0 cmd/...@v1.0.0
-stderr '^go install: package cmd/go not provided by module example.com/cmd@v1.0.0$'
+stderr '^package cmd/go not provided by module example.com/cmd@v1.0.0$'
 
 # 'go install pkg@version' should accept multiple arguments but report an error
 # if the version suffixes are different, even if they refer to the same version.
@@ -106,19 +106,19 @@
 env GO111MODULE=auto
 
 ! go install example.com/cmd/a@v1.0.0 example.com/cmd/b@latest
-stderr '^go install example.com/cmd/b@latest: all arguments must have the same version \(@v1.0.0\)$'
+stderr '^go install: example.com/cmd/b@latest: all arguments must have the same version \(@v1.0.0\)$'
 
 
 # 'go install pkg@version' should report an error if the arguments are in
 # different modules.
 ! go install example.com/cmd/a@v1.0.0 rsc.io/fortune@v1.0.0
-stderr '^go install: package rsc.io/fortune provided by module rsc.io/fortune@v1.0.0\n\tAll packages must be provided by the same module \(example.com/cmd@v1.0.0\).$'
+stderr '^package rsc.io/fortune provided by module rsc.io/fortune@v1.0.0\n\tAll packages must be provided by the same module \(example.com/cmd@v1.0.0\).$'
 
 
 # 'go install pkg@version' should report an error if an argument is not
 # a main package.
 ! go install example.com/cmd/a@v1.0.0 example.com/cmd/err@v1.0.0
-stderr '^go install: package example.com/cmd/err is not a main package$'
+stderr '^package example.com/cmd/err is not a main package$'
 
 # Wildcards should match only main packages. This module has a non-main package
 # with an error, so we'll know if that gets built.
@@ -137,13 +137,13 @@
 
 # If a wildcard matches no packages, we should see a warning.
 ! go install example.com/cmd/nomatch...@v1.0.0
-stderr '^go install example.com/cmd/nomatch\.\.\.@v1.0.0: module example.com/cmd@v1.0.0 found, but does not contain packages matching example.com/cmd/nomatch\.\.\.$'
+stderr '^go install: example.com/cmd/nomatch\.\.\.@v1.0.0: module example.com/cmd@v1.0.0 found, but does not contain packages matching example.com/cmd/nomatch\.\.\.$'
 go install example.com/cmd/a@v1.0.0 example.com/cmd/nomatch...@v1.0.0
 stderr '^go: warning: "example.com/cmd/nomatch\.\.\." matched no packages$'
 
 # If a wildcard matches only non-main packges, we should see a different warning.
 go install example.com/cmd/err...@v1.0.0
-stderr '^go: warning: "example.com/cmd/err\.\.\." matched no main packages$'
+stderr '^go: warning: "example.com/cmd/err\.\.\." matched only non-main packages$'
 
 
 # 'go install pkg@version' should report errors if the module contains
@@ -159,7 +159,7 @@
 # 'go install pkg@version' should report an error if the module requires a
 # higher version of itself.
 ! go install example.com/cmd/a@v1.0.0-newerself
-stderr '^go install example.com/cmd/a@v1.0.0-newerself: version constraints conflict:\n\texample.com/cmd@v1.0.0-newerself requires example.com/cmd@v1.0.0, but example.com/cmd@v1.0.0-newerself is requested$'
+stderr '^go install: example.com/cmd/a@v1.0.0-newerself: version constraints conflict:\n\texample.com/cmd@v1.0.0-newerself requires example.com/cmd@v1.0.0, but example.com/cmd@v1.0.0-newerself is requested$'
 
 
 # 'go install pkg@version' will only match a retracted version if it's
@@ -192,12 +192,12 @@
 
 func main() {}
 -- replace-err --
-go install example.com/cmd/a@v1.0.0-replace: example.com/cmd@v1.0.0-replace
+go install: example.com/cmd/a@v1.0.0-replace (in example.com/cmd@v1.0.0-replace):
 	The go.mod file for the module providing named packages contains one or
 	more replace directives. It must not contain directives that would cause
 	it to be interpreted differently than if it were the main module.
 -- exclude-err --
-go install example.com/cmd/a@v1.0.0-exclude: example.com/cmd@v1.0.0-exclude
+go install: example.com/cmd/a@v1.0.0-exclude (in example.com/cmd@v1.0.0-exclude):
 	The go.mod file for the module providing named packages contains one or
 	more exclude directives. It must not contain directives that would cause
 	it to be interpreted differently than if it were the main module.
diff --git a/src/cmd/go/testdata/script/mod_invalid_path.txt b/src/cmd/go/testdata/script/mod_invalid_path.txt
index c8c075d..333a3ff 100644
--- a/src/cmd/go/testdata/script/mod_invalid_path.txt
+++ b/src/cmd/go/testdata/script/mod_invalid_path.txt
@@ -8,11 +8,8 @@
 # Test that go mod init in GOPATH doesn't add a module declaration
 # with a path that can't possibly be a module path, because
 # it isn't even a valid import path.
-# The single quote and backtick are the only characters  we don't allow
-# in checkModulePathLax, but is allowed in a Windows file name.
-# TODO(matloob): choose a different character once
-# module.CheckImportPath is laxened and replaces
-# checkModulePathLax.
+# The single quote and backtick are the only characters which are not allowed
+# but are a valid Windows file name.
 cd $WORK/'gopath/src/m''d'
 ! go mod init
 stderr 'cannot determine module path'
@@ -21,7 +18,7 @@
 # possibly be a module path, because it isn't even a valid import path
 cd $WORK/gopath/src/badname
 ! go list .
-stderr 'invalid module path'
+stderr 'malformed module path'
 
 # Test that an import path containing an element with a leading dot is valid,
 # but such a module path is not.
diff --git a/src/cmd/go/testdata/script/mod_invalid_path_dotname.txt b/src/cmd/go/testdata/script/mod_invalid_path_dotname.txt
new file mode 100644
index 0000000..8593433
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_invalid_path_dotname.txt
@@ -0,0 +1,46 @@
+# Test that an import path containing an element with a leading dot
+# in another module is valid.
+
+# 'go get' works with no version query.
+cp go.mod.empty go.mod
+go get -d example.com/dotname/.dot
+go list -m example.com/dotname
+stdout '^example.com/dotname v1.0.0$'
+
+# 'go get' works with a version query.
+cp go.mod.empty go.mod
+go get -d example.com/dotname/.dot@latest
+go list -m example.com/dotname
+stdout '^example.com/dotname v1.0.0$'
+
+# 'go get' works on an importing package.
+cp go.mod.empty go.mod
+go get -d .
+go list -m example.com/dotname
+stdout '^example.com/dotname v1.0.0$'
+
+# 'go list' works on the dotted package.
+go list example.com/dotname/.dot
+stdout '^example.com/dotname/.dot$'
+
+# 'go list' works on an importing package.
+go list .
+stdout '^m$'
+
+# 'go mod tidy' works.
+cp go.mod.empty go.mod
+go mod tidy
+go list -m example.com/dotname
+stdout '^example.com/dotname v1.0.0$'
+
+-- go.mod.empty --
+module m
+
+go 1.16
+-- go.sum --
+example.com/dotname v1.0.0 h1:Q0JMAn464CnwFVCshs1n4+f5EFiW/eRhnx/fTWjw2Ag=
+example.com/dotname v1.0.0/go.mod h1:7K4VLT7QylRI8H7yZwUkeDH2s19wQnyfp/3oBlItWJ0=
+-- use.go --
+package use
+
+import _ "example.com/dotname/.dot"
diff --git a/src/cmd/go/testdata/script/mod_invalid_path_plus.txt b/src/cmd/go/testdata/script/mod_invalid_path_plus.txt
index 2f2488f..51dbf93 100644
--- a/src/cmd/go/testdata/script/mod_invalid_path_plus.txt
+++ b/src/cmd/go/testdata/script/mod_invalid_path_plus.txt
@@ -2,18 +2,22 @@
 # The '+' character should be disallowed in module paths, but allowed in package
 # paths within valid modules.
 
+# 'go list' accepts package paths with pluses.
+cp go.mod.orig go.mod
 go get -d example.net/cmd
 go list example.net/cmd/x++
 
+# 'go list -m' rejects module paths with pluses.
 ! go list -versions -m 'example.net/bad++'
-stderr '^go list -m: module example.net/bad\+\+: malformed module path "example.net/bad\+\+": invalid char ''\+''$'
+stderr '^go list -m: malformed module path "example.net/bad\+\+": invalid char ''\+''$'
 
-# TODO(bcmills): 'go get -d example.net/cmd/x++' should also work, but currently
-# it does not. This might be fixed by https://golang.org/cl/297891.
-! go get -d example.net/cmd/x++
-stderr '^go get: malformed module path "example.net/cmd/x\+\+": invalid char ''\+''$'
+# 'go get' accepts package paths with pluses.
+cp go.mod.orig go.mod
+go get -d example.net/cmd/x++
+go list -m example.net/cmd
+stdout '^example.net/cmd v0.0.0-00010101000000-000000000000 => ./cmd$'
 
--- go.mod --
+-- go.mod.orig --
 module example.com/m
 
 go 1.16
diff --git a/src/cmd/go/testdata/script/mod_invalid_version.txt b/src/cmd/go/testdata/script/mod_invalid_version.txt
index 43b9564..6846a79 100644
--- a/src/cmd/go/testdata/script/mod_invalid_version.txt
+++ b/src/cmd/go/testdata/script/mod_invalid_version.txt
@@ -19,7 +19,7 @@
 go mod edit -require golang.org/x/text@14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 \(replaced by \./\..\): parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "14c0d48ead0c" invalid: must be of the form v1.2.3'
+stderr 'go list -m: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ..[/\\]go.mod: '$WORK'[/\\]gopath[/\\]src[/\\]go.mod:5: require golang.org/x/text: version "14c0d48ead0c" invalid: must be of the form v1.2.3'
 cd ..
 go list -m golang.org/x/text
 stdout 'golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c'
@@ -30,7 +30,7 @@
 go mod edit -require golang.org/x/text/unicode@v0.0.0-20170915032832-14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text/unicode@v0.0.0-20170915032832-14c0d48ead0c: invalid version: missing golang.org/x/text/unicode/go.mod at revision 14c0d48ead0c'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgolang.org/x/text/unicode@v0.0.0-20170915032832-14c0d48ead0c: invalid version: missing golang.org/x/text/unicode/go.mod at revision 14c0d48ead0c'
 cd ..
 ! go list -m golang.org/x/text
 stderr 'golang.org/x/text/unicode@v0.0.0-20170915032832-14c0d48ead0c: invalid version: missing golang.org/x/text/unicode/go.mod at revision 14c0d48ead0c'
@@ -47,17 +47,17 @@
 go mod edit -require golang.org/x/text@v2.1.1-0.20170915032832-14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
+stderr 'go list -m: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ..[/\\]go.mod: '$WORK'[/\\]gopath[/\\]src[/\\]go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
 cd ..
 ! go list -m golang.org/x/text
-stderr $WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
+stderr $WORK'[/\\]gopath[/\\]src[/\\]go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
 
 # A pseudo-version with fewer than 12 digits of SHA-1 prefix is invalid.
 cp go.mod.orig go.mod
 go mod edit -require golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0: invalid pseudo-version: revision is shorter than canonical \(14c0d48ead0c\)'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0: invalid pseudo-version: revision is shorter than canonical \(14c0d48ead0c\)'
 cd ..
 ! go list -m golang.org/x/text
 stderr 'golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0: invalid pseudo-version: revision is shorter than canonical \(14c0d48ead0c\)'
@@ -67,7 +67,7 @@
 go mod edit -require golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0cd47e3104ada247d91be04afc7a5a
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0cd47e3104ada247d91be04afc7a5a: invalid pseudo-version: revision is longer than canonical \(14c0d48ead0c\)'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0cd47e3104ada247d91be04afc7a5a: invalid pseudo-version: revision is longer than canonical \(14c0d48ead0c\)'
 cd ..
 ! go list -m golang.org/x/text
 stderr 'golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0cd47e3104ada247d91be04afc7a5a: invalid pseudo-version: revision is longer than canonical \(14c0d48ead0c\)'
@@ -77,7 +77,7 @@
 go mod edit -require golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)'
 cd ..
 ! go list -m golang.org/x/text
 stderr 'golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)'
@@ -87,7 +87,7 @@
 go mod edit -replace golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c=golang.org/x/text@14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)'
 cd ..
 go list -m golang.org/x/text
 stdout 'golang.org/x/text v0.1.1-0.20190915032832-14c0d48ead0c => golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c'
@@ -97,7 +97,7 @@
 go mod edit -require golang.org/x/text@v1.999.999-0.20170915032832-14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v1.999.999-0.20170915032832-14c0d48ead0c: invalid pseudo-version: preceding tag \(v1.999.998\) not found'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgolang.org/x/text@v1.999.999-0.20170915032832-14c0d48ead0c: invalid pseudo-version: preceding tag \(v1.999.998\) not found'
 cd ..
 ! go list -m golang.org/x/text
 stderr 'golang.org/x/text@v1.999.999-0.20170915032832-14c0d48ead0c: invalid pseudo-version: preceding tag \(v1.999.998\) not found'
@@ -109,7 +109,7 @@
 go mod edit -require golang.org/x/text@v1.0.0-20170915032832-14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v1.0.0-20170915032832-14c0d48ead0c: invalid pseudo-version: major version without preceding tag must be v0, not v1'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgolang.org/x/text@v1.0.0-20170915032832-14c0d48ead0c: invalid pseudo-version: major version without preceding tag must be v0, not v1'
 cd ..
 ! go list -m golang.org/x/text
 stderr 'golang.org/x/text@v1.0.0-20170915032832-14c0d48ead0c: invalid pseudo-version: major version without preceding tag must be v0, not v1'
@@ -120,7 +120,7 @@
 go mod edit -require golang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c: invalid pseudo-version: version before v0.0.0 would have negative patch number'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c: invalid pseudo-version: version before v0.0.0 would have negative patch number'
 cd ..
 ! go list -m golang.org/x/text
 stderr 'golang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c: invalid pseudo-version: version before v0.0.0 would have negative patch number'
@@ -130,7 +130,7 @@
 go mod edit -replace golang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c=golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c: invalid pseudo-version: version before v0.0.0 would have negative patch number'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c: invalid pseudo-version: version before v0.0.0 would have negative patch number'
 cd ..
 go list -m golang.org/x/text
 stdout 'golang.org/x/text v0.0.0-0.20170915032832-14c0d48ead0c => golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c'
@@ -153,7 +153,7 @@
 go mod edit -require golang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c: invalid pseudo-version: revision 14c0d48ead0c is not a descendent of preceding tag \(v0.2.0\)'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c: invalid pseudo-version: revision 14c0d48ead0c is not a descendent of preceding tag \(v0.2.0\)'
 cd ..
 ! go list -m golang.org/x/text
 stderr 'golang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c: invalid pseudo-version: revision 14c0d48ead0c is not a descendent of preceding tag \(v0.2.0\)'
@@ -163,7 +163,7 @@
 go mod edit -require golang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac: invalid pseudo-version: tag \(v0.2.0\) found on revision c4d099d611ac is already canonical, so should not be replaced with a pseudo-version derived from that tag'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac: invalid pseudo-version: tag \(v0.2.0\) found on revision c4d099d611ac is already canonical, so should not be replaced with a pseudo-version derived from that tag'
 cd ..
 ! go list -m golang.org/x/text
 stderr 'golang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac: invalid pseudo-version: tag \(v0.2.0\) found on revision c4d099d611ac is already canonical, so should not be replaced with a pseudo-version derived from that tag'
@@ -173,7 +173,7 @@
 go mod edit -require golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0c+incompatible
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0c\+incompatible: invalid version: \+incompatible suffix not allowed: major version v0 is compatible'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0c\+incompatible: invalid version: \+incompatible suffix not allowed: major version v0 is compatible'
 cd ..
 ! go list -m golang.org/x/text
 stderr 'golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0c\+incompatible: invalid version: \+incompatible suffix not allowed: major version v0 is compatible'
@@ -194,7 +194,7 @@
 go mod edit -require github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d+incompatible
 cd outside
 ! go list -m github.com/pierrec/lz4
-stderr 'go: example.com@v0.0.0 requires\n\tgithub.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required'
+stderr 'go list -m: example.com@v0.0.0 requires\n\tgithub.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required'
 cd ..
 ! go list -m github.com/pierrec/lz4
 stderr 'github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required'
diff --git a/src/cmd/go/testdata/script/mod_lazy_consistency.txt b/src/cmd/go/testdata/script/mod_lazy_consistency.txt
new file mode 100644
index 0000000..1bf3e31
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_lazy_consistency.txt
@@ -0,0 +1,95 @@
+# If the root requirements in a lazy module are inconsistent
+# (for example, due to a bad hand-edit or git merge),
+# they can go unnoticed as long as the module with the violated
+# requirement is not used.
+# When we load a package from that module, we should spot-check its
+# requirements and either emit an error or update the go.mod file.
+
+cp go.mod go.mod.orig
+
+
+# If we load package x from x.1, we only check the requirements of x,
+# which are fine: loading succeeds.
+
+go list -deps ./usex
+stdout '^example.net/x$'
+cmp go.mod go.mod.orig
+
+
+# However, if we load needx2, we should load the requirements of needx2.
+# Those requirements indicate x.2, not x.1, so the module graph is
+# inconsistent and needs to be fixed.
+
+! go list -deps ./useneedx2
+stderr '^go: updates to go.mod needed; to update it:\n\tgo mod tidy$'
+
+! go list -deps example.net/needx2
+stderr '^go: updates to go.mod needed; to update it:\n\tgo mod tidy$'
+
+
+# The command printed in the error message should fix the problem.
+
+go mod tidy
+go list -deps ./useneedx2
+stdout '^example.net/m/useneedx2$'
+stdout '^example.net/needx2$'
+stdout '^example.net/x$'
+
+go list -m all
+stdout '^example.net/needx2 v0\.1\.0 '
+stdout '^example.net/x v0\.2\.0 '
+
+
+-- go.mod --
+module example.net/m
+
+go 1.17
+
+require (
+	example.net/needx2 v0.1.0
+	example.net/x v0.1.0
+)
+
+replace (
+	example.net/needx2 v0.1.0 => ./needx2.1
+	example.net/x v0.1.0 => ./x.1
+	example.net/x v0.2.0 => ./x.2
+)
+-- useneedx2/useneedx2.go --
+package useneedx2
+
+import _ "example.net/needx2"
+-- usex/usex.go --
+package usex
+
+import _ "example.net/x"
+
+-- x.1/go.mod --
+module example.com/x
+
+go 1.17
+-- x.1/x.go --
+package x
+
+-- x.2/go.mod --
+module example.com/x
+
+go 1.17
+-- x.2/x.go --
+package x
+
+const AddedInV2 = true
+
+-- needx2.1/go.mod --
+module example.com/x
+
+go 1.17
+
+require example.net/x v0.2.0
+-- needx2.1/needx2.go --
+// Package needx2 needs x v0.2.0 or higher.
+package needx2
+
+import "example.net/x"
+
+var _ = x.AddedInV2
diff --git a/src/cmd/go/testdata/script/mod_lazy_downgrade.txt b/src/cmd/go/testdata/script/mod_lazy_downgrade.txt
index 1e84820..2f815fe 100644
--- a/src/cmd/go/testdata/script/mod_lazy_downgrade.txt
+++ b/src/cmd/go/testdata/script/mod_lazy_downgrade.txt
@@ -1,5 +1,5 @@
 # This test illustrates the interaction between lazy loading and downgrading in
-# 'go get.
+# 'go get'.
 
 # The package import graph used in this test looks like:
 #
@@ -46,7 +46,7 @@
 # outside of the deepening scan should not affect the downgrade.
 
 cp go.mod.orig go.mod
-go mod edit -go=1.16
+go mod edit -go=1.17
 
 go list -m all
 stdout '^example.com/a v0.1.0 '
@@ -59,12 +59,50 @@
 stdout '^example.com/b v0.2.0 '
 stdout '^example.com/c v0.1.0 '
 
+# At this point, b.2 is still an explicit root, so its dependency on c
+# is still tracked, and it will still be downgraded away if we remove c.
+# ('go get' never makes a root into a non-root. Only 'go mod tidy' does that.)
+
 go get -d example.com/c@none
 go list -m all
-! stdout '^example.com/a '  # TODO(#36460): example.com/a v0.1.0
-! stdout '^example.com/b '  # TODO(#36460): example.com/b v0.1.0
+! stdout '^example.com/a '
+! stdout '^example.com/b '
 ! stdout '^example.com/c '
 
+
+# This time, we drop the explicit 'b' root by downgrading it to v0.1.0
+# (the version required by a.1) and running 'go mod tidy'.
+# It is still selected at v0.1.0 (as a dependency of a),
+# but its dependency on c is now pruned from the module graph, so it doesn't
+# result in any downgrades to b or a if we run 'go get c@none'.
+
+cp go.mod.orig go.mod
+go mod edit -go=1.17
+
+go list -m all
+stdout '^example.com/a v0.1.0 '
+stdout '^example.com/b v0.3.0 '
+stdout '^example.com/c v0.2.0 '
+
+go get -d example.com/c@v0.1.0 example.com/b@v0.1.0
+go list -m all
+stdout '^example.com/a v0.1.0 '
+stdout '^example.com/b v0.1.0 '
+stdout '^example.com/c v0.1.0 '
+
+go mod tidy
+go list -m all
+stdout '^example.com/a v0.1.0 '
+stdout '^example.com/b v0.1.0 '
+! stdout '^example.com/c '
+
+go get -d example.com/c@none
+go list -m all
+stdout '^example.com/a v0.1.0'
+stdout '^example.com/b v0.1.0'
+! stdout '^example.com/c '
+
+
 -- go.mod --
 module example.com/lazy
 
@@ -91,7 +129,7 @@
 -- a/go.mod --
 module example.com/a
 
-go 1.15
+go 1.17
 
 require example.com/b v0.1.0
 -- a/a.go --
@@ -104,7 +142,7 @@
 -- b1/go.mod --
 module example.com/b
 
-go 1.15
+go 1.17
 
 require example.com/c v0.1.0
 -- b1/b.go --
@@ -116,7 +154,7 @@
 -- b2/go.mod --
 module example.com/b
 
-go 1.15
+go 1.17
 
 require example.com/c v0.1.0
 -- b2/b.go --
@@ -128,7 +166,7 @@
 -- b3/go.mod --
 module example.com/b
 
-go 1.15
+go 1.17
 
 require example.com/c v0.2.0
 -- b3/b.go --
@@ -140,6 +178,6 @@
 -- c/go.mod --
 module example.com/c
 
-go 1.15
+go 1.17
 -- c/c.go --
 package c
diff --git a/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt b/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt
index 4ad8cbf..97718c4 100644
--- a/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt
+++ b/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt
@@ -53,8 +53,8 @@
 
 cp m.go.orig m.go
 cp go.mod.orig go.mod
-go mod edit -go=1.16
-go mod edit -go=1.16 go.mod.new
+go mod edit -go=1.17
+go mod edit -go=1.17 go.mod.new
 
 cp go.mod go.mod.orig
 go mod tidy
@@ -63,14 +63,15 @@
 go list -m all
 stdout '^a v0.1.0 '
 stdout '^b v0.1.0 '
-stdout '^c v0.1.0 '  # TODO(#36460): This should be pruned out.
+! stdout '^c '
 
-# After adding a new import of b/y,
-# the import of c from b/y should again resolve to the version required by b.
+# After adding a new direct import of b/y,
+# the existing verison of b should be promoted to a root,
+# bringing the version of c required by b into the build list.
 
 cp m.go.new m.go
 go mod tidy
-cmp go.mod.new go.mod
+cmp go.mod.lazy go.mod
 
 go list -m all
 stdout '^a v0.1.0 '
@@ -130,10 +131,28 @@
 	c v0.1.0 => ./c1
 	c v0.2.0 => ./c2
 )
+-- go.mod.lazy --
+module m
+
+go 1.17
+
+require (
+	a v0.1.0
+	b v0.1.0
+)
+
+require c v0.1.0 // indirect
+
+replace (
+	a v0.1.0 => ./a1
+	b v0.1.0 => ./b1
+	c v0.1.0 => ./c1
+	c v0.2.0 => ./c2
+)
 -- a1/go.mod --
 module a
 
-go 1.16
+go 1.17
 
 require b v0.1.0
 -- a1/a.go --
@@ -145,7 +164,7 @@
 -- b1/go.mod --
 module b
 
-go 1.16
+go 1.17
 
 require c v0.1.0
 -- b1/x/x.go --
@@ -161,7 +180,7 @@
 -- c1/go.mod --
 module c
 
-go 1.16
+go 1.17
 -- c1/c.go --
 package c
 
diff --git a/src/cmd/go/testdata/script/mod_lazy_new_import.txt b/src/cmd/go/testdata/script/mod_lazy_new_import.txt
index 02935bf..4272a52 100644
--- a/src/cmd/go/testdata/script/mod_lazy_new_import.txt
+++ b/src/cmd/go/testdata/script/mod_lazy_new_import.txt
@@ -5,7 +5,7 @@
 #
 # lazy ---- a/x ---- b
 #     \
-#      ---- a/y ---- c
+#      ---- a/y (new) ---- c
 #
 # Where a/x and x/y are disjoint packages, but both contained in module a.
 #
@@ -32,17 +32,32 @@
 cp lazy.go.new lazy.go
 go list all
 go list -m all
-stdout '^example.com/c v0.1.0' # not v0.2.0 as would be be resolved by 'latest'
+stdout '^example.com/c v0.1.0' # not v0.2.0 as would be resolved by 'latest'
 cmp go.mod go.mod.old
 
-# TODO(#36460):
+# Now, we repeat the test with a lazy main module.
 cp lazy.go.old lazy.go
-cp go.mod.old go.mod
-go mod edit -go=1.16
+cp go.mod.117 go.mod
+
+# Before adding a new import, the go.mod file should
+# enumerate modules for all packages already imported.
+go list all
+cmp go.mod go.mod.117
 
 # When a new import is found, we should perform a deepening scan of the existing
 # dependencies and add a requirement on the version required by those
 # dependencies — not re-resolve 'latest'.
+cp lazy.go.new lazy.go
+
+! go list all
+stderr '^go: updates to go.mod needed; to update it:\n\tgo mod tidy$'
+
+go mod tidy
+go list all
+go list -m all
+stdout '^example.com/c v0.1.0' # not v0.2.0 as would be resolved by 'latest'
+
+cmp go.mod go.mod.new
 
 
 -- go.mod --
@@ -58,6 +73,39 @@
 	example.com/c v0.1.0 => ./c1
 	example.com/c v0.2.0 => ./c2
 )
+-- go.mod.117 --
+module example.com/lazy
+
+go 1.17
+
+require example.com/a v0.1.0
+
+require example.com/b v0.1.0 // indirect
+
+replace (
+	example.com/a v0.1.0 => ./a
+	example.com/b v0.1.0 => ./b
+	example.com/c v0.1.0 => ./c1
+	example.com/c v0.2.0 => ./c2
+)
+-- go.mod.new --
+module example.com/lazy
+
+go 1.17
+
+require example.com/a v0.1.0
+
+require (
+	example.com/b v0.1.0 // indirect
+	example.com/c v0.1.0 // indirect
+)
+
+replace (
+	example.com/a v0.1.0 => ./a
+	example.com/b v0.1.0 => ./b
+	example.com/c v0.1.0 => ./c1
+	example.com/c v0.2.0 => ./c2
+)
 -- lazy.go --
 package lazy
 
diff --git a/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt b/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt
index 9cdfad7..7d07eb6 100644
--- a/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt
+++ b/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt
@@ -32,12 +32,12 @@
 # but the irrelevant dependency on c v0.2.0 should be pruned out,
 # leaving only the relevant dependency on c v0.1.0.
 
-go mod edit -go=1.16
+go mod edit -go=1.17
 go list -m c
-stdout '^c v0.2.0'  # TODO(#36460): v0.1.0
+stdout '^c v0.1.0'
 
 [!short] go test -v x
-[!short] stdout ' c v0.2.0$'  # TODO(#36460): v0.1.0
+[!short] stdout ' c v0.1.0$'
 
 -- m.go --
 package m
@@ -66,7 +66,7 @@
 -- a1/go.mod --
 module a
 
-go 1.16
+go 1.17
 
 require b v0.1.0
 -- a1/a.go --
@@ -78,7 +78,7 @@
 -- b1/go.mod --
 module b
 
-go 1.16
+go 1.17
 
 require c v0.2.0
 -- b1/b.go --
@@ -97,7 +97,7 @@
 -- c1/go.mod --
 module c
 
-go 1.16
+go 1.17
 -- c1/c.go --
 package c
 
@@ -105,7 +105,7 @@
 -- c2/go.mod --
 module c
 
-go 1.16
+go 1.17
 -- c2/c.go --
 package c
 
@@ -113,7 +113,7 @@
 -- x1/go.mod --
 module x
 
-go 1.16
+go 1.17
 
 require c v0.1.0
 -- x1/x.go --
diff --git a/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt b/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt
index ca6c550..68a5b6d 100644
--- a/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt
+++ b/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt
@@ -21,12 +21,13 @@
 go mod tidy
 cmp go.mod go.mod.old
 
+
 # In Go 1.15 mode, 'go list -m all' includes modules needed by the
 # transitive closure of tests of dependencies of tests of dependencies of ….
 
 go list -m all
-stdout 'example.com/b v0.1.0'
-stdout 'example.com/c v0.1.0'
+stdout '^example.com/b v0.1.0 '
+stdout '^example.com/c v0.1.0 '
 cmp go.mod go.mod.old
 
 # 'go test' (or equivalent) of any such dependency, no matter how remote, does
@@ -36,18 +37,24 @@
 stdout example.com/b
 ! stdout example.com/c
 
-[!short] go test -c example.com/a
+[!short] go test -c -o $devnull example.com/a
 [!short] cmp go.mod go.mod.old
 
 go list -test -deps example.com/b
 stdout example.com/c
 
-[!short] go test -c example.com/b
+[!short] go test -c -o $devnull example.com/b
 [!short] cmp go.mod go.mod.old
 
-# TODO(#36460):
+go mod edit -go=1.17 a/go.mod
+go mod edit -go=1.17 b1/go.mod
+go mod edit -go=1.17 b2/go.mod
+go mod edit -go=1.17 c1/go.mod
+go mod edit -go=1.17 c2/go.mod
+go mod edit -go=1.17
 
-# After changing to 'go 1.16` uniformly, 'go list -m all' should prune out
+
+# After changing to 'go 1.17` uniformly, 'go list -m all' should prune out
 # example.com/c, because it is not imported by any package (or test of a package)
 # transitively imported by the main module.
 #
@@ -62,10 +69,66 @@
 # version of its module.
 
 # However, if we reach c by running successive tests starting from the main
-# module, we should end up with exactly the version require by c, with an update
+# module, we should end up with exactly the version required by b, with an update
 # to the go.mod file as soon as we test a test dependency that is not itself in
 # "all".
 
+cp go.mod go.mod.117
+go mod tidy
+cmp go.mod go.mod.117
+
+go list -m all
+stdout '^example.com/b v0.1.0 '
+! stdout '^example.com/c '
+
+# 'go test' of a package (transitively) imported by the main module
+# should work without changes to the go.mod file.
+
+go list -test -deps example.com/a
+stdout example.com/b
+! stdout example.com/c
+
+[!short] go test -c -o $devnull example.com/a
+
+# However, 'go test' of a package that is itself a dependency should require an
+# update to the go.mod file.
+! go list -test -deps example.com/b
+
+	# TODO(#36460): The hint here is wrong. We should suggest
+	# 'go get -t example.com/b@v0.1.0' instead of 'go mod tidy'.
+stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$'
+
+[!short] ! go test -c -o $devnull example.com/b
+[!short] stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$'
+
+go get -t example.com/b@v0.1.0
+go list -test -deps example.com/b
+stdout example.com/c
+
+[!short] go test -c -o $devnull example.com/b
+
+# The update should bring the version required by b, not the latest version of c.
+
+go list -m example.com/c
+stdout '^example.com/c v0.1.0 '
+
+cmp go.mod go.mod.b
+
+
+# We should reach the same state if we arrive at it via `go test -mod=mod`.
+
+cp go.mod.117 go.mod
+
+[short] go list -mod=mod -test -deps example.com/a
+[!short] go test -mod=mod -c -o $devnull example.com/a
+
+[short] go list -mod=mod -test -deps example.com/b
+[!short] go test -mod=mod -c -o $devnull example.com/b
+
+cmp go.mod go.mod.b
+
+
+
 -- go.mod --
 module example.com/lazy
 
@@ -80,6 +143,22 @@
 	example.com/c v0.1.0 => ./c1
 	example.com/c v0.2.0 => ./c2
 )
+-- go.mod.b --
+module example.com/lazy
+
+go 1.17
+
+require example.com/a v0.1.0
+
+require example.com/b v0.1.0 // indirect
+
+replace (
+	example.com/a v0.1.0 => ./a
+	example.com/b v0.1.0 => ./b1
+	example.com/b v0.2.0 => ./b2
+	example.com/c v0.1.0 => ./c1
+	example.com/c v0.2.0 => ./c2
+)
 -- lazy.go --
 package lazy
 
diff --git a/src/cmd/go/testdata/script/mod_list.txt b/src/cmd/go/testdata/script/mod_list.txt
index 1ba6d7c..239c7ca 100644
--- a/src/cmd/go/testdata/script/mod_list.txt
+++ b/src/cmd/go/testdata/script/mod_list.txt
@@ -29,7 +29,8 @@
 go list std
 stdout ^math/big
 
-# rsc.io/quote/buggy should be listable as a package
+# rsc.io/quote/buggy should be listable as a package,
+# even though it is only a test.
 go list -mod=mod rsc.io/quote/buggy
 
 # rsc.io/quote/buggy should not be listable as a module
diff --git a/src/cmd/go/testdata/script/mod_list_deprecated.txt b/src/cmd/go/testdata/script/mod_list_deprecated.txt
new file mode 100644
index 0000000..f0ecbba
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_list_deprecated.txt
@@ -0,0 +1,52 @@
+# 'go list pkg' does not show deprecation.
+go list example.com/deprecated/a
+stdout '^example.com/deprecated/a$'
+
+# 'go list -m' does not show deprecation.
+go list -m example.com/deprecated/a
+stdout '^example.com/deprecated/a v1.9.0$'
+
+# 'go list -m -versions' does not show deprecation.
+go list -m -versions example.com/deprecated/a
+stdout '^example.com/deprecated/a v1.0.0 v1.9.0$'
+
+# 'go list -m -u' shows deprecation.
+go list -m -u example.com/deprecated/a
+stdout '^example.com/deprecated/a v1.9.0 \(deprecated\)$'
+
+# 'go list -m -u -f' exposes the deprecation message.
+go list -m -u -f {{.Deprecated}} example.com/deprecated/a
+stdout '^in example.com/deprecated/a@v1.9.0$'
+
+# This works even if we use an old version that does not have the deprecation
+# message in its go.mod file.
+go get -d example.com/deprecated/a@v1.0.0
+! grep Deprecated: $WORK/gopath/pkg/mod/cache/download/example.com/deprecated/a/@v/v1.0.0.mod
+go list -m -u -f {{.Deprecated}} example.com/deprecated/a
+stdout '^in example.com/deprecated/a@v1.9.0$'
+
+# 'go list -m -u' does not show deprecation for the main module.
+go list -m -u
+! stdout deprecated
+go list -m -u -f '{{if not .Deprecated}}ok{{end}}'
+stdout ok
+
+# 'go list -m -u' does not show a deprecation message for a module that is not
+# deprecated at the latest version, even if it is deprecated at the current
+# version.
+go list -m -u example.com/undeprecated
+stdout '^example.com/undeprecated v1.0.0 \[v1.0.1\]$'
+-- go.mod --
+// Deprecated: main module is deprecated, too!
+module example.com/use
+
+go 1.17
+
+require (
+	example.com/deprecated/a v1.9.0
+	example.com/undeprecated v1.0.0
+)
+-- go.sum --
+example.com/deprecated/a v1.9.0 h1:pRyvBIZheJpQVVnNW4Fdg8QuoqDgtkCreqZZbASV3BE=
+example.com/deprecated/a v1.9.0/go.mod h1:Z1uUVshSY9kh6l/2hZ8oA9SBviX2yfaeEpcLDz6AZwY=
+example.com/undeprecated v1.0.0/go.mod h1:1qiRbdA9VzJXDqlG26Y41O5Z7YyO+jAD9do8XCZQ+Gg=
diff --git a/src/cmd/go/testdata/script/mod_list_deprecated_replace.txt b/src/cmd/go/testdata/script/mod_list_deprecated_replace.txt
new file mode 100644
index 0000000..48b991f
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_list_deprecated_replace.txt
@@ -0,0 +1,68 @@
+# When all versions are replaced, we should not look up a deprecation message.
+# We will still look up a deprecation message for the replacement.
+cp go.mod.allreplaced go.mod
+go list -m -u -f '{{.Path}}@{{.Version}} <{{.Deprecated}}>{{with .Replace}} => {{.Path}}@{{.Version}} <{{.Deprecated}}>{{end}}' all
+stdout '^example.com/deprecated/a@v1.0.0 <> => example.com/deprecated/b@v1.0.0 <in example.com/deprecated/b@v1.9.0>$'
+
+# When one version is replaced, we should see a deprecation message.
+cp go.mod.onereplaced go.mod
+go list -m -u -f '{{.Path}}@{{.Version}} <{{.Deprecated}}>{{with .Replace}} => {{.Path}}@{{.Version}} <{{.Deprecated}}>{{end}}' all
+stdout '^example.com/deprecated/a@v1.0.0 <in example.com/deprecated/a@v1.9.0> => example.com/deprecated/b@v1.0.0 <in example.com/deprecated/b@v1.9.0>$'
+
+# If the replacement is a directory, we won't look that up.
+cp go.mod.dirreplacement go.mod
+go list -m -u -f '{{.Path}}@{{.Version}} <{{.Deprecated}}>{{with .Replace}} => {{.Path}}@{{.Version}} <{{.Deprecated}}>{{end}}' all
+stdout '^example.com/deprecated/a@v1.0.0 <> => ./a@ <>$'
+
+# If the latest version of the replacement is replaced, we'll use the content
+# from that replacement.
+cp go.mod.latestreplaced go.mod
+go list -m -u -f '{{.Path}}@{{.Version}} <{{.Deprecated}}>{{with .Replace}} => {{.Path}}@{{.Version}} <{{.Deprecated}}>{{end}}' all
+stdout '^example.com/deprecated/a@v1.0.0 <> => example.com/deprecated/b@v1.0.0 <in ./b>$'
+
+-- go.mod.allreplaced --
+module m
+
+go 1.17
+
+require example.com/deprecated/a v1.0.0
+
+replace example.com/deprecated/a => example.com/deprecated/b v1.0.0
+-- go.mod.onereplaced --
+module m
+
+go 1.17
+
+require example.com/deprecated/a v1.0.0
+
+replace example.com/deprecated/a v1.0.0 => example.com/deprecated/b v1.0.0
+-- go.mod.dirreplacement --
+module m
+
+go 1.17
+
+require example.com/deprecated/a v1.0.0
+
+replace example.com/deprecated/a => ./a
+-- go.mod.latestreplaced --
+module m
+
+go 1.17
+
+require example.com/deprecated/a v1.0.0
+
+replace (
+	example.com/deprecated/a => example.com/deprecated/b v1.0.0
+	example.com/deprecated/b v1.9.0 => ./b
+)
+-- go.sum --
+example.com/deprecated/b v1.0.0/go.mod h1:b19J9ywRGviY7Nq4aJ1WBJ+A7qUlEY9ihp22yI4/F6M=
+-- a/go.mod --
+module example.com/deprecated/a
+
+go 1.17
+-- b/go.mod --
+// Deprecated: in ./b
+module example.com/deprecated/b
+
+go 1.17
diff --git a/src/cmd/go/testdata/script/mod_list_retract.txt b/src/cmd/go/testdata/script/mod_list_retract.txt
index 3ba53bc..4b13348 100644
--- a/src/cmd/go/testdata/script/mod_list_retract.txt
+++ b/src/cmd/go/testdata/script/mod_list_retract.txt
@@ -29,12 +29,12 @@
 go list -m -f '{{with .Retracted}}retracted{{end}}' example.com/retract@v1.0.0-unused
 ! stdout .
 
-# 'go list -m -retracted mod@version' shows an error if the go.mod that should
-# contain the retractions is not available.
-! go list -m -retracted example.com/retract/missingmod@v1.0.0
-stderr '^go list -m: loading module retractions for example.com/retract/missingmod@v1.0.0: .*404 Not Found$'
-go list -e -m -retracted -f '{{.Error.Err}}' example.com/retract/missingmod@v1.0.0
-stdout '^loading module retractions for example.com/retract/missingmod@v1.0.0: .*404 Not Found$'
+# 'go list -m -retracted mod@version' does not show an error if the module
+# that would contain the retraction is unavailable. See #45305.
+go list -m -retracted -f '{{.Path}} {{.Version}} {{.Error}}' example.com/retract/missingmod@v1.0.0
+stdout '^example.com/retract/missingmod v1.0.0 <nil>$'
+exists $GOPATH/pkg/mod/cache/download/example.com/retract/missingmod/@v/v1.9.0.info
+! exists $GOPATH/pkg/mod/cache/download/example.com/retract/missingmod/@v/v1.9.0.mod
 
 # 'go list -m -retracted mod@version' shows retractions.
 go list -m -retracted example.com/retract@v1.0.0-unused
diff --git a/src/cmd/go/testdata/script/mod_list_std.txt b/src/cmd/go/testdata/script/mod_list_std.txt
index baf7908..f4e0433 100644
--- a/src/cmd/go/testdata/script/mod_list_std.txt
+++ b/src/cmd/go/testdata/script/mod_list_std.txt
@@ -48,18 +48,20 @@
 ! stdout ^golang\.org/x
 
 # Within the std module, the dependencies of the non-vendored packages within
-# std should appear to come from modules, but they should be loaded from the
-# vendor directory (just like ordinary vendored module dependencies).
+# std should appear to be packages beginning with 'vendor/', not 'golang.org/…'
+# module dependencies.
 
 go list all
-stdout ^golang.org/x/
+! stdout ^golang.org/x/
 ! stdout ^std/
 ! stdout ^cmd/
-! stdout ^vendor/
+stdout ^vendor/
 
 go list -deps -f '{{if not .Standard}}{{.ImportPath}}{{end}}' std
-! stdout ^vendor/golang.org/x/net/http2/hpack
-stdout ^golang.org/x/net/http2/hpack
+! stdout .
+
+# However, the 'golang.org/…' module dependencies should resolve to those same
+# directories.
 
 go list -f '{{.Dir}}' golang.org/x/net/http2/hpack
 stdout $GOROOT[/\\]src[/\\]vendor
diff --git a/src/cmd/go/testdata/script/mod_list_sums.txt b/src/cmd/go/testdata/script/mod_list_sums.txt
new file mode 100644
index 0000000..86c528f
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_list_sums.txt
@@ -0,0 +1,32 @@
+# https://golang.org/issue/41297: 'go list -m' should not require go.sum with
+# -versions or when all args are version queries.
+
+go mod init m
+go mod edit -require=rsc.io/quote@v1.5.1
+
+go list -m -mod=readonly rsc.io/quote@latest
+stdout '^rsc\.io/quote v1\.5\.2$'
+! stderr .
+
+go list -m -mod=readonly -versions rsc.io/quote
+stdout 'rsc\.io/quote v1\.0\.0 .* v1\.5\.3-pre1$'
+! stderr .
+
+# Incidentally fetching the required version of a module records its checksum,
+# just because it happens to be in the build list, and recording the checksum
+# triggers an error under -mod=readonly.
+#
+# TODO(#41297): This should not be an error.
+! go list -m -mod=readonly rsc.io/quote@<v1.5.2
+stderr '^go: updates to go.sum needed, disabled by -mod=readonly$'
+! stderr 'missing go.sum entry'
+
+# Attempting to list the versions of a module that is not a root dependency
+# causes the build list to be resolved (so that the selected version can *also*
+# be identified, even though it is not relevant to this particular output).
+# That, in turn, causes us to need checksums for the go.sum files for the
+# modules in the module graph.
+#
+# TODO(#41297): This should not be an error either.
+! go list -m -mod=readonly -versions rsc.io/sampler
+stderr '^go list -m: rsc\.io/quote@v1\.5\.1: missing go\.sum entry; to add it:\n\tgo mod download rsc\.io/quote$'
diff --git a/src/cmd/go/testdata/script/mod_list_test_cycle.txt b/src/cmd/go/testdata/script/mod_list_test_cycle.txt
new file mode 100644
index 0000000..755e50b
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_list_test_cycle.txt
@@ -0,0 +1,23 @@
+# https://golang.org/issue/45863: a typo in a test package leading to an
+# import cycle should be diagnosed, instead of causing an infinite loop.
+# The failure mode of this test prior to the fix was a timeout or OOM crash.
+
+go list -e -test -deps ./datastore/sql
+
+-- go.mod --
+module golang.org/issue45863
+
+go 1.17
+-- datastore/datastore_health.go --
+package datastore
+
+import (
+	"golang.org/issue45863/datastore"
+	"golang.org/issue45863/datastore/sql"
+)
+-- datastore/sql/sql.go --
+package sql
+-- datastore/sql/sql_test.go --
+package sql
+
+import _ "golang.org/issue45863/datastore"
diff --git a/src/cmd/go/testdata/script/mod_list_update_nolatest.txt b/src/cmd/go/testdata/script/mod_list_update_nolatest.txt
new file mode 100644
index 0000000..c6bbbb0
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_list_update_nolatest.txt
@@ -0,0 +1,55 @@
+# Check that if a proxy does not have a version of a module that could be
+# an upgrade, 'go list -m -u' still succeeds.
+# We use a local file proxy, since our test proxy doesn't have the behavior
+# we want to test, and we don't want it to be too clever.
+# Verifies #45305, where proxy.golang.org serves an empty /@v/list (200)
+# but has no /@latest (410) because the go.mod at the tip of the default
+# branch has a different major version suffix.
+env testproxy=$GOPROXY
+env GOPROXY=file:///$WORK/proxy
+env GOSUMDB=off
+
+# If the proxy does not return a list of versions (404/410)
+# or a latest version (404/410), we should see no error.
+go list -m example.com/noversion
+stdout '^example.com/noversion v0.0.0$'
+go list -m -u example.com/noversion
+stdout '^example.com/noversion v0.0.0$'
+
+# If the proxy returns an empty list of versions (200, not 404/410)
+# but does not have a latest version (404/410), we should see no error.
+go list -m example.com/nolatest
+stdout '^example.com/nolatest v0.0.0$'
+go list -m -u example.com/nolatest
+stdout '^example.com/nolatest v0.0.0$'
+
+# If proxy returns an invalid response, we should see an error.
+env GOPROXY=$testproxy/invalid
+! go list -m -u example.com/nolatest
+stderr '^go list -m: loading module retractions for example.com/nolatest@v0.0.0: invalid response from proxy "[^"]*": invalid character ''i'' looking for beginning of value$'
+
+-- go.mod --
+module m
+
+go 1.17
+
+require (
+	example.com/nolatest v0.0.0
+	example.com/noversion v0.0.0
+)
+-- go.sum --
+example.com/nolatest v0.0.0/go.mod h1:HnLrCt6SJga5tCtJ7IzG9dOOCniY3G5C0VT7jfMdS0M=
+example.com/noversion v0.0.0/go.mod h1:2RUfWiCYsygSXPM2Igxx0FD3Kq33OnVdxm34eDDhXbQ=
+-- $WORK/proxy/example.com/nolatest/@v/list --
+-- $WORK/proxy/example.com/nolatest/@v/v0.0.0.info --
+{"Version":"v0.0.0"}
+-- $WORK/proxy/example.com/nolatest/@v/v0.0.0.mod --
+module example.com/nolatest
+
+go 1.17
+-- $WORK/proxy/example.com/noversion/@v/v0.0.0.info --
+{"Version":"v0.0.0"}
+-- $WORK/proxy/example.com/noversion/@v/v0.0.0.mod --
+module example.com/noversion
+
+go 1.17
diff --git a/src/cmd/go/testdata/script/mod_load_badchain.txt b/src/cmd/go/testdata/script/mod_load_badchain.txt
index c0c382b..eb464ab 100644
--- a/src/cmd/go/testdata/script/mod_load_badchain.txt
+++ b/src/cmd/go/testdata/script/mod_load_badchain.txt
@@ -22,7 +22,7 @@
 
 # Update manually. Listing modules should produce an error.
 go mod edit -require=example.com/badchain/a@v1.1.0
-! go list -m
+! go list -m all
 cmp stderr list-expected
 
 # Try listing a package that imports a package
@@ -69,19 +69,17 @@
 
 func Test(t *testing.T) {}
 -- update-main-expected --
-go get: example.com/badchain/c@v1.0.0 updating to
-	example.com/badchain/c@v1.1.0: parsing go.mod:
+go get: example.com/badchain/c@v1.1.0: parsing go.mod:
 	module declares its path as: badchain.example.com/c
 	        but was required as: example.com/badchain/c
 -- update-a-expected --
-go get: example.com/badchain/a@v1.0.0 updating to
-	example.com/badchain/a@v1.1.0 requires
+go get: example.com/badchain/a@v1.1.0 requires
 	example.com/badchain/b@v1.1.0 requires
 	example.com/badchain/c@v1.1.0: parsing go.mod:
 	module declares its path as: badchain.example.com/c
 	        but was required as: example.com/badchain/c
 -- list-expected --
-go: example.com/badchain/a@v1.1.0 requires
+go list -m: example.com/badchain/a@v1.1.0 requires
 	example.com/badchain/b@v1.1.0 requires
 	example.com/badchain/c@v1.1.0: parsing go.mod:
 	module declares its path as: badchain.example.com/c
diff --git a/src/cmd/go/testdata/script/mod_outside.txt b/src/cmd/go/testdata/script/mod_outside.txt
index 5655892..33341f7 100644
--- a/src/cmd/go/testdata/script/mod_outside.txt
+++ b/src/cmd/go/testdata/script/mod_outside.txt
@@ -61,6 +61,11 @@
 stderr 'go: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$'
 ! stdout 'example.com/version'
 
+# 'go list -m <mods>' should fail if any of the mods lacks an explicit version.
+! go list -m example.com/printversion
+stderr 'go: cannot match "example.com/printversion" without -versions or an explicit version: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
+! stdout 'example.com/version'
+
 # 'go list -m' with wildcards should fail. Wildcards match modules in the
 # build list, so they aren't meaningful outside a module.
 ! go list -m ...
@@ -164,6 +169,8 @@
 # 'go build' should succeed for standard-library packages.
 go build -n fmt
 
+# 'go build' should use the latest version of the Go language.
+go build ./newgo/newgo.go
 
 # 'go doc' without arguments implicitly operates on the current directory, and should fail.
 # TODO(golang.org/issue/32027): currently, it succeeds.
@@ -200,10 +207,6 @@
 go install cmd/addr2line
 ! stderr .
 
-# 'go run' with a verison should fail due to syntax.
-! go run example.com/printversion@v1.0.0
-stderr 'can only use path@version syntax with'
-
 # 'go run' should fail if a package argument must be resolved to a module.
 ! go run example.com/printversion
 stderr '^no required module provides package example.com/printversion: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
@@ -326,3 +329,15 @@
 	fmt.Println("stdonly was tested")
 }
 
+-- newgo/newgo.go --
+// Package newgo requires Go 1.14 or newer.
+package newgo
+
+import "io"
+
+const C = 299_792_458
+
+type ReadWriteCloser interface {
+	io.ReadCloser
+	io.WriteCloser
+}
diff --git a/src/cmd/go/testdata/script/mod_overlay.txt b/src/cmd/go/testdata/script/mod_overlay.txt
index 92e79c7..86ab04b 100644
--- a/src/cmd/go/testdata/script/mod_overlay.txt
+++ b/src/cmd/go/testdata/script/mod_overlay.txt
@@ -21,7 +21,7 @@
 cd $WORK/gopath/src/get-doesnt-add-dep
 cp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod
 ! go get -d -overlay overlay.json .
-stderr 'overlaid files can''t be opened for write'
+stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
 cmp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod
 
 # Content of overlaid go.sum is used.
@@ -41,10 +41,10 @@
 # attempting to update the file
 cp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
 ! go get -d -overlay overlay.json .
-stderr 'overlaid files can''t be opened for write'
+stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$'
 cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
 ! go mod tidy -overlay overlay.json
-stderr 'overlaid files can''t be opened for write'
+stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$'
 cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
 
 # -overlay works with -modfile.
@@ -56,7 +56,7 @@
 stdout 'found.the/module'
 # Even with -modfile, overlaid files can't be opened for write.
 ! go get -modfile=alternate.mod -overlay overlay.json -d rsc.io/quote
-stderr 'overlaid files can''t be opened for write'
+stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
 
 # Carving out a module by adding an overlaid go.mod file
 cd $WORK/gopath/src/carve
@@ -78,7 +78,7 @@
 stdout ^carve2/nomod$
 # Editing go.mod file fails because overlay is read only
 ! go get -overlay overlay.json -d rsc.io/quote
-stderr 'overlaid files can''t be opened for write'
+stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
 ! grep rsc.io/quote $WORK/overlay/carve2-nomod-go.mod
 # Editing go.mod file succeeds because we use -modfile to redirect to same file
 go get -overlay overlay.json -modfile $WORK/overlay/carve2-nomod-go.mod -d rsc.io/quote
diff --git a/src/cmd/go/testdata/script/mod_prefer_compatible.txt b/src/cmd/go/testdata/script/mod_prefer_compatible.txt
index aa6260f..1b408c3 100644
--- a/src/cmd/go/testdata/script/mod_prefer_compatible.txt
+++ b/src/cmd/go/testdata/script/mod_prefer_compatible.txt
@@ -23,8 +23,8 @@
 go list -m github.com/russross/blackfriday@upgrade
 stdout '^github.com/russross/blackfriday v1\.'
 
-go list -m github.com/russross/blackfriday@patch
-stdout '^github.com/russross/blackfriday v1\.'
+! go list -m github.com/russross/blackfriday@patch
+stderr '^go list -m: github.com/russross/blackfriday@patch: can''t query version "patch" of module github.com/russross/blackfriday: no existing version is required$'
 
 # If we're fetching directly from version control, ignored +incompatible
 # versions should also be omitted by 'go list'.
diff --git a/src/cmd/go/testdata/script/mod_proxy_https.txt b/src/cmd/go/testdata/script/mod_proxy_https.txt
index a23090c..a5e28dd 100644
--- a/src/cmd/go/testdata/script/mod_proxy_https.txt
+++ b/src/cmd/go/testdata/script/mod_proxy_https.txt
@@ -10,6 +10,7 @@
 # GOPROXY HTTPS paths may elide the "https://" prefix.
 # (See golang.org/issue/32191.)
 env GOPROXY=proxy.golang.org
+env GOSUMDB=
 go list -versions -m golang.org/x/text
 
 -- go.mod --
diff --git a/src/cmd/go/testdata/script/mod_query.txt b/src/cmd/go/testdata/script/mod_query.txt
index e101857..a75f86e 100644
--- a/src/cmd/go/testdata/script/mod_query.txt
+++ b/src/cmd/go/testdata/script/mod_query.txt
@@ -1,9 +1,7 @@
 env GO111MODULE=on
 
-# Populate go.sum.
 # TODO(golang.org/issue/41297): we shouldn't need go.sum. None of the commands
 # below depend on the build list.
-go mod download
 
 go list -m -versions rsc.io/quote
 stdout '^rsc.io/quote v1.0.0 v1.1.0 v1.2.0 v1.2.1 v1.3.0 v1.4.0 v1.5.0 v1.5.1 v1.5.2 v1.5.3-pre1$'
@@ -36,6 +34,9 @@
 module x
 require rsc.io/quote v1.0.0
 
+-- go.sum --
+rsc.io/quote v1.0.0 h1:kQ3IZQzPTiDJxSZI98YaWgxFEhlNdYASHvh+MplbViw=
+rsc.io/quote v1.0.0/go.mod h1:v83Ri/njykPcgJltBc/gEkJTmjTsNgtO1Y7vyIK1CQA=
 -- use.go --
 package use
 
diff --git a/src/cmd/go/testdata/script/mod_readonly.txt b/src/cmd/go/testdata/script/mod_readonly.txt
index 176be72..d05ad2a 100644
--- a/src/cmd/go/testdata/script/mod_readonly.txt
+++ b/src/cmd/go/testdata/script/mod_readonly.txt
@@ -89,7 +89,7 @@
 -- go.mod --
 module m
 
-go 1.20
+go 1.16
 
 -- x.go --
 package x
@@ -104,7 +104,7 @@
 -- go.mod.redundant --
 module m
 
-go 1.20
+go 1.16
 
 require (
 	rsc.io/quote v1.5.2
@@ -114,7 +114,7 @@
 -- go.mod.indirect --
 module m
 
-go 1.20
+go 1.16
 
 require (
 	rsc.io/quote v1.5.2 // indirect
@@ -124,7 +124,7 @@
 -- go.mod.untidy --
 module m
 
-go 1.20
+go 1.16
 
 require (
 	rsc.io/sampler v1.3.0 // indirect
diff --git a/src/cmd/go/testdata/script/mod_replace.txt b/src/cmd/go/testdata/script/mod_replace.txt
index dc9667f..a0a367f 100644
--- a/src/cmd/go/testdata/script/mod_replace.txt
+++ b/src/cmd/go/testdata/script/mod_replace.txt
@@ -48,7 +48,7 @@
 # The reported Dir and GoMod for a replaced module should be accurate.
 cp go.mod.orig go.mod
 go mod edit -replace=rsc.io/quote/v3=not-rsc.io/quote@v0.1.0-nomod
-go mod download
+go mod download rsc.io/quote/v3
 go list -m -f '{{.Path}} {{.Version}} {{.Dir}} {{.GoMod}}{{with .Replace}} => {{.Path}} {{.Version}} {{.Dir}} {{.GoMod}}{{end}}' rsc.io/quote/v3
 stdout '^rsc.io/quote/v3 v3.0.0 '$GOPATH'[/\\]pkg[/\\]mod[/\\]not-rsc.io[/\\]quote@v0.1.0-nomod '$GOPATH'[/\\]pkg[/\\]mod[/\\]cache[/\\]download[/\\]not-rsc.io[/\\]quote[/\\]@v[/\\]v0.1.0-nomod.mod => not-rsc.io/quote v0.1.0-nomod '$GOPATH'[/\\]pkg[/\\]mod[/\\]not-rsc.io[/\\]quote@v0.1.0-nomod '$GOPATH'[/\\]pkg[/\\]mod[/\\]cache[/\\]download[/\\]not-rsc.io[/\\]quote[/\\]@v[/\\]v0.1.0-nomod.mod$'
 
diff --git a/src/cmd/go/testdata/script/mod_replace_gopkgin.txt b/src/cmd/go/testdata/script/mod_replace_gopkgin.txt
index df752d9..d24f37b 100644
--- a/src/cmd/go/testdata/script/mod_replace_gopkgin.txt
+++ b/src/cmd/go/testdata/script/mod_replace_gopkgin.txt
@@ -35,7 +35,7 @@
 # A mismatched gopkg.in path should not be able to replace a different major version.
 cd ../3-to-gomod-4
 ! go list -m gopkg.in/src-d/go-git.v3
-stderr '^go: gopkg\.in/src-d/go-git\.v3@v3\.2\.0 \(replaced by gopkg\.in/src-d/go-git\.v3@v3\.0\.0-20190801152248-0d1a009cbb60\): version "v3\.0\.0-20190801152248-0d1a009cbb60" invalid: go\.mod has non-\.\.\.\.v3 module path "gopkg\.in/src-d/go-git\.v4" at revision 0d1a009cbb60$'
+stderr '^go list -m: gopkg\.in/src-d/go-git\.v3@v3\.2\.0 \(replaced by gopkg\.in/src-d/go-git\.v3@v3\.0\.0-20190801152248-0d1a009cbb60\): version "v3\.0\.0-20190801152248-0d1a009cbb60" invalid: go\.mod has non-\.\.\.\.v3 module path "gopkg\.in/src-d/go-git\.v4" at revision 0d1a009cbb60$'
 
 -- 4-to-4/go.mod --
 module golang.org/issue/34254
diff --git a/src/cmd/go/testdata/script/mod_require_exclude.txt b/src/cmd/go/testdata/script/mod_require_exclude.txt
index 9156d4c..0946dbf 100644
--- a/src/cmd/go/testdata/script/mod_require_exclude.txt
+++ b/src/cmd/go/testdata/script/mod_require_exclude.txt
@@ -7,16 +7,27 @@
 
 ! go list -mod=readonly -m all
 stderr '^go: ignoring requirement on excluded version rsc.io/sampler v1\.99\.99$'
-stderr '^go: updates to go.mod needed, disabled by -mod=readonly$'
+stderr '^go: updates to go.mod needed, disabled by -mod=readonly; to update it:\n\tgo mod tidy$'
 ! stdout '^rsc.io/sampler v1.99.99'
 cmp go.mod go.mod.orig
 
 ! go list -mod=vendor -m rsc.io/sampler
 stderr '^go: ignoring requirement on excluded version rsc.io/sampler v1\.99\.99$'
-stderr '^go list -m: module rsc.io/sampler: can''t resolve module using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass\.\)$'
+stderr '^go: updates to go.mod needed, disabled by -mod=vendor; to update it:\n\tgo mod tidy$'
 ! stdout '^rsc.io/sampler v1.99.99'
 cmp go.mod go.mod.orig
 
+# The failure message should be clear when -mod=vendor is implicit.
+
+go mod edit -go=1.14
+! go list -m rsc.io/sampler
+stderr '^go: ignoring requirement on excluded version rsc.io/sampler v1\.99\.99$'
+stderr '^go: updates to go.mod needed, disabled by -mod=vendor\n\t\(Go version in go.mod is at least 1.14 and vendor directory exists\.\)\n\tto update it:\n\tgo mod tidy$'
+! stdout '^rsc.io/sampler v1.99.99'
+go mod edit -go=1.13
+cmp go.mod go.mod.orig
+
+
 # With the selected version excluded, commands that load only modules should
 # drop the excluded module.
 
@@ -58,7 +69,11 @@
 go 1.13
 
 exclude rsc.io/sampler v1.99.99
+
 require rsc.io/sampler v1.99.99
+-- vendor/modules.txt --
+# rsc.io/sampler v1.99.99
+## explicit
 -- go.moddrop --
 module x
 
diff --git a/src/cmd/go/testdata/script/mod_retention.txt b/src/cmd/go/testdata/script/mod_retention.txt
index a4441c4..7a371b1 100644
--- a/src/cmd/go/testdata/script/mod_retention.txt
+++ b/src/cmd/go/testdata/script/mod_retention.txt
@@ -62,9 +62,10 @@
 
 # A missing "go" version directive should be added.
 # However, that should not remove other redundant requirements.
+# In fact, it may *add* redundant requirements due to activating lazy loading.
 cp go.mod.nogo go.mod
 go list -mod=mod all
-cmpenv go.mod go.mod.currentgo
+cmpenv go.mod go.mod.addedgo
 
 
 -- go.mod.tidy --
@@ -133,7 +134,7 @@
 	rsc.io/sampler v1.3.0 // indirect
 	rsc.io/testonly v1.0.0 // indirect
 )
--- go.mod.currentgo --
+-- go.mod.addedgo --
 module m
 
 go $goversion
@@ -143,3 +144,5 @@
 	rsc.io/sampler v1.3.0 // indirect
 	rsc.io/testonly v1.0.0 // indirect
 )
+
+require golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect
diff --git a/src/cmd/go/testdata/script/mod_retract.txt b/src/cmd/go/testdata/script/mod_retract.txt
index a52e05b..4f95ece 100644
--- a/src/cmd/go/testdata/script/mod_retract.txt
+++ b/src/cmd/go/testdata/script/mod_retract.txt
@@ -1,8 +1,5 @@
 cp go.mod go.mod.orig
 
-# Populate go.sum.
-go mod download
-
 # 'go list pkg' does not report an error when a retracted version is used.
 go list -e -f '{{if .Error}}{{.Error}}{{end}}' ./use
 ! stdout .
@@ -32,6 +29,11 @@
 
 require example.com/retract v1.0.0-bad
 
+-- go.sum --
+example.com/retract v1.0.0-bad h1:liAW69rbtjY67x2CcNzat668L/w+YGgNX3lhJsWIJis=
+example.com/retract v1.0.0-bad/go.mod h1:0DvGGofJ9hr1q63cBrOY/jSY52OwhRGA0K47NE80I5Y=
+example.com/retract/self/prev v1.1.0 h1:0/8I/GTG+1eJTFeDQ/fUbgrMsVHHyKhh3Z8DSZp1fuA=
+example.com/retract/self/prev v1.1.0/go.mod h1:xl2EcklWuZZHVtHWcpzfSJQmnzAGpKZYpA/Wto7SZN4=
 -- use/use.go --
 package use
 
diff --git a/src/cmd/go/testdata/script/mod_retract_rationale.txt b/src/cmd/go/testdata/script/mod_retract_rationale.txt
index 4d3a3d6..823c384 100644
--- a/src/cmd/go/testdata/script/mod_retract_rationale.txt
+++ b/src/cmd/go/testdata/script/mod_retract_rationale.txt
@@ -29,7 +29,7 @@
 
 # 'go get' should omit long messages.
 go get -d example.com/retract/rationale@v1.0.0-long
-stderr '^go: warning: example.com/retract/rationale@v1.0.0-long: retracted by module author: \(rationale omitted: too long\)'
+stderr '^go: warning: example.com/retract/rationale@v1.0.0-long: retracted by module author: \(message omitted: too long\)'
 
 # 'go list' should show the full message.
 go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale
@@ -38,7 +38,7 @@
 
 # 'go get' should omit messages with unprintable characters.
 go get -d example.com/retract/rationale@v1.0.0-unprintable
-stderr '^go: warning: example.com/retract/rationale@v1.0.0-unprintable: retracted by module author: \(rationale omitted: contains non-printable characters\)'
+stderr '^go: warning: example.com/retract/rationale@v1.0.0-unprintable: retracted by module author: \(message omitted: contains non-printable characters\)'
 
 # 'go list' should show the full message.
 go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale
diff --git a/src/cmd/go/testdata/script/mod_retract_replace.txt b/src/cmd/go/testdata/script/mod_retract_replace.txt
index 770aea4..9cd7147 100644
--- a/src/cmd/go/testdata/script/mod_retract_replace.txt
+++ b/src/cmd/go/testdata/script/mod_retract_replace.txt
@@ -5,8 +5,10 @@
 go get -d
 
 # The latest version, v1.9.0, is not available on the proxy.
-! go list -m -retracted example.com/retract/missingmod
-stderr '^go list -m: loading module retractions for example.com/retract/missingmod@v1.0.0: .*404 Not Found$'
+go list -m -retracted example.com/retract/missingmod
+stdout '^example.com/retract/missingmod v1.0.0$'
+exists $GOPATH/pkg/mod/cache/download/example.com/retract/missingmod/@v/v1.9.0.info
+! exists $GOPATH/pkg/mod/cache/download/example.com/retract/missingmod/@v/v1.9.0.mod
 
 # If we replace that version, we should see retractions.
 go mod edit -replace=example.com/retract/missingmod@v1.9.0=./missingmod-v1.9.0
diff --git a/src/cmd/go/testdata/script/mod_retract_versions.txt b/src/cmd/go/testdata/script/mod_retract_versions.txt
new file mode 100644
index 0000000..012fa15
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_retract_versions.txt
@@ -0,0 +1,22 @@
+# https://golang.org/issue/44296: the --versions flag should not affect
+# the version reported by 'go list' in case of retractions.
+
+env FMT='{{.Path}}{{with .Error}}: {{printf "%q" .Err}}{{end}} {{printf "%q" .Version}}{{with .Versions}} {{.}}{{end}}'
+
+go list -m -e -f $FMT example.com/retract/self/pseudo
+stdout '^example.com/retract/self/pseudo: "module example.com/retract/self/pseudo: not a known dependency" ""$'
+
+go list -m -e -f $FMT example.com/retract/self/pseudo@latest
+stdout '^example.com/retract/self/pseudo: "module example.com/retract/self/pseudo: no matching versions for query \\"latest\\"" "latest"$'
+
+
+go list -m -e -f $FMT --versions example.com/retract/self/pseudo
+stdout '^example.com/retract/self/pseudo ""$'
+
+go list -m -e -f $FMT --versions example.com/retract/self/pseudo@latest
+stdout '^example.com/retract/self/pseudo: "module example.com/retract/self/pseudo: no matching versions for query \\"latest\\"" "latest"$'
+
+-- go.mod --
+module test
+
+go 1.17
diff --git a/src/cmd/go/testdata/script/mod_run_nonmain.txt b/src/cmd/go/testdata/script/mod_run_nonmain.txt
new file mode 100644
index 0000000..036755d
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_run_nonmain.txt
@@ -0,0 +1,18 @@
+! go run $PWD
+! stderr 'no packages loaded'
+stderr '^package example.net/nonmain is not a main package$'
+
+! go run .
+stderr '^package example.net/nonmain is not a main package$'
+
+! go run ./...
+stderr '^go: warning: "\./\.\.\." matched only non-main packages$'
+stderr '^go run: no packages loaded from \./\.\.\.$'
+
+-- go.mod --
+module example.net/nonmain
+
+go 1.17
+-- nonmain.go --
+// Package nonmain is not a main package.
+package nonmain
diff --git a/src/cmd/go/testdata/script/mod_run_pkg_version.txt b/src/cmd/go/testdata/script/mod_run_pkg_version.txt
new file mode 100644
index 0000000..e921fab
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_run_pkg_version.txt
@@ -0,0 +1,103 @@
+# This test checks the behavior of 'go run' with a 'cmd@version' argument.
+# Most of 'go run' is covered in other tests.
+# mod_install_pkg_version covers most of the package loading functionality.
+# This test focuses on 'go run' behavior specific to this mode.
+[short] skip
+
+# 'go run pkg@version' works outside a module.
+env GO111MODULE=auto
+go run example.com/cmd/a@v1.0.0
+stdout '^a@v1.0.0$'
+
+
+# 'go run pkg@version' reports an error if modules are disabled.
+env GO111MODULE=off
+! go run example.com/cmd/a@v1.0.0
+stderr '^go: modules disabled by GO111MODULE=off; see ''go help modules''$'
+env GO111MODULE=on
+
+
+# 'go run pkg@version' ignores go.mod in the current directory.
+cd m
+cp go.mod go.mod.orig
+! go list -m all
+stderr '^go list -m: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry; to add it:\n\tgo mod download example.com/cmd$'
+go run example.com/cmd/a@v1.0.0
+stdout '^a@v1.0.0$'
+cmp go.mod go.mod.orig
+cd ..
+
+
+# 'go install pkg@version' works on a module that doesn't have a go.mod file
+# and with a module whose go.mod file has missing requirements.
+# With a proxy, the two cases are indistinguishable.
+go run rsc.io/fortune@v1.0.0
+stderr '^go: found rsc.io/quote in rsc.io/quote v1.5.2$'
+stderr '^Hello, world.$'
+
+
+# 'go run pkg@version' should report an error if pkg is not a main package.
+! go run example.com/cmd/err@v1.0.0
+stderr '^package example.com/cmd/err is not a main package$'
+
+
+# 'go run pkg@version' should report errors if the module contains
+# replace or exclude directives.
+go mod download example.com/cmd@v1.0.0-replace
+! go run example.com/cmd/a@v1.0.0-replace
+cmp stderr replace-err
+
+go mod download example.com/cmd@v1.0.0-exclude
+! go run example.com/cmd/a@v1.0.0-exclude
+cmp stderr exclude-err
+
+
+# 'go run dir@version' works like a normal 'go run' command if
+# dir is a relative or absolute path.
+go mod download rsc.io/fortune@v1.0.0
+! go run $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0
+stderr '^go: go\.mod file not found in current directory or any parent directory; see ''go help modules''$'
+! go run ../pkg/mod/rsc.io/fortune@v1.0.0
+stderr '^go: go\.mod file not found in current directory or any parent directory; see ''go help modules''$'
+mkdir tmp
+cd tmp
+go mod init tmp
+go mod edit -require=rsc.io/fortune@v1.0.0
+! go run -mod=readonly $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0
+stderr '^missing go\.sum entry for module providing package rsc\.io/fortune; to add:\n\tgo mod download rsc\.io/fortune$'
+! go run -mod=readonly ../../pkg/mod/rsc.io/fortune@v1.0.0
+stderr '^missing go\.sum entry for module providing package rsc\.io/fortune; to add:\n\tgo mod download rsc\.io/fortune$'
+cd ..
+rm tmp
+
+
+# 'go run' does not interpret @version arguments after the first.
+go run example.com/cmd/a@v1.0.0 example.com/doesnotexist@v1.0.0
+stdout '^a@v1.0.0$'
+
+
+# 'go run pkg@version' succeeds when -mod=readonly is set explicitly.
+# Verifies #43278.
+go run -mod=readonly example.com/cmd/a@v1.0.0
+stdout '^a@v1.0.0$'
+
+-- m/go.mod --
+module m
+
+go 1.16
+
+require example.com/cmd v1.1.0-doesnotexist
+-- x/x.go --
+package main
+
+func main() {}
+-- replace-err --
+go run: example.com/cmd/a@v1.0.0-replace (in example.com/cmd@v1.0.0-replace):
+	The go.mod file for the module providing named packages contains one or
+	more replace directives. It must not contain directives that would cause
+	it to be interpreted differently than if it were the main module.
+-- exclude-err --
+go run: example.com/cmd/a@v1.0.0-exclude (in example.com/cmd@v1.0.0-exclude):
+	The go.mod file for the module providing named packages contains one or
+	more exclude directives. It must not contain directives that would cause
+	it to be interpreted differently than if it were the main module.
diff --git a/src/cmd/go/testdata/script/mod_run_pkgerror.txt b/src/cmd/go/testdata/script/mod_run_pkgerror.txt
new file mode 100644
index 0000000..48f900d
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_run_pkgerror.txt
@@ -0,0 +1,32 @@
+# https://golang.org/issue/39986: files reported as invalid by go/build should
+# be listed in InvalidGoFiles.
+
+go list -e -f '{{.Incomplete}}{{"\n"}}{{.Error}}{{"\n"}}{{.InvalidGoFiles}}{{"\n"}}' .
+stdout '^true\nfound packages m \(m\.go\) and main \(main\.go\) in '$PWD'\n\[main.go\]\n'
+
+
+# https://golang.org/issue/45827: 'go run .' should report the same package
+# errors as 'go build' and 'go list'.
+
+! go build
+stderr '^found packages m \(m\.go\) and main \(main\.go\) in '$PWD'$'
+
+! go list .
+stderr '^found packages m \(m\.go\) and main \(main\.go\) in '$PWD'$'
+
+! go run .
+! stderr 'no packages loaded'
+stderr '^found packages m \(m\.go\) and main \(main\.go\) in '$PWD'$'
+
+! go run ./...
+! stderr 'no packages loaded'
+stderr '^found packages m \(m\.go\) and main \(main\.go\) in '$PWD'$'
+
+-- go.mod --
+module m
+
+go 1.17
+-- m.go --
+package m
+-- main.go --
+package main
diff --git a/src/cmd/go/testdata/script/mod_std_vendor.txt b/src/cmd/go/testdata/script/mod_std_vendor.txt
index fb954d7..c3cde52 100644
--- a/src/cmd/go/testdata/script/mod_std_vendor.txt
+++ b/src/cmd/go/testdata/script/mod_std_vendor.txt
@@ -36,11 +36,11 @@
 
 
 # When run within the 'std' module, 'go list -test' should report vendored
-# transitive dependencies at their original module paths.
+# transitive dependencies at their vendored paths.
 cd $GOROOT/src
 go list -test -f '{{range .Deps}}{{.}}{{"\n"}}{{end}}' net/http
-stdout ^golang.org/x/net/http2/hpack
-! stdout ^vendor/golang.org/x/net/http2/hpack
+! stdout ^golang.org/x/net/http2/hpack
+stdout ^vendor/golang.org/x/net/http2/hpack
 
 -- go.mod --
 module m
diff --git a/src/cmd/go/testdata/script/mod_sum_readonly.txt b/src/cmd/go/testdata/script/mod_sum_readonly.txt
index 57c5bbe..113f13e 100644
--- a/src/cmd/go/testdata/script/mod_sum_readonly.txt
+++ b/src/cmd/go/testdata/script/mod_sum_readonly.txt
@@ -4,7 +4,7 @@
 # When a sum is needed to load the build list, we get an error for the
 # specific module. The .mod file is not downloaded, and go.sum is not written.
 ! go list -m all
-stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$'
+stderr '^go list -m: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$'
 ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
 ! exists go.sum
 
@@ -12,7 +12,7 @@
 # we should see the same error.
 cp go.sum.h2only go.sum
 ! go list -m all
-stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$'
+stderr '^go list -m: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$'
 ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
 cmp go.sum go.sum.h2only
 rm go.sum
@@ -21,7 +21,7 @@
 cp go.mod go.mod.orig
 go mod edit -replace rsc.io/quote@v1.5.2=rsc.io/quote@v1.5.1
 ! go list -m all
-stderr '^go: rsc.io/quote@v1.5.2 \(replaced by rsc.io/quote@v1.5.1\): missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$'
+stderr '^go list -m: rsc.io/quote@v1.5.2 \(replaced by rsc.io/quote@v1.5.1\): missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$'
 ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.mod
 ! exists go.sum
 cp go.mod.orig go.mod
diff --git a/src/cmd/go/testdata/script/mod_sumdb.txt b/src/cmd/go/testdata/script/mod_sumdb.txt
index 9a688e1..fa3483c 100644
--- a/src/cmd/go/testdata/script/mod_sumdb.txt
+++ b/src/cmd/go/testdata/script/mod_sumdb.txt
@@ -37,3 +37,9 @@
 
 -- go.mod.orig --
 module m
+
+go 1.16
+-- m.go --
+package m
+
+import _ "rsc.io/quote"
diff --git a/src/cmd/go/testdata/script/mod_sumdb_cache.txt b/src/cmd/go/testdata/script/mod_sumdb_cache.txt
index 2937b2e..1b38475 100644
--- a/src/cmd/go/testdata/script/mod_sumdb_cache.txt
+++ b/src/cmd/go/testdata/script/mod_sumdb_cache.txt
@@ -43,12 +43,5 @@
 ! go get -d rsc.io/quote@v1.5.2
 stderr 504
 
-# but -insecure bypasses the checksum lookup entirely
-env GOINSECURE=
-go get -d -insecure rsc.io/quote@v1.5.2
-
-# and then it is in go.sum again
-go get -d rsc.io/quote@v1.5.2
-
 -- go.mod.orig --
 module m
diff --git a/src/cmd/go/testdata/script/mod_sumdb_golang.txt b/src/cmd/go/testdata/script/mod_sumdb_golang.txt
index cc0b0da..becd88b 100644
--- a/src/cmd/go/testdata/script/mod_sumdb_golang.txt
+++ b/src/cmd/go/testdata/script/mod_sumdb_golang.txt
@@ -10,45 +10,73 @@
 stdout '^sum.golang.org$'
 
 # Download direct from github.
+
 [!net] skip
 [!exec:git] skip
 env GOSUMDB=sum.golang.org
 env GOPROXY=direct
+
 go get -d rsc.io/quote@v1.5.2
 cp go.sum saved.sum
 
+
 # Download from proxy.golang.org with go.sum entry already.
 # Use 'go list' instead of 'go get' since the latter may download extra go.mod
 # files not listed in go.sum.
+
 go clean -modcache
 env GOSUMDB=
 env GOPROXY=
-go list -x -deps rsc.io/quote
+
+go list -x -m all  # Download go.mod files.
 ! stderr github
 stderr proxy.golang.org/rsc.io/quote
 ! stderr sum.golang.org/tile
 ! stderr sum.golang.org/lookup/rsc.io/quote
+
+go list -x -deps rsc.io/quote  # Download module source.
+! stderr github
+stderr proxy.golang.org/rsc.io/quote
+! stderr sum.golang.org/tile
+! stderr sum.golang.org/lookup/rsc.io/quote
+
 cmp go.sum saved.sum
 
+
 # Download again.
 # Should use the checksum database to validate new go.sum lines,
 # but not need to fetch any new data from the proxy.
+
 rm go.sum
-go list -mod=mod -x rsc.io/quote
+
+go list -mod=mod -x -m all  # Add checksums for go.mod files.
+stderr sum.golang.org/tile
 ! stderr github
 ! stderr proxy.golang.org/rsc.io/quote
-stderr sum.golang.org/tile
 stderr sum.golang.org/lookup/rsc.io/quote
+
+go list -mod=mod -x rsc.io/quote  # Add checksums for module source.
+! stderr .  # Adds checksums, but for entities already in the module cache.
+
 cmp go.sum saved.sum
 
+
 # test fallback to direct
+
 env TESTGOPROXY404=1
 go clean -modcache
 rm go.sum
-go list -mod=mod -x rsc.io/quote
+
+go list -mod=mod -x -m all  # Download go.mod files
 stderr 'proxy.golang.org.*404 testing'
 stderr github.com/rsc
+
+go list -mod=mod -x rsc.io/quote  # Download module source.
+stderr 'proxy.golang.org.*404 testing'
+stderr github.com/rsc
+
 cmp go.sum saved.sum
 
+
 -- go.mod --
 module m
diff --git a/src/cmd/go/testdata/script/mod_test.txt b/src/cmd/go/testdata/script/mod_test.txt
index 50f0035..76f1d7a 100644
--- a/src/cmd/go/testdata/script/mod_test.txt
+++ b/src/cmd/go/testdata/script/mod_test.txt
@@ -60,6 +60,8 @@
 -- a/go.mod.empty --
 module example.com/user/a
 
+go 1.11
+
 -- a/a.go --
 package a
 
diff --git a/src/cmd/go/testdata/script/mod_tidy_compat.txt b/src/cmd/go/testdata/script/mod_tidy_compat.txt
new file mode 100644
index 0000000..e6edef5
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_compat.txt
@@ -0,0 +1,95 @@
+# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by
+# default preserve enough checksums for the module to be used by Go 1.16.
+#
+# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the
+# 'go' version in the go.mod file to 1.16, without actually updating the
+# requirements to match.
+
+[short] skip
+
+env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}'
+
+
+# This module has the same module dependency graph in Go 1.16 as in Go 1.17,
+# but in 1.16 requires (checksums for) additional (irrelevant) go.mod files.
+#
+# The module graph under both versions looks like:
+#
+# m ---- example.com/version v1.1.0
+# |
+# + ---- example.net/lazy v0.1.0 ---- example.com/version v1.0.1
+#
+# Go 1.17 avoids loading the go.mod file for example.com/version v1.0.1
+# (because it is lower than the verison explicitly required by m,
+# and the module that requires it — m — specifies 'go 1.17').
+#
+# That go.mod file happens not to affect the final 1.16 module graph anyway,
+# so the pruned graph is equivalent to the unpruned one.
+
+cp go.mod go.mod.orig
+go mod tidy
+cmp go.mod go.mod.orig
+
+go list -m all
+cmp stdout m_all.txt
+
+go mod edit -go=1.16
+go list -m all
+cmp stdout m_all.txt
+
+
+# If we explicitly drop compatibility with 1.16, we retain fewer checksums,
+# which gives a cleaner go.sum file but causes 1.16 to fail in readonly mode.
+
+cp go.mod.orig go.mod
+go mod tidy -compat=1.17
+cmp go.mod go.mod.orig
+
+go list -m all
+cmp stdout m_all.txt
+
+go mod edit -go=1.16
+! go list -m all
+stderr '^go list -m: example.net/lazy@v0.1.0 requires\n\texample.com/version@v1.0.1: missing go.sum entry; to add it:\n\tgo mod download example.com/version$'
+
+
+-- go.mod --
+// Module m happens to have the exact same build list as what would be
+// selected under Go 1.16, but computes that build list without looking at
+// as many go.mod files.
+module example.com/m
+
+go 1.17
+
+replace example.net/lazy v0.1.0 => ./lazy
+
+require (
+	example.com/version v1.1.0
+	example.net/lazy v0.1.0
+)
+-- m_all.txt --
+example.com/m
+example.com/version v1.1.0
+example.net/lazy v0.1.0 => ./lazy
+-- compatible.go --
+package compatible
+
+import (
+	_ "example.com/version"
+	_ "example.net/lazy"
+)
+-- lazy/go.mod --
+// Module lazy requires example.com/version v1.0.1.
+//
+// However, since this module is lazy, its dependents
+// should not need checksums for that version of the module
+// unless they actually import packages from it.
+module example.net/lazy
+
+go 1.17
+
+require example.com/version v1.0.1
+-- lazy/lazy.go --
+package lazy
+
+import _ "example.com/version"
diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_added.txt b/src/cmd/go/testdata/script/mod_tidy_compat_added.txt
new file mode 100644
index 0000000..94fa79b
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_compat_added.txt
@@ -0,0 +1,105 @@
+# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by
+# default preserve enough checksums for the module to be used by Go 1.16.
+#
+# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the
+# 'go' version in the go.mod file to 1.16, without actually updating the
+# requirements to match.
+
+[short] skip
+
+env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}'
+
+
+# For this module, Go 1.17 produces an error for one module, and Go 1.16
+# produces a different error for a different module.
+
+cp go.mod go.mod.orig
+
+! go mod tidy
+
+stderr '^example\.com/m imports\n\texample\.net/added: module example\.net/added@latest found \(v0\.3\.0, replaced by \./a1\), but does not contain package example\.net/added$'
+
+cmp go.mod go.mod.orig
+
+
+# When we run 'go mod tidy -e', we should proceed past the first error and follow
+# it with a second error describing the version descrepancy.
+#
+# We should not provide advice on how to push past the version descrepancy,
+# because the '-e' flag should already do that, writing out an otherwise-tidied
+# go.mod file.
+
+go mod tidy -e
+
+stderr '^example\.com/m imports\n\texample\.net/added: module example\.net/added@latest found \(v0\.3\.0, replaced by \./a1\), but does not contain package example\.net/added\nexample\.net/added failed to load from any module,\n\tbut go 1\.16 would load it from example\.net/added@v0\.2\.0$'
+
+! stderr '\n\tgo mod tidy'
+
+cmp go.mod go.mod.tidy
+
+
+-- go.mod --
+module example.com/m
+
+go 1.17
+
+replace (
+	example.net/added v0.1.0 => ./a1
+	example.net/added v0.2.0 => ./a2
+	example.net/added v0.3.0 => ./a1
+	example.net/lazy v0.1.0 => ./lazy
+	example.net/pruned v0.1.0 => ./pruned
+)
+
+require (
+	example.net/added v0.1.0
+	example.net/lazy v0.1.0
+)
+-- go.mod.tidy --
+module example.com/m
+
+go 1.17
+
+replace (
+	example.net/added v0.1.0 => ./a1
+	example.net/added v0.2.0 => ./a2
+	example.net/added v0.3.0 => ./a1
+	example.net/lazy v0.1.0 => ./lazy
+	example.net/pruned v0.1.0 => ./pruned
+)
+
+require example.net/lazy v0.1.0
+-- m.go --
+package m
+
+import (
+	_ "example.net/added"
+	_ "example.net/lazy"
+)
+
+-- a1/go.mod --
+module example.net/added
+
+go 1.17
+-- a2/go.mod --
+module example.net/added
+
+go 1.17
+-- a2/added.go --
+package added
+
+-- lazy/go.mod --
+module example.net/lazy
+
+go 1.17
+
+require example.net/pruned v0.1.0
+-- lazy/lazy.go --
+package lazy
+
+-- pruned/go.mod --
+module example.net/pruned
+
+go 1.17
+
+require example.net/added v0.2.0
diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_ambiguous.txt b/src/cmd/go/testdata/script/mod_tidy_compat_ambiguous.txt
new file mode 100644
index 0000000..c544cb7
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_compat_ambiguous.txt
@@ -0,0 +1,98 @@
+# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by
+# default preserve enough checksums for the module to be used by Go 1.16.
+#
+# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the
+# 'go' version in the go.mod file to 1.16, without actually updating the
+# requirements to match.
+
+[short] skip
+
+env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}'
+
+# For this module, the dependency providing package
+# example.net/ambiguous/nested/pkg is unambiguous in Go 1.17 (because only one
+# root of the module graph contains the package), whereas it is ambiguous in
+# Go 1.16 (because two different modules contain plausible packages and Go 1.16
+# does not privilege roots above other dependencies).
+#
+# However, the overall build list is identical for both versions.
+
+cp go.mod go.mod.orig
+
+! go mod tidy
+
+stderr '^example\.com/m imports\n\texample\.net/indirect imports\n\texample\.net/ambiguous/nested/pkg loaded from example\.net/ambiguous/nested@v0\.1\.0,\n\tbut go 1.16 would fail to locate it:\n\tambiguous import: found package example\.net/ambiguous/nested/pkg in multiple modules:\n\texample\.net/ambiguous v0.1.0 \(.*\)\n\texample\.net/ambiguous/nested v0.1.0 \(.*\)\n\n'
+
+stderr '\n\nTo proceed despite packages unresolved in go 1\.16:\n\tgo mod tidy -e\nIf reproducibility with go 1.16 is not needed:\n\tgo mod tidy -compat=1\.17\nFor other options, see:\n\thttps://golang\.org/doc/modules/pruning\n'
+
+cmp go.mod go.mod.orig
+
+
+# If we run 'go mod tidy -e', we should still save enough checksums to run
+# 'go list -m all' reproducibly with go 1.16, even though we can't list
+# the specific package.
+
+go mod tidy -e
+! stderr '\n\tgo mod tidy'
+cmp go.mod go.mod.orig
+
+go list -m all
+cmp stdout all-m.txt
+
+go list -f $MODFMT example.net/ambiguous/nested/pkg
+stdout '^example.net/ambiguous/nested v0\.1\.0$'
+! stderr .
+
+go mod edit -go=1.16
+go list -m all
+cmp stdout all-m.txt
+
+! go list -f $MODFMT example.net/ambiguous/nested/pkg
+stderr '^ambiguous import: found package example\.net/ambiguous/nested/pkg in multiple modules:\n\texample\.net/ambiguous v0\.1\.0 \(.*\)\n\texample\.net/ambiguous/nested v0\.1\.0 \(.*\)\n'
+
+
+# On the other hand, if we use -compat=1.17, 1.16 can't even load
+# the build list (due to missing checksums).
+
+cp go.mod.orig go.mod
+go mod tidy -compat=1.17
+! stderr .
+go list -m all
+cmp stdout all-m.txt
+
+go mod edit -go=1.16
+! go list -m all
+stderr '^go list -m: example\.net/indirect@v0\.1\.0 requires\n\texample\.net/ambiguous@v0\.1\.0: missing go\.sum entry; to add it:\n\tgo mod download example\.net/ambiguous\n'
+
+
+-- go.mod --
+module example.com/m
+
+go 1.17
+
+replace example.net/indirect v0.1.0 => ./indirect
+
+require (
+	example.net/ambiguous/nested v0.1.0 // indirect
+	example.net/indirect v0.1.0
+)
+-- all-m.txt --
+example.com/m
+example.net/ambiguous v0.1.0
+example.net/ambiguous/nested v0.1.0
+example.net/indirect v0.1.0 => ./indirect
+-- m.go --
+package m
+
+import _ "example.net/indirect"
+
+-- indirect/go.mod --
+module example.net/indirect
+
+go 1.17
+
+require example.net/ambiguous v0.1.0
+-- indirect/indirect.go --
+package indirect
+
+import _ "example.net/ambiguous/nested/pkg"
diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_deleted.txt b/src/cmd/go/testdata/script/mod_tidy_compat_deleted.txt
new file mode 100644
index 0000000..dcf13e2
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_compat_deleted.txt
@@ -0,0 +1,128 @@
+# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by
+# default preserve enough checksums for the module to be used by Go 1.16.
+#
+# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the
+# 'go' version in the go.mod file to 1.16, without actually updating the
+# requirements to match.
+
+[short] skip
+
+env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}'
+
+
+# For this module, the "deleted" dependency contains an imported package, but
+# Go 1.16 selects a higher version (in which that package has been deleted).
+
+cp go.mod go.mod.orig
+
+! go mod tidy
+
+stderr '^example\.com/m imports\n\texample\.net/deleted loaded from example\.net/deleted@v0\.1\.0,\n\tbut go 1\.16 would fail to locate it in example\.net/deleted@v0\.2\.0\n\n'
+
+stderr '\n\nTo upgrade to the versions selected by go 1.16, leaving some packages unresolved:\n\tgo mod tidy -e -go=1\.16 && go mod tidy -e -go=1\.17\nIf reproducibility with go 1.16 is not needed:\n\tgo mod tidy -compat=1\.17\nFor other options, see:\n\thttps://golang\.org/doc/modules/pruning\n'
+
+
+# The suggested 'go mod tidy -e' command should proceed anyway.
+
+go mod tidy -e
+cmp go.mod go.mod.tidy
+
+
+# In 'go 1.16' mode we should error out in the way we claimed.
+
+cd 116-outside
+! go list -deps -f $MODFMT example.com/m
+stderr '^\.\.[/\\]m\.go:4:2: no required module provides package example\.net/deleted; to add it:\n\tgo get example\.net/deleted$'
+cd ..
+
+go mod edit -go=1.16
+! go list -deps -f $MODFMT example.com/m
+stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$'
+
+! go mod tidy
+stderr '^example\.com/m imports\n\texample\.net/deleted: module example\.net/deleted@latest found \(v0\.2\.0, replaced by \./d2\), but does not contain package example\.net/deleted$'
+
+
+-- go.mod --
+module example.com/m
+
+go 1.17
+
+replace (
+	example.net/deleted v0.1.0 => ./d1
+	example.net/deleted v0.2.0 => ./d2
+	example.net/lazy v0.1.0 => ./lazy
+	example.net/pruned v0.1.0 => ./pruned
+)
+
+require (
+	example.net/deleted v0.1.0
+	example.net/deleted v0.1.0 // redundant
+	example.net/lazy v0.1.0
+)
+-- go.mod.tidy --
+module example.com/m
+
+go 1.17
+
+replace (
+	example.net/deleted v0.1.0 => ./d1
+	example.net/deleted v0.2.0 => ./d2
+	example.net/lazy v0.1.0 => ./lazy
+	example.net/pruned v0.1.0 => ./pruned
+)
+
+require (
+	example.net/deleted v0.1.0
+	example.net/lazy v0.1.0
+)
+-- 116-outside/go.mod --
+module outside
+
+go 1.16
+
+replace (
+	example.com/m => ../
+	example.net/deleted v0.1.0 => ../d1
+	example.net/deleted v0.2.0 => ../d2
+	example.net/lazy v0.1.0 => ../lazy
+	example.net/pruned v0.1.0 => ../pruned
+)
+
+require example.com/m v0.1.0
+-- m.go --
+package m
+
+import (
+	_ "example.net/deleted"
+	_ "example.net/lazy"
+)
+
+-- d1/go.mod --
+module example.net/deleted
+
+go 1.17
+-- d1/deleted.go --
+package deleted
+-- d2/go.mod --
+module example.net/deleted
+
+go 1.17
+-- d2/README --
+There is no longer a Go package here.
+
+-- lazy/go.mod --
+module example.net/lazy
+
+go 1.17
+
+require example.net/pruned v0.1.0
+-- lazy/lazy.go --
+package lazy
+
+-- pruned/go.mod --
+module example.net/pruned
+
+go 1.17
+
+require example.net/deleted v0.2.0
diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_implicit.txt b/src/cmd/go/testdata/script/mod_tidy_compat_implicit.txt
new file mode 100644
index 0000000..186a3f8
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_compat_implicit.txt
@@ -0,0 +1,129 @@
+# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by
+# default preserve enough checksums for the module to be used by Go 1.16.
+#
+# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the
+# 'go' version in the go.mod file to 1.16, without actually updating the
+# requirements to match.
+
+[short] skip
+
+env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}'
+
+
+# For this module, Go 1.16 selects the same versions of all explicit dependencies
+# as Go 1.17 does. However, Go 1.16 selects a higher version of an *implicit*
+# dependency, imported by a test of one of the (external) imported packages.
+# As a result, Go 1.16 also needs checksums for the module sources for that higher
+# version.
+#
+# The Go 1.16 module graph looks like:
+#
+# m ---- lazy v0.1.0 ---- incompatible v1.0.0
+#         |
+#         + ------------- requireincompatible v0.1.0 ---- incompatible v2.0.0+incompatible
+#
+# The Go 1.17 module graph is the same except that the dependencies of
+# requireincompatible are pruned out (because the module that requires
+# it — lazy v0.1.0 — specifies 'go 1.17', and it is not otherwise relevant to
+# the main module).
+
+# 'go mod tidy' should by default diagnose the difference in dependencies as an
+# error, with useful suggestions about how to resolve it.
+
+cp go.mod go.mod.orig
+! go mod tidy
+stderr '^example\.com/m imports\n\texample\.net/lazy tested by\n\texample\.net/lazy.test imports\n\texample\.com/retract/incompatible loaded from example\.com/retract/incompatible@v1\.0\.0,\n\tbut go 1\.16 would select v2\.0\.0\+incompatible\n\n'
+stderr '\n\nTo upgrade to the versions selected by go 1\.16:\n\tgo mod tidy -go=1\.16 && go mod tidy -go=1\.17\nIf reproducibility with go 1.16 is not needed:\n\tgo mod tidy -compat=1.17\nFor other options, see:\n\thttps://golang\.org/doc/modules/pruning\n'
+
+cmp go.mod go.mod.orig
+
+# The suggested '-compat' flag to ignore differences should silence the error
+# and leave go.mod unchanged, resulting in checksum errors when Go 1.16 tries
+# to load a module pruned out by Go 1.17.
+
+go mod tidy -compat=1.17
+! stderr .
+cmp go.mod go.mod.orig
+
+go list -deps -test -f $MODFMT all
+stdout '^example\.com/retract/incompatible v1\.0\.0$'
+
+go mod edit -go=1.16
+! go list -deps -test -f $MODFMT all
+
+	# TODO(#46160): -count=1 instead of -count=2.
+stderr -count=2 '^go: example\.net/lazy@v0\.1\.0 requires\n\texample\.com/retract/incompatible@v1\.0\.0: missing go\.sum entry; to add it:\n\tgo mod download example\.com/retract/incompatible$'
+
+
+# If we combine a Go 1.16 go.sum file...
+go mod tidy -go=1.16
+
+# ...with a Go 1.17 go.mod file...
+cp go.mod.orig go.mod
+
+# ...then Go 1.17 no longer works. 😞
+! go list -deps -test -f $MODFMT all
+stderr -count=1 '^can''t load test package: lazy[/\\]lazy_test.go:3:8: missing go\.sum entry for module providing package example\.com/retract/incompatible \(imported by example\.net/lazy\); to add:\n\tgo get -t example.net/lazy@v0\.1\.0$'
+
+
+# However, if we take the union of the go.sum files...
+go list -mod=mod -deps -test all
+cmp go.mod go.mod.orig
+
+# ...then Go 1.17 continues to work...
+go list -deps -test -f $MODFMT all
+stdout '^example\.com/retract/incompatible v1\.0\.0$'
+
+# ...and 1.16 also works(‽), but selects a different version for the
+# external-test dependency.
+go mod edit -go=1.16
+go list -deps -test -f $MODFMT all
+stdout '^example\.com/retract/incompatible v2\.0\.0\+incompatible$'
+
+
+-- go.mod --
+// Module m imports packages from the same versions under Go 1.17
+// as under Go 1.16, but under 1.16 its (implicit) external test dependencies
+// are higher.
+module example.com/m
+
+go 1.17
+
+replace (
+	example.net/lazy v0.1.0 => ./lazy
+	example.net/requireincompatible v0.1.0 => ./requireincompatible
+)
+
+require example.net/lazy v0.1.0
+-- implicit.go --
+package implicit
+
+import _ "example.net/lazy"
+-- lazy/go.mod --
+// Module lazy requires example.com/retract/incompatible v1.0.0.
+//
+// When viewed from the outside it also has a transitive dependency
+// on v2.0.0+incompatible, but in lazy mode that transitive dependency
+// is pruned out.
+module example.net/lazy
+
+go 1.17
+
+exclude example.com/retract/incompatible v2.0.0+incompatible
+
+require (
+	example.com/retract/incompatible v1.0.0
+	example.net/requireincompatible v0.1.0
+)
+-- lazy/lazy.go --
+package lazy
+-- lazy/lazy_test.go --
+package lazy_test
+
+import _ "example.com/retract/incompatible"
+-- requireincompatible/go.mod --
+module example.net/requireincompatible
+
+go 1.15
+
+require example.com/retract/incompatible v2.0.0+incompatible
diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_incompatible.txt b/src/cmd/go/testdata/script/mod_tidy_compat_incompatible.txt
new file mode 100644
index 0000000..ea9e42e
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_compat_incompatible.txt
@@ -0,0 +1,135 @@
+# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by
+# default preserve enough checksums for the module to be used by Go 1.16.
+#
+# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the
+# 'go' version in the go.mod file to 1.16, without actually updating the
+# requirements to match.
+
+[short] skip
+
+env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}'
+
+
+# For this module, Go 1.17 prunes out a (transitive and otherwise-irrelevant)
+# requirement on a retracted higher version of a dependency.
+# However, when Go 1.16 reads the same requirements from the go.mod file,
+# it does not prune out that requirement, and selects the retracted version.
+#
+# The Go 1.16 module graph looks like:
+#
+# m ---- lazy v0.1.0 ---- requireincompatible v0.1.0 ---- incompatible v2.0.0+incompatible
+# |        |
+# + -------+------------- incompatible v1.0.0
+#
+# The Go 1.17 module graph is the same except that the dependencies of
+# requireincompatible are pruned out (because the module that requires
+# it — lazy v0.1.0 — specifies 'go 1.17', and it is not otherwise relevant to
+# the main module).
+
+
+# 'go mod tidy' should by default diagnose the difference in dependencies as an
+# error, with useful suggestions about how to resolve it.
+
+cp go.mod go.mod.orig
+! go mod tidy
+stderr '^example\.com/m imports\n\texample\.net/lazy imports\n\texample\.com/retract/incompatible loaded from example\.com/retract/incompatible@v1\.0\.0,\n\tbut go 1\.16 would select v2\.0\.0\+incompatible\n\n'
+stderr '\n\nTo upgrade to the versions selected by go 1\.16:\n\tgo mod tidy -go=1\.16 && go mod tidy -go=1\.17\nIf reproducibility with go 1\.16 is not needed:\n\tgo mod tidy -compat=1.17\nFor other options, see:\n\thttps://golang\.org/doc/modules/pruning\n'
+
+cmp go.mod go.mod.orig
+
+
+# The suggested '-compat' flag to ignore differences should silence the error
+# and leave go.mod unchanged, resulting in checksum errors when Go 1.16 tries
+# to load a module pruned out by Go 1.17.
+
+go mod tidy -compat=1.17
+! stderr .
+cmp go.mod go.mod.orig
+
+go mod edit -go=1.16
+! go list -f $MODFMT -deps ./...
+	# TODO(#46160): -count=1 instead of -count=2.
+stderr -count=2 '^go: example\.net/lazy@v0\.1\.0 requires\n\texample\.net/requireincompatible@v0\.1\.0 requires\n\texample\.com/retract/incompatible@v2\.0\.0\+incompatible: missing go.sum entry; to add it:\n\tgo mod download example.com/retract/incompatible$'
+
+
+# There are two ways for the module author to bring the two into alignment.
+# One is to *explicitly* 'exclude' the version that is already *implicitly*
+# pruned out under 1.17.
+
+go mod edit -exclude=example.com/retract/incompatible@v2.0.0+incompatible
+go list -f $MODFMT -deps ./...
+stdout '^example.com/retract/incompatible v1\.0\.0$'
+! stdout 'v2\.0\.0'
+
+
+# The other is to explicitly upgrade the version required under Go 1.17
+# to match the version selected by Go 1.16. The commands suggested by
+# 'go mod tidy' should do exactly that.
+
+cp go.mod.orig go.mod
+
+go mod tidy -go=1.16
+go list -f $MODFMT -deps ./...
+stdout '^example.com/retract/incompatible v2\.0\.0\+incompatible$'
+! stdout 'v1\.0\.0'
+
+go mod tidy -go=1.17
+go list -f $MODFMT -deps ./...
+stdout '^example.com/retract/incompatible v2\.0\.0\+incompatible$'
+! stdout 'v1\.0\.0'
+
+go mod edit -go=1.16
+go list -f $MODFMT -deps ./...
+stdout '^example.com/retract/incompatible v2\.0\.0\+incompatible$'
+! stdout 'v1\.0\.0'
+
+
+-- go.mod --
+// Module m indirectly imports a package from
+// example.com/retract/incompatible. Its selected version of
+// that module is lower under Go 1.17 semantics than under Go 1.16.
+module example.com/m
+
+go 1.17
+
+replace (
+	example.net/lazy v0.1.0 => ./lazy
+	example.net/requireincompatible v0.1.0 => ./requireincompatible
+)
+
+require (
+	example.com/retract/incompatible v1.0.0 // indirect
+	example.net/lazy v0.1.0
+)
+-- incompatible.go --
+package incompatible
+
+import _ "example.net/lazy"
+
+-- lazy/go.mod --
+// Module lazy requires example.com/retract/incompatible v1.0.0.
+//
+// When viewed from the outside it also has a transitive dependency
+// on v2.0.0+incompatible, but in lazy mode that transitive dependency
+// is pruned out.
+module example.net/lazy
+
+go 1.17
+
+exclude example.com/retract/incompatible v2.0.0+incompatible
+
+require (
+	example.com/retract/incompatible v1.0.0
+	example.net/requireincompatible v0.1.0
+)
+-- lazy/lazy.go --
+package lazy
+
+import _ "example.com/retract/incompatible"
+
+-- requireincompatible/go.mod --
+module example.net/requireincompatible
+
+go 1.15
+
+require example.com/retract/incompatible v2.0.0+incompatible
diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_irrelevant.txt b/src/cmd/go/testdata/script/mod_tidy_compat_irrelevant.txt
new file mode 100644
index 0000000..7c22fca
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_compat_irrelevant.txt
@@ -0,0 +1,99 @@
+# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by
+# default preserve enough checksums for the module to be used by Go 1.16.
+#
+# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the
+# 'go' version in the go.mod file to 1.16, without actually updating the
+# requirements to match.
+
+[short] skip
+
+env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}'
+
+
+# This module selects the same versions in Go 1.16 and 1.17 for all modules
+# that provide packages (or test dependencies of packages) imported by the
+# main module. However, in Go 1.16 it selects a higher version of a
+# transitive module dependency that is not otherwise relevant to the main module.
+# As a result, Go 1.16 needs an additional checksum for the go.mod file of
+# that irrelevant dependency.
+#
+# The Go 1.16 module graph looks like:
+#
+# m ---- lazy v0.1.0 ---- incompatible v1.0.0
+#         |
+#         + ------------- requireincompatible v0.1.0 ---- incompatible v2.0.0+incompatible
+
+cp go.mod go.mod.orig
+go mod tidy
+cmp go.mod go.mod.orig
+
+go list -deps -test -f $MODFMT all
+cp stdout out-117.txt
+
+go mod edit -go=1.16
+go list -deps -test -f $MODFMT all
+cmp stdout out-117.txt
+
+
+# If we explicitly drop compatibility with 1.16, we retain fewer checksums,
+# which gives a cleaner go.sum file but causes 1.16 to fail in readonly mode.
+
+cp go.mod.orig go.mod
+go mod tidy -compat=1.17
+cmp go.mod go.mod.orig
+
+go list -deps -test -f $MODFMT all
+cmp stdout out-117.txt
+
+go mod edit -go=1.16
+! go list -deps -test -f $MODFMT all
+	# TODO(#46160): -count=1 instead of -count=2.
+stderr -count=2 '^go: example.net/lazy@v0.1.0 requires\n\texample.com/retract/incompatible@v1.0.0: missing go.sum entry; to add it:\n\tgo mod download example.com/retract/incompatible$'
+
+
+-- go.mod --
+// Module m imports packages from the same versions under Go 1.17
+// as under Go 1.16, but under 1.16 its (implicit) external test dependencies
+// are higher.
+module example.com/m
+
+go 1.17
+
+replace (
+	example.net/lazy v0.1.0 => ./lazy
+	example.net/requireincompatible v0.1.0 => ./requireincompatible
+)
+
+require example.net/lazy v0.1.0
+-- m.go --
+package m
+
+import _ "example.net/lazy"
+-- lazy/go.mod --
+// Module lazy requires example.com/retract/incompatible v1.0.0.
+//
+// When viewed from the outside it also has a transitive dependency
+// on v2.0.0+incompatible, but in lazy mode that transitive dependency
+// is pruned out.
+module example.net/lazy
+
+go 1.17
+
+exclude example.com/retract/incompatible v2.0.0+incompatible
+
+require (
+	example.com/retract/incompatible v1.0.0
+	example.net/requireincompatible v0.1.0
+)
+-- lazy/lazy.go --
+package lazy
+-- lazy/unimported/unimported.go --
+package unimported
+
+import _ "example.com/retract/incompatible"
+-- requireincompatible/go.mod --
+module example.net/requireincompatible
+
+go 1.15
+
+require example.com/retract/incompatible v2.0.0+incompatible
diff --git a/src/cmd/go/testdata/script/mod_tidy_convergence.txt b/src/cmd/go/testdata/script/mod_tidy_convergence.txt
new file mode 100644
index 0000000..09c46f7
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_convergence.txt
@@ -0,0 +1,202 @@
+# This test demonstrates a simple case in which 'go mod tidy' may resolve a
+# missing package, only to remove that package when resolving its dependencies.
+#
+# If we naively iterate 'go mod tidy' until the dependency graph converges, this
+# scenario may fail to converge.
+
+# The import graph used in this test looks like:
+#
+# m --- x
+#       |
+#       x_test --- y
+#
+# The module dependency graph of m is initially empty.
+# Modules x and y look like:
+#
+# x.1 (provides package x that imports y, but does not depend on module y)
+#
+# x.2-pre (no dependencies, but does not provide package x)
+#
+# y.1 (no dependencies, but provides package y)
+#
+# y.2 --- x.2-pre (provides package y)
+#
+#
+# When we resolve the missing import of y in x_test, we add y@latest — which is
+# y.2, not y.1 — as a new dependency. That upgrades to x to x.2-pre, which
+# removes package x (and also the need for module y). We can then safely remove
+# the dependency on module y, because nothing imports package y any more!
+#
+# We might be tempted to remove the dependency on module x for the same reason:
+# it no longer provides any imported package. However, that would cause 'go mod
+# tidy -e' to become unstable: with x.2-pre out of the way, we could once again
+# resolve the missing import of package x by re-adding x.1.
+
+cp go.mod go.mod.orig
+
+# 'go mod tidy' without -e should fail without modifying go.mod,
+# because it cannot resolve x and y simultaneously.
+! go mod tidy
+
+cmp go.mod go.mod.orig
+
+stderr '^go: found example\.net/y in example\.net/y v0.2.0$'
+stderr '^go: finding module for package example\.net/x$'
+
+	# TODO: This error message should be clearer — it doesn't indicate why v0.2.0-pre is required.
+stderr '^example\.net/m imports\n\texample\.net/x: package example\.net/x provided by example\.net/x at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$'
+
+
+# 'go mod tidy -e' should follow upgrades to try to resolve the modules that it
+# can, and then stop. When we resolve example.net/y, we upgrade to example.net/x
+# to v0.2.0-pre. At that version, package x no longer exists and no longer
+# imports package y, so the import of x should be left unsatisfied and the
+# existing dependency on example.net/x removed.
+#
+# TODO(bcmills): It would be ever better if we could keep the original
+# dependency on example.net/x v0.1.0, but I don't see a way to do that without
+# making the algorithm way too complicated. (We would have to detect that the
+# new dependency on example.net/y interferes with the package that caused us to
+# to add that dependency in the first place, and back out that part of the change
+# without also backing out any other needed changes.)
+
+go mod tidy -e
+cmp go.mod go.mod.tidye
+stderr '^go: found example\.net/y in example\.net/y v0.2.0$'
+
+	# TODO: This error message should be clearer — it doesn't indicate why v0.2.0-pre is required.
+stderr '^example\.net/m imports\n\texample\.net/x: package example\.net/x provided by example\.net/x at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$'
+
+
+# Since we attempt to resolve the dependencies of package x whenever we add x itself,
+# this end state is stable.
+
+go mod tidy -e
+cmp go.mod go.mod.tidye
+
+
+# An explicit 'go get' with the correct versions should allow 'go mod tidy' to
+# succeed and remain stable. y.1 does not upgrade x, and can therefore be used
+# with it.
+
+go get -d example.net/x@v0.1.0 example.net/y@v0.1.0
+go mod tidy
+cmp go.mod go.mod.postget
+
+
+# The 'tidy' logic for a lazy main module is somewhat different from that for an
+# eager main module, but the overall behavior is the same.
+
+cp go.mod.orig go.mod
+go mod edit -go=1.17 go.mod
+go mod edit -go=1.17 go.mod.tidye
+
+go mod tidy -e
+cmp go.mod go.mod.tidye
+stderr '^go: found example\.net/y in example\.net/y v0.2.0$'
+stderr '^example\.net/m imports\n\texample\.net/x: package example\.net/x provided by example\.net/x at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$'
+
+go get -d example.net/x@v0.1.0 example.net/y@v0.1.0
+go mod tidy
+cmp go.mod go.mod.postget-117
+
+
+-- go.mod --
+module example.net/m
+
+go 1.16
+
+replace (
+	example.net/x v0.1.0 => ./x1
+	example.net/x v0.2.0-pre => ./x2-pre
+	example.net/y v0.1.0 => ./y1
+	example.net/y v0.2.0 => ./y2
+)
+
+require (
+	example.net/x v0.1.0
+)
+-- go.mod.tidye --
+module example.net/m
+
+go 1.16
+
+replace (
+	example.net/x v0.1.0 => ./x1
+	example.net/x v0.2.0-pre => ./x2-pre
+	example.net/y v0.1.0 => ./y1
+	example.net/y v0.2.0 => ./y2
+)
+-- go.mod.postget --
+module example.net/m
+
+go 1.16
+
+replace (
+	example.net/x v0.1.0 => ./x1
+	example.net/x v0.2.0-pre => ./x2-pre
+	example.net/y v0.1.0 => ./y1
+	example.net/y v0.2.0 => ./y2
+)
+
+require (
+	example.net/x v0.1.0
+	example.net/y v0.1.0 // indirect
+)
+-- go.mod.postget-117 --
+module example.net/m
+
+go 1.17
+
+replace (
+	example.net/x v0.1.0 => ./x1
+	example.net/x v0.2.0-pre => ./x2-pre
+	example.net/y v0.1.0 => ./y1
+	example.net/y v0.2.0 => ./y2
+)
+
+require example.net/x v0.1.0
+
+require example.net/y v0.1.0 // indirect
+-- m.go --
+package m
+
+import _ "example.net/x"
+
+-- x1/go.mod --
+module example.net/x
+
+go 1.16
+-- x1/x.go --
+package x
+-- x1/x_test.go --
+package x
+
+import _ "example.net/y"
+
+-- x2-pre/go.mod --
+module example.net/x
+
+go 1.16
+-- x2-pre/README.txt --
+There is no package x here. Use example.com/x/subpkg instead.
+-- x2-pre/subpkg/subpkg.go --
+package subpkg  // import "example.net/x/subpkg"
+
+-- y1/go.mod --
+module example.net/y
+
+go 1.16
+-- y1/y.go --
+package y
+
+-- y2/go.mod --
+module example.net/y
+
+go 1.16
+
+require example.net/x v0.2.0-pre
+-- y2/y.go --
+package y
+
+import _ "example.net/x/subpkg"
diff --git a/src/cmd/go/testdata/script/mod_tidy_convergence_loop.txt b/src/cmd/go/testdata/script/mod_tidy_convergence_loop.txt
new file mode 100644
index 0000000..3c4d324
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_convergence_loop.txt
@@ -0,0 +1,329 @@
+# This test demonstrates a simple case in which 'go mod tidy' may resolve a
+# missing package, only to remove that package when resolving its dependencies.
+#
+# If we naively iterate 'go mod tidy' until the dependency graph converges, this
+# scenario may fail to converge.
+
+# The import graph used in this test looks like:
+#
+# m --- w
+# |
+# + --- x
+# |
+# + --- y
+# |
+# + --- z
+#
+# The module dependency graph of m initially contains w.1 (and, by extension,
+# y.2-pre and z.2-pre). This is an arbitrary point in the cycle of possible
+# configurations.
+#
+# w.1 requires y.2-pre and z.2-pre
+# x.1 requires z.2-pre and w.2-pre
+# y.1 requires w.2-pre and x.2-pre
+# z.1 requires x.2-pre and y.2-pre
+#
+# At each point, exactly one missing package can be resolved by adding a
+# dependency on the .1 release of the module that provides that package.
+# However, adding that dependency causes the module providing another package to
+# roll over from its .1 release to its .2-pre release, which removes the
+# package. Once the package is removed, 'go mod tidy -e' no longer sees the
+# module as relevant to the main module, and will happily remove the existing
+# dependency on it.
+#
+# The cycle is of length 4 so that at every step only one package can be
+# resolved. This is important because it prevents the iteration from ever
+# reaching a state in which every package is simultaneously over-upgraded — such
+# a state is stable and does not exhibit failure to converge.
+
+cp go.mod go.mod.orig
+
+# 'go mod tidy' without -e should fail without modifying go.mod,
+# because it cannot resolve x, y, and z simultaneously.
+! go mod tidy
+
+cmp go.mod go.mod.orig
+
+stderr '^go: finding module for package example\.net/w$'
+stderr '^go: finding module for package example\.net/x$'
+stderr -count=2 '^go: finding module for package example\.net/y$'
+stderr -count=2 '^go: finding module for package example\.net/z$'
+stderr '^go: found example\.net/x in example\.net/x v0.1.0$'
+
+	# TODO: These error messages should be clearer — it doesn't indicate why v0.2.0-pre is required.
+stderr '^example\.net/m imports\n\texample\.net/w: package example\.net/w provided by example\.net/w at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$'
+stderr '^example\.net/m imports\n\texample\.net/y: package example\.net/y provided by example\.net/y at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$'
+stderr '^example\.net/m imports\n\texample\.net/z: package example\.net/z provided by example\.net/z at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$'
+
+
+# 'go mod tidy -e' should preserve all of the upgrades to modules that could
+# provide the missing packages but don't. That would at least explain why they
+# are missing, and why no individual module can be upgraded in order to satisfy
+# a missing import.
+#
+# TODO(bcmills): Today, it doesn't preserve those upgrades, and instead advances
+# the state by one through the cycle of semi-tidy states.
+
+go mod tidy -e
+
+cmp go.mod go.mod.tidye1
+
+stderr '^go: finding module for package example\.net/w$'
+stderr '^go: finding module for package example\.net/x$'
+stderr -count=2 '^go: finding module for package example\.net/y$'
+stderr -count=2 '^go: finding module for package example\.net/z$'
+stderr '^go: found example\.net/x in example\.net/x v0.1.0$'
+
+stderr '^example\.net/m imports\n\texample\.net/w: package example\.net/w provided by example\.net/w at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$'
+stderr '^example\.net/m imports\n\texample\.net/y: package example\.net/y provided by example\.net/y at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$'
+stderr '^example\.net/m imports\n\texample\.net/z: package example\.net/z provided by example\.net/z at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$'
+
+
+go mod tidy -e
+cmp go.mod go.mod.tidye2
+
+go mod tidy -e
+cmp go.mod go.mod.tidye3
+
+go mod tidy -e
+cmp go.mod go.mod.orig
+
+
+# If we upgrade away all of the packages simultaneously, the resulting tidy
+# state converges at "no dependencies", because simultaneously adding all of the
+# packages simultaneously over-upgrades all of the dependencies, and 'go mod
+# tidy' treats "no package can be added" as a terminal state.
+
+go get -d example.net/w@v0.2.0-pre example.net/x@v0.2.0-pre example.net/y@v0.2.0-pre example.net/z@v0.2.0-pre
+go mod tidy -e
+cmp go.mod go.mod.postget
+go mod tidy -e
+cmp go.mod go.mod.postget
+
+
+# The 'tidy' logic for a lazy main module requires more iterations to converge,
+# because it is willing to drop dependencies on non-root modules that do not
+# otherwise provide imported packages.
+#
+# On the first iteration, it adds x.1 as a root, which upgrades z and w,
+# dropping w.1's requirement on y. w.1 was initially a root, so the upgraded
+# w.2-pre is retained as a root.
+#
+# On the second iteration, it adds y.1 as a root, which upgrades w and x,
+# dropping x.1's requirement on z. x.1 was added as a root in the previous step,
+# so the upgraded x.2-pre is retained as a root.
+#
+# On the third iteration, it adds z.1 as a root, which upgrades x and y.
+# x and y were already roots (from the previous steps), so their upgraded versions
+# are retained (not dropped) and the iteration stops.
+#
+# At that point, we have z.1 as a root providing package z,
+# and w, x, and y have all been upgraded to no longer provide any packages.
+# So only z is retained as a new root.
+#
+# (From the above, we can see that in a lazy module we still cycle through the
+# same possible root states, but in a different order from the eager case.)
+#
+# TODO(bcmills): if we retained the upgrades on w, x, and y (since they are
+# lexical prefixes for unresolved packages w, x, and y, respectively), then 'go
+# mod tidy -e' itself would become stable and no longer cycle through states.
+
+cp go.mod.orig go.mod
+go mod edit -go=1.17 go.mod
+cp go.mod go.mod.117
+go mod edit -go=1.17 go.mod.tidye1
+go mod edit -go=1.17 go.mod.tidye2
+go mod edit -go=1.17 go.mod.tidye3
+go mod edit -go=1.17 go.mod.postget
+
+go list -m all
+
+go mod tidy -e
+cmp go.mod go.mod.tidye3
+
+go mod tidy -e
+cmp go.mod go.mod.tidye2
+
+go mod tidy -e
+cmp go.mod go.mod.tidye1
+
+go mod tidy -e
+cmp go.mod go.mod.117
+
+
+# As in the eager case, for the lazy module the fully-upgraded dependency graph
+# becomes empty, and the empty graph is stable.
+
+go get -d example.net/w@v0.2.0-pre example.net/x@v0.2.0-pre example.net/y@v0.2.0-pre example.net/z@v0.2.0-pre
+go mod tidy -e
+cmp go.mod go.mod.postget
+go mod tidy -e
+cmp go.mod go.mod.postget
+
+
+-- m.go --
+package m
+
+import (
+	_ "example.net/w"
+	_ "example.net/x"
+	_ "example.net/y"
+	_ "example.net/z"
+)
+
+-- go.mod --
+module example.net/m
+
+go 1.16
+
+replace (
+	example.net/w v0.1.0 => ./w1
+	example.net/w v0.2.0-pre => ./w2-pre
+	example.net/x v0.1.0 => ./x1
+	example.net/x v0.2.0-pre => ./x2-pre
+	example.net/y v0.1.0 => ./y1
+	example.net/y v0.2.0-pre => ./y2-pre
+	example.net/z v0.1.0 => ./z1
+	example.net/z v0.2.0-pre => ./z2-pre
+)
+
+require example.net/w v0.1.0
+-- go.mod.tidye1 --
+module example.net/m
+
+go 1.16
+
+replace (
+	example.net/w v0.1.0 => ./w1
+	example.net/w v0.2.0-pre => ./w2-pre
+	example.net/x v0.1.0 => ./x1
+	example.net/x v0.2.0-pre => ./x2-pre
+	example.net/y v0.1.0 => ./y1
+	example.net/y v0.2.0-pre => ./y2-pre
+	example.net/z v0.1.0 => ./z1
+	example.net/z v0.2.0-pre => ./z2-pre
+)
+
+require example.net/x v0.1.0
+-- go.mod.tidye2 --
+module example.net/m
+
+go 1.16
+
+replace (
+	example.net/w v0.1.0 => ./w1
+	example.net/w v0.2.0-pre => ./w2-pre
+	example.net/x v0.1.0 => ./x1
+	example.net/x v0.2.0-pre => ./x2-pre
+	example.net/y v0.1.0 => ./y1
+	example.net/y v0.2.0-pre => ./y2-pre
+	example.net/z v0.1.0 => ./z1
+	example.net/z v0.2.0-pre => ./z2-pre
+)
+
+require example.net/y v0.1.0
+-- go.mod.tidye3 --
+module example.net/m
+
+go 1.16
+
+replace (
+	example.net/w v0.1.0 => ./w1
+	example.net/w v0.2.0-pre => ./w2-pre
+	example.net/x v0.1.0 => ./x1
+	example.net/x v0.2.0-pre => ./x2-pre
+	example.net/y v0.1.0 => ./y1
+	example.net/y v0.2.0-pre => ./y2-pre
+	example.net/z v0.1.0 => ./z1
+	example.net/z v0.2.0-pre => ./z2-pre
+)
+
+require example.net/z v0.1.0
+-- go.mod.postget --
+module example.net/m
+
+go 1.16
+
+replace (
+	example.net/w v0.1.0 => ./w1
+	example.net/w v0.2.0-pre => ./w2-pre
+	example.net/x v0.1.0 => ./x1
+	example.net/x v0.2.0-pre => ./x2-pre
+	example.net/y v0.1.0 => ./y1
+	example.net/y v0.2.0-pre => ./y2-pre
+	example.net/z v0.1.0 => ./z1
+	example.net/z v0.2.0-pre => ./z2-pre
+)
+-- w1/go.mod --
+module example.net/w
+
+go 1.16
+
+require (
+	example.net/y v0.2.0-pre
+	example.net/z v0.2.0-pre
+)
+-- w1/w.go --
+package w
+-- w2-pre/go.mod --
+module example.net/w
+
+go 1.16
+-- w2-pre/README.txt --
+Package w has been removed.
+
+-- x1/go.mod --
+module example.net/x
+
+go 1.16
+
+require (
+	example.net/z v0.2.0-pre
+	example.net/w v0.2.0-pre
+)
+-- x1/x.go --
+package x
+-- x2-pre/go.mod --
+module example.net/x
+
+go 1.16
+-- x2-pre/README.txt --
+Package x has been removed.
+
+-- y1/go.mod --
+module example.net/y
+
+go 1.16
+
+require (
+	example.net/w v0.2.0-pre
+	example.net/x v0.2.0-pre
+)
+-- y1/y.go --
+package y
+
+-- y2-pre/go.mod --
+module example.net/y
+
+go 1.16
+-- y2-pre/README.txt --
+Package y has been removed.
+
+-- z1/go.mod --
+module example.net/z
+
+go 1.16
+
+require (
+	example.net/x v0.2.0-pre
+	example.net/y v0.2.0-pre
+)
+-- z1/z.go --
+package z
+
+-- z2-pre/go.mod --
+module example.net/z
+
+go 1.16
+-- z2-pre/README.txt --
+Package z has been removed.
diff --git a/src/cmd/go/testdata/script/mod_tidy_indirect.txt b/src/cmd/go/testdata/script/mod_tidy_indirect.txt
new file mode 100644
index 0000000..1f092b2
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_indirect.txt
@@ -0,0 +1,67 @@
+cp go.mod go.mod.orig
+go mod tidy
+cmp go.mod go.mod.orig
+
+-- go.mod --
+module example.com/tidy
+
+go 1.16
+
+require (
+	example.net/incomplete v0.1.0
+	example.net/indirect v0.2.0 // indirect
+	example.net/toolow v0.1.0
+)
+
+replace (
+	example.net/incomplete v0.1.0 => ./incomplete
+	example.net/indirect v0.1.0 => ./indirect.1
+	example.net/indirect v0.2.0 => ./indirect.2
+	example.net/toolow v0.1.0 => ./toolow
+)
+-- tidy.go --
+package tidy
+
+import (
+	_ "example.net/incomplete"
+	_ "example.net/toolow"
+)
+
+-- incomplete/go.mod --
+module example.net/incomplete
+
+go 1.16
+
+// This module omits a needed requirement on example.net/indirect.
+-- incomplete/incomplete.go --
+package incomplete
+
+import _ "example.net/indirect/newpkg"
+
+-- toolow/go.mod --
+module example.net/toolow
+
+go 1.16
+
+require example.net/indirect v0.1.0
+-- toolow/toolow.go --
+package toolow
+
+import _ "example.net/indirect/oldpkg"
+
+-- indirect.1/go.mod --
+module example.net/indirect
+
+go 1.16
+-- indirect.1/oldpkg/oldpkg.go --
+package oldpkg
+
+
+-- indirect.2/go.mod --
+module example.net/indirect
+
+go 1.16
+-- indirect.2/oldpkg/oldpkg.go --
+package oldpkg
+-- indirect.2/newpkg/newpkg.go --
+package newpkg
diff --git a/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt b/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt
new file mode 100644
index 0000000..9abbabd
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt
@@ -0,0 +1,66 @@
+# Regression test for https://golang.org/issue/46078:
+# 'go mod tidy' should not panic if the main module initially
+# requires an older version of itself.
+
+# A module may require an older version of itself without error. This is
+# inconsistent (the required version is never selected), but we still get
+# a reproducible build list.
+go list -m all
+stdout '^golang.org/issue/46078$'
+
+# 'go mod tidy' should fix this (and not crash).
+go mod tidy
+
+
+# We prune out redundant roots very early on in module loading, and at that
+# point the indirect requirement on example.net/x v0.1.0 appears to be
+# irrelevant. It should be pruned out; when the import of "example.net/x" is
+# later resolved, it should resolve at the latest version (v0.2.0), not the
+# version implied by the (former) misleading requirement on the older version of
+# the main module.
+
+cmp go.mod go.mod.tidy
+
+
+-- go.mod --
+module golang.org/issue/46078
+
+go 1.17
+
+replace (
+	example.net/x v0.1.0 => ./x
+	example.net/x v0.2.0 => ./x
+	golang.org/issue/46078 v0.1.0 => ./old
+)
+
+require golang.org/issue/46078 v0.1.0
+-- go.mod.tidy --
+module golang.org/issue/46078
+
+go 1.17
+
+replace (
+	example.net/x v0.1.0 => ./x
+	example.net/x v0.2.0 => ./x
+	golang.org/issue/46078 v0.1.0 => ./old
+)
+
+require example.net/x v0.2.0
+-- issue46078/issue.go --
+package issue46078
+
+import _ "example.net/x"
+
+-- old/go.mod --
+module golang.org/issue/46078
+
+go 1.17
+
+require example.net/x v0.1.0
+
+-- x/go.mod --
+module example.net/x
+
+go 1.17
+-- x/x.go --
+package x
diff --git a/src/cmd/go/testdata/script/mod_tidy_newroot.txt b/src/cmd/go/testdata/script/mod_tidy_newroot.txt
new file mode 100644
index 0000000..3abd5ef
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_newroot.txt
@@ -0,0 +1,82 @@
+# https://golang.org/issue/45952: 'go mod tidy' in an eager module failed due
+# to an erroneous check on root completeness.
+#
+# Per the issue report:
+# > It may have to do with:
+# >
+# > package A imports package B in go.mod, which imports package C in its own go.mod
+# > package A drops direct dependency on package B …
+#
+# We infer from that that package C is still needed by some other indirect
+# dependency, and must be at a higher version than what is required by that
+# dependency (or else no new root would be needed). An additional package D
+# in its own module satisfies that condition, reproducing the bug.
+
+go mod tidy
+cmp go.mod go.mod.tidy
+
+-- go.mod --
+module example.net/a
+
+go 1.16
+
+require (
+	example.net/b v0.1.0
+	example.net/d v0.1.0
+)
+
+replace (
+	example.net/b v0.1.0 => ./b
+	example.net/c v0.1.0 => ./c
+	example.net/c v0.2.0 => ./c
+	example.net/d v0.1.0 => ./d
+)
+-- go.mod.tidy --
+module example.net/a
+
+go 1.16
+
+require (
+	example.net/c v0.2.0 // indirect
+	example.net/d v0.1.0
+)
+
+replace (
+	example.net/b v0.1.0 => ./b
+	example.net/c v0.1.0 => ./c
+	example.net/c v0.2.0 => ./c
+	example.net/d v0.1.0 => ./d
+)
+-- a.go --
+package a
+
+import _ "example.net/d"
+
+-- b/go.mod --
+module example.net/b
+
+go 1.16
+
+require example.net/c v0.2.0
+-- b/b.go --
+package b
+
+import _ "example.net/c"
+
+-- c/go.mod --
+module example.net/c
+
+go 1.16
+-- c/c.go --
+package c
+
+-- d/go.mod --
+module example.net/d
+
+go 1.16
+
+require example.net/c v0.1.0
+-- d/d.go --
+package d
+
+import _ "example.net/c"
diff --git a/src/cmd/go/testdata/script/mod_tidy_oldgo.txt b/src/cmd/go/testdata/script/mod_tidy_oldgo.txt
new file mode 100644
index 0000000..0e88b06
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_oldgo.txt
@@ -0,0 +1,21 @@
+# Modules were introduced in Go 1.11, but for various reasons users may
+# decide to declare a (much!) older go version in their go.mod file.
+# Modules with very old versions should not be rejected, and should have
+# the same module-graph semantics as in Go 1.11.
+
+cp go.mod go.mod.orig
+go mod tidy
+cmp go.mod go.mod.orig
+
+-- go.mod --
+module example.com/legacy/go1
+
+go 1.0
+
+require golang.org/x/text v0.3.0
+-- main.go --
+package main
+
+import _ "golang.org/x/text/language"
+
+func main() {}
diff --git a/src/cmd/go/testdata/script/mod_tidy_replace.txt b/src/cmd/go/testdata/script/mod_tidy_replace.txt
index dd99438..297f6a6 100644
--- a/src/cmd/go/testdata/script/mod_tidy_replace.txt
+++ b/src/cmd/go/testdata/script/mod_tidy_replace.txt
@@ -136,3 +136,10 @@
 )
 
 replace not-rsc.io/quote/v3 => rsc.io/quote/v3 v3.0.0
+-- multiple-paths/use.go --
+package quoter
+
+import (
+	_ "not-rsc.io/quote/v3"
+	_ "rsc.io/quote/v3"
+)
diff --git a/src/cmd/go/testdata/script/mod_tidy_replace_old.txt b/src/cmd/go/testdata/script/mod_tidy_replace_old.txt
new file mode 100644
index 0000000..cfd3792
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_replace_old.txt
@@ -0,0 +1,34 @@
+# Regression test for https://golang.org/issue/46659.
+#
+# If a 'replace' directive specifies an older-than-selected version of a module,
+# 'go mod tidy' shouldn't try to add that version to the build list to resolve a
+# missing package: it won't be selected, and would cause the module loader to
+# loop indefinitely trying to resolve the package.
+
+cp go.mod go.mod.orig
+
+! go mod tidy
+! stderr panic
+stderr '^golang\.org/issue46659 imports\n\texample\.com/missingpkg/deprecated: package example\.com/missingpkg/deprecated provided by example\.com/missingpkg at latest version v1\.0\.0 but not at required version v1\.0\.1-beta$'
+
+go mod tidy -e
+
+cmp go.mod go.mod.orig
+
+-- go.mod --
+module golang.org/issue46659
+
+go 1.17
+
+replace example.com/missingpkg v1.0.1-alpha => example.com/missingpkg v1.0.0
+
+require example.com/usemissingpre v1.0.0
+
+require example.com/missingpkg v1.0.1-beta // indirect
+-- m.go --
+package m
+
+import (
+	_ "example.com/missingpkg/deprecated"
+	_ "example.com/usemissingpre"
+)
diff --git a/src/cmd/go/testdata/script/mod_tidy_symlink_issue35941.txt b/src/cmd/go/testdata/script/mod_tidy_symlink_issue35941.txt
new file mode 100644
index 0000000..d4658c6
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_symlink_issue35941.txt
@@ -0,0 +1,36 @@
+env GO111MODULE=on
+[!symlink] skip
+
+cd m
+symlink symlink -> ../outside
+
+cp go.mod go.mod.orig
+
+# Issue 35941: suppress symlink warnings when running 'go mod tidy'.
+# 'go mod tidy' should not scan packages in symlinked subdirectories.
+go mod tidy
+! stderr 'warning: ignoring symlink'
+cmp go.mod go.mod.orig
+
+! go build ./symlink
+stderr '^symlink[\\/]symlink.go:3:8: module example.net/unresolved provides package example.net/unresolved and is replaced but not required; to add it:\n\tgo get example.net/unresolved@v0.1.0$'
+
+-- m/go.mod --
+module example.net/m
+
+go 1.16
+
+replace example.net/unresolved v0.1.0 => ../unresolved
+-- m/a.go --
+package a
+-- outside/symlink.go --
+package symlink
+
+import _ "example.net/unresolved"
+-- unresolved/go.mod --
+module example.net/unresolved
+
+go 1.16
+-- unresolved/unresolved.go --
+// Package unresolved exists, but 'go mod tidy' won't add it.
+package unresolved
diff --git a/src/cmd/go/testdata/script/mod_tidy_too_new.txt b/src/cmd/go/testdata/script/mod_tidy_too_new.txt
new file mode 100644
index 0000000..b9c53b5
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_too_new.txt
@@ -0,0 +1,57 @@
+# https://golang.org/issue/46142: 'go mod tidy' should error out if the version
+# in the go.mod file is newer than the most recent supported version.
+
+cp go.mod go.mod.orig
+
+
+# If the go.mod file specifies an unsupported Go version, 'go mod tidy' should
+# refuse to edit it: we don't know what a tidy go.mod file for that version
+# would look like.
+
+! go mod tidy
+stderr 'go mod tidy: go.mod file indicates go 2000.0, but maximum supported version is '$goversion'$'
+cmp go.mod go.mod.orig
+
+
+# The -e flag should push past the error and edit the file anyway,
+# but preserve the too-high version.
+
+cp go.mod.orig go.mod
+go mod tidy -e
+stderr 'go mod tidy: go.mod file indicates go 2000.0, but maximum supported version is '$goversion'$'
+cmp go.mod go.mod.tidy
+
+
+# Explicitly switching to a supported version should suppress the error completely.
+
+cp go.mod.orig go.mod
+go mod tidy -go=1.17
+! stderr 'maximum supported version'
+go mod edit -go=1.17 go.mod.tidy
+cmp go.mod go.mod.tidy
+
+
+-- go.mod --
+module example.net/from/the/future
+
+go 2000.0
+
+replace example.net/m v0.0.0 => ./m
+-- go.mod.tidy --
+module example.net/from/the/future
+
+go 2000.0
+
+replace example.net/m v0.0.0 => ./m
+
+require example.net/m v0.0.0
+-- x.go --
+package x
+
+import "example.net/m"
+-- m/go.mod --
+module example.net/m
+
+go 1.17
+-- m/m.go --
+package m
diff --git a/src/cmd/go/testdata/script/mod_tidy_version.txt b/src/cmd/go/testdata/script/mod_tidy_version.txt
new file mode 100644
index 0000000..3bc97bc
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_version.txt
@@ -0,0 +1,262 @@
+# https://golang.org/issue/45094: 'go mod tidy' now accepts a '-go' flag
+# to change the language version in use.
+#
+# The package import graph used in this test looks like:
+#
+# m --- a --- b
+#             |
+#             b_test --- c
+#                        |
+#                        c_test --- d
+#
+# The module diagram looks like:
+#
+# m --- a --- b
+# |
+# + --- c
+# |
+# + --- d
+#
+# Module b omits its dependency on c, and module c omits its dependency on d.
+#
+# In go 1.15, the tidy main module must require a (because it is direct),
+# c (because it is a missing test dependency of an imported package),
+# and d (because it is a missing transitive test dependency).
+#
+# In go 1.16, the tidy main module can omit d because it is no longer
+# included in "all".
+#
+# In go 1.17, the main module must explicitly require b
+# (because it is transitively imported by the main module).
+
+
+cp go.mod go.mod.orig
+
+
+# An invalid argument should be rejected.
+
+! go mod tidy -go=bananas
+stderr '^invalid value "bananas" for flag -go: expecting a Go version like "'$goversion'"$'
+cmp go.mod go.mod.orig
+
+! go mod tidy -go=0.9
+stderr '^invalid value "0.9" for flag -go: expecting a Go version like "'$goversion'"$'
+
+! go mod tidy -go=2000.0
+stderr '^invalid value "2000.0" for flag -go: maximum supported Go version is '$goversion'$'
+
+
+# Supported versions should change the go.mod file to be tidy according to the
+# indicated version.
+
+go mod tidy -go=1.15
+cmp go.mod go.mod.115
+
+go mod tidy
+cmp go.mod go.mod.115
+
+
+go mod tidy -go=1.16
+cmp go.mod go.mod.116
+
+go mod tidy
+cmp go.mod go.mod.116
+
+
+go mod tidy -go=1.17
+cmp go.mod go.mod.117
+
+go mod tidy
+cmp go.mod go.mod.117
+
+
+# If we downgrade back to 1.15, we should re-resolve d to v0.2.0 instead
+# of the original v0.1.0 (because the original requirement is lost).
+
+go mod tidy -go=1.15
+cmp go.mod go.mod.115-2
+
+
+# -go= (with an empty argument) maintains the existing version or adds the
+#  default version (just like omitting the flag).
+
+go mod tidy -go=''
+cmp go.mod go.mod.115-2
+
+cp go.mod.orig go.mod
+go mod tidy -go=''
+cmpenv go.mod go.mod.latest
+
+
+
+-- go.mod --
+module example.com/m
+
+require example.net/a v0.1.0
+
+require (
+	example.net/c v0.1.0 // indirect
+	example.net/d v0.1.0 // indirect
+)
+
+replace (
+	example.net/a v0.1.0 => ./a
+	example.net/a v0.2.0 => ./a
+	example.net/b v0.1.0 => ./b
+	example.net/b v0.2.0 => ./b
+	example.net/c v0.1.0 => ./c
+	example.net/c v0.2.0 => ./c
+	example.net/d v0.1.0 => ./d
+	example.net/d v0.2.0 => ./d
+)
+-- m.go --
+package m
+
+import _ "example.net/a"
+
+-- go.mod.115 --
+module example.com/m
+
+go 1.15
+
+require example.net/a v0.1.0
+
+require (
+	example.net/c v0.1.0 // indirect
+	example.net/d v0.1.0 // indirect
+)
+
+replace (
+	example.net/a v0.1.0 => ./a
+	example.net/a v0.2.0 => ./a
+	example.net/b v0.1.0 => ./b
+	example.net/b v0.2.0 => ./b
+	example.net/c v0.1.0 => ./c
+	example.net/c v0.2.0 => ./c
+	example.net/d v0.1.0 => ./d
+	example.net/d v0.2.0 => ./d
+)
+-- go.mod.115-2 --
+module example.com/m
+
+go 1.15
+
+require example.net/a v0.1.0
+
+require (
+	example.net/c v0.1.0 // indirect
+	example.net/d v0.2.0 // indirect
+)
+
+replace (
+	example.net/a v0.1.0 => ./a
+	example.net/a v0.2.0 => ./a
+	example.net/b v0.1.0 => ./b
+	example.net/b v0.2.0 => ./b
+	example.net/c v0.1.0 => ./c
+	example.net/c v0.2.0 => ./c
+	example.net/d v0.1.0 => ./d
+	example.net/d v0.2.0 => ./d
+)
+-- go.mod.116 --
+module example.com/m
+
+go 1.16
+
+require example.net/a v0.1.0
+
+require example.net/c v0.1.0 // indirect
+
+replace (
+	example.net/a v0.1.0 => ./a
+	example.net/a v0.2.0 => ./a
+	example.net/b v0.1.0 => ./b
+	example.net/b v0.2.0 => ./b
+	example.net/c v0.1.0 => ./c
+	example.net/c v0.2.0 => ./c
+	example.net/d v0.1.0 => ./d
+	example.net/d v0.2.0 => ./d
+)
+-- go.mod.117 --
+module example.com/m
+
+go 1.17
+
+require example.net/a v0.1.0
+
+require (
+	example.net/b v0.1.0 // indirect
+	example.net/c v0.1.0 // indirect
+)
+
+replace (
+	example.net/a v0.1.0 => ./a
+	example.net/a v0.2.0 => ./a
+	example.net/b v0.1.0 => ./b
+	example.net/b v0.2.0 => ./b
+	example.net/c v0.1.0 => ./c
+	example.net/c v0.2.0 => ./c
+	example.net/d v0.1.0 => ./d
+	example.net/d v0.2.0 => ./d
+)
+-- go.mod.latest --
+module example.com/m
+
+go $goversion
+
+require example.net/a v0.1.0
+
+require (
+	example.net/b v0.1.0 // indirect
+	example.net/c v0.1.0 // indirect
+)
+
+replace (
+	example.net/a v0.1.0 => ./a
+	example.net/a v0.2.0 => ./a
+	example.net/b v0.1.0 => ./b
+	example.net/b v0.2.0 => ./b
+	example.net/c v0.1.0 => ./c
+	example.net/c v0.2.0 => ./c
+	example.net/d v0.1.0 => ./d
+	example.net/d v0.2.0 => ./d
+)
+-- a/go.mod --
+module example.net/a
+
+go 1.15
+
+require example.net/b v0.1.0
+-- a/a.go --
+package a
+
+import _ "example.net/b"
+
+-- b/go.mod --
+module example.net/b
+
+go 1.15
+-- b/b.go --
+package b
+-- b/b_test.go --
+package b_test
+
+import _ "example.net/c"
+
+-- c/go.mod --
+module example.net/c
+
+go 1.15
+-- c/c.go --
+package c
+-- c/c_test.go --
+package c_test
+
+import _ "example.net/d"
+
+-- d/go.mod --
+module example.net/d
+
+go 1.15
+-- d/d.go --
+package d
diff --git a/src/cmd/go/testdata/script/mod_update_sum_readonly.txt b/src/cmd/go/testdata/script/mod_update_sum_readonly.txt
new file mode 100644
index 0000000..41f12e4
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_update_sum_readonly.txt
@@ -0,0 +1,34 @@
+# When finding the latest version of a module, we should not download version
+# contents. Previously, we downloaded .zip files to determine whether a real
+# .mod file was present in order to decide whether +incompatible versions
+# could be "latest".
+#
+# Verifies #47377.
+
+# rsc.io/breaker has two versions, neither of which has a .mod file.
+go list -m -versions rsc.io/breaker
+stdout '^rsc.io/breaker v1.0.0 v2.0.0\+incompatible$'
+go mod download rsc.io/breaker@v1.0.0
+! grep '^go' $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v1.0.0.mod
+go mod download rsc.io/breaker@v2.0.0+incompatible
+! grep '^go' $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v2.0.0+incompatible.mod
+
+# Delete downloaded .zip files.
+go clean -modcache
+
+# Check for updates.
+go list -m -u rsc.io/breaker
+stdout '^rsc.io/breaker v1.0.0 \[v2.0.0\+incompatible\]$'
+
+# We should not have downloaded zips.
+! exists $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v1.0.0.zip
+! exists $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v2.0.0+incompatible.zip
+
+-- go.mod --
+module m
+
+go 1.16
+
+require rsc.io/breaker v1.0.0
+-- go.sum --
+rsc.io/breaker v1.0.0/go.mod h1:s5yxDXvD88U1/ESC23I2FK3Lkv4YIKaB1ij/Hbm805g=
diff --git a/src/cmd/go/testdata/script/mod_vendor_gomod.txt b/src/cmd/go/testdata/script/mod_vendor_gomod.txt
new file mode 100644
index 0000000..3f6ea35
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_vendor_gomod.txt
@@ -0,0 +1,38 @@
+# https://golang.org/issue/42970: As of Go 1.17, go.mod and go.sum files should
+# be stripped from vendored dependencies.
+
+go mod vendor
+cd vendor/example.net/x
+go list all
+! stdout '^example.net/m'
+stdout '^example.net/x$'
+exists ./go.sum
+
+cd ../../..
+go mod edit -go=1.17
+go mod vendor
+cd vendor/example.net/x
+go list all
+stdout '^example.net/m$'
+stdout '^example.net/x$'
+! exists ./go.sum
+
+-- go.mod --
+module example.net/m
+
+go 1.16
+
+require example.net/x v0.1.0
+
+replace example.net/x v0.1.0 => ./x
+-- m.go --
+package m
+
+import _ "example.net/x"
+-- x/go.mod --
+module example.net/x
+
+go 1.16
+-- x/go.sum --
+-- x/x.go --
+package x
diff --git a/src/cmd/go/testdata/script/mod_vendor_goversion.txt b/src/cmd/go/testdata/script/mod_vendor_goversion.txt
new file mode 100644
index 0000000..aa4cb41
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_vendor_goversion.txt
@@ -0,0 +1,102 @@
+# https://golang.org/issue/36876: As of Go 1.17, vendor/modules.txt should
+# indicate the language version used by each dependency.
+
+[short] skip
+
+
+# Control case: without a vendor directory, need117 builds and bad114 doesn't.
+
+go build example.net/need117
+! go build example.net/bad114
+stderr '^bad114[/\\]bad114.go:15:2: duplicate method Y$'
+
+
+# With a vendor/modules.txt lacking language versions, the world is topsy-turvy,
+# because we have to guess a uniform version for everything.
+#
+# We always guess Go 1.16, because that was the last version for which
+# 'go mod vendor' failed to record dependency versions, and it has most of
+# the language features added since modules were introduced in Go 1.11.
+#
+# Even so, modules that declare 'go 1.17' and use 1.17 features spuriously fail
+# to build, and modules that declare an older version and use features from a
+# newer one spuriously build (instead of failing as they ought to).
+
+go mod vendor
+
+! grep 1.17 vendor/modules.txt
+! go build example.net/need117
+stderr '^vendor[/\\]example\.net[/\\]need117[/\\]need117.go:5:18: .*\n\tconversion of slices to array pointers only supported as of -lang=go1\.17'
+
+! grep 1.13 vendor/modules.txt
+go build example.net/bad114
+
+
+# Upgrading the main module to 1.17 adds version annotations.
+# Then everything is once again consistent with the non-vendored world.
+
+go mod edit -go=1.17
+go mod vendor
+
+grep '^## explicit; go 1.17$' vendor/modules.txt
+go build example.net/need117
+
+grep '^## explicit; go 1.13$' vendor/modules.txt
+! go build example.net/bad114
+stderr '^vendor[/\\]example\.net[/\\]bad114[/\\]bad114.go:15:2: duplicate method Y$'
+
+-- go.mod --
+module example.net/m
+
+go 1.16
+
+require (
+	example.net/bad114 v0.1.0
+	example.net/need117 v0.1.0
+)
+
+replace (
+	example.net/bad114 v0.1.0 => ./bad114
+	example.net/need117 v0.1.0 => ./need117
+)
+-- m.go --
+package m
+
+import _ "example.net/bad114"
+import _ "example.net/need117"
+
+-- bad114/go.mod --
+// Module bad114 requires Go 1.14 or higher, but declares Go 1.13.
+module example.net/bad114
+
+go 1.13
+-- bad114/bad114.go --
+package bad114
+
+type XY interface {
+	X()
+	Y()
+}
+
+type YZ interface {
+	Y()
+	Z()
+}
+
+type XYZ interface {
+	XY
+	YZ
+}
+
+-- need117/go.mod --
+// Module need117 requires Go 1.17 or higher.
+module example.net/need117
+
+go 1.17
+-- need117/need117.go --
+package need117
+
+func init() {
+		 s := make([]byte, 4)
+		 _ = (*[4]byte)(s)
+}
diff --git a/src/cmd/go/testdata/script/mod_vendor_issue46867.txt b/src/cmd/go/testdata/script/mod_vendor_issue46867.txt
new file mode 100644
index 0000000..38ae87b
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_vendor_issue46867.txt
@@ -0,0 +1,31 @@
+# Regression test for golang.org/issue/46867:
+# 'go mod vendor' on Windows attempted to open and copy
+# files from directories outside of the module.
+
+cd subdir
+go mod vendor
+! exists vendor/example.net/NOTICE
+exists vendor/example.net/m/NOTICE
+
+-- subdir/go.mod --
+module golang.org/issue46867
+
+go 1.17
+
+replace example.net/m v0.1.0 => ./m
+
+require example.net/m v0.1.0
+-- subdir/issue.go --
+package issue
+
+import _ "example.net/m/n"
+-- subdir/m/go.mod --
+module example.net/m
+
+go 1.17
+-- subdir/m/n/n.go --
+package n
+-- subdir/m/NOTICE --
+This notice is in module m and SHOULD be vendored.
+-- subdir/NOTICE --
+This notice is outside of module m and SHOULD NOT be vendored.
diff --git a/src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt b/src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt
new file mode 100644
index 0000000..3f6f5c5
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt
@@ -0,0 +1,29 @@
+# 'go list -mod=vendor' should succeed even when go.mod contains redundant
+# requirements. Verifies #47565.
+go list -mod=vendor
+
+-- go.mod --
+module m
+
+go 1.17
+
+require example.com/m v0.0.0
+require example.com/m v0.0.0
+
+replace example.com/m v0.0.0 => ./m
+-- m/go.mod --
+module example.com/m
+
+go 1.17
+-- m/m.go --
+package m
+-- use.go --
+package use
+
+import _ "example.com/m"
+-- vendor/example.com/m/m.go --
+package m
+-- vendor/modules.txt --
+# example.com/m v0.0.0 => ./m
+## explicit; go 1.17
+example.com/m
diff --git a/src/cmd/go/testdata/script/test_cache_inputs.txt b/src/cmd/go/testdata/script/test_cache_inputs.txt
index 50486e1..d694a30 100644
--- a/src/cmd/go/testdata/script/test_cache_inputs.txt
+++ b/src/cmd/go/testdata/script/test_cache_inputs.txt
@@ -99,6 +99,15 @@
 go test testcache -run=ExternalFile
 stdout '\(cached\)'
 
+# The -benchtime flag without -bench should not affect caching.
+go test testcache -run=Benchtime -benchtime=1x
+go test testcache -run=Benchtime -benchtime=1x
+stdout '\(cached\)'
+
+go test testcache -run=Benchtime -bench=Benchtime -benchtime=1x
+go test testcache -run=Benchtime -bench=Benchtime -benchtime=1x
+! stdout '\(cached\)'
+
 # Executables within GOROOT and GOPATH should affect caching,
 # even if the test does not stat them explicitly.
 
@@ -228,6 +237,10 @@
 func TestOSArgs(t *testing.T) {
 	t.Log(os.Args)
 }
+
+func TestBenchtime(t *testing.T) {
+}
+
 -- mkold.go --
 package main
 
diff --git a/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt b/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt
index 3f7360b..f8faa93 100644
--- a/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt
+++ b/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt
@@ -14,7 +14,7 @@
 stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"=== CONT  TestChattyParallel/sub-2\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"    chatty_parallel_test.go:38: error from sub-2\\n"}'
 
 -- chatty_parallel_test.go --
-package chatty_paralell_test
+package chatty_parallel_test
 
 import (
 	"testing"
@@ -22,7 +22,7 @@
 	"flag"
 )
 
-// This test ensures the the order of CONT lines in parallel chatty tests.
+// This test ensures the order of CONT lines in parallel chatty tests.
 func TestChattyParallel(t *testing.T) {
 	t.Parallel()
 
diff --git a/src/cmd/go/testdata/script/test_chatty_parallel_success.txt b/src/cmd/go/testdata/script/test_chatty_parallel_success.txt
index 4a86d74..63034fa 100644
--- a/src/cmd/go/testdata/script/test_chatty_parallel_success.txt
+++ b/src/cmd/go/testdata/script/test_chatty_parallel_success.txt
@@ -13,7 +13,7 @@
 stdout -count=2 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"=== CONT  TestChattyParallel/sub-2\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"    chatty_parallel_test.go:32: this is sub-2\\n"}'
 
 -- chatty_parallel_test.go --
-package chatty_paralell_test
+package chatty_parallel_test
 
 import (
 	"testing"
@@ -21,7 +21,7 @@
 	"flag"
 )
 
-// This test ensures the the order of CONT lines in parallel chatty tests.
+// This test ensures the order of CONT lines in parallel chatty tests.
 func TestChattyParallel(t *testing.T) {
 	t.Parallel()
 
diff --git a/src/cmd/go/testdata/script/test_chatty_parallel_success_sleepy.txt b/src/cmd/go/testdata/script/test_chatty_parallel_success_sleepy.txt
index 5952a87..e651a7e 100644
--- a/src/cmd/go/testdata/script/test_chatty_parallel_success_sleepy.txt
+++ b/src/cmd/go/testdata/script/test_chatty_parallel_success_sleepy.txt
@@ -5,7 +5,7 @@
 stdout '--- PASS: TestFast \([0-9.]{4}s\)\n=== CONT  TestSlow\n    chatty_parallel_test.go:31: this is the second TestSlow log\n--- PASS: TestSlow \([0-9.]{4}s\)'
 
 -- chatty_parallel_test.go --
-package chatty_paralell_test
+package chatty_parallel_test
 
 import (
 	"testing"
diff --git a/src/cmd/go/testdata/script/test_finished_subtest_goroutines.txt b/src/cmd/go/testdata/script/test_finished_subtest_goroutines.txt
new file mode 100644
index 0000000..8db821e
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_finished_subtest_goroutines.txt
@@ -0,0 +1,52 @@
+# Regression test for https://golang.org/issue/45127:
+# Goroutines for completed parallel subtests should exit immediately,
+# not block until earlier subtests have finished.
+
+[short] skip
+
+! go test .
+stdout 'panic: slow failure'
+! stdout '\[chan send'
+
+-- go.mod --
+module golang.org/issue45127
+
+go 1.16
+-- issue45127_test.go --
+package main
+
+import (
+	"fmt"
+	"runtime"
+	"runtime/debug"
+	"sync"
+	"testing"
+)
+
+func TestTestingGoroutineLeak(t *testing.T) {
+	debug.SetTraceback("all")
+
+	var wg sync.WaitGroup
+	const nFast = 10
+
+	t.Run("slow", func(t *testing.T) {
+		t.Parallel()
+		wg.Wait()
+		for i := 0; i < nFast; i++ {
+			// If the subtest goroutines are going to park on the channel
+			// send, allow them to park now. If they're not going to park,
+			// make sure they have had a chance to run to completion so
+			// that they aren't spuriously parked when we panic.
+			runtime.Gosched()
+		}
+		panic("slow failure")
+	})
+
+	wg.Add(nFast)
+	for i := 0; i < nFast; i++ {
+		t.Run(fmt.Sprintf("leaky%d", i), func(t *testing.T) {
+			t.Parallel()
+			wg.Done()
+		})
+	}
+}
diff --git a/src/cmd/go/testdata/script/test_overlay.txt b/src/cmd/go/testdata/script/test_overlay.txt
new file mode 100644
index 0000000..b6bdc11
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_overlay.txt
@@ -0,0 +1,24 @@
+[short] skip
+
+cd $WORK/gopath/src/foo
+go test -list=. -overlay=overlay.json .
+stdout 'TestBar'
+
+-- go.mod --
+module test.pkg
+-- foo/foo_test.go --
+package foo
+
+import "testing"
+
+func TestFoo(t *testing.T) { }
+-- tmp/bar_test.go --
+package foo
+
+import "testing"
+
+func TestBar(t *testing.T) {
+	t.Fatal("dummy failure")
+}
+-- foo/overlay.json --
+{"Replace": {"foo_test.go": "../tmp/bar_test.go"}}
diff --git a/src/cmd/go/testdata/script/test_race_install_cgo.txt b/src/cmd/go/testdata/script/test_race_install_cgo.txt
index 3f4eb90..e1fe4f2 100644
--- a/src/cmd/go/testdata/script/test_race_install_cgo.txt
+++ b/src/cmd/go/testdata/script/test_race_install_cgo.txt
@@ -2,8 +2,6 @@
 
 [!race] skip
 
-[!darwin] ! stale cmd/cgo  # The darwin builders are spuriously stale; see #33598.
-
 env GOBIN=$WORK/bin
 go install m/mtime m/sametime
 
diff --git a/src/cmd/go/testdata/script/test_script_cmdcd.txt b/src/cmd/go/testdata/script/test_script_cmdcd.txt
new file mode 100644
index 0000000..6e6f67e
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_script_cmdcd.txt
@@ -0,0 +1,13 @@
+# Tests that after a cd command, where usually the UNIX path separator is used,
+# a match against $PWD does not fail on Windows.
+
+cd $WORK/a/b/c/pkg
+
+go list -find -f {{.Root}}
+stdout $PWD
+
+-- $WORK/a/b/c/pkg/go.mod --
+module pkg
+
+-- $WORK/a/b/c/pkg/pkg.go --
+package pkg
diff --git a/src/cmd/go/testdata/script/test_shuffle.txt b/src/cmd/go/testdata/script/test_shuffle.txt
new file mode 100644
index 0000000..3a50605
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_shuffle.txt
@@ -0,0 +1,148 @@
+# Shuffle order of tests and benchmarks
+
+# Run tests
+go test -v foo_test.go
+! stdout '-test.shuffle '
+stdout '(?s)TestOne(.*)TestTwo(.*)TestThree'
+
+go test -v -shuffle=off foo_test.go
+! stdout '-test.shuffle '
+stdout '(?s)TestOne(.*)TestTwo(.*)TestThree'
+
+go test -v -shuffle=42 foo_test.go
+stdout '^-test.shuffle 42'
+stdout '(?s)TestThree(.*)TestOne(.*)TestTwo'
+
+go test -v -shuffle=43 foo_test.go
+stdout '^-test.shuffle 43'
+stdout '(?s)TestThree(.*)TestTwo(.*)TestOne'
+
+go test -v -shuffle=44 foo_test.go
+stdout '^-test.shuffle 44'
+stdout '(?s)TestOne(.*)TestThree(.*)TestTwo'
+
+go test -v -shuffle=0 foo_test.go
+stdout '^-test.shuffle 0'
+stdout '(?s)TestTwo(.*)TestOne(.*)TestThree'
+
+go test -v -shuffle -1 foo_test.go
+stdout '^-test.shuffle -1'
+stdout '(?s)TestThree(.*)TestOne(.*)TestTwo'
+
+go test -v -shuffle=on foo_test.go
+stdout '^-test.shuffle '
+stdout '(?s)=== RUN   TestOne(.*)--- PASS: TestOne'
+stdout '(?s)=== RUN   TestTwo(.*)--- PASS: TestTwo'
+stdout '(?s)=== RUN   TestThree(.*)--- PASS: TestThree'
+
+
+# Run tests and benchmarks
+go test -v -bench=. foo_test.go
+! stdout '-test.shuffle '
+stdout '(?s)TestOne(.*)TestTwo(.*)TestThree(.*)BenchmarkOne(.*)BenchmarkTwo(.*)BenchmarkThree'
+
+go test -v -bench=. -shuffle=off foo_test.go
+! stdout '-test.shuffle '
+stdout '(?s)TestOne(.*)TestTwo(.*)TestThree(.*)BenchmarkOne(.*)BenchmarkTwo(.*)BenchmarkThree'
+
+go test -v -bench=. -shuffle=42 foo_test.go
+stdout '^-test.shuffle 42'
+stdout '(?s)TestThree(.*)TestOne(.*)TestTwo(.*)BenchmarkThree(.*)BenchmarkOne(.*)BenchmarkTwo'
+
+go test -v -bench=. -shuffle=43 foo_test.go
+stdout '^-test.shuffle 43'
+stdout '(?s)TestThree(.*)TestTwo(.*)TestOne(.*)BenchmarkThree(.*)BenchmarkOne(.*)BenchmarkTwo'
+
+go test -v -bench=. -shuffle=44 foo_test.go
+stdout '^-test.shuffle 44'
+stdout '(?s)TestOne(.*)TestThree(.*)TestTwo(.*)BenchmarkTwo(.*)BenchmarkOne(.*)BenchmarkThree'
+
+go test -v -bench=. -shuffle=0 foo_test.go
+stdout '^-test.shuffle 0'
+stdout '(?s)TestTwo(.*)TestOne(.*)TestThree(.*)BenchmarkThree(.*)BenchmarkOne(.*)BenchmarkTwo'
+
+go test -v -bench=. -shuffle -1 foo_test.go
+stdout '^-test.shuffle -1'
+stdout '(?s)TestThree(.*)TestOne(.*)TestTwo(.*)BenchmarkOne(.*)BenchmarkThree(.*)BenchmarkTwo'
+
+go test -v -bench=. -shuffle=on foo_test.go
+stdout '^-test.shuffle '
+stdout '(?s)=== RUN   TestOne(.*)--- PASS: TestOne'
+stdout '(?s)=== RUN   TestTwo(.*)--- PASS: TestTwo'
+stdout '(?s)=== RUN   TestThree(.*)--- PASS: TestThree'
+stdout -count=2 'BenchmarkOne'
+stdout -count=2 'BenchmarkTwo'
+stdout -count=2 'BenchmarkThree'
+
+
+# When running go test -count=N, each of the N runs distinct runs should maintain the same
+# shuffled order of these tests.
+go test -v -shuffle=43 -count=4 foo_test.go
+stdout '^-test.shuffle 43'
+stdout '(?s)TestThree(.*)TestTwo(.*)TestOne(.*)TestThree(.*)TestTwo(.*)TestOne(.*)TestThree(.*)TestTwo(.*)TestOne(.*)TestThree(.*)TestTwo(.*)TestOne'
+
+go test -v -bench=. -shuffle=44 -count=2 foo_test.go
+stdout '^-test.shuffle 44'
+stdout '(?s)TestOne(.*)TestThree(.*)TestTwo(.*)TestOne(.*)TestThree(.*)TestTwo(.*)BenchmarkTwo(.*)BenchmarkOne(.*)BenchmarkThree(.*)'
+
+
+# The feature should work with test binaries as well
+go test -c
+exec ./m.test -test.shuffle=off
+! stdout '^-test.shuffle '
+
+exec ./m.test -test.shuffle=on
+stdout '^-test.shuffle '
+
+exec ./m.test -test.v -test.bench=. -test.shuffle=0 foo_test.go
+stdout '^-test.shuffle 0'
+stdout '(?s)TestTwo(.*)TestOne(.*)TestThree(.*)BenchmarkThree(.*)BenchmarkOne(.*)BenchmarkTwo'
+
+exec ./m.test -test.v -test.bench=. -test.shuffle=123 foo_test.go
+stdout '^-test.shuffle 123'
+stdout '(?s)TestThree(.*)TestOne(.*)TestTwo(.*)BenchmarkThree(.*)BenchmarkTwo(.*)BenchmarkOne'
+
+exec ./m.test -test.v -test.bench=. -test.shuffle=-1 foo_test.go
+stdout '^-test.shuffle -1'
+stdout '(?s)TestThree(.*)TestOne(.*)TestTwo(.*)BenchmarkOne(.*)BenchmarkThree(.*)BenchmarkTwo'
+
+exec ./m.test -test.v -test.bench=. -test.shuffle=44 -test.count=2 foo_test.go
+stdout '^-test.shuffle 44'
+stdout '(?s)TestOne(.*)TestThree(.*)TestTwo(.*)TestOne(.*)TestThree(.*)TestTwo(.*)BenchmarkTwo(.*)BenchmarkOne(.*)BenchmarkThree(.*)'
+
+
+# Negative testcases for invalid input
+! go test -shuffle -count=2
+stderr 'invalid value "-count=2" for flag -shuffle: -shuffle argument must be "on", "off", or an int64: strconv.ParseInt: parsing "-count=2": invalid syntax'
+
+! go test -shuffle=
+stderr '(?s)invalid value "" for flag -shuffle: -shuffle argument must be "on", "off", or an int64: strconv.ParseInt: parsing "": invalid syntax'
+
+! go test -shuffle=' '
+stderr '(?s)invalid value " " for flag -shuffle: -shuffle argument must be "on", "off", or an int64: strconv.ParseInt: parsing " ": invalid syntax'
+
+! go test -shuffle=true
+stderr 'invalid value "true" for flag -shuffle: -shuffle argument must be "on", "off", or an int64: strconv.ParseInt: parsing "true": invalid syntax'
+
+! go test -shuffle='abc'
+stderr 'invalid value "abc" for flag -shuffle: -shuffle argument must be "on", "off", or an int64: strconv.ParseInt: parsing "abc": invalid syntax'
+
+-- go.mod --
+module m
+
+go 1.16
+-- foo_test.go --
+package foo
+
+import "testing"
+
+func TestOne(t *testing.T)   {}
+func TestTwo(t *testing.T)   {}
+func TestThree(t *testing.T) {}
+
+func BenchmarkOne(b *testing.B)   {}
+func BenchmarkTwo(b *testing.B)   {}
+func BenchmarkThree(b *testing.B) {}
+
+-- foo.go --
+package foo
diff --git a/src/cmd/go/testdata/script/test_trimpath.txt b/src/cmd/go/testdata/script/test_trimpath.txt
new file mode 100644
index 0000000..065f9ce
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_trimpath.txt
@@ -0,0 +1,51 @@
+[short] skip
+
+go test -trimpath -v .
+! stdout '[/\\]pkg_test[/\\]'
+stdout -count=3 '[/\\]pkg[/\\]'
+
+-- go.mod --
+module example.com/pkg
+
+go 1.17
+
+-- pkg.go --
+package pkg
+
+import "runtime"
+
+func PrintFile() {
+	_, file, _, _ := runtime.Caller(0)
+	println(file)
+}
+
+-- pkg_test.go --
+package pkg
+
+import "runtime"
+
+func PrintFileForTest() {
+	_, file, _, _ := runtime.Caller(0)
+	println(file)
+}
+
+-- pkg_x_test.go --
+package pkg_test
+
+import (
+	"runtime"
+	"testing"
+
+	"example.com/pkg"
+)
+
+func TestMain(m *testing.M) {
+	pkg.PrintFile()
+	pkg.PrintFileForTest()
+	PrintFileInXTest()
+}
+
+func PrintFileInXTest() {
+	_, file, _, _ := runtime.Caller(0)
+	println(file)
+}
diff --git a/src/cmd/go/testdata/script/test_trimpath_main.txt b/src/cmd/go/testdata/script/test_trimpath_main.txt
new file mode 100644
index 0000000..c076212
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_trimpath_main.txt
@@ -0,0 +1,38 @@
+[short] skip
+
+go test -trimpath -v .
+! stdout '[/\\]pkg_test[/\\]'
+stdout -count=2 '[/\\]pkg[/\\]'
+
+-- go.mod --
+module example.com/pkg
+
+go 1.17
+
+-- main.go --
+package main
+
+import "runtime"
+
+func PrintFile() {
+	_, file, _, _ := runtime.Caller(0)
+	println(file)
+}
+
+-- main_test.go --
+package main
+
+import (
+	"runtime"
+	"testing"
+)
+
+func PrintFileForTest() {
+	_, file, _, _ := runtime.Caller(0)
+	println(file)
+}
+
+func TestMain(m *testing.M) {
+	PrintFile()
+	PrintFileForTest()
+}
diff --git a/src/cmd/go/testdata/script/test_trimpath_test_suffix.txt b/src/cmd/go/testdata/script/test_trimpath_test_suffix.txt
new file mode 100644
index 0000000..6cbad83
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_trimpath_test_suffix.txt
@@ -0,0 +1,40 @@
+[short] skip
+
+go test -trimpath -v .
+! stdout '[/\\]pkg_test_test[/\\]'
+stdout -count=2 '[/\\]pkg_test[/\\]'
+
+-- go.mod --
+module example.com/pkg_test
+
+go 1.17
+
+-- pkg.go --
+package pkg_test
+
+import "runtime"
+
+func PrintFile() {
+	_, file, _, _ := runtime.Caller(0)
+	println(file)
+}
+
+-- pkg_x_test.go --
+package pkg_test_test
+
+import (
+	"runtime"
+	"testing"
+
+	"example.com/pkg_test"
+)
+
+func PrintFileForTest() {
+	_, file, _, _ := runtime.Caller(0)
+	println(file)
+}
+
+func TestMain(m *testing.M) {
+	pkg_test.PrintFile()
+	PrintFileForTest()
+}
diff --git a/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt b/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt
index 08e67a4..0db183f 100644
--- a/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt
+++ b/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt
@@ -3,6 +3,7 @@
 [short] skip
 
 ! go test -cpuprofile cpu.pprof -memprofile mem.pprof -timeout 1ms
+stdout '^panic: test timed out'
 grep . cpu.pprof
 grep . mem.pprof
 
@@ -12,6 +13,14 @@
 go 1.16
 -- timeout_test.go --
 package timeouttest_test
-import "testing"
-import "time"
-func TestSleep(t *testing.T) { time.Sleep(time.Second) }
+
+import (
+	"testing"
+	"time"
+)
+
+func TestSleep(t *testing.T) {
+	for {
+		time.Sleep(1 * time.Second)
+	}
+}
diff --git a/src/cmd/go/testdata/script/toolexec.txt b/src/cmd/go/testdata/script/toolexec.txt
index 5262341..bb86467 100644
--- a/src/cmd/go/testdata/script/toolexec.txt
+++ b/src/cmd/go/testdata/script/toolexec.txt
@@ -3,6 +3,12 @@
 # Build our simple toolexec program.
 go build ./cmd/mytool
 
+# Use an ephemeral build cache so that our toolexec output is not cached
+# for any stale standard-library dependencies.
+#
+# TODO(#27628): This should not be necessary.
+env GOCACHE=$WORK/gocache
+
 # Build the main package with our toolexec program. For each action, it will
 # print the tool's name and the TOOLEXEC_IMPORTPATH value. We expect to compile
 # each package once, and link the main package once.
@@ -11,12 +17,37 @@
 # Finally, note that asm and cgo are run twice.
 
 go build -toolexec=$PWD/mytool
-[amd64] stderr -count=2 '^asm'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withasm$'
-stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withasm$'
-[cgo] stderr -count=2 '^cgo'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withcgo$'
-[cgo] stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withcgo$'
-stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main$'
-stderr -count=1 '^link'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main$'
+[amd64] stderr -count=2 '^asm'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withasm"$'
+stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withasm"$'
+[cgo] stderr -count=2 '^cgo'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withcgo"$'
+[cgo] stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withcgo"$'
+stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main"$'
+stderr -count=1 '^link'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main"$'
+
+# Test packages are a little bit trickier.
+# We have four variants of test/main, as reported by 'go list -test':
+#
+#    test/main                        - the regular non-test package
+#    test/main.test                   - the generated test program
+#    test/main [test/main.test]       - the test package for foo_test.go
+#    test/main_test [test/main.test]  - the test package for foo_separate_test.go
+#
+# As such, TOOLEXEC_IMPORTPATH must see the same strings, to be able to uniquely
+# identify each package being built as reported by 'go list -f {{.ImportPath}}'.
+# Note that these are not really "import paths" anymore, but that naming is
+# consistent with 'go list -json' at least.
+
+go test -toolexec=$PWD/mytool
+
+stderr -count=2 '^# test/main\.test$'
+stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main\.test"$'
+stderr -count=1 '^link'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main\.test"$'
+
+stderr -count=1 '^# test/main \[test/main\.test\]$'
+stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main \[test/main\.test\]"$'
+
+stderr -count=1 '^# test/main_test \[test/main\.test\]$'
+stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main_test \[test/main\.test\]"$'
 
 -- go.mod --
 module test/main
@@ -32,6 +63,18 @@
 )
 
 func main() {}
+-- foo_test.go --
+package main
+
+import "testing"
+
+func TestFoo(t *testing.T) {}
+-- foo_separate_test.go --
+package main_test
+
+import "testing"
+
+func TestSeparateFoo(t *testing.T) {}
 -- withcgo/withcgo.go --
 package withcgo
 
@@ -71,7 +114,7 @@
 		// We can't alter the version output.
 	} else {
 		// Print which tool we're running, and on what package.
-		fmt.Fprintf(os.Stdout, "%s TOOLEXEC_IMPORTPATH=%s\n", toolName, os.Getenv("TOOLEXEC_IMPORTPATH"))
+		fmt.Fprintf(os.Stdout, "%s TOOLEXEC_IMPORTPATH=%q\n", toolName, os.Getenv("TOOLEXEC_IMPORTPATH"))
 	}
 
 	// Simply run the tool.
diff --git a/src/cmd/go/testdata/script/vendor_test_issue14613.txt b/src/cmd/go/testdata/script/vendor_test_issue14613.txt
index 7801e69..cfd7e58 100644
--- a/src/cmd/go/testdata/script/vendor_test_issue14613.txt
+++ b/src/cmd/go/testdata/script/vendor_test_issue14613.txt
@@ -19,4 +19,4 @@
 # test with imported and not used
 go test -i github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go
 ! go test github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go
-stderr 'imported and not used:'
+stderr 'imported and not used'
diff --git a/src/cmd/go/testdata/script/version_goexperiment.txt b/src/cmd/go/testdata/script/version_goexperiment.txt
new file mode 100644
index 0000000..4b165eb
--- /dev/null
+++ b/src/cmd/go/testdata/script/version_goexperiment.txt
@@ -0,0 +1,16 @@
+# Test that experiments appear in "go version <binary>"
+
+# This test requires rebuilding the runtime, which takes a while.
+[short] skip
+
+env GOEXPERIMENT=fieldtrack
+go build -o main$GOEXE version.go
+go version main$GOEXE
+stdout 'X:fieldtrack$'
+exec ./main$GOEXE
+stderr 'X:fieldtrack$'
+
+-- version.go --
+package main
+import "runtime"
+func main() { println(runtime.Version()) }
diff --git a/src/cmd/gofmt/gofmt.go b/src/cmd/gofmt/gofmt.go
index 2793c2c..b3c120d 100644
--- a/src/cmd/gofmt/gofmt.go
+++ b/src/cmd/gofmt/gofmt.go
@@ -151,7 +151,7 @@
 			if err != nil {
 				return fmt.Errorf("computing diff: %s", err)
 			}
-			fmt.Printf("diff -u %s %s\n", filepath.ToSlash(filename+".orig"), filepath.ToSlash(filename))
+			fmt.Fprintf(out, "diff -u %s %s\n", filepath.ToSlash(filename+".orig"), filepath.ToSlash(filename))
 			out.Write(data)
 		}
 	}
@@ -164,21 +164,15 @@
 }
 
 func visitFile(path string, f fs.DirEntry, err error) error {
-	if err == nil && isGoFile(f) {
-		err = processFile(path, nil, os.Stdout, false)
+	if err != nil || !isGoFile(f) {
+		return err
 	}
-	// Don't complain if a file was deleted in the meantime (i.e.
-	// the directory changed concurrently while running gofmt).
-	if err != nil && !os.IsNotExist(err) {
+	if err := processFile(path, nil, os.Stdout, false); err != nil {
 		report(err)
 	}
 	return nil
 }
 
-func walkDir(path string) {
-	filepath.WalkDir(path, visitFile)
-}
-
 func main() {
 	// call gofmtMain in a separate function
 	// so that it can use defer and have them
@@ -206,7 +200,8 @@
 	initParserMode()
 	initRewrite()
 
-	if flag.NArg() == 0 {
+	args := flag.Args()
+	if len(args) == 0 {
 		if *write {
 			fmt.Fprintln(os.Stderr, "error: cannot use -w with standard input")
 			exitCode = 2
@@ -218,15 +213,18 @@
 		return
 	}
 
-	for i := 0; i < flag.NArg(); i++ {
-		path := flag.Arg(i)
-		switch dir, err := os.Stat(path); {
+	for _, arg := range args {
+		switch info, err := os.Stat(arg); {
 		case err != nil:
 			report(err)
-		case dir.IsDir():
-			walkDir(path)
+		case !info.IsDir():
+			// Non-directory arguments are always formatted.
+			if err := processFile(arg, nil, os.Stdout, false); err != nil {
+				report(err)
+			}
 		default:
-			if err := processFile(path, nil, os.Stdout, false); err != nil {
+			// Directories are walked, ignoring non-Go files.
+			if err := filepath.WalkDir(arg, visitFile); err != nil {
 				report(err)
 			}
 		}
diff --git a/src/cmd/gofmt/gofmt_test.go b/src/cmd/gofmt/gofmt_test.go
index bf2adfe..f0d3f87 100644
--- a/src/cmd/gofmt/gofmt_test.go
+++ b/src/cmd/gofmt/gofmt_test.go
@@ -49,12 +49,13 @@
 		case scanner.EOF:
 			return ""
 		}
-
 	}
 
 	return ""
 }
 
+var typeParamsEnabled = false
+
 func runTest(t *testing.T, in, out string) {
 	// process flags
 	*simplifyAST = false
@@ -77,6 +78,11 @@
 		case "-stdin":
 			// fake flag - pretend input is from stdin
 			stdin = true
+		case "-G":
+			// fake flag - test is for generic code
+			if !typeParamsEnabled {
+				return
+			}
 		default:
 			t.Errorf("unrecognized flag name: %s", name)
 		}
diff --git a/src/cmd/gofmt/gofmt_typeparams_test.go b/src/cmd/gofmt/gofmt_typeparams_test.go
new file mode 100644
index 0000000..10641a7
--- /dev/null
+++ b/src/cmd/gofmt/gofmt_typeparams_test.go
@@ -0,0 +1,12 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build typeparams
+// +build typeparams
+
+package main
+
+func init() {
+	typeParamsEnabled = true
+}
diff --git a/src/cmd/gofmt/testdata/typeparams.golden b/src/cmd/gofmt/testdata/typeparams.golden
new file mode 100644
index 0000000..35f08d1
--- /dev/null
+++ b/src/cmd/gofmt/testdata/typeparams.golden
@@ -0,0 +1,35 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//gofmt -G
+
+package typeparams
+
+type T[P any] struct{}
+type T[P1, P2, P3 any] struct{}
+
+type T[P C] struct{}
+type T[P1, P2, P3 C] struct{}
+
+type T[P C[P]] struct{}
+type T[P1, P2, P3 C[P1, P2, P3]] struct{}
+
+func f[P any](x P)
+func f[P1, P2, P3 any](x1 P1, x2 P2, x3 P3) struct{}
+
+func f[P interface{}](x P)
+func f[P1, P2, P3 interface {
+	m1(P1)
+	type P2, P3
+}](x1 P1, x2 P2, x3 P3) struct{}
+func f[P any](T1[P], T2[P]) T3[P]
+
+func (x T[P]) m()
+func (T[P]) m(x T[P]) P
+
+func _() {
+	type _ []T[P]
+	var _ []T[P]
+	_ = []T[P]{}
+}
diff --git a/src/cmd/gofmt/testdata/typeparams.input b/src/cmd/gofmt/testdata/typeparams.input
new file mode 100644
index 0000000..7f3212c
--- /dev/null
+++ b/src/cmd/gofmt/testdata/typeparams.input
@@ -0,0 +1,32 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//gofmt -G
+
+package typeparams
+
+type T[  P any] struct{}
+type T[P1, P2, P3 any] struct{}
+
+type T[P C] struct{}
+type T[P1,P2, P3 C] struct{}
+
+type T[P C[P]] struct{}
+type T[P1, P2, P3 C[P1,P2,P3]] struct{}
+
+func f[P any](x P)
+func f[P1, P2, P3 any](x1 P1, x2 P2, x3 P3) struct{}
+
+func f[P interface{}](x P)
+func f[P1, P2, P3 interface{ m1(P1); type P2, P3 }](x1 P1, x2 P2, x3 P3) struct{}
+func f[P any](T1[P], T2[P]) T3[P]
+
+func (x T[P]) m()
+func ((T[P])) m(x T[P]) P
+
+func _() {
+	type _ []T[P]
+	var _ []T[P]
+	_ = []T[P]{}
+}
diff --git a/src/cmd/internal/archive/archive.go b/src/cmd/internal/archive/archive.go
index c1661d7..da1f293 100644
--- a/src/cmd/internal/archive/archive.go
+++ b/src/cmd/internal/archive/archive.go
@@ -106,6 +106,12 @@
 	errNotObject        = errors.New("unrecognized object file format")
 )
 
+type ErrGoObjOtherVersion struct{ magic []byte }
+
+func (e ErrGoObjOtherVersion) Error() string {
+	return fmt.Sprintf("go object of a different version: %q", e.magic)
+}
+
 // An objReader is an object file reader.
 type objReader struct {
 	a      *Archive
@@ -118,9 +124,9 @@
 
 func (r *objReader) init(f *os.File) {
 	r.a = &Archive{f, nil}
-	r.offset, _ = f.Seek(0, io.SeekCurrent)
-	r.limit, _ = f.Seek(0, io.SeekEnd)
-	f.Seek(r.offset, io.SeekStart)
+	r.offset, _ = f.Seek(0, os.SEEK_CUR)
+	r.limit, _ = f.Seek(0, os.SEEK_END)
+	f.Seek(r.offset, os.SEEK_SET)
 	r.b = bio.NewReader(f)
 }
 
@@ -221,7 +227,7 @@
 		r.readFull(r.tmp[:n])
 	} else {
 		// Seek, giving up buffered data.
-		r.b.MustSeek(r.offset+n, io.SeekStart)
+		r.b.MustSeek(r.offset+n, os.SEEK_SET)
 		r.offset += n
 	}
 }
@@ -389,7 +395,7 @@
 // The object file consists of a textual header ending in "\n!\n"
 // and then the part we want to parse begins.
 // The format of that part is defined in a comment at the top
-// of src/liblink/objfile.c.
+// of cmd/internal/goobj/objfile.go.
 func (r *objReader) parseObject(o *GoObj, size int64) error {
 	h := make([]byte, 0, 256)
 	var c1, c2, c3 byte
@@ -418,6 +424,9 @@
 		return err
 	}
 	if !bytes.Equal(p, []byte(goobj.Magic)) {
+		if bytes.HasPrefix(p, []byte("\x00go1")) && bytes.HasSuffix(p, []byte("ld")) {
+			return r.error(ErrGoObjOtherVersion{p[1:]}) // strip the \x00 byte
+		}
 		return r.error(errCorruptObject)
 	}
 	r.skip(o.Size)
@@ -426,7 +435,7 @@
 
 // AddEntry adds an entry to the end of a, with the content from r.
 func (a *Archive) AddEntry(typ EntryType, name string, mtime int64, uid, gid int, mode os.FileMode, size int64, r io.Reader) {
-	off, err := a.f.Seek(0, io.SeekEnd)
+	off, err := a.f.Seek(0, os.SEEK_END)
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -464,3 +473,24 @@
 	s += sixteenSpaces[:16-len(s)]
 	return s
 }
+
+// architecture-independent object file output
+const HeaderSize = 60
+
+func ReadHeader(b *bufio.Reader, name string) int {
+	var buf [HeaderSize]byte
+	if _, err := io.ReadFull(b, buf[:]); err != nil {
+		return -1
+	}
+	aname := strings.Trim(string(buf[0:16]), " ")
+	if !strings.HasPrefix(aname, name) {
+		return -1
+	}
+	asize := strings.Trim(string(buf[48:58]), " ")
+	i, _ := strconv.Atoi(asize)
+	return i
+}
+
+func FormatHeader(arhdr []byte, name string, size int64) {
+	copy(arhdr[:], fmt.Sprintf("%-16s%-12d%-6d%-6d%-8o%-10d`\n", name, 0, 0, 0, 0644, size))
+}
diff --git a/src/cmd/internal/archive/archive_test.go b/src/cmd/internal/archive/archive_test.go
index cb4eb84..c284a9c 100644
--- a/src/cmd/internal/archive/archive_test.go
+++ b/src/cmd/internal/archive/archive_test.go
@@ -173,7 +173,7 @@
 			continue
 		}
 		if e.Type != EntryGoObj {
-			t.Errorf("wrong type of object: wnat EntryGoObj, got %v", e.Type)
+			t.Errorf("wrong type of object: want EntryGoObj, got %v", e.Type)
 		}
 		if !bytes.Contains(e.Obj.TextHeader, []byte(runtime.GOARCH)) {
 			t.Errorf("text header does not contain GOARCH %s: %q", runtime.GOARCH, e.Obj.TextHeader)
@@ -204,7 +204,7 @@
 			continue
 		}
 		if e.Type != EntryGoObj {
-			t.Errorf("wrong type of object: wnat EntryGoObj, got %v", e.Type)
+			t.Errorf("wrong type of object: want EntryGoObj, got %v", e.Type)
 		}
 		if !bytes.Contains(e.Obj.TextHeader, []byte(runtime.GOARCH)) {
 			t.Errorf("text header does not contain GOARCH %s: %q", runtime.GOARCH, e.Obj.TextHeader)
diff --git a/src/cmd/internal/bio/buf_mmap.go b/src/cmd/internal/bio/buf_mmap.go
index 4b43d74..b9755c7 100644
--- a/src/cmd/internal/bio/buf_mmap.go
+++ b/src/cmd/internal/bio/buf_mmap.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
 // +build darwin dragonfly freebsd linux netbsd openbsd
 
 package bio
diff --git a/src/cmd/internal/bio/buf_nommap.go b/src/cmd/internal/bio/buf_nommap.go
index f43c67a..533a931 100644
--- a/src/cmd/internal/bio/buf_nommap.go
+++ b/src/cmd/internal/bio/buf_nommap.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd
 // +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd
 
 package bio
diff --git a/src/cmd/internal/diff/diff.go b/src/cmd/internal/diff/diff.go
index c0ca2f3..0ec2d7f 100644
--- a/src/cmd/internal/diff/diff.go
+++ b/src/cmd/internal/diff/diff.go
@@ -7,6 +7,7 @@
 package diff
 
 import (
+	"bytes"
 	exec "internal/execabs"
 	"io/ioutil"
 	"os"
@@ -38,6 +39,25 @@
 		// Ignore that failure as long as we get output.
 		err = nil
 	}
+
+	// If we are on Windows and the diff is Cygwin diff,
+	// machines can get into a state where every Cygwin
+	// command works fine but prints a useless message like:
+	//
+	//	Cygwin WARNING:
+	//	  Couldn't compute FAST_CWD pointer.  This typically occurs if you're using
+	//	  an older Cygwin version on a newer Windows.  Please update to the latest
+	//	  available Cygwin version from https://cygwin.com/.  If the problem persists,
+	//	  please see https://cygwin.com/problems.html
+	//
+	// Skip over that message and just return the actual diff.
+	if len(data) > 0 && !bytes.HasPrefix(data, []byte("--- ")) {
+		i := bytes.Index(data, []byte("\n--- "))
+		if i >= 0 && i < 80*10 && bytes.Contains(data[:i], []byte("://cygwin.com/")) {
+			data = data[i+1:]
+		}
+	}
+
 	return data, err
 }
 
diff --git a/src/cmd/internal/dwarf/dwarf.go b/src/cmd/internal/dwarf/dwarf.go
index 8de4096..ec441c2 100644
--- a/src/cmd/internal/dwarf/dwarf.go
+++ b/src/cmd/internal/dwarf/dwarf.go
@@ -9,13 +9,15 @@
 
 import (
 	"bytes"
-	"cmd/internal/objabi"
 	"errors"
 	"fmt"
+	"internal/buildcfg"
 	exec "internal/execabs"
 	"sort"
 	"strconv"
 	"strings"
+
+	"cmd/internal/objabi"
 )
 
 // InfoPrefix is the prefix for all the symbols containing DWARF info entries.
@@ -318,8 +320,6 @@
 )
 
 // Index into the abbrevs table below.
-// Keep in sync with ispubname() and ispubtype() in ld/dwarf.go.
-// ispubtype considers >= NULLTYPE public
 const (
 	DW_ABRV_NULL = iota
 	DW_ABRV_COMPUNIT
@@ -383,7 +383,7 @@
 		return form
 	}
 	expandedForm := DW_FORM_udata
-	if objabi.GOOS == "darwin" || objabi.GOOS == "ios" {
+	if buildcfg.GOOS == "darwin" || buildcfg.GOOS == "ios" {
 		expandedForm = DW_FORM_data4
 	}
 	return uint8(expandedForm)
@@ -1043,6 +1043,15 @@
 	putattr(ctxt, info, DW_ABRV_INT_CONSTANT, DW_FORM_sdata, DW_CLS_CONSTANT, val, nil)
 }
 
+// PutGlobal writes a DIE for a global variable.
+func PutGlobal(ctxt Context, info, typ, gvar Sym, name string) {
+	Uleb128put(ctxt, info, DW_ABRV_VARIABLE)
+	putattr(ctxt, info, DW_ABRV_VARIABLE, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name)
+	putattr(ctxt, info, DW_ABRV_VARIABLE, DW_FORM_block1, DW_CLS_ADDRESS, 0, gvar)
+	putattr(ctxt, info, DW_ABRV_VARIABLE, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, typ)
+	putattr(ctxt, info, DW_ABRV_VARIABLE, DW_FORM_flag, DW_CLS_FLAG, 1, nil)
+}
+
 // PutBasedRanges writes a range table to sym. All addresses in ranges are
 // relative to some base address, which must be arranged by the caller
 // (e.g., with a DW_AT_low_pc attribute, or in a BASE-prefixed range).
@@ -1257,7 +1266,7 @@
 // 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 {
+func putInlinedFunc(ctxt Context, s *FnState, callersym Sym, callIdx int) error {
 	ic := s.InlCalls.Calls[callIdx]
 	callee := ic.AbsFunSym
 
@@ -1268,7 +1277,7 @@
 	Uleb128put(ctxt, s.Info, int64(abbrev))
 
 	if logDwarf {
-		ctxt.Logf("PutInlinedFunc(caller=%v,callee=%v,abbrev=%d)\n", callersym, callee, abbrev)
+		ctxt.Logf("putInlinedFunc(caller=%v,callee=%v,abbrev=%d)\n", callersym, callee, abbrev)
 	}
 
 	// Abstract origin.
@@ -1304,7 +1313,7 @@
 	// Children of this inline.
 	for _, sib := range inlChildren(callIdx, &s.InlCalls) {
 		absfn := s.InlCalls.Calls[sib].AbsFunSym
-		err := PutInlinedFunc(ctxt, s, absfn, sib)
+		err := putInlinedFunc(ctxt, s, absfn, sib)
 		if err != nil {
 			return err
 		}
@@ -1346,7 +1355,7 @@
 	// Inlined subroutines.
 	for _, sib := range inlChildren(-1, &s.InlCalls) {
 		absfn := s.InlCalls.Calls[sib].AbsFunSym
-		err := PutInlinedFunc(ctxt, s, absfn, sib)
+		err := putInlinedFunc(ctxt, s, absfn, sib)
 		if err != nil {
 			return err
 		}
@@ -1394,7 +1403,7 @@
 	// Inlined subroutines.
 	for _, sib := range inlChildren(-1, &s.InlCalls) {
 		absfn := s.InlCalls.Calls[sib].AbsFunSym
-		err := PutInlinedFunc(ctxt, s, absfn, sib)
+		err := putInlinedFunc(ctxt, s, absfn, sib)
 		if err != nil {
 			return err
 		}
@@ -1600,14 +1609,6 @@
 	// Var has no children => no terminator
 }
 
-// VarsByOffset attaches the methods of sort.Interface to []*Var,
-// 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].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
 
diff --git a/src/cmd/internal/goobj/builtinlist.go b/src/cmd/internal/goobj/builtinlist.go
index 0cca752..9f24813 100644
--- a/src/cmd/internal/goobj/builtinlist.go
+++ b/src/cmd/internal/goobj/builtinlist.go
@@ -41,6 +41,7 @@
 	{"runtime.printcomplex", 1},
 	{"runtime.printstring", 1},
 	{"runtime.printpointer", 1},
+	{"runtime.printuintptr", 1},
 	{"runtime.printiface", 1},
 	{"runtime.printeface", 1},
 	{"runtime.printslice", 1},
@@ -61,7 +62,6 @@
 	{"runtime.stringtoslicebyte", 1},
 	{"runtime.stringtoslicerune", 1},
 	{"runtime.slicecopy", 1},
-	{"runtime.slicestringcopy", 1},
 	{"runtime.decoderune", 1},
 	{"runtime.countrunes", 1},
 	{"runtime.convI2I", 1},
@@ -122,7 +122,6 @@
 	{"runtime.typedslicecopy", 1},
 	{"runtime.selectnbsend", 1},
 	{"runtime.selectnbrecv", 1},
-	{"runtime.selectnbrecv2", 1},
 	{"runtime.selectsetpc", 1},
 	{"runtime.selectgo", 1},
 	{"runtime.block", 1},
@@ -172,8 +171,9 @@
 	{"runtime.uint64tofloat64", 1},
 	{"runtime.uint32tofloat64", 1},
 	{"runtime.complex128div", 1},
+	{"runtime.getcallerpc", 1},
+	{"runtime.getcallersp", 1},
 	{"runtime.racefuncenter", 1},
-	{"runtime.racefuncenterfp", 1},
 	{"runtime.racefuncexit", 1},
 	{"runtime.raceread", 1},
 	{"runtime.racewrite", 1},
@@ -181,6 +181,7 @@
 	{"runtime.racewriterange", 1},
 	{"runtime.msanread", 1},
 	{"runtime.msanwrite", 1},
+	{"runtime.msanmove", 1},
 	{"runtime.checkptrAlignment", 1},
 	{"runtime.checkptrArithmetic", 1},
 	{"runtime.libfuzzerTraceCmp1", 1},
diff --git a/src/cmd/internal/goobj/funcinfo.go b/src/cmd/internal/goobj/funcinfo.go
index 2cca8f6..6d33a10 100644
--- a/src/cmd/internal/goobj/funcinfo.go
+++ b/src/cmd/internal/goobj/funcinfo.go
@@ -19,9 +19,10 @@
 //
 // TODO: make each pcdata a separate symbol?
 type FuncInfo struct {
-	Args   uint32
-	Locals uint32
-	FuncID objabi.FuncID
+	Args     uint32
+	Locals   uint32
+	FuncID   objabi.FuncID
+	FuncFlag objabi.FuncFlag
 
 	Pcsp        SymRef
 	Pcfile      SymRef
@@ -35,6 +36,9 @@
 }
 
 func (a *FuncInfo) Write(w *bytes.Buffer) {
+	writeUint8 := func(x uint8) {
+		w.WriteByte(x)
+	}
 	var b [4]byte
 	writeUint32 := func(x uint32) {
 		binary.LittleEndian.PutUint32(b[:], x)
@@ -47,8 +51,10 @@
 
 	writeUint32(a.Args)
 	writeUint32(a.Locals)
-	writeUint32(uint32(a.FuncID))
-
+	writeUint8(uint8(a.FuncID))
+	writeUint8(uint8(a.FuncFlag))
+	writeUint8(0) // pad to uint32 boundary
+	writeUint8(0)
 	writeSymRef(a.Pcsp)
 	writeSymRef(a.Pcfile)
 	writeSymRef(a.Pcline)
@@ -72,46 +78,6 @@
 	}
 }
 
-func (a *FuncInfo) Read(b []byte) {
-	readUint32 := func() uint32 {
-		x := binary.LittleEndian.Uint32(b)
-		b = b[4:]
-		return x
-	}
-	readSymIdx := func() SymRef {
-		return SymRef{readUint32(), readUint32()}
-	}
-
-	a.Args = readUint32()
-	a.Locals = readUint32()
-	a.FuncID = objabi.FuncID(readUint32())
-
-	a.Pcsp = readSymIdx()
-	a.Pcfile = readSymIdx()
-	a.Pcline = readSymIdx()
-	a.Pcinline = readSymIdx()
-	a.Pcdata = make([]SymRef, readUint32())
-	for i := range a.Pcdata {
-		a.Pcdata[i] = readSymIdx()
-	}
-
-	funcdataofflen := readUint32()
-	a.Funcdataoff = make([]uint32, funcdataofflen)
-	for i := range a.Funcdataoff {
-		a.Funcdataoff[i] = readUint32()
-	}
-	filelen := readUint32()
-	a.File = make([]CUFileIndex, filelen)
-	for i := range a.File {
-		a.File[i] = CUFileIndex(readUint32())
-	}
-	inltreelen := readUint32()
-	a.InlTree = make([]InlTreeNode, inltreelen)
-	for i := range a.InlTree {
-		b = a.InlTree[i].Read(b)
-	}
-}
-
 // FuncInfoLengths is a cache containing a roadmap of offsets and
 // lengths for things within a serialized FuncInfo. Each length field
 // stores the number of items (e.g. files, inltree nodes, etc), and the
@@ -159,7 +125,9 @@
 
 func (*FuncInfo) ReadLocals(b []byte) uint32 { return binary.LittleEndian.Uint32(b[4:]) }
 
-func (*FuncInfo) ReadFuncID(b []byte) uint32 { return binary.LittleEndian.Uint32(b[8:]) }
+func (*FuncInfo) ReadFuncID(b []byte) objabi.FuncID { return objabi.FuncID(b[8]) }
+
+func (*FuncInfo) ReadFuncFlag(b []byte) objabi.FuncFlag { return objabi.FuncFlag(b[9]) }
 
 func (*FuncInfo) ReadPcsp(b []byte) SymRef {
 	return SymRef{binary.LittleEndian.Uint32(b[12:]), binary.LittleEndian.Uint32(b[16:])}
diff --git a/src/cmd/internal/goobj/mkbuiltin.go b/src/cmd/internal/goobj/mkbuiltin.go
index 07c3406..18b9695 100644
--- a/src/cmd/internal/goobj/mkbuiltin.go
+++ b/src/cmd/internal/goobj/mkbuiltin.go
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
-// Generate builtinlist.go from cmd/compile/internal/gc/builtin/runtime.go.
+// Generate builtinlist.go from cmd/compile/internal/typecheck/builtin/runtime.go.
 
 package main
 
@@ -53,7 +54,7 @@
 func mkbuiltin(w io.Writer) {
 	pkg := "runtime"
 	fset := token.NewFileSet()
-	path := filepath.Join("..", "..", "compile", "internal", "gc", "builtin", "runtime.go")
+	path := filepath.Join("..", "..", "compile", "internal", "typecheck", "builtin", "runtime.go")
 	f, err := parser.ParseFile(fset, path, nil, 0)
 	if err != nil {
 		log.Fatal(err)
@@ -118,8 +119,8 @@
 
 // addBasicTypes returns the symbol names for basic types that are
 // defined in the runtime and referenced in other packages.
-// Needs to be kept in sync with reflect.go:dumpbasictypes() and
-// reflect.go:dtypesym() in the compiler.
+// Needs to be kept in sync with reflect.go:WriteBasicTypes() and
+// reflect.go:writeType() in the compiler.
 func enumerateBasicTypes() []extra {
 	names := [...]string{
 		"int8", "uint8", "int16", "uint16",
diff --git a/src/cmd/internal/goobj/objfile.go b/src/cmd/internal/goobj/objfile.go
index e6447e4..e2858bd 100644
--- a/src/cmd/internal/goobj/objfile.go
+++ b/src/cmd/internal/goobj/objfile.go
@@ -33,7 +33,7 @@
 // New object file format.
 //
 //    Header struct {
-//       Magic       [...]byte   // "\x00go116ld"
+//       Magic       [...]byte   // "\x00go117ld"
 //       Fingerprint [8]byte
 //       Flags       uint32
 //       Offsets     [...]uint32 // byte offset of each block below
@@ -89,7 +89,7 @@
 //    Relocs [...]struct {
 //       Off  int32
 //       Size uint8
-//       Type uint8
+//       Type uint16
 //       Add  int64
 //       Sym  symRef
 //    }
@@ -219,7 +219,7 @@
 	Offsets     [NBlk]uint32
 }
 
-const Magic = "\x00go116ld"
+const Magic = "\x00go117ld"
 
 func (h *Header) Write(w *Writer) {
 	w.RawString(h.Magic)
@@ -298,7 +298,6 @@
 	SymFlagNoSplit
 	SymFlagReflectMethod
 	SymFlagGoType
-	SymFlagTopFrame
 )
 
 // Sym.Flag2
@@ -332,7 +331,6 @@
 func (s *Sym) NoSplit() bool       { return s.Flag()&SymFlagNoSplit != 0 }
 func (s *Sym) ReflectMethod() bool { return s.Flag()&SymFlagReflectMethod != 0 }
 func (s *Sym) IsGoType() bool      { return s.Flag()&SymFlagGoType != 0 }
-func (s *Sym) TopFrame() bool      { return s.Flag()&SymFlagTopFrame != 0 }
 func (s *Sym) UsedInIface() bool   { return s.Flag2()&SymFlagUsedInIface != 0 }
 func (s *Sym) IsItab() bool        { return s.Flag2()&SymFlagItab != 0 }
 
@@ -375,32 +373,32 @@
 // Reloc struct {
 //    Off  int32
 //    Siz  uint8
-//    Type uint8
+//    Type uint16
 //    Add  int64
 //    Sym  SymRef
 // }
 type Reloc [RelocSize]byte
 
-const RelocSize = 4 + 1 + 1 + 8 + 8
+const RelocSize = 4 + 1 + 2 + 8 + 8
 
-func (r *Reloc) Off() int32  { return int32(binary.LittleEndian.Uint32(r[:])) }
-func (r *Reloc) Siz() uint8  { return r[4] }
-func (r *Reloc) Type() uint8 { return r[5] }
-func (r *Reloc) Add() int64  { return int64(binary.LittleEndian.Uint64(r[6:])) }
+func (r *Reloc) Off() int32   { return int32(binary.LittleEndian.Uint32(r[:])) }
+func (r *Reloc) Siz() uint8   { return r[4] }
+func (r *Reloc) Type() uint16 { return binary.LittleEndian.Uint16(r[5:]) }
+func (r *Reloc) Add() int64   { return int64(binary.LittleEndian.Uint64(r[7:])) }
 func (r *Reloc) Sym() SymRef {
-	return SymRef{binary.LittleEndian.Uint32(r[14:]), binary.LittleEndian.Uint32(r[18:])}
+	return SymRef{binary.LittleEndian.Uint32(r[15:]), binary.LittleEndian.Uint32(r[19:])}
 }
 
-func (r *Reloc) SetOff(x int32)  { binary.LittleEndian.PutUint32(r[:], uint32(x)) }
-func (r *Reloc) SetSiz(x uint8)  { r[4] = x }
-func (r *Reloc) SetType(x uint8) { r[5] = x }
-func (r *Reloc) SetAdd(x int64)  { binary.LittleEndian.PutUint64(r[6:], uint64(x)) }
+func (r *Reloc) SetOff(x int32)   { binary.LittleEndian.PutUint32(r[:], uint32(x)) }
+func (r *Reloc) SetSiz(x uint8)   { r[4] = x }
+func (r *Reloc) SetType(x uint16) { binary.LittleEndian.PutUint16(r[5:], x) }
+func (r *Reloc) SetAdd(x int64)   { binary.LittleEndian.PutUint64(r[7:], uint64(x)) }
 func (r *Reloc) SetSym(x SymRef) {
-	binary.LittleEndian.PutUint32(r[14:], x.PkgIdx)
-	binary.LittleEndian.PutUint32(r[18:], x.SymIdx)
+	binary.LittleEndian.PutUint32(r[15:], x.PkgIdx)
+	binary.LittleEndian.PutUint32(r[19:], x.SymIdx)
 }
 
-func (r *Reloc) Set(off int32, size uint8, typ uint8, add int64, sym SymRef) {
+func (r *Reloc) Set(off int32, size uint8, typ uint16, add int64, sym SymRef) {
 	r.SetOff(off)
 	r.SetSiz(size)
 	r.SetType(typ)
@@ -483,7 +481,7 @@
 
 func (r *RefFlags) Write(w *Writer) { w.Bytes(r[:]) }
 
-// Used to construct an artifically large array type when reading an
+// Used to construct an artificially large array type when reading an
 // item from the object file relocs section or aux sym section (needs
 // to work on 32-bit as well as 64-bit). See issue 41621.
 const huge = (1<<31 - 1) / RelocSize
diff --git a/src/cmd/internal/goobj/objfile_test.go b/src/cmd/internal/goobj/objfile_test.go
index c6fd427..ed942aa 100644
--- a/src/cmd/internal/goobj/objfile_test.go
+++ b/src/cmd/internal/goobj/objfile_test.go
@@ -9,6 +9,12 @@
 	"bytes"
 	"cmd/internal/bio"
 	"cmd/internal/objabi"
+	"fmt"
+	"internal/buildcfg"
+	"internal/testenv"
+	"io/ioutil"
+	"os"
+	"os/exec"
 	"testing"
 )
 
@@ -35,7 +41,7 @@
 	var r Reloc
 	r.SetOff(12)
 	r.SetSiz(4)
-	r.SetType(uint8(objabi.R_ADDR))
+	r.SetType(uint16(objabi.R_ADDR))
 	r.SetAdd(54321)
 	r.SetSym(SymRef{11, 22})
 	r.Write(w)
@@ -58,7 +64,7 @@
 	b = b[SymSize:]
 	var r2 Reloc
 	r2.fromBytes(b)
-	if r2.Off() != 12 || r2.Siz() != 4 || r2.Type() != uint8(objabi.R_ADDR) || r2.Add() != 54321 || r2.Sym() != (SymRef{11, 22}) {
+	if r2.Off() != 12 || r2.Siz() != 4 || r2.Type() != uint16(objabi.R_ADDR) || r2.Add() != 54321 || r2.Sym() != (SymRef{11, 22}) {
 		t.Errorf("read Reloc2 mismatch: got %v %v %v %v %v", r2.Off(), r2.Siz(), r2.Type(), r2.Add(), r2.Sym())
 	}
 
@@ -69,3 +75,60 @@
 		t.Errorf("read Aux2 mismatch: got %v %v", a2.Type(), a2.Sym())
 	}
 }
+
+var issue41621prolog = `
+package main
+var lines = []string{
+`
+
+var issue41621epilog = `
+}
+func getLines() []string {
+	return lines
+}
+func main() {
+	println(getLines())
+}
+`
+
+func TestIssue41621LargeNumberOfRelocations(t *testing.T) {
+	if testing.Short() || (buildcfg.GOARCH != "amd64") {
+		t.Skipf("Skipping large number of relocations test in short mode or on %s", buildcfg.GOARCH)
+	}
+	testenv.MustHaveGoBuild(t)
+
+	tmpdir, err := ioutil.TempDir("", "lotsofrelocs")
+	if err != nil {
+		t.Fatalf("can't create temp directory: %v\n", err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	// Emit testcase.
+	var w bytes.Buffer
+	fmt.Fprintf(&w, issue41621prolog)
+	for i := 0; i < 1048576+13; i++ {
+		fmt.Fprintf(&w, "\t\"%d\",\n", i)
+	}
+	fmt.Fprintf(&w, issue41621epilog)
+	err = ioutil.WriteFile(tmpdir+"/large.go", w.Bytes(), 0666)
+	if err != nil {
+		t.Fatalf("can't write output: %v\n", err)
+	}
+
+	// Emit go.mod
+	w.Reset()
+	fmt.Fprintf(&w, "module issue41621\n\ngo 1.12\n")
+	err = ioutil.WriteFile(tmpdir+"/go.mod", w.Bytes(), 0666)
+	if err != nil {
+		t.Fatalf("can't write output: %v\n", err)
+	}
+	w.Reset()
+
+	// Build.
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "large")
+	cmd.Dir = tmpdir
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("Build failed: %v, output: %s", err, out)
+	}
+}
diff --git a/src/cmd/internal/moddeps/moddeps_test.go b/src/cmd/internal/moddeps/moddeps_test.go
index cba401c..56c3b25 100644
--- a/src/cmd/internal/moddeps/moddeps_test.go
+++ b/src/cmd/internal/moddeps/moddeps_test.go
@@ -5,6 +5,7 @@
 package moddeps_test
 
 import (
+	"bytes"
 	"encoding/json"
 	"fmt"
 	"internal/testenv"
@@ -61,14 +62,14 @@
 				_, err := cmd.Output()
 				if err != nil {
 					t.Errorf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr)
-					t.Logf("(Run 'go mod vendor' in %s to ensure that dependecies have been vendored.)", m.Dir)
+					t.Logf("(Run 'go mod vendor' in %s to ensure that dependencies have been vendored.)", m.Dir)
 				}
 				return
 			}
 
 			// There is no vendor directory, so the module must have no dependencies.
 			// Check that the list of active modules contains only the main module.
-			cmd := exec.Command(goBin, "list", "-mod=mod", "-m", "all")
+			cmd := exec.Command(goBin, "list", "-mod=readonly", "-m", "all")
 			cmd.Env = append(os.Environ(), "GO111MODULE=on")
 			cmd.Dir = m.Dir
 			cmd.Stderr = new(strings.Builder)
@@ -123,10 +124,38 @@
 		t.Skip("skipping because a diff command with support for --recursive and --unified flags is unavailable")
 	}
 
+	// We're going to check the standard modules for tidiness, so we need a usable
+	// GOMODCACHE. If the default directory doesn't exist, use a temporary
+	// directory instead. (That can occur, for example, when running under
+	// run.bash with GO_TEST_SHORT=0: run.bash sets GOPATH=/nonexist-gopath, and
+	// GO_TEST_SHORT=0 causes it to run this portion of the test.)
+	var modcacheEnv []string
+	{
+		out, err := exec.Command(goBin, "env", "GOMODCACHE").Output()
+		if err != nil {
+			t.Fatalf("%s env GOMODCACHE: %v", goBin, err)
+		}
+		modcacheOk := false
+		if gomodcache := string(bytes.TrimSpace(out)); gomodcache != "" {
+			if _, err := os.Stat(gomodcache); err == nil {
+				modcacheOk = true
+			}
+		}
+		if !modcacheOk {
+			modcacheEnv = []string{
+				"GOMODCACHE=" + t.TempDir(),
+				"GOFLAGS=" + os.Getenv("GOFLAGS") + " -modcacherw", // Allow t.TempDir() to clean up subdirectories.
+			}
+		}
+	}
+
 	// Build the bundle binary at the golang.org/x/tools
 	// module version specified in GOROOT/src/cmd/go.mod.
 	bundleDir := t.TempDir()
-	r := runner{Dir: filepath.Join(runtime.GOROOT(), "src/cmd")}
+	r := runner{
+		Dir: filepath.Join(runtime.GOROOT(), "src/cmd"),
+		Env: append(os.Environ(), modcacheEnv...),
+	}
 	r.run(t, goBin, "build", "-mod=readonly", "-o", bundleDir, "golang.org/x/tools/cmd/bundle")
 
 	var gorootCopyDir string
@@ -160,11 +189,11 @@
 			}
 			r := runner{
 				Dir: filepath.Join(gorootCopyDir, rel),
-				Env: append(os.Environ(),
+				Env: append(append(os.Environ(), modcacheEnv...),
 					// Set GOROOT.
 					"GOROOT="+gorootCopyDir,
-					// Explicitly clear PWD and GOROOT_FINAL so that GOROOT=gorootCopyDir is definitely used.
-					"PWD=",
+					// Explicitly override PWD and clear GOROOT_FINAL so that GOROOT=gorootCopyDir is definitely used.
+					"PWD="+filepath.Join(gorootCopyDir, rel),
 					"GOROOT_FINAL=",
 					// Add GOROOTcopy/bin and bundleDir to front of PATH.
 					"PATH="+filepath.Join(gorootCopyDir, "bin")+string(filepath.ListSeparator)+
@@ -179,7 +208,7 @@
 			r.run(t, goBinCopy, "generate", `-run=^//go:generate bundle `, pkgs) // See issue 41409.
 			advice := "$ cd " + m.Dir + "\n" +
 				"$ go mod tidy                               # to remove extraneous dependencies\n" +
-				"$ go mod vendor                             # to vendor dependecies\n" +
+				"$ go mod vendor                             # to vendor dependencies\n" +
 				"$ go generate -run=bundle " + pkgs + "               # to regenerate bundled packages\n"
 			if m.Path == "std" {
 				r.run(t, goBinCopy, "generate", "syscall", "internal/syscall/...") // See issue 43440.
@@ -227,7 +256,7 @@
 		if err != nil {
 			return err
 		}
-		if src == filepath.Join(runtime.GOROOT(), ".git") {
+		if info.IsDir() && src == filepath.Join(runtime.GOROOT(), ".git") {
 			return filepath.SkipDir
 		}
 
@@ -237,9 +266,8 @@
 		}
 		dst := filepath.Join(gorootCopyDir, rel)
 
-		switch src {
-		case filepath.Join(runtime.GOROOT(), "bin"),
-			filepath.Join(runtime.GOROOT(), "pkg"):
+		if info.IsDir() && (src == filepath.Join(runtime.GOROOT(), "bin") ||
+			src == filepath.Join(runtime.GOROOT(), "pkg")) {
 			// If the OS supports symlinks, use them instead
 			// of copying the bin and pkg directories.
 			if err := os.Symlink(src, dst); err == nil {
@@ -414,7 +442,7 @@
 			if info.IsDir() && (info.Name() == "vendor" || info.Name() == "testdata") {
 				return filepath.SkipDir
 			}
-			if path == filepath.Join(runtime.GOROOT(), "pkg") {
+			if info.IsDir() && path == filepath.Join(runtime.GOROOT(), "pkg") {
 				// GOROOT/pkg contains generated artifacts, not source code.
 				//
 				// In https://golang.org/issue/37929 it was observed to somehow contain
@@ -422,6 +450,12 @@
 				// running time of this test anyway.)
 				return filepath.SkipDir
 			}
+			if info.IsDir() && (strings.HasPrefix(info.Name(), "_") || strings.HasPrefix(info.Name(), ".")) {
+				// _ and . prefixed directories can be used for internal modules
+				// without a vendor directory that don't contribute to the build
+				// but might be used for example as code generators.
+				return filepath.SkipDir
+			}
 			if info.IsDir() || info.Name() != "go.mod" {
 				return nil
 			}
@@ -451,8 +485,31 @@
 			goroot.modules = append(goroot.modules, m)
 			return nil
 		})
-	})
+		if goroot.err != nil {
+			return
+		}
 
+		// knownGOROOTModules is a hard-coded list of modules that are known to exist in GOROOT.
+		// If findGorootModules doesn't find a module, it won't be covered by tests at all,
+		// so make sure at least these modules are found. See issue 46254. If this list
+		// becomes a nuisance to update, can be replaced with len(goroot.modules) check.
+		knownGOROOTModules := [...]string{
+			"std",
+			"cmd",
+			"misc",
+			"test/bench/go1",
+		}
+		var seen = make(map[string]bool) // Key is module path.
+		for _, m := range goroot.modules {
+			seen[m.Path] = true
+		}
+		for _, m := range knownGOROOTModules {
+			if !seen[m] {
+				goroot.err = fmt.Errorf("findGorootModules didn't find the well-known module %q", m)
+				break
+			}
+		}
+	})
 	if goroot.err != nil {
 		t.Fatal(goroot.err)
 	}
diff --git a/src/cmd/internal/obj/arm/a.out.go b/src/cmd/internal/obj/arm/a.out.go
index a1d9e28..fd695ad 100644
--- a/src/cmd/internal/obj/arm/a.out.go
+++ b/src/cmd/internal/obj/arm/a.out.go
@@ -163,8 +163,8 @@
 	C_SFCON
 	C_LFCON
 
-	C_RACON
-	C_LACON
+	C_RACON /* <=0xff rotated constant offset from auto */
+	C_LACON /* Large Auto CONstant, i.e. large offset from SP */
 
 	C_SBRA
 	C_LBRA
diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go
index ebb98b4..ccf5f9e 100644
--- a/src/cmd/internal/obj/arm/asm5.go
+++ b/src/cmd/internal/obj/arm/asm5.go
@@ -34,6 +34,7 @@
 	"cmd/internal/obj"
 	"cmd/internal/objabi"
 	"fmt"
+	"internal/buildcfg"
 	"log"
 	"math"
 	"sort"
@@ -976,7 +977,7 @@
 			if immrot(^uint32(c.instoffset)) != 0 {
 				return C_NCON
 			}
-			if uint32(c.instoffset) <= 0xffff && objabi.GOARM == 7 {
+			if uint32(c.instoffset) <= 0xffff && buildcfg.GOARM == 7 {
 				return C_SCON
 			}
 			if x, y := immrot2a(uint32(c.instoffset)); x != 0 && y != 0 {
@@ -3044,7 +3045,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 || math.Float64bits(e) != 0 {
+	if buildcfg.GOARM < 7 || math.Float64bits(e) != 0 {
 		return -1
 	}
 	return 0
@@ -3052,7 +3053,7 @@
 
 func (c *ctxt5) chipfloat5(e float64) int {
 	// We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions.
-	if objabi.GOARM < 7 {
+	if buildcfg.GOARM < 7 {
 		return -1
 	}
 
diff --git a/src/cmd/internal/obj/arm/obj5.go b/src/cmd/internal/obj/arm/obj5.go
index 29d3a58..1454d8a 100644
--- a/src/cmd/internal/obj/arm/obj5.go
+++ b/src/cmd/internal/obj/arm/obj5.go
@@ -34,6 +34,8 @@
 	"cmd/internal/obj"
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
+	"internal/buildcfg"
+	"log"
 )
 
 var progedit_tlsfallback *obj.LSym
@@ -63,7 +65,7 @@
 				ctxt.Diag("%v: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p.Line())
 			}
 
-			if objabi.GOARM < 7 {
+			if buildcfg.GOARM < 7 {
 				// Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension.
 				if progedit_tlsfallback == nil {
 					progedit_tlsfallback = ctxt.Lookup("runtime.read_tls_fallback")
@@ -613,6 +615,21 @@
 				p.From.Reg = REGSP
 			}
 		}
+
+		if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
+			f := c.cursym.Func()
+			if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
+				c.cursym.Func().FuncFlag |= objabi.FuncFlag_SPWRITE
+				if ctxt.Debugvlog || !ctxt.IsAsm {
+					ctxt.Logf("auto-SPWRITE: %s %v\n", c.cursym.Name, p)
+					if !ctxt.IsAsm {
+						ctxt.Diag("invalid auto-SPWRITE in non-assembly")
+						ctxt.DiagFlush()
+						log.Fatalf("bad SPWRITE")
+					}
+				}
+			}
+		}
 	}
 }
 
@@ -664,57 +681,37 @@
 		p.From.Reg = REG_R1
 		p.Reg = REG_R2
 	} else {
-		// Such a large stack we need to protect against wraparound
-		// if SP is close to zero.
-		//	SP-stackguard+StackGuard < framesize + (StackGuard-StackSmall)
-		// The +StackGuard on both sides is required to keep the left side positive:
-		// SP is allowed to be slightly below stackguard. See stack.h.
-		//	CMP     $StackPreempt, R1
-		//	MOVW.NE $StackGuard(SP), R2
-		//	SUB.NE  R1, R2
-		//	MOVW.NE $(framesize+(StackGuard-StackSmall)), R3
-		//	CMP.NE  R3, R2
-		p = obj.Appendp(p, c.newprog)
-
-		p.As = ACMP
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = int64(uint32(objabi.StackPreempt & (1<<32 - 1)))
-		p.Reg = REG_R1
-
-		p = obj.Appendp(p, c.newprog)
-		p.As = AMOVW
-		p.From.Type = obj.TYPE_ADDR
-		p.From.Reg = REGSP
-		p.From.Offset = int64(objabi.StackGuard)
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R2
-		p.Scond = C_SCOND_NE
+		// Such a large stack we need to protect against underflow.
+		// The runtime guarantees SP > objabi.StackBig, but
+		// framesize is large enough that SP-framesize may
+		// underflow, causing a direct comparison with the
+		// stack guard to incorrectly succeed. We explicitly
+		// guard against underflow.
+		//
+		//	// Try subtracting from SP and check for underflow.
+		//	// If this underflows, it sets C to 0.
+		//	SUB.S $(framesize-StackSmall), SP, R2
+		//	// If C is 1 (unsigned >=), compare with guard.
+		//	CMP.HS stackguard, R2
 
 		p = obj.Appendp(p, c.newprog)
 		p.As = ASUB
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R1
+		p.Scond = C_SBIT
+		p.From.Type = obj.TYPE_CONST
+		p.From.Offset = int64(framesize) - objabi.StackSmall
+		p.Reg = REGSP
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = REG_R2
-		p.Scond = C_SCOND_NE
-
-		p = obj.Appendp(p, c.newprog)
-		p.As = AMOVW
-		p.From.Type = obj.TYPE_ADDR
-		p.From.Offset = int64(framesize) + (int64(objabi.StackGuard) - objabi.StackSmall)
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R3
-		p.Scond = C_SCOND_NE
 
 		p = obj.Appendp(p, c.newprog)
 		p.As = ACMP
+		p.Scond = C_SCOND_HS
 		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R3
+		p.From.Reg = REG_R1
 		p.Reg = REG_R2
-		p.Scond = C_SCOND_NE
 	}
 
-	// BLS call-to-morestack
+	// BLS call-to-morestack (C is 0 or Z is 1)
 	bls := obj.Appendp(p, c.newprog)
 	bls.As = ABLS
 	bls.To.Type = obj.TYPE_BRANCH
diff --git a/src/cmd/internal/obj/arm64/a.out.go b/src/cmd/internal/obj/arm64/a.out.go
index 1d1bea5..bf75bb4 100644
--- a/src/cmd/internal/obj/arm64/a.out.go
+++ b/src/cmd/internal/obj/arm64/a.out.go
@@ -239,7 +239,7 @@
 	REGCTXT = REG_R26 // environment for closures
 	REGTMP  = REG_R27 // reserved for liblink
 	REGG    = REG_R28 // G
-	REGFP   = REG_R29 // frame pointer, unused in the Go toolchain
+	REGFP   = REG_R29 // frame pointer
 	REGLINK = REG_R30
 
 	// ARM64 uses R31 as both stack pointer and zero register,
@@ -420,16 +420,21 @@
 	C_LBRA
 
 	C_ZAUTO       // 0(RSP)
+	C_NSAUTO_16   // -256 <= x < 0, 0 mod 16
 	C_NSAUTO_8    // -256 <= x < 0, 0 mod 8
 	C_NSAUTO_4    // -256 <= x < 0, 0 mod 4
 	C_NSAUTO      // -256 <= x < 0
+	C_NPAUTO_16   // -512 <= x < 0, 0 mod 16
 	C_NPAUTO      // -512 <= x < 0, 0 mod 8
+	C_NQAUTO_16   // -1024 <= x < 0, 0 mod 16
 	C_NAUTO4K     // -4095 <= x < 0
+	C_PSAUTO_16   // 0 to 255, 0 mod 16
 	C_PSAUTO_8    // 0 to 255, 0 mod 8
 	C_PSAUTO_4    // 0 to 255, 0 mod 4
 	C_PSAUTO      // 0 to 255
 	C_PPAUTO_16   // 0 to 504, 0 mod 16
 	C_PPAUTO      // 0 to 504, 0 mod 8
+	C_PQAUTO_16   // 0 to 1008, 0 mod 16
 	C_UAUTO4K_16  // 0 to 4095, 0 mod 16
 	C_UAUTO4K_8   // 0 to 4095, 0 mod 8
 	C_UAUTO4K_4   // 0 to 4095, 0 mod 4
@@ -454,17 +459,22 @@
 	C_SEXT16 // 0 to 65520
 	C_LEXT
 
-	C_ZOREG    // 0(R)
-	C_NSOREG_8 // must mirror C_NSAUTO_8, etc
+	C_ZOREG     // 0(R)
+	C_NSOREG_16 // must mirror C_NSAUTO_16, etc
+	C_NSOREG_8
 	C_NSOREG_4
 	C_NSOREG
+	C_NPOREG_16
 	C_NPOREG
+	C_NQOREG_16
 	C_NOREG4K
+	C_PSOREG_16
 	C_PSOREG_8
 	C_PSOREG_4
 	C_PSOREG
 	C_PPOREG_16
 	C_PPOREG
+	C_PQOREG_16
 	C_UOREG4K_16
 	C_UOREG4K_8
 	C_UOREG4K_4
@@ -898,6 +908,7 @@
 	AFDIVD
 	AFDIVS
 	AFLDPD
+	AFLDPQ
 	AFLDPS
 	AFMOVQ
 	AFMOVD
@@ -912,6 +923,7 @@
 	AFSQRTD
 	AFSQRTS
 	AFSTPD
+	AFSTPQ
 	AFSTPS
 	AFSUBD
 	AFSUBS
@@ -1019,6 +1031,8 @@
 	AVEXT
 	AVRBIT
 	AVRAX1
+	AVUMAX
+	AVUMIN
 	AVUSHR
 	AVUSHLL
 	AVUSHLL2
diff --git a/src/cmd/internal/obj/arm64/anames.go b/src/cmd/internal/obj/arm64/anames.go
index a98f8c7..9cc5871 100644
--- a/src/cmd/internal/obj/arm64/anames.go
+++ b/src/cmd/internal/obj/arm64/anames.go
@@ -392,6 +392,7 @@
 	"FDIVD",
 	"FDIVS",
 	"FLDPD",
+	"FLDPQ",
 	"FLDPS",
 	"FMOVQ",
 	"FMOVD",
@@ -406,6 +407,7 @@
 	"FSQRTD",
 	"FSQRTS",
 	"FSTPD",
+	"FSTPQ",
 	"FSTPS",
 	"FSUBD",
 	"FSUBS",
@@ -513,6 +515,8 @@
 	"VEXT",
 	"VRBIT",
 	"VRAX1",
+	"VUMAX",
+	"VUMIN",
 	"VUSHR",
 	"VUSHLL",
 	"VUSHLL2",
diff --git a/src/cmd/internal/obj/arm64/anames7.go b/src/cmd/internal/obj/arm64/anames7.go
index f7e9951..2ecd816 100644
--- a/src/cmd/internal/obj/arm64/anames7.go
+++ b/src/cmd/internal/obj/arm64/anames7.go
@@ -42,15 +42,21 @@
 	"SBRA",
 	"LBRA",
 	"ZAUTO",
+	"NSAUTO_16",
 	"NSAUTO_8",
 	"NSAUTO_4",
 	"NSAUTO",
+	"NPAUTO_16",
 	"NPAUTO",
+	"NQAUTO_16",
 	"NAUTO4K",
+	"PSAUTO_16",
 	"PSAUTO_8",
 	"PSAUTO_4",
 	"PSAUTO",
+	"PPAUTO_16",
 	"PPAUTO",
+	"PQAUTO_16",
 	"UAUTO4K_16",
 	"UAUTO4K_8",
 	"UAUTO4K_4",
@@ -74,15 +80,21 @@
 	"SEXT16",
 	"LEXT",
 	"ZOREG",
+	"NSOREG_16",
 	"NSOREG_8",
 	"NSOREG_4",
 	"NSOREG",
+	"NPOREG_16",
 	"NPOREG",
+	"NQOREG_16",
 	"NOREG4K",
+	"PSOREG_16",
 	"PSOREG_8",
 	"PSOREG_4",
 	"PSOREG",
+	"PPOREG_16",
 	"PPOREG",
+	"PQOREG_16",
 	"UOREG4K_16",
 	"UOREG4K_8",
 	"UOREG4K_4",
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index 70072cf..d99afa3 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -321,15 +321,17 @@
 	{ACMP, C_VCON, C_REG, C_NONE, C_NONE, 13, 20, 0, 0, 0},
 	{AADD, C_SHIFT, C_REG, C_NONE, C_REG, 3, 4, 0, 0, 0},
 	{AADD, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
+	{AADD, C_SHIFT, C_RSP, C_NONE, C_RSP, 26, 4, 0, 0, 0},
+	{AADD, C_SHIFT, C_NONE, C_NONE, C_RSP, 26, 4, 0, 0, 0},
 	{AMVN, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
 	{ACMP, C_SHIFT, C_REG, C_NONE, C_NONE, 3, 4, 0, 0, 0},
-	{ANEG, C_SHIFT, C_NONE, C_NONE, C_REG, 26, 4, 0, 0, 0},
+	{ACMP, C_SHIFT, C_RSP, C_NONE, C_NONE, 26, 4, 0, 0, 0},
+	{ANEG, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
 	{AADD, C_REG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0},
 	{AADD, C_REG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
 	{ACMP, C_REG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0},
 	{AADD, C_EXTREG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0},
 	{AADD, C_EXTREG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
-	{AMVN, C_EXTREG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
 	{ACMP, C_EXTREG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0},
 	{AADD, C_REG, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
 	{AADD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0, 0, 0},
@@ -404,8 +406,8 @@
 	/* MOVs that become MOVK/MOVN/MOVZ/ADD/SUB/OR */
 	{AMOVW, C_MOVCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
 	{AMOVD, C_MOVCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
-	{AMOVW, C_BITCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
-	{AMOVD, C_BITCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
+	{AMOVW, C_BITCON, C_NONE, C_NONE, C_RSP, 32, 4, 0, 0, 0},
+	{AMOVD, C_BITCON, C_NONE, C_NONE, C_RSP, 32, 4, 0, 0, 0},
 	{AMOVW, C_MOVCON2, C_NONE, C_NONE, C_REG, 12, 8, 0, NOTUSETMP, 0},
 	{AMOVD, C_MOVCON2, C_NONE, C_NONE, C_REG, 12, 8, 0, NOTUSETMP, 0},
 	{AMOVD, C_MOVCON3, C_NONE, C_NONE, C_REG, 12, 12, 0, NOTUSETMP, 0},
@@ -499,6 +501,8 @@
 	{AVMOV, C_REG, C_NONE, C_NONE, C_ELEM, 78, 4, 0, 0, 0},
 	{AVMOV, C_ARNG, C_NONE, C_NONE, C_ARNG, 83, 4, 0, 0, 0},
 	{AVDUP, C_ELEM, C_NONE, C_NONE, C_ARNG, 79, 4, 0, 0, 0},
+	{AVDUP, C_ELEM, C_NONE, C_NONE, C_VREG, 80, 4, 0, 0, 0},
+	{AVDUP, C_REG, C_NONE, C_NONE, C_ARNG, 82, 4, 0, 0, 0},
 	{AVMOVI, C_ADDCON, C_NONE, C_NONE, C_ARNG, 86, 4, 0, 0, 0},
 	{AVFMLA, C_ARNG, C_ARNG, C_NONE, C_ARNG, 72, 4, 0, 0, 0},
 	{AVEXT, C_VCON, C_ARNG, C_ARNG, C_ARNG, 94, 4, 0, 0, 0},
@@ -689,6 +693,46 @@
 
 	/* pre/post-indexed/signed-offset load/store register pair
 	   (unscaled, signed 10-bit quad-aligned and long offset) */
+	{AFLDPQ, C_NQAUTO_16, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0},
+	{AFLDPQ, C_NQAUTO_16, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPRE},
+	{AFLDPQ, C_NQAUTO_16, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPOST},
+	{AFLDPQ, C_PQAUTO_16, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0},
+	{AFLDPQ, C_PQAUTO_16, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPRE},
+	{AFLDPQ, C_PQAUTO_16, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPOST},
+	{AFLDPQ, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0},
+	{AFLDPQ, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0},
+	{AFLDPQ, C_LAUTO, C_NONE, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, 0},
+	{AFLDPQ, C_NQOREG_16, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, 0},
+	{AFLDPQ, C_NQOREG_16, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
+	{AFLDPQ, C_NQOREG_16, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
+	{AFLDPQ, C_PQOREG_16, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, 0},
+	{AFLDPQ, C_PQOREG_16, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
+	{AFLDPQ, C_PQOREG_16, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
+	{AFLDPQ, C_UOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, 0},
+	{AFLDPQ, C_NOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, 0},
+	{AFLDPQ, C_LOREG, C_NONE, C_NONE, C_PAIR, 75, 12, 0, LFROM, 0},
+	{AFLDPQ, C_ADDR, C_NONE, C_NONE, C_PAIR, 88, 12, 0, 0, 0},
+
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQAUTO_16, 67, 4, REGSP, 0, 0},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQAUTO_16, 67, 4, REGSP, 0, C_XPRE},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQAUTO_16, 67, 4, REGSP, 0, C_XPOST},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQAUTO_16, 67, 4, REGSP, 0, 0},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQAUTO_16, 67, 4, REGSP, 0, C_XPRE},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQAUTO_16, 67, 4, REGSP, 0, C_XPOST},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, 0},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, 76, 8, REGSP, 0, 0},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, 0},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQOREG_16, 67, 4, 0, 0, 0},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQOREG_16, 67, 4, 0, 0, C_XPRE},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQOREG_16, 67, 4, 0, 0, C_XPOST},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQOREG_16, 67, 4, 0, 0, 0},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQOREG_16, 67, 4, 0, 0, C_XPRE},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQOREG_16, 67, 4, 0, 0, C_XPOST},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_UOREG4K, 76, 8, 0, 0, 0},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NOREG4K, 76, 8, 0, 0, 0},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_LOREG, 77, 12, 0, LTO, 0},
+	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_ADDR, 87, 12, 0, 0, 0},
+
 	{ALDP, C_NPAUTO, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0},
 	{ALDP, C_NPAUTO, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPRE},
 	{ALDP, C_NPAUTO, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPOST},
@@ -696,14 +740,8 @@
 	{ALDP, C_PPAUTO, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPRE},
 	{ALDP, C_PPAUTO, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPOST},
 	{ALDP, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0},
-	{ALDP, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPRE},
-	{ALDP, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPOST},
 	{ALDP, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0},
-	{ALDP, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPRE},
-	{ALDP, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPOST},
 	{ALDP, C_LAUTO, C_NONE, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, 0},
-	{ALDP, C_LAUTO, C_NONE, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, C_XPRE},
-	{ALDP, C_LAUTO, C_NONE, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, C_XPOST},
 	{ALDP, C_NPOREG, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, 0},
 	{ALDP, C_NPOREG, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
 	{ALDP, C_NPOREG, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
@@ -711,14 +749,8 @@
 	{ALDP, C_PPOREG, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
 	{ALDP, C_PPOREG, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
 	{ALDP, C_UOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, 0},
-	{ALDP, C_UOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPRE},
-	{ALDP, C_UOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPOST},
 	{ALDP, C_NOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, 0},
-	{ALDP, C_NOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPRE},
-	{ALDP, C_NOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPOST},
 	{ALDP, C_LOREG, C_NONE, C_NONE, C_PAIR, 75, 12, 0, LFROM, 0},
-	{ALDP, C_LOREG, C_NONE, C_NONE, C_PAIR, 75, 12, 0, LFROM, C_XPRE},
-	{ALDP, C_LOREG, C_NONE, C_NONE, C_PAIR, 75, 12, 0, LFROM, C_XPOST},
 	{ALDP, C_ADDR, C_NONE, C_NONE, C_PAIR, 88, 12, 0, 0, 0},
 
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_NPAUTO, 67, 4, REGSP, 0, 0},
@@ -728,14 +760,8 @@
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_PPAUTO, 67, 4, REGSP, 0, C_XPRE},
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_PPAUTO, 67, 4, REGSP, 0, C_XPOST},
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, 0},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, C_XPRE},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, C_XPOST},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, 76, 12, REGSP, 0, 0},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, 76, 12, REGSP, 0, C_XPRE},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, 76, 12, REGSP, 0, C_XPOST},
+	{ASTP, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, 76, 8, REGSP, 0, 0},
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, 0},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, C_XPRE},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, C_XPOST},
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_NPOREG, 67, 4, 0, 0, 0},
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_NPOREG, 67, 4, 0, 0, C_XPRE},
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_NPOREG, 67, 4, 0, 0, C_XPOST},
@@ -743,14 +769,8 @@
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_PPOREG, 67, 4, 0, 0, C_XPRE},
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_PPOREG, 67, 4, 0, 0, C_XPOST},
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_UOREG4K, 76, 8, 0, 0, 0},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_UOREG4K, 76, 8, 0, 0, C_XPRE},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_UOREG4K, 76, 8, 0, 0, C_XPOST},
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_NOREG4K, 76, 8, 0, 0, 0},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_NOREG4K, 76, 8, 0, 0, C_XPRE},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_NOREG4K, 76, 8, 0, 0, C_XPOST},
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_LOREG, 77, 12, 0, LTO, 0},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_LOREG, 77, 12, 0, LTO, C_XPRE},
-	{ASTP, C_PAIR, C_NONE, C_NONE, C_LOREG, 77, 12, 0, LTO, C_XPOST},
 	{ASTP, C_PAIR, C_NONE, C_NONE, C_ADDR, 87, 12, 0, 0, 0},
 
 	// differ from LDP/STP for C_NSAUTO_4/C_PSAUTO_4/C_NSOREG_4/C_PSOREG_4
@@ -761,14 +781,8 @@
 	{ALDPW, C_PSAUTO_4, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPRE},
 	{ALDPW, C_PSAUTO_4, C_NONE, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPOST},
 	{ALDPW, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0},
-	{ALDPW, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPRE},
-	{ALDPW, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPOST},
 	{ALDPW, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0},
-	{ALDPW, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPRE},
-	{ALDPW, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPOST},
 	{ALDPW, C_LAUTO, C_NONE, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, 0},
-	{ALDPW, C_LAUTO, C_NONE, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, C_XPRE},
-	{ALDPW, C_LAUTO, C_NONE, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, C_XPOST},
 	{ALDPW, C_NSOREG_4, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, 0},
 	{ALDPW, C_NSOREG_4, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
 	{ALDPW, C_NSOREG_4, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
@@ -776,14 +790,8 @@
 	{ALDPW, C_PSOREG_4, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
 	{ALDPW, C_PSOREG_4, C_NONE, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
 	{ALDPW, C_UOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, 0},
-	{ALDPW, C_UOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPRE},
-	{ALDPW, C_UOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPOST},
 	{ALDPW, C_NOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, 0},
-	{ALDPW, C_NOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPRE},
-	{ALDPW, C_NOREG4K, C_NONE, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPOST},
 	{ALDPW, C_LOREG, C_NONE, C_NONE, C_PAIR, 75, 12, 0, LFROM, 0},
-	{ALDPW, C_LOREG, C_NONE, C_NONE, C_PAIR, 75, 12, 0, LFROM, C_XPRE},
-	{ALDPW, C_LOREG, C_NONE, C_NONE, C_PAIR, 75, 12, 0, LFROM, C_XPOST},
 	{ALDPW, C_ADDR, C_NONE, C_NONE, C_PAIR, 88, 12, 0, 0, 0},
 
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NSAUTO_4, 67, 4, REGSP, 0, 0},
@@ -793,14 +801,8 @@
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_PSAUTO_4, 67, 4, REGSP, 0, C_XPRE},
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_PSAUTO_4, 67, 4, REGSP, 0, C_XPOST},
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, 0},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, C_XPRE},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, C_XPOST},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, 76, 12, REGSP, 0, 0},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, 76, 12, REGSP, 0, C_XPRE},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, 76, 12, REGSP, 0, C_XPOST},
+	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, 76, 8, REGSP, 0, 0},
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, 0},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, C_XPRE},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, C_XPOST},
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NSOREG_4, 67, 4, 0, 0, 0},
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NSOREG_4, 67, 4, 0, 0, C_XPRE},
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NSOREG_4, 67, 4, 0, 0, C_XPOST},
@@ -808,14 +810,8 @@
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_PSOREG_4, 67, 4, 0, 0, C_XPRE},
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_PSOREG_4, 67, 4, 0, 0, C_XPOST},
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_UOREG4K, 76, 8, 0, 0, 0},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_UOREG4K, 76, 8, 0, 0, C_XPRE},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_UOREG4K, 76, 8, 0, 0, C_XPOST},
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NOREG4K, 76, 8, 0, 0, 0},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NOREG4K, 76, 8, 0, 0, C_XPRE},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NOREG4K, 76, 8, 0, 0, C_XPOST},
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_LOREG, 77, 12, 0, LTO, 0},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_LOREG, 77, 12, 0, LTO, C_XPRE},
-	{ASTPW, C_PAIR, C_NONE, C_NONE, C_LOREG, 77, 12, 0, LTO, C_XPOST},
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_ADDR, 87, 12, 0, 0, 0},
 
 	{ASWPD, C_REG, C_NONE, C_NONE, C_ZOREG, 47, 4, 0, 0, 0},        // RegTo2=C_REG
@@ -1204,19 +1200,16 @@
 // addpool128 adds a 128-bit constant to literal pool by two consecutive DWORD
 // instructions, the 128-bit constant is formed by ah.Offset<<64+al.Offset.
 func (c *ctxt7) addpool128(p *obj.Prog, al, ah *obj.Addr) {
-	lit := al.Offset
 	q := c.newprog()
 	q.As = ADWORD
 	q.To.Type = obj.TYPE_CONST
-	q.To.Offset = lit
-	q.Pc = int64(c.pool.size)
+	q.To.Offset = al.Offset
 
-	lit = ah.Offset
 	t := c.newprog()
 	t.As = ADWORD
 	t.To.Type = obj.TYPE_CONST
-	t.To.Offset = lit
-	t.Pc = int64(c.pool.size + 8)
+	t.To.Offset = ah.Offset
+
 	q.Link = t
 
 	if c.blitrl == nil {
@@ -1227,6 +1220,7 @@
 	}
 
 	c.elitrl = t
+	c.pool.size = roundUp(c.pool.size, 16)
 	c.pool.size += 16
 	p.Pool = q
 }
@@ -1259,88 +1253,8 @@
 		sz = 8
 	}
 
-	switch cls {
-	// TODO(aram): remove.
-	default:
-		if a.Name != obj.NAME_EXTERN {
-			fmt.Printf("addpool: %v in %v shouldn't go to default case\n", DRconv(cls), p)
-		}
-
-		t.To.Offset = a.Offset
-		t.To.Sym = a.Sym
-		t.To.Type = a.Type
-		t.To.Name = a.Name
-
-	/* This is here because MOV uint12<<12, R is disabled in optab.
-	Because of this, we need to load the constant from memory. */
-	case C_ADDCON:
-		fallthrough
-
-	case C_ZAUTO,
-		C_PSAUTO,
-		C_PSAUTO_8,
-		C_PSAUTO_4,
-		C_PPAUTO_16,
-		C_PPAUTO,
-		C_UAUTO4K_16,
-		C_UAUTO4K_8,
-		C_UAUTO4K_4,
-		C_UAUTO4K_2,
-		C_UAUTO4K,
-		C_UAUTO8K_16,
-		C_UAUTO8K_8,
-		C_UAUTO8K_4,
-		C_UAUTO8K,
-		C_UAUTO16K_16,
-		C_UAUTO16K_8,
-		C_UAUTO16K,
-		C_UAUTO32K_16,
-		C_UAUTO32K,
-		C_UAUTO64K,
-		C_NSAUTO_8,
-		C_NSAUTO_4,
-		C_NSAUTO,
-		C_NPAUTO,
-		C_NAUTO4K,
-		C_LAUTO,
-		C_PSOREG,
-		C_PSOREG_8,
-		C_PSOREG_4,
-		C_PPOREG_16,
-		C_PPOREG,
-		C_UOREG4K_16,
-		C_UOREG4K_8,
-		C_UOREG4K_4,
-		C_UOREG4K_2,
-		C_UOREG4K,
-		C_UOREG8K_16,
-		C_UOREG8K_8,
-		C_UOREG8K_4,
-		C_UOREG8K,
-		C_UOREG16K_16,
-		C_UOREG16K_8,
-		C_UOREG16K,
-		C_UOREG32K_16,
-		C_UOREG32K,
-		C_UOREG64K,
-		C_NSOREG_8,
-		C_NSOREG_4,
-		C_NSOREG,
-		C_NPOREG,
-		C_NOREG4K,
-		C_LOREG,
-		C_LACON,
-		C_ADDCON2,
-		C_LCON,
-		C_VCON:
-		if a.Name == obj.NAME_EXTERN {
-			fmt.Printf("addpool: %v in %v needs reloc\n", DRconv(cls), p)
-		}
-
-		t.To.Type = obj.TYPE_CONST
-		t.To.Offset = lit
-		break
-	}
+	t.To.Type = obj.TYPE_CONST
+	t.To.Offset = lit
 
 	for q := c.blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */
 		if q.To == t.To {
@@ -1351,7 +1265,6 @@
 
 	q := c.newprog()
 	*q = *t
-	q.Pc = int64(c.pool.size)
 	if c.blitrl == nil {
 		c.blitrl = q
 		c.pool.start = uint32(p.Pc)
@@ -1359,11 +1272,24 @@
 		c.elitrl.Link = q
 	}
 	c.elitrl = q
-	c.pool.size = -c.pool.size & (funcAlign - 1)
+	if q.As == ADWORD {
+		// make DWORD 8-byte aligned, this is not required by ISA,
+		// just to avoid performance penalties when loading from
+		// the constant pool across a cache line.
+		c.pool.size = roundUp(c.pool.size, 8)
+	}
 	c.pool.size += uint32(sz)
 	p.Pool = q
 }
 
+// roundUp rounds up x to "to".
+func roundUp(x, to uint32) uint32 {
+	if to == 0 || to&(to-1) != 0 {
+		log.Fatalf("rounded up to a value that is not a power of 2: %d\n", to)
+	}
+	return (x + to - 1) &^ (to - 1)
+}
+
 func (c *ctxt7) regoff(a *obj.Addr) uint32 {
 	c.instoffset = 0
 	c.aclass(a)
@@ -1421,6 +1347,22 @@
 	return false
 }
 
+func isADDSop(op obj.As) bool {
+	switch op {
+	case AADDS, AADDSW, ASUBS, ASUBSW:
+		return true
+	}
+	return false
+}
+
+func isNEGop(op obj.As) bool {
+	switch op {
+	case ANEG, ANEGW, ANEGS, ANEGSW:
+		return true
+	}
+	return false
+}
+
 func isRegShiftOrExt(a *obj.Addr) bool {
 	return (a.Index-obj.RBaseARM64)&REG_EXT != 0 || (a.Index-obj.RBaseARM64)&REG_LSL != 0
 }
@@ -1590,6 +1532,9 @@
 	}
 
 	if l < 0 {
+		if l >= -256 && (l&15) == 0 {
+			return C_NSAUTO_16
+		}
 		if l >= -256 && (l&7) == 0 {
 			return C_NSAUTO_8
 		}
@@ -1599,9 +1544,15 @@
 		if l >= -256 {
 			return C_NSAUTO
 		}
+		if l >= -512 && (l&15) == 0 {
+			return C_NPAUTO_16
+		}
 		if l >= -512 && (l&7) == 0 {
 			return C_NPAUTO
 		}
+		if l >= -1024 && (l&15) == 0 {
+			return C_NQAUTO_16
+		}
 		if l >= -4095 {
 			return C_NAUTO4K
 		}
@@ -1609,6 +1560,9 @@
 	}
 
 	if l <= 255 {
+		if (l & 15) == 0 {
+			return C_PSAUTO_16
+		}
 		if (l & 7) == 0 {
 			return C_PSAUTO_8
 		}
@@ -1625,6 +1579,11 @@
 			return C_PPAUTO
 		}
 	}
+	if l <= 1008 {
+		if l&15 == 0 {
+			return C_PQAUTO_16
+		}
+	}
 	if l <= 4095 {
 		if l&15 == 0 {
 			return C_UAUTO4K_16
@@ -2038,9 +1997,10 @@
 		}
 		a1 = a0 + 1
 		p.From.Class = int8(a1)
-		// more specific classification of 32-bit integers
 		if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE {
-			if p.As == AMOVW || isADDWop(p.As) {
+			if p.As == AMOVW || isADDWop(p.As) || isANDWop(p.As) {
+				// For 32-bit instruction with constant, we need to
+				// treat its offset value as 32 bits to classify it.
 				ra0 := c.con32class(&p.From)
 				// do not break C_ADDCON2 when S bit is set
 				if (p.As == AADDSW || p.As == ASUBSW) && ra0 == C_ADDCON2 {
@@ -2049,16 +2009,8 @@
 				a1 = ra0 + 1
 				p.From.Class = int8(a1)
 			}
-			if isANDWop(p.As) && a0 != C_BITCON {
-				// For 32-bit logical instruction with constant,
-				// the BITCON test is special in that it looks at
-				// the 64-bit which has the high 32-bit as a copy
-				// of the low 32-bit. We have handled that and
-				// don't pass it to con32class.
-				a1 = c.con32class(&p.From) + 1
-				p.From.Class = int8(a1)
-			}
 			if ((p.As == AMOVD) || isANDop(p.As) || isADDop(p.As)) && (a0 == C_LCON || a0 == C_VCON) {
+				// more specific classification of 64-bit integers
 				a1 = c.con64class(&p.From) + 1
 				p.From.Class = int8(a1)
 			}
@@ -2193,64 +2145,99 @@
 			return true
 		}
 
+	case C_NSAUTO_8:
+		if b == C_NSAUTO_16 {
+			return true
+		}
+
 	case C_NSAUTO_4:
-		if b == C_NSAUTO_8 {
+		if b == C_NSAUTO_16 || b == C_NSAUTO_8 {
 			return true
 		}
 
 	case C_NSAUTO:
 		switch b {
-		case C_NSAUTO_4, C_NSAUTO_8:
+		case C_NSAUTO_4, C_NSAUTO_8, C_NSAUTO_16:
+			return true
+		}
+
+	case C_NPAUTO_16:
+		switch b {
+		case C_NSAUTO_16:
 			return true
 		}
 
 	case C_NPAUTO:
 		switch b {
-		case C_NSAUTO_8:
+		case C_NSAUTO_16, C_NSAUTO_8, C_NPAUTO_16:
+			return true
+		}
+
+	case C_NQAUTO_16:
+		switch b {
+		case C_NSAUTO_16, C_NPAUTO_16:
 			return true
 		}
 
 	case C_NAUTO4K:
 		switch b {
-		case C_NSAUTO_8, C_NSAUTO_4, C_NSAUTO, C_NPAUTO:
+		case C_NSAUTO_16, C_NSAUTO_8, C_NSAUTO_4, C_NSAUTO, C_NPAUTO_16,
+			C_NPAUTO, C_NQAUTO_16:
+			return true
+		}
+
+	case C_PSAUTO_16:
+		if b == C_ZAUTO {
 			return true
 		}
 
 	case C_PSAUTO_8:
-		if b == C_ZAUTO {
+		if b == C_ZAUTO || b == C_PSAUTO_16 {
 			return true
 		}
 
 	case C_PSAUTO_4:
 		switch b {
-		case C_ZAUTO, C_PSAUTO_8:
+		case C_ZAUTO, C_PSAUTO_16, C_PSAUTO_8:
 			return true
 		}
 
 	case C_PSAUTO:
 		switch b {
-		case C_ZAUTO, C_PSAUTO_8, C_PSAUTO_4:
+		case C_ZAUTO, C_PSAUTO_16, C_PSAUTO_8, C_PSAUTO_4:
+			return true
+		}
+
+	case C_PPAUTO_16:
+		switch b {
+		case C_ZAUTO, C_PSAUTO_16:
 			return true
 		}
 
 	case C_PPAUTO:
 		switch b {
-		case C_ZAUTO, C_PSAUTO_8, C_PPAUTO_16:
+		case C_ZAUTO, C_PSAUTO_16, C_PSAUTO_8, C_PPAUTO_16:
+			return true
+		}
+
+	case C_PQAUTO_16:
+		switch b {
+		case C_ZAUTO, C_PSAUTO_16, C_PPAUTO_16:
 			return true
 		}
 
 	case C_UAUTO4K:
 		switch b {
-		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8,
-			C_PPAUTO, C_PPAUTO_16,
+		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
+			C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
 			C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16:
 			return true
 		}
 
 	case C_UAUTO8K:
 		switch b {
-		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8,
-			C_PPAUTO, C_PPAUTO_16,
+		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
+			C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
 			C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16,
 			C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16:
 			return true
@@ -2258,8 +2245,8 @@
 
 	case C_UAUTO16K:
 		switch b {
-		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8,
-			C_PPAUTO, C_PPAUTO_16,
+		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
+			C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
 			C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16,
 			C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16,
 			C_UAUTO16K_8, C_UAUTO16K_16:
@@ -2268,8 +2255,8 @@
 
 	case C_UAUTO32K:
 		switch b {
-		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8,
-			C_PPAUTO, C_PPAUTO_16,
+		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
+			C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
 			C_UAUTO4K_8, C_UAUTO4K_16,
 			C_UAUTO8K_8, C_UAUTO8K_16,
 			C_UAUTO16K_8, C_UAUTO16K_16,
@@ -2279,17 +2266,17 @@
 
 	case C_UAUTO64K:
 		switch b {
-		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8,
-			C_PPAUTO_16, C_UAUTO4K_16, C_UAUTO8K_16, C_UAUTO16K_16,
+		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
+			C_PPAUTO_16, C_PQAUTO_16, C_UAUTO4K_16, C_UAUTO8K_16, C_UAUTO16K_16,
 			C_UAUTO32K_16:
 			return true
 		}
 
 	case C_LAUTO:
 		switch b {
-		case C_ZAUTO, C_NSAUTO, C_NSAUTO_4, C_NSAUTO_8, C_NPAUTO, C_NAUTO4K,
-			C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8,
-			C_PPAUTO, C_PPAUTO_16,
+		case C_ZAUTO, C_NSAUTO, C_NSAUTO_4, C_NSAUTO_8, C_NSAUTO_16, C_NPAUTO_16, C_NPAUTO, C_NQAUTO_16, C_NAUTO4K,
+			C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
+			C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
 			C_UAUTO4K, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16,
 			C_UAUTO8K, C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16,
 			C_UAUTO16K, C_UAUTO16K_8, C_UAUTO16K_16,
@@ -2298,64 +2285,98 @@
 			return true
 		}
 
+	case C_NSOREG_8:
+		if b == C_NSOREG_16 {
+			return true
+		}
+
 	case C_NSOREG_4:
-		if b == C_NSOREG_8 {
+		if b == C_NSOREG_8 || b == C_NSOREG_16 {
 			return true
 		}
 
 	case C_NSOREG:
 		switch b {
-		case C_NSOREG_4, C_NSOREG_8:
+		case C_NSOREG_4, C_NSOREG_8, C_NSOREG_16:
+			return true
+		}
+
+	case C_NPOREG_16:
+		switch b {
+		case C_NSOREG_16:
 			return true
 		}
 
 	case C_NPOREG:
 		switch b {
-		case C_NSOREG_8:
+		case C_NSOREG_16, C_NSOREG_8, C_NPOREG_16:
+			return true
+		}
+
+	case C_NQOREG_16:
+		switch b {
+		case C_NSOREG_16, C_NPOREG_16:
 			return true
 		}
 
 	case C_NOREG4K:
 		switch b {
-		case C_NSOREG_8, C_NSOREG_4, C_NSOREG, C_NPOREG:
+		case C_NSOREG_16, C_NSOREG_8, C_NSOREG_4, C_NSOREG, C_NPOREG_16, C_NPOREG, C_NQOREG_16:
+			return true
+		}
+
+	case C_PSOREG_16:
+		if b == C_ZOREG {
 			return true
 		}
 
 	case C_PSOREG_8:
-		if b == C_ZOREG {
+		if b == C_ZOREG || b == C_PSOREG_16 {
 			return true
 		}
 
 	case C_PSOREG_4:
 		switch b {
-		case C_ZOREG, C_PSOREG_8:
+		case C_ZOREG, C_PSOREG_16, C_PSOREG_8:
 			return true
 		}
 
 	case C_PSOREG:
 		switch b {
-		case C_ZOREG, C_PSOREG_8, C_PSOREG_4:
+		case C_ZOREG, C_PSOREG_16, C_PSOREG_8, C_PSOREG_4:
+			return true
+		}
+
+	case C_PPOREG_16:
+		switch b {
+		case C_ZOREG, C_PSOREG_16:
 			return true
 		}
 
 	case C_PPOREG:
 		switch b {
-		case C_ZOREG, C_PSOREG_8, C_PPOREG_16:
+		case C_ZOREG, C_PSOREG_16, C_PSOREG_8, C_PPOREG_16:
+			return true
+		}
+
+	case C_PQOREG_16:
+		switch b {
+		case C_ZOREG, C_PSOREG_16, C_PPOREG_16:
 			return true
 		}
 
 	case C_UOREG4K:
 		switch b {
-		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8,
-			C_PPOREG, C_PPOREG_16,
+		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
+			C_PPOREG, C_PPOREG_16, C_PQOREG_16,
 			C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16:
 			return true
 		}
 
 	case C_UOREG8K:
 		switch b {
-		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8,
-			C_PPOREG, C_PPOREG_16,
+		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
+			C_PPOREG, C_PPOREG_16, C_PQOREG_16,
 			C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16,
 			C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16:
 			return true
@@ -2363,8 +2384,8 @@
 
 	case C_UOREG16K:
 		switch b {
-		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8,
-			C_PPOREG, C_PPOREG_16,
+		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
+			C_PPOREG, C_PPOREG_16, C_PQOREG_16,
 			C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16,
 			C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16,
 			C_UOREG16K_8, C_UOREG16K_16:
@@ -2373,8 +2394,8 @@
 
 	case C_UOREG32K:
 		switch b {
-		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8,
-			C_PPOREG, C_PPOREG_16,
+		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
+			C_PPOREG, C_PPOREG_16, C_PQOREG_16,
 			C_UOREG4K_8, C_UOREG4K_16,
 			C_UOREG8K_8, C_UOREG8K_16,
 			C_UOREG16K_8, C_UOREG16K_16,
@@ -2384,17 +2405,17 @@
 
 	case C_UOREG64K:
 		switch b {
-		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8,
-			C_PPOREG_16, C_UOREG4K_16, C_UOREG8K_16, C_UOREG16K_16,
+		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
+			C_PPOREG_16, C_PQOREG_16, C_UOREG4K_16, C_UOREG8K_16, C_UOREG16K_16,
 			C_UOREG32K_16:
 			return true
 		}
 
 	case C_LOREG:
 		switch b {
-		case C_ZOREG, C_NSOREG, C_NSOREG_4, C_NSOREG_8, C_NPOREG, C_NOREG4K,
-			C_PSOREG, C_PSOREG_4, C_PSOREG_8,
-			C_PPOREG, C_PPOREG_16,
+		case C_ZOREG, C_NSOREG, C_NSOREG_4, C_NSOREG_8, C_NSOREG_16, C_NPOREG, C_NPOREG_16, C_NQOREG_16, C_NOREG4K,
+			C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
+			C_PPOREG, C_PPOREG_16, C_PQOREG_16,
 			C_UOREG4K, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16,
 			C_UOREG8K, C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16,
 			C_UOREG16K, C_UOREG16K_8, C_UOREG16K_16,
@@ -2722,6 +2743,10 @@
 			obj.ATEXT:
 			break
 
+		case AFLDPQ:
+			break
+		case AFSTPQ:
+			break
 		case ALDP:
 			oprangeset(AFLDPD, t)
 
@@ -2922,6 +2947,8 @@
 			oprangeset(AVBSL, t)
 			oprangeset(AVBIT, t)
 			oprangeset(AVCMTST, t)
+			oprangeset(AVUMAX, t)
+			oprangeset(AVUMIN, t)
 			oprangeset(AVUZP1, t)
 			oprangeset(AVUZP2, t)
 			oprangeset(AVBIF, t)
@@ -3204,6 +3231,9 @@
 		o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
 
 	case 2: /* add/sub $(uimm12|uimm24)[,R],R; cmp $(uimm12|uimm24),R */
+		if p.To.Reg == REG_RSP && isADDSop(p.As) {
+			c.ctxt.Diag("illegal destination register: %v\n", p)
+		}
 		o1 = c.opirr(p, p.As)
 
 		rt := int(p.To.Reg)
@@ -3229,13 +3259,17 @@
 		if is64bit == 0 && amount >= 32 {
 			c.ctxt.Diag("shift amount out of range 0 to 31: %v", p)
 		}
+		shift := (p.From.Offset >> 22) & 3
+		if (shift > 2 || shift < 0) && (isADDop(p.As) || isADDWop(p.As) || isNEGop(p.As)) {
+			c.ctxt.Diag("unsupported shift operator: %v", p)
+		}
 		o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
 		rt := int(p.To.Reg)
 		if p.To.Type == obj.TYPE_NONE {
 			rt = REGZERO
 		}
 		r := int(p.Reg)
-		if p.As == AMVN || p.As == AMVNW {
+		if p.As == AMVN || p.As == AMVNW || isNEGop(p.As) {
 			r = REGZERO
 		} else if r == 0 {
 			r = rt
@@ -3385,6 +3419,9 @@
 		o4 = os[3]
 
 	case 13: /* addop $vcon, [R], R (64 bit literal); cmp $lcon,R -> addop $lcon,R, ZR */
+		if p.To.Reg == REG_RSP && isADDSop(p.As) {
+			c.ctxt.Diag("illegal destination register: %v\n", p)
+		}
 		o := uint32(0)
 		num := uint8(0)
 		cls := oclass(&p.From)
@@ -3499,27 +3536,25 @@
 		o1 = c.oprrr(p, p.As)
 
 		cond := int(p.From.Reg)
-		if cond < COND_EQ || cond > COND_NV {
+		// AL and NV are not allowed for CINC/CINV/CNEG/CSET/CSETM instructions
+		if cond < COND_EQ || cond > COND_NV || (cond == COND_AL || cond == COND_NV) && p.From3Type() == obj.TYPE_NONE {
 			c.ctxt.Diag("invalid condition: %v", p)
 		} else {
 			cond -= COND_EQ
 		}
 
 		r := int(p.Reg)
-		var rf int
-		if r != 0 {
-			if p.From3Type() == obj.TYPE_NONE {
-				/* CINC/CINV/CNEG */
-				rf = r
-				cond ^= 1
-			} else {
-				rf = int(p.GetFrom3().Reg) /* CSEL */
+		var rf int = r
+		if p.From3Type() == obj.TYPE_NONE {
+			/* CINC/CINV/CNEG or CSET/CSETM*/
+			if r == 0 {
+				/* CSET/CSETM */
+				rf = REGZERO
+				r = rf
 			}
-		} else {
-			/* CSET */
-			rf = REGZERO
-			r = rf
 			cond ^= 1
+		} else {
+			rf = int(p.GetFrom3().Reg) /* CSEL */
 		}
 
 		rt := int(p.To.Reg)
@@ -3584,7 +3619,7 @@
 		v := int32(p.From.Offset)
 
 		if v < -256 || v > 255 {
-			c.ctxt.Diag("offset out of range [-255,254]: %v", p)
+			c.ctxt.Diag("offset out of range [-256,255]: %v", p)
 		}
 		o1 = c.opldr(p, p.As)
 		if o.scond == C_XPOST {
@@ -3602,7 +3637,7 @@
 		v := int32(p.To.Offset)
 
 		if v < -256 || v > 255 {
-			c.ctxt.Diag("offset out of range [-255,254]: %v", p)
+			c.ctxt.Diag("offset out of range [-256,255]: %v", p)
 		}
 		o1 = c.opstr(p, p.As)
 		if o.scond == C_XPOST {
@@ -3640,14 +3675,45 @@
 		rt := int(p.To.Reg)
 		o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
 
-	case 26: /* negX Rm<<s, Rd -> subX Rm<<s, ZR, Rd */
-		o1 = c.oprrr(p, p.As)
+	case 26: // op R<<n, RSP, RSP (extended register)
+		// Refer to ARM reference manual, if "Rd" or "Rn" is RSP,
+		// it can be encoded as op(extended regster) instruction.
+		if !(p.To.Reg == REGSP || p.Reg == REGSP) {
+			c.ctxt.Diag("expected SP reference: %v", p)
+			break
+		}
+		if p.To.Reg == REGSP && (p.As == AADDS || p.As == AADDSW || p.As == ASUBS || p.As == ASUBSW) {
+			c.ctxt.Diag("unexpected SP reference: %v", p)
+			break
+		}
+		amount := (p.From.Offset >> 10) & 63
+		shift := (p.From.Offset >> 22) & 3
+		if shift != 0 {
+			c.ctxt.Diag("illegal combination: %v", p)
+			break
+		}
 
-		o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
+		if amount > 4 {
+			c.ctxt.Diag("the left shift amount out of range 0 to 4: %v", p)
+			break
+		}
+		rf := (p.From.Offset >> 16) & 31
 		rt := int(p.To.Reg)
-		o1 |= (REGZERO & 31 << 5) | uint32(rt&31)
+		r := int(p.Reg)
+		if p.To.Type == obj.TYPE_NONE {
+			rt = REGZERO
+		}
+		if r == 0 {
+			r = rt
+		}
+
+		o1 = c.opxrrr(p, p.As, false)
+		o1 |= uint32(rf)<<16 | uint32(amount&7)<<10 | (uint32(r&31) << 5) | uint32(rt&31)
 
 	case 27: /* op Rm<<n[,Rn],Rd (extended register) */
+		if p.To.Reg == REG_RSP && isADDSop(p.As) {
+			c.ctxt.Diag("illegal destination register: %v\n", p)
+		}
 		if (p.From.Reg-obj.RBaseARM64)&REG_EXT != 0 {
 			amount := (p.From.Reg >> 5) & 7
 			if amount > 4 {
@@ -4264,8 +4330,13 @@
 		if p.Reg == REGTMP {
 			c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
 		}
+		if p.To.Reg == REG_RSP && isADDSop(p.As) {
+			c.ctxt.Diag("illegal destination register: %v\n", p)
+		}
+		lsl0 := LSL0_64
 		if isADDWop(p.As) || isANDWop(p.As) {
 			o1 = c.omovconst(AMOVW, p, &p.From, REGTMP)
+			lsl0 = LSL0_32
 		} else {
 			o1 = c.omovconst(AMOVD, p, &p.From, REGTMP)
 		}
@@ -4281,7 +4352,7 @@
 		if p.To.Reg == REGSP || r == REGSP {
 			o2 = c.opxrrr(p, p.As, false)
 			o2 |= REGTMP & 31 << 16
-			o2 |= LSL0_64
+			o2 |= uint32(lsl0)
 		} else {
 			o2 = c.oprrr(p, p.As)
 			o2 |= REGTMP & 31 << 16 /* shift is 0 */
@@ -4434,6 +4505,10 @@
 			if af != ARNG_2D && af != ARNG_2S && af != ARNG_4S {
 				c.ctxt.Diag("invalid arrangement: %v", p)
 			}
+		case AVUMAX, AVUMIN:
+			if af == ARNG_2D {
+				c.ctxt.Diag("invalid arrangement: %v", p)
+			}
 		}
 		switch p.As {
 		case AVAND, AVEOR:
@@ -4650,13 +4725,13 @@
 		o1 |= (uint32(Q&1) << 30) | (uint32(imm5&0x1f) << 16)
 		o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
 
-	case 80: /* vmov V.<T>[index], Vn */
+	case 80: /* vmov/vdup V.<T>[index], Vn */
 		rf := int(p.From.Reg)
 		rt := int(p.To.Reg)
 		imm5 := 0
 		index := int(p.From.Index)
 		switch p.As {
-		case AVMOV:
+		case AVMOV, AVDUP:
 			o1 = 1<<30 | 15<<25 | 1<<10
 			switch (p.From.Reg >> 5) & 15 {
 			case ARNG_B:
@@ -4706,7 +4781,7 @@
 		o1 = c.maskOpvldvst(p, o1)
 		o1 |= uint32(r&31) << 5
 
-	case 82: /* vmov Rn, Vd.<T> */
+	case 82: /* vmov/vdup Rn, Vd.<T> */
 		rf := int(p.From.Reg)
 		rt := int(p.To.Reg)
 		o1 = 7<<25 | 3<<10
@@ -4734,7 +4809,7 @@
 			Q = 1
 			imm5 = 2
 		default:
-			c.ctxt.Diag("invalid arrangement on VMOV Rn, Vd.<T>: %v\n", p)
+			c.ctxt.Diag("invalid arrangement: %v\n", p)
 		}
 		o1 |= (Q & 1 << 30) | (imm5 & 0x1f << 16)
 		o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
@@ -6110,6 +6185,12 @@
 	case AVCMTST:
 		return 0xE<<24 | 1<<21 | 0x23<<10
 
+	case AVUMAX:
+		return 1<<29 | 7<<25 | 1<<21 | 0x19<<10
+
+	case AVUMIN:
+		return 1<<29 | 7<<25 | 1<<21 | 0x1b<<10
+
 	case AVUZP1:
 		return 7<<25 | 3<<11
 
@@ -6387,11 +6468,10 @@
 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:
+		if isADDop(a) {
 			extension = LSL0_64
-
-		case AADDW, ACMNW, AADDSW, ASUBW, ACMPW, ASUBSW:
+		}
+		if isADDWop(a) {
 			extension = LSL0_32
 		}
 	}
@@ -7192,7 +7272,7 @@
 	return o
 }
 
-/* genrate instruction encoding for LDP/LDPW/LDPSW/STP/STPW */
+/* genrate instruction encoding for ldp and stp series */
 func (c *ctxt7) opldpstp(p *obj.Prog, o *Optab, vo int32, rbase, rl, rh, ldp uint32) uint32 {
 	wback := false
 	if o.scond == C_XPOST || o.scond == C_XPRE {
@@ -7205,30 +7285,36 @@
 		if wback == true {
 			c.checkUnpredictable(p, false, true, p.To.Reg, p.From.Reg, int16(p.From.Offset))
 		}
-	case AFLDPD, AFLDPS:
+	case AFLDPD, AFLDPQ, AFLDPS:
 		c.checkUnpredictable(p, true, false, p.From.Reg, p.To.Reg, int16(p.To.Offset))
 	}
 	var ret uint32
 	// check offset
 	switch p.As {
+	case AFLDPQ, AFSTPQ:
+		if vo < -1024 || vo > 1008 || vo%16 != 0 {
+			c.ctxt.Diag("invalid offset %v\n", p)
+		}
+		vo /= 16
+		ret = 2<<30 | 1<<26
 	case AFLDPD, AFSTPD:
 		if vo < -512 || vo > 504 || vo%8 != 0 {
 			c.ctxt.Diag("invalid offset %v\n", p)
 		}
 		vo /= 8
 		ret = 1<<30 | 1<<26
-	case ALDP, ASTP:
-		if vo < -512 || vo > 504 || vo%8 != 0 {
-			c.ctxt.Diag("invalid offset %v\n", p)
-		}
-		vo /= 8
-		ret = 2 << 30
 	case AFLDPS, AFSTPS:
 		if vo < -256 || vo > 252 || vo%4 != 0 {
 			c.ctxt.Diag("invalid offset %v\n", p)
 		}
 		vo /= 4
 		ret = 1 << 26
+	case ALDP, ASTP:
+		if vo < -512 || vo > 504 || vo%8 != 0 {
+			c.ctxt.Diag("invalid offset %v\n", p)
+		}
+		vo /= 8
+		ret = 2 << 30
 	case ALDPW, ASTPW:
 		if vo < -256 || vo > 252 || vo%4 != 0 {
 			c.ctxt.Diag("invalid offset %v\n", p)
@@ -7246,7 +7332,7 @@
 	}
 	// check register pair
 	switch p.As {
-	case AFLDPD, AFLDPS, AFSTPD, AFSTPS:
+	case AFLDPQ, AFLDPD, AFLDPS, AFSTPQ, AFSTPD, AFSTPS:
 		if rl < REG_F0 || REG_F31 < rl || rh < REG_F0 || REG_F31 < rh {
 			c.ctxt.Diag("invalid register pair %v\n", p)
 		}
diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go
index 0baf519..e41fb3b 100644
--- a/src/cmd/internal/obj/arm64/obj7.go
+++ b/src/cmd/internal/obj/arm64/obj7.go
@@ -35,6 +35,8 @@
 	"cmd/internal/objabi"
 	"cmd/internal/src"
 	"cmd/internal/sys"
+	"internal/buildcfg"
+	"log"
 	"math"
 )
 
@@ -106,55 +108,35 @@
 		p.From.Reg = REG_R1
 		p.Reg = REG_R2
 	} else {
-		// Such a large stack we need to protect against wraparound
-		// if SP is close to zero.
-		//	SP-stackguard+StackGuard < framesize + (StackGuard-StackSmall)
-		// The +StackGuard on both sides is required to keep the left side positive:
-		// SP is allowed to be slightly below stackguard. See stack.h.
-		//	CMP	$StackPreempt, R1
-		//	BEQ	label_of_call_to_morestack
-		//	ADD	$StackGuard, SP, R2
-		//	SUB	R1, R2
-		//	MOV	$(framesize+(StackGuard-StackSmall)), R3
-		//	CMP	R3, R2
-		p = obj.Appendp(p, c.newprog)
+		// Such a large stack we need to protect against underflow.
+		// The runtime guarantees SP > objabi.StackBig, but
+		// framesize is large enough that SP-framesize may
+		// underflow, causing a direct comparison with the
+		// stack guard to incorrectly succeed. We explicitly
+		// guard against underflow.
+		//
+		//	SUBS	$(framesize-StackSmall), SP, R2
+		//	// On underflow, jump to morestack
+		//	BLO	label_of_call_to_morestack
+		//	CMP	stackguard, R2
 
-		p.As = ACMP
+		p = obj.Appendp(p, c.newprog)
+		p.As = ASUBS
 		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = objabi.StackPreempt
-		p.Reg = REG_R1
-
-		p = obj.Appendp(p, c.newprog)
-		q = p
-		p.As = ABEQ
-		p.To.Type = obj.TYPE_BRANCH
-
-		p = obj.Appendp(p, c.newprog)
-		p.As = AADD
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = int64(objabi.StackGuard)
+		p.From.Offset = int64(framesize) - objabi.StackSmall
 		p.Reg = REGSP
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = REG_R2
 
 		p = obj.Appendp(p, c.newprog)
-		p.As = ASUB
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R1
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R2
-
-		p = obj.Appendp(p, c.newprog)
-		p.As = AMOVD
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = int64(framesize) + (int64(objabi.StackGuard) - objabi.StackSmall)
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R3
+		q = p
+		p.As = ABLO
+		p.To.Type = obj.TYPE_BRANCH
 
 		p = obj.Appendp(p, c.newprog)
 		p.As = ACMP
 		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R3
+		p.From.Reg = REG_R1
 		p.Reg = REG_R2
 	}
 
@@ -313,13 +295,13 @@
 		}
 	}
 
-	// For 32-bit logical instruction with constant,
-	// rewrite the high 32-bit to be a repetition of
-	// the low 32-bit, so that the BITCON test can be
-	// shared for both 32-bit and 64-bit. 32-bit ops
-	// will zero the high 32-bit of the destination
-	// register anyway.
-	if isANDWop(p.As) && p.From.Type == obj.TYPE_CONST {
+	// For 32-bit instruction with constant, rewrite
+	// the high 32-bit to be a repetition of the low
+	// 32-bit, so that the BITCON test can be shared
+	// for both 32-bit and 64-bit. 32-bit ops will
+	// zero the high 32-bit of the destination register
+	// anyway.
+	if (isANDWop(p.As) || isADDWop(p.As) || p.As == AMOVW) && p.From.Type == obj.TYPE_CONST {
 		v := p.From.Offset & 0xffffffff
 		p.From.Offset = v | v<<32
 	}
@@ -538,6 +520,12 @@
 				}
 			}
 
+			if p.Mark&LEAF != 0 && c.autosize < objabi.StackSmall {
+				// A leaf function with a small stack can be marked
+				// NOSPLIT, avoiding a stack check.
+				p.From.Sym.Set(obj.AttrNoSplit, true)
+			}
+
 			if !p.From.Sym.NoSplit() {
 				p = c.stacksplit(p, c.autosize) // emit split check
 			}
@@ -589,7 +577,7 @@
 				q1.To.Reg = REGSP
 				q1.Spadj = c.autosize
 
-				if objabi.GOOS == "ios" {
+				if buildcfg.GOOS == "ios" {
 					// iOS does not support SA_ONSTACK. We will run the signal handler
 					// on the G stack. If we write below SP, it may be clobbered by
 					// the signal handler. So we save LR after decrementing SP.
@@ -621,25 +609,24 @@
 
 			prologueEnd.Pos = prologueEnd.Pos.WithXlogue(src.PosPrologueEnd)
 
-			if objabi.Framepointer_enabled {
-				q1 = obj.Appendp(q1, c.newprog)
-				q1.Pos = p.Pos
-				q1.As = AMOVD
-				q1.From.Type = obj.TYPE_REG
-				q1.From.Reg = REGFP
-				q1.To.Type = obj.TYPE_MEM
-				q1.To.Reg = REGSP
-				q1.To.Offset = -8
+			// Frame pointer.
+			q1 = obj.Appendp(q1, c.newprog)
+			q1.Pos = p.Pos
+			q1.As = AMOVD
+			q1.From.Type = obj.TYPE_REG
+			q1.From.Reg = REGFP
+			q1.To.Type = obj.TYPE_MEM
+			q1.To.Reg = REGSP
+			q1.To.Offset = -8
 
-				q1 = obj.Appendp(q1, c.newprog)
-				q1.Pos = p.Pos
-				q1.As = ASUB
-				q1.From.Type = obj.TYPE_CONST
-				q1.From.Offset = 8
-				q1.Reg = REGSP
-				q1.To.Type = obj.TYPE_REG
-				q1.To.Reg = REGFP
-			}
+			q1 = obj.Appendp(q1, c.newprog)
+			q1.Pos = p.Pos
+			q1.As = ASUB
+			q1.From.Type = obj.TYPE_CONST
+			q1.From.Offset = 8
+			q1.Reg = REGSP
+			q1.To.Type = obj.TYPE_REG
+			q1.To.Reg = REGFP
 
 			if c.cursym.Func().Text.From.Sym.Wrapper() {
 				// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
@@ -764,28 +751,26 @@
 					p.To.Reg = REGSP
 					p.Spadj = -c.autosize
 
-					if objabi.Framepointer_enabled {
-						p = obj.Appendp(p, c.newprog)
-						p.As = ASUB
-						p.From.Type = obj.TYPE_CONST
-						p.From.Offset = 8
-						p.Reg = REGSP
-						p.To.Type = obj.TYPE_REG
-						p.To.Reg = REGFP
-					}
+					// Frame pointer.
+					p = obj.Appendp(p, c.newprog)
+					p.As = ASUB
+					p.From.Type = obj.TYPE_CONST
+					p.From.Offset = 8
+					p.Reg = REGSP
+					p.To.Type = obj.TYPE_REG
+					p.To.Reg = REGFP
 				}
 			} else {
 				/* want write-back pre-indexed SP+autosize -> SP, loading REGLINK*/
 
-				if objabi.Framepointer_enabled {
-					p.As = AMOVD
-					p.From.Type = obj.TYPE_MEM
-					p.From.Reg = REGSP
-					p.From.Offset = -8
-					p.To.Type = obj.TYPE_REG
-					p.To.Reg = REGFP
-					p = obj.Appendp(p, c.newprog)
-				}
+				// Frame pointer.
+				p.As = AMOVD
+				p.From.Type = obj.TYPE_MEM
+				p.From.Reg = REGSP
+				p.From.Offset = -8
+				p.To.Type = obj.TYPE_REG
+				p.To.Reg = REGFP
+				p = obj.Appendp(p, c.newprog)
 
 				aoffset := c.autosize
 
@@ -820,6 +805,28 @@
 				}
 			}
 
+			// If enabled, this code emits 'MOV PC, R27' before every 'MOV LR, PC',
+			// so that if you are debugging a low-level crash where PC and LR are zero,
+			// you can look at R27 to see what jumped to the zero.
+			// This is useful when bringing up Go on a new system.
+			// (There is similar code in ../ppc64/obj9.go:/if.false.)
+			const debugRETZERO = false
+			if debugRETZERO {
+				if p.As != obj.ARET {
+					q = newprog()
+					q.Pos = p.Pos
+					q.Link = p.Link
+					p.Link = q
+					p = q
+				}
+				p.As = AADR
+				p.From.Type = obj.TYPE_BRANCH
+				p.From.Offset = 0
+				p.To.Type = obj.TYPE_REG
+				p.To.Reg = REGTMP
+
+			}
+
 			if p.As != obj.ARET {
 				q = newprog()
 				q.Pos = p.Pos
@@ -865,109 +872,120 @@
 			}
 
 		case obj.ADUFFCOPY:
-			if objabi.Framepointer_enabled {
-				//  ADR	ret_addr, R27
-				//  STP	(FP, R27), -24(SP)
-				//  SUB	24, SP, FP
-				//  DUFFCOPY
-				// ret_addr:
-				//  SUB	8, SP, FP
+			//  ADR	ret_addr, R27
+			//  STP	(FP, R27), -24(SP)
+			//  SUB	24, SP, FP
+			//  DUFFCOPY
+			// ret_addr:
+			//  SUB	8, SP, FP
 
-				q1 := p
-				// copy DUFFCOPY from q1 to q4
-				q4 := obj.Appendp(p, c.newprog)
-				q4.Pos = p.Pos
-				q4.As = obj.ADUFFCOPY
-				q4.To = p.To
+			q1 := p
+			// copy DUFFCOPY from q1 to q4
+			q4 := obj.Appendp(p, c.newprog)
+			q4.Pos = p.Pos
+			q4.As = obj.ADUFFCOPY
+			q4.To = p.To
 
-				q1.As = AADR
-				q1.From.Type = obj.TYPE_BRANCH
-				q1.To.Type = obj.TYPE_REG
-				q1.To.Reg = REG_R27
+			q1.As = AADR
+			q1.From.Type = obj.TYPE_BRANCH
+			q1.To.Type = obj.TYPE_REG
+			q1.To.Reg = REG_R27
 
-				q2 := obj.Appendp(q1, c.newprog)
-				q2.Pos = p.Pos
-				q2.As = ASTP
-				q2.From.Type = obj.TYPE_REGREG
-				q2.From.Reg = REGFP
-				q2.From.Offset = int64(REG_R27)
-				q2.To.Type = obj.TYPE_MEM
-				q2.To.Reg = REGSP
-				q2.To.Offset = -24
+			q2 := obj.Appendp(q1, c.newprog)
+			q2.Pos = p.Pos
+			q2.As = ASTP
+			q2.From.Type = obj.TYPE_REGREG
+			q2.From.Reg = REGFP
+			q2.From.Offset = int64(REG_R27)
+			q2.To.Type = obj.TYPE_MEM
+			q2.To.Reg = REGSP
+			q2.To.Offset = -24
 
-				// maintaine FP for DUFFCOPY
-				q3 := obj.Appendp(q2, c.newprog)
-				q3.Pos = p.Pos
-				q3.As = ASUB
-				q3.From.Type = obj.TYPE_CONST
-				q3.From.Offset = 24
-				q3.Reg = REGSP
-				q3.To.Type = obj.TYPE_REG
-				q3.To.Reg = REGFP
+			// maintain FP for DUFFCOPY
+			q3 := obj.Appendp(q2, c.newprog)
+			q3.Pos = p.Pos
+			q3.As = ASUB
+			q3.From.Type = obj.TYPE_CONST
+			q3.From.Offset = 24
+			q3.Reg = REGSP
+			q3.To.Type = obj.TYPE_REG
+			q3.To.Reg = REGFP
 
-				q5 := obj.Appendp(q4, c.newprog)
-				q5.Pos = p.Pos
-				q5.As = ASUB
-				q5.From.Type = obj.TYPE_CONST
-				q5.From.Offset = 8
-				q5.Reg = REGSP
-				q5.To.Type = obj.TYPE_REG
-				q5.To.Reg = REGFP
-				q1.From.SetTarget(q5)
-				p = q5
-			}
+			q5 := obj.Appendp(q4, c.newprog)
+			q5.Pos = p.Pos
+			q5.As = ASUB
+			q5.From.Type = obj.TYPE_CONST
+			q5.From.Offset = 8
+			q5.Reg = REGSP
+			q5.To.Type = obj.TYPE_REG
+			q5.To.Reg = REGFP
+			q1.From.SetTarget(q5)
+			p = q5
 
 		case obj.ADUFFZERO:
-			if objabi.Framepointer_enabled {
-				//  ADR	ret_addr, R27
-				//  STP	(FP, R27), -24(SP)
-				//  SUB	24, SP, FP
-				//  DUFFZERO
-				// ret_addr:
-				//  SUB	8, SP, FP
+			//  ADR	ret_addr, R27
+			//  STP	(FP, R27), -24(SP)
+			//  SUB	24, SP, FP
+			//  DUFFZERO
+			// ret_addr:
+			//  SUB	8, SP, FP
 
-				q1 := p
-				// copy DUFFZERO from q1 to q4
-				q4 := obj.Appendp(p, c.newprog)
-				q4.Pos = p.Pos
-				q4.As = obj.ADUFFZERO
-				q4.To = p.To
+			q1 := p
+			// copy DUFFZERO from q1 to q4
+			q4 := obj.Appendp(p, c.newprog)
+			q4.Pos = p.Pos
+			q4.As = obj.ADUFFZERO
+			q4.To = p.To
 
-				q1.As = AADR
-				q1.From.Type = obj.TYPE_BRANCH
-				q1.To.Type = obj.TYPE_REG
-				q1.To.Reg = REG_R27
+			q1.As = AADR
+			q1.From.Type = obj.TYPE_BRANCH
+			q1.To.Type = obj.TYPE_REG
+			q1.To.Reg = REG_R27
 
-				q2 := obj.Appendp(q1, c.newprog)
-				q2.Pos = p.Pos
-				q2.As = ASTP
-				q2.From.Type = obj.TYPE_REGREG
-				q2.From.Reg = REGFP
-				q2.From.Offset = int64(REG_R27)
-				q2.To.Type = obj.TYPE_MEM
-				q2.To.Reg = REGSP
-				q2.To.Offset = -24
+			q2 := obj.Appendp(q1, c.newprog)
+			q2.Pos = p.Pos
+			q2.As = ASTP
+			q2.From.Type = obj.TYPE_REGREG
+			q2.From.Reg = REGFP
+			q2.From.Offset = int64(REG_R27)
+			q2.To.Type = obj.TYPE_MEM
+			q2.To.Reg = REGSP
+			q2.To.Offset = -24
 
-				// maintaine FP for DUFFZERO
-				q3 := obj.Appendp(q2, c.newprog)
-				q3.Pos = p.Pos
-				q3.As = ASUB
-				q3.From.Type = obj.TYPE_CONST
-				q3.From.Offset = 24
-				q3.Reg = REGSP
-				q3.To.Type = obj.TYPE_REG
-				q3.To.Reg = REGFP
+			// maintain FP for DUFFZERO
+			q3 := obj.Appendp(q2, c.newprog)
+			q3.Pos = p.Pos
+			q3.As = ASUB
+			q3.From.Type = obj.TYPE_CONST
+			q3.From.Offset = 24
+			q3.Reg = REGSP
+			q3.To.Type = obj.TYPE_REG
+			q3.To.Reg = REGFP
 
-				q5 := obj.Appendp(q4, c.newprog)
-				q5.Pos = p.Pos
-				q5.As = ASUB
-				q5.From.Type = obj.TYPE_CONST
-				q5.From.Offset = 8
-				q5.Reg = REGSP
-				q5.To.Type = obj.TYPE_REG
-				q5.To.Reg = REGFP
-				q1.From.SetTarget(q5)
-				p = q5
+			q5 := obj.Appendp(q4, c.newprog)
+			q5.Pos = p.Pos
+			q5.As = ASUB
+			q5.From.Type = obj.TYPE_CONST
+			q5.From.Offset = 8
+			q5.Reg = REGSP
+			q5.To.Type = obj.TYPE_REG
+			q5.To.Reg = REGFP
+			q1.From.SetTarget(q5)
+			p = q5
+		}
+
+		if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
+			f := c.cursym.Func()
+			if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
+				c.cursym.Func().FuncFlag |= objabi.FuncFlag_SPWRITE
+				if ctxt.Debugvlog || !ctxt.IsAsm {
+					ctxt.Logf("auto-SPWRITE: %s %v\n", c.cursym.Name, p)
+					if !ctxt.IsAsm {
+						ctxt.Diag("invalid auto-SPWRITE in non-assembly")
+						ctxt.DiagFlush()
+						log.Fatalf("bad SPWRITE")
+					}
+				}
 			}
 		}
 	}
diff --git a/src/cmd/internal/obj/data.go b/src/cmd/internal/obj/data.go
index f32e07a..bcba53c 100644
--- a/src/cmd/internal/obj/data.go
+++ b/src/cmd/internal/obj/data.go
@@ -135,6 +135,13 @@
 	s.writeAddr(ctxt, off, siz, rsym, roff, objabi.R_ADDR)
 }
 
+// WriteWeakAddr writes an address of size siz into s at offset off.
+// rsym and roff specify the relocation for the address.
+// This is a weak reference.
+func (s *LSym) WriteWeakAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) {
+	s.writeAddr(ctxt, off, siz, rsym, roff, objabi.R_WEAKADDR)
+}
+
 // 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
diff --git a/src/cmd/internal/obj/dwarf.go b/src/cmd/internal/obj/dwarf.go
index 87c62e2..6dd53ff 100644
--- a/src/cmd/internal/obj/dwarf.go
+++ b/src/cmd/internal/obj/dwarf.go
@@ -402,6 +402,31 @@
 	dwarf.PutIntConst(dwCtxt{ctxt}, s, ctxt.Lookup(dwarf.InfoPrefix+typename), myimportpath+"."+name, val)
 }
 
+// DwarfGlobal creates a link symbol containing a DWARF entry for
+// a global variable.
+func (ctxt *Link) DwarfGlobal(myimportpath, typename string, varSym *LSym) {
+	if myimportpath == "" || varSym.Local() {
+		return
+	}
+	var varname string
+	if varSym.Pkg == "_" {
+		// The frontend uses package "_" to mark symbols that should not
+		// be referenced by index, e.g. linkname'd symbols.
+		varname = varSym.Name
+	} else {
+		// Convert "".<name> into a fully qualified package.sym name.
+		varname = objabi.PathToPrefix(myimportpath) + varSym.Name[len(`""`):]
+	}
+	dieSymName := dwarf.InfoPrefix + varname
+	dieSym := ctxt.LookupInit(dieSymName, func(s *LSym) {
+		s.Type = objabi.SDWARFVAR
+		s.Set(AttrDuplicateOK, true) // needed for shared linkage
+		ctxt.Data = append(ctxt.Data, s)
+	})
+	typeSym := ctxt.Lookup(dwarf.InfoPrefix + typename)
+	dwarf.PutGlobal(dwCtxt{ctxt}, dieSym, typeSym, varSym, varname)
+}
+
 func (ctxt *Link) DwarfAbstractFunc(curfn interface{}, s *LSym, myimportpath string) {
 	absfn := ctxt.DwFixups.AbsFuncDwarfSym(s)
 	if absfn.Size != 0 {
diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go
index 8c8ff58..28626e6 100644
--- a/src/cmd/internal/obj/link.go
+++ b/src/cmd/internal/obj/link.go
@@ -39,6 +39,7 @@
 	"cmd/internal/sys"
 	"fmt"
 	"sync"
+	"sync/atomic"
 )
 
 // An Addr is an argument to an instruction.
@@ -250,6 +251,12 @@
 	a.Val = t
 }
 
+func (a *Addr) SetConst(v int64) {
+	a.Sym = nil
+	a.Type = TYPE_CONST
+	a.Offset = v
+}
+
 // Prog describes a single machine instruction.
 //
 // The general instruction form is:
@@ -353,7 +360,21 @@
 	p.RestArgs = []AddrPos{{a, Source}}
 }
 
-// SetTo2 assings []Args{{a, 1}} to p.RestArgs when the second destination
+// SetFrom3Reg calls p.SetFrom3 with a register Addr containing reg.
+//
+// Deprecated: for the same reasons as Prog.GetFrom3.
+func (p *Prog) SetFrom3Reg(reg int16) {
+	p.SetFrom3(Addr{Type: TYPE_REG, Reg: reg})
+}
+
+// SetFrom3Const calls p.SetFrom3 with a const Addr containing x.
+//
+// Deprecated: for the same reasons as Prog.GetFrom3.
+func (p *Prog) SetFrom3Const(off int64) {
+	p.SetFrom3(Addr{Type: TYPE_CONST, Offset: off})
+}
+
+// SetTo2 assigns []Args{{a, 1}} to p.RestArgs when the second destination
 // operand does not fit into prog.RegTo2.
 func (p *Prog) SetTo2(a Addr) {
 	p.RestArgs = []AddrPos{{a, Destination}}
@@ -447,10 +468,12 @@
 	Locals   int32
 	Align    int32
 	FuncID   objabi.FuncID
+	FuncFlag objabi.FuncFlag
 	Text     *Prog
 	Autot    map[*LSym]struct{}
 	Pcln     Pcln
 	InlMarks []InlMark
+	spills   []RegSpill
 
 	dwarfInfoSym       *LSym
 	dwarfLocSym        *LSym
@@ -462,6 +485,7 @@
 	GCLocals           *LSym
 	StackObjects       *LSym
 	OpenCodedDeferInfo *LSym
+	ArgInfo            *LSym // argument info for traceback
 
 	FuncInfoSym *LSym
 }
@@ -530,6 +554,11 @@
 	fi.InlMarks = append(fi.InlMarks, InlMark{p: p, id: id})
 }
 
+// AddSpill appends a spill record to the list for FuncInfo fi
+func (fi *FuncInfo) AddSpill(s RegSpill) {
+	fi.spills = append(fi.spills, s)
+}
+
 // Record the type symbol for an auto variable so that the linker
 // an emit DWARF type information for the type.
 func (fi *FuncInfo) RecordAutoType(gotype *LSym) {
@@ -575,6 +604,48 @@
 	}
 }
 
+// ABISet is a bit set of ABI values.
+type ABISet uint8
+
+const (
+	// ABISetCallable is the set of all ABIs any function could
+	// potentially be called using.
+	ABISetCallable ABISet = (1 << ABI0) | (1 << ABIInternal)
+)
+
+// Ensure ABISet is big enough to hold all ABIs.
+var _ ABISet = 1 << (ABICount - 1)
+
+func ABISetOf(abi ABI) ABISet {
+	return 1 << abi
+}
+
+func (a *ABISet) Set(abi ABI, value bool) {
+	if value {
+		*a |= 1 << abi
+	} else {
+		*a &^= 1 << abi
+	}
+}
+
+func (a *ABISet) Get(abi ABI) bool {
+	return (*a>>abi)&1 != 0
+}
+
+func (a ABISet) String() string {
+	s := "{"
+	for i := ABI(0); a != 0; i++ {
+		if a&(1<<i) != 0 {
+			if s != "{" {
+				s += ","
+			}
+			s += i.String()
+			a &^= 1 << i
+		}
+	}
+	return s + "}"
+}
+
 // Attribute is a set of symbol attributes.
 type Attribute uint32
 
@@ -612,10 +683,6 @@
 	// target of an inline during compilation
 	AttrWasInlined
 
-	// TopFrame means that this function is an entry point and unwinders should not
-	// keep unwinding beyond this frame.
-	AttrTopFrame
-
 	// Indexed indicates this symbol has been assigned with an index (when using the
 	// new object file format).
 	AttrIndexed
@@ -629,6 +696,10 @@
 	// ContentAddressable indicates this is a content-addressable symbol.
 	AttrContentAddressable
 
+	// ABI wrapper is set for compiler-generated text symbols that
+	// convert between ABI0 and ABIInternal calling conventions.
+	AttrABIWrapper
+
 	// attrABIBase is the value at which the ABI is encoded in
 	// Attribute. This must be last; all bits after this are
 	// assumed to be an ABI value.
@@ -637,36 +708,51 @@
 	attrABIBase
 )
 
-func (a Attribute) DuplicateOK() bool        { return a&AttrDuplicateOK != 0 }
-func (a Attribute) MakeTypelink() bool       { return a&AttrMakeTypelink != 0 }
-func (a Attribute) CFunc() bool              { return a&AttrCFunc != 0 }
-func (a Attribute) NoSplit() bool            { return a&AttrNoSplit != 0 }
-func (a Attribute) Leaf() bool               { return a&AttrLeaf != 0 }
-func (a Attribute) OnList() bool             { return a&AttrOnList != 0 }
-func (a Attribute) ReflectMethod() bool      { return a&AttrReflectMethod != 0 }
-func (a Attribute) Local() bool              { return a&AttrLocal != 0 }
-func (a Attribute) Wrapper() bool            { return a&AttrWrapper != 0 }
-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) TopFrame() bool           { return a&AttrTopFrame != 0 }
-func (a Attribute) Indexed() bool            { return a&AttrIndexed != 0 }
-func (a Attribute) UsedInIface() bool        { return a&AttrUsedInIface != 0 }
-func (a Attribute) ContentAddressable() bool { return a&AttrContentAddressable != 0 }
+func (a *Attribute) load() Attribute { return Attribute(atomic.LoadUint32((*uint32)(a))) }
+
+func (a *Attribute) DuplicateOK() bool        { return a.load()&AttrDuplicateOK != 0 }
+func (a *Attribute) MakeTypelink() bool       { return a.load()&AttrMakeTypelink != 0 }
+func (a *Attribute) CFunc() bool              { return a.load()&AttrCFunc != 0 }
+func (a *Attribute) NoSplit() bool            { return a.load()&AttrNoSplit != 0 }
+func (a *Attribute) Leaf() bool               { return a.load()&AttrLeaf != 0 }
+func (a *Attribute) OnList() bool             { return a.load()&AttrOnList != 0 }
+func (a *Attribute) ReflectMethod() bool      { return a.load()&AttrReflectMethod != 0 }
+func (a *Attribute) Local() bool              { return a.load()&AttrLocal != 0 }
+func (a *Attribute) Wrapper() bool            { return a.load()&AttrWrapper != 0 }
+func (a *Attribute) NeedCtxt() bool           { return a.load()&AttrNeedCtxt != 0 }
+func (a *Attribute) NoFrame() bool            { return a.load()&AttrNoFrame != 0 }
+func (a *Attribute) Static() bool             { return a.load()&AttrStatic != 0 }
+func (a *Attribute) WasInlined() bool         { return a.load()&AttrWasInlined != 0 }
+func (a *Attribute) Indexed() bool            { return a.load()&AttrIndexed != 0 }
+func (a *Attribute) UsedInIface() bool        { return a.load()&AttrUsedInIface != 0 }
+func (a *Attribute) ContentAddressable() bool { return a.load()&AttrContentAddressable != 0 }
+func (a *Attribute) ABIWrapper() bool         { return a.load()&AttrABIWrapper != 0 }
 
 func (a *Attribute) Set(flag Attribute, value bool) {
-	if value {
-		*a |= flag
-	} else {
-		*a &^= flag
+	for {
+		v0 := a.load()
+		v := v0
+		if value {
+			v |= flag
+		} else {
+			v &^= flag
+		}
+		if atomic.CompareAndSwapUint32((*uint32)(a), uint32(v0), uint32(v)) {
+			break
+		}
 	}
 }
 
-func (a Attribute) ABI() ABI { return ABI(a / attrABIBase) }
+func (a *Attribute) ABI() ABI { return ABI(a.load() / attrABIBase) }
 func (a *Attribute) SetABI(abi ABI) {
 	const mask = 1 // Only one ABI bit for now.
-	*a = (*a &^ (mask * attrABIBase)) | Attribute(abi)*attrABIBase
+	for {
+		v0 := a.load()
+		v := (v0 &^ (mask * attrABIBase)) | Attribute(abi)*attrABIBase
+		if atomic.CompareAndSwapUint32((*uint32)(a), uint32(v0), uint32(v)) {
+			break
+		}
+	}
 }
 
 var textAttrStrings = [...]struct {
@@ -686,13 +772,13 @@
 	{bit: AttrNoFrame, s: "NOFRAME"},
 	{bit: AttrStatic, s: "STATIC"},
 	{bit: AttrWasInlined, s: ""},
-	{bit: AttrTopFrame, s: "TOPFRAME"},
 	{bit: AttrIndexed, s: ""},
 	{bit: AttrContentAddressable, s: ""},
+	{bit: AttrABIWrapper, s: "ABIWRAPPER"},
 }
 
-// TextAttrString formats a for printing in as part of a TEXT prog.
-func (a Attribute) TextAttrString() string {
+// String formats a for printing in as part of a TEXT prog.
+func (a Attribute) String() string {
 	var s string
 	for _, x := range textAttrStrings {
 		if a&x.bit != 0 {
@@ -718,13 +804,25 @@
 	return s
 }
 
+// TextAttrString formats the symbol attributes for printing in as part of a TEXT prog.
+func (s *LSym) TextAttrString() string {
+	attr := s.Attribute.String()
+	if s.Func().FuncFlag&objabi.FuncFlag_TOPFRAME != 0 {
+		if attr != "" {
+			attr += "|"
+		}
+		attr += "TOPFRAME"
+	}
+	return attr
+}
+
 func (s *LSym) String() string {
 	return s.Name
 }
 
 // The compiler needs *LSym to be assignable to cmd/compile/internal/ssa.Sym.
-func (s *LSym) CanBeAnSSASym() {
-}
+func (*LSym) CanBeAnSSASym() {}
+func (*LSym) CanBeAnSSAAux() {}
 
 type Pcln struct {
 	// Aux symbols for pcln
@@ -754,6 +852,17 @@
 	Gotype  *LSym
 }
 
+// RegSpill provides spill/fill information for a register-resident argument
+// to a function.  These need spilling/filling in the safepoint/stackgrowth case.
+// At the time of fill/spill, the offset must be adjusted by the architecture-dependent
+// adjustment to hardware SP that occurs in a call instruction.  E.g., for AMD64,
+// at Offset+8 because the return address was pushed.
+type RegSpill struct {
+	Addr           Addr
+	Reg            int16
+	Spill, Unspill As
+}
+
 // 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 {
@@ -832,6 +941,36 @@
 	ctxt.Bso.Flush()
 }
 
+// SpillRegisterArgs emits the code to spill register args into whatever
+// locations the spill records specify.
+func (fi *FuncInfo) SpillRegisterArgs(last *Prog, pa ProgAlloc) *Prog {
+	// Spill register args.
+	for _, ra := range fi.spills {
+		spill := Appendp(last, pa)
+		spill.As = ra.Spill
+		spill.From.Type = TYPE_REG
+		spill.From.Reg = ra.Reg
+		spill.To = ra.Addr
+		last = spill
+	}
+	return last
+}
+
+// UnspillRegisterArgs emits the code to restore register args from whatever
+// locations the spill records specify.
+func (fi *FuncInfo) UnspillRegisterArgs(last *Prog, pa ProgAlloc) *Prog {
+	// Unspill any spilled register args
+	for _, ra := range fi.spills {
+		unspill := Appendp(last, pa)
+		unspill.As = ra.Unspill
+		unspill.From = ra.Addr
+		unspill.To.Type = TYPE_REG
+		unspill.To.Reg = ra.Reg
+		last = unspill
+	}
+	return last
+}
+
 // The smallest possible offset from the hardware stack pointer to a local
 // variable on the stack. Architectures that use a link register save its value
 // on the stack in the function prologue and so always have a pointer between
@@ -853,6 +992,7 @@
 type LinkArch struct {
 	*sys.Arch
 	Init           func(*Link)
+	ErrorCheck     func(*Link, *LSym)
 	Preprocess     func(*Link, *LSym, ProgAlloc)
 	Assemble       func(*Link, *LSym, ProgAlloc)
 	Progedit       func(*Link, *Prog, ProgAlloc)
diff --git a/src/cmd/internal/obj/mips/a.out.go b/src/cmd/internal/obj/mips/a.out.go
index ddd048a..c6ce53a 100644
--- a/src/cmd/internal/obj/mips/a.out.go
+++ b/src/cmd/internal/obj/mips/a.out.go
@@ -390,6 +390,8 @@
 	AREM
 	AREMU
 	ARFE
+	AROTR
+	AROTRV
 	ASC
 	ASCV
 	ASGT
diff --git a/src/cmd/internal/obj/mips/anames.go b/src/cmd/internal/obj/mips/anames.go
index 2a44e4c..ca2ad5a 100644
--- a/src/cmd/internal/obj/mips/anames.go
+++ b/src/cmd/internal/obj/mips/anames.go
@@ -78,6 +78,8 @@
 	"REM",
 	"REMU",
 	"RFE",
+	"ROTR",
+	"ROTRV",
 	"SC",
 	"SCV",
 	"SGT",
diff --git a/src/cmd/internal/obj/mips/asm0.go b/src/cmd/internal/obj/mips/asm0.go
index fd29f9f..e475ffd 100644
--- a/src/cmd/internal/obj/mips/asm0.go
+++ b/src/cmd/internal/obj/mips/asm0.go
@@ -1022,10 +1022,12 @@
 		case ASLL:
 			opset(ASRL, r0)
 			opset(ASRA, r0)
+			opset(AROTR, r0)
 
 		case ASLLV:
 			opset(ASRAV, r0)
 			opset(ASRLV, r0)
+			opset(AROTRV, r0)
 
 		case ASUB:
 			opset(ASUBU, r0)
@@ -1732,12 +1734,16 @@
 		return OP(0, 6)
 	case ASRA:
 		return OP(0, 7)
+	case AROTR:
+		return OP(8, 6)
 	case ASLLV:
 		return OP(2, 4)
 	case ASRLV:
 		return OP(2, 6)
 	case ASRAV:
 		return OP(2, 7)
+	case AROTRV:
+		return OP(10, 6)
 	case AADDV:
 		return OP(5, 4)
 	case AADDVU:
@@ -1916,6 +1922,8 @@
 		return OP(0, 2)
 	case ASRA:
 		return OP(0, 3)
+	case AROTR:
+		return OP(0, 2) | 1<<21
 	case AADDV:
 		return SP(3, 0)
 	case AADDVU:
@@ -2028,12 +2036,16 @@
 		return OP(7, 2)
 	case ASRAV:
 		return OP(7, 3)
+	case AROTRV:
+		return OP(7, 2) | 1<<21
 	case -ASLLV:
 		return OP(7, 4)
 	case -ASRLV:
 		return OP(7, 6)
 	case -ASRAV:
 		return OP(7, 7)
+	case -AROTRV:
+		return OP(7, 6) | 1<<21
 
 	case ATEQ:
 		return OP(6, 4)
@@ -2061,7 +2073,8 @@
 	switch a {
 	case ASLLV,
 		ASRLV,
-		ASRAV:
+		ASRAV,
+		AROTRV:
 		return true
 	}
 	return false
diff --git a/src/cmd/internal/obj/mips/obj0.go b/src/cmd/internal/obj/mips/obj0.go
index 135a8df..1f31d0c 100644
--- a/src/cmd/internal/obj/mips/obj0.go
+++ b/src/cmd/internal/obj/mips/obj0.go
@@ -35,6 +35,7 @@
 	"cmd/internal/sys"
 	"encoding/binary"
 	"fmt"
+	"log"
 	"math"
 )
 
@@ -536,6 +537,21 @@
 				p.From.Reg = REGSP
 			}
 		}
+
+		if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
+			f := c.cursym.Func()
+			if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
+				c.cursym.Func().FuncFlag |= objabi.FuncFlag_SPWRITE
+				if ctxt.Debugvlog || !ctxt.IsAsm {
+					ctxt.Logf("auto-SPWRITE: %s %v\n", c.cursym.Name, p)
+					if !ctxt.IsAsm {
+						ctxt.Diag("invalid auto-SPWRITE in non-assembly")
+						ctxt.DiagFlush()
+						log.Fatalf("bad SPWRITE")
+					}
+				}
+			}
+		}
 	}
 
 	if c.ctxt.Arch.Family == sys.MIPS {
@@ -632,16 +648,14 @@
 }
 
 func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
-	var mov, add, sub obj.As
+	var mov, add obj.As
 
 	if c.ctxt.Arch.Family == sys.MIPS64 {
 		add = AADDV
 		mov = AMOVV
-		sub = ASUBVU
 	} else {
 		add = AADDU
 		mov = AMOVW
-		sub = ASUBU
 	}
 
 	// MOV	g_stackguard(g), R1
@@ -675,15 +689,45 @@
 		p.Reg = REG_R1
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = REG_R1
-	} else if framesize <= objabi.StackBig {
+	} else {
 		// large stack: SP-framesize < stackguard-StackSmall
+		offset := int64(framesize) - objabi.StackSmall
+		if framesize > objabi.StackBig {
+			// Such a large stack we need to protect against underflow.
+			// The runtime guarantees SP > objabi.StackBig, but
+			// framesize is large enough that SP-framesize may
+			// underflow, causing a direct comparison with the
+			// stack guard to incorrectly succeed. We explicitly
+			// guard against underflow.
+			//
+			//	SGTU	$(framesize-StackSmall), SP, R2
+			//	BNE	R2, label-of-call-to-morestack
+
+			p = obj.Appendp(p, c.newprog)
+			p.As = ASGTU
+			p.From.Type = obj.TYPE_CONST
+			p.From.Offset = offset
+			p.Reg = REGSP
+			p.To.Type = obj.TYPE_REG
+			p.To.Reg = REG_R2
+
+			p = obj.Appendp(p, c.newprog)
+			q = p
+			p.As = ABNE
+			p.From.Type = obj.TYPE_REG
+			p.From.Reg = REG_R2
+			p.To.Type = obj.TYPE_BRANCH
+			p.Mark |= BRANCH
+		}
+
+		// Check against the stack guard. We've ensured this won't underflow.
 		//	ADD	$-(framesize-StackSmall), SP, R2
 		//	SGTU	R2, stackguard, R1
 		p = obj.Appendp(p, c.newprog)
 
 		p.As = add
 		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = -(int64(framesize) - objabi.StackSmall)
+		p.From.Offset = -offset
 		p.Reg = REGSP
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = REG_R2
@@ -695,68 +739,6 @@
 		p.Reg = REG_R1
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = REG_R1
-	} else {
-		// Such a large stack we need to protect against wraparound.
-		// If SP is close to zero:
-		//	SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
-		// The +StackGuard on both sides is required to keep the left side positive:
-		// SP is allowed to be slightly below stackguard. See stack.h.
-		//
-		// Preemption sets stackguard to StackPreempt, a very large value.
-		// That breaks the math above, so we have to check for that explicitly.
-		//	// stackguard is R1
-		//	MOV	$StackPreempt, R2
-		//	BEQ	R1, R2, label-of-call-to-morestack
-		//	ADD	$StackGuard, SP, R2
-		//	SUB	R1, R2
-		//	MOV	$(framesize+(StackGuard-StackSmall)), R1
-		//	SGTU	R2, R1, R1
-		p = obj.Appendp(p, c.newprog)
-
-		p.As = mov
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = objabi.StackPreempt
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R2
-
-		p = obj.Appendp(p, c.newprog)
-		q = p
-		p.As = ABEQ
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R1
-		p.Reg = REG_R2
-		p.To.Type = obj.TYPE_BRANCH
-		p.Mark |= BRANCH
-
-		p = obj.Appendp(p, c.newprog)
-		p.As = add
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = int64(objabi.StackGuard)
-		p.Reg = REGSP
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R2
-
-		p = obj.Appendp(p, c.newprog)
-		p.As = sub
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R1
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R2
-
-		p = obj.Appendp(p, c.newprog)
-		p.As = mov
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = int64(framesize) + int64(objabi.StackGuard) - objabi.StackSmall
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R1
-
-		p = obj.Appendp(p, c.newprog)
-		p.As = ASGTU
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R2
-		p.Reg = REG_R1
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R1
 	}
 
 	// q1: BNE	R1, done
diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go
index bb58b4f..24fb5a1 100644
--- a/src/cmd/internal/obj/objfile.go
+++ b/src/cmd/internal/obj/objfile.go
@@ -330,9 +330,6 @@
 	if s.ReflectMethod() {
 		flag |= goobj.SymFlagReflectMethod
 	}
-	if s.TopFrame() {
-		flag |= goobj.SymFlagTopFrame
-	}
 	if strings.HasPrefix(s.Name, "type.") && s.Name[5] != '.' && s.Type == objabi.SRODATA {
 		flag |= goobj.SymFlagGoType
 	}
@@ -386,7 +383,7 @@
 
 func (w *writer) Hash64(s *LSym) {
 	if !s.ContentAddressable() || len(s.R) != 0 {
-		panic("Hash of non-content-addresable symbol")
+		panic("Hash of non-content-addressable symbol")
 	}
 	b := contentHash64(s)
 	w.Bytes(b[:])
@@ -394,7 +391,7 @@
 
 func (w *writer) Hash(s *LSym) {
 	if !s.ContentAddressable() {
-		panic("Hash of non-content-addresable symbol")
+		panic("Hash of non-content-addressable symbol")
 	}
 	b := w.contentHash(s)
 	w.Bytes(b[:])
@@ -501,7 +498,7 @@
 	var o goobj.Reloc
 	o.SetOff(r.Off)
 	o.SetSiz(r.Siz)
-	o.SetType(uint8(r.Type))
+	o.SetType(uint16(r.Type))
 	o.SetAdd(r.Add)
 	o.SetSym(makeSymRef(r.Sym))
 	o.Write(w.Writer)
@@ -673,9 +670,10 @@
 			continue
 		}
 		o := goobj.FuncInfo{
-			Args:   uint32(fn.Args),
-			Locals: uint32(fn.Locals),
-			FuncID: objabi.FuncID(fn.FuncID),
+			Args:     uint32(fn.Args),
+			Locals:   uint32(fn.Locals),
+			FuncID:   fn.FuncID,
+			FuncFlag: fn.FuncFlag,
 		}
 		pc := &fn.Pcln
 		o.Pcsp = makeSymRef(preparePcSym(pc.Pcsp))
@@ -788,7 +786,7 @@
 	if s.NoSplit() {
 		fmt.Fprintf(ctxt.Bso, "nosplit ")
 	}
-	if s.TopFrame() {
+	if s.Func() != nil && s.Func().FuncFlag&objabi.FuncFlag_TOPFRAME != 0 {
 		fmt.Fprintf(ctxt.Bso, "topframe ")
 	}
 	fmt.Fprintf(ctxt.Bso, "size=%d", s.Size)
diff --git a/src/cmd/internal/obj/pcln.go b/src/cmd/internal/obj/pcln.go
index 67c4f9a..7af8133 100644
--- a/src/cmd/internal/obj/pcln.go
+++ b/src/cmd/internal/obj/pcln.go
@@ -37,7 +37,7 @@
 	oldval := val
 	fn := func_.Func()
 	if fn.Text == nil {
-		// Return the emtpy symbol we've built so far.
+		// Return the empty symbol we've built so far.
 		return sym
 	}
 
diff --git a/src/cmd/internal/obj/plist.go b/src/cmd/internal/obj/plist.go
index 2b09699..6beb4dd 100644
--- a/src/cmd/internal/obj/plist.go
+++ b/src/cmd/internal/obj/plist.go
@@ -75,33 +75,60 @@
 		newprog = ctxt.NewProg
 	}
 
-	// Add reference to Go arguments for C or assembly functions without them.
-	for _, s := range text {
-		if !strings.HasPrefix(s.Name, "\"\".") {
-			continue
-		}
-		found := false
-		for p := s.Func().Text; p != nil; p = p.Link {
-			if p.As == AFUNCDATA && p.From.Type == TYPE_CONST && p.From.Offset == objabi.FUNCDATA_ArgsPointerMaps {
-				found = true
-				break
+	// Add reference to Go arguments for assembly functions without them.
+	if ctxt.IsAsm {
+		for _, s := range text {
+			if !strings.HasPrefix(s.Name, "\"\".") {
+				continue
 			}
-		}
-
-		if !found {
-			p := Appendp(s.Func().Text, newprog)
-			p.As = AFUNCDATA
-			p.From.Type = TYPE_CONST
-			p.From.Offset = objabi.FUNCDATA_ArgsPointerMaps
-			p.To.Type = TYPE_MEM
-			p.To.Name = NAME_EXTERN
-			p.To.Sym = ctxt.LookupDerived(s, s.Name+".args_stackmap")
+			// The current args_stackmap generation in the compiler assumes
+			// that the function in question is ABI0, so avoid introducing
+			// an args_stackmap reference if the func is not ABI0 (better to
+			// have no stackmap than an incorrect/lying stackmap).
+			if s.ABI() != ABI0 {
+				continue
+			}
+			foundArgMap, foundArgInfo := false, false
+			for p := s.Func().Text; p != nil; p = p.Link {
+				if p.As == AFUNCDATA && p.From.Type == TYPE_CONST {
+					if p.From.Offset == objabi.FUNCDATA_ArgsPointerMaps {
+						foundArgMap = true
+					}
+					if p.From.Offset == objabi.FUNCDATA_ArgInfo {
+						foundArgInfo = true
+					}
+					if foundArgMap && foundArgInfo {
+						break
+					}
+				}
+			}
+			if !foundArgMap {
+				p := Appendp(s.Func().Text, newprog)
+				p.As = AFUNCDATA
+				p.From.Type = TYPE_CONST
+				p.From.Offset = objabi.FUNCDATA_ArgsPointerMaps
+				p.To.Type = TYPE_MEM
+				p.To.Name = NAME_EXTERN
+				p.To.Sym = ctxt.LookupDerived(s, s.Name+".args_stackmap")
+			}
+			if !foundArgInfo {
+				p := Appendp(s.Func().Text, newprog)
+				p.As = AFUNCDATA
+				p.From.Type = TYPE_CONST
+				p.From.Offset = objabi.FUNCDATA_ArgInfo
+				p.To.Type = TYPE_MEM
+				p.To.Name = NAME_EXTERN
+				p.To.Sym = ctxt.LookupDerived(s, fmt.Sprintf("%s.arginfo%d", s.Name, s.ABI()))
+			}
 		}
 	}
 
 	// Turn functions into machine code images.
 	for _, s := range text {
 		mkfwd(s)
+		if ctxt.Arch.ErrorCheck != nil {
+			ctxt.Arch.ErrorCheck(ctxt, s)
+		}
 		linkpatch(ctxt, s, newprog)
 		ctxt.Arch.Preprocess(ctxt, s, newprog)
 		ctxt.Arch.Assemble(ctxt, s, newprog)
@@ -128,15 +155,16 @@
 		ctxt.Diag("symbol %s listed multiple times", s.Name)
 	}
 	name := strings.Replace(s.Name, "\"\"", ctxt.Pkgpath, -1)
-	s.Func().FuncID = objabi.GetFuncID(name, flag&WRAPPER != 0)
+	s.Func().FuncID = objabi.GetFuncID(name, flag&WRAPPER != 0 || flag&ABIWRAPPER != 0)
+	s.Func().FuncFlag = toFuncFlag(flag)
 	s.Set(AttrOnList, true)
 	s.Set(AttrDuplicateOK, flag&DUPOK != 0)
 	s.Set(AttrNoSplit, flag&NOSPLIT != 0)
 	s.Set(AttrReflectMethod, flag&REFLECTMETHOD != 0)
 	s.Set(AttrWrapper, flag&WRAPPER != 0)
+	s.Set(AttrABIWrapper, flag&ABIWRAPPER != 0)
 	s.Set(AttrNeedCtxt, flag&NEEDCTXT != 0)
 	s.Set(AttrNoFrame, flag&NOFRAME != 0)
-	s.Set(AttrTopFrame, flag&TOPFRAME != 0)
 	s.Type = objabi.STEXT
 	ctxt.Text = append(ctxt.Text, s)
 
@@ -144,6 +172,14 @@
 	ctxt.dwarfSym(s)
 }
 
+func toFuncFlag(flag int) objabi.FuncFlag {
+	var out objabi.FuncFlag
+	if flag&TOPFRAME != 0 {
+		out |= objabi.FuncFlag_TOPFRAME
+	}
+	return out
+}
+
 func (ctxt *Link) Globl(s *LSym, size int64, flag int) {
 	if s.OnList() {
 		ctxt.Diag("symbol %s listed multiple times", s.Name)
diff --git a/src/cmd/internal/obj/ppc64/a.out.go b/src/cmd/internal/obj/ppc64/a.out.go
index 4c97302..428cac5 100644
--- a/src/cmd/internal/obj/ppc64/a.out.go
+++ b/src/cmd/internal/obj/ppc64/a.out.go
@@ -368,30 +368,21 @@
 	C_LCON   /* other 32 */
 	C_DCON   /* other 64 (could subdivide further) */
 	C_SACON  /* $n(REG) where n <= int16 */
-	C_SECON
-	C_LACON /* $n(REG) where int16 < n <= int32 */
-	C_LECON
-	C_DACON /* $n(REG) where int32 < n */
+	C_LACON  /* $n(REG) where int16 < n <= int32 */
+	C_DACON  /* $n(REG) where int32 < n */
 	C_SBRA
 	C_LBRA
 	C_LBRAPIC
-	C_SAUTO
-	C_LAUTO
-	C_SEXT
-	C_LEXT
 	C_ZOREG // conjecture: either (1) register + zeroed offset, or (2) "R0" implies zero or C_REG
-	C_SOREG // register + signed offset
-	C_LOREG
+	C_SOREG // D/DS form memory operation
+	C_LOREG // 32 bit addis + D/DS-form memory operation
 	C_FPSCR
-	C_MSR
 	C_XER
 	C_LR
 	C_CTR
 	C_ANY
 	C_GOK
 	C_ADDR
-	C_GOTADDR
-	C_TOCADDR
 	C_TLS_LE
 	C_TLS_IE
 	C_TEXTSIZE
diff --git a/src/cmd/internal/obj/ppc64/anames9.go b/src/cmd/internal/obj/ppc64/anames9.go
index 4699a15..b2632aa 100644
--- a/src/cmd/internal/obj/ppc64/anames9.go
+++ b/src/cmd/internal/obj/ppc64/anames9.go
@@ -20,30 +20,21 @@
 	"LCON",
 	"DCON",
 	"SACON",
-	"SECON",
 	"LACON",
-	"LECON",
 	"DACON",
 	"SBRA",
 	"LBRA",
 	"LBRAPIC",
-	"SAUTO",
-	"LAUTO",
-	"SEXT",
-	"LEXT",
 	"ZOREG",
 	"SOREG",
 	"LOREG",
 	"FPSCR",
-	"MSR",
 	"XER",
 	"LR",
 	"CTR",
 	"ANY",
 	"GOK",
 	"ADDR",
-	"GOTADDR",
-	"TOCADDR",
 	"TLS_LE",
 	"TLS_IE",
 	"TEXTSIZE",
diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go
index 41e263b..316959f 100644
--- a/src/cmd/internal/obj/ppc64/asm9.go
+++ b/src/cmd/internal/obj/ppc64/asm9.go
@@ -64,567 +64,464 @@
 
 type Optab struct {
 	as    obj.As // Opcode
-	a1    uint8
-	a2    uint8
-	a3    uint8
-	a4    uint8
-	type_ int8 // cases in asmout below. E.g., 44 = st r,(ra+rb); 45 = ld (ra+rb), r
-	size  int8
-	param int16
+	a1    uint8  // p.From argument (obj.Addr). p is of type obj.Prog.
+	a2    uint8  // p.Reg argument (int16 Register)
+	a3    uint8  // p.RestArgs[0]  (obj.AddrPos)
+	a4    uint8  // p.RestArgs[1]
+	a5    uint8  // p.RestARgs[2]
+	a6    uint8  // p.To (obj.Addr)
+	type_ int8   // cases in asmout below. E.g., 44 = st r,(ra+rb); 45 = ld (ra+rb), r
+	size  int8   // Text space in bytes to lay operation
 }
 
-// This optab contains a list of opcodes with the operand
-// combinations that are implemented. Not all opcodes are in this
-// table, but are added later in buildop by calling opset for those
-// opcodes which allow the same operand combinations as an opcode
-// already in the table.
+// optab contains an array to be sliced of accepted operand combinations for an
+// instruction. Unused arguments and fields are not explicitly enumerated, and
+// should not be listed for clarity. Unused arguments and values should always
+// assume the default value for the given type.
 //
-// The type field in the Optabl identifies the case in asmout where
-// the instruction word is assembled.
+// optab does not list every valid ppc64 opcode, it enumerates representative
+// operand combinations for a class of instruction.  The variable oprange indexes
+// all valid ppc64 opcodes.
+//
+// oprange is initialized to point a slice within optab which contains the valid
+// operand combinations for a given instruction.  This is initialized from buildop.
+//
+// Likewise, each slice of optab is dynamically sorted using the ocmp Sort interface
+// to arrange entries to minimize text size of each opcode.
 var optab = []Optab{
-	{obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
-	{obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
-	{obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
-	{obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
+	{as: obj.ATEXT, a1: C_LOREG, a6: C_TEXTSIZE, type_: 0, size: 0},
+	{as: obj.ATEXT, a1: C_LOREG, a3: C_LCON, a6: C_TEXTSIZE, type_: 0, size: 0},
+	{as: obj.ATEXT, a1: C_ADDR, a6: C_TEXTSIZE, type_: 0, size: 0},
+	{as: obj.ATEXT, a1: C_ADDR, a3: C_LCON, a6: C_TEXTSIZE, type_: 0, size: 0},
 	/* move register */
-	{AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
-	{AMOVBZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},
-	{AADD, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
-	{AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
-	{AADD, C_SCON, C_REG, C_NONE, C_REG, 4, 4, 0},
-	{AADD, C_SCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
-	{AADD, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
-	{AADD, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
-	{AADD, C_UCON, C_REG, C_NONE, C_REG, 20, 4, 0},
-	{AADD, C_UCON, C_NONE, C_NONE, C_REG, 20, 4, 0},
-	{AADD, C_ANDCON, C_REG, C_NONE, C_REG, 22, 8, 0},
-	{AADD, C_ANDCON, C_NONE, C_NONE, C_REG, 22, 8, 0},
-	{AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
-	{AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
-	{AADDIS, C_ADDCON, C_REG, C_NONE, C_REG, 20, 4, 0},
-	{AADDIS, C_ADDCON, C_NONE, C_NONE, C_REG, 20, 4, 0},
-	{AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
-	{AADDC, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
-	{AADDC, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
-	{AADDC, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
-	{AADDC, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
-	{AADDC, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
-	{AAND, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, no literal */
-	{AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
-	{AANDCC, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
-	{AANDCC, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
-	{AANDCC, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},
-	{AANDCC, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
-	{AANDCC, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
-	{AANDCC, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
-	{AANDCC, C_ADDCON, C_NONE, C_NONE, C_REG, 23, 8, 0},
-	{AANDCC, C_ADDCON, C_REG, C_NONE, C_REG, 23, 8, 0},
-	{AANDCC, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
-	{AANDCC, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
-	{AANDISCC, C_ANDCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
-	{AANDISCC, C_ANDCON, C_REG, C_NONE, C_REG, 59, 4, 0},
-	{AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
-	{AMULLW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
-	{AMULLW, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
-	{AMULLW, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
-	{AMULLW, C_ANDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
-	{AMULLW, C_ANDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
-	{AMULLW, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
-	{AMULLW, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
-	{ASUBC, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0},
-	{ASUBC, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},
-	{ASUBC, C_REG, C_NONE, C_ADDCON, C_REG, 27, 4, 0},
-	{ASUBC, C_REG, C_NONE, C_LCON, C_REG, 28, 12, 0},
-	{AOR, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, literal not cc (or/xor) */
-	{AOR, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
-	{AOR, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},
-	{AOR, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
-	{AOR, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
-	{AOR, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
-	{AOR, C_ADDCON, C_NONE, C_NONE, C_REG, 23, 8, 0},
-	{AOR, C_ADDCON, C_REG, C_NONE, C_REG, 23, 8, 0},
-	{AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
-	{AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
-	{AORIS, C_ANDCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
-	{AORIS, C_ANDCON, C_REG, C_NONE, C_REG, 59, 4, 0},
-	{ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, /* op r1[,r2],r3 */
-	{ADIVW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
-	{ASUB, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0}, /* op r2[,r1],r3 */
-	{ASUB, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},
-	{ASLW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
-	{ASLW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
-	{ASLD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
-	{ASLD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
-	{ASLD, C_SCON, C_REG, C_NONE, C_REG, 25, 4, 0},
-	{ASLD, C_SCON, C_NONE, C_NONE, C_REG, 25, 4, 0},
-	{AEXTSWSLI, C_SCON, C_NONE, C_NONE, C_REG, 25, 4, 0},
-	{AEXTSWSLI, C_SCON, C_REG, C_NONE, C_REG, 25, 4, 0},
-	{ASLW, C_SCON, C_REG, C_NONE, C_REG, 57, 4, 0},
-	{ASLW, C_SCON, C_NONE, C_NONE, C_REG, 57, 4, 0},
-	{ASRAW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
-	{ASRAW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
-	{ASRAW, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},
-	{ASRAW, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},
-	{ASRAD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
-	{ASRAD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
-	{ASRAD, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},
-	{ASRAD, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},
-	{ARLWMI, C_SCON, C_REG, C_LCON, C_REG, 62, 4, 0},
-	{ARLWMI, C_REG, C_REG, C_LCON, C_REG, 63, 4, 0},
-	{ACLRLSLWI, C_SCON, C_REG, C_LCON, C_REG, 62, 4, 0},
-	{ARLDMI, C_SCON, C_REG, C_LCON, C_REG, 30, 4, 0},
-	{ARLDC, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
-	{ARLDCL, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
-	{ARLDCL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},
-	{ARLDICL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},
-	{ARLDICL, C_SCON, C_REG, C_LCON, C_REG, 14, 4, 0},
-	{ARLDCL, C_REG, C_NONE, C_LCON, C_REG, 14, 4, 0},
-	{AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 4, 0},
-	{AFADD, C_FREG, C_FREG, C_NONE, C_FREG, 2, 4, 0},
-	{AFABS, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},
-	{AFABS, C_NONE, C_NONE, C_NONE, C_FREG, 33, 4, 0},
-	{AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},
-	{AFMADD, C_FREG, C_FREG, C_FREG, C_FREG, 34, 4, 0},
-	{AFMUL, C_FREG, C_NONE, C_NONE, C_FREG, 32, 4, 0},
-	{AFMUL, C_FREG, C_FREG, C_NONE, C_FREG, 32, 4, 0},
+	{as: AADD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 2, size: 4},
+	{as: AADD, a1: C_REG, a6: C_REG, type_: 2, size: 4},
+	{as: AADD, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
+	{as: AADD, a1: C_SCON, a6: C_REG, type_: 4, size: 4},
+	{as: AADD, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
+	{as: AADD, a1: C_ADDCON, a6: C_REG, type_: 4, size: 4},
+	{as: AADD, a1: C_UCON, a2: C_REG, a6: C_REG, type_: 20, size: 4},
+	{as: AADD, a1: C_UCON, a6: C_REG, type_: 20, size: 4},
+	{as: AADD, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 22, size: 8},
+	{as: AADD, a1: C_ANDCON, a6: C_REG, type_: 22, size: 8},
+	{as: AADD, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 22, size: 12},
+	{as: AADD, a1: C_LCON, a6: C_REG, type_: 22, size: 12},
+	{as: AADDIS, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 20, size: 4},
+	{as: AADDIS, a1: C_ADDCON, a6: C_REG, type_: 20, size: 4},
+	{as: AADDC, a1: C_REG, a2: C_REG, a6: C_REG, type_: 2, size: 4},
+	{as: AADDC, a1: C_REG, a6: C_REG, type_: 2, size: 4},
+	{as: AADDC, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
+	{as: AADDC, a1: C_ADDCON, a6: C_REG, type_: 4, size: 4},
+	{as: AADDC, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 22, size: 12},
+	{as: AADDC, a1: C_LCON, a6: C_REG, type_: 22, size: 12},
+	{as: AAND, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4}, /* logical, no literal */
+	{as: AAND, a1: C_REG, a6: C_REG, type_: 6, size: 4},
+	{as: AANDCC, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
+	{as: AANDCC, a1: C_REG, a6: C_REG, type_: 6, size: 4},
+	{as: AANDCC, a1: C_ANDCON, a6: C_REG, type_: 58, size: 4},
+	{as: AANDCC, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 58, size: 4},
+	{as: AANDCC, a1: C_UCON, a6: C_REG, type_: 59, size: 4},
+	{as: AANDCC, a1: C_UCON, a2: C_REG, a6: C_REG, type_: 59, size: 4},
+	{as: AANDCC, a1: C_ADDCON, a6: C_REG, type_: 23, size: 8},
+	{as: AANDCC, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 23, size: 8},
+	{as: AANDCC, a1: C_LCON, a6: C_REG, type_: 23, size: 12},
+	{as: AANDCC, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 23, size: 12},
+	{as: AANDISCC, a1: C_ANDCON, a6: C_REG, type_: 59, size: 4},
+	{as: AANDISCC, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 59, size: 4},
+	{as: AMULLW, a1: C_REG, a2: C_REG, a6: C_REG, type_: 2, size: 4},
+	{as: AMULLW, a1: C_REG, a6: C_REG, type_: 2, size: 4},
+	{as: AMULLW, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
+	{as: AMULLW, a1: C_ADDCON, a6: C_REG, type_: 4, size: 4},
+	{as: AMULLW, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
+	{as: AMULLW, a1: C_ANDCON, a6: C_REG, type_: 4, size: 4},
+	{as: AMULLW, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 22, size: 12},
+	{as: AMULLW, a1: C_LCON, a6: C_REG, type_: 22, size: 12},
+	{as: ASUBC, a1: C_REG, a2: C_REG, a6: C_REG, type_: 10, size: 4},
+	{as: ASUBC, a1: C_REG, a6: C_REG, type_: 10, size: 4},
+	{as: ASUBC, a1: C_REG, a3: C_ADDCON, a6: C_REG, type_: 27, size: 4},
+	{as: ASUBC, a1: C_REG, a3: C_LCON, a6: C_REG, type_: 28, size: 12},
+	{as: AOR, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4}, /* logical, literal not cc (or/xor) */
+	{as: AOR, a1: C_REG, a6: C_REG, type_: 6, size: 4},
+	{as: AOR, a1: C_ANDCON, a6: C_REG, type_: 58, size: 4},
+	{as: AOR, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 58, size: 4},
+	{as: AOR, a1: C_UCON, a6: C_REG, type_: 59, size: 4},
+	{as: AOR, a1: C_UCON, a2: C_REG, a6: C_REG, type_: 59, size: 4},
+	{as: AOR, a1: C_ADDCON, a6: C_REG, type_: 23, size: 8},
+	{as: AOR, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 23, size: 8},
+	{as: AOR, a1: C_LCON, a6: C_REG, type_: 23, size: 12},
+	{as: AOR, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 23, size: 12},
+	{as: AORIS, a1: C_ANDCON, a6: C_REG, type_: 59, size: 4},
+	{as: AORIS, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 59, size: 4},
+	{as: ADIVW, a1: C_REG, a2: C_REG, a6: C_REG, type_: 2, size: 4}, /* op r1[,r2],r3 */
+	{as: ADIVW, a1: C_REG, a6: C_REG, type_: 2, size: 4},
+	{as: ASUB, a1: C_REG, a2: C_REG, a6: C_REG, type_: 10, size: 4}, /* op r2[,r1],r3 */
+	{as: ASUB, a1: C_REG, a6: C_REG, type_: 10, size: 4},
+	{as: ASLW, a1: C_REG, a6: C_REG, type_: 6, size: 4},
+	{as: ASLW, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
+	{as: ASLD, a1: C_REG, a6: C_REG, type_: 6, size: 4},
+	{as: ASLD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
+	{as: ASLD, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 25, size: 4},
+	{as: ASLD, a1: C_SCON, a6: C_REG, type_: 25, size: 4},
+	{as: AEXTSWSLI, a1: C_SCON, a6: C_REG, type_: 25, size: 4},
+	{as: AEXTSWSLI, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 25, size: 4},
+	{as: ASLW, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 57, size: 4},
+	{as: ASLW, a1: C_SCON, a6: C_REG, type_: 57, size: 4},
+	{as: ASRAW, a1: C_REG, a6: C_REG, type_: 6, size: 4},
+	{as: ASRAW, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
+	{as: ASRAW, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 56, size: 4},
+	{as: ASRAW, a1: C_SCON, a6: C_REG, type_: 56, size: 4},
+	{as: ASRAD, a1: C_REG, a6: C_REG, type_: 6, size: 4},
+	{as: ASRAD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
+	{as: ASRAD, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 56, size: 4},
+	{as: ASRAD, a1: C_SCON, a6: C_REG, type_: 56, size: 4},
+	{as: ARLWMI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
+	{as: ARLWMI, a1: C_SCON, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 102, size: 4},
+	{as: ARLWMI, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 63, size: 4},
+	{as: ARLWMI, a1: C_REG, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 103, size: 4},
+	{as: ACLRLSLWI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
+	{as: ARLDMI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 30, size: 4},
+	{as: ARLDC, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 29, size: 4},
+	{as: ARLDCL, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 29, size: 4},
+	{as: ARLDCL, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
+	{as: ARLDICL, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
+	{as: ARLDICL, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
+	{as: ARLDCL, a1: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
+	{as: AFADD, a1: C_FREG, a6: C_FREG, type_: 2, size: 4},
+	{as: AFADD, a1: C_FREG, a2: C_FREG, a6: C_FREG, type_: 2, size: 4},
+	{as: AFABS, a1: C_FREG, a6: C_FREG, type_: 33, size: 4},
+	{as: AFABS, a6: C_FREG, type_: 33, size: 4},
+	{as: AFMADD, a1: C_FREG, a2: C_FREG, a3: C_FREG, a6: C_FREG, type_: 34, size: 4},
+	{as: AFMUL, a1: C_FREG, a6: C_FREG, type_: 32, size: 4},
+	{as: AFMUL, a1: C_FREG, a2: C_FREG, a6: C_FREG, type_: 32, size: 4},
 
-	/* store, short offset */
-	{AMOVD, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
-	{AMOVW, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
-	{AMOVWZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
-	{AMOVBZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
-	{AMOVBZU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
-	{AMOVB, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
-	{AMOVBU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
-	{AMOVBZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
-	{AMOVBZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
-	{AMOVBZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
-	{AMOVBZU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
-	{AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
+	{as: AMOVBU, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+	{as: AMOVBU, a1: C_SOREG, a6: C_REG, type_: 8, size: 8},
 
-	/* load, short offset */
-	{AMOVD, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
-	{AMOVW, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
-	{AMOVWZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
-	{AMOVBZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
-	{AMOVBZU, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
-	{AMOVB, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},
-	{AMOVBU, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},
-	{AMOVD, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
-	{AMOVW, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
-	{AMOVWZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
-	{AMOVBZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
-	{AMOVB, C_SEXT, C_NONE, C_NONE, C_REG, 9, 8, REGSB},
-	{AMOVD, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
-	{AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
-	{AMOVWZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
-	{AMOVBZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
-	{AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, 9, 8, REGSP},
-	{AMOVD, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
-	{AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
-	{AMOVWZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
-	{AMOVBZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
-	{AMOVBZU, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
-	{AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},
-	{AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},
+	{as: AMOVBZU, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+	{as: AMOVBZU, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
 
-	/* store, long offset */
-	{AMOVD, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
-	{AMOVBZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
-	{AMOVBZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
-	{AMOVBZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
-	{AMOVBZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
+	{as: AMOVHBR, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
+	{as: AMOVHBR, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
 
-	/* load, long offset */
-	{AMOVD, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
-	{AMOVW, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
-	{AMOVWZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
-	{AMOVBZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
-	{AMOVB, C_LEXT, C_NONE, C_NONE, C_REG, 37, 12, REGSB},
-	{AMOVD, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
-	{AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
-	{AMOVWZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
-	{AMOVBZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
-	{AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, 37, 12, REGSP},
-	{AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
-	{AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
-	{AMOVWZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
-	{AMOVBZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
-	{AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 37, 12, REGZERO},
-	{AMOVD, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
-	{AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
-	{AMOVWZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
-	{AMOVBZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
-	{AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 76, 12, 0},
+	{as: AMOVB, a1: C_ADDR, a6: C_REG, type_: 75, size: 12},
+	{as: AMOVB, a1: C_LOREG, a6: C_REG, type_: 36, size: 12},
+	{as: AMOVB, a1: C_SOREG, a6: C_REG, type_: 8, size: 8},
+	{as: AMOVB, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
+	{as: AMOVB, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+	{as: AMOVB, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
+	{as: AMOVB, a1: C_REG, a6: C_REG, type_: 13, size: 4},
 
-	{AMOVD, C_TLS_LE, C_NONE, C_NONE, C_REG, 79, 4, 0},
-	{AMOVD, C_TLS_IE, C_NONE, C_NONE, C_REG, 80, 8, 0},
+	{as: AMOVBZ, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
+	{as: AMOVBZ, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
+	{as: AMOVBZ, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
+	{as: AMOVBZ, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
+	{as: AMOVBZ, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+	{as: AMOVBZ, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
+	{as: AMOVBZ, a1: C_REG, a6: C_REG, type_: 13, size: 4},
 
-	{AMOVD, C_GOTADDR, C_NONE, C_NONE, C_REG, 81, 8, 0},
-	{AMOVD, C_TOCADDR, C_NONE, C_NONE, C_REG, 95, 8, 0},
+	{as: AMOVD, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
+	{as: AMOVD, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
+	{as: AMOVD, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
+	{as: AMOVD, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
+	{as: AMOVD, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
+	{as: AMOVD, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
+	{as: AMOVD, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
+	{as: AMOVD, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
+	{as: AMOVD, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
+	{as: AMOVD, a1: C_TLS_LE, a6: C_REG, type_: 79, size: 8},
+	{as: AMOVD, a1: C_TLS_IE, a6: C_REG, type_: 80, size: 12},
+	{as: AMOVD, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
+	{as: AMOVD, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
+	{as: AMOVD, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+	{as: AMOVD, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
+	{as: AMOVD, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
+	{as: AMOVD, a1: C_REG, a6: C_REG, type_: 13, size: 4},
 
-	/* load constant */
-	{AMOVD, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB},
-	{AMOVD, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
-	{AMOVD, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
-	{AMOVD, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
-	{AMOVD, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
-	{AMOVD, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
-	{AMOVW, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */
-	{AMOVW, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
-	{AMOVW, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
-	{AMOVW, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
-	{AMOVW, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
-	{AMOVW, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
-	{AMOVWZ, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */
-	{AMOVWZ, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
-	{AMOVWZ, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
-	{AMOVWZ, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
-	{AMOVWZ, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
-	{AMOVWZ, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
+	{as: AMOVW, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
+	{as: AMOVW, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
+	{as: AMOVW, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
+	{as: AMOVW, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
+	{as: AMOVW, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
+	{as: AMOVW, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
+	{as: AMOVW, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
+	{as: AMOVW, a1: C_CREG, a6: C_REG, type_: 68, size: 4},
+	{as: AMOVW, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
+	{as: AMOVW, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
+	{as: AMOVW, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
+	{as: AMOVW, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
+	{as: AMOVW, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
+	{as: AMOVW, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+	{as: AMOVW, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
+	{as: AMOVW, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
+	{as: AMOVW, a1: C_REG, a6: C_REG, type_: 13, size: 4},
 
-	/* load unsigned/long constants (TO DO: check) */
-	{AMOVD, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
-	{AMOVD, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
-	{AMOVW, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
-	{AMOVW, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
-	{AMOVWZ, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
-	{AMOVWZ, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
-	{AMOVHBR, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
-	{AMOVHBR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
-	{AMOVHBR, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
-	{AMOVHBR, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
-	{ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0},
-	{ASYSCALL, C_REG, C_NONE, C_NONE, C_NONE, 77, 12, 0},
-	{ASYSCALL, C_SCON, C_NONE, C_NONE, C_NONE, 77, 12, 0},
-	{ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 16, 4, 0},
-	{ABEQ, C_CREG, C_NONE, C_NONE, C_SBRA, 16, 4, 0},
-	{ABR, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0},
-	{ABR, C_NONE, C_NONE, C_NONE, C_LBRAPIC, 11, 8, 0},
-	{ABC, C_SCON, C_REG, C_NONE, C_SBRA, 16, 4, 0},
-	{ABC, C_SCON, C_REG, C_NONE, C_LBRA, 17, 4, 0},
-	{ABR, C_NONE, C_NONE, C_NONE, C_LR, 18, 4, 0},
-	{ABR, C_NONE, C_NONE, C_SCON, C_LR, 18, 4, 0},
-	{ABR, C_NONE, C_NONE, C_NONE, C_CTR, 18, 4, 0},
-	{ABR, C_REG, C_NONE, C_NONE, C_CTR, 18, 4, 0},
-	{ABR, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},
-	{ABC, C_NONE, C_REG, C_NONE, C_LR, 18, 4, 0},
-	{ABC, C_NONE, C_REG, C_NONE, C_CTR, 18, 4, 0},
-	{ABC, C_SCON, C_REG, C_NONE, C_LR, 18, 4, 0},
-	{ABC, C_SCON, C_REG, C_NONE, C_CTR, 18, 4, 0},
-	{ABC, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},
-	{AFMOVD, C_SEXT, C_NONE, C_NONE, C_FREG, 8, 4, REGSB},
-	{AFMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, 8, 4, REGSP},
-	{AFMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, 8, 4, REGZERO},
-	{AFMOVD, C_LEXT, C_NONE, C_NONE, C_FREG, 36, 8, REGSB},
-	{AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, 8, REGSP},
-	{AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 8, REGZERO},
-	{AFMOVD, C_ZCON, C_NONE, C_NONE, C_FREG, 24, 4, 0},
-	{AFMOVD, C_ADDCON, C_NONE, C_NONE, C_FREG, 24, 8, 0},
-	{AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 8, 0},
-	{AFMOVD, C_FREG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
-	{AFMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
-	{AFMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
-	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
-	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
-	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
-	{AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
-	{AFMOVSX, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0},
-	{AFMOVSX, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0},
-	{AFMOVSX, C_FREG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
-	{AFMOVSX, C_FREG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
-	{AFMOVSZ, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0},
-	{AFMOVSZ, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0},
-	{ASYNC, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
-	{AWORD, C_LCON, C_NONE, C_NONE, C_NONE, 40, 4, 0},
-	{ADWORD, C_LCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},
-	{ADWORD, C_DCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},
-	{AADDME, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
-	{AEXTSB, C_REG, C_NONE, C_NONE, C_REG, 48, 4, 0},
-	{AEXTSB, C_NONE, C_NONE, C_NONE, C_REG, 48, 4, 0},
-	{AISEL, C_LCON, C_REG, C_REG, C_REG, 84, 4, 0},
-	{AISEL, C_ZCON, C_REG, C_REG, C_REG, 84, 4, 0},
-	{ANEG, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
-	{ANEG, C_NONE, C_NONE, C_NONE, C_REG, 47, 4, 0},
-	{AREM, C_REG, C_NONE, C_NONE, C_REG, 50, 12, 0},
-	{AREM, C_REG, C_REG, C_NONE, C_REG, 50, 12, 0},
-	{AREMU, C_REG, C_NONE, C_NONE, C_REG, 50, 16, 0},
-	{AREMU, C_REG, C_REG, C_NONE, C_REG, 50, 16, 0},
-	{AREMD, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0},
-	{AREMD, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0},
-	{AMTFSB0, C_SCON, C_NONE, C_NONE, C_NONE, 52, 4, 0},
-	{AMOVFL, C_FPSCR, C_NONE, C_NONE, C_FREG, 53, 4, 0},
-	{AMOVFL, C_FREG, C_NONE, C_NONE, C_FPSCR, 64, 4, 0},
-	{AMOVFL, C_FREG, C_NONE, C_LCON, C_FPSCR, 64, 4, 0},
-	{AMOVFL, C_LCON, C_NONE, C_NONE, C_FPSCR, 65, 4, 0},
-	{AMOVD, C_MSR, C_NONE, C_NONE, C_REG, 54, 4, 0},  /* mfmsr */
-	{AMOVD, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0},  /* mtmsrd */
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsr */
+	{as: AFMOVD, a1: C_ADDCON, a6: C_FREG, type_: 24, size: 8},
+	{as: AFMOVD, a1: C_SOREG, a6: C_FREG, type_: 8, size: 4},
+	{as: AFMOVD, a1: C_LOREG, a6: C_FREG, type_: 36, size: 8},
+	{as: AFMOVD, a1: C_ZCON, a6: C_FREG, type_: 24, size: 4},
+	{as: AFMOVD, a1: C_ADDR, a6: C_FREG, type_: 75, size: 8},
+	{as: AFMOVD, a1: C_FREG, a6: C_FREG, type_: 33, size: 4},
+	{as: AFMOVD, a1: C_FREG, a6: C_SOREG, type_: 7, size: 4},
+	{as: AFMOVD, a1: C_FREG, a6: C_LOREG, type_: 35, size: 8},
+	{as: AFMOVD, a1: C_FREG, a6: C_ADDR, type_: 74, size: 8},
 
+	{as: AFMOVSX, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4},
+	{as: AFMOVSX, a1: C_FREG, a6: C_ZOREG, type_: 44, size: 4},
+
+	{as: AFMOVSZ, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4},
+
+	{as: AMOVFL, a1: C_CREG, a6: C_CREG, type_: 67, size: 4},
+	{as: AMOVFL, a1: C_FPSCR, a6: C_CREG, type_: 73, size: 4},
+	{as: AMOVFL, a1: C_FPSCR, a6: C_FREG, type_: 53, size: 4},
+	{as: AMOVFL, a1: C_FREG, a3: C_LCON, a6: C_FPSCR, type_: 64, size: 4},
+	{as: AMOVFL, a1: C_FREG, a6: C_FPSCR, type_: 64, size: 4},
+	{as: AMOVFL, a1: C_LCON, a6: C_FPSCR, type_: 65, size: 4},
+	{as: AMOVFL, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
+	{as: AMOVFL, a1: C_REG, a6: C_LCON, type_: 69, size: 4},
+
+	{as: ASYSCALL, type_: 5, size: 4},
+	{as: ASYSCALL, a1: C_REG, type_: 77, size: 12},
+	{as: ASYSCALL, a1: C_SCON, type_: 77, size: 12},
+	{as: ABEQ, a6: C_SBRA, type_: 16, size: 4},
+	{as: ABEQ, a1: C_CREG, a6: C_SBRA, type_: 16, size: 4},
+	{as: ABR, a6: C_LBRA, type_: 11, size: 4},
+	{as: ABR, a6: C_LBRAPIC, type_: 11, size: 8},
+	{as: ABC, a1: C_SCON, a2: C_REG, a6: C_SBRA, type_: 16, size: 4},
+	{as: ABC, a1: C_SCON, a2: C_REG, a6: C_LBRA, type_: 17, size: 4},
+	{as: ABR, a6: C_LR, type_: 18, size: 4},
+	{as: ABR, a3: C_SCON, a6: C_LR, type_: 18, size: 4},
+	{as: ABR, a6: C_CTR, type_: 18, size: 4},
+	{as: ABR, a1: C_REG, a6: C_CTR, type_: 18, size: 4},
+	{as: ABR, a6: C_ZOREG, type_: 15, size: 8},
+	{as: ABC, a2: C_REG, a6: C_LR, type_: 18, size: 4},
+	{as: ABC, a2: C_REG, a6: C_CTR, type_: 18, size: 4},
+	{as: ABC, a1: C_SCON, a2: C_REG, a6: C_LR, type_: 18, size: 4},
+	{as: ABC, a1: C_SCON, a2: C_REG, a6: C_CTR, type_: 18, size: 4},
+	{as: ABC, a6: C_ZOREG, type_: 15, size: 8},
+	{as: ASYNC, type_: 46, size: 4},
+	{as: AWORD, a1: C_LCON, type_: 40, size: 4},
+	{as: ADWORD, a1: C_LCON, type_: 31, size: 8},
+	{as: ADWORD, a1: C_DCON, type_: 31, size: 8},
+	{as: ADWORD, a1: C_LACON, type_: 31, size: 8},
+	{as: AADDME, a1: C_REG, a6: C_REG, type_: 47, size: 4},
+	{as: AEXTSB, a1: C_REG, a6: C_REG, type_: 48, size: 4},
+	{as: AEXTSB, a6: C_REG, type_: 48, size: 4},
+	{as: AISEL, a1: C_LCON, a2: C_REG, a3: C_REG, a6: C_REG, type_: 84, size: 4},
+	{as: AISEL, a1: C_ZCON, a2: C_REG, a3: C_REG, a6: C_REG, type_: 84, size: 4},
+	{as: ANEG, a1: C_REG, a6: C_REG, type_: 47, size: 4},
+	{as: ANEG, a6: C_REG, type_: 47, size: 4},
+	{as: AREM, a1: C_REG, a6: C_REG, type_: 50, size: 12},
+	{as: AREM, a1: C_REG, a2: C_REG, a6: C_REG, type_: 50, size: 12},
+	{as: AREMU, a1: C_REG, a6: C_REG, type_: 50, size: 16},
+	{as: AREMU, a1: C_REG, a2: C_REG, a6: C_REG, type_: 50, size: 16},
+	{as: AREMD, a1: C_REG, a6: C_REG, type_: 51, size: 12},
+	{as: AREMD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 51, size: 12},
+	{as: AMTFSB0, a1: C_SCON, type_: 52, size: 4},
 	/* 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, ISA 3.0 */
-	{ACMPEQB, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
-	{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 */
-	{ACRAND, C_CREG, C_NONE, C_NONE, C_CREG, 2, 4, 0},   /* logical ops for condition registers xl-form */
+	{as: APOPCNTD, a1: C_REG, a6: C_REG, type_: 93, size: 4},            /* population count, x-form */
+	{as: ACMPB, a1: C_REG, a2: C_REG, a6: C_REG, type_: 92, size: 4},    /* compare byte, x-form */
+	{as: ACMPEQB, a1: C_REG, a2: C_REG, a6: C_CREG, type_: 92, size: 4}, /* compare equal byte, x-form, ISA 3.0 */
+	{as: ACMPEQB, a1: C_REG, a6: C_REG, type_: 70, size: 4},
+	{as: AFTDIV, a1: C_FREG, a2: C_FREG, a6: C_SCON, type_: 92, size: 4},          /* floating test for sw divide, x-form */
+	{as: AFTSQRT, a1: C_FREG, a6: C_SCON, type_: 93, size: 4},                     /* floating test for sw square root, x-form */
+	{as: ACOPY, a1: C_REG, a6: C_REG, type_: 92, size: 4},                         /* copy/paste facility, x-form */
+	{as: ADARN, a1: C_SCON, a6: C_REG, type_: 92, size: 4},                        /* deliver random number, x-form */
+	{as: ALDMX, a1: C_SOREG, a6: C_REG, type_: 45, size: 4},                       /* load doubleword monitored, x-form */
+	{as: AMADDHD, a1: C_REG, a2: C_REG, a3: C_REG, a6: C_REG, type_: 83, size: 4}, /* multiply-add high/low doubleword, va-form */
+	{as: AADDEX, a1: C_REG, a2: C_REG, a3: C_SCON, a6: C_REG, type_: 94, size: 4}, /* add extended using alternate carry, z23-form */
+	{as: ACRAND, a1: C_CREG, a6: C_CREG, type_: 2, size: 4},                       /* logical ops for condition registers xl-form */
 
 	/* Vector instructions */
 
 	/* Vector load */
-	{ALV, C_SOREG, C_NONE, C_NONE, C_VREG, 45, 4, 0}, /* vector load, x-form */
+	{as: ALV, a1: C_SOREG, a6: C_VREG, type_: 45, size: 4}, /* vector load, x-form */
 
 	/* Vector store */
-	{ASTV, C_VREG, C_NONE, C_NONE, C_SOREG, 44, 4, 0}, /* vector store, x-form */
+	{as: ASTV, a1: C_VREG, a6: C_SOREG, type_: 44, size: 4}, /* vector store, x-form */
 
 	/* Vector logical */
-	{AVAND, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector and, vx-form */
-	{AVOR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0},  /* vector or, vx-form */
+	{as: AVAND, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector and, vx-form */
+	{as: AVOR, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},  /* vector or, vx-form */
 
 	/* Vector add */
-	{AVADDUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add unsigned modulo, vx-form */
-	{AVADDCU, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add & write carry unsigned, vx-form */
-	{AVADDUS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add unsigned saturate, vx-form */
-	{AVADDSS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add signed saturate, vx-form */
-	{AVADDE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0},  /* vector add extended, va-form */
+	{as: AVADDUM, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector add unsigned modulo, vx-form */
+	{as: AVADDCU, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector add & write carry unsigned, vx-form */
+	{as: AVADDUS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector add unsigned saturate, vx-form */
+	{as: AVADDSS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector add signed saturate, vx-form */
+	{as: AVADDE, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector add extended, va-form */
 
 	/* Vector subtract */
-	{AVSUBUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract unsigned modulo, vx-form */
-	{AVSUBCU, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract & write carry unsigned, vx-form */
-	{AVSUBUS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract unsigned saturate, vx-form */
-	{AVSUBSS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract signed saturate, vx-form */
-	{AVSUBE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0},  /* vector subtract extended, va-form */
+	{as: AVSUBUM, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector subtract unsigned modulo, vx-form */
+	{as: AVSUBCU, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector subtract & write carry unsigned, vx-form */
+	{as: AVSUBUS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector subtract unsigned saturate, vx-form */
+	{as: AVSUBSS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector subtract signed saturate, vx-form */
+	{as: AVSUBE, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector subtract extended, va-form */
 
 	/* Vector multiply */
-	{AVMULESB, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 9},  /* vector multiply, 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 */
+	{as: AVMULESB, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},              /* vector multiply, vx-form */
+	{as: AVPMSUM, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},               /* vector polynomial multiply & sum, vx-form */
+	{as: AVMSUMUDM, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector multiply-sum, va-form */
 
 	/* Vector rotate */
-	{AVR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector rotate, vx-form */
+	{as: AVR, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector rotate, vx-form */
 
 	/* Vector shift */
-	{AVS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0},     /* vector shift, vx-form */
-	{AVSA, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0},    /* vector shift algebraic, vx-form */
-	{AVSOI, C_ANDCON, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector shift by octet immediate, va-form */
+	{as: AVS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},                 /* vector shift, vx-form */
+	{as: AVSA, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},                /* vector shift algebraic, vx-form */
+	{as: AVSOI, a1: C_ANDCON, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector shift by octet immediate, va-form */
 
 	/* Vector count */
-	{AVCLZ, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0},    /* vector count leading zeros, vx-form */
-	{AVPOPCNT, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0}, /* vector population count, vx-form */
+	{as: AVCLZ, a1: C_VREG, a6: C_VREG, type_: 85, size: 4},    /* vector count leading zeros, vx-form */
+	{as: AVPOPCNT, a1: C_VREG, a6: C_VREG, type_: 85, size: 4}, /* 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 */
-	{AVCMPNEZB, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare not equal, vx-form */
+	{as: AVCMPEQ, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},   /* vector compare equal, vc-form */
+	{as: AVCMPGT, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},   /* vector compare greater than, vc-form */
+	{as: AVCMPNEZB, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector compare not equal, vx-form */
 
 	/* Vector merge */
-	{AVMRGOW, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector merge odd word, vx-form */
+	{as: AVMRGOW, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector merge odd word, vx-form */
 
 	/* Vector permute */
-	{AVPERM, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector permute, va-form */
+	{as: AVPERM, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector permute, va-form */
 
 	/* Vector bit permute */
-	{AVBPERMQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector bit permute, vx-form */
+	{as: AVBPERMQ, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector bit permute, vx-form */
 
 	/* Vector select */
-	{AVSEL, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector select, va-form */
+	{as: AVSEL, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector select, va-form */
 
 	/* Vector splat */
-	{AVSPLTB, C_SCON, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector splat, vx-form */
-	{AVSPLTB, C_ADDCON, C_VREG, C_NONE, C_VREG, 82, 4, 0},
-	{AVSPLTISB, C_SCON, C_NONE, C_NONE, C_VREG, 82, 4, 0}, /* vector splat immediate, vx-form */
-	{AVSPLTISB, C_ADDCON, C_NONE, C_NONE, C_VREG, 82, 4, 0},
+	{as: AVSPLTB, a1: C_SCON, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector splat, vx-form */
+	{as: AVSPLTB, a1: C_ADDCON, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},
+	{as: AVSPLTISB, a1: C_SCON, a6: C_VREG, type_: 82, size: 4}, /* vector splat immediate, vx-form */
+	{as: AVSPLTISB, a1: C_ADDCON, a6: C_VREG, type_: 82, size: 4},
 
 	/* Vector AES */
-	{AVCIPH, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0},  /* vector AES cipher, vx-form */
-	{AVNCIPH, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector AES inverse cipher, vx-form */
-	{AVSBOX, C_VREG, C_NONE, C_NONE, C_VREG, 82, 4, 0},  /* vector AES subbytes, vx-form */
+	{as: AVCIPH, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},  /* vector AES cipher, vx-form */
+	{as: AVNCIPH, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector AES inverse cipher, vx-form */
+	{as: AVSBOX, a1: C_VREG, a6: C_VREG, type_: 82, size: 4},              /* vector AES subbytes, vx-form */
 
 	/* Vector SHA */
-	{AVSHASIGMA, C_ANDCON, C_VREG, C_ANDCON, C_VREG, 82, 4, 0}, /* vector SHA sigma, vx-form */
+	{as: AVSHASIGMA, a1: C_ANDCON, a2: C_VREG, a3: C_ANDCON, a6: C_VREG, type_: 82, size: 4}, /* vector SHA sigma, vx-form */
 
 	/* VSX vector load */
-	{ALXVD2X, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx vector load, xx1-form */
-	{ALXV, C_SOREG, C_NONE, C_NONE, C_VSREG, 96, 4, 0},    /* vsx vector load, dq-form */
-	{ALXVL, C_REG, C_REG, C_NONE, C_VSREG, 98, 4, 0},      /* vsx vector load length */
+	{as: ALXVD2X, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4},        /* vsx vector load, xx1-form */
+	{as: ALXV, a1: C_SOREG, a6: C_VSREG, type_: 96, size: 4},           /* vsx vector load, dq-form */
+	{as: ALXVL, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 98, size: 4}, /* vsx vector load length */
 
 	/* VSX vector store */
-	{ASTXVD2X, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx vector store, xx1-form */
-	{ASTXV, C_VSREG, C_NONE, C_NONE, C_SOREG, 97, 4, 0},    /* vsx vector store, dq-form */
-	{ASTXVL, C_VSREG, C_REG, C_NONE, C_REG, 99, 4, 0},      /* vsx vector store with length x-form */
+	{as: ASTXVD2X, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4},        /* vsx vector store, xx1-form */
+	{as: ASTXV, a1: C_VSREG, a6: C_SOREG, type_: 97, size: 4},           /* vsx vector store, dq-form */
+	{as: ASTXVL, a1: C_VSREG, a2: C_REG, a6: C_REG, type_: 99, size: 4}, /* vsx vector store with length x-form */
 
 	/* VSX scalar load */
-	{ALXSDX, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx scalar load, xx1-form */
+	{as: ALXSDX, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar load, xx1-form */
 
 	/* VSX scalar store */
-	{ASTXSDX, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx scalar store, xx1-form */
+	{as: ASTXSDX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar store, xx1-form */
 
 	/* VSX scalar as integer load */
-	{ALXSIWAX, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx scalar as integer load, xx1-form */
+	{as: ALXSIWAX, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar as integer load, xx1-form */
 
 	/* VSX scalar store as integer */
-	{ASTXSIWX, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx scalar as integer store, xx1-form */
+	{as: ASTXSIWX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar as integer store, xx1-form */
 
 	/* VSX move from VSR */
-	{AMFVSRD, C_VSREG, C_NONE, C_NONE, C_REG, 88, 4, 0}, /* vsx move from vsr, xx1-form */
-	{AMFVSRD, C_FREG, C_NONE, C_NONE, C_REG, 88, 4, 0},
-	{AMFVSRD, C_VREG, C_NONE, C_NONE, C_REG, 88, 4, 0},
+	{as: AMFVSRD, a1: C_VSREG, a6: C_REG, type_: 88, size: 4}, /* vsx move from vsr, xx1-form */
+	{as: AMFVSRD, a1: C_FREG, a6: C_REG, type_: 88, size: 4},
+	{as: AMFVSRD, a1: C_VREG, a6: C_REG, type_: 88, size: 4},
 
 	/* VSX move to VSR */
-	{AMTVSRD, C_REG, C_NONE, C_NONE, C_VSREG, 88, 4, 0}, /* vsx move to vsr, xx1-form */
-	{AMTVSRD, C_REG, C_REG, C_NONE, C_VSREG, 88, 4, 0},
-	{AMTVSRD, C_REG, C_NONE, C_NONE, C_FREG, 88, 4, 0},
-	{AMTVSRD, C_REG, C_NONE, C_NONE, C_VREG, 88, 4, 0},
+	{as: AMTVSRD, a1: C_REG, a6: C_VSREG, type_: 88, size: 4}, /* vsx move to vsr, xx1-form */
+	{as: AMTVSRD, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 88, size: 4},
+	{as: AMTVSRD, a1: C_REG, a6: C_FREG, type_: 88, size: 4},
+	{as: AMTVSRD, a1: C_REG, a6: C_VREG, type_: 88, size: 4},
 
 	/* VSX logical */
-	{AXXLAND, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx and, xx3-form */
-	{AXXLOR, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0},  /* vsx or, xx3-form */
+	{as: AXXLAND, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx and, xx3-form */
+	{as: AXXLOR, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4},  /* vsx or, xx3-form */
 
 	/* VSX select */
-	{AXXSEL, C_VSREG, C_VSREG, C_VSREG, C_VSREG, 91, 4, 0}, /* vsx select, xx4-form */
+	{as: AXXSEL, a1: C_VSREG, a2: C_VSREG, a3: C_VSREG, a6: C_VSREG, type_: 91, size: 4}, /* vsx select, xx4-form */
 
 	/* VSX merge */
-	{AXXMRGHW, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx merge, xx3-form */
+	{as: AXXMRGHW, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx merge, xx3-form */
 
 	/* VSX splat */
-	{AXXSPLTW, C_VSREG, C_NONE, C_SCON, C_VSREG, 89, 4, 0},  /* vsx splat, xx2-form */
-	{AXXSPLTIB, C_SCON, C_NONE, C_NONE, C_VSREG, 100, 4, 0}, /* vsx splat, xx2-form */
+	{as: AXXSPLTW, a1: C_VSREG, a3: C_SCON, a6: C_VSREG, type_: 89, size: 4}, /* vsx splat, xx2-form */
+	{as: AXXSPLTIB, a1: C_SCON, a6: C_VSREG, type_: 100, size: 4},            /* vsx splat, xx2-form */
 
 	/* VSX permute */
-	{AXXPERM, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx permute, xx3-form */
+	{as: AXXPERM, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx permute, xx3-form */
 
 	/* VSX shift */
-	{AXXSLDWI, C_VSREG, C_VSREG, C_SCON, C_VSREG, 90, 4, 0}, /* vsx shift immediate, xx3-form */
+	{as: AXXSLDWI, a1: C_VSREG, a2: C_VSREG, a3: C_SCON, a6: C_VSREG, type_: 90, size: 4}, /* vsx shift immediate, xx3-form */
 
 	/* VSX reverse bytes */
-	{AXXBRQ, C_VSREG, C_NONE, C_NONE, C_VSREG, 101, 4, 0}, /* vsx reverse bytes */
+	{as: AXXBRQ, a1: C_VSREG, a6: C_VSREG, type_: 101, size: 4}, /* vsx reverse bytes */
 
 	/* VSX scalar FP-FP conversion */
-	{AXSCVDPSP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar fp-fp conversion, xx2-form */
+	{as: AXSCVDPSP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx scalar fp-fp conversion, xx2-form */
 
 	/* VSX vector FP-FP conversion */
-	{AXVCVDPSP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector fp-fp conversion, xx2-form */
+	{as: AXVCVDPSP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx vector fp-fp conversion, xx2-form */
 
 	/* VSX scalar FP-integer conversion */
-	{AXSCVDPSXDS, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar fp-integer conversion, xx2-form */
+	{as: AXSCVDPSXDS, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx scalar fp-integer conversion, xx2-form */
 
 	/* VSX scalar integer-FP conversion */
-	{AXSCVSXDDP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar integer-fp conversion, xx2-form */
+	{as: AXSCVSXDDP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx scalar integer-fp conversion, xx2-form */
 
 	/* VSX vector FP-integer conversion */
-	{AXVCVDPSXDS, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector fp-integer conversion, xx2-form */
+	{as: AXVCVDPSXDS, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx vector fp-integer conversion, xx2-form */
 
 	/* VSX vector integer-FP conversion */
-	{AXVCVSXDDP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector integer-fp conversion, xx2-form */
+	{as: AXVCVSXDDP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx vector integer-fp conversion, xx2-form */
 
-	/* 64-bit special registers */
-	{AMOVD, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_LR, 66, 4, 0},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
-	{AMOVD, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
-	{AMOVD, C_LR, C_NONE, C_NONE, C_REG, 66, 4, 0},
-	{AMOVD, C_CTR, C_NONE, C_NONE, C_REG, 66, 4, 0},
-	{AMOVD, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
+	{as: ACMP, a1: C_REG, a6: C_REG, type_: 70, size: 4},
+	{as: ACMP, a1: C_REG, a2: C_REG, a6: C_REG, type_: 70, size: 4},
+	{as: ACMP, a1: C_REG, a6: C_ADDCON, type_: 71, size: 4},
+	{as: ACMP, a1: C_REG, a2: C_REG, a6: C_ADDCON, type_: 71, size: 4},
+	{as: ACMPU, a1: C_REG, a6: C_REG, type_: 70, size: 4},
+	{as: ACMPU, a1: C_REG, a2: C_REG, a6: C_REG, type_: 70, size: 4},
+	{as: ACMPU, a1: C_REG, a6: C_ANDCON, type_: 71, size: 4},
+	{as: ACMPU, a1: C_REG, a2: C_REG, a6: C_ANDCON, type_: 71, size: 4},
+	{as: AFCMPO, a1: C_FREG, a6: C_FREG, type_: 70, size: 4},
+	{as: AFCMPO, a1: C_FREG, a2: C_REG, a6: C_FREG, type_: 70, size: 4},
+	{as: ATW, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 60, size: 4},
+	{as: ATW, a1: C_LCON, a2: C_REG, a6: C_ADDCON, type_: 61, size: 4},
+	{as: ADCBF, a1: C_ZOREG, type_: 43, size: 4},
+	{as: ADCBF, a1: C_SOREG, type_: 43, size: 4},
+	{as: ADCBF, a1: C_ZOREG, a2: C_REG, a6: C_SCON, type_: 43, size: 4},
+	{as: ADCBF, a1: C_SOREG, a6: C_SCON, type_: 43, size: 4},
+	{as: AECOWX, a1: C_REG, a2: C_REG, a6: C_ZOREG, type_: 44, size: 4},
+	{as: AECIWX, a1: C_ZOREG, a2: C_REG, a6: C_REG, type_: 45, size: 4},
+	{as: AECOWX, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
+	{as: AECIWX, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
+	{as: ALDAR, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
+	{as: ALDAR, a1: C_ZOREG, a3: C_ANDCON, a6: C_REG, type_: 45, size: 4},
+	{as: AEIEIO, type_: 46, size: 4},
+	{as: ATLBIE, a1: C_REG, type_: 49, size: 4},
+	{as: ATLBIE, a1: C_SCON, a6: C_REG, type_: 49, size: 4},
+	{as: ASLBMFEE, a1: C_REG, a6: C_REG, type_: 55, size: 4},
+	{as: ASLBMTE, a1: C_REG, a6: C_REG, type_: 55, size: 4},
+	{as: ASTSW, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
+	{as: ASTSW, a1: C_REG, a3: C_LCON, a6: C_ZOREG, type_: 41, size: 4},
+	{as: ALSW, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
+	{as: ALSW, a1: C_ZOREG, a3: C_LCON, a6: C_REG, type_: 42, size: 4},
+	{as: obj.AUNDEF, type_: 78, size: 4},
+	{as: obj.APCDATA, a1: C_LCON, a6: C_LCON, type_: 0, size: 0},
+	{as: obj.AFUNCDATA, a1: C_SCON, a6: C_ADDR, type_: 0, size: 0},
+	{as: obj.ANOP, type_: 0, size: 0},
+	{as: obj.ANOP, a1: C_LCON, type_: 0, size: 0}, // NOP operand variations added for #40689
+	{as: obj.ANOP, a1: C_REG, type_: 0, size: 0},  // to preserve previous behavior
+	{as: obj.ANOP, a1: C_FREG, type_: 0, size: 0},
+	{as: obj.ADUFFZERO, a6: C_LBRA, type_: 11, size: 4}, // same as ABR/ABL
+	{as: obj.ADUFFCOPY, a6: C_LBRA, type_: 11, size: 4}, // same as ABR/ABL
+	{as: obj.APCALIGN, a1: C_LCON, type_: 0, size: 0},   // align code
 
-	/* 32-bit special registers (gloss over sign-extension or not?) */
-	{AMOVW, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
-	{AMOVW, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
-	{AMOVW, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
-	{AMOVWZ, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
-	{AMOVWZ, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
-	{AMOVFL, C_FPSCR, C_NONE, C_NONE, C_CREG, 73, 4, 0},
-	{AMOVFL, C_CREG, C_NONE, C_NONE, C_CREG, 67, 4, 0},
-	{AMOVW, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
-	{AMOVWZ, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
-	{AMOVFL, C_REG, C_NONE, C_NONE, C_LCON, 69, 4, 0},
-	{AMOVFL, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
-	{AMOVWZ, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
-	{ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
-	{ACMP, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
-	{ACMP, C_REG, C_NONE, C_NONE, C_ADDCON, 71, 4, 0},
-	{ACMP, C_REG, C_REG, C_NONE, C_ADDCON, 71, 4, 0},
-	{ACMPU, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
-	{ACMPU, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
-	{ACMPU, C_REG, C_NONE, C_NONE, C_ANDCON, 71, 4, 0},
-	{ACMPU, C_REG, C_REG, C_NONE, C_ANDCON, 71, 4, 0},
-	{AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 4, 0},
-	{AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 4, 0},
-	{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_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},
-	{AECIWX, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
-	{ALDAR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
-	{ALDAR, C_ZOREG, C_NONE, C_ANDCON, C_REG, 45, 4, 0},
-	{AEIEIO, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
-	{ATLBIE, C_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0},
-	{ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 49, 4, 0},
-	{ASLBMFEE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
-	{ASLBMTE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
-	{ASTSW, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
-	{ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0},
-	{ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
-	{ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0},
-	{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},
-	{obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},
-	{obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},
-	{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},
-	{obj.ANOP, C_LCON, C_NONE, C_NONE, C_NONE, 0, 0, 0}, // NOP operand variations added for #40689
-	{obj.ANOP, C_REG, C_NONE, C_NONE, C_NONE, 0, 0, 0},  // to preserve previous behavior
-	{obj.ANOP, C_FREG, C_NONE, C_NONE, C_NONE, 0, 0, 0},
-	{obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
-	{obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
-	{obj.APCALIGN, C_LCON, C_NONE, C_NONE, C_NONE, 0, 0, 0},   // align code
-
-	{obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0},
+	{as: obj.AXXX, type_: 0, size: 4},
 }
 
 var oprange [ALAST & obj.AMask][]Optab
@@ -674,6 +571,30 @@
 	return 0
 }
 
+// Get the implied register of a operand which doesn't specify one.  These show up
+// in handwritten asm like "MOVD R5, foosymbol" where a base register is not supplied,
+// or "MOVD R5, foo+10(SP) or pseudo-register is used.  The other common case is when
+// generating constants in register like "MOVD $constant, Rx".
+func (c *ctxt9) getimpliedreg(a *obj.Addr, p *obj.Prog) int {
+	switch oclass(a) {
+	case C_ADDCON, C_ANDCON, C_UCON, C_LCON, C_SCON, C_ZCON:
+		return REGZERO
+	case C_SACON, C_LACON:
+		return REGSP
+	case C_LOREG, C_SOREG, C_ZOREG:
+		switch a.Name {
+		case obj.NAME_EXTERN, obj.NAME_STATIC:
+			return REGSB
+		case obj.NAME_AUTO, obj.NAME_PARAM:
+			return REGSP
+		case obj.NAME_NONE:
+			return REGZERO
+		}
+	}
+	c.ctxt.Diag("failed to determine implied reg for class %v (%v)", DRconv(oclass(a)), p)
+	return 0
+}
+
 func span9(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
@@ -864,50 +785,42 @@
 		if a.Reg == REG_FPSCR {
 			return C_FPSCR
 		}
-		if a.Reg == REG_MSR {
-			return C_MSR
-		}
 		return C_GOK
 
 	case obj.TYPE_MEM:
 		switch a.Name {
+		case obj.NAME_GOTREF, obj.NAME_TOCREF:
+			return C_ADDR
+
 		case obj.NAME_EXTERN,
 			obj.NAME_STATIC:
+			c.instoffset = a.Offset
 			if a.Sym == nil {
 				break
-			}
-			c.instoffset = a.Offset
-			if a.Sym != nil { // use relocation
-				if a.Sym.Type == objabi.STLSBSS {
-					if c.ctxt.Flag_shared {
-						return C_TLS_IE
-					} else {
-						return C_TLS_LE
-					}
+			} else if a.Sym.Type == objabi.STLSBSS {
+				// For PIC builds, use 12 byte got initial-exec TLS accesses.
+				if c.ctxt.Flag_shared {
+					return C_TLS_IE
 				}
+				// Otherwise, use 8 byte local-exec TLS accesses.
+				return C_TLS_LE
+			} else {
 				return C_ADDR
 			}
-			return C_LEXT
-
-		case obj.NAME_GOTREF:
-			return C_GOTADDR
-
-		case obj.NAME_TOCREF:
-			return C_TOCADDR
 
 		case obj.NAME_AUTO:
 			c.instoffset = int64(c.autosize) + a.Offset
 			if c.instoffset >= -BIG && c.instoffset < BIG {
-				return C_SAUTO
+				return C_SOREG
 			}
-			return C_LAUTO
+			return C_LOREG
 
 		case obj.NAME_PARAM:
 			c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
 			if c.instoffset >= -BIG && c.instoffset < BIG {
-				return C_SAUTO
+				return C_SOREG
 			}
-			return C_LAUTO
+			return C_LOREG
 
 		case obj.NAME_NONE:
 			c.instoffset = a.Offset
@@ -958,11 +871,8 @@
 			if s == nil {
 				return C_GOK
 			}
-
 			c.instoffset = a.Offset
-
-			/* not sure why this barfs */
-			return C_LCON
+			return C_LACON
 
 		case obj.NAME_AUTO:
 			c.instoffset = int64(c.autosize) + a.Offset
@@ -1036,25 +946,28 @@
 		a1 = c.aclass(&p.From) + 1
 		p.From.Class = int8(a1)
 	}
-
 	a1--
-	a3 := C_NONE + 1
-	if p.GetFrom3() != nil {
-		a3 = int(p.GetFrom3().Class)
-		if a3 == 0 {
-			a3 = c.aclass(p.GetFrom3()) + 1
-			p.GetFrom3().Class = int8(a3)
+
+	argsv := [3]int{C_NONE + 1, C_NONE + 1, C_NONE + 1}
+	for i, ap := range p.RestArgs {
+		argsv[i] = int(ap.Addr.Class)
+		if argsv[i] == 0 {
+			argsv[i] = c.aclass(&ap.Addr) + 1
+			ap.Addr.Class = int8(argsv[i])
 		}
-	}
 
-	a3--
-	a4 := int(p.To.Class)
-	if a4 == 0 {
-		a4 = c.aclass(&p.To) + 1
-		p.To.Class = int8(a4)
 	}
+	a3 := argsv[0] - 1
+	a4 := argsv[1] - 1
+	a5 := argsv[2] - 1
 
-	a4--
+	a6 := int(p.To.Class)
+	if a6 == 0 {
+		a6 = c.aclass(&p.To) + 1
+		p.To.Class = int8(a6)
+	}
+	a6--
+
 	a2 := C_NONE
 	if p.Reg != 0 {
 		if REG_R0 <= p.Reg && p.Reg <= REG_R31 {
@@ -1068,20 +981,22 @@
 		}
 	}
 
-	// c.ctxt.Logf("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4)
+	// c.ctxt.Logf("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4, a5, a6)
 	ops := oprange[p.As&obj.AMask]
 	c1 := &xcmp[a1]
 	c3 := &xcmp[a3]
 	c4 := &xcmp[a4]
+	c5 := &xcmp[a5]
+	c6 := &xcmp[a6]
 	for i := range ops {
 		op := &ops[i]
-		if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] {
+		if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] && c5[op.a5] && c6[op.a6] {
 			p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
 			return op
 		}
 	}
 
-	c.ctxt.Diag("illegal combination %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4))
+	c.ctxt.Diag("illegal combination %v %v %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4), DRconv(a5), DRconv(a6))
 	prasm(p)
 	if ops == nil {
 		ops = optab
@@ -1134,13 +1049,13 @@
 			return true
 		}
 
-	case C_LEXT:
-		if b == C_SEXT {
+	case C_SOREG:
+		if b == C_ZOREG {
 			return true
 		}
 
-	case C_LAUTO:
-		if b == C_SAUTO {
+	case C_LOREG:
+		if b == C_SOREG || b == C_ZOREG {
 			return true
 		}
 
@@ -1149,16 +1064,6 @@
 			return r0iszero != 0 /*TypeKind(100016)*/
 		}
 
-	case C_LOREG:
-		if b == C_ZOREG || b == C_SOREG {
-			return true
-		}
-
-	case C_SOREG:
-		if b == C_ZOREG {
-			return true
-		}
-
 	case C_ANY:
 		return true
 	}
@@ -1211,6 +1116,14 @@
 	if n != 0 {
 		return n < 0
 	}
+	n = int(p1.a5) - int(p2.a5)
+	if n != 0 {
+		return n < 0
+	}
+	n = int(p1.a6) - int(p2.a6)
+	if n != 0 {
+		return n < 0
+	}
 	return false
 }
 
@@ -1985,6 +1898,9 @@
 		case AFTSQRT:
 			opset(AFTSQRT, r0)
 
+		case AMOVW: /* load/store/move word with sign extension; move 32-bit literals  */
+			opset(AMOVWZ, r0) /* Same as above, but zero extended */
+
 		case AADD,
 			AADDIS,
 			AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra */
@@ -1992,9 +1908,6 @@
 			AFMOVSX,
 			AFMOVSZ,
 			ALSW,
-			AMOVW,
-			/* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
-			AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals  */
 			AMOVD,  /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
 			AMOVB,  /* macro: move byte with sign extension */
 			AMOVBU, /* macro: move byte with sign extension & update */
@@ -2065,6 +1978,11 @@
 	return OPVCC(o, xo, 0, rc)
 }
 
+/* Generate MD-form opcode */
+func OPMD(o, xo, rc uint32) uint32 {
+	return o<<26 | xo<<2 | rc&1
+}
+
 /* the order is dest, a/s, b/imm for both arithmetic and logical operations */
 func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
 	return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
@@ -2220,15 +2138,12 @@
 	OP_MCRXR    = 31<<26 | 512<<1 | 0<<10 | 0
 	OP_MFCR     = 31<<26 | 19<<1 | 0<<10 | 0
 	OP_MFFS     = 63<<26 | 583<<1 | 0<<10 | 0
-	OP_MFMSR    = 31<<26 | 83<<1 | 0<<10 | 0
 	OP_MFSPR    = 31<<26 | 339<<1 | 0<<10 | 0
 	OP_MFSR     = 31<<26 | 595<<1 | 0<<10 | 0
 	OP_MFSRIN   = 31<<26 | 659<<1 | 0<<10 | 0
 	OP_MTCRF    = 31<<26 | 144<<1 | 0<<10 | 0
 	OP_MTFSF    = 63<<26 | 711<<1 | 0<<10 | 0
 	OP_MTFSFI   = 63<<26 | 134<<1 | 0<<10 | 0
-	OP_MTMSR    = 31<<26 | 146<<1 | 0<<10 | 0
-	OP_MTMSRD   = 31<<26 | 178<<1 | 0<<10 | 0
 	OP_MTSPR    = 31<<26 | 467<<1 | 0<<10 | 0
 	OP_MTSR     = 31<<26 | 210<<1 | 0<<10 | 0
 	OP_MTSRIN   = 31<<26 | 242<<1 | 0<<10 | 0
@@ -2305,7 +2220,7 @@
 
 // Encode instructions and create relocation for accessing s+d according to the
 // instruction op with source or destination (as appropriate) register reg.
-func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32) (o1, o2 uint32) {
+func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32, reuse bool) (o1, o2 uint32) {
 	if c.ctxt.Headtype == objabi.Haix {
 		// Every symbol access must be made via a TOC anchor.
 		c.ctxt.Diag("symbolAccess called for %s", s.Name)
@@ -2317,8 +2232,15 @@
 	} else {
 		base = REG_R0
 	}
-	o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0)
-	o2 = AOP_IRR(op, uint32(reg), REGTMP, 0)
+	// If reg can be reused when computing the symbol address,
+	// use it instead of REGTMP.
+	if !reuse {
+		o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0)
+		o2 = AOP_IRR(op, uint32(reg), REGTMP, 0)
+	} else {
+		o1 = AOP_IRR(OP_ADDIS, uint32(reg), base, 0)
+		o2 = AOP_IRR(op, uint32(reg), uint32(reg), 0)
+	}
 	rel := obj.Addrel(c.cursym)
 	rel.Off = int32(c.pc)
 	rel.Siz = 8
@@ -2455,20 +2377,6 @@
 	case 0: /* pseudo ops */
 		break
 
-	case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
-		if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
-			v := c.regoff(&p.From)
-			if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
-				//nerrors--;
-				c.ctxt.Diag("literal operation on R0\n%v", p)
-			}
-
-			o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
-			break
-		}
-
-		o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
-
 	case 2: /* int/cr/fp op Rb,[Ra],Rd */
 		r := int(p.Reg)
 
@@ -2483,7 +2391,7 @@
 		v := int32(d)
 		r := int(p.From.Reg)
 		if r == 0 {
-			r = int(o.param)
+			r = c.getimpliedreg(&p.From, p)
 		}
 		if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
 			c.ctxt.Diag("literal operation on R0\n%v", p)
@@ -2556,25 +2464,13 @@
 		r := int(p.To.Reg)
 
 		if r == 0 {
-			r = int(o.param)
+			r = c.getimpliedreg(&p.To, p)
 		}
 		v := c.regoff(&p.To)
 		if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 {
 			if v != 0 {
 				c.ctxt.Diag("illegal indexed instruction\n%v", p)
 			}
-			if c.ctxt.Flag_shared && r == REG_R13 {
-				rel := obj.Addrel(c.cursym)
-				rel.Off = int32(c.pc)
-				rel.Siz = 4
-				// This (and the matching part in the load case
-				// below) are the only places in the ppc64 toolchain
-				// that knows the name of the tls variable. Possibly
-				// we could add some assembly syntax so that the name
-				// of the variable does not have to be assumed.
-				rel.Sym = c.ctxt.Lookup("runtime.tls_g")
-				rel.Type = objabi.R_POWER_TLS
-			}
 			o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
 		} else {
 			if int32(int16(v)) != v {
@@ -2588,24 +2484,17 @@
 			o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v))
 		}
 
-	case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
+	case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r), lbz o(r) + extsb r,r */
 		r := int(p.From.Reg)
 
 		if r == 0 {
-			r = int(o.param)
+			r = c.getimpliedreg(&p.From, p)
 		}
 		v := c.regoff(&p.From)
 		if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
 			if v != 0 {
 				c.ctxt.Diag("illegal indexed instruction\n%v", p)
 			}
-			if c.ctxt.Flag_shared && r == REG_R13 {
-				rel := obj.Addrel(c.cursym)
-				rel.Off = int32(c.pc)
-				rel.Siz = 4
-				rel.Sym = c.ctxt.Lookup("runtime.tls_g")
-				rel.Type = objabi.R_POWER_TLS
-			}
 			o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
 		} else {
 			if int32(int16(v)) != v {
@@ -2619,21 +2508,7 @@
 			o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v))
 		}
 
-	case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
-		r := int(p.From.Reg)
-
-		if r == 0 {
-			r = int(o.param)
-		}
-		v := c.regoff(&p.From)
-		if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
-			if v != 0 {
-				c.ctxt.Diag("illegal indexed instruction\n%v", p)
-			}
-			o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
-		} else {
-			o1 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
-		}
+		// Sign extend MOVB operations. This is ignored for other cases (o.size == 4).
 		o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
 
 	case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
@@ -2676,34 +2551,35 @@
 		}
 		o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking
 
-	case 12: /* movb r,r (extsb); movw r,r (extsw) */
-		if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
-			v := c.regoff(&p.From)
-			if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
-				c.ctxt.Diag("literal operation on R0\n%v", p)
-			}
-
-			o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
+	case 13: /* mov[bhwd]{z,} r,r */
+		// This needs to handle "MOV* $0, Rx".  This shows up because $0 also
+		// matches C_REG if r0iszero. This happens because C_REG sorts before C_ANDCON
+		// TODO: fix the above behavior and cleanup this exception.
+		if p.From.Type == obj.TYPE_CONST {
+			o1 = LOP_IRR(OP_ADDI, REGZERO, uint32(p.To.Reg), 0)
 			break
 		}
-
-		if p.As == AMOVW {
-			o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
-		} else {
-			o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
+		if p.To.Type == obj.TYPE_CONST {
+			c.ctxt.Diag("cannot move into constant 0\n%v", p)
 		}
 
-	case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
-		if p.As == AMOVBZ {
+		switch p.As {
+		case AMOVB:
+			o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
+		case AMOVBZ:
 			o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
-		} else if p.As == AMOVH {
+		case AMOVH:
 			o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
-		} else if p.As == AMOVHZ {
+		case AMOVHZ:
 			o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)
-		} else if p.As == AMOVWZ {
+		case AMOVW:
+			o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
+		case AMOVWZ:
 			o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
-		} else {
-			c.ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
+		case AMOVD:
+			o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
+		default:
+			c.ctxt.Diag("internal: bad register move/truncation\n%v", p)
 		}
 
 	case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
@@ -2883,13 +2759,8 @@
 
 	case 19: /* mov $lcon,r ==> cau+or */
 		d := c.vregoff(&p.From)
-
-		if p.From.Sym == nil {
-			o1 = loadu32(int(p.To.Reg), d)
-			o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
-		} else {
-			o1, o2 = c.symbolAccess(p.From.Sym, d, p.To.Reg, OP_ADDI)
-		}
+		o1 = loadu32(int(p.To.Reg), d)
+		o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
 
 	case 20: /* add $ucon,,r | addis $addcon,r,r */
 		v := c.regoff(&p.From)
@@ -3007,16 +2878,21 @@
 		}
 
 	case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
-		if p.To.Reg == REGTMP {
-			c.ctxt.Diag("can't synthesize large constant\n%v", p)
-		}
-		v := c.regoff(&p.From)
+		v := c.vregoff(&p.From)
 		r := int(p.From.Reg)
-		if r == 0 {
-			r = int(o.param)
+
+		switch p.From.Name {
+		case obj.NAME_EXTERN, obj.NAME_STATIC:
+			// Load a 32 bit constant, or relocation depending on if a symbol is attached
+			o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, OP_ADDI, true)
+		default:
+			if r == 0 {
+				r = c.getimpliedreg(&p.From, p)
+			}
+			// Add a 32 bit offset to a register.
+			o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), uint32(r), uint32(high16adjusted(int32(v))))
+			o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(v))
 		}
-		o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
-		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.GetFrom3())
@@ -3157,7 +3033,7 @@
 
 		r := int(p.To.Reg)
 		if r == 0 {
-			r = int(o.param)
+			r = c.getimpliedreg(&p.To, p)
 		}
 		// Offsets in DS form stores must be a multiple of 4
 		inst := c.opstore(p.As)
@@ -3167,25 +3043,17 @@
 		o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
 		o2 = AOP_IRR(inst, uint32(p.From.Reg), REGTMP, uint32(v))
 
-	case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
+	case 36: /* mov b/bz/h/hz lext/lauto/lreg,r ==> lbz+extsb/lbz/lha/lhz etc */
 		v := c.regoff(&p.From)
 
 		r := int(p.From.Reg)
 		if r == 0 {
-			r = int(o.param)
+			r = c.getimpliedreg(&p.From, p)
 		}
-		o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
-		o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))
+		o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), uint32(r), uint32(high16adjusted(v)))
+		o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(p.To.Reg), uint32(v))
 
-	case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
-		v := c.regoff(&p.From)
-
-		r := int(p.From.Reg)
-		if r == 0 {
-			r = int(o.param)
-		}
-		o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
-		o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))
+		// Sign extend MOVB if needed
 		o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
 
 	case 40: /* word */
@@ -3305,17 +3173,6 @@
 	case 53: /* mffsX ,fr1 */
 		o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0)
 
-	case 54: /* mov msr,r1; mov r1, msr*/
-		if oclass(&p.From) == C_REG {
-			if p.As == AMOVD {
-				o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
-			} else {
-				o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
-			}
-		} else {
-			o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)
-		}
-
 	case 55: /* op Rb, Rd */
 		o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(p.From.Reg))
 
@@ -3554,41 +3411,51 @@
 		if c.opform(inst) == DS_FORM && v&0x3 != 0 {
 			log.Fatalf("invalid offset for DS form load/store %v", p)
 		}
-		o1, o2 = c.symbolAccess(p.To.Sym, v, p.From.Reg, inst)
+		// Can't reuse base for store instructions.
+		o1, o2 = c.symbolAccess(p.To.Sym, v, p.From.Reg, inst, false)
 
-	//if(dlm) reloc(&p->to, p->pc, 1);
+	case 75: // 32 bit offset symbol loads (got/toc/addr)
+		v := p.From.Offset
 
-	case 75:
-		v := c.vregoff(&p.From)
 		// Offsets in DS form loads must be a multiple of 4
 		inst := c.opload(p.As)
 		if c.opform(inst) == DS_FORM && v&0x3 != 0 {
 			log.Fatalf("invalid offset for DS form load/store %v", p)
 		}
-		o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
-
-	//if(dlm) reloc(&p->from, p->pc, 1);
-
-	case 76:
-		v := c.vregoff(&p.From)
-		// Offsets in DS form loads must be a multiple of 4
-		inst := c.opload(p.As)
-		if c.opform(inst) == DS_FORM && v&0x3 != 0 {
-			log.Fatalf("invalid offset for DS form load/store %v", p)
+		switch p.From.Name {
+		case obj.NAME_GOTREF, obj.NAME_TOCREF:
+			if v != 0 {
+				c.ctxt.Diag("invalid offset for GOT/TOC access %v", p)
+			}
+			o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
+			o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0)
+			rel := obj.Addrel(c.cursym)
+			rel.Off = int32(c.pc)
+			rel.Siz = 8
+			rel.Sym = p.From.Sym
+			switch p.From.Name {
+			case obj.NAME_GOTREF:
+				rel.Type = objabi.R_ADDRPOWER_GOT
+			case obj.NAME_TOCREF:
+				rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
+			}
+		default:
+			reuseBaseReg := p.As != AFMOVD && p.As != AFMOVS
+			// Reuse To.Reg as base register if not FP move.
+			o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst, reuseBaseReg)
 		}
-		o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
+
 		o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
 
-		//if(dlm) reloc(&p->from, p->pc, 1);
-
 	case 79:
 		if p.From.Offset != 0 {
 			c.ctxt.Diag("invalid offset against tls var %v", p)
 		}
-		o1 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGZERO, 0)
+		o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R13, 0)
+		o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), uint32(p.To.Reg), 0)
 		rel := obj.Addrel(c.cursym)
 		rel.Off = int32(c.pc)
-		rel.Siz = 4
+		rel.Siz = 8
 		rel.Sym = p.From.Sym
 		rel.Type = objabi.R_POWER_TLS_LE
 
@@ -3598,25 +3465,18 @@
 		}
 		o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
 		o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
+		o3 = AOP_RRR(OP_ADD, uint32(p.To.Reg), uint32(p.To.Reg), REG_R13)
 		rel := obj.Addrel(c.cursym)
 		rel.Off = int32(c.pc)
 		rel.Siz = 8
 		rel.Sym = p.From.Sym
 		rel.Type = objabi.R_POWER_TLS_IE
-
-	case 81:
-		v := c.vregoff(&p.To)
-		if v != 0 {
-			c.ctxt.Diag("invalid offset against GOT slot %v", p)
-		}
-
-		o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
-		o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
-		rel := obj.Addrel(c.cursym)
-		rel.Off = int32(c.pc)
-		rel.Siz = 8
+		rel = obj.Addrel(c.cursym)
+		rel.Off = int32(c.pc) + 8
+		rel.Siz = 4
 		rel.Sym = p.From.Sym
-		rel.Type = objabi.R_ADDRPOWER_GOT
+		rel.Type = objabi.R_POWER_TLS
+
 	case 82: /* vector instructions, VX-form and VC-form */
 		if p.From.Type == obj.TYPE_REG {
 			/* reg reg none OR reg reg reg */
@@ -3785,26 +3645,6 @@
 		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))
 
-	case 95: /* Retrieve TOC relative symbol */
-		/* This code is for AIX only */
-		v := c.vregoff(&p.From)
-		if v != 0 {
-			c.ctxt.Diag("invalid offset against TOC slot %v", p)
-		}
-
-		inst := c.opload(p.As)
-		if c.opform(inst) != DS_FORM {
-			c.ctxt.Diag("invalid form for a TOC access in %v", p)
-		}
-
-		o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
-		o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0)
-		rel := obj.Addrel(c.cursym)
-		rel.Off = int32(c.pc)
-		rel.Siz = 8
-		rel.Sym = p.From.Sym
-		rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
-
 	case 96: /* VSX load, DQ-form */
 		/* reg imm reg */
 		/* operand order: (RA)(DQ), XT */
@@ -3840,6 +3680,17 @@
 		}
 	case 101:
 		o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
+
+	case 102: /* RLWMI $sh,rs,$mb,$me,rt (M-form opcode)*/
+		mb := uint32(c.regoff(&p.RestArgs[0].Addr))
+		me := uint32(c.regoff(&p.RestArgs[1].Addr))
+		sh := uint32(c.regoff(&p.From))
+		o1 = OP_RLW(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), sh, mb, me)
+
+	case 103: /* RLWMI rb,rs,$mb,$me,rt (M-form opcode)*/
+		mb := uint32(c.regoff(&p.RestArgs[0].Addr))
+		me := uint32(c.regoff(&p.RestArgs[1].Addr))
+		o1 = OP_RLW(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), mb, me)
 	}
 
 	out[0] = o1
@@ -4336,14 +4187,14 @@
 	case ARLDICLCC:
 		return OPVCC(30, 0, 0, 1)
 	case ARLDICR:
-		return OPVCC(30, 0, 0, 0) | 2<<1 // rldicr
+		return OPMD(30, 1, 0) // rldicr
 	case ARLDICRCC:
-		return OPVCC(30, 0, 0, 1) | 2<<1 // rldicr.
+		return OPMD(30, 1, 1) // rldicr.
 
 	case ARLDIC:
-		return OPVCC(30, 0, 0, 0) | 4<<1 // rldic
+		return OPMD(30, 2, 0) // rldic
 	case ARLDICCC:
-		return OPVCC(30, 0, 0, 1) | 4<<1 // rldic.
+		return OPMD(30, 2, 1) // rldic.
 
 	case ASYSCALL:
 		return OPVCC(17, 1, 0, 0)
@@ -5001,30 +4852,30 @@
 	case ARLWMICC:
 		return OPVCC(20, 0, 0, 1)
 	case ARLDMI:
-		return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
+		return OPMD(30, 3, 0) /* rldimi */
 	case ARLDMICC:
-		return OPVCC(30, 0, 0, 1) | 3<<2
+		return OPMD(30, 3, 1) /* rldimi. */
 	case ARLDIMI:
-		return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
+		return OPMD(30, 3, 0) /* rldimi */
 	case ARLDIMICC:
-		return OPVCC(30, 0, 0, 1) | 3<<2
+		return OPMD(30, 3, 1) /* rldimi. */
 	case ARLWNM:
 		return OPVCC(21, 0, 0, 0) /* rlwinm */
 	case ARLWNMCC:
 		return OPVCC(21, 0, 0, 1)
 
 	case ARLDCL:
-		return OPVCC(30, 0, 0, 0) /* rldicl */
+		return OPMD(30, 0, 0) /* rldicl */
 	case ARLDCLCC:
-		return OPVCC(30, 0, 0, 1)
+		return OPMD(30, 0, 1) /* rldicl. */
 	case ARLDCR:
-		return OPVCC(30, 1, 0, 0) /* rldicr */
+		return OPMD(30, 1, 0) /* rldicr */
 	case ARLDCRCC:
-		return OPVCC(30, 1, 0, 1)
+		return OPMD(30, 1, 1) /* rldicr. */
 	case ARLDC:
-		return OPVCC(30, 0, 0, 0) | 2<<2
+		return OPMD(30, 2, 0) /* rldic */
 	case ARLDCCC:
-		return OPVCC(30, 0, 0, 1) | 2<<2
+		return OPMD(30, 2, 1) /* rldic. */
 
 	case ASRAW:
 		return OPVCC(31, 824, 0, 0)
diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go
index fddf552..c2722b0 100644
--- a/src/cmd/internal/obj/ppc64/obj9.go
+++ b/src/cmd/internal/obj/ppc64/obj9.go
@@ -34,6 +34,7 @@
 	"cmd/internal/objabi"
 	"cmd/internal/src"
 	"cmd/internal/sys"
+	"log"
 )
 
 func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
@@ -984,6 +985,21 @@
 				p.From.Reg = REGSP
 			}
 		}
+
+		if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 && p.As != ACMPU {
+			f := c.cursym.Func()
+			if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
+				c.cursym.Func().FuncFlag |= objabi.FuncFlag_SPWRITE
+				if ctxt.Debugvlog || !ctxt.IsAsm {
+					ctxt.Logf("auto-SPWRITE: %s %v\n", c.cursym.Name, p)
+					if !ctxt.IsAsm {
+						ctxt.Diag("invalid auto-SPWRITE in non-assembly")
+						ctxt.DiagFlush()
+						log.Fatalf("bad SPWRITE")
+					}
+				}
+			}
+		}
 	}
 }
 
@@ -1065,80 +1081,65 @@
 		p.From.Reg = REG_R3
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = REGSP
-	} else if framesize <= objabi.StackBig {
-		// large stack: SP-framesize < stackguard-StackSmall
-		//	ADD $-(framesize-StackSmall), SP, R4
-		//	CMP stackguard, R4
-		p = obj.Appendp(p, c.newprog)
-
-		p.As = AADD
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = -(int64(framesize) - objabi.StackSmall)
-		p.Reg = REGSP
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R4
-
-		p = obj.Appendp(p, c.newprog)
-		p.As = ACMPU
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R3
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R4
 	} else {
-		// Such a large stack we need to protect against wraparound.
-		// If SP is close to zero:
-		//	SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
-		// The +StackGuard on both sides is required to keep the left side positive:
-		// SP is allowed to be slightly below stackguard. See stack.h.
-		//
-		// Preemption sets stackguard to StackPreempt, a very large value.
-		// That breaks the math above, so we have to check for that explicitly.
-		//	// stackguard is R3
-		//	CMP	R3, $StackPreempt
-		//	BEQ	label-of-call-to-morestack
-		//	ADD	$StackGuard, SP, R4
-		//	SUB	R3, R4
-		//	MOVD	$(framesize+(StackGuard-StackSmall)), R31
-		//	CMPU	R31, R4
+		// large stack: SP-framesize < stackguard-StackSmall
+		offset := int64(framesize) - objabi.StackSmall
+		if framesize > objabi.StackBig {
+			// Such a large stack we need to protect against underflow.
+			// The runtime guarantees SP > objabi.StackBig, but
+			// framesize is large enough that SP-framesize may
+			// underflow, causing a direct comparison with the
+			// stack guard to incorrectly succeed. We explicitly
+			// guard against underflow.
+			//
+			//	CMPU	SP, $(framesize-StackSmall)
+			//	BLT	label-of-call-to-morestack
+			if offset <= 0xffff {
+				p = obj.Appendp(p, c.newprog)
+				p.As = ACMPU
+				p.From.Type = obj.TYPE_REG
+				p.From.Reg = REGSP
+				p.To.Type = obj.TYPE_CONST
+				p.To.Offset = offset
+			} else {
+				// Constant is too big for CMPU.
+				p = obj.Appendp(p, c.newprog)
+				p.As = AMOVD
+				p.From.Type = obj.TYPE_CONST
+				p.From.Offset = offset
+				p.To.Type = obj.TYPE_REG
+				p.To.Reg = REG_R4
+
+				p = obj.Appendp(p, c.newprog)
+				p.As = ACMPU
+				p.From.Type = obj.TYPE_REG
+				p.From.Reg = REGSP
+				p.To.Type = obj.TYPE_REG
+				p.To.Reg = REG_R4
+			}
+
+			p = obj.Appendp(p, c.newprog)
+			q = p
+			p.As = ABLT
+			p.To.Type = obj.TYPE_BRANCH
+		}
+
+		// Check against the stack guard. We've ensured this won't underflow.
+		//	ADD  $-(framesize-StackSmall), SP, R4
+		//	CMPU stackguard, R4
 		p = obj.Appendp(p, c.newprog)
 
-		p.As = ACMP
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R3
-		p.To.Type = obj.TYPE_CONST
-		p.To.Offset = objabi.StackPreempt
-
-		p = obj.Appendp(p, c.newprog)
-		q = p
-		p.As = ABEQ
-		p.To.Type = obj.TYPE_BRANCH
-
-		p = obj.Appendp(p, c.newprog)
 		p.As = AADD
 		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = int64(objabi.StackGuard)
+		p.From.Offset = -offset
 		p.Reg = REGSP
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = REG_R4
 
 		p = obj.Appendp(p, c.newprog)
-		p.As = ASUB
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R3
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R4
-
-		p = obj.Appendp(p, c.newprog)
-		p.As = AMOVD
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = int64(framesize) + int64(objabi.StackGuard) - objabi.StackSmall
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REGTMP
-
-		p = obj.Appendp(p, c.newprog)
 		p.As = ACMPU
 		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REGTMP
+		p.From.Reg = REG_R3
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = REG_R4
 	}
diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go
index 9257a64..a305eda 100644
--- a/src/cmd/internal/obj/riscv/obj.go
+++ b/src/cmd/internal/obj/riscv/obj.go
@@ -25,6 +25,7 @@
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"fmt"
+	"log"
 )
 
 func buildop(ctxt *obj.Link) {}
@@ -119,7 +120,7 @@
 			switch p.To.Name {
 			case obj.NAME_NONE:
 				p.As = AJALR
-			case obj.NAME_EXTERN:
+			case obj.NAME_EXTERN, obj.NAME_STATIC:
 				// Handled in preprocess.
 			default:
 				ctxt.Diag("unsupported name %d for %v", p.To.Name, p)
@@ -150,6 +151,15 @@
 	case ASBREAK:
 		// SBREAK is the old name for EBREAK.
 		p.As = AEBREAK
+
+	case AMOV:
+		// Put >32-bit constants in memory and load them.
+		if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE && p.From.Reg == 0 && int64(int32(p.From.Offset)) != p.From.Offset {
+			p.From.Type = obj.TYPE_MEM
+			p.From.Sym = ctxt.Int64Sym(p.From.Offset)
+			p.From.Name = obj.NAME_EXTERN
+			p.From.Offset = 0
+		}
 	}
 }
 
@@ -267,7 +277,7 @@
 				p.As = movToStore(p.As)
 				p.To.Reg = addrToReg(p.To)
 
-			case obj.NAME_EXTERN:
+			case obj.NAME_EXTERN, obj.NAME_STATIC:
 				// AUIPC $off_hi, TMP
 				// S $off_lo, TMP, R
 				as := p.As
@@ -301,7 +311,10 @@
 		//   LUI top20bits(c), R
 		//   ADD bottom12bits(c), R, R
 		if p.As != AMOV {
-			ctxt.Diag("unsupported constant load at %v", p)
+			ctxt.Diag("%v: unsupported constant load", p)
+		}
+		if p.To.Type != obj.TYPE_REG {
+			ctxt.Diag("%v: constant load must target register", p)
 		}
 		off := p.From.Offset
 		to := p.To
@@ -666,7 +679,7 @@
 			switch p.To.Type {
 			case obj.TYPE_MEM:
 				switch p.To.Name {
-				case obj.NAME_EXTERN:
+				case obj.NAME_EXTERN, obj.NAME_STATIC:
 					// JMP to symbol.
 					jalrToSym(ctxt, p, newprog, REG_ZERO)
 				}
@@ -716,6 +729,21 @@
 				p.Spadj = int32(-p.From.Offset)
 			}
 		}
+
+		if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
+			f := cursym.Func()
+			if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
+				f.FuncFlag |= objabi.FuncFlag_SPWRITE
+				if ctxt.Debugvlog || !ctxt.IsAsm {
+					ctxt.Logf("auto-SPWRITE: %s %v\n", cursym.Name, p)
+					if !ctxt.IsAsm {
+						ctxt.Diag("invalid auto-SPWRITE in non-assembly")
+						ctxt.DiagFlush()
+						log.Fatalf("bad SPWRITE")
+					}
+				}
+			}
+		}
 	}
 
 	// Rewrite MOV pseudo-instructions. This cannot be done in
@@ -956,8 +984,9 @@
 	var to_done, to_more *obj.Prog
 
 	if framesize <= objabi.StackSmall {
-		// small stack: SP < stackguard
-		//	BLTU	SP, stackguard, done
+		// small stack
+		//	// if SP > stackguard { goto done }
+		//	BLTU	stackguard, SP, done
 		p = obj.Appendp(p, newprog)
 		p.As = ABLTU
 		p.From.Type = obj.TYPE_REG
@@ -965,81 +994,49 @@
 		p.Reg = REG_SP
 		p.To.Type = obj.TYPE_BRANCH
 		to_done = p
-	} else if framesize <= objabi.StackBig {
-		// large stack: SP-framesize < stackguard-StackSmall
-		//	ADD	$-(framesize-StackSmall), SP, X11
-		//	BLTU	X11, stackguard, done
-		p = obj.Appendp(p, newprog)
-		// TODO(sorear): logic inconsistent with comment, but both match all non-x86 arches
-		p.As = AADDI
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = -(int64(framesize) - objabi.StackSmall)
-		p.Reg = REG_SP
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_X11
-
-		p = obj.Appendp(p, newprog)
-		p.As = ABLTU
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_X10
-		p.Reg = REG_X11
-		p.To.Type = obj.TYPE_BRANCH
-		to_done = p
 	} else {
-		// Such a large stack we need to protect against wraparound.
-		// If SP is close to zero:
-		//	SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
-		// The +StackGuard on both sides is required to keep the left side positive:
-		// SP is allowed to be slightly below stackguard. See stack.h.
-		//
-		// Preemption sets stackguard to StackPreempt, a very large value.
-		// That breaks the math above, so we have to check for that explicitly.
-		//	// stackguard is X10
-		//	MOV	$StackPreempt, X11
-		//	BEQ	X10, X11, more
-		//	ADD	$StackGuard, SP, X11
-		//	SUB	X10, X11
-		//	MOV	$(framesize+(StackGuard-StackSmall)), X10
-		//	BGTU	X11, X10, done
-		p = obj.Appendp(p, newprog)
-		p.As = AMOV
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = objabi.StackPreempt
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_X11
+		// large stack: SP-framesize < stackguard-StackSmall
+		offset := int64(framesize) - objabi.StackSmall
+		if framesize > objabi.StackBig {
+			// Such a large stack we need to protect against underflow.
+			// The runtime guarantees SP > objabi.StackBig, but
+			// framesize is large enough that SP-framesize may
+			// underflow, causing a direct comparison with the
+			// stack guard to incorrectly succeed. We explicitly
+			// guard against underflow.
+			//
+			//	MOV	$(framesize-StackSmall), X11
+			//	BLTU	SP, X11, label-of-call-to-morestack
 
-		p = obj.Appendp(p, newprog)
-		to_more = p
-		p.As = ABEQ
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_X10
-		p.Reg = REG_X11
-		p.To.Type = obj.TYPE_BRANCH
+			p = obj.Appendp(p, newprog)
+			p.As = AMOV
+			p.From.Type = obj.TYPE_CONST
+			p.From.Offset = offset
+			p.To.Type = obj.TYPE_REG
+			p.To.Reg = REG_X11
 
+			p = obj.Appendp(p, newprog)
+			p.As = ABLTU
+			p.From.Type = obj.TYPE_REG
+			p.From.Reg = REG_SP
+			p.Reg = REG_X11
+			p.To.Type = obj.TYPE_BRANCH
+			to_more = p
+		}
+
+		// Check against the stack guard. We've ensured this won't underflow.
+		//	ADD	$-(framesize-StackSmall), SP, X11
+		//	// if X11 > stackguard { goto done }
+		//	BLTU	stackguard, X11, done
 		p = obj.Appendp(p, newprog)
 		p.As = AADDI
 		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = int64(objabi.StackGuard)
+		p.From.Offset = -offset
 		p.Reg = REG_SP
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = REG_X11
 
 		p = obj.Appendp(p, newprog)
-		p.As = ASUB
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_X10
-		p.Reg = REG_X11
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_X11
-
-		p = obj.Appendp(p, newprog)
-		p.As = AMOV
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = int64(framesize) + int64(objabi.StackGuard) - objabi.StackSmall
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_X10
-
-		p = obj.Appendp(p, newprog)
 		p.As = ABLTU
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = REG_X10
diff --git a/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go b/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go
index 279aeb2..de412c6 100644
--- a/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go
+++ b/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go
@@ -25,84 +25,73 @@
 func testBLTZ(a int64) (r bool)
 func testBNEZ(a int64) (r bool)
 
+func testGoBGE(a, b int64) bool  { return a >= b }
+func testGoBGEU(a, b int64) bool { return uint64(a) >= uint64(b) }
+func testGoBGT(a, b int64) bool  { return a > b }
+func testGoBGTU(a, b int64) bool { return uint64(a) > uint64(b) }
+func testGoBLE(a, b int64) bool  { return a <= b }
+func testGoBLEU(a, b int64) bool { return uint64(a) <= uint64(b) }
+func testGoBLT(a, b int64) bool  { return a < b }
+func testGoBLTZ(a, b int64) bool { return uint64(a) < uint64(b) }
+
 func TestBranchCondition(t *testing.T) {
 	tests := []struct {
 		ins  string
 		a    int64
 		b    int64
 		fn   func(a, b int64) bool
+		goFn func(a, b int64) bool
 		want bool
 	}{
-		{"BGE", 0, 1, testBGE, false},
-		{"BGE", 0, 0, testBGE, true},
-		{"BGE", 0, -1, testBGE, true},
-		{"BGE", -1, 0, testBGE, false},
-		{"BGE", 1, 0, testBGE, true},
-		{"BGEU", 0, 1, testBGEU, false},
-		{"BGEU", 0, 0, testBGEU, true},
-		{"BGEU", 0, -1, testBGEU, false},
-		{"BGEU", -1, 0, testBGEU, true},
-		{"BGEU", 1, 0, testBGEU, true},
-		{"BGT", 0, 1, testBGT, false},
-		{"BGT", 0, 0, testBGT, false},
-		{"BGT", 0, -1, testBGT, true},
-		{"BGT", -1, 0, testBGT, false},
-		{"BGT", 1, 0, testBGT, true},
-		{"BGTU", 0, 1, testBGTU, false},
-		{"BGTU", 0, 0, testBGTU, false},
-		{"BGTU", 0, -1, testBGTU, false},
-		{"BGTU", -1, 0, testBGTU, true},
-		{"BGTU", 1, 0, testBGTU, true},
-		{"BLE", 0, 1, testBLE, true},
-		{"BLE", 0, 0, testBLE, true},
-		{"BLE", 0, -1, testBLE, false},
-		{"BLE", -1, 0, testBLE, true},
-		{"BLE", 1, 0, testBLE, false},
-		{"BLEU", 0, 1, testBLEU, true},
-		{"BLEU", 0, 0, testBLEU, true},
-		{"BLEU", 0, -1, testBLEU, true},
-		{"BLEU", -1, 0, testBLEU, false},
-		{"BLEU", 1, 0, testBLEU, false},
-		{"BLT", 0, 1, testBLT, true},
-		{"BLT", 0, 0, testBLT, false},
-		{"BLT", 0, -1, testBLT, false},
-		{"BLT", -1, 0, testBLT, true},
-		{"BLT", 1, 0, testBLT, false},
-		{"BLTU", 0, 1, testBLTU, true},
-		{"BLTU", 0, 0, testBLTU, false},
-		{"BLTU", 0, -1, testBLTU, true},
-		{"BLTU", -1, 0, testBLTU, false},
-		{"BLTU", 1, 0, testBLTU, false},
+		{"BGE", 0, 1, testBGE, testGoBGE, false},
+		{"BGE", 0, 0, testBGE, testGoBGE, true},
+		{"BGE", 0, -1, testBGE, testGoBGE, true},
+		{"BGE", -1, 0, testBGE, testGoBGE, false},
+		{"BGE", 1, 0, testBGE, testGoBGE, true},
+		{"BGEU", 0, 1, testBGEU, testGoBGEU, false},
+		{"BGEU", 0, 0, testBGEU, testGoBGEU, true},
+		{"BGEU", 0, -1, testBGEU, testGoBGEU, false},
+		{"BGEU", -1, 0, testBGEU, testGoBGEU, true},
+		{"BGEU", 1, 0, testBGEU, testGoBGEU, true},
+		{"BGT", 0, 1, testBGT, testGoBGT, false},
+		{"BGT", 0, 0, testBGT, testGoBGT, false},
+		{"BGT", 0, -1, testBGT, testGoBGT, true},
+		{"BGT", -1, 0, testBGT, testGoBGT, false},
+		{"BGT", 1, 0, testBGT, testGoBGT, true},
+		{"BGTU", 0, 1, testBGTU, testGoBGTU, false},
+		{"BGTU", 0, 0, testBGTU, testGoBGTU, false},
+		{"BGTU", 0, -1, testBGTU, testGoBGTU, false},
+		{"BGTU", -1, 0, testBGTU, testGoBGTU, true},
+		{"BGTU", 1, 0, testBGTU, testGoBGTU, true},
+		{"BLE", 0, 1, testBLE, testGoBLE, true},
+		{"BLE", 0, 0, testBLE, testGoBLE, true},
+		{"BLE", 0, -1, testBLE, testGoBLE, false},
+		{"BLE", -1, 0, testBLE, testGoBLE, true},
+		{"BLE", 1, 0, testBLE, testGoBLE, false},
+		{"BLEU", 0, 1, testBLEU, testGoBLEU, true},
+		{"BLEU", 0, 0, testBLEU, testGoBLEU, true},
+		{"BLEU", 0, -1, testBLEU, testGoBLEU, true},
+		{"BLEU", -1, 0, testBLEU, testGoBLEU, false},
+		{"BLEU", 1, 0, testBLEU, testGoBLEU, false},
+		{"BLT", 0, 1, testBLT, testGoBLT, true},
+		{"BLT", 0, 0, testBLT, testGoBLT, false},
+		{"BLT", 0, -1, testBLT, testGoBLT, false},
+		{"BLT", -1, 0, testBLT, testGoBLT, true},
+		{"BLT", 1, 0, testBLT, testGoBLT, false},
+		{"BLTU", 0, 1, testBLTU, testGoBLTU, true},
+		{"BLTU", 0, 0, testBLTU, testGoBLTU, false},
+		{"BLTU", 0, -1, testBLTU, testGoBLTU, true},
+		{"BLTU", -1, 0, testBLTU, testGoBLTU, false},
+		{"BLTU", 1, 0, testBLTU, testGoBLTU, false},
 	}
 	for _, test := range tests {
 		t.Run(test.ins, func(t *testing.T) {
-			var fn func(a, b int64) bool
-			switch test.ins {
-			case "BGE":
-				fn = func(a, b int64) bool { return a >= b }
-			case "BGEU":
-				fn = func(a, b int64) bool { return uint64(a) >= uint64(b) }
-			case "BGT":
-				fn = func(a, b int64) bool { return a > b }
-			case "BGTU":
-				fn = func(a, b int64) bool { return uint64(a) > uint64(b) }
-			case "BLE":
-				fn = func(a, b int64) bool { return a <= b }
-			case "BLEU":
-				fn = func(a, b int64) bool { return uint64(a) <= uint64(b) }
-			case "BLT":
-				fn = func(a, b int64) bool { return a < b }
-			case "BLTU":
-				fn = func(a, b int64) bool { return uint64(a) < uint64(b) }
-			default:
-				t.Fatalf("Unknown instruction %q", test.ins)
-			}
-			if got := fn(test.a, test.b); got != test.want {
-				t.Errorf("Go %v %v, %v = %v, want %v", test.ins, test.a, test.b, got, test.want)
-			}
 			if got := test.fn(test.a, test.b); got != test.want {
 				t.Errorf("Assembly %v %v, %v = %v, want %v", test.ins, test.a, test.b, got, test.want)
 			}
+			if got := test.goFn(test.a, test.b); got != test.want {
+				t.Errorf("Go %v %v, %v = %v, want %v", test.ins, test.a, test.b, got, test.want)
+			}
 		})
 	}
 }
diff --git a/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s b/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s
index 8dd6f56..cce296f 100644
--- a/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s
+++ b/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s
@@ -7,7 +7,7 @@
 #include "textflag.h"
 
 // func testBEQZ(a int64) (r bool)
-TEXT ·testBEQZ(SB),NOSPLIT,$0-0
+TEXT ·testBEQZ(SB),NOSPLIT,$0-9
 	MOV	a+0(FP), X5
 	MOV	$1, X6
 	BEQZ	X5, b
@@ -17,7 +17,7 @@
 	RET
 
 // func testBGE(a, b int64) (r bool)
-TEXT ·testBGE(SB),NOSPLIT,$0-0
+TEXT ·testBGE(SB),NOSPLIT,$0-17
 	MOV	a+0(FP), X5
 	MOV	b+8(FP), X6
 	MOV	$1, X7
@@ -28,7 +28,7 @@
 	RET
 
 // func testBGEU(a, b int64) (r bool)
-TEXT ·testBGEU(SB),NOSPLIT,$0-0
+TEXT ·testBGEU(SB),NOSPLIT,$0-17
 	MOV	a+0(FP), X5
 	MOV	b+8(FP), X6
 	MOV	$1, X7
@@ -39,7 +39,7 @@
 	RET
 
 // func testBGEZ(a int64) (r bool)
-TEXT ·testBGEZ(SB),NOSPLIT,$0-0
+TEXT ·testBGEZ(SB),NOSPLIT,$0-9
 	MOV	a+0(FP), X5
 	MOV	$1, X6
 	BGEZ	X5, b
@@ -49,7 +49,7 @@
 	RET
 
 // func testBGT(a, b int64) (r bool)
-TEXT ·testBGT(SB),NOSPLIT,$0-0
+TEXT ·testBGT(SB),NOSPLIT,$0-17
 	MOV	a+0(FP), X5
 	MOV	b+8(FP), X6
 	MOV	$1, X7
@@ -60,7 +60,7 @@
 	RET
 
 // func testBGTU(a, b int64) (r bool)
-TEXT ·testBGTU(SB),NOSPLIT,$0-0
+TEXT ·testBGTU(SB),NOSPLIT,$0-17
 	MOV	a+0(FP), X5
 	MOV	b+8(FP), X6
 	MOV	$1, X7
@@ -71,7 +71,7 @@
 	RET
 
 // func testBGTZ(a int64) (r bool)
-TEXT ·testBGTZ(SB),NOSPLIT,$0-0
+TEXT ·testBGTZ(SB),NOSPLIT,$0-9
 	MOV	a+0(FP), X5
 	MOV	$1, X6
 	BGTZ	X5, b
@@ -81,7 +81,7 @@
 	RET
 
 // func testBLE(a, b int64) (r bool)
-TEXT ·testBLE(SB),NOSPLIT,$0-0
+TEXT ·testBLE(SB),NOSPLIT,$0-17
 	MOV	a+0(FP), X5
 	MOV	b+8(FP), X6
 	MOV	$1, X7
@@ -92,7 +92,7 @@
 	RET
 
 // func testBLEU(a, b int64) (r bool)
-TEXT ·testBLEU(SB),NOSPLIT,$0-0
+TEXT ·testBLEU(SB),NOSPLIT,$0-17
 	MOV	a+0(FP), X5
 	MOV	b+8(FP), X6
 	MOV	$1, X7
@@ -103,7 +103,7 @@
 	RET
 
 // func testBLEZ(a int64) (r bool)
-TEXT ·testBLEZ(SB),NOSPLIT,$0-0
+TEXT ·testBLEZ(SB),NOSPLIT,$0-9
 	MOV	a+0(FP), X5
 	MOV	$1, X6
 	BLEZ	X5, b
@@ -113,7 +113,7 @@
 	RET
 
 // func testBLT(a, b int64) (r bool)
-TEXT ·testBLT(SB),NOSPLIT,$0-0
+TEXT ·testBLT(SB),NOSPLIT,$0-17
 	MOV	a+0(FP), X5
 	MOV	b+8(FP), X6
 	MOV	$1, X7
@@ -124,7 +124,7 @@
 	RET
 
 // func testBLTU(a, b int64) (r bool)
-TEXT ·testBLTU(SB),NOSPLIT,$0-0
+TEXT ·testBLTU(SB),NOSPLIT,$0-17
 	MOV	a+0(FP), X5
 	MOV	b+8(FP), X6
 	MOV	$1, X7
@@ -135,7 +135,7 @@
 	RET
 
 // func testBLTZ(a int64) (r bool)
-TEXT ·testBLTZ(SB),NOSPLIT,$0-0
+TEXT ·testBLTZ(SB),NOSPLIT,$0-9
 	MOV	a+0(FP), X5
 	MOV	$1, X6
 	BLTZ	X5, b
@@ -145,7 +145,7 @@
 	RET
 
 // func testBNEZ(a int64) (r bool)
-TEXT ·testBNEZ(SB),NOSPLIT,$0-0
+TEXT ·testBNEZ(SB),NOSPLIT,$0-9
 	MOV	a+0(FP), X5
 	MOV	$1, X6
 	BNEZ	X5, b
diff --git a/src/cmd/internal/obj/s390x/condition_code.go b/src/cmd/internal/obj/s390x/condition_code.go
index 764fc5b..f498fd6 100644
--- a/src/cmd/internal/obj/s390x/condition_code.go
+++ b/src/cmd/internal/obj/s390x/condition_code.go
@@ -124,3 +124,5 @@
 	// invalid
 	return fmt.Sprintf("Invalid (%#x)", c)
 }
+
+func (CCMask) CanBeAnSSAAux() {}
diff --git a/src/cmd/internal/obj/s390x/objz.go b/src/cmd/internal/obj/s390x/objz.go
index 970cf82..201163b 100644
--- a/src/cmd/internal/obj/s390x/objz.go
+++ b/src/cmd/internal/obj/s390x/objz.go
@@ -33,6 +33,7 @@
 	"cmd/internal/obj"
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
+	"log"
 	"math"
 )
 
@@ -545,6 +546,21 @@
 				p.From.Reg = REGSP
 			}
 		}
+
+		if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
+			f := c.cursym.Func()
+			if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
+				c.cursym.Func().FuncFlag |= objabi.FuncFlag_SPWRITE
+				if ctxt.Debugvlog || !ctxt.IsAsm {
+					ctxt.Logf("auto-SPWRITE: %s\n", c.cursym.Name)
+					if !ctxt.IsAsm {
+						ctxt.Diag("invalid auto-SPWRITE in non-assembly")
+						ctxt.DiagFlush()
+						log.Fatalf("bad SPWRITE")
+					}
+				}
+			}
+		}
 	}
 	if wasSplit {
 		c.stacksplitPost(pLast, pPre, pPreempt, autosize) // emit post part of split check
@@ -552,7 +568,6 @@
 }
 
 func (c *ctxtz) stacksplitPre(p *obj.Prog, framesize int32) (*obj.Prog, *obj.Prog) {
-	var q *obj.Prog
 
 	// MOVD	g_stackguard(g), R3
 	p = obj.Appendp(p, c.newprog)
@@ -573,98 +588,69 @@
 	// unnecessarily. See issue #35470.
 	p = c.ctxt.StartUnsafePoint(p, c.newprog)
 
-	q = nil
 	if framesize <= objabi.StackSmall {
 		// small stack: SP < stackguard
 		//	CMPUBGE	stackguard, SP, label-of-call-to-morestack
 
 		p = obj.Appendp(p, c.newprog)
-		//q1 = p
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = REG_R3
 		p.Reg = REGSP
 		p.As = ACMPUBGE
 		p.To.Type = obj.TYPE_BRANCH
 
-	} else if framesize <= objabi.StackBig {
-		// large stack: SP-framesize < stackguard-StackSmall
-		//	ADD $-(framesize-StackSmall), SP, R4
-		//	CMPUBGE stackguard, R4, label-of-call-to-morestack
-		p = obj.Appendp(p, c.newprog)
+		return p, nil
+	}
 
-		p.As = AADD
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = -(int64(framesize) - objabi.StackSmall)
-		p.Reg = REGSP
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R4
+	// large stack: SP-framesize < stackguard-StackSmall
 
-		p = obj.Appendp(p, c.newprog)
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R3
-		p.Reg = REG_R4
-		p.As = ACMPUBGE
-		p.To.Type = obj.TYPE_BRANCH
-
-	} else {
-		// Such a large stack we need to protect against wraparound.
-		// If SP is close to zero:
-		//	SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
-		// The +StackGuard on both sides is required to keep the left side positive:
-		// SP is allowed to be slightly below stackguard. See stack.h.
+	var q *obj.Prog
+	offset := int64(framesize) - objabi.StackSmall
+	if framesize > objabi.StackBig {
+		// Such a large stack we need to protect against underflow.
+		// The runtime guarantees SP > objabi.StackBig, but
+		// framesize is large enough that SP-framesize may
+		// underflow, causing a direct comparison with the
+		// stack guard to incorrectly succeed. We explicitly
+		// guard against underflow.
 		//
-		// Preemption sets stackguard to StackPreempt, a very large value.
-		// That breaks the math above, so we have to check for that explicitly.
-		//	// stackguard is R3
-		//	CMP	R3, $StackPreempt
-		//	BEQ	label-of-call-to-morestack
-		//	ADD	$StackGuard, SP, R4
-		//	SUB	R3, R4
-		//	MOVD	$(framesize+(StackGuard-StackSmall)), TEMP
-		//	CMPUBGE	TEMP, R4, label-of-call-to-morestack
-		p = obj.Appendp(p, c.newprog)
-
-		p.As = ACMP
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R3
-		p.To.Type = obj.TYPE_CONST
-		p.To.Offset = objabi.StackPreempt
-
-		p = obj.Appendp(p, c.newprog)
-		q = p
-		p.As = ABEQ
-		p.To.Type = obj.TYPE_BRANCH
-
-		p = obj.Appendp(p, c.newprog)
-		p.As = AADD
-		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = int64(objabi.StackGuard)
-		p.Reg = REGSP
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R4
-
-		p = obj.Appendp(p, c.newprog)
-		p.As = ASUB
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_R3
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_R4
+		//	MOVD	$(framesize-StackSmall), R4
+		//	CMPUBLT	SP, R4, label-of-call-to-morestack
 
 		p = obj.Appendp(p, c.newprog)
 		p.As = AMOVD
 		p.From.Type = obj.TYPE_CONST
-		p.From.Offset = int64(framesize) + int64(objabi.StackGuard) - objabi.StackSmall
+		p.From.Offset = offset
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REGTMP
+		p.To.Reg = REG_R4
 
 		p = obj.Appendp(p, c.newprog)
+		q = p
+		p.As = ACMPUBLT
 		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REGTMP
+		p.From.Reg = REGSP
 		p.Reg = REG_R4
-		p.As = ACMPUBGE
 		p.To.Type = obj.TYPE_BRANCH
 	}
 
+	// Check against the stack guard. We've ensured this won't underflow.
+	//	ADD $-(framesize-StackSmall), SP, R4
+	//	CMPUBGE stackguard, R4, label-of-call-to-morestack
+	p = obj.Appendp(p, c.newprog)
+	p.As = AADD
+	p.From.Type = obj.TYPE_CONST
+	p.From.Offset = -offset
+	p.Reg = REGSP
+	p.To.Type = obj.TYPE_REG
+	p.To.Reg = REG_R4
+
+	p = obj.Appendp(p, c.newprog)
+	p.From.Type = obj.TYPE_REG
+	p.From.Reg = REG_R3
+	p.Reg = REG_R4
+	p.As = ACMPUBGE
+	p.To.Type = obj.TYPE_BRANCH
+
 	return p, q
 }
 
diff --git a/src/cmd/internal/obj/s390x/rotate.go b/src/cmd/internal/obj/s390x/rotate.go
index 388bd40..5407c8d 100644
--- a/src/cmd/internal/obj/s390x/rotate.go
+++ b/src/cmd/internal/obj/s390x/rotate.go
@@ -113,3 +113,5 @@
 func (r RotateParams) InMerge(mask uint64) *RotateParams {
 	return r.OutMerge(bits.RotateLeft64(mask, int(r.Amount)))
 }
+
+func (RotateParams) CanBeAnSSAAux() {}
diff --git a/src/cmd/internal/obj/stringer.go b/src/cmd/internal/obj/stringer.go
index f67b890..a4d507d 100644
--- a/src/cmd/internal/obj/stringer.go
+++ b/src/cmd/internal/obj/stringer.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // This is a mini version of the stringer tool customized for the Anames table
diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go
index 4515bdd..9e8b4dd 100644
--- a/src/cmd/internal/obj/sym.go
+++ b/src/cmd/internal/obj/sym.go
@@ -35,6 +35,7 @@
 	"cmd/internal/goobj"
 	"cmd/internal/objabi"
 	"fmt"
+	"internal/buildcfg"
 	"log"
 	"math"
 	"sort"
@@ -49,15 +50,15 @@
 	ctxt.Arch = arch
 	ctxt.Pathname = objabi.WorkingDir()
 
-	if err := ctxt.Headtype.Set(objabi.GOOS); err != nil {
-		log.Fatalf("unknown goos %s", objabi.GOOS)
+	if err := ctxt.Headtype.Set(buildcfg.GOOS); err != nil {
+		log.Fatalf("unknown goos %s", buildcfg.GOOS)
 	}
 
 	ctxt.Flag_optimize = true
 	return ctxt
 }
 
-// LookupDerived looks up or creates the symbol with name name derived from symbol s.
+// LookupDerived looks up or creates the symbol with name derived from symbol s.
 // The resulting symbol will be static iff s is.
 func (ctxt *Link) LookupDerived(s *LSym, name string) *LSym {
 	if s.Static() {
diff --git a/src/cmd/internal/obj/textflag.go b/src/cmd/internal/obj/textflag.go
index d2cec73..5ae7502 100644
--- a/src/cmd/internal/obj/textflag.go
+++ b/src/cmd/internal/obj/textflag.go
@@ -27,13 +27,14 @@
 	// This data contains no pointers.
 	NOPTR = 16
 
-	// This is a wrapper function and should not count as disabling 'recover'.
+	// This is a wrapper function and should not count as
+	// disabling 'recover' or appear in tracebacks by default.
 	WRAPPER = 32
 
 	// This function uses its incoming context register.
 	NEEDCTXT = 64
 
-	// When passed to ggloblsym, causes Local to be set to true on the LSym it creates.
+	// When passed to objw.Global, causes Local to be set to true on the LSym it creates.
 	LOCAL = 128
 
 	// Allocate a word of thread local storage and store the offset from the
@@ -48,7 +49,10 @@
 	// Function can call reflect.Type.Method or reflect.Type.MethodByName.
 	REFLECTMETHOD = 1024
 
-	// Function is the top of the call stack. Call stack unwinders should stop
-	// at this function.
+	// Function is the outermost frame of the call stack. Call stack unwinders
+	// should stop at this function.
 	TOPFRAME = 2048
+
+	// Function is an ABI wrapper.
+	ABIWRAPPER = 4096
 )
diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go
index b9bacb7..e8441a6 100644
--- a/src/cmd/internal/obj/util.go
+++ b/src/cmd/internal/obj/util.go
@@ -8,6 +8,7 @@
 	"bytes"
 	"cmd/internal/objabi"
 	"fmt"
+	"internal/buildcfg"
 	"io"
 	"strings"
 )
@@ -83,7 +84,7 @@
 	}
 	for i := range opSuffixSpace {
 		sset := &opSuffixSpace[i]
-		if sset.arch == objabi.GOARCH {
+		if sset.arch == buildcfg.GOARCH {
 			return sset.cconv(s)
 		}
 	}
@@ -187,7 +188,7 @@
 		// In short, print one of these two:
 		// TEXT	foo(SB), DUPOK|NOSPLIT, $0
 		// TEXT	foo(SB), $0
-		s := p.From.Sym.Attribute.TextAttrString()
+		s := p.From.Sym.TextAttrString()
 		if s != "" {
 			fmt.Fprintf(w, "%s%s", sep, s)
 			sep = ", "
@@ -330,7 +331,7 @@
 	case TYPE_SHIFT:
 		v := int(a.Offset)
 		ops := "<<>>->@>"
-		switch objabi.GOARCH {
+		switch buildcfg.GOARCH {
 		case "arm":
 			op := ops[((v>>5)&3)<<1:]
 			if v&(1<<4) != 0 {
@@ -346,7 +347,7 @@
 			r := (v >> 16) & 31
 			fmt.Fprintf(w, "%s%c%c%d", Rconv(r+RBaseARM64), op[0], op[1], (v>>10)&63)
 		default:
-			panic("TYPE_SHIFT is not supported on " + objabi.GOARCH)
+			panic("TYPE_SHIFT is not supported on " + buildcfg.GOARCH)
 		}
 
 	case TYPE_REGREG:
diff --git a/src/cmd/internal/obj/wasm/wasmobj.go b/src/cmd/internal/obj/wasm/wasmobj.go
index 2e9890d..ceeae7a 100644
--- a/src/cmd/internal/obj/wasm/wasmobj.go
+++ b/src/cmd/internal/obj/wasm/wasmobj.go
@@ -144,11 +144,9 @@
 	gcWriteBarrier = ctxt.LookupABI("runtime.gcWriteBarrier", obj.ABIInternal)
 	sigpanic = ctxt.LookupABI("runtime.sigpanic", obj.ABIInternal)
 	deferreturn = ctxt.LookupABI("runtime.deferreturn", obj.ABIInternal)
-	// jmpdefer is defined in assembly as ABI0, but what we're
-	// looking for is the *call* to jmpdefer from the Go function
-	// deferreturn, so we're looking for the ABIInternal version
-	// of jmpdefer that's called by Go.
-	jmpdefer = ctxt.LookupABI(`"".jmpdefer`, obj.ABIInternal)
+	// jmpdefer is defined in assembly as ABI0. The compiler will
+	// generate a direct ABI0 call from Go, so look for that.
+	jmpdefer = ctxt.LookupABI(`"".jmpdefer`, obj.ABI0)
 }
 
 func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
diff --git a/src/cmd/internal/obj/x86/a.out.go b/src/cmd/internal/obj/x86/a.out.go
index 30c1a6a..b121f6d 100644
--- a/src/cmd/internal/obj/x86/a.out.go
+++ b/src/cmd/internal/obj/x86/a.out.go
@@ -258,22 +258,25 @@
 	REG_DR = REG_DR0
 	REG_TR = REG_TR0
 
-	REGARG   = -1
-	REGRET   = REG_AX
-	FREGRET  = REG_X0
-	REGSP    = REG_SP
-	REGCTXT  = REG_DX
-	REGEXT   = REG_R15     // compiler allocates external registers R15 down
-	FREGMIN  = REG_X0 + 5  // first register variable
-	FREGEXT  = REG_X0 + 15 // first external register
-	T_TYPE   = 1 << 0
-	T_INDEX  = 1 << 1
-	T_OFFSET = 1 << 2
-	T_FCONST = 1 << 3
-	T_SYM    = 1 << 4
-	T_SCONST = 1 << 5
-	T_64     = 1 << 6
-	T_GOTYPE = 1 << 7
+	REGARG       = -1
+	REGRET       = REG_AX
+	FREGRET      = REG_X0
+	REGSP        = REG_SP
+	REGCTXT      = REG_DX
+	REGENTRYTMP0 = REG_R12     // scratch register available at function entry in ABIInternal
+	REGENTRYTMP1 = REG_R13     // scratch register available at function entry in ABIInternal
+	REGG         = REG_R14     // g register in ABIInternal
+	REGEXT       = REG_R15     // compiler allocates external registers R15 down
+	FREGMIN      = REG_X0 + 5  // first register variable
+	FREGEXT      = REG_X0 + 15 // first external register
+	T_TYPE       = 1 << 0
+	T_INDEX      = 1 << 1
+	T_OFFSET     = 1 << 2
+	T_FCONST     = 1 << 3
+	T_SYM        = 1 << 4
+	T_SCONST     = 1 << 5
+	T_64         = 1 << 6
+	T_GOTYPE     = 1 << 7
 )
 
 // https://www.uclibc.org/docs/psABI-x86_64.pdf, figure 3.36
diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go
index a6b85ac..17fa767 100644
--- a/src/cmd/internal/obj/x86/asm6.go
+++ b/src/cmd/internal/obj/x86/asm6.go
@@ -36,6 +36,7 @@
 	"cmd/internal/sys"
 	"encoding/binary"
 	"fmt"
+	"internal/buildcfg"
 	"log"
 	"strings"
 )
@@ -1887,7 +1888,7 @@
 func fusedJump(p *obj.Prog) (bool, uint8) {
 	var fusedSize uint8
 
-	// The first instruction in a macro fused pair may be preceeded by the LOCK prefix,
+	// The first instruction in a macro fused pair may be preceded by the LOCK prefix,
 	// or possibly an XACQUIRE/XRELEASE prefix followed by a LOCK prefix. If it is, we
 	// need to be careful to insert any padding before the locks rather than directly after them.
 
@@ -2460,7 +2461,7 @@
 	}
 }
 
-var isAndroid = objabi.GOOS == "android"
+var isAndroid = buildcfg.GOOS == "android"
 
 func prefixof(ctxt *obj.Link, a *obj.Addr) int {
 	if a.Reg < REG_CS && a.Index < REG_CS { // fast path
@@ -5306,7 +5307,7 @@
 		}
 	}
 
-	ctxt.Diag("invalid instruction: %v", p)
+	ctxt.Diag("%s: invalid instruction: %v", cursym.Name, p)
 }
 
 // byteswapreg returns a byte-addressable register (AX, BX, CX, DX)
diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go
index 184fb43..e2732d5 100644
--- a/src/cmd/internal/obj/x86/obj6.go
+++ b/src/cmd/internal/obj/x86/obj6.go
@@ -35,7 +35,10 @@
 	"cmd/internal/objabi"
 	"cmd/internal/src"
 	"cmd/internal/sys"
+	"internal/buildcfg"
+	"log"
 	"math"
+	"path"
 	"strings"
 )
 
@@ -134,7 +137,7 @@
 			p.To.Index = REG_NONE
 		}
 	} else {
-		// load_g_cx, below, always inserts the 1-instruction sequence. Rewrite it
+		// load_g, below, always inserts the 1-instruction sequence. Rewrite it
 		// as the 2-instruction sequence if necessary.
 		//	MOVQ 0(TLS), BX
 		// becomes
@@ -562,6 +565,11 @@
 	obj.Nopout(p)
 }
 
+// Prog.mark
+const (
+	markBit = 1 << 0 // used in errorCheck to avoid duplicate work
+)
+
 func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
 	if cursym.Func().Text == nil || cursym.Func().Text.Link == nil {
 		return
@@ -637,13 +645,29 @@
 		}
 	}
 
+	var regg int16
 	if !p.From.Sym.NoSplit() || p.From.Sym.Wrapper() {
-		p = obj.Appendp(p, newprog)
-		p = load_g_cx(ctxt, p, newprog) // load g into CX
+		if ctxt.Arch.Family == sys.AMD64 && buildcfg.Experiment.RegabiG && cursym.ABI() == obj.ABIInternal {
+			regg = REGG // use the g register directly in ABIInternal
+		} else {
+			p = obj.Appendp(p, newprog)
+			regg = REG_CX
+			if ctxt.Arch.Family == sys.AMD64 {
+				// Using this register means that stacksplit works w/ //go:registerparams even when !buildcfg.Experiment.RegabiG
+				regg = REGG // == REG_R14
+			}
+			p = load_g(ctxt, p, newprog, regg) // load g into regg
+		}
+	}
+	var regEntryTmp0, regEntryTmp1 int16
+	if ctxt.Arch.Family == sys.AMD64 {
+		regEntryTmp0, regEntryTmp1 = REGENTRYTMP0, REGENTRYTMP1
+	} else {
+		regEntryTmp0, regEntryTmp1 = REG_BX, REG_DI
 	}
 
 	if !cursym.Func().Text.From.Sym.NoSplit() {
-		p = stacksplit(ctxt, cursym, p, newprog, autoffset, int32(textarg)) // emit split check
+		p = stacksplit(ctxt, cursym, p, newprog, autoffset, int32(textarg), regg) // emit split check
 	}
 
 	// Delve debugger would like the next instruction to be noted as the end of the function prologue.
@@ -695,17 +719,17 @@
 		//   g._panic.argp = bottom-of-frame
 		// }
 		//
-		//	MOVQ g_panic(CX), BX
-		//	TESTQ BX, BX
+		//	MOVQ g_panic(g), regEntryTmp0
+		//	TESTQ regEntryTmp0, regEntryTmp0
 		//	JNE checkargp
 		// end:
 		//	NOP
 		//  ... rest of function ...
 		// checkargp:
-		//	LEAQ (autoffset+8)(SP), DI
-		//	CMPQ panic_argp(BX), DI
+		//	LEAQ (autoffset+8)(SP), regEntryTmp1
+		//	CMPQ panic_argp(regEntryTmp0), regEntryTmp1
 		//	JNE end
-		//  MOVQ SP, panic_argp(BX)
+		//  MOVQ SP, panic_argp(regEntryTmp0)
 		//  JMP end
 		//
 		// The NOP is needed to give the jumps somewhere to land.
@@ -714,25 +738,25 @@
 		// The layout is chosen to help static branch prediction:
 		// Both conditional jumps are unlikely, so they are arranged to be forward jumps.
 
-		// MOVQ g_panic(CX), BX
+		// MOVQ g_panic(g), regEntryTmp0
 		p = obj.Appendp(p, newprog)
 		p.As = AMOVQ
 		p.From.Type = obj.TYPE_MEM
-		p.From.Reg = REG_CX
+		p.From.Reg = regg
 		p.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // g_panic
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_BX
+		p.To.Reg = regEntryTmp0
 		if ctxt.Arch.Family == sys.I386 {
 			p.As = AMOVL
 		}
 
-		// TESTQ BX, BX
+		// TESTQ regEntryTmp0, regEntryTmp0
 		p = obj.Appendp(p, newprog)
 		p.As = ATESTQ
 		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_BX
+		p.From.Reg = regEntryTmp0
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_BX
+		p.To.Reg = regEntryTmp0
 		if ctxt.Arch.Family == sys.I386 {
 			p.As = ATESTL
 		}
@@ -752,14 +776,14 @@
 		for last = end; last.Link != nil; last = last.Link {
 		}
 
-		// LEAQ (autoffset+8)(SP), DI
+		// LEAQ (autoffset+8)(SP), regEntryTmp1
 		p = obj.Appendp(last, newprog)
 		p.As = ALEAQ
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = REG_SP
 		p.From.Offset = int64(autoffset) + int64(ctxt.Arch.RegSize)
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_DI
+		p.To.Reg = regEntryTmp1
 		if ctxt.Arch.Family == sys.I386 {
 			p.As = ALEAL
 		}
@@ -767,14 +791,14 @@
 		// Set jne branch target.
 		jne.To.SetTarget(p)
 
-		// CMPQ panic_argp(BX), DI
+		// CMPQ panic_argp(regEntryTmp0), regEntryTmp1
 		p = obj.Appendp(p, newprog)
 		p.As = ACMPQ
 		p.From.Type = obj.TYPE_MEM
-		p.From.Reg = REG_BX
+		p.From.Reg = regEntryTmp0
 		p.From.Offset = 0 // Panic.argp
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_DI
+		p.To.Reg = regEntryTmp1
 		if ctxt.Arch.Family == sys.I386 {
 			p.As = ACMPL
 		}
@@ -785,13 +809,13 @@
 		p.To.Type = obj.TYPE_BRANCH
 		p.To.SetTarget(end)
 
-		// MOVQ SP, panic_argp(BX)
+		// MOVQ SP, panic_argp(regEntryTmp0)
 		p = obj.Appendp(p, newprog)
 		p.As = AMOVQ
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = REG_SP
 		p.To.Type = obj.TYPE_MEM
-		p.To.Reg = REG_BX
+		p.To.Reg = regEntryTmp0
 		p.To.Offset = 0 // Panic.argp
 		if ctxt.Arch.Family == sys.I386 {
 			p.As = AMOVL
@@ -833,6 +857,20 @@
 
 		switch p.As {
 		default:
+			if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_SP && p.As != ACMPL && p.As != ACMPQ {
+				f := cursym.Func()
+				if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
+					f.FuncFlag |= objabi.FuncFlag_SPWRITE
+					if ctxt.Debugvlog || !ctxt.IsAsm {
+						ctxt.Logf("auto-SPWRITE: %s %v\n", cursym.Name, p)
+						if !ctxt.IsAsm {
+							ctxt.Diag("invalid auto-SPWRITE in non-assembly")
+							ctxt.DiagFlush()
+							log.Fatalf("bad SPWRITE")
+						}
+					}
+				}
+			}
 			continue
 
 		case APUSHL, APUSHFL:
@@ -875,7 +913,7 @@
 		}
 
 		if autoffset != deltasp {
-			ctxt.Diag("unbalanced PUSH/POP")
+			ctxt.Diag("%s: unbalanced PUSH/POP", cursym)
 		}
 
 		if autoffset != 0 {
@@ -942,7 +980,7 @@
 // Overwriting p is unusual but it lets use this in both the
 // prologue (caller must call appendp first) and in the epilogue.
 // Returns last new instruction.
-func load_g_cx(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) *obj.Prog {
+func load_g(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, rg int16) *obj.Prog {
 	p.As = AMOVQ
 	if ctxt.Arch.PtrSize == 4 {
 		p.As = AMOVL
@@ -951,7 +989,7 @@
 	p.From.Reg = REG_TLS
 	p.From.Offset = 0
 	p.To.Type = obj.TYPE_REG
-	p.To.Reg = REG_CX
+	p.To.Reg = rg
 
 	next := p.Link
 	progedit(ctxt, p, newprog)
@@ -969,9 +1007,9 @@
 
 // Append code to p to check for stack split.
 // Appends to (does not overwrite) p.
-// Assumes g is in CX.
+// Assumes g is in rg.
 // Returns last new instruction.
-func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc, framesize int32, textarg int32) *obj.Prog {
+func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc, framesize int32, textarg int32, rg int16) *obj.Prog {
 	cmp := ACMPQ
 	lea := ALEAQ
 	mov := AMOVQ
@@ -984,6 +1022,12 @@
 		sub = ASUBL
 	}
 
+	tmp := int16(REG_AX) // use AX for 32-bit
+	if ctxt.Arch.Family == sys.AMD64 {
+		// Avoid register parameters.
+		tmp = int16(REGENTRYTMP0)
+	}
+
 	var q1 *obj.Prog
 	if framesize <= objabi.StackSmall {
 		// small stack: SP <= stackguard
@@ -993,7 +1037,8 @@
 		p.As = cmp
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = REG_SP
-		indir_cx(ctxt, &p.To)
+		p.To.Type = obj.TYPE_MEM
+		p.To.Reg = rg
 		p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
 		if cursym.CFunc() {
 			p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
@@ -1006,8 +1051,8 @@
 		p = ctxt.StartUnsafePoint(p, newprog)
 	} else if framesize <= objabi.StackBig {
 		// large stack: SP-framesize <= stackguard-StackSmall
-		//	LEAQ -xxx(SP), AX
-		//	CMPQ AX, stackguard
+		//	LEAQ -xxx(SP), tmp
+		//	CMPQ tmp, stackguard
 		p = obj.Appendp(p, newprog)
 
 		p.As = lea
@@ -1015,13 +1060,14 @@
 		p.From.Reg = REG_SP
 		p.From.Offset = -(int64(framesize) - objabi.StackSmall)
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_AX
+		p.To.Reg = tmp
 
 		p = obj.Appendp(p, newprog)
 		p.As = cmp
 		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_AX
-		indir_cx(ctxt, &p.To)
+		p.From.Reg = tmp
+		p.To.Type = obj.TYPE_MEM
+		p.To.Reg = rg
 		p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
 		if cursym.CFunc() {
 			p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
@@ -1029,70 +1075,51 @@
 
 		p = ctxt.StartUnsafePoint(p, newprog) // see the comment above
 	} else {
-		// Such a large stack we need to protect against wraparound.
-		// If SP is close to zero:
-		//	SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
-		// The +StackGuard on both sides is required to keep the left side positive:
-		// SP is allowed to be slightly below stackguard. See stack.h.
+		// Such a large stack we need to protect against underflow.
+		// The runtime guarantees SP > objabi.StackBig, but
+		// framesize is large enough that SP-framesize may
+		// underflow, causing a direct comparison with the
+		// stack guard to incorrectly succeed. We explicitly
+		// guard against underflow.
 		//
-		// Preemption sets stackguard to StackPreempt, a very large value.
-		// That breaks the math above, so we have to check for that explicitly.
-		//	MOVQ	stackguard, SI
-		//	CMPQ	SI, $StackPreempt
-		//	JEQ	label-of-call-to-morestack
-		//	LEAQ	StackGuard(SP), AX
-		//	SUBQ	SI, AX
-		//	CMPQ	AX, $(framesize+(StackGuard-StackSmall))
+		//	MOVQ	SP, tmp
+		//	SUBQ	$(framesize - StackSmall), tmp
+		//	// If subtraction wrapped (carry set), morestack.
+		//	JCS	label-of-call-to-morestack
+		//	CMPQ	tmp, stackguard
 
 		p = obj.Appendp(p, newprog)
 
 		p.As = mov
-		indir_cx(ctxt, &p.From)
-		p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
-		if cursym.CFunc() {
-			p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
-		}
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = REG_SP
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_SI
+		p.To.Reg = tmp
 
 		p = ctxt.StartUnsafePoint(p, newprog) // see the comment above
 
 		p = obj.Appendp(p, newprog)
-		p.As = cmp
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_SI
-		p.To.Type = obj.TYPE_CONST
-		p.To.Offset = objabi.StackPreempt
-		if ctxt.Arch.Family == sys.I386 {
-			p.To.Offset = int64(uint32(objabi.StackPreempt & (1<<32 - 1)))
-		}
+		p.As = sub
+		p.From.Type = obj.TYPE_CONST
+		p.From.Offset = int64(framesize) - objabi.StackSmall
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = tmp
 
 		p = obj.Appendp(p, newprog)
-		p.As = AJEQ
+		p.As = AJCS
 		p.To.Type = obj.TYPE_BRANCH
 		q1 = p
 
 		p = obj.Appendp(p, newprog)
-		p.As = lea
-		p.From.Type = obj.TYPE_MEM
-		p.From.Reg = REG_SP
-		p.From.Offset = int64(objabi.StackGuard)
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_AX
-
-		p = obj.Appendp(p, newprog)
-		p.As = sub
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_SI
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REG_AX
-
-		p = obj.Appendp(p, newprog)
 		p.As = cmp
 		p.From.Type = obj.TYPE_REG
-		p.From.Reg = REG_AX
-		p.To.Type = obj.TYPE_CONST
-		p.To.Offset = int64(framesize) + (int64(objabi.StackGuard) - objabi.StackSmall)
+		p.From.Reg = tmp
+		p.To.Type = obj.TYPE_MEM
+		p.To.Reg = rg
+		p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
+		if cursym.CFunc() {
+			p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
+		}
 	}
 
 	// common
@@ -1114,7 +1141,8 @@
 	spfix.Spadj = -framesize
 
 	pcdata := ctxt.EmitEntryStackMap(cursym, spfix, newprog)
-	pcdata = ctxt.StartUnsafePoint(pcdata, newprog)
+	spill := ctxt.StartUnsafePoint(pcdata, newprog)
+	pcdata = cursym.Func().SpillRegisterArgs(spill, newprog)
 
 	call := obj.Appendp(pcdata, newprog)
 	call.Pos = cursym.Func().Text.Pos
@@ -1139,7 +1167,8 @@
 		progedit(ctxt, callend.Link, newprog)
 	}
 
-	pcdata = ctxt.EndUnsafePoint(callend, newprog, -1)
+	pcdata = cursym.Func().UnspillRegisterArgs(callend, newprog)
+	pcdata = ctxt.EndUnsafePoint(pcdata, newprog, -1)
 
 	jmp := obj.Appendp(pcdata, newprog)
 	jmp.As = obj.AJMP
@@ -1147,14 +1176,122 @@
 	jmp.To.SetTarget(cursym.Func().Text.Link)
 	jmp.Spadj = +framesize
 
-	jls.To.SetTarget(call)
+	jls.To.SetTarget(spill)
 	if q1 != nil {
-		q1.To.SetTarget(call)
+		q1.To.SetTarget(spill)
 	}
 
 	return end
 }
 
+func isR15(r int16) bool {
+	return r == REG_R15 || r == REG_R15B
+}
+func addrMentionsR15(a *obj.Addr) bool {
+	if a == nil {
+		return false
+	}
+	return isR15(a.Reg) || isR15(a.Index)
+}
+func progMentionsR15(p *obj.Prog) bool {
+	return addrMentionsR15(&p.From) || addrMentionsR15(&p.To) || isR15(p.Reg) || addrMentionsR15(p.GetFrom3())
+}
+
+// progOverwritesR15 reports whether p writes to R15 and does not depend on
+// the previous value of R15.
+func progOverwritesR15(p *obj.Prog) bool {
+	if !(p.To.Type == obj.TYPE_REG && isR15(p.To.Reg)) {
+		// Not writing to R15.
+		return false
+	}
+	if (p.As == AXORL || p.As == AXORQ) && p.From.Type == obj.TYPE_REG && isR15(p.From.Reg) {
+		// These look like uses of R15, but aren't, so we must detect these
+		// before the use check below.
+		return true
+	}
+	if addrMentionsR15(&p.From) || isR15(p.Reg) || addrMentionsR15(p.GetFrom3()) {
+		// use before overwrite
+		return false
+	}
+	if p.As == AMOVL || p.As == AMOVQ || p.As == APOPQ {
+		return true
+		// TODO: MOVB might be ok if we only ever use R15B.
+	}
+	return false
+}
+
+func addrUsesGlobal(a *obj.Addr) bool {
+	if a == nil {
+		return false
+	}
+	return a.Name == obj.NAME_EXTERN && !a.Sym.Local()
+}
+func progUsesGlobal(p *obj.Prog) bool {
+	if p.As == obj.ACALL || p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ARET || p.As == obj.AJMP {
+		// These opcodes don't use a GOT to access their argument (see rewriteToUseGot),
+		// or R15 would be dead at them anyway.
+		return false
+	}
+	if p.As == ALEAQ {
+		// The GOT entry is placed directly in the destination register; R15 is not used.
+		return false
+	}
+	return addrUsesGlobal(&p.From) || addrUsesGlobal(&p.To) || addrUsesGlobal(p.GetFrom3())
+}
+
+func errorCheck(ctxt *obj.Link, s *obj.LSym) {
+	// When dynamic linking, R15 is used to access globals. Reject code that
+	// uses R15 after a global variable access.
+	if !ctxt.Flag_dynlink {
+		return
+	}
+
+	// Flood fill all the instructions where R15's value is junk.
+	// If there are any uses of R15 in that set, report an error.
+	var work []*obj.Prog
+	var mentionsR15 bool
+	for p := s.Func().Text; p != nil; p = p.Link {
+		if progUsesGlobal(p) {
+			work = append(work, p)
+			p.Mark |= markBit
+		}
+		if progMentionsR15(p) {
+			mentionsR15 = true
+		}
+	}
+	if mentionsR15 {
+		for len(work) > 0 {
+			p := work[len(work)-1]
+			work = work[:len(work)-1]
+			if q := p.To.Target(); q != nil && q.Mark&markBit == 0 {
+				q.Mark |= markBit
+				work = append(work, q)
+			}
+			if p.As == obj.AJMP || p.As == obj.ARET {
+				continue // no fallthrough
+			}
+			if progMentionsR15(p) {
+				if progOverwritesR15(p) {
+					// R15 is overwritten by this instruction. Its value is not junk any more.
+					continue
+				}
+				pos := ctxt.PosTable.Pos(p.Pos)
+				ctxt.Diag("%s:%s: when dynamic linking, R15 is clobbered by a global variable access and is used here: %v", path.Base(pos.Filename()), pos.LineNumber(), p)
+				break // only report one error
+			}
+			if q := p.Link; q != nil && q.Mark&markBit == 0 {
+				q.Mark |= markBit
+				work = append(work, q)
+			}
+		}
+	}
+
+	// Clean up.
+	for p := s.Func().Text; p != nil; p = p.Link {
+		p.Mark &^= markBit
+	}
+}
+
 var unaryDst = map[obj.As]bool{
 	ABSWAPL:     true,
 	ABSWAPQ:     true,
@@ -1243,6 +1380,7 @@
 var Linkamd64 = obj.LinkArch{
 	Arch:           sys.ArchAMD64,
 	Init:           instinit,
+	ErrorCheck:     errorCheck,
 	Preprocess:     preprocess,
 	Assemble:       span6,
 	Progedit:       progedit,
diff --git a/src/cmd/internal/objabi/flag.go b/src/cmd/internal/objabi/flag.go
index 3fd73f3..e41fc57 100644
--- a/src/cmd/internal/objabi/flag.go
+++ b/src/cmd/internal/objabi/flag.go
@@ -8,6 +8,7 @@
 	"bytes"
 	"flag"
 	"fmt"
+	"internal/buildcfg"
 	"io"
 	"io/ioutil"
 	"log"
@@ -91,16 +92,18 @@
 	name = name[strings.LastIndex(name, `\`)+1:]
 	name = strings.TrimSuffix(name, ".exe")
 
-	// If there's an active experiment, include that,
-	// to distinguish go1.10.2 with an experiment
-	// from go1.10.2 without an experiment.
-	p := Expstring()
-	if p == DefaultExpstring() {
-		p = ""
-	}
-	sep := ""
-	if p != "" {
-		sep = " "
+	p := ""
+
+	if s == "goexperiment" {
+		// test/run.go uses this to discover the full set of
+		// experiment tags. Report everything.
+		p = " X:" + strings.Join(buildcfg.AllExperiments(), ",")
+	} else {
+		// If the enabled experiments differ from the defaults,
+		// include that difference.
+		if goexperiment := buildcfg.GOEXPERIMENT(); goexperiment != "" {
+			p = " X:" + goexperiment
+		}
 	}
 
 	// The go command invokes -V=full to get a unique identifier
@@ -109,12 +112,12 @@
 	// build ID of the binary, so that if the compiler is changed and
 	// rebuilt, we notice and rebuild all packages.
 	if s == "full" {
-		if strings.HasPrefix(Version, "devel") {
+		if strings.HasPrefix(buildcfg.Version, "devel") {
 			p += " buildID=" + buildID
 		}
 	}
 
-	fmt.Printf("%s version %s%s%s\n", name, Version, sep, p)
+	fmt.Printf("%s version %s%s\n", name, buildcfg.Version, p)
 	os.Exit(0)
 	return nil
 }
diff --git a/src/cmd/internal/objabi/funcdata.go b/src/cmd/internal/objabi/funcdata.go
index faa2863..4ff0ebe 100644
--- a/src/cmd/internal/objabi/funcdata.go
+++ b/src/cmd/internal/objabi/funcdata.go
@@ -20,6 +20,7 @@
 	FUNCDATA_StackObjects       = 2
 	FUNCDATA_InlTree            = 3
 	FUNCDATA_OpenCodedDeferInfo = 4
+	FUNCDATA_ArgInfo            = 5
 
 	// ArgsSizeUnknown is set in Func.argsize to mark all functions
 	// whose argument size is unknown (C vararg functions, and
diff --git a/src/cmd/internal/objabi/funcid.go b/src/cmd/internal/objabi/funcid.go
index 1d098ee..93ebd7b 100644
--- a/src/cmd/internal/objabi/funcid.go
+++ b/src/cmd/internal/objabi/funcid.go
@@ -4,97 +4,90 @@
 
 package objabi
 
+import "strings"
+
+// A FuncFlag records bits about a function, passed to the runtime.
+type FuncFlag uint8
+
+// Note: This list must match the list in runtime/symtab.go.
+const (
+	FuncFlag_TOPFRAME = 1 << iota
+	FuncFlag_SPWRITE
+)
+
 // A FuncID identifies particular functions that need to be treated
 // specially by the runtime.
 // Note that in some situations involving plugins, there may be multiple
 // copies of a particular special runtime function.
-// Note: this list must match the list in runtime/symtab.go.
 type FuncID uint8
 
+// Note: this list must match the list in runtime/symtab.go.
 const (
 	FuncID_normal FuncID = iota // not a special function
-	FuncID_runtime_main
+	FuncID_abort
+	FuncID_asmcgocall
+	FuncID_asyncPreempt
+	FuncID_cgocallback
+	FuncID_debugCallV2
+	FuncID_gcBgMarkWorker
 	FuncID_goexit
+	FuncID_gogo
+	FuncID_gopanic
+	FuncID_handleAsyncEvent
 	FuncID_jmpdefer
 	FuncID_mcall
 	FuncID_morestack
 	FuncID_mstart
-	FuncID_rt0_go
-	FuncID_asmcgocall
-	FuncID_sigpanic
-	FuncID_runfinq
-	FuncID_gcBgMarkWorker
-	FuncID_systemstack_switch
-	FuncID_systemstack
-	FuncID_cgocallback
-	FuncID_gogo
-	FuncID_externalthreadhandler
-	FuncID_debugCallV1
-	FuncID_gopanic
 	FuncID_panicwrap
-	FuncID_handleAsyncEvent
-	FuncID_asyncPreempt
+	FuncID_rt0_go
+	FuncID_runfinq
+	FuncID_runtime_main
+	FuncID_sigpanic
+	FuncID_systemstack
+	FuncID_systemstack_switch
 	FuncID_wrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.)
 )
 
+var funcIDs = map[string]FuncID{
+	"abort":            FuncID_abort,
+	"asmcgocall":       FuncID_asmcgocall,
+	"asyncPreempt":     FuncID_asyncPreempt,
+	"cgocallback":      FuncID_cgocallback,
+	"debugCallV2":      FuncID_debugCallV2,
+	"gcBgMarkWorker":   FuncID_gcBgMarkWorker,
+	"go":               FuncID_rt0_go,
+	"goexit":           FuncID_goexit,
+	"gogo":             FuncID_gogo,
+	"gopanic":          FuncID_gopanic,
+	"handleAsyncEvent": FuncID_handleAsyncEvent,
+	"jmpdefer":         FuncID_jmpdefer,
+	"main":             FuncID_runtime_main,
+	"mcall":            FuncID_mcall,
+	"morestack":        FuncID_morestack,
+	"mstart":           FuncID_mstart,
+	"panicwrap":        FuncID_panicwrap,
+	"runfinq":          FuncID_runfinq,
+	"sigpanic":         FuncID_sigpanic,
+	"switch":           FuncID_systemstack_switch,
+	"systemstack":      FuncID_systemstack,
+
+	// Don't show in call stack but otherwise not special.
+	"deferreturn":       FuncID_wrapper,
+	"runOpenDeferFrame": FuncID_wrapper,
+	"reflectcallSave":   FuncID_wrapper,
+	"deferCallSave":     FuncID_wrapper,
+}
+
 // Get the function ID for the named function in the named file.
 // The function should be package-qualified.
 func GetFuncID(name string, isWrapper bool) FuncID {
 	if isWrapper {
 		return FuncID_wrapper
 	}
-	switch name {
-	case "runtime.main":
-		return FuncID_runtime_main
-	case "runtime.goexit":
-		return FuncID_goexit
-	case "runtime.jmpdefer":
-		return FuncID_jmpdefer
-	case "runtime.mcall":
-		return FuncID_mcall
-	case "runtime.morestack":
-		return FuncID_morestack
-	case "runtime.mstart":
-		return FuncID_mstart
-	case "runtime.rt0_go":
-		return FuncID_rt0_go
-	case "runtime.asmcgocall":
-		return FuncID_asmcgocall
-	case "runtime.sigpanic":
-		return FuncID_sigpanic
-	case "runtime.runfinq":
-		return FuncID_runfinq
-	case "runtime.gcBgMarkWorker":
-		return FuncID_gcBgMarkWorker
-	case "runtime.systemstack_switch":
-		return FuncID_systemstack_switch
-	case "runtime.systemstack":
-		return FuncID_systemstack
-	case "runtime.cgocallback":
-		return FuncID_cgocallback
-	case "runtime.gogo":
-		return FuncID_gogo
-	case "runtime.externalthreadhandler":
-		return FuncID_externalthreadhandler
-	case "runtime.debugCallV1":
-		return FuncID_debugCallV1
-	case "runtime.gopanic":
-		return FuncID_gopanic
-	case "runtime.panicwrap":
-		return FuncID_panicwrap
-	case "runtime.handleAsyncEvent":
-		return FuncID_handleAsyncEvent
-	case "runtime.asyncPreempt":
-		return FuncID_asyncPreempt
-	case "runtime.deferreturn":
-		// Don't show in the call stack (used when invoking defer functions)
-		return FuncID_wrapper
-	case "runtime.runOpenDeferFrame":
-		// Don't show in the call stack (used when invoking defer functions)
-		return FuncID_wrapper
-	case "runtime.reflectcallSave":
-		// Don't show in the call stack (used when invoking defer functions)
-		return FuncID_wrapper
+	if strings.HasPrefix(name, "runtime.") {
+		if id, ok := funcIDs[name[len("runtime."):]]; ok {
+			return id
+		}
 	}
 	return FuncID_normal
 }
diff --git a/src/cmd/internal/objabi/line.go b/src/cmd/internal/objabi/line.go
index 0733b65..0b1e0bb 100644
--- a/src/cmd/internal/objabi/line.go
+++ b/src/cmd/internal/objabi/line.go
@@ -5,6 +5,7 @@
 package objabi
 
 import (
+	"internal/buildcfg"
 	"os"
 	"path/filepath"
 	"strings"
@@ -38,8 +39,8 @@
 	}
 
 	abs, rewritten := ApplyRewrites(abs, rewrites)
-	if !rewritten && hasPathPrefix(abs, GOROOT) {
-		abs = "$GOROOT" + abs[len(GOROOT):]
+	if !rewritten && hasPathPrefix(abs, buildcfg.GOROOT) {
+		abs = "$GOROOT" + abs[len(buildcfg.GOROOT):]
 	}
 
 	if abs == "" {
diff --git a/src/cmd/internal/objabi/path.go b/src/cmd/internal/objabi/path.go
index fd1c998..aacab9a 100644
--- a/src/cmd/internal/objabi/path.go
+++ b/src/cmd/internal/objabi/path.go
@@ -47,6 +47,8 @@
 // some cases need to be aware of when they are building such a
 // package, for example to enable features such as ABI selectors in
 // assembly sources.
+//
+// Keep in sync with cmd/dist/build.go:IsRuntimePackagePath.
 func IsRuntimePackagePath(pkgpath string) bool {
 	rval := false
 	switch pkgpath {
@@ -56,6 +58,8 @@
 		rval = true
 	case "syscall":
 		rval = true
+	case "internal/bytealg":
+		rval = true
 	default:
 		rval = strings.HasPrefix(pkgpath, "runtime/internal")
 	}
diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go
index 649f690..52827a6 100644
--- a/src/cmd/internal/objabi/reloctype.go
+++ b/src/cmd/internal/objabi/reloctype.go
@@ -50,11 +50,6 @@
 	// R_ADDROFF resolves to a 32-bit offset from the beginning of the section
 	// holding the data being relocated to the referenced symbol.
 	R_ADDROFF
-	// R_WEAKADDROFF resolves just like R_ADDROFF but is a weak relocation.
-	// A weak relocation does not make the symbol it refers to reachable,
-	// and is only honored by the linker if the symbol is in some other way
-	// reachable.
-	R_WEAKADDROFF
 	R_SIZE
 	R_CALL
 	R_CALLARM
@@ -106,6 +101,9 @@
 	// *rtype, and may be set to zero by the linker if it determines the method
 	// text is unreachable by the linked program.
 	R_METHODOFF
+	// R_KEEP tells the linker to keep the referred-to symbol in the final binary
+	// if the symbol containing the R_KEEP relocation is in the final binary.
+	R_KEEP
 	R_POWER_TOC
 	R_GOTPCREL
 	// R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address
@@ -172,8 +170,8 @@
 
 	// R_POWER_TLS_LE is used to implement the "local exec" model for tls
 	// access. It resolves to the offset of the thread-local symbol from the
-	// thread pointer (R13) and inserts this value into the low 16 bits of an
-	// instruction word.
+	// thread pointer (R13) and is split against a pair of instructions to
+	// support a 32 bit displacement.
 	R_POWER_TLS_LE
 
 	// R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It
@@ -183,10 +181,12 @@
 	// symbol from the thread pointer (R13)).
 	R_POWER_TLS_IE
 
-	// R_POWER_TLS marks an X-form instruction such as "MOVD 0(R13)(R31*1), g" as
-	// accessing a particular thread-local symbol. It does not affect code generation
-	// but is used by the system linker when relaxing "initial exec" model code to
-	// "local exec" model code.
+	// R_POWER_TLS marks an X-form instruction such as "ADD R3,R13,R4" as completing
+	// a sequence of GOT-relative relocations to compute a TLS address. This can be
+	// used by the system linker to to rewrite the GOT-relative TLS relocation into a
+	// simpler thread-pointer relative relocation. See table 3.26 and 3.28 in the
+	// ppc64 elfv2 1.4 ABI on this transformation.  Likewise, the second argument
+	// (usually called RB in X-form instructions) is assumed to be R13.
 	R_POWER_TLS
 
 	// R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second
@@ -256,6 +256,15 @@
 	// of a symbol. This isn't a real relocation, it can be placed in anywhere
 	// in a symbol and target any symbols.
 	R_XCOFFREF
+
+	// R_WEAK marks the relocation as a weak reference.
+	// A weak relocation does not make the symbol it refers to reachable,
+	// and is only honored by the linker if the symbol is in some other way
+	// reachable.
+	R_WEAK = -1 << 15
+
+	R_WEAKADDR    = R_WEAK | R_ADDR
+	R_WEAKADDROFF = R_WEAK | R_ADDROFF
 )
 
 // IsDirectCall reports whether r is a relocation for a direct call.
diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go
index 658a44f..4638ef1 100644
--- a/src/cmd/internal/objabi/reloctype_string.go
+++ b/src/cmd/internal/objabi/reloctype_string.go
@@ -13,28 +13,28 @@
 	_ = x[R_ADDRARM64-3]
 	_ = x[R_ADDRMIPS-4]
 	_ = x[R_ADDROFF-5]
-	_ = x[R_WEAKADDROFF-6]
-	_ = x[R_SIZE-7]
-	_ = x[R_CALL-8]
-	_ = x[R_CALLARM-9]
-	_ = x[R_CALLARM64-10]
-	_ = x[R_CALLIND-11]
-	_ = x[R_CALLPOWER-12]
-	_ = x[R_CALLMIPS-13]
-	_ = x[R_CALLRISCV-14]
-	_ = x[R_CONST-15]
-	_ = x[R_PCREL-16]
-	_ = x[R_TLS_LE-17]
-	_ = x[R_TLS_IE-18]
-	_ = x[R_GOTOFF-19]
-	_ = x[R_PLT0-20]
-	_ = x[R_PLT1-21]
-	_ = x[R_PLT2-22]
-	_ = x[R_USEFIELD-23]
-	_ = x[R_USETYPE-24]
-	_ = x[R_USEIFACE-25]
-	_ = x[R_USEIFACEMETHOD-26]
-	_ = x[R_METHODOFF-27]
+	_ = x[R_SIZE-6]
+	_ = x[R_CALL-7]
+	_ = x[R_CALLARM-8]
+	_ = x[R_CALLARM64-9]
+	_ = x[R_CALLIND-10]
+	_ = x[R_CALLPOWER-11]
+	_ = x[R_CALLMIPS-12]
+	_ = x[R_CALLRISCV-13]
+	_ = x[R_CONST-14]
+	_ = x[R_PCREL-15]
+	_ = x[R_TLS_LE-16]
+	_ = x[R_TLS_IE-17]
+	_ = x[R_GOTOFF-18]
+	_ = x[R_PLT0-19]
+	_ = x[R_PLT1-20]
+	_ = x[R_PLT2-21]
+	_ = x[R_USEFIELD-22]
+	_ = x[R_USETYPE-23]
+	_ = x[R_USEIFACE-24]
+	_ = x[R_USEIFACEMETHOD-25]
+	_ = x[R_METHODOFF-26]
+	_ = x[R_KEEP-27]
 	_ = x[R_POWER_TOC-28]
 	_ = x[R_GOTPCREL-29]
 	_ = x[R_JMPMIPS-30]
@@ -70,9 +70,9 @@
 	_ = x[R_XCOFFREF-60]
 }
 
-const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF"
+const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF"
 
-var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 218, 234, 245, 256, 266, 275, 288, 302, 316, 330, 346, 357, 370, 383, 397, 411, 425, 440, 454, 468, 479, 493, 508, 525, 543, 564, 583, 602, 622, 642, 652, 663, 676, 687, 699, 709}
+var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 120, 127, 134, 142, 150, 158, 164, 170, 176, 186, 195, 205, 221, 232, 238, 249, 259, 268, 281, 295, 309, 323, 339, 350, 363, 376, 390, 404, 418, 433, 447, 461, 472, 486, 501, 518, 536, 557, 576, 595, 615, 635, 645, 656, 669, 680, 692, 702}
 
 func (i RelocType) String() string {
 	i -= 1
diff --git a/src/cmd/internal/objabi/stack.go b/src/cmd/internal/objabi/stack.go
index 05a1d4a..0c82a7c 100644
--- a/src/cmd/internal/objabi/stack.go
+++ b/src/cmd/internal/objabi/stack.go
@@ -4,6 +4,8 @@
 
 package objabi
 
+import "internal/buildcfg"
+
 // For the linkers. Must match Go definitions.
 
 const (
@@ -13,10 +15,6 @@
 	StackSmall  = 128
 )
 
-const (
-	StackPreempt = -1314 // 0xfff...fade
-)
-
 // Initialize StackGuard and StackLimit according to target system.
 var StackGuard = 928*stackGuardMultiplier() + StackSystem
 var StackLimit = StackGuard - StackSystem - StackSmall
@@ -26,7 +24,7 @@
 // builds that have larger stack frames or for specific targets.
 func stackGuardMultiplier() int {
 	// On AIX, a larger stack is needed for syscalls.
-	if GOOS == "aix" {
+	if buildcfg.GOOS == "aix" {
 		return 2
 	}
 	return stackGuardMultiplierDefault
diff --git a/src/cmd/internal/objabi/util.go b/src/cmd/internal/objabi/util.go
index a73ab47..6364095 100644
--- a/src/cmd/internal/objabi/util.go
+++ b/src/cmd/internal/objabi/util.go
@@ -6,32 +6,9 @@
 
 import (
 	"fmt"
-	"log"
-	"os"
 	"strings"
-)
 
-func envOr(key, value string) string {
-	if x := os.Getenv(key); x != "" {
-		return x
-	}
-	return value
-}
-
-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()
-	GOMIPS64 = gomips64()
-	GOPPC64  = goppc64()
-	GOWASM   = gowasm()
-	GO_LDSO  = defaultGO_LDSO
-	Version  = version
+	"internal/buildcfg"
 )
 
 const (
@@ -39,163 +16,10 @@
 	MachoRelocOffset = 2048 // reserve enough space for ELF relocations
 )
 
-func goarm() int {
-	def := defaultGOARM
-	if GOOS == "android" && GOARCH == "arm" {
-		// Android arm devices always support GOARM=7.
-		def = "7"
-	}
-	switch v := envOr("GOARM", def); v {
-	case "5":
-		return 5
-	case "6":
-		return 6
-	case "7":
-		return 7
-	}
-	// Fail here, rather than validate at multiple call sites.
-	log.Fatalf("Invalid GOARM value. Must be 5, 6, or 7.")
-	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 gomips64() string {
-	switch v := envOr("GOMIPS64", defaultGOMIPS64); v {
-	case "hardfloat", "softfloat":
-		return v
-	}
-	log.Fatalf("Invalid GOMIPS64 value. Must be hardfloat or softfloat.")
-	panic("unreachable")
-}
-
-func goppc64() int {
-	switch v := envOr("GOPPC64", defaultGOPPC64); v {
-	case "power8":
-		return 8
-	case "power9":
-		return 9
-	}
-	log.Fatalf("Invalid GOPPC64 value. Must be power8 or power9.")
-	panic("unreachable")
-}
-
-type gowasmFeatures struct {
-	SignExt bool
-	SatConv bool
-}
-
-func (f gowasmFeatures) String() string {
-	var flags []string
-	if f.SatConv {
-		flags = append(flags, "satconv")
-	}
-	if f.SignExt {
-		flags = append(flags, "signext")
-	}
-	return strings.Join(flags, ",")
-}
-
-func gowasm() (f gowasmFeatures) {
-	for _, opt := range strings.Split(envOr("GOWASM", ""), ",") {
-		switch opt {
-		case "satconv":
-			f.SatConv = true
-		case "signext":
-			f.SignExt = true
-		case "":
-			// ignore
-		default:
-			log.Fatalf("Invalid GOWASM value. No such feature: " + opt)
-		}
-	}
-	return
-}
-
-func Getgoextlinkenabled() string {
-	return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
-}
-
-func init() {
-	for _, f := range strings.Split(goexperiment, ",") {
-		if f != "" {
-			addexp(f)
-		}
-	}
-
-	// regabi is only supported on amd64.
-	if GOARCH != "amd64" {
-		Regabi_enabled = 0
-	}
-}
-
-// Note: must agree with runtime.framepointer_enabled.
-var Framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64" && (GOOS == "linux" || GOOS == "darwin" || GOOS == "ios")
-
-func addexp(s string) {
-	// Could do general integer parsing here, but the runtime copy doesn't yet.
-	v := 1
-	name := s
-	if len(name) > 2 && name[:2] == "no" {
-		v = 0
-		name = name[2:]
-	}
-	for i := 0; i < len(exper); i++ {
-		if exper[i].name == name {
-			if exper[i].val != nil {
-				*exper[i].val = v
-			}
-			return
-		}
-	}
-
-	fmt.Printf("unknown experiment %s\n", s)
-	os.Exit(2)
-}
-
-var (
-	Fieldtrack_enabled        int
-	Preemptibleloops_enabled  int
-	Staticlockranking_enabled int
-	Regabi_enabled            int
-)
-
-// Toolchain experiments.
-// These are controlled by the GOEXPERIMENT environment
-// variable recorded when the toolchain is built.
-// This list is also known to cmd/gc.
-var exper = []struct {
-	name string
-	val  *int
-}{
-	{"fieldtrack", &Fieldtrack_enabled},
-	{"preemptibleloops", &Preemptibleloops_enabled},
-	{"staticlockranking", &Staticlockranking_enabled},
-	{"regabi", &Regabi_enabled},
-}
-
-var defaultExpstring = Expstring()
-
-func DefaultExpstring() string {
-	return defaultExpstring
-}
-
-func Expstring() string {
-	buf := "X"
-	for i := range exper {
-		if *exper[i].val != 0 {
-			buf += "," + exper[i].name
-		}
-	}
-	if buf == "X" {
-		buf += ",none"
-	}
-	return "X:" + buf[2:]
+// HeaderString returns the toolchain configuration string written in
+// Go object headers. This string ensures we don't attempt to import
+// or link object files that are incompatible with each other. This
+// string always starts with "go object ".
+func HeaderString() string {
+	return fmt.Sprintf("go object %s %s %s X:%s\n", buildcfg.GOOS, buildcfg.GOARCH, buildcfg.Version, strings.Join(buildcfg.EnabledExperiments(), ","))
 }
diff --git a/src/cmd/internal/objabi/zbootstrap.go b/src/cmd/internal/objabi/zbootstrap.go
index 3c67a6e..512fb0f 100644
--- a/src/cmd/internal/objabi/zbootstrap.go
+++ b/src/cmd/internal/objabi/zbootstrap.go
@@ -2,17 +2,4 @@
 
 package objabi
 
-import "runtime"
-
-const defaultGO386 = `sse2`
-const defaultGOARM = `5`
-const defaultGOMIPS = `hardfloat`
-const defaultGOMIPS64 = `hardfloat`
-const defaultGOPPC64 = `power8`
-const defaultGOOS = runtime.GOOS
-const defaultGOARCH = runtime.GOARCH
-const defaultGO_EXTLINK_ENABLED = ``
-const defaultGO_LDSO = ``
-const version = `go1.16.3`
 const stackGuardMultiplierDefault = 1
-const goexperiment = ``
diff --git a/src/cmd/internal/objfile/goobj.go b/src/cmd/internal/objfile/goobj.go
index f19bec5..dd21d22 100644
--- a/src/cmd/internal/objfile/goobj.go
+++ b/src/cmd/internal/objfile/goobj.go
@@ -168,7 +168,7 @@
 			code = 'T'
 		case objabi.SRODATA:
 			code = 'R'
-		case objabi.SDATA:
+		case objabi.SNOPTRDATA, objabi.SDATA:
 			code = 'D'
 		case objabi.SBSS, objabi.SNOPTRBSS, objabi.STLSBSS:
 			code = 'B'
diff --git a/src/cmd/internal/objfile/objfile.go b/src/cmd/internal/objfile/objfile.go
index a58e0e1..dcfd158 100644
--- a/src/cmd/internal/objfile/objfile.go
+++ b/src/cmd/internal/objfile/objfile.go
@@ -6,6 +6,7 @@
 package objfile
 
 import (
+	"cmd/internal/archive"
 	"debug/dwarf"
 	"debug/gosym"
 	"fmt"
@@ -73,6 +74,8 @@
 	}
 	if f, err := openGoFile(r); err == nil {
 		return f, nil
+	} else if _, ok := err.(archive.ErrGoObjOtherVersion); ok {
+		return nil, fmt.Errorf("open %s: %v", name, err)
 	}
 	for _, try := range openers {
 		if raw, err := try(r); err == nil {
diff --git a/src/cmd/internal/objfile/pe.go b/src/cmd/internal/objfile/pe.go
index b20cda9..9088866 100644
--- a/src/cmd/internal/objfile/pe.go
+++ b/src/cmd/internal/objfile/pe.go
@@ -189,6 +189,8 @@
 		return "amd64"
 	case pe.IMAGE_FILE_MACHINE_ARMNT:
 		return "arm"
+	case pe.IMAGE_FILE_MACHINE_ARM64:
+		return "arm64"
 	default:
 		return ""
 	}
diff --git a/src/cmd/internal/sys/arch.go b/src/cmd/internal/sys/arch.go
index e868736..a3e3976 100644
--- a/src/cmd/internal/sys/arch.go
+++ b/src/cmd/internal/sys/arch.go
@@ -40,6 +40,12 @@
 
 	// MinLC is the minimum length of an instruction code.
 	MinLC int
+
+	// Alignment is maximum alignment required by the architecture
+	// for any (compiler-generated) load or store instruction.
+	// Loads or stores smaller than Alignment must be naturally aligned.
+	// Loads or stores larger than Alignment need only be Alignment-aligned.
+	Alignment int8
 }
 
 // InFamily reports whether a is a member of any of the specified
@@ -60,6 +66,7 @@
 	PtrSize:   4,
 	RegSize:   4,
 	MinLC:     1,
+	Alignment: 1,
 }
 
 var ArchAMD64 = &Arch{
@@ -69,6 +76,7 @@
 	PtrSize:   8,
 	RegSize:   8,
 	MinLC:     1,
+	Alignment: 1,
 }
 
 var ArchARM = &Arch{
@@ -78,6 +86,7 @@
 	PtrSize:   4,
 	RegSize:   4,
 	MinLC:     4,
+	Alignment: 4, // TODO: just for arm5?
 }
 
 var ArchARM64 = &Arch{
@@ -87,6 +96,7 @@
 	PtrSize:   8,
 	RegSize:   8,
 	MinLC:     4,
+	Alignment: 1,
 }
 
 var ArchMIPS = &Arch{
@@ -96,6 +106,7 @@
 	PtrSize:   4,
 	RegSize:   4,
 	MinLC:     4,
+	Alignment: 4,
 }
 
 var ArchMIPSLE = &Arch{
@@ -105,6 +116,7 @@
 	PtrSize:   4,
 	RegSize:   4,
 	MinLC:     4,
+	Alignment: 4,
 }
 
 var ArchMIPS64 = &Arch{
@@ -114,6 +126,7 @@
 	PtrSize:   8,
 	RegSize:   8,
 	MinLC:     4,
+	Alignment: 8,
 }
 
 var ArchMIPS64LE = &Arch{
@@ -123,6 +136,7 @@
 	PtrSize:   8,
 	RegSize:   8,
 	MinLC:     4,
+	Alignment: 8,
 }
 
 var ArchPPC64 = &Arch{
@@ -132,6 +146,7 @@
 	PtrSize:   8,
 	RegSize:   8,
 	MinLC:     4,
+	Alignment: 1,
 }
 
 var ArchPPC64LE = &Arch{
@@ -141,6 +156,7 @@
 	PtrSize:   8,
 	RegSize:   8,
 	MinLC:     4,
+	Alignment: 1,
 }
 
 var ArchRISCV64 = &Arch{
@@ -150,6 +166,7 @@
 	PtrSize:   8,
 	RegSize:   8,
 	MinLC:     4,
+	Alignment: 8, // riscv unaligned loads work, but are really slow (trap + simulated by OS)
 }
 
 var ArchS390X = &Arch{
@@ -159,6 +176,7 @@
 	PtrSize:   8,
 	RegSize:   8,
 	MinLC:     2,
+	Alignment: 1,
 }
 
 var ArchWasm = &Arch{
@@ -168,6 +186,7 @@
 	PtrSize:   8,
 	RegSize:   8,
 	MinLC:     1,
+	Alignment: 1,
 }
 
 var Archs = [...]*Arch{
diff --git a/src/cmd/internal/sys/supported.go b/src/cmd/internal/sys/supported.go
index ef7c017..0d2bad9 100644
--- a/src/cmd/internal/sys/supported.go
+++ b/src/cmd/internal/sys/supported.go
@@ -15,7 +15,7 @@
 		return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64"
 	case "darwin":
 		return goarch == "amd64" || goarch == "arm64"
-	case "freebsd", "netbsd", "windows":
+	case "freebsd", "netbsd", "openbsd", "windows":
 		return goarch == "amd64"
 	default:
 		return false
@@ -23,7 +23,8 @@
 }
 
 // MSanSupported reports whether goos/goarch supports the memory
-// sanitizer option. There is a copy of this function in cmd/dist/test.go.
+// sanitizer option.
+// There is a copy of this function in misc/cgo/testsanitizers/cc_test.go.
 func MSanSupported(goos, goarch string) bool {
 	switch goos {
 	case "linux":
@@ -73,7 +74,7 @@
 			"android/amd64", "android/arm", "android/arm64", "android/386",
 			"freebsd/amd64",
 			"darwin/amd64", "darwin/arm64",
-			"windows/amd64", "windows/386":
+			"windows/amd64", "windows/386", "windows/arm64":
 			return true
 		}
 		return false
diff --git a/src/cmd/link/cgo_test.go b/src/cmd/link/cgo_test.go
new file mode 100644
index 0000000..26ab802
--- /dev/null
+++ b/src/cmd/link/cgo_test.go
@@ -0,0 +1,141 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"internal/testenv"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"testing"
+)
+
+// Issues 43830, 46295
+func TestCGOLTO(t *testing.T) {
+	testenv.MustHaveCGO(t)
+	testenv.MustHaveGoBuild(t)
+
+	t.Parallel()
+
+	for _, cc := range []string{"gcc", "clang"} {
+		for test := 0; test < 2; test++ {
+			t.Run(fmt.Sprintf("%s-%d", cc, test), func(t *testing.T) {
+				testCGOLTO(t, cc, test)
+			})
+		}
+	}
+}
+
+const test1_main = `
+package main
+
+/*
+extern int myadd(int, int);
+int c_add(int a, int b) {
+	return myadd(a, b);
+}
+*/
+import "C"
+
+func main() {
+	println(C.c_add(1, 2))
+}
+`
+
+const test1_add = `
+package main
+
+import "C"
+
+/* test */
+
+//export myadd
+func myadd(a C.int, b C.int) C.int {
+	return a + b
+}
+`
+
+const test2_main = `
+package main
+
+import "fmt"
+
+/*
+#include <stdio.h>
+
+void hello(void) {
+  printf("hello\n");
+}
+*/
+import "C"
+
+func main() {
+	hello := C.hello
+	fmt.Printf("%v\n", hello)
+}
+`
+
+func testCGOLTO(t *testing.T, cc string, test int) {
+	t.Parallel()
+
+	if _, err := exec.LookPath(cc); err != nil {
+		t.Skipf("no %s compiler", cc)
+	}
+
+	dir := t.TempDir()
+
+	writeTempFile := func(name, contents string) {
+		if err := os.WriteFile(filepath.Join(dir, name), []byte(contents), 0644); err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	writeTempFile("go.mod", "module cgolto\n")
+
+	switch test {
+	case 0:
+		writeTempFile("main.go", test1_main)
+		writeTempFile("add.go", test1_add)
+	case 1:
+		writeTempFile("main.go", test2_main)
+	default:
+		t.Fatalf("bad case %d", test)
+	}
+
+	cmd := exec.Command(testenv.GoToolPath(t), "build")
+	cmd.Dir = dir
+	cmd.Env = append(os.Environ(),
+		"CC="+cc,
+		"CGO_CFLAGS=-flto",
+	)
+
+	t.Log("go build")
+	out, err := cmd.CombinedOutput()
+	t.Logf("%s", out)
+
+	if err != nil {
+		t.Logf("go build failed: %v", err)
+
+		// Error messages we've seen indicating that LTO is not supported.
+		// These errors come from GCC or clang, not Go.
+		var noLTO = []string{
+			`unrecognized command line option "-flto"`,
+			"unable to pass LLVM bit-code files to linker",
+			"file not recognized: File format not recognized",
+			"LTO support has not been enabled",
+			"linker command failed with exit code",
+			"gcc: can't load library",
+		}
+		for _, msg := range noLTO {
+			if bytes.Contains(out, []byte(msg)) {
+				t.Skipf("C compiler %v does not support LTO", cc)
+			}
+		}
+
+		t.Error("failed")
+	}
+}
diff --git a/src/cmd/link/dwarf_test.go b/src/cmd/link/dwarf_test.go
index db710be..3ca59bd 100644
--- a/src/cmd/link/dwarf_test.go
+++ b/src/cmd/link/dwarf_test.go
@@ -10,7 +10,6 @@
 	"cmd/internal/objfile"
 	"debug/dwarf"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path"
@@ -20,6 +19,36 @@
 	"testing"
 )
 
+// TestMain allows this test binary to run as a -toolexec wrapper for the 'go'
+// command. If LINK_TEST_TOOLEXEC is set, TestMain runs the binary as if it were
+// cmd/link, and otherwise runs the requested tool as a subprocess.
+//
+// This allows the test to verify the behavior of the current contents of the
+// cmd/link package even if the installed cmd/link binary is stale.
+func TestMain(m *testing.M) {
+	if os.Getenv("LINK_TEST_TOOLEXEC") == "" {
+		// Not running as a -toolexec wrapper. Just run the tests.
+		os.Exit(m.Run())
+	}
+
+	if strings.TrimSuffix(filepath.Base(os.Args[1]), ".exe") == "link" {
+		// Running as a -toolexec linker, and the tool is cmd/link.
+		// Substitute this test binary for the linker.
+		os.Args = os.Args[1:]
+		main()
+		os.Exit(0)
+	}
+
+	cmd := exec.Command(os.Args[1], os.Args[2:]...)
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	if err := cmd.Run(); err != nil {
+		os.Exit(1)
+	}
+	os.Exit(0)
+}
+
 func testDWARF(t *testing.T, buildmode string, expectDWARF bool, env ...string) {
 	testenv.MustHaveCGO(t)
 	testenv.MustHaveGoBuild(t)
@@ -30,17 +59,6 @@
 
 	t.Parallel()
 
-	out, err := exec.Command(testenv.GoToolPath(t), "list", "-f", "{{.Stale}}", "cmd/link").CombinedOutput()
-	if err != nil {
-		t.Fatalf("go list: %v\n%s", err, out)
-	}
-	if string(out) != "false\n" {
-		if strings.HasPrefix(testenv.Builder(), "darwin-") {
-			t.Skipf("cmd/link is spuriously stale on Darwin builders - see #33598")
-		}
-		t.Fatalf("cmd/link is stale - run go install cmd/link")
-	}
-
 	for _, prog := range []string{"testprog", "testprogcgo"} {
 		prog := prog
 		expectDWARF := expectDWARF
@@ -49,33 +67,28 @@
 			if extld == "" {
 				extld = "gcc"
 			}
+			var err error
 			expectDWARF, err = cmddwarf.IsDWARFEnabledOnAIXLd(extld)
 			if err != nil {
 				t.Fatal(err)
 			}
-
 		}
 
 		t.Run(prog, func(t *testing.T) {
 			t.Parallel()
 
-			tmpDir, err := ioutil.TempDir("", "go-link-TestDWARF")
-			if err != nil {
-				t.Fatal(err)
-			}
-			defer os.RemoveAll(tmpDir)
+			tmpDir := t.TempDir()
 
 			exe := filepath.Join(tmpDir, prog+".exe")
 			dir := "../../runtime/testdata/" + prog
-			cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe)
+			cmd := exec.Command(testenv.GoToolPath(t), "build", "-toolexec", os.Args[0], "-o", exe)
 			if buildmode != "" {
 				cmd.Args = append(cmd.Args, "-buildmode", buildmode)
 			}
 			cmd.Args = append(cmd.Args, dir)
-			if env != nil {
-				cmd.Env = append(os.Environ(), env...)
-				cmd.Env = append(cmd.Env, "CGO_CFLAGS=") // ensure CGO_CFLAGS does not contain any flags. Issue #35459
-			}
+			cmd.Env = append(os.Environ(), env...)
+			cmd.Env = append(cmd.Env, "CGO_CFLAGS=") // ensure CGO_CFLAGS does not contain any flags. Issue #35459
+			cmd.Env = append(cmd.Env, "LINK_TEST_TOOLEXEC=1")
 			out, err := cmd.CombinedOutput()
 			if err != nil {
 				t.Fatalf("go build -o %v %v: %v\n%s", exe, dir, err, out)
@@ -91,7 +104,8 @@
 				exe = filepath.Join(tmpDir, "go.o")
 			}
 
-			if runtime.GOOS == "darwin" {
+			darwinSymbolTestIsTooFlaky := true // Turn this off, it is too flaky -- See #32218
+			if runtime.GOOS == "darwin" && !darwinSymbolTestIsTooFlaky {
 				if _, err = exec.LookPath("symbols"); err == nil {
 					// Ensure Apple's tooling can parse our object for symbols.
 					out, err = exec.Command("symbols", exe).CombinedOutput()
diff --git a/src/cmd/link/elf_test.go b/src/cmd/link/elf_test.go
index 20754d0..012c0b5 100644
--- a/src/cmd/link/elf_test.go
+++ b/src/cmd/link/elf_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || linux || netbsd || openbsd
 // +build dragonfly freebsd linux netbsd openbsd
 
 package main
@@ -69,11 +70,7 @@
 		t.Skipf("can't find objcopy: %v", err)
 	}
 
-	dir, err := ioutil.TempDir("", "go-link-TestSectionsWithSameName")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	gopath := filepath.Join(dir, "GOPATH")
 	env := append(os.Environ(), "GOPATH="+gopath)
@@ -143,11 +140,7 @@
 	testenv.MustHaveCGO(t)
 	t.Parallel()
 
-	dir, err := ioutil.TempDir("", "go-link-TestMinusRSymsWithSameName")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	gopath := filepath.Join(dir, "GOPATH")
 	env := append(os.Environ(), "GOPATH="+gopath)
@@ -270,11 +263,7 @@
 		t.Run(name, func(t *testing.T) {
 			t.Parallel()
 
-			dir, err := ioutil.TempDir("", "go-link-"+name)
-			if err != nil {
-				t.Fatal(err)
-			}
-			defer os.RemoveAll(dir)
+			dir := t.TempDir()
 
 			writeGo(t, dir)
 
diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go
index 2d09a61..fb96049 100644
--- a/src/cmd/link/internal/amd64/asm.go
+++ b/src/cmd/link/internal/amd64/asm.go
@@ -548,7 +548,7 @@
 	return -1, 0, false
 }
 
-func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64, []byte) int64 {
 	log.Fatalf("unexpected relocation variant")
 	return -1
 }
diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go
index 03caeae..ab78021 100644
--- a/src/cmd/link/internal/arm/asm.go
+++ b/src/cmd/link/internal/arm/asm.go
@@ -111,7 +111,7 @@
 			return false
 		}
 
-		// Handle relocations found in ELF object files.
+	// Handle relocations found in ELF object files.
 	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PLT32):
 		su := ldr.MakeSymbolUpdater(s)
 		su.SetRelocType(rIdx, objabi.R_CALLARM)
@@ -237,6 +237,21 @@
 			su.SetRelocSym(rIdx, 0)
 			return true
 		}
+
+	case objabi.R_GOTPCREL:
+		if target.IsExternal() {
+			// External linker will do this relocation.
+			return true
+		}
+		if targType != sym.SDYNIMPORT {
+			ldr.Errorf(s, "R_GOTPCREL target is not SDYNIMPORT symbol: %v", ldr.SymName(targ))
+		}
+		ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_ARM_GLOB_DAT))
+		su := ldr.MakeSymbolUpdater(s)
+		su.SetRelocType(rIdx, objabi.R_PCREL)
+		su.SetRelocSym(rIdx, syms.GOT)
+		su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
+		return true
 	}
 
 	return false
@@ -369,6 +384,12 @@
 	relocs := ldr.Relocs(s)
 	r := relocs.At(ri)
 	switch r.Type() {
+	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL),
+		objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PC24),
+		objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24):
+		// Host object relocations that will be turned into a PLT call.
+		// The PLT may be too far. Insert a trampoline for them.
+		fallthrough
 	case objabi.R_CALLARM:
 		var t int64
 		// ldr.SymValue(rs) == 0 indicates a cross-package jump to a function that is not yet
@@ -415,7 +436,7 @@
 				// trampoline does not exist, create one
 				trampb := ldr.MakeSymbolUpdater(tramp)
 				ctxt.AddTramp(trampb)
-				if ctxt.DynlinkingGo() {
+				if ctxt.DynlinkingGo() || ldr.SymType(rs) == sym.SDYNIMPORT {
 					if immrot(uint32(offset)) == 0 {
 						ctxt.Errorf(s, "odd offset in dynlink direct call: %v+%d", ldr.SymName(rs), offset)
 					}
@@ -443,8 +464,8 @@
 	tramp.SetSize(12) // 3 instructions
 	P := make([]byte, tramp.Size())
 	t := ldr.SymValue(target) + offset
-	o1 := uint32(0xe5900000 | 11<<12 | 15<<16) // MOVW (R15), R11 // R15 is actual pc + 8
-	o2 := uint32(0xe12fff10 | 11)              // JMP  (R11)
+	o1 := uint32(0xe5900000 | 12<<12 | 15<<16) // MOVW (R15), R12 // R15 is actual pc + 8
+	o2 := uint32(0xe12fff10 | 12)              // JMP  (R12)
 	o3 := uint32(t)                            // WORD $target
 	arch.ByteOrder.PutUint32(P, o1)
 	arch.ByteOrder.PutUint32(P[4:], o2)
@@ -464,9 +485,9 @@
 func gentramppic(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
 	tramp.SetSize(16) // 4 instructions
 	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)
+	o1 := uint32(0xe5900000 | 12<<12 | 15<<16 | 4)  // MOVW 4(R15), R12 // R15 is actual pc + 8
+	o2 := uint32(0xe0800000 | 12<<12 | 15<<16 | 12) // ADD R15, R12, R12
+	o3 := uint32(0xe12fff10 | 12)                   // JMP  (R12)
 	o4 := uint32(0)                                 // WORD $(target-pc) // filled in with relocation
 	arch.ByteOrder.PutUint32(P, o1)
 	arch.ByteOrder.PutUint32(P[4:], o2)
@@ -484,10 +505,10 @@
 // generate a trampoline to target+offset in dynlink mode (using GOT)
 func gentrampdyn(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
 	tramp.SetSize(20)                               // 5 instructions
-	o1 := uint32(0xe5900000 | 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
-	o3 := uint32(0xe5900000 | 11<<12 | 11<<16)      // MOVW (R11), R11
-	o4 := uint32(0xe12fff10 | 11)                   // JMP  (R11)
+	o1 := uint32(0xe5900000 | 12<<12 | 15<<16 | 8)  // MOVW 8(R15), R12 // R15 is actual pc + 8
+	o2 := uint32(0xe0800000 | 12<<12 | 15<<16 | 12) // ADD R15, R12, R12
+	o3 := uint32(0xe5900000 | 12<<12 | 12<<16)      // MOVW (R12), R12
+	o4 := uint32(0xe12fff10 | 12)                   // JMP  (R12)
 	o5 := uint32(0)                                 // WORD $target@GOT // filled in with relocation
 	o6 := uint32(0)
 	if offset != 0 {
@@ -495,8 +516,8 @@
 		tramp.SetSize(24) // 6 instructions
 		o6 = o5
 		o5 = o4
-		o4 = 0xe2800000 | 11<<12 | 11<<16 | immrot(uint32(offset)) // ADD $offset, R11, R11
-		o1 = uint32(0xe5900000 | 11<<12 | 15<<16 | 12)             // MOVW 12(R15), R11
+		o4 = 0xe2800000 | 12<<12 | 12<<16 | immrot(uint32(offset)) // ADD $offset, R12, R12
+		o1 = uint32(0xe5900000 | 12<<12 | 15<<16 | 12)             // MOVW 12(R15), R12
 	}
 	P := make([]byte, tramp.Size())
 	arch.ByteOrder.PutUint32(P, o1)
@@ -565,7 +586,7 @@
 	return val, 0, false
 }
 
-func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64, []byte) int64 {
 	log.Fatalf("unexpected relocation variant")
 	return -1
 }
diff --git a/src/cmd/link/internal/arm/obj.go b/src/cmd/link/internal/arm/obj.go
index fed8dce..b7d1498 100644
--- a/src/cmd/link/internal/arm/obj.go
+++ b/src/cmd/link/internal/arm/obj.go
@@ -45,6 +45,7 @@
 		Minalign:   minAlign,
 		Dwarfregsp: dwarfRegSP,
 		Dwarfreglr: dwarfRegLR,
+		TrampLimit: 0x1c00000, // 24-bit signed offset * 4, leave room for PLT etc.
 
 		Plan9Magic: 0x647,
 
diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go
index 14a20a1..c10bdc4 100644
--- a/src/cmd/link/internal/arm64/asm.go
+++ b/src/cmd/link/internal/arm64/asm.go
@@ -413,6 +413,35 @@
 			// (e.g. go version).
 			return true
 		}
+
+	case objabi.R_ARM64_GOTPCREL:
+		if target.IsExternal() {
+			// External linker will do this relocation.
+			return true
+		}
+		if targType != sym.SDYNIMPORT {
+			ldr.Errorf(s, "R_ARM64_GOTPCREL target is not SDYNIMPORT symbol: %v", ldr.SymName(targ))
+		}
+		if r.Add() != 0 {
+			ldr.Errorf(s, "R_ARM64_GOTPCREL with non-zero addend (%v)", r.Add())
+		}
+		if target.IsElf() {
+			ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_AARCH64_GLOB_DAT))
+		} else {
+			ld.AddGotSym(target, ldr, syms, targ, 0)
+		}
+		// turn into two relocations, one for each instruction.
+		su := ldr.MakeSymbolUpdater(s)
+		r.SetType(objabi.R_ARM64_GOT)
+		r.SetSiz(4)
+		r.SetSym(syms.GOT)
+		r.SetAdd(int64(ldr.SymGot(targ)))
+		r2, _ := su.AddRel(objabi.R_ARM64_GOT)
+		r2.SetSiz(4)
+		r2.SetOff(r.Off() + 4)
+		r2.SetSym(syms.GOT)
+		r2.SetAdd(int64(ldr.SymGot(targ)))
+		return true
 	}
 	return false
 }
@@ -464,8 +493,9 @@
 	return true
 }
 
-// sign-extends from 24-bit.
-func signext24(x int64) int64 { return x << 40 >> 40 }
+// sign-extends from 21, 24-bit.
+func signext21(x int64) int64 { return x << (64 - 21) >> (64 - 21) }
+func signext24(x int64) int64 { return x << (64 - 24) >> (64 - 24) }
 
 func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, sectoff int64) bool {
 	var v uint32
@@ -478,7 +508,7 @@
 	if xadd != signext24(xadd) {
 		// If the relocation target would overflow the addend, then target
 		// a linker-manufactured label symbol with a smaller addend instead.
-		label := ldr.Lookup(machoLabelName(ldr, rs, xadd), ldr.SymVersion(rs))
+		label := ldr.Lookup(offsetLabelName(ldr, rs, xadd/machoRelocLimit*machoRelocLimit), ldr.SymVersion(rs))
 		if label != 0 {
 			xadd = ldr.SymValue(rs) + xadd - ldr.SymValue(label)
 			rs = label
@@ -568,6 +598,72 @@
 	return true
 }
 
+func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, sectoff int64) bool {
+	rs := r.Xsym
+	rt := r.Type
+
+	if r.Xadd != signext21(r.Xadd) {
+		// If the relocation target would overflow the addend, then target
+		// a linker-manufactured label symbol with a smaller addend instead.
+		label := ldr.Lookup(offsetLabelName(ldr, rs, r.Xadd/peRelocLimit*peRelocLimit), ldr.SymVersion(rs))
+		if label == 0 {
+			ldr.Errorf(s, "invalid relocation: %v %s+0x%x", rt, ldr.SymName(rs), r.Xadd)
+			return false
+		}
+		rs = label
+	}
+	if rt == objabi.R_CALLARM64 && r.Xadd != 0 {
+		label := ldr.Lookup(offsetLabelName(ldr, rs, r.Xadd), ldr.SymVersion(rs))
+		if label == 0 {
+			ldr.Errorf(s, "invalid relocation: %v %s+0x%x", rt, ldr.SymName(rs), r.Xadd)
+			return false
+		}
+		rs = label
+	}
+	symdynid := ldr.SymDynid(rs)
+	if symdynid < 0 {
+		ldr.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
+		return false
+	}
+
+	switch rt {
+	default:
+		return false
+
+	case objabi.R_DWARFSECREF:
+		out.Write32(uint32(sectoff))
+		out.Write32(uint32(symdynid))
+		out.Write16(ld.IMAGE_REL_ARM64_SECREL)
+
+	case objabi.R_ADDR:
+		out.Write32(uint32(sectoff))
+		out.Write32(uint32(symdynid))
+		if r.Size == 8 {
+			out.Write16(ld.IMAGE_REL_ARM64_ADDR64)
+		} else {
+			out.Write16(ld.IMAGE_REL_ARM64_ADDR32)
+		}
+
+	case objabi.R_ADDRARM64:
+		// Note: r.Xadd has been taken care of below, in archreloc.
+		out.Write32(uint32(sectoff))
+		out.Write32(uint32(symdynid))
+		out.Write16(ld.IMAGE_REL_ARM64_PAGEBASE_REL21)
+
+		out.Write32(uint32(sectoff + 4))
+		out.Write32(uint32(symdynid))
+		out.Write16(ld.IMAGE_REL_ARM64_PAGEOFFSET_12A)
+
+	case objabi.R_CALLARM64:
+		// Note: r.Xadd has been taken care of above, by using a label pointing into the middle of the function.
+		out.Write32(uint32(sectoff))
+		out.Write32(uint32(symdynid))
+		out.Write16(ld.IMAGE_REL_ARM64_BRANCH26)
+	}
+
+	return true
+}
+
 func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc, s loader.Sym, val int64) (int64, int, bool) {
 	const noExtReloc = 0
 	const isOk = true
@@ -594,14 +690,8 @@
 				nExtReloc = 4 // need another two relocations for non-zero addend
 			}
 
-			// Note: ld64 currently has a bug that any non-zero addend for BR26 relocation
-			// will make the linking fail because it thinks the code is not PIC even though
-			// the BR26 relocation should be fully resolved at link time.
-			// That is the reason why the next if block is disabled. When the bug in ld64
-			// is fixed, we can enable this block and also enable duff's device in cmd/7g.
-			if false && target.IsDarwin() {
+			if target.IsWindows() {
 				var o0, o1 uint32
-
 				if target.IsBigEndian() {
 					o0 = uint32(val >> 32)
 					o1 = uint32(val)
@@ -609,15 +699,20 @@
 					o0 = uint32(val)
 					o1 = uint32(val >> 32)
 				}
-				// Mach-O wants the addend to be encoded in the instruction
-				// Note that although Mach-O supports ARM64_RELOC_ADDEND, it
-				// can only encode 24-bit of signed addend, but the instructions
-				// supports 33-bit of signed addend, so we always encode the
-				// addend in place.
-				o0 |= (uint32((xadd>>12)&3) << 29) | (uint32((xadd>>12>>2)&0x7ffff) << 5)
-				o1 |= uint32(xadd&0xfff) << 10
 
-				// when laid out, the instruction order must always be o1, o2.
+				// The first instruction (ADRP) has a 21-bit immediate field,
+				// and the second (ADD) has a 12-bit immediate field.
+				// The first instruction is only for high bits, but to get the carry bits right we have
+				// to put the full addend, including the bottom 12 bits again.
+				// That limits the distance of any addend to only 21 bits.
+				// But we assume that LDRP's top bit will be interpreted as a sign bit,
+				// so we only use 20 bits.
+				// pereloc takes care of introducing new symbol labels
+				// every megabyte for longer relocations.
+				xadd := uint32(xadd)
+				o0 |= (xadd&3)<<29 | (xadd&0xffffc)<<3
+				o1 |= (xadd & 0xfff) << 10
+
 				if target.IsBigEndian() {
 					val = int64(o0)<<32 | int64(o1)
 				} else {
@@ -634,6 +729,18 @@
 				nExtReloc = 2 // need two ELF relocations. see elfreloc1
 			}
 			return val, nExtReloc, isOk
+
+		case objabi.R_ADDR:
+			if target.IsWindows() && r.Add() != 0 {
+				if r.Siz() == 8 {
+					val = r.Add()
+				} else if target.IsBigEndian() {
+					val = int64(uint32(val)) | int64(r.Add())<<32
+				} else {
+					val = val>>32<<32 | int64(uint32(r.Add()))
+				}
+				return val, 1, true
+			}
 		}
 	}
 
@@ -831,7 +938,7 @@
 	return val, 0, false
 }
 
-func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64, []byte) int64 {
 	log.Fatalf("unexpected relocation variant")
 	return -1
 }
@@ -984,37 +1091,54 @@
 	}
 }
 
-const machoRelocLimit = 1 << 23
+const (
+	machoRelocLimit = 1 << 23
+	peRelocLimit    = 1 << 20
+)
 
 func gensymlate(ctxt *ld.Link, ldr *loader.Loader) {
 	// When external linking on darwin, Mach-O relocation has only signed 24-bit
 	// addend. For large symbols, we generate "label" symbols in the middle, so
 	// that relocations can target them with smaller addends.
-	if !ctxt.IsDarwin() || !ctxt.IsExternal() {
+	// On Windows, we only get 21 bits, again (presumably) signed.
+	if !ctxt.IsDarwin() && !ctxt.IsWindows() || !ctxt.IsExternal() {
 		return
 	}
 
-	big := false
-	for _, seg := range ld.Segments {
-		if seg.Length >= machoRelocLimit {
-			big = true
-			break
-		}
-	}
-	if !big {
-		return // skip work if nothing big
+	limit := int64(machoRelocLimit)
+	if ctxt.IsWindows() {
+		limit = peRelocLimit
 	}
 
-	// addLabelSyms adds "label" symbols at s+machoRelocLimit, s+2*machoRelocLimit, etc.
-	addLabelSyms := func(s loader.Sym, sz int64) {
+	if ctxt.IsDarwin() {
+		big := false
+		for _, seg := range ld.Segments {
+			if seg.Length >= machoRelocLimit {
+				big = true
+				break
+			}
+		}
+		if !big {
+			return // skip work if nothing big
+		}
+	}
+
+	// addLabelSyms adds "label" symbols at s+limit, s+2*limit, etc.
+	addLabelSyms := func(s loader.Sym, limit, sz int64) {
 		v := ldr.SymValue(s)
-		for off := int64(machoRelocLimit); off < sz; off += machoRelocLimit {
-			p := ldr.LookupOrCreateSym(machoLabelName(ldr, s, off), ldr.SymVersion(s))
+		for off := limit; off < sz; off += limit {
+			p := ldr.LookupOrCreateSym(offsetLabelName(ldr, s, off), ldr.SymVersion(s))
 			ldr.SetAttrReachable(p, true)
 			ldr.SetSymValue(p, v+off)
 			ldr.SetSymSect(p, ldr.SymSect(s))
-			ld.AddMachoSym(ldr, p)
-			//fmt.Printf("gensymlate %s %x\n", ldr.SymName(p), ldr.SymValue(p))
+			if ctxt.IsDarwin() {
+				ld.AddMachoSym(ldr, p)
+			} else if ctxt.IsWindows() {
+				ld.AddPELabelSym(ldr, p)
+			} else {
+				panic("missing case in gensymlate")
+			}
+			// fmt.Printf("gensymlate %s %x\n", ldr.SymName(p), ldr.SymValue(p))
 		}
 	}
 
@@ -1023,26 +1147,150 @@
 			continue
 		}
 		if ldr.SymType(s) == sym.STEXT {
-			continue // we don't target the middle of a function
+			if ctxt.IsDarwin() || ctxt.IsWindows() {
+				// Cannot relocate into middle of function.
+				// Generate symbol names for every offset we need in duffcopy/duffzero (only 64 each).
+				switch ldr.SymName(s) {
+				case "runtime.duffcopy":
+					addLabelSyms(s, 8, 8*64)
+				case "runtime.duffzero":
+					addLabelSyms(s, 4, 4*64)
+				}
+			}
+			continue // we don't target the middle of other functions
 		}
 		sz := ldr.SymSize(s)
-		if sz <= machoRelocLimit {
+		if sz <= limit {
 			continue
 		}
-		addLabelSyms(s, sz)
+		addLabelSyms(s, limit, sz)
 	}
 
 	// Also for carrier symbols (for which SymSize is 0)
 	for _, ss := range ld.CarrierSymByType {
-		if ss.Sym != 0 && ss.Size > machoRelocLimit {
-			addLabelSyms(ss.Sym, ss.Size)
+		if ss.Sym != 0 && ss.Size > limit {
+			addLabelSyms(ss.Sym, limit, ss.Size)
 		}
 	}
 }
 
-// machoLabelName returns the name of the "label" symbol used for a
-// relocation targeting s+off. The label symbols is used on darwin
-// when external linking, so that the addend fits in a Mach-O relocation.
-func machoLabelName(ldr *loader.Loader, s loader.Sym, off int64) string {
-	return fmt.Sprintf("%s.%d", ldr.SymExtname(s), off/machoRelocLimit)
+// offsetLabelName returns the name of the "label" symbol used for a
+// relocation targeting s+off. The label symbols is used on Darwin/Windows
+// when external linking, so that the addend fits in a Mach-O/PE relocation.
+func offsetLabelName(ldr *loader.Loader, s loader.Sym, off int64) string {
+	if off>>20<<20 == off {
+		return fmt.Sprintf("%s+%dMB", ldr.SymExtname(s), off>>20)
+	}
+	return fmt.Sprintf("%s+%d", ldr.SymExtname(s), off)
+}
+
+// Convert the direct jump relocation r to refer to a trampoline if the target is too far
+func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
+	relocs := ldr.Relocs(s)
+	r := relocs.At(ri)
+	const pcrel = 1
+	switch r.Type() {
+	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_CALL26),
+		objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_JUMP26),
+		objabi.MachoRelocOffset + ld.MACHO_ARM64_RELOC_BRANCH26*2 + pcrel:
+		// Host object relocations that will be turned into a PLT call.
+		// The PLT may be too far. Insert a trampoline for them.
+		fallthrough
+	case objabi.R_CALLARM64:
+		var t int64
+		// ldr.SymValue(rs) == 0 indicates a cross-package jump to a function that is not yet
+		// laid out. Conservatively use a trampoline. This should be rare, as we lay out packages
+		// in dependency order.
+		if ldr.SymValue(rs) != 0 {
+			t = ldr.SymValue(rs) + r.Add() - (ldr.SymValue(s) + int64(r.Off()))
+		}
+		if t >= 1<<27 || t < -1<<27 || ldr.SymValue(rs) == 0 || (*ld.FlagDebugTramp > 1 && (ldr.SymPkg(s) == "" || ldr.SymPkg(s) != ldr.SymPkg(rs))) {
+			// direct call too far, need to insert trampoline.
+			// look up existing trampolines first. if we found one within the range
+			// of direct call, we can reuse it. otherwise create a new one.
+			var tramp loader.Sym
+			for i := 0; ; i++ {
+				oName := ldr.SymName(rs)
+				name := oName + fmt.Sprintf("%+x-tramp%d", r.Add(), i)
+				tramp = ldr.LookupOrCreateSym(name, int(ldr.SymVersion(rs)))
+				ldr.SetAttrReachable(tramp, true)
+				if ldr.SymType(tramp) == sym.SDYNIMPORT {
+					// don't reuse trampoline defined in other module
+					continue
+				}
+				if oName == "runtime.deferreturn" {
+					ldr.SetIsDeferReturnTramp(tramp, true)
+				}
+				if ldr.SymValue(tramp) == 0 {
+					// either the trampoline does not exist -- we need to create one,
+					// or found one the address which is not assigned -- this will be
+					// laid down immediately after the current function. use this one.
+					break
+				}
+
+				t = ldr.SymValue(tramp) - (ldr.SymValue(s) + int64(r.Off()))
+				if t >= -1<<27 && t < 1<<27 {
+					// found an existing trampoline that is not too far
+					// we can just use it
+					break
+				}
+			}
+			if ldr.SymType(tramp) == 0 {
+				// trampoline does not exist, create one
+				trampb := ldr.MakeSymbolUpdater(tramp)
+				ctxt.AddTramp(trampb)
+				if ldr.SymType(rs) == sym.SDYNIMPORT {
+					if r.Add() != 0 {
+						ctxt.Errorf(s, "nonzero addend for DYNIMPORT call: %v+%d", ldr.SymName(rs), r.Add())
+					}
+					gentrampgot(ctxt, ldr, trampb, rs)
+				} else {
+					gentramp(ctxt, ldr, trampb, rs, r.Add())
+				}
+			}
+			// modify reloc to point to tramp, which will be resolved later
+			sb := ldr.MakeSymbolUpdater(s)
+			relocs := sb.Relocs()
+			r := relocs.At(ri)
+			r.SetSym(tramp)
+			r.SetAdd(0) // clear the offset embedded in the instruction
+		}
+	default:
+		ctxt.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(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
+	tramp.SetSize(12) // 3 instructions
+	P := make([]byte, tramp.Size())
+	o1 := uint32(0x90000010) // adrp x16, target
+	o2 := uint32(0x91000210) // add x16, pc-relative-offset
+	o3 := uint32(0xd61f0200) // br x16
+	ctxt.Arch.ByteOrder.PutUint32(P, o1)
+	ctxt.Arch.ByteOrder.PutUint32(P[4:], o2)
+	ctxt.Arch.ByteOrder.PutUint32(P[8:], o3)
+	tramp.SetData(P)
+
+	r, _ := tramp.AddRel(objabi.R_ADDRARM64)
+	r.SetSiz(8)
+	r.SetSym(target)
+	r.SetAdd(offset)
+}
+
+// generate a trampoline to target+offset for a DYNIMPORT symbol via GOT.
+func gentrampgot(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, target loader.Sym) {
+	tramp.SetSize(12) // 3 instructions
+	P := make([]byte, tramp.Size())
+	o1 := uint32(0x90000010) // adrp x16, target@GOT
+	o2 := uint32(0xf9400210) // ldr x16, [x16, offset]
+	o3 := uint32(0xd61f0200) // br x16
+	ctxt.Arch.ByteOrder.PutUint32(P, o1)
+	ctxt.Arch.ByteOrder.PutUint32(P[4:], o2)
+	ctxt.Arch.ByteOrder.PutUint32(P[8:], o3)
+	tramp.SetData(P)
+
+	r, _ := tramp.AddRel(objabi.R_ARM64_GOTPCREL)
+	r.SetSiz(8)
+	r.SetSym(target)
 }
diff --git a/src/cmd/link/internal/arm64/obj.go b/src/cmd/link/internal/arm64/obj.go
index bd13295..9c74598 100644
--- a/src/cmd/link/internal/arm64/obj.go
+++ b/src/cmd/link/internal/arm64/obj.go
@@ -45,6 +45,7 @@
 		Minalign:   minAlign,
 		Dwarfregsp: dwarfRegSP,
 		Dwarfreglr: dwarfRegLR,
+		TrampLimit: 0x7c00000, // 26-bit signed offset * 4, leave room for PLT etc.
 
 		Adddynrel:        adddynrel,
 		Archinit:         archinit,
@@ -58,6 +59,8 @@
 		GenSymsLate:      gensymlate,
 		Machoreloc1:      machoreloc1,
 		MachorelocSize:   8,
+		PEreloc1:         pereloc1,
+		Trampoline:       trampoline,
 
 		Androiddynld: "/system/bin/linker64",
 		Linuxdynld:   "/lib/ld-linux-aarch64.so.1",
@@ -108,5 +111,9 @@
 		if *ld.FlagRound == -1 {
 			*ld.FlagRound = 16384 // 16K page alignment
 		}
+
+	case objabi.Hwindows: /* PE executable */
+		// ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit
+		return
 	}
 }
diff --git a/src/cmd/link/internal/ld/ar.go b/src/cmd/link/internal/ld/ar.go
index e4fd591..23915f9 100644
--- a/src/cmd/link/internal/ld/ar.go
+++ b/src/cmd/link/internal/ld/ar.go
@@ -32,10 +32,10 @@
 
 import (
 	"cmd/internal/bio"
-	"cmd/internal/objabi"
 	"cmd/link/internal/sym"
 	"encoding/binary"
 	"fmt"
+	"internal/buildcfg"
 	"io"
 	"os"
 )
@@ -124,6 +124,10 @@
 
 			libgcc := sym.Library{Pkg: "libgcc"}
 			h := ldobj(ctxt, f, &libgcc, l, pname, name)
+			if h.ld == nil {
+				Errorf(nil, "%s unrecognized object file at offset %d", name, off)
+				continue
+			}
 			f.MustSeek(h.off, 0)
 			h.ld(ctxt, f, h.pkg, h.length, h.pn)
 		}
@@ -170,7 +174,7 @@
 
 		// For Mach-O and PE/386 files we strip a leading
 		// underscore from the symbol name.
-		if objabi.GOOS == "darwin" || objabi.GOOS == "ios" || (objabi.GOOS == "windows" && objabi.GOARCH == "386") {
+		if buildcfg.GOOS == "darwin" || buildcfg.GOOS == "ios" || (buildcfg.GOOS == "windows" && buildcfg.GOARCH == "386") {
 			if name[0] == '_' && len(name) > 1 {
 				name = name[1:]
 			}
diff --git a/src/cmd/link/internal/ld/asmb.go b/src/cmd/link/internal/ld/asmb.go
index fda0439..d6ecb28 100644
--- a/src/cmd/link/internal/ld/asmb.go
+++ b/src/cmd/link/internal/ld/asmb.go
@@ -29,8 +29,6 @@
 	}
 
 	var wg sync.WaitGroup
-	sect := Segtext.Sections[0]
-	offset := sect.Vaddr - Segtext.Vaddr + Segtext.Fileoff
 	f := func(ctxt *Link, out *OutBuf, start, length int64) {
 		pad := thearch.CodePad
 		if pad == nil {
@@ -39,23 +37,14 @@
 		CodeblkPad(ctxt, out, start, length, pad)
 	}
 
-	if !thearch.WriteTextBlocks {
-		writeParallel(&wg, f, ctxt, offset, sect.Vaddr, sect.Length)
-		for _, sect := range Segtext.Sections[1:] {
-			offset := sect.Vaddr - Segtext.Vaddr + Segtext.Fileoff
+	for _, sect := range Segtext.Sections {
+		offset := sect.Vaddr - Segtext.Vaddr + Segtext.Fileoff
+		// Handle text sections with Codeblk
+		if sect.Name == ".text" {
+			writeParallel(&wg, f, ctxt, offset, sect.Vaddr, sect.Length)
+		} else {
 			writeParallel(&wg, datblk, ctxt, offset, sect.Vaddr, sect.Length)
 		}
-	} else {
-		// TODO why can't we handle all sections this way?
-		for _, sect := range Segtext.Sections {
-			offset := sect.Vaddr - Segtext.Vaddr + Segtext.Fileoff
-			// Handle additional text sections with Codeblk
-			if sect.Name == ".text" {
-				writeParallel(&wg, f, ctxt, offset, sect.Vaddr, sect.Length)
-			} else {
-				writeParallel(&wg, datblk, ctxt, offset, sect.Vaddr, sect.Length)
-			}
-		}
 	}
 
 	if Segrodata.Filelen > 0 {
@@ -178,7 +167,10 @@
 		}
 	}
 	filesz := ctxt.Out.Offset() + sz
-	ctxt.Out.Mmap(uint64(filesz))
+	err := ctxt.Out.Mmap(uint64(filesz))
+	if err != nil {
+		Exitf("mapping output file failed: %v", err)
+	}
 }
 
 // relocSectFn wraps the function writing relocations of a section
diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go
index d1e0623..20f1d0b 100644
--- a/src/cmd/link/internal/ld/config.go
+++ b/src/cmd/link/internal/ld/config.go
@@ -5,10 +5,9 @@
 package ld
 
 import (
-	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"fmt"
-	"log"
+	"internal/buildcfg"
 )
 
 // A BuildMode indicates the sort of object we are building.
@@ -29,23 +28,23 @@
 
 func (mode *BuildMode) Set(s string) error {
 	badmode := func() error {
-		return fmt.Errorf("buildmode %s not supported on %s/%s", s, objabi.GOOS, objabi.GOARCH)
+		return fmt.Errorf("buildmode %s not supported on %s/%s", s, buildcfg.GOOS, buildcfg.GOARCH)
 	}
 	switch s {
 	default:
 		return fmt.Errorf("invalid buildmode: %q", s)
 	case "exe":
-		switch objabi.GOOS + "/" + objabi.GOARCH {
-		case "darwin/arm64", "windows/arm": // On these platforms, everything is PIE
+		switch buildcfg.GOOS + "/" + buildcfg.GOARCH {
+		case "darwin/arm64", "windows/arm", "windows/arm64": // On these platforms, everything is PIE
 			*mode = BuildModePIE
 		default:
 			*mode = BuildModeExe
 		}
 	case "pie":
-		switch objabi.GOOS {
+		switch buildcfg.GOOS {
 		case "aix", "android", "linux", "windows", "darwin", "ios":
 		case "freebsd":
-			switch objabi.GOARCH {
+			switch buildcfg.GOARCH {
 			case "amd64":
 			default:
 				return badmode()
@@ -55,17 +54,17 @@
 		}
 		*mode = BuildModePIE
 	case "c-archive":
-		switch objabi.GOOS {
+		switch buildcfg.GOOS {
 		case "aix", "darwin", "ios", "linux":
 		case "freebsd":
-			switch objabi.GOARCH {
+			switch buildcfg.GOARCH {
 			case "amd64":
 			default:
 				return badmode()
 			}
 		case "windows":
-			switch objabi.GOARCH {
-			case "amd64", "386", "arm":
+			switch buildcfg.GOARCH {
+			case "amd64", "386", "arm", "arm64":
 			default:
 				return badmode()
 			}
@@ -74,16 +73,16 @@
 		}
 		*mode = BuildModeCArchive
 	case "c-shared":
-		switch objabi.GOARCH {
+		switch buildcfg.GOARCH {
 		case "386", "amd64", "arm", "arm64", "ppc64le", "s390x":
 		default:
 			return badmode()
 		}
 		*mode = BuildModeCShared
 	case "shared":
-		switch objabi.GOOS {
+		switch buildcfg.GOOS {
 		case "linux":
-			switch objabi.GOARCH {
+			switch buildcfg.GOARCH {
 			case "386", "amd64", "arm", "arm64", "ppc64le", "s390x":
 			default:
 				return badmode()
@@ -93,21 +92,21 @@
 		}
 		*mode = BuildModeShared
 	case "plugin":
-		switch objabi.GOOS {
+		switch buildcfg.GOOS {
 		case "linux":
-			switch objabi.GOARCH {
+			switch buildcfg.GOARCH {
 			case "386", "amd64", "arm", "arm64", "s390x", "ppc64le":
 			default:
 				return badmode()
 			}
 		case "darwin":
-			switch objabi.GOARCH {
+			switch buildcfg.GOARCH {
 			case "amd64", "arm64":
 			default:
 				return badmode()
 			}
 		case "freebsd":
-			switch objabi.GOARCH {
+			switch buildcfg.GOARCH {
 			case "amd64":
 			default:
 				return badmode()
@@ -181,13 +180,13 @@
 	if ctxt.Debugvlog > 1 {
 		defer func() {
 			if res {
-				log.Printf("external linking is forced by: %s\n", reason)
+				ctxt.Logf("external linking is forced by: %s\n", reason)
 			}
 		}()
 	}
 
-	if sys.MustLinkExternal(objabi.GOOS, objabi.GOARCH) {
-		return true, fmt.Sprintf("%s/%s requires external linking", objabi.GOOS, objabi.GOARCH)
+	if sys.MustLinkExternal(buildcfg.GOOS, buildcfg.GOARCH) {
+		return true, fmt.Sprintf("%s/%s requires external linking", buildcfg.GOOS, buildcfg.GOARCH)
 	}
 
 	if *flagMsan {
@@ -198,17 +197,24 @@
 	// https://golang.org/issue/14449
 	// https://golang.org/issue/21961
 	if iscgo && ctxt.Arch.InFamily(sys.MIPS64, sys.MIPS, sys.PPC64, sys.RISCV64) {
-		return true, objabi.GOARCH + " does not support internal cgo"
+		return true, buildcfg.GOARCH + " does not support internal cgo"
 	}
-	if iscgo && objabi.GOOS == "android" {
-		return true, objabi.GOOS + " does not support internal cgo"
+	if iscgo && (buildcfg.GOOS == "android" || buildcfg.GOOS == "dragonfly") {
+		// It seems that on Dragonfly thread local storage is
+		// set up by the dynamic linker, so internal cgo linking
+		// doesn't work. Test case is "go test runtime/cgo".
+		return true, buildcfg.GOOS + " does not support internal cgo"
+	}
+	if iscgo && buildcfg.GOOS == "windows" && buildcfg.GOARCH == "arm64" {
+		// windows/arm64 internal linking is not implemented.
+		return true, buildcfg.GOOS + "/" + buildcfg.GOARCH + " does not support internal cgo"
 	}
 
 	// When the race flag is set, the LLVM tsan relocatable file is linked
 	// into the final binary, which means external linking is required because
 	// internal linking does not support it.
 	if *flagRace && ctxt.Arch.InFamily(sys.PPC64) {
-		return true, "race on " + objabi.GOARCH
+		return true, "race on " + buildcfg.GOARCH
 	}
 
 	// Some build modes require work the internal linker cannot do (yet).
@@ -218,9 +224,9 @@
 	case BuildModeCShared:
 		return true, "buildmode=c-shared"
 	case BuildModePIE:
-		switch objabi.GOOS + "/" + objabi.GOARCH {
+		switch buildcfg.GOOS + "/" + buildcfg.GOARCH {
 		case "linux/amd64", "linux/arm64", "android/arm64":
-		case "windows/386", "windows/amd64", "windows/arm":
+		case "windows/386", "windows/amd64", "windows/arm", "windows/arm64":
 		case "darwin/amd64", "darwin/arm64":
 		default:
 			// Internal linking does not support TLS_IE.
@@ -235,6 +241,10 @@
 		return true, "dynamically linking with a shared library"
 	}
 
+	if unknownObjFormat {
+		return true, "some input objects have an unrecognized file format"
+	}
+
 	return false, ""
 }
 
@@ -242,7 +252,7 @@
 //
 // It is called after flags are processed and inputs are processed,
 // so the ctxt.LinkMode variable has an initial value from the -linkmode
-// flag and the iscgo externalobj variables are set.
+// flag and the iscgo, externalobj, and unknownObjFormat variables are set.
 func determineLinkMode(ctxt *Link) {
 	extNeeded, extReason := mustLinkExternal(ctxt)
 	via := ""
@@ -252,7 +262,7 @@
 		// default value of -linkmode. If it is not set when the
 		// linker is called we take the value it was set to when
 		// cmd/link was compiled. (See make.bash.)
-		switch objabi.Getgoextlinkenabled() {
+		switch buildcfg.Getgoextlinkenabled() {
 		case "0":
 			ctxt.LinkMode = LinkInternal
 			via = "via GO_EXTLINK_ENABLED "
@@ -275,8 +285,8 @@
 		}
 	case LinkExternal:
 		switch {
-		case objabi.GOARCH == "ppc64" && objabi.GOOS != "aix":
-			Exitf("external linking not supported for %s/ppc64", objabi.GOOS)
+		case buildcfg.GOARCH == "ppc64" && buildcfg.GOOS != "aix":
+			Exitf("external linking not supported for %s/ppc64", buildcfg.GOOS)
 		}
 	}
 }
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index 52035e9..70fbb9d 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -39,6 +39,7 @@
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
 	"compress/zlib"
+	"debug/elf"
 	"encoding/binary"
 	"fmt"
 	"log"
@@ -55,6 +56,7 @@
 	switch pkg {
 	case "runtime",
 		"sync/atomic",      // runtime may call to sync/atomic, due to go:linkname
+		"internal/abi",     // used by reflectcall (and maybe more)
 		"internal/bytealg", // for IndexByte
 		"internal/cpu":     // for cpu features
 		return true
@@ -65,7 +67,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(ldr *loader.Loader, s loader.Sym, isTramp bool) uint64 {
+func maxSizeTrampolines(ctxt *Link, ldr *loader.Loader, s loader.Sym, 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 {
@@ -80,8 +82,14 @@
 			n++
 		}
 	}
-	// Trampolines in ppc64 are 4 instructions.
-	return n * 16
+
+	if ctxt.IsPPC64() {
+		return n * 16 // Trampolines in PPC64 are 4 instructions.
+	}
+	if ctxt.IsARM64() {
+		return n * 12 // Trampolines in ARM64 are 3 instructions.
+	}
+	panic("unreachable")
 }
 
 // detect too-far jumps in function s, and add trampolines if necessary
@@ -97,7 +105,8 @@
 	relocs := ldr.Relocs(s)
 	for ri := 0; ri < relocs.Count(); ri++ {
 		r := relocs.At(ri)
-		if !r.Type().IsDirectCallOrJump() {
+		rt := r.Type()
+		if !rt.IsDirectCallOrJump() && !isPLTCall(rt) {
 			continue
 		}
 		rs := r.Sym()
@@ -106,8 +115,11 @@
 		}
 		rs = ldr.ResolveABIAlias(rs)
 		if ldr.SymValue(rs) == 0 && (ldr.SymType(rs) != sym.SDYNIMPORT && ldr.SymType(rs) != sym.SUNDEFEXT) {
-			if ldr.SymPkg(rs) == ldr.SymPkg(s) {
-				continue // symbols in the same package are laid out together
+			if ldr.SymPkg(s) != "" && ldr.SymPkg(rs) == ldr.SymPkg(s) {
+				// Symbols in the same package are laid out together.
+				// Except that if SymPkg(s) == "", it is a host object symbol
+				// which may call an external symbol via PLT.
+				continue
 			}
 			if isRuntimeDepPkg(ldr.SymPkg(s)) && isRuntimeDepPkg(ldr.SymPkg(rs)) {
 				continue // runtime packages are laid out together
@@ -116,7 +128,27 @@
 
 		thearch.Trampoline(ctxt, ldr, ri, rs, s)
 	}
+}
 
+// whether rt is a (host object) relocation that will be turned into
+// a call to PLT.
+func isPLTCall(rt objabi.RelocType) bool {
+	const pcrel = 1
+	switch rt {
+	// ARM64
+	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_CALL26),
+		objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_JUMP26),
+		objabi.MachoRelocOffset + MACHO_ARM64_RELOC_BRANCH26*2 + pcrel:
+		return true
+
+	// ARM
+	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL),
+		objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PC24),
+		objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24):
+		return true
+	}
+	// TODO: other architectures.
+	return false
 }
 
 // FoldSubSymbolOffset computes the offset of symbol s to its top-level outer
@@ -164,6 +196,7 @@
 		rs := r.Sym()
 		rs = ldr.ResolveABIAlias(rs)
 		rt := r.Type()
+		weak := r.Weak()
 		if off < 0 || off+siz > int32(len(P)) {
 			rname := ""
 			if rs != 0 {
@@ -210,7 +243,7 @@
 				st.err.Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", ldr.SymName(rs), rst, rst, rt, sym.RelocName(target.Arch, rt))
 			}
 		}
-		if rs != 0 && rst != sym.STLSBSS && rt != objabi.R_WEAKADDROFF && rt != objabi.R_METHODOFF && !ldr.AttrReachable(rs) {
+		if rs != 0 && rst != sym.STLSBSS && !weak && rt != objabi.R_METHODOFF && !ldr.AttrReachable(rs) {
 			st.err.Errorf(s, "unreachable sym in relocation: %s", ldr.SymName(rs))
 		}
 
@@ -304,6 +337,11 @@
 				log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", ldr.SymName(s))
 			}
 		case objabi.R_ADDR:
+			if weak && !ldr.AttrReachable(rs) {
+				// Redirect it to runtime.unreachableMethod, which will throw if called.
+				rs = syms.unreachableMethod
+				rs = ldr.ResolveABIAlias(rs)
+			}
 			if target.IsExternal() {
 				nExtReloc++
 
@@ -386,18 +424,18 @@
 				break
 			}
 			o = ldr.SymValue(rs) + r.Add() - int64(ldr.SymSect(rs).Vaddr)
-		case objabi.R_WEAKADDROFF, objabi.R_METHODOFF:
+		case objabi.R_METHODOFF:
 			if !ldr.AttrReachable(rs) {
-				if rt == objabi.R_METHODOFF {
-					// Set it to a sentinel value. The runtime knows this is not pointing to
-					// anything valid.
-					o = -1
-					break
-				}
-				continue
+				// Set it to a sentinel value. The runtime knows this is not pointing to
+				// anything valid.
+				o = -1
+				break
 			}
 			fallthrough
 		case objabi.R_ADDROFF:
+			if weak && !ldr.AttrReachable(rs) {
+				continue
+			}
 			// The method offset tables using this relocation expect the offset to be relative
 			// to the start of the first text section, even if there are multiple.
 			if ldr.SymSect(rs).Name == ".text" {
@@ -505,7 +543,7 @@
 
 		if target.IsPPC64() || target.IsS390X() {
 			if rv != sym.RV_NONE {
-				o = thearch.Archrelocvariant(target, ldr, r, rv, s, o)
+				o = thearch.Archrelocvariant(target, ldr, r, rv, s, o, P)
 			}
 		}
 
@@ -584,6 +622,10 @@
 	case objabi.R_ADDR:
 		// set up addend for eventual relocation via outer symbol.
 		rs := ldr.ResolveABIAlias(r.Sym())
+		if r.Weak() && !ldr.AttrReachable(rs) {
+			rs = ctxt.ArchSyms.unreachableMethod
+			rs = ldr.ResolveABIAlias(rs)
+		}
 		rs, off := FoldSubSymbolOffset(ldr, rs)
 		rr.Xadd = r.Add() + off
 		rr.Xsym = rs
@@ -634,7 +676,7 @@
 		return ExtrelocSimple(ldr, r), true
 
 	// These reloc types don't need external relocations.
-	case objabi.R_ADDROFF, objabi.R_WEAKADDROFF, objabi.R_METHODOFF, objabi.R_ADDRCUOFF,
+	case objabi.R_ADDROFF, objabi.R_METHODOFF, objabi.R_ADDRCUOFF,
 		objabi.R_SIZE, objabi.R_CONST, objabi.R_GOTOFF:
 		return rr, false
 	}
@@ -709,9 +751,8 @@
 		if targ == 0 {
 			continue
 		}
-		rt := r.Type()
 		if !ctxt.loader.AttrReachable(targ) {
-			if rt == objabi.R_WEAKADDROFF {
+			if r.Weak() {
 				continue
 			}
 			ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s",
@@ -785,6 +826,10 @@
 		if r.IsMarker() {
 			continue // skip marker relocations
 		}
+		rSym := r.Sym()
+		if r.Weak() && !ldr.AttrReachable(rSym) {
+			continue
+		}
 		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
@@ -793,7 +838,6 @@
 			continue
 		}
 
-		rSym := r.Sym()
 		if rSym != 0 && ldr.SymType(rSym) == sym.SDYNIMPORT || r.Type() >= objabi.ElfRelocOffset {
 			if rSym != 0 && !ldr.AttrReachable(rSym) {
 				ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s", ldr.SymName(rSym))
@@ -1506,7 +1550,7 @@
 
 	if ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal {
 		// These symbols must have the same alignment as their section.
-		// Otherwize, ld might change the layout of Go sections.
+		// Otherwise, ld might change the layout of Go sections.
 		ldr.SetSymAlign(ldr.Lookup("runtime.data", 0), state.dataMaxAlign[sym.SDATA])
 		ldr.SetSymAlign(ldr.Lookup("runtime.bss", 0), state.dataMaxAlign[sym.SBSS])
 	}
@@ -2192,23 +2236,87 @@
 		ctxt.Textp[0] = text
 	}
 
-	va := uint64(Rnd(*FlagTextAddr, int64(Funcalign)))
+	start := uint64(Rnd(*FlagTextAddr, int64(Funcalign)))
+	va := start
 	n := 1
 	sect.Vaddr = va
-	ntramps := 0
+
+	limit := thearch.TrampLimit
+	if limit == 0 {
+		limit = 1 << 63 // unlimited
+	}
+	if *FlagDebugTextSize != 0 {
+		limit = uint64(*FlagDebugTextSize)
+	}
+	if *FlagDebugTramp > 1 {
+		limit = 1 // debug mode, force generating trampolines for everything
+	}
+
+	if ctxt.IsAIX() && ctxt.IsExternal() {
+		// On AIX, normally we won't generate direct calls to external symbols,
+		// except in one test, cmd/go/testdata/script/link_syso_issue33139.txt.
+		// That test doesn't make much sense, and I'm not sure it ever works.
+		// Just generate trampoline for now (which will turn a direct call to
+		// an indirect call, which at least builds).
+		limit = 1
+	}
+
+	// First pass: assign addresses assuming the program is small and
+	// don't generate trampolines.
+	big := false
 	for _, s := range ctxt.Textp {
-		sect, n, va = assignAddress(ctxt, sect, n, s, va, false)
+		sect, n, va = assignAddress(ctxt, sect, n, s, va, false, big)
+		if va-start >= limit {
+			big = true
+			break
+		}
+	}
 
-		trampoline(ctxt, s) // resolve jumps, may add trampolines if jump too far
-
-		// lay down trampolines after each function
-		for ; ntramps < len(ctxt.tramps); ntramps++ {
-			tramp := ctxt.tramps[ntramps]
-			if ctxt.IsAIX() && strings.HasPrefix(ldr.SymName(tramp), "runtime.text.") {
-				// Already set in assignAddress
+	// Second pass: only if it is too big, insert trampolines for too-far
+	// jumps and targets with unknown addresses.
+	if big {
+		// reset addresses
+		for _, s := range ctxt.Textp {
+			if ldr.OuterSym(s) != 0 || s == text {
 				continue
 			}
-			sect, n, va = assignAddress(ctxt, sect, n, tramp, va, true)
+			oldv := ldr.SymValue(s)
+			for sub := s; sub != 0; sub = ldr.SubSym(sub) {
+				ldr.SetSymValue(sub, ldr.SymValue(sub)-oldv)
+			}
+		}
+		va = start
+
+		ntramps := 0
+		for _, s := range ctxt.Textp {
+			sect, n, va = assignAddress(ctxt, sect, n, s, va, false, big)
+
+			trampoline(ctxt, s) // resolve jumps, may add trampolines if jump too far
+
+			// lay down trampolines after each function
+			for ; ntramps < len(ctxt.tramps); ntramps++ {
+				tramp := ctxt.tramps[ntramps]
+				if ctxt.IsAIX() && strings.HasPrefix(ldr.SymName(tramp), "runtime.text.") {
+					// Already set in assignAddress
+					continue
+				}
+				sect, n, va = assignAddress(ctxt, sect, n, tramp, va, true, big)
+			}
+		}
+
+		// merge tramps into Textp, keeping Textp in address order
+		if ntramps != 0 {
+			newtextp := make([]loader.Sym, 0, len(ctxt.Textp)+ntramps)
+			i := 0
+			for _, s := range ctxt.Textp {
+				for ; i < ntramps && ldr.SymValue(ctxt.tramps[i]) < ldr.SymValue(s); i++ {
+					newtextp = append(newtextp, ctxt.tramps[i])
+				}
+				newtextp = append(newtextp, s)
+			}
+			newtextp = append(newtextp, ctxt.tramps[i:ntramps]...)
+
+			ctxt.Textp = newtextp
 		}
 	}
 
@@ -2220,25 +2328,10 @@
 		ldr.SetSymValue(etext, int64(va))
 		ldr.SetSymValue(text, int64(Segtext.Sections[0].Vaddr))
 	}
-
-	// merge tramps into Textp, keeping Textp in address order
-	if ntramps != 0 {
-		newtextp := make([]loader.Sym, 0, len(ctxt.Textp)+ntramps)
-		i := 0
-		for _, s := range ctxt.Textp {
-			for ; i < ntramps && ldr.SymValue(ctxt.tramps[i]) < ldr.SymValue(s); i++ {
-				newtextp = append(newtextp, ctxt.tramps[i])
-			}
-			newtextp = append(newtextp, s)
-		}
-		newtextp = append(newtextp, ctxt.tramps[i:ntramps]...)
-
-		ctxt.Textp = newtextp
-	}
 }
 
 // assigns address for a text symbol, returns (possibly new) section, its number, and the address
-func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64, isTramp bool) (*sym.Section, int, uint64) {
+func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64, isTramp, big bool) (*sym.Section, int, uint64) {
 	ldr := ctxt.loader
 	if thearch.AssignAddress != nil {
 		return thearch.AssignAddress(ldr, sect, n, s, va, isTramp)
@@ -2263,36 +2356,46 @@
 		funcsize = uint64(ldr.SymSize(s))
 	}
 
-	// On ppc64x a text section should not be larger than 2^26 bytes due to the size of
-	// call target offset field in the bl instruction.  Splitting into smaller text
-	// sections smaller than this limit allows the GNU linker to modify the long calls
-	// appropriately.  The limit allows for the space needed for tables inserted by the linker.
-
-	// If this function doesn't fit in the current text section, then create a new one.
-
+	// If we need to split text sections, and this function doesn't fit in the current
+	// section, then create a new one.
+	//
 	// Only break at outermost syms.
+	if big && splitTextSections(ctxt) && ldr.OuterSym(s) == 0 {
+		// For debugging purposes, allow text size limit to be cranked down,
+		// so as to stress test the code that handles multiple text sections.
+		var textSizelimit uint64 = thearch.TrampLimit
+		if *FlagDebugTextSize != 0 {
+			textSizelimit = uint64(*FlagDebugTextSize)
+		}
 
-	// For debugging purposes, allow text size limit to be cranked down,
-	// so as to stress test the code that handles multiple text sections.
-	var textSizelimit uint64 = 0x1c00000
-	if *FlagDebugTextSize != 0 {
-		textSizelimit = uint64(*FlagDebugTextSize)
-	}
-
-	if ctxt.Arch.InFamily(sys.PPC64) && ldr.OuterSym(s) == 0 && ctxt.IsExternal() {
 		// Sanity check: make sure the limit is larger than any
 		// individual text symbol.
 		if funcsize > textSizelimit {
-			panic(fmt.Sprintf("error: ppc64 text size limit %d less than text symbol %s size of %d", textSizelimit, ldr.SymName(s), funcsize))
+			panic(fmt.Sprintf("error: text size limit %d less than text symbol %s size of %d", textSizelimit, ldr.SymName(s), funcsize))
 		}
 
-		if va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(ldr, s, isTramp) > textSizelimit {
+		if va-sect.Vaddr+funcsize+maxSizeTrampolines(ctxt, ldr, s, isTramp) > textSizelimit {
+			sectAlign := int32(thearch.Funcalign)
+			if ctxt.IsPPC64() {
+				// Align the next text section to the worst case function alignment likely
+				// to be encountered when processing function symbols. The start address
+				// is rounded against the final alignment of the text section later on in
+				// (*Link).address. This may happen due to usage of PCALIGN directives
+				// larger than Funcalign, or usage of ISA 3.1 prefixed instructions
+				// (see ISA 3.1 Book I 1.9).
+				const ppc64maxFuncalign = 64
+				sectAlign = ppc64maxFuncalign
+				va = uint64(Rnd(int64(va), ppc64maxFuncalign))
+			}
+
 			// Set the length for the previous text section
 			sect.Length = va - sect.Vaddr
 
 			// Create new section, set the starting Vaddr
 			sect = addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
+
 			sect.Vaddr = va
+			sect.Align = sectAlign
 			ldr.SetSymSect(s, sect)
 
 			// Create a symbol for the start of the secondary text sections
@@ -2305,6 +2408,7 @@
 				ntext.SetType(sym.STEXT)
 				ntext.SetSize(int64(MINFUNC))
 				ntext.SetOnList(true)
+				ntext.SetAlign(sectAlign)
 				ctxt.tramps = append(ctxt.tramps, ntext.Sym())
 
 				ntext.SetValue(int64(va))
@@ -2323,6 +2427,9 @@
 	ldr.SetSymValue(s, 0)
 	for sub := s; sub != 0; sub = ldr.SubSym(sub) {
 		ldr.SetSymValue(sub, ldr.SymValue(sub)+int64(va))
+		if ctxt.Debugvlog > 2 {
+			fmt.Println("assign text address:", ldr.SymName(sub), ldr.SymValue(sub))
+		}
 	}
 
 	va += funcsize
@@ -2330,6 +2437,19 @@
 	return sect, n, va
 }
 
+// Return whether we may need to split text sections.
+//
+// On PPC64x whem external linking a text section should not be larger than 2^25 bytes
+// due to the size of call target offset field in the bl instruction.  Splitting into
+// smaller text sections smaller than this limit allows the system linker to modify the long
+// calls appropriately. The limit allows for the space needed for tables inserted by the
+// linker.
+//
+// The same applies to Darwin/ARM64, with 2^27 byte threshold.
+func splitTextSections(ctxt *Link) bool {
+	return (ctxt.IsPPC64() || (ctxt.IsARM64() && ctxt.IsDarwin())) && ctxt.IsExternal()
+}
+
 // address assigns virtual addresses to all segments and sections and
 // returns all segments in file order.
 func (ctxt *Link) address() []*sym.Segment {
diff --git a/src/cmd/link/internal/ld/data_test.go b/src/cmd/link/internal/ld/data_test.go
index 7c46307..f91493b 100644
--- a/src/cmd/link/internal/ld/data_test.go
+++ b/src/cmd/link/internal/ld/data_test.go
@@ -8,6 +8,7 @@
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"cmd/link/internal/loader"
+	"internal/buildcfg"
 	"testing"
 )
 
@@ -63,14 +64,14 @@
 	}
 
 	// Save the architecture as we're going to set it on each test run.
-	origArch := objabi.GOARCH
+	origArch := buildcfg.GOARCH
 	defer func() {
-		objabi.GOARCH = origArch
+		buildcfg.GOARCH = origArch
 	}()
 
 	for i, test := range tests {
 		iself := len(test.rel) != 0
-		objabi.GOARCH = test.arch.Name
+		buildcfg.GOARCH = test.arch.Name
 		ctxt := setUpContext(test.arch, iself, test.ht, test.bm, test.lm)
 		foo := ctxt.loader.CreateSymForUpdate("foo", 0)
 		ctxt.loader.CreateExtSym("bar", 0)
diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go
index bfa8640..416e5da 100644
--- a/src/cmd/link/internal/ld/deadcode.go
+++ b/src/cmd/link/internal/ld/deadcode.go
@@ -11,6 +11,7 @@
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
 	"fmt"
+	"internal/buildcfg"
 	"unicode"
 )
 
@@ -19,7 +20,7 @@
 type deadcodePass struct {
 	ctxt *Link
 	ldr  *loader.Loader
-	wq   heap // work queue, using min-heap for beter locality
+	wq   heap // work queue, using min-heap for better locality
 
 	ifaceMethod     map[methodsig]bool // methods declared in reached interfaces
 	markableMethods []methodref        // methods of reached types
@@ -32,7 +33,7 @@
 func (d *deadcodePass) init() {
 	d.ldr.InitReachable()
 	d.ifaceMethod = make(map[methodsig]bool)
-	if objabi.Fieldtrack_enabled != 0 {
+	if buildcfg.Experiment.FieldTrack {
 		d.ldr.Reachparent = make([]loader.Sym, d.ldr.NSym())
 	}
 	d.dynlink = d.ctxt.DynlinkingGo()
@@ -64,33 +65,32 @@
 			}
 		}
 		names = append(names, *flagEntrySymbol)
-		if !d.ctxt.linkShared && d.ctxt.BuildMode != BuildModePlugin {
-			// runtime.buildVersion and runtime.modinfo are referenced in .go.buildinfo section
-			// (see function buildinfo in data.go). They should normally be reachable from the
-			// runtime. Just make it explicit, in case.
-			names = append(names, "runtime.buildVersion", "runtime.modinfo")
-		}
-		if d.ctxt.BuildMode == BuildModePlugin {
-			names = append(names, objabi.PathToPrefix(*flagPluginPath)+"..inittask", objabi.PathToPrefix(*flagPluginPath)+".main", "go.plugin.tabs")
+	}
+	// runtime.unreachableMethod is a function that will throw if called.
+	// We redirect unreachable methods to it.
+	names = append(names, "runtime.unreachableMethod")
+	if !d.ctxt.linkShared && d.ctxt.BuildMode != BuildModePlugin {
+		// runtime.buildVersion and runtime.modinfo are referenced in .go.buildinfo section
+		// (see function buildinfo in data.go). They should normally be reachable from the
+		// runtime. Just make it explicit, in case.
+		names = append(names, "runtime.buildVersion", "runtime.modinfo")
+	}
+	if d.ctxt.BuildMode == BuildModePlugin {
+		names = append(names, objabi.PathToPrefix(*flagPluginPath)+"..inittask", objabi.PathToPrefix(*flagPluginPath)+".main", "go.plugin.tabs")
 
-			// We don't keep the go.plugin.exports symbol,
-			// but we do keep the symbols it refers to.
-			exportsIdx := d.ldr.Lookup("go.plugin.exports", 0)
-			if exportsIdx != 0 {
-				relocs := d.ldr.Relocs(exportsIdx)
-				for i := 0; i < relocs.Count(); i++ {
-					d.mark(relocs.At(i).Sym(), 0)
-				}
+		// We don't keep the go.plugin.exports symbol,
+		// but we do keep the symbols it refers to.
+		exportsIdx := d.ldr.Lookup("go.plugin.exports", 0)
+		if exportsIdx != 0 {
+			relocs := d.ldr.Relocs(exportsIdx)
+			for i := 0; i < relocs.Count(); i++ {
+				d.mark(relocs.At(i).Sym(), 0)
 			}
 		}
 	}
 
-	dynexpMap := d.ctxt.cgo_export_dynamic
-	if d.ctxt.LinkMode == LinkExternal {
-		dynexpMap = d.ctxt.cgo_export_static
-	}
-	for exp := range dynexpMap {
-		names = append(names, exp)
+	if d.ctxt.Debugvlog > 1 {
+		d.ctxt.Logf("deadcode start names: %v\n", names)
 	}
 
 	for _, name := range names {
@@ -99,6 +99,14 @@
 		// Also mark any Go functions (internal ABI).
 		d.mark(d.ldr.Lookup(name, sym.SymVerABIInternal), 0)
 	}
+
+	// All dynamic exports are roots.
+	for _, s := range d.ctxt.dynexp {
+		if d.ctxt.Debugvlog > 1 {
+			d.ctxt.Logf("deadcode start dynexp: %s<%d>\n", d.ldr.SymName(s), d.ldr.SymVersion(s))
+		}
+		d.mark(s, 0)
+	}
 }
 
 func (d *deadcodePass) flood() {
@@ -114,7 +122,7 @@
 
 		if isgotype {
 			if d.dynlink {
-				// When dynaamic linking, a type may be passed across DSO
+				// When dynamic linking, a type may be passed across DSO
 				// boundary and get converted to interface at the other side.
 				d.ldr.SetAttrUsedInIface(symIdx, true)
 			}
@@ -124,10 +132,11 @@
 		methods = methods[:0]
 		for i := 0; i < relocs.Count(); i++ {
 			r := relocs.At(i)
+			if r.Weak() {
+				continue
+			}
 			t := r.Type()
 			switch t {
-			case objabi.R_WEAKADDROFF:
-				continue
 			case objabi.R_METHODOFF:
 				if i+2 >= relocs.Count() {
 					panic("expect three consecutive R_METHODOFF relocs")
@@ -250,7 +259,7 @@
 	if symIdx != 0 && !d.ldr.AttrReachable(symIdx) {
 		d.wq.push(symIdx)
 		d.ldr.SetAttrReachable(symIdx, true)
-		if objabi.Fieldtrack_enabled != 0 && d.ldr.Reachparent[symIdx] == 0 {
+		if buildcfg.Experiment.FieldTrack && d.ldr.Reachparent[symIdx] == 0 {
 			d.ldr.Reachparent[symIdx] = parent
 		}
 		if *flagDumpDep {
diff --git a/src/cmd/link/internal/ld/deadcode_test.go b/src/cmd/link/internal/ld/deadcode_test.go
index b756091..6e12843 100644
--- a/src/cmd/link/internal/ld/deadcode_test.go
+++ b/src/cmd/link/internal/ld/deadcode_test.go
@@ -7,8 +7,6 @@
 import (
 	"bytes"
 	"internal/testenv"
-	"io/ioutil"
-	"os"
 	"os/exec"
 	"path/filepath"
 	"testing"
@@ -18,11 +16,7 @@
 	testenv.MustHaveGoBuild(t)
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestDeadcode")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	tests := []struct {
 		src      string
@@ -46,10 +40,10 @@
 			if err != nil {
 				t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
 			}
-			if test.pos != "" && !bytes.Contains(out, []byte(test.pos)) {
+			if test.pos != "" && !bytes.Contains(out, []byte(test.pos+"\n")) {
 				t.Errorf("%s should be reachable. Output:\n%s", test.pos, out)
 			}
-			if test.neg != "" && bytes.Contains(out, []byte(test.neg)) {
+			if test.neg != "" && bytes.Contains(out, []byte(test.neg+"\n")) {
 				t.Errorf("%s should not be reachable. Output:\n%s", test.neg, out)
 			}
 		})
diff --git a/src/cmd/link/internal/ld/decodesym.go b/src/cmd/link/internal/ld/decodesym.go
index fc179fc..629bdcf 100644
--- a/src/cmd/link/internal/ld/decodesym.go
+++ b/src/cmd/link/internal/ld/decodesym.go
@@ -10,17 +10,18 @@
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
 	"debug/elf"
+	"encoding/binary"
 	"log"
 )
 
 // Decoding the type.* symbols.	 This has to be in sync with
 // ../../runtime/type.go, or more specifically, with what
-// cmd/compile/internal/gc/reflect.go stuffs in these.
+// cmd/compile/internal/reflectdata/reflect.go stuffs in these.
 
 // tflag is documented in reflect/type.go.
 //
 // tflag values must be kept in sync with copies in:
-//	cmd/compile/internal/gc/reflect.go
+//	cmd/compile/internal/reflectdata/reflect.go
 //	cmd/link/internal/ld/decodesym.go
 //	reflect/type.go
 //	runtime/type.go
@@ -126,8 +127,8 @@
 	}
 
 	data := ldr.Data(r)
-	namelen := int(uint16(data[1])<<8 | uint16(data[2]))
-	return string(data[3 : 3+namelen])
+	nameLen, nameLenLen := binary.Uvarint(data[1:])
+	return string(data[1+nameLenLen : 1+nameLenLen+int(nameLen)])
 }
 
 func decodetypeFuncInType(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, i int) loader.Sym {
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index 2ab9a55..c53d240 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -22,6 +22,7 @@
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
 	"fmt"
+	"internal/buildcfg"
 	"log"
 	"path"
 	"runtime"
@@ -458,12 +459,6 @@
 	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 (d *dwctxt) newabslocexprattr(die *dwarf.DWDie, addr int64, symIdx loader.Sym) {
-	newattr(die, dwarf.DW_AT_location, dwarf.DW_CLS_ADDRESS, addr, dwSym(symIdx))
-}
-
 func (d *dwctxt) lookupOrDiag(n string) loader.Sym {
 	symIdx := d.ldr.Lookup(n, 0)
 	if symIdx == 0 {
@@ -1020,25 +1015,6 @@
 	}
 }
 
-func (d *dwctxt) dwarfDefineGlobal(ctxt *Link, symIdx loader.Sym, str string, v int64, gotype loader.Sym) {
-	// Find a suitable CU DIE to include the global.
-	// One would think it's as simple as just looking at the unit, but that might
-	// not have any reachable code. So, we go to the runtime's CU if our unit
-	// isn't otherwise reachable.
-	unit := d.ldr.SymUnit(symIdx)
-	if unit == nil {
-		unit = ctxt.runtimeCU
-	}
-	ver := d.ldr.SymVersion(symIdx)
-	dv := d.newdie(unit.DWInfo, dwarf.DW_ABRV_VARIABLE, str, int(ver))
-	d.newabslocexprattr(dv, v, symIdx)
-	if d.ldr.SymVersion(symIdx) < sym.SymVerStatic {
-		newattr(dv, dwarf.DW_AT_external, dwarf.DW_CLS_FLAG, 1, 0)
-	}
-	dt := d.defgotype(gotype)
-	d.newrefattr(dv, dwarf.DW_AT_type, dt)
-}
-
 // createUnitLength creates the initial length field with value v and update
 // offset of unit_length if needed.
 func (d *dwctxt) createUnitLength(su *loader.SymbolBuilder, v uint64) {
@@ -1454,7 +1430,7 @@
 		// Emit a FDE, Section 6.4.1.
 		// First build the section contents into a byte buffer.
 		deltaBuf = deltaBuf[:0]
-		if haslr && d.ldr.AttrTopFrame(fn) {
+		if haslr && fi.TopFrame() {
 			// Mark the link register as having an undefined value.
 			// This stops call stack unwinders progressing any further.
 			// TODO: similar mark on non-LR architectures.
@@ -1480,7 +1456,7 @@
 				spdelta += int64(d.arch.PtrSize)
 			}
 
-			if haslr && !d.ldr.AttrTopFrame(fn) {
+			if haslr && !fi.TopFrame() {
 				// TODO(bryanpkc): This is imprecise. In general, the instruction
 				// that stores the return address to the stack frame is not the
 				// same one that allocates the frame.
@@ -1552,7 +1528,7 @@
 
 func (d *dwctxt) writeUnitInfo(u *sym.CompilationUnit, abbrevsym loader.Sym, infoEpilog loader.Sym) []loader.Sym {
 	syms := []loader.Sym{}
-	if len(u.Textp) == 0 && u.DWInfo.Child == nil {
+	if len(u.Textp) == 0 && u.DWInfo.Child == nil && len(u.VarDIEs) == 0 {
 		return syms
 	}
 
@@ -1583,6 +1559,7 @@
 	if u.Consts != 0 {
 		cu = append(cu, loader.Sym(u.Consts))
 	}
+	cu = appendSyms(cu, u.VarDIEs)
 	var cusize int64
 	for _, child := range cu {
 		cusize += int64(len(d.ldr.Data(child)))
@@ -1867,7 +1844,7 @@
 			if producerExtra := d.ldr.Lookup(dwarf.CUInfoPrefix+"producer."+unit.Lib.Pkg, 0); producerExtra != 0 {
 				peData = d.ldr.Data(producerExtra)
 			}
-			producer := "Go cmd/compile " + objabi.Version
+			producer := "Go cmd/compile " + buildcfg.Version
 			if len(peData) > 0 {
 				// We put a semicolon before the flags to clearly
 				// separate them from the version, which can be long
@@ -1907,10 +1884,11 @@
 		checkStrictDups = 1
 	}
 
-	// Create DIEs for global variables and the types they use.
-	// FIXME: ideally this should be done in the compiler, since
-	// for globals there isn't any abiguity about which package
-	// a global belongs to.
+	// Make a pass through all data symbols, looking for those
+	// corresponding to reachable, Go-generated, user-visible
+	// global variables. For each global of this sort, locate
+	// the corresponding compiler-generated DIE symbol and tack
+	// it onto the list associated with the unit.
 	for idx := loader.Sym(1); idx < loader.Sym(d.ldr.NDef()); idx++ {
 		if !d.ldr.AttrReachable(idx) ||
 			d.ldr.AttrNotInSymbolTable(idx) ||
@@ -1925,7 +1903,8 @@
 			continue
 		}
 		// Skip things with no type
-		if d.ldr.SymGoType(idx) == 0 {
+		gt := d.ldr.SymGoType(idx)
+		if gt == 0 {
 			continue
 		}
 		// Skip file local symbols (this includes static tmps, stack
@@ -1939,10 +1918,20 @@
 			continue
 		}
 
-		// Create DIE for global.
-		sv := d.ldr.SymValue(idx)
-		gt := d.ldr.SymGoType(idx)
-		d.dwarfDefineGlobal(ctxt, idx, sn, sv, gt)
+		// Find compiler-generated DWARF info sym for global in question,
+		// and tack it onto the appropriate unit.  Note that there are
+		// circumstances under which we can't find the compiler-generated
+		// symbol-- this typically happens as a result of compiler options
+		// (e.g. compile package X with "-dwarf=0").
+
+		// FIXME: use an aux sym or a relocation here instead of a
+		// name lookup.
+		varDIE := d.ldr.Lookup(dwarf.InfoPrefix+sn, 0)
+		if varDIE != 0 {
+			unit := d.ldr.SymUnit(idx)
+			d.defgotype(gt)
+			unit.VarDIEs = append(unit.VarDIEs, sym.LoaderSym(varDIE))
+		}
 	}
 
 	d.synthesizestringtypes(ctxt, dwtypes.Child)
@@ -2302,12 +2291,6 @@
 	return dwsectCUSize[sname+"."+pkgname]
 }
 
-func saveDwsectCUSize(sname string, pkgname string, size uint64) {
-	dwsectCUSizeMu.Lock()
-	defer dwsectCUSizeMu.Unlock()
-	dwsectCUSize[sname+"."+pkgname] = size
-}
-
 func addDwsectCUSize(sname string, pkgname string, size uint64) {
 	dwsectCUSizeMu.Lock()
 	defer dwsectCUSizeMu.Unlock()
diff --git a/src/cmd/link/internal/ld/dwarf_test.go b/src/cmd/link/internal/ld/dwarf_test.go
index a66506d..2f59c2f 100644
--- a/src/cmd/link/internal/ld/dwarf_test.go
+++ b/src/cmd/link/internal/ld/dwarf_test.go
@@ -19,6 +19,7 @@
 	"path/filepath"
 	"reflect"
 	"runtime"
+	"sort"
 	"strconv"
 	"strings"
 	"testing"
@@ -39,11 +40,7 @@
 		t.Skip("skipping on plan9; no DWARF symbol table in executables")
 	}
 
-	dir, err := ioutil.TempDir("", "TestRuntimeTypesPresent")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	f := gobuild(t, dir, `package main; func main() { }`, NoOpt)
 	defer f.Close()
@@ -171,11 +168,7 @@
 		"main.Baz": {"Foo": true, "name": false},
 	}
 
-	dir, err := ioutil.TempDir("", "TestEmbeddedStructMarker")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	f := gobuild(t, dir, prog, NoOpt)
 
@@ -255,11 +248,8 @@
 	y[0] = nil
 }
 `
-	dir, err := ioutil.TempDir("", "TestSizes")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
+
 	f := gobuild(t, dir, prog, NoOpt)
 	defer f.Close()
 	d, err := f.DWARF()
@@ -303,11 +293,7 @@
 	c <- "foo"
 }
 `
-	dir, err := ioutil.TempDir("", "TestFieldOverlap")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	f := gobuild(t, dir, prog, NoOpt)
 	defer f.Close()
@@ -351,13 +337,10 @@
 
 	prog := fmt.Sprintf("package main\n%s\nfunc main() {\n\nvar i int\ni = i\n}\n", directive)
 
-	dir, err := ioutil.TempDir("", testpoint)
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	f := gobuild(t, dir, prog, NoOpt)
+	defer f.Close()
 
 	d, err := f.DWARF()
 	if err != nil {
@@ -628,8 +611,8 @@
 	if runtime.GOOS == "plan9" {
 		t.Skip("skipping on plan9; no DWARF symbol table in executables")
 	}
-	if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" || runtime.GOOS == "darwin" {
-		t.Skip("skipping on solaris, illumos, and darwin, pending resolution of issue #23168")
+	if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" {
+		t.Skip("skipping on solaris, illumos, pending resolution of issue #23168")
 	}
 
 	t.Parallel()
@@ -653,11 +636,7 @@
     G = x
 }
 `
-	dir, err := ioutil.TempDir("", "TestInlinedRoutineRecords")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	// 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
@@ -665,6 +644,7 @@
 	// main.main, however, hence we build with "-gcflags=-l=4" as opposed
 	// to "-gcflags=all=-l=4".
 	f := gobuild(t, dir, prog, OptInl4)
+	defer f.Close()
 
 	d, err := f.DWARF()
 	if err != nil {
@@ -788,14 +768,11 @@
 func abstractOriginSanity(t *testing.T, pkgDir string, flags string) {
 	t.Parallel()
 
-	dir, err := ioutil.TempDir("", "TestAbstractOriginSanity")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	// Build with inlining, to exercise DWARF inlining support.
 	f := gobuildTestdata(t, dir, filepath.Join(pkgDir, "main"), flags)
+	defer f.Close()
 
 	d, err := f.DWARF()
 	if err != nil {
@@ -871,8 +848,8 @@
 	if runtime.GOOS == "plan9" {
 		t.Skip("skipping on plan9; no DWARF symbol table in executables")
 	}
-	if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" || runtime.GOOS == "darwin" {
-		t.Skip("skipping on solaris, illumos, and darwin, pending resolution of issue #23168")
+	if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" {
+		t.Skip("skipping on solaris, illumos, pending resolution of issue #23168")
 	}
 
 	if wd, err := os.Getwd(); err == nil {
@@ -889,11 +866,11 @@
 	if runtime.GOOS == "plan9" {
 		t.Skip("skipping on plan9; no DWARF symbol table in executables")
 	}
-	if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" || runtime.GOOS == "darwin" {
-		t.Skip("skipping on solaris, illumos, and darwin, pending resolution of issue #23168")
+	if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" {
+		t.Skip("skipping on solaris, illumos, pending resolution of issue #23168")
 	}
-	if runtime.GOARCH != "amd64" && runtime.GOARCH != "x86" {
-		t.Skip("skipping on not-amd64 not-x86; location lists not supported")
+	if runtime.GOARCH != "amd64" && runtime.GOARCH != "386" {
+		t.Skip("skipping on not-amd64 not-386; location lists not supported")
 	}
 
 	if wd, err := os.Getwd(); err == nil {
@@ -910,8 +887,8 @@
 	if runtime.GOOS == "plan9" {
 		t.Skip("skipping on plan9; no DWARF symbol table in executables")
 	}
-	if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" || runtime.GOOS == "darwin" {
-		t.Skip("skipping on solaris, illumos, and darwin, pending resolution of issue #23168")
+	if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" {
+		t.Skip("skipping on solaris, illumos, pending resolution of issue #23168")
 	}
 	if wd, err := os.Getwd(); err == nil {
 		gopathdir := filepath.Join(wd, "testdata", "issue26237")
@@ -973,13 +950,11 @@
 	print(p)
 }
 `
-	dir, err := ioutil.TempDir("", "TestRuntimeType")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	f := gobuild(t, dir, prog, flags)
+	defer f.Close()
+
 	out, err := exec.Command(f.path).CombinedOutput()
 	if err != nil {
 		t.Fatalf("could not run test program: %v", err)
@@ -1043,11 +1018,7 @@
 
 	t.Parallel()
 
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	const prog = `package main
 
@@ -1161,11 +1132,7 @@
 
 	t.Parallel()
 
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	const prog = `package main
 
@@ -1243,11 +1210,7 @@
 
 	t.Parallel()
 
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	const prog = "package main\nfunc main() {\nprintln(\"hello world\")\n}\n"
 
@@ -1307,14 +1270,10 @@
 		t.Skip("skipping; test only interesting on darwin")
 	}
 
-	tmpdir, err := ioutil.TempDir("", "TestMachoIssue32233")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
-	wd, err2 := os.Getwd()
-	if err2 != nil {
+	wd, err := os.Getwd()
+	if err != nil {
 		t.Fatalf("where am I? %v", err)
 	}
 	pdir := filepath.Join(wd, "testdata", "issue32233", "main")
@@ -1328,11 +1287,7 @@
 		t.Skip("skipping: test only on windows")
 	}
 
-	dir, err := ioutil.TempDir("", "TestEmbeddedStructMarker")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	prog := `
 package main
@@ -1343,10 +1298,12 @@
   fmt.Println("Hello World")
 }`
 	f := gobuild(t, dir, prog, NoOpt)
+	defer f.Close()
 	exe, err := pe.Open(f.path)
 	if err != nil {
 		t.Fatalf("error opening pe file: %v", err)
 	}
+	defer exe.Close()
 	dw, err := exe.DWARF()
 	if err != nil {
 		t.Fatalf("error parsing DWARF: %v", err)
@@ -1397,17 +1354,14 @@
 
 	// Build a test program that contains a translation unit whose
 	// text (from am assembly source) contains only a single instruction.
-	tmpdir, err := ioutil.TempDir("", "TestIssue38192")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 	wd, err := os.Getwd()
 	if err != nil {
 		t.Fatalf("where am I? %v", err)
 	}
 	pdir := filepath.Join(wd, "testdata", "issue38192")
 	f := gobuildTestdata(t, tmpdir, pdir, DefaultOpt)
+	defer f.Close()
 
 	// Open the resulting binary and examine the DWARF it contains.
 	// Look for the function of interest ("main.singleInstruction")
@@ -1520,17 +1474,15 @@
 	// compiler/runtime in ways that aren't happening now, so this
 	// might be something to check for if it does start failing.
 
-	tmpdir, err := ioutil.TempDir("", "TestIssue38192")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
+
 	wd, err := os.Getwd()
 	if err != nil {
 		t.Fatalf("where am I? %v", err)
 	}
 	pdir := filepath.Join(wd, "testdata", "issue39757")
 	f := gobuildTestdata(t, tmpdir, pdir, DefaultOpt)
+	defer f.Close()
 
 	syms, err := f.Symbols()
 	if err != nil {
@@ -1619,3 +1571,187 @@
 		}
 	}
 }
+
+func TestIssue42484(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; no DWARF symbol table in executables")
+	}
+
+	t.Parallel()
+
+	tmpdir, err := ioutil.TempDir("", "TestIssue42484")
+	if err != nil {
+		t.Fatalf("could not create directory: %v", err)
+	}
+	defer os.RemoveAll(tmpdir)
+	wd, err := os.Getwd()
+	if err != nil {
+		t.Fatalf("where am I? %v", err)
+	}
+	pdir := filepath.Join(wd, "testdata", "issue42484")
+	f := gobuildTestdata(t, tmpdir, pdir, NoOpt)
+
+	var lastAddr uint64
+	var lastFile string
+	var lastLine int
+
+	dw, err := f.DWARF()
+	if err != nil {
+		t.Fatalf("error parsing DWARF: %v", err)
+	}
+	rdr := dw.Reader()
+	for {
+		e, err := rdr.Next()
+		if err != nil {
+			t.Fatalf("error reading DWARF: %v", err)
+		}
+		if e == nil {
+			break
+		}
+		if e.Tag != dwarf.TagCompileUnit {
+			continue
+		}
+		lnrdr, err := dw.LineReader(e)
+		if err != nil {
+			t.Fatalf("error creating DWARF line reader: %v", err)
+		}
+		if lnrdr != nil {
+			var lne dwarf.LineEntry
+			for {
+				err := lnrdr.Next(&lne)
+				if err == io.EOF {
+					break
+				}
+				if err != nil {
+					t.Fatalf("error reading next DWARF line: %v", err)
+				}
+				if lne.EndSequence {
+					continue
+				}
+				if lne.Address == lastAddr && (lne.File.Name != lastFile || lne.Line != lastLine) {
+					t.Errorf("address %#x is assigned to both %s:%d and %s:%d", lastAddr, lastFile, lastLine, lne.File.Name, lne.Line)
+				}
+				lastAddr = lne.Address
+				lastFile = lne.File.Name
+				lastLine = lne.Line
+			}
+		}
+		rdr.SkipChildren()
+	}
+	f.Close()
+}
+
+func TestOutputParamAbbrevAndAttr(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; no DWARF symbol table in executables")
+	}
+	t.Parallel()
+
+	// This test verifies that the compiler is selecting the correct
+	// DWARF abbreviation for output parameters, and that the
+	// variable parameter attribute is correct for in-params and
+	// out-params.
+
+	const prog = `
+package main
+
+//go:noinline
+func ABC(c1, c2, c3 int, d1, d2, d3, d4 string, f1, f2, f3 float32, g1 [1024]int) (r1 int, r2 int, r3 [1024]int, r4 byte, r5 string, r6 float32) {
+	g1[0] = 6
+	r1, r2, r3, r4, r5, r6 = c3, c2+c1, g1, 'a', d1+d2+d3+d4, f1+f2+f3
+	return
+}
+
+func main() {
+	a := [1024]int{}
+	v1, v2, v3, v4, v5, v6 := ABC(1, 2, 3, "a", "b", "c", "d", 1.0, 2.0, 1.0, a)
+	println(v1, v2, v3[0], v4, v5, v6)
+}
+`
+	dir := t.TempDir()
+	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()
+	ex := examiner{}
+	if err := ex.populate(rdr); err != nil {
+		t.Fatalf("error reading DWARF: %v", err)
+	}
+
+	// Locate the main.ABC DIE
+	abcs := ex.Named("main.ABC")
+	if len(abcs) == 0 {
+		t.Fatalf("unable to locate DIE for main.ABC")
+	}
+	if len(abcs) != 1 {
+		t.Fatalf("more than one main.ABC DIE")
+	}
+	abcdie := abcs[0]
+
+	// Vet the DIE
+	if abcdie.Tag != dwarf.TagSubprogram {
+		t.Fatalf("unexpected tag %v on main.ABC DIE", abcdie.Tag)
+	}
+
+	// A setting of DW_AT_variable_parameter indicates that the
+	// param in question is an output parameter; we want to see this
+	// attribute set to TRUE for all Go return params. It would be
+	// OK to have it missing for input parameters, but for the moment
+	// we verify that the attr is present but set to false.
+
+	// Values in this map are of the form <order>:<varparam>
+	// where order is the order within the child DIE list of the param,
+	// and <varparam> is an integer:
+	//
+	//  -1: varparm attr not found
+	//   1: varparm found with value false
+	//   2: varparm found with value true
+	//
+	foundParams := make(map[string]string)
+
+	// Walk ABCs's children looking for params.
+	abcIdx := ex.idxFromOffset(abcdie.Offset)
+	childDies := ex.Children(abcIdx)
+	idx := 0
+	for _, child := range childDies {
+		if child.Tag == dwarf.TagFormalParameter {
+			st := -1
+			if vp, ok := child.Val(dwarf.AttrVarParam).(bool); ok {
+				if vp {
+					st = 2
+				} else {
+					st = 1
+				}
+			}
+			if name, ok := child.Val(dwarf.AttrName).(string); ok {
+				foundParams[name] = fmt.Sprintf("%d:%d", idx, st)
+				idx++
+			}
+		}
+	}
+
+	// Digest the result.
+	found := make([]string, 0, len(foundParams))
+	for k, v := range foundParams {
+		found = append(found, fmt.Sprintf("%s:%s", k, v))
+	}
+	sort.Strings(found)
+
+	// Make sure we see all of the expected params in the proper
+	// order, that they have the varparam attr, and the varparm is set
+	// for the returns.
+	expected := "[c1:0:1 c2:1:1 c3:2:1 d1:3:1 d2:4:1 d3:5:1 d4:6:1 f1:7:1 f2:8:1 f3:9:1 g1:10:1 r1:11:2 r2:12:2 r3:13:2 r4:14:2 r5:15:2 r6:16:2]"
+	if fmt.Sprintf("%+v", found) != expected {
+		t.Errorf("param check failed, wanted %s got %s\n",
+			expected, found)
+	}
+}
diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go
index 37b2dc6..8101163 100644
--- a/src/cmd/link/internal/ld/elf.go
+++ b/src/cmd/link/internal/ld/elf.go
@@ -14,6 +14,7 @@
 	"encoding/binary"
 	"encoding/hex"
 	"fmt"
+	"internal/buildcfg"
 	"path/filepath"
 	"sort"
 	"strings"
@@ -519,6 +520,90 @@
 	return int(sh.Size)
 }
 
+// member of .gnu.attributes of MIPS for fpAbi
+const (
+	// No floating point is present in the module (default)
+	MIPS_FPABI_NONE = 0
+	// FP code in the module uses the FP32 ABI for a 32-bit ABI
+	MIPS_FPABI_ANY = 1
+	// FP code in the module only uses single precision ABI
+	MIPS_FPABI_SINGLE = 2
+	// FP code in the module uses soft-float ABI
+	MIPS_FPABI_SOFT = 3
+	// FP code in the module assumes an FPU with FR=1 and has 12
+	// callee-saved doubles. Historic, no longer supported.
+	MIPS_FPABI_HIST = 4
+	// FP code in the module uses the FPXX  ABI
+	MIPS_FPABI_FPXX = 5
+	// FP code in the module uses the FP64  ABI
+	MIPS_FPABI_FP64 = 6
+	// FP code in the module uses the FP64A ABI
+	MIPS_FPABI_FP64A = 7
+)
+
+func elfMipsAbiFlags(sh *ElfShdr, startva uint64, resoff uint64) int {
+	n := 24
+	sh.Addr = startva + resoff - uint64(n)
+	sh.Off = resoff - uint64(n)
+	sh.Size = uint64(n)
+	sh.Type = uint32(elf.SHT_MIPS_ABIFLAGS)
+	sh.Flags = uint64(elf.SHF_ALLOC)
+
+	return n
+}
+
+//typedef struct
+//{
+//  /* Version of flags structure.  */
+//  uint16_t version;
+//  /* The level of the ISA: 1-5, 32, 64.  */
+//  uint8_t isa_level;
+//  /* The revision of ISA: 0 for MIPS V and below, 1-n otherwise.  */
+//  uint8_t isa_rev;
+//  /* The size of general purpose registers.  */
+//  uint8_t gpr_size;
+//  /* The size of co-processor 1 registers.  */
+//  uint8_t cpr1_size;
+//  /* The size of co-processor 2 registers.  */
+//  uint8_t cpr2_size;
+//  /* The floating-point ABI.  */
+//  uint8_t fp_abi;
+//  /* Processor-specific extension.  */
+//  uint32_t isa_ext;
+//  /* Mask of ASEs used.  */
+//  uint32_t ases;
+//  /* Mask of general flags.  */
+//  uint32_t flags1;
+//  uint32_t flags2;
+//} Elf_Internal_ABIFlags_v0;
+func elfWriteMipsAbiFlags(ctxt *Link) int {
+	sh := elfshname(".MIPS.abiflags")
+	ctxt.Out.SeekSet(int64(sh.Off))
+	ctxt.Out.Write16(0) // version
+	ctxt.Out.Write8(32) // isaLevel
+	ctxt.Out.Write8(1)  // isaRev
+	ctxt.Out.Write8(1)  // gprSize
+	ctxt.Out.Write8(1)  // cpr1Size
+	ctxt.Out.Write8(0)  // cpr2Size
+	if buildcfg.GOMIPS == "softfloat" {
+		ctxt.Out.Write8(MIPS_FPABI_SOFT) // fpAbi
+	} else {
+		// Go cannot make sure non odd-number-fpr is used (ie, in load a double from memory).
+		// So, we mark the object is MIPS I style paired float/double register scheme,
+		// aka MIPS_FPABI_ANY. If we mark the object as FPXX, the kernel may use FR=1 mode,
+		// then we meet some problem.
+		// Note: MIPS_FPABI_ANY is bad naming: in fact it is MIPS I style FPR usage.
+		//       It is not for 'ANY'.
+		// TODO: switch to FPXX after be sure that no odd-number-fpr is used.
+		ctxt.Out.Write8(MIPS_FPABI_ANY) // fpAbi
+	}
+	ctxt.Out.Write32(0) // isaExt
+	ctxt.Out.Write32(0) // ases
+	ctxt.Out.Write32(0) // flags1
+	ctxt.Out.Write32(0) // flags2
+	return int(sh.Size)
+}
+
 func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int) int {
 	n := 3*4 + uint64(sz) + resoff%4
 
@@ -865,6 +950,11 @@
 	}
 
 	s = ldr.CreateSymForUpdate(".dynamic", 0)
+	if ctxt.BuildMode == BuildModePIE {
+		// https://github.com/bminor/glibc/blob/895ef79e04a953cac1493863bcae29ad85657ee1/elf/elf.h#L986
+		const DTFLAGS_1_PIE = 0x08000000
+		Elfwritedynent(ctxt.Arch, s, elf.DT_FLAGS_1, uint64(DTFLAGS_1_PIE))
+	}
 	elfverneed = nfile
 	if elfverneed != 0 {
 		elfWriteDynEntSym(ctxt, s, elf.DT_VERNEED, gnuVersionR.Sym())
@@ -1086,7 +1176,7 @@
 		}
 	}
 
-	eaddr := int32(sect.Vaddr + sect.Length)
+	eaddr := sect.Vaddr + sect.Length
 	for _, s := range syms {
 		if !ldr.AttrReachable(s) {
 			continue
@@ -1204,6 +1294,10 @@
 	shstrtab.Addstring(".noptrbss")
 	shstrtab.Addstring("__libfuzzer_extra_counters")
 	shstrtab.Addstring(".go.buildinfo")
+	if ctxt.IsMIPS() {
+		shstrtab.Addstring(".MIPS.abiflags")
+		shstrtab.Addstring(".gnu.attributes")
+	}
 
 	// generate .tbss section for dynamic internal linker or external
 	// linking, so that various binutils could correctly calculate
@@ -1254,6 +1348,10 @@
 			shstrtab.Addstring(elfRelType + ".data.rel.ro")
 		}
 		shstrtab.Addstring(elfRelType + ".go.buildinfo")
+		if ctxt.IsMIPS() {
+			shstrtab.Addstring(elfRelType + ".MIPS.abiflags")
+			shstrtab.Addstring(elfRelType + ".gnu.attributes")
+		}
 
 		// add a .note.GNU-stack section to mark the stack as non-executable
 		shstrtab.Addstring(".note.GNU-stack")
@@ -1445,6 +1543,35 @@
 	if ctxt.LinkMode == LinkExternal && *flagBuildid != "" {
 		addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(*flagBuildid))
 	}
+
+	//type mipsGnuAttributes struct {
+	//	version uint8   // 'A'
+	//	length  uint32  // 15 including itself
+	//	gnu     [4]byte // "gnu\0"
+	//	tag     uint8   // 1:file, 2: section, 3: symbol, 1 here
+	//	taglen  uint32  // tag length, including tag, 7 here
+	//	tagfp   uint8   // 4
+	//	fpAbi  uint8    // see .MIPS.abiflags
+	//}
+	if ctxt.IsMIPS() {
+		gnuattributes := ldr.CreateSymForUpdate(".gnu.attributes", 0)
+		gnuattributes.SetType(sym.SELFROSECT)
+		gnuattributes.SetReachable(true)
+		gnuattributes.AddUint8('A')               // version 'A'
+		gnuattributes.AddUint32(ctxt.Arch, 15)    // length 15 including itself
+		gnuattributes.AddBytes([]byte("gnu\x00")) // "gnu\0"
+		gnuattributes.AddUint8(1)                 // 1:file, 2: section, 3: symbol, 1 here
+		gnuattributes.AddUint32(ctxt.Arch, 7)     // tag length, including tag, 7 here
+		gnuattributes.AddUint8(4)                 // 4 for FP, 8 for MSA
+		if buildcfg.GOMIPS == "softfloat" {
+			gnuattributes.AddUint8(MIPS_FPABI_SOFT)
+		} else {
+			// Note: MIPS_FPABI_ANY is bad naming: in fact it is MIPS I style FPR usage.
+			//       It is not for 'ANY'.
+			// TODO: switch to FPXX after be sure that no odd-number-fpr is used.
+			gnuattributes.AddUint8(MIPS_FPABI_ANY)
+		}
+	}
 }
 
 // Do not write DT_NULL.  elfdynhash will finish it.
@@ -1622,14 +1749,14 @@
 		sh.Flags = uint64(elf.SHF_ALLOC)
 		sh.Addralign = 1
 
-		if interpreter == "" && objabi.GO_LDSO != "" {
-			interpreter = objabi.GO_LDSO
+		if interpreter == "" && buildcfg.GO_LDSO != "" {
+			interpreter = buildcfg.GO_LDSO
 		}
 
 		if interpreter == "" {
 			switch ctxt.HeadType {
 			case objabi.Hlinux:
-				if objabi.GOOS == "android" {
+				if buildcfg.GOOS == "android" {
 					interpreter = thearch.Androiddynld
 					if interpreter == "" {
 						Exitf("ELF interpreter not set")
@@ -1910,6 +2037,25 @@
 	shsym(sh, ldr, ldr.Lookup(".shstrtab", 0))
 	eh.Shstrndx = uint16(sh.shnum)
 
+	if ctxt.IsMIPS() {
+		sh = elfshname(".MIPS.abiflags")
+		sh.Type = uint32(elf.SHT_MIPS_ABIFLAGS)
+		sh.Flags = uint64(elf.SHF_ALLOC)
+		sh.Addralign = 8
+		resoff -= int64(elfMipsAbiFlags(sh, uint64(startva), uint64(resoff)))
+
+		ph := newElfPhdr()
+		ph.Type = elf.PT_MIPS_ABIFLAGS
+		ph.Flags = elf.PF_R
+		phsh(ph, sh)
+
+		sh = elfshname(".gnu.attributes")
+		sh.Type = uint32(elf.SHT_GNU_ATTRIBUTES)
+		sh.Addralign = 1
+		ldr := ctxt.loader
+		shsym(sh, ldr, ldr.Lookup(".gnu.attributes", 0))
+	}
+
 	// put these sections early in the list
 	if !*FlagS {
 		elfshname(".symtab")
@@ -2029,6 +2175,10 @@
 	if !*FlagD {
 		a += int64(elfwriteinterp(ctxt.Out))
 	}
+	if ctxt.IsMIPS() {
+		a += int64(elfWriteMipsAbiFlags(ctxt))
+	}
+
 	if ctxt.LinkMode != LinkExternal {
 		if ctxt.HeadType == objabi.Hnetbsd {
 			a += int64(elfwritenetbsdsig(ctxt.Out))
@@ -2050,6 +2200,12 @@
 	if a > elfreserve {
 		Errorf(nil, "ELFRESERVE too small: %d > %d with %d text sections", a, elfreserve, numtext)
 	}
+
+	// Verify the amount of space allocated for the elf header is sufficient.  The file offsets are
+	// already computed in layout, so we could spill into another section.
+	if a > int64(HEADR) {
+		Errorf(nil, "HEADR too small: %d > %d with %d text sections", a, HEADR, numtext)
+	}
 }
 
 func elfadddynsym(ldr *loader.Loader, target *Target, syms *ArchSyms, s loader.Sym) {
diff --git a/src/cmd/link/internal/ld/elf_test.go b/src/cmd/link/internal/ld/elf_test.go
index 776fc1b..d86ebb8 100644
--- a/src/cmd/link/internal/ld/elf_test.go
+++ b/src/cmd/link/internal/ld/elf_test.go
@@ -1,3 +1,4 @@
+//go:build cgo
 // +build cgo
 
 // Copyright 2019 The Go Authors. All rights reserved.
@@ -21,11 +22,7 @@
 func TestDynSymShInfo(t *testing.T) {
 	t.Parallel()
 	testenv.MustHaveGoBuild(t)
-	dir, err := ioutil.TempDir("", "go-build-issue33358")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	const prog = `
 package main
@@ -51,6 +48,7 @@
 	if err != nil {
 		t.Fatalf("failed to open built file: %v", err)
 	}
+	defer fi.Close()
 
 	elfFile, err := elf.NewFile(fi)
 	if err != nil {
@@ -95,11 +93,7 @@
 
 	t.Parallel()
 
-	dir, err := ioutil.TempDir("", "no-dup-needed")
-	if err != nil {
-		t.Fatalf("Failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	wd, err := os.Getwd()
 	if err != nil {
diff --git a/src/cmd/link/internal/ld/execarchive.go b/src/cmd/link/internal/ld/execarchive.go
index 4687c62..918b86c 100644
--- a/src/cmd/link/internal/ld/execarchive.go
+++ b/src/cmd/link/internal/ld/execarchive.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !wasm && !windows
 // +build !wasm,!windows
 
 package ld
diff --git a/src/cmd/link/internal/ld/execarchive_noexec.go b/src/cmd/link/internal/ld/execarchive_noexec.go
index a70dea9..5e1f266 100644
--- a/src/cmd/link/internal/ld/execarchive_noexec.go
+++ b/src/cmd/link/internal/ld/execarchive_noexec.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build wasm || windows
 // +build wasm windows
 
 package ld
diff --git a/src/cmd/link/internal/ld/fallocate_test.go b/src/cmd/link/internal/ld/fallocate_test.go
index 244b70f..1ed0eb2 100644
--- a/src/cmd/link/internal/ld/fallocate_test.go
+++ b/src/cmd/link/internal/ld/fallocate_test.go
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || linux
 // +build darwin linux
 
 package ld
 
 import (
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"syscall"
@@ -15,14 +15,10 @@
 )
 
 func TestFallocate(t *testing.T) {
-	dir, err := ioutil.TempDir("", "TestFallocate")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 	filename := filepath.Join(dir, "a.out")
 	out := NewOutBuf(nil)
-	err = out.Open(filename)
+	err := out.Open(filename)
 	if err != nil {
 		t.Fatalf("Open file failed: %v", err)
 	}
diff --git a/src/cmd/link/internal/ld/go.go b/src/cmd/link/internal/ld/go.go
index fbc7a78..fc63b30 100644
--- a/src/cmd/link/internal/ld/go.go
+++ b/src/cmd/link/internal/ld/go.go
@@ -9,6 +9,7 @@
 import (
 	"bytes"
 	"cmd/internal/bio"
+	"cmd/internal/obj"
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"cmd/link/internal/loader"
@@ -101,36 +102,13 @@
 		return
 	}
 
-	// Find cgo_export symbols. They are roots in the deadcode pass.
-	for _, f := range directives {
-		switch f[0] {
-		case "cgo_export_static", "cgo_export_dynamic":
-			if len(f) < 2 || len(f) > 3 {
-				continue
-			}
-			local := f[1]
-			switch ctxt.BuildMode {
-			case BuildModeCShared, BuildModeCArchive, BuildModePlugin:
-				if local == "main" {
-					continue
-				}
-			}
-			local = expandpkg(local, pkg)
-			if f[0] == "cgo_export_static" {
-				ctxt.cgo_export_static[local] = true
-			} else {
-				ctxt.cgo_export_dynamic[local] = true
-			}
-		}
-	}
-
 	// Record the directives. We'll process them later after Symbols are created.
 	ctxt.cgodata = append(ctxt.cgodata, cgodata{file, pkg, directives})
 }
 
 // Set symbol attributes or flags based on cgo directives.
 // Any newly discovered HOSTOBJ syms are added to 'hostObjSyms'.
-func setCgoAttr(ctxt *Link, lookup func(string, int) loader.Sym, file string, pkg string, directives [][]string, hostObjSyms map[loader.Sym]struct{}) {
+func setCgoAttr(ctxt *Link, file string, pkg string, directives [][]string, hostObjSyms map[loader.Sym]struct{}) {
 	l := ctxt.loader
 	for _, f := range directives {
 		switch f[0] {
@@ -173,7 +151,7 @@
 			if i := strings.Index(remote, "#"); i >= 0 {
 				remote, q = remote[:i], remote[i+1:]
 			}
-			s := lookup(local, 0)
+			s := l.LookupOrCreateSym(local, 0)
 			st := l.SymType(s)
 			if st == 0 || st == sym.SXREF || st == sym.SBSS || st == sym.SNOPTRBSS || st == sym.SHOSTOBJ {
 				l.SetSymDynimplib(s, lib)
@@ -199,7 +177,7 @@
 			}
 			local := f[1]
 
-			s := lookup(local, 0)
+			s := l.LookupOrCreateSym(local, 0)
 			su := l.MakeSymbolUpdater(s)
 			su.SetType(sym.SHOSTOBJ)
 			su.SetSize(0)
@@ -207,7 +185,7 @@
 			continue
 
 		case "cgo_export_static", "cgo_export_dynamic":
-			if len(f) < 2 || len(f) > 3 {
+			if len(f) < 2 || len(f) > 4 {
 				break
 			}
 			local := f[1]
@@ -216,13 +194,20 @@
 				remote = f[2]
 			}
 			local = expandpkg(local, pkg)
+			// The compiler adds a fourth argument giving
+			// the definition ABI of function symbols.
+			abi := obj.ABI0
+			if len(f) > 3 {
+				var ok bool
+				abi, ok = obj.ParseABI(f[3])
+				if !ok {
+					fmt.Fprintf(os.Stderr, "%s: bad ABI in cgo_export directive %s\n", os.Args[0], f)
+					nerrors++
+					return
+				}
+			}
 
-			// The compiler arranges for an ABI0 wrapper
-			// to be available for all cgo-exported
-			// functions. Link.loadlib will resolve any
-			// ABI aliases we find here (since we may not
-			// yet know it's an alias).
-			s := lookup(local, 0)
+			s := l.LookupOrCreateSym(local, sym.ABIToVersion(abi))
 
 			if l.SymType(s) == sym.SHOSTOBJ {
 				hostObjSyms[s] = struct{}{}
@@ -230,7 +215,7 @@
 
 			switch ctxt.BuildMode {
 			case BuildModeCShared, BuildModeCArchive, BuildModePlugin:
-				if s == lookup("main", 0) {
+				if s == l.Lookup("main", 0) {
 					continue
 				}
 			}
@@ -254,11 +239,32 @@
 				return
 			}
 
+			// Mark exported symbols and also add them to
+			// the lists used for roots in the deadcode pass.
 			if f[0] == "cgo_export_static" {
+				if ctxt.LinkMode == LinkExternal && !l.AttrCgoExportStatic(s) {
+					// Static cgo exports appear
+					// in the exported symbol table.
+					ctxt.dynexp = append(ctxt.dynexp, s)
+				}
+				if ctxt.LinkMode == LinkInternal {
+					// For internal linking, we're
+					// responsible for resolving
+					// relocations from host objects.
+					// Record the right Go symbol
+					// version to use.
+					l.AddCgoExport(s)
+				}
 				l.SetAttrCgoExportStatic(s, true)
 			} else {
+				if ctxt.LinkMode == LinkInternal && !l.AttrCgoExportDynamic(s) {
+					// Dynamic cgo exports appear
+					// in the exported symbol table.
+					ctxt.dynexp = append(ctxt.dynexp, s)
+				}
 				l.SetAttrCgoExportDynamic(s, true)
 			}
+
 			continue
 
 		case "cgo_dynamic_linker":
@@ -440,9 +446,16 @@
 		return
 	}
 
-	for _, exp := range ctxt.dynexp {
-		Adddynsym(ctxt.loader, &ctxt.Target, &ctxt.ArchSyms, exp)
+	// Add dynamic symbols.
+	for _, s := range ctxt.dynexp {
+		// Consistency check.
+		if !ctxt.loader.AttrReachable(s) {
+			panic("dynexp entry not reachable")
+		}
+
+		Adddynsym(ctxt.loader, &ctxt.Target, &ctxt.ArchSyms, s)
 	}
+
 	for _, lib := range dedupLibraries(ctxt, dynlib) {
 		adddynlib(ctxt, lib)
 	}
diff --git a/src/cmd/link/internal/ld/go_test.go b/src/cmd/link/internal/ld/go_test.go
index 0197196..230f85a 100644
--- a/src/cmd/link/internal/ld/go_test.go
+++ b/src/cmd/link/internal/ld/go_test.go
@@ -8,7 +8,6 @@
 	"cmd/internal/objabi"
 	"internal/testenv"
 	"io/ioutil"
-	"os"
 	"os/exec"
 	"path/filepath"
 	"reflect"
@@ -86,11 +85,7 @@
 	testenv.MustHaveCGO(t)
 	t.Parallel()
 
-	dir, err := ioutil.TempDir("", "dedup-build")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	// cgo_import_dynamic both the unversioned libraries and pull in the
 	// net package to get a cgo package with a versioned library.
diff --git a/src/cmd/link/internal/ld/issue33808_test.go b/src/cmd/link/internal/ld/issue33808_test.go
index 92a47fa..43f4540 100644
--- a/src/cmd/link/internal/ld/issue33808_test.go
+++ b/src/cmd/link/internal/ld/issue33808_test.go
@@ -6,8 +6,6 @@
 
 import (
 	"internal/testenv"
-	"io/ioutil"
-	"os"
 	"runtime"
 	"strings"
 	"testing"
@@ -31,11 +29,7 @@
 	testenv.MustHaveCGO(t)
 	t.Parallel()
 
-	dir, err := ioutil.TempDir("", "TestIssue33808")
-	if err != nil {
-		t.Fatalf("could not create directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	f := gobuild(t, dir, prog, "-ldflags=-linkmode=external")
 	f.Close()
diff --git a/src/cmd/link/internal/ld/ld_test.go b/src/cmd/link/internal/ld/ld_test.go
index cdfaadb..3702a4d 100644
--- a/src/cmd/link/internal/ld/ld_test.go
+++ b/src/cmd/link/internal/ld/ld_test.go
@@ -9,7 +9,6 @@
 	"fmt"
 	"internal/testenv"
 	"io/ioutil"
-	"os"
 	"os/exec"
 	"path/filepath"
 	"runtime"
@@ -25,11 +24,6 @@
 	testenv.MustInternalLink(t)
 
 	t.Parallel()
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
 
 	out, err := exec.Command(testenv.GoToolPath(t), "build", "./testdata/issue10978").CombinedOutput()
 	if err == nil {
@@ -108,11 +102,7 @@
 	case "openbsd", "windows":
 		t.Skip("c-archive unsupported")
 	}
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	srcfile := filepath.Join(dir, "test.go")
 	arfile := filepath.Join(dir, "test.a")
@@ -141,34 +131,36 @@
 	}
 }
 
-func TestPPC64LargeTextSectionSplitting(t *testing.T) {
-	// The behavior we're checking for is of interest only on ppc64.
-	if !strings.HasPrefix(runtime.GOARCH, "ppc64") {
-		t.Skip("test useful only for ppc64")
+func TestLargeTextSectionSplitting(t *testing.T) {
+	switch runtime.GOARCH {
+	case "ppc64", "ppc64le":
+	case "arm64":
+		if runtime.GOOS == "darwin" {
+			break
+		}
+		fallthrough
+	default:
+		t.Skipf("text section splitting is not done in %s/%s", runtime.GOOS, runtime.GOARCH)
 	}
 
 	testenv.MustHaveGoBuild(t)
 	testenv.MustHaveCGO(t)
 	t.Parallel()
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
-	// NB: the use of -ldflags=-debugppc64textsize=1048576 tells the linker to
+	// NB: the use of -ldflags=-debugtextsize=1048576 tells the linker to
 	// split text sections at a size threshold of 1M instead of the
-	// architected limit of 67M. The choice of building cmd/go is
-	// arbitrary; we just need something sufficiently large that uses
+	// architected limit of 67M or larger. The choice of building cmd/go
+	// is arbitrary; we just need something sufficiently large that uses
 	// external linking.
 	exe := filepath.Join(dir, "go.exe")
-	out, eerr := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, "-ldflags=-linkmode=external -debugppc64textsize=1048576", "cmd/go").CombinedOutput()
+	out, eerr := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, "-ldflags=-linkmode=external -debugtextsize=1048576", "cmd/go").CombinedOutput()
 	if eerr != nil {
 		t.Fatalf("build failure: %s\n%s\n", eerr, string(out))
 	}
 
 	// Result should be runnable.
-	_, err = exec.Command(exe, "version").CombinedOutput()
+	_, err := exec.Command(exe, "version").CombinedOutput()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -182,6 +174,8 @@
 		t.Skip("skipping windows amd64/386 only test")
 	}
 
+	testenv.MustHaveCGO(t)
+
 	t.Run("aslr", func(t *testing.T) {
 		testWindowsBuildmodeCSharedASLR(t, true)
 	})
@@ -194,11 +188,7 @@
 	t.Parallel()
 	testenv.MustHaveGoBuild(t)
 
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	srcfile := filepath.Join(dir, "test.go")
 	objfile := filepath.Join(dir, "test.dll")
@@ -242,3 +232,103 @@
 		t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag should not be set")
 	}
 }
+
+// TestMemProfileCheck tests that cmd/link sets
+// runtime.disableMemoryProfiling if the runtime.MemProfile
+// symbol is unreachable after deadcode (and not dynlinking).
+// The runtime then uses that to set the default value of
+// runtime.MemProfileRate, which this test checks.
+func TestMemProfileCheck(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+	t.Parallel()
+
+	tests := []struct {
+		name    string
+		prog    string
+		wantOut string
+	}{
+		{
+			"no_memprofile",
+			`
+package main
+import "runtime"
+func main() {
+	println(runtime.MemProfileRate)
+}
+`,
+			"0",
+		},
+		{
+			"with_memprofile",
+			`
+package main
+import "runtime"
+func main() {
+	runtime.MemProfile(nil, false)
+	println(runtime.MemProfileRate)
+}
+`,
+			"524288",
+		},
+		{
+			"with_memprofile_indirect",
+			`
+package main
+import "runtime"
+var f = runtime.MemProfile
+func main() {
+	if f == nil {
+		panic("no f")
+	}
+	println(runtime.MemProfileRate)
+}
+`,
+			"524288",
+		},
+		{
+			"with_memprofile_runtime_pprof",
+			`
+package main
+import "runtime"
+import "runtime/pprof"
+func main() {
+        _ = pprof.Profiles()
+	println(runtime.MemProfileRate)
+}
+`,
+			"524288",
+		},
+		{
+			"with_memprofile_http_pprof",
+			`
+package main
+import "runtime"
+import _ "net/http/pprof"
+func main() {
+	println(runtime.MemProfileRate)
+}
+`,
+			"524288",
+		},
+	}
+	for _, tt := range tests {
+		tt := tt
+		t.Run(tt.name, func(t *testing.T) {
+			t.Parallel()
+			tempDir := t.TempDir()
+			src := filepath.Join(tempDir, "x.go")
+			if err := ioutil.WriteFile(src, []byte(tt.prog), 0644); err != nil {
+				t.Fatal(err)
+			}
+			cmd := exec.Command(testenv.GoToolPath(t), "run", src)
+			out, err := cmd.CombinedOutput()
+			if err != nil {
+				t.Fatal(err)
+			}
+			got := strings.TrimSpace(string(out))
+			if got != tt.wantOut {
+				t.Errorf("got %q; want %q", got, tt.wantOut)
+			}
+		})
+	}
+}
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 17d5040..644faeb 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -49,6 +49,7 @@
 	"encoding/base64"
 	"encoding/binary"
 	"fmt"
+	"internal/buildcfg"
 	exec "internal/execabs"
 	"io"
 	"io/ioutil"
@@ -56,7 +57,6 @@
 	"os"
 	"path/filepath"
 	"runtime"
-	"sort"
 	"strings"
 	"sync"
 )
@@ -118,6 +118,8 @@
 	Dynamic loader.Sym
 	DynSym  loader.Sym
 	DynStr  loader.Sym
+
+	unreachableMethod loader.Sym
 }
 
 // mkArchSym is a helper for setArchSyms, to set up a special symbol.
@@ -142,6 +144,7 @@
 	ctxt.mkArchSym(".dynamic", 0, &ctxt.Dynamic)
 	ctxt.mkArchSym(".dynsym", 0, &ctxt.DynSym)
 	ctxt.mkArchSym(".dynstr", 0, &ctxt.DynStr)
+	ctxt.mkArchSym("runtime.unreachableMethod", sym.SymVerABIInternal, &ctxt.unreachableMethod)
 
 	if ctxt.IsPPC64() {
 		ctxt.mkArchSym("TOC", 0, &ctxt.TOC)
@@ -174,11 +177,18 @@
 }
 
 type Arch struct {
-	Funcalign      int
-	Maxalign       int
-	Minalign       int
-	Dwarfregsp     int
-	Dwarfreglr     int
+	Funcalign  int
+	Maxalign   int
+	Minalign   int
+	Dwarfregsp int
+	Dwarfreglr int
+
+	// Threshold of total text size, used for trampoline insertion. If the total
+	// text size is smaller than TrampLimit, we won't need to insert trampolines.
+	// It is pretty close to the offset range of a direct CALL machine instruction.
+	// We leave some room for extra stuff like PLT stubs.
+	TrampLimit uint64
+
 	Androiddynld   string
 	Linuxdynld     string
 	Freebsddynld   string
@@ -193,9 +203,6 @@
 	// are padded with zeros.
 	CodePad []byte
 
-	// Set to true to write all text blocks in with CodeBlkWrite
-	WriteTextBlocks bool
-
 	// Plan 9 variables.
 	Plan9Magic  uint32
 	Plan9_64Bit bool
@@ -223,7 +230,7 @@
 	// to-be-relocated data item (from sym.P). Return is an updated
 	// offset value.
 	Archrelocvariant func(target *Target, ldr *loader.Loader, rel loader.Reloc,
-		rv sym.RelocVariant, sym loader.Sym, offset int64) (relocatedOffset int64)
+		rv sym.RelocVariant, sym loader.Sym, offset int64, data []byte) (relocatedOffset int64)
 
 	// Generate a trampoline for a call from s to rs if necessary. ri is
 	// index of the relocation.
@@ -336,10 +343,16 @@
 const pkgdef = "__.PKGDEF"
 
 var (
-	// Set if we see an object compiled by the host compiler that is not
-	// from a package that is known to support internal linking mode.
+	// externalobj is set to true if we see an object compiled by
+	// the host compiler that is not from a package that is known
+	// to support internal linking mode.
 	externalobj = false
-	theline     string
+
+	// unknownObjFormat is set to true if we see an object whose
+	// format we don't recognize.
+	unknownObjFormat = false
+
+	theline string
 )
 
 func Lflag(ctxt *Link, arg string) {
@@ -377,7 +390,7 @@
 		suffix = "msan"
 	}
 
-	Lflag(ctxt, filepath.Join(objabi.GOROOT, "pkg", fmt.Sprintf("%s_%s%s%s", objabi.GOOS, objabi.GOARCH, suffixsep, suffix)))
+	Lflag(ctxt, filepath.Join(buildcfg.GOROOT, "pkg", fmt.Sprintf("%s_%s%s%s", buildcfg.GOOS, buildcfg.GOARCH, suffixsep, suffix)))
 
 	mayberemoveoutfile()
 
@@ -388,9 +401,9 @@
 	if *flagEntrySymbol == "" {
 		switch ctxt.BuildMode {
 		case BuildModeCShared, BuildModeCArchive:
-			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", objabi.GOARCH, objabi.GOOS)
+			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", buildcfg.GOARCH, buildcfg.GOOS)
 		case BuildModeExe, BuildModePIE:
-			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", objabi.GOARCH, objabi.GOOS)
+			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", buildcfg.GOARCH, buildcfg.GOOS)
 		case BuildModeShared, BuildModePlugin:
 			// No *flagEntrySymbol for -buildmode=shared and plugin
 		default:
@@ -489,19 +502,20 @@
 	case 0:
 		// nothing to do
 	case 1, 2:
-		flags = loader.FlagStrictDups
+		flags |= loader.FlagStrictDups
 	default:
 		log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
 	}
+	if !buildcfg.Experiment.RegabiWrappers {
+		// Use ABI aliases if ABI wrappers are not used.
+		flags |= loader.FlagUseABIAlias
+	}
 	elfsetstring1 := func(str string, off int) { elfsetstring(ctxt, 0, str, off) }
 	ctxt.loader = loader.NewLoader(flags, elfsetstring1, &ctxt.ErrorReporter.ErrorReporter)
 	ctxt.ErrorReporter.SymName = func(s loader.Sym) string {
 		return ctxt.loader.SymName(s)
 	}
 
-	ctxt.cgo_export_static = make(map[string]bool)
-	ctxt.cgo_export_dynamic = make(map[string]bool)
-
 	// ctxt.Library grows during the loop, so not a range loop.
 	i := 0
 	for ; i < len(ctxt.Library); i++ {
@@ -533,12 +547,15 @@
 	// up symbol by name may not get expected result.
 
 	iscgo = ctxt.LibraryByPkg["runtime/cgo"] != nil
-	ctxt.canUsePlugins = ctxt.LibraryByPkg["plugin"] != nil
+
+	// Plugins a require cgo support to function. Similarly, plugins may require additional
+	// internal linker support on some platforms which may not be implemented.
+	ctxt.canUsePlugins = ctxt.LibraryByPkg["plugin"] != nil && iscgo
 
 	// We now have enough information to determine the link mode.
 	determineLinkMode(ctxt)
 
-	if ctxt.LinkMode == LinkExternal && !iscgo && !(objabi.GOOS == "darwin" && ctxt.BuildMode != BuildModePlugin && ctxt.Arch.Family == sys.AMD64) {
+	if ctxt.LinkMode == LinkExternal && !iscgo && !(buildcfg.GOOS == "darwin" && ctxt.BuildMode != BuildModePlugin && ctxt.Arch.Family == sys.AMD64) {
 		// 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
@@ -547,7 +564,12 @@
 			if ctxt.BuildMode == BuildModeShared || ctxt.linkShared {
 				Exitf("cannot implicitly include runtime/cgo in a shared library")
 			}
-			loadobjfile(ctxt, lib)
+			for ; i < len(ctxt.Library); i++ {
+				lib := ctxt.Library[i]
+				if lib.Shlib == "" {
+					loadobjfile(ctxt, lib)
+				}
+			}
 		}
 	}
 
@@ -589,9 +611,6 @@
 				// errors - see if we can find libcompiler_rt.a instead.
 				*flagLibGCC = ctxt.findLibPathCmd("--print-file-name=libcompiler_rt.a", "libcompiler_rt")
 			}
-			if *flagLibGCC != "none" {
-				hostArchive(ctxt, *flagLibGCC)
-			}
 			if ctxt.HeadType == objabi.Hwindows {
 				if p := ctxt.findLibPath("libmingwex.a"); p != "none" {
 					hostArchive(ctxt, p)
@@ -613,6 +632,9 @@
 					libmsvcrt.a libm.a
 				*/
 			}
+			if *flagLibGCC != "none" {
+				hostArchive(ctxt, *flagLibGCC)
+			}
 		}
 	}
 
@@ -624,50 +646,13 @@
 	strictDupMsgCount = ctxt.loader.NStrictDupMsgs()
 }
 
-// setupdynexp constructs ctxt.dynexp, a list of loader.Sym.
-func setupdynexp(ctxt *Link) {
-	dynexpMap := ctxt.cgo_export_dynamic
-	if ctxt.LinkMode == LinkExternal {
-		dynexpMap = ctxt.cgo_export_static
-	}
-	d := make([]loader.Sym, 0, len(dynexpMap))
-	for exp := range dynexpMap {
-		s := ctxt.loader.LookupOrCreateSym(exp, 0)
-		d = append(d, s)
-		// sanity check
-		if !ctxt.loader.AttrReachable(s) {
-			panic("dynexp entry not reachable")
-		}
-	}
-	sort.Slice(d, func(i, j int) bool {
-		return ctxt.loader.SymName(d[i]) < ctxt.loader.SymName(d[j])
-	})
-
-	// Resolve ABI aliases in the list of cgo-exported functions.
-	// This is necessary because we load the ABI0 symbol for all
-	// cgo exports.
-	for i, s := range d {
-		if ctxt.loader.SymType(s) != sym.SABIALIAS {
-			continue
-		}
-		t := ctxt.loader.ResolveABIAlias(s)
-		ctxt.loader.CopyAttributes(s, t)
-		ctxt.loader.SetSymExtname(t, ctxt.loader.SymExtname(s))
-		d[i] = t
-	}
-	ctxt.dynexp = d
-
-	ctxt.cgo_export_static = nil
-	ctxt.cgo_export_dynamic = nil
-}
-
 // loadcgodirectives reads the previously discovered cgo directives, creating
 // symbols in preparation for host object loading or use later in the link.
 func (ctxt *Link) loadcgodirectives() {
 	l := ctxt.loader
 	hostObjSyms := make(map[loader.Sym]struct{})
 	for _, d := range ctxt.cgodata {
-		setCgoAttr(ctxt, ctxt.loader.LookupOrCreateSym, d.file, d.pkg, d.directives, hostObjSyms)
+		setCgoAttr(ctxt, d.file, d.pkg, d.directives, hostObjSyms)
 	}
 	ctxt.cgodata = nil
 
@@ -732,7 +717,7 @@
 		}
 	}
 
-	if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 && objabi.GOOS != "aix" {
+	if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 && buildcfg.GOOS != "aix" {
 		toc := ctxt.loader.LookupOrCreateSym(".TOC.", 0)
 		sb := ctxt.loader.MakeSymbolUpdater(toc)
 		sb.SetType(sym.SDYNIMPORT)
@@ -741,7 +726,7 @@
 	// The Android Q linker started to complain about underalignment of the our TLS
 	// section. We don't actually use the section on android, so don't
 	// generate it.
-	if objabi.GOOS != "android" {
+	if buildcfg.GOOS != "android" {
 		tlsg := ctxt.loader.LookupOrCreateSym("runtime.tlsg", 0)
 		sb := ctxt.loader.MakeSymbolUpdater(tlsg)
 
@@ -782,7 +767,19 @@
 			sb := ctxt.loader.MakeSymbolUpdater(goarm)
 			sb.SetType(sym.SDATA)
 			sb.SetSize(0)
-			sb.AddUint8(uint8(objabi.GOARM))
+			sb.AddUint8(uint8(buildcfg.GOARM))
+		}
+
+		// Set runtime.disableMemoryProfiling bool if
+		// runtime.MemProfile is not retained in the binary after
+		// deadcode (and we're not dynamically linking).
+		memProfile := ctxt.loader.Lookup("runtime.MemProfile", sym.SymVerABIInternal)
+		if memProfile != 0 && !ctxt.loader.AttrReachable(memProfile) && !ctxt.DynlinkingGo() {
+			memProfSym := ctxt.loader.LookupOrCreateSym("runtime.disableMemoryProfiling", 0)
+			sb := ctxt.loader.MakeSymbolUpdater(memProfSym)
+			sb.SetType(sym.SDATA)
+			sb.SetSize(0)
+			sb.AddUint8(1) // true bool
 		}
 	} else {
 		// If OTOH the module does not contain the runtime package,
@@ -1074,6 +1071,10 @@
 		}
 
 		f.MustSeek(h.off, 0)
+		if h.ld == nil {
+			Errorf(nil, "%s: unrecognized object file format", h.pn)
+			continue
+		}
 		h.ld(ctxt, f, h.pkg, h.length, h.pn)
 		f.Close()
 	}
@@ -1263,7 +1264,7 @@
 			// -headerpad is incompatible with -fembed-bitcode.
 			argv = append(argv, "-Wl,-headerpad,1144")
 		}
-		if ctxt.DynlinkingGo() && objabi.GOOS != "ios" {
+		if ctxt.DynlinkingGo() && buildcfg.GOOS != "ios" {
 			// -flat_namespace is deprecated on iOS.
 			// It is useful for supporting plugins. We don't support plugins on iOS.
 			argv = append(argv, "-Wl,-flat_namespace")
@@ -1337,8 +1338,6 @@
 		if ctxt.HeadType == objabi.Hdarwin {
 			argv = append(argv, "-dynamiclib")
 		} else {
-			// ELF.
-			argv = append(argv, "-Wl,-Bsymbolic")
 			if ctxt.UseRelro() {
 				argv = append(argv, "-Wl,-z,relro")
 			}
@@ -1351,6 +1350,8 @@
 				// Pass -z nodelete to mark the shared library as
 				// non-closeable: a dlclose will do nothing.
 				argv = append(argv, "-Wl,-z,nodelete")
+				// Only pass Bsymbolic on non-Windows.
+				argv = append(argv, "-Wl,-Bsymbolic")
 			}
 		}
 	case BuildModeShared:
@@ -1381,12 +1382,12 @@
 		// from the beginning of the section (like sym.STYPE).
 		argv = append(argv, "-Wl,-znocopyreloc")
 
-		if objabi.GOOS == "android" {
+		if buildcfg.GOOS == "android" {
 			// Use lld to avoid errors from default linker (issue #38838)
 			altLinker = "lld"
 		}
 
-		if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) && objabi.GOOS == "linux" {
+		if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) && buildcfg.GOOS == "linux" {
 			// On ARM, the GNU linker will generate COPY relocations
 			// even with -znocopyreloc set.
 			// https://sourceware.org/bugzilla/show_bug.cgi?id=19962
@@ -1408,7 +1409,7 @@
 			}
 		}
 	}
-	if ctxt.Arch.Family == sys.ARM64 && objabi.GOOS == "freebsd" {
+	if ctxt.Arch.Family == sys.ARM64 && buildcfg.GOOS == "freebsd" {
 		// Switch to ld.bfd on freebsd/arm64.
 		altLinker = "bfd"
 
@@ -1435,7 +1436,7 @@
 	// only want to do this when producing a Windows output file
 	// on a Windows host.
 	outopt := *flagOutfile
-	if objabi.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" {
+	if buildcfg.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" {
 		outopt += "."
 	}
 	argv = append(argv, "-o")
@@ -1445,6 +1446,14 @@
 		argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val))
 	}
 
+	if *flagInterpreter != "" {
+		// Many linkers support both -I and the --dynamic-linker flags
+		// to set the ELF interpreter, but lld only supports
+		// --dynamic-linker so prefer that (ld on very old Solaris only
+		// supports -I but that seems less important).
+		argv = append(argv, fmt.Sprintf("-Wl,--dynamic-linker,%s", *flagInterpreter))
+	}
+
 	// Force global symbols to be exported for dlopen, etc.
 	if ctxt.IsELF {
 		argv = append(argv, "-rdynamic")
@@ -1454,8 +1463,9 @@
 		argv = append(argv, "-Wl,-bE:"+fileName)
 	}
 
-	if strings.Contains(argv[0], "clang") {
-		argv = append(argv, "-Qunused-arguments")
+	const unusedArguments = "-Qunused-arguments"
+	if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, unusedArguments) {
+		argv = append(argv, unusedArguments)
 	}
 
 	const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
@@ -1522,12 +1532,13 @@
 	// even when linking with -static, causing a linker
 	// error when using GNU ld. So take out -rdynamic if
 	// we added it. We do it in this order, rather than
-	// only adding -rdynamic later, so that -*extldflags
+	// only adding -rdynamic later, so that -extldflags
 	// can override -rdynamic without using -static.
+	// Similarly for -Wl,--dynamic-linker.
 	checkStatic := func(arg string) {
 		if ctxt.IsELF && arg == "-static" {
 			for i := range argv {
-				if argv[i] == "-rdynamic" {
+				if argv[i] == "-rdynamic" || strings.HasPrefix(argv[i], "-Wl,--dynamic-linker,") {
 					argv[i] = "-static"
 				}
 			}
@@ -1751,7 +1762,7 @@
 	case sys.I386:
 		return []string{"-m32"}
 	case sys.AMD64:
-		if objabi.GOOS == "darwin" {
+		if buildcfg.GOOS == "darwin" {
 			return []string{"-arch", "x86_64", "-m64"}
 		}
 		return []string{"-m64"}
@@ -1760,7 +1771,7 @@
 	case sys.ARM:
 		return []string{"-marm"}
 	case sys.ARM64:
-		if objabi.GOOS == "darwin" {
+		if buildcfg.GOOS == "darwin" {
 			return []string{"-arch", "arm64"}
 		}
 	case sys.MIPS64:
@@ -1768,7 +1779,7 @@
 	case sys.MIPS:
 		return []string{"-mabi=32"}
 	case sys.PPC64:
-		if objabi.GOOS == "aix" {
+		if buildcfg.GOOS == "aix" {
 			return []string{"-maix64"}
 		} else {
 			return []string{"-m64"}
@@ -1778,6 +1789,8 @@
 	return nil
 }
 
+var wantHdr = objabi.HeaderString()
+
 // 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.
@@ -1821,7 +1834,11 @@
 		return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
 	}
 
-	if /* x86 */ c1 == 0x4c && c2 == 0x01 || /* x86_64 */ c1 == 0x64 && c2 == 0x86 || /* armv7 */ c1 == 0xc4 && c2 == 0x01 {
+	switch c1<<8 | c2 {
+	case 0x4c01, // 386
+		0x6486, // amd64
+		0xc401, // arm
+		0x64aa: // arm64
 		ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
 			textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
 			if err != nil {
@@ -1848,6 +1865,14 @@
 		return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
 	}
 
+	if c1 != 'g' || c2 != 'o' || c3 != ' ' || c4 != 'o' {
+		// An unrecognized object is just passed to the external linker.
+		// If we try to read symbols from this object, we will
+		// report an error at that time.
+		unknownObjFormat = true
+		return ldhostobj(nil, ctxt.HeadType, f, pkg, length, pn, file)
+	}
+
 	/* check the header */
 	line, err := f.ReadString('\n')
 	if err != nil {
@@ -1867,29 +1892,13 @@
 			return nil
 		}
 
-		Errorf(nil, "%s: not an object file", pn)
+		Errorf(nil, "%s: not an object file: @%d %q", pn, start, line)
 		return nil
 	}
 
 	// First, check that the basic GOOS, GOARCH, and Version match.
-	t := fmt.Sprintf("%s %s %s ", objabi.GOOS, objabi.GOARCH, objabi.Version)
-
-	line = strings.TrimRight(line, "\n")
-	if !strings.HasPrefix(line[10:]+" ", t) && !*flagF {
-		Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], t)
-		return nil
-	}
-
-	// Second, check that longer lines match each other exactly,
-	// so that the Go compiler and write additional information
-	// that must be the same from run to run.
-	if len(line) >= len(t)+10 {
-		if theline == "" {
-			theline = line[10:]
-		} else if theline != line[10:] {
-			Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], theline)
-			return nil
-		}
+	if line != wantHdr {
+		Errorf(nil, "%s: linked object header mismatch:\nhave %q\nwant %q\n", pn, line, wantHdr)
 	}
 
 	// Skip over exports and other info -- ends with \n!\n.
@@ -2091,6 +2100,7 @@
 		Errorf(nil, "cannot read symbols from shared library: %s", libpath)
 		return
 	}
+
 	for _, elfsym := range syms {
 		if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
 			continue
@@ -2099,12 +2109,22 @@
 		// Symbols whose names start with "type." are compiler
 		// generated, so make functions with that prefix internal.
 		ver := 0
+		symname := elfsym.Name // (unmangled) symbol name
 		if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") {
 			ver = sym.SymVerABIInternal
+		} else if buildcfg.Experiment.RegabiWrappers && elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC {
+			// Demangle the ABI name. Keep in sync with symtab.go:mangleABIName.
+			if strings.HasSuffix(elfsym.Name, ".abiinternal") {
+				ver = sym.SymVerABIInternal
+				symname = strings.TrimSuffix(elfsym.Name, ".abiinternal")
+			} else if strings.HasSuffix(elfsym.Name, ".abi0") {
+				ver = 0
+				symname = strings.TrimSuffix(elfsym.Name, ".abi0")
+			}
 		}
 
 		l := ctxt.loader
-		s := l.LookupOrCreateSym(elfsym.Name, ver)
+		s := l.LookupOrCreateSym(symname, ver)
 
 		// Because loadlib above loads all .a files before loading
 		// any shared libraries, any non-dynimport symbols we find
@@ -2129,15 +2149,14 @@
 			}
 		}
 
-		// For function symbols, we don't know what ABI is
-		// available, so alias it under both ABIs.
-		//
-		// TODO(austin): This is almost certainly wrong once
-		// the ABIs are actually different. We might have to
-		// mangle Go function names in the .so to include the
-		// ABI.
-		if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 {
-			alias := ctxt.loader.LookupOrCreateSym(elfsym.Name, sym.SymVerABIInternal)
+		if symname != elfsym.Name {
+			l.SetSymExtname(s, elfsym.Name)
+		}
+
+		// For function symbols, if ABI wrappers are not used, we don't
+		// know what ABI is available, so alias it under both ABIs.
+		if !buildcfg.Experiment.RegabiWrappers && elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 {
+			alias := ctxt.loader.LookupOrCreateSym(symname, sym.SymVerABIInternal)
 			if l.SymType(alias) != 0 {
 				continue
 			}
@@ -2204,7 +2223,7 @@
 	// of non-splitting functions.
 	var ch chain
 	ch.limit = objabi.StackLimit - callsize(ctxt)
-	if objabi.GOARCH == "arm64" {
+	if buildcfg.GOARCH == "arm64" {
 		// need extra 8 bytes below SP to save FP
 		ch.limit -= 8
 	}
@@ -2354,7 +2373,7 @@
 	ctxt := sc.ctxt
 	var name string
 	if ch.sym != 0 {
-		name = ldr.SymName(ch.sym)
+		name = fmt.Sprintf("%s<%d>", ldr.SymName(ch.sym), ldr.SymVersion(ch.sym))
 		if ldr.IsNoSplit(ch.sym) {
 			name += " (nosplit)"
 		}
diff --git a/src/cmd/link/internal/ld/link.go b/src/cmd/link/internal/ld/link.go
index f26d051..13618be 100644
--- a/src/cmd/link/internal/ld/link.go
+++ b/src/cmd/link/internal/ld/link.go
@@ -84,9 +84,6 @@
 	loader  *loader.Loader
 	cgodata []cgodata // cgo directives to load, three strings are args for loadcgo
 
-	cgo_export_static  map[string]bool
-	cgo_export_dynamic map[string]bool
-
 	datap  []loader.Sym
 	dynexp []loader.Sym
 
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go
index 3630e67..45a3971 100644
--- a/src/cmd/link/internal/ld/macho.go
+++ b/src/cmd/link/internal/ld/macho.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"cmd/internal/codesign"
+	"cmd/internal/obj"
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"cmd/link/internal/loader"
@@ -14,6 +15,7 @@
 	"debug/macho"
 	"encoding/binary"
 	"fmt"
+	"internal/buildcfg"
 	"io"
 	"os"
 	"sort"
@@ -86,6 +88,8 @@
 	MACHO_SUBCPU_ARMV7                   = 9
 	MACHO_CPU_ARM64                      = 1<<24 | 12
 	MACHO_SUBCPU_ARM64_ALL               = 0
+	MACHO_SUBCPU_ARM64_V8                = 1
+	MACHO_SUBCPU_ARM64E                  = 2
 	MACHO32SYMSIZE                       = 12
 	MACHO64SYMSIZE                       = 16
 	MACHO_X86_64_RELOC_UNSIGNED          = 0
@@ -176,6 +180,8 @@
 	LC_VERSION_MIN_WATCHOS      = 0x30
 	LC_VERSION_NOTE             = 0x31
 	LC_BUILD_VERSION            = 0x32
+	LC_DYLD_EXPORTS_TRIE        = 0x80000033
+	LC_DYLD_CHAINED_FIXUPS      = 0x80000034
 )
 
 const (
@@ -466,27 +472,25 @@
 		}
 	}
 	if machoPlatform == 0 {
-		switch ctxt.Arch.Family {
-		default:
-			machoPlatform = PLATFORM_MACOS
-			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).
-				// Go on iOS uses linkmode=external, and linkmode=external
-				// adds this itself. So we only need this code for linkmode=internal
-				// and we can assume OS X.
-				//
-				// See golang.org/issues/12941.
-				//
-				// The version must be at least 10.9; see golang.org/issues/30488.
-				ml := newMachoLoad(ctxt.Arch, LC_VERSION_MIN_MACOSX, 2)
-				ml.data[0] = 10<<16 | 9<<8 | 0<<0 // OS X version 10.9.0
-				ml.data[1] = 10<<16 | 9<<8 | 0<<0 // SDK 10.9.0
-			}
-		case sys.ARM, sys.ARM64:
+		machoPlatform = PLATFORM_MACOS
+		if buildcfg.GOOS == "ios" {
 			machoPlatform = PLATFORM_IOS
 		}
+		if ctxt.LinkMode == LinkInternal && machoPlatform == PLATFORM_MACOS {
+			var version uint32
+			switch ctxt.Arch.Family {
+			case sys.AMD64:
+				// The version must be at least 10.9; see golang.org/issues/30488.
+				version = 10<<16 | 9<<8 | 0<<0 // 10.9.0
+			case sys.ARM64:
+				version = 11<<16 | 0<<8 | 0<<0 // 11.0.0
+			}
+			ml := newMachoLoad(ctxt.Arch, LC_BUILD_VERSION, 4)
+			ml.data[0] = uint32(machoPlatform)
+			ml.data[1] = version // OS version
+			ml.data[2] = version // SDK version
+			ml.data[3] = 0       // ntools
+		}
 	}
 
 	// empirically, string table must begin with " \x00".
@@ -535,12 +539,31 @@
 		sb.AddUint8(0)
 	}
 
-	// Do not export C symbols dynamically in plugins, as runtime C symbols like crosscall2
-	// are in pclntab and end up pointing at the host binary, breaking unwinding.
-	// See Issue #18190.
+	// Un-export runtime symbols from plugins. Since the runtime
+	// is included in both the main binary and each plugin, these
+	// symbols appear in both images. If we leave them exported in
+	// the plugin, then the dynamic linker will resolve
+	// relocations to these functions in the plugin's functab to
+	// point to the main image, causing the runtime to think the
+	// plugin's functab is corrupted. By unexporting them, these
+	// become static references, which are resolved to the
+	// plugin's text.
+	//
+	// It would be better to omit the runtime from plugins. (Using
+	// relative PCs in the functab instead of relocations would
+	// also address this.)
+	//
+	// See issue #18190.
 	if ctxt.BuildMode == BuildModePlugin {
 		for _, name := range []string{"_cgo_topofstack", "__cgo_topofstack", "_cgo_panic", "crosscall2"} {
-			s := ctxt.loader.Lookup(name, 0)
+			// Most of these are data symbols or C
+			// symbols, so they have symbol version 0.
+			ver := 0
+			// _cgo_panic is a Go function, so it uses ABIInternal.
+			if name == "_cgo_panic" {
+				ver = sym.ABIToVersion(obj.ABIInternal)
+			}
+			s := ctxt.loader.Lookup(name, ver)
 			if s != 0 {
 				ctxt.loader.SetAttrCgoExportDynamic(s, false)
 			}
@@ -925,12 +948,12 @@
 			if machoPlatform == PLATFORM_MACOS {
 				switch n := ldr.SymExtname(s); n {
 				case "fdopendir":
-					switch objabi.GOARCH {
+					switch buildcfg.GOARCH {
 					case "amd64":
 						ldr.SetSymExtname(s, n+"$INODE64")
 					}
 				case "readdir_r", "getfsstat":
-					switch objabi.GOARCH {
+					switch buildcfg.GOARCH {
 					case "amd64":
 						ldr.SetSymExtname(s, n+"$INODE64")
 					}
@@ -1022,7 +1045,10 @@
 		symstr.AddUint8('_')
 
 		// replace "·" as ".", because DTrace cannot handle it.
-		symstr.Addstring(strings.Replace(ldr.SymExtname(s), "·", ".", -1))
+		name := strings.Replace(ldr.SymExtname(s), "·", ".", -1)
+
+		name = mangleABIName(ctxt, ldr, s, name)
+		symstr.Addstring(name)
 
 		if t := ldr.SymType(s); t == sym.SDYNIMPORT || t == sym.SHOSTOBJ || t == sym.SUNDEFEXT {
 			symtab.AddUint8(0x01)                             // type N_EXT, external symbol
@@ -1168,7 +1194,7 @@
 		}
 	}
 
-	eaddr := int32(sect.Vaddr + sect.Length)
+	eaddr := sect.Vaddr + sect.Length
 	for _, s := range syms {
 		if !ldr.AttrReachable(s) {
 			continue
@@ -1215,7 +1241,11 @@
 
 	relocSect(ctxt, Segtext.Sections[0], ctxt.Textp)
 	for _, sect := range Segtext.Sections[1:] {
-		relocSect(ctxt, sect, ctxt.datap)
+		if sect.Name == ".text" {
+			relocSect(ctxt, sect, ctxt.Textp)
+		} else {
+			relocSect(ctxt, sect, ctxt.datap)
+		}
 	}
 	for _, sect := range Segrelrodata.Sections {
 		relocSect(ctxt, sect, ctxt.datap)
diff --git a/src/cmd/link/internal/ld/macho_combine_dwarf.go b/src/cmd/link/internal/ld/macho_combine_dwarf.go
index 77ee8a4..2ab7da9 100644
--- a/src/cmd/link/internal/ld/macho_combine_dwarf.go
+++ b/src/cmd/link/internal/ld/macho_combine_dwarf.go
@@ -222,11 +222,19 @@
 			err = machoUpdateLoadCommand(reader, linkseg, linkoffset, &macho.SymtabCmd{}, "Symoff", "Stroff")
 		case macho.LoadCmdDysymtab:
 			err = machoUpdateLoadCommand(reader, linkseg, linkoffset, &macho.DysymtabCmd{}, "Tocoffset", "Modtaboff", "Extrefsymoff", "Indirectsymoff", "Extreloff", "Locreloff")
-		case LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS:
+		case LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS,
+			LC_DYLD_EXPORTS_TRIE, LC_DYLD_CHAINED_FIXUPS:
 			err = machoUpdateLoadCommand(reader, linkseg, linkoffset, &linkEditDataCmd{}, "DataOff")
 		case LC_ENCRYPTION_INFO, LC_ENCRYPTION_INFO_64:
 			err = machoUpdateLoadCommand(reader, linkseg, linkoffset, &encryptionInfoCmd{}, "CryptOff")
-		case macho.LoadCmdDylib, macho.LoadCmdThread, macho.LoadCmdUnixThread, LC_PREBOUND_DYLIB, LC_UUID, LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS, LC_SOURCE_VERSION, LC_MAIN, LC_LOAD_DYLINKER, LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_RPATH, LC_ID_DYLIB, LC_SYMSEG, LC_LOADFVMLIB, LC_IDFVMLIB, LC_IDENT, LC_FVMFILE, LC_PREPAGE, LC_ID_DYLINKER, LC_ROUTINES, LC_SUB_FRAMEWORK, LC_SUB_UMBRELLA, LC_SUB_CLIENT, LC_SUB_LIBRARY, LC_TWOLEVEL_HINTS, LC_PREBIND_CKSUM, LC_ROUTINES_64, LC_LAZY_LOAD_DYLIB, LC_LOAD_UPWARD_DYLIB, LC_DYLD_ENVIRONMENT, LC_LINKER_OPTION, LC_LINKER_OPTIMIZATION_HINT, LC_VERSION_MIN_TVOS, LC_VERSION_MIN_WATCHOS, LC_VERSION_NOTE, LC_BUILD_VERSION:
+		case macho.LoadCmdDylib, macho.LoadCmdThread, macho.LoadCmdUnixThread,
+			LC_PREBOUND_DYLIB, LC_UUID, LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS, LC_SOURCE_VERSION,
+			LC_MAIN, LC_LOAD_DYLINKER, LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_RPATH, LC_ID_DYLIB,
+			LC_SYMSEG, LC_LOADFVMLIB, LC_IDFVMLIB, LC_IDENT, LC_FVMFILE, LC_PREPAGE, LC_ID_DYLINKER,
+			LC_ROUTINES, LC_SUB_FRAMEWORK, LC_SUB_UMBRELLA, LC_SUB_CLIENT, LC_SUB_LIBRARY, LC_TWOLEVEL_HINTS,
+			LC_PREBIND_CKSUM, LC_ROUTINES_64, LC_LAZY_LOAD_DYLIB, LC_LOAD_UPWARD_DYLIB, LC_DYLD_ENVIRONMENT,
+			LC_LINKER_OPTION, LC_LINKER_OPTIMIZATION_HINT, LC_VERSION_MIN_TVOS, LC_VERSION_MIN_WATCHOS,
+			LC_VERSION_NOTE, LC_BUILD_VERSION:
 			// Nothing to update
 		default:
 			err = fmt.Errorf("unknown load command 0x%x (%s)", int(cmd.Cmd), cmd.Cmd)
@@ -394,7 +402,7 @@
 	// We want the DWARF segment to be considered non-loadable, so
 	// force vmaddr and vmsize to zero. In addition, set the initial
 	// protection to zero so as to make the dynamic loader happy,
-	// since otherwise it may complain that that the vm size and file
+	// since otherwise it may complain that the vm size and file
 	// size don't match for the segment. See issues 21647 and 32673
 	// for more context. Also useful to refer to the Apple dynamic
 	// loader source, specifically ImageLoaderMachO::sniffLoadCommands
diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go
index 5a096f1..cba0e3d 100644
--- a/src/cmd/link/internal/ld/main.go
+++ b/src/cmd/link/internal/ld/main.go
@@ -37,6 +37,7 @@
 	"cmd/internal/sys"
 	"cmd/link/internal/benchmark"
 	"flag"
+	"internal/buildcfg"
 	"log"
 	"os"
 	"runtime"
@@ -87,16 +88,14 @@
 	flag8             bool // use 64-bit addresses in symbol table
 	flagInterpreter   = flag.String("I", "", "use `linker` as ELF dynamic linker")
 	FlagDebugTramp    = flag.Int("debugtramp", 0, "debug trampolines")
-	FlagDebugTextSize = flag.Int("debugppc64textsize", 0, "debug PPC64 text section max")
+	FlagDebugTextSize = flag.Int("debugtextsize", 0, "debug text section max size")
 	FlagStrictDups    = flag.Int("strictdups", 0, "sanity check duplicate symbol contents during object file reading (1=warn 2=err).")
 	FlagRound         = flag.Int("R", -1, "set address rounding `quantum`")
 	FlagTextAddr      = flag.Int64("T", -1, "set text segment `address`")
 	flagEntrySymbol   = flag.String("E", "", "set `entry` symbol name")
-
-	cpuprofile     = flag.String("cpuprofile", "", "write cpu profile to `file`")
-	memprofile     = flag.String("memprofile", "", "write memory profile to `file`")
-	memprofilerate = flag.Int64("memprofilerate", 0, "set runtime.MemProfileRate to `rate`")
-
+	cpuprofile        = flag.String("cpuprofile", "", "write cpu profile to `file`")
+	memprofile        = flag.String("memprofile", "", "write memory profile to `file`")
+	memprofilerate    = flag.Int64("memprofilerate", 0, "set runtime.MemProfileRate to `rate`")
 	benchmarkFlag     = flag.String("benchmark", "", "set to 'mem' or 'cpu' to enable phase benchmarking")
 	benchmarkFileFlag = flag.String("benchmarkprofile", "", "emit phase profiles to `base`_phase.{cpu,mem}prof")
 )
@@ -117,11 +116,17 @@
 	}
 
 	final := gorootFinal()
-	addstrdata1(ctxt, "runtime/internal/sys.DefaultGoroot="+final)
-	addstrdata1(ctxt, "cmd/internal/objabi.defaultGOROOT="+final)
+	addstrdata1(ctxt, "runtime.defaultGOROOT="+final)
+	addstrdata1(ctxt, "internal/buildcfg.defaultGOROOT="+final)
+
+	buildVersion := buildcfg.Version
+	if goexperiment := buildcfg.GOEXPERIMENT(); goexperiment != "" {
+		buildVersion += " X:" + goexperiment
+	}
+	addstrdata1(ctxt, "runtime.buildVersion="+buildVersion)
 
 	// TODO(matloob): define these above and then check flag values here
-	if ctxt.Arch.Family == sys.AMD64 && objabi.GOOS == "plan9" {
+	if ctxt.Arch.Family == sys.AMD64 && buildcfg.GOOS == "plan9" {
 		flag.BoolVar(&flag8, "8", false, "use 64-bit addresses in symbol table")
 	}
 	flagHeadType := flag.String("H", "", "set header `type`")
@@ -155,7 +160,7 @@
 		}
 	}
 	if ctxt.HeadType == objabi.Hunknown {
-		ctxt.HeadType.Set(objabi.GOOS)
+		ctxt.HeadType.Set(buildcfg.GOOS)
 	}
 
 	if !*flagAslr && ctxt.BuildMode != BuildModeCShared {
@@ -251,7 +256,7 @@
 
 	bench.Start("dostrdata")
 	ctxt.dostrdata()
-	if objabi.Fieldtrack_enabled != 0 {
+	if buildcfg.Experiment.FieldTrack {
 		bench.Start("fieldtrack")
 		fieldtrack(ctxt.Arch, ctxt.loader)
 	}
@@ -290,7 +295,6 @@
 	bench.Start("textbuildid")
 	ctxt.textbuildid()
 	bench.Start("addexport")
-	setupdynexp(ctxt)
 	ctxt.setArchSyms()
 	ctxt.addexport()
 	bench.Start("Gentext")
@@ -330,7 +334,7 @@
 		// Don't mmap if we're building for Wasm. Wasm file
 		// layout is very different so filesize is meaningless.
 		if err := ctxt.Out.Mmap(filesize); err != nil {
-			panic(err)
+			Exitf("mapping output file failed: %v", err)
 		}
 	}
 	// asmb will redirect symbols to the output file mmap, and relocations
diff --git a/src/cmd/link/internal/ld/nooptcgolink_test.go b/src/cmd/link/internal/ld/nooptcgolink_test.go
index 4d2ff1a..73548da 100644
--- a/src/cmd/link/internal/ld/nooptcgolink_test.go
+++ b/src/cmd/link/internal/ld/nooptcgolink_test.go
@@ -6,8 +6,6 @@
 
 import (
 	"internal/testenv"
-	"io/ioutil"
-	"os"
 	"os/exec"
 	"path/filepath"
 	"runtime"
@@ -22,11 +20,7 @@
 
 	testenv.MustHaveGoBuild(t)
 	testenv.MustHaveCGO(t)
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 	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()
diff --git a/src/cmd/link/internal/ld/outbuf.go b/src/cmd/link/internal/ld/outbuf.go
index 530836e..9d5e885 100644
--- a/src/cmd/link/internal/ld/outbuf.go
+++ b/src/cmd/link/internal/ld/outbuf.go
@@ -160,7 +160,7 @@
 	total := uint64(bufLen + heapLen)
 	if heapLen != 0 {
 		if err := out.Mmap(total); err != nil { // Mmap will copy out.heap over to out.buf
-			panic(err)
+			Exitf("mapping output file failed: %v", err)
 		}
 	}
 	return true
diff --git a/src/cmd/link/internal/ld/outbuf_mmap.go b/src/cmd/link/internal/ld/outbuf_mmap.go
index 807fe24..40a3222 100644
--- a/src/cmd/link/internal/ld/outbuf_mmap.go
+++ b/src/cmd/link/internal/ld/outbuf_mmap.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd
 // +build aix darwin dragonfly freebsd linux netbsd openbsd
 
 package ld
diff --git a/src/cmd/link/internal/ld/outbuf_nofallocate.go b/src/cmd/link/internal/ld/outbuf_nofallocate.go
index 6bf96bc..6564bd5 100644
--- a/src/cmd/link/internal/ld/outbuf_nofallocate.go
+++ b/src/cmd/link/internal/ld/outbuf_nofallocate.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !darwin && !linux
 // +build !darwin,!linux
 
 package ld
diff --git a/src/cmd/link/internal/ld/outbuf_nommap.go b/src/cmd/link/internal/ld/outbuf_nommap.go
index 6b40253..c870fa2 100644
--- a/src/cmd/link/internal/ld/outbuf_nommap.go
+++ b/src/cmd/link/internal/ld/outbuf_nommap.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !windows
 // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!windows
 
 package ld
diff --git a/src/cmd/link/internal/ld/outbuf_notdarwin.go b/src/cmd/link/internal/ld/outbuf_notdarwin.go
index 8c5666f..f9caa41 100644
--- a/src/cmd/link/internal/ld/outbuf_notdarwin.go
+++ b/src/cmd/link/internal/ld/outbuf_notdarwin.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !darwin
 // +build !darwin
 
 package ld
diff --git a/src/cmd/link/internal/ld/outbuf_test.go b/src/cmd/link/internal/ld/outbuf_test.go
index e6643da..a7b105f 100644
--- a/src/cmd/link/internal/ld/outbuf_test.go
+++ b/src/cmd/link/internal/ld/outbuf_test.go
@@ -5,8 +5,6 @@
 package ld
 
 import (
-	"io/ioutil"
-	"os"
 	"path/filepath"
 	"runtime"
 	"testing"
@@ -19,11 +17,7 @@
 		t.Skip("unsupported OS")
 	case "aix", "darwin", "ios", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "windows":
 	}
-	dir, err := ioutil.TempDir("", "TestMMap")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 	filename := filepath.Join(dir, "foo.out")
 	ob := NewOutBuf(nil)
 	if err := ob.Open(filename); err != nil {
diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go
index 72bf33e..05fd302 100644
--- a/src/cmd/link/internal/ld/pcln.go
+++ b/src/cmd/link/internal/ld/pcln.go
@@ -11,6 +11,7 @@
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
 	"fmt"
+	"internal/buildcfg"
 	"os"
 	"path/filepath"
 )
@@ -50,7 +51,7 @@
 }
 
 // addGeneratedSym adds a generator symbol to pclntab, returning the new Sym.
-// It is the caller's responsibilty to save they symbol in state.
+// It is the caller's responsibility to save they symbol in state.
 func (state *pclntab) addGeneratedSym(ctxt *Link, name string, size int64, f generatorFunc) loader.Sym {
 	size = Rnd(size, int64(ctxt.Arch.PtrSize))
 	state.size += size
@@ -360,7 +361,7 @@
 	// then not loading extra filenames), and just use the hash value of the
 	// symbol name to do this cataloging.
 	//
-	// TOOD: Store filenames as symbols. (Note this would be easiest if you
+	// TODO: Store filenames as symbols. (Note this would be easiest if you
 	// also move strings to ALWAYS using the larger content addressable hash
 	// function, and use that hash value for uniqueness testing.)
 	cuEntries := make([]goobj.CUFileIndex, len(compUnits))
@@ -589,6 +590,7 @@
 	if !useSymValue {
 		// Generate relocations for funcdata when externally linking.
 		state.writeFuncData(ctxt, sb, funcs, inlSyms, startLocations, setAddr, setUintNOP)
+		sb.SortRelocs()
 	}
 }
 
@@ -796,7 +798,14 @@
 		}
 		off = uint32(sb.SetUint8(ctxt.Arch, int64(off), uint8(funcID)))
 
-		off += 2 // pad
+		// flag uint8
+		var flag objabi.FuncFlag
+		if fi.Valid() {
+			flag = fi.FuncFlag()
+		}
+		off = uint32(sb.SetUint8(ctxt.Arch, int64(off), uint8(flag)))
+
+		off += 1 // pad
 
 		// nfuncdata must be the final entry.
 		funcdata, funcdataoff = funcData(fi, 0, funcdata, funcdataoff)
@@ -872,7 +881,7 @@
 }
 
 func gorootFinal() string {
-	root := objabi.GOROOT
+	root := buildcfg.GOROOT
 	if final := os.Getenv("GOROOT_FINAL"); final != "" {
 		root = final
 	}
diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go
index 5edaf54..8eb4231 100644
--- a/src/cmd/link/internal/ld/pe.go
+++ b/src/cmd/link/internal/ld/pe.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // PE (Portable Executable) file writing
-// https://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
+// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
 
 package ld
 
@@ -15,6 +15,7 @@
 	"debug/pe"
 	"encoding/binary"
 	"fmt"
+	"internal/buildcfg"
 	"sort"
 	"strconv"
 	"strings"
@@ -42,11 +43,11 @@
 	AddressOfNameOrdinals uint32
 }
 
-const (
-	PEBASE = 0x00400000
-)
-
 var (
+	// PEBASE is the base address for the executable.
+	// It is small for 32-bit and large for 64-bit.
+	PEBASE int64
+
 	// SectionAlignment must be greater than or equal to FileAlignment.
 	// The default is the page size for the architecture.
 	PESECTALIGN int64 = 0x1000
@@ -61,14 +62,40 @@
 	IMAGE_SCN_CNT_CODE               = 0x00000020
 	IMAGE_SCN_CNT_INITIALIZED_DATA   = 0x00000040
 	IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080
+	IMAGE_SCN_LNK_OTHER              = 0x00000100
+	IMAGE_SCN_LNK_INFO               = 0x00000200
+	IMAGE_SCN_LNK_REMOVE             = 0x00000800
+	IMAGE_SCN_LNK_COMDAT             = 0x00001000
+	IMAGE_SCN_GPREL                  = 0x00008000
+	IMAGE_SCN_MEM_PURGEABLE          = 0x00020000
+	IMAGE_SCN_MEM_16BIT              = 0x00020000
+	IMAGE_SCN_MEM_LOCKED             = 0x00040000
+	IMAGE_SCN_MEM_PRELOAD            = 0x00080000
+	IMAGE_SCN_ALIGN_1BYTES           = 0x00100000
+	IMAGE_SCN_ALIGN_2BYTES           = 0x00200000
+	IMAGE_SCN_ALIGN_4BYTES           = 0x00300000
+	IMAGE_SCN_ALIGN_8BYTES           = 0x00400000
+	IMAGE_SCN_ALIGN_16BYTES          = 0x00500000
+	IMAGE_SCN_ALIGN_32BYTES          = 0x00600000
+	IMAGE_SCN_ALIGN_64BYTES          = 0x00700000
+	IMAGE_SCN_ALIGN_128BYTES         = 0x00800000
+	IMAGE_SCN_ALIGN_256BYTES         = 0x00900000
+	IMAGE_SCN_ALIGN_512BYTES         = 0x00A00000
+	IMAGE_SCN_ALIGN_1024BYTES        = 0x00B00000
+	IMAGE_SCN_ALIGN_2048BYTES        = 0x00C00000
+	IMAGE_SCN_ALIGN_4096BYTES        = 0x00D00000
+	IMAGE_SCN_ALIGN_8192BYTES        = 0x00E00000
+	IMAGE_SCN_LNK_NRELOC_OVFL        = 0x01000000
+	IMAGE_SCN_MEM_DISCARDABLE        = 0x02000000
+	IMAGE_SCN_MEM_NOT_CACHED         = 0x04000000
+	IMAGE_SCN_MEM_NOT_PAGED          = 0x08000000
+	IMAGE_SCN_MEM_SHARED             = 0x10000000
 	IMAGE_SCN_MEM_EXECUTE            = 0x20000000
 	IMAGE_SCN_MEM_READ               = 0x40000000
 	IMAGE_SCN_MEM_WRITE              = 0x80000000
-	IMAGE_SCN_MEM_DISCARDABLE        = 0x2000000
-	IMAGE_SCN_LNK_NRELOC_OVFL        = 0x1000000
-	IMAGE_SCN_ALIGN_32BYTES          = 0x600000
 )
 
+// See https://docs.microsoft.com/en-us/windows/win32/debug/pe-format.
 // 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
@@ -95,6 +122,25 @@
 	IMAGE_REL_ARM_BRANCH11 = 0x0004
 	IMAGE_REL_ARM_SECREL   = 0x000F
 
+	IMAGE_REL_ARM64_ABSOLUTE       = 0x0000
+	IMAGE_REL_ARM64_ADDR32         = 0x0001
+	IMAGE_REL_ARM64_ADDR32NB       = 0x0002
+	IMAGE_REL_ARM64_BRANCH26       = 0x0003
+	IMAGE_REL_ARM64_PAGEBASE_REL21 = 0x0004
+	IMAGE_REL_ARM64_REL21          = 0x0005
+	IMAGE_REL_ARM64_PAGEOFFSET_12A = 0x0006
+	IMAGE_REL_ARM64_PAGEOFFSET_12L = 0x0007
+	IMAGE_REL_ARM64_SECREL         = 0x0008
+	IMAGE_REL_ARM64_SECREL_LOW12A  = 0x0009
+	IMAGE_REL_ARM64_SECREL_HIGH12A = 0x000A
+	IMAGE_REL_ARM64_SECREL_LOW12L  = 0x000B
+	IMAGE_REL_ARM64_TOKEN          = 0x000C
+	IMAGE_REL_ARM64_SECTION        = 0x000D
+	IMAGE_REL_ARM64_ADDR64         = 0x000E
+	IMAGE_REL_ARM64_BRANCH19       = 0x000F
+	IMAGE_REL_ARM64_BRANCH14       = 0x0010
+	IMAGE_REL_ARM64_REL32          = 0x0011
+
 	IMAGE_REL_BASED_HIGHLOW = 3
 	IMAGE_REL_BASED_DIR64   = 10
 )
@@ -316,8 +362,8 @@
 // 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)))
+	if seg.Vaddr-uint64(PEBASE) != uint64(sect.virtualAddress) {
+		Errorf(nil, "%s.VirtualAddress = %#x, want %#x", sect.name, uint64(int64(sect.virtualAddress)), uint64(int64(seg.Vaddr-uint64(PEBASE))))
 		errorexit()
 	}
 	if seg.Fileoff != uint64(sect.pointerToRawData) {
@@ -398,14 +444,16 @@
 		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.virtualSize = uint32(sectsize)
 		sect.sizeOfRawData = uint32(Rnd(int64(filesize), PEFILEALIGN))
 		f.nextFileOffset += sect.sizeOfRawData
+	} else {
+		sect.sizeOfRawData = uint32(sectsize)
 	}
 	f.sections = append(f.sections, sect)
 	return sect
@@ -427,7 +475,7 @@
 	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
+	h.characteristics = IMAGE_SCN_ALIGN_1BYTES | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_CNT_INITIALIZED_DATA
 	return h
 }
 
@@ -456,28 +504,29 @@
 	// 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 {
+	var alignment uint32
+	switch buildcfg.GOARCH {
 	default:
-		Exitf("peFile.addInitArray: unsupported GOARCH=%q\n", objabi.GOARCH)
-	case "386":
+		Exitf("peFile.addInitArray: unsupported GOARCH=%q\n", buildcfg.GOARCH)
+	case "386", "arm":
 		size = 4
-	case "amd64":
+		alignment = IMAGE_SCN_ALIGN_4BYTES
+	case "amd64", "arm64":
 		size = 8
-	case "arm":
-		size = 4
+		alignment = IMAGE_SCN_ALIGN_8BYTES
 	}
 	sect := f.addSection(".ctors", size, size)
-	sect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
+	sect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | alignment
 	sect.sizeOfRawData = uint32(size)
 	ctxt.Out.SeekSet(int64(sect.pointerToRawData))
 	sect.checkOffset(ctxt.Out.Offset())
 
 	init_entry := ctxt.loader.Lookup(*flagEntrySymbol, 0)
 	addr := uint64(ctxt.loader.SymValue(init_entry)) - ctxt.loader.SymSect(init_entry).Vaddr
-	switch objabi.GOARCH {
+	switch buildcfg.GOARCH {
 	case "386", "arm":
 		ctxt.Out.Write32(uint32(addr))
-	case "amd64":
+	case "amd64", "arm64":
 		ctxt.Out.Write64(addr)
 	}
 	return sect
@@ -498,7 +547,6 @@
 		if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
 			return 0
 		}
-		nrelocs := 0
 		sect.Reloff = uint64(ctxt.Out.Offset())
 		for i, s := range syms {
 			if !ldr.AttrReachable(s) {
@@ -509,12 +557,12 @@
 				break
 			}
 		}
-		eaddr := int32(sect.Vaddr + sect.Length)
+		eaddr := int64(sect.Vaddr + sect.Length)
 		for _, s := range syms {
 			if !ldr.AttrReachable(s) {
 				continue
 			}
-			if ldr.SymValue(s) >= int64(eaddr) {
+			if ldr.SymValue(s) >= eaddr {
 				break
 			}
 			// Compute external relocations on the go, and pass to PEreloc1
@@ -534,13 +582,13 @@
 					ctxt.Errorf(s, "reloc %d to non-coff symbol %s (outer=%s) %d", r.Type(), ldr.SymName(r.Sym()), ldr.SymName(rr.Xsym), ldr.SymType(r.Sym()))
 				}
 				if !thearch.PEreloc1(ctxt.Arch, ctxt.Out, ldr, s, rr, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-base)) {
-					ctxt.Errorf(s, "unsupported obj reloc %d/%d to %s", r.Type(), r.Siz(), ldr.SymName(r.Sym()))
+					ctxt.Errorf(s, "unsupported obj reloc %v/%d to %s", r.Type(), r.Siz(), ldr.SymName(r.Sym()))
 				}
-				nrelocs++
 			}
 		}
 		sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
-		return nrelocs
+		const relocLen = 4 + 4 + 2
+		return int(sect.Rellen / relocLen)
 	}
 
 	sects := []struct {
@@ -581,19 +629,25 @@
 		Errorf(nil, "emitRelocations: could not find %q section", sect.Name)
 	}
 
+	if f.ctorsSect == nil {
+		return
+	}
+
 	f.ctorsSect.emitRelocations(ctxt.Out, func() int {
 		dottext := ldr.Lookup(".text", 0)
 		ctxt.Out.Write32(0)
 		ctxt.Out.Write32(uint32(ldr.SymDynid(dottext)))
-		switch objabi.GOARCH {
+		switch buildcfg.GOARCH {
 		default:
-			ctxt.Errorf(dottext, "unknown architecture for PE: %q\n", objabi.GOARCH)
+			ctxt.Errorf(dottext, "unknown architecture for PE: %q\n", buildcfg.GOARCH)
 		case "386":
 			ctxt.Out.Write16(IMAGE_REL_I386_DIR32)
 		case "amd64":
 			ctxt.Out.Write16(IMAGE_REL_AMD64_ADDR64)
 		case "arm":
 			ctxt.Out.Write16(IMAGE_REL_ARM_ADDR32)
+		case "arm64":
+			ctxt.Out.Write16(IMAGE_REL_ARM64_ADDR64)
 		}
 		return 1
 	})
@@ -650,6 +704,12 @@
 	return f.bssSect.index, int64(v - Segdata.Filelen), nil
 }
 
+var isLabel = make(map[loader.Sym]bool)
+
+func AddPELabelSym(ldr *loader.Loader, s loader.Sym) {
+	isLabel[s] = true
+}
+
 // writeSymbols writes all COFF symbol table records.
 func (f *peFile) writeSymbols(ctxt *Link) {
 	ldr := ctxt.loader
@@ -667,6 +727,8 @@
 			name = "_" + name
 		}
 
+		name = mangleABIName(ctxt, ldr, s, name)
+
 		var peSymType uint16
 		if ctxt.IsExternal() {
 			peSymType = IMAGE_SYM_TYPE_NULL
@@ -744,6 +806,10 @@
 		switch t {
 		case sym.SDYNIMPORT, sym.SHOSTOBJ, sym.SUNDEFEXT:
 			addsym(s)
+		default:
+			if len(isLabel) > 0 && isLabel[s] {
+				addsym(s)
+			}
 		}
 	}
 }
@@ -788,6 +854,8 @@
 		fh.Machine = pe.IMAGE_FILE_MACHINE_I386
 	case sys.ARM:
 		fh.Machine = pe.IMAGE_FILE_MACHINE_ARMNT
+	case sys.ARM64:
+		fh.Machine = pe.IMAGE_FILE_MACHINE_ARM64
 	}
 
 	fh.NumberOfSections = uint16(len(f.sections))
@@ -852,8 +920,8 @@
 	}
 	oh64.BaseOfCode = f.textSect.virtualAddress
 	oh.BaseOfCode = f.textSect.virtualAddress
-	oh64.ImageBase = PEBASE
-	oh.ImageBase = PEBASE
+	oh64.ImageBase = uint64(PEBASE)
+	oh.ImageBase = uint32(PEBASE)
 	oh64.SectionAlignment = uint32(PESECTALIGN)
 	oh.SectionAlignment = uint32(PESECTALIGN)
 	oh64.FileAlignment = uint32(PEFILEALIGN)
@@ -891,13 +959,7 @@
 	oh.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_NX_COMPAT
 
 	// The DLL can be relocated at load time.
-	switch ctxt.Arch.Family {
-	case sys.AMD64, sys.I386:
-		if ctxt.BuildMode == BuildModePIE {
-			oh64.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
-			oh.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
-		}
-	case sys.ARM:
+	if needPEBaseReloc(ctxt) {
 		oh64.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
 		oh.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
 	}
@@ -922,9 +984,7 @@
 	// calls that may need more stack than we think.
 	//
 	// The default stack reserve size directly affects only the main
-	// thread, ctrlhandler thread, and profileloop thread. For
-	// these, it must be greater than the stack size assumed by
-	// externalthreadhandler.
+	// thread.
 	//
 	// For other threads, the runtime explicitly asks the kernel
 	// to use the default stack size so that all stacks are
@@ -975,18 +1035,23 @@
 func Peinit(ctxt *Link) {
 	var l int
 
-	switch ctxt.Arch.Family {
-	// 64-bit architectures
-	case sys.AMD64:
+	if ctxt.Arch.PtrSize == 8 {
+		// 64-bit architectures
 		pe64 = 1
+		PEBASE = 1 << 32
+		if ctxt.Arch.Family == sys.AMD64 {
+			// TODO(rsc): For cgo we currently use 32-bit relocations
+			// that fail when PEBASE is too large.
+			// We need to fix this, but for now, use a smaller PEBASE.
+			PEBASE = 1 << 22
+		}
 		var oh64 pe.OptionalHeader64
 		l = binary.Size(&oh64)
-
-	// 32-bit architectures
-	default:
+	} else {
+		// 32-bit architectures
+		PEBASE = 1 << 22
 		var oh pe.OptionalHeader32
 		l = binary.Size(&oh)
-
 	}
 
 	if ctxt.LinkMode == LinkExternal {
@@ -1210,7 +1275,7 @@
 	endoff := ctxt.Out.Offset()
 
 	// write FirstThunks (allocated in .data section)
-	ftbase := uint64(ldr.SymValue(dynamic)) - uint64(datsect.virtualAddress) - PEBASE
+	ftbase := uint64(ldr.SymValue(dynamic)) - uint64(datsect.virtualAddress) - uint64(PEBASE)
 
 	ctxt.Out.SeekSet(int64(uint64(datsect.pointerToRawData) + ftbase))
 	for d := dr; d != nil; d = d.next {
@@ -1463,17 +1528,18 @@
 	}
 }
 
+func needPEBaseReloc(ctxt *Link) bool {
+	// Non-PIE x86 binaries don't need the base relocation table.
+	// Everyone else does.
+	if (ctxt.Arch.Family == sys.I386 || ctxt.Arch.Family == sys.AMD64) && ctxt.BuildMode != BuildModePIE {
+		return false
+	}
+	return true
+}
+
 func addPEBaseReloc(ctxt *Link) {
-	// Arm does not work without base relocation table.
-	// 386 and amd64 will only require the table for BuildModePIE.
-	switch ctxt.Arch.Family {
-	default:
+	if !needPEBaseReloc(ctxt) {
 		return
-	case sys.I386, sys.AMD64:
-		if ctxt.BuildMode != BuildModePIE {
-			return
-		}
-	case sys.ARM:
 	}
 
 	var rt peBaseRelocTable
@@ -1562,14 +1628,8 @@
 }
 
 func asmbPe(ctxt *Link) {
-	switch ctxt.Arch.Family {
-	default:
-		Exitf("unknown PE architecture: %v", ctxt.Arch.Family)
-	case sys.AMD64, sys.I386, sys.ARM:
-	}
-
 	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
+	t.characteristics = IMAGE_SCN_CNT_CODE | 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.
diff --git a/src/cmd/link/internal/ld/sym.go b/src/cmd/link/internal/ld/sym.go
index 7548972..7263996 100644
--- a/src/cmd/link/internal/ld/sym.go
+++ b/src/cmd/link/internal/ld/sym.go
@@ -36,6 +36,7 @@
 	"cmd/internal/sys"
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
+	"internal/buildcfg"
 	"log"
 	"runtime"
 )
@@ -53,8 +54,8 @@
 		generatorSyms: make(map[loader.Sym]generatorFunc),
 	}
 
-	if objabi.GOARCH != arch.Name {
-		log.Fatalf("invalid objabi.GOARCH %s (want %s)", objabi.GOARCH, arch.Name)
+	if buildcfg.GOARCH != arch.Name {
+		log.Fatalf("invalid buildcfg.GOARCH %s (want %s)", buildcfg.GOARCH, arch.Name)
 	}
 
 	AtExit(func() {
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index f54cf9e..00f5578 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -37,6 +37,7 @@
 	"cmd/link/internal/sym"
 	"debug/elf"
 	"fmt"
+	"internal/buildcfg"
 	"path/filepath"
 	"strings"
 )
@@ -104,6 +105,7 @@
 	}
 
 	sname := ldr.SymExtname(x)
+	sname = mangleABIName(ctxt, ldr, x, sname)
 
 	// One pass for each binding: elf.STB_LOCAL, elf.STB_GLOBAL,
 	// maybe one day elf.STB_WEAK.
@@ -583,7 +585,9 @@
 			strings.HasPrefix(name, "gclocals."),
 			strings.HasPrefix(name, "gclocals·"),
 			ldr.SymType(s) == sym.SGOFUNC && s != symgofunc,
-			strings.HasSuffix(name, ".opendefer"):
+			strings.HasSuffix(name, ".opendefer"),
+			strings.HasSuffix(name, ".arginfo0"),
+			strings.HasSuffix(name, ".arginfo1"):
 			symGroupType[s] = sym.SGOFUNC
 			ldr.SetAttrNotInSymbolTable(s, true)
 			ldr.SetCarrierSym(s, symgofunc)
@@ -830,3 +834,39 @@
 func isStaticTmp(name string) bool {
 	return strings.Contains(name, "."+obj.StaticNamePref)
 }
+
+// Mangle function name with ABI information.
+func mangleABIName(ctxt *Link, ldr *loader.Loader, x loader.Sym, name string) string {
+	// For functions with ABI wrappers, we have to make sure that we
+	// don't wind up with two symbol table entries with the same
+	// name (since this will generated an error from the external
+	// linker). If we have wrappers, keep the ABIInternal name
+	// unmangled since we want cross-load-module calls to target
+	// ABIInternal, and rename other symbols.
+	//
+	// TODO: avoid the ldr.Lookup calls below by instead using an aux
+	// sym or marker relocation to associate the wrapper with the
+	// wrapped function.
+	if !buildcfg.Experiment.RegabiWrappers {
+		return name
+	}
+
+	if !ldr.IsExternal(x) && ldr.SymType(x) == sym.STEXT && ldr.SymVersion(x) != sym.SymVerABIInternal {
+		if s2 := ldr.Lookup(name, sym.SymVerABIInternal); s2 != 0 && ldr.SymType(s2) == sym.STEXT {
+			name = fmt.Sprintf("%s.abi%d", name, ldr.SymVersion(x))
+		}
+	}
+
+	// When loading a shared library, if a symbol has only one ABI,
+	// and the name is not mangled, we don't know what ABI it is.
+	// So we always mangle ABIInternal function name in shared linkage,
+	// except symbols that are exported to C. Type symbols are always
+	// ABIInternal so they are not mangled.
+	if ctxt.IsShared() {
+		if ldr.SymType(x) == sym.STEXT && ldr.SymVersion(x) == sym.SymVerABIInternal && !ldr.AttrCgoExport(x) && !strings.HasPrefix(name, "type.") {
+			name = fmt.Sprintf("%s.abiinternal", name)
+		}
+	}
+
+	return name
+}
diff --git a/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod3.go b/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod3.go
index 9a8dfbc..37c8937 100644
--- a/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod3.go
+++ b/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod3.go
@@ -14,7 +14,7 @@
 
 func (s S) M() { println("S.M") }
 
-type I interface { M() }
+type I interface{ M() }
 
 type T float64
 
diff --git a/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod4.go b/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod4.go
index 52ee2e3..4af47ad 100644
--- a/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod4.go
+++ b/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod4.go
@@ -10,6 +10,7 @@
 
 type T int
 
+//go:noinline
 func (T) M() {}
 
 type I interface{ M() }
@@ -20,4 +21,5 @@
 func main() {
 	p = new(T)  // use type T
 	pp = new(I) // use type I
+	*pp = *p    // convert T to I, build itab
 }
diff --git a/src/cmd/link/internal/ld/testdata/issue42484/main.go b/src/cmd/link/internal/ld/testdata/issue42484/main.go
new file mode 100644
index 0000000..60fc110
--- /dev/null
+++ b/src/cmd/link/internal/ld/testdata/issue42484/main.go
@@ -0,0 +1,16 @@
+package main
+
+import (
+	"fmt"
+)
+
+func main() {
+	a := 0
+	a++
+	b := 0
+	f1(a, b)
+}
+
+func f1(a, b int) {
+	fmt.Printf("%d %d\n", a, b)
+}
diff --git a/src/cmd/link/internal/ld/util.go b/src/cmd/link/internal/ld/util.go
index 9228ed1..779f498 100644
--- a/src/cmd/link/internal/ld/util.go
+++ b/src/cmd/link/internal/ld/util.go
@@ -57,7 +57,7 @@
 // Logging an error means that on exit cmd/link will delete any
 // output file and return a non-zero error code.
 //
-// TODO: remove. Use ctxt.Errof instead.
+// TODO: remove. Use ctxt.Errorf instead.
 // All remaining calls use nil as first arg.
 func Errorf(dummy *int, format string, args ...interface{}) {
 	format += "\n"
diff --git a/src/cmd/link/internal/ld/xcoff.go b/src/cmd/link/internal/ld/xcoff.go
index ba818ea..12bd23f 100644
--- a/src/cmd/link/internal/ld/xcoff.go
+++ b/src/cmd/link/internal/ld/xcoff.go
@@ -28,8 +28,11 @@
 	// Total amount of space to reserve at the start of the file
 	// for File Header, Auxiliary Header, and Section Headers.
 	// May waste some.
-	XCOFFHDRRESERVE       = FILHSZ_64 + AOUTHSZ_EXEC64 + SCNHSZ_64*23
-	XCOFFSECTALIGN  int64 = 32 // base on dump -o
+	XCOFFHDRRESERVE = FILHSZ_64 + AOUTHSZ_EXEC64 + SCNHSZ_64*23
+
+	// base on dump -o, then rounded from 32B to 64B to
+	// match worst case elf text section alignment on ppc64.
+	XCOFFSECTALIGN int64 = 64
 
 	// XCOFF binaries should normally have all its sections position-independent.
 	// However, this is not yet possible for .text because of some R_ADDR relocations
@@ -555,11 +558,12 @@
 
 // type records C_FILE information needed for genasmsym in XCOFF.
 type xcoffSymSrcFile struct {
-	name       string
-	file       *XcoffSymEnt64   // Symbol of this C_FILE
-	csectAux   *XcoffAuxCSect64 // Symbol for the current .csect
-	csectSymNb uint64           // Symbol number for the current .csect
-	csectSize  int64
+	name         string
+	file         *XcoffSymEnt64   // Symbol of this C_FILE
+	csectAux     *XcoffAuxCSect64 // Symbol for the current .csect
+	csectSymNb   uint64           // Symbol number for the current .csect
+	csectVAStart int64
+	csectVAEnd   int64
 }
 
 var (
@@ -746,7 +750,8 @@
 	f.addSymbol(aux)
 
 	currSymSrcFile.csectAux = aux
-	currSymSrcFile.csectSize = 0
+	currSymSrcFile.csectVAStart = int64(firstEntry)
+	currSymSrcFile.csectVAEnd = int64(firstEntry)
 }
 
 // Update values for the previous package.
@@ -768,8 +773,9 @@
 
 	// update csect scnlen in this auxiliary entry
 	aux := currSymSrcFile.csectAux
-	aux.Xscnlenlo = uint32(currSymSrcFile.csectSize & 0xFFFFFFFF)
-	aux.Xscnlenhi = uint32(currSymSrcFile.csectSize >> 32)
+	csectSize := currSymSrcFile.csectVAEnd - currSymSrcFile.csectVAStart
+	aux.Xscnlenlo = uint32(csectSize & 0xFFFFFFFF)
+	aux.Xscnlenhi = uint32(csectSize >> 32)
 }
 
 // Write symbol representing a .text function.
@@ -825,15 +831,20 @@
 		Nnumaux: 2,
 	}
 
-	if ldr.SymVersion(x) != 0 || ldr.AttrVisibilityHidden(x) || ldr.AttrLocal(x) {
+	if ldr.IsFileLocal(x) || ldr.AttrVisibilityHidden(x) || ldr.AttrLocal(x) {
 		s.Nsclass = C_HIDEXT
 	}
 
 	ldr.SetSymDynid(x, int32(xfile.symbolCount))
 	syms = append(syms, s)
 
-	// Update current csect size
-	currSymSrcFile.csectSize += ldr.SymSize(x)
+	// Keep track of the section size by tracking the VA range. Individual
+	// alignment differences may introduce a few extra bytes of padding
+	// which are not fully accounted for by ldr.SymSize(x).
+	sv := ldr.SymValue(x) + ldr.SymSize(x)
+	if currSymSrcFile.csectVAEnd < sv {
+		currSymSrcFile.csectVAEnd = sv
+	}
 
 	// create auxiliary entries
 	a2 := &XcoffAuxFcn64{
@@ -914,7 +925,7 @@
 			Nnumaux: 1,
 		}
 
-		if ldr.SymVersion(x) != 0 || ldr.AttrVisibilityHidden(x) || ldr.AttrLocal(x) {
+		if ldr.IsFileLocal(x) || ldr.AttrVisibilityHidden(x) || ldr.AttrLocal(x) {
 			// There is more symbols in the case of a global data
 			// which are related to the assembly generated
 			// to access such symbols.
@@ -1318,19 +1329,14 @@
 			if !ldr.AttrCgoExport(s) {
 				continue
 			}
-			if ldr.SymVersion(s) != 0 { // sanity check
-				panic("cgo_export on non-version 0 symbol")
+			if ldr.IsFileLocal(s) {
+				panic("cgo_export on static symbol")
 			}
 
 			if ldr.SymType(s) == sym.STEXT || ldr.SymType(s) == sym.SABIALIAS {
 				// On AIX, a exported function must have two symbols:
 				// - a .text symbol which must start with a ".".
 				// - a .data symbol which is a function descriptor.
-				//
-				// CgoExport attribute should only be set on a version 0
-				// symbol, which can be TEXT or ABIALIAS.
-				// (before, setupdynexp copies the attribute from the
-				// alias to the aliased. Now we are before setupdynexp.)
 				name := ldr.SymExtname(s)
 				ldr.SetSymExtname(s, "."+name)
 
@@ -1554,7 +1560,7 @@
 		f.xahdr.Otoc = uint64(ldr.SymValue(toc))
 		f.xahdr.Osntoc = f.getXCOFFscnum(ldr.SymSect(toc))
 
-		f.xahdr.Oalgntext = int16(logBase2(int(Funcalign)))
+		f.xahdr.Oalgntext = int16(logBase2(int(XCOFFSECTALIGN)))
 		f.xahdr.Oalgndata = 0x5
 
 		binary.Write(ctxt.Out, binary.BigEndian, &f.xfhdr)
@@ -1787,8 +1793,8 @@
 		if !strings.HasPrefix(extname, "._cgoexp_") {
 			continue
 		}
-		if ldr.SymVersion(s) != 0 {
-			continue // Only export version 0 symbols. See the comment in doxcoff.
+		if ldr.IsFileLocal(s) {
+			continue // Only export non-static symbols
 		}
 
 		// Retrieve the name of the initial symbol
diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go
index c698874..c695629 100644
--- a/src/cmd/link/internal/loadelf/ldelf.go
+++ b/src/cmd/link/internal/loadelf/ldelf.go
@@ -245,13 +245,13 @@
 	newSym := func(name string, version int) loader.Sym {
 		return l.CreateStaticSym(name)
 	}
-	lookup := func(name string, version int) loader.Sym {
-		return l.LookupOrCreateSym(name, version)
-	}
+	lookup := l.LookupOrCreateCgoExport
 	errorf := func(str string, args ...interface{}) ([]loader.Sym, uint32, error) {
 		return nil, 0, fmt.Errorf("loadelf: %s: %v", pn, fmt.Sprintf(str, args...))
 	}
 
+	ehdrFlags = initEhdrFlags
+
 	base := f.Offset()
 
 	var hdrbuf [64]byte
@@ -753,7 +753,7 @@
 			}
 
 			rType := objabi.ElfRelocOffset + objabi.RelocType(relocType)
-			rSize, err := relSize(arch, pn, uint32(relocType))
+			rSize, addendSize, err := relSize(arch, pn, uint32(relocType))
 			if err != nil {
 				return nil, 0, err
 			}
@@ -770,10 +770,10 @@
 				}
 			}
 
-			if rSize == 2 {
+			if addendSize == 2 {
 				rAdd = int64(int16(rAdd))
 			}
-			if rSize == 4 {
+			if addendSize == 4 {
 				rAdd = int64(int32(rAdd))
 			}
 
@@ -945,7 +945,10 @@
 	return nil
 }
 
-func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
+// Return the size of the relocated field, and the size of the addend as the first
+// and second values. Note, the addend may be larger than the relocation field in
+// some cases when a relocated value is split across multiple relocations.
+func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, 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.
@@ -964,7 +967,7 @@
 
 	switch uint32(arch.Family) | elftype<<16 {
 	default:
-		return 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
+		return 0, 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
 
 	case MIPS | uint32(elf.R_MIPS_HI16)<<16,
 		MIPS | uint32(elf.R_MIPS_LO16)<<16,
@@ -983,27 +986,23 @@
 		MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16,
 		MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16,
 		MIPS64 | uint32(elf.R_MIPS_JALR)<<16,
-		MIPS64 | uint32(elf.R_MIPS_GOT_OFST)<<16:
-		return 4, nil
+		MIPS64 | uint32(elf.R_MIPS_GOT_OFST)<<16,
+		MIPS64 | uint32(elf.R_MIPS_CALL16)<<16,
+		MIPS64 | uint32(elf.R_MIPS_GPREL32)<<16,
+		MIPS64 | uint32(elf.R_MIPS_64)<<16,
+		MIPS64 | uint32(elf.R_MIPS_GOT_DISP)<<16:
+		return 4, 4, nil
 
 	case S390X | uint32(elf.R_390_8)<<16:
-		return 1, nil
+		return 1, 1, nil
 
 	case PPC64 | uint32(elf.R_PPC64_TOC16)<<16,
-		PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<16,
-		PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<16,
-		PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<16,
-		PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<16,
-		PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16,
-		PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16,
-		PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16,
-		PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16,
 		S390X | uint32(elf.R_390_16)<<16,
 		S390X | uint32(elf.R_390_GOT16)<<16,
 		S390X | uint32(elf.R_390_PC16)<<16,
 		S390X | uint32(elf.R_390_PC16DBL)<<16,
 		S390X | uint32(elf.R_390_PLT16DBL)<<16:
-		return 2, nil
+		return 2, 2, nil
 
 	case ARM | uint32(elf.R_ARM_ABS32)<<16,
 		ARM | uint32(elf.R_ARM_GOT32)<<16,
@@ -1051,7 +1050,7 @@
 		S390X | uint32(elf.R_390_PLT32DBL)<<16,
 		S390X | uint32(elf.R_390_GOTPCDBL)<<16,
 		S390X | uint32(elf.R_390_GOTENT)<<16:
-		return 4, nil
+		return 4, 4, nil
 
 	case AMD64 | uint32(elf.R_X86_64_64)<<16,
 		AMD64 | uint32(elf.R_X86_64_PC64)<<16,
@@ -1066,11 +1065,11 @@
 		S390X | uint32(elf.R_390_PC64)<<16,
 		S390X | uint32(elf.R_390_GOT64)<<16,
 		S390X | uint32(elf.R_390_PLT64)<<16:
-		return 8, nil
+		return 8, 8, nil
 
 	case RISCV64 | uint32(elf.R_RISCV_RVC_BRANCH)<<16,
 		RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16:
-		return 2, nil
+		return 2, 2, nil
 
 	case RISCV64 | uint32(elf.R_RISCV_32)<<16,
 		RISCV64 | uint32(elf.R_RISCV_BRANCH)<<16,
@@ -1082,12 +1081,22 @@
 		RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_I)<<16,
 		RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_S)<<16,
 		RISCV64 | uint32(elf.R_RISCV_RELAX)<<16:
-		return 4, nil
+		return 4, 4, nil
 
 	case RISCV64 | uint32(elf.R_RISCV_64)<<16,
 		RISCV64 | uint32(elf.R_RISCV_CALL)<<16,
 		RISCV64 | uint32(elf.R_RISCV_CALL_PLT)<<16:
-		return 8, nil
+		return 8, 8, nil
+
+	case PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<16,
+		PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<16,
+		PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<16,
+		PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<16,
+		PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16,
+		PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16,
+		PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16,
+		PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16:
+		return 2, 4, nil
 	}
 }
 
diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go
index 971cc43..9d5319c 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -51,30 +51,14 @@
 	*goobj.Reloc
 	r *oReader
 	l *Loader
-
-	// External reloc types may not fit into a uint8 which the Go object file uses.
-	// Store it here, instead of in the byte of goobj.Reloc.
-	// For Go symbols this will always be zero.
-	// goobj.Reloc.Type() + typ is always the right type, for both Go and external
-	// symbols.
-	typ objabi.RelocType
 }
 
-func (rel Reloc) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc.Type()) + rel.typ }
-func (rel Reloc) Sym() Sym               { return rel.l.resolve(rel.r, rel.Reloc.Sym()) }
-func (rel Reloc) SetSym(s Sym)           { rel.Reloc.SetSym(goobj.SymRef{PkgIdx: 0, SymIdx: uint32(s)}) }
-func (rel Reloc) IsMarker() bool         { return rel.Siz() == 0 }
-
-func (rel Reloc) SetType(t objabi.RelocType) {
-	if t != objabi.RelocType(uint8(t)) {
-		panic("SetType: type doesn't fit into Reloc")
-	}
-	rel.Reloc.SetType(uint8(t))
-	if rel.typ != 0 {
-		// should use SymbolBuilder.SetRelocType
-		panic("wrong method to set reloc type")
-	}
-}
+func (rel Reloc) Type() objabi.RelocType     { return objabi.RelocType(rel.Reloc.Type()) &^ objabi.R_WEAK }
+func (rel Reloc) Weak() bool                 { return objabi.RelocType(rel.Reloc.Type())&objabi.R_WEAK != 0 }
+func (rel Reloc) SetType(t objabi.RelocType) { rel.Reloc.SetType(uint16(t)) }
+func (rel Reloc) Sym() Sym                   { return rel.l.resolve(rel.r, rel.Reloc.Sym()) }
+func (rel Reloc) SetSym(s Sym)               { rel.Reloc.SetSym(goobj.SymRef{PkgIdx: 0, SymIdx: uint32(s)}) }
+func (rel Reloc) IsMarker() bool             { return rel.Siz() == 0 }
 
 // Aux holds a "handle" to access an aux symbol record from an
 // object file.
@@ -241,7 +225,6 @@
 	attrExternal         Bitmap // external symbols, indexed by ext sym index
 
 	attrReadOnly         map[Sym]bool     // readonly data for this sym
-	attrTopFrame         map[Sym]struct{} // top frame symbols
 	attrSpecial          map[Sym]struct{} // "special" frame symbols
 	attrCgoExportDynamic map[Sym]struct{} // "cgo_export_dynamic" symbols
 	attrCgoExportStatic  map[Sym]struct{} // "cgo_export_static" symbols
@@ -274,6 +257,9 @@
 	// the symbol that triggered the marking of symbol K as live.
 	Reachparent []Sym
 
+	// CgoExports records cgo-exported symbols by SymName.
+	CgoExports map[string]Sym
+
 	flags uint32
 
 	hasUnknownPkgPath bool // if any Go object has unknown package path
@@ -308,20 +294,20 @@
 // extSymPayload holds the payload (data + relocations) for linker-synthesized
 // external symbols (note that symbol value is stored in a separate slice).
 type extSymPayload struct {
-	name     string // TODO: would this be better as offset into str table?
-	size     int64
-	ver      int
-	kind     sym.SymKind
-	objidx   uint32 // index of original object if sym made by cloneToExternal
-	relocs   []goobj.Reloc
-	reltypes []objabi.RelocType // relocation types
-	data     []byte
-	auxs     []goobj.Aux
+	name   string // TODO: would this be better as offset into str table?
+	size   int64
+	ver    int
+	kind   sym.SymKind
+	objidx uint32 // index of original object if sym made by cloneToExternal
+	relocs []goobj.Reloc
+	data   []byte
+	auxs   []goobj.Aux
 }
 
 const (
 	// Loader.flags
 	FlagStrictDups = 1 << iota
+	FlagUseABIAlias
 )
 
 func NewLoader(flags uint32, elfsetstring elfsetstringFunc, reporter *ErrorReporter) *Loader {
@@ -348,7 +334,6 @@
 		plt:                  make(map[Sym]int32),
 		got:                  make(map[Sym]int32),
 		dynid:                make(map[Sym]int32),
-		attrTopFrame:         make(map[Sym]struct{}),
 		attrSpecial:          make(map[Sym]struct{}),
 		attrCgoExportDynamic: make(map[Sym]struct{}),
 		attrCgoExportStatic:  make(map[Sym]struct{}),
@@ -474,6 +459,15 @@
 		if l.flags&FlagStrictDups != 0 {
 			l.checkdup(name, r, li, oldi)
 		}
+		// Fix for issue #47185 -- given two dupok symbols with
+		// different sizes, favor symbol with larger size. See
+		// also issue #46653.
+		szdup := l.SymSize(oldi)
+		sz := int64(r.Sym(li).Siz())
+		if szdup < sz {
+			// new symbol overwrites old symbol.
+			l.objSyms[oldi] = objSym{r.objidx, li}
+		}
 		return oldi
 	}
 	oldr, oldli := l.toLocal(oldi)
@@ -486,14 +480,14 @@
 		// new symbol overwrites old symbol.
 		oldtyp := sym.AbiSymKindToSymKind[objabi.SymKind(oldsym.Type())]
 		if !(oldtyp.IsData() && oldr.DataSize(oldli) == 0) {
-			log.Fatalf("duplicated definition of symbol " + name)
+			log.Fatalf("duplicated definition of symbol %s, from %s and %s", name, r.unit.Lib.Pkg, oldr.unit.Lib.Pkg)
 		}
 		l.objSyms[oldi] = objSym{r.objidx, li}
 	} else {
 		// old symbol overwrites new symbol.
 		typ := sym.AbiSymKindToSymKind[objabi.SymKind(oldsym.Type())]
 		if !typ.IsData() { // only allow overwriting data symbol
-			log.Fatalf("duplicated definition of symbol " + name)
+			log.Fatalf("duplicated definition of symbol %s, from %s and %s", name, r.unit.Lib.Pkg, oldr.unit.Lib.Pkg)
 		}
 	}
 	return oldi
@@ -532,6 +526,36 @@
 	return i
 }
 
+// AddCgoExport records a cgo-exported symbol in l.CgoExports.
+// This table is used to identify the correct Go symbol ABI to use
+// to resolve references from host objects (which don't have ABIs).
+func (l *Loader) AddCgoExport(s Sym) {
+	if l.CgoExports == nil {
+		l.CgoExports = make(map[string]Sym)
+	}
+	l.CgoExports[l.SymName(s)] = s
+}
+
+// LookupOrCreateCgoExport is like LookupOrCreateSym, but if ver
+// indicates a global symbol, it uses the CgoExport table to determine
+// the appropriate symbol version (ABI) to use. ver must be either 0
+// or a static symbol version.
+func (l *Loader) LookupOrCreateCgoExport(name string, ver int) Sym {
+	if ver >= sym.SymVerStatic {
+		return l.LookupOrCreateSym(name, ver)
+	}
+	if ver != 0 {
+		panic("ver must be 0 or a static version")
+	}
+	// Look for a cgo-exported symbol from Go.
+	if s, ok := l.CgoExports[name]; ok {
+		return s
+	}
+	// Otherwise, this must just be a symbol in the host object.
+	// Create a version 0 symbol for it.
+	return l.LookupOrCreateSym(name, 0)
+}
+
 func (l *Loader) IsExternal(i Sym) bool {
 	r, _ := l.toLocal(i)
 	return l.isExtReader(r)
@@ -684,12 +708,18 @@
 	p := r.Data(li)
 	rdup, ldup := l.toLocal(dup)
 	pdup := rdup.Data(ldup)
-	if bytes.Equal(p, pdup) {
-		return
-	}
 	reason := "same length but different contents"
 	if len(p) != len(pdup) {
 		reason = fmt.Sprintf("new length %d != old length %d", len(p), len(pdup))
+	} else if bytes.Equal(p, pdup) {
+		// For BSS symbols, we need to check size as well, see issue 46653.
+		szdup := l.SymSize(dup)
+		sz := int64(r.Sym(li).Siz())
+		if szdup == sz {
+			return
+		}
+		reason = fmt.Sprintf("different sizes: new size %d != old size %d",
+			sz, szdup)
 	}
 	fmt.Fprintf(os.Stderr, "cmd/link: while reading object for '%v': duplicate symbol '%s', previous def at '%v', with mismatched payload: %s\n", r.unit.Lib, name, rdup.unit.Lib, reason)
 
@@ -756,6 +786,9 @@
 		return pp.name
 	}
 	r, li := l.toLocal(i)
+	if r == nil {
+		return "?"
+	}
 	name := r.Sym(li).Name(r.Reader)
 	if !r.NeedNameExpansion() {
 		return name
@@ -1008,24 +1041,6 @@
 	}
 }
 
-// AttrTopFrame returns true for a function symbol that is an entry
-// point, meaning that unwinders should stop when they hit this
-// function.
-func (l *Loader) AttrTopFrame(i Sym) bool {
-	_, ok := l.attrTopFrame[i]
-	return ok
-}
-
-// SetAttrTopFrame sets the "top frame" property for a symbol (see
-// AttrTopFrame).
-func (l *Loader) SetAttrTopFrame(i Sym, v bool) {
-	if v {
-		l.attrTopFrame[i] = struct{}{}
-	} else {
-		delete(l.attrTopFrame, i)
-	}
-}
-
 // AttrSpecial returns true for a symbols that do not have their
 // address (i.e. Value) computed by the usual mechanism of
 // data.go:dodata() & data.go:address().
@@ -1446,7 +1461,7 @@
 	}
 }
 
-// SymPlt returns the plt value for pe symbols.
+// SymPlt returns the PLT offset of symbol s.
 func (l *Loader) SymPlt(s Sym) int32 {
 	if v, ok := l.plt[s]; ok {
 		return v
@@ -1454,7 +1469,7 @@
 	return -1
 }
 
-// SetPlt sets the plt value for pe symbols.
+// SetPlt sets the PLT offset of symbol i.
 func (l *Loader) SetPlt(i Sym, v int32) {
 	if i >= Sym(len(l.objSyms)) || i == 0 {
 		panic("bad symbol for SetPlt")
@@ -1466,7 +1481,7 @@
 	}
 }
 
-// SymGot returns the got value for pe symbols.
+// SymGot returns the GOT offset of symbol s.
 func (l *Loader) SymGot(s Sym) int32 {
 	if v, ok := l.got[s]; ok {
 		return v
@@ -1474,7 +1489,7 @@
 	return -1
 }
 
-// SetGot sets the got value for pe symbols.
+// SetGot sets the GOT offset of symbol i.
 func (l *Loader) SetGot(i Sym, v int32) {
 	if i >= Sym(len(l.objSyms)) || i == 0 {
 		panic("bad symbol for SetGot")
@@ -1566,7 +1581,7 @@
 // regular compiler-generated Go symbols), but in the case of
 // building with "-linkshared" (when a symbol is read from a
 // shared library), will hold the library name.
-// NOTE: this correspondes to sym.Symbol.File field.
+// NOTE: this corresponds to sym.Symbol.File field.
 func (l *Loader) SymPkg(i Sym) string {
 	if f, ok := l.symPkg[i]; ok {
 		return f
@@ -1852,10 +1867,9 @@
 // At returns the j-th reloc for a global symbol.
 func (relocs *Relocs) At(j int) Reloc {
 	if relocs.l.isExtReader(relocs.r) {
-		pp := relocs.l.payloads[relocs.li]
-		return Reloc{&relocs.rs[j], relocs.r, relocs.l, pp.reltypes[j]}
+		return Reloc{&relocs.rs[j], relocs.r, relocs.l}
 	}
-	return Reloc{&relocs.rs[j], relocs.r, relocs.l, 0}
+	return Reloc{&relocs.rs[j], relocs.r, relocs.l}
 }
 
 // Relocs returns a Relocs object for the given global sym.
@@ -1904,7 +1918,11 @@
 }
 
 func (fi *FuncInfo) FuncID() objabi.FuncID {
-	return objabi.FuncID((*goobj.FuncInfo)(nil).ReadFuncID(fi.data))
+	return (*goobj.FuncInfo)(nil).ReadFuncID(fi.data)
+}
+
+func (fi *FuncInfo) FuncFlag() objabi.FuncFlag {
+	return (*goobj.FuncInfo)(nil).ReadFuncFlag(fi.data)
 }
 
 func (fi *FuncInfo) Pcsp() Sym {
@@ -1991,6 +2009,13 @@
 	return (*goobj.FuncInfo)(nil).ReadFile(fi.data, fi.lengths.FileOff, uint32(k))
 }
 
+// TopFrame returns true if the function associated with this FuncInfo
+// is an entry point, meaning that unwinders should stop when they hit
+// this function.
+func (fi *FuncInfo) TopFrame() bool {
+	return (fi.FuncFlag() & objabi.FuncFlag_TOPFRAME) != 0
+}
+
 type InlTreeNode struct {
 	Parent   int32
 	File     goobj.CUFileIndex
@@ -2150,9 +2175,6 @@
 		}
 		gi := st.addSym(name, v, r, i, kind, osym)
 		r.syms[i] = gi
-		if osym.TopFrame() {
-			l.SetAttrTopFrame(gi, true)
-		}
 		if osym.Local() {
 			l.SetAttrLocal(gi, true)
 		}
@@ -2237,7 +2259,7 @@
 		pkg := r.Pkg(i)
 		objidx, ok := l.objByPkg[pkg]
 		if !ok {
-			log.Fatalf("reference of nonexisted package %s, from %v", pkg, r.unit.Lib)
+			log.Fatalf("%v: reference to nonexistent package %s", r.unit.Lib, pkg)
 		}
 		r.pkg[i] = objidx
 	}
@@ -2270,6 +2292,9 @@
 // symbol. If the sym in question is not an alias, the sym itself is
 // returned.
 func (l *Loader) ResolveABIAlias(s Sym) Sym {
+	if l.flags&FlagUseABIAlias == 0 {
+		return s
+	}
 	if s == 0 {
 		return 0
 	}
@@ -2345,13 +2370,11 @@
 		// Copy relocations
 		relocs := l.Relocs(symIdx)
 		pp.relocs = make([]goobj.Reloc, relocs.Count())
-		pp.reltypes = make([]objabi.RelocType, relocs.Count())
 		for i := range pp.relocs {
 			// Copy the relocs slice.
 			// Convert local reference to global reference.
 			rel := relocs.At(i)
-			pp.relocs[i].Set(rel.Off(), rel.Siz(), 0, rel.Add(), goobj.SymRef{PkgIdx: 0, SymIdx: uint32(rel.Sym())})
-			pp.reltypes[i] = rel.Type()
+			pp.relocs[i].Set(rel.Off(), rel.Siz(), uint16(rel.Type()), rel.Add(), goobj.SymRef{PkgIdx: 0, SymIdx: uint32(rel.Sym())})
 		}
 
 		// Copy data
@@ -2407,7 +2430,6 @@
 		// when copying attributes from a dupOK ABI wrapper symbol to
 		// the real target symbol (which may not be marked dupOK).
 	}
-	l.SetAttrTopFrame(dst, l.AttrTopFrame(src))
 	l.SetAttrSpecial(dst, l.AttrSpecial(src))
 	l.SetAttrCgoExportDynamic(dst, l.AttrCgoExportDynamic(src))
 	l.SetAttrCgoExportStatic(dst, l.AttrCgoExportStatic(src))
@@ -2567,7 +2589,7 @@
 			for i, list := range lists {
 				for _, s := range list {
 					sym := Sym(s)
-					if l.attrReachable.Has(sym) && !assignedToUnit.Has(sym) {
+					if !assignedToUnit.Has(sym) {
 						textp = append(textp, sym)
 						unit := l.SymUnit(sym)
 						if unit != nil {
diff --git a/src/cmd/link/internal/loader/loader_test.go b/src/cmd/link/internal/loader/loader_test.go
index 1371c2a..15ae830 100644
--- a/src/cmd/link/internal/loader/loader_test.go
+++ b/src/cmd/link/internal/loader/loader_test.go
@@ -237,7 +237,8 @@
 type addFunc func(l *Loader, s Sym, s2 Sym) Sym
 
 func mkReloc(l *Loader, typ objabi.RelocType, off int32, siz uint8, add int64, sym Sym) Reloc {
-	r := Reloc{&goobj.Reloc{}, l.extReader, l, typ}
+	r := Reloc{&goobj.Reloc{}, l.extReader, l}
+	r.SetType(typ)
 	r.SetOff(off)
 	r.SetSiz(siz)
 	r.SetAdd(add)
diff --git a/src/cmd/link/internal/loader/symbolbuilder.go b/src/cmd/link/internal/loader/symbolbuilder.go
index 5d37da8..204d044 100644
--- a/src/cmd/link/internal/loader/symbolbuilder.go
+++ b/src/cmd/link/internal/loader/symbolbuilder.go
@@ -121,13 +121,11 @@
 // ResetRelocs removes all relocations on this symbol.
 func (sb *SymbolBuilder) ResetRelocs() {
 	sb.relocs = sb.relocs[:0]
-	sb.reltypes = sb.reltypes[:0]
 }
 
 // SetRelocType sets the type of the 'i'-th relocation on this sym to 't'
 func (sb *SymbolBuilder) SetRelocType(i int, t objabi.RelocType) {
-	sb.relocs[i].SetType(0)
-	sb.reltypes[i] = t
+	sb.relocs[i].SetType(uint16(t))
 }
 
 // SetRelocSym sets the target sym of the 'i'-th relocation on this sym to 's'
@@ -143,7 +141,6 @@
 // Add n relocations, return a handle to the relocations.
 func (sb *SymbolBuilder) AddRelocs(n int) Relocs {
 	sb.relocs = append(sb.relocs, make([]goobj.Reloc, n)...)
-	sb.reltypes = append(sb.reltypes, make([]objabi.RelocType, n)...)
 	return sb.l.Relocs(sb.symIdx)
 }
 
@@ -152,7 +149,7 @@
 func (sb *SymbolBuilder) AddRel(typ objabi.RelocType) (Reloc, int) {
 	j := len(sb.relocs)
 	sb.relocs = append(sb.relocs, goobj.Reloc{})
-	sb.reltypes = append(sb.reltypes, typ)
+	sb.relocs[j].SetType(uint16(typ))
 	relocs := sb.Relocs()
 	return relocs.At(j), j
 }
@@ -169,7 +166,6 @@
 func (p *relocsByOff) Less(i, j int) bool { return p.relocs[i].Off() < p.relocs[j].Off() }
 func (p *relocsByOff) Swap(i, j int) {
 	p.relocs[i], p.relocs[j] = p.relocs[j], p.relocs[i]
-	p.reltypes[i], p.reltypes[j] = p.reltypes[j], p.reltypes[i]
 }
 
 func (sb *SymbolBuilder) Reachable() bool {
diff --git a/src/cmd/link/internal/loadmacho/ldmacho.go b/src/cmd/link/internal/loadmacho/ldmacho.go
index 6d1d9bb..e7d9eeb 100644
--- a/src/cmd/link/internal/loadmacho/ldmacho.go
+++ b/src/cmd/link/internal/loadmacho/ldmacho.go
@@ -607,7 +607,7 @@
 		if machsym.type_&N_EXT == 0 {
 			v = localSymVersion
 		}
-		s := l.LookupOrCreateSym(name, v)
+		s := l.LookupOrCreateCgoExport(name, v)
 		if machsym.type_&N_EXT == 0 {
 			l.SetAttrDuplicateOK(s, true)
 		}
diff --git a/src/cmd/link/internal/loadpe/ldpe.go b/src/cmd/link/internal/loadpe/ldpe.go
index a5c025d..9cc7eff 100644
--- a/src/cmd/link/internal/loadpe/ldpe.go
+++ b/src/cmd/link/internal/loadpe/ldpe.go
@@ -115,6 +115,24 @@
 	IMAGE_REL_THUMB_BRANCH24         = 0x0014
 	IMAGE_REL_THUMB_BLX23            = 0x0015
 	IMAGE_REL_ARM_PAIR               = 0x0016
+	IMAGE_REL_ARM64_ABSOLUTE         = 0x0000
+	IMAGE_REL_ARM64_ADDR32           = 0x0001
+	IMAGE_REL_ARM64_ADDR32NB         = 0x0002
+	IMAGE_REL_ARM64_BRANCH26         = 0x0003
+	IMAGE_REL_ARM64_PAGEBASE_REL21   = 0x0004
+	IMAGE_REL_ARM64_REL21            = 0x0005
+	IMAGE_REL_ARM64_PAGEOFFSET_12A   = 0x0006
+	IMAGE_REL_ARM64_PAGEOFFSET_12L   = 0x0007
+	IMAGE_REL_ARM64_SECREL           = 0x0008
+	IMAGE_REL_ARM64_SECREL_LOW12A    = 0x0009
+	IMAGE_REL_ARM64_SECREL_HIGH12A   = 0x000A
+	IMAGE_REL_ARM64_SECREL_LOW12L    = 0x000B
+	IMAGE_REL_ARM64_TOKEN            = 0x000C
+	IMAGE_REL_ARM64_SECTION          = 0x000D
+	IMAGE_REL_ARM64_ADDR64           = 0x000E
+	IMAGE_REL_ARM64_BRANCH19         = 0x000F
+	IMAGE_REL_ARM64_BRANCH14         = 0x0010
+	IMAGE_REL_ARM64_REL32            = 0x0011
 )
 
 // TODO(crawshaw): de-duplicate these symbols with cmd/internal/ld, ideally in debug/pe.
@@ -160,11 +178,7 @@
 // If an .rsrc section or set of .rsrc$xx sections is found, its symbols are
 // returned as rsrc.
 func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Reader, pkg string, length int64, pn string) (textp []loader.Sym, rsrc []loader.Sym, err error) {
-	lookup := func(name string, version int) (*loader.SymbolBuilder, loader.Sym) {
-		s := l.LookupOrCreateSym(name, version)
-		sb := l.MakeSymbolUpdater(s)
-		return sb, s
-	}
+	lookup := l.LookupOrCreateCgoExport
 	sectsyms := make(map[*pe.Section]loader.Sym)
 	sectdata := make(map[*pe.Section][]byte)
 
@@ -196,7 +210,8 @@
 		}
 
 		name := fmt.Sprintf("%s(%s)", pkg, sect.Name)
-		bld, s := lookup(name, localSymVersion)
+		s := lookup(name, localSymVersion)
+		bld := l.MakeSymbolUpdater(s)
 
 		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
@@ -254,7 +269,7 @@
 				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(l, arch, l.LookupOrCreateSym, f, pesym, sectsyms, localSymVersion)
+			_, gosym, err := readpesym(l, arch, lookup, f, pesym, sectsyms, localSymVersion)
 			if err != nil {
 				return nil, nil, err
 			}
@@ -321,6 +336,17 @@
 
 					rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
 				}
+
+			case sys.ARM64:
+				switch r.Type {
+				default:
+					return nil, nil, fmt.Errorf("%s: %v: unknown ARM64 relocation type %v", pn, sectsyms[rsect], r.Type)
+
+				case IMAGE_REL_ARM64_ADDR32, IMAGE_REL_ARM64_ADDR32NB:
+					rType = objabi.R_ADDR
+
+					rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
+				}
 			}
 
 			// ld -r could generate multiple section symbols for the
@@ -385,7 +411,7 @@
 			}
 		}
 
-		bld, s, err := readpesym(l, arch, l.LookupOrCreateSym, f, pesym, sectsyms, localSymVersion)
+		bld, s, err := readpesym(l, arch, lookup, f, pesym, sectsyms, localSymVersion)
 		if err != nil {
 			return nil, nil, err
 		}
diff --git a/src/cmd/link/internal/loadxcoff/ldxcoff.go b/src/cmd/link/internal/loadxcoff/ldxcoff.go
index a574421..920e1c8 100644
--- a/src/cmd/link/internal/loadxcoff/ldxcoff.go
+++ b/src/cmd/link/internal/loadxcoff/ldxcoff.go
@@ -121,7 +121,7 @@
 		}
 		sb := l.MakeSymbolUpdater(sect.sym)
 		for _, rx := range sect.Relocs {
-			rSym := l.LookupOrCreateSym(rx.Symbol.Name, 0)
+			rSym := l.LookupOrCreateCgoExport(rx.Symbol.Name, 0)
 			if uint64(int32(rx.VirtualAddress)) != rx.VirtualAddress {
 				return errorf("virtual address of a relocation is too big: 0x%x", rx.VirtualAddress)
 			}
diff --git a/src/cmd/link/internal/mips/asm.go b/src/cmd/link/internal/mips/asm.go
index 17b1b20..8505dc6 100644
--- a/src/cmd/link/internal/mips/asm.go
+++ b/src/cmd/link/internal/mips/asm.go
@@ -140,7 +140,7 @@
 	return val, 0, false
 }
 
-func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64, []byte) int64 {
 	return -1
 }
 
diff --git a/src/cmd/link/internal/mips/obj.go b/src/cmd/link/internal/mips/obj.go
index f20597c..5ca7582 100644
--- a/src/cmd/link/internal/mips/obj.go
+++ b/src/cmd/link/internal/mips/obj.go
@@ -34,11 +34,12 @@
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"cmd/link/internal/ld"
+	"internal/buildcfg"
 )
 
 func Init() (*sys.Arch, ld.Arch) {
 	arch := sys.ArchMIPS
-	if objabi.GOARCH == "mipsle" {
+	if buildcfg.GOARCH == "mipsle" {
 		arch = sys.ArchMIPSLE
 	}
 
diff --git a/src/cmd/link/internal/mips64/asm.go b/src/cmd/link/internal/mips64/asm.go
index 4789b41..f7f91d1 100644
--- a/src/cmd/link/internal/mips64/asm.go
+++ b/src/cmd/link/internal/mips64/asm.go
@@ -52,6 +52,8 @@
 	//		type	uint8
 	//		addend	int64
 
+	addend := r.Xadd
+
 	out.Write64(uint64(sectoff))
 
 	elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
@@ -77,11 +79,17 @@
 		out.Write8(uint8(elf.R_MIPS_HI16))
 	case objabi.R_ADDRMIPSTLS:
 		out.Write8(uint8(elf.R_MIPS_TLS_TPREL_LO16))
+		if ctxt.Target.IsOpenbsd() {
+			// OpenBSD mips64 does not currently offset TLS by 0x7000,
+			// as such we need to add this back to get the correct offset
+			// via the external linker.
+			addend += 0x7000
+		}
 	case objabi.R_CALLMIPS,
 		objabi.R_JMPMIPS:
 		out.Write8(uint8(elf.R_MIPS_26))
 	}
-	out.Write64(uint64(r.Xadd))
+	out.Write64(uint64(addend))
 
 	return true
 }
@@ -124,6 +132,11 @@
 	case objabi.R_ADDRMIPSTLS:
 		// thread pointer is at 0x7000 offset from the start of TLS data area
 		t := ldr.SymValue(rs) + r.Add() - 0x7000
+		if target.IsOpenbsd() {
+			// OpenBSD mips64 does not currently offset TLS by 0x7000,
+			// as such we need to add this back to get the correct offset.
+			t += 0x7000
+		}
 		if t < -32768 || t >= 32678 {
 			ldr.Errorf(s, "TLS offset out of range %d", t)
 		}
@@ -138,7 +151,7 @@
 	return val, 0, false
 }
 
-func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64, []byte) int64 {
 	return -1
 }
 
diff --git a/src/cmd/link/internal/mips64/obj.go b/src/cmd/link/internal/mips64/obj.go
index 01d89a2..544e1ef 100644
--- a/src/cmd/link/internal/mips64/obj.go
+++ b/src/cmd/link/internal/mips64/obj.go
@@ -34,11 +34,12 @@
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"cmd/link/internal/ld"
+	"internal/buildcfg"
 )
 
 func Init() (*sys.Arch, ld.Arch) {
 	arch := sys.ArchMIPS64
-	if objabi.GOARCH == "mips64le" {
+	if buildcfg.GOARCH == "mips64le" {
 		arch = sys.ArchMIPS64LE
 	}
 
diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go
index 602f0b5..b877864 100644
--- a/src/cmd/link/internal/ppc64/asm.go
+++ b/src/cmd/link/internal/ppc64/asm.go
@@ -121,16 +121,21 @@
 			// Update the relocation to use the call stub
 			r.SetSym(stub.Sym())
 
-			// make sure the data is writeable
-			if ldr.AttrReadOnly(s) {
-				panic("can't write to read-only sym data")
-			}
+			// Make the symbol writeable so we can fixup toc.
+			su := ldr.MakeSymbolUpdater(s)
+			su.MakeWritable()
+			p := su.Data()
 
-			// Restore TOC after bl. The compiler put a
-			// nop here for us to overwrite.
-			sp := ldr.Data(s)
+			// Check for toc restore slot (a nop), and replace with toc restore.
+			var nop uint32
+			if len(p) >= int(r.Off()+8) {
+				nop = ctxt.Arch.ByteOrder.Uint32(p[r.Off()+4:])
+			}
+			if nop != 0x60000000 {
+				ldr.Errorf(s, "Symbol %s is missing toc restoration slot at offset %d", ldr.SymName(s), r.Off()+4)
+			}
 			const o1 = 0xe8410018 // ld r2,24(r1)
-			ctxt.Arch.ByteOrder.PutUint32(sp[r.Off()+4:], o1)
+			ctxt.Arch.ByteOrder.PutUint32(p[r.Off()+4:], o1)
 		}
 	}
 	// Put call stubs at the beginning (instead of the end).
@@ -413,6 +418,7 @@
 		emitReloc(ld.XCOFF_R_TOCU|(0x0F<<8), 2)
 		emitReloc(ld.XCOFF_R_TOCL|(0x0F<<8), 6)
 	case objabi.R_POWER_TLS_LE:
+		// This only supports 16b relocations.  It is fixed up in archreloc.
 		emitReloc(ld.XCOFF_R_TLS_LE|0x0F<<8, 2)
 	case objabi.R_CALLPOWER:
 		if r.Size != 4 {
@@ -453,7 +459,10 @@
 	case objabi.R_POWER_TLS:
 		out.Write64(uint64(elf.R_PPC64_TLS) | uint64(elfsym)<<32)
 	case objabi.R_POWER_TLS_LE:
-		out.Write64(uint64(elf.R_PPC64_TPREL16) | uint64(elfsym)<<32)
+		out.Write64(uint64(elf.R_PPC64_TPREL16_HA) | uint64(elfsym)<<32)
+		out.Write64(uint64(r.Xadd))
+		out.Write64(uint64(sectoff + 4))
+		out.Write64(uint64(elf.R_PPC64_TPREL16_LO) | uint64(elfsym)<<32)
 	case objabi.R_POWER_TLS_IE:
 		out.Write64(uint64(elf.R_PPC64_GOT_TPREL16_HA) | uint64(elfsym)<<32)
 		out.Write64(uint64(r.Xadd))
@@ -642,6 +651,16 @@
 	return int64(o2)<<32 | int64(o1)
 }
 
+// Determine if the code was compiled so that the TOC register R2 is initialized and maintained
+func r2Valid(ctxt *ld.Link) bool {
+	switch ctxt.BuildMode {
+	case ld.BuildModeCArchive, ld.BuildModeCShared, ld.BuildModePIE, ld.BuildModeShared, ld.BuildModePlugin:
+		return true
+	}
+	// -linkshared option
+	return ctxt.IsSharedGoLink()
+}
+
 // resolve direct jump relocation r in s, and add trampoline if necessary
 func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
 
@@ -649,7 +668,7 @@
 	// 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 ctxt.IsExternal() && (ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE) {
+	if ctxt.IsExternal() && r2Valid(ctxt) {
 		// No trampolines needed since r2 contains the TOC
 		return
 	}
@@ -703,7 +722,7 @@
 				}
 			}
 			if ldr.SymType(tramp) == 0 {
-				if ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
+				if r2Valid(ctxt) {
 					// Should have returned for above cases
 					ctxt.Errorf(s, "unexpected trampoline for shared or dynamic linking")
 				} else {
@@ -792,11 +811,25 @@
 			if !target.IsAIX() {
 				return val, nExtReloc, false
 			}
-		case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
-			// check Outer is nil, Type is TLSBSS?
+		case objabi.R_POWER_TLS:
 			nExtReloc = 1
-			if rt == objabi.R_POWER_TLS_IE {
-				nExtReloc = 2 // need two ELF relocations, see elfreloc1
+			return val, nExtReloc, true
+		case objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
+			if target.IsAIX() && rt == objabi.R_POWER_TLS_LE {
+				// Fixup val, an addis/addi pair of instructions, which generate a 32b displacement
+				// from the threadpointer (R13), into a 16b relocation. XCOFF only supports 16b
+				// TLS LE relocations. Likewise, verify this is an addis/addi sequence.
+				const expectedOpcodes = 0x3C00000038000000
+				const expectedOpmasks = 0xFC000000FC000000
+				if uint64(val)&expectedOpmasks != expectedOpcodes {
+					ldr.Errorf(s, "relocation for %s+%d is not an addis/addi pair: %16x", ldr.SymName(rs), r.Off(), uint64(val))
+				}
+				nval := (int64(uint32(0x380d0000)) | val&0x03e00000) << 32 // addi rX, r13, $0
+				nval |= int64(0x60000000)                                  // nop
+				val = nval
+				nExtReloc = 1
+			} else {
+				nExtReloc = 2
 			}
 			return val, nExtReloc, true
 		case objabi.R_ADDRPOWER,
@@ -850,16 +883,32 @@
 			// the TLS.
 			v -= 0x800
 		}
-		if int64(int16(v)) != v {
+
+		var o1, o2 uint32
+		if int64(int32(v)) != v {
 			ldr.Errorf(s, "TLS offset out of range %d", v)
 		}
-		return (val &^ 0xffff) | (v & 0xffff), nExtReloc, true
+		if target.IsBigEndian() {
+			o1 = uint32(val >> 32)
+			o2 = uint32(val)
+		} else {
+			o1 = uint32(val)
+			o2 = uint32(val >> 32)
+		}
+
+		o1 |= uint32(((v + 0x8000) >> 16) & 0xFFFF)
+		o2 |= uint32(v & 0xFFFF)
+
+		if target.IsBigEndian() {
+			return int64(o1)<<32 | int64(o2), nExtReloc, true
+		}
+		return int64(o2)<<32 | int64(o1), nExtReloc, true
 	}
 
 	return val, nExtReloc, false
 }
 
-func archrelocvariant(target *ld.Target, ldr *loader.Loader, r loader.Reloc, rv sym.RelocVariant, s loader.Sym, t int64) (relocatedOffset int64) {
+func archrelocvariant(target *ld.Target, ldr *loader.Loader, r loader.Reloc, rv sym.RelocVariant, s loader.Sym, t int64, p []byte) (relocatedOffset int64) {
 	rs := ldr.ResolveABIAlias(r.Sym())
 	switch rv & sym.RV_TYPE_MASK {
 	default:
@@ -875,9 +924,10 @@
 			// overflow depends on the instruction
 			var o1 uint32
 			if target.IsBigEndian() {
-				o1 = binary.BigEndian.Uint32(ldr.Data(s)[r.Off()-2:])
+				o1 = binary.BigEndian.Uint32(p[r.Off()-2:])
+
 			} else {
-				o1 = binary.LittleEndian.Uint32(ldr.Data(s)[r.Off():])
+				o1 = binary.LittleEndian.Uint32(p[r.Off():])
 			}
 			switch o1 >> 26 {
 			case 24, // ori
@@ -909,9 +959,9 @@
 			// overflow depends on the instruction
 			var o1 uint32
 			if target.IsBigEndian() {
-				o1 = binary.BigEndian.Uint32(ldr.Data(s)[r.Off()-2:])
+				o1 = binary.BigEndian.Uint32(p[r.Off()-2:])
 			} else {
-				o1 = binary.LittleEndian.Uint32(ldr.Data(s)[r.Off():])
+				o1 = binary.LittleEndian.Uint32(p[r.Off():])
 			}
 			switch o1 >> 26 {
 			case 25, // oris
@@ -933,9 +983,9 @@
 	case sym.RV_POWER_DS:
 		var o1 uint32
 		if target.IsBigEndian() {
-			o1 = uint32(binary.BigEndian.Uint16(ldr.Data(s)[r.Off():]))
+			o1 = uint32(binary.BigEndian.Uint16(p[r.Off():]))
 		} else {
-			o1 = uint32(binary.LittleEndian.Uint16(ldr.Data(s)[r.Off():]))
+			o1 = uint32(binary.LittleEndian.Uint16(p[r.Off():]))
 		}
 		if t&3 != 0 {
 			ldr.Errorf(s, "relocation for %s+%d is not aligned: %d", ldr.SymName(rs), r.Off(), t)
@@ -1039,8 +1089,11 @@
 	glink.AddUint32(ctxt.Arch, 0x7800f082) // srdi r0,r0,2
 
 	// r11 = address of the first byte of the PLT
-	glink.AddSymRef(ctxt.Arch, ctxt.PLT, 0, objabi.R_ADDRPOWER, 8)
-
+	r, _ := glink.AddRel(objabi.R_ADDRPOWER)
+	r.SetSym(ctxt.PLT)
+	r.SetSiz(8)
+	r.SetOff(int32(glink.Size()))
+	r.SetAdd(0)
 	glink.AddUint32(ctxt.Arch, 0x3d600000) // addis r11,0,.plt@ha
 	glink.AddUint32(ctxt.Arch, 0x396b0000) // addi r11,r11,.plt@l
 
diff --git a/src/cmd/link/internal/ppc64/obj.go b/src/cmd/link/internal/ppc64/obj.go
index ef4393f..b6d5ad9 100644
--- a/src/cmd/link/internal/ppc64/obj.go
+++ b/src/cmd/link/internal/ppc64/obj.go
@@ -34,21 +34,22 @@
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"cmd/link/internal/ld"
+	"internal/buildcfg"
 )
 
 func Init() (*sys.Arch, ld.Arch) {
 	arch := sys.ArchPPC64
-	if objabi.GOARCH == "ppc64le" {
+	if buildcfg.GOARCH == "ppc64le" {
 		arch = sys.ArchPPC64LE
 	}
 
 	theArch := ld.Arch{
-		Funcalign:       funcAlign,
-		Maxalign:        maxAlign,
-		Minalign:        minAlign,
-		Dwarfregsp:      dwarfRegSP,
-		Dwarfreglr:      dwarfRegLR,
-		WriteTextBlocks: true,
+		Funcalign:  funcAlign,
+		Maxalign:   maxAlign,
+		Minalign:   minAlign,
+		Dwarfregsp: dwarfRegSP,
+		Dwarfreglr: dwarfRegLR,
+		TrampLimit: 0x1c00000,
 
 		Adddynrel:        adddynrel,
 		Archinit:         archinit,
diff --git a/src/cmd/link/internal/riscv64/asm.go b/src/cmd/link/internal/riscv64/asm.go
index c18e054..6eace61 100644
--- a/src/cmd/link/internal/riscv64/asm.go
+++ b/src/cmd/link/internal/riscv64/asm.go
@@ -230,7 +230,7 @@
 	return val, 0, false
 }
 
-func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64, []byte) int64 {
 	log.Fatalf("archrelocvariant")
 	return -1
 }
diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go
index 78d2cc8..1952971 100644
--- a/src/cmd/link/internal/s390x/asm.go
+++ b/src/cmd/link/internal/s390x/asm.go
@@ -371,7 +371,7 @@
 	return val, 0, false
 }
 
-func archrelocvariant(target *ld.Target, ldr *loader.Loader, r loader.Reloc, rv sym.RelocVariant, s loader.Sym, t int64) int64 {
+func archrelocvariant(target *ld.Target, ldr *loader.Loader, r loader.Reloc, rv sym.RelocVariant, s loader.Sym, t int64, p []byte) int64 {
 	switch rv & sym.RV_TYPE_MASK {
 	default:
 		ldr.Errorf(s, "unexpected relocation variant %d", rv)
diff --git a/src/cmd/link/internal/sym/compilation_unit.go b/src/cmd/link/internal/sym/compilation_unit.go
index 5d7206d..3bad5bf 100644
--- a/src/cmd/link/internal/sym/compilation_unit.go
+++ b/src/cmd/link/internal/sym/compilation_unit.go
@@ -20,7 +20,6 @@
 //
 // These are used for both DWARF and pclntab generation.
 type CompilationUnit struct {
-	Pkg       string        // The package name, eg ("fmt", or "runtime")
 	Lib       *Library      // Our library
 	PclnIndex int           // Index of this CU in pclntab
 	PCs       []dwarf.Range // PC ranges, relative to Textp[0]
@@ -29,6 +28,7 @@
 
 	Consts    LoaderSym   // Package constants DIEs
 	FuncDIEs  []LoaderSym // Function DIE subtrees
+	VarDIEs   []LoaderSym // Global variable DIEs
 	AbsFnDIEs []LoaderSym // Abstract function DIE subtrees
 	RangeSyms []LoaderSym // Symbols for debug_range
 	Textp     []LoaderSym // Text symbols in this CU
diff --git a/src/cmd/link/internal/wasm/asm.go b/src/cmd/link/internal/wasm/asm.go
index 31851fb..5bdfdba 100644
--- a/src/cmd/link/internal/wasm/asm.go
+++ b/src/cmd/link/internal/wasm/asm.go
@@ -10,6 +10,7 @@
 	"cmd/link/internal/ld"
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
+	"internal/buildcfg"
 	"io"
 	"regexp"
 )
@@ -506,15 +507,15 @@
 
 	writeUleb128(ctxt.Out, 2) // number of fields
 
-	writeName(ctxt.Out, "language")     // field name
-	writeUleb128(ctxt.Out, 1)           // number of values
-	writeName(ctxt.Out, "Go")           // value: name
-	writeName(ctxt.Out, objabi.Version) // value: version
+	writeName(ctxt.Out, "language")       // field name
+	writeUleb128(ctxt.Out, 1)             // number of values
+	writeName(ctxt.Out, "Go")             // value: name
+	writeName(ctxt.Out, buildcfg.Version) // value: version
 
 	writeName(ctxt.Out, "processed-by")   // field name
 	writeUleb128(ctxt.Out, 1)             // number of values
 	writeName(ctxt.Out, "Go cmd/compile") // value: name
-	writeName(ctxt.Out, objabi.Version)   // value: version
+	writeName(ctxt.Out, buildcfg.Version) // value: version
 
 	writeSecSize(ctxt, sizeOffset)
 }
diff --git a/src/cmd/link/internal/x86/asm.go b/src/cmd/link/internal/x86/asm.go
index af0ce11..5f6bcfb 100644
--- a/src/cmd/link/internal/x86/asm.go
+++ b/src/cmd/link/internal/x86/asm.go
@@ -415,7 +415,7 @@
 	return -1, 0, false
 }
 
-func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64, []byte) int64 {
 	log.Fatalf("unexpected relocation variant")
 	return -1
 }
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
index 08ddd00..7230054 100644
--- a/src/cmd/link/link_test.go
+++ b/src/cmd/link/link_test.go
@@ -48,13 +48,9 @@
 func main() {}
 `
 
-	tmpdir, err := ioutil.TempDir("", "issue21703")
-	if err != nil {
-		t.Fatalf("failed to create temp dir: %v\n", err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
-	err = ioutil.WriteFile(filepath.Join(tmpdir, "main.go"), []byte(source), 0666)
+	err := ioutil.WriteFile(filepath.Join(tmpdir, "main.go"), []byte(source), 0666)
 	if err != nil {
 		t.Fatalf("failed to write main.go: %v\n", err)
 	}
@@ -83,11 +79,7 @@
 
 	testenv.MustHaveGoBuild(t)
 
-	tmpdir, err := ioutil.TempDir("", "issue28429-")
-	if err != nil {
-		t.Fatalf("failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	write := func(name, content string) {
 		err := ioutil.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
@@ -126,11 +118,7 @@
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "unresolved-")
-	if err != nil {
-		t.Fatalf("failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	write := func(name, content string) {
 		err := ioutil.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
@@ -189,17 +177,14 @@
 	case "mips", "mipsle", "mips64", "mips64le":
 		t.Skipf("Skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
 	}
-	if runtime.GOOS == "aix" {
+	if runtime.GOOS == "aix" ||
+		runtime.GOOS == "windows" && runtime.GOARCH == "arm64" {
 		t.Skipf("Skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
 	}
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "unresolved-")
-	if err != nil {
-		t.Fatalf("failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	write := func(name, content string) {
 		err := ioutil.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
@@ -300,11 +285,7 @@
 		"-framework", "CoreFoundation",
 	}
 	lib := filepath.Join("testdata", "testBuildFortvOS", "lib.go")
-	tmpDir, err := ioutil.TempDir("", "go-link-TestBuildFortvOS")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpDir)
+	tmpDir := t.TempDir()
 
 	ar := filepath.Join(tmpDir, "lib.a")
 	cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", ar, lib)
@@ -339,14 +320,10 @@
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestXFlag")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "main.go")
-	err = ioutil.WriteFile(src, []byte(testXFlagSrc), 0666)
+	err := ioutil.WriteFile(src, []byte(testXFlagSrc), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -357,24 +334,20 @@
 	}
 }
 
-var testMacOSVersionSrc = `
+var testMachOBuildVersionSrc = `
 package main
 func main() { }
 `
 
-func TestMacOSVersion(t *testing.T) {
+func TestMachOBuildVersion(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestMacOSVersion")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "main.go")
-	err = ioutil.WriteFile(src, []byte(testMacOSVersionSrc), 0666)
+	err := ioutil.WriteFile(src, []byte(testMachOBuildVersionSrc), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -393,33 +366,34 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+	defer exef.Close()
 	exem, err := macho.NewFile(exef)
 	if err != nil {
 		t.Fatal(err)
 	}
 	found := false
-	const LC_VERSION_MIN_MACOSX = 0x24
+	const LC_BUILD_VERSION = 0x32
 	checkMin := func(ver uint32) {
 		major, minor := (ver>>16)&0xff, (ver>>8)&0xff
 		if major != 10 || minor < 9 {
-			t.Errorf("LC_VERSION_MIN_MACOSX version %d.%d < 10.9", major, minor)
+			t.Errorf("LC_BUILD_VERSION version %d.%d < 10.9", major, minor)
 		}
 	}
 	for _, cmd := range exem.Loads {
 		raw := cmd.Raw()
 		type_ := exem.ByteOrder.Uint32(raw)
-		if type_ != LC_VERSION_MIN_MACOSX {
+		if type_ != LC_BUILD_VERSION {
 			continue
 		}
-		osVer := exem.ByteOrder.Uint32(raw[8:])
+		osVer := exem.ByteOrder.Uint32(raw[12:])
 		checkMin(osVer)
-		sdkVer := exem.ByteOrder.Uint32(raw[12:])
+		sdkVer := exem.ByteOrder.Uint32(raw[16:])
 		checkMin(sdkVer)
 		found = true
 		break
 	}
 	if !found {
-		t.Errorf("no LC_VERSION_MIN_MACOSX load command found")
+		t.Errorf("no LC_BUILD_VERSION load command found")
 	}
 }
 
@@ -446,14 +420,10 @@
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestIssue34788Android386TLSSequence")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "blah.go")
-	err = ioutil.WriteFile(src, []byte(Issue34788src), 0666)
+	err := ioutil.WriteFile(src, []byte(Issue34788src), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -500,32 +470,45 @@
 	JMP	0(PC)
 `
 
+const testStrictDupAsmSrc3 = `
+#include "textflag.h"
+GLOBL ·rcon(SB), RODATA|DUPOK, $64
+`
+
+const testStrictDupAsmSrc4 = `
+#include "textflag.h"
+GLOBL ·rcon(SB), RODATA|DUPOK, $32
+`
+
 func TestStrictDup(t *testing.T) {
 	// Check that -strictdups flag works.
 	testenv.MustHaveGoBuild(t)
 
+	asmfiles := []struct {
+		fname   string
+		payload string
+	}{
+		{"a", testStrictDupAsmSrc1},
+		{"b", testStrictDupAsmSrc2},
+		{"c", testStrictDupAsmSrc3},
+		{"d", testStrictDupAsmSrc4},
+	}
+
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestStrictDup")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "x.go")
-	err = ioutil.WriteFile(src, []byte(testStrictDupGoSrc), 0666)
+	err := ioutil.WriteFile(src, []byte(testStrictDupGoSrc), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
-	src = filepath.Join(tmpdir, "a.s")
-	err = ioutil.WriteFile(src, []byte(testStrictDupAsmSrc1), 0666)
-	if err != nil {
-		t.Fatal(err)
-	}
-	src = filepath.Join(tmpdir, "b.s")
-	err = ioutil.WriteFile(src, []byte(testStrictDupAsmSrc2), 0666)
-	if err != nil {
-		t.Fatal(err)
+	for _, af := range asmfiles {
+		src = filepath.Join(tmpdir, af.fname+".s")
+		err = ioutil.WriteFile(src, []byte(af.payload), 0666)
+		if err != nil {
+			t.Fatal(err)
+		}
 	}
 	src = filepath.Join(tmpdir, "go.mod")
 	err = ioutil.WriteFile(src, []byte("module teststrictdup\n"), 0666)
@@ -537,7 +520,7 @@
 	cmd.Dir = tmpdir
 	out, err := cmd.CombinedOutput()
 	if err != nil {
-		t.Errorf("linking with -strictdups=1 failed: %v", err)
+		t.Errorf("linking with -strictdups=1 failed: %v\n%s", err, string(out))
 	}
 	if !bytes.Contains(out, []byte("mismatched payload")) {
 		t.Errorf("unexpected output:\n%s", out)
@@ -549,7 +532,11 @@
 	if err == nil {
 		t.Errorf("linking with -strictdups=2 did not fail")
 	}
-	if !bytes.Contains(out, []byte("mismatched payload")) {
+	// NB: on amd64 we get the 'new length' error, on arm64 the 'different
+	// contents' error.
+	if !(bytes.Contains(out, []byte("mismatched payload: new length")) ||
+		bytes.Contains(out, []byte("mismatched payload: same length but different contents"))) ||
+		!bytes.Contains(out, []byte("mismatched payload: different sizes")) {
 		t.Errorf("unexpected output:\n%s", out)
 	}
 }
@@ -592,14 +579,10 @@
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestFuncAlign")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "go.mod")
-	err = ioutil.WriteFile(src, []byte("module cmd/link/TestFuncAlign/falign"), 0666)
+	err := ioutil.WriteFile(src, []byte("module cmd/link/TestFuncAlign/falign"), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -656,7 +639,7 @@
 	// threshold for trampoline generation, and essentially all cross-package
 	// calls will use trampolines.
 	switch runtime.GOARCH {
-	case "arm", "ppc64", "ppc64le":
+	case "arm", "arm64", "ppc64", "ppc64le":
 	default:
 		t.Skipf("trampoline insertion is not implemented on %s", runtime.GOARCH)
 	}
@@ -665,14 +648,10 @@
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestTrampoline")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "hello.go")
-	err = ioutil.WriteFile(src, []byte(testTrampSrc), 0666)
+	err := ioutil.WriteFile(src, []byte(testTrampSrc), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -693,6 +672,77 @@
 	}
 }
 
+const testTrampCgoSrc = `
+package main
+
+// #include <stdio.h>
+// void CHello() { printf("hello\n"); fflush(stdout); }
+import "C"
+
+func main() {
+	C.CHello()
+}
+`
+
+func TestTrampolineCgo(t *testing.T) {
+	// Test that trampoline insertion works for cgo code.
+	// For stress test, we set -debugtramp=2 flag, which sets a very low
+	// threshold for trampoline generation, and essentially all cross-package
+	// calls will use trampolines.
+	switch runtime.GOARCH {
+	case "arm", "arm64", "ppc64", "ppc64le":
+	default:
+		t.Skipf("trampoline insertion is not implemented on %s", runtime.GOARCH)
+	}
+
+	testenv.MustHaveGoBuild(t)
+	testenv.MustHaveCGO(t)
+
+	t.Parallel()
+
+	tmpdir := t.TempDir()
+
+	src := filepath.Join(tmpdir, "hello.go")
+	err := ioutil.WriteFile(src, []byte(testTrampCgoSrc), 0666)
+	if err != nil {
+		t.Fatal(err)
+	}
+	exe := filepath.Join(tmpdir, "hello.exe")
+
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-debugtramp=2", "-o", exe, src)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("build failed: %v\n%s", err, out)
+	}
+	cmd = exec.Command(exe)
+	out, err = cmd.CombinedOutput()
+	if err != nil {
+		t.Errorf("executable failed to run: %v\n%s", err, out)
+	}
+	if string(out) != "hello\n" && string(out) != "hello\r\n" {
+		t.Errorf("unexpected output:\n%s", out)
+	}
+
+	// Test internal linking mode.
+
+	if runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" || (runtime.GOARCH == "arm64" && runtime.GOOS == "windows") || !testenv.CanInternalLink() {
+		return // internal linking cgo is not supported
+	}
+	cmd = exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-debugtramp=2 -linkmode=internal", "-o", exe, src)
+	out, err = cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("build failed: %v\n%s", err, out)
+	}
+	cmd = exec.Command(exe)
+	out, err = cmd.CombinedOutput()
+	if err != nil {
+		t.Errorf("executable failed to run: %v\n%s", err, out)
+	}
+	if string(out) != "hello\n" && string(out) != "hello\r\n" {
+		t.Errorf("unexpected output:\n%s", out)
+	}
+}
+
 func TestIndexMismatch(t *testing.T) {
 	// Test that index mismatch will cause a link-time error (not run-time error).
 	// This shouldn't happen with "go build". We invoke the compiler and the linker
@@ -701,11 +751,7 @@
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestIndexMismatch")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	aSrc := filepath.Join("testdata", "testIndexMismatch", "a.go")
 	bSrc := filepath.Join("testdata", "testIndexMismatch", "b.go")
@@ -753,23 +799,20 @@
 	}
 }
 
-func TestPErsrc(t *testing.T) {
+func TestPErsrcBinutils(t *testing.T) {
 	// Test that PE rsrc section is handled correctly (issue 39658).
 	testenv.MustHaveGoBuild(t)
 
-	if runtime.GOARCH != "amd64" || runtime.GOOS != "windows" {
-		t.Skipf("this is a windows/amd64-only test")
+	if (runtime.GOARCH != "386" && runtime.GOARCH != "amd64") || runtime.GOOS != "windows" {
+		// This test is limited to amd64 and 386, because binutils is limited as such
+		t.Skipf("this is only for windows/amd64 and windows/386")
 	}
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestPErsrc")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
-	pkgdir := filepath.Join("testdata", "testPErsrc")
+	pkgdir := filepath.Join("testdata", "pe-binutils")
 	exe := filepath.Join(tmpdir, "a.exe")
 	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe)
 	cmd.Dir = pkgdir
@@ -787,19 +830,32 @@
 	if !bytes.Contains(b, []byte("Hello Gophers!")) {
 		t.Fatalf("binary does not contain expected content")
 	}
+}
 
-	pkgdir = filepath.Join("testdata", "testPErsrc-complex")
-	exe = filepath.Join(tmpdir, "a.exe")
-	cmd = exec.Command(testenv.GoToolPath(t), "build", "-o", exe)
+func TestPErsrcLLVM(t *testing.T) {
+	// Test that PE rsrc section is handled correctly (issue 39658).
+	testenv.MustHaveGoBuild(t)
+
+	if runtime.GOOS != "windows" {
+		t.Skipf("this is a windows-only test")
+	}
+
+	t.Parallel()
+
+	tmpdir := t.TempDir()
+
+	pkgdir := filepath.Join("testdata", "pe-llvm")
+	exe := filepath.Join(tmpdir, "a.exe")
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe)
 	cmd.Dir = pkgdir
 	// cmd.Env = append(os.Environ(), "GOOS=windows", "GOARCH=amd64") // uncomment if debugging in a cross-compiling environment
-	out, err = cmd.CombinedOutput()
+	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("building failed: %v, output:\n%s", err, out)
 	}
 
 	// Check that the binary contains the rsrc data
-	b, err = ioutil.ReadFile(exe)
+	b, err := ioutil.ReadFile(exe)
 	if err != nil {
 		t.Fatalf("reading output failed: %v", err)
 	}
@@ -814,12 +870,6 @@
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestContentAddressableSymbols")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
-
 	src := filepath.Join("testdata", "testHashedSyms", "p.go")
 	cmd := exec.Command(testenv.GoToolPath(t), "run", src)
 	out, err := cmd.CombinedOutput()
@@ -863,14 +913,10 @@
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestIssue38554")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "x.go")
-	err = ioutil.WriteFile(src, []byte(testIssue38554Src), 0666)
+	err := ioutil.WriteFile(src, []byte(testIssue38554Src), 0666)
 	if err != nil {
 		t.Fatalf("failed to write source file: %v", err)
 	}
@@ -917,14 +963,10 @@
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestIssue42396")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "main.go")
-	err = ioutil.WriteFile(src, []byte(testIssue42396src), 0666)
+	err := ioutil.WriteFile(src, []byte(testIssue42396src), 0666)
 	if err != nil {
 		t.Fatalf("failed to write source file: %v", err)
 	}
@@ -974,14 +1016,10 @@
 	testenv.MustHaveGoBuild(t)
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestIssue42396")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "x.go")
-	err = ioutil.WriteFile(src, []byte(testLargeRelocSrc), 0666)
+	err := ioutil.WriteFile(src, []byte(testLargeRelocSrc), 0666)
 	if err != nil {
 		t.Fatalf("failed to write source file: %v", err)
 	}
diff --git a/src/cmd/link/linkbig_test.go b/src/cmd/link/linkbig_test.go
index 78d2bc1..9a4430c 100644
--- a/src/cmd/link/linkbig_test.go
+++ b/src/cmd/link/linkbig_test.go
@@ -10,29 +10,27 @@
 
 import (
 	"bytes"
-	"cmd/internal/objabi"
 	"fmt"
+	"internal/buildcfg"
 	"internal/testenv"
 	"io/ioutil"
-	"os"
 	"os/exec"
 	"testing"
 )
 
 func TestLargeText(t *testing.T) {
-	if testing.Short() || (objabi.GOARCH != "ppc64le" && objabi.GOARCH != "ppc64" && objabi.GOARCH != "arm") {
-		t.Skipf("Skipping large text section test in short mode or on %s", objabi.GOARCH)
+	if testing.Short() || (buildcfg.GOARCH != "ppc64le" && buildcfg.GOARCH != "ppc64" && buildcfg.GOARCH != "arm") {
+		t.Skipf("Skipping large text section test in short mode or on %s", buildcfg.GOARCH)
 	}
 	testenv.MustHaveGoBuild(t)
 
 	var w bytes.Buffer
 	const FN = 4
-	tmpdir, err := ioutil.TempDir("", "bigtext")
-	if err != nil {
-		t.Fatalf("can't create temp directory: %v\n", err)
-	}
+	tmpdir := t.TempDir()
 
-	defer os.RemoveAll(tmpdir)
+	if err := ioutil.WriteFile(tmpdir+"/go.mod", []byte("module big_test\n"), 0666); err != nil {
+		t.Fatal(err)
+	}
 
 	// Generate the scenario where the total amount of text exceeds the
 	// limit for the jmp/call instruction, on RISC architectures like ppc64le,
@@ -44,7 +42,7 @@
 		"ppc64le": "\tMOVD\tR0,R3\n",
 		"arm":     "\tMOVW\tR0,R1\n",
 	}
-	inst := instOnArch[objabi.GOARCH]
+	inst := instOnArch[buildcfg.GOARCH]
 	for j := 0; j < FN; j++ {
 		testname := fmt.Sprintf("bigfn%d", j)
 		fmt.Fprintf(&w, "TEXT ·%s(SB),$0\n", testname)
@@ -79,32 +77,34 @@
 	fmt.Fprintf(&w, "\t}\n")
 	fmt.Fprintf(&w, "\tfmt.Printf(\"PASS\\n\")\n")
 	fmt.Fprintf(&w, "}")
-	err = ioutil.WriteFile(tmpdir+"/bigfn.go", w.Bytes(), 0666)
+	err := ioutil.WriteFile(tmpdir+"/bigfn.go", w.Bytes(), 0666)
 	if err != nil {
 		t.Fatalf("can't write output: %v\n", err)
 	}
 
 	// Build and run with internal linking.
-	os.Chdir(tmpdir)
 	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "bigtext")
+	cmd.Dir = tmpdir
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("Build failed for big text program with internal linking: %v, output: %s", err, out)
 	}
-	cmd = exec.Command(tmpdir + "/bigtext")
+	cmd = exec.Command("./bigtext")
+	cmd.Dir = tmpdir
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("Program built with internal linking failed to run with err %v, output: %s", err, out)
 	}
 
 	// Build and run with external linking
-	os.Chdir(tmpdir)
 	cmd = exec.Command(testenv.GoToolPath(t), "build", "-o", "bigtext", "-ldflags", "'-linkmode=external'")
+	cmd.Dir = tmpdir
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("Build failed for big text program with external linking: %v, output: %s", err, out)
 	}
-	cmd = exec.Command(tmpdir + "/bigtext")
+	cmd = exec.Command("./bigtext")
+	cmd.Dir = tmpdir
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("Program built with external linking failed to run with err %v, output: %s", err, out)
diff --git a/src/cmd/link/main.go b/src/cmd/link/main.go
index 6b4ca97..d92478e 100644
--- a/src/cmd/link/main.go
+++ b/src/cmd/link/main.go
@@ -5,7 +5,6 @@
 package main
 
 import (
-	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"cmd/link/internal/amd64"
 	"cmd/link/internal/arm"
@@ -19,6 +18,7 @@
 	"cmd/link/internal/wasm"
 	"cmd/link/internal/x86"
 	"fmt"
+	"internal/buildcfg"
 	"os"
 )
 
@@ -40,9 +40,10 @@
 	var arch *sys.Arch
 	var theArch ld.Arch
 
-	switch objabi.GOARCH {
+	buildcfg.Check()
+	switch buildcfg.GOARCH {
 	default:
-		fmt.Fprintf(os.Stderr, "link: unknown architecture %q\n", objabi.GOARCH)
+		fmt.Fprintf(os.Stderr, "link: unknown architecture %q\n", buildcfg.GOARCH)
 		os.Exit(2)
 	case "386":
 		arch, theArch = x86.Init()
diff --git a/src/cmd/link/testdata/pe-binutils/main.go b/src/cmd/link/testdata/pe-binutils/main.go
new file mode 100644
index 0000000..14ea6f9
--- /dev/null
+++ b/src/cmd/link/testdata/pe-binutils/main.go
@@ -0,0 +1,18 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that a PE rsrc section is handled correctly (issue 39658).
+//
+// rsrc.syso is created using binutils with:
+//	{x86_64,i686}-w64-mingw32-windres -i a.rc -o rsrc_$GOARCH.syso -O coff
+// where a.rc is a text file with the following content:
+//
+// resname RCDATA {
+//   "Hello Gophers!\0",
+//   "This is a test.\0",
+// }
+
+package main
+
+func main() {}
diff --git a/src/cmd/link/testdata/pe-binutils/rsrc_386.syso b/src/cmd/link/testdata/pe-binutils/rsrc_386.syso
new file mode 100644
index 0000000..b4abc58
--- /dev/null
+++ b/src/cmd/link/testdata/pe-binutils/rsrc_386.syso
Binary files differ
diff --git a/src/cmd/link/testdata/testPErsrc/rsrc.syso b/src/cmd/link/testdata/pe-binutils/rsrc_amd64.syso
similarity index 100%
rename from src/cmd/link/testdata/testPErsrc/rsrc.syso
rename to src/cmd/link/testdata/pe-binutils/rsrc_amd64.syso
Binary files differ
diff --git a/src/cmd/link/testdata/pe-llvm/main.go b/src/cmd/link/testdata/pe-llvm/main.go
new file mode 100644
index 0000000..099a71a
--- /dev/null
+++ b/src/cmd/link/testdata/pe-llvm/main.go
@@ -0,0 +1,43 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that a PE rsrc section is handled correctly, when the object files
+// have been created by llvm-rc or msvc's rc.exe, which means there's the
+// @feat.00 symbol as well as split .rsrc$00 and .rsrc$01 section to deal with.
+//
+// rsrc.syso is created using llvm with:
+//    {i686,x86_64,armv7,arm64}-w64-mingw32-windres -i a.rc -o rsrc_$GOARCH.syso -O coff
+// where this windres calls into llvm-rc and llvm-cvtres. The source file,
+// a.rc, simply contains a reference to its own bytes:
+//
+//    resname RCDATA a.rc
+//
+// Object dumping the resultant rsrc.syso, we can see the split sections and
+// the @feat.00 SEH symbol:
+//
+//     rsrc.syso:      file format coff-x86-64
+//
+//     architecture: x86_64
+//     start address: 0x0000000000000000
+//
+//     Export Table:
+//     Sections:
+//     Idx Name          Size     VMA              Type
+//       0 .rsrc$01      00000068 0000000000000000 DATA
+//       1 .rsrc$02      00000018 0000000000000000 DATA
+//
+//     SYMBOL TABLE:
+//     [ 0](sec -1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000011 @feat.00
+//     [ 1](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .rsrc$01
+//     AUX scnlen 0x68 nreloc 1 nlnno 0 checksum 0x0 assoc 0 comdat 0
+//     [ 3](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .rsrc$02
+//     AUX scnlen 0x18 nreloc 0 nlnno 0 checksum 0x0 assoc 0 comdat 0
+//     [ 5](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000000 $R000000
+//     RELOCATION RECORDS FOR [.rsrc$01]:
+//     OFFSET           TYPE                     VALUE
+//     0000000000000048 IMAGE_REL_AMD64_ADDR32NB $R000000
+
+package main
+
+func main() {}
diff --git a/src/cmd/link/testdata/pe-llvm/rsrc_386.syso b/src/cmd/link/testdata/pe-llvm/rsrc_386.syso
new file mode 100644
index 0000000..21126c9
--- /dev/null
+++ b/src/cmd/link/testdata/pe-llvm/rsrc_386.syso
Binary files differ
diff --git a/src/cmd/link/testdata/pe-llvm/rsrc_amd64.syso b/src/cmd/link/testdata/pe-llvm/rsrc_amd64.syso
new file mode 100644
index 0000000..56f9260
--- /dev/null
+++ b/src/cmd/link/testdata/pe-llvm/rsrc_amd64.syso
Binary files differ
diff --git a/src/cmd/link/testdata/pe-llvm/rsrc_arm.syso b/src/cmd/link/testdata/pe-llvm/rsrc_arm.syso
new file mode 100644
index 0000000..c93a1e9
--- /dev/null
+++ b/src/cmd/link/testdata/pe-llvm/rsrc_arm.syso
Binary files differ
diff --git a/src/cmd/link/testdata/pe-llvm/rsrc_arm64.syso b/src/cmd/link/testdata/pe-llvm/rsrc_arm64.syso
new file mode 100644
index 0000000..7849638
--- /dev/null
+++ b/src/cmd/link/testdata/pe-llvm/rsrc_arm64.syso
Binary files differ
diff --git a/src/cmd/link/testdata/testPErsrc-complex/main.go b/src/cmd/link/testdata/testPErsrc-complex/main.go
deleted file mode 100644
index affd6ea..0000000
--- a/src/cmd/link/testdata/testPErsrc-complex/main.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test that a PE rsrc section is handled correctly, when the object files
-// have been created by llvm-rc or msvc's rc.exe, which means there's the
-// @feat.00 symbol as well as split .rsrc$00 and .rsrc$01 section to deal with.
-//
-// rsrc.syso is created with:
-//    windres -i a.rc -o rsrc.syso -O coff
-// where this windres calls into llvm-rc and llvm-cvtres. The source file,
-// a.rc, simply contains a reference to its own bytes:
-//
-//    resname RCDATA a.rc
-//
-// Object dumping the resultant rsrc.syso, we can see the split sections and
-// the @feat.00 SEH symbol:
-//
-//     rsrc.syso:      file format coff-x86-64
-//
-//     architecture: x86_64
-//     start address: 0x0000000000000000
-//
-//     Export Table:
-//     Sections:
-//     Idx Name          Size     VMA              Type
-//       0 .rsrc$01      00000068 0000000000000000 DATA
-//       1 .rsrc$02      00000018 0000000000000000 DATA
-//
-//     SYMBOL TABLE:
-//     [ 0](sec -1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000011 @feat.00
-//     [ 1](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .rsrc$01
-//     AUX scnlen 0x68 nreloc 1 nlnno 0 checksum 0x0 assoc 0 comdat 0
-//     [ 3](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .rsrc$02
-//     AUX scnlen 0x18 nreloc 0 nlnno 0 checksum 0x0 assoc 0 comdat 0
-//     [ 5](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000000 $R000000
-//     RELOCATION RECORDS FOR [.rsrc$01]:
-//     OFFSET           TYPE                     VALUE
-//     0000000000000048 IMAGE_REL_AMD64_ADDR32NB $R000000
-
-package main
-
-func main() {}
diff --git a/src/cmd/link/testdata/testPErsrc-complex/rsrc.syso b/src/cmd/link/testdata/testPErsrc-complex/rsrc.syso
deleted file mode 100644
index eff630b..0000000
--- a/src/cmd/link/testdata/testPErsrc-complex/rsrc.syso
+++ /dev/null
Binary files differ
diff --git a/src/cmd/link/testdata/testPErsrc/main.go b/src/cmd/link/testdata/testPErsrc/main.go
deleted file mode 100644
index 5eb66fb..0000000
--- a/src/cmd/link/testdata/testPErsrc/main.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test that a PE rsrc section is handled correctly (issue 39658).
-//
-// rsrc.syso is created with:
-//	windres -i a.rc -o rsrc.syso -O coff
-// on windows-amd64-2016 builder, where a.rc is a text file with
-// the following content:
-//
-// resname RCDATA {
-//   "Hello Gophers!\0",
-//   "This is a test.\0",
-// }
-
-package main
-
-func main() {}
diff --git a/src/cmd/nm/nm_cgo_test.go b/src/cmd/nm/nm_cgo_test.go
index e0414e6..1544be0 100644
--- a/src/cmd/nm/nm_cgo_test.go
+++ b/src/cmd/nm/nm_cgo_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo
 // +build cgo
 
 package main
@@ -29,6 +30,11 @@
 		}
 	case "openbsd":
 		switch runtime.GOARCH {
+		case "arm64", "mips64":
+			return false
+		}
+	case "windows":
+		switch runtime.GOARCH {
 		case "arm64":
 			return false
 		}
diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go
index 1748e13..f231a7c 100644
--- a/src/cmd/objdump/objdump_test.go
+++ b/src/cmd/objdump/objdump_test.go
@@ -64,13 +64,13 @@
 }
 
 var amd64GnuNeed = []string{
-	"movq",
+	"jmp",
 	"callq",
 	"cmpb",
 }
 
 var i386GnuNeed = []string{
-	"mov",
+	"jmp",
 	"call",
 	"cmp",
 }
@@ -345,3 +345,18 @@
 		t.Logf("output:\n%s", text)
 	}
 }
+
+func TestGoObjOtherVersion(t *testing.T) {
+	testenv.MustHaveExec(t)
+	t.Parallel()
+
+	obj := filepath.Join("testdata", "go116.o")
+	cmd := exec.Command(exe, obj)
+	out, err := cmd.CombinedOutput()
+	if err == nil {
+		t.Fatalf("objdump go116.o succeeded unexpectly")
+	}
+	if !strings.Contains(string(out), "go object of a different version") {
+		t.Errorf("unexpected error message:\n%s", out)
+	}
+}
diff --git a/src/cmd/objdump/testdata/go116.o b/src/cmd/objdump/testdata/go116.o
new file mode 100644
index 0000000..6434d5c
--- /dev/null
+++ b/src/cmd/objdump/testdata/go116.o
Binary files differ
diff --git a/src/cmd/pack/pack_test.go b/src/cmd/pack/pack_test.go
index 118376f..7842b56 100644
--- a/src/cmd/pack/pack_test.go
+++ b/src/cmd/pack/pack_test.go
@@ -19,15 +19,6 @@
 	"time"
 )
 
-// tmpDir creates a temporary directory and returns its name.
-func tmpDir(t *testing.T) string {
-	name, err := os.MkdirTemp("", "pack")
-	if err != nil {
-		t.Fatal(err)
-	}
-	return name
-}
-
 // testCreate creates an archive in the specified directory.
 func testCreate(t *testing.T, dir string) {
 	name := filepath.Join(dir, "pack.a")
@@ -57,15 +48,13 @@
 // Test that we can create an archive, write to it, and get the same contents back.
 // Tests the rv and then the pv command on a new archive.
 func TestCreate(t *testing.T) {
-	dir := tmpDir(t)
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 	testCreate(t, dir)
 }
 
 // Test that we can create an archive twice with the same name (Issue 8369).
 func TestCreateTwice(t *testing.T) {
-	dir := tmpDir(t)
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 	testCreate(t, dir)
 	testCreate(t, dir)
 }
@@ -73,8 +62,7 @@
 // Test that we can create an archive, put some files in it, and get back a correct listing.
 // Tests the tv command.
 func TestTableOfContents(t *testing.T) {
-	dir := tmpDir(t)
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 	name := filepath.Join(dir, "pack.a")
 	ar := openArchive(name, os.O_RDWR|os.O_CREATE, nil)
 
@@ -131,8 +119,7 @@
 // Test that we can create an archive, put some files in it, and get back a file.
 // Tests the x command.
 func TestExtract(t *testing.T) {
-	dir := tmpDir(t)
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 	name := filepath.Join(dir, "pack.a")
 	ar := openArchive(name, os.O_RDWR|os.O_CREATE, nil)
 	// Add some entries by hand.
@@ -173,8 +160,7 @@
 func TestHello(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
 
-	dir := tmpDir(t)
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 	hello := filepath.Join(dir, "hello.go")
 	prog := `
 		package main
@@ -209,8 +195,7 @@
 	}
 	testenv.MustHaveGoBuild(t)
 
-	dir := tmpDir(t)
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 	large := filepath.Join(dir, "large.go")
 	f, err := os.Create(large)
 	if err != nil {
@@ -276,8 +261,7 @@
 func TestIssue21703(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
 
-	dir := tmpDir(t)
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	const aSrc = `package a; const X = "\n!\n"`
 	err := os.WriteFile(filepath.Join(dir, "a.go"), []byte(aSrc), 0666)
@@ -307,8 +291,7 @@
 func TestCreateWithCompilerObj(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
 
-	dir := tmpDir(t)
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 	src := filepath.Join(dir, "p.go")
 	prog := "package p; var X = 42\n"
 	err := os.WriteFile(src, []byte(prog), 0666)
@@ -372,8 +355,7 @@
 func TestRWithNonexistentFile(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
 
-	dir := tmpDir(t)
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 	src := filepath.Join(dir, "p.go")
 	prog := "package p; var X = 42\n"
 	err := os.WriteFile(src, []byte(prog), 0666)
diff --git a/src/cmd/pprof/pprof.go b/src/cmd/pprof/pprof.go
index 11f91cb..e72c765 100644
--- a/src/cmd/pprof/pprof.go
+++ b/src/cmd/pprof/pprof.go
@@ -232,9 +232,9 @@
 	return f.name
 }
 
-func (f *file) Base() uint64 {
-	// No support for shared libraries.
-	return 0
+func (f *file) ObjAddr(addr uint64) (uint64, error) {
+	// No support for shared libraries, so translation is a no-op.
+	return addr, nil
 }
 
 func (f *file) BuildID() string {
diff --git a/src/cmd/pprof/pprof_test.go b/src/cmd/pprof/pprof_test.go
new file mode 100644
index 0000000..11e251b
--- /dev/null
+++ b/src/cmd/pprof/pprof_test.go
@@ -0,0 +1,127 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"internal/testenv"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+var tmp, pprofExe string // populated by buildPprof
+
+func TestMain(m *testing.M) {
+	if !testenv.HasGoBuild() {
+		return
+	}
+
+	var exitcode int
+	if err := buildPprof(); err == nil {
+		exitcode = m.Run()
+	} else {
+		fmt.Println(err)
+		exitcode = 1
+	}
+	os.RemoveAll(tmp)
+	os.Exit(exitcode)
+}
+
+func buildPprof() error {
+	var err error
+	tmp, err = os.MkdirTemp("", "TestPprof")
+	if err != nil {
+		return fmt.Errorf("TempDir failed: %v", err)
+	}
+
+	pprofExe = filepath.Join(tmp, "testpprof.exe")
+	gotool, err := testenv.GoTool()
+	if err != nil {
+		return err
+	}
+	out, err := exec.Command(gotool, "build", "-o", pprofExe, "cmd/pprof").CombinedOutput()
+	if err != nil {
+		os.RemoveAll(tmp)
+		return fmt.Errorf("go build -o %v cmd/pprof: %v\n%s", pprofExe, err, string(out))
+	}
+
+	return nil
+}
+
+// See also runtime/pprof.cpuProfilingBroken.
+func mustHaveCPUProfiling(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping on %s, unimplemented", runtime.GOOS)
+	case "aix":
+		t.Skipf("skipping on %s, issue 45170", runtime.GOOS)
+	case "ios", "dragonfly", "netbsd", "illumos", "solaris":
+		t.Skipf("skipping on %s, issue 13841", runtime.GOOS)
+	case "openbsd":
+		if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
+			t.Skipf("skipping on %s/%s, issue 13841", runtime.GOOS, runtime.GOARCH)
+		}
+	}
+}
+
+func mustHaveDisasm(t *testing.T) {
+	switch runtime.GOARCH {
+	case "mips", "mipsle", "mips64", "mips64le":
+		t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)
+	case "riscv64":
+		t.Skipf("skipping on %s, issue 36738", runtime.GOARCH)
+	case "s390x":
+		t.Skipf("skipping on %s, issue 15255", runtime.GOARCH)
+	}
+
+	// Skip PIE platforms, pprof can't disassemble PIE.
+	if runtime.GOOS == "windows" {
+		t.Skipf("skipping on %s, issue 46639", runtime.GOOS)
+	}
+	if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
+		t.Skipf("skipping on %s/%s, issue 46639", runtime.GOOS, runtime.GOARCH)
+	}
+}
+
+// TestDisasm verifies that cmd/pprof can successfully disassemble functions.
+//
+// This is a regression test for issue 46636.
+func TestDisasm(t *testing.T) {
+	mustHaveCPUProfiling(t)
+	mustHaveDisasm(t)
+	testenv.MustHaveGoBuild(t)
+
+	tmpdir := t.TempDir()
+	cpuExe := filepath.Join(tmpdir, "cpu.exe")
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", cpuExe, "cpu.go")
+	cmd.Dir = "testdata/"
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("build failed: %v\n%s", err, out)
+	}
+
+	profile := filepath.Join(tmpdir, "cpu.pprof")
+	cmd = exec.Command(cpuExe, "-output", profile)
+	out, err = cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("cpu failed: %v\n%s", err, out)
+	}
+
+	cmd = exec.Command(pprofExe, "-disasm", "main.main", cpuExe, profile)
+	out, err = cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("pprof failed: %v\n%s", err, out)
+	}
+
+	sout := string(out)
+	want := "ROUTINE ======================== main.main"
+	if !strings.Contains(sout, want) {
+		t.Errorf("pprof disasm got %s want contains %q", sout, want)
+	}
+}
diff --git a/src/cmd/pprof/readlineui.go b/src/cmd/pprof/readlineui.go
index 0c9fafd..f46e934 100644
--- a/src/cmd/pprof/readlineui.go
+++ b/src/cmd/pprof/readlineui.go
@@ -5,6 +5,7 @@
 // This file contains a driver.UI implementation
 // that provides the readline functionality if possible.
 
+//go:build (darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows) && !appengine && !android
 // +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
 // +build !appengine
 // +build !android
@@ -18,7 +19,7 @@
 	"strings"
 
 	"github.com/google/pprof/driver"
-	"golang.org/x/crypto/ssh/terminal"
+	"golang.org/x/term"
 )
 
 func init() {
@@ -26,11 +27,11 @@
 }
 
 // readlineUI implements driver.UI interface using the
-// golang.org/x/crypto/ssh/terminal package.
+// golang.org/x/term package.
 // The upstream pprof command implements the same functionality
 // using the github.com/chzyer/readline package.
 type readlineUI struct {
-	term *terminal.Terminal
+	term *term.Terminal
 }
 
 func newReadlineUI() driver.UI {
@@ -38,19 +39,19 @@
 	if v := strings.ToLower(os.Getenv("TERM")); v == "" || v == "dumb" {
 		return nil
 	}
-	// test if we can use terminal.ReadLine
+	// test if we can use term.ReadLine
 	// that assumes operation in the raw mode.
-	oldState, err := terminal.MakeRaw(0)
+	oldState, err := term.MakeRaw(0)
 	if err != nil {
 		return nil
 	}
-	terminal.Restore(0, oldState)
+	term.Restore(0, oldState)
 
 	rw := struct {
 		io.Reader
 		io.Writer
 	}{os.Stdin, os.Stderr}
-	return &readlineUI{term: terminal.NewTerminal(rw, "")}
+	return &readlineUI{term: term.NewTerminal(rw, "")}
 }
 
 // Read returns a line of text (a command) read from the user.
@@ -60,8 +61,8 @@
 
 	// skip error checking because we tested it
 	// when creating this readlineUI initially.
-	oldState, _ := terminal.MakeRaw(0)
-	defer terminal.Restore(0, oldState)
+	oldState, _ := term.MakeRaw(0)
+	defer term.Restore(0, oldState)
 
 	s, err := r.term.ReadLine()
 	return s, err
@@ -105,7 +106,7 @@
 // interactive terminal (as opposed to being redirected to a file).
 func (r *readlineUI) IsTerminal() bool {
 	const stdout = 1
-	return terminal.IsTerminal(stdout)
+	return term.IsTerminal(stdout)
 }
 
 // WantBrowser indicates whether browser should be opened with the -http option.
diff --git a/src/cmd/pprof/testdata/cpu.go b/src/cmd/pprof/testdata/cpu.go
new file mode 100644
index 0000000..5b68287
--- /dev/null
+++ b/src/cmd/pprof/testdata/cpu.go
@@ -0,0 +1,41 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"flag"
+	"fmt"
+	"os"
+	"runtime/pprof"
+	"time"
+)
+
+var output = flag.String("output", "", "pprof profile output file")
+
+func main() {
+	flag.Parse()
+	if *output == "" {
+		fmt.Fprintf(os.Stderr, "usage: %s -output file.pprof\n", os.Args[0])
+		os.Exit(2)
+	}
+
+	f, err := os.Create(*output)
+	if err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(2)
+	}
+	defer f.Close()
+
+	if err := pprof.StartCPUProfile(f); err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(2)
+	}
+	defer pprof.StopCPUProfile()
+
+	// Spin for long enough to collect some samples.
+	start := time.Now()
+	for time.Since(start) < time.Second {
+	}
+}
diff --git a/src/cmd/trace/annotations_test.go b/src/cmd/trace/annotations_test.go
index 9c2d027..acd5693 100644
--- a/src/cmd/trace/annotations_test.go
+++ b/src/cmd/trace/annotations_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package main
diff --git a/src/cmd/trace/mmu.go b/src/cmd/trace/mmu.go
index b92fac6..1d1fd2e 100644
--- a/src/cmd/trace/mmu.go
+++ b/src/cmd/trace/mmu.go
@@ -283,7 +283,7 @@
          .done(function(worst) {
             details.text('Lowest mutator utilization in ' + niceDuration(windowNS) + ' windows:');
             for (var i = 0; i < worst.length; i++) {
-              details.append($('<br/>'));
+              details.append($('<br>'));
               var text = worst[i].MutatorUtil.toFixed(3) + ' at time ' + niceDuration(worst[i].Time);
               details.append($('<a/>').text(text).attr('href', worst[i].URL));
             }
@@ -328,27 +328,27 @@
       <div id="mmu_chart" style="width: 900px; height: 500px; display: inline-block; vertical-align: top">Loading plot...</div>
       <div id="options" style="display: inline-block; vertical-align: top">
         <p>
-          <b>View</b><br/>
+          <b>View</b><br>
           <input type="radio" name="view" id="system" checked><label for="system">System</label>
-          <span class="help">?<span>Consider whole system utilization. For example, if one of four procs is available to the mutator, mutator utilization will be 0.25. This is the standard definition of an MMU.</span></span><br/>
+          <span class="help">?<span>Consider whole system utilization. For example, if one of four procs is available to the mutator, mutator utilization will be 0.25. This is the standard definition of an MMU.</span></span><br>
           <input type="radio" name="view" id="perProc"><label for="perProc">Per-goroutine</label>
-          <span class="help">?<span>Consider per-goroutine utilization. When even one goroutine is interrupted by GC, mutator utilization is 0.</span></span><br/>
+          <span class="help">?<span>Consider per-goroutine utilization. When even one goroutine is interrupted by GC, mutator utilization is 0.</span></span><br>
         </p>
         <p>
-          <b>Include</b><br/>
+          <b>Include</b><br>
           <input type="checkbox" id="stw" checked><label for="stw">STW</label>
-          <span class="help">?<span>Stop-the-world stops all goroutines simultaneously.</span></span><br/>
+          <span class="help">?<span>Stop-the-world stops all goroutines simultaneously.</span></span><br>
           <input type="checkbox" id="background" checked><label for="background">Background workers</label>
-          <span class="help">?<span>Background workers are GC-specific goroutines. 25% of the CPU is dedicated to background workers during GC.</span></span><br/>
+          <span class="help">?<span>Background workers are GC-specific goroutines. 25% of the CPU is dedicated to background workers during GC.</span></span><br>
           <input type="checkbox" id="assist" checked><label for="assist">Mark assist</label>
-          <span class="help">?<span>Mark assists are performed by allocation to prevent the mutator from outpacing GC.</span></span><br/>
+          <span class="help">?<span>Mark assists are performed by allocation to prevent the mutator from outpacing GC.</span></span><br>
           <input type="checkbox" id="sweep"><label for="sweep">Sweep</label>
-          <span class="help">?<span>Sweep reclaims unused memory between GCs. (Enabling this may be very slow.).</span></span><br/>
+          <span class="help">?<span>Sweep reclaims unused memory between GCs. (Enabling this may be very slow.).</span></span><br>
         </p>
         <p>
-          <b>Display</b><br/>
+          <b>Display</b><br>
           <input type="checkbox" id="mut"><label for="mut">Show percentiles</label>
-          <span class="help">?<span>Display percentile mutator utilization in addition to minimum. E.g., p99 MU drops the worst 1% of windows.</span></span><br/>
+          <span class="help">?<span>Display percentile mutator utilization in addition to minimum. E.g., p99 MU drops the worst 1% of windows.</span></span><br>
         </p>
       </div>
     </div>
diff --git a/src/cmd/trace/trace.go b/src/cmd/trace/trace.go
index 30c80f0..ca10736 100644
--- a/src/cmd/trace/trace.go
+++ b/src/cmd/trace/trace.go
@@ -627,7 +627,7 @@
 			}
 		case trace.EvHeapAlloc:
 			ctx.heapStats.heapAlloc = ev.Args[0]
-		case trace.EvNextGC:
+		case trace.EvHeapGoal:
 			ctx.heapStats.nextGC = ev.Args[0]
 		}
 		if setGStateErr != nil {
diff --git a/src/cmd/trace/trace_test.go b/src/cmd/trace/trace_test.go
index ea0cc6f..2b1a68d 100644
--- a/src/cmd/trace/trace_test.go
+++ b/src/cmd/trace/trace_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package main
diff --git a/src/cmd/trace/trace_unix_test.go b/src/cmd/trace/trace_unix_test.go
index c569b40..8dc56a8 100644
--- a/src/cmd/trace/trace_unix_test.go
+++ b/src/cmd/trace/trace_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package main
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 e65bc2f..fc05f91 100644
--- a/src/cmd/vendor/github.com/google/pprof/driver/driver.go
+++ b/src/cmd/vendor/github.com/google/pprof/driver/driver.go
@@ -159,8 +159,8 @@
 	// Name returns the underlying file name, if available.
 	Name() string
 
-	// Base returns the base address to use when looking up symbols in the file.
-	Base() uint64
+	// ObjAddr returns the objdump address corresponding to a runtime address.
+	ObjAddr(addr uint64) (uint64, error)
 
 	// BuildID returns the GNU build ID of the file, or an empty string.
 	BuildID() string
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 c0661bf..0c70239 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
@@ -70,7 +70,11 @@
 }
 
 func (a *addr2LinerJob) readLine() (string, error) {
-	return a.out.ReadString('\n')
+	s, err := a.out.ReadString('\n')
+	if err != nil {
+		return "", err
+	}
+	return strings.TrimSpace(s), nil
 }
 
 // close releases any resources used by the addr2liner object.
@@ -115,19 +119,11 @@
 	return a, nil
 }
 
-func (d *addr2Liner) readString() (string, error) {
-	s, err := d.rw.readLine()
-	if err != nil {
-		return "", err
-	}
-	return strings.TrimSpace(s), nil
-}
-
 // readFrame parses the addr2line output for a single address. It
 // returns a populated plugin.Frame and whether it has reached the end of the
 // data.
 func (d *addr2Liner) readFrame() (plugin.Frame, bool) {
-	funcname, err := d.readString()
+	funcname, err := d.rw.readLine()
 	if err != nil {
 		return plugin.Frame{}, true
 	}
@@ -135,12 +131,12 @@
 		// If addr2line returns a hex address we can assume it is the
 		// sentinel. Read and ignore next two lines of output from
 		// addr2line
-		d.readString()
-		d.readString()
+		d.rw.readLine()
+		d.rw.readLine()
 		return plugin.Frame{}, true
 	}
 
-	fileline, err := d.readString()
+	fileline, err := d.rw.readLine()
 	if err != nil {
 		return plugin.Frame{}, true
 	}
@@ -186,7 +182,7 @@
 		return nil, err
 	}
 
-	resp, err := d.readString()
+	resp, err := d.rw.readLine()
 	if err != nil {
 		return nil, err
 	}
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 68fa559..24c48e6 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
@@ -43,15 +43,21 @@
 	cmd *exec.Cmd
 	in  io.WriteCloser
 	out *bufio.Reader
+	// llvm-symbolizer requires the symbol type, CODE or DATA, for symbolization.
+	symType string
 }
 
 func (a *llvmSymbolizerJob) write(s string) error {
-	_, err := fmt.Fprint(a.in, s+"\n")
+	_, err := fmt.Fprintln(a.in, a.symType, s)
 	return err
 }
 
 func (a *llvmSymbolizerJob) readLine() (string, error) {
-	return a.out.ReadString('\n')
+	s, err := a.out.ReadString('\n')
+	if err != nil {
+		return "", err
+	}
+	return strings.TrimSpace(s), nil
 }
 
 // close releases any resources used by the llvmSymbolizer object.
@@ -64,13 +70,17 @@
 // information about the given executable file. If file is a shared
 // library, base should be the address at which it was mapped in the
 // program under consideration.
-func newLLVMSymbolizer(cmd, file string, base uint64) (*llvmSymbolizer, error) {
+func newLLVMSymbolizer(cmd, file string, base uint64, isData bool) (*llvmSymbolizer, error) {
 	if cmd == "" {
 		cmd = defaultLLVMSymbolizer
 	}
 
 	j := &llvmSymbolizerJob{
-		cmd: exec.Command(cmd, "-inlining", "-demangle=false"),
+		cmd:     exec.Command(cmd, "-inlining", "-demangle=false"),
+		symType: "CODE",
+	}
+	if isData {
+		j.symType = "DATA"
 	}
 
 	var err error
@@ -97,19 +107,11 @@
 	return a, nil
 }
 
-func (d *llvmSymbolizer) readString() (string, error) {
-	s, err := d.rw.readLine()
-	if err != nil {
-		return "", err
-	}
-	return strings.TrimSpace(s), nil
-}
-
 // readFrame parses the llvm-symbolizer output for a single address. It
 // returns a populated plugin.Frame and whether it has reached the end of the
 // data.
 func (d *llvmSymbolizer) readFrame() (plugin.Frame, bool) {
-	funcname, err := d.readString()
+	funcname, err := d.rw.readLine()
 	if err != nil {
 		return plugin.Frame{}, true
 	}
@@ -121,13 +123,17 @@
 		funcname = ""
 	}
 
-	fileline, err := d.readString()
+	fileline, err := d.rw.readLine()
 	if err != nil {
 		return plugin.Frame{Func: funcname}, true
 	}
 
 	linenumber := 0
-	if fileline == "??:0" {
+	// The llvm-symbolizer outputs the <file_name>:<line_number>:<column_number>.
+	// When it cannot identify the source code location, it outputs "??:0:0".
+	// Older versions output just the filename and line number, so we check for
+	// both conditions here.
+	if fileline == "??:0" || fileline == "??:0:0" {
 		fileline = ""
 	} else {
 		switch split := strings.Split(fileline, ":"); len(split) {
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 1987bd3..8e0ccc7 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
@@ -29,27 +29,42 @@
 	defaultNM = "nm"
 )
 
-// addr2LinerNM is a connection to an nm command for obtaining address
+// addr2LinerNM is a connection to an nm command for obtaining symbol
 // information from a binary.
 type addr2LinerNM struct {
-	m []symbolInfo // Sorted list of addresses from binary.
+	m []symbolInfo // Sorted list of symbol addresses from binary.
 }
 
 type symbolInfo struct {
 	address uint64
+	size    uint64
 	name    string
+	symType string
 }
 
-//  newAddr2LinerNM starts the given nm command reporting information about the
-// given executable file. If file is a shared library, base should be
-// the address at which it was mapped in the program under
-// consideration.
+// isData returns if the symbol has a known data object symbol type.
+func (s *symbolInfo) isData() bool {
+	// The following symbol types are taken from https://linux.die.net/man/1/nm:
+	// Lowercase letter means local symbol, uppercase denotes a global symbol.
+	// - b or B: the symbol is in the uninitialized data section, e.g. .bss;
+	// - d or D: the symbol is in the initialized data section;
+	// - r or R: the symbol is in a read only data section;
+	// - v or V: the symbol is a weak object;
+	// - W: the symbol is a weak symbol that has not been specifically tagged as a
+	//      weak object symbol. Experiments with some binaries, showed these to be
+	//      mostly data objects.
+	return strings.ContainsAny(s.symType, "bBdDrRvVW")
+}
+
+// newAddr2LinerNM starts the given nm command reporting information about the
+// given executable file. If file is a shared library, base should be the
+// address at which it was mapped in the program under consideration.
 func newAddr2LinerNM(cmd, file string, base uint64) (*addr2LinerNM, error) {
 	if cmd == "" {
 		cmd = defaultNM
 	}
 	var b bytes.Buffer
-	c := exec.Command(cmd, "-n", file)
+	c := exec.Command(cmd, "--numeric-sort", "--print-size", "--format=posix", file)
 	c.Stdout = &b
 	if err := c.Run(); err != nil {
 		return nil, err
@@ -74,17 +89,23 @@
 			return nil, err
 		}
 		line = strings.TrimSpace(line)
-		fields := strings.SplitN(line, " ", 3)
-		if len(fields) != 3 {
+		fields := strings.Split(line, " ")
+		if len(fields) != 4 {
 			continue
 		}
-		address, err := strconv.ParseUint(fields[0], 16, 64)
+		address, err := strconv.ParseUint(fields[2], 16, 64)
+		if err != nil {
+			continue
+		}
+		size, err := strconv.ParseUint(fields[3], 16, 64)
 		if err != nil {
 			continue
 		}
 		a.m = append(a.m, symbolInfo{
 			address: address + base,
-			name:    fields[2],
+			size:    size,
+			name:    fields[0],
+			symType: fields[1],
 		})
 	}
 
@@ -94,7 +115,7 @@
 // addrInfo returns the stack frame information for a specific program
 // address. It returns nil if the address could not be identified.
 func (a *addr2LinerNM) addrInfo(addr uint64) ([]plugin.Frame, error) {
-	if len(a.m) == 0 || addr < a.m[0].address || addr > a.m[len(a.m)-1].address {
+	if len(a.m) == 0 || addr < a.m[0].address || addr >= (a.m[len(a.m)-1].address+a.m[len(a.m)-1].size) {
 		return nil, nil
 	}
 
@@ -113,12 +134,11 @@
 		}
 	}
 
-	// Address is between a.m[low] and a.m[high].
-	// Pick low, as it represents [low, high).
-	f := []plugin.Frame{
-		{
-			Func: a.m[low].name,
-		},
+	// Address is between a.m[low] and a.m[high]. Pick low, as it represents
+	// [low, high). For data symbols, we use a strict check that the address is in
+	// the [start, start + size) range of a.m[low].
+	if a.m[low].isData() && addr >= (a.m[low].address+a.m[low].size) {
+		return nil, nil
 	}
-	return f, nil
+	return []plugin.Frame{{Func: a.m[low].name}}, 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 4b67cc4..5ed8a1f 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
@@ -18,6 +18,7 @@
 import (
 	"debug/elf"
 	"debug/macho"
+	"debug/pe"
 	"encoding/binary"
 	"errors"
 	"fmt"
@@ -41,7 +42,12 @@
 	rep *binrep
 }
 
-var objdumpLLVMVerRE = regexp.MustCompile(`LLVM version (?:(\d*)\.(\d*)\.(\d*)|.*(trunk).*)`)
+var (
+	objdumpLLVMVerRE = regexp.MustCompile(`LLVM version (?:(\d*)\.(\d*)\.(\d*)|.*(trunk).*)`)
+
+	// Defined for testing
+	elfOpen = elf.Open
+)
 
 // binrep is an immutable representation for Binutils.  It is atomically
 // replaced on every mutation to provide thread-safe access.
@@ -255,7 +261,7 @@
 	if !b.objdumpFound {
 		return nil, errors.New("cannot disasm: no objdump tool available")
 	}
-	args := []string{"--disassemble-all", "--demangle", "--no-show-raw-insn",
+	args := []string{"--disassemble", "--demangle", "--no-show-raw-insn",
 		"--line-numbers", fmt.Sprintf("--start-address=%#x", start),
 		fmt.Sprintf("--stop-address=%#x", end)}
 
@@ -337,6 +343,15 @@
 		return f, nil
 	}
 
+	peMagic := string(header[:2])
+	if peMagic == "MZ" {
+		f, err := b.openPE(name, start, limit, offset)
+		if err != nil {
+			return nil, fmt.Errorf("error reading PE file %s: %v", name, err)
+		}
+		return f, nil
+	}
+
 	return nil, fmt.Errorf("unrecognized binary format: %s", name)
 }
 
@@ -411,14 +426,23 @@
 }
 
 func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFile, error) {
-	ef, err := elf.Open(name)
+	ef, err := elfOpen(name)
 	if err != nil {
 		return nil, fmt.Errorf("error parsing %s: %v", name, err)
 	}
 	defer ef.Close()
 
-	var stextOffset *uint64
-	var pageAligned = func(addr uint64) bool { return addr%4096 == 0 }
+	buildID := ""
+	if f, err := os.Open(name); err == nil {
+		if id, err := elfexec.GetBuildID(f); err == nil {
+			buildID = fmt.Sprintf("%x", id)
+		}
+	}
+
+	var (
+		stextOffset *uint64
+		pageAligned = func(addr uint64) bool { return addr%4096 == 0 }
+	)
 	if strings.Contains(name, "vmlinux") || !pageAligned(start) || !pageAligned(limit) || !pageAligned(offset) {
 		// Reading all Symbols is expensive, and we only rarely need it so
 		// we don't want to do it every time. But if _stext happens to be
@@ -440,37 +464,171 @@
 		}
 	}
 
-	base, err := elfexec.GetBase(&ef.FileHeader, elfexec.FindTextProgHeader(ef), stextOffset, start, limit, offset)
-	if err != nil {
+	// Check that we can compute a base for the binary. This may not be the
+	// correct base value, so we don't save it. We delay computing the actual base
+	// value until we have a sample address for this mapping, so that we can
+	// correctly identify the associated program segment that is needed to compute
+	// the base.
+	if _, err := elfexec.GetBase(&ef.FileHeader, elfexec.FindTextProgHeader(ef), stextOffset, start, limit, offset); err != nil {
 		return nil, fmt.Errorf("could not identify base for %s: %v", name, err)
 	}
 
-	buildID := ""
-	if f, err := os.Open(name); err == nil {
-		if id, err := elfexec.GetBuildID(f); err == nil {
-			buildID = fmt.Sprintf("%x", id)
-		}
+	if b.fast || (!b.addr2lineFound && !b.llvmSymbolizerFound) {
+		return &fileNM{file: file{
+			b:       b,
+			name:    name,
+			buildID: buildID,
+			m:       &elfMapping{start: start, limit: limit, offset: offset, stextOffset: stextOffset},
+		}}, nil
+	}
+	return &fileAddr2Line{file: file{
+		b:       b,
+		name:    name,
+		buildID: buildID,
+		m:       &elfMapping{start: start, limit: limit, offset: offset, stextOffset: stextOffset},
+	}}, nil
+}
+
+func (b *binrep) openPE(name string, start, limit, offset uint64) (plugin.ObjFile, error) {
+	pf, err := pe.Open(name)
+	if err != nil {
+		return nil, fmt.Errorf("error parsing %s: %v", name, err)
+	}
+	defer pf.Close()
+
+	var imageBase uint64
+	switch h := pf.OptionalHeader.(type) {
+	case *pe.OptionalHeader32:
+		imageBase = uint64(h.ImageBase)
+	case *pe.OptionalHeader64:
+		imageBase = uint64(h.ImageBase)
+	default:
+		return nil, fmt.Errorf("unknown OptionalHeader %T", pf.OptionalHeader)
+	}
+
+	var base uint64
+	if start > 0 {
+		base = start - imageBase
 	}
 	if b.fast || (!b.addr2lineFound && !b.llvmSymbolizerFound) {
-		return &fileNM{file: file{b, name, base, buildID}}, nil
+		return &fileNM{file: file{b: b, name: name, base: base}}, nil
 	}
-	return &fileAddr2Line{file: file{b, name, base, buildID}}, nil
+	return &fileAddr2Line{file: file{b: b, name: name, base: base}}, nil
+}
+
+// elfMapping stores the parameters of a runtime mapping that are needed to
+// identify the ELF segment associated with a mapping.
+type elfMapping struct {
+	// Runtime mapping parameters.
+	start, limit, offset uint64
+	// Offset of _stext symbol. Only defined for kernel images, nil otherwise.
+	stextOffset *uint64
 }
 
 // file implements the binutils.ObjFile interface.
 type file struct {
 	b       *binrep
 	name    string
-	base    uint64
 	buildID string
+
+	baseOnce sync.Once // Ensures the base, baseErr and isData are computed once.
+	base     uint64
+	baseErr  error // Any eventual error while computing the base.
+	isData   bool
+	// Mapping information. Relevant only for ELF files, nil otherwise.
+	m *elfMapping
+}
+
+// computeBase computes the relocation base for the given binary file only if
+// the elfMapping field is set. It populates the base and isData fields and
+// returns an error.
+func (f *file) computeBase(addr uint64) error {
+	if f == nil || f.m == nil {
+		return nil
+	}
+	if addr < f.m.start || addr >= f.m.limit {
+		return fmt.Errorf("specified address %x is outside the mapping range [%x, %x] for file %q", addr, f.m.start, f.m.limit, f.name)
+	}
+	ef, err := elfOpen(f.name)
+	if err != nil {
+		return fmt.Errorf("error parsing %s: %v", f.name, err)
+	}
+	defer ef.Close()
+
+	var ph *elf.ProgHeader
+	// For user space executables, find the actual program segment that is
+	// associated with the given mapping. Skip this search if limit <= start.
+	// We cannot use just a check on the start address of the mapping to tell if
+	// it's a kernel / .ko module mapping, because with quipper address remapping
+	// enabled, the address would be in the lower half of the address space.
+	if f.m.stextOffset == nil && f.m.start < f.m.limit && f.m.limit < (uint64(1)<<63) {
+		// Get all program headers associated with the mapping.
+		headers, hasLoadables := elfexec.ProgramHeadersForMapping(ef, f.m.offset, f.m.limit-f.m.start)
+
+		// Some ELF files don't contain any loadable program segments, e.g. .ko
+		// kernel modules. It's not an error to have no header in such cases.
+		if hasLoadables {
+			ph, err = matchUniqueHeader(headers, addr-f.m.start+f.m.offset)
+			if err != nil {
+				return fmt.Errorf("failed to find program header for file %q, ELF mapping %#v, address %x: %v", f.name, *f.m, addr, err)
+			}
+		}
+	} else {
+		// For the kernel, find the program segment that includes the .text section.
+		ph = elfexec.FindTextProgHeader(ef)
+	}
+
+	base, err := elfexec.GetBase(&ef.FileHeader, ph, f.m.stextOffset, f.m.start, f.m.limit, f.m.offset)
+	if err != nil {
+		return err
+	}
+	f.base = base
+	f.isData = ph != nil && ph.Flags&elf.PF_X == 0
+	return nil
+}
+
+// matchUniqueHeader attempts to identify a unique header from the given list,
+// using the given file offset to disambiguate between multiple segments. It
+// returns an error if the header list is empty or if it cannot identify a
+// unique header.
+func matchUniqueHeader(headers []*elf.ProgHeader, fileOffset uint64) (*elf.ProgHeader, error) {
+	if len(headers) == 0 {
+		return nil, errors.New("no program header matches mapping info")
+	}
+	if len(headers) == 1 {
+		// Don't use the file offset if we already have a single header.
+		return headers[0], nil
+	}
+	// We have multiple input segments. Attempt to identify a unique one
+	// based on the given file offset.
+	var ph *elf.ProgHeader
+	for _, h := range headers {
+		if fileOffset >= h.Off && fileOffset < h.Off+h.Memsz {
+			if ph != nil {
+				// Assuming no other bugs, this can only happen if we have two or
+				// more small program segments that fit on the same page, and a
+				// segment other than the last one includes uninitialized data.
+				return nil, fmt.Errorf("found second program header (%#v) that matches file offset %x, first program header is %#v. Does first program segment contain uninitialized data?", *h, fileOffset, *ph)
+			}
+			ph = h
+		}
+	}
+	if ph == nil {
+		return nil, fmt.Errorf("no program header matches file offset %x", fileOffset)
+	}
+	return ph, nil
 }
 
 func (f *file) Name() string {
 	return f.name
 }
 
-func (f *file) Base() uint64 {
-	return f.base
+func (f *file) ObjAddr(addr uint64) (uint64, error) {
+	f.baseOnce.Do(func() { f.baseErr = f.computeBase(addr) })
+	if f.baseErr != nil {
+		return 0, f.baseErr
+	}
+	return addr - f.base, nil
 }
 
 func (f *file) BuildID() string {
@@ -478,7 +636,11 @@
 }
 
 func (f *file) SourceLine(addr uint64) ([]plugin.Frame, error) {
-	return []plugin.Frame{}, nil
+	f.baseOnce.Do(func() { f.baseErr = f.computeBase(addr) })
+	if f.baseErr != nil {
+		return nil, f.baseErr
+	}
+	return nil, nil
 }
 
 func (f *file) Close() error {
@@ -505,6 +667,10 @@
 }
 
 func (f *fileNM) SourceLine(addr uint64) ([]plugin.Frame, error) {
+	f.baseOnce.Do(func() { f.baseErr = f.computeBase(addr) })
+	if f.baseErr != nil {
+		return nil, f.baseErr
+	}
 	if f.addr2linernm == nil {
 		addr2liner, err := newAddr2LinerNM(f.b.nm, f.name, f.base)
 		if err != nil {
@@ -524,9 +690,14 @@
 	file
 	addr2liner     *addr2Liner
 	llvmSymbolizer *llvmSymbolizer
+	isData         bool
 }
 
 func (f *fileAddr2Line) SourceLine(addr uint64) ([]plugin.Frame, error) {
+	f.baseOnce.Do(func() { f.baseErr = f.computeBase(addr) })
+	if f.baseErr != nil {
+		return nil, f.baseErr
+	}
 	f.once.Do(f.init)
 	if f.llvmSymbolizer != nil {
 		return f.llvmSymbolizer.addrInfo(addr)
@@ -538,7 +709,7 @@
 }
 
 func (f *fileAddr2Line) init() {
-	if llvmSymbolizer, err := newLLVMSymbolizer(f.b.llvmSymbolizer, f.name, f.base); err == nil {
+	if llvmSymbolizer, err := newLLVMSymbolizer(f.b.llvmSymbolizer, f.name, f.base, f.isData); err == nil {
 		f.llvmSymbolizer = llvmSymbolizer
 		return
 	}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm.go
index d0be614..e64adf5 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm.go
@@ -19,6 +19,7 @@
 	"io"
 	"regexp"
 	"strconv"
+	"strings"
 
 	"github.com/google/pprof/internal/plugin"
 	"github.com/ianlancetaylor/demangle"
@@ -121,6 +122,7 @@
 				break
 			}
 		}
+		input = strings.TrimSpace(input)
 
 		if fields := objdumpAsmOutputRE.FindStringSubmatch(input); len(fields) == 3 {
 			if address, err := strconv.ParseUint(fields[1], 16, 64); err == nil {
@@ -167,6 +169,7 @@
 				return 0, "", err
 			}
 		}
+		line = strings.TrimSpace(line)
 
 		if fields := nmOutputRE.FindStringSubmatch(line); len(fields) == 4 {
 			if address, err := strconv.ParseUint(fields[1], 16, 64); err == nil {
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 878f2e1..3967a12 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
@@ -163,7 +163,7 @@
 	trim := cfg.Trim
 
 	switch cmd {
-	case "disasm", "weblist":
+	case "disasm":
 		trim = false
 		cfg.Granularity = "addresses"
 		// Force the 'noinlines' mode so that source locations for a given address
@@ -172,6 +172,10 @@
 		// This is because the merge is done by address and in case of an inlined
 		// stack each of the inlined entries is a separate callgraph node.
 		cfg.NoInlines = true
+	case "weblist":
+		trim = false
+		cfg.Granularity = "addresses"
+		cfg.NoInlines = false // Need inline info to support call expansion
 	case "peek":
 		trim = false
 	case "list":
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go
index 4f7610c..b8e8b50 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go
@@ -62,6 +62,7 @@
 .header .title h1 {
   font-size: 1.75em;
   margin-right: 1rem;
+  margin-bottom: 4px;
 }
 .header .title a {
   color: #212121;
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 d520765..2638b2d 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
@@ -283,3 +283,72 @@
 	}
 	return nil
 }
+
+// ProgramHeadersForMapping returns the loadable program segment headers that
+// are fully contained in the runtime mapping with file offset pgoff and memory
+// size memsz, and if the binary includes any loadable segments.
+func ProgramHeadersForMapping(f *elf.File, pgoff, memsz uint64) ([]*elf.ProgHeader, bool) {
+	const (
+		// pageSize defines the virtual memory page size used by the loader. This
+		// value is dependent on the memory management unit of the CPU. The page
+		// size is 4KB virtually on all the architectures that we care about, so we
+		// define this metric as a constant. If we encounter architectures where
+		// page sie is not 4KB, we must try to guess the page size on the system
+		// where the profile was collected, possibly using the architecture
+		// specified in the ELF file header.
+		pageSize       = 4096
+		pageOffsetMask = pageSize - 1
+		pageMask       = ^uint64(pageOffsetMask)
+	)
+	var headers []*elf.ProgHeader
+	hasLoadables := false
+	for _, p := range f.Progs {
+		// The segment must be fully included in the mapping.
+		if p.Type == elf.PT_LOAD && pgoff <= p.Off && p.Off+p.Memsz <= pgoff+memsz {
+			alignedOffset := uint64(0)
+			if p.Off > (p.Vaddr & pageOffsetMask) {
+				alignedOffset = p.Off - (p.Vaddr & pageOffsetMask)
+			}
+			if alignedOffset <= pgoff {
+				headers = append(headers, &p.ProgHeader)
+			}
+		}
+		if p.Type == elf.PT_LOAD {
+			hasLoadables = true
+		}
+	}
+	if len(headers) < 2 {
+		return headers, hasLoadables
+	}
+
+	// If we have more than one matching segments, try a strict check on the
+	// segment memory size. We use a heuristic to compute the minimum mapping size
+	// required for a segment, assuming mappings are page aligned.
+	// The memory size based heuristic makes sense only if the mapping size is a
+	// multiple of page size.
+	if memsz%pageSize != 0 {
+		return headers, hasLoadables
+	}
+
+	// Return all found headers if we cannot narrow the selection to a single
+	// program segment.
+	var ph *elf.ProgHeader
+	for _, h := range headers {
+		wantSize := (h.Vaddr+h.Memsz+pageSize-1)&pageMask - (h.Vaddr & pageMask)
+		if wantSize != memsz {
+			continue
+		}
+		if ph != nil {
+			// Found a second program header matching, so return all previously
+			// identified headers.
+			return headers, hasLoadables
+		}
+		ph = h
+	}
+	if ph == nil {
+		// No matching header for the strict check. Return all previously identified
+		// headers.
+		return headers, hasLoadables
+	}
+	return []*elf.ProgHeader{ph}, hasLoadables
+}
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 8cb87da..8008675 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
@@ -322,8 +322,8 @@
 }
 
 // dotColor returns a color for the given score (between -1.0 and
-// 1.0), with -1.0 colored red, 0.0 colored grey, and 1.0 colored
-// green. If isBackground is true, then a light (low-saturation)
+// 1.0), with -1.0 colored green, 0.0 colored grey, and 1.0 colored
+// red. If isBackground is true, then a light (low-saturation)
 // color is returned (suitable for use as a background color);
 // otherwise, a darker color is returned (suitable for use as a
 // foreground color).
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 e95b261..5332574 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
@@ -111,8 +111,9 @@
 	}
 
 	return v1.Unit == v2.Unit ||
-		(isTimeUnit(v1.Unit) && isTimeUnit(v2.Unit)) ||
-		(isMemoryUnit(v1.Unit) && isMemoryUnit(v2.Unit))
+		(timeUnits.sniffUnit(v1.Unit) != nil && timeUnits.sniffUnit(v2.Unit) != nil) ||
+		(memoryUnits.sniffUnit(v1.Unit) != nil && memoryUnits.sniffUnit(v2.Unit) != nil) ||
+		(gcuUnits.sniffUnit(v1.Unit) != nil && gcuUnits.sniffUnit(v2.Unit) != nil)
 }
 
 // Scale a measurement from an unit to a different unit and returns
@@ -124,12 +125,15 @@
 		v, u := Scale(-value, fromUnit, toUnit)
 		return -v, u
 	}
-	if m, u, ok := memoryLabel(value, fromUnit, toUnit); ok {
+	if m, u, ok := memoryUnits.convertUnit(value, fromUnit, toUnit); ok {
 		return m, u
 	}
-	if t, u, ok := timeLabel(value, fromUnit, toUnit); ok {
+	if t, u, ok := timeUnits.convertUnit(value, fromUnit, toUnit); ok {
 		return t, u
 	}
+	if g, u, ok := gcuUnits.convertUnit(value, fromUnit, toUnit); ok {
+		return g, u
+	}
 	// Skip non-interesting units.
 	switch toUnit {
 	case "count", "sample", "unit", "minimum", "auto":
@@ -172,157 +176,121 @@
 	}
 }
 
-// isMemoryUnit returns whether a name is recognized as a memory size
-// unit.
-func isMemoryUnit(unit string) bool {
-	switch strings.TrimSuffix(strings.ToLower(unit), "s") {
-	case "byte", "b", "kilobyte", "kb", "megabyte", "mb", "gigabyte", "gb":
-		return true
-	}
-	return false
+// unit includes a list of aliases representing a specific unit and a factor
+// which one can multiple a value in the specified unit by to get the value
+// in terms of the base unit.
+type unit struct {
+	canonicalName string
+	aliases       []string
+	factor        float64
 }
 
-func memoryLabel(value int64, fromUnit, toUnit string) (v float64, u string, ok bool) {
-	fromUnit = strings.TrimSuffix(strings.ToLower(fromUnit), "s")
-	toUnit = strings.TrimSuffix(strings.ToLower(toUnit), "s")
+// unitType includes a list of units that are within the same category (i.e.
+// memory or time units) and a default unit to use for this type of unit.
+type unitType struct {
+	defaultUnit unit
+	units       []unit
+}
 
-	switch fromUnit {
-	case "byte", "b":
-	case "kb", "kbyte", "kilobyte":
-		value *= 1024
-	case "mb", "mbyte", "megabyte":
-		value *= 1024 * 1024
-	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
-	}
-
-	if toUnit == "minimum" || toUnit == "auto" {
-		switch {
-		case value < 1024:
-			toUnit = "b"
-		case value < 1024*1024:
-			toUnit = "kb"
-		case value < 1024*1024*1024:
-			toUnit = "mb"
-		case value < 1024*1024*1024*1024:
-			toUnit = "gb"
-		case value < 1024*1024*1024*1024*1024:
-			toUnit = "tb"
-		default:
-			toUnit = "pb"
+// findByAlias returns the unit associated with the specified alias. It returns
+// nil if the unit with such alias is not found.
+func (ut unitType) findByAlias(alias string) *unit {
+	for _, u := range ut.units {
+		for _, a := range u.aliases {
+			if alias == a {
+				return &u
+			}
 		}
 	}
-
-	var output float64
-	switch toUnit {
-	default:
-		output, toUnit = float64(value), "B"
-	case "kb", "kbyte", "kilobyte":
-		output, toUnit = float64(value)/1024, "kB"
-	case "mb", "mbyte", "megabyte":
-		output, toUnit = float64(value)/(1024*1024), "MB"
-	case "gb", "gbyte", "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
+	return nil
 }
 
-// isTimeUnit returns whether a name is recognized as a time unit.
-func isTimeUnit(unit string) bool {
+// sniffUnit simpifies the input alias and returns the unit associated with the
+// specified alias. It returns nil if the unit with such alias is not found.
+func (ut unitType) sniffUnit(unit string) *unit {
 	unit = strings.ToLower(unit)
 	if len(unit) > 2 {
 		unit = strings.TrimSuffix(unit, "s")
 	}
-
-	switch unit {
-	case "nanosecond", "ns", "microsecond", "millisecond", "ms", "s", "second", "sec", "hr", "day", "week", "year":
-		return true
-	}
-	return false
+	return ut.findByAlias(unit)
 }
 
-func timeLabel(value int64, fromUnit, toUnit string) (v float64, u string, ok bool) {
-	fromUnit = strings.ToLower(fromUnit)
-	if len(fromUnit) > 2 {
-		fromUnit = strings.TrimSuffix(fromUnit, "s")
-	}
-
-	toUnit = strings.ToLower(toUnit)
-	if len(toUnit) > 2 {
-		toUnit = strings.TrimSuffix(toUnit, "s")
-	}
-
-	var d time.Duration
-	switch fromUnit {
-	case "nanosecond", "ns":
-		d = time.Duration(value) * time.Nanosecond
-	case "microsecond":
-		d = time.Duration(value) * time.Microsecond
-	case "millisecond", "ms":
-		d = time.Duration(value) * time.Millisecond
-	case "second", "sec", "s":
-		d = time.Duration(value) * time.Second
-	case "cycle":
-		return float64(value), "", true
-	default:
-		return 0, "", false
-	}
-
-	if toUnit == "minimum" || toUnit == "auto" {
-		switch {
-		case d < 1*time.Microsecond:
-			toUnit = "ns"
-		case d < 1*time.Millisecond:
-			toUnit = "us"
-		case d < 1*time.Second:
-			toUnit = "ms"
-		case d < 1*time.Minute:
-			toUnit = "sec"
-		case d < 1*time.Hour:
-			toUnit = "min"
-		case d < 24*time.Hour:
-			toUnit = "hour"
-		case d < 15*24*time.Hour:
-			toUnit = "day"
-		case d < 120*24*time.Hour:
-			toUnit = "week"
-		default:
-			toUnit = "year"
+// autoScale takes in the value with units of the base unit and returns
+// that value scaled to a reasonable unit if a reasonable unit is
+// found.
+func (ut unitType) autoScale(value float64) (float64, string, bool) {
+	var f float64
+	var unit string
+	for _, u := range ut.units {
+		if u.factor >= f && (value/u.factor) >= 1.0 {
+			f = u.factor
+			unit = u.canonicalName
 		}
 	}
-
-	var output float64
-	dd := float64(d)
-	switch toUnit {
-	case "ns", "nanosecond":
-		output, toUnit = dd/float64(time.Nanosecond), "ns"
-	case "us", "microsecond":
-		output, toUnit = dd/float64(time.Microsecond), "us"
-	case "ms", "millisecond":
-		output, toUnit = dd/float64(time.Millisecond), "ms"
-	case "min", "minute":
-		output, toUnit = dd/float64(time.Minute), "mins"
-	case "hour", "hr":
-		output, toUnit = dd/float64(time.Hour), "hrs"
-	case "day":
-		output, toUnit = dd/float64(24*time.Hour), "days"
-	case "week", "wk":
-		output, toUnit = dd/float64(7*24*time.Hour), "wks"
-	case "year", "yr":
-		output, toUnit = dd/float64(365*24*time.Hour), "yrs"
-	default:
-		// "sec", "second", "s" handled by default case.
-		output, toUnit = dd/float64(time.Second), "s"
+	if f == 0 {
+		return 0, "", false
 	}
-	return output, toUnit, true
+	return value / f, unit, true
+}
+
+// convertUnit converts a value from the fromUnit to the toUnit, autoscaling
+// the value if the toUnit is "minimum" or "auto". If the fromUnit is not
+// included in the unitType, then a false boolean will be returned. If the
+// toUnit is not in the unitType, the value will be returned in terms of the
+// default unitType.
+func (ut unitType) convertUnit(value int64, fromUnitStr, toUnitStr string) (float64, string, bool) {
+	fromUnit := ut.sniffUnit(fromUnitStr)
+	if fromUnit == nil {
+		return 0, "", false
+	}
+	v := float64(value) * fromUnit.factor
+	if toUnitStr == "minimum" || toUnitStr == "auto" {
+		if v, u, ok := ut.autoScale(v); ok {
+			return v, u, true
+		}
+		return v / ut.defaultUnit.factor, ut.defaultUnit.canonicalName, true
+	}
+	toUnit := ut.sniffUnit(toUnitStr)
+	if toUnit == nil {
+		return v / ut.defaultUnit.factor, ut.defaultUnit.canonicalName, true
+	}
+	return v / toUnit.factor, toUnit.canonicalName, true
+}
+
+var memoryUnits = unitType{
+	units: []unit{
+		{"B", []string{"b", "byte"}, 1},
+		{"kB", []string{"kb", "kbyte", "kilobyte"}, float64(1 << 10)},
+		{"MB", []string{"mb", "mbyte", "megabyte"}, float64(1 << 20)},
+		{"GB", []string{"gb", "gbyte", "gigabyte"}, float64(1 << 30)},
+		{"TB", []string{"tb", "tbyte", "terabyte"}, float64(1 << 40)},
+		{"PB", []string{"pb", "pbyte", "petabyte"}, float64(1 << 50)},
+	},
+	defaultUnit: unit{"B", []string{"b", "byte"}, 1},
+}
+
+var timeUnits = unitType{
+	units: []unit{
+		{"ns", []string{"ns", "nanosecond"}, float64(time.Nanosecond)},
+		{"us", []string{"μs", "us", "microsecond"}, float64(time.Microsecond)},
+		{"ms", []string{"ms", "millisecond"}, float64(time.Millisecond)},
+		{"s", []string{"s", "sec", "second"}, float64(time.Second)},
+		{"hrs", []string{"hour", "hr"}, float64(time.Hour)},
+	},
+	defaultUnit: unit{"s", []string{}, float64(time.Second)},
+}
+
+var gcuUnits = unitType{
+	units: []unit{
+		{"n*GCU", []string{"nanogcu"}, 1e-9},
+		{"u*GCU", []string{"microgcu"}, 1e-6},
+		{"m*GCU", []string{"milligcu"}, 1e-3},
+		{"GCU", []string{"gcu"}, 1},
+		{"k*GCU", []string{"kilogcu"}, 1e3},
+		{"M*GCU", []string{"megagcu"}, 1e6},
+		{"G*GCU", []string{"gigagcu"}, 1e9},
+		{"T*GCU", []string{"teragcu"}, 1e12},
+		{"P*GCU", []string{"petagcu"}, 1e15},
+	},
+	defaultUnit: unit{"GCU", []string{}, 1.0},
 }
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 3a8d0af..a57a0b2 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
@@ -131,8 +131,9 @@
 	// Name returns the underlyinf file name, if available
 	Name() string
 
-	// Base returns the base address to use when looking up symbols in the file.
-	Base() uint64
+	// ObjAddr returns the objdump (linker) address corresponding to a runtime
+	// address, and an error.
+	ObjAddr(addr uint64) (uint64, error)
 
 	// BuildID returns the GNU build ID of the file, or an empty string.
 	BuildID() string
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 bc5685d..4a86554 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
@@ -445,7 +445,7 @@
 			return err
 		}
 
-		ns := annotateAssembly(insts, sns, s.base)
+		ns := annotateAssembly(insts, sns, s.file)
 
 		fmt.Fprintf(w, "ROUTINE ======================== %s\n", s.sym.Name[0])
 		for _, name := range s.sym.Name[1:] {
@@ -534,7 +534,6 @@
 			addr = *address
 		}
 		msyms, err := f.Symbols(rx, addr)
-		base := f.Base()
 		f.Close()
 		if err != nil {
 			continue
@@ -543,7 +542,6 @@
 			objSyms = append(objSyms,
 				&objSymbol{
 					sym:  ms,
-					base: base,
 					file: f,
 				},
 			)
@@ -558,7 +556,6 @@
 // added to correspond to sample addresses
 type objSymbol struct {
 	sym  *plugin.Sym
-	base uint64
 	file plugin.ObjFile
 }
 
@@ -578,8 +575,7 @@
 	for _, s := range symbols {
 		// Gather samples for this symbol.
 		for _, n := range ns {
-			address := n.Info.Address - s.base
-			if address >= s.sym.Start && address < s.sym.End {
+			if address, err := s.file.ObjAddr(n.Info.Address); err == nil && address >= s.sym.Start && address < s.sym.End {
 				symNodes[s] = append(symNodes[s], n)
 			}
 		}
@@ -621,7 +617,7 @@
 // annotateAssembly annotates a set of assembly instructions with a
 // set of samples. It returns a set of nodes to display. base is an
 // offset to adjust the sample addresses.
-func annotateAssembly(insts []plugin.Inst, samples graph.Nodes, base uint64) []assemblyInstruction {
+func annotateAssembly(insts []plugin.Inst, samples graph.Nodes, file plugin.ObjFile) []assemblyInstruction {
 	// Add end marker to simplify printing loop.
 	insts = append(insts, plugin.Inst{
 		Addr: ^uint64(0),
@@ -645,7 +641,10 @@
 
 		// Sum all the samples until the next instruction (to account
 		// for samples attributed to the middle of an instruction).
-		for next := insts[ix+1].Addr; s < len(samples) && samples[s].Info.Address-base < next; s++ {
+		for next := insts[ix+1].Addr; s < len(samples); s++ {
+			if addr, err := file.ObjAddr(samples[s].Info.Address); err != nil || addr >= next {
+				break
+			}
 			sample := samples[s]
 			n.flatDiv += sample.FlatDiv
 			n.flat += sample.Flat
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 b480535..54245e5 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
@@ -24,12 +24,15 @@
 	"io"
 	"os"
 	"path/filepath"
+	"regexp"
+	"sort"
 	"strconv"
 	"strings"
 
 	"github.com/google/pprof/internal/graph"
 	"github.com/google/pprof/internal/measurement"
 	"github.com/google/pprof/internal/plugin"
+	"github.com/google/pprof/profile"
 )
 
 // printSource prints an annotated source listing, include all
@@ -126,19 +129,75 @@
 	return nil
 }
 
+// sourcePrinter holds state needed for generating source+asm HTML listing.
+type sourcePrinter struct {
+	reader     *sourceReader
+	synth      *synthCode
+	objectTool plugin.ObjTool
+	objects    map[string]plugin.ObjFile  // Opened object files
+	sym        *regexp.Regexp             // May be nil
+	files      map[string]*sourceFile     // Set of files to print.
+	insts      map[uint64]instructionInfo // Instructions of interest (keyed by address).
+
+	// Set of function names that we are interested in (because they had
+	// a sample and match sym).
+	interest map[string]bool
+
+	// Mapping from system function names to printable names.
+	prettyNames map[string]string
+}
+
+// addrInfo holds information for an address we are interested in.
+type addrInfo struct {
+	loc *profile.Location // Always non-nil
+	obj plugin.ObjFile    // May be nil
+}
+
+// instructionInfo holds collected information for an instruction.
+type instructionInfo struct {
+	objAddr   uint64 // Address in object file (with base subtracted out)
+	length    int    // Instruction length in bytes
+	disasm    string // Disassembly of instruction
+	file      string // For top-level function in which instruction occurs
+	line      int    // For top-level function in which instruction occurs
+	flat, cum int64  // Samples to report (divisor already applied)
+}
+
+// sourceFile contains collected information for files we will print.
+type sourceFile struct {
+	fname    string
+	cum      int64
+	flat     int64
+	lines    map[int][]sourceInst // Instructions to show per line
+	funcName map[int]string       // Function name per line
+}
+
+// sourceInst holds information for an instruction to be displayed.
+type sourceInst struct {
+	addr  uint64
+	stack []callID // Inlined call-stack
+}
+
+// sourceFunction contains information for a contiguous range of lines per function we
+// will print.
+type sourceFunction struct {
+	name       string
+	begin, end int // Line numbers (end is not included in the range)
+	flat, cum  int64
+}
+
+// addressRange is a range of addresses plus the object file that contains it.
+type addressRange struct {
+	begin, end uint64
+	obj        plugin.ObjFile
+	mapping    *profile.Mapping
+	score      int64 // Used to order ranges for processing
+}
+
 // PrintWebList prints annotated source listing of rpt to w.
+// rpt.prof should contain inlined call info.
 func PrintWebList(w io.Writer, rpt *Report, obj plugin.ObjTool, maxFiles int) error {
-	o := rpt.options
-	g := rpt.newGraph(nil)
-
-	// If the regexp source can be parsed as an address, also match
-	// functions that land on that address.
-	var address *uint64
-	if hex, err := strconv.ParseUint(o.Symbol.String(), 0, 64); err == nil {
-		address = &hex
-	}
-
-	sourcePath := o.SourcePath
+	sourcePath := rpt.options.SourcePath
 	if sourcePath == "" {
 		wd, err := os.Getwd()
 		if err != nil {
@@ -146,171 +205,544 @@
 		}
 		sourcePath = wd
 	}
-	reader := newSourceReader(sourcePath, o.TrimPath)
+	sp := newSourcePrinter(rpt, obj, sourcePath)
+	sp.print(w, maxFiles, rpt)
+	sp.close()
+	return nil
+}
 
-	type fileFunction struct {
-		fileName, functionName string
+func newSourcePrinter(rpt *Report, obj plugin.ObjTool, sourcePath string) *sourcePrinter {
+	sp := &sourcePrinter{
+		reader:      newSourceReader(sourcePath, rpt.options.TrimPath),
+		synth:       newSynthCode(rpt.prof.Mapping),
+		objectTool:  obj,
+		objects:     map[string]plugin.ObjFile{},
+		sym:         rpt.options.Symbol,
+		files:       map[string]*sourceFile{},
+		insts:       map[uint64]instructionInfo{},
+		prettyNames: map[string]string{},
+		interest:    map[string]bool{},
 	}
 
-	// Extract interesting symbols from binary files in the profile and
-	// classify samples per symbol.
-	symbols := symbolsFromBinaries(rpt.prof, g, o.Symbol, address, obj)
-	symNodes := nodesPerSymbol(g.Nodes, symbols)
+	// If the regexp source can be parsed as an address, also match
+	// functions that land on that address.
+	var address *uint64
+	if sp.sym != nil {
+		if hex, err := strconv.ParseUint(sp.sym.String(), 0, 64); err == nil {
+			address = &hex
+		}
+	}
 
-	// Identify sources associated to a symbol by examining
-	// symbol samples. Classify samples per source file.
-	fileNodes := make(map[fileFunction]graph.Nodes)
-	if len(symNodes) == 0 {
-		for _, n := range g.Nodes {
-			if n.Info.File == "" || !o.Symbol.MatchString(n.Info.Name) {
+	addrs := map[uint64]addrInfo{}
+	flat := map[uint64]int64{}
+	cum := map[uint64]int64{}
+
+	// Record an interest in the function corresponding to lines[index].
+	markInterest := func(addr uint64, loc *profile.Location, index int) {
+		fn := loc.Line[index]
+		if fn.Function == nil {
+			return
+		}
+		sp.interest[fn.Function.Name] = true
+		sp.interest[fn.Function.SystemName] = true
+		if _, ok := addrs[addr]; !ok {
+			addrs[addr] = addrInfo{loc, sp.objectFile(loc.Mapping)}
+		}
+	}
+
+	// See if sp.sym matches line.
+	matches := func(line profile.Line) bool {
+		if line.Function == nil {
+			return false
+		}
+		return sp.sym.MatchString(line.Function.Name) ||
+			sp.sym.MatchString(line.Function.SystemName) ||
+			sp.sym.MatchString(line.Function.Filename)
+	}
+
+	// Extract sample counts and compute set of interesting functions.
+	for _, sample := range rpt.prof.Sample {
+		value := rpt.options.SampleValue(sample.Value)
+		if rpt.options.SampleMeanDivisor != nil {
+			div := rpt.options.SampleMeanDivisor(sample.Value)
+			if div != 0 {
+				value /= div
+			}
+		}
+
+		// Find call-sites matching sym.
+		for i := len(sample.Location) - 1; i >= 0; i-- {
+			loc := sample.Location[i]
+			for _, line := range loc.Line {
+				if line.Function == nil {
+					continue
+				}
+				sp.prettyNames[line.Function.SystemName] = line.Function.Name
+			}
+
+			addr := loc.Address
+			if addr == 0 {
+				// Some profiles are missing valid addresses.
+				addr = sp.synth.address(loc)
+			}
+
+			cum[addr] += value
+			if i == 0 {
+				flat[addr] += value
+			}
+
+			if sp.sym == nil || (address != nil && addr == *address) {
+				// Interested in top-level entry of stack.
+				if len(loc.Line) > 0 {
+					markInterest(addr, loc, len(loc.Line)-1)
+				}
 				continue
 			}
-			ff := fileFunction{n.Info.File, n.Info.Name}
-			fileNodes[ff] = append(fileNodes[ff], n)
-		}
-	} else {
-		for _, nodes := range symNodes {
-			for _, n := range nodes {
-				if n.Info.File != "" {
-					ff := fileFunction{n.Info.File, n.Info.Name}
-					fileNodes[ff] = append(fileNodes[ff], n)
+
+			// Seach in inlined stack for a match.
+			matchFile := (loc.Mapping != nil && sp.sym.MatchString(loc.Mapping.File))
+			for j, line := range loc.Line {
+				if (j == 0 && matchFile) || matches(line) {
+					markInterest(addr, loc, j)
 				}
 			}
 		}
 	}
 
-	if len(fileNodes) == 0 {
-		return fmt.Errorf("no source information for %s", o.Symbol.String())
-	}
+	sp.expandAddresses(rpt, addrs, flat)
+	sp.initSamples(flat, cum)
+	return sp
+}
 
-	sourceFiles := make(graph.Nodes, 0, len(fileNodes))
-	for _, nodes := range fileNodes {
-		sNode := *nodes[0]
-		sNode.Flat, sNode.Cum = nodes.Sum()
-		sourceFiles = append(sourceFiles, &sNode)
-	}
-
-	// Limit number of files printed?
-	if maxFiles < 0 {
-		sourceFiles.Sort(graph.FileOrder)
-	} else {
-		sourceFiles.Sort(graph.FlatNameOrder)
-		if maxFiles < len(sourceFiles) {
-			sourceFiles = sourceFiles[:maxFiles]
+func (sp *sourcePrinter) close() {
+	for _, objFile := range sp.objects {
+		if objFile != nil {
+			objFile.Close()
 		}
 	}
+}
 
-	// Print each file associated with this function.
-	for _, n := range sourceFiles {
-		ff := fileFunction{n.Info.File, n.Info.Name}
-		fns := fileNodes[ff]
+func (sp *sourcePrinter) expandAddresses(rpt *Report, addrs map[uint64]addrInfo, flat map[uint64]int64) {
+	// We found interesting addresses (ones with non-zero samples) above.
+	// Get covering address ranges and disassemble the ranges.
+	ranges, unprocessed := sp.splitIntoRanges(rpt.prof, addrs, flat)
+	sp.handleUnprocessed(addrs, unprocessed)
 
-		asm := assemblyPerSourceLine(symbols, fns, ff.fileName, obj, o.IntelSyntax)
-		start, end := sourceCoordinates(asm)
+	// Trim ranges if there are too many.
+	const maxRanges = 25
+	sort.Slice(ranges, func(i, j int) bool {
+		return ranges[i].score > ranges[j].score
+	})
+	if len(ranges) > maxRanges {
+		ranges = ranges[:maxRanges]
+	}
 
-		fnodes, path, err := getSourceFromFile(ff.fileName, reader, fns, start, end)
+	for _, r := range ranges {
+		objBegin, err := r.obj.ObjAddr(r.begin)
 		if err != nil {
-			fnodes, path = getMissingFunctionSource(ff.fileName, asm, start, end)
+			fmt.Fprintf(os.Stderr, "Failed to compute objdump address for range start %x: %v\n", r.begin, err)
+			continue
+		}
+		objEnd, err := r.obj.ObjAddr(r.end)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "Failed to compute objdump address for range end %x: %v\n", r.end, err)
+			continue
+		}
+		base := r.begin - objBegin
+		insts, err := sp.objectTool.Disasm(r.mapping.File, objBegin, objEnd, rpt.options.IntelSyntax)
+		if err != nil {
+			// TODO(sanjay): Report that the covered addresses are missing.
+			continue
 		}
 
-		printFunctionHeader(w, ff.functionName, path, n.Flat, n.Cum, rpt)
-		for _, fn := range fnodes {
-			printFunctionSourceLine(w, fn, asm[fn.Info.Lineno], reader, rpt)
+		var lastFrames []plugin.Frame
+		var lastAddr, maxAddr uint64
+		for i, inst := range insts {
+			addr := inst.Addr + base
+
+			// Guard against duplicate output from Disasm.
+			if addr <= maxAddr {
+				continue
+			}
+			maxAddr = addr
+
+			length := 1
+			if i+1 < len(insts) && insts[i+1].Addr > inst.Addr {
+				// Extend to next instruction.
+				length = int(insts[i+1].Addr - inst.Addr)
+			}
+
+			// Get inlined-call-stack for address.
+			frames, err := r.obj.SourceLine(addr)
+			if err != nil {
+				// Construct a frame from disassembler output.
+				frames = []plugin.Frame{{Func: inst.Function, File: inst.File, Line: inst.Line}}
+			}
+
+			x := instructionInfo{objAddr: inst.Addr, length: length, disasm: inst.Text}
+			if len(frames) > 0 {
+				// We could consider using the outer-most caller's source
+				// location so we give the some hint as to where the
+				// inlining happened that led to this instruction. So for
+				// example, suppose we have the following (inlined) call
+				// chains for this instruction:
+				//   F1->G->H
+				//   F2->G->H
+				// We could tag the instructions from the first call with
+				// F1 and instructions from the second call with F2. But
+				// that leads to a somewhat confusing display. So for now,
+				// we stick with just the inner-most location (i.e., H).
+				// In the future we will consider changing the display to
+				// make caller info more visible.
+				index := 0 // Inner-most frame
+				x.file = frames[index].File
+				x.line = frames[index].Line
+			}
+			sp.insts[addr] = x
+
+			// We sometimes get instructions with a zero reported line number.
+			// Make such instructions have the same line info as the preceding
+			// instruction, if an earlier instruction is found close enough.
+			const neighborhood = 32
+			if len(frames) > 0 && frames[0].Line != 0 {
+				lastFrames = frames
+				lastAddr = addr
+			} else if (addr-lastAddr <= neighborhood) && lastFrames != nil {
+				frames = lastFrames
+			}
+
+			sp.addStack(addr, frames)
+		}
+	}
+}
+
+func (sp *sourcePrinter) addStack(addr uint64, frames []plugin.Frame) {
+	// See if the stack contains a function we are interested in.
+	for i, f := range frames {
+		if !sp.interest[f.Func] {
+			continue
+		}
+
+		// Record sub-stack under frame's file/line.
+		fname := canonicalizeFileName(f.File)
+		file := sp.files[fname]
+		if file == nil {
+			file = &sourceFile{
+				fname:    fname,
+				lines:    map[int][]sourceInst{},
+				funcName: map[int]string{},
+			}
+			sp.files[fname] = file
+		}
+		callees := frames[:i]
+		stack := make([]callID, 0, len(callees))
+		for j := len(callees) - 1; j >= 0; j-- { // Reverse so caller is first
+			stack = append(stack, callID{
+				file: callees[j].File,
+				line: callees[j].Line,
+			})
+		}
+		file.lines[f.Line] = append(file.lines[f.Line], sourceInst{addr, stack})
+
+		// Remember the first function name encountered per source line
+		// and assume that that line belongs to that function.
+		if _, ok := file.funcName[f.Line]; !ok {
+			file.funcName[f.Line] = f.Func
+		}
+	}
+}
+
+// synthAsm is the special disassembler value used for instructions without an object file.
+const synthAsm = ""
+
+// handleUnprocessed handles addresses that were skipped by splitIntoRanges because they
+// did not belong to a known object file.
+func (sp *sourcePrinter) handleUnprocessed(addrs map[uint64]addrInfo, unprocessed []uint64) {
+	// makeFrames synthesizes a []plugin.Frame list for the specified address.
+	// The result will typically have length 1, but may be longer if address corresponds
+	// to inlined calls.
+	makeFrames := func(addr uint64) []plugin.Frame {
+		loc := addrs[addr].loc
+		stack := make([]plugin.Frame, 0, len(loc.Line))
+		for _, line := range loc.Line {
+			fn := line.Function
+			if fn == nil {
+				continue
+			}
+			stack = append(stack, plugin.Frame{
+				Func: fn.Name,
+				File: fn.Filename,
+				Line: int(line.Line),
+			})
+		}
+		return stack
+	}
+
+	for _, addr := range unprocessed {
+		frames := makeFrames(addr)
+		x := instructionInfo{
+			objAddr: addr,
+			length:  1,
+			disasm:  synthAsm,
+		}
+		if len(frames) > 0 {
+			x.file = frames[0].File
+			x.line = frames[0].Line
+		}
+		sp.insts[addr] = x
+
+		sp.addStack(addr, frames)
+	}
+}
+
+// splitIntoRanges converts the set of addresses we are interested in into a set of address
+// ranges to disassemble. It also returns the set of addresses found that did not have an
+// associated object file and were therefore not added to an address range.
+func (sp *sourcePrinter) splitIntoRanges(prof *profile.Profile, addrMap map[uint64]addrInfo, flat map[uint64]int64) ([]addressRange, []uint64) {
+	// Partition addresses into two sets: ones with a known object file, and ones without.
+	var addrs, unprocessed []uint64
+	for addr, info := range addrMap {
+		if info.obj != nil {
+			addrs = append(addrs, addr)
+		} else {
+			unprocessed = append(unprocessed, addr)
+		}
+	}
+	sort.Slice(addrs, func(i, j int) bool { return addrs[i] < addrs[j] })
+
+	const expand = 500 // How much to expand range to pick up nearby addresses.
+	var result []addressRange
+	for i, n := 0, len(addrs); i < n; {
+		begin, end := addrs[i], addrs[i]
+		sum := flat[begin]
+		i++
+
+		info := addrMap[begin]
+		m := info.loc.Mapping
+		obj := info.obj // Non-nil because of the partitioning done above.
+
+		// Find following addresses that are close enough to addrs[i].
+		for i < n && addrs[i] <= end+2*expand && addrs[i] < m.Limit {
+			// When we expand ranges by "expand" on either side, the ranges
+			// for addrs[i] and addrs[i-1] will merge.
+			end = addrs[i]
+			sum += flat[end]
+			i++
+		}
+		if m.Start-begin >= expand {
+			begin -= expand
+		} else {
+			begin = m.Start
+		}
+		if m.Limit-end >= expand {
+			end += expand
+		} else {
+			end = m.Limit
+		}
+
+		result = append(result, addressRange{begin, end, obj, m, sum})
+	}
+	return result, unprocessed
+}
+
+func (sp *sourcePrinter) initSamples(flat, cum map[uint64]int64) {
+	for addr, inst := range sp.insts {
+		// Move all samples that were assigned to the middle of an instruction to the
+		// beginning of that instruction. This takes care of samples that were recorded
+		// against pc+1.
+		instEnd := addr + uint64(inst.length)
+		for p := addr; p < instEnd; p++ {
+			inst.flat += flat[p]
+			inst.cum += cum[p]
+		}
+		sp.insts[addr] = inst
+	}
+}
+
+func (sp *sourcePrinter) print(w io.Writer, maxFiles int, rpt *Report) {
+	// Finalize per-file counts.
+	for _, file := range sp.files {
+		seen := map[uint64]bool{}
+		for _, line := range file.lines {
+			for _, x := range line {
+				if seen[x.addr] {
+					// Same address can be displayed multiple times in a file
+					// (e.g., if we show multiple inlined functions).
+					// Avoid double-counting samples in this case.
+					continue
+				}
+				seen[x.addr] = true
+				inst := sp.insts[x.addr]
+				file.cum += inst.cum
+				file.flat += inst.flat
+			}
+		}
+	}
+
+	// Get sorted list of files to print.
+	var files []*sourceFile
+	for _, f := range sp.files {
+		files = append(files, f)
+	}
+	order := func(i, j int) bool { return files[i].flat > files[j].flat }
+	if maxFiles < 0 {
+		// Order by name for compatibility with old code.
+		order = func(i, j int) bool { return files[i].fname < files[j].fname }
+		maxFiles = len(files)
+	}
+	sort.Slice(files, order)
+	for i, f := range files {
+		if i < maxFiles {
+			sp.printFile(w, f, rpt)
+		}
+	}
+}
+
+func (sp *sourcePrinter) printFile(w io.Writer, f *sourceFile, rpt *Report) {
+	for _, fn := range sp.functions(f) {
+		if fn.cum == 0 {
+			continue
+		}
+		printFunctionHeader(w, fn.name, f.fname, fn.flat, fn.cum, rpt)
+		var asm []assemblyInstruction
+		for l := fn.begin; l < fn.end; l++ {
+			lineContents, ok := sp.reader.line(f.fname, l)
+			if !ok {
+				if len(f.lines[l]) == 0 {
+					// Outside of range of valid lines and nothing to print.
+					continue
+				}
+				if l == 0 {
+					// Line number 0 shows up if line number is not known.
+					lineContents = "<instructions with unknown line numbers>"
+				} else {
+					// Past end of file, but have data to print.
+					lineContents = "???"
+				}
+			}
+
+			// Make list of assembly instructions.
+			asm = asm[:0]
+			var flatSum, cumSum int64
+			var lastAddr uint64
+			for _, inst := range f.lines[l] {
+				addr := inst.addr
+				x := sp.insts[addr]
+				flatSum += x.flat
+				cumSum += x.cum
+				startsBlock := (addr != lastAddr+uint64(sp.insts[lastAddr].length))
+				lastAddr = addr
+
+				// divisors already applied, so leave flatDiv,cumDiv as 0
+				asm = append(asm, assemblyInstruction{
+					address:     x.objAddr,
+					instruction: x.disasm,
+					function:    fn.name,
+					file:        x.file,
+					line:        x.line,
+					flat:        x.flat,
+					cum:         x.cum,
+					startsBlock: startsBlock,
+					inlineCalls: inst.stack,
+				})
+			}
+
+			printFunctionSourceLine(w, l, flatSum, cumSum, lineContents, asm, sp.reader, rpt)
 		}
 		printFunctionClosing(w)
 	}
-	return nil
 }
 
-// sourceCoordinates returns the lowest and highest line numbers from
-// a set of assembly statements.
-func sourceCoordinates(asm map[int][]assemblyInstruction) (start, end int) {
-	for l := range asm {
-		if start == 0 || l < start {
-			start = l
-		}
-		if end == 0 || l > end {
-			end = l
-		}
+// functions splits apart the lines to show in a file into a list of per-function ranges.
+func (sp *sourcePrinter) functions(f *sourceFile) []sourceFunction {
+	var funcs []sourceFunction
+
+	// Get interesting lines in sorted order.
+	lines := make([]int, 0, len(f.lines))
+	for l := range f.lines {
+		lines = append(lines, l)
 	}
-	return start, end
+	sort.Ints(lines)
+
+	// Merge adjacent lines that are in same function and not too far apart.
+	const mergeLimit = 20
+	for _, l := range lines {
+		name := f.funcName[l]
+		if pretty, ok := sp.prettyNames[name]; ok {
+			// Use demangled name if available.
+			name = pretty
+		}
+
+		fn := sourceFunction{name: name, begin: l, end: l + 1}
+		for _, x := range f.lines[l] {
+			inst := sp.insts[x.addr]
+			fn.flat += inst.flat
+			fn.cum += inst.cum
+		}
+
+		// See if we should merge into preceding function.
+		if len(funcs) > 0 {
+			last := funcs[len(funcs)-1]
+			if l-last.end < mergeLimit && last.name == name {
+				last.end = l + 1
+				last.flat += fn.flat
+				last.cum += fn.cum
+				funcs[len(funcs)-1] = last
+				continue
+			}
+		}
+
+		// Add new function.
+		funcs = append(funcs, fn)
+	}
+
+	// Expand function boundaries to show neighborhood.
+	const expand = 5
+	for i, f := range funcs {
+		if i == 0 {
+			// Extend backwards, stopping at line number 1, but do not disturb 0
+			// since that is a special line number that can show up when addr2line
+			// cannot determine the real line number.
+			if f.begin > expand {
+				f.begin -= expand
+			} else if f.begin > 1 {
+				f.begin = 1
+			}
+		} else {
+			// Find gap from predecessor and divide between predecessor and f.
+			halfGap := (f.begin - funcs[i-1].end) / 2
+			if halfGap > expand {
+				halfGap = expand
+			}
+			funcs[i-1].end += halfGap
+			f.begin -= halfGap
+		}
+		funcs[i] = f
+	}
+
+	// Also extend the ending point of the last function.
+	if len(funcs) > 0 {
+		funcs[len(funcs)-1].end += expand
+	}
+
+	return funcs
 }
 
-// assemblyPerSourceLine disassembles the binary containing a symbol
-// and classifies the assembly instructions according to its
-// corresponding source line, annotating them with a set of samples.
-func assemblyPerSourceLine(objSyms []*objSymbol, rs graph.Nodes, src string, obj plugin.ObjTool, intelSyntax bool) map[int][]assemblyInstruction {
-	assembly := make(map[int][]assemblyInstruction)
-	// Identify symbol to use for this collection of samples.
-	o := findMatchingSymbol(objSyms, rs)
-	if o == nil {
-		return assembly
+// objectFile return the object for the specified mapping, opening it if necessary.
+// It returns nil on error.
+func (sp *sourcePrinter) objectFile(m *profile.Mapping) plugin.ObjFile {
+	if m == nil {
+		return nil
 	}
-
-	// Extract assembly for matched symbol
-	insts, err := obj.Disasm(o.sym.File, o.sym.Start, o.sym.End, intelSyntax)
+	if object, ok := sp.objects[m.File]; ok {
+		return object // May be nil if we detected an error earlier.
+	}
+	object, err := sp.objectTool.Open(m.File, m.Start, m.Limit, m.Offset)
 	if err != nil {
-		return assembly
+		object = nil
 	}
-
-	srcBase := filepath.Base(src)
-	anodes := annotateAssembly(insts, rs, o.base)
-	var lineno = 0
-	var prevline = 0
-	for _, an := range anodes {
-		// 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)
-		}
-	}
-
-	return assembly
-}
-
-// findMatchingSymbol looks for the symbol that corresponds to a set
-// of samples, by comparing their addresses.
-func findMatchingSymbol(objSyms []*objSymbol, ns graph.Nodes) *objSymbol {
-	for _, n := range ns {
-		for _, o := range objSyms {
-			if filepath.Base(o.sym.File) == filepath.Base(n.Info.Objfile) &&
-				o.sym.Start <= n.Info.Address-o.base &&
-				n.Info.Address-o.base <= o.sym.End {
-				return o
-			}
-		}
-	}
-	return nil
+	sp.objects[m.File] = object // Cache even on error.
+	return object
 }
 
 // printHeader prints the page header for a weblist report.
@@ -348,22 +780,39 @@
 }
 
 // printFunctionSourceLine prints a source line and the corresponding assembly.
-func printFunctionSourceLine(w io.Writer, fn *graph.Node, assembly []assemblyInstruction, reader *sourceReader, rpt *Report) {
+func printFunctionSourceLine(w io.Writer, lineNo int, flat, cum int64, lineContents string,
+	assembly []assemblyInstruction, reader *sourceReader, rpt *Report) {
 	if len(assembly) == 0 {
 		fmt.Fprintf(w,
 			"<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))
+			lineNo,
+			valueOrDot(flat, rpt), valueOrDot(cum, rpt),
+			"", template.HTMLEscapeString(lineContents))
 		return
 	}
 
+	nestedInfo := false
+	cl := "deadsrc"
+	for _, an := range assembly {
+		if len(an.inlineCalls) > 0 || an.instruction != synthAsm {
+			nestedInfo = true
+			cl = "livesrc"
+		}
+	}
+
 	fmt.Fprintf(w,
-		"<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))
-	srcIndent := indentation(fn.Info.Name)
+		"<span class=line> %6d</span> <span class=%s>  %10s %10s %8s  %s </span>",
+		lineNo, cl,
+		valueOrDot(flat, rpt), valueOrDot(cum, rpt),
+		"", template.HTMLEscapeString(lineContents))
+	if nestedInfo {
+		srcIndent := indentation(lineContents)
+		printNested(w, srcIndent, assembly, reader, rpt)
+	}
+	fmt.Fprintln(w)
+}
+
+func printNested(w io.Writer, srcIndent int, assembly []assemblyInstruction, reader *sourceReader, rpt *Report) {
 	fmt.Fprint(w, "<span class=asm>")
 	var curCalls []callID
 	for i, an := range assembly {
@@ -374,15 +823,9 @@
 
 		var fileline string
 		if an.file != "" {
-			fileline = fmt.Sprintf("%s:%d", template.HTMLEscapeString(an.file), an.line)
+			fileline = fmt.Sprintf("%s:%d", template.HTMLEscapeString(filepath.Base(an.file)), an.line)
 		}
 		flat, cum := an.flat, an.cum
-		if an.flatDiv != 0 {
-			flat = flat / an.flatDiv
-		}
-		if an.cumDiv != 0 {
-			cum = cum / an.cumDiv
-		}
 
 		// Print inlined call context.
 		for j, c := range an.inlineCalls {
@@ -398,17 +841,23 @@
 			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(rightPad(text, 80)),
 				template.HTMLEscapeString(filepath.Base(c.file)), c.line)
 		}
 		curCalls = an.inlineCalls
+		if an.instruction == synthAsm {
+			continue
+		}
 		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))
+			template.HTMLEscapeString(rightPad(text, 80)),
+			// fileline should not be escaped since it was formed by appending
+			// line number (just digits) to an escaped file name. Escaping here
+			// would cause double-escaping of file name.
+			fileline)
 	}
-	fmt.Fprintln(w, "</span>")
+	fmt.Fprint(w, "</span>")
 }
 
 // printFunctionClosing prints the end of a function in a weblist report.
@@ -482,36 +931,6 @@
 	return src, file, nil
 }
 
-// getMissingFunctionSource creates a dummy function body to point to
-// the source file and annotates it with the samples in asm.
-func getMissingFunctionSource(filename string, asm map[int][]assemblyInstruction, start, end int) (graph.Nodes, string) {
-	var fnodes graph.Nodes
-	for i := start; i <= end; i++ {
-		insts := asm[i]
-		if len(insts) == 0 {
-			continue
-		}
-		var group assemblyInstruction
-		for _, insn := range insts {
-			group.flat += insn.flat
-			group.cum += insn.cum
-			group.flatDiv += insn.flatDiv
-			group.cumDiv += insn.cumDiv
-		}
-		flat := group.flatValue()
-		cum := group.cumValue()
-		fnodes = append(fnodes, &graph.Node{
-			Info: graph.NodeInfo{
-				Name:   "???",
-				Lineno: i,
-			},
-			Flat: flat,
-			Cum:  cum,
-		})
-	}
-	return fnodes, filename
-}
-
 // sourceReader provides access to source code with caching of file contents.
 type sourceReader struct {
 	// searchPath is a filepath.ListSeparator-separated list of directories where
@@ -543,6 +962,7 @@
 	return reader.errors[path]
 }
 
+// line returns the line numbered "lineno" in path, or _,false if lineno is out of range.
 func (reader *sourceReader) line(path string, lineno int) (string, bool) {
 	lines, ok := reader.files[path]
 	if !ok {
@@ -651,3 +1071,37 @@
 	}
 	return column
 }
+
+// rightPad pads the input with spaces on the right-hand-side to make it have
+// at least width n. It treats tabs as enough spaces that lead to the next
+// 8-aligned tab-stop.
+func rightPad(s string, n int) string {
+	var str strings.Builder
+
+	// Convert tabs to spaces as we go so padding works regardless of what prefix
+	// is placed before the result.
+	column := 0
+	for _, c := range s {
+		column++
+		if c == '\t' {
+			str.WriteRune(' ')
+			for column%8 != 0 {
+				column++
+				str.WriteRune(' ')
+			}
+		} else {
+			str.WriteRune(c)
+		}
+	}
+	for column < n {
+		column++
+		str.WriteRune(' ')
+	}
+	return str.String()
+}
+
+func canonicalizeFileName(fname string) string {
+	fname = strings.TrimPrefix(fname, "/proc/self/cwd/")
+	fname = strings.TrimPrefix(fname, "./")
+	return filepath.Clean(fname)
+}
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 02a6d77..17c9f6e 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
@@ -25,12 +25,11 @@
 }
 
 const weblistPageCSS = `<style type="text/css">
-body {
+body #content{
 font-family: sans-serif;
 }
 h1 {
   font-size: 1.5em;
-  margin-bottom: 4px;
 }
 .legend {
   font-size: 1.25em;
@@ -41,14 +40,7 @@
 .inlinesrc {
   color: #000066;
 }
-.deadsrc {
-cursor: pointer;
-}
-.deadsrc:hover {
-background-color: #eeeeee;
-}
 .livesrc {
-color: #0000ff;
 cursor: pointer;
 }
 .livesrc:hover {
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/synth.go b/src/cmd/vendor/github.com/google/pprof/internal/report/synth.go
new file mode 100644
index 0000000..7a35bbc
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/synth.go
@@ -0,0 +1,39 @@
+package report
+
+import (
+	"github.com/google/pprof/profile"
+)
+
+// synthCode assigns addresses to locations without an address.
+type synthCode struct {
+	next uint64
+	addr map[*profile.Location]uint64 // Synthesized address assigned to a location
+}
+
+func newSynthCode(mappings []*profile.Mapping) *synthCode {
+	// Find a larger address than any mapping.
+	s := &synthCode{next: 1}
+	for _, m := range mappings {
+		if s.next < m.Limit {
+			s.next = m.Limit
+		}
+	}
+	return s
+}
+
+// address returns the synthetic address for loc, creating one if needed.
+func (s *synthCode) address(loc *profile.Location) uint64 {
+	if loc.Address != 0 {
+		panic("can only synthesize addresses for locations without an address")
+	}
+	if addr, ok := s.addr[loc]; ok {
+		return addr
+	}
+	if s.addr == nil {
+		s.addr = map[*profile.Location]uint64{}
+	}
+	addr := s.next
+	s.next++
+	s.addr[loc] = addr
+	return addr
+}
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 1e84c72..ab7f03a 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/encode.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/encode.go
@@ -308,7 +308,7 @@
 			if l.strX != 0 {
 				value, err = getString(p.stringTable, &l.strX, err)
 				labels[key] = append(labels[key], value)
-			} else if l.numX != 0 {
+			} else if l.numX != 0 || l.unitX != 0 {
 				numValues := numLabels[key]
 				units := numUnits[key]
 				if l.unitX != 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 4dcc27f..9978e73 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/merge.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/merge.go
@@ -35,7 +35,10 @@
 // functions and mappings. Profiles must have identical profile sample
 // and period types or the merge will fail. profile.Period of the
 // resulting profile will be the maximum of all profiles, and
-// profile.TimeNanos will be the earliest nonzero one.
+// profile.TimeNanos will be the earliest nonzero one. Merges are
+// associative with the caveat of the first profile having some
+// specialization in how headers are combined. There may be other
+// subtleties now or in the future regarding associativity.
 func Merge(srcs []*Profile) (*Profile, error) {
 	if len(srcs) == 0 {
 		return nil, fmt.Errorf("no profiles to merge")
@@ -228,7 +231,6 @@
 	}
 
 	if l, ok := pm.locationsByID[src.ID]; ok {
-		pm.locationsByID[src.ID] = l
 		return l
 	}
 
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 d94d8b3..2590c8d 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/profile.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/profile.go
@@ -22,6 +22,7 @@
 	"fmt"
 	"io"
 	"io/ioutil"
+	"math"
 	"path/filepath"
 	"regexp"
 	"sort"
@@ -712,7 +713,8 @@
 	return s.HasLabel("pprof::base", "true")
 }
 
-// Scale multiplies all sample values in a profile by a constant.
+// Scale multiplies all sample values in a profile by a constant and keeps
+// only samples that have at least one non-zero value.
 func (p *Profile) Scale(ratio float64) {
 	if ratio == 1 {
 		return
@@ -724,7 +726,8 @@
 	p.ScaleN(ratios)
 }
 
-// ScaleN multiplies each sample values in a sample by a different amount.
+// ScaleN multiplies each sample values in a sample by a different amount
+// and keeps only samples that have at least one non-zero value.
 func (p *Profile) ScaleN(ratios []float64) error {
 	if len(p.SampleType) != len(ratios) {
 		return fmt.Errorf("mismatched scale ratios, got %d, want %d", len(ratios), len(p.SampleType))
@@ -739,13 +742,22 @@
 	if allOnes {
 		return nil
 	}
+	fillIdx := 0
 	for _, s := range p.Sample {
+		keepSample := false
 		for i, v := range s.Value {
 			if ratios[i] != 1 {
-				s.Value[i] = int64(float64(v) * ratios[i])
+				val := int64(math.Round(float64(v) * ratios[i]))
+				s.Value[i] = val
+				keepSample = keepSample || val != 0
 			}
 		}
+		if keepSample {
+			p.Sample[fillIdx] = s
+			fillIdx++
+		}
 	}
+	p.Sample = p.Sample[:fillIdx]
 	return nil
 }
 
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
index cf690e2..afeb9a3 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/inst.go
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/inst.go
@@ -538,10 +538,12 @@
 	Extend ExtShift
 	// Amount indicates the index shift amount (but also see ShiftMustBeZero field below).
 	Amount uint8
-	// ShiftMustBeZero is set to true when the shift amount must be 0, even if the
-	// Amount field is not 0. In GNU syntax, a #0 shift amount is printed if Amount
-	// is not 0 but ShiftMustBeZero is true; #0 is not printed if Amount is 0 and
-	// ShiftMustBeZero is true. Both cases represent shift by 0 bit.
+	// Refer to ARM reference manual, for byte load/store(register), the index
+	// shift amount must be 0, encoded in "S" as 0 if omitted, or as 1 if present.
+	// a.ShiftMustBeZero is set true indicates the index shift amount must be 0.
+	// In GNU syntax, a #0 shift amount is printed if Amount is 1 but ShiftMustBeZero
+	// is true; #0 is not printed if Amount is 0 and ShiftMustBeZero is true.
+	// Both cases represent shift by 0 bit.
 	ShiftMustBeZero bool
 }
 
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
index c9e4570..3aaf0b2 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/plan9x.go
+++ b/src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/plan9x.go
@@ -126,7 +126,7 @@
 			op = "VMOV"
 		}
 
-	case LDR:
+	case LDR, LDUR:
 		var rno uint16
 		if r, ok := inst.Args[0].(Reg); ok {
 			rno = uint16(r)
@@ -135,12 +135,21 @@
 		}
 		if rno <= uint16(WZR) {
 			op = "MOVWU" + suffix
+		} else if rno >= uint16(B0) && rno <= uint16(B31) {
+			op = "FMOVB" + suffix
+			args[0] = fmt.Sprintf("F%d", rno&31)
+		} else if rno >= uint16(H0) && rno <= uint16(H31) {
+			op = "FMOVH" + suffix
+			args[0] = fmt.Sprintf("F%d", rno&31)
 		} else if rno >= uint16(S0) && rno <= uint16(S31) {
 			op = "FMOVS" + suffix
 			args[0] = fmt.Sprintf("F%d", rno&31)
 		} else if rno >= uint16(D0) && rno <= uint16(D31) {
 			op = "FMOVD" + suffix
 			args[0] = fmt.Sprintf("F%d", rno&31)
+		} else if rno >= uint16(Q0) && rno <= uint16(Q31) {
+			op = "FMOVQ" + suffix
+			args[0] = fmt.Sprintf("F%d", rno&31)
 		} else {
 			op = "MOVD" + suffix
 		}
@@ -181,12 +190,21 @@
 		}
 		if rno <= uint16(WZR) {
 			op = "MOVW" + suffix
+		} else if rno >= uint16(B0) && rno <= uint16(B31) {
+			op = "FMOVB" + suffix
+			args[0] = fmt.Sprintf("F%d", rno&31)
+		} else if rno >= uint16(H0) && rno <= uint16(H31) {
+			op = "FMOVH" + suffix
+			args[0] = fmt.Sprintf("F%d", rno&31)
 		} else if rno >= uint16(S0) && rno <= uint16(S31) {
 			op = "FMOVS" + suffix
 			args[0] = fmt.Sprintf("F%d", rno&31)
 		} else if rno >= uint16(D0) && rno <= uint16(D31) {
 			op = "FMOVD" + suffix
 			args[0] = fmt.Sprintf("F%d", rno&31)
+		} else if rno >= uint16(Q0) && rno <= uint16(Q31) {
+			op = "FMOVQ" + suffix
+			args[0] = fmt.Sprintf("F%d", rno&31)
 		} else {
 			op = "MOVD" + suffix
 		}
@@ -251,18 +269,31 @@
 				op += "W"
 			}
 		}
-		fallthrough
+		args[0] = fmt.Sprintf("(%s, %s)", args[0], args[1])
+		args[1] = args[2]
+		return op + " " + args[1] + ", " + args[0]
 
 	case STP, LDP:
 		args[0] = fmt.Sprintf("(%s, %s)", args[0], args[1])
 		args[1] = args[2]
-		if op == "STP" {
-			op = op + suffix
+
+		rno, ok := inst.Args[0].(Reg)
+		if !ok {
+			rno = Reg(inst.Args[0].(RegSP))
+		}
+		if rno <= WZR {
+			op = op + "W"
+		} else if rno >= S0 && rno <= S31 {
+			op = "F" + op + "S"
+		} else if rno >= D0 && rno <= D31 {
+			op = "F" + op + "D"
+		} else if rno >= Q0 && rno <= Q31 {
+			op = "F" + op + "Q"
+		}
+		op = op + suffix
+		if inst.Op.String() == "STP" {
 			return op + " " + args[0] + ", " + args[1]
-		} else if op == "LDP" {
-			op = op + suffix
-			return op + " " + args[1] + ", " + args[0]
-		} else if op == "LDAXP" || op == "LDXP" || op == "LDAXPW" || op == "LDXPW" {
+		} else {
 			return op + " " + args[1] + ", " + args[0]
 		}
 
@@ -469,6 +500,12 @@
 SHA256SU1
 `)
 
+// floating point instrcutions without "F" prefix.
+var fOpsWithoutFPrefix = map[Op]bool{
+	LDP: true,
+	STP: true,
+}
+
 func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
 	switch a := arg.(type) {
 	case Imm:
@@ -494,20 +531,17 @@
 		regenum := uint16(a)
 		regno := uint16(a) & 31
 
-		if regenum >= uint16(B0) && regenum <= uint16(D31) {
-			if strings.HasPrefix(inst.Op.String(), "F") || strings.HasSuffix(inst.Op.String(), "CVTF") {
+		if regenum >= uint16(B0) && regenum <= uint16(Q31) {
+			if strings.HasPrefix(inst.Op.String(), "F") || strings.HasSuffix(inst.Op.String(), "CVTF") || fOpsWithoutFPrefix[inst.Op] {
 				// FP registers are the same ones as SIMD registers
 				// Print Fn for scalar variant to align with assembler (e.g., FCVT, SCVTF, UCVTF, etc.)
 				return fmt.Sprintf("F%d", regno)
 			} else {
+				// Print Vn to align with assembler (e.g., SHA256H)
 				return fmt.Sprintf("V%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"
 		}
@@ -595,14 +629,18 @@
 		}
 
 		if a.Extend == lsl {
+			// Refer to ARM reference manual, for byte load/store(register), the index
+			// shift amount must be 0, encoded in "S" as 0 if omitted, or as 1 if present.
 			// a.Amount indicates the index shift amount, encoded in "S" field.
-			// a.ShiftMustBeZero is set true when the index shift amount must be 0,
-			// even if the a.Amount field is not 0.
-			// When a.ShiftMustBeZero is ture, GNU syntax prints #0 shift amount if
-			// "S" equals to 1, or does not print #0 shift amount if "S" equals to 0.
-			// Go syntax should never print a zero index shift amount.
+			// a.ShiftMustBeZero is set true indicates the index shift amount must be 0.
+			// When a.ShiftMustBeZero is true, GNU syntax prints "[Xn, Xm lsl #0]" if "S"
+			// equals to 1, or prints "[Xn, Xm]" if "S" equals to 0.
 			if a.Amount != 0 && !a.ShiftMustBeZero {
 				index = fmt.Sprintf("(%s<<%d)", indexreg, a.Amount)
+			} else if a.ShiftMustBeZero && a.Amount == 1 {
+				// When a.ShiftMustBeZero is ture, Go syntax prints "(Rm<<0)" if "a.Amount"
+				// equals to 1.
+				index = fmt.Sprintf("(%s<<0)", indexreg)
 			} else {
 				index = fmt.Sprintf("(%s)", indexreg)
 			}
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go
index 5f04ff4..59bd325 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go
@@ -12,18 +12,25 @@
 
 const debugDecode = false
 
+const prefixOpcode = 1
+
 // instFormat is a decoding rule for one specific instruction form.
-// a uint32 instruction ins matches the rule if ins&Mask == Value
+// an instruction ins matches the rule if ins&Mask == Value
 // DontCare bits should be zero, but the machine might not reject
 // ones in those bits, they are mainly reserved for future expansion
 // of the instruction set.
 // The Args are stored in the same order as the instruction manual.
+//
+// Prefixed instructions are stored as:
+//   prefix << 32 | suffix,
+// Regular instructions are:
+//   inst << 32
 type instFormat struct {
 	Op       Op
-	Mask     uint32
-	Value    uint32
-	DontCare uint32
-	Args     [5]*argField
+	Mask     uint64
+	Value    uint64
+	DontCare uint64
+	Args     [6]*argField
 }
 
 // argField indicate how to decode an argument to an instruction.
@@ -36,7 +43,7 @@
 }
 
 // Parse parses the Arg out from the given binary instruction i.
-func (a argField) Parse(i uint32) Arg {
+func (a argField) Parse(i [2]uint32) Arg {
 	switch a.Type {
 	default:
 		return nil
@@ -54,6 +61,10 @@
 		return V0 + Reg(a.BitFields.Parse(i))
 	case TypeVecSReg:
 		return VS0 + Reg(a.BitFields.Parse(i))
+	case TypeVecSpReg:
+		return VS0 + Reg(a.BitFields.Parse(i))*2
+	case TypeMMAReg:
+		return A0 + Reg(a.BitFields.Parse(i))
 	case TypeSpReg:
 		return SpReg(a.BitFields.Parse(i))
 	case TypeImmSigned:
@@ -81,6 +92,8 @@
 	TypeFPReg                // floating point register
 	TypeVecReg               // vector register
 	TypeVecSReg              // VSX register
+	TypeVecSpReg             // VSX register pair (even only encoding)
+	TypeMMAReg               // MMA register
 	TypeSpReg                // special register (depends on Op)
 	TypeImmSigned            // signed immediate
 	TypeImmUnsigned          // unsigned immediate/flag/mask, this is the catch-all type
@@ -106,6 +119,10 @@
 		return "VecReg"
 	case TypeVecSReg:
 		return "VecSReg"
+	case TypeVecSpReg:
+		return "VecSpReg"
+	case TypeMMAReg:
+		return "MMAReg"
 	case TypeSpReg:
 		return "SpReg"
 	case TypeImmSigned:
@@ -146,9 +163,22 @@
 	if decoderCover == nil {
 		decoderCover = make([]bool, len(instFormats))
 	}
-	inst.Len = 4 // only 4-byte instructions are supported
-	ui := ord.Uint32(src[:inst.Len])
-	inst.Enc = ui
+	inst.Len = 4
+	ui_extn := [2]uint32{ord.Uint32(src[:inst.Len]), 0}
+	ui := uint64(ui_extn[0]) << 32
+	inst.Enc = ui_extn[0]
+	opcode := inst.Enc >> 26
+	if opcode == prefixOpcode {
+		// This is a prefixed instruction
+		inst.Len = 8
+		if len(src) < 8 {
+			return inst, errShort
+		}
+		// Merge the suffixed word.
+		ui_extn[1] = ord.Uint32(src[4:inst.Len])
+		ui |= uint64(ui_extn[1])
+		inst.SuffixEnc = ui_extn[1]
+	}
 	for i, iform := range instFormats {
 		if ui&iform.Mask != iform.Value {
 			continue
@@ -163,7 +193,7 @@
 			if argfield == nil {
 				break
 			}
-			inst.Args[i] = argfield.Parse(ui)
+			inst.Args[i] = argfield.Parse(ui_extn)
 		}
 		inst.Op = iform.Op
 		if debugDecode {
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/field.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/field.go
index 26a4fdf..882c91a 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/field.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/field.go
@@ -14,6 +14,10 @@
 type BitField struct {
 	Offs uint8 // the offset of the left-most bit.
 	Bits uint8 // length in bits.
+	// This instruction word holding this field.
+	// It is always 0 for ISA < 3.1 instructions. It is
+	// in decoding order. (0 == prefix, 1 == suffix on ISA 3.1)
+	Word uint8
 }
 
 func (b BitField) String() string {
@@ -28,16 +32,16 @@
 
 // Parse extracts the bitfield b from i, and return it as an unsigned integer.
 // Parse will panic if b is invalid.
-func (b BitField) Parse(i uint32) uint32 {
+func (b BitField) Parse(i [2]uint32) uint32 {
 	if b.Bits > 32 || b.Bits == 0 || b.Offs > 31 || b.Offs+b.Bits > 32 {
 		panic(fmt.Sprintf("invalid bitfiled %v", b))
 	}
-	return (i >> (32 - b.Offs - b.Bits)) & ((1 << b.Bits) - 1)
+	return (i[b.Word] >> (32 - b.Offs - b.Bits)) & ((1 << b.Bits) - 1)
 }
 
 // ParseSigned extracts the bitfield b from i, and return it as a signed integer.
 // ParseSigned will panic if b is invalid.
-func (b BitField) ParseSigned(i uint32) int32 {
+func (b BitField) ParseSigned(i [2]uint32) int32 {
 	u := int32(b.Parse(i))
 	return u << (32 - b.Bits) >> (32 - b.Bits)
 }
@@ -61,9 +65,9 @@
 // as an unsigned integer and the total length of all the bitfields.
 // parse will panic if any bitfield in b is invalid, but it doesn't check if
 // the sequence of bitfields is reasonable.
-func (bs BitFields) parse(i uint32) (u uint32, Bits uint8) {
+func (bs BitFields) parse(i [2]uint32) (u uint64, Bits uint8) {
 	for _, b := range bs {
-		u = (u << b.Bits) | b.Parse(i)
+		u = (uint64(u) << b.Bits) | uint64(b.Parse(i))
 		Bits += b.Bits
 	}
 	return u, Bits
@@ -71,14 +75,14 @@
 
 // Parse extracts the bitfields from i, concatenate them and return the result
 // as an unsigned integer. Parse will panic if any bitfield in b is invalid.
-func (bs BitFields) Parse(i uint32) uint32 {
+func (bs BitFields) Parse(i [2]uint32) uint64 {
 	u, _ := bs.parse(i)
 	return u
 }
 
 // Parse extracts the bitfields from i, concatenate them and return the result
 // as a signed integer. Parse will panic if any bitfield in b is invalid.
-func (bs BitFields) ParseSigned(i uint32) int32 {
+func (bs BitFields) ParseSigned(i [2]uint32) int64 {
 	u, l := bs.parse(i)
-	return int32(u) << (32 - l) >> (32 - l)
+	return int64(u) << (64 - l) >> (64 - l)
 }
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go
index 1849a29..225ef4f 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go
@@ -11,8 +11,10 @@
 )
 
 var (
-	condBit    = [4]string{"lt", "gt", "eq", "so"}
-	condBitNeg = [4]string{"ge", "le", "ne", "so"}
+	// bit 3 of index is a negated check.
+	condBit = [8]string{
+		"lt", "gt", "eq", "so",
+		"ge", "le", "ne", "ns"}
 )
 
 // GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
@@ -31,57 +33,146 @@
 	// Special handling for some ops
 	startArg := 0
 	sep := " "
-	switch inst.Op.String() {
-	case "bc":
-		bo := gnuArg(&inst, 0, inst.Args[0], PC)
-		bi := inst.Args[1]
-		switch bi := bi.(type) {
-		case CondReg:
-			if bi >= CR0 {
-				if bi == CR0 && bo == "16" {
-					buf.WriteString("bdnz")
-				}
-				buf.WriteString(fmt.Sprintf("bc cr%d", bi-CR0))
-			}
-			cr := bi / 4
-			switch bo {
-			case "4":
-				bit := condBitNeg[(bi-Cond0LT)%4]
-				if cr == 0 {
-					buf.WriteString(fmt.Sprintf("b%s", bit))
-				} else {
-					buf.WriteString(fmt.Sprintf("b%s cr%d,", bit, cr))
-					sep = ""
-				}
-			case "12":
-				bit := condBit[(bi-Cond0LT)%4]
-				if cr == 0 {
-					buf.WriteString(fmt.Sprintf("b%s", bit))
-				} else {
-					buf.WriteString(fmt.Sprintf("b%s cr%d,", bit, cr))
-					sep = ""
-				}
-			case "8":
-				bit := condBit[(bi-Cond0LT)%4]
-				sep = ""
-				if cr == 0 {
-					buf.WriteString(fmt.Sprintf("bdnzt %s,", bit))
-				} else {
-					buf.WriteString(fmt.Sprintf("bdnzt cr%d,%s,", cr, bit))
-				}
-			case "16":
-				if cr == 0 && bi == Cond0LT {
-					buf.WriteString("bdnz")
-				} else {
-					buf.WriteString(fmt.Sprintf("bdnz cr%d,", cr))
-					sep = ""
-				}
-			}
-			startArg = 2
-		default:
-			fmt.Printf("Unexpected bi: %d for bc with bo: %s\n", bi, bo)
+	opName := inst.Op.String()
+	argList := inst.Args[:]
+
+	switch opName {
+	case "bc", "bcl", "bca", "bcla", "bclr", "bclrl", "bcctr", "bcctrl", "bctar", "bctarl":
+		sfx := inst.Op.String()[2:]
+		bo := int(inst.Args[0].(Imm))
+		bi := inst.Args[1].(CondReg)
+		atsfx := [4]string{"", "?", "-", "+"}
+		decsfx := [2]string{"dnz", "dz"}
+
+		//BO field is... complicated (z == ignored bit, at == prediction hint)
+		//Paraphrased from ISA 3.1 Book I Section 2.4:
+		//
+		//0000z -> decrement ctr, b if ctr != 0 and CRbi == 0
+		//0001z -> decrement ctr, b if ctr == 0 and CRbi == 0
+		//001at -> b if CRbi == 0
+		//0100z -> decrement ctr, b if ctr != 0 and CRbi == 1
+		//0101z -> decrement ctr, b if ctr == 0 and CRbi == 1
+		//011at -> b if CRbi == 1
+		//1a00t -> decrement ctr, b if ctr != 0
+		//1a01t -> decrement ctr, b if ctr == 0
+		//1z1zz -> b always
+
+		// Decoding (in this order) we get
+		// BO & 0b00100 == 0b00000 -> dz if BO[1], else dnz (not simplified for bcctrl forms)
+		// BO & 0b10000 == 0b10000 -> (bc and bca forms not simplified), at = B[4]B[0] if B[2] != 0, done
+		// BO & 0b10000 == 0b00000 -> t if BO[3], else f
+		// BO & 0b10100 == 0b00100 -> at = B[0:1]
+
+		// BI fields rename as follows:
+		// less than            : lt BI%4==0 && test == t
+		// less than or equal   : le BI%4==1 && test == f
+		// equal 		: eq BI%4==2 && test == t
+		// greater than or equal: ge BI%4==0 && test == f
+		// greater than		: gt BI%4==1 && test == t
+		// not less than	: nl BI%4==0 && test == f
+		// not equal		: ne BI%4==2 && test == f
+		// not greater than	: ng BI%4==1 && test == f
+		// summary overflow	: so BI%4==3 && test == t
+		// not summary overflow : ns BI%4==3 && test == f
+		// unordered		: un BI%4==3 && test == t
+		// not unordered	: nu BI%4==3 && test == f
+		//
+		// Note, there are only 8 possible tests, but quite a few more
+		// ways to name fields.  For simplicity, we choose those in condBit.
+
+		at := 0   // 0 == no hint, 1 == reserved, 2 == not likely, 3 == likely
+		form := 1 // 1 == n/a,  0 == cr bit not set, 4 == cr bit set
+		cr := (bi - Cond0LT) / 4
+		bh := -1 // Only for lr/tar/ctr variants.
+		switch opName {
+		case "bclr", "bclrl", "bcctr", "bcctrl", "bctar", "bctarl":
+			bh = int(inst.Args[2].(Imm))
 		}
-		startArg = 2
+
+		if bo&0x14 == 0x14 {
+			if bo == 0x14 && bi == Cond0LT { // preferred form of unconditional branch
+				// Likewise, avoid printing fake b/ba/bl/bla
+				if opName != "bc" && opName != "bca" && opName != "bcl" && opName != "bcla" {
+					startArg = 2
+				}
+			}
+		} else if bo&0x04 == 0 { // ctr is decremented
+			if opName != "bcctr" && opName != "bcctrl" {
+				startArg = 1
+				tf := ""
+				if bo&0x10 == 0x00 {
+					tf = "f"
+					if bo&0x08 == 0x08 {
+						tf = "t"
+					}
+				}
+				sfx = decsfx[(bo>>1)&1] + tf + sfx
+			}
+			if bo&0x10 == 0x10 {
+				if opName != "bcctr" && opName != "bcctrl" {
+					startArg = 2
+				}
+				if bi != Cond0LT {
+					// A non-zero BI bit was encoded, but ignored by BO
+					startArg = 0
+				}
+				at = ((bo & 0x8) >> 2) | (bo & 0x1)
+			} else if bo&0x4 == 0x4 {
+				at = bo & 0x3
+			}
+		} else if bo&0x10 == 0x10 { // BI field is not used
+			if opName != "bca" && opName != "bc" {
+				at = ((bo & 0x8) >> 2) | (bo & 0x1)
+				startArg = 2
+			}
+			// If BI is encoded as a bit other than 0, no mnemonic.
+			if bo&0x14 == 0x14 {
+				startArg = 0
+			}
+		} else {
+			form = (bo & 0x8) >> 1
+			startArg = 2
+			if bo&0x14 == 0x04 {
+				at = bo & 0x3
+			}
+		}
+		sfx += atsfx[at]
+
+		if form != 1 {
+			bit := int((bi-Cond0LT)%4) | (^form)&0x4
+			sfx = condBit[bit] + sfx
+		}
+
+		if at != 1 && startArg > 0 && bh <= 0 {
+			str := fmt.Sprintf("b%s", sfx)
+			if startArg > 1 && (cr != 0 || bh > 0) {
+				str += fmt.Sprintf(" cr%d", cr)
+				sep = ","
+			}
+			buf.WriteString(str)
+			if startArg < 2 && bh == 0 {
+				str := fmt.Sprintf(" %s",
+					gnuArg(&inst, 1, inst.Args[1], PC))
+				buf.WriteString(str)
+				startArg = 3
+			} else if bh == 0 {
+				startArg = 3
+			}
+		} else {
+			if startArg == 0 || bh > 0 || at == 1 {
+				buf.WriteString(inst.Op.String())
+				buf.WriteString(atsfx[at])
+				startArg = 0
+			} else {
+				buf.WriteString("b" + sfx)
+			}
+			if bh == 0 {
+				str := fmt.Sprintf(" %d,%s", bo, gnuArg(&inst, 1, inst.Args[1], PC))
+				buf.WriteString(str)
+				startArg = 3
+			}
+		}
+
 	case "mtspr":
 		opcode := inst.Op.String()
 		buf.WriteString(opcode[0:2])
@@ -134,23 +225,111 @@
 			buf.WriteString("spr")
 		}
 
-	case "sync":
-		switch arg := inst.Args[0].(type) {
-		case Imm:
-			switch arg {
-			case 0:
-				buf.WriteString("hwsync")
-			case 1:
-				buf.WriteString("lwsync")
-			case 2:
-				buf.WriteString("ptesync")
-			}
+	case "mtfsfi", "mtfsfi.":
+		buf.WriteString(opName)
+		l := inst.Args[2].(Imm)
+		if l == 0 {
+			// L == 0 is an extended mnemonic for the same.
+			asm := fmt.Sprintf(" %s,%s",
+				gnuArg(&inst, 0, inst.Args[0], PC),
+				gnuArg(&inst, 1, inst.Args[1], PC))
+			buf.WriteString(asm)
+			startArg = 3
 		}
-		startArg = 2
-	default:
+
+	case "paste.":
+		buf.WriteString(opName)
+		l := inst.Args[2].(Imm)
+		if l == 1 {
+			// L == 1 is an extended mnemonic for the same.
+			asm := fmt.Sprintf(" %s,%s",
+				gnuArg(&inst, 0, inst.Args[0], PC),
+				gnuArg(&inst, 1, inst.Args[1], PC))
+			buf.WriteString(asm)
+			startArg = 3
+		}
+
+	case "mtfsf", "mtfsf.":
+		buf.WriteString(opName)
+		l := inst.Args[3].(Imm)
+		if l == 0 {
+			// L == 0 is an extended mnemonic for the same.
+			asm := fmt.Sprintf(" %s,%s,%s",
+				gnuArg(&inst, 0, inst.Args[0], PC),
+				gnuArg(&inst, 1, inst.Args[1], PC),
+				gnuArg(&inst, 2, inst.Args[2], PC))
+			buf.WriteString(asm)
+			startArg = 4
+		}
+
+	case "sync":
+		lsc := inst.Args[0].(Imm)<<4 | inst.Args[1].(Imm)
+		switch lsc {
+		case 0x00:
+			buf.WriteString("hwsync")
+			startArg = 2
+		case 0x10:
+			buf.WriteString("lwsync")
+			startArg = 2
+		default:
+			buf.WriteString(opName)
+		}
+
+	case "lbarx", "lharx", "lwarx", "ldarx":
+		// If EH == 0, omit printing EH.
+		eh := inst.Args[3].(Imm)
+		if eh == 0 {
+			argList = inst.Args[:3]
+		}
 		buf.WriteString(inst.Op.String())
+
+	case "paddi":
+		// There are several extended mnemonics.  Notably, "pla" is
+		// the only valid mnemonic for paddi (R=1), In this case, RA must
+		// always be 0.  Otherwise it is invalid.
+		r := inst.Args[3].(Imm)
+		ra := inst.Args[1].(Reg)
+		str := opName
+		if ra == R0 {
+			name := []string{"pli", "pla"}
+			str = fmt.Sprintf("%s %s,%s",
+				name[r&1],
+				gnuArg(&inst, 0, inst.Args[0], PC),
+				gnuArg(&inst, 2, inst.Args[2], PC))
+			startArg = 4
+		} else if r == 0 {
+			str = fmt.Sprintf("%s %s,%s,%s", opName,
+				gnuArg(&inst, 0, inst.Args[0], PC),
+				gnuArg(&inst, 1, inst.Args[1], PC),
+				gnuArg(&inst, 2, inst.Args[2], PC))
+			startArg = 4
+		}
+		buf.WriteString(str)
+
+	default:
+		// Prefixed load/stores do not print the displacement register when R==1 (they are PCrel).
+		// This also implies RA should be 0.  Likewise, when R==0, printing of R can be omitted.
+		if strings.HasPrefix(opName, "pl") || strings.HasPrefix(opName, "pst") {
+			r := inst.Args[3].(Imm)
+			ra := inst.Args[2].(Reg)
+			d := inst.Args[1].(Offset)
+			if r == 1 && ra == R0 {
+				str := fmt.Sprintf("%s %s,%d", opName, gnuArg(&inst, 0, inst.Args[0], PC), d)
+				buf.WriteString(str)
+				startArg = 4
+			} else if r == 0 {
+				str := fmt.Sprintf("%s %s,%d(%s)", opName,
+					gnuArg(&inst, 0, inst.Args[0], PC),
+					d,
+					gnuArg(&inst, 2, inst.Args[2], PC))
+				buf.WriteString(str)
+				startArg = 4
+			}
+		} else {
+			buf.WriteString(opName)
+		}
 	}
-	for i, arg := range inst.Args[:] {
+	for i, arg := range argList {
 		if arg == nil {
 			break
 		}
@@ -198,7 +377,7 @@
 		if arg <= Cond0SO {
 			return bit
 		}
-		return fmt.Sprintf("%s cr%d", bit, int(arg-Cond0LT)/4)
+		return fmt.Sprintf("4*cr%d+%s", int(arg-Cond0LT)/4, bit)
 	case Imm:
 		return fmt.Sprintf("%d", arg)
 	case SpReg:
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/inst.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/inst.go
index 870522a..41e0451 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/inst.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/inst.go
@@ -10,10 +10,11 @@
 )
 
 type Inst struct {
-	Op   Op     // Opcode mnemonic
-	Enc  uint32 // Raw encoding bits
-	Len  int    // Length of encoding in bytes.
-	Args Args   // Instruction arguments, in Power ISA manual order.
+	Op        Op     // Opcode mnemonic
+	Enc       uint32 // Raw encoding bits (if Len == 8, this is the prefix word)
+	Len       int    // Length of encoding in bytes.
+	SuffixEnc uint32 // Raw encoding bits of second word (if Len == 8)
+	Args      Args   // Instruction arguments, in Power ISA manual order.
 }
 
 func (i Inst) String() string {
@@ -50,9 +51,9 @@
 }
 
 // An Args holds the instruction arguments.
-// If an instruction has fewer than 4 arguments,
+// If an instruction has fewer than 6 arguments,
 // the final elements in the array are nil.
-type Args [5]Arg
+type Args [6]Arg
 
 // A Reg is a single register. The zero value means R0, not the absence of a register.
 // It also includes special registers.
@@ -220,6 +221,14 @@
 	VS61
 	VS62
 	VS63
+	A0 // MMA registers.  These are effectively shadow registers of four adjacent VSR's [An*4,An*4+3]
+	A1
+	A2
+	A3
+	A4
+	A5
+	A6
+	A7
 )
 
 func (Reg) IsArg() {}
@@ -233,6 +242,8 @@
 		return fmt.Sprintf("v%d", int(r-V0))
 	case VS0 <= r && r <= VS63:
 		return fmt.Sprintf("vs%d", int(r-VS0))
+	case A0 <= r && r <= A7:
+		return fmt.Sprintf("a%d", int(r-A0))
 	default:
 		return fmt.Sprintf("Reg(%d)", int(r))
 	}
@@ -328,7 +339,7 @@
 }
 
 // Imm represents an immediate number.
-type Imm int32
+type Imm int64
 
 func (Imm) IsArg() {}
 func (i Imm) String() string {
@@ -336,7 +347,7 @@
 }
 
 // Offset represents a memory offset immediate.
-type Offset int32
+type Offset int64
 
 func (Offset) IsArg() {}
 func (o Offset) String() string {
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go
index 48a4e97..89b9173 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go
@@ -76,6 +76,9 @@
 		}
 		args = append(args, args[0])
 		return op + " " + strings.Join(args[1:], ",")
+	case PASTECC:
+		// paste. has two input registers, and an L field, unlike other 3 operand instructions.
+		return op + " " + args[0] + "," + args[1] + "," + args[2]
 	case SYNC:
 		if args[0] == "$1" {
 			return "LWSYNC"
@@ -136,7 +139,7 @@
 	case LXVL, LXVLL:
 		return op + " " + args[1] + "," + args[2] + "," + args[0]
 
-	case DCBT, DCBTST, DCBZ, DCBST, DCBI, ICBI:
+	case DCBT, DCBTST, DCBZ, DCBST, ICBI:
 		if args[0] == "0" || args[0] == "R0" {
 			return op + " (" + args[1] + ")"
 		}
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go
index 76f9635..d42ab0f 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go
@@ -1,183 +1,585 @@
 // DO NOT EDIT
-// generated by: ppc64map -fmt=decoder pp64.csv
+// generated by: ppc64map -fmt=decoder ../pp64.csv
 
 package ppc64asm
 
 const (
 	_ Op = iota
-	CNTLZW
-	CNTLZWCC
-	B
-	BA
-	BL
-	BLA
-	BC
-	BCA
-	BCL
-	BCLA
-	BCLR
-	BCLRL
-	BCCTR
-	BCCTRL
+	BRD
+	BRH
+	BRW
+	CFUGED
+	CNTLZDM
+	CNTTZDM
+	DCFFIXQQ
+	DCTFIXQQ
+	LXVKQ
+	LXVP
+	LXVPX
+	LXVRBX
+	LXVRDX
+	LXVRHX
+	LXVRWX
+	MTVSRBM
+	MTVSRBMI
+	MTVSRDM
+	MTVSRHM
+	MTVSRQM
+	MTVSRWM
+	PADDI
+	PDEPD
+	PEXTD
+	PLBZ
+	PLD
+	PLFD
+	PLFS
+	PLHA
+	PLHZ
+	PLQ
+	PLWA
+	PLWZ
+	PLXSD
+	PLXSSP
+	PLXV
+	PLXVP
+	PMXVBF16GER2
+	PMXVBF16GER2NN
+	PMXVBF16GER2NP
+	PMXVBF16GER2PN
+	PMXVBF16GER2PP
+	PMXVF16GER2
+	PMXVF16GER2NN
+	PMXVF16GER2NP
+	PMXVF16GER2PN
+	PMXVF16GER2PP
+	PMXVF32GER
+	PMXVF32GERNN
+	PMXVF32GERNP
+	PMXVF32GERPN
+	PMXVF32GERPP
+	PMXVF64GER
+	PMXVF64GERNN
+	PMXVF64GERNP
+	PMXVF64GERPN
+	PMXVF64GERPP
+	PMXVI16GER2
+	PMXVI16GER2PP
+	PMXVI16GER2S
+	PMXVI16GER2SPP
+	PMXVI4GER8
+	PMXVI4GER8PP
+	PMXVI8GER4
+	PMXVI8GER4PP
+	PMXVI8GER4SPP
+	PNOP
+	PSTB
+	PSTD
+	PSTFD
+	PSTFS
+	PSTH
+	PSTQ
+	PSTW
+	PSTXSD
+	PSTXSSP
+	PSTXV
+	PSTXVP
+	SETBC
+	SETBCR
+	SETNBC
+	SETNBCR
+	STXVP
+	STXVPX
+	STXVRBX
+	STXVRDX
+	STXVRHX
+	STXVRWX
+	VCFUGED
+	VCLRLB
+	VCLRRB
+	VCLZDM
+	VCMPEQUQ
+	VCMPEQUQCC
+	VCMPGTSQ
+	VCMPGTSQCC
+	VCMPGTUQ
+	VCMPGTUQCC
+	VCMPSQ
+	VCMPUQ
+	VCNTMBB
+	VCNTMBD
+	VCNTMBH
+	VCNTMBW
+	VCTZDM
+	VDIVESD
+	VDIVESQ
+	VDIVESW
+	VDIVEUD
+	VDIVEUQ
+	VDIVEUW
+	VDIVSD
+	VDIVSQ
+	VDIVSW
+	VDIVUD
+	VDIVUQ
+	VDIVUW
+	VEXPANDBM
+	VEXPANDDM
+	VEXPANDHM
+	VEXPANDQM
+	VEXPANDWM
+	VEXTDDVLX
+	VEXTDDVRX
+	VEXTDUBVLX
+	VEXTDUBVRX
+	VEXTDUHVLX
+	VEXTDUHVRX
+	VEXTDUWVLX
+	VEXTDUWVRX
+	VEXTRACTBM
+	VEXTRACTDM
+	VEXTRACTHM
+	VEXTRACTQM
+	VEXTRACTWM
+	VEXTSD2Q
+	VGNB
+	VINSBLX
+	VINSBRX
+	VINSBVLX
+	VINSBVRX
+	VINSD
+	VINSDLX
+	VINSDRX
+	VINSHLX
+	VINSHRX
+	VINSHVLX
+	VINSHVRX
+	VINSW
+	VINSWLX
+	VINSWRX
+	VINSWVLX
+	VINSWVRX
+	VMODSD
+	VMODSQ
+	VMODSW
+	VMODUD
+	VMODUQ
+	VMODUW
+	VMSUMCUD
+	VMULESD
+	VMULEUD
+	VMULHSD
+	VMULHSW
+	VMULHUD
+	VMULHUW
+	VMULLD
+	VMULOSD
+	VMULOUD
+	VPDEPD
+	VPEXTD
+	VRLQ
+	VRLQMI
+	VRLQNM
+	VSLDBI
+	VSLQ
+	VSRAQ
+	VSRDBI
+	VSRQ
+	VSTRIBL
+	VSTRIBLCC
+	VSTRIBR
+	VSTRIBRCC
+	VSTRIHL
+	VSTRIHLCC
+	VSTRIHR
+	VSTRIHRCC
+	XSCMPEQQP
+	XSCMPGEQP
+	XSCMPGTQP
+	XSCVQPSQZ
+	XSCVQPUQZ
+	XSCVSQQP
+	XSCVUQQP
+	XSMAXCQP
+	XSMINCQP
+	XVBF16GER2
+	XVBF16GER2NN
+	XVBF16GER2NP
+	XVBF16GER2PN
+	XVBF16GER2PP
+	XVCVBF16SPN
+	XVCVSPBF16
+	XVF16GER2
+	XVF16GER2NN
+	XVF16GER2NP
+	XVF16GER2PN
+	XVF16GER2PP
+	XVF32GER
+	XVF32GERNN
+	XVF32GERNP
+	XVF32GERPN
+	XVF32GERPP
+	XVF64GER
+	XVF64GERNN
+	XVF64GERNP
+	XVF64GERPN
+	XVF64GERPP
+	XVI16GER2
+	XVI16GER2PP
+	XVI16GER2S
+	XVI16GER2SPP
+	XVI4GER8
+	XVI4GER8PP
+	XVI8GER4
+	XVI8GER4PP
+	XVI8GER4SPP
+	XVTLSBB
+	XXBLENDVB
+	XXBLENDVD
+	XXBLENDVH
+	XXBLENDVW
+	XXEVAL
+	XXGENPCVBM
+	XXGENPCVDM
+	XXGENPCVHM
+	XXGENPCVWM
+	XXMFACC
+	XXMTACC
+	XXPERMX
+	XXSETACCZ
+	XXSPLTI32DX
+	XXSPLTIDP
+	XXSPLTIW
+	MSGCLRU
+	MSGSNDU
+	URFID
+	ADDEX
+	MFFSCDRN
+	MFFSCDRNI
+	MFFSCE
+	MFFSCRN
+	MFFSCRNI
+	MFFSL
+	SLBIAG
+	VMSUMUDM
+	ADDPCIS
+	BCDCFNCC
+	BCDCFSQCC
+	BCDCFZCC
+	BCDCPSGNCC
+	BCDCTNCC
+	BCDCTSQCC
+	BCDCTZCC
+	BCDSCC
+	BCDSETSGNCC
+	BCDSRCC
+	BCDTRUNCCC
+	BCDUSCC
+	BCDUTRUNCCC
+	CMPEQB
+	CMPRB
+	CNTTZD
+	CNTTZDCC
+	CNTTZW
+	CNTTZWCC
+	COPY
+	CPABORT
+	DARN
+	DTSTSFI
+	DTSTSFIQ
+	EXTSWSLI
+	EXTSWSLICC
+	LDAT
+	LWAT
+	LXSD
+	LXSIBZX
+	LXSIHZX
+	LXSSP
+	LXV
+	LXVB16X
+	LXVH8X
+	LXVL
+	LXVLL
+	LXVWSX
+	LXVX
+	MADDHD
+	MADDHDU
+	MADDLD
+	MCRXRX
+	MFVSRLD
+	MODSD
+	MODSW
+	MODUD
+	MODUW
+	MSGSYNC
+	MTVSRDD
+	MTVSRWS
+	PASTECC
+	SETB
+	SLBIEG
+	SLBSYNC
+	STDAT
+	STOP
+	STWAT
+	STXSD
+	STXSIBX
+	STXSIHX
+	STXSSP
+	STXV
+	STXVB16X
+	STXVH8X
+	STXVL
+	STXVLL
+	STXVX
+	VABSDUB
+	VABSDUH
+	VABSDUW
+	VBPERMD
+	VCLZLSBB
+	VCMPNEB
+	VCMPNEBCC
+	VCMPNEH
+	VCMPNEHCC
+	VCMPNEW
+	VCMPNEWCC
+	VCMPNEZB
+	VCMPNEZBCC
+	VCMPNEZH
+	VCMPNEZHCC
+	VCMPNEZW
+	VCMPNEZWCC
+	VCTZB
+	VCTZD
+	VCTZH
+	VCTZLSBB
+	VCTZW
+	VEXTRACTD
+	VEXTRACTUB
+	VEXTRACTUH
+	VEXTRACTUW
+	VEXTSB2D
+	VEXTSB2W
+	VEXTSH2D
+	VEXTSH2W
+	VEXTSW2D
+	VEXTUBLX
+	VEXTUBRX
+	VEXTUHLX
+	VEXTUHRX
+	VEXTUWLX
+	VEXTUWRX
+	VINSERTB
+	VINSERTD
+	VINSERTH
+	VINSERTW
+	VMUL10CUQ
+	VMUL10ECUQ
+	VMUL10EUQ
+	VMUL10UQ
+	VNEGD
+	VNEGW
+	VPERMR
+	VPRTYBD
+	VPRTYBQ
+	VPRTYBW
+	VRLDMI
+	VRLDNM
+	VRLWMI
+	VRLWNM
+	VSLV
+	VSRV
+	WAIT
+	XSABSQP
+	XSADDQP
+	XSADDQPO
+	XSCMPEQDP
+	XSCMPEXPDP
+	XSCMPEXPQP
+	XSCMPGEDP
+	XSCMPGTDP
+	XSCMPOQP
+	XSCMPUQP
+	XSCPSGNQP
+	XSCVDPHP
+	XSCVDPQP
+	XSCVHPDP
+	XSCVQPDP
+	XSCVQPDPO
+	XSCVQPSDZ
+	XSCVQPSWZ
+	XSCVQPUDZ
+	XSCVQPUWZ
+	XSCVSDQP
+	XSCVUDQP
+	XSDIVQP
+	XSDIVQPO
+	XSIEXPDP
+	XSIEXPQP
+	XSMADDQP
+	XSMADDQPO
+	XSMAXCDP
+	XSMAXJDP
+	XSMINCDP
+	XSMINJDP
+	XSMSUBQP
+	XSMSUBQPO
+	XSMULQP
+	XSMULQPO
+	XSNABSQP
+	XSNEGQP
+	XSNMADDQP
+	XSNMADDQPO
+	XSNMSUBQP
+	XSNMSUBQPO
+	XSRQPI
+	XSRQPIX
+	XSRQPXP
+	XSSQRTQP
+	XSSQRTQPO
+	XSSUBQP
+	XSSUBQPO
+	XSTSTDCDP
+	XSTSTDCQP
+	XSTSTDCSP
+	XSXEXPDP
+	XSXEXPQP
+	XSXSIGDP
+	XSXSIGQP
+	XVCVHPSP
+	XVCVSPHP
+	XVIEXPDP
+	XVIEXPSP
+	XVTSTDCDP
+	XVTSTDCSP
+	XVXEXPDP
+	XVXEXPSP
+	XVXSIGDP
+	XVXSIGSP
+	XXBRD
+	XXBRH
+	XXBRQ
+	XXBRW
+	XXEXTRACTUW
+	XXINSERTW
+	XXPERM
+	XXPERMR
+	XXSPLTIB
+	BCDADDCC
+	BCDSUBCC
 	BCTAR
 	BCTARL
-	CRAND
-	CROR
-	CRNAND
-	CRXOR
-	CRNOR
-	CRANDC
-	MCRF
-	CREQV
-	CRORC
-	SC
 	CLRBHRB
+	FMRGEW
+	FMRGOW
+	ICBT
+	LQARX
+	LXSIWAX
+	LXSIWZX
+	LXSSPX
 	MFBHRBE
-	LBZ
-	LBZU
-	LBZX
-	LBZUX
-	LHZ
-	LHZU
-	LHZX
-	LHZUX
-	LHA
-	LHAU
-	LHAX
-	LHAUX
-	LWZ
-	LWZU
-	LWZX
-	LWZUX
-	LWA
-	LWAX
-	LWAUX
-	LD
-	LDU
-	LDX
-	LDUX
-	STB
-	STBU
-	STBX
-	STBUX
-	STH
-	STHU
-	STHX
-	STHUX
-	STW
-	STWU
-	STWX
-	STWUX
-	STD
-	STDU
-	STDX
-	STDUX
-	LQ
-	STQ
-	LHBRX
-	LWBRX
-	STHBRX
-	STWBRX
-	LDBRX
-	STDBRX
-	LMW
-	STMW
-	LSWI
-	LSWX
-	STSWI
-	STSWX
-	LI
-	ADDI
-	LIS
-	ADDIS
-	ADD
-	ADDCC
-	ADDO
-	ADDOCC
-	ADDIC
-	SUBF
-	SUBFCC
-	SUBFO
-	SUBFOCC
-	ADDICCC
-	SUBFIC
-	ADDC
-	ADDCCC
-	ADDCO
-	ADDCOCC
-	SUBFC
-	SUBFCCC
-	SUBFCO
-	SUBFCOCC
-	ADDE
-	ADDECC
-	ADDEO
-	ADDEOCC
-	ADDME
-	ADDMECC
-	ADDMEO
-	ADDMEOCC
-	SUBFE
-	SUBFECC
-	SUBFEO
-	SUBFEOCC
-	SUBFME
-	SUBFMECC
-	SUBFMEO
-	SUBFMEOCC
-	ADDZE
-	ADDZECC
-	ADDZEO
-	ADDZEOCC
-	SUBFZE
-	SUBFZECC
-	SUBFZEO
-	SUBFZEOCC
-	NEG
-	NEGCC
-	NEGO
-	NEGOCC
-	MULLI
-	MULLW
-	MULLWCC
-	MULLWO
-	MULLWOCC
-	MULHW
-	MULHWCC
-	MULHWU
-	MULHWUCC
-	DIVW
-	DIVWCC
-	DIVWO
-	DIVWOCC
-	DIVWU
-	DIVWUCC
-	DIVWUO
-	DIVWUOCC
-	DIVWE
-	DIVWECC
-	DIVWEO
-	DIVWEOCC
-	DIVWEU
-	DIVWEUCC
-	DIVWEUO
-	DIVWEUOCC
-	MULLD
-	MULLDCC
-	MULLDO
-	MULLDOCC
-	MULHDU
-	MULHDUCC
-	MULHD
-	MULHDCC
-	DIVD
-	DIVDCC
-	DIVDO
-	DIVDOCC
-	DIVDU
-	DIVDUCC
-	DIVDUO
-	DIVDUOCC
+	MFVSRD
+	MFVSRWZ
+	MSGCLR
+	MSGCLRP
+	MSGSND
+	MSGSNDP
+	MTVSRD
+	MTVSRWA
+	MTVSRWZ
+	RFEBB
+	STQCXCC
+	STXSIWX
+	STXSSPX
+	VADDCUQ
+	VADDECUQ
+	VADDEUQM
+	VADDUDM
+	VADDUQM
+	VBPERMQ
+	VCIPHER
+	VCIPHERLAST
+	VCLZB
+	VCLZD
+	VCLZH
+	VCLZW
+	VCMPEQUD
+	VCMPEQUDCC
+	VCMPGTSD
+	VCMPGTSDCC
+	VCMPGTUD
+	VCMPGTUDCC
+	VEQV
+	VGBBD
+	VMAXSD
+	VMAXUD
+	VMINSD
+	VMINUD
+	VMRGEW
+	VMRGOW
+	VMULESW
+	VMULEUW
+	VMULOSW
+	VMULOUW
+	VMULUWM
+	VNAND
+	VNCIPHER
+	VNCIPHERLAST
+	VORC
+	VPERMXOR
+	VPKSDSS
+	VPKSDUS
+	VPKUDUM
+	VPKUDUS
+	VPMSUMB
+	VPMSUMD
+	VPMSUMH
+	VPMSUMW
+	VPOPCNTB
+	VPOPCNTD
+	VPOPCNTH
+	VPOPCNTW
+	VRLD
+	VSBOX
+	VSHASIGMAD
+	VSHASIGMAW
+	VSLD
+	VSRAD
+	VSRD
+	VSUBCUQ
+	VSUBECUQ
+	VSUBEUQM
+	VSUBUDM
+	VSUBUQM
+	VUPKHSW
+	VUPKLSW
+	XSADDSP
+	XSCVDPSPN
+	XSCVSPDPN
+	XSCVSXDSP
+	XSCVUXDSP
+	XSDIVSP
+	XSMADDASP
+	XSMADDMSP
+	XSMSUBASP
+	XSMSUBMSP
+	XSMULSP
+	XSNMADDASP
+	XSNMADDMSP
+	XSNMSUBASP
+	XSNMSUBMSP
+	XSRESP
+	XSRSP
+	XSRSQRTESP
+	XSSQRTSP
+	XSSUBSP
+	XXLEQV
+	XXLNAND
+	XXLORC
+	ADDG6S
+	BPERMD
+	CBCDTD
+	CDTBCD
+	DCFFIX
+	DCFFIXCC
 	DIVDE
 	DIVDECC
 	DIVDEO
@@ -186,612 +588,82 @@
 	DIVDEUCC
 	DIVDEUO
 	DIVDEUOCC
-	MODSD
-	MODUD
-	MODSW
-	MODUW
-	CMPWI
-	CMPDI
-	CMPW
-	CMPD
-	CMPLWI
-	CMPLDI
-	CMPLW
-	CMPLD
-	TWI
-	TW
-	TDI
-	ISEL
-	TD
-	ANDICC
-	ANDISCC
-	ORI
-	ORIS
-	XORI
-	XORIS
-	AND
-	ANDCC
-	XOR
-	XORCC
-	NAND
-	NANDCC
-	OR
-	ORCC
-	NOR
-	NORCC
-	ANDC
-	ANDCCC
-	EXTSB
-	EXTSBCC
-	EQV
-	EQVCC
-	ORC
-	ORCCC
-	EXTSH
-	EXTSHCC
-	CMPB
-	POPCNTB
-	POPCNTW
-	PRTYD
-	PRTYW
-	EXTSW
-	EXTSWCC
-	CNTLZD
-	CNTLZDCC
-	POPCNTD
-	BPERMD
-	RLWINM
-	RLWINMCC
-	RLWNM
-	RLWNMCC
-	RLWIMI
-	RLWIMICC
-	RLDICL
-	RLDICLCC
-	RLDICR
-	RLDICRCC
-	RLDIC
-	RLDICCC
-	RLDCL
-	RLDCLCC
-	RLDCR
-	RLDCRCC
-	RLDIMI
-	RLDIMICC
-	SLW
-	SLWCC
-	SRW
-	SRWCC
-	SRAWI
-	SRAWICC
-	SRAW
-	SRAWCC
-	SLD
-	SLDCC
-	SRD
-	SRDCC
-	SRADI
-	SRADICC
-	SRAD
-	SRADCC
-	CDTBCD
-	CBCDTD
-	ADDG6S
-	MTSPR
-	MFSPR
-	MTCRF
-	MFCR
-	MTSLE
-	MFVSRD
-	MFVSRWZ
-	MTVSRD
-	MTVSRWA
-	MTVSRWZ
-	MTOCRF
-	MFOCRF
-	MCRXR
-	MTDCRUX
-	MFDCRUX
-	LFS
-	LFSU
-	LFSX
-	LFSUX
-	LFD
-	LFDU
-	LFDX
-	LFDUX
-	LFIWAX
-	LFIWZX
-	STFS
-	STFSU
-	STFSX
-	STFSUX
-	STFD
-	STFDU
-	STFDX
-	STFDUX
-	STFIWX
-	LFDP
-	LFDPX
-	STFDP
-	STFDPX
-	FMR
-	FMRCC
-	FABS
-	FABSCC
-	FNABS
-	FNABSCC
-	FNEG
-	FNEGCC
-	FCPSGN
-	FCPSGNCC
-	FMRGEW
-	FMRGOW
-	FADD
-	FADDCC
-	FADDS
-	FADDSCC
-	FSUB
-	FSUBCC
-	FSUBS
-	FSUBSCC
-	FMUL
-	FMULCC
-	FMULS
-	FMULSCC
-	FDIV
-	FDIVCC
-	FDIVS
-	FDIVSCC
-	FSQRT
-	FSQRTCC
-	FSQRTS
-	FSQRTSCC
-	FRE
-	FRECC
-	FRES
-	FRESCC
-	FRSQRTE
-	FRSQRTECC
-	FRSQRTES
-	FRSQRTESCC
-	FTDIV
-	FTSQRT
-	FMADD
-	FMADDCC
-	FMADDS
-	FMADDSCC
-	FMSUB
-	FMSUBCC
-	FMSUBS
-	FMSUBSCC
-	FNMADD
-	FNMADDCC
-	FNMADDS
-	FNMADDSCC
-	FNMSUB
-	FNMSUBCC
-	FNMSUBS
-	FNMSUBSCC
-	FRSP
-	FRSPCC
-	FCTID
-	FCTIDCC
-	FCTIDZ
-	FCTIDZCC
+	DIVWE
+	DIVWECC
+	DIVWEO
+	DIVWEOCC
+	DIVWEU
+	DIVWEUCC
+	DIVWEUO
+	DIVWEUOCC
+	FCFIDS
+	FCFIDSCC
+	FCFIDU
+	FCFIDUCC
+	FCFIDUS
+	FCFIDUSCC
 	FCTIDU
 	FCTIDUCC
 	FCTIDUZ
 	FCTIDUZCC
-	FCTIW
-	FCTIWCC
-	FCTIWZ
-	FCTIWZCC
 	FCTIWU
 	FCTIWUCC
 	FCTIWUZ
 	FCTIWUZCC
-	FCFID
-	FCFIDCC
-	FCFIDU
-	FCFIDUCC
-	FCFIDS
-	FCFIDSCC
-	FCFIDUS
-	FCFIDUSCC
-	FRIN
-	FRINCC
-	FRIZ
-	FRIZCC
-	FRIP
-	FRIPCC
-	FRIM
-	FRIMCC
-	FCMPU
-	FCMPO
-	FSEL
-	FSELCC
-	MFFS
-	MFFSCC
-	MCRFS
-	MTFSFI
-	MTFSFICC
-	MTFSF
-	MTFSFCC
-	MTFSB0
-	MTFSB0CC
-	MTFSB1
-	MTFSB1CC
-	LVEBX
-	LVEHX
-	LVEWX
-	LVX
-	LVXL
-	STVEBX
-	STVEHX
-	STVEWX
-	STVX
-	STVXL
-	LVSL
-	LVSR
-	VPKPX
-	VPKSDSS
-	VPKSDUS
-	VPKSHSS
-	VPKSHUS
-	VPKSWSS
-	VPKSWUS
-	VPKUDUM
-	VPKUDUS
-	VPKUHUM
-	VPKUHUS
-	VPKUWUM
-	VPKUWUS
-	VUPKHPX
-	VUPKLPX
-	VUPKHSB
-	VUPKHSH
-	VUPKHSW
-	VUPKLSB
-	VUPKLSH
-	VUPKLSW
-	VMRGHB
-	VMRGHH
-	VMRGLB
-	VMRGLH
-	VMRGHW
-	VMRGLW
-	VMRGEW
-	VMRGOW
-	VSPLTB
-	VSPLTH
-	VSPLTW
-	VSPLTISB
-	VSPLTISH
-	VSPLTISW
-	VPERM
-	VPERMR
-	VSEL
-	VSL
-	VSLDOI
-	VSLO
-	VSR
-	VSRO
-	VADDCUW
-	VADDSBS
-	VADDSHS
-	VADDSWS
-	VADDUBM
-	VADDUDM
-	VADDUHM
-	VADDUWM
-	VADDUBS
-	VADDUHS
-	VADDUWS
-	VADDUQM
-	VADDEUQM
-	VADDCUQ
-	VADDECUQ
-	VSUBCUW
-	VSUBSBS
-	VSUBSHS
-	VSUBSWS
-	VSUBUBM
-	VSUBUDM
-	VSUBUHM
-	VSUBUWM
-	VSUBUBS
-	VSUBUHS
-	VSUBUWS
-	VSUBUQM
-	VSUBEUQM
-	VSUBCUQ
-	VSUBECUQ
-	VMULESB
-	VMULEUB
-	VMULOSB
-	VMULOUB
-	VMULESH
-	VMULEUH
-	VMULOSH
-	VMULOUH
-	VMULESW
-	VMULEUW
-	VMULOSW
-	VMULOUW
-	VMULUWM
-	VMHADDSHS
-	VMHRADDSHS
-	VMLADDUHM
-	VMSUMUBM
-	VMSUMMBM
-	VMSUMSHM
-	VMSUMSHS
-	VMSUMUHM
-	VMSUMUHS
-	VMSUMUDM
-	VSUMSWS
-	VSUM2SWS
-	VSUM4SBS
-	VSUM4SHS
-	VSUM4UBS
-	VAVGSB
-	VAVGSH
-	VAVGSW
-	VAVGUB
-	VAVGUW
-	VAVGUH
-	VMAXSB
-	VMAXSD
-	VMAXUB
-	VMAXUD
-	VMAXSH
-	VMAXSW
-	VMAXUH
-	VMAXUW
-	VMINSB
-	VMINSD
-	VMINUB
-	VMINUD
-	VMINSH
-	VMINSW
-	VMINUH
-	VMINUW
-	VCMPEQUB
-	VCMPEQUBCC
-	VCMPEQUH
-	VCMPEQUHCC
-	VCMPEQUW
-	VCMPEQUWCC
-	VCMPEQUD
-	VCMPEQUDCC
-	VCMPNEB
-	VCMPNEBCC
-	VCMPNEZB
-	VCMPNEZBCC
-	VCMPNEH
-	VCMPNEHCC
-	VCMPNEZH
-	VCMPNEZHCC
-	VCMPNEW
-	VCMPNEWCC
-	VCMPNEZW
-	VCMPNEZWCC
-	VCMPGTSB
-	VCMPGTSBCC
-	VCMPGTSD
-	VCMPGTSDCC
-	VCMPGTSH
-	VCMPGTSHCC
-	VCMPGTSW
-	VCMPGTSWCC
-	VCMPGTUB
-	VCMPGTUBCC
-	VCMPGTUD
-	VCMPGTUDCC
-	VCMPGTUH
-	VCMPGTUHCC
-	VCMPGTUW
-	VCMPGTUWCC
-	VAND
-	VANDC
-	VEQV
-	VNAND
-	VORC
-	VNOR
-	VOR
-	VXOR
-	VRLB
-	VRLH
-	VRLW
-	VRLD
-	VSLB
-	VSLH
-	VSLW
-	VSLD
-	VSRB
-	VSRH
-	VSRW
-	VSRD
-	VSRAB
-	VSRAH
-	VSRAW
-	VSRAD
-	VADDFP
-	VSUBFP
-	VMADDFP
-	VNMSUBFP
-	VMAXFP
-	VMINFP
-	VCTSXS
-	VCTUXS
-	VCFSX
-	VCFUX
-	VRFIM
-	VRFIN
-	VRFIP
-	VRFIZ
-	VCMPBFP
-	VCMPBFPCC
-	VCMPEQFP
-	VCMPEQFPCC
-	VCMPGEFP
-	VCMPGEFPCC
-	VCMPGTFP
-	VCMPGTFPCC
-	VEXPTEFP
-	VLOGEFP
-	VREFP
-	VRSQRTEFP
-	VCIPHER
-	VCIPHERLAST
-	VNCIPHER
-	VNCIPHERLAST
-	VSBOX
-	VSHASIGMAD
-	VSHASIGMAW
-	VPMSUMB
-	VPMSUMD
-	VPMSUMH
-	VPMSUMW
-	VPERMXOR
-	VGBBD
-	VCLZB
-	VCLZH
-	VCLZW
-	VCLZD
-	VPOPCNTB
-	VPOPCNTD
-	VPOPCNTH
-	VPOPCNTW
-	VBPERMQ
-	VBPERMD
-	BCDADDCC
-	BCDSUBCC
-	MTVSCR
-	MFVSCR
-	DADD
-	DADDCC
-	DSUB
-	DSUBCC
-	DMUL
-	DMULCC
-	DDIV
-	DDIVCC
-	DCMPU
-	DCMPO
-	DTSTDC
-	DTSTDG
-	DTSTEX
-	DTSTSF
-	DQUAI
-	DQUAICC
-	DQUA
-	DQUACC
-	DRRND
-	DRRNDCC
-	DRINTX
-	DRINTXCC
-	DRINTN
-	DRINTNCC
-	DCTDP
-	DCTDPCC
-	DCTQPQ
-	DCTQPQCC
-	DRSP
-	DRSPCC
-	DRDPQ
-	DRDPQCC
-	DCFFIX
-	DCFFIXCC
-	DCFFIXQ
-	DCFFIXQCC
-	DCTFIX
-	DCTFIXCC
-	DDEDPD
-	DDEDPDCC
-	DENBCD
-	DENBCDCC
-	DXEX
-	DXEXCC
-	DIEX
-	DIEXCC
-	DSCLI
-	DSCLICC
-	DSCRI
-	DSCRICC
+	FTDIV
+	FTSQRT
+	LBARX
+	LDBRX
+	LFIWZX
+	LHARX
 	LXSDX
-	LXSIWAX
-	LXSIWZX
-	LXSSPX
 	LXVD2X
 	LXVDSX
 	LXVW4X
-	LXVH8X
-	LXVB16X
-	LXV
-	LXVL
-	LXVLL
-	LXVX
+	POPCNTD
+	POPCNTW
+	STBCXCC
+	STDBRX
+	STHCXCC
 	STXSDX
-	STXSIWX
-	STXSSPX
 	STXVD2X
 	STXVW4X
-	STXVH8X
-	STXVB16X
-	STXV
-	STXVL
-	STXVLL
-	STXVX
 	XSABSDP
 	XSADDDP
-	XSADDSP
 	XSCMPODP
 	XSCMPUDP
 	XSCPSGNDP
 	XSCVDPSP
-	XSCVDPSPN
 	XSCVDPSXDS
 	XSCVDPSXWS
 	XSCVDPUXDS
 	XSCVDPUXWS
 	XSCVSPDP
-	XSCVSPDPN
 	XSCVSXDDP
-	XSCVSXDSP
 	XSCVUXDDP
-	XSCVUXDSP
 	XSDIVDP
-	XSDIVSP
 	XSMADDADP
-	XSMADDASP
+	XSMADDMDP
 	XSMAXDP
 	XSMINDP
 	XSMSUBADP
-	XSMSUBASP
+	XSMSUBMDP
 	XSMULDP
-	XSMULSP
 	XSNABSDP
 	XSNEGDP
 	XSNMADDADP
-	XSNMADDASP
+	XSNMADDMDP
 	XSNMSUBADP
-	XSNMSUBASP
+	XSNMSUBMDP
 	XSRDPI
 	XSRDPIC
 	XSRDPIM
 	XSRDPIP
 	XSRDPIZ
 	XSREDP
-	XSRESP
-	XSRSP
 	XSRSQRTEDP
-	XSRSQRTESP
 	XSSQRTDP
-	XSSQRTSP
 	XSSUBDP
-	XSSUBSP
 	XSTDIVDP
 	XSTSQRTDP
 	XVABSDP
@@ -834,12 +706,16 @@
 	XVDIVSP
 	XVMADDADP
 	XVMADDASP
+	XVMADDMDP
+	XVMADDMSP
 	XVMAXDP
 	XVMAXSP
 	XVMINDP
 	XVMINSP
 	XVMSUBADP
 	XVMSUBASP
+	XVMSUBMDP
+	XVMSUBMSP
 	XVMULDP
 	XVMULSP
 	XVNABSDP
@@ -848,8 +724,12 @@
 	XVNEGSP
 	XVNMADDADP
 	XVNMADDASP
+	XVNMADDMDP
+	XVNMADDMSP
 	XVNMSUBADP
 	XVNMSUBASP
+	XVNMSUBMDP
+	XVNMSUBMSP
 	XVRDPI
 	XVRDPIC
 	XVRDPIM
@@ -874,4762 +754,5019 @@
 	XVTSQRTSP
 	XXLAND
 	XXLANDC
-	XXLEQV
-	XXLNAND
-	XXLORC
 	XXLNOR
 	XXLOR
 	XXLXOR
 	XXMRGHW
 	XXMRGLW
 	XXPERMDI
-	XXPERM
 	XXSEL
 	XXSLDWI
 	XXSPLTW
-	XXBRD
-	XXBRW
-	XXBRH
-	BRINC
-	EVABS
-	EVADDIW
-	EVADDSMIAAW
-	EVADDSSIAAW
-	EVADDUMIAAW
-	EVADDUSIAAW
-	EVADDW
-	EVAND
-	EVCMPEQ
-	EVANDC
-	EVCMPGTS
-	EVCMPGTU
-	EVCMPLTU
-	EVCMPLTS
-	EVCNTLSW
-	EVCNTLZW
-	EVDIVWS
-	EVDIVWU
-	EVEQV
-	EVEXTSB
-	EVEXTSH
-	EVLDD
-	EVLDH
-	EVLDDX
-	EVLDHX
-	EVLDW
-	EVLHHESPLAT
-	EVLDWX
-	EVLHHESPLATX
-	EVLHHOSSPLAT
-	EVLHHOUSPLAT
-	EVLHHOSSPLATX
-	EVLHHOUSPLATX
-	EVLWHE
-	EVLWHOS
-	EVLWHEX
-	EVLWHOSX
-	EVLWHOU
-	EVLWHSPLAT
-	EVLWHOUX
-	EVLWHSPLATX
-	EVLWWSPLAT
-	EVMERGEHI
-	EVLWWSPLATX
-	EVMERGELO
-	EVMERGEHILO
-	EVMHEGSMFAA
-	EVMERGELOHI
-	EVMHEGSMFAN
-	EVMHEGSMIAA
-	EVMHEGUMIAA
-	EVMHEGSMIAN
-	EVMHEGUMIAN
-	EVMHESMF
-	EVMHESMFAAW
-	EVMHESMFA
-	EVMHESMFANW
-	EVMHESMI
-	EVMHESMIAAW
-	EVMHESMIA
-	EVMHESMIANW
-	EVMHESSF
-	EVMHESSFA
-	EVMHESSFAAW
-	EVMHESSFANW
-	EVMHESSIAAW
-	EVMHESSIANW
-	EVMHEUMI
-	EVMHEUMIAAW
-	EVMHEUMIA
-	EVMHEUMIANW
-	EVMHEUSIAAW
-	EVMHEUSIANW
-	EVMHOGSMFAA
-	EVMHOGSMIAA
-	EVMHOGSMFAN
-	EVMHOGSMIAN
-	EVMHOGUMIAA
-	EVMHOSMF
-	EVMHOGUMIAN
-	EVMHOSMFA
-	EVMHOSMFAAW
-	EVMHOSMI
-	EVMHOSMFANW
-	EVMHOSMIA
-	EVMHOSMIAAW
-	EVMHOSMIANW
-	EVMHOSSF
-	EVMHOSSFA
-	EVMHOSSFAAW
-	EVMHOSSFANW
-	EVMHOSSIAAW
-	EVMHOUMI
-	EVMHOSSIANW
-	EVMHOUMIA
-	EVMHOUMIAAW
-	EVMHOUSIAAW
-	EVMHOUMIANW
-	EVMHOUSIANW
-	EVMRA
-	EVMWHSMF
-	EVMWHSMI
-	EVMWHSMFA
-	EVMWHSMIA
-	EVMWHSSF
-	EVMWHUMI
-	EVMWHSSFA
-	EVMWHUMIA
-	EVMWLSMIAAW
-	EVMWLSSIAAW
-	EVMWLSMIANW
-	EVMWLSSIANW
-	EVMWLUMI
-	EVMWLUMIAAW
-	EVMWLUMIA
-	EVMWLUMIANW
-	EVMWLUSIAAW
-	EVMWSMF
-	EVMWLUSIANW
-	EVMWSMFA
-	EVMWSMFAA
-	EVMWSMI
-	EVMWSMIAA
-	EVMWSMFAN
-	EVMWSMIA
-	EVMWSMIAN
-	EVMWSSF
-	EVMWSSFA
-	EVMWSSFAA
-	EVMWUMI
-	EVMWSSFAN
-	EVMWUMIA
-	EVMWUMIAA
-	EVNAND
-	EVMWUMIAN
-	EVNEG
-	EVNOR
-	EVORC
-	EVOR
-	EVRLW
-	EVRLWI
-	EVSEL
-	EVRNDW
-	EVSLW
-	EVSPLATFI
-	EVSRWIS
-	EVSLWI
-	EVSPLATI
-	EVSRWIU
-	EVSRWS
-	EVSTDD
-	EVSRWU
-	EVSTDDX
-	EVSTDH
-	EVSTDW
-	EVSTDHX
-	EVSTDWX
-	EVSTWHE
-	EVSTWHO
-	EVSTWWE
-	EVSTWHEX
-	EVSTWHOX
-	EVSTWWEX
-	EVSTWWO
-	EVSUBFSMIAAW
-	EVSTWWOX
-	EVSUBFSSIAAW
-	EVSUBFUMIAAW
-	EVSUBFUSIAAW
-	EVSUBFW
-	EVSUBIFW
-	EVXOR
-	EVFSABS
-	EVFSNABS
-	EVFSNEG
-	EVFSADD
-	EVFSMUL
-	EVFSSUB
-	EVFSDIV
-	EVFSCMPGT
-	EVFSCMPLT
-	EVFSCMPEQ
-	EVFSTSTGT
-	EVFSTSTLT
-	EVFSTSTEQ
-	EVFSCFSI
-	EVFSCFSF
-	EVFSCFUI
-	EVFSCFUF
-	EVFSCTSI
-	EVFSCTUI
-	EVFSCTSIZ
-	EVFSCTUIZ
-	EVFSCTSF
-	EVFSCTUF
-	EFSABS
-	EFSNEG
-	EFSNABS
-	EFSADD
-	EFSMUL
-	EFSSUB
-	EFSDIV
-	EFSCMPGT
-	EFSCMPLT
-	EFSCMPEQ
-	EFSTSTGT
-	EFSTSTLT
-	EFSTSTEQ
-	EFSCFSI
-	EFSCFSF
-	EFSCTSI
-	EFSCFUI
-	EFSCFUF
-	EFSCTUI
-	EFSCTSIZ
-	EFSCTSF
-	EFSCTUIZ
-	EFSCTUF
-	EFDABS
-	EFDNEG
-	EFDNABS
-	EFDADD
-	EFDMUL
-	EFDSUB
-	EFDDIV
-	EFDCMPGT
-	EFDCMPEQ
-	EFDCMPLT
-	EFDTSTGT
-	EFDTSTLT
-	EFDCFSI
-	EFDTSTEQ
-	EFDCFUI
-	EFDCFSID
-	EFDCFSF
-	EFDCFUF
-	EFDCFUID
-	EFDCTSI
-	EFDCTUI
-	EFDCTSIDZ
-	EFDCTUIDZ
-	EFDCTSIZ
-	EFDCTSF
-	EFDCTUF
-	EFDCTUIZ
-	EFDCFS
-	EFSCFD
-	DLMZB
-	DLMZBCC
-	MACCHW
-	MACCHWCC
-	MACCHWO
-	MACCHWOCC
-	MACCHWS
-	MACCHWSCC
-	MACCHWSO
-	MACCHWSOCC
-	MACCHWU
-	MACCHWUCC
-	MACCHWUO
-	MACCHWUOCC
-	MACCHWSU
-	MACCHWSUCC
-	MACCHWSUO
-	MACCHWSUOCC
-	MACHHW
-	MACHHWCC
-	MACHHWO
-	MACHHWOCC
-	MACHHWS
-	MACHHWSCC
-	MACHHWSO
-	MACHHWSOCC
-	MACHHWU
-	MACHHWUCC
-	MACHHWUO
-	MACHHWUOCC
-	MACHHWSU
-	MACHHWSUCC
-	MACHHWSUO
-	MACHHWSUOCC
-	MACLHW
-	MACLHWCC
-	MACLHWO
-	MACLHWOCC
-	MACLHWS
-	MACLHWSCC
-	MACLHWSO
-	MACLHWSOCC
-	MACLHWU
-	MACLHWUCC
-	MACLHWUO
-	MACLHWUOCC
-	MULCHW
-	MULCHWCC
-	MACLHWSU
-	MACLHWSUCC
-	MACLHWSUO
-	MACLHWSUOCC
-	MULCHWU
-	MULCHWUCC
-	MULHHW
-	MULHHWCC
-	MULLHW
-	MULLHWCC
-	MULHHWU
-	MULHHWUCC
-	MULLHWU
-	MULLHWUCC
-	NMACCHW
-	NMACCHWCC
-	NMACCHWO
-	NMACCHWOCC
-	NMACCHWS
-	NMACCHWSCC
-	NMACCHWSO
-	NMACCHWSOCC
-	NMACHHW
-	NMACHHWCC
-	NMACHHWO
-	NMACHHWOCC
-	NMACHHWS
-	NMACHHWSCC
-	NMACHHWSO
-	NMACHHWSOCC
-	NMACLHW
-	NMACLHWCC
-	NMACLHWO
-	NMACLHWOCC
-	NMACLHWS
-	NMACLHWSCC
-	NMACLHWSO
-	NMACLHWSOCC
-	ICBI
-	ICBT
-	DCBA
+	CMPB
+	DADD
+	DADDCC
+	DADDQ
+	DADDQCC
+	DCFFIXQ
+	DCFFIXQCC
+	DCMPO
+	DCMPOQ
+	DCMPU
+	DCMPUQ
+	DCTDP
+	DCTDPCC
+	DCTFIX
+	DCTFIXCC
+	DCTFIXQ
+	DCTFIXQCC
+	DCTQPQ
+	DCTQPQCC
+	DDEDPD
+	DDEDPDCC
+	DDEDPDQ
+	DDEDPDQCC
+	DDIV
+	DDIVCC
+	DDIVQ
+	DDIVQCC
+	DENBCD
+	DENBCDCC
+	DENBCDQ
+	DENBCDQCC
+	DIEX
+	DIEXCC
+	DIEXQCC
+	DIEXQ
+	DMUL
+	DMULCC
+	DMULQ
+	DMULQCC
+	DQUA
+	DQUACC
+	DQUAI
+	DQUAICC
+	DQUAIQ
+	DQUAIQCC
+	DQUAQ
+	DQUAQCC
+	DRDPQ
+	DRDPQCC
+	DRINTN
+	DRINTNCC
+	DRINTNQ
+	DRINTNQCC
+	DRINTX
+	DRINTXCC
+	DRINTXQ
+	DRINTXQCC
+	DRRND
+	DRRNDCC
+	DRRNDQ
+	DRRNDQCC
+	DRSP
+	DRSPCC
+	DSCLI
+	DSCLICC
+	DSCLIQ
+	DSCLIQCC
+	DSCRI
+	DSCRICC
+	DSCRIQ
+	DSCRIQCC
+	DSUB
+	DSUBCC
+	DSUBQ
+	DSUBQCC
+	DTSTDC
+	DTSTDCQ
+	DTSTDG
+	DTSTDGQ
+	DTSTEX
+	DTSTEXQ
+	DTSTSF
+	DTSTSFQ
+	DXEX
+	DXEXCC
+	DXEXQ
+	DXEXQCC
+	FCPSGN
+	FCPSGNCC
+	LBZCIX
+	LDCIX
+	LFDP
+	LFDPX
+	LFIWAX
+	LHZCIX
+	LWZCIX
+	PRTYD
+	PRTYW
+	SLBFEECC
+	STBCIX
+	STDCIX
+	STFDP
+	STFDPX
+	STHCIX
+	STWCIX
+	ISEL
+	LVEBX
+	LVEHX
+	LVEWX
+	LVSL
+	LVSR
+	LVX
+	LVXL
+	MFVSCR
+	MTVSCR
+	STVEBX
+	STVEHX
+	STVEWX
+	STVX
+	STVXL
+	TLBIEL
+	VADDCUW
+	VADDFP
+	VADDSBS
+	VADDSHS
+	VADDSWS
+	VADDUBM
+	VADDUBS
+	VADDUHM
+	VADDUHS
+	VADDUWM
+	VADDUWS
+	VAND
+	VANDC
+	VAVGSB
+	VAVGSH
+	VAVGSW
+	VAVGUB
+	VAVGUH
+	VAVGUW
+	VCFSX
+	VCFUX
+	VCMPBFP
+	VCMPBFPCC
+	VCMPEQFP
+	VCMPEQFPCC
+	VCMPEQUB
+	VCMPEQUBCC
+	VCMPEQUH
+	VCMPEQUHCC
+	VCMPEQUW
+	VCMPEQUWCC
+	VCMPGEFP
+	VCMPGEFPCC
+	VCMPGTFP
+	VCMPGTFPCC
+	VCMPGTSB
+	VCMPGTSBCC
+	VCMPGTSH
+	VCMPGTSHCC
+	VCMPGTSW
+	VCMPGTSWCC
+	VCMPGTUB
+	VCMPGTUBCC
+	VCMPGTUH
+	VCMPGTUHCC
+	VCMPGTUW
+	VCMPGTUWCC
+	VCTSXS
+	VCTUXS
+	VEXPTEFP
+	VLOGEFP
+	VMADDFP
+	VMAXFP
+	VMAXSB
+	VMAXSH
+	VMAXSW
+	VMAXUB
+	VMAXUH
+	VMAXUW
+	VMHADDSHS
+	VMHRADDSHS
+	VMINFP
+	VMINSB
+	VMINSH
+	VMINSW
+	VMINUB
+	VMINUH
+	VMINUW
+	VMLADDUHM
+	VMRGHB
+	VMRGHH
+	VMRGHW
+	VMRGLB
+	VMRGLH
+	VMRGLW
+	VMSUMMBM
+	VMSUMSHM
+	VMSUMSHS
+	VMSUMUBM
+	VMSUMUHM
+	VMSUMUHS
+	VMULESB
+	VMULESH
+	VMULEUB
+	VMULEUH
+	VMULOSB
+	VMULOSH
+	VMULOUB
+	VMULOUH
+	VNMSUBFP
+	VNOR
+	VOR
+	VPERM
+	VPKPX
+	VPKSHSS
+	VPKSHUS
+	VPKSWSS
+	VPKSWUS
+	VPKUHUM
+	VPKUHUS
+	VPKUWUM
+	VPKUWUS
+	VREFP
+	VRFIM
+	VRFIN
+	VRFIP
+	VRFIZ
+	VRLB
+	VRLH
+	VRLW
+	VRSQRTEFP
+	VSEL
+	VSL
+	VSLB
+	VSLDOI
+	VSLH
+	VSLO
+	VSLW
+	VSPLTB
+	VSPLTH
+	VSPLTISB
+	VSPLTISH
+	VSPLTISW
+	VSPLTW
+	VSR
+	VSRAB
+	VSRAH
+	VSRAW
+	VSRB
+	VSRH
+	VSRO
+	VSRW
+	VSUBCUW
+	VSUBFP
+	VSUBSBS
+	VSUBSHS
+	VSUBSWS
+	VSUBUBM
+	VSUBUBS
+	VSUBUHM
+	VSUBUHS
+	VSUBUWM
+	VSUBUWS
+	VSUM2SWS
+	VSUM4SBS
+	VSUM4SHS
+	VSUM4UBS
+	VSUMSWS
+	VUPKHPX
+	VUPKHSB
+	VUPKHSH
+	VUPKLPX
+	VUPKLSB
+	VUPKLSH
+	VXOR
+	FRE
+	FRECC
+	FRIM
+	FRIMCC
+	FRIN
+	FRINCC
+	FRIP
+	FRIPCC
+	FRIZ
+	FRIZCC
+	FRSQRTES
+	FRSQRTESCC
+	HRFID
+	POPCNTB
+	MFOCRF
+	MTOCRF
+	SLBMFEE
+	SLBMFEV
+	SLBMTE
+	RFSCV
+	SCV
+	LQ
+	STQ
+	CNTLZD
+	CNTLZDCC
+	DCBF
+	DCBST
 	DCBT
 	DCBTST
-	DCBZ
-	DCBST
-	DCBF
-	ISYNC
-	LBARX
-	LHARX
-	LWARX
-	STBCXCC
-	STHCXCC
-	STWCXCC
-	LDARX
-	STDCXCC
-	LQARX
-	STQCXCC
-	SYNC
+	DIVD
+	DIVDCC
+	DIVDO
+	DIVDOCC
+	DIVDU
+	DIVDUCC
+	DIVDUO
+	DIVDUOCC
+	DIVW
+	DIVWCC
+	DIVWO
+	DIVWOCC
+	DIVWU
+	DIVWUCC
+	DIVWUO
+	DIVWUOCC
 	EIEIO
-	MBAR
-	WAIT
-	TBEGINCC
-	TENDCC
-	TABORTCC
-	TABORTWCCC
-	TABORTWCICC
-	TABORTDCCC
-	TABORTDCICC
-	TSRCC
-	TCHECK
+	EXTSB
+	EXTSBCC
+	EXTSW
+	EXTSWCC
+	FADDS
+	FADDSCC
+	FCFID
+	FCFIDCC
+	FCTID
+	FCTIDCC
+	FCTIDZ
+	FCTIDZCC
+	FDIVS
+	FDIVSCC
+	FMADDS
+	FMADDSCC
+	FMSUBS
+	FMSUBSCC
+	FMULS
+	FMULSCC
+	FNMADDS
+	FNMADDSCC
+	FNMSUBS
+	FNMSUBSCC
+	FRES
+	FRESCC
+	FRSQRTE
+	FRSQRTECC
+	FSEL
+	FSELCC
+	FSQRTS
+	FSQRTSCC
+	FSUBS
+	FSUBSCC
+	ICBI
+	LD
+	LDARX
+	LDU
+	LDUX
+	LDX
+	LWA
+	LWARX
+	LWAUX
+	LWAX
 	MFTB
-	RFEBB
-	LBDX
-	LHDX
-	LWDX
-	LDDX
-	LFDDX
-	STBDX
-	STHDX
-	STWDX
-	STDDX
-	STFDDX
-	DSN
-	ECIWX
-	ECOWX
-	RFID
-	HRFID
-	DOZE
-	NAP
-	SLEEP
-	RVWINKLE
-	LBZCIX
-	LWZCIX
-	LHZCIX
-	LDCIX
-	STBCIX
-	STWCIX
-	STHCIX
-	STDCIX
-	TRECLAIMCC
-	TRECHKPTCC
-	MTMSR
 	MTMSRD
-	MFMSR
-	SLBIE
+	MULHD
+	MULHDCC
+	MULHDU
+	MULHDUCC
+	MULHW
+	MULHWCC
+	MULHWU
+	MULHWUCC
+	MULLD
+	MULLDCC
+	MULLDO
+	MULLDOCC
+	RFID
+	RLDCL
+	RLDCLCC
+	RLDCR
+	RLDCRCC
+	RLDIC
+	RLDICCC
+	RLDICL
+	RLDICLCC
+	RLDICR
+	RLDICRCC
+	RLDIMI
+	RLDIMICC
+	SC
 	SLBIA
-	SLBMTE
-	SLBMFEV
-	SLBMFEE
-	SLBFEECC
-	MTSR
-	MTSRIN
-	MFSR
-	MFSRIN
-	TLBIE
-	TLBIEL
-	TLBIA
+	SLBIE
+	SLD
+	SLDCC
+	SRAD
+	SRADCC
+	SRADI
+	SRADICC
+	SRD
+	SRDCC
+	STD
+	STDCXCC
+	STDU
+	STDUX
+	STDX
+	STFIWX
+	STWCXCC
+	SUBF
+	SUBFCC
+	SUBFO
+	SUBFOCC
+	TD
+	TDI
 	TLBSYNC
-	MSGSND
-	MSGCLR
-	MSGSNDP
-	MSGCLRP
-	MTTMR
-	RFI
-	RFCI
-	RFDI
-	RFMCI
-	RFGI
-	EHPRIV
-	MTDCR
-	MTDCRX
-	MFDCR
-	MFDCRX
-	WRTEE
-	WRTEEI
-	LBEPX
-	LHEPX
-	LWEPX
-	LDEPX
-	STBEPX
-	STHEPX
-	STWEPX
-	STDEPX
-	DCBSTEP
-	DCBTEP
-	DCBFEP
-	DCBTSTEP
-	ICBIEP
-	DCBZEP
-	LFDEPX
-	STFDEPX
-	EVLDDEPX
-	EVSTDDEPX
-	LVEPX
-	LVEPXL
-	STVEPX
-	STVEPXL
-	DCBI
-	DCBLQCC
-	ICBLQCC
-	DCBTLS
-	DCBTSTLS
-	ICBTLS
-	ICBLC
-	DCBLC
-	TLBIVAX
-	TLBILX
-	TLBSX
-	TLBSRXCC
-	TLBRE
-	TLBWE
-	DNH
-	DCI
-	ICI
-	DCREAD
-	ICREAD
-	MFPMR
-	MTPMR
-	ADDEX
-	DARN
-	MADDHD
-	MADDHDU
-	MADDLD
-	CMPRB
-	CMPEQB
-	EXTSWSLI
-	EXTSWSLICC
-	MFVSRLD
-	MTVSRDD
-	MTVSRWS
-	MCRXRX
-	COPY
-	PASTECC
+	FCTIW
+	FCTIWCC
+	FCTIWZ
+	FCTIWZCC
+	FSQRT
+	FSQRTCC
+	ADD
+	ADDCC
+	ADDO
+	ADDOCC
+	ADDC
+	ADDCCC
+	ADDCO
+	ADDCOCC
+	ADDE
+	ADDECC
+	ADDEO
+	ADDEOCC
+	LI
+	ADDI
+	ADDIC
+	ADDICCC
+	LIS
+	ADDIS
+	ADDME
+	ADDMECC
+	ADDMEO
+	ADDMEOCC
+	ADDZE
+	ADDZECC
+	ADDZEO
+	ADDZEOCC
+	AND
+	ANDCC
+	ANDC
+	ANDCCC
+	ANDICC
+	ANDISCC
+	B
+	BA
+	BL
+	BLA
+	BC
+	BCA
+	BCL
+	BCLA
+	BCCTR
+	BCCTRL
+	BCLR
+	BCLRL
+	CMPW
+	CMPD
+	CMP
+	CMPWI
+	CMPDI
+	CMPI
+	CMPLW
+	CMPLD
+	CMPL
+	CMPLWI
+	CMPLDI
+	CMPLI
+	CNTLZW
+	CNTLZWCC
+	CRAND
+	CRANDC
+	CREQV
+	CRNAND
+	CRNOR
+	CROR
+	CRORC
+	CRXOR
+	DCBZ
+	EQV
+	EQVCC
+	EXTSH
+	EXTSHCC
+	FABS
+	FABSCC
+	FADD
+	FADDCC
+	FCMPO
+	FCMPU
+	FDIV
+	FDIVCC
+	FMADD
+	FMADDCC
+	FMR
+	FMRCC
+	FMSUB
+	FMSUBCC
+	FMUL
+	FMULCC
+	FNABS
+	FNABSCC
+	FNEG
+	FNEGCC
+	FNMADD
+	FNMADDCC
+	FNMSUB
+	FNMSUBCC
+	FRSP
+	FRSPCC
+	FSUB
+	FSUBCC
+	ISYNC
+	LBZ
+	LBZU
+	LBZUX
+	LBZX
+	LFD
+	LFDU
+	LFDUX
+	LFDX
+	LFS
+	LFSU
+	LFSUX
+	LFSX
+	LHA
+	LHAU
+	LHAUX
+	LHAX
+	LHBRX
+	LHZ
+	LHZU
+	LHZUX
+	LHZX
+	LMW
+	LSWI
+	LSWX
+	LWBRX
+	LWZ
+	LWZU
+	LWZUX
+	LWZX
+	MCRF
+	MCRFS
+	MFCR
+	MFFS
+	MFFSCC
+	MFMSR
+	MFSPR
+	MTCRF
+	MTFSB0
+	MTFSB0CC
+	MTFSB1
+	MTFSB1CC
+	MTFSF
+	MTFSFCC
+	MTFSFI
+	MTFSFICC
+	MTMSR
+	MTSPR
+	MULLI
+	MULLW
+	MULLWCC
+	MULLWO
+	MULLWOCC
+	NAND
+	NANDCC
+	NEG
+	NEGCC
+	NEGO
+	NEGOCC
+	NOR
+	NORCC
+	OR
+	ORCC
+	ORC
+	ORCCC
+	NOP
+	ORI
+	ORIS
+	RLWIMI
+	RLWIMICC
+	RLWINM
+	RLWINMCC
+	RLWNM
+	RLWNMCC
+	SLW
+	SLWCC
+	SRAW
+	SRAWCC
+	SRAWI
+	SRAWICC
+	SRW
+	SRWCC
+	STB
+	STBU
+	STBUX
+	STBX
+	STFD
+	STFDU
+	STFDUX
+	STFDX
+	STFS
+	STFSU
+	STFSUX
+	STFSX
+	STH
+	STHBRX
+	STHU
+	STHUX
+	STHX
+	STMW
+	STSWI
+	STSWX
+	STW
+	STWBRX
+	STWU
+	STWUX
+	STWX
+	SUBFC
+	SUBFCCC
+	SUBFCO
+	SUBFCOCC
+	SUBFE
+	SUBFECC
+	SUBFEO
+	SUBFEOCC
+	SUBFIC
+	SUBFME
+	SUBFMECC
+	SUBFMEO
+	SUBFMEOCC
+	SUBFZE
+	SUBFZECC
+	SUBFZEO
+	SUBFZEOCC
+	SYNC
+	TLBIE
+	TW
+	TWI
+	XOR
+	XORCC
+	XORI
+	XORIS
 )
 
 var opstr = [...]string{
-	CNTLZW:        "cntlzw",
-	CNTLZWCC:      "cntlzw.",
-	B:             "b",
-	BA:            "ba",
-	BL:            "bl",
-	BLA:           "bla",
-	BC:            "bc",
-	BCA:           "bca",
-	BCL:           "bcl",
-	BCLA:          "bcla",
-	BCLR:          "bclr",
-	BCLRL:         "bclrl",
-	BCCTR:         "bcctr",
-	BCCTRL:        "bcctrl",
-	BCTAR:         "bctar",
-	BCTARL:        "bctarl",
-	CRAND:         "crand",
-	CROR:          "cror",
-	CRNAND:        "crnand",
-	CRXOR:         "crxor",
-	CRNOR:         "crnor",
-	CRANDC:        "crandc",
-	MCRF:          "mcrf",
-	CREQV:         "creqv",
-	CRORC:         "crorc",
-	SC:            "sc",
-	CLRBHRB:       "clrbhrb",
-	MFBHRBE:       "mfbhrbe",
-	LBZ:           "lbz",
-	LBZU:          "lbzu",
-	LBZX:          "lbzx",
-	LBZUX:         "lbzux",
-	LHZ:           "lhz",
-	LHZU:          "lhzu",
-	LHZX:          "lhzx",
-	LHZUX:         "lhzux",
-	LHA:           "lha",
-	LHAU:          "lhau",
-	LHAX:          "lhax",
-	LHAUX:         "lhaux",
-	LWZ:           "lwz",
-	LWZU:          "lwzu",
-	LWZX:          "lwzx",
-	LWZUX:         "lwzux",
-	LWA:           "lwa",
-	LWAX:          "lwax",
-	LWAUX:         "lwaux",
-	LD:            "ld",
-	LDU:           "ldu",
-	LDX:           "ldx",
-	LDUX:          "ldux",
-	STB:           "stb",
-	STBU:          "stbu",
-	STBX:          "stbx",
-	STBUX:         "stbux",
-	STH:           "sth",
-	STHU:          "sthu",
-	STHX:          "sthx",
-	STHUX:         "sthux",
-	STW:           "stw",
-	STWU:          "stwu",
-	STWX:          "stwx",
-	STWUX:         "stwux",
-	STD:           "std",
-	STDU:          "stdu",
-	STDX:          "stdx",
-	STDUX:         "stdux",
-	LQ:            "lq",
-	STQ:           "stq",
-	LHBRX:         "lhbrx",
-	LWBRX:         "lwbrx",
-	STHBRX:        "sthbrx",
-	STWBRX:        "stwbrx",
-	LDBRX:         "ldbrx",
-	STDBRX:        "stdbrx",
-	LMW:           "lmw",
-	STMW:          "stmw",
-	LSWI:          "lswi",
-	LSWX:          "lswx",
-	STSWI:         "stswi",
-	STSWX:         "stswx",
-	LI:            "li",
-	ADDI:          "addi",
-	LIS:           "lis",
-	ADDIS:         "addis",
-	ADD:           "add",
-	ADDCC:         "add.",
-	ADDO:          "addo",
-	ADDOCC:        "addo.",
-	ADDIC:         "addic",
-	SUBF:          "subf",
-	SUBFCC:        "subf.",
-	SUBFO:         "subfo",
-	SUBFOCC:       "subfo.",
-	ADDICCC:       "addic.",
-	SUBFIC:        "subfic",
-	ADDC:          "addc",
-	ADDCCC:        "addc.",
-	ADDCO:         "addco",
-	ADDCOCC:       "addco.",
-	SUBFC:         "subfc",
-	SUBFCCC:       "subfc.",
-	SUBFCO:        "subfco",
-	SUBFCOCC:      "subfco.",
-	ADDE:          "adde",
-	ADDECC:        "adde.",
-	ADDEO:         "addeo",
-	ADDEOCC:       "addeo.",
-	ADDME:         "addme",
-	ADDMECC:       "addme.",
-	ADDMEO:        "addmeo",
-	ADDMEOCC:      "addmeo.",
-	SUBFE:         "subfe",
-	SUBFECC:       "subfe.",
-	SUBFEO:        "subfeo",
-	SUBFEOCC:      "subfeo.",
-	SUBFME:        "subfme",
-	SUBFMECC:      "subfme.",
-	SUBFMEO:       "subfmeo",
-	SUBFMEOCC:     "subfmeo.",
-	ADDZE:         "addze",
-	ADDZECC:       "addze.",
-	ADDZEO:        "addzeo",
-	ADDZEOCC:      "addzeo.",
-	SUBFZE:        "subfze",
-	SUBFZECC:      "subfze.",
-	SUBFZEO:       "subfzeo",
-	SUBFZEOCC:     "subfzeo.",
-	NEG:           "neg",
-	NEGCC:         "neg.",
-	NEGO:          "nego",
-	NEGOCC:        "nego.",
-	MULLI:         "mulli",
-	MULLW:         "mullw",
-	MULLWCC:       "mullw.",
-	MULLWO:        "mullwo",
-	MULLWOCC:      "mullwo.",
-	MULHW:         "mulhw",
-	MULHWCC:       "mulhw.",
-	MULHWU:        "mulhwu",
-	MULHWUCC:      "mulhwu.",
-	DIVW:          "divw",
-	DIVWCC:        "divw.",
-	DIVWO:         "divwo",
-	DIVWOCC:       "divwo.",
-	DIVWU:         "divwu",
-	DIVWUCC:       "divwu.",
-	DIVWUO:        "divwuo",
-	DIVWUOCC:      "divwuo.",
-	DIVWE:         "divwe",
-	DIVWECC:       "divwe.",
-	DIVWEO:        "divweo",
-	DIVWEOCC:      "divweo.",
-	DIVWEU:        "divweu",
-	DIVWEUCC:      "divweu.",
-	DIVWEUO:       "divweuo",
-	DIVWEUOCC:     "divweuo.",
-	MULLD:         "mulld",
-	MULLDCC:       "mulld.",
-	MULLDO:        "mulldo",
-	MULLDOCC:      "mulldo.",
-	MULHDU:        "mulhdu",
-	MULHDUCC:      "mulhdu.",
-	MULHD:         "mulhd",
-	MULHDCC:       "mulhd.",
-	DIVD:          "divd",
-	DIVDCC:        "divd.",
-	DIVDO:         "divdo",
-	DIVDOCC:       "divdo.",
-	DIVDU:         "divdu",
-	DIVDUCC:       "divdu.",
-	DIVDUO:        "divduo",
-	DIVDUOCC:      "divduo.",
-	DIVDE:         "divde",
-	DIVDECC:       "divde.",
-	DIVDEO:        "divdeo",
-	DIVDEOCC:      "divdeo.",
-	DIVDEU:        "divdeu",
-	DIVDEUCC:      "divdeu.",
-	DIVDEUO:       "divdeuo",
-	DIVDEUOCC:     "divdeuo.",
-	MODSD:         "modsd",
-	MODUD:         "modud",
-	MODSW:         "modsw",
-	MODUW:         "moduw",
-	CMPWI:         "cmpwi",
-	CMPDI:         "cmpdi",
-	CMPW:          "cmpw",
-	CMPD:          "cmpd",
-	CMPLWI:        "cmplwi",
-	CMPLDI:        "cmpldi",
-	CMPLW:         "cmplw",
-	CMPLD:         "cmpld",
-	TWI:           "twi",
-	TW:            "tw",
-	TDI:           "tdi",
-	ISEL:          "isel",
-	TD:            "td",
-	ANDICC:        "andi.",
-	ANDISCC:       "andis.",
-	ORI:           "ori",
-	ORIS:          "oris",
-	XORI:          "xori",
-	XORIS:         "xoris",
-	AND:           "and",
-	ANDCC:         "and.",
-	XOR:           "xor",
-	XORCC:         "xor.",
-	NAND:          "nand",
-	NANDCC:        "nand.",
-	OR:            "or",
-	ORCC:          "or.",
-	NOR:           "nor",
-	NORCC:         "nor.",
-	ANDC:          "andc",
-	ANDCCC:        "andc.",
-	EXTSB:         "extsb",
-	EXTSBCC:       "extsb.",
-	EQV:           "eqv",
-	EQVCC:         "eqv.",
-	ORC:           "orc",
-	ORCCC:         "orc.",
-	EXTSH:         "extsh",
-	EXTSHCC:       "extsh.",
-	CMPB:          "cmpb",
-	POPCNTB:       "popcntb",
-	POPCNTW:       "popcntw",
-	PRTYD:         "prtyd",
-	PRTYW:         "prtyw",
-	EXTSW:         "extsw",
-	EXTSWCC:       "extsw.",
-	CNTLZD:        "cntlzd",
-	CNTLZDCC:      "cntlzd.",
-	POPCNTD:       "popcntd",
-	BPERMD:        "bpermd",
-	RLWINM:        "rlwinm",
-	RLWINMCC:      "rlwinm.",
-	RLWNM:         "rlwnm",
-	RLWNMCC:       "rlwnm.",
-	RLWIMI:        "rlwimi",
-	RLWIMICC:      "rlwimi.",
-	RLDICL:        "rldicl",
-	RLDICLCC:      "rldicl.",
-	RLDICR:        "rldicr",
-	RLDICRCC:      "rldicr.",
-	RLDIC:         "rldic",
-	RLDICCC:       "rldic.",
-	RLDCL:         "rldcl",
-	RLDCLCC:       "rldcl.",
-	RLDCR:         "rldcr",
-	RLDCRCC:       "rldcr.",
-	RLDIMI:        "rldimi",
-	RLDIMICC:      "rldimi.",
-	SLW:           "slw",
-	SLWCC:         "slw.",
-	SRW:           "srw",
-	SRWCC:         "srw.",
-	SRAWI:         "srawi",
-	SRAWICC:       "srawi.",
-	SRAW:          "sraw",
-	SRAWCC:        "sraw.",
-	SLD:           "sld",
-	SLDCC:         "sld.",
-	SRD:           "srd",
-	SRDCC:         "srd.",
-	SRADI:         "sradi",
-	SRADICC:       "sradi.",
-	SRAD:          "srad",
-	SRADCC:        "srad.",
-	CDTBCD:        "cdtbcd",
-	CBCDTD:        "cbcdtd",
-	ADDG6S:        "addg6s",
-	MTSPR:         "mtspr",
-	MFSPR:         "mfspr",
-	MTCRF:         "mtcrf",
-	MFCR:          "mfcr",
-	MTSLE:         "mtsle",
-	MFVSRD:        "mfvsrd",
-	MFVSRWZ:       "mfvsrwz",
-	MTVSRD:        "mtvsrd",
-	MTVSRWA:       "mtvsrwa",
-	MTVSRWZ:       "mtvsrwz",
-	MTOCRF:        "mtocrf",
-	MFOCRF:        "mfocrf",
-	MCRXR:         "mcrxr",
-	MTDCRUX:       "mtdcrux",
-	MFDCRUX:       "mfdcrux",
-	LFS:           "lfs",
-	LFSU:          "lfsu",
-	LFSX:          "lfsx",
-	LFSUX:         "lfsux",
-	LFD:           "lfd",
-	LFDU:          "lfdu",
-	LFDX:          "lfdx",
-	LFDUX:         "lfdux",
-	LFIWAX:        "lfiwax",
-	LFIWZX:        "lfiwzx",
-	STFS:          "stfs",
-	STFSU:         "stfsu",
-	STFSX:         "stfsx",
-	STFSUX:        "stfsux",
-	STFD:          "stfd",
-	STFDU:         "stfdu",
-	STFDX:         "stfdx",
-	STFDUX:        "stfdux",
-	STFIWX:        "stfiwx",
-	LFDP:          "lfdp",
-	LFDPX:         "lfdpx",
-	STFDP:         "stfdp",
-	STFDPX:        "stfdpx",
-	FMR:           "fmr",
-	FMRCC:         "fmr.",
-	FABS:          "fabs",
-	FABSCC:        "fabs.",
-	FNABS:         "fnabs",
-	FNABSCC:       "fnabs.",
-	FNEG:          "fneg",
-	FNEGCC:        "fneg.",
-	FCPSGN:        "fcpsgn",
-	FCPSGNCC:      "fcpsgn.",
-	FMRGEW:        "fmrgew",
-	FMRGOW:        "fmrgow",
-	FADD:          "fadd",
-	FADDCC:        "fadd.",
-	FADDS:         "fadds",
-	FADDSCC:       "fadds.",
-	FSUB:          "fsub",
-	FSUBCC:        "fsub.",
-	FSUBS:         "fsubs",
-	FSUBSCC:       "fsubs.",
-	FMUL:          "fmul",
-	FMULCC:        "fmul.",
-	FMULS:         "fmuls",
-	FMULSCC:       "fmuls.",
-	FDIV:          "fdiv",
-	FDIVCC:        "fdiv.",
-	FDIVS:         "fdivs",
-	FDIVSCC:       "fdivs.",
-	FSQRT:         "fsqrt",
-	FSQRTCC:       "fsqrt.",
-	FSQRTS:        "fsqrts",
-	FSQRTSCC:      "fsqrts.",
-	FRE:           "fre",
-	FRECC:         "fre.",
-	FRES:          "fres",
-	FRESCC:        "fres.",
-	FRSQRTE:       "frsqrte",
-	FRSQRTECC:     "frsqrte.",
-	FRSQRTES:      "frsqrtes",
-	FRSQRTESCC:    "frsqrtes.",
-	FTDIV:         "ftdiv",
-	FTSQRT:        "ftsqrt",
-	FMADD:         "fmadd",
-	FMADDCC:       "fmadd.",
-	FMADDS:        "fmadds",
-	FMADDSCC:      "fmadds.",
-	FMSUB:         "fmsub",
-	FMSUBCC:       "fmsub.",
-	FMSUBS:        "fmsubs",
-	FMSUBSCC:      "fmsubs.",
-	FNMADD:        "fnmadd",
-	FNMADDCC:      "fnmadd.",
-	FNMADDS:       "fnmadds",
-	FNMADDSCC:     "fnmadds.",
-	FNMSUB:        "fnmsub",
-	FNMSUBCC:      "fnmsub.",
-	FNMSUBS:       "fnmsubs",
-	FNMSUBSCC:     "fnmsubs.",
-	FRSP:          "frsp",
-	FRSPCC:        "frsp.",
-	FCTID:         "fctid",
-	FCTIDCC:       "fctid.",
-	FCTIDZ:        "fctidz",
-	FCTIDZCC:      "fctidz.",
-	FCTIDU:        "fctidu",
-	FCTIDUCC:      "fctidu.",
-	FCTIDUZ:       "fctiduz",
-	FCTIDUZCC:     "fctiduz.",
-	FCTIW:         "fctiw",
-	FCTIWCC:       "fctiw.",
-	FCTIWZ:        "fctiwz",
-	FCTIWZCC:      "fctiwz.",
-	FCTIWU:        "fctiwu",
-	FCTIWUCC:      "fctiwu.",
-	FCTIWUZ:       "fctiwuz",
-	FCTIWUZCC:     "fctiwuz.",
-	FCFID:         "fcfid",
-	FCFIDCC:       "fcfid.",
-	FCFIDU:        "fcfidu",
-	FCFIDUCC:      "fcfidu.",
-	FCFIDS:        "fcfids",
-	FCFIDSCC:      "fcfids.",
-	FCFIDUS:       "fcfidus",
-	FCFIDUSCC:     "fcfidus.",
-	FRIN:          "frin",
-	FRINCC:        "frin.",
-	FRIZ:          "friz",
-	FRIZCC:        "friz.",
-	FRIP:          "frip",
-	FRIPCC:        "frip.",
-	FRIM:          "frim",
-	FRIMCC:        "frim.",
-	FCMPU:         "fcmpu",
-	FCMPO:         "fcmpo",
-	FSEL:          "fsel",
-	FSELCC:        "fsel.",
-	MFFS:          "mffs",
-	MFFSCC:        "mffs.",
-	MCRFS:         "mcrfs",
-	MTFSFI:        "mtfsfi",
-	MTFSFICC:      "mtfsfi.",
-	MTFSF:         "mtfsf",
-	MTFSFCC:       "mtfsf.",
-	MTFSB0:        "mtfsb0",
-	MTFSB0CC:      "mtfsb0.",
-	MTFSB1:        "mtfsb1",
-	MTFSB1CC:      "mtfsb1.",
-	LVEBX:         "lvebx",
-	LVEHX:         "lvehx",
-	LVEWX:         "lvewx",
-	LVX:           "lvx",
-	LVXL:          "lvxl",
-	STVEBX:        "stvebx",
-	STVEHX:        "stvehx",
-	STVEWX:        "stvewx",
-	STVX:          "stvx",
-	STVXL:         "stvxl",
-	LVSL:          "lvsl",
-	LVSR:          "lvsr",
-	VPKPX:         "vpkpx",
-	VPKSDSS:       "vpksdss",
-	VPKSDUS:       "vpksdus",
-	VPKSHSS:       "vpkshss",
-	VPKSHUS:       "vpkshus",
-	VPKSWSS:       "vpkswss",
-	VPKSWUS:       "vpkswus",
-	VPKUDUM:       "vpkudum",
-	VPKUDUS:       "vpkudus",
-	VPKUHUM:       "vpkuhum",
-	VPKUHUS:       "vpkuhus",
-	VPKUWUM:       "vpkuwum",
-	VPKUWUS:       "vpkuwus",
-	VUPKHPX:       "vupkhpx",
-	VUPKLPX:       "vupklpx",
-	VUPKHSB:       "vupkhsb",
-	VUPKHSH:       "vupkhsh",
-	VUPKHSW:       "vupkhsw",
-	VUPKLSB:       "vupklsb",
-	VUPKLSH:       "vupklsh",
-	VUPKLSW:       "vupklsw",
-	VMRGHB:        "vmrghb",
-	VMRGHH:        "vmrghh",
-	VMRGLB:        "vmrglb",
-	VMRGLH:        "vmrglh",
-	VMRGHW:        "vmrghw",
-	VMRGLW:        "vmrglw",
-	VMRGEW:        "vmrgew",
-	VMRGOW:        "vmrgow",
-	VSPLTB:        "vspltb",
-	VSPLTH:        "vsplth",
-	VSPLTW:        "vspltw",
-	VSPLTISB:      "vspltisb",
-	VSPLTISH:      "vspltish",
-	VSPLTISW:      "vspltisw",
-	VPERM:         "vperm",
-	VPERMR:        "vpermr",
-	VSEL:          "vsel",
-	VSL:           "vsl",
-	VSLDOI:        "vsldoi",
-	VSLO:          "vslo",
-	VSR:           "vsr",
-	VSRO:          "vsro",
-	VADDCUW:       "vaddcuw",
-	VADDSBS:       "vaddsbs",
-	VADDSHS:       "vaddshs",
-	VADDSWS:       "vaddsws",
-	VADDUBM:       "vaddubm",
-	VADDUDM:       "vaddudm",
-	VADDUHM:       "vadduhm",
-	VADDUWM:       "vadduwm",
-	VADDUBS:       "vaddubs",
-	VADDUHS:       "vadduhs",
-	VADDUWS:       "vadduws",
-	VADDUQM:       "vadduqm",
-	VADDEUQM:      "vaddeuqm",
-	VADDCUQ:       "vaddcuq",
-	VADDECUQ:      "vaddecuq",
-	VSUBCUW:       "vsubcuw",
-	VSUBSBS:       "vsubsbs",
-	VSUBSHS:       "vsubshs",
-	VSUBSWS:       "vsubsws",
-	VSUBUBM:       "vsububm",
-	VSUBUDM:       "vsubudm",
-	VSUBUHM:       "vsubuhm",
-	VSUBUWM:       "vsubuwm",
-	VSUBUBS:       "vsububs",
-	VSUBUHS:       "vsubuhs",
-	VSUBUWS:       "vsubuws",
-	VSUBUQM:       "vsubuqm",
-	VSUBEUQM:      "vsubeuqm",
-	VSUBCUQ:       "vsubcuq",
-	VSUBECUQ:      "vsubecuq",
-	VMULESB:       "vmulesb",
-	VMULEUB:       "vmuleub",
-	VMULOSB:       "vmulosb",
-	VMULOUB:       "vmuloub",
-	VMULESH:       "vmulesh",
-	VMULEUH:       "vmuleuh",
-	VMULOSH:       "vmulosh",
-	VMULOUH:       "vmulouh",
-	VMULESW:       "vmulesw",
-	VMULEUW:       "vmuleuw",
-	VMULOSW:       "vmulosw",
-	VMULOUW:       "vmulouw",
-	VMULUWM:       "vmuluwm",
-	VMHADDSHS:     "vmhaddshs",
-	VMHRADDSHS:    "vmhraddshs",
-	VMLADDUHM:     "vmladduhm",
-	VMSUMUBM:      "vmsumubm",
-	VMSUMMBM:      "vmsummbm",
-	VMSUMSHM:      "vmsumshm",
-	VMSUMSHS:      "vmsumshs",
-	VMSUMUHM:      "vmsumuhm",
-	VMSUMUHS:      "vmsumuhs",
-	VMSUMUDM:      "vmsumudm",
-	VSUMSWS:       "vsumsws",
-	VSUM2SWS:      "vsum2sws",
-	VSUM4SBS:      "vsum4sbs",
-	VSUM4SHS:      "vsum4shs",
-	VSUM4UBS:      "vsum4ubs",
-	VAVGSB:        "vavgsb",
-	VAVGSH:        "vavgsh",
-	VAVGSW:        "vavgsw",
-	VAVGUB:        "vavgub",
-	VAVGUW:        "vavguw",
-	VAVGUH:        "vavguh",
-	VMAXSB:        "vmaxsb",
-	VMAXSD:        "vmaxsd",
-	VMAXUB:        "vmaxub",
-	VMAXUD:        "vmaxud",
-	VMAXSH:        "vmaxsh",
-	VMAXSW:        "vmaxsw",
-	VMAXUH:        "vmaxuh",
-	VMAXUW:        "vmaxuw",
-	VMINSB:        "vminsb",
-	VMINSD:        "vminsd",
-	VMINUB:        "vminub",
-	VMINUD:        "vminud",
-	VMINSH:        "vminsh",
-	VMINSW:        "vminsw",
-	VMINUH:        "vminuh",
-	VMINUW:        "vminuw",
-	VCMPEQUB:      "vcmpequb",
-	VCMPEQUBCC:    "vcmpequb.",
-	VCMPEQUH:      "vcmpequh",
-	VCMPEQUHCC:    "vcmpequh.",
-	VCMPEQUW:      "vcmpequw",
-	VCMPEQUWCC:    "vcmpequw.",
-	VCMPEQUD:      "vcmpequd",
-	VCMPEQUDCC:    "vcmpequd.",
-	VCMPNEB:       "vcmpneb",
-	VCMPNEBCC:     "vcmpneb.",
-	VCMPNEZB:      "vcmpnezb",
-	VCMPNEZBCC:    "vcmpnezb.",
-	VCMPNEH:       "vcmpneh",
-	VCMPNEHCC:     "vcmpneh.",
-	VCMPNEZH:      "vcmpnezh",
-	VCMPNEZHCC:    "vcmpnezh.",
-	VCMPNEW:       "vcmpnew",
-	VCMPNEWCC:     "vcmpnew.",
-	VCMPNEZW:      "vcmpnezw",
-	VCMPNEZWCC:    "vcmpnezw.",
-	VCMPGTSB:      "vcmpgtsb",
-	VCMPGTSBCC:    "vcmpgtsb.",
-	VCMPGTSD:      "vcmpgtsd",
-	VCMPGTSDCC:    "vcmpgtsd.",
-	VCMPGTSH:      "vcmpgtsh",
-	VCMPGTSHCC:    "vcmpgtsh.",
-	VCMPGTSW:      "vcmpgtsw",
-	VCMPGTSWCC:    "vcmpgtsw.",
-	VCMPGTUB:      "vcmpgtub",
-	VCMPGTUBCC:    "vcmpgtub.",
-	VCMPGTUD:      "vcmpgtud",
-	VCMPGTUDCC:    "vcmpgtud.",
-	VCMPGTUH:      "vcmpgtuh",
-	VCMPGTUHCC:    "vcmpgtuh.",
-	VCMPGTUW:      "vcmpgtuw",
-	VCMPGTUWCC:    "vcmpgtuw.",
-	VAND:          "vand",
-	VANDC:         "vandc",
-	VEQV:          "veqv",
-	VNAND:         "vnand",
-	VORC:          "vorc",
-	VNOR:          "vnor",
-	VOR:           "vor",
-	VXOR:          "vxor",
-	VRLB:          "vrlb",
-	VRLH:          "vrlh",
-	VRLW:          "vrlw",
-	VRLD:          "vrld",
-	VSLB:          "vslb",
-	VSLH:          "vslh",
-	VSLW:          "vslw",
-	VSLD:          "vsld",
-	VSRB:          "vsrb",
-	VSRH:          "vsrh",
-	VSRW:          "vsrw",
-	VSRD:          "vsrd",
-	VSRAB:         "vsrab",
-	VSRAH:         "vsrah",
-	VSRAW:         "vsraw",
-	VSRAD:         "vsrad",
-	VADDFP:        "vaddfp",
-	VSUBFP:        "vsubfp",
-	VMADDFP:       "vmaddfp",
-	VNMSUBFP:      "vnmsubfp",
-	VMAXFP:        "vmaxfp",
-	VMINFP:        "vminfp",
-	VCTSXS:        "vctsxs",
-	VCTUXS:        "vctuxs",
-	VCFSX:         "vcfsx",
-	VCFUX:         "vcfux",
-	VRFIM:         "vrfim",
-	VRFIN:         "vrfin",
-	VRFIP:         "vrfip",
-	VRFIZ:         "vrfiz",
-	VCMPBFP:       "vcmpbfp",
-	VCMPBFPCC:     "vcmpbfp.",
-	VCMPEQFP:      "vcmpeqfp",
-	VCMPEQFPCC:    "vcmpeqfp.",
-	VCMPGEFP:      "vcmpgefp",
-	VCMPGEFPCC:    "vcmpgefp.",
-	VCMPGTFP:      "vcmpgtfp",
-	VCMPGTFPCC:    "vcmpgtfp.",
-	VEXPTEFP:      "vexptefp",
-	VLOGEFP:       "vlogefp",
-	VREFP:         "vrefp",
-	VRSQRTEFP:     "vrsqrtefp",
-	VCIPHER:       "vcipher",
-	VCIPHERLAST:   "vcipherlast",
-	VNCIPHER:      "vncipher",
-	VNCIPHERLAST:  "vncipherlast",
-	VSBOX:         "vsbox",
-	VSHASIGMAD:    "vshasigmad",
-	VSHASIGMAW:    "vshasigmaw",
-	VPMSUMB:       "vpmsumb",
-	VPMSUMD:       "vpmsumd",
-	VPMSUMH:       "vpmsumh",
-	VPMSUMW:       "vpmsumw",
-	VPERMXOR:      "vpermxor",
-	VGBBD:         "vgbbd",
-	VCLZB:         "vclzb",
-	VCLZH:         "vclzh",
-	VCLZW:         "vclzw",
-	VCLZD:         "vclzd",
-	VPOPCNTB:      "vpopcntb",
-	VPOPCNTD:      "vpopcntd",
-	VPOPCNTH:      "vpopcnth",
-	VPOPCNTW:      "vpopcntw",
-	VBPERMQ:       "vbpermq",
-	VBPERMD:       "vbpermd",
-	BCDADDCC:      "bcdadd.",
-	BCDSUBCC:      "bcdsub.",
-	MTVSCR:        "mtvscr",
-	MFVSCR:        "mfvscr",
-	DADD:          "dadd",
-	DADDCC:        "dadd.",
-	DSUB:          "dsub",
-	DSUBCC:        "dsub.",
-	DMUL:          "dmul",
-	DMULCC:        "dmul.",
-	DDIV:          "ddiv",
-	DDIVCC:        "ddiv.",
-	DCMPU:         "dcmpu",
-	DCMPO:         "dcmpo",
-	DTSTDC:        "dtstdc",
-	DTSTDG:        "dtstdg",
-	DTSTEX:        "dtstex",
-	DTSTSF:        "dtstsf",
-	DQUAI:         "dquai",
-	DQUAICC:       "dquai.",
-	DQUA:          "dqua",
-	DQUACC:        "dqua.",
-	DRRND:         "drrnd",
-	DRRNDCC:       "drrnd.",
-	DRINTX:        "drintx",
-	DRINTXCC:      "drintx.",
-	DRINTN:        "drintn",
-	DRINTNCC:      "drintn.",
-	DCTDP:         "dctdp",
-	DCTDPCC:       "dctdp.",
-	DCTQPQ:        "dctqpq",
-	DCTQPQCC:      "dctqpq.",
-	DRSP:          "drsp",
-	DRSPCC:        "drsp.",
-	DRDPQ:         "drdpq",
-	DRDPQCC:       "drdpq.",
-	DCFFIX:        "dcffix",
-	DCFFIXCC:      "dcffix.",
-	DCFFIXQ:       "dcffixq",
-	DCFFIXQCC:     "dcffixq.",
-	DCTFIX:        "dctfix",
-	DCTFIXCC:      "dctfix.",
-	DDEDPD:        "ddedpd",
-	DDEDPDCC:      "ddedpd.",
-	DENBCD:        "denbcd",
-	DENBCDCC:      "denbcd.",
-	DXEX:          "dxex",
-	DXEXCC:        "dxex.",
-	DIEX:          "diex",
-	DIEXCC:        "diex.",
-	DSCLI:         "dscli",
-	DSCLICC:       "dscli.",
-	DSCRI:         "dscri",
-	DSCRICC:       "dscri.",
-	LXSDX:         "lxsdx",
-	LXSIWAX:       "lxsiwax",
-	LXSIWZX:       "lxsiwzx",
-	LXSSPX:        "lxsspx",
-	LXVD2X:        "lxvd2x",
-	LXVDSX:        "lxvdsx",
-	LXVW4X:        "lxvw4x",
-	LXVH8X:        "lxvh8x",
-	LXVB16X:       "lxvb16x",
-	LXV:           "lxv",
-	LXVL:          "lxvl",
-	LXVLL:         "lxvll",
-	LXVX:          "lxvx",
-	STXSDX:        "stxsdx",
-	STXSIWX:       "stxsiwx",
-	STXSSPX:       "stxsspx",
-	STXVD2X:       "stxvd2x",
-	STXVW4X:       "stxvw4x",
-	STXVH8X:       "stxvh8x",
-	STXVB16X:      "stxvb16x",
-	STXV:          "stxv",
-	STXVL:         "stxvl",
-	STXVLL:        "stxvll",
-	STXVX:         "stxvx",
-	XSABSDP:       "xsabsdp",
-	XSADDDP:       "xsadddp",
-	XSADDSP:       "xsaddsp",
-	XSCMPODP:      "xscmpodp",
-	XSCMPUDP:      "xscmpudp",
-	XSCPSGNDP:     "xscpsgndp",
-	XSCVDPSP:      "xscvdpsp",
-	XSCVDPSPN:     "xscvdpspn",
-	XSCVDPSXDS:    "xscvdpsxds",
-	XSCVDPSXWS:    "xscvdpsxws",
-	XSCVDPUXDS:    "xscvdpuxds",
-	XSCVDPUXWS:    "xscvdpuxws",
-	XSCVSPDP:      "xscvspdp",
-	XSCVSPDPN:     "xscvspdpn",
-	XSCVSXDDP:     "xscvsxddp",
-	XSCVSXDSP:     "xscvsxdsp",
-	XSCVUXDDP:     "xscvuxddp",
-	XSCVUXDSP:     "xscvuxdsp",
-	XSDIVDP:       "xsdivdp",
-	XSDIVSP:       "xsdivsp",
-	XSMADDADP:     "xsmaddadp",
-	XSMADDASP:     "xsmaddasp",
-	XSMAXDP:       "xsmaxdp",
-	XSMINDP:       "xsmindp",
-	XSMSUBADP:     "xsmsubadp",
-	XSMSUBASP:     "xsmsubasp",
-	XSMULDP:       "xsmuldp",
-	XSMULSP:       "xsmulsp",
-	XSNABSDP:      "xsnabsdp",
-	XSNEGDP:       "xsnegdp",
-	XSNMADDADP:    "xsnmaddadp",
-	XSNMADDASP:    "xsnmaddasp",
-	XSNMSUBADP:    "xsnmsubadp",
-	XSNMSUBASP:    "xsnmsubasp",
-	XSRDPI:        "xsrdpi",
-	XSRDPIC:       "xsrdpic",
-	XSRDPIM:       "xsrdpim",
-	XSRDPIP:       "xsrdpip",
-	XSRDPIZ:       "xsrdpiz",
-	XSREDP:        "xsredp",
-	XSRESP:        "xsresp",
-	XSRSP:         "xsrsp",
-	XSRSQRTEDP:    "xsrsqrtedp",
-	XSRSQRTESP:    "xsrsqrtesp",
-	XSSQRTDP:      "xssqrtdp",
-	XSSQRTSP:      "xssqrtsp",
-	XSSUBDP:       "xssubdp",
-	XSSUBSP:       "xssubsp",
-	XSTDIVDP:      "xstdivdp",
-	XSTSQRTDP:     "xstsqrtdp",
-	XVABSDP:       "xvabsdp",
-	XVABSSP:       "xvabssp",
-	XVADDDP:       "xvadddp",
-	XVADDSP:       "xvaddsp",
-	XVCMPEQDP:     "xvcmpeqdp",
-	XVCMPEQDPCC:   "xvcmpeqdp.",
-	XVCMPEQSP:     "xvcmpeqsp",
-	XVCMPEQSPCC:   "xvcmpeqsp.",
-	XVCMPGEDP:     "xvcmpgedp",
-	XVCMPGEDPCC:   "xvcmpgedp.",
-	XVCMPGESP:     "xvcmpgesp",
-	XVCMPGESPCC:   "xvcmpgesp.",
-	XVCMPGTDP:     "xvcmpgtdp",
-	XVCMPGTDPCC:   "xvcmpgtdp.",
-	XVCMPGTSP:     "xvcmpgtsp",
-	XVCMPGTSPCC:   "xvcmpgtsp.",
-	XVCPSGNDP:     "xvcpsgndp",
-	XVCPSGNSP:     "xvcpsgnsp",
-	XVCVDPSP:      "xvcvdpsp",
-	XVCVDPSXDS:    "xvcvdpsxds",
-	XVCVDPSXWS:    "xvcvdpsxws",
-	XVCVDPUXDS:    "xvcvdpuxds",
-	XVCVDPUXWS:    "xvcvdpuxws",
-	XVCVSPDP:      "xvcvspdp",
-	XVCVSPSXDS:    "xvcvspsxds",
-	XVCVSPSXWS:    "xvcvspsxws",
-	XVCVSPUXDS:    "xvcvspuxds",
-	XVCVSPUXWS:    "xvcvspuxws",
-	XVCVSXDDP:     "xvcvsxddp",
-	XVCVSXDSP:     "xvcvsxdsp",
-	XVCVSXWDP:     "xvcvsxwdp",
-	XVCVSXWSP:     "xvcvsxwsp",
-	XVCVUXDDP:     "xvcvuxddp",
-	XVCVUXDSP:     "xvcvuxdsp",
-	XVCVUXWDP:     "xvcvuxwdp",
-	XVCVUXWSP:     "xvcvuxwsp",
-	XVDIVDP:       "xvdivdp",
-	XVDIVSP:       "xvdivsp",
-	XVMADDADP:     "xvmaddadp",
-	XVMADDASP:     "xvmaddasp",
-	XVMAXDP:       "xvmaxdp",
-	XVMAXSP:       "xvmaxsp",
-	XVMINDP:       "xvmindp",
-	XVMINSP:       "xvminsp",
-	XVMSUBADP:     "xvmsubadp",
-	XVMSUBASP:     "xvmsubasp",
-	XVMULDP:       "xvmuldp",
-	XVMULSP:       "xvmulsp",
-	XVNABSDP:      "xvnabsdp",
-	XVNABSSP:      "xvnabssp",
-	XVNEGDP:       "xvnegdp",
-	XVNEGSP:       "xvnegsp",
-	XVNMADDADP:    "xvnmaddadp",
-	XVNMADDASP:    "xvnmaddasp",
-	XVNMSUBADP:    "xvnmsubadp",
-	XVNMSUBASP:    "xvnmsubasp",
-	XVRDPI:        "xvrdpi",
-	XVRDPIC:       "xvrdpic",
-	XVRDPIM:       "xvrdpim",
-	XVRDPIP:       "xvrdpip",
-	XVRDPIZ:       "xvrdpiz",
-	XVREDP:        "xvredp",
-	XVRESP:        "xvresp",
-	XVRSPI:        "xvrspi",
-	XVRSPIC:       "xvrspic",
-	XVRSPIM:       "xvrspim",
-	XVRSPIP:       "xvrspip",
-	XVRSPIZ:       "xvrspiz",
-	XVRSQRTEDP:    "xvrsqrtedp",
-	XVRSQRTESP:    "xvrsqrtesp",
-	XVSQRTDP:      "xvsqrtdp",
-	XVSQRTSP:      "xvsqrtsp",
-	XVSUBDP:       "xvsubdp",
-	XVSUBSP:       "xvsubsp",
-	XVTDIVDP:      "xvtdivdp",
-	XVTDIVSP:      "xvtdivsp",
-	XVTSQRTDP:     "xvtsqrtdp",
-	XVTSQRTSP:     "xvtsqrtsp",
-	XXLAND:        "xxland",
-	XXLANDC:       "xxlandc",
-	XXLEQV:        "xxleqv",
-	XXLNAND:       "xxlnand",
-	XXLORC:        "xxlorc",
-	XXLNOR:        "xxlnor",
-	XXLOR:         "xxlor",
-	XXLXOR:        "xxlxor",
-	XXMRGHW:       "xxmrghw",
-	XXMRGLW:       "xxmrglw",
-	XXPERMDI:      "xxpermdi",
-	XXPERM:        "xxperm",
-	XXSEL:         "xxsel",
-	XXSLDWI:       "xxsldwi",
-	XXSPLTW:       "xxspltw",
-	XXBRD:         "xxbrd",
-	XXBRW:         "xxbrw",
-	XXBRH:         "xxbrh",
-	BRINC:         "brinc",
-	EVABS:         "evabs",
-	EVADDIW:       "evaddiw",
-	EVADDSMIAAW:   "evaddsmiaaw",
-	EVADDSSIAAW:   "evaddssiaaw",
-	EVADDUMIAAW:   "evaddumiaaw",
-	EVADDUSIAAW:   "evaddusiaaw",
-	EVADDW:        "evaddw",
-	EVAND:         "evand",
-	EVCMPEQ:       "evcmpeq",
-	EVANDC:        "evandc",
-	EVCMPGTS:      "evcmpgts",
-	EVCMPGTU:      "evcmpgtu",
-	EVCMPLTU:      "evcmpltu",
-	EVCMPLTS:      "evcmplts",
-	EVCNTLSW:      "evcntlsw",
-	EVCNTLZW:      "evcntlzw",
-	EVDIVWS:       "evdivws",
-	EVDIVWU:       "evdivwu",
-	EVEQV:         "eveqv",
-	EVEXTSB:       "evextsb",
-	EVEXTSH:       "evextsh",
-	EVLDD:         "evldd",
-	EVLDH:         "evldh",
-	EVLDDX:        "evlddx",
-	EVLDHX:        "evldhx",
-	EVLDW:         "evldw",
-	EVLHHESPLAT:   "evlhhesplat",
-	EVLDWX:        "evldwx",
-	EVLHHESPLATX:  "evlhhesplatx",
-	EVLHHOSSPLAT:  "evlhhossplat",
-	EVLHHOUSPLAT:  "evlhhousplat",
-	EVLHHOSSPLATX: "evlhhossplatx",
-	EVLHHOUSPLATX: "evlhhousplatx",
-	EVLWHE:        "evlwhe",
-	EVLWHOS:       "evlwhos",
-	EVLWHEX:       "evlwhex",
-	EVLWHOSX:      "evlwhosx",
-	EVLWHOU:       "evlwhou",
-	EVLWHSPLAT:    "evlwhsplat",
-	EVLWHOUX:      "evlwhoux",
-	EVLWHSPLATX:   "evlwhsplatx",
-	EVLWWSPLAT:    "evlwwsplat",
-	EVMERGEHI:     "evmergehi",
-	EVLWWSPLATX:   "evlwwsplatx",
-	EVMERGELO:     "evmergelo",
-	EVMERGEHILO:   "evmergehilo",
-	EVMHEGSMFAA:   "evmhegsmfaa",
-	EVMERGELOHI:   "evmergelohi",
-	EVMHEGSMFAN:   "evmhegsmfan",
-	EVMHEGSMIAA:   "evmhegsmiaa",
-	EVMHEGUMIAA:   "evmhegumiaa",
-	EVMHEGSMIAN:   "evmhegsmian",
-	EVMHEGUMIAN:   "evmhegumian",
-	EVMHESMF:      "evmhesmf",
-	EVMHESMFAAW:   "evmhesmfaaw",
-	EVMHESMFA:     "evmhesmfa",
-	EVMHESMFANW:   "evmhesmfanw",
-	EVMHESMI:      "evmhesmi",
-	EVMHESMIAAW:   "evmhesmiaaw",
-	EVMHESMIA:     "evmhesmia",
-	EVMHESMIANW:   "evmhesmianw",
-	EVMHESSF:      "evmhessf",
-	EVMHESSFA:     "evmhessfa",
-	EVMHESSFAAW:   "evmhessfaaw",
-	EVMHESSFANW:   "evmhessfanw",
-	EVMHESSIAAW:   "evmhessiaaw",
-	EVMHESSIANW:   "evmhessianw",
-	EVMHEUMI:      "evmheumi",
-	EVMHEUMIAAW:   "evmheumiaaw",
-	EVMHEUMIA:     "evmheumia",
-	EVMHEUMIANW:   "evmheumianw",
-	EVMHEUSIAAW:   "evmheusiaaw",
-	EVMHEUSIANW:   "evmheusianw",
-	EVMHOGSMFAA:   "evmhogsmfaa",
-	EVMHOGSMIAA:   "evmhogsmiaa",
-	EVMHOGSMFAN:   "evmhogsmfan",
-	EVMHOGSMIAN:   "evmhogsmian",
-	EVMHOGUMIAA:   "evmhogumiaa",
-	EVMHOSMF:      "evmhosmf",
-	EVMHOGUMIAN:   "evmhogumian",
-	EVMHOSMFA:     "evmhosmfa",
-	EVMHOSMFAAW:   "evmhosmfaaw",
-	EVMHOSMI:      "evmhosmi",
-	EVMHOSMFANW:   "evmhosmfanw",
-	EVMHOSMIA:     "evmhosmia",
-	EVMHOSMIAAW:   "evmhosmiaaw",
-	EVMHOSMIANW:   "evmhosmianw",
-	EVMHOSSF:      "evmhossf",
-	EVMHOSSFA:     "evmhossfa",
-	EVMHOSSFAAW:   "evmhossfaaw",
-	EVMHOSSFANW:   "evmhossfanw",
-	EVMHOSSIAAW:   "evmhossiaaw",
-	EVMHOUMI:      "evmhoumi",
-	EVMHOSSIANW:   "evmhossianw",
-	EVMHOUMIA:     "evmhoumia",
-	EVMHOUMIAAW:   "evmhoumiaaw",
-	EVMHOUSIAAW:   "evmhousiaaw",
-	EVMHOUMIANW:   "evmhoumianw",
-	EVMHOUSIANW:   "evmhousianw",
-	EVMRA:         "evmra",
-	EVMWHSMF:      "evmwhsmf",
-	EVMWHSMI:      "evmwhsmi",
-	EVMWHSMFA:     "evmwhsmfa",
-	EVMWHSMIA:     "evmwhsmia",
-	EVMWHSSF:      "evmwhssf",
-	EVMWHUMI:      "evmwhumi",
-	EVMWHSSFA:     "evmwhssfa",
-	EVMWHUMIA:     "evmwhumia",
-	EVMWLSMIAAW:   "evmwlsmiaaw",
-	EVMWLSSIAAW:   "evmwlssiaaw",
-	EVMWLSMIANW:   "evmwlsmianw",
-	EVMWLSSIANW:   "evmwlssianw",
-	EVMWLUMI:      "evmwlumi",
-	EVMWLUMIAAW:   "evmwlumiaaw",
-	EVMWLUMIA:     "evmwlumia",
-	EVMWLUMIANW:   "evmwlumianw",
-	EVMWLUSIAAW:   "evmwlusiaaw",
-	EVMWSMF:       "evmwsmf",
-	EVMWLUSIANW:   "evmwlusianw",
-	EVMWSMFA:      "evmwsmfa",
-	EVMWSMFAA:     "evmwsmfaa",
-	EVMWSMI:       "evmwsmi",
-	EVMWSMIAA:     "evmwsmiaa",
-	EVMWSMFAN:     "evmwsmfan",
-	EVMWSMIA:      "evmwsmia",
-	EVMWSMIAN:     "evmwsmian",
-	EVMWSSF:       "evmwssf",
-	EVMWSSFA:      "evmwssfa",
-	EVMWSSFAA:     "evmwssfaa",
-	EVMWUMI:       "evmwumi",
-	EVMWSSFAN:     "evmwssfan",
-	EVMWUMIA:      "evmwumia",
-	EVMWUMIAA:     "evmwumiaa",
-	EVNAND:        "evnand",
-	EVMWUMIAN:     "evmwumian",
-	EVNEG:         "evneg",
-	EVNOR:         "evnor",
-	EVORC:         "evorc",
-	EVOR:          "evor",
-	EVRLW:         "evrlw",
-	EVRLWI:        "evrlwi",
-	EVSEL:         "evsel",
-	EVRNDW:        "evrndw",
-	EVSLW:         "evslw",
-	EVSPLATFI:     "evsplatfi",
-	EVSRWIS:       "evsrwis",
-	EVSLWI:        "evslwi",
-	EVSPLATI:      "evsplati",
-	EVSRWIU:       "evsrwiu",
-	EVSRWS:        "evsrws",
-	EVSTDD:        "evstdd",
-	EVSRWU:        "evsrwu",
-	EVSTDDX:       "evstddx",
-	EVSTDH:        "evstdh",
-	EVSTDW:        "evstdw",
-	EVSTDHX:       "evstdhx",
-	EVSTDWX:       "evstdwx",
-	EVSTWHE:       "evstwhe",
-	EVSTWHO:       "evstwho",
-	EVSTWWE:       "evstwwe",
-	EVSTWHEX:      "evstwhex",
-	EVSTWHOX:      "evstwhox",
-	EVSTWWEX:      "evstwwex",
-	EVSTWWO:       "evstwwo",
-	EVSUBFSMIAAW:  "evsubfsmiaaw",
-	EVSTWWOX:      "evstwwox",
-	EVSUBFSSIAAW:  "evsubfssiaaw",
-	EVSUBFUMIAAW:  "evsubfumiaaw",
-	EVSUBFUSIAAW:  "evsubfusiaaw",
-	EVSUBFW:       "evsubfw",
-	EVSUBIFW:      "evsubifw",
-	EVXOR:         "evxor",
-	EVFSABS:       "evfsabs",
-	EVFSNABS:      "evfsnabs",
-	EVFSNEG:       "evfsneg",
-	EVFSADD:       "evfsadd",
-	EVFSMUL:       "evfsmul",
-	EVFSSUB:       "evfssub",
-	EVFSDIV:       "evfsdiv",
-	EVFSCMPGT:     "evfscmpgt",
-	EVFSCMPLT:     "evfscmplt",
-	EVFSCMPEQ:     "evfscmpeq",
-	EVFSTSTGT:     "evfststgt",
-	EVFSTSTLT:     "evfststlt",
-	EVFSTSTEQ:     "evfststeq",
-	EVFSCFSI:      "evfscfsi",
-	EVFSCFSF:      "evfscfsf",
-	EVFSCFUI:      "evfscfui",
-	EVFSCFUF:      "evfscfuf",
-	EVFSCTSI:      "evfsctsi",
-	EVFSCTUI:      "evfsctui",
-	EVFSCTSIZ:     "evfsctsiz",
-	EVFSCTUIZ:     "evfsctuiz",
-	EVFSCTSF:      "evfsctsf",
-	EVFSCTUF:      "evfsctuf",
-	EFSABS:        "efsabs",
-	EFSNEG:        "efsneg",
-	EFSNABS:       "efsnabs",
-	EFSADD:        "efsadd",
-	EFSMUL:        "efsmul",
-	EFSSUB:        "efssub",
-	EFSDIV:        "efsdiv",
-	EFSCMPGT:      "efscmpgt",
-	EFSCMPLT:      "efscmplt",
-	EFSCMPEQ:      "efscmpeq",
-	EFSTSTGT:      "efststgt",
-	EFSTSTLT:      "efststlt",
-	EFSTSTEQ:      "efststeq",
-	EFSCFSI:       "efscfsi",
-	EFSCFSF:       "efscfsf",
-	EFSCTSI:       "efsctsi",
-	EFSCFUI:       "efscfui",
-	EFSCFUF:       "efscfuf",
-	EFSCTUI:       "efsctui",
-	EFSCTSIZ:      "efsctsiz",
-	EFSCTSF:       "efsctsf",
-	EFSCTUIZ:      "efsctuiz",
-	EFSCTUF:       "efsctuf",
-	EFDABS:        "efdabs",
-	EFDNEG:        "efdneg",
-	EFDNABS:       "efdnabs",
-	EFDADD:        "efdadd",
-	EFDMUL:        "efdmul",
-	EFDSUB:        "efdsub",
-	EFDDIV:        "efddiv",
-	EFDCMPGT:      "efdcmpgt",
-	EFDCMPEQ:      "efdcmpeq",
-	EFDCMPLT:      "efdcmplt",
-	EFDTSTGT:      "efdtstgt",
-	EFDTSTLT:      "efdtstlt",
-	EFDCFSI:       "efdcfsi",
-	EFDTSTEQ:      "efdtsteq",
-	EFDCFUI:       "efdcfui",
-	EFDCFSID:      "efdcfsid",
-	EFDCFSF:       "efdcfsf",
-	EFDCFUF:       "efdcfuf",
-	EFDCFUID:      "efdcfuid",
-	EFDCTSI:       "efdctsi",
-	EFDCTUI:       "efdctui",
-	EFDCTSIDZ:     "efdctsidz",
-	EFDCTUIDZ:     "efdctuidz",
-	EFDCTSIZ:      "efdctsiz",
-	EFDCTSF:       "efdctsf",
-	EFDCTUF:       "efdctuf",
-	EFDCTUIZ:      "efdctuiz",
-	EFDCFS:        "efdcfs",
-	EFSCFD:        "efscfd",
-	DLMZB:         "dlmzb",
-	DLMZBCC:       "dlmzb.",
-	MACCHW:        "macchw",
-	MACCHWCC:      "macchw.",
-	MACCHWO:       "macchwo",
-	MACCHWOCC:     "macchwo.",
-	MACCHWS:       "macchws",
-	MACCHWSCC:     "macchws.",
-	MACCHWSO:      "macchwso",
-	MACCHWSOCC:    "macchwso.",
-	MACCHWU:       "macchwu",
-	MACCHWUCC:     "macchwu.",
-	MACCHWUO:      "macchwuo",
-	MACCHWUOCC:    "macchwuo.",
-	MACCHWSU:      "macchwsu",
-	MACCHWSUCC:    "macchwsu.",
-	MACCHWSUO:     "macchwsuo",
-	MACCHWSUOCC:   "macchwsuo.",
-	MACHHW:        "machhw",
-	MACHHWCC:      "machhw.",
-	MACHHWO:       "machhwo",
-	MACHHWOCC:     "machhwo.",
-	MACHHWS:       "machhws",
-	MACHHWSCC:     "machhws.",
-	MACHHWSO:      "machhwso",
-	MACHHWSOCC:    "machhwso.",
-	MACHHWU:       "machhwu",
-	MACHHWUCC:     "machhwu.",
-	MACHHWUO:      "machhwuo",
-	MACHHWUOCC:    "machhwuo.",
-	MACHHWSU:      "machhwsu",
-	MACHHWSUCC:    "machhwsu.",
-	MACHHWSUO:     "machhwsuo",
-	MACHHWSUOCC:   "machhwsuo.",
-	MACLHW:        "maclhw",
-	MACLHWCC:      "maclhw.",
-	MACLHWO:       "maclhwo",
-	MACLHWOCC:     "maclhwo.",
-	MACLHWS:       "maclhws",
-	MACLHWSCC:     "maclhws.",
-	MACLHWSO:      "maclhwso",
-	MACLHWSOCC:    "maclhwso.",
-	MACLHWU:       "maclhwu",
-	MACLHWUCC:     "maclhwu.",
-	MACLHWUO:      "maclhwuo",
-	MACLHWUOCC:    "maclhwuo.",
-	MULCHW:        "mulchw",
-	MULCHWCC:      "mulchw.",
-	MACLHWSU:      "maclhwsu",
-	MACLHWSUCC:    "maclhwsu.",
-	MACLHWSUO:     "maclhwsuo",
-	MACLHWSUOCC:   "maclhwsuo.",
-	MULCHWU:       "mulchwu",
-	MULCHWUCC:     "mulchwu.",
-	MULHHW:        "mulhhw",
-	MULHHWCC:      "mulhhw.",
-	MULLHW:        "mullhw",
-	MULLHWCC:      "mullhw.",
-	MULHHWU:       "mulhhwu",
-	MULHHWUCC:     "mulhhwu.",
-	MULLHWU:       "mullhwu",
-	MULLHWUCC:     "mullhwu.",
-	NMACCHW:       "nmacchw",
-	NMACCHWCC:     "nmacchw.",
-	NMACCHWO:      "nmacchwo",
-	NMACCHWOCC:    "nmacchwo.",
-	NMACCHWS:      "nmacchws",
-	NMACCHWSCC:    "nmacchws.",
-	NMACCHWSO:     "nmacchwso",
-	NMACCHWSOCC:   "nmacchwso.",
-	NMACHHW:       "nmachhw",
-	NMACHHWCC:     "nmachhw.",
-	NMACHHWO:      "nmachhwo",
-	NMACHHWOCC:    "nmachhwo.",
-	NMACHHWS:      "nmachhws",
-	NMACHHWSCC:    "nmachhws.",
-	NMACHHWSO:     "nmachhwso",
-	NMACHHWSOCC:   "nmachhwso.",
-	NMACLHW:       "nmaclhw",
-	NMACLHWCC:     "nmaclhw.",
-	NMACLHWO:      "nmaclhwo",
-	NMACLHWOCC:    "nmaclhwo.",
-	NMACLHWS:      "nmaclhws",
-	NMACLHWSCC:    "nmaclhws.",
-	NMACLHWSO:     "nmaclhwso",
-	NMACLHWSOCC:   "nmaclhwso.",
-	ICBI:          "icbi",
-	ICBT:          "icbt",
-	DCBA:          "dcba",
-	DCBT:          "dcbt",
-	DCBTST:        "dcbtst",
-	DCBZ:          "dcbz",
-	DCBST:         "dcbst",
-	DCBF:          "dcbf",
-	ISYNC:         "isync",
-	LBARX:         "lbarx",
-	LHARX:         "lharx",
-	LWARX:         "lwarx",
-	STBCXCC:       "stbcx.",
-	STHCXCC:       "sthcx.",
-	STWCXCC:       "stwcx.",
-	LDARX:         "ldarx",
-	STDCXCC:       "stdcx.",
-	LQARX:         "lqarx",
-	STQCXCC:       "stqcx.",
-	SYNC:          "sync",
-	EIEIO:         "eieio",
-	MBAR:          "mbar",
-	WAIT:          "wait",
-	TBEGINCC:      "tbegin.",
-	TENDCC:        "tend.",
-	TABORTCC:      "tabort.",
-	TABORTWCCC:    "tabortwc.",
-	TABORTWCICC:   "tabortwci.",
-	TABORTDCCC:    "tabortdc.",
-	TABORTDCICC:   "tabortdci.",
-	TSRCC:         "tsr.",
-	TCHECK:        "tcheck",
-	MFTB:          "mftb",
-	RFEBB:         "rfebb",
-	LBDX:          "lbdx",
-	LHDX:          "lhdx",
-	LWDX:          "lwdx",
-	LDDX:          "lddx",
-	LFDDX:         "lfddx",
-	STBDX:         "stbdx",
-	STHDX:         "sthdx",
-	STWDX:         "stwdx",
-	STDDX:         "stddx",
-	STFDDX:        "stfddx",
-	DSN:           "dsn",
-	ECIWX:         "eciwx",
-	ECOWX:         "ecowx",
-	RFID:          "rfid",
-	HRFID:         "hrfid",
-	DOZE:          "doze",
-	NAP:           "nap",
-	SLEEP:         "sleep",
-	RVWINKLE:      "rvwinkle",
-	LBZCIX:        "lbzcix",
-	LWZCIX:        "lwzcix",
-	LHZCIX:        "lhzcix",
-	LDCIX:         "ldcix",
-	STBCIX:        "stbcix",
-	STWCIX:        "stwcix",
-	STHCIX:        "sthcix",
-	STDCIX:        "stdcix",
-	TRECLAIMCC:    "treclaim.",
-	TRECHKPTCC:    "trechkpt.",
-	MTMSR:         "mtmsr",
-	MTMSRD:        "mtmsrd",
-	MFMSR:         "mfmsr",
-	SLBIE:         "slbie",
-	SLBIA:         "slbia",
-	SLBMTE:        "slbmte",
-	SLBMFEV:       "slbmfev",
-	SLBMFEE:       "slbmfee",
-	SLBFEECC:      "slbfee.",
-	MTSR:          "mtsr",
-	MTSRIN:        "mtsrin",
-	MFSR:          "mfsr",
-	MFSRIN:        "mfsrin",
-	TLBIE:         "tlbie",
-	TLBIEL:        "tlbiel",
-	TLBIA:         "tlbia",
-	TLBSYNC:       "tlbsync",
-	MSGSND:        "msgsnd",
-	MSGCLR:        "msgclr",
-	MSGSNDP:       "msgsndp",
-	MSGCLRP:       "msgclrp",
-	MTTMR:         "mttmr",
-	RFI:           "rfi",
-	RFCI:          "rfci",
-	RFDI:          "rfdi",
-	RFMCI:         "rfmci",
-	RFGI:          "rfgi",
-	EHPRIV:        "ehpriv",
-	MTDCR:         "mtdcr",
-	MTDCRX:        "mtdcrx",
-	MFDCR:         "mfdcr",
-	MFDCRX:        "mfdcrx",
-	WRTEE:         "wrtee",
-	WRTEEI:        "wrteei",
-	LBEPX:         "lbepx",
-	LHEPX:         "lhepx",
-	LWEPX:         "lwepx",
-	LDEPX:         "ldepx",
-	STBEPX:        "stbepx",
-	STHEPX:        "sthepx",
-	STWEPX:        "stwepx",
-	STDEPX:        "stdepx",
-	DCBSTEP:       "dcbstep",
-	DCBTEP:        "dcbtep",
-	DCBFEP:        "dcbfep",
-	DCBTSTEP:      "dcbtstep",
-	ICBIEP:        "icbiep",
-	DCBZEP:        "dcbzep",
-	LFDEPX:        "lfdepx",
-	STFDEPX:       "stfdepx",
-	EVLDDEPX:      "evlddepx",
-	EVSTDDEPX:     "evstddepx",
-	LVEPX:         "lvepx",
-	LVEPXL:        "lvepxl",
-	STVEPX:        "stvepx",
-	STVEPXL:       "stvepxl",
-	DCBI:          "dcbi",
-	DCBLQCC:       "dcblq.",
-	ICBLQCC:       "icblq.",
-	DCBTLS:        "dcbtls",
-	DCBTSTLS:      "dcbtstls",
-	ICBTLS:        "icbtls",
-	ICBLC:         "icblc",
-	DCBLC:         "dcblc",
-	TLBIVAX:       "tlbivax",
-	TLBILX:        "tlbilx",
-	TLBSX:         "tlbsx",
-	TLBSRXCC:      "tlbsrx.",
-	TLBRE:         "tlbre",
-	TLBWE:         "tlbwe",
-	DNH:           "dnh",
-	DCI:           "dci",
-	ICI:           "ici",
-	DCREAD:        "dcread",
-	ICREAD:        "icread",
-	MFPMR:         "mfpmr",
-	MTPMR:         "mtpmr",
-	ADDEX:         "addex",
-	DARN:          "darn",
-	MADDHD:        "maddhd",
-	MADDHDU:       "maddhdu",
-	MADDLD:        "maddld",
-	CMPRB:         "cmprb",
-	CMPEQB:        "cmpeqb",
-	EXTSWSLI:      "extswsli",
-	EXTSWSLICC:    "extswsli.",
-	MFVSRLD:       "mfvsrld",
-	MTVSRDD:       "mtvsrdd",
-	MTVSRWS:       "mtvsrws",
-	MCRXRX:        "mcrxrx",
-	COPY:          "copy",
-	PASTECC:       "paste.",
+	BRD:            "brd",
+	BRH:            "brh",
+	BRW:            "brw",
+	CFUGED:         "cfuged",
+	CNTLZDM:        "cntlzdm",
+	CNTTZDM:        "cnttzdm",
+	DCFFIXQQ:       "dcffixqq",
+	DCTFIXQQ:       "dctfixqq",
+	LXVKQ:          "lxvkq",
+	LXVP:           "lxvp",
+	LXVPX:          "lxvpx",
+	LXVRBX:         "lxvrbx",
+	LXVRDX:         "lxvrdx",
+	LXVRHX:         "lxvrhx",
+	LXVRWX:         "lxvrwx",
+	MTVSRBM:        "mtvsrbm",
+	MTVSRBMI:       "mtvsrbmi",
+	MTVSRDM:        "mtvsrdm",
+	MTVSRHM:        "mtvsrhm",
+	MTVSRQM:        "mtvsrqm",
+	MTVSRWM:        "mtvsrwm",
+	PADDI:          "paddi",
+	PDEPD:          "pdepd",
+	PEXTD:          "pextd",
+	PLBZ:           "plbz",
+	PLD:            "pld",
+	PLFD:           "plfd",
+	PLFS:           "plfs",
+	PLHA:           "plha",
+	PLHZ:           "plhz",
+	PLQ:            "plq",
+	PLWA:           "plwa",
+	PLWZ:           "plwz",
+	PLXSD:          "plxsd",
+	PLXSSP:         "plxssp",
+	PLXV:           "plxv",
+	PLXVP:          "plxvp",
+	PMXVBF16GER2:   "pmxvbf16ger2",
+	PMXVBF16GER2NN: "pmxvbf16ger2nn",
+	PMXVBF16GER2NP: "pmxvbf16ger2np",
+	PMXVBF16GER2PN: "pmxvbf16ger2pn",
+	PMXVBF16GER2PP: "pmxvbf16ger2pp",
+	PMXVF16GER2:    "pmxvf16ger2",
+	PMXVF16GER2NN:  "pmxvf16ger2nn",
+	PMXVF16GER2NP:  "pmxvf16ger2np",
+	PMXVF16GER2PN:  "pmxvf16ger2pn",
+	PMXVF16GER2PP:  "pmxvf16ger2pp",
+	PMXVF32GER:     "pmxvf32ger",
+	PMXVF32GERNN:   "pmxvf32gernn",
+	PMXVF32GERNP:   "pmxvf32gernp",
+	PMXVF32GERPN:   "pmxvf32gerpn",
+	PMXVF32GERPP:   "pmxvf32gerpp",
+	PMXVF64GER:     "pmxvf64ger",
+	PMXVF64GERNN:   "pmxvf64gernn",
+	PMXVF64GERNP:   "pmxvf64gernp",
+	PMXVF64GERPN:   "pmxvf64gerpn",
+	PMXVF64GERPP:   "pmxvf64gerpp",
+	PMXVI16GER2:    "pmxvi16ger2",
+	PMXVI16GER2PP:  "pmxvi16ger2pp",
+	PMXVI16GER2S:   "pmxvi16ger2s",
+	PMXVI16GER2SPP: "pmxvi16ger2spp",
+	PMXVI4GER8:     "pmxvi4ger8",
+	PMXVI4GER8PP:   "pmxvi4ger8pp",
+	PMXVI8GER4:     "pmxvi8ger4",
+	PMXVI8GER4PP:   "pmxvi8ger4pp",
+	PMXVI8GER4SPP:  "pmxvi8ger4spp",
+	PNOP:           "pnop",
+	PSTB:           "pstb",
+	PSTD:           "pstd",
+	PSTFD:          "pstfd",
+	PSTFS:          "pstfs",
+	PSTH:           "psth",
+	PSTQ:           "pstq",
+	PSTW:           "pstw",
+	PSTXSD:         "pstxsd",
+	PSTXSSP:        "pstxssp",
+	PSTXV:          "pstxv",
+	PSTXVP:         "pstxvp",
+	SETBC:          "setbc",
+	SETBCR:         "setbcr",
+	SETNBC:         "setnbc",
+	SETNBCR:        "setnbcr",
+	STXVP:          "stxvp",
+	STXVPX:         "stxvpx",
+	STXVRBX:        "stxvrbx",
+	STXVRDX:        "stxvrdx",
+	STXVRHX:        "stxvrhx",
+	STXVRWX:        "stxvrwx",
+	VCFUGED:        "vcfuged",
+	VCLRLB:         "vclrlb",
+	VCLRRB:         "vclrrb",
+	VCLZDM:         "vclzdm",
+	VCMPEQUQ:       "vcmpequq",
+	VCMPEQUQCC:     "vcmpequq.",
+	VCMPGTSQ:       "vcmpgtsq",
+	VCMPGTSQCC:     "vcmpgtsq.",
+	VCMPGTUQ:       "vcmpgtuq",
+	VCMPGTUQCC:     "vcmpgtuq.",
+	VCMPSQ:         "vcmpsq",
+	VCMPUQ:         "vcmpuq",
+	VCNTMBB:        "vcntmbb",
+	VCNTMBD:        "vcntmbd",
+	VCNTMBH:        "vcntmbh",
+	VCNTMBW:        "vcntmbw",
+	VCTZDM:         "vctzdm",
+	VDIVESD:        "vdivesd",
+	VDIVESQ:        "vdivesq",
+	VDIVESW:        "vdivesw",
+	VDIVEUD:        "vdiveud",
+	VDIVEUQ:        "vdiveuq",
+	VDIVEUW:        "vdiveuw",
+	VDIVSD:         "vdivsd",
+	VDIVSQ:         "vdivsq",
+	VDIVSW:         "vdivsw",
+	VDIVUD:         "vdivud",
+	VDIVUQ:         "vdivuq",
+	VDIVUW:         "vdivuw",
+	VEXPANDBM:      "vexpandbm",
+	VEXPANDDM:      "vexpanddm",
+	VEXPANDHM:      "vexpandhm",
+	VEXPANDQM:      "vexpandqm",
+	VEXPANDWM:      "vexpandwm",
+	VEXTDDVLX:      "vextddvlx",
+	VEXTDDVRX:      "vextddvrx",
+	VEXTDUBVLX:     "vextdubvlx",
+	VEXTDUBVRX:     "vextdubvrx",
+	VEXTDUHVLX:     "vextduhvlx",
+	VEXTDUHVRX:     "vextduhvrx",
+	VEXTDUWVLX:     "vextduwvlx",
+	VEXTDUWVRX:     "vextduwvrx",
+	VEXTRACTBM:     "vextractbm",
+	VEXTRACTDM:     "vextractdm",
+	VEXTRACTHM:     "vextracthm",
+	VEXTRACTQM:     "vextractqm",
+	VEXTRACTWM:     "vextractwm",
+	VEXTSD2Q:       "vextsd2q",
+	VGNB:           "vgnb",
+	VINSBLX:        "vinsblx",
+	VINSBRX:        "vinsbrx",
+	VINSBVLX:       "vinsbvlx",
+	VINSBVRX:       "vinsbvrx",
+	VINSD:          "vinsd",
+	VINSDLX:        "vinsdlx",
+	VINSDRX:        "vinsdrx",
+	VINSHLX:        "vinshlx",
+	VINSHRX:        "vinshrx",
+	VINSHVLX:       "vinshvlx",
+	VINSHVRX:       "vinshvrx",
+	VINSW:          "vinsw",
+	VINSWLX:        "vinswlx",
+	VINSWRX:        "vinswrx",
+	VINSWVLX:       "vinswvlx",
+	VINSWVRX:       "vinswvrx",
+	VMODSD:         "vmodsd",
+	VMODSQ:         "vmodsq",
+	VMODSW:         "vmodsw",
+	VMODUD:         "vmodud",
+	VMODUQ:         "vmoduq",
+	VMODUW:         "vmoduw",
+	VMSUMCUD:       "vmsumcud",
+	VMULESD:        "vmulesd",
+	VMULEUD:        "vmuleud",
+	VMULHSD:        "vmulhsd",
+	VMULHSW:        "vmulhsw",
+	VMULHUD:        "vmulhud",
+	VMULHUW:        "vmulhuw",
+	VMULLD:         "vmulld",
+	VMULOSD:        "vmulosd",
+	VMULOUD:        "vmuloud",
+	VPDEPD:         "vpdepd",
+	VPEXTD:         "vpextd",
+	VRLQ:           "vrlq",
+	VRLQMI:         "vrlqmi",
+	VRLQNM:         "vrlqnm",
+	VSLDBI:         "vsldbi",
+	VSLQ:           "vslq",
+	VSRAQ:          "vsraq",
+	VSRDBI:         "vsrdbi",
+	VSRQ:           "vsrq",
+	VSTRIBL:        "vstribl",
+	VSTRIBLCC:      "vstribl.",
+	VSTRIBR:        "vstribr",
+	VSTRIBRCC:      "vstribr.",
+	VSTRIHL:        "vstrihl",
+	VSTRIHLCC:      "vstrihl.",
+	VSTRIHR:        "vstrihr",
+	VSTRIHRCC:      "vstrihr.",
+	XSCMPEQQP:      "xscmpeqqp",
+	XSCMPGEQP:      "xscmpgeqp",
+	XSCMPGTQP:      "xscmpgtqp",
+	XSCVQPSQZ:      "xscvqpsqz",
+	XSCVQPUQZ:      "xscvqpuqz",
+	XSCVSQQP:       "xscvsqqp",
+	XSCVUQQP:       "xscvuqqp",
+	XSMAXCQP:       "xsmaxcqp",
+	XSMINCQP:       "xsmincqp",
+	XVBF16GER2:     "xvbf16ger2",
+	XVBF16GER2NN:   "xvbf16ger2nn",
+	XVBF16GER2NP:   "xvbf16ger2np",
+	XVBF16GER2PN:   "xvbf16ger2pn",
+	XVBF16GER2PP:   "xvbf16ger2pp",
+	XVCVBF16SPN:    "xvcvbf16spn",
+	XVCVSPBF16:     "xvcvspbf16",
+	XVF16GER2:      "xvf16ger2",
+	XVF16GER2NN:    "xvf16ger2nn",
+	XVF16GER2NP:    "xvf16ger2np",
+	XVF16GER2PN:    "xvf16ger2pn",
+	XVF16GER2PP:    "xvf16ger2pp",
+	XVF32GER:       "xvf32ger",
+	XVF32GERNN:     "xvf32gernn",
+	XVF32GERNP:     "xvf32gernp",
+	XVF32GERPN:     "xvf32gerpn",
+	XVF32GERPP:     "xvf32gerpp",
+	XVF64GER:       "xvf64ger",
+	XVF64GERNN:     "xvf64gernn",
+	XVF64GERNP:     "xvf64gernp",
+	XVF64GERPN:     "xvf64gerpn",
+	XVF64GERPP:     "xvf64gerpp",
+	XVI16GER2:      "xvi16ger2",
+	XVI16GER2PP:    "xvi16ger2pp",
+	XVI16GER2S:     "xvi16ger2s",
+	XVI16GER2SPP:   "xvi16ger2spp",
+	XVI4GER8:       "xvi4ger8",
+	XVI4GER8PP:     "xvi4ger8pp",
+	XVI8GER4:       "xvi8ger4",
+	XVI8GER4PP:     "xvi8ger4pp",
+	XVI8GER4SPP:    "xvi8ger4spp",
+	XVTLSBB:        "xvtlsbb",
+	XXBLENDVB:      "xxblendvb",
+	XXBLENDVD:      "xxblendvd",
+	XXBLENDVH:      "xxblendvh",
+	XXBLENDVW:      "xxblendvw",
+	XXEVAL:         "xxeval",
+	XXGENPCVBM:     "xxgenpcvbm",
+	XXGENPCVDM:     "xxgenpcvdm",
+	XXGENPCVHM:     "xxgenpcvhm",
+	XXGENPCVWM:     "xxgenpcvwm",
+	XXMFACC:        "xxmfacc",
+	XXMTACC:        "xxmtacc",
+	XXPERMX:        "xxpermx",
+	XXSETACCZ:      "xxsetaccz",
+	XXSPLTI32DX:    "xxsplti32dx",
+	XXSPLTIDP:      "xxspltidp",
+	XXSPLTIW:       "xxspltiw",
+	MSGCLRU:        "msgclru",
+	MSGSNDU:        "msgsndu",
+	URFID:          "urfid",
+	ADDEX:          "addex",
+	MFFSCDRN:       "mffscdrn",
+	MFFSCDRNI:      "mffscdrni",
+	MFFSCE:         "mffsce",
+	MFFSCRN:        "mffscrn",
+	MFFSCRNI:       "mffscrni",
+	MFFSL:          "mffsl",
+	SLBIAG:         "slbiag",
+	VMSUMUDM:       "vmsumudm",
+	ADDPCIS:        "addpcis",
+	BCDCFNCC:       "bcdcfn.",
+	BCDCFSQCC:      "bcdcfsq.",
+	BCDCFZCC:       "bcdcfz.",
+	BCDCPSGNCC:     "bcdcpsgn.",
+	BCDCTNCC:       "bcdctn.",
+	BCDCTSQCC:      "bcdctsq.",
+	BCDCTZCC:       "bcdctz.",
+	BCDSCC:         "bcds.",
+	BCDSETSGNCC:    "bcdsetsgn.",
+	BCDSRCC:        "bcdsr.",
+	BCDTRUNCCC:     "bcdtrunc.",
+	BCDUSCC:        "bcdus.",
+	BCDUTRUNCCC:    "bcdutrunc.",
+	CMPEQB:         "cmpeqb",
+	CMPRB:          "cmprb",
+	CNTTZD:         "cnttzd",
+	CNTTZDCC:       "cnttzd.",
+	CNTTZW:         "cnttzw",
+	CNTTZWCC:       "cnttzw.",
+	COPY:           "copy",
+	CPABORT:        "cpabort",
+	DARN:           "darn",
+	DTSTSFI:        "dtstsfi",
+	DTSTSFIQ:       "dtstsfiq",
+	EXTSWSLI:       "extswsli",
+	EXTSWSLICC:     "extswsli.",
+	LDAT:           "ldat",
+	LWAT:           "lwat",
+	LXSD:           "lxsd",
+	LXSIBZX:        "lxsibzx",
+	LXSIHZX:        "lxsihzx",
+	LXSSP:          "lxssp",
+	LXV:            "lxv",
+	LXVB16X:        "lxvb16x",
+	LXVH8X:         "lxvh8x",
+	LXVL:           "lxvl",
+	LXVLL:          "lxvll",
+	LXVWSX:         "lxvwsx",
+	LXVX:           "lxvx",
+	MADDHD:         "maddhd",
+	MADDHDU:        "maddhdu",
+	MADDLD:         "maddld",
+	MCRXRX:         "mcrxrx",
+	MFVSRLD:        "mfvsrld",
+	MODSD:          "modsd",
+	MODSW:          "modsw",
+	MODUD:          "modud",
+	MODUW:          "moduw",
+	MSGSYNC:        "msgsync",
+	MTVSRDD:        "mtvsrdd",
+	MTVSRWS:        "mtvsrws",
+	PASTECC:        "paste.",
+	SETB:           "setb",
+	SLBIEG:         "slbieg",
+	SLBSYNC:        "slbsync",
+	STDAT:          "stdat",
+	STOP:           "stop",
+	STWAT:          "stwat",
+	STXSD:          "stxsd",
+	STXSIBX:        "stxsibx",
+	STXSIHX:        "stxsihx",
+	STXSSP:         "stxssp",
+	STXV:           "stxv",
+	STXVB16X:       "stxvb16x",
+	STXVH8X:        "stxvh8x",
+	STXVL:          "stxvl",
+	STXVLL:         "stxvll",
+	STXVX:          "stxvx",
+	VABSDUB:        "vabsdub",
+	VABSDUH:        "vabsduh",
+	VABSDUW:        "vabsduw",
+	VBPERMD:        "vbpermd",
+	VCLZLSBB:       "vclzlsbb",
+	VCMPNEB:        "vcmpneb",
+	VCMPNEBCC:      "vcmpneb.",
+	VCMPNEH:        "vcmpneh",
+	VCMPNEHCC:      "vcmpneh.",
+	VCMPNEW:        "vcmpnew",
+	VCMPNEWCC:      "vcmpnew.",
+	VCMPNEZB:       "vcmpnezb",
+	VCMPNEZBCC:     "vcmpnezb.",
+	VCMPNEZH:       "vcmpnezh",
+	VCMPNEZHCC:     "vcmpnezh.",
+	VCMPNEZW:       "vcmpnezw",
+	VCMPNEZWCC:     "vcmpnezw.",
+	VCTZB:          "vctzb",
+	VCTZD:          "vctzd",
+	VCTZH:          "vctzh",
+	VCTZLSBB:       "vctzlsbb",
+	VCTZW:          "vctzw",
+	VEXTRACTD:      "vextractd",
+	VEXTRACTUB:     "vextractub",
+	VEXTRACTUH:     "vextractuh",
+	VEXTRACTUW:     "vextractuw",
+	VEXTSB2D:       "vextsb2d",
+	VEXTSB2W:       "vextsb2w",
+	VEXTSH2D:       "vextsh2d",
+	VEXTSH2W:       "vextsh2w",
+	VEXTSW2D:       "vextsw2d",
+	VEXTUBLX:       "vextublx",
+	VEXTUBRX:       "vextubrx",
+	VEXTUHLX:       "vextuhlx",
+	VEXTUHRX:       "vextuhrx",
+	VEXTUWLX:       "vextuwlx",
+	VEXTUWRX:       "vextuwrx",
+	VINSERTB:       "vinsertb",
+	VINSERTD:       "vinsertd",
+	VINSERTH:       "vinserth",
+	VINSERTW:       "vinsertw",
+	VMUL10CUQ:      "vmul10cuq",
+	VMUL10ECUQ:     "vmul10ecuq",
+	VMUL10EUQ:      "vmul10euq",
+	VMUL10UQ:       "vmul10uq",
+	VNEGD:          "vnegd",
+	VNEGW:          "vnegw",
+	VPERMR:         "vpermr",
+	VPRTYBD:        "vprtybd",
+	VPRTYBQ:        "vprtybq",
+	VPRTYBW:        "vprtybw",
+	VRLDMI:         "vrldmi",
+	VRLDNM:         "vrldnm",
+	VRLWMI:         "vrlwmi",
+	VRLWNM:         "vrlwnm",
+	VSLV:           "vslv",
+	VSRV:           "vsrv",
+	WAIT:           "wait",
+	XSABSQP:        "xsabsqp",
+	XSADDQP:        "xsaddqp",
+	XSADDQPO:       "xsaddqpo",
+	XSCMPEQDP:      "xscmpeqdp",
+	XSCMPEXPDP:     "xscmpexpdp",
+	XSCMPEXPQP:     "xscmpexpqp",
+	XSCMPGEDP:      "xscmpgedp",
+	XSCMPGTDP:      "xscmpgtdp",
+	XSCMPOQP:       "xscmpoqp",
+	XSCMPUQP:       "xscmpuqp",
+	XSCPSGNQP:      "xscpsgnqp",
+	XSCVDPHP:       "xscvdphp",
+	XSCVDPQP:       "xscvdpqp",
+	XSCVHPDP:       "xscvhpdp",
+	XSCVQPDP:       "xscvqpdp",
+	XSCVQPDPO:      "xscvqpdpo",
+	XSCVQPSDZ:      "xscvqpsdz",
+	XSCVQPSWZ:      "xscvqpswz",
+	XSCVQPUDZ:      "xscvqpudz",
+	XSCVQPUWZ:      "xscvqpuwz",
+	XSCVSDQP:       "xscvsdqp",
+	XSCVUDQP:       "xscvudqp",
+	XSDIVQP:        "xsdivqp",
+	XSDIVQPO:       "xsdivqpo",
+	XSIEXPDP:       "xsiexpdp",
+	XSIEXPQP:       "xsiexpqp",
+	XSMADDQP:       "xsmaddqp",
+	XSMADDQPO:      "xsmaddqpo",
+	XSMAXCDP:       "xsmaxcdp",
+	XSMAXJDP:       "xsmaxjdp",
+	XSMINCDP:       "xsmincdp",
+	XSMINJDP:       "xsminjdp",
+	XSMSUBQP:       "xsmsubqp",
+	XSMSUBQPO:      "xsmsubqpo",
+	XSMULQP:        "xsmulqp",
+	XSMULQPO:       "xsmulqpo",
+	XSNABSQP:       "xsnabsqp",
+	XSNEGQP:        "xsnegqp",
+	XSNMADDQP:      "xsnmaddqp",
+	XSNMADDQPO:     "xsnmaddqpo",
+	XSNMSUBQP:      "xsnmsubqp",
+	XSNMSUBQPO:     "xsnmsubqpo",
+	XSRQPI:         "xsrqpi",
+	XSRQPIX:        "xsrqpix",
+	XSRQPXP:        "xsrqpxp",
+	XSSQRTQP:       "xssqrtqp",
+	XSSQRTQPO:      "xssqrtqpo",
+	XSSUBQP:        "xssubqp",
+	XSSUBQPO:       "xssubqpo",
+	XSTSTDCDP:      "xststdcdp",
+	XSTSTDCQP:      "xststdcqp",
+	XSTSTDCSP:      "xststdcsp",
+	XSXEXPDP:       "xsxexpdp",
+	XSXEXPQP:       "xsxexpqp",
+	XSXSIGDP:       "xsxsigdp",
+	XSXSIGQP:       "xsxsigqp",
+	XVCVHPSP:       "xvcvhpsp",
+	XVCVSPHP:       "xvcvsphp",
+	XVIEXPDP:       "xviexpdp",
+	XVIEXPSP:       "xviexpsp",
+	XVTSTDCDP:      "xvtstdcdp",
+	XVTSTDCSP:      "xvtstdcsp",
+	XVXEXPDP:       "xvxexpdp",
+	XVXEXPSP:       "xvxexpsp",
+	XVXSIGDP:       "xvxsigdp",
+	XVXSIGSP:       "xvxsigsp",
+	XXBRD:          "xxbrd",
+	XXBRH:          "xxbrh",
+	XXBRQ:          "xxbrq",
+	XXBRW:          "xxbrw",
+	XXEXTRACTUW:    "xxextractuw",
+	XXINSERTW:      "xxinsertw",
+	XXPERM:         "xxperm",
+	XXPERMR:        "xxpermr",
+	XXSPLTIB:       "xxspltib",
+	BCDADDCC:       "bcdadd.",
+	BCDSUBCC:       "bcdsub.",
+	BCTAR:          "bctar",
+	BCTARL:         "bctarl",
+	CLRBHRB:        "clrbhrb",
+	FMRGEW:         "fmrgew",
+	FMRGOW:         "fmrgow",
+	ICBT:           "icbt",
+	LQARX:          "lqarx",
+	LXSIWAX:        "lxsiwax",
+	LXSIWZX:        "lxsiwzx",
+	LXSSPX:         "lxsspx",
+	MFBHRBE:        "mfbhrbe",
+	MFVSRD:         "mfvsrd",
+	MFVSRWZ:        "mfvsrwz",
+	MSGCLR:         "msgclr",
+	MSGCLRP:        "msgclrp",
+	MSGSND:         "msgsnd",
+	MSGSNDP:        "msgsndp",
+	MTVSRD:         "mtvsrd",
+	MTVSRWA:        "mtvsrwa",
+	MTVSRWZ:        "mtvsrwz",
+	RFEBB:          "rfebb",
+	STQCXCC:        "stqcx.",
+	STXSIWX:        "stxsiwx",
+	STXSSPX:        "stxsspx",
+	VADDCUQ:        "vaddcuq",
+	VADDECUQ:       "vaddecuq",
+	VADDEUQM:       "vaddeuqm",
+	VADDUDM:        "vaddudm",
+	VADDUQM:        "vadduqm",
+	VBPERMQ:        "vbpermq",
+	VCIPHER:        "vcipher",
+	VCIPHERLAST:    "vcipherlast",
+	VCLZB:          "vclzb",
+	VCLZD:          "vclzd",
+	VCLZH:          "vclzh",
+	VCLZW:          "vclzw",
+	VCMPEQUD:       "vcmpequd",
+	VCMPEQUDCC:     "vcmpequd.",
+	VCMPGTSD:       "vcmpgtsd",
+	VCMPGTSDCC:     "vcmpgtsd.",
+	VCMPGTUD:       "vcmpgtud",
+	VCMPGTUDCC:     "vcmpgtud.",
+	VEQV:           "veqv",
+	VGBBD:          "vgbbd",
+	VMAXSD:         "vmaxsd",
+	VMAXUD:         "vmaxud",
+	VMINSD:         "vminsd",
+	VMINUD:         "vminud",
+	VMRGEW:         "vmrgew",
+	VMRGOW:         "vmrgow",
+	VMULESW:        "vmulesw",
+	VMULEUW:        "vmuleuw",
+	VMULOSW:        "vmulosw",
+	VMULOUW:        "vmulouw",
+	VMULUWM:        "vmuluwm",
+	VNAND:          "vnand",
+	VNCIPHER:       "vncipher",
+	VNCIPHERLAST:   "vncipherlast",
+	VORC:           "vorc",
+	VPERMXOR:       "vpermxor",
+	VPKSDSS:        "vpksdss",
+	VPKSDUS:        "vpksdus",
+	VPKUDUM:        "vpkudum",
+	VPKUDUS:        "vpkudus",
+	VPMSUMB:        "vpmsumb",
+	VPMSUMD:        "vpmsumd",
+	VPMSUMH:        "vpmsumh",
+	VPMSUMW:        "vpmsumw",
+	VPOPCNTB:       "vpopcntb",
+	VPOPCNTD:       "vpopcntd",
+	VPOPCNTH:       "vpopcnth",
+	VPOPCNTW:       "vpopcntw",
+	VRLD:           "vrld",
+	VSBOX:          "vsbox",
+	VSHASIGMAD:     "vshasigmad",
+	VSHASIGMAW:     "vshasigmaw",
+	VSLD:           "vsld",
+	VSRAD:          "vsrad",
+	VSRD:           "vsrd",
+	VSUBCUQ:        "vsubcuq",
+	VSUBECUQ:       "vsubecuq",
+	VSUBEUQM:       "vsubeuqm",
+	VSUBUDM:        "vsubudm",
+	VSUBUQM:        "vsubuqm",
+	VUPKHSW:        "vupkhsw",
+	VUPKLSW:        "vupklsw",
+	XSADDSP:        "xsaddsp",
+	XSCVDPSPN:      "xscvdpspn",
+	XSCVSPDPN:      "xscvspdpn",
+	XSCVSXDSP:      "xscvsxdsp",
+	XSCVUXDSP:      "xscvuxdsp",
+	XSDIVSP:        "xsdivsp",
+	XSMADDASP:      "xsmaddasp",
+	XSMADDMSP:      "xsmaddmsp",
+	XSMSUBASP:      "xsmsubasp",
+	XSMSUBMSP:      "xsmsubmsp",
+	XSMULSP:        "xsmulsp",
+	XSNMADDASP:     "xsnmaddasp",
+	XSNMADDMSP:     "xsnmaddmsp",
+	XSNMSUBASP:     "xsnmsubasp",
+	XSNMSUBMSP:     "xsnmsubmsp",
+	XSRESP:         "xsresp",
+	XSRSP:          "xsrsp",
+	XSRSQRTESP:     "xsrsqrtesp",
+	XSSQRTSP:       "xssqrtsp",
+	XSSUBSP:        "xssubsp",
+	XXLEQV:         "xxleqv",
+	XXLNAND:        "xxlnand",
+	XXLORC:         "xxlorc",
+	ADDG6S:         "addg6s",
+	BPERMD:         "bpermd",
+	CBCDTD:         "cbcdtd",
+	CDTBCD:         "cdtbcd",
+	DCFFIX:         "dcffix",
+	DCFFIXCC:       "dcffix.",
+	DIVDE:          "divde",
+	DIVDECC:        "divde.",
+	DIVDEO:         "divdeo",
+	DIVDEOCC:       "divdeo.",
+	DIVDEU:         "divdeu",
+	DIVDEUCC:       "divdeu.",
+	DIVDEUO:        "divdeuo",
+	DIVDEUOCC:      "divdeuo.",
+	DIVWE:          "divwe",
+	DIVWECC:        "divwe.",
+	DIVWEO:         "divweo",
+	DIVWEOCC:       "divweo.",
+	DIVWEU:         "divweu",
+	DIVWEUCC:       "divweu.",
+	DIVWEUO:        "divweuo",
+	DIVWEUOCC:      "divweuo.",
+	FCFIDS:         "fcfids",
+	FCFIDSCC:       "fcfids.",
+	FCFIDU:         "fcfidu",
+	FCFIDUCC:       "fcfidu.",
+	FCFIDUS:        "fcfidus",
+	FCFIDUSCC:      "fcfidus.",
+	FCTIDU:         "fctidu",
+	FCTIDUCC:       "fctidu.",
+	FCTIDUZ:        "fctiduz",
+	FCTIDUZCC:      "fctiduz.",
+	FCTIWU:         "fctiwu",
+	FCTIWUCC:       "fctiwu.",
+	FCTIWUZ:        "fctiwuz",
+	FCTIWUZCC:      "fctiwuz.",
+	FTDIV:          "ftdiv",
+	FTSQRT:         "ftsqrt",
+	LBARX:          "lbarx",
+	LDBRX:          "ldbrx",
+	LFIWZX:         "lfiwzx",
+	LHARX:          "lharx",
+	LXSDX:          "lxsdx",
+	LXVD2X:         "lxvd2x",
+	LXVDSX:         "lxvdsx",
+	LXVW4X:         "lxvw4x",
+	POPCNTD:        "popcntd",
+	POPCNTW:        "popcntw",
+	STBCXCC:        "stbcx.",
+	STDBRX:         "stdbrx",
+	STHCXCC:        "sthcx.",
+	STXSDX:         "stxsdx",
+	STXVD2X:        "stxvd2x",
+	STXVW4X:        "stxvw4x",
+	XSABSDP:        "xsabsdp",
+	XSADDDP:        "xsadddp",
+	XSCMPODP:       "xscmpodp",
+	XSCMPUDP:       "xscmpudp",
+	XSCPSGNDP:      "xscpsgndp",
+	XSCVDPSP:       "xscvdpsp",
+	XSCVDPSXDS:     "xscvdpsxds",
+	XSCVDPSXWS:     "xscvdpsxws",
+	XSCVDPUXDS:     "xscvdpuxds",
+	XSCVDPUXWS:     "xscvdpuxws",
+	XSCVSPDP:       "xscvspdp",
+	XSCVSXDDP:      "xscvsxddp",
+	XSCVUXDDP:      "xscvuxddp",
+	XSDIVDP:        "xsdivdp",
+	XSMADDADP:      "xsmaddadp",
+	XSMADDMDP:      "xsmaddmdp",
+	XSMAXDP:        "xsmaxdp",
+	XSMINDP:        "xsmindp",
+	XSMSUBADP:      "xsmsubadp",
+	XSMSUBMDP:      "xsmsubmdp",
+	XSMULDP:        "xsmuldp",
+	XSNABSDP:       "xsnabsdp",
+	XSNEGDP:        "xsnegdp",
+	XSNMADDADP:     "xsnmaddadp",
+	XSNMADDMDP:     "xsnmaddmdp",
+	XSNMSUBADP:     "xsnmsubadp",
+	XSNMSUBMDP:     "xsnmsubmdp",
+	XSRDPI:         "xsrdpi",
+	XSRDPIC:        "xsrdpic",
+	XSRDPIM:        "xsrdpim",
+	XSRDPIP:        "xsrdpip",
+	XSRDPIZ:        "xsrdpiz",
+	XSREDP:         "xsredp",
+	XSRSQRTEDP:     "xsrsqrtedp",
+	XSSQRTDP:       "xssqrtdp",
+	XSSUBDP:        "xssubdp",
+	XSTDIVDP:       "xstdivdp",
+	XSTSQRTDP:      "xstsqrtdp",
+	XVABSDP:        "xvabsdp",
+	XVABSSP:        "xvabssp",
+	XVADDDP:        "xvadddp",
+	XVADDSP:        "xvaddsp",
+	XVCMPEQDP:      "xvcmpeqdp",
+	XVCMPEQDPCC:    "xvcmpeqdp.",
+	XVCMPEQSP:      "xvcmpeqsp",
+	XVCMPEQSPCC:    "xvcmpeqsp.",
+	XVCMPGEDP:      "xvcmpgedp",
+	XVCMPGEDPCC:    "xvcmpgedp.",
+	XVCMPGESP:      "xvcmpgesp",
+	XVCMPGESPCC:    "xvcmpgesp.",
+	XVCMPGTDP:      "xvcmpgtdp",
+	XVCMPGTDPCC:    "xvcmpgtdp.",
+	XVCMPGTSP:      "xvcmpgtsp",
+	XVCMPGTSPCC:    "xvcmpgtsp.",
+	XVCPSGNDP:      "xvcpsgndp",
+	XVCPSGNSP:      "xvcpsgnsp",
+	XVCVDPSP:       "xvcvdpsp",
+	XVCVDPSXDS:     "xvcvdpsxds",
+	XVCVDPSXWS:     "xvcvdpsxws",
+	XVCVDPUXDS:     "xvcvdpuxds",
+	XVCVDPUXWS:     "xvcvdpuxws",
+	XVCVSPDP:       "xvcvspdp",
+	XVCVSPSXDS:     "xvcvspsxds",
+	XVCVSPSXWS:     "xvcvspsxws",
+	XVCVSPUXDS:     "xvcvspuxds",
+	XVCVSPUXWS:     "xvcvspuxws",
+	XVCVSXDDP:      "xvcvsxddp",
+	XVCVSXDSP:      "xvcvsxdsp",
+	XVCVSXWDP:      "xvcvsxwdp",
+	XVCVSXWSP:      "xvcvsxwsp",
+	XVCVUXDDP:      "xvcvuxddp",
+	XVCVUXDSP:      "xvcvuxdsp",
+	XVCVUXWDP:      "xvcvuxwdp",
+	XVCVUXWSP:      "xvcvuxwsp",
+	XVDIVDP:        "xvdivdp",
+	XVDIVSP:        "xvdivsp",
+	XVMADDADP:      "xvmaddadp",
+	XVMADDASP:      "xvmaddasp",
+	XVMADDMDP:      "xvmaddmdp",
+	XVMADDMSP:      "xvmaddmsp",
+	XVMAXDP:        "xvmaxdp",
+	XVMAXSP:        "xvmaxsp",
+	XVMINDP:        "xvmindp",
+	XVMINSP:        "xvminsp",
+	XVMSUBADP:      "xvmsubadp",
+	XVMSUBASP:      "xvmsubasp",
+	XVMSUBMDP:      "xvmsubmdp",
+	XVMSUBMSP:      "xvmsubmsp",
+	XVMULDP:        "xvmuldp",
+	XVMULSP:        "xvmulsp",
+	XVNABSDP:       "xvnabsdp",
+	XVNABSSP:       "xvnabssp",
+	XVNEGDP:        "xvnegdp",
+	XVNEGSP:        "xvnegsp",
+	XVNMADDADP:     "xvnmaddadp",
+	XVNMADDASP:     "xvnmaddasp",
+	XVNMADDMDP:     "xvnmaddmdp",
+	XVNMADDMSP:     "xvnmaddmsp",
+	XVNMSUBADP:     "xvnmsubadp",
+	XVNMSUBASP:     "xvnmsubasp",
+	XVNMSUBMDP:     "xvnmsubmdp",
+	XVNMSUBMSP:     "xvnmsubmsp",
+	XVRDPI:         "xvrdpi",
+	XVRDPIC:        "xvrdpic",
+	XVRDPIM:        "xvrdpim",
+	XVRDPIP:        "xvrdpip",
+	XVRDPIZ:        "xvrdpiz",
+	XVREDP:         "xvredp",
+	XVRESP:         "xvresp",
+	XVRSPI:         "xvrspi",
+	XVRSPIC:        "xvrspic",
+	XVRSPIM:        "xvrspim",
+	XVRSPIP:        "xvrspip",
+	XVRSPIZ:        "xvrspiz",
+	XVRSQRTEDP:     "xvrsqrtedp",
+	XVRSQRTESP:     "xvrsqrtesp",
+	XVSQRTDP:       "xvsqrtdp",
+	XVSQRTSP:       "xvsqrtsp",
+	XVSUBDP:        "xvsubdp",
+	XVSUBSP:        "xvsubsp",
+	XVTDIVDP:       "xvtdivdp",
+	XVTDIVSP:       "xvtdivsp",
+	XVTSQRTDP:      "xvtsqrtdp",
+	XVTSQRTSP:      "xvtsqrtsp",
+	XXLAND:         "xxland",
+	XXLANDC:        "xxlandc",
+	XXLNOR:         "xxlnor",
+	XXLOR:          "xxlor",
+	XXLXOR:         "xxlxor",
+	XXMRGHW:        "xxmrghw",
+	XXMRGLW:        "xxmrglw",
+	XXPERMDI:       "xxpermdi",
+	XXSEL:          "xxsel",
+	XXSLDWI:        "xxsldwi",
+	XXSPLTW:        "xxspltw",
+	CMPB:           "cmpb",
+	DADD:           "dadd",
+	DADDCC:         "dadd.",
+	DADDQ:          "daddq",
+	DADDQCC:        "daddq.",
+	DCFFIXQ:        "dcffixq",
+	DCFFIXQCC:      "dcffixq.",
+	DCMPO:          "dcmpo",
+	DCMPOQ:         "dcmpoq",
+	DCMPU:          "dcmpu",
+	DCMPUQ:         "dcmpuq",
+	DCTDP:          "dctdp",
+	DCTDPCC:        "dctdp.",
+	DCTFIX:         "dctfix",
+	DCTFIXCC:       "dctfix.",
+	DCTFIXQ:        "dctfixq",
+	DCTFIXQCC:      "dctfixq.",
+	DCTQPQ:         "dctqpq",
+	DCTQPQCC:       "dctqpq.",
+	DDEDPD:         "ddedpd",
+	DDEDPDCC:       "ddedpd.",
+	DDEDPDQ:        "ddedpdq",
+	DDEDPDQCC:      "ddedpdq.",
+	DDIV:           "ddiv",
+	DDIVCC:         "ddiv.",
+	DDIVQ:          "ddivq",
+	DDIVQCC:        "ddivq.",
+	DENBCD:         "denbcd",
+	DENBCDCC:       "denbcd.",
+	DENBCDQ:        "denbcdq",
+	DENBCDQCC:      "denbcdq.",
+	DIEX:           "diex",
+	DIEXCC:         "diex.",
+	DIEXQCC:        "diexq.",
+	DIEXQ:          "diexq",
+	DMUL:           "dmul",
+	DMULCC:         "dmul.",
+	DMULQ:          "dmulq",
+	DMULQCC:        "dmulq.",
+	DQUA:           "dqua",
+	DQUACC:         "dqua.",
+	DQUAI:          "dquai",
+	DQUAICC:        "dquai.",
+	DQUAIQ:         "dquaiq",
+	DQUAIQCC:       "dquaiq.",
+	DQUAQ:          "dquaq",
+	DQUAQCC:        "dquaq.",
+	DRDPQ:          "drdpq",
+	DRDPQCC:        "drdpq.",
+	DRINTN:         "drintn",
+	DRINTNCC:       "drintn.",
+	DRINTNQ:        "drintnq",
+	DRINTNQCC:      "drintnq.",
+	DRINTX:         "drintx",
+	DRINTXCC:       "drintx.",
+	DRINTXQ:        "drintxq",
+	DRINTXQCC:      "drintxq.",
+	DRRND:          "drrnd",
+	DRRNDCC:        "drrnd.",
+	DRRNDQ:         "drrndq",
+	DRRNDQCC:       "drrndq.",
+	DRSP:           "drsp",
+	DRSPCC:         "drsp.",
+	DSCLI:          "dscli",
+	DSCLICC:        "dscli.",
+	DSCLIQ:         "dscliq",
+	DSCLIQCC:       "dscliq.",
+	DSCRI:          "dscri",
+	DSCRICC:        "dscri.",
+	DSCRIQ:         "dscriq",
+	DSCRIQCC:       "dscriq.",
+	DSUB:           "dsub",
+	DSUBCC:         "dsub.",
+	DSUBQ:          "dsubq",
+	DSUBQCC:        "dsubq.",
+	DTSTDC:         "dtstdc",
+	DTSTDCQ:        "dtstdcq",
+	DTSTDG:         "dtstdg",
+	DTSTDGQ:        "dtstdgq",
+	DTSTEX:         "dtstex",
+	DTSTEXQ:        "dtstexq",
+	DTSTSF:         "dtstsf",
+	DTSTSFQ:        "dtstsfq",
+	DXEX:           "dxex",
+	DXEXCC:         "dxex.",
+	DXEXQ:          "dxexq",
+	DXEXQCC:        "dxexq.",
+	FCPSGN:         "fcpsgn",
+	FCPSGNCC:       "fcpsgn.",
+	LBZCIX:         "lbzcix",
+	LDCIX:          "ldcix",
+	LFDP:           "lfdp",
+	LFDPX:          "lfdpx",
+	LFIWAX:         "lfiwax",
+	LHZCIX:         "lhzcix",
+	LWZCIX:         "lwzcix",
+	PRTYD:          "prtyd",
+	PRTYW:          "prtyw",
+	SLBFEECC:       "slbfee.",
+	STBCIX:         "stbcix",
+	STDCIX:         "stdcix",
+	STFDP:          "stfdp",
+	STFDPX:         "stfdpx",
+	STHCIX:         "sthcix",
+	STWCIX:         "stwcix",
+	ISEL:           "isel",
+	LVEBX:          "lvebx",
+	LVEHX:          "lvehx",
+	LVEWX:          "lvewx",
+	LVSL:           "lvsl",
+	LVSR:           "lvsr",
+	LVX:            "lvx",
+	LVXL:           "lvxl",
+	MFVSCR:         "mfvscr",
+	MTVSCR:         "mtvscr",
+	STVEBX:         "stvebx",
+	STVEHX:         "stvehx",
+	STVEWX:         "stvewx",
+	STVX:           "stvx",
+	STVXL:          "stvxl",
+	TLBIEL:         "tlbiel",
+	VADDCUW:        "vaddcuw",
+	VADDFP:         "vaddfp",
+	VADDSBS:        "vaddsbs",
+	VADDSHS:        "vaddshs",
+	VADDSWS:        "vaddsws",
+	VADDUBM:        "vaddubm",
+	VADDUBS:        "vaddubs",
+	VADDUHM:        "vadduhm",
+	VADDUHS:        "vadduhs",
+	VADDUWM:        "vadduwm",
+	VADDUWS:        "vadduws",
+	VAND:           "vand",
+	VANDC:          "vandc",
+	VAVGSB:         "vavgsb",
+	VAVGSH:         "vavgsh",
+	VAVGSW:         "vavgsw",
+	VAVGUB:         "vavgub",
+	VAVGUH:         "vavguh",
+	VAVGUW:         "vavguw",
+	VCFSX:          "vcfsx",
+	VCFUX:          "vcfux",
+	VCMPBFP:        "vcmpbfp",
+	VCMPBFPCC:      "vcmpbfp.",
+	VCMPEQFP:       "vcmpeqfp",
+	VCMPEQFPCC:     "vcmpeqfp.",
+	VCMPEQUB:       "vcmpequb",
+	VCMPEQUBCC:     "vcmpequb.",
+	VCMPEQUH:       "vcmpequh",
+	VCMPEQUHCC:     "vcmpequh.",
+	VCMPEQUW:       "vcmpequw",
+	VCMPEQUWCC:     "vcmpequw.",
+	VCMPGEFP:       "vcmpgefp",
+	VCMPGEFPCC:     "vcmpgefp.",
+	VCMPGTFP:       "vcmpgtfp",
+	VCMPGTFPCC:     "vcmpgtfp.",
+	VCMPGTSB:       "vcmpgtsb",
+	VCMPGTSBCC:     "vcmpgtsb.",
+	VCMPGTSH:       "vcmpgtsh",
+	VCMPGTSHCC:     "vcmpgtsh.",
+	VCMPGTSW:       "vcmpgtsw",
+	VCMPGTSWCC:     "vcmpgtsw.",
+	VCMPGTUB:       "vcmpgtub",
+	VCMPGTUBCC:     "vcmpgtub.",
+	VCMPGTUH:       "vcmpgtuh",
+	VCMPGTUHCC:     "vcmpgtuh.",
+	VCMPGTUW:       "vcmpgtuw",
+	VCMPGTUWCC:     "vcmpgtuw.",
+	VCTSXS:         "vctsxs",
+	VCTUXS:         "vctuxs",
+	VEXPTEFP:       "vexptefp",
+	VLOGEFP:        "vlogefp",
+	VMADDFP:        "vmaddfp",
+	VMAXFP:         "vmaxfp",
+	VMAXSB:         "vmaxsb",
+	VMAXSH:         "vmaxsh",
+	VMAXSW:         "vmaxsw",
+	VMAXUB:         "vmaxub",
+	VMAXUH:         "vmaxuh",
+	VMAXUW:         "vmaxuw",
+	VMHADDSHS:      "vmhaddshs",
+	VMHRADDSHS:     "vmhraddshs",
+	VMINFP:         "vminfp",
+	VMINSB:         "vminsb",
+	VMINSH:         "vminsh",
+	VMINSW:         "vminsw",
+	VMINUB:         "vminub",
+	VMINUH:         "vminuh",
+	VMINUW:         "vminuw",
+	VMLADDUHM:      "vmladduhm",
+	VMRGHB:         "vmrghb",
+	VMRGHH:         "vmrghh",
+	VMRGHW:         "vmrghw",
+	VMRGLB:         "vmrglb",
+	VMRGLH:         "vmrglh",
+	VMRGLW:         "vmrglw",
+	VMSUMMBM:       "vmsummbm",
+	VMSUMSHM:       "vmsumshm",
+	VMSUMSHS:       "vmsumshs",
+	VMSUMUBM:       "vmsumubm",
+	VMSUMUHM:       "vmsumuhm",
+	VMSUMUHS:       "vmsumuhs",
+	VMULESB:        "vmulesb",
+	VMULESH:        "vmulesh",
+	VMULEUB:        "vmuleub",
+	VMULEUH:        "vmuleuh",
+	VMULOSB:        "vmulosb",
+	VMULOSH:        "vmulosh",
+	VMULOUB:        "vmuloub",
+	VMULOUH:        "vmulouh",
+	VNMSUBFP:       "vnmsubfp",
+	VNOR:           "vnor",
+	VOR:            "vor",
+	VPERM:          "vperm",
+	VPKPX:          "vpkpx",
+	VPKSHSS:        "vpkshss",
+	VPKSHUS:        "vpkshus",
+	VPKSWSS:        "vpkswss",
+	VPKSWUS:        "vpkswus",
+	VPKUHUM:        "vpkuhum",
+	VPKUHUS:        "vpkuhus",
+	VPKUWUM:        "vpkuwum",
+	VPKUWUS:        "vpkuwus",
+	VREFP:          "vrefp",
+	VRFIM:          "vrfim",
+	VRFIN:          "vrfin",
+	VRFIP:          "vrfip",
+	VRFIZ:          "vrfiz",
+	VRLB:           "vrlb",
+	VRLH:           "vrlh",
+	VRLW:           "vrlw",
+	VRSQRTEFP:      "vrsqrtefp",
+	VSEL:           "vsel",
+	VSL:            "vsl",
+	VSLB:           "vslb",
+	VSLDOI:         "vsldoi",
+	VSLH:           "vslh",
+	VSLO:           "vslo",
+	VSLW:           "vslw",
+	VSPLTB:         "vspltb",
+	VSPLTH:         "vsplth",
+	VSPLTISB:       "vspltisb",
+	VSPLTISH:       "vspltish",
+	VSPLTISW:       "vspltisw",
+	VSPLTW:         "vspltw",
+	VSR:            "vsr",
+	VSRAB:          "vsrab",
+	VSRAH:          "vsrah",
+	VSRAW:          "vsraw",
+	VSRB:           "vsrb",
+	VSRH:           "vsrh",
+	VSRO:           "vsro",
+	VSRW:           "vsrw",
+	VSUBCUW:        "vsubcuw",
+	VSUBFP:         "vsubfp",
+	VSUBSBS:        "vsubsbs",
+	VSUBSHS:        "vsubshs",
+	VSUBSWS:        "vsubsws",
+	VSUBUBM:        "vsububm",
+	VSUBUBS:        "vsububs",
+	VSUBUHM:        "vsubuhm",
+	VSUBUHS:        "vsubuhs",
+	VSUBUWM:        "vsubuwm",
+	VSUBUWS:        "vsubuws",
+	VSUM2SWS:       "vsum2sws",
+	VSUM4SBS:       "vsum4sbs",
+	VSUM4SHS:       "vsum4shs",
+	VSUM4UBS:       "vsum4ubs",
+	VSUMSWS:        "vsumsws",
+	VUPKHPX:        "vupkhpx",
+	VUPKHSB:        "vupkhsb",
+	VUPKHSH:        "vupkhsh",
+	VUPKLPX:        "vupklpx",
+	VUPKLSB:        "vupklsb",
+	VUPKLSH:        "vupklsh",
+	VXOR:           "vxor",
+	FRE:            "fre",
+	FRECC:          "fre.",
+	FRIM:           "frim",
+	FRIMCC:         "frim.",
+	FRIN:           "frin",
+	FRINCC:         "frin.",
+	FRIP:           "frip",
+	FRIPCC:         "frip.",
+	FRIZ:           "friz",
+	FRIZCC:         "friz.",
+	FRSQRTES:       "frsqrtes",
+	FRSQRTESCC:     "frsqrtes.",
+	HRFID:          "hrfid",
+	POPCNTB:        "popcntb",
+	MFOCRF:         "mfocrf",
+	MTOCRF:         "mtocrf",
+	SLBMFEE:        "slbmfee",
+	SLBMFEV:        "slbmfev",
+	SLBMTE:         "slbmte",
+	RFSCV:          "rfscv",
+	SCV:            "scv",
+	LQ:             "lq",
+	STQ:            "stq",
+	CNTLZD:         "cntlzd",
+	CNTLZDCC:       "cntlzd.",
+	DCBF:           "dcbf",
+	DCBST:          "dcbst",
+	DCBT:           "dcbt",
+	DCBTST:         "dcbtst",
+	DIVD:           "divd",
+	DIVDCC:         "divd.",
+	DIVDO:          "divdo",
+	DIVDOCC:        "divdo.",
+	DIVDU:          "divdu",
+	DIVDUCC:        "divdu.",
+	DIVDUO:         "divduo",
+	DIVDUOCC:       "divduo.",
+	DIVW:           "divw",
+	DIVWCC:         "divw.",
+	DIVWO:          "divwo",
+	DIVWOCC:        "divwo.",
+	DIVWU:          "divwu",
+	DIVWUCC:        "divwu.",
+	DIVWUO:         "divwuo",
+	DIVWUOCC:       "divwuo.",
+	EIEIO:          "eieio",
+	EXTSB:          "extsb",
+	EXTSBCC:        "extsb.",
+	EXTSW:          "extsw",
+	EXTSWCC:        "extsw.",
+	FADDS:          "fadds",
+	FADDSCC:        "fadds.",
+	FCFID:          "fcfid",
+	FCFIDCC:        "fcfid.",
+	FCTID:          "fctid",
+	FCTIDCC:        "fctid.",
+	FCTIDZ:         "fctidz",
+	FCTIDZCC:       "fctidz.",
+	FDIVS:          "fdivs",
+	FDIVSCC:        "fdivs.",
+	FMADDS:         "fmadds",
+	FMADDSCC:       "fmadds.",
+	FMSUBS:         "fmsubs",
+	FMSUBSCC:       "fmsubs.",
+	FMULS:          "fmuls",
+	FMULSCC:        "fmuls.",
+	FNMADDS:        "fnmadds",
+	FNMADDSCC:      "fnmadds.",
+	FNMSUBS:        "fnmsubs",
+	FNMSUBSCC:      "fnmsubs.",
+	FRES:           "fres",
+	FRESCC:         "fres.",
+	FRSQRTE:        "frsqrte",
+	FRSQRTECC:      "frsqrte.",
+	FSEL:           "fsel",
+	FSELCC:         "fsel.",
+	FSQRTS:         "fsqrts",
+	FSQRTSCC:       "fsqrts.",
+	FSUBS:          "fsubs",
+	FSUBSCC:        "fsubs.",
+	ICBI:           "icbi",
+	LD:             "ld",
+	LDARX:          "ldarx",
+	LDU:            "ldu",
+	LDUX:           "ldux",
+	LDX:            "ldx",
+	LWA:            "lwa",
+	LWARX:          "lwarx",
+	LWAUX:          "lwaux",
+	LWAX:           "lwax",
+	MFTB:           "mftb",
+	MTMSRD:         "mtmsrd",
+	MULHD:          "mulhd",
+	MULHDCC:        "mulhd.",
+	MULHDU:         "mulhdu",
+	MULHDUCC:       "mulhdu.",
+	MULHW:          "mulhw",
+	MULHWCC:        "mulhw.",
+	MULHWU:         "mulhwu",
+	MULHWUCC:       "mulhwu.",
+	MULLD:          "mulld",
+	MULLDCC:        "mulld.",
+	MULLDO:         "mulldo",
+	MULLDOCC:       "mulldo.",
+	RFID:           "rfid",
+	RLDCL:          "rldcl",
+	RLDCLCC:        "rldcl.",
+	RLDCR:          "rldcr",
+	RLDCRCC:        "rldcr.",
+	RLDIC:          "rldic",
+	RLDICCC:        "rldic.",
+	RLDICL:         "rldicl",
+	RLDICLCC:       "rldicl.",
+	RLDICR:         "rldicr",
+	RLDICRCC:       "rldicr.",
+	RLDIMI:         "rldimi",
+	RLDIMICC:       "rldimi.",
+	SC:             "sc",
+	SLBIA:          "slbia",
+	SLBIE:          "slbie",
+	SLD:            "sld",
+	SLDCC:          "sld.",
+	SRAD:           "srad",
+	SRADCC:         "srad.",
+	SRADI:          "sradi",
+	SRADICC:        "sradi.",
+	SRD:            "srd",
+	SRDCC:          "srd.",
+	STD:            "std",
+	STDCXCC:        "stdcx.",
+	STDU:           "stdu",
+	STDUX:          "stdux",
+	STDX:           "stdx",
+	STFIWX:         "stfiwx",
+	STWCXCC:        "stwcx.",
+	SUBF:           "subf",
+	SUBFCC:         "subf.",
+	SUBFO:          "subfo",
+	SUBFOCC:        "subfo.",
+	TD:             "td",
+	TDI:            "tdi",
+	TLBSYNC:        "tlbsync",
+	FCTIW:          "fctiw",
+	FCTIWCC:        "fctiw.",
+	FCTIWZ:         "fctiwz",
+	FCTIWZCC:       "fctiwz.",
+	FSQRT:          "fsqrt",
+	FSQRTCC:        "fsqrt.",
+	ADD:            "add",
+	ADDCC:          "add.",
+	ADDO:           "addo",
+	ADDOCC:         "addo.",
+	ADDC:           "addc",
+	ADDCCC:         "addc.",
+	ADDCO:          "addco",
+	ADDCOCC:        "addco.",
+	ADDE:           "adde",
+	ADDECC:         "adde.",
+	ADDEO:          "addeo",
+	ADDEOCC:        "addeo.",
+	LI:             "li",
+	ADDI:           "addi",
+	ADDIC:          "addic",
+	ADDICCC:        "addic.",
+	LIS:            "lis",
+	ADDIS:          "addis",
+	ADDME:          "addme",
+	ADDMECC:        "addme.",
+	ADDMEO:         "addmeo",
+	ADDMEOCC:       "addmeo.",
+	ADDZE:          "addze",
+	ADDZECC:        "addze.",
+	ADDZEO:         "addzeo",
+	ADDZEOCC:       "addzeo.",
+	AND:            "and",
+	ANDCC:          "and.",
+	ANDC:           "andc",
+	ANDCCC:         "andc.",
+	ANDICC:         "andi.",
+	ANDISCC:        "andis.",
+	B:              "b",
+	BA:             "ba",
+	BL:             "bl",
+	BLA:            "bla",
+	BC:             "bc",
+	BCA:            "bca",
+	BCL:            "bcl",
+	BCLA:           "bcla",
+	BCCTR:          "bcctr",
+	BCCTRL:         "bcctrl",
+	BCLR:           "bclr",
+	BCLRL:          "bclrl",
+	CMPW:           "cmpw",
+	CMPD:           "cmpd",
+	CMP:            "cmp",
+	CMPWI:          "cmpwi",
+	CMPDI:          "cmpdi",
+	CMPI:           "cmpi",
+	CMPLW:          "cmplw",
+	CMPLD:          "cmpld",
+	CMPL:           "cmpl",
+	CMPLWI:         "cmplwi",
+	CMPLDI:         "cmpldi",
+	CMPLI:          "cmpli",
+	CNTLZW:         "cntlzw",
+	CNTLZWCC:       "cntlzw.",
+	CRAND:          "crand",
+	CRANDC:         "crandc",
+	CREQV:          "creqv",
+	CRNAND:         "crnand",
+	CRNOR:          "crnor",
+	CROR:           "cror",
+	CRORC:          "crorc",
+	CRXOR:          "crxor",
+	DCBZ:           "dcbz",
+	EQV:            "eqv",
+	EQVCC:          "eqv.",
+	EXTSH:          "extsh",
+	EXTSHCC:        "extsh.",
+	FABS:           "fabs",
+	FABSCC:         "fabs.",
+	FADD:           "fadd",
+	FADDCC:         "fadd.",
+	FCMPO:          "fcmpo",
+	FCMPU:          "fcmpu",
+	FDIV:           "fdiv",
+	FDIVCC:         "fdiv.",
+	FMADD:          "fmadd",
+	FMADDCC:        "fmadd.",
+	FMR:            "fmr",
+	FMRCC:          "fmr.",
+	FMSUB:          "fmsub",
+	FMSUBCC:        "fmsub.",
+	FMUL:           "fmul",
+	FMULCC:         "fmul.",
+	FNABS:          "fnabs",
+	FNABSCC:        "fnabs.",
+	FNEG:           "fneg",
+	FNEGCC:         "fneg.",
+	FNMADD:         "fnmadd",
+	FNMADDCC:       "fnmadd.",
+	FNMSUB:         "fnmsub",
+	FNMSUBCC:       "fnmsub.",
+	FRSP:           "frsp",
+	FRSPCC:         "frsp.",
+	FSUB:           "fsub",
+	FSUBCC:         "fsub.",
+	ISYNC:          "isync",
+	LBZ:            "lbz",
+	LBZU:           "lbzu",
+	LBZUX:          "lbzux",
+	LBZX:           "lbzx",
+	LFD:            "lfd",
+	LFDU:           "lfdu",
+	LFDUX:          "lfdux",
+	LFDX:           "lfdx",
+	LFS:            "lfs",
+	LFSU:           "lfsu",
+	LFSUX:          "lfsux",
+	LFSX:           "lfsx",
+	LHA:            "lha",
+	LHAU:           "lhau",
+	LHAUX:          "lhaux",
+	LHAX:           "lhax",
+	LHBRX:          "lhbrx",
+	LHZ:            "lhz",
+	LHZU:           "lhzu",
+	LHZUX:          "lhzux",
+	LHZX:           "lhzx",
+	LMW:            "lmw",
+	LSWI:           "lswi",
+	LSWX:           "lswx",
+	LWBRX:          "lwbrx",
+	LWZ:            "lwz",
+	LWZU:           "lwzu",
+	LWZUX:          "lwzux",
+	LWZX:           "lwzx",
+	MCRF:           "mcrf",
+	MCRFS:          "mcrfs",
+	MFCR:           "mfcr",
+	MFFS:           "mffs",
+	MFFSCC:         "mffs.",
+	MFMSR:          "mfmsr",
+	MFSPR:          "mfspr",
+	MTCRF:          "mtcrf",
+	MTFSB0:         "mtfsb0",
+	MTFSB0CC:       "mtfsb0.",
+	MTFSB1:         "mtfsb1",
+	MTFSB1CC:       "mtfsb1.",
+	MTFSF:          "mtfsf",
+	MTFSFCC:        "mtfsf.",
+	MTFSFI:         "mtfsfi",
+	MTFSFICC:       "mtfsfi.",
+	MTMSR:          "mtmsr",
+	MTSPR:          "mtspr",
+	MULLI:          "mulli",
+	MULLW:          "mullw",
+	MULLWCC:        "mullw.",
+	MULLWO:         "mullwo",
+	MULLWOCC:       "mullwo.",
+	NAND:           "nand",
+	NANDCC:         "nand.",
+	NEG:            "neg",
+	NEGCC:          "neg.",
+	NEGO:           "nego",
+	NEGOCC:         "nego.",
+	NOR:            "nor",
+	NORCC:          "nor.",
+	OR:             "or",
+	ORCC:           "or.",
+	ORC:            "orc",
+	ORCCC:          "orc.",
+	NOP:            "nop",
+	ORI:            "ori",
+	ORIS:           "oris",
+	RLWIMI:         "rlwimi",
+	RLWIMICC:       "rlwimi.",
+	RLWINM:         "rlwinm",
+	RLWINMCC:       "rlwinm.",
+	RLWNM:          "rlwnm",
+	RLWNMCC:        "rlwnm.",
+	SLW:            "slw",
+	SLWCC:          "slw.",
+	SRAW:           "sraw",
+	SRAWCC:         "sraw.",
+	SRAWI:          "srawi",
+	SRAWICC:        "srawi.",
+	SRW:            "srw",
+	SRWCC:          "srw.",
+	STB:            "stb",
+	STBU:           "stbu",
+	STBUX:          "stbux",
+	STBX:           "stbx",
+	STFD:           "stfd",
+	STFDU:          "stfdu",
+	STFDUX:         "stfdux",
+	STFDX:          "stfdx",
+	STFS:           "stfs",
+	STFSU:          "stfsu",
+	STFSUX:         "stfsux",
+	STFSX:          "stfsx",
+	STH:            "sth",
+	STHBRX:         "sthbrx",
+	STHU:           "sthu",
+	STHUX:          "sthux",
+	STHX:           "sthx",
+	STMW:           "stmw",
+	STSWI:          "stswi",
+	STSWX:          "stswx",
+	STW:            "stw",
+	STWBRX:         "stwbrx",
+	STWU:           "stwu",
+	STWUX:          "stwux",
+	STWX:           "stwx",
+	SUBFC:          "subfc",
+	SUBFCCC:        "subfc.",
+	SUBFCO:         "subfco",
+	SUBFCOCC:       "subfco.",
+	SUBFE:          "subfe",
+	SUBFECC:        "subfe.",
+	SUBFEO:         "subfeo",
+	SUBFEOCC:       "subfeo.",
+	SUBFIC:         "subfic",
+	SUBFME:         "subfme",
+	SUBFMECC:       "subfme.",
+	SUBFMEO:        "subfmeo",
+	SUBFMEOCC:      "subfmeo.",
+	SUBFZE:         "subfze",
+	SUBFZECC:       "subfze.",
+	SUBFZEO:        "subfzeo",
+	SUBFZEOCC:      "subfzeo.",
+	SYNC:           "sync",
+	TLBIE:          "tlbie",
+	TW:             "tw",
+	TWI:            "twi",
+	XOR:            "xor",
+	XORCC:          "xor.",
+	XORI:           "xori",
+	XORIS:          "xoris",
 }
 
 var (
-	ap_Reg_11_15               = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{11, 5}}}
-	ap_Reg_6_10                = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{6, 5}}}
-	ap_PCRel_6_29_shift2       = &argField{Type: TypePCRel, Shift: 2, BitFields: BitFields{{6, 24}}}
-	ap_Label_6_29_shift2       = &argField{Type: TypeLabel, Shift: 2, BitFields: BitFields{{6, 24}}}
-	ap_ImmUnsigned_6_10        = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{6, 5}}}
-	ap_CondRegBit_11_15        = &argField{Type: TypeCondRegBit, Shift: 0, BitFields: BitFields{{11, 5}}}
-	ap_PCRel_16_29_shift2      = &argField{Type: TypePCRel, Shift: 2, BitFields: BitFields{{16, 14}}}
-	ap_Label_16_29_shift2      = &argField{Type: TypeLabel, Shift: 2, BitFields: BitFields{{16, 14}}}
-	ap_ImmUnsigned_19_20       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{19, 2}}}
-	ap_CondRegBit_6_10         = &argField{Type: TypeCondRegBit, Shift: 0, BitFields: BitFields{{6, 5}}}
-	ap_CondRegBit_16_20        = &argField{Type: TypeCondRegBit, Shift: 0, BitFields: BitFields{{16, 5}}}
-	ap_CondRegField_6_8        = &argField{Type: TypeCondRegField, Shift: 0, BitFields: BitFields{{6, 3}}}
-	ap_CondRegField_11_13      = &argField{Type: TypeCondRegField, Shift: 0, BitFields: BitFields{{11, 3}}}
-	ap_ImmUnsigned_20_26       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{20, 7}}}
-	ap_SpReg_11_20             = &argField{Type: TypeSpReg, Shift: 0, BitFields: BitFields{{11, 10}}}
-	ap_Offset_16_31            = &argField{Type: TypeOffset, Shift: 0, BitFields: BitFields{{16, 16}}}
-	ap_Reg_16_20               = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{16, 5}}}
-	ap_Offset_16_29_shift2     = &argField{Type: TypeOffset, Shift: 2, BitFields: BitFields{{16, 14}}}
-	ap_Offset_16_27_shift4     = &argField{Type: TypeOffset, Shift: 4, BitFields: BitFields{{16, 12}}}
-	ap_ImmUnsigned_16_20       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 5}}}
-	ap_ImmSigned_16_31         = &argField{Type: TypeImmSigned, Shift: 0, BitFields: BitFields{{16, 16}}}
-	ap_ImmUnsigned_16_31       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 16}}}
-	ap_CondRegBit_21_25        = &argField{Type: TypeCondRegBit, Shift: 0, BitFields: BitFields{{21, 5}}}
-	ap_ImmUnsigned_21_25       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{21, 5}}}
-	ap_ImmUnsigned_26_30       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{26, 5}}}
-	ap_ImmUnsigned_30_30_16_20 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{30, 1}, {16, 5}}}
-	ap_ImmUnsigned_26_26_21_25 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{26, 1}, {21, 5}}}
-	ap_SpReg_16_20_11_15       = &argField{Type: TypeSpReg, Shift: 0, BitFields: BitFields{{16, 5}, {11, 5}}}
-	ap_ImmUnsigned_12_19       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{12, 8}}}
-	ap_ImmUnsigned_10_10       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{10, 1}}}
-	ap_VecSReg_31_31_6_10      = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{31, 1}, {6, 5}}}
-	ap_FPReg_6_10              = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{6, 5}}}
-	ap_FPReg_16_20             = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{16, 5}}}
-	ap_FPReg_11_15             = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{11, 5}}}
-	ap_FPReg_21_25             = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{21, 5}}}
-	ap_ImmUnsigned_16_19       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 4}}}
-	ap_ImmUnsigned_15_15       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{15, 1}}}
-	ap_ImmUnsigned_7_14        = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{7, 8}}}
-	ap_ImmUnsigned_6_6         = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{6, 1}}}
-	ap_VecReg_6_10             = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{6, 5}}}
-	ap_VecReg_11_15            = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{11, 5}}}
-	ap_VecReg_16_20            = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{16, 5}}}
-	ap_ImmUnsigned_12_15       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{12, 4}}}
-	ap_ImmUnsigned_13_15       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{13, 3}}}
-	ap_ImmUnsigned_14_15       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{14, 2}}}
-	ap_ImmSigned_11_15         = &argField{Type: TypeImmSigned, Shift: 0, BitFields: BitFields{{11, 5}}}
-	ap_VecReg_21_25            = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{21, 5}}}
-	ap_ImmUnsigned_22_25       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{22, 4}}}
-	ap_ImmUnsigned_11_15       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 5}}}
-	ap_ImmUnsigned_16_16       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 1}}}
-	ap_ImmUnsigned_17_20       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{17, 4}}}
-	ap_ImmUnsigned_22_22       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{22, 1}}}
-	ap_ImmUnsigned_16_21       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 6}}}
-	ap_ImmUnsigned_21_22       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{21, 2}}}
-	ap_ImmUnsigned_11_12       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 2}}}
-	ap_ImmUnsigned_11_11       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 1}}}
-	ap_VecSReg_28_28_6_10      = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{28, 1}, {6, 5}}}
-	ap_VecSReg_30_30_16_20     = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{30, 1}, {16, 5}}}
-	ap_VecSReg_29_29_11_15     = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{29, 1}, {11, 5}}}
-	ap_ImmUnsigned_22_23       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{22, 2}}}
-	ap_VecSReg_28_28_21_25     = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{28, 1}, {21, 5}}}
-	ap_CondRegField_29_31      = &argField{Type: TypeCondRegField, Shift: 0, BitFields: BitFields{{29, 3}}}
-	ap_ImmUnsigned_7_10        = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{7, 4}}}
-	ap_ImmUnsigned_9_10        = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{9, 2}}}
-	ap_ImmUnsigned_31_31       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{31, 1}}}
-	ap_ImmSigned_16_20         = &argField{Type: TypeImmSigned, Shift: 0, BitFields: BitFields{{16, 5}}}
-	ap_ImmUnsigned_20_20       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{20, 1}}}
-	ap_ImmUnsigned_8_10        = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{8, 3}}}
-	ap_SpReg_12_15             = &argField{Type: TypeSpReg, Shift: 0, BitFields: BitFields{{12, 4}}}
-	ap_ImmUnsigned_6_20        = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{6, 15}}}
-	ap_ImmUnsigned_11_20       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 10}}}
-	ap_Reg_21_25               = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{21, 5}}}
+	ap_Reg_11_15                     = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{11, 5, 0}}}
+	ap_Reg_6_10                      = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{6, 5, 0}}}
+	ap_Reg_16_20                     = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{16, 5, 0}}}
+	ap_FPReg_6_10                    = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{6, 5, 0}}}
+	ap_VecReg_16_20                  = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{16, 5, 0}}}
+	ap_VecReg_6_10                   = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{6, 5, 0}}}
+	ap_FPReg_16_20                   = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{16, 5, 0}}}
+	ap_VecSReg_31_31_6_10            = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{31, 1, 0}, {6, 5, 0}}}
+	ap_ImmUnsigned_16_20             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 5, 0}}}
+	ap_VecSpReg_10_10_6_9            = &argField{Type: TypeVecSpReg, Shift: 0, BitFields: BitFields{{10, 1, 0}, {6, 4, 0}}}
+	ap_Offset_16_27_shift4           = &argField{Type: TypeOffset, Shift: 4, BitFields: BitFields{{16, 12, 0}}}
+	ap_ImmUnsigned_16_25_11_15_31_31 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 10, 0}, {11, 5, 0}, {31, 1, 0}}}
+	ap_Reg_38_42                     = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{6, 5, 1}}}
+	ap_Reg_43_47                     = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{11, 5, 1}}}
+	ap_ImmSigned_14_31_48_63         = &argField{Type: TypeImmSigned, Shift: 0, BitFields: BitFields{{14, 18, 0}, {16, 16, 1}}}
+	ap_ImmUnsigned_11_11             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 1, 0}}}
+	ap_Offset_14_31_48_63            = &argField{Type: TypeOffset, Shift: 0, BitFields: BitFields{{14, 18, 0}, {16, 16, 1}}}
+	ap_FPReg_38_42                   = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{6, 5, 1}}}
+	ap_VecReg_38_42                  = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{6, 5, 1}}}
+	ap_VecSReg_37_37_38_42           = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{5, 1, 1}, {6, 5, 1}}}
+	ap_VecSpReg_42_42_38_41          = &argField{Type: TypeVecSpReg, Shift: 0, BitFields: BitFields{{10, 1, 1}, {6, 4, 1}}}
+	ap_MMAReg_38_40                  = &argField{Type: TypeMMAReg, Shift: 0, BitFields: BitFields{{6, 3, 1}}}
+	ap_VecSReg_61_61_43_47           = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{29, 1, 1}, {11, 5, 1}}}
+	ap_VecSReg_62_62_48_52           = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{30, 1, 1}, {16, 5, 1}}}
+	ap_ImmUnsigned_24_27             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{24, 4, 0}}}
+	ap_ImmUnsigned_28_31             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{28, 4, 0}}}
+	ap_ImmUnsigned_16_17             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 2, 0}}}
+	ap_ImmUnsigned_28_29             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{28, 2, 0}}}
+	ap_ImmUnsigned_16_23             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 8, 0}}}
+	ap_ImmUnsigned_16_19             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 4, 0}}}
+	ap_CondRegBit_11_15              = &argField{Type: TypeCondRegBit, Shift: 0, BitFields: BitFields{{11, 5, 0}}}
+	ap_VecReg_11_15                  = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{11, 5, 0}}}
+	ap_CondRegField_6_8              = &argField{Type: TypeCondRegField, Shift: 0, BitFields: BitFields{{6, 3, 0}}}
+	ap_ImmUnsigned_15_15             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{15, 1, 0}}}
+	ap_Reg_21_25                     = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{21, 5, 0}}}
+	ap_ImmUnsigned_13_15             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{13, 3, 0}}}
+	ap_ImmUnsigned_12_15             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{12, 4, 0}}}
+	ap_VecReg_21_25                  = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{21, 5, 0}}}
+	ap_ImmUnsigned_23_25             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{23, 3, 0}}}
+	ap_MMAReg_6_8                    = &argField{Type: TypeMMAReg, Shift: 0, BitFields: BitFields{{6, 3, 0}}}
+	ap_VecSReg_29_29_11_15           = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{29, 1, 0}, {11, 5, 0}}}
+	ap_VecSReg_30_30_16_20           = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{30, 1, 0}, {16, 5, 0}}}
+	ap_VecSReg_63_63_38_42           = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{31, 1, 1}, {6, 5, 1}}}
+	ap_VecSReg_60_60_53_57           = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{28, 1, 1}, {21, 5, 1}}}
+	ap_ImmUnsigned_24_31             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{24, 8, 0}}}
+	ap_ImmUnsigned_11_15             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 5, 0}}}
+	ap_ImmUnsigned_29_31             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{29, 3, 0}}}
+	ap_VecSReg_47_47_38_42           = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{15, 1, 1}, {6, 5, 1}}}
+	ap_ImmUnsigned_46_46             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{14, 1, 1}}}
+	ap_ImmUnsigned_16_31_48_63       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 16, 0}, {16, 16, 1}}}
+	ap_ImmUnsigned_21_22             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{21, 2, 0}}}
+	ap_ImmUnsigned_18_20             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{18, 3, 0}}}
+	ap_ImmUnsigned_19_20             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{19, 2, 0}}}
+	ap_ImmSigned_16_25_11_15_31_31   = &argField{Type: TypeImmSigned, Shift: 0, BitFields: BitFields{{16, 10, 0}, {11, 5, 0}, {31, 1, 0}}}
+	ap_ImmUnsigned_22_22             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{22, 1, 0}}}
+	ap_ImmUnsigned_10_10             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{10, 1, 0}}}
+	ap_ImmUnsigned_14_15             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{14, 2, 0}}}
+	ap_ImmUnsigned_10_15             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{10, 6, 0}}}
+	ap_ImmUnsigned_30_30_16_20       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{30, 1, 0}, {16, 5, 0}}}
+	ap_Offset_16_29_shift2           = &argField{Type: TypeOffset, Shift: 2, BitFields: BitFields{{16, 14, 0}}}
+	ap_VecSReg_28_28_6_10            = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{28, 1, 0}, {6, 5, 0}}}
+	ap_CondRegField_11_13            = &argField{Type: TypeCondRegField, Shift: 0, BitFields: BitFields{{11, 3, 0}}}
+	ap_ImmUnsigned_9_10              = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{9, 2, 0}}}
+	ap_ImmUnsigned_9_15              = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{9, 7, 0}}}
+	ap_ImmUnsigned_25_25_29_29_11_15 = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{25, 1, 0}, {29, 1, 0}, {11, 5, 0}}}
+	ap_ImmUnsigned_13_20             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{13, 8, 0}}}
+	ap_ImmUnsigned_6_10              = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{6, 5, 0}}}
+	ap_FPReg_11_15                   = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{11, 5, 0}}}
+	ap_ImmUnsigned_7_10              = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{7, 4, 0}}}
+	ap_ImmUnsigned_31_31             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{31, 1, 0}}}
+	ap_SpReg_11_20                   = &argField{Type: TypeSpReg, Shift: 0, BitFields: BitFields{{11, 10, 0}}}
+	ap_ImmUnsigned_20_20             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{20, 1, 0}}}
+	ap_ImmUnsigned_16_16             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 1, 0}}}
+	ap_ImmUnsigned_17_20             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{17, 4, 0}}}
+	ap_ImmUnsigned_22_23             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{22, 2, 0}}}
+	ap_VecSReg_28_28_21_25           = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{28, 1, 0}, {21, 5, 0}}}
+	ap_ImmUnsigned_11_12             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 2, 0}}}
+	ap_ImmSigned_11_15               = &argField{Type: TypeImmSigned, Shift: 0, BitFields: BitFields{{11, 5, 0}}}
+	ap_ImmUnsigned_16_21             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 6, 0}}}
+	ap_CondRegBit_21_25              = &argField{Type: TypeCondRegBit, Shift: 0, BitFields: BitFields{{21, 5, 0}}}
+	ap_ImmUnsigned_12_13             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{12, 2, 0}}}
+	ap_ImmUnsigned_14_14             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{14, 1, 0}}}
+	ap_ImmUnsigned_22_25             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{22, 4, 0}}}
+	ap_ImmUnsigned_12_19             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{12, 8, 0}}}
+	ap_ImmUnsigned_20_26             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{20, 7, 0}}}
+	ap_ImmUnsigned_8_10              = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{8, 3, 0}}}
+	ap_FPReg_21_25                   = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{21, 5, 0}}}
+	ap_SpReg_16_20_11_15             = &argField{Type: TypeSpReg, Shift: 0, BitFields: BitFields{{16, 5, 0}, {11, 5, 0}}}
+	ap_ImmUnsigned_26_26_21_25       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{26, 1, 0}, {21, 5, 0}}}
+	ap_ImmSigned_16_31               = &argField{Type: TypeImmSigned, Shift: 0, BitFields: BitFields{{16, 16, 0}}}
+	ap_ImmUnsigned_16_31             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 16, 0}}}
+	ap_PCRel_6_29_shift2             = &argField{Type: TypePCRel, Shift: 2, BitFields: BitFields{{6, 24, 0}}}
+	ap_Label_6_29_shift2             = &argField{Type: TypeLabel, Shift: 2, BitFields: BitFields{{6, 24, 0}}}
+	ap_PCRel_16_29_shift2            = &argField{Type: TypePCRel, Shift: 2, BitFields: BitFields{{16, 14, 0}}}
+	ap_Label_16_29_shift2            = &argField{Type: TypeLabel, Shift: 2, BitFields: BitFields{{16, 14, 0}}}
+	ap_CondRegBit_6_10               = &argField{Type: TypeCondRegBit, Shift: 0, BitFields: BitFields{{6, 5, 0}}}
+	ap_CondRegBit_16_20              = &argField{Type: TypeCondRegBit, Shift: 0, BitFields: BitFields{{16, 5, 0}}}
+	ap_Offset_16_31                  = &argField{Type: TypeOffset, Shift: 0, BitFields: BitFields{{16, 16, 0}}}
+	ap_ImmUnsigned_7_14              = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{7, 8, 0}}}
+	ap_ImmUnsigned_6_6               = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{6, 1, 0}}}
+	ap_ImmUnsigned_6_8               = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{6, 3, 0}}}
+	ap_ImmUnsigned_21_25             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{21, 5, 0}}}
+	ap_ImmUnsigned_26_30             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{26, 5, 0}}}
 )
 
 var instFormats = [...]instFormat{
-	{CNTLZW, 0xfc0007ff, 0x7c000034, 0xf800, // Count Leading Zeros Word X-form (cntlzw RA, RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{CNTLZWCC, 0xfc0007ff, 0x7c000035, 0xf800, // Count Leading Zeros Word X-form (cntlzw. RA, RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{B, 0xfc000003, 0x48000000, 0x0, // Branch I-form (b target_addr)
-		[5]*argField{ap_PCRel_6_29_shift2}},
-	{BA, 0xfc000003, 0x48000002, 0x0, // Branch I-form (ba target_addr)
-		[5]*argField{ap_Label_6_29_shift2}},
-	{BL, 0xfc000003, 0x48000001, 0x0, // Branch I-form (bl target_addr)
-		[5]*argField{ap_PCRel_6_29_shift2}},
-	{BLA, 0xfc000003, 0x48000003, 0x0, // Branch I-form (bla target_addr)
-		[5]*argField{ap_Label_6_29_shift2}},
-	{BC, 0xfc000003, 0x40000000, 0x0, // Branch Conditional B-form (bc BO,BI,target_addr)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_PCRel_16_29_shift2}},
-	{BCA, 0xfc000003, 0x40000002, 0x0, // Branch Conditional B-form (bca BO,BI,target_addr)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_Label_16_29_shift2}},
-	{BCL, 0xfc000003, 0x40000001, 0x0, // Branch Conditional B-form (bcl BO,BI,target_addr)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_PCRel_16_29_shift2}},
-	{BCLA, 0xfc000003, 0x40000003, 0x0, // Branch Conditional B-form (bcla BO,BI,target_addr)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_Label_16_29_shift2}},
-	{BCLR, 0xfc0007ff, 0x4c000020, 0xe000, // Branch Conditional to Link Register XL-form (bclr BO,BI,BH)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}},
-	{BCLRL, 0xfc0007ff, 0x4c000021, 0xe000, // Branch Conditional to Link Register XL-form (bclrl BO,BI,BH)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}},
-	{BCCTR, 0xfc0007ff, 0x4c000420, 0xe000, // Branch Conditional to Count Register XL-form (bcctr BO,BI,BH)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}},
-	{BCCTRL, 0xfc0007ff, 0x4c000421, 0xe000, // Branch Conditional to Count Register XL-form (bcctrl BO,BI,BH)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}},
-	{BCTAR, 0xfc0007ff, 0x4c000460, 0xe000, // Branch Conditional to Branch Target Address Register XL-form (bctar BO,BI,BH)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}},
-	{BCTARL, 0xfc0007ff, 0x4c000461, 0xe000, // Branch Conditional to Branch Target Address Register XL-form (bctarl BO,BI,BH)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}},
-	{CRAND, 0xfc0007fe, 0x4c000202, 0x1, // Condition Register AND XL-form (crand BT,BA,BB)
-		[5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
-	{CROR, 0xfc0007fe, 0x4c000382, 0x1, // Condition Register OR XL-form (cror BT,BA,BB)
-		[5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
-	{CRNAND, 0xfc0007fe, 0x4c0001c2, 0x1, // Condition Register NAND XL-form (crnand BT,BA,BB)
-		[5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
-	{CRXOR, 0xfc0007fe, 0x4c000182, 0x1, // Condition Register XOR XL-form (crxor BT,BA,BB)
-		[5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
-	{CRNOR, 0xfc0007fe, 0x4c000042, 0x1, // Condition Register NOR XL-form (crnor BT,BA,BB)
-		[5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
-	{CRANDC, 0xfc0007fe, 0x4c000102, 0x1, // Condition Register AND with Complement XL-form (crandc BT,BA,BB)
-		[5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
-	{MCRF, 0xfc0007fe, 0x4c000000, 0x63f801, // Move Condition Register Field XL-form (mcrf BF,BFA)
-		[5]*argField{ap_CondRegField_6_8, ap_CondRegField_11_13}},
-	{CREQV, 0xfc0007fe, 0x4c000242, 0x1, // Condition Register Equivalent XL-form (creqv BT,BA,BB)
-		[5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
-	{CRORC, 0xfc0007fe, 0x4c000342, 0x1, // Condition Register OR with Complement XL-form (crorc BT,BA,BB)
-		[5]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
-	{SC, 0xfc000002, 0x44000002, 0x3fff01d, // System Call SC-form (sc LEV)
-		[5]*argField{ap_ImmUnsigned_20_26}},
-	{CLRBHRB, 0xfc0007fe, 0x7c00035c, 0x3fff801, // Clear BHRB X-form (clrbhrb)
-		[5]*argField{}},
-	{MFBHRBE, 0xfc0007fe, 0x7c00025c, 0x1, // Move From Branch History Rolling Buffer XFX-form (mfbhrbe RT,BHRBE)
-		[5]*argField{ap_Reg_6_10, ap_SpReg_11_20}},
-	{LBZ, 0xfc000000, 0x88000000, 0x0, // Load Byte and Zero D-form (lbz RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LBZU, 0xfc000000, 0x8c000000, 0x0, // Load Byte and Zero with Update D-form (lbzu RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LBZX, 0xfc0007fe, 0x7c0000ae, 0x1, // Load Byte and Zero Indexed X-form (lbzx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LBZUX, 0xfc0007fe, 0x7c0000ee, 0x1, // Load Byte and Zero with Update Indexed X-form (lbzux RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LHZ, 0xfc000000, 0xa0000000, 0x0, // Load Halfword and Zero D-form (lhz RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LHZU, 0xfc000000, 0xa4000000, 0x0, // Load Halfword and Zero with Update D-form (lhzu RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LHZX, 0xfc0007fe, 0x7c00022e, 0x1, // Load Halfword and Zero Indexed X-form (lhzx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LHZUX, 0xfc0007fe, 0x7c00026e, 0x1, // Load Halfword and Zero with Update Indexed X-form (lhzux RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LHA, 0xfc000000, 0xa8000000, 0x0, // Load Halfword Algebraic D-form (lha RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LHAU, 0xfc000000, 0xac000000, 0x0, // Load Halfword Algebraic with Update D-form (lhau RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LHAX, 0xfc0007fe, 0x7c0002ae, 0x1, // Load Halfword Algebraic Indexed X-form (lhax RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LHAUX, 0xfc0007fe, 0x7c0002ee, 0x1, // Load Halfword Algebraic with Update Indexed X-form (lhaux RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LWZ, 0xfc000000, 0x80000000, 0x0, // Load Word and Zero D-form (lwz RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LWZU, 0xfc000000, 0x84000000, 0x0, // Load Word and Zero with Update D-form (lwzu RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LWZX, 0xfc0007fe, 0x7c00002e, 0x1, // Load Word and Zero Indexed X-form (lwzx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LWZUX, 0xfc0007fe, 0x7c00006e, 0x1, // Load Word and Zero with Update Indexed X-form (lwzux RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LWA, 0xfc000003, 0xe8000002, 0x0, // Load Word Algebraic DS-form (lwa RT,DS(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
-	{LWAX, 0xfc0007fe, 0x7c0002aa, 0x1, // Load Word Algebraic Indexed X-form (lwax RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LWAUX, 0xfc0007fe, 0x7c0002ea, 0x1, // Load Word Algebraic with Update Indexed X-form (lwaux RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LD, 0xfc000003, 0xe8000000, 0x0, // Load Doubleword DS-form (ld RT,DS(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
-	{LDU, 0xfc000003, 0xe8000001, 0x0, // Load Doubleword with Update DS-form (ldu RT,DS(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
-	{LDX, 0xfc0007fe, 0x7c00002a, 0x1, // Load Doubleword Indexed X-form (ldx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LDUX, 0xfc0007fe, 0x7c00006a, 0x1, // Load Doubleword with Update Indexed X-form (ldux RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STB, 0xfc000000, 0x98000000, 0x0, // Store Byte D-form (stb RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{STBU, 0xfc000000, 0x9c000000, 0x0, // Store Byte with Update D-form (stbu RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{STBX, 0xfc0007fe, 0x7c0001ae, 0x1, // Store Byte Indexed X-form (stbx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STBUX, 0xfc0007fe, 0x7c0001ee, 0x1, // Store Byte with Update Indexed X-form (stbux RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STH, 0xfc000000, 0xb0000000, 0x0, // Store Halfword D-form (sth RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{STHU, 0xfc000000, 0xb4000000, 0x0, // Store Halfword with Update D-form (sthu RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{STHX, 0xfc0007fe, 0x7c00032e, 0x1, // Store Halfword Indexed X-form (sthx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STHUX, 0xfc0007fe, 0x7c00036e, 0x1, // Store Halfword with Update Indexed X-form (sthux RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STW, 0xfc000000, 0x90000000, 0x0, // Store Word D-form (stw RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{STWU, 0xfc000000, 0x94000000, 0x0, // Store Word with Update D-form (stwu RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{STWX, 0xfc0007fe, 0x7c00012e, 0x1, // Store Word Indexed X-form (stwx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STWUX, 0xfc0007fe, 0x7c00016e, 0x1, // Store Word with Update Indexed X-form (stwux RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STD, 0xfc000003, 0xf8000000, 0x0, // Store Doubleword DS-form (std RS,DS(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
-	{STDU, 0xfc000003, 0xf8000001, 0x0, // Store Doubleword with Update DS-form (stdu RS,DS(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
-	{STDX, 0xfc0007fe, 0x7c00012a, 0x1, // Store Doubleword Indexed X-form (stdx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STDUX, 0xfc0007fe, 0x7c00016a, 0x1, // Store Doubleword with Update Indexed X-form (stdux RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LQ, 0xfc000000, 0xe0000000, 0xf, // Load Quadword DQ-form (lq RTp,DQ(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_27_shift4, ap_Reg_11_15}},
-	{STQ, 0xfc000003, 0xf8000002, 0x0, // Store Quadword DS-form (stq RSp,DS(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
-	{LHBRX, 0xfc0007fe, 0x7c00062c, 0x1, // Load Halfword Byte-Reverse Indexed X-form (lhbrx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LWBRX, 0xfc0007fe, 0x7c00042c, 0x1, // Load Word Byte-Reverse Indexed X-form (lwbrx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STHBRX, 0xfc0007fe, 0x7c00072c, 0x1, // Store Halfword Byte-Reverse Indexed X-form (sthbrx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STWBRX, 0xfc0007fe, 0x7c00052c, 0x1, // Store Word Byte-Reverse Indexed X-form (stwbrx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LDBRX, 0xfc0007fe, 0x7c000428, 0x1, // Load Doubleword Byte-Reverse Indexed X-form (ldbrx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STDBRX, 0xfc0007fe, 0x7c000528, 0x1, // Store Doubleword Byte-Reverse Indexed X-form (stdbrx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LMW, 0xfc000000, 0xb8000000, 0x0, // Load Multiple Word D-form (lmw RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{STMW, 0xfc000000, 0xbc000000, 0x0, // Store Multiple Word D-form (stmw RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LSWI, 0xfc0007fe, 0x7c0004aa, 0x1, // Load String Word Immediate X-form (lswi RT,RA,NB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}},
-	{LSWX, 0xfc0007fe, 0x7c00042a, 0x1, // Load String Word Indexed X-form (lswx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STSWI, 0xfc0007fe, 0x7c0005aa, 0x1, // Store String Word Immediate X-form (stswi RS,RA,NB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}},
-	{STSWX, 0xfc0007fe, 0x7c00052a, 0x1, // Store String Word Indexed X-form (stswx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LI, 0xfc1f0000, 0x38000000, 0x0, // Add Immediate D-form (li RT,SI)
-		[5]*argField{ap_Reg_6_10, ap_ImmSigned_16_31}},
-	{ADDI, 0xfc000000, 0x38000000, 0x0, // Add Immediate D-form (addi RT,RA,SI)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
-	{LIS, 0xfc1f0000, 0x3c000000, 0x0, // Add Immediate Shifted D-form (lis RT, SI)
-		[5]*argField{ap_Reg_6_10, ap_ImmSigned_16_31}},
-	{ADDIS, 0xfc000000, 0x3c000000, 0x0, // Add Immediate Shifted D-form (addis RT,RA,SI)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
-	{ADD, 0xfc0007ff, 0x7c000214, 0x0, // Add XO-form (add RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDCC, 0xfc0007ff, 0x7c000215, 0x0, // Add XO-form (add. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDO, 0xfc0007ff, 0x7c000614, 0x0, // Add XO-form (addo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDOCC, 0xfc0007ff, 0x7c000615, 0x0, // Add XO-form (addo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDIC, 0xfc000000, 0x30000000, 0x0, // Add Immediate Carrying D-form (addic RT,RA,SI)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
-	{SUBF, 0xfc0007ff, 0x7c000050, 0x0, // Subtract From XO-form (subf RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SUBFCC, 0xfc0007ff, 0x7c000051, 0x0, // Subtract From XO-form (subf. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SUBFO, 0xfc0007ff, 0x7c000450, 0x0, // Subtract From XO-form (subfo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SUBFOCC, 0xfc0007ff, 0x7c000451, 0x0, // Subtract From XO-form (subfo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDICCC, 0xfc000000, 0x34000000, 0x0, // Add Immediate Carrying and Record D-form (addic. RT,RA,SI)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
-	{SUBFIC, 0xfc000000, 0x20000000, 0x0, // Subtract From Immediate Carrying D-form (subfic RT,RA,SI)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
-	{ADDC, 0xfc0007ff, 0x7c000014, 0x0, // Add Carrying XO-form (addc RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDCCC, 0xfc0007ff, 0x7c000015, 0x0, // Add Carrying XO-form (addc. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDCO, 0xfc0007ff, 0x7c000414, 0x0, // Add Carrying XO-form (addco RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDCOCC, 0xfc0007ff, 0x7c000415, 0x0, // Add Carrying XO-form (addco. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SUBFC, 0xfc0007ff, 0x7c000010, 0x0, // Subtract From Carrying XO-form (subfc RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SUBFCCC, 0xfc0007ff, 0x7c000011, 0x0, // Subtract From Carrying XO-form (subfc. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SUBFCO, 0xfc0007ff, 0x7c000410, 0x0, // Subtract From Carrying XO-form (subfco RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SUBFCOCC, 0xfc0007ff, 0x7c000411, 0x0, // Subtract From Carrying XO-form (subfco. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDE, 0xfc0007ff, 0x7c000114, 0x0, // Add Extended XO-form (adde RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDECC, 0xfc0007ff, 0x7c000115, 0x0, // Add Extended XO-form (adde. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDEO, 0xfc0007ff, 0x7c000514, 0x0, // Add Extended XO-form (addeo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDEOCC, 0xfc0007ff, 0x7c000515, 0x0, // Add Extended XO-form (addeo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ADDME, 0xfc0007ff, 0x7c0001d4, 0xf800, // Add to Minus One Extended XO-form (addme RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{ADDMECC, 0xfc0007ff, 0x7c0001d5, 0xf800, // Add to Minus One Extended XO-form (addme. RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{ADDMEO, 0xfc0007ff, 0x7c0005d4, 0xf800, // Add to Minus One Extended XO-form (addmeo RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{ADDMEOCC, 0xfc0007ff, 0x7c0005d5, 0xf800, // Add to Minus One Extended XO-form (addmeo. RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{SUBFE, 0xfc0007ff, 0x7c000110, 0x0, // Subtract From Extended XO-form (subfe RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SUBFECC, 0xfc0007ff, 0x7c000111, 0x0, // Subtract From Extended XO-form (subfe. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SUBFEO, 0xfc0007ff, 0x7c000510, 0x0, // Subtract From Extended XO-form (subfeo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SUBFEOCC, 0xfc0007ff, 0x7c000511, 0x0, // Subtract From Extended XO-form (subfeo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SUBFME, 0xfc0007ff, 0x7c0001d0, 0xf800, // Subtract From Minus One Extended XO-form (subfme RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{SUBFMECC, 0xfc0007ff, 0x7c0001d1, 0xf800, // Subtract From Minus One Extended XO-form (subfme. RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{SUBFMEO, 0xfc0007ff, 0x7c0005d0, 0xf800, // Subtract From Minus One Extended XO-form (subfmeo RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{SUBFMEOCC, 0xfc0007ff, 0x7c0005d1, 0xf800, // Subtract From Minus One Extended XO-form (subfmeo. RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{ADDZE, 0xfc0007ff, 0x7c000194, 0xf800, // Add to Zero Extended XO-form (addze RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{ADDZECC, 0xfc0007ff, 0x7c000195, 0xf800, // Add to Zero Extended XO-form (addze. RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{ADDZEO, 0xfc0007ff, 0x7c000594, 0xf800, // Add to Zero Extended XO-form (addzeo RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{ADDZEOCC, 0xfc0007ff, 0x7c000595, 0xf800, // Add to Zero Extended XO-form (addzeo. RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{SUBFZE, 0xfc0007ff, 0x7c000190, 0xf800, // Subtract From Zero Extended XO-form (subfze RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{SUBFZECC, 0xfc0007ff, 0x7c000191, 0xf800, // Subtract From Zero Extended XO-form (subfze. RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{SUBFZEO, 0xfc0007ff, 0x7c000590, 0xf800, // Subtract From Zero Extended XO-form (subfzeo RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{SUBFZEOCC, 0xfc0007ff, 0x7c000591, 0xf800, // Subtract From Zero Extended XO-form (subfzeo. RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{NEG, 0xfc0007ff, 0x7c0000d0, 0xf800, // Negate XO-form (neg RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{NEGCC, 0xfc0007ff, 0x7c0000d1, 0xf800, // Negate XO-form (neg. RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{NEGO, 0xfc0007ff, 0x7c0004d0, 0xf800, // Negate XO-form (nego RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{NEGOCC, 0xfc0007ff, 0x7c0004d1, 0xf800, // Negate XO-form (nego. RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{MULLI, 0xfc000000, 0x1c000000, 0x0, // Multiply Low Immediate D-form (mulli RT,RA,SI)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
-	{MULLW, 0xfc0007ff, 0x7c0001d6, 0x0, // Multiply Low Word XO-form (mullw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULLWCC, 0xfc0007ff, 0x7c0001d7, 0x0, // Multiply Low Word XO-form (mullw. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULLWO, 0xfc0007ff, 0x7c0005d6, 0x0, // Multiply Low Word XO-form (mullwo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULLWOCC, 0xfc0007ff, 0x7c0005d7, 0x0, // Multiply Low Word XO-form (mullwo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULHW, 0xfc0003ff, 0x7c000096, 0x400, // Multiply High Word XO-form (mulhw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULHWCC, 0xfc0003ff, 0x7c000097, 0x400, // Multiply High Word XO-form (mulhw. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULHWU, 0xfc0003ff, 0x7c000016, 0x400, // Multiply High Word Unsigned XO-form (mulhwu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULHWUCC, 0xfc0003ff, 0x7c000017, 0x400, // Multiply High Word Unsigned XO-form (mulhwu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVW, 0xfc0007ff, 0x7c0003d6, 0x0, // Divide Word XO-form (divw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWCC, 0xfc0007ff, 0x7c0003d7, 0x0, // Divide Word XO-form (divw. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWO, 0xfc0007ff, 0x7c0007d6, 0x0, // Divide Word XO-form (divwo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWOCC, 0xfc0007ff, 0x7c0007d7, 0x0, // Divide Word XO-form (divwo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWU, 0xfc0007ff, 0x7c000396, 0x0, // Divide Word Unsigned XO-form (divwu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWUCC, 0xfc0007ff, 0x7c000397, 0x0, // Divide Word Unsigned XO-form (divwu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWUO, 0xfc0007ff, 0x7c000796, 0x0, // Divide Word Unsigned XO-form (divwuo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWUOCC, 0xfc0007ff, 0x7c000797, 0x0, // Divide Word Unsigned XO-form (divwuo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWE, 0xfc0007ff, 0x7c000356, 0x0, // Divide Word Extended XO-form (divwe RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWECC, 0xfc0007ff, 0x7c000357, 0x0, // Divide Word Extended XO-form (divwe. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWEO, 0xfc0007ff, 0x7c000756, 0x0, // Divide Word Extended XO-form (divweo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWEOCC, 0xfc0007ff, 0x7c000757, 0x0, // Divide Word Extended XO-form (divweo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWEU, 0xfc0007ff, 0x7c000316, 0x0, // Divide Word Extended Unsigned XO-form (divweu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWEUCC, 0xfc0007ff, 0x7c000317, 0x0, // Divide Word Extended Unsigned XO-form (divweu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWEUO, 0xfc0007ff, 0x7c000716, 0x0, // Divide Word Extended Unsigned XO-form (divweuo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVWEUOCC, 0xfc0007ff, 0x7c000717, 0x0, // Divide Word Extended Unsigned XO-form (divweuo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULLD, 0xfc0007ff, 0x7c0001d2, 0x0, // Multiply Low Doubleword XO-form (mulld RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULLDCC, 0xfc0007ff, 0x7c0001d3, 0x0, // Multiply Low Doubleword XO-form (mulld. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULLDO, 0xfc0007ff, 0x7c0005d2, 0x0, // Multiply Low Doubleword XO-form (mulldo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULLDOCC, 0xfc0007ff, 0x7c0005d3, 0x0, // Multiply Low Doubleword XO-form (mulldo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULHDU, 0xfc0003ff, 0x7c000012, 0x400, // Multiply High Doubleword Unsigned XO-form (mulhdu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULHDUCC, 0xfc0003ff, 0x7c000013, 0x400, // Multiply High Doubleword Unsigned XO-form (mulhdu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULHD, 0xfc0003ff, 0x7c000092, 0x400, // Multiply High Doubleword XO-form (mulhd RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULHDCC, 0xfc0003ff, 0x7c000093, 0x400, // Multiply High Doubleword XO-form (mulhd. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVD, 0xfc0007ff, 0x7c0003d2, 0x0, // Divide Doubleword XO-form (divd RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDCC, 0xfc0007ff, 0x7c0003d3, 0x0, // Divide Doubleword XO-form (divd. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDO, 0xfc0007ff, 0x7c0007d2, 0x0, // Divide Doubleword XO-form (divdo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDOCC, 0xfc0007ff, 0x7c0007d3, 0x0, // Divide Doubleword XO-form (divdo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDU, 0xfc0007ff, 0x7c000392, 0x0, // Divide Doubleword Unsigned XO-form (divdu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDUCC, 0xfc0007ff, 0x7c000393, 0x0, // Divide Doubleword Unsigned XO-form (divdu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDUO, 0xfc0007ff, 0x7c000792, 0x0, // Divide Doubleword Unsigned XO-form (divduo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDUOCC, 0xfc0007ff, 0x7c000793, 0x0, // Divide Doubleword Unsigned XO-form (divduo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDE, 0xfc0007ff, 0x7c000352, 0x0, // Divide Doubleword Extended XO-form (divde RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDECC, 0xfc0007ff, 0x7c000353, 0x0, // Divide Doubleword Extended XO-form (divde. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDEO, 0xfc0007ff, 0x7c000752, 0x0, // Divide Doubleword Extended XO-form (divdeo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDEOCC, 0xfc0007ff, 0x7c000753, 0x0, // Divide Doubleword Extended XO-form (divdeo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDEU, 0xfc0007ff, 0x7c000312, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDEUCC, 0xfc0007ff, 0x7c000313, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDEUO, 0xfc0007ff, 0x7c000712, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeuo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DIVDEUOCC, 0xfc0007ff, 0x7c000713, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeuo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MODSD, 0xfc0007fe, 0x7c000612, 0x1, // Modulo Signed Doubleword X-form (modsd RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MODUD, 0xfc0007fe, 0x7c000212, 0x1, // Modulo Unsigned Doubleword X-form (modud RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MODSW, 0xfc0007fe, 0x7c000616, 0x1, // Modulo Signed Word X-form (modsw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MODUW, 0xfc0007fe, 0x7c000216, 0x1, // Modulo Unsigned Word X-form (moduw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{CMPWI, 0xfc200000, 0x2c000000, 0x400000, // Compare Immediate D-form (cmpwi BF,RA,SI)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmSigned_16_31}},
-	{CMPDI, 0xfc200000, 0x2c200000, 0x400000, // Compare Immediate D-form (cmpdi BF,RA,SI)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmSigned_16_31}},
-	{CMPW, 0xfc2007fe, 0x7c000000, 0x400001, // Compare X-form (cmpw BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{CMPD, 0xfc2007fe, 0x7c200000, 0x400001, // Compare X-form (cmpd BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{CMPLWI, 0xfc200000, 0x28000000, 0x400000, // Compare Logical Immediate D-form (cmplwi BF,RA,UI)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmUnsigned_16_31}},
-	{CMPLDI, 0xfc200000, 0x28200000, 0x400000, // Compare Logical Immediate D-form (cmpldi BF,RA,UI)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmUnsigned_16_31}},
-	{CMPLW, 0xfc2007fe, 0x7c000040, 0x400001, // Compare Logical X-form (cmplw BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{CMPLD, 0xfc2007fe, 0x7c200040, 0x400001, // Compare Logical X-form (cmpld BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{TWI, 0xfc000000, 0xc000000, 0x0, // Trap Word Immediate D-form (twi TO,RA,SI)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
-	{TW, 0xfc0007fe, 0x7c000008, 0x1, // Trap Word X-form (tw TO,RA,RB)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{TDI, 0xfc000000, 0x8000000, 0x0, // Trap Doubleword Immediate D-form (tdi TO,RA,SI)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
-	{ISEL, 0xfc00003e, 0x7c00001e, 0x1, // Integer Select A-form (isel RT,RA,RB,BC)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_CondRegBit_21_25}},
-	{TD, 0xfc0007fe, 0x7c000088, 0x1, // Trap Doubleword X-form (td TO,RA,RB)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ANDICC, 0xfc000000, 0x70000000, 0x0, // AND Immediate D-form (andi. RA,RS,UI)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}},
-	{ANDISCC, 0xfc000000, 0x74000000, 0x0, // AND Immediate Shifted D-form (andis. RA,RS,UI)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}},
-	{ORI, 0xfc000000, 0x60000000, 0x0, // OR Immediate D-form (ori RA,RS,UI)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}},
-	{ORIS, 0xfc000000, 0x64000000, 0x0, // OR Immediate Shifted D-form (oris RA,RS,UI)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}},
-	{XORI, 0xfc000000, 0x68000000, 0x0, // XOR Immediate D-form (xori RA,RS,UI)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}},
-	{XORIS, 0xfc000000, 0x6c000000, 0x0, // XOR Immediate Shifted D-form (xoris RA,RS,UI)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}},
-	{AND, 0xfc0007ff, 0x7c000038, 0x0, // AND X-form (and RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{ANDCC, 0xfc0007ff, 0x7c000039, 0x0, // AND X-form (and. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{XOR, 0xfc0007ff, 0x7c000278, 0x0, // XOR X-form (xor RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{XORCC, 0xfc0007ff, 0x7c000279, 0x0, // XOR X-form (xor. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{NAND, 0xfc0007ff, 0x7c0003b8, 0x0, // NAND X-form (nand RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{NANDCC, 0xfc0007ff, 0x7c0003b9, 0x0, // NAND X-form (nand. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{OR, 0xfc0007ff, 0x7c000378, 0x0, // OR X-form (or RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{ORCC, 0xfc0007ff, 0x7c000379, 0x0, // OR X-form (or. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{NOR, 0xfc0007ff, 0x7c0000f8, 0x0, // NOR X-form (nor RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{NORCC, 0xfc0007ff, 0x7c0000f9, 0x0, // NOR X-form (nor. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{ANDC, 0xfc0007ff, 0x7c000078, 0x0, // AND with Complement X-form (andc RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{ANDCCC, 0xfc0007ff, 0x7c000079, 0x0, // AND with Complement X-form (andc. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{EXTSB, 0xfc0007ff, 0x7c000774, 0xf800, // Extend Sign Byte X-form (extsb RA,RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{EXTSBCC, 0xfc0007ff, 0x7c000775, 0xf800, // Extend Sign Byte X-form (extsb. RA,RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{EQV, 0xfc0007ff, 0x7c000238, 0x0, // Equivalent X-form (eqv RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{EQVCC, 0xfc0007ff, 0x7c000239, 0x0, // Equivalent X-form (eqv. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{ORC, 0xfc0007ff, 0x7c000338, 0x0, // OR with Complement X-form (orc RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{ORCCC, 0xfc0007ff, 0x7c000339, 0x0, // OR with Complement X-form (orc. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{EXTSH, 0xfc0007ff, 0x7c000734, 0xf800, // Extend Sign Halfword X-form (extsh RA,RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{EXTSHCC, 0xfc0007ff, 0x7c000735, 0xf800, // Extend Sign Halfword X-form (extsh. RA,RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{CMPB, 0xfc0007fe, 0x7c0003f8, 0x1, // Compare Bytes X-form (cmpb RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{POPCNTB, 0xfc0007fe, 0x7c0000f4, 0xf801, // Population Count Bytes X-form (popcntb RA, RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{POPCNTW, 0xfc0007fe, 0x7c0002f4, 0xf801, // Population Count Words X-form (popcntw RA, RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{PRTYD, 0xfc0007fe, 0x7c000174, 0xf801, // Parity Doubleword X-form (prtyd RA,RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{PRTYW, 0xfc0007fe, 0x7c000134, 0xf801, // Parity Word X-form (prtyw RA,RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{EXTSW, 0xfc0007ff, 0x7c0007b4, 0xf800, // Extend Sign Word X-form (extsw RA,RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{EXTSWCC, 0xfc0007ff, 0x7c0007b5, 0xf800, // Extend Sign Word X-form (extsw. RA,RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{CNTLZD, 0xfc0007ff, 0x7c000074, 0xf800, // Count Leading Zeros Doubleword X-form (cntlzd RA,RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{CNTLZDCC, 0xfc0007ff, 0x7c000075, 0xf800, // Count Leading Zeros Doubleword X-form (cntlzd. RA,RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{POPCNTD, 0xfc0007fe, 0x7c0003f4, 0xf801, // Population Count Doubleword X-form (popcntd RA, RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{BPERMD, 0xfc0007fe, 0x7c0001f8, 0x1, // Bit Permute Doubleword X-form (bpermd RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{RLWINM, 0xfc000001, 0x54000000, 0x0, // Rotate Left Word Immediate then AND with Mask M-form (rlwinm RA,RS,SH,MB,ME)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}},
-	{RLWINMCC, 0xfc000001, 0x54000001, 0x0, // Rotate Left Word Immediate then AND with Mask M-form (rlwinm. RA,RS,SH,MB,ME)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}},
-	{RLWNM, 0xfc000001, 0x5c000000, 0x0, // Rotate Left Word then AND with Mask M-form (rlwnm RA,RS,RB,MB,ME)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}},
-	{RLWNMCC, 0xfc000001, 0x5c000001, 0x0, // Rotate Left Word then AND with Mask M-form (rlwnm. RA,RS,RB,MB,ME)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}},
-	{RLWIMI, 0xfc000001, 0x50000000, 0x0, // Rotate Left Word Immediate then Mask Insert M-form (rlwimi RA,RS,SH,MB,ME)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}},
-	{RLWIMICC, 0xfc000001, 0x50000001, 0x0, // Rotate Left Word Immediate then Mask Insert M-form (rlwimi. RA,RS,SH,MB,ME)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}},
-	{RLDICL, 0xfc00001d, 0x78000000, 0x0, // Rotate Left Doubleword Immediate then Clear Left MD-form (rldicl RA,RS,SH,MB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
-	{RLDICLCC, 0xfc00001d, 0x78000001, 0x0, // Rotate Left Doubleword Immediate then Clear Left MD-form (rldicl. RA,RS,SH,MB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
-	{RLDICR, 0xfc00001d, 0x78000004, 0x0, // Rotate Left Doubleword Immediate then Clear Right MD-form (rldicr RA,RS,SH,ME)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
-	{RLDICRCC, 0xfc00001d, 0x78000005, 0x0, // Rotate Left Doubleword Immediate then Clear Right MD-form (rldicr. RA,RS,SH,ME)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
-	{RLDIC, 0xfc00001d, 0x78000008, 0x0, // Rotate Left Doubleword Immediate then Clear MD-form (rldic RA,RS,SH,MB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
-	{RLDICCC, 0xfc00001d, 0x78000009, 0x0, // Rotate Left Doubleword Immediate then Clear MD-form (rldic. RA,RS,SH,MB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
-	{RLDCL, 0xfc00001f, 0x78000010, 0x0, // Rotate Left Doubleword then Clear Left MDS-form (rldcl RA,RS,RB,MB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_26_26_21_25}},
-	{RLDCLCC, 0xfc00001f, 0x78000011, 0x0, // Rotate Left Doubleword then Clear Left MDS-form (rldcl. RA,RS,RB,MB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_26_26_21_25}},
-	{RLDCR, 0xfc00001f, 0x78000012, 0x0, // Rotate Left Doubleword then Clear Right MDS-form (rldcr RA,RS,RB,ME)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_26_26_21_25}},
-	{RLDCRCC, 0xfc00001f, 0x78000013, 0x0, // Rotate Left Doubleword then Clear Right MDS-form (rldcr. RA,RS,RB,ME)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_26_26_21_25}},
-	{RLDIMI, 0xfc00001d, 0x7800000c, 0x0, // Rotate Left Doubleword Immediate then Mask Insert MD-form (rldimi RA,RS,SH,MB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
-	{RLDIMICC, 0xfc00001d, 0x7800000d, 0x0, // Rotate Left Doubleword Immediate then Mask Insert MD-form (rldimi. RA,RS,SH,MB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
-	{SLW, 0xfc0007ff, 0x7c000030, 0x0, // Shift Left Word X-form (slw RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{SLWCC, 0xfc0007ff, 0x7c000031, 0x0, // Shift Left Word X-form (slw. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{SRW, 0xfc0007ff, 0x7c000430, 0x0, // Shift Right Word X-form (srw RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{SRWCC, 0xfc0007ff, 0x7c000431, 0x0, // Shift Right Word X-form (srw. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{SRAWI, 0xfc0007ff, 0x7c000670, 0x0, // Shift Right Algebraic Word Immediate X-form (srawi RA,RS,SH)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20}},
-	{SRAWICC, 0xfc0007ff, 0x7c000671, 0x0, // Shift Right Algebraic Word Immediate X-form (srawi. RA,RS,SH)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20}},
-	{SRAW, 0xfc0007ff, 0x7c000630, 0x0, // Shift Right Algebraic Word X-form (sraw RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{SRAWCC, 0xfc0007ff, 0x7c000631, 0x0, // Shift Right Algebraic Word X-form (sraw. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{SLD, 0xfc0007ff, 0x7c000036, 0x0, // Shift Left Doubleword X-form (sld RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{SLDCC, 0xfc0007ff, 0x7c000037, 0x0, // Shift Left Doubleword X-form (sld. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{SRD, 0xfc0007ff, 0x7c000436, 0x0, // Shift Right Doubleword X-form (srd RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{SRDCC, 0xfc0007ff, 0x7c000437, 0x0, // Shift Right Doubleword X-form (srd. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{SRADI, 0xfc0007fd, 0x7c000674, 0x0, // Shift Right Algebraic Doubleword Immediate XS-form (sradi RA,RS,SH)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20}},
-	{SRADICC, 0xfc0007fd, 0x7c000675, 0x0, // Shift Right Algebraic Doubleword Immediate XS-form (sradi. RA,RS,SH)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20}},
-	{SRAD, 0xfc0007ff, 0x7c000634, 0x0, // Shift Right Algebraic Doubleword X-form (srad RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{SRADCC, 0xfc0007ff, 0x7c000635, 0x0, // Shift Right Algebraic Doubleword X-form (srad. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{CDTBCD, 0xfc0007fe, 0x7c000234, 0xf801, // Convert Declets To Binary Coded Decimal X-form (cdtbcd RA, RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{CBCDTD, 0xfc0007fe, 0x7c000274, 0xf801, // Convert Binary Coded Decimal To Declets X-form (cbcdtd RA, RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{ADDG6S, 0xfc0003fe, 0x7c000094, 0x401, // Add and Generate Sixes XO-form (addg6s RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MTSPR, 0xfc0007fe, 0x7c0003a6, 0x1, // Move To Special Purpose Register XFX-form (mtspr SPR,RS)
-		[5]*argField{ap_SpReg_16_20_11_15, ap_Reg_6_10}},
-	{MFSPR, 0xfc0007fe, 0x7c0002a6, 0x1, // Move From Special Purpose Register XFX-form (mfspr RT,SPR)
-		[5]*argField{ap_Reg_6_10, ap_SpReg_16_20_11_15}},
-	{MTCRF, 0xfc1007fe, 0x7c000120, 0x801, // Move To Condition Register Fields XFX-form (mtcrf FXM,RS)
-		[5]*argField{ap_ImmUnsigned_12_19, ap_Reg_6_10}},
-	{MFCR, 0xfc1007fe, 0x7c000026, 0xff801, // Move From Condition Register XFX-form (mfcr RT)
-		[5]*argField{ap_Reg_6_10}},
-	{MTSLE, 0xfc0007fe, 0x7c000126, 0x3dff801, // Move To Split Little Endian X-form (mtsle L)
-		[5]*argField{ap_ImmUnsigned_10_10}},
-	{MFVSRD, 0xfc0007fe, 0x7c000066, 0xf800, // Move From VSR Doubleword XX1-form (mfvsrd RA,XS)
-		[5]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}},
-	{MFVSRWZ, 0xfc0007fe, 0x7c0000e6, 0xf800, // Move From VSR Word and Zero XX1-form (mfvsrwz RA,XS)
-		[5]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}},
-	{MTVSRD, 0xfc0007fe, 0x7c000166, 0xf800, // Move To VSR Doubleword XX1-form (mtvsrd XT,RA)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}},
-	{MTVSRWA, 0xfc0007fe, 0x7c0001a6, 0xf800, // Move To VSR Word Algebraic XX1-form (mtvsrwa XT,RA)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}},
-	{MTVSRWZ, 0xfc0007fe, 0x7c0001e6, 0xf800, // Move To VSR Word and Zero XX1-form (mtvsrwz XT,RA)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}},
-	{MTOCRF, 0xfc1007fe, 0x7c100120, 0x801, // Move To One Condition Register Field XFX-form (mtocrf FXM,RS)
-		[5]*argField{ap_ImmUnsigned_12_19, ap_Reg_6_10}},
-	{MFOCRF, 0xfc1007fe, 0x7c100026, 0x801, // Move From One Condition Register Field XFX-form (mfocrf RT,FXM)
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_12_19}},
-	{MCRXR, 0xfc0007fe, 0x7c000400, 0x7ff801, // Move to Condition Register from XER X-form (mcrxr BF)
-		[5]*argField{ap_CondRegField_6_8}},
-	{MTDCRUX, 0xfc0007fe, 0x7c000346, 0xf801, // Move To Device Control Register User-mode Indexed X-form (mtdcrux RS,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{MFDCRUX, 0xfc0007fe, 0x7c000246, 0xf801, // Move From Device Control Register User-mode Indexed X-form (mfdcrux RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{LFS, 0xfc000000, 0xc0000000, 0x0, // Load Floating-Point Single D-form (lfs FRT,D(RA))
-		[5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LFSU, 0xfc000000, 0xc4000000, 0x0, // Load Floating-Point Single with Update D-form (lfsu FRT,D(RA))
-		[5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LFSX, 0xfc0007fe, 0x7c00042e, 0x1, // Load Floating-Point Single Indexed X-form (lfsx FRT,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LFSUX, 0xfc0007fe, 0x7c00046e, 0x1, // Load Floating-Point Single with Update Indexed X-form (lfsux FRT,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LFD, 0xfc000000, 0xc8000000, 0x0, // Load Floating-Point Double D-form (lfd FRT,D(RA))
-		[5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LFDU, 0xfc000000, 0xcc000000, 0x0, // Load Floating-Point Double with Update D-form (lfdu FRT,D(RA))
-		[5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{LFDX, 0xfc0007fe, 0x7c0004ae, 0x1, // Load Floating-Point Double Indexed X-form (lfdx FRT,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LFDUX, 0xfc0007fe, 0x7c0004ee, 0x1, // Load Floating-Point Double with Update Indexed X-form (lfdux FRT,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LFIWAX, 0xfc0007fe, 0x7c0006ae, 0x1, // Load Floating-Point as Integer Word Algebraic Indexed X-form (lfiwax FRT,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LFIWZX, 0xfc0007fe, 0x7c0006ee, 0x1, // Load Floating-Point as Integer Word and Zero Indexed X-form (lfiwzx FRT,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STFS, 0xfc000000, 0xd0000000, 0x0, // Store Floating-Point Single D-form (stfs FRS,D(RA))
-		[5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{STFSU, 0xfc000000, 0xd4000000, 0x0, // Store Floating-Point Single with Update D-form (stfsu FRS,D(RA))
-		[5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{STFSX, 0xfc0007fe, 0x7c00052e, 0x1, // Store Floating-Point Single Indexed X-form (stfsx FRS,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STFSUX, 0xfc0007fe, 0x7c00056e, 0x1, // Store Floating-Point Single with Update Indexed X-form (stfsux FRS,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STFD, 0xfc000000, 0xd8000000, 0x0, // Store Floating-Point Double D-form (stfd FRS,D(RA))
-		[5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{STFDU, 0xfc000000, 0xdc000000, 0x0, // Store Floating-Point Double with Update D-form (stfdu FRS,D(RA))
-		[5]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
-	{STFDX, 0xfc0007fe, 0x7c0005ae, 0x1, // Store Floating-Point Double Indexed X-form (stfdx FRS,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STFDUX, 0xfc0007fe, 0x7c0005ee, 0x1, // Store Floating-Point Double with Update Indexed X-form (stfdux FRS,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STFIWX, 0xfc0007fe, 0x7c0007ae, 0x1, // Store Floating-Point as Integer Word Indexed X-form (stfiwx FRS,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LFDP, 0xfc000003, 0xe4000000, 0x0, // Load Floating-Point Double Pair DS-form (lfdp FRTp,DS(RA))
-		[5]*argField{ap_FPReg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
-	{LFDPX, 0xfc0007fe, 0x7c00062e, 0x1, // Load Floating-Point Double Pair Indexed X-form (lfdpx FRTp,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STFDP, 0xfc000003, 0xf4000000, 0x0, // Store Floating-Point Double Pair DS-form (stfdp FRSp,DS(RA))
-		[5]*argField{ap_FPReg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
-	{STFDPX, 0xfc0007fe, 0x7c00072e, 0x1, // Store Floating-Point Double Pair Indexed X-form (stfdpx FRSp,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{FMR, 0xfc0007ff, 0xfc000090, 0x1f0000, // Floating Move Register X-form (fmr FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FMRCC, 0xfc0007ff, 0xfc000091, 0x1f0000, // Floating Move Register X-form (fmr. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FABS, 0xfc0007ff, 0xfc000210, 0x1f0000, // Floating Absolute Value X-form (fabs FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FABSCC, 0xfc0007ff, 0xfc000211, 0x1f0000, // Floating Absolute Value X-form (fabs. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FNABS, 0xfc0007ff, 0xfc000110, 0x1f0000, // Floating Negative Absolute Value X-form (fnabs FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FNABSCC, 0xfc0007ff, 0xfc000111, 0x1f0000, // Floating Negative Absolute Value X-form (fnabs. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FNEG, 0xfc0007ff, 0xfc000050, 0x1f0000, // Floating Negate X-form (fneg FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FNEGCC, 0xfc0007ff, 0xfc000051, 0x1f0000, // Floating Negate X-form (fneg. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCPSGN, 0xfc0007ff, 0xfc000010, 0x0, // Floating Copy Sign X-form (fcpsgn FRT, FRA, FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FCPSGNCC, 0xfc0007ff, 0xfc000011, 0x0, // Floating Copy Sign X-form (fcpsgn. FRT, FRA, FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FMRGEW, 0xfc0007fe, 0xfc00078c, 0x1, // Floating Merge Even Word X-form (fmrgew FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FMRGOW, 0xfc0007fe, 0xfc00068c, 0x1, // Floating Merge Odd Word X-form (fmrgow FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FADD, 0xfc00003f, 0xfc00002a, 0x7c0, // Floating Add [Single] A-form (fadd FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FADDCC, 0xfc00003f, 0xfc00002b, 0x7c0, // Floating Add [Single] A-form (fadd. FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FADDS, 0xfc00003f, 0xec00002a, 0x7c0, // Floating Add [Single] A-form (fadds FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FADDSCC, 0xfc00003f, 0xec00002b, 0x7c0, // Floating Add [Single] A-form (fadds. FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FSUB, 0xfc00003f, 0xfc000028, 0x7c0, // Floating Subtract [Single] A-form (fsub FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FSUBCC, 0xfc00003f, 0xfc000029, 0x7c0, // Floating Subtract [Single] A-form (fsub. FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FSUBS, 0xfc00003f, 0xec000028, 0x7c0, // Floating Subtract [Single] A-form (fsubs FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FSUBSCC, 0xfc00003f, 0xec000029, 0x7c0, // Floating Subtract [Single] A-form (fsubs. FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FMUL, 0xfc00003f, 0xfc000032, 0xf800, // Floating Multiply [Single] A-form (fmul FRT,FRA,FRC)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25}},
-	{FMULCC, 0xfc00003f, 0xfc000033, 0xf800, // Floating Multiply [Single] A-form (fmul. FRT,FRA,FRC)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25}},
-	{FMULS, 0xfc00003f, 0xec000032, 0xf800, // Floating Multiply [Single] A-form (fmuls FRT,FRA,FRC)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25}},
-	{FMULSCC, 0xfc00003f, 0xec000033, 0xf800, // Floating Multiply [Single] A-form (fmuls. FRT,FRA,FRC)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25}},
-	{FDIV, 0xfc00003f, 0xfc000024, 0x7c0, // Floating Divide [Single] A-form (fdiv FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FDIVCC, 0xfc00003f, 0xfc000025, 0x7c0, // Floating Divide [Single] A-form (fdiv. FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FDIVS, 0xfc00003f, 0xec000024, 0x7c0, // Floating Divide [Single] A-form (fdivs FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FDIVSCC, 0xfc00003f, 0xec000025, 0x7c0, // Floating Divide [Single] A-form (fdivs. FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FSQRT, 0xfc00003f, 0xfc00002c, 0x1f07c0, // Floating Square Root [Single] A-form (fsqrt FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FSQRTCC, 0xfc00003f, 0xfc00002d, 0x1f07c0, // Floating Square Root [Single] A-form (fsqrt. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FSQRTS, 0xfc00003f, 0xec00002c, 0x1f07c0, // Floating Square Root [Single] A-form (fsqrts FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FSQRTSCC, 0xfc00003f, 0xec00002d, 0x1f07c0, // Floating Square Root [Single] A-form (fsqrts. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRE, 0xfc00003f, 0xfc000030, 0x1f07c0, // Floating Reciprocal Estimate [Single] A-form (fre FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRECC, 0xfc00003f, 0xfc000031, 0x1f07c0, // Floating Reciprocal Estimate [Single] A-form (fre. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRES, 0xfc00003f, 0xec000030, 0x1f07c0, // Floating Reciprocal Estimate [Single] A-form (fres FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRESCC, 0xfc00003f, 0xec000031, 0x1f07c0, // Floating Reciprocal Estimate [Single] A-form (fres. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRSQRTE, 0xfc00003f, 0xfc000034, 0x1f07c0, // Floating Reciprocal Square Root Estimate [Single] A-form (frsqrte FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRSQRTECC, 0xfc00003f, 0xfc000035, 0x1f07c0, // Floating Reciprocal Square Root Estimate [Single] A-form (frsqrte. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRSQRTES, 0xfc00003f, 0xec000034, 0x1f07c0, // Floating Reciprocal Square Root Estimate [Single] A-form (frsqrtes FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRSQRTESCC, 0xfc00003f, 0xec000035, 0x1f07c0, // Floating Reciprocal Square Root Estimate [Single] A-form (frsqrtes. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FTDIV, 0xfc0007fe, 0xfc000100, 0x600001, // Floating Test for software Divide X-form (ftdiv BF,FRA,FRB)
-		[5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FTSQRT, 0xfc0007fe, 0xfc000140, 0x7f0001, // Floating Test for software Square Root X-form (ftsqrt BF,FRB)
-		[5]*argField{ap_CondRegField_6_8, ap_FPReg_16_20}},
-	{FMADD, 0xfc00003f, 0xfc00003a, 0x0, // Floating Multiply-Add [Single] A-form (fmadd FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FMADDCC, 0xfc00003f, 0xfc00003b, 0x0, // Floating Multiply-Add [Single] A-form (fmadd. FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FMADDS, 0xfc00003f, 0xec00003a, 0x0, // Floating Multiply-Add [Single] A-form (fmadds FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FMADDSCC, 0xfc00003f, 0xec00003b, 0x0, // Floating Multiply-Add [Single] A-form (fmadds. FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FMSUB, 0xfc00003f, 0xfc000038, 0x0, // Floating Multiply-Subtract [Single] A-form (fmsub FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FMSUBCC, 0xfc00003f, 0xfc000039, 0x0, // Floating Multiply-Subtract [Single] A-form (fmsub. FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FMSUBS, 0xfc00003f, 0xec000038, 0x0, // Floating Multiply-Subtract [Single] A-form (fmsubs FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FMSUBSCC, 0xfc00003f, 0xec000039, 0x0, // Floating Multiply-Subtract [Single] A-form (fmsubs. FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FNMADD, 0xfc00003f, 0xfc00003e, 0x0, // Floating Negative Multiply-Add [Single] A-form (fnmadd FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FNMADDCC, 0xfc00003f, 0xfc00003f, 0x0, // Floating Negative Multiply-Add [Single] A-form (fnmadd. FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FNMADDS, 0xfc00003f, 0xec00003e, 0x0, // Floating Negative Multiply-Add [Single] A-form (fnmadds FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FNMADDSCC, 0xfc00003f, 0xec00003f, 0x0, // Floating Negative Multiply-Add [Single] A-form (fnmadds. FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FNMSUB, 0xfc00003f, 0xfc00003c, 0x0, // Floating Negative Multiply-Subtract [Single] A-form (fnmsub FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FNMSUBCC, 0xfc00003f, 0xfc00003d, 0x0, // Floating Negative Multiply-Subtract [Single] A-form (fnmsub. FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FNMSUBS, 0xfc00003f, 0xec00003c, 0x0, // Floating Negative Multiply-Subtract [Single] A-form (fnmsubs FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FNMSUBSCC, 0xfc00003f, 0xec00003d, 0x0, // Floating Negative Multiply-Subtract [Single] A-form (fnmsubs. FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FRSP, 0xfc0007ff, 0xfc000018, 0x1f0000, // Floating Round to Single-Precision X-form (frsp FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRSPCC, 0xfc0007ff, 0xfc000019, 0x1f0000, // Floating Round to Single-Precision X-form (frsp. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTID, 0xfc0007ff, 0xfc00065c, 0x1f0000, // Floating Convert To Integer Doubleword X-form (fctid FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIDCC, 0xfc0007ff, 0xfc00065d, 0x1f0000, // Floating Convert To Integer Doubleword X-form (fctid. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIDZ, 0xfc0007ff, 0xfc00065e, 0x1f0000, // Floating Convert To Integer Doubleword with round toward Zero X-form (fctidz FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIDZCC, 0xfc0007ff, 0xfc00065f, 0x1f0000, // Floating Convert To Integer Doubleword with round toward Zero X-form (fctidz. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIDU, 0xfc0007ff, 0xfc00075c, 0x1f0000, // Floating Convert To Integer Doubleword Unsigned X-form (fctidu FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIDUCC, 0xfc0007ff, 0xfc00075d, 0x1f0000, // Floating Convert To Integer Doubleword Unsigned X-form (fctidu. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIDUZ, 0xfc0007ff, 0xfc00075e, 0x1f0000, // Floating Convert To Integer Doubleword Unsigned with round toward Zero X-form (fctiduz FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIDUZCC, 0xfc0007ff, 0xfc00075f, 0x1f0000, // Floating Convert To Integer Doubleword Unsigned with round toward Zero X-form (fctiduz. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIW, 0xfc0007ff, 0xfc00001c, 0x1f0000, // Floating Convert To Integer Word X-form (fctiw FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIWCC, 0xfc0007ff, 0xfc00001d, 0x1f0000, // Floating Convert To Integer Word X-form (fctiw. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIWZ, 0xfc0007ff, 0xfc00001e, 0x1f0000, // Floating Convert To Integer Word with round toward Zero X-form (fctiwz FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIWZCC, 0xfc0007ff, 0xfc00001f, 0x1f0000, // Floating Convert To Integer Word with round toward Zero X-form (fctiwz. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIWU, 0xfc0007ff, 0xfc00011c, 0x1f0000, // Floating Convert To Integer Word Unsigned X-form (fctiwu FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIWUCC, 0xfc0007ff, 0xfc00011d, 0x1f0000, // Floating Convert To Integer Word Unsigned X-form (fctiwu. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIWUZ, 0xfc0007ff, 0xfc00011e, 0x1f0000, // Floating Convert To Integer Word Unsigned with round toward Zero X-form (fctiwuz FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCTIWUZCC, 0xfc0007ff, 0xfc00011f, 0x1f0000, // Floating Convert To Integer Word Unsigned with round toward Zero X-form (fctiwuz. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCFID, 0xfc0007ff, 0xfc00069c, 0x1f0000, // Floating Convert From Integer Doubleword X-form (fcfid FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCFIDCC, 0xfc0007ff, 0xfc00069d, 0x1f0000, // Floating Convert From Integer Doubleword X-form (fcfid. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCFIDU, 0xfc0007ff, 0xfc00079c, 0x1f0000, // Floating Convert From Integer Doubleword Unsigned X-form (fcfidu FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCFIDUCC, 0xfc0007ff, 0xfc00079d, 0x1f0000, // Floating Convert From Integer Doubleword Unsigned X-form (fcfidu. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCFIDS, 0xfc0007ff, 0xec00069c, 0x1f0000, // Floating Convert From Integer Doubleword Single X-form (fcfids FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCFIDSCC, 0xfc0007ff, 0xec00069d, 0x1f0000, // Floating Convert From Integer Doubleword Single X-form (fcfids. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCFIDUS, 0xfc0007ff, 0xec00079c, 0x1f0000, // Floating Convert From Integer Doubleword Unsigned Single X-form (fcfidus FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCFIDUSCC, 0xfc0007ff, 0xec00079d, 0x1f0000, // Floating Convert From Integer Doubleword Unsigned Single X-form (fcfidus. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRIN, 0xfc0007ff, 0xfc000310, 0x1f0000, // Floating Round to Integer Nearest X-form (frin FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRINCC, 0xfc0007ff, 0xfc000311, 0x1f0000, // Floating Round to Integer Nearest X-form (frin. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRIZ, 0xfc0007ff, 0xfc000350, 0x1f0000, // Floating Round to Integer Toward Zero X-form (friz FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRIZCC, 0xfc0007ff, 0xfc000351, 0x1f0000, // Floating Round to Integer Toward Zero X-form (friz. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRIP, 0xfc0007ff, 0xfc000390, 0x1f0000, // Floating Round to Integer Plus X-form (frip FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRIPCC, 0xfc0007ff, 0xfc000391, 0x1f0000, // Floating Round to Integer Plus X-form (frip. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRIM, 0xfc0007ff, 0xfc0003d0, 0x1f0000, // Floating Round to Integer Minus X-form (frim FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FRIMCC, 0xfc0007ff, 0xfc0003d1, 0x1f0000, // Floating Round to Integer Minus X-form (frim. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{FCMPU, 0xfc0007fe, 0xfc000000, 0x600001, // Floating Compare Unordered X-form (fcmpu BF,FRA,FRB)
-		[5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FCMPO, 0xfc0007fe, 0xfc000040, 0x600001, // Floating Compare Ordered X-form (fcmpo BF,FRA,FRB)
-		[5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{FSEL, 0xfc00003f, 0xfc00002e, 0x0, // Floating Select A-form (fsel FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{FSELCC, 0xfc00003f, 0xfc00002f, 0x0, // Floating Select A-form (fsel. FRT,FRA,FRC,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
-	{MFFS, 0xfc0007ff, 0xfc00048e, 0x1ff800, // Move From FPSCR X-form (mffs FRT)
-		[5]*argField{ap_FPReg_6_10}},
-	{MFFSCC, 0xfc0007ff, 0xfc00048f, 0x1ff800, // Move From FPSCR X-form (mffs. FRT)
-		[5]*argField{ap_FPReg_6_10}},
-	{MCRFS, 0xfc0007fe, 0xfc000080, 0x63f801, // Move to Condition Register from FPSCR X-form (mcrfs BF,BFA)
-		[5]*argField{ap_CondRegField_6_8, ap_CondRegField_11_13}},
-	{MTFSFI, 0xfc0007ff, 0xfc00010c, 0x7e0800, // Move To FPSCR Field Immediate X-form (mtfsfi BF,U,W)
-		[5]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_16_19, ap_ImmUnsigned_15_15}},
-	{MTFSFICC, 0xfc0007ff, 0xfc00010d, 0x7e0800, // Move To FPSCR Field Immediate X-form (mtfsfi. BF,U,W)
-		[5]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_16_19, ap_ImmUnsigned_15_15}},
-	{MTFSF, 0xfc0007ff, 0xfc00058e, 0x0, // Move To FPSCR Fields XFL-form (mtfsf FLM,FRB,L,W)
-		[5]*argField{ap_ImmUnsigned_7_14, ap_FPReg_16_20, ap_ImmUnsigned_6_6, ap_ImmUnsigned_15_15}},
-	{MTFSFCC, 0xfc0007ff, 0xfc00058f, 0x0, // Move To FPSCR Fields XFL-form (mtfsf. FLM,FRB,L,W)
-		[5]*argField{ap_ImmUnsigned_7_14, ap_FPReg_16_20, ap_ImmUnsigned_6_6, ap_ImmUnsigned_15_15}},
-	{MTFSB0, 0xfc0007ff, 0xfc00008c, 0x1ff800, // Move To FPSCR Bit 0 X-form (mtfsb0 BT)
-		[5]*argField{ap_CondRegBit_6_10}},
-	{MTFSB0CC, 0xfc0007ff, 0xfc00008d, 0x1ff800, // Move To FPSCR Bit 0 X-form (mtfsb0. BT)
-		[5]*argField{ap_CondRegBit_6_10}},
-	{MTFSB1, 0xfc0007ff, 0xfc00004c, 0x1ff800, // Move To FPSCR Bit 1 X-form (mtfsb1 BT)
-		[5]*argField{ap_CondRegBit_6_10}},
-	{MTFSB1CC, 0xfc0007ff, 0xfc00004d, 0x1ff800, // Move To FPSCR Bit 1 X-form (mtfsb1. BT)
-		[5]*argField{ap_CondRegBit_6_10}},
-	{LVEBX, 0xfc0007fe, 0x7c00000e, 0x1, // Load Vector Element Byte Indexed X-form (lvebx VRT,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LVEHX, 0xfc0007fe, 0x7c00004e, 0x1, // Load Vector Element Halfword Indexed X-form (lvehx VRT,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LVEWX, 0xfc0007fe, 0x7c00008e, 0x1, // Load Vector Element Word Indexed X-form (lvewx VRT,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LVX, 0xfc0007fe, 0x7c0000ce, 0x1, // Load Vector Indexed X-form (lvx VRT,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LVXL, 0xfc0007fe, 0x7c0002ce, 0x1, // Load Vector Indexed LRU X-form (lvxl VRT,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STVEBX, 0xfc0007fe, 0x7c00010e, 0x1, // Store Vector Element Byte Indexed X-form (stvebx VRS,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STVEHX, 0xfc0007fe, 0x7c00014e, 0x1, // Store Vector Element Halfword Indexed X-form (stvehx VRS,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STVEWX, 0xfc0007fe, 0x7c00018e, 0x1, // Store Vector Element Word Indexed X-form (stvewx VRS,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STVX, 0xfc0007fe, 0x7c0001ce, 0x1, // Store Vector Indexed X-form (stvx VRS,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STVXL, 0xfc0007fe, 0x7c0003ce, 0x1, // Store Vector Indexed LRU X-form (stvxl VRS,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LVSL, 0xfc0007fe, 0x7c00000c, 0x1, // Load Vector for Shift Left Indexed X-form (lvsl VRT,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LVSR, 0xfc0007fe, 0x7c00004c, 0x1, // Load Vector for Shift Right Indexed X-form (lvsr VRT,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{VPKPX, 0xfc0007ff, 0x1000030e, 0x0, // Vector Pack Pixel VX-form (vpkpx VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPKSDSS, 0xfc0007ff, 0x100005ce, 0x0, // Vector Pack Signed Doubleword Signed Saturate VX-form (vpksdss VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPKSDUS, 0xfc0007ff, 0x1000054e, 0x0, // Vector Pack Signed Doubleword Unsigned Saturate VX-form (vpksdus VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPKSHSS, 0xfc0007ff, 0x1000018e, 0x0, // Vector Pack Signed Halfword Signed Saturate VX-form (vpkshss VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPKSHUS, 0xfc0007ff, 0x1000010e, 0x0, // Vector Pack Signed Halfword Unsigned Saturate VX-form (vpkshus VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPKSWSS, 0xfc0007ff, 0x100001ce, 0x0, // Vector Pack Signed Word Signed Saturate VX-form (vpkswss VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPKSWUS, 0xfc0007ff, 0x1000014e, 0x0, // Vector Pack Signed Word Unsigned Saturate VX-form (vpkswus VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPKUDUM, 0xfc0007ff, 0x1000044e, 0x0, // Vector Pack Unsigned Doubleword Unsigned Modulo VX-form (vpkudum VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPKUDUS, 0xfc0007ff, 0x100004ce, 0x0, // Vector Pack Unsigned Doubleword Unsigned Saturate VX-form (vpkudus VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPKUHUM, 0xfc0007ff, 0x1000000e, 0x0, // Vector Pack Unsigned Halfword Unsigned Modulo VX-form (vpkuhum VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPKUHUS, 0xfc0007ff, 0x1000008e, 0x0, // Vector Pack Unsigned Halfword Unsigned Saturate VX-form (vpkuhus VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPKUWUM, 0xfc0007ff, 0x1000004e, 0x0, // Vector Pack Unsigned Word Unsigned Modulo VX-form (vpkuwum VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPKUWUS, 0xfc0007ff, 0x100000ce, 0x0, // Vector Pack Unsigned Word Unsigned Saturate VX-form (vpkuwus VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VUPKHPX, 0xfc0007ff, 0x1000034e, 0x1f0000, // Vector Unpack High Pixel VX-form (vupkhpx VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VUPKLPX, 0xfc0007ff, 0x100003ce, 0x1f0000, // Vector Unpack Low Pixel VX-form (vupklpx VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VUPKHSB, 0xfc0007ff, 0x1000020e, 0x1f0000, // Vector Unpack High Signed Byte VX-form (vupkhsb VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VUPKHSH, 0xfc0007ff, 0x1000024e, 0x1f0000, // Vector Unpack High Signed Halfword VX-form (vupkhsh VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VUPKHSW, 0xfc0007ff, 0x1000064e, 0x1f0000, // Vector Unpack High Signed Word VX-form (vupkhsw VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VUPKLSB, 0xfc0007ff, 0x1000028e, 0x1f0000, // Vector Unpack Low Signed Byte VX-form (vupklsb VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VUPKLSH, 0xfc0007ff, 0x100002ce, 0x1f0000, // Vector Unpack Low Signed Halfword VX-form (vupklsh VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VUPKLSW, 0xfc0007ff, 0x100006ce, 0x1f0000, // Vector Unpack Low Signed Word VX-form (vupklsw VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VMRGHB, 0xfc0007ff, 0x1000000c, 0x0, // Vector Merge High Byte VX-form (vmrghb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMRGHH, 0xfc0007ff, 0x1000004c, 0x0, // Vector Merge High Halfword VX-form (vmrghh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMRGLB, 0xfc0007ff, 0x1000010c, 0x0, // Vector Merge Low Byte VX-form (vmrglb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMRGLH, 0xfc0007ff, 0x1000014c, 0x0, // Vector Merge Low Halfword VX-form (vmrglh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMRGHW, 0xfc0007ff, 0x1000008c, 0x0, // Vector Merge High Word VX-form (vmrghw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMRGLW, 0xfc0007ff, 0x1000018c, 0x0, // Vector Merge Low Word VX-form (vmrglw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMRGEW, 0xfc0007ff, 0x1000078c, 0x0, // Vector Merge Even Word VX-form (vmrgew VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMRGOW, 0xfc0007ff, 0x1000068c, 0x0, // Vector Merge Odd Word VX-form (vmrgow VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSPLTB, 0xfc0007ff, 0x1000020c, 0x100000, // Vector Splat Byte VX-form (vspltb VRT,VRB,UIM)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_12_15}},
-	{VSPLTH, 0xfc0007ff, 0x1000024c, 0x180000, // Vector Splat Halfword VX-form (vsplth VRT,VRB,UIM)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_13_15}},
-	{VSPLTW, 0xfc0007ff, 0x1000028c, 0x1c0000, // Vector Splat Word VX-form (vspltw VRT,VRB,UIM)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_14_15}},
-	{VSPLTISB, 0xfc0007ff, 0x1000030c, 0xf800, // Vector Splat Immediate Signed Byte VX-form (vspltisb VRT,SIM)
-		[5]*argField{ap_VecReg_6_10, ap_ImmSigned_11_15}},
-	{VSPLTISH, 0xfc0007ff, 0x1000034c, 0xf800, // Vector Splat Immediate Signed Halfword VX-form (vspltish VRT,SIM)
-		[5]*argField{ap_VecReg_6_10, ap_ImmSigned_11_15}},
-	{VSPLTISW, 0xfc0007ff, 0x1000038c, 0xf800, // Vector Splat Immediate Signed Word VX-form (vspltisw VRT,SIM)
-		[5]*argField{ap_VecReg_6_10, ap_ImmSigned_11_15}},
-	{VPERM, 0xfc00003f, 0x1000002b, 0x0, // Vector Permute VA-form (vperm VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VPERMR, 0xfc00003f, 0x1000003b, 0x0, // Vector Permute Right-indexed VA-form (vpermr VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VSEL, 0xfc00003f, 0x1000002a, 0x0, // Vector Select VA-form (vsel VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VSL, 0xfc0007ff, 0x100001c4, 0x0, // Vector Shift Left VX-form (vsl VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSLDOI, 0xfc00003f, 0x1000002c, 0x400, // Vector Shift Left Double by Octet Immediate VA-form (vsldoi VRT,VRA,VRB,SHB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_25}},
-	{VSLO, 0xfc0007ff, 0x1000040c, 0x0, // Vector Shift Left by Octet VX-form (vslo VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSR, 0xfc0007ff, 0x100002c4, 0x0, // Vector Shift Right VX-form (vsr VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSRO, 0xfc0007ff, 0x1000044c, 0x0, // Vector Shift Right by Octet VX-form (vsro VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDCUW, 0xfc0007ff, 0x10000180, 0x0, // Vector Add and Write Carry-Out Unsigned Word VX-form (vaddcuw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDSBS, 0xfc0007ff, 0x10000300, 0x0, // Vector Add Signed Byte Saturate VX-form (vaddsbs VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDSHS, 0xfc0007ff, 0x10000340, 0x0, // Vector Add Signed Halfword Saturate VX-form (vaddshs VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDSWS, 0xfc0007ff, 0x10000380, 0x0, // Vector Add Signed Word Saturate VX-form (vaddsws VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDUBM, 0xfc0007ff, 0x10000000, 0x0, // Vector Add Unsigned Byte Modulo VX-form (vaddubm VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDUDM, 0xfc0007ff, 0x100000c0, 0x0, // Vector Add Unsigned Doubleword Modulo VX-form (vaddudm VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDUHM, 0xfc0007ff, 0x10000040, 0x0, // Vector Add Unsigned Halfword Modulo VX-form (vadduhm VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDUWM, 0xfc0007ff, 0x10000080, 0x0, // Vector Add Unsigned Word Modulo VX-form (vadduwm VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDUBS, 0xfc0007ff, 0x10000200, 0x0, // Vector Add Unsigned Byte Saturate VX-form (vaddubs VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDUHS, 0xfc0007ff, 0x10000240, 0x0, // Vector Add Unsigned Halfword Saturate VX-form (vadduhs VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDUWS, 0xfc0007ff, 0x10000280, 0x0, // Vector Add Unsigned Word Saturate VX-form (vadduws VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDUQM, 0xfc0007ff, 0x10000100, 0x0, // Vector Add Unsigned Quadword Modulo VX-form (vadduqm VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDEUQM, 0xfc00003f, 0x1000003c, 0x0, // Vector Add Extended Unsigned Quadword Modulo VA-form (vaddeuqm VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VADDCUQ, 0xfc0007ff, 0x10000140, 0x0, // Vector Add & write Carry Unsigned Quadword VX-form (vaddcuq VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDECUQ, 0xfc00003f, 0x1000003d, 0x0, // Vector Add Extended & write Carry Unsigned Quadword VA-form (vaddecuq VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VSUBCUW, 0xfc0007ff, 0x10000580, 0x0, // Vector Subtract and Write Carry-Out Unsigned Word VX-form (vsubcuw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBSBS, 0xfc0007ff, 0x10000700, 0x0, // Vector Subtract Signed Byte Saturate VX-form (vsubsbs VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBSHS, 0xfc0007ff, 0x10000740, 0x0, // Vector Subtract Signed Halfword Saturate VX-form (vsubshs VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBSWS, 0xfc0007ff, 0x10000780, 0x0, // Vector Subtract Signed Word Saturate VX-form (vsubsws VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBUBM, 0xfc0007ff, 0x10000400, 0x0, // Vector Subtract Unsigned Byte Modulo VX-form (vsububm VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBUDM, 0xfc0007ff, 0x100004c0, 0x0, // Vector Subtract Unsigned Doubleword Modulo VX-form (vsubudm VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBUHM, 0xfc0007ff, 0x10000440, 0x0, // Vector Subtract Unsigned Halfword Modulo VX-form (vsubuhm VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBUWM, 0xfc0007ff, 0x10000480, 0x0, // Vector Subtract Unsigned Word Modulo VX-form (vsubuwm VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBUBS, 0xfc0007ff, 0x10000600, 0x0, // Vector Subtract Unsigned Byte Saturate VX-form (vsububs VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBUHS, 0xfc0007ff, 0x10000640, 0x0, // Vector Subtract Unsigned Halfword Saturate VX-form (vsubuhs VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBUWS, 0xfc0007ff, 0x10000680, 0x0, // Vector Subtract Unsigned Word Saturate VX-form (vsubuws VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBUQM, 0xfc0007ff, 0x10000500, 0x0, // Vector Subtract Unsigned Quadword Modulo VX-form (vsubuqm VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBEUQM, 0xfc00003f, 0x1000003e, 0x0, // Vector Subtract Extended Unsigned Quadword Modulo VA-form (vsubeuqm VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VSUBCUQ, 0xfc0007ff, 0x10000540, 0x0, // Vector Subtract & write Carry Unsigned Quadword VX-form (vsubcuq VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBECUQ, 0xfc00003f, 0x1000003f, 0x0, // Vector Subtract Extended & write Carry Unsigned Quadword VA-form (vsubecuq VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VMULESB, 0xfc0007ff, 0x10000308, 0x0, // Vector Multiply Even Signed Byte VX-form (vmulesb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMULEUB, 0xfc0007ff, 0x10000208, 0x0, // Vector Multiply Even Unsigned Byte VX-form (vmuleub VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMULOSB, 0xfc0007ff, 0x10000108, 0x0, // Vector Multiply Odd Signed Byte VX-form (vmulosb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMULOUB, 0xfc0007ff, 0x10000008, 0x0, // Vector Multiply Odd Unsigned Byte VX-form (vmuloub VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMULESH, 0xfc0007ff, 0x10000348, 0x0, // Vector Multiply Even Signed Halfword VX-form (vmulesh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMULEUH, 0xfc0007ff, 0x10000248, 0x0, // Vector Multiply Even Unsigned Halfword VX-form (vmuleuh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMULOSH, 0xfc0007ff, 0x10000148, 0x0, // Vector Multiply Odd Signed Halfword VX-form (vmulosh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMULOUH, 0xfc0007ff, 0x10000048, 0x0, // Vector Multiply Odd Unsigned Halfword VX-form (vmulouh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMULESW, 0xfc0007ff, 0x10000388, 0x0, // Vector Multiply Even Signed Word VX-form (vmulesw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMULEUW, 0xfc0007ff, 0x10000288, 0x0, // Vector Multiply Even Unsigned Word VX-form (vmuleuw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMULOSW, 0xfc0007ff, 0x10000188, 0x0, // Vector Multiply Odd Signed Word VX-form (vmulosw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMULOUW, 0xfc0007ff, 0x10000088, 0x0, // Vector Multiply Odd Unsigned Word VX-form (vmulouw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMULUWM, 0xfc0007ff, 0x10000089, 0x0, // Vector Multiply Unsigned Word Modulo VX-form (vmuluwm VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMHADDSHS, 0xfc00003f, 0x10000020, 0x0, // Vector Multiply-High-Add Signed Halfword Saturate VA-form (vmhaddshs VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VMHRADDSHS, 0xfc00003f, 0x10000021, 0x0, // Vector Multiply-High-Round-Add Signed Halfword Saturate VA-form (vmhraddshs VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VMLADDUHM, 0xfc00003f, 0x10000022, 0x0, // Vector Multiply-Low-Add Unsigned Halfword Modulo VA-form (vmladduhm VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VMSUMUBM, 0xfc00003f, 0x10000024, 0x0, // Vector Multiply-Sum Unsigned Byte Modulo VA-form (vmsumubm VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VMSUMMBM, 0xfc00003f, 0x10000025, 0x0, // Vector Multiply-Sum Mixed Byte Modulo VA-form (vmsummbm VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VMSUMSHM, 0xfc00003f, 0x10000028, 0x0, // Vector Multiply-Sum Signed Halfword Modulo VA-form (vmsumshm VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VMSUMSHS, 0xfc00003f, 0x10000029, 0x0, // Vector Multiply-Sum Signed Halfword Saturate VA-form (vmsumshs VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VMSUMUHM, 0xfc00003f, 0x10000026, 0x0, // Vector Multiply-Sum Unsigned Halfword Modulo VA-form (vmsumuhm VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VMSUMUHS, 0xfc00003f, 0x10000027, 0x0, // Vector Multiply-Sum Unsigned Halfword Saturate VA-form (vmsumuhs VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VMSUMUDM, 0xfc00003f, 0x10000023, 0x0, // Vector Multiply-Sum Unsigned Doubleword Modulo VA-form (vmsumudm VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VSUMSWS, 0xfc0007ff, 0x10000788, 0x0, // Vector Sum across Signed Word Saturate VX-form (vsumsws VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUM2SWS, 0xfc0007ff, 0x10000688, 0x0, // Vector Sum across Half Signed Word Saturate VX-form (vsum2sws VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUM4SBS, 0xfc0007ff, 0x10000708, 0x0, // Vector Sum across Quarter Signed Byte Saturate VX-form (vsum4sbs VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUM4SHS, 0xfc0007ff, 0x10000648, 0x0, // Vector Sum across Quarter Signed Halfword Saturate VX-form (vsum4shs VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUM4UBS, 0xfc0007ff, 0x10000608, 0x0, // Vector Sum across Quarter Unsigned Byte Saturate VX-form (vsum4ubs VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VAVGSB, 0xfc0007ff, 0x10000502, 0x0, // Vector Average Signed Byte VX-form (vavgsb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VAVGSH, 0xfc0007ff, 0x10000542, 0x0, // Vector Average Signed Halfword VX-form (vavgsh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VAVGSW, 0xfc0007ff, 0x10000582, 0x0, // Vector Average Signed Word VX-form (vavgsw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VAVGUB, 0xfc0007ff, 0x10000402, 0x0, // Vector Average Unsigned Byte VX-form (vavgub VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VAVGUW, 0xfc0007ff, 0x10000482, 0x0, // Vector Average Unsigned Word VX-form (vavguw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VAVGUH, 0xfc0007ff, 0x10000442, 0x0, // Vector Average Unsigned Halfword VX-form (vavguh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMAXSB, 0xfc0007ff, 0x10000102, 0x0, // Vector Maximum Signed Byte VX-form (vmaxsb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMAXSD, 0xfc0007ff, 0x100001c2, 0x0, // Vector Maximum Signed Doubleword VX-form (vmaxsd VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMAXUB, 0xfc0007ff, 0x10000002, 0x0, // Vector Maximum Unsigned Byte VX-form (vmaxub VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMAXUD, 0xfc0007ff, 0x100000c2, 0x0, // Vector Maximum Unsigned Doubleword VX-form (vmaxud VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMAXSH, 0xfc0007ff, 0x10000142, 0x0, // Vector Maximum Signed Halfword VX-form (vmaxsh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMAXSW, 0xfc0007ff, 0x10000182, 0x0, // Vector Maximum Signed Word VX-form (vmaxsw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMAXUH, 0xfc0007ff, 0x10000042, 0x0, // Vector Maximum Unsigned Halfword VX-form (vmaxuh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMAXUW, 0xfc0007ff, 0x10000082, 0x0, // Vector Maximum Unsigned Word VX-form (vmaxuw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMINSB, 0xfc0007ff, 0x10000302, 0x0, // Vector Minimum Signed Byte VX-form (vminsb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMINSD, 0xfc0007ff, 0x100003c2, 0x0, // Vector Minimum Signed Doubleword VX-form (vminsd VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMINUB, 0xfc0007ff, 0x10000202, 0x0, // Vector Minimum Unsigned Byte VX-form (vminub VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMINUD, 0xfc0007ff, 0x100002c2, 0x0, // Vector Minimum Unsigned Doubleword VX-form (vminud VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMINSH, 0xfc0007ff, 0x10000342, 0x0, // Vector Minimum Signed Halfword VX-form (vminsh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMINSW, 0xfc0007ff, 0x10000382, 0x0, // Vector Minimum Signed Word VX-form (vminsw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMINUH, 0xfc0007ff, 0x10000242, 0x0, // Vector Minimum Unsigned Halfword VX-form (vminuh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMINUW, 0xfc0007ff, 0x10000282, 0x0, // Vector Minimum Unsigned Word VX-form (vminuw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPEQUB, 0xfc0007ff, 0x10000006, 0x0, // Vector Compare Equal To Unsigned Byte VC-form (vcmpequb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPEQUBCC, 0xfc0007ff, 0x10000406, 0x0, // Vector Compare Equal To Unsigned Byte VC-form (vcmpequb. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPEQUH, 0xfc0007ff, 0x10000046, 0x0, // Vector Compare Equal To Unsigned Halfword VC-form (vcmpequh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPEQUHCC, 0xfc0007ff, 0x10000446, 0x0, // Vector Compare Equal To Unsigned Halfword VC-form (vcmpequh. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPEQUW, 0xfc0007ff, 0x10000086, 0x0, // Vector Compare Equal To Unsigned Word VC-form (vcmpequw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPEQUWCC, 0xfc0007ff, 0x10000486, 0x0, // Vector Compare Equal To Unsigned Word VC-form (vcmpequw. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPEQUD, 0xfc0007ff, 0x100000c7, 0x0, // Vector Compare Equal To Unsigned Doubleword VX-form (vcmpequd VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPEQUDCC, 0xfc0007ff, 0x100004c7, 0x0, // Vector Compare Equal To Unsigned Doubleword VX-form (vcmpequd. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPNEB, 0xfc0007ff, 0x10000007, 0x0, // Vector Compare Not Equal Byte VX-form (vcmpneb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPNEBCC, 0xfc0007ff, 0x10000407, 0x0, // Vector Compare Not Equal Byte VX-form (vcmpneb. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPNEZB, 0xfc0007ff, 0x10000107, 0x0, // Vector Compare Not Equal or Zero Byte VX-form (vcmpnezb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPNEZBCC, 0xfc0007ff, 0x10000507, 0x0, // Vector Compare Not Equal or Zero Byte VX-form (vcmpnezb. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPNEH, 0xfc0007ff, 0x10000047, 0x0, // Vector Compare Not Equal Halfword VX-form (vcmpneh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPNEHCC, 0xfc0007ff, 0x10000447, 0x0, // Vector Compare Not Equal Halfword VX-form (vcmpneh. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPNEZH, 0xfc0007ff, 0x10000147, 0x0, // Vector Compare Not Equal or Zero Halfword VX-form (vcmpnezh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPNEZHCC, 0xfc0007ff, 0x10000547, 0x0, // Vector Compare Not Equal or Zero Halfword VX-form (vcmpnezh. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPNEW, 0xfc0007ff, 0x10000087, 0x0, // Vector Compare Not Equal Word VX-form (vcmpnew VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPNEWCC, 0xfc0007ff, 0x10000487, 0x0, // Vector Compare Not Equal Word VX-form (vcmpnew. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPNEZW, 0xfc0007ff, 0x10000187, 0x0, // Vector Compare Not Equal or Zero Word VX-form (vcmpnezw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPNEZWCC, 0xfc0007ff, 0x10000587, 0x0, // Vector Compare Not Equal or Zero Word VX-form (vcmpnezw. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTSB, 0xfc0007ff, 0x10000306, 0x0, // Vector Compare Greater Than Signed Byte VC-form (vcmpgtsb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTSBCC, 0xfc0007ff, 0x10000706, 0x0, // Vector Compare Greater Than Signed Byte VC-form (vcmpgtsb. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTSD, 0xfc0007ff, 0x100003c7, 0x0, // Vector Compare Greater Than Signed Doubleword VX-form (vcmpgtsd VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTSDCC, 0xfc0007ff, 0x100007c7, 0x0, // Vector Compare Greater Than Signed Doubleword VX-form (vcmpgtsd. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTSH, 0xfc0007ff, 0x10000346, 0x0, // Vector Compare Greater Than Signed Halfword VC-form (vcmpgtsh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTSHCC, 0xfc0007ff, 0x10000746, 0x0, // Vector Compare Greater Than Signed Halfword VC-form (vcmpgtsh. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTSW, 0xfc0007ff, 0x10000386, 0x0, // Vector Compare Greater Than Signed Word VC-form (vcmpgtsw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTSWCC, 0xfc0007ff, 0x10000786, 0x0, // Vector Compare Greater Than Signed Word VC-form (vcmpgtsw. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTUB, 0xfc0007ff, 0x10000206, 0x0, // Vector Compare Greater Than Unsigned Byte VC-form (vcmpgtub VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTUBCC, 0xfc0007ff, 0x10000606, 0x0, // Vector Compare Greater Than Unsigned Byte VC-form (vcmpgtub. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTUD, 0xfc0007ff, 0x100002c7, 0x0, // Vector Compare Greater Than Unsigned Doubleword VX-form (vcmpgtud VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTUDCC, 0xfc0007ff, 0x100006c7, 0x0, // Vector Compare Greater Than Unsigned Doubleword VX-form (vcmpgtud. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTUH, 0xfc0007ff, 0x10000246, 0x0, // Vector Compare Greater Than Unsigned Halfword VC-form (vcmpgtuh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTUHCC, 0xfc0007ff, 0x10000646, 0x0, // Vector Compare Greater Than Unsigned Halfword VC-form (vcmpgtuh. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTUW, 0xfc0007ff, 0x10000286, 0x0, // Vector Compare Greater Than Unsigned Word VC-form (vcmpgtuw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTUWCC, 0xfc0007ff, 0x10000686, 0x0, // Vector Compare Greater Than Unsigned Word VC-form (vcmpgtuw. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VAND, 0xfc0007ff, 0x10000404, 0x0, // Vector Logical AND VX-form (vand VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VANDC, 0xfc0007ff, 0x10000444, 0x0, // Vector Logical AND with Complement VX-form (vandc VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VEQV, 0xfc0007ff, 0x10000684, 0x0, // Vector Logical Equivalent VX-form (veqv VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VNAND, 0xfc0007ff, 0x10000584, 0x0, // Vector Logical NAND VX-form (vnand VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VORC, 0xfc0007ff, 0x10000544, 0x0, // Vector Logical OR with Complement VX-form (vorc VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VNOR, 0xfc0007ff, 0x10000504, 0x0, // Vector Logical NOR VX-form (vnor VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VOR, 0xfc0007ff, 0x10000484, 0x0, // Vector Logical OR VX-form (vor VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VXOR, 0xfc0007ff, 0x100004c4, 0x0, // Vector Logical XOR VX-form (vxor VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VRLB, 0xfc0007ff, 0x10000004, 0x0, // Vector Rotate Left Byte VX-form (vrlb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VRLH, 0xfc0007ff, 0x10000044, 0x0, // Vector Rotate Left Halfword VX-form (vrlh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VRLW, 0xfc0007ff, 0x10000084, 0x0, // Vector Rotate Left Word VX-form (vrlw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VRLD, 0xfc0007ff, 0x100000c4, 0x0, // Vector Rotate Left Doubleword VX-form (vrld VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSLB, 0xfc0007ff, 0x10000104, 0x0, // Vector Shift Left Byte VX-form (vslb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSLH, 0xfc0007ff, 0x10000144, 0x0, // Vector Shift Left Halfword VX-form (vslh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSLW, 0xfc0007ff, 0x10000184, 0x0, // Vector Shift Left Word VX-form (vslw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSLD, 0xfc0007ff, 0x100005c4, 0x0, // Vector Shift Left Doubleword VX-form (vsld VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSRB, 0xfc0007ff, 0x10000204, 0x0, // Vector Shift Right Byte VX-form (vsrb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSRH, 0xfc0007ff, 0x10000244, 0x0, // Vector Shift Right Halfword VX-form (vsrh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSRW, 0xfc0007ff, 0x10000284, 0x0, // Vector Shift Right Word VX-form (vsrw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSRD, 0xfc0007ff, 0x100006c4, 0x0, // Vector Shift Right Doubleword VX-form (vsrd VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSRAB, 0xfc0007ff, 0x10000304, 0x0, // Vector Shift Right Algebraic Byte VX-form (vsrab VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSRAH, 0xfc0007ff, 0x10000344, 0x0, // Vector Shift Right Algebraic Halfword VX-form (vsrah VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSRAW, 0xfc0007ff, 0x10000384, 0x0, // Vector Shift Right Algebraic Word VX-form (vsraw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSRAD, 0xfc0007ff, 0x100003c4, 0x0, // Vector Shift Right Algebraic Doubleword VX-form (vsrad VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VADDFP, 0xfc0007ff, 0x1000000a, 0x0, // Vector Add Single-Precision VX-form (vaddfp VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSUBFP, 0xfc0007ff, 0x1000004a, 0x0, // Vector Subtract Single-Precision VX-form (vsubfp VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMADDFP, 0xfc00003f, 0x1000002e, 0x0, // Vector Multiply-Add Single-Precision VA-form (vmaddfp VRT,VRA,VRC,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_21_25, ap_VecReg_16_20}},
-	{VNMSUBFP, 0xfc00003f, 0x1000002f, 0x0, // Vector Negative Multiply-Subtract Single-Precision VA-form (vnmsubfp VRT,VRA,VRC,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_21_25, ap_VecReg_16_20}},
-	{VMAXFP, 0xfc0007ff, 0x1000040a, 0x0, // Vector Maximum Single-Precision VX-form (vmaxfp VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VMINFP, 0xfc0007ff, 0x1000044a, 0x0, // Vector Minimum Single-Precision VX-form (vminfp VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCTSXS, 0xfc0007ff, 0x100003ca, 0x0, // Vector Convert To Signed Fixed-Point Word Saturate VX-form (vctsxs VRT,VRB,UIM)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}},
-	{VCTUXS, 0xfc0007ff, 0x1000038a, 0x0, // Vector Convert To Unsigned Fixed-Point Word Saturate VX-form (vctuxs VRT,VRB,UIM)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}},
-	{VCFSX, 0xfc0007ff, 0x1000034a, 0x0, // Vector Convert From Signed Fixed-Point Word VX-form (vcfsx VRT,VRB,UIM)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}},
-	{VCFUX, 0xfc0007ff, 0x1000030a, 0x0, // Vector Convert From Unsigned Fixed-Point Word VX-form (vcfux VRT,VRB,UIM)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}},
-	{VRFIM, 0xfc0007ff, 0x100002ca, 0x1f0000, // Vector Round to Single-Precision Integer toward -Infinity VX-form (vrfim VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VRFIN, 0xfc0007ff, 0x1000020a, 0x1f0000, // Vector Round to Single-Precision Integer Nearest VX-form (vrfin VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VRFIP, 0xfc0007ff, 0x1000028a, 0x1f0000, // Vector Round to Single-Precision Integer toward +Infinity VX-form (vrfip VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VRFIZ, 0xfc0007ff, 0x1000024a, 0x1f0000, // Vector Round to Single-Precision Integer toward Zero VX-form (vrfiz VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VCMPBFP, 0xfc0007ff, 0x100003c6, 0x0, // Vector Compare Bounds Single-Precision VC-form (vcmpbfp VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPBFPCC, 0xfc0007ff, 0x100007c6, 0x0, // Vector Compare Bounds Single-Precision VC-form (vcmpbfp. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPEQFP, 0xfc0007ff, 0x100000c6, 0x0, // Vector Compare Equal To Single-Precision VC-form (vcmpeqfp VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPEQFPCC, 0xfc0007ff, 0x100004c6, 0x0, // Vector Compare Equal To Single-Precision VC-form (vcmpeqfp. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGEFP, 0xfc0007ff, 0x100001c6, 0x0, // Vector Compare Greater Than or Equal To Single-Precision VC-form (vcmpgefp VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGEFPCC, 0xfc0007ff, 0x100005c6, 0x0, // Vector Compare Greater Than or Equal To Single-Precision VC-form (vcmpgefp. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTFP, 0xfc0007ff, 0x100002c6, 0x0, // Vector Compare Greater Than Single-Precision VC-form (vcmpgtfp VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCMPGTFPCC, 0xfc0007ff, 0x100006c6, 0x0, // Vector Compare Greater Than Single-Precision VC-form (vcmpgtfp. VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VEXPTEFP, 0xfc0007ff, 0x1000018a, 0x1f0000, // Vector 2 Raised to the Exponent Estimate Floating-Point VX-form (vexptefp VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VLOGEFP, 0xfc0007ff, 0x100001ca, 0x1f0000, // Vector Log Base 2 Estimate Floating-Point VX-form (vlogefp VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VREFP, 0xfc0007ff, 0x1000010a, 0x1f0000, // Vector Reciprocal Estimate Single-Precision VX-form (vrefp VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VRSQRTEFP, 0xfc0007ff, 0x1000014a, 0x1f0000, // Vector Reciprocal Square Root Estimate Single-Precision VX-form (vrsqrtefp VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VCIPHER, 0xfc0007ff, 0x10000508, 0x0, // Vector AES Cipher VX-form (vcipher VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VCIPHERLAST, 0xfc0007ff, 0x10000509, 0x0, // Vector AES Cipher Last VX-form (vcipherlast VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VNCIPHER, 0xfc0007ff, 0x10000548, 0x0, // Vector AES Inverse Cipher VX-form (vncipher VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VNCIPHERLAST, 0xfc0007ff, 0x10000549, 0x0, // Vector AES Inverse Cipher Last VX-form (vncipherlast VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VSBOX, 0xfc0007ff, 0x100005c8, 0xf800, // Vector AES SubBytes VX-form (vsbox VRT,VRA)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15}},
-	{VSHASIGMAD, 0xfc0007ff, 0x100006c2, 0x0, // Vector SHA-512 Sigma Doubleword VX-form (vshasigmad VRT,VRA,ST,SIX)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_ImmUnsigned_16_16, ap_ImmUnsigned_17_20}},
-	{VSHASIGMAW, 0xfc0007ff, 0x10000682, 0x0, // Vector SHA-256 Sigma Word VX-form (vshasigmaw VRT,VRA,ST,SIX)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_ImmUnsigned_16_16, ap_ImmUnsigned_17_20}},
-	{VPMSUMB, 0xfc0007ff, 0x10000408, 0x0, // Vector Polynomial Multiply-Sum Byte VX-form (vpmsumb VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPMSUMD, 0xfc0007ff, 0x100004c8, 0x0, // Vector Polynomial Multiply-Sum Doubleword VX-form (vpmsumd VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPMSUMH, 0xfc0007ff, 0x10000448, 0x0, // Vector Polynomial Multiply-Sum Halfword VX-form (vpmsumh VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPMSUMW, 0xfc0007ff, 0x10000488, 0x0, // Vector Polynomial Multiply-Sum Word VX-form (vpmsumw VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VPERMXOR, 0xfc00003f, 0x1000002d, 0x0, // Vector Permute and Exclusive-OR VA-form (vpermxor VRT,VRA,VRB,VRC)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
-	{VGBBD, 0xfc0007ff, 0x1000050c, 0x1f0000, // Vector Gather Bits by Bytes by Doubleword VX-form (vgbbd VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VCLZB, 0xfc0007ff, 0x10000702, 0x1f0000, // Vector Count Leading Zeros Byte VX-form (vclzb VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VCLZH, 0xfc0007ff, 0x10000742, 0x1f0000, // Vector Count Leading Zeros Halfword VX-form (vclzh VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VCLZW, 0xfc0007ff, 0x10000782, 0x1f0000, // Vector Count Leading Zeros Word VX-form (vclzw VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VCLZD, 0xfc0007ff, 0x100007c2, 0x1f0000, // Vector Count Leading Zeros Doubleword (vclzd VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VPOPCNTB, 0xfc0007ff, 0x10000703, 0x1f0000, // Vector Population Count Byte (vpopcntb VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VPOPCNTD, 0xfc0007ff, 0x100007c3, 0x1f0000, // Vector Population Count Doubleword (vpopcntd VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VPOPCNTH, 0xfc0007ff, 0x10000743, 0x1f0000, // Vector Population Count Halfword (vpopcnth VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VPOPCNTW, 0xfc0007ff, 0x10000783, 0x1f0000, // Vector Population Count Word (vpopcntw VRT,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
-	{VBPERMQ, 0xfc0007ff, 0x1000054c, 0x0, // Vector Bit Permute Quadword VX-form (vbpermq VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{VBPERMD, 0xfc0007ff, 0x100005cc, 0x0, // Vector Bit Permute Doubleword VX-form (vbpermd VRT,VRA,VRB)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
-	{BCDADDCC, 0xfc0005ff, 0x10000401, 0x0, // Decimal Add Modulo VX-form (bcdadd. VRT,VRA,VRB,PS)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
-	{BCDSUBCC, 0xfc0005ff, 0x10000441, 0x0, // Decimal Subtract Modulo VX-form (bcdsub. VRT,VRA,VRB,PS)
-		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
-	{MTVSCR, 0xfc0007ff, 0x10000644, 0x3ff0000, // Move To Vector Status and Control Register VX-form (mtvscr VRB)
-		[5]*argField{ap_VecReg_16_20}},
-	{MFVSCR, 0xfc0007ff, 0x10000604, 0x1ff800, // Move From Vector Status and Control Register VX-form (mfvscr VRT)
-		[5]*argField{ap_VecReg_6_10}},
-	{DADD, 0xfc0007ff, 0xec000004, 0x0, // DFP Add [Quad] X-form (dadd FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DADDCC, 0xfc0007ff, 0xec000005, 0x0, // DFP Add [Quad] X-form (dadd. FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DSUB, 0xfc0007ff, 0xec000404, 0x0, // DFP Subtract [Quad] X-form (dsub FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DSUBCC, 0xfc0007ff, 0xec000405, 0x0, // DFP Subtract [Quad] X-form (dsub. FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DMUL, 0xfc0007ff, 0xec000044, 0x0, // DFP Multiply [Quad] X-form (dmul FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DMULCC, 0xfc0007ff, 0xec000045, 0x0, // DFP Multiply [Quad] X-form (dmul. FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DDIV, 0xfc0007ff, 0xec000444, 0x0, // DFP Divide [Quad] X-form (ddiv FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DDIVCC, 0xfc0007ff, 0xec000445, 0x0, // DFP Divide [Quad] X-form (ddiv. FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DCMPU, 0xfc0007fe, 0xec000504, 0x600001, // DFP Compare Unordered [Quad] X-form (dcmpu BF,FRA,FRB)
-		[5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DCMPO, 0xfc0007fe, 0xec000104, 0x600001, // DFP Compare Ordered [Quad] X-form (dcmpo BF,FRA,FRB)
-		[5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DTSTDC, 0xfc0003fe, 0xec000184, 0x600001, // DFP Test Data Class [Quad] Z22-form (dtstdc BF,FRA,DCM)
-		[5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
-	{DTSTDG, 0xfc0003fe, 0xec0001c4, 0x600001, // DFP Test Data Group [Quad] Z22-form (dtstdg BF,FRA,DGM)
-		[5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
-	{DTSTEX, 0xfc0007fe, 0xec000144, 0x600001, // DFP Test Exponent [Quad] X-form (dtstex BF,FRA,FRB)
-		[5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DTSTSF, 0xfc0007fe, 0xec000544, 0x600001, // DFP Test Significance [Quad] X-form (dtstsf BF,FRA,FRB)
-		[5]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DQUAI, 0xfc0001ff, 0xec000086, 0x0, // DFP Quantize Immediate [Quad] Z23-form (dquai TE,FRT,FRB,RMC)
-		[5]*argField{ap_ImmSigned_11_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
-	{DQUAICC, 0xfc0001ff, 0xec000087, 0x0, // DFP Quantize Immediate [Quad] Z23-form (dquai. TE,FRT,FRB,RMC)
-		[5]*argField{ap_ImmSigned_11_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
-	{DQUA, 0xfc0001ff, 0xec000006, 0x0, // DFP Quantize [Quad] Z23-form (dqua FRT,FRA,FRB,RMC)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
-	{DQUACC, 0xfc0001ff, 0xec000007, 0x0, // DFP Quantize [Quad] Z23-form (dqua. FRT,FRA,FRB,RMC)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
-	{DRRND, 0xfc0001ff, 0xec000046, 0x0, // DFP Reround [Quad] Z23-form (drrnd FRT,FRA,FRB,RMC)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
-	{DRRNDCC, 0xfc0001ff, 0xec000047, 0x0, // DFP Reround [Quad] Z23-form (drrnd. FRT,FRA,FRB,RMC)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
-	{DRINTX, 0xfc0001ff, 0xec0000c6, 0x1e0000, // DFP Round To FP Integer With Inexact [Quad] Z23-form (drintx R,FRT,FRB,RMC)
-		[5]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
-	{DRINTXCC, 0xfc0001ff, 0xec0000c7, 0x1e0000, // DFP Round To FP Integer With Inexact [Quad] Z23-form (drintx. R,FRT,FRB,RMC)
-		[5]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
-	{DRINTN, 0xfc0001ff, 0xec0001c6, 0x1e0000, // DFP Round To FP Integer Without Inexact [Quad] Z23-form (drintn R,FRT,FRB,RMC)
-		[5]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
-	{DRINTNCC, 0xfc0001ff, 0xec0001c7, 0x1e0000, // DFP Round To FP Integer Without Inexact [Quad] Z23-form (drintn. R,FRT,FRB,RMC)
-		[5]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
-	{DCTDP, 0xfc0007ff, 0xec000204, 0x1f0000, // DFP Convert To DFP Long X-form (dctdp FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DCTDPCC, 0xfc0007ff, 0xec000205, 0x1f0000, // DFP Convert To DFP Long X-form (dctdp. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DCTQPQ, 0xfc0007ff, 0xfc000204, 0x1f0000, // DFP Convert To DFP Extended X-form (dctqpq FRTp,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DCTQPQCC, 0xfc0007ff, 0xfc000205, 0x1f0000, // DFP Convert To DFP Extended X-form (dctqpq. FRTp,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DRSP, 0xfc0007ff, 0xec000604, 0x1f0000, // DFP Round To DFP Short X-form (drsp FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DRSPCC, 0xfc0007ff, 0xec000605, 0x1f0000, // DFP Round To DFP Short X-form (drsp. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DRDPQ, 0xfc0007ff, 0xfc000604, 0x1f0000, // DFP Round To DFP Long X-form (drdpq FRTp,FRBp)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DRDPQCC, 0xfc0007ff, 0xfc000605, 0x1f0000, // DFP Round To DFP Long X-form (drdpq. FRTp,FRBp)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DCFFIX, 0xfc0007ff, 0xec000644, 0x1f0000, // DFP Convert From Fixed X-form (dcffix FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DCFFIXCC, 0xfc0007ff, 0xec000645, 0x1f0000, // DFP Convert From Fixed X-form (dcffix. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DCFFIXQ, 0xfc0007ff, 0xfc000644, 0x1f0000, // DFP Convert From Fixed Quad X-form (dcffixq FRTp,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DCFFIXQCC, 0xfc0007ff, 0xfc000645, 0x1f0000, // DFP Convert From Fixed Quad X-form (dcffixq. FRTp,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DCTFIX, 0xfc0007ff, 0xec000244, 0x1f0000, // DFP Convert To Fixed [Quad] X-form (dctfix FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DCTFIXCC, 0xfc0007ff, 0xec000245, 0x1f0000, // DFP Convert To Fixed [Quad] X-form (dctfix. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DDEDPD, 0xfc0007ff, 0xec000284, 0x70000, // DFP Decode DPD To BCD [Quad] X-form (ddedpd SP,FRT,FRB)
-		[5]*argField{ap_ImmUnsigned_11_12, ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DDEDPDCC, 0xfc0007ff, 0xec000285, 0x70000, // DFP Decode DPD To BCD [Quad] X-form (ddedpd. SP,FRT,FRB)
-		[5]*argField{ap_ImmUnsigned_11_12, ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DENBCD, 0xfc0007ff, 0xec000684, 0xf0000, // DFP Encode BCD To DPD [Quad] X-form (denbcd S,FRT,FRB)
-		[5]*argField{ap_ImmUnsigned_11_11, ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DENBCDCC, 0xfc0007ff, 0xec000685, 0xf0000, // DFP Encode BCD To DPD [Quad] X-form (denbcd. S,FRT,FRB)
-		[5]*argField{ap_ImmUnsigned_11_11, ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DXEX, 0xfc0007ff, 0xec0002c4, 0x1f0000, // DFP Extract Biased Exponent [Quad] X-form (dxex FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DXEXCC, 0xfc0007ff, 0xec0002c5, 0x1f0000, // DFP Extract Biased Exponent [Quad] X-form (dxex. FRT,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
-	{DIEX, 0xfc0007ff, 0xec0006c4, 0x0, // DFP Insert Biased Exponent [Quad] X-form (diex FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DIEXCC, 0xfc0007ff, 0xec0006c5, 0x0, // DFP Insert Biased Exponent [Quad] X-form (diex. FRT,FRA,FRB)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
-	{DSCLI, 0xfc0003ff, 0xec000084, 0x0, // DFP Shift Significand Left Immediate [Quad] Z22-form (dscli FRT,FRA,SH)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
-	{DSCLICC, 0xfc0003ff, 0xec000085, 0x0, // DFP Shift Significand Left Immediate [Quad] Z22-form (dscli. FRT,FRA,SH)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
-	{DSCRI, 0xfc0003ff, 0xec0000c4, 0x0, // DFP Shift Significand Right Immediate [Quad] Z22-form (dscri FRT,FRA,SH)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
-	{DSCRICC, 0xfc0003ff, 0xec0000c5, 0x0, // DFP Shift Significand Right Immediate [Quad] Z22-form (dscri. FRT,FRA,SH)
-		[5]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
-	{LXSDX, 0xfc0007fe, 0x7c000498, 0x0, // Load VSX Scalar Doubleword Indexed XX1-form (lxsdx XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LXSIWAX, 0xfc0007fe, 0x7c000098, 0x0, // Load VSX Scalar as Integer Word Algebraic Indexed XX1-form (lxsiwax XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LXSIWZX, 0xfc0007fe, 0x7c000018, 0x0, // Load VSX Scalar as Integer Word and Zero Indexed XX1-form (lxsiwzx XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LXSSPX, 0xfc0007fe, 0x7c000418, 0x0, // Load VSX Scalar Single-Precision Indexed XX1-form (lxsspx XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LXVD2X, 0xfc0007fe, 0x7c000698, 0x0, // Load VSX Vector Doubleword*2 Indexed XX1-form (lxvd2x XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LXVDSX, 0xfc0007fe, 0x7c000298, 0x0, // Load VSX Vector Doubleword & Splat Indexed XX1-form (lxvdsx XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LXVW4X, 0xfc0007fe, 0x7c000618, 0x0, // Load VSX Vector Word*4 Indexed XX1-form (lxvw4x XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LXVH8X, 0xfc0007fe, 0x7c000658, 0x0, // Load VSX Vector Halfword*8 Indexed XX1-form (lxvh8x XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LXVB16X, 0xfc0007fe, 0x7c0006d8, 0x0, // Load VSX Vector Byte*16 Indexed XX1-form (lxvb16x XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LXV, 0xfc000007, 0xf4000001, 0x0, // Load VSX Vector DQ-form (lxv XT,DQ(RA))
-		[5]*argField{ap_VecSReg_28_28_6_10, ap_Offset_16_27_shift4, ap_Reg_11_15}},
-	{LXVL, 0xfc0007fe, 0x7c00021a, 0x0, // Load VSX Vector with Length X-form (lxvl XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LXVLL, 0xfc0007fe, 0x7c00025a, 0x0, // Load VSX Vector Left-justified with Length X-form (lxvll XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LXVX, 0xfc0007be, 0x7c000218, 0x40, // Load VSX Vector Indexed X-form (lxvx XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STXSDX, 0xfc0007fe, 0x7c000598, 0x0, // Store VSX Scalar Doubleword Indexed XX1-form (stxsdx XS,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STXSIWX, 0xfc0007fe, 0x7c000118, 0x0, // Store VSX Scalar as Integer Word Indexed XX1-form (stxsiwx XS,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STXSSPX, 0xfc0007fe, 0x7c000518, 0x0, // Store VSX Scalar Single-Precision Indexed XX1-form (stxsspx XS,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STXVD2X, 0xfc0007fe, 0x7c000798, 0x0, // Store VSX Vector Doubleword*2 Indexed XX1-form (stxvd2x XS,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STXVW4X, 0xfc0007fe, 0x7c000718, 0x0, // Store VSX Vector Word*4 Indexed XX1-form (stxvw4x XS,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STXVH8X, 0xfc0007fe, 0x7c000758, 0x0, // Store VSX Vector Halfword*4 Indexed XX1-form (stxvh8x XS,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STXVB16X, 0xfc0007fe, 0x7c0007d8, 0x0, // Store VSX Vector Byte*16 Indexed XX1-form (stxvb16x XS,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STXV, 0xfc000007, 0xf4000005, 0x0, // Store VSX Vector DQ-form (stxv XS,DQ(RA))
-		[5]*argField{ap_VecSReg_28_28_6_10, ap_Offset_16_27_shift4, ap_Reg_11_15}},
-	{STXVL, 0xfc0007fe, 0x7c00031a, 0x0, // Store VSX Vector with Length X-form (stxvl XS,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STXVLL, 0xfc0007fe, 0x7c00035a, 0x0, // Store VSX Vector Left-justified with Length X-form (stxvll XS,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STXVX, 0xfc0007fe, 0x7c000318, 0x0, // Store VSX Vector Indexed X-form (stxvx XS,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{XSABSDP, 0xfc0007fc, 0xf0000564, 0x1f0000, // VSX Scalar Absolute Value Double-Precision XX2-form (xsabsdp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSADDDP, 0xfc0007f8, 0xf0000100, 0x0, // VSX Scalar Add Double-Precision XX3-form (xsadddp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSADDSP, 0xfc0007f8, 0xf0000000, 0x0, // VSX Scalar Add Single-Precision XX3-form (xsaddsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSCMPODP, 0xfc0007f8, 0xf0000158, 0x600001, // VSX Scalar Compare Ordered Double-Precision XX3-form (xscmpodp BF,XA,XB)
-		[5]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSCMPUDP, 0xfc0007f8, 0xf0000118, 0x600001, // VSX Scalar Compare Unordered Double-Precision XX3-form (xscmpudp BF,XA,XB)
-		[5]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSCPSGNDP, 0xfc0007f8, 0xf0000580, 0x0, // VSX Scalar Copy Sign Double-Precision XX3-form (xscpsgndp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSCVDPSP, 0xfc0007fc, 0xf0000424, 0x1f0000, // VSX Scalar round Double-Precision to single-precision and Convert to Single-Precision format XX2-form (xscvdpsp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSCVDPSPN, 0xfc0007fc, 0xf000042c, 0x1f0000, // VSX Scalar Convert Scalar Single-Precision to Vector Single-Precision format Non-signalling XX2-form (xscvdpspn XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSCVDPSXDS, 0xfc0007fc, 0xf0000560, 0x1f0000, // VSX Scalar truncate Double-Precision to integer and Convert to Signed Integer Doubleword format with Saturate XX2-form (xscvdpsxds XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSCVDPSXWS, 0xfc0007fc, 0xf0000160, 0x1f0000, // VSX Scalar truncate Double-Precision to integer and Convert to Signed Integer Word format with Saturate XX2-form (xscvdpsxws XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSCVDPUXDS, 0xfc0007fc, 0xf0000520, 0x1f0000, // VSX Scalar truncate Double-Precision integer and Convert to Unsigned Integer Doubleword format with Saturate XX2-form (xscvdpuxds XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSCVDPUXWS, 0xfc0007fc, 0xf0000120, 0x1f0000, // VSX Scalar truncate Double-Precision to integer and Convert to Unsigned Integer Word format with Saturate XX2-form (xscvdpuxws XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSCVSPDP, 0xfc0007fc, 0xf0000524, 0x1f0000, // VSX Scalar Convert Single-Precision to Double-Precision format XX2-form (xscvspdp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSCVSPDPN, 0xfc0007fc, 0xf000052c, 0x1f0000, // VSX Scalar Convert Single-Precision to Double-Precision format Non-signalling XX2-form (xscvspdpn XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSCVSXDDP, 0xfc0007fc, 0xf00005e0, 0x1f0000, // VSX Scalar Convert Signed Integer Doubleword to floating-point format and round to Double-Precision format XX2-form (xscvsxddp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSCVSXDSP, 0xfc0007fc, 0xf00004e0, 0x1f0000, // VSX Scalar Convert Signed Integer Doubleword to floating-point format and round to Single-Precision XX2-form (xscvsxdsp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSCVUXDDP, 0xfc0007fc, 0xf00005a0, 0x1f0000, // VSX Scalar Convert Unsigned Integer Doubleword to floating-point format and round to Double-Precision format XX2-form (xscvuxddp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSCVUXDSP, 0xfc0007fc, 0xf00004a0, 0x1f0000, // VSX Scalar Convert Unsigned Integer Doubleword to floating-point format and round to Single-Precision XX2-form (xscvuxdsp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSDIVDP, 0xfc0007f8, 0xf00001c0, 0x0, // VSX Scalar Divide Double-Precision XX3-form (xsdivdp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSDIVSP, 0xfc0007f8, 0xf00000c0, 0x0, // VSX Scalar Divide Single-Precision XX3-form (xsdivsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSMADDADP, 0xfc0007f8, 0xf0000108, 0x0, // VSX Scalar Multiply-Add Double-Precision XX3-form (xsmaddadp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSMADDASP, 0xfc0007f8, 0xf0000008, 0x0, // VSX Scalar Multiply-Add Single-Precision XX3-form (xsmaddasp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSMAXDP, 0xfc0007f8, 0xf0000500, 0x0, // VSX Scalar Maximum Double-Precision XX3-form (xsmaxdp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSMINDP, 0xfc0007f8, 0xf0000540, 0x0, // VSX Scalar Minimum Double-Precision XX3-form (xsmindp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSMSUBADP, 0xfc0007f8, 0xf0000188, 0x0, // VSX Scalar Multiply-Subtract Double-Precision XX3-form (xsmsubadp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSMSUBASP, 0xfc0007f8, 0xf0000088, 0x0, // VSX Scalar Multiply-Subtract Single-Precision XX3-form (xsmsubasp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSMULDP, 0xfc0007f8, 0xf0000180, 0x0, // VSX Scalar Multiply Double-Precision XX3-form (xsmuldp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSMULSP, 0xfc0007f8, 0xf0000080, 0x0, // VSX Scalar Multiply Single-Precision XX3-form (xsmulsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSNABSDP, 0xfc0007fc, 0xf00005a4, 0x1f0000, // VSX Scalar Negative Absolute Value Double-Precision XX2-form (xsnabsdp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSNEGDP, 0xfc0007fc, 0xf00005e4, 0x1f0000, // VSX Scalar Negate Double-Precision XX2-form (xsnegdp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSNMADDADP, 0xfc0007f8, 0xf0000508, 0x0, // VSX Scalar Negative Multiply-Add Double-Precision XX3-form (xsnmaddadp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSNMADDASP, 0xfc0007f8, 0xf0000408, 0x0, // VSX Scalar Negative Multiply-Add Single-Precision XX3-form (xsnmaddasp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSNMSUBADP, 0xfc0007f8, 0xf0000588, 0x0, // VSX Scalar Negative Multiply-Subtract Double-Precision XX3-form (xsnmsubadp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSNMSUBASP, 0xfc0007f8, 0xf0000488, 0x0, // VSX Scalar Negative Multiply-Subtract Single-Precision XX3-form (xsnmsubasp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSRDPI, 0xfc0007fc, 0xf0000124, 0x1f0000, // VSX Scalar Round to Double-Precision Integer using round to Nearest Away XX2-form (xsrdpi XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSRDPIC, 0xfc0007fc, 0xf00001ac, 0x1f0000, // VSX Scalar Round to Double-Precision Integer exact using Current rounding mode XX2-form (xsrdpic XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSRDPIM, 0xfc0007fc, 0xf00001e4, 0x1f0000, // VSX Scalar Round to Double-Precision Integer using round toward -Infinity XX2-form (xsrdpim XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSRDPIP, 0xfc0007fc, 0xf00001a4, 0x1f0000, // VSX Scalar Round to Double-Precision Integer using round toward +Infinity XX2-form (xsrdpip XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSRDPIZ, 0xfc0007fc, 0xf0000164, 0x1f0000, // VSX Scalar Round to Double-Precision Integer using round toward Zero XX2-form (xsrdpiz XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSREDP, 0xfc0007fc, 0xf0000168, 0x1f0000, // VSX Scalar Reciprocal Estimate Double-Precision XX2-form (xsredp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSRESP, 0xfc0007fc, 0xf0000068, 0x1f0000, // VSX Scalar Reciprocal Estimate Single-Precision XX2-form (xsresp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSRSP, 0xfc0007fc, 0xf0000464, 0x1f0000, // VSX Scalar Round to Single-Precision XX2-form (xsrsp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSRSQRTEDP, 0xfc0007fc, 0xf0000128, 0x1f0000, // VSX Scalar Reciprocal Square Root Estimate Double-Precision XX2-form (xsrsqrtedp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSRSQRTESP, 0xfc0007fc, 0xf0000028, 0x1f0000, // VSX Scalar Reciprocal Square Root Estimate Single-Precision XX2-form (xsrsqrtesp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSSQRTDP, 0xfc0007fc, 0xf000012c, 0x1f0000, // VSX Scalar Square Root Double-Precision XX2-form (xssqrtdp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSSQRTSP, 0xfc0007fc, 0xf000002c, 0x1f0000, // VSX Scalar Square Root Single-Precision XX-form (xssqrtsp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XSSUBDP, 0xfc0007f8, 0xf0000140, 0x0, // VSX Scalar Subtract Double-Precision XX3-form (xssubdp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSSUBSP, 0xfc0007f8, 0xf0000040, 0x0, // VSX Scalar Subtract Single-Precision XX3-form (xssubsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSTDIVDP, 0xfc0007f8, 0xf00001e8, 0x600001, // VSX Scalar Test for software Divide Double-Precision XX3-form (xstdivdp BF,XA,XB)
-		[5]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XSTSQRTDP, 0xfc0007fc, 0xf00001a8, 0x7f0001, // VSX Scalar Test for software Square Root Double-Precision XX2-form (xstsqrtdp BF,XB)
-		[5]*argField{ap_CondRegField_6_8, ap_VecSReg_30_30_16_20}},
-	{XVABSDP, 0xfc0007fc, 0xf0000764, 0x1f0000, // VSX Vector Absolute Value Double-Precision XX2-form (xvabsdp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVABSSP, 0xfc0007fc, 0xf0000664, 0x1f0000, // VSX Vector Absolute Value Single-Precision XX2-form (xvabssp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVADDDP, 0xfc0007f8, 0xf0000300, 0x0, // VSX Vector Add Double-Precision XX3-form (xvadddp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVADDSP, 0xfc0007f8, 0xf0000200, 0x0, // VSX Vector Add Single-Precision XX3-form (xvaddsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCMPEQDP, 0xfc0007f8, 0xf0000318, 0x0, // VSX Vector Compare Equal To Double-Precision [ & Record ] XX3-form (xvcmpeqdp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCMPEQDPCC, 0xfc0007f8, 0xf0000718, 0x0, // VSX Vector Compare Equal To Double-Precision [ & Record ] XX3-form (xvcmpeqdp. XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCMPEQSP, 0xfc0007f8, 0xf0000218, 0x0, // VSX Vector Compare Equal To Single-Precision [ & Record ] XX3-form (xvcmpeqsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCMPEQSPCC, 0xfc0007f8, 0xf0000618, 0x0, // VSX Vector Compare Equal To Single-Precision [ & Record ] XX3-form (xvcmpeqsp. XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCMPGEDP, 0xfc0007f8, 0xf0000398, 0x0, // VSX Vector Compare Greater Than or Equal To Double-Precision [ & Record ] XX3-form (xvcmpgedp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCMPGEDPCC, 0xfc0007f8, 0xf0000798, 0x0, // VSX Vector Compare Greater Than or Equal To Double-Precision [ & Record ] XX3-form (xvcmpgedp. XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCMPGESP, 0xfc0007f8, 0xf0000298, 0x0, // VSX Vector Compare Greater Than or Equal To Single-Precision [ & record CR6 ] XX3-form (xvcmpgesp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCMPGESPCC, 0xfc0007f8, 0xf0000698, 0x0, // VSX Vector Compare Greater Than or Equal To Single-Precision [ & record CR6 ] XX3-form (xvcmpgesp. XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCMPGTDP, 0xfc0007f8, 0xf0000358, 0x0, // VSX Vector Compare Greater Than Double-Precision [ & record CR6 ] XX3-form (xvcmpgtdp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCMPGTDPCC, 0xfc0007f8, 0xf0000758, 0x0, // VSX Vector Compare Greater Than Double-Precision [ & record CR6 ] XX3-form (xvcmpgtdp. XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCMPGTSP, 0xfc0007f8, 0xf0000258, 0x0, // VSX Vector Compare Greater Than Single-Precision [ & record CR6 ] XX3-form (xvcmpgtsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCMPGTSPCC, 0xfc0007f8, 0xf0000658, 0x0, // VSX Vector Compare Greater Than Single-Precision [ & record CR6 ] XX3-form (xvcmpgtsp. XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCPSGNDP, 0xfc0007f8, 0xf0000780, 0x0, // VSX Vector Copy Sign Double-Precision XX3-form (xvcpsgndp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCPSGNSP, 0xfc0007f8, 0xf0000680, 0x0, // VSX Vector Copy Sign Single-Precision XX3-form (xvcpsgnsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCVDPSP, 0xfc0007fc, 0xf0000624, 0x1f0000, // VSX Vector round Double-Precision to single-precision and Convert to Single-Precision format XX2-form (xvcvdpsp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVDPSXDS, 0xfc0007fc, 0xf0000760, 0x1f0000, // VSX Vector truncate Double-Precision to integer and Convert to Signed Integer Doubleword format with Saturate XX2-form (xvcvdpsxds XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVDPSXWS, 0xfc0007fc, 0xf0000360, 0x1f0000, // VSX Vector truncate Double-Precision to integer and Convert to Signed Integer Word format with Saturate XX2-form (xvcvdpsxws XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVDPUXDS, 0xfc0007fc, 0xf0000720, 0x1f0000, // VSX Vector truncate Double-Precision to integer and Convert to Unsigned Integer Doubleword format with Saturate XX2-form (xvcvdpuxds XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVDPUXWS, 0xfc0007fc, 0xf0000320, 0x1f0000, // VSX Vector truncate Double-Precision to integer and Convert to Unsigned Integer Word format with Saturate XX2-form (xvcvdpuxws XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVSPDP, 0xfc0007fc, 0xf0000724, 0x1f0000, // VSX Vector Convert Single-Precision to Double-Precision format XX2-form (xvcvspdp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVSPSXDS, 0xfc0007fc, 0xf0000660, 0x1f0000, // VSX Vector truncate Single-Precision to integer and Convert to Signed Integer Doubleword format with Saturate XX2-form (xvcvspsxds XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVSPSXWS, 0xfc0007fc, 0xf0000260, 0x1f0000, // VSX Vector truncate Single-Precision to integer and Convert to Signed Integer Word format with Saturate XX2-form (xvcvspsxws XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVSPUXDS, 0xfc0007fc, 0xf0000620, 0x1f0000, // VSX Vector truncate Single-Precision to integer and Convert to Unsigned Integer Doubleword format with Saturate XX2-form (xvcvspuxds XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVSPUXWS, 0xfc0007fc, 0xf0000220, 0x1f0000, // VSX Vector truncate Single-Precision to integer and Convert to Unsigned Integer Word format with Saturate XX2-form (xvcvspuxws XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVSXDDP, 0xfc0007fc, 0xf00007e0, 0x1f0000, // VSX Vector Convert and round Signed Integer Doubleword to Double-Precision format XX2-form (xvcvsxddp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVSXDSP, 0xfc0007fc, 0xf00006e0, 0x1f0000, // VSX Vector Convert and round Signed Integer Doubleword to Single-Precision format XX2-form (xvcvsxdsp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVSXWDP, 0xfc0007fc, 0xf00003e0, 0x1f0000, // VSX Vector Convert Signed Integer Word to Double-Precision format XX2-form (xvcvsxwdp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVSXWSP, 0xfc0007fc, 0xf00002e0, 0x1f0000, // VSX Vector Convert and round Signed Integer Word to Single-Precision format XX2-form (xvcvsxwsp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVUXDDP, 0xfc0007fc, 0xf00007a0, 0x1f0000, // VSX Vector Convert and round Unsigned Integer Doubleword to Double-Precision format XX2-form (xvcvuxddp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVUXDSP, 0xfc0007fc, 0xf00006a0, 0x1f0000, // VSX Vector Convert and round Unsigned Integer Doubleword to Single-Precision format XX2-form (xvcvuxdsp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVUXWDP, 0xfc0007fc, 0xf00003a0, 0x1f0000, // VSX Vector Convert and round Unsigned Integer Word to Double-Precision format XX2-form (xvcvuxwdp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVCVUXWSP, 0xfc0007fc, 0xf00002a0, 0x1f0000, // VSX Vector Convert and round Unsigned Integer Word to Single-Precision format XX2-form (xvcvuxwsp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVDIVDP, 0xfc0007f8, 0xf00003c0, 0x0, // VSX Vector Divide Double-Precision XX3-form (xvdivdp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVDIVSP, 0xfc0007f8, 0xf00002c0, 0x0, // VSX Vector Divide Single-Precision XX3-form (xvdivsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVMADDADP, 0xfc0007f8, 0xf0000308, 0x0, // VSX Vector Multiply-Add Double-Precision XX3-form (xvmaddadp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVMADDASP, 0xfc0007f8, 0xf0000208, 0x0, // VSX Vector Multiply-Add Single-Precision XX3-form (xvmaddasp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVMAXDP, 0xfc0007f8, 0xf0000700, 0x0, // VSX Vector Maximum Double-Precision XX3-form (xvmaxdp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVMAXSP, 0xfc0007f8, 0xf0000600, 0x0, // VSX Vector Maximum Single-Precision XX3-form (xvmaxsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVMINDP, 0xfc0007f8, 0xf0000740, 0x0, // VSX Vector Minimum Double-Precision XX3-form (xvmindp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVMINSP, 0xfc0007f8, 0xf0000640, 0x0, // VSX Vector Minimum Single-Precision XX3-form (xvminsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVMSUBADP, 0xfc0007f8, 0xf0000388, 0x0, // VSX Vector Multiply-Subtract Double-Precision XX3-form (xvmsubadp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVMSUBASP, 0xfc0007f8, 0xf0000288, 0x0, // VSX Vector Multiply-Subtract Single-Precision XX3-form (xvmsubasp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVMULDP, 0xfc0007f8, 0xf0000380, 0x0, // VSX Vector Multiply Double-Precision XX3-form (xvmuldp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVMULSP, 0xfc0007f8, 0xf0000280, 0x0, // VSX Vector Multiply Single-Precision XX3-form (xvmulsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVNABSDP, 0xfc0007fc, 0xf00007a4, 0x1f0000, // VSX Vector Negative Absolute Value Double-Precision XX2-form (xvnabsdp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVNABSSP, 0xfc0007fc, 0xf00006a4, 0x1f0000, // VSX Vector Negative Absolute Value Single-Precision XX2-form (xvnabssp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVNEGDP, 0xfc0007fc, 0xf00007e4, 0x1f0000, // VSX Vector Negate Double-Precision XX2-form (xvnegdp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVNEGSP, 0xfc0007fc, 0xf00006e4, 0x1f0000, // VSX Vector Negate Single-Precision XX2-form (xvnegsp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVNMADDADP, 0xfc0007f8, 0xf0000708, 0x0, // VSX Vector Negative Multiply-Add Double-Precision XX3-form (xvnmaddadp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVNMADDASP, 0xfc0007f8, 0xf0000608, 0x0, // VSX Vector Negative Multiply-Add Single-Precision XX3-form (xvnmaddasp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVNMSUBADP, 0xfc0007f8, 0xf0000788, 0x0, // VSX Vector Negative Multiply-Subtract Double-Precision XX3-form (xvnmsubadp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVNMSUBASP, 0xfc0007f8, 0xf0000688, 0x0, // VSX Vector Negative Multiply-Subtract Single-Precision XX3-form (xvnmsubasp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVRDPI, 0xfc0007fc, 0xf0000324, 0x1f0000, // VSX Vector Round to Double-Precision Integer using round to Nearest Away XX2-form (xvrdpi XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVRDPIC, 0xfc0007fc, 0xf00003ac, 0x1f0000, // VSX Vector Round to Double-Precision Integer Exact using Current rounding mode XX2-form (xvrdpic XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVRDPIM, 0xfc0007fc, 0xf00003e4, 0x1f0000, // VSX Vector Round to Double-Precision Integer using round toward -Infinity XX2-form (xvrdpim XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVRDPIP, 0xfc0007fc, 0xf00003a4, 0x1f0000, // VSX Vector Round to Double-Precision Integer using round toward +Infinity XX2-form (xvrdpip XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVRDPIZ, 0xfc0007fc, 0xf0000364, 0x1f0000, // VSX Vector Round to Double-Precision Integer using round toward Zero XX2-form (xvrdpiz XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVREDP, 0xfc0007fc, 0xf0000368, 0x1f0000, // VSX Vector Reciprocal Estimate Double-Precision XX2-form (xvredp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVRESP, 0xfc0007fc, 0xf0000268, 0x1f0000, // VSX Vector Reciprocal Estimate Single-Precision XX2-form (xvresp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVRSPI, 0xfc0007fc, 0xf0000224, 0x1f0000, // VSX Vector Round to Single-Precision Integer using round to Nearest Away XX2-form (xvrspi XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVRSPIC, 0xfc0007fc, 0xf00002ac, 0x1f0000, // VSX Vector Round to Single-Precision Integer Exact using Current rounding mode XX2-form (xvrspic XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVRSPIM, 0xfc0007fc, 0xf00002e4, 0x1f0000, // VSX Vector Round to Single-Precision Integer using round toward -Infinity XX2-form (xvrspim XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVRSPIP, 0xfc0007fc, 0xf00002a4, 0x1f0000, // VSX Vector Round to Single-Precision Integer using round toward +Infinity XX2-form (xvrspip XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVRSPIZ, 0xfc0007fc, 0xf0000264, 0x1f0000, // VSX Vector Round to Single-Precision Integer using round toward Zero XX2-form (xvrspiz XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVRSQRTEDP, 0xfc0007fc, 0xf0000328, 0x1f0000, // VSX Vector Reciprocal Square Root Estimate Double-Precision XX2-form (xvrsqrtedp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVRSQRTESP, 0xfc0007fc, 0xf0000228, 0x1f0000, // VSX Vector Reciprocal Square Root Estimate Single-Precision XX2-form (xvrsqrtesp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVSQRTDP, 0xfc0007fc, 0xf000032c, 0x1f0000, // VSX Vector Square Root Double-Precision XX2-form (xvsqrtdp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVSQRTSP, 0xfc0007fc, 0xf000022c, 0x1f0000, // VSX Vector Square Root Single-Precision XX2-form (xvsqrtsp XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XVSUBDP, 0xfc0007f8, 0xf0000340, 0x0, // VSX Vector Subtract Double-Precision XX3-form (xvsubdp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVSUBSP, 0xfc0007f8, 0xf0000240, 0x0, // VSX Vector Subtract Single-Precision XX3-form (xvsubsp XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVTDIVDP, 0xfc0007f8, 0xf00003e8, 0x600001, // VSX Vector Test for software Divide Double-Precision XX3-form (xvtdivdp BF,XA,XB)
-		[5]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVTDIVSP, 0xfc0007f8, 0xf00002e8, 0x600001, // VSX Vector Test for software Divide Single-Precision XX3-form (xvtdivsp BF,XA,XB)
-		[5]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVTSQRTDP, 0xfc0007fc, 0xf00003a8, 0x7f0001, // VSX Vector Test for software Square Root Double-Precision XX2-form (xvtsqrtdp BF,XB)
-		[5]*argField{ap_CondRegField_6_8, ap_VecSReg_30_30_16_20}},
-	{XVTSQRTSP, 0xfc0007fc, 0xf00002a8, 0x7f0001, // VSX Vector Test for software Square Root Single-Precision XX2-form (xvtsqrtsp BF,XB)
-		[5]*argField{ap_CondRegField_6_8, ap_VecSReg_30_30_16_20}},
-	{XXLAND, 0xfc0007f8, 0xf0000410, 0x0, // VSX Logical AND XX3-form (xxland XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XXLANDC, 0xfc0007f8, 0xf0000450, 0x0, // VSX Logical AND with Complement XX3-form (xxlandc XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XXLEQV, 0xfc0007f8, 0xf00005d0, 0x0, // VSX Logical Equivalence XX3-form (xxleqv XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XXLNAND, 0xfc0007f8, 0xf0000590, 0x0, // VSX Logical NAND XX3-form (xxlnand XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XXLORC, 0xfc0007f8, 0xf0000550, 0x0, // VSX Logical OR with Complement XX3-form (xxlorc XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XXLNOR, 0xfc0007f8, 0xf0000510, 0x0, // VSX Logical NOR XX3-form (xxlnor XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XXLOR, 0xfc0007f8, 0xf0000490, 0x0, // VSX Logical OR XX3-form (xxlor XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XXLXOR, 0xfc0007f8, 0xf00004d0, 0x0, // VSX Logical XOR XX3-form (xxlxor XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XXMRGHW, 0xfc0007f8, 0xf0000090, 0x0, // VSX Merge High Word XX3-form (xxmrghw XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XXMRGLW, 0xfc0007f8, 0xf0000190, 0x0, // VSX Merge Low Word XX3-form (xxmrglw XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XXPERMDI, 0xfc0004f8, 0xf0000050, 0x0, // VSX Permute Doubleword Immediate XX3-form (xxpermdi XT,XA,XB,DM)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_22_23}},
-	{XXPERM, 0xfc0007f8, 0xf00000d0, 0x0, // VSX Permute XX3-form (xxperm XT,XA,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XXSEL, 0xfc000030, 0xf0000030, 0x0, // VSX Select XX4-form (xxsel XT,XA,XB,XC)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20, ap_VecSReg_28_28_21_25}},
-	{XXSLDWI, 0xfc0004f8, 0xf0000010, 0x0, // VSX Shift Left Double by Word Immediate XX3-form (xxsldwi XT,XA,XB,SHW)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_22_23}},
-	{XXSPLTW, 0xfc0007fc, 0xf0000290, 0x1c0000, // VSX Splat Word XX2-form (xxspltw XT,XB,UIM)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_14_15}},
-	{XXBRD, 0xfc1f07fc, 0xf017076c, 0x0, // VSX Vector Byte-Reverse Doubleword XX2-form (xxbrd XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XXBRW, 0xfc1f07fc, 0xf00f076c, 0x0, // VSX Vector Byte-Reverse Word XX2-form (xxbrw XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{XXBRH, 0xfc1f07fc, 0xf007076c, 0x0, // VSX Vector Byte-Reverse Halfword XX2-form (xxbrh XT,XB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
-	{BRINC, 0xfc0007ff, 0x1000020f, 0x0, // Bit Reversed Increment EVX-form (brinc RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVABS, 0xfc0007ff, 0x10000208, 0xf800, // Vector Absolute Value EVX-form (evabs RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVADDIW, 0xfc0007ff, 0x10000202, 0x0, // Vector Add Immediate Word EVX-form (evaddiw RT,RB,UI)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_11_15}},
-	{EVADDSMIAAW, 0xfc0007ff, 0x100004c9, 0xf800, // Vector Add Signed, Modulo, Integer to Accumulator Word EVX-form (evaddsmiaaw RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVADDSSIAAW, 0xfc0007ff, 0x100004c1, 0xf800, // Vector Add Signed, Saturate, Integer to Accumulator Word EVX-form (evaddssiaaw RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVADDUMIAAW, 0xfc0007ff, 0x100004c8, 0xf800, // Vector Add Unsigned, Modulo, Integer to Accumulator Word EVX-form (evaddumiaaw RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVADDUSIAAW, 0xfc0007ff, 0x100004c0, 0xf800, // Vector Add Unsigned, Saturate, Integer to Accumulator Word EVX-form (evaddusiaaw RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVADDW, 0xfc0007ff, 0x10000200, 0x0, // Vector Add Word EVX-form (evaddw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVAND, 0xfc0007ff, 0x10000211, 0x0, // Vector AND EVX-form (evand RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVCMPEQ, 0xfc0007ff, 0x10000234, 0x600000, // Vector Compare Equal EVX-form (evcmpeq BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVANDC, 0xfc0007ff, 0x10000212, 0x0, // Vector AND with Complement EVX-form (evandc RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVCMPGTS, 0xfc0007ff, 0x10000231, 0x600000, // Vector Compare Greater Than Signed EVX-form (evcmpgts BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVCMPGTU, 0xfc0007ff, 0x10000230, 0x600000, // Vector Compare Greater Than Unsigned EVX-form (evcmpgtu BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVCMPLTU, 0xfc0007ff, 0x10000232, 0x600000, // Vector Compare Less Than Unsigned EVX-form (evcmpltu BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVCMPLTS, 0xfc0007ff, 0x10000233, 0x600000, // Vector Compare Less Than Signed EVX-form (evcmplts BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVCNTLSW, 0xfc0007ff, 0x1000020e, 0xf800, // Vector Count Leading Signed Bits Word EVX-form (evcntlsw RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVCNTLZW, 0xfc0007ff, 0x1000020d, 0xf800, // Vector Count Leading Zeros Word EVX-form (evcntlzw RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVDIVWS, 0xfc0007ff, 0x100004c6, 0x0, // Vector Divide Word Signed EVX-form (evdivws RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVDIVWU, 0xfc0007ff, 0x100004c7, 0x0, // Vector Divide Word Unsigned EVX-form (evdivwu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVEQV, 0xfc0007ff, 0x10000219, 0x0, // Vector Equivalent EVX-form (eveqv RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVEXTSB, 0xfc0007ff, 0x1000020a, 0xf800, // Vector Extend Sign Byte EVX-form (evextsb RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVEXTSH, 0xfc0007ff, 0x1000020b, 0xf800, // Vector Extend Sign Halfword EVX-form (evextsh RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVLDD, 0xfc0007ff, 0x10000301, 0x0, // Vector Load Double Word into Double Word EVX-form (evldd RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVLDH, 0xfc0007ff, 0x10000305, 0x0, // Vector Load Double into Four Halfwords EVX-form (evldh RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVLDDX, 0xfc0007ff, 0x10000300, 0x0, // Vector Load Double Word into Double Word Indexed EVX-form (evlddx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVLDHX, 0xfc0007ff, 0x10000304, 0x0, // Vector Load Double into Four Halfwords Indexed EVX-form (evldhx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVLDW, 0xfc0007ff, 0x10000303, 0x0, // Vector Load Double into Two Words EVX-form (evldw RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVLHHESPLAT, 0xfc0007ff, 0x10000309, 0x0, // Vector Load Halfword into Halfwords Even and Splat EVX-form (evlhhesplat RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVLDWX, 0xfc0007ff, 0x10000302, 0x0, // Vector Load Double into Two Words Indexed EVX-form (evldwx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVLHHESPLATX, 0xfc0007ff, 0x10000308, 0x0, // Vector Load Halfword into Halfwords Even and Splat Indexed EVX-form (evlhhesplatx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVLHHOSSPLAT, 0xfc0007ff, 0x1000030f, 0x0, // Vector Load Halfword into Halfword Odd Signed and Splat EVX-form (evlhhossplat RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVLHHOUSPLAT, 0xfc0007ff, 0x1000030d, 0x0, // Vector Load Halfword into Halfword Odd Unsigned and Splat EVX-form (evlhhousplat RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVLHHOSSPLATX, 0xfc0007ff, 0x1000030e, 0x0, // Vector Load Halfword into Halfword Odd Signed and Splat Indexed EVX-form (evlhhossplatx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVLHHOUSPLATX, 0xfc0007ff, 0x1000030c, 0x0, // Vector Load Halfword into Halfword Odd Unsigned and Splat Indexed EVX-form (evlhhousplatx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVLWHE, 0xfc0007ff, 0x10000311, 0x0, // Vector Load Word into Two Halfwords Even EVX-form (evlwhe RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVLWHOS, 0xfc0007ff, 0x10000317, 0x0, // Vector Load Word into Two Halfwords Odd Signed (with sign extension) EVX-form (evlwhos RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVLWHEX, 0xfc0007ff, 0x10000310, 0x0, // Vector Load Word into Two Halfwords Even Indexed EVX-form (evlwhex RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVLWHOSX, 0xfc0007ff, 0x10000316, 0x0, // Vector Load Word into Two Halfwords Odd Signed Indexed (with sign extension) EVX-form (evlwhosx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVLWHOU, 0xfc0007ff, 0x10000315, 0x0, // Vector Load Word into Two Halfwords Odd Unsigned (zero-extended) EVX-form (evlwhou RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVLWHSPLAT, 0xfc0007ff, 0x1000031d, 0x0, // Vector Load Word into Two Halfwords and Splat EVX-form (evlwhsplat RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVLWHOUX, 0xfc0007ff, 0x10000314, 0x0, // Vector Load Word into Two Halfwords Odd Unsigned Indexed (zero-extended) EVX-form (evlwhoux RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVLWHSPLATX, 0xfc0007ff, 0x1000031c, 0x0, // Vector Load Word into Two Halfwords and Splat Indexed EVX-form (evlwhsplatx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVLWWSPLAT, 0xfc0007ff, 0x10000319, 0x0, // Vector Load Word into Word and Splat EVX-form (evlwwsplat RT,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVMERGEHI, 0xfc0007ff, 0x1000022c, 0x0, // Vector Merge High EVX-form (evmergehi RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVLWWSPLATX, 0xfc0007ff, 0x10000318, 0x0, // Vector Load Word into Word and Splat Indexed EVX-form (evlwwsplatx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMERGELO, 0xfc0007ff, 0x1000022d, 0x0, // Vector Merge Low EVX-form (evmergelo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMERGEHILO, 0xfc0007ff, 0x1000022e, 0x0, // Vector Merge High/Low EVX-form (evmergehilo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHEGSMFAA, 0xfc0007ff, 0x1000052b, 0x0, // Vector Multiply Halfwords, Even, Guarded, Signed, Modulo, Fractional and Accumulate EVX-form (evmhegsmfaa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMERGELOHI, 0xfc0007ff, 0x1000022f, 0x0, // Vector Merge Low/High EVX-form (evmergelohi RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHEGSMFAN, 0xfc0007ff, 0x100005ab, 0x0, // Vector Multiply Halfwords, Even, Guarded, Signed, Modulo, Fractional and Accumulate Negative EVX-form (evmhegsmfan RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHEGSMIAA, 0xfc0007ff, 0x10000529, 0x0, // Vector Multiply Halfwords, Even, Guarded, Signed, Modulo, Integer and Accumulate EVX-form (evmhegsmiaa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHEGUMIAA, 0xfc0007ff, 0x10000528, 0x0, // Vector Multiply Halfwords, Even, Guarded, Unsigned, Modulo, Integer and Accumulate EVX-form (evmhegumiaa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHEGSMIAN, 0xfc0007ff, 0x100005a9, 0x0, // Vector Multiply Halfwords, Even, Guarded, Signed, Modulo, Integer and Accumulate Negative EVX-form (evmhegsmian RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHEGUMIAN, 0xfc0007ff, 0x100005a8, 0x0, // Vector Multiply Halfwords, Even, Guarded, Unsigned, Modulo, Integer and Accumulate Negative EVX-form (evmhegumian RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESMF, 0xfc0007ff, 0x1000040b, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Fractional EVX-form (evmhesmf RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESMFAAW, 0xfc0007ff, 0x1000050b, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Fractional and Accumulate into Words EVX-form (evmhesmfaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESMFA, 0xfc0007ff, 0x1000042b, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Fractional to Accumulator EVX-form (evmhesmfa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESMFANW, 0xfc0007ff, 0x1000058b, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Fractional and Accumulate Negative into Words EVX-form (evmhesmfanw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESMI, 0xfc0007ff, 0x10000409, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Integer EVX-form (evmhesmi RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESMIAAW, 0xfc0007ff, 0x10000509, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Integer and Accumulate into Words EVX-form (evmhesmiaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESMIA, 0xfc0007ff, 0x10000429, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Integer to Accumulator EVX-form (evmhesmia RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESMIANW, 0xfc0007ff, 0x10000589, 0x0, // Vector Multiply Halfwords, Even, Signed, Modulo, Integer and Accumulate Negative into Words EVX-form (evmhesmianw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESSF, 0xfc0007ff, 0x10000403, 0x0, // Vector Multiply Halfwords, Even, Signed, Saturate, Fractional EVX-form (evmhessf RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESSFA, 0xfc0007ff, 0x10000423, 0x0, // Vector Multiply Halfwords, Even, Signed, Saturate, Fractional to Accumulator EVX-form (evmhessfa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESSFAAW, 0xfc0007ff, 0x10000503, 0x0, // Vector Multiply Halfwords, Even, Signed, Saturate, Fractional and Accumulate into Words EVX-form (evmhessfaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESSFANW, 0xfc0007ff, 0x10000583, 0x0, // Vector Multiply Halfwords, Even, Signed, Saturate, Fractional and Accumulate Negative into Words EVX-form (evmhessfanw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESSIAAW, 0xfc0007ff, 0x10000501, 0x0, // Vector Multiply Halfwords, Even, Signed, Saturate, Integer and Accumulate into Words EVX-form (evmhessiaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHESSIANW, 0xfc0007ff, 0x10000581, 0x0, // Vector Multiply Halfwords, Even, Signed, Saturate, Integer and Accumulate Negative into Words EVX-form (evmhessianw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHEUMI, 0xfc0007ff, 0x10000408, 0x0, // Vector Multiply Halfwords, Even, Unsigned, Modulo, Integer EVX-form (evmheumi RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHEUMIAAW, 0xfc0007ff, 0x10000508, 0x0, // Vector Multiply Halfwords, Even, Unsigned, Modulo, Integer and Accumulate into Words EVX-form (evmheumiaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHEUMIA, 0xfc0007ff, 0x10000428, 0x0, // Vector Multiply Halfwords, Even, Unsigned, Modulo, Integer to Accumulator EVX-form (evmheumia RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHEUMIANW, 0xfc0007ff, 0x10000588, 0x0, // Vector Multiply Halfwords, Even, Unsigned, Modulo, Integer and Accumulate Negative into Words EVX-form (evmheumianw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHEUSIAAW, 0xfc0007ff, 0x10000500, 0x0, // Vector Multiply Halfwords, Even, Unsigned, Saturate, Integer and Accumulate into Words EVX-form (evmheusiaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHEUSIANW, 0xfc0007ff, 0x10000580, 0x0, // Vector Multiply Halfwords, Even, Unsigned, Saturate, Integer and Accumulate Negative into Words EVX-form (evmheusianw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOGSMFAA, 0xfc0007ff, 0x1000052f, 0x0, // Vector Multiply Halfwords, Odd, Guarded, Signed, Modulo, Fractional and Accumulate EVX-form (evmhogsmfaa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOGSMIAA, 0xfc0007ff, 0x1000052d, 0x0, // Vector Multiply Halfwords, Odd, Guarded, Signed, Modulo, Integer and Accumulate EVX-form (evmhogsmiaa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOGSMFAN, 0xfc0007ff, 0x100005af, 0x0, // Vector Multiply Halfwords, Odd, Guarded, Signed, Modulo, Fractional and Accumulate Negative EVX-form (evmhogsmfan RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOGSMIAN, 0xfc0007ff, 0x100005ad, 0x0, // Vector Multiply Halfwords, Odd, Guarded, Signed, Modulo, Integer and Accumulate Negative EVX-form (evmhogsmian RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOGUMIAA, 0xfc0007ff, 0x1000052c, 0x0, // Vector Multiply Halfwords, Odd, Guarded, Unsigned, Modulo, Integer and Accumulate EVX-form (evmhogumiaa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSMF, 0xfc0007ff, 0x1000040f, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Fractional EVX-form (evmhosmf RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOGUMIAN, 0xfc0007ff, 0x100005ac, 0x0, // Vector Multiply Halfwords, Odd, Guarded, Unsigned, Modulo, Integer and Accumulate Negative EVX-form (evmhogumian RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSMFA, 0xfc0007ff, 0x1000042f, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Fractional to Accumulator EVX-form (evmhosmfa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSMFAAW, 0xfc0007ff, 0x1000050f, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Fractional and Accumulate into Words EVX-form (evmhosmfaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSMI, 0xfc0007ff, 0x1000040d, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Integer EVX-form (evmhosmi RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSMFANW, 0xfc0007ff, 0x1000058f, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Fractional and Accumulate Negative into Words EVX-form (evmhosmfanw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSMIA, 0xfc0007ff, 0x1000042d, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Integer to Accumulator EVX-form (evmhosmia RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSMIAAW, 0xfc0007ff, 0x1000050d, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Integer and Accumulate into Words EVX-form (evmhosmiaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSMIANW, 0xfc0007ff, 0x1000058d, 0x0, // Vector Multiply Halfwords, Odd, Signed, Modulo, Integer and Accumulate Negative into Words EVX-form (evmhosmianw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSSF, 0xfc0007ff, 0x10000407, 0x0, // Vector Multiply Halfwords, Odd, Signed, Saturate, Fractional EVX-form (evmhossf RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSSFA, 0xfc0007ff, 0x10000427, 0x0, // Vector Multiply Halfwords, Odd, Signed, Saturate, Fractional to Accumulator EVX-form (evmhossfa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSSFAAW, 0xfc0007ff, 0x10000507, 0x0, // Vector Multiply Halfwords, Odd, Signed, Saturate, Fractional and Accumulate into Words EVX-form (evmhossfaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSSFANW, 0xfc0007ff, 0x10000587, 0x0, // Vector Multiply Halfwords, Odd, Signed, Saturate, Fractional and Accumulate Negative into Words EVX-form (evmhossfanw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSSIAAW, 0xfc0007ff, 0x10000505, 0x0, // Vector Multiply Halfwords, Odd, Signed, Saturate, Integer and Accumulate into Words EVX-form (evmhossiaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOUMI, 0xfc0007ff, 0x1000040c, 0x0, // Vector Multiply Halfwords, Odd, Unsigned, Modulo, Integer EVX-form (evmhoumi RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOSSIANW, 0xfc0007ff, 0x10000585, 0x0, // Vector Multiply Halfwords, Odd, Signed, Saturate, Integer and Accumulate Negative into Words EVX-form (evmhossianw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOUMIA, 0xfc0007ff, 0x1000042c, 0x0, // Vector Multiply Halfwords, Odd, Unsigned, Modulo, Integer to Accumulator EVX-form (evmhoumia RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOUMIAAW, 0xfc0007ff, 0x1000050c, 0x0, // Vector Multiply Halfwords, Odd, Unsigned, Modulo, Integer and Accumulate into Words EVX-form (evmhoumiaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOUSIAAW, 0xfc0007ff, 0x10000504, 0x0, // Vector Multiply Halfwords, Odd, Unsigned, Saturate, Integer and Accumulate into Words EVX-form (evmhousiaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOUMIANW, 0xfc0007ff, 0x1000058c, 0x0, // Vector Multiply Halfwords, Odd, Unsigned, Modulo, Integer and Accumulate Negative into Words EVX-form (evmhoumianw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMHOUSIANW, 0xfc0007ff, 0x10000584, 0x0, // Vector Multiply Halfwords, Odd, Unsigned, Saturate, Integer and Accumulate Negative into Words EVX-form (evmhousianw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMRA, 0xfc0007ff, 0x100004c4, 0xf800, // Initialize Accumulator EVX-form (evmra RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVMWHSMF, 0xfc0007ff, 0x1000044f, 0x0, // Vector Multiply Word High Signed, Modulo, Fractional EVX-form (evmwhsmf RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWHSMI, 0xfc0007ff, 0x1000044d, 0x0, // Vector Multiply Word High Signed, Modulo, Integer EVX-form (evmwhsmi RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWHSMFA, 0xfc0007ff, 0x1000046f, 0x0, // Vector Multiply Word High Signed, Modulo, Fractional to Accumulator EVX-form (evmwhsmfa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWHSMIA, 0xfc0007ff, 0x1000046d, 0x0, // Vector Multiply Word High Signed, Modulo, Integer to Accumulator EVX-form (evmwhsmia RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWHSSF, 0xfc0007ff, 0x10000447, 0x0, // Vector Multiply Word High Signed, Saturate, Fractional EVX-form (evmwhssf RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWHUMI, 0xfc0007ff, 0x1000044c, 0x0, // Vector Multiply Word High Unsigned, Modulo, Integer EVX-form (evmwhumi RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWHSSFA, 0xfc0007ff, 0x10000467, 0x0, // Vector Multiply Word High Signed, Saturate, Fractional to Accumulator EVX-form (evmwhssfa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWHUMIA, 0xfc0007ff, 0x1000046c, 0x0, // Vector Multiply Word High Unsigned, Modulo, Integer to Accumulator EVX-form (evmwhumia RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWLSMIAAW, 0xfc0007ff, 0x10000549, 0x0, // Vector Multiply Word Low Signed, Modulo, Integer and Accumulate into Words EVX-form (evmwlsmiaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWLSSIAAW, 0xfc0007ff, 0x10000541, 0x0, // Vector Multiply Word Low Signed, Saturate, Integer and Accumulate into Words EVX-form (evmwlssiaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWLSMIANW, 0xfc0007ff, 0x100005c9, 0x0, // Vector Multiply Word Low Signed, Modulo, Integer and Accumulate Negative in Words EVX-form (evmwlsmianw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWLSSIANW, 0xfc0007ff, 0x100005c1, 0x0, // Vector Multiply Word Low Signed, Saturate, Integer and Accumulate Negative in Words EVX-form (evmwlssianw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWLUMI, 0xfc0007ff, 0x10000448, 0x0, // Vector Multiply Word Low Unsigned, Modulo, Integer EVX-form (evmwlumi RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWLUMIAAW, 0xfc0007ff, 0x10000548, 0x0, // Vector Multiply Word Low Unsigned, Modulo, Integer and Accumulate into Words EVX-form (evmwlumiaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWLUMIA, 0xfc0007ff, 0x10000468, 0x0, // Vector Multiply Word Low Unsigned, Modulo, Integer to Accumulator EVX-form (evmwlumia RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWLUMIANW, 0xfc0007ff, 0x100005c8, 0x0, // Vector Multiply Word Low Unsigned, Modulo, Integer and Accumulate Negative in Words EVX-form (evmwlumianw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWLUSIAAW, 0xfc0007ff, 0x10000540, 0x0, // Vector Multiply Word Low Unsigned, Saturate, Integer and Accumulate into Words EVX-form (evmwlusiaaw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWSMF, 0xfc0007ff, 0x1000045b, 0x0, // Vector Multiply Word Signed, Modulo, Fractional EVX-form (evmwsmf RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWLUSIANW, 0xfc0007ff, 0x100005c0, 0x0, // Vector Multiply Word Low Unsigned, Saturate, Integer and Accumulate Negative in Words EVX-form (evmwlusianw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWSMFA, 0xfc0007ff, 0x1000047b, 0x0, // Vector Multiply Word Signed, Modulo, Fractional to Accumulator EVX-form (evmwsmfa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWSMFAA, 0xfc0007ff, 0x1000055b, 0x0, // Vector Multiply Word Signed, Modulo, Fractional and Accumulate EVX-form (evmwsmfaa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWSMI, 0xfc0007ff, 0x10000459, 0x0, // Vector Multiply Word Signed, Modulo, Integer EVX-form (evmwsmi RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWSMIAA, 0xfc0007ff, 0x10000559, 0x0, // Vector Multiply Word Signed, Modulo, Integer and Accumulate EVX-form (evmwsmiaa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWSMFAN, 0xfc0007ff, 0x100005db, 0x0, // Vector Multiply Word Signed, Modulo, Fractional and Accumulate Negative EVX-form (evmwsmfan RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWSMIA, 0xfc0007ff, 0x10000479, 0x0, // Vector Multiply Word Signed, Modulo, Integer to Accumulator EVX-form (evmwsmia RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWSMIAN, 0xfc0007ff, 0x100005d9, 0x0, // Vector Multiply Word Signed, Modulo, Integer and Accumulate Negative EVX-form (evmwsmian RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWSSF, 0xfc0007ff, 0x10000453, 0x0, // Vector Multiply Word Signed, Saturate, Fractional EVX-form (evmwssf RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWSSFA, 0xfc0007ff, 0x10000473, 0x0, // Vector Multiply Word Signed, Saturate, Fractional to Accumulator EVX-form (evmwssfa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWSSFAA, 0xfc0007ff, 0x10000553, 0x0, // Vector Multiply Word Signed, Saturate, Fractional and Accumulate EVX-form (evmwssfaa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWUMI, 0xfc0007ff, 0x10000458, 0x0, // Vector Multiply Word Unsigned, Modulo, Integer EVX-form (evmwumi RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWSSFAN, 0xfc0007ff, 0x100005d3, 0x0, // Vector Multiply Word Signed, Saturate, Fractional and Accumulate Negative EVX-form (evmwssfan RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWUMIA, 0xfc0007ff, 0x10000478, 0x0, // Vector Multiply Word Unsigned, Modulo, Integer to Accumulator EVX-form (evmwumia RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWUMIAA, 0xfc0007ff, 0x10000558, 0x0, // Vector Multiply Word Unsigned, Modulo, Integer and Accumulate EVX-form (evmwumiaa RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVNAND, 0xfc0007ff, 0x1000021e, 0x0, // Vector NAND EVX-form (evnand RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVMWUMIAN, 0xfc0007ff, 0x100005d8, 0x0, // Vector Multiply Word Unsigned, Modulo, Integer and Accumulate Negative EVX-form (evmwumian RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVNEG, 0xfc0007ff, 0x10000209, 0xf800, // Vector Negate EVX-form (evneg RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVNOR, 0xfc0007ff, 0x10000218, 0x0, // Vector NOR EVX-form (evnor RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVORC, 0xfc0007ff, 0x1000021b, 0x0, // Vector OR with Complement EVX-form (evorc RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVOR, 0xfc0007ff, 0x10000217, 0x0, // Vector OR EVX-form (evor RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVRLW, 0xfc0007ff, 0x10000228, 0x0, // Vector Rotate Left Word EVX-form (evrlw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVRLWI, 0xfc0007ff, 0x1000022a, 0x0, // Vector Rotate Left Word Immediate EVX-form (evrlwi RT,RA,UI)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}},
-	{EVSEL, 0xfc0007f8, 0x10000278, 0x0, // Vector Select EVS-form (evsel RT,RA,RB,BFA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_CondRegField_29_31}},
-	{EVRNDW, 0xfc0007ff, 0x1000020c, 0xf800, // Vector Round Word EVX-form (evrndw RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVSLW, 0xfc0007ff, 0x10000224, 0x0, // Vector Shift Left Word EVX-form (evslw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVSPLATFI, 0xfc0007ff, 0x1000022b, 0xf800, // Vector Splat Fractional Immediate EVX-form (evsplatfi RT,SI)
-		[5]*argField{ap_Reg_6_10, ap_ImmSigned_11_15}},
-	{EVSRWIS, 0xfc0007ff, 0x10000223, 0x0, // Vector Shift Right Word Immediate Signed EVX-form (evsrwis RT,RA,UI)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}},
-	{EVSLWI, 0xfc0007ff, 0x10000226, 0x0, // Vector Shift Left Word Immediate EVX-form (evslwi RT,RA,UI)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}},
-	{EVSPLATI, 0xfc0007ff, 0x10000229, 0xf800, // Vector Splat Immediate EVX-form (evsplati RT,SI)
-		[5]*argField{ap_Reg_6_10, ap_ImmSigned_11_15}},
-	{EVSRWIU, 0xfc0007ff, 0x10000222, 0x0, // Vector Shift Right Word Immediate Unsigned EVX-form (evsrwiu RT,RA,UI)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}},
-	{EVSRWS, 0xfc0007ff, 0x10000221, 0x0, // Vector Shift Right Word Signed EVX-form (evsrws RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVSTDD, 0xfc0007ff, 0x10000321, 0x0, // Vector Store Double of Double EVX-form (evstdd RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVSRWU, 0xfc0007ff, 0x10000220, 0x0, // Vector Shift Right Word Unsigned EVX-form (evsrwu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVSTDDX, 0xfc0007ff, 0x10000320, 0x0, // Vector Store Double of Double Indexed EVX-form (evstddx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVSTDH, 0xfc0007ff, 0x10000325, 0x0, // Vector Store Double of Four Halfwords EVX-form (evstdh RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVSTDW, 0xfc0007ff, 0x10000323, 0x0, // Vector Store Double of Two Words EVX-form (evstdw RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVSTDHX, 0xfc0007ff, 0x10000324, 0x0, // Vector Store Double of Four Halfwords Indexed EVX-form (evstdhx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVSTDWX, 0xfc0007ff, 0x10000322, 0x0, // Vector Store Double of Two Words Indexed EVX-form (evstdwx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVSTWHE, 0xfc0007ff, 0x10000331, 0x0, // Vector Store Word of Two Halfwords from Even EVX-form (evstwhe RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVSTWHO, 0xfc0007ff, 0x10000335, 0x0, // Vector Store Word of Two Halfwords from Odd EVX-form (evstwho RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVSTWWE, 0xfc0007ff, 0x10000339, 0x0, // Vector Store Word of Word from Even EVX-form (evstwwe RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVSTWHEX, 0xfc0007ff, 0x10000330, 0x0, // Vector Store Word of Two Halfwords from Even Indexed EVX-form (evstwhex RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVSTWHOX, 0xfc0007ff, 0x10000334, 0x0, // Vector Store Word of Two Halfwords from Odd Indexed EVX-form (evstwhox RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVSTWWEX, 0xfc0007ff, 0x10000338, 0x0, // Vector Store Word of Word from Even Indexed EVX-form (evstwwex RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVSTWWO, 0xfc0007ff, 0x1000033d, 0x0, // Vector Store Word of Word from Odd EVX-form (evstwwo RS,D(RA))
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_Reg_11_15}},
-	{EVSUBFSMIAAW, 0xfc0007ff, 0x100004cb, 0xf800, // Vector Subtract Signed, Modulo, Integer to Accumulator Word EVX-form (evsubfsmiaaw RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVSTWWOX, 0xfc0007ff, 0x1000033c, 0x0, // Vector Store Word of Word from Odd Indexed EVX-form (evstwwox RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVSUBFSSIAAW, 0xfc0007ff, 0x100004c3, 0xf800, // Vector Subtract Signed, Saturate, Integer to Accumulator Word EVX-form (evsubfssiaaw RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVSUBFUMIAAW, 0xfc0007ff, 0x100004ca, 0xf800, // Vector Subtract Unsigned, Modulo, Integer to Accumulator Word EVX-form (evsubfumiaaw RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVSUBFUSIAAW, 0xfc0007ff, 0x100004c2, 0xf800, // Vector Subtract Unsigned, Saturate, Integer to Accumulator Word EVX-form (evsubfusiaaw RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVSUBFW, 0xfc0007ff, 0x10000204, 0x0, // Vector Subtract from Word EVX-form (evsubfw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVSUBIFW, 0xfc0007ff, 0x10000206, 0x0, // Vector Subtract Immediate from Word EVX-form (evsubifw RT,UI,RB)
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_11_15, ap_Reg_16_20}},
-	{EVXOR, 0xfc0007ff, 0x10000216, 0x0, // Vector XOR EVX-form (evxor RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVFSABS, 0xfc0007ff, 0x10000284, 0xf800, // Vector Floating-Point Single-Precision Absolute Value EVX-form (evfsabs RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVFSNABS, 0xfc0007ff, 0x10000285, 0xf800, // Vector Floating-Point Single-Precision Negative Absolute Value EVX-form (evfsnabs RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVFSNEG, 0xfc0007ff, 0x10000286, 0xf800, // Vector Floating-Point Single-Precision Negate EVX-form (evfsneg RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EVFSADD, 0xfc0007ff, 0x10000280, 0x0, // Vector Floating-Point Single-Precision Add EVX-form (evfsadd RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVFSMUL, 0xfc0007ff, 0x10000288, 0x0, // Vector Floating-Point Single-Precision Multiply EVX-form (evfsmul RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVFSSUB, 0xfc0007ff, 0x10000281, 0x0, // Vector Floating-Point Single-Precision Subtract EVX-form (evfssub RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVFSDIV, 0xfc0007ff, 0x10000289, 0x0, // Vector Floating-Point Single-Precision Divide EVX-form (evfsdiv RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVFSCMPGT, 0xfc0007ff, 0x1000028c, 0x600000, // Vector Floating-Point Single-Precision Compare Greater Than EVX-form (evfscmpgt BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVFSCMPLT, 0xfc0007ff, 0x1000028d, 0x600000, // Vector Floating-Point Single-Precision Compare Less Than EVX-form (evfscmplt BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVFSCMPEQ, 0xfc0007ff, 0x1000028e, 0x600000, // Vector Floating-Point Single-Precision Compare Equal EVX-form (evfscmpeq BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVFSTSTGT, 0xfc0007ff, 0x1000029c, 0x600000, // Vector Floating-Point Single-Precision Test Greater Than EVX-form (evfststgt BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVFSTSTLT, 0xfc0007ff, 0x1000029d, 0x600000, // Vector Floating-Point Single-Precision Test Less Than EVX-form (evfststlt BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVFSTSTEQ, 0xfc0007ff, 0x1000029e, 0x600000, // Vector Floating-Point Single-Precision Test Equal EVX-form (evfststeq BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVFSCFSI, 0xfc0007ff, 0x10000291, 0x1f0000, // Vector Convert Floating-Point Single-Precision from Signed Integer EVX-form (evfscfsi RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EVFSCFSF, 0xfc0007ff, 0x10000293, 0x1f0000, // Vector Convert Floating-Point Single-Precision from Signed Fraction EVX-form (evfscfsf RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EVFSCFUI, 0xfc0007ff, 0x10000290, 0x1f0000, // Vector Convert Floating-Point Single-Precision from Unsigned Integer EVX-form (evfscfui RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EVFSCFUF, 0xfc0007ff, 0x10000292, 0x1f0000, // Vector Convert Floating-Point Single-Precision from Unsigned Fraction EVX-form (evfscfuf RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EVFSCTSI, 0xfc0007ff, 0x10000295, 0x1f0000, // Vector Convert Floating-Point Single-Precision to Signed Integer EVX-form (evfsctsi RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EVFSCTUI, 0xfc0007ff, 0x10000294, 0x1f0000, // Vector Convert Floating-Point Single-Precision to Unsigned Integer EVX-form (evfsctui RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EVFSCTSIZ, 0xfc0007ff, 0x1000029a, 0x1f0000, // Vector Convert Floating-Point Single-Precision to Signed Integer with Round toward Zero EVX-form (evfsctsiz RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EVFSCTUIZ, 0xfc0007ff, 0x10000298, 0x1f0000, // Vector Convert Floating-Point Single-Precision to Unsigned Integer with Round toward Zero EVX-form (evfsctuiz RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EVFSCTSF, 0xfc0007ff, 0x10000297, 0x1f0000, // Vector Convert Floating-Point Single-Precision to Signed Fraction EVX-form (evfsctsf RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EVFSCTUF, 0xfc0007ff, 0x10000296, 0x1f0000, // Vector Convert Floating-Point Single-Precision to Unsigned Fraction EVX-form (evfsctuf RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFSABS, 0xfc0007ff, 0x100002c4, 0xf800, // Floating-Point Single-Precision Absolute Value EVX-form (efsabs RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EFSNEG, 0xfc0007ff, 0x100002c6, 0xf800, // Floating-Point Single-Precision Negate EVX-form (efsneg RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EFSNABS, 0xfc0007ff, 0x100002c5, 0xf800, // Floating-Point Single-Precision Negative Absolute Value EVX-form (efsnabs RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EFSADD, 0xfc0007ff, 0x100002c0, 0x0, // Floating-Point Single-Precision Add EVX-form (efsadd RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFSMUL, 0xfc0007ff, 0x100002c8, 0x0, // Floating-Point Single-Precision Multiply EVX-form (efsmul RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFSSUB, 0xfc0007ff, 0x100002c1, 0x0, // Floating-Point Single-Precision Subtract EVX-form (efssub RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFSDIV, 0xfc0007ff, 0x100002c9, 0x0, // Floating-Point Single-Precision Divide EVX-form (efsdiv RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFSCMPGT, 0xfc0007ff, 0x100002cc, 0x600000, // Floating-Point Single-Precision Compare Greater Than EVX-form (efscmpgt BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFSCMPLT, 0xfc0007ff, 0x100002cd, 0x600000, // Floating-Point Single-Precision Compare Less Than EVX-form (efscmplt BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFSCMPEQ, 0xfc0007ff, 0x100002ce, 0x600000, // Floating-Point Single-Precision Compare Equal EVX-form (efscmpeq BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFSTSTGT, 0xfc0007ff, 0x100002dc, 0x600000, // Floating-Point Single-Precision Test Greater Than EVX-form (efststgt BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFSTSTLT, 0xfc0007ff, 0x100002dd, 0x600000, // Floating-Point Single-Precision Test Less Than EVX-form (efststlt BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFSTSTEQ, 0xfc0007ff, 0x100002de, 0x600000, // Floating-Point Single-Precision Test Equal EVX-form (efststeq BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFSCFSI, 0xfc0007ff, 0x100002d1, 0x1f0000, // Convert Floating-Point Single-Precision from Signed Integer EVX-form (efscfsi RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFSCFSF, 0xfc0007ff, 0x100002d3, 0x1f0000, // Convert Floating-Point Single-Precision from Signed Fraction EVX-form (efscfsf RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFSCTSI, 0xfc0007ff, 0x100002d5, 0x1f0000, // Convert Floating-Point Single-Precision to Signed Integer EVX-form (efsctsi RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFSCFUI, 0xfc0007ff, 0x100002d0, 0x1f0000, // Convert Floating-Point Single-Precision from Unsigned Integer EVX-form (efscfui RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFSCFUF, 0xfc0007ff, 0x100002d2, 0x1f0000, // Convert Floating-Point Single-Precision from Unsigned Fraction EVX-form (efscfuf RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFSCTUI, 0xfc0007ff, 0x100002d4, 0x1f0000, // Convert Floating-Point Single-Precision to Unsigned Integer EVX-form (efsctui RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFSCTSIZ, 0xfc0007ff, 0x100002da, 0x1f0000, // Convert Floating-Point Single-Precision to Signed Integer with Round toward Zero EVX-form (efsctsiz RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFSCTSF, 0xfc0007ff, 0x100002d7, 0x1f0000, // Convert Floating-Point Single-Precision to Signed Fraction EVX-form (efsctsf RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFSCTUIZ, 0xfc0007ff, 0x100002d8, 0x1f0000, // Convert Floating-Point Single-Precision to Unsigned Integer with Round toward Zero EVX-form (efsctuiz RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFSCTUF, 0xfc0007ff, 0x100002d6, 0x1f0000, // Convert Floating-Point Single-Precision to Unsigned Fraction EVX-form (efsctuf RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDABS, 0xfc0007ff, 0x100002e4, 0xf800, // Floating-Point Double-Precision Absolute Value EVX-form (efdabs RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EFDNEG, 0xfc0007ff, 0x100002e6, 0xf800, // Floating-Point Double-Precision Negate EVX-form (efdneg RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EFDNABS, 0xfc0007ff, 0x100002e5, 0xf800, // Floating-Point Double-Precision Negative Absolute Value EVX-form (efdnabs RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{EFDADD, 0xfc0007ff, 0x100002e0, 0x0, // Floating-Point Double-Precision Add EVX-form (efdadd RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFDMUL, 0xfc0007ff, 0x100002e8, 0x0, // Floating-Point Double-Precision Multiply EVX-form (efdmul RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFDSUB, 0xfc0007ff, 0x100002e1, 0x0, // Floating-Point Double-Precision Subtract EVX-form (efdsub RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFDDIV, 0xfc0007ff, 0x100002e9, 0x0, // Floating-Point Double-Precision Divide EVX-form (efddiv RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFDCMPGT, 0xfc0007ff, 0x100002ec, 0x600000, // Floating-Point Double-Precision Compare Greater Than EVX-form (efdcmpgt BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFDCMPEQ, 0xfc0007ff, 0x100002ee, 0x600000, // Floating-Point Double-Precision Compare Equal EVX-form (efdcmpeq BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFDCMPLT, 0xfc0007ff, 0x100002ed, 0x600000, // Floating-Point Double-Precision Compare Less Than EVX-form (efdcmplt BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFDTSTGT, 0xfc0007ff, 0x100002fc, 0x600000, // Floating-Point Double-Precision Test Greater Than EVX-form (efdtstgt BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFDTSTLT, 0xfc0007ff, 0x100002fd, 0x600000, // Floating-Point Double-Precision Test Less Than EVX-form (efdtstlt BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFDCFSI, 0xfc0007ff, 0x100002f1, 0x1f0000, // Convert Floating-Point Double-Precision from Signed Integer EVX-form (efdcfsi RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDTSTEQ, 0xfc0007ff, 0x100002fe, 0x600000, // Floating-Point Double-Precision Test Equal EVX-form (efdtsteq BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{EFDCFUI, 0xfc0007ff, 0x100002f0, 0x1f0000, // Convert Floating-Point Double-Precision from Unsigned Integer EVX-form (efdcfui RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCFSID, 0xfc0007ff, 0x100002e3, 0x1f0000, // Convert Floating-Point Double-Precision from Signed Integer Doubleword EVX-form (efdcfsid RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCFSF, 0xfc0007ff, 0x100002f3, 0x1f0000, // Convert Floating-Point Double-Precision from Signed Fraction EVX-form (efdcfsf RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCFUF, 0xfc0007ff, 0x100002f2, 0x1f0000, // Convert Floating-Point Double-Precision from Unsigned Fraction EVX-form (efdcfuf RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCFUID, 0xfc0007ff, 0x100002e2, 0x1f0000, // Convert Floating-Point Double-Precision from Unsigned Integer Doubleword EVX-form (efdcfuid RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCTSI, 0xfc0007ff, 0x100002f5, 0x1f0000, // Convert Floating-Point Double-Precision to Signed Integer EVX-form (efdctsi RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCTUI, 0xfc0007ff, 0x100002f4, 0x1f0000, // Convert Floating-Point Double-Precision to Unsigned Integer EVX-form (efdctui RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCTSIDZ, 0xfc0007ff, 0x100002eb, 0x1f0000, // Convert Floating-Point Double-Precision to Signed Integer Doubleword with Round toward Zero EVX-form (efdctsidz RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCTUIDZ, 0xfc0007ff, 0x100002ea, 0x1f0000, // Convert Floating-Point Double-Precision to Unsigned Integer Doubleword with Round toward Zero EVX-form (efdctuidz RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCTSIZ, 0xfc0007ff, 0x100002fa, 0x1f0000, // Convert Floating-Point Double-Precision to Signed Integer with Round toward Zero EVX-form (efdctsiz RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCTSF, 0xfc0007ff, 0x100002f7, 0x1f0000, // Convert Floating-Point Double-Precision to Signed Fraction EVX-form (efdctsf RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCTUF, 0xfc0007ff, 0x100002f6, 0x1f0000, // Convert Floating-Point Double-Precision to Unsigned Fraction EVX-form (efdctuf RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCTUIZ, 0xfc0007ff, 0x100002f8, 0x1f0000, // Convert Floating-Point Double-Precision to Unsigned Integer with Round toward Zero EVX-form (efdctuiz RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFDCFS, 0xfc0007ff, 0x100002ef, 0x1f0000, // Floating-Point Double-Precision Convert from Single-Precision EVX-form (efdcfs RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{EFSCFD, 0xfc0007ff, 0x100002cf, 0x1f0000, // Floating-Point Single-Precision Convert from Double-Precision EVX-form (efscfd RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{DLMZB, 0xfc0007ff, 0x7c00009c, 0x0, // Determine Leftmost Zero Byte X-form (dlmzb RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{DLMZBCC, 0xfc0007ff, 0x7c00009d, 0x0, // Determine Leftmost Zero Byte X-form (dlmzb. RA,RS,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{MACCHW, 0xfc0007ff, 0x10000158, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (macchw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWCC, 0xfc0007ff, 0x10000159, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (macchw. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWO, 0xfc0007ff, 0x10000558, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (macchwo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWOCC, 0xfc0007ff, 0x10000559, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (macchwo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWS, 0xfc0007ff, 0x100001d8, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (macchws RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWSCC, 0xfc0007ff, 0x100001d9, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (macchws. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWSO, 0xfc0007ff, 0x100005d8, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (macchwso RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWSOCC, 0xfc0007ff, 0x100005d9, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (macchwso. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWU, 0xfc0007ff, 0x10000118, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Unsigned XO-form (macchwu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWUCC, 0xfc0007ff, 0x10000119, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Unsigned XO-form (macchwu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWUO, 0xfc0007ff, 0x10000518, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Unsigned XO-form (macchwuo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWUOCC, 0xfc0007ff, 0x10000519, 0x0, // Multiply Accumulate Cross Halfword to Word Modulo Unsigned XO-form (macchwuo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWSU, 0xfc0007ff, 0x10000198, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Unsigned XO-form (macchwsu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWSUCC, 0xfc0007ff, 0x10000199, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Unsigned XO-form (macchwsu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWSUO, 0xfc0007ff, 0x10000598, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Unsigned XO-form (macchwsuo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACCHWSUOCC, 0xfc0007ff, 0x10000599, 0x0, // Multiply Accumulate Cross Halfword to Word Saturate Unsigned XO-form (macchwsuo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHW, 0xfc0007ff, 0x10000058, 0x0, // Multiply Accumulate High Halfword to Word Modulo Signed XO-form (machhw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWCC, 0xfc0007ff, 0x10000059, 0x0, // Multiply Accumulate High Halfword to Word Modulo Signed XO-form (machhw. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWO, 0xfc0007ff, 0x10000458, 0x0, // Multiply Accumulate High Halfword to Word Modulo Signed XO-form (machhwo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWOCC, 0xfc0007ff, 0x10000459, 0x0, // Multiply Accumulate High Halfword to Word Modulo Signed XO-form (machhwo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWS, 0xfc0007ff, 0x100000d8, 0x0, // Multiply Accumulate High Halfword to Word Saturate Signed XO-form (machhws RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWSCC, 0xfc0007ff, 0x100000d9, 0x0, // Multiply Accumulate High Halfword to Word Saturate Signed XO-form (machhws. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWSO, 0xfc0007ff, 0x100004d8, 0x0, // Multiply Accumulate High Halfword to Word Saturate Signed XO-form (machhwso RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWSOCC, 0xfc0007ff, 0x100004d9, 0x0, // Multiply Accumulate High Halfword to Word Saturate Signed XO-form (machhwso. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWU, 0xfc0007ff, 0x10000018, 0x0, // Multiply Accumulate High Halfword to Word Modulo Unsigned XO-form (machhwu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWUCC, 0xfc0007ff, 0x10000019, 0x0, // Multiply Accumulate High Halfword to Word Modulo Unsigned XO-form (machhwu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWUO, 0xfc0007ff, 0x10000418, 0x0, // Multiply Accumulate High Halfword to Word Modulo Unsigned XO-form (machhwuo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWUOCC, 0xfc0007ff, 0x10000419, 0x0, // Multiply Accumulate High Halfword to Word Modulo Unsigned XO-form (machhwuo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWSU, 0xfc0007ff, 0x10000098, 0x0, // Multiply Accumulate High Halfword to Word Saturate Unsigned XO-form (machhwsu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWSUCC, 0xfc0007ff, 0x10000099, 0x0, // Multiply Accumulate High Halfword to Word Saturate Unsigned XO-form (machhwsu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWSUO, 0xfc0007ff, 0x10000498, 0x0, // Multiply Accumulate High Halfword to Word Saturate Unsigned XO-form (machhwsuo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACHHWSUOCC, 0xfc0007ff, 0x10000499, 0x0, // Multiply Accumulate High Halfword to Word Saturate Unsigned XO-form (machhwsuo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHW, 0xfc0007ff, 0x10000358, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (maclhw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWCC, 0xfc0007ff, 0x10000359, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (maclhw. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWO, 0xfc0007ff, 0x10000758, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (maclhwo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWOCC, 0xfc0007ff, 0x10000759, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (maclhwo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWS, 0xfc0007ff, 0x100003d8, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (maclhws RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWSCC, 0xfc0007ff, 0x100003d9, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (maclhws. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWSO, 0xfc0007ff, 0x100007d8, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (maclhwso RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWSOCC, 0xfc0007ff, 0x100007d9, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (maclhwso. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWU, 0xfc0007ff, 0x10000318, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Unsigned XO-form (maclhwu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWUCC, 0xfc0007ff, 0x10000319, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Unsigned XO-form (maclhwu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWUO, 0xfc0007ff, 0x10000718, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Unsigned XO-form (maclhwuo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWUOCC, 0xfc0007ff, 0x10000719, 0x0, // Multiply Accumulate Low Halfword to Word Modulo Unsigned XO-form (maclhwuo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULCHW, 0xfc0007ff, 0x10000150, 0x0, // Multiply Cross Halfword to Word Signed X-form (mulchw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULCHWCC, 0xfc0007ff, 0x10000151, 0x0, // Multiply Cross Halfword to Word Signed X-form (mulchw. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWSU, 0xfc0007ff, 0x10000398, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Unsigned XO-form (maclhwsu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWSUCC, 0xfc0007ff, 0x10000399, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Unsigned XO-form (maclhwsu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWSUO, 0xfc0007ff, 0x10000798, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Unsigned XO-form (maclhwsuo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MACLHWSUOCC, 0xfc0007ff, 0x10000799, 0x0, // Multiply Accumulate Low Halfword to Word Saturate Unsigned XO-form (maclhwsuo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULCHWU, 0xfc0007ff, 0x10000110, 0x0, // Multiply Cross Halfword to Word Unsigned X-form (mulchwu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULCHWUCC, 0xfc0007ff, 0x10000111, 0x0, // Multiply Cross Halfword to Word Unsigned X-form (mulchwu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULHHW, 0xfc0007ff, 0x10000050, 0x0, // Multiply High Halfword to Word Signed X-form (mulhhw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULHHWCC, 0xfc0007ff, 0x10000051, 0x0, // Multiply High Halfword to Word Signed X-form (mulhhw. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULLHW, 0xfc0007ff, 0x10000350, 0x0, // Multiply Low Halfword to Word Signed X-form (mullhw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULLHWCC, 0xfc0007ff, 0x10000351, 0x0, // Multiply Low Halfword to Word Signed X-form (mullhw. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULHHWU, 0xfc0007ff, 0x10000010, 0x0, // Multiply High Halfword to Word Unsigned X-form (mulhhwu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULHHWUCC, 0xfc0007ff, 0x10000011, 0x0, // Multiply High Halfword to Word Unsigned X-form (mulhhwu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULLHWU, 0xfc0007ff, 0x10000310, 0x0, // Multiply Low Halfword to Word Unsigned X-form (mullhwu RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MULLHWUCC, 0xfc0007ff, 0x10000311, 0x0, // Multiply Low Halfword to Word Unsigned X-form (mullhwu. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACCHW, 0xfc0007ff, 0x1000015c, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (nmacchw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACCHWCC, 0xfc0007ff, 0x1000015d, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (nmacchw. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACCHWO, 0xfc0007ff, 0x1000055c, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (nmacchwo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACCHWOCC, 0xfc0007ff, 0x1000055d, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Modulo Signed XO-form (nmacchwo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACCHWS, 0xfc0007ff, 0x100001dc, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (nmacchws RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACCHWSCC, 0xfc0007ff, 0x100001dd, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (nmacchws. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACCHWSO, 0xfc0007ff, 0x100005dc, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (nmacchwso RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACCHWSOCC, 0xfc0007ff, 0x100005dd, 0x0, // Negative Multiply Accumulate Cross Halfword to Word Saturate Signed XO-form (nmacchwso. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACHHW, 0xfc0007ff, 0x1000005c, 0x0, // Negative Multiply Accumulate High Halfword to Word Modulo Signed XO-form (nmachhw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACHHWCC, 0xfc0007ff, 0x1000005d, 0x0, // Negative Multiply Accumulate High Halfword to Word Modulo Signed XO-form (nmachhw. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACHHWO, 0xfc0007ff, 0x1000045c, 0x0, // Negative Multiply Accumulate High Halfword to Word Modulo Signed XO-form (nmachhwo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACHHWOCC, 0xfc0007ff, 0x1000045d, 0x0, // Negative Multiply Accumulate High Halfword to Word Modulo Signed XO-form (nmachhwo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACHHWS, 0xfc0007ff, 0x100000dc, 0x0, // Negative Multiply Accumulate High Halfword to Word Saturate Signed XO-form (nmachhws RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACHHWSCC, 0xfc0007ff, 0x100000dd, 0x0, // Negative Multiply Accumulate High Halfword to Word Saturate Signed XO-form (nmachhws. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACHHWSO, 0xfc0007ff, 0x100004dc, 0x0, // Negative Multiply Accumulate High Halfword to Word Saturate Signed XO-form (nmachhwso RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACHHWSOCC, 0xfc0007ff, 0x100004dd, 0x0, // Negative Multiply Accumulate High Halfword to Word Saturate Signed XO-form (nmachhwso. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACLHW, 0xfc0007ff, 0x1000035c, 0x0, // Negative Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (nmaclhw RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACLHWCC, 0xfc0007ff, 0x1000035d, 0x0, // Negative Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (nmaclhw. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACLHWO, 0xfc0007ff, 0x1000075c, 0x0, // Negative Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (nmaclhwo RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACLHWOCC, 0xfc0007ff, 0x1000075d, 0x0, // Negative Multiply Accumulate Low Halfword to Word Modulo Signed XO-form (nmaclhwo. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACLHWS, 0xfc0007ff, 0x100003dc, 0x0, // Negative Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (nmaclhws RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACLHWSCC, 0xfc0007ff, 0x100003dd, 0x0, // Negative Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (nmaclhws. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACLHWSO, 0xfc0007ff, 0x100007dc, 0x0, // Negative Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (nmaclhwso RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{NMACLHWSOCC, 0xfc0007ff, 0x100007dd, 0x0, // Negative Multiply Accumulate Low Halfword to Word Saturate Signed XO-form (nmaclhwso. RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ICBI, 0xfc0007fe, 0x7c0007ac, 0x3e00001, // Instruction Cache Block Invalidate X-form (icbi RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{ICBT, 0xfc0007fe, 0x7c00002c, 0x2000001, // Instruction Cache Block Touch X-form (icbt CT, RA, RB)
-		[5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBA, 0xfc0007fe, 0x7c0005ec, 0x3e00001, // Data Cache Block Allocate X-form (dcba RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBT, 0xfc0007fe, 0x7c00022c, 0x1, // Data Cache Block Touch X-form (dcbt RA,RB,TH)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_6_10}},
-	{DCBT, 0xfc0007fe, 0x7c00022c, 0x1, // Data Cache Block Touch X-form (dcbt TH,RA,RB)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBTST, 0xfc0007fe, 0x7c0001ec, 0x1, // Data Cache Block Touch for Store X-form (dcbtst RA,RB,TH)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_6_10}},
-	{DCBTST, 0xfc0007fe, 0x7c0001ec, 0x1, // Data Cache Block Touch for Store X-form (dcbtst TH,RA,RB)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBZ, 0xfc0007fe, 0x7c0007ec, 0x3e00001, // Data Cache Block set to Zero X-form (dcbz RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBST, 0xfc0007fe, 0x7c00006c, 0x3e00001, // Data Cache Block Store X-form (dcbst RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBF, 0xfc0007fe, 0x7c0000ac, 0x3800001, // Data Cache Block Flush X-form (dcbf RA,RB,L)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_9_10}},
-	{ISYNC, 0xfc0007fe, 0x4c00012c, 0x3fff801, // Instruction Synchronize XL-form (isync)
-		[5]*argField{}},
-	{LBARX, 0xfc0007ff, 0x7c000068, 0x0, // Load Byte And Reserve Indexed X-form [Category: Phased-In] (lbarx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LBARX, 0xfc0007fe, 0x7c000068, 0x0, // Load Byte And Reserve Indexed X-form [Category: Phased-In] (lbarx RT,RA,RB,EH)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}},
-	{LHARX, 0xfc0007ff, 0x7c0000e8, 0x0, // Load Halfword And Reserve Indexed X-form [Category: Phased-In] (lharx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LHARX, 0xfc0007fe, 0x7c0000e8, 0x0, // Load Halfword And Reserve Indexed X-form [Category: Phased-In] (lharx RT,RA,RB,EH)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}},
-	{LWARX, 0xfc0007ff, 0x7c000028, 0x0, // Load Word And Reserve Indexed X-form (lwarx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LWARX, 0xfc0007ff, 0x7c000028, 0x0, // Load Word And Reserve Indexed X-form (lwarx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LWARX, 0xfc0007fe, 0x7c000028, 0x0, // Load Word And Reserve Indexed X-form (lwarx RT,RA,RB,EH)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}},
-	{STBCXCC, 0xfc0007ff, 0x7c00056d, 0x0, // Store Byte Conditional Indexed X-form [Category: Phased-In] (stbcx. RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STHCXCC, 0xfc0007ff, 0x7c0005ad, 0x0, // Store Halfword Conditional Indexed X-form [Category: Phased-In] (sthcx. RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STWCXCC, 0xfc0007ff, 0x7c00012d, 0x0, // Store Word Conditional Indexed X-form (stwcx. RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LDARX, 0xfc0007ff, 0x7c0000a8, 0x0, // Load Doubleword And Reserve Indexed X-form (ldarx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LDARX, 0xfc0007fe, 0x7c0000a8, 0x0, // Load Doubleword And Reserve Indexed X-form (ldarx RT,RA,RB,EH)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}},
-	{STDCXCC, 0xfc0007ff, 0x7c0001ad, 0x0, // Store Doubleword Conditional Indexed X-form (stdcx. RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LQARX, 0xfc0007ff, 0x7c000228, 0x0, // Load Quadword And Reserve Indexed X-form (lqarx RTp,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LQARX, 0xfc0007fe, 0x7c000228, 0x0, // Load Quadword And Reserve Indexed X-form (lqarx RTp,RA,RB,EH)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}},
-	{STQCXCC, 0xfc0007ff, 0x7c00016d, 0x0, // Store Quadword Conditional Indexed X-form (stqcx. RSp,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SYNC, 0xfc0007fe, 0x7c0004ac, 0x390f801, // Synchronize X-form (sync L, E)
-		[5]*argField{ap_ImmUnsigned_9_10, ap_ImmUnsigned_12_15}},
-	{EIEIO, 0xfc0007fe, 0x7c0006ac, 0x3fff801, // Enforce In-order Execution of I/O X-form (eieio)
-		[5]*argField{}},
-	{MBAR, 0xfc0007fe, 0x7c0006ac, 0x1ff801, // Memory Barrier X-form (mbar MO)
-		[5]*argField{ap_ImmUnsigned_6_10}},
-	{WAIT, 0xfc0007fe, 0x7c00007c, 0x39ff801, // Wait X-form (wait WC)
-		[5]*argField{ap_ImmUnsigned_9_10}},
-	{TBEGINCC, 0xfc0007ff, 0x7c00051d, 0x1dff800, // Transaction Begin X-form (tbegin. R)
-		[5]*argField{ap_ImmUnsigned_10_10}},
-	{TENDCC, 0xfc0007ff, 0x7c00055d, 0x1fff800, // Transaction End X-form (tend. A)
-		[5]*argField{ap_ImmUnsigned_6_6}},
-	{TABORTCC, 0xfc0007ff, 0x7c00071d, 0x3e0f800, // Transaction Abort X-form (tabort. RA)
-		[5]*argField{ap_Reg_11_15}},
-	{TABORTWCCC, 0xfc0007ff, 0x7c00061d, 0x0, // Transaction Abort Word Conditional X-form (tabortwc. TO,RA,RB)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{TABORTWCICC, 0xfc0007ff, 0x7c00069d, 0x0, // Transaction Abort Word Conditional Immediate X-form (tabortwci. TO,RA,SI)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_ImmSigned_16_20}},
-	{TABORTDCCC, 0xfc0007ff, 0x7c00065d, 0x0, // Transaction Abort Doubleword Conditional X-form (tabortdc. TO,RA,RB)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{TABORTDCICC, 0xfc0007ff, 0x7c0006dd, 0x0, // Transaction Abort Doubleword Conditional Immediate X-form (tabortdci. TO,RA, SI)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_ImmSigned_16_20}},
-	{TSRCC, 0xfc0007ff, 0x7c0005dd, 0x3dff800, // Transaction Suspend or Resume X-form (tsr. L)
-		[5]*argField{ap_ImmUnsigned_10_10}},
-	{TCHECK, 0xfc0007fe, 0x7c00059c, 0x7ff801, // Transaction Check X-form (tcheck BF)
-		[5]*argField{ap_CondRegField_6_8}},
-	{MFTB, 0xfc0007fe, 0x7c0002e6, 0x1, // Move From Time Base XFX-form (mftb RT,TBR)
-		[5]*argField{ap_Reg_6_10, ap_SpReg_16_20_11_15}},
-	{RFEBB, 0xfc0007fe, 0x4c000124, 0x3fff001, // Return from Event-Based Branch XL-form (rfebb S)
-		[5]*argField{ap_ImmUnsigned_20_20}},
-	{LBDX, 0xfc0007fe, 0x7c000406, 0x1, // Load Byte with Decoration Indexed X-form (lbdx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LHDX, 0xfc0007fe, 0x7c000446, 0x1, // Load Halfword with Decoration Indexed X-form (lhdx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LWDX, 0xfc0007fe, 0x7c000486, 0x1, // Load Word with Decoration Indexed X-form (lwdx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LDDX, 0xfc0007fe, 0x7c0004c6, 0x1, // Load Doubleword with Decoration Indexed X-form (lddx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LFDDX, 0xfc0007fe, 0x7c000646, 0x1, // Load Floating Doubleword with Decoration Indexed X-form (lfddx FRT,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STBDX, 0xfc0007fe, 0x7c000506, 0x1, // Store Byte with Decoration Indexed X-form (stbdx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STHDX, 0xfc0007fe, 0x7c000546, 0x1, // Store Halfword with Decoration Indexed X-form (sthdx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STWDX, 0xfc0007fe, 0x7c000586, 0x1, // Store Word with Decoration Indexed X-form (stwdx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STDDX, 0xfc0007fe, 0x7c0005c6, 0x1, // Store Doubleword with Decoration Indexed X-form (stddx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STFDDX, 0xfc0007fe, 0x7c000746, 0x1, // Store Floating Doubleword with Decoration Indexed X-form (stfddx FRS,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DSN, 0xfc0007fe, 0x7c0003c6, 0x3e00001, // Decorated Storage Notify X-form (dsn RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{ECIWX, 0xfc0007fe, 0x7c00026c, 0x1, // External Control In Word Indexed X-form (eciwx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ECOWX, 0xfc0007fe, 0x7c00036c, 0x1, // External Control Out Word Indexed X-form (ecowx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{SC, 0xfc000002, 0x44000002, 0x3fff01d, // System Call SC-form (sc LEV)
-		[5]*argField{ap_ImmUnsigned_20_26}},
-	{RFID, 0xfc0007fe, 0x4c000024, 0x3fff801, // Return From Interrupt Doubleword XL-form (rfid)
-		[5]*argField{}},
-	{HRFID, 0xfc0007fe, 0x4c000224, 0x3fff801, // Hypervisor Return From Interrupt Doubleword XL-form (hrfid)
-		[5]*argField{}},
-	{DOZE, 0xfc0007fe, 0x4c000324, 0x3fff801, // Doze XL-form (doze)
-		[5]*argField{}},
-	{NAP, 0xfc0007fe, 0x4c000364, 0x3fff801, // Nap XL-form (nap)
-		[5]*argField{}},
-	{SLEEP, 0xfc0007fe, 0x4c0003a4, 0x3fff801, // Sleep XL-form (sleep)
-		[5]*argField{}},
-	{RVWINKLE, 0xfc0007fe, 0x4c0003e4, 0x3fff801, // Rip Van Winkle XL-form (rvwinkle)
-		[5]*argField{}},
-	{LBZCIX, 0xfc0007fe, 0x7c0006aa, 0x1, // Load Byte and Zero Caching Inhibited Indexed X-form (lbzcix RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LWZCIX, 0xfc0007fe, 0x7c00062a, 0x1, // Load Word and Zero Caching Inhibited Indexed X-form (lwzcix RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LHZCIX, 0xfc0007fe, 0x7c00066a, 0x1, // Load Halfword and Zero Caching Inhibited Indexed X-form (lhzcix RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LDCIX, 0xfc0007fe, 0x7c0006ea, 0x1, // Load Doubleword Caching Inhibited Indexed X-form (ldcix RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STBCIX, 0xfc0007fe, 0x7c0007aa, 0x1, // Store Byte Caching Inhibited Indexed X-form (stbcix RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STWCIX, 0xfc0007fe, 0x7c00072a, 0x1, // Store Word Caching Inhibited Indexed X-form (stwcix RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STHCIX, 0xfc0007fe, 0x7c00076a, 0x1, // Store Halfword Caching Inhibited Indexed X-form (sthcix RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STDCIX, 0xfc0007fe, 0x7c0007ea, 0x1, // Store Doubleword Caching Inhibited Indexed X-form (stdcix RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{TRECLAIMCC, 0xfc0007ff, 0x7c00075d, 0x3e0f800, // Transaction Reclaim X-form (treclaim. RA)
-		[5]*argField{ap_Reg_11_15}},
-	{TRECHKPTCC, 0xfc0007ff, 0x7c0007dd, 0x3fff800, // Transaction Recheckpoint X-form (trechkpt.)
-		[5]*argField{}},
-	{MTSPR, 0xfc0007fe, 0x7c0003a6, 0x1, // Move To Special Purpose Register XFX-form (mtspr SPR,RS)
-		[5]*argField{ap_SpReg_16_20_11_15, ap_Reg_6_10}},
-	{MFSPR, 0xfc0007fe, 0x7c0002a6, 0x1, // Move From Special Purpose Register XFX-form (mfspr RT,SPR)
-		[5]*argField{ap_Reg_6_10, ap_SpReg_16_20_11_15}},
-	{MTMSR, 0xfc0007fe, 0x7c000124, 0x1ef801, // Move To Machine State Register X-form (mtmsr RS,L)
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_15_15}},
-	{MTMSRD, 0xfc0007fe, 0x7c000164, 0x1ef801, // Move To Machine State Register Doubleword X-form (mtmsrd RS,L)
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_15_15}},
-	{MFMSR, 0xfc0007fe, 0x7c0000a6, 0x1ff801, // Move From Machine State Register X-form (mfmsr RT)
-		[5]*argField{ap_Reg_6_10}},
-	{SLBIE, 0xfc0007fe, 0x7c000364, 0x3ff0001, // SLB Invalidate Entry X-form (slbie RB)
-		[5]*argField{ap_Reg_16_20}},
-	{SLBIA, 0xfc0007fe, 0x7c0003e4, 0x31ff801, // SLB Invalidate All X-form (slbia IH)
-		[5]*argField{ap_ImmUnsigned_8_10}},
-	{SLBMTE, 0xfc0007fe, 0x7c000324, 0x1f0001, // SLB Move To Entry X-form (slbmte RS,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{SLBMFEV, 0xfc0007fe, 0x7c0006a6, 0x1f0001, // SLB Move From Entry VSID X-form (slbmfev RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{SLBMFEE, 0xfc0007fe, 0x7c000726, 0x1f0001, // SLB Move From Entry ESID X-form (slbmfee RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{SLBFEECC, 0xfc0007ff, 0x7c0007a7, 0x1f0000, // SLB Find Entry ESID X-form (slbfee. RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{MTSR, 0xfc0007fe, 0x7c0001a4, 0x10f801, // Move To Segment Register X-form (mtsr SR,RS)
-		[5]*argField{ap_SpReg_12_15, ap_Reg_6_10}},
-	{MTSRIN, 0xfc0007fe, 0x7c0001e4, 0x1f0001, // Move To Segment Register Indirect X-form (mtsrin RS,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{MFSR, 0xfc0007fe, 0x7c0004a6, 0x10f801, // Move From Segment Register X-form (mfsr RT,SR)
-		[5]*argField{ap_Reg_6_10, ap_SpReg_12_15}},
-	{MFSRIN, 0xfc0007fe, 0x7c000526, 0x1f0001, // Move From Segment Register Indirect X-form (mfsrin RT,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_16_20}},
-	{TLBIE, 0xfc0007fe, 0x7c000264, 0x1f0001, // TLB Invalidate Entry X-form (tlbie RB,RS)
-		[5]*argField{ap_Reg_16_20, ap_Reg_6_10}},
-	{TLBIEL, 0xfc0007fe, 0x7c000224, 0x3ff0001, // TLB Invalidate Entry Local X-form (tlbiel RB)
-		[5]*argField{ap_Reg_16_20}},
-	{TLBIA, 0xfc0007fe, 0x7c0002e4, 0x3fff801, // TLB Invalidate All X-form (tlbia)
-		[5]*argField{}},
-	{TLBSYNC, 0xfc0007fe, 0x7c00046c, 0x3fff801, // TLB Synchronize X-form (tlbsync)
-		[5]*argField{}},
-	{MSGSND, 0xfc0007fe, 0x7c00019c, 0x3ff0001, // Message Send X-form (msgsnd RB)
-		[5]*argField{ap_Reg_16_20}},
-	{MSGCLR, 0xfc0007fe, 0x7c0001dc, 0x3ff0001, // Message Clear X-form (msgclr RB)
-		[5]*argField{ap_Reg_16_20}},
-	{MSGSNDP, 0xfc0007fe, 0x7c00011c, 0x3ff0001, // Message Send Privileged X-form (msgsndp RB)
-		[5]*argField{ap_Reg_16_20}},
-	{MSGCLRP, 0xfc0007fe, 0x7c00015c, 0x3ff0001, // Message Clear Privileged X-form (msgclrp RB)
-		[5]*argField{ap_Reg_16_20}},
-	{MTTMR, 0xfc0007fe, 0x7c0003dc, 0x1, // Move To Thread Management Register XFX-form (mttmr TMR,RS)
-		[5]*argField{ap_SpReg_16_20_11_15, ap_Reg_6_10}},
-	{SC, 0xfc000002, 0x44000002, 0x3fffffd, // System Call SC-form (sc)
-		[5]*argField{}},
-	{RFI, 0xfc0007fe, 0x4c000064, 0x3fff801, // Return From Interrupt XL-form (rfi)
-		[5]*argField{}},
-	{RFCI, 0xfc0007fe, 0x4c000066, 0x3fff801, // Return From Critical Interrupt XL-form (rfci)
-		[5]*argField{}},
-	{RFDI, 0xfc0007fe, 0x4c00004e, 0x3fff801, // Return From Debug Interrupt X-form (rfdi)
-		[5]*argField{}},
-	{RFMCI, 0xfc0007fe, 0x4c00004c, 0x3fff801, // Return From Machine Check Interrupt XL-form (rfmci)
-		[5]*argField{}},
-	{RFGI, 0xfc0007fe, 0x4c0000cc, 0x3fff801, // Return From Guest Interrupt XL-form (rfgi)
-		[5]*argField{}},
-	{EHPRIV, 0xfc0007fe, 0x7c00021c, 0x1, // Embedded Hypervisor Privilege XL-form (ehpriv OC)
-		[5]*argField{ap_ImmUnsigned_6_20}},
-	{MTSPR, 0xfc0007fe, 0x7c0003a6, 0x1, // Move To Special Purpose Register XFX-form (mtspr SPR,RS)
-		[5]*argField{ap_SpReg_16_20_11_15, ap_Reg_6_10}},
-	{MFSPR, 0xfc0007fe, 0x7c0002a6, 0x1, // Move From Special Purpose Register XFX-form (mfspr RT,SPR)
-		[5]*argField{ap_Reg_6_10, ap_SpReg_16_20_11_15}},
-	{MTDCR, 0xfc0007fe, 0x7c000386, 0x1, // Move To Device Control Register XFX-form (mtdcr DCRN,RS)
-		[5]*argField{ap_SpReg_16_20_11_15, ap_Reg_6_10}},
-	{MTDCRX, 0xfc0007fe, 0x7c000306, 0xf801, // Move To Device Control Register Indexed X-form (mtdcrx RA,RS)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10}},
-	{MFDCR, 0xfc0007fe, 0x7c000286, 0x1, // Move From Device Control Register XFX-form (mfdcr RT,DCRN)
-		[5]*argField{ap_Reg_6_10, ap_SpReg_16_20_11_15}},
-	{MFDCRX, 0xfc0007fe, 0x7c000206, 0xf801, // Move From Device Control Register Indexed X-form (mfdcrx RT,RA)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15}},
-	{MTMSR, 0xfc0007fe, 0x7c000124, 0x1ff801, // Move To Machine State Register X-form (mtmsr RS)
-		[5]*argField{ap_Reg_6_10}},
-	{MFMSR, 0xfc0007fe, 0x7c0000a6, 0x1ff801, // Move From Machine State Register X-form (mfmsr RT)
-		[5]*argField{ap_Reg_6_10}},
-	{WRTEE, 0xfc0007fe, 0x7c000106, 0x1ff801, // Write MSR External Enable X-form (wrtee RS)
-		[5]*argField{ap_Reg_6_10}},
-	{WRTEEI, 0xfc0007fe, 0x7c000146, 0x3ff7801, // Write MSR External Enable Immediate X-form (wrteei E)
-		[5]*argField{ap_ImmUnsigned_16_16}},
-	{LBEPX, 0xfc0007fe, 0x7c0000be, 0x1, // Load Byte by External Process ID Indexed X-form (lbepx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LHEPX, 0xfc0007fe, 0x7c00023e, 0x1, // Load Halfword by External Process ID Indexed X-form (lhepx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LWEPX, 0xfc0007fe, 0x7c00003e, 0x1, // Load Word by External Process ID Indexed X-form (lwepx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LDEPX, 0xfc0007fe, 0x7c00003a, 0x1, // Load Doubleword by External Process ID Indexed X-form (ldepx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STBEPX, 0xfc0007fe, 0x7c0001be, 0x1, // Store Byte by External Process ID Indexed X-form (stbepx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STHEPX, 0xfc0007fe, 0x7c00033e, 0x1, // Store Halfword by External Process ID Indexed X-form (sthepx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STWEPX, 0xfc0007fe, 0x7c00013e, 0x1, // Store Word by External Process ID Indexed X-form (stwepx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STDEPX, 0xfc0007fe, 0x7c00013a, 0x1, // Store Doubleword by External Process ID Indexed X-form (stdepx RS,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBSTEP, 0xfc0007fe, 0x7c00007e, 0x3e00001, // Data Cache Block Store by External PID X-form (dcbstep RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBTEP, 0xfc0007fe, 0x7c00027e, 0x1, // Data Cache Block Touch by External PID X-form (dcbtep TH,RA,RB)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBFEP, 0xfc0007fe, 0x7c0000fe, 0x3800001, // Data Cache Block Flush by External PID X-form (dcbfep RA,RB,L)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_9_10}},
-	{DCBTSTEP, 0xfc0007fe, 0x7c0001fe, 0x1, // Data Cache Block Touch for Store by External PID X-form (dcbtstep TH,RA,RB)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ICBIEP, 0xfc0007fe, 0x7c0007be, 0x3e00001, // Instruction Cache Block Invalidate by External PID X-form (icbiep RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBZEP, 0xfc0007fe, 0x7c0007fe, 0x3e00001, // Data Cache Block set to Zero by External PID X-form (dcbzep RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{LFDEPX, 0xfc0007fe, 0x7c0004be, 0x1, // Load Floating-Point Double by External Process ID Indexed X-form (lfdepx FRT,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STFDEPX, 0xfc0007fe, 0x7c0005be, 0x1, // Store Floating-Point Double by External Process ID Indexed X-form (stfdepx FRS,RA,RB)
-		[5]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVLDDEPX, 0xfc0007fe, 0x7c00063e, 0x1, // Vector Load Doubleword into Doubleword by External Process ID Indexed EVX-form (evlddepx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{EVSTDDEPX, 0xfc0007fe, 0x7c00073e, 0x1, // Vector Store Doubleword into Doubleword by External Process ID Indexed EVX-form (evstddepx RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LVEPX, 0xfc0007fe, 0x7c00024e, 0x1, // Load Vector by External Process ID Indexed X-form (lvepx VRT,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{LVEPXL, 0xfc0007fe, 0x7c00020e, 0x1, // Load Vector by External Process ID Indexed LRU X-form (lvepxl VRT,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STVEPX, 0xfc0007fe, 0x7c00064e, 0x1, // Store Vector by External Process ID Indexed X-form (stvepx VRS,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{STVEPXL, 0xfc0007fe, 0x7c00060e, 0x1, // Store Vector by External Process ID Indexed LRU X-form (stvepxl VRS,RA,RB)
-		[5]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBI, 0xfc0007fe, 0x7c0003ac, 0x3e00001, // Data Cache Block Invalidate X-form (dcbi RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBLQCC, 0xfc0007ff, 0x7c00034d, 0x2000000, // Data Cache Block Lock Query X-form (dcblq. CT,RA,RB)
-		[5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ICBLQCC, 0xfc0007ff, 0x7c00018d, 0x2000000, // Instruction Cache Block Lock Query X-form (icblq. CT,RA,RB)
-		[5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBTLS, 0xfc0007fe, 0x7c00014c, 0x2000001, // Data Cache Block Touch and Lock Set X-form (dcbtls CT,RA,RB)
-		[5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBTSTLS, 0xfc0007fe, 0x7c00010c, 0x2000001, // Data Cache Block Touch for Store and Lock Set X-form (dcbtstls CT,RA,RB)
-		[5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ICBTLS, 0xfc0007fe, 0x7c0003cc, 0x2000001, // Instruction Cache Block Touch and Lock Set X-form (icbtls CT,RA,RB)
-		[5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ICBLC, 0xfc0007fe, 0x7c0001cc, 0x2000001, // Instruction Cache Block Lock Clear X-form (icblc CT,RA,RB)
-		[5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{DCBLC, 0xfc0007fe, 0x7c00030c, 0x2000001, // Data Cache Block Lock Clear X-form (dcblc CT,RA,RB)
-		[5]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{TLBIVAX, 0xfc0007fe, 0x7c000624, 0x3e00001, // TLB Invalidate Virtual Address Indexed X-form (tlbivax RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{TLBILX, 0xfc0007fe, 0x7c000024, 0x3800001, // TLB Invalidate Local Indexed X-form (tlbilx RA,RB])
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{TLBSX, 0xfc0007fe, 0x7c000724, 0x3e00001, // TLB Search Indexed X-form (tlbsx RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{TLBSRXCC, 0xfc0007ff, 0x7c0006a5, 0x3e00000, // TLB Search and Reserve Indexed X-form (tlbsrx. RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{TLBRE, 0xfc0007fe, 0x7c000764, 0x3fff801, // TLB Read Entry X-form (tlbre)
-		[5]*argField{}},
-	{TLBSYNC, 0xfc0007fe, 0x7c00046c, 0x3fff801, // TLB Synchronize X-form (tlbsync)
-		[5]*argField{}},
-	{TLBWE, 0xfc0007fe, 0x7c0007a4, 0x3fff801, // TLB Write Entry X-form (tlbwe)
-		[5]*argField{}},
-	{DNH, 0xfc0007fe, 0x4c00018c, 0x1, // Debugger Notify Halt XFX-form (dnh DUI,DUIS)
-		[5]*argField{ap_ImmUnsigned_6_10, ap_ImmUnsigned_11_20}},
-	{MSGSND, 0xfc0007fe, 0x7c00019c, 0x3ff0001, // Message Send X-form (msgsnd RB)
-		[5]*argField{ap_Reg_16_20}},
-	{MSGCLR, 0xfc0007fe, 0x7c0001dc, 0x3ff0001, // Message Clear X-form (msgclr RB)
-		[5]*argField{ap_Reg_16_20}},
-	{DCI, 0xfc0007fe, 0x7c00038c, 0x21ff801, // Data Cache Invalidate X-form (dci CT)
-		[5]*argField{ap_ImmUnsigned_7_10}},
-	{ICI, 0xfc0007fe, 0x7c00078c, 0x21ff801, // Instruction Cache Invalidate X-form (ici CT)
-		[5]*argField{ap_ImmUnsigned_7_10}},
-	{DCREAD, 0xfc0007fe, 0x7c0003cc, 0x1, // Data Cache Read X-form (dcread RT,RA,RB)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{ICREAD, 0xfc0007fe, 0x7c0007cc, 0x3e00001, // Instruction Cache Read X-form (icread RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{MFPMR, 0xfc0007fe, 0x7c00029c, 0x1, // Move From Performance Monitor Register XFX-form (mfpmr RT,PMRN)
-		[5]*argField{ap_Reg_6_10, ap_SpReg_11_20}},
-	{MTPMR, 0xfc0007fe, 0x7c00039c, 0x1, // Move To Performance Monitor Register XFX-form (mtpmr PMRN,RS)
-		[5]*argField{ap_SpReg_11_20, ap_Reg_6_10}},
-	{ADDEX, 0xfc0001fe, 0x7c000154, 0x1, // Add Extended using alternate carry bit Z23-form (addex RT,RA,RB,CY)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_21_22}},
-	{DARN, 0xfc0007fe, 0x7c0005e6, 0x1cf801, // Deliver A Random Number X-form (darn RT,L)
-		[5]*argField{ap_Reg_6_10, ap_ImmUnsigned_14_15}},
-	{MADDHD, 0xfc00003f, 0x10000030, 0x0, // Multiply-Add High Doubleword VA-form (maddhd RT,RA,RB,RC)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_Reg_21_25}},
-	{MADDHDU, 0xfc00003f, 0x10000031, 0x0, // Multiply-Add High Doubleword Unsigned VA-form (maddhdu RT,RA,RB,RC)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_Reg_21_25}},
-	{MADDLD, 0xfc00003f, 0x10000033, 0x0, // Multiply-Add Low Doubleword VA-form (maddld RT,RA,RB,RC)
-		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_Reg_21_25}},
-	{CMPRB, 0xfc0007fe, 0x7c000180, 0x400001, // Compare Ranged Byte X-form (cmprb BF,L,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_10_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{CMPEQB, 0xfc0007fe, 0x7c0001c0, 0x600001, // Compare Equal Byte X-form (cmpeqb BF,RA,RB)
-		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
-	{BPERMD, 0xfc0007fe, 0x7c0001f8, 0x1, // Bit Permute Doubleword X-form (bpermd RA,RS,RB])
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
-	{EXTSWSLI, 0xfc0007fd, 0x7c0006f4, 0x0, // Extend-Sign Word and Shift Left Immediate XS-form (extswsli RA,RS,SH)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20}},
-	{EXTSWSLICC, 0xfc0007fd, 0x7c0006f5, 0x0, // Extend-Sign Word and Shift Left Immediate XS-form (extswsli. RA,RS,SH)
-		[5]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20}},
-	{MFVSRD, 0xfc0007fe, 0x7c000066, 0xf800, // Move From VSR Doubleword X-form (mfvsrd RA,XS)
-		[5]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}},
-	{MFVSRLD, 0xfc0007fe, 0x7c000266, 0xf800, // Move From VSR Lower Doubleword X-form (mfvsrld RA,XS)
-		[5]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}},
-	{MFVSRWZ, 0xfc0007fe, 0x7c0000e6, 0xf800, // Move From VSR Word and Zero X-form (mfvsrwz RA,XS)
-		[5]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}},
-	{MTVSRD, 0xfc0007fe, 0x7c000166, 0xf800, // Move To VSR Doubleword X-form (mtvsrd XT,RA)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}},
-	{MTVSRWA, 0xfc0007fe, 0x7c0001a6, 0xf800, // Move To VSR Word Algebraic X-form (mtvsrwa XT,RA)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}},
-	{MTVSRWZ, 0xfc0007fe, 0x7c0001e6, 0xf800, // Move To VSR Word and Zero X-form (mtvsrwz XT,RA)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}},
-	{MTVSRDD, 0xfc0007fe, 0x7c000366, 0x0, // Move To VSR Double Doubleword X-form (mtvsrdd XT,RA,RB)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
-	{MTVSRWS, 0xfc0007fe, 0x7c000326, 0xf800, // Move To VSR Word & Splat X-form (mtvsrws XT,RA)
-		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}},
-	{MCRXRX, 0xfc0007fe, 0x7c000480, 0x7ff801, // Move to CR from XER Extended X-form (mcrxrx BF)
-		[5]*argField{ap_CondRegField_6_8}},
-	{COPY, 0xfc2007fe, 0x7c20060c, 0x3c00001, // Copy X-form (copy RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
-	{PASTECC, 0xfc2007ff, 0x7c20070d, 0x3c00000, // Paste X-form (paste. RA,RB)
-		[5]*argField{ap_Reg_11_15, ap_Reg_16_20}},
+	{BRD, 0xfc0007fe00000000, 0x7c00017600000000, 0xf80100000000, // Byte-Reverse Doubleword X-form (brd RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{BRH, 0xfc0007fe00000000, 0x7c0001b600000000, 0xf80100000000, // Byte-Reverse Halfword X-form (brh RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{BRW, 0xfc0007fe00000000, 0x7c00013600000000, 0xf80100000000, // Byte-Reverse Word X-form (brw RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{CFUGED, 0xfc0007fe00000000, 0x7c0001b800000000, 0x100000000, // Centrifuge Doubleword X-form (cfuged RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{CNTLZDM, 0xfc0007fe00000000, 0x7c00007600000000, 0x100000000, // Count Leading Zeros Doubleword under bit Mask X-form (cntlzdm RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{CNTTZDM, 0xfc0007fe00000000, 0x7c00047600000000, 0x100000000, // Count Trailing Zeros Doubleword under bit Mask X-form (cnttzdm RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{DCFFIXQQ, 0xfc1f07fe00000000, 0xfc0007c400000000, 0x100000000, // DFP Convert From Fixed Quadword Quad X-form (dcffixqq FRTp,VRB)
+		[6]*argField{ap_FPReg_6_10, ap_VecReg_16_20}},
+	{DCTFIXQQ, 0xfc1f07fe00000000, 0xfc0107c400000000, 0x100000000, // DFP Convert To Fixed Quadword Quad X-form (dctfixqq VRT,FRBp)
+		[6]*argField{ap_VecReg_6_10, ap_FPReg_16_20}},
+	{LXVKQ, 0xfc1f07fe00000000, 0xf01f02d000000000, 0x0, // Load VSX Vector Special Value Quadword X-form (lxvkq XT,UIM)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_ImmUnsigned_16_20}},
+	{LXVP, 0xfc00000f00000000, 0x1800000000000000, 0x0, // Load VSX Vector Paired DQ-form (lxvp XTp,DQ(RA))
+		[6]*argField{ap_VecSpReg_10_10_6_9, ap_Offset_16_27_shift4, ap_Reg_11_15}},
+	{LXVPX, 0xfc0007fe00000000, 0x7c00029a00000000, 0x100000000, // Load VSX Vector Paired Indexed X-form (lxvpx XTp,RA,RB)
+		[6]*argField{ap_VecSpReg_10_10_6_9, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVRBX, 0xfc0007fe00000000, 0x7c00001a00000000, 0x0, // Load VSX Vector Rightmost Byte Indexed X-form (lxvrbx XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVRDX, 0xfc0007fe00000000, 0x7c0000da00000000, 0x0, // Load VSX Vector Rightmost Doubleword Indexed X-form (lxvrdx XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVRHX, 0xfc0007fe00000000, 0x7c00005a00000000, 0x0, // Load VSX Vector Rightmost Halfword Indexed X-form (lxvrhx XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVRWX, 0xfc0007fe00000000, 0x7c00009a00000000, 0x0, // Load VSX Vector Rightmost Word Indexed X-form (lxvrwx XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MTVSRBM, 0xfc1f07ff00000000, 0x1010064200000000, 0x0, // Move to VSR Byte Mask VX-form (mtvsrbm VRT,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_16_20}},
+	{MTVSRBMI, 0xfc00003e00000000, 0x1000001400000000, 0x0, // Move To VSR Byte Mask Immediate DX-form (mtvsrbmi VRT,bm)
+		[6]*argField{ap_VecReg_6_10, ap_ImmUnsigned_16_25_11_15_31_31}},
+	{MTVSRDM, 0xfc1f07ff00000000, 0x1013064200000000, 0x0, // Move to VSR Doubleword Mask VX-form (mtvsrdm VRT,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_16_20}},
+	{MTVSRHM, 0xfc1f07ff00000000, 0x1011064200000000, 0x0, // Move to VSR Halfword Mask VX-form (mtvsrhm VRT,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_16_20}},
+	{MTVSRQM, 0xfc1f07ff00000000, 0x1014064200000000, 0x0, // Move to VSR Quadword Mask VX-form (mtvsrqm VRT,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_16_20}},
+	{MTVSRWM, 0xfc1f07ff00000000, 0x1012064200000000, 0x0, // Move to VSR Word Mask VX-form (mtvsrwm VRT,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_16_20}},
+	{PADDI, 0xff800000fc000000, 0x600000038000000, 0x6c000000000000, // Prefixed Add Immediate MLS:D-form (paddi RT,RA,SI,R)
+		[6]*argField{ap_Reg_38_42, ap_Reg_43_47, ap_ImmSigned_14_31_48_63, ap_ImmUnsigned_11_11}},
+	{PDEPD, 0xfc0007fe00000000, 0x7c00013800000000, 0x100000000, // Parallel Bits Deposit Doubleword X-form (pdepd RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{PEXTD, 0xfc0007fe00000000, 0x7c00017800000000, 0x100000000, // Parallel Bits Extract Doubleword X-form (pextd RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{PLBZ, 0xff800000fc000000, 0x600000088000000, 0x6c000000000000, // Prefixed Load Byte and Zero MLS:D-form (plbz RT,D(RA),R)
+		[6]*argField{ap_Reg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PLD, 0xff800000fc000000, 0x4000000e4000000, 0x6c000000000000, // Prefixed Load Doubleword 8LS:D-form (pld RT,D(RA),R)
+		[6]*argField{ap_Reg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PLFD, 0xff800000fc000000, 0x6000000c8000000, 0x6c000000000000, // Prefixed Load Floating-Point Double MLS:D-form (plfd FRT,D(RA),R)
+		[6]*argField{ap_FPReg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PLFS, 0xff800000fc000000, 0x6000000c0000000, 0x6c000000000000, // Prefixed Load Floating-Point Single MLS:D-form (plfs FRT,D(RA),R)
+		[6]*argField{ap_FPReg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PLHA, 0xff800000fc000000, 0x6000000a8000000, 0x6c000000000000, // Prefixed Load Halfword Algebraic MLS:D-form (plha RT,D(RA),R)
+		[6]*argField{ap_Reg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PLHZ, 0xff800000fc000000, 0x6000000a0000000, 0x6c000000000000, // Prefixed Load Halfword and Zero MLS:D-form (plhz RT,D(RA),R)
+		[6]*argField{ap_Reg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PLQ, 0xff800000fc000000, 0x4000000e0000000, 0x6c000000000000, // Prefixed Load Quadword 8LS:D-form (plq RTp,D(RA),R)
+		[6]*argField{ap_Reg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PLWA, 0xff800000fc000000, 0x4000000a4000000, 0x6c000000000000, // Prefixed Load Word Algebraic 8LS:D-form (plwa RT,D(RA),R)
+		[6]*argField{ap_Reg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PLWZ, 0xff800000fc000000, 0x600000080000000, 0x6c000000000000, // Prefixed Load Word and Zero MLS:D-form (plwz RT,D(RA),R)
+		[6]*argField{ap_Reg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PLXSD, 0xff800000fc000000, 0x4000000a8000000, 0x6c000000000000, // Prefixed Load VSX Scalar Doubleword 8LS:D-form (plxsd VRT,D(RA),R)
+		[6]*argField{ap_VecReg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PLXSSP, 0xff800000fc000000, 0x4000000ac000000, 0x6c000000000000, // Prefixed Load VSX Scalar Single-Precision 8LS:D-form (plxssp VRT,D(RA),R)
+		[6]*argField{ap_VecReg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PLXV, 0xff800000f8000000, 0x4000000c8000000, 0x6c000000000000, // Prefixed Load VSX Vector 8LS:D-form (plxv XT,D(RA),R)
+		[6]*argField{ap_VecSReg_37_37_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PLXVP, 0xff800000fc000000, 0x4000000e8000000, 0x6c000000000000, // Prefixed Load VSX Vector Paired 8LS:D-form (plxvp XTp,D(RA),R)
+		[6]*argField{ap_VecSpReg_42_42_38_41, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PMXVBF16GER2, 0xfff00000fc0007f8, 0x7900000ec000198, 0xf3f0000000000, // Prefixed Masked VSX Vector bfloat16 GER (Rank-2 Update) MMIRR:XX3-form (pmxvbf16ger2 AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVBF16GER2NN, 0xfff00000fc0007f8, 0x7900000ec000790, 0xf3f0000000000, // Prefixed Masked VSX Vector bfloat16 GER (Rank-2 Update) Negative multiply, Negative accumulate MMIRR:XX3-form (pmxvbf16ger2nn AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVBF16GER2NP, 0xfff00000fc0007f8, 0x7900000ec000390, 0xf3f0000000000, // Prefixed Masked VSX Vector bfloat16 GER (Rank-2 Update) Negative multiply, Positive accumulate MMIRR:XX3-form (pmxvbf16ger2np AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVBF16GER2PN, 0xfff00000fc0007f8, 0x7900000ec000590, 0xf3f0000000000, // Prefixed Masked VSX Vector bfloat16 GER (Rank-2 Update) Positive multiply, Negative accumulate MMIRR:XX3-form (pmxvbf16ger2pn AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVBF16GER2PP, 0xfff00000fc0007f8, 0x7900000ec000190, 0xf3f0000000000, // Prefixed Masked VSX Vector bfloat16 GER (Rank-2 Update) Positive multiply, Positive accumulate MMIRR:XX3-form (pmxvbf16ger2pp AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVF16GER2, 0xfff00000fc0007f8, 0x7900000ec000098, 0xf3f0000000000, // Prefixed Masked VSX Vector 16-bit Floating-Point GER (rank-2 update) MMIRR:XX3-form (pmxvf16ger2 AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVF16GER2NN, 0xfff00000fc0007f8, 0x7900000ec000690, 0xf3f0000000000, // Prefixed Masked VSX Vector 16-bit Floating-Point GER (rank-2 update) Negative multiply, Negative accumulate MMIRR:XX3-form (pmxvf16ger2nn AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVF16GER2NP, 0xfff00000fc0007f8, 0x7900000ec000290, 0xf3f0000000000, // Prefixed Masked VSX Vector 16-bit Floating-Point GER (rank-2 update) Negative multiply, Positive accumulate MMIRR:XX3-form (pmxvf16ger2np AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVF16GER2PN, 0xfff00000fc0007f8, 0x7900000ec000490, 0xf3f0000000000, // Prefixed Masked VSX Vector 16-bit Floating-Point GER (rank-2 update) Positive multiply, Negative accumulate MMIRR:XX3-form (pmxvf16ger2pn AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVF16GER2PP, 0xfff00000fc0007f8, 0x7900000ec000090, 0xf3f0000000000, // Prefixed Masked VSX Vector 16-bit Floating-Point GER (rank-2 update) Positive multiply, Positive accumulate MMIRR:XX3-form (pmxvf16ger2pp AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVF32GER, 0xfff00000fc0007f8, 0x7900000ec0000d8, 0xfff0000000000, // Prefixed Masked VSX Vector 32-bit Floating-Point GER (rank-1 update) MMIRR:XX3-form (pmxvf32ger AT,XA,XB,XMSK,YMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31}},
+	{PMXVF32GERNN, 0xfff00000fc0007f8, 0x7900000ec0006d0, 0xfff0000000000, // Prefixed Masked VSX Vector 32-bit Floating-Point GER (rank-1 update) Negative multiply, Negative accumulate MMIRR:XX3-form (pmxvf32gernn AT,XA,XB,XMSK,YMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31}},
+	{PMXVF32GERNP, 0xfff00000fc0007f8, 0x7900000ec0002d0, 0xfff0000000000, // Prefixed Masked VSX Vector 32-bit Floating-Point GER (rank-1 update) Negative multiply, Positive accumulate MMIRR:XX3-form (pmxvf32gernp AT,XA,XB,XMSK,YMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31}},
+	{PMXVF32GERPN, 0xfff00000fc0007f8, 0x7900000ec0004d0, 0xfff0000000000, // Prefixed Masked VSX Vector 32-bit Floating-Point GER (rank-1 update) Positive multiply, Negative accumulate MMIRR:XX3-form (pmxvf32gerpn AT,XA,XB,XMSK,YMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31}},
+	{PMXVF32GERPP, 0xfff00000fc0007f8, 0x7900000ec0000d0, 0xfff0000000000, // Prefixed Masked VSX Vector 32-bit Floating-Point GER (rank-1 update) Positive multiply, Positive accumulate MMIRR:XX3-form (pmxvf32gerpp AT,XA,XB,XMSK,YMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31}},
+	{PMXVF64GER, 0xfff00000fc0007f8, 0x7900000ec0001d8, 0xfff0300000000, // Prefixed Masked VSX Vector 64-bit Floating-Point GER (rank-1 update) MMIRR:XX3-form (pmxvf64ger AT,XAp,XB,XMSK,YMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_29}},
+	{PMXVF64GERNN, 0xfff00000fc0007f8, 0x7900000ec0007d0, 0xfff0300000000, // Prefixed Masked VSX Vector 64-bit Floating-Point GER (rank-1 update) Negative multiply, Negative accumulate MMIRR:XX3-form (pmxvf64gernn AT,XAp,XB,XMSK,YMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_29}},
+	{PMXVF64GERNP, 0xfff00000fc0007f8, 0x7900000ec0003d0, 0xfff0300000000, // Prefixed Masked VSX Vector 64-bit Floating-Point GER (rank-1 update) Negative multiply, Positive accumulate MMIRR:XX3-form (pmxvf64gernp AT,XAp,XB,XMSK,YMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_29}},
+	{PMXVF64GERPN, 0xfff00000fc0007f8, 0x7900000ec0005d0, 0xfff0300000000, // Prefixed Masked VSX Vector 64-bit Floating-Point GER (rank-1 update) Positive multiply, Negative accumulate MMIRR:XX3-form (pmxvf64gerpn AT,XAp,XB,XMSK,YMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_29}},
+	{PMXVF64GERPP, 0xfff00000fc0007f8, 0x7900000ec0001d0, 0xfff0300000000, // Prefixed Masked VSX Vector 64-bit Floating-Point GER (rank-1 update) Positive multiply, Positive accumulate MMIRR:XX3-form (pmxvf64gerpp AT,XAp,XB,XMSK,YMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_29}},
+	{PMXVI16GER2, 0xfff00000fc0007f8, 0x7900000ec000258, 0xf3f0000000000, // Prefixed Masked VSX Vector 16-bit Signed Integer GER (rank-2 update) MMIRR:XX3-form (pmxvi16ger2 AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVI16GER2PP, 0xfff00000fc0007f8, 0x7900000ec000358, 0xf3f0000000000, // Prefixed Masked VSX Vector 16-bit Signed Integer GER (rank-2 update) Positive multiply, Positive accumulate MMIRR:XX3-form (pmxvi16ger2pp AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVI16GER2S, 0xfff00000fc0007f8, 0x7900000ec000158, 0xf3f0000000000, // Prefixed Masked VSX Vector 16-bit Signed Integer GER (rank-2 update) with Saturation MMIRR:XX3-form (pmxvi16ger2s AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVI16GER2SPP, 0xfff00000fc0007f8, 0x7900000ec000150, 0xf3f0000000000, // Prefixed Masked VSX Vector 16-bit Signed Integer GER (rank-2 update) with Saturation Positive multiply, Positive accumulate MMIRR:XX3-form (pmxvi16ger2spp AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_17}},
+	{PMXVI4GER8, 0xfff00000fc0007f8, 0x7900000ec000118, 0xf000000000000, // Prefixed Masked VSX Vector 4-bit Signed Integer GER (rank-8 update) MMIRR:XX3-form (pmxvi4ger8 AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_23}},
+	{PMXVI4GER8PP, 0xfff00000fc0007f8, 0x7900000ec000110, 0xf000000000000, // Prefixed Masked VSX Vector 4-bit Signed Integer GER (rank-8 update) Positive multiply, Positive accumulate MMIRR:XX3-form (pmxvi4ger8pp AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_23}},
+	{PMXVI8GER4, 0xfff00000fc0007f8, 0x7900000ec000018, 0xf0f0000000000, // Prefixed Masked VSX Vector 8-bit Signed/Unsigned Integer GER (rank-4 update) MMIRR:XX3-form (pmxvi8ger4 AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_19}},
+	{PMXVI8GER4PP, 0xfff00000fc0007f8, 0x7900000ec000010, 0xf0f0000000000, // Prefixed Masked VSX Vector 8-bit Signed/Unsigned Integer GER (rank-4 update) Positive multiply, Positive accumulate MMIRR:XX3-form (pmxvi8ger4pp AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_19}},
+	{PMXVI8GER4SPP, 0xfff00000fc0007f8, 0x7900000ec000318, 0xf0f0000000000, // Prefixed Masked VSX Vector 8-bit Signed/Unsigned Integer GER (rank-4 update) with Saturate Positive multiply, Positive accumulate MMIRR:XX3-form (pmxvi8ger4spp AT,XA,XB,XMSK,YMSK,PMSK)
+		[6]*argField{ap_MMAReg_38_40, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_ImmUnsigned_24_27, ap_ImmUnsigned_28_31, ap_ImmUnsigned_16_19}},
+	{PNOP, 0xfff3fffe00000000, 0x700000000000000, 0xc000100000000, // Prefixed Nop MRR:*-form (pnop)
+		[6]*argField{}},
+	{PSTB, 0xff800000fc000000, 0x600000098000000, 0x6c000000000000, // Prefixed Store Byte MLS:D-form (pstb RS,D(RA),R)
+		[6]*argField{ap_Reg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PSTD, 0xff800000fc000000, 0x4000000f4000000, 0x6c000000000000, // Prefixed Store Doubleword 8LS:D-form (pstd RS,D(RA),R)
+		[6]*argField{ap_Reg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PSTFD, 0xff800000fc000000, 0x6000000d8000000, 0x6c000000000000, // Prefixed Store Floating-Point Double MLS:D-form (pstfd FRS,D(RA),R)
+		[6]*argField{ap_FPReg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PSTFS, 0xff800000fc000000, 0x6000000d0000000, 0x6c000000000000, // Prefixed Store Floating-Point Single MLS:D-form (pstfs FRS,D(RA),R)
+		[6]*argField{ap_FPReg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PSTH, 0xff800000fc000000, 0x6000000b0000000, 0x6c000000000000, // Prefixed Store Halfword MLS:D-form (psth RS,D(RA),R)
+		[6]*argField{ap_Reg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PSTQ, 0xff800000fc000000, 0x4000000f0000000, 0x6c000000000000, // Prefixed Store Quadword 8LS:D-form (pstq RSp,D(RA),R)
+		[6]*argField{ap_Reg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PSTW, 0xff800000fc000000, 0x600000090000000, 0x6c000000000000, // Prefixed Store Word MLS:D-form (pstw RS,D(RA),R)
+		[6]*argField{ap_Reg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PSTXSD, 0xff800000fc000000, 0x4000000b8000000, 0x6c000000000000, // Prefixed Store VSX Scalar Doubleword 8LS:D-form (pstxsd VRS,D(RA),R)
+		[6]*argField{ap_VecReg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PSTXSSP, 0xff800000fc000000, 0x4000000bc000000, 0x6c000000000000, // Prefixed Store VSX Scalar Single-Precision 8LS:D-form (pstxssp VRS,D(RA),R)
+		[6]*argField{ap_VecReg_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PSTXV, 0xff800000f8000000, 0x4000000d8000000, 0x6c000000000000, // Prefixed Store VSX Vector 8LS:D-form (pstxv XS,D(RA),R)
+		[6]*argField{ap_VecSReg_37_37_38_42, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{PSTXVP, 0xff800000fc000000, 0x4000000f8000000, 0x6c000000000000, // Prefixed Store VSX Vector Paired 8LS:D-form (pstxvp XSp,D(RA),R)
+		[6]*argField{ap_VecSpReg_42_42_38_41, ap_Offset_14_31_48_63, ap_Reg_43_47, ap_ImmUnsigned_11_11}},
+	{SETBC, 0xfc0007fe00000000, 0x7c00030000000000, 0xf80100000000, // Set Boolean Condition X-form (setbc RT,BI)
+		[6]*argField{ap_Reg_6_10, ap_CondRegBit_11_15}},
+	{SETBCR, 0xfc0007fe00000000, 0x7c00034000000000, 0xf80100000000, // Set Boolean Condition Reverse X-form (setbcr RT,BI)
+		[6]*argField{ap_Reg_6_10, ap_CondRegBit_11_15}},
+	{SETNBC, 0xfc0007fe00000000, 0x7c00038000000000, 0xf80100000000, // Set Negative Boolean Condition X-form (setnbc RT,BI)
+		[6]*argField{ap_Reg_6_10, ap_CondRegBit_11_15}},
+	{SETNBCR, 0xfc0007fe00000000, 0x7c0003c000000000, 0xf80100000000, // Set Negative Boolean Condition Reverse X-form (setnbcr RT,BI)
+		[6]*argField{ap_Reg_6_10, ap_CondRegBit_11_15}},
+	{STXVP, 0xfc00000f00000000, 0x1800000100000000, 0x0, // Store VSX Vector Paired DQ-form (stxvp XSp,DQ(RA))
+		[6]*argField{ap_VecSpReg_10_10_6_9, ap_Offset_16_27_shift4, ap_Reg_11_15}},
+	{STXVPX, 0xfc0007fe00000000, 0x7c00039a00000000, 0x100000000, // Store VSX Vector Paired Indexed X-form (stxvpx XSp,RA,RB)
+		[6]*argField{ap_VecSpReg_10_10_6_9, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXVRBX, 0xfc0007fe00000000, 0x7c00011a00000000, 0x0, // Store VSX Vector Rightmost Byte Indexed X-form (stxvrbx XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXVRDX, 0xfc0007fe00000000, 0x7c0001da00000000, 0x0, // Store VSX Vector Rightmost Doubleword Indexed X-form (stxvrdx XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXVRHX, 0xfc0007fe00000000, 0x7c00015a00000000, 0x0, // Store VSX Vector Rightmost Halfword Indexed X-form (stxvrhx XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXVRWX, 0xfc0007fe00000000, 0x7c00019a00000000, 0x0, // Store VSX Vector Rightmost Word Indexed X-form (stxvrwx XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{VCFUGED, 0xfc0007ff00000000, 0x1000054d00000000, 0x0, // Vector Centrifuge Doubleword VX-form (vcfuged VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCLRLB, 0xfc0007ff00000000, 0x1000018d00000000, 0x0, // Vector Clear Leftmost Bytes VX-form (vclrlb VRT,VRA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_Reg_16_20}},
+	{VCLRRB, 0xfc0007ff00000000, 0x100001cd00000000, 0x0, // Vector Clear Rightmost Bytes VX-form (vclrrb VRT,VRA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_Reg_16_20}},
+	{VCLZDM, 0xfc0007ff00000000, 0x1000078400000000, 0x0, // Vector Count Leading Zeros Doubleword under bit Mask VX-form (vclzdm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPEQUQ, 0xfc0007ff00000000, 0x100001c700000000, 0x0, // Vector Compare Equal Quadword VC-form (vcmpequq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPEQUQCC, 0xfc0007ff00000000, 0x100005c700000000, 0x0, // Vector Compare Equal Quadword VC-form (vcmpequq. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTSQ, 0xfc0007ff00000000, 0x1000038700000000, 0x0, // Vector Compare Greater Than Signed Quadword VC-form (vcmpgtsq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTSQCC, 0xfc0007ff00000000, 0x1000078700000000, 0x0, // Vector Compare Greater Than Signed Quadword VC-form (vcmpgtsq. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTUQ, 0xfc0007ff00000000, 0x1000028700000000, 0x0, // Vector Compare Greater Than Unsigned Quadword VC-form (vcmpgtuq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTUQCC, 0xfc0007ff00000000, 0x1000068700000000, 0x0, // Vector Compare Greater Than Unsigned Quadword VC-form (vcmpgtuq. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPSQ, 0xfc0007ff00000000, 0x1000014100000000, 0x60000000000000, // Vector Compare Signed Quadword VX-form (vcmpsq BF,VRA,VRB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPUQ, 0xfc0007ff00000000, 0x1000010100000000, 0x60000000000000, // Vector Compare Unsigned Quadword VX-form (vcmpuq BF,VRA,VRB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCNTMBB, 0xfc1e07ff00000000, 0x1018064200000000, 0x0, // Vector Count Mask Bits Byte VX-form (vcntmbb RT,VRB,MP)
+		[6]*argField{ap_Reg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_15_15}},
+	{VCNTMBD, 0xfc1e07ff00000000, 0x101e064200000000, 0x0, // Vector Count Mask Bits Doubleword VX-form (vcntmbd RT,VRB,MP)
+		[6]*argField{ap_Reg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_15_15}},
+	{VCNTMBH, 0xfc1e07ff00000000, 0x101a064200000000, 0x0, // Vector Count Mask Bits Halfword VX-form (vcntmbh RT,VRB,MP)
+		[6]*argField{ap_Reg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_15_15}},
+	{VCNTMBW, 0xfc1e07ff00000000, 0x101c064200000000, 0x0, // Vector Count Mask Bits Word VX-form (vcntmbw RT,VRB,MP)
+		[6]*argField{ap_Reg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_15_15}},
+	{VCTZDM, 0xfc0007ff00000000, 0x100007c400000000, 0x0, // Vector Count Trailing Zeros Doubleword under bit Mask VX-form (vctzdm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VDIVESD, 0xfc0007ff00000000, 0x100003cb00000000, 0x0, // Vector Divide Extended Signed Doubleword VX-form (vdivesd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VDIVESQ, 0xfc0007ff00000000, 0x1000030b00000000, 0x0, // Vector Divide Extended Signed Quadword VX-form (vdivesq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VDIVESW, 0xfc0007ff00000000, 0x1000038b00000000, 0x0, // Vector Divide Extended Signed Word VX-form (vdivesw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VDIVEUD, 0xfc0007ff00000000, 0x100002cb00000000, 0x0, // Vector Divide Extended Unsigned Doubleword VX-form (vdiveud VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VDIVEUQ, 0xfc0007ff00000000, 0x1000020b00000000, 0x0, // Vector Divide Extended Unsigned Quadword VX-form (vdiveuq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VDIVEUW, 0xfc0007ff00000000, 0x1000028b00000000, 0x0, // Vector Divide Extended Unsigned Word VX-form (vdiveuw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VDIVSD, 0xfc0007ff00000000, 0x100001cb00000000, 0x0, // Vector Divide Signed Doubleword VX-form (vdivsd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VDIVSQ, 0xfc0007ff00000000, 0x1000010b00000000, 0x0, // Vector Divide Signed Quadword VX-form (vdivsq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VDIVSW, 0xfc0007ff00000000, 0x1000018b00000000, 0x0, // Vector Divide Signed Word VX-form (vdivsw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VDIVUD, 0xfc0007ff00000000, 0x100000cb00000000, 0x0, // Vector Divide Unsigned Doubleword VX-form (vdivud VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VDIVUQ, 0xfc0007ff00000000, 0x1000000b00000000, 0x0, // Vector Divide Unsigned Quadword VX-form (vdivuq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VDIVUW, 0xfc0007ff00000000, 0x1000008b00000000, 0x0, // Vector Divide Unsigned Word VX-form (vdivuw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VEXPANDBM, 0xfc1f07ff00000000, 0x1000064200000000, 0x0, // Vector Expand Byte Mask VX-form (vexpandbm VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VEXPANDDM, 0xfc1f07ff00000000, 0x1003064200000000, 0x0, // Vector Expand Doubleword Mask VX-form (vexpanddm VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VEXPANDHM, 0xfc1f07ff00000000, 0x1001064200000000, 0x0, // Vector Expand Halfword Mask VX-form (vexpandhm VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VEXPANDQM, 0xfc1f07ff00000000, 0x1004064200000000, 0x0, // Vector Expand Quadword Mask VX-form (vexpandqm VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VEXPANDWM, 0xfc1f07ff00000000, 0x1002064200000000, 0x0, // Vector Expand Word Mask VX-form (vexpandwm VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VEXTDDVLX, 0xfc00003f00000000, 0x1000001e00000000, 0x0, // Vector Extract Double Doubleword to VSR using GPR-specified Left-Index VA-form (vextddvlx VRT,VRA,VRB,RC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_Reg_21_25}},
+	{VEXTDDVRX, 0xfc00003f00000000, 0x1000001f00000000, 0x0, // Vector Extract Double Doubleword to VSR using GPR-specified Right-Index VA-form (vextddvrx VRT,VRA,VRB,RC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_Reg_21_25}},
+	{VEXTDUBVLX, 0xfc00003f00000000, 0x1000001800000000, 0x0, // Vector Extract Double Unsigned Byte to VSR using GPR-specified Left-Index VA-form (vextdubvlx VRT,VRA,VRB,RC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_Reg_21_25}},
+	{VEXTDUBVRX, 0xfc00003f00000000, 0x1000001900000000, 0x0, // Vector Extract Double Unsigned Byte to VSR using GPR-specified Right-Index VA-form (vextdubvrx VRT,VRA,VRB,RC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_Reg_21_25}},
+	{VEXTDUHVLX, 0xfc00003f00000000, 0x1000001a00000000, 0x0, // Vector Extract Double Unsigned Halfword to VSR using GPR-specified Left-Index VA-form (vextduhvlx VRT,VRA,VRB,RC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_Reg_21_25}},
+	{VEXTDUHVRX, 0xfc00003f00000000, 0x1000001b00000000, 0x0, // Vector Extract Double Unsigned Halfword to VSR using GPR-specified Right-Index VA-form (vextduhvrx VRT,VRA,VRB,RC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_Reg_21_25}},
+	{VEXTDUWVLX, 0xfc00003f00000000, 0x1000001c00000000, 0x0, // Vector Extract Double Unsigned Word to VSR using GPR-specified Left-Index VA-form (vextduwvlx VRT,VRA,VRB,RC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_Reg_21_25}},
+	{VEXTDUWVRX, 0xfc00003f00000000, 0x1000001d00000000, 0x0, // Vector Extract Double Unsigned Word to VSR using GPR-specified Right-Index VA-form (vextduwvrx VRT,VRA,VRB,RC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_Reg_21_25}},
+	{VEXTRACTBM, 0xfc1f07ff00000000, 0x1008064200000000, 0x0, // Vector Extract Byte Mask VX-form (vextractbm RT,VRB)
+		[6]*argField{ap_Reg_6_10, ap_VecReg_16_20}},
+	{VEXTRACTDM, 0xfc1f07ff00000000, 0x100b064200000000, 0x0, // Vector Extract Doubleword Mask VX-form (vextractdm RT,VRB)
+		[6]*argField{ap_Reg_6_10, ap_VecReg_16_20}},
+	{VEXTRACTHM, 0xfc1f07ff00000000, 0x1009064200000000, 0x0, // Vector Extract Halfword Mask VX-form (vextracthm RT,VRB)
+		[6]*argField{ap_Reg_6_10, ap_VecReg_16_20}},
+	{VEXTRACTQM, 0xfc1f07ff00000000, 0x100c064200000000, 0x0, // Vector Extract Quadword Mask VX-form (vextractqm RT,VRB)
+		[6]*argField{ap_Reg_6_10, ap_VecReg_16_20}},
+	{VEXTRACTWM, 0xfc1f07ff00000000, 0x100a064200000000, 0x0, // Vector Extract Word Mask VX-form (vextractwm RT,VRB)
+		[6]*argField{ap_Reg_6_10, ap_VecReg_16_20}},
+	{VEXTSD2Q, 0xfc1f07ff00000000, 0x101b060200000000, 0x0, // Vector Extend Sign Doubleword to Quadword VX-form (vextsd2q VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VGNB, 0xfc0007ff00000000, 0x100004cc00000000, 0x18000000000000, // Vector Gather every Nth Bit VX-form (vgnb RT,VRB,N)
+		[6]*argField{ap_Reg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_13_15}},
+	{VINSBLX, 0xfc0007ff00000000, 0x1000020f00000000, 0x0, // Vector Insert Byte from GPR using GPR-specified Left-Index VX-form (vinsblx VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{VINSBRX, 0xfc0007ff00000000, 0x1000030f00000000, 0x0, // Vector Insert Byte from GPR using GPR-specified Right-Index VX-form (vinsbrx VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{VINSBVLX, 0xfc0007ff00000000, 0x1000000f00000000, 0x0, // Vector Insert Byte from VSR using GPR-specified Left-Index VX-form (vinsbvlx VRT,RA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_VecReg_16_20}},
+	{VINSBVRX, 0xfc0007ff00000000, 0x1000010f00000000, 0x0, // Vector Insert Byte from VSR using GPR-specified Right-Index VX-form (vinsbvrx VRT,RA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_VecReg_16_20}},
+	{VINSD, 0xfc0007ff00000000, 0x100001cf00000000, 0x10000000000000, // Vector Insert Doubleword from GPR using immediate-specified index VX-form (vinsd VRT,RB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_16_20, ap_ImmUnsigned_12_15}},
+	{VINSDLX, 0xfc0007ff00000000, 0x100002cf00000000, 0x0, // Vector Insert Doubleword from GPR using GPR-specified Left-Index VX-form (vinsdlx VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{VINSDRX, 0xfc0007ff00000000, 0x100003cf00000000, 0x0, // Vector Insert Doubleword from GPR using GPR-specified Right-Index VX-form (vinsdrx VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{VINSHLX, 0xfc0007ff00000000, 0x1000024f00000000, 0x0, // Vector Insert Halfword from GPR using GPR-specified Left-Index VX-form (vinshlx VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{VINSHRX, 0xfc0007ff00000000, 0x1000034f00000000, 0x0, // Vector Insert Halfword from GPR using GPR-specified Right-Index VX-form (vinshrx VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{VINSHVLX, 0xfc0007ff00000000, 0x1000004f00000000, 0x0, // Vector Insert Halfword from VSR using GPR-specified Left-Index VX-form (vinshvlx VRT,RA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_VecReg_16_20}},
+	{VINSHVRX, 0xfc0007ff00000000, 0x1000014f00000000, 0x0, // Vector Insert Halfword from VSR using GPR-specified Right-Index VX-form (vinshvrx VRT,RA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_VecReg_16_20}},
+	{VINSW, 0xfc0007ff00000000, 0x100000cf00000000, 0x10000000000000, // Vector Insert Word from GPR using immediate-specified index VX-form (vinsw VRT,RB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_16_20, ap_ImmUnsigned_12_15}},
+	{VINSWLX, 0xfc0007ff00000000, 0x1000028f00000000, 0x0, // Vector Insert Word from GPR using GPR-specified Left-Index VX-form (vinswlx VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{VINSWRX, 0xfc0007ff00000000, 0x1000038f00000000, 0x0, // Vector Insert Word from GPR using GPR-specified Right-Index VX-form (vinswrx VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{VINSWVLX, 0xfc0007ff00000000, 0x1000008f00000000, 0x0, // Vector Insert Word from VSR using GPR-specified Left-Index VX-form (vinswvlx VRT,RA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_VecReg_16_20}},
+	{VINSWVRX, 0xfc0007ff00000000, 0x1000018f00000000, 0x0, // Vector Insert Word from VSR using GPR-specified Left-Index VX-form (vinswvrx VRT,RA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_VecReg_16_20}},
+	{VMODSD, 0xfc0007ff00000000, 0x100007cb00000000, 0x0, // Vector Modulo Signed Doubleword VX-form (vmodsd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMODSQ, 0xfc0007ff00000000, 0x1000070b00000000, 0x0, // Vector Modulo Signed Quadword VX-form (vmodsq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMODSW, 0xfc0007ff00000000, 0x1000078b00000000, 0x0, // Vector Modulo Signed Word VX-form (vmodsw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMODUD, 0xfc0007ff00000000, 0x100006cb00000000, 0x0, // Vector Modulo Unsigned Doubleword VX-form (vmodud VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMODUQ, 0xfc0007ff00000000, 0x1000060b00000000, 0x0, // Vector Modulo Unsigned Quadword VX-form (vmoduq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMODUW, 0xfc0007ff00000000, 0x1000068b00000000, 0x0, // Vector Modulo Unsigned Word VX-form (vmoduw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMSUMCUD, 0xfc00003f00000000, 0x1000001700000000, 0x0, // Vector Multiply-Sum & write Carry-out Unsigned Doubleword VA-form (vmsumcud VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VMULESD, 0xfc0007ff00000000, 0x100003c800000000, 0x0, // Vector Multiply Even Signed Doubleword VX-form (vmulesd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULEUD, 0xfc0007ff00000000, 0x100002c800000000, 0x0, // Vector Multiply Even Unsigned Doubleword VX-form (vmuleud VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULHSD, 0xfc0007ff00000000, 0x100003c900000000, 0x0, // Vector Multiply High Signed Doubleword VX-form (vmulhsd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULHSW, 0xfc0007ff00000000, 0x1000038900000000, 0x0, // Vector Multiply High Signed Word VX-form (vmulhsw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULHUD, 0xfc0007ff00000000, 0x100002c900000000, 0x0, // Vector Multiply High Unsigned Doubleword VX-form (vmulhud VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULHUW, 0xfc0007ff00000000, 0x1000028900000000, 0x0, // Vector Multiply High Unsigned Word VX-form (vmulhuw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULLD, 0xfc0007ff00000000, 0x100001c900000000, 0x0, // Vector Multiply Low Doubleword VX-form (vmulld VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULOSD, 0xfc0007ff00000000, 0x100001c800000000, 0x0, // Vector Multiply Odd Signed Doubleword VX-form (vmulosd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULOUD, 0xfc0007ff00000000, 0x100000c800000000, 0x0, // Vector Multiply Odd Unsigned Doubleword VX-form (vmuloud VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPDEPD, 0xfc0007ff00000000, 0x100005cd00000000, 0x0, // Vector Parallel Bits Deposit Doubleword VX-form (vpdepd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPEXTD, 0xfc0007ff00000000, 0x1000058d00000000, 0x0, // Vector Parallel Bits Extract Doubleword VX-form (vpextd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VRLQ, 0xfc0007ff00000000, 0x1000000500000000, 0x0, // Vector Rotate Left Quadword VX-form (vrlq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VRLQMI, 0xfc0007ff00000000, 0x1000004500000000, 0x0, // Vector Rotate Left Quadword then Mask Insert VX-form (vrlqmi VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VRLQNM, 0xfc0007ff00000000, 0x1000014500000000, 0x0, // Vector Rotate Left Quadword then AND with Mask VX-form (vrlqnm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSLDBI, 0xfc00063f00000000, 0x1000001600000000, 0x0, // Vector Shift Left Double by Bit Immediate VN-form (vsldbi VRT,VRA,VRB,SH)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_23_25}},
+	{VSLQ, 0xfc0007ff00000000, 0x1000010500000000, 0x0, // Vector Shift Left Quadword VX-form (vslq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSRAQ, 0xfc0007ff00000000, 0x1000030500000000, 0x0, // Vector Shift Right Algebraic Quadword VX-form (vsraq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSRDBI, 0xfc00063f00000000, 0x1000021600000000, 0x0, // Vector Shift Right Double by Bit Immediate VN-form (vsrdbi VRT,VRA,VRB,SH)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_23_25}},
+	{VSRQ, 0xfc0007ff00000000, 0x1000020500000000, 0x0, // Vector Shift Right Quadword VX-form (vsrq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSTRIBL, 0xfc1f07ff00000000, 0x1000000d00000000, 0x0, // Vector String Isolate Byte Left-justified VX-form (vstribl VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VSTRIBLCC, 0xfc1f07ff00000000, 0x1000040d00000000, 0x0, // Vector String Isolate Byte Left-justified VX-form (vstribl. VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VSTRIBR, 0xfc1f07ff00000000, 0x1001000d00000000, 0x0, // Vector String Isolate Byte Right-justified VX-form (vstribr VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VSTRIBRCC, 0xfc1f07ff00000000, 0x1001040d00000000, 0x0, // Vector String Isolate Byte Right-justified VX-form (vstribr. VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VSTRIHL, 0xfc1f07ff00000000, 0x1002000d00000000, 0x0, // Vector String Isolate Halfword Left-justified VX-form (vstrihl VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VSTRIHLCC, 0xfc1f07ff00000000, 0x1002040d00000000, 0x0, // Vector String Isolate Halfword Left-justified VX-form (vstrihl. VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VSTRIHR, 0xfc1f07ff00000000, 0x1003000d00000000, 0x0, // Vector String Isolate Halfword Right-justified VX-form (vstrihr VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VSTRIHRCC, 0xfc1f07ff00000000, 0x1003040d00000000, 0x0, // Vector String Isolate Halfword Right-justified VX-form (vstrihr. VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSCMPEQQP, 0xfc0007fe00000000, 0xfc00008800000000, 0x100000000, // VSX Scalar Compare Equal Quad-Precision X-form (xscmpeqqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSCMPGEQP, 0xfc0007fe00000000, 0xfc00018800000000, 0x100000000, // VSX Scalar Compare Greater Than or Equal Quad-Precision X-form (xscmpgeqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSCMPGTQP, 0xfc0007fe00000000, 0xfc0001c800000000, 0x100000000, // VSX Scalar Compare Greater Than Quad-Precision X-form (xscmpgtqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSCVQPSQZ, 0xfc1f07fe00000000, 0xfc08068800000000, 0x100000000, // VSX Scalar Convert with round to zero Quad-Precision to Signed Quadword X-form (xscvqpsqz VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSCVQPUQZ, 0xfc1f07fe00000000, 0xfc00068800000000, 0x100000000, // VSX Scalar Convert with round to zero Quad-Precision to Unsigned Quadword X-form (xscvqpuqz VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSCVSQQP, 0xfc1f07fe00000000, 0xfc0b068800000000, 0x100000000, // VSX Scalar Convert with round Signed Quadword to Quad-Precision X-form (xscvsqqp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSCVUQQP, 0xfc1f07fe00000000, 0xfc03068800000000, 0x100000000, // VSX Scalar Convert with round Unsigned Quadword to Quad-Precision X-form (xscvuqqp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSMAXCQP, 0xfc0007fe00000000, 0xfc00054800000000, 0x100000000, // VSX Scalar Maximum Type-C Quad-Precision X-form (xsmaxcqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSMINCQP, 0xfc0007fe00000000, 0xfc0005c800000000, 0x100000000, // VSX Scalar Minimum Type-C Quad-Precision X-form (xsmincqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XVBF16GER2, 0xfc0007f800000000, 0xec00019800000000, 0x60000100000000, // VSX Vector bfloat16 GER (Rank-2 Update) XX3-form (xvbf16ger2 AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVBF16GER2NN, 0xfc0007f800000000, 0xec00079000000000, 0x60000100000000, // VSX Vector bfloat16 GER (Rank-2 Update) Negative multiply, Negative accumulate XX3-form (xvbf16ger2nn AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVBF16GER2NP, 0xfc0007f800000000, 0xec00039000000000, 0x60000100000000, // VSX Vector bfloat16 GER (Rank-2 Update) Negative multiply, Positive accumulate XX3-form (xvbf16ger2np AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVBF16GER2PN, 0xfc0007f800000000, 0xec00059000000000, 0x60000100000000, // VSX Vector bfloat16 GER (Rank-2 Update) Positive multiply, Negative accumulate XX3-form (xvbf16ger2pn AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVBF16GER2PP, 0xfc0007f800000000, 0xec00019000000000, 0x60000100000000, // VSX Vector bfloat16 GER (Rank-2 Update) Positive multiply, Positive accumulate XX3-form (xvbf16ger2pp AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCVBF16SPN, 0xfc1f07fc00000000, 0xf010076c00000000, 0x0, // VSX Vector Convert bfloat16 to Single-Precision format XX2-form (xvcvbf16spn XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVSPBF16, 0xfc1f07fc00000000, 0xf011076c00000000, 0x0, // VSX Vector Convert with round Single-Precision to bfloat16 format XX2-form (xvcvspbf16 XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVF16GER2, 0xfc0007f800000000, 0xec00009800000000, 0x60000100000000, // VSX Vector 16-bit Floating-Point GER (rank-2 update) XX3-form (xvf16ger2 AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF16GER2NN, 0xfc0007f800000000, 0xec00069000000000, 0x60000100000000, // VSX Vector 16-bit Floating-Point GER (rank-2 update) Negative multiply, Negative accumulate XX3-form (xvf16ger2nn AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF16GER2NP, 0xfc0007f800000000, 0xec00029000000000, 0x60000100000000, // VSX Vector 16-bit Floating-Point GER (rank-2 update) Negative multiply, Positive accumulate XX3-form (xvf16ger2np AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF16GER2PN, 0xfc0007f800000000, 0xec00049000000000, 0x60000100000000, // VSX Vector 16-bit Floating-Point GER (rank-2 update) Positive multiply, Negative accumulate XX3-form (xvf16ger2pn AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF16GER2PP, 0xfc0007f800000000, 0xec00009000000000, 0x60000100000000, // VSX Vector 16-bit Floating-Point GER (rank-2 update) Positive multiply, Positive accumulate XX3-form (xvf16ger2pp AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF32GER, 0xfc0007f800000000, 0xec0000d800000000, 0x60000100000000, // VSX Vector 32-bit Floating-Point GER (rank-1 update) XX3-form (xvf32ger AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF32GERNN, 0xfc0007f800000000, 0xec0006d000000000, 0x60000100000000, // VSX Vector 32-bit Floating-Point GER (rank-1 update) Negative multiply, Negative accumulate XX3-form (xvf32gernn AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF32GERNP, 0xfc0007f800000000, 0xec0002d000000000, 0x60000100000000, // VSX Vector 32-bit Floating-Point GER (rank-1 update) Negative multiply, Positive accumulate XX3-form (xvf32gernp AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF32GERPN, 0xfc0007f800000000, 0xec0004d000000000, 0x60000100000000, // VSX Vector 32-bit Floating-Point GER (rank-1 update) Positive multiply, Negative accumulate XX3-form (xvf32gerpn AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF32GERPP, 0xfc0007f800000000, 0xec0000d000000000, 0x60000100000000, // VSX Vector 32-bit Floating-Point GER (rank-1 update) Positive multiply, Positive accumulate XX3-form (xvf32gerpp AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF64GER, 0xfc0007f800000000, 0xec0001d800000000, 0x60000100000000, // VSX Vector 64-bit Floating-Point GER (rank-1 update) XX3-form (xvf64ger AT,XAp,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF64GERNN, 0xfc0007f800000000, 0xec0007d000000000, 0x60000100000000, // VSX Vector 64-bit Floating-Point GER (rank-1 update) Negative multiply, Negative accumulate XX3-form (xvf64gernn AT,XAp,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF64GERNP, 0xfc0007f800000000, 0xec0003d000000000, 0x60000100000000, // VSX Vector 64-bit Floating-Point GER (rank-1 update) Negative multiply, Positive accumulate XX3-form (xvf64gernp AT,XAp,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF64GERPN, 0xfc0007f800000000, 0xec0005d000000000, 0x60000100000000, // VSX Vector 64-bit Floating-Point GER (rank-1 update) Positive multiply, Negative accumulate XX3-form (xvf64gerpn AT,XAp,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVF64GERPP, 0xfc0007f800000000, 0xec0001d000000000, 0x60000100000000, // VSX Vector 64-bit Floating-Point GER (rank-1 update) Positive multiply, Positive accumulate XX3-form (xvf64gerpp AT,XAp,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVI16GER2, 0xfc0007f800000000, 0xec00025800000000, 0x60000100000000, // VSX Vector 16-bit Signed Integer GER (rank-2 update) XX3-form (xvi16ger2 AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVI16GER2PP, 0xfc0007f800000000, 0xec00035800000000, 0x60000100000000, // VSX Vector 16-bit Signed Integer GER (rank-2 update) Positive multiply, Positive accumulate XX3-form (xvi16ger2pp AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVI16GER2S, 0xfc0007f800000000, 0xec00015800000000, 0x60000100000000, // VSX Vector 16-bit Signed Integer GER (rank-2 update) with Saturation XX3-form (xvi16ger2s AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVI16GER2SPP, 0xfc0007f800000000, 0xec00015000000000, 0x60000100000000, // VSX Vector 16-bit Signed Integer GER (rank-2 update) with Saturation Positive multiply, Positive accumulate XX3-form (xvi16ger2spp AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVI4GER8, 0xfc0007f800000000, 0xec00011800000000, 0x60000100000000, // VSX Vector 4-bit Signed Integer GER (rank-8 update) XX3-form (xvi4ger8 AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVI4GER8PP, 0xfc0007f800000000, 0xec00011000000000, 0x60000100000000, // VSX Vector 4-bit Signed Integer GER (rank-8 update) Positive multiply, Positive accumulate XX3-form (xvi4ger8pp AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVI8GER4, 0xfc0007f800000000, 0xec00001800000000, 0x60000100000000, // VSX Vector 8-bit Signed/Unsigned Integer GER (rank-4 update) XX3-form (xvi8ger4 AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVI8GER4PP, 0xfc0007f800000000, 0xec00001000000000, 0x60000100000000, // VSX Vector 8-bit Signed/Unsigned Integer GER (rank-4 update) Positive multiply, Positive accumulate XX3-form (xvi8ger4pp AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVI8GER4SPP, 0xfc0007f800000000, 0xec00031800000000, 0x60000100000000, // VSX Vector 8-bit Signed/Unsigned Integer GER (rank-4 update) with Saturate Positive multiply, Positive accumulate XX3-form (xvi8ger4spp AT,XA,XB)
+		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVTLSBB, 0xfc1f07fc00000000, 0xf002076c00000000, 0x60000100000000, // VSX Vector Test Least-Significant Bit by Byte XX2-form (xvtlsbb BF,XB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecSReg_30_30_16_20}},
+	{XXBLENDVB, 0xfff00000fc000030, 0x500000084000000, 0xfffff00000000, // VSX Vector Blend Variable Byte 8RR:XX4-form (xxblendvb XT,XA,XB,XC)
+		[6]*argField{ap_VecSReg_63_63_38_42, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_VecSReg_60_60_53_57}},
+	{XXBLENDVD, 0xfff00000fc000030, 0x500000084000030, 0xfffff00000000, // VSX Vector Blend Variable Doubleword 8RR:XX4-form (xxblendvd XT,XA,XB,XC)
+		[6]*argField{ap_VecSReg_63_63_38_42, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_VecSReg_60_60_53_57}},
+	{XXBLENDVH, 0xfff00000fc000030, 0x500000084000010, 0xfffff00000000, // VSX Vector Blend Variable Halfword 8RR:XX4-form (xxblendvh XT,XA,XB,XC)
+		[6]*argField{ap_VecSReg_63_63_38_42, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_VecSReg_60_60_53_57}},
+	{XXBLENDVW, 0xfff00000fc000030, 0x500000084000020, 0xfffff00000000, // VSX Vector Blend Variable Word 8RR:XX4-form (xxblendvw XT,XA,XB,XC)
+		[6]*argField{ap_VecSReg_63_63_38_42, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_VecSReg_60_60_53_57}},
+	{XXEVAL, 0xfff00000fc000030, 0x500000088000010, 0xfff0000000000, // VSX Vector Evaluate 8RR-XX4-form (xxeval XT,XA,XB,XC,IMM)
+		[6]*argField{ap_VecSReg_63_63_38_42, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_VecSReg_60_60_53_57, ap_ImmUnsigned_24_31}},
+	{XXGENPCVBM, 0xfc0007fe00000000, 0xf000072800000000, 0x0, // VSX Vector Generate PCV from Byte Mask X-form (xxgenpcvbm XT,VRB,IMM)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}},
+	{XXGENPCVDM, 0xfc0007fe00000000, 0xf000076a00000000, 0x0, // VSX Vector Generate PCV from Doubleword Mask X-form (xxgenpcvdm XT,VRB,IMM)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}},
+	{XXGENPCVHM, 0xfc0007fe00000000, 0xf000072a00000000, 0x0, // VSX Vector Generate PCV from Halfword Mask X-form (xxgenpcvhm XT,VRB,IMM)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}},
+	{XXGENPCVWM, 0xfc0007fe00000000, 0xf000076800000000, 0x0, // VSX Vector Generate PCV from Word Mask X-form (xxgenpcvwm XT,VRB,IMM)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}},
+	{XXMFACC, 0xfc1f07fe00000000, 0x7c00016200000000, 0x60f80100000000, // VSX Move From Accumulator X-form (xxmfacc AS)
+		[6]*argField{ap_MMAReg_6_8}},
+	{XXMTACC, 0xfc1f07fe00000000, 0x7c01016200000000, 0x60f80100000000, // VSX Move To Accumulator X-form (xxmtacc AT)
+		[6]*argField{ap_MMAReg_6_8}},
+	{XXPERMX, 0xfff00000fc000030, 0x500000088000000, 0xffff800000000, // VSX Vector Permute Extended 8RR:XX4-form (xxpermx XT,XA,XB,XC,UIM)
+		[6]*argField{ap_VecSReg_63_63_38_42, ap_VecSReg_61_61_43_47, ap_VecSReg_62_62_48_52, ap_VecSReg_60_60_53_57, ap_ImmUnsigned_29_31}},
+	{XXSETACCZ, 0xfc1f07fe00000000, 0x7c03016200000000, 0x60f80100000000, // VSX Set Accumulator to Zero X-form (xxsetaccz AT)
+		[6]*argField{ap_MMAReg_6_8}},
+	{XXSPLTI32DX, 0xfff00000fc1c0000, 0x500000080000000, 0xf000000000000, // VSX Vector Splat Immediate32 Doubleword Indexed 8RR:D-form (xxsplti32dx XT,IX,IMM32)
+		[6]*argField{ap_VecSReg_47_47_38_42, ap_ImmUnsigned_46_46, ap_ImmUnsigned_16_31_48_63}},
+	{XXSPLTIDP, 0xfff00000fc1e0000, 0x500000080040000, 0xf000000000000, // VSX Vector Splat Immediate Double-Precision 8RR:D-form (xxspltidp XT,IMM32)
+		[6]*argField{ap_VecSReg_47_47_38_42, ap_ImmUnsigned_16_31_48_63}},
+	{XXSPLTIW, 0xfff00000fc1e0000, 0x500000080060000, 0xf000000000000, // VSX Vector Splat Immediate Word 8RR:D-form (xxspltiw XT,IMM32)
+		[6]*argField{ap_VecSReg_47_47_38_42, ap_ImmUnsigned_16_31_48_63}},
+	{MSGCLRU, 0xfc0007fe00000000, 0x7c0000dc00000000, 0x3ff000100000000, // Ultravisor Message Clear X-form (msgclru RB)
+		[6]*argField{ap_Reg_16_20}},
+	{MSGSNDU, 0xfc0007fe00000000, 0x7c00009c00000000, 0x3ff000100000000, // Ultravisor Message SendX-form (msgsndu RB)
+		[6]*argField{ap_Reg_16_20}},
+	{URFID, 0xfc0007fe00000000, 0x4c00026400000000, 0x3fff80100000000, // Ultravisor Return From Interrupt Doubleword XL-form (urfid)
+		[6]*argField{}},
+	{ADDEX, 0xfc0001fe00000000, 0x7c00015400000000, 0x100000000, // Add Extended using alternate carry bit Z23-form (addex RT,RA,RB,CY)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_21_22}},
+	{MFFSCDRN, 0xfc1f07fe00000000, 0xfc14048e00000000, 0x100000000, // Move From FPSCR Control & Set DRN X-form (mffscdrn FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{MFFSCDRNI, 0xfc1f07fe00000000, 0xfc15048e00000000, 0xc00100000000, // Move From FPSCR Control & Set DRN Immediate X-form (mffscdrni FRT,DRM)
+		[6]*argField{ap_FPReg_6_10, ap_ImmUnsigned_18_20}},
+	{MFFSCE, 0xfc1f07fe00000000, 0xfc01048e00000000, 0xf80100000000, // Move From FPSCR & Clear Enables X-form (mffsce FRT)
+		[6]*argField{ap_FPReg_6_10}},
+	{MFFSCRN, 0xfc1f07fe00000000, 0xfc16048e00000000, 0x100000000, // Move From FPSCR Control & Set RN X-form (mffscrn FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{MFFSCRNI, 0xfc1f07fe00000000, 0xfc17048e00000000, 0xe00100000000, // Move From FPSCR Control & Set RN Immediate X-form (mffscrni FRT,RM)
+		[6]*argField{ap_FPReg_6_10, ap_ImmUnsigned_19_20}},
+	{MFFSL, 0xfc1f07fe00000000, 0xfc18048e00000000, 0xf80100000000, // Move From FPSCR Lightweight X-form (mffsl FRT)
+		[6]*argField{ap_FPReg_6_10}},
+	{SLBIAG, 0xfc0007fe00000000, 0x7c0006a400000000, 0x1ef80100000000, // SLB Invalidate All Global X-form (slbiag RS, L)
+		[6]*argField{ap_Reg_6_10, ap_ImmUnsigned_15_15}},
+	{VMSUMUDM, 0xfc00003f00000000, 0x1000002300000000, 0x0, // Vector Multiply-Sum Unsigned Doubleword Modulo VA-form (vmsumudm VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{ADDPCIS, 0xfc00003e00000000, 0x4c00000400000000, 0x0, // Add PC Immediate Shifted DX-form (addpcis RT,D)
+		[6]*argField{ap_Reg_6_10, ap_ImmSigned_16_25_11_15_31_31}},
+	{BCDCFNCC, 0xfc1f05ff00000000, 0x1007058100000000, 0x0, // Decimal Convert From National VX-form (bcdcfn. VRT,VRB,PS)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
+	{BCDCFSQCC, 0xfc1f05ff00000000, 0x1002058100000000, 0x0, // Decimal Convert From Signed Quadword VX-form (bcdcfsq. VRT,VRB,PS)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
+	{BCDCFZCC, 0xfc1f05ff00000000, 0x1006058100000000, 0x0, // Decimal Convert From Zoned VX-form (bcdcfz. VRT,VRB,PS)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
+	{BCDCPSGNCC, 0xfc0007ff00000000, 0x1000034100000000, 0x0, // Decimal Copy Sign VX-form (bcdcpsgn. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{BCDCTNCC, 0xfc1f05ff00000000, 0x1005058100000000, 0x20000000000, // Decimal Convert To National VX-form (bcdctn. VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{BCDCTSQCC, 0xfc1f05ff00000000, 0x1000058100000000, 0x20000000000, // Decimal Convert To Signed Quadword VX-form (bcdctsq. VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{BCDCTZCC, 0xfc1f05ff00000000, 0x1004058100000000, 0x0, // Decimal Convert To Zoned VX-form (bcdctz. VRT,VRB,PS)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
+	{BCDSCC, 0xfc0005ff00000000, 0x100004c100000000, 0x0, // Decimal Shift VX-form (bcds. VRT,VRA,VRB,PS)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
+	{BCDSETSGNCC, 0xfc1f05ff00000000, 0x101f058100000000, 0x0, // Decimal Set Sign VX-form (bcdsetsgn. VRT,VRB,PS)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
+	{BCDSRCC, 0xfc0005ff00000000, 0x100005c100000000, 0x0, // Decimal Shift and Round VX-form (bcdsr. VRT,VRA,VRB,PS)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
+	{BCDTRUNCCC, 0xfc0005ff00000000, 0x1000050100000000, 0x0, // Decimal Truncate VX-form (bcdtrunc. VRT,VRA,VRB,PS)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
+	{BCDUSCC, 0xfc0005ff00000000, 0x1000048100000000, 0x20000000000, // Decimal Unsigned Shift VX-form (bcdus. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{BCDUTRUNCCC, 0xfc0005ff00000000, 0x1000054100000000, 0x20000000000, // Decimal Unsigned Truncate VX-form (bcdutrunc. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{CMPEQB, 0xfc0007fe00000000, 0x7c0001c000000000, 0x60000100000000, // Compare Equal Byte X-form (cmpeqb BF,RA,RB)
+		[6]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
+	{CMPRB, 0xfc0007fe00000000, 0x7c00018000000000, 0x40000100000000, // Compare Ranged Byte X-form (cmprb BF,L,RA,RB)
+		[6]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_10_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{CNTTZD, 0xfc0007ff00000000, 0x7c00047400000000, 0xf80000000000, // Count Trailing Zeros Doubleword X-form (cnttzd RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{CNTTZDCC, 0xfc0007ff00000000, 0x7c00047500000000, 0xf80000000000, // Count Trailing Zeros Doubleword X-form (cnttzd. RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{CNTTZW, 0xfc0007ff00000000, 0x7c00043400000000, 0xf80000000000, // Count Trailing Zeros Word X-form (cnttzw RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{CNTTZWCC, 0xfc0007ff00000000, 0x7c00043500000000, 0xf80000000000, // Count Trailing Zeros Word X-form (cnttzw. RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{COPY, 0xfc2007fe00000000, 0x7c20060c00000000, 0x3c0000100000000, // Copy X-form (copy RA,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_16_20}},
+	{CPABORT, 0xfc0007fe00000000, 0x7c00068c00000000, 0x3fff80100000000, // Copy-Paste Abort X-form (cpabort)
+		[6]*argField{}},
+	{DARN, 0xfc0007fe00000000, 0x7c0005e600000000, 0x1cf80100000000, // Deliver A Random Number X-form (darn RT,L)
+		[6]*argField{ap_Reg_6_10, ap_ImmUnsigned_14_15}},
+	{DTSTSFI, 0xfc0007fe00000000, 0xec00054600000000, 0x40000100000000, // DFP Test Significance Immediate X-form (dtstsfi BF,UIM,FRB)
+		[6]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_10_15, ap_FPReg_16_20}},
+	{DTSTSFIQ, 0xfc0007fe00000000, 0xfc00054600000000, 0x40000100000000, // DFP Test Significance Immediate Quad X-form (dtstsfiq BF,UIM,FRBp)
+		[6]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_10_15, ap_FPReg_16_20}},
+	{EXTSWSLI, 0xfc0007fd00000000, 0x7c0006f400000000, 0x0, // Extend Sign Word and Shift Left Immediate XS-form (extswsli RA,RS,SH)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20}},
+	{EXTSWSLICC, 0xfc0007fd00000000, 0x7c0006f500000000, 0x0, // Extend Sign Word and Shift Left Immediate XS-form (extswsli. RA,RS,SH)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20}},
+	{LDAT, 0xfc0007fe00000000, 0x7c0004cc00000000, 0x100000000, // Load Doubleword ATomic X-form (ldat RT,RA,FC)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}},
+	{LWAT, 0xfc0007fe00000000, 0x7c00048c00000000, 0x100000000, // Load Word ATomic X-form (lwat RT,RA,FC)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}},
+	{LXSD, 0xfc00000300000000, 0xe400000200000000, 0x0, // Load VSX Scalar Doubleword DS-form (lxsd VRT,DS(RA))
+		[6]*argField{ap_VecReg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
+	{LXSIBZX, 0xfc0007fe00000000, 0x7c00061a00000000, 0x0, // Load VSX Scalar as Integer Byte & Zero Indexed X-form (lxsibzx XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXSIHZX, 0xfc0007fe00000000, 0x7c00065a00000000, 0x0, // Load VSX Scalar as Integer Halfword & Zero Indexed X-form (lxsihzx XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXSSP, 0xfc00000300000000, 0xe400000300000000, 0x0, // Load VSX Scalar Single-Precision DS-form (lxssp VRT,DS(RA))
+		[6]*argField{ap_VecReg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
+	{LXV, 0xfc00000700000000, 0xf400000100000000, 0x0, // Load VSX Vector DQ-form (lxv XT,DQ(RA))
+		[6]*argField{ap_VecSReg_28_28_6_10, ap_Offset_16_27_shift4, ap_Reg_11_15}},
+	{LXVB16X, 0xfc0007fe00000000, 0x7c0006d800000000, 0x0, // Load VSX Vector Byte*16 Indexed X-form (lxvb16x XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVH8X, 0xfc0007fe00000000, 0x7c00065800000000, 0x0, // Load VSX Vector Halfword*8 Indexed X-form (lxvh8x XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVL, 0xfc0007fe00000000, 0x7c00021a00000000, 0x0, // Load VSX Vector with Length X-form (lxvl XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVLL, 0xfc0007fe00000000, 0x7c00025a00000000, 0x0, // Load VSX Vector with Length Left-justified X-form (lxvll XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVWSX, 0xfc0007fe00000000, 0x7c0002d800000000, 0x0, // Load VSX Vector Word & Splat Indexed X-form (lxvwsx XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVX, 0xfc0007be00000000, 0x7c00021800000000, 0x4000000000, // Load VSX Vector Indexed X-form (lxvx XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MADDHD, 0xfc00003f00000000, 0x1000003000000000, 0x0, // Multiply-Add High Doubleword VA-form (maddhd RT,RA,RB,RC)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_Reg_21_25}},
+	{MADDHDU, 0xfc00003f00000000, 0x1000003100000000, 0x0, // Multiply-Add High Doubleword Unsigned VA-form (maddhdu RT,RA,RB,RC)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_Reg_21_25}},
+	{MADDLD, 0xfc00003f00000000, 0x1000003300000000, 0x0, // Multiply-Add Low Doubleword VA-form (maddld RT,RA,RB,RC)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_Reg_21_25}},
+	{MCRXRX, 0xfc0007fe00000000, 0x7c00048000000000, 0x7ff80100000000, // Move to CR from XER Extended X-form (mcrxrx BF)
+		[6]*argField{ap_CondRegField_6_8}},
+	{MFVSRLD, 0xfc0007fe00000000, 0x7c00026600000000, 0xf80000000000, // Move From VSR Lower Doubleword X-form (mfvsrld RA,XS)
+		[6]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}},
+	{MODSD, 0xfc0007fe00000000, 0x7c00061200000000, 0x100000000, // Modulo Signed Doubleword X-form (modsd RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MODSW, 0xfc0007fe00000000, 0x7c00061600000000, 0x100000000, // Modulo Signed Word X-form (modsw RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MODUD, 0xfc0007fe00000000, 0x7c00021200000000, 0x100000000, // Modulo Unsigned Doubleword X-form (modud RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MODUW, 0xfc0007fe00000000, 0x7c00021600000000, 0x100000000, // Modulo Unsigned Word X-form (moduw RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MSGSYNC, 0xfc0007fe00000000, 0x7c0006ec00000000, 0x3fff80100000000, // Message Synchronize X-form (msgsync)
+		[6]*argField{}},
+	{MTVSRDD, 0xfc0007fe00000000, 0x7c00036600000000, 0x0, // Move To VSR Double Doubleword X-form (mtvsrdd XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MTVSRWS, 0xfc0007fe00000000, 0x7c00032600000000, 0xf80000000000, // Move To VSR Word & Splat X-form (mtvsrws XT,RA)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}},
+	{PASTECC, 0xfc0007ff00000000, 0x7c00070d00000000, 0x3c0000000000000, // Paste X-form (paste. RA,RB,L)
+		[6]*argField{ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_10_10}},
+	{SETB, 0xfc0007fe00000000, 0x7c00010000000000, 0x3f80100000000, // Set Boolean X-form (setb RT,BFA)
+		[6]*argField{ap_Reg_6_10, ap_CondRegField_11_13}},
+	{SLBIEG, 0xfc0007fe00000000, 0x7c0003a400000000, 0x1f000100000000, // SLB Invalidate Entry Global X-form (slbieg RS,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_16_20}},
+	{SLBSYNC, 0xfc0007fe00000000, 0x7c0002a400000000, 0x3fff80100000000, // SLB Synchronize X-form (slbsync)
+		[6]*argField{}},
+	{STDAT, 0xfc0007fe00000000, 0x7c0005cc00000000, 0x100000000, // Store Doubleword ATomic X-form (stdat RS,RA,FC)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}},
+	{STOP, 0xfc0007fe00000000, 0x4c0002e400000000, 0x3fff80100000000, // Stop XL-form (stop)
+		[6]*argField{}},
+	{STWAT, 0xfc0007fe00000000, 0x7c00058c00000000, 0x100000000, // Store Word ATomic X-form (stwat RS,RA,FC)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}},
+	{STXSD, 0xfc00000300000000, 0xf400000200000000, 0x0, // Store VSX Scalar Doubleword DS-form (stxsd VRS,DS(RA))
+		[6]*argField{ap_VecReg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
+	{STXSIBX, 0xfc0007fe00000000, 0x7c00071a00000000, 0x0, // Store VSX Scalar as Integer Byte Indexed X-form (stxsibx XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXSIHX, 0xfc0007fe00000000, 0x7c00075a00000000, 0x0, // Store VSX Scalar as Integer Halfword Indexed X-form (stxsihx XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXSSP, 0xfc00000300000000, 0xf400000300000000, 0x0, // Store VSX Scalar Single DS-form (stxssp VRS,DS(RA))
+		[6]*argField{ap_VecReg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
+	{STXV, 0xfc00000700000000, 0xf400000500000000, 0x0, // Store VSX Vector DQ-form (stxv XS,DQ(RA))
+		[6]*argField{ap_VecSReg_28_28_6_10, ap_Offset_16_27_shift4, ap_Reg_11_15}},
+	{STXVB16X, 0xfc0007fe00000000, 0x7c0007d800000000, 0x0, // Store VSX Vector Byte*16 Indexed X-form (stxvb16x XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXVH8X, 0xfc0007fe00000000, 0x7c00075800000000, 0x0, // Store VSX Vector Halfword*8 Indexed X-form (stxvh8x XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXVL, 0xfc0007fe00000000, 0x7c00031a00000000, 0x0, // Store VSX Vector with Length X-form (stxvl XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXVLL, 0xfc0007fe00000000, 0x7c00035a00000000, 0x0, // Store VSX Vector with Length Left-justified X-form (stxvll XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXVX, 0xfc0007fe00000000, 0x7c00031800000000, 0x0, // Store VSX Vector Indexed X-form (stxvx XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{VABSDUB, 0xfc0007ff00000000, 0x1000040300000000, 0x0, // Vector Absolute Difference Unsigned Byte VX-form (vabsdub VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VABSDUH, 0xfc0007ff00000000, 0x1000044300000000, 0x0, // Vector Absolute Difference Unsigned Halfword VX-form (vabsduh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VABSDUW, 0xfc0007ff00000000, 0x1000048300000000, 0x0, // Vector Absolute Difference Unsigned Word VX-form (vabsduw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VBPERMD, 0xfc0007ff00000000, 0x100005cc00000000, 0x0, // Vector Bit Permute Doubleword VX-form (vbpermd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCLZLSBB, 0xfc1f07ff00000000, 0x1000060200000000, 0x0, // Vector Count Leading Zero Least-Significant Bits Byte VX-form (vclzlsbb RT,VRB)
+		[6]*argField{ap_Reg_6_10, ap_VecReg_16_20}},
+	{VCMPNEB, 0xfc0007ff00000000, 0x1000000700000000, 0x0, // Vector Compare Not Equal Byte VC-form (vcmpneb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEBCC, 0xfc0007ff00000000, 0x1000040700000000, 0x0, // Vector Compare Not Equal Byte VC-form (vcmpneb. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEH, 0xfc0007ff00000000, 0x1000004700000000, 0x0, // Vector Compare Not Equal Halfword VC-form (vcmpneh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEHCC, 0xfc0007ff00000000, 0x1000044700000000, 0x0, // Vector Compare Not Equal Halfword VC-form (vcmpneh. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEW, 0xfc0007ff00000000, 0x1000008700000000, 0x0, // Vector Compare Not Equal Word VC-form (vcmpnew VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEWCC, 0xfc0007ff00000000, 0x1000048700000000, 0x0, // Vector Compare Not Equal Word VC-form (vcmpnew. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEZB, 0xfc0007ff00000000, 0x1000010700000000, 0x0, // Vector Compare Not Equal or Zero Byte VC-form (vcmpnezb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEZBCC, 0xfc0007ff00000000, 0x1000050700000000, 0x0, // Vector Compare Not Equal or Zero Byte VC-form (vcmpnezb. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEZH, 0xfc0007ff00000000, 0x1000014700000000, 0x0, // Vector Compare Not Equal or Zero Halfword VC-form (vcmpnezh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEZHCC, 0xfc0007ff00000000, 0x1000054700000000, 0x0, // Vector Compare Not Equal or Zero Halfword VC-form (vcmpnezh. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEZW, 0xfc0007ff00000000, 0x1000018700000000, 0x0, // Vector Compare Not Equal or Zero Word VC-form (vcmpnezw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEZWCC, 0xfc0007ff00000000, 0x1000058700000000, 0x0, // Vector Compare Not Equal or Zero Word VC-form (vcmpnezw. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCTZB, 0xfc1f07ff00000000, 0x101c060200000000, 0x0, // Vector Count Trailing Zeros Byte VX-form (vctzb VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VCTZD, 0xfc1f07ff00000000, 0x101f060200000000, 0x0, // Vector Count Trailing Zeros Doubleword VX-form (vctzd VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VCTZH, 0xfc1f07ff00000000, 0x101d060200000000, 0x0, // Vector Count Trailing Zeros Halfword VX-form (vctzh VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VCTZLSBB, 0xfc1f07ff00000000, 0x1001060200000000, 0x0, // Vector Count Trailing Zero Least-Significant Bits Byte VX-form (vctzlsbb RT,VRB)
+		[6]*argField{ap_Reg_6_10, ap_VecReg_16_20}},
+	{VCTZW, 0xfc1f07ff00000000, 0x101e060200000000, 0x0, // Vector Count Trailing Zeros Word VX-form (vctzw VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VEXTRACTD, 0xfc0007ff00000000, 0x100002cd00000000, 0x10000000000000, // Vector Extract Doubleword to VSR using immediate-specified index VX-form (vextractd VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_12_15}},
+	{VEXTRACTUB, 0xfc0007ff00000000, 0x1000020d00000000, 0x10000000000000, // Vector Extract Unsigned Byte to VSR using immediate-specified index VX-form (vextractub VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_12_15}},
+	{VEXTRACTUH, 0xfc0007ff00000000, 0x1000024d00000000, 0x10000000000000, // Vector Extract Unsigned Halfword to VSR using immediate-specified index VX-form (vextractuh VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_12_15}},
+	{VEXTRACTUW, 0xfc0007ff00000000, 0x1000028d00000000, 0x10000000000000, // Vector Extract Unsigned Word to VSR using immediate-specified index VX-form (vextractuw VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_12_15}},
+	{VEXTSB2D, 0xfc1f07ff00000000, 0x1018060200000000, 0x0, // Vector Extend Sign Byte To Doubleword VX-form (vextsb2d VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VEXTSB2W, 0xfc1f07ff00000000, 0x1010060200000000, 0x0, // Vector Extend Sign Byte To Word VX-form (vextsb2w VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VEXTSH2D, 0xfc1f07ff00000000, 0x1019060200000000, 0x0, // Vector Extend Sign Halfword To Doubleword VX-form (vextsh2d VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VEXTSH2W, 0xfc1f07ff00000000, 0x1011060200000000, 0x0, // Vector Extend Sign Halfword To Word VX-form (vextsh2w VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VEXTSW2D, 0xfc1f07ff00000000, 0x101a060200000000, 0x0, // Vector Extend Sign Word To Doubleword VX-form (vextsw2d VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VEXTUBLX, 0xfc0007ff00000000, 0x1000060d00000000, 0x0, // Vector Extract Unsigned Byte to GPR using GPR-specified Left-Index VX-form (vextublx RT,RA,VRB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_VecReg_16_20}},
+	{VEXTUBRX, 0xfc0007ff00000000, 0x1000070d00000000, 0x0, // Vector Extract Unsigned Byte to GPR using GPR-specified Right-Index VX-form (vextubrx RT,RA,VRB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_VecReg_16_20}},
+	{VEXTUHLX, 0xfc0007ff00000000, 0x1000064d00000000, 0x0, // Vector Extract Unsigned Halfword to GPR using GPR-specified Left-Index VX-form (vextuhlx RT,RA,VRB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_VecReg_16_20}},
+	{VEXTUHRX, 0xfc0007ff00000000, 0x1000074d00000000, 0x0, // Vector Extract Unsigned Halfword to GPR using GPR-specified Right-Index VX-form (vextuhrx RT,RA,VRB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_VecReg_16_20}},
+	{VEXTUWLX, 0xfc0007ff00000000, 0x1000068d00000000, 0x0, // Vector Extract Unsigned Word to GPR using GPR-specified Left-Index VX-form (vextuwlx RT,RA,VRB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_VecReg_16_20}},
+	{VEXTUWRX, 0xfc0007ff00000000, 0x1000078d00000000, 0x0, // Vector Extract Unsigned Word to GPR using GPR-specified Right-Index VX-form (vextuwrx RT,RA,VRB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_VecReg_16_20}},
+	{VINSERTB, 0xfc0007ff00000000, 0x1000030d00000000, 0x10000000000000, // Vector Insert Byte from VSR using immediate-specified index VX-form (vinsertb VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_12_15}},
+	{VINSERTD, 0xfc0007ff00000000, 0x100003cd00000000, 0x10000000000000, // Vector Insert Doubleword from VSR using immediate-specified index VX-form (vinsertd VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_12_15}},
+	{VINSERTH, 0xfc0007ff00000000, 0x1000034d00000000, 0x10000000000000, // Vector Insert Halfword from VSR using immediate-specified index VX-form (vinserth VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_12_15}},
+	{VINSERTW, 0xfc0007ff00000000, 0x1000038d00000000, 0x10000000000000, // Vector Insert Word from VSR using immediate-specified index VX-form (vinsertw VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_12_15}},
+	{VMUL10CUQ, 0xfc0007ff00000000, 0x1000000100000000, 0xf80000000000, // Vector Multiply-by-10 & write Carry-out Unsigned Quadword VX-form (vmul10cuq VRT,VRA)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15}},
+	{VMUL10ECUQ, 0xfc0007ff00000000, 0x1000004100000000, 0x0, // Vector Multiply-by-10 Extended & write Carry-out Unsigned Quadword VX-form (vmul10ecuq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMUL10EUQ, 0xfc0007ff00000000, 0x1000024100000000, 0x0, // Vector Multiply-by-10 Extended Unsigned Quadword VX-form (vmul10euq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMUL10UQ, 0xfc0007ff00000000, 0x1000020100000000, 0xf80000000000, // Vector Multiply-by-10 Unsigned Quadword VX-form (vmul10uq VRT,VRA)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15}},
+	{VNEGD, 0xfc1f07ff00000000, 0x1007060200000000, 0x0, // Vector Negate Doubleword VX-form (vnegd VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VNEGW, 0xfc1f07ff00000000, 0x1006060200000000, 0x0, // Vector Negate Word VX-form (vnegw VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VPERMR, 0xfc00003f00000000, 0x1000003b00000000, 0x0, // Vector Permute Right-indexed VA-form (vpermr VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VPRTYBD, 0xfc1f07ff00000000, 0x1009060200000000, 0x0, // Vector Parity Byte Doubleword VX-form (vprtybd VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VPRTYBQ, 0xfc1f07ff00000000, 0x100a060200000000, 0x0, // Vector Parity Byte Quadword VX-form (vprtybq VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VPRTYBW, 0xfc1f07ff00000000, 0x1008060200000000, 0x0, // Vector Parity Byte Word VX-form (vprtybw VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VRLDMI, 0xfc0007ff00000000, 0x100000c500000000, 0x0, // Vector Rotate Left Doubleword then Mask Insert VX-form (vrldmi VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VRLDNM, 0xfc0007ff00000000, 0x100001c500000000, 0x0, // Vector Rotate Left Doubleword then AND with Mask VX-form (vrldnm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VRLWMI, 0xfc0007ff00000000, 0x1000008500000000, 0x0, // Vector Rotate Left Word then Mask Insert VX-form (vrlwmi VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VRLWNM, 0xfc0007ff00000000, 0x1000018500000000, 0x0, // Vector Rotate Left Word then AND with Mask VX-form (vrlwnm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSLV, 0xfc0007ff00000000, 0x1000074400000000, 0x0, // Vector Shift Left Variable VX-form (vslv VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSRV, 0xfc0007ff00000000, 0x1000070400000000, 0x0, // Vector Shift Right Variable VX-form (vsrv VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{WAIT, 0xfc0007fe00000000, 0x7c00003c00000000, 0x9cf80100000000, // Wait X-form (wait WC,PL)
+		[6]*argField{ap_ImmUnsigned_9_10, ap_ImmUnsigned_14_15}},
+	{XSABSQP, 0xfc1f07fe00000000, 0xfc00064800000000, 0x100000000, // VSX Scalar Absolute Quad-Precision X-form (xsabsqp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSADDQP, 0xfc0007ff00000000, 0xfc00000800000000, 0x0, // VSX Scalar Add Quad-Precision [using round to Odd] X-form (xsaddqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSADDQPO, 0xfc0007ff00000000, 0xfc00000900000000, 0x0, // VSX Scalar Add Quad-Precision [using round to Odd] X-form (xsaddqpo VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSCMPEQDP, 0xfc0007f800000000, 0xf000001800000000, 0x0, // VSX Scalar Compare Equal Double-Precision XX3-form (xscmpeqdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSCMPEXPDP, 0xfc0007f800000000, 0xf00001d800000000, 0x60000100000000, // VSX Scalar Compare Exponents Double-Precision XX3-form (xscmpexpdp BF,XA,XB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSCMPEXPQP, 0xfc0007fe00000000, 0xfc00014800000000, 0x60000100000000, // VSX Scalar Compare Exponents Quad-Precision X-form (xscmpexpqp BF,VRA,VRB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSCMPGEDP, 0xfc0007f800000000, 0xf000009800000000, 0x0, // VSX Scalar Compare Greater Than or Equal Double-Precision XX3-form (xscmpgedp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSCMPGTDP, 0xfc0007f800000000, 0xf000005800000000, 0x0, // VSX Scalar Compare Greater Than Double-Precision XX3-form (xscmpgtdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSCMPOQP, 0xfc0007fe00000000, 0xfc00010800000000, 0x60000100000000, // VSX Scalar Compare Ordered Quad-Precision X-form (xscmpoqp BF,VRA,VRB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSCMPUQP, 0xfc0007fe00000000, 0xfc00050800000000, 0x60000100000000, // VSX Scalar Compare Unordered Quad-Precision X-form (xscmpuqp BF,VRA,VRB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSCPSGNQP, 0xfc0007fe00000000, 0xfc0000c800000000, 0x100000000, // VSX Scalar Copy Sign Quad-Precision X-form (xscpsgnqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSCVDPHP, 0xfc1f07fc00000000, 0xf011056c00000000, 0x0, // VSX Scalar Convert with round Double-Precision to Half-Precision format XX2-form (xscvdphp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSCVDPQP, 0xfc1f07fe00000000, 0xfc16068800000000, 0x100000000, // VSX Scalar Convert Double-Precision to Quad-Precision format X-form (xscvdpqp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSCVHPDP, 0xfc1f07fc00000000, 0xf010056c00000000, 0x0, // VSX Scalar Convert Half-Precision to Double-Precision format XX2-form (xscvhpdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSCVQPDP, 0xfc1f07ff00000000, 0xfc14068800000000, 0x0, // VSX Scalar Convert with round Quad-Precision to Double-Precision format [using round to Odd] X-form (xscvqpdp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSCVQPDPO, 0xfc1f07ff00000000, 0xfc14068900000000, 0x0, // VSX Scalar Convert with round Quad-Precision to Double-Precision format [using round to Odd] X-form (xscvqpdpo VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSCVQPSDZ, 0xfc1f07fe00000000, 0xfc19068800000000, 0x100000000, // VSX Scalar Convert with round to zero Quad-Precision to Signed Doubleword format X-form (xscvqpsdz VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSCVQPSWZ, 0xfc1f07fe00000000, 0xfc09068800000000, 0x100000000, // VSX Scalar Convert with round to zero Quad-Precision to Signed Word format X-form (xscvqpswz VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSCVQPUDZ, 0xfc1f07fe00000000, 0xfc11068800000000, 0x100000000, // VSX Scalar Convert with round to zero Quad-Precision to Unsigned Doubleword format X-form (xscvqpudz VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSCVQPUWZ, 0xfc1f07fe00000000, 0xfc01068800000000, 0x100000000, // VSX Scalar Convert with round to zero Quad-Precision to Unsigned Word format X-form (xscvqpuwz VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSCVSDQP, 0xfc1f07fe00000000, 0xfc0a068800000000, 0x100000000, // VSX Scalar Convert Signed Doubleword to Quad-Precision format X-form (xscvsdqp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSCVUDQP, 0xfc1f07fe00000000, 0xfc02068800000000, 0x100000000, // VSX Scalar Convert Unsigned Doubleword to Quad-Precision format X-form (xscvudqp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSDIVQP, 0xfc0007ff00000000, 0xfc00044800000000, 0x0, // VSX Scalar Divide Quad-Precision [using round to Odd] X-form (xsdivqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSDIVQPO, 0xfc0007ff00000000, 0xfc00044900000000, 0x0, // VSX Scalar Divide Quad-Precision [using round to Odd] X-form (xsdivqpo VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSIEXPDP, 0xfc0007fe00000000, 0xf000072c00000000, 0x0, // VSX Scalar Insert Exponent Double-Precision X-form (xsiexpdp XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{XSIEXPQP, 0xfc0007fe00000000, 0xfc0006c800000000, 0x100000000, // VSX Scalar Insert Exponent Quad-Precision X-form (xsiexpqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSMADDQP, 0xfc0007ff00000000, 0xfc00030800000000, 0x0, // VSX Scalar Multiply-Add Quad-Precision [using round to Odd] X-form (xsmaddqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSMADDQPO, 0xfc0007ff00000000, 0xfc00030900000000, 0x0, // VSX Scalar Multiply-Add Quad-Precision [using round to Odd] X-form (xsmaddqpo VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSMAXCDP, 0xfc0007f800000000, 0xf000040000000000, 0x0, // VSX Scalar Maximum Type-C Double-Precision XX3-form (xsmaxcdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMAXJDP, 0xfc0007f800000000, 0xf000048000000000, 0x0, // VSX Scalar Maximum Type-J Double-Precision XX3-form (xsmaxjdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMINCDP, 0xfc0007f800000000, 0xf000044000000000, 0x0, // VSX Scalar Minimum Type-C Double-Precision XX3-form (xsmincdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMINJDP, 0xfc0007f800000000, 0xf00004c000000000, 0x0, // VSX Scalar Minimum Type-J Double-Precision XX3-form (xsminjdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMSUBQP, 0xfc0007ff00000000, 0xfc00034800000000, 0x0, // VSX Scalar Multiply-Subtract Quad-Precision [using round to Odd] X-form (xsmsubqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSMSUBQPO, 0xfc0007ff00000000, 0xfc00034900000000, 0x0, // VSX Scalar Multiply-Subtract Quad-Precision [using round to Odd] X-form (xsmsubqpo VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSMULQP, 0xfc0007ff00000000, 0xfc00004800000000, 0x0, // VSX Scalar Multiply Quad-Precision [using round to Odd] X-form (xsmulqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSMULQPO, 0xfc0007ff00000000, 0xfc00004900000000, 0x0, // VSX Scalar Multiply Quad-Precision [using round to Odd] X-form (xsmulqpo VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSNABSQP, 0xfc1f07fe00000000, 0xfc08064800000000, 0x0, // VSX Scalar Negative Absolute Quad-Precision X-form (xsnabsqp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSNEGQP, 0xfc1f07fe00000000, 0xfc10064800000000, 0x100000000, // VSX Scalar Negate Quad-Precision X-form (xsnegqp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSNMADDQP, 0xfc0007ff00000000, 0xfc00038800000000, 0x0, // VSX Scalar Negative Multiply-Add Quad-Precision [using round to Odd] X-form (xsnmaddqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSNMADDQPO, 0xfc0007ff00000000, 0xfc00038900000000, 0x0, // VSX Scalar Negative Multiply-Add Quad-Precision [using round to Odd] X-form (xsnmaddqpo VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSNMSUBQP, 0xfc0007ff00000000, 0xfc0003c800000000, 0x0, // VSX Scalar Negative Multiply-Subtract Quad-Precision [using round to Odd] X-form (xsnmsubqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSNMSUBQPO, 0xfc0007ff00000000, 0xfc0003c900000000, 0x0, // VSX Scalar Negative Multiply-Subtract Quad-Precision [using round to Odd] X-form (xsnmsubqpo VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSRQPI, 0xfc0001ff00000000, 0xfc00000a00000000, 0x1e000000000000, // VSX Scalar Round to Quad-Precision Integer [with Inexact] Z23-form (xsrqpi R,VRT,VRB,RMC)
+		[6]*argField{ap_ImmUnsigned_15_15, ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_21_22}},
+	{XSRQPIX, 0xfc0001ff00000000, 0xfc00000b00000000, 0x1e000000000000, // VSX Scalar Round to Quad-Precision Integer [with Inexact] Z23-form (xsrqpix R,VRT,VRB,RMC)
+		[6]*argField{ap_ImmUnsigned_15_15, ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_21_22}},
+	{XSRQPXP, 0xfc0001fe00000000, 0xfc00004a00000000, 0x1e000100000000, // VSX Scalar Round Quad-Precision to Double-Extended Precision Z23-form (xsrqpxp R,VRT,VRB,RMC)
+		[6]*argField{ap_ImmUnsigned_15_15, ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_21_22}},
+	{XSSQRTQP, 0xfc1f07ff00000000, 0xfc1b064800000000, 0x0, // VSX Scalar Square Root Quad-Precision [using round to Odd] X-form (xssqrtqp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSSQRTQPO, 0xfc1f07ff00000000, 0xfc1b064900000000, 0x0, // VSX Scalar Square Root Quad-Precision [using round to Odd] X-form (xssqrtqpo VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSSUBQP, 0xfc0007ff00000000, 0xfc00040800000000, 0x0, // VSX Scalar Subtract Quad-Precision [using round to Odd] X-form (xssubqp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSSUBQPO, 0xfc0007ff00000000, 0xfc00040900000000, 0x0, // VSX Scalar Subtract Quad-Precision [using round to Odd] X-form (xssubqpo VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{XSTSTDCDP, 0xfc0007fc00000000, 0xf00005a800000000, 0x100000000, // VSX Scalar Test Data Class Double-Precision XX2-form (xststdcdp BF,XB,DCMX)
+		[6]*argField{ap_CondRegField_6_8, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_9_15}},
+	{XSTSTDCQP, 0xfc0007fe00000000, 0xfc00058800000000, 0x100000000, // VSX Scalar Test Data Class Quad-Precision X-form (xststdcqp BF,VRB,DCMX)
+		[6]*argField{ap_CondRegField_6_8, ap_VecReg_16_20, ap_ImmUnsigned_9_15}},
+	{XSTSTDCSP, 0xfc0007fc00000000, 0xf00004a800000000, 0x100000000, // VSX Scalar Test Data Class Single-Precision XX2-form (xststdcsp BF,XB,DCMX)
+		[6]*argField{ap_CondRegField_6_8, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_9_15}},
+	{XSXEXPDP, 0xfc1f07fc00000000, 0xf000056c00000000, 0x100000000, // VSX Scalar Extract Exponent Double-Precision XX2-form (xsxexpdp RT,XB)
+		[6]*argField{ap_Reg_6_10, ap_VecSReg_30_30_16_20}},
+	{XSXEXPQP, 0xfc1f07fe00000000, 0xfc02064800000000, 0x100000000, // VSX Scalar Extract Exponent Quad-Precision X-form (xsxexpqp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSXSIGDP, 0xfc1f07fc00000000, 0xf001056c00000000, 0x100000000, // VSX Scalar Extract Significand Double-Precision XX2-form (xsxsigdp RT,XB)
+		[6]*argField{ap_Reg_6_10, ap_VecSReg_30_30_16_20}},
+	{XSXSIGQP, 0xfc1f07fe00000000, 0xfc12064800000000, 0x100000000, // VSX Scalar Extract Significand Quad-Precision X-form (xsxsigqp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XVCVHPSP, 0xfc1f07fc00000000, 0xf018076c00000000, 0x0, // VSX Vector Convert Half-Precision to Single-Precision format XX2-form (xvcvhpsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVSPHP, 0xfc1f07fc00000000, 0xf019076c00000000, 0x0, // VSX Vector Convert with round Single-Precision to Half-Precision format XX2-form (xvcvsphp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVIEXPDP, 0xfc0007f800000000, 0xf00007c000000000, 0x0, // VSX Vector Insert Exponent Double-Precision XX3-form (xviexpdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVIEXPSP, 0xfc0007f800000000, 0xf00006c000000000, 0x0, // VSX Vector Insert Exponent Single-Precision XX3-form (xviexpsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVTSTDCDP, 0xfc0007b800000000, 0xf00007a800000000, 0x0, // VSX Vector Test Data Class Double-Precision XX2-form (xvtstdcdp XT,XB,DCMX)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_25_25_29_29_11_15}},
+	{XVTSTDCSP, 0xfc0007b800000000, 0xf00006a800000000, 0x0, // VSX Vector Test Data Class Single-Precision XX2-form (xvtstdcsp XT,XB,DCMX)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_25_25_29_29_11_15}},
+	{XVXEXPDP, 0xfc1f07fc00000000, 0xf000076c00000000, 0x0, // VSX Vector Extract Exponent Double-Precision XX2-form (xvxexpdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVXEXPSP, 0xfc1f07fc00000000, 0xf008076c00000000, 0x0, // VSX Vector Extract Exponent Single-Precision XX2-form (xvxexpsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVXSIGDP, 0xfc1f07fc00000000, 0xf001076c00000000, 0x0, // VSX Vector Extract Significand Double-Precision XX2-form (xvxsigdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVXSIGSP, 0xfc1f07fc00000000, 0xf009076c00000000, 0x0, // VSX Vector Extract Significand Single-Precision XX2-form (xvxsigsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XXBRD, 0xfc1f07fc00000000, 0xf017076c00000000, 0x0, // VSX Vector Byte-Reverse Doubleword XX2-form (xxbrd XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XXBRH, 0xfc1f07fc00000000, 0xf007076c00000000, 0x0, // VSX Vector Byte-Reverse Halfword XX2-form (xxbrh XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XXBRQ, 0xfc1f07fc00000000, 0xf01f076c00000000, 0x0, // VSX Vector Byte-Reverse Quadword XX2-form (xxbrq XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XXBRW, 0xfc1f07fc00000000, 0xf00f076c00000000, 0x0, // VSX Vector Byte-Reverse Word XX2-form (xxbrw XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XXEXTRACTUW, 0xfc0007fc00000000, 0xf000029400000000, 0x10000000000000, // VSX Vector Extract Unsigned Word XX2-form (xxextractuw XT,XB,UIM)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_12_15}},
+	{XXINSERTW, 0xfc0007fc00000000, 0xf00002d400000000, 0x10000000000000, // VSX Vector Insert Word XX2-form (xxinsertw XT,XB,UIM)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_12_15}},
+	{XXPERM, 0xfc0007f800000000, 0xf00000d000000000, 0x0, // VSX Vector Permute XX3-form (xxperm XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XXPERMR, 0xfc0007f800000000, 0xf00001d000000000, 0x0, // VSX Vector Permute Right-indexed XX3-form (xxpermr XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XXSPLTIB, 0xfc1807fe00000000, 0xf00002d000000000, 0x0, // VSX Vector Splat Immediate Byte X-form (xxspltib XT,IMM8)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_ImmUnsigned_13_20}},
+	{BCDADDCC, 0xfc0005ff00000000, 0x1000040100000000, 0x0, // Decimal Add Modulo VX-form (bcdadd. VRT,VRA,VRB,PS)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
+	{BCDSUBCC, 0xfc0005ff00000000, 0x1000044100000000, 0x0, // Decimal Subtract Modulo VX-form (bcdsub. VRT,VRA,VRB,PS)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
+	{BCTAR, 0xfc0007ff00000000, 0x4c00046000000000, 0xe00000000000, // Branch Conditional to Branch Target Address Register XL-form (bctar BO,BI,BH)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}},
+	{BCTARL, 0xfc0007ff00000000, 0x4c00046100000000, 0xe00000000000, // Branch Conditional to Branch Target Address Register XL-form (bctarl BO,BI,BH)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}},
+	{CLRBHRB, 0xfc0007fe00000000, 0x7c00035c00000000, 0x3fff80100000000, // Clear BHRB X-form (clrbhrb)
+		[6]*argField{}},
+	{FMRGEW, 0xfc0007fe00000000, 0xfc00078c00000000, 0x100000000, // Floating Merge Even Word X-form (fmrgew FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FMRGOW, 0xfc0007fe00000000, 0xfc00068c00000000, 0x100000000, // Floating Merge Odd Word X-form (fmrgow FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{ICBT, 0xfc0007fe00000000, 0x7c00002c00000000, 0x200000100000000, // Instruction Cache Block Touch X-form (icbt CT, RA, RB)
+		[6]*argField{ap_ImmUnsigned_7_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LQARX, 0xfc0007fe00000000, 0x7c00022800000000, 0x0, // Load Quadword And Reserve Indexed X-form (lqarx RTp,RA,RB,EH)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}},
+	{LXSIWAX, 0xfc0007fe00000000, 0x7c00009800000000, 0x0, // Load VSX Scalar as Integer Word Algebraic Indexed X-form (lxsiwax XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXSIWZX, 0xfc0007fe00000000, 0x7c00001800000000, 0x0, // Load VSX Scalar as Integer Word & Zero Indexed X-form (lxsiwzx XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXSSPX, 0xfc0007fe00000000, 0x7c00041800000000, 0x0, // Load VSX Scalar Single-Precision Indexed X-form (lxsspx XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MFBHRBE, 0xfc0007fe00000000, 0x7c00025c00000000, 0x100000000, // Move From BHRB XFX-form (mfbhrbe RT,BHRBE)
+		[6]*argField{ap_Reg_6_10, ap_SpReg_11_20}},
+	{MFVSRD, 0xfc0007fe00000000, 0x7c00006600000000, 0xf80000000000, // Move From VSR Doubleword X-form (mfvsrd RA,XS)
+		[6]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}},
+	{MFVSRWZ, 0xfc0007fe00000000, 0x7c0000e600000000, 0xf80000000000, // Move From VSR Word and Zero X-form (mfvsrwz RA,XS)
+		[6]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}},
+	{MSGCLR, 0xfc0007fe00000000, 0x7c0001dc00000000, 0x3ff000100000000, // Message Clear X-form (msgclr RB)
+		[6]*argField{ap_Reg_16_20}},
+	{MSGCLRP, 0xfc0007fe00000000, 0x7c00015c00000000, 0x3ff000100000000, // Message Clear Privileged X-form (msgclrp RB)
+		[6]*argField{ap_Reg_16_20}},
+	{MSGSND, 0xfc0007fe00000000, 0x7c00019c00000000, 0x3ff000100000000, // Message Send X-form (msgsnd RB)
+		[6]*argField{ap_Reg_16_20}},
+	{MSGSNDP, 0xfc0007fe00000000, 0x7c00011c00000000, 0x3ff000100000000, // Message Send Privileged X-form (msgsndp RB)
+		[6]*argField{ap_Reg_16_20}},
+	{MTVSRD, 0xfc0007fe00000000, 0x7c00016600000000, 0xf80000000000, // Move To VSR Doubleword X-form (mtvsrd XT,RA)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}},
+	{MTVSRWA, 0xfc0007fe00000000, 0x7c0001a600000000, 0xf80000000000, // Move To VSR Word Algebraic X-form (mtvsrwa XT,RA)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}},
+	{MTVSRWZ, 0xfc0007fe00000000, 0x7c0001e600000000, 0xf80000000000, // Move To VSR Word and Zero X-form (mtvsrwz XT,RA)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15}},
+	{RFEBB, 0xfc0007fe00000000, 0x4c00012400000000, 0x3fff00100000000, // Return from Event Based Branch XL-form (rfebb S)
+		[6]*argField{ap_ImmUnsigned_20_20}},
+	{STQCXCC, 0xfc0007ff00000000, 0x7c00016d00000000, 0x0, // Store Quadword Conditional Indexed X-form (stqcx. RSp,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXSIWX, 0xfc0007fe00000000, 0x7c00011800000000, 0x0, // Store VSX Scalar as Integer Word Indexed X-form (stxsiwx XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXSSPX, 0xfc0007fe00000000, 0x7c00051800000000, 0x0, // Store VSX Scalar Single-Precision Indexed X-form (stxsspx XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{VADDCUQ, 0xfc0007ff00000000, 0x1000014000000000, 0x0, // Vector Add & write Carry Unsigned Quadword VX-form (vaddcuq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VADDECUQ, 0xfc00003f00000000, 0x1000003d00000000, 0x0, // Vector Add Extended & write Carry Unsigned Quadword VA-form (vaddecuq VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VADDEUQM, 0xfc00003f00000000, 0x1000003c00000000, 0x0, // Vector Add Extended Unsigned Quadword Modulo VA-form (vaddeuqm VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VADDUDM, 0xfc0007ff00000000, 0x100000c000000000, 0x0, // Vector Add Unsigned Doubleword Modulo VX-form (vaddudm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VADDUQM, 0xfc0007ff00000000, 0x1000010000000000, 0x0, // Vector Add Unsigned Quadword Modulo VX-form (vadduqm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VBPERMQ, 0xfc0007ff00000000, 0x1000054c00000000, 0x0, // Vector Bit Permute Quadword VX-form (vbpermq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCIPHER, 0xfc0007ff00000000, 0x1000050800000000, 0x0, // Vector AES Cipher VX-form (vcipher VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCIPHERLAST, 0xfc0007ff00000000, 0x1000050900000000, 0x0, // Vector AES Cipher Last VX-form (vcipherlast VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCLZB, 0xfc0007ff00000000, 0x1000070200000000, 0x1f000000000000, // Vector Count Leading Zeros Byte VX-form (vclzb VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VCLZD, 0xfc0007ff00000000, 0x100007c200000000, 0x1f000000000000, // Vector Count Leading Zeros Doubleword VX-form (vclzd VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VCLZH, 0xfc0007ff00000000, 0x1000074200000000, 0x1f000000000000, // Vector Count Leading Zeros Halfword VX-form (vclzh VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VCLZW, 0xfc0007ff00000000, 0x1000078200000000, 0x1f000000000000, // Vector Count Leading Zeros Word VX-form (vclzw VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VCMPEQUD, 0xfc0007ff00000000, 0x100000c700000000, 0x0, // Vector Compare Equal Unsigned Doubleword VC-form (vcmpequd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPEQUDCC, 0xfc0007ff00000000, 0x100004c700000000, 0x0, // Vector Compare Equal Unsigned Doubleword VC-form (vcmpequd. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTSD, 0xfc0007ff00000000, 0x100003c700000000, 0x0, // Vector Compare Greater Than Signed Doubleword VC-form (vcmpgtsd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTSDCC, 0xfc0007ff00000000, 0x100007c700000000, 0x0, // Vector Compare Greater Than Signed Doubleword VC-form (vcmpgtsd. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTUD, 0xfc0007ff00000000, 0x100002c700000000, 0x0, // Vector Compare Greater Than Unsigned Doubleword VC-form (vcmpgtud VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTUDCC, 0xfc0007ff00000000, 0x100006c700000000, 0x0, // Vector Compare Greater Than Unsigned Doubleword VC-form (vcmpgtud. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VEQV, 0xfc0007ff00000000, 0x1000068400000000, 0x0, // Vector Logical Equivalence VX-form (veqv VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VGBBD, 0xfc0007ff00000000, 0x1000050c00000000, 0x1f000000000000, // Vector Gather Bits by Bytes by Doubleword VX-form (vgbbd VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VMAXSD, 0xfc0007ff00000000, 0x100001c200000000, 0x0, // Vector Maximum Signed Doubleword VX-form (vmaxsd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMAXUD, 0xfc0007ff00000000, 0x100000c200000000, 0x0, // Vector Maximum Unsigned Doubleword VX-form (vmaxud VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMINSD, 0xfc0007ff00000000, 0x100003c200000000, 0x0, // Vector Minimum Signed Doubleword VX-form (vminsd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMINUD, 0xfc0007ff00000000, 0x100002c200000000, 0x0, // Vector Minimum Unsigned Doubleword VX-form (vminud VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMRGEW, 0xfc0007ff00000000, 0x1000078c00000000, 0x0, // Vector Merge Even Word VX-form (vmrgew VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMRGOW, 0xfc0007ff00000000, 0x1000068c00000000, 0x0, // Vector Merge Odd Word VX-form (vmrgow VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULESW, 0xfc0007ff00000000, 0x1000038800000000, 0x0, // Vector Multiply Even Signed Word VX-form (vmulesw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULEUW, 0xfc0007ff00000000, 0x1000028800000000, 0x0, // Vector Multiply Even Unsigned Word VX-form (vmuleuw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULOSW, 0xfc0007ff00000000, 0x1000018800000000, 0x0, // Vector Multiply Odd Signed Word VX-form (vmulosw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULOUW, 0xfc0007ff00000000, 0x1000008800000000, 0x0, // Vector Multiply Odd Unsigned Word VX-form (vmulouw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULUWM, 0xfc0007ff00000000, 0x1000008900000000, 0x0, // Vector Multiply Unsigned Word Modulo VX-form (vmuluwm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VNAND, 0xfc0007ff00000000, 0x1000058400000000, 0x0, // Vector Logical NAND VX-form (vnand VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VNCIPHER, 0xfc0007ff00000000, 0x1000054800000000, 0x0, // Vector AES Inverse Cipher VX-form (vncipher VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VNCIPHERLAST, 0xfc0007ff00000000, 0x1000054900000000, 0x0, // Vector AES Inverse Cipher Last VX-form (vncipherlast VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VORC, 0xfc0007ff00000000, 0x1000054400000000, 0x0, // Vector Logical OR with Complement VX-form (vorc VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPERMXOR, 0xfc00003f00000000, 0x1000002d00000000, 0x0, // Vector Permute & Exclusive-OR VA-form (vpermxor VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VPKSDSS, 0xfc0007ff00000000, 0x100005ce00000000, 0x0, // Vector Pack Signed Doubleword Signed Saturate VX-form (vpksdss VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPKSDUS, 0xfc0007ff00000000, 0x1000054e00000000, 0x0, // Vector Pack Signed Doubleword Unsigned Saturate VX-form (vpksdus VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPKUDUM, 0xfc0007ff00000000, 0x1000044e00000000, 0x0, // Vector Pack Unsigned Doubleword Unsigned Modulo VX-form (vpkudum VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPKUDUS, 0xfc0007ff00000000, 0x100004ce00000000, 0x0, // Vector Pack Unsigned Doubleword Unsigned Saturate VX-form (vpkudus VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPMSUMB, 0xfc0007ff00000000, 0x1000040800000000, 0x0, // Vector Polynomial Multiply-Sum Byte VX-form (vpmsumb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPMSUMD, 0xfc0007ff00000000, 0x100004c800000000, 0x0, // Vector Polynomial Multiply-Sum Doubleword VX-form (vpmsumd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPMSUMH, 0xfc0007ff00000000, 0x1000044800000000, 0x0, // Vector Polynomial Multiply-Sum Halfword VX-form (vpmsumh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPMSUMW, 0xfc0007ff00000000, 0x1000048800000000, 0x0, // Vector Polynomial Multiply-Sum Word VX-form (vpmsumw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPOPCNTB, 0xfc0007ff00000000, 0x1000070300000000, 0x1f000000000000, // Vector Population Count Byte VX-form (vpopcntb VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VPOPCNTD, 0xfc0007ff00000000, 0x100007c300000000, 0x1f000000000000, // Vector Population Count Doubleword VX-form (vpopcntd VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VPOPCNTH, 0xfc0007ff00000000, 0x1000074300000000, 0x1f000000000000, // Vector Population Count Halfword VX-form (vpopcnth VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VPOPCNTW, 0xfc0007ff00000000, 0x1000078300000000, 0x1f000000000000, // Vector Population Count Word VX-form (vpopcntw VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VRLD, 0xfc0007ff00000000, 0x100000c400000000, 0x0, // Vector Rotate Left Doubleword VX-form (vrld VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSBOX, 0xfc0007ff00000000, 0x100005c800000000, 0xf80000000000, // Vector AES SubBytes VX-form (vsbox VRT,VRA)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15}},
+	{VSHASIGMAD, 0xfc0007ff00000000, 0x100006c200000000, 0x0, // Vector SHA-512 Sigma Doubleword VX-form (vshasigmad VRT,VRA,ST,SIX)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_ImmUnsigned_16_16, ap_ImmUnsigned_17_20}},
+	{VSHASIGMAW, 0xfc0007ff00000000, 0x1000068200000000, 0x0, // Vector SHA-256 Sigma Word VX-form (vshasigmaw VRT,VRA,ST,SIX)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_ImmUnsigned_16_16, ap_ImmUnsigned_17_20}},
+	{VSLD, 0xfc0007ff00000000, 0x100005c400000000, 0x0, // Vector Shift Left Doubleword VX-form (vsld VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSRAD, 0xfc0007ff00000000, 0x100003c400000000, 0x0, // Vector Shift Right Algebraic Doubleword VX-form (vsrad VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSRD, 0xfc0007ff00000000, 0x100006c400000000, 0x0, // Vector Shift Right Doubleword VX-form (vsrd VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBCUQ, 0xfc0007ff00000000, 0x1000054000000000, 0x0, // Vector Subtract & write Carry-out Unsigned Quadword VX-form (vsubcuq VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBECUQ, 0xfc00003f00000000, 0x1000003f00000000, 0x0, // Vector Subtract Extended & write Carry-out Unsigned Quadword VA-form (vsubecuq VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VSUBEUQM, 0xfc00003f00000000, 0x1000003e00000000, 0x0, // Vector Subtract Extended Unsigned Quadword Modulo VA-form (vsubeuqm VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VSUBUDM, 0xfc0007ff00000000, 0x100004c000000000, 0x0, // Vector Subtract Unsigned Doubleword Modulo VX-form (vsubudm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBUQM, 0xfc0007ff00000000, 0x1000050000000000, 0x0, // Vector Subtract Unsigned Quadword Modulo VX-form (vsubuqm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VUPKHSW, 0xfc0007ff00000000, 0x1000064e00000000, 0x1f000000000000, // Vector Unpack High Signed Word VX-form (vupkhsw VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VUPKLSW, 0xfc0007ff00000000, 0x100006ce00000000, 0x1f000000000000, // Vector Unpack Low Signed Word VX-form (vupklsw VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{XSADDSP, 0xfc0007f800000000, 0xf000000000000000, 0x0, // VSX Scalar Add Single-Precision XX3-form (xsaddsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSCVDPSPN, 0xfc0007fc00000000, 0xf000042c00000000, 0x1f000000000000, // VSX Scalar Convert Scalar Single-Precision to Vector Single-Precision format Non-signalling XX2-form (xscvdpspn XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSCVSPDPN, 0xfc0007fc00000000, 0xf000052c00000000, 0x1f000000000000, // VSX Scalar Convert Single-Precision to Double-Precision format Non-signalling XX2-form (xscvspdpn XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSCVSXDSP, 0xfc0007fc00000000, 0xf00004e000000000, 0x1f000000000000, // VSX Scalar Convert with round Signed Doubleword to Single-Precision format XX2-form (xscvsxdsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSCVUXDSP, 0xfc0007fc00000000, 0xf00004a000000000, 0x1f000000000000, // VSX Scalar Convert with round Unsigned Doubleword to Single-Precision XX2-form (xscvuxdsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSDIVSP, 0xfc0007f800000000, 0xf00000c000000000, 0x0, // VSX Scalar Divide Single-Precision XX3-form (xsdivsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMADDASP, 0xfc0007f800000000, 0xf000000800000000, 0x0, // VSX Scalar Multiply-Add Type-A Single-Precision XX3-form (xsmaddasp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMADDMSP, 0xfc0007f800000000, 0xf000004800000000, 0x0, // VSX Scalar Multiply-Add Type-M Single-Precision XX3-form (xsmaddmsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMSUBASP, 0xfc0007f800000000, 0xf000008800000000, 0x0, // VSX Scalar Multiply-Subtract Type-A Single-Precision XX3-form (xsmsubasp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMSUBMSP, 0xfc0007f800000000, 0xf00000c800000000, 0x0, // VSX Scalar Multiply-Subtract Type-M Single-Precision XX3-form (xsmsubmsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMULSP, 0xfc0007f800000000, 0xf000008000000000, 0x0, // VSX Scalar Multiply Single-Precision XX3-form (xsmulsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSNMADDASP, 0xfc0007f800000000, 0xf000040800000000, 0x0, // VSX Scalar Negative Multiply-Add Type-A Single-Precision XX3-form (xsnmaddasp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSNMADDMSP, 0xfc0007f800000000, 0xf000044800000000, 0x0, // VSX Scalar Negative Multiply-Add Type-M Single-Precision XX3-form (xsnmaddmsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSNMSUBASP, 0xfc0007f800000000, 0xf000048800000000, 0x0, // VSX Scalar Negative Multiply-Subtract Type-A Single-Precision XX3-form (xsnmsubasp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSNMSUBMSP, 0xfc0007f800000000, 0xf00004c800000000, 0x0, // VSX Scalar Negative Multiply-Subtract Type-M Single-Precision XX3-form (xsnmsubmsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSRESP, 0xfc0007fc00000000, 0xf000006800000000, 0x1f000000000000, // VSX Scalar Reciprocal Estimate Single-Precision XX2-form (xsresp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSRSP, 0xfc0007fc00000000, 0xf000046400000000, 0x1f000000000000, // VSX Scalar Round to Single-Precision XX2-form (xsrsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSRSQRTESP, 0xfc0007fc00000000, 0xf000002800000000, 0x1f000000000000, // VSX Scalar Reciprocal Square Root Estimate Single-Precision XX2-form (xsrsqrtesp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSSQRTSP, 0xfc0007fc00000000, 0xf000002c00000000, 0x1f000000000000, // VSX Scalar Square Root Single-Precision XX2-form (xssqrtsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSSUBSP, 0xfc0007f800000000, 0xf000004000000000, 0x0, // VSX Scalar Subtract Single-Precision XX3-form (xssubsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XXLEQV, 0xfc0007f800000000, 0xf00005d000000000, 0x0, // VSX Vector Logical Equivalence XX3-form (xxleqv XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XXLNAND, 0xfc0007f800000000, 0xf000059000000000, 0x0, // VSX Vector Logical NAND XX3-form (xxlnand XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XXLORC, 0xfc0007f800000000, 0xf000055000000000, 0x0, // VSX Vector Logical OR with Complement XX3-form (xxlorc XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{ADDG6S, 0xfc0003fe00000000, 0x7c00009400000000, 0x40100000000, // Add and Generate Sixes XO-form (addg6s RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{BPERMD, 0xfc0007fe00000000, 0x7c0001f800000000, 0x100000000, // Bit Permute Doubleword X-form (bpermd RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{CBCDTD, 0xfc0007fe00000000, 0x7c00027400000000, 0xf80100000000, // Convert Binary Coded Decimal To Declets X-form (cbcdtd RA, RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{CDTBCD, 0xfc0007fe00000000, 0x7c00023400000000, 0xf80100000000, // Convert Declets To Binary Coded Decimal X-form (cdtbcd RA, RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{DCFFIX, 0xfc0007ff00000000, 0xec00064400000000, 0x1f000000000000, // DFP Convert From Fixed X-form (dcffix FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DCFFIXCC, 0xfc0007ff00000000, 0xec00064500000000, 0x1f000000000000, // DFP Convert From Fixed X-form (dcffix. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DIVDE, 0xfc0007ff00000000, 0x7c00035200000000, 0x0, // Divide Doubleword Extended XO-form (divde RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDECC, 0xfc0007ff00000000, 0x7c00035300000000, 0x0, // Divide Doubleword Extended XO-form (divde. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDEO, 0xfc0007ff00000000, 0x7c00075200000000, 0x0, // Divide Doubleword Extended XO-form (divdeo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDEOCC, 0xfc0007ff00000000, 0x7c00075300000000, 0x0, // Divide Doubleword Extended XO-form (divdeo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDEU, 0xfc0007ff00000000, 0x7c00031200000000, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeu RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDEUCC, 0xfc0007ff00000000, 0x7c00031300000000, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeu. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDEUO, 0xfc0007ff00000000, 0x7c00071200000000, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeuo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDEUOCC, 0xfc0007ff00000000, 0x7c00071300000000, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeuo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWE, 0xfc0007ff00000000, 0x7c00035600000000, 0x0, // Divide Word Extended XO-form (divwe RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWECC, 0xfc0007ff00000000, 0x7c00035700000000, 0x0, // Divide Word Extended XO-form (divwe. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWEO, 0xfc0007ff00000000, 0x7c00075600000000, 0x0, // Divide Word Extended XO-form (divweo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWEOCC, 0xfc0007ff00000000, 0x7c00075700000000, 0x0, // Divide Word Extended XO-form (divweo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWEU, 0xfc0007ff00000000, 0x7c00031600000000, 0x0, // Divide Word Extended Unsigned XO-form (divweu RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWEUCC, 0xfc0007ff00000000, 0x7c00031700000000, 0x0, // Divide Word Extended Unsigned XO-form (divweu. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWEUO, 0xfc0007ff00000000, 0x7c00071600000000, 0x0, // Divide Word Extended Unsigned XO-form (divweuo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWEUOCC, 0xfc0007ff00000000, 0x7c00071700000000, 0x0, // Divide Word Extended Unsigned XO-form (divweuo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{FCFIDS, 0xfc0007ff00000000, 0xec00069c00000000, 0x1f000000000000, // Floating Convert with round Signed Doubleword to Single-Precision format X-form (fcfids FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCFIDSCC, 0xfc0007ff00000000, 0xec00069d00000000, 0x1f000000000000, // Floating Convert with round Signed Doubleword to Single-Precision format X-form (fcfids. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCFIDU, 0xfc0007ff00000000, 0xfc00079c00000000, 0x1f000000000000, // Floating Convert with round Unsigned Doubleword to Double-Precision format X-form (fcfidu FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCFIDUCC, 0xfc0007ff00000000, 0xfc00079d00000000, 0x1f000000000000, // Floating Convert with round Unsigned Doubleword to Double-Precision format X-form (fcfidu. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCFIDUS, 0xfc0007ff00000000, 0xec00079c00000000, 0x1f000000000000, // Floating Convert with round Unsigned Doubleword to Single-Precision format X-form (fcfidus FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCFIDUSCC, 0xfc0007ff00000000, 0xec00079d00000000, 0x1f000000000000, // Floating Convert with round Unsigned Doubleword to Single-Precision format X-form (fcfidus. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIDU, 0xfc0007ff00000000, 0xfc00075c00000000, 0x1f000000000000, // Floating Convert with round Double-Precision To Unsigned Doubleword format X-form (fctidu FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIDUCC, 0xfc0007ff00000000, 0xfc00075d00000000, 0x1f000000000000, // Floating Convert with round Double-Precision To Unsigned Doubleword format X-form (fctidu. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIDUZ, 0xfc0007ff00000000, 0xfc00075e00000000, 0x1f000000000000, // Floating Convert with truncate Double-Precision To Unsigned Doubleword format X-form (fctiduz FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIDUZCC, 0xfc0007ff00000000, 0xfc00075f00000000, 0x1f000000000000, // Floating Convert with truncate Double-Precision To Unsigned Doubleword format X-form (fctiduz. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIWU, 0xfc0007ff00000000, 0xfc00011c00000000, 0x1f000000000000, // Floating Convert with round Double-Precision To Unsigned Word format X-form (fctiwu FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIWUCC, 0xfc0007ff00000000, 0xfc00011d00000000, 0x1f000000000000, // Floating Convert with round Double-Precision To Unsigned Word format X-form (fctiwu. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIWUZ, 0xfc0007ff00000000, 0xfc00011e00000000, 0x1f000000000000, // Floating Convert with truncate Double-Precision To Unsigned Word format X-form (fctiwuz FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIWUZCC, 0xfc0007ff00000000, 0xfc00011f00000000, 0x1f000000000000, // Floating Convert with truncate Double-Precision To Unsigned Word format X-form (fctiwuz. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FTDIV, 0xfc0007fe00000000, 0xfc00010000000000, 0x60000100000000, // Floating Test for software Divide X-form (ftdiv BF,FRA,FRB)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FTSQRT, 0xfc0007fe00000000, 0xfc00014000000000, 0x7f000100000000, // Floating Test for software Square Root X-form (ftsqrt BF,FRB)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_16_20}},
+	{LBARX, 0xfc0007fe00000000, 0x7c00006800000000, 0x0, // Load Byte And Reserve Indexed X-form (lbarx RT,RA,RB,EH)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}},
+	{LDBRX, 0xfc0007fe00000000, 0x7c00042800000000, 0x100000000, // Load Doubleword Byte-Reverse Indexed X-form (ldbrx RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LFIWZX, 0xfc0007fe00000000, 0x7c0006ee00000000, 0x100000000, // Load Floating-Point as Integer Word & Zero Indexed X-form (lfiwzx FRT,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LHARX, 0xfc0007fe00000000, 0x7c0000e800000000, 0x0, // Load Halfword And Reserve Indexed Xform (lharx RT,RA,RB,EH)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}},
+	{LXSDX, 0xfc0007fe00000000, 0x7c00049800000000, 0x0, // Load VSX Scalar Doubleword Indexed X-form (lxsdx XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVD2X, 0xfc0007fe00000000, 0x7c00069800000000, 0x0, // Load VSX Vector Doubleword*2 Indexed X-form (lxvd2x XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVDSX, 0xfc0007fe00000000, 0x7c00029800000000, 0x0, // Load VSX Vector Doubleword & Splat Indexed X-form (lxvdsx XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVW4X, 0xfc0007fe00000000, 0x7c00061800000000, 0x0, // Load VSX Vector Word*4 Indexed X-form (lxvw4x XT,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{POPCNTD, 0xfc0007fe00000000, 0x7c0003f400000000, 0xf80100000000, // Population Count Doubleword X-form (popcntd RA, RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{POPCNTW, 0xfc0007fe00000000, 0x7c0002f400000000, 0xf80100000000, // Population Count Words X-form (popcntw RA, RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{STBCXCC, 0xfc0007ff00000000, 0x7c00056d00000000, 0x0, // Store Byte Conditional Indexed X-form (stbcx. RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STDBRX, 0xfc0007fe00000000, 0x7c00052800000000, 0x100000000, // Store Doubleword Byte-Reverse Indexed X-form (stdbrx RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STHCXCC, 0xfc0007ff00000000, 0x7c0005ad00000000, 0x0, // Store Halfword Conditional Indexed X-form (sthcx. RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXSDX, 0xfc0007fe00000000, 0x7c00059800000000, 0x0, // Store VSX Scalar Doubleword Indexed X-form (stxsdx XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXVD2X, 0xfc0007fe00000000, 0x7c00079800000000, 0x0, // Store VSX Vector Doubleword*2 Indexed X-form (stxvd2x XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXVW4X, 0xfc0007fe00000000, 0x7c00071800000000, 0x0, // Store VSX Vector Word*4 Indexed X-form (stxvw4x XS,RA,RB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{XSABSDP, 0xfc0007fc00000000, 0xf000056400000000, 0x1f000000000000, // VSX Scalar Absolute Double-Precision XX2-form (xsabsdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSADDDP, 0xfc0007f800000000, 0xf000010000000000, 0x0, // VSX Scalar Add Double-Precision XX3-form (xsadddp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSCMPODP, 0xfc0007f800000000, 0xf000015800000000, 0x60000100000000, // VSX Scalar Compare Ordered Double-Precision XX3-form (xscmpodp BF,XA,XB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSCMPUDP, 0xfc0007f800000000, 0xf000011800000000, 0x60000100000000, // VSX Scalar Compare Unordered Double-Precision XX3-form (xscmpudp BF,XA,XB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSCPSGNDP, 0xfc0007f800000000, 0xf000058000000000, 0x0, // VSX Scalar Copy Sign Double-Precision XX3-form (xscpsgndp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSCVDPSP, 0xfc0007fc00000000, 0xf000042400000000, 0x1f000000000000, // VSX Scalar Convert with round Double-Precision to Single-Precision format XX2-form (xscvdpsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSCVDPSXDS, 0xfc0007fc00000000, 0xf000056000000000, 0x1f000000000000, // VSX Scalar Convert with round to zero Double-Precision to Signed Doubleword format XX2-form (xscvdpsxds XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSCVDPSXWS, 0xfc0007fc00000000, 0xf000016000000000, 0x1f000000000000, // VSX Scalar Convert with round to zero Double-Precision to Signed Word format XX2-form (xscvdpsxws XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSCVDPUXDS, 0xfc0007fc00000000, 0xf000052000000000, 0x1f000000000000, // VSX Scalar Convert with round to zero Double-Precision to Unsigned Doubleword format XX2-form (xscvdpuxds XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSCVDPUXWS, 0xfc0007fc00000000, 0xf000012000000000, 0x1f000000000000, // VSX Scalar Convert with round to zero Double-Precision to Unsigned Word format XX2-form (xscvdpuxws XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSCVSPDP, 0xfc0007fc00000000, 0xf000052400000000, 0x1f000000000000, // VSX Scalar Convert Single-Precision to Double-Precision format XX2-form (xscvspdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSCVSXDDP, 0xfc0007fc00000000, 0xf00005e000000000, 0x1f000000000000, // VSX Scalar Convert with round Signed Doubleword to Double-Precision format XX2-form (xscvsxddp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSCVUXDDP, 0xfc0007fc00000000, 0xf00005a000000000, 0x1f000000000000, // VSX Scalar Convert with round Unsigned Doubleword to Double-Precision format XX2-form (xscvuxddp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSDIVDP, 0xfc0007f800000000, 0xf00001c000000000, 0x0, // VSX Scalar Divide Double-Precision XX3-form (xsdivdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMADDADP, 0xfc0007f800000000, 0xf000010800000000, 0x0, // VSX Scalar Multiply-Add Type-A Double-Precision XX3-form (xsmaddadp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMADDMDP, 0xfc0007f800000000, 0xf000014800000000, 0x0, // VSX Scalar Multiply-Add Type-M Double-Precision XX3-form (xsmaddmdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMAXDP, 0xfc0007f800000000, 0xf000050000000000, 0x0, // VSX Scalar Maximum Double-Precision XX3-form (xsmaxdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMINDP, 0xfc0007f800000000, 0xf000054000000000, 0x0, // VSX Scalar Minimum Double-Precision XX3-form (xsmindp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMSUBADP, 0xfc0007f800000000, 0xf000018800000000, 0x0, // VSX Scalar Multiply-Subtract Type-A Double-Precision XX3-form (xsmsubadp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMSUBMDP, 0xfc0007f800000000, 0xf00001c800000000, 0x0, // VSX Scalar Multiply-Subtract Type-M Double-Precision XX3-form (xsmsubmdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSMULDP, 0xfc0007f800000000, 0xf000018000000000, 0x0, // VSX Scalar Multiply Double-Precision XX3-form (xsmuldp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSNABSDP, 0xfc0007fc00000000, 0xf00005a400000000, 0x1f000000000000, // VSX Scalar Negative Absolute Double-Precision XX2-form (xsnabsdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSNEGDP, 0xfc0007fc00000000, 0xf00005e400000000, 0x1f000000000000, // VSX Scalar Negate Double-Precision XX2-form (xsnegdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSNMADDADP, 0xfc0007f800000000, 0xf000050800000000, 0x0, // VSX Scalar Negative Multiply-Add Type-A Double-Precision XX3-form (xsnmaddadp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSNMADDMDP, 0xfc0007f800000000, 0xf000054800000000, 0x0, // VSX Scalar Negative Multiply-Add Type-M Double-Precision XX3-form (xsnmaddmdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSNMSUBADP, 0xfc0007f800000000, 0xf000058800000000, 0x0, // VSX Scalar Negative Multiply-Subtract Type-A Double-Precision XX3-form (xsnmsubadp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSNMSUBMDP, 0xfc0007f800000000, 0xf00005c800000000, 0x0, // VSX Scalar Negative Multiply-Subtract Type-M Double-Precision XX3-form (xsnmsubmdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSRDPI, 0xfc0007fc00000000, 0xf000012400000000, 0x1f000000000000, // VSX Scalar Round to Double-Precision Integer using round to Nearest Away XX2-form (xsrdpi XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSRDPIC, 0xfc0007fc00000000, 0xf00001ac00000000, 0x1f000000000000, // VSX Scalar Round to Double-Precision Integer exact using Current rounding mode XX2-form (xsrdpic XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSRDPIM, 0xfc0007fc00000000, 0xf00001e400000000, 0x1f000000000000, // VSX Scalar Round to Double-Precision Integer using round toward -Infinity XX2-form (xsrdpim XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSRDPIP, 0xfc0007fc00000000, 0xf00001a400000000, 0x1f000000000000, // VSX Scalar Round to Double-Precision Integer using round toward +Infinity XX2-form (xsrdpip XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSRDPIZ, 0xfc0007fc00000000, 0xf000016400000000, 0x1f000000000000, // VSX Scalar Round to Double-Precision Integer using round toward Zero XX2-form (xsrdpiz XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSREDP, 0xfc0007fc00000000, 0xf000016800000000, 0x1f000000000000, // VSX Scalar Reciprocal Estimate Double-Precision XX2-form (xsredp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSRSQRTEDP, 0xfc0007fc00000000, 0xf000012800000000, 0x1f000000000000, // VSX Scalar Reciprocal Square Root Estimate Double-Precision XX2-form (xsrsqrtedp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSSQRTDP, 0xfc0007fc00000000, 0xf000012c00000000, 0x1f000000000000, // VSX Scalar Square Root Double-Precision XX2-form (xssqrtdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XSSUBDP, 0xfc0007f800000000, 0xf000014000000000, 0x0, // VSX Scalar Subtract Double-Precision XX3-form (xssubdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSTDIVDP, 0xfc0007f800000000, 0xf00001e800000000, 0x60000100000000, // VSX Scalar Test for software Divide Double-Precision XX3-form (xstdivdp BF,XA,XB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XSTSQRTDP, 0xfc0007fc00000000, 0xf00001a800000000, 0x7f000100000000, // VSX Scalar Test for software Square Root Double-Precision XX2-form (xstsqrtdp BF,XB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecSReg_30_30_16_20}},
+	{XVABSDP, 0xfc0007fc00000000, 0xf000076400000000, 0x1f000000000000, // VSX Vector Absolute Value Double-Precision XX2-form (xvabsdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVABSSP, 0xfc0007fc00000000, 0xf000066400000000, 0x1f000000000000, // VSX Vector Absolute Value Single-Precision XX2-form (xvabssp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVADDDP, 0xfc0007f800000000, 0xf000030000000000, 0x0, // VSX Vector Add Double-Precision XX3-form (xvadddp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVADDSP, 0xfc0007f800000000, 0xf000020000000000, 0x0, // VSX Vector Add Single-Precision XX3-form (xvaddsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCMPEQDP, 0xfc0007f800000000, 0xf000031800000000, 0x0, // VSX Vector Compare Equal To Double-Precision XX3-form (xvcmpeqdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCMPEQDPCC, 0xfc0007f800000000, 0xf000071800000000, 0x0, // VSX Vector Compare Equal To Double-Precision XX3-form (xvcmpeqdp. XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCMPEQSP, 0xfc0007f800000000, 0xf000021800000000, 0x0, // VSX Vector Compare Equal To Single-Precision XX3-form (xvcmpeqsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCMPEQSPCC, 0xfc0007f800000000, 0xf000061800000000, 0x0, // VSX Vector Compare Equal To Single-Precision XX3-form (xvcmpeqsp. XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCMPGEDP, 0xfc0007f800000000, 0xf000039800000000, 0x0, // VSX Vector Compare Greater Than or Equal To Double-Precision XX3-form (xvcmpgedp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCMPGEDPCC, 0xfc0007f800000000, 0xf000079800000000, 0x0, // VSX Vector Compare Greater Than or Equal To Double-Precision XX3-form (xvcmpgedp. XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCMPGESP, 0xfc0007f800000000, 0xf000029800000000, 0x0, // VSX Vector Compare Greater Than or Equal To Single-Precision XX3-form (xvcmpgesp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCMPGESPCC, 0xfc0007f800000000, 0xf000069800000000, 0x0, // VSX Vector Compare Greater Than or Equal To Single-Precision XX3-form (xvcmpgesp. XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCMPGTDP, 0xfc0007f800000000, 0xf000035800000000, 0x0, // VSX Vector Compare Greater Than Double-Precision XX3-form (xvcmpgtdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCMPGTDPCC, 0xfc0007f800000000, 0xf000075800000000, 0x0, // VSX Vector Compare Greater Than Double-Precision XX3-form (xvcmpgtdp. XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCMPGTSP, 0xfc0007f800000000, 0xf000025800000000, 0x0, // VSX Vector Compare Greater Than Single-Precision XX3-form (xvcmpgtsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCMPGTSPCC, 0xfc0007f800000000, 0xf000065800000000, 0x0, // VSX Vector Compare Greater Than Single-Precision XX3-form (xvcmpgtsp. XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCPSGNDP, 0xfc0007f800000000, 0xf000078000000000, 0x0, // VSX Vector Copy Sign Double-Precision XX3-form (xvcpsgndp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCPSGNSP, 0xfc0007f800000000, 0xf000068000000000, 0x0, // VSX Vector Copy Sign Single-Precision XX3-form (xvcpsgnsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVCVDPSP, 0xfc0007fc00000000, 0xf000062400000000, 0x1f000000000000, // VSX Vector Convert with round Double-Precision to Single-Precision format XX2-form (xvcvdpsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVDPSXDS, 0xfc0007fc00000000, 0xf000076000000000, 0x1f000000000000, // VSX Vector Convert with round to zero Double-Precision to Signed Doubleword format XX2-form (xvcvdpsxds XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVDPSXWS, 0xfc0007fc00000000, 0xf000036000000000, 0x1f000000000000, // VSX Vector Convert with round to zero Double-Precision to Signed Word format XX2-form (xvcvdpsxws XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVDPUXDS, 0xfc0007fc00000000, 0xf000072000000000, 0x1f000000000000, // VSX Vector Convert with round to zero Double-Precision to Unsigned Doubleword format XX2-form (xvcvdpuxds XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVDPUXWS, 0xfc0007fc00000000, 0xf000032000000000, 0x1f000000000000, // VSX Vector Convert with round to zero Double-Precision to Unsigned Word format XX2-form (xvcvdpuxws XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVSPDP, 0xfc0007fc00000000, 0xf000072400000000, 0x1f000000000000, // VSX Vector Convert Single-Precision to Double-Precision format XX2-form (xvcvspdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVSPSXDS, 0xfc0007fc00000000, 0xf000066000000000, 0x1f000000000000, // VSX Vector Convert with round to zero Single-Precision to Signed Doubleword format XX2-form (xvcvspsxds XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVSPSXWS, 0xfc0007fc00000000, 0xf000026000000000, 0x1f000000000000, // VSX Vector Convert with round to zero Single-Precision to Signed Word format XX2-form (xvcvspsxws XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVSPUXDS, 0xfc0007fc00000000, 0xf000062000000000, 0x1f000000000000, // VSX Vector Convert with round to zero Single-Precision to Unsigned Doubleword format XX2-form (xvcvspuxds XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVSPUXWS, 0xfc0007fc00000000, 0xf000022000000000, 0x1f000000000000, // VSX Vector Convert with round to zero Single-Precision to Unsigned Word format XX2-form (xvcvspuxws XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVSXDDP, 0xfc0007fc00000000, 0xf00007e000000000, 0x1f000000000000, // VSX Vector Convert with round Signed Doubleword to Double-Precision format XX2-form (xvcvsxddp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVSXDSP, 0xfc0007fc00000000, 0xf00006e000000000, 0x1f000000000000, // VSX Vector Convert with round Signed Doubleword to Single-Precision format XX2-form (xvcvsxdsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVSXWDP, 0xfc0007fc00000000, 0xf00003e000000000, 0x1f000000000000, // VSX Vector Convert Signed Word to Double-Precision format XX2-form (xvcvsxwdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVSXWSP, 0xfc0007fc00000000, 0xf00002e000000000, 0x1f000000000000, // VSX Vector Convert with round Signed Word to Single-Precision format XX2-form (xvcvsxwsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVUXDDP, 0xfc0007fc00000000, 0xf00007a000000000, 0x1f000000000000, // VSX Vector Convert with round Unsigned Doubleword to Double-Precision format XX2-form (xvcvuxddp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVUXDSP, 0xfc0007fc00000000, 0xf00006a000000000, 0x1f000000000000, // VSX Vector Convert with round Unsigned Doubleword to Single-Precision format XX2-form (xvcvuxdsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVUXWDP, 0xfc0007fc00000000, 0xf00003a000000000, 0x1f000000000000, // VSX Vector Convert Unsigned Word to Double-Precision format XX2-form (xvcvuxwdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVCVUXWSP, 0xfc0007fc00000000, 0xf00002a000000000, 0x1f000000000000, // VSX Vector Convert with round Unsigned Word to Single-Precision format XX2-form (xvcvuxwsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVDIVDP, 0xfc0007f800000000, 0xf00003c000000000, 0x0, // VSX Vector Divide Double-Precision XX3-form (xvdivdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVDIVSP, 0xfc0007f800000000, 0xf00002c000000000, 0x0, // VSX Vector Divide Single-Precision XX3-form (xvdivsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMADDADP, 0xfc0007f800000000, 0xf000030800000000, 0x0, // VSX Vector Multiply-Add Type-A Double-Precision XX3-form (xvmaddadp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMADDASP, 0xfc0007f800000000, 0xf000020800000000, 0x0, // VSX Vector Multiply-Add Type-A Single-Precision XX3-form (xvmaddasp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMADDMDP, 0xfc0007f800000000, 0xf000034800000000, 0x0, // VSX Vector Multiply-Add Type-M Double-Precision XX3-form (xvmaddmdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMADDMSP, 0xfc0007f800000000, 0xf000024800000000, 0x0, // VSX Vector Multiply-Add Type-M Single-Precision XX3-form (xvmaddmsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMAXDP, 0xfc0007f800000000, 0xf000070000000000, 0x0, // VSX Vector Maximum Double-Precision XX3-form (xvmaxdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMAXSP, 0xfc0007f800000000, 0xf000060000000000, 0x0, // VSX Vector Maximum Single-Precision XX3-form (xvmaxsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMINDP, 0xfc0007f800000000, 0xf000074000000000, 0x0, // VSX Vector Minimum Double-Precision XX3-form (xvmindp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMINSP, 0xfc0007f800000000, 0xf000064000000000, 0x0, // VSX Vector Minimum Single-Precision XX3-form (xvminsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMSUBADP, 0xfc0007f800000000, 0xf000038800000000, 0x0, // VSX Vector Multiply-Subtract Type-A Double-Precision XX3-form (xvmsubadp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMSUBASP, 0xfc0007f800000000, 0xf000028800000000, 0x0, // VSX Vector Multiply-Subtract Type-A Single-Precision XX3-form (xvmsubasp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMSUBMDP, 0xfc0007f800000000, 0xf00003c800000000, 0x0, // VSX Vector Multiply-Subtract Type-M Double-Precision XX3-form (xvmsubmdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMSUBMSP, 0xfc0007f800000000, 0xf00002c800000000, 0x0, // VSX Vector Multiply-Subtract Type-M Single-Precision XX3-form (xvmsubmsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMULDP, 0xfc0007f800000000, 0xf000038000000000, 0x0, // VSX Vector Multiply Double-Precision XX3-form (xvmuldp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVMULSP, 0xfc0007f800000000, 0xf000028000000000, 0x0, // VSX Vector Multiply Single-Precision XX3-form (xvmulsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVNABSDP, 0xfc0007fc00000000, 0xf00007a400000000, 0x1f000000000000, // VSX Vector Negative Absolute Double-Precision XX2-form (xvnabsdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVNABSSP, 0xfc0007fc00000000, 0xf00006a400000000, 0x1f000000000000, // VSX Vector Negative Absolute Single-Precision XX2-form (xvnabssp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVNEGDP, 0xfc0007fc00000000, 0xf00007e400000000, 0x1f000000000000, // VSX Vector Negate Double-Precision XX2-form (xvnegdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVNEGSP, 0xfc0007fc00000000, 0xf00006e400000000, 0x1f000000000000, // VSX Vector Negate Single-Precision XX2-form (xvnegsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVNMADDADP, 0xfc0007f800000000, 0xf000070800000000, 0x0, // VSX Vector Negative Multiply-Add Type-A Double-Precision XX3-form (xvnmaddadp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVNMADDASP, 0xfc0007f800000000, 0xf000060800000000, 0x0, // VSX Vector Negative Multiply-Add Type-A Single-Precision XX3-form (xvnmaddasp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVNMADDMDP, 0xfc0007f800000000, 0xf000074800000000, 0x0, // VSX Vector Negative Multiply-Add Type-M Double-Precision XX3-form (xvnmaddmdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVNMADDMSP, 0xfc0007f800000000, 0xf000064800000000, 0x0, // VSX Vector Negative Multiply-Add Type-M Single-Precision XX3-form (xvnmaddmsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVNMSUBADP, 0xfc0007f800000000, 0xf000078800000000, 0x0, // VSX Vector Negative Multiply-Subtract Type-A Double-Precision XX3-form (xvnmsubadp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVNMSUBASP, 0xfc0007f800000000, 0xf000068800000000, 0x0, // VSX Vector Negative Multiply-Subtract Type-A Single-Precision XX3-form (xvnmsubasp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVNMSUBMDP, 0xfc0007f800000000, 0xf00007c800000000, 0x0, // VSX Vector Negative Multiply-Subtract Type-M Double-Precision XX3-form (xvnmsubmdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVNMSUBMSP, 0xfc0007f800000000, 0xf00006c800000000, 0x0, // VSX Vector Negative Multiply-Subtract Type-M Single-Precision XX3-form (xvnmsubmsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVRDPI, 0xfc0007fc00000000, 0xf000032400000000, 0x1f000000000000, // VSX Vector Round to Double-Precision Integer using round to Nearest Away XX2-form (xvrdpi XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVRDPIC, 0xfc0007fc00000000, 0xf00003ac00000000, 0x1f000000000000, // VSX Vector Round to Double-Precision Integer Exact using Current rounding mode XX2-form (xvrdpic XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVRDPIM, 0xfc0007fc00000000, 0xf00003e400000000, 0x1f000000000000, // VSX Vector Round to Double-Precision Integer using round toward -Infinity XX2-form (xvrdpim XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVRDPIP, 0xfc0007fc00000000, 0xf00003a400000000, 0x1f000000000000, // VSX Vector Round to Double-Precision Integer using round toward +Infinity XX2-form (xvrdpip XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVRDPIZ, 0xfc0007fc00000000, 0xf000036400000000, 0x1f000000000000, // VSX Vector Round to Double-Precision Integer using round toward Zero XX2-form (xvrdpiz XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVREDP, 0xfc0007fc00000000, 0xf000036800000000, 0x1f000000000000, // VSX Vector Reciprocal Estimate Double-Precision XX2-form (xvredp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVRESP, 0xfc0007fc00000000, 0xf000026800000000, 0x1f000000000000, // VSX Vector Reciprocal Estimate Single-Precision XX2-form (xvresp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVRSPI, 0xfc0007fc00000000, 0xf000022400000000, 0x1f000000000000, // VSX Vector Round to Single-Precision Integer using round to Nearest Away XX2-form (xvrspi XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVRSPIC, 0xfc0007fc00000000, 0xf00002ac00000000, 0x1f000000000000, // VSX Vector Round to Single-Precision Integer Exact using Current rounding mode XX2-form (xvrspic XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVRSPIM, 0xfc0007fc00000000, 0xf00002e400000000, 0x1f000000000000, // VSX Vector Round to Single-Precision Integer using round toward -Infinity XX2-form (xvrspim XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVRSPIP, 0xfc0007fc00000000, 0xf00002a400000000, 0x1f000000000000, // VSX Vector Round to Single-Precision Integer using round toward +Infinity XX2-form (xvrspip XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVRSPIZ, 0xfc0007fc00000000, 0xf000026400000000, 0x1f000000000000, // VSX Vector Round to Single-Precision Integer using round toward Zero XX2-form (xvrspiz XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVRSQRTEDP, 0xfc0007fc00000000, 0xf000032800000000, 0x1f000000000000, // VSX Vector Reciprocal Square Root Estimate Double-Precision XX2-form (xvrsqrtedp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVRSQRTESP, 0xfc0007fc00000000, 0xf000022800000000, 0x1f000000000000, // VSX Vector Reciprocal Square Root Estimate Single-Precision XX2-form (xvrsqrtesp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVSQRTDP, 0xfc0007fc00000000, 0xf000032c00000000, 0x1f000000000000, // VSX Vector Square Root Double-Precision XX2-form (xvsqrtdp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVSQRTSP, 0xfc0007fc00000000, 0xf000022c00000000, 0x1f000000000000, // VSX Vector Square Root Single-Precision XX2-form (xvsqrtsp XT,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
+	{XVSUBDP, 0xfc0007f800000000, 0xf000034000000000, 0x0, // VSX Vector Subtract Double-Precision XX3-form (xvsubdp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVSUBSP, 0xfc0007f800000000, 0xf000024000000000, 0x0, // VSX Vector Subtract Single-Precision XX3-form (xvsubsp XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVTDIVDP, 0xfc0007f800000000, 0xf00003e800000000, 0x60000100000000, // VSX Vector Test for software Divide Double-Precision XX3-form (xvtdivdp BF,XA,XB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVTDIVSP, 0xfc0007f800000000, 0xf00002e800000000, 0x60000100000000, // VSX Vector Test for software Divide Single-Precision XX3-form (xvtdivsp BF,XA,XB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XVTSQRTDP, 0xfc0007fc00000000, 0xf00003a800000000, 0x7f000100000000, // VSX Vector Test for software Square Root Double-Precision XX2-form (xvtsqrtdp BF,XB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecSReg_30_30_16_20}},
+	{XVTSQRTSP, 0xfc0007fc00000000, 0xf00002a800000000, 0x7f000100000000, // VSX Vector Test for software Square Root Single-Precision XX2-form (xvtsqrtsp BF,XB)
+		[6]*argField{ap_CondRegField_6_8, ap_VecSReg_30_30_16_20}},
+	{XXLAND, 0xfc0007f800000000, 0xf000041000000000, 0x0, // VSX Vector Logical AND XX3-form (xxland XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XXLANDC, 0xfc0007f800000000, 0xf000045000000000, 0x0, // VSX Vector Logical AND with Complement XX3-form (xxlandc XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XXLNOR, 0xfc0007f800000000, 0xf000051000000000, 0x0, // VSX Vector Logical NOR XX3-form (xxlnor XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XXLOR, 0xfc0007f800000000, 0xf000049000000000, 0x0, // VSX Vector Logical OR XX3-form (xxlor XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XXLXOR, 0xfc0007f800000000, 0xf00004d000000000, 0x0, // VSX Vector Logical XOR XX3-form (xxlxor XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XXMRGHW, 0xfc0007f800000000, 0xf000009000000000, 0x0, // VSX Vector Merge High Word XX3-form (xxmrghw XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XXMRGLW, 0xfc0007f800000000, 0xf000019000000000, 0x0, // VSX Vector Merge Low Word XX3-form (xxmrglw XT,XA,XB)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
+	{XXPERMDI, 0xfc0004f800000000, 0xf000005000000000, 0x0, // VSX Vector Permute Doubleword Immediate XX3-form (xxpermdi XT,XA,XB,DM)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_22_23}},
+	{XXSEL, 0xfc00003000000000, 0xf000003000000000, 0x0, // VSX Vector Select XX4-form (xxsel XT,XA,XB,XC)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20, ap_VecSReg_28_28_21_25}},
+	{XXSLDWI, 0xfc0004f800000000, 0xf000001000000000, 0x0, // VSX Vector Shift Left Double by Word Immediate XX3-form (xxsldwi XT,XA,XB,SHW)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_22_23}},
+	{XXSPLTW, 0xfc0007fc00000000, 0xf000029000000000, 0x1c000000000000, // VSX Vector Splat Word XX2-form (xxspltw XT,XB,UIM)
+		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_14_15}},
+	{CMPB, 0xfc0007fe00000000, 0x7c0003f800000000, 0x100000000, // Compare Bytes X-form (cmpb RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{DADD, 0xfc0007ff00000000, 0xec00000400000000, 0x0, // DFP Add X-form (dadd FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DADDCC, 0xfc0007ff00000000, 0xec00000500000000, 0x0, // DFP Add X-form (dadd. FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DADDQ, 0xfc0007ff00000000, 0xfc00000400000000, 0x0, // DFP Add Quad X-form (daddq FRTp,FRAp,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DADDQCC, 0xfc0007ff00000000, 0xfc00000500000000, 0x0, // DFP Add Quad X-form (daddq. FRTp,FRAp,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DCFFIXQ, 0xfc0007ff00000000, 0xfc00064400000000, 0x1f000000000000, // DFP Convert From Fixed Quad X-form (dcffixq FRTp,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DCFFIXQCC, 0xfc0007ff00000000, 0xfc00064500000000, 0x1f000000000000, // DFP Convert From Fixed Quad X-form (dcffixq. FRTp,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DCMPO, 0xfc0007fe00000000, 0xec00010400000000, 0x60000100000000, // DFP Compare Ordered X-form (dcmpo BF,FRA,FRB)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DCMPOQ, 0xfc0007fe00000000, 0xfc00010400000000, 0x60000100000000, // DFP Compare Ordered Quad X-form (dcmpoq BF,FRAp,FRBp)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DCMPU, 0xfc0007fe00000000, 0xec00050400000000, 0x60000100000000, // DFP Compare Unordered X-form (dcmpu BF,FRA,FRB)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DCMPUQ, 0xfc0007fe00000000, 0xfc00050400000000, 0x60000100000000, // DFP Compare Unordered Quad X-form (dcmpuq BF,FRAp,FRBp)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DCTDP, 0xfc0007ff00000000, 0xec00020400000000, 0x1f000000000000, // DFP Convert To DFP Long X-form (dctdp FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DCTDPCC, 0xfc0007ff00000000, 0xec00020500000000, 0x1f000000000000, // DFP Convert To DFP Long X-form (dctdp. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DCTFIX, 0xfc0007ff00000000, 0xec00024400000000, 0x1f000000000000, // DFP Convert To Fixed X-form (dctfix FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DCTFIXCC, 0xfc0007ff00000000, 0xec00024500000000, 0x1f000000000000, // DFP Convert To Fixed X-form (dctfix. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DCTFIXQ, 0xfc0007ff00000000, 0xfc00024400000000, 0x1f000000000000, // DFP Convert To Fixed Quad X-form (dctfixq FRT,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DCTFIXQCC, 0xfc0007ff00000000, 0xfc00024500000000, 0x1f000000000000, // DFP Convert To Fixed Quad X-form (dctfixq. FRT,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DCTQPQ, 0xfc0007ff00000000, 0xfc00020400000000, 0x1f000000000000, // DFP Convert To DFP Extended X-form (dctqpq FRTp,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DCTQPQCC, 0xfc0007ff00000000, 0xfc00020500000000, 0x1f000000000000, // DFP Convert To DFP Extended X-form (dctqpq. FRTp,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DDEDPD, 0xfc0007ff00000000, 0xec00028400000000, 0x7000000000000, // DFP Decode DPD To BCD X-form (ddedpd SP,FRT,FRB)
+		[6]*argField{ap_ImmUnsigned_11_12, ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DDEDPDCC, 0xfc0007ff00000000, 0xec00028500000000, 0x7000000000000, // DFP Decode DPD To BCD X-form (ddedpd. SP,FRT,FRB)
+		[6]*argField{ap_ImmUnsigned_11_12, ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DDEDPDQ, 0xfc0007ff00000000, 0xfc00028400000000, 0x7000000000000, // DFP Decode DPD To BCD Quad X-form (ddedpdq SP,FRTp,FRBp)
+		[6]*argField{ap_ImmUnsigned_11_12, ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DDEDPDQCC, 0xfc0007ff00000000, 0xfc00028500000000, 0x7000000000000, // DFP Decode DPD To BCD Quad X-form (ddedpdq. SP,FRTp,FRBp)
+		[6]*argField{ap_ImmUnsigned_11_12, ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DDIV, 0xfc0007ff00000000, 0xec00044400000000, 0x0, // DFP Divide X-form (ddiv FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DDIVCC, 0xfc0007ff00000000, 0xec00044500000000, 0x0, // DFP Divide X-form (ddiv. FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DDIVQ, 0xfc0007ff00000000, 0xfc00044400000000, 0x0, // DFP Divide Quad X-form (ddivq FRTp,FRAp,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DDIVQCC, 0xfc0007ff00000000, 0xfc00044500000000, 0x0, // DFP Divide Quad X-form (ddivq. FRTp,FRAp,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DENBCD, 0xfc0007ff00000000, 0xec00068400000000, 0xf000000000000, // DFP Encode BCD To DPD X-form (denbcd S,FRT,FRB)
+		[6]*argField{ap_ImmUnsigned_11_11, ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DENBCDCC, 0xfc0007ff00000000, 0xec00068500000000, 0xf000000000000, // DFP Encode BCD To DPD X-form (denbcd. S,FRT,FRB)
+		[6]*argField{ap_ImmUnsigned_11_11, ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DENBCDQ, 0xfc0007ff00000000, 0xfc00068400000000, 0xf000000000000, // DFP Encode BCD To DPD Quad X-form (denbcdq S,FRTp,FRBp)
+		[6]*argField{ap_ImmUnsigned_11_11, ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DENBCDQCC, 0xfc0007ff00000000, 0xfc00068500000000, 0xf000000000000, // DFP Encode BCD To DPD Quad X-form (denbcdq. S,FRTp,FRBp)
+		[6]*argField{ap_ImmUnsigned_11_11, ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DIEX, 0xfc0007ff00000000, 0xec0006c400000000, 0x0, // DFP Insert Biased Exponent X-form (diex FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DIEXCC, 0xfc0007ff00000000, 0xec0006c500000000, 0x0, // DFP Insert Biased Exponent X-form (diex. FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DIEXQCC, 0xfc0007ff00000000, 0xfc0006c500000000, 0x0, // DFP Insert Biased Exponent Quad X-form (diexq. FRTp,FRA,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DIEXQ, 0xfc0007fe00000000, 0xfc0006c400000000, 0x0, // DFP Insert Biased Exponent Quad X-form (diexq FRTp,FRA,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DMUL, 0xfc0007ff00000000, 0xec00004400000000, 0x0, // DFP Multiply X-form (dmul FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DMULCC, 0xfc0007ff00000000, 0xec00004500000000, 0x0, // DFP Multiply X-form (dmul. FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DMULQ, 0xfc0007ff00000000, 0xfc00004400000000, 0x0, // DFP Multiply Quad X-form (dmulq FRTp,FRAp,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DMULQCC, 0xfc0007ff00000000, 0xfc00004500000000, 0x0, // DFP Multiply Quad X-form (dmulq. FRTp,FRAp,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DQUA, 0xfc0001ff00000000, 0xec00000600000000, 0x0, // DFP Quantize Z23-form (dqua FRT,FRA,FRB,RMC)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DQUACC, 0xfc0001ff00000000, 0xec00000700000000, 0x0, // DFP Quantize Z23-form (dqua. FRT,FRA,FRB,RMC)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DQUAI, 0xfc0001ff00000000, 0xec00008600000000, 0x0, // DFP Quantize Immediate Z23-form (dquai TE,FRT,FRB,RMC)
+		[6]*argField{ap_ImmSigned_11_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DQUAICC, 0xfc0001ff00000000, 0xec00008700000000, 0x0, // DFP Quantize Immediate Z23-form (dquai. TE,FRT,FRB,RMC)
+		[6]*argField{ap_ImmSigned_11_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DQUAIQ, 0xfc0001ff00000000, 0xfc00008600000000, 0x0, // DFP Quantize Immediate Quad Z23-form (dquaiq TE,FRTp,FRBp,RMC)
+		[6]*argField{ap_ImmSigned_11_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DQUAIQCC, 0xfc0001ff00000000, 0xfc00008700000000, 0x0, // DFP Quantize Immediate Quad Z23-form (dquaiq. TE,FRTp,FRBp,RMC)
+		[6]*argField{ap_ImmSigned_11_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DQUAQ, 0xfc0001ff00000000, 0xfc00000600000000, 0x0, // DFP Quantize Quad Z23-form (dquaq FRTp,FRAp,FRBp,RMC)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DQUAQCC, 0xfc0001ff00000000, 0xfc00000700000000, 0x0, // DFP Quantize Quad Z23-form (dquaq. FRTp,FRAp,FRBp,RMC)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRDPQ, 0xfc0007ff00000000, 0xfc00060400000000, 0x1f000000000000, // DFP Round To DFP Long X-form (drdpq FRTp,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DRDPQCC, 0xfc0007ff00000000, 0xfc00060500000000, 0x1f000000000000, // DFP Round To DFP Long X-form (drdpq. FRTp,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DRINTN, 0xfc0001ff00000000, 0xec0001c600000000, 0x1e000000000000, // DFP Round To FP Integer Without Inexact Z23-form (drintn R,FRT,FRB,RMC)
+		[6]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRINTNCC, 0xfc0001ff00000000, 0xec0001c700000000, 0x1e000000000000, // DFP Round To FP Integer Without Inexact Z23-form (drintn. R,FRT,FRB,RMC)
+		[6]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRINTNQ, 0xfc0001ff00000000, 0xfc0001c600000000, 0x1e000000000000, // DFP Round To FP Integer Without Inexact Quad Z23-form (drintnq R,FRTp,FRBp,RMC)
+		[6]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRINTNQCC, 0xfc0001ff00000000, 0xfc0001c700000000, 0x1e000000000000, // DFP Round To FP Integer Without Inexact Quad Z23-form (drintnq. R,FRTp,FRBp,RMC)
+		[6]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRINTX, 0xfc0001ff00000000, 0xec0000c600000000, 0x1e000000000000, // DFP Round To FP Integer With Inexact Z23-form (drintx R,FRT,FRB,RMC)
+		[6]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRINTXCC, 0xfc0001ff00000000, 0xec0000c700000000, 0x1e000000000000, // DFP Round To FP Integer With Inexact Z23-form (drintx. R,FRT,FRB,RMC)
+		[6]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRINTXQ, 0xfc0001ff00000000, 0xfc0000c600000000, 0x1e000000000000, // DFP Round To FP Integer With Inexact Quad Z23-form (drintxq R,FRTp,FRBp,RMC)
+		[6]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRINTXQCC, 0xfc0001ff00000000, 0xfc0000c700000000, 0x1e000000000000, // DFP Round To FP Integer With Inexact Quad Z23-form (drintxq. R,FRTp,FRBp,RMC)
+		[6]*argField{ap_ImmUnsigned_15_15, ap_FPReg_6_10, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRRND, 0xfc0001ff00000000, 0xec00004600000000, 0x0, // DFP Reround Z23-form (drrnd FRT,FRA,FRB,RMC)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRRNDCC, 0xfc0001ff00000000, 0xec00004700000000, 0x0, // DFP Reround Z23-form (drrnd. FRT,FRA,FRB,RMC)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRRNDQ, 0xfc0001ff00000000, 0xfc00004600000000, 0x0, // DFP Reround Quad Z23-form (drrndq FRTp,FRA,FRBp,RMC)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRRNDQCC, 0xfc0001ff00000000, 0xfc00004700000000, 0x0, // DFP Reround Quad Z23-form (drrndq. FRTp,FRA,FRBp,RMC)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20, ap_ImmUnsigned_21_22}},
+	{DRSP, 0xfc0007ff00000000, 0xec00060400000000, 0x1f000000000000, // DFP Round To DFP Short X-form (drsp FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DRSPCC, 0xfc0007ff00000000, 0xec00060500000000, 0x1f000000000000, // DFP Round To DFP Short X-form (drsp. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DSCLI, 0xfc0003ff00000000, 0xec00008400000000, 0x0, // DFP Shift Significand Left Immediate Z22-form (dscli FRT,FRA,SH)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
+	{DSCLICC, 0xfc0003ff00000000, 0xec00008500000000, 0x0, // DFP Shift Significand Left Immediate Z22-form (dscli. FRT,FRA,SH)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
+	{DSCLIQ, 0xfc0003ff00000000, 0xfc00008400000000, 0x0, // DFP Shift Significand Left Immediate Quad Z22-form (dscliq FRTp,FRAp,SH)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
+	{DSCLIQCC, 0xfc0003ff00000000, 0xfc00008500000000, 0x0, // DFP Shift Significand Left Immediate Quad Z22-form (dscliq. FRTp,FRAp,SH)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
+	{DSCRI, 0xfc0003ff00000000, 0xec0000c400000000, 0x0, // DFP Shift Significand Right Immediate Z22-form (dscri FRT,FRA,SH)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
+	{DSCRICC, 0xfc0003ff00000000, 0xec0000c500000000, 0x0, // DFP Shift Significand Right Immediate Z22-form (dscri. FRT,FRA,SH)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
+	{DSCRIQ, 0xfc0003ff00000000, 0xfc0000c400000000, 0x0, // DFP Shift Significand Right Immediate Quad Z22-form (dscriq FRTp,FRAp,SH)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
+	{DSCRIQCC, 0xfc0003ff00000000, 0xfc0000c500000000, 0x0, // DFP Shift Significand Right Immediate Quad Z22-form (dscriq. FRTp,FRAp,SH)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
+	{DSUB, 0xfc0007ff00000000, 0xec00040400000000, 0x0, // DFP Subtract X-form (dsub FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DSUBCC, 0xfc0007ff00000000, 0xec00040500000000, 0x0, // DFP Subtract X-form (dsub. FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DSUBQ, 0xfc0007ff00000000, 0xfc00040400000000, 0x0, // DFP Subtract Quad X-form (dsubq FRTp,FRAp,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DSUBQCC, 0xfc0007ff00000000, 0xfc00040500000000, 0x0, // DFP Subtract Quad X-form (dsubq. FRTp,FRAp,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DTSTDC, 0xfc0003fe00000000, 0xec00018400000000, 0x60000100000000, // DFP Test Data Class Z22-form (dtstdc BF,FRA,DCM)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
+	{DTSTDCQ, 0xfc0003fe00000000, 0xfc00018400000000, 0x60000100000000, // DFP Test Data Class Quad Z22-form (dtstdcq BF,FRAp,DCM)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
+	{DTSTDG, 0xfc0003fe00000000, 0xec0001c400000000, 0x60000100000000, // DFP Test Data Group Z22-form (dtstdg BF,FRA,DGM)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
+	{DTSTDGQ, 0xfc0003fe00000000, 0xfc0001c400000000, 0x60000100000000, // DFP Test Data Group Quad Z22-form (dtstdgq BF,FRAp,DGM)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_ImmUnsigned_16_21}},
+	{DTSTEX, 0xfc0007fe00000000, 0xec00014400000000, 0x60000100000000, // DFP Test Exponent X-form (dtstex BF,FRA,FRB)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DTSTEXQ, 0xfc0007fe00000000, 0xfc00014400000000, 0x60000100000000, // DFP Test Exponent Quad X-form (dtstexq BF,FRAp,FRBp)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DTSTSF, 0xfc0007fe00000000, 0xec00054400000000, 0x60000100000000, // DFP Test Significance X-form (dtstsf BF,FRA,FRB)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DTSTSFQ, 0xfc0007fe00000000, 0xfc00054400000000, 0x60000100000000, // DFP Test Significance Quad X-form (dtstsfq BF,FRA,FRBp)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{DXEX, 0xfc0007ff00000000, 0xec0002c400000000, 0x1f000000000000, // DFP Extract Biased Exponent X-form (dxex FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DXEXCC, 0xfc0007ff00000000, 0xec0002c500000000, 0x1f000000000000, // DFP Extract Biased Exponent X-form (dxex. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DXEXQ, 0xfc0007ff00000000, 0xfc0002c400000000, 0x1f000000000000, // DFP Extract Biased Exponent Quad X-form (dxexq FRT,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{DXEXQCC, 0xfc0007ff00000000, 0xfc0002c500000000, 0x1f000000000000, // DFP Extract Biased Exponent Quad X-form (dxexq. FRT,FRBp)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCPSGN, 0xfc0007ff00000000, 0xfc00001000000000, 0x0, // Floating Copy Sign X-form (fcpsgn FRT, FRA, FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FCPSGNCC, 0xfc0007ff00000000, 0xfc00001100000000, 0x0, // Floating Copy Sign X-form (fcpsgn. FRT, FRA, FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{LBZCIX, 0xfc0007fe00000000, 0x7c0006aa00000000, 0x100000000, // Load Byte & Zero Caching Inhibited Indexed X-form (lbzcix RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LDCIX, 0xfc0007fe00000000, 0x7c0006ea00000000, 0x100000000, // Load Doubleword Caching Inhibited Indexed X-form (ldcix RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LFDP, 0xfc00000300000000, 0xe400000000000000, 0x0, // Load Floating-Point Double Pair DS-form (lfdp FRTp,DS(RA))
+		[6]*argField{ap_FPReg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
+	{LFDPX, 0xfc0007fe00000000, 0x7c00062e00000000, 0x100000000, // Load Floating-Point Double Pair Indexed X-form (lfdpx FRTp,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LFIWAX, 0xfc0007fe00000000, 0x7c0006ae00000000, 0x100000000, // Load Floating-Point as Integer Word Algebraic Indexed X-form (lfiwax FRT,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LHZCIX, 0xfc0007fe00000000, 0x7c00066a00000000, 0x100000000, // Load Halfword & Zero Caching Inhibited Indexed X-form (lhzcix RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LWZCIX, 0xfc0007fe00000000, 0x7c00062a00000000, 0x100000000, // Load Word & Zero Caching Inhibited Indexed X-form (lwzcix RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{PRTYD, 0xfc0007fe00000000, 0x7c00017400000000, 0xf80100000000, // Parity Doubleword X-form (prtyd RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{PRTYW, 0xfc0007fe00000000, 0x7c00013400000000, 0xf80100000000, // Parity Word X-form (prtyw RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{SLBFEECC, 0xfc0007ff00000000, 0x7c0007a700000000, 0x1f000000000000, // SLB Find Entry ESID X-form (slbfee. RT,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_16_20}},
+	{STBCIX, 0xfc0007fe00000000, 0x7c0007aa00000000, 0x100000000, // Store Byte Caching Inhibited Indexed X-form (stbcix RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STDCIX, 0xfc0007fe00000000, 0x7c0007ea00000000, 0x100000000, // Store Doubleword Caching Inhibited Indexed X-form (stdcix RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STFDP, 0xfc00000300000000, 0xf400000000000000, 0x0, // Store Floating-Point Double Pair DS-form (stfdp FRSp,DS(RA))
+		[6]*argField{ap_FPReg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
+	{STFDPX, 0xfc0007fe00000000, 0x7c00072e00000000, 0x100000000, // Store Floating-Point Double Pair Indexed X-form (stfdpx FRSp,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STHCIX, 0xfc0007fe00000000, 0x7c00076a00000000, 0x100000000, // Store Halfword Caching Inhibited Indexed X-form (sthcix RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STWCIX, 0xfc0007fe00000000, 0x7c00072a00000000, 0x100000000, // Store Word Caching Inhibited Indexed X-form (stwcix RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{ISEL, 0xfc00003e00000000, 0x7c00001e00000000, 0x100000000, // Integer Select A-form (isel RT,RA,RB,BC)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_CondRegBit_21_25}},
+	{LVEBX, 0xfc0007fe00000000, 0x7c00000e00000000, 0x100000000, // Load Vector Element Byte Indexed X-form (lvebx VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LVEHX, 0xfc0007fe00000000, 0x7c00004e00000000, 0x100000000, // Load Vector Element Halfword Indexed X-form (lvehx VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LVEWX, 0xfc0007fe00000000, 0x7c00008e00000000, 0x100000000, // Load Vector Element Word Indexed X-form (lvewx VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LVSL, 0xfc0007fe00000000, 0x7c00000c00000000, 0x100000000, // Load Vector for Shift Left Indexed X-form (lvsl VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LVSR, 0xfc0007fe00000000, 0x7c00004c00000000, 0x100000000, // Load Vector for Shift Right Indexed X-form (lvsr VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LVX, 0xfc0007fe00000000, 0x7c0000ce00000000, 0x100000000, // Load Vector Indexed X-form (lvx VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LVXL, 0xfc0007fe00000000, 0x7c0002ce00000000, 0x100000000, // Load Vector Indexed Last X-form (lvxl VRT,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MFVSCR, 0xfc0007ff00000000, 0x1000060400000000, 0x1ff80000000000, // Move From Vector Status and Control Register VX-form (mfvscr VRT)
+		[6]*argField{ap_VecReg_6_10}},
+	{MTVSCR, 0xfc0007ff00000000, 0x1000064400000000, 0x3ff000000000000, // Move To Vector Status and Control Register VX-form (mtvscr VRB)
+		[6]*argField{ap_VecReg_16_20}},
+	{STVEBX, 0xfc0007fe00000000, 0x7c00010e00000000, 0x100000000, // Store Vector Element Byte Indexed X-form (stvebx VRS,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STVEHX, 0xfc0007fe00000000, 0x7c00014e00000000, 0x100000000, // Store Vector Element Halfword Indexed X-form (stvehx VRS,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STVEWX, 0xfc0007fe00000000, 0x7c00018e00000000, 0x100000000, // Store Vector Element Word Indexed X-form (stvewx VRS,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STVX, 0xfc0007fe00000000, 0x7c0001ce00000000, 0x100000000, // Store Vector Indexed X-form (stvx VRS,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STVXL, 0xfc0007fe00000000, 0x7c0003ce00000000, 0x100000000, // Store Vector Indexed Last X-form (stvxl VRS,RA,RB)
+		[6]*argField{ap_VecReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{TLBIEL, 0xfc0007fe00000000, 0x7c00022400000000, 0x10000100000000, // TLB Invalidate Entry Local X-form (tlbiel RB,RS,RIC,PRS,R)
+		[6]*argField{ap_Reg_16_20, ap_Reg_6_10, ap_ImmUnsigned_12_13, ap_ImmUnsigned_14_14, ap_ImmUnsigned_15_15}},
+	{VADDCUW, 0xfc0007ff00000000, 0x1000018000000000, 0x0, // Vector Add & write Carry Unsigned Word VX-form (vaddcuw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VADDFP, 0xfc0007ff00000000, 0x1000000a00000000, 0x0, // Vector Add Floating-Point VX-form (vaddfp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VADDSBS, 0xfc0007ff00000000, 0x1000030000000000, 0x0, // Vector Add Signed Byte Saturate VX-form (vaddsbs VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VADDSHS, 0xfc0007ff00000000, 0x1000034000000000, 0x0, // Vector Add Signed Halfword Saturate VX-form (vaddshs VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VADDSWS, 0xfc0007ff00000000, 0x1000038000000000, 0x0, // Vector Add Signed Word Saturate VX-form (vaddsws VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VADDUBM, 0xfc0007ff00000000, 0x1000000000000000, 0x0, // Vector Add Unsigned Byte Modulo VX-form (vaddubm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VADDUBS, 0xfc0007ff00000000, 0x1000020000000000, 0x0, // Vector Add Unsigned Byte Saturate VX-form (vaddubs VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VADDUHM, 0xfc0007ff00000000, 0x1000004000000000, 0x0, // Vector Add Unsigned Halfword Modulo VX-form (vadduhm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VADDUHS, 0xfc0007ff00000000, 0x1000024000000000, 0x0, // Vector Add Unsigned Halfword Saturate VX-form (vadduhs VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VADDUWM, 0xfc0007ff00000000, 0x1000008000000000, 0x0, // Vector Add Unsigned Word Modulo VX-form (vadduwm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VADDUWS, 0xfc0007ff00000000, 0x1000028000000000, 0x0, // Vector Add Unsigned Word Saturate VX-form (vadduws VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VAND, 0xfc0007ff00000000, 0x1000040400000000, 0x0, // Vector Logical AND VX-form (vand VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VANDC, 0xfc0007ff00000000, 0x1000044400000000, 0x0, // Vector Logical AND with Complement VX-form (vandc VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VAVGSB, 0xfc0007ff00000000, 0x1000050200000000, 0x0, // Vector Average Signed Byte VX-form (vavgsb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VAVGSH, 0xfc0007ff00000000, 0x1000054200000000, 0x0, // Vector Average Signed Halfword VX-form (vavgsh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VAVGSW, 0xfc0007ff00000000, 0x1000058200000000, 0x0, // Vector Average Signed Word VX-form (vavgsw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VAVGUB, 0xfc0007ff00000000, 0x1000040200000000, 0x0, // Vector Average Unsigned Byte VX-form (vavgub VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VAVGUH, 0xfc0007ff00000000, 0x1000044200000000, 0x0, // Vector Average Unsigned Halfword VX-form (vavguh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VAVGUW, 0xfc0007ff00000000, 0x1000048200000000, 0x0, // Vector Average Unsigned Word VX-form (vavguw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCFSX, 0xfc0007ff00000000, 0x1000034a00000000, 0x0, // Vector Convert with round to nearest From Signed Word to floating-point format VX-form (vcfsx VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}},
+	{VCFUX, 0xfc0007ff00000000, 0x1000030a00000000, 0x0, // Vector Convert with round to nearest From Unsigned Word to floating-point format VX-form (vcfux VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}},
+	{VCMPBFP, 0xfc0007ff00000000, 0x100003c600000000, 0x0, // Vector Compare Bounds Floating-Point VC-form (vcmpbfp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPBFPCC, 0xfc0007ff00000000, 0x100007c600000000, 0x0, // Vector Compare Bounds Floating-Point VC-form (vcmpbfp. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPEQFP, 0xfc0007ff00000000, 0x100000c600000000, 0x0, // Vector Compare Equal Floating-Point VC-form (vcmpeqfp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPEQFPCC, 0xfc0007ff00000000, 0x100004c600000000, 0x0, // Vector Compare Equal Floating-Point VC-form (vcmpeqfp. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPEQUB, 0xfc0007ff00000000, 0x1000000600000000, 0x0, // Vector Compare Equal Unsigned Byte VC-form (vcmpequb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPEQUBCC, 0xfc0007ff00000000, 0x1000040600000000, 0x0, // Vector Compare Equal Unsigned Byte VC-form (vcmpequb. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPEQUH, 0xfc0007ff00000000, 0x1000004600000000, 0x0, // Vector Compare Equal Unsigned Halfword VC-form (vcmpequh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPEQUHCC, 0xfc0007ff00000000, 0x1000044600000000, 0x0, // Vector Compare Equal Unsigned Halfword VC-form (vcmpequh. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPEQUW, 0xfc0007ff00000000, 0x1000008600000000, 0x0, // Vector Compare Equal Unsigned Word VC-form (vcmpequw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPEQUWCC, 0xfc0007ff00000000, 0x1000048600000000, 0x0, // Vector Compare Equal Unsigned Word VC-form (vcmpequw. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGEFP, 0xfc0007ff00000000, 0x100001c600000000, 0x0, // Vector Compare Greater Than or Equal Floating-Point VC-form (vcmpgefp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGEFPCC, 0xfc0007ff00000000, 0x100005c600000000, 0x0, // Vector Compare Greater Than or Equal Floating-Point VC-form (vcmpgefp. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTFP, 0xfc0007ff00000000, 0x100002c600000000, 0x0, // Vector Compare Greater Than Floating-Point VC-form (vcmpgtfp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTFPCC, 0xfc0007ff00000000, 0x100006c600000000, 0x0, // Vector Compare Greater Than Floating-Point VC-form (vcmpgtfp. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTSB, 0xfc0007ff00000000, 0x1000030600000000, 0x0, // Vector Compare Greater Than Signed Byte VC-form (vcmpgtsb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTSBCC, 0xfc0007ff00000000, 0x1000070600000000, 0x0, // Vector Compare Greater Than Signed Byte VC-form (vcmpgtsb. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTSH, 0xfc0007ff00000000, 0x1000034600000000, 0x0, // Vector Compare Greater Than Signed Halfword VC-form (vcmpgtsh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTSHCC, 0xfc0007ff00000000, 0x1000074600000000, 0x0, // Vector Compare Greater Than Signed Halfword VC-form (vcmpgtsh. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTSW, 0xfc0007ff00000000, 0x1000038600000000, 0x0, // Vector Compare Greater Than Signed Word VC-form (vcmpgtsw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTSWCC, 0xfc0007ff00000000, 0x1000078600000000, 0x0, // Vector Compare Greater Than Signed Word VC-form (vcmpgtsw. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTUB, 0xfc0007ff00000000, 0x1000020600000000, 0x0, // Vector Compare Greater Than Unsigned Byte VC-form (vcmpgtub VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTUBCC, 0xfc0007ff00000000, 0x1000060600000000, 0x0, // Vector Compare Greater Than Unsigned Byte VC-form (vcmpgtub. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTUH, 0xfc0007ff00000000, 0x1000024600000000, 0x0, // Vector Compare Greater Than Unsigned Halfword VC-form (vcmpgtuh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTUHCC, 0xfc0007ff00000000, 0x1000064600000000, 0x0, // Vector Compare Greater Than Unsigned Halfword VC-form (vcmpgtuh. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTUW, 0xfc0007ff00000000, 0x1000028600000000, 0x0, // Vector Compare Greater Than Unsigned Word VC-form (vcmpgtuw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPGTUWCC, 0xfc0007ff00000000, 0x1000068600000000, 0x0, // Vector Compare Greater Than Unsigned Word VC-form (vcmpgtuw. VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCTSXS, 0xfc0007ff00000000, 0x100003ca00000000, 0x0, // Vector Convert with round to zero from floating-point To Signed Word format Saturate VX-form (vctsxs VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}},
+	{VCTUXS, 0xfc0007ff00000000, 0x1000038a00000000, 0x0, // Vector Convert with round to zero from floating-point To Unsigned Word format Saturate VX-form (vctuxs VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_11_15}},
+	{VEXPTEFP, 0xfc0007ff00000000, 0x1000018a00000000, 0x1f000000000000, // Vector 2 Raised to the Exponent Estimate Floating-Point VX-form (vexptefp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VLOGEFP, 0xfc0007ff00000000, 0x100001ca00000000, 0x1f000000000000, // Vector Log Base 2 Estimate Floating-Point VX-form (vlogefp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VMADDFP, 0xfc00003f00000000, 0x1000002e00000000, 0x0, // Vector Multiply-Add Floating-Point VA-form (vmaddfp VRT,VRA,VRC,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_21_25, ap_VecReg_16_20}},
+	{VMAXFP, 0xfc0007ff00000000, 0x1000040a00000000, 0x0, // Vector Maximum Floating-Point VX-form (vmaxfp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMAXSB, 0xfc0007ff00000000, 0x1000010200000000, 0x0, // Vector Maximum Signed Byte VX-form (vmaxsb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMAXSH, 0xfc0007ff00000000, 0x1000014200000000, 0x0, // Vector Maximum Signed Halfword VX-form (vmaxsh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMAXSW, 0xfc0007ff00000000, 0x1000018200000000, 0x0, // Vector Maximum Signed Word VX-form (vmaxsw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMAXUB, 0xfc0007ff00000000, 0x1000000200000000, 0x0, // Vector Maximum Unsigned Byte VX-form (vmaxub VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMAXUH, 0xfc0007ff00000000, 0x1000004200000000, 0x0, // Vector Maximum Unsigned Halfword VX-form (vmaxuh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMAXUW, 0xfc0007ff00000000, 0x1000008200000000, 0x0, // Vector Maximum Unsigned Word VX-form (vmaxuw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMHADDSHS, 0xfc00003f00000000, 0x1000002000000000, 0x0, // Vector Multiply-High-Add Signed Halfword Saturate VA-form (vmhaddshs VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VMHRADDSHS, 0xfc00003f00000000, 0x1000002100000000, 0x0, // Vector Multiply-High-Round-Add Signed Halfword Saturate VA-form (vmhraddshs VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VMINFP, 0xfc0007ff00000000, 0x1000044a00000000, 0x0, // Vector Minimum Floating-Point VX-form (vminfp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMINSB, 0xfc0007ff00000000, 0x1000030200000000, 0x0, // Vector Minimum Signed Byte VX-form (vminsb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMINSH, 0xfc0007ff00000000, 0x1000034200000000, 0x0, // Vector Minimum Signed Halfword VX-form (vminsh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMINSW, 0xfc0007ff00000000, 0x1000038200000000, 0x0, // Vector Minimum Signed Word VX-form (vminsw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMINUB, 0xfc0007ff00000000, 0x1000020200000000, 0x0, // Vector Minimum Unsigned Byte VX-form (vminub VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMINUH, 0xfc0007ff00000000, 0x1000024200000000, 0x0, // Vector Minimum Unsigned Halfword VX-form (vminuh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMINUW, 0xfc0007ff00000000, 0x1000028200000000, 0x0, // Vector Minimum Unsigned Word VX-form (vminuw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMLADDUHM, 0xfc00003f00000000, 0x1000002200000000, 0x0, // Vector Multiply-Low-Add Unsigned Halfword Modulo VA-form (vmladduhm VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VMRGHB, 0xfc0007ff00000000, 0x1000000c00000000, 0x0, // Vector Merge High Byte VX-form (vmrghb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMRGHH, 0xfc0007ff00000000, 0x1000004c00000000, 0x0, // Vector Merge High Halfword VX-form (vmrghh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMRGHW, 0xfc0007ff00000000, 0x1000008c00000000, 0x0, // Vector Merge High Word VX-form (vmrghw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMRGLB, 0xfc0007ff00000000, 0x1000010c00000000, 0x0, // Vector Merge Low Byte VX-form (vmrglb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMRGLH, 0xfc0007ff00000000, 0x1000014c00000000, 0x0, // Vector Merge Low Halfword VX-form (vmrglh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMRGLW, 0xfc0007ff00000000, 0x1000018c00000000, 0x0, // Vector Merge Low Word VX-form (vmrglw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMSUMMBM, 0xfc00003f00000000, 0x1000002500000000, 0x0, // Vector Multiply-Sum Mixed Byte Modulo VA-form (vmsummbm VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VMSUMSHM, 0xfc00003f00000000, 0x1000002800000000, 0x0, // Vector Multiply-Sum Signed Halfword Modulo VA-form (vmsumshm VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VMSUMSHS, 0xfc00003f00000000, 0x1000002900000000, 0x0, // Vector Multiply-Sum Signed Halfword Saturate VA-form (vmsumshs VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VMSUMUBM, 0xfc00003f00000000, 0x1000002400000000, 0x0, // Vector Multiply-Sum Unsigned Byte Modulo VA-form (vmsumubm VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VMSUMUHM, 0xfc00003f00000000, 0x1000002600000000, 0x0, // Vector Multiply-Sum Unsigned Halfword Modulo VA-form (vmsumuhm VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VMSUMUHS, 0xfc00003f00000000, 0x1000002700000000, 0x0, // Vector Multiply-Sum Unsigned Halfword Saturate VA-form (vmsumuhs VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VMULESB, 0xfc0007ff00000000, 0x1000030800000000, 0x0, // Vector Multiply Even Signed Byte VX-form (vmulesb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULESH, 0xfc0007ff00000000, 0x1000034800000000, 0x0, // Vector Multiply Even Signed Halfword VX-form (vmulesh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULEUB, 0xfc0007ff00000000, 0x1000020800000000, 0x0, // Vector Multiply Even Unsigned Byte VX-form (vmuleub VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULEUH, 0xfc0007ff00000000, 0x1000024800000000, 0x0, // Vector Multiply Even Unsigned Halfword VX-form (vmuleuh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULOSB, 0xfc0007ff00000000, 0x1000010800000000, 0x0, // Vector Multiply Odd Signed Byte VX-form (vmulosb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULOSH, 0xfc0007ff00000000, 0x1000014800000000, 0x0, // Vector Multiply Odd Signed Halfword VX-form (vmulosh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULOUB, 0xfc0007ff00000000, 0x1000000800000000, 0x0, // Vector Multiply Odd Unsigned Byte VX-form (vmuloub VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VMULOUH, 0xfc0007ff00000000, 0x1000004800000000, 0x0, // Vector Multiply Odd Unsigned Halfword VX-form (vmulouh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VNMSUBFP, 0xfc00003f00000000, 0x1000002f00000000, 0x0, // Vector Negative Multiply-Subtract Floating-Point VA-form (vnmsubfp VRT,VRA,VRC,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_21_25, ap_VecReg_16_20}},
+	{VNOR, 0xfc0007ff00000000, 0x1000050400000000, 0x0, // Vector Logical NOR VX-form (vnor VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VOR, 0xfc0007ff00000000, 0x1000048400000000, 0x0, // Vector Logical OR VX-form (vor VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPERM, 0xfc00003f00000000, 0x1000002b00000000, 0x0, // Vector Permute VA-form (vperm VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VPKPX, 0xfc0007ff00000000, 0x1000030e00000000, 0x0, // Vector Pack Pixel VX-form (vpkpx VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPKSHSS, 0xfc0007ff00000000, 0x1000018e00000000, 0x0, // Vector Pack Signed Halfword Signed Saturate VX-form (vpkshss VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPKSHUS, 0xfc0007ff00000000, 0x1000010e00000000, 0x0, // Vector Pack Signed Halfword Unsigned Saturate VX-form (vpkshus VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPKSWSS, 0xfc0007ff00000000, 0x100001ce00000000, 0x0, // Vector Pack Signed Word Signed Saturate VX-form (vpkswss VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPKSWUS, 0xfc0007ff00000000, 0x1000014e00000000, 0x0, // Vector Pack Signed Word Unsigned Saturate VX-form (vpkswus VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPKUHUM, 0xfc0007ff00000000, 0x1000000e00000000, 0x0, // Vector Pack Unsigned Halfword Unsigned Modulo VX-form (vpkuhum VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPKUHUS, 0xfc0007ff00000000, 0x1000008e00000000, 0x0, // Vector Pack Unsigned Halfword Unsigned Saturate VX-form (vpkuhus VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPKUWUM, 0xfc0007ff00000000, 0x1000004e00000000, 0x0, // Vector Pack Unsigned Word Unsigned Modulo VX-form (vpkuwum VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VPKUWUS, 0xfc0007ff00000000, 0x100000ce00000000, 0x0, // Vector Pack Unsigned Word Unsigned Saturate VX-form (vpkuwus VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VREFP, 0xfc0007ff00000000, 0x1000010a00000000, 0x1f000000000000, // Vector Reciprocal Estimate Floating-Point VX-form (vrefp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VRFIM, 0xfc0007ff00000000, 0x100002ca00000000, 0x1f000000000000, // Vector Round to Floating-Point Integer toward -Infinity VX-form (vrfim VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VRFIN, 0xfc0007ff00000000, 0x1000020a00000000, 0x1f000000000000, // Vector Round to Floating-Point Integer Nearest VX-form (vrfin VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VRFIP, 0xfc0007ff00000000, 0x1000028a00000000, 0x1f000000000000, // Vector Round to Floating-Point Integer toward +Infinity VX-form (vrfip VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VRFIZ, 0xfc0007ff00000000, 0x1000024a00000000, 0x1f000000000000, // Vector Round to Floating-Point Integer toward Zero VX-form (vrfiz VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VRLB, 0xfc0007ff00000000, 0x1000000400000000, 0x0, // Vector Rotate Left Byte VX-form (vrlb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VRLH, 0xfc0007ff00000000, 0x1000004400000000, 0x0, // Vector Rotate Left Halfword VX-form (vrlh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VRLW, 0xfc0007ff00000000, 0x1000008400000000, 0x0, // Vector Rotate Left Word VX-form (vrlw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VRSQRTEFP, 0xfc0007ff00000000, 0x1000014a00000000, 0x1f000000000000, // Vector Reciprocal Square Root Estimate Floating-Point VX-form (vrsqrtefp VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VSEL, 0xfc00003f00000000, 0x1000002a00000000, 0x0, // Vector Select VA-form (vsel VRT,VRA,VRB,VRC)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VSL, 0xfc0007ff00000000, 0x100001c400000000, 0x0, // Vector Shift Left VX-form (vsl VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSLB, 0xfc0007ff00000000, 0x1000010400000000, 0x0, // Vector Shift Left Byte VX-form (vslb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSLDOI, 0xfc00003f00000000, 0x1000002c00000000, 0x40000000000, // Vector Shift Left Double by Octet Immediate VA-form (vsldoi VRT,VRA,VRB,SHB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_25}},
+	{VSLH, 0xfc0007ff00000000, 0x1000014400000000, 0x0, // Vector Shift Left Halfword VX-form (vslh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSLO, 0xfc0007ff00000000, 0x1000040c00000000, 0x0, // Vector Shift Left by Octet VX-form (vslo VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSLW, 0xfc0007ff00000000, 0x1000018400000000, 0x0, // Vector Shift Left Word VX-form (vslw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSPLTB, 0xfc0007ff00000000, 0x1000020c00000000, 0x10000000000000, // Vector Splat Byte VX-form (vspltb VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_12_15}},
+	{VSPLTH, 0xfc0007ff00000000, 0x1000024c00000000, 0x18000000000000, // Vector Splat Halfword VX-form (vsplth VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_13_15}},
+	{VSPLTISB, 0xfc0007ff00000000, 0x1000030c00000000, 0xf80000000000, // Vector Splat Immediate Signed Byte VX-form (vspltisb VRT,SIM)
+		[6]*argField{ap_VecReg_6_10, ap_ImmSigned_11_15}},
+	{VSPLTISH, 0xfc0007ff00000000, 0x1000034c00000000, 0xf80000000000, // Vector Splat Immediate Signed Halfword VX-form (vspltish VRT,SIM)
+		[6]*argField{ap_VecReg_6_10, ap_ImmSigned_11_15}},
+	{VSPLTISW, 0xfc0007ff00000000, 0x1000038c00000000, 0xf80000000000, // Vector Splat Immediate Signed Word VX-form (vspltisw VRT,SIM)
+		[6]*argField{ap_VecReg_6_10, ap_ImmSigned_11_15}},
+	{VSPLTW, 0xfc0007ff00000000, 0x1000028c00000000, 0x1c000000000000, // Vector Splat Word VX-form (vspltw VRT,VRB,UIM)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20, ap_ImmUnsigned_14_15}},
+	{VSR, 0xfc0007ff00000000, 0x100002c400000000, 0x0, // Vector Shift Right VX-form (vsr VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSRAB, 0xfc0007ff00000000, 0x1000030400000000, 0x0, // Vector Shift Right Algebraic Byte VX-form (vsrab VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSRAH, 0xfc0007ff00000000, 0x1000034400000000, 0x0, // Vector Shift Right Algebraic Halfword VX-form (vsrah VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSRAW, 0xfc0007ff00000000, 0x1000038400000000, 0x0, // Vector Shift Right Algebraic Word VX-form (vsraw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSRB, 0xfc0007ff00000000, 0x1000020400000000, 0x0, // Vector Shift Right Byte VX-form (vsrb VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSRH, 0xfc0007ff00000000, 0x1000024400000000, 0x0, // Vector Shift Right Halfword VX-form (vsrh VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSRO, 0xfc0007ff00000000, 0x1000044c00000000, 0x0, // Vector Shift Right by Octet VX-form (vsro VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSRW, 0xfc0007ff00000000, 0x1000028400000000, 0x0, // Vector Shift Right Word VX-form (vsrw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBCUW, 0xfc0007ff00000000, 0x1000058000000000, 0x0, // Vector Subtract & Write Carry-out Unsigned Word VX-form (vsubcuw VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBFP, 0xfc0007ff00000000, 0x1000004a00000000, 0x0, // Vector Subtract Floating-Point VX-form (vsubfp VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBSBS, 0xfc0007ff00000000, 0x1000070000000000, 0x0, // Vector Subtract Signed Byte Saturate VX-form (vsubsbs VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBSHS, 0xfc0007ff00000000, 0x1000074000000000, 0x0, // Vector Subtract Signed Halfword Saturate VX-form (vsubshs VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBSWS, 0xfc0007ff00000000, 0x1000078000000000, 0x0, // Vector Subtract Signed Word Saturate VX-form (vsubsws VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBUBM, 0xfc0007ff00000000, 0x1000040000000000, 0x0, // Vector Subtract Unsigned Byte Modulo VX-form (vsububm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBUBS, 0xfc0007ff00000000, 0x1000060000000000, 0x0, // Vector Subtract Unsigned Byte Saturate VX-form (vsububs VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBUHM, 0xfc0007ff00000000, 0x1000044000000000, 0x0, // Vector Subtract Unsigned Halfword Modulo VX-form (vsubuhm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBUHS, 0xfc0007ff00000000, 0x1000064000000000, 0x0, // Vector Subtract Unsigned Halfword Saturate VX-form (vsubuhs VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBUWM, 0xfc0007ff00000000, 0x1000048000000000, 0x0, // Vector Subtract Unsigned Word Modulo VX-form (vsubuwm VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUBUWS, 0xfc0007ff00000000, 0x1000068000000000, 0x0, // Vector Subtract Unsigned Word Saturate VX-form (vsubuws VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUM2SWS, 0xfc0007ff00000000, 0x1000068800000000, 0x0, // Vector Sum across Half Signed Word Saturate VX-form (vsum2sws VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUM4SBS, 0xfc0007ff00000000, 0x1000070800000000, 0x0, // Vector Sum across Quarter Signed Byte Saturate VX-form (vsum4sbs VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUM4SHS, 0xfc0007ff00000000, 0x1000064800000000, 0x0, // Vector Sum across Quarter Signed Halfword Saturate VX-form (vsum4shs VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUM4UBS, 0xfc0007ff00000000, 0x1000060800000000, 0x0, // Vector Sum across Quarter Unsigned Byte Saturate VX-form (vsum4ubs VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VSUMSWS, 0xfc0007ff00000000, 0x1000078800000000, 0x0, // Vector Sum across Signed Word Saturate VX-form (vsumsws VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VUPKHPX, 0xfc0007ff00000000, 0x1000034e00000000, 0x1f000000000000, // Vector Unpack High Pixel VX-form (vupkhpx VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VUPKHSB, 0xfc0007ff00000000, 0x1000020e00000000, 0x1f000000000000, // Vector Unpack High Signed Byte VX-form (vupkhsb VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VUPKHSH, 0xfc0007ff00000000, 0x1000024e00000000, 0x1f000000000000, // Vector Unpack High Signed Halfword VX-form (vupkhsh VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VUPKLPX, 0xfc0007ff00000000, 0x100003ce00000000, 0x1f000000000000, // Vector Unpack Low Pixel VX-form (vupklpx VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VUPKLSB, 0xfc0007ff00000000, 0x1000028e00000000, 0x1f000000000000, // Vector Unpack Low Signed Byte VX-form (vupklsb VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VUPKLSH, 0xfc0007ff00000000, 0x100002ce00000000, 0x1f000000000000, // Vector Unpack Low Signed Halfword VX-form (vupklsh VRT,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
+	{VXOR, 0xfc0007ff00000000, 0x100004c400000000, 0x0, // Vector Logical XOR VX-form (vxor VRT,VRA,VRB)
+		[6]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{FRE, 0xfc00003f00000000, 0xfc00003000000000, 0x1f07c000000000, // Floating Reciprocal Estimate A-form (fre FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRECC, 0xfc00003f00000000, 0xfc00003100000000, 0x1f07c000000000, // Floating Reciprocal Estimate A-form (fre. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRIM, 0xfc0007ff00000000, 0xfc0003d000000000, 0x1f000000000000, // Floating Round to Integer Minus X-form (frim FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRIMCC, 0xfc0007ff00000000, 0xfc0003d100000000, 0x1f000000000000, // Floating Round to Integer Minus X-form (frim. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRIN, 0xfc0007ff00000000, 0xfc00031000000000, 0x1f000000000000, // Floating Round to Integer Nearest X-form (frin FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRINCC, 0xfc0007ff00000000, 0xfc00031100000000, 0x1f000000000000, // Floating Round to Integer Nearest X-form (frin. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRIP, 0xfc0007ff00000000, 0xfc00039000000000, 0x1f000000000000, // Floating Round to Integer Plus X-form (frip FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRIPCC, 0xfc0007ff00000000, 0xfc00039100000000, 0x1f000000000000, // Floating Round to Integer Plus X-form (frip. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRIZ, 0xfc0007ff00000000, 0xfc00035000000000, 0x1f000000000000, // Floating Round to Integer Toward Zero X-form (friz FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRIZCC, 0xfc0007ff00000000, 0xfc00035100000000, 0x1f000000000000, // Floating Round to Integer Toward Zero X-form (friz. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRSQRTES, 0xfc00003f00000000, 0xec00003400000000, 0x1f07c000000000, // Floating Reciprocal Square Root Estimate Single A-form (frsqrtes FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRSQRTESCC, 0xfc00003f00000000, 0xec00003500000000, 0x1f07c000000000, // Floating Reciprocal Square Root Estimate Single A-form (frsqrtes. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{HRFID, 0xfc0007fe00000000, 0x4c00022400000000, 0x3fff80100000000, // Return From Interrupt Doubleword Hypervisor XL-form (hrfid)
+		[6]*argField{}},
+	{POPCNTB, 0xfc0007fe00000000, 0x7c0000f400000000, 0xf80100000000, // Population Count Bytes X-form (popcntb RA, RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{MFOCRF, 0xfc1007fe00000000, 0x7c10002600000000, 0x80100000000, // Move From One Condition Register Field XFX-form (mfocrf RT,FXM)
+		[6]*argField{ap_Reg_6_10, ap_ImmUnsigned_12_19}},
+	{MTOCRF, 0xfc1007fe00000000, 0x7c10012000000000, 0x80100000000, // Move To One Condition Register Field XFX-form (mtocrf FXM,RS)
+		[6]*argField{ap_ImmUnsigned_12_19, ap_Reg_6_10}},
+	{SLBMFEE, 0xfc0007fe00000000, 0x7c00072600000000, 0x1e000100000000, // SLB Move From Entry ESID X-form (slbmfee RT,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_16_20}},
+	{SLBMFEV, 0xfc0007fe00000000, 0x7c0006a600000000, 0x1e000100000000, // SLB Move From Entry VSID X-form (slbmfev RT,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_16_20}},
+	{SLBMTE, 0xfc0007fe00000000, 0x7c00032400000000, 0x1f000100000000, // SLB Move To Entry X-form (slbmte RS,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_16_20}},
+	{RFSCV, 0xfc0007fe00000000, 0x4c0000a400000000, 0x3fff80100000000, // Return From System Call Vectored XL-form (rfscv)
+		[6]*argField{}},
+	{SCV, 0xfc00000300000000, 0x4400000100000000, 0x3fff01c00000000, // System Call Vectored SC-form (scv LEV)
+		[6]*argField{ap_ImmUnsigned_20_26}},
+	{LQ, 0xfc00000000000000, 0xe000000000000000, 0xf00000000, // Load Quadword DQ-form (lq RTp,DQ(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_27_shift4, ap_Reg_11_15}},
+	{STQ, 0xfc00000300000000, 0xf800000200000000, 0x0, // Store Quadword DS-form (stq RSp,DS(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
+	{CNTLZD, 0xfc0007ff00000000, 0x7c00007400000000, 0xf80000000000, // Count Leading Zeros Doubleword X-form (cntlzd RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{CNTLZDCC, 0xfc0007ff00000000, 0x7c00007500000000, 0xf80000000000, // Count Leading Zeros Doubleword X-form (cntlzd. RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{DCBF, 0xfc0007fe00000000, 0x7c0000ac00000000, 0x300000100000000, // Data Cache Block Flush X-form (dcbf RA,RB,L)
+		[6]*argField{ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_8_10}},
+	{DCBST, 0xfc0007fe00000000, 0x7c00006c00000000, 0x3e0000100000000, // Data Cache Block Store X-form (dcbst RA,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_16_20}},
+	{DCBT, 0xfc0007fe00000000, 0x7c00022c00000000, 0x100000000, // Data Cache Block Touch X-form (dcbt RA,RB,TH)
+		[6]*argField{ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_6_10}},
+	{DCBTST, 0xfc0007fe00000000, 0x7c0001ec00000000, 0x100000000, // Data Cache Block Touch for Store X-form (dcbtst RA,RB,TH)
+		[6]*argField{ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_6_10}},
+	{DIVD, 0xfc0007ff00000000, 0x7c0003d200000000, 0x0, // Divide Doubleword XO-form (divd RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDCC, 0xfc0007ff00000000, 0x7c0003d300000000, 0x0, // Divide Doubleword XO-form (divd. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDO, 0xfc0007ff00000000, 0x7c0007d200000000, 0x0, // Divide Doubleword XO-form (divdo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDOCC, 0xfc0007ff00000000, 0x7c0007d300000000, 0x0, // Divide Doubleword XO-form (divdo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDU, 0xfc0007ff00000000, 0x7c00039200000000, 0x0, // Divide Doubleword Unsigned XO-form (divdu RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDUCC, 0xfc0007ff00000000, 0x7c00039300000000, 0x0, // Divide Doubleword Unsigned XO-form (divdu. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDUO, 0xfc0007ff00000000, 0x7c00079200000000, 0x0, // Divide Doubleword Unsigned XO-form (divduo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVDUOCC, 0xfc0007ff00000000, 0x7c00079300000000, 0x0, // Divide Doubleword Unsigned XO-form (divduo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVW, 0xfc0007ff00000000, 0x7c0003d600000000, 0x0, // Divide Word XO-form (divw RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWCC, 0xfc0007ff00000000, 0x7c0003d700000000, 0x0, // Divide Word XO-form (divw. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWO, 0xfc0007ff00000000, 0x7c0007d600000000, 0x0, // Divide Word XO-form (divwo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWOCC, 0xfc0007ff00000000, 0x7c0007d700000000, 0x0, // Divide Word XO-form (divwo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWU, 0xfc0007ff00000000, 0x7c00039600000000, 0x0, // Divide Word Unsigned XO-form (divwu RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWUCC, 0xfc0007ff00000000, 0x7c00039700000000, 0x0, // Divide Word Unsigned XO-form (divwu. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWUO, 0xfc0007ff00000000, 0x7c00079600000000, 0x0, // Divide Word Unsigned XO-form (divwuo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{DIVWUOCC, 0xfc0007ff00000000, 0x7c00079700000000, 0x0, // Divide Word Unsigned XO-form (divwuo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{EIEIO, 0xfc0007fe00000000, 0x7c0006ac00000000, 0x3fff80100000000, // Enforce In-order Execution of I/O X-form (eieio)
+		[6]*argField{}},
+	{EXTSB, 0xfc0007ff00000000, 0x7c00077400000000, 0xf80000000000, // Extend Sign Byte X-form (extsb RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{EXTSBCC, 0xfc0007ff00000000, 0x7c00077500000000, 0xf80000000000, // Extend Sign Byte X-form (extsb. RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{EXTSW, 0xfc0007ff00000000, 0x7c0007b400000000, 0xf80000000000, // Extend Sign Word X-form (extsw RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{EXTSWCC, 0xfc0007ff00000000, 0x7c0007b500000000, 0xf80000000000, // Extend Sign Word X-form (extsw. RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{FADDS, 0xfc00003f00000000, 0xec00002a00000000, 0x7c000000000, // Floating Add Single A-form (fadds FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FADDSCC, 0xfc00003f00000000, 0xec00002b00000000, 0x7c000000000, // Floating Add Single A-form (fadds. FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FCFID, 0xfc0007ff00000000, 0xfc00069c00000000, 0x1f000000000000, // Floating Convert with round Signed Doubleword to Double-Precision format X-form (fcfid FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCFIDCC, 0xfc0007ff00000000, 0xfc00069d00000000, 0x1f000000000000, // Floating Convert with round Signed Doubleword to Double-Precision format X-form (fcfid. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTID, 0xfc0007ff00000000, 0xfc00065c00000000, 0x1f000000000000, // Floating Convert with round Double-Precision To Signed Doubleword format X-form (fctid FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIDCC, 0xfc0007ff00000000, 0xfc00065d00000000, 0x1f000000000000, // Floating Convert with round Double-Precision To Signed Doubleword format X-form (fctid. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIDZ, 0xfc0007ff00000000, 0xfc00065e00000000, 0x1f000000000000, // Floating Convert with truncate Double-Precision To Signed Doubleword format X-form (fctidz FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIDZCC, 0xfc0007ff00000000, 0xfc00065f00000000, 0x1f000000000000, // Floating Convert with truncate Double-Precision To Signed Doubleword format X-form (fctidz. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FDIVS, 0xfc00003f00000000, 0xec00002400000000, 0x7c000000000, // Floating Divide Single A-form (fdivs FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FDIVSCC, 0xfc00003f00000000, 0xec00002500000000, 0x7c000000000, // Floating Divide Single A-form (fdivs. FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FMADDS, 0xfc00003f00000000, 0xec00003a00000000, 0x0, // Floating Multiply-Add Single A-form (fmadds FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FMADDSCC, 0xfc00003f00000000, 0xec00003b00000000, 0x0, // Floating Multiply-Add Single A-form (fmadds. FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FMSUBS, 0xfc00003f00000000, 0xec00003800000000, 0x0, // Floating Multiply-Subtract Single A-form (fmsubs FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FMSUBSCC, 0xfc00003f00000000, 0xec00003900000000, 0x0, // Floating Multiply-Subtract Single A-form (fmsubs. FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FMULS, 0xfc00003f00000000, 0xec00003200000000, 0xf80000000000, // Floating Multiply Single A-form (fmuls FRT,FRA,FRC)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25}},
+	{FMULSCC, 0xfc00003f00000000, 0xec00003300000000, 0xf80000000000, // Floating Multiply Single A-form (fmuls. FRT,FRA,FRC)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25}},
+	{FNMADDS, 0xfc00003f00000000, 0xec00003e00000000, 0x0, // Floating Negative Multiply-Add Single A-form (fnmadds FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FNMADDSCC, 0xfc00003f00000000, 0xec00003f00000000, 0x0, // Floating Negative Multiply-Add Single A-form (fnmadds. FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FNMSUBS, 0xfc00003f00000000, 0xec00003c00000000, 0x0, // Floating Negative Multiply-Subtract Single A-form (fnmsubs FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FNMSUBSCC, 0xfc00003f00000000, 0xec00003d00000000, 0x0, // Floating Negative Multiply-Subtract Single A-form (fnmsubs. FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FRES, 0xfc00003f00000000, 0xec00003000000000, 0x1f07c000000000, // Floating Reciprocal Estimate Single A-form (fres FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRESCC, 0xfc00003f00000000, 0xec00003100000000, 0x1f07c000000000, // Floating Reciprocal Estimate Single A-form (fres. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRSQRTE, 0xfc00003f00000000, 0xfc00003400000000, 0x1f07c000000000, // Floating Reciprocal Square Root Estimate A-form (frsqrte FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRSQRTECC, 0xfc00003f00000000, 0xfc00003500000000, 0x1f07c000000000, // Floating Reciprocal Square Root Estimate A-form (frsqrte. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FSEL, 0xfc00003f00000000, 0xfc00002e00000000, 0x0, // Floating Select A-form (fsel FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FSELCC, 0xfc00003f00000000, 0xfc00002f00000000, 0x0, // Floating Select A-form (fsel. FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FSQRTS, 0xfc00003f00000000, 0xec00002c00000000, 0x1f07c000000000, // Floating Square Root Single A-form (fsqrts FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FSQRTSCC, 0xfc00003f00000000, 0xec00002d00000000, 0x1f07c000000000, // Floating Square Root Single A-form (fsqrts. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FSUBS, 0xfc00003f00000000, 0xec00002800000000, 0x7c000000000, // Floating Subtract Single A-form (fsubs FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FSUBSCC, 0xfc00003f00000000, 0xec00002900000000, 0x7c000000000, // Floating Subtract Single A-form (fsubs. FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{ICBI, 0xfc0007fe00000000, 0x7c0007ac00000000, 0x3e0000100000000, // Instruction Cache Block Invalidate X-form (icbi RA,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_16_20}},
+	{LD, 0xfc00000300000000, 0xe800000000000000, 0x0, // Load Doubleword DS-form (ld RT,DS(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
+	{LDARX, 0xfc0007fe00000000, 0x7c0000a800000000, 0x0, // Load Doubleword And Reserve Indexed X-form (ldarx RT,RA,RB,EH)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}},
+	{LDU, 0xfc00000300000000, 0xe800000100000000, 0x0, // Load Doubleword with Update DS-form (ldu RT,DS(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
+	{LDUX, 0xfc0007fe00000000, 0x7c00006a00000000, 0x100000000, // Load Doubleword with Update Indexed X-form (ldux RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LDX, 0xfc0007fe00000000, 0x7c00002a00000000, 0x100000000, // Load Doubleword Indexed X-form (ldx RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LWA, 0xfc00000300000000, 0xe800000200000000, 0x0, // Load Word Algebraic DS-form (lwa RT,DS(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
+	{LWARX, 0xfc0007fe00000000, 0x7c00002800000000, 0x0, // Load Word & Reserve Indexed X-form (lwarx RT,RA,RB,EH)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20, ap_ImmUnsigned_31_31}},
+	{LWAUX, 0xfc0007fe00000000, 0x7c0002ea00000000, 0x100000000, // Load Word Algebraic with Update Indexed X-form (lwaux RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LWAX, 0xfc0007fe00000000, 0x7c0002aa00000000, 0x100000000, // Load Word Algebraic Indexed X-form (lwax RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MFTB, 0xfc0007fe00000000, 0x7c0002e600000000, 0x100000000, // Move From Time Base XFX-form (mftb RT,TBR)
+		[6]*argField{ap_Reg_6_10, ap_SpReg_16_20_11_15}},
+	{MTMSRD, 0xfc0007fe00000000, 0x7c00016400000000, 0x1ef80100000000, // Move To MSR Doubleword X-form (mtmsrd RS,L)
+		[6]*argField{ap_Reg_6_10, ap_ImmUnsigned_15_15}},
+	{MULHD, 0xfc0003ff00000000, 0x7c00009200000000, 0x40000000000, // Multiply High Doubleword XO-form (mulhd RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULHDCC, 0xfc0003ff00000000, 0x7c00009300000000, 0x40000000000, // Multiply High Doubleword XO-form (mulhd. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULHDU, 0xfc0003ff00000000, 0x7c00001200000000, 0x40000000000, // Multiply High Doubleword Unsigned XO-form (mulhdu RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULHDUCC, 0xfc0003ff00000000, 0x7c00001300000000, 0x40000000000, // Multiply High Doubleword Unsigned XO-form (mulhdu. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULHW, 0xfc0003ff00000000, 0x7c00009600000000, 0x40000000000, // Multiply High Word XO-form (mulhw RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULHWCC, 0xfc0003ff00000000, 0x7c00009700000000, 0x40000000000, // Multiply High Word XO-form (mulhw. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULHWU, 0xfc0003ff00000000, 0x7c00001600000000, 0x40000000000, // Multiply High Word Unsigned XO-form (mulhwu RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULHWUCC, 0xfc0003ff00000000, 0x7c00001700000000, 0x40000000000, // Multiply High Word Unsigned XO-form (mulhwu. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULLD, 0xfc0007ff00000000, 0x7c0001d200000000, 0x0, // Multiply Low Doubleword XO-form (mulld RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULLDCC, 0xfc0007ff00000000, 0x7c0001d300000000, 0x0, // Multiply Low Doubleword XO-form (mulld. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULLDO, 0xfc0007ff00000000, 0x7c0005d200000000, 0x0, // Multiply Low Doubleword XO-form (mulldo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULLDOCC, 0xfc0007ff00000000, 0x7c0005d300000000, 0x0, // Multiply Low Doubleword XO-form (mulldo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{RFID, 0xfc0007fe00000000, 0x4c00002400000000, 0x3fff80100000000, // Return from Interrupt Doubleword XL-form (rfid)
+		[6]*argField{}},
+	{RLDCL, 0xfc00001f00000000, 0x7800001000000000, 0x0, // Rotate Left Doubleword then Clear Left MDS-form (rldcl RA,RS,RB,MB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_26_26_21_25}},
+	{RLDCLCC, 0xfc00001f00000000, 0x7800001100000000, 0x0, // Rotate Left Doubleword then Clear Left MDS-form (rldcl. RA,RS,RB,MB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_26_26_21_25}},
+	{RLDCR, 0xfc00001f00000000, 0x7800001200000000, 0x0, // Rotate Left Doubleword then Clear Right MDS-form (rldcr RA,RS,RB,ME)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_26_26_21_25}},
+	{RLDCRCC, 0xfc00001f00000000, 0x7800001300000000, 0x0, // Rotate Left Doubleword then Clear Right MDS-form (rldcr. RA,RS,RB,ME)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_26_26_21_25}},
+	{RLDIC, 0xfc00001d00000000, 0x7800000800000000, 0x0, // Rotate Left Doubleword Immediate then Clear MD-form (rldic RA,RS,SH,MB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
+	{RLDICCC, 0xfc00001d00000000, 0x7800000900000000, 0x0, // Rotate Left Doubleword Immediate then Clear MD-form (rldic. RA,RS,SH,MB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
+	{RLDICL, 0xfc00001d00000000, 0x7800000000000000, 0x0, // Rotate Left Doubleword Immediate then Clear Left MD-form (rldicl RA,RS,SH,MB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
+	{RLDICLCC, 0xfc00001d00000000, 0x7800000100000000, 0x0, // Rotate Left Doubleword Immediate then Clear Left MD-form (rldicl. RA,RS,SH,MB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
+	{RLDICR, 0xfc00001d00000000, 0x7800000400000000, 0x0, // Rotate Left Doubleword Immediate then Clear Right MD-form (rldicr RA,RS,SH,ME)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
+	{RLDICRCC, 0xfc00001d00000000, 0x7800000500000000, 0x0, // Rotate Left Doubleword Immediate then Clear Right MD-form (rldicr. RA,RS,SH,ME)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
+	{RLDIMI, 0xfc00001d00000000, 0x7800000c00000000, 0x0, // Rotate Left Doubleword Immediate then Mask Insert MD-form (rldimi RA,RS,SH,MB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
+	{RLDIMICC, 0xfc00001d00000000, 0x7800000d00000000, 0x0, // Rotate Left Doubleword Immediate then Mask Insert MD-form (rldimi. RA,RS,SH,MB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20, ap_ImmUnsigned_26_26_21_25}},
+	{SC, 0xfc00000200000000, 0x4400000200000000, 0x3fff01d00000000, // System Call SC-form (sc LEV)
+		[6]*argField{ap_ImmUnsigned_20_26}},
+	{SLBIA, 0xfc0007fe00000000, 0x7c0003e400000000, 0x31ff80100000000, // SLB Invalidate All X-form (slbia IH)
+		[6]*argField{ap_ImmUnsigned_8_10}},
+	{SLBIE, 0xfc0007fe00000000, 0x7c00036400000000, 0x3ff000100000000, // SLB Invalidate Entry X-form (slbie RB)
+		[6]*argField{ap_Reg_16_20}},
+	{SLD, 0xfc0007ff00000000, 0x7c00003600000000, 0x0, // Shift Left Doubleword X-form (sld RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{SLDCC, 0xfc0007ff00000000, 0x7c00003700000000, 0x0, // Shift Left Doubleword X-form (sld. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{SRAD, 0xfc0007ff00000000, 0x7c00063400000000, 0x0, // Shift Right Algebraic Doubleword X-form (srad RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{SRADCC, 0xfc0007ff00000000, 0x7c00063500000000, 0x0, // Shift Right Algebraic Doubleword X-form (srad. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{SRADI, 0xfc0007fd00000000, 0x7c00067400000000, 0x0, // Shift Right Algebraic Doubleword Immediate XS-form (sradi RA,RS,SH)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20}},
+	{SRADICC, 0xfc0007fd00000000, 0x7c00067500000000, 0x0, // Shift Right Algebraic Doubleword Immediate XS-form (sradi. RA,RS,SH)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_30_30_16_20}},
+	{SRD, 0xfc0007ff00000000, 0x7c00043600000000, 0x0, // Shift Right Doubleword X-form (srd RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{SRDCC, 0xfc0007ff00000000, 0x7c00043700000000, 0x0, // Shift Right Doubleword X-form (srd. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{STD, 0xfc00000300000000, 0xf800000000000000, 0x0, // Store Doubleword DS-form (std RS,DS(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
+	{STDCXCC, 0xfc0007ff00000000, 0x7c0001ad00000000, 0x0, // Store Doubleword Conditional Indexed X-form (stdcx. RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STDU, 0xfc00000300000000, 0xf800000100000000, 0x0, // Store Doubleword with Update DS-form (stdu RS,DS(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_29_shift2, ap_Reg_11_15}},
+	{STDUX, 0xfc0007fe00000000, 0x7c00016a00000000, 0x100000000, // Store Doubleword with Update Indexed X-form (stdux RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STDX, 0xfc0007fe00000000, 0x7c00012a00000000, 0x100000000, // Store Doubleword Indexed X-form (stdx RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STFIWX, 0xfc0007fe00000000, 0x7c0007ae00000000, 0x100000000, // Store Floating-Point as Integer Word Indexed X-form (stfiwx FRS,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STWCXCC, 0xfc0007ff00000000, 0x7c00012d00000000, 0x0, // Store Word Conditional Indexed X-form (stwcx. RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBF, 0xfc0007ff00000000, 0x7c00005000000000, 0x0, // Subtract From XO-form (subf RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBFCC, 0xfc0007ff00000000, 0x7c00005100000000, 0x0, // Subtract From XO-form (subf. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBFO, 0xfc0007ff00000000, 0x7c00045000000000, 0x0, // Subtract From XO-form (subfo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBFOCC, 0xfc0007ff00000000, 0x7c00045100000000, 0x0, // Subtract From XO-form (subfo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{TD, 0xfc0007fe00000000, 0x7c00008800000000, 0x100000000, // Trap Doubleword X-form (td TO,RA,RB)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{TDI, 0xfc00000000000000, 0x800000000000000, 0x0, // Trap Doubleword Immediate D-form (tdi TO,RA,SI)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
+	{TLBSYNC, 0xfc0007fe00000000, 0x7c00046c00000000, 0x3fff80100000000, // TLB Synchronize X-form (tlbsync)
+		[6]*argField{}},
+	{FCTIW, 0xfc0007ff00000000, 0xfc00001c00000000, 0x1f000000000000, // Floating Convert with round Double-Precision To Signed Word format X-form (fctiw FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIWCC, 0xfc0007ff00000000, 0xfc00001d00000000, 0x1f000000000000, // Floating Convert with round Double-Precision To Signed Word format X-form (fctiw. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIWZ, 0xfc0007ff00000000, 0xfc00001e00000000, 0x1f000000000000, // Floating Convert with truncate Double-Precision To Signed Word fomat X-form (fctiwz FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FCTIWZCC, 0xfc0007ff00000000, 0xfc00001f00000000, 0x1f000000000000, // Floating Convert with truncate Double-Precision To Signed Word fomat X-form (fctiwz. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FSQRT, 0xfc00003f00000000, 0xfc00002c00000000, 0x1f07c000000000, // Floating Square Root A-form (fsqrt FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FSQRTCC, 0xfc00003f00000000, 0xfc00002d00000000, 0x1f07c000000000, // Floating Square Root A-form (fsqrt. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{ADD, 0xfc0007ff00000000, 0x7c00021400000000, 0x0, // Add XO-form (add RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{ADDCC, 0xfc0007ff00000000, 0x7c00021500000000, 0x0, // Add XO-form (add. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{ADDO, 0xfc0007ff00000000, 0x7c00061400000000, 0x0, // Add XO-form (addo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{ADDOCC, 0xfc0007ff00000000, 0x7c00061500000000, 0x0, // Add XO-form (addo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{ADDC, 0xfc0007ff00000000, 0x7c00001400000000, 0x0, // Add Carrying XO-form (addc RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{ADDCCC, 0xfc0007ff00000000, 0x7c00001500000000, 0x0, // Add Carrying XO-form (addc. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{ADDCO, 0xfc0007ff00000000, 0x7c00041400000000, 0x0, // Add Carrying XO-form (addco RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{ADDCOCC, 0xfc0007ff00000000, 0x7c00041500000000, 0x0, // Add Carrying XO-form (addco. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{ADDE, 0xfc0007ff00000000, 0x7c00011400000000, 0x0, // Add Extended XO-form (adde RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{ADDECC, 0xfc0007ff00000000, 0x7c00011500000000, 0x0, // Add Extended XO-form (adde. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{ADDEO, 0xfc0007ff00000000, 0x7c00051400000000, 0x0, // Add Extended XO-form (addeo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{ADDEOCC, 0xfc0007ff00000000, 0x7c00051500000000, 0x0, // Add Extended XO-form (addeo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LI, 0xfc1f000000000000, 0x3800000000000000, 0x0, // Add Immediate D-form (li RT,SI)
+		[6]*argField{ap_Reg_6_10, ap_ImmSigned_16_31}},
+	{ADDI, 0xfc00000000000000, 0x3800000000000000, 0x0, // Add Immediate D-form (addi RT,RA,SI)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
+	{ADDIC, 0xfc00000000000000, 0x3000000000000000, 0x0, // Add Immediate Carrying D-formy (addic RT,RA,SI)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
+	{ADDICCC, 0xfc00000000000000, 0x3400000000000000, 0x0, // Add Immediate Carrying and Record D-form (addic. RT,RA,SI)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
+	{LIS, 0xfc1f000000000000, 0x3c00000000000000, 0x0, // Add Immediate Shifted D-form (lis RT,SI)
+		[6]*argField{ap_Reg_6_10, ap_ImmSigned_16_31}},
+	{ADDIS, 0xfc00000000000000, 0x3c00000000000000, 0x0, // Add Immediate Shifted D-form (addis RT,RA,SI)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
+	{ADDME, 0xfc0007ff00000000, 0x7c0001d400000000, 0xf80000000000, // Add to Minus One Extended XO-form (addme RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{ADDMECC, 0xfc0007ff00000000, 0x7c0001d500000000, 0xf80000000000, // Add to Minus One Extended XO-form (addme. RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{ADDMEO, 0xfc0007ff00000000, 0x7c0005d400000000, 0xf80000000000, // Add to Minus One Extended XO-form (addmeo RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{ADDMEOCC, 0xfc0007ff00000000, 0x7c0005d500000000, 0xf80000000000, // Add to Minus One Extended XO-form (addmeo. RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{ADDZE, 0xfc0007ff00000000, 0x7c00019400000000, 0xf80000000000, // Add to Zero Extended XO-form (addze RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{ADDZECC, 0xfc0007ff00000000, 0x7c00019500000000, 0xf80000000000, // Add to Zero Extended XO-form (addze. RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{ADDZEO, 0xfc0007ff00000000, 0x7c00059400000000, 0xf80000000000, // Add to Zero Extended XO-form (addzeo RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{ADDZEOCC, 0xfc0007ff00000000, 0x7c00059500000000, 0xf80000000000, // Add to Zero Extended XO-form (addzeo. RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{AND, 0xfc0007ff00000000, 0x7c00003800000000, 0x0, // AND X-form (and RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{ANDCC, 0xfc0007ff00000000, 0x7c00003900000000, 0x0, // AND X-form (and. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{ANDC, 0xfc0007ff00000000, 0x7c00007800000000, 0x0, // AND with Complement X-form (andc RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{ANDCCC, 0xfc0007ff00000000, 0x7c00007900000000, 0x0, // AND with Complement X-form (andc. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{ANDICC, 0xfc00000000000000, 0x7000000000000000, 0x0, // AND Immediate D-form (andi. RA,RS,UI)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}},
+	{ANDISCC, 0xfc00000000000000, 0x7400000000000000, 0x0, // AND Immediate Shifted D-form (andis. RA,RS,UI)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}},
+	{B, 0xfc00000300000000, 0x4800000000000000, 0x0, // Branch I-form (b target_addr)
+		[6]*argField{ap_PCRel_6_29_shift2}},
+	{BA, 0xfc00000300000000, 0x4800000200000000, 0x0, // Branch I-form (ba target_addr)
+		[6]*argField{ap_Label_6_29_shift2}},
+	{BL, 0xfc00000300000000, 0x4800000100000000, 0x0, // Branch I-form (bl target_addr)
+		[6]*argField{ap_PCRel_6_29_shift2}},
+	{BLA, 0xfc00000300000000, 0x4800000300000000, 0x0, // Branch I-form (bla target_addr)
+		[6]*argField{ap_Label_6_29_shift2}},
+	{BC, 0xfc00000300000000, 0x4000000000000000, 0x0, // Branch Conditional B-form (bc BO,BI,target_addr)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_PCRel_16_29_shift2}},
+	{BCA, 0xfc00000300000000, 0x4000000200000000, 0x0, // Branch Conditional B-form (bca BO,BI,target_addr)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_Label_16_29_shift2}},
+	{BCL, 0xfc00000300000000, 0x4000000100000000, 0x0, // Branch Conditional B-form (bcl BO,BI,target_addr)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_PCRel_16_29_shift2}},
+	{BCLA, 0xfc00000300000000, 0x4000000300000000, 0x0, // Branch Conditional B-form (bcla BO,BI,target_addr)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_Label_16_29_shift2}},
+	{BCCTR, 0xfc0007ff00000000, 0x4c00042000000000, 0xe00000000000, // Branch Conditional to Count Register XL-form (bcctr BO,BI,BH)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}},
+	{BCCTRL, 0xfc0007ff00000000, 0x4c00042100000000, 0xe00000000000, // Branch Conditional to Count Register XL-form (bcctrl BO,BI,BH)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}},
+	{BCLR, 0xfc0007ff00000000, 0x4c00002000000000, 0xe00000000000, // Branch Conditional to Link Register XL-form (bclr BO,BI,BH)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}},
+	{BCLRL, 0xfc0007ff00000000, 0x4c00002100000000, 0xe00000000000, // Branch Conditional to Link Register XL-form (bclrl BO,BI,BH)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_CondRegBit_11_15, ap_ImmUnsigned_19_20}},
+	{CMPW, 0xfc2007fe00000000, 0x7c00000000000000, 0x40000100000000, // Compare X-form (cmpw BF,RA,RB)
+		[6]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
+	{CMPD, 0xfc2007fe00000000, 0x7c20000000000000, 0x40000100000000, // Compare X-form (cmpd BF,RA,RB)
+		[6]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
+	{CMP, 0xfc0007fe00000000, 0x7c00000000000000, 0x40000100000000, // Compare X-form (cmp BF,L,RA,RB)
+		[6]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_10_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{CMPWI, 0xfc20000000000000, 0x2c00000000000000, 0x40000000000000, // Compare Immediate D-form (cmpwi BF,RA,SI)
+		[6]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmSigned_16_31}},
+	{CMPDI, 0xfc20000000000000, 0x2c20000000000000, 0x40000000000000, // Compare Immediate D-form (cmpdi BF,RA,SI)
+		[6]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmSigned_16_31}},
+	{CMPI, 0xfc00000000000000, 0x2c00000000000000, 0x40000000000000, // Compare Immediate D-form (cmpi BF,L,RA,SI)
+		[6]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_10_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
+	{CMPLW, 0xfc2007fe00000000, 0x7c00004000000000, 0x40000100000000, // Compare Logical X-form (cmplw BF,RA,RB)
+		[6]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
+	{CMPLD, 0xfc2007fe00000000, 0x7c20004000000000, 0x40000100000000, // Compare Logical X-form (cmpld BF,RA,RB)
+		[6]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_Reg_16_20}},
+	{CMPL, 0xfc0007fe00000000, 0x7c00004000000000, 0x40000100000000, // Compare Logical X-form (cmpl BF,L,RA,RB)
+		[6]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_10_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{CMPLWI, 0xfc20000000000000, 0x2800000000000000, 0x40000000000000, // Compare Logical Immediate D-form (cmplwi BF,RA,UI)
+		[6]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmUnsigned_16_31}},
+	{CMPLDI, 0xfc20000000000000, 0x2820000000000000, 0x40000000000000, // Compare Logical Immediate D-form (cmpldi BF,RA,UI)
+		[6]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmUnsigned_16_31}},
+	{CMPLI, 0xfc00000000000000, 0x2800000000000000, 0x40000000000000, // Compare Logical Immediate D-form (cmpli BF,L,RA,UI)
+		[6]*argField{ap_CondRegField_6_8, ap_ImmUnsigned_10_10, ap_Reg_11_15, ap_ImmUnsigned_16_31}},
+	{CNTLZW, 0xfc0007ff00000000, 0x7c00003400000000, 0xf80000000000, // Count Leading Zeros Word X-form (cntlzw RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{CNTLZWCC, 0xfc0007ff00000000, 0x7c00003500000000, 0xf80000000000, // Count Leading Zeros Word X-form (cntlzw. RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{CRAND, 0xfc0007fe00000000, 0x4c00020200000000, 0x100000000, // Condition Register AND XL-form (crand BT,BA,BB)
+		[6]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
+	{CRANDC, 0xfc0007fe00000000, 0x4c00010200000000, 0x100000000, // Condition Register AND with Complement XL-form (crandc BT,BA,BB)
+		[6]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
+	{CREQV, 0xfc0007fe00000000, 0x4c00024200000000, 0x100000000, // Condition Register Equivalent XL-form (creqv BT,BA,BB)
+		[6]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
+	{CRNAND, 0xfc0007fe00000000, 0x4c0001c200000000, 0x100000000, // Condition Register NAND XL-form (crnand BT,BA,BB)
+		[6]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
+	{CRNOR, 0xfc0007fe00000000, 0x4c00004200000000, 0x100000000, // Condition Register NOR XL-form (crnor BT,BA,BB)
+		[6]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
+	{CROR, 0xfc0007fe00000000, 0x4c00038200000000, 0x100000000, // Condition Register OR XL-form (cror BT,BA,BB)
+		[6]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
+	{CRORC, 0xfc0007fe00000000, 0x4c00034200000000, 0x100000000, // Condition Register OR with Complement XL-form (crorc BT,BA,BB)
+		[6]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
+	{CRXOR, 0xfc0007fe00000000, 0x4c00018200000000, 0x100000000, // Condition Register XOR XL-form (crxor BT,BA,BB)
+		[6]*argField{ap_CondRegBit_6_10, ap_CondRegBit_11_15, ap_CondRegBit_16_20}},
+	{DCBZ, 0xfc0007fe00000000, 0x7c0007ec00000000, 0x3e0000100000000, // Data Cache Block set to Zero X-form (dcbz RA,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_16_20}},
+	{EQV, 0xfc0007ff00000000, 0x7c00023800000000, 0x0, // Equivalent X-form (eqv RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{EQVCC, 0xfc0007ff00000000, 0x7c00023900000000, 0x0, // Equivalent X-form (eqv. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{EXTSH, 0xfc0007ff00000000, 0x7c00073400000000, 0xf80000000000, // Extend Sign Halfword X-form (extsh RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{EXTSHCC, 0xfc0007ff00000000, 0x7c00073500000000, 0xf80000000000, // Extend Sign Halfword X-form (extsh. RA,RS)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
+	{FABS, 0xfc0007ff00000000, 0xfc00021000000000, 0x1f000000000000, // Floating Absolute Value X-form (fabs FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FABSCC, 0xfc0007ff00000000, 0xfc00021100000000, 0x1f000000000000, // Floating Absolute Value X-form (fabs. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FADD, 0xfc00003f00000000, 0xfc00002a00000000, 0x7c000000000, // Floating Add A-form (fadd FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FADDCC, 0xfc00003f00000000, 0xfc00002b00000000, 0x7c000000000, // Floating Add A-form (fadd. FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FCMPO, 0xfc0007fe00000000, 0xfc00004000000000, 0x60000100000000, // Floating Compare Ordered X-form (fcmpo BF,FRA,FRB)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FCMPU, 0xfc0007fe00000000, 0xfc00000000000000, 0x60000100000000, // Floating Compare Unordered X-form (fcmpu BF,FRA,FRB)
+		[6]*argField{ap_CondRegField_6_8, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FDIV, 0xfc00003f00000000, 0xfc00002400000000, 0x7c000000000, // Floating Divide A-form (fdiv FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FDIVCC, 0xfc00003f00000000, 0xfc00002500000000, 0x7c000000000, // Floating Divide A-form (fdiv. FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FMADD, 0xfc00003f00000000, 0xfc00003a00000000, 0x0, // Floating Multiply-Add A-form (fmadd FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FMADDCC, 0xfc00003f00000000, 0xfc00003b00000000, 0x0, // Floating Multiply-Add A-form (fmadd. FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FMR, 0xfc0007ff00000000, 0xfc00009000000000, 0x1f000000000000, // Floating Move Register X-form (fmr FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FMRCC, 0xfc0007ff00000000, 0xfc00009100000000, 0x1f000000000000, // Floating Move Register X-form (fmr. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FMSUB, 0xfc00003f00000000, 0xfc00003800000000, 0x0, // Floating Multiply-Subtract A-form (fmsub FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FMSUBCC, 0xfc00003f00000000, 0xfc00003900000000, 0x0, // Floating Multiply-Subtract A-form (fmsub. FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FMUL, 0xfc00003f00000000, 0xfc00003200000000, 0xf80000000000, // Floating Multiply A-form (fmul FRT,FRA,FRC)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25}},
+	{FMULCC, 0xfc00003f00000000, 0xfc00003300000000, 0xf80000000000, // Floating Multiply A-form (fmul. FRT,FRA,FRC)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25}},
+	{FNABS, 0xfc0007ff00000000, 0xfc00011000000000, 0x1f000000000000, // Floating Negative Absolute Value X-form (fnabs FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FNABSCC, 0xfc0007ff00000000, 0xfc00011100000000, 0x1f000000000000, // Floating Negative Absolute Value X-form (fnabs. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FNEG, 0xfc0007ff00000000, 0xfc00005000000000, 0x1f000000000000, // Floating Negate X-form (fneg FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FNEGCC, 0xfc0007ff00000000, 0xfc00005100000000, 0x1f000000000000, // Floating Negate X-form (fneg. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FNMADD, 0xfc00003f00000000, 0xfc00003e00000000, 0x0, // Floating Negative Multiply-Add A-form (fnmadd FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FNMADDCC, 0xfc00003f00000000, 0xfc00003f00000000, 0x0, // Floating Negative Multiply-Add A-form (fnmadd. FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FNMSUB, 0xfc00003f00000000, 0xfc00003c00000000, 0x0, // Floating Negative Multiply-Subtract A-form (fnmsub FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FNMSUBCC, 0xfc00003f00000000, 0xfc00003d00000000, 0x0, // Floating Negative Multiply-Subtract A-form (fnmsub. FRT,FRA,FRC,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_21_25, ap_FPReg_16_20}},
+	{FRSP, 0xfc0007ff00000000, 0xfc00001800000000, 0x1f000000000000, // Floating Round to Single-Precision X-form (frsp FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FRSPCC, 0xfc0007ff00000000, 0xfc00001900000000, 0x1f000000000000, // Floating Round to Single-Precision X-form (frsp. FRT,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_16_20}},
+	{FSUB, 0xfc00003f00000000, 0xfc00002800000000, 0x7c000000000, // Floating Subtract A-form (fsub FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{FSUBCC, 0xfc00003f00000000, 0xfc00002900000000, 0x7c000000000, // Floating Subtract A-form (fsub. FRT,FRA,FRB)
+		[6]*argField{ap_FPReg_6_10, ap_FPReg_11_15, ap_FPReg_16_20}},
+	{ISYNC, 0xfc0007fe00000000, 0x4c00012c00000000, 0x3fff80100000000, // Instruction Synchronize XL-form (isync)
+		[6]*argField{}},
+	{LBZ, 0xfc00000000000000, 0x8800000000000000, 0x0, // Load Byte and Zero D-form (lbz RT,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LBZU, 0xfc00000000000000, 0x8c00000000000000, 0x0, // Load Byte and Zero with Update D-form (lbzu RT,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LBZUX, 0xfc0007fe00000000, 0x7c0000ee00000000, 0x100000000, // Load Byte and Zero with Update Indexed X-form (lbzux RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LBZX, 0xfc0007fe00000000, 0x7c0000ae00000000, 0x100000000, // Load Byte and Zero Indexed X-form (lbzx RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LFD, 0xfc00000000000000, 0xc800000000000000, 0x0, // Load Floating-Point Double D-form (lfd FRT,D(RA))
+		[6]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LFDU, 0xfc00000000000000, 0xcc00000000000000, 0x0, // Load Floating-Point Double with Update D-form (lfdu FRT,D(RA))
+		[6]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LFDUX, 0xfc0007fe00000000, 0x7c0004ee00000000, 0x100000000, // Load Floating-Point Double with Update Indexed X-form (lfdux FRT,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LFDX, 0xfc0007fe00000000, 0x7c0004ae00000000, 0x100000000, // Load Floating-Point Double Indexed X-form (lfdx FRT,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LFS, 0xfc00000000000000, 0xc000000000000000, 0x0, // Load Floating-Point Single D-form (lfs FRT,D(RA))
+		[6]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LFSU, 0xfc00000000000000, 0xc400000000000000, 0x0, // Load Floating-Point Single with Update D-form (lfsu FRT,D(RA))
+		[6]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LFSUX, 0xfc0007fe00000000, 0x7c00046e00000000, 0x100000000, // Load Floating-Point Single with Update Indexed X-form (lfsux FRT,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LFSX, 0xfc0007fe00000000, 0x7c00042e00000000, 0x100000000, // Load Floating-Point Single Indexed X-form (lfsx FRT,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LHA, 0xfc00000000000000, 0xa800000000000000, 0x0, // Load Halfword Algebraic D-form (lha RT,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LHAU, 0xfc00000000000000, 0xac00000000000000, 0x0, // Load Halfword Algebraic with Update D-form (lhau RT,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LHAUX, 0xfc0007fe00000000, 0x7c0002ee00000000, 0x100000000, // Load Halfword Algebraic with Update Indexed X-form (lhaux RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LHAX, 0xfc0007fe00000000, 0x7c0002ae00000000, 0x100000000, // Load Halfword Algebraic Indexed X-form (lhax RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LHBRX, 0xfc0007fe00000000, 0x7c00062c00000000, 0x100000000, // Load Halfword Byte-Reverse Indexed X-form (lhbrx RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LHZ, 0xfc00000000000000, 0xa000000000000000, 0x0, // Load Halfword and Zero D-form (lhz RT,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LHZU, 0xfc00000000000000, 0xa400000000000000, 0x0, // Load Halfword and Zero with Update D-form (lhzu RT,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LHZUX, 0xfc0007fe00000000, 0x7c00026e00000000, 0x100000000, // Load Halfword and Zero with Update Indexed X-form (lhzux RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LHZX, 0xfc0007fe00000000, 0x7c00022e00000000, 0x100000000, // Load Halfword and Zero Indexed X-form (lhzx RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LMW, 0xfc00000000000000, 0xb800000000000000, 0x0, // Load Multiple Word D-form (lmw RT,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LSWI, 0xfc0007fe00000000, 0x7c0004aa00000000, 0x100000000, // Load String Word Immediate X-form (lswi RT,RA,NB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}},
+	{LSWX, 0xfc0007fe00000000, 0x7c00042a00000000, 0x100000000, // Load String Word Indexed X-form (lswx RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LWBRX, 0xfc0007fe00000000, 0x7c00042c00000000, 0x100000000, // Load Word Byte-Reverse Indexed X-form (lwbrx RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LWZ, 0xfc00000000000000, 0x8000000000000000, 0x0, // Load Word and Zero D-form (lwz RT,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LWZU, 0xfc00000000000000, 0x8400000000000000, 0x0, // Load Word and Zero with Update D-form (lwzu RT,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{LWZUX, 0xfc0007fe00000000, 0x7c00006e00000000, 0x100000000, // Load Word and Zero with Update Indexed X-form (lwzux RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LWZX, 0xfc0007fe00000000, 0x7c00002e00000000, 0x100000000, // Load Word and Zero Indexed X-form (lwzx RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MCRF, 0xfc0007fe00000000, 0x4c00000000000000, 0x63f80100000000, // Move Condition Register Field XL-form (mcrf BF,BFA)
+		[6]*argField{ap_CondRegField_6_8, ap_CondRegField_11_13}},
+	{MCRFS, 0xfc0007fe00000000, 0xfc00008000000000, 0x63f80100000000, // Move to Condition Register from FPSCR X-form (mcrfs BF,BFA)
+		[6]*argField{ap_CondRegField_6_8, ap_CondRegField_11_13}},
+	{MFCR, 0xfc1007fe00000000, 0x7c00002600000000, 0xff80100000000, // Move From Condition Register XFX-form (mfcr RT)
+		[6]*argField{ap_Reg_6_10}},
+	{MFFS, 0xfc1f07ff00000000, 0xfc00048e00000000, 0xf80000000000, // Move From FPSCR X-form (mffs FRT)
+		[6]*argField{ap_FPReg_6_10}},
+	{MFFSCC, 0xfc1f07ff00000000, 0xfc00048f00000000, 0xf80000000000, // Move From FPSCR X-form (mffs. FRT)
+		[6]*argField{ap_FPReg_6_10}},
+	{MFMSR, 0xfc0007fe00000000, 0x7c0000a600000000, 0x1ff80100000000, // Move From MSR X-form (mfmsr RT)
+		[6]*argField{ap_Reg_6_10}},
+	{MFSPR, 0xfc0007fe00000000, 0x7c0002a600000000, 0x100000000, // Move From Special Purpose Register XFX-form (mfspr RT,SPR)
+		[6]*argField{ap_Reg_6_10, ap_SpReg_16_20_11_15}},
+	{MTCRF, 0xfc1007fe00000000, 0x7c00012000000000, 0x80100000000, // Move To Condition Register Fields XFX-form (mtcrf FXM,RS)
+		[6]*argField{ap_ImmUnsigned_12_19, ap_Reg_6_10}},
+	{MTFSB0, 0xfc0007ff00000000, 0xfc00008c00000000, 0x1ff80000000000, // Move To FPSCR Bit 0 X-form (mtfsb0 BT)
+		[6]*argField{ap_ImmUnsigned_6_10}},
+	{MTFSB0CC, 0xfc0007ff00000000, 0xfc00008d00000000, 0x1ff80000000000, // Move To FPSCR Bit 0 X-form (mtfsb0. BT)
+		[6]*argField{ap_ImmUnsigned_6_10}},
+	{MTFSB1, 0xfc0007ff00000000, 0xfc00004c00000000, 0x1ff80000000000, // Move To FPSCR Bit 1 X-form (mtfsb1 BT)
+		[6]*argField{ap_ImmUnsigned_6_10}},
+	{MTFSB1CC, 0xfc0007ff00000000, 0xfc00004d00000000, 0x1ff80000000000, // Move To FPSCR Bit 1 X-form (mtfsb1. BT)
+		[6]*argField{ap_ImmUnsigned_6_10}},
+	{MTFSF, 0xfc0007ff00000000, 0xfc00058e00000000, 0x0, // Move To FPSCR Fields XFL-form (mtfsf FLM,FRB,L,W)
+		[6]*argField{ap_ImmUnsigned_7_14, ap_FPReg_16_20, ap_ImmUnsigned_6_6, ap_ImmUnsigned_15_15}},
+	{MTFSFCC, 0xfc0007ff00000000, 0xfc00058f00000000, 0x0, // Move To FPSCR Fields XFL-form (mtfsf. FLM,FRB,L,W)
+		[6]*argField{ap_ImmUnsigned_7_14, ap_FPReg_16_20, ap_ImmUnsigned_6_6, ap_ImmUnsigned_15_15}},
+	{MTFSFI, 0xfc0007ff00000000, 0xfc00010c00000000, 0x7e080000000000, // Move To FPSCR Field Immediate X-form (mtfsfi BF,U,W)
+		[6]*argField{ap_ImmUnsigned_6_8, ap_ImmUnsigned_16_19, ap_ImmUnsigned_15_15}},
+	{MTFSFICC, 0xfc0007ff00000000, 0xfc00010d00000000, 0x7e080000000000, // Move To FPSCR Field Immediate X-form (mtfsfi. BF,U,W)
+		[6]*argField{ap_ImmUnsigned_6_8, ap_ImmUnsigned_16_19, ap_ImmUnsigned_15_15}},
+	{MTMSR, 0xfc0007fe00000000, 0x7c00012400000000, 0x1ef80100000000, // Move To MSR X-form (mtmsr RS,L)
+		[6]*argField{ap_Reg_6_10, ap_ImmUnsigned_15_15}},
+	{MTSPR, 0xfc0007fe00000000, 0x7c0003a600000000, 0x100000000, // Move To Special Purpose Register XFX-form (mtspr SPR,RS)
+		[6]*argField{ap_SpReg_16_20_11_15, ap_Reg_6_10}},
+	{MULLI, 0xfc00000000000000, 0x1c00000000000000, 0x0, // Multiply Low Immediate D-form (mulli RT,RA,SI)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
+	{MULLW, 0xfc0007ff00000000, 0x7c0001d600000000, 0x0, // Multiply Low Word XO-form (mullw RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULLWCC, 0xfc0007ff00000000, 0x7c0001d700000000, 0x0, // Multiply Low Word XO-form (mullw. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULLWO, 0xfc0007ff00000000, 0x7c0005d600000000, 0x0, // Multiply Low Word XO-form (mullwo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MULLWOCC, 0xfc0007ff00000000, 0x7c0005d700000000, 0x0, // Multiply Low Word XO-form (mullwo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{NAND, 0xfc0007ff00000000, 0x7c0003b800000000, 0x0, // NAND X-form (nand RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{NANDCC, 0xfc0007ff00000000, 0x7c0003b900000000, 0x0, // NAND X-form (nand. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{NEG, 0xfc0007ff00000000, 0x7c0000d000000000, 0xf80000000000, // Negate XO-form (neg RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{NEGCC, 0xfc0007ff00000000, 0x7c0000d100000000, 0xf80000000000, // Negate XO-form (neg. RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{NEGO, 0xfc0007ff00000000, 0x7c0004d000000000, 0xf80000000000, // Negate XO-form (nego RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{NEGOCC, 0xfc0007ff00000000, 0x7c0004d100000000, 0xf80000000000, // Negate XO-form (nego. RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{NOR, 0xfc0007ff00000000, 0x7c0000f800000000, 0x0, // NOR X-form (nor RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{NORCC, 0xfc0007ff00000000, 0x7c0000f900000000, 0x0, // NOR X-form (nor. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{OR, 0xfc0007ff00000000, 0x7c00037800000000, 0x0, // OR X-form (or RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{ORCC, 0xfc0007ff00000000, 0x7c00037900000000, 0x0, // OR X-form (or. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{ORC, 0xfc0007ff00000000, 0x7c00033800000000, 0x0, // OR with Complement X-form (orc RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{ORCCC, 0xfc0007ff00000000, 0x7c00033900000000, 0x0, // OR with Complement X-form (orc. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{NOP, 0xffffffff00000000, 0x6000000000000000, 0x0, // OR Immediate D-form (nop)
+		[6]*argField{}},
+	{ORI, 0xfc00000000000000, 0x6000000000000000, 0x0, // OR Immediate D-form (ori RA,RS,UI)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}},
+	{ORIS, 0xfc00000000000000, 0x6400000000000000, 0x0, // OR Immediate Shifted D-form (oris RA,RS,UI)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}},
+	{RLWIMI, 0xfc00000100000000, 0x5000000000000000, 0x0, // Rotate Left Word Immediate then Mask Insert M-form (rlwimi RA,RS,SH,MB,ME)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}},
+	{RLWIMICC, 0xfc00000100000000, 0x5000000100000000, 0x0, // Rotate Left Word Immediate then Mask Insert M-form (rlwimi. RA,RS,SH,MB,ME)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}},
+	{RLWINM, 0xfc00000100000000, 0x5400000000000000, 0x0, // Rotate Left Word Immediate then AND with Mask M-form (rlwinm RA,RS,SH,MB,ME)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}},
+	{RLWINMCC, 0xfc00000100000000, 0x5400000100000000, 0x0, // Rotate Left Word Immediate then AND with Mask M-form (rlwinm. RA,RS,SH,MB,ME)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}},
+	{RLWNM, 0xfc00000100000000, 0x5c00000000000000, 0x0, // Rotate Left Word then AND with Mask M-form (rlwnm RA,RS,RB,MB,ME)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}},
+	{RLWNMCC, 0xfc00000100000000, 0x5c00000100000000, 0x0, // Rotate Left Word then AND with Mask M-form (rlwnm. RA,RS,RB,MB,ME)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20, ap_ImmUnsigned_21_25, ap_ImmUnsigned_26_30}},
+	{SLW, 0xfc0007ff00000000, 0x7c00003000000000, 0x0, // Shift Left Word X-form (slw RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{SLWCC, 0xfc0007ff00000000, 0x7c00003100000000, 0x0, // Shift Left Word X-form (slw. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{SRAW, 0xfc0007ff00000000, 0x7c00063000000000, 0x0, // Shift Right Algebraic Word X-form (sraw RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{SRAWCC, 0xfc0007ff00000000, 0x7c00063100000000, 0x0, // Shift Right Algebraic Word X-form (sraw. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{SRAWI, 0xfc0007ff00000000, 0x7c00067000000000, 0x0, // Shift Right Algebraic Word Immediate X-form (srawi RA,RS,SH)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20}},
+	{SRAWICC, 0xfc0007ff00000000, 0x7c00067100000000, 0x0, // Shift Right Algebraic Word Immediate X-form (srawi. RA,RS,SH)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_20}},
+	{SRW, 0xfc0007ff00000000, 0x7c00043000000000, 0x0, // Shift Right Word X-form (srw RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{SRWCC, 0xfc0007ff00000000, 0x7c00043100000000, 0x0, // Shift Right Word X-form (srw. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{STB, 0xfc00000000000000, 0x9800000000000000, 0x0, // Store Byte D-form (stb RS,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{STBU, 0xfc00000000000000, 0x9c00000000000000, 0x0, // Store Byte with Update D-form (stbu RS,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{STBUX, 0xfc0007fe00000000, 0x7c0001ee00000000, 0x100000000, // Store Byte with Update Indexed X-form (stbux RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STBX, 0xfc0007fe00000000, 0x7c0001ae00000000, 0x100000000, // Store Byte Indexed X-form (stbx RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STFD, 0xfc00000000000000, 0xd800000000000000, 0x0, // Store Floating-Point Double D-form (stfd FRS,D(RA))
+		[6]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{STFDU, 0xfc00000000000000, 0xdc00000000000000, 0x0, // Store Floating-Point Double with Update D-form (stfdu FRS,D(RA))
+		[6]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{STFDUX, 0xfc0007fe00000000, 0x7c0005ee00000000, 0x100000000, // Store Floating-Point Double with Update Indexed X-form (stfdux FRS,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STFDX, 0xfc0007fe00000000, 0x7c0005ae00000000, 0x100000000, // Store Floating-Point Double Indexed X-form (stfdx FRS,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STFS, 0xfc00000000000000, 0xd000000000000000, 0x0, // Store Floating-Point Single D-form (stfs FRS,D(RA))
+		[6]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{STFSU, 0xfc00000000000000, 0xd400000000000000, 0x0, // Store Floating-Point Single with Update D-form (stfsu FRS,D(RA))
+		[6]*argField{ap_FPReg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{STFSUX, 0xfc0007fe00000000, 0x7c00056e00000000, 0x100000000, // Store Floating-Point Single with Update Indexed X-form (stfsux FRS,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STFSX, 0xfc0007fe00000000, 0x7c00052e00000000, 0x100000000, // Store Floating-Point Single Indexed X-form (stfsx FRS,RA,RB)
+		[6]*argField{ap_FPReg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STH, 0xfc00000000000000, 0xb000000000000000, 0x0, // Store Halfword D-form (sth RS,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{STHBRX, 0xfc0007fe00000000, 0x7c00072c00000000, 0x100000000, // Store Halfword Byte-Reverse Indexed X-form (sthbrx RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STHU, 0xfc00000000000000, 0xb400000000000000, 0x0, // Store Halfword with Update D-form (sthu RS,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{STHUX, 0xfc0007fe00000000, 0x7c00036e00000000, 0x100000000, // Store Halfword with Update Indexed X-form (sthux RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STHX, 0xfc0007fe00000000, 0x7c00032e00000000, 0x100000000, // Store Halfword Indexed X-form (sthx RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STMW, 0xfc00000000000000, 0xbc00000000000000, 0x0, // Store Multiple Word D-form (stmw RS,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{STSWI, 0xfc0007fe00000000, 0x7c0005aa00000000, 0x100000000, // Store String Word Immediate X-form (stswi RS,RA,NB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmUnsigned_16_20}},
+	{STSWX, 0xfc0007fe00000000, 0x7c00052a00000000, 0x100000000, // Store String Word Indexed X-form (stswx RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STW, 0xfc00000000000000, 0x9000000000000000, 0x0, // Store Word D-form (stw RS,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{STWBRX, 0xfc0007fe00000000, 0x7c00052c00000000, 0x100000000, // Store Word Byte-Reverse Indexed X-form (stwbrx RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STWU, 0xfc00000000000000, 0x9400000000000000, 0x0, // Store Word with Update D-form (stwu RS,D(RA))
+		[6]*argField{ap_Reg_6_10, ap_Offset_16_31, ap_Reg_11_15}},
+	{STWUX, 0xfc0007fe00000000, 0x7c00016e00000000, 0x100000000, // Store Word with Update Indexed X-form (stwux RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STWX, 0xfc0007fe00000000, 0x7c00012e00000000, 0x100000000, // Store Word Indexed X-form (stwx RS,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBFC, 0xfc0007ff00000000, 0x7c00001000000000, 0x0, // Subtract From Carrying XO-form (subfc RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBFCCC, 0xfc0007ff00000000, 0x7c00001100000000, 0x0, // Subtract From Carrying XO-form (subfc. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBFCO, 0xfc0007ff00000000, 0x7c00041000000000, 0x0, // Subtract From Carrying XO-form (subfco RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBFCOCC, 0xfc0007ff00000000, 0x7c00041100000000, 0x0, // Subtract From Carrying XO-form (subfco. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBFE, 0xfc0007ff00000000, 0x7c00011000000000, 0x0, // Subtract From Extended XO-form (subfe RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBFECC, 0xfc0007ff00000000, 0x7c00011100000000, 0x0, // Subtract From Extended XO-form (subfe. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBFEO, 0xfc0007ff00000000, 0x7c00051000000000, 0x0, // Subtract From Extended XO-form (subfeo RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBFEOCC, 0xfc0007ff00000000, 0x7c00051100000000, 0x0, // Subtract From Extended XO-form (subfeo. RT,RA,RB)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{SUBFIC, 0xfc00000000000000, 0x2000000000000000, 0x0, // Subtract From Immediate Carrying D-form (subfic RT,RA,SI)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
+	{SUBFME, 0xfc0007ff00000000, 0x7c0001d000000000, 0xf80000000000, // Subtract From Minus One Extended XO-form (subfme RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{SUBFMECC, 0xfc0007ff00000000, 0x7c0001d100000000, 0xf80000000000, // Subtract From Minus One Extended XO-form (subfme. RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{SUBFMEO, 0xfc0007ff00000000, 0x7c0005d000000000, 0xf80000000000, // Subtract From Minus One Extended XO-form (subfmeo RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{SUBFMEOCC, 0xfc0007ff00000000, 0x7c0005d100000000, 0xf80000000000, // Subtract From Minus One Extended XO-form (subfmeo. RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{SUBFZE, 0xfc0007ff00000000, 0x7c00019000000000, 0xf80000000000, // Subtract From Zero Extended XO-form (subfze RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{SUBFZECC, 0xfc0007ff00000000, 0x7c00019100000000, 0xf80000000000, // Subtract From Zero Extended XO-form (subfze. RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{SUBFZEO, 0xfc0007ff00000000, 0x7c00059000000000, 0xf80000000000, // Subtract From Zero Extended XO-form (subfzeo RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{SUBFZEOCC, 0xfc0007ff00000000, 0x7c00059100000000, 0xf80000000000, // Subtract From Zero Extended XO-form (subfzeo. RT,RA)
+		[6]*argField{ap_Reg_6_10, ap_Reg_11_15}},
+	{SYNC, 0xfc0007fe00000000, 0x7c0004ac00000000, 0x31cf80100000000, // Synchronize X-form (sync L,SC)
+		[6]*argField{ap_ImmUnsigned_8_10, ap_ImmUnsigned_14_15}},
+	{TLBIE, 0xfc0007fe00000000, 0x7c00026400000000, 0x10000100000000, // TLB Invalidate Entry X-form (tlbie RB,RS,RIC,PRS,R)
+		[6]*argField{ap_Reg_16_20, ap_Reg_6_10, ap_ImmUnsigned_12_13, ap_ImmUnsigned_14_14, ap_ImmUnsigned_15_15}},
+	{TW, 0xfc0007fe00000000, 0x7c00000800000000, 0x100000000, // Trap Word X-form (tw TO,RA,RB)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{TWI, 0xfc00000000000000, 0xc00000000000000, 0x0, // Trap Word Immediate D-form (twi TO,RA,SI)
+		[6]*argField{ap_ImmUnsigned_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
+	{XOR, 0xfc0007ff00000000, 0x7c00027800000000, 0x0, // XOR X-form (xor RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{XORCC, 0xfc0007ff00000000, 0x7c00027900000000, 0x0, // XOR X-form (xor. RA,RS,RB)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_Reg_16_20}},
+	{XORI, 0xfc00000000000000, 0x6800000000000000, 0x0, // XOR Immediate D-form (xori RA,RS,UI)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}},
+	{XORIS, 0xfc00000000000000, 0x6c00000000000000, 0x0, // XOR Immediate Shifted D-form (xoris RA,RS,UI)
+		[6]*argField{ap_Reg_11_15, ap_Reg_6_10, ap_ImmUnsigned_16_31}},
 }
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/tables.go b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/tables.go
index 5635399..af3fb73 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/tables.go
+++ b/src/cmd/vendor/golang.org/x/arch/x86/x86asm/tables.go
@@ -22,233 +22,233 @@
 	0x0D, 685,
 	0x0E, 714,
 	0x0F, 721,
-	0x10, 8026,
-	0x11, 8032,
-	0x12, 8061,
-	0x13, 8067,
-	0x14, 8096,
-	0x15, 8102,
-	0x16, 8131,
-	0x17, 8138,
-	0x18, 8145,
-	0x19, 8151,
-	0x1A, 8180,
-	0x1B, 8186,
-	0x1C, 8215,
-	0x1D, 8221,
-	0x1E, 8250,
-	0x1F, 8257,
-	0x20, 8264,
-	0x21, 8270,
-	0x22, 8299,
-	0x23, 8305,
-	0x24, 8334,
-	0x25, 8340,
-	0x27, 8369,
-	0x28, 8375,
-	0x29, 8381,
-	0x2A, 8410,
-	0x2B, 8452,
-	0x2C, 8481,
-	0x2D, 8487,
-	0x2F, 8516,
-	0x30, 8522,
-	0x31, 8528,
-	0x32, 8557,
-	0x33, 8563,
-	0x34, 8592,
-	0x35, 8598,
-	0x37, 8627,
-	0x38, 8633,
-	0x39, 8639,
-	0x3A, 8668,
-	0x3B, 8674,
-	0x3C, 8703,
-	0x3D, 8709,
-	0x3F, 8738,
-	0x40, 8744,
-	0x41, 8744,
-	0x42, 8744,
-	0x43, 8744,
-	0x44, 8744,
-	0x45, 8744,
-	0x46, 8744,
-	0x47, 8744,
-	0x48, 8759,
-	0x49, 8759,
-	0x4a, 8759,
-	0x4b, 8759,
-	0x4c, 8759,
-	0x4d, 8759,
-	0x4e, 8759,
-	0x4f, 8759,
-	0x50, 8774,
-	0x51, 8774,
-	0x52, 8774,
-	0x53, 8774,
-	0x54, 8774,
-	0x55, 8774,
-	0x56, 8774,
-	0x57, 8774,
-	0x58, 8801,
-	0x59, 8801,
-	0x5a, 8801,
-	0x5b, 8801,
-	0x5c, 8801,
-	0x5d, 8801,
-	0x5e, 8801,
-	0x5f, 8801,
-	0x60, 8828,
-	0x61, 8841,
-	0x62, 8854,
-	0x63, 8873,
-	0x68, 8904,
-	0x69, 8923,
-	0x6A, 8958,
-	0x6B, 8963,
-	0x6C, 8998,
-	0x6D, 9001,
-	0x6E, 9014,
-	0x6F, 9017,
-	0x70, 9090,
-	0x71, 9095,
-	0x72, 9100,
-	0x73, 9105,
-	0x74, 9110,
-	0x75, 9115,
-	0x76, 9120,
-	0x77, 9125,
-	0x78, 9152,
-	0x79, 9157,
-	0x7A, 9162,
-	0x7B, 9167,
-	0x7C, 9172,
-	0x7D, 9177,
-	0x7E, 9182,
-	0x7F, 9187,
-	0x80, 9252,
-	0x81, 9309,
-	0x83, 9550,
-	0x84, 9791,
-	0x85, 9797,
-	0x86, 9826,
-	0x87, 9832,
-	0x88, 9861,
-	0x89, 9867,
-	0x8A, 9889,
-	0x8B, 9895,
-	0x8C, 9917,
-	0x8D, 9946,
-	0x8E, 9975,
-	0x8F, 10004,
-	0x90, 10040,
-	0x91, 10040,
-	0x92, 10040,
-	0x93, 10040,
-	0x94, 10040,
-	0x95, 10040,
-	0x96, 10040,
-	0x97, 10040,
-	0x98, 10066,
-	0x99, 10086,
-	0x9A, 10106,
-	0x9B, 10123,
-	0x9C, 10126,
-	0x9D, 10149,
-	0x9E, 10172,
-	0x9F, 10175,
-	0xA0, 10178,
-	0xA1, 10197,
-	0xA2, 10219,
-	0xA3, 10238,
-	0xA4, 10260,
-	0xA5, 10263,
-	0xA6, 10283,
-	0xA7, 10286,
-	0xA8, 10306,
-	0xA9, 10312,
-	0xAA, 10341,
-	0xAB, 10344,
-	0xAC, 10364,
-	0xAD, 10367,
-	0xAE, 10387,
-	0xAF, 10390,
-	0xb0, 10410,
-	0xb1, 10410,
-	0xb2, 10410,
-	0xb3, 10410,
-	0xb4, 10410,
-	0xb5, 10410,
-	0xb6, 10410,
-	0xb7, 10410,
-	0xb8, 10416,
-	0xb9, 10416,
-	0xba, 10416,
-	0xbb, 10416,
-	0xbc, 10416,
-	0xbd, 10416,
-	0xbe, 10416,
-	0xbf, 10416,
-	0xC0, 10445,
-	0xC1, 10496,
-	0xC2, 10694,
-	0xC3, 10699,
-	0xC4, 10702,
-	0xC5, 10721,
-	0xC6, 10740,
-	0xC7, 10764,
-	0xC8, 10825,
-	0xC9, 10832,
-	0xCA, 10855,
-	0xCB, 10860,
-	0xCC, 10863,
-	0xCD, 10867,
-	0xCE, 10872,
-	0xCF, 10878,
-	0xD0, 10898,
-	0xD1, 10942,
-	0xD2, 11133,
-	0xD3, 11177,
-	0xD4, 11368,
-	0xD5, 11376,
-	0xD7, 11384,
-	0xD8, 11397,
-	0xD9, 11606,
-	0xDA, 11825,
-	0xDB, 11957,
-	0xDC, 12128,
-	0xDD, 12297,
-	0xDE, 12436,
-	0xDF, 12610,
-	0xE0, 12721,
-	0xE1, 12726,
-	0xE2, 12731,
-	0xE3, 12736,
-	0xE4, 12762,
-	0xE5, 12768,
-	0xE6, 12790,
-	0xE7, 12796,
-	0xE8, 12854,
-	0xE9, 12885,
-	0xEA, 12916,
-	0xEB, 12933,
-	0xEC, 12938,
-	0xED, 12943,
-	0xEE, 12962,
-	0xEF, 12967,
-	0xF1, 12986,
-	0xF4, 12989,
-	0xF5, 12992,
-	0xF6, 12995,
-	0xF7, 13034,
-	0xF8, 13210,
-	0xF9, 13213,
-	0xFA, 13216,
-	0xFB, 13219,
-	0xFC, 13222,
-	0xFD, 13225,
-	0xFE, 13228,
-	0xFF, 13245,
+	0x10, 8045,
+	0x11, 8051,
+	0x12, 8080,
+	0x13, 8086,
+	0x14, 8115,
+	0x15, 8121,
+	0x16, 8150,
+	0x17, 8157,
+	0x18, 8164,
+	0x19, 8170,
+	0x1A, 8199,
+	0x1B, 8205,
+	0x1C, 8234,
+	0x1D, 8240,
+	0x1E, 8269,
+	0x1F, 8276,
+	0x20, 8283,
+	0x21, 8289,
+	0x22, 8318,
+	0x23, 8324,
+	0x24, 8353,
+	0x25, 8359,
+	0x27, 8388,
+	0x28, 8394,
+	0x29, 8400,
+	0x2A, 8429,
+	0x2B, 8471,
+	0x2C, 8500,
+	0x2D, 8506,
+	0x2F, 8535,
+	0x30, 8541,
+	0x31, 8547,
+	0x32, 8576,
+	0x33, 8582,
+	0x34, 8611,
+	0x35, 8617,
+	0x37, 8646,
+	0x38, 8652,
+	0x39, 8658,
+	0x3A, 8687,
+	0x3B, 8693,
+	0x3C, 8722,
+	0x3D, 8728,
+	0x3F, 8757,
+	0x40, 8763,
+	0x41, 8763,
+	0x42, 8763,
+	0x43, 8763,
+	0x44, 8763,
+	0x45, 8763,
+	0x46, 8763,
+	0x47, 8763,
+	0x48, 8778,
+	0x49, 8778,
+	0x4a, 8778,
+	0x4b, 8778,
+	0x4c, 8778,
+	0x4d, 8778,
+	0x4e, 8778,
+	0x4f, 8778,
+	0x50, 8793,
+	0x51, 8793,
+	0x52, 8793,
+	0x53, 8793,
+	0x54, 8793,
+	0x55, 8793,
+	0x56, 8793,
+	0x57, 8793,
+	0x58, 8820,
+	0x59, 8820,
+	0x5a, 8820,
+	0x5b, 8820,
+	0x5c, 8820,
+	0x5d, 8820,
+	0x5e, 8820,
+	0x5f, 8820,
+	0x60, 8847,
+	0x61, 8860,
+	0x62, 8873,
+	0x63, 8892,
+	0x68, 8923,
+	0x69, 8942,
+	0x6A, 8977,
+	0x6B, 8982,
+	0x6C, 9017,
+	0x6D, 9020,
+	0x6E, 9033,
+	0x6F, 9036,
+	0x70, 9109,
+	0x71, 9114,
+	0x72, 9119,
+	0x73, 9124,
+	0x74, 9129,
+	0x75, 9134,
+	0x76, 9139,
+	0x77, 9144,
+	0x78, 9171,
+	0x79, 9176,
+	0x7A, 9181,
+	0x7B, 9186,
+	0x7C, 9191,
+	0x7D, 9196,
+	0x7E, 9201,
+	0x7F, 9206,
+	0x80, 9271,
+	0x81, 9328,
+	0x83, 9569,
+	0x84, 9810,
+	0x85, 9816,
+	0x86, 9845,
+	0x87, 9851,
+	0x88, 9880,
+	0x89, 9886,
+	0x8A, 9908,
+	0x8B, 9914,
+	0x8C, 9936,
+	0x8D, 9965,
+	0x8E, 9994,
+	0x8F, 10023,
+	0x90, 10059,
+	0x91, 10059,
+	0x92, 10059,
+	0x93, 10059,
+	0x94, 10059,
+	0x95, 10059,
+	0x96, 10059,
+	0x97, 10059,
+	0x98, 10085,
+	0x99, 10105,
+	0x9A, 10125,
+	0x9B, 10142,
+	0x9C, 10145,
+	0x9D, 10168,
+	0x9E, 10191,
+	0x9F, 10194,
+	0xA0, 10197,
+	0xA1, 10216,
+	0xA2, 10238,
+	0xA3, 10257,
+	0xA4, 10279,
+	0xA5, 10282,
+	0xA6, 10302,
+	0xA7, 10305,
+	0xA8, 10325,
+	0xA9, 10331,
+	0xAA, 10360,
+	0xAB, 10363,
+	0xAC, 10383,
+	0xAD, 10386,
+	0xAE, 10406,
+	0xAF, 10409,
+	0xb0, 10429,
+	0xb1, 10429,
+	0xb2, 10429,
+	0xb3, 10429,
+	0xb4, 10429,
+	0xb5, 10429,
+	0xb6, 10429,
+	0xb7, 10429,
+	0xb8, 10435,
+	0xb9, 10435,
+	0xba, 10435,
+	0xbb, 10435,
+	0xbc, 10435,
+	0xbd, 10435,
+	0xbe, 10435,
+	0xbf, 10435,
+	0xC0, 10464,
+	0xC1, 10515,
+	0xC2, 10713,
+	0xC3, 10718,
+	0xC4, 10721,
+	0xC5, 10740,
+	0xC6, 10759,
+	0xC7, 10783,
+	0xC8, 10844,
+	0xC9, 10851,
+	0xCA, 10874,
+	0xCB, 10879,
+	0xCC, 10882,
+	0xCD, 10886,
+	0xCE, 10891,
+	0xCF, 10897,
+	0xD0, 10917,
+	0xD1, 10961,
+	0xD2, 11152,
+	0xD3, 11196,
+	0xD4, 11387,
+	0xD5, 11395,
+	0xD7, 11403,
+	0xD8, 11416,
+	0xD9, 11625,
+	0xDA, 11844,
+	0xDB, 11976,
+	0xDC, 12147,
+	0xDD, 12316,
+	0xDE, 12455,
+	0xDF, 12629,
+	0xE0, 12740,
+	0xE1, 12745,
+	0xE2, 12750,
+	0xE3, 12755,
+	0xE4, 12781,
+	0xE5, 12787,
+	0xE6, 12809,
+	0xE7, 12815,
+	0xE8, 12873,
+	0xE9, 12904,
+	0xEA, 12935,
+	0xEB, 12952,
+	0xEC, 12957,
+	0xED, 12962,
+	0xEE, 12981,
+	0xEF, 12986,
+	0xF1, 13005,
+	0xF4, 13008,
+	0xF5, 13011,
+	0xF6, 13014,
+	0xF7, 13053,
+	0xF8, 13229,
+	0xF9, 13232,
+	0xFA, 13235,
+	0xFB, 13238,
+	0xFC, 13241,
+	0xFD, 13244,
+	0xFE, 13247,
+	0xFF, 13264,
 	uint16(xFail),
 	/*490*/ uint16(xSetOp), uint16(ADD),
 	/*492*/ uint16(xReadSlashR),
@@ -400,587 +400,588 @@
 	/*717*/ uint16(xSetOp), uint16(PUSH),
 	/*719*/ uint16(xArgCS),
 	/*720*/ uint16(xMatch),
-	/*721*/ uint16(xCondByte), 228,
-	0x00, 1180,
-	0x01, 1237,
-	0x02, 1345,
-	0x03, 1367,
-	0x05, 1389,
-	0x06, 1395,
-	0x07, 1398,
-	0x08, 1404,
-	0x09, 1407,
-	0x0B, 1410,
-	0x0D, 1413,
-	0x10, 1426,
-	0x11, 1460,
-	0x12, 1494,
-	0x13, 1537,
-	0x14, 1555,
-	0x15, 1573,
-	0x16, 1591,
-	0x17, 1626,
-	0x18, 1644,
-	0x1F, 1669,
-	0x20, 1690,
-	0x21, 1705,
-	0x22, 1720,
-	0x23, 1735,
-	0x24, 1750,
-	0x26, 1765,
-	0x28, 1780,
-	0x29, 1798,
-	0x2A, 1816,
-	0x2B, 1903,
-	0x2C, 1937,
-	0x2D, 2024,
-	0x2E, 2111,
-	0x2F, 2129,
-	0x30, 2147,
-	0x31, 2150,
-	0x32, 2153,
-	0x33, 2156,
-	0x34, 2159,
-	0x35, 2162,
-	0x38, 2172,
-	0x3A, 3073,
-	0x40, 3484,
-	0x41, 3513,
-	0x42, 3542,
-	0x43, 3571,
-	0x44, 3600,
-	0x45, 3629,
-	0x46, 3658,
-	0x47, 3687,
-	0x48, 3716,
-	0x49, 3745,
-	0x4A, 3774,
-	0x4B, 3803,
-	0x4C, 3832,
-	0x4D, 3861,
-	0x4E, 3890,
-	0x4F, 3919,
-	0x50, 3948,
-	0x51, 3966,
-	0x52, 4000,
-	0x53, 4018,
-	0x54, 4036,
-	0x55, 4054,
-	0x56, 4072,
-	0x57, 4090,
-	0x58, 4108,
-	0x59, 4142,
-	0x5A, 4176,
-	0x5B, 4210,
-	0x5C, 4236,
-	0x5D, 4270,
-	0x5E, 4304,
-	0x5F, 4338,
-	0x60, 4372,
-	0x61, 4390,
-	0x62, 4408,
-	0x63, 4426,
-	0x64, 4444,
-	0x65, 4462,
-	0x66, 4480,
-	0x67, 4498,
-	0x68, 4516,
-	0x69, 4534,
-	0x6A, 4552,
-	0x6B, 4570,
-	0x6C, 4588,
-	0x6D, 4598,
-	0x6E, 4608,
-	0x6F, 4675,
-	0x70, 4701,
-	0x71, 4743,
-	0x72, 4806,
-	0x73, 4869,
-	0x74, 4934,
-	0x75, 4952,
-	0x76, 4970,
-	0x77, 4988,
-	0x7C, 4991,
-	0x7D, 5009,
-	0x7E, 5027,
-	0x7F, 5104,
-	0x80, 5130,
-	0x81, 5161,
-	0x82, 5192,
-	0x83, 5223,
-	0x84, 5254,
-	0x85, 5285,
-	0x86, 5316,
-	0x87, 5347,
-	0x88, 5378,
-	0x89, 5409,
-	0x8A, 5440,
-	0x8B, 5471,
-	0x8C, 5502,
-	0x8D, 5533,
-	0x8E, 5564,
-	0x8F, 5595,
-	0x90, 5626,
-	0x91, 5631,
-	0x92, 5636,
-	0x93, 5641,
-	0x94, 5646,
-	0x95, 5651,
-	0x96, 5656,
-	0x97, 5661,
-	0x98, 5666,
-	0x99, 5671,
-	0x9A, 5676,
-	0x9B, 5681,
-	0x9C, 5686,
-	0x9D, 5691,
-	0x9E, 5696,
-	0x9F, 5701,
-	0xA0, 5706,
-	0xA1, 5710,
-	0xA2, 5737,
-	0xA3, 5740,
-	0xA4, 5769,
-	0xA5, 5804,
-	0xA8, 5836,
-	0xA9, 5840,
-	0xAA, 5867,
-	0xAB, 5870,
-	0xAC, 5899,
-	0xAD, 5934,
-	0xAE, 5966,
-	0xAF, 6224,
-	0xB0, 6253,
-	0xB1, 6259,
-	0xB2, 6288,
-	0xB3, 6317,
-	0xB4, 6346,
-	0xB5, 6375,
-	0xB6, 6404,
-	0xB7, 6433,
-	0xB8, 6462,
-	0xB9, 6499,
-	0xBA, 6502,
-	0xBB, 6627,
-	0xBC, 6656,
-	0xBD, 6723,
-	0xBE, 6790,
-	0xBF, 6819,
-	0xC0, 6848,
-	0xC1, 6854,
-	0xC2, 6883,
-	0xC3, 6925,
-	0xC4, 6954,
-	0xC5, 6976,
-	0xC6, 6998,
-	0xC7, 7020,
-	0xc8, 7149,
-	0xc9, 7149,
-	0xca, 7149,
-	0xcb, 7149,
-	0xcc, 7149,
-	0xcd, 7149,
-	0xce, 7149,
-	0xcf, 7149,
-	0xD0, 7172,
-	0xD1, 7190,
-	0xD2, 7208,
-	0xD3, 7226,
-	0xD4, 7244,
-	0xD5, 7262,
-	0xD6, 7280,
-	0xD7, 7306,
-	0xD8, 7324,
-	0xD9, 7342,
-	0xDA, 7360,
-	0xDB, 7378,
-	0xDC, 7396,
-	0xDD, 7414,
-	0xDE, 7432,
-	0xDF, 7450,
-	0xE0, 7468,
-	0xE1, 7486,
-	0xE2, 7504,
-	0xE3, 7522,
-	0xE4, 7540,
-	0xE5, 7558,
-	0xE6, 7576,
-	0xE7, 7602,
-	0xE8, 7620,
-	0xE9, 7638,
-	0xEA, 7656,
-	0xEB, 7674,
-	0xEC, 7692,
-	0xED, 7710,
-	0xEE, 7728,
-	0xEF, 7746,
-	0xF0, 7764,
-	0xF1, 7774,
-	0xF2, 7792,
-	0xF3, 7810,
-	0xF4, 7828,
-	0xF5, 7846,
-	0xF6, 7864,
-	0xF7, 7882,
-	0xF8, 7900,
-	0xF9, 7918,
-	0xFA, 7936,
-	0xFB, 7954,
-	0xFC, 7972,
-	0xFD, 7990,
-	0xFE, 8008,
+	/*721*/ uint16(xCondByte), 229,
+	0x00, 1182,
+	0x01, 1239,
+	0x02, 1347,
+	0x03, 1369,
+	0x05, 1391,
+	0x06, 1397,
+	0x07, 1400,
+	0x08, 1406,
+	0x09, 1409,
+	0x0B, 1412,
+	0x0D, 1415,
+	0x10, 1428,
+	0x11, 1462,
+	0x12, 1496,
+	0x13, 1539,
+	0x14, 1557,
+	0x15, 1575,
+	0x16, 1593,
+	0x17, 1628,
+	0x18, 1646,
+	0x1F, 1671,
+	0x20, 1692,
+	0x21, 1707,
+	0x22, 1722,
+	0x23, 1737,
+	0x24, 1752,
+	0x26, 1767,
+	0x28, 1782,
+	0x29, 1800,
+	0x2A, 1818,
+	0x2B, 1905,
+	0x2C, 1939,
+	0x2D, 2026,
+	0x2E, 2113,
+	0x2F, 2131,
+	0x30, 2149,
+	0x31, 2152,
+	0x32, 2155,
+	0x33, 2158,
+	0x34, 2161,
+	0x35, 2164,
+	0x38, 2174,
+	0x3A, 3075,
+	0x40, 3486,
+	0x41, 3515,
+	0x42, 3544,
+	0x43, 3573,
+	0x44, 3602,
+	0x45, 3631,
+	0x46, 3660,
+	0x47, 3689,
+	0x48, 3718,
+	0x49, 3747,
+	0x4A, 3776,
+	0x4B, 3805,
+	0x4C, 3834,
+	0x4D, 3863,
+	0x4E, 3892,
+	0x4F, 3921,
+	0x50, 3950,
+	0x51, 3968,
+	0x52, 4002,
+	0x53, 4020,
+	0x54, 4038,
+	0x55, 4056,
+	0x56, 4074,
+	0x57, 4092,
+	0x58, 4110,
+	0x59, 4144,
+	0x5A, 4178,
+	0x5B, 4212,
+	0x5C, 4238,
+	0x5D, 4272,
+	0x5E, 4306,
+	0x5F, 4340,
+	0x60, 4374,
+	0x61, 4392,
+	0x62, 4410,
+	0x63, 4428,
+	0x64, 4446,
+	0x65, 4464,
+	0x66, 4482,
+	0x67, 4500,
+	0x68, 4518,
+	0x69, 4536,
+	0x6A, 4554,
+	0x6B, 4572,
+	0x6C, 4590,
+	0x6D, 4600,
+	0x6E, 4610,
+	0x6F, 4677,
+	0x70, 4703,
+	0x71, 4745,
+	0x72, 4808,
+	0x73, 4871,
+	0x74, 4936,
+	0x75, 4954,
+	0x76, 4972,
+	0x77, 4990,
+	0x7C, 4993,
+	0x7D, 5011,
+	0x7E, 5029,
+	0x7F, 5106,
+	0x80, 5132,
+	0x81, 5163,
+	0x82, 5194,
+	0x83, 5225,
+	0x84, 5256,
+	0x85, 5287,
+	0x86, 5318,
+	0x87, 5349,
+	0x88, 5380,
+	0x89, 5411,
+	0x8A, 5442,
+	0x8B, 5473,
+	0x8C, 5504,
+	0x8D, 5535,
+	0x8E, 5566,
+	0x8F, 5597,
+	0x90, 5628,
+	0x91, 5633,
+	0x92, 5638,
+	0x93, 5643,
+	0x94, 5648,
+	0x95, 5653,
+	0x96, 5658,
+	0x97, 5663,
+	0x98, 5668,
+	0x99, 5673,
+	0x9A, 5678,
+	0x9B, 5683,
+	0x9C, 5688,
+	0x9D, 5693,
+	0x9E, 5698,
+	0x9F, 5703,
+	0xA0, 5708,
+	0xA1, 5712,
+	0xA2, 5739,
+	0xA3, 5742,
+	0xA4, 5771,
+	0xA5, 5806,
+	0xA8, 5838,
+	0xA9, 5842,
+	0xAA, 5869,
+	0xAB, 5872,
+	0xAC, 5901,
+	0xAD, 5936,
+	0xAE, 5968,
+	0xAF, 6226,
+	0xB0, 6255,
+	0xB1, 6261,
+	0xB2, 6290,
+	0xB3, 6319,
+	0xB4, 6348,
+	0xB5, 6377,
+	0xB6, 6406,
+	0xB7, 6435,
+	0xB8, 6464,
+	0xB9, 6501,
+	0xBA, 6511,
+	0xBB, 6636,
+	0xBC, 6665,
+	0xBD, 6732,
+	0xBE, 6799,
+	0xBF, 6828,
+	0xC0, 6857,
+	0xC1, 6863,
+	0xC2, 6892,
+	0xC3, 6934,
+	0xC4, 6963,
+	0xC5, 6985,
+	0xC6, 7007,
+	0xC7, 7029,
+	0xc8, 7158,
+	0xc9, 7158,
+	0xca, 7158,
+	0xcb, 7158,
+	0xcc, 7158,
+	0xcd, 7158,
+	0xce, 7158,
+	0xcf, 7158,
+	0xD0, 7181,
+	0xD1, 7199,
+	0xD2, 7217,
+	0xD3, 7235,
+	0xD4, 7253,
+	0xD5, 7271,
+	0xD6, 7289,
+	0xD7, 7315,
+	0xD8, 7333,
+	0xD9, 7351,
+	0xDA, 7369,
+	0xDB, 7387,
+	0xDC, 7405,
+	0xDD, 7423,
+	0xDE, 7441,
+	0xDF, 7459,
+	0xE0, 7477,
+	0xE1, 7495,
+	0xE2, 7513,
+	0xE3, 7531,
+	0xE4, 7549,
+	0xE5, 7567,
+	0xE6, 7585,
+	0xE7, 7611,
+	0xE8, 7629,
+	0xE9, 7647,
+	0xEA, 7665,
+	0xEB, 7683,
+	0xEC, 7701,
+	0xED, 7719,
+	0xEE, 7737,
+	0xEF, 7755,
+	0xF0, 7773,
+	0xF1, 7783,
+	0xF2, 7801,
+	0xF3, 7819,
+	0xF4, 7837,
+	0xF5, 7855,
+	0xF6, 7873,
+	0xF7, 7891,
+	0xF8, 7909,
+	0xF9, 7927,
+	0xFA, 7945,
+	0xFB, 7963,
+	0xFC, 7981,
+	0xFD, 7999,
+	0xFE, 8017,
+	0xFF, 8035,
 	uint16(xFail),
-	/*1180*/ uint16(xCondSlashR),
-	1189, // 0
-	1205, // 1
-	1221, // 2
-	1225, // 3
-	1229, // 4
-	1233, // 5
+	/*1182*/ uint16(xCondSlashR),
+	1191, // 0
+	1207, // 1
+	1223, // 2
+	1227, // 3
+	1231, // 4
+	1235, // 5
 	0,    // 6
 	0,    // 7
-	/*1189*/ uint16(xCondDataSize), 1193, 1197, 1201,
-	/*1193*/ uint16(xSetOp), uint16(SLDT),
-	/*1195*/ uint16(xArgRM16),
-	/*1196*/ uint16(xMatch),
-	/*1197*/ uint16(xSetOp), uint16(SLDT),
-	/*1199*/ uint16(xArgR32M16),
-	/*1200*/ uint16(xMatch),
-	/*1201*/ uint16(xSetOp), uint16(SLDT),
-	/*1203*/ uint16(xArgR64M16),
-	/*1204*/ uint16(xMatch),
-	/*1205*/ uint16(xCondDataSize), 1209, 1213, 1217,
-	/*1209*/ uint16(xSetOp), uint16(STR),
-	/*1211*/ uint16(xArgRM16),
-	/*1212*/ uint16(xMatch),
-	/*1213*/ uint16(xSetOp), uint16(STR),
-	/*1215*/ uint16(xArgR32M16),
-	/*1216*/ uint16(xMatch),
-	/*1217*/ uint16(xSetOp), uint16(STR),
-	/*1219*/ uint16(xArgR64M16),
-	/*1220*/ uint16(xMatch),
-	/*1221*/ uint16(xSetOp), uint16(LLDT),
-	/*1223*/ uint16(xArgRM16),
-	/*1224*/ uint16(xMatch),
-	/*1225*/ uint16(xSetOp), uint16(LTR),
-	/*1227*/ uint16(xArgRM16),
-	/*1228*/ uint16(xMatch),
-	/*1229*/ uint16(xSetOp), uint16(VERR),
-	/*1231*/ uint16(xArgRM16),
-	/*1232*/ uint16(xMatch),
-	/*1233*/ uint16(xSetOp), uint16(VERW),
-	/*1235*/ uint16(xArgRM16),
-	/*1236*/ uint16(xMatch),
-	/*1237*/ uint16(xCondByte), 8,
-	0xC8, 1318,
-	0xC9, 1321,
-	0xD0, 1324,
-	0xD1, 1327,
-	0xD5, 1330,
-	0xD6, 1333,
-	0xF8, 1336,
-	0xF9, 1342,
-	/*1255*/ uint16(xCondSlashR),
-	1264, // 0
-	1268, // 1
-	1272, // 2
-	1283, // 3
-	1294, // 4
+	/*1191*/ uint16(xCondDataSize), 1195, 1199, 1203,
+	/*1195*/ uint16(xSetOp), uint16(SLDT),
+	/*1197*/ uint16(xArgRM16),
+	/*1198*/ uint16(xMatch),
+	/*1199*/ uint16(xSetOp), uint16(SLDT),
+	/*1201*/ uint16(xArgR32M16),
+	/*1202*/ uint16(xMatch),
+	/*1203*/ uint16(xSetOp), uint16(SLDT),
+	/*1205*/ uint16(xArgR64M16),
+	/*1206*/ uint16(xMatch),
+	/*1207*/ uint16(xCondDataSize), 1211, 1215, 1219,
+	/*1211*/ uint16(xSetOp), uint16(STR),
+	/*1213*/ uint16(xArgRM16),
+	/*1214*/ uint16(xMatch),
+	/*1215*/ uint16(xSetOp), uint16(STR),
+	/*1217*/ uint16(xArgR32M16),
+	/*1218*/ uint16(xMatch),
+	/*1219*/ uint16(xSetOp), uint16(STR),
+	/*1221*/ uint16(xArgR64M16),
+	/*1222*/ uint16(xMatch),
+	/*1223*/ uint16(xSetOp), uint16(LLDT),
+	/*1225*/ uint16(xArgRM16),
+	/*1226*/ uint16(xMatch),
+	/*1227*/ uint16(xSetOp), uint16(LTR),
+	/*1229*/ uint16(xArgRM16),
+	/*1230*/ uint16(xMatch),
+	/*1231*/ uint16(xSetOp), uint16(VERR),
+	/*1233*/ uint16(xArgRM16),
+	/*1234*/ uint16(xMatch),
+	/*1235*/ uint16(xSetOp), uint16(VERW),
+	/*1237*/ uint16(xArgRM16),
+	/*1238*/ uint16(xMatch),
+	/*1239*/ uint16(xCondByte), 8,
+	0xC8, 1320,
+	0xC9, 1323,
+	0xD0, 1326,
+	0xD1, 1329,
+	0xD5, 1332,
+	0xD6, 1335,
+	0xF8, 1338,
+	0xF9, 1344,
+	/*1257*/ uint16(xCondSlashR),
+	1266, // 0
+	1270, // 1
+	1274, // 2
+	1285, // 3
+	1296, // 4
 	0,    // 5
-	1310, // 6
-	1314, // 7
-	/*1264*/ uint16(xSetOp), uint16(SGDT),
-	/*1266*/ uint16(xArgM),
-	/*1267*/ uint16(xMatch),
-	/*1268*/ uint16(xSetOp), uint16(SIDT),
-	/*1270*/ uint16(xArgM),
-	/*1271*/ uint16(xMatch),
-	/*1272*/ uint16(xCondIs64), 1275, 1279,
-	/*1275*/ uint16(xSetOp), uint16(LGDT),
-	/*1277*/ uint16(xArgM16and32),
-	/*1278*/ uint16(xMatch),
-	/*1279*/ uint16(xSetOp), uint16(LGDT),
-	/*1281*/ uint16(xArgM16and64),
-	/*1282*/ uint16(xMatch),
-	/*1283*/ uint16(xCondIs64), 1286, 1290,
-	/*1286*/ uint16(xSetOp), uint16(LIDT),
-	/*1288*/ uint16(xArgM16and32),
-	/*1289*/ uint16(xMatch),
-	/*1290*/ uint16(xSetOp), uint16(LIDT),
-	/*1292*/ uint16(xArgM16and64),
-	/*1293*/ uint16(xMatch),
-	/*1294*/ uint16(xCondDataSize), 1298, 1302, 1306,
-	/*1298*/ uint16(xSetOp), uint16(SMSW),
-	/*1300*/ uint16(xArgRM16),
-	/*1301*/ uint16(xMatch),
-	/*1302*/ uint16(xSetOp), uint16(SMSW),
-	/*1304*/ uint16(xArgR32M16),
-	/*1305*/ uint16(xMatch),
-	/*1306*/ uint16(xSetOp), uint16(SMSW),
-	/*1308*/ uint16(xArgR64M16),
-	/*1309*/ uint16(xMatch),
-	/*1310*/ uint16(xSetOp), uint16(LMSW),
-	/*1312*/ uint16(xArgRM16),
-	/*1313*/ uint16(xMatch),
-	/*1314*/ uint16(xSetOp), uint16(INVLPG),
-	/*1316*/ uint16(xArgM),
-	/*1317*/ uint16(xMatch),
-	/*1318*/ uint16(xSetOp), uint16(MONITOR),
-	/*1320*/ uint16(xMatch),
-	/*1321*/ uint16(xSetOp), uint16(MWAIT),
-	/*1323*/ uint16(xMatch),
-	/*1324*/ uint16(xSetOp), uint16(XGETBV),
-	/*1326*/ uint16(xMatch),
-	/*1327*/ uint16(xSetOp), uint16(XSETBV),
-	/*1329*/ uint16(xMatch),
-	/*1330*/ uint16(xSetOp), uint16(XEND),
-	/*1332*/ uint16(xMatch),
-	/*1333*/ uint16(xSetOp), uint16(XTEST),
-	/*1335*/ uint16(xMatch),
-	/*1336*/ uint16(xCondIs64), 0, 1339,
-	/*1339*/ uint16(xSetOp), uint16(SWAPGS),
-	/*1341*/ uint16(xMatch),
-	/*1342*/ uint16(xSetOp), uint16(RDTSCP),
-	/*1344*/ uint16(xMatch),
-	/*1345*/ uint16(xCondDataSize), 1349, 1355, 1361,
-	/*1349*/ uint16(xSetOp), uint16(LAR),
-	/*1351*/ uint16(xReadSlashR),
-	/*1352*/ uint16(xArgR16),
-	/*1353*/ uint16(xArgRM16),
-	/*1354*/ uint16(xMatch),
-	/*1355*/ uint16(xSetOp), uint16(LAR),
-	/*1357*/ uint16(xReadSlashR),
-	/*1358*/ uint16(xArgR32),
-	/*1359*/ uint16(xArgR32M16),
-	/*1360*/ uint16(xMatch),
-	/*1361*/ uint16(xSetOp), uint16(LAR),
-	/*1363*/ uint16(xReadSlashR),
-	/*1364*/ uint16(xArgR64),
-	/*1365*/ uint16(xArgR64M16),
-	/*1366*/ uint16(xMatch),
-	/*1367*/ uint16(xCondDataSize), 1371, 1377, 1383,
-	/*1371*/ uint16(xSetOp), uint16(LSL),
-	/*1373*/ uint16(xReadSlashR),
-	/*1374*/ uint16(xArgR16),
-	/*1375*/ uint16(xArgRM16),
-	/*1376*/ uint16(xMatch),
-	/*1377*/ uint16(xSetOp), uint16(LSL),
-	/*1379*/ uint16(xReadSlashR),
-	/*1380*/ uint16(xArgR32),
-	/*1381*/ uint16(xArgR32M16),
-	/*1382*/ uint16(xMatch),
-	/*1383*/ uint16(xSetOp), uint16(LSL),
-	/*1385*/ uint16(xReadSlashR),
-	/*1386*/ uint16(xArgR64),
-	/*1387*/ uint16(xArgR32M16),
-	/*1388*/ uint16(xMatch),
-	/*1389*/ uint16(xCondIs64), 0, 1392,
-	/*1392*/ uint16(xSetOp), uint16(SYSCALL),
-	/*1394*/ uint16(xMatch),
-	/*1395*/ uint16(xSetOp), uint16(CLTS),
-	/*1397*/ uint16(xMatch),
-	/*1398*/ uint16(xCondIs64), 0, 1401,
-	/*1401*/ uint16(xSetOp), uint16(SYSRET),
-	/*1403*/ uint16(xMatch),
-	/*1404*/ uint16(xSetOp), uint16(INVD),
-	/*1406*/ uint16(xMatch),
-	/*1407*/ uint16(xSetOp), uint16(WBINVD),
-	/*1409*/ uint16(xMatch),
-	/*1410*/ uint16(xSetOp), uint16(UD2),
-	/*1412*/ uint16(xMatch),
-	/*1413*/ uint16(xCondSlashR),
+	1312, // 6
+	1316, // 7
+	/*1266*/ uint16(xSetOp), uint16(SGDT),
+	/*1268*/ uint16(xArgM),
+	/*1269*/ uint16(xMatch),
+	/*1270*/ uint16(xSetOp), uint16(SIDT),
+	/*1272*/ uint16(xArgM),
+	/*1273*/ uint16(xMatch),
+	/*1274*/ uint16(xCondIs64), 1277, 1281,
+	/*1277*/ uint16(xSetOp), uint16(LGDT),
+	/*1279*/ uint16(xArgM16and32),
+	/*1280*/ uint16(xMatch),
+	/*1281*/ uint16(xSetOp), uint16(LGDT),
+	/*1283*/ uint16(xArgM16and64),
+	/*1284*/ uint16(xMatch),
+	/*1285*/ uint16(xCondIs64), 1288, 1292,
+	/*1288*/ uint16(xSetOp), uint16(LIDT),
+	/*1290*/ uint16(xArgM16and32),
+	/*1291*/ uint16(xMatch),
+	/*1292*/ uint16(xSetOp), uint16(LIDT),
+	/*1294*/ uint16(xArgM16and64),
+	/*1295*/ uint16(xMatch),
+	/*1296*/ uint16(xCondDataSize), 1300, 1304, 1308,
+	/*1300*/ uint16(xSetOp), uint16(SMSW),
+	/*1302*/ uint16(xArgRM16),
+	/*1303*/ uint16(xMatch),
+	/*1304*/ uint16(xSetOp), uint16(SMSW),
+	/*1306*/ uint16(xArgR32M16),
+	/*1307*/ uint16(xMatch),
+	/*1308*/ uint16(xSetOp), uint16(SMSW),
+	/*1310*/ uint16(xArgR64M16),
+	/*1311*/ uint16(xMatch),
+	/*1312*/ uint16(xSetOp), uint16(LMSW),
+	/*1314*/ uint16(xArgRM16),
+	/*1315*/ uint16(xMatch),
+	/*1316*/ uint16(xSetOp), uint16(INVLPG),
+	/*1318*/ uint16(xArgM),
+	/*1319*/ uint16(xMatch),
+	/*1320*/ uint16(xSetOp), uint16(MONITOR),
+	/*1322*/ uint16(xMatch),
+	/*1323*/ uint16(xSetOp), uint16(MWAIT),
+	/*1325*/ uint16(xMatch),
+	/*1326*/ uint16(xSetOp), uint16(XGETBV),
+	/*1328*/ uint16(xMatch),
+	/*1329*/ uint16(xSetOp), uint16(XSETBV),
+	/*1331*/ uint16(xMatch),
+	/*1332*/ uint16(xSetOp), uint16(XEND),
+	/*1334*/ uint16(xMatch),
+	/*1335*/ uint16(xSetOp), uint16(XTEST),
+	/*1337*/ uint16(xMatch),
+	/*1338*/ uint16(xCondIs64), 0, 1341,
+	/*1341*/ uint16(xSetOp), uint16(SWAPGS),
+	/*1343*/ uint16(xMatch),
+	/*1344*/ uint16(xSetOp), uint16(RDTSCP),
+	/*1346*/ uint16(xMatch),
+	/*1347*/ uint16(xCondDataSize), 1351, 1357, 1363,
+	/*1351*/ uint16(xSetOp), uint16(LAR),
+	/*1353*/ uint16(xReadSlashR),
+	/*1354*/ uint16(xArgR16),
+	/*1355*/ uint16(xArgRM16),
+	/*1356*/ uint16(xMatch),
+	/*1357*/ uint16(xSetOp), uint16(LAR),
+	/*1359*/ uint16(xReadSlashR),
+	/*1360*/ uint16(xArgR32),
+	/*1361*/ uint16(xArgR32M16),
+	/*1362*/ uint16(xMatch),
+	/*1363*/ uint16(xSetOp), uint16(LAR),
+	/*1365*/ uint16(xReadSlashR),
+	/*1366*/ uint16(xArgR64),
+	/*1367*/ uint16(xArgR64M16),
+	/*1368*/ uint16(xMatch),
+	/*1369*/ uint16(xCondDataSize), 1373, 1379, 1385,
+	/*1373*/ uint16(xSetOp), uint16(LSL),
+	/*1375*/ uint16(xReadSlashR),
+	/*1376*/ uint16(xArgR16),
+	/*1377*/ uint16(xArgRM16),
+	/*1378*/ uint16(xMatch),
+	/*1379*/ uint16(xSetOp), uint16(LSL),
+	/*1381*/ uint16(xReadSlashR),
+	/*1382*/ uint16(xArgR32),
+	/*1383*/ uint16(xArgR32M16),
+	/*1384*/ uint16(xMatch),
+	/*1385*/ uint16(xSetOp), uint16(LSL),
+	/*1387*/ uint16(xReadSlashR),
+	/*1388*/ uint16(xArgR64),
+	/*1389*/ uint16(xArgR32M16),
+	/*1390*/ uint16(xMatch),
+	/*1391*/ uint16(xCondIs64), 0, 1394,
+	/*1394*/ uint16(xSetOp), uint16(SYSCALL),
+	/*1396*/ uint16(xMatch),
+	/*1397*/ uint16(xSetOp), uint16(CLTS),
+	/*1399*/ uint16(xMatch),
+	/*1400*/ uint16(xCondIs64), 0, 1403,
+	/*1403*/ uint16(xSetOp), uint16(SYSRET),
+	/*1405*/ uint16(xMatch),
+	/*1406*/ uint16(xSetOp), uint16(INVD),
+	/*1408*/ uint16(xMatch),
+	/*1409*/ uint16(xSetOp), uint16(WBINVD),
+	/*1411*/ uint16(xMatch),
+	/*1412*/ uint16(xSetOp), uint16(UD2),
+	/*1414*/ uint16(xMatch),
+	/*1415*/ uint16(xCondSlashR),
 	0,    // 0
-	1422, // 1
+	1424, // 1
 	0,    // 2
 	0,    // 3
 	0,    // 4
 	0,    // 5
 	0,    // 6
 	0,    // 7
-	/*1422*/ uint16(xSetOp), uint16(PREFETCHW),
-	/*1424*/ uint16(xArgM8),
-	/*1425*/ uint16(xMatch),
-	/*1426*/ uint16(xCondPrefix), 4,
-	0xF3, 1454,
-	0xF2, 1448,
-	0x66, 1442,
-	0x0, 1436,
-	/*1436*/ uint16(xSetOp), uint16(MOVUPS),
-	/*1438*/ uint16(xReadSlashR),
-	/*1439*/ uint16(xArgXmm1),
-	/*1440*/ uint16(xArgXmm2M128),
-	/*1441*/ uint16(xMatch),
-	/*1442*/ uint16(xSetOp), uint16(MOVUPD),
-	/*1444*/ uint16(xReadSlashR),
-	/*1445*/ uint16(xArgXmm1),
-	/*1446*/ uint16(xArgXmm2M128),
-	/*1447*/ uint16(xMatch),
-	/*1448*/ uint16(xSetOp), uint16(MOVSD_XMM),
-	/*1450*/ uint16(xReadSlashR),
-	/*1451*/ uint16(xArgXmm1),
-	/*1452*/ uint16(xArgXmm2M64),
-	/*1453*/ uint16(xMatch),
-	/*1454*/ uint16(xSetOp), uint16(MOVSS),
-	/*1456*/ uint16(xReadSlashR),
-	/*1457*/ uint16(xArgXmm1),
-	/*1458*/ uint16(xArgXmm2M32),
-	/*1459*/ uint16(xMatch),
-	/*1460*/ uint16(xCondPrefix), 4,
-	0xF3, 1488,
-	0xF2, 1482,
-	0x66, 1476,
-	0x0, 1470,
-	/*1470*/ uint16(xSetOp), uint16(MOVUPS),
-	/*1472*/ uint16(xReadSlashR),
-	/*1473*/ uint16(xArgXmm2M128),
-	/*1474*/ uint16(xArgXmm1),
-	/*1475*/ uint16(xMatch),
-	/*1476*/ uint16(xSetOp), uint16(MOVUPD),
-	/*1478*/ uint16(xReadSlashR),
-	/*1479*/ uint16(xArgXmm2M128),
-	/*1480*/ uint16(xArgXmm),
-	/*1481*/ uint16(xMatch),
-	/*1482*/ uint16(xSetOp), uint16(MOVSD_XMM),
-	/*1484*/ uint16(xReadSlashR),
-	/*1485*/ uint16(xArgXmm2M64),
-	/*1486*/ uint16(xArgXmm1),
-	/*1487*/ uint16(xMatch),
-	/*1488*/ uint16(xSetOp), uint16(MOVSS),
-	/*1490*/ uint16(xReadSlashR),
-	/*1491*/ uint16(xArgXmm2M32),
-	/*1492*/ uint16(xArgXmm),
-	/*1493*/ uint16(xMatch),
-	/*1494*/ uint16(xCondPrefix), 4,
-	0xF3, 1531,
-	0xF2, 1525,
-	0x66, 1519,
-	0x0, 1504,
-	/*1504*/ uint16(xCondIsMem), 1507, 1513,
-	/*1507*/ uint16(xSetOp), uint16(MOVHLPS),
-	/*1509*/ uint16(xReadSlashR),
-	/*1510*/ uint16(xArgXmm1),
-	/*1511*/ uint16(xArgXmm2),
-	/*1512*/ uint16(xMatch),
-	/*1513*/ uint16(xSetOp), uint16(MOVLPS),
-	/*1515*/ uint16(xReadSlashR),
-	/*1516*/ uint16(xArgXmm),
-	/*1517*/ uint16(xArgM64),
-	/*1518*/ uint16(xMatch),
-	/*1519*/ uint16(xSetOp), uint16(MOVLPD),
-	/*1521*/ uint16(xReadSlashR),
-	/*1522*/ uint16(xArgXmm),
-	/*1523*/ uint16(xArgXmm2M64),
-	/*1524*/ uint16(xMatch),
-	/*1525*/ uint16(xSetOp), uint16(MOVDDUP),
-	/*1527*/ uint16(xReadSlashR),
-	/*1528*/ uint16(xArgXmm1),
-	/*1529*/ uint16(xArgXmm2M64),
-	/*1530*/ uint16(xMatch),
-	/*1531*/ uint16(xSetOp), uint16(MOVSLDUP),
-	/*1533*/ uint16(xReadSlashR),
-	/*1534*/ uint16(xArgXmm1),
-	/*1535*/ uint16(xArgXmm2M128),
-	/*1536*/ uint16(xMatch),
-	/*1537*/ uint16(xCondPrefix), 2,
-	0x66, 1549,
-	0x0, 1543,
-	/*1543*/ uint16(xSetOp), uint16(MOVLPS),
-	/*1545*/ uint16(xReadSlashR),
-	/*1546*/ uint16(xArgM64),
-	/*1547*/ uint16(xArgXmm),
-	/*1548*/ uint16(xMatch),
-	/*1549*/ uint16(xSetOp), uint16(MOVLPD),
-	/*1551*/ uint16(xReadSlashR),
-	/*1552*/ uint16(xArgXmm2M64),
-	/*1553*/ uint16(xArgXmm),
-	/*1554*/ uint16(xMatch),
-	/*1555*/ uint16(xCondPrefix), 2,
-	0x66, 1567,
-	0x0, 1561,
-	/*1561*/ uint16(xSetOp), uint16(UNPCKLPS),
-	/*1563*/ uint16(xReadSlashR),
-	/*1564*/ uint16(xArgXmm1),
-	/*1565*/ uint16(xArgXmm2M128),
-	/*1566*/ uint16(xMatch),
-	/*1567*/ uint16(xSetOp), uint16(UNPCKLPD),
-	/*1569*/ uint16(xReadSlashR),
-	/*1570*/ uint16(xArgXmm1),
-	/*1571*/ uint16(xArgXmm2M128),
-	/*1572*/ uint16(xMatch),
-	/*1573*/ uint16(xCondPrefix), 2,
-	0x66, 1585,
-	0x0, 1579,
-	/*1579*/ uint16(xSetOp), uint16(UNPCKHPS),
-	/*1581*/ uint16(xReadSlashR),
-	/*1582*/ uint16(xArgXmm1),
-	/*1583*/ uint16(xArgXmm2M128),
-	/*1584*/ uint16(xMatch),
-	/*1585*/ uint16(xSetOp), uint16(UNPCKHPD),
-	/*1587*/ uint16(xReadSlashR),
-	/*1588*/ uint16(xArgXmm1),
-	/*1589*/ uint16(xArgXmm2M128),
-	/*1590*/ uint16(xMatch),
-	/*1591*/ uint16(xCondPrefix), 3,
-	0xF3, 1620,
-	0x66, 1614,
-	0x0, 1599,
-	/*1599*/ uint16(xCondIsMem), 1602, 1608,
-	/*1602*/ uint16(xSetOp), uint16(MOVLHPS),
-	/*1604*/ uint16(xReadSlashR),
-	/*1605*/ uint16(xArgXmm1),
-	/*1606*/ uint16(xArgXmm2),
-	/*1607*/ uint16(xMatch),
-	/*1608*/ uint16(xSetOp), uint16(MOVHPS),
-	/*1610*/ uint16(xReadSlashR),
-	/*1611*/ uint16(xArgXmm),
-	/*1612*/ uint16(xArgM64),
-	/*1613*/ uint16(xMatch),
-	/*1614*/ uint16(xSetOp), uint16(MOVHPD),
-	/*1616*/ uint16(xReadSlashR),
-	/*1617*/ uint16(xArgXmm),
-	/*1618*/ uint16(xArgXmm2M64),
-	/*1619*/ uint16(xMatch),
-	/*1620*/ uint16(xSetOp), uint16(MOVSHDUP),
-	/*1622*/ uint16(xReadSlashR),
-	/*1623*/ uint16(xArgXmm1),
-	/*1624*/ uint16(xArgXmm2M128),
-	/*1625*/ uint16(xMatch),
-	/*1626*/ uint16(xCondPrefix), 2,
-	0x66, 1638,
-	0x0, 1632,
-	/*1632*/ uint16(xSetOp), uint16(MOVHPS),
-	/*1634*/ uint16(xReadSlashR),
-	/*1635*/ uint16(xArgM64),
-	/*1636*/ uint16(xArgXmm),
-	/*1637*/ uint16(xMatch),
-	/*1638*/ uint16(xSetOp), uint16(MOVHPD),
-	/*1640*/ uint16(xReadSlashR),
-	/*1641*/ uint16(xArgXmm2M64),
-	/*1642*/ uint16(xArgXmm),
-	/*1643*/ uint16(xMatch),
-	/*1644*/ uint16(xCondSlashR),
-	1653, // 0
-	1657, // 1
-	1661, // 2
-	1665, // 3
+	/*1424*/ uint16(xSetOp), uint16(PREFETCHW),
+	/*1426*/ uint16(xArgM8),
+	/*1427*/ uint16(xMatch),
+	/*1428*/ uint16(xCondPrefix), 4,
+	0xF3, 1456,
+	0xF2, 1450,
+	0x66, 1444,
+	0x0, 1438,
+	/*1438*/ uint16(xSetOp), uint16(MOVUPS),
+	/*1440*/ uint16(xReadSlashR),
+	/*1441*/ uint16(xArgXmm1),
+	/*1442*/ uint16(xArgXmm2M128),
+	/*1443*/ uint16(xMatch),
+	/*1444*/ uint16(xSetOp), uint16(MOVUPD),
+	/*1446*/ uint16(xReadSlashR),
+	/*1447*/ uint16(xArgXmm1),
+	/*1448*/ uint16(xArgXmm2M128),
+	/*1449*/ uint16(xMatch),
+	/*1450*/ uint16(xSetOp), uint16(MOVSD_XMM),
+	/*1452*/ uint16(xReadSlashR),
+	/*1453*/ uint16(xArgXmm1),
+	/*1454*/ uint16(xArgXmm2M64),
+	/*1455*/ uint16(xMatch),
+	/*1456*/ uint16(xSetOp), uint16(MOVSS),
+	/*1458*/ uint16(xReadSlashR),
+	/*1459*/ uint16(xArgXmm1),
+	/*1460*/ uint16(xArgXmm2M32),
+	/*1461*/ uint16(xMatch),
+	/*1462*/ uint16(xCondPrefix), 4,
+	0xF3, 1490,
+	0xF2, 1484,
+	0x66, 1478,
+	0x0, 1472,
+	/*1472*/ uint16(xSetOp), uint16(MOVUPS),
+	/*1474*/ uint16(xReadSlashR),
+	/*1475*/ uint16(xArgXmm2M128),
+	/*1476*/ uint16(xArgXmm1),
+	/*1477*/ uint16(xMatch),
+	/*1478*/ uint16(xSetOp), uint16(MOVUPD),
+	/*1480*/ uint16(xReadSlashR),
+	/*1481*/ uint16(xArgXmm2M128),
+	/*1482*/ uint16(xArgXmm),
+	/*1483*/ uint16(xMatch),
+	/*1484*/ uint16(xSetOp), uint16(MOVSD_XMM),
+	/*1486*/ uint16(xReadSlashR),
+	/*1487*/ uint16(xArgXmm2M64),
+	/*1488*/ uint16(xArgXmm1),
+	/*1489*/ uint16(xMatch),
+	/*1490*/ uint16(xSetOp), uint16(MOVSS),
+	/*1492*/ uint16(xReadSlashR),
+	/*1493*/ uint16(xArgXmm2M32),
+	/*1494*/ uint16(xArgXmm),
+	/*1495*/ uint16(xMatch),
+	/*1496*/ uint16(xCondPrefix), 4,
+	0xF3, 1533,
+	0xF2, 1527,
+	0x66, 1521,
+	0x0, 1506,
+	/*1506*/ uint16(xCondIsMem), 1509, 1515,
+	/*1509*/ uint16(xSetOp), uint16(MOVHLPS),
+	/*1511*/ uint16(xReadSlashR),
+	/*1512*/ uint16(xArgXmm1),
+	/*1513*/ uint16(xArgXmm2),
+	/*1514*/ uint16(xMatch),
+	/*1515*/ uint16(xSetOp), uint16(MOVLPS),
+	/*1517*/ uint16(xReadSlashR),
+	/*1518*/ uint16(xArgXmm),
+	/*1519*/ uint16(xArgM64),
+	/*1520*/ uint16(xMatch),
+	/*1521*/ uint16(xSetOp), uint16(MOVLPD),
+	/*1523*/ uint16(xReadSlashR),
+	/*1524*/ uint16(xArgXmm),
+	/*1525*/ uint16(xArgXmm2M64),
+	/*1526*/ uint16(xMatch),
+	/*1527*/ uint16(xSetOp), uint16(MOVDDUP),
+	/*1529*/ uint16(xReadSlashR),
+	/*1530*/ uint16(xArgXmm1),
+	/*1531*/ uint16(xArgXmm2M64),
+	/*1532*/ uint16(xMatch),
+	/*1533*/ uint16(xSetOp), uint16(MOVSLDUP),
+	/*1535*/ uint16(xReadSlashR),
+	/*1536*/ uint16(xArgXmm1),
+	/*1537*/ uint16(xArgXmm2M128),
+	/*1538*/ uint16(xMatch),
+	/*1539*/ uint16(xCondPrefix), 2,
+	0x66, 1551,
+	0x0, 1545,
+	/*1545*/ uint16(xSetOp), uint16(MOVLPS),
+	/*1547*/ uint16(xReadSlashR),
+	/*1548*/ uint16(xArgM64),
+	/*1549*/ uint16(xArgXmm),
+	/*1550*/ uint16(xMatch),
+	/*1551*/ uint16(xSetOp), uint16(MOVLPD),
+	/*1553*/ uint16(xReadSlashR),
+	/*1554*/ uint16(xArgXmm2M64),
+	/*1555*/ uint16(xArgXmm),
+	/*1556*/ uint16(xMatch),
+	/*1557*/ uint16(xCondPrefix), 2,
+	0x66, 1569,
+	0x0, 1563,
+	/*1563*/ uint16(xSetOp), uint16(UNPCKLPS),
+	/*1565*/ uint16(xReadSlashR),
+	/*1566*/ uint16(xArgXmm1),
+	/*1567*/ uint16(xArgXmm2M128),
+	/*1568*/ uint16(xMatch),
+	/*1569*/ uint16(xSetOp), uint16(UNPCKLPD),
+	/*1571*/ uint16(xReadSlashR),
+	/*1572*/ uint16(xArgXmm1),
+	/*1573*/ uint16(xArgXmm2M128),
+	/*1574*/ uint16(xMatch),
+	/*1575*/ uint16(xCondPrefix), 2,
+	0x66, 1587,
+	0x0, 1581,
+	/*1581*/ uint16(xSetOp), uint16(UNPCKHPS),
+	/*1583*/ uint16(xReadSlashR),
+	/*1584*/ uint16(xArgXmm1),
+	/*1585*/ uint16(xArgXmm2M128),
+	/*1586*/ uint16(xMatch),
+	/*1587*/ uint16(xSetOp), uint16(UNPCKHPD),
+	/*1589*/ uint16(xReadSlashR),
+	/*1590*/ uint16(xArgXmm1),
+	/*1591*/ uint16(xArgXmm2M128),
+	/*1592*/ uint16(xMatch),
+	/*1593*/ uint16(xCondPrefix), 3,
+	0xF3, 1622,
+	0x66, 1616,
+	0x0, 1601,
+	/*1601*/ uint16(xCondIsMem), 1604, 1610,
+	/*1604*/ uint16(xSetOp), uint16(MOVLHPS),
+	/*1606*/ uint16(xReadSlashR),
+	/*1607*/ uint16(xArgXmm1),
+	/*1608*/ uint16(xArgXmm2),
+	/*1609*/ uint16(xMatch),
+	/*1610*/ uint16(xSetOp), uint16(MOVHPS),
+	/*1612*/ uint16(xReadSlashR),
+	/*1613*/ uint16(xArgXmm),
+	/*1614*/ uint16(xArgM64),
+	/*1615*/ uint16(xMatch),
+	/*1616*/ uint16(xSetOp), uint16(MOVHPD),
+	/*1618*/ uint16(xReadSlashR),
+	/*1619*/ uint16(xArgXmm),
+	/*1620*/ uint16(xArgXmm2M64),
+	/*1621*/ uint16(xMatch),
+	/*1622*/ uint16(xSetOp), uint16(MOVSHDUP),
+	/*1624*/ uint16(xReadSlashR),
+	/*1625*/ uint16(xArgXmm1),
+	/*1626*/ uint16(xArgXmm2M128),
+	/*1627*/ uint16(xMatch),
+	/*1628*/ uint16(xCondPrefix), 2,
+	0x66, 1640,
+	0x0, 1634,
+	/*1634*/ uint16(xSetOp), uint16(MOVHPS),
+	/*1636*/ uint16(xReadSlashR),
+	/*1637*/ uint16(xArgM64),
+	/*1638*/ uint16(xArgXmm),
+	/*1639*/ uint16(xMatch),
+	/*1640*/ uint16(xSetOp), uint16(MOVHPD),
+	/*1642*/ uint16(xReadSlashR),
+	/*1643*/ uint16(xArgXmm2M64),
+	/*1644*/ uint16(xArgXmm),
+	/*1645*/ uint16(xMatch),
+	/*1646*/ uint16(xCondSlashR),
+	1655, // 0
+	1659, // 1
+	1663, // 2
+	1667, // 3
 	0,    // 4
 	0,    // 5
 	0,    // 6
 	0,    // 7
-	/*1653*/ uint16(xSetOp), uint16(PREFETCHNTA),
-	/*1655*/ uint16(xArgM8),
-	/*1656*/ uint16(xMatch),
-	/*1657*/ uint16(xSetOp), uint16(PREFETCHT0),
-	/*1659*/ uint16(xArgM8),
-	/*1660*/ uint16(xMatch),
-	/*1661*/ uint16(xSetOp), uint16(PREFETCHT1),
-	/*1663*/ uint16(xArgM8),
-	/*1664*/ uint16(xMatch),
-	/*1665*/ uint16(xSetOp), uint16(PREFETCHT2),
-	/*1667*/ uint16(xArgM8),
-	/*1668*/ uint16(xMatch),
-	/*1669*/ uint16(xCondSlashR),
-	1678, // 0
+	/*1655*/ uint16(xSetOp), uint16(PREFETCHNTA),
+	/*1657*/ uint16(xArgM8),
+	/*1658*/ uint16(xMatch),
+	/*1659*/ uint16(xSetOp), uint16(PREFETCHT0),
+	/*1661*/ uint16(xArgM8),
+	/*1662*/ uint16(xMatch),
+	/*1663*/ uint16(xSetOp), uint16(PREFETCHT1),
+	/*1665*/ uint16(xArgM8),
+	/*1666*/ uint16(xMatch),
+	/*1667*/ uint16(xSetOp), uint16(PREFETCHT2),
+	/*1669*/ uint16(xArgM8),
+	/*1670*/ uint16(xMatch),
+	/*1671*/ uint16(xCondSlashR),
+	1680, // 0
 	0,    // 1
 	0,    // 2
 	0,    // 3
@@ -988,5551 +989,5561 @@
 	0,    // 5
 	0,    // 6
 	0,    // 7
-	/*1678*/ uint16(xCondDataSize), 1682, 1686, 0,
-	/*1682*/ uint16(xSetOp), uint16(NOP),
-	/*1684*/ uint16(xArgRM16),
-	/*1685*/ uint16(xMatch),
-	/*1686*/ uint16(xSetOp), uint16(NOP),
-	/*1688*/ uint16(xArgRM32),
-	/*1689*/ uint16(xMatch),
-	/*1690*/ uint16(xCondIs64), 1693, 1699,
-	/*1693*/ uint16(xSetOp), uint16(MOV),
-	/*1695*/ uint16(xReadSlashR),
-	/*1696*/ uint16(xArgRmf32),
-	/*1697*/ uint16(xArgCR0dashCR7),
-	/*1698*/ uint16(xMatch),
-	/*1699*/ uint16(xSetOp), uint16(MOV),
-	/*1701*/ uint16(xReadSlashR),
-	/*1702*/ uint16(xArgRmf64),
-	/*1703*/ uint16(xArgCR0dashCR7),
-	/*1704*/ uint16(xMatch),
-	/*1705*/ uint16(xCondIs64), 1708, 1714,
-	/*1708*/ uint16(xSetOp), uint16(MOV),
-	/*1710*/ uint16(xReadSlashR),
-	/*1711*/ uint16(xArgRmf32),
-	/*1712*/ uint16(xArgDR0dashDR7),
-	/*1713*/ uint16(xMatch),
-	/*1714*/ uint16(xSetOp), uint16(MOV),
-	/*1716*/ uint16(xReadSlashR),
-	/*1717*/ uint16(xArgRmf64),
-	/*1718*/ uint16(xArgDR0dashDR7),
-	/*1719*/ uint16(xMatch),
-	/*1720*/ uint16(xCondIs64), 1723, 1729,
-	/*1723*/ uint16(xSetOp), uint16(MOV),
-	/*1725*/ uint16(xReadSlashR),
-	/*1726*/ uint16(xArgCR0dashCR7),
-	/*1727*/ uint16(xArgRmf32),
-	/*1728*/ uint16(xMatch),
-	/*1729*/ uint16(xSetOp), uint16(MOV),
-	/*1731*/ uint16(xReadSlashR),
-	/*1732*/ uint16(xArgCR0dashCR7),
-	/*1733*/ uint16(xArgRmf64),
-	/*1734*/ uint16(xMatch),
-	/*1735*/ uint16(xCondIs64), 1738, 1744,
-	/*1738*/ uint16(xSetOp), uint16(MOV),
-	/*1740*/ uint16(xReadSlashR),
-	/*1741*/ uint16(xArgDR0dashDR7),
-	/*1742*/ uint16(xArgRmf32),
-	/*1743*/ uint16(xMatch),
-	/*1744*/ uint16(xSetOp), uint16(MOV),
-	/*1746*/ uint16(xReadSlashR),
-	/*1747*/ uint16(xArgDR0dashDR7),
-	/*1748*/ uint16(xArgRmf64),
-	/*1749*/ uint16(xMatch),
-	/*1750*/ uint16(xCondIs64), 1753, 1759,
-	/*1753*/ uint16(xSetOp), uint16(MOV),
-	/*1755*/ uint16(xReadSlashR),
-	/*1756*/ uint16(xArgRmf32),
-	/*1757*/ uint16(xArgTR0dashTR7),
-	/*1758*/ uint16(xMatch),
-	/*1759*/ uint16(xSetOp), uint16(MOV),
-	/*1761*/ uint16(xReadSlashR),
-	/*1762*/ uint16(xArgRmf64),
-	/*1763*/ uint16(xArgTR0dashTR7),
-	/*1764*/ uint16(xMatch),
-	/*1765*/ uint16(xCondIs64), 1768, 1774,
-	/*1768*/ uint16(xSetOp), uint16(MOV),
-	/*1770*/ uint16(xReadSlashR),
-	/*1771*/ uint16(xArgTR0dashTR7),
-	/*1772*/ uint16(xArgRmf32),
-	/*1773*/ uint16(xMatch),
-	/*1774*/ uint16(xSetOp), uint16(MOV),
-	/*1776*/ uint16(xReadSlashR),
-	/*1777*/ uint16(xArgTR0dashTR7),
-	/*1778*/ uint16(xArgRmf64),
-	/*1779*/ uint16(xMatch),
-	/*1780*/ uint16(xCondPrefix), 2,
-	0x66, 1792,
-	0x0, 1786,
-	/*1786*/ uint16(xSetOp), uint16(MOVAPS),
-	/*1788*/ uint16(xReadSlashR),
-	/*1789*/ uint16(xArgXmm1),
-	/*1790*/ uint16(xArgXmm2M128),
-	/*1791*/ uint16(xMatch),
-	/*1792*/ uint16(xSetOp), uint16(MOVAPD),
-	/*1794*/ uint16(xReadSlashR),
-	/*1795*/ uint16(xArgXmm1),
-	/*1796*/ uint16(xArgXmm2M128),
-	/*1797*/ uint16(xMatch),
-	/*1798*/ uint16(xCondPrefix), 2,
-	0x66, 1810,
-	0x0, 1804,
-	/*1804*/ uint16(xSetOp), uint16(MOVAPS),
-	/*1806*/ uint16(xReadSlashR),
-	/*1807*/ uint16(xArgXmm2M128),
-	/*1808*/ uint16(xArgXmm1),
-	/*1809*/ uint16(xMatch),
-	/*1810*/ uint16(xSetOp), uint16(MOVAPD),
-	/*1812*/ uint16(xReadSlashR),
-	/*1813*/ uint16(xArgXmm2M128),
-	/*1814*/ uint16(xArgXmm1),
-	/*1815*/ uint16(xMatch),
-	/*1816*/ uint16(xCondIs64), 1819, 1873,
-	/*1819*/ uint16(xCondPrefix), 4,
-	0xF3, 1857,
-	0xF2, 1841,
-	0x66, 1835,
-	0x0, 1829,
-	/*1829*/ uint16(xSetOp), uint16(CVTPI2PS),
-	/*1831*/ uint16(xReadSlashR),
-	/*1832*/ uint16(xArgXmm),
-	/*1833*/ uint16(xArgMmM64),
-	/*1834*/ uint16(xMatch),
-	/*1835*/ uint16(xSetOp), uint16(CVTPI2PD),
-	/*1837*/ uint16(xReadSlashR),
-	/*1838*/ uint16(xArgXmm),
-	/*1839*/ uint16(xArgMmM64),
-	/*1840*/ uint16(xMatch),
-	/*1841*/ uint16(xCondDataSize), 1845, 1851, 0,
-	/*1845*/ uint16(xSetOp), uint16(CVTSI2SD),
-	/*1847*/ uint16(xReadSlashR),
-	/*1848*/ uint16(xArgXmm),
-	/*1849*/ uint16(xArgRM32),
-	/*1850*/ uint16(xMatch),
-	/*1851*/ uint16(xSetOp), uint16(CVTSI2SD),
-	/*1853*/ uint16(xReadSlashR),
-	/*1854*/ uint16(xArgXmm),
-	/*1855*/ uint16(xArgRM32),
-	/*1856*/ uint16(xMatch),
-	/*1857*/ uint16(xCondDataSize), 1861, 1867, 0,
-	/*1861*/ uint16(xSetOp), uint16(CVTSI2SS),
-	/*1863*/ uint16(xReadSlashR),
-	/*1864*/ uint16(xArgXmm),
-	/*1865*/ uint16(xArgRM32),
-	/*1866*/ uint16(xMatch),
-	/*1867*/ uint16(xSetOp), uint16(CVTSI2SS),
-	/*1869*/ uint16(xReadSlashR),
-	/*1870*/ uint16(xArgXmm),
-	/*1871*/ uint16(xArgRM32),
-	/*1872*/ uint16(xMatch),
-	/*1873*/ uint16(xCondPrefix), 4,
-	0xF3, 1893,
-	0xF2, 1883,
-	0x66, 1835,
-	0x0, 1829,
-	/*1883*/ uint16(xCondDataSize), 1845, 1851, 1887,
-	/*1887*/ uint16(xSetOp), uint16(CVTSI2SD),
-	/*1889*/ uint16(xReadSlashR),
-	/*1890*/ uint16(xArgXmm),
-	/*1891*/ uint16(xArgRM64),
-	/*1892*/ uint16(xMatch),
-	/*1893*/ uint16(xCondDataSize), 1861, 1867, 1897,
-	/*1897*/ uint16(xSetOp), uint16(CVTSI2SS),
-	/*1899*/ uint16(xReadSlashR),
-	/*1900*/ uint16(xArgXmm),
-	/*1901*/ uint16(xArgRM64),
-	/*1902*/ uint16(xMatch),
-	/*1903*/ uint16(xCondPrefix), 4,
-	0xF3, 1931,
-	0xF2, 1925,
-	0x66, 1919,
-	0x0, 1913,
-	/*1913*/ uint16(xSetOp), uint16(MOVNTPS),
-	/*1915*/ uint16(xReadSlashR),
-	/*1916*/ uint16(xArgM128),
-	/*1917*/ uint16(xArgXmm),
-	/*1918*/ uint16(xMatch),
-	/*1919*/ uint16(xSetOp), uint16(MOVNTPD),
-	/*1921*/ uint16(xReadSlashR),
-	/*1922*/ uint16(xArgM128),
-	/*1923*/ uint16(xArgXmm),
-	/*1924*/ uint16(xMatch),
-	/*1925*/ uint16(xSetOp), uint16(MOVNTSD),
-	/*1927*/ uint16(xReadSlashR),
-	/*1928*/ uint16(xArgM64),
-	/*1929*/ uint16(xArgXmm),
-	/*1930*/ uint16(xMatch),
-	/*1931*/ uint16(xSetOp), uint16(MOVNTSS),
-	/*1933*/ uint16(xReadSlashR),
-	/*1934*/ uint16(xArgM32),
-	/*1935*/ uint16(xArgXmm),
-	/*1936*/ uint16(xMatch),
-	/*1937*/ uint16(xCondIs64), 1940, 1994,
-	/*1940*/ uint16(xCondPrefix), 4,
-	0xF3, 1978,
-	0xF2, 1962,
-	0x66, 1956,
-	0x0, 1950,
-	/*1950*/ uint16(xSetOp), uint16(CVTTPS2PI),
-	/*1952*/ uint16(xReadSlashR),
-	/*1953*/ uint16(xArgMm),
-	/*1954*/ uint16(xArgXmmM64),
-	/*1955*/ uint16(xMatch),
-	/*1956*/ uint16(xSetOp), uint16(CVTTPD2PI),
-	/*1958*/ uint16(xReadSlashR),
-	/*1959*/ uint16(xArgMm),
-	/*1960*/ uint16(xArgXmmM128),
-	/*1961*/ uint16(xMatch),
-	/*1962*/ uint16(xCondDataSize), 1966, 1972, 0,
-	/*1966*/ uint16(xSetOp), uint16(CVTTSD2SI),
-	/*1968*/ uint16(xReadSlashR),
-	/*1969*/ uint16(xArgR32),
-	/*1970*/ uint16(xArgXmmM64),
-	/*1971*/ uint16(xMatch),
-	/*1972*/ uint16(xSetOp), uint16(CVTTSD2SI),
-	/*1974*/ uint16(xReadSlashR),
-	/*1975*/ uint16(xArgR32),
-	/*1976*/ uint16(xArgXmmM64),
-	/*1977*/ uint16(xMatch),
-	/*1978*/ uint16(xCondDataSize), 1982, 1988, 0,
-	/*1982*/ uint16(xSetOp), uint16(CVTTSS2SI),
-	/*1984*/ uint16(xReadSlashR),
-	/*1985*/ uint16(xArgR32),
-	/*1986*/ uint16(xArgXmmM32),
-	/*1987*/ uint16(xMatch),
-	/*1988*/ uint16(xSetOp), uint16(CVTTSS2SI),
-	/*1990*/ uint16(xReadSlashR),
-	/*1991*/ uint16(xArgR32),
-	/*1992*/ uint16(xArgXmmM32),
-	/*1993*/ uint16(xMatch),
-	/*1994*/ uint16(xCondPrefix), 4,
-	0xF3, 2014,
-	0xF2, 2004,
-	0x66, 1956,
-	0x0, 1950,
-	/*2004*/ uint16(xCondDataSize), 1966, 1972, 2008,
-	/*2008*/ uint16(xSetOp), uint16(CVTTSD2SI),
-	/*2010*/ uint16(xReadSlashR),
-	/*2011*/ uint16(xArgR64),
-	/*2012*/ uint16(xArgXmmM64),
-	/*2013*/ uint16(xMatch),
-	/*2014*/ uint16(xCondDataSize), 1982, 1988, 2018,
-	/*2018*/ uint16(xSetOp), uint16(CVTTSS2SI),
-	/*2020*/ uint16(xReadSlashR),
-	/*2021*/ uint16(xArgR64),
-	/*2022*/ uint16(xArgXmmM32),
-	/*2023*/ uint16(xMatch),
-	/*2024*/ uint16(xCondIs64), 2027, 2081,
-	/*2027*/ uint16(xCondPrefix), 4,
-	0xF3, 2065,
-	0xF2, 2049,
-	0x66, 2043,
-	0x0, 2037,
-	/*2037*/ uint16(xSetOp), uint16(CVTPS2PI),
-	/*2039*/ uint16(xReadSlashR),
-	/*2040*/ uint16(xArgMm),
-	/*2041*/ uint16(xArgXmmM64),
-	/*2042*/ uint16(xMatch),
-	/*2043*/ uint16(xSetOp), uint16(CVTPD2PI),
-	/*2045*/ uint16(xReadSlashR),
-	/*2046*/ uint16(xArgMm),
-	/*2047*/ uint16(xArgXmmM128),
-	/*2048*/ uint16(xMatch),
-	/*2049*/ uint16(xCondDataSize), 2053, 2059, 0,
-	/*2053*/ uint16(xSetOp), uint16(CVTSD2SI),
-	/*2055*/ uint16(xReadSlashR),
-	/*2056*/ uint16(xArgR32),
-	/*2057*/ uint16(xArgXmmM64),
-	/*2058*/ uint16(xMatch),
-	/*2059*/ uint16(xSetOp), uint16(CVTSD2SI),
-	/*2061*/ uint16(xReadSlashR),
-	/*2062*/ uint16(xArgR32),
-	/*2063*/ uint16(xArgXmmM64),
-	/*2064*/ uint16(xMatch),
-	/*2065*/ uint16(xCondDataSize), 2069, 2075, 0,
-	/*2069*/ uint16(xSetOp), uint16(CVTSS2SI),
-	/*2071*/ uint16(xReadSlashR),
-	/*2072*/ uint16(xArgR32),
-	/*2073*/ uint16(xArgXmmM32),
-	/*2074*/ uint16(xMatch),
-	/*2075*/ uint16(xSetOp), uint16(CVTSS2SI),
-	/*2077*/ uint16(xReadSlashR),
-	/*2078*/ uint16(xArgR32),
-	/*2079*/ uint16(xArgXmmM32),
-	/*2080*/ uint16(xMatch),
-	/*2081*/ uint16(xCondPrefix), 4,
-	0xF3, 2101,
-	0xF2, 2091,
-	0x66, 2043,
-	0x0, 2037,
-	/*2091*/ uint16(xCondDataSize), 2053, 2059, 2095,
-	/*2095*/ uint16(xSetOp), uint16(CVTSD2SI),
-	/*2097*/ uint16(xReadSlashR),
-	/*2098*/ uint16(xArgR64),
-	/*2099*/ uint16(xArgXmmM64),
-	/*2100*/ uint16(xMatch),
-	/*2101*/ uint16(xCondDataSize), 2069, 2075, 2105,
-	/*2105*/ uint16(xSetOp), uint16(CVTSS2SI),
-	/*2107*/ uint16(xReadSlashR),
-	/*2108*/ uint16(xArgR64),
-	/*2109*/ uint16(xArgXmmM32),
-	/*2110*/ uint16(xMatch),
-	/*2111*/ uint16(xCondPrefix), 2,
-	0x66, 2123,
-	0x0, 2117,
-	/*2117*/ uint16(xSetOp), uint16(UCOMISS),
-	/*2119*/ uint16(xReadSlashR),
-	/*2120*/ uint16(xArgXmm1),
-	/*2121*/ uint16(xArgXmm2M32),
-	/*2122*/ uint16(xMatch),
-	/*2123*/ uint16(xSetOp), uint16(UCOMISD),
-	/*2125*/ uint16(xReadSlashR),
-	/*2126*/ uint16(xArgXmm1),
-	/*2127*/ uint16(xArgXmm2M64),
-	/*2128*/ uint16(xMatch),
-	/*2129*/ uint16(xCondPrefix), 2,
-	0x66, 2141,
-	0x0, 2135,
-	/*2135*/ uint16(xSetOp), uint16(COMISS),
-	/*2137*/ uint16(xReadSlashR),
-	/*2138*/ uint16(xArgXmm1),
-	/*2139*/ uint16(xArgXmm2M32),
-	/*2140*/ uint16(xMatch),
-	/*2141*/ uint16(xSetOp), uint16(COMISD),
-	/*2143*/ uint16(xReadSlashR),
-	/*2144*/ uint16(xArgXmm1),
-	/*2145*/ uint16(xArgXmm2M64),
-	/*2146*/ uint16(xMatch),
-	/*2147*/ uint16(xSetOp), uint16(WRMSR),
-	/*2149*/ uint16(xMatch),
-	/*2150*/ uint16(xSetOp), uint16(RDTSC),
-	/*2152*/ uint16(xMatch),
-	/*2153*/ uint16(xSetOp), uint16(RDMSR),
-	/*2155*/ uint16(xMatch),
-	/*2156*/ uint16(xSetOp), uint16(RDPMC),
-	/*2158*/ uint16(xMatch),
-	/*2159*/ uint16(xSetOp), uint16(SYSENTER),
-	/*2161*/ uint16(xMatch),
-	/*2162*/ uint16(xCondDataSize), 2166, 2166, 2169,
-	/*2166*/ uint16(xSetOp), uint16(SYSEXIT),
-	/*2168*/ uint16(xMatch),
-	/*2169*/ uint16(xSetOp), uint16(SYSEXIT),
-	/*2171*/ uint16(xMatch),
-	/*2172*/ uint16(xCondByte), 54,
-	0x00, 2283,
-	0x01, 2301,
-	0x02, 2319,
-	0x03, 2337,
-	0x04, 2355,
-	0x05, 2373,
-	0x06, 2391,
-	0x07, 2409,
-	0x08, 2427,
-	0x09, 2445,
-	0x0A, 2463,
-	0x0B, 2481,
-	0x10, 2499,
-	0x14, 2510,
-	0x15, 2521,
-	0x17, 2532,
-	0x1C, 2542,
-	0x1D, 2560,
-	0x1E, 2578,
-	0x20, 2596,
-	0x21, 2606,
-	0x22, 2616,
-	0x23, 2626,
-	0x24, 2636,
-	0x25, 2646,
-	0x28, 2656,
-	0x29, 2666,
-	0x2A, 2676,
-	0x2B, 2686,
-	0x30, 2696,
-	0x31, 2706,
-	0x32, 2716,
-	0x33, 2726,
-	0x34, 2736,
-	0x35, 2746,
-	0x37, 2756,
-	0x38, 2766,
-	0x39, 2776,
-	0x3A, 2786,
-	0x3B, 2796,
-	0x3C, 2806,
-	0x3D, 2816,
-	0x3E, 2826,
-	0x3F, 2836,
-	0x40, 2846,
-	0x41, 2856,
-	0x82, 2866,
-	0xDB, 2889,
-	0xDC, 2899,
-	0xDD, 2909,
-	0xDE, 2919,
-	0xDF, 2929,
-	0xF0, 2939,
-	0xF1, 3006,
+	/*1680*/ uint16(xCondDataSize), 1684, 1688, 0,
+	/*1684*/ uint16(xSetOp), uint16(NOP),
+	/*1686*/ uint16(xArgRM16),
+	/*1687*/ uint16(xMatch),
+	/*1688*/ uint16(xSetOp), uint16(NOP),
+	/*1690*/ uint16(xArgRM32),
+	/*1691*/ uint16(xMatch),
+	/*1692*/ uint16(xCondIs64), 1695, 1701,
+	/*1695*/ uint16(xSetOp), uint16(MOV),
+	/*1697*/ uint16(xReadSlashR),
+	/*1698*/ uint16(xArgRmf32),
+	/*1699*/ uint16(xArgCR0dashCR7),
+	/*1700*/ uint16(xMatch),
+	/*1701*/ uint16(xSetOp), uint16(MOV),
+	/*1703*/ uint16(xReadSlashR),
+	/*1704*/ uint16(xArgRmf64),
+	/*1705*/ uint16(xArgCR0dashCR7),
+	/*1706*/ uint16(xMatch),
+	/*1707*/ uint16(xCondIs64), 1710, 1716,
+	/*1710*/ uint16(xSetOp), uint16(MOV),
+	/*1712*/ uint16(xReadSlashR),
+	/*1713*/ uint16(xArgRmf32),
+	/*1714*/ uint16(xArgDR0dashDR7),
+	/*1715*/ uint16(xMatch),
+	/*1716*/ uint16(xSetOp), uint16(MOV),
+	/*1718*/ uint16(xReadSlashR),
+	/*1719*/ uint16(xArgRmf64),
+	/*1720*/ uint16(xArgDR0dashDR7),
+	/*1721*/ uint16(xMatch),
+	/*1722*/ uint16(xCondIs64), 1725, 1731,
+	/*1725*/ uint16(xSetOp), uint16(MOV),
+	/*1727*/ uint16(xReadSlashR),
+	/*1728*/ uint16(xArgCR0dashCR7),
+	/*1729*/ uint16(xArgRmf32),
+	/*1730*/ uint16(xMatch),
+	/*1731*/ uint16(xSetOp), uint16(MOV),
+	/*1733*/ uint16(xReadSlashR),
+	/*1734*/ uint16(xArgCR0dashCR7),
+	/*1735*/ uint16(xArgRmf64),
+	/*1736*/ uint16(xMatch),
+	/*1737*/ uint16(xCondIs64), 1740, 1746,
+	/*1740*/ uint16(xSetOp), uint16(MOV),
+	/*1742*/ uint16(xReadSlashR),
+	/*1743*/ uint16(xArgDR0dashDR7),
+	/*1744*/ uint16(xArgRmf32),
+	/*1745*/ uint16(xMatch),
+	/*1746*/ uint16(xSetOp), uint16(MOV),
+	/*1748*/ uint16(xReadSlashR),
+	/*1749*/ uint16(xArgDR0dashDR7),
+	/*1750*/ uint16(xArgRmf64),
+	/*1751*/ uint16(xMatch),
+	/*1752*/ uint16(xCondIs64), 1755, 1761,
+	/*1755*/ uint16(xSetOp), uint16(MOV),
+	/*1757*/ uint16(xReadSlashR),
+	/*1758*/ uint16(xArgRmf32),
+	/*1759*/ uint16(xArgTR0dashTR7),
+	/*1760*/ uint16(xMatch),
+	/*1761*/ uint16(xSetOp), uint16(MOV),
+	/*1763*/ uint16(xReadSlashR),
+	/*1764*/ uint16(xArgRmf64),
+	/*1765*/ uint16(xArgTR0dashTR7),
+	/*1766*/ uint16(xMatch),
+	/*1767*/ uint16(xCondIs64), 1770, 1776,
+	/*1770*/ uint16(xSetOp), uint16(MOV),
+	/*1772*/ uint16(xReadSlashR),
+	/*1773*/ uint16(xArgTR0dashTR7),
+	/*1774*/ uint16(xArgRmf32),
+	/*1775*/ uint16(xMatch),
+	/*1776*/ uint16(xSetOp), uint16(MOV),
+	/*1778*/ uint16(xReadSlashR),
+	/*1779*/ uint16(xArgTR0dashTR7),
+	/*1780*/ uint16(xArgRmf64),
+	/*1781*/ uint16(xMatch),
+	/*1782*/ uint16(xCondPrefix), 2,
+	0x66, 1794,
+	0x0, 1788,
+	/*1788*/ uint16(xSetOp), uint16(MOVAPS),
+	/*1790*/ uint16(xReadSlashR),
+	/*1791*/ uint16(xArgXmm1),
+	/*1792*/ uint16(xArgXmm2M128),
+	/*1793*/ uint16(xMatch),
+	/*1794*/ uint16(xSetOp), uint16(MOVAPD),
+	/*1796*/ uint16(xReadSlashR),
+	/*1797*/ uint16(xArgXmm1),
+	/*1798*/ uint16(xArgXmm2M128),
+	/*1799*/ uint16(xMatch),
+	/*1800*/ uint16(xCondPrefix), 2,
+	0x66, 1812,
+	0x0, 1806,
+	/*1806*/ uint16(xSetOp), uint16(MOVAPS),
+	/*1808*/ uint16(xReadSlashR),
+	/*1809*/ uint16(xArgXmm2M128),
+	/*1810*/ uint16(xArgXmm1),
+	/*1811*/ uint16(xMatch),
+	/*1812*/ uint16(xSetOp), uint16(MOVAPD),
+	/*1814*/ uint16(xReadSlashR),
+	/*1815*/ uint16(xArgXmm2M128),
+	/*1816*/ uint16(xArgXmm1),
+	/*1817*/ uint16(xMatch),
+	/*1818*/ uint16(xCondIs64), 1821, 1875,
+	/*1821*/ uint16(xCondPrefix), 4,
+	0xF3, 1859,
+	0xF2, 1843,
+	0x66, 1837,
+	0x0, 1831,
+	/*1831*/ uint16(xSetOp), uint16(CVTPI2PS),
+	/*1833*/ uint16(xReadSlashR),
+	/*1834*/ uint16(xArgXmm),
+	/*1835*/ uint16(xArgMmM64),
+	/*1836*/ uint16(xMatch),
+	/*1837*/ uint16(xSetOp), uint16(CVTPI2PD),
+	/*1839*/ uint16(xReadSlashR),
+	/*1840*/ uint16(xArgXmm),
+	/*1841*/ uint16(xArgMmM64),
+	/*1842*/ uint16(xMatch),
+	/*1843*/ uint16(xCondDataSize), 1847, 1853, 0,
+	/*1847*/ uint16(xSetOp), uint16(CVTSI2SD),
+	/*1849*/ uint16(xReadSlashR),
+	/*1850*/ uint16(xArgXmm),
+	/*1851*/ uint16(xArgRM32),
+	/*1852*/ uint16(xMatch),
+	/*1853*/ uint16(xSetOp), uint16(CVTSI2SD),
+	/*1855*/ uint16(xReadSlashR),
+	/*1856*/ uint16(xArgXmm),
+	/*1857*/ uint16(xArgRM32),
+	/*1858*/ uint16(xMatch),
+	/*1859*/ uint16(xCondDataSize), 1863, 1869, 0,
+	/*1863*/ uint16(xSetOp), uint16(CVTSI2SS),
+	/*1865*/ uint16(xReadSlashR),
+	/*1866*/ uint16(xArgXmm),
+	/*1867*/ uint16(xArgRM32),
+	/*1868*/ uint16(xMatch),
+	/*1869*/ uint16(xSetOp), uint16(CVTSI2SS),
+	/*1871*/ uint16(xReadSlashR),
+	/*1872*/ uint16(xArgXmm),
+	/*1873*/ uint16(xArgRM32),
+	/*1874*/ uint16(xMatch),
+	/*1875*/ uint16(xCondPrefix), 4,
+	0xF3, 1895,
+	0xF2, 1885,
+	0x66, 1837,
+	0x0, 1831,
+	/*1885*/ uint16(xCondDataSize), 1847, 1853, 1889,
+	/*1889*/ uint16(xSetOp), uint16(CVTSI2SD),
+	/*1891*/ uint16(xReadSlashR),
+	/*1892*/ uint16(xArgXmm),
+	/*1893*/ uint16(xArgRM64),
+	/*1894*/ uint16(xMatch),
+	/*1895*/ uint16(xCondDataSize), 1863, 1869, 1899,
+	/*1899*/ uint16(xSetOp), uint16(CVTSI2SS),
+	/*1901*/ uint16(xReadSlashR),
+	/*1902*/ uint16(xArgXmm),
+	/*1903*/ uint16(xArgRM64),
+	/*1904*/ uint16(xMatch),
+	/*1905*/ uint16(xCondPrefix), 4,
+	0xF3, 1933,
+	0xF2, 1927,
+	0x66, 1921,
+	0x0, 1915,
+	/*1915*/ uint16(xSetOp), uint16(MOVNTPS),
+	/*1917*/ uint16(xReadSlashR),
+	/*1918*/ uint16(xArgM128),
+	/*1919*/ uint16(xArgXmm),
+	/*1920*/ uint16(xMatch),
+	/*1921*/ uint16(xSetOp), uint16(MOVNTPD),
+	/*1923*/ uint16(xReadSlashR),
+	/*1924*/ uint16(xArgM128),
+	/*1925*/ uint16(xArgXmm),
+	/*1926*/ uint16(xMatch),
+	/*1927*/ uint16(xSetOp), uint16(MOVNTSD),
+	/*1929*/ uint16(xReadSlashR),
+	/*1930*/ uint16(xArgM64),
+	/*1931*/ uint16(xArgXmm),
+	/*1932*/ uint16(xMatch),
+	/*1933*/ uint16(xSetOp), uint16(MOVNTSS),
+	/*1935*/ uint16(xReadSlashR),
+	/*1936*/ uint16(xArgM32),
+	/*1937*/ uint16(xArgXmm),
+	/*1938*/ uint16(xMatch),
+	/*1939*/ uint16(xCondIs64), 1942, 1996,
+	/*1942*/ uint16(xCondPrefix), 4,
+	0xF3, 1980,
+	0xF2, 1964,
+	0x66, 1958,
+	0x0, 1952,
+	/*1952*/ uint16(xSetOp), uint16(CVTTPS2PI),
+	/*1954*/ uint16(xReadSlashR),
+	/*1955*/ uint16(xArgMm),
+	/*1956*/ uint16(xArgXmmM64),
+	/*1957*/ uint16(xMatch),
+	/*1958*/ uint16(xSetOp), uint16(CVTTPD2PI),
+	/*1960*/ uint16(xReadSlashR),
+	/*1961*/ uint16(xArgMm),
+	/*1962*/ uint16(xArgXmmM128),
+	/*1963*/ uint16(xMatch),
+	/*1964*/ uint16(xCondDataSize), 1968, 1974, 0,
+	/*1968*/ uint16(xSetOp), uint16(CVTTSD2SI),
+	/*1970*/ uint16(xReadSlashR),
+	/*1971*/ uint16(xArgR32),
+	/*1972*/ uint16(xArgXmmM64),
+	/*1973*/ uint16(xMatch),
+	/*1974*/ uint16(xSetOp), uint16(CVTTSD2SI),
+	/*1976*/ uint16(xReadSlashR),
+	/*1977*/ uint16(xArgR32),
+	/*1978*/ uint16(xArgXmmM64),
+	/*1979*/ uint16(xMatch),
+	/*1980*/ uint16(xCondDataSize), 1984, 1990, 0,
+	/*1984*/ uint16(xSetOp), uint16(CVTTSS2SI),
+	/*1986*/ uint16(xReadSlashR),
+	/*1987*/ uint16(xArgR32),
+	/*1988*/ uint16(xArgXmmM32),
+	/*1989*/ uint16(xMatch),
+	/*1990*/ uint16(xSetOp), uint16(CVTTSS2SI),
+	/*1992*/ uint16(xReadSlashR),
+	/*1993*/ uint16(xArgR32),
+	/*1994*/ uint16(xArgXmmM32),
+	/*1995*/ uint16(xMatch),
+	/*1996*/ uint16(xCondPrefix), 4,
+	0xF3, 2016,
+	0xF2, 2006,
+	0x66, 1958,
+	0x0, 1952,
+	/*2006*/ uint16(xCondDataSize), 1968, 1974, 2010,
+	/*2010*/ uint16(xSetOp), uint16(CVTTSD2SI),
+	/*2012*/ uint16(xReadSlashR),
+	/*2013*/ uint16(xArgR64),
+	/*2014*/ uint16(xArgXmmM64),
+	/*2015*/ uint16(xMatch),
+	/*2016*/ uint16(xCondDataSize), 1984, 1990, 2020,
+	/*2020*/ uint16(xSetOp), uint16(CVTTSS2SI),
+	/*2022*/ uint16(xReadSlashR),
+	/*2023*/ uint16(xArgR64),
+	/*2024*/ uint16(xArgXmmM32),
+	/*2025*/ uint16(xMatch),
+	/*2026*/ uint16(xCondIs64), 2029, 2083,
+	/*2029*/ uint16(xCondPrefix), 4,
+	0xF3, 2067,
+	0xF2, 2051,
+	0x66, 2045,
+	0x0, 2039,
+	/*2039*/ uint16(xSetOp), uint16(CVTPS2PI),
+	/*2041*/ uint16(xReadSlashR),
+	/*2042*/ uint16(xArgMm),
+	/*2043*/ uint16(xArgXmmM64),
+	/*2044*/ uint16(xMatch),
+	/*2045*/ uint16(xSetOp), uint16(CVTPD2PI),
+	/*2047*/ uint16(xReadSlashR),
+	/*2048*/ uint16(xArgMm),
+	/*2049*/ uint16(xArgXmmM128),
+	/*2050*/ uint16(xMatch),
+	/*2051*/ uint16(xCondDataSize), 2055, 2061, 0,
+	/*2055*/ uint16(xSetOp), uint16(CVTSD2SI),
+	/*2057*/ uint16(xReadSlashR),
+	/*2058*/ uint16(xArgR32),
+	/*2059*/ uint16(xArgXmmM64),
+	/*2060*/ uint16(xMatch),
+	/*2061*/ uint16(xSetOp), uint16(CVTSD2SI),
+	/*2063*/ uint16(xReadSlashR),
+	/*2064*/ uint16(xArgR32),
+	/*2065*/ uint16(xArgXmmM64),
+	/*2066*/ uint16(xMatch),
+	/*2067*/ uint16(xCondDataSize), 2071, 2077, 0,
+	/*2071*/ uint16(xSetOp), uint16(CVTSS2SI),
+	/*2073*/ uint16(xReadSlashR),
+	/*2074*/ uint16(xArgR32),
+	/*2075*/ uint16(xArgXmmM32),
+	/*2076*/ uint16(xMatch),
+	/*2077*/ uint16(xSetOp), uint16(CVTSS2SI),
+	/*2079*/ uint16(xReadSlashR),
+	/*2080*/ uint16(xArgR32),
+	/*2081*/ uint16(xArgXmmM32),
+	/*2082*/ uint16(xMatch),
+	/*2083*/ uint16(xCondPrefix), 4,
+	0xF3, 2103,
+	0xF2, 2093,
+	0x66, 2045,
+	0x0, 2039,
+	/*2093*/ uint16(xCondDataSize), 2055, 2061, 2097,
+	/*2097*/ uint16(xSetOp), uint16(CVTSD2SI),
+	/*2099*/ uint16(xReadSlashR),
+	/*2100*/ uint16(xArgR64),
+	/*2101*/ uint16(xArgXmmM64),
+	/*2102*/ uint16(xMatch),
+	/*2103*/ uint16(xCondDataSize), 2071, 2077, 2107,
+	/*2107*/ uint16(xSetOp), uint16(CVTSS2SI),
+	/*2109*/ uint16(xReadSlashR),
+	/*2110*/ uint16(xArgR64),
+	/*2111*/ uint16(xArgXmmM32),
+	/*2112*/ uint16(xMatch),
+	/*2113*/ uint16(xCondPrefix), 2,
+	0x66, 2125,
+	0x0, 2119,
+	/*2119*/ uint16(xSetOp), uint16(UCOMISS),
+	/*2121*/ uint16(xReadSlashR),
+	/*2122*/ uint16(xArgXmm1),
+	/*2123*/ uint16(xArgXmm2M32),
+	/*2124*/ uint16(xMatch),
+	/*2125*/ uint16(xSetOp), uint16(UCOMISD),
+	/*2127*/ uint16(xReadSlashR),
+	/*2128*/ uint16(xArgXmm1),
+	/*2129*/ uint16(xArgXmm2M64),
+	/*2130*/ uint16(xMatch),
+	/*2131*/ uint16(xCondPrefix), 2,
+	0x66, 2143,
+	0x0, 2137,
+	/*2137*/ uint16(xSetOp), uint16(COMISS),
+	/*2139*/ uint16(xReadSlashR),
+	/*2140*/ uint16(xArgXmm1),
+	/*2141*/ uint16(xArgXmm2M32),
+	/*2142*/ uint16(xMatch),
+	/*2143*/ uint16(xSetOp), uint16(COMISD),
+	/*2145*/ uint16(xReadSlashR),
+	/*2146*/ uint16(xArgXmm1),
+	/*2147*/ uint16(xArgXmm2M64),
+	/*2148*/ uint16(xMatch),
+	/*2149*/ uint16(xSetOp), uint16(WRMSR),
+	/*2151*/ uint16(xMatch),
+	/*2152*/ uint16(xSetOp), uint16(RDTSC),
+	/*2154*/ uint16(xMatch),
+	/*2155*/ uint16(xSetOp), uint16(RDMSR),
+	/*2157*/ uint16(xMatch),
+	/*2158*/ uint16(xSetOp), uint16(RDPMC),
+	/*2160*/ uint16(xMatch),
+	/*2161*/ uint16(xSetOp), uint16(SYSENTER),
+	/*2163*/ uint16(xMatch),
+	/*2164*/ uint16(xCondDataSize), 2168, 2168, 2171,
+	/*2168*/ uint16(xSetOp), uint16(SYSEXIT),
+	/*2170*/ uint16(xMatch),
+	/*2171*/ uint16(xSetOp), uint16(SYSEXIT),
+	/*2173*/ uint16(xMatch),
+	/*2174*/ uint16(xCondByte), 54,
+	0x00, 2285,
+	0x01, 2303,
+	0x02, 2321,
+	0x03, 2339,
+	0x04, 2357,
+	0x05, 2375,
+	0x06, 2393,
+	0x07, 2411,
+	0x08, 2429,
+	0x09, 2447,
+	0x0A, 2465,
+	0x0B, 2483,
+	0x10, 2501,
+	0x14, 2512,
+	0x15, 2523,
+	0x17, 2534,
+	0x1C, 2544,
+	0x1D, 2562,
+	0x1E, 2580,
+	0x20, 2598,
+	0x21, 2608,
+	0x22, 2618,
+	0x23, 2628,
+	0x24, 2638,
+	0x25, 2648,
+	0x28, 2658,
+	0x29, 2668,
+	0x2A, 2678,
+	0x2B, 2688,
+	0x30, 2698,
+	0x31, 2708,
+	0x32, 2718,
+	0x33, 2728,
+	0x34, 2738,
+	0x35, 2748,
+	0x37, 2758,
+	0x38, 2768,
+	0x39, 2778,
+	0x3A, 2788,
+	0x3B, 2798,
+	0x3C, 2808,
+	0x3D, 2818,
+	0x3E, 2828,
+	0x3F, 2838,
+	0x40, 2848,
+	0x41, 2858,
+	0x82, 2868,
+	0xDB, 2891,
+	0xDC, 2901,
+	0xDD, 2911,
+	0xDE, 2921,
+	0xDF, 2931,
+	0xF0, 2941,
+	0xF1, 3008,
 	uint16(xFail),
-	/*2283*/ uint16(xCondPrefix), 2,
-	0x66, 2295,
-	0x0, 2289,
-	/*2289*/ uint16(xSetOp), uint16(PSHUFB),
-	/*2291*/ uint16(xReadSlashR),
-	/*2292*/ uint16(xArgMm1),
-	/*2293*/ uint16(xArgMm2M64),
-	/*2294*/ uint16(xMatch),
-	/*2295*/ uint16(xSetOp), uint16(PSHUFB),
-	/*2297*/ uint16(xReadSlashR),
-	/*2298*/ uint16(xArgXmm1),
-	/*2299*/ uint16(xArgXmm2M128),
-	/*2300*/ uint16(xMatch),
-	/*2301*/ uint16(xCondPrefix), 2,
-	0x66, 2313,
-	0x0, 2307,
-	/*2307*/ uint16(xSetOp), uint16(PHADDW),
-	/*2309*/ uint16(xReadSlashR),
-	/*2310*/ uint16(xArgMm1),
-	/*2311*/ uint16(xArgMm2M64),
-	/*2312*/ uint16(xMatch),
-	/*2313*/ uint16(xSetOp), uint16(PHADDW),
-	/*2315*/ uint16(xReadSlashR),
-	/*2316*/ uint16(xArgXmm1),
-	/*2317*/ uint16(xArgXmm2M128),
-	/*2318*/ uint16(xMatch),
-	/*2319*/ uint16(xCondPrefix), 2,
-	0x66, 2331,
-	0x0, 2325,
-	/*2325*/ uint16(xSetOp), uint16(PHADDD),
-	/*2327*/ uint16(xReadSlashR),
-	/*2328*/ uint16(xArgMm1),
-	/*2329*/ uint16(xArgMm2M64),
-	/*2330*/ uint16(xMatch),
-	/*2331*/ uint16(xSetOp), uint16(PHADDD),
-	/*2333*/ uint16(xReadSlashR),
-	/*2334*/ uint16(xArgXmm1),
-	/*2335*/ uint16(xArgXmm2M128),
-	/*2336*/ uint16(xMatch),
-	/*2337*/ uint16(xCondPrefix), 2,
-	0x66, 2349,
-	0x0, 2343,
-	/*2343*/ uint16(xSetOp), uint16(PHADDSW),
-	/*2345*/ uint16(xReadSlashR),
-	/*2346*/ uint16(xArgMm1),
-	/*2347*/ uint16(xArgMm2M64),
-	/*2348*/ uint16(xMatch),
-	/*2349*/ uint16(xSetOp), uint16(PHADDSW),
-	/*2351*/ uint16(xReadSlashR),
-	/*2352*/ uint16(xArgXmm1),
-	/*2353*/ uint16(xArgXmm2M128),
-	/*2354*/ uint16(xMatch),
-	/*2355*/ uint16(xCondPrefix), 2,
-	0x66, 2367,
-	0x0, 2361,
-	/*2361*/ uint16(xSetOp), uint16(PMADDUBSW),
-	/*2363*/ uint16(xReadSlashR),
-	/*2364*/ uint16(xArgMm1),
-	/*2365*/ uint16(xArgMm2M64),
-	/*2366*/ uint16(xMatch),
-	/*2367*/ uint16(xSetOp), uint16(PMADDUBSW),
-	/*2369*/ uint16(xReadSlashR),
-	/*2370*/ uint16(xArgXmm1),
-	/*2371*/ uint16(xArgXmm2M128),
-	/*2372*/ uint16(xMatch),
-	/*2373*/ uint16(xCondPrefix), 2,
-	0x66, 2385,
-	0x0, 2379,
-	/*2379*/ uint16(xSetOp), uint16(PHSUBW),
-	/*2381*/ uint16(xReadSlashR),
-	/*2382*/ uint16(xArgMm1),
-	/*2383*/ uint16(xArgMm2M64),
-	/*2384*/ uint16(xMatch),
-	/*2385*/ uint16(xSetOp), uint16(PHSUBW),
-	/*2387*/ uint16(xReadSlashR),
-	/*2388*/ uint16(xArgXmm1),
-	/*2389*/ uint16(xArgXmm2M128),
-	/*2390*/ uint16(xMatch),
-	/*2391*/ uint16(xCondPrefix), 2,
-	0x66, 2403,
-	0x0, 2397,
-	/*2397*/ uint16(xSetOp), uint16(PHSUBD),
-	/*2399*/ uint16(xReadSlashR),
-	/*2400*/ uint16(xArgMm1),
-	/*2401*/ uint16(xArgMm2M64),
-	/*2402*/ uint16(xMatch),
-	/*2403*/ uint16(xSetOp), uint16(PHSUBD),
-	/*2405*/ uint16(xReadSlashR),
-	/*2406*/ uint16(xArgXmm1),
-	/*2407*/ uint16(xArgXmm2M128),
-	/*2408*/ uint16(xMatch),
-	/*2409*/ uint16(xCondPrefix), 2,
-	0x66, 2421,
-	0x0, 2415,
-	/*2415*/ uint16(xSetOp), uint16(PHSUBSW),
-	/*2417*/ uint16(xReadSlashR),
-	/*2418*/ uint16(xArgMm1),
-	/*2419*/ uint16(xArgMm2M64),
-	/*2420*/ uint16(xMatch),
-	/*2421*/ uint16(xSetOp), uint16(PHSUBSW),
-	/*2423*/ uint16(xReadSlashR),
-	/*2424*/ uint16(xArgXmm1),
-	/*2425*/ uint16(xArgXmm2M128),
-	/*2426*/ uint16(xMatch),
-	/*2427*/ uint16(xCondPrefix), 2,
-	0x66, 2439,
-	0x0, 2433,
-	/*2433*/ uint16(xSetOp), uint16(PSIGNB),
-	/*2435*/ uint16(xReadSlashR),
-	/*2436*/ uint16(xArgMm1),
-	/*2437*/ uint16(xArgMm2M64),
-	/*2438*/ uint16(xMatch),
-	/*2439*/ uint16(xSetOp), uint16(PSIGNB),
-	/*2441*/ uint16(xReadSlashR),
-	/*2442*/ uint16(xArgXmm1),
-	/*2443*/ uint16(xArgXmm2M128),
-	/*2444*/ uint16(xMatch),
-	/*2445*/ uint16(xCondPrefix), 2,
-	0x66, 2457,
-	0x0, 2451,
-	/*2451*/ uint16(xSetOp), uint16(PSIGNW),
-	/*2453*/ uint16(xReadSlashR),
-	/*2454*/ uint16(xArgMm1),
-	/*2455*/ uint16(xArgMm2M64),
-	/*2456*/ uint16(xMatch),
-	/*2457*/ uint16(xSetOp), uint16(PSIGNW),
-	/*2459*/ uint16(xReadSlashR),
-	/*2460*/ uint16(xArgXmm1),
-	/*2461*/ uint16(xArgXmm2M128),
-	/*2462*/ uint16(xMatch),
-	/*2463*/ uint16(xCondPrefix), 2,
-	0x66, 2475,
-	0x0, 2469,
-	/*2469*/ uint16(xSetOp), uint16(PSIGND),
-	/*2471*/ uint16(xReadSlashR),
-	/*2472*/ uint16(xArgMm1),
-	/*2473*/ uint16(xArgMm2M64),
-	/*2474*/ uint16(xMatch),
-	/*2475*/ uint16(xSetOp), uint16(PSIGND),
-	/*2477*/ uint16(xReadSlashR),
-	/*2478*/ uint16(xArgXmm1),
-	/*2479*/ uint16(xArgXmm2M128),
-	/*2480*/ uint16(xMatch),
-	/*2481*/ uint16(xCondPrefix), 2,
-	0x66, 2493,
-	0x0, 2487,
-	/*2487*/ uint16(xSetOp), uint16(PMULHRSW),
-	/*2489*/ uint16(xReadSlashR),
-	/*2490*/ uint16(xArgMm1),
-	/*2491*/ uint16(xArgMm2M64),
-	/*2492*/ uint16(xMatch),
-	/*2493*/ uint16(xSetOp), uint16(PMULHRSW),
-	/*2495*/ uint16(xReadSlashR),
-	/*2496*/ uint16(xArgXmm1),
-	/*2497*/ uint16(xArgXmm2M128),
-	/*2498*/ uint16(xMatch),
-	/*2499*/ uint16(xCondPrefix), 1,
-	0x66, 2503,
-	/*2503*/ uint16(xSetOp), uint16(PBLENDVB),
-	/*2505*/ uint16(xReadSlashR),
-	/*2506*/ uint16(xArgXmm1),
-	/*2507*/ uint16(xArgXmm2M128),
-	/*2508*/ uint16(xArgXMM0),
-	/*2509*/ uint16(xMatch),
-	/*2510*/ uint16(xCondPrefix), 1,
-	0x66, 2514,
-	/*2514*/ uint16(xSetOp), uint16(BLENDVPS),
-	/*2516*/ uint16(xReadSlashR),
-	/*2517*/ uint16(xArgXmm1),
-	/*2518*/ uint16(xArgXmm2M128),
-	/*2519*/ uint16(xArgXMM0),
-	/*2520*/ uint16(xMatch),
-	/*2521*/ uint16(xCondPrefix), 1,
-	0x66, 2525,
-	/*2525*/ uint16(xSetOp), uint16(BLENDVPD),
-	/*2527*/ uint16(xReadSlashR),
-	/*2528*/ uint16(xArgXmm1),
-	/*2529*/ uint16(xArgXmm2M128),
-	/*2530*/ uint16(xArgXMM0),
-	/*2531*/ uint16(xMatch),
-	/*2532*/ uint16(xCondPrefix), 1,
-	0x66, 2536,
-	/*2536*/ uint16(xSetOp), uint16(PTEST),
-	/*2538*/ uint16(xReadSlashR),
-	/*2539*/ uint16(xArgXmm1),
-	/*2540*/ uint16(xArgXmm2M128),
-	/*2541*/ uint16(xMatch),
-	/*2542*/ uint16(xCondPrefix), 2,
-	0x66, 2554,
-	0x0, 2548,
-	/*2548*/ uint16(xSetOp), uint16(PABSB),
-	/*2550*/ uint16(xReadSlashR),
-	/*2551*/ uint16(xArgMm1),
-	/*2552*/ uint16(xArgMm2M64),
-	/*2553*/ uint16(xMatch),
-	/*2554*/ uint16(xSetOp), uint16(PABSB),
-	/*2556*/ uint16(xReadSlashR),
-	/*2557*/ uint16(xArgXmm1),
-	/*2558*/ uint16(xArgXmm2M128),
-	/*2559*/ uint16(xMatch),
-	/*2560*/ uint16(xCondPrefix), 2,
-	0x66, 2572,
-	0x0, 2566,
-	/*2566*/ uint16(xSetOp), uint16(PABSW),
-	/*2568*/ uint16(xReadSlashR),
-	/*2569*/ uint16(xArgMm1),
-	/*2570*/ uint16(xArgMm2M64),
-	/*2571*/ uint16(xMatch),
-	/*2572*/ uint16(xSetOp), uint16(PABSW),
-	/*2574*/ uint16(xReadSlashR),
-	/*2575*/ uint16(xArgXmm1),
-	/*2576*/ uint16(xArgXmm2M128),
-	/*2577*/ uint16(xMatch),
-	/*2578*/ uint16(xCondPrefix), 2,
-	0x66, 2590,
-	0x0, 2584,
-	/*2584*/ uint16(xSetOp), uint16(PABSD),
-	/*2586*/ uint16(xReadSlashR),
-	/*2587*/ uint16(xArgMm1),
-	/*2588*/ uint16(xArgMm2M64),
-	/*2589*/ uint16(xMatch),
-	/*2590*/ uint16(xSetOp), uint16(PABSD),
-	/*2592*/ uint16(xReadSlashR),
-	/*2593*/ uint16(xArgXmm1),
-	/*2594*/ uint16(xArgXmm2M128),
-	/*2595*/ uint16(xMatch),
-	/*2596*/ uint16(xCondPrefix), 1,
-	0x66, 2600,
-	/*2600*/ uint16(xSetOp), uint16(PMOVSXBW),
-	/*2602*/ uint16(xReadSlashR),
-	/*2603*/ uint16(xArgXmm1),
-	/*2604*/ uint16(xArgXmm2M64),
-	/*2605*/ uint16(xMatch),
-	/*2606*/ uint16(xCondPrefix), 1,
-	0x66, 2610,
-	/*2610*/ uint16(xSetOp), uint16(PMOVSXBD),
-	/*2612*/ uint16(xReadSlashR),
-	/*2613*/ uint16(xArgXmm1),
-	/*2614*/ uint16(xArgXmm2M32),
-	/*2615*/ uint16(xMatch),
-	/*2616*/ uint16(xCondPrefix), 1,
-	0x66, 2620,
-	/*2620*/ uint16(xSetOp), uint16(PMOVSXBQ),
-	/*2622*/ uint16(xReadSlashR),
-	/*2623*/ uint16(xArgXmm1),
-	/*2624*/ uint16(xArgXmm2M16),
-	/*2625*/ uint16(xMatch),
-	/*2626*/ uint16(xCondPrefix), 1,
-	0x66, 2630,
-	/*2630*/ uint16(xSetOp), uint16(PMOVSXWD),
-	/*2632*/ uint16(xReadSlashR),
-	/*2633*/ uint16(xArgXmm1),
-	/*2634*/ uint16(xArgXmm2M64),
-	/*2635*/ uint16(xMatch),
-	/*2636*/ uint16(xCondPrefix), 1,
-	0x66, 2640,
-	/*2640*/ uint16(xSetOp), uint16(PMOVSXWQ),
-	/*2642*/ uint16(xReadSlashR),
-	/*2643*/ uint16(xArgXmm1),
-	/*2644*/ uint16(xArgXmm2M32),
-	/*2645*/ uint16(xMatch),
-	/*2646*/ uint16(xCondPrefix), 1,
-	0x66, 2650,
-	/*2650*/ uint16(xSetOp), uint16(PMOVSXDQ),
-	/*2652*/ uint16(xReadSlashR),
-	/*2653*/ uint16(xArgXmm1),
-	/*2654*/ uint16(xArgXmm2M64),
-	/*2655*/ uint16(xMatch),
-	/*2656*/ uint16(xCondPrefix), 1,
-	0x66, 2660,
-	/*2660*/ uint16(xSetOp), uint16(PMULDQ),
-	/*2662*/ uint16(xReadSlashR),
-	/*2663*/ uint16(xArgXmm1),
-	/*2664*/ uint16(xArgXmm2M128),
-	/*2665*/ uint16(xMatch),
-	/*2666*/ uint16(xCondPrefix), 1,
-	0x66, 2670,
-	/*2670*/ uint16(xSetOp), uint16(PCMPEQQ),
-	/*2672*/ uint16(xReadSlashR),
-	/*2673*/ uint16(xArgXmm1),
-	/*2674*/ uint16(xArgXmm2M128),
-	/*2675*/ uint16(xMatch),
-	/*2676*/ uint16(xCondPrefix), 1,
-	0x66, 2680,
-	/*2680*/ uint16(xSetOp), uint16(MOVNTDQA),
-	/*2682*/ uint16(xReadSlashR),
-	/*2683*/ uint16(xArgXmm1),
-	/*2684*/ uint16(xArgM128),
-	/*2685*/ uint16(xMatch),
-	/*2686*/ uint16(xCondPrefix), 1,
-	0x66, 2690,
-	/*2690*/ uint16(xSetOp), uint16(PACKUSDW),
-	/*2692*/ uint16(xReadSlashR),
-	/*2693*/ uint16(xArgXmm1),
-	/*2694*/ uint16(xArgXmm2M128),
-	/*2695*/ uint16(xMatch),
-	/*2696*/ uint16(xCondPrefix), 1,
-	0x66, 2700,
-	/*2700*/ uint16(xSetOp), uint16(PMOVZXBW),
-	/*2702*/ uint16(xReadSlashR),
-	/*2703*/ uint16(xArgXmm1),
-	/*2704*/ uint16(xArgXmm2M64),
-	/*2705*/ uint16(xMatch),
-	/*2706*/ uint16(xCondPrefix), 1,
-	0x66, 2710,
-	/*2710*/ uint16(xSetOp), uint16(PMOVZXBD),
-	/*2712*/ uint16(xReadSlashR),
-	/*2713*/ uint16(xArgXmm1),
-	/*2714*/ uint16(xArgXmm2M32),
-	/*2715*/ uint16(xMatch),
-	/*2716*/ uint16(xCondPrefix), 1,
-	0x66, 2720,
-	/*2720*/ uint16(xSetOp), uint16(PMOVZXBQ),
-	/*2722*/ uint16(xReadSlashR),
-	/*2723*/ uint16(xArgXmm1),
-	/*2724*/ uint16(xArgXmm2M16),
-	/*2725*/ uint16(xMatch),
-	/*2726*/ uint16(xCondPrefix), 1,
-	0x66, 2730,
-	/*2730*/ uint16(xSetOp), uint16(PMOVZXWD),
-	/*2732*/ uint16(xReadSlashR),
-	/*2733*/ uint16(xArgXmm1),
-	/*2734*/ uint16(xArgXmm2M64),
-	/*2735*/ uint16(xMatch),
-	/*2736*/ uint16(xCondPrefix), 1,
-	0x66, 2740,
-	/*2740*/ uint16(xSetOp), uint16(PMOVZXWQ),
-	/*2742*/ uint16(xReadSlashR),
-	/*2743*/ uint16(xArgXmm1),
-	/*2744*/ uint16(xArgXmm2M32),
-	/*2745*/ uint16(xMatch),
-	/*2746*/ uint16(xCondPrefix), 1,
-	0x66, 2750,
-	/*2750*/ uint16(xSetOp), uint16(PMOVZXDQ),
-	/*2752*/ uint16(xReadSlashR),
-	/*2753*/ uint16(xArgXmm1),
-	/*2754*/ uint16(xArgXmm2M64),
-	/*2755*/ uint16(xMatch),
-	/*2756*/ uint16(xCondPrefix), 1,
-	0x66, 2760,
-	/*2760*/ uint16(xSetOp), uint16(PCMPGTQ),
-	/*2762*/ uint16(xReadSlashR),
-	/*2763*/ uint16(xArgXmm1),
-	/*2764*/ uint16(xArgXmm2M128),
-	/*2765*/ uint16(xMatch),
-	/*2766*/ uint16(xCondPrefix), 1,
-	0x66, 2770,
-	/*2770*/ uint16(xSetOp), uint16(PMINSB),
-	/*2772*/ uint16(xReadSlashR),
-	/*2773*/ uint16(xArgXmm1),
-	/*2774*/ uint16(xArgXmm2M128),
-	/*2775*/ uint16(xMatch),
-	/*2776*/ uint16(xCondPrefix), 1,
-	0x66, 2780,
-	/*2780*/ uint16(xSetOp), uint16(PMINSD),
-	/*2782*/ uint16(xReadSlashR),
-	/*2783*/ uint16(xArgXmm1),
-	/*2784*/ uint16(xArgXmm2M128),
-	/*2785*/ uint16(xMatch),
-	/*2786*/ uint16(xCondPrefix), 1,
-	0x66, 2790,
-	/*2790*/ uint16(xSetOp), uint16(PMINUW),
-	/*2792*/ uint16(xReadSlashR),
-	/*2793*/ uint16(xArgXmm1),
-	/*2794*/ uint16(xArgXmm2M128),
-	/*2795*/ uint16(xMatch),
-	/*2796*/ uint16(xCondPrefix), 1,
-	0x66, 2800,
-	/*2800*/ uint16(xSetOp), uint16(PMINUD),
-	/*2802*/ uint16(xReadSlashR),
-	/*2803*/ uint16(xArgXmm1),
-	/*2804*/ uint16(xArgXmm2M128),
-	/*2805*/ uint16(xMatch),
-	/*2806*/ uint16(xCondPrefix), 1,
-	0x66, 2810,
-	/*2810*/ uint16(xSetOp), uint16(PMAXSB),
-	/*2812*/ uint16(xReadSlashR),
-	/*2813*/ uint16(xArgXmm1),
-	/*2814*/ uint16(xArgXmm2M128),
-	/*2815*/ uint16(xMatch),
-	/*2816*/ uint16(xCondPrefix), 1,
-	0x66, 2820,
-	/*2820*/ uint16(xSetOp), uint16(PMAXSD),
-	/*2822*/ uint16(xReadSlashR),
-	/*2823*/ uint16(xArgXmm1),
-	/*2824*/ uint16(xArgXmm2M128),
-	/*2825*/ uint16(xMatch),
-	/*2826*/ uint16(xCondPrefix), 1,
-	0x66, 2830,
-	/*2830*/ uint16(xSetOp), uint16(PMAXUW),
-	/*2832*/ uint16(xReadSlashR),
-	/*2833*/ uint16(xArgXmm1),
-	/*2834*/ uint16(xArgXmm2M128),
-	/*2835*/ uint16(xMatch),
-	/*2836*/ uint16(xCondPrefix), 1,
-	0x66, 2840,
-	/*2840*/ uint16(xSetOp), uint16(PMAXUD),
-	/*2842*/ uint16(xReadSlashR),
-	/*2843*/ uint16(xArgXmm1),
-	/*2844*/ uint16(xArgXmm2M128),
-	/*2845*/ uint16(xMatch),
-	/*2846*/ uint16(xCondPrefix), 1,
-	0x66, 2850,
-	/*2850*/ uint16(xSetOp), uint16(PMULLD),
-	/*2852*/ uint16(xReadSlashR),
-	/*2853*/ uint16(xArgXmm1),
-	/*2854*/ uint16(xArgXmm2M128),
-	/*2855*/ uint16(xMatch),
-	/*2856*/ uint16(xCondPrefix), 1,
-	0x66, 2860,
-	/*2860*/ uint16(xSetOp), uint16(PHMINPOSUW),
-	/*2862*/ uint16(xReadSlashR),
-	/*2863*/ uint16(xArgXmm1),
-	/*2864*/ uint16(xArgXmm2M128),
-	/*2865*/ uint16(xMatch),
-	/*2866*/ uint16(xCondIs64), 2869, 2879,
-	/*2869*/ uint16(xCondPrefix), 1,
-	0x66, 2873,
-	/*2873*/ uint16(xSetOp), uint16(INVPCID),
-	/*2875*/ uint16(xReadSlashR),
-	/*2876*/ uint16(xArgR32),
-	/*2877*/ uint16(xArgM128),
-	/*2878*/ uint16(xMatch),
-	/*2879*/ uint16(xCondPrefix), 1,
-	0x66, 2883,
-	/*2883*/ uint16(xSetOp), uint16(INVPCID),
-	/*2885*/ uint16(xReadSlashR),
-	/*2886*/ uint16(xArgR64),
-	/*2887*/ uint16(xArgM128),
-	/*2888*/ uint16(xMatch),
-	/*2889*/ uint16(xCondPrefix), 1,
-	0x66, 2893,
-	/*2893*/ uint16(xSetOp), uint16(AESIMC),
-	/*2895*/ uint16(xReadSlashR),
-	/*2896*/ uint16(xArgXmm1),
-	/*2897*/ uint16(xArgXmm2M128),
-	/*2898*/ uint16(xMatch),
-	/*2899*/ uint16(xCondPrefix), 1,
-	0x66, 2903,
-	/*2903*/ uint16(xSetOp), uint16(AESENC),
-	/*2905*/ uint16(xReadSlashR),
-	/*2906*/ uint16(xArgXmm1),
-	/*2907*/ uint16(xArgXmm2M128),
-	/*2908*/ uint16(xMatch),
-	/*2909*/ uint16(xCondPrefix), 1,
-	0x66, 2913,
-	/*2913*/ uint16(xSetOp), uint16(AESENCLAST),
-	/*2915*/ uint16(xReadSlashR),
-	/*2916*/ uint16(xArgXmm1),
-	/*2917*/ uint16(xArgXmm2M128),
-	/*2918*/ uint16(xMatch),
-	/*2919*/ uint16(xCondPrefix), 1,
-	0x66, 2923,
-	/*2923*/ uint16(xSetOp), uint16(AESDEC),
-	/*2925*/ uint16(xReadSlashR),
-	/*2926*/ uint16(xArgXmm1),
-	/*2927*/ uint16(xArgXmm2M128),
-	/*2928*/ uint16(xMatch),
-	/*2929*/ uint16(xCondPrefix), 1,
-	0x66, 2933,
-	/*2933*/ uint16(xSetOp), uint16(AESDECLAST),
-	/*2935*/ uint16(xReadSlashR),
-	/*2936*/ uint16(xArgXmm1),
-	/*2937*/ uint16(xArgXmm2M128),
-	/*2938*/ uint16(xMatch),
-	/*2939*/ uint16(xCondIs64), 2942, 2980,
-	/*2942*/ uint16(xCondPrefix), 2,
-	0xF2, 2964,
-	0x0, 2948,
-	/*2948*/ uint16(xCondDataSize), 2952, 2958, 0,
-	/*2952*/ uint16(xSetOp), uint16(MOVBE),
-	/*2954*/ uint16(xReadSlashR),
-	/*2955*/ uint16(xArgR16),
-	/*2956*/ uint16(xArgM16),
-	/*2957*/ uint16(xMatch),
-	/*2958*/ uint16(xSetOp), uint16(MOVBE),
-	/*2960*/ uint16(xReadSlashR),
-	/*2961*/ uint16(xArgR32),
-	/*2962*/ uint16(xArgM32),
-	/*2963*/ uint16(xMatch),
-	/*2964*/ uint16(xCondDataSize), 2968, 2974, 0,
-	/*2968*/ uint16(xSetOp), uint16(CRC32),
-	/*2970*/ uint16(xReadSlashR),
-	/*2971*/ uint16(xArgR32),
-	/*2972*/ uint16(xArgRM8),
-	/*2973*/ uint16(xMatch),
-	/*2974*/ uint16(xSetOp), uint16(CRC32),
-	/*2976*/ uint16(xReadSlashR),
-	/*2977*/ uint16(xArgR32),
-	/*2978*/ uint16(xArgRM8),
-	/*2979*/ uint16(xMatch),
-	/*2980*/ uint16(xCondPrefix), 2,
-	0xF2, 2996,
-	0x0, 2986,
-	/*2986*/ uint16(xCondDataSize), 2952, 2958, 2990,
-	/*2990*/ uint16(xSetOp), uint16(MOVBE),
-	/*2992*/ uint16(xReadSlashR),
-	/*2993*/ uint16(xArgR64),
-	/*2994*/ uint16(xArgM64),
-	/*2995*/ uint16(xMatch),
-	/*2996*/ uint16(xCondDataSize), 2968, 2974, 3000,
-	/*3000*/ uint16(xSetOp), uint16(CRC32),
-	/*3002*/ uint16(xReadSlashR),
-	/*3003*/ uint16(xArgR64),
-	/*3004*/ uint16(xArgRM8),
-	/*3005*/ uint16(xMatch),
-	/*3006*/ uint16(xCondIs64), 3009, 3047,
-	/*3009*/ uint16(xCondPrefix), 2,
-	0xF2, 3031,
-	0x0, 3015,
-	/*3015*/ uint16(xCondDataSize), 3019, 3025, 0,
-	/*3019*/ uint16(xSetOp), uint16(MOVBE),
-	/*3021*/ uint16(xReadSlashR),
-	/*3022*/ uint16(xArgM16),
-	/*3023*/ uint16(xArgR16),
-	/*3024*/ uint16(xMatch),
-	/*3025*/ uint16(xSetOp), uint16(MOVBE),
-	/*3027*/ uint16(xReadSlashR),
-	/*3028*/ uint16(xArgM32),
-	/*3029*/ uint16(xArgR32),
-	/*3030*/ uint16(xMatch),
-	/*3031*/ uint16(xCondDataSize), 3035, 3041, 0,
-	/*3035*/ uint16(xSetOp), uint16(CRC32),
-	/*3037*/ uint16(xReadSlashR),
-	/*3038*/ uint16(xArgR32),
-	/*3039*/ uint16(xArgRM16),
-	/*3040*/ uint16(xMatch),
-	/*3041*/ uint16(xSetOp), uint16(CRC32),
-	/*3043*/ uint16(xReadSlashR),
-	/*3044*/ uint16(xArgR32),
-	/*3045*/ uint16(xArgRM32),
-	/*3046*/ uint16(xMatch),
-	/*3047*/ uint16(xCondPrefix), 2,
-	0xF2, 3063,
-	0x0, 3053,
-	/*3053*/ uint16(xCondDataSize), 3019, 3025, 3057,
-	/*3057*/ uint16(xSetOp), uint16(MOVBE),
-	/*3059*/ uint16(xReadSlashR),
-	/*3060*/ uint16(xArgM64),
-	/*3061*/ uint16(xArgR64),
-	/*3062*/ uint16(xMatch),
-	/*3063*/ uint16(xCondDataSize), 3035, 3041, 3067,
-	/*3067*/ uint16(xSetOp), uint16(CRC32),
-	/*3069*/ uint16(xReadSlashR),
-	/*3070*/ uint16(xArgR64),
-	/*3071*/ uint16(xArgRM64),
-	/*3072*/ uint16(xMatch),
-	/*3073*/ uint16(xCondByte), 24,
-	0x08, 3124,
-	0x09, 3136,
-	0x0A, 3148,
-	0x0B, 3160,
-	0x0C, 3172,
-	0x0D, 3184,
-	0x0E, 3196,
-	0x0F, 3208,
-	0x14, 3230,
-	0x15, 3242,
-	0x16, 3254,
-	0x17, 3297,
-	0x20, 3309,
-	0x21, 3321,
-	0x22, 3333,
-	0x40, 3376,
-	0x41, 3388,
-	0x42, 3400,
-	0x44, 3412,
-	0x60, 3424,
-	0x61, 3436,
-	0x62, 3448,
-	0x63, 3460,
-	0xDF, 3472,
+	/*2285*/ uint16(xCondPrefix), 2,
+	0x66, 2297,
+	0x0, 2291,
+	/*2291*/ uint16(xSetOp), uint16(PSHUFB),
+	/*2293*/ uint16(xReadSlashR),
+	/*2294*/ uint16(xArgMm1),
+	/*2295*/ uint16(xArgMm2M64),
+	/*2296*/ uint16(xMatch),
+	/*2297*/ uint16(xSetOp), uint16(PSHUFB),
+	/*2299*/ uint16(xReadSlashR),
+	/*2300*/ uint16(xArgXmm1),
+	/*2301*/ uint16(xArgXmm2M128),
+	/*2302*/ uint16(xMatch),
+	/*2303*/ uint16(xCondPrefix), 2,
+	0x66, 2315,
+	0x0, 2309,
+	/*2309*/ uint16(xSetOp), uint16(PHADDW),
+	/*2311*/ uint16(xReadSlashR),
+	/*2312*/ uint16(xArgMm1),
+	/*2313*/ uint16(xArgMm2M64),
+	/*2314*/ uint16(xMatch),
+	/*2315*/ uint16(xSetOp), uint16(PHADDW),
+	/*2317*/ uint16(xReadSlashR),
+	/*2318*/ uint16(xArgXmm1),
+	/*2319*/ uint16(xArgXmm2M128),
+	/*2320*/ uint16(xMatch),
+	/*2321*/ uint16(xCondPrefix), 2,
+	0x66, 2333,
+	0x0, 2327,
+	/*2327*/ uint16(xSetOp), uint16(PHADDD),
+	/*2329*/ uint16(xReadSlashR),
+	/*2330*/ uint16(xArgMm1),
+	/*2331*/ uint16(xArgMm2M64),
+	/*2332*/ uint16(xMatch),
+	/*2333*/ uint16(xSetOp), uint16(PHADDD),
+	/*2335*/ uint16(xReadSlashR),
+	/*2336*/ uint16(xArgXmm1),
+	/*2337*/ uint16(xArgXmm2M128),
+	/*2338*/ uint16(xMatch),
+	/*2339*/ uint16(xCondPrefix), 2,
+	0x66, 2351,
+	0x0, 2345,
+	/*2345*/ uint16(xSetOp), uint16(PHADDSW),
+	/*2347*/ uint16(xReadSlashR),
+	/*2348*/ uint16(xArgMm1),
+	/*2349*/ uint16(xArgMm2M64),
+	/*2350*/ uint16(xMatch),
+	/*2351*/ uint16(xSetOp), uint16(PHADDSW),
+	/*2353*/ uint16(xReadSlashR),
+	/*2354*/ uint16(xArgXmm1),
+	/*2355*/ uint16(xArgXmm2M128),
+	/*2356*/ uint16(xMatch),
+	/*2357*/ uint16(xCondPrefix), 2,
+	0x66, 2369,
+	0x0, 2363,
+	/*2363*/ uint16(xSetOp), uint16(PMADDUBSW),
+	/*2365*/ uint16(xReadSlashR),
+	/*2366*/ uint16(xArgMm1),
+	/*2367*/ uint16(xArgMm2M64),
+	/*2368*/ uint16(xMatch),
+	/*2369*/ uint16(xSetOp), uint16(PMADDUBSW),
+	/*2371*/ uint16(xReadSlashR),
+	/*2372*/ uint16(xArgXmm1),
+	/*2373*/ uint16(xArgXmm2M128),
+	/*2374*/ uint16(xMatch),
+	/*2375*/ uint16(xCondPrefix), 2,
+	0x66, 2387,
+	0x0, 2381,
+	/*2381*/ uint16(xSetOp), uint16(PHSUBW),
+	/*2383*/ uint16(xReadSlashR),
+	/*2384*/ uint16(xArgMm1),
+	/*2385*/ uint16(xArgMm2M64),
+	/*2386*/ uint16(xMatch),
+	/*2387*/ uint16(xSetOp), uint16(PHSUBW),
+	/*2389*/ uint16(xReadSlashR),
+	/*2390*/ uint16(xArgXmm1),
+	/*2391*/ uint16(xArgXmm2M128),
+	/*2392*/ uint16(xMatch),
+	/*2393*/ uint16(xCondPrefix), 2,
+	0x66, 2405,
+	0x0, 2399,
+	/*2399*/ uint16(xSetOp), uint16(PHSUBD),
+	/*2401*/ uint16(xReadSlashR),
+	/*2402*/ uint16(xArgMm1),
+	/*2403*/ uint16(xArgMm2M64),
+	/*2404*/ uint16(xMatch),
+	/*2405*/ uint16(xSetOp), uint16(PHSUBD),
+	/*2407*/ uint16(xReadSlashR),
+	/*2408*/ uint16(xArgXmm1),
+	/*2409*/ uint16(xArgXmm2M128),
+	/*2410*/ uint16(xMatch),
+	/*2411*/ uint16(xCondPrefix), 2,
+	0x66, 2423,
+	0x0, 2417,
+	/*2417*/ uint16(xSetOp), uint16(PHSUBSW),
+	/*2419*/ uint16(xReadSlashR),
+	/*2420*/ uint16(xArgMm1),
+	/*2421*/ uint16(xArgMm2M64),
+	/*2422*/ uint16(xMatch),
+	/*2423*/ uint16(xSetOp), uint16(PHSUBSW),
+	/*2425*/ uint16(xReadSlashR),
+	/*2426*/ uint16(xArgXmm1),
+	/*2427*/ uint16(xArgXmm2M128),
+	/*2428*/ uint16(xMatch),
+	/*2429*/ uint16(xCondPrefix), 2,
+	0x66, 2441,
+	0x0, 2435,
+	/*2435*/ uint16(xSetOp), uint16(PSIGNB),
+	/*2437*/ uint16(xReadSlashR),
+	/*2438*/ uint16(xArgMm1),
+	/*2439*/ uint16(xArgMm2M64),
+	/*2440*/ uint16(xMatch),
+	/*2441*/ uint16(xSetOp), uint16(PSIGNB),
+	/*2443*/ uint16(xReadSlashR),
+	/*2444*/ uint16(xArgXmm1),
+	/*2445*/ uint16(xArgXmm2M128),
+	/*2446*/ uint16(xMatch),
+	/*2447*/ uint16(xCondPrefix), 2,
+	0x66, 2459,
+	0x0, 2453,
+	/*2453*/ uint16(xSetOp), uint16(PSIGNW),
+	/*2455*/ uint16(xReadSlashR),
+	/*2456*/ uint16(xArgMm1),
+	/*2457*/ uint16(xArgMm2M64),
+	/*2458*/ uint16(xMatch),
+	/*2459*/ uint16(xSetOp), uint16(PSIGNW),
+	/*2461*/ uint16(xReadSlashR),
+	/*2462*/ uint16(xArgXmm1),
+	/*2463*/ uint16(xArgXmm2M128),
+	/*2464*/ uint16(xMatch),
+	/*2465*/ uint16(xCondPrefix), 2,
+	0x66, 2477,
+	0x0, 2471,
+	/*2471*/ uint16(xSetOp), uint16(PSIGND),
+	/*2473*/ uint16(xReadSlashR),
+	/*2474*/ uint16(xArgMm1),
+	/*2475*/ uint16(xArgMm2M64),
+	/*2476*/ uint16(xMatch),
+	/*2477*/ uint16(xSetOp), uint16(PSIGND),
+	/*2479*/ uint16(xReadSlashR),
+	/*2480*/ uint16(xArgXmm1),
+	/*2481*/ uint16(xArgXmm2M128),
+	/*2482*/ uint16(xMatch),
+	/*2483*/ uint16(xCondPrefix), 2,
+	0x66, 2495,
+	0x0, 2489,
+	/*2489*/ uint16(xSetOp), uint16(PMULHRSW),
+	/*2491*/ uint16(xReadSlashR),
+	/*2492*/ uint16(xArgMm1),
+	/*2493*/ uint16(xArgMm2M64),
+	/*2494*/ uint16(xMatch),
+	/*2495*/ uint16(xSetOp), uint16(PMULHRSW),
+	/*2497*/ uint16(xReadSlashR),
+	/*2498*/ uint16(xArgXmm1),
+	/*2499*/ uint16(xArgXmm2M128),
+	/*2500*/ uint16(xMatch),
+	/*2501*/ uint16(xCondPrefix), 1,
+	0x66, 2505,
+	/*2505*/ uint16(xSetOp), uint16(PBLENDVB),
+	/*2507*/ uint16(xReadSlashR),
+	/*2508*/ uint16(xArgXmm1),
+	/*2509*/ uint16(xArgXmm2M128),
+	/*2510*/ uint16(xArgXMM0),
+	/*2511*/ uint16(xMatch),
+	/*2512*/ uint16(xCondPrefix), 1,
+	0x66, 2516,
+	/*2516*/ uint16(xSetOp), uint16(BLENDVPS),
+	/*2518*/ uint16(xReadSlashR),
+	/*2519*/ uint16(xArgXmm1),
+	/*2520*/ uint16(xArgXmm2M128),
+	/*2521*/ uint16(xArgXMM0),
+	/*2522*/ uint16(xMatch),
+	/*2523*/ uint16(xCondPrefix), 1,
+	0x66, 2527,
+	/*2527*/ uint16(xSetOp), uint16(BLENDVPD),
+	/*2529*/ uint16(xReadSlashR),
+	/*2530*/ uint16(xArgXmm1),
+	/*2531*/ uint16(xArgXmm2M128),
+	/*2532*/ uint16(xArgXMM0),
+	/*2533*/ uint16(xMatch),
+	/*2534*/ uint16(xCondPrefix), 1,
+	0x66, 2538,
+	/*2538*/ uint16(xSetOp), uint16(PTEST),
+	/*2540*/ uint16(xReadSlashR),
+	/*2541*/ uint16(xArgXmm1),
+	/*2542*/ uint16(xArgXmm2M128),
+	/*2543*/ uint16(xMatch),
+	/*2544*/ uint16(xCondPrefix), 2,
+	0x66, 2556,
+	0x0, 2550,
+	/*2550*/ uint16(xSetOp), uint16(PABSB),
+	/*2552*/ uint16(xReadSlashR),
+	/*2553*/ uint16(xArgMm1),
+	/*2554*/ uint16(xArgMm2M64),
+	/*2555*/ uint16(xMatch),
+	/*2556*/ uint16(xSetOp), uint16(PABSB),
+	/*2558*/ uint16(xReadSlashR),
+	/*2559*/ uint16(xArgXmm1),
+	/*2560*/ uint16(xArgXmm2M128),
+	/*2561*/ uint16(xMatch),
+	/*2562*/ uint16(xCondPrefix), 2,
+	0x66, 2574,
+	0x0, 2568,
+	/*2568*/ uint16(xSetOp), uint16(PABSW),
+	/*2570*/ uint16(xReadSlashR),
+	/*2571*/ uint16(xArgMm1),
+	/*2572*/ uint16(xArgMm2M64),
+	/*2573*/ uint16(xMatch),
+	/*2574*/ uint16(xSetOp), uint16(PABSW),
+	/*2576*/ uint16(xReadSlashR),
+	/*2577*/ uint16(xArgXmm1),
+	/*2578*/ uint16(xArgXmm2M128),
+	/*2579*/ uint16(xMatch),
+	/*2580*/ uint16(xCondPrefix), 2,
+	0x66, 2592,
+	0x0, 2586,
+	/*2586*/ uint16(xSetOp), uint16(PABSD),
+	/*2588*/ uint16(xReadSlashR),
+	/*2589*/ uint16(xArgMm1),
+	/*2590*/ uint16(xArgMm2M64),
+	/*2591*/ uint16(xMatch),
+	/*2592*/ uint16(xSetOp), uint16(PABSD),
+	/*2594*/ uint16(xReadSlashR),
+	/*2595*/ uint16(xArgXmm1),
+	/*2596*/ uint16(xArgXmm2M128),
+	/*2597*/ uint16(xMatch),
+	/*2598*/ uint16(xCondPrefix), 1,
+	0x66, 2602,
+	/*2602*/ uint16(xSetOp), uint16(PMOVSXBW),
+	/*2604*/ uint16(xReadSlashR),
+	/*2605*/ uint16(xArgXmm1),
+	/*2606*/ uint16(xArgXmm2M64),
+	/*2607*/ uint16(xMatch),
+	/*2608*/ uint16(xCondPrefix), 1,
+	0x66, 2612,
+	/*2612*/ uint16(xSetOp), uint16(PMOVSXBD),
+	/*2614*/ uint16(xReadSlashR),
+	/*2615*/ uint16(xArgXmm1),
+	/*2616*/ uint16(xArgXmm2M32),
+	/*2617*/ uint16(xMatch),
+	/*2618*/ uint16(xCondPrefix), 1,
+	0x66, 2622,
+	/*2622*/ uint16(xSetOp), uint16(PMOVSXBQ),
+	/*2624*/ uint16(xReadSlashR),
+	/*2625*/ uint16(xArgXmm1),
+	/*2626*/ uint16(xArgXmm2M16),
+	/*2627*/ uint16(xMatch),
+	/*2628*/ uint16(xCondPrefix), 1,
+	0x66, 2632,
+	/*2632*/ uint16(xSetOp), uint16(PMOVSXWD),
+	/*2634*/ uint16(xReadSlashR),
+	/*2635*/ uint16(xArgXmm1),
+	/*2636*/ uint16(xArgXmm2M64),
+	/*2637*/ uint16(xMatch),
+	/*2638*/ uint16(xCondPrefix), 1,
+	0x66, 2642,
+	/*2642*/ uint16(xSetOp), uint16(PMOVSXWQ),
+	/*2644*/ uint16(xReadSlashR),
+	/*2645*/ uint16(xArgXmm1),
+	/*2646*/ uint16(xArgXmm2M32),
+	/*2647*/ uint16(xMatch),
+	/*2648*/ uint16(xCondPrefix), 1,
+	0x66, 2652,
+	/*2652*/ uint16(xSetOp), uint16(PMOVSXDQ),
+	/*2654*/ uint16(xReadSlashR),
+	/*2655*/ uint16(xArgXmm1),
+	/*2656*/ uint16(xArgXmm2M64),
+	/*2657*/ uint16(xMatch),
+	/*2658*/ uint16(xCondPrefix), 1,
+	0x66, 2662,
+	/*2662*/ uint16(xSetOp), uint16(PMULDQ),
+	/*2664*/ uint16(xReadSlashR),
+	/*2665*/ uint16(xArgXmm1),
+	/*2666*/ uint16(xArgXmm2M128),
+	/*2667*/ uint16(xMatch),
+	/*2668*/ uint16(xCondPrefix), 1,
+	0x66, 2672,
+	/*2672*/ uint16(xSetOp), uint16(PCMPEQQ),
+	/*2674*/ uint16(xReadSlashR),
+	/*2675*/ uint16(xArgXmm1),
+	/*2676*/ uint16(xArgXmm2M128),
+	/*2677*/ uint16(xMatch),
+	/*2678*/ uint16(xCondPrefix), 1,
+	0x66, 2682,
+	/*2682*/ uint16(xSetOp), uint16(MOVNTDQA),
+	/*2684*/ uint16(xReadSlashR),
+	/*2685*/ uint16(xArgXmm1),
+	/*2686*/ uint16(xArgM128),
+	/*2687*/ uint16(xMatch),
+	/*2688*/ uint16(xCondPrefix), 1,
+	0x66, 2692,
+	/*2692*/ uint16(xSetOp), uint16(PACKUSDW),
+	/*2694*/ uint16(xReadSlashR),
+	/*2695*/ uint16(xArgXmm1),
+	/*2696*/ uint16(xArgXmm2M128),
+	/*2697*/ uint16(xMatch),
+	/*2698*/ uint16(xCondPrefix), 1,
+	0x66, 2702,
+	/*2702*/ uint16(xSetOp), uint16(PMOVZXBW),
+	/*2704*/ uint16(xReadSlashR),
+	/*2705*/ uint16(xArgXmm1),
+	/*2706*/ uint16(xArgXmm2M64),
+	/*2707*/ uint16(xMatch),
+	/*2708*/ uint16(xCondPrefix), 1,
+	0x66, 2712,
+	/*2712*/ uint16(xSetOp), uint16(PMOVZXBD),
+	/*2714*/ uint16(xReadSlashR),
+	/*2715*/ uint16(xArgXmm1),
+	/*2716*/ uint16(xArgXmm2M32),
+	/*2717*/ uint16(xMatch),
+	/*2718*/ uint16(xCondPrefix), 1,
+	0x66, 2722,
+	/*2722*/ uint16(xSetOp), uint16(PMOVZXBQ),
+	/*2724*/ uint16(xReadSlashR),
+	/*2725*/ uint16(xArgXmm1),
+	/*2726*/ uint16(xArgXmm2M16),
+	/*2727*/ uint16(xMatch),
+	/*2728*/ uint16(xCondPrefix), 1,
+	0x66, 2732,
+	/*2732*/ uint16(xSetOp), uint16(PMOVZXWD),
+	/*2734*/ uint16(xReadSlashR),
+	/*2735*/ uint16(xArgXmm1),
+	/*2736*/ uint16(xArgXmm2M64),
+	/*2737*/ uint16(xMatch),
+	/*2738*/ uint16(xCondPrefix), 1,
+	0x66, 2742,
+	/*2742*/ uint16(xSetOp), uint16(PMOVZXWQ),
+	/*2744*/ uint16(xReadSlashR),
+	/*2745*/ uint16(xArgXmm1),
+	/*2746*/ uint16(xArgXmm2M32),
+	/*2747*/ uint16(xMatch),
+	/*2748*/ uint16(xCondPrefix), 1,
+	0x66, 2752,
+	/*2752*/ uint16(xSetOp), uint16(PMOVZXDQ),
+	/*2754*/ uint16(xReadSlashR),
+	/*2755*/ uint16(xArgXmm1),
+	/*2756*/ uint16(xArgXmm2M64),
+	/*2757*/ uint16(xMatch),
+	/*2758*/ uint16(xCondPrefix), 1,
+	0x66, 2762,
+	/*2762*/ uint16(xSetOp), uint16(PCMPGTQ),
+	/*2764*/ uint16(xReadSlashR),
+	/*2765*/ uint16(xArgXmm1),
+	/*2766*/ uint16(xArgXmm2M128),
+	/*2767*/ uint16(xMatch),
+	/*2768*/ uint16(xCondPrefix), 1,
+	0x66, 2772,
+	/*2772*/ uint16(xSetOp), uint16(PMINSB),
+	/*2774*/ uint16(xReadSlashR),
+	/*2775*/ uint16(xArgXmm1),
+	/*2776*/ uint16(xArgXmm2M128),
+	/*2777*/ uint16(xMatch),
+	/*2778*/ uint16(xCondPrefix), 1,
+	0x66, 2782,
+	/*2782*/ uint16(xSetOp), uint16(PMINSD),
+	/*2784*/ uint16(xReadSlashR),
+	/*2785*/ uint16(xArgXmm1),
+	/*2786*/ uint16(xArgXmm2M128),
+	/*2787*/ uint16(xMatch),
+	/*2788*/ uint16(xCondPrefix), 1,
+	0x66, 2792,
+	/*2792*/ uint16(xSetOp), uint16(PMINUW),
+	/*2794*/ uint16(xReadSlashR),
+	/*2795*/ uint16(xArgXmm1),
+	/*2796*/ uint16(xArgXmm2M128),
+	/*2797*/ uint16(xMatch),
+	/*2798*/ uint16(xCondPrefix), 1,
+	0x66, 2802,
+	/*2802*/ uint16(xSetOp), uint16(PMINUD),
+	/*2804*/ uint16(xReadSlashR),
+	/*2805*/ uint16(xArgXmm1),
+	/*2806*/ uint16(xArgXmm2M128),
+	/*2807*/ uint16(xMatch),
+	/*2808*/ uint16(xCondPrefix), 1,
+	0x66, 2812,
+	/*2812*/ uint16(xSetOp), uint16(PMAXSB),
+	/*2814*/ uint16(xReadSlashR),
+	/*2815*/ uint16(xArgXmm1),
+	/*2816*/ uint16(xArgXmm2M128),
+	/*2817*/ uint16(xMatch),
+	/*2818*/ uint16(xCondPrefix), 1,
+	0x66, 2822,
+	/*2822*/ uint16(xSetOp), uint16(PMAXSD),
+	/*2824*/ uint16(xReadSlashR),
+	/*2825*/ uint16(xArgXmm1),
+	/*2826*/ uint16(xArgXmm2M128),
+	/*2827*/ uint16(xMatch),
+	/*2828*/ uint16(xCondPrefix), 1,
+	0x66, 2832,
+	/*2832*/ uint16(xSetOp), uint16(PMAXUW),
+	/*2834*/ uint16(xReadSlashR),
+	/*2835*/ uint16(xArgXmm1),
+	/*2836*/ uint16(xArgXmm2M128),
+	/*2837*/ uint16(xMatch),
+	/*2838*/ uint16(xCondPrefix), 1,
+	0x66, 2842,
+	/*2842*/ uint16(xSetOp), uint16(PMAXUD),
+	/*2844*/ uint16(xReadSlashR),
+	/*2845*/ uint16(xArgXmm1),
+	/*2846*/ uint16(xArgXmm2M128),
+	/*2847*/ uint16(xMatch),
+	/*2848*/ uint16(xCondPrefix), 1,
+	0x66, 2852,
+	/*2852*/ uint16(xSetOp), uint16(PMULLD),
+	/*2854*/ uint16(xReadSlashR),
+	/*2855*/ uint16(xArgXmm1),
+	/*2856*/ uint16(xArgXmm2M128),
+	/*2857*/ uint16(xMatch),
+	/*2858*/ uint16(xCondPrefix), 1,
+	0x66, 2862,
+	/*2862*/ uint16(xSetOp), uint16(PHMINPOSUW),
+	/*2864*/ uint16(xReadSlashR),
+	/*2865*/ uint16(xArgXmm1),
+	/*2866*/ uint16(xArgXmm2M128),
+	/*2867*/ uint16(xMatch),
+	/*2868*/ uint16(xCondIs64), 2871, 2881,
+	/*2871*/ uint16(xCondPrefix), 1,
+	0x66, 2875,
+	/*2875*/ uint16(xSetOp), uint16(INVPCID),
+	/*2877*/ uint16(xReadSlashR),
+	/*2878*/ uint16(xArgR32),
+	/*2879*/ uint16(xArgM128),
+	/*2880*/ uint16(xMatch),
+	/*2881*/ uint16(xCondPrefix), 1,
+	0x66, 2885,
+	/*2885*/ uint16(xSetOp), uint16(INVPCID),
+	/*2887*/ uint16(xReadSlashR),
+	/*2888*/ uint16(xArgR64),
+	/*2889*/ uint16(xArgM128),
+	/*2890*/ uint16(xMatch),
+	/*2891*/ uint16(xCondPrefix), 1,
+	0x66, 2895,
+	/*2895*/ uint16(xSetOp), uint16(AESIMC),
+	/*2897*/ uint16(xReadSlashR),
+	/*2898*/ uint16(xArgXmm1),
+	/*2899*/ uint16(xArgXmm2M128),
+	/*2900*/ uint16(xMatch),
+	/*2901*/ uint16(xCondPrefix), 1,
+	0x66, 2905,
+	/*2905*/ uint16(xSetOp), uint16(AESENC),
+	/*2907*/ uint16(xReadSlashR),
+	/*2908*/ uint16(xArgXmm1),
+	/*2909*/ uint16(xArgXmm2M128),
+	/*2910*/ uint16(xMatch),
+	/*2911*/ uint16(xCondPrefix), 1,
+	0x66, 2915,
+	/*2915*/ uint16(xSetOp), uint16(AESENCLAST),
+	/*2917*/ uint16(xReadSlashR),
+	/*2918*/ uint16(xArgXmm1),
+	/*2919*/ uint16(xArgXmm2M128),
+	/*2920*/ uint16(xMatch),
+	/*2921*/ uint16(xCondPrefix), 1,
+	0x66, 2925,
+	/*2925*/ uint16(xSetOp), uint16(AESDEC),
+	/*2927*/ uint16(xReadSlashR),
+	/*2928*/ uint16(xArgXmm1),
+	/*2929*/ uint16(xArgXmm2M128),
+	/*2930*/ uint16(xMatch),
+	/*2931*/ uint16(xCondPrefix), 1,
+	0x66, 2935,
+	/*2935*/ uint16(xSetOp), uint16(AESDECLAST),
+	/*2937*/ uint16(xReadSlashR),
+	/*2938*/ uint16(xArgXmm1),
+	/*2939*/ uint16(xArgXmm2M128),
+	/*2940*/ uint16(xMatch),
+	/*2941*/ uint16(xCondIs64), 2944, 2982,
+	/*2944*/ uint16(xCondPrefix), 2,
+	0xF2, 2966,
+	0x0, 2950,
+	/*2950*/ uint16(xCondDataSize), 2954, 2960, 0,
+	/*2954*/ uint16(xSetOp), uint16(MOVBE),
+	/*2956*/ uint16(xReadSlashR),
+	/*2957*/ uint16(xArgR16),
+	/*2958*/ uint16(xArgM16),
+	/*2959*/ uint16(xMatch),
+	/*2960*/ uint16(xSetOp), uint16(MOVBE),
+	/*2962*/ uint16(xReadSlashR),
+	/*2963*/ uint16(xArgR32),
+	/*2964*/ uint16(xArgM32),
+	/*2965*/ uint16(xMatch),
+	/*2966*/ uint16(xCondDataSize), 2970, 2976, 0,
+	/*2970*/ uint16(xSetOp), uint16(CRC32),
+	/*2972*/ uint16(xReadSlashR),
+	/*2973*/ uint16(xArgR32),
+	/*2974*/ uint16(xArgRM8),
+	/*2975*/ uint16(xMatch),
+	/*2976*/ uint16(xSetOp), uint16(CRC32),
+	/*2978*/ uint16(xReadSlashR),
+	/*2979*/ uint16(xArgR32),
+	/*2980*/ uint16(xArgRM8),
+	/*2981*/ uint16(xMatch),
+	/*2982*/ uint16(xCondPrefix), 2,
+	0xF2, 2998,
+	0x0, 2988,
+	/*2988*/ uint16(xCondDataSize), 2954, 2960, 2992,
+	/*2992*/ uint16(xSetOp), uint16(MOVBE),
+	/*2994*/ uint16(xReadSlashR),
+	/*2995*/ uint16(xArgR64),
+	/*2996*/ uint16(xArgM64),
+	/*2997*/ uint16(xMatch),
+	/*2998*/ uint16(xCondDataSize), 2970, 2976, 3002,
+	/*3002*/ uint16(xSetOp), uint16(CRC32),
+	/*3004*/ uint16(xReadSlashR),
+	/*3005*/ uint16(xArgR64),
+	/*3006*/ uint16(xArgRM8),
+	/*3007*/ uint16(xMatch),
+	/*3008*/ uint16(xCondIs64), 3011, 3049,
+	/*3011*/ uint16(xCondPrefix), 2,
+	0xF2, 3033,
+	0x0, 3017,
+	/*3017*/ uint16(xCondDataSize), 3021, 3027, 0,
+	/*3021*/ uint16(xSetOp), uint16(MOVBE),
+	/*3023*/ uint16(xReadSlashR),
+	/*3024*/ uint16(xArgM16),
+	/*3025*/ uint16(xArgR16),
+	/*3026*/ uint16(xMatch),
+	/*3027*/ uint16(xSetOp), uint16(MOVBE),
+	/*3029*/ uint16(xReadSlashR),
+	/*3030*/ uint16(xArgM32),
+	/*3031*/ uint16(xArgR32),
+	/*3032*/ uint16(xMatch),
+	/*3033*/ uint16(xCondDataSize), 3037, 3043, 0,
+	/*3037*/ uint16(xSetOp), uint16(CRC32),
+	/*3039*/ uint16(xReadSlashR),
+	/*3040*/ uint16(xArgR32),
+	/*3041*/ uint16(xArgRM16),
+	/*3042*/ uint16(xMatch),
+	/*3043*/ uint16(xSetOp), uint16(CRC32),
+	/*3045*/ uint16(xReadSlashR),
+	/*3046*/ uint16(xArgR32),
+	/*3047*/ uint16(xArgRM32),
+	/*3048*/ uint16(xMatch),
+	/*3049*/ uint16(xCondPrefix), 2,
+	0xF2, 3065,
+	0x0, 3055,
+	/*3055*/ uint16(xCondDataSize), 3021, 3027, 3059,
+	/*3059*/ uint16(xSetOp), uint16(MOVBE),
+	/*3061*/ uint16(xReadSlashR),
+	/*3062*/ uint16(xArgM64),
+	/*3063*/ uint16(xArgR64),
+	/*3064*/ uint16(xMatch),
+	/*3065*/ uint16(xCondDataSize), 3037, 3043, 3069,
+	/*3069*/ uint16(xSetOp), uint16(CRC32),
+	/*3071*/ uint16(xReadSlashR),
+	/*3072*/ uint16(xArgR64),
+	/*3073*/ uint16(xArgRM64),
+	/*3074*/ uint16(xMatch),
+	/*3075*/ uint16(xCondByte), 24,
+	0x08, 3126,
+	0x09, 3138,
+	0x0A, 3150,
+	0x0B, 3162,
+	0x0C, 3174,
+	0x0D, 3186,
+	0x0E, 3198,
+	0x0F, 3210,
+	0x14, 3232,
+	0x15, 3244,
+	0x16, 3256,
+	0x17, 3299,
+	0x20, 3311,
+	0x21, 3323,
+	0x22, 3335,
+	0x40, 3378,
+	0x41, 3390,
+	0x42, 3402,
+	0x44, 3414,
+	0x60, 3426,
+	0x61, 3438,
+	0x62, 3450,
+	0x63, 3462,
+	0xDF, 3474,
 	uint16(xFail),
-	/*3124*/ uint16(xCondPrefix), 1,
-	0x66, 3128,
-	/*3128*/ uint16(xSetOp), uint16(ROUNDPS),
-	/*3130*/ uint16(xReadSlashR),
-	/*3131*/ uint16(xReadIb),
-	/*3132*/ uint16(xArgXmm1),
-	/*3133*/ uint16(xArgXmm2M128),
-	/*3134*/ uint16(xArgImm8u),
-	/*3135*/ uint16(xMatch),
-	/*3136*/ uint16(xCondPrefix), 1,
-	0x66, 3140,
-	/*3140*/ uint16(xSetOp), uint16(ROUNDPD),
-	/*3142*/ uint16(xReadSlashR),
-	/*3143*/ uint16(xReadIb),
-	/*3144*/ uint16(xArgXmm1),
-	/*3145*/ uint16(xArgXmm2M128),
-	/*3146*/ uint16(xArgImm8u),
-	/*3147*/ uint16(xMatch),
-	/*3148*/ uint16(xCondPrefix), 1,
-	0x66, 3152,
-	/*3152*/ uint16(xSetOp), uint16(ROUNDSS),
-	/*3154*/ uint16(xReadSlashR),
-	/*3155*/ uint16(xReadIb),
-	/*3156*/ uint16(xArgXmm1),
-	/*3157*/ uint16(xArgXmm2M32),
-	/*3158*/ uint16(xArgImm8u),
-	/*3159*/ uint16(xMatch),
-	/*3160*/ uint16(xCondPrefix), 1,
-	0x66, 3164,
-	/*3164*/ uint16(xSetOp), uint16(ROUNDSD),
-	/*3166*/ uint16(xReadSlashR),
-	/*3167*/ uint16(xReadIb),
-	/*3168*/ uint16(xArgXmm1),
-	/*3169*/ uint16(xArgXmm2M64),
-	/*3170*/ uint16(xArgImm8u),
-	/*3171*/ uint16(xMatch),
-	/*3172*/ uint16(xCondPrefix), 1,
-	0x66, 3176,
-	/*3176*/ uint16(xSetOp), uint16(BLENDPS),
-	/*3178*/ uint16(xReadSlashR),
-	/*3179*/ uint16(xReadIb),
-	/*3180*/ uint16(xArgXmm1),
-	/*3181*/ uint16(xArgXmm2M128),
-	/*3182*/ uint16(xArgImm8u),
-	/*3183*/ uint16(xMatch),
-	/*3184*/ uint16(xCondPrefix), 1,
-	0x66, 3188,
-	/*3188*/ uint16(xSetOp), uint16(BLENDPD),
-	/*3190*/ uint16(xReadSlashR),
-	/*3191*/ uint16(xReadIb),
-	/*3192*/ uint16(xArgXmm1),
-	/*3193*/ uint16(xArgXmm2M128),
-	/*3194*/ uint16(xArgImm8u),
-	/*3195*/ uint16(xMatch),
-	/*3196*/ uint16(xCondPrefix), 1,
-	0x66, 3200,
-	/*3200*/ uint16(xSetOp), uint16(PBLENDW),
-	/*3202*/ uint16(xReadSlashR),
-	/*3203*/ uint16(xReadIb),
-	/*3204*/ uint16(xArgXmm1),
-	/*3205*/ uint16(xArgXmm2M128),
-	/*3206*/ uint16(xArgImm8u),
-	/*3207*/ uint16(xMatch),
-	/*3208*/ uint16(xCondPrefix), 2,
-	0x66, 3222,
-	0x0, 3214,
-	/*3214*/ uint16(xSetOp), uint16(PALIGNR),
-	/*3216*/ uint16(xReadSlashR),
-	/*3217*/ uint16(xReadIb),
-	/*3218*/ uint16(xArgMm1),
-	/*3219*/ uint16(xArgMm2M64),
-	/*3220*/ uint16(xArgImm8u),
-	/*3221*/ uint16(xMatch),
-	/*3222*/ uint16(xSetOp), uint16(PALIGNR),
-	/*3224*/ uint16(xReadSlashR),
-	/*3225*/ uint16(xReadIb),
-	/*3226*/ uint16(xArgXmm1),
-	/*3227*/ uint16(xArgXmm2M128),
-	/*3228*/ uint16(xArgImm8u),
-	/*3229*/ uint16(xMatch),
-	/*3230*/ uint16(xCondPrefix), 1,
-	0x66, 3234,
-	/*3234*/ uint16(xSetOp), uint16(PEXTRB),
-	/*3236*/ uint16(xReadSlashR),
-	/*3237*/ uint16(xReadIb),
-	/*3238*/ uint16(xArgR32M8),
-	/*3239*/ uint16(xArgXmm1),
-	/*3240*/ uint16(xArgImm8u),
-	/*3241*/ uint16(xMatch),
-	/*3242*/ uint16(xCondPrefix), 1,
-	0x66, 3246,
-	/*3246*/ uint16(xSetOp), uint16(PEXTRW),
-	/*3248*/ uint16(xReadSlashR),
-	/*3249*/ uint16(xReadIb),
-	/*3250*/ uint16(xArgR32M16),
-	/*3251*/ uint16(xArgXmm1),
-	/*3252*/ uint16(xArgImm8u),
-	/*3253*/ uint16(xMatch),
-	/*3254*/ uint16(xCondIs64), 3257, 3281,
-	/*3257*/ uint16(xCondPrefix), 1,
-	0x66, 3261,
-	/*3261*/ uint16(xCondDataSize), 3265, 3273, 0,
-	/*3265*/ uint16(xSetOp), uint16(PEXTRD),
-	/*3267*/ uint16(xReadSlashR),
-	/*3268*/ uint16(xReadIb),
-	/*3269*/ uint16(xArgRM32),
-	/*3270*/ uint16(xArgXmm1),
-	/*3271*/ uint16(xArgImm8u),
-	/*3272*/ uint16(xMatch),
-	/*3273*/ uint16(xSetOp), uint16(PEXTRD),
-	/*3275*/ uint16(xReadSlashR),
-	/*3276*/ uint16(xReadIb),
-	/*3277*/ uint16(xArgRM32),
-	/*3278*/ uint16(xArgXmm1),
-	/*3279*/ uint16(xArgImm8u),
-	/*3280*/ uint16(xMatch),
-	/*3281*/ uint16(xCondPrefix), 1,
-	0x66, 3285,
-	/*3285*/ uint16(xCondDataSize), 3265, 3273, 3289,
-	/*3289*/ uint16(xSetOp), uint16(PEXTRQ),
-	/*3291*/ uint16(xReadSlashR),
-	/*3292*/ uint16(xReadIb),
-	/*3293*/ uint16(xArgRM64),
-	/*3294*/ uint16(xArgXmm1),
-	/*3295*/ uint16(xArgImm8u),
-	/*3296*/ uint16(xMatch),
-	/*3297*/ uint16(xCondPrefix), 1,
-	0x66, 3301,
-	/*3301*/ uint16(xSetOp), uint16(EXTRACTPS),
-	/*3303*/ uint16(xReadSlashR),
-	/*3304*/ uint16(xReadIb),
-	/*3305*/ uint16(xArgRM32),
-	/*3306*/ uint16(xArgXmm1),
-	/*3307*/ uint16(xArgImm8u),
-	/*3308*/ uint16(xMatch),
-	/*3309*/ uint16(xCondPrefix), 1,
-	0x66, 3313,
-	/*3313*/ uint16(xSetOp), uint16(PINSRB),
-	/*3315*/ uint16(xReadSlashR),
-	/*3316*/ uint16(xReadIb),
-	/*3317*/ uint16(xArgXmm1),
-	/*3318*/ uint16(xArgR32M8),
-	/*3319*/ uint16(xArgImm8u),
-	/*3320*/ uint16(xMatch),
-	/*3321*/ uint16(xCondPrefix), 1,
-	0x66, 3325,
-	/*3325*/ uint16(xSetOp), uint16(INSERTPS),
-	/*3327*/ uint16(xReadSlashR),
-	/*3328*/ uint16(xReadIb),
-	/*3329*/ uint16(xArgXmm1),
-	/*3330*/ uint16(xArgXmm2M32),
-	/*3331*/ uint16(xArgImm8u),
-	/*3332*/ uint16(xMatch),
-	/*3333*/ uint16(xCondIs64), 3336, 3360,
-	/*3336*/ uint16(xCondPrefix), 1,
-	0x66, 3340,
-	/*3340*/ uint16(xCondDataSize), 3344, 3352, 0,
-	/*3344*/ uint16(xSetOp), uint16(PINSRD),
-	/*3346*/ uint16(xReadSlashR),
-	/*3347*/ uint16(xReadIb),
-	/*3348*/ uint16(xArgXmm1),
-	/*3349*/ uint16(xArgRM32),
-	/*3350*/ uint16(xArgImm8u),
-	/*3351*/ uint16(xMatch),
-	/*3352*/ uint16(xSetOp), uint16(PINSRD),
-	/*3354*/ uint16(xReadSlashR),
-	/*3355*/ uint16(xReadIb),
-	/*3356*/ uint16(xArgXmm1),
-	/*3357*/ uint16(xArgRM32),
-	/*3358*/ uint16(xArgImm8u),
-	/*3359*/ uint16(xMatch),
-	/*3360*/ uint16(xCondPrefix), 1,
-	0x66, 3364,
-	/*3364*/ uint16(xCondDataSize), 3344, 3352, 3368,
-	/*3368*/ uint16(xSetOp), uint16(PINSRQ),
-	/*3370*/ uint16(xReadSlashR),
-	/*3371*/ uint16(xReadIb),
-	/*3372*/ uint16(xArgXmm1),
-	/*3373*/ uint16(xArgRM64),
-	/*3374*/ uint16(xArgImm8u),
-	/*3375*/ uint16(xMatch),
-	/*3376*/ uint16(xCondPrefix), 1,
-	0x66, 3380,
-	/*3380*/ uint16(xSetOp), uint16(DPPS),
-	/*3382*/ uint16(xReadSlashR),
-	/*3383*/ uint16(xReadIb),
-	/*3384*/ uint16(xArgXmm1),
-	/*3385*/ uint16(xArgXmm2M128),
-	/*3386*/ uint16(xArgImm8u),
-	/*3387*/ uint16(xMatch),
-	/*3388*/ uint16(xCondPrefix), 1,
-	0x66, 3392,
-	/*3392*/ uint16(xSetOp), uint16(DPPD),
-	/*3394*/ uint16(xReadSlashR),
-	/*3395*/ uint16(xReadIb),
-	/*3396*/ uint16(xArgXmm1),
-	/*3397*/ uint16(xArgXmm2M128),
-	/*3398*/ uint16(xArgImm8u),
-	/*3399*/ uint16(xMatch),
-	/*3400*/ uint16(xCondPrefix), 1,
-	0x66, 3404,
-	/*3404*/ uint16(xSetOp), uint16(MPSADBW),
-	/*3406*/ uint16(xReadSlashR),
-	/*3407*/ uint16(xReadIb),
-	/*3408*/ uint16(xArgXmm1),
-	/*3409*/ uint16(xArgXmm2M128),
-	/*3410*/ uint16(xArgImm8u),
-	/*3411*/ uint16(xMatch),
-	/*3412*/ uint16(xCondPrefix), 1,
-	0x66, 3416,
-	/*3416*/ uint16(xSetOp), uint16(PCLMULQDQ),
-	/*3418*/ uint16(xReadSlashR),
-	/*3419*/ uint16(xReadIb),
-	/*3420*/ uint16(xArgXmm1),
-	/*3421*/ uint16(xArgXmm2M128),
-	/*3422*/ uint16(xArgImm8u),
-	/*3423*/ uint16(xMatch),
-	/*3424*/ uint16(xCondPrefix), 1,
-	0x66, 3428,
-	/*3428*/ uint16(xSetOp), uint16(PCMPESTRM),
-	/*3430*/ uint16(xReadSlashR),
-	/*3431*/ uint16(xReadIb),
-	/*3432*/ uint16(xArgXmm1),
-	/*3433*/ uint16(xArgXmm2M128),
-	/*3434*/ uint16(xArgImm8u),
-	/*3435*/ uint16(xMatch),
-	/*3436*/ uint16(xCondPrefix), 1,
-	0x66, 3440,
-	/*3440*/ uint16(xSetOp), uint16(PCMPESTRI),
-	/*3442*/ uint16(xReadSlashR),
-	/*3443*/ uint16(xReadIb),
-	/*3444*/ uint16(xArgXmm1),
-	/*3445*/ uint16(xArgXmm2M128),
-	/*3446*/ uint16(xArgImm8u),
-	/*3447*/ uint16(xMatch),
-	/*3448*/ uint16(xCondPrefix), 1,
-	0x66, 3452,
-	/*3452*/ uint16(xSetOp), uint16(PCMPISTRM),
-	/*3454*/ uint16(xReadSlashR),
-	/*3455*/ uint16(xReadIb),
-	/*3456*/ uint16(xArgXmm1),
-	/*3457*/ uint16(xArgXmm2M128),
-	/*3458*/ uint16(xArgImm8u),
-	/*3459*/ uint16(xMatch),
-	/*3460*/ uint16(xCondPrefix), 1,
-	0x66, 3464,
-	/*3464*/ uint16(xSetOp), uint16(PCMPISTRI),
-	/*3466*/ uint16(xReadSlashR),
-	/*3467*/ uint16(xReadIb),
-	/*3468*/ uint16(xArgXmm1),
-	/*3469*/ uint16(xArgXmm2M128),
-	/*3470*/ uint16(xArgImm8u),
-	/*3471*/ uint16(xMatch),
-	/*3472*/ uint16(xCondPrefix), 1,
-	0x66, 3476,
-	/*3476*/ uint16(xSetOp), uint16(AESKEYGENASSIST),
-	/*3478*/ uint16(xReadSlashR),
-	/*3479*/ uint16(xReadIb),
-	/*3480*/ uint16(xArgXmm1),
-	/*3481*/ uint16(xArgXmm2M128),
-	/*3482*/ uint16(xArgImm8u),
-	/*3483*/ uint16(xMatch),
-	/*3484*/ uint16(xCondIs64), 3487, 3503,
-	/*3487*/ uint16(xCondDataSize), 3491, 3497, 0,
-	/*3491*/ uint16(xSetOp), uint16(CMOVO),
-	/*3493*/ uint16(xReadSlashR),
-	/*3494*/ uint16(xArgR16),
-	/*3495*/ uint16(xArgRM16),
-	/*3496*/ uint16(xMatch),
-	/*3497*/ uint16(xSetOp), uint16(CMOVO),
-	/*3499*/ uint16(xReadSlashR),
-	/*3500*/ uint16(xArgR32),
-	/*3501*/ uint16(xArgRM32),
-	/*3502*/ uint16(xMatch),
-	/*3503*/ uint16(xCondDataSize), 3491, 3497, 3507,
-	/*3507*/ uint16(xSetOp), uint16(CMOVO),
-	/*3509*/ uint16(xReadSlashR),
-	/*3510*/ uint16(xArgR64),
-	/*3511*/ uint16(xArgRM64),
-	/*3512*/ uint16(xMatch),
-	/*3513*/ uint16(xCondIs64), 3516, 3532,
-	/*3516*/ uint16(xCondDataSize), 3520, 3526, 0,
-	/*3520*/ uint16(xSetOp), uint16(CMOVNO),
-	/*3522*/ uint16(xReadSlashR),
-	/*3523*/ uint16(xArgR16),
-	/*3524*/ uint16(xArgRM16),
-	/*3525*/ uint16(xMatch),
-	/*3526*/ uint16(xSetOp), uint16(CMOVNO),
-	/*3528*/ uint16(xReadSlashR),
-	/*3529*/ uint16(xArgR32),
-	/*3530*/ uint16(xArgRM32),
-	/*3531*/ uint16(xMatch),
-	/*3532*/ uint16(xCondDataSize), 3520, 3526, 3536,
-	/*3536*/ uint16(xSetOp), uint16(CMOVNO),
-	/*3538*/ uint16(xReadSlashR),
-	/*3539*/ uint16(xArgR64),
-	/*3540*/ uint16(xArgRM64),
-	/*3541*/ uint16(xMatch),
-	/*3542*/ uint16(xCondIs64), 3545, 3561,
-	/*3545*/ uint16(xCondDataSize), 3549, 3555, 0,
-	/*3549*/ uint16(xSetOp), uint16(CMOVB),
-	/*3551*/ uint16(xReadSlashR),
-	/*3552*/ uint16(xArgR16),
-	/*3553*/ uint16(xArgRM16),
-	/*3554*/ uint16(xMatch),
-	/*3555*/ uint16(xSetOp), uint16(CMOVB),
-	/*3557*/ uint16(xReadSlashR),
-	/*3558*/ uint16(xArgR32),
-	/*3559*/ uint16(xArgRM32),
-	/*3560*/ uint16(xMatch),
-	/*3561*/ uint16(xCondDataSize), 3549, 3555, 3565,
-	/*3565*/ uint16(xSetOp), uint16(CMOVB),
-	/*3567*/ uint16(xReadSlashR),
-	/*3568*/ uint16(xArgR64),
-	/*3569*/ uint16(xArgRM64),
-	/*3570*/ uint16(xMatch),
-	/*3571*/ uint16(xCondIs64), 3574, 3590,
-	/*3574*/ uint16(xCondDataSize), 3578, 3584, 0,
-	/*3578*/ uint16(xSetOp), uint16(CMOVAE),
-	/*3580*/ uint16(xReadSlashR),
-	/*3581*/ uint16(xArgR16),
-	/*3582*/ uint16(xArgRM16),
-	/*3583*/ uint16(xMatch),
-	/*3584*/ uint16(xSetOp), uint16(CMOVAE),
-	/*3586*/ uint16(xReadSlashR),
-	/*3587*/ uint16(xArgR32),
-	/*3588*/ uint16(xArgRM32),
-	/*3589*/ uint16(xMatch),
-	/*3590*/ uint16(xCondDataSize), 3578, 3584, 3594,
-	/*3594*/ uint16(xSetOp), uint16(CMOVAE),
-	/*3596*/ uint16(xReadSlashR),
-	/*3597*/ uint16(xArgR64),
-	/*3598*/ uint16(xArgRM64),
-	/*3599*/ uint16(xMatch),
-	/*3600*/ uint16(xCondIs64), 3603, 3619,
-	/*3603*/ uint16(xCondDataSize), 3607, 3613, 0,
-	/*3607*/ uint16(xSetOp), uint16(CMOVE),
-	/*3609*/ uint16(xReadSlashR),
-	/*3610*/ uint16(xArgR16),
-	/*3611*/ uint16(xArgRM16),
-	/*3612*/ uint16(xMatch),
-	/*3613*/ uint16(xSetOp), uint16(CMOVE),
-	/*3615*/ uint16(xReadSlashR),
-	/*3616*/ uint16(xArgR32),
-	/*3617*/ uint16(xArgRM32),
-	/*3618*/ uint16(xMatch),
-	/*3619*/ uint16(xCondDataSize), 3607, 3613, 3623,
-	/*3623*/ uint16(xSetOp), uint16(CMOVE),
-	/*3625*/ uint16(xReadSlashR),
-	/*3626*/ uint16(xArgR64),
-	/*3627*/ uint16(xArgRM64),
-	/*3628*/ uint16(xMatch),
-	/*3629*/ uint16(xCondIs64), 3632, 3648,
-	/*3632*/ uint16(xCondDataSize), 3636, 3642, 0,
-	/*3636*/ uint16(xSetOp), uint16(CMOVNE),
-	/*3638*/ uint16(xReadSlashR),
-	/*3639*/ uint16(xArgR16),
-	/*3640*/ uint16(xArgRM16),
-	/*3641*/ uint16(xMatch),
-	/*3642*/ uint16(xSetOp), uint16(CMOVNE),
-	/*3644*/ uint16(xReadSlashR),
-	/*3645*/ uint16(xArgR32),
-	/*3646*/ uint16(xArgRM32),
-	/*3647*/ uint16(xMatch),
-	/*3648*/ uint16(xCondDataSize), 3636, 3642, 3652,
-	/*3652*/ uint16(xSetOp), uint16(CMOVNE),
-	/*3654*/ uint16(xReadSlashR),
-	/*3655*/ uint16(xArgR64),
-	/*3656*/ uint16(xArgRM64),
-	/*3657*/ uint16(xMatch),
-	/*3658*/ uint16(xCondIs64), 3661, 3677,
-	/*3661*/ uint16(xCondDataSize), 3665, 3671, 0,
-	/*3665*/ uint16(xSetOp), uint16(CMOVBE),
-	/*3667*/ uint16(xReadSlashR),
-	/*3668*/ uint16(xArgR16),
-	/*3669*/ uint16(xArgRM16),
-	/*3670*/ uint16(xMatch),
-	/*3671*/ uint16(xSetOp), uint16(CMOVBE),
-	/*3673*/ uint16(xReadSlashR),
-	/*3674*/ uint16(xArgR32),
-	/*3675*/ uint16(xArgRM32),
-	/*3676*/ uint16(xMatch),
-	/*3677*/ uint16(xCondDataSize), 3665, 3671, 3681,
-	/*3681*/ uint16(xSetOp), uint16(CMOVBE),
-	/*3683*/ uint16(xReadSlashR),
-	/*3684*/ uint16(xArgR64),
-	/*3685*/ uint16(xArgRM64),
-	/*3686*/ uint16(xMatch),
-	/*3687*/ uint16(xCondIs64), 3690, 3706,
-	/*3690*/ uint16(xCondDataSize), 3694, 3700, 0,
-	/*3694*/ uint16(xSetOp), uint16(CMOVA),
-	/*3696*/ uint16(xReadSlashR),
-	/*3697*/ uint16(xArgR16),
-	/*3698*/ uint16(xArgRM16),
-	/*3699*/ uint16(xMatch),
-	/*3700*/ uint16(xSetOp), uint16(CMOVA),
-	/*3702*/ uint16(xReadSlashR),
-	/*3703*/ uint16(xArgR32),
-	/*3704*/ uint16(xArgRM32),
-	/*3705*/ uint16(xMatch),
-	/*3706*/ uint16(xCondDataSize), 3694, 3700, 3710,
-	/*3710*/ uint16(xSetOp), uint16(CMOVA),
-	/*3712*/ uint16(xReadSlashR),
-	/*3713*/ uint16(xArgR64),
-	/*3714*/ uint16(xArgRM64),
-	/*3715*/ uint16(xMatch),
-	/*3716*/ uint16(xCondIs64), 3719, 3735,
-	/*3719*/ uint16(xCondDataSize), 3723, 3729, 0,
-	/*3723*/ uint16(xSetOp), uint16(CMOVS),
-	/*3725*/ uint16(xReadSlashR),
-	/*3726*/ uint16(xArgR16),
-	/*3727*/ uint16(xArgRM16),
-	/*3728*/ uint16(xMatch),
-	/*3729*/ uint16(xSetOp), uint16(CMOVS),
-	/*3731*/ uint16(xReadSlashR),
-	/*3732*/ uint16(xArgR32),
-	/*3733*/ uint16(xArgRM32),
-	/*3734*/ uint16(xMatch),
-	/*3735*/ uint16(xCondDataSize), 3723, 3729, 3739,
-	/*3739*/ uint16(xSetOp), uint16(CMOVS),
-	/*3741*/ uint16(xReadSlashR),
-	/*3742*/ uint16(xArgR64),
-	/*3743*/ uint16(xArgRM64),
-	/*3744*/ uint16(xMatch),
-	/*3745*/ uint16(xCondIs64), 3748, 3764,
-	/*3748*/ uint16(xCondDataSize), 3752, 3758, 0,
-	/*3752*/ uint16(xSetOp), uint16(CMOVNS),
-	/*3754*/ uint16(xReadSlashR),
-	/*3755*/ uint16(xArgR16),
-	/*3756*/ uint16(xArgRM16),
-	/*3757*/ uint16(xMatch),
-	/*3758*/ uint16(xSetOp), uint16(CMOVNS),
-	/*3760*/ uint16(xReadSlashR),
-	/*3761*/ uint16(xArgR32),
-	/*3762*/ uint16(xArgRM32),
-	/*3763*/ uint16(xMatch),
-	/*3764*/ uint16(xCondDataSize), 3752, 3758, 3768,
-	/*3768*/ uint16(xSetOp), uint16(CMOVNS),
-	/*3770*/ uint16(xReadSlashR),
-	/*3771*/ uint16(xArgR64),
-	/*3772*/ uint16(xArgRM64),
-	/*3773*/ uint16(xMatch),
-	/*3774*/ uint16(xCondIs64), 3777, 3793,
-	/*3777*/ uint16(xCondDataSize), 3781, 3787, 0,
-	/*3781*/ uint16(xSetOp), uint16(CMOVP),
-	/*3783*/ uint16(xReadSlashR),
-	/*3784*/ uint16(xArgR16),
-	/*3785*/ uint16(xArgRM16),
-	/*3786*/ uint16(xMatch),
-	/*3787*/ uint16(xSetOp), uint16(CMOVP),
-	/*3789*/ uint16(xReadSlashR),
-	/*3790*/ uint16(xArgR32),
-	/*3791*/ uint16(xArgRM32),
-	/*3792*/ uint16(xMatch),
-	/*3793*/ uint16(xCondDataSize), 3781, 3787, 3797,
-	/*3797*/ uint16(xSetOp), uint16(CMOVP),
-	/*3799*/ uint16(xReadSlashR),
-	/*3800*/ uint16(xArgR64),
-	/*3801*/ uint16(xArgRM64),
-	/*3802*/ uint16(xMatch),
-	/*3803*/ uint16(xCondIs64), 3806, 3822,
-	/*3806*/ uint16(xCondDataSize), 3810, 3816, 0,
-	/*3810*/ uint16(xSetOp), uint16(CMOVNP),
-	/*3812*/ uint16(xReadSlashR),
-	/*3813*/ uint16(xArgR16),
-	/*3814*/ uint16(xArgRM16),
-	/*3815*/ uint16(xMatch),
-	/*3816*/ uint16(xSetOp), uint16(CMOVNP),
-	/*3818*/ uint16(xReadSlashR),
-	/*3819*/ uint16(xArgR32),
-	/*3820*/ uint16(xArgRM32),
-	/*3821*/ uint16(xMatch),
-	/*3822*/ uint16(xCondDataSize), 3810, 3816, 3826,
-	/*3826*/ uint16(xSetOp), uint16(CMOVNP),
-	/*3828*/ uint16(xReadSlashR),
-	/*3829*/ uint16(xArgR64),
-	/*3830*/ uint16(xArgRM64),
-	/*3831*/ uint16(xMatch),
-	/*3832*/ uint16(xCondIs64), 3835, 3851,
-	/*3835*/ uint16(xCondDataSize), 3839, 3845, 0,
-	/*3839*/ uint16(xSetOp), uint16(CMOVL),
-	/*3841*/ uint16(xReadSlashR),
-	/*3842*/ uint16(xArgR16),
-	/*3843*/ uint16(xArgRM16),
-	/*3844*/ uint16(xMatch),
-	/*3845*/ uint16(xSetOp), uint16(CMOVL),
-	/*3847*/ uint16(xReadSlashR),
-	/*3848*/ uint16(xArgR32),
-	/*3849*/ uint16(xArgRM32),
-	/*3850*/ uint16(xMatch),
-	/*3851*/ uint16(xCondDataSize), 3839, 3845, 3855,
-	/*3855*/ uint16(xSetOp), uint16(CMOVL),
-	/*3857*/ uint16(xReadSlashR),
-	/*3858*/ uint16(xArgR64),
-	/*3859*/ uint16(xArgRM64),
-	/*3860*/ uint16(xMatch),
-	/*3861*/ uint16(xCondIs64), 3864, 3880,
-	/*3864*/ uint16(xCondDataSize), 3868, 3874, 0,
-	/*3868*/ uint16(xSetOp), uint16(CMOVGE),
-	/*3870*/ uint16(xReadSlashR),
-	/*3871*/ uint16(xArgR16),
-	/*3872*/ uint16(xArgRM16),
-	/*3873*/ uint16(xMatch),
-	/*3874*/ uint16(xSetOp), uint16(CMOVGE),
-	/*3876*/ uint16(xReadSlashR),
-	/*3877*/ uint16(xArgR32),
-	/*3878*/ uint16(xArgRM32),
-	/*3879*/ uint16(xMatch),
-	/*3880*/ uint16(xCondDataSize), 3868, 3874, 3884,
-	/*3884*/ uint16(xSetOp), uint16(CMOVGE),
-	/*3886*/ uint16(xReadSlashR),
-	/*3887*/ uint16(xArgR64),
-	/*3888*/ uint16(xArgRM64),
-	/*3889*/ uint16(xMatch),
-	/*3890*/ uint16(xCondIs64), 3893, 3909,
-	/*3893*/ uint16(xCondDataSize), 3897, 3903, 0,
-	/*3897*/ uint16(xSetOp), uint16(CMOVLE),
-	/*3899*/ uint16(xReadSlashR),
-	/*3900*/ uint16(xArgR16),
-	/*3901*/ uint16(xArgRM16),
-	/*3902*/ uint16(xMatch),
-	/*3903*/ uint16(xSetOp), uint16(CMOVLE),
-	/*3905*/ uint16(xReadSlashR),
-	/*3906*/ uint16(xArgR32),
-	/*3907*/ uint16(xArgRM32),
-	/*3908*/ uint16(xMatch),
-	/*3909*/ uint16(xCondDataSize), 3897, 3903, 3913,
-	/*3913*/ uint16(xSetOp), uint16(CMOVLE),
-	/*3915*/ uint16(xReadSlashR),
-	/*3916*/ uint16(xArgR64),
-	/*3917*/ uint16(xArgRM64),
-	/*3918*/ uint16(xMatch),
-	/*3919*/ uint16(xCondIs64), 3922, 3938,
-	/*3922*/ uint16(xCondDataSize), 3926, 3932, 0,
-	/*3926*/ uint16(xSetOp), uint16(CMOVG),
-	/*3928*/ uint16(xReadSlashR),
-	/*3929*/ uint16(xArgR16),
-	/*3930*/ uint16(xArgRM16),
-	/*3931*/ uint16(xMatch),
-	/*3932*/ uint16(xSetOp), uint16(CMOVG),
-	/*3934*/ uint16(xReadSlashR),
-	/*3935*/ uint16(xArgR32),
-	/*3936*/ uint16(xArgRM32),
-	/*3937*/ uint16(xMatch),
-	/*3938*/ uint16(xCondDataSize), 3926, 3932, 3942,
-	/*3942*/ uint16(xSetOp), uint16(CMOVG),
-	/*3944*/ uint16(xReadSlashR),
-	/*3945*/ uint16(xArgR64),
-	/*3946*/ uint16(xArgRM64),
-	/*3947*/ uint16(xMatch),
-	/*3948*/ uint16(xCondPrefix), 2,
-	0x66, 3960,
-	0x0, 3954,
-	/*3954*/ uint16(xSetOp), uint16(MOVMSKPS),
-	/*3956*/ uint16(xReadSlashR),
-	/*3957*/ uint16(xArgR32),
-	/*3958*/ uint16(xArgXmm2),
-	/*3959*/ uint16(xMatch),
-	/*3960*/ uint16(xSetOp), uint16(MOVMSKPD),
-	/*3962*/ uint16(xReadSlashR),
-	/*3963*/ uint16(xArgR32),
-	/*3964*/ uint16(xArgXmm2),
-	/*3965*/ uint16(xMatch),
-	/*3966*/ uint16(xCondPrefix), 4,
-	0xF3, 3994,
-	0xF2, 3988,
-	0x66, 3982,
-	0x0, 3976,
-	/*3976*/ uint16(xSetOp), uint16(SQRTPS),
-	/*3978*/ uint16(xReadSlashR),
-	/*3979*/ uint16(xArgXmm1),
-	/*3980*/ uint16(xArgXmm2M128),
-	/*3981*/ uint16(xMatch),
-	/*3982*/ uint16(xSetOp), uint16(SQRTPD),
-	/*3984*/ uint16(xReadSlashR),
-	/*3985*/ uint16(xArgXmm1),
-	/*3986*/ uint16(xArgXmm2M128),
-	/*3987*/ uint16(xMatch),
-	/*3988*/ uint16(xSetOp), uint16(SQRTSD),
-	/*3990*/ uint16(xReadSlashR),
-	/*3991*/ uint16(xArgXmm1),
-	/*3992*/ uint16(xArgXmm2M64),
-	/*3993*/ uint16(xMatch),
-	/*3994*/ uint16(xSetOp), uint16(SQRTSS),
-	/*3996*/ uint16(xReadSlashR),
-	/*3997*/ uint16(xArgXmm1),
-	/*3998*/ uint16(xArgXmm2M32),
-	/*3999*/ uint16(xMatch),
-	/*4000*/ uint16(xCondPrefix), 2,
-	0xF3, 4012,
-	0x0, 4006,
-	/*4006*/ uint16(xSetOp), uint16(RSQRTPS),
-	/*4008*/ uint16(xReadSlashR),
-	/*4009*/ uint16(xArgXmm1),
-	/*4010*/ uint16(xArgXmm2M128),
-	/*4011*/ uint16(xMatch),
-	/*4012*/ uint16(xSetOp), uint16(RSQRTSS),
-	/*4014*/ uint16(xReadSlashR),
-	/*4015*/ uint16(xArgXmm1),
-	/*4016*/ uint16(xArgXmm2M32),
-	/*4017*/ uint16(xMatch),
-	/*4018*/ uint16(xCondPrefix), 2,
-	0xF3, 4030,
-	0x0, 4024,
-	/*4024*/ uint16(xSetOp), uint16(RCPPS),
-	/*4026*/ uint16(xReadSlashR),
-	/*4027*/ uint16(xArgXmm1),
-	/*4028*/ uint16(xArgXmm2M128),
-	/*4029*/ uint16(xMatch),
-	/*4030*/ uint16(xSetOp), uint16(RCPSS),
-	/*4032*/ uint16(xReadSlashR),
-	/*4033*/ uint16(xArgXmm1),
-	/*4034*/ uint16(xArgXmm2M32),
-	/*4035*/ uint16(xMatch),
-	/*4036*/ uint16(xCondPrefix), 2,
-	0x66, 4048,
-	0x0, 4042,
-	/*4042*/ uint16(xSetOp), uint16(ANDPS),
-	/*4044*/ uint16(xReadSlashR),
-	/*4045*/ uint16(xArgXmm1),
-	/*4046*/ uint16(xArgXmm2M128),
-	/*4047*/ uint16(xMatch),
-	/*4048*/ uint16(xSetOp), uint16(ANDPD),
-	/*4050*/ uint16(xReadSlashR),
-	/*4051*/ uint16(xArgXmm1),
-	/*4052*/ uint16(xArgXmm2M128),
-	/*4053*/ uint16(xMatch),
-	/*4054*/ uint16(xCondPrefix), 2,
-	0x66, 4066,
-	0x0, 4060,
-	/*4060*/ uint16(xSetOp), uint16(ANDNPS),
-	/*4062*/ uint16(xReadSlashR),
-	/*4063*/ uint16(xArgXmm1),
-	/*4064*/ uint16(xArgXmm2M128),
-	/*4065*/ uint16(xMatch),
-	/*4066*/ uint16(xSetOp), uint16(ANDNPD),
-	/*4068*/ uint16(xReadSlashR),
-	/*4069*/ uint16(xArgXmm1),
-	/*4070*/ uint16(xArgXmm2M128),
-	/*4071*/ uint16(xMatch),
-	/*4072*/ uint16(xCondPrefix), 2,
-	0x66, 4084,
-	0x0, 4078,
-	/*4078*/ uint16(xSetOp), uint16(ORPS),
-	/*4080*/ uint16(xReadSlashR),
-	/*4081*/ uint16(xArgXmm1),
-	/*4082*/ uint16(xArgXmm2M128),
-	/*4083*/ uint16(xMatch),
-	/*4084*/ uint16(xSetOp), uint16(ORPD),
-	/*4086*/ uint16(xReadSlashR),
-	/*4087*/ uint16(xArgXmm1),
-	/*4088*/ uint16(xArgXmm2M128),
-	/*4089*/ uint16(xMatch),
-	/*4090*/ uint16(xCondPrefix), 2,
-	0x66, 4102,
-	0x0, 4096,
-	/*4096*/ uint16(xSetOp), uint16(XORPS),
-	/*4098*/ uint16(xReadSlashR),
-	/*4099*/ uint16(xArgXmm1),
-	/*4100*/ uint16(xArgXmm2M128),
-	/*4101*/ uint16(xMatch),
-	/*4102*/ uint16(xSetOp), uint16(XORPD),
-	/*4104*/ uint16(xReadSlashR),
-	/*4105*/ uint16(xArgXmm1),
-	/*4106*/ uint16(xArgXmm2M128),
-	/*4107*/ uint16(xMatch),
-	/*4108*/ uint16(xCondPrefix), 4,
-	0xF3, 4136,
-	0xF2, 4130,
-	0x66, 4124,
-	0x0, 4118,
-	/*4118*/ uint16(xSetOp), uint16(ADDPS),
-	/*4120*/ uint16(xReadSlashR),
-	/*4121*/ uint16(xArgXmm1),
-	/*4122*/ uint16(xArgXmm2M128),
-	/*4123*/ uint16(xMatch),
-	/*4124*/ uint16(xSetOp), uint16(ADDPD),
-	/*4126*/ uint16(xReadSlashR),
-	/*4127*/ uint16(xArgXmm1),
-	/*4128*/ uint16(xArgXmm2M128),
-	/*4129*/ uint16(xMatch),
-	/*4130*/ uint16(xSetOp), uint16(ADDSD),
-	/*4132*/ uint16(xReadSlashR),
-	/*4133*/ uint16(xArgXmm1),
-	/*4134*/ uint16(xArgXmm2M64),
-	/*4135*/ uint16(xMatch),
-	/*4136*/ uint16(xSetOp), uint16(ADDSS),
-	/*4138*/ uint16(xReadSlashR),
-	/*4139*/ uint16(xArgXmm1),
-	/*4140*/ uint16(xArgXmm2M32),
-	/*4141*/ uint16(xMatch),
-	/*4142*/ uint16(xCondPrefix), 4,
-	0xF3, 4170,
-	0xF2, 4164,
-	0x66, 4158,
-	0x0, 4152,
-	/*4152*/ uint16(xSetOp), uint16(MULPS),
-	/*4154*/ uint16(xReadSlashR),
-	/*4155*/ uint16(xArgXmm1),
-	/*4156*/ uint16(xArgXmm2M128),
-	/*4157*/ uint16(xMatch),
-	/*4158*/ uint16(xSetOp), uint16(MULPD),
-	/*4160*/ uint16(xReadSlashR),
-	/*4161*/ uint16(xArgXmm1),
-	/*4162*/ uint16(xArgXmm2M128),
-	/*4163*/ uint16(xMatch),
-	/*4164*/ uint16(xSetOp), uint16(MULSD),
-	/*4166*/ uint16(xReadSlashR),
-	/*4167*/ uint16(xArgXmm1),
-	/*4168*/ uint16(xArgXmm2M64),
-	/*4169*/ uint16(xMatch),
-	/*4170*/ uint16(xSetOp), uint16(MULSS),
-	/*4172*/ uint16(xReadSlashR),
-	/*4173*/ uint16(xArgXmm1),
-	/*4174*/ uint16(xArgXmm2M32),
-	/*4175*/ uint16(xMatch),
-	/*4176*/ uint16(xCondPrefix), 4,
-	0xF3, 4204,
-	0xF2, 4198,
-	0x66, 4192,
-	0x0, 4186,
-	/*4186*/ uint16(xSetOp), uint16(CVTPS2PD),
-	/*4188*/ uint16(xReadSlashR),
-	/*4189*/ uint16(xArgXmm1),
-	/*4190*/ uint16(xArgXmm2M64),
-	/*4191*/ uint16(xMatch),
-	/*4192*/ uint16(xSetOp), uint16(CVTPD2PS),
-	/*4194*/ uint16(xReadSlashR),
-	/*4195*/ uint16(xArgXmm1),
-	/*4196*/ uint16(xArgXmm2M128),
-	/*4197*/ uint16(xMatch),
-	/*4198*/ uint16(xSetOp), uint16(CVTSD2SS),
-	/*4200*/ uint16(xReadSlashR),
-	/*4201*/ uint16(xArgXmm1),
-	/*4202*/ uint16(xArgXmm2M64),
-	/*4203*/ uint16(xMatch),
-	/*4204*/ uint16(xSetOp), uint16(CVTSS2SD),
-	/*4206*/ uint16(xReadSlashR),
-	/*4207*/ uint16(xArgXmm1),
-	/*4208*/ uint16(xArgXmm2M32),
-	/*4209*/ uint16(xMatch),
-	/*4210*/ uint16(xCondPrefix), 3,
-	0xF3, 4230,
-	0x66, 4224,
-	0x0, 4218,
-	/*4218*/ uint16(xSetOp), uint16(CVTDQ2PS),
-	/*4220*/ uint16(xReadSlashR),
-	/*4221*/ uint16(xArgXmm1),
-	/*4222*/ uint16(xArgXmm2M128),
-	/*4223*/ uint16(xMatch),
-	/*4224*/ uint16(xSetOp), uint16(CVTPS2DQ),
-	/*4226*/ uint16(xReadSlashR),
-	/*4227*/ uint16(xArgXmm1),
-	/*4228*/ uint16(xArgXmm2M128),
-	/*4229*/ uint16(xMatch),
-	/*4230*/ uint16(xSetOp), uint16(CVTTPS2DQ),
-	/*4232*/ uint16(xReadSlashR),
-	/*4233*/ uint16(xArgXmm1),
-	/*4234*/ uint16(xArgXmm2M128),
-	/*4235*/ uint16(xMatch),
-	/*4236*/ uint16(xCondPrefix), 4,
-	0xF3, 4264,
-	0xF2, 4258,
-	0x66, 4252,
-	0x0, 4246,
-	/*4246*/ uint16(xSetOp), uint16(SUBPS),
-	/*4248*/ uint16(xReadSlashR),
-	/*4249*/ uint16(xArgXmm1),
-	/*4250*/ uint16(xArgXmm2M128),
-	/*4251*/ uint16(xMatch),
-	/*4252*/ uint16(xSetOp), uint16(SUBPD),
-	/*4254*/ uint16(xReadSlashR),
-	/*4255*/ uint16(xArgXmm1),
-	/*4256*/ uint16(xArgXmm2M128),
-	/*4257*/ uint16(xMatch),
-	/*4258*/ uint16(xSetOp), uint16(SUBSD),
-	/*4260*/ uint16(xReadSlashR),
-	/*4261*/ uint16(xArgXmm1),
-	/*4262*/ uint16(xArgXmm2M64),
-	/*4263*/ uint16(xMatch),
-	/*4264*/ uint16(xSetOp), uint16(SUBSS),
-	/*4266*/ uint16(xReadSlashR),
-	/*4267*/ uint16(xArgXmm1),
-	/*4268*/ uint16(xArgXmm2M32),
-	/*4269*/ uint16(xMatch),
-	/*4270*/ uint16(xCondPrefix), 4,
-	0xF3, 4298,
-	0xF2, 4292,
-	0x66, 4286,
-	0x0, 4280,
-	/*4280*/ uint16(xSetOp), uint16(MINPS),
-	/*4282*/ uint16(xReadSlashR),
-	/*4283*/ uint16(xArgXmm1),
-	/*4284*/ uint16(xArgXmm2M128),
-	/*4285*/ uint16(xMatch),
-	/*4286*/ uint16(xSetOp), uint16(MINPD),
-	/*4288*/ uint16(xReadSlashR),
-	/*4289*/ uint16(xArgXmm1),
-	/*4290*/ uint16(xArgXmm2M128),
-	/*4291*/ uint16(xMatch),
-	/*4292*/ uint16(xSetOp), uint16(MINSD),
-	/*4294*/ uint16(xReadSlashR),
-	/*4295*/ uint16(xArgXmm1),
-	/*4296*/ uint16(xArgXmm2M64),
-	/*4297*/ uint16(xMatch),
-	/*4298*/ uint16(xSetOp), uint16(MINSS),
-	/*4300*/ uint16(xReadSlashR),
-	/*4301*/ uint16(xArgXmm1),
-	/*4302*/ uint16(xArgXmm2M32),
-	/*4303*/ uint16(xMatch),
-	/*4304*/ uint16(xCondPrefix), 4,
-	0xF3, 4332,
-	0xF2, 4326,
-	0x66, 4320,
-	0x0, 4314,
-	/*4314*/ uint16(xSetOp), uint16(DIVPS),
-	/*4316*/ uint16(xReadSlashR),
-	/*4317*/ uint16(xArgXmm1),
-	/*4318*/ uint16(xArgXmm2M128),
-	/*4319*/ uint16(xMatch),
-	/*4320*/ uint16(xSetOp), uint16(DIVPD),
-	/*4322*/ uint16(xReadSlashR),
-	/*4323*/ uint16(xArgXmm1),
-	/*4324*/ uint16(xArgXmm2M128),
-	/*4325*/ uint16(xMatch),
-	/*4326*/ uint16(xSetOp), uint16(DIVSD),
-	/*4328*/ uint16(xReadSlashR),
-	/*4329*/ uint16(xArgXmm1),
-	/*4330*/ uint16(xArgXmm2M64),
-	/*4331*/ uint16(xMatch),
-	/*4332*/ uint16(xSetOp), uint16(DIVSS),
-	/*4334*/ uint16(xReadSlashR),
-	/*4335*/ uint16(xArgXmm1),
-	/*4336*/ uint16(xArgXmm2M32),
-	/*4337*/ uint16(xMatch),
-	/*4338*/ uint16(xCondPrefix), 4,
-	0xF3, 4366,
-	0xF2, 4360,
-	0x66, 4354,
-	0x0, 4348,
-	/*4348*/ uint16(xSetOp), uint16(MAXPS),
-	/*4350*/ uint16(xReadSlashR),
-	/*4351*/ uint16(xArgXmm1),
-	/*4352*/ uint16(xArgXmm2M128),
-	/*4353*/ uint16(xMatch),
-	/*4354*/ uint16(xSetOp), uint16(MAXPD),
-	/*4356*/ uint16(xReadSlashR),
-	/*4357*/ uint16(xArgXmm1),
-	/*4358*/ uint16(xArgXmm2M128),
-	/*4359*/ uint16(xMatch),
-	/*4360*/ uint16(xSetOp), uint16(MAXSD),
-	/*4362*/ uint16(xReadSlashR),
-	/*4363*/ uint16(xArgXmm1),
-	/*4364*/ uint16(xArgXmm2M64),
-	/*4365*/ uint16(xMatch),
-	/*4366*/ uint16(xSetOp), uint16(MAXSS),
-	/*4368*/ uint16(xReadSlashR),
-	/*4369*/ uint16(xArgXmm1),
-	/*4370*/ uint16(xArgXmm2M32),
-	/*4371*/ uint16(xMatch),
-	/*4372*/ uint16(xCondPrefix), 2,
-	0x66, 4384,
-	0x0, 4378,
-	/*4378*/ uint16(xSetOp), uint16(PUNPCKLBW),
-	/*4380*/ uint16(xReadSlashR),
-	/*4381*/ uint16(xArgMm),
-	/*4382*/ uint16(xArgMmM32),
-	/*4383*/ uint16(xMatch),
-	/*4384*/ uint16(xSetOp), uint16(PUNPCKLBW),
-	/*4386*/ uint16(xReadSlashR),
-	/*4387*/ uint16(xArgXmm1),
-	/*4388*/ uint16(xArgXmm2M128),
-	/*4389*/ uint16(xMatch),
-	/*4390*/ uint16(xCondPrefix), 2,
-	0x66, 4402,
-	0x0, 4396,
-	/*4396*/ uint16(xSetOp), uint16(PUNPCKLWD),
-	/*4398*/ uint16(xReadSlashR),
-	/*4399*/ uint16(xArgMm),
-	/*4400*/ uint16(xArgMmM32),
-	/*4401*/ uint16(xMatch),
-	/*4402*/ uint16(xSetOp), uint16(PUNPCKLWD),
-	/*4404*/ uint16(xReadSlashR),
-	/*4405*/ uint16(xArgXmm1),
-	/*4406*/ uint16(xArgXmm2M128),
-	/*4407*/ uint16(xMatch),
-	/*4408*/ uint16(xCondPrefix), 2,
-	0x66, 4420,
-	0x0, 4414,
-	/*4414*/ uint16(xSetOp), uint16(PUNPCKLDQ),
-	/*4416*/ uint16(xReadSlashR),
-	/*4417*/ uint16(xArgMm),
-	/*4418*/ uint16(xArgMmM32),
-	/*4419*/ uint16(xMatch),
-	/*4420*/ uint16(xSetOp), uint16(PUNPCKLDQ),
-	/*4422*/ uint16(xReadSlashR),
-	/*4423*/ uint16(xArgXmm1),
-	/*4424*/ uint16(xArgXmm2M128),
-	/*4425*/ uint16(xMatch),
-	/*4426*/ uint16(xCondPrefix), 2,
-	0x66, 4438,
-	0x0, 4432,
-	/*4432*/ uint16(xSetOp), uint16(PACKSSWB),
-	/*4434*/ uint16(xReadSlashR),
-	/*4435*/ uint16(xArgMm1),
-	/*4436*/ uint16(xArgMm2M64),
-	/*4437*/ uint16(xMatch),
-	/*4438*/ uint16(xSetOp), uint16(PACKSSWB),
-	/*4440*/ uint16(xReadSlashR),
-	/*4441*/ uint16(xArgXmm1),
-	/*4442*/ uint16(xArgXmm2M128),
-	/*4443*/ uint16(xMatch),
-	/*4444*/ uint16(xCondPrefix), 2,
-	0x66, 4456,
-	0x0, 4450,
-	/*4450*/ uint16(xSetOp), uint16(PCMPGTB),
-	/*4452*/ uint16(xReadSlashR),
-	/*4453*/ uint16(xArgMm),
-	/*4454*/ uint16(xArgMmM64),
-	/*4455*/ uint16(xMatch),
-	/*4456*/ uint16(xSetOp), uint16(PCMPGTB),
-	/*4458*/ uint16(xReadSlashR),
-	/*4459*/ uint16(xArgXmm1),
-	/*4460*/ uint16(xArgXmm2M128),
-	/*4461*/ uint16(xMatch),
-	/*4462*/ uint16(xCondPrefix), 2,
-	0x66, 4474,
-	0x0, 4468,
-	/*4468*/ uint16(xSetOp), uint16(PCMPGTW),
-	/*4470*/ uint16(xReadSlashR),
-	/*4471*/ uint16(xArgMm),
-	/*4472*/ uint16(xArgMmM64),
-	/*4473*/ uint16(xMatch),
-	/*4474*/ uint16(xSetOp), uint16(PCMPGTW),
-	/*4476*/ uint16(xReadSlashR),
-	/*4477*/ uint16(xArgXmm1),
-	/*4478*/ uint16(xArgXmm2M128),
-	/*4479*/ uint16(xMatch),
-	/*4480*/ uint16(xCondPrefix), 2,
-	0x66, 4492,
-	0x0, 4486,
-	/*4486*/ uint16(xSetOp), uint16(PCMPGTD),
-	/*4488*/ uint16(xReadSlashR),
-	/*4489*/ uint16(xArgMm),
-	/*4490*/ uint16(xArgMmM64),
-	/*4491*/ uint16(xMatch),
-	/*4492*/ uint16(xSetOp), uint16(PCMPGTD),
-	/*4494*/ uint16(xReadSlashR),
-	/*4495*/ uint16(xArgXmm1),
-	/*4496*/ uint16(xArgXmm2M128),
-	/*4497*/ uint16(xMatch),
-	/*4498*/ uint16(xCondPrefix), 2,
-	0x66, 4510,
-	0x0, 4504,
-	/*4504*/ uint16(xSetOp), uint16(PACKUSWB),
-	/*4506*/ uint16(xReadSlashR),
-	/*4507*/ uint16(xArgMm),
-	/*4508*/ uint16(xArgMmM64),
-	/*4509*/ uint16(xMatch),
-	/*4510*/ uint16(xSetOp), uint16(PACKUSWB),
-	/*4512*/ uint16(xReadSlashR),
-	/*4513*/ uint16(xArgXmm1),
-	/*4514*/ uint16(xArgXmm2M128),
-	/*4515*/ uint16(xMatch),
-	/*4516*/ uint16(xCondPrefix), 2,
-	0x66, 4528,
-	0x0, 4522,
-	/*4522*/ uint16(xSetOp), uint16(PUNPCKHBW),
-	/*4524*/ uint16(xReadSlashR),
-	/*4525*/ uint16(xArgMm),
-	/*4526*/ uint16(xArgMmM64),
-	/*4527*/ uint16(xMatch),
-	/*4528*/ uint16(xSetOp), uint16(PUNPCKHBW),
-	/*4530*/ uint16(xReadSlashR),
-	/*4531*/ uint16(xArgXmm1),
-	/*4532*/ uint16(xArgXmm2M128),
-	/*4533*/ uint16(xMatch),
-	/*4534*/ uint16(xCondPrefix), 2,
-	0x66, 4546,
-	0x0, 4540,
-	/*4540*/ uint16(xSetOp), uint16(PUNPCKHWD),
-	/*4542*/ uint16(xReadSlashR),
-	/*4543*/ uint16(xArgMm),
-	/*4544*/ uint16(xArgMmM64),
-	/*4545*/ uint16(xMatch),
-	/*4546*/ uint16(xSetOp), uint16(PUNPCKHWD),
-	/*4548*/ uint16(xReadSlashR),
-	/*4549*/ uint16(xArgXmm1),
-	/*4550*/ uint16(xArgXmm2M128),
-	/*4551*/ uint16(xMatch),
-	/*4552*/ uint16(xCondPrefix), 2,
-	0x66, 4564,
-	0x0, 4558,
-	/*4558*/ uint16(xSetOp), uint16(PUNPCKHDQ),
-	/*4560*/ uint16(xReadSlashR),
-	/*4561*/ uint16(xArgMm),
-	/*4562*/ uint16(xArgMmM64),
-	/*4563*/ uint16(xMatch),
-	/*4564*/ uint16(xSetOp), uint16(PUNPCKHDQ),
-	/*4566*/ uint16(xReadSlashR),
-	/*4567*/ uint16(xArgXmm1),
-	/*4568*/ uint16(xArgXmm2M128),
-	/*4569*/ uint16(xMatch),
-	/*4570*/ uint16(xCondPrefix), 2,
-	0x66, 4582,
-	0x0, 4576,
-	/*4576*/ uint16(xSetOp), uint16(PACKSSDW),
-	/*4578*/ uint16(xReadSlashR),
-	/*4579*/ uint16(xArgMm1),
-	/*4580*/ uint16(xArgMm2M64),
-	/*4581*/ uint16(xMatch),
-	/*4582*/ uint16(xSetOp), uint16(PACKSSDW),
-	/*4584*/ uint16(xReadSlashR),
-	/*4585*/ uint16(xArgXmm1),
-	/*4586*/ uint16(xArgXmm2M128),
-	/*4587*/ uint16(xMatch),
-	/*4588*/ uint16(xCondPrefix), 1,
-	0x66, 4592,
-	/*4592*/ uint16(xSetOp), uint16(PUNPCKLQDQ),
-	/*4594*/ uint16(xReadSlashR),
-	/*4595*/ uint16(xArgXmm1),
-	/*4596*/ uint16(xArgXmm2M128),
-	/*4597*/ uint16(xMatch),
-	/*4598*/ uint16(xCondPrefix), 1,
-	0x66, 4602,
-	/*4602*/ uint16(xSetOp), uint16(PUNPCKHQDQ),
-	/*4604*/ uint16(xReadSlashR),
-	/*4605*/ uint16(xArgXmm1),
-	/*4606*/ uint16(xArgXmm2M128),
-	/*4607*/ uint16(xMatch),
-	/*4608*/ uint16(xCondIs64), 4611, 4649,
-	/*4611*/ uint16(xCondPrefix), 2,
-	0x66, 4633,
-	0x0, 4617,
-	/*4617*/ uint16(xCondDataSize), 4621, 4627, 0,
-	/*4621*/ uint16(xSetOp), uint16(MOVD),
-	/*4623*/ uint16(xReadSlashR),
-	/*4624*/ uint16(xArgMm),
-	/*4625*/ uint16(xArgRM32),
-	/*4626*/ uint16(xMatch),
-	/*4627*/ uint16(xSetOp), uint16(MOVD),
-	/*4629*/ uint16(xReadSlashR),
-	/*4630*/ uint16(xArgMm),
-	/*4631*/ uint16(xArgRM32),
-	/*4632*/ uint16(xMatch),
-	/*4633*/ uint16(xCondDataSize), 4637, 4643, 0,
-	/*4637*/ uint16(xSetOp), uint16(MOVD),
-	/*4639*/ uint16(xReadSlashR),
-	/*4640*/ uint16(xArgXmm),
-	/*4641*/ uint16(xArgRM32),
-	/*4642*/ uint16(xMatch),
-	/*4643*/ uint16(xSetOp), uint16(MOVD),
-	/*4645*/ uint16(xReadSlashR),
-	/*4646*/ uint16(xArgXmm),
-	/*4647*/ uint16(xArgRM32),
-	/*4648*/ uint16(xMatch),
-	/*4649*/ uint16(xCondPrefix), 2,
-	0x66, 4665,
-	0x0, 4655,
-	/*4655*/ uint16(xCondDataSize), 4621, 4627, 4659,
-	/*4659*/ uint16(xSetOp), uint16(MOVQ),
-	/*4661*/ uint16(xReadSlashR),
-	/*4662*/ uint16(xArgMm),
-	/*4663*/ uint16(xArgRM64),
-	/*4664*/ uint16(xMatch),
-	/*4665*/ uint16(xCondDataSize), 4637, 4643, 4669,
-	/*4669*/ uint16(xSetOp), uint16(MOVQ),
-	/*4671*/ uint16(xReadSlashR),
-	/*4672*/ uint16(xArgXmm),
-	/*4673*/ uint16(xArgRM64),
-	/*4674*/ uint16(xMatch),
-	/*4675*/ uint16(xCondPrefix), 3,
-	0xF3, 4695,
-	0x66, 4689,
-	0x0, 4683,
-	/*4683*/ uint16(xSetOp), uint16(MOVQ),
-	/*4685*/ uint16(xReadSlashR),
-	/*4686*/ uint16(xArgMm),
-	/*4687*/ uint16(xArgMmM64),
-	/*4688*/ uint16(xMatch),
-	/*4689*/ uint16(xSetOp), uint16(MOVDQA),
-	/*4691*/ uint16(xReadSlashR),
-	/*4692*/ uint16(xArgXmm1),
-	/*4693*/ uint16(xArgXmm2M128),
-	/*4694*/ uint16(xMatch),
-	/*4695*/ uint16(xSetOp), uint16(MOVDQU),
-	/*4697*/ uint16(xReadSlashR),
-	/*4698*/ uint16(xArgXmm1),
-	/*4699*/ uint16(xArgXmm2M128),
-	/*4700*/ uint16(xMatch),
-	/*4701*/ uint16(xCondPrefix), 4,
-	0xF3, 4735,
-	0xF2, 4727,
-	0x66, 4719,
-	0x0, 4711,
-	/*4711*/ uint16(xSetOp), uint16(PSHUFW),
-	/*4713*/ uint16(xReadSlashR),
-	/*4714*/ uint16(xReadIb),
-	/*4715*/ uint16(xArgMm1),
-	/*4716*/ uint16(xArgMm2M64),
-	/*4717*/ uint16(xArgImm8u),
-	/*4718*/ uint16(xMatch),
-	/*4719*/ uint16(xSetOp), uint16(PSHUFD),
-	/*4721*/ uint16(xReadSlashR),
-	/*4722*/ uint16(xReadIb),
-	/*4723*/ uint16(xArgXmm1),
-	/*4724*/ uint16(xArgXmm2M128),
-	/*4725*/ uint16(xArgImm8u),
-	/*4726*/ uint16(xMatch),
-	/*4727*/ uint16(xSetOp), uint16(PSHUFLW),
-	/*4729*/ uint16(xReadSlashR),
-	/*4730*/ uint16(xReadIb),
-	/*4731*/ uint16(xArgXmm1),
-	/*4732*/ uint16(xArgXmm2M128),
-	/*4733*/ uint16(xArgImm8u),
-	/*4734*/ uint16(xMatch),
-	/*4735*/ uint16(xSetOp), uint16(PSHUFHW),
-	/*4737*/ uint16(xReadSlashR),
-	/*4738*/ uint16(xReadIb),
-	/*4739*/ uint16(xArgXmm1),
-	/*4740*/ uint16(xArgXmm2M128),
-	/*4741*/ uint16(xArgImm8u),
-	/*4742*/ uint16(xMatch),
-	/*4743*/ uint16(xCondSlashR),
+	/*3126*/ uint16(xCondPrefix), 1,
+	0x66, 3130,
+	/*3130*/ uint16(xSetOp), uint16(ROUNDPS),
+	/*3132*/ uint16(xReadSlashR),
+	/*3133*/ uint16(xReadIb),
+	/*3134*/ uint16(xArgXmm1),
+	/*3135*/ uint16(xArgXmm2M128),
+	/*3136*/ uint16(xArgImm8u),
+	/*3137*/ uint16(xMatch),
+	/*3138*/ uint16(xCondPrefix), 1,
+	0x66, 3142,
+	/*3142*/ uint16(xSetOp), uint16(ROUNDPD),
+	/*3144*/ uint16(xReadSlashR),
+	/*3145*/ uint16(xReadIb),
+	/*3146*/ uint16(xArgXmm1),
+	/*3147*/ uint16(xArgXmm2M128),
+	/*3148*/ uint16(xArgImm8u),
+	/*3149*/ uint16(xMatch),
+	/*3150*/ uint16(xCondPrefix), 1,
+	0x66, 3154,
+	/*3154*/ uint16(xSetOp), uint16(ROUNDSS),
+	/*3156*/ uint16(xReadSlashR),
+	/*3157*/ uint16(xReadIb),
+	/*3158*/ uint16(xArgXmm1),
+	/*3159*/ uint16(xArgXmm2M32),
+	/*3160*/ uint16(xArgImm8u),
+	/*3161*/ uint16(xMatch),
+	/*3162*/ uint16(xCondPrefix), 1,
+	0x66, 3166,
+	/*3166*/ uint16(xSetOp), uint16(ROUNDSD),
+	/*3168*/ uint16(xReadSlashR),
+	/*3169*/ uint16(xReadIb),
+	/*3170*/ uint16(xArgXmm1),
+	/*3171*/ uint16(xArgXmm2M64),
+	/*3172*/ uint16(xArgImm8u),
+	/*3173*/ uint16(xMatch),
+	/*3174*/ uint16(xCondPrefix), 1,
+	0x66, 3178,
+	/*3178*/ uint16(xSetOp), uint16(BLENDPS),
+	/*3180*/ uint16(xReadSlashR),
+	/*3181*/ uint16(xReadIb),
+	/*3182*/ uint16(xArgXmm1),
+	/*3183*/ uint16(xArgXmm2M128),
+	/*3184*/ uint16(xArgImm8u),
+	/*3185*/ uint16(xMatch),
+	/*3186*/ uint16(xCondPrefix), 1,
+	0x66, 3190,
+	/*3190*/ uint16(xSetOp), uint16(BLENDPD),
+	/*3192*/ uint16(xReadSlashR),
+	/*3193*/ uint16(xReadIb),
+	/*3194*/ uint16(xArgXmm1),
+	/*3195*/ uint16(xArgXmm2M128),
+	/*3196*/ uint16(xArgImm8u),
+	/*3197*/ uint16(xMatch),
+	/*3198*/ uint16(xCondPrefix), 1,
+	0x66, 3202,
+	/*3202*/ uint16(xSetOp), uint16(PBLENDW),
+	/*3204*/ uint16(xReadSlashR),
+	/*3205*/ uint16(xReadIb),
+	/*3206*/ uint16(xArgXmm1),
+	/*3207*/ uint16(xArgXmm2M128),
+	/*3208*/ uint16(xArgImm8u),
+	/*3209*/ uint16(xMatch),
+	/*3210*/ uint16(xCondPrefix), 2,
+	0x66, 3224,
+	0x0, 3216,
+	/*3216*/ uint16(xSetOp), uint16(PALIGNR),
+	/*3218*/ uint16(xReadSlashR),
+	/*3219*/ uint16(xReadIb),
+	/*3220*/ uint16(xArgMm1),
+	/*3221*/ uint16(xArgMm2M64),
+	/*3222*/ uint16(xArgImm8u),
+	/*3223*/ uint16(xMatch),
+	/*3224*/ uint16(xSetOp), uint16(PALIGNR),
+	/*3226*/ uint16(xReadSlashR),
+	/*3227*/ uint16(xReadIb),
+	/*3228*/ uint16(xArgXmm1),
+	/*3229*/ uint16(xArgXmm2M128),
+	/*3230*/ uint16(xArgImm8u),
+	/*3231*/ uint16(xMatch),
+	/*3232*/ uint16(xCondPrefix), 1,
+	0x66, 3236,
+	/*3236*/ uint16(xSetOp), uint16(PEXTRB),
+	/*3238*/ uint16(xReadSlashR),
+	/*3239*/ uint16(xReadIb),
+	/*3240*/ uint16(xArgR32M8),
+	/*3241*/ uint16(xArgXmm1),
+	/*3242*/ uint16(xArgImm8u),
+	/*3243*/ uint16(xMatch),
+	/*3244*/ uint16(xCondPrefix), 1,
+	0x66, 3248,
+	/*3248*/ uint16(xSetOp), uint16(PEXTRW),
+	/*3250*/ uint16(xReadSlashR),
+	/*3251*/ uint16(xReadIb),
+	/*3252*/ uint16(xArgR32M16),
+	/*3253*/ uint16(xArgXmm1),
+	/*3254*/ uint16(xArgImm8u),
+	/*3255*/ uint16(xMatch),
+	/*3256*/ uint16(xCondIs64), 3259, 3283,
+	/*3259*/ uint16(xCondPrefix), 1,
+	0x66, 3263,
+	/*3263*/ uint16(xCondDataSize), 3267, 3275, 0,
+	/*3267*/ uint16(xSetOp), uint16(PEXTRD),
+	/*3269*/ uint16(xReadSlashR),
+	/*3270*/ uint16(xReadIb),
+	/*3271*/ uint16(xArgRM32),
+	/*3272*/ uint16(xArgXmm1),
+	/*3273*/ uint16(xArgImm8u),
+	/*3274*/ uint16(xMatch),
+	/*3275*/ uint16(xSetOp), uint16(PEXTRD),
+	/*3277*/ uint16(xReadSlashR),
+	/*3278*/ uint16(xReadIb),
+	/*3279*/ uint16(xArgRM32),
+	/*3280*/ uint16(xArgXmm1),
+	/*3281*/ uint16(xArgImm8u),
+	/*3282*/ uint16(xMatch),
+	/*3283*/ uint16(xCondPrefix), 1,
+	0x66, 3287,
+	/*3287*/ uint16(xCondDataSize), 3267, 3275, 3291,
+	/*3291*/ uint16(xSetOp), uint16(PEXTRQ),
+	/*3293*/ uint16(xReadSlashR),
+	/*3294*/ uint16(xReadIb),
+	/*3295*/ uint16(xArgRM64),
+	/*3296*/ uint16(xArgXmm1),
+	/*3297*/ uint16(xArgImm8u),
+	/*3298*/ uint16(xMatch),
+	/*3299*/ uint16(xCondPrefix), 1,
+	0x66, 3303,
+	/*3303*/ uint16(xSetOp), uint16(EXTRACTPS),
+	/*3305*/ uint16(xReadSlashR),
+	/*3306*/ uint16(xReadIb),
+	/*3307*/ uint16(xArgRM32),
+	/*3308*/ uint16(xArgXmm1),
+	/*3309*/ uint16(xArgImm8u),
+	/*3310*/ uint16(xMatch),
+	/*3311*/ uint16(xCondPrefix), 1,
+	0x66, 3315,
+	/*3315*/ uint16(xSetOp), uint16(PINSRB),
+	/*3317*/ uint16(xReadSlashR),
+	/*3318*/ uint16(xReadIb),
+	/*3319*/ uint16(xArgXmm1),
+	/*3320*/ uint16(xArgR32M8),
+	/*3321*/ uint16(xArgImm8u),
+	/*3322*/ uint16(xMatch),
+	/*3323*/ uint16(xCondPrefix), 1,
+	0x66, 3327,
+	/*3327*/ uint16(xSetOp), uint16(INSERTPS),
+	/*3329*/ uint16(xReadSlashR),
+	/*3330*/ uint16(xReadIb),
+	/*3331*/ uint16(xArgXmm1),
+	/*3332*/ uint16(xArgXmm2M32),
+	/*3333*/ uint16(xArgImm8u),
+	/*3334*/ uint16(xMatch),
+	/*3335*/ uint16(xCondIs64), 3338, 3362,
+	/*3338*/ uint16(xCondPrefix), 1,
+	0x66, 3342,
+	/*3342*/ uint16(xCondDataSize), 3346, 3354, 0,
+	/*3346*/ uint16(xSetOp), uint16(PINSRD),
+	/*3348*/ uint16(xReadSlashR),
+	/*3349*/ uint16(xReadIb),
+	/*3350*/ uint16(xArgXmm1),
+	/*3351*/ uint16(xArgRM32),
+	/*3352*/ uint16(xArgImm8u),
+	/*3353*/ uint16(xMatch),
+	/*3354*/ uint16(xSetOp), uint16(PINSRD),
+	/*3356*/ uint16(xReadSlashR),
+	/*3357*/ uint16(xReadIb),
+	/*3358*/ uint16(xArgXmm1),
+	/*3359*/ uint16(xArgRM32),
+	/*3360*/ uint16(xArgImm8u),
+	/*3361*/ uint16(xMatch),
+	/*3362*/ uint16(xCondPrefix), 1,
+	0x66, 3366,
+	/*3366*/ uint16(xCondDataSize), 3346, 3354, 3370,
+	/*3370*/ uint16(xSetOp), uint16(PINSRQ),
+	/*3372*/ uint16(xReadSlashR),
+	/*3373*/ uint16(xReadIb),
+	/*3374*/ uint16(xArgXmm1),
+	/*3375*/ uint16(xArgRM64),
+	/*3376*/ uint16(xArgImm8u),
+	/*3377*/ uint16(xMatch),
+	/*3378*/ uint16(xCondPrefix), 1,
+	0x66, 3382,
+	/*3382*/ uint16(xSetOp), uint16(DPPS),
+	/*3384*/ uint16(xReadSlashR),
+	/*3385*/ uint16(xReadIb),
+	/*3386*/ uint16(xArgXmm1),
+	/*3387*/ uint16(xArgXmm2M128),
+	/*3388*/ uint16(xArgImm8u),
+	/*3389*/ uint16(xMatch),
+	/*3390*/ uint16(xCondPrefix), 1,
+	0x66, 3394,
+	/*3394*/ uint16(xSetOp), uint16(DPPD),
+	/*3396*/ uint16(xReadSlashR),
+	/*3397*/ uint16(xReadIb),
+	/*3398*/ uint16(xArgXmm1),
+	/*3399*/ uint16(xArgXmm2M128),
+	/*3400*/ uint16(xArgImm8u),
+	/*3401*/ uint16(xMatch),
+	/*3402*/ uint16(xCondPrefix), 1,
+	0x66, 3406,
+	/*3406*/ uint16(xSetOp), uint16(MPSADBW),
+	/*3408*/ uint16(xReadSlashR),
+	/*3409*/ uint16(xReadIb),
+	/*3410*/ uint16(xArgXmm1),
+	/*3411*/ uint16(xArgXmm2M128),
+	/*3412*/ uint16(xArgImm8u),
+	/*3413*/ uint16(xMatch),
+	/*3414*/ uint16(xCondPrefix), 1,
+	0x66, 3418,
+	/*3418*/ uint16(xSetOp), uint16(PCLMULQDQ),
+	/*3420*/ uint16(xReadSlashR),
+	/*3421*/ uint16(xReadIb),
+	/*3422*/ uint16(xArgXmm1),
+	/*3423*/ uint16(xArgXmm2M128),
+	/*3424*/ uint16(xArgImm8u),
+	/*3425*/ uint16(xMatch),
+	/*3426*/ uint16(xCondPrefix), 1,
+	0x66, 3430,
+	/*3430*/ uint16(xSetOp), uint16(PCMPESTRM),
+	/*3432*/ uint16(xReadSlashR),
+	/*3433*/ uint16(xReadIb),
+	/*3434*/ uint16(xArgXmm1),
+	/*3435*/ uint16(xArgXmm2M128),
+	/*3436*/ uint16(xArgImm8u),
+	/*3437*/ uint16(xMatch),
+	/*3438*/ uint16(xCondPrefix), 1,
+	0x66, 3442,
+	/*3442*/ uint16(xSetOp), uint16(PCMPESTRI),
+	/*3444*/ uint16(xReadSlashR),
+	/*3445*/ uint16(xReadIb),
+	/*3446*/ uint16(xArgXmm1),
+	/*3447*/ uint16(xArgXmm2M128),
+	/*3448*/ uint16(xArgImm8u),
+	/*3449*/ uint16(xMatch),
+	/*3450*/ uint16(xCondPrefix), 1,
+	0x66, 3454,
+	/*3454*/ uint16(xSetOp), uint16(PCMPISTRM),
+	/*3456*/ uint16(xReadSlashR),
+	/*3457*/ uint16(xReadIb),
+	/*3458*/ uint16(xArgXmm1),
+	/*3459*/ uint16(xArgXmm2M128),
+	/*3460*/ uint16(xArgImm8u),
+	/*3461*/ uint16(xMatch),
+	/*3462*/ uint16(xCondPrefix), 1,
+	0x66, 3466,
+	/*3466*/ uint16(xSetOp), uint16(PCMPISTRI),
+	/*3468*/ uint16(xReadSlashR),
+	/*3469*/ uint16(xReadIb),
+	/*3470*/ uint16(xArgXmm1),
+	/*3471*/ uint16(xArgXmm2M128),
+	/*3472*/ uint16(xArgImm8u),
+	/*3473*/ uint16(xMatch),
+	/*3474*/ uint16(xCondPrefix), 1,
+	0x66, 3478,
+	/*3478*/ uint16(xSetOp), uint16(AESKEYGENASSIST),
+	/*3480*/ uint16(xReadSlashR),
+	/*3481*/ uint16(xReadIb),
+	/*3482*/ uint16(xArgXmm1),
+	/*3483*/ uint16(xArgXmm2M128),
+	/*3484*/ uint16(xArgImm8u),
+	/*3485*/ uint16(xMatch),
+	/*3486*/ uint16(xCondIs64), 3489, 3505,
+	/*3489*/ uint16(xCondDataSize), 3493, 3499, 0,
+	/*3493*/ uint16(xSetOp), uint16(CMOVO),
+	/*3495*/ uint16(xReadSlashR),
+	/*3496*/ uint16(xArgR16),
+	/*3497*/ uint16(xArgRM16),
+	/*3498*/ uint16(xMatch),
+	/*3499*/ uint16(xSetOp), uint16(CMOVO),
+	/*3501*/ uint16(xReadSlashR),
+	/*3502*/ uint16(xArgR32),
+	/*3503*/ uint16(xArgRM32),
+	/*3504*/ uint16(xMatch),
+	/*3505*/ uint16(xCondDataSize), 3493, 3499, 3509,
+	/*3509*/ uint16(xSetOp), uint16(CMOVO),
+	/*3511*/ uint16(xReadSlashR),
+	/*3512*/ uint16(xArgR64),
+	/*3513*/ uint16(xArgRM64),
+	/*3514*/ uint16(xMatch),
+	/*3515*/ uint16(xCondIs64), 3518, 3534,
+	/*3518*/ uint16(xCondDataSize), 3522, 3528, 0,
+	/*3522*/ uint16(xSetOp), uint16(CMOVNO),
+	/*3524*/ uint16(xReadSlashR),
+	/*3525*/ uint16(xArgR16),
+	/*3526*/ uint16(xArgRM16),
+	/*3527*/ uint16(xMatch),
+	/*3528*/ uint16(xSetOp), uint16(CMOVNO),
+	/*3530*/ uint16(xReadSlashR),
+	/*3531*/ uint16(xArgR32),
+	/*3532*/ uint16(xArgRM32),
+	/*3533*/ uint16(xMatch),
+	/*3534*/ uint16(xCondDataSize), 3522, 3528, 3538,
+	/*3538*/ uint16(xSetOp), uint16(CMOVNO),
+	/*3540*/ uint16(xReadSlashR),
+	/*3541*/ uint16(xArgR64),
+	/*3542*/ uint16(xArgRM64),
+	/*3543*/ uint16(xMatch),
+	/*3544*/ uint16(xCondIs64), 3547, 3563,
+	/*3547*/ uint16(xCondDataSize), 3551, 3557, 0,
+	/*3551*/ uint16(xSetOp), uint16(CMOVB),
+	/*3553*/ uint16(xReadSlashR),
+	/*3554*/ uint16(xArgR16),
+	/*3555*/ uint16(xArgRM16),
+	/*3556*/ uint16(xMatch),
+	/*3557*/ uint16(xSetOp), uint16(CMOVB),
+	/*3559*/ uint16(xReadSlashR),
+	/*3560*/ uint16(xArgR32),
+	/*3561*/ uint16(xArgRM32),
+	/*3562*/ uint16(xMatch),
+	/*3563*/ uint16(xCondDataSize), 3551, 3557, 3567,
+	/*3567*/ uint16(xSetOp), uint16(CMOVB),
+	/*3569*/ uint16(xReadSlashR),
+	/*3570*/ uint16(xArgR64),
+	/*3571*/ uint16(xArgRM64),
+	/*3572*/ uint16(xMatch),
+	/*3573*/ uint16(xCondIs64), 3576, 3592,
+	/*3576*/ uint16(xCondDataSize), 3580, 3586, 0,
+	/*3580*/ uint16(xSetOp), uint16(CMOVAE),
+	/*3582*/ uint16(xReadSlashR),
+	/*3583*/ uint16(xArgR16),
+	/*3584*/ uint16(xArgRM16),
+	/*3585*/ uint16(xMatch),
+	/*3586*/ uint16(xSetOp), uint16(CMOVAE),
+	/*3588*/ uint16(xReadSlashR),
+	/*3589*/ uint16(xArgR32),
+	/*3590*/ uint16(xArgRM32),
+	/*3591*/ uint16(xMatch),
+	/*3592*/ uint16(xCondDataSize), 3580, 3586, 3596,
+	/*3596*/ uint16(xSetOp), uint16(CMOVAE),
+	/*3598*/ uint16(xReadSlashR),
+	/*3599*/ uint16(xArgR64),
+	/*3600*/ uint16(xArgRM64),
+	/*3601*/ uint16(xMatch),
+	/*3602*/ uint16(xCondIs64), 3605, 3621,
+	/*3605*/ uint16(xCondDataSize), 3609, 3615, 0,
+	/*3609*/ uint16(xSetOp), uint16(CMOVE),
+	/*3611*/ uint16(xReadSlashR),
+	/*3612*/ uint16(xArgR16),
+	/*3613*/ uint16(xArgRM16),
+	/*3614*/ uint16(xMatch),
+	/*3615*/ uint16(xSetOp), uint16(CMOVE),
+	/*3617*/ uint16(xReadSlashR),
+	/*3618*/ uint16(xArgR32),
+	/*3619*/ uint16(xArgRM32),
+	/*3620*/ uint16(xMatch),
+	/*3621*/ uint16(xCondDataSize), 3609, 3615, 3625,
+	/*3625*/ uint16(xSetOp), uint16(CMOVE),
+	/*3627*/ uint16(xReadSlashR),
+	/*3628*/ uint16(xArgR64),
+	/*3629*/ uint16(xArgRM64),
+	/*3630*/ uint16(xMatch),
+	/*3631*/ uint16(xCondIs64), 3634, 3650,
+	/*3634*/ uint16(xCondDataSize), 3638, 3644, 0,
+	/*3638*/ uint16(xSetOp), uint16(CMOVNE),
+	/*3640*/ uint16(xReadSlashR),
+	/*3641*/ uint16(xArgR16),
+	/*3642*/ uint16(xArgRM16),
+	/*3643*/ uint16(xMatch),
+	/*3644*/ uint16(xSetOp), uint16(CMOVNE),
+	/*3646*/ uint16(xReadSlashR),
+	/*3647*/ uint16(xArgR32),
+	/*3648*/ uint16(xArgRM32),
+	/*3649*/ uint16(xMatch),
+	/*3650*/ uint16(xCondDataSize), 3638, 3644, 3654,
+	/*3654*/ uint16(xSetOp), uint16(CMOVNE),
+	/*3656*/ uint16(xReadSlashR),
+	/*3657*/ uint16(xArgR64),
+	/*3658*/ uint16(xArgRM64),
+	/*3659*/ uint16(xMatch),
+	/*3660*/ uint16(xCondIs64), 3663, 3679,
+	/*3663*/ uint16(xCondDataSize), 3667, 3673, 0,
+	/*3667*/ uint16(xSetOp), uint16(CMOVBE),
+	/*3669*/ uint16(xReadSlashR),
+	/*3670*/ uint16(xArgR16),
+	/*3671*/ uint16(xArgRM16),
+	/*3672*/ uint16(xMatch),
+	/*3673*/ uint16(xSetOp), uint16(CMOVBE),
+	/*3675*/ uint16(xReadSlashR),
+	/*3676*/ uint16(xArgR32),
+	/*3677*/ uint16(xArgRM32),
+	/*3678*/ uint16(xMatch),
+	/*3679*/ uint16(xCondDataSize), 3667, 3673, 3683,
+	/*3683*/ uint16(xSetOp), uint16(CMOVBE),
+	/*3685*/ uint16(xReadSlashR),
+	/*3686*/ uint16(xArgR64),
+	/*3687*/ uint16(xArgRM64),
+	/*3688*/ uint16(xMatch),
+	/*3689*/ uint16(xCondIs64), 3692, 3708,
+	/*3692*/ uint16(xCondDataSize), 3696, 3702, 0,
+	/*3696*/ uint16(xSetOp), uint16(CMOVA),
+	/*3698*/ uint16(xReadSlashR),
+	/*3699*/ uint16(xArgR16),
+	/*3700*/ uint16(xArgRM16),
+	/*3701*/ uint16(xMatch),
+	/*3702*/ uint16(xSetOp), uint16(CMOVA),
+	/*3704*/ uint16(xReadSlashR),
+	/*3705*/ uint16(xArgR32),
+	/*3706*/ uint16(xArgRM32),
+	/*3707*/ uint16(xMatch),
+	/*3708*/ uint16(xCondDataSize), 3696, 3702, 3712,
+	/*3712*/ uint16(xSetOp), uint16(CMOVA),
+	/*3714*/ uint16(xReadSlashR),
+	/*3715*/ uint16(xArgR64),
+	/*3716*/ uint16(xArgRM64),
+	/*3717*/ uint16(xMatch),
+	/*3718*/ uint16(xCondIs64), 3721, 3737,
+	/*3721*/ uint16(xCondDataSize), 3725, 3731, 0,
+	/*3725*/ uint16(xSetOp), uint16(CMOVS),
+	/*3727*/ uint16(xReadSlashR),
+	/*3728*/ uint16(xArgR16),
+	/*3729*/ uint16(xArgRM16),
+	/*3730*/ uint16(xMatch),
+	/*3731*/ uint16(xSetOp), uint16(CMOVS),
+	/*3733*/ uint16(xReadSlashR),
+	/*3734*/ uint16(xArgR32),
+	/*3735*/ uint16(xArgRM32),
+	/*3736*/ uint16(xMatch),
+	/*3737*/ uint16(xCondDataSize), 3725, 3731, 3741,
+	/*3741*/ uint16(xSetOp), uint16(CMOVS),
+	/*3743*/ uint16(xReadSlashR),
+	/*3744*/ uint16(xArgR64),
+	/*3745*/ uint16(xArgRM64),
+	/*3746*/ uint16(xMatch),
+	/*3747*/ uint16(xCondIs64), 3750, 3766,
+	/*3750*/ uint16(xCondDataSize), 3754, 3760, 0,
+	/*3754*/ uint16(xSetOp), uint16(CMOVNS),
+	/*3756*/ uint16(xReadSlashR),
+	/*3757*/ uint16(xArgR16),
+	/*3758*/ uint16(xArgRM16),
+	/*3759*/ uint16(xMatch),
+	/*3760*/ uint16(xSetOp), uint16(CMOVNS),
+	/*3762*/ uint16(xReadSlashR),
+	/*3763*/ uint16(xArgR32),
+	/*3764*/ uint16(xArgRM32),
+	/*3765*/ uint16(xMatch),
+	/*3766*/ uint16(xCondDataSize), 3754, 3760, 3770,
+	/*3770*/ uint16(xSetOp), uint16(CMOVNS),
+	/*3772*/ uint16(xReadSlashR),
+	/*3773*/ uint16(xArgR64),
+	/*3774*/ uint16(xArgRM64),
+	/*3775*/ uint16(xMatch),
+	/*3776*/ uint16(xCondIs64), 3779, 3795,
+	/*3779*/ uint16(xCondDataSize), 3783, 3789, 0,
+	/*3783*/ uint16(xSetOp), uint16(CMOVP),
+	/*3785*/ uint16(xReadSlashR),
+	/*3786*/ uint16(xArgR16),
+	/*3787*/ uint16(xArgRM16),
+	/*3788*/ uint16(xMatch),
+	/*3789*/ uint16(xSetOp), uint16(CMOVP),
+	/*3791*/ uint16(xReadSlashR),
+	/*3792*/ uint16(xArgR32),
+	/*3793*/ uint16(xArgRM32),
+	/*3794*/ uint16(xMatch),
+	/*3795*/ uint16(xCondDataSize), 3783, 3789, 3799,
+	/*3799*/ uint16(xSetOp), uint16(CMOVP),
+	/*3801*/ uint16(xReadSlashR),
+	/*3802*/ uint16(xArgR64),
+	/*3803*/ uint16(xArgRM64),
+	/*3804*/ uint16(xMatch),
+	/*3805*/ uint16(xCondIs64), 3808, 3824,
+	/*3808*/ uint16(xCondDataSize), 3812, 3818, 0,
+	/*3812*/ uint16(xSetOp), uint16(CMOVNP),
+	/*3814*/ uint16(xReadSlashR),
+	/*3815*/ uint16(xArgR16),
+	/*3816*/ uint16(xArgRM16),
+	/*3817*/ uint16(xMatch),
+	/*3818*/ uint16(xSetOp), uint16(CMOVNP),
+	/*3820*/ uint16(xReadSlashR),
+	/*3821*/ uint16(xArgR32),
+	/*3822*/ uint16(xArgRM32),
+	/*3823*/ uint16(xMatch),
+	/*3824*/ uint16(xCondDataSize), 3812, 3818, 3828,
+	/*3828*/ uint16(xSetOp), uint16(CMOVNP),
+	/*3830*/ uint16(xReadSlashR),
+	/*3831*/ uint16(xArgR64),
+	/*3832*/ uint16(xArgRM64),
+	/*3833*/ uint16(xMatch),
+	/*3834*/ uint16(xCondIs64), 3837, 3853,
+	/*3837*/ uint16(xCondDataSize), 3841, 3847, 0,
+	/*3841*/ uint16(xSetOp), uint16(CMOVL),
+	/*3843*/ uint16(xReadSlashR),
+	/*3844*/ uint16(xArgR16),
+	/*3845*/ uint16(xArgRM16),
+	/*3846*/ uint16(xMatch),
+	/*3847*/ uint16(xSetOp), uint16(CMOVL),
+	/*3849*/ uint16(xReadSlashR),
+	/*3850*/ uint16(xArgR32),
+	/*3851*/ uint16(xArgRM32),
+	/*3852*/ uint16(xMatch),
+	/*3853*/ uint16(xCondDataSize), 3841, 3847, 3857,
+	/*3857*/ uint16(xSetOp), uint16(CMOVL),
+	/*3859*/ uint16(xReadSlashR),
+	/*3860*/ uint16(xArgR64),
+	/*3861*/ uint16(xArgRM64),
+	/*3862*/ uint16(xMatch),
+	/*3863*/ uint16(xCondIs64), 3866, 3882,
+	/*3866*/ uint16(xCondDataSize), 3870, 3876, 0,
+	/*3870*/ uint16(xSetOp), uint16(CMOVGE),
+	/*3872*/ uint16(xReadSlashR),
+	/*3873*/ uint16(xArgR16),
+	/*3874*/ uint16(xArgRM16),
+	/*3875*/ uint16(xMatch),
+	/*3876*/ uint16(xSetOp), uint16(CMOVGE),
+	/*3878*/ uint16(xReadSlashR),
+	/*3879*/ uint16(xArgR32),
+	/*3880*/ uint16(xArgRM32),
+	/*3881*/ uint16(xMatch),
+	/*3882*/ uint16(xCondDataSize), 3870, 3876, 3886,
+	/*3886*/ uint16(xSetOp), uint16(CMOVGE),
+	/*3888*/ uint16(xReadSlashR),
+	/*3889*/ uint16(xArgR64),
+	/*3890*/ uint16(xArgRM64),
+	/*3891*/ uint16(xMatch),
+	/*3892*/ uint16(xCondIs64), 3895, 3911,
+	/*3895*/ uint16(xCondDataSize), 3899, 3905, 0,
+	/*3899*/ uint16(xSetOp), uint16(CMOVLE),
+	/*3901*/ uint16(xReadSlashR),
+	/*3902*/ uint16(xArgR16),
+	/*3903*/ uint16(xArgRM16),
+	/*3904*/ uint16(xMatch),
+	/*3905*/ uint16(xSetOp), uint16(CMOVLE),
+	/*3907*/ uint16(xReadSlashR),
+	/*3908*/ uint16(xArgR32),
+	/*3909*/ uint16(xArgRM32),
+	/*3910*/ uint16(xMatch),
+	/*3911*/ uint16(xCondDataSize), 3899, 3905, 3915,
+	/*3915*/ uint16(xSetOp), uint16(CMOVLE),
+	/*3917*/ uint16(xReadSlashR),
+	/*3918*/ uint16(xArgR64),
+	/*3919*/ uint16(xArgRM64),
+	/*3920*/ uint16(xMatch),
+	/*3921*/ uint16(xCondIs64), 3924, 3940,
+	/*3924*/ uint16(xCondDataSize), 3928, 3934, 0,
+	/*3928*/ uint16(xSetOp), uint16(CMOVG),
+	/*3930*/ uint16(xReadSlashR),
+	/*3931*/ uint16(xArgR16),
+	/*3932*/ uint16(xArgRM16),
+	/*3933*/ uint16(xMatch),
+	/*3934*/ uint16(xSetOp), uint16(CMOVG),
+	/*3936*/ uint16(xReadSlashR),
+	/*3937*/ uint16(xArgR32),
+	/*3938*/ uint16(xArgRM32),
+	/*3939*/ uint16(xMatch),
+	/*3940*/ uint16(xCondDataSize), 3928, 3934, 3944,
+	/*3944*/ uint16(xSetOp), uint16(CMOVG),
+	/*3946*/ uint16(xReadSlashR),
+	/*3947*/ uint16(xArgR64),
+	/*3948*/ uint16(xArgRM64),
+	/*3949*/ uint16(xMatch),
+	/*3950*/ uint16(xCondPrefix), 2,
+	0x66, 3962,
+	0x0, 3956,
+	/*3956*/ uint16(xSetOp), uint16(MOVMSKPS),
+	/*3958*/ uint16(xReadSlashR),
+	/*3959*/ uint16(xArgR32),
+	/*3960*/ uint16(xArgXmm2),
+	/*3961*/ uint16(xMatch),
+	/*3962*/ uint16(xSetOp), uint16(MOVMSKPD),
+	/*3964*/ uint16(xReadSlashR),
+	/*3965*/ uint16(xArgR32),
+	/*3966*/ uint16(xArgXmm2),
+	/*3967*/ uint16(xMatch),
+	/*3968*/ uint16(xCondPrefix), 4,
+	0xF3, 3996,
+	0xF2, 3990,
+	0x66, 3984,
+	0x0, 3978,
+	/*3978*/ uint16(xSetOp), uint16(SQRTPS),
+	/*3980*/ uint16(xReadSlashR),
+	/*3981*/ uint16(xArgXmm1),
+	/*3982*/ uint16(xArgXmm2M128),
+	/*3983*/ uint16(xMatch),
+	/*3984*/ uint16(xSetOp), uint16(SQRTPD),
+	/*3986*/ uint16(xReadSlashR),
+	/*3987*/ uint16(xArgXmm1),
+	/*3988*/ uint16(xArgXmm2M128),
+	/*3989*/ uint16(xMatch),
+	/*3990*/ uint16(xSetOp), uint16(SQRTSD),
+	/*3992*/ uint16(xReadSlashR),
+	/*3993*/ uint16(xArgXmm1),
+	/*3994*/ uint16(xArgXmm2M64),
+	/*3995*/ uint16(xMatch),
+	/*3996*/ uint16(xSetOp), uint16(SQRTSS),
+	/*3998*/ uint16(xReadSlashR),
+	/*3999*/ uint16(xArgXmm1),
+	/*4000*/ uint16(xArgXmm2M32),
+	/*4001*/ uint16(xMatch),
+	/*4002*/ uint16(xCondPrefix), 2,
+	0xF3, 4014,
+	0x0, 4008,
+	/*4008*/ uint16(xSetOp), uint16(RSQRTPS),
+	/*4010*/ uint16(xReadSlashR),
+	/*4011*/ uint16(xArgXmm1),
+	/*4012*/ uint16(xArgXmm2M128),
+	/*4013*/ uint16(xMatch),
+	/*4014*/ uint16(xSetOp), uint16(RSQRTSS),
+	/*4016*/ uint16(xReadSlashR),
+	/*4017*/ uint16(xArgXmm1),
+	/*4018*/ uint16(xArgXmm2M32),
+	/*4019*/ uint16(xMatch),
+	/*4020*/ uint16(xCondPrefix), 2,
+	0xF3, 4032,
+	0x0, 4026,
+	/*4026*/ uint16(xSetOp), uint16(RCPPS),
+	/*4028*/ uint16(xReadSlashR),
+	/*4029*/ uint16(xArgXmm1),
+	/*4030*/ uint16(xArgXmm2M128),
+	/*4031*/ uint16(xMatch),
+	/*4032*/ uint16(xSetOp), uint16(RCPSS),
+	/*4034*/ uint16(xReadSlashR),
+	/*4035*/ uint16(xArgXmm1),
+	/*4036*/ uint16(xArgXmm2M32),
+	/*4037*/ uint16(xMatch),
+	/*4038*/ uint16(xCondPrefix), 2,
+	0x66, 4050,
+	0x0, 4044,
+	/*4044*/ uint16(xSetOp), uint16(ANDPS),
+	/*4046*/ uint16(xReadSlashR),
+	/*4047*/ uint16(xArgXmm1),
+	/*4048*/ uint16(xArgXmm2M128),
+	/*4049*/ uint16(xMatch),
+	/*4050*/ uint16(xSetOp), uint16(ANDPD),
+	/*4052*/ uint16(xReadSlashR),
+	/*4053*/ uint16(xArgXmm1),
+	/*4054*/ uint16(xArgXmm2M128),
+	/*4055*/ uint16(xMatch),
+	/*4056*/ uint16(xCondPrefix), 2,
+	0x66, 4068,
+	0x0, 4062,
+	/*4062*/ uint16(xSetOp), uint16(ANDNPS),
+	/*4064*/ uint16(xReadSlashR),
+	/*4065*/ uint16(xArgXmm1),
+	/*4066*/ uint16(xArgXmm2M128),
+	/*4067*/ uint16(xMatch),
+	/*4068*/ uint16(xSetOp), uint16(ANDNPD),
+	/*4070*/ uint16(xReadSlashR),
+	/*4071*/ uint16(xArgXmm1),
+	/*4072*/ uint16(xArgXmm2M128),
+	/*4073*/ uint16(xMatch),
+	/*4074*/ uint16(xCondPrefix), 2,
+	0x66, 4086,
+	0x0, 4080,
+	/*4080*/ uint16(xSetOp), uint16(ORPS),
+	/*4082*/ uint16(xReadSlashR),
+	/*4083*/ uint16(xArgXmm1),
+	/*4084*/ uint16(xArgXmm2M128),
+	/*4085*/ uint16(xMatch),
+	/*4086*/ uint16(xSetOp), uint16(ORPD),
+	/*4088*/ uint16(xReadSlashR),
+	/*4089*/ uint16(xArgXmm1),
+	/*4090*/ uint16(xArgXmm2M128),
+	/*4091*/ uint16(xMatch),
+	/*4092*/ uint16(xCondPrefix), 2,
+	0x66, 4104,
+	0x0, 4098,
+	/*4098*/ uint16(xSetOp), uint16(XORPS),
+	/*4100*/ uint16(xReadSlashR),
+	/*4101*/ uint16(xArgXmm1),
+	/*4102*/ uint16(xArgXmm2M128),
+	/*4103*/ uint16(xMatch),
+	/*4104*/ uint16(xSetOp), uint16(XORPD),
+	/*4106*/ uint16(xReadSlashR),
+	/*4107*/ uint16(xArgXmm1),
+	/*4108*/ uint16(xArgXmm2M128),
+	/*4109*/ uint16(xMatch),
+	/*4110*/ uint16(xCondPrefix), 4,
+	0xF3, 4138,
+	0xF2, 4132,
+	0x66, 4126,
+	0x0, 4120,
+	/*4120*/ uint16(xSetOp), uint16(ADDPS),
+	/*4122*/ uint16(xReadSlashR),
+	/*4123*/ uint16(xArgXmm1),
+	/*4124*/ uint16(xArgXmm2M128),
+	/*4125*/ uint16(xMatch),
+	/*4126*/ uint16(xSetOp), uint16(ADDPD),
+	/*4128*/ uint16(xReadSlashR),
+	/*4129*/ uint16(xArgXmm1),
+	/*4130*/ uint16(xArgXmm2M128),
+	/*4131*/ uint16(xMatch),
+	/*4132*/ uint16(xSetOp), uint16(ADDSD),
+	/*4134*/ uint16(xReadSlashR),
+	/*4135*/ uint16(xArgXmm1),
+	/*4136*/ uint16(xArgXmm2M64),
+	/*4137*/ uint16(xMatch),
+	/*4138*/ uint16(xSetOp), uint16(ADDSS),
+	/*4140*/ uint16(xReadSlashR),
+	/*4141*/ uint16(xArgXmm1),
+	/*4142*/ uint16(xArgXmm2M32),
+	/*4143*/ uint16(xMatch),
+	/*4144*/ uint16(xCondPrefix), 4,
+	0xF3, 4172,
+	0xF2, 4166,
+	0x66, 4160,
+	0x0, 4154,
+	/*4154*/ uint16(xSetOp), uint16(MULPS),
+	/*4156*/ uint16(xReadSlashR),
+	/*4157*/ uint16(xArgXmm1),
+	/*4158*/ uint16(xArgXmm2M128),
+	/*4159*/ uint16(xMatch),
+	/*4160*/ uint16(xSetOp), uint16(MULPD),
+	/*4162*/ uint16(xReadSlashR),
+	/*4163*/ uint16(xArgXmm1),
+	/*4164*/ uint16(xArgXmm2M128),
+	/*4165*/ uint16(xMatch),
+	/*4166*/ uint16(xSetOp), uint16(MULSD),
+	/*4168*/ uint16(xReadSlashR),
+	/*4169*/ uint16(xArgXmm1),
+	/*4170*/ uint16(xArgXmm2M64),
+	/*4171*/ uint16(xMatch),
+	/*4172*/ uint16(xSetOp), uint16(MULSS),
+	/*4174*/ uint16(xReadSlashR),
+	/*4175*/ uint16(xArgXmm1),
+	/*4176*/ uint16(xArgXmm2M32),
+	/*4177*/ uint16(xMatch),
+	/*4178*/ uint16(xCondPrefix), 4,
+	0xF3, 4206,
+	0xF2, 4200,
+	0x66, 4194,
+	0x0, 4188,
+	/*4188*/ uint16(xSetOp), uint16(CVTPS2PD),
+	/*4190*/ uint16(xReadSlashR),
+	/*4191*/ uint16(xArgXmm1),
+	/*4192*/ uint16(xArgXmm2M64),
+	/*4193*/ uint16(xMatch),
+	/*4194*/ uint16(xSetOp), uint16(CVTPD2PS),
+	/*4196*/ uint16(xReadSlashR),
+	/*4197*/ uint16(xArgXmm1),
+	/*4198*/ uint16(xArgXmm2M128),
+	/*4199*/ uint16(xMatch),
+	/*4200*/ uint16(xSetOp), uint16(CVTSD2SS),
+	/*4202*/ uint16(xReadSlashR),
+	/*4203*/ uint16(xArgXmm1),
+	/*4204*/ uint16(xArgXmm2M64),
+	/*4205*/ uint16(xMatch),
+	/*4206*/ uint16(xSetOp), uint16(CVTSS2SD),
+	/*4208*/ uint16(xReadSlashR),
+	/*4209*/ uint16(xArgXmm1),
+	/*4210*/ uint16(xArgXmm2M32),
+	/*4211*/ uint16(xMatch),
+	/*4212*/ uint16(xCondPrefix), 3,
+	0xF3, 4232,
+	0x66, 4226,
+	0x0, 4220,
+	/*4220*/ uint16(xSetOp), uint16(CVTDQ2PS),
+	/*4222*/ uint16(xReadSlashR),
+	/*4223*/ uint16(xArgXmm1),
+	/*4224*/ uint16(xArgXmm2M128),
+	/*4225*/ uint16(xMatch),
+	/*4226*/ uint16(xSetOp), uint16(CVTPS2DQ),
+	/*4228*/ uint16(xReadSlashR),
+	/*4229*/ uint16(xArgXmm1),
+	/*4230*/ uint16(xArgXmm2M128),
+	/*4231*/ uint16(xMatch),
+	/*4232*/ uint16(xSetOp), uint16(CVTTPS2DQ),
+	/*4234*/ uint16(xReadSlashR),
+	/*4235*/ uint16(xArgXmm1),
+	/*4236*/ uint16(xArgXmm2M128),
+	/*4237*/ uint16(xMatch),
+	/*4238*/ uint16(xCondPrefix), 4,
+	0xF3, 4266,
+	0xF2, 4260,
+	0x66, 4254,
+	0x0, 4248,
+	/*4248*/ uint16(xSetOp), uint16(SUBPS),
+	/*4250*/ uint16(xReadSlashR),
+	/*4251*/ uint16(xArgXmm1),
+	/*4252*/ uint16(xArgXmm2M128),
+	/*4253*/ uint16(xMatch),
+	/*4254*/ uint16(xSetOp), uint16(SUBPD),
+	/*4256*/ uint16(xReadSlashR),
+	/*4257*/ uint16(xArgXmm1),
+	/*4258*/ uint16(xArgXmm2M128),
+	/*4259*/ uint16(xMatch),
+	/*4260*/ uint16(xSetOp), uint16(SUBSD),
+	/*4262*/ uint16(xReadSlashR),
+	/*4263*/ uint16(xArgXmm1),
+	/*4264*/ uint16(xArgXmm2M64),
+	/*4265*/ uint16(xMatch),
+	/*4266*/ uint16(xSetOp), uint16(SUBSS),
+	/*4268*/ uint16(xReadSlashR),
+	/*4269*/ uint16(xArgXmm1),
+	/*4270*/ uint16(xArgXmm2M32),
+	/*4271*/ uint16(xMatch),
+	/*4272*/ uint16(xCondPrefix), 4,
+	0xF3, 4300,
+	0xF2, 4294,
+	0x66, 4288,
+	0x0, 4282,
+	/*4282*/ uint16(xSetOp), uint16(MINPS),
+	/*4284*/ uint16(xReadSlashR),
+	/*4285*/ uint16(xArgXmm1),
+	/*4286*/ uint16(xArgXmm2M128),
+	/*4287*/ uint16(xMatch),
+	/*4288*/ uint16(xSetOp), uint16(MINPD),
+	/*4290*/ uint16(xReadSlashR),
+	/*4291*/ uint16(xArgXmm1),
+	/*4292*/ uint16(xArgXmm2M128),
+	/*4293*/ uint16(xMatch),
+	/*4294*/ uint16(xSetOp), uint16(MINSD),
+	/*4296*/ uint16(xReadSlashR),
+	/*4297*/ uint16(xArgXmm1),
+	/*4298*/ uint16(xArgXmm2M64),
+	/*4299*/ uint16(xMatch),
+	/*4300*/ uint16(xSetOp), uint16(MINSS),
+	/*4302*/ uint16(xReadSlashR),
+	/*4303*/ uint16(xArgXmm1),
+	/*4304*/ uint16(xArgXmm2M32),
+	/*4305*/ uint16(xMatch),
+	/*4306*/ uint16(xCondPrefix), 4,
+	0xF3, 4334,
+	0xF2, 4328,
+	0x66, 4322,
+	0x0, 4316,
+	/*4316*/ uint16(xSetOp), uint16(DIVPS),
+	/*4318*/ uint16(xReadSlashR),
+	/*4319*/ uint16(xArgXmm1),
+	/*4320*/ uint16(xArgXmm2M128),
+	/*4321*/ uint16(xMatch),
+	/*4322*/ uint16(xSetOp), uint16(DIVPD),
+	/*4324*/ uint16(xReadSlashR),
+	/*4325*/ uint16(xArgXmm1),
+	/*4326*/ uint16(xArgXmm2M128),
+	/*4327*/ uint16(xMatch),
+	/*4328*/ uint16(xSetOp), uint16(DIVSD),
+	/*4330*/ uint16(xReadSlashR),
+	/*4331*/ uint16(xArgXmm1),
+	/*4332*/ uint16(xArgXmm2M64),
+	/*4333*/ uint16(xMatch),
+	/*4334*/ uint16(xSetOp), uint16(DIVSS),
+	/*4336*/ uint16(xReadSlashR),
+	/*4337*/ uint16(xArgXmm1),
+	/*4338*/ uint16(xArgXmm2M32),
+	/*4339*/ uint16(xMatch),
+	/*4340*/ uint16(xCondPrefix), 4,
+	0xF3, 4368,
+	0xF2, 4362,
+	0x66, 4356,
+	0x0, 4350,
+	/*4350*/ uint16(xSetOp), uint16(MAXPS),
+	/*4352*/ uint16(xReadSlashR),
+	/*4353*/ uint16(xArgXmm1),
+	/*4354*/ uint16(xArgXmm2M128),
+	/*4355*/ uint16(xMatch),
+	/*4356*/ uint16(xSetOp), uint16(MAXPD),
+	/*4358*/ uint16(xReadSlashR),
+	/*4359*/ uint16(xArgXmm1),
+	/*4360*/ uint16(xArgXmm2M128),
+	/*4361*/ uint16(xMatch),
+	/*4362*/ uint16(xSetOp), uint16(MAXSD),
+	/*4364*/ uint16(xReadSlashR),
+	/*4365*/ uint16(xArgXmm1),
+	/*4366*/ uint16(xArgXmm2M64),
+	/*4367*/ uint16(xMatch),
+	/*4368*/ uint16(xSetOp), uint16(MAXSS),
+	/*4370*/ uint16(xReadSlashR),
+	/*4371*/ uint16(xArgXmm1),
+	/*4372*/ uint16(xArgXmm2M32),
+	/*4373*/ uint16(xMatch),
+	/*4374*/ uint16(xCondPrefix), 2,
+	0x66, 4386,
+	0x0, 4380,
+	/*4380*/ uint16(xSetOp), uint16(PUNPCKLBW),
+	/*4382*/ uint16(xReadSlashR),
+	/*4383*/ uint16(xArgMm),
+	/*4384*/ uint16(xArgMmM32),
+	/*4385*/ uint16(xMatch),
+	/*4386*/ uint16(xSetOp), uint16(PUNPCKLBW),
+	/*4388*/ uint16(xReadSlashR),
+	/*4389*/ uint16(xArgXmm1),
+	/*4390*/ uint16(xArgXmm2M128),
+	/*4391*/ uint16(xMatch),
+	/*4392*/ uint16(xCondPrefix), 2,
+	0x66, 4404,
+	0x0, 4398,
+	/*4398*/ uint16(xSetOp), uint16(PUNPCKLWD),
+	/*4400*/ uint16(xReadSlashR),
+	/*4401*/ uint16(xArgMm),
+	/*4402*/ uint16(xArgMmM32),
+	/*4403*/ uint16(xMatch),
+	/*4404*/ uint16(xSetOp), uint16(PUNPCKLWD),
+	/*4406*/ uint16(xReadSlashR),
+	/*4407*/ uint16(xArgXmm1),
+	/*4408*/ uint16(xArgXmm2M128),
+	/*4409*/ uint16(xMatch),
+	/*4410*/ uint16(xCondPrefix), 2,
+	0x66, 4422,
+	0x0, 4416,
+	/*4416*/ uint16(xSetOp), uint16(PUNPCKLDQ),
+	/*4418*/ uint16(xReadSlashR),
+	/*4419*/ uint16(xArgMm),
+	/*4420*/ uint16(xArgMmM32),
+	/*4421*/ uint16(xMatch),
+	/*4422*/ uint16(xSetOp), uint16(PUNPCKLDQ),
+	/*4424*/ uint16(xReadSlashR),
+	/*4425*/ uint16(xArgXmm1),
+	/*4426*/ uint16(xArgXmm2M128),
+	/*4427*/ uint16(xMatch),
+	/*4428*/ uint16(xCondPrefix), 2,
+	0x66, 4440,
+	0x0, 4434,
+	/*4434*/ uint16(xSetOp), uint16(PACKSSWB),
+	/*4436*/ uint16(xReadSlashR),
+	/*4437*/ uint16(xArgMm1),
+	/*4438*/ uint16(xArgMm2M64),
+	/*4439*/ uint16(xMatch),
+	/*4440*/ uint16(xSetOp), uint16(PACKSSWB),
+	/*4442*/ uint16(xReadSlashR),
+	/*4443*/ uint16(xArgXmm1),
+	/*4444*/ uint16(xArgXmm2M128),
+	/*4445*/ uint16(xMatch),
+	/*4446*/ uint16(xCondPrefix), 2,
+	0x66, 4458,
+	0x0, 4452,
+	/*4452*/ uint16(xSetOp), uint16(PCMPGTB),
+	/*4454*/ uint16(xReadSlashR),
+	/*4455*/ uint16(xArgMm),
+	/*4456*/ uint16(xArgMmM64),
+	/*4457*/ uint16(xMatch),
+	/*4458*/ uint16(xSetOp), uint16(PCMPGTB),
+	/*4460*/ uint16(xReadSlashR),
+	/*4461*/ uint16(xArgXmm1),
+	/*4462*/ uint16(xArgXmm2M128),
+	/*4463*/ uint16(xMatch),
+	/*4464*/ uint16(xCondPrefix), 2,
+	0x66, 4476,
+	0x0, 4470,
+	/*4470*/ uint16(xSetOp), uint16(PCMPGTW),
+	/*4472*/ uint16(xReadSlashR),
+	/*4473*/ uint16(xArgMm),
+	/*4474*/ uint16(xArgMmM64),
+	/*4475*/ uint16(xMatch),
+	/*4476*/ uint16(xSetOp), uint16(PCMPGTW),
+	/*4478*/ uint16(xReadSlashR),
+	/*4479*/ uint16(xArgXmm1),
+	/*4480*/ uint16(xArgXmm2M128),
+	/*4481*/ uint16(xMatch),
+	/*4482*/ uint16(xCondPrefix), 2,
+	0x66, 4494,
+	0x0, 4488,
+	/*4488*/ uint16(xSetOp), uint16(PCMPGTD),
+	/*4490*/ uint16(xReadSlashR),
+	/*4491*/ uint16(xArgMm),
+	/*4492*/ uint16(xArgMmM64),
+	/*4493*/ uint16(xMatch),
+	/*4494*/ uint16(xSetOp), uint16(PCMPGTD),
+	/*4496*/ uint16(xReadSlashR),
+	/*4497*/ uint16(xArgXmm1),
+	/*4498*/ uint16(xArgXmm2M128),
+	/*4499*/ uint16(xMatch),
+	/*4500*/ uint16(xCondPrefix), 2,
+	0x66, 4512,
+	0x0, 4506,
+	/*4506*/ uint16(xSetOp), uint16(PACKUSWB),
+	/*4508*/ uint16(xReadSlashR),
+	/*4509*/ uint16(xArgMm),
+	/*4510*/ uint16(xArgMmM64),
+	/*4511*/ uint16(xMatch),
+	/*4512*/ uint16(xSetOp), uint16(PACKUSWB),
+	/*4514*/ uint16(xReadSlashR),
+	/*4515*/ uint16(xArgXmm1),
+	/*4516*/ uint16(xArgXmm2M128),
+	/*4517*/ uint16(xMatch),
+	/*4518*/ uint16(xCondPrefix), 2,
+	0x66, 4530,
+	0x0, 4524,
+	/*4524*/ uint16(xSetOp), uint16(PUNPCKHBW),
+	/*4526*/ uint16(xReadSlashR),
+	/*4527*/ uint16(xArgMm),
+	/*4528*/ uint16(xArgMmM64),
+	/*4529*/ uint16(xMatch),
+	/*4530*/ uint16(xSetOp), uint16(PUNPCKHBW),
+	/*4532*/ uint16(xReadSlashR),
+	/*4533*/ uint16(xArgXmm1),
+	/*4534*/ uint16(xArgXmm2M128),
+	/*4535*/ uint16(xMatch),
+	/*4536*/ uint16(xCondPrefix), 2,
+	0x66, 4548,
+	0x0, 4542,
+	/*4542*/ uint16(xSetOp), uint16(PUNPCKHWD),
+	/*4544*/ uint16(xReadSlashR),
+	/*4545*/ uint16(xArgMm),
+	/*4546*/ uint16(xArgMmM64),
+	/*4547*/ uint16(xMatch),
+	/*4548*/ uint16(xSetOp), uint16(PUNPCKHWD),
+	/*4550*/ uint16(xReadSlashR),
+	/*4551*/ uint16(xArgXmm1),
+	/*4552*/ uint16(xArgXmm2M128),
+	/*4553*/ uint16(xMatch),
+	/*4554*/ uint16(xCondPrefix), 2,
+	0x66, 4566,
+	0x0, 4560,
+	/*4560*/ uint16(xSetOp), uint16(PUNPCKHDQ),
+	/*4562*/ uint16(xReadSlashR),
+	/*4563*/ uint16(xArgMm),
+	/*4564*/ uint16(xArgMmM64),
+	/*4565*/ uint16(xMatch),
+	/*4566*/ uint16(xSetOp), uint16(PUNPCKHDQ),
+	/*4568*/ uint16(xReadSlashR),
+	/*4569*/ uint16(xArgXmm1),
+	/*4570*/ uint16(xArgXmm2M128),
+	/*4571*/ uint16(xMatch),
+	/*4572*/ uint16(xCondPrefix), 2,
+	0x66, 4584,
+	0x0, 4578,
+	/*4578*/ uint16(xSetOp), uint16(PACKSSDW),
+	/*4580*/ uint16(xReadSlashR),
+	/*4581*/ uint16(xArgMm1),
+	/*4582*/ uint16(xArgMm2M64),
+	/*4583*/ uint16(xMatch),
+	/*4584*/ uint16(xSetOp), uint16(PACKSSDW),
+	/*4586*/ uint16(xReadSlashR),
+	/*4587*/ uint16(xArgXmm1),
+	/*4588*/ uint16(xArgXmm2M128),
+	/*4589*/ uint16(xMatch),
+	/*4590*/ uint16(xCondPrefix), 1,
+	0x66, 4594,
+	/*4594*/ uint16(xSetOp), uint16(PUNPCKLQDQ),
+	/*4596*/ uint16(xReadSlashR),
+	/*4597*/ uint16(xArgXmm1),
+	/*4598*/ uint16(xArgXmm2M128),
+	/*4599*/ uint16(xMatch),
+	/*4600*/ uint16(xCondPrefix), 1,
+	0x66, 4604,
+	/*4604*/ uint16(xSetOp), uint16(PUNPCKHQDQ),
+	/*4606*/ uint16(xReadSlashR),
+	/*4607*/ uint16(xArgXmm1),
+	/*4608*/ uint16(xArgXmm2M128),
+	/*4609*/ uint16(xMatch),
+	/*4610*/ uint16(xCondIs64), 4613, 4651,
+	/*4613*/ uint16(xCondPrefix), 2,
+	0x66, 4635,
+	0x0, 4619,
+	/*4619*/ uint16(xCondDataSize), 4623, 4629, 0,
+	/*4623*/ uint16(xSetOp), uint16(MOVD),
+	/*4625*/ uint16(xReadSlashR),
+	/*4626*/ uint16(xArgMm),
+	/*4627*/ uint16(xArgRM32),
+	/*4628*/ uint16(xMatch),
+	/*4629*/ uint16(xSetOp), uint16(MOVD),
+	/*4631*/ uint16(xReadSlashR),
+	/*4632*/ uint16(xArgMm),
+	/*4633*/ uint16(xArgRM32),
+	/*4634*/ uint16(xMatch),
+	/*4635*/ uint16(xCondDataSize), 4639, 4645, 0,
+	/*4639*/ uint16(xSetOp), uint16(MOVD),
+	/*4641*/ uint16(xReadSlashR),
+	/*4642*/ uint16(xArgXmm),
+	/*4643*/ uint16(xArgRM32),
+	/*4644*/ uint16(xMatch),
+	/*4645*/ uint16(xSetOp), uint16(MOVD),
+	/*4647*/ uint16(xReadSlashR),
+	/*4648*/ uint16(xArgXmm),
+	/*4649*/ uint16(xArgRM32),
+	/*4650*/ uint16(xMatch),
+	/*4651*/ uint16(xCondPrefix), 2,
+	0x66, 4667,
+	0x0, 4657,
+	/*4657*/ uint16(xCondDataSize), 4623, 4629, 4661,
+	/*4661*/ uint16(xSetOp), uint16(MOVQ),
+	/*4663*/ uint16(xReadSlashR),
+	/*4664*/ uint16(xArgMm),
+	/*4665*/ uint16(xArgRM64),
+	/*4666*/ uint16(xMatch),
+	/*4667*/ uint16(xCondDataSize), 4639, 4645, 4671,
+	/*4671*/ uint16(xSetOp), uint16(MOVQ),
+	/*4673*/ uint16(xReadSlashR),
+	/*4674*/ uint16(xArgXmm),
+	/*4675*/ uint16(xArgRM64),
+	/*4676*/ uint16(xMatch),
+	/*4677*/ uint16(xCondPrefix), 3,
+	0xF3, 4697,
+	0x66, 4691,
+	0x0, 4685,
+	/*4685*/ uint16(xSetOp), uint16(MOVQ),
+	/*4687*/ uint16(xReadSlashR),
+	/*4688*/ uint16(xArgMm),
+	/*4689*/ uint16(xArgMmM64),
+	/*4690*/ uint16(xMatch),
+	/*4691*/ uint16(xSetOp), uint16(MOVDQA),
+	/*4693*/ uint16(xReadSlashR),
+	/*4694*/ uint16(xArgXmm1),
+	/*4695*/ uint16(xArgXmm2M128),
+	/*4696*/ uint16(xMatch),
+	/*4697*/ uint16(xSetOp), uint16(MOVDQU),
+	/*4699*/ uint16(xReadSlashR),
+	/*4700*/ uint16(xArgXmm1),
+	/*4701*/ uint16(xArgXmm2M128),
+	/*4702*/ uint16(xMatch),
+	/*4703*/ uint16(xCondPrefix), 4,
+	0xF3, 4737,
+	0xF2, 4729,
+	0x66, 4721,
+	0x0, 4713,
+	/*4713*/ uint16(xSetOp), uint16(PSHUFW),
+	/*4715*/ uint16(xReadSlashR),
+	/*4716*/ uint16(xReadIb),
+	/*4717*/ uint16(xArgMm1),
+	/*4718*/ uint16(xArgMm2M64),
+	/*4719*/ uint16(xArgImm8u),
+	/*4720*/ uint16(xMatch),
+	/*4721*/ uint16(xSetOp), uint16(PSHUFD),
+	/*4723*/ uint16(xReadSlashR),
+	/*4724*/ uint16(xReadIb),
+	/*4725*/ uint16(xArgXmm1),
+	/*4726*/ uint16(xArgXmm2M128),
+	/*4727*/ uint16(xArgImm8u),
+	/*4728*/ uint16(xMatch),
+	/*4729*/ uint16(xSetOp), uint16(PSHUFLW),
+	/*4731*/ uint16(xReadSlashR),
+	/*4732*/ uint16(xReadIb),
+	/*4733*/ uint16(xArgXmm1),
+	/*4734*/ uint16(xArgXmm2M128),
+	/*4735*/ uint16(xArgImm8u),
+	/*4736*/ uint16(xMatch),
+	/*4737*/ uint16(xSetOp), uint16(PSHUFHW),
+	/*4739*/ uint16(xReadSlashR),
+	/*4740*/ uint16(xReadIb),
+	/*4741*/ uint16(xArgXmm1),
+	/*4742*/ uint16(xArgXmm2M128),
+	/*4743*/ uint16(xArgImm8u),
+	/*4744*/ uint16(xMatch),
+	/*4745*/ uint16(xCondSlashR),
 	0,    // 0
 	0,    // 1
-	4752, // 2
+	4754, // 2
 	0,    // 3
-	4770, // 4
+	4772, // 4
 	0,    // 5
-	4788, // 6
+	4790, // 6
 	0,    // 7
-	/*4752*/ uint16(xCondPrefix), 2,
-	0x66, 4764,
-	0x0, 4758,
-	/*4758*/ uint16(xSetOp), uint16(PSRLW),
-	/*4760*/ uint16(xReadIb),
-	/*4761*/ uint16(xArgMm2),
-	/*4762*/ uint16(xArgImm8u),
-	/*4763*/ uint16(xMatch),
-	/*4764*/ uint16(xSetOp), uint16(PSRLW),
-	/*4766*/ uint16(xReadIb),
-	/*4767*/ uint16(xArgXmm2),
-	/*4768*/ uint16(xArgImm8u),
-	/*4769*/ uint16(xMatch),
-	/*4770*/ uint16(xCondPrefix), 2,
-	0x66, 4782,
-	0x0, 4776,
-	/*4776*/ uint16(xSetOp), uint16(PSRAW),
-	/*4778*/ uint16(xReadIb),
-	/*4779*/ uint16(xArgMm2),
-	/*4780*/ uint16(xArgImm8u),
-	/*4781*/ uint16(xMatch),
-	/*4782*/ uint16(xSetOp), uint16(PSRAW),
-	/*4784*/ uint16(xReadIb),
-	/*4785*/ uint16(xArgXmm2),
-	/*4786*/ uint16(xArgImm8u),
-	/*4787*/ uint16(xMatch),
-	/*4788*/ uint16(xCondPrefix), 2,
-	0x66, 4800,
-	0x0, 4794,
-	/*4794*/ uint16(xSetOp), uint16(PSLLW),
-	/*4796*/ uint16(xReadIb),
-	/*4797*/ uint16(xArgMm2),
-	/*4798*/ uint16(xArgImm8u),
-	/*4799*/ uint16(xMatch),
-	/*4800*/ uint16(xSetOp), uint16(PSLLW),
-	/*4802*/ uint16(xReadIb),
-	/*4803*/ uint16(xArgXmm2),
-	/*4804*/ uint16(xArgImm8u),
-	/*4805*/ uint16(xMatch),
-	/*4806*/ uint16(xCondSlashR),
+	/*4754*/ uint16(xCondPrefix), 2,
+	0x66, 4766,
+	0x0, 4760,
+	/*4760*/ uint16(xSetOp), uint16(PSRLW),
+	/*4762*/ uint16(xReadIb),
+	/*4763*/ uint16(xArgMm2),
+	/*4764*/ uint16(xArgImm8u),
+	/*4765*/ uint16(xMatch),
+	/*4766*/ uint16(xSetOp), uint16(PSRLW),
+	/*4768*/ uint16(xReadIb),
+	/*4769*/ uint16(xArgXmm2),
+	/*4770*/ uint16(xArgImm8u),
+	/*4771*/ uint16(xMatch),
+	/*4772*/ uint16(xCondPrefix), 2,
+	0x66, 4784,
+	0x0, 4778,
+	/*4778*/ uint16(xSetOp), uint16(PSRAW),
+	/*4780*/ uint16(xReadIb),
+	/*4781*/ uint16(xArgMm2),
+	/*4782*/ uint16(xArgImm8u),
+	/*4783*/ uint16(xMatch),
+	/*4784*/ uint16(xSetOp), uint16(PSRAW),
+	/*4786*/ uint16(xReadIb),
+	/*4787*/ uint16(xArgXmm2),
+	/*4788*/ uint16(xArgImm8u),
+	/*4789*/ uint16(xMatch),
+	/*4790*/ uint16(xCondPrefix), 2,
+	0x66, 4802,
+	0x0, 4796,
+	/*4796*/ uint16(xSetOp), uint16(PSLLW),
+	/*4798*/ uint16(xReadIb),
+	/*4799*/ uint16(xArgMm2),
+	/*4800*/ uint16(xArgImm8u),
+	/*4801*/ uint16(xMatch),
+	/*4802*/ uint16(xSetOp), uint16(PSLLW),
+	/*4804*/ uint16(xReadIb),
+	/*4805*/ uint16(xArgXmm2),
+	/*4806*/ uint16(xArgImm8u),
+	/*4807*/ uint16(xMatch),
+	/*4808*/ uint16(xCondSlashR),
 	0,    // 0
 	0,    // 1
-	4815, // 2
+	4817, // 2
 	0,    // 3
-	4833, // 4
+	4835, // 4
 	0,    // 5
-	4851, // 6
+	4853, // 6
 	0,    // 7
-	/*4815*/ uint16(xCondPrefix), 2,
-	0x66, 4827,
-	0x0, 4821,
-	/*4821*/ uint16(xSetOp), uint16(PSRLD),
-	/*4823*/ uint16(xReadIb),
-	/*4824*/ uint16(xArgMm2),
-	/*4825*/ uint16(xArgImm8u),
-	/*4826*/ uint16(xMatch),
-	/*4827*/ uint16(xSetOp), uint16(PSRLD),
-	/*4829*/ uint16(xReadIb),
-	/*4830*/ uint16(xArgXmm2),
-	/*4831*/ uint16(xArgImm8u),
-	/*4832*/ uint16(xMatch),
-	/*4833*/ uint16(xCondPrefix), 2,
-	0x66, 4845,
-	0x0, 4839,
-	/*4839*/ uint16(xSetOp), uint16(PSRAD),
-	/*4841*/ uint16(xReadIb),
-	/*4842*/ uint16(xArgMm2),
-	/*4843*/ uint16(xArgImm8u),
-	/*4844*/ uint16(xMatch),
-	/*4845*/ uint16(xSetOp), uint16(PSRAD),
-	/*4847*/ uint16(xReadIb),
-	/*4848*/ uint16(xArgXmm2),
-	/*4849*/ uint16(xArgImm8u),
-	/*4850*/ uint16(xMatch),
-	/*4851*/ uint16(xCondPrefix), 2,
-	0x66, 4863,
-	0x0, 4857,
-	/*4857*/ uint16(xSetOp), uint16(PSLLD),
-	/*4859*/ uint16(xReadIb),
-	/*4860*/ uint16(xArgMm2),
-	/*4861*/ uint16(xArgImm8u),
-	/*4862*/ uint16(xMatch),
-	/*4863*/ uint16(xSetOp), uint16(PSLLD),
-	/*4865*/ uint16(xReadIb),
-	/*4866*/ uint16(xArgXmm2),
-	/*4867*/ uint16(xArgImm8u),
-	/*4868*/ uint16(xMatch),
-	/*4869*/ uint16(xCondSlashR),
+	/*4817*/ uint16(xCondPrefix), 2,
+	0x66, 4829,
+	0x0, 4823,
+	/*4823*/ uint16(xSetOp), uint16(PSRLD),
+	/*4825*/ uint16(xReadIb),
+	/*4826*/ uint16(xArgMm2),
+	/*4827*/ uint16(xArgImm8u),
+	/*4828*/ uint16(xMatch),
+	/*4829*/ uint16(xSetOp), uint16(PSRLD),
+	/*4831*/ uint16(xReadIb),
+	/*4832*/ uint16(xArgXmm2),
+	/*4833*/ uint16(xArgImm8u),
+	/*4834*/ uint16(xMatch),
+	/*4835*/ uint16(xCondPrefix), 2,
+	0x66, 4847,
+	0x0, 4841,
+	/*4841*/ uint16(xSetOp), uint16(PSRAD),
+	/*4843*/ uint16(xReadIb),
+	/*4844*/ uint16(xArgMm2),
+	/*4845*/ uint16(xArgImm8u),
+	/*4846*/ uint16(xMatch),
+	/*4847*/ uint16(xSetOp), uint16(PSRAD),
+	/*4849*/ uint16(xReadIb),
+	/*4850*/ uint16(xArgXmm2),
+	/*4851*/ uint16(xArgImm8u),
+	/*4852*/ uint16(xMatch),
+	/*4853*/ uint16(xCondPrefix), 2,
+	0x66, 4865,
+	0x0, 4859,
+	/*4859*/ uint16(xSetOp), uint16(PSLLD),
+	/*4861*/ uint16(xReadIb),
+	/*4862*/ uint16(xArgMm2),
+	/*4863*/ uint16(xArgImm8u),
+	/*4864*/ uint16(xMatch),
+	/*4865*/ uint16(xSetOp), uint16(PSLLD),
+	/*4867*/ uint16(xReadIb),
+	/*4868*/ uint16(xArgXmm2),
+	/*4869*/ uint16(xArgImm8u),
+	/*4870*/ uint16(xMatch),
+	/*4871*/ uint16(xCondSlashR),
 	0,    // 0
 	0,    // 1
-	4878, // 2
-	4896, // 3
+	4880, // 2
+	4898, // 3
 	0,    // 4
 	0,    // 5
-	4906, // 6
-	4924, // 7
-	/*4878*/ uint16(xCondPrefix), 2,
-	0x66, 4890,
-	0x0, 4884,
-	/*4884*/ uint16(xSetOp), uint16(PSRLQ),
-	/*4886*/ uint16(xReadIb),
-	/*4887*/ uint16(xArgMm2),
-	/*4888*/ uint16(xArgImm8u),
-	/*4889*/ uint16(xMatch),
-	/*4890*/ uint16(xSetOp), uint16(PSRLQ),
-	/*4892*/ uint16(xReadIb),
-	/*4893*/ uint16(xArgXmm2),
-	/*4894*/ uint16(xArgImm8u),
-	/*4895*/ uint16(xMatch),
-	/*4896*/ uint16(xCondPrefix), 1,
-	0x66, 4900,
-	/*4900*/ uint16(xSetOp), uint16(PSRLDQ),
-	/*4902*/ uint16(xReadIb),
-	/*4903*/ uint16(xArgXmm2),
-	/*4904*/ uint16(xArgImm8u),
-	/*4905*/ uint16(xMatch),
-	/*4906*/ uint16(xCondPrefix), 2,
-	0x66, 4918,
-	0x0, 4912,
-	/*4912*/ uint16(xSetOp), uint16(PSLLQ),
-	/*4914*/ uint16(xReadIb),
-	/*4915*/ uint16(xArgMm2),
-	/*4916*/ uint16(xArgImm8u),
-	/*4917*/ uint16(xMatch),
-	/*4918*/ uint16(xSetOp), uint16(PSLLQ),
-	/*4920*/ uint16(xReadIb),
-	/*4921*/ uint16(xArgXmm2),
-	/*4922*/ uint16(xArgImm8u),
-	/*4923*/ uint16(xMatch),
-	/*4924*/ uint16(xCondPrefix), 1,
-	0x66, 4928,
-	/*4928*/ uint16(xSetOp), uint16(PSLLDQ),
-	/*4930*/ uint16(xReadIb),
-	/*4931*/ uint16(xArgXmm2),
-	/*4932*/ uint16(xArgImm8u),
-	/*4933*/ uint16(xMatch),
-	/*4934*/ uint16(xCondPrefix), 2,
-	0x66, 4946,
-	0x0, 4940,
-	/*4940*/ uint16(xSetOp), uint16(PCMPEQB),
-	/*4942*/ uint16(xReadSlashR),
-	/*4943*/ uint16(xArgMm),
-	/*4944*/ uint16(xArgMmM64),
-	/*4945*/ uint16(xMatch),
-	/*4946*/ uint16(xSetOp), uint16(PCMPEQB),
-	/*4948*/ uint16(xReadSlashR),
-	/*4949*/ uint16(xArgXmm1),
-	/*4950*/ uint16(xArgXmm2M128),
-	/*4951*/ uint16(xMatch),
-	/*4952*/ uint16(xCondPrefix), 2,
-	0x66, 4964,
-	0x0, 4958,
-	/*4958*/ uint16(xSetOp), uint16(PCMPEQW),
-	/*4960*/ uint16(xReadSlashR),
-	/*4961*/ uint16(xArgMm),
-	/*4962*/ uint16(xArgMmM64),
-	/*4963*/ uint16(xMatch),
-	/*4964*/ uint16(xSetOp), uint16(PCMPEQW),
-	/*4966*/ uint16(xReadSlashR),
-	/*4967*/ uint16(xArgXmm1),
-	/*4968*/ uint16(xArgXmm2M128),
-	/*4969*/ uint16(xMatch),
-	/*4970*/ uint16(xCondPrefix), 2,
-	0x66, 4982,
-	0x0, 4976,
-	/*4976*/ uint16(xSetOp), uint16(PCMPEQD),
-	/*4978*/ uint16(xReadSlashR),
-	/*4979*/ uint16(xArgMm),
-	/*4980*/ uint16(xArgMmM64),
-	/*4981*/ uint16(xMatch),
-	/*4982*/ uint16(xSetOp), uint16(PCMPEQD),
-	/*4984*/ uint16(xReadSlashR),
-	/*4985*/ uint16(xArgXmm1),
-	/*4986*/ uint16(xArgXmm2M128),
-	/*4987*/ uint16(xMatch),
-	/*4988*/ uint16(xSetOp), uint16(EMMS),
-	/*4990*/ uint16(xMatch),
-	/*4991*/ uint16(xCondPrefix), 2,
-	0xF2, 5003,
-	0x66, 4997,
-	/*4997*/ uint16(xSetOp), uint16(HADDPD),
-	/*4999*/ uint16(xReadSlashR),
-	/*5000*/ uint16(xArgXmm1),
-	/*5001*/ uint16(xArgXmm2M128),
-	/*5002*/ uint16(xMatch),
-	/*5003*/ uint16(xSetOp), uint16(HADDPS),
-	/*5005*/ uint16(xReadSlashR),
-	/*5006*/ uint16(xArgXmm1),
-	/*5007*/ uint16(xArgXmm2M128),
-	/*5008*/ uint16(xMatch),
-	/*5009*/ uint16(xCondPrefix), 2,
-	0xF2, 5021,
-	0x66, 5015,
-	/*5015*/ uint16(xSetOp), uint16(HSUBPD),
-	/*5017*/ uint16(xReadSlashR),
-	/*5018*/ uint16(xArgXmm1),
-	/*5019*/ uint16(xArgXmm2M128),
-	/*5020*/ uint16(xMatch),
-	/*5021*/ uint16(xSetOp), uint16(HSUBPS),
-	/*5023*/ uint16(xReadSlashR),
-	/*5024*/ uint16(xArgXmm1),
-	/*5025*/ uint16(xArgXmm2M128),
-	/*5026*/ uint16(xMatch),
-	/*5027*/ uint16(xCondIs64), 5030, 5076,
-	/*5030*/ uint16(xCondPrefix), 3,
-	0xF3, 5070,
-	0x66, 5054,
-	0x0, 5038,
-	/*5038*/ uint16(xCondDataSize), 5042, 5048, 0,
-	/*5042*/ uint16(xSetOp), uint16(MOVD),
-	/*5044*/ uint16(xReadSlashR),
-	/*5045*/ uint16(xArgRM32),
-	/*5046*/ uint16(xArgMm),
-	/*5047*/ uint16(xMatch),
-	/*5048*/ uint16(xSetOp), uint16(MOVD),
-	/*5050*/ uint16(xReadSlashR),
-	/*5051*/ uint16(xArgRM32),
-	/*5052*/ uint16(xArgMm),
-	/*5053*/ uint16(xMatch),
-	/*5054*/ uint16(xCondDataSize), 5058, 5064, 0,
-	/*5058*/ uint16(xSetOp), uint16(MOVD),
-	/*5060*/ uint16(xReadSlashR),
-	/*5061*/ uint16(xArgRM32),
-	/*5062*/ uint16(xArgXmm),
-	/*5063*/ uint16(xMatch),
-	/*5064*/ uint16(xSetOp), uint16(MOVD),
-	/*5066*/ uint16(xReadSlashR),
-	/*5067*/ uint16(xArgRM32),
-	/*5068*/ uint16(xArgXmm),
-	/*5069*/ uint16(xMatch),
-	/*5070*/ uint16(xSetOp), uint16(MOVQ),
-	/*5072*/ uint16(xReadSlashR),
-	/*5073*/ uint16(xArgXmm1),
-	/*5074*/ uint16(xArgXmm2M64),
-	/*5075*/ uint16(xMatch),
-	/*5076*/ uint16(xCondPrefix), 3,
-	0xF3, 5070,
-	0x66, 5094,
-	0x0, 5084,
-	/*5084*/ uint16(xCondDataSize), 5042, 5048, 5088,
-	/*5088*/ uint16(xSetOp), uint16(MOVQ),
-	/*5090*/ uint16(xReadSlashR),
-	/*5091*/ uint16(xArgRM64),
-	/*5092*/ uint16(xArgMm),
-	/*5093*/ uint16(xMatch),
-	/*5094*/ uint16(xCondDataSize), 5058, 5064, 5098,
-	/*5098*/ uint16(xSetOp), uint16(MOVQ),
-	/*5100*/ uint16(xReadSlashR),
-	/*5101*/ uint16(xArgRM64),
-	/*5102*/ uint16(xArgXmm),
-	/*5103*/ uint16(xMatch),
-	/*5104*/ uint16(xCondPrefix), 3,
-	0xF3, 5124,
-	0x66, 5118,
-	0x0, 5112,
-	/*5112*/ uint16(xSetOp), uint16(MOVQ),
-	/*5114*/ uint16(xReadSlashR),
-	/*5115*/ uint16(xArgMmM64),
-	/*5116*/ uint16(xArgMm),
-	/*5117*/ uint16(xMatch),
-	/*5118*/ uint16(xSetOp), uint16(MOVDQA),
-	/*5120*/ uint16(xReadSlashR),
-	/*5121*/ uint16(xArgXmm2M128),
-	/*5122*/ uint16(xArgXmm1),
-	/*5123*/ uint16(xMatch),
-	/*5124*/ uint16(xSetOp), uint16(MOVDQU),
-	/*5126*/ uint16(xReadSlashR),
-	/*5127*/ uint16(xArgXmm2M128),
-	/*5128*/ uint16(xArgXmm1),
-	/*5129*/ uint16(xMatch),
-	/*5130*/ uint16(xCondIs64), 5133, 5147,
-	/*5133*/ uint16(xCondDataSize), 5137, 5142, 0,
-	/*5137*/ uint16(xSetOp), uint16(JO),
-	/*5139*/ uint16(xReadCw),
-	/*5140*/ uint16(xArgRel16),
-	/*5141*/ uint16(xMatch),
-	/*5142*/ uint16(xSetOp), uint16(JO),
-	/*5144*/ uint16(xReadCd),
-	/*5145*/ uint16(xArgRel32),
-	/*5146*/ uint16(xMatch),
-	/*5147*/ uint16(xCondDataSize), 5151, 5142, 5156,
-	/*5151*/ uint16(xSetOp), uint16(JO),
-	/*5153*/ uint16(xReadCd),
-	/*5154*/ uint16(xArgRel32),
-	/*5155*/ uint16(xMatch),
-	/*5156*/ uint16(xSetOp), uint16(JO),
-	/*5158*/ uint16(xReadCd),
-	/*5159*/ uint16(xArgRel32),
-	/*5160*/ uint16(xMatch),
-	/*5161*/ uint16(xCondIs64), 5164, 5178,
-	/*5164*/ uint16(xCondDataSize), 5168, 5173, 0,
-	/*5168*/ uint16(xSetOp), uint16(JNO),
-	/*5170*/ uint16(xReadCw),
-	/*5171*/ uint16(xArgRel16),
-	/*5172*/ uint16(xMatch),
-	/*5173*/ uint16(xSetOp), uint16(JNO),
-	/*5175*/ uint16(xReadCd),
-	/*5176*/ uint16(xArgRel32),
-	/*5177*/ uint16(xMatch),
-	/*5178*/ uint16(xCondDataSize), 5182, 5173, 5187,
-	/*5182*/ uint16(xSetOp), uint16(JNO),
-	/*5184*/ uint16(xReadCd),
-	/*5185*/ uint16(xArgRel32),
-	/*5186*/ uint16(xMatch),
-	/*5187*/ uint16(xSetOp), uint16(JNO),
-	/*5189*/ uint16(xReadCd),
-	/*5190*/ uint16(xArgRel32),
-	/*5191*/ uint16(xMatch),
-	/*5192*/ uint16(xCondIs64), 5195, 5209,
-	/*5195*/ uint16(xCondDataSize), 5199, 5204, 0,
-	/*5199*/ uint16(xSetOp), uint16(JB),
-	/*5201*/ uint16(xReadCw),
-	/*5202*/ uint16(xArgRel16),
-	/*5203*/ uint16(xMatch),
-	/*5204*/ uint16(xSetOp), uint16(JB),
-	/*5206*/ uint16(xReadCd),
-	/*5207*/ uint16(xArgRel32),
-	/*5208*/ uint16(xMatch),
-	/*5209*/ uint16(xCondDataSize), 5213, 5204, 5218,
-	/*5213*/ uint16(xSetOp), uint16(JB),
-	/*5215*/ uint16(xReadCd),
-	/*5216*/ uint16(xArgRel32),
-	/*5217*/ uint16(xMatch),
-	/*5218*/ uint16(xSetOp), uint16(JB),
-	/*5220*/ uint16(xReadCd),
-	/*5221*/ uint16(xArgRel32),
-	/*5222*/ uint16(xMatch),
-	/*5223*/ uint16(xCondIs64), 5226, 5240,
-	/*5226*/ uint16(xCondDataSize), 5230, 5235, 0,
-	/*5230*/ uint16(xSetOp), uint16(JAE),
-	/*5232*/ uint16(xReadCw),
-	/*5233*/ uint16(xArgRel16),
-	/*5234*/ uint16(xMatch),
-	/*5235*/ uint16(xSetOp), uint16(JAE),
-	/*5237*/ uint16(xReadCd),
-	/*5238*/ uint16(xArgRel32),
-	/*5239*/ uint16(xMatch),
-	/*5240*/ uint16(xCondDataSize), 5244, 5235, 5249,
-	/*5244*/ uint16(xSetOp), uint16(JAE),
-	/*5246*/ uint16(xReadCd),
-	/*5247*/ uint16(xArgRel32),
-	/*5248*/ uint16(xMatch),
-	/*5249*/ uint16(xSetOp), uint16(JAE),
-	/*5251*/ uint16(xReadCd),
-	/*5252*/ uint16(xArgRel32),
-	/*5253*/ uint16(xMatch),
-	/*5254*/ uint16(xCondIs64), 5257, 5271,
-	/*5257*/ uint16(xCondDataSize), 5261, 5266, 0,
-	/*5261*/ uint16(xSetOp), uint16(JE),
-	/*5263*/ uint16(xReadCw),
-	/*5264*/ uint16(xArgRel16),
-	/*5265*/ uint16(xMatch),
-	/*5266*/ uint16(xSetOp), uint16(JE),
-	/*5268*/ uint16(xReadCd),
-	/*5269*/ uint16(xArgRel32),
-	/*5270*/ uint16(xMatch),
-	/*5271*/ uint16(xCondDataSize), 5275, 5266, 5280,
-	/*5275*/ uint16(xSetOp), uint16(JE),
-	/*5277*/ uint16(xReadCd),
-	/*5278*/ uint16(xArgRel32),
-	/*5279*/ uint16(xMatch),
-	/*5280*/ uint16(xSetOp), uint16(JE),
-	/*5282*/ uint16(xReadCd),
-	/*5283*/ uint16(xArgRel32),
-	/*5284*/ uint16(xMatch),
-	/*5285*/ uint16(xCondIs64), 5288, 5302,
-	/*5288*/ uint16(xCondDataSize), 5292, 5297, 0,
-	/*5292*/ uint16(xSetOp), uint16(JNE),
-	/*5294*/ uint16(xReadCw),
-	/*5295*/ uint16(xArgRel16),
-	/*5296*/ uint16(xMatch),
-	/*5297*/ uint16(xSetOp), uint16(JNE),
-	/*5299*/ uint16(xReadCd),
-	/*5300*/ uint16(xArgRel32),
-	/*5301*/ uint16(xMatch),
-	/*5302*/ uint16(xCondDataSize), 5306, 5297, 5311,
-	/*5306*/ uint16(xSetOp), uint16(JNE),
-	/*5308*/ uint16(xReadCd),
-	/*5309*/ uint16(xArgRel32),
-	/*5310*/ uint16(xMatch),
-	/*5311*/ uint16(xSetOp), uint16(JNE),
-	/*5313*/ uint16(xReadCd),
-	/*5314*/ uint16(xArgRel32),
-	/*5315*/ uint16(xMatch),
-	/*5316*/ uint16(xCondIs64), 5319, 5333,
-	/*5319*/ uint16(xCondDataSize), 5323, 5328, 0,
-	/*5323*/ uint16(xSetOp), uint16(JBE),
-	/*5325*/ uint16(xReadCw),
-	/*5326*/ uint16(xArgRel16),
-	/*5327*/ uint16(xMatch),
-	/*5328*/ uint16(xSetOp), uint16(JBE),
-	/*5330*/ uint16(xReadCd),
-	/*5331*/ uint16(xArgRel32),
-	/*5332*/ uint16(xMatch),
-	/*5333*/ uint16(xCondDataSize), 5337, 5328, 5342,
-	/*5337*/ uint16(xSetOp), uint16(JBE),
-	/*5339*/ uint16(xReadCd),
-	/*5340*/ uint16(xArgRel32),
-	/*5341*/ uint16(xMatch),
-	/*5342*/ uint16(xSetOp), uint16(JBE),
-	/*5344*/ uint16(xReadCd),
-	/*5345*/ uint16(xArgRel32),
-	/*5346*/ uint16(xMatch),
-	/*5347*/ uint16(xCondIs64), 5350, 5364,
-	/*5350*/ uint16(xCondDataSize), 5354, 5359, 0,
-	/*5354*/ uint16(xSetOp), uint16(JA),
-	/*5356*/ uint16(xReadCw),
-	/*5357*/ uint16(xArgRel16),
-	/*5358*/ uint16(xMatch),
-	/*5359*/ uint16(xSetOp), uint16(JA),
-	/*5361*/ uint16(xReadCd),
-	/*5362*/ uint16(xArgRel32),
-	/*5363*/ uint16(xMatch),
-	/*5364*/ uint16(xCondDataSize), 5368, 5359, 5373,
-	/*5368*/ uint16(xSetOp), uint16(JA),
-	/*5370*/ uint16(xReadCd),
-	/*5371*/ uint16(xArgRel32),
-	/*5372*/ uint16(xMatch),
-	/*5373*/ uint16(xSetOp), uint16(JA),
-	/*5375*/ uint16(xReadCd),
-	/*5376*/ uint16(xArgRel32),
-	/*5377*/ uint16(xMatch),
-	/*5378*/ uint16(xCondIs64), 5381, 5395,
-	/*5381*/ uint16(xCondDataSize), 5385, 5390, 0,
-	/*5385*/ uint16(xSetOp), uint16(JS),
-	/*5387*/ uint16(xReadCw),
-	/*5388*/ uint16(xArgRel16),
-	/*5389*/ uint16(xMatch),
-	/*5390*/ uint16(xSetOp), uint16(JS),
-	/*5392*/ uint16(xReadCd),
-	/*5393*/ uint16(xArgRel32),
-	/*5394*/ uint16(xMatch),
-	/*5395*/ uint16(xCondDataSize), 5399, 5390, 5404,
-	/*5399*/ uint16(xSetOp), uint16(JS),
-	/*5401*/ uint16(xReadCd),
-	/*5402*/ uint16(xArgRel32),
-	/*5403*/ uint16(xMatch),
-	/*5404*/ uint16(xSetOp), uint16(JS),
-	/*5406*/ uint16(xReadCd),
-	/*5407*/ uint16(xArgRel32),
-	/*5408*/ uint16(xMatch),
-	/*5409*/ uint16(xCondIs64), 5412, 5426,
-	/*5412*/ uint16(xCondDataSize), 5416, 5421, 0,
-	/*5416*/ uint16(xSetOp), uint16(JNS),
-	/*5418*/ uint16(xReadCw),
-	/*5419*/ uint16(xArgRel16),
-	/*5420*/ uint16(xMatch),
-	/*5421*/ uint16(xSetOp), uint16(JNS),
-	/*5423*/ uint16(xReadCd),
-	/*5424*/ uint16(xArgRel32),
-	/*5425*/ uint16(xMatch),
-	/*5426*/ uint16(xCondDataSize), 5430, 5421, 5435,
-	/*5430*/ uint16(xSetOp), uint16(JNS),
-	/*5432*/ uint16(xReadCd),
-	/*5433*/ uint16(xArgRel32),
-	/*5434*/ uint16(xMatch),
-	/*5435*/ uint16(xSetOp), uint16(JNS),
-	/*5437*/ uint16(xReadCd),
-	/*5438*/ uint16(xArgRel32),
-	/*5439*/ uint16(xMatch),
-	/*5440*/ uint16(xCondIs64), 5443, 5457,
-	/*5443*/ uint16(xCondDataSize), 5447, 5452, 0,
-	/*5447*/ uint16(xSetOp), uint16(JP),
-	/*5449*/ uint16(xReadCw),
-	/*5450*/ uint16(xArgRel16),
-	/*5451*/ uint16(xMatch),
-	/*5452*/ uint16(xSetOp), uint16(JP),
-	/*5454*/ uint16(xReadCd),
-	/*5455*/ uint16(xArgRel32),
-	/*5456*/ uint16(xMatch),
-	/*5457*/ uint16(xCondDataSize), 5461, 5452, 5466,
-	/*5461*/ uint16(xSetOp), uint16(JP),
-	/*5463*/ uint16(xReadCd),
-	/*5464*/ uint16(xArgRel32),
-	/*5465*/ uint16(xMatch),
-	/*5466*/ uint16(xSetOp), uint16(JP),
-	/*5468*/ uint16(xReadCd),
-	/*5469*/ uint16(xArgRel32),
-	/*5470*/ uint16(xMatch),
-	/*5471*/ uint16(xCondIs64), 5474, 5488,
-	/*5474*/ uint16(xCondDataSize), 5478, 5483, 0,
-	/*5478*/ uint16(xSetOp), uint16(JNP),
-	/*5480*/ uint16(xReadCw),
-	/*5481*/ uint16(xArgRel16),
-	/*5482*/ uint16(xMatch),
-	/*5483*/ uint16(xSetOp), uint16(JNP),
-	/*5485*/ uint16(xReadCd),
-	/*5486*/ uint16(xArgRel32),
-	/*5487*/ uint16(xMatch),
-	/*5488*/ uint16(xCondDataSize), 5492, 5483, 5497,
-	/*5492*/ uint16(xSetOp), uint16(JNP),
-	/*5494*/ uint16(xReadCd),
-	/*5495*/ uint16(xArgRel32),
-	/*5496*/ uint16(xMatch),
-	/*5497*/ uint16(xSetOp), uint16(JNP),
-	/*5499*/ uint16(xReadCd),
-	/*5500*/ uint16(xArgRel32),
-	/*5501*/ uint16(xMatch),
-	/*5502*/ uint16(xCondIs64), 5505, 5519,
-	/*5505*/ uint16(xCondDataSize), 5509, 5514, 0,
-	/*5509*/ uint16(xSetOp), uint16(JL),
-	/*5511*/ uint16(xReadCw),
-	/*5512*/ uint16(xArgRel16),
-	/*5513*/ uint16(xMatch),
-	/*5514*/ uint16(xSetOp), uint16(JL),
-	/*5516*/ uint16(xReadCd),
-	/*5517*/ uint16(xArgRel32),
-	/*5518*/ uint16(xMatch),
-	/*5519*/ uint16(xCondDataSize), 5523, 5514, 5528,
-	/*5523*/ uint16(xSetOp), uint16(JL),
-	/*5525*/ uint16(xReadCd),
-	/*5526*/ uint16(xArgRel32),
-	/*5527*/ uint16(xMatch),
-	/*5528*/ uint16(xSetOp), uint16(JL),
-	/*5530*/ uint16(xReadCd),
-	/*5531*/ uint16(xArgRel32),
-	/*5532*/ uint16(xMatch),
-	/*5533*/ uint16(xCondIs64), 5536, 5550,
-	/*5536*/ uint16(xCondDataSize), 5540, 5545, 0,
-	/*5540*/ uint16(xSetOp), uint16(JGE),
-	/*5542*/ uint16(xReadCw),
-	/*5543*/ uint16(xArgRel16),
-	/*5544*/ uint16(xMatch),
-	/*5545*/ uint16(xSetOp), uint16(JGE),
-	/*5547*/ uint16(xReadCd),
-	/*5548*/ uint16(xArgRel32),
-	/*5549*/ uint16(xMatch),
-	/*5550*/ uint16(xCondDataSize), 5554, 5545, 5559,
-	/*5554*/ uint16(xSetOp), uint16(JGE),
-	/*5556*/ uint16(xReadCd),
-	/*5557*/ uint16(xArgRel32),
-	/*5558*/ uint16(xMatch),
-	/*5559*/ uint16(xSetOp), uint16(JGE),
-	/*5561*/ uint16(xReadCd),
-	/*5562*/ uint16(xArgRel32),
-	/*5563*/ uint16(xMatch),
-	/*5564*/ uint16(xCondIs64), 5567, 5581,
-	/*5567*/ uint16(xCondDataSize), 5571, 5576, 0,
-	/*5571*/ uint16(xSetOp), uint16(JLE),
-	/*5573*/ uint16(xReadCw),
-	/*5574*/ uint16(xArgRel16),
-	/*5575*/ uint16(xMatch),
-	/*5576*/ uint16(xSetOp), uint16(JLE),
-	/*5578*/ uint16(xReadCd),
-	/*5579*/ uint16(xArgRel32),
-	/*5580*/ uint16(xMatch),
-	/*5581*/ uint16(xCondDataSize), 5585, 5576, 5590,
-	/*5585*/ uint16(xSetOp), uint16(JLE),
-	/*5587*/ uint16(xReadCd),
-	/*5588*/ uint16(xArgRel32),
-	/*5589*/ uint16(xMatch),
-	/*5590*/ uint16(xSetOp), uint16(JLE),
-	/*5592*/ uint16(xReadCd),
-	/*5593*/ uint16(xArgRel32),
-	/*5594*/ uint16(xMatch),
-	/*5595*/ uint16(xCondIs64), 5598, 5612,
-	/*5598*/ uint16(xCondDataSize), 5602, 5607, 0,
-	/*5602*/ uint16(xSetOp), uint16(JG),
-	/*5604*/ uint16(xReadCw),
-	/*5605*/ uint16(xArgRel16),
-	/*5606*/ uint16(xMatch),
-	/*5607*/ uint16(xSetOp), uint16(JG),
-	/*5609*/ uint16(xReadCd),
-	/*5610*/ uint16(xArgRel32),
-	/*5611*/ uint16(xMatch),
-	/*5612*/ uint16(xCondDataSize), 5616, 5607, 5621,
-	/*5616*/ uint16(xSetOp), uint16(JG),
-	/*5618*/ uint16(xReadCd),
-	/*5619*/ uint16(xArgRel32),
-	/*5620*/ uint16(xMatch),
-	/*5621*/ uint16(xSetOp), uint16(JG),
-	/*5623*/ uint16(xReadCd),
-	/*5624*/ uint16(xArgRel32),
-	/*5625*/ uint16(xMatch),
-	/*5626*/ uint16(xSetOp), uint16(SETO),
-	/*5628*/ uint16(xReadSlashR),
-	/*5629*/ uint16(xArgRM8),
-	/*5630*/ uint16(xMatch),
-	/*5631*/ uint16(xSetOp), uint16(SETNO),
-	/*5633*/ uint16(xReadSlashR),
-	/*5634*/ uint16(xArgRM8),
-	/*5635*/ uint16(xMatch),
-	/*5636*/ uint16(xSetOp), uint16(SETB),
-	/*5638*/ uint16(xReadSlashR),
-	/*5639*/ uint16(xArgRM8),
-	/*5640*/ uint16(xMatch),
-	/*5641*/ uint16(xSetOp), uint16(SETAE),
-	/*5643*/ uint16(xReadSlashR),
-	/*5644*/ uint16(xArgRM8),
-	/*5645*/ uint16(xMatch),
-	/*5646*/ uint16(xSetOp), uint16(SETE),
-	/*5648*/ uint16(xReadSlashR),
-	/*5649*/ uint16(xArgRM8),
-	/*5650*/ uint16(xMatch),
-	/*5651*/ uint16(xSetOp), uint16(SETNE),
-	/*5653*/ uint16(xReadSlashR),
-	/*5654*/ uint16(xArgRM8),
-	/*5655*/ uint16(xMatch),
-	/*5656*/ uint16(xSetOp), uint16(SETBE),
-	/*5658*/ uint16(xReadSlashR),
-	/*5659*/ uint16(xArgRM8),
-	/*5660*/ uint16(xMatch),
-	/*5661*/ uint16(xSetOp), uint16(SETA),
-	/*5663*/ uint16(xReadSlashR),
-	/*5664*/ uint16(xArgRM8),
-	/*5665*/ uint16(xMatch),
-	/*5666*/ uint16(xSetOp), uint16(SETS),
-	/*5668*/ uint16(xReadSlashR),
-	/*5669*/ uint16(xArgRM8),
-	/*5670*/ uint16(xMatch),
-	/*5671*/ uint16(xSetOp), uint16(SETNS),
-	/*5673*/ uint16(xReadSlashR),
-	/*5674*/ uint16(xArgRM8),
-	/*5675*/ uint16(xMatch),
-	/*5676*/ uint16(xSetOp), uint16(SETP),
-	/*5678*/ uint16(xReadSlashR),
-	/*5679*/ uint16(xArgRM8),
-	/*5680*/ uint16(xMatch),
-	/*5681*/ uint16(xSetOp), uint16(SETNP),
-	/*5683*/ uint16(xReadSlashR),
-	/*5684*/ uint16(xArgRM8),
-	/*5685*/ uint16(xMatch),
-	/*5686*/ uint16(xSetOp), uint16(SETL),
-	/*5688*/ uint16(xReadSlashR),
-	/*5689*/ uint16(xArgRM8),
-	/*5690*/ uint16(xMatch),
-	/*5691*/ uint16(xSetOp), uint16(SETGE),
-	/*5693*/ uint16(xReadSlashR),
-	/*5694*/ uint16(xArgRM8),
-	/*5695*/ uint16(xMatch),
-	/*5696*/ uint16(xSetOp), uint16(SETLE),
-	/*5698*/ uint16(xReadSlashR),
-	/*5699*/ uint16(xArgRM8),
-	/*5700*/ uint16(xMatch),
-	/*5701*/ uint16(xSetOp), uint16(SETG),
-	/*5703*/ uint16(xReadSlashR),
-	/*5704*/ uint16(xArgRM8),
-	/*5705*/ uint16(xMatch),
-	/*5706*/ uint16(xSetOp), uint16(PUSH),
-	/*5708*/ uint16(xArgFS),
-	/*5709*/ uint16(xMatch),
-	/*5710*/ uint16(xCondIs64), 5713, 5725,
-	/*5713*/ uint16(xCondDataSize), 5717, 5721, 0,
-	/*5717*/ uint16(xSetOp), uint16(POP),
-	/*5719*/ uint16(xArgFS),
-	/*5720*/ uint16(xMatch),
-	/*5721*/ uint16(xSetOp), uint16(POP),
-	/*5723*/ uint16(xArgFS),
-	/*5724*/ uint16(xMatch),
-	/*5725*/ uint16(xCondDataSize), 5717, 5729, 5733,
-	/*5729*/ uint16(xSetOp), uint16(POP),
-	/*5731*/ uint16(xArgFS),
-	/*5732*/ uint16(xMatch),
-	/*5733*/ uint16(xSetOp), uint16(POP),
-	/*5735*/ uint16(xArgFS),
-	/*5736*/ uint16(xMatch),
-	/*5737*/ uint16(xSetOp), uint16(CPUID),
-	/*5739*/ uint16(xMatch),
-	/*5740*/ uint16(xCondIs64), 5743, 5759,
-	/*5743*/ uint16(xCondDataSize), 5747, 5753, 0,
-	/*5747*/ uint16(xSetOp), uint16(BT),
-	/*5749*/ uint16(xReadSlashR),
-	/*5750*/ uint16(xArgRM16),
-	/*5751*/ uint16(xArgR16),
-	/*5752*/ uint16(xMatch),
-	/*5753*/ uint16(xSetOp), uint16(BT),
-	/*5755*/ uint16(xReadSlashR),
-	/*5756*/ uint16(xArgRM32),
-	/*5757*/ uint16(xArgR32),
-	/*5758*/ uint16(xMatch),
-	/*5759*/ uint16(xCondDataSize), 5747, 5753, 5763,
-	/*5763*/ uint16(xSetOp), uint16(BT),
-	/*5765*/ uint16(xReadSlashR),
-	/*5766*/ uint16(xArgRM64),
-	/*5767*/ uint16(xArgR64),
-	/*5768*/ uint16(xMatch),
-	/*5769*/ uint16(xCondIs64), 5772, 5792,
-	/*5772*/ uint16(xCondDataSize), 5776, 5784, 0,
-	/*5776*/ uint16(xSetOp), uint16(SHLD),
-	/*5778*/ uint16(xReadSlashR),
-	/*5779*/ uint16(xReadIb),
-	/*5780*/ uint16(xArgRM16),
-	/*5781*/ uint16(xArgR16),
-	/*5782*/ uint16(xArgImm8u),
-	/*5783*/ uint16(xMatch),
-	/*5784*/ uint16(xSetOp), uint16(SHLD),
-	/*5786*/ uint16(xReadSlashR),
-	/*5787*/ uint16(xReadIb),
-	/*5788*/ uint16(xArgRM32),
-	/*5789*/ uint16(xArgR32),
-	/*5790*/ uint16(xArgImm8u),
-	/*5791*/ uint16(xMatch),
-	/*5792*/ uint16(xCondDataSize), 5776, 5784, 5796,
-	/*5796*/ uint16(xSetOp), uint16(SHLD),
-	/*5798*/ uint16(xReadSlashR),
-	/*5799*/ uint16(xReadIb),
-	/*5800*/ uint16(xArgRM64),
-	/*5801*/ uint16(xArgR64),
-	/*5802*/ uint16(xArgImm8u),
-	/*5803*/ uint16(xMatch),
-	/*5804*/ uint16(xCondIs64), 5807, 5825,
-	/*5807*/ uint16(xCondDataSize), 5811, 5818, 0,
-	/*5811*/ uint16(xSetOp), uint16(SHLD),
-	/*5813*/ uint16(xReadSlashR),
-	/*5814*/ uint16(xArgRM16),
-	/*5815*/ uint16(xArgR16),
-	/*5816*/ uint16(xArgCL),
-	/*5817*/ uint16(xMatch),
-	/*5818*/ uint16(xSetOp), uint16(SHLD),
-	/*5820*/ uint16(xReadSlashR),
-	/*5821*/ uint16(xArgRM32),
-	/*5822*/ uint16(xArgR32),
-	/*5823*/ uint16(xArgCL),
-	/*5824*/ uint16(xMatch),
-	/*5825*/ uint16(xCondDataSize), 5811, 5818, 5829,
-	/*5829*/ uint16(xSetOp), uint16(SHLD),
-	/*5831*/ uint16(xReadSlashR),
-	/*5832*/ uint16(xArgRM64),
-	/*5833*/ uint16(xArgR64),
-	/*5834*/ uint16(xArgCL),
-	/*5835*/ uint16(xMatch),
-	/*5836*/ uint16(xSetOp), uint16(PUSH),
-	/*5838*/ uint16(xArgGS),
-	/*5839*/ uint16(xMatch),
-	/*5840*/ uint16(xCondIs64), 5843, 5855,
-	/*5843*/ uint16(xCondDataSize), 5847, 5851, 0,
-	/*5847*/ uint16(xSetOp), uint16(POP),
-	/*5849*/ uint16(xArgGS),
-	/*5850*/ uint16(xMatch),
-	/*5851*/ uint16(xSetOp), uint16(POP),
-	/*5853*/ uint16(xArgGS),
-	/*5854*/ uint16(xMatch),
-	/*5855*/ uint16(xCondDataSize), 5847, 5859, 5863,
-	/*5859*/ uint16(xSetOp), uint16(POP),
-	/*5861*/ uint16(xArgGS),
-	/*5862*/ uint16(xMatch),
-	/*5863*/ uint16(xSetOp), uint16(POP),
-	/*5865*/ uint16(xArgGS),
-	/*5866*/ uint16(xMatch),
-	/*5867*/ uint16(xSetOp), uint16(RSM),
-	/*5869*/ uint16(xMatch),
-	/*5870*/ uint16(xCondIs64), 5873, 5889,
-	/*5873*/ uint16(xCondDataSize), 5877, 5883, 0,
-	/*5877*/ uint16(xSetOp), uint16(BTS),
-	/*5879*/ uint16(xReadSlashR),
-	/*5880*/ uint16(xArgRM16),
-	/*5881*/ uint16(xArgR16),
-	/*5882*/ uint16(xMatch),
-	/*5883*/ uint16(xSetOp), uint16(BTS),
-	/*5885*/ uint16(xReadSlashR),
-	/*5886*/ uint16(xArgRM32),
-	/*5887*/ uint16(xArgR32),
-	/*5888*/ uint16(xMatch),
-	/*5889*/ uint16(xCondDataSize), 5877, 5883, 5893,
-	/*5893*/ uint16(xSetOp), uint16(BTS),
-	/*5895*/ uint16(xReadSlashR),
-	/*5896*/ uint16(xArgRM64),
-	/*5897*/ uint16(xArgR64),
-	/*5898*/ uint16(xMatch),
-	/*5899*/ uint16(xCondIs64), 5902, 5922,
-	/*5902*/ uint16(xCondDataSize), 5906, 5914, 0,
-	/*5906*/ uint16(xSetOp), uint16(SHRD),
-	/*5908*/ uint16(xReadSlashR),
-	/*5909*/ uint16(xReadIb),
-	/*5910*/ uint16(xArgRM16),
-	/*5911*/ uint16(xArgR16),
-	/*5912*/ uint16(xArgImm8u),
-	/*5913*/ uint16(xMatch),
-	/*5914*/ uint16(xSetOp), uint16(SHRD),
-	/*5916*/ uint16(xReadSlashR),
-	/*5917*/ uint16(xReadIb),
-	/*5918*/ uint16(xArgRM32),
-	/*5919*/ uint16(xArgR32),
-	/*5920*/ uint16(xArgImm8u),
-	/*5921*/ uint16(xMatch),
-	/*5922*/ uint16(xCondDataSize), 5906, 5914, 5926,
-	/*5926*/ uint16(xSetOp), uint16(SHRD),
-	/*5928*/ uint16(xReadSlashR),
-	/*5929*/ uint16(xReadIb),
-	/*5930*/ uint16(xArgRM64),
-	/*5931*/ uint16(xArgR64),
-	/*5932*/ uint16(xArgImm8u),
-	/*5933*/ uint16(xMatch),
-	/*5934*/ uint16(xCondIs64), 5937, 5955,
-	/*5937*/ uint16(xCondDataSize), 5941, 5948, 0,
-	/*5941*/ uint16(xSetOp), uint16(SHRD),
-	/*5943*/ uint16(xReadSlashR),
-	/*5944*/ uint16(xArgRM16),
-	/*5945*/ uint16(xArgR16),
-	/*5946*/ uint16(xArgCL),
-	/*5947*/ uint16(xMatch),
-	/*5948*/ uint16(xSetOp), uint16(SHRD),
-	/*5950*/ uint16(xReadSlashR),
-	/*5951*/ uint16(xArgRM32),
-	/*5952*/ uint16(xArgR32),
-	/*5953*/ uint16(xArgCL),
-	/*5954*/ uint16(xMatch),
-	/*5955*/ uint16(xCondDataSize), 5941, 5948, 5959,
-	/*5959*/ uint16(xSetOp), uint16(SHRD),
-	/*5961*/ uint16(xReadSlashR),
-	/*5962*/ uint16(xArgRM64),
-	/*5963*/ uint16(xArgR64),
-	/*5964*/ uint16(xArgCL),
-	/*5965*/ uint16(xMatch),
-	/*5966*/ uint16(xCondByte), 3,
-	0xE8, 6215,
-	0xF0, 6218,
-	0xF8, 6221,
-	/*5974*/ uint16(xCondSlashR),
-	5983, // 0
-	6037, // 1
-	6091, // 2
-	6120, // 3
-	6149, // 4
-	6172, // 5
-	6195, // 6
-	6211, // 7
-	/*5983*/ uint16(xCondIs64), 5986, 5998,
-	/*5986*/ uint16(xCondDataSize), 5990, 5994, 0,
-	/*5990*/ uint16(xSetOp), uint16(FXSAVE),
-	/*5992*/ uint16(xArgM512byte),
-	/*5993*/ uint16(xMatch),
-	/*5994*/ uint16(xSetOp), uint16(FXSAVE),
-	/*5996*/ uint16(xArgM512byte),
-	/*5997*/ uint16(xMatch),
-	/*5998*/ uint16(xCondPrefix), 2,
-	0xF3, 6012,
-	0x0, 6004,
-	/*6004*/ uint16(xCondDataSize), 5990, 5994, 6008,
-	/*6008*/ uint16(xSetOp), uint16(FXSAVE64),
-	/*6010*/ uint16(xArgM512byte),
-	/*6011*/ uint16(xMatch),
-	/*6012*/ uint16(xCondDataSize), 6016, 6023, 6030,
-	/*6016*/ uint16(xCondIsMem), 6019, 0,
-	/*6019*/ uint16(xSetOp), uint16(RDFSBASE),
-	/*6021*/ uint16(xArgRM32),
-	/*6022*/ uint16(xMatch),
-	/*6023*/ uint16(xCondIsMem), 6026, 0,
-	/*6026*/ uint16(xSetOp), uint16(RDFSBASE),
-	/*6028*/ uint16(xArgRM32),
-	/*6029*/ uint16(xMatch),
-	/*6030*/ uint16(xCondIsMem), 6033, 0,
-	/*6033*/ uint16(xSetOp), uint16(RDFSBASE),
-	/*6035*/ uint16(xArgRM64),
-	/*6036*/ uint16(xMatch),
-	/*6037*/ uint16(xCondIs64), 6040, 6052,
-	/*6040*/ uint16(xCondDataSize), 6044, 6048, 0,
-	/*6044*/ uint16(xSetOp), uint16(FXRSTOR),
-	/*6046*/ uint16(xArgM512byte),
-	/*6047*/ uint16(xMatch),
-	/*6048*/ uint16(xSetOp), uint16(FXRSTOR),
-	/*6050*/ uint16(xArgM512byte),
-	/*6051*/ uint16(xMatch),
-	/*6052*/ uint16(xCondPrefix), 2,
-	0xF3, 6066,
-	0x0, 6058,
-	/*6058*/ uint16(xCondDataSize), 6044, 6048, 6062,
-	/*6062*/ uint16(xSetOp), uint16(FXRSTOR64),
-	/*6064*/ uint16(xArgM512byte),
-	/*6065*/ uint16(xMatch),
-	/*6066*/ uint16(xCondDataSize), 6070, 6077, 6084,
-	/*6070*/ uint16(xCondIsMem), 6073, 0,
-	/*6073*/ uint16(xSetOp), uint16(RDGSBASE),
-	/*6075*/ uint16(xArgRM32),
-	/*6076*/ uint16(xMatch),
-	/*6077*/ uint16(xCondIsMem), 6080, 0,
-	/*6080*/ uint16(xSetOp), uint16(RDGSBASE),
-	/*6082*/ uint16(xArgRM32),
-	/*6083*/ uint16(xMatch),
-	/*6084*/ uint16(xCondIsMem), 6087, 0,
-	/*6087*/ uint16(xSetOp), uint16(RDGSBASE),
-	/*6089*/ uint16(xArgRM64),
-	/*6090*/ uint16(xMatch),
-	/*6091*/ uint16(xCondIs64), 6094, 6098,
-	/*6094*/ uint16(xSetOp), uint16(LDMXCSR),
-	/*6096*/ uint16(xArgM32),
-	/*6097*/ uint16(xMatch),
-	/*6098*/ uint16(xCondPrefix), 2,
-	0xF3, 6104,
-	0x0, 6094,
-	/*6104*/ uint16(xCondDataSize), 6108, 6112, 6116,
-	/*6108*/ uint16(xSetOp), uint16(WRFSBASE),
-	/*6110*/ uint16(xArgRM32),
-	/*6111*/ uint16(xMatch),
-	/*6112*/ uint16(xSetOp), uint16(WRFSBASE),
-	/*6114*/ uint16(xArgRM32),
-	/*6115*/ uint16(xMatch),
-	/*6116*/ uint16(xSetOp), uint16(WRFSBASE),
-	/*6118*/ uint16(xArgRM64),
-	/*6119*/ uint16(xMatch),
-	/*6120*/ uint16(xCondIs64), 6123, 6127,
-	/*6123*/ uint16(xSetOp), uint16(STMXCSR),
-	/*6125*/ uint16(xArgM32),
-	/*6126*/ uint16(xMatch),
-	/*6127*/ uint16(xCondPrefix), 2,
-	0xF3, 6133,
-	0x0, 6123,
-	/*6133*/ uint16(xCondDataSize), 6137, 6141, 6145,
-	/*6137*/ uint16(xSetOp), uint16(WRGSBASE),
-	/*6139*/ uint16(xArgRM32),
-	/*6140*/ uint16(xMatch),
-	/*6141*/ uint16(xSetOp), uint16(WRGSBASE),
-	/*6143*/ uint16(xArgRM32),
-	/*6144*/ uint16(xMatch),
-	/*6145*/ uint16(xSetOp), uint16(WRGSBASE),
-	/*6147*/ uint16(xArgRM64),
-	/*6148*/ uint16(xMatch),
-	/*6149*/ uint16(xCondIs64), 6152, 6164,
-	/*6152*/ uint16(xCondDataSize), 6156, 6160, 0,
-	/*6156*/ uint16(xSetOp), uint16(XSAVE),
-	/*6158*/ uint16(xArgMem),
-	/*6159*/ uint16(xMatch),
-	/*6160*/ uint16(xSetOp), uint16(XSAVE),
-	/*6162*/ uint16(xArgMem),
-	/*6163*/ uint16(xMatch),
-	/*6164*/ uint16(xCondDataSize), 6156, 6160, 6168,
-	/*6168*/ uint16(xSetOp), uint16(XSAVE64),
-	/*6170*/ uint16(xArgMem),
-	/*6171*/ uint16(xMatch),
-	/*6172*/ uint16(xCondIs64), 6175, 6187,
-	/*6175*/ uint16(xCondDataSize), 6179, 6183, 0,
-	/*6179*/ uint16(xSetOp), uint16(XRSTOR),
-	/*6181*/ uint16(xArgMem),
-	/*6182*/ uint16(xMatch),
-	/*6183*/ uint16(xSetOp), uint16(XRSTOR),
-	/*6185*/ uint16(xArgMem),
-	/*6186*/ uint16(xMatch),
-	/*6187*/ uint16(xCondDataSize), 6179, 6183, 6191,
-	/*6191*/ uint16(xSetOp), uint16(XRSTOR64),
-	/*6193*/ uint16(xArgMem),
-	/*6194*/ uint16(xMatch),
-	/*6195*/ uint16(xCondDataSize), 6199, 6203, 6207,
-	/*6199*/ uint16(xSetOp), uint16(XSAVEOPT),
-	/*6201*/ uint16(xArgMem),
-	/*6202*/ uint16(xMatch),
-	/*6203*/ uint16(xSetOp), uint16(XSAVEOPT),
-	/*6205*/ uint16(xArgMem),
-	/*6206*/ uint16(xMatch),
-	/*6207*/ uint16(xSetOp), uint16(XSAVEOPT64),
-	/*6209*/ uint16(xArgMem),
-	/*6210*/ uint16(xMatch),
-	/*6211*/ uint16(xSetOp), uint16(CLFLUSH),
-	/*6213*/ uint16(xArgM8),
-	/*6214*/ uint16(xMatch),
-	/*6215*/ uint16(xSetOp), uint16(LFENCE),
-	/*6217*/ uint16(xMatch),
-	/*6218*/ uint16(xSetOp), uint16(MFENCE),
-	/*6220*/ uint16(xMatch),
-	/*6221*/ uint16(xSetOp), uint16(SFENCE),
-	/*6223*/ uint16(xMatch),
-	/*6224*/ uint16(xCondIs64), 6227, 6243,
-	/*6227*/ uint16(xCondDataSize), 6231, 6237, 0,
-	/*6231*/ uint16(xSetOp), uint16(IMUL),
-	/*6233*/ uint16(xReadSlashR),
-	/*6234*/ uint16(xArgR16),
-	/*6235*/ uint16(xArgRM16),
-	/*6236*/ uint16(xMatch),
-	/*6237*/ uint16(xSetOp), uint16(IMUL),
-	/*6239*/ uint16(xReadSlashR),
-	/*6240*/ uint16(xArgR32),
-	/*6241*/ uint16(xArgRM32),
-	/*6242*/ uint16(xMatch),
-	/*6243*/ uint16(xCondDataSize), 6231, 6237, 6247,
-	/*6247*/ uint16(xSetOp), uint16(IMUL),
-	/*6249*/ uint16(xReadSlashR),
-	/*6250*/ uint16(xArgR64),
-	/*6251*/ uint16(xArgRM64),
-	/*6252*/ uint16(xMatch),
-	/*6253*/ uint16(xSetOp), uint16(CMPXCHG),
-	/*6255*/ uint16(xReadSlashR),
-	/*6256*/ uint16(xArgRM8),
-	/*6257*/ uint16(xArgR8),
-	/*6258*/ uint16(xMatch),
-	/*6259*/ uint16(xCondIs64), 6262, 6278,
-	/*6262*/ uint16(xCondDataSize), 6266, 6272, 0,
-	/*6266*/ uint16(xSetOp), uint16(CMPXCHG),
-	/*6268*/ uint16(xReadSlashR),
-	/*6269*/ uint16(xArgRM16),
-	/*6270*/ uint16(xArgR16),
-	/*6271*/ uint16(xMatch),
-	/*6272*/ uint16(xSetOp), uint16(CMPXCHG),
-	/*6274*/ uint16(xReadSlashR),
-	/*6275*/ uint16(xArgRM32),
-	/*6276*/ uint16(xArgR32),
-	/*6277*/ uint16(xMatch),
-	/*6278*/ uint16(xCondDataSize), 6266, 6272, 6282,
-	/*6282*/ uint16(xSetOp), uint16(CMPXCHG),
-	/*6284*/ uint16(xReadSlashR),
-	/*6285*/ uint16(xArgRM64),
-	/*6286*/ uint16(xArgR64),
-	/*6287*/ uint16(xMatch),
-	/*6288*/ uint16(xCondIs64), 6291, 6307,
-	/*6291*/ uint16(xCondDataSize), 6295, 6301, 0,
-	/*6295*/ uint16(xSetOp), uint16(LSS),
-	/*6297*/ uint16(xReadSlashR),
-	/*6298*/ uint16(xArgR16),
-	/*6299*/ uint16(xArgM16colon16),
-	/*6300*/ uint16(xMatch),
-	/*6301*/ uint16(xSetOp), uint16(LSS),
-	/*6303*/ uint16(xReadSlashR),
-	/*6304*/ uint16(xArgR32),
-	/*6305*/ uint16(xArgM16colon32),
-	/*6306*/ uint16(xMatch),
-	/*6307*/ uint16(xCondDataSize), 6295, 6301, 6311,
-	/*6311*/ uint16(xSetOp), uint16(LSS),
-	/*6313*/ uint16(xReadSlashR),
-	/*6314*/ uint16(xArgR64),
-	/*6315*/ uint16(xArgM16colon64),
-	/*6316*/ uint16(xMatch),
-	/*6317*/ uint16(xCondIs64), 6320, 6336,
-	/*6320*/ uint16(xCondDataSize), 6324, 6330, 0,
-	/*6324*/ uint16(xSetOp), uint16(BTR),
-	/*6326*/ uint16(xReadSlashR),
-	/*6327*/ uint16(xArgRM16),
-	/*6328*/ uint16(xArgR16),
-	/*6329*/ uint16(xMatch),
-	/*6330*/ uint16(xSetOp), uint16(BTR),
-	/*6332*/ uint16(xReadSlashR),
-	/*6333*/ uint16(xArgRM32),
-	/*6334*/ uint16(xArgR32),
-	/*6335*/ uint16(xMatch),
-	/*6336*/ uint16(xCondDataSize), 6324, 6330, 6340,
-	/*6340*/ uint16(xSetOp), uint16(BTR),
-	/*6342*/ uint16(xReadSlashR),
-	/*6343*/ uint16(xArgRM64),
-	/*6344*/ uint16(xArgR64),
-	/*6345*/ uint16(xMatch),
-	/*6346*/ uint16(xCondIs64), 6349, 6365,
-	/*6349*/ uint16(xCondDataSize), 6353, 6359, 0,
-	/*6353*/ uint16(xSetOp), uint16(LFS),
-	/*6355*/ uint16(xReadSlashR),
-	/*6356*/ uint16(xArgR16),
-	/*6357*/ uint16(xArgM16colon16),
-	/*6358*/ uint16(xMatch),
-	/*6359*/ uint16(xSetOp), uint16(LFS),
-	/*6361*/ uint16(xReadSlashR),
-	/*6362*/ uint16(xArgR32),
-	/*6363*/ uint16(xArgM16colon32),
-	/*6364*/ uint16(xMatch),
-	/*6365*/ uint16(xCondDataSize), 6353, 6359, 6369,
-	/*6369*/ uint16(xSetOp), uint16(LFS),
-	/*6371*/ uint16(xReadSlashR),
-	/*6372*/ uint16(xArgR64),
-	/*6373*/ uint16(xArgM16colon64),
-	/*6374*/ uint16(xMatch),
-	/*6375*/ uint16(xCondIs64), 6378, 6394,
-	/*6378*/ uint16(xCondDataSize), 6382, 6388, 0,
-	/*6382*/ uint16(xSetOp), uint16(LGS),
-	/*6384*/ uint16(xReadSlashR),
-	/*6385*/ uint16(xArgR16),
-	/*6386*/ uint16(xArgM16colon16),
-	/*6387*/ uint16(xMatch),
-	/*6388*/ uint16(xSetOp), uint16(LGS),
-	/*6390*/ uint16(xReadSlashR),
-	/*6391*/ uint16(xArgR32),
-	/*6392*/ uint16(xArgM16colon32),
-	/*6393*/ uint16(xMatch),
-	/*6394*/ uint16(xCondDataSize), 6382, 6388, 6398,
-	/*6398*/ uint16(xSetOp), uint16(LGS),
-	/*6400*/ uint16(xReadSlashR),
-	/*6401*/ uint16(xArgR64),
-	/*6402*/ uint16(xArgM16colon64),
-	/*6403*/ uint16(xMatch),
-	/*6404*/ uint16(xCondIs64), 6407, 6423,
-	/*6407*/ uint16(xCondDataSize), 6411, 6417, 0,
-	/*6411*/ uint16(xSetOp), uint16(MOVZX),
-	/*6413*/ uint16(xReadSlashR),
-	/*6414*/ uint16(xArgR16),
-	/*6415*/ uint16(xArgRM8),
-	/*6416*/ uint16(xMatch),
-	/*6417*/ uint16(xSetOp), uint16(MOVZX),
-	/*6419*/ uint16(xReadSlashR),
-	/*6420*/ uint16(xArgR32),
-	/*6421*/ uint16(xArgRM8),
-	/*6422*/ uint16(xMatch),
-	/*6423*/ uint16(xCondDataSize), 6411, 6417, 6427,
-	/*6427*/ uint16(xSetOp), uint16(MOVZX),
-	/*6429*/ uint16(xReadSlashR),
-	/*6430*/ uint16(xArgR64),
-	/*6431*/ uint16(xArgRM8),
-	/*6432*/ uint16(xMatch),
-	/*6433*/ uint16(xCondIs64), 6436, 6452,
-	/*6436*/ uint16(xCondDataSize), 6440, 6446, 0,
-	/*6440*/ uint16(xSetOp), uint16(MOVZX),
-	/*6442*/ uint16(xReadSlashR),
-	/*6443*/ uint16(xArgR16),
-	/*6444*/ uint16(xArgRM16),
-	/*6445*/ uint16(xMatch),
-	/*6446*/ uint16(xSetOp), uint16(MOVZX),
-	/*6448*/ uint16(xReadSlashR),
-	/*6449*/ uint16(xArgR32),
-	/*6450*/ uint16(xArgRM16),
-	/*6451*/ uint16(xMatch),
-	/*6452*/ uint16(xCondDataSize), 6440, 6446, 6456,
-	/*6456*/ uint16(xSetOp), uint16(MOVZX),
-	/*6458*/ uint16(xReadSlashR),
-	/*6459*/ uint16(xArgR64),
-	/*6460*/ uint16(xArgRM16),
-	/*6461*/ uint16(xMatch),
-	/*6462*/ uint16(xCondIs64), 6465, 6485,
-	/*6465*/ uint16(xCondPrefix), 1,
-	0xF3, 6469,
-	/*6469*/ uint16(xCondDataSize), 6473, 6479, 0,
-	/*6473*/ uint16(xSetOp), uint16(POPCNT),
-	/*6475*/ uint16(xReadSlashR),
-	/*6476*/ uint16(xArgR16),
-	/*6477*/ uint16(xArgRM16),
-	/*6478*/ uint16(xMatch),
-	/*6479*/ uint16(xSetOp), uint16(POPCNT),
-	/*6481*/ uint16(xReadSlashR),
-	/*6482*/ uint16(xArgR32),
-	/*6483*/ uint16(xArgRM32),
-	/*6484*/ uint16(xMatch),
-	/*6485*/ uint16(xCondPrefix), 1,
-	0xF3, 6489,
-	/*6489*/ uint16(xCondDataSize), 6473, 6479, 6493,
-	/*6493*/ uint16(xSetOp), uint16(POPCNT),
-	/*6495*/ uint16(xReadSlashR),
-	/*6496*/ uint16(xArgR64),
-	/*6497*/ uint16(xArgRM64),
-	/*6498*/ uint16(xMatch),
-	/*6499*/ uint16(xSetOp), uint16(UD1),
-	/*6501*/ uint16(xMatch),
-	/*6502*/ uint16(xCondSlashR),
+	4908, // 6
+	4926, // 7
+	/*4880*/ uint16(xCondPrefix), 2,
+	0x66, 4892,
+	0x0, 4886,
+	/*4886*/ uint16(xSetOp), uint16(PSRLQ),
+	/*4888*/ uint16(xReadIb),
+	/*4889*/ uint16(xArgMm2),
+	/*4890*/ uint16(xArgImm8u),
+	/*4891*/ uint16(xMatch),
+	/*4892*/ uint16(xSetOp), uint16(PSRLQ),
+	/*4894*/ uint16(xReadIb),
+	/*4895*/ uint16(xArgXmm2),
+	/*4896*/ uint16(xArgImm8u),
+	/*4897*/ uint16(xMatch),
+	/*4898*/ uint16(xCondPrefix), 1,
+	0x66, 4902,
+	/*4902*/ uint16(xSetOp), uint16(PSRLDQ),
+	/*4904*/ uint16(xReadIb),
+	/*4905*/ uint16(xArgXmm2),
+	/*4906*/ uint16(xArgImm8u),
+	/*4907*/ uint16(xMatch),
+	/*4908*/ uint16(xCondPrefix), 2,
+	0x66, 4920,
+	0x0, 4914,
+	/*4914*/ uint16(xSetOp), uint16(PSLLQ),
+	/*4916*/ uint16(xReadIb),
+	/*4917*/ uint16(xArgMm2),
+	/*4918*/ uint16(xArgImm8u),
+	/*4919*/ uint16(xMatch),
+	/*4920*/ uint16(xSetOp), uint16(PSLLQ),
+	/*4922*/ uint16(xReadIb),
+	/*4923*/ uint16(xArgXmm2),
+	/*4924*/ uint16(xArgImm8u),
+	/*4925*/ uint16(xMatch),
+	/*4926*/ uint16(xCondPrefix), 1,
+	0x66, 4930,
+	/*4930*/ uint16(xSetOp), uint16(PSLLDQ),
+	/*4932*/ uint16(xReadIb),
+	/*4933*/ uint16(xArgXmm2),
+	/*4934*/ uint16(xArgImm8u),
+	/*4935*/ uint16(xMatch),
+	/*4936*/ uint16(xCondPrefix), 2,
+	0x66, 4948,
+	0x0, 4942,
+	/*4942*/ uint16(xSetOp), uint16(PCMPEQB),
+	/*4944*/ uint16(xReadSlashR),
+	/*4945*/ uint16(xArgMm),
+	/*4946*/ uint16(xArgMmM64),
+	/*4947*/ uint16(xMatch),
+	/*4948*/ uint16(xSetOp), uint16(PCMPEQB),
+	/*4950*/ uint16(xReadSlashR),
+	/*4951*/ uint16(xArgXmm1),
+	/*4952*/ uint16(xArgXmm2M128),
+	/*4953*/ uint16(xMatch),
+	/*4954*/ uint16(xCondPrefix), 2,
+	0x66, 4966,
+	0x0, 4960,
+	/*4960*/ uint16(xSetOp), uint16(PCMPEQW),
+	/*4962*/ uint16(xReadSlashR),
+	/*4963*/ uint16(xArgMm),
+	/*4964*/ uint16(xArgMmM64),
+	/*4965*/ uint16(xMatch),
+	/*4966*/ uint16(xSetOp), uint16(PCMPEQW),
+	/*4968*/ uint16(xReadSlashR),
+	/*4969*/ uint16(xArgXmm1),
+	/*4970*/ uint16(xArgXmm2M128),
+	/*4971*/ uint16(xMatch),
+	/*4972*/ uint16(xCondPrefix), 2,
+	0x66, 4984,
+	0x0, 4978,
+	/*4978*/ uint16(xSetOp), uint16(PCMPEQD),
+	/*4980*/ uint16(xReadSlashR),
+	/*4981*/ uint16(xArgMm),
+	/*4982*/ uint16(xArgMmM64),
+	/*4983*/ uint16(xMatch),
+	/*4984*/ uint16(xSetOp), uint16(PCMPEQD),
+	/*4986*/ uint16(xReadSlashR),
+	/*4987*/ uint16(xArgXmm1),
+	/*4988*/ uint16(xArgXmm2M128),
+	/*4989*/ uint16(xMatch),
+	/*4990*/ uint16(xSetOp), uint16(EMMS),
+	/*4992*/ uint16(xMatch),
+	/*4993*/ uint16(xCondPrefix), 2,
+	0xF2, 5005,
+	0x66, 4999,
+	/*4999*/ uint16(xSetOp), uint16(HADDPD),
+	/*5001*/ uint16(xReadSlashR),
+	/*5002*/ uint16(xArgXmm1),
+	/*5003*/ uint16(xArgXmm2M128),
+	/*5004*/ uint16(xMatch),
+	/*5005*/ uint16(xSetOp), uint16(HADDPS),
+	/*5007*/ uint16(xReadSlashR),
+	/*5008*/ uint16(xArgXmm1),
+	/*5009*/ uint16(xArgXmm2M128),
+	/*5010*/ uint16(xMatch),
+	/*5011*/ uint16(xCondPrefix), 2,
+	0xF2, 5023,
+	0x66, 5017,
+	/*5017*/ uint16(xSetOp), uint16(HSUBPD),
+	/*5019*/ uint16(xReadSlashR),
+	/*5020*/ uint16(xArgXmm1),
+	/*5021*/ uint16(xArgXmm2M128),
+	/*5022*/ uint16(xMatch),
+	/*5023*/ uint16(xSetOp), uint16(HSUBPS),
+	/*5025*/ uint16(xReadSlashR),
+	/*5026*/ uint16(xArgXmm1),
+	/*5027*/ uint16(xArgXmm2M128),
+	/*5028*/ uint16(xMatch),
+	/*5029*/ uint16(xCondIs64), 5032, 5078,
+	/*5032*/ uint16(xCondPrefix), 3,
+	0xF3, 5072,
+	0x66, 5056,
+	0x0, 5040,
+	/*5040*/ uint16(xCondDataSize), 5044, 5050, 0,
+	/*5044*/ uint16(xSetOp), uint16(MOVD),
+	/*5046*/ uint16(xReadSlashR),
+	/*5047*/ uint16(xArgRM32),
+	/*5048*/ uint16(xArgMm),
+	/*5049*/ uint16(xMatch),
+	/*5050*/ uint16(xSetOp), uint16(MOVD),
+	/*5052*/ uint16(xReadSlashR),
+	/*5053*/ uint16(xArgRM32),
+	/*5054*/ uint16(xArgMm),
+	/*5055*/ uint16(xMatch),
+	/*5056*/ uint16(xCondDataSize), 5060, 5066, 0,
+	/*5060*/ uint16(xSetOp), uint16(MOVD),
+	/*5062*/ uint16(xReadSlashR),
+	/*5063*/ uint16(xArgRM32),
+	/*5064*/ uint16(xArgXmm),
+	/*5065*/ uint16(xMatch),
+	/*5066*/ uint16(xSetOp), uint16(MOVD),
+	/*5068*/ uint16(xReadSlashR),
+	/*5069*/ uint16(xArgRM32),
+	/*5070*/ uint16(xArgXmm),
+	/*5071*/ uint16(xMatch),
+	/*5072*/ uint16(xSetOp), uint16(MOVQ),
+	/*5074*/ uint16(xReadSlashR),
+	/*5075*/ uint16(xArgXmm1),
+	/*5076*/ uint16(xArgXmm2M64),
+	/*5077*/ uint16(xMatch),
+	/*5078*/ uint16(xCondPrefix), 3,
+	0xF3, 5072,
+	0x66, 5096,
+	0x0, 5086,
+	/*5086*/ uint16(xCondDataSize), 5044, 5050, 5090,
+	/*5090*/ uint16(xSetOp), uint16(MOVQ),
+	/*5092*/ uint16(xReadSlashR),
+	/*5093*/ uint16(xArgRM64),
+	/*5094*/ uint16(xArgMm),
+	/*5095*/ uint16(xMatch),
+	/*5096*/ uint16(xCondDataSize), 5060, 5066, 5100,
+	/*5100*/ uint16(xSetOp), uint16(MOVQ),
+	/*5102*/ uint16(xReadSlashR),
+	/*5103*/ uint16(xArgRM64),
+	/*5104*/ uint16(xArgXmm),
+	/*5105*/ uint16(xMatch),
+	/*5106*/ uint16(xCondPrefix), 3,
+	0xF3, 5126,
+	0x66, 5120,
+	0x0, 5114,
+	/*5114*/ uint16(xSetOp), uint16(MOVQ),
+	/*5116*/ uint16(xReadSlashR),
+	/*5117*/ uint16(xArgMmM64),
+	/*5118*/ uint16(xArgMm),
+	/*5119*/ uint16(xMatch),
+	/*5120*/ uint16(xSetOp), uint16(MOVDQA),
+	/*5122*/ uint16(xReadSlashR),
+	/*5123*/ uint16(xArgXmm2M128),
+	/*5124*/ uint16(xArgXmm1),
+	/*5125*/ uint16(xMatch),
+	/*5126*/ uint16(xSetOp), uint16(MOVDQU),
+	/*5128*/ uint16(xReadSlashR),
+	/*5129*/ uint16(xArgXmm2M128),
+	/*5130*/ uint16(xArgXmm1),
+	/*5131*/ uint16(xMatch),
+	/*5132*/ uint16(xCondIs64), 5135, 5149,
+	/*5135*/ uint16(xCondDataSize), 5139, 5144, 0,
+	/*5139*/ uint16(xSetOp), uint16(JO),
+	/*5141*/ uint16(xReadCw),
+	/*5142*/ uint16(xArgRel16),
+	/*5143*/ uint16(xMatch),
+	/*5144*/ uint16(xSetOp), uint16(JO),
+	/*5146*/ uint16(xReadCd),
+	/*5147*/ uint16(xArgRel32),
+	/*5148*/ uint16(xMatch),
+	/*5149*/ uint16(xCondDataSize), 5153, 5144, 5158,
+	/*5153*/ uint16(xSetOp), uint16(JO),
+	/*5155*/ uint16(xReadCd),
+	/*5156*/ uint16(xArgRel32),
+	/*5157*/ uint16(xMatch),
+	/*5158*/ uint16(xSetOp), uint16(JO),
+	/*5160*/ uint16(xReadCd),
+	/*5161*/ uint16(xArgRel32),
+	/*5162*/ uint16(xMatch),
+	/*5163*/ uint16(xCondIs64), 5166, 5180,
+	/*5166*/ uint16(xCondDataSize), 5170, 5175, 0,
+	/*5170*/ uint16(xSetOp), uint16(JNO),
+	/*5172*/ uint16(xReadCw),
+	/*5173*/ uint16(xArgRel16),
+	/*5174*/ uint16(xMatch),
+	/*5175*/ uint16(xSetOp), uint16(JNO),
+	/*5177*/ uint16(xReadCd),
+	/*5178*/ uint16(xArgRel32),
+	/*5179*/ uint16(xMatch),
+	/*5180*/ uint16(xCondDataSize), 5184, 5175, 5189,
+	/*5184*/ uint16(xSetOp), uint16(JNO),
+	/*5186*/ uint16(xReadCd),
+	/*5187*/ uint16(xArgRel32),
+	/*5188*/ uint16(xMatch),
+	/*5189*/ uint16(xSetOp), uint16(JNO),
+	/*5191*/ uint16(xReadCd),
+	/*5192*/ uint16(xArgRel32),
+	/*5193*/ uint16(xMatch),
+	/*5194*/ uint16(xCondIs64), 5197, 5211,
+	/*5197*/ uint16(xCondDataSize), 5201, 5206, 0,
+	/*5201*/ uint16(xSetOp), uint16(JB),
+	/*5203*/ uint16(xReadCw),
+	/*5204*/ uint16(xArgRel16),
+	/*5205*/ uint16(xMatch),
+	/*5206*/ uint16(xSetOp), uint16(JB),
+	/*5208*/ uint16(xReadCd),
+	/*5209*/ uint16(xArgRel32),
+	/*5210*/ uint16(xMatch),
+	/*5211*/ uint16(xCondDataSize), 5215, 5206, 5220,
+	/*5215*/ uint16(xSetOp), uint16(JB),
+	/*5217*/ uint16(xReadCd),
+	/*5218*/ uint16(xArgRel32),
+	/*5219*/ uint16(xMatch),
+	/*5220*/ uint16(xSetOp), uint16(JB),
+	/*5222*/ uint16(xReadCd),
+	/*5223*/ uint16(xArgRel32),
+	/*5224*/ uint16(xMatch),
+	/*5225*/ uint16(xCondIs64), 5228, 5242,
+	/*5228*/ uint16(xCondDataSize), 5232, 5237, 0,
+	/*5232*/ uint16(xSetOp), uint16(JAE),
+	/*5234*/ uint16(xReadCw),
+	/*5235*/ uint16(xArgRel16),
+	/*5236*/ uint16(xMatch),
+	/*5237*/ uint16(xSetOp), uint16(JAE),
+	/*5239*/ uint16(xReadCd),
+	/*5240*/ uint16(xArgRel32),
+	/*5241*/ uint16(xMatch),
+	/*5242*/ uint16(xCondDataSize), 5246, 5237, 5251,
+	/*5246*/ uint16(xSetOp), uint16(JAE),
+	/*5248*/ uint16(xReadCd),
+	/*5249*/ uint16(xArgRel32),
+	/*5250*/ uint16(xMatch),
+	/*5251*/ uint16(xSetOp), uint16(JAE),
+	/*5253*/ uint16(xReadCd),
+	/*5254*/ uint16(xArgRel32),
+	/*5255*/ uint16(xMatch),
+	/*5256*/ uint16(xCondIs64), 5259, 5273,
+	/*5259*/ uint16(xCondDataSize), 5263, 5268, 0,
+	/*5263*/ uint16(xSetOp), uint16(JE),
+	/*5265*/ uint16(xReadCw),
+	/*5266*/ uint16(xArgRel16),
+	/*5267*/ uint16(xMatch),
+	/*5268*/ uint16(xSetOp), uint16(JE),
+	/*5270*/ uint16(xReadCd),
+	/*5271*/ uint16(xArgRel32),
+	/*5272*/ uint16(xMatch),
+	/*5273*/ uint16(xCondDataSize), 5277, 5268, 5282,
+	/*5277*/ uint16(xSetOp), uint16(JE),
+	/*5279*/ uint16(xReadCd),
+	/*5280*/ uint16(xArgRel32),
+	/*5281*/ uint16(xMatch),
+	/*5282*/ uint16(xSetOp), uint16(JE),
+	/*5284*/ uint16(xReadCd),
+	/*5285*/ uint16(xArgRel32),
+	/*5286*/ uint16(xMatch),
+	/*5287*/ uint16(xCondIs64), 5290, 5304,
+	/*5290*/ uint16(xCondDataSize), 5294, 5299, 0,
+	/*5294*/ uint16(xSetOp), uint16(JNE),
+	/*5296*/ uint16(xReadCw),
+	/*5297*/ uint16(xArgRel16),
+	/*5298*/ uint16(xMatch),
+	/*5299*/ uint16(xSetOp), uint16(JNE),
+	/*5301*/ uint16(xReadCd),
+	/*5302*/ uint16(xArgRel32),
+	/*5303*/ uint16(xMatch),
+	/*5304*/ uint16(xCondDataSize), 5308, 5299, 5313,
+	/*5308*/ uint16(xSetOp), uint16(JNE),
+	/*5310*/ uint16(xReadCd),
+	/*5311*/ uint16(xArgRel32),
+	/*5312*/ uint16(xMatch),
+	/*5313*/ uint16(xSetOp), uint16(JNE),
+	/*5315*/ uint16(xReadCd),
+	/*5316*/ uint16(xArgRel32),
+	/*5317*/ uint16(xMatch),
+	/*5318*/ uint16(xCondIs64), 5321, 5335,
+	/*5321*/ uint16(xCondDataSize), 5325, 5330, 0,
+	/*5325*/ uint16(xSetOp), uint16(JBE),
+	/*5327*/ uint16(xReadCw),
+	/*5328*/ uint16(xArgRel16),
+	/*5329*/ uint16(xMatch),
+	/*5330*/ uint16(xSetOp), uint16(JBE),
+	/*5332*/ uint16(xReadCd),
+	/*5333*/ uint16(xArgRel32),
+	/*5334*/ uint16(xMatch),
+	/*5335*/ uint16(xCondDataSize), 5339, 5330, 5344,
+	/*5339*/ uint16(xSetOp), uint16(JBE),
+	/*5341*/ uint16(xReadCd),
+	/*5342*/ uint16(xArgRel32),
+	/*5343*/ uint16(xMatch),
+	/*5344*/ uint16(xSetOp), uint16(JBE),
+	/*5346*/ uint16(xReadCd),
+	/*5347*/ uint16(xArgRel32),
+	/*5348*/ uint16(xMatch),
+	/*5349*/ uint16(xCondIs64), 5352, 5366,
+	/*5352*/ uint16(xCondDataSize), 5356, 5361, 0,
+	/*5356*/ uint16(xSetOp), uint16(JA),
+	/*5358*/ uint16(xReadCw),
+	/*5359*/ uint16(xArgRel16),
+	/*5360*/ uint16(xMatch),
+	/*5361*/ uint16(xSetOp), uint16(JA),
+	/*5363*/ uint16(xReadCd),
+	/*5364*/ uint16(xArgRel32),
+	/*5365*/ uint16(xMatch),
+	/*5366*/ uint16(xCondDataSize), 5370, 5361, 5375,
+	/*5370*/ uint16(xSetOp), uint16(JA),
+	/*5372*/ uint16(xReadCd),
+	/*5373*/ uint16(xArgRel32),
+	/*5374*/ uint16(xMatch),
+	/*5375*/ uint16(xSetOp), uint16(JA),
+	/*5377*/ uint16(xReadCd),
+	/*5378*/ uint16(xArgRel32),
+	/*5379*/ uint16(xMatch),
+	/*5380*/ uint16(xCondIs64), 5383, 5397,
+	/*5383*/ uint16(xCondDataSize), 5387, 5392, 0,
+	/*5387*/ uint16(xSetOp), uint16(JS),
+	/*5389*/ uint16(xReadCw),
+	/*5390*/ uint16(xArgRel16),
+	/*5391*/ uint16(xMatch),
+	/*5392*/ uint16(xSetOp), uint16(JS),
+	/*5394*/ uint16(xReadCd),
+	/*5395*/ uint16(xArgRel32),
+	/*5396*/ uint16(xMatch),
+	/*5397*/ uint16(xCondDataSize), 5401, 5392, 5406,
+	/*5401*/ uint16(xSetOp), uint16(JS),
+	/*5403*/ uint16(xReadCd),
+	/*5404*/ uint16(xArgRel32),
+	/*5405*/ uint16(xMatch),
+	/*5406*/ uint16(xSetOp), uint16(JS),
+	/*5408*/ uint16(xReadCd),
+	/*5409*/ uint16(xArgRel32),
+	/*5410*/ uint16(xMatch),
+	/*5411*/ uint16(xCondIs64), 5414, 5428,
+	/*5414*/ uint16(xCondDataSize), 5418, 5423, 0,
+	/*5418*/ uint16(xSetOp), uint16(JNS),
+	/*5420*/ uint16(xReadCw),
+	/*5421*/ uint16(xArgRel16),
+	/*5422*/ uint16(xMatch),
+	/*5423*/ uint16(xSetOp), uint16(JNS),
+	/*5425*/ uint16(xReadCd),
+	/*5426*/ uint16(xArgRel32),
+	/*5427*/ uint16(xMatch),
+	/*5428*/ uint16(xCondDataSize), 5432, 5423, 5437,
+	/*5432*/ uint16(xSetOp), uint16(JNS),
+	/*5434*/ uint16(xReadCd),
+	/*5435*/ uint16(xArgRel32),
+	/*5436*/ uint16(xMatch),
+	/*5437*/ uint16(xSetOp), uint16(JNS),
+	/*5439*/ uint16(xReadCd),
+	/*5440*/ uint16(xArgRel32),
+	/*5441*/ uint16(xMatch),
+	/*5442*/ uint16(xCondIs64), 5445, 5459,
+	/*5445*/ uint16(xCondDataSize), 5449, 5454, 0,
+	/*5449*/ uint16(xSetOp), uint16(JP),
+	/*5451*/ uint16(xReadCw),
+	/*5452*/ uint16(xArgRel16),
+	/*5453*/ uint16(xMatch),
+	/*5454*/ uint16(xSetOp), uint16(JP),
+	/*5456*/ uint16(xReadCd),
+	/*5457*/ uint16(xArgRel32),
+	/*5458*/ uint16(xMatch),
+	/*5459*/ uint16(xCondDataSize), 5463, 5454, 5468,
+	/*5463*/ uint16(xSetOp), uint16(JP),
+	/*5465*/ uint16(xReadCd),
+	/*5466*/ uint16(xArgRel32),
+	/*5467*/ uint16(xMatch),
+	/*5468*/ uint16(xSetOp), uint16(JP),
+	/*5470*/ uint16(xReadCd),
+	/*5471*/ uint16(xArgRel32),
+	/*5472*/ uint16(xMatch),
+	/*5473*/ uint16(xCondIs64), 5476, 5490,
+	/*5476*/ uint16(xCondDataSize), 5480, 5485, 0,
+	/*5480*/ uint16(xSetOp), uint16(JNP),
+	/*5482*/ uint16(xReadCw),
+	/*5483*/ uint16(xArgRel16),
+	/*5484*/ uint16(xMatch),
+	/*5485*/ uint16(xSetOp), uint16(JNP),
+	/*5487*/ uint16(xReadCd),
+	/*5488*/ uint16(xArgRel32),
+	/*5489*/ uint16(xMatch),
+	/*5490*/ uint16(xCondDataSize), 5494, 5485, 5499,
+	/*5494*/ uint16(xSetOp), uint16(JNP),
+	/*5496*/ uint16(xReadCd),
+	/*5497*/ uint16(xArgRel32),
+	/*5498*/ uint16(xMatch),
+	/*5499*/ uint16(xSetOp), uint16(JNP),
+	/*5501*/ uint16(xReadCd),
+	/*5502*/ uint16(xArgRel32),
+	/*5503*/ uint16(xMatch),
+	/*5504*/ uint16(xCondIs64), 5507, 5521,
+	/*5507*/ uint16(xCondDataSize), 5511, 5516, 0,
+	/*5511*/ uint16(xSetOp), uint16(JL),
+	/*5513*/ uint16(xReadCw),
+	/*5514*/ uint16(xArgRel16),
+	/*5515*/ uint16(xMatch),
+	/*5516*/ uint16(xSetOp), uint16(JL),
+	/*5518*/ uint16(xReadCd),
+	/*5519*/ uint16(xArgRel32),
+	/*5520*/ uint16(xMatch),
+	/*5521*/ uint16(xCondDataSize), 5525, 5516, 5530,
+	/*5525*/ uint16(xSetOp), uint16(JL),
+	/*5527*/ uint16(xReadCd),
+	/*5528*/ uint16(xArgRel32),
+	/*5529*/ uint16(xMatch),
+	/*5530*/ uint16(xSetOp), uint16(JL),
+	/*5532*/ uint16(xReadCd),
+	/*5533*/ uint16(xArgRel32),
+	/*5534*/ uint16(xMatch),
+	/*5535*/ uint16(xCondIs64), 5538, 5552,
+	/*5538*/ uint16(xCondDataSize), 5542, 5547, 0,
+	/*5542*/ uint16(xSetOp), uint16(JGE),
+	/*5544*/ uint16(xReadCw),
+	/*5545*/ uint16(xArgRel16),
+	/*5546*/ uint16(xMatch),
+	/*5547*/ uint16(xSetOp), uint16(JGE),
+	/*5549*/ uint16(xReadCd),
+	/*5550*/ uint16(xArgRel32),
+	/*5551*/ uint16(xMatch),
+	/*5552*/ uint16(xCondDataSize), 5556, 5547, 5561,
+	/*5556*/ uint16(xSetOp), uint16(JGE),
+	/*5558*/ uint16(xReadCd),
+	/*5559*/ uint16(xArgRel32),
+	/*5560*/ uint16(xMatch),
+	/*5561*/ uint16(xSetOp), uint16(JGE),
+	/*5563*/ uint16(xReadCd),
+	/*5564*/ uint16(xArgRel32),
+	/*5565*/ uint16(xMatch),
+	/*5566*/ uint16(xCondIs64), 5569, 5583,
+	/*5569*/ uint16(xCondDataSize), 5573, 5578, 0,
+	/*5573*/ uint16(xSetOp), uint16(JLE),
+	/*5575*/ uint16(xReadCw),
+	/*5576*/ uint16(xArgRel16),
+	/*5577*/ uint16(xMatch),
+	/*5578*/ uint16(xSetOp), uint16(JLE),
+	/*5580*/ uint16(xReadCd),
+	/*5581*/ uint16(xArgRel32),
+	/*5582*/ uint16(xMatch),
+	/*5583*/ uint16(xCondDataSize), 5587, 5578, 5592,
+	/*5587*/ uint16(xSetOp), uint16(JLE),
+	/*5589*/ uint16(xReadCd),
+	/*5590*/ uint16(xArgRel32),
+	/*5591*/ uint16(xMatch),
+	/*5592*/ uint16(xSetOp), uint16(JLE),
+	/*5594*/ uint16(xReadCd),
+	/*5595*/ uint16(xArgRel32),
+	/*5596*/ uint16(xMatch),
+	/*5597*/ uint16(xCondIs64), 5600, 5614,
+	/*5600*/ uint16(xCondDataSize), 5604, 5609, 0,
+	/*5604*/ uint16(xSetOp), uint16(JG),
+	/*5606*/ uint16(xReadCw),
+	/*5607*/ uint16(xArgRel16),
+	/*5608*/ uint16(xMatch),
+	/*5609*/ uint16(xSetOp), uint16(JG),
+	/*5611*/ uint16(xReadCd),
+	/*5612*/ uint16(xArgRel32),
+	/*5613*/ uint16(xMatch),
+	/*5614*/ uint16(xCondDataSize), 5618, 5609, 5623,
+	/*5618*/ uint16(xSetOp), uint16(JG),
+	/*5620*/ uint16(xReadCd),
+	/*5621*/ uint16(xArgRel32),
+	/*5622*/ uint16(xMatch),
+	/*5623*/ uint16(xSetOp), uint16(JG),
+	/*5625*/ uint16(xReadCd),
+	/*5626*/ uint16(xArgRel32),
+	/*5627*/ uint16(xMatch),
+	/*5628*/ uint16(xSetOp), uint16(SETO),
+	/*5630*/ uint16(xReadSlashR),
+	/*5631*/ uint16(xArgRM8),
+	/*5632*/ uint16(xMatch),
+	/*5633*/ uint16(xSetOp), uint16(SETNO),
+	/*5635*/ uint16(xReadSlashR),
+	/*5636*/ uint16(xArgRM8),
+	/*5637*/ uint16(xMatch),
+	/*5638*/ uint16(xSetOp), uint16(SETB),
+	/*5640*/ uint16(xReadSlashR),
+	/*5641*/ uint16(xArgRM8),
+	/*5642*/ uint16(xMatch),
+	/*5643*/ uint16(xSetOp), uint16(SETAE),
+	/*5645*/ uint16(xReadSlashR),
+	/*5646*/ uint16(xArgRM8),
+	/*5647*/ uint16(xMatch),
+	/*5648*/ uint16(xSetOp), uint16(SETE),
+	/*5650*/ uint16(xReadSlashR),
+	/*5651*/ uint16(xArgRM8),
+	/*5652*/ uint16(xMatch),
+	/*5653*/ uint16(xSetOp), uint16(SETNE),
+	/*5655*/ uint16(xReadSlashR),
+	/*5656*/ uint16(xArgRM8),
+	/*5657*/ uint16(xMatch),
+	/*5658*/ uint16(xSetOp), uint16(SETBE),
+	/*5660*/ uint16(xReadSlashR),
+	/*5661*/ uint16(xArgRM8),
+	/*5662*/ uint16(xMatch),
+	/*5663*/ uint16(xSetOp), uint16(SETA),
+	/*5665*/ uint16(xReadSlashR),
+	/*5666*/ uint16(xArgRM8),
+	/*5667*/ uint16(xMatch),
+	/*5668*/ uint16(xSetOp), uint16(SETS),
+	/*5670*/ uint16(xReadSlashR),
+	/*5671*/ uint16(xArgRM8),
+	/*5672*/ uint16(xMatch),
+	/*5673*/ uint16(xSetOp), uint16(SETNS),
+	/*5675*/ uint16(xReadSlashR),
+	/*5676*/ uint16(xArgRM8),
+	/*5677*/ uint16(xMatch),
+	/*5678*/ uint16(xSetOp), uint16(SETP),
+	/*5680*/ uint16(xReadSlashR),
+	/*5681*/ uint16(xArgRM8),
+	/*5682*/ uint16(xMatch),
+	/*5683*/ uint16(xSetOp), uint16(SETNP),
+	/*5685*/ uint16(xReadSlashR),
+	/*5686*/ uint16(xArgRM8),
+	/*5687*/ uint16(xMatch),
+	/*5688*/ uint16(xSetOp), uint16(SETL),
+	/*5690*/ uint16(xReadSlashR),
+	/*5691*/ uint16(xArgRM8),
+	/*5692*/ uint16(xMatch),
+	/*5693*/ uint16(xSetOp), uint16(SETGE),
+	/*5695*/ uint16(xReadSlashR),
+	/*5696*/ uint16(xArgRM8),
+	/*5697*/ uint16(xMatch),
+	/*5698*/ uint16(xSetOp), uint16(SETLE),
+	/*5700*/ uint16(xReadSlashR),
+	/*5701*/ uint16(xArgRM8),
+	/*5702*/ uint16(xMatch),
+	/*5703*/ uint16(xSetOp), uint16(SETG),
+	/*5705*/ uint16(xReadSlashR),
+	/*5706*/ uint16(xArgRM8),
+	/*5707*/ uint16(xMatch),
+	/*5708*/ uint16(xSetOp), uint16(PUSH),
+	/*5710*/ uint16(xArgFS),
+	/*5711*/ uint16(xMatch),
+	/*5712*/ uint16(xCondIs64), 5715, 5727,
+	/*5715*/ uint16(xCondDataSize), 5719, 5723, 0,
+	/*5719*/ uint16(xSetOp), uint16(POP),
+	/*5721*/ uint16(xArgFS),
+	/*5722*/ uint16(xMatch),
+	/*5723*/ uint16(xSetOp), uint16(POP),
+	/*5725*/ uint16(xArgFS),
+	/*5726*/ uint16(xMatch),
+	/*5727*/ uint16(xCondDataSize), 5719, 5731, 5735,
+	/*5731*/ uint16(xSetOp), uint16(POP),
+	/*5733*/ uint16(xArgFS),
+	/*5734*/ uint16(xMatch),
+	/*5735*/ uint16(xSetOp), uint16(POP),
+	/*5737*/ uint16(xArgFS),
+	/*5738*/ uint16(xMatch),
+	/*5739*/ uint16(xSetOp), uint16(CPUID),
+	/*5741*/ uint16(xMatch),
+	/*5742*/ uint16(xCondIs64), 5745, 5761,
+	/*5745*/ uint16(xCondDataSize), 5749, 5755, 0,
+	/*5749*/ uint16(xSetOp), uint16(BT),
+	/*5751*/ uint16(xReadSlashR),
+	/*5752*/ uint16(xArgRM16),
+	/*5753*/ uint16(xArgR16),
+	/*5754*/ uint16(xMatch),
+	/*5755*/ uint16(xSetOp), uint16(BT),
+	/*5757*/ uint16(xReadSlashR),
+	/*5758*/ uint16(xArgRM32),
+	/*5759*/ uint16(xArgR32),
+	/*5760*/ uint16(xMatch),
+	/*5761*/ uint16(xCondDataSize), 5749, 5755, 5765,
+	/*5765*/ uint16(xSetOp), uint16(BT),
+	/*5767*/ uint16(xReadSlashR),
+	/*5768*/ uint16(xArgRM64),
+	/*5769*/ uint16(xArgR64),
+	/*5770*/ uint16(xMatch),
+	/*5771*/ uint16(xCondIs64), 5774, 5794,
+	/*5774*/ uint16(xCondDataSize), 5778, 5786, 0,
+	/*5778*/ uint16(xSetOp), uint16(SHLD),
+	/*5780*/ uint16(xReadSlashR),
+	/*5781*/ uint16(xReadIb),
+	/*5782*/ uint16(xArgRM16),
+	/*5783*/ uint16(xArgR16),
+	/*5784*/ uint16(xArgImm8u),
+	/*5785*/ uint16(xMatch),
+	/*5786*/ uint16(xSetOp), uint16(SHLD),
+	/*5788*/ uint16(xReadSlashR),
+	/*5789*/ uint16(xReadIb),
+	/*5790*/ uint16(xArgRM32),
+	/*5791*/ uint16(xArgR32),
+	/*5792*/ uint16(xArgImm8u),
+	/*5793*/ uint16(xMatch),
+	/*5794*/ uint16(xCondDataSize), 5778, 5786, 5798,
+	/*5798*/ uint16(xSetOp), uint16(SHLD),
+	/*5800*/ uint16(xReadSlashR),
+	/*5801*/ uint16(xReadIb),
+	/*5802*/ uint16(xArgRM64),
+	/*5803*/ uint16(xArgR64),
+	/*5804*/ uint16(xArgImm8u),
+	/*5805*/ uint16(xMatch),
+	/*5806*/ uint16(xCondIs64), 5809, 5827,
+	/*5809*/ uint16(xCondDataSize), 5813, 5820, 0,
+	/*5813*/ uint16(xSetOp), uint16(SHLD),
+	/*5815*/ uint16(xReadSlashR),
+	/*5816*/ uint16(xArgRM16),
+	/*5817*/ uint16(xArgR16),
+	/*5818*/ uint16(xArgCL),
+	/*5819*/ uint16(xMatch),
+	/*5820*/ uint16(xSetOp), uint16(SHLD),
+	/*5822*/ uint16(xReadSlashR),
+	/*5823*/ uint16(xArgRM32),
+	/*5824*/ uint16(xArgR32),
+	/*5825*/ uint16(xArgCL),
+	/*5826*/ uint16(xMatch),
+	/*5827*/ uint16(xCondDataSize), 5813, 5820, 5831,
+	/*5831*/ uint16(xSetOp), uint16(SHLD),
+	/*5833*/ uint16(xReadSlashR),
+	/*5834*/ uint16(xArgRM64),
+	/*5835*/ uint16(xArgR64),
+	/*5836*/ uint16(xArgCL),
+	/*5837*/ uint16(xMatch),
+	/*5838*/ uint16(xSetOp), uint16(PUSH),
+	/*5840*/ uint16(xArgGS),
+	/*5841*/ uint16(xMatch),
+	/*5842*/ uint16(xCondIs64), 5845, 5857,
+	/*5845*/ uint16(xCondDataSize), 5849, 5853, 0,
+	/*5849*/ uint16(xSetOp), uint16(POP),
+	/*5851*/ uint16(xArgGS),
+	/*5852*/ uint16(xMatch),
+	/*5853*/ uint16(xSetOp), uint16(POP),
+	/*5855*/ uint16(xArgGS),
+	/*5856*/ uint16(xMatch),
+	/*5857*/ uint16(xCondDataSize), 5849, 5861, 5865,
+	/*5861*/ uint16(xSetOp), uint16(POP),
+	/*5863*/ uint16(xArgGS),
+	/*5864*/ uint16(xMatch),
+	/*5865*/ uint16(xSetOp), uint16(POP),
+	/*5867*/ uint16(xArgGS),
+	/*5868*/ uint16(xMatch),
+	/*5869*/ uint16(xSetOp), uint16(RSM),
+	/*5871*/ uint16(xMatch),
+	/*5872*/ uint16(xCondIs64), 5875, 5891,
+	/*5875*/ uint16(xCondDataSize), 5879, 5885, 0,
+	/*5879*/ uint16(xSetOp), uint16(BTS),
+	/*5881*/ uint16(xReadSlashR),
+	/*5882*/ uint16(xArgRM16),
+	/*5883*/ uint16(xArgR16),
+	/*5884*/ uint16(xMatch),
+	/*5885*/ uint16(xSetOp), uint16(BTS),
+	/*5887*/ uint16(xReadSlashR),
+	/*5888*/ uint16(xArgRM32),
+	/*5889*/ uint16(xArgR32),
+	/*5890*/ uint16(xMatch),
+	/*5891*/ uint16(xCondDataSize), 5879, 5885, 5895,
+	/*5895*/ uint16(xSetOp), uint16(BTS),
+	/*5897*/ uint16(xReadSlashR),
+	/*5898*/ uint16(xArgRM64),
+	/*5899*/ uint16(xArgR64),
+	/*5900*/ uint16(xMatch),
+	/*5901*/ uint16(xCondIs64), 5904, 5924,
+	/*5904*/ uint16(xCondDataSize), 5908, 5916, 0,
+	/*5908*/ uint16(xSetOp), uint16(SHRD),
+	/*5910*/ uint16(xReadSlashR),
+	/*5911*/ uint16(xReadIb),
+	/*5912*/ uint16(xArgRM16),
+	/*5913*/ uint16(xArgR16),
+	/*5914*/ uint16(xArgImm8u),
+	/*5915*/ uint16(xMatch),
+	/*5916*/ uint16(xSetOp), uint16(SHRD),
+	/*5918*/ uint16(xReadSlashR),
+	/*5919*/ uint16(xReadIb),
+	/*5920*/ uint16(xArgRM32),
+	/*5921*/ uint16(xArgR32),
+	/*5922*/ uint16(xArgImm8u),
+	/*5923*/ uint16(xMatch),
+	/*5924*/ uint16(xCondDataSize), 5908, 5916, 5928,
+	/*5928*/ uint16(xSetOp), uint16(SHRD),
+	/*5930*/ uint16(xReadSlashR),
+	/*5931*/ uint16(xReadIb),
+	/*5932*/ uint16(xArgRM64),
+	/*5933*/ uint16(xArgR64),
+	/*5934*/ uint16(xArgImm8u),
+	/*5935*/ uint16(xMatch),
+	/*5936*/ uint16(xCondIs64), 5939, 5957,
+	/*5939*/ uint16(xCondDataSize), 5943, 5950, 0,
+	/*5943*/ uint16(xSetOp), uint16(SHRD),
+	/*5945*/ uint16(xReadSlashR),
+	/*5946*/ uint16(xArgRM16),
+	/*5947*/ uint16(xArgR16),
+	/*5948*/ uint16(xArgCL),
+	/*5949*/ uint16(xMatch),
+	/*5950*/ uint16(xSetOp), uint16(SHRD),
+	/*5952*/ uint16(xReadSlashR),
+	/*5953*/ uint16(xArgRM32),
+	/*5954*/ uint16(xArgR32),
+	/*5955*/ uint16(xArgCL),
+	/*5956*/ uint16(xMatch),
+	/*5957*/ uint16(xCondDataSize), 5943, 5950, 5961,
+	/*5961*/ uint16(xSetOp), uint16(SHRD),
+	/*5963*/ uint16(xReadSlashR),
+	/*5964*/ uint16(xArgRM64),
+	/*5965*/ uint16(xArgR64),
+	/*5966*/ uint16(xArgCL),
+	/*5967*/ uint16(xMatch),
+	/*5968*/ uint16(xCondByte), 3,
+	0xE8, 6217,
+	0xF0, 6220,
+	0xF8, 6223,
+	/*5976*/ uint16(xCondSlashR),
+	5985, // 0
+	6039, // 1
+	6093, // 2
+	6122, // 3
+	6151, // 4
+	6174, // 5
+	6197, // 6
+	6213, // 7
+	/*5985*/ uint16(xCondIs64), 5988, 6000,
+	/*5988*/ uint16(xCondDataSize), 5992, 5996, 0,
+	/*5992*/ uint16(xSetOp), uint16(FXSAVE),
+	/*5994*/ uint16(xArgM512byte),
+	/*5995*/ uint16(xMatch),
+	/*5996*/ uint16(xSetOp), uint16(FXSAVE),
+	/*5998*/ uint16(xArgM512byte),
+	/*5999*/ uint16(xMatch),
+	/*6000*/ uint16(xCondPrefix), 2,
+	0xF3, 6014,
+	0x0, 6006,
+	/*6006*/ uint16(xCondDataSize), 5992, 5996, 6010,
+	/*6010*/ uint16(xSetOp), uint16(FXSAVE64),
+	/*6012*/ uint16(xArgM512byte),
+	/*6013*/ uint16(xMatch),
+	/*6014*/ uint16(xCondDataSize), 6018, 6025, 6032,
+	/*6018*/ uint16(xCondIsMem), 6021, 0,
+	/*6021*/ uint16(xSetOp), uint16(RDFSBASE),
+	/*6023*/ uint16(xArgRM32),
+	/*6024*/ uint16(xMatch),
+	/*6025*/ uint16(xCondIsMem), 6028, 0,
+	/*6028*/ uint16(xSetOp), uint16(RDFSBASE),
+	/*6030*/ uint16(xArgRM32),
+	/*6031*/ uint16(xMatch),
+	/*6032*/ uint16(xCondIsMem), 6035, 0,
+	/*6035*/ uint16(xSetOp), uint16(RDFSBASE),
+	/*6037*/ uint16(xArgRM64),
+	/*6038*/ uint16(xMatch),
+	/*6039*/ uint16(xCondIs64), 6042, 6054,
+	/*6042*/ uint16(xCondDataSize), 6046, 6050, 0,
+	/*6046*/ uint16(xSetOp), uint16(FXRSTOR),
+	/*6048*/ uint16(xArgM512byte),
+	/*6049*/ uint16(xMatch),
+	/*6050*/ uint16(xSetOp), uint16(FXRSTOR),
+	/*6052*/ uint16(xArgM512byte),
+	/*6053*/ uint16(xMatch),
+	/*6054*/ uint16(xCondPrefix), 2,
+	0xF3, 6068,
+	0x0, 6060,
+	/*6060*/ uint16(xCondDataSize), 6046, 6050, 6064,
+	/*6064*/ uint16(xSetOp), uint16(FXRSTOR64),
+	/*6066*/ uint16(xArgM512byte),
+	/*6067*/ uint16(xMatch),
+	/*6068*/ uint16(xCondDataSize), 6072, 6079, 6086,
+	/*6072*/ uint16(xCondIsMem), 6075, 0,
+	/*6075*/ uint16(xSetOp), uint16(RDGSBASE),
+	/*6077*/ uint16(xArgRM32),
+	/*6078*/ uint16(xMatch),
+	/*6079*/ uint16(xCondIsMem), 6082, 0,
+	/*6082*/ uint16(xSetOp), uint16(RDGSBASE),
+	/*6084*/ uint16(xArgRM32),
+	/*6085*/ uint16(xMatch),
+	/*6086*/ uint16(xCondIsMem), 6089, 0,
+	/*6089*/ uint16(xSetOp), uint16(RDGSBASE),
+	/*6091*/ uint16(xArgRM64),
+	/*6092*/ uint16(xMatch),
+	/*6093*/ uint16(xCondIs64), 6096, 6100,
+	/*6096*/ uint16(xSetOp), uint16(LDMXCSR),
+	/*6098*/ uint16(xArgM32),
+	/*6099*/ uint16(xMatch),
+	/*6100*/ uint16(xCondPrefix), 2,
+	0xF3, 6106,
+	0x0, 6096,
+	/*6106*/ uint16(xCondDataSize), 6110, 6114, 6118,
+	/*6110*/ uint16(xSetOp), uint16(WRFSBASE),
+	/*6112*/ uint16(xArgRM32),
+	/*6113*/ uint16(xMatch),
+	/*6114*/ uint16(xSetOp), uint16(WRFSBASE),
+	/*6116*/ uint16(xArgRM32),
+	/*6117*/ uint16(xMatch),
+	/*6118*/ uint16(xSetOp), uint16(WRFSBASE),
+	/*6120*/ uint16(xArgRM64),
+	/*6121*/ uint16(xMatch),
+	/*6122*/ uint16(xCondIs64), 6125, 6129,
+	/*6125*/ uint16(xSetOp), uint16(STMXCSR),
+	/*6127*/ uint16(xArgM32),
+	/*6128*/ uint16(xMatch),
+	/*6129*/ uint16(xCondPrefix), 2,
+	0xF3, 6135,
+	0x0, 6125,
+	/*6135*/ uint16(xCondDataSize), 6139, 6143, 6147,
+	/*6139*/ uint16(xSetOp), uint16(WRGSBASE),
+	/*6141*/ uint16(xArgRM32),
+	/*6142*/ uint16(xMatch),
+	/*6143*/ uint16(xSetOp), uint16(WRGSBASE),
+	/*6145*/ uint16(xArgRM32),
+	/*6146*/ uint16(xMatch),
+	/*6147*/ uint16(xSetOp), uint16(WRGSBASE),
+	/*6149*/ uint16(xArgRM64),
+	/*6150*/ uint16(xMatch),
+	/*6151*/ uint16(xCondIs64), 6154, 6166,
+	/*6154*/ uint16(xCondDataSize), 6158, 6162, 0,
+	/*6158*/ uint16(xSetOp), uint16(XSAVE),
+	/*6160*/ uint16(xArgMem),
+	/*6161*/ uint16(xMatch),
+	/*6162*/ uint16(xSetOp), uint16(XSAVE),
+	/*6164*/ uint16(xArgMem),
+	/*6165*/ uint16(xMatch),
+	/*6166*/ uint16(xCondDataSize), 6158, 6162, 6170,
+	/*6170*/ uint16(xSetOp), uint16(XSAVE64),
+	/*6172*/ uint16(xArgMem),
+	/*6173*/ uint16(xMatch),
+	/*6174*/ uint16(xCondIs64), 6177, 6189,
+	/*6177*/ uint16(xCondDataSize), 6181, 6185, 0,
+	/*6181*/ uint16(xSetOp), uint16(XRSTOR),
+	/*6183*/ uint16(xArgMem),
+	/*6184*/ uint16(xMatch),
+	/*6185*/ uint16(xSetOp), uint16(XRSTOR),
+	/*6187*/ uint16(xArgMem),
+	/*6188*/ uint16(xMatch),
+	/*6189*/ uint16(xCondDataSize), 6181, 6185, 6193,
+	/*6193*/ uint16(xSetOp), uint16(XRSTOR64),
+	/*6195*/ uint16(xArgMem),
+	/*6196*/ uint16(xMatch),
+	/*6197*/ uint16(xCondDataSize), 6201, 6205, 6209,
+	/*6201*/ uint16(xSetOp), uint16(XSAVEOPT),
+	/*6203*/ uint16(xArgMem),
+	/*6204*/ uint16(xMatch),
+	/*6205*/ uint16(xSetOp), uint16(XSAVEOPT),
+	/*6207*/ uint16(xArgMem),
+	/*6208*/ uint16(xMatch),
+	/*6209*/ uint16(xSetOp), uint16(XSAVEOPT64),
+	/*6211*/ uint16(xArgMem),
+	/*6212*/ uint16(xMatch),
+	/*6213*/ uint16(xSetOp), uint16(CLFLUSH),
+	/*6215*/ uint16(xArgM8),
+	/*6216*/ uint16(xMatch),
+	/*6217*/ uint16(xSetOp), uint16(LFENCE),
+	/*6219*/ uint16(xMatch),
+	/*6220*/ uint16(xSetOp), uint16(MFENCE),
+	/*6222*/ uint16(xMatch),
+	/*6223*/ uint16(xSetOp), uint16(SFENCE),
+	/*6225*/ uint16(xMatch),
+	/*6226*/ uint16(xCondIs64), 6229, 6245,
+	/*6229*/ uint16(xCondDataSize), 6233, 6239, 0,
+	/*6233*/ uint16(xSetOp), uint16(IMUL),
+	/*6235*/ uint16(xReadSlashR),
+	/*6236*/ uint16(xArgR16),
+	/*6237*/ uint16(xArgRM16),
+	/*6238*/ uint16(xMatch),
+	/*6239*/ uint16(xSetOp), uint16(IMUL),
+	/*6241*/ uint16(xReadSlashR),
+	/*6242*/ uint16(xArgR32),
+	/*6243*/ uint16(xArgRM32),
+	/*6244*/ uint16(xMatch),
+	/*6245*/ uint16(xCondDataSize), 6233, 6239, 6249,
+	/*6249*/ uint16(xSetOp), uint16(IMUL),
+	/*6251*/ uint16(xReadSlashR),
+	/*6252*/ uint16(xArgR64),
+	/*6253*/ uint16(xArgRM64),
+	/*6254*/ uint16(xMatch),
+	/*6255*/ uint16(xSetOp), uint16(CMPXCHG),
+	/*6257*/ uint16(xReadSlashR),
+	/*6258*/ uint16(xArgRM8),
+	/*6259*/ uint16(xArgR8),
+	/*6260*/ uint16(xMatch),
+	/*6261*/ uint16(xCondIs64), 6264, 6280,
+	/*6264*/ uint16(xCondDataSize), 6268, 6274, 0,
+	/*6268*/ uint16(xSetOp), uint16(CMPXCHG),
+	/*6270*/ uint16(xReadSlashR),
+	/*6271*/ uint16(xArgRM16),
+	/*6272*/ uint16(xArgR16),
+	/*6273*/ uint16(xMatch),
+	/*6274*/ uint16(xSetOp), uint16(CMPXCHG),
+	/*6276*/ uint16(xReadSlashR),
+	/*6277*/ uint16(xArgRM32),
+	/*6278*/ uint16(xArgR32),
+	/*6279*/ uint16(xMatch),
+	/*6280*/ uint16(xCondDataSize), 6268, 6274, 6284,
+	/*6284*/ uint16(xSetOp), uint16(CMPXCHG),
+	/*6286*/ uint16(xReadSlashR),
+	/*6287*/ uint16(xArgRM64),
+	/*6288*/ uint16(xArgR64),
+	/*6289*/ uint16(xMatch),
+	/*6290*/ uint16(xCondIs64), 6293, 6309,
+	/*6293*/ uint16(xCondDataSize), 6297, 6303, 0,
+	/*6297*/ uint16(xSetOp), uint16(LSS),
+	/*6299*/ uint16(xReadSlashR),
+	/*6300*/ uint16(xArgR16),
+	/*6301*/ uint16(xArgM16colon16),
+	/*6302*/ uint16(xMatch),
+	/*6303*/ uint16(xSetOp), uint16(LSS),
+	/*6305*/ uint16(xReadSlashR),
+	/*6306*/ uint16(xArgR32),
+	/*6307*/ uint16(xArgM16colon32),
+	/*6308*/ uint16(xMatch),
+	/*6309*/ uint16(xCondDataSize), 6297, 6303, 6313,
+	/*6313*/ uint16(xSetOp), uint16(LSS),
+	/*6315*/ uint16(xReadSlashR),
+	/*6316*/ uint16(xArgR64),
+	/*6317*/ uint16(xArgM16colon64),
+	/*6318*/ uint16(xMatch),
+	/*6319*/ uint16(xCondIs64), 6322, 6338,
+	/*6322*/ uint16(xCondDataSize), 6326, 6332, 0,
+	/*6326*/ uint16(xSetOp), uint16(BTR),
+	/*6328*/ uint16(xReadSlashR),
+	/*6329*/ uint16(xArgRM16),
+	/*6330*/ uint16(xArgR16),
+	/*6331*/ uint16(xMatch),
+	/*6332*/ uint16(xSetOp), uint16(BTR),
+	/*6334*/ uint16(xReadSlashR),
+	/*6335*/ uint16(xArgRM32),
+	/*6336*/ uint16(xArgR32),
+	/*6337*/ uint16(xMatch),
+	/*6338*/ uint16(xCondDataSize), 6326, 6332, 6342,
+	/*6342*/ uint16(xSetOp), uint16(BTR),
+	/*6344*/ uint16(xReadSlashR),
+	/*6345*/ uint16(xArgRM64),
+	/*6346*/ uint16(xArgR64),
+	/*6347*/ uint16(xMatch),
+	/*6348*/ uint16(xCondIs64), 6351, 6367,
+	/*6351*/ uint16(xCondDataSize), 6355, 6361, 0,
+	/*6355*/ uint16(xSetOp), uint16(LFS),
+	/*6357*/ uint16(xReadSlashR),
+	/*6358*/ uint16(xArgR16),
+	/*6359*/ uint16(xArgM16colon16),
+	/*6360*/ uint16(xMatch),
+	/*6361*/ uint16(xSetOp), uint16(LFS),
+	/*6363*/ uint16(xReadSlashR),
+	/*6364*/ uint16(xArgR32),
+	/*6365*/ uint16(xArgM16colon32),
+	/*6366*/ uint16(xMatch),
+	/*6367*/ uint16(xCondDataSize), 6355, 6361, 6371,
+	/*6371*/ uint16(xSetOp), uint16(LFS),
+	/*6373*/ uint16(xReadSlashR),
+	/*6374*/ uint16(xArgR64),
+	/*6375*/ uint16(xArgM16colon64),
+	/*6376*/ uint16(xMatch),
+	/*6377*/ uint16(xCondIs64), 6380, 6396,
+	/*6380*/ uint16(xCondDataSize), 6384, 6390, 0,
+	/*6384*/ uint16(xSetOp), uint16(LGS),
+	/*6386*/ uint16(xReadSlashR),
+	/*6387*/ uint16(xArgR16),
+	/*6388*/ uint16(xArgM16colon16),
+	/*6389*/ uint16(xMatch),
+	/*6390*/ uint16(xSetOp), uint16(LGS),
+	/*6392*/ uint16(xReadSlashR),
+	/*6393*/ uint16(xArgR32),
+	/*6394*/ uint16(xArgM16colon32),
+	/*6395*/ uint16(xMatch),
+	/*6396*/ uint16(xCondDataSize), 6384, 6390, 6400,
+	/*6400*/ uint16(xSetOp), uint16(LGS),
+	/*6402*/ uint16(xReadSlashR),
+	/*6403*/ uint16(xArgR64),
+	/*6404*/ uint16(xArgM16colon64),
+	/*6405*/ uint16(xMatch),
+	/*6406*/ uint16(xCondIs64), 6409, 6425,
+	/*6409*/ uint16(xCondDataSize), 6413, 6419, 0,
+	/*6413*/ uint16(xSetOp), uint16(MOVZX),
+	/*6415*/ uint16(xReadSlashR),
+	/*6416*/ uint16(xArgR16),
+	/*6417*/ uint16(xArgRM8),
+	/*6418*/ uint16(xMatch),
+	/*6419*/ uint16(xSetOp), uint16(MOVZX),
+	/*6421*/ uint16(xReadSlashR),
+	/*6422*/ uint16(xArgR32),
+	/*6423*/ uint16(xArgRM8),
+	/*6424*/ uint16(xMatch),
+	/*6425*/ uint16(xCondDataSize), 6413, 6419, 6429,
+	/*6429*/ uint16(xSetOp), uint16(MOVZX),
+	/*6431*/ uint16(xReadSlashR),
+	/*6432*/ uint16(xArgR64),
+	/*6433*/ uint16(xArgRM8),
+	/*6434*/ uint16(xMatch),
+	/*6435*/ uint16(xCondIs64), 6438, 6454,
+	/*6438*/ uint16(xCondDataSize), 6442, 6448, 0,
+	/*6442*/ uint16(xSetOp), uint16(MOVZX),
+	/*6444*/ uint16(xReadSlashR),
+	/*6445*/ uint16(xArgR16),
+	/*6446*/ uint16(xArgRM16),
+	/*6447*/ uint16(xMatch),
+	/*6448*/ uint16(xSetOp), uint16(MOVZX),
+	/*6450*/ uint16(xReadSlashR),
+	/*6451*/ uint16(xArgR32),
+	/*6452*/ uint16(xArgRM16),
+	/*6453*/ uint16(xMatch),
+	/*6454*/ uint16(xCondDataSize), 6442, 6448, 6458,
+	/*6458*/ uint16(xSetOp), uint16(MOVZX),
+	/*6460*/ uint16(xReadSlashR),
+	/*6461*/ uint16(xArgR64),
+	/*6462*/ uint16(xArgRM16),
+	/*6463*/ uint16(xMatch),
+	/*6464*/ uint16(xCondIs64), 6467, 6487,
+	/*6467*/ uint16(xCondPrefix), 1,
+	0xF3, 6471,
+	/*6471*/ uint16(xCondDataSize), 6475, 6481, 0,
+	/*6475*/ uint16(xSetOp), uint16(POPCNT),
+	/*6477*/ uint16(xReadSlashR),
+	/*6478*/ uint16(xArgR16),
+	/*6479*/ uint16(xArgRM16),
+	/*6480*/ uint16(xMatch),
+	/*6481*/ uint16(xSetOp), uint16(POPCNT),
+	/*6483*/ uint16(xReadSlashR),
+	/*6484*/ uint16(xArgR32),
+	/*6485*/ uint16(xArgRM32),
+	/*6486*/ uint16(xMatch),
+	/*6487*/ uint16(xCondPrefix), 1,
+	0xF3, 6491,
+	/*6491*/ uint16(xCondDataSize), 6475, 6481, 6495,
+	/*6495*/ uint16(xSetOp), uint16(POPCNT),
+	/*6497*/ uint16(xReadSlashR),
+	/*6498*/ uint16(xArgR64),
+	/*6499*/ uint16(xArgRM64),
+	/*6500*/ uint16(xMatch),
+	/*6501*/ uint16(xCondDataSize), 0, 6505, 0,
+	/*6505*/ uint16(xSetOp), uint16(UD1),
+	/*6507*/ uint16(xReadSlashR),
+	/*6508*/ uint16(xArgR32),
+	/*6509*/ uint16(xArgRM32),
+	/*6510*/ uint16(xMatch),
+	/*6511*/ uint16(xCondSlashR),
 	0,    // 0
 	0,    // 1
 	0,    // 2
 	0,    // 3
-	6511, // 4
-	6540, // 5
-	6569, // 6
-	6598, // 7
-	/*6511*/ uint16(xCondIs64), 6514, 6530,
-	/*6514*/ uint16(xCondDataSize), 6518, 6524, 0,
-	/*6518*/ uint16(xSetOp), uint16(BT),
-	/*6520*/ uint16(xReadIb),
-	/*6521*/ uint16(xArgRM16),
-	/*6522*/ uint16(xArgImm8u),
-	/*6523*/ uint16(xMatch),
-	/*6524*/ uint16(xSetOp), uint16(BT),
-	/*6526*/ uint16(xReadIb),
-	/*6527*/ uint16(xArgRM32),
-	/*6528*/ uint16(xArgImm8u),
-	/*6529*/ uint16(xMatch),
-	/*6530*/ uint16(xCondDataSize), 6518, 6524, 6534,
-	/*6534*/ uint16(xSetOp), uint16(BT),
-	/*6536*/ uint16(xReadIb),
-	/*6537*/ uint16(xArgRM64),
-	/*6538*/ uint16(xArgImm8u),
-	/*6539*/ uint16(xMatch),
-	/*6540*/ uint16(xCondIs64), 6543, 6559,
-	/*6543*/ uint16(xCondDataSize), 6547, 6553, 0,
-	/*6547*/ uint16(xSetOp), uint16(BTS),
-	/*6549*/ uint16(xReadIb),
-	/*6550*/ uint16(xArgRM16),
-	/*6551*/ uint16(xArgImm8u),
-	/*6552*/ uint16(xMatch),
-	/*6553*/ uint16(xSetOp), uint16(BTS),
-	/*6555*/ uint16(xReadIb),
-	/*6556*/ uint16(xArgRM32),
-	/*6557*/ uint16(xArgImm8u),
-	/*6558*/ uint16(xMatch),
-	/*6559*/ uint16(xCondDataSize), 6547, 6553, 6563,
-	/*6563*/ uint16(xSetOp), uint16(BTS),
-	/*6565*/ uint16(xReadIb),
-	/*6566*/ uint16(xArgRM64),
-	/*6567*/ uint16(xArgImm8u),
-	/*6568*/ uint16(xMatch),
-	/*6569*/ uint16(xCondIs64), 6572, 6588,
-	/*6572*/ uint16(xCondDataSize), 6576, 6582, 0,
-	/*6576*/ uint16(xSetOp), uint16(BTR),
-	/*6578*/ uint16(xReadIb),
-	/*6579*/ uint16(xArgRM16),
-	/*6580*/ uint16(xArgImm8u),
-	/*6581*/ uint16(xMatch),
-	/*6582*/ uint16(xSetOp), uint16(BTR),
-	/*6584*/ uint16(xReadIb),
-	/*6585*/ uint16(xArgRM32),
-	/*6586*/ uint16(xArgImm8u),
-	/*6587*/ uint16(xMatch),
-	/*6588*/ uint16(xCondDataSize), 6576, 6582, 6592,
-	/*6592*/ uint16(xSetOp), uint16(BTR),
-	/*6594*/ uint16(xReadIb),
-	/*6595*/ uint16(xArgRM64),
-	/*6596*/ uint16(xArgImm8u),
-	/*6597*/ uint16(xMatch),
-	/*6598*/ uint16(xCondIs64), 6601, 6617,
-	/*6601*/ uint16(xCondDataSize), 6605, 6611, 0,
-	/*6605*/ uint16(xSetOp), uint16(BTC),
-	/*6607*/ uint16(xReadIb),
-	/*6608*/ uint16(xArgRM16),
-	/*6609*/ uint16(xArgImm8u),
-	/*6610*/ uint16(xMatch),
-	/*6611*/ uint16(xSetOp), uint16(BTC),
-	/*6613*/ uint16(xReadIb),
-	/*6614*/ uint16(xArgRM32),
-	/*6615*/ uint16(xArgImm8u),
-	/*6616*/ uint16(xMatch),
-	/*6617*/ uint16(xCondDataSize), 6605, 6611, 6621,
-	/*6621*/ uint16(xSetOp), uint16(BTC),
-	/*6623*/ uint16(xReadIb),
-	/*6624*/ uint16(xArgRM64),
-	/*6625*/ uint16(xArgImm8u),
-	/*6626*/ uint16(xMatch),
-	/*6627*/ uint16(xCondIs64), 6630, 6646,
-	/*6630*/ uint16(xCondDataSize), 6634, 6640, 0,
-	/*6634*/ uint16(xSetOp), uint16(BTC),
-	/*6636*/ uint16(xReadSlashR),
-	/*6637*/ uint16(xArgRM16),
-	/*6638*/ uint16(xArgR16),
-	/*6639*/ uint16(xMatch),
-	/*6640*/ uint16(xSetOp), uint16(BTC),
-	/*6642*/ uint16(xReadSlashR),
-	/*6643*/ uint16(xArgRM32),
-	/*6644*/ uint16(xArgR32),
-	/*6645*/ uint16(xMatch),
-	/*6646*/ uint16(xCondDataSize), 6634, 6640, 6650,
-	/*6650*/ uint16(xSetOp), uint16(BTC),
-	/*6652*/ uint16(xReadSlashR),
-	/*6653*/ uint16(xArgRM64),
-	/*6654*/ uint16(xArgR64),
-	/*6655*/ uint16(xMatch),
-	/*6656*/ uint16(xCondIs64), 6659, 6697,
-	/*6659*/ uint16(xCondPrefix), 2,
-	0xF3, 6681,
-	0x0, 6665,
-	/*6665*/ uint16(xCondDataSize), 6669, 6675, 0,
-	/*6669*/ uint16(xSetOp), uint16(BSF),
-	/*6671*/ uint16(xReadSlashR),
-	/*6672*/ uint16(xArgR16),
-	/*6673*/ uint16(xArgRM16),
-	/*6674*/ uint16(xMatch),
-	/*6675*/ uint16(xSetOp), uint16(BSF),
-	/*6677*/ uint16(xReadSlashR),
-	/*6678*/ uint16(xArgR32),
-	/*6679*/ uint16(xArgRM32),
-	/*6680*/ uint16(xMatch),
-	/*6681*/ uint16(xCondDataSize), 6685, 6691, 0,
-	/*6685*/ uint16(xSetOp), uint16(TZCNT),
-	/*6687*/ uint16(xReadSlashR),
-	/*6688*/ uint16(xArgR16),
-	/*6689*/ uint16(xArgRM16),
-	/*6690*/ uint16(xMatch),
-	/*6691*/ uint16(xSetOp), uint16(TZCNT),
-	/*6693*/ uint16(xReadSlashR),
-	/*6694*/ uint16(xArgR32),
-	/*6695*/ uint16(xArgRM32),
-	/*6696*/ uint16(xMatch),
-	/*6697*/ uint16(xCondPrefix), 2,
-	0xF3, 6713,
-	0x0, 6703,
-	/*6703*/ uint16(xCondDataSize), 6669, 6675, 6707,
-	/*6707*/ uint16(xSetOp), uint16(BSF),
-	/*6709*/ uint16(xReadSlashR),
-	/*6710*/ uint16(xArgR64),
-	/*6711*/ uint16(xArgRM64),
-	/*6712*/ uint16(xMatch),
-	/*6713*/ uint16(xCondDataSize), 6685, 6691, 6717,
-	/*6717*/ uint16(xSetOp), uint16(TZCNT),
-	/*6719*/ uint16(xReadSlashR),
-	/*6720*/ uint16(xArgR64),
-	/*6721*/ uint16(xArgRM64),
-	/*6722*/ uint16(xMatch),
-	/*6723*/ uint16(xCondIs64), 6726, 6764,
-	/*6726*/ uint16(xCondPrefix), 2,
-	0xF3, 6748,
-	0x0, 6732,
-	/*6732*/ uint16(xCondDataSize), 6736, 6742, 0,
-	/*6736*/ uint16(xSetOp), uint16(BSR),
-	/*6738*/ uint16(xReadSlashR),
-	/*6739*/ uint16(xArgR16),
-	/*6740*/ uint16(xArgRM16),
-	/*6741*/ uint16(xMatch),
-	/*6742*/ uint16(xSetOp), uint16(BSR),
-	/*6744*/ uint16(xReadSlashR),
-	/*6745*/ uint16(xArgR32),
-	/*6746*/ uint16(xArgRM32),
-	/*6747*/ uint16(xMatch),
-	/*6748*/ uint16(xCondDataSize), 6752, 6758, 0,
-	/*6752*/ uint16(xSetOp), uint16(LZCNT),
-	/*6754*/ uint16(xReadSlashR),
-	/*6755*/ uint16(xArgR16),
-	/*6756*/ uint16(xArgRM16),
-	/*6757*/ uint16(xMatch),
-	/*6758*/ uint16(xSetOp), uint16(LZCNT),
-	/*6760*/ uint16(xReadSlashR),
-	/*6761*/ uint16(xArgR32),
-	/*6762*/ uint16(xArgRM32),
-	/*6763*/ uint16(xMatch),
-	/*6764*/ uint16(xCondPrefix), 2,
-	0xF3, 6780,
-	0x0, 6770,
-	/*6770*/ uint16(xCondDataSize), 6736, 6742, 6774,
-	/*6774*/ uint16(xSetOp), uint16(BSR),
-	/*6776*/ uint16(xReadSlashR),
-	/*6777*/ uint16(xArgR64),
-	/*6778*/ uint16(xArgRM64),
-	/*6779*/ uint16(xMatch),
-	/*6780*/ uint16(xCondDataSize), 6752, 6758, 6784,
-	/*6784*/ uint16(xSetOp), uint16(LZCNT),
-	/*6786*/ uint16(xReadSlashR),
-	/*6787*/ uint16(xArgR64),
-	/*6788*/ uint16(xArgRM64),
-	/*6789*/ uint16(xMatch),
-	/*6790*/ uint16(xCondIs64), 6793, 6809,
-	/*6793*/ uint16(xCondDataSize), 6797, 6803, 0,
-	/*6797*/ uint16(xSetOp), uint16(MOVSX),
-	/*6799*/ uint16(xReadSlashR),
-	/*6800*/ uint16(xArgR16),
-	/*6801*/ uint16(xArgRM8),
-	/*6802*/ uint16(xMatch),
-	/*6803*/ uint16(xSetOp), uint16(MOVSX),
-	/*6805*/ uint16(xReadSlashR),
-	/*6806*/ uint16(xArgR32),
-	/*6807*/ uint16(xArgRM8),
-	/*6808*/ uint16(xMatch),
-	/*6809*/ uint16(xCondDataSize), 6797, 6803, 6813,
-	/*6813*/ uint16(xSetOp), uint16(MOVSX),
-	/*6815*/ uint16(xReadSlashR),
-	/*6816*/ uint16(xArgR64),
-	/*6817*/ uint16(xArgRM8),
-	/*6818*/ uint16(xMatch),
-	/*6819*/ uint16(xCondIs64), 6822, 6838,
-	/*6822*/ uint16(xCondDataSize), 6826, 6832, 0,
-	/*6826*/ uint16(xSetOp), uint16(MOVSX),
-	/*6828*/ uint16(xReadSlashR),
-	/*6829*/ uint16(xArgR16),
-	/*6830*/ uint16(xArgRM16),
-	/*6831*/ uint16(xMatch),
-	/*6832*/ uint16(xSetOp), uint16(MOVSX),
-	/*6834*/ uint16(xReadSlashR),
-	/*6835*/ uint16(xArgR32),
-	/*6836*/ uint16(xArgRM16),
-	/*6837*/ uint16(xMatch),
-	/*6838*/ uint16(xCondDataSize), 6826, 6832, 6842,
-	/*6842*/ uint16(xSetOp), uint16(MOVSX),
-	/*6844*/ uint16(xReadSlashR),
-	/*6845*/ uint16(xArgR64),
-	/*6846*/ uint16(xArgRM16),
-	/*6847*/ uint16(xMatch),
-	/*6848*/ uint16(xSetOp), uint16(XADD),
-	/*6850*/ uint16(xReadSlashR),
-	/*6851*/ uint16(xArgRM8),
-	/*6852*/ uint16(xArgR8),
-	/*6853*/ uint16(xMatch),
-	/*6854*/ uint16(xCondIs64), 6857, 6873,
-	/*6857*/ uint16(xCondDataSize), 6861, 6867, 0,
-	/*6861*/ uint16(xSetOp), uint16(XADD),
-	/*6863*/ uint16(xReadSlashR),
-	/*6864*/ uint16(xArgRM16),
-	/*6865*/ uint16(xArgR16),
-	/*6866*/ uint16(xMatch),
-	/*6867*/ uint16(xSetOp), uint16(XADD),
-	/*6869*/ uint16(xReadSlashR),
-	/*6870*/ uint16(xArgRM32),
-	/*6871*/ uint16(xArgR32),
-	/*6872*/ uint16(xMatch),
-	/*6873*/ uint16(xCondDataSize), 6861, 6867, 6877,
-	/*6877*/ uint16(xSetOp), uint16(XADD),
-	/*6879*/ uint16(xReadSlashR),
-	/*6880*/ uint16(xArgRM64),
-	/*6881*/ uint16(xArgR64),
-	/*6882*/ uint16(xMatch),
-	/*6883*/ uint16(xCondPrefix), 4,
-	0xF3, 6917,
-	0xF2, 6909,
-	0x66, 6901,
-	0x0, 6893,
-	/*6893*/ uint16(xSetOp), uint16(CMPPS),
-	/*6895*/ uint16(xReadSlashR),
-	/*6896*/ uint16(xReadIb),
-	/*6897*/ uint16(xArgXmm1),
-	/*6898*/ uint16(xArgXmm2M128),
-	/*6899*/ uint16(xArgImm8u),
-	/*6900*/ uint16(xMatch),
-	/*6901*/ uint16(xSetOp), uint16(CMPPD),
-	/*6903*/ uint16(xReadSlashR),
-	/*6904*/ uint16(xReadIb),
-	/*6905*/ uint16(xArgXmm1),
-	/*6906*/ uint16(xArgXmm2M128),
-	/*6907*/ uint16(xArgImm8u),
-	/*6908*/ uint16(xMatch),
-	/*6909*/ uint16(xSetOp), uint16(CMPSD_XMM),
-	/*6911*/ uint16(xReadSlashR),
-	/*6912*/ uint16(xReadIb),
-	/*6913*/ uint16(xArgXmm1),
-	/*6914*/ uint16(xArgXmm2M64),
-	/*6915*/ uint16(xArgImm8u),
-	/*6916*/ uint16(xMatch),
-	/*6917*/ uint16(xSetOp), uint16(CMPSS),
-	/*6919*/ uint16(xReadSlashR),
-	/*6920*/ uint16(xReadIb),
-	/*6921*/ uint16(xArgXmm1),
-	/*6922*/ uint16(xArgXmm2M32),
-	/*6923*/ uint16(xArgImm8u),
-	/*6924*/ uint16(xMatch),
-	/*6925*/ uint16(xCondIs64), 6928, 6944,
-	/*6928*/ uint16(xCondDataSize), 6932, 6938, 0,
-	/*6932*/ uint16(xSetOp), uint16(MOVNTI),
-	/*6934*/ uint16(xReadSlashR),
-	/*6935*/ uint16(xArgM32),
-	/*6936*/ uint16(xArgR32),
-	/*6937*/ uint16(xMatch),
-	/*6938*/ uint16(xSetOp), uint16(MOVNTI),
-	/*6940*/ uint16(xReadSlashR),
-	/*6941*/ uint16(xArgM32),
-	/*6942*/ uint16(xArgR32),
-	/*6943*/ uint16(xMatch),
-	/*6944*/ uint16(xCondDataSize), 6932, 6938, 6948,
-	/*6948*/ uint16(xSetOp), uint16(MOVNTI),
-	/*6950*/ uint16(xReadSlashR),
-	/*6951*/ uint16(xArgM64),
-	/*6952*/ uint16(xArgR64),
-	/*6953*/ uint16(xMatch),
-	/*6954*/ uint16(xCondPrefix), 2,
-	0x66, 6968,
-	0x0, 6960,
-	/*6960*/ uint16(xSetOp), uint16(PINSRW),
-	/*6962*/ uint16(xReadSlashR),
-	/*6963*/ uint16(xReadIb),
-	/*6964*/ uint16(xArgMm),
-	/*6965*/ uint16(xArgR32M16),
-	/*6966*/ uint16(xArgImm8u),
-	/*6967*/ uint16(xMatch),
-	/*6968*/ uint16(xSetOp), uint16(PINSRW),
-	/*6970*/ uint16(xReadSlashR),
-	/*6971*/ uint16(xReadIb),
-	/*6972*/ uint16(xArgXmm),
-	/*6973*/ uint16(xArgR32M16),
-	/*6974*/ uint16(xArgImm8u),
-	/*6975*/ uint16(xMatch),
-	/*6976*/ uint16(xCondPrefix), 2,
-	0x66, 6990,
-	0x0, 6982,
-	/*6982*/ uint16(xSetOp), uint16(PEXTRW),
-	/*6984*/ uint16(xReadSlashR),
-	/*6985*/ uint16(xReadIb),
-	/*6986*/ uint16(xArgR32),
-	/*6987*/ uint16(xArgMm2),
-	/*6988*/ uint16(xArgImm8u),
-	/*6989*/ uint16(xMatch),
-	/*6990*/ uint16(xSetOp), uint16(PEXTRW),
-	/*6992*/ uint16(xReadSlashR),
-	/*6993*/ uint16(xReadIb),
-	/*6994*/ uint16(xArgR32),
-	/*6995*/ uint16(xArgXmm2),
-	/*6996*/ uint16(xArgImm8u),
-	/*6997*/ uint16(xMatch),
-	/*6998*/ uint16(xCondPrefix), 2,
-	0x66, 7012,
-	0x0, 7004,
-	/*7004*/ uint16(xSetOp), uint16(SHUFPS),
-	/*7006*/ uint16(xReadSlashR),
-	/*7007*/ uint16(xReadIb),
-	/*7008*/ uint16(xArgXmm1),
-	/*7009*/ uint16(xArgXmm2M128),
-	/*7010*/ uint16(xArgImm8u),
-	/*7011*/ uint16(xMatch),
-	/*7012*/ uint16(xSetOp), uint16(SHUFPD),
-	/*7014*/ uint16(xReadSlashR),
-	/*7015*/ uint16(xReadIb),
-	/*7016*/ uint16(xArgXmm1),
-	/*7017*/ uint16(xArgXmm2M128),
-	/*7018*/ uint16(xArgImm8u),
-	/*7019*/ uint16(xMatch),
-	/*7020*/ uint16(xCondSlashR),
+	6520, // 4
+	6549, // 5
+	6578, // 6
+	6607, // 7
+	/*6520*/ uint16(xCondIs64), 6523, 6539,
+	/*6523*/ uint16(xCondDataSize), 6527, 6533, 0,
+	/*6527*/ uint16(xSetOp), uint16(BT),
+	/*6529*/ uint16(xReadIb),
+	/*6530*/ uint16(xArgRM16),
+	/*6531*/ uint16(xArgImm8u),
+	/*6532*/ uint16(xMatch),
+	/*6533*/ uint16(xSetOp), uint16(BT),
+	/*6535*/ uint16(xReadIb),
+	/*6536*/ uint16(xArgRM32),
+	/*6537*/ uint16(xArgImm8u),
+	/*6538*/ uint16(xMatch),
+	/*6539*/ uint16(xCondDataSize), 6527, 6533, 6543,
+	/*6543*/ uint16(xSetOp), uint16(BT),
+	/*6545*/ uint16(xReadIb),
+	/*6546*/ uint16(xArgRM64),
+	/*6547*/ uint16(xArgImm8u),
+	/*6548*/ uint16(xMatch),
+	/*6549*/ uint16(xCondIs64), 6552, 6568,
+	/*6552*/ uint16(xCondDataSize), 6556, 6562, 0,
+	/*6556*/ uint16(xSetOp), uint16(BTS),
+	/*6558*/ uint16(xReadIb),
+	/*6559*/ uint16(xArgRM16),
+	/*6560*/ uint16(xArgImm8u),
+	/*6561*/ uint16(xMatch),
+	/*6562*/ uint16(xSetOp), uint16(BTS),
+	/*6564*/ uint16(xReadIb),
+	/*6565*/ uint16(xArgRM32),
+	/*6566*/ uint16(xArgImm8u),
+	/*6567*/ uint16(xMatch),
+	/*6568*/ uint16(xCondDataSize), 6556, 6562, 6572,
+	/*6572*/ uint16(xSetOp), uint16(BTS),
+	/*6574*/ uint16(xReadIb),
+	/*6575*/ uint16(xArgRM64),
+	/*6576*/ uint16(xArgImm8u),
+	/*6577*/ uint16(xMatch),
+	/*6578*/ uint16(xCondIs64), 6581, 6597,
+	/*6581*/ uint16(xCondDataSize), 6585, 6591, 0,
+	/*6585*/ uint16(xSetOp), uint16(BTR),
+	/*6587*/ uint16(xReadIb),
+	/*6588*/ uint16(xArgRM16),
+	/*6589*/ uint16(xArgImm8u),
+	/*6590*/ uint16(xMatch),
+	/*6591*/ uint16(xSetOp), uint16(BTR),
+	/*6593*/ uint16(xReadIb),
+	/*6594*/ uint16(xArgRM32),
+	/*6595*/ uint16(xArgImm8u),
+	/*6596*/ uint16(xMatch),
+	/*6597*/ uint16(xCondDataSize), 6585, 6591, 6601,
+	/*6601*/ uint16(xSetOp), uint16(BTR),
+	/*6603*/ uint16(xReadIb),
+	/*6604*/ uint16(xArgRM64),
+	/*6605*/ uint16(xArgImm8u),
+	/*6606*/ uint16(xMatch),
+	/*6607*/ uint16(xCondIs64), 6610, 6626,
+	/*6610*/ uint16(xCondDataSize), 6614, 6620, 0,
+	/*6614*/ uint16(xSetOp), uint16(BTC),
+	/*6616*/ uint16(xReadIb),
+	/*6617*/ uint16(xArgRM16),
+	/*6618*/ uint16(xArgImm8u),
+	/*6619*/ uint16(xMatch),
+	/*6620*/ uint16(xSetOp), uint16(BTC),
+	/*6622*/ uint16(xReadIb),
+	/*6623*/ uint16(xArgRM32),
+	/*6624*/ uint16(xArgImm8u),
+	/*6625*/ uint16(xMatch),
+	/*6626*/ uint16(xCondDataSize), 6614, 6620, 6630,
+	/*6630*/ uint16(xSetOp), uint16(BTC),
+	/*6632*/ uint16(xReadIb),
+	/*6633*/ uint16(xArgRM64),
+	/*6634*/ uint16(xArgImm8u),
+	/*6635*/ uint16(xMatch),
+	/*6636*/ uint16(xCondIs64), 6639, 6655,
+	/*6639*/ uint16(xCondDataSize), 6643, 6649, 0,
+	/*6643*/ uint16(xSetOp), uint16(BTC),
+	/*6645*/ uint16(xReadSlashR),
+	/*6646*/ uint16(xArgRM16),
+	/*6647*/ uint16(xArgR16),
+	/*6648*/ uint16(xMatch),
+	/*6649*/ uint16(xSetOp), uint16(BTC),
+	/*6651*/ uint16(xReadSlashR),
+	/*6652*/ uint16(xArgRM32),
+	/*6653*/ uint16(xArgR32),
+	/*6654*/ uint16(xMatch),
+	/*6655*/ uint16(xCondDataSize), 6643, 6649, 6659,
+	/*6659*/ uint16(xSetOp), uint16(BTC),
+	/*6661*/ uint16(xReadSlashR),
+	/*6662*/ uint16(xArgRM64),
+	/*6663*/ uint16(xArgR64),
+	/*6664*/ uint16(xMatch),
+	/*6665*/ uint16(xCondIs64), 6668, 6706,
+	/*6668*/ uint16(xCondPrefix), 2,
+	0xF3, 6690,
+	0x0, 6674,
+	/*6674*/ uint16(xCondDataSize), 6678, 6684, 0,
+	/*6678*/ uint16(xSetOp), uint16(BSF),
+	/*6680*/ uint16(xReadSlashR),
+	/*6681*/ uint16(xArgR16),
+	/*6682*/ uint16(xArgRM16),
+	/*6683*/ uint16(xMatch),
+	/*6684*/ uint16(xSetOp), uint16(BSF),
+	/*6686*/ uint16(xReadSlashR),
+	/*6687*/ uint16(xArgR32),
+	/*6688*/ uint16(xArgRM32),
+	/*6689*/ uint16(xMatch),
+	/*6690*/ uint16(xCondDataSize), 6694, 6700, 0,
+	/*6694*/ uint16(xSetOp), uint16(TZCNT),
+	/*6696*/ uint16(xReadSlashR),
+	/*6697*/ uint16(xArgR16),
+	/*6698*/ uint16(xArgRM16),
+	/*6699*/ uint16(xMatch),
+	/*6700*/ uint16(xSetOp), uint16(TZCNT),
+	/*6702*/ uint16(xReadSlashR),
+	/*6703*/ uint16(xArgR32),
+	/*6704*/ uint16(xArgRM32),
+	/*6705*/ uint16(xMatch),
+	/*6706*/ uint16(xCondPrefix), 2,
+	0xF3, 6722,
+	0x0, 6712,
+	/*6712*/ uint16(xCondDataSize), 6678, 6684, 6716,
+	/*6716*/ uint16(xSetOp), uint16(BSF),
+	/*6718*/ uint16(xReadSlashR),
+	/*6719*/ uint16(xArgR64),
+	/*6720*/ uint16(xArgRM64),
+	/*6721*/ uint16(xMatch),
+	/*6722*/ uint16(xCondDataSize), 6694, 6700, 6726,
+	/*6726*/ uint16(xSetOp), uint16(TZCNT),
+	/*6728*/ uint16(xReadSlashR),
+	/*6729*/ uint16(xArgR64),
+	/*6730*/ uint16(xArgRM64),
+	/*6731*/ uint16(xMatch),
+	/*6732*/ uint16(xCondIs64), 6735, 6773,
+	/*6735*/ uint16(xCondPrefix), 2,
+	0xF3, 6757,
+	0x0, 6741,
+	/*6741*/ uint16(xCondDataSize), 6745, 6751, 0,
+	/*6745*/ uint16(xSetOp), uint16(BSR),
+	/*6747*/ uint16(xReadSlashR),
+	/*6748*/ uint16(xArgR16),
+	/*6749*/ uint16(xArgRM16),
+	/*6750*/ uint16(xMatch),
+	/*6751*/ uint16(xSetOp), uint16(BSR),
+	/*6753*/ uint16(xReadSlashR),
+	/*6754*/ uint16(xArgR32),
+	/*6755*/ uint16(xArgRM32),
+	/*6756*/ uint16(xMatch),
+	/*6757*/ uint16(xCondDataSize), 6761, 6767, 0,
+	/*6761*/ uint16(xSetOp), uint16(LZCNT),
+	/*6763*/ uint16(xReadSlashR),
+	/*6764*/ uint16(xArgR16),
+	/*6765*/ uint16(xArgRM16),
+	/*6766*/ uint16(xMatch),
+	/*6767*/ uint16(xSetOp), uint16(LZCNT),
+	/*6769*/ uint16(xReadSlashR),
+	/*6770*/ uint16(xArgR32),
+	/*6771*/ uint16(xArgRM32),
+	/*6772*/ uint16(xMatch),
+	/*6773*/ uint16(xCondPrefix), 2,
+	0xF3, 6789,
+	0x0, 6779,
+	/*6779*/ uint16(xCondDataSize), 6745, 6751, 6783,
+	/*6783*/ uint16(xSetOp), uint16(BSR),
+	/*6785*/ uint16(xReadSlashR),
+	/*6786*/ uint16(xArgR64),
+	/*6787*/ uint16(xArgRM64),
+	/*6788*/ uint16(xMatch),
+	/*6789*/ uint16(xCondDataSize), 6761, 6767, 6793,
+	/*6793*/ uint16(xSetOp), uint16(LZCNT),
+	/*6795*/ uint16(xReadSlashR),
+	/*6796*/ uint16(xArgR64),
+	/*6797*/ uint16(xArgRM64),
+	/*6798*/ uint16(xMatch),
+	/*6799*/ uint16(xCondIs64), 6802, 6818,
+	/*6802*/ uint16(xCondDataSize), 6806, 6812, 0,
+	/*6806*/ uint16(xSetOp), uint16(MOVSX),
+	/*6808*/ uint16(xReadSlashR),
+	/*6809*/ uint16(xArgR16),
+	/*6810*/ uint16(xArgRM8),
+	/*6811*/ uint16(xMatch),
+	/*6812*/ uint16(xSetOp), uint16(MOVSX),
+	/*6814*/ uint16(xReadSlashR),
+	/*6815*/ uint16(xArgR32),
+	/*6816*/ uint16(xArgRM8),
+	/*6817*/ uint16(xMatch),
+	/*6818*/ uint16(xCondDataSize), 6806, 6812, 6822,
+	/*6822*/ uint16(xSetOp), uint16(MOVSX),
+	/*6824*/ uint16(xReadSlashR),
+	/*6825*/ uint16(xArgR64),
+	/*6826*/ uint16(xArgRM8),
+	/*6827*/ uint16(xMatch),
+	/*6828*/ uint16(xCondIs64), 6831, 6847,
+	/*6831*/ uint16(xCondDataSize), 6835, 6841, 0,
+	/*6835*/ uint16(xSetOp), uint16(MOVSX),
+	/*6837*/ uint16(xReadSlashR),
+	/*6838*/ uint16(xArgR16),
+	/*6839*/ uint16(xArgRM16),
+	/*6840*/ uint16(xMatch),
+	/*6841*/ uint16(xSetOp), uint16(MOVSX),
+	/*6843*/ uint16(xReadSlashR),
+	/*6844*/ uint16(xArgR32),
+	/*6845*/ uint16(xArgRM16),
+	/*6846*/ uint16(xMatch),
+	/*6847*/ uint16(xCondDataSize), 6835, 6841, 6851,
+	/*6851*/ uint16(xSetOp), uint16(MOVSX),
+	/*6853*/ uint16(xReadSlashR),
+	/*6854*/ uint16(xArgR64),
+	/*6855*/ uint16(xArgRM16),
+	/*6856*/ uint16(xMatch),
+	/*6857*/ uint16(xSetOp), uint16(XADD),
+	/*6859*/ uint16(xReadSlashR),
+	/*6860*/ uint16(xArgRM8),
+	/*6861*/ uint16(xArgR8),
+	/*6862*/ uint16(xMatch),
+	/*6863*/ uint16(xCondIs64), 6866, 6882,
+	/*6866*/ uint16(xCondDataSize), 6870, 6876, 0,
+	/*6870*/ uint16(xSetOp), uint16(XADD),
+	/*6872*/ uint16(xReadSlashR),
+	/*6873*/ uint16(xArgRM16),
+	/*6874*/ uint16(xArgR16),
+	/*6875*/ uint16(xMatch),
+	/*6876*/ uint16(xSetOp), uint16(XADD),
+	/*6878*/ uint16(xReadSlashR),
+	/*6879*/ uint16(xArgRM32),
+	/*6880*/ uint16(xArgR32),
+	/*6881*/ uint16(xMatch),
+	/*6882*/ uint16(xCondDataSize), 6870, 6876, 6886,
+	/*6886*/ uint16(xSetOp), uint16(XADD),
+	/*6888*/ uint16(xReadSlashR),
+	/*6889*/ uint16(xArgRM64),
+	/*6890*/ uint16(xArgR64),
+	/*6891*/ uint16(xMatch),
+	/*6892*/ uint16(xCondPrefix), 4,
+	0xF3, 6926,
+	0xF2, 6918,
+	0x66, 6910,
+	0x0, 6902,
+	/*6902*/ uint16(xSetOp), uint16(CMPPS),
+	/*6904*/ uint16(xReadSlashR),
+	/*6905*/ uint16(xReadIb),
+	/*6906*/ uint16(xArgXmm1),
+	/*6907*/ uint16(xArgXmm2M128),
+	/*6908*/ uint16(xArgImm8u),
+	/*6909*/ uint16(xMatch),
+	/*6910*/ uint16(xSetOp), uint16(CMPPD),
+	/*6912*/ uint16(xReadSlashR),
+	/*6913*/ uint16(xReadIb),
+	/*6914*/ uint16(xArgXmm1),
+	/*6915*/ uint16(xArgXmm2M128),
+	/*6916*/ uint16(xArgImm8u),
+	/*6917*/ uint16(xMatch),
+	/*6918*/ uint16(xSetOp), uint16(CMPSD_XMM),
+	/*6920*/ uint16(xReadSlashR),
+	/*6921*/ uint16(xReadIb),
+	/*6922*/ uint16(xArgXmm1),
+	/*6923*/ uint16(xArgXmm2M64),
+	/*6924*/ uint16(xArgImm8u),
+	/*6925*/ uint16(xMatch),
+	/*6926*/ uint16(xSetOp), uint16(CMPSS),
+	/*6928*/ uint16(xReadSlashR),
+	/*6929*/ uint16(xReadIb),
+	/*6930*/ uint16(xArgXmm1),
+	/*6931*/ uint16(xArgXmm2M32),
+	/*6932*/ uint16(xArgImm8u),
+	/*6933*/ uint16(xMatch),
+	/*6934*/ uint16(xCondIs64), 6937, 6953,
+	/*6937*/ uint16(xCondDataSize), 6941, 6947, 0,
+	/*6941*/ uint16(xSetOp), uint16(MOVNTI),
+	/*6943*/ uint16(xReadSlashR),
+	/*6944*/ uint16(xArgM32),
+	/*6945*/ uint16(xArgR32),
+	/*6946*/ uint16(xMatch),
+	/*6947*/ uint16(xSetOp), uint16(MOVNTI),
+	/*6949*/ uint16(xReadSlashR),
+	/*6950*/ uint16(xArgM32),
+	/*6951*/ uint16(xArgR32),
+	/*6952*/ uint16(xMatch),
+	/*6953*/ uint16(xCondDataSize), 6941, 6947, 6957,
+	/*6957*/ uint16(xSetOp), uint16(MOVNTI),
+	/*6959*/ uint16(xReadSlashR),
+	/*6960*/ uint16(xArgM64),
+	/*6961*/ uint16(xArgR64),
+	/*6962*/ uint16(xMatch),
+	/*6963*/ uint16(xCondPrefix), 2,
+	0x66, 6977,
+	0x0, 6969,
+	/*6969*/ uint16(xSetOp), uint16(PINSRW),
+	/*6971*/ uint16(xReadSlashR),
+	/*6972*/ uint16(xReadIb),
+	/*6973*/ uint16(xArgMm),
+	/*6974*/ uint16(xArgR32M16),
+	/*6975*/ uint16(xArgImm8u),
+	/*6976*/ uint16(xMatch),
+	/*6977*/ uint16(xSetOp), uint16(PINSRW),
+	/*6979*/ uint16(xReadSlashR),
+	/*6980*/ uint16(xReadIb),
+	/*6981*/ uint16(xArgXmm),
+	/*6982*/ uint16(xArgR32M16),
+	/*6983*/ uint16(xArgImm8u),
+	/*6984*/ uint16(xMatch),
+	/*6985*/ uint16(xCondPrefix), 2,
+	0x66, 6999,
+	0x0, 6991,
+	/*6991*/ uint16(xSetOp), uint16(PEXTRW),
+	/*6993*/ uint16(xReadSlashR),
+	/*6994*/ uint16(xReadIb),
+	/*6995*/ uint16(xArgR32),
+	/*6996*/ uint16(xArgMm2),
+	/*6997*/ uint16(xArgImm8u),
+	/*6998*/ uint16(xMatch),
+	/*6999*/ uint16(xSetOp), uint16(PEXTRW),
+	/*7001*/ uint16(xReadSlashR),
+	/*7002*/ uint16(xReadIb),
+	/*7003*/ uint16(xArgR32),
+	/*7004*/ uint16(xArgXmm2),
+	/*7005*/ uint16(xArgImm8u),
+	/*7006*/ uint16(xMatch),
+	/*7007*/ uint16(xCondPrefix), 2,
+	0x66, 7021,
+	0x0, 7013,
+	/*7013*/ uint16(xSetOp), uint16(SHUFPS),
+	/*7015*/ uint16(xReadSlashR),
+	/*7016*/ uint16(xReadIb),
+	/*7017*/ uint16(xArgXmm1),
+	/*7018*/ uint16(xArgXmm2M128),
+	/*7019*/ uint16(xArgImm8u),
+	/*7020*/ uint16(xMatch),
+	/*7021*/ uint16(xSetOp), uint16(SHUFPD),
+	/*7023*/ uint16(xReadSlashR),
+	/*7024*/ uint16(xReadIb),
+	/*7025*/ uint16(xArgXmm1),
+	/*7026*/ uint16(xArgXmm2M128),
+	/*7027*/ uint16(xArgImm8u),
+	/*7028*/ uint16(xMatch),
+	/*7029*/ uint16(xCondSlashR),
 	0,    // 0
-	7029, // 1
+	7038, // 1
 	0,    // 2
-	7052, // 3
-	7075, // 4
-	7098, // 5
-	7121, // 6
+	7061, // 3
+	7084, // 4
+	7107, // 5
+	7130, // 6
 	0,    // 7
-	/*7029*/ uint16(xCondIs64), 7032, 7044,
-	/*7032*/ uint16(xCondDataSize), 7036, 7040, 0,
-	/*7036*/ uint16(xSetOp), uint16(CMPXCHG8B),
-	/*7038*/ uint16(xArgM64),
-	/*7039*/ uint16(xMatch),
-	/*7040*/ uint16(xSetOp), uint16(CMPXCHG8B),
-	/*7042*/ uint16(xArgM64),
-	/*7043*/ uint16(xMatch),
-	/*7044*/ uint16(xCondDataSize), 7036, 7040, 7048,
-	/*7048*/ uint16(xSetOp), uint16(CMPXCHG16B),
-	/*7050*/ uint16(xArgM128),
-	/*7051*/ uint16(xMatch),
-	/*7052*/ uint16(xCondIs64), 7055, 7067,
-	/*7055*/ uint16(xCondDataSize), 7059, 7063, 0,
-	/*7059*/ uint16(xSetOp), uint16(XRSTORS),
-	/*7061*/ uint16(xArgMem),
-	/*7062*/ uint16(xMatch),
-	/*7063*/ uint16(xSetOp), uint16(XRSTORS),
-	/*7065*/ uint16(xArgMem),
-	/*7066*/ uint16(xMatch),
-	/*7067*/ uint16(xCondDataSize), 7059, 7063, 7071,
-	/*7071*/ uint16(xSetOp), uint16(XRSTORS64),
-	/*7073*/ uint16(xArgMem),
-	/*7074*/ uint16(xMatch),
-	/*7075*/ uint16(xCondIs64), 7078, 7090,
-	/*7078*/ uint16(xCondDataSize), 7082, 7086, 0,
-	/*7082*/ uint16(xSetOp), uint16(XSAVEC),
-	/*7084*/ uint16(xArgMem),
-	/*7085*/ uint16(xMatch),
-	/*7086*/ uint16(xSetOp), uint16(XSAVEC),
-	/*7088*/ uint16(xArgMem),
-	/*7089*/ uint16(xMatch),
-	/*7090*/ uint16(xCondDataSize), 7082, 7086, 7094,
-	/*7094*/ uint16(xSetOp), uint16(XSAVEC64),
-	/*7096*/ uint16(xArgMem),
-	/*7097*/ uint16(xMatch),
-	/*7098*/ uint16(xCondIs64), 7101, 7113,
-	/*7101*/ uint16(xCondDataSize), 7105, 7109, 0,
-	/*7105*/ uint16(xSetOp), uint16(XSAVES),
-	/*7107*/ uint16(xArgMem),
-	/*7108*/ uint16(xMatch),
-	/*7109*/ uint16(xSetOp), uint16(XSAVES),
-	/*7111*/ uint16(xArgMem),
-	/*7112*/ uint16(xMatch),
-	/*7113*/ uint16(xCondDataSize), 7105, 7109, 7117,
-	/*7117*/ uint16(xSetOp), uint16(XSAVES64),
-	/*7119*/ uint16(xArgMem),
-	/*7120*/ uint16(xMatch),
-	/*7121*/ uint16(xCondIs64), 7124, 7142,
-	/*7124*/ uint16(xCondDataSize), 7128, 7135, 0,
-	/*7128*/ uint16(xCondIsMem), 7131, 0,
-	/*7131*/ uint16(xSetOp), uint16(RDRAND),
-	/*7133*/ uint16(xArgRmf16),
-	/*7134*/ uint16(xMatch),
-	/*7135*/ uint16(xCondIsMem), 7138, 0,
-	/*7138*/ uint16(xSetOp), uint16(RDRAND),
-	/*7140*/ uint16(xArgRmf32),
-	/*7141*/ uint16(xMatch),
-	/*7142*/ uint16(xCondDataSize), 7128, 7135, 7146,
-	/*7146*/ uint16(xSetOp), uint16(RDRAND),
-	/*7148*/ uint16(xMatch),
-	/*7149*/ uint16(xCondIs64), 7152, 7164,
-	/*7152*/ uint16(xCondDataSize), 7156, 7160, 0,
-	/*7156*/ uint16(xSetOp), uint16(BSWAP),
-	/*7158*/ uint16(xArgR16op),
-	/*7159*/ uint16(xMatch),
-	/*7160*/ uint16(xSetOp), uint16(BSWAP),
-	/*7162*/ uint16(xArgR32op),
-	/*7163*/ uint16(xMatch),
-	/*7164*/ uint16(xCondDataSize), 7156, 7160, 7168,
-	/*7168*/ uint16(xSetOp), uint16(BSWAP),
-	/*7170*/ uint16(xArgR64op),
-	/*7171*/ uint16(xMatch),
-	/*7172*/ uint16(xCondPrefix), 2,
-	0xF2, 7184,
-	0x66, 7178,
-	/*7178*/ uint16(xSetOp), uint16(ADDSUBPD),
-	/*7180*/ uint16(xReadSlashR),
-	/*7181*/ uint16(xArgXmm1),
-	/*7182*/ uint16(xArgXmm2M128),
-	/*7183*/ uint16(xMatch),
-	/*7184*/ uint16(xSetOp), uint16(ADDSUBPS),
-	/*7186*/ uint16(xReadSlashR),
-	/*7187*/ uint16(xArgXmm1),
-	/*7188*/ uint16(xArgXmm2M128),
-	/*7189*/ uint16(xMatch),
-	/*7190*/ uint16(xCondPrefix), 2,
-	0x66, 7202,
-	0x0, 7196,
-	/*7196*/ uint16(xSetOp), uint16(PSRLW),
-	/*7198*/ uint16(xReadSlashR),
-	/*7199*/ uint16(xArgMm),
-	/*7200*/ uint16(xArgMmM64),
-	/*7201*/ uint16(xMatch),
-	/*7202*/ uint16(xSetOp), uint16(PSRLW),
-	/*7204*/ uint16(xReadSlashR),
-	/*7205*/ uint16(xArgXmm1),
-	/*7206*/ uint16(xArgXmm2M128),
-	/*7207*/ uint16(xMatch),
-	/*7208*/ uint16(xCondPrefix), 2,
-	0x66, 7220,
-	0x0, 7214,
-	/*7214*/ uint16(xSetOp), uint16(PSRLD),
-	/*7216*/ uint16(xReadSlashR),
-	/*7217*/ uint16(xArgMm),
-	/*7218*/ uint16(xArgMmM64),
-	/*7219*/ uint16(xMatch),
-	/*7220*/ uint16(xSetOp), uint16(PSRLD),
-	/*7222*/ uint16(xReadSlashR),
-	/*7223*/ uint16(xArgXmm1),
-	/*7224*/ uint16(xArgXmm2M128),
-	/*7225*/ uint16(xMatch),
-	/*7226*/ uint16(xCondPrefix), 2,
-	0x66, 7238,
-	0x0, 7232,
-	/*7232*/ uint16(xSetOp), uint16(PSRLQ),
-	/*7234*/ uint16(xReadSlashR),
-	/*7235*/ uint16(xArgMm),
-	/*7236*/ uint16(xArgMmM64),
-	/*7237*/ uint16(xMatch),
-	/*7238*/ uint16(xSetOp), uint16(PSRLQ),
-	/*7240*/ uint16(xReadSlashR),
-	/*7241*/ uint16(xArgXmm1),
-	/*7242*/ uint16(xArgXmm2M128),
-	/*7243*/ uint16(xMatch),
-	/*7244*/ uint16(xCondPrefix), 2,
-	0x66, 7256,
-	0x0, 7250,
-	/*7250*/ uint16(xSetOp), uint16(PADDQ),
-	/*7252*/ uint16(xReadSlashR),
-	/*7253*/ uint16(xArgMm1),
-	/*7254*/ uint16(xArgMm2M64),
-	/*7255*/ uint16(xMatch),
-	/*7256*/ uint16(xSetOp), uint16(PADDQ),
-	/*7258*/ uint16(xReadSlashR),
-	/*7259*/ uint16(xArgXmm1),
-	/*7260*/ uint16(xArgXmm2M128),
-	/*7261*/ uint16(xMatch),
-	/*7262*/ uint16(xCondPrefix), 2,
-	0x66, 7274,
-	0x0, 7268,
-	/*7268*/ uint16(xSetOp), uint16(PMULLW),
-	/*7270*/ uint16(xReadSlashR),
-	/*7271*/ uint16(xArgMm),
-	/*7272*/ uint16(xArgMmM64),
-	/*7273*/ uint16(xMatch),
-	/*7274*/ uint16(xSetOp), uint16(PMULLW),
-	/*7276*/ uint16(xReadSlashR),
-	/*7277*/ uint16(xArgXmm1),
-	/*7278*/ uint16(xArgXmm2M128),
-	/*7279*/ uint16(xMatch),
-	/*7280*/ uint16(xCondPrefix), 3,
-	0xF3, 7300,
-	0xF2, 7294,
-	0x66, 7288,
-	/*7288*/ uint16(xSetOp), uint16(MOVQ),
-	/*7290*/ uint16(xReadSlashR),
-	/*7291*/ uint16(xArgXmm2M64),
-	/*7292*/ uint16(xArgXmm1),
-	/*7293*/ uint16(xMatch),
-	/*7294*/ uint16(xSetOp), uint16(MOVDQ2Q),
-	/*7296*/ uint16(xReadSlashR),
-	/*7297*/ uint16(xArgMm),
-	/*7298*/ uint16(xArgXmm2),
-	/*7299*/ uint16(xMatch),
-	/*7300*/ uint16(xSetOp), uint16(MOVQ2DQ),
-	/*7302*/ uint16(xReadSlashR),
-	/*7303*/ uint16(xArgXmm1),
-	/*7304*/ uint16(xArgMm2),
-	/*7305*/ uint16(xMatch),
-	/*7306*/ uint16(xCondPrefix), 2,
-	0x66, 7318,
-	0x0, 7312,
-	/*7312*/ uint16(xSetOp), uint16(PMOVMSKB),
-	/*7314*/ uint16(xReadSlashR),
-	/*7315*/ uint16(xArgR32),
-	/*7316*/ uint16(xArgMm2),
-	/*7317*/ uint16(xMatch),
-	/*7318*/ uint16(xSetOp), uint16(PMOVMSKB),
-	/*7320*/ uint16(xReadSlashR),
-	/*7321*/ uint16(xArgR32),
-	/*7322*/ uint16(xArgXmm2),
-	/*7323*/ uint16(xMatch),
-	/*7324*/ uint16(xCondPrefix), 2,
-	0x66, 7336,
-	0x0, 7330,
-	/*7330*/ uint16(xSetOp), uint16(PSUBUSB),
-	/*7332*/ uint16(xReadSlashR),
-	/*7333*/ uint16(xArgMm),
-	/*7334*/ uint16(xArgMmM64),
-	/*7335*/ uint16(xMatch),
-	/*7336*/ uint16(xSetOp), uint16(PSUBUSB),
-	/*7338*/ uint16(xReadSlashR),
-	/*7339*/ uint16(xArgXmm1),
-	/*7340*/ uint16(xArgXmm2M128),
-	/*7341*/ uint16(xMatch),
-	/*7342*/ uint16(xCondPrefix), 2,
-	0x66, 7354,
-	0x0, 7348,
-	/*7348*/ uint16(xSetOp), uint16(PSUBUSW),
-	/*7350*/ uint16(xReadSlashR),
-	/*7351*/ uint16(xArgMm),
-	/*7352*/ uint16(xArgMmM64),
-	/*7353*/ uint16(xMatch),
-	/*7354*/ uint16(xSetOp), uint16(PSUBUSW),
-	/*7356*/ uint16(xReadSlashR),
-	/*7357*/ uint16(xArgXmm1),
-	/*7358*/ uint16(xArgXmm2M128),
-	/*7359*/ uint16(xMatch),
-	/*7360*/ uint16(xCondPrefix), 2,
-	0x66, 7372,
-	0x0, 7366,
-	/*7366*/ uint16(xSetOp), uint16(PMINUB),
-	/*7368*/ uint16(xReadSlashR),
-	/*7369*/ uint16(xArgMm1),
-	/*7370*/ uint16(xArgMm2M64),
-	/*7371*/ uint16(xMatch),
-	/*7372*/ uint16(xSetOp), uint16(PMINUB),
-	/*7374*/ uint16(xReadSlashR),
-	/*7375*/ uint16(xArgXmm1),
-	/*7376*/ uint16(xArgXmm2M128),
-	/*7377*/ uint16(xMatch),
-	/*7378*/ uint16(xCondPrefix), 2,
-	0x66, 7390,
-	0x0, 7384,
-	/*7384*/ uint16(xSetOp), uint16(PAND),
-	/*7386*/ uint16(xReadSlashR),
-	/*7387*/ uint16(xArgMm),
-	/*7388*/ uint16(xArgMmM64),
-	/*7389*/ uint16(xMatch),
-	/*7390*/ uint16(xSetOp), uint16(PAND),
-	/*7392*/ uint16(xReadSlashR),
-	/*7393*/ uint16(xArgXmm1),
-	/*7394*/ uint16(xArgXmm2M128),
-	/*7395*/ uint16(xMatch),
-	/*7396*/ uint16(xCondPrefix), 2,
-	0x66, 7408,
-	0x0, 7402,
-	/*7402*/ uint16(xSetOp), uint16(PADDUSB),
-	/*7404*/ uint16(xReadSlashR),
-	/*7405*/ uint16(xArgMm),
-	/*7406*/ uint16(xArgMmM64),
-	/*7407*/ uint16(xMatch),
-	/*7408*/ uint16(xSetOp), uint16(PADDUSB),
-	/*7410*/ uint16(xReadSlashR),
-	/*7411*/ uint16(xArgXmm1),
-	/*7412*/ uint16(xArgXmm2M128),
-	/*7413*/ uint16(xMatch),
-	/*7414*/ uint16(xCondPrefix), 2,
-	0x66, 7426,
-	0x0, 7420,
-	/*7420*/ uint16(xSetOp), uint16(PADDUSW),
-	/*7422*/ uint16(xReadSlashR),
-	/*7423*/ uint16(xArgMm),
-	/*7424*/ uint16(xArgMmM64),
-	/*7425*/ uint16(xMatch),
-	/*7426*/ uint16(xSetOp), uint16(PADDUSW),
-	/*7428*/ uint16(xReadSlashR),
-	/*7429*/ uint16(xArgXmm1),
-	/*7430*/ uint16(xArgXmm2M128),
-	/*7431*/ uint16(xMatch),
-	/*7432*/ uint16(xCondPrefix), 2,
-	0x66, 7444,
-	0x0, 7438,
-	/*7438*/ uint16(xSetOp), uint16(PMAXUB),
-	/*7440*/ uint16(xReadSlashR),
-	/*7441*/ uint16(xArgMm1),
-	/*7442*/ uint16(xArgMm2M64),
-	/*7443*/ uint16(xMatch),
-	/*7444*/ uint16(xSetOp), uint16(PMAXUB),
-	/*7446*/ uint16(xReadSlashR),
-	/*7447*/ uint16(xArgXmm1),
-	/*7448*/ uint16(xArgXmm2M128),
-	/*7449*/ uint16(xMatch),
-	/*7450*/ uint16(xCondPrefix), 2,
-	0x66, 7462,
-	0x0, 7456,
-	/*7456*/ uint16(xSetOp), uint16(PANDN),
-	/*7458*/ uint16(xReadSlashR),
-	/*7459*/ uint16(xArgMm),
-	/*7460*/ uint16(xArgMmM64),
-	/*7461*/ uint16(xMatch),
-	/*7462*/ uint16(xSetOp), uint16(PANDN),
-	/*7464*/ uint16(xReadSlashR),
-	/*7465*/ uint16(xArgXmm1),
-	/*7466*/ uint16(xArgXmm2M128),
-	/*7467*/ uint16(xMatch),
-	/*7468*/ uint16(xCondPrefix), 2,
-	0x66, 7480,
-	0x0, 7474,
-	/*7474*/ uint16(xSetOp), uint16(PAVGB),
-	/*7476*/ uint16(xReadSlashR),
-	/*7477*/ uint16(xArgMm1),
-	/*7478*/ uint16(xArgMm2M64),
-	/*7479*/ uint16(xMatch),
-	/*7480*/ uint16(xSetOp), uint16(PAVGB),
-	/*7482*/ uint16(xReadSlashR),
-	/*7483*/ uint16(xArgXmm1),
-	/*7484*/ uint16(xArgXmm2M128),
-	/*7485*/ uint16(xMatch),
-	/*7486*/ uint16(xCondPrefix), 2,
-	0x66, 7498,
-	0x0, 7492,
-	/*7492*/ uint16(xSetOp), uint16(PSRAW),
-	/*7494*/ uint16(xReadSlashR),
-	/*7495*/ uint16(xArgMm),
-	/*7496*/ uint16(xArgMmM64),
-	/*7497*/ uint16(xMatch),
-	/*7498*/ uint16(xSetOp), uint16(PSRAW),
-	/*7500*/ uint16(xReadSlashR),
-	/*7501*/ uint16(xArgXmm1),
-	/*7502*/ uint16(xArgXmm2M128),
-	/*7503*/ uint16(xMatch),
-	/*7504*/ uint16(xCondPrefix), 2,
-	0x66, 7516,
-	0x0, 7510,
-	/*7510*/ uint16(xSetOp), uint16(PSRAD),
-	/*7512*/ uint16(xReadSlashR),
-	/*7513*/ uint16(xArgMm),
-	/*7514*/ uint16(xArgMmM64),
-	/*7515*/ uint16(xMatch),
-	/*7516*/ uint16(xSetOp), uint16(PSRAD),
-	/*7518*/ uint16(xReadSlashR),
-	/*7519*/ uint16(xArgXmm1),
-	/*7520*/ uint16(xArgXmm2M128),
-	/*7521*/ uint16(xMatch),
-	/*7522*/ uint16(xCondPrefix), 2,
-	0x66, 7534,
-	0x0, 7528,
-	/*7528*/ uint16(xSetOp), uint16(PAVGW),
-	/*7530*/ uint16(xReadSlashR),
-	/*7531*/ uint16(xArgMm1),
-	/*7532*/ uint16(xArgMm2M64),
-	/*7533*/ uint16(xMatch),
-	/*7534*/ uint16(xSetOp), uint16(PAVGW),
-	/*7536*/ uint16(xReadSlashR),
-	/*7537*/ uint16(xArgXmm1),
-	/*7538*/ uint16(xArgXmm2M128),
-	/*7539*/ uint16(xMatch),
-	/*7540*/ uint16(xCondPrefix), 2,
-	0x66, 7552,
-	0x0, 7546,
-	/*7546*/ uint16(xSetOp), uint16(PMULHUW),
-	/*7548*/ uint16(xReadSlashR),
-	/*7549*/ uint16(xArgMm1),
-	/*7550*/ uint16(xArgMm2M64),
-	/*7551*/ uint16(xMatch),
-	/*7552*/ uint16(xSetOp), uint16(PMULHUW),
-	/*7554*/ uint16(xReadSlashR),
-	/*7555*/ uint16(xArgXmm1),
-	/*7556*/ uint16(xArgXmm2M128),
-	/*7557*/ uint16(xMatch),
-	/*7558*/ uint16(xCondPrefix), 2,
-	0x66, 7570,
-	0x0, 7564,
-	/*7564*/ uint16(xSetOp), uint16(PMULHW),
-	/*7566*/ uint16(xReadSlashR),
-	/*7567*/ uint16(xArgMm),
-	/*7568*/ uint16(xArgMmM64),
-	/*7569*/ uint16(xMatch),
-	/*7570*/ uint16(xSetOp), uint16(PMULHW),
-	/*7572*/ uint16(xReadSlashR),
-	/*7573*/ uint16(xArgXmm1),
-	/*7574*/ uint16(xArgXmm2M128),
-	/*7575*/ uint16(xMatch),
-	/*7576*/ uint16(xCondPrefix), 3,
-	0xF3, 7596,
-	0xF2, 7590,
-	0x66, 7584,
-	/*7584*/ uint16(xSetOp), uint16(CVTTPD2DQ),
-	/*7586*/ uint16(xReadSlashR),
-	/*7587*/ uint16(xArgXmm1),
-	/*7588*/ uint16(xArgXmm2M128),
-	/*7589*/ uint16(xMatch),
-	/*7590*/ uint16(xSetOp), uint16(CVTPD2DQ),
-	/*7592*/ uint16(xReadSlashR),
-	/*7593*/ uint16(xArgXmm1),
-	/*7594*/ uint16(xArgXmm2M128),
-	/*7595*/ uint16(xMatch),
-	/*7596*/ uint16(xSetOp), uint16(CVTDQ2PD),
-	/*7598*/ uint16(xReadSlashR),
-	/*7599*/ uint16(xArgXmm1),
-	/*7600*/ uint16(xArgXmm2M64),
-	/*7601*/ uint16(xMatch),
-	/*7602*/ uint16(xCondPrefix), 2,
-	0x66, 7614,
-	0x0, 7608,
-	/*7608*/ uint16(xSetOp), uint16(MOVNTQ),
-	/*7610*/ uint16(xReadSlashR),
-	/*7611*/ uint16(xArgM64),
-	/*7612*/ uint16(xArgMm),
-	/*7613*/ uint16(xMatch),
-	/*7614*/ uint16(xSetOp), uint16(MOVNTDQ),
-	/*7616*/ uint16(xReadSlashR),
-	/*7617*/ uint16(xArgM128),
-	/*7618*/ uint16(xArgXmm),
-	/*7619*/ uint16(xMatch),
-	/*7620*/ uint16(xCondPrefix), 2,
-	0x66, 7632,
-	0x0, 7626,
-	/*7626*/ uint16(xSetOp), uint16(PSUBSB),
-	/*7628*/ uint16(xReadSlashR),
-	/*7629*/ uint16(xArgMm),
-	/*7630*/ uint16(xArgMmM64),
-	/*7631*/ uint16(xMatch),
-	/*7632*/ uint16(xSetOp), uint16(PSUBSB),
-	/*7634*/ uint16(xReadSlashR),
-	/*7635*/ uint16(xArgXmm1),
-	/*7636*/ uint16(xArgXmm2M128),
-	/*7637*/ uint16(xMatch),
-	/*7638*/ uint16(xCondPrefix), 2,
-	0x66, 7650,
-	0x0, 7644,
-	/*7644*/ uint16(xSetOp), uint16(PSUBSW),
-	/*7646*/ uint16(xReadSlashR),
-	/*7647*/ uint16(xArgMm),
-	/*7648*/ uint16(xArgMmM64),
-	/*7649*/ uint16(xMatch),
-	/*7650*/ uint16(xSetOp), uint16(PSUBSW),
-	/*7652*/ uint16(xReadSlashR),
-	/*7653*/ uint16(xArgXmm1),
-	/*7654*/ uint16(xArgXmm2M128),
-	/*7655*/ uint16(xMatch),
-	/*7656*/ uint16(xCondPrefix), 2,
-	0x66, 7668,
-	0x0, 7662,
-	/*7662*/ uint16(xSetOp), uint16(PMINSW),
-	/*7664*/ uint16(xReadSlashR),
-	/*7665*/ uint16(xArgMm1),
-	/*7666*/ uint16(xArgMm2M64),
-	/*7667*/ uint16(xMatch),
-	/*7668*/ uint16(xSetOp), uint16(PMINSW),
-	/*7670*/ uint16(xReadSlashR),
-	/*7671*/ uint16(xArgXmm1),
-	/*7672*/ uint16(xArgXmm2M128),
-	/*7673*/ uint16(xMatch),
-	/*7674*/ uint16(xCondPrefix), 2,
-	0x66, 7686,
-	0x0, 7680,
-	/*7680*/ uint16(xSetOp), uint16(POR),
-	/*7682*/ uint16(xReadSlashR),
-	/*7683*/ uint16(xArgMm),
-	/*7684*/ uint16(xArgMmM64),
-	/*7685*/ uint16(xMatch),
-	/*7686*/ uint16(xSetOp), uint16(POR),
-	/*7688*/ uint16(xReadSlashR),
-	/*7689*/ uint16(xArgXmm1),
-	/*7690*/ uint16(xArgXmm2M128),
-	/*7691*/ uint16(xMatch),
-	/*7692*/ uint16(xCondPrefix), 2,
-	0x66, 7704,
-	0x0, 7698,
-	/*7698*/ uint16(xSetOp), uint16(PADDSB),
-	/*7700*/ uint16(xReadSlashR),
-	/*7701*/ uint16(xArgMm),
-	/*7702*/ uint16(xArgMmM64),
-	/*7703*/ uint16(xMatch),
-	/*7704*/ uint16(xSetOp), uint16(PADDSB),
-	/*7706*/ uint16(xReadSlashR),
-	/*7707*/ uint16(xArgXmm1),
-	/*7708*/ uint16(xArgXmm2M128),
-	/*7709*/ uint16(xMatch),
-	/*7710*/ uint16(xCondPrefix), 2,
-	0x66, 7722,
-	0x0, 7716,
-	/*7716*/ uint16(xSetOp), uint16(PADDSW),
-	/*7718*/ uint16(xReadSlashR),
-	/*7719*/ uint16(xArgMm),
-	/*7720*/ uint16(xArgMmM64),
-	/*7721*/ uint16(xMatch),
-	/*7722*/ uint16(xSetOp), uint16(PADDSW),
-	/*7724*/ uint16(xReadSlashR),
-	/*7725*/ uint16(xArgXmm1),
-	/*7726*/ uint16(xArgXmm2M128),
-	/*7727*/ uint16(xMatch),
-	/*7728*/ uint16(xCondPrefix), 2,
-	0x66, 7740,
-	0x0, 7734,
-	/*7734*/ uint16(xSetOp), uint16(PMAXSW),
-	/*7736*/ uint16(xReadSlashR),
-	/*7737*/ uint16(xArgMm1),
-	/*7738*/ uint16(xArgMm2M64),
-	/*7739*/ uint16(xMatch),
-	/*7740*/ uint16(xSetOp), uint16(PMAXSW),
-	/*7742*/ uint16(xReadSlashR),
-	/*7743*/ uint16(xArgXmm1),
-	/*7744*/ uint16(xArgXmm2M128),
-	/*7745*/ uint16(xMatch),
-	/*7746*/ uint16(xCondPrefix), 2,
-	0x66, 7758,
-	0x0, 7752,
-	/*7752*/ uint16(xSetOp), uint16(PXOR),
-	/*7754*/ uint16(xReadSlashR),
-	/*7755*/ uint16(xArgMm),
-	/*7756*/ uint16(xArgMmM64),
-	/*7757*/ uint16(xMatch),
-	/*7758*/ uint16(xSetOp), uint16(PXOR),
-	/*7760*/ uint16(xReadSlashR),
-	/*7761*/ uint16(xArgXmm1),
-	/*7762*/ uint16(xArgXmm2M128),
-	/*7763*/ uint16(xMatch),
-	/*7764*/ uint16(xCondPrefix), 1,
-	0xF2, 7768,
-	/*7768*/ uint16(xSetOp), uint16(LDDQU),
-	/*7770*/ uint16(xReadSlashR),
-	/*7771*/ uint16(xArgXmm1),
-	/*7772*/ uint16(xArgM128),
-	/*7773*/ uint16(xMatch),
-	/*7774*/ uint16(xCondPrefix), 2,
-	0x66, 7786,
-	0x0, 7780,
-	/*7780*/ uint16(xSetOp), uint16(PSLLW),
-	/*7782*/ uint16(xReadSlashR),
-	/*7783*/ uint16(xArgMm),
-	/*7784*/ uint16(xArgMmM64),
-	/*7785*/ uint16(xMatch),
-	/*7786*/ uint16(xSetOp), uint16(PSLLW),
-	/*7788*/ uint16(xReadSlashR),
-	/*7789*/ uint16(xArgXmm1),
-	/*7790*/ uint16(xArgXmm2M128),
-	/*7791*/ uint16(xMatch),
-	/*7792*/ uint16(xCondPrefix), 2,
-	0x66, 7804,
-	0x0, 7798,
-	/*7798*/ uint16(xSetOp), uint16(PSLLD),
-	/*7800*/ uint16(xReadSlashR),
-	/*7801*/ uint16(xArgMm),
-	/*7802*/ uint16(xArgMmM64),
-	/*7803*/ uint16(xMatch),
-	/*7804*/ uint16(xSetOp), uint16(PSLLD),
-	/*7806*/ uint16(xReadSlashR),
-	/*7807*/ uint16(xArgXmm1),
-	/*7808*/ uint16(xArgXmm2M128),
-	/*7809*/ uint16(xMatch),
-	/*7810*/ uint16(xCondPrefix), 2,
-	0x66, 7822,
-	0x0, 7816,
-	/*7816*/ uint16(xSetOp), uint16(PSLLQ),
-	/*7818*/ uint16(xReadSlashR),
-	/*7819*/ uint16(xArgMm),
-	/*7820*/ uint16(xArgMmM64),
-	/*7821*/ uint16(xMatch),
-	/*7822*/ uint16(xSetOp), uint16(PSLLQ),
-	/*7824*/ uint16(xReadSlashR),
-	/*7825*/ uint16(xArgXmm1),
-	/*7826*/ uint16(xArgXmm2M128),
-	/*7827*/ uint16(xMatch),
-	/*7828*/ uint16(xCondPrefix), 2,
-	0x66, 7840,
-	0x0, 7834,
-	/*7834*/ uint16(xSetOp), uint16(PMULUDQ),
-	/*7836*/ uint16(xReadSlashR),
-	/*7837*/ uint16(xArgMm1),
-	/*7838*/ uint16(xArgMm2M64),
-	/*7839*/ uint16(xMatch),
-	/*7840*/ uint16(xSetOp), uint16(PMULUDQ),
-	/*7842*/ uint16(xReadSlashR),
-	/*7843*/ uint16(xArgXmm1),
-	/*7844*/ uint16(xArgXmm2M128),
-	/*7845*/ uint16(xMatch),
-	/*7846*/ uint16(xCondPrefix), 2,
-	0x66, 7858,
-	0x0, 7852,
-	/*7852*/ uint16(xSetOp), uint16(PMADDWD),
-	/*7854*/ uint16(xReadSlashR),
-	/*7855*/ uint16(xArgMm),
-	/*7856*/ uint16(xArgMmM64),
-	/*7857*/ uint16(xMatch),
-	/*7858*/ uint16(xSetOp), uint16(PMADDWD),
-	/*7860*/ uint16(xReadSlashR),
-	/*7861*/ uint16(xArgXmm1),
-	/*7862*/ uint16(xArgXmm2M128),
-	/*7863*/ uint16(xMatch),
-	/*7864*/ uint16(xCondPrefix), 2,
-	0x66, 7876,
-	0x0, 7870,
-	/*7870*/ uint16(xSetOp), uint16(PSADBW),
-	/*7872*/ uint16(xReadSlashR),
-	/*7873*/ uint16(xArgMm1),
-	/*7874*/ uint16(xArgMm2M64),
-	/*7875*/ uint16(xMatch),
-	/*7876*/ uint16(xSetOp), uint16(PSADBW),
-	/*7878*/ uint16(xReadSlashR),
-	/*7879*/ uint16(xArgXmm1),
-	/*7880*/ uint16(xArgXmm2M128),
-	/*7881*/ uint16(xMatch),
-	/*7882*/ uint16(xCondPrefix), 2,
-	0x66, 7894,
-	0x0, 7888,
-	/*7888*/ uint16(xSetOp), uint16(MASKMOVQ),
-	/*7890*/ uint16(xReadSlashR),
-	/*7891*/ uint16(xArgMm1),
-	/*7892*/ uint16(xArgMm2),
-	/*7893*/ uint16(xMatch),
-	/*7894*/ uint16(xSetOp), uint16(MASKMOVDQU),
-	/*7896*/ uint16(xReadSlashR),
-	/*7897*/ uint16(xArgXmm1),
-	/*7898*/ uint16(xArgXmm2),
-	/*7899*/ uint16(xMatch),
-	/*7900*/ uint16(xCondPrefix), 2,
-	0x66, 7912,
-	0x0, 7906,
-	/*7906*/ uint16(xSetOp), uint16(PSUBB),
-	/*7908*/ uint16(xReadSlashR),
-	/*7909*/ uint16(xArgMm),
-	/*7910*/ uint16(xArgMmM64),
-	/*7911*/ uint16(xMatch),
-	/*7912*/ uint16(xSetOp), uint16(PSUBB),
-	/*7914*/ uint16(xReadSlashR),
-	/*7915*/ uint16(xArgXmm1),
-	/*7916*/ uint16(xArgXmm2M128),
-	/*7917*/ uint16(xMatch),
-	/*7918*/ uint16(xCondPrefix), 2,
-	0x66, 7930,
-	0x0, 7924,
-	/*7924*/ uint16(xSetOp), uint16(PSUBW),
-	/*7926*/ uint16(xReadSlashR),
-	/*7927*/ uint16(xArgMm),
-	/*7928*/ uint16(xArgMmM64),
-	/*7929*/ uint16(xMatch),
-	/*7930*/ uint16(xSetOp), uint16(PSUBW),
-	/*7932*/ uint16(xReadSlashR),
-	/*7933*/ uint16(xArgXmm1),
-	/*7934*/ uint16(xArgXmm2M128),
-	/*7935*/ uint16(xMatch),
-	/*7936*/ uint16(xCondPrefix), 2,
-	0x66, 7948,
-	0x0, 7942,
-	/*7942*/ uint16(xSetOp), uint16(PSUBD),
-	/*7944*/ uint16(xReadSlashR),
-	/*7945*/ uint16(xArgMm),
-	/*7946*/ uint16(xArgMmM64),
-	/*7947*/ uint16(xMatch),
-	/*7948*/ uint16(xSetOp), uint16(PSUBD),
-	/*7950*/ uint16(xReadSlashR),
-	/*7951*/ uint16(xArgXmm1),
-	/*7952*/ uint16(xArgXmm2M128),
-	/*7953*/ uint16(xMatch),
-	/*7954*/ uint16(xCondPrefix), 2,
-	0x66, 7966,
-	0x0, 7960,
-	/*7960*/ uint16(xSetOp), uint16(PSUBQ),
-	/*7962*/ uint16(xReadSlashR),
-	/*7963*/ uint16(xArgMm1),
-	/*7964*/ uint16(xArgMm2M64),
-	/*7965*/ uint16(xMatch),
-	/*7966*/ uint16(xSetOp), uint16(PSUBQ),
-	/*7968*/ uint16(xReadSlashR),
-	/*7969*/ uint16(xArgXmm1),
-	/*7970*/ uint16(xArgXmm2M128),
-	/*7971*/ uint16(xMatch),
-	/*7972*/ uint16(xCondPrefix), 2,
-	0x66, 7984,
-	0x0, 7978,
-	/*7978*/ uint16(xSetOp), uint16(PADDB),
-	/*7980*/ uint16(xReadSlashR),
-	/*7981*/ uint16(xArgMm),
-	/*7982*/ uint16(xArgMmM64),
-	/*7983*/ uint16(xMatch),
-	/*7984*/ uint16(xSetOp), uint16(PADDB),
-	/*7986*/ uint16(xReadSlashR),
-	/*7987*/ uint16(xArgXmm1),
-	/*7988*/ uint16(xArgXmm2M128),
-	/*7989*/ uint16(xMatch),
-	/*7990*/ uint16(xCondPrefix), 2,
-	0x66, 8002,
-	0x0, 7996,
-	/*7996*/ uint16(xSetOp), uint16(PADDW),
-	/*7998*/ uint16(xReadSlashR),
-	/*7999*/ uint16(xArgMm),
-	/*8000*/ uint16(xArgMmM64),
-	/*8001*/ uint16(xMatch),
-	/*8002*/ uint16(xSetOp), uint16(PADDW),
-	/*8004*/ uint16(xReadSlashR),
-	/*8005*/ uint16(xArgXmm1),
-	/*8006*/ uint16(xArgXmm2M128),
-	/*8007*/ uint16(xMatch),
-	/*8008*/ uint16(xCondPrefix), 2,
-	0x66, 8020,
-	0x0, 8014,
-	/*8014*/ uint16(xSetOp), uint16(PADDD),
-	/*8016*/ uint16(xReadSlashR),
-	/*8017*/ uint16(xArgMm),
-	/*8018*/ uint16(xArgMmM64),
-	/*8019*/ uint16(xMatch),
-	/*8020*/ uint16(xSetOp), uint16(PADDD),
-	/*8022*/ uint16(xReadSlashR),
-	/*8023*/ uint16(xArgXmm1),
-	/*8024*/ uint16(xArgXmm2M128),
-	/*8025*/ uint16(xMatch),
-	/*8026*/ uint16(xSetOp), uint16(ADC),
-	/*8028*/ uint16(xReadSlashR),
-	/*8029*/ uint16(xArgRM8),
-	/*8030*/ uint16(xArgR8),
-	/*8031*/ uint16(xMatch),
-	/*8032*/ uint16(xCondIs64), 8035, 8051,
-	/*8035*/ uint16(xCondDataSize), 8039, 8045, 0,
-	/*8039*/ uint16(xSetOp), uint16(ADC),
+	/*7038*/ uint16(xCondIs64), 7041, 7053,
+	/*7041*/ uint16(xCondDataSize), 7045, 7049, 0,
+	/*7045*/ uint16(xSetOp), uint16(CMPXCHG8B),
+	/*7047*/ uint16(xArgM64),
+	/*7048*/ uint16(xMatch),
+	/*7049*/ uint16(xSetOp), uint16(CMPXCHG8B),
+	/*7051*/ uint16(xArgM64),
+	/*7052*/ uint16(xMatch),
+	/*7053*/ uint16(xCondDataSize), 7045, 7049, 7057,
+	/*7057*/ uint16(xSetOp), uint16(CMPXCHG16B),
+	/*7059*/ uint16(xArgM128),
+	/*7060*/ uint16(xMatch),
+	/*7061*/ uint16(xCondIs64), 7064, 7076,
+	/*7064*/ uint16(xCondDataSize), 7068, 7072, 0,
+	/*7068*/ uint16(xSetOp), uint16(XRSTORS),
+	/*7070*/ uint16(xArgMem),
+	/*7071*/ uint16(xMatch),
+	/*7072*/ uint16(xSetOp), uint16(XRSTORS),
+	/*7074*/ uint16(xArgMem),
+	/*7075*/ uint16(xMatch),
+	/*7076*/ uint16(xCondDataSize), 7068, 7072, 7080,
+	/*7080*/ uint16(xSetOp), uint16(XRSTORS64),
+	/*7082*/ uint16(xArgMem),
+	/*7083*/ uint16(xMatch),
+	/*7084*/ uint16(xCondIs64), 7087, 7099,
+	/*7087*/ uint16(xCondDataSize), 7091, 7095, 0,
+	/*7091*/ uint16(xSetOp), uint16(XSAVEC),
+	/*7093*/ uint16(xArgMem),
+	/*7094*/ uint16(xMatch),
+	/*7095*/ uint16(xSetOp), uint16(XSAVEC),
+	/*7097*/ uint16(xArgMem),
+	/*7098*/ uint16(xMatch),
+	/*7099*/ uint16(xCondDataSize), 7091, 7095, 7103,
+	/*7103*/ uint16(xSetOp), uint16(XSAVEC64),
+	/*7105*/ uint16(xArgMem),
+	/*7106*/ uint16(xMatch),
+	/*7107*/ uint16(xCondIs64), 7110, 7122,
+	/*7110*/ uint16(xCondDataSize), 7114, 7118, 0,
+	/*7114*/ uint16(xSetOp), uint16(XSAVES),
+	/*7116*/ uint16(xArgMem),
+	/*7117*/ uint16(xMatch),
+	/*7118*/ uint16(xSetOp), uint16(XSAVES),
+	/*7120*/ uint16(xArgMem),
+	/*7121*/ uint16(xMatch),
+	/*7122*/ uint16(xCondDataSize), 7114, 7118, 7126,
+	/*7126*/ uint16(xSetOp), uint16(XSAVES64),
+	/*7128*/ uint16(xArgMem),
+	/*7129*/ uint16(xMatch),
+	/*7130*/ uint16(xCondIs64), 7133, 7151,
+	/*7133*/ uint16(xCondDataSize), 7137, 7144, 0,
+	/*7137*/ uint16(xCondIsMem), 7140, 0,
+	/*7140*/ uint16(xSetOp), uint16(RDRAND),
+	/*7142*/ uint16(xArgRmf16),
+	/*7143*/ uint16(xMatch),
+	/*7144*/ uint16(xCondIsMem), 7147, 0,
+	/*7147*/ uint16(xSetOp), uint16(RDRAND),
+	/*7149*/ uint16(xArgRmf32),
+	/*7150*/ uint16(xMatch),
+	/*7151*/ uint16(xCondDataSize), 7137, 7144, 7155,
+	/*7155*/ uint16(xSetOp), uint16(RDRAND),
+	/*7157*/ uint16(xMatch),
+	/*7158*/ uint16(xCondIs64), 7161, 7173,
+	/*7161*/ uint16(xCondDataSize), 7165, 7169, 0,
+	/*7165*/ uint16(xSetOp), uint16(BSWAP),
+	/*7167*/ uint16(xArgR16op),
+	/*7168*/ uint16(xMatch),
+	/*7169*/ uint16(xSetOp), uint16(BSWAP),
+	/*7171*/ uint16(xArgR32op),
+	/*7172*/ uint16(xMatch),
+	/*7173*/ uint16(xCondDataSize), 7165, 7169, 7177,
+	/*7177*/ uint16(xSetOp), uint16(BSWAP),
+	/*7179*/ uint16(xArgR64op),
+	/*7180*/ uint16(xMatch),
+	/*7181*/ uint16(xCondPrefix), 2,
+	0xF2, 7193,
+	0x66, 7187,
+	/*7187*/ uint16(xSetOp), uint16(ADDSUBPD),
+	/*7189*/ uint16(xReadSlashR),
+	/*7190*/ uint16(xArgXmm1),
+	/*7191*/ uint16(xArgXmm2M128),
+	/*7192*/ uint16(xMatch),
+	/*7193*/ uint16(xSetOp), uint16(ADDSUBPS),
+	/*7195*/ uint16(xReadSlashR),
+	/*7196*/ uint16(xArgXmm1),
+	/*7197*/ uint16(xArgXmm2M128),
+	/*7198*/ uint16(xMatch),
+	/*7199*/ uint16(xCondPrefix), 2,
+	0x66, 7211,
+	0x0, 7205,
+	/*7205*/ uint16(xSetOp), uint16(PSRLW),
+	/*7207*/ uint16(xReadSlashR),
+	/*7208*/ uint16(xArgMm),
+	/*7209*/ uint16(xArgMmM64),
+	/*7210*/ uint16(xMatch),
+	/*7211*/ uint16(xSetOp), uint16(PSRLW),
+	/*7213*/ uint16(xReadSlashR),
+	/*7214*/ uint16(xArgXmm1),
+	/*7215*/ uint16(xArgXmm2M128),
+	/*7216*/ uint16(xMatch),
+	/*7217*/ uint16(xCondPrefix), 2,
+	0x66, 7229,
+	0x0, 7223,
+	/*7223*/ uint16(xSetOp), uint16(PSRLD),
+	/*7225*/ uint16(xReadSlashR),
+	/*7226*/ uint16(xArgMm),
+	/*7227*/ uint16(xArgMmM64),
+	/*7228*/ uint16(xMatch),
+	/*7229*/ uint16(xSetOp), uint16(PSRLD),
+	/*7231*/ uint16(xReadSlashR),
+	/*7232*/ uint16(xArgXmm1),
+	/*7233*/ uint16(xArgXmm2M128),
+	/*7234*/ uint16(xMatch),
+	/*7235*/ uint16(xCondPrefix), 2,
+	0x66, 7247,
+	0x0, 7241,
+	/*7241*/ uint16(xSetOp), uint16(PSRLQ),
+	/*7243*/ uint16(xReadSlashR),
+	/*7244*/ uint16(xArgMm),
+	/*7245*/ uint16(xArgMmM64),
+	/*7246*/ uint16(xMatch),
+	/*7247*/ uint16(xSetOp), uint16(PSRLQ),
+	/*7249*/ uint16(xReadSlashR),
+	/*7250*/ uint16(xArgXmm1),
+	/*7251*/ uint16(xArgXmm2M128),
+	/*7252*/ uint16(xMatch),
+	/*7253*/ uint16(xCondPrefix), 2,
+	0x66, 7265,
+	0x0, 7259,
+	/*7259*/ uint16(xSetOp), uint16(PADDQ),
+	/*7261*/ uint16(xReadSlashR),
+	/*7262*/ uint16(xArgMm1),
+	/*7263*/ uint16(xArgMm2M64),
+	/*7264*/ uint16(xMatch),
+	/*7265*/ uint16(xSetOp), uint16(PADDQ),
+	/*7267*/ uint16(xReadSlashR),
+	/*7268*/ uint16(xArgXmm1),
+	/*7269*/ uint16(xArgXmm2M128),
+	/*7270*/ uint16(xMatch),
+	/*7271*/ uint16(xCondPrefix), 2,
+	0x66, 7283,
+	0x0, 7277,
+	/*7277*/ uint16(xSetOp), uint16(PMULLW),
+	/*7279*/ uint16(xReadSlashR),
+	/*7280*/ uint16(xArgMm),
+	/*7281*/ uint16(xArgMmM64),
+	/*7282*/ uint16(xMatch),
+	/*7283*/ uint16(xSetOp), uint16(PMULLW),
+	/*7285*/ uint16(xReadSlashR),
+	/*7286*/ uint16(xArgXmm1),
+	/*7287*/ uint16(xArgXmm2M128),
+	/*7288*/ uint16(xMatch),
+	/*7289*/ uint16(xCondPrefix), 3,
+	0xF3, 7309,
+	0xF2, 7303,
+	0x66, 7297,
+	/*7297*/ uint16(xSetOp), uint16(MOVQ),
+	/*7299*/ uint16(xReadSlashR),
+	/*7300*/ uint16(xArgXmm2M64),
+	/*7301*/ uint16(xArgXmm1),
+	/*7302*/ uint16(xMatch),
+	/*7303*/ uint16(xSetOp), uint16(MOVDQ2Q),
+	/*7305*/ uint16(xReadSlashR),
+	/*7306*/ uint16(xArgMm),
+	/*7307*/ uint16(xArgXmm2),
+	/*7308*/ uint16(xMatch),
+	/*7309*/ uint16(xSetOp), uint16(MOVQ2DQ),
+	/*7311*/ uint16(xReadSlashR),
+	/*7312*/ uint16(xArgXmm1),
+	/*7313*/ uint16(xArgMm2),
+	/*7314*/ uint16(xMatch),
+	/*7315*/ uint16(xCondPrefix), 2,
+	0x66, 7327,
+	0x0, 7321,
+	/*7321*/ uint16(xSetOp), uint16(PMOVMSKB),
+	/*7323*/ uint16(xReadSlashR),
+	/*7324*/ uint16(xArgR32),
+	/*7325*/ uint16(xArgMm2),
+	/*7326*/ uint16(xMatch),
+	/*7327*/ uint16(xSetOp), uint16(PMOVMSKB),
+	/*7329*/ uint16(xReadSlashR),
+	/*7330*/ uint16(xArgR32),
+	/*7331*/ uint16(xArgXmm2),
+	/*7332*/ uint16(xMatch),
+	/*7333*/ uint16(xCondPrefix), 2,
+	0x66, 7345,
+	0x0, 7339,
+	/*7339*/ uint16(xSetOp), uint16(PSUBUSB),
+	/*7341*/ uint16(xReadSlashR),
+	/*7342*/ uint16(xArgMm),
+	/*7343*/ uint16(xArgMmM64),
+	/*7344*/ uint16(xMatch),
+	/*7345*/ uint16(xSetOp), uint16(PSUBUSB),
+	/*7347*/ uint16(xReadSlashR),
+	/*7348*/ uint16(xArgXmm1),
+	/*7349*/ uint16(xArgXmm2M128),
+	/*7350*/ uint16(xMatch),
+	/*7351*/ uint16(xCondPrefix), 2,
+	0x66, 7363,
+	0x0, 7357,
+	/*7357*/ uint16(xSetOp), uint16(PSUBUSW),
+	/*7359*/ uint16(xReadSlashR),
+	/*7360*/ uint16(xArgMm),
+	/*7361*/ uint16(xArgMmM64),
+	/*7362*/ uint16(xMatch),
+	/*7363*/ uint16(xSetOp), uint16(PSUBUSW),
+	/*7365*/ uint16(xReadSlashR),
+	/*7366*/ uint16(xArgXmm1),
+	/*7367*/ uint16(xArgXmm2M128),
+	/*7368*/ uint16(xMatch),
+	/*7369*/ uint16(xCondPrefix), 2,
+	0x66, 7381,
+	0x0, 7375,
+	/*7375*/ uint16(xSetOp), uint16(PMINUB),
+	/*7377*/ uint16(xReadSlashR),
+	/*7378*/ uint16(xArgMm1),
+	/*7379*/ uint16(xArgMm2M64),
+	/*7380*/ uint16(xMatch),
+	/*7381*/ uint16(xSetOp), uint16(PMINUB),
+	/*7383*/ uint16(xReadSlashR),
+	/*7384*/ uint16(xArgXmm1),
+	/*7385*/ uint16(xArgXmm2M128),
+	/*7386*/ uint16(xMatch),
+	/*7387*/ uint16(xCondPrefix), 2,
+	0x66, 7399,
+	0x0, 7393,
+	/*7393*/ uint16(xSetOp), uint16(PAND),
+	/*7395*/ uint16(xReadSlashR),
+	/*7396*/ uint16(xArgMm),
+	/*7397*/ uint16(xArgMmM64),
+	/*7398*/ uint16(xMatch),
+	/*7399*/ uint16(xSetOp), uint16(PAND),
+	/*7401*/ uint16(xReadSlashR),
+	/*7402*/ uint16(xArgXmm1),
+	/*7403*/ uint16(xArgXmm2M128),
+	/*7404*/ uint16(xMatch),
+	/*7405*/ uint16(xCondPrefix), 2,
+	0x66, 7417,
+	0x0, 7411,
+	/*7411*/ uint16(xSetOp), uint16(PADDUSB),
+	/*7413*/ uint16(xReadSlashR),
+	/*7414*/ uint16(xArgMm),
+	/*7415*/ uint16(xArgMmM64),
+	/*7416*/ uint16(xMatch),
+	/*7417*/ uint16(xSetOp), uint16(PADDUSB),
+	/*7419*/ uint16(xReadSlashR),
+	/*7420*/ uint16(xArgXmm1),
+	/*7421*/ uint16(xArgXmm2M128),
+	/*7422*/ uint16(xMatch),
+	/*7423*/ uint16(xCondPrefix), 2,
+	0x66, 7435,
+	0x0, 7429,
+	/*7429*/ uint16(xSetOp), uint16(PADDUSW),
+	/*7431*/ uint16(xReadSlashR),
+	/*7432*/ uint16(xArgMm),
+	/*7433*/ uint16(xArgMmM64),
+	/*7434*/ uint16(xMatch),
+	/*7435*/ uint16(xSetOp), uint16(PADDUSW),
+	/*7437*/ uint16(xReadSlashR),
+	/*7438*/ uint16(xArgXmm1),
+	/*7439*/ uint16(xArgXmm2M128),
+	/*7440*/ uint16(xMatch),
+	/*7441*/ uint16(xCondPrefix), 2,
+	0x66, 7453,
+	0x0, 7447,
+	/*7447*/ uint16(xSetOp), uint16(PMAXUB),
+	/*7449*/ uint16(xReadSlashR),
+	/*7450*/ uint16(xArgMm1),
+	/*7451*/ uint16(xArgMm2M64),
+	/*7452*/ uint16(xMatch),
+	/*7453*/ uint16(xSetOp), uint16(PMAXUB),
+	/*7455*/ uint16(xReadSlashR),
+	/*7456*/ uint16(xArgXmm1),
+	/*7457*/ uint16(xArgXmm2M128),
+	/*7458*/ uint16(xMatch),
+	/*7459*/ uint16(xCondPrefix), 2,
+	0x66, 7471,
+	0x0, 7465,
+	/*7465*/ uint16(xSetOp), uint16(PANDN),
+	/*7467*/ uint16(xReadSlashR),
+	/*7468*/ uint16(xArgMm),
+	/*7469*/ uint16(xArgMmM64),
+	/*7470*/ uint16(xMatch),
+	/*7471*/ uint16(xSetOp), uint16(PANDN),
+	/*7473*/ uint16(xReadSlashR),
+	/*7474*/ uint16(xArgXmm1),
+	/*7475*/ uint16(xArgXmm2M128),
+	/*7476*/ uint16(xMatch),
+	/*7477*/ uint16(xCondPrefix), 2,
+	0x66, 7489,
+	0x0, 7483,
+	/*7483*/ uint16(xSetOp), uint16(PAVGB),
+	/*7485*/ uint16(xReadSlashR),
+	/*7486*/ uint16(xArgMm1),
+	/*7487*/ uint16(xArgMm2M64),
+	/*7488*/ uint16(xMatch),
+	/*7489*/ uint16(xSetOp), uint16(PAVGB),
+	/*7491*/ uint16(xReadSlashR),
+	/*7492*/ uint16(xArgXmm1),
+	/*7493*/ uint16(xArgXmm2M128),
+	/*7494*/ uint16(xMatch),
+	/*7495*/ uint16(xCondPrefix), 2,
+	0x66, 7507,
+	0x0, 7501,
+	/*7501*/ uint16(xSetOp), uint16(PSRAW),
+	/*7503*/ uint16(xReadSlashR),
+	/*7504*/ uint16(xArgMm),
+	/*7505*/ uint16(xArgMmM64),
+	/*7506*/ uint16(xMatch),
+	/*7507*/ uint16(xSetOp), uint16(PSRAW),
+	/*7509*/ uint16(xReadSlashR),
+	/*7510*/ uint16(xArgXmm1),
+	/*7511*/ uint16(xArgXmm2M128),
+	/*7512*/ uint16(xMatch),
+	/*7513*/ uint16(xCondPrefix), 2,
+	0x66, 7525,
+	0x0, 7519,
+	/*7519*/ uint16(xSetOp), uint16(PSRAD),
+	/*7521*/ uint16(xReadSlashR),
+	/*7522*/ uint16(xArgMm),
+	/*7523*/ uint16(xArgMmM64),
+	/*7524*/ uint16(xMatch),
+	/*7525*/ uint16(xSetOp), uint16(PSRAD),
+	/*7527*/ uint16(xReadSlashR),
+	/*7528*/ uint16(xArgXmm1),
+	/*7529*/ uint16(xArgXmm2M128),
+	/*7530*/ uint16(xMatch),
+	/*7531*/ uint16(xCondPrefix), 2,
+	0x66, 7543,
+	0x0, 7537,
+	/*7537*/ uint16(xSetOp), uint16(PAVGW),
+	/*7539*/ uint16(xReadSlashR),
+	/*7540*/ uint16(xArgMm1),
+	/*7541*/ uint16(xArgMm2M64),
+	/*7542*/ uint16(xMatch),
+	/*7543*/ uint16(xSetOp), uint16(PAVGW),
+	/*7545*/ uint16(xReadSlashR),
+	/*7546*/ uint16(xArgXmm1),
+	/*7547*/ uint16(xArgXmm2M128),
+	/*7548*/ uint16(xMatch),
+	/*7549*/ uint16(xCondPrefix), 2,
+	0x66, 7561,
+	0x0, 7555,
+	/*7555*/ uint16(xSetOp), uint16(PMULHUW),
+	/*7557*/ uint16(xReadSlashR),
+	/*7558*/ uint16(xArgMm1),
+	/*7559*/ uint16(xArgMm2M64),
+	/*7560*/ uint16(xMatch),
+	/*7561*/ uint16(xSetOp), uint16(PMULHUW),
+	/*7563*/ uint16(xReadSlashR),
+	/*7564*/ uint16(xArgXmm1),
+	/*7565*/ uint16(xArgXmm2M128),
+	/*7566*/ uint16(xMatch),
+	/*7567*/ uint16(xCondPrefix), 2,
+	0x66, 7579,
+	0x0, 7573,
+	/*7573*/ uint16(xSetOp), uint16(PMULHW),
+	/*7575*/ uint16(xReadSlashR),
+	/*7576*/ uint16(xArgMm),
+	/*7577*/ uint16(xArgMmM64),
+	/*7578*/ uint16(xMatch),
+	/*7579*/ uint16(xSetOp), uint16(PMULHW),
+	/*7581*/ uint16(xReadSlashR),
+	/*7582*/ uint16(xArgXmm1),
+	/*7583*/ uint16(xArgXmm2M128),
+	/*7584*/ uint16(xMatch),
+	/*7585*/ uint16(xCondPrefix), 3,
+	0xF3, 7605,
+	0xF2, 7599,
+	0x66, 7593,
+	/*7593*/ uint16(xSetOp), uint16(CVTTPD2DQ),
+	/*7595*/ uint16(xReadSlashR),
+	/*7596*/ uint16(xArgXmm1),
+	/*7597*/ uint16(xArgXmm2M128),
+	/*7598*/ uint16(xMatch),
+	/*7599*/ uint16(xSetOp), uint16(CVTPD2DQ),
+	/*7601*/ uint16(xReadSlashR),
+	/*7602*/ uint16(xArgXmm1),
+	/*7603*/ uint16(xArgXmm2M128),
+	/*7604*/ uint16(xMatch),
+	/*7605*/ uint16(xSetOp), uint16(CVTDQ2PD),
+	/*7607*/ uint16(xReadSlashR),
+	/*7608*/ uint16(xArgXmm1),
+	/*7609*/ uint16(xArgXmm2M64),
+	/*7610*/ uint16(xMatch),
+	/*7611*/ uint16(xCondPrefix), 2,
+	0x66, 7623,
+	0x0, 7617,
+	/*7617*/ uint16(xSetOp), uint16(MOVNTQ),
+	/*7619*/ uint16(xReadSlashR),
+	/*7620*/ uint16(xArgM64),
+	/*7621*/ uint16(xArgMm),
+	/*7622*/ uint16(xMatch),
+	/*7623*/ uint16(xSetOp), uint16(MOVNTDQ),
+	/*7625*/ uint16(xReadSlashR),
+	/*7626*/ uint16(xArgM128),
+	/*7627*/ uint16(xArgXmm),
+	/*7628*/ uint16(xMatch),
+	/*7629*/ uint16(xCondPrefix), 2,
+	0x66, 7641,
+	0x0, 7635,
+	/*7635*/ uint16(xSetOp), uint16(PSUBSB),
+	/*7637*/ uint16(xReadSlashR),
+	/*7638*/ uint16(xArgMm),
+	/*7639*/ uint16(xArgMmM64),
+	/*7640*/ uint16(xMatch),
+	/*7641*/ uint16(xSetOp), uint16(PSUBSB),
+	/*7643*/ uint16(xReadSlashR),
+	/*7644*/ uint16(xArgXmm1),
+	/*7645*/ uint16(xArgXmm2M128),
+	/*7646*/ uint16(xMatch),
+	/*7647*/ uint16(xCondPrefix), 2,
+	0x66, 7659,
+	0x0, 7653,
+	/*7653*/ uint16(xSetOp), uint16(PSUBSW),
+	/*7655*/ uint16(xReadSlashR),
+	/*7656*/ uint16(xArgMm),
+	/*7657*/ uint16(xArgMmM64),
+	/*7658*/ uint16(xMatch),
+	/*7659*/ uint16(xSetOp), uint16(PSUBSW),
+	/*7661*/ uint16(xReadSlashR),
+	/*7662*/ uint16(xArgXmm1),
+	/*7663*/ uint16(xArgXmm2M128),
+	/*7664*/ uint16(xMatch),
+	/*7665*/ uint16(xCondPrefix), 2,
+	0x66, 7677,
+	0x0, 7671,
+	/*7671*/ uint16(xSetOp), uint16(PMINSW),
+	/*7673*/ uint16(xReadSlashR),
+	/*7674*/ uint16(xArgMm1),
+	/*7675*/ uint16(xArgMm2M64),
+	/*7676*/ uint16(xMatch),
+	/*7677*/ uint16(xSetOp), uint16(PMINSW),
+	/*7679*/ uint16(xReadSlashR),
+	/*7680*/ uint16(xArgXmm1),
+	/*7681*/ uint16(xArgXmm2M128),
+	/*7682*/ uint16(xMatch),
+	/*7683*/ uint16(xCondPrefix), 2,
+	0x66, 7695,
+	0x0, 7689,
+	/*7689*/ uint16(xSetOp), uint16(POR),
+	/*7691*/ uint16(xReadSlashR),
+	/*7692*/ uint16(xArgMm),
+	/*7693*/ uint16(xArgMmM64),
+	/*7694*/ uint16(xMatch),
+	/*7695*/ uint16(xSetOp), uint16(POR),
+	/*7697*/ uint16(xReadSlashR),
+	/*7698*/ uint16(xArgXmm1),
+	/*7699*/ uint16(xArgXmm2M128),
+	/*7700*/ uint16(xMatch),
+	/*7701*/ uint16(xCondPrefix), 2,
+	0x66, 7713,
+	0x0, 7707,
+	/*7707*/ uint16(xSetOp), uint16(PADDSB),
+	/*7709*/ uint16(xReadSlashR),
+	/*7710*/ uint16(xArgMm),
+	/*7711*/ uint16(xArgMmM64),
+	/*7712*/ uint16(xMatch),
+	/*7713*/ uint16(xSetOp), uint16(PADDSB),
+	/*7715*/ uint16(xReadSlashR),
+	/*7716*/ uint16(xArgXmm1),
+	/*7717*/ uint16(xArgXmm2M128),
+	/*7718*/ uint16(xMatch),
+	/*7719*/ uint16(xCondPrefix), 2,
+	0x66, 7731,
+	0x0, 7725,
+	/*7725*/ uint16(xSetOp), uint16(PADDSW),
+	/*7727*/ uint16(xReadSlashR),
+	/*7728*/ uint16(xArgMm),
+	/*7729*/ uint16(xArgMmM64),
+	/*7730*/ uint16(xMatch),
+	/*7731*/ uint16(xSetOp), uint16(PADDSW),
+	/*7733*/ uint16(xReadSlashR),
+	/*7734*/ uint16(xArgXmm1),
+	/*7735*/ uint16(xArgXmm2M128),
+	/*7736*/ uint16(xMatch),
+	/*7737*/ uint16(xCondPrefix), 2,
+	0x66, 7749,
+	0x0, 7743,
+	/*7743*/ uint16(xSetOp), uint16(PMAXSW),
+	/*7745*/ uint16(xReadSlashR),
+	/*7746*/ uint16(xArgMm1),
+	/*7747*/ uint16(xArgMm2M64),
+	/*7748*/ uint16(xMatch),
+	/*7749*/ uint16(xSetOp), uint16(PMAXSW),
+	/*7751*/ uint16(xReadSlashR),
+	/*7752*/ uint16(xArgXmm1),
+	/*7753*/ uint16(xArgXmm2M128),
+	/*7754*/ uint16(xMatch),
+	/*7755*/ uint16(xCondPrefix), 2,
+	0x66, 7767,
+	0x0, 7761,
+	/*7761*/ uint16(xSetOp), uint16(PXOR),
+	/*7763*/ uint16(xReadSlashR),
+	/*7764*/ uint16(xArgMm),
+	/*7765*/ uint16(xArgMmM64),
+	/*7766*/ uint16(xMatch),
+	/*7767*/ uint16(xSetOp), uint16(PXOR),
+	/*7769*/ uint16(xReadSlashR),
+	/*7770*/ uint16(xArgXmm1),
+	/*7771*/ uint16(xArgXmm2M128),
+	/*7772*/ uint16(xMatch),
+	/*7773*/ uint16(xCondPrefix), 1,
+	0xF2, 7777,
+	/*7777*/ uint16(xSetOp), uint16(LDDQU),
+	/*7779*/ uint16(xReadSlashR),
+	/*7780*/ uint16(xArgXmm1),
+	/*7781*/ uint16(xArgM128),
+	/*7782*/ uint16(xMatch),
+	/*7783*/ uint16(xCondPrefix), 2,
+	0x66, 7795,
+	0x0, 7789,
+	/*7789*/ uint16(xSetOp), uint16(PSLLW),
+	/*7791*/ uint16(xReadSlashR),
+	/*7792*/ uint16(xArgMm),
+	/*7793*/ uint16(xArgMmM64),
+	/*7794*/ uint16(xMatch),
+	/*7795*/ uint16(xSetOp), uint16(PSLLW),
+	/*7797*/ uint16(xReadSlashR),
+	/*7798*/ uint16(xArgXmm1),
+	/*7799*/ uint16(xArgXmm2M128),
+	/*7800*/ uint16(xMatch),
+	/*7801*/ uint16(xCondPrefix), 2,
+	0x66, 7813,
+	0x0, 7807,
+	/*7807*/ uint16(xSetOp), uint16(PSLLD),
+	/*7809*/ uint16(xReadSlashR),
+	/*7810*/ uint16(xArgMm),
+	/*7811*/ uint16(xArgMmM64),
+	/*7812*/ uint16(xMatch),
+	/*7813*/ uint16(xSetOp), uint16(PSLLD),
+	/*7815*/ uint16(xReadSlashR),
+	/*7816*/ uint16(xArgXmm1),
+	/*7817*/ uint16(xArgXmm2M128),
+	/*7818*/ uint16(xMatch),
+	/*7819*/ uint16(xCondPrefix), 2,
+	0x66, 7831,
+	0x0, 7825,
+	/*7825*/ uint16(xSetOp), uint16(PSLLQ),
+	/*7827*/ uint16(xReadSlashR),
+	/*7828*/ uint16(xArgMm),
+	/*7829*/ uint16(xArgMmM64),
+	/*7830*/ uint16(xMatch),
+	/*7831*/ uint16(xSetOp), uint16(PSLLQ),
+	/*7833*/ uint16(xReadSlashR),
+	/*7834*/ uint16(xArgXmm1),
+	/*7835*/ uint16(xArgXmm2M128),
+	/*7836*/ uint16(xMatch),
+	/*7837*/ uint16(xCondPrefix), 2,
+	0x66, 7849,
+	0x0, 7843,
+	/*7843*/ uint16(xSetOp), uint16(PMULUDQ),
+	/*7845*/ uint16(xReadSlashR),
+	/*7846*/ uint16(xArgMm1),
+	/*7847*/ uint16(xArgMm2M64),
+	/*7848*/ uint16(xMatch),
+	/*7849*/ uint16(xSetOp), uint16(PMULUDQ),
+	/*7851*/ uint16(xReadSlashR),
+	/*7852*/ uint16(xArgXmm1),
+	/*7853*/ uint16(xArgXmm2M128),
+	/*7854*/ uint16(xMatch),
+	/*7855*/ uint16(xCondPrefix), 2,
+	0x66, 7867,
+	0x0, 7861,
+	/*7861*/ uint16(xSetOp), uint16(PMADDWD),
+	/*7863*/ uint16(xReadSlashR),
+	/*7864*/ uint16(xArgMm),
+	/*7865*/ uint16(xArgMmM64),
+	/*7866*/ uint16(xMatch),
+	/*7867*/ uint16(xSetOp), uint16(PMADDWD),
+	/*7869*/ uint16(xReadSlashR),
+	/*7870*/ uint16(xArgXmm1),
+	/*7871*/ uint16(xArgXmm2M128),
+	/*7872*/ uint16(xMatch),
+	/*7873*/ uint16(xCondPrefix), 2,
+	0x66, 7885,
+	0x0, 7879,
+	/*7879*/ uint16(xSetOp), uint16(PSADBW),
+	/*7881*/ uint16(xReadSlashR),
+	/*7882*/ uint16(xArgMm1),
+	/*7883*/ uint16(xArgMm2M64),
+	/*7884*/ uint16(xMatch),
+	/*7885*/ uint16(xSetOp), uint16(PSADBW),
+	/*7887*/ uint16(xReadSlashR),
+	/*7888*/ uint16(xArgXmm1),
+	/*7889*/ uint16(xArgXmm2M128),
+	/*7890*/ uint16(xMatch),
+	/*7891*/ uint16(xCondPrefix), 2,
+	0x66, 7903,
+	0x0, 7897,
+	/*7897*/ uint16(xSetOp), uint16(MASKMOVQ),
+	/*7899*/ uint16(xReadSlashR),
+	/*7900*/ uint16(xArgMm1),
+	/*7901*/ uint16(xArgMm2),
+	/*7902*/ uint16(xMatch),
+	/*7903*/ uint16(xSetOp), uint16(MASKMOVDQU),
+	/*7905*/ uint16(xReadSlashR),
+	/*7906*/ uint16(xArgXmm1),
+	/*7907*/ uint16(xArgXmm2),
+	/*7908*/ uint16(xMatch),
+	/*7909*/ uint16(xCondPrefix), 2,
+	0x66, 7921,
+	0x0, 7915,
+	/*7915*/ uint16(xSetOp), uint16(PSUBB),
+	/*7917*/ uint16(xReadSlashR),
+	/*7918*/ uint16(xArgMm),
+	/*7919*/ uint16(xArgMmM64),
+	/*7920*/ uint16(xMatch),
+	/*7921*/ uint16(xSetOp), uint16(PSUBB),
+	/*7923*/ uint16(xReadSlashR),
+	/*7924*/ uint16(xArgXmm1),
+	/*7925*/ uint16(xArgXmm2M128),
+	/*7926*/ uint16(xMatch),
+	/*7927*/ uint16(xCondPrefix), 2,
+	0x66, 7939,
+	0x0, 7933,
+	/*7933*/ uint16(xSetOp), uint16(PSUBW),
+	/*7935*/ uint16(xReadSlashR),
+	/*7936*/ uint16(xArgMm),
+	/*7937*/ uint16(xArgMmM64),
+	/*7938*/ uint16(xMatch),
+	/*7939*/ uint16(xSetOp), uint16(PSUBW),
+	/*7941*/ uint16(xReadSlashR),
+	/*7942*/ uint16(xArgXmm1),
+	/*7943*/ uint16(xArgXmm2M128),
+	/*7944*/ uint16(xMatch),
+	/*7945*/ uint16(xCondPrefix), 2,
+	0x66, 7957,
+	0x0, 7951,
+	/*7951*/ uint16(xSetOp), uint16(PSUBD),
+	/*7953*/ uint16(xReadSlashR),
+	/*7954*/ uint16(xArgMm),
+	/*7955*/ uint16(xArgMmM64),
+	/*7956*/ uint16(xMatch),
+	/*7957*/ uint16(xSetOp), uint16(PSUBD),
+	/*7959*/ uint16(xReadSlashR),
+	/*7960*/ uint16(xArgXmm1),
+	/*7961*/ uint16(xArgXmm2M128),
+	/*7962*/ uint16(xMatch),
+	/*7963*/ uint16(xCondPrefix), 2,
+	0x66, 7975,
+	0x0, 7969,
+	/*7969*/ uint16(xSetOp), uint16(PSUBQ),
+	/*7971*/ uint16(xReadSlashR),
+	/*7972*/ uint16(xArgMm1),
+	/*7973*/ uint16(xArgMm2M64),
+	/*7974*/ uint16(xMatch),
+	/*7975*/ uint16(xSetOp), uint16(PSUBQ),
+	/*7977*/ uint16(xReadSlashR),
+	/*7978*/ uint16(xArgXmm1),
+	/*7979*/ uint16(xArgXmm2M128),
+	/*7980*/ uint16(xMatch),
+	/*7981*/ uint16(xCondPrefix), 2,
+	0x66, 7993,
+	0x0, 7987,
+	/*7987*/ uint16(xSetOp), uint16(PADDB),
+	/*7989*/ uint16(xReadSlashR),
+	/*7990*/ uint16(xArgMm),
+	/*7991*/ uint16(xArgMmM64),
+	/*7992*/ uint16(xMatch),
+	/*7993*/ uint16(xSetOp), uint16(PADDB),
+	/*7995*/ uint16(xReadSlashR),
+	/*7996*/ uint16(xArgXmm1),
+	/*7997*/ uint16(xArgXmm2M128),
+	/*7998*/ uint16(xMatch),
+	/*7999*/ uint16(xCondPrefix), 2,
+	0x66, 8011,
+	0x0, 8005,
+	/*8005*/ uint16(xSetOp), uint16(PADDW),
+	/*8007*/ uint16(xReadSlashR),
+	/*8008*/ uint16(xArgMm),
+	/*8009*/ uint16(xArgMmM64),
+	/*8010*/ uint16(xMatch),
+	/*8011*/ uint16(xSetOp), uint16(PADDW),
+	/*8013*/ uint16(xReadSlashR),
+	/*8014*/ uint16(xArgXmm1),
+	/*8015*/ uint16(xArgXmm2M128),
+	/*8016*/ uint16(xMatch),
+	/*8017*/ uint16(xCondPrefix), 2,
+	0x66, 8029,
+	0x0, 8023,
+	/*8023*/ uint16(xSetOp), uint16(PADDD),
+	/*8025*/ uint16(xReadSlashR),
+	/*8026*/ uint16(xArgMm),
+	/*8027*/ uint16(xArgMmM64),
+	/*8028*/ uint16(xMatch),
+	/*8029*/ uint16(xSetOp), uint16(PADDD),
+	/*8031*/ uint16(xReadSlashR),
+	/*8032*/ uint16(xArgXmm1),
+	/*8033*/ uint16(xArgXmm2M128),
+	/*8034*/ uint16(xMatch),
+	/*8035*/ uint16(xCondDataSize), 0, 8039, 0,
+	/*8039*/ uint16(xSetOp), uint16(UD0),
 	/*8041*/ uint16(xReadSlashR),
-	/*8042*/ uint16(xArgRM16),
-	/*8043*/ uint16(xArgR16),
+	/*8042*/ uint16(xArgR32),
+	/*8043*/ uint16(xArgRM32),
 	/*8044*/ uint16(xMatch),
 	/*8045*/ uint16(xSetOp), uint16(ADC),
 	/*8047*/ uint16(xReadSlashR),
-	/*8048*/ uint16(xArgRM32),
-	/*8049*/ uint16(xArgR32),
+	/*8048*/ uint16(xArgRM8),
+	/*8049*/ uint16(xArgR8),
 	/*8050*/ uint16(xMatch),
-	/*8051*/ uint16(xCondDataSize), 8039, 8045, 8055,
-	/*8055*/ uint16(xSetOp), uint16(ADC),
-	/*8057*/ uint16(xReadSlashR),
-	/*8058*/ uint16(xArgRM64),
-	/*8059*/ uint16(xArgR64),
-	/*8060*/ uint16(xMatch),
-	/*8061*/ uint16(xSetOp), uint16(ADC),
-	/*8063*/ uint16(xReadSlashR),
-	/*8064*/ uint16(xArgR8),
-	/*8065*/ uint16(xArgRM8),
-	/*8066*/ uint16(xMatch),
-	/*8067*/ uint16(xCondIs64), 8070, 8086,
-	/*8070*/ uint16(xCondDataSize), 8074, 8080, 0,
+	/*8051*/ uint16(xCondIs64), 8054, 8070,
+	/*8054*/ uint16(xCondDataSize), 8058, 8064, 0,
+	/*8058*/ uint16(xSetOp), uint16(ADC),
+	/*8060*/ uint16(xReadSlashR),
+	/*8061*/ uint16(xArgRM16),
+	/*8062*/ uint16(xArgR16),
+	/*8063*/ uint16(xMatch),
+	/*8064*/ uint16(xSetOp), uint16(ADC),
+	/*8066*/ uint16(xReadSlashR),
+	/*8067*/ uint16(xArgRM32),
+	/*8068*/ uint16(xArgR32),
+	/*8069*/ uint16(xMatch),
+	/*8070*/ uint16(xCondDataSize), 8058, 8064, 8074,
 	/*8074*/ uint16(xSetOp), uint16(ADC),
 	/*8076*/ uint16(xReadSlashR),
-	/*8077*/ uint16(xArgR16),
-	/*8078*/ uint16(xArgRM16),
+	/*8077*/ uint16(xArgRM64),
+	/*8078*/ uint16(xArgR64),
 	/*8079*/ uint16(xMatch),
 	/*8080*/ uint16(xSetOp), uint16(ADC),
 	/*8082*/ uint16(xReadSlashR),
-	/*8083*/ uint16(xArgR32),
-	/*8084*/ uint16(xArgRM32),
+	/*8083*/ uint16(xArgR8),
+	/*8084*/ uint16(xArgRM8),
 	/*8085*/ uint16(xMatch),
-	/*8086*/ uint16(xCondDataSize), 8074, 8080, 8090,
-	/*8090*/ uint16(xSetOp), uint16(ADC),
-	/*8092*/ uint16(xReadSlashR),
-	/*8093*/ uint16(xArgR64),
-	/*8094*/ uint16(xArgRM64),
-	/*8095*/ uint16(xMatch),
-	/*8096*/ uint16(xSetOp), uint16(ADC),
-	/*8098*/ uint16(xReadIb),
-	/*8099*/ uint16(xArgAL),
-	/*8100*/ uint16(xArgImm8u),
-	/*8101*/ uint16(xMatch),
-	/*8102*/ uint16(xCondIs64), 8105, 8121,
-	/*8105*/ uint16(xCondDataSize), 8109, 8115, 0,
+	/*8086*/ uint16(xCondIs64), 8089, 8105,
+	/*8089*/ uint16(xCondDataSize), 8093, 8099, 0,
+	/*8093*/ uint16(xSetOp), uint16(ADC),
+	/*8095*/ uint16(xReadSlashR),
+	/*8096*/ uint16(xArgR16),
+	/*8097*/ uint16(xArgRM16),
+	/*8098*/ uint16(xMatch),
+	/*8099*/ uint16(xSetOp), uint16(ADC),
+	/*8101*/ uint16(xReadSlashR),
+	/*8102*/ uint16(xArgR32),
+	/*8103*/ uint16(xArgRM32),
+	/*8104*/ uint16(xMatch),
+	/*8105*/ uint16(xCondDataSize), 8093, 8099, 8109,
 	/*8109*/ uint16(xSetOp), uint16(ADC),
-	/*8111*/ uint16(xReadIw),
-	/*8112*/ uint16(xArgAX),
-	/*8113*/ uint16(xArgImm16),
+	/*8111*/ uint16(xReadSlashR),
+	/*8112*/ uint16(xArgR64),
+	/*8113*/ uint16(xArgRM64),
 	/*8114*/ uint16(xMatch),
 	/*8115*/ uint16(xSetOp), uint16(ADC),
-	/*8117*/ uint16(xReadId),
-	/*8118*/ uint16(xArgEAX),
-	/*8119*/ uint16(xArgImm32),
+	/*8117*/ uint16(xReadIb),
+	/*8118*/ uint16(xArgAL),
+	/*8119*/ uint16(xArgImm8u),
 	/*8120*/ uint16(xMatch),
-	/*8121*/ uint16(xCondDataSize), 8109, 8115, 8125,
-	/*8125*/ uint16(xSetOp), uint16(ADC),
-	/*8127*/ uint16(xReadId),
-	/*8128*/ uint16(xArgRAX),
-	/*8129*/ uint16(xArgImm32),
-	/*8130*/ uint16(xMatch),
-	/*8131*/ uint16(xCondIs64), 8134, 0,
-	/*8134*/ uint16(xSetOp), uint16(PUSH),
-	/*8136*/ uint16(xArgSS),
-	/*8137*/ uint16(xMatch),
-	/*8138*/ uint16(xCondIs64), 8141, 0,
-	/*8141*/ uint16(xSetOp), uint16(POP),
-	/*8143*/ uint16(xArgSS),
-	/*8144*/ uint16(xMatch),
-	/*8145*/ uint16(xSetOp), uint16(SBB),
-	/*8147*/ uint16(xReadSlashR),
-	/*8148*/ uint16(xArgRM8),
-	/*8149*/ uint16(xArgR8),
-	/*8150*/ uint16(xMatch),
-	/*8151*/ uint16(xCondIs64), 8154, 8170,
-	/*8154*/ uint16(xCondDataSize), 8158, 8164, 0,
-	/*8158*/ uint16(xSetOp), uint16(SBB),
-	/*8160*/ uint16(xReadSlashR),
-	/*8161*/ uint16(xArgRM16),
-	/*8162*/ uint16(xArgR16),
+	/*8121*/ uint16(xCondIs64), 8124, 8140,
+	/*8124*/ uint16(xCondDataSize), 8128, 8134, 0,
+	/*8128*/ uint16(xSetOp), uint16(ADC),
+	/*8130*/ uint16(xReadIw),
+	/*8131*/ uint16(xArgAX),
+	/*8132*/ uint16(xArgImm16),
+	/*8133*/ uint16(xMatch),
+	/*8134*/ uint16(xSetOp), uint16(ADC),
+	/*8136*/ uint16(xReadId),
+	/*8137*/ uint16(xArgEAX),
+	/*8138*/ uint16(xArgImm32),
+	/*8139*/ uint16(xMatch),
+	/*8140*/ uint16(xCondDataSize), 8128, 8134, 8144,
+	/*8144*/ uint16(xSetOp), uint16(ADC),
+	/*8146*/ uint16(xReadId),
+	/*8147*/ uint16(xArgRAX),
+	/*8148*/ uint16(xArgImm32),
+	/*8149*/ uint16(xMatch),
+	/*8150*/ uint16(xCondIs64), 8153, 0,
+	/*8153*/ uint16(xSetOp), uint16(PUSH),
+	/*8155*/ uint16(xArgSS),
+	/*8156*/ uint16(xMatch),
+	/*8157*/ uint16(xCondIs64), 8160, 0,
+	/*8160*/ uint16(xSetOp), uint16(POP),
+	/*8162*/ uint16(xArgSS),
 	/*8163*/ uint16(xMatch),
 	/*8164*/ uint16(xSetOp), uint16(SBB),
 	/*8166*/ uint16(xReadSlashR),
-	/*8167*/ uint16(xArgRM32),
-	/*8168*/ uint16(xArgR32),
+	/*8167*/ uint16(xArgRM8),
+	/*8168*/ uint16(xArgR8),
 	/*8169*/ uint16(xMatch),
-	/*8170*/ uint16(xCondDataSize), 8158, 8164, 8174,
-	/*8174*/ uint16(xSetOp), uint16(SBB),
-	/*8176*/ uint16(xReadSlashR),
-	/*8177*/ uint16(xArgRM64),
-	/*8178*/ uint16(xArgR64),
-	/*8179*/ uint16(xMatch),
-	/*8180*/ uint16(xSetOp), uint16(SBB),
-	/*8182*/ uint16(xReadSlashR),
-	/*8183*/ uint16(xArgR8),
-	/*8184*/ uint16(xArgRM8),
-	/*8185*/ uint16(xMatch),
-	/*8186*/ uint16(xCondIs64), 8189, 8205,
-	/*8189*/ uint16(xCondDataSize), 8193, 8199, 0,
+	/*8170*/ uint16(xCondIs64), 8173, 8189,
+	/*8173*/ uint16(xCondDataSize), 8177, 8183, 0,
+	/*8177*/ uint16(xSetOp), uint16(SBB),
+	/*8179*/ uint16(xReadSlashR),
+	/*8180*/ uint16(xArgRM16),
+	/*8181*/ uint16(xArgR16),
+	/*8182*/ uint16(xMatch),
+	/*8183*/ uint16(xSetOp), uint16(SBB),
+	/*8185*/ uint16(xReadSlashR),
+	/*8186*/ uint16(xArgRM32),
+	/*8187*/ uint16(xArgR32),
+	/*8188*/ uint16(xMatch),
+	/*8189*/ uint16(xCondDataSize), 8177, 8183, 8193,
 	/*8193*/ uint16(xSetOp), uint16(SBB),
 	/*8195*/ uint16(xReadSlashR),
-	/*8196*/ uint16(xArgR16),
-	/*8197*/ uint16(xArgRM16),
+	/*8196*/ uint16(xArgRM64),
+	/*8197*/ uint16(xArgR64),
 	/*8198*/ uint16(xMatch),
 	/*8199*/ uint16(xSetOp), uint16(SBB),
 	/*8201*/ uint16(xReadSlashR),
-	/*8202*/ uint16(xArgR32),
-	/*8203*/ uint16(xArgRM32),
+	/*8202*/ uint16(xArgR8),
+	/*8203*/ uint16(xArgRM8),
 	/*8204*/ uint16(xMatch),
-	/*8205*/ uint16(xCondDataSize), 8193, 8199, 8209,
-	/*8209*/ uint16(xSetOp), uint16(SBB),
-	/*8211*/ uint16(xReadSlashR),
-	/*8212*/ uint16(xArgR64),
-	/*8213*/ uint16(xArgRM64),
-	/*8214*/ uint16(xMatch),
-	/*8215*/ uint16(xSetOp), uint16(SBB),
-	/*8217*/ uint16(xReadIb),
-	/*8218*/ uint16(xArgAL),
-	/*8219*/ uint16(xArgImm8u),
-	/*8220*/ uint16(xMatch),
-	/*8221*/ uint16(xCondIs64), 8224, 8240,
-	/*8224*/ uint16(xCondDataSize), 8228, 8234, 0,
+	/*8205*/ uint16(xCondIs64), 8208, 8224,
+	/*8208*/ uint16(xCondDataSize), 8212, 8218, 0,
+	/*8212*/ uint16(xSetOp), uint16(SBB),
+	/*8214*/ uint16(xReadSlashR),
+	/*8215*/ uint16(xArgR16),
+	/*8216*/ uint16(xArgRM16),
+	/*8217*/ uint16(xMatch),
+	/*8218*/ uint16(xSetOp), uint16(SBB),
+	/*8220*/ uint16(xReadSlashR),
+	/*8221*/ uint16(xArgR32),
+	/*8222*/ uint16(xArgRM32),
+	/*8223*/ uint16(xMatch),
+	/*8224*/ uint16(xCondDataSize), 8212, 8218, 8228,
 	/*8228*/ uint16(xSetOp), uint16(SBB),
-	/*8230*/ uint16(xReadIw),
-	/*8231*/ uint16(xArgAX),
-	/*8232*/ uint16(xArgImm16),
+	/*8230*/ uint16(xReadSlashR),
+	/*8231*/ uint16(xArgR64),
+	/*8232*/ uint16(xArgRM64),
 	/*8233*/ uint16(xMatch),
 	/*8234*/ uint16(xSetOp), uint16(SBB),
-	/*8236*/ uint16(xReadId),
-	/*8237*/ uint16(xArgEAX),
-	/*8238*/ uint16(xArgImm32),
+	/*8236*/ uint16(xReadIb),
+	/*8237*/ uint16(xArgAL),
+	/*8238*/ uint16(xArgImm8u),
 	/*8239*/ uint16(xMatch),
-	/*8240*/ uint16(xCondDataSize), 8228, 8234, 8244,
-	/*8244*/ uint16(xSetOp), uint16(SBB),
-	/*8246*/ uint16(xReadId),
-	/*8247*/ uint16(xArgRAX),
-	/*8248*/ uint16(xArgImm32),
-	/*8249*/ uint16(xMatch),
-	/*8250*/ uint16(xCondIs64), 8253, 0,
-	/*8253*/ uint16(xSetOp), uint16(PUSH),
-	/*8255*/ uint16(xArgDS),
-	/*8256*/ uint16(xMatch),
-	/*8257*/ uint16(xCondIs64), 8260, 0,
-	/*8260*/ uint16(xSetOp), uint16(POP),
-	/*8262*/ uint16(xArgDS),
-	/*8263*/ uint16(xMatch),
-	/*8264*/ uint16(xSetOp), uint16(AND),
-	/*8266*/ uint16(xReadSlashR),
-	/*8267*/ uint16(xArgRM8),
-	/*8268*/ uint16(xArgR8),
-	/*8269*/ uint16(xMatch),
-	/*8270*/ uint16(xCondIs64), 8273, 8289,
-	/*8273*/ uint16(xCondDataSize), 8277, 8283, 0,
-	/*8277*/ uint16(xSetOp), uint16(AND),
-	/*8279*/ uint16(xReadSlashR),
-	/*8280*/ uint16(xArgRM16),
-	/*8281*/ uint16(xArgR16),
+	/*8240*/ uint16(xCondIs64), 8243, 8259,
+	/*8243*/ uint16(xCondDataSize), 8247, 8253, 0,
+	/*8247*/ uint16(xSetOp), uint16(SBB),
+	/*8249*/ uint16(xReadIw),
+	/*8250*/ uint16(xArgAX),
+	/*8251*/ uint16(xArgImm16),
+	/*8252*/ uint16(xMatch),
+	/*8253*/ uint16(xSetOp), uint16(SBB),
+	/*8255*/ uint16(xReadId),
+	/*8256*/ uint16(xArgEAX),
+	/*8257*/ uint16(xArgImm32),
+	/*8258*/ uint16(xMatch),
+	/*8259*/ uint16(xCondDataSize), 8247, 8253, 8263,
+	/*8263*/ uint16(xSetOp), uint16(SBB),
+	/*8265*/ uint16(xReadId),
+	/*8266*/ uint16(xArgRAX),
+	/*8267*/ uint16(xArgImm32),
+	/*8268*/ uint16(xMatch),
+	/*8269*/ uint16(xCondIs64), 8272, 0,
+	/*8272*/ uint16(xSetOp), uint16(PUSH),
+	/*8274*/ uint16(xArgDS),
+	/*8275*/ uint16(xMatch),
+	/*8276*/ uint16(xCondIs64), 8279, 0,
+	/*8279*/ uint16(xSetOp), uint16(POP),
+	/*8281*/ uint16(xArgDS),
 	/*8282*/ uint16(xMatch),
 	/*8283*/ uint16(xSetOp), uint16(AND),
 	/*8285*/ uint16(xReadSlashR),
-	/*8286*/ uint16(xArgRM32),
-	/*8287*/ uint16(xArgR32),
+	/*8286*/ uint16(xArgRM8),
+	/*8287*/ uint16(xArgR8),
 	/*8288*/ uint16(xMatch),
-	/*8289*/ uint16(xCondDataSize), 8277, 8283, 8293,
-	/*8293*/ uint16(xSetOp), uint16(AND),
-	/*8295*/ uint16(xReadSlashR),
-	/*8296*/ uint16(xArgRM64),
-	/*8297*/ uint16(xArgR64),
-	/*8298*/ uint16(xMatch),
-	/*8299*/ uint16(xSetOp), uint16(AND),
-	/*8301*/ uint16(xReadSlashR),
-	/*8302*/ uint16(xArgR8),
-	/*8303*/ uint16(xArgRM8),
-	/*8304*/ uint16(xMatch),
-	/*8305*/ uint16(xCondIs64), 8308, 8324,
-	/*8308*/ uint16(xCondDataSize), 8312, 8318, 0,
+	/*8289*/ uint16(xCondIs64), 8292, 8308,
+	/*8292*/ uint16(xCondDataSize), 8296, 8302, 0,
+	/*8296*/ uint16(xSetOp), uint16(AND),
+	/*8298*/ uint16(xReadSlashR),
+	/*8299*/ uint16(xArgRM16),
+	/*8300*/ uint16(xArgR16),
+	/*8301*/ uint16(xMatch),
+	/*8302*/ uint16(xSetOp), uint16(AND),
+	/*8304*/ uint16(xReadSlashR),
+	/*8305*/ uint16(xArgRM32),
+	/*8306*/ uint16(xArgR32),
+	/*8307*/ uint16(xMatch),
+	/*8308*/ uint16(xCondDataSize), 8296, 8302, 8312,
 	/*8312*/ uint16(xSetOp), uint16(AND),
 	/*8314*/ uint16(xReadSlashR),
-	/*8315*/ uint16(xArgR16),
-	/*8316*/ uint16(xArgRM16),
+	/*8315*/ uint16(xArgRM64),
+	/*8316*/ uint16(xArgR64),
 	/*8317*/ uint16(xMatch),
 	/*8318*/ uint16(xSetOp), uint16(AND),
 	/*8320*/ uint16(xReadSlashR),
-	/*8321*/ uint16(xArgR32),
-	/*8322*/ uint16(xArgRM32),
+	/*8321*/ uint16(xArgR8),
+	/*8322*/ uint16(xArgRM8),
 	/*8323*/ uint16(xMatch),
-	/*8324*/ uint16(xCondDataSize), 8312, 8318, 8328,
-	/*8328*/ uint16(xSetOp), uint16(AND),
-	/*8330*/ uint16(xReadSlashR),
-	/*8331*/ uint16(xArgR64),
-	/*8332*/ uint16(xArgRM64),
-	/*8333*/ uint16(xMatch),
-	/*8334*/ uint16(xSetOp), uint16(AND),
-	/*8336*/ uint16(xReadIb),
-	/*8337*/ uint16(xArgAL),
-	/*8338*/ uint16(xArgImm8u),
-	/*8339*/ uint16(xMatch),
-	/*8340*/ uint16(xCondIs64), 8343, 8359,
-	/*8343*/ uint16(xCondDataSize), 8347, 8353, 0,
+	/*8324*/ uint16(xCondIs64), 8327, 8343,
+	/*8327*/ uint16(xCondDataSize), 8331, 8337, 0,
+	/*8331*/ uint16(xSetOp), uint16(AND),
+	/*8333*/ uint16(xReadSlashR),
+	/*8334*/ uint16(xArgR16),
+	/*8335*/ uint16(xArgRM16),
+	/*8336*/ uint16(xMatch),
+	/*8337*/ uint16(xSetOp), uint16(AND),
+	/*8339*/ uint16(xReadSlashR),
+	/*8340*/ uint16(xArgR32),
+	/*8341*/ uint16(xArgRM32),
+	/*8342*/ uint16(xMatch),
+	/*8343*/ uint16(xCondDataSize), 8331, 8337, 8347,
 	/*8347*/ uint16(xSetOp), uint16(AND),
-	/*8349*/ uint16(xReadIw),
-	/*8350*/ uint16(xArgAX),
-	/*8351*/ uint16(xArgImm16),
+	/*8349*/ uint16(xReadSlashR),
+	/*8350*/ uint16(xArgR64),
+	/*8351*/ uint16(xArgRM64),
 	/*8352*/ uint16(xMatch),
 	/*8353*/ uint16(xSetOp), uint16(AND),
-	/*8355*/ uint16(xReadId),
-	/*8356*/ uint16(xArgEAX),
-	/*8357*/ uint16(xArgImm32),
+	/*8355*/ uint16(xReadIb),
+	/*8356*/ uint16(xArgAL),
+	/*8357*/ uint16(xArgImm8u),
 	/*8358*/ uint16(xMatch),
-	/*8359*/ uint16(xCondDataSize), 8347, 8353, 8363,
-	/*8363*/ uint16(xSetOp), uint16(AND),
-	/*8365*/ uint16(xReadId),
-	/*8366*/ uint16(xArgRAX),
-	/*8367*/ uint16(xArgImm32),
-	/*8368*/ uint16(xMatch),
-	/*8369*/ uint16(xCondIs64), 8372, 0,
-	/*8372*/ uint16(xSetOp), uint16(DAA),
-	/*8374*/ uint16(xMatch),
-	/*8375*/ uint16(xSetOp), uint16(SUB),
-	/*8377*/ uint16(xReadSlashR),
-	/*8378*/ uint16(xArgRM8),
-	/*8379*/ uint16(xArgR8),
-	/*8380*/ uint16(xMatch),
-	/*8381*/ uint16(xCondIs64), 8384, 8400,
-	/*8384*/ uint16(xCondDataSize), 8388, 8394, 0,
-	/*8388*/ uint16(xSetOp), uint16(SUB),
-	/*8390*/ uint16(xReadSlashR),
-	/*8391*/ uint16(xArgRM16),
-	/*8392*/ uint16(xArgR16),
+	/*8359*/ uint16(xCondIs64), 8362, 8378,
+	/*8362*/ uint16(xCondDataSize), 8366, 8372, 0,
+	/*8366*/ uint16(xSetOp), uint16(AND),
+	/*8368*/ uint16(xReadIw),
+	/*8369*/ uint16(xArgAX),
+	/*8370*/ uint16(xArgImm16),
+	/*8371*/ uint16(xMatch),
+	/*8372*/ uint16(xSetOp), uint16(AND),
+	/*8374*/ uint16(xReadId),
+	/*8375*/ uint16(xArgEAX),
+	/*8376*/ uint16(xArgImm32),
+	/*8377*/ uint16(xMatch),
+	/*8378*/ uint16(xCondDataSize), 8366, 8372, 8382,
+	/*8382*/ uint16(xSetOp), uint16(AND),
+	/*8384*/ uint16(xReadId),
+	/*8385*/ uint16(xArgRAX),
+	/*8386*/ uint16(xArgImm32),
+	/*8387*/ uint16(xMatch),
+	/*8388*/ uint16(xCondIs64), 8391, 0,
+	/*8391*/ uint16(xSetOp), uint16(DAA),
 	/*8393*/ uint16(xMatch),
 	/*8394*/ uint16(xSetOp), uint16(SUB),
 	/*8396*/ uint16(xReadSlashR),
-	/*8397*/ uint16(xArgRM32),
-	/*8398*/ uint16(xArgR32),
+	/*8397*/ uint16(xArgRM8),
+	/*8398*/ uint16(xArgR8),
 	/*8399*/ uint16(xMatch),
-	/*8400*/ uint16(xCondDataSize), 8388, 8394, 8404,
-	/*8404*/ uint16(xSetOp), uint16(SUB),
-	/*8406*/ uint16(xReadSlashR),
-	/*8407*/ uint16(xArgRM64),
-	/*8408*/ uint16(xArgR64),
-	/*8409*/ uint16(xMatch),
-	/*8410*/ uint16(xCondPrefix), 3,
-	0xC5, 8438,
-	0xC4, 8424,
-	0x0, 8418,
-	/*8418*/ uint16(xSetOp), uint16(SUB),
-	/*8420*/ uint16(xReadSlashR),
-	/*8421*/ uint16(xArgR8),
-	/*8422*/ uint16(xArgRM8),
-	/*8423*/ uint16(xMatch),
-	/*8424*/ uint16(xCondPrefix), 1,
-	0x66, 8428,
-	/*8428*/ uint16(xCondPrefix), 1,
-	0x0F38, 8432,
-	/*8432*/ uint16(xSetOp), uint16(VMOVNTDQA),
-	/*8434*/ uint16(xReadSlashR),
-	/*8435*/ uint16(xArgYmm1),
-	/*8436*/ uint16(xArgM256),
-	/*8437*/ uint16(xMatch),
-	/*8438*/ uint16(xCondPrefix), 1,
-	0x66, 8442,
-	/*8442*/ uint16(xCondPrefix), 1,
-	0x0F38, 8446,
-	/*8446*/ uint16(xSetOp), uint16(VMOVNTDQA),
-	/*8448*/ uint16(xReadSlashR),
-	/*8449*/ uint16(xArgYmm1),
-	/*8450*/ uint16(xArgM256),
-	/*8451*/ uint16(xMatch),
-	/*8452*/ uint16(xCondIs64), 8455, 8471,
-	/*8455*/ uint16(xCondDataSize), 8459, 8465, 0,
-	/*8459*/ uint16(xSetOp), uint16(SUB),
-	/*8461*/ uint16(xReadSlashR),
-	/*8462*/ uint16(xArgR16),
-	/*8463*/ uint16(xArgRM16),
-	/*8464*/ uint16(xMatch),
-	/*8465*/ uint16(xSetOp), uint16(SUB),
+	/*8400*/ uint16(xCondIs64), 8403, 8419,
+	/*8403*/ uint16(xCondDataSize), 8407, 8413, 0,
+	/*8407*/ uint16(xSetOp), uint16(SUB),
+	/*8409*/ uint16(xReadSlashR),
+	/*8410*/ uint16(xArgRM16),
+	/*8411*/ uint16(xArgR16),
+	/*8412*/ uint16(xMatch),
+	/*8413*/ uint16(xSetOp), uint16(SUB),
+	/*8415*/ uint16(xReadSlashR),
+	/*8416*/ uint16(xArgRM32),
+	/*8417*/ uint16(xArgR32),
+	/*8418*/ uint16(xMatch),
+	/*8419*/ uint16(xCondDataSize), 8407, 8413, 8423,
+	/*8423*/ uint16(xSetOp), uint16(SUB),
+	/*8425*/ uint16(xReadSlashR),
+	/*8426*/ uint16(xArgRM64),
+	/*8427*/ uint16(xArgR64),
+	/*8428*/ uint16(xMatch),
+	/*8429*/ uint16(xCondPrefix), 3,
+	0xC5, 8457,
+	0xC4, 8443,
+	0x0, 8437,
+	/*8437*/ uint16(xSetOp), uint16(SUB),
+	/*8439*/ uint16(xReadSlashR),
+	/*8440*/ uint16(xArgR8),
+	/*8441*/ uint16(xArgRM8),
+	/*8442*/ uint16(xMatch),
+	/*8443*/ uint16(xCondPrefix), 1,
+	0x66, 8447,
+	/*8447*/ uint16(xCondPrefix), 1,
+	0x0F38, 8451,
+	/*8451*/ uint16(xSetOp), uint16(VMOVNTDQA),
+	/*8453*/ uint16(xReadSlashR),
+	/*8454*/ uint16(xArgYmm1),
+	/*8455*/ uint16(xArgM256),
+	/*8456*/ uint16(xMatch),
+	/*8457*/ uint16(xCondPrefix), 1,
+	0x66, 8461,
+	/*8461*/ uint16(xCondPrefix), 1,
+	0x0F38, 8465,
+	/*8465*/ uint16(xSetOp), uint16(VMOVNTDQA),
 	/*8467*/ uint16(xReadSlashR),
-	/*8468*/ uint16(xArgR32),
-	/*8469*/ uint16(xArgRM32),
+	/*8468*/ uint16(xArgYmm1),
+	/*8469*/ uint16(xArgM256),
 	/*8470*/ uint16(xMatch),
-	/*8471*/ uint16(xCondDataSize), 8459, 8465, 8475,
-	/*8475*/ uint16(xSetOp), uint16(SUB),
-	/*8477*/ uint16(xReadSlashR),
-	/*8478*/ uint16(xArgR64),
-	/*8479*/ uint16(xArgRM64),
-	/*8480*/ uint16(xMatch),
-	/*8481*/ uint16(xSetOp), uint16(SUB),
-	/*8483*/ uint16(xReadIb),
-	/*8484*/ uint16(xArgAL),
-	/*8485*/ uint16(xArgImm8u),
-	/*8486*/ uint16(xMatch),
-	/*8487*/ uint16(xCondIs64), 8490, 8506,
-	/*8490*/ uint16(xCondDataSize), 8494, 8500, 0,
+	/*8471*/ uint16(xCondIs64), 8474, 8490,
+	/*8474*/ uint16(xCondDataSize), 8478, 8484, 0,
+	/*8478*/ uint16(xSetOp), uint16(SUB),
+	/*8480*/ uint16(xReadSlashR),
+	/*8481*/ uint16(xArgR16),
+	/*8482*/ uint16(xArgRM16),
+	/*8483*/ uint16(xMatch),
+	/*8484*/ uint16(xSetOp), uint16(SUB),
+	/*8486*/ uint16(xReadSlashR),
+	/*8487*/ uint16(xArgR32),
+	/*8488*/ uint16(xArgRM32),
+	/*8489*/ uint16(xMatch),
+	/*8490*/ uint16(xCondDataSize), 8478, 8484, 8494,
 	/*8494*/ uint16(xSetOp), uint16(SUB),
-	/*8496*/ uint16(xReadIw),
-	/*8497*/ uint16(xArgAX),
-	/*8498*/ uint16(xArgImm16),
+	/*8496*/ uint16(xReadSlashR),
+	/*8497*/ uint16(xArgR64),
+	/*8498*/ uint16(xArgRM64),
 	/*8499*/ uint16(xMatch),
 	/*8500*/ uint16(xSetOp), uint16(SUB),
-	/*8502*/ uint16(xReadId),
-	/*8503*/ uint16(xArgEAX),
-	/*8504*/ uint16(xArgImm32),
+	/*8502*/ uint16(xReadIb),
+	/*8503*/ uint16(xArgAL),
+	/*8504*/ uint16(xArgImm8u),
 	/*8505*/ uint16(xMatch),
-	/*8506*/ uint16(xCondDataSize), 8494, 8500, 8510,
-	/*8510*/ uint16(xSetOp), uint16(SUB),
-	/*8512*/ uint16(xReadId),
-	/*8513*/ uint16(xArgRAX),
-	/*8514*/ uint16(xArgImm32),
-	/*8515*/ uint16(xMatch),
-	/*8516*/ uint16(xCondIs64), 8519, 0,
-	/*8519*/ uint16(xSetOp), uint16(DAS),
-	/*8521*/ uint16(xMatch),
-	/*8522*/ uint16(xSetOp), uint16(XOR),
-	/*8524*/ uint16(xReadSlashR),
-	/*8525*/ uint16(xArgRM8),
-	/*8526*/ uint16(xArgR8),
-	/*8527*/ uint16(xMatch),
-	/*8528*/ uint16(xCondIs64), 8531, 8547,
-	/*8531*/ uint16(xCondDataSize), 8535, 8541, 0,
-	/*8535*/ uint16(xSetOp), uint16(XOR),
-	/*8537*/ uint16(xReadSlashR),
-	/*8538*/ uint16(xArgRM16),
-	/*8539*/ uint16(xArgR16),
+	/*8506*/ uint16(xCondIs64), 8509, 8525,
+	/*8509*/ uint16(xCondDataSize), 8513, 8519, 0,
+	/*8513*/ uint16(xSetOp), uint16(SUB),
+	/*8515*/ uint16(xReadIw),
+	/*8516*/ uint16(xArgAX),
+	/*8517*/ uint16(xArgImm16),
+	/*8518*/ uint16(xMatch),
+	/*8519*/ uint16(xSetOp), uint16(SUB),
+	/*8521*/ uint16(xReadId),
+	/*8522*/ uint16(xArgEAX),
+	/*8523*/ uint16(xArgImm32),
+	/*8524*/ uint16(xMatch),
+	/*8525*/ uint16(xCondDataSize), 8513, 8519, 8529,
+	/*8529*/ uint16(xSetOp), uint16(SUB),
+	/*8531*/ uint16(xReadId),
+	/*8532*/ uint16(xArgRAX),
+	/*8533*/ uint16(xArgImm32),
+	/*8534*/ uint16(xMatch),
+	/*8535*/ uint16(xCondIs64), 8538, 0,
+	/*8538*/ uint16(xSetOp), uint16(DAS),
 	/*8540*/ uint16(xMatch),
 	/*8541*/ uint16(xSetOp), uint16(XOR),
 	/*8543*/ uint16(xReadSlashR),
-	/*8544*/ uint16(xArgRM32),
-	/*8545*/ uint16(xArgR32),
+	/*8544*/ uint16(xArgRM8),
+	/*8545*/ uint16(xArgR8),
 	/*8546*/ uint16(xMatch),
-	/*8547*/ uint16(xCondDataSize), 8535, 8541, 8551,
-	/*8551*/ uint16(xSetOp), uint16(XOR),
-	/*8553*/ uint16(xReadSlashR),
-	/*8554*/ uint16(xArgRM64),
-	/*8555*/ uint16(xArgR64),
-	/*8556*/ uint16(xMatch),
-	/*8557*/ uint16(xSetOp), uint16(XOR),
-	/*8559*/ uint16(xReadSlashR),
-	/*8560*/ uint16(xArgR8),
-	/*8561*/ uint16(xArgRM8),
-	/*8562*/ uint16(xMatch),
-	/*8563*/ uint16(xCondIs64), 8566, 8582,
-	/*8566*/ uint16(xCondDataSize), 8570, 8576, 0,
+	/*8547*/ uint16(xCondIs64), 8550, 8566,
+	/*8550*/ uint16(xCondDataSize), 8554, 8560, 0,
+	/*8554*/ uint16(xSetOp), uint16(XOR),
+	/*8556*/ uint16(xReadSlashR),
+	/*8557*/ uint16(xArgRM16),
+	/*8558*/ uint16(xArgR16),
+	/*8559*/ uint16(xMatch),
+	/*8560*/ uint16(xSetOp), uint16(XOR),
+	/*8562*/ uint16(xReadSlashR),
+	/*8563*/ uint16(xArgRM32),
+	/*8564*/ uint16(xArgR32),
+	/*8565*/ uint16(xMatch),
+	/*8566*/ uint16(xCondDataSize), 8554, 8560, 8570,
 	/*8570*/ uint16(xSetOp), uint16(XOR),
 	/*8572*/ uint16(xReadSlashR),
-	/*8573*/ uint16(xArgR16),
-	/*8574*/ uint16(xArgRM16),
+	/*8573*/ uint16(xArgRM64),
+	/*8574*/ uint16(xArgR64),
 	/*8575*/ uint16(xMatch),
 	/*8576*/ uint16(xSetOp), uint16(XOR),
 	/*8578*/ uint16(xReadSlashR),
-	/*8579*/ uint16(xArgR32),
-	/*8580*/ uint16(xArgRM32),
+	/*8579*/ uint16(xArgR8),
+	/*8580*/ uint16(xArgRM8),
 	/*8581*/ uint16(xMatch),
-	/*8582*/ uint16(xCondDataSize), 8570, 8576, 8586,
-	/*8586*/ uint16(xSetOp), uint16(XOR),
-	/*8588*/ uint16(xReadSlashR),
-	/*8589*/ uint16(xArgR64),
-	/*8590*/ uint16(xArgRM64),
-	/*8591*/ uint16(xMatch),
-	/*8592*/ uint16(xSetOp), uint16(XOR),
-	/*8594*/ uint16(xReadIb),
-	/*8595*/ uint16(xArgAL),
-	/*8596*/ uint16(xArgImm8u),
-	/*8597*/ uint16(xMatch),
-	/*8598*/ uint16(xCondIs64), 8601, 8617,
-	/*8601*/ uint16(xCondDataSize), 8605, 8611, 0,
+	/*8582*/ uint16(xCondIs64), 8585, 8601,
+	/*8585*/ uint16(xCondDataSize), 8589, 8595, 0,
+	/*8589*/ uint16(xSetOp), uint16(XOR),
+	/*8591*/ uint16(xReadSlashR),
+	/*8592*/ uint16(xArgR16),
+	/*8593*/ uint16(xArgRM16),
+	/*8594*/ uint16(xMatch),
+	/*8595*/ uint16(xSetOp), uint16(XOR),
+	/*8597*/ uint16(xReadSlashR),
+	/*8598*/ uint16(xArgR32),
+	/*8599*/ uint16(xArgRM32),
+	/*8600*/ uint16(xMatch),
+	/*8601*/ uint16(xCondDataSize), 8589, 8595, 8605,
 	/*8605*/ uint16(xSetOp), uint16(XOR),
-	/*8607*/ uint16(xReadIw),
-	/*8608*/ uint16(xArgAX),
-	/*8609*/ uint16(xArgImm16),
+	/*8607*/ uint16(xReadSlashR),
+	/*8608*/ uint16(xArgR64),
+	/*8609*/ uint16(xArgRM64),
 	/*8610*/ uint16(xMatch),
 	/*8611*/ uint16(xSetOp), uint16(XOR),
-	/*8613*/ uint16(xReadId),
-	/*8614*/ uint16(xArgEAX),
-	/*8615*/ uint16(xArgImm32),
+	/*8613*/ uint16(xReadIb),
+	/*8614*/ uint16(xArgAL),
+	/*8615*/ uint16(xArgImm8u),
 	/*8616*/ uint16(xMatch),
-	/*8617*/ uint16(xCondDataSize), 8605, 8611, 8621,
-	/*8621*/ uint16(xSetOp), uint16(XOR),
-	/*8623*/ uint16(xReadId),
-	/*8624*/ uint16(xArgRAX),
-	/*8625*/ uint16(xArgImm32),
-	/*8626*/ uint16(xMatch),
-	/*8627*/ uint16(xCondIs64), 8630, 0,
-	/*8630*/ uint16(xSetOp), uint16(AAA),
-	/*8632*/ uint16(xMatch),
-	/*8633*/ uint16(xSetOp), uint16(CMP),
-	/*8635*/ uint16(xReadSlashR),
-	/*8636*/ uint16(xArgRM8),
-	/*8637*/ uint16(xArgR8),
-	/*8638*/ uint16(xMatch),
-	/*8639*/ uint16(xCondIs64), 8642, 8658,
-	/*8642*/ uint16(xCondDataSize), 8646, 8652, 0,
-	/*8646*/ uint16(xSetOp), uint16(CMP),
-	/*8648*/ uint16(xReadSlashR),
-	/*8649*/ uint16(xArgRM16),
-	/*8650*/ uint16(xArgR16),
+	/*8617*/ uint16(xCondIs64), 8620, 8636,
+	/*8620*/ uint16(xCondDataSize), 8624, 8630, 0,
+	/*8624*/ uint16(xSetOp), uint16(XOR),
+	/*8626*/ uint16(xReadIw),
+	/*8627*/ uint16(xArgAX),
+	/*8628*/ uint16(xArgImm16),
+	/*8629*/ uint16(xMatch),
+	/*8630*/ uint16(xSetOp), uint16(XOR),
+	/*8632*/ uint16(xReadId),
+	/*8633*/ uint16(xArgEAX),
+	/*8634*/ uint16(xArgImm32),
+	/*8635*/ uint16(xMatch),
+	/*8636*/ uint16(xCondDataSize), 8624, 8630, 8640,
+	/*8640*/ uint16(xSetOp), uint16(XOR),
+	/*8642*/ uint16(xReadId),
+	/*8643*/ uint16(xArgRAX),
+	/*8644*/ uint16(xArgImm32),
+	/*8645*/ uint16(xMatch),
+	/*8646*/ uint16(xCondIs64), 8649, 0,
+	/*8649*/ uint16(xSetOp), uint16(AAA),
 	/*8651*/ uint16(xMatch),
 	/*8652*/ uint16(xSetOp), uint16(CMP),
 	/*8654*/ uint16(xReadSlashR),
-	/*8655*/ uint16(xArgRM32),
-	/*8656*/ uint16(xArgR32),
+	/*8655*/ uint16(xArgRM8),
+	/*8656*/ uint16(xArgR8),
 	/*8657*/ uint16(xMatch),
-	/*8658*/ uint16(xCondDataSize), 8646, 8652, 8662,
-	/*8662*/ uint16(xSetOp), uint16(CMP),
-	/*8664*/ uint16(xReadSlashR),
-	/*8665*/ uint16(xArgRM64),
-	/*8666*/ uint16(xArgR64),
-	/*8667*/ uint16(xMatch),
-	/*8668*/ uint16(xSetOp), uint16(CMP),
-	/*8670*/ uint16(xReadSlashR),
-	/*8671*/ uint16(xArgR8),
-	/*8672*/ uint16(xArgRM8),
-	/*8673*/ uint16(xMatch),
-	/*8674*/ uint16(xCondIs64), 8677, 8693,
-	/*8677*/ uint16(xCondDataSize), 8681, 8687, 0,
+	/*8658*/ uint16(xCondIs64), 8661, 8677,
+	/*8661*/ uint16(xCondDataSize), 8665, 8671, 0,
+	/*8665*/ uint16(xSetOp), uint16(CMP),
+	/*8667*/ uint16(xReadSlashR),
+	/*8668*/ uint16(xArgRM16),
+	/*8669*/ uint16(xArgR16),
+	/*8670*/ uint16(xMatch),
+	/*8671*/ uint16(xSetOp), uint16(CMP),
+	/*8673*/ uint16(xReadSlashR),
+	/*8674*/ uint16(xArgRM32),
+	/*8675*/ uint16(xArgR32),
+	/*8676*/ uint16(xMatch),
+	/*8677*/ uint16(xCondDataSize), 8665, 8671, 8681,
 	/*8681*/ uint16(xSetOp), uint16(CMP),
 	/*8683*/ uint16(xReadSlashR),
-	/*8684*/ uint16(xArgR16),
-	/*8685*/ uint16(xArgRM16),
+	/*8684*/ uint16(xArgRM64),
+	/*8685*/ uint16(xArgR64),
 	/*8686*/ uint16(xMatch),
 	/*8687*/ uint16(xSetOp), uint16(CMP),
 	/*8689*/ uint16(xReadSlashR),
-	/*8690*/ uint16(xArgR32),
-	/*8691*/ uint16(xArgRM32),
+	/*8690*/ uint16(xArgR8),
+	/*8691*/ uint16(xArgRM8),
 	/*8692*/ uint16(xMatch),
-	/*8693*/ uint16(xCondDataSize), 8681, 8687, 8697,
-	/*8697*/ uint16(xSetOp), uint16(CMP),
-	/*8699*/ uint16(xReadSlashR),
-	/*8700*/ uint16(xArgR64),
-	/*8701*/ uint16(xArgRM64),
-	/*8702*/ uint16(xMatch),
-	/*8703*/ uint16(xSetOp), uint16(CMP),
-	/*8705*/ uint16(xReadIb),
-	/*8706*/ uint16(xArgAL),
-	/*8707*/ uint16(xArgImm8u),
-	/*8708*/ uint16(xMatch),
-	/*8709*/ uint16(xCondIs64), 8712, 8728,
-	/*8712*/ uint16(xCondDataSize), 8716, 8722, 0,
+	/*8693*/ uint16(xCondIs64), 8696, 8712,
+	/*8696*/ uint16(xCondDataSize), 8700, 8706, 0,
+	/*8700*/ uint16(xSetOp), uint16(CMP),
+	/*8702*/ uint16(xReadSlashR),
+	/*8703*/ uint16(xArgR16),
+	/*8704*/ uint16(xArgRM16),
+	/*8705*/ uint16(xMatch),
+	/*8706*/ uint16(xSetOp), uint16(CMP),
+	/*8708*/ uint16(xReadSlashR),
+	/*8709*/ uint16(xArgR32),
+	/*8710*/ uint16(xArgRM32),
+	/*8711*/ uint16(xMatch),
+	/*8712*/ uint16(xCondDataSize), 8700, 8706, 8716,
 	/*8716*/ uint16(xSetOp), uint16(CMP),
-	/*8718*/ uint16(xReadIw),
-	/*8719*/ uint16(xArgAX),
-	/*8720*/ uint16(xArgImm16),
+	/*8718*/ uint16(xReadSlashR),
+	/*8719*/ uint16(xArgR64),
+	/*8720*/ uint16(xArgRM64),
 	/*8721*/ uint16(xMatch),
 	/*8722*/ uint16(xSetOp), uint16(CMP),
-	/*8724*/ uint16(xReadId),
-	/*8725*/ uint16(xArgEAX),
-	/*8726*/ uint16(xArgImm32),
+	/*8724*/ uint16(xReadIb),
+	/*8725*/ uint16(xArgAL),
+	/*8726*/ uint16(xArgImm8u),
 	/*8727*/ uint16(xMatch),
-	/*8728*/ uint16(xCondDataSize), 8716, 8722, 8732,
-	/*8732*/ uint16(xSetOp), uint16(CMP),
-	/*8734*/ uint16(xReadId),
-	/*8735*/ uint16(xArgRAX),
-	/*8736*/ uint16(xArgImm32),
-	/*8737*/ uint16(xMatch),
-	/*8738*/ uint16(xCondIs64), 8741, 0,
-	/*8741*/ uint16(xSetOp), uint16(AAS),
-	/*8743*/ uint16(xMatch),
-	/*8744*/ uint16(xCondIs64), 8747, 0,
-	/*8747*/ uint16(xCondDataSize), 8751, 8755, 0,
-	/*8751*/ uint16(xSetOp), uint16(INC),
-	/*8753*/ uint16(xArgR16op),
-	/*8754*/ uint16(xMatch),
-	/*8755*/ uint16(xSetOp), uint16(INC),
-	/*8757*/ uint16(xArgR32op),
-	/*8758*/ uint16(xMatch),
-	/*8759*/ uint16(xCondIs64), 8762, 0,
-	/*8762*/ uint16(xCondDataSize), 8766, 8770, 0,
-	/*8766*/ uint16(xSetOp), uint16(DEC),
-	/*8768*/ uint16(xArgR16op),
-	/*8769*/ uint16(xMatch),
-	/*8770*/ uint16(xSetOp), uint16(DEC),
-	/*8772*/ uint16(xArgR32op),
+	/*8728*/ uint16(xCondIs64), 8731, 8747,
+	/*8731*/ uint16(xCondDataSize), 8735, 8741, 0,
+	/*8735*/ uint16(xSetOp), uint16(CMP),
+	/*8737*/ uint16(xReadIw),
+	/*8738*/ uint16(xArgAX),
+	/*8739*/ uint16(xArgImm16),
+	/*8740*/ uint16(xMatch),
+	/*8741*/ uint16(xSetOp), uint16(CMP),
+	/*8743*/ uint16(xReadId),
+	/*8744*/ uint16(xArgEAX),
+	/*8745*/ uint16(xArgImm32),
+	/*8746*/ uint16(xMatch),
+	/*8747*/ uint16(xCondDataSize), 8735, 8741, 8751,
+	/*8751*/ uint16(xSetOp), uint16(CMP),
+	/*8753*/ uint16(xReadId),
+	/*8754*/ uint16(xArgRAX),
+	/*8755*/ uint16(xArgImm32),
+	/*8756*/ uint16(xMatch),
+	/*8757*/ uint16(xCondIs64), 8760, 0,
+	/*8760*/ uint16(xSetOp), uint16(AAS),
+	/*8762*/ uint16(xMatch),
+	/*8763*/ uint16(xCondIs64), 8766, 0,
+	/*8766*/ uint16(xCondDataSize), 8770, 8774, 0,
+	/*8770*/ uint16(xSetOp), uint16(INC),
+	/*8772*/ uint16(xArgR16op),
 	/*8773*/ uint16(xMatch),
-	/*8774*/ uint16(xCondIs64), 8777, 8789,
-	/*8777*/ uint16(xCondDataSize), 8781, 8785, 0,
-	/*8781*/ uint16(xSetOp), uint16(PUSH),
-	/*8783*/ uint16(xArgR16op),
-	/*8784*/ uint16(xMatch),
-	/*8785*/ uint16(xSetOp), uint16(PUSH),
-	/*8787*/ uint16(xArgR32op),
+	/*8774*/ uint16(xSetOp), uint16(INC),
+	/*8776*/ uint16(xArgR32op),
+	/*8777*/ uint16(xMatch),
+	/*8778*/ uint16(xCondIs64), 8781, 0,
+	/*8781*/ uint16(xCondDataSize), 8785, 8789, 0,
+	/*8785*/ uint16(xSetOp), uint16(DEC),
+	/*8787*/ uint16(xArgR16op),
 	/*8788*/ uint16(xMatch),
-	/*8789*/ uint16(xCondDataSize), 8781, 8793, 8797,
-	/*8793*/ uint16(xSetOp), uint16(PUSH),
-	/*8795*/ uint16(xArgR64op),
-	/*8796*/ uint16(xMatch),
-	/*8797*/ uint16(xSetOp), uint16(PUSH),
-	/*8799*/ uint16(xArgR64op),
-	/*8800*/ uint16(xMatch),
-	/*8801*/ uint16(xCondIs64), 8804, 8816,
-	/*8804*/ uint16(xCondDataSize), 8808, 8812, 0,
-	/*8808*/ uint16(xSetOp), uint16(POP),
-	/*8810*/ uint16(xArgR16op),
-	/*8811*/ uint16(xMatch),
-	/*8812*/ uint16(xSetOp), uint16(POP),
-	/*8814*/ uint16(xArgR32op),
+	/*8789*/ uint16(xSetOp), uint16(DEC),
+	/*8791*/ uint16(xArgR32op),
+	/*8792*/ uint16(xMatch),
+	/*8793*/ uint16(xCondIs64), 8796, 8808,
+	/*8796*/ uint16(xCondDataSize), 8800, 8804, 0,
+	/*8800*/ uint16(xSetOp), uint16(PUSH),
+	/*8802*/ uint16(xArgR16op),
+	/*8803*/ uint16(xMatch),
+	/*8804*/ uint16(xSetOp), uint16(PUSH),
+	/*8806*/ uint16(xArgR32op),
+	/*8807*/ uint16(xMatch),
+	/*8808*/ uint16(xCondDataSize), 8800, 8812, 8816,
+	/*8812*/ uint16(xSetOp), uint16(PUSH),
+	/*8814*/ uint16(xArgR64op),
 	/*8815*/ uint16(xMatch),
-	/*8816*/ uint16(xCondDataSize), 8808, 8820, 8824,
-	/*8820*/ uint16(xSetOp), uint16(POP),
-	/*8822*/ uint16(xArgR64op),
-	/*8823*/ uint16(xMatch),
-	/*8824*/ uint16(xSetOp), uint16(POP),
-	/*8826*/ uint16(xArgR64op),
-	/*8827*/ uint16(xMatch),
-	/*8828*/ uint16(xCondIs64), 8831, 0,
-	/*8831*/ uint16(xCondDataSize), 8835, 8838, 0,
-	/*8835*/ uint16(xSetOp), uint16(PUSHA),
-	/*8837*/ uint16(xMatch),
-	/*8838*/ uint16(xSetOp), uint16(PUSHAD),
-	/*8840*/ uint16(xMatch),
-	/*8841*/ uint16(xCondIs64), 8844, 0,
-	/*8844*/ uint16(xCondDataSize), 8848, 8851, 0,
-	/*8848*/ uint16(xSetOp), uint16(POPA),
-	/*8850*/ uint16(xMatch),
-	/*8851*/ uint16(xSetOp), uint16(POPAD),
-	/*8853*/ uint16(xMatch),
-	/*8854*/ uint16(xCondIs64), 8857, 0,
-	/*8857*/ uint16(xCondDataSize), 8861, 8867, 0,
-	/*8861*/ uint16(xSetOp), uint16(BOUND),
-	/*8863*/ uint16(xReadSlashR),
-	/*8864*/ uint16(xArgR16),
-	/*8865*/ uint16(xArgM16and16),
-	/*8866*/ uint16(xMatch),
-	/*8867*/ uint16(xSetOp), uint16(BOUND),
-	/*8869*/ uint16(xReadSlashR),
-	/*8870*/ uint16(xArgR32),
-	/*8871*/ uint16(xArgM32and32),
+	/*8816*/ uint16(xSetOp), uint16(PUSH),
+	/*8818*/ uint16(xArgR64op),
+	/*8819*/ uint16(xMatch),
+	/*8820*/ uint16(xCondIs64), 8823, 8835,
+	/*8823*/ uint16(xCondDataSize), 8827, 8831, 0,
+	/*8827*/ uint16(xSetOp), uint16(POP),
+	/*8829*/ uint16(xArgR16op),
+	/*8830*/ uint16(xMatch),
+	/*8831*/ uint16(xSetOp), uint16(POP),
+	/*8833*/ uint16(xArgR32op),
+	/*8834*/ uint16(xMatch),
+	/*8835*/ uint16(xCondDataSize), 8827, 8839, 8843,
+	/*8839*/ uint16(xSetOp), uint16(POP),
+	/*8841*/ uint16(xArgR64op),
+	/*8842*/ uint16(xMatch),
+	/*8843*/ uint16(xSetOp), uint16(POP),
+	/*8845*/ uint16(xArgR64op),
+	/*8846*/ uint16(xMatch),
+	/*8847*/ uint16(xCondIs64), 8850, 0,
+	/*8850*/ uint16(xCondDataSize), 8854, 8857, 0,
+	/*8854*/ uint16(xSetOp), uint16(PUSHA),
+	/*8856*/ uint16(xMatch),
+	/*8857*/ uint16(xSetOp), uint16(PUSHAD),
+	/*8859*/ uint16(xMatch),
+	/*8860*/ uint16(xCondIs64), 8863, 0,
+	/*8863*/ uint16(xCondDataSize), 8867, 8870, 0,
+	/*8867*/ uint16(xSetOp), uint16(POPA),
+	/*8869*/ uint16(xMatch),
+	/*8870*/ uint16(xSetOp), uint16(POPAD),
 	/*8872*/ uint16(xMatch),
-	/*8873*/ uint16(xCondIs64), 8876, 8882,
-	/*8876*/ uint16(xSetOp), uint16(ARPL),
-	/*8878*/ uint16(xReadSlashR),
-	/*8879*/ uint16(xArgRM16),
-	/*8880*/ uint16(xArgR16),
-	/*8881*/ uint16(xMatch),
-	/*8882*/ uint16(xCondDataSize), 8886, 8892, 8898,
-	/*8886*/ uint16(xSetOp), uint16(MOVSXD),
+	/*8873*/ uint16(xCondIs64), 8876, 0,
+	/*8876*/ uint16(xCondDataSize), 8880, 8886, 0,
+	/*8880*/ uint16(xSetOp), uint16(BOUND),
+	/*8882*/ uint16(xReadSlashR),
+	/*8883*/ uint16(xArgR16),
+	/*8884*/ uint16(xArgM16and16),
+	/*8885*/ uint16(xMatch),
+	/*8886*/ uint16(xSetOp), uint16(BOUND),
 	/*8888*/ uint16(xReadSlashR),
-	/*8889*/ uint16(xArgR16),
-	/*8890*/ uint16(xArgRM32),
+	/*8889*/ uint16(xArgR32),
+	/*8890*/ uint16(xArgM32and32),
 	/*8891*/ uint16(xMatch),
-	/*8892*/ uint16(xSetOp), uint16(MOVSXD),
-	/*8894*/ uint16(xReadSlashR),
-	/*8895*/ uint16(xArgR32),
-	/*8896*/ uint16(xArgRM32),
-	/*8897*/ uint16(xMatch),
-	/*8898*/ uint16(xSetOp), uint16(MOVSXD),
-	/*8900*/ uint16(xReadSlashR),
-	/*8901*/ uint16(xArgR64),
-	/*8902*/ uint16(xArgRM32),
-	/*8903*/ uint16(xMatch),
-	/*8904*/ uint16(xCondDataSize), 8908, 8913, 8918,
-	/*8908*/ uint16(xSetOp), uint16(PUSH),
-	/*8910*/ uint16(xReadIw),
-	/*8911*/ uint16(xArgImm16),
-	/*8912*/ uint16(xMatch),
-	/*8913*/ uint16(xSetOp), uint16(PUSH),
-	/*8915*/ uint16(xReadId),
-	/*8916*/ uint16(xArgImm32),
-	/*8917*/ uint16(xMatch),
-	/*8918*/ uint16(xSetOp), uint16(PUSH),
-	/*8920*/ uint16(xReadId),
-	/*8921*/ uint16(xArgImm32),
+	/*8892*/ uint16(xCondIs64), 8895, 8901,
+	/*8895*/ uint16(xSetOp), uint16(ARPL),
+	/*8897*/ uint16(xReadSlashR),
+	/*8898*/ uint16(xArgRM16),
+	/*8899*/ uint16(xArgR16),
+	/*8900*/ uint16(xMatch),
+	/*8901*/ uint16(xCondDataSize), 8905, 8911, 8917,
+	/*8905*/ uint16(xSetOp), uint16(MOVSXD),
+	/*8907*/ uint16(xReadSlashR),
+	/*8908*/ uint16(xArgR16),
+	/*8909*/ uint16(xArgRM32),
+	/*8910*/ uint16(xMatch),
+	/*8911*/ uint16(xSetOp), uint16(MOVSXD),
+	/*8913*/ uint16(xReadSlashR),
+	/*8914*/ uint16(xArgR32),
+	/*8915*/ uint16(xArgRM32),
+	/*8916*/ uint16(xMatch),
+	/*8917*/ uint16(xSetOp), uint16(MOVSXD),
+	/*8919*/ uint16(xReadSlashR),
+	/*8920*/ uint16(xArgR64),
+	/*8921*/ uint16(xArgRM32),
 	/*8922*/ uint16(xMatch),
-	/*8923*/ uint16(xCondIs64), 8926, 8946,
-	/*8926*/ uint16(xCondDataSize), 8930, 8938, 0,
-	/*8930*/ uint16(xSetOp), uint16(IMUL),
-	/*8932*/ uint16(xReadSlashR),
-	/*8933*/ uint16(xReadIw),
-	/*8934*/ uint16(xArgR16),
-	/*8935*/ uint16(xArgRM16),
-	/*8936*/ uint16(xArgImm16),
-	/*8937*/ uint16(xMatch),
-	/*8938*/ uint16(xSetOp), uint16(IMUL),
-	/*8940*/ uint16(xReadSlashR),
-	/*8941*/ uint16(xReadId),
-	/*8942*/ uint16(xArgR32),
-	/*8943*/ uint16(xArgRM32),
-	/*8944*/ uint16(xArgImm32),
-	/*8945*/ uint16(xMatch),
-	/*8946*/ uint16(xCondDataSize), 8930, 8938, 8950,
-	/*8950*/ uint16(xSetOp), uint16(IMUL),
-	/*8952*/ uint16(xReadSlashR),
-	/*8953*/ uint16(xReadId),
-	/*8954*/ uint16(xArgR64),
-	/*8955*/ uint16(xArgRM64),
-	/*8956*/ uint16(xArgImm32),
-	/*8957*/ uint16(xMatch),
-	/*8958*/ uint16(xSetOp), uint16(PUSH),
-	/*8960*/ uint16(xReadIb),
-	/*8961*/ uint16(xArgImm8),
-	/*8962*/ uint16(xMatch),
-	/*8963*/ uint16(xCondIs64), 8966, 8986,
-	/*8966*/ uint16(xCondDataSize), 8970, 8978, 0,
-	/*8970*/ uint16(xSetOp), uint16(IMUL),
-	/*8972*/ uint16(xReadSlashR),
-	/*8973*/ uint16(xReadIb),
-	/*8974*/ uint16(xArgR16),
-	/*8975*/ uint16(xArgRM16),
-	/*8976*/ uint16(xArgImm8),
-	/*8977*/ uint16(xMatch),
-	/*8978*/ uint16(xSetOp), uint16(IMUL),
-	/*8980*/ uint16(xReadSlashR),
-	/*8981*/ uint16(xReadIb),
-	/*8982*/ uint16(xArgR32),
-	/*8983*/ uint16(xArgRM32),
-	/*8984*/ uint16(xArgImm8),
-	/*8985*/ uint16(xMatch),
-	/*8986*/ uint16(xCondDataSize), 8970, 8978, 8990,
-	/*8990*/ uint16(xSetOp), uint16(IMUL),
-	/*8992*/ uint16(xReadSlashR),
-	/*8993*/ uint16(xReadIb),
-	/*8994*/ uint16(xArgR64),
-	/*8995*/ uint16(xArgRM64),
-	/*8996*/ uint16(xArgImm8),
-	/*8997*/ uint16(xMatch),
-	/*8998*/ uint16(xSetOp), uint16(INSB),
-	/*9000*/ uint16(xMatch),
-	/*9001*/ uint16(xCondDataSize), 9005, 9008, 9011,
-	/*9005*/ uint16(xSetOp), uint16(INSW),
-	/*9007*/ uint16(xMatch),
-	/*9008*/ uint16(xSetOp), uint16(INSD),
-	/*9010*/ uint16(xMatch),
-	/*9011*/ uint16(xSetOp), uint16(INSD),
-	/*9013*/ uint16(xMatch),
-	/*9014*/ uint16(xSetOp), uint16(OUTSB),
+	/*8923*/ uint16(xCondDataSize), 8927, 8932, 8937,
+	/*8927*/ uint16(xSetOp), uint16(PUSH),
+	/*8929*/ uint16(xReadIw),
+	/*8930*/ uint16(xArgImm16),
+	/*8931*/ uint16(xMatch),
+	/*8932*/ uint16(xSetOp), uint16(PUSH),
+	/*8934*/ uint16(xReadId),
+	/*8935*/ uint16(xArgImm32),
+	/*8936*/ uint16(xMatch),
+	/*8937*/ uint16(xSetOp), uint16(PUSH),
+	/*8939*/ uint16(xReadId),
+	/*8940*/ uint16(xArgImm32),
+	/*8941*/ uint16(xMatch),
+	/*8942*/ uint16(xCondIs64), 8945, 8965,
+	/*8945*/ uint16(xCondDataSize), 8949, 8957, 0,
+	/*8949*/ uint16(xSetOp), uint16(IMUL),
+	/*8951*/ uint16(xReadSlashR),
+	/*8952*/ uint16(xReadIw),
+	/*8953*/ uint16(xArgR16),
+	/*8954*/ uint16(xArgRM16),
+	/*8955*/ uint16(xArgImm16),
+	/*8956*/ uint16(xMatch),
+	/*8957*/ uint16(xSetOp), uint16(IMUL),
+	/*8959*/ uint16(xReadSlashR),
+	/*8960*/ uint16(xReadId),
+	/*8961*/ uint16(xArgR32),
+	/*8962*/ uint16(xArgRM32),
+	/*8963*/ uint16(xArgImm32),
+	/*8964*/ uint16(xMatch),
+	/*8965*/ uint16(xCondDataSize), 8949, 8957, 8969,
+	/*8969*/ uint16(xSetOp), uint16(IMUL),
+	/*8971*/ uint16(xReadSlashR),
+	/*8972*/ uint16(xReadId),
+	/*8973*/ uint16(xArgR64),
+	/*8974*/ uint16(xArgRM64),
+	/*8975*/ uint16(xArgImm32),
+	/*8976*/ uint16(xMatch),
+	/*8977*/ uint16(xSetOp), uint16(PUSH),
+	/*8979*/ uint16(xReadIb),
+	/*8980*/ uint16(xArgImm8),
+	/*8981*/ uint16(xMatch),
+	/*8982*/ uint16(xCondIs64), 8985, 9005,
+	/*8985*/ uint16(xCondDataSize), 8989, 8997, 0,
+	/*8989*/ uint16(xSetOp), uint16(IMUL),
+	/*8991*/ uint16(xReadSlashR),
+	/*8992*/ uint16(xReadIb),
+	/*8993*/ uint16(xArgR16),
+	/*8994*/ uint16(xArgRM16),
+	/*8995*/ uint16(xArgImm8),
+	/*8996*/ uint16(xMatch),
+	/*8997*/ uint16(xSetOp), uint16(IMUL),
+	/*8999*/ uint16(xReadSlashR),
+	/*9000*/ uint16(xReadIb),
+	/*9001*/ uint16(xArgR32),
+	/*9002*/ uint16(xArgRM32),
+	/*9003*/ uint16(xArgImm8),
+	/*9004*/ uint16(xMatch),
+	/*9005*/ uint16(xCondDataSize), 8989, 8997, 9009,
+	/*9009*/ uint16(xSetOp), uint16(IMUL),
+	/*9011*/ uint16(xReadSlashR),
+	/*9012*/ uint16(xReadIb),
+	/*9013*/ uint16(xArgR64),
+	/*9014*/ uint16(xArgRM64),
+	/*9015*/ uint16(xArgImm8),
 	/*9016*/ uint16(xMatch),
-	/*9017*/ uint16(xCondPrefix), 3,
-	0xC5, 9064,
-	0xC4, 9038,
-	0x0, 9025,
-	/*9025*/ uint16(xCondDataSize), 9029, 9032, 9035,
-	/*9029*/ uint16(xSetOp), uint16(OUTSW),
-	/*9031*/ uint16(xMatch),
-	/*9032*/ uint16(xSetOp), uint16(OUTSD),
-	/*9034*/ uint16(xMatch),
-	/*9035*/ uint16(xSetOp), uint16(OUTSD),
-	/*9037*/ uint16(xMatch),
-	/*9038*/ uint16(xCondPrefix), 2,
-	0xF3, 9054,
-	0x66, 9044,
-	/*9044*/ uint16(xCondPrefix), 1,
-	0x0F, 9048,
-	/*9048*/ uint16(xSetOp), uint16(VMOVDQA),
-	/*9050*/ uint16(xReadSlashR),
-	/*9051*/ uint16(xArgYmm1),
-	/*9052*/ uint16(xArgYmm2M256),
+	/*9017*/ uint16(xSetOp), uint16(INSB),
+	/*9019*/ uint16(xMatch),
+	/*9020*/ uint16(xCondDataSize), 9024, 9027, 9030,
+	/*9024*/ uint16(xSetOp), uint16(INSW),
+	/*9026*/ uint16(xMatch),
+	/*9027*/ uint16(xSetOp), uint16(INSD),
+	/*9029*/ uint16(xMatch),
+	/*9030*/ uint16(xSetOp), uint16(INSD),
+	/*9032*/ uint16(xMatch),
+	/*9033*/ uint16(xSetOp), uint16(OUTSB),
+	/*9035*/ uint16(xMatch),
+	/*9036*/ uint16(xCondPrefix), 3,
+	0xC5, 9083,
+	0xC4, 9057,
+	0x0, 9044,
+	/*9044*/ uint16(xCondDataSize), 9048, 9051, 9054,
+	/*9048*/ uint16(xSetOp), uint16(OUTSW),
+	/*9050*/ uint16(xMatch),
+	/*9051*/ uint16(xSetOp), uint16(OUTSD),
 	/*9053*/ uint16(xMatch),
-	/*9054*/ uint16(xCondPrefix), 1,
-	0x0F, 9058,
-	/*9058*/ uint16(xSetOp), uint16(VMOVDQU),
-	/*9060*/ uint16(xReadSlashR),
-	/*9061*/ uint16(xArgYmm1),
-	/*9062*/ uint16(xArgYmm2M256),
-	/*9063*/ uint16(xMatch),
-	/*9064*/ uint16(xCondPrefix), 2,
-	0xF3, 9080,
-	0x66, 9070,
-	/*9070*/ uint16(xCondPrefix), 1,
-	0x0F, 9074,
-	/*9074*/ uint16(xSetOp), uint16(VMOVDQA),
-	/*9076*/ uint16(xReadSlashR),
-	/*9077*/ uint16(xArgYmm1),
-	/*9078*/ uint16(xArgYmm2M256),
-	/*9079*/ uint16(xMatch),
-	/*9080*/ uint16(xCondPrefix), 1,
-	0x0F, 9084,
-	/*9084*/ uint16(xSetOp), uint16(VMOVDQU),
-	/*9086*/ uint16(xReadSlashR),
-	/*9087*/ uint16(xArgYmm1),
-	/*9088*/ uint16(xArgYmm2M256),
-	/*9089*/ uint16(xMatch),
-	/*9090*/ uint16(xSetOp), uint16(JO),
-	/*9092*/ uint16(xReadCb),
-	/*9093*/ uint16(xArgRel8),
-	/*9094*/ uint16(xMatch),
-	/*9095*/ uint16(xSetOp), uint16(JNO),
-	/*9097*/ uint16(xReadCb),
-	/*9098*/ uint16(xArgRel8),
-	/*9099*/ uint16(xMatch),
-	/*9100*/ uint16(xSetOp), uint16(JB),
-	/*9102*/ uint16(xReadCb),
-	/*9103*/ uint16(xArgRel8),
-	/*9104*/ uint16(xMatch),
-	/*9105*/ uint16(xSetOp), uint16(JAE),
-	/*9107*/ uint16(xReadCb),
-	/*9108*/ uint16(xArgRel8),
-	/*9109*/ uint16(xMatch),
-	/*9110*/ uint16(xSetOp), uint16(JE),
-	/*9112*/ uint16(xReadCb),
-	/*9113*/ uint16(xArgRel8),
-	/*9114*/ uint16(xMatch),
-	/*9115*/ uint16(xSetOp), uint16(JNE),
-	/*9117*/ uint16(xReadCb),
-	/*9118*/ uint16(xArgRel8),
-	/*9119*/ uint16(xMatch),
-	/*9120*/ uint16(xSetOp), uint16(JBE),
-	/*9122*/ uint16(xReadCb),
-	/*9123*/ uint16(xArgRel8),
-	/*9124*/ uint16(xMatch),
-	/*9125*/ uint16(xCondPrefix), 3,
-	0xC5, 9145,
-	0xC4, 9138,
-	0x0, 9133,
-	/*9133*/ uint16(xSetOp), uint16(JA),
-	/*9135*/ uint16(xReadCb),
-	/*9136*/ uint16(xArgRel8),
-	/*9137*/ uint16(xMatch),
-	/*9138*/ uint16(xCondPrefix), 1,
-	0x0F, 9142,
-	/*9142*/ uint16(xSetOp), uint16(VZEROUPPER),
-	/*9144*/ uint16(xMatch),
-	/*9145*/ uint16(xCondPrefix), 1,
-	0x0F, 9149,
-	/*9149*/ uint16(xSetOp), uint16(VZEROUPPER),
-	/*9151*/ uint16(xMatch),
-	/*9152*/ uint16(xSetOp), uint16(JS),
+	/*9054*/ uint16(xSetOp), uint16(OUTSD),
+	/*9056*/ uint16(xMatch),
+	/*9057*/ uint16(xCondPrefix), 2,
+	0xF3, 9073,
+	0x66, 9063,
+	/*9063*/ uint16(xCondPrefix), 1,
+	0x0F, 9067,
+	/*9067*/ uint16(xSetOp), uint16(VMOVDQA),
+	/*9069*/ uint16(xReadSlashR),
+	/*9070*/ uint16(xArgYmm1),
+	/*9071*/ uint16(xArgYmm2M256),
+	/*9072*/ uint16(xMatch),
+	/*9073*/ uint16(xCondPrefix), 1,
+	0x0F, 9077,
+	/*9077*/ uint16(xSetOp), uint16(VMOVDQU),
+	/*9079*/ uint16(xReadSlashR),
+	/*9080*/ uint16(xArgYmm1),
+	/*9081*/ uint16(xArgYmm2M256),
+	/*9082*/ uint16(xMatch),
+	/*9083*/ uint16(xCondPrefix), 2,
+	0xF3, 9099,
+	0x66, 9089,
+	/*9089*/ uint16(xCondPrefix), 1,
+	0x0F, 9093,
+	/*9093*/ uint16(xSetOp), uint16(VMOVDQA),
+	/*9095*/ uint16(xReadSlashR),
+	/*9096*/ uint16(xArgYmm1),
+	/*9097*/ uint16(xArgYmm2M256),
+	/*9098*/ uint16(xMatch),
+	/*9099*/ uint16(xCondPrefix), 1,
+	0x0F, 9103,
+	/*9103*/ uint16(xSetOp), uint16(VMOVDQU),
+	/*9105*/ uint16(xReadSlashR),
+	/*9106*/ uint16(xArgYmm1),
+	/*9107*/ uint16(xArgYmm2M256),
+	/*9108*/ uint16(xMatch),
+	/*9109*/ uint16(xSetOp), uint16(JO),
+	/*9111*/ uint16(xReadCb),
+	/*9112*/ uint16(xArgRel8),
+	/*9113*/ uint16(xMatch),
+	/*9114*/ uint16(xSetOp), uint16(JNO),
+	/*9116*/ uint16(xReadCb),
+	/*9117*/ uint16(xArgRel8),
+	/*9118*/ uint16(xMatch),
+	/*9119*/ uint16(xSetOp), uint16(JB),
+	/*9121*/ uint16(xReadCb),
+	/*9122*/ uint16(xArgRel8),
+	/*9123*/ uint16(xMatch),
+	/*9124*/ uint16(xSetOp), uint16(JAE),
+	/*9126*/ uint16(xReadCb),
+	/*9127*/ uint16(xArgRel8),
+	/*9128*/ uint16(xMatch),
+	/*9129*/ uint16(xSetOp), uint16(JE),
+	/*9131*/ uint16(xReadCb),
+	/*9132*/ uint16(xArgRel8),
+	/*9133*/ uint16(xMatch),
+	/*9134*/ uint16(xSetOp), uint16(JNE),
+	/*9136*/ uint16(xReadCb),
+	/*9137*/ uint16(xArgRel8),
+	/*9138*/ uint16(xMatch),
+	/*9139*/ uint16(xSetOp), uint16(JBE),
+	/*9141*/ uint16(xReadCb),
+	/*9142*/ uint16(xArgRel8),
+	/*9143*/ uint16(xMatch),
+	/*9144*/ uint16(xCondPrefix), 3,
+	0xC5, 9164,
+	0xC4, 9157,
+	0x0, 9152,
+	/*9152*/ uint16(xSetOp), uint16(JA),
 	/*9154*/ uint16(xReadCb),
 	/*9155*/ uint16(xArgRel8),
 	/*9156*/ uint16(xMatch),
-	/*9157*/ uint16(xSetOp), uint16(JNS),
-	/*9159*/ uint16(xReadCb),
-	/*9160*/ uint16(xArgRel8),
-	/*9161*/ uint16(xMatch),
-	/*9162*/ uint16(xSetOp), uint16(JP),
-	/*9164*/ uint16(xReadCb),
-	/*9165*/ uint16(xArgRel8),
-	/*9166*/ uint16(xMatch),
-	/*9167*/ uint16(xSetOp), uint16(JNP),
-	/*9169*/ uint16(xReadCb),
-	/*9170*/ uint16(xArgRel8),
-	/*9171*/ uint16(xMatch),
-	/*9172*/ uint16(xSetOp), uint16(JL),
-	/*9174*/ uint16(xReadCb),
-	/*9175*/ uint16(xArgRel8),
-	/*9176*/ uint16(xMatch),
-	/*9177*/ uint16(xSetOp), uint16(JGE),
-	/*9179*/ uint16(xReadCb),
-	/*9180*/ uint16(xArgRel8),
-	/*9181*/ uint16(xMatch),
-	/*9182*/ uint16(xSetOp), uint16(JLE),
-	/*9184*/ uint16(xReadCb),
-	/*9185*/ uint16(xArgRel8),
-	/*9186*/ uint16(xMatch),
-	/*9187*/ uint16(xCondPrefix), 3,
-	0xC5, 9226,
-	0xC4, 9200,
-	0x0, 9195,
-	/*9195*/ uint16(xSetOp), uint16(JG),
-	/*9197*/ uint16(xReadCb),
-	/*9198*/ uint16(xArgRel8),
-	/*9199*/ uint16(xMatch),
-	/*9200*/ uint16(xCondPrefix), 2,
-	0xF3, 9216,
-	0x66, 9206,
-	/*9206*/ uint16(xCondPrefix), 1,
-	0x0F, 9210,
-	/*9210*/ uint16(xSetOp), uint16(VMOVDQA),
-	/*9212*/ uint16(xReadSlashR),
-	/*9213*/ uint16(xArgYmm2M256),
-	/*9214*/ uint16(xArgYmm1),
-	/*9215*/ uint16(xMatch),
-	/*9216*/ uint16(xCondPrefix), 1,
-	0x0F, 9220,
-	/*9220*/ uint16(xSetOp), uint16(VMOVDQU),
-	/*9222*/ uint16(xReadSlashR),
-	/*9223*/ uint16(xArgYmm2M256),
-	/*9224*/ uint16(xArgYmm1),
-	/*9225*/ uint16(xMatch),
-	/*9226*/ uint16(xCondPrefix), 2,
-	0xF3, 9242,
-	0x66, 9232,
-	/*9232*/ uint16(xCondPrefix), 1,
-	0x0F, 9236,
-	/*9236*/ uint16(xSetOp), uint16(VMOVDQA),
-	/*9238*/ uint16(xReadSlashR),
-	/*9239*/ uint16(xArgYmm2M256),
-	/*9240*/ uint16(xArgYmm1),
-	/*9241*/ uint16(xMatch),
-	/*9242*/ uint16(xCondPrefix), 1,
-	0x0F, 9246,
-	/*9246*/ uint16(xSetOp), uint16(VMOVDQU),
-	/*9248*/ uint16(xReadSlashR),
-	/*9249*/ uint16(xArgYmm2M256),
-	/*9250*/ uint16(xArgYmm1),
-	/*9251*/ uint16(xMatch),
-	/*9252*/ uint16(xCondSlashR),
-	9261, // 0
-	9267, // 1
-	9273, // 2
-	9279, // 3
-	9285, // 4
-	9291, // 5
-	9297, // 6
-	9303, // 7
-	/*9261*/ uint16(xSetOp), uint16(ADD),
-	/*9263*/ uint16(xReadIb),
-	/*9264*/ uint16(xArgRM8),
-	/*9265*/ uint16(xArgImm8u),
-	/*9266*/ uint16(xMatch),
-	/*9267*/ uint16(xSetOp), uint16(OR),
-	/*9269*/ uint16(xReadIb),
-	/*9270*/ uint16(xArgRM8),
-	/*9271*/ uint16(xArgImm8u),
-	/*9272*/ uint16(xMatch),
-	/*9273*/ uint16(xSetOp), uint16(ADC),
-	/*9275*/ uint16(xReadIb),
-	/*9276*/ uint16(xArgRM8),
-	/*9277*/ uint16(xArgImm8u),
-	/*9278*/ uint16(xMatch),
-	/*9279*/ uint16(xSetOp), uint16(SBB),
-	/*9281*/ uint16(xReadIb),
-	/*9282*/ uint16(xArgRM8),
-	/*9283*/ uint16(xArgImm8u),
-	/*9284*/ uint16(xMatch),
-	/*9285*/ uint16(xSetOp), uint16(AND),
-	/*9287*/ uint16(xReadIb),
-	/*9288*/ uint16(xArgRM8),
-	/*9289*/ uint16(xArgImm8u),
-	/*9290*/ uint16(xMatch),
-	/*9291*/ uint16(xSetOp), uint16(SUB),
-	/*9293*/ uint16(xReadIb),
-	/*9294*/ uint16(xArgRM8),
-	/*9295*/ uint16(xArgImm8u),
-	/*9296*/ uint16(xMatch),
-	/*9297*/ uint16(xSetOp), uint16(XOR),
-	/*9299*/ uint16(xReadIb),
-	/*9300*/ uint16(xArgRM8),
-	/*9301*/ uint16(xArgImm8u),
-	/*9302*/ uint16(xMatch),
-	/*9303*/ uint16(xSetOp), uint16(CMP),
-	/*9305*/ uint16(xReadIb),
-	/*9306*/ uint16(xArgRM8),
-	/*9307*/ uint16(xArgImm8u),
-	/*9308*/ uint16(xMatch),
-	/*9309*/ uint16(xCondSlashR),
-	9318, // 0
-	9347, // 1
-	9376, // 2
-	9405, // 3
-	9434, // 4
-	9463, // 5
-	9492, // 6
-	9521, // 7
-	/*9318*/ uint16(xCondIs64), 9321, 9337,
-	/*9321*/ uint16(xCondDataSize), 9325, 9331, 0,
-	/*9325*/ uint16(xSetOp), uint16(ADD),
-	/*9327*/ uint16(xReadIw),
-	/*9328*/ uint16(xArgRM16),
-	/*9329*/ uint16(xArgImm16),
-	/*9330*/ uint16(xMatch),
-	/*9331*/ uint16(xSetOp), uint16(ADD),
-	/*9333*/ uint16(xReadId),
-	/*9334*/ uint16(xArgRM32),
-	/*9335*/ uint16(xArgImm32),
-	/*9336*/ uint16(xMatch),
-	/*9337*/ uint16(xCondDataSize), 9325, 9331, 9341,
-	/*9341*/ uint16(xSetOp), uint16(ADD),
-	/*9343*/ uint16(xReadId),
-	/*9344*/ uint16(xArgRM64),
-	/*9345*/ uint16(xArgImm32),
-	/*9346*/ uint16(xMatch),
-	/*9347*/ uint16(xCondIs64), 9350, 9366,
-	/*9350*/ uint16(xCondDataSize), 9354, 9360, 0,
-	/*9354*/ uint16(xSetOp), uint16(OR),
-	/*9356*/ uint16(xReadIw),
-	/*9357*/ uint16(xArgRM16),
-	/*9358*/ uint16(xArgImm16),
-	/*9359*/ uint16(xMatch),
-	/*9360*/ uint16(xSetOp), uint16(OR),
+	/*9157*/ uint16(xCondPrefix), 1,
+	0x0F, 9161,
+	/*9161*/ uint16(xSetOp), uint16(VZEROUPPER),
+	/*9163*/ uint16(xMatch),
+	/*9164*/ uint16(xCondPrefix), 1,
+	0x0F, 9168,
+	/*9168*/ uint16(xSetOp), uint16(VZEROUPPER),
+	/*9170*/ uint16(xMatch),
+	/*9171*/ uint16(xSetOp), uint16(JS),
+	/*9173*/ uint16(xReadCb),
+	/*9174*/ uint16(xArgRel8),
+	/*9175*/ uint16(xMatch),
+	/*9176*/ uint16(xSetOp), uint16(JNS),
+	/*9178*/ uint16(xReadCb),
+	/*9179*/ uint16(xArgRel8),
+	/*9180*/ uint16(xMatch),
+	/*9181*/ uint16(xSetOp), uint16(JP),
+	/*9183*/ uint16(xReadCb),
+	/*9184*/ uint16(xArgRel8),
+	/*9185*/ uint16(xMatch),
+	/*9186*/ uint16(xSetOp), uint16(JNP),
+	/*9188*/ uint16(xReadCb),
+	/*9189*/ uint16(xArgRel8),
+	/*9190*/ uint16(xMatch),
+	/*9191*/ uint16(xSetOp), uint16(JL),
+	/*9193*/ uint16(xReadCb),
+	/*9194*/ uint16(xArgRel8),
+	/*9195*/ uint16(xMatch),
+	/*9196*/ uint16(xSetOp), uint16(JGE),
+	/*9198*/ uint16(xReadCb),
+	/*9199*/ uint16(xArgRel8),
+	/*9200*/ uint16(xMatch),
+	/*9201*/ uint16(xSetOp), uint16(JLE),
+	/*9203*/ uint16(xReadCb),
+	/*9204*/ uint16(xArgRel8),
+	/*9205*/ uint16(xMatch),
+	/*9206*/ uint16(xCondPrefix), 3,
+	0xC5, 9245,
+	0xC4, 9219,
+	0x0, 9214,
+	/*9214*/ uint16(xSetOp), uint16(JG),
+	/*9216*/ uint16(xReadCb),
+	/*9217*/ uint16(xArgRel8),
+	/*9218*/ uint16(xMatch),
+	/*9219*/ uint16(xCondPrefix), 2,
+	0xF3, 9235,
+	0x66, 9225,
+	/*9225*/ uint16(xCondPrefix), 1,
+	0x0F, 9229,
+	/*9229*/ uint16(xSetOp), uint16(VMOVDQA),
+	/*9231*/ uint16(xReadSlashR),
+	/*9232*/ uint16(xArgYmm2M256),
+	/*9233*/ uint16(xArgYmm1),
+	/*9234*/ uint16(xMatch),
+	/*9235*/ uint16(xCondPrefix), 1,
+	0x0F, 9239,
+	/*9239*/ uint16(xSetOp), uint16(VMOVDQU),
+	/*9241*/ uint16(xReadSlashR),
+	/*9242*/ uint16(xArgYmm2M256),
+	/*9243*/ uint16(xArgYmm1),
+	/*9244*/ uint16(xMatch),
+	/*9245*/ uint16(xCondPrefix), 2,
+	0xF3, 9261,
+	0x66, 9251,
+	/*9251*/ uint16(xCondPrefix), 1,
+	0x0F, 9255,
+	/*9255*/ uint16(xSetOp), uint16(VMOVDQA),
+	/*9257*/ uint16(xReadSlashR),
+	/*9258*/ uint16(xArgYmm2M256),
+	/*9259*/ uint16(xArgYmm1),
+	/*9260*/ uint16(xMatch),
+	/*9261*/ uint16(xCondPrefix), 1,
+	0x0F, 9265,
+	/*9265*/ uint16(xSetOp), uint16(VMOVDQU),
+	/*9267*/ uint16(xReadSlashR),
+	/*9268*/ uint16(xArgYmm2M256),
+	/*9269*/ uint16(xArgYmm1),
+	/*9270*/ uint16(xMatch),
+	/*9271*/ uint16(xCondSlashR),
+	9280, // 0
+	9286, // 1
+	9292, // 2
+	9298, // 3
+	9304, // 4
+	9310, // 5
+	9316, // 6
+	9322, // 7
+	/*9280*/ uint16(xSetOp), uint16(ADD),
+	/*9282*/ uint16(xReadIb),
+	/*9283*/ uint16(xArgRM8),
+	/*9284*/ uint16(xArgImm8u),
+	/*9285*/ uint16(xMatch),
+	/*9286*/ uint16(xSetOp), uint16(OR),
+	/*9288*/ uint16(xReadIb),
+	/*9289*/ uint16(xArgRM8),
+	/*9290*/ uint16(xArgImm8u),
+	/*9291*/ uint16(xMatch),
+	/*9292*/ uint16(xSetOp), uint16(ADC),
+	/*9294*/ uint16(xReadIb),
+	/*9295*/ uint16(xArgRM8),
+	/*9296*/ uint16(xArgImm8u),
+	/*9297*/ uint16(xMatch),
+	/*9298*/ uint16(xSetOp), uint16(SBB),
+	/*9300*/ uint16(xReadIb),
+	/*9301*/ uint16(xArgRM8),
+	/*9302*/ uint16(xArgImm8u),
+	/*9303*/ uint16(xMatch),
+	/*9304*/ uint16(xSetOp), uint16(AND),
+	/*9306*/ uint16(xReadIb),
+	/*9307*/ uint16(xArgRM8),
+	/*9308*/ uint16(xArgImm8u),
+	/*9309*/ uint16(xMatch),
+	/*9310*/ uint16(xSetOp), uint16(SUB),
+	/*9312*/ uint16(xReadIb),
+	/*9313*/ uint16(xArgRM8),
+	/*9314*/ uint16(xArgImm8u),
+	/*9315*/ uint16(xMatch),
+	/*9316*/ uint16(xSetOp), uint16(XOR),
+	/*9318*/ uint16(xReadIb),
+	/*9319*/ uint16(xArgRM8),
+	/*9320*/ uint16(xArgImm8u),
+	/*9321*/ uint16(xMatch),
+	/*9322*/ uint16(xSetOp), uint16(CMP),
+	/*9324*/ uint16(xReadIb),
+	/*9325*/ uint16(xArgRM8),
+	/*9326*/ uint16(xArgImm8u),
+	/*9327*/ uint16(xMatch),
+	/*9328*/ uint16(xCondSlashR),
+	9337, // 0
+	9366, // 1
+	9395, // 2
+	9424, // 3
+	9453, // 4
+	9482, // 5
+	9511, // 6
+	9540, // 7
+	/*9337*/ uint16(xCondIs64), 9340, 9356,
+	/*9340*/ uint16(xCondDataSize), 9344, 9350, 0,
+	/*9344*/ uint16(xSetOp), uint16(ADD),
+	/*9346*/ uint16(xReadIw),
+	/*9347*/ uint16(xArgRM16),
+	/*9348*/ uint16(xArgImm16),
+	/*9349*/ uint16(xMatch),
+	/*9350*/ uint16(xSetOp), uint16(ADD),
+	/*9352*/ uint16(xReadId),
+	/*9353*/ uint16(xArgRM32),
+	/*9354*/ uint16(xArgImm32),
+	/*9355*/ uint16(xMatch),
+	/*9356*/ uint16(xCondDataSize), 9344, 9350, 9360,
+	/*9360*/ uint16(xSetOp), uint16(ADD),
 	/*9362*/ uint16(xReadId),
-	/*9363*/ uint16(xArgRM32),
+	/*9363*/ uint16(xArgRM64),
 	/*9364*/ uint16(xArgImm32),
 	/*9365*/ uint16(xMatch),
-	/*9366*/ uint16(xCondDataSize), 9354, 9360, 9370,
-	/*9370*/ uint16(xSetOp), uint16(OR),
-	/*9372*/ uint16(xReadId),
-	/*9373*/ uint16(xArgRM64),
-	/*9374*/ uint16(xArgImm32),
-	/*9375*/ uint16(xMatch),
-	/*9376*/ uint16(xCondIs64), 9379, 9395,
-	/*9379*/ uint16(xCondDataSize), 9383, 9389, 0,
-	/*9383*/ uint16(xSetOp), uint16(ADC),
-	/*9385*/ uint16(xReadIw),
-	/*9386*/ uint16(xArgRM16),
-	/*9387*/ uint16(xArgImm16),
-	/*9388*/ uint16(xMatch),
-	/*9389*/ uint16(xSetOp), uint16(ADC),
+	/*9366*/ uint16(xCondIs64), 9369, 9385,
+	/*9369*/ uint16(xCondDataSize), 9373, 9379, 0,
+	/*9373*/ uint16(xSetOp), uint16(OR),
+	/*9375*/ uint16(xReadIw),
+	/*9376*/ uint16(xArgRM16),
+	/*9377*/ uint16(xArgImm16),
+	/*9378*/ uint16(xMatch),
+	/*9379*/ uint16(xSetOp), uint16(OR),
+	/*9381*/ uint16(xReadId),
+	/*9382*/ uint16(xArgRM32),
+	/*9383*/ uint16(xArgImm32),
+	/*9384*/ uint16(xMatch),
+	/*9385*/ uint16(xCondDataSize), 9373, 9379, 9389,
+	/*9389*/ uint16(xSetOp), uint16(OR),
 	/*9391*/ uint16(xReadId),
-	/*9392*/ uint16(xArgRM32),
+	/*9392*/ uint16(xArgRM64),
 	/*9393*/ uint16(xArgImm32),
 	/*9394*/ uint16(xMatch),
-	/*9395*/ uint16(xCondDataSize), 9383, 9389, 9399,
-	/*9399*/ uint16(xSetOp), uint16(ADC),
-	/*9401*/ uint16(xReadId),
-	/*9402*/ uint16(xArgRM64),
-	/*9403*/ uint16(xArgImm32),
-	/*9404*/ uint16(xMatch),
-	/*9405*/ uint16(xCondIs64), 9408, 9424,
-	/*9408*/ uint16(xCondDataSize), 9412, 9418, 0,
-	/*9412*/ uint16(xSetOp), uint16(SBB),
-	/*9414*/ uint16(xReadIw),
-	/*9415*/ uint16(xArgRM16),
-	/*9416*/ uint16(xArgImm16),
-	/*9417*/ uint16(xMatch),
-	/*9418*/ uint16(xSetOp), uint16(SBB),
+	/*9395*/ uint16(xCondIs64), 9398, 9414,
+	/*9398*/ uint16(xCondDataSize), 9402, 9408, 0,
+	/*9402*/ uint16(xSetOp), uint16(ADC),
+	/*9404*/ uint16(xReadIw),
+	/*9405*/ uint16(xArgRM16),
+	/*9406*/ uint16(xArgImm16),
+	/*9407*/ uint16(xMatch),
+	/*9408*/ uint16(xSetOp), uint16(ADC),
+	/*9410*/ uint16(xReadId),
+	/*9411*/ uint16(xArgRM32),
+	/*9412*/ uint16(xArgImm32),
+	/*9413*/ uint16(xMatch),
+	/*9414*/ uint16(xCondDataSize), 9402, 9408, 9418,
+	/*9418*/ uint16(xSetOp), uint16(ADC),
 	/*9420*/ uint16(xReadId),
-	/*9421*/ uint16(xArgRM32),
+	/*9421*/ uint16(xArgRM64),
 	/*9422*/ uint16(xArgImm32),
 	/*9423*/ uint16(xMatch),
-	/*9424*/ uint16(xCondDataSize), 9412, 9418, 9428,
-	/*9428*/ uint16(xSetOp), uint16(SBB),
-	/*9430*/ uint16(xReadId),
-	/*9431*/ uint16(xArgRM64),
-	/*9432*/ uint16(xArgImm32),
-	/*9433*/ uint16(xMatch),
-	/*9434*/ uint16(xCondIs64), 9437, 9453,
-	/*9437*/ uint16(xCondDataSize), 9441, 9447, 0,
-	/*9441*/ uint16(xSetOp), uint16(AND),
-	/*9443*/ uint16(xReadIw),
-	/*9444*/ uint16(xArgRM16),
-	/*9445*/ uint16(xArgImm16),
-	/*9446*/ uint16(xMatch),
-	/*9447*/ uint16(xSetOp), uint16(AND),
+	/*9424*/ uint16(xCondIs64), 9427, 9443,
+	/*9427*/ uint16(xCondDataSize), 9431, 9437, 0,
+	/*9431*/ uint16(xSetOp), uint16(SBB),
+	/*9433*/ uint16(xReadIw),
+	/*9434*/ uint16(xArgRM16),
+	/*9435*/ uint16(xArgImm16),
+	/*9436*/ uint16(xMatch),
+	/*9437*/ uint16(xSetOp), uint16(SBB),
+	/*9439*/ uint16(xReadId),
+	/*9440*/ uint16(xArgRM32),
+	/*9441*/ uint16(xArgImm32),
+	/*9442*/ uint16(xMatch),
+	/*9443*/ uint16(xCondDataSize), 9431, 9437, 9447,
+	/*9447*/ uint16(xSetOp), uint16(SBB),
 	/*9449*/ uint16(xReadId),
-	/*9450*/ uint16(xArgRM32),
+	/*9450*/ uint16(xArgRM64),
 	/*9451*/ uint16(xArgImm32),
 	/*9452*/ uint16(xMatch),
-	/*9453*/ uint16(xCondDataSize), 9441, 9447, 9457,
-	/*9457*/ uint16(xSetOp), uint16(AND),
-	/*9459*/ uint16(xReadId),
-	/*9460*/ uint16(xArgRM64),
-	/*9461*/ uint16(xArgImm32),
-	/*9462*/ uint16(xMatch),
-	/*9463*/ uint16(xCondIs64), 9466, 9482,
-	/*9466*/ uint16(xCondDataSize), 9470, 9476, 0,
-	/*9470*/ uint16(xSetOp), uint16(SUB),
-	/*9472*/ uint16(xReadIw),
-	/*9473*/ uint16(xArgRM16),
-	/*9474*/ uint16(xArgImm16),
-	/*9475*/ uint16(xMatch),
-	/*9476*/ uint16(xSetOp), uint16(SUB),
+	/*9453*/ uint16(xCondIs64), 9456, 9472,
+	/*9456*/ uint16(xCondDataSize), 9460, 9466, 0,
+	/*9460*/ uint16(xSetOp), uint16(AND),
+	/*9462*/ uint16(xReadIw),
+	/*9463*/ uint16(xArgRM16),
+	/*9464*/ uint16(xArgImm16),
+	/*9465*/ uint16(xMatch),
+	/*9466*/ uint16(xSetOp), uint16(AND),
+	/*9468*/ uint16(xReadId),
+	/*9469*/ uint16(xArgRM32),
+	/*9470*/ uint16(xArgImm32),
+	/*9471*/ uint16(xMatch),
+	/*9472*/ uint16(xCondDataSize), 9460, 9466, 9476,
+	/*9476*/ uint16(xSetOp), uint16(AND),
 	/*9478*/ uint16(xReadId),
-	/*9479*/ uint16(xArgRM32),
+	/*9479*/ uint16(xArgRM64),
 	/*9480*/ uint16(xArgImm32),
 	/*9481*/ uint16(xMatch),
-	/*9482*/ uint16(xCondDataSize), 9470, 9476, 9486,
-	/*9486*/ uint16(xSetOp), uint16(SUB),
-	/*9488*/ uint16(xReadId),
-	/*9489*/ uint16(xArgRM64),
-	/*9490*/ uint16(xArgImm32),
-	/*9491*/ uint16(xMatch),
-	/*9492*/ uint16(xCondIs64), 9495, 9511,
-	/*9495*/ uint16(xCondDataSize), 9499, 9505, 0,
-	/*9499*/ uint16(xSetOp), uint16(XOR),
-	/*9501*/ uint16(xReadIw),
-	/*9502*/ uint16(xArgRM16),
-	/*9503*/ uint16(xArgImm16),
-	/*9504*/ uint16(xMatch),
-	/*9505*/ uint16(xSetOp), uint16(XOR),
+	/*9482*/ uint16(xCondIs64), 9485, 9501,
+	/*9485*/ uint16(xCondDataSize), 9489, 9495, 0,
+	/*9489*/ uint16(xSetOp), uint16(SUB),
+	/*9491*/ uint16(xReadIw),
+	/*9492*/ uint16(xArgRM16),
+	/*9493*/ uint16(xArgImm16),
+	/*9494*/ uint16(xMatch),
+	/*9495*/ uint16(xSetOp), uint16(SUB),
+	/*9497*/ uint16(xReadId),
+	/*9498*/ uint16(xArgRM32),
+	/*9499*/ uint16(xArgImm32),
+	/*9500*/ uint16(xMatch),
+	/*9501*/ uint16(xCondDataSize), 9489, 9495, 9505,
+	/*9505*/ uint16(xSetOp), uint16(SUB),
 	/*9507*/ uint16(xReadId),
-	/*9508*/ uint16(xArgRM32),
+	/*9508*/ uint16(xArgRM64),
 	/*9509*/ uint16(xArgImm32),
 	/*9510*/ uint16(xMatch),
-	/*9511*/ uint16(xCondDataSize), 9499, 9505, 9515,
-	/*9515*/ uint16(xSetOp), uint16(XOR),
-	/*9517*/ uint16(xReadId),
-	/*9518*/ uint16(xArgRM64),
-	/*9519*/ uint16(xArgImm32),
-	/*9520*/ uint16(xMatch),
-	/*9521*/ uint16(xCondIs64), 9524, 9540,
-	/*9524*/ uint16(xCondDataSize), 9528, 9534, 0,
-	/*9528*/ uint16(xSetOp), uint16(CMP),
-	/*9530*/ uint16(xReadIw),
-	/*9531*/ uint16(xArgRM16),
-	/*9532*/ uint16(xArgImm16),
-	/*9533*/ uint16(xMatch),
-	/*9534*/ uint16(xSetOp), uint16(CMP),
+	/*9511*/ uint16(xCondIs64), 9514, 9530,
+	/*9514*/ uint16(xCondDataSize), 9518, 9524, 0,
+	/*9518*/ uint16(xSetOp), uint16(XOR),
+	/*9520*/ uint16(xReadIw),
+	/*9521*/ uint16(xArgRM16),
+	/*9522*/ uint16(xArgImm16),
+	/*9523*/ uint16(xMatch),
+	/*9524*/ uint16(xSetOp), uint16(XOR),
+	/*9526*/ uint16(xReadId),
+	/*9527*/ uint16(xArgRM32),
+	/*9528*/ uint16(xArgImm32),
+	/*9529*/ uint16(xMatch),
+	/*9530*/ uint16(xCondDataSize), 9518, 9524, 9534,
+	/*9534*/ uint16(xSetOp), uint16(XOR),
 	/*9536*/ uint16(xReadId),
-	/*9537*/ uint16(xArgRM32),
+	/*9537*/ uint16(xArgRM64),
 	/*9538*/ uint16(xArgImm32),
 	/*9539*/ uint16(xMatch),
-	/*9540*/ uint16(xCondDataSize), 9528, 9534, 9544,
-	/*9544*/ uint16(xSetOp), uint16(CMP),
-	/*9546*/ uint16(xReadId),
-	/*9547*/ uint16(xArgRM64),
-	/*9548*/ uint16(xArgImm32),
-	/*9549*/ uint16(xMatch),
-	/*9550*/ uint16(xCondSlashR),
-	9559, // 0
-	9588, // 1
-	9617, // 2
-	9646, // 3
-	9675, // 4
-	9704, // 5
-	9733, // 6
-	9762, // 7
-	/*9559*/ uint16(xCondIs64), 9562, 9578,
-	/*9562*/ uint16(xCondDataSize), 9566, 9572, 0,
-	/*9566*/ uint16(xSetOp), uint16(ADD),
-	/*9568*/ uint16(xReadIb),
-	/*9569*/ uint16(xArgRM16),
-	/*9570*/ uint16(xArgImm8),
-	/*9571*/ uint16(xMatch),
-	/*9572*/ uint16(xSetOp), uint16(ADD),
-	/*9574*/ uint16(xReadIb),
-	/*9575*/ uint16(xArgRM32),
-	/*9576*/ uint16(xArgImm8),
-	/*9577*/ uint16(xMatch),
-	/*9578*/ uint16(xCondDataSize), 9566, 9572, 9582,
-	/*9582*/ uint16(xSetOp), uint16(ADD),
-	/*9584*/ uint16(xReadIb),
-	/*9585*/ uint16(xArgRM64),
-	/*9586*/ uint16(xArgImm8),
-	/*9587*/ uint16(xMatch),
-	/*9588*/ uint16(xCondIs64), 9591, 9607,
-	/*9591*/ uint16(xCondDataSize), 9595, 9601, 0,
-	/*9595*/ uint16(xSetOp), uint16(OR),
-	/*9597*/ uint16(xReadIb),
-	/*9598*/ uint16(xArgRM16),
-	/*9599*/ uint16(xArgImm8),
-	/*9600*/ uint16(xMatch),
-	/*9601*/ uint16(xSetOp), uint16(OR),
+	/*9540*/ uint16(xCondIs64), 9543, 9559,
+	/*9543*/ uint16(xCondDataSize), 9547, 9553, 0,
+	/*9547*/ uint16(xSetOp), uint16(CMP),
+	/*9549*/ uint16(xReadIw),
+	/*9550*/ uint16(xArgRM16),
+	/*9551*/ uint16(xArgImm16),
+	/*9552*/ uint16(xMatch),
+	/*9553*/ uint16(xSetOp), uint16(CMP),
+	/*9555*/ uint16(xReadId),
+	/*9556*/ uint16(xArgRM32),
+	/*9557*/ uint16(xArgImm32),
+	/*9558*/ uint16(xMatch),
+	/*9559*/ uint16(xCondDataSize), 9547, 9553, 9563,
+	/*9563*/ uint16(xSetOp), uint16(CMP),
+	/*9565*/ uint16(xReadId),
+	/*9566*/ uint16(xArgRM64),
+	/*9567*/ uint16(xArgImm32),
+	/*9568*/ uint16(xMatch),
+	/*9569*/ uint16(xCondSlashR),
+	9578, // 0
+	9607, // 1
+	9636, // 2
+	9665, // 3
+	9694, // 4
+	9723, // 5
+	9752, // 6
+	9781, // 7
+	/*9578*/ uint16(xCondIs64), 9581, 9597,
+	/*9581*/ uint16(xCondDataSize), 9585, 9591, 0,
+	/*9585*/ uint16(xSetOp), uint16(ADD),
+	/*9587*/ uint16(xReadIb),
+	/*9588*/ uint16(xArgRM16),
+	/*9589*/ uint16(xArgImm8),
+	/*9590*/ uint16(xMatch),
+	/*9591*/ uint16(xSetOp), uint16(ADD),
+	/*9593*/ uint16(xReadIb),
+	/*9594*/ uint16(xArgRM32),
+	/*9595*/ uint16(xArgImm8),
+	/*9596*/ uint16(xMatch),
+	/*9597*/ uint16(xCondDataSize), 9585, 9591, 9601,
+	/*9601*/ uint16(xSetOp), uint16(ADD),
 	/*9603*/ uint16(xReadIb),
-	/*9604*/ uint16(xArgRM32),
+	/*9604*/ uint16(xArgRM64),
 	/*9605*/ uint16(xArgImm8),
 	/*9606*/ uint16(xMatch),
-	/*9607*/ uint16(xCondDataSize), 9595, 9601, 9611,
-	/*9611*/ uint16(xSetOp), uint16(OR),
-	/*9613*/ uint16(xReadIb),
-	/*9614*/ uint16(xArgRM64),
-	/*9615*/ uint16(xArgImm8),
-	/*9616*/ uint16(xMatch),
-	/*9617*/ uint16(xCondIs64), 9620, 9636,
-	/*9620*/ uint16(xCondDataSize), 9624, 9630, 0,
-	/*9624*/ uint16(xSetOp), uint16(ADC),
-	/*9626*/ uint16(xReadIb),
-	/*9627*/ uint16(xArgRM16),
-	/*9628*/ uint16(xArgImm8),
-	/*9629*/ uint16(xMatch),
-	/*9630*/ uint16(xSetOp), uint16(ADC),
+	/*9607*/ uint16(xCondIs64), 9610, 9626,
+	/*9610*/ uint16(xCondDataSize), 9614, 9620, 0,
+	/*9614*/ uint16(xSetOp), uint16(OR),
+	/*9616*/ uint16(xReadIb),
+	/*9617*/ uint16(xArgRM16),
+	/*9618*/ uint16(xArgImm8),
+	/*9619*/ uint16(xMatch),
+	/*9620*/ uint16(xSetOp), uint16(OR),
+	/*9622*/ uint16(xReadIb),
+	/*9623*/ uint16(xArgRM32),
+	/*9624*/ uint16(xArgImm8),
+	/*9625*/ uint16(xMatch),
+	/*9626*/ uint16(xCondDataSize), 9614, 9620, 9630,
+	/*9630*/ uint16(xSetOp), uint16(OR),
 	/*9632*/ uint16(xReadIb),
-	/*9633*/ uint16(xArgRM32),
+	/*9633*/ uint16(xArgRM64),
 	/*9634*/ uint16(xArgImm8),
 	/*9635*/ uint16(xMatch),
-	/*9636*/ uint16(xCondDataSize), 9624, 9630, 9640,
-	/*9640*/ uint16(xSetOp), uint16(ADC),
-	/*9642*/ uint16(xReadIb),
-	/*9643*/ uint16(xArgRM64),
-	/*9644*/ uint16(xArgImm8),
-	/*9645*/ uint16(xMatch),
-	/*9646*/ uint16(xCondIs64), 9649, 9665,
-	/*9649*/ uint16(xCondDataSize), 9653, 9659, 0,
-	/*9653*/ uint16(xSetOp), uint16(SBB),
-	/*9655*/ uint16(xReadIb),
-	/*9656*/ uint16(xArgRM16),
-	/*9657*/ uint16(xArgImm8),
-	/*9658*/ uint16(xMatch),
-	/*9659*/ uint16(xSetOp), uint16(SBB),
+	/*9636*/ uint16(xCondIs64), 9639, 9655,
+	/*9639*/ uint16(xCondDataSize), 9643, 9649, 0,
+	/*9643*/ uint16(xSetOp), uint16(ADC),
+	/*9645*/ uint16(xReadIb),
+	/*9646*/ uint16(xArgRM16),
+	/*9647*/ uint16(xArgImm8),
+	/*9648*/ uint16(xMatch),
+	/*9649*/ uint16(xSetOp), uint16(ADC),
+	/*9651*/ uint16(xReadIb),
+	/*9652*/ uint16(xArgRM32),
+	/*9653*/ uint16(xArgImm8),
+	/*9654*/ uint16(xMatch),
+	/*9655*/ uint16(xCondDataSize), 9643, 9649, 9659,
+	/*9659*/ uint16(xSetOp), uint16(ADC),
 	/*9661*/ uint16(xReadIb),
-	/*9662*/ uint16(xArgRM32),
+	/*9662*/ uint16(xArgRM64),
 	/*9663*/ uint16(xArgImm8),
 	/*9664*/ uint16(xMatch),
-	/*9665*/ uint16(xCondDataSize), 9653, 9659, 9669,
-	/*9669*/ uint16(xSetOp), uint16(SBB),
-	/*9671*/ uint16(xReadIb),
-	/*9672*/ uint16(xArgRM64),
-	/*9673*/ uint16(xArgImm8),
-	/*9674*/ uint16(xMatch),
-	/*9675*/ uint16(xCondIs64), 9678, 9694,
-	/*9678*/ uint16(xCondDataSize), 9682, 9688, 0,
-	/*9682*/ uint16(xSetOp), uint16(AND),
-	/*9684*/ uint16(xReadIb),
-	/*9685*/ uint16(xArgRM16),
-	/*9686*/ uint16(xArgImm8),
-	/*9687*/ uint16(xMatch),
-	/*9688*/ uint16(xSetOp), uint16(AND),
+	/*9665*/ uint16(xCondIs64), 9668, 9684,
+	/*9668*/ uint16(xCondDataSize), 9672, 9678, 0,
+	/*9672*/ uint16(xSetOp), uint16(SBB),
+	/*9674*/ uint16(xReadIb),
+	/*9675*/ uint16(xArgRM16),
+	/*9676*/ uint16(xArgImm8),
+	/*9677*/ uint16(xMatch),
+	/*9678*/ uint16(xSetOp), uint16(SBB),
+	/*9680*/ uint16(xReadIb),
+	/*9681*/ uint16(xArgRM32),
+	/*9682*/ uint16(xArgImm8),
+	/*9683*/ uint16(xMatch),
+	/*9684*/ uint16(xCondDataSize), 9672, 9678, 9688,
+	/*9688*/ uint16(xSetOp), uint16(SBB),
 	/*9690*/ uint16(xReadIb),
-	/*9691*/ uint16(xArgRM32),
+	/*9691*/ uint16(xArgRM64),
 	/*9692*/ uint16(xArgImm8),
 	/*9693*/ uint16(xMatch),
-	/*9694*/ uint16(xCondDataSize), 9682, 9688, 9698,
-	/*9698*/ uint16(xSetOp), uint16(AND),
-	/*9700*/ uint16(xReadIb),
-	/*9701*/ uint16(xArgRM64),
-	/*9702*/ uint16(xArgImm8),
-	/*9703*/ uint16(xMatch),
-	/*9704*/ uint16(xCondIs64), 9707, 9723,
-	/*9707*/ uint16(xCondDataSize), 9711, 9717, 0,
-	/*9711*/ uint16(xSetOp), uint16(SUB),
-	/*9713*/ uint16(xReadIb),
-	/*9714*/ uint16(xArgRM16),
-	/*9715*/ uint16(xArgImm8),
-	/*9716*/ uint16(xMatch),
-	/*9717*/ uint16(xSetOp), uint16(SUB),
+	/*9694*/ uint16(xCondIs64), 9697, 9713,
+	/*9697*/ uint16(xCondDataSize), 9701, 9707, 0,
+	/*9701*/ uint16(xSetOp), uint16(AND),
+	/*9703*/ uint16(xReadIb),
+	/*9704*/ uint16(xArgRM16),
+	/*9705*/ uint16(xArgImm8),
+	/*9706*/ uint16(xMatch),
+	/*9707*/ uint16(xSetOp), uint16(AND),
+	/*9709*/ uint16(xReadIb),
+	/*9710*/ uint16(xArgRM32),
+	/*9711*/ uint16(xArgImm8),
+	/*9712*/ uint16(xMatch),
+	/*9713*/ uint16(xCondDataSize), 9701, 9707, 9717,
+	/*9717*/ uint16(xSetOp), uint16(AND),
 	/*9719*/ uint16(xReadIb),
-	/*9720*/ uint16(xArgRM32),
+	/*9720*/ uint16(xArgRM64),
 	/*9721*/ uint16(xArgImm8),
 	/*9722*/ uint16(xMatch),
-	/*9723*/ uint16(xCondDataSize), 9711, 9717, 9727,
-	/*9727*/ uint16(xSetOp), uint16(SUB),
-	/*9729*/ uint16(xReadIb),
-	/*9730*/ uint16(xArgRM64),
-	/*9731*/ uint16(xArgImm8),
-	/*9732*/ uint16(xMatch),
-	/*9733*/ uint16(xCondIs64), 9736, 9752,
-	/*9736*/ uint16(xCondDataSize), 9740, 9746, 0,
-	/*9740*/ uint16(xSetOp), uint16(XOR),
-	/*9742*/ uint16(xReadIb),
-	/*9743*/ uint16(xArgRM16),
-	/*9744*/ uint16(xArgImm8),
-	/*9745*/ uint16(xMatch),
-	/*9746*/ uint16(xSetOp), uint16(XOR),
+	/*9723*/ uint16(xCondIs64), 9726, 9742,
+	/*9726*/ uint16(xCondDataSize), 9730, 9736, 0,
+	/*9730*/ uint16(xSetOp), uint16(SUB),
+	/*9732*/ uint16(xReadIb),
+	/*9733*/ uint16(xArgRM16),
+	/*9734*/ uint16(xArgImm8),
+	/*9735*/ uint16(xMatch),
+	/*9736*/ uint16(xSetOp), uint16(SUB),
+	/*9738*/ uint16(xReadIb),
+	/*9739*/ uint16(xArgRM32),
+	/*9740*/ uint16(xArgImm8),
+	/*9741*/ uint16(xMatch),
+	/*9742*/ uint16(xCondDataSize), 9730, 9736, 9746,
+	/*9746*/ uint16(xSetOp), uint16(SUB),
 	/*9748*/ uint16(xReadIb),
-	/*9749*/ uint16(xArgRM32),
+	/*9749*/ uint16(xArgRM64),
 	/*9750*/ uint16(xArgImm8),
 	/*9751*/ uint16(xMatch),
-	/*9752*/ uint16(xCondDataSize), 9740, 9746, 9756,
-	/*9756*/ uint16(xSetOp), uint16(XOR),
-	/*9758*/ uint16(xReadIb),
-	/*9759*/ uint16(xArgRM64),
-	/*9760*/ uint16(xArgImm8),
-	/*9761*/ uint16(xMatch),
-	/*9762*/ uint16(xCondIs64), 9765, 9781,
-	/*9765*/ uint16(xCondDataSize), 9769, 9775, 0,
-	/*9769*/ uint16(xSetOp), uint16(CMP),
-	/*9771*/ uint16(xReadIb),
-	/*9772*/ uint16(xArgRM16),
-	/*9773*/ uint16(xArgImm8),
-	/*9774*/ uint16(xMatch),
-	/*9775*/ uint16(xSetOp), uint16(CMP),
+	/*9752*/ uint16(xCondIs64), 9755, 9771,
+	/*9755*/ uint16(xCondDataSize), 9759, 9765, 0,
+	/*9759*/ uint16(xSetOp), uint16(XOR),
+	/*9761*/ uint16(xReadIb),
+	/*9762*/ uint16(xArgRM16),
+	/*9763*/ uint16(xArgImm8),
+	/*9764*/ uint16(xMatch),
+	/*9765*/ uint16(xSetOp), uint16(XOR),
+	/*9767*/ uint16(xReadIb),
+	/*9768*/ uint16(xArgRM32),
+	/*9769*/ uint16(xArgImm8),
+	/*9770*/ uint16(xMatch),
+	/*9771*/ uint16(xCondDataSize), 9759, 9765, 9775,
+	/*9775*/ uint16(xSetOp), uint16(XOR),
 	/*9777*/ uint16(xReadIb),
-	/*9778*/ uint16(xArgRM32),
+	/*9778*/ uint16(xArgRM64),
 	/*9779*/ uint16(xArgImm8),
 	/*9780*/ uint16(xMatch),
-	/*9781*/ uint16(xCondDataSize), 9769, 9775, 9785,
-	/*9785*/ uint16(xSetOp), uint16(CMP),
-	/*9787*/ uint16(xReadIb),
-	/*9788*/ uint16(xArgRM64),
-	/*9789*/ uint16(xArgImm8),
-	/*9790*/ uint16(xMatch),
-	/*9791*/ uint16(xSetOp), uint16(TEST),
-	/*9793*/ uint16(xReadSlashR),
-	/*9794*/ uint16(xArgRM8),
-	/*9795*/ uint16(xArgR8),
-	/*9796*/ uint16(xMatch),
-	/*9797*/ uint16(xCondIs64), 9800, 9816,
-	/*9800*/ uint16(xCondDataSize), 9804, 9810, 0,
-	/*9804*/ uint16(xSetOp), uint16(TEST),
-	/*9806*/ uint16(xReadSlashR),
-	/*9807*/ uint16(xArgRM16),
-	/*9808*/ uint16(xArgR16),
+	/*9781*/ uint16(xCondIs64), 9784, 9800,
+	/*9784*/ uint16(xCondDataSize), 9788, 9794, 0,
+	/*9788*/ uint16(xSetOp), uint16(CMP),
+	/*9790*/ uint16(xReadIb),
+	/*9791*/ uint16(xArgRM16),
+	/*9792*/ uint16(xArgImm8),
+	/*9793*/ uint16(xMatch),
+	/*9794*/ uint16(xSetOp), uint16(CMP),
+	/*9796*/ uint16(xReadIb),
+	/*9797*/ uint16(xArgRM32),
+	/*9798*/ uint16(xArgImm8),
+	/*9799*/ uint16(xMatch),
+	/*9800*/ uint16(xCondDataSize), 9788, 9794, 9804,
+	/*9804*/ uint16(xSetOp), uint16(CMP),
+	/*9806*/ uint16(xReadIb),
+	/*9807*/ uint16(xArgRM64),
+	/*9808*/ uint16(xArgImm8),
 	/*9809*/ uint16(xMatch),
 	/*9810*/ uint16(xSetOp), uint16(TEST),
 	/*9812*/ uint16(xReadSlashR),
-	/*9813*/ uint16(xArgRM32),
-	/*9814*/ uint16(xArgR32),
+	/*9813*/ uint16(xArgRM8),
+	/*9814*/ uint16(xArgR8),
 	/*9815*/ uint16(xMatch),
-	/*9816*/ uint16(xCondDataSize), 9804, 9810, 9820,
-	/*9820*/ uint16(xSetOp), uint16(TEST),
-	/*9822*/ uint16(xReadSlashR),
-	/*9823*/ uint16(xArgRM64),
-	/*9824*/ uint16(xArgR64),
-	/*9825*/ uint16(xMatch),
-	/*9826*/ uint16(xSetOp), uint16(XCHG),
-	/*9828*/ uint16(xReadSlashR),
-	/*9829*/ uint16(xArgRM8),
-	/*9830*/ uint16(xArgR8),
-	/*9831*/ uint16(xMatch),
-	/*9832*/ uint16(xCondIs64), 9835, 9851,
-	/*9835*/ uint16(xCondDataSize), 9839, 9845, 0,
-	/*9839*/ uint16(xSetOp), uint16(XCHG),
+	/*9816*/ uint16(xCondIs64), 9819, 9835,
+	/*9819*/ uint16(xCondDataSize), 9823, 9829, 0,
+	/*9823*/ uint16(xSetOp), uint16(TEST),
+	/*9825*/ uint16(xReadSlashR),
+	/*9826*/ uint16(xArgRM16),
+	/*9827*/ uint16(xArgR16),
+	/*9828*/ uint16(xMatch),
+	/*9829*/ uint16(xSetOp), uint16(TEST),
+	/*9831*/ uint16(xReadSlashR),
+	/*9832*/ uint16(xArgRM32),
+	/*9833*/ uint16(xArgR32),
+	/*9834*/ uint16(xMatch),
+	/*9835*/ uint16(xCondDataSize), 9823, 9829, 9839,
+	/*9839*/ uint16(xSetOp), uint16(TEST),
 	/*9841*/ uint16(xReadSlashR),
-	/*9842*/ uint16(xArgRM16),
-	/*9843*/ uint16(xArgR16),
+	/*9842*/ uint16(xArgRM64),
+	/*9843*/ uint16(xArgR64),
 	/*9844*/ uint16(xMatch),
 	/*9845*/ uint16(xSetOp), uint16(XCHG),
 	/*9847*/ uint16(xReadSlashR),
-	/*9848*/ uint16(xArgRM32),
-	/*9849*/ uint16(xArgR32),
+	/*9848*/ uint16(xArgRM8),
+	/*9849*/ uint16(xArgR8),
 	/*9850*/ uint16(xMatch),
-	/*9851*/ uint16(xCondDataSize), 9839, 9845, 9855,
-	/*9855*/ uint16(xSetOp), uint16(XCHG),
-	/*9857*/ uint16(xReadSlashR),
-	/*9858*/ uint16(xArgRM64),
-	/*9859*/ uint16(xArgR64),
-	/*9860*/ uint16(xMatch),
-	/*9861*/ uint16(xSetOp), uint16(MOV),
-	/*9863*/ uint16(xReadSlashR),
-	/*9864*/ uint16(xArgRM8),
-	/*9865*/ uint16(xArgR8),
-	/*9866*/ uint16(xMatch),
-	/*9867*/ uint16(xCondDataSize), 9871, 9877, 9883,
-	/*9871*/ uint16(xSetOp), uint16(MOV),
-	/*9873*/ uint16(xReadSlashR),
-	/*9874*/ uint16(xArgRM16),
-	/*9875*/ uint16(xArgR16),
-	/*9876*/ uint16(xMatch),
-	/*9877*/ uint16(xSetOp), uint16(MOV),
-	/*9879*/ uint16(xReadSlashR),
-	/*9880*/ uint16(xArgRM32),
-	/*9881*/ uint16(xArgR32),
-	/*9882*/ uint16(xMatch),
-	/*9883*/ uint16(xSetOp), uint16(MOV),
-	/*9885*/ uint16(xReadSlashR),
-	/*9886*/ uint16(xArgRM64),
-	/*9887*/ uint16(xArgR64),
-	/*9888*/ uint16(xMatch),
-	/*9889*/ uint16(xSetOp), uint16(MOV),
-	/*9891*/ uint16(xReadSlashR),
-	/*9892*/ uint16(xArgR8),
-	/*9893*/ uint16(xArgRM8),
-	/*9894*/ uint16(xMatch),
-	/*9895*/ uint16(xCondDataSize), 9899, 9905, 9911,
-	/*9899*/ uint16(xSetOp), uint16(MOV),
-	/*9901*/ uint16(xReadSlashR),
-	/*9902*/ uint16(xArgR16),
-	/*9903*/ uint16(xArgRM16),
-	/*9904*/ uint16(xMatch),
-	/*9905*/ uint16(xSetOp), uint16(MOV),
-	/*9907*/ uint16(xReadSlashR),
-	/*9908*/ uint16(xArgR32),
-	/*9909*/ uint16(xArgRM32),
-	/*9910*/ uint16(xMatch),
-	/*9911*/ uint16(xSetOp), uint16(MOV),
-	/*9913*/ uint16(xReadSlashR),
-	/*9914*/ uint16(xArgR64),
-	/*9915*/ uint16(xArgRM64),
-	/*9916*/ uint16(xMatch),
-	/*9917*/ uint16(xCondIs64), 9920, 9936,
-	/*9920*/ uint16(xCondDataSize), 9924, 9930, 0,
+	/*9851*/ uint16(xCondIs64), 9854, 9870,
+	/*9854*/ uint16(xCondDataSize), 9858, 9864, 0,
+	/*9858*/ uint16(xSetOp), uint16(XCHG),
+	/*9860*/ uint16(xReadSlashR),
+	/*9861*/ uint16(xArgRM16),
+	/*9862*/ uint16(xArgR16),
+	/*9863*/ uint16(xMatch),
+	/*9864*/ uint16(xSetOp), uint16(XCHG),
+	/*9866*/ uint16(xReadSlashR),
+	/*9867*/ uint16(xArgRM32),
+	/*9868*/ uint16(xArgR32),
+	/*9869*/ uint16(xMatch),
+	/*9870*/ uint16(xCondDataSize), 9858, 9864, 9874,
+	/*9874*/ uint16(xSetOp), uint16(XCHG),
+	/*9876*/ uint16(xReadSlashR),
+	/*9877*/ uint16(xArgRM64),
+	/*9878*/ uint16(xArgR64),
+	/*9879*/ uint16(xMatch),
+	/*9880*/ uint16(xSetOp), uint16(MOV),
+	/*9882*/ uint16(xReadSlashR),
+	/*9883*/ uint16(xArgRM8),
+	/*9884*/ uint16(xArgR8),
+	/*9885*/ uint16(xMatch),
+	/*9886*/ uint16(xCondDataSize), 9890, 9896, 9902,
+	/*9890*/ uint16(xSetOp), uint16(MOV),
+	/*9892*/ uint16(xReadSlashR),
+	/*9893*/ uint16(xArgRM16),
+	/*9894*/ uint16(xArgR16),
+	/*9895*/ uint16(xMatch),
+	/*9896*/ uint16(xSetOp), uint16(MOV),
+	/*9898*/ uint16(xReadSlashR),
+	/*9899*/ uint16(xArgRM32),
+	/*9900*/ uint16(xArgR32),
+	/*9901*/ uint16(xMatch),
+	/*9902*/ uint16(xSetOp), uint16(MOV),
+	/*9904*/ uint16(xReadSlashR),
+	/*9905*/ uint16(xArgRM64),
+	/*9906*/ uint16(xArgR64),
+	/*9907*/ uint16(xMatch),
+	/*9908*/ uint16(xSetOp), uint16(MOV),
+	/*9910*/ uint16(xReadSlashR),
+	/*9911*/ uint16(xArgR8),
+	/*9912*/ uint16(xArgRM8),
+	/*9913*/ uint16(xMatch),
+	/*9914*/ uint16(xCondDataSize), 9918, 9924, 9930,
+	/*9918*/ uint16(xSetOp), uint16(MOV),
+	/*9920*/ uint16(xReadSlashR),
+	/*9921*/ uint16(xArgR16),
+	/*9922*/ uint16(xArgRM16),
+	/*9923*/ uint16(xMatch),
 	/*9924*/ uint16(xSetOp), uint16(MOV),
 	/*9926*/ uint16(xReadSlashR),
-	/*9927*/ uint16(xArgRM16),
-	/*9928*/ uint16(xArgSreg),
+	/*9927*/ uint16(xArgR32),
+	/*9928*/ uint16(xArgRM32),
 	/*9929*/ uint16(xMatch),
 	/*9930*/ uint16(xSetOp), uint16(MOV),
 	/*9932*/ uint16(xReadSlashR),
-	/*9933*/ uint16(xArgR32M16),
-	/*9934*/ uint16(xArgSreg),
+	/*9933*/ uint16(xArgR64),
+	/*9934*/ uint16(xArgRM64),
 	/*9935*/ uint16(xMatch),
-	/*9936*/ uint16(xCondDataSize), 9924, 9930, 9940,
-	/*9940*/ uint16(xSetOp), uint16(MOV),
-	/*9942*/ uint16(xReadSlashR),
-	/*9943*/ uint16(xArgR64M16),
-	/*9944*/ uint16(xArgSreg),
-	/*9945*/ uint16(xMatch),
-	/*9946*/ uint16(xCondIs64), 9949, 9965,
-	/*9949*/ uint16(xCondDataSize), 9953, 9959, 0,
-	/*9953*/ uint16(xSetOp), uint16(LEA),
-	/*9955*/ uint16(xReadSlashR),
-	/*9956*/ uint16(xArgR16),
-	/*9957*/ uint16(xArgM),
-	/*9958*/ uint16(xMatch),
-	/*9959*/ uint16(xSetOp), uint16(LEA),
+	/*9936*/ uint16(xCondIs64), 9939, 9955,
+	/*9939*/ uint16(xCondDataSize), 9943, 9949, 0,
+	/*9943*/ uint16(xSetOp), uint16(MOV),
+	/*9945*/ uint16(xReadSlashR),
+	/*9946*/ uint16(xArgRM16),
+	/*9947*/ uint16(xArgSreg),
+	/*9948*/ uint16(xMatch),
+	/*9949*/ uint16(xSetOp), uint16(MOV),
+	/*9951*/ uint16(xReadSlashR),
+	/*9952*/ uint16(xArgR32M16),
+	/*9953*/ uint16(xArgSreg),
+	/*9954*/ uint16(xMatch),
+	/*9955*/ uint16(xCondDataSize), 9943, 9949, 9959,
+	/*9959*/ uint16(xSetOp), uint16(MOV),
 	/*9961*/ uint16(xReadSlashR),
-	/*9962*/ uint16(xArgR32),
-	/*9963*/ uint16(xArgM),
+	/*9962*/ uint16(xArgR64M16),
+	/*9963*/ uint16(xArgSreg),
 	/*9964*/ uint16(xMatch),
-	/*9965*/ uint16(xCondDataSize), 9953, 9959, 9969,
-	/*9969*/ uint16(xSetOp), uint16(LEA),
-	/*9971*/ uint16(xReadSlashR),
-	/*9972*/ uint16(xArgR64),
-	/*9973*/ uint16(xArgM),
-	/*9974*/ uint16(xMatch),
-	/*9975*/ uint16(xCondIs64), 9978, 9994,
-	/*9978*/ uint16(xCondDataSize), 9982, 9988, 0,
-	/*9982*/ uint16(xSetOp), uint16(MOV),
-	/*9984*/ uint16(xReadSlashR),
-	/*9985*/ uint16(xArgSreg),
-	/*9986*/ uint16(xArgRM16),
-	/*9987*/ uint16(xMatch),
-	/*9988*/ uint16(xSetOp), uint16(MOV),
+	/*9965*/ uint16(xCondIs64), 9968, 9984,
+	/*9968*/ uint16(xCondDataSize), 9972, 9978, 0,
+	/*9972*/ uint16(xSetOp), uint16(LEA),
+	/*9974*/ uint16(xReadSlashR),
+	/*9975*/ uint16(xArgR16),
+	/*9976*/ uint16(xArgM),
+	/*9977*/ uint16(xMatch),
+	/*9978*/ uint16(xSetOp), uint16(LEA),
+	/*9980*/ uint16(xReadSlashR),
+	/*9981*/ uint16(xArgR32),
+	/*9982*/ uint16(xArgM),
+	/*9983*/ uint16(xMatch),
+	/*9984*/ uint16(xCondDataSize), 9972, 9978, 9988,
+	/*9988*/ uint16(xSetOp), uint16(LEA),
 	/*9990*/ uint16(xReadSlashR),
-	/*9991*/ uint16(xArgSreg),
-	/*9992*/ uint16(xArgR32M16),
+	/*9991*/ uint16(xArgR64),
+	/*9992*/ uint16(xArgM),
 	/*9993*/ uint16(xMatch),
-	/*9994*/ uint16(xCondDataSize), 9982, 9988, 9998,
-	/*9998*/ uint16(xSetOp), uint16(MOV),
-	/*10000*/ uint16(xReadSlashR),
-	/*10001*/ uint16(xArgSreg),
-	/*10002*/ uint16(xArgR64M16),
-	/*10003*/ uint16(xMatch),
-	/*10004*/ uint16(xCondSlashR),
-	10013, // 0
+	/*9994*/ uint16(xCondIs64), 9997, 10013,
+	/*9997*/ uint16(xCondDataSize), 10001, 10007, 0,
+	/*10001*/ uint16(xSetOp), uint16(MOV),
+	/*10003*/ uint16(xReadSlashR),
+	/*10004*/ uint16(xArgSreg),
+	/*10005*/ uint16(xArgRM16),
+	/*10006*/ uint16(xMatch),
+	/*10007*/ uint16(xSetOp), uint16(MOV),
+	/*10009*/ uint16(xReadSlashR),
+	/*10010*/ uint16(xArgSreg),
+	/*10011*/ uint16(xArgR32M16),
+	/*10012*/ uint16(xMatch),
+	/*10013*/ uint16(xCondDataSize), 10001, 10007, 10017,
+	/*10017*/ uint16(xSetOp), uint16(MOV),
+	/*10019*/ uint16(xReadSlashR),
+	/*10020*/ uint16(xArgSreg),
+	/*10021*/ uint16(xArgR64M16),
+	/*10022*/ uint16(xMatch),
+	/*10023*/ uint16(xCondSlashR),
+	10032, // 0
 	0,     // 1
 	0,     // 2
 	0,     // 3
@@ -6540,478 +6551,458 @@
 	0,     // 5
 	0,     // 6
 	0,     // 7
-	/*10013*/ uint16(xCondIs64), 10016, 10028,
-	/*10016*/ uint16(xCondDataSize), 10020, 10024, 0,
-	/*10020*/ uint16(xSetOp), uint16(POP),
-	/*10022*/ uint16(xArgRM16),
-	/*10023*/ uint16(xMatch),
-	/*10024*/ uint16(xSetOp), uint16(POP),
-	/*10026*/ uint16(xArgRM32),
-	/*10027*/ uint16(xMatch),
-	/*10028*/ uint16(xCondDataSize), 10020, 10032, 10036,
-	/*10032*/ uint16(xSetOp), uint16(POP),
-	/*10034*/ uint16(xArgRM64),
-	/*10035*/ uint16(xMatch),
-	/*10036*/ uint16(xSetOp), uint16(POP),
-	/*10038*/ uint16(xArgRM64),
-	/*10039*/ uint16(xMatch),
-	/*10040*/ uint16(xCondIs64), 10043, 10057,
-	/*10043*/ uint16(xCondDataSize), 10047, 10052, 0,
-	/*10047*/ uint16(xSetOp), uint16(XCHG),
-	/*10049*/ uint16(xArgR16op),
-	/*10050*/ uint16(xArgAX),
-	/*10051*/ uint16(xMatch),
-	/*10052*/ uint16(xSetOp), uint16(XCHG),
-	/*10054*/ uint16(xArgR32op),
-	/*10055*/ uint16(xArgEAX),
-	/*10056*/ uint16(xMatch),
-	/*10057*/ uint16(xCondDataSize), 10047, 10052, 10061,
-	/*10061*/ uint16(xSetOp), uint16(XCHG),
-	/*10063*/ uint16(xArgR64op),
-	/*10064*/ uint16(xArgRAX),
-	/*10065*/ uint16(xMatch),
-	/*10066*/ uint16(xCondIs64), 10069, 10079,
-	/*10069*/ uint16(xCondDataSize), 10073, 10076, 0,
-	/*10073*/ uint16(xSetOp), uint16(CBW),
+	/*10032*/ uint16(xCondIs64), 10035, 10047,
+	/*10035*/ uint16(xCondDataSize), 10039, 10043, 0,
+	/*10039*/ uint16(xSetOp), uint16(POP),
+	/*10041*/ uint16(xArgRM16),
+	/*10042*/ uint16(xMatch),
+	/*10043*/ uint16(xSetOp), uint16(POP),
+	/*10045*/ uint16(xArgRM32),
+	/*10046*/ uint16(xMatch),
+	/*10047*/ uint16(xCondDataSize), 10039, 10051, 10055,
+	/*10051*/ uint16(xSetOp), uint16(POP),
+	/*10053*/ uint16(xArgRM64),
+	/*10054*/ uint16(xMatch),
+	/*10055*/ uint16(xSetOp), uint16(POP),
+	/*10057*/ uint16(xArgRM64),
+	/*10058*/ uint16(xMatch),
+	/*10059*/ uint16(xCondIs64), 10062, 10076,
+	/*10062*/ uint16(xCondDataSize), 10066, 10071, 0,
+	/*10066*/ uint16(xSetOp), uint16(XCHG),
+	/*10068*/ uint16(xArgR16op),
+	/*10069*/ uint16(xArgAX),
+	/*10070*/ uint16(xMatch),
+	/*10071*/ uint16(xSetOp), uint16(XCHG),
+	/*10073*/ uint16(xArgR32op),
+	/*10074*/ uint16(xArgEAX),
 	/*10075*/ uint16(xMatch),
-	/*10076*/ uint16(xSetOp), uint16(CWDE),
-	/*10078*/ uint16(xMatch),
-	/*10079*/ uint16(xCondDataSize), 10073, 10076, 10083,
-	/*10083*/ uint16(xSetOp), uint16(CDQE),
-	/*10085*/ uint16(xMatch),
-	/*10086*/ uint16(xCondIs64), 10089, 10099,
-	/*10089*/ uint16(xCondDataSize), 10093, 10096, 0,
-	/*10093*/ uint16(xSetOp), uint16(CWD),
-	/*10095*/ uint16(xMatch),
-	/*10096*/ uint16(xSetOp), uint16(CDQ),
-	/*10098*/ uint16(xMatch),
-	/*10099*/ uint16(xCondDataSize), 10093, 10096, 10103,
-	/*10103*/ uint16(xSetOp), uint16(CQO),
-	/*10105*/ uint16(xMatch),
-	/*10106*/ uint16(xCondIs64), 10109, 0,
-	/*10109*/ uint16(xCondDataSize), 10113, 10118, 0,
-	/*10113*/ uint16(xSetOp), uint16(LCALL),
-	/*10115*/ uint16(xReadCd),
-	/*10116*/ uint16(xArgPtr16colon16),
+	/*10076*/ uint16(xCondDataSize), 10066, 10071, 10080,
+	/*10080*/ uint16(xSetOp), uint16(XCHG),
+	/*10082*/ uint16(xArgR64op),
+	/*10083*/ uint16(xArgRAX),
+	/*10084*/ uint16(xMatch),
+	/*10085*/ uint16(xCondIs64), 10088, 10098,
+	/*10088*/ uint16(xCondDataSize), 10092, 10095, 0,
+	/*10092*/ uint16(xSetOp), uint16(CBW),
+	/*10094*/ uint16(xMatch),
+	/*10095*/ uint16(xSetOp), uint16(CWDE),
+	/*10097*/ uint16(xMatch),
+	/*10098*/ uint16(xCondDataSize), 10092, 10095, 10102,
+	/*10102*/ uint16(xSetOp), uint16(CDQE),
+	/*10104*/ uint16(xMatch),
+	/*10105*/ uint16(xCondIs64), 10108, 10118,
+	/*10108*/ uint16(xCondDataSize), 10112, 10115, 0,
+	/*10112*/ uint16(xSetOp), uint16(CWD),
+	/*10114*/ uint16(xMatch),
+	/*10115*/ uint16(xSetOp), uint16(CDQ),
 	/*10117*/ uint16(xMatch),
-	/*10118*/ uint16(xSetOp), uint16(LCALL),
-	/*10120*/ uint16(xReadCp),
-	/*10121*/ uint16(xArgPtr16colon32),
-	/*10122*/ uint16(xMatch),
-	/*10123*/ uint16(xSetOp), uint16(FWAIT),
-	/*10125*/ uint16(xMatch),
-	/*10126*/ uint16(xCondIs64), 10129, 10139,
-	/*10129*/ uint16(xCondDataSize), 10133, 10136, 0,
-	/*10133*/ uint16(xSetOp), uint16(PUSHF),
-	/*10135*/ uint16(xMatch),
-	/*10136*/ uint16(xSetOp), uint16(PUSHFD),
-	/*10138*/ uint16(xMatch),
-	/*10139*/ uint16(xCondDataSize), 10133, 10143, 10146,
-	/*10143*/ uint16(xSetOp), uint16(PUSHFQ),
-	/*10145*/ uint16(xMatch),
-	/*10146*/ uint16(xSetOp), uint16(PUSHFQ),
-	/*10148*/ uint16(xMatch),
-	/*10149*/ uint16(xCondIs64), 10152, 10162,
-	/*10152*/ uint16(xCondDataSize), 10156, 10159, 0,
-	/*10156*/ uint16(xSetOp), uint16(POPF),
-	/*10158*/ uint16(xMatch),
-	/*10159*/ uint16(xSetOp), uint16(POPFD),
-	/*10161*/ uint16(xMatch),
-	/*10162*/ uint16(xCondDataSize), 10156, 10166, 10169,
-	/*10166*/ uint16(xSetOp), uint16(POPFQ),
-	/*10168*/ uint16(xMatch),
-	/*10169*/ uint16(xSetOp), uint16(POPFQ),
-	/*10171*/ uint16(xMatch),
-	/*10172*/ uint16(xSetOp), uint16(SAHF),
-	/*10174*/ uint16(xMatch),
-	/*10175*/ uint16(xSetOp), uint16(LAHF),
+	/*10118*/ uint16(xCondDataSize), 10112, 10115, 10122,
+	/*10122*/ uint16(xSetOp), uint16(CQO),
+	/*10124*/ uint16(xMatch),
+	/*10125*/ uint16(xCondIs64), 10128, 0,
+	/*10128*/ uint16(xCondDataSize), 10132, 10137, 0,
+	/*10132*/ uint16(xSetOp), uint16(LCALL),
+	/*10134*/ uint16(xReadCd),
+	/*10135*/ uint16(xArgPtr16colon16),
+	/*10136*/ uint16(xMatch),
+	/*10137*/ uint16(xSetOp), uint16(LCALL),
+	/*10139*/ uint16(xReadCp),
+	/*10140*/ uint16(xArgPtr16colon32),
+	/*10141*/ uint16(xMatch),
+	/*10142*/ uint16(xSetOp), uint16(FWAIT),
+	/*10144*/ uint16(xMatch),
+	/*10145*/ uint16(xCondIs64), 10148, 10158,
+	/*10148*/ uint16(xCondDataSize), 10152, 10155, 0,
+	/*10152*/ uint16(xSetOp), uint16(PUSHF),
+	/*10154*/ uint16(xMatch),
+	/*10155*/ uint16(xSetOp), uint16(PUSHFD),
+	/*10157*/ uint16(xMatch),
+	/*10158*/ uint16(xCondDataSize), 10152, 10162, 10165,
+	/*10162*/ uint16(xSetOp), uint16(PUSHFQ),
+	/*10164*/ uint16(xMatch),
+	/*10165*/ uint16(xSetOp), uint16(PUSHFQ),
+	/*10167*/ uint16(xMatch),
+	/*10168*/ uint16(xCondIs64), 10171, 10181,
+	/*10171*/ uint16(xCondDataSize), 10175, 10178, 0,
+	/*10175*/ uint16(xSetOp), uint16(POPF),
 	/*10177*/ uint16(xMatch),
-	/*10178*/ uint16(xCondIs64), 10181, 10187,
-	/*10181*/ uint16(xSetOp), uint16(MOV),
-	/*10183*/ uint16(xReadCm),
-	/*10184*/ uint16(xArgAL),
-	/*10185*/ uint16(xArgMoffs8),
-	/*10186*/ uint16(xMatch),
-	/*10187*/ uint16(xCondDataSize), 10181, 10181, 10191,
-	/*10191*/ uint16(xSetOp), uint16(MOV),
-	/*10193*/ uint16(xReadCm),
-	/*10194*/ uint16(xArgAL),
-	/*10195*/ uint16(xArgMoffs8),
+	/*10178*/ uint16(xSetOp), uint16(POPFD),
+	/*10180*/ uint16(xMatch),
+	/*10181*/ uint16(xCondDataSize), 10175, 10185, 10188,
+	/*10185*/ uint16(xSetOp), uint16(POPFQ),
+	/*10187*/ uint16(xMatch),
+	/*10188*/ uint16(xSetOp), uint16(POPFQ),
+	/*10190*/ uint16(xMatch),
+	/*10191*/ uint16(xSetOp), uint16(SAHF),
+	/*10193*/ uint16(xMatch),
+	/*10194*/ uint16(xSetOp), uint16(LAHF),
 	/*10196*/ uint16(xMatch),
-	/*10197*/ uint16(xCondDataSize), 10201, 10207, 10213,
-	/*10201*/ uint16(xSetOp), uint16(MOV),
-	/*10203*/ uint16(xReadCm),
-	/*10204*/ uint16(xArgAX),
-	/*10205*/ uint16(xArgMoffs16),
-	/*10206*/ uint16(xMatch),
-	/*10207*/ uint16(xSetOp), uint16(MOV),
-	/*10209*/ uint16(xReadCm),
-	/*10210*/ uint16(xArgEAX),
-	/*10211*/ uint16(xArgMoffs32),
-	/*10212*/ uint16(xMatch),
-	/*10213*/ uint16(xSetOp), uint16(MOV),
-	/*10215*/ uint16(xReadCm),
-	/*10216*/ uint16(xArgRAX),
-	/*10217*/ uint16(xArgMoffs64),
-	/*10218*/ uint16(xMatch),
-	/*10219*/ uint16(xCondIs64), 10222, 10228,
-	/*10222*/ uint16(xSetOp), uint16(MOV),
-	/*10224*/ uint16(xReadCm),
-	/*10225*/ uint16(xArgMoffs8),
-	/*10226*/ uint16(xArgAL),
-	/*10227*/ uint16(xMatch),
-	/*10228*/ uint16(xCondDataSize), 10222, 10222, 10232,
+	/*10197*/ uint16(xCondIs64), 10200, 10206,
+	/*10200*/ uint16(xSetOp), uint16(MOV),
+	/*10202*/ uint16(xReadCm),
+	/*10203*/ uint16(xArgAL),
+	/*10204*/ uint16(xArgMoffs8),
+	/*10205*/ uint16(xMatch),
+	/*10206*/ uint16(xCondDataSize), 10200, 10200, 10210,
+	/*10210*/ uint16(xSetOp), uint16(MOV),
+	/*10212*/ uint16(xReadCm),
+	/*10213*/ uint16(xArgAL),
+	/*10214*/ uint16(xArgMoffs8),
+	/*10215*/ uint16(xMatch),
+	/*10216*/ uint16(xCondDataSize), 10220, 10226, 10232,
+	/*10220*/ uint16(xSetOp), uint16(MOV),
+	/*10222*/ uint16(xReadCm),
+	/*10223*/ uint16(xArgAX),
+	/*10224*/ uint16(xArgMoffs16),
+	/*10225*/ uint16(xMatch),
+	/*10226*/ uint16(xSetOp), uint16(MOV),
+	/*10228*/ uint16(xReadCm),
+	/*10229*/ uint16(xArgEAX),
+	/*10230*/ uint16(xArgMoffs32),
+	/*10231*/ uint16(xMatch),
 	/*10232*/ uint16(xSetOp), uint16(MOV),
 	/*10234*/ uint16(xReadCm),
-	/*10235*/ uint16(xArgMoffs8),
-	/*10236*/ uint16(xArgAL),
+	/*10235*/ uint16(xArgRAX),
+	/*10236*/ uint16(xArgMoffs64),
 	/*10237*/ uint16(xMatch),
-	/*10238*/ uint16(xCondDataSize), 10242, 10248, 10254,
-	/*10242*/ uint16(xSetOp), uint16(MOV),
-	/*10244*/ uint16(xReadCm),
-	/*10245*/ uint16(xArgMoffs16),
-	/*10246*/ uint16(xArgAX),
-	/*10247*/ uint16(xMatch),
-	/*10248*/ uint16(xSetOp), uint16(MOV),
-	/*10250*/ uint16(xReadCm),
-	/*10251*/ uint16(xArgMoffs32),
-	/*10252*/ uint16(xArgEAX),
-	/*10253*/ uint16(xMatch),
-	/*10254*/ uint16(xSetOp), uint16(MOV),
-	/*10256*/ uint16(xReadCm),
-	/*10257*/ uint16(xArgMoffs64),
-	/*10258*/ uint16(xArgRAX),
-	/*10259*/ uint16(xMatch),
-	/*10260*/ uint16(xSetOp), uint16(MOVSB),
-	/*10262*/ uint16(xMatch),
-	/*10263*/ uint16(xCondIs64), 10266, 10276,
-	/*10266*/ uint16(xCondDataSize), 10270, 10273, 0,
-	/*10270*/ uint16(xSetOp), uint16(MOVSW),
+	/*10238*/ uint16(xCondIs64), 10241, 10247,
+	/*10241*/ uint16(xSetOp), uint16(MOV),
+	/*10243*/ uint16(xReadCm),
+	/*10244*/ uint16(xArgMoffs8),
+	/*10245*/ uint16(xArgAL),
+	/*10246*/ uint16(xMatch),
+	/*10247*/ uint16(xCondDataSize), 10241, 10241, 10251,
+	/*10251*/ uint16(xSetOp), uint16(MOV),
+	/*10253*/ uint16(xReadCm),
+	/*10254*/ uint16(xArgMoffs8),
+	/*10255*/ uint16(xArgAL),
+	/*10256*/ uint16(xMatch),
+	/*10257*/ uint16(xCondDataSize), 10261, 10267, 10273,
+	/*10261*/ uint16(xSetOp), uint16(MOV),
+	/*10263*/ uint16(xReadCm),
+	/*10264*/ uint16(xArgMoffs16),
+	/*10265*/ uint16(xArgAX),
+	/*10266*/ uint16(xMatch),
+	/*10267*/ uint16(xSetOp), uint16(MOV),
+	/*10269*/ uint16(xReadCm),
+	/*10270*/ uint16(xArgMoffs32),
+	/*10271*/ uint16(xArgEAX),
 	/*10272*/ uint16(xMatch),
-	/*10273*/ uint16(xSetOp), uint16(MOVSD),
-	/*10275*/ uint16(xMatch),
-	/*10276*/ uint16(xCondDataSize), 10270, 10273, 10280,
-	/*10280*/ uint16(xSetOp), uint16(MOVSQ),
-	/*10282*/ uint16(xMatch),
-	/*10283*/ uint16(xSetOp), uint16(CMPSB),
-	/*10285*/ uint16(xMatch),
-	/*10286*/ uint16(xCondIs64), 10289, 10299,
-	/*10289*/ uint16(xCondDataSize), 10293, 10296, 0,
-	/*10293*/ uint16(xSetOp), uint16(CMPSW),
-	/*10295*/ uint16(xMatch),
-	/*10296*/ uint16(xSetOp), uint16(CMPSD),
-	/*10298*/ uint16(xMatch),
-	/*10299*/ uint16(xCondDataSize), 10293, 10296, 10303,
-	/*10303*/ uint16(xSetOp), uint16(CMPSQ),
-	/*10305*/ uint16(xMatch),
-	/*10306*/ uint16(xSetOp), uint16(TEST),
-	/*10308*/ uint16(xReadIb),
-	/*10309*/ uint16(xArgAL),
-	/*10310*/ uint16(xArgImm8u),
-	/*10311*/ uint16(xMatch),
-	/*10312*/ uint16(xCondIs64), 10315, 10331,
-	/*10315*/ uint16(xCondDataSize), 10319, 10325, 0,
-	/*10319*/ uint16(xSetOp), uint16(TEST),
-	/*10321*/ uint16(xReadIw),
-	/*10322*/ uint16(xArgAX),
-	/*10323*/ uint16(xArgImm16),
+	/*10273*/ uint16(xSetOp), uint16(MOV),
+	/*10275*/ uint16(xReadCm),
+	/*10276*/ uint16(xArgMoffs64),
+	/*10277*/ uint16(xArgRAX),
+	/*10278*/ uint16(xMatch),
+	/*10279*/ uint16(xSetOp), uint16(MOVSB),
+	/*10281*/ uint16(xMatch),
+	/*10282*/ uint16(xCondIs64), 10285, 10295,
+	/*10285*/ uint16(xCondDataSize), 10289, 10292, 0,
+	/*10289*/ uint16(xSetOp), uint16(MOVSW),
+	/*10291*/ uint16(xMatch),
+	/*10292*/ uint16(xSetOp), uint16(MOVSD),
+	/*10294*/ uint16(xMatch),
+	/*10295*/ uint16(xCondDataSize), 10289, 10292, 10299,
+	/*10299*/ uint16(xSetOp), uint16(MOVSQ),
+	/*10301*/ uint16(xMatch),
+	/*10302*/ uint16(xSetOp), uint16(CMPSB),
+	/*10304*/ uint16(xMatch),
+	/*10305*/ uint16(xCondIs64), 10308, 10318,
+	/*10308*/ uint16(xCondDataSize), 10312, 10315, 0,
+	/*10312*/ uint16(xSetOp), uint16(CMPSW),
+	/*10314*/ uint16(xMatch),
+	/*10315*/ uint16(xSetOp), uint16(CMPSD),
+	/*10317*/ uint16(xMatch),
+	/*10318*/ uint16(xCondDataSize), 10312, 10315, 10322,
+	/*10322*/ uint16(xSetOp), uint16(CMPSQ),
 	/*10324*/ uint16(xMatch),
 	/*10325*/ uint16(xSetOp), uint16(TEST),
-	/*10327*/ uint16(xReadId),
-	/*10328*/ uint16(xArgEAX),
-	/*10329*/ uint16(xArgImm32),
+	/*10327*/ uint16(xReadIb),
+	/*10328*/ uint16(xArgAL),
+	/*10329*/ uint16(xArgImm8u),
 	/*10330*/ uint16(xMatch),
-	/*10331*/ uint16(xCondDataSize), 10319, 10325, 10335,
-	/*10335*/ uint16(xSetOp), uint16(TEST),
-	/*10337*/ uint16(xReadId),
-	/*10338*/ uint16(xArgRAX),
-	/*10339*/ uint16(xArgImm32),
-	/*10340*/ uint16(xMatch),
-	/*10341*/ uint16(xSetOp), uint16(STOSB),
+	/*10331*/ uint16(xCondIs64), 10334, 10350,
+	/*10334*/ uint16(xCondDataSize), 10338, 10344, 0,
+	/*10338*/ uint16(xSetOp), uint16(TEST),
+	/*10340*/ uint16(xReadIw),
+	/*10341*/ uint16(xArgAX),
+	/*10342*/ uint16(xArgImm16),
 	/*10343*/ uint16(xMatch),
-	/*10344*/ uint16(xCondIs64), 10347, 10357,
-	/*10347*/ uint16(xCondDataSize), 10351, 10354, 0,
-	/*10351*/ uint16(xSetOp), uint16(STOSW),
-	/*10353*/ uint16(xMatch),
-	/*10354*/ uint16(xSetOp), uint16(STOSD),
-	/*10356*/ uint16(xMatch),
-	/*10357*/ uint16(xCondDataSize), 10351, 10354, 10361,
-	/*10361*/ uint16(xSetOp), uint16(STOSQ),
-	/*10363*/ uint16(xMatch),
-	/*10364*/ uint16(xSetOp), uint16(LODSB),
-	/*10366*/ uint16(xMatch),
-	/*10367*/ uint16(xCondIs64), 10370, 10380,
-	/*10370*/ uint16(xCondDataSize), 10374, 10377, 0,
-	/*10374*/ uint16(xSetOp), uint16(LODSW),
-	/*10376*/ uint16(xMatch),
-	/*10377*/ uint16(xSetOp), uint16(LODSD),
-	/*10379*/ uint16(xMatch),
-	/*10380*/ uint16(xCondDataSize), 10374, 10377, 10384,
-	/*10384*/ uint16(xSetOp), uint16(LODSQ),
-	/*10386*/ uint16(xMatch),
-	/*10387*/ uint16(xSetOp), uint16(SCASB),
-	/*10389*/ uint16(xMatch),
-	/*10390*/ uint16(xCondIs64), 10393, 10403,
-	/*10393*/ uint16(xCondDataSize), 10397, 10400, 0,
-	/*10397*/ uint16(xSetOp), uint16(SCASW),
-	/*10399*/ uint16(xMatch),
-	/*10400*/ uint16(xSetOp), uint16(SCASD),
-	/*10402*/ uint16(xMatch),
-	/*10403*/ uint16(xCondDataSize), 10397, 10400, 10407,
-	/*10407*/ uint16(xSetOp), uint16(SCASQ),
-	/*10409*/ uint16(xMatch),
-	/*10410*/ uint16(xSetOp), uint16(MOV),
-	/*10412*/ uint16(xReadIb),
-	/*10413*/ uint16(xArgR8op),
-	/*10414*/ uint16(xArgImm8u),
-	/*10415*/ uint16(xMatch),
-	/*10416*/ uint16(xCondIs64), 10419, 10435,
-	/*10419*/ uint16(xCondDataSize), 10423, 10429, 0,
-	/*10423*/ uint16(xSetOp), uint16(MOV),
-	/*10425*/ uint16(xReadIw),
-	/*10426*/ uint16(xArgR16op),
-	/*10427*/ uint16(xArgImm16),
+	/*10344*/ uint16(xSetOp), uint16(TEST),
+	/*10346*/ uint16(xReadId),
+	/*10347*/ uint16(xArgEAX),
+	/*10348*/ uint16(xArgImm32),
+	/*10349*/ uint16(xMatch),
+	/*10350*/ uint16(xCondDataSize), 10338, 10344, 10354,
+	/*10354*/ uint16(xSetOp), uint16(TEST),
+	/*10356*/ uint16(xReadId),
+	/*10357*/ uint16(xArgRAX),
+	/*10358*/ uint16(xArgImm32),
+	/*10359*/ uint16(xMatch),
+	/*10360*/ uint16(xSetOp), uint16(STOSB),
+	/*10362*/ uint16(xMatch),
+	/*10363*/ uint16(xCondIs64), 10366, 10376,
+	/*10366*/ uint16(xCondDataSize), 10370, 10373, 0,
+	/*10370*/ uint16(xSetOp), uint16(STOSW),
+	/*10372*/ uint16(xMatch),
+	/*10373*/ uint16(xSetOp), uint16(STOSD),
+	/*10375*/ uint16(xMatch),
+	/*10376*/ uint16(xCondDataSize), 10370, 10373, 10380,
+	/*10380*/ uint16(xSetOp), uint16(STOSQ),
+	/*10382*/ uint16(xMatch),
+	/*10383*/ uint16(xSetOp), uint16(LODSB),
+	/*10385*/ uint16(xMatch),
+	/*10386*/ uint16(xCondIs64), 10389, 10399,
+	/*10389*/ uint16(xCondDataSize), 10393, 10396, 0,
+	/*10393*/ uint16(xSetOp), uint16(LODSW),
+	/*10395*/ uint16(xMatch),
+	/*10396*/ uint16(xSetOp), uint16(LODSD),
+	/*10398*/ uint16(xMatch),
+	/*10399*/ uint16(xCondDataSize), 10393, 10396, 10403,
+	/*10403*/ uint16(xSetOp), uint16(LODSQ),
+	/*10405*/ uint16(xMatch),
+	/*10406*/ uint16(xSetOp), uint16(SCASB),
+	/*10408*/ uint16(xMatch),
+	/*10409*/ uint16(xCondIs64), 10412, 10422,
+	/*10412*/ uint16(xCondDataSize), 10416, 10419, 0,
+	/*10416*/ uint16(xSetOp), uint16(SCASW),
+	/*10418*/ uint16(xMatch),
+	/*10419*/ uint16(xSetOp), uint16(SCASD),
+	/*10421*/ uint16(xMatch),
+	/*10422*/ uint16(xCondDataSize), 10416, 10419, 10426,
+	/*10426*/ uint16(xSetOp), uint16(SCASQ),
 	/*10428*/ uint16(xMatch),
 	/*10429*/ uint16(xSetOp), uint16(MOV),
-	/*10431*/ uint16(xReadId),
-	/*10432*/ uint16(xArgR32op),
-	/*10433*/ uint16(xArgImm32),
+	/*10431*/ uint16(xReadIb),
+	/*10432*/ uint16(xArgR8op),
+	/*10433*/ uint16(xArgImm8u),
 	/*10434*/ uint16(xMatch),
-	/*10435*/ uint16(xCondDataSize), 10423, 10429, 10439,
-	/*10439*/ uint16(xSetOp), uint16(MOV),
-	/*10441*/ uint16(xReadIo),
-	/*10442*/ uint16(xArgR64op),
-	/*10443*/ uint16(xArgImm64),
-	/*10444*/ uint16(xMatch),
-	/*10445*/ uint16(xCondSlashR),
-	10454, // 0
-	10460, // 1
-	10466, // 2
-	10472, // 3
-	10478, // 4
-	10484, // 5
+	/*10435*/ uint16(xCondIs64), 10438, 10454,
+	/*10438*/ uint16(xCondDataSize), 10442, 10448, 0,
+	/*10442*/ uint16(xSetOp), uint16(MOV),
+	/*10444*/ uint16(xReadIw),
+	/*10445*/ uint16(xArgR16op),
+	/*10446*/ uint16(xArgImm16),
+	/*10447*/ uint16(xMatch),
+	/*10448*/ uint16(xSetOp), uint16(MOV),
+	/*10450*/ uint16(xReadId),
+	/*10451*/ uint16(xArgR32op),
+	/*10452*/ uint16(xArgImm32),
+	/*10453*/ uint16(xMatch),
+	/*10454*/ uint16(xCondDataSize), 10442, 10448, 10458,
+	/*10458*/ uint16(xSetOp), uint16(MOV),
+	/*10460*/ uint16(xReadIo),
+	/*10461*/ uint16(xArgR64op),
+	/*10462*/ uint16(xArgImm64),
+	/*10463*/ uint16(xMatch),
+	/*10464*/ uint16(xCondSlashR),
+	10473, // 0
+	10479, // 1
+	10485, // 2
+	10491, // 3
+	10497, // 4
+	10503, // 5
 	0,     // 6
-	10490, // 7
-	/*10454*/ uint16(xSetOp), uint16(ROL),
-	/*10456*/ uint16(xReadIb),
-	/*10457*/ uint16(xArgRM8),
-	/*10458*/ uint16(xArgImm8u),
-	/*10459*/ uint16(xMatch),
-	/*10460*/ uint16(xSetOp), uint16(ROR),
-	/*10462*/ uint16(xReadIb),
-	/*10463*/ uint16(xArgRM8),
-	/*10464*/ uint16(xArgImm8u),
-	/*10465*/ uint16(xMatch),
-	/*10466*/ uint16(xSetOp), uint16(RCL),
-	/*10468*/ uint16(xReadIb),
-	/*10469*/ uint16(xArgRM8),
-	/*10470*/ uint16(xArgImm8u),
-	/*10471*/ uint16(xMatch),
-	/*10472*/ uint16(xSetOp), uint16(RCR),
-	/*10474*/ uint16(xReadIb),
-	/*10475*/ uint16(xArgRM8),
-	/*10476*/ uint16(xArgImm8u),
-	/*10477*/ uint16(xMatch),
-	/*10478*/ uint16(xSetOp), uint16(SHL),
-	/*10480*/ uint16(xReadIb),
-	/*10481*/ uint16(xArgRM8),
-	/*10482*/ uint16(xArgImm8u),
-	/*10483*/ uint16(xMatch),
-	/*10484*/ uint16(xSetOp), uint16(SHR),
-	/*10486*/ uint16(xReadIb),
-	/*10487*/ uint16(xArgRM8),
-	/*10488*/ uint16(xArgImm8u),
-	/*10489*/ uint16(xMatch),
-	/*10490*/ uint16(xSetOp), uint16(SAR),
-	/*10492*/ uint16(xReadIb),
-	/*10493*/ uint16(xArgRM8),
-	/*10494*/ uint16(xArgImm8u),
-	/*10495*/ uint16(xMatch),
-	/*10496*/ uint16(xCondSlashR),
-	10505, // 0
-	10527, // 1
-	10549, // 2
-	10578, // 3
-	10607, // 4
-	10636, // 5
-	0,     // 6
-	10665, // 7
-	/*10505*/ uint16(xCondDataSize), 10509, 10515, 10521,
-	/*10509*/ uint16(xSetOp), uint16(ROL),
+	10509, // 7
+	/*10473*/ uint16(xSetOp), uint16(ROL),
+	/*10475*/ uint16(xReadIb),
+	/*10476*/ uint16(xArgRM8),
+	/*10477*/ uint16(xArgImm8u),
+	/*10478*/ uint16(xMatch),
+	/*10479*/ uint16(xSetOp), uint16(ROR),
+	/*10481*/ uint16(xReadIb),
+	/*10482*/ uint16(xArgRM8),
+	/*10483*/ uint16(xArgImm8u),
+	/*10484*/ uint16(xMatch),
+	/*10485*/ uint16(xSetOp), uint16(RCL),
+	/*10487*/ uint16(xReadIb),
+	/*10488*/ uint16(xArgRM8),
+	/*10489*/ uint16(xArgImm8u),
+	/*10490*/ uint16(xMatch),
+	/*10491*/ uint16(xSetOp), uint16(RCR),
+	/*10493*/ uint16(xReadIb),
+	/*10494*/ uint16(xArgRM8),
+	/*10495*/ uint16(xArgImm8u),
+	/*10496*/ uint16(xMatch),
+	/*10497*/ uint16(xSetOp), uint16(SHL),
+	/*10499*/ uint16(xReadIb),
+	/*10500*/ uint16(xArgRM8),
+	/*10501*/ uint16(xArgImm8u),
+	/*10502*/ uint16(xMatch),
+	/*10503*/ uint16(xSetOp), uint16(SHR),
+	/*10505*/ uint16(xReadIb),
+	/*10506*/ uint16(xArgRM8),
+	/*10507*/ uint16(xArgImm8u),
+	/*10508*/ uint16(xMatch),
+	/*10509*/ uint16(xSetOp), uint16(SAR),
 	/*10511*/ uint16(xReadIb),
-	/*10512*/ uint16(xArgRM16),
+	/*10512*/ uint16(xArgRM8),
 	/*10513*/ uint16(xArgImm8u),
 	/*10514*/ uint16(xMatch),
-	/*10515*/ uint16(xSetOp), uint16(ROL),
-	/*10517*/ uint16(xReadIb),
-	/*10518*/ uint16(xArgRM32),
-	/*10519*/ uint16(xArgImm8u),
-	/*10520*/ uint16(xMatch),
-	/*10521*/ uint16(xSetOp), uint16(ROL),
-	/*10523*/ uint16(xReadIb),
-	/*10524*/ uint16(xArgRM64),
-	/*10525*/ uint16(xArgImm8u),
-	/*10526*/ uint16(xMatch),
-	/*10527*/ uint16(xCondDataSize), 10531, 10537, 10543,
-	/*10531*/ uint16(xSetOp), uint16(ROR),
-	/*10533*/ uint16(xReadIb),
-	/*10534*/ uint16(xArgRM16),
-	/*10535*/ uint16(xArgImm8u),
-	/*10536*/ uint16(xMatch),
-	/*10537*/ uint16(xSetOp), uint16(ROR),
-	/*10539*/ uint16(xReadIb),
-	/*10540*/ uint16(xArgRM32),
-	/*10541*/ uint16(xArgImm8u),
-	/*10542*/ uint16(xMatch),
-	/*10543*/ uint16(xSetOp), uint16(ROR),
-	/*10545*/ uint16(xReadIb),
-	/*10546*/ uint16(xArgRM64),
-	/*10547*/ uint16(xArgImm8u),
-	/*10548*/ uint16(xMatch),
-	/*10549*/ uint16(xCondIs64), 10552, 10568,
-	/*10552*/ uint16(xCondDataSize), 10556, 10562, 0,
-	/*10556*/ uint16(xSetOp), uint16(RCL),
+	/*10515*/ uint16(xCondSlashR),
+	10524, // 0
+	10546, // 1
+	10568, // 2
+	10597, // 3
+	10626, // 4
+	10655, // 5
+	0,     // 6
+	10684, // 7
+	/*10524*/ uint16(xCondDataSize), 10528, 10534, 10540,
+	/*10528*/ uint16(xSetOp), uint16(ROL),
+	/*10530*/ uint16(xReadIb),
+	/*10531*/ uint16(xArgRM16),
+	/*10532*/ uint16(xArgImm8u),
+	/*10533*/ uint16(xMatch),
+	/*10534*/ uint16(xSetOp), uint16(ROL),
+	/*10536*/ uint16(xReadIb),
+	/*10537*/ uint16(xArgRM32),
+	/*10538*/ uint16(xArgImm8u),
+	/*10539*/ uint16(xMatch),
+	/*10540*/ uint16(xSetOp), uint16(ROL),
+	/*10542*/ uint16(xReadIb),
+	/*10543*/ uint16(xArgRM64),
+	/*10544*/ uint16(xArgImm8u),
+	/*10545*/ uint16(xMatch),
+	/*10546*/ uint16(xCondDataSize), 10550, 10556, 10562,
+	/*10550*/ uint16(xSetOp), uint16(ROR),
+	/*10552*/ uint16(xReadIb),
+	/*10553*/ uint16(xArgRM16),
+	/*10554*/ uint16(xArgImm8u),
+	/*10555*/ uint16(xMatch),
+	/*10556*/ uint16(xSetOp), uint16(ROR),
 	/*10558*/ uint16(xReadIb),
-	/*10559*/ uint16(xArgRM16),
+	/*10559*/ uint16(xArgRM32),
 	/*10560*/ uint16(xArgImm8u),
 	/*10561*/ uint16(xMatch),
-	/*10562*/ uint16(xSetOp), uint16(RCL),
+	/*10562*/ uint16(xSetOp), uint16(ROR),
 	/*10564*/ uint16(xReadIb),
-	/*10565*/ uint16(xArgRM32),
+	/*10565*/ uint16(xArgRM64),
 	/*10566*/ uint16(xArgImm8u),
 	/*10567*/ uint16(xMatch),
-	/*10568*/ uint16(xCondDataSize), 10556, 10562, 10572,
-	/*10572*/ uint16(xSetOp), uint16(RCL),
-	/*10574*/ uint16(xReadIb),
-	/*10575*/ uint16(xArgRM64),
-	/*10576*/ uint16(xArgImm8u),
-	/*10577*/ uint16(xMatch),
-	/*10578*/ uint16(xCondIs64), 10581, 10597,
-	/*10581*/ uint16(xCondDataSize), 10585, 10591, 0,
-	/*10585*/ uint16(xSetOp), uint16(RCR),
-	/*10587*/ uint16(xReadIb),
-	/*10588*/ uint16(xArgRM16),
-	/*10589*/ uint16(xArgImm8u),
-	/*10590*/ uint16(xMatch),
-	/*10591*/ uint16(xSetOp), uint16(RCR),
+	/*10568*/ uint16(xCondIs64), 10571, 10587,
+	/*10571*/ uint16(xCondDataSize), 10575, 10581, 0,
+	/*10575*/ uint16(xSetOp), uint16(RCL),
+	/*10577*/ uint16(xReadIb),
+	/*10578*/ uint16(xArgRM16),
+	/*10579*/ uint16(xArgImm8u),
+	/*10580*/ uint16(xMatch),
+	/*10581*/ uint16(xSetOp), uint16(RCL),
+	/*10583*/ uint16(xReadIb),
+	/*10584*/ uint16(xArgRM32),
+	/*10585*/ uint16(xArgImm8u),
+	/*10586*/ uint16(xMatch),
+	/*10587*/ uint16(xCondDataSize), 10575, 10581, 10591,
+	/*10591*/ uint16(xSetOp), uint16(RCL),
 	/*10593*/ uint16(xReadIb),
-	/*10594*/ uint16(xArgRM32),
+	/*10594*/ uint16(xArgRM64),
 	/*10595*/ uint16(xArgImm8u),
 	/*10596*/ uint16(xMatch),
-	/*10597*/ uint16(xCondDataSize), 10585, 10591, 10601,
-	/*10601*/ uint16(xSetOp), uint16(RCR),
-	/*10603*/ uint16(xReadIb),
-	/*10604*/ uint16(xArgRM64),
-	/*10605*/ uint16(xArgImm8u),
-	/*10606*/ uint16(xMatch),
-	/*10607*/ uint16(xCondIs64), 10610, 10626,
-	/*10610*/ uint16(xCondDataSize), 10614, 10620, 0,
-	/*10614*/ uint16(xSetOp), uint16(SHL),
-	/*10616*/ uint16(xReadIb),
-	/*10617*/ uint16(xArgRM16),
-	/*10618*/ uint16(xArgImm8u),
-	/*10619*/ uint16(xMatch),
-	/*10620*/ uint16(xSetOp), uint16(SHL),
+	/*10597*/ uint16(xCondIs64), 10600, 10616,
+	/*10600*/ uint16(xCondDataSize), 10604, 10610, 0,
+	/*10604*/ uint16(xSetOp), uint16(RCR),
+	/*10606*/ uint16(xReadIb),
+	/*10607*/ uint16(xArgRM16),
+	/*10608*/ uint16(xArgImm8u),
+	/*10609*/ uint16(xMatch),
+	/*10610*/ uint16(xSetOp), uint16(RCR),
+	/*10612*/ uint16(xReadIb),
+	/*10613*/ uint16(xArgRM32),
+	/*10614*/ uint16(xArgImm8u),
+	/*10615*/ uint16(xMatch),
+	/*10616*/ uint16(xCondDataSize), 10604, 10610, 10620,
+	/*10620*/ uint16(xSetOp), uint16(RCR),
 	/*10622*/ uint16(xReadIb),
-	/*10623*/ uint16(xArgRM32),
+	/*10623*/ uint16(xArgRM64),
 	/*10624*/ uint16(xArgImm8u),
 	/*10625*/ uint16(xMatch),
-	/*10626*/ uint16(xCondDataSize), 10614, 10620, 10630,
-	/*10630*/ uint16(xSetOp), uint16(SHL),
-	/*10632*/ uint16(xReadIb),
-	/*10633*/ uint16(xArgRM64),
-	/*10634*/ uint16(xArgImm8u),
-	/*10635*/ uint16(xMatch),
-	/*10636*/ uint16(xCondIs64), 10639, 10655,
-	/*10639*/ uint16(xCondDataSize), 10643, 10649, 0,
-	/*10643*/ uint16(xSetOp), uint16(SHR),
-	/*10645*/ uint16(xReadIb),
-	/*10646*/ uint16(xArgRM16),
-	/*10647*/ uint16(xArgImm8u),
-	/*10648*/ uint16(xMatch),
-	/*10649*/ uint16(xSetOp), uint16(SHR),
+	/*10626*/ uint16(xCondIs64), 10629, 10645,
+	/*10629*/ uint16(xCondDataSize), 10633, 10639, 0,
+	/*10633*/ uint16(xSetOp), uint16(SHL),
+	/*10635*/ uint16(xReadIb),
+	/*10636*/ uint16(xArgRM16),
+	/*10637*/ uint16(xArgImm8u),
+	/*10638*/ uint16(xMatch),
+	/*10639*/ uint16(xSetOp), uint16(SHL),
+	/*10641*/ uint16(xReadIb),
+	/*10642*/ uint16(xArgRM32),
+	/*10643*/ uint16(xArgImm8u),
+	/*10644*/ uint16(xMatch),
+	/*10645*/ uint16(xCondDataSize), 10633, 10639, 10649,
+	/*10649*/ uint16(xSetOp), uint16(SHL),
 	/*10651*/ uint16(xReadIb),
-	/*10652*/ uint16(xArgRM32),
+	/*10652*/ uint16(xArgRM64),
 	/*10653*/ uint16(xArgImm8u),
 	/*10654*/ uint16(xMatch),
-	/*10655*/ uint16(xCondDataSize), 10643, 10649, 10659,
-	/*10659*/ uint16(xSetOp), uint16(SHR),
-	/*10661*/ uint16(xReadIb),
-	/*10662*/ uint16(xArgRM64),
-	/*10663*/ uint16(xArgImm8u),
-	/*10664*/ uint16(xMatch),
-	/*10665*/ uint16(xCondIs64), 10668, 10684,
-	/*10668*/ uint16(xCondDataSize), 10672, 10678, 0,
-	/*10672*/ uint16(xSetOp), uint16(SAR),
-	/*10674*/ uint16(xReadIb),
-	/*10675*/ uint16(xArgRM16),
-	/*10676*/ uint16(xArgImm8u),
-	/*10677*/ uint16(xMatch),
-	/*10678*/ uint16(xSetOp), uint16(SAR),
+	/*10655*/ uint16(xCondIs64), 10658, 10674,
+	/*10658*/ uint16(xCondDataSize), 10662, 10668, 0,
+	/*10662*/ uint16(xSetOp), uint16(SHR),
+	/*10664*/ uint16(xReadIb),
+	/*10665*/ uint16(xArgRM16),
+	/*10666*/ uint16(xArgImm8u),
+	/*10667*/ uint16(xMatch),
+	/*10668*/ uint16(xSetOp), uint16(SHR),
+	/*10670*/ uint16(xReadIb),
+	/*10671*/ uint16(xArgRM32),
+	/*10672*/ uint16(xArgImm8u),
+	/*10673*/ uint16(xMatch),
+	/*10674*/ uint16(xCondDataSize), 10662, 10668, 10678,
+	/*10678*/ uint16(xSetOp), uint16(SHR),
 	/*10680*/ uint16(xReadIb),
-	/*10681*/ uint16(xArgRM32),
+	/*10681*/ uint16(xArgRM64),
 	/*10682*/ uint16(xArgImm8u),
 	/*10683*/ uint16(xMatch),
-	/*10684*/ uint16(xCondDataSize), 10672, 10678, 10688,
-	/*10688*/ uint16(xSetOp), uint16(SAR),
-	/*10690*/ uint16(xReadIb),
-	/*10691*/ uint16(xArgRM64),
-	/*10692*/ uint16(xArgImm8u),
-	/*10693*/ uint16(xMatch),
-	/*10694*/ uint16(xSetOp), uint16(RET),
-	/*10696*/ uint16(xReadIw),
-	/*10697*/ uint16(xArgImm16u),
-	/*10698*/ uint16(xMatch),
-	/*10699*/ uint16(xSetOp), uint16(RET),
-	/*10701*/ uint16(xMatch),
-	/*10702*/ uint16(xCondIs64), 10705, 0,
-	/*10705*/ uint16(xCondDataSize), 10709, 10715, 0,
-	/*10709*/ uint16(xSetOp), uint16(LES),
-	/*10711*/ uint16(xReadSlashR),
-	/*10712*/ uint16(xArgR16),
-	/*10713*/ uint16(xArgM16colon16),
-	/*10714*/ uint16(xMatch),
-	/*10715*/ uint16(xSetOp), uint16(LES),
-	/*10717*/ uint16(xReadSlashR),
-	/*10718*/ uint16(xArgR32),
-	/*10719*/ uint16(xArgM16colon32),
+	/*10684*/ uint16(xCondIs64), 10687, 10703,
+	/*10687*/ uint16(xCondDataSize), 10691, 10697, 0,
+	/*10691*/ uint16(xSetOp), uint16(SAR),
+	/*10693*/ uint16(xReadIb),
+	/*10694*/ uint16(xArgRM16),
+	/*10695*/ uint16(xArgImm8u),
+	/*10696*/ uint16(xMatch),
+	/*10697*/ uint16(xSetOp), uint16(SAR),
+	/*10699*/ uint16(xReadIb),
+	/*10700*/ uint16(xArgRM32),
+	/*10701*/ uint16(xArgImm8u),
+	/*10702*/ uint16(xMatch),
+	/*10703*/ uint16(xCondDataSize), 10691, 10697, 10707,
+	/*10707*/ uint16(xSetOp), uint16(SAR),
+	/*10709*/ uint16(xReadIb),
+	/*10710*/ uint16(xArgRM64),
+	/*10711*/ uint16(xArgImm8u),
+	/*10712*/ uint16(xMatch),
+	/*10713*/ uint16(xSetOp), uint16(RET),
+	/*10715*/ uint16(xReadIw),
+	/*10716*/ uint16(xArgImm16u),
+	/*10717*/ uint16(xMatch),
+	/*10718*/ uint16(xSetOp), uint16(RET),
 	/*10720*/ uint16(xMatch),
 	/*10721*/ uint16(xCondIs64), 10724, 0,
 	/*10724*/ uint16(xCondDataSize), 10728, 10734, 0,
-	/*10728*/ uint16(xSetOp), uint16(LDS),
+	/*10728*/ uint16(xSetOp), uint16(LES),
 	/*10730*/ uint16(xReadSlashR),
 	/*10731*/ uint16(xArgR16),
 	/*10732*/ uint16(xArgM16colon16),
 	/*10733*/ uint16(xMatch),
-	/*10734*/ uint16(xSetOp), uint16(LDS),
+	/*10734*/ uint16(xSetOp), uint16(LES),
 	/*10736*/ uint16(xReadSlashR),
 	/*10737*/ uint16(xArgR32),
 	/*10738*/ uint16(xArgM16colon32),
 	/*10739*/ uint16(xMatch),
-	/*10740*/ uint16(xCondByte), 1,
-	0xF8, 10759,
-	/*10744*/ uint16(xCondSlashR),
-	10753, // 0
-	0,     // 1
-	0,     // 2
-	0,     // 3
-	0,     // 4
-	0,     // 5
-	0,     // 6
-	0,     // 7
-	/*10753*/ uint16(xSetOp), uint16(MOV),
-	/*10755*/ uint16(xReadIb),
-	/*10756*/ uint16(xArgRM8),
-	/*10757*/ uint16(xArgImm8u),
+	/*10740*/ uint16(xCondIs64), 10743, 0,
+	/*10743*/ uint16(xCondDataSize), 10747, 10753, 0,
+	/*10747*/ uint16(xSetOp), uint16(LDS),
+	/*10749*/ uint16(xReadSlashR),
+	/*10750*/ uint16(xArgR16),
+	/*10751*/ uint16(xArgM16colon16),
+	/*10752*/ uint16(xMatch),
+	/*10753*/ uint16(xSetOp), uint16(LDS),
+	/*10755*/ uint16(xReadSlashR),
+	/*10756*/ uint16(xArgR32),
+	/*10757*/ uint16(xArgM16colon32),
 	/*10758*/ uint16(xMatch),
-	/*10759*/ uint16(xSetOp), uint16(XABORT),
-	/*10761*/ uint16(xReadIb),
-	/*10762*/ uint16(xArgImm8u),
-	/*10763*/ uint16(xMatch),
-	/*10764*/ uint16(xCondByte), 1,
-	0xF8, 10806,
-	/*10768*/ uint16(xCondSlashR),
-	10777, // 0
+	/*10759*/ uint16(xCondByte), 1,
+	0xF8, 10778,
+	/*10763*/ uint16(xCondSlashR),
+	10772, // 0
 	0,     // 1
 	0,     // 2
 	0,     // 3
@@ -7019,1662 +7010,1682 @@
 	0,     // 5
 	0,     // 6
 	0,     // 7
-	/*10777*/ uint16(xCondIs64), 10780, 10796,
-	/*10780*/ uint16(xCondDataSize), 10784, 10790, 0,
-	/*10784*/ uint16(xSetOp), uint16(MOV),
-	/*10786*/ uint16(xReadIw),
-	/*10787*/ uint16(xArgRM16),
-	/*10788*/ uint16(xArgImm16),
-	/*10789*/ uint16(xMatch),
-	/*10790*/ uint16(xSetOp), uint16(MOV),
-	/*10792*/ uint16(xReadId),
-	/*10793*/ uint16(xArgRM32),
-	/*10794*/ uint16(xArgImm32),
-	/*10795*/ uint16(xMatch),
-	/*10796*/ uint16(xCondDataSize), 10784, 10790, 10800,
-	/*10800*/ uint16(xSetOp), uint16(MOV),
-	/*10802*/ uint16(xReadId),
-	/*10803*/ uint16(xArgRM64),
-	/*10804*/ uint16(xArgImm32),
-	/*10805*/ uint16(xMatch),
-	/*10806*/ uint16(xCondDataSize), 10810, 10815, 10820,
-	/*10810*/ uint16(xSetOp), uint16(XBEGIN),
-	/*10812*/ uint16(xReadCw),
-	/*10813*/ uint16(xArgRel16),
+	/*10772*/ uint16(xSetOp), uint16(MOV),
+	/*10774*/ uint16(xReadIb),
+	/*10775*/ uint16(xArgRM8),
+	/*10776*/ uint16(xArgImm8u),
+	/*10777*/ uint16(xMatch),
+	/*10778*/ uint16(xSetOp), uint16(XABORT),
+	/*10780*/ uint16(xReadIb),
+	/*10781*/ uint16(xArgImm8u),
+	/*10782*/ uint16(xMatch),
+	/*10783*/ uint16(xCondByte), 1,
+	0xF8, 10825,
+	/*10787*/ uint16(xCondSlashR),
+	10796, // 0
+	0,     // 1
+	0,     // 2
+	0,     // 3
+	0,     // 4
+	0,     // 5
+	0,     // 6
+	0,     // 7
+	/*10796*/ uint16(xCondIs64), 10799, 10815,
+	/*10799*/ uint16(xCondDataSize), 10803, 10809, 0,
+	/*10803*/ uint16(xSetOp), uint16(MOV),
+	/*10805*/ uint16(xReadIw),
+	/*10806*/ uint16(xArgRM16),
+	/*10807*/ uint16(xArgImm16),
+	/*10808*/ uint16(xMatch),
+	/*10809*/ uint16(xSetOp), uint16(MOV),
+	/*10811*/ uint16(xReadId),
+	/*10812*/ uint16(xArgRM32),
+	/*10813*/ uint16(xArgImm32),
 	/*10814*/ uint16(xMatch),
-	/*10815*/ uint16(xSetOp), uint16(XBEGIN),
-	/*10817*/ uint16(xReadCd),
-	/*10818*/ uint16(xArgRel32),
-	/*10819*/ uint16(xMatch),
-	/*10820*/ uint16(xSetOp), uint16(XBEGIN),
-	/*10822*/ uint16(xReadCd),
-	/*10823*/ uint16(xArgRel32),
+	/*10815*/ uint16(xCondDataSize), 10803, 10809, 10819,
+	/*10819*/ uint16(xSetOp), uint16(MOV),
+	/*10821*/ uint16(xReadId),
+	/*10822*/ uint16(xArgRM64),
+	/*10823*/ uint16(xArgImm32),
 	/*10824*/ uint16(xMatch),
-	/*10825*/ uint16(xSetOp), uint16(ENTER),
-	/*10827*/ uint16(xReadIw),
-	/*10828*/ uint16(xReadIb),
-	/*10829*/ uint16(xArgImm16u),
-	/*10830*/ uint16(xArgImm8u),
-	/*10831*/ uint16(xMatch),
-	/*10832*/ uint16(xCondIs64), 10835, 10845,
-	/*10835*/ uint16(xCondDataSize), 10839, 10842, 0,
-	/*10839*/ uint16(xSetOp), uint16(LEAVE),
-	/*10841*/ uint16(xMatch),
-	/*10842*/ uint16(xSetOp), uint16(LEAVE),
-	/*10844*/ uint16(xMatch),
-	/*10845*/ uint16(xCondDataSize), 10839, 10849, 10852,
-	/*10849*/ uint16(xSetOp), uint16(LEAVE),
-	/*10851*/ uint16(xMatch),
-	/*10852*/ uint16(xSetOp), uint16(LEAVE),
-	/*10854*/ uint16(xMatch),
-	/*10855*/ uint16(xSetOp), uint16(LRET),
-	/*10857*/ uint16(xReadIw),
-	/*10858*/ uint16(xArgImm16u),
-	/*10859*/ uint16(xMatch),
-	/*10860*/ uint16(xSetOp), uint16(LRET),
-	/*10862*/ uint16(xMatch),
-	/*10863*/ uint16(xSetOp), uint16(INT),
-	/*10865*/ uint16(xArg3),
-	/*10866*/ uint16(xMatch),
-	/*10867*/ uint16(xSetOp), uint16(INT),
-	/*10869*/ uint16(xReadIb),
-	/*10870*/ uint16(xArgImm8u),
-	/*10871*/ uint16(xMatch),
-	/*10872*/ uint16(xCondIs64), 10875, 0,
-	/*10875*/ uint16(xSetOp), uint16(INTO),
-	/*10877*/ uint16(xMatch),
-	/*10878*/ uint16(xCondIs64), 10881, 10891,
-	/*10881*/ uint16(xCondDataSize), 10885, 10888, 0,
-	/*10885*/ uint16(xSetOp), uint16(IRET),
-	/*10887*/ uint16(xMatch),
-	/*10888*/ uint16(xSetOp), uint16(IRETD),
+	/*10825*/ uint16(xCondDataSize), 10829, 10834, 10839,
+	/*10829*/ uint16(xSetOp), uint16(XBEGIN),
+	/*10831*/ uint16(xReadCw),
+	/*10832*/ uint16(xArgRel16),
+	/*10833*/ uint16(xMatch),
+	/*10834*/ uint16(xSetOp), uint16(XBEGIN),
+	/*10836*/ uint16(xReadCd),
+	/*10837*/ uint16(xArgRel32),
+	/*10838*/ uint16(xMatch),
+	/*10839*/ uint16(xSetOp), uint16(XBEGIN),
+	/*10841*/ uint16(xReadCd),
+	/*10842*/ uint16(xArgRel32),
+	/*10843*/ uint16(xMatch),
+	/*10844*/ uint16(xSetOp), uint16(ENTER),
+	/*10846*/ uint16(xReadIw),
+	/*10847*/ uint16(xReadIb),
+	/*10848*/ uint16(xArgImm16u),
+	/*10849*/ uint16(xArgImm8u),
+	/*10850*/ uint16(xMatch),
+	/*10851*/ uint16(xCondIs64), 10854, 10864,
+	/*10854*/ uint16(xCondDataSize), 10858, 10861, 0,
+	/*10858*/ uint16(xSetOp), uint16(LEAVE),
+	/*10860*/ uint16(xMatch),
+	/*10861*/ uint16(xSetOp), uint16(LEAVE),
+	/*10863*/ uint16(xMatch),
+	/*10864*/ uint16(xCondDataSize), 10858, 10868, 10871,
+	/*10868*/ uint16(xSetOp), uint16(LEAVE),
+	/*10870*/ uint16(xMatch),
+	/*10871*/ uint16(xSetOp), uint16(LEAVE),
+	/*10873*/ uint16(xMatch),
+	/*10874*/ uint16(xSetOp), uint16(LRET),
+	/*10876*/ uint16(xReadIw),
+	/*10877*/ uint16(xArgImm16u),
+	/*10878*/ uint16(xMatch),
+	/*10879*/ uint16(xSetOp), uint16(LRET),
+	/*10881*/ uint16(xMatch),
+	/*10882*/ uint16(xSetOp), uint16(INT),
+	/*10884*/ uint16(xArg3),
+	/*10885*/ uint16(xMatch),
+	/*10886*/ uint16(xSetOp), uint16(INT),
+	/*10888*/ uint16(xReadIb),
+	/*10889*/ uint16(xArgImm8u),
 	/*10890*/ uint16(xMatch),
-	/*10891*/ uint16(xCondDataSize), 10885, 10888, 10895,
-	/*10895*/ uint16(xSetOp), uint16(IRETQ),
-	/*10897*/ uint16(xMatch),
-	/*10898*/ uint16(xCondSlashR),
-	10907, // 0
-	10912, // 1
-	10917, // 2
-	10922, // 3
-	10927, // 4
-	10932, // 5
-	0,     // 6
-	10937, // 7
-	/*10907*/ uint16(xSetOp), uint16(ROL),
-	/*10909*/ uint16(xArgRM8),
-	/*10910*/ uint16(xArg1),
-	/*10911*/ uint16(xMatch),
-	/*10912*/ uint16(xSetOp), uint16(ROR),
-	/*10914*/ uint16(xArgRM8),
-	/*10915*/ uint16(xArg1),
+	/*10891*/ uint16(xCondIs64), 10894, 0,
+	/*10894*/ uint16(xSetOp), uint16(INTO),
+	/*10896*/ uint16(xMatch),
+	/*10897*/ uint16(xCondIs64), 10900, 10910,
+	/*10900*/ uint16(xCondDataSize), 10904, 10907, 0,
+	/*10904*/ uint16(xSetOp), uint16(IRET),
+	/*10906*/ uint16(xMatch),
+	/*10907*/ uint16(xSetOp), uint16(IRETD),
+	/*10909*/ uint16(xMatch),
+	/*10910*/ uint16(xCondDataSize), 10904, 10907, 10914,
+	/*10914*/ uint16(xSetOp), uint16(IRETQ),
 	/*10916*/ uint16(xMatch),
-	/*10917*/ uint16(xSetOp), uint16(RCL),
-	/*10919*/ uint16(xArgRM8),
-	/*10920*/ uint16(xArg1),
-	/*10921*/ uint16(xMatch),
-	/*10922*/ uint16(xSetOp), uint16(RCR),
-	/*10924*/ uint16(xArgRM8),
-	/*10925*/ uint16(xArg1),
-	/*10926*/ uint16(xMatch),
-	/*10927*/ uint16(xSetOp), uint16(SHL),
-	/*10929*/ uint16(xArgRM8),
-	/*10930*/ uint16(xArg1),
-	/*10931*/ uint16(xMatch),
-	/*10932*/ uint16(xSetOp), uint16(SHR),
-	/*10934*/ uint16(xArgRM8),
-	/*10935*/ uint16(xArg1),
-	/*10936*/ uint16(xMatch),
-	/*10937*/ uint16(xSetOp), uint16(SAR),
-	/*10939*/ uint16(xArgRM8),
-	/*10940*/ uint16(xArg1),
-	/*10941*/ uint16(xMatch),
-	/*10942*/ uint16(xCondSlashR),
-	10951, // 0
-	10977, // 1
-	11003, // 2
-	11029, // 3
-	11055, // 4
-	11081, // 5
+	/*10917*/ uint16(xCondSlashR),
+	10926, // 0
+	10931, // 1
+	10936, // 2
+	10941, // 3
+	10946, // 4
+	10951, // 5
 	0,     // 6
-	11107, // 7
-	/*10951*/ uint16(xCondIs64), 10954, 10968,
-	/*10954*/ uint16(xCondDataSize), 10958, 10963, 0,
-	/*10958*/ uint16(xSetOp), uint16(ROL),
-	/*10960*/ uint16(xArgRM16),
-	/*10961*/ uint16(xArg1),
-	/*10962*/ uint16(xMatch),
-	/*10963*/ uint16(xSetOp), uint16(ROL),
-	/*10965*/ uint16(xArgRM32),
-	/*10966*/ uint16(xArg1),
-	/*10967*/ uint16(xMatch),
-	/*10968*/ uint16(xCondDataSize), 10958, 10963, 10972,
-	/*10972*/ uint16(xSetOp), uint16(ROL),
-	/*10974*/ uint16(xArgRM64),
-	/*10975*/ uint16(xArg1),
-	/*10976*/ uint16(xMatch),
-	/*10977*/ uint16(xCondIs64), 10980, 10994,
-	/*10980*/ uint16(xCondDataSize), 10984, 10989, 0,
-	/*10984*/ uint16(xSetOp), uint16(ROR),
-	/*10986*/ uint16(xArgRM16),
-	/*10987*/ uint16(xArg1),
-	/*10988*/ uint16(xMatch),
-	/*10989*/ uint16(xSetOp), uint16(ROR),
-	/*10991*/ uint16(xArgRM32),
-	/*10992*/ uint16(xArg1),
-	/*10993*/ uint16(xMatch),
-	/*10994*/ uint16(xCondDataSize), 10984, 10989, 10998,
-	/*10998*/ uint16(xSetOp), uint16(ROR),
-	/*11000*/ uint16(xArgRM64),
-	/*11001*/ uint16(xArg1),
-	/*11002*/ uint16(xMatch),
-	/*11003*/ uint16(xCondIs64), 11006, 11020,
-	/*11006*/ uint16(xCondDataSize), 11010, 11015, 0,
-	/*11010*/ uint16(xSetOp), uint16(RCL),
-	/*11012*/ uint16(xArgRM16),
-	/*11013*/ uint16(xArg1),
-	/*11014*/ uint16(xMatch),
-	/*11015*/ uint16(xSetOp), uint16(RCL),
-	/*11017*/ uint16(xArgRM32),
-	/*11018*/ uint16(xArg1),
-	/*11019*/ uint16(xMatch),
-	/*11020*/ uint16(xCondDataSize), 11010, 11015, 11024,
-	/*11024*/ uint16(xSetOp), uint16(RCL),
-	/*11026*/ uint16(xArgRM64),
-	/*11027*/ uint16(xArg1),
-	/*11028*/ uint16(xMatch),
-	/*11029*/ uint16(xCondIs64), 11032, 11046,
-	/*11032*/ uint16(xCondDataSize), 11036, 11041, 0,
-	/*11036*/ uint16(xSetOp), uint16(RCR),
-	/*11038*/ uint16(xArgRM16),
-	/*11039*/ uint16(xArg1),
-	/*11040*/ uint16(xMatch),
-	/*11041*/ uint16(xSetOp), uint16(RCR),
-	/*11043*/ uint16(xArgRM32),
-	/*11044*/ uint16(xArg1),
-	/*11045*/ uint16(xMatch),
-	/*11046*/ uint16(xCondDataSize), 11036, 11041, 11050,
-	/*11050*/ uint16(xSetOp), uint16(RCR),
-	/*11052*/ uint16(xArgRM64),
-	/*11053*/ uint16(xArg1),
-	/*11054*/ uint16(xMatch),
-	/*11055*/ uint16(xCondIs64), 11058, 11072,
-	/*11058*/ uint16(xCondDataSize), 11062, 11067, 0,
-	/*11062*/ uint16(xSetOp), uint16(SHL),
-	/*11064*/ uint16(xArgRM16),
-	/*11065*/ uint16(xArg1),
-	/*11066*/ uint16(xMatch),
-	/*11067*/ uint16(xSetOp), uint16(SHL),
-	/*11069*/ uint16(xArgRM32),
-	/*11070*/ uint16(xArg1),
-	/*11071*/ uint16(xMatch),
-	/*11072*/ uint16(xCondDataSize), 11062, 11067, 11076,
-	/*11076*/ uint16(xSetOp), uint16(SHL),
-	/*11078*/ uint16(xArgRM64),
-	/*11079*/ uint16(xArg1),
-	/*11080*/ uint16(xMatch),
-	/*11081*/ uint16(xCondIs64), 11084, 11098,
-	/*11084*/ uint16(xCondDataSize), 11088, 11093, 0,
-	/*11088*/ uint16(xSetOp), uint16(SHR),
-	/*11090*/ uint16(xArgRM16),
-	/*11091*/ uint16(xArg1),
-	/*11092*/ uint16(xMatch),
-	/*11093*/ uint16(xSetOp), uint16(SHR),
-	/*11095*/ uint16(xArgRM32),
-	/*11096*/ uint16(xArg1),
-	/*11097*/ uint16(xMatch),
-	/*11098*/ uint16(xCondDataSize), 11088, 11093, 11102,
-	/*11102*/ uint16(xSetOp), uint16(SHR),
-	/*11104*/ uint16(xArgRM64),
-	/*11105*/ uint16(xArg1),
-	/*11106*/ uint16(xMatch),
-	/*11107*/ uint16(xCondIs64), 11110, 11124,
-	/*11110*/ uint16(xCondDataSize), 11114, 11119, 0,
-	/*11114*/ uint16(xSetOp), uint16(SAR),
-	/*11116*/ uint16(xArgRM16),
-	/*11117*/ uint16(xArg1),
-	/*11118*/ uint16(xMatch),
-	/*11119*/ uint16(xSetOp), uint16(SAR),
-	/*11121*/ uint16(xArgRM32),
-	/*11122*/ uint16(xArg1),
-	/*11123*/ uint16(xMatch),
-	/*11124*/ uint16(xCondDataSize), 11114, 11119, 11128,
-	/*11128*/ uint16(xSetOp), uint16(SAR),
-	/*11130*/ uint16(xArgRM64),
-	/*11131*/ uint16(xArg1),
-	/*11132*/ uint16(xMatch),
-	/*11133*/ uint16(xCondSlashR),
-	11142, // 0
-	11147, // 1
-	11152, // 2
-	11157, // 3
-	11162, // 4
-	11167, // 5
+	10956, // 7
+	/*10926*/ uint16(xSetOp), uint16(ROL),
+	/*10928*/ uint16(xArgRM8),
+	/*10929*/ uint16(xArg1),
+	/*10930*/ uint16(xMatch),
+	/*10931*/ uint16(xSetOp), uint16(ROR),
+	/*10933*/ uint16(xArgRM8),
+	/*10934*/ uint16(xArg1),
+	/*10935*/ uint16(xMatch),
+	/*10936*/ uint16(xSetOp), uint16(RCL),
+	/*10938*/ uint16(xArgRM8),
+	/*10939*/ uint16(xArg1),
+	/*10940*/ uint16(xMatch),
+	/*10941*/ uint16(xSetOp), uint16(RCR),
+	/*10943*/ uint16(xArgRM8),
+	/*10944*/ uint16(xArg1),
+	/*10945*/ uint16(xMatch),
+	/*10946*/ uint16(xSetOp), uint16(SHL),
+	/*10948*/ uint16(xArgRM8),
+	/*10949*/ uint16(xArg1),
+	/*10950*/ uint16(xMatch),
+	/*10951*/ uint16(xSetOp), uint16(SHR),
+	/*10953*/ uint16(xArgRM8),
+	/*10954*/ uint16(xArg1),
+	/*10955*/ uint16(xMatch),
+	/*10956*/ uint16(xSetOp), uint16(SAR),
+	/*10958*/ uint16(xArgRM8),
+	/*10959*/ uint16(xArg1),
+	/*10960*/ uint16(xMatch),
+	/*10961*/ uint16(xCondSlashR),
+	10970, // 0
+	10996, // 1
+	11022, // 2
+	11048, // 3
+	11074, // 4
+	11100, // 5
 	0,     // 6
-	11172, // 7
-	/*11142*/ uint16(xSetOp), uint16(ROL),
-	/*11144*/ uint16(xArgRM8),
-	/*11145*/ uint16(xArgCL),
-	/*11146*/ uint16(xMatch),
-	/*11147*/ uint16(xSetOp), uint16(ROR),
-	/*11149*/ uint16(xArgRM8),
-	/*11150*/ uint16(xArgCL),
+	11126, // 7
+	/*10970*/ uint16(xCondIs64), 10973, 10987,
+	/*10973*/ uint16(xCondDataSize), 10977, 10982, 0,
+	/*10977*/ uint16(xSetOp), uint16(ROL),
+	/*10979*/ uint16(xArgRM16),
+	/*10980*/ uint16(xArg1),
+	/*10981*/ uint16(xMatch),
+	/*10982*/ uint16(xSetOp), uint16(ROL),
+	/*10984*/ uint16(xArgRM32),
+	/*10985*/ uint16(xArg1),
+	/*10986*/ uint16(xMatch),
+	/*10987*/ uint16(xCondDataSize), 10977, 10982, 10991,
+	/*10991*/ uint16(xSetOp), uint16(ROL),
+	/*10993*/ uint16(xArgRM64),
+	/*10994*/ uint16(xArg1),
+	/*10995*/ uint16(xMatch),
+	/*10996*/ uint16(xCondIs64), 10999, 11013,
+	/*10999*/ uint16(xCondDataSize), 11003, 11008, 0,
+	/*11003*/ uint16(xSetOp), uint16(ROR),
+	/*11005*/ uint16(xArgRM16),
+	/*11006*/ uint16(xArg1),
+	/*11007*/ uint16(xMatch),
+	/*11008*/ uint16(xSetOp), uint16(ROR),
+	/*11010*/ uint16(xArgRM32),
+	/*11011*/ uint16(xArg1),
+	/*11012*/ uint16(xMatch),
+	/*11013*/ uint16(xCondDataSize), 11003, 11008, 11017,
+	/*11017*/ uint16(xSetOp), uint16(ROR),
+	/*11019*/ uint16(xArgRM64),
+	/*11020*/ uint16(xArg1),
+	/*11021*/ uint16(xMatch),
+	/*11022*/ uint16(xCondIs64), 11025, 11039,
+	/*11025*/ uint16(xCondDataSize), 11029, 11034, 0,
+	/*11029*/ uint16(xSetOp), uint16(RCL),
+	/*11031*/ uint16(xArgRM16),
+	/*11032*/ uint16(xArg1),
+	/*11033*/ uint16(xMatch),
+	/*11034*/ uint16(xSetOp), uint16(RCL),
+	/*11036*/ uint16(xArgRM32),
+	/*11037*/ uint16(xArg1),
+	/*11038*/ uint16(xMatch),
+	/*11039*/ uint16(xCondDataSize), 11029, 11034, 11043,
+	/*11043*/ uint16(xSetOp), uint16(RCL),
+	/*11045*/ uint16(xArgRM64),
+	/*11046*/ uint16(xArg1),
+	/*11047*/ uint16(xMatch),
+	/*11048*/ uint16(xCondIs64), 11051, 11065,
+	/*11051*/ uint16(xCondDataSize), 11055, 11060, 0,
+	/*11055*/ uint16(xSetOp), uint16(RCR),
+	/*11057*/ uint16(xArgRM16),
+	/*11058*/ uint16(xArg1),
+	/*11059*/ uint16(xMatch),
+	/*11060*/ uint16(xSetOp), uint16(RCR),
+	/*11062*/ uint16(xArgRM32),
+	/*11063*/ uint16(xArg1),
+	/*11064*/ uint16(xMatch),
+	/*11065*/ uint16(xCondDataSize), 11055, 11060, 11069,
+	/*11069*/ uint16(xSetOp), uint16(RCR),
+	/*11071*/ uint16(xArgRM64),
+	/*11072*/ uint16(xArg1),
+	/*11073*/ uint16(xMatch),
+	/*11074*/ uint16(xCondIs64), 11077, 11091,
+	/*11077*/ uint16(xCondDataSize), 11081, 11086, 0,
+	/*11081*/ uint16(xSetOp), uint16(SHL),
+	/*11083*/ uint16(xArgRM16),
+	/*11084*/ uint16(xArg1),
+	/*11085*/ uint16(xMatch),
+	/*11086*/ uint16(xSetOp), uint16(SHL),
+	/*11088*/ uint16(xArgRM32),
+	/*11089*/ uint16(xArg1),
+	/*11090*/ uint16(xMatch),
+	/*11091*/ uint16(xCondDataSize), 11081, 11086, 11095,
+	/*11095*/ uint16(xSetOp), uint16(SHL),
+	/*11097*/ uint16(xArgRM64),
+	/*11098*/ uint16(xArg1),
+	/*11099*/ uint16(xMatch),
+	/*11100*/ uint16(xCondIs64), 11103, 11117,
+	/*11103*/ uint16(xCondDataSize), 11107, 11112, 0,
+	/*11107*/ uint16(xSetOp), uint16(SHR),
+	/*11109*/ uint16(xArgRM16),
+	/*11110*/ uint16(xArg1),
+	/*11111*/ uint16(xMatch),
+	/*11112*/ uint16(xSetOp), uint16(SHR),
+	/*11114*/ uint16(xArgRM32),
+	/*11115*/ uint16(xArg1),
+	/*11116*/ uint16(xMatch),
+	/*11117*/ uint16(xCondDataSize), 11107, 11112, 11121,
+	/*11121*/ uint16(xSetOp), uint16(SHR),
+	/*11123*/ uint16(xArgRM64),
+	/*11124*/ uint16(xArg1),
+	/*11125*/ uint16(xMatch),
+	/*11126*/ uint16(xCondIs64), 11129, 11143,
+	/*11129*/ uint16(xCondDataSize), 11133, 11138, 0,
+	/*11133*/ uint16(xSetOp), uint16(SAR),
+	/*11135*/ uint16(xArgRM16),
+	/*11136*/ uint16(xArg1),
+	/*11137*/ uint16(xMatch),
+	/*11138*/ uint16(xSetOp), uint16(SAR),
+	/*11140*/ uint16(xArgRM32),
+	/*11141*/ uint16(xArg1),
+	/*11142*/ uint16(xMatch),
+	/*11143*/ uint16(xCondDataSize), 11133, 11138, 11147,
+	/*11147*/ uint16(xSetOp), uint16(SAR),
+	/*11149*/ uint16(xArgRM64),
+	/*11150*/ uint16(xArg1),
 	/*11151*/ uint16(xMatch),
-	/*11152*/ uint16(xSetOp), uint16(RCL),
-	/*11154*/ uint16(xArgRM8),
-	/*11155*/ uint16(xArgCL),
-	/*11156*/ uint16(xMatch),
-	/*11157*/ uint16(xSetOp), uint16(RCR),
-	/*11159*/ uint16(xArgRM8),
-	/*11160*/ uint16(xArgCL),
-	/*11161*/ uint16(xMatch),
-	/*11162*/ uint16(xSetOp), uint16(SHL),
-	/*11164*/ uint16(xArgRM8),
-	/*11165*/ uint16(xArgCL),
-	/*11166*/ uint16(xMatch),
-	/*11167*/ uint16(xSetOp), uint16(SHR),
-	/*11169*/ uint16(xArgRM8),
-	/*11170*/ uint16(xArgCL),
-	/*11171*/ uint16(xMatch),
-	/*11172*/ uint16(xSetOp), uint16(SAR),
-	/*11174*/ uint16(xArgRM8),
-	/*11175*/ uint16(xArgCL),
-	/*11176*/ uint16(xMatch),
-	/*11177*/ uint16(xCondSlashR),
-	11186, // 0
-	11212, // 1
-	11238, // 2
-	11264, // 3
-	11290, // 4
-	11316, // 5
+	/*11152*/ uint16(xCondSlashR),
+	11161, // 0
+	11166, // 1
+	11171, // 2
+	11176, // 3
+	11181, // 4
+	11186, // 5
 	0,     // 6
-	11342, // 7
-	/*11186*/ uint16(xCondIs64), 11189, 11203,
-	/*11189*/ uint16(xCondDataSize), 11193, 11198, 0,
-	/*11193*/ uint16(xSetOp), uint16(ROL),
-	/*11195*/ uint16(xArgRM16),
-	/*11196*/ uint16(xArgCL),
-	/*11197*/ uint16(xMatch),
-	/*11198*/ uint16(xSetOp), uint16(ROL),
-	/*11200*/ uint16(xArgRM32),
-	/*11201*/ uint16(xArgCL),
-	/*11202*/ uint16(xMatch),
-	/*11203*/ uint16(xCondDataSize), 11193, 11198, 11207,
-	/*11207*/ uint16(xSetOp), uint16(ROL),
-	/*11209*/ uint16(xArgRM64),
-	/*11210*/ uint16(xArgCL),
-	/*11211*/ uint16(xMatch),
-	/*11212*/ uint16(xCondIs64), 11215, 11229,
-	/*11215*/ uint16(xCondDataSize), 11219, 11224, 0,
-	/*11219*/ uint16(xSetOp), uint16(ROR),
-	/*11221*/ uint16(xArgRM16),
-	/*11222*/ uint16(xArgCL),
-	/*11223*/ uint16(xMatch),
-	/*11224*/ uint16(xSetOp), uint16(ROR),
-	/*11226*/ uint16(xArgRM32),
-	/*11227*/ uint16(xArgCL),
-	/*11228*/ uint16(xMatch),
-	/*11229*/ uint16(xCondDataSize), 11219, 11224, 11233,
-	/*11233*/ uint16(xSetOp), uint16(ROR),
-	/*11235*/ uint16(xArgRM64),
-	/*11236*/ uint16(xArgCL),
-	/*11237*/ uint16(xMatch),
-	/*11238*/ uint16(xCondIs64), 11241, 11255,
-	/*11241*/ uint16(xCondDataSize), 11245, 11250, 0,
-	/*11245*/ uint16(xSetOp), uint16(RCL),
-	/*11247*/ uint16(xArgRM16),
-	/*11248*/ uint16(xArgCL),
-	/*11249*/ uint16(xMatch),
-	/*11250*/ uint16(xSetOp), uint16(RCL),
-	/*11252*/ uint16(xArgRM32),
-	/*11253*/ uint16(xArgCL),
-	/*11254*/ uint16(xMatch),
-	/*11255*/ uint16(xCondDataSize), 11245, 11250, 11259,
-	/*11259*/ uint16(xSetOp), uint16(RCL),
-	/*11261*/ uint16(xArgRM64),
-	/*11262*/ uint16(xArgCL),
-	/*11263*/ uint16(xMatch),
-	/*11264*/ uint16(xCondIs64), 11267, 11281,
-	/*11267*/ uint16(xCondDataSize), 11271, 11276, 0,
-	/*11271*/ uint16(xSetOp), uint16(RCR),
-	/*11273*/ uint16(xArgRM16),
-	/*11274*/ uint16(xArgCL),
-	/*11275*/ uint16(xMatch),
-	/*11276*/ uint16(xSetOp), uint16(RCR),
-	/*11278*/ uint16(xArgRM32),
-	/*11279*/ uint16(xArgCL),
-	/*11280*/ uint16(xMatch),
-	/*11281*/ uint16(xCondDataSize), 11271, 11276, 11285,
-	/*11285*/ uint16(xSetOp), uint16(RCR),
-	/*11287*/ uint16(xArgRM64),
-	/*11288*/ uint16(xArgCL),
-	/*11289*/ uint16(xMatch),
-	/*11290*/ uint16(xCondIs64), 11293, 11307,
-	/*11293*/ uint16(xCondDataSize), 11297, 11302, 0,
-	/*11297*/ uint16(xSetOp), uint16(SHL),
-	/*11299*/ uint16(xArgRM16),
-	/*11300*/ uint16(xArgCL),
-	/*11301*/ uint16(xMatch),
-	/*11302*/ uint16(xSetOp), uint16(SHL),
-	/*11304*/ uint16(xArgRM32),
-	/*11305*/ uint16(xArgCL),
-	/*11306*/ uint16(xMatch),
-	/*11307*/ uint16(xCondDataSize), 11297, 11302, 11311,
-	/*11311*/ uint16(xSetOp), uint16(SHL),
-	/*11313*/ uint16(xArgRM64),
-	/*11314*/ uint16(xArgCL),
-	/*11315*/ uint16(xMatch),
-	/*11316*/ uint16(xCondIs64), 11319, 11333,
-	/*11319*/ uint16(xCondDataSize), 11323, 11328, 0,
-	/*11323*/ uint16(xSetOp), uint16(SHR),
-	/*11325*/ uint16(xArgRM16),
-	/*11326*/ uint16(xArgCL),
-	/*11327*/ uint16(xMatch),
-	/*11328*/ uint16(xSetOp), uint16(SHR),
-	/*11330*/ uint16(xArgRM32),
-	/*11331*/ uint16(xArgCL),
-	/*11332*/ uint16(xMatch),
-	/*11333*/ uint16(xCondDataSize), 11323, 11328, 11337,
-	/*11337*/ uint16(xSetOp), uint16(SHR),
-	/*11339*/ uint16(xArgRM64),
-	/*11340*/ uint16(xArgCL),
-	/*11341*/ uint16(xMatch),
-	/*11342*/ uint16(xCondIs64), 11345, 11359,
-	/*11345*/ uint16(xCondDataSize), 11349, 11354, 0,
-	/*11349*/ uint16(xSetOp), uint16(SAR),
-	/*11351*/ uint16(xArgRM16),
-	/*11352*/ uint16(xArgCL),
-	/*11353*/ uint16(xMatch),
-	/*11354*/ uint16(xSetOp), uint16(SAR),
-	/*11356*/ uint16(xArgRM32),
-	/*11357*/ uint16(xArgCL),
-	/*11358*/ uint16(xMatch),
-	/*11359*/ uint16(xCondDataSize), 11349, 11354, 11363,
-	/*11363*/ uint16(xSetOp), uint16(SAR),
-	/*11365*/ uint16(xArgRM64),
-	/*11366*/ uint16(xArgCL),
-	/*11367*/ uint16(xMatch),
-	/*11368*/ uint16(xCondIs64), 11371, 0,
-	/*11371*/ uint16(xSetOp), uint16(AAM),
-	/*11373*/ uint16(xReadIb),
-	/*11374*/ uint16(xArgImm8u),
-	/*11375*/ uint16(xMatch),
-	/*11376*/ uint16(xCondIs64), 11379, 0,
-	/*11379*/ uint16(xSetOp), uint16(AAD),
-	/*11381*/ uint16(xReadIb),
-	/*11382*/ uint16(xArgImm8u),
-	/*11383*/ uint16(xMatch),
-	/*11384*/ uint16(xCondIs64), 11387, 11390,
-	/*11387*/ uint16(xSetOp), uint16(XLATB),
-	/*11389*/ uint16(xMatch),
-	/*11390*/ uint16(xCondDataSize), 11387, 11387, 11394,
-	/*11394*/ uint16(xSetOp), uint16(XLATB),
-	/*11396*/ uint16(xMatch),
-	/*11397*/ uint16(xCondByte), 64,
-	0xc0, 11568,
-	0xc1, 11568,
-	0xc2, 11568,
-	0xc3, 11568,
-	0xc4, 11568,
-	0xc5, 11568,
-	0xc6, 11568,
-	0xc7, 11568,
-	0xc8, 11573,
-	0xc9, 11573,
-	0xca, 11573,
-	0xcb, 11573,
-	0xcc, 11573,
-	0xcd, 11573,
-	0xce, 11573,
-	0xcf, 11573,
-	0xd0, 11578,
-	0xd1, 11578,
-	0xd2, 11578,
-	0xd3, 11578,
-	0xd4, 11578,
-	0xd5, 11578,
-	0xd6, 11578,
-	0xd7, 11578,
-	0xd8, 11582,
-	0xd9, 11582,
-	0xda, 11582,
-	0xdb, 11582,
-	0xdc, 11582,
-	0xdd, 11582,
-	0xde, 11582,
-	0xdf, 11582,
-	0xe0, 11586,
-	0xe1, 11586,
-	0xe2, 11586,
-	0xe3, 11586,
-	0xe4, 11586,
-	0xe5, 11586,
-	0xe6, 11586,
-	0xe7, 11586,
-	0xe8, 11591,
-	0xe9, 11591,
-	0xea, 11591,
-	0xeb, 11591,
-	0xec, 11591,
-	0xed, 11591,
-	0xee, 11591,
-	0xef, 11591,
-	0xf0, 11596,
-	0xf1, 11596,
-	0xf2, 11596,
-	0xf3, 11596,
-	0xf4, 11596,
-	0xf5, 11596,
-	0xf6, 11596,
-	0xf7, 11596,
-	0xf8, 11601,
-	0xf9, 11601,
-	0xfa, 11601,
-	0xfb, 11601,
-	0xfc, 11601,
-	0xfd, 11601,
-	0xfe, 11601,
-	0xff, 11601,
-	/*11527*/ uint16(xCondSlashR),
-	11536, // 0
-	11540, // 1
-	11544, // 2
-	11548, // 3
-	11552, // 4
-	11556, // 5
-	11560, // 6
-	11564, // 7
-	/*11536*/ uint16(xSetOp), uint16(FADD),
-	/*11538*/ uint16(xArgM32fp),
-	/*11539*/ uint16(xMatch),
-	/*11540*/ uint16(xSetOp), uint16(FMUL),
-	/*11542*/ uint16(xArgM32fp),
-	/*11543*/ uint16(xMatch),
-	/*11544*/ uint16(xSetOp), uint16(FCOM),
-	/*11546*/ uint16(xArgM32fp),
-	/*11547*/ uint16(xMatch),
-	/*11548*/ uint16(xSetOp), uint16(FCOMP),
-	/*11550*/ uint16(xArgM32fp),
-	/*11551*/ uint16(xMatch),
-	/*11552*/ uint16(xSetOp), uint16(FSUB),
-	/*11554*/ uint16(xArgM32fp),
-	/*11555*/ uint16(xMatch),
-	/*11556*/ uint16(xSetOp), uint16(FSUBR),
-	/*11558*/ uint16(xArgM32fp),
-	/*11559*/ uint16(xMatch),
-	/*11560*/ uint16(xSetOp), uint16(FDIV),
-	/*11562*/ uint16(xArgM32fp),
-	/*11563*/ uint16(xMatch),
-	/*11564*/ uint16(xSetOp), uint16(FDIVR),
-	/*11566*/ uint16(xArgM32fp),
-	/*11567*/ uint16(xMatch),
-	/*11568*/ uint16(xSetOp), uint16(FADD),
-	/*11570*/ uint16(xArgST),
-	/*11571*/ uint16(xArgSTi),
-	/*11572*/ uint16(xMatch),
-	/*11573*/ uint16(xSetOp), uint16(FMUL),
-	/*11575*/ uint16(xArgST),
-	/*11576*/ uint16(xArgSTi),
-	/*11577*/ uint16(xMatch),
-	/*11578*/ uint16(xSetOp), uint16(FCOM),
-	/*11580*/ uint16(xArgSTi),
-	/*11581*/ uint16(xMatch),
-	/*11582*/ uint16(xSetOp), uint16(FCOMP),
-	/*11584*/ uint16(xArgSTi),
-	/*11585*/ uint16(xMatch),
-	/*11586*/ uint16(xSetOp), uint16(FSUB),
-	/*11588*/ uint16(xArgST),
-	/*11589*/ uint16(xArgSTi),
-	/*11590*/ uint16(xMatch),
-	/*11591*/ uint16(xSetOp), uint16(FSUBR),
-	/*11593*/ uint16(xArgST),
-	/*11594*/ uint16(xArgSTi),
-	/*11595*/ uint16(xMatch),
-	/*11596*/ uint16(xSetOp), uint16(FDIV),
-	/*11598*/ uint16(xArgST),
+	11191, // 7
+	/*11161*/ uint16(xSetOp), uint16(ROL),
+	/*11163*/ uint16(xArgRM8),
+	/*11164*/ uint16(xArgCL),
+	/*11165*/ uint16(xMatch),
+	/*11166*/ uint16(xSetOp), uint16(ROR),
+	/*11168*/ uint16(xArgRM8),
+	/*11169*/ uint16(xArgCL),
+	/*11170*/ uint16(xMatch),
+	/*11171*/ uint16(xSetOp), uint16(RCL),
+	/*11173*/ uint16(xArgRM8),
+	/*11174*/ uint16(xArgCL),
+	/*11175*/ uint16(xMatch),
+	/*11176*/ uint16(xSetOp), uint16(RCR),
+	/*11178*/ uint16(xArgRM8),
+	/*11179*/ uint16(xArgCL),
+	/*11180*/ uint16(xMatch),
+	/*11181*/ uint16(xSetOp), uint16(SHL),
+	/*11183*/ uint16(xArgRM8),
+	/*11184*/ uint16(xArgCL),
+	/*11185*/ uint16(xMatch),
+	/*11186*/ uint16(xSetOp), uint16(SHR),
+	/*11188*/ uint16(xArgRM8),
+	/*11189*/ uint16(xArgCL),
+	/*11190*/ uint16(xMatch),
+	/*11191*/ uint16(xSetOp), uint16(SAR),
+	/*11193*/ uint16(xArgRM8),
+	/*11194*/ uint16(xArgCL),
+	/*11195*/ uint16(xMatch),
+	/*11196*/ uint16(xCondSlashR),
+	11205, // 0
+	11231, // 1
+	11257, // 2
+	11283, // 3
+	11309, // 4
+	11335, // 5
+	0,     // 6
+	11361, // 7
+	/*11205*/ uint16(xCondIs64), 11208, 11222,
+	/*11208*/ uint16(xCondDataSize), 11212, 11217, 0,
+	/*11212*/ uint16(xSetOp), uint16(ROL),
+	/*11214*/ uint16(xArgRM16),
+	/*11215*/ uint16(xArgCL),
+	/*11216*/ uint16(xMatch),
+	/*11217*/ uint16(xSetOp), uint16(ROL),
+	/*11219*/ uint16(xArgRM32),
+	/*11220*/ uint16(xArgCL),
+	/*11221*/ uint16(xMatch),
+	/*11222*/ uint16(xCondDataSize), 11212, 11217, 11226,
+	/*11226*/ uint16(xSetOp), uint16(ROL),
+	/*11228*/ uint16(xArgRM64),
+	/*11229*/ uint16(xArgCL),
+	/*11230*/ uint16(xMatch),
+	/*11231*/ uint16(xCondIs64), 11234, 11248,
+	/*11234*/ uint16(xCondDataSize), 11238, 11243, 0,
+	/*11238*/ uint16(xSetOp), uint16(ROR),
+	/*11240*/ uint16(xArgRM16),
+	/*11241*/ uint16(xArgCL),
+	/*11242*/ uint16(xMatch),
+	/*11243*/ uint16(xSetOp), uint16(ROR),
+	/*11245*/ uint16(xArgRM32),
+	/*11246*/ uint16(xArgCL),
+	/*11247*/ uint16(xMatch),
+	/*11248*/ uint16(xCondDataSize), 11238, 11243, 11252,
+	/*11252*/ uint16(xSetOp), uint16(ROR),
+	/*11254*/ uint16(xArgRM64),
+	/*11255*/ uint16(xArgCL),
+	/*11256*/ uint16(xMatch),
+	/*11257*/ uint16(xCondIs64), 11260, 11274,
+	/*11260*/ uint16(xCondDataSize), 11264, 11269, 0,
+	/*11264*/ uint16(xSetOp), uint16(RCL),
+	/*11266*/ uint16(xArgRM16),
+	/*11267*/ uint16(xArgCL),
+	/*11268*/ uint16(xMatch),
+	/*11269*/ uint16(xSetOp), uint16(RCL),
+	/*11271*/ uint16(xArgRM32),
+	/*11272*/ uint16(xArgCL),
+	/*11273*/ uint16(xMatch),
+	/*11274*/ uint16(xCondDataSize), 11264, 11269, 11278,
+	/*11278*/ uint16(xSetOp), uint16(RCL),
+	/*11280*/ uint16(xArgRM64),
+	/*11281*/ uint16(xArgCL),
+	/*11282*/ uint16(xMatch),
+	/*11283*/ uint16(xCondIs64), 11286, 11300,
+	/*11286*/ uint16(xCondDataSize), 11290, 11295, 0,
+	/*11290*/ uint16(xSetOp), uint16(RCR),
+	/*11292*/ uint16(xArgRM16),
+	/*11293*/ uint16(xArgCL),
+	/*11294*/ uint16(xMatch),
+	/*11295*/ uint16(xSetOp), uint16(RCR),
+	/*11297*/ uint16(xArgRM32),
+	/*11298*/ uint16(xArgCL),
+	/*11299*/ uint16(xMatch),
+	/*11300*/ uint16(xCondDataSize), 11290, 11295, 11304,
+	/*11304*/ uint16(xSetOp), uint16(RCR),
+	/*11306*/ uint16(xArgRM64),
+	/*11307*/ uint16(xArgCL),
+	/*11308*/ uint16(xMatch),
+	/*11309*/ uint16(xCondIs64), 11312, 11326,
+	/*11312*/ uint16(xCondDataSize), 11316, 11321, 0,
+	/*11316*/ uint16(xSetOp), uint16(SHL),
+	/*11318*/ uint16(xArgRM16),
+	/*11319*/ uint16(xArgCL),
+	/*11320*/ uint16(xMatch),
+	/*11321*/ uint16(xSetOp), uint16(SHL),
+	/*11323*/ uint16(xArgRM32),
+	/*11324*/ uint16(xArgCL),
+	/*11325*/ uint16(xMatch),
+	/*11326*/ uint16(xCondDataSize), 11316, 11321, 11330,
+	/*11330*/ uint16(xSetOp), uint16(SHL),
+	/*11332*/ uint16(xArgRM64),
+	/*11333*/ uint16(xArgCL),
+	/*11334*/ uint16(xMatch),
+	/*11335*/ uint16(xCondIs64), 11338, 11352,
+	/*11338*/ uint16(xCondDataSize), 11342, 11347, 0,
+	/*11342*/ uint16(xSetOp), uint16(SHR),
+	/*11344*/ uint16(xArgRM16),
+	/*11345*/ uint16(xArgCL),
+	/*11346*/ uint16(xMatch),
+	/*11347*/ uint16(xSetOp), uint16(SHR),
+	/*11349*/ uint16(xArgRM32),
+	/*11350*/ uint16(xArgCL),
+	/*11351*/ uint16(xMatch),
+	/*11352*/ uint16(xCondDataSize), 11342, 11347, 11356,
+	/*11356*/ uint16(xSetOp), uint16(SHR),
+	/*11358*/ uint16(xArgRM64),
+	/*11359*/ uint16(xArgCL),
+	/*11360*/ uint16(xMatch),
+	/*11361*/ uint16(xCondIs64), 11364, 11378,
+	/*11364*/ uint16(xCondDataSize), 11368, 11373, 0,
+	/*11368*/ uint16(xSetOp), uint16(SAR),
+	/*11370*/ uint16(xArgRM16),
+	/*11371*/ uint16(xArgCL),
+	/*11372*/ uint16(xMatch),
+	/*11373*/ uint16(xSetOp), uint16(SAR),
+	/*11375*/ uint16(xArgRM32),
+	/*11376*/ uint16(xArgCL),
+	/*11377*/ uint16(xMatch),
+	/*11378*/ uint16(xCondDataSize), 11368, 11373, 11382,
+	/*11382*/ uint16(xSetOp), uint16(SAR),
+	/*11384*/ uint16(xArgRM64),
+	/*11385*/ uint16(xArgCL),
+	/*11386*/ uint16(xMatch),
+	/*11387*/ uint16(xCondIs64), 11390, 0,
+	/*11390*/ uint16(xSetOp), uint16(AAM),
+	/*11392*/ uint16(xReadIb),
+	/*11393*/ uint16(xArgImm8u),
+	/*11394*/ uint16(xMatch),
+	/*11395*/ uint16(xCondIs64), 11398, 0,
+	/*11398*/ uint16(xSetOp), uint16(AAD),
+	/*11400*/ uint16(xReadIb),
+	/*11401*/ uint16(xArgImm8u),
+	/*11402*/ uint16(xMatch),
+	/*11403*/ uint16(xCondIs64), 11406, 11409,
+	/*11406*/ uint16(xSetOp), uint16(XLATB),
+	/*11408*/ uint16(xMatch),
+	/*11409*/ uint16(xCondDataSize), 11406, 11406, 11413,
+	/*11413*/ uint16(xSetOp), uint16(XLATB),
+	/*11415*/ uint16(xMatch),
+	/*11416*/ uint16(xCondByte), 64,
+	0xc0, 11587,
+	0xc1, 11587,
+	0xc2, 11587,
+	0xc3, 11587,
+	0xc4, 11587,
+	0xc5, 11587,
+	0xc6, 11587,
+	0xc7, 11587,
+	0xc8, 11592,
+	0xc9, 11592,
+	0xca, 11592,
+	0xcb, 11592,
+	0xcc, 11592,
+	0xcd, 11592,
+	0xce, 11592,
+	0xcf, 11592,
+	0xd0, 11597,
+	0xd1, 11597,
+	0xd2, 11597,
+	0xd3, 11597,
+	0xd4, 11597,
+	0xd5, 11597,
+	0xd6, 11597,
+	0xd7, 11597,
+	0xd8, 11601,
+	0xd9, 11601,
+	0xda, 11601,
+	0xdb, 11601,
+	0xdc, 11601,
+	0xdd, 11601,
+	0xde, 11601,
+	0xdf, 11601,
+	0xe0, 11605,
+	0xe1, 11605,
+	0xe2, 11605,
+	0xe3, 11605,
+	0xe4, 11605,
+	0xe5, 11605,
+	0xe6, 11605,
+	0xe7, 11605,
+	0xe8, 11610,
+	0xe9, 11610,
+	0xea, 11610,
+	0xeb, 11610,
+	0xec, 11610,
+	0xed, 11610,
+	0xee, 11610,
+	0xef, 11610,
+	0xf0, 11615,
+	0xf1, 11615,
+	0xf2, 11615,
+	0xf3, 11615,
+	0xf4, 11615,
+	0xf5, 11615,
+	0xf6, 11615,
+	0xf7, 11615,
+	0xf8, 11620,
+	0xf9, 11620,
+	0xfa, 11620,
+	0xfb, 11620,
+	0xfc, 11620,
+	0xfd, 11620,
+	0xfe, 11620,
+	0xff, 11620,
+	/*11546*/ uint16(xCondSlashR),
+	11555, // 0
+	11559, // 1
+	11563, // 2
+	11567, // 3
+	11571, // 4
+	11575, // 5
+	11579, // 6
+	11583, // 7
+	/*11555*/ uint16(xSetOp), uint16(FADD),
+	/*11557*/ uint16(xArgM32fp),
+	/*11558*/ uint16(xMatch),
+	/*11559*/ uint16(xSetOp), uint16(FMUL),
+	/*11561*/ uint16(xArgM32fp),
+	/*11562*/ uint16(xMatch),
+	/*11563*/ uint16(xSetOp), uint16(FCOM),
+	/*11565*/ uint16(xArgM32fp),
+	/*11566*/ uint16(xMatch),
+	/*11567*/ uint16(xSetOp), uint16(FCOMP),
+	/*11569*/ uint16(xArgM32fp),
+	/*11570*/ uint16(xMatch),
+	/*11571*/ uint16(xSetOp), uint16(FSUB),
+	/*11573*/ uint16(xArgM32fp),
+	/*11574*/ uint16(xMatch),
+	/*11575*/ uint16(xSetOp), uint16(FSUBR),
+	/*11577*/ uint16(xArgM32fp),
+	/*11578*/ uint16(xMatch),
+	/*11579*/ uint16(xSetOp), uint16(FDIV),
+	/*11581*/ uint16(xArgM32fp),
+	/*11582*/ uint16(xMatch),
+	/*11583*/ uint16(xSetOp), uint16(FDIVR),
+	/*11585*/ uint16(xArgM32fp),
+	/*11586*/ uint16(xMatch),
+	/*11587*/ uint16(xSetOp), uint16(FADD),
+	/*11589*/ uint16(xArgST),
+	/*11590*/ uint16(xArgSTi),
+	/*11591*/ uint16(xMatch),
+	/*11592*/ uint16(xSetOp), uint16(FMUL),
+	/*11594*/ uint16(xArgST),
+	/*11595*/ uint16(xArgSTi),
+	/*11596*/ uint16(xMatch),
+	/*11597*/ uint16(xSetOp), uint16(FCOM),
 	/*11599*/ uint16(xArgSTi),
 	/*11600*/ uint16(xMatch),
-	/*11601*/ uint16(xSetOp), uint16(FDIVR),
-	/*11603*/ uint16(xArgST),
-	/*11604*/ uint16(xArgSTi),
-	/*11605*/ uint16(xMatch),
-	/*11606*/ uint16(xCondByte), 44,
-	0xc0, 11733,
-	0xc1, 11733,
-	0xc2, 11733,
-	0xc3, 11733,
-	0xc4, 11733,
-	0xc5, 11733,
-	0xc6, 11733,
-	0xc7, 11733,
-	0xc8, 11737,
-	0xc9, 11737,
-	0xca, 11737,
-	0xcb, 11737,
-	0xcc, 11737,
-	0xcd, 11737,
-	0xce, 11737,
-	0xcf, 11737,
-	0xD0, 11741,
-	0xE0, 11744,
-	0xE1, 11747,
-	0xE4, 11750,
-	0xE5, 11753,
-	0xE8, 11756,
-	0xE9, 11759,
-	0xEA, 11762,
-	0xEB, 11765,
-	0xEC, 11768,
-	0xED, 11771,
-	0xEE, 11774,
-	0xF0, 11777,
-	0xF1, 11780,
-	0xF2, 11783,
-	0xF3, 11786,
-	0xF4, 11789,
-	0xF5, 11792,
-	0xF6, 11795,
-	0xF7, 11798,
-	0xF8, 11801,
-	0xF9, 11804,
-	0xFA, 11807,
-	0xFB, 11810,
-	0xFC, 11813,
-	0xFD, 11816,
-	0xFE, 11819,
-	0xFF, 11822,
-	/*11696*/ uint16(xCondSlashR),
-	11705, // 0
+	/*11601*/ uint16(xSetOp), uint16(FCOMP),
+	/*11603*/ uint16(xArgSTi),
+	/*11604*/ uint16(xMatch),
+	/*11605*/ uint16(xSetOp), uint16(FSUB),
+	/*11607*/ uint16(xArgST),
+	/*11608*/ uint16(xArgSTi),
+	/*11609*/ uint16(xMatch),
+	/*11610*/ uint16(xSetOp), uint16(FSUBR),
+	/*11612*/ uint16(xArgST),
+	/*11613*/ uint16(xArgSTi),
+	/*11614*/ uint16(xMatch),
+	/*11615*/ uint16(xSetOp), uint16(FDIV),
+	/*11617*/ uint16(xArgST),
+	/*11618*/ uint16(xArgSTi),
+	/*11619*/ uint16(xMatch),
+	/*11620*/ uint16(xSetOp), uint16(FDIVR),
+	/*11622*/ uint16(xArgST),
+	/*11623*/ uint16(xArgSTi),
+	/*11624*/ uint16(xMatch),
+	/*11625*/ uint16(xCondByte), 44,
+	0xc0, 11752,
+	0xc1, 11752,
+	0xc2, 11752,
+	0xc3, 11752,
+	0xc4, 11752,
+	0xc5, 11752,
+	0xc6, 11752,
+	0xc7, 11752,
+	0xc8, 11756,
+	0xc9, 11756,
+	0xca, 11756,
+	0xcb, 11756,
+	0xcc, 11756,
+	0xcd, 11756,
+	0xce, 11756,
+	0xcf, 11756,
+	0xD0, 11760,
+	0xE0, 11763,
+	0xE1, 11766,
+	0xE4, 11769,
+	0xE5, 11772,
+	0xE8, 11775,
+	0xE9, 11778,
+	0xEA, 11781,
+	0xEB, 11784,
+	0xEC, 11787,
+	0xED, 11790,
+	0xEE, 11793,
+	0xF0, 11796,
+	0xF1, 11799,
+	0xF2, 11802,
+	0xF3, 11805,
+	0xF4, 11808,
+	0xF5, 11811,
+	0xF6, 11814,
+	0xF7, 11817,
+	0xF8, 11820,
+	0xF9, 11823,
+	0xFA, 11826,
+	0xFB, 11829,
+	0xFC, 11832,
+	0xFD, 11835,
+	0xFE, 11838,
+	0xFF, 11841,
+	/*11715*/ uint16(xCondSlashR),
+	11724, // 0
 	0,     // 1
-	11709, // 2
-	11713, // 3
-	11717, // 4
-	11721, // 5
-	11725, // 6
-	11729, // 7
-	/*11705*/ uint16(xSetOp), uint16(FLD),
-	/*11707*/ uint16(xArgM32fp),
-	/*11708*/ uint16(xMatch),
-	/*11709*/ uint16(xSetOp), uint16(FST),
-	/*11711*/ uint16(xArgM32fp),
-	/*11712*/ uint16(xMatch),
-	/*11713*/ uint16(xSetOp), uint16(FSTP),
-	/*11715*/ uint16(xArgM32fp),
-	/*11716*/ uint16(xMatch),
-	/*11717*/ uint16(xSetOp), uint16(FLDENV),
-	/*11719*/ uint16(xArgM1428byte),
-	/*11720*/ uint16(xMatch),
-	/*11721*/ uint16(xSetOp), uint16(FLDCW),
-	/*11723*/ uint16(xArgM2byte),
-	/*11724*/ uint16(xMatch),
-	/*11725*/ uint16(xSetOp), uint16(FNSTENV),
-	/*11727*/ uint16(xArgM1428byte),
-	/*11728*/ uint16(xMatch),
-	/*11729*/ uint16(xSetOp), uint16(FNSTCW),
-	/*11731*/ uint16(xArgM2byte),
-	/*11732*/ uint16(xMatch),
-	/*11733*/ uint16(xSetOp), uint16(FLD),
-	/*11735*/ uint16(xArgSTi),
-	/*11736*/ uint16(xMatch),
-	/*11737*/ uint16(xSetOp), uint16(FXCH),
-	/*11739*/ uint16(xArgSTi),
-	/*11740*/ uint16(xMatch),
-	/*11741*/ uint16(xSetOp), uint16(FNOP),
+	11728, // 2
+	11732, // 3
+	11736, // 4
+	11740, // 5
+	11744, // 6
+	11748, // 7
+	/*11724*/ uint16(xSetOp), uint16(FLD),
+	/*11726*/ uint16(xArgM32fp),
+	/*11727*/ uint16(xMatch),
+	/*11728*/ uint16(xSetOp), uint16(FST),
+	/*11730*/ uint16(xArgM32fp),
+	/*11731*/ uint16(xMatch),
+	/*11732*/ uint16(xSetOp), uint16(FSTP),
+	/*11734*/ uint16(xArgM32fp),
+	/*11735*/ uint16(xMatch),
+	/*11736*/ uint16(xSetOp), uint16(FLDENV),
+	/*11738*/ uint16(xArgM1428byte),
+	/*11739*/ uint16(xMatch),
+	/*11740*/ uint16(xSetOp), uint16(FLDCW),
+	/*11742*/ uint16(xArgM2byte),
 	/*11743*/ uint16(xMatch),
-	/*11744*/ uint16(xSetOp), uint16(FCHS),
-	/*11746*/ uint16(xMatch),
-	/*11747*/ uint16(xSetOp), uint16(FABS),
-	/*11749*/ uint16(xMatch),
-	/*11750*/ uint16(xSetOp), uint16(FTST),
-	/*11752*/ uint16(xMatch),
-	/*11753*/ uint16(xSetOp), uint16(FXAM),
+	/*11744*/ uint16(xSetOp), uint16(FNSTENV),
+	/*11746*/ uint16(xArgM1428byte),
+	/*11747*/ uint16(xMatch),
+	/*11748*/ uint16(xSetOp), uint16(FNSTCW),
+	/*11750*/ uint16(xArgM2byte),
+	/*11751*/ uint16(xMatch),
+	/*11752*/ uint16(xSetOp), uint16(FLD),
+	/*11754*/ uint16(xArgSTi),
 	/*11755*/ uint16(xMatch),
-	/*11756*/ uint16(xSetOp), uint16(FLD1),
-	/*11758*/ uint16(xMatch),
-	/*11759*/ uint16(xSetOp), uint16(FLDL2T),
-	/*11761*/ uint16(xMatch),
-	/*11762*/ uint16(xSetOp), uint16(FLDL2E),
-	/*11764*/ uint16(xMatch),
-	/*11765*/ uint16(xSetOp), uint16(FLDPI),
-	/*11767*/ uint16(xMatch),
-	/*11768*/ uint16(xSetOp), uint16(FLDLG2),
-	/*11770*/ uint16(xMatch),
-	/*11771*/ uint16(xSetOp), uint16(FLDLN2),
-	/*11773*/ uint16(xMatch),
-	/*11774*/ uint16(xSetOp), uint16(FLDZ),
-	/*11776*/ uint16(xMatch),
-	/*11777*/ uint16(xSetOp), uint16(F2XM1),
-	/*11779*/ uint16(xMatch),
-	/*11780*/ uint16(xSetOp), uint16(FYL2X),
-	/*11782*/ uint16(xMatch),
-	/*11783*/ uint16(xSetOp), uint16(FPTAN),
-	/*11785*/ uint16(xMatch),
-	/*11786*/ uint16(xSetOp), uint16(FPATAN),
-	/*11788*/ uint16(xMatch),
-	/*11789*/ uint16(xSetOp), uint16(FXTRACT),
-	/*11791*/ uint16(xMatch),
-	/*11792*/ uint16(xSetOp), uint16(FPREM1),
-	/*11794*/ uint16(xMatch),
-	/*11795*/ uint16(xSetOp), uint16(FDECSTP),
-	/*11797*/ uint16(xMatch),
-	/*11798*/ uint16(xSetOp), uint16(FINCSTP),
-	/*11800*/ uint16(xMatch),
-	/*11801*/ uint16(xSetOp), uint16(FPREM),
-	/*11803*/ uint16(xMatch),
-	/*11804*/ uint16(xSetOp), uint16(FYL2XP1),
-	/*11806*/ uint16(xMatch),
-	/*11807*/ uint16(xSetOp), uint16(FSQRT),
-	/*11809*/ uint16(xMatch),
-	/*11810*/ uint16(xSetOp), uint16(FSINCOS),
-	/*11812*/ uint16(xMatch),
-	/*11813*/ uint16(xSetOp), uint16(FRNDINT),
-	/*11815*/ uint16(xMatch),
-	/*11816*/ uint16(xSetOp), uint16(FSCALE),
-	/*11818*/ uint16(xMatch),
-	/*11819*/ uint16(xSetOp), uint16(FSIN),
-	/*11821*/ uint16(xMatch),
-	/*11822*/ uint16(xSetOp), uint16(FCOS),
-	/*11824*/ uint16(xMatch),
-	/*11825*/ uint16(xCondByte), 33,
-	0xc0, 11934,
-	0xc1, 11934,
-	0xc2, 11934,
-	0xc3, 11934,
-	0xc4, 11934,
-	0xc5, 11934,
-	0xc6, 11934,
-	0xc7, 11934,
-	0xc8, 11939,
-	0xc9, 11939,
-	0xca, 11939,
-	0xcb, 11939,
-	0xcc, 11939,
-	0xcd, 11939,
-	0xce, 11939,
-	0xcf, 11939,
-	0xd0, 11944,
-	0xd1, 11944,
-	0xd2, 11944,
-	0xd3, 11944,
-	0xd4, 11944,
-	0xd5, 11944,
-	0xd6, 11944,
-	0xd7, 11944,
-	0xd8, 11949,
-	0xd9, 11949,
-	0xda, 11949,
-	0xdb, 11949,
-	0xdc, 11949,
-	0xdd, 11949,
-	0xde, 11949,
-	0xdf, 11949,
-	0xE9, 11954,
-	/*11893*/ uint16(xCondSlashR),
-	11902, // 0
-	11906, // 1
-	11910, // 2
-	11914, // 3
-	11918, // 4
-	11922, // 5
-	11926, // 6
-	11930, // 7
-	/*11902*/ uint16(xSetOp), uint16(FIADD),
-	/*11904*/ uint16(xArgM32int),
-	/*11905*/ uint16(xMatch),
-	/*11906*/ uint16(xSetOp), uint16(FIMUL),
-	/*11908*/ uint16(xArgM32int),
-	/*11909*/ uint16(xMatch),
-	/*11910*/ uint16(xSetOp), uint16(FICOM),
-	/*11912*/ uint16(xArgM32int),
-	/*11913*/ uint16(xMatch),
-	/*11914*/ uint16(xSetOp), uint16(FICOMP),
-	/*11916*/ uint16(xArgM32int),
-	/*11917*/ uint16(xMatch),
-	/*11918*/ uint16(xSetOp), uint16(FISUB),
-	/*11920*/ uint16(xArgM32int),
-	/*11921*/ uint16(xMatch),
-	/*11922*/ uint16(xSetOp), uint16(FISUBR),
-	/*11924*/ uint16(xArgM32int),
-	/*11925*/ uint16(xMatch),
-	/*11926*/ uint16(xSetOp), uint16(FIDIV),
-	/*11928*/ uint16(xArgM32int),
-	/*11929*/ uint16(xMatch),
-	/*11930*/ uint16(xSetOp), uint16(FIDIVR),
-	/*11932*/ uint16(xArgM32int),
-	/*11933*/ uint16(xMatch),
-	/*11934*/ uint16(xSetOp), uint16(FCMOVB),
-	/*11936*/ uint16(xArgST),
-	/*11937*/ uint16(xArgSTi),
-	/*11938*/ uint16(xMatch),
-	/*11939*/ uint16(xSetOp), uint16(FCMOVE),
-	/*11941*/ uint16(xArgST),
-	/*11942*/ uint16(xArgSTi),
-	/*11943*/ uint16(xMatch),
-	/*11944*/ uint16(xSetOp), uint16(FCMOVBE),
-	/*11946*/ uint16(xArgST),
-	/*11947*/ uint16(xArgSTi),
+	/*11756*/ uint16(xSetOp), uint16(FXCH),
+	/*11758*/ uint16(xArgSTi),
+	/*11759*/ uint16(xMatch),
+	/*11760*/ uint16(xSetOp), uint16(FNOP),
+	/*11762*/ uint16(xMatch),
+	/*11763*/ uint16(xSetOp), uint16(FCHS),
+	/*11765*/ uint16(xMatch),
+	/*11766*/ uint16(xSetOp), uint16(FABS),
+	/*11768*/ uint16(xMatch),
+	/*11769*/ uint16(xSetOp), uint16(FTST),
+	/*11771*/ uint16(xMatch),
+	/*11772*/ uint16(xSetOp), uint16(FXAM),
+	/*11774*/ uint16(xMatch),
+	/*11775*/ uint16(xSetOp), uint16(FLD1),
+	/*11777*/ uint16(xMatch),
+	/*11778*/ uint16(xSetOp), uint16(FLDL2T),
+	/*11780*/ uint16(xMatch),
+	/*11781*/ uint16(xSetOp), uint16(FLDL2E),
+	/*11783*/ uint16(xMatch),
+	/*11784*/ uint16(xSetOp), uint16(FLDPI),
+	/*11786*/ uint16(xMatch),
+	/*11787*/ uint16(xSetOp), uint16(FLDLG2),
+	/*11789*/ uint16(xMatch),
+	/*11790*/ uint16(xSetOp), uint16(FLDLN2),
+	/*11792*/ uint16(xMatch),
+	/*11793*/ uint16(xSetOp), uint16(FLDZ),
+	/*11795*/ uint16(xMatch),
+	/*11796*/ uint16(xSetOp), uint16(F2XM1),
+	/*11798*/ uint16(xMatch),
+	/*11799*/ uint16(xSetOp), uint16(FYL2X),
+	/*11801*/ uint16(xMatch),
+	/*11802*/ uint16(xSetOp), uint16(FPTAN),
+	/*11804*/ uint16(xMatch),
+	/*11805*/ uint16(xSetOp), uint16(FPATAN),
+	/*11807*/ uint16(xMatch),
+	/*11808*/ uint16(xSetOp), uint16(FXTRACT),
+	/*11810*/ uint16(xMatch),
+	/*11811*/ uint16(xSetOp), uint16(FPREM1),
+	/*11813*/ uint16(xMatch),
+	/*11814*/ uint16(xSetOp), uint16(FDECSTP),
+	/*11816*/ uint16(xMatch),
+	/*11817*/ uint16(xSetOp), uint16(FINCSTP),
+	/*11819*/ uint16(xMatch),
+	/*11820*/ uint16(xSetOp), uint16(FPREM),
+	/*11822*/ uint16(xMatch),
+	/*11823*/ uint16(xSetOp), uint16(FYL2XP1),
+	/*11825*/ uint16(xMatch),
+	/*11826*/ uint16(xSetOp), uint16(FSQRT),
+	/*11828*/ uint16(xMatch),
+	/*11829*/ uint16(xSetOp), uint16(FSINCOS),
+	/*11831*/ uint16(xMatch),
+	/*11832*/ uint16(xSetOp), uint16(FRNDINT),
+	/*11834*/ uint16(xMatch),
+	/*11835*/ uint16(xSetOp), uint16(FSCALE),
+	/*11837*/ uint16(xMatch),
+	/*11838*/ uint16(xSetOp), uint16(FSIN),
+	/*11840*/ uint16(xMatch),
+	/*11841*/ uint16(xSetOp), uint16(FCOS),
+	/*11843*/ uint16(xMatch),
+	/*11844*/ uint16(xCondByte), 33,
+	0xc0, 11953,
+	0xc1, 11953,
+	0xc2, 11953,
+	0xc3, 11953,
+	0xc4, 11953,
+	0xc5, 11953,
+	0xc6, 11953,
+	0xc7, 11953,
+	0xc8, 11958,
+	0xc9, 11958,
+	0xca, 11958,
+	0xcb, 11958,
+	0xcc, 11958,
+	0xcd, 11958,
+	0xce, 11958,
+	0xcf, 11958,
+	0xd0, 11963,
+	0xd1, 11963,
+	0xd2, 11963,
+	0xd3, 11963,
+	0xd4, 11963,
+	0xd5, 11963,
+	0xd6, 11963,
+	0xd7, 11963,
+	0xd8, 11968,
+	0xd9, 11968,
+	0xda, 11968,
+	0xdb, 11968,
+	0xdc, 11968,
+	0xdd, 11968,
+	0xde, 11968,
+	0xdf, 11968,
+	0xE9, 11973,
+	/*11912*/ uint16(xCondSlashR),
+	11921, // 0
+	11925, // 1
+	11929, // 2
+	11933, // 3
+	11937, // 4
+	11941, // 5
+	11945, // 6
+	11949, // 7
+	/*11921*/ uint16(xSetOp), uint16(FIADD),
+	/*11923*/ uint16(xArgM32int),
+	/*11924*/ uint16(xMatch),
+	/*11925*/ uint16(xSetOp), uint16(FIMUL),
+	/*11927*/ uint16(xArgM32int),
+	/*11928*/ uint16(xMatch),
+	/*11929*/ uint16(xSetOp), uint16(FICOM),
+	/*11931*/ uint16(xArgM32int),
+	/*11932*/ uint16(xMatch),
+	/*11933*/ uint16(xSetOp), uint16(FICOMP),
+	/*11935*/ uint16(xArgM32int),
+	/*11936*/ uint16(xMatch),
+	/*11937*/ uint16(xSetOp), uint16(FISUB),
+	/*11939*/ uint16(xArgM32int),
+	/*11940*/ uint16(xMatch),
+	/*11941*/ uint16(xSetOp), uint16(FISUBR),
+	/*11943*/ uint16(xArgM32int),
+	/*11944*/ uint16(xMatch),
+	/*11945*/ uint16(xSetOp), uint16(FIDIV),
+	/*11947*/ uint16(xArgM32int),
 	/*11948*/ uint16(xMatch),
-	/*11949*/ uint16(xSetOp), uint16(FCMOVU),
-	/*11951*/ uint16(xArgST),
-	/*11952*/ uint16(xArgSTi),
-	/*11953*/ uint16(xMatch),
-	/*11954*/ uint16(xSetOp), uint16(FUCOMPP),
-	/*11956*/ uint16(xMatch),
-	/*11957*/ uint16(xCondByte), 50,
-	0xc0, 12092,
-	0xc1, 12092,
-	0xc2, 12092,
-	0xc3, 12092,
-	0xc4, 12092,
-	0xc5, 12092,
-	0xc6, 12092,
-	0xc7, 12092,
-	0xc8, 12097,
-	0xc9, 12097,
-	0xca, 12097,
-	0xcb, 12097,
-	0xcc, 12097,
-	0xcd, 12097,
-	0xce, 12097,
-	0xcf, 12097,
-	0xd0, 12102,
-	0xd1, 12102,
-	0xd2, 12102,
-	0xd3, 12102,
-	0xd4, 12102,
-	0xd5, 12102,
-	0xd6, 12102,
-	0xd7, 12102,
-	0xd8, 12107,
-	0xd9, 12107,
-	0xda, 12107,
-	0xdb, 12107,
-	0xdc, 12107,
-	0xdd, 12107,
-	0xde, 12107,
-	0xdf, 12107,
-	0xE2, 12112,
-	0xE3, 12115,
-	0xe8, 12118,
-	0xe9, 12118,
-	0xea, 12118,
-	0xeb, 12118,
-	0xec, 12118,
-	0xed, 12118,
-	0xee, 12118,
-	0xef, 12118,
-	0xf0, 12123,
-	0xf1, 12123,
-	0xf2, 12123,
-	0xf3, 12123,
-	0xf4, 12123,
-	0xf5, 12123,
-	0xf6, 12123,
-	0xf7, 12123,
-	/*12059*/ uint16(xCondSlashR),
-	12068, // 0
-	12072, // 1
-	12076, // 2
-	12080, // 3
+	/*11949*/ uint16(xSetOp), uint16(FIDIVR),
+	/*11951*/ uint16(xArgM32int),
+	/*11952*/ uint16(xMatch),
+	/*11953*/ uint16(xSetOp), uint16(FCMOVB),
+	/*11955*/ uint16(xArgST),
+	/*11956*/ uint16(xArgSTi),
+	/*11957*/ uint16(xMatch),
+	/*11958*/ uint16(xSetOp), uint16(FCMOVE),
+	/*11960*/ uint16(xArgST),
+	/*11961*/ uint16(xArgSTi),
+	/*11962*/ uint16(xMatch),
+	/*11963*/ uint16(xSetOp), uint16(FCMOVBE),
+	/*11965*/ uint16(xArgST),
+	/*11966*/ uint16(xArgSTi),
+	/*11967*/ uint16(xMatch),
+	/*11968*/ uint16(xSetOp), uint16(FCMOVU),
+	/*11970*/ uint16(xArgST),
+	/*11971*/ uint16(xArgSTi),
+	/*11972*/ uint16(xMatch),
+	/*11973*/ uint16(xSetOp), uint16(FUCOMPP),
+	/*11975*/ uint16(xMatch),
+	/*11976*/ uint16(xCondByte), 50,
+	0xc0, 12111,
+	0xc1, 12111,
+	0xc2, 12111,
+	0xc3, 12111,
+	0xc4, 12111,
+	0xc5, 12111,
+	0xc6, 12111,
+	0xc7, 12111,
+	0xc8, 12116,
+	0xc9, 12116,
+	0xca, 12116,
+	0xcb, 12116,
+	0xcc, 12116,
+	0xcd, 12116,
+	0xce, 12116,
+	0xcf, 12116,
+	0xd0, 12121,
+	0xd1, 12121,
+	0xd2, 12121,
+	0xd3, 12121,
+	0xd4, 12121,
+	0xd5, 12121,
+	0xd6, 12121,
+	0xd7, 12121,
+	0xd8, 12126,
+	0xd9, 12126,
+	0xda, 12126,
+	0xdb, 12126,
+	0xdc, 12126,
+	0xdd, 12126,
+	0xde, 12126,
+	0xdf, 12126,
+	0xE2, 12131,
+	0xE3, 12134,
+	0xe8, 12137,
+	0xe9, 12137,
+	0xea, 12137,
+	0xeb, 12137,
+	0xec, 12137,
+	0xed, 12137,
+	0xee, 12137,
+	0xef, 12137,
+	0xf0, 12142,
+	0xf1, 12142,
+	0xf2, 12142,
+	0xf3, 12142,
+	0xf4, 12142,
+	0xf5, 12142,
+	0xf6, 12142,
+	0xf7, 12142,
+	/*12078*/ uint16(xCondSlashR),
+	12087, // 0
+	12091, // 1
+	12095, // 2
+	12099, // 3
 	0,     // 4
-	12084, // 5
+	12103, // 5
 	0,     // 6
-	12088, // 7
-	/*12068*/ uint16(xSetOp), uint16(FILD),
-	/*12070*/ uint16(xArgM32int),
-	/*12071*/ uint16(xMatch),
-	/*12072*/ uint16(xSetOp), uint16(FISTTP),
-	/*12074*/ uint16(xArgM32int),
-	/*12075*/ uint16(xMatch),
-	/*12076*/ uint16(xSetOp), uint16(FIST),
-	/*12078*/ uint16(xArgM32int),
-	/*12079*/ uint16(xMatch),
-	/*12080*/ uint16(xSetOp), uint16(FISTP),
-	/*12082*/ uint16(xArgM32int),
-	/*12083*/ uint16(xMatch),
-	/*12084*/ uint16(xSetOp), uint16(FLD),
-	/*12086*/ uint16(xArgM80fp),
-	/*12087*/ uint16(xMatch),
-	/*12088*/ uint16(xSetOp), uint16(FSTP),
-	/*12090*/ uint16(xArgM80fp),
-	/*12091*/ uint16(xMatch),
-	/*12092*/ uint16(xSetOp), uint16(FCMOVNB),
-	/*12094*/ uint16(xArgST),
-	/*12095*/ uint16(xArgSTi),
-	/*12096*/ uint16(xMatch),
-	/*12097*/ uint16(xSetOp), uint16(FCMOVNE),
-	/*12099*/ uint16(xArgST),
-	/*12100*/ uint16(xArgSTi),
-	/*12101*/ uint16(xMatch),
-	/*12102*/ uint16(xSetOp), uint16(FCMOVNBE),
-	/*12104*/ uint16(xArgST),
-	/*12105*/ uint16(xArgSTi),
+	12107, // 7
+	/*12087*/ uint16(xSetOp), uint16(FILD),
+	/*12089*/ uint16(xArgM32int),
+	/*12090*/ uint16(xMatch),
+	/*12091*/ uint16(xSetOp), uint16(FISTTP),
+	/*12093*/ uint16(xArgM32int),
+	/*12094*/ uint16(xMatch),
+	/*12095*/ uint16(xSetOp), uint16(FIST),
+	/*12097*/ uint16(xArgM32int),
+	/*12098*/ uint16(xMatch),
+	/*12099*/ uint16(xSetOp), uint16(FISTP),
+	/*12101*/ uint16(xArgM32int),
+	/*12102*/ uint16(xMatch),
+	/*12103*/ uint16(xSetOp), uint16(FLD),
+	/*12105*/ uint16(xArgM80fp),
 	/*12106*/ uint16(xMatch),
-	/*12107*/ uint16(xSetOp), uint16(FCMOVNU),
-	/*12109*/ uint16(xArgST),
-	/*12110*/ uint16(xArgSTi),
-	/*12111*/ uint16(xMatch),
-	/*12112*/ uint16(xSetOp), uint16(FNCLEX),
-	/*12114*/ uint16(xMatch),
-	/*12115*/ uint16(xSetOp), uint16(FNINIT),
-	/*12117*/ uint16(xMatch),
-	/*12118*/ uint16(xSetOp), uint16(FUCOMI),
-	/*12120*/ uint16(xArgST),
-	/*12121*/ uint16(xArgSTi),
-	/*12122*/ uint16(xMatch),
-	/*12123*/ uint16(xSetOp), uint16(FCOMI),
-	/*12125*/ uint16(xArgST),
-	/*12126*/ uint16(xArgSTi),
-	/*12127*/ uint16(xMatch),
-	/*12128*/ uint16(xCondByte), 48,
-	0xc0, 12267,
-	0xc1, 12267,
-	0xc2, 12267,
-	0xc3, 12267,
-	0xc4, 12267,
-	0xc5, 12267,
-	0xc6, 12267,
-	0xc7, 12267,
-	0xc8, 12272,
-	0xc9, 12272,
-	0xca, 12272,
-	0xcb, 12272,
-	0xcc, 12272,
-	0xcd, 12272,
-	0xce, 12272,
-	0xcf, 12272,
-	0xe0, 12277,
-	0xe1, 12277,
-	0xe2, 12277,
-	0xe3, 12277,
-	0xe4, 12277,
-	0xe5, 12277,
-	0xe6, 12277,
-	0xe7, 12277,
-	0xe8, 12282,
-	0xe9, 12282,
-	0xea, 12282,
-	0xeb, 12282,
-	0xec, 12282,
-	0xed, 12282,
-	0xee, 12282,
-	0xef, 12282,
-	0xf0, 12287,
-	0xf1, 12287,
-	0xf2, 12287,
-	0xf3, 12287,
-	0xf4, 12287,
-	0xf5, 12287,
-	0xf6, 12287,
-	0xf7, 12287,
-	0xf8, 12292,
-	0xf9, 12292,
-	0xfa, 12292,
-	0xfb, 12292,
-	0xfc, 12292,
-	0xfd, 12292,
-	0xfe, 12292,
-	0xff, 12292,
-	/*12226*/ uint16(xCondSlashR),
-	12235, // 0
-	12239, // 1
-	12243, // 2
-	12247, // 3
-	12251, // 4
-	12255, // 5
-	12259, // 6
-	12263, // 7
-	/*12235*/ uint16(xSetOp), uint16(FADD),
-	/*12237*/ uint16(xArgM64fp),
-	/*12238*/ uint16(xMatch),
-	/*12239*/ uint16(xSetOp), uint16(FMUL),
-	/*12241*/ uint16(xArgM64fp),
-	/*12242*/ uint16(xMatch),
-	/*12243*/ uint16(xSetOp), uint16(FCOM),
-	/*12245*/ uint16(xArgM64fp),
-	/*12246*/ uint16(xMatch),
-	/*12247*/ uint16(xSetOp), uint16(FCOMP),
-	/*12249*/ uint16(xArgM64fp),
-	/*12250*/ uint16(xMatch),
-	/*12251*/ uint16(xSetOp), uint16(FSUB),
-	/*12253*/ uint16(xArgM64fp),
-	/*12254*/ uint16(xMatch),
-	/*12255*/ uint16(xSetOp), uint16(FSUBR),
-	/*12257*/ uint16(xArgM64fp),
-	/*12258*/ uint16(xMatch),
-	/*12259*/ uint16(xSetOp), uint16(FDIV),
-	/*12261*/ uint16(xArgM64fp),
-	/*12262*/ uint16(xMatch),
-	/*12263*/ uint16(xSetOp), uint16(FDIVR),
-	/*12265*/ uint16(xArgM64fp),
-	/*12266*/ uint16(xMatch),
-	/*12267*/ uint16(xSetOp), uint16(FADD),
-	/*12269*/ uint16(xArgSTi),
-	/*12270*/ uint16(xArgST),
-	/*12271*/ uint16(xMatch),
-	/*12272*/ uint16(xSetOp), uint16(FMUL),
-	/*12274*/ uint16(xArgSTi),
-	/*12275*/ uint16(xArgST),
-	/*12276*/ uint16(xMatch),
-	/*12277*/ uint16(xSetOp), uint16(FSUBR),
-	/*12279*/ uint16(xArgSTi),
-	/*12280*/ uint16(xArgST),
+	/*12107*/ uint16(xSetOp), uint16(FSTP),
+	/*12109*/ uint16(xArgM80fp),
+	/*12110*/ uint16(xMatch),
+	/*12111*/ uint16(xSetOp), uint16(FCMOVNB),
+	/*12113*/ uint16(xArgST),
+	/*12114*/ uint16(xArgSTi),
+	/*12115*/ uint16(xMatch),
+	/*12116*/ uint16(xSetOp), uint16(FCMOVNE),
+	/*12118*/ uint16(xArgST),
+	/*12119*/ uint16(xArgSTi),
+	/*12120*/ uint16(xMatch),
+	/*12121*/ uint16(xSetOp), uint16(FCMOVNBE),
+	/*12123*/ uint16(xArgST),
+	/*12124*/ uint16(xArgSTi),
+	/*12125*/ uint16(xMatch),
+	/*12126*/ uint16(xSetOp), uint16(FCMOVNU),
+	/*12128*/ uint16(xArgST),
+	/*12129*/ uint16(xArgSTi),
+	/*12130*/ uint16(xMatch),
+	/*12131*/ uint16(xSetOp), uint16(FNCLEX),
+	/*12133*/ uint16(xMatch),
+	/*12134*/ uint16(xSetOp), uint16(FNINIT),
+	/*12136*/ uint16(xMatch),
+	/*12137*/ uint16(xSetOp), uint16(FUCOMI),
+	/*12139*/ uint16(xArgST),
+	/*12140*/ uint16(xArgSTi),
+	/*12141*/ uint16(xMatch),
+	/*12142*/ uint16(xSetOp), uint16(FCOMI),
+	/*12144*/ uint16(xArgST),
+	/*12145*/ uint16(xArgSTi),
+	/*12146*/ uint16(xMatch),
+	/*12147*/ uint16(xCondByte), 48,
+	0xc0, 12286,
+	0xc1, 12286,
+	0xc2, 12286,
+	0xc3, 12286,
+	0xc4, 12286,
+	0xc5, 12286,
+	0xc6, 12286,
+	0xc7, 12286,
+	0xc8, 12291,
+	0xc9, 12291,
+	0xca, 12291,
+	0xcb, 12291,
+	0xcc, 12291,
+	0xcd, 12291,
+	0xce, 12291,
+	0xcf, 12291,
+	0xe0, 12296,
+	0xe1, 12296,
+	0xe2, 12296,
+	0xe3, 12296,
+	0xe4, 12296,
+	0xe5, 12296,
+	0xe6, 12296,
+	0xe7, 12296,
+	0xe8, 12301,
+	0xe9, 12301,
+	0xea, 12301,
+	0xeb, 12301,
+	0xec, 12301,
+	0xed, 12301,
+	0xee, 12301,
+	0xef, 12301,
+	0xf0, 12306,
+	0xf1, 12306,
+	0xf2, 12306,
+	0xf3, 12306,
+	0xf4, 12306,
+	0xf5, 12306,
+	0xf6, 12306,
+	0xf7, 12306,
+	0xf8, 12311,
+	0xf9, 12311,
+	0xfa, 12311,
+	0xfb, 12311,
+	0xfc, 12311,
+	0xfd, 12311,
+	0xfe, 12311,
+	0xff, 12311,
+	/*12245*/ uint16(xCondSlashR),
+	12254, // 0
+	12258, // 1
+	12262, // 2
+	12266, // 3
+	12270, // 4
+	12274, // 5
+	12278, // 6
+	12282, // 7
+	/*12254*/ uint16(xSetOp), uint16(FADD),
+	/*12256*/ uint16(xArgM64fp),
+	/*12257*/ uint16(xMatch),
+	/*12258*/ uint16(xSetOp), uint16(FMUL),
+	/*12260*/ uint16(xArgM64fp),
+	/*12261*/ uint16(xMatch),
+	/*12262*/ uint16(xSetOp), uint16(FCOM),
+	/*12264*/ uint16(xArgM64fp),
+	/*12265*/ uint16(xMatch),
+	/*12266*/ uint16(xSetOp), uint16(FCOMP),
+	/*12268*/ uint16(xArgM64fp),
+	/*12269*/ uint16(xMatch),
+	/*12270*/ uint16(xSetOp), uint16(FSUB),
+	/*12272*/ uint16(xArgM64fp),
+	/*12273*/ uint16(xMatch),
+	/*12274*/ uint16(xSetOp), uint16(FSUBR),
+	/*12276*/ uint16(xArgM64fp),
+	/*12277*/ uint16(xMatch),
+	/*12278*/ uint16(xSetOp), uint16(FDIV),
+	/*12280*/ uint16(xArgM64fp),
 	/*12281*/ uint16(xMatch),
-	/*12282*/ uint16(xSetOp), uint16(FSUB),
-	/*12284*/ uint16(xArgSTi),
-	/*12285*/ uint16(xArgST),
-	/*12286*/ uint16(xMatch),
-	/*12287*/ uint16(xSetOp), uint16(FDIVR),
-	/*12289*/ uint16(xArgSTi),
-	/*12290*/ uint16(xArgST),
-	/*12291*/ uint16(xMatch),
-	/*12292*/ uint16(xSetOp), uint16(FDIV),
-	/*12294*/ uint16(xArgSTi),
-	/*12295*/ uint16(xArgST),
-	/*12296*/ uint16(xMatch),
-	/*12297*/ uint16(xCondByte), 40,
-	0xc0, 12416,
-	0xc1, 12416,
-	0xc2, 12416,
-	0xc3, 12416,
-	0xc4, 12416,
-	0xc5, 12416,
-	0xc6, 12416,
-	0xc7, 12416,
-	0xd0, 12420,
-	0xd1, 12420,
-	0xd2, 12420,
-	0xd3, 12420,
-	0xd4, 12420,
-	0xd5, 12420,
-	0xd6, 12420,
-	0xd7, 12420,
-	0xd8, 12424,
-	0xd9, 12424,
-	0xda, 12424,
-	0xdb, 12424,
-	0xdc, 12424,
-	0xdd, 12424,
-	0xde, 12424,
-	0xdf, 12424,
-	0xe0, 12428,
-	0xe1, 12428,
-	0xe2, 12428,
-	0xe3, 12428,
-	0xe4, 12428,
-	0xe5, 12428,
-	0xe6, 12428,
-	0xe7, 12428,
-	0xe8, 12432,
-	0xe9, 12432,
-	0xea, 12432,
-	0xeb, 12432,
-	0xec, 12432,
-	0xed, 12432,
-	0xee, 12432,
-	0xef, 12432,
-	/*12379*/ uint16(xCondSlashR),
-	12388, // 0
-	12392, // 1
-	12396, // 2
-	12400, // 3
-	12404, // 4
+	/*12282*/ uint16(xSetOp), uint16(FDIVR),
+	/*12284*/ uint16(xArgM64fp),
+	/*12285*/ uint16(xMatch),
+	/*12286*/ uint16(xSetOp), uint16(FADD),
+	/*12288*/ uint16(xArgSTi),
+	/*12289*/ uint16(xArgST),
+	/*12290*/ uint16(xMatch),
+	/*12291*/ uint16(xSetOp), uint16(FMUL),
+	/*12293*/ uint16(xArgSTi),
+	/*12294*/ uint16(xArgST),
+	/*12295*/ uint16(xMatch),
+	/*12296*/ uint16(xSetOp), uint16(FSUBR),
+	/*12298*/ uint16(xArgSTi),
+	/*12299*/ uint16(xArgST),
+	/*12300*/ uint16(xMatch),
+	/*12301*/ uint16(xSetOp), uint16(FSUB),
+	/*12303*/ uint16(xArgSTi),
+	/*12304*/ uint16(xArgST),
+	/*12305*/ uint16(xMatch),
+	/*12306*/ uint16(xSetOp), uint16(FDIVR),
+	/*12308*/ uint16(xArgSTi),
+	/*12309*/ uint16(xArgST),
+	/*12310*/ uint16(xMatch),
+	/*12311*/ uint16(xSetOp), uint16(FDIV),
+	/*12313*/ uint16(xArgSTi),
+	/*12314*/ uint16(xArgST),
+	/*12315*/ uint16(xMatch),
+	/*12316*/ uint16(xCondByte), 40,
+	0xc0, 12435,
+	0xc1, 12435,
+	0xc2, 12435,
+	0xc3, 12435,
+	0xc4, 12435,
+	0xc5, 12435,
+	0xc6, 12435,
+	0xc7, 12435,
+	0xd0, 12439,
+	0xd1, 12439,
+	0xd2, 12439,
+	0xd3, 12439,
+	0xd4, 12439,
+	0xd5, 12439,
+	0xd6, 12439,
+	0xd7, 12439,
+	0xd8, 12443,
+	0xd9, 12443,
+	0xda, 12443,
+	0xdb, 12443,
+	0xdc, 12443,
+	0xdd, 12443,
+	0xde, 12443,
+	0xdf, 12443,
+	0xe0, 12447,
+	0xe1, 12447,
+	0xe2, 12447,
+	0xe3, 12447,
+	0xe4, 12447,
+	0xe5, 12447,
+	0xe6, 12447,
+	0xe7, 12447,
+	0xe8, 12451,
+	0xe9, 12451,
+	0xea, 12451,
+	0xeb, 12451,
+	0xec, 12451,
+	0xed, 12451,
+	0xee, 12451,
+	0xef, 12451,
+	/*12398*/ uint16(xCondSlashR),
+	12407, // 0
+	12411, // 1
+	12415, // 2
+	12419, // 3
+	12423, // 4
 	0,     // 5
-	12408, // 6
-	12412, // 7
-	/*12388*/ uint16(xSetOp), uint16(FLD),
-	/*12390*/ uint16(xArgM64fp),
-	/*12391*/ uint16(xMatch),
-	/*12392*/ uint16(xSetOp), uint16(FISTTP),
-	/*12394*/ uint16(xArgM64int),
-	/*12395*/ uint16(xMatch),
-	/*12396*/ uint16(xSetOp), uint16(FST),
-	/*12398*/ uint16(xArgM64fp),
-	/*12399*/ uint16(xMatch),
-	/*12400*/ uint16(xSetOp), uint16(FSTP),
-	/*12402*/ uint16(xArgM64fp),
-	/*12403*/ uint16(xMatch),
-	/*12404*/ uint16(xSetOp), uint16(FRSTOR),
-	/*12406*/ uint16(xArgM94108byte),
-	/*12407*/ uint16(xMatch),
-	/*12408*/ uint16(xSetOp), uint16(FNSAVE),
-	/*12410*/ uint16(xArgM94108byte),
-	/*12411*/ uint16(xMatch),
-	/*12412*/ uint16(xSetOp), uint16(FNSTSW),
-	/*12414*/ uint16(xArgM2byte),
-	/*12415*/ uint16(xMatch),
-	/*12416*/ uint16(xSetOp), uint16(FFREE),
-	/*12418*/ uint16(xArgSTi),
-	/*12419*/ uint16(xMatch),
-	/*12420*/ uint16(xSetOp), uint16(FST),
-	/*12422*/ uint16(xArgSTi),
-	/*12423*/ uint16(xMatch),
-	/*12424*/ uint16(xSetOp), uint16(FSTP),
-	/*12426*/ uint16(xArgSTi),
-	/*12427*/ uint16(xMatch),
-	/*12428*/ uint16(xSetOp), uint16(FUCOM),
-	/*12430*/ uint16(xArgSTi),
-	/*12431*/ uint16(xMatch),
-	/*12432*/ uint16(xSetOp), uint16(FUCOMP),
-	/*12434*/ uint16(xArgSTi),
-	/*12435*/ uint16(xMatch),
-	/*12436*/ uint16(xCondByte), 49,
-	0xc0, 12577,
-	0xc1, 12577,
-	0xc2, 12577,
-	0xc3, 12577,
-	0xc4, 12577,
-	0xc5, 12577,
-	0xc6, 12577,
-	0xc7, 12577,
-	0xc8, 12582,
-	0xc9, 12582,
-	0xca, 12582,
-	0xcb, 12582,
-	0xcc, 12582,
-	0xcd, 12582,
-	0xce, 12582,
-	0xcf, 12582,
-	0xD9, 12587,
-	0xe0, 12590,
-	0xe1, 12590,
-	0xe2, 12590,
-	0xe3, 12590,
-	0xe4, 12590,
-	0xe5, 12590,
-	0xe6, 12590,
-	0xe7, 12590,
-	0xe8, 12595,
-	0xe9, 12595,
-	0xea, 12595,
-	0xeb, 12595,
-	0xec, 12595,
-	0xed, 12595,
-	0xee, 12595,
-	0xef, 12595,
-	0xf0, 12600,
-	0xf1, 12600,
-	0xf2, 12600,
-	0xf3, 12600,
-	0xf4, 12600,
-	0xf5, 12600,
-	0xf6, 12600,
-	0xf7, 12600,
-	0xf8, 12605,
-	0xf9, 12605,
-	0xfa, 12605,
-	0xfb, 12605,
-	0xfc, 12605,
-	0xfd, 12605,
-	0xfe, 12605,
-	0xff, 12605,
-	/*12536*/ uint16(xCondSlashR),
-	12545, // 0
-	12549, // 1
-	12553, // 2
-	12557, // 3
-	12561, // 4
-	12565, // 5
-	12569, // 6
-	12573, // 7
-	/*12545*/ uint16(xSetOp), uint16(FIADD),
-	/*12547*/ uint16(xArgM16int),
-	/*12548*/ uint16(xMatch),
-	/*12549*/ uint16(xSetOp), uint16(FIMUL),
-	/*12551*/ uint16(xArgM16int),
-	/*12552*/ uint16(xMatch),
-	/*12553*/ uint16(xSetOp), uint16(FICOM),
-	/*12555*/ uint16(xArgM16int),
-	/*12556*/ uint16(xMatch),
-	/*12557*/ uint16(xSetOp), uint16(FICOMP),
-	/*12559*/ uint16(xArgM16int),
-	/*12560*/ uint16(xMatch),
-	/*12561*/ uint16(xSetOp), uint16(FISUB),
-	/*12563*/ uint16(xArgM16int),
-	/*12564*/ uint16(xMatch),
-	/*12565*/ uint16(xSetOp), uint16(FISUBR),
-	/*12567*/ uint16(xArgM16int),
-	/*12568*/ uint16(xMatch),
-	/*12569*/ uint16(xSetOp), uint16(FIDIV),
-	/*12571*/ uint16(xArgM16int),
-	/*12572*/ uint16(xMatch),
-	/*12573*/ uint16(xSetOp), uint16(FIDIVR),
-	/*12575*/ uint16(xArgM16int),
-	/*12576*/ uint16(xMatch),
-	/*12577*/ uint16(xSetOp), uint16(FADDP),
-	/*12579*/ uint16(xArgSTi),
-	/*12580*/ uint16(xArgST),
-	/*12581*/ uint16(xMatch),
-	/*12582*/ uint16(xSetOp), uint16(FMULP),
-	/*12584*/ uint16(xArgSTi),
-	/*12585*/ uint16(xArgST),
-	/*12586*/ uint16(xMatch),
-	/*12587*/ uint16(xSetOp), uint16(FCOMPP),
-	/*12589*/ uint16(xMatch),
-	/*12590*/ uint16(xSetOp), uint16(FSUBRP),
-	/*12592*/ uint16(xArgSTi),
-	/*12593*/ uint16(xArgST),
-	/*12594*/ uint16(xMatch),
-	/*12595*/ uint16(xSetOp), uint16(FSUBP),
-	/*12597*/ uint16(xArgSTi),
-	/*12598*/ uint16(xArgST),
-	/*12599*/ uint16(xMatch),
-	/*12600*/ uint16(xSetOp), uint16(FDIVRP),
-	/*12602*/ uint16(xArgSTi),
-	/*12603*/ uint16(xArgST),
-	/*12604*/ uint16(xMatch),
-	/*12605*/ uint16(xSetOp), uint16(FDIVP),
-	/*12607*/ uint16(xArgSTi),
-	/*12608*/ uint16(xArgST),
-	/*12609*/ uint16(xMatch),
-	/*12610*/ uint16(xCondByte), 25,
-	0xc0, 12703,
-	0xc1, 12703,
-	0xc2, 12703,
-	0xc3, 12703,
-	0xc4, 12703,
-	0xc5, 12703,
-	0xc6, 12703,
-	0xc7, 12703,
-	0xE0, 12707,
-	0xe8, 12711,
-	0xe9, 12711,
-	0xea, 12711,
-	0xeb, 12711,
-	0xec, 12711,
-	0xed, 12711,
-	0xee, 12711,
-	0xef, 12711,
-	0xf0, 12716,
-	0xf1, 12716,
-	0xf2, 12716,
-	0xf3, 12716,
-	0xf4, 12716,
-	0xf5, 12716,
-	0xf6, 12716,
-	0xf7, 12716,
-	/*12662*/ uint16(xCondSlashR),
-	12671, // 0
-	12675, // 1
-	12679, // 2
-	12683, // 3
-	12687, // 4
-	12691, // 5
-	12695, // 6
-	12699, // 7
-	/*12671*/ uint16(xSetOp), uint16(FILD),
-	/*12673*/ uint16(xArgM16int),
-	/*12674*/ uint16(xMatch),
-	/*12675*/ uint16(xSetOp), uint16(FISTTP),
-	/*12677*/ uint16(xArgM16int),
-	/*12678*/ uint16(xMatch),
-	/*12679*/ uint16(xSetOp), uint16(FIST),
-	/*12681*/ uint16(xArgM16int),
-	/*12682*/ uint16(xMatch),
-	/*12683*/ uint16(xSetOp), uint16(FISTP),
-	/*12685*/ uint16(xArgM16int),
-	/*12686*/ uint16(xMatch),
-	/*12687*/ uint16(xSetOp), uint16(FBLD),
-	/*12689*/ uint16(xArgM80dec),
-	/*12690*/ uint16(xMatch),
-	/*12691*/ uint16(xSetOp), uint16(FILD),
-	/*12693*/ uint16(xArgM64int),
-	/*12694*/ uint16(xMatch),
-	/*12695*/ uint16(xSetOp), uint16(FBSTP),
-	/*12697*/ uint16(xArgM80bcd),
-	/*12698*/ uint16(xMatch),
-	/*12699*/ uint16(xSetOp), uint16(FISTP),
-	/*12701*/ uint16(xArgM64int),
-	/*12702*/ uint16(xMatch),
-	/*12703*/ uint16(xSetOp), uint16(FFREEP),
-	/*12705*/ uint16(xArgSTi),
-	/*12706*/ uint16(xMatch),
-	/*12707*/ uint16(xSetOp), uint16(FNSTSW),
-	/*12709*/ uint16(xArgAX),
-	/*12710*/ uint16(xMatch),
-	/*12711*/ uint16(xSetOp), uint16(FUCOMIP),
-	/*12713*/ uint16(xArgST),
-	/*12714*/ uint16(xArgSTi),
-	/*12715*/ uint16(xMatch),
-	/*12716*/ uint16(xSetOp), uint16(FCOMIP),
-	/*12718*/ uint16(xArgST),
-	/*12719*/ uint16(xArgSTi),
-	/*12720*/ uint16(xMatch),
-	/*12721*/ uint16(xSetOp), uint16(LOOPNE),
-	/*12723*/ uint16(xReadCb),
-	/*12724*/ uint16(xArgRel8),
+	12427, // 6
+	12431, // 7
+	/*12407*/ uint16(xSetOp), uint16(FLD),
+	/*12409*/ uint16(xArgM64fp),
+	/*12410*/ uint16(xMatch),
+	/*12411*/ uint16(xSetOp), uint16(FISTTP),
+	/*12413*/ uint16(xArgM64int),
+	/*12414*/ uint16(xMatch),
+	/*12415*/ uint16(xSetOp), uint16(FST),
+	/*12417*/ uint16(xArgM64fp),
+	/*12418*/ uint16(xMatch),
+	/*12419*/ uint16(xSetOp), uint16(FSTP),
+	/*12421*/ uint16(xArgM64fp),
+	/*12422*/ uint16(xMatch),
+	/*12423*/ uint16(xSetOp), uint16(FRSTOR),
+	/*12425*/ uint16(xArgM94108byte),
+	/*12426*/ uint16(xMatch),
+	/*12427*/ uint16(xSetOp), uint16(FNSAVE),
+	/*12429*/ uint16(xArgM94108byte),
+	/*12430*/ uint16(xMatch),
+	/*12431*/ uint16(xSetOp), uint16(FNSTSW),
+	/*12433*/ uint16(xArgM2byte),
+	/*12434*/ uint16(xMatch),
+	/*12435*/ uint16(xSetOp), uint16(FFREE),
+	/*12437*/ uint16(xArgSTi),
+	/*12438*/ uint16(xMatch),
+	/*12439*/ uint16(xSetOp), uint16(FST),
+	/*12441*/ uint16(xArgSTi),
+	/*12442*/ uint16(xMatch),
+	/*12443*/ uint16(xSetOp), uint16(FSTP),
+	/*12445*/ uint16(xArgSTi),
+	/*12446*/ uint16(xMatch),
+	/*12447*/ uint16(xSetOp), uint16(FUCOM),
+	/*12449*/ uint16(xArgSTi),
+	/*12450*/ uint16(xMatch),
+	/*12451*/ uint16(xSetOp), uint16(FUCOMP),
+	/*12453*/ uint16(xArgSTi),
+	/*12454*/ uint16(xMatch),
+	/*12455*/ uint16(xCondByte), 49,
+	0xc0, 12596,
+	0xc1, 12596,
+	0xc2, 12596,
+	0xc3, 12596,
+	0xc4, 12596,
+	0xc5, 12596,
+	0xc6, 12596,
+	0xc7, 12596,
+	0xc8, 12601,
+	0xc9, 12601,
+	0xca, 12601,
+	0xcb, 12601,
+	0xcc, 12601,
+	0xcd, 12601,
+	0xce, 12601,
+	0xcf, 12601,
+	0xD9, 12606,
+	0xe0, 12609,
+	0xe1, 12609,
+	0xe2, 12609,
+	0xe3, 12609,
+	0xe4, 12609,
+	0xe5, 12609,
+	0xe6, 12609,
+	0xe7, 12609,
+	0xe8, 12614,
+	0xe9, 12614,
+	0xea, 12614,
+	0xeb, 12614,
+	0xec, 12614,
+	0xed, 12614,
+	0xee, 12614,
+	0xef, 12614,
+	0xf0, 12619,
+	0xf1, 12619,
+	0xf2, 12619,
+	0xf3, 12619,
+	0xf4, 12619,
+	0xf5, 12619,
+	0xf6, 12619,
+	0xf7, 12619,
+	0xf8, 12624,
+	0xf9, 12624,
+	0xfa, 12624,
+	0xfb, 12624,
+	0xfc, 12624,
+	0xfd, 12624,
+	0xfe, 12624,
+	0xff, 12624,
+	/*12555*/ uint16(xCondSlashR),
+	12564, // 0
+	12568, // 1
+	12572, // 2
+	12576, // 3
+	12580, // 4
+	12584, // 5
+	12588, // 6
+	12592, // 7
+	/*12564*/ uint16(xSetOp), uint16(FIADD),
+	/*12566*/ uint16(xArgM16int),
+	/*12567*/ uint16(xMatch),
+	/*12568*/ uint16(xSetOp), uint16(FIMUL),
+	/*12570*/ uint16(xArgM16int),
+	/*12571*/ uint16(xMatch),
+	/*12572*/ uint16(xSetOp), uint16(FICOM),
+	/*12574*/ uint16(xArgM16int),
+	/*12575*/ uint16(xMatch),
+	/*12576*/ uint16(xSetOp), uint16(FICOMP),
+	/*12578*/ uint16(xArgM16int),
+	/*12579*/ uint16(xMatch),
+	/*12580*/ uint16(xSetOp), uint16(FISUB),
+	/*12582*/ uint16(xArgM16int),
+	/*12583*/ uint16(xMatch),
+	/*12584*/ uint16(xSetOp), uint16(FISUBR),
+	/*12586*/ uint16(xArgM16int),
+	/*12587*/ uint16(xMatch),
+	/*12588*/ uint16(xSetOp), uint16(FIDIV),
+	/*12590*/ uint16(xArgM16int),
+	/*12591*/ uint16(xMatch),
+	/*12592*/ uint16(xSetOp), uint16(FIDIVR),
+	/*12594*/ uint16(xArgM16int),
+	/*12595*/ uint16(xMatch),
+	/*12596*/ uint16(xSetOp), uint16(FADDP),
+	/*12598*/ uint16(xArgSTi),
+	/*12599*/ uint16(xArgST),
+	/*12600*/ uint16(xMatch),
+	/*12601*/ uint16(xSetOp), uint16(FMULP),
+	/*12603*/ uint16(xArgSTi),
+	/*12604*/ uint16(xArgST),
+	/*12605*/ uint16(xMatch),
+	/*12606*/ uint16(xSetOp), uint16(FCOMPP),
+	/*12608*/ uint16(xMatch),
+	/*12609*/ uint16(xSetOp), uint16(FSUBRP),
+	/*12611*/ uint16(xArgSTi),
+	/*12612*/ uint16(xArgST),
+	/*12613*/ uint16(xMatch),
+	/*12614*/ uint16(xSetOp), uint16(FSUBP),
+	/*12616*/ uint16(xArgSTi),
+	/*12617*/ uint16(xArgST),
+	/*12618*/ uint16(xMatch),
+	/*12619*/ uint16(xSetOp), uint16(FDIVRP),
+	/*12621*/ uint16(xArgSTi),
+	/*12622*/ uint16(xArgST),
+	/*12623*/ uint16(xMatch),
+	/*12624*/ uint16(xSetOp), uint16(FDIVP),
+	/*12626*/ uint16(xArgSTi),
+	/*12627*/ uint16(xArgST),
+	/*12628*/ uint16(xMatch),
+	/*12629*/ uint16(xCondByte), 25,
+	0xc0, 12722,
+	0xc1, 12722,
+	0xc2, 12722,
+	0xc3, 12722,
+	0xc4, 12722,
+	0xc5, 12722,
+	0xc6, 12722,
+	0xc7, 12722,
+	0xE0, 12726,
+	0xe8, 12730,
+	0xe9, 12730,
+	0xea, 12730,
+	0xeb, 12730,
+	0xec, 12730,
+	0xed, 12730,
+	0xee, 12730,
+	0xef, 12730,
+	0xf0, 12735,
+	0xf1, 12735,
+	0xf2, 12735,
+	0xf3, 12735,
+	0xf4, 12735,
+	0xf5, 12735,
+	0xf6, 12735,
+	0xf7, 12735,
+	/*12681*/ uint16(xCondSlashR),
+	12690, // 0
+	12694, // 1
+	12698, // 2
+	12702, // 3
+	12706, // 4
+	12710, // 5
+	12714, // 6
+	12718, // 7
+	/*12690*/ uint16(xSetOp), uint16(FILD),
+	/*12692*/ uint16(xArgM16int),
+	/*12693*/ uint16(xMatch),
+	/*12694*/ uint16(xSetOp), uint16(FISTTP),
+	/*12696*/ uint16(xArgM16int),
+	/*12697*/ uint16(xMatch),
+	/*12698*/ uint16(xSetOp), uint16(FIST),
+	/*12700*/ uint16(xArgM16int),
+	/*12701*/ uint16(xMatch),
+	/*12702*/ uint16(xSetOp), uint16(FISTP),
+	/*12704*/ uint16(xArgM16int),
+	/*12705*/ uint16(xMatch),
+	/*12706*/ uint16(xSetOp), uint16(FBLD),
+	/*12708*/ uint16(xArgM80dec),
+	/*12709*/ uint16(xMatch),
+	/*12710*/ uint16(xSetOp), uint16(FILD),
+	/*12712*/ uint16(xArgM64int),
+	/*12713*/ uint16(xMatch),
+	/*12714*/ uint16(xSetOp), uint16(FBSTP),
+	/*12716*/ uint16(xArgM80bcd),
+	/*12717*/ uint16(xMatch),
+	/*12718*/ uint16(xSetOp), uint16(FISTP),
+	/*12720*/ uint16(xArgM64int),
+	/*12721*/ uint16(xMatch),
+	/*12722*/ uint16(xSetOp), uint16(FFREEP),
+	/*12724*/ uint16(xArgSTi),
 	/*12725*/ uint16(xMatch),
-	/*12726*/ uint16(xSetOp), uint16(LOOPE),
-	/*12728*/ uint16(xReadCb),
-	/*12729*/ uint16(xArgRel8),
-	/*12730*/ uint16(xMatch),
-	/*12731*/ uint16(xSetOp), uint16(LOOP),
-	/*12733*/ uint16(xReadCb),
-	/*12734*/ uint16(xArgRel8),
-	/*12735*/ uint16(xMatch),
-	/*12736*/ uint16(xCondIs64), 12739, 12753,
-	/*12739*/ uint16(xCondAddrSize), 12743, 12748, 0,
-	/*12743*/ uint16(xSetOp), uint16(JCXZ),
-	/*12745*/ uint16(xReadCb),
-	/*12746*/ uint16(xArgRel8),
-	/*12747*/ uint16(xMatch),
-	/*12748*/ uint16(xSetOp), uint16(JECXZ),
-	/*12750*/ uint16(xReadCb),
-	/*12751*/ uint16(xArgRel8),
-	/*12752*/ uint16(xMatch),
-	/*12753*/ uint16(xCondAddrSize), 0, 12748, 12757,
-	/*12757*/ uint16(xSetOp), uint16(JRCXZ),
-	/*12759*/ uint16(xReadCb),
-	/*12760*/ uint16(xArgRel8),
-	/*12761*/ uint16(xMatch),
-	/*12762*/ uint16(xSetOp), uint16(IN),
-	/*12764*/ uint16(xReadIb),
-	/*12765*/ uint16(xArgAL),
-	/*12766*/ uint16(xArgImm8u),
-	/*12767*/ uint16(xMatch),
-	/*12768*/ uint16(xCondDataSize), 12772, 12778, 12784,
-	/*12772*/ uint16(xSetOp), uint16(IN),
-	/*12774*/ uint16(xReadIb),
-	/*12775*/ uint16(xArgAX),
-	/*12776*/ uint16(xArgImm8u),
-	/*12777*/ uint16(xMatch),
-	/*12778*/ uint16(xSetOp), uint16(IN),
-	/*12780*/ uint16(xReadIb),
-	/*12781*/ uint16(xArgEAX),
-	/*12782*/ uint16(xArgImm8u),
-	/*12783*/ uint16(xMatch),
-	/*12784*/ uint16(xSetOp), uint16(IN),
-	/*12786*/ uint16(xReadIb),
-	/*12787*/ uint16(xArgEAX),
-	/*12788*/ uint16(xArgImm8u),
-	/*12789*/ uint16(xMatch),
-	/*12790*/ uint16(xSetOp), uint16(OUT),
-	/*12792*/ uint16(xReadIb),
-	/*12793*/ uint16(xArgImm8u),
-	/*12794*/ uint16(xArgAL),
-	/*12795*/ uint16(xMatch),
-	/*12796*/ uint16(xCondPrefix), 3,
-	0xC5, 12840,
-	0xC4, 12826,
-	0x0, 12804,
-	/*12804*/ uint16(xCondDataSize), 12808, 12814, 12820,
-	/*12808*/ uint16(xSetOp), uint16(OUT),
-	/*12810*/ uint16(xReadIb),
-	/*12811*/ uint16(xArgImm8u),
-	/*12812*/ uint16(xArgAX),
-	/*12813*/ uint16(xMatch),
-	/*12814*/ uint16(xSetOp), uint16(OUT),
-	/*12816*/ uint16(xReadIb),
-	/*12817*/ uint16(xArgImm8u),
-	/*12818*/ uint16(xArgEAX),
-	/*12819*/ uint16(xMatch),
-	/*12820*/ uint16(xSetOp), uint16(OUT),
-	/*12822*/ uint16(xReadIb),
-	/*12823*/ uint16(xArgImm8u),
-	/*12824*/ uint16(xArgEAX),
-	/*12825*/ uint16(xMatch),
-	/*12826*/ uint16(xCondPrefix), 1,
-	0x66, 12830,
-	/*12830*/ uint16(xCondPrefix), 1,
-	0x0F, 12834,
-	/*12834*/ uint16(xSetOp), uint16(VMOVNTDQ),
-	/*12836*/ uint16(xReadSlashR),
-	/*12837*/ uint16(xArgM256),
-	/*12838*/ uint16(xArgYmm1),
-	/*12839*/ uint16(xMatch),
-	/*12840*/ uint16(xCondPrefix), 1,
-	0x66, 12844,
-	/*12844*/ uint16(xCondPrefix), 1,
-	0x0F, 12848,
-	/*12848*/ uint16(xSetOp), uint16(VMOVNTDQ),
-	/*12850*/ uint16(xReadSlashR),
-	/*12851*/ uint16(xArgM256),
-	/*12852*/ uint16(xArgYmm1),
-	/*12853*/ uint16(xMatch),
-	/*12854*/ uint16(xCondIs64), 12857, 12871,
-	/*12857*/ uint16(xCondDataSize), 12861, 12866, 0,
-	/*12861*/ uint16(xSetOp), uint16(CALL),
-	/*12863*/ uint16(xReadCw),
-	/*12864*/ uint16(xArgRel16),
-	/*12865*/ uint16(xMatch),
-	/*12866*/ uint16(xSetOp), uint16(CALL),
-	/*12868*/ uint16(xReadCd),
-	/*12869*/ uint16(xArgRel32),
-	/*12870*/ uint16(xMatch),
-	/*12871*/ uint16(xCondDataSize), 12875, 12866, 12880,
-	/*12875*/ uint16(xSetOp), uint16(CALL),
-	/*12877*/ uint16(xReadCd),
-	/*12878*/ uint16(xArgRel32),
-	/*12879*/ uint16(xMatch),
+	/*12726*/ uint16(xSetOp), uint16(FNSTSW),
+	/*12728*/ uint16(xArgAX),
+	/*12729*/ uint16(xMatch),
+	/*12730*/ uint16(xSetOp), uint16(FUCOMIP),
+	/*12732*/ uint16(xArgST),
+	/*12733*/ uint16(xArgSTi),
+	/*12734*/ uint16(xMatch),
+	/*12735*/ uint16(xSetOp), uint16(FCOMIP),
+	/*12737*/ uint16(xArgST),
+	/*12738*/ uint16(xArgSTi),
+	/*12739*/ uint16(xMatch),
+	/*12740*/ uint16(xSetOp), uint16(LOOPNE),
+	/*12742*/ uint16(xReadCb),
+	/*12743*/ uint16(xArgRel8),
+	/*12744*/ uint16(xMatch),
+	/*12745*/ uint16(xSetOp), uint16(LOOPE),
+	/*12747*/ uint16(xReadCb),
+	/*12748*/ uint16(xArgRel8),
+	/*12749*/ uint16(xMatch),
+	/*12750*/ uint16(xSetOp), uint16(LOOP),
+	/*12752*/ uint16(xReadCb),
+	/*12753*/ uint16(xArgRel8),
+	/*12754*/ uint16(xMatch),
+	/*12755*/ uint16(xCondIs64), 12758, 12772,
+	/*12758*/ uint16(xCondAddrSize), 12762, 12767, 0,
+	/*12762*/ uint16(xSetOp), uint16(JCXZ),
+	/*12764*/ uint16(xReadCb),
+	/*12765*/ uint16(xArgRel8),
+	/*12766*/ uint16(xMatch),
+	/*12767*/ uint16(xSetOp), uint16(JECXZ),
+	/*12769*/ uint16(xReadCb),
+	/*12770*/ uint16(xArgRel8),
+	/*12771*/ uint16(xMatch),
+	/*12772*/ uint16(xCondAddrSize), 0, 12767, 12776,
+	/*12776*/ uint16(xSetOp), uint16(JRCXZ),
+	/*12778*/ uint16(xReadCb),
+	/*12779*/ uint16(xArgRel8),
+	/*12780*/ uint16(xMatch),
+	/*12781*/ uint16(xSetOp), uint16(IN),
+	/*12783*/ uint16(xReadIb),
+	/*12784*/ uint16(xArgAL),
+	/*12785*/ uint16(xArgImm8u),
+	/*12786*/ uint16(xMatch),
+	/*12787*/ uint16(xCondDataSize), 12791, 12797, 12803,
+	/*12791*/ uint16(xSetOp), uint16(IN),
+	/*12793*/ uint16(xReadIb),
+	/*12794*/ uint16(xArgAX),
+	/*12795*/ uint16(xArgImm8u),
+	/*12796*/ uint16(xMatch),
+	/*12797*/ uint16(xSetOp), uint16(IN),
+	/*12799*/ uint16(xReadIb),
+	/*12800*/ uint16(xArgEAX),
+	/*12801*/ uint16(xArgImm8u),
+	/*12802*/ uint16(xMatch),
+	/*12803*/ uint16(xSetOp), uint16(IN),
+	/*12805*/ uint16(xReadIb),
+	/*12806*/ uint16(xArgEAX),
+	/*12807*/ uint16(xArgImm8u),
+	/*12808*/ uint16(xMatch),
+	/*12809*/ uint16(xSetOp), uint16(OUT),
+	/*12811*/ uint16(xReadIb),
+	/*12812*/ uint16(xArgImm8u),
+	/*12813*/ uint16(xArgAL),
+	/*12814*/ uint16(xMatch),
+	/*12815*/ uint16(xCondPrefix), 3,
+	0xC5, 12859,
+	0xC4, 12845,
+	0x0, 12823,
+	/*12823*/ uint16(xCondDataSize), 12827, 12833, 12839,
+	/*12827*/ uint16(xSetOp), uint16(OUT),
+	/*12829*/ uint16(xReadIb),
+	/*12830*/ uint16(xArgImm8u),
+	/*12831*/ uint16(xArgAX),
+	/*12832*/ uint16(xMatch),
+	/*12833*/ uint16(xSetOp), uint16(OUT),
+	/*12835*/ uint16(xReadIb),
+	/*12836*/ uint16(xArgImm8u),
+	/*12837*/ uint16(xArgEAX),
+	/*12838*/ uint16(xMatch),
+	/*12839*/ uint16(xSetOp), uint16(OUT),
+	/*12841*/ uint16(xReadIb),
+	/*12842*/ uint16(xArgImm8u),
+	/*12843*/ uint16(xArgEAX),
+	/*12844*/ uint16(xMatch),
+	/*12845*/ uint16(xCondPrefix), 1,
+	0x66, 12849,
+	/*12849*/ uint16(xCondPrefix), 1,
+	0x0F, 12853,
+	/*12853*/ uint16(xSetOp), uint16(VMOVNTDQ),
+	/*12855*/ uint16(xReadSlashR),
+	/*12856*/ uint16(xArgM256),
+	/*12857*/ uint16(xArgYmm1),
+	/*12858*/ uint16(xMatch),
+	/*12859*/ uint16(xCondPrefix), 1,
+	0x66, 12863,
+	/*12863*/ uint16(xCondPrefix), 1,
+	0x0F, 12867,
+	/*12867*/ uint16(xSetOp), uint16(VMOVNTDQ),
+	/*12869*/ uint16(xReadSlashR),
+	/*12870*/ uint16(xArgM256),
+	/*12871*/ uint16(xArgYmm1),
+	/*12872*/ uint16(xMatch),
+	/*12873*/ uint16(xCondIs64), 12876, 12890,
+	/*12876*/ uint16(xCondDataSize), 12880, 12885, 0,
 	/*12880*/ uint16(xSetOp), uint16(CALL),
-	/*12882*/ uint16(xReadCd),
-	/*12883*/ uint16(xArgRel32),
+	/*12882*/ uint16(xReadCw),
+	/*12883*/ uint16(xArgRel16),
 	/*12884*/ uint16(xMatch),
-	/*12885*/ uint16(xCondIs64), 12888, 12902,
-	/*12888*/ uint16(xCondDataSize), 12892, 12897, 0,
-	/*12892*/ uint16(xSetOp), uint16(JMP),
-	/*12894*/ uint16(xReadCw),
-	/*12895*/ uint16(xArgRel16),
-	/*12896*/ uint16(xMatch),
-	/*12897*/ uint16(xSetOp), uint16(JMP),
-	/*12899*/ uint16(xReadCd),
-	/*12900*/ uint16(xArgRel32),
-	/*12901*/ uint16(xMatch),
-	/*12902*/ uint16(xCondDataSize), 12906, 12897, 12911,
-	/*12906*/ uint16(xSetOp), uint16(JMP),
-	/*12908*/ uint16(xReadCd),
-	/*12909*/ uint16(xArgRel32),
-	/*12910*/ uint16(xMatch),
+	/*12885*/ uint16(xSetOp), uint16(CALL),
+	/*12887*/ uint16(xReadCd),
+	/*12888*/ uint16(xArgRel32),
+	/*12889*/ uint16(xMatch),
+	/*12890*/ uint16(xCondDataSize), 12894, 12885, 12899,
+	/*12894*/ uint16(xSetOp), uint16(CALL),
+	/*12896*/ uint16(xReadCd),
+	/*12897*/ uint16(xArgRel32),
+	/*12898*/ uint16(xMatch),
+	/*12899*/ uint16(xSetOp), uint16(CALL),
+	/*12901*/ uint16(xReadCd),
+	/*12902*/ uint16(xArgRel32),
+	/*12903*/ uint16(xMatch),
+	/*12904*/ uint16(xCondIs64), 12907, 12921,
+	/*12907*/ uint16(xCondDataSize), 12911, 12916, 0,
 	/*12911*/ uint16(xSetOp), uint16(JMP),
-	/*12913*/ uint16(xReadCd),
-	/*12914*/ uint16(xArgRel32),
+	/*12913*/ uint16(xReadCw),
+	/*12914*/ uint16(xArgRel16),
 	/*12915*/ uint16(xMatch),
-	/*12916*/ uint16(xCondIs64), 12919, 0,
-	/*12919*/ uint16(xCondDataSize), 12923, 12928, 0,
-	/*12923*/ uint16(xSetOp), uint16(LJMP),
-	/*12925*/ uint16(xReadCd),
-	/*12926*/ uint16(xArgPtr16colon16),
-	/*12927*/ uint16(xMatch),
-	/*12928*/ uint16(xSetOp), uint16(LJMP),
-	/*12930*/ uint16(xReadCp),
-	/*12931*/ uint16(xArgPtr16colon32),
-	/*12932*/ uint16(xMatch),
-	/*12933*/ uint16(xSetOp), uint16(JMP),
-	/*12935*/ uint16(xReadCb),
-	/*12936*/ uint16(xArgRel8),
-	/*12937*/ uint16(xMatch),
-	/*12938*/ uint16(xSetOp), uint16(IN),
-	/*12940*/ uint16(xArgAL),
-	/*12941*/ uint16(xArgDX),
-	/*12942*/ uint16(xMatch),
-	/*12943*/ uint16(xCondDataSize), 12947, 12952, 12957,
-	/*12947*/ uint16(xSetOp), uint16(IN),
-	/*12949*/ uint16(xArgAX),
-	/*12950*/ uint16(xArgDX),
+	/*12916*/ uint16(xSetOp), uint16(JMP),
+	/*12918*/ uint16(xReadCd),
+	/*12919*/ uint16(xArgRel32),
+	/*12920*/ uint16(xMatch),
+	/*12921*/ uint16(xCondDataSize), 12925, 12916, 12930,
+	/*12925*/ uint16(xSetOp), uint16(JMP),
+	/*12927*/ uint16(xReadCd),
+	/*12928*/ uint16(xArgRel32),
+	/*12929*/ uint16(xMatch),
+	/*12930*/ uint16(xSetOp), uint16(JMP),
+	/*12932*/ uint16(xReadCd),
+	/*12933*/ uint16(xArgRel32),
+	/*12934*/ uint16(xMatch),
+	/*12935*/ uint16(xCondIs64), 12938, 0,
+	/*12938*/ uint16(xCondDataSize), 12942, 12947, 0,
+	/*12942*/ uint16(xSetOp), uint16(LJMP),
+	/*12944*/ uint16(xReadCd),
+	/*12945*/ uint16(xArgPtr16colon16),
+	/*12946*/ uint16(xMatch),
+	/*12947*/ uint16(xSetOp), uint16(LJMP),
+	/*12949*/ uint16(xReadCp),
+	/*12950*/ uint16(xArgPtr16colon32),
 	/*12951*/ uint16(xMatch),
-	/*12952*/ uint16(xSetOp), uint16(IN),
-	/*12954*/ uint16(xArgEAX),
-	/*12955*/ uint16(xArgDX),
+	/*12952*/ uint16(xSetOp), uint16(JMP),
+	/*12954*/ uint16(xReadCb),
+	/*12955*/ uint16(xArgRel8),
 	/*12956*/ uint16(xMatch),
 	/*12957*/ uint16(xSetOp), uint16(IN),
-	/*12959*/ uint16(xArgEAX),
+	/*12959*/ uint16(xArgAL),
 	/*12960*/ uint16(xArgDX),
 	/*12961*/ uint16(xMatch),
-	/*12962*/ uint16(xSetOp), uint16(OUT),
-	/*12964*/ uint16(xArgDX),
-	/*12965*/ uint16(xArgAL),
-	/*12966*/ uint16(xMatch),
-	/*12967*/ uint16(xCondDataSize), 12971, 12976, 12981,
-	/*12971*/ uint16(xSetOp), uint16(OUT),
-	/*12973*/ uint16(xArgDX),
-	/*12974*/ uint16(xArgAX),
+	/*12962*/ uint16(xCondDataSize), 12966, 12971, 12976,
+	/*12966*/ uint16(xSetOp), uint16(IN),
+	/*12968*/ uint16(xArgAX),
+	/*12969*/ uint16(xArgDX),
+	/*12970*/ uint16(xMatch),
+	/*12971*/ uint16(xSetOp), uint16(IN),
+	/*12973*/ uint16(xArgEAX),
+	/*12974*/ uint16(xArgDX),
 	/*12975*/ uint16(xMatch),
-	/*12976*/ uint16(xSetOp), uint16(OUT),
-	/*12978*/ uint16(xArgDX),
-	/*12979*/ uint16(xArgEAX),
+	/*12976*/ uint16(xSetOp), uint16(IN),
+	/*12978*/ uint16(xArgEAX),
+	/*12979*/ uint16(xArgDX),
 	/*12980*/ uint16(xMatch),
 	/*12981*/ uint16(xSetOp), uint16(OUT),
 	/*12983*/ uint16(xArgDX),
-	/*12984*/ uint16(xArgEAX),
+	/*12984*/ uint16(xArgAL),
 	/*12985*/ uint16(xMatch),
-	/*12986*/ uint16(xSetOp), uint16(ICEBP),
-	/*12988*/ uint16(xMatch),
-	/*12989*/ uint16(xSetOp), uint16(HLT),
-	/*12991*/ uint16(xMatch),
-	/*12992*/ uint16(xSetOp), uint16(CMC),
+	/*12986*/ uint16(xCondDataSize), 12990, 12995, 13000,
+	/*12990*/ uint16(xSetOp), uint16(OUT),
+	/*12992*/ uint16(xArgDX),
+	/*12993*/ uint16(xArgAX),
 	/*12994*/ uint16(xMatch),
-	/*12995*/ uint16(xCondSlashR),
-	13004, // 0
-	0,     // 1
-	13010, // 2
-	13014, // 3
-	13018, // 4
-	13022, // 5
-	13026, // 6
-	13030, // 7
-	/*13004*/ uint16(xSetOp), uint16(TEST),
-	/*13006*/ uint16(xReadIb),
-	/*13007*/ uint16(xArgRM8),
-	/*13008*/ uint16(xArgImm8u),
-	/*13009*/ uint16(xMatch),
-	/*13010*/ uint16(xSetOp), uint16(NOT),
-	/*13012*/ uint16(xArgRM8),
+	/*12995*/ uint16(xSetOp), uint16(OUT),
+	/*12997*/ uint16(xArgDX),
+	/*12998*/ uint16(xArgEAX),
+	/*12999*/ uint16(xMatch),
+	/*13000*/ uint16(xSetOp), uint16(OUT),
+	/*13002*/ uint16(xArgDX),
+	/*13003*/ uint16(xArgEAX),
+	/*13004*/ uint16(xMatch),
+	/*13005*/ uint16(xSetOp), uint16(ICEBP),
+	/*13007*/ uint16(xMatch),
+	/*13008*/ uint16(xSetOp), uint16(HLT),
+	/*13010*/ uint16(xMatch),
+	/*13011*/ uint16(xSetOp), uint16(CMC),
 	/*13013*/ uint16(xMatch),
-	/*13014*/ uint16(xSetOp), uint16(NEG),
-	/*13016*/ uint16(xArgRM8),
-	/*13017*/ uint16(xMatch),
-	/*13018*/ uint16(xSetOp), uint16(MUL),
-	/*13020*/ uint16(xArgRM8),
-	/*13021*/ uint16(xMatch),
-	/*13022*/ uint16(xSetOp), uint16(IMUL),
-	/*13024*/ uint16(xArgRM8),
-	/*13025*/ uint16(xMatch),
-	/*13026*/ uint16(xSetOp), uint16(DIV),
-	/*13028*/ uint16(xArgRM8),
-	/*13029*/ uint16(xMatch),
-	/*13030*/ uint16(xSetOp), uint16(IDIV),
-	/*13032*/ uint16(xArgRM8),
-	/*13033*/ uint16(xMatch),
-	/*13034*/ uint16(xCondSlashR),
-	13043, // 0
+	/*13014*/ uint16(xCondSlashR),
+	13023, // 0
 	0,     // 1
-	13072, // 2
-	13095, // 3
-	13118, // 4
-	13141, // 5
-	13164, // 6
-	13187, // 7
-	/*13043*/ uint16(xCondIs64), 13046, 13062,
-	/*13046*/ uint16(xCondDataSize), 13050, 13056, 0,
-	/*13050*/ uint16(xSetOp), uint16(TEST),
-	/*13052*/ uint16(xReadIw),
-	/*13053*/ uint16(xArgRM16),
-	/*13054*/ uint16(xArgImm16),
-	/*13055*/ uint16(xMatch),
-	/*13056*/ uint16(xSetOp), uint16(TEST),
-	/*13058*/ uint16(xReadId),
-	/*13059*/ uint16(xArgRM32),
-	/*13060*/ uint16(xArgImm32),
-	/*13061*/ uint16(xMatch),
-	/*13062*/ uint16(xCondDataSize), 13050, 13056, 13066,
-	/*13066*/ uint16(xSetOp), uint16(TEST),
-	/*13068*/ uint16(xReadId),
-	/*13069*/ uint16(xArgRM64),
-	/*13070*/ uint16(xArgImm32),
-	/*13071*/ uint16(xMatch),
-	/*13072*/ uint16(xCondIs64), 13075, 13087,
-	/*13075*/ uint16(xCondDataSize), 13079, 13083, 0,
-	/*13079*/ uint16(xSetOp), uint16(NOT),
-	/*13081*/ uint16(xArgRM16),
-	/*13082*/ uint16(xMatch),
-	/*13083*/ uint16(xSetOp), uint16(NOT),
-	/*13085*/ uint16(xArgRM32),
-	/*13086*/ uint16(xMatch),
-	/*13087*/ uint16(xCondDataSize), 13079, 13083, 13091,
-	/*13091*/ uint16(xSetOp), uint16(NOT),
-	/*13093*/ uint16(xArgRM64),
-	/*13094*/ uint16(xMatch),
-	/*13095*/ uint16(xCondIs64), 13098, 13110,
-	/*13098*/ uint16(xCondDataSize), 13102, 13106, 0,
-	/*13102*/ uint16(xSetOp), uint16(NEG),
-	/*13104*/ uint16(xArgRM16),
+	13029, // 2
+	13033, // 3
+	13037, // 4
+	13041, // 5
+	13045, // 6
+	13049, // 7
+	/*13023*/ uint16(xSetOp), uint16(TEST),
+	/*13025*/ uint16(xReadIb),
+	/*13026*/ uint16(xArgRM8),
+	/*13027*/ uint16(xArgImm8u),
+	/*13028*/ uint16(xMatch),
+	/*13029*/ uint16(xSetOp), uint16(NOT),
+	/*13031*/ uint16(xArgRM8),
+	/*13032*/ uint16(xMatch),
+	/*13033*/ uint16(xSetOp), uint16(NEG),
+	/*13035*/ uint16(xArgRM8),
+	/*13036*/ uint16(xMatch),
+	/*13037*/ uint16(xSetOp), uint16(MUL),
+	/*13039*/ uint16(xArgRM8),
+	/*13040*/ uint16(xMatch),
+	/*13041*/ uint16(xSetOp), uint16(IMUL),
+	/*13043*/ uint16(xArgRM8),
+	/*13044*/ uint16(xMatch),
+	/*13045*/ uint16(xSetOp), uint16(DIV),
+	/*13047*/ uint16(xArgRM8),
+	/*13048*/ uint16(xMatch),
+	/*13049*/ uint16(xSetOp), uint16(IDIV),
+	/*13051*/ uint16(xArgRM8),
+	/*13052*/ uint16(xMatch),
+	/*13053*/ uint16(xCondSlashR),
+	13062, // 0
+	0,     // 1
+	13091, // 2
+	13114, // 3
+	13137, // 4
+	13160, // 5
+	13183, // 6
+	13206, // 7
+	/*13062*/ uint16(xCondIs64), 13065, 13081,
+	/*13065*/ uint16(xCondDataSize), 13069, 13075, 0,
+	/*13069*/ uint16(xSetOp), uint16(TEST),
+	/*13071*/ uint16(xReadIw),
+	/*13072*/ uint16(xArgRM16),
+	/*13073*/ uint16(xArgImm16),
+	/*13074*/ uint16(xMatch),
+	/*13075*/ uint16(xSetOp), uint16(TEST),
+	/*13077*/ uint16(xReadId),
+	/*13078*/ uint16(xArgRM32),
+	/*13079*/ uint16(xArgImm32),
+	/*13080*/ uint16(xMatch),
+	/*13081*/ uint16(xCondDataSize), 13069, 13075, 13085,
+	/*13085*/ uint16(xSetOp), uint16(TEST),
+	/*13087*/ uint16(xReadId),
+	/*13088*/ uint16(xArgRM64),
+	/*13089*/ uint16(xArgImm32),
+	/*13090*/ uint16(xMatch),
+	/*13091*/ uint16(xCondIs64), 13094, 13106,
+	/*13094*/ uint16(xCondDataSize), 13098, 13102, 0,
+	/*13098*/ uint16(xSetOp), uint16(NOT),
+	/*13100*/ uint16(xArgRM16),
+	/*13101*/ uint16(xMatch),
+	/*13102*/ uint16(xSetOp), uint16(NOT),
+	/*13104*/ uint16(xArgRM32),
 	/*13105*/ uint16(xMatch),
-	/*13106*/ uint16(xSetOp), uint16(NEG),
-	/*13108*/ uint16(xArgRM32),
-	/*13109*/ uint16(xMatch),
-	/*13110*/ uint16(xCondDataSize), 13102, 13106, 13114,
-	/*13114*/ uint16(xSetOp), uint16(NEG),
-	/*13116*/ uint16(xArgRM64),
-	/*13117*/ uint16(xMatch),
-	/*13118*/ uint16(xCondIs64), 13121, 13133,
-	/*13121*/ uint16(xCondDataSize), 13125, 13129, 0,
-	/*13125*/ uint16(xSetOp), uint16(MUL),
-	/*13127*/ uint16(xArgRM16),
+	/*13106*/ uint16(xCondDataSize), 13098, 13102, 13110,
+	/*13110*/ uint16(xSetOp), uint16(NOT),
+	/*13112*/ uint16(xArgRM64),
+	/*13113*/ uint16(xMatch),
+	/*13114*/ uint16(xCondIs64), 13117, 13129,
+	/*13117*/ uint16(xCondDataSize), 13121, 13125, 0,
+	/*13121*/ uint16(xSetOp), uint16(NEG),
+	/*13123*/ uint16(xArgRM16),
+	/*13124*/ uint16(xMatch),
+	/*13125*/ uint16(xSetOp), uint16(NEG),
+	/*13127*/ uint16(xArgRM32),
 	/*13128*/ uint16(xMatch),
-	/*13129*/ uint16(xSetOp), uint16(MUL),
-	/*13131*/ uint16(xArgRM32),
-	/*13132*/ uint16(xMatch),
-	/*13133*/ uint16(xCondDataSize), 13125, 13129, 13137,
-	/*13137*/ uint16(xSetOp), uint16(MUL),
-	/*13139*/ uint16(xArgRM64),
-	/*13140*/ uint16(xMatch),
-	/*13141*/ uint16(xCondIs64), 13144, 13156,
-	/*13144*/ uint16(xCondDataSize), 13148, 13152, 0,
-	/*13148*/ uint16(xSetOp), uint16(IMUL),
-	/*13150*/ uint16(xArgRM16),
+	/*13129*/ uint16(xCondDataSize), 13121, 13125, 13133,
+	/*13133*/ uint16(xSetOp), uint16(NEG),
+	/*13135*/ uint16(xArgRM64),
+	/*13136*/ uint16(xMatch),
+	/*13137*/ uint16(xCondIs64), 13140, 13152,
+	/*13140*/ uint16(xCondDataSize), 13144, 13148, 0,
+	/*13144*/ uint16(xSetOp), uint16(MUL),
+	/*13146*/ uint16(xArgRM16),
+	/*13147*/ uint16(xMatch),
+	/*13148*/ uint16(xSetOp), uint16(MUL),
+	/*13150*/ uint16(xArgRM32),
 	/*13151*/ uint16(xMatch),
-	/*13152*/ uint16(xSetOp), uint16(IMUL),
-	/*13154*/ uint16(xArgRM32),
-	/*13155*/ uint16(xMatch),
-	/*13156*/ uint16(xCondDataSize), 13148, 13152, 13160,
-	/*13160*/ uint16(xSetOp), uint16(IMUL),
-	/*13162*/ uint16(xArgRM64),
-	/*13163*/ uint16(xMatch),
-	/*13164*/ uint16(xCondIs64), 13167, 13179,
-	/*13167*/ uint16(xCondDataSize), 13171, 13175, 0,
-	/*13171*/ uint16(xSetOp), uint16(DIV),
-	/*13173*/ uint16(xArgRM16),
+	/*13152*/ uint16(xCondDataSize), 13144, 13148, 13156,
+	/*13156*/ uint16(xSetOp), uint16(MUL),
+	/*13158*/ uint16(xArgRM64),
+	/*13159*/ uint16(xMatch),
+	/*13160*/ uint16(xCondIs64), 13163, 13175,
+	/*13163*/ uint16(xCondDataSize), 13167, 13171, 0,
+	/*13167*/ uint16(xSetOp), uint16(IMUL),
+	/*13169*/ uint16(xArgRM16),
+	/*13170*/ uint16(xMatch),
+	/*13171*/ uint16(xSetOp), uint16(IMUL),
+	/*13173*/ uint16(xArgRM32),
 	/*13174*/ uint16(xMatch),
-	/*13175*/ uint16(xSetOp), uint16(DIV),
-	/*13177*/ uint16(xArgRM32),
-	/*13178*/ uint16(xMatch),
-	/*13179*/ uint16(xCondDataSize), 13171, 13175, 13183,
-	/*13183*/ uint16(xSetOp), uint16(DIV),
-	/*13185*/ uint16(xArgRM64),
-	/*13186*/ uint16(xMatch),
-	/*13187*/ uint16(xCondIs64), 13190, 13202,
-	/*13190*/ uint16(xCondDataSize), 13194, 13198, 0,
-	/*13194*/ uint16(xSetOp), uint16(IDIV),
-	/*13196*/ uint16(xArgRM16),
+	/*13175*/ uint16(xCondDataSize), 13167, 13171, 13179,
+	/*13179*/ uint16(xSetOp), uint16(IMUL),
+	/*13181*/ uint16(xArgRM64),
+	/*13182*/ uint16(xMatch),
+	/*13183*/ uint16(xCondIs64), 13186, 13198,
+	/*13186*/ uint16(xCondDataSize), 13190, 13194, 0,
+	/*13190*/ uint16(xSetOp), uint16(DIV),
+	/*13192*/ uint16(xArgRM16),
+	/*13193*/ uint16(xMatch),
+	/*13194*/ uint16(xSetOp), uint16(DIV),
+	/*13196*/ uint16(xArgRM32),
 	/*13197*/ uint16(xMatch),
-	/*13198*/ uint16(xSetOp), uint16(IDIV),
-	/*13200*/ uint16(xArgRM32),
-	/*13201*/ uint16(xMatch),
-	/*13202*/ uint16(xCondDataSize), 13194, 13198, 13206,
-	/*13206*/ uint16(xSetOp), uint16(IDIV),
-	/*13208*/ uint16(xArgRM64),
-	/*13209*/ uint16(xMatch),
-	/*13210*/ uint16(xSetOp), uint16(CLC),
-	/*13212*/ uint16(xMatch),
-	/*13213*/ uint16(xSetOp), uint16(STC),
-	/*13215*/ uint16(xMatch),
-	/*13216*/ uint16(xSetOp), uint16(CLI),
-	/*13218*/ uint16(xMatch),
-	/*13219*/ uint16(xSetOp), uint16(STI),
-	/*13221*/ uint16(xMatch),
-	/*13222*/ uint16(xSetOp), uint16(CLD),
-	/*13224*/ uint16(xMatch),
-	/*13225*/ uint16(xSetOp), uint16(STD),
-	/*13227*/ uint16(xMatch),
-	/*13228*/ uint16(xCondSlashR),
-	13237, // 0
-	13241, // 1
+	/*13198*/ uint16(xCondDataSize), 13190, 13194, 13202,
+	/*13202*/ uint16(xSetOp), uint16(DIV),
+	/*13204*/ uint16(xArgRM64),
+	/*13205*/ uint16(xMatch),
+	/*13206*/ uint16(xCondIs64), 13209, 13221,
+	/*13209*/ uint16(xCondDataSize), 13213, 13217, 0,
+	/*13213*/ uint16(xSetOp), uint16(IDIV),
+	/*13215*/ uint16(xArgRM16),
+	/*13216*/ uint16(xMatch),
+	/*13217*/ uint16(xSetOp), uint16(IDIV),
+	/*13219*/ uint16(xArgRM32),
+	/*13220*/ uint16(xMatch),
+	/*13221*/ uint16(xCondDataSize), 13213, 13217, 13225,
+	/*13225*/ uint16(xSetOp), uint16(IDIV),
+	/*13227*/ uint16(xArgRM64),
+	/*13228*/ uint16(xMatch),
+	/*13229*/ uint16(xSetOp), uint16(CLC),
+	/*13231*/ uint16(xMatch),
+	/*13232*/ uint16(xSetOp), uint16(STC),
+	/*13234*/ uint16(xMatch),
+	/*13235*/ uint16(xSetOp), uint16(CLI),
+	/*13237*/ uint16(xMatch),
+	/*13238*/ uint16(xSetOp), uint16(STI),
+	/*13240*/ uint16(xMatch),
+	/*13241*/ uint16(xSetOp), uint16(CLD),
+	/*13243*/ uint16(xMatch),
+	/*13244*/ uint16(xSetOp), uint16(STD),
+	/*13246*/ uint16(xMatch),
+	/*13247*/ uint16(xCondSlashR),
+	13256, // 0
+	13260, // 1
 	0,     // 2
 	0,     // 3
 	0,     // 4
 	0,     // 5
 	0,     // 6
 	0,     // 7
-	/*13237*/ uint16(xSetOp), uint16(INC),
-	/*13239*/ uint16(xArgRM8),
-	/*13240*/ uint16(xMatch),
-	/*13241*/ uint16(xSetOp), uint16(DEC),
-	/*13243*/ uint16(xArgRM8),
-	/*13244*/ uint16(xMatch),
-	/*13245*/ uint16(xCondSlashR),
-	13254, // 0
-	13277, // 1
-	13300, // 2
-	13319, // 3
-	13342, // 4
-	13361, // 5
-	13384, // 6
+	/*13256*/ uint16(xSetOp), uint16(INC),
+	/*13258*/ uint16(xArgRM8),
+	/*13259*/ uint16(xMatch),
+	/*13260*/ uint16(xSetOp), uint16(DEC),
+	/*13262*/ uint16(xArgRM8),
+	/*13263*/ uint16(xMatch),
+	/*13264*/ uint16(xCondSlashR),
+	13273, // 0
+	13296, // 1
+	13319, // 2
+	13338, // 3
+	13361, // 4
+	13380, // 5
+	13403, // 6
 	0,     // 7
-	/*13254*/ uint16(xCondIs64), 13257, 13269,
-	/*13257*/ uint16(xCondDataSize), 13261, 13265, 0,
-	/*13261*/ uint16(xSetOp), uint16(INC),
-	/*13263*/ uint16(xArgRM16),
-	/*13264*/ uint16(xMatch),
-	/*13265*/ uint16(xSetOp), uint16(INC),
-	/*13267*/ uint16(xArgRM32),
-	/*13268*/ uint16(xMatch),
-	/*13269*/ uint16(xCondDataSize), 13261, 13265, 13273,
-	/*13273*/ uint16(xSetOp), uint16(INC),
-	/*13275*/ uint16(xArgRM64),
-	/*13276*/ uint16(xMatch),
-	/*13277*/ uint16(xCondIs64), 13280, 13292,
-	/*13280*/ uint16(xCondDataSize), 13284, 13288, 0,
-	/*13284*/ uint16(xSetOp), uint16(DEC),
-	/*13286*/ uint16(xArgRM16),
+	/*13273*/ uint16(xCondIs64), 13276, 13288,
+	/*13276*/ uint16(xCondDataSize), 13280, 13284, 0,
+	/*13280*/ uint16(xSetOp), uint16(INC),
+	/*13282*/ uint16(xArgRM16),
+	/*13283*/ uint16(xMatch),
+	/*13284*/ uint16(xSetOp), uint16(INC),
+	/*13286*/ uint16(xArgRM32),
 	/*13287*/ uint16(xMatch),
-	/*13288*/ uint16(xSetOp), uint16(DEC),
-	/*13290*/ uint16(xArgRM32),
-	/*13291*/ uint16(xMatch),
-	/*13292*/ uint16(xCondDataSize), 13284, 13288, 13296,
-	/*13296*/ uint16(xSetOp), uint16(DEC),
-	/*13298*/ uint16(xArgRM64),
-	/*13299*/ uint16(xMatch),
-	/*13300*/ uint16(xCondIs64), 13303, 13315,
-	/*13303*/ uint16(xCondDataSize), 13307, 13311, 0,
-	/*13307*/ uint16(xSetOp), uint16(CALL),
-	/*13309*/ uint16(xArgRM16),
+	/*13288*/ uint16(xCondDataSize), 13280, 13284, 13292,
+	/*13292*/ uint16(xSetOp), uint16(INC),
+	/*13294*/ uint16(xArgRM64),
+	/*13295*/ uint16(xMatch),
+	/*13296*/ uint16(xCondIs64), 13299, 13311,
+	/*13299*/ uint16(xCondDataSize), 13303, 13307, 0,
+	/*13303*/ uint16(xSetOp), uint16(DEC),
+	/*13305*/ uint16(xArgRM16),
+	/*13306*/ uint16(xMatch),
+	/*13307*/ uint16(xSetOp), uint16(DEC),
+	/*13309*/ uint16(xArgRM32),
 	/*13310*/ uint16(xMatch),
-	/*13311*/ uint16(xSetOp), uint16(CALL),
-	/*13313*/ uint16(xArgRM32),
-	/*13314*/ uint16(xMatch),
-	/*13315*/ uint16(xSetOp), uint16(CALL),
+	/*13311*/ uint16(xCondDataSize), 13303, 13307, 13315,
+	/*13315*/ uint16(xSetOp), uint16(DEC),
 	/*13317*/ uint16(xArgRM64),
 	/*13318*/ uint16(xMatch),
 	/*13319*/ uint16(xCondIs64), 13322, 13334,
 	/*13322*/ uint16(xCondDataSize), 13326, 13330, 0,
-	/*13326*/ uint16(xSetOp), uint16(LCALL),
-	/*13328*/ uint16(xArgM16colon16),
+	/*13326*/ uint16(xSetOp), uint16(CALL),
+	/*13328*/ uint16(xArgRM16),
 	/*13329*/ uint16(xMatch),
-	/*13330*/ uint16(xSetOp), uint16(LCALL),
-	/*13332*/ uint16(xArgM16colon32),
+	/*13330*/ uint16(xSetOp), uint16(CALL),
+	/*13332*/ uint16(xArgRM32),
 	/*13333*/ uint16(xMatch),
-	/*13334*/ uint16(xCondDataSize), 13326, 13330, 13338,
-	/*13338*/ uint16(xSetOp), uint16(LCALL),
-	/*13340*/ uint16(xArgM16colon64),
-	/*13341*/ uint16(xMatch),
-	/*13342*/ uint16(xCondIs64), 13345, 13357,
-	/*13345*/ uint16(xCondDataSize), 13349, 13353, 0,
-	/*13349*/ uint16(xSetOp), uint16(JMP),
-	/*13351*/ uint16(xArgRM16),
+	/*13334*/ uint16(xSetOp), uint16(CALL),
+	/*13336*/ uint16(xArgRM64),
+	/*13337*/ uint16(xMatch),
+	/*13338*/ uint16(xCondIs64), 13341, 13353,
+	/*13341*/ uint16(xCondDataSize), 13345, 13349, 0,
+	/*13345*/ uint16(xSetOp), uint16(LCALL),
+	/*13347*/ uint16(xArgM16colon16),
+	/*13348*/ uint16(xMatch),
+	/*13349*/ uint16(xSetOp), uint16(LCALL),
+	/*13351*/ uint16(xArgM16colon32),
 	/*13352*/ uint16(xMatch),
-	/*13353*/ uint16(xSetOp), uint16(JMP),
-	/*13355*/ uint16(xArgRM32),
-	/*13356*/ uint16(xMatch),
-	/*13357*/ uint16(xSetOp), uint16(JMP),
-	/*13359*/ uint16(xArgRM64),
+	/*13353*/ uint16(xCondDataSize), 13345, 13349, 13357,
+	/*13357*/ uint16(xSetOp), uint16(LCALL),
+	/*13359*/ uint16(xArgM16colon64),
 	/*13360*/ uint16(xMatch),
 	/*13361*/ uint16(xCondIs64), 13364, 13376,
 	/*13364*/ uint16(xCondDataSize), 13368, 13372, 0,
-	/*13368*/ uint16(xSetOp), uint16(LJMP),
-	/*13370*/ uint16(xArgM16colon16),
+	/*13368*/ uint16(xSetOp), uint16(JMP),
+	/*13370*/ uint16(xArgRM16),
 	/*13371*/ uint16(xMatch),
-	/*13372*/ uint16(xSetOp), uint16(LJMP),
-	/*13374*/ uint16(xArgM16colon32),
+	/*13372*/ uint16(xSetOp), uint16(JMP),
+	/*13374*/ uint16(xArgRM32),
 	/*13375*/ uint16(xMatch),
-	/*13376*/ uint16(xCondDataSize), 13368, 13372, 13380,
-	/*13380*/ uint16(xSetOp), uint16(LJMP),
-	/*13382*/ uint16(xArgM16colon64),
-	/*13383*/ uint16(xMatch),
-	/*13384*/ uint16(xCondIs64), 13387, 13399,
-	/*13387*/ uint16(xCondDataSize), 13391, 13395, 0,
-	/*13391*/ uint16(xSetOp), uint16(PUSH),
-	/*13393*/ uint16(xArgRM16),
+	/*13376*/ uint16(xSetOp), uint16(JMP),
+	/*13378*/ uint16(xArgRM64),
+	/*13379*/ uint16(xMatch),
+	/*13380*/ uint16(xCondIs64), 13383, 13395,
+	/*13383*/ uint16(xCondDataSize), 13387, 13391, 0,
+	/*13387*/ uint16(xSetOp), uint16(LJMP),
+	/*13389*/ uint16(xArgM16colon16),
+	/*13390*/ uint16(xMatch),
+	/*13391*/ uint16(xSetOp), uint16(LJMP),
+	/*13393*/ uint16(xArgM16colon32),
 	/*13394*/ uint16(xMatch),
-	/*13395*/ uint16(xSetOp), uint16(PUSH),
-	/*13397*/ uint16(xArgRM32),
-	/*13398*/ uint16(xMatch),
-	/*13399*/ uint16(xCondDataSize), 13391, 13403, 13407,
-	/*13403*/ uint16(xSetOp), uint16(PUSH),
-	/*13405*/ uint16(xArgRM64),
-	/*13406*/ uint16(xMatch),
-	/*13407*/ uint16(xSetOp), uint16(PUSH),
-	/*13409*/ uint16(xArgRM64),
-	/*13410*/ uint16(xMatch),
+	/*13395*/ uint16(xCondDataSize), 13387, 13391, 13399,
+	/*13399*/ uint16(xSetOp), uint16(LJMP),
+	/*13401*/ uint16(xArgM16colon64),
+	/*13402*/ uint16(xMatch),
+	/*13403*/ uint16(xCondIs64), 13406, 13418,
+	/*13406*/ uint16(xCondDataSize), 13410, 13414, 0,
+	/*13410*/ uint16(xSetOp), uint16(PUSH),
+	/*13412*/ uint16(xArgRM16),
+	/*13413*/ uint16(xMatch),
+	/*13414*/ uint16(xSetOp), uint16(PUSH),
+	/*13416*/ uint16(xArgRM32),
+	/*13417*/ uint16(xMatch),
+	/*13418*/ uint16(xCondDataSize), 13410, 13422, 13426,
+	/*13422*/ uint16(xSetOp), uint16(PUSH),
+	/*13424*/ uint16(xArgRM64),
+	/*13425*/ uint16(xMatch),
+	/*13426*/ uint16(xSetOp), uint16(PUSH),
+	/*13428*/ uint16(xArgRM64),
+	/*13429*/ uint16(xMatch),
 }
 
 const (
@@ -9251,6 +9262,7 @@
 	TZCNT
 	UCOMISD
 	UCOMISS
+	UD0
 	UD1
 	UD2
 	UNPCKHPD
@@ -9868,6 +9880,7 @@
 	TZCNT:           "TZCNT",
 	UCOMISD:         "UCOMISD",
 	UCOMISS:         "UCOMISS",
+	UD0:             "UD0",
 	UD1:             "UD1",
 	UD2:             "UD2",
 	UNPCKHPD:        "UNPCKHPD",
diff --git a/src/cmd/vendor/golang.org/x/crypto/ed25519/ed25519.go b/src/cmd/vendor/golang.org/x/crypto/ed25519/ed25519.go
index c7f8c7e..71ad917 100644
--- a/src/cmd/vendor/golang.org/x/crypto/ed25519/ed25519.go
+++ b/src/cmd/vendor/golang.org/x/crypto/ed25519/ed25519.go
@@ -5,6 +5,7 @@
 // In Go 1.13, the ed25519 package was promoted to the standard library as
 // crypto/ed25519, and this package became a wrapper for the standard library one.
 //
+//go:build !go1.13
 // +build !go1.13
 
 // Package ed25519 implements the Ed25519 signature algorithm. See
diff --git a/src/cmd/vendor/golang.org/x/crypto/ed25519/ed25519_go113.go b/src/cmd/vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
index d1448d8..b5974dc 100644
--- a/src/cmd/vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
+++ b/src/cmd/vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.13
 // +build go1.13
 
 // Package ed25519 implements the Ed25519 signature algorithm. See
diff --git a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
deleted file mode 100644
index 2ffb97b..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
+++ /dev/null
@@ -1,987 +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 terminal
-
-import (
-	"bytes"
-	"io"
-	"runtime"
-	"strconv"
-	"sync"
-	"unicode/utf8"
-)
-
-// EscapeCodes contains escape sequences that can be written to the terminal in
-// order to achieve different styles of text.
-type EscapeCodes struct {
-	// Foreground colors
-	Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte
-
-	// Reset all attributes
-	Reset []byte
-}
-
-var vt100EscapeCodes = EscapeCodes{
-	Black:   []byte{keyEscape, '[', '3', '0', 'm'},
-	Red:     []byte{keyEscape, '[', '3', '1', 'm'},
-	Green:   []byte{keyEscape, '[', '3', '2', 'm'},
-	Yellow:  []byte{keyEscape, '[', '3', '3', 'm'},
-	Blue:    []byte{keyEscape, '[', '3', '4', 'm'},
-	Magenta: []byte{keyEscape, '[', '3', '5', 'm'},
-	Cyan:    []byte{keyEscape, '[', '3', '6', 'm'},
-	White:   []byte{keyEscape, '[', '3', '7', 'm'},
-
-	Reset: []byte{keyEscape, '[', '0', 'm'},
-}
-
-// Terminal contains the state for running a VT100 terminal that is capable of
-// reading lines of input.
-type Terminal struct {
-	// AutoCompleteCallback, if non-null, is called for each keypress with
-	// the full input line and the current position of the cursor (in
-	// bytes, as an index into |line|). If it returns ok=false, the key
-	// press is processed normally. Otherwise it returns a replacement line
-	// and the new cursor position.
-	AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
-
-	// Escape contains a pointer to the escape codes for this terminal.
-	// It's always a valid pointer, although the escape codes themselves
-	// may be empty if the terminal doesn't support them.
-	Escape *EscapeCodes
-
-	// lock protects the terminal and the state in this object from
-	// concurrent processing of a key press and a Write() call.
-	lock sync.Mutex
-
-	c      io.ReadWriter
-	prompt []rune
-
-	// line is the current line being entered.
-	line []rune
-	// pos is the logical position of the cursor in line
-	pos int
-	// echo is true if local echo is enabled
-	echo bool
-	// pasteActive is true iff there is a bracketed paste operation in
-	// progress.
-	pasteActive bool
-
-	// cursorX contains the current X value of the cursor where the left
-	// edge is 0. cursorY contains the row number where the first row of
-	// the current line is 0.
-	cursorX, cursorY int
-	// maxLine is the greatest value of cursorY so far.
-	maxLine int
-
-	termWidth, termHeight int
-
-	// outBuf contains the terminal data to be sent.
-	outBuf []byte
-	// remainder contains the remainder of any partial key sequences after
-	// a read. It aliases into inBuf.
-	remainder []byte
-	inBuf     [256]byte
-
-	// history contains previously entered commands so that they can be
-	// accessed with the up and down keys.
-	history stRingBuffer
-	// historyIndex stores the currently accessed history entry, where zero
-	// means the immediately previous entry.
-	historyIndex int
-	// When navigating up and down the history it's possible to return to
-	// the incomplete, initial line. That value is stored in
-	// historyPending.
-	historyPending string
-}
-
-// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
-// a local terminal, that terminal must first have been put into raw mode.
-// prompt is a string that is written at the start of each input line (i.e.
-// "> ").
-func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
-	return &Terminal{
-		Escape:       &vt100EscapeCodes,
-		c:            c,
-		prompt:       []rune(prompt),
-		termWidth:    80,
-		termHeight:   24,
-		echo:         true,
-		historyIndex: -1,
-	}
-}
-
-const (
-	keyCtrlC     = 3
-	keyCtrlD     = 4
-	keyCtrlU     = 21
-	keyEnter     = '\r'
-	keyEscape    = 27
-	keyBackspace = 127
-	keyUnknown   = 0xd800 /* UTF-16 surrogate area */ + iota
-	keyUp
-	keyDown
-	keyLeft
-	keyRight
-	keyAltLeft
-	keyAltRight
-	keyHome
-	keyEnd
-	keyDeleteWord
-	keyDeleteLine
-	keyClearScreen
-	keyPasteStart
-	keyPasteEnd
-)
-
-var (
-	crlf       = []byte{'\r', '\n'}
-	pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'}
-	pasteEnd   = []byte{keyEscape, '[', '2', '0', '1', '~'}
-)
-
-// bytesToKey tries to parse a key sequence from b. If successful, it returns
-// the key and the remainder of the input. Otherwise it returns utf8.RuneError.
-func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
-	if len(b) == 0 {
-		return utf8.RuneError, nil
-	}
-
-	if !pasteActive {
-		switch b[0] {
-		case 1: // ^A
-			return keyHome, b[1:]
-		case 2: // ^B
-			return keyLeft, b[1:]
-		case 5: // ^E
-			return keyEnd, b[1:]
-		case 6: // ^F
-			return keyRight, b[1:]
-		case 8: // ^H
-			return keyBackspace, b[1:]
-		case 11: // ^K
-			return keyDeleteLine, b[1:]
-		case 12: // ^L
-			return keyClearScreen, b[1:]
-		case 23: // ^W
-			return keyDeleteWord, b[1:]
-		case 14: // ^N
-			return keyDown, b[1:]
-		case 16: // ^P
-			return keyUp, b[1:]
-		}
-	}
-
-	if b[0] != keyEscape {
-		if !utf8.FullRune(b) {
-			return utf8.RuneError, b
-		}
-		r, l := utf8.DecodeRune(b)
-		return r, b[l:]
-	}
-
-	if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' {
-		switch b[2] {
-		case 'A':
-			return keyUp, b[3:]
-		case 'B':
-			return keyDown, b[3:]
-		case 'C':
-			return keyRight, b[3:]
-		case 'D':
-			return keyLeft, b[3:]
-		case 'H':
-			return keyHome, b[3:]
-		case 'F':
-			return keyEnd, b[3:]
-		}
-	}
-
-	if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' {
-		switch b[5] {
-		case 'C':
-			return keyAltRight, b[6:]
-		case 'D':
-			return keyAltLeft, b[6:]
-		}
-	}
-
-	if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) {
-		return keyPasteStart, b[6:]
-	}
-
-	if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) {
-		return keyPasteEnd, b[6:]
-	}
-
-	// If we get here then we have a key that we don't recognise, or a
-	// partial sequence. It's not clear how one should find the end of a
-	// sequence without knowing them all, but it seems that [a-zA-Z~] only
-	// appears at the end of a sequence.
-	for i, c := range b[0:] {
-		if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' {
-			return keyUnknown, b[i+1:]
-		}
-	}
-
-	return utf8.RuneError, b
-}
-
-// queue appends data to the end of t.outBuf
-func (t *Terminal) queue(data []rune) {
-	t.outBuf = append(t.outBuf, []byte(string(data))...)
-}
-
-var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'}
-var space = []rune{' '}
-
-func isPrintable(key rune) bool {
-	isInSurrogateArea := key >= 0xd800 && key <= 0xdbff
-	return key >= 32 && !isInSurrogateArea
-}
-
-// moveCursorToPos appends data to t.outBuf which will move the cursor to the
-// given, logical position in the text.
-func (t *Terminal) moveCursorToPos(pos int) {
-	if !t.echo {
-		return
-	}
-
-	x := visualLength(t.prompt) + pos
-	y := x / t.termWidth
-	x = x % t.termWidth
-
-	up := 0
-	if y < t.cursorY {
-		up = t.cursorY - y
-	}
-
-	down := 0
-	if y > t.cursorY {
-		down = y - t.cursorY
-	}
-
-	left := 0
-	if x < t.cursorX {
-		left = t.cursorX - x
-	}
-
-	right := 0
-	if x > t.cursorX {
-		right = x - t.cursorX
-	}
-
-	t.cursorX = x
-	t.cursorY = y
-	t.move(up, down, left, right)
-}
-
-func (t *Terminal) move(up, down, left, right int) {
-	m := []rune{}
-
-	// 1 unit up can be expressed as ^[[A or ^[A
-	// 5 units up can be expressed as ^[[5A
-
-	if up == 1 {
-		m = append(m, keyEscape, '[', 'A')
-	} else if up > 1 {
-		m = append(m, keyEscape, '[')
-		m = append(m, []rune(strconv.Itoa(up))...)
-		m = append(m, 'A')
-	}
-
-	if down == 1 {
-		m = append(m, keyEscape, '[', 'B')
-	} else if down > 1 {
-		m = append(m, keyEscape, '[')
-		m = append(m, []rune(strconv.Itoa(down))...)
-		m = append(m, 'B')
-	}
-
-	if right == 1 {
-		m = append(m, keyEscape, '[', 'C')
-	} else if right > 1 {
-		m = append(m, keyEscape, '[')
-		m = append(m, []rune(strconv.Itoa(right))...)
-		m = append(m, 'C')
-	}
-
-	if left == 1 {
-		m = append(m, keyEscape, '[', 'D')
-	} else if left > 1 {
-		m = append(m, keyEscape, '[')
-		m = append(m, []rune(strconv.Itoa(left))...)
-		m = append(m, 'D')
-	}
-
-	t.queue(m)
-}
-
-func (t *Terminal) clearLineToRight() {
-	op := []rune{keyEscape, '[', 'K'}
-	t.queue(op)
-}
-
-const maxLineLength = 4096
-
-func (t *Terminal) setLine(newLine []rune, newPos int) {
-	if t.echo {
-		t.moveCursorToPos(0)
-		t.writeLine(newLine)
-		for i := len(newLine); i < len(t.line); i++ {
-			t.writeLine(space)
-		}
-		t.moveCursorToPos(newPos)
-	}
-	t.line = newLine
-	t.pos = newPos
-}
-
-func (t *Terminal) advanceCursor(places int) {
-	t.cursorX += places
-	t.cursorY += t.cursorX / t.termWidth
-	if t.cursorY > t.maxLine {
-		t.maxLine = t.cursorY
-	}
-	t.cursorX = t.cursorX % t.termWidth
-
-	if places > 0 && t.cursorX == 0 {
-		// Normally terminals will advance the current position
-		// when writing a character. But that doesn't happen
-		// for the last character in a line. However, when
-		// writing a character (except a new line) that causes
-		// a line wrap, the position will be advanced two
-		// places.
-		//
-		// So, if we are stopping at the end of a line, we
-		// need to write a newline so that our cursor can be
-		// advanced to the next line.
-		t.outBuf = append(t.outBuf, '\r', '\n')
-	}
-}
-
-func (t *Terminal) eraseNPreviousChars(n int) {
-	if n == 0 {
-		return
-	}
-
-	if t.pos < n {
-		n = t.pos
-	}
-	t.pos -= n
-	t.moveCursorToPos(t.pos)
-
-	copy(t.line[t.pos:], t.line[n+t.pos:])
-	t.line = t.line[:len(t.line)-n]
-	if t.echo {
-		t.writeLine(t.line[t.pos:])
-		for i := 0; i < n; i++ {
-			t.queue(space)
-		}
-		t.advanceCursor(n)
-		t.moveCursorToPos(t.pos)
-	}
-}
-
-// countToLeftWord returns then number of characters from the cursor to the
-// start of the previous word.
-func (t *Terminal) countToLeftWord() int {
-	if t.pos == 0 {
-		return 0
-	}
-
-	pos := t.pos - 1
-	for pos > 0 {
-		if t.line[pos] != ' ' {
-			break
-		}
-		pos--
-	}
-	for pos > 0 {
-		if t.line[pos] == ' ' {
-			pos++
-			break
-		}
-		pos--
-	}
-
-	return t.pos - pos
-}
-
-// countToRightWord returns then number of characters from the cursor to the
-// start of the next word.
-func (t *Terminal) countToRightWord() int {
-	pos := t.pos
-	for pos < len(t.line) {
-		if t.line[pos] == ' ' {
-			break
-		}
-		pos++
-	}
-	for pos < len(t.line) {
-		if t.line[pos] != ' ' {
-			break
-		}
-		pos++
-	}
-	return pos - t.pos
-}
-
-// visualLength returns the number of visible glyphs in s.
-func visualLength(runes []rune) int {
-	inEscapeSeq := false
-	length := 0
-
-	for _, r := range runes {
-		switch {
-		case inEscapeSeq:
-			if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') {
-				inEscapeSeq = false
-			}
-		case r == '\x1b':
-			inEscapeSeq = true
-		default:
-			length++
-		}
-	}
-
-	return length
-}
-
-// handleKey processes the given key and, optionally, returns a line of text
-// that the user has entered.
-func (t *Terminal) handleKey(key rune) (line string, ok bool) {
-	if t.pasteActive && key != keyEnter {
-		t.addKeyToLine(key)
-		return
-	}
-
-	switch key {
-	case keyBackspace:
-		if t.pos == 0 {
-			return
-		}
-		t.eraseNPreviousChars(1)
-	case keyAltLeft:
-		// move left by a word.
-		t.pos -= t.countToLeftWord()
-		t.moveCursorToPos(t.pos)
-	case keyAltRight:
-		// move right by a word.
-		t.pos += t.countToRightWord()
-		t.moveCursorToPos(t.pos)
-	case keyLeft:
-		if t.pos == 0 {
-			return
-		}
-		t.pos--
-		t.moveCursorToPos(t.pos)
-	case keyRight:
-		if t.pos == len(t.line) {
-			return
-		}
-		t.pos++
-		t.moveCursorToPos(t.pos)
-	case keyHome:
-		if t.pos == 0 {
-			return
-		}
-		t.pos = 0
-		t.moveCursorToPos(t.pos)
-	case keyEnd:
-		if t.pos == len(t.line) {
-			return
-		}
-		t.pos = len(t.line)
-		t.moveCursorToPos(t.pos)
-	case keyUp:
-		entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1)
-		if !ok {
-			return "", false
-		}
-		if t.historyIndex == -1 {
-			t.historyPending = string(t.line)
-		}
-		t.historyIndex++
-		runes := []rune(entry)
-		t.setLine(runes, len(runes))
-	case keyDown:
-		switch t.historyIndex {
-		case -1:
-			return
-		case 0:
-			runes := []rune(t.historyPending)
-			t.setLine(runes, len(runes))
-			t.historyIndex--
-		default:
-			entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1)
-			if ok {
-				t.historyIndex--
-				runes := []rune(entry)
-				t.setLine(runes, len(runes))
-			}
-		}
-	case keyEnter:
-		t.moveCursorToPos(len(t.line))
-		t.queue([]rune("\r\n"))
-		line = string(t.line)
-		ok = true
-		t.line = t.line[:0]
-		t.pos = 0
-		t.cursorX = 0
-		t.cursorY = 0
-		t.maxLine = 0
-	case keyDeleteWord:
-		// Delete zero or more spaces and then one or more characters.
-		t.eraseNPreviousChars(t.countToLeftWord())
-	case keyDeleteLine:
-		// Delete everything from the current cursor position to the
-		// end of line.
-		for i := t.pos; i < len(t.line); i++ {
-			t.queue(space)
-			t.advanceCursor(1)
-		}
-		t.line = t.line[:t.pos]
-		t.moveCursorToPos(t.pos)
-	case keyCtrlD:
-		// Erase the character under the current position.
-		// The EOF case when the line is empty is handled in
-		// readLine().
-		if t.pos < len(t.line) {
-			t.pos++
-			t.eraseNPreviousChars(1)
-		}
-	case keyCtrlU:
-		t.eraseNPreviousChars(t.pos)
-	case keyClearScreen:
-		// Erases the screen and moves the cursor to the home position.
-		t.queue([]rune("\x1b[2J\x1b[H"))
-		t.queue(t.prompt)
-		t.cursorX, t.cursorY = 0, 0
-		t.advanceCursor(visualLength(t.prompt))
-		t.setLine(t.line, t.pos)
-	default:
-		if t.AutoCompleteCallback != nil {
-			prefix := string(t.line[:t.pos])
-			suffix := string(t.line[t.pos:])
-
-			t.lock.Unlock()
-			newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key)
-			t.lock.Lock()
-
-			if completeOk {
-				t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos]))
-				return
-			}
-		}
-		if !isPrintable(key) {
-			return
-		}
-		if len(t.line) == maxLineLength {
-			return
-		}
-		t.addKeyToLine(key)
-	}
-	return
-}
-
-// addKeyToLine inserts the given key at the current position in the current
-// line.
-func (t *Terminal) addKeyToLine(key rune) {
-	if len(t.line) == cap(t.line) {
-		newLine := make([]rune, len(t.line), 2*(1+len(t.line)))
-		copy(newLine, t.line)
-		t.line = newLine
-	}
-	t.line = t.line[:len(t.line)+1]
-	copy(t.line[t.pos+1:], t.line[t.pos:])
-	t.line[t.pos] = key
-	if t.echo {
-		t.writeLine(t.line[t.pos:])
-	}
-	t.pos++
-	t.moveCursorToPos(t.pos)
-}
-
-func (t *Terminal) writeLine(line []rune) {
-	for len(line) != 0 {
-		remainingOnLine := t.termWidth - t.cursorX
-		todo := len(line)
-		if todo > remainingOnLine {
-			todo = remainingOnLine
-		}
-		t.queue(line[:todo])
-		t.advanceCursor(visualLength(line[:todo]))
-		line = line[todo:]
-	}
-}
-
-// writeWithCRLF writes buf to w but replaces all occurrences of \n with \r\n.
-func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) {
-	for len(buf) > 0 {
-		i := bytes.IndexByte(buf, '\n')
-		todo := len(buf)
-		if i >= 0 {
-			todo = i
-		}
-
-		var nn int
-		nn, err = w.Write(buf[:todo])
-		n += nn
-		if err != nil {
-			return n, err
-		}
-		buf = buf[todo:]
-
-		if i >= 0 {
-			if _, err = w.Write(crlf); err != nil {
-				return n, err
-			}
-			n++
-			buf = buf[1:]
-		}
-	}
-
-	return n, nil
-}
-
-func (t *Terminal) Write(buf []byte) (n int, err error) {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	if t.cursorX == 0 && t.cursorY == 0 {
-		// This is the easy case: there's nothing on the screen that we
-		// have to move out of the way.
-		return writeWithCRLF(t.c, buf)
-	}
-
-	// We have a prompt and possibly user input on the screen. We
-	// have to clear it first.
-	t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */)
-	t.cursorX = 0
-	t.clearLineToRight()
-
-	for t.cursorY > 0 {
-		t.move(1 /* up */, 0, 0, 0)
-		t.cursorY--
-		t.clearLineToRight()
-	}
-
-	if _, err = t.c.Write(t.outBuf); err != nil {
-		return
-	}
-	t.outBuf = t.outBuf[:0]
-
-	if n, err = writeWithCRLF(t.c, buf); err != nil {
-		return
-	}
-
-	t.writeLine(t.prompt)
-	if t.echo {
-		t.writeLine(t.line)
-	}
-
-	t.moveCursorToPos(t.pos)
-
-	if _, err = t.c.Write(t.outBuf); err != nil {
-		return
-	}
-	t.outBuf = t.outBuf[:0]
-	return
-}
-
-// ReadPassword temporarily changes the prompt and reads a password, without
-// echo, from the terminal.
-func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	oldPrompt := t.prompt
-	t.prompt = []rune(prompt)
-	t.echo = false
-
-	line, err = t.readLine()
-
-	t.prompt = oldPrompt
-	t.echo = true
-
-	return
-}
-
-// ReadLine returns a line of input from the terminal.
-func (t *Terminal) ReadLine() (line string, err error) {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.readLine()
-}
-
-func (t *Terminal) readLine() (line string, err error) {
-	// t.lock must be held at this point
-
-	if t.cursorX == 0 && t.cursorY == 0 {
-		t.writeLine(t.prompt)
-		t.c.Write(t.outBuf)
-		t.outBuf = t.outBuf[:0]
-	}
-
-	lineIsPasted := t.pasteActive
-
-	for {
-		rest := t.remainder
-		lineOk := false
-		for !lineOk {
-			var key rune
-			key, rest = bytesToKey(rest, t.pasteActive)
-			if key == utf8.RuneError {
-				break
-			}
-			if !t.pasteActive {
-				if key == keyCtrlD {
-					if len(t.line) == 0 {
-						return "", io.EOF
-					}
-				}
-				if key == keyCtrlC {
-					return "", io.EOF
-				}
-				if key == keyPasteStart {
-					t.pasteActive = true
-					if len(t.line) == 0 {
-						lineIsPasted = true
-					}
-					continue
-				}
-			} else if key == keyPasteEnd {
-				t.pasteActive = false
-				continue
-			}
-			if !t.pasteActive {
-				lineIsPasted = false
-			}
-			line, lineOk = t.handleKey(key)
-		}
-		if len(rest) > 0 {
-			n := copy(t.inBuf[:], rest)
-			t.remainder = t.inBuf[:n]
-		} else {
-			t.remainder = nil
-		}
-		t.c.Write(t.outBuf)
-		t.outBuf = t.outBuf[:0]
-		if lineOk {
-			if t.echo {
-				t.historyIndex = -1
-				t.history.Add(line)
-			}
-			if lineIsPasted {
-				err = ErrPasteIndicator
-			}
-			return
-		}
-
-		// t.remainder is a slice at the beginning of t.inBuf
-		// containing a partial key sequence
-		readBuf := t.inBuf[len(t.remainder):]
-		var n int
-
-		t.lock.Unlock()
-		n, err = t.c.Read(readBuf)
-		t.lock.Lock()
-
-		if err != nil {
-			return
-		}
-
-		t.remainder = t.inBuf[:n+len(t.remainder)]
-	}
-}
-
-// SetPrompt sets the prompt to be used when reading subsequent lines.
-func (t *Terminal) SetPrompt(prompt string) {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	t.prompt = []rune(prompt)
-}
-
-func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) {
-	// Move cursor to column zero at the start of the line.
-	t.move(t.cursorY, 0, t.cursorX, 0)
-	t.cursorX, t.cursorY = 0, 0
-	t.clearLineToRight()
-	for t.cursorY < numPrevLines {
-		// Move down a line
-		t.move(0, 1, 0, 0)
-		t.cursorY++
-		t.clearLineToRight()
-	}
-	// Move back to beginning.
-	t.move(t.cursorY, 0, 0, 0)
-	t.cursorX, t.cursorY = 0, 0
-
-	t.queue(t.prompt)
-	t.advanceCursor(visualLength(t.prompt))
-	t.writeLine(t.line)
-	t.moveCursorToPos(t.pos)
-}
-
-func (t *Terminal) SetSize(width, height int) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	if width == 0 {
-		width = 1
-	}
-
-	oldWidth := t.termWidth
-	t.termWidth, t.termHeight = width, height
-
-	switch {
-	case width == oldWidth:
-		// If the width didn't change then nothing else needs to be
-		// done.
-		return nil
-	case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0:
-		// If there is nothing on current line and no prompt printed,
-		// just do nothing
-		return nil
-	case width < oldWidth:
-		// Some terminals (e.g. xterm) will truncate lines that were
-		// too long when shinking. Others, (e.g. gnome-terminal) will
-		// attempt to wrap them. For the former, repainting t.maxLine
-		// works great, but that behaviour goes badly wrong in the case
-		// of the latter because they have doubled every full line.
-
-		// We assume that we are working on a terminal that wraps lines
-		// and adjust the cursor position based on every previous line
-		// wrapping and turning into two. This causes the prompt on
-		// xterms to move upwards, which isn't great, but it avoids a
-		// huge mess with gnome-terminal.
-		if t.cursorX >= t.termWidth {
-			t.cursorX = t.termWidth - 1
-		}
-		t.cursorY *= 2
-		t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2)
-	case width > oldWidth:
-		// If the terminal expands then our position calculations will
-		// be wrong in the future because we think the cursor is
-		// |t.pos| chars into the string, but there will be a gap at
-		// the end of any wrapped line.
-		//
-		// But the position will actually be correct until we move, so
-		// we can move back to the beginning and repaint everything.
-		t.clearAndRepaintLinePlusNPrevious(t.maxLine)
-	}
-
-	_, err := t.c.Write(t.outBuf)
-	t.outBuf = t.outBuf[:0]
-	return err
-}
-
-type pasteIndicatorError struct{}
-
-func (pasteIndicatorError) Error() string {
-	return "terminal: ErrPasteIndicator not correctly handled"
-}
-
-// ErrPasteIndicator may be returned from ReadLine as the error, in addition
-// to valid line data. It indicates that bracketed paste mode is enabled and
-// that the returned line consists only of pasted data. Programs may wish to
-// interpret pasted data more literally than typed data.
-var ErrPasteIndicator = pasteIndicatorError{}
-
-// SetBracketedPasteMode requests that the terminal bracket paste operations
-// with markers. Not all terminals support this but, if it is supported, then
-// enabling this mode will stop any autocomplete callback from running due to
-// pastes. Additionally, any lines that are completely pasted will be returned
-// from ReadLine with the error set to ErrPasteIndicator.
-func (t *Terminal) SetBracketedPasteMode(on bool) {
-	if on {
-		io.WriteString(t.c, "\x1b[?2004h")
-	} else {
-		io.WriteString(t.c, "\x1b[?2004l")
-	}
-}
-
-// stRingBuffer is a ring buffer of strings.
-type stRingBuffer struct {
-	// entries contains max elements.
-	entries []string
-	max     int
-	// head contains the index of the element most recently added to the ring.
-	head int
-	// size contains the number of elements in the ring.
-	size int
-}
-
-func (s *stRingBuffer) Add(a string) {
-	if s.entries == nil {
-		const defaultNumEntries = 100
-		s.entries = make([]string, defaultNumEntries)
-		s.max = defaultNumEntries
-	}
-
-	s.head = (s.head + 1) % s.max
-	s.entries[s.head] = a
-	if s.size < s.max {
-		s.size++
-	}
-}
-
-// NthPreviousEntry returns the value passed to the nth previous call to Add.
-// If n is zero then the immediately prior value is returned, if one, then the
-// next most recent, and so on. If such an element doesn't exist then ok is
-// false.
-func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
-	if n >= s.size {
-		return "", false
-	}
-	index := s.head - n
-	if index < 0 {
-		index += s.max
-	}
-	return s.entries[index], true
-}
-
-// readPasswordLine reads from reader until it finds \n or io.EOF.
-// The slice returned does not include the \n.
-// readPasswordLine also ignores any \r it finds.
-// Windows uses \r as end of line. So, on Windows, readPasswordLine
-// reads until it finds \r and ignores any \n it finds during processing.
-func readPasswordLine(reader io.Reader) ([]byte, error) {
-	var buf [1]byte
-	var ret []byte
-
-	for {
-		n, err := reader.Read(buf[:])
-		if n > 0 {
-			switch buf[0] {
-			case '\b':
-				if len(ret) > 0 {
-					ret = ret[:len(ret)-1]
-				}
-			case '\n':
-				if runtime.GOOS != "windows" {
-					return ret, nil
-				}
-				// otherwise ignore \n
-			case '\r':
-				if runtime.GOOS == "windows" {
-					return ret, nil
-				}
-				// otherwise ignore \r
-			default:
-				ret = append(ret, buf[0])
-			}
-			continue
-		}
-		if err != nil {
-			if err == io.EOF && len(ret) > 0 {
-				return ret, nil
-			}
-			return ret, err
-		}
-	}
-}
diff --git a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util.go b/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util.go
deleted file mode 100644
index 3911040..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util.go
+++ /dev/null
@@ -1,114 +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 aix darwin dragonfly freebsd linux,!appengine netbsd openbsd
-
-// Package terminal provides support functions for dealing with terminals, as
-// commonly found on UNIX systems.
-//
-// Putting a terminal into raw mode is the most common requirement:
-//
-// 	oldState, err := terminal.MakeRaw(0)
-// 	if err != nil {
-// 	        panic(err)
-// 	}
-// 	defer terminal.Restore(0, oldState)
-package terminal // import "golang.org/x/crypto/ssh/terminal"
-
-import (
-	"golang.org/x/sys/unix"
-)
-
-// State contains the state of a terminal.
-type State struct {
-	termios unix.Termios
-}
-
-// IsTerminal returns whether the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
-	_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
-	return err == nil
-}
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd int) (*State, error) {
-	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
-	if err != nil {
-		return nil, err
-	}
-
-	oldState := State{termios: *termios}
-
-	// This attempts to replicate the behaviour documented for cfmakeraw in
-	// the termios(3) manpage.
-	termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
-	termios.Oflag &^= unix.OPOST
-	termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
-	termios.Cflag &^= unix.CSIZE | unix.PARENB
-	termios.Cflag |= unix.CS8
-	termios.Cc[unix.VMIN] = 1
-	termios.Cc[unix.VTIME] = 0
-	if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, termios); err != nil {
-		return nil, err
-	}
-
-	return &oldState, nil
-}
-
-// GetState returns the current state of a terminal which may be useful to
-// restore the terminal after a signal.
-func GetState(fd int) (*State, error) {
-	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
-	if err != nil {
-		return nil, err
-	}
-
-	return &State{termios: *termios}, nil
-}
-
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func Restore(fd int, state *State) error {
-	return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios)
-}
-
-// GetSize returns the dimensions of the given terminal.
-func GetSize(fd int) (width, height int, err error) {
-	ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
-	if err != nil {
-		return -1, -1, err
-	}
-	return int(ws.Col), int(ws.Row), nil
-}
-
-// passwordReader is an io.Reader that reads from a specific file descriptor.
-type passwordReader int
-
-func (r passwordReader) Read(buf []byte) (int, error) {
-	return unix.Read(int(r), buf)
-}
-
-// ReadPassword reads a line of input from a terminal without local echo.  This
-// is commonly used for inputting passwords and other sensitive data. The slice
-// returned does not include the \n.
-func ReadPassword(fd int) ([]byte, error) {
-	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
-	if err != nil {
-		return nil, err
-	}
-
-	newState := *termios
-	newState.Lflag &^= unix.ECHO
-	newState.Lflag |= unix.ICANON | unix.ISIG
-	newState.Iflag |= unix.ICRNL
-	if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newState); err != nil {
-		return nil, err
-	}
-
-	defer unix.IoctlSetTermios(fd, ioctlWriteTermios, termios)
-
-	return readPasswordLine(passwordReader(fd))
-}
diff --git a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_aix.go b/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_aix.go
deleted file mode 100644
index dfcd627..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_aix.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build aix
-
-package terminal
-
-import "golang.org/x/sys/unix"
-
-const ioctlReadTermios = unix.TCGETS
-const ioctlWriteTermios = unix.TCSETS
diff --git a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go b/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go
deleted file mode 100644
index cb23a59..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd netbsd openbsd
-
-package terminal
-
-import "golang.org/x/sys/unix"
-
-const ioctlReadTermios = unix.TIOCGETA
-const ioctlWriteTermios = unix.TIOCSETA
diff --git a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go b/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go
deleted file mode 100644
index 5fadfe8..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go
+++ /dev/null
@@ -1,10 +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 terminal
-
-import "golang.org/x/sys/unix"
-
-const ioctlReadTermios = unix.TCGETS
-const ioctlWriteTermios = unix.TCSETS
diff --git a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go b/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go
deleted file mode 100644
index 9317ac7..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go
+++ /dev/null
@@ -1,58 +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.
-
-// Package terminal provides support functions for dealing with terminals, as
-// commonly found on UNIX systems.
-//
-// Putting a terminal into raw mode is the most common requirement:
-//
-// 	oldState, err := terminal.MakeRaw(0)
-// 	if err != nil {
-// 	        panic(err)
-// 	}
-// 	defer terminal.Restore(0, oldState)
-package terminal
-
-import (
-	"fmt"
-	"runtime"
-)
-
-type State struct{}
-
-// IsTerminal returns whether the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
-	return false
-}
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd int) (*State, error) {
-	return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
-
-// GetState returns the current state of a terminal which may be useful to
-// restore the terminal after a signal.
-func GetState(fd int) (*State, error) {
-	return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
-
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func Restore(fd int, state *State) error {
-	return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
-
-// GetSize returns the dimensions of the given terminal.
-func GetSize(fd int) (width, height int, err error) {
-	return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
-
-// ReadPassword reads a line of input from a terminal without local echo.  This
-// is commonly used for inputting passwords and other sensitive data. The slice
-// returned does not include the \n.
-func ReadPassword(fd int) ([]byte, error) {
-	return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
diff --git a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go b/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go
deleted file mode 100644
index 3d5f06a..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go
+++ /dev/null
@@ -1,124 +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.
-
-// +build solaris
-
-package terminal // import "golang.org/x/crypto/ssh/terminal"
-
-import (
-	"golang.org/x/sys/unix"
-	"io"
-	"syscall"
-)
-
-// State contains the state of a terminal.
-type State struct {
-	termios unix.Termios
-}
-
-// IsTerminal returns whether the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
-	_, err := unix.IoctlGetTermio(fd, unix.TCGETA)
-	return err == nil
-}
-
-// ReadPassword reads a line of input from a terminal without local echo.  This
-// is commonly used for inputting passwords and other sensitive data. The slice
-// returned does not include the \n.
-func ReadPassword(fd int) ([]byte, error) {
-	// see also: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c
-	val, err := unix.IoctlGetTermios(fd, unix.TCGETS)
-	if err != nil {
-		return nil, err
-	}
-	oldState := *val
-
-	newState := oldState
-	newState.Lflag &^= syscall.ECHO
-	newState.Lflag |= syscall.ICANON | syscall.ISIG
-	newState.Iflag |= syscall.ICRNL
-	err = unix.IoctlSetTermios(fd, unix.TCSETS, &newState)
-	if err != nil {
-		return nil, err
-	}
-
-	defer unix.IoctlSetTermios(fd, unix.TCSETS, &oldState)
-
-	var buf [16]byte
-	var ret []byte
-	for {
-		n, err := syscall.Read(fd, buf[:])
-		if err != nil {
-			return nil, err
-		}
-		if n == 0 {
-			if len(ret) == 0 {
-				return nil, io.EOF
-			}
-			break
-		}
-		if buf[n-1] == '\n' {
-			n--
-		}
-		ret = append(ret, buf[:n]...)
-		if n < len(buf) {
-			break
-		}
-	}
-
-	return ret, nil
-}
-
-// MakeRaw puts the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-// see http://cr.illumos.org/~webrev/andy_js/1060/
-func MakeRaw(fd int) (*State, error) {
-	termios, err := unix.IoctlGetTermios(fd, unix.TCGETS)
-	if err != nil {
-		return nil, err
-	}
-
-	oldState := State{termios: *termios}
-
-	termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
-	termios.Oflag &^= unix.OPOST
-	termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
-	termios.Cflag &^= unix.CSIZE | unix.PARENB
-	termios.Cflag |= unix.CS8
-	termios.Cc[unix.VMIN] = 1
-	termios.Cc[unix.VTIME] = 0
-
-	if err := unix.IoctlSetTermios(fd, unix.TCSETS, termios); err != nil {
-		return nil, err
-	}
-
-	return &oldState, nil
-}
-
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func Restore(fd int, oldState *State) error {
-	return unix.IoctlSetTermios(fd, unix.TCSETS, &oldState.termios)
-}
-
-// GetState returns the current state of a terminal which may be useful to
-// restore the terminal after a signal.
-func GetState(fd int) (*State, error) {
-	termios, err := unix.IoctlGetTermios(fd, unix.TCGETS)
-	if err != nil {
-		return nil, err
-	}
-
-	return &State{termios: *termios}, nil
-}
-
-// GetSize returns the dimensions of the given terminal.
-func GetSize(fd int) (width, height int, err error) {
-	ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
-	if err != nil {
-		return 0, 0, err
-	}
-	return int(ws.Col), int(ws.Row), nil
-}
diff --git a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go b/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
deleted file mode 100644
index f614e9c..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
+++ /dev/null
@@ -1,105 +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 windows
-
-// Package terminal provides support functions for dealing with terminals, as
-// commonly found on UNIX systems.
-//
-// Putting a terminal into raw mode is the most common requirement:
-//
-// 	oldState, err := terminal.MakeRaw(0)
-// 	if err != nil {
-// 	        panic(err)
-// 	}
-// 	defer terminal.Restore(0, oldState)
-package terminal
-
-import (
-	"os"
-
-	"golang.org/x/sys/windows"
-)
-
-type State struct {
-	mode uint32
-}
-
-// IsTerminal returns whether the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
-	var st uint32
-	err := windows.GetConsoleMode(windows.Handle(fd), &st)
-	return err == nil
-}
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd int) (*State, error) {
-	var st uint32
-	if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
-		return nil, err
-	}
-	raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
-	if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil {
-		return nil, err
-	}
-	return &State{st}, nil
-}
-
-// GetState returns the current state of a terminal which may be useful to
-// restore the terminal after a signal.
-func GetState(fd int) (*State, error) {
-	var st uint32
-	if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
-		return nil, err
-	}
-	return &State{st}, nil
-}
-
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func Restore(fd int, state *State) error {
-	return windows.SetConsoleMode(windows.Handle(fd), state.mode)
-}
-
-// GetSize returns the visible dimensions of the given terminal.
-//
-// These dimensions don't include any scrollback buffer height.
-func GetSize(fd int) (width, height int, err error) {
-	var info windows.ConsoleScreenBufferInfo
-	if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
-		return 0, 0, err
-	}
-	return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil
-}
-
-// ReadPassword reads a line of input from a terminal without local echo.  This
-// is commonly used for inputting passwords and other sensitive data. The slice
-// returned does not include the \n.
-func ReadPassword(fd int) ([]byte, error) {
-	var st uint32
-	if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
-		return nil, err
-	}
-	old := st
-
-	st &^= (windows.ENABLE_ECHO_INPUT | windows.ENABLE_LINE_INPUT)
-	st |= (windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_PROCESSED_INPUT)
-	if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil {
-		return nil, err
-	}
-
-	defer windows.SetConsoleMode(windows.Handle(fd), old)
-
-	var h windows.Handle
-	p, _ := windows.GetCurrentProcess()
-	if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil {
-		return nil, err
-	}
-
-	f := os.NewFile(uintptr(h), "stdin")
-	defer f.Close()
-	return readPasswordLine(f)
-}
diff --git a/src/cmd/vendor/golang.org/x/mod/modfile/read.go b/src/cmd/vendor/golang.org/x/mod/modfile/read.go
index 2a961ca..956f30c 100644
--- a/src/cmd/vendor/golang.org/x/mod/modfile/read.go
+++ b/src/cmd/vendor/golang.org/x/mod/modfile/read.go
@@ -194,12 +194,15 @@
 	line.Token = tokens
 }
 
-func (x *FileSyntax) removeLine(line *Line) {
+// markRemoved modifies line so that it (and its end-of-line comment, if any)
+// will be dropped by (*FileSyntax).Cleanup.
+func (line *Line) markRemoved() {
 	line.Token = nil
+	line.Comments.Suffix = nil
 }
 
 // Cleanup cleans up the file syntax x after any edit operations.
-// To avoid quadratic behavior, removeLine marks the line as dead
+// To avoid quadratic behavior, (*Line).markRemoved marks the line as dead
 // by setting line.Token = nil but does not remove it from the slice
 // in which it appears. After edits have all been indicated,
 // calling Cleanup cleans out the dead lines.
diff --git a/src/cmd/vendor/golang.org/x/mod/modfile/rule.go b/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
index f8c9384..78f83fa 100644
--- a/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
+++ b/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
@@ -47,8 +47,9 @@
 
 // A Module is the module statement.
 type Module struct {
-	Mod    module.Version
-	Syntax *Line
+	Mod        module.Version
+	Deprecated string
+	Syntax     *Line
 }
 
 // A Go is the go statement.
@@ -57,13 +58,6 @@
 	Syntax  *Line
 }
 
-// A Require is a single require statement.
-type Require struct {
-	Mod      module.Version
-	Indirect bool // has "// indirect" comment
-	Syntax   *Line
-}
-
 // An Exclude is a single exclude statement.
 type Exclude struct {
 	Mod    module.Version
@@ -92,6 +86,93 @@
 	Low, High string
 }
 
+// A Require is a single require statement.
+type Require struct {
+	Mod      module.Version
+	Indirect bool // has "// indirect" comment
+	Syntax   *Line
+}
+
+func (r *Require) markRemoved() {
+	r.Syntax.markRemoved()
+	*r = Require{}
+}
+
+func (r *Require) setVersion(v string) {
+	r.Mod.Version = v
+
+	if line := r.Syntax; len(line.Token) > 0 {
+		if line.InBlock {
+			// If the line is preceded by an empty line, remove it; see
+			// https://golang.org/issue/33779.
+			if len(line.Comments.Before) == 1 && len(line.Comments.Before[0].Token) == 0 {
+				line.Comments.Before = line.Comments.Before[:0]
+			}
+			if len(line.Token) >= 2 { // example.com v1.2.3
+				line.Token[1] = v
+			}
+		} else {
+			if len(line.Token) >= 3 { // require example.com v1.2.3
+				line.Token[2] = v
+			}
+		}
+	}
+}
+
+// setIndirect sets line to have (or not have) a "// indirect" comment.
+func (r *Require) setIndirect(indirect bool) {
+	r.Indirect = indirect
+	line := r.Syntax
+	if isIndirect(line) == indirect {
+		return
+	}
+	if indirect {
+		// Adding comment.
+		if len(line.Suffix) == 0 {
+			// New comment.
+			line.Suffix = []Comment{{Token: "// indirect", Suffix: true}}
+			return
+		}
+
+		com := &line.Suffix[0]
+		text := strings.TrimSpace(strings.TrimPrefix(com.Token, string(slashSlash)))
+		if text == "" {
+			// Empty comment.
+			com.Token = "// indirect"
+			return
+		}
+
+		// Insert at beginning of existing comment.
+		com.Token = "// indirect; " + text
+		return
+	}
+
+	// Removing comment.
+	f := strings.TrimSpace(strings.TrimPrefix(line.Suffix[0].Token, string(slashSlash)))
+	if f == "indirect" {
+		// Remove whole comment.
+		line.Suffix = nil
+		return
+	}
+
+	// Remove comment prefix.
+	com := &line.Suffix[0]
+	i := strings.Index(com.Token, "indirect;")
+	com.Token = "//" + com.Token[i+len("indirect;"):]
+}
+
+// isIndirect reports whether line has a "// indirect" comment,
+// meaning it is in go.mod only for its effect on indirect dependencies,
+// so that it can be dropped entirely once the effective version of the
+// indirect dependency reaches the given minimum version.
+func isIndirect(line *Line) bool {
+	if len(line.Suffix) == 0 {
+		return false
+	}
+	f := strings.Fields(strings.TrimPrefix(line.Suffix[0].Token, string(slashSlash)))
+	return (len(f) == 1 && f[0] == "indirect" || len(f) > 1 && f[0] == "indirect;")
+}
+
 func (f *File) AddModuleStmt(path string) error {
 	if f.Syntax == nil {
 		f.Syntax = new(FileSyntax)
@@ -131,8 +212,15 @@
 	return vers, nil
 }
 
-// Parse parses the data, reported in errors as being from file,
-// into a File struct. It applies fix, if non-nil, to canonicalize all module versions found.
+// Parse parses and returns a go.mod file.
+//
+// file is the name of the file, used in positions and errors.
+//
+// data is the content of the file.
+//
+// fix is an optional function that canonicalizes module versions.
+// If fix is nil, all module versions must be canonical (module.CanonicalVersion
+// must return the same string).
 func Parse(file string, data []byte, fix VersionFixer) (*File, error) {
 	return parseToFile(file, data, fix, true)
 }
@@ -209,6 +297,7 @@
 }
 
 var GoVersionRE = lazyregexp.New(`^([1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
+var laxGoVersionRE = lazyregexp.New(`^v?(([1-9][0-9]*)\.(0|[1-9][0-9]*))([^0-9].*)$`)
 
 func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, args []string, fix VersionFixer, strict bool) {
 	// If strict is false, this module is a dependency.
@@ -259,8 +348,17 @@
 			errorf("go directive expects exactly one argument")
 			return
 		} else if !GoVersionRE.MatchString(args[0]) {
-			errorf("invalid go version '%s': must match format 1.23", args[0])
-			return
+			fixed := false
+			if !strict {
+				if m := laxGoVersionRE.FindStringSubmatch(args[0]); m != nil {
+					args[0] = m[1]
+					fixed = true
+				}
+			}
+			if !fixed {
+				errorf("invalid go version '%s': must match format 1.23", args[0])
+				return
+			}
 		}
 
 		f.Go = &Go{Syntax: line}
@@ -271,7 +369,11 @@
 			errorf("repeated module statement")
 			return
 		}
-		f.Module = &Module{Syntax: line}
+		deprecated := parseDeprecation(block, line)
+		f.Module = &Module{
+			Syntax:     line,
+			Deprecated: deprecated,
+		}
 		if len(args) != 1 {
 			errorf("usage: module module/path")
 			return
@@ -385,7 +487,7 @@
 		})
 
 	case "retract":
-		rationale := parseRetractRationale(block, line)
+		rationale := parseDirectiveComment(block, line)
 		vi, err := parseVersionInterval(verb, "", &args, dontFixRetract)
 		if err != nil {
 			if strict {
@@ -454,58 +556,6 @@
 	}
 }
 
-// isIndirect reports whether line has a "// indirect" comment,
-// meaning it is in go.mod only for its effect on indirect dependencies,
-// so that it can be dropped entirely once the effective version of the
-// indirect dependency reaches the given minimum version.
-func isIndirect(line *Line) bool {
-	if len(line.Suffix) == 0 {
-		return false
-	}
-	f := strings.Fields(strings.TrimPrefix(line.Suffix[0].Token, string(slashSlash)))
-	return (len(f) == 1 && f[0] == "indirect" || len(f) > 1 && f[0] == "indirect;")
-}
-
-// setIndirect sets line to have (or not have) a "// indirect" comment.
-func setIndirect(line *Line, indirect bool) {
-	if isIndirect(line) == indirect {
-		return
-	}
-	if indirect {
-		// Adding comment.
-		if len(line.Suffix) == 0 {
-			// New comment.
-			line.Suffix = []Comment{{Token: "// indirect", Suffix: true}}
-			return
-		}
-
-		com := &line.Suffix[0]
-		text := strings.TrimSpace(strings.TrimPrefix(com.Token, string(slashSlash)))
-		if text == "" {
-			// Empty comment.
-			com.Token = "// indirect"
-			return
-		}
-
-		// Insert at beginning of existing comment.
-		com.Token = "// indirect; " + text
-		return
-	}
-
-	// Removing comment.
-	f := strings.Fields(line.Suffix[0].Token)
-	if len(f) == 2 {
-		// Remove whole comment.
-		line.Suffix = nil
-		return
-	}
-
-	// Remove comment prefix.
-	com := &line.Suffix[0]
-	i := strings.Index(com.Token, "indirect;")
-	com.Token = "//" + com.Token[i+len("indirect;"):]
-}
-
 // IsDirectoryPath reports whether the given path should be interpreted
 // as a directory path. Just like on the go command line, relative paths
 // and rooted paths are directory paths; the rest are module paths.
@@ -612,10 +662,29 @@
 	return t, nil
 }
 
-// parseRetractRationale extracts the rationale for a retract directive from the
-// surrounding comments. If the line does not have comments and is part of a
-// block that does have comments, the block's comments are used.
-func parseRetractRationale(block *LineBlock, line *Line) string {
+var deprecatedRE = lazyregexp.New(`(?s)(?:^|\n\n)Deprecated: *(.*?)(?:$|\n\n)`)
+
+// parseDeprecation extracts the text of comments on a "module" directive and
+// extracts a deprecation message from that.
+//
+// A deprecation message is contained in a paragraph within a block of comments
+// that starts with "Deprecated:" (case sensitive). The message runs until the
+// end of the paragraph and does not include the "Deprecated:" prefix. If the
+// comment block has multiple paragraphs that start with "Deprecated:",
+// parseDeprecation returns the message from the first.
+func parseDeprecation(block *LineBlock, line *Line) string {
+	text := parseDirectiveComment(block, line)
+	m := deprecatedRE.FindStringSubmatch(text)
+	if m == nil {
+		return ""
+	}
+	return m[1]
+}
+
+// parseDirectiveComment extracts the text of comments on a directive.
+// If the directive's line does not have comments and is part of a block that
+// does have comments, the block's comments are used.
+func parseDirectiveComment(block *LineBlock, line *Line) string {
 	comments := line.Comment()
 	if block != nil && len(comments.Before) == 0 && len(comments.Suffix) == 0 {
 		comments = block.Comment()
@@ -794,6 +863,12 @@
 	return nil
 }
 
+// AddRequire sets the first require line for path to version vers,
+// preserving any existing comments for that line and removing all
+// other lines for path.
+//
+// If no line currently exists for path, AddRequire adds a new line
+// at the end of the last require block.
 func (f *File) AddRequire(path, vers string) error {
 	need := true
 	for _, r := range f.Require {
@@ -803,7 +878,7 @@
 				f.Syntax.updateLine(r.Syntax, "require", AutoQuote(path), vers)
 				need = false
 			} else {
-				f.Syntax.removeLine(r.Syntax)
+				r.Syntax.markRemoved()
 				*r = Require{}
 			}
 		}
@@ -815,69 +890,235 @@
 	return nil
 }
 
+// AddNewRequire adds a new require line for path at version vers at the end of
+// the last require block, regardless of any existing require lines for path.
 func (f *File) AddNewRequire(path, vers string, indirect bool) {
 	line := f.Syntax.addLine(nil, "require", AutoQuote(path), vers)
-	setIndirect(line, indirect)
-	f.Require = append(f.Require, &Require{module.Version{Path: path, Version: vers}, indirect, line})
+	r := &Require{
+		Mod:    module.Version{Path: path, Version: vers},
+		Syntax: line,
+	}
+	r.setIndirect(indirect)
+	f.Require = append(f.Require, r)
 }
 
+// SetRequire updates the requirements of f to contain exactly req, preserving
+// the existing block structure and line comment contents (except for 'indirect'
+// markings) for the first requirement on each named module path.
+//
+// The Syntax field is ignored for the requirements in req.
+//
+// Any requirements not already present in the file are added to the block
+// containing the last require line.
+//
+// The requirements in req must specify at most one distinct version for each
+// module path.
+//
+// If any existing requirements may be removed, the caller should call Cleanup
+// after all edits are complete.
 func (f *File) SetRequire(req []*Require) {
-	need := make(map[string]string)
-	indirect := make(map[string]bool)
+	type elem struct {
+		version  string
+		indirect bool
+	}
+	need := make(map[string]elem)
 	for _, r := range req {
-		need[r.Mod.Path] = r.Mod.Version
-		indirect[r.Mod.Path] = r.Indirect
-	}
-
-	for _, r := range f.Require {
-		if v, ok := need[r.Mod.Path]; ok {
-			r.Mod.Version = v
-			r.Indirect = indirect[r.Mod.Path]
-		} else {
-			*r = Require{}
+		if prev, dup := need[r.Mod.Path]; dup && prev.version != r.Mod.Version {
+			panic(fmt.Errorf("SetRequire called with conflicting versions for path %s (%s and %s)", r.Mod.Path, prev.version, r.Mod.Version))
 		}
+		need[r.Mod.Path] = elem{r.Mod.Version, r.Indirect}
 	}
 
-	var newStmts []Expr
+	// Update or delete the existing Require entries to preserve
+	// only the first for each module path in req.
+	for _, r := range f.Require {
+		e, ok := need[r.Mod.Path]
+		if ok {
+			r.setVersion(e.version)
+			r.setIndirect(e.indirect)
+		} else {
+			r.markRemoved()
+		}
+		delete(need, r.Mod.Path)
+	}
+
+	// Add new entries in the last block of the file for any paths that weren't
+	// already present.
+	//
+	// This step is nondeterministic, but the final result will be deterministic
+	// because we will sort the block.
+	for path, e := range need {
+		f.AddNewRequire(path, e.version, e.indirect)
+	}
+
+	f.SortBlocks()
+}
+
+// SetRequireSeparateIndirect updates the requirements of f to contain the given
+// requirements. Comment contents (except for 'indirect' markings) are retained
+// from the first existing requirement for each module path, and block structure
+// is maintained as long as the indirect markings match.
+//
+// Any requirements on paths not already present in the file are added. Direct
+// requirements are added to the last block containing *any* other direct
+// requirement. Indirect requirements are added to the last block containing
+// *only* other indirect requirements. If no suitable block exists, a new one is
+// added, with the last block containing a direct dependency (if any)
+// immediately before the first block containing only indirect dependencies.
+//
+// The Syntax field is ignored for requirements in the given blocks.
+func (f *File) SetRequireSeparateIndirect(req []*Require) {
+	type modKey struct {
+		path     string
+		indirect bool
+	}
+	need := make(map[modKey]string)
+	for _, r := range req {
+		need[modKey{r.Mod.Path, r.Indirect}] = r.Mod.Version
+	}
+
+	comments := make(map[string]Comments)
+	for _, r := range f.Require {
+		v, ok := need[modKey{r.Mod.Path, r.Indirect}]
+		if !ok {
+			if _, ok := need[modKey{r.Mod.Path, !r.Indirect}]; ok {
+				if _, dup := comments[r.Mod.Path]; !dup {
+					comments[r.Mod.Path] = r.Syntax.Comments
+				}
+			}
+			r.markRemoved()
+			continue
+		}
+		r.setVersion(v)
+		delete(need, modKey{r.Mod.Path, r.Indirect})
+	}
+
+	var (
+		lastDirectOrMixedBlock Expr
+		firstIndirectOnlyBlock Expr
+		lastIndirectOnlyBlock  Expr
+	)
 	for _, stmt := range f.Syntax.Stmt {
 		switch stmt := stmt.(type) {
-		case *LineBlock:
-			if len(stmt.Token) > 0 && stmt.Token[0] == "require" {
-				var newLines []*Line
-				for _, line := range stmt.Line {
-					if p, err := parseString(&line.Token[0]); err == nil && need[p] != "" {
-						if len(line.Comments.Before) == 1 && len(line.Comments.Before[0].Token) == 0 {
-							line.Comments.Before = line.Comments.Before[:0]
-						}
-						line.Token[1] = need[p]
-						delete(need, p)
-						setIndirect(line, indirect[p])
-						newLines = append(newLines, line)
-					}
-				}
-				if len(newLines) == 0 {
-					continue // drop stmt
-				}
-				stmt.Line = newLines
-			}
-
 		case *Line:
-			if len(stmt.Token) > 0 && stmt.Token[0] == "require" {
-				if p, err := parseString(&stmt.Token[1]); err == nil && need[p] != "" {
-					stmt.Token[2] = need[p]
-					delete(need, p)
-					setIndirect(stmt, indirect[p])
-				} else {
-					continue // drop stmt
+			if len(stmt.Token) == 0 || stmt.Token[0] != "require" {
+				continue
+			}
+			if isIndirect(stmt) {
+				lastIndirectOnlyBlock = stmt
+			} else {
+				lastDirectOrMixedBlock = stmt
+			}
+		case *LineBlock:
+			if len(stmt.Token) == 0 || stmt.Token[0] != "require" {
+				continue
+			}
+			indirectOnly := true
+			for _, line := range stmt.Line {
+				if len(line.Token) == 0 {
+					continue
+				}
+				if !isIndirect(line) {
+					indirectOnly = false
+					break
+				}
+			}
+			if indirectOnly {
+				lastIndirectOnlyBlock = stmt
+				if firstIndirectOnlyBlock == nil {
+					firstIndirectOnlyBlock = stmt
+				}
+			} else {
+				lastDirectOrMixedBlock = stmt
+			}
+		}
+	}
+
+	isOrContainsStmt := func(stmt Expr, target Expr) bool {
+		if stmt == target {
+			return true
+		}
+		if stmt, ok := stmt.(*LineBlock); ok {
+			if target, ok := target.(*Line); ok {
+				for _, line := range stmt.Line {
+					if line == target {
+						return true
+					}
 				}
 			}
 		}
-		newStmts = append(newStmts, stmt)
+		return false
 	}
-	f.Syntax.Stmt = newStmts
 
-	for path, vers := range need {
-		f.AddNewRequire(path, vers, indirect[path])
+	addRequire := func(path, vers string, indirect bool, comments Comments) {
+		var line *Line
+		if indirect {
+			if lastIndirectOnlyBlock != nil {
+				line = f.Syntax.addLine(lastIndirectOnlyBlock, "require", path, vers)
+			} else {
+				// Add a new require block after the last direct-only or mixed "require"
+				// block (if any).
+				//
+				// (f.Syntax.addLine would add the line to an existing "require" block if
+				// present, but here the existing "require" blocks are all direct-only, so
+				// we know we need to add a new block instead.)
+				line = &Line{Token: []string{"require", path, vers}}
+				lastIndirectOnlyBlock = line
+				firstIndirectOnlyBlock = line // only block implies first block
+				if lastDirectOrMixedBlock == nil {
+					f.Syntax.Stmt = append(f.Syntax.Stmt, line)
+				} else {
+					for i, stmt := range f.Syntax.Stmt {
+						if isOrContainsStmt(stmt, lastDirectOrMixedBlock) {
+							f.Syntax.Stmt = append(f.Syntax.Stmt, nil)     // increase size
+							copy(f.Syntax.Stmt[i+2:], f.Syntax.Stmt[i+1:]) // shuffle elements up
+							f.Syntax.Stmt[i+1] = line
+							break
+						}
+					}
+				}
+			}
+		} else {
+			if lastDirectOrMixedBlock != nil {
+				line = f.Syntax.addLine(lastDirectOrMixedBlock, "require", path, vers)
+			} else {
+				// Add a new require block before the first indirect block (if any).
+				//
+				// That way if the file initially contains only indirect lines,
+				// the direct lines still appear before it: we preserve existing
+				// structure, but only to the extent that that structure already
+				// reflects the direct/indirect split.
+				line = &Line{Token: []string{"require", path, vers}}
+				lastDirectOrMixedBlock = line
+				if firstIndirectOnlyBlock == nil {
+					f.Syntax.Stmt = append(f.Syntax.Stmt, line)
+				} else {
+					for i, stmt := range f.Syntax.Stmt {
+						if isOrContainsStmt(stmt, firstIndirectOnlyBlock) {
+							f.Syntax.Stmt = append(f.Syntax.Stmt, nil)   // increase size
+							copy(f.Syntax.Stmt[i+1:], f.Syntax.Stmt[i:]) // shuffle elements up
+							f.Syntax.Stmt[i] = line
+							break
+						}
+					}
+				}
+			}
+		}
+
+		line.Comments.Before = commentsAdd(line.Comments.Before, comments.Before)
+		line.Comments.Suffix = commentsAdd(line.Comments.Suffix, comments.Suffix)
+
+		r := &Require{
+			Mod:      module.Version{Path: path, Version: vers},
+			Indirect: indirect,
+			Syntax:   line,
+		}
+		r.setIndirect(indirect)
+		f.Require = append(f.Require, r)
+	}
+
+	for k, vers := range need {
+		addRequire(k.path, vers, k.indirect, comments[k.path])
 	}
 	f.SortBlocks()
 }
@@ -885,7 +1126,7 @@
 func (f *File) DropRequire(path string) error {
 	for _, r := range f.Require {
 		if r.Mod.Path == path {
-			f.Syntax.removeLine(r.Syntax)
+			r.Syntax.markRemoved()
 			*r = Require{}
 		}
 	}
@@ -916,7 +1157,7 @@
 func (f *File) DropExclude(path, vers string) error {
 	for _, x := range f.Exclude {
 		if x.Mod.Path == path && x.Mod.Version == vers {
-			f.Syntax.removeLine(x.Syntax)
+			x.Syntax.markRemoved()
 			*x = Exclude{}
 		}
 	}
@@ -947,7 +1188,7 @@
 				continue
 			}
 			// Already added; delete other replacements for same.
-			f.Syntax.removeLine(r.Syntax)
+			r.Syntax.markRemoved()
 			*r = Replace{}
 		}
 		if r.Old.Path == oldPath {
@@ -963,7 +1204,7 @@
 func (f *File) DropReplace(oldPath, oldVers string) error {
 	for _, r := range f.Replace {
 		if r.Old.Path == oldPath && r.Old.Version == oldVers {
-			f.Syntax.removeLine(r.Syntax)
+			r.Syntax.markRemoved()
 			*r = Replace{}
 		}
 	}
@@ -1004,7 +1245,7 @@
 func (f *File) DropRetract(vi VersionInterval) error {
 	for _, r := range f.Retract {
 		if r.VersionInterval == vi {
-			f.Syntax.removeLine(r.Syntax)
+			r.Syntax.markRemoved()
 			*r = Retract{}
 		}
 	}
diff --git a/src/cmd/vendor/golang.org/x/mod/module/module.go b/src/cmd/vendor/golang.org/x/mod/module/module.go
index 0e03014..ba97ac3 100644
--- a/src/cmd/vendor/golang.org/x/mod/module/module.go
+++ b/src/cmd/vendor/golang.org/x/mod/module/module.go
@@ -192,6 +192,21 @@
 
 func (e *InvalidVersionError) Unwrap() error { return e.Err }
 
+// An InvalidPathError indicates a module, import, or file path doesn't
+// satisfy all naming constraints. See CheckPath, CheckImportPath,
+// and CheckFilePath for specific restrictions.
+type InvalidPathError struct {
+	Kind string // "module", "import", or "file"
+	Path string
+	Err  error
+}
+
+func (e *InvalidPathError) Error() string {
+	return fmt.Sprintf("malformed %s path %q: %v", e.Kind, e.Path, e.Err)
+}
+
+func (e *InvalidPathError) Unwrap() error { return e.Err }
+
 // Check checks that a given module path, version pair is valid.
 // In addition to the path being a valid module path
 // and the version being a valid semantic version,
@@ -296,30 +311,36 @@
 // this second requirement is replaced by a requirement that the path
 // follow the gopkg.in server's conventions.
 // Third, no path element may begin with a dot.
-func CheckPath(path string) error {
+func CheckPath(path string) (err error) {
+	defer func() {
+		if err != nil {
+			err = &InvalidPathError{Kind: "module", Path: path, Err: err}
+		}
+	}()
+
 	if err := checkPath(path, modulePath); err != nil {
-		return fmt.Errorf("malformed module path %q: %v", path, err)
+		return err
 	}
 	i := strings.Index(path, "/")
 	if i < 0 {
 		i = len(path)
 	}
 	if i == 0 {
-		return fmt.Errorf("malformed module path %q: leading slash", path)
+		return fmt.Errorf("leading slash")
 	}
 	if !strings.Contains(path[:i], ".") {
-		return fmt.Errorf("malformed module path %q: missing dot in first path element", path)
+		return fmt.Errorf("missing dot in first path element")
 	}
 	if path[0] == '-' {
-		return fmt.Errorf("malformed module path %q: leading dash in first path element", path)
+		return fmt.Errorf("leading dash in first path element")
 	}
 	for _, r := range path[:i] {
 		if !firstPathOK(r) {
-			return fmt.Errorf("malformed module path %q: invalid char %q in first path element", path, r)
+			return fmt.Errorf("invalid char %q in first path element", r)
 		}
 	}
 	if _, _, ok := SplitPathVersion(path); !ok {
-		return fmt.Errorf("malformed module path %q: invalid version", path)
+		return fmt.Errorf("invalid version")
 	}
 	return nil
 }
@@ -343,7 +364,7 @@
 // subtleties of Unicode.
 func CheckImportPath(path string) error {
 	if err := checkPath(path, importPath); err != nil {
-		return fmt.Errorf("malformed import path %q: %v", path, err)
+		return &InvalidPathError{Kind: "import", Path: path, Err: err}
 	}
 	return nil
 }
@@ -358,12 +379,13 @@
 	filePath
 )
 
-// checkPath checks that a general path is valid.
-// It returns an error describing why but not mentioning path.
-// Because these checks apply to both module paths and import paths,
-// the caller is expected to add the "malformed ___ path %q: " prefix.
-// fileName indicates whether the final element of the path is a file name
-// (as opposed to a directory name).
+// checkPath checks that a general path is valid. kind indicates what
+// specific constraints should be applied.
+//
+// checkPath returns an error describing why the path is not valid.
+// Because these checks apply to module, import, and file paths,
+// and because other checks may be applied, the caller is expected to wrap
+// this error with InvalidPathError.
 func checkPath(path string, kind pathKind) error {
 	if !utf8.ValidString(path) {
 		return fmt.Errorf("invalid UTF-8")
@@ -371,7 +393,7 @@
 	if path == "" {
 		return fmt.Errorf("empty string")
 	}
-	if path[0] == '-' {
+	if path[0] == '-' && kind != filePath {
 		return fmt.Errorf("leading dash")
 	}
 	if strings.Contains(path, "//") {
@@ -477,7 +499,7 @@
 // subtleties of Unicode.
 func CheckFilePath(path string) error {
 	if err := checkPath(path, filePath); err != nil {
-		return fmt.Errorf("malformed file path %q: %v", path, err)
+		return &InvalidPathError{Kind: "file", Path: path, Err: err}
 	}
 	return nil
 }
diff --git a/src/cmd/vendor/golang.org/x/mod/module/pseudo.go b/src/cmd/vendor/golang.org/x/mod/module/pseudo.go
new file mode 100644
index 0000000..f04ad37
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/mod/module/pseudo.go
@@ -0,0 +1,250 @@
+// 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.
+
+// Pseudo-versions
+//
+// Code authors are expected to tag the revisions they want users to use,
+// including prereleases. However, not all authors tag versions at all,
+// and not all commits a user might want to try will have tags.
+// A pseudo-version is a version with a special form that allows us to
+// address an untagged commit and order that version with respect to
+// other versions we might encounter.
+//
+// A pseudo-version takes one of the general forms:
+//
+//	(1) vX.0.0-yyyymmddhhmmss-abcdef123456
+//	(2) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456
+//	(3) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible
+//	(4) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456
+//	(5) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible
+//
+// If there is no recently tagged version with the right major version vX,
+// then form (1) is used, creating a space of pseudo-versions at the bottom
+// of the vX version range, less than any tagged version, including the unlikely v0.0.0.
+//
+// If the most recent tagged version before the target commit is vX.Y.Z or vX.Y.Z+incompatible,
+// then the pseudo-version uses form (2) or (3), making it a prerelease for the next
+// possible semantic version after vX.Y.Z. The leading 0 segment in the prerelease string
+// ensures that the pseudo-version compares less than possible future explicit prereleases
+// like vX.Y.(Z+1)-rc1 or vX.Y.(Z+1)-1.
+//
+// If the most recent tagged version before the target commit is vX.Y.Z-pre or vX.Y.Z-pre+incompatible,
+// then the pseudo-version uses form (4) or (5), making it a slightly later prerelease.
+
+package module
+
+import (
+	"errors"
+	"fmt"
+	"strings"
+	"time"
+
+	"golang.org/x/mod/internal/lazyregexp"
+	"golang.org/x/mod/semver"
+)
+
+var pseudoVersionRE = lazyregexp.New(`^v[0-9]+\.(0\.0-|\d+\.\d+-([^+]*\.)?0\.)\d{14}-[A-Za-z0-9]+(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$`)
+
+const PseudoVersionTimestampFormat = "20060102150405"
+
+// PseudoVersion returns a pseudo-version for the given major version ("v1")
+// preexisting older tagged version ("" or "v1.2.3" or "v1.2.3-pre"), revision time,
+// and revision identifier (usually a 12-byte commit hash prefix).
+func PseudoVersion(major, older string, t time.Time, rev string) string {
+	if major == "" {
+		major = "v0"
+	}
+	segment := fmt.Sprintf("%s-%s", t.UTC().Format(PseudoVersionTimestampFormat), rev)
+	build := semver.Build(older)
+	older = semver.Canonical(older)
+	if older == "" {
+		return major + ".0.0-" + segment // form (1)
+	}
+	if semver.Prerelease(older) != "" {
+		return older + ".0." + segment + build // form (4), (5)
+	}
+
+	// Form (2), (3).
+	// Extract patch from vMAJOR.MINOR.PATCH
+	i := strings.LastIndex(older, ".") + 1
+	v, patch := older[:i], older[i:]
+
+	// Reassemble.
+	return v + incDecimal(patch) + "-0." + segment + build
+}
+
+// ZeroPseudoVersion returns a pseudo-version with a zero timestamp and
+// revision, which may be used as a placeholder.
+func ZeroPseudoVersion(major string) string {
+	return PseudoVersion(major, "", time.Time{}, "000000000000")
+}
+
+// incDecimal returns the decimal string incremented by 1.
+func incDecimal(decimal string) string {
+	// Scan right to left turning 9s to 0s until you find a digit to increment.
+	digits := []byte(decimal)
+	i := len(digits) - 1
+	for ; i >= 0 && digits[i] == '9'; i-- {
+		digits[i] = '0'
+	}
+	if i >= 0 {
+		digits[i]++
+	} else {
+		// digits is all zeros
+		digits[0] = '1'
+		digits = append(digits, '0')
+	}
+	return string(digits)
+}
+
+// decDecimal returns the decimal string decremented by 1, or the empty string
+// if the decimal is all zeroes.
+func decDecimal(decimal string) string {
+	// Scan right to left turning 0s to 9s until you find a digit to decrement.
+	digits := []byte(decimal)
+	i := len(digits) - 1
+	for ; i >= 0 && digits[i] == '0'; i-- {
+		digits[i] = '9'
+	}
+	if i < 0 {
+		// decimal is all zeros
+		return ""
+	}
+	if i == 0 && digits[i] == '1' && len(digits) > 1 {
+		digits = digits[1:]
+	} else {
+		digits[i]--
+	}
+	return string(digits)
+}
+
+// IsPseudoVersion reports whether v is a pseudo-version.
+func IsPseudoVersion(v string) bool {
+	return strings.Count(v, "-") >= 2 && semver.IsValid(v) && pseudoVersionRE.MatchString(v)
+}
+
+// IsZeroPseudoVersion returns whether v is a pseudo-version with a zero base,
+// timestamp, and revision, as returned by ZeroPseudoVersion.
+func IsZeroPseudoVersion(v string) bool {
+	return v == ZeroPseudoVersion(semver.Major(v))
+}
+
+// PseudoVersionTime returns the time stamp of the pseudo-version v.
+// It returns an error if v is not a pseudo-version or if the time stamp
+// embedded in the pseudo-version is not a valid time.
+func PseudoVersionTime(v string) (time.Time, error) {
+	_, timestamp, _, _, err := parsePseudoVersion(v)
+	if err != nil {
+		return time.Time{}, err
+	}
+	t, err := time.Parse("20060102150405", timestamp)
+	if err != nil {
+		return time.Time{}, &InvalidVersionError{
+			Version: v,
+			Pseudo:  true,
+			Err:     fmt.Errorf("malformed time %q", timestamp),
+		}
+	}
+	return t, nil
+}
+
+// PseudoVersionRev returns the revision identifier of the pseudo-version v.
+// It returns an error if v is not a pseudo-version.
+func PseudoVersionRev(v string) (rev string, err error) {
+	_, _, rev, _, err = parsePseudoVersion(v)
+	return
+}
+
+// PseudoVersionBase returns the canonical parent version, if any, upon which
+// the pseudo-version v is based.
+//
+// If v has no parent version (that is, if it is "vX.0.0-[…]"),
+// PseudoVersionBase returns the empty string and a nil error.
+func PseudoVersionBase(v string) (string, error) {
+	base, _, _, build, err := parsePseudoVersion(v)
+	if err != nil {
+		return "", err
+	}
+
+	switch pre := semver.Prerelease(base); pre {
+	case "":
+		// vX.0.0-yyyymmddhhmmss-abcdef123456 → ""
+		if build != "" {
+			// Pseudo-versions of the form vX.0.0-yyyymmddhhmmss-abcdef123456+incompatible
+			// are nonsensical: the "vX.0.0-" prefix implies that there is no parent tag,
+			// but the "+incompatible" suffix implies that the major version of
+			// the parent tag is not compatible with the module's import path.
+			//
+			// There are a few such entries in the index generated by proxy.golang.org,
+			// but we believe those entries were generated by the proxy itself.
+			return "", &InvalidVersionError{
+				Version: v,
+				Pseudo:  true,
+				Err:     fmt.Errorf("lacks base version, but has build metadata %q", build),
+			}
+		}
+		return "", nil
+
+	case "-0":
+		// vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z
+		// vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z+incompatible
+		base = strings.TrimSuffix(base, pre)
+		i := strings.LastIndexByte(base, '.')
+		if i < 0 {
+			panic("base from parsePseudoVersion missing patch number: " + base)
+		}
+		patch := decDecimal(base[i+1:])
+		if patch == "" {
+			// vX.0.0-0 is invalid, but has been observed in the wild in the index
+			// generated by requests to proxy.golang.org.
+			//
+			// NOTE(bcmills): I cannot find a historical bug that accounts for
+			// pseudo-versions of this form, nor have I seen such versions in any
+			// actual go.mod files. If we find actual examples of this form and a
+			// reasonable theory of how they came into existence, it seems fine to
+			// treat them as equivalent to vX.0.0 (especially since the invalid
+			// pseudo-versions have lower precedence than the real ones). For now, we
+			// reject them.
+			return "", &InvalidVersionError{
+				Version: v,
+				Pseudo:  true,
+				Err:     fmt.Errorf("version before %s would have negative patch number", base),
+			}
+		}
+		return base[:i+1] + patch + build, nil
+
+	default:
+		// vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z-pre
+		// vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z-pre+incompatible
+		if !strings.HasSuffix(base, ".0") {
+			panic(`base from parsePseudoVersion missing ".0" before date: ` + base)
+		}
+		return strings.TrimSuffix(base, ".0") + build, nil
+	}
+}
+
+var errPseudoSyntax = errors.New("syntax error")
+
+func parsePseudoVersion(v string) (base, timestamp, rev, build string, err error) {
+	if !IsPseudoVersion(v) {
+		return "", "", "", "", &InvalidVersionError{
+			Version: v,
+			Pseudo:  true,
+			Err:     errPseudoSyntax,
+		}
+	}
+	build = semver.Build(v)
+	v = strings.TrimSuffix(v, build)
+	j := strings.LastIndex(v, "-")
+	v, rev = v[:j], v[j+1:]
+	i := strings.LastIndex(v, "-")
+	if j := strings.LastIndex(v, "."); j > i {
+		base = v[:j] // "vX.Y.Z-pre.0" or "vX.Y.(Z+1)-0"
+		timestamp = v[j+1:]
+	} else {
+		base = v[:i] // "vX.0.0"
+		timestamp = v[i+1:]
+	}
+	return base, timestamp, rev, build, nil
+}
diff --git a/src/cmd/vendor/golang.org/x/mod/semver/semver.go b/src/cmd/vendor/golang.org/x/mod/semver/semver.go
index 4338f35..7be398f 100644
--- a/src/cmd/vendor/golang.org/x/mod/semver/semver.go
+++ b/src/cmd/vendor/golang.org/x/mod/semver/semver.go
@@ -22,6 +22,8 @@
 // as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
 package semver
 
+import "sort"
+
 // parsed returns the parsed form of a semantic version string.
 type parsed struct {
 	major      string
@@ -150,6 +152,24 @@
 	return w
 }
 
+// ByVersion implements sort.Interface for sorting semantic version strings.
+type ByVersion []string
+
+func (vs ByVersion) Len() int      { return len(vs) }
+func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] }
+func (vs ByVersion) Less(i, j int) bool {
+	cmp := Compare(vs[i], vs[j])
+	if cmp != 0 {
+		return cmp < 0
+	}
+	return vs[i] < vs[j]
+}
+
+// Sort sorts a list of semantic version strings using ByVersion.
+func Sort(list []string) {
+	sort.Sort(ByVersion(list))
+}
+
 func parse(v string) (p parsed, ok bool) {
 	if v == "" || v[0] != 'v' {
 		p.err = "missing v prefix"
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/asm.s b/src/cmd/vendor/golang.org/x/sys/plan9/asm.s
new file mode 100644
index 0000000..06449eb
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/asm.s
@@ -0,0 +1,8 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·use(SB),NOSPLIT,$0
+	RET
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/asm_plan9_386.s b/src/cmd/vendor/golang.org/x/sys/plan9/asm_plan9_386.s
new file mode 100644
index 0000000..bc5cab1
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/asm_plan9_386.s
@@ -0,0 +1,30 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+//
+// System call support for 386, Plan 9
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-32
+	JMP	syscall·Syscall(SB)
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-44
+	JMP	syscall·Syscall6(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+	JMP	syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
+	JMP	syscall·RawSyscall6(SB)
+
+TEXT ·seek(SB),NOSPLIT,$0-36
+	JMP	syscall·seek(SB)
+
+TEXT ·exit(SB),NOSPLIT,$4-4
+	JMP	syscall·exit(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s b/src/cmd/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s
new file mode 100644
index 0000000..d3448e6
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s
@@ -0,0 +1,30 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+//
+// System call support for amd64, Plan 9
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-64
+	JMP	syscall·Syscall(SB)
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-88
+	JMP	syscall·Syscall6(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+	JMP	syscall·RawSyscall(SB)
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
+	JMP	syscall·RawSyscall6(SB)
+
+TEXT ·seek(SB),NOSPLIT,$0-56
+	JMP	syscall·seek(SB)
+
+TEXT ·exit(SB),NOSPLIT,$8-8
+	JMP	syscall·exit(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/asm_plan9_arm.s b/src/cmd/vendor/golang.org/x/sys/plan9/asm_plan9_arm.s
new file mode 100644
index 0000000..afb7c0a
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/asm_plan9_arm.s
@@ -0,0 +1,25 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// System call support for plan9 on arm
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-32
+	JMP	syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-44
+	JMP	syscall·Syscall6(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+	JMP	syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
+	JMP	syscall·RawSyscall6(SB)
+
+TEXT ·seek(SB),NOSPLIT,$0-36
+	JMP	syscall·exit(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/const_plan9.go b/src/cmd/vendor/golang.org/x/sys/plan9/const_plan9.go
new file mode 100644
index 0000000..b4e85a3
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/const_plan9.go
@@ -0,0 +1,70 @@
+package plan9
+
+// Plan 9 Constants
+
+// Open modes
+const (
+	O_RDONLY  = 0
+	O_WRONLY  = 1
+	O_RDWR    = 2
+	O_TRUNC   = 16
+	O_CLOEXEC = 32
+	O_EXCL    = 0x1000
+)
+
+// Rfork flags
+const (
+	RFNAMEG  = 1 << 0
+	RFENVG   = 1 << 1
+	RFFDG    = 1 << 2
+	RFNOTEG  = 1 << 3
+	RFPROC   = 1 << 4
+	RFMEM    = 1 << 5
+	RFNOWAIT = 1 << 6
+	RFCNAMEG = 1 << 10
+	RFCENVG  = 1 << 11
+	RFCFDG   = 1 << 12
+	RFREND   = 1 << 13
+	RFNOMNT  = 1 << 14
+)
+
+// Qid.Type bits
+const (
+	QTDIR    = 0x80
+	QTAPPEND = 0x40
+	QTEXCL   = 0x20
+	QTMOUNT  = 0x10
+	QTAUTH   = 0x08
+	QTTMP    = 0x04
+	QTFILE   = 0x00
+)
+
+// Dir.Mode bits
+const (
+	DMDIR    = 0x80000000
+	DMAPPEND = 0x40000000
+	DMEXCL   = 0x20000000
+	DMMOUNT  = 0x10000000
+	DMAUTH   = 0x08000000
+	DMTMP    = 0x04000000
+	DMREAD   = 0x4
+	DMWRITE  = 0x2
+	DMEXEC   = 0x1
+)
+
+const (
+	STATMAX    = 65535
+	ERRMAX     = 128
+	STATFIXLEN = 49
+)
+
+// Mount and bind flags
+const (
+	MREPL   = 0x0000
+	MBEFORE = 0x0001
+	MAFTER  = 0x0002
+	MORDER  = 0x0003
+	MCREATE = 0x0004
+	MCACHE  = 0x0010
+	MMASK   = 0x0017
+)
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/dir_plan9.go b/src/cmd/vendor/golang.org/x/sys/plan9/dir_plan9.go
new file mode 100644
index 0000000..0955e0c
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/dir_plan9.go
@@ -0,0 +1,212 @@
+// 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.
+
+// Plan 9 directory marshalling. See intro(5).
+
+package plan9
+
+import "errors"
+
+var (
+	ErrShortStat = errors.New("stat buffer too short")
+	ErrBadStat   = errors.New("malformed stat buffer")
+	ErrBadName   = errors.New("bad character in file name")
+)
+
+// A Qid represents a 9P server's unique identification for a file.
+type Qid struct {
+	Path uint64 // the file server's unique identification for the file
+	Vers uint32 // version number for given Path
+	Type uint8  // the type of the file (plan9.QTDIR for example)
+}
+
+// A Dir contains the metadata for a file.
+type Dir struct {
+	// system-modified data
+	Type uint16 // server type
+	Dev  uint32 // server subtype
+
+	// file data
+	Qid    Qid    // unique id from server
+	Mode   uint32 // permissions
+	Atime  uint32 // last read time
+	Mtime  uint32 // last write time
+	Length int64  // file length
+	Name   string // last element of path
+	Uid    string // owner name
+	Gid    string // group name
+	Muid   string // last modifier name
+}
+
+var nullDir = Dir{
+	Type: ^uint16(0),
+	Dev:  ^uint32(0),
+	Qid: Qid{
+		Path: ^uint64(0),
+		Vers: ^uint32(0),
+		Type: ^uint8(0),
+	},
+	Mode:   ^uint32(0),
+	Atime:  ^uint32(0),
+	Mtime:  ^uint32(0),
+	Length: ^int64(0),
+}
+
+// Null assigns special "don't touch" values to members of d to
+// avoid modifying them during plan9.Wstat.
+func (d *Dir) Null() { *d = nullDir }
+
+// Marshal encodes a 9P stat message corresponding to d into b
+//
+// If there isn't enough space in b for a stat message, ErrShortStat is returned.
+func (d *Dir) Marshal(b []byte) (n int, err error) {
+	n = STATFIXLEN + len(d.Name) + len(d.Uid) + len(d.Gid) + len(d.Muid)
+	if n > len(b) {
+		return n, ErrShortStat
+	}
+
+	for _, c := range d.Name {
+		if c == '/' {
+			return n, ErrBadName
+		}
+	}
+
+	b = pbit16(b, uint16(n)-2)
+	b = pbit16(b, d.Type)
+	b = pbit32(b, d.Dev)
+	b = pbit8(b, d.Qid.Type)
+	b = pbit32(b, d.Qid.Vers)
+	b = pbit64(b, d.Qid.Path)
+	b = pbit32(b, d.Mode)
+	b = pbit32(b, d.Atime)
+	b = pbit32(b, d.Mtime)
+	b = pbit64(b, uint64(d.Length))
+	b = pstring(b, d.Name)
+	b = pstring(b, d.Uid)
+	b = pstring(b, d.Gid)
+	b = pstring(b, d.Muid)
+
+	return n, nil
+}
+
+// UnmarshalDir decodes a single 9P stat message from b and returns the resulting Dir.
+//
+// If b is too small to hold a valid stat message, ErrShortStat is returned.
+//
+// If the stat message itself is invalid, ErrBadStat is returned.
+func UnmarshalDir(b []byte) (*Dir, error) {
+	if len(b) < STATFIXLEN {
+		return nil, ErrShortStat
+	}
+	size, buf := gbit16(b)
+	if len(b) != int(size)+2 {
+		return nil, ErrBadStat
+	}
+	b = buf
+
+	var d Dir
+	d.Type, b = gbit16(b)
+	d.Dev, b = gbit32(b)
+	d.Qid.Type, b = gbit8(b)
+	d.Qid.Vers, b = gbit32(b)
+	d.Qid.Path, b = gbit64(b)
+	d.Mode, b = gbit32(b)
+	d.Atime, b = gbit32(b)
+	d.Mtime, b = gbit32(b)
+
+	n, b := gbit64(b)
+	d.Length = int64(n)
+
+	var ok bool
+	if d.Name, b, ok = gstring(b); !ok {
+		return nil, ErrBadStat
+	}
+	if d.Uid, b, ok = gstring(b); !ok {
+		return nil, ErrBadStat
+	}
+	if d.Gid, b, ok = gstring(b); !ok {
+		return nil, ErrBadStat
+	}
+	if d.Muid, b, ok = gstring(b); !ok {
+		return nil, ErrBadStat
+	}
+
+	return &d, nil
+}
+
+// pbit8 copies the 8-bit number v to b and returns the remaining slice of b.
+func pbit8(b []byte, v uint8) []byte {
+	b[0] = byte(v)
+	return b[1:]
+}
+
+// pbit16 copies the 16-bit number v to b in little-endian order and returns the remaining slice of b.
+func pbit16(b []byte, v uint16) []byte {
+	b[0] = byte(v)
+	b[1] = byte(v >> 8)
+	return b[2:]
+}
+
+// pbit32 copies the 32-bit number v to b in little-endian order and returns the remaining slice of b.
+func pbit32(b []byte, v uint32) []byte {
+	b[0] = byte(v)
+	b[1] = byte(v >> 8)
+	b[2] = byte(v >> 16)
+	b[3] = byte(v >> 24)
+	return b[4:]
+}
+
+// pbit64 copies the 64-bit number v to b in little-endian order and returns the remaining slice of b.
+func pbit64(b []byte, v uint64) []byte {
+	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)
+	return b[8:]
+}
+
+// pstring copies the string s to b, prepending it with a 16-bit length in little-endian order, and
+// returning the remaining slice of b..
+func pstring(b []byte, s string) []byte {
+	b = pbit16(b, uint16(len(s)))
+	n := copy(b, s)
+	return b[n:]
+}
+
+// gbit8 reads an 8-bit number from b and returns it with the remaining slice of b.
+func gbit8(b []byte) (uint8, []byte) {
+	return uint8(b[0]), b[1:]
+}
+
+// gbit16 reads a 16-bit number in little-endian order from b and returns it with the remaining slice of b.
+func gbit16(b []byte) (uint16, []byte) {
+	return uint16(b[0]) | uint16(b[1])<<8, b[2:]
+}
+
+// gbit32 reads a 32-bit number in little-endian order from b and returns it with the remaining slice of b.
+func gbit32(b []byte) (uint32, []byte) {
+	return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24, b[4:]
+}
+
+// gbit64 reads a 64-bit number in little-endian order from b and returns it with the remaining slice of b.
+func gbit64(b []byte) (uint64, []byte) {
+	lo := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+	hi := uint32(b[4]) | uint32(b[5])<<8 | uint32(b[6])<<16 | uint32(b[7])<<24
+	return uint64(lo) | uint64(hi)<<32, b[8:]
+}
+
+// gstring reads a string from b, prefixed with a 16-bit length in little-endian order.
+// It returns the string with the remaining slice of b and a boolean. If the length is
+// greater than the number of bytes in b, the boolean will be false.
+func gstring(b []byte) (string, []byte, bool) {
+	n, b := gbit16(b)
+	if int(n) > len(b) {
+		return "", b, false
+	}
+	return string(b[:n]), b[n:], true
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/env_plan9.go b/src/cmd/vendor/golang.org/x/sys/plan9/env_plan9.go
new file mode 100644
index 0000000..8f19180
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/env_plan9.go
@@ -0,0 +1,31 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Plan 9 environment variables.
+
+package plan9
+
+import (
+	"syscall"
+)
+
+func Getenv(key string) (value string, found bool) {
+	return syscall.Getenv(key)
+}
+
+func Setenv(key, value string) error {
+	return syscall.Setenv(key, value)
+}
+
+func Clearenv() {
+	syscall.Clearenv()
+}
+
+func Environ() []string {
+	return syscall.Environ()
+}
+
+func Unsetenv(key string) error {
+	return syscall.Unsetenv(key)
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/errors_plan9.go b/src/cmd/vendor/golang.org/x/sys/plan9/errors_plan9.go
new file mode 100644
index 0000000..65fe74d
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/errors_plan9.go
@@ -0,0 +1,50 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package plan9
+
+import "syscall"
+
+// Constants
+const (
+	// Invented values to support what package os expects.
+	O_CREAT    = 0x02000
+	O_APPEND   = 0x00400
+	O_NOCTTY   = 0x00000
+	O_NONBLOCK = 0x00000
+	O_SYNC     = 0x00000
+	O_ASYNC    = 0x00000
+
+	S_IFMT   = 0x1f000
+	S_IFIFO  = 0x1000
+	S_IFCHR  = 0x2000
+	S_IFDIR  = 0x4000
+	S_IFBLK  = 0x6000
+	S_IFREG  = 0x8000
+	S_IFLNK  = 0xa000
+	S_IFSOCK = 0xc000
+)
+
+// Errors
+var (
+	EINVAL       = syscall.NewError("bad arg in system call")
+	ENOTDIR      = syscall.NewError("not a directory")
+	EISDIR       = syscall.NewError("file is a directory")
+	ENOENT       = syscall.NewError("file does not exist")
+	EEXIST       = syscall.NewError("file already exists")
+	EMFILE       = syscall.NewError("no free file descriptors")
+	EIO          = syscall.NewError("i/o error")
+	ENAMETOOLONG = syscall.NewError("file name too long")
+	EINTR        = syscall.NewError("interrupted")
+	EPERM        = syscall.NewError("permission denied")
+	EBUSY        = syscall.NewError("no free devices")
+	ETIMEDOUT    = syscall.NewError("connection timed out")
+	EPLAN9       = syscall.NewError("not supported by plan 9")
+
+	// The following errors do not correspond to any
+	// Plan 9 system messages. Invented to support
+	// what package os and others expect.
+	EACCES       = syscall.NewError("access permission denied")
+	EAFNOSUPPORT = syscall.NewError("address family not supported by protocol")
+)
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/mkall.sh b/src/cmd/vendor/golang.org/x/sys/plan9/mkall.sh
new file mode 100644
index 0000000..1650fbc
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/mkall.sh
@@ -0,0 +1,150 @@
+#!/usr/bin/env bash
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# The plan9 package provides access to the raw system call
+# interface of the underlying operating system.  Porting Go to
+# a new architecture/operating system combination requires
+# some manual effort, though there are tools that automate
+# much of the process.  The auto-generated files have names
+# beginning with z.
+#
+# This script runs or (given -n) prints suggested commands to generate z files
+# for the current system.  Running those commands is not automatic.
+# This script is documentation more than anything else.
+#
+# * asm_${GOOS}_${GOARCH}.s
+#
+# This hand-written assembly file implements system call dispatch.
+# There are three entry points:
+#
+# 	func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+# 	func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
+# 	func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+#
+# The first and second are the standard ones; they differ only in
+# how many arguments can be passed to the kernel.
+# The third is for low-level use by the ForkExec wrapper;
+# unlike the first two, it does not call into the scheduler to
+# let it know that a system call is running.
+#
+# * syscall_${GOOS}.go
+#
+# This hand-written Go file implements system calls that need
+# special handling and lists "//sys" comments giving prototypes
+# for ones that can be auto-generated.  Mksyscall reads those
+# comments to generate the stubs.
+#
+# * syscall_${GOOS}_${GOARCH}.go
+#
+# Same as syscall_${GOOS}.go except that it contains code specific
+# to ${GOOS} on one particular architecture.
+#
+# * types_${GOOS}.c
+#
+# This hand-written C file includes standard C headers and then
+# creates typedef or enum names beginning with a dollar sign
+# (use of $ in variable names is a gcc extension).  The hardest
+# part about preparing this file is figuring out which headers to
+# include and which symbols need to be #defined to get the
+# actual data structures that pass through to the kernel system calls.
+# Some C libraries present alternate versions for binary compatibility
+# and translate them on the way in and out of system calls, but
+# there is almost always a #define that can get the real ones.
+# See types_darwin.c and types_linux.c for examples.
+#
+# * zerror_${GOOS}_${GOARCH}.go
+#
+# This machine-generated file defines the system's error numbers,
+# error strings, and signal numbers.  The generator is "mkerrors.sh".
+# Usually no arguments are needed, but mkerrors.sh will pass its
+# arguments on to godefs.
+#
+# * zsyscall_${GOOS}_${GOARCH}.go
+#
+# Generated by mksyscall.pl; see syscall_${GOOS}.go above.
+#
+# * zsysnum_${GOOS}_${GOARCH}.go
+#
+# Generated by mksysnum_${GOOS}.
+#
+# * ztypes_${GOOS}_${GOARCH}.go
+#
+# Generated by godefs; see types_${GOOS}.c above.
+
+GOOSARCH="${GOOS}_${GOARCH}"
+
+# defaults
+mksyscall="go run mksyscall.go"
+mkerrors="./mkerrors.sh"
+zerrors="zerrors_$GOOSARCH.go"
+mksysctl=""
+zsysctl="zsysctl_$GOOSARCH.go"
+mksysnum=
+mktypes=
+run="sh"
+
+case "$1" in
+-syscalls)
+	for i in zsyscall*go
+	do
+		sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
+		rm _$i
+	done
+	exit 0
+	;;
+-n)
+	run="cat"
+	shift
+esac
+
+case "$#" in
+0)
+	;;
+*)
+	echo 'usage: mkall.sh [-n]' 1>&2
+	exit 2
+esac
+
+case "$GOOSARCH" in
+_* | *_ | _)
+	echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
+	exit 1
+	;;
+plan9_386)
+	mkerrors=
+	mksyscall="go run mksyscall.go -l32 -plan9 -tags plan9,386"
+	mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
+	mktypes="XXX"
+	;;
+plan9_amd64)
+	mkerrors=
+	mksyscall="go run mksyscall.go -l32 -plan9 -tags plan9,amd64"
+	mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
+	mktypes="XXX"
+	;;
+plan9_arm)
+	mkerrors=
+	mksyscall="go run mksyscall.go -l32 -plan9 -tags plan9,arm"
+	mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
+	mktypes="XXX"
+	;;
+*)
+	echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
+	exit 1
+	;;
+esac
+
+(
+	if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
+	case "$GOOS" in
+	plan9)
+		syscall_goos="syscall_$GOOS.go"
+		if [ -n "$mksyscall" ]; then echo "$mksyscall $syscall_goos |gofmt >zsyscall_$GOOSARCH.go"; fi
+		;;
+	esac
+	if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
+	if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
+	if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go |gofmt >ztypes_$GOOSARCH.go"; fi
+) | $run
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/mkerrors.sh b/src/cmd/vendor/golang.org/x/sys/plan9/mkerrors.sh
new file mode 100644
index 0000000..85309c4
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/mkerrors.sh
@@ -0,0 +1,246 @@
+#!/usr/bin/env bash
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# Generate Go code listing errors and other #defined constant
+# values (ENAMETOOLONG etc.), by asking the preprocessor
+# about the definitions.
+
+unset LANG
+export LC_ALL=C
+export LC_CTYPE=C
+
+CC=${CC:-gcc}
+
+uname=$(uname)
+
+includes='
+#include <sys/types.h>
+#include <sys/file.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include <errno.h>
+#include <sys/signal.h>
+#include <signal.h>
+#include <sys/resource.h>
+'
+
+ccflags="$@"
+
+# Write go tool cgo -godefs input.
+(
+	echo package plan9
+	echo
+	echo '/*'
+	indirect="includes_$(uname)"
+	echo "${!indirect} $includes"
+	echo '*/'
+	echo 'import "C"'
+	echo
+	echo 'const ('
+
+	# The gcc command line prints all the #defines
+	# it encounters while processing the input
+	echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
+	awk '
+		$1 != "#define" || $2 ~ /\(/ || $3 == "" {next}
+
+		$2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next}  # 386 registers
+		$2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
+		$2 ~ /^(SCM_SRCRT)$/ {next}
+		$2 ~ /^(MAP_FAILED)$/ {next}
+
+		$2 !~ /^ETH_/ &&
+		$2 !~ /^EPROC_/ &&
+		$2 !~ /^EQUIV_/ &&
+		$2 !~ /^EXPR_/ &&
+		$2 ~ /^E[A-Z0-9_]+$/ ||
+		$2 ~ /^B[0-9_]+$/ ||
+		$2 ~ /^V[A-Z0-9]+$/ ||
+		$2 ~ /^CS[A-Z0-9]/ ||
+		$2 ~ /^I(SIG|CANON|CRNL|EXTEN|MAXBEL|STRIP|UTF8)$/ ||
+		$2 ~ /^IGN/ ||
+		$2 ~ /^IX(ON|ANY|OFF)$/ ||
+		$2 ~ /^IN(LCR|PCK)$/ ||
+		$2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
+		$2 ~ /^C(LOCAL|READ)$/ ||
+		$2 == "BRKINT" ||
+		$2 == "HUPCL" ||
+		$2 == "PENDIN" ||
+		$2 == "TOSTOP" ||
+		$2 ~ /^PAR/ ||
+		$2 ~ /^SIG[^_]/ ||
+		$2 ~ /^O[CNPFP][A-Z]+[^_][A-Z]+$/ ||
+		$2 ~ /^IN_/ ||
+		$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
+		$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
+		$2 == "ICMPV6_FILTER" ||
+		$2 == "SOMAXCONN" ||
+		$2 == "NAME_MAX" ||
+		$2 == "IFNAMSIZ" ||
+		$2 ~ /^CTL_(MAXNAME|NET|QUERY)$/ ||
+		$2 ~ /^SYSCTL_VERS/ ||
+		$2 ~ /^(MS|MNT)_/ ||
+		$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
+		$2 ~ /^(O|F|FD|NAME|S|PTRACE|PT)_/ ||
+		$2 ~ /^LINUX_REBOOT_CMD_/ ||
+		$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
+		$2 !~ "NLA_TYPE_MASK" &&
+		$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
+		$2 ~ /^SIOC/ ||
+		$2 ~ /^TIOC/ ||
+		$2 !~ "RTF_BITS" &&
+		$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
+		$2 ~ /^BIOC/ ||
+		$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
+		$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|NOFILE|STACK)|RLIM_INFINITY/ ||
+		$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
+		$2 ~ /^CLONE_[A-Z_]+/ ||
+		$2 !~ /^(BPF_TIMEVAL)$/ &&
+		$2 ~ /^(BPF|DLT)_/ ||
+		$2 !~ "WMESGLEN" &&
+		$2 ~ /^W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", $2, $2)}
+		$2 ~ /^__WCOREFLAG$/ {next}
+		$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
+
+		{next}
+	' | sort
+
+	echo ')'
+) >_const.go
+
+# Pull out the error names for later.
+errors=$(
+	echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
+	awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
+	sort
+)
+
+# Pull out the signal names for later.
+signals=$(
+	echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
+	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
+	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+	sort
+)
+
+# Again, writing regexps to a file.
+echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
+	awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
+	sort >_error.grep
+echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
+	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
+	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+	sort >_signal.grep
+
+echo '// mkerrors.sh' "$@"
+echo '// Code generated by the command above; DO NOT EDIT.'
+echo
+go tool cgo -godefs -- "$@" _const.go >_error.out
+cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
+echo
+echo '// Errors'
+echo 'const ('
+cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= Errno(\1)/'
+echo ')'
+
+echo
+echo '// Signals'
+echo 'const ('
+cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= Signal(\1)/'
+echo ')'
+
+# Run C program to print error and syscall strings.
+(
+	echo -E "
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <signal.h>
+
+#define nelem(x) (sizeof(x)/sizeof((x)[0]))
+
+enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
+
+int errors[] = {
+"
+	for i in $errors
+	do
+		echo -E '	'$i,
+	done
+
+	echo -E "
+};
+
+int signals[] = {
+"
+	for i in $signals
+	do
+		echo -E '	'$i,
+	done
+
+	# Use -E because on some systems bash builtin interprets \n itself.
+	echo -E '
+};
+
+static int
+intcmp(const void *a, const void *b)
+{
+	return *(int*)a - *(int*)b;
+}
+
+int
+main(void)
+{
+	int i, j, e;
+	char buf[1024], *p;
+
+	printf("\n\n// Error table\n");
+	printf("var errors = [...]string {\n");
+	qsort(errors, nelem(errors), sizeof errors[0], intcmp);
+	for(i=0; i<nelem(errors); i++) {
+		e = errors[i];
+		if(i > 0 && errors[i-1] == e)
+			continue;
+		strcpy(buf, strerror(e));
+		// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
+		if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
+			buf[0] += a - A;
+		printf("\t%d: \"%s\",\n", e, buf);
+	}
+	printf("}\n\n");
+	
+	printf("\n\n// Signal table\n");
+	printf("var signals = [...]string {\n");
+	qsort(signals, nelem(signals), sizeof signals[0], intcmp);
+	for(i=0; i<nelem(signals); i++) {
+		e = signals[i];
+		if(i > 0 && signals[i-1] == e)
+			continue;
+		strcpy(buf, strsignal(e));
+		// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
+		if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
+			buf[0] += a - A;
+		// cut trailing : number.
+		p = strrchr(buf, ":"[0]);
+		if(p)
+			*p = '\0';
+		printf("\t%d: \"%s\",\n", e, buf);
+	}
+	printf("}\n\n");
+
+	return 0;
+}
+
+'
+) >_errors.c
+
+$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/mksysnum_plan9.sh b/src/cmd/vendor/golang.org/x/sys/plan9/mksysnum_plan9.sh
new file mode 100644
index 0000000..3c3ab05
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/mksysnum_plan9.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+COMMAND="mksysnum_plan9.sh $@"
+
+cat <<EOF
+// $COMMAND
+// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+
+package plan9
+
+const(
+EOF
+
+SP='[ 	]' # space or tab
+sed "s/^#define${SP}\\([A-Z0-9_][A-Z0-9_]*\\)${SP}${SP}*\\([0-9][0-9]*\\)/SYS_\\1=\\2/g" \
+	< $1 | grep -v SYS__
+
+cat <<EOF
+)
+EOF
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go b/src/cmd/vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go
new file mode 100644
index 0000000..87ae9d2
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go
@@ -0,0 +1,21 @@
+// 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 go1.5
+
+package plan9
+
+import "syscall"
+
+func fixwd() {
+	syscall.Fixwd()
+}
+
+func Getwd() (wd string, err error) {
+	return syscall.Getwd()
+}
+
+func Chdir(path string) error {
+	return syscall.Chdir(path)
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/pwd_plan9.go b/src/cmd/vendor/golang.org/x/sys/plan9/pwd_plan9.go
new file mode 100644
index 0000000..c07c798
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/pwd_plan9.go
@@ -0,0 +1,23 @@
+// 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 !go1.5
+
+package plan9
+
+func fixwd() {
+}
+
+func Getwd() (wd string, err error) {
+	fd, err := open(".", O_RDONLY)
+	if err != nil {
+		return "", err
+	}
+	defer Close(fd)
+	return Fd2path(fd)
+}
+
+func Chdir(path string) error {
+	return chdir(path)
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/race.go b/src/cmd/vendor/golang.org/x/sys/plan9/race.go
new file mode 100644
index 0000000..42edd93
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/race.go
@@ -0,0 +1,30 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build plan9,race
+
+package plan9
+
+import (
+	"runtime"
+	"unsafe"
+)
+
+const raceenabled = true
+
+func raceAcquire(addr unsafe.Pointer) {
+	runtime.RaceAcquire(addr)
+}
+
+func raceReleaseMerge(addr unsafe.Pointer) {
+	runtime.RaceReleaseMerge(addr)
+}
+
+func raceReadRange(addr unsafe.Pointer, len int) {
+	runtime.RaceReadRange(addr, len)
+}
+
+func raceWriteRange(addr unsafe.Pointer, len int) {
+	runtime.RaceWriteRange(addr, len)
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/race0.go b/src/cmd/vendor/golang.org/x/sys/plan9/race0.go
new file mode 100644
index 0000000..c89cf8f
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/race0.go
@@ -0,0 +1,25 @@
+// 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 plan9,!race
+
+package plan9
+
+import (
+	"unsafe"
+)
+
+const raceenabled = false
+
+func raceAcquire(addr unsafe.Pointer) {
+}
+
+func raceReleaseMerge(addr unsafe.Pointer) {
+}
+
+func raceReadRange(addr unsafe.Pointer, len int) {
+}
+
+func raceWriteRange(addr unsafe.Pointer, len int) {
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/str.go b/src/cmd/vendor/golang.org/x/sys/plan9/str.go
new file mode 100644
index 0000000..4f7f9ad
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/str.go
@@ -0,0 +1,22 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build plan9
+
+package plan9
+
+func itoa(val int) string { // do it here rather than with fmt to avoid dependency
+	if val < 0 {
+		return "-" + itoa(-val)
+	}
+	var buf [32]byte // big enough for int64
+	i := len(buf) - 1
+	for val >= 10 {
+		buf[i] = byte(val%10 + '0')
+		i--
+		val /= 10
+	}
+	buf[i] = byte(val + '0')
+	return string(buf[i:])
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/syscall.go b/src/cmd/vendor/golang.org/x/sys/plan9/syscall.go
new file mode 100644
index 0000000..e7363a2
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/syscall.go
@@ -0,0 +1,116 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build plan9
+
+// Package plan9 contains an interface to the low-level operating system
+// primitives. OS details vary depending on the underlying system, and
+// by default, godoc will display the OS-specific documentation for the current
+// system. If you want godoc to display documentation for another
+// system, set $GOOS and $GOARCH to the desired system. For example, if
+// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
+// to freebsd and $GOARCH to arm.
+//
+// The primary use of this package is inside other packages that provide a more
+// portable interface to the system, such as "os", "time" and "net".  Use
+// those packages rather than this one if you can.
+//
+// For details of the functions and data types in this package consult
+// the manuals for the appropriate operating system.
+//
+// These calls return err == nil to indicate success; otherwise
+// err represents an operating system error describing the failure and
+// holds a value of type syscall.ErrorString.
+package plan9 // import "golang.org/x/sys/plan9"
+
+import (
+	"bytes"
+	"strings"
+	"unsafe"
+
+	"golang.org/x/sys/internal/unsafeheader"
+)
+
+// ByteSliceFromString returns a NUL-terminated slice of bytes
+// containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, EINVAL).
+func ByteSliceFromString(s string) ([]byte, error) {
+	if strings.IndexByte(s, 0) != -1 {
+		return nil, EINVAL
+	}
+	a := make([]byte, len(s)+1)
+	copy(a, s)
+	return a, nil
+}
+
+// BytePtrFromString returns a pointer to a NUL-terminated array of
+// bytes containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, EINVAL).
+func BytePtrFromString(s string) (*byte, error) {
+	a, err := ByteSliceFromString(s)
+	if err != nil {
+		return nil, err
+	}
+	return &a[0], nil
+}
+
+// ByteSliceToString returns a string form of the text represented by the slice s, with a terminating NUL and any
+// bytes after the NUL removed.
+func ByteSliceToString(s []byte) string {
+	if i := bytes.IndexByte(s, 0); i != -1 {
+		s = s[:i]
+	}
+	return string(s)
+}
+
+// BytePtrToString takes a pointer to a sequence of text and returns the corresponding string.
+// If the pointer is nil, it returns the empty string. It assumes that the text sequence is terminated
+// at a zero byte; if the zero byte is not present, the program may crash.
+func BytePtrToString(p *byte) string {
+	if p == nil {
+		return ""
+	}
+	if *p == 0 {
+		return ""
+	}
+
+	// Find NUL terminator.
+	n := 0
+	for ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ {
+		ptr = unsafe.Pointer(uintptr(ptr) + 1)
+	}
+
+	var s []byte
+	h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
+	h.Data = unsafe.Pointer(p)
+	h.Len = n
+	h.Cap = n
+
+	return string(s)
+}
+
+// Single-word zero for use when we need a valid pointer to 0 bytes.
+// See mksyscall.pl.
+var _zero uintptr
+
+func (ts *Timespec) Unix() (sec int64, nsec int64) {
+	return int64(ts.Sec), int64(ts.Nsec)
+}
+
+func (tv *Timeval) Unix() (sec int64, nsec int64) {
+	return int64(tv.Sec), int64(tv.Usec) * 1000
+}
+
+func (ts *Timespec) Nano() int64 {
+	return int64(ts.Sec)*1e9 + int64(ts.Nsec)
+}
+
+func (tv *Timeval) Nano() int64 {
+	return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
+}
+
+// use is a no-op, but the compiler cannot see that it is.
+// Calling use(p) ensures that p is kept live until that point.
+//go:noescape
+func use(p unsafe.Pointer)
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/syscall_plan9.go b/src/cmd/vendor/golang.org/x/sys/plan9/syscall_plan9.go
new file mode 100644
index 0000000..84e1471
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/syscall_plan9.go
@@ -0,0 +1,349 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Plan 9 system calls.
+// This file is compiled as ordinary Go code,
+// but it is also input to mksyscall,
+// which parses the //sys lines and generates system call stubs.
+// Note that sometimes we use a lowercase //sys name and
+// wrap it in our own nicer implementation.
+
+package plan9
+
+import (
+	"bytes"
+	"syscall"
+	"unsafe"
+)
+
+// A Note is a string describing a process note.
+// It implements the os.Signal interface.
+type Note string
+
+func (n Note) Signal() {}
+
+func (n Note) String() string {
+	return string(n)
+}
+
+var (
+	Stdin  = 0
+	Stdout = 1
+	Stderr = 2
+)
+
+// For testing: clients can set this flag to force
+// creation of IPv6 sockets to return EAFNOSUPPORT.
+var SocketDisableIPv6 bool
+
+func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.ErrorString)
+func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.ErrorString)
+func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
+func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
+
+func atoi(b []byte) (n uint) {
+	n = 0
+	for i := 0; i < len(b); i++ {
+		n = n*10 + uint(b[i]-'0')
+	}
+	return
+}
+
+func cstring(s []byte) string {
+	i := bytes.IndexByte(s, 0)
+	if i == -1 {
+		i = len(s)
+	}
+	return string(s[:i])
+}
+
+func errstr() string {
+	var buf [ERRMAX]byte
+
+	RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)
+
+	buf[len(buf)-1] = 0
+	return cstring(buf[:])
+}
+
+// Implemented in assembly to import from runtime.
+func exit(code int)
+
+func Exit(code int) { exit(code) }
+
+func readnum(path string) (uint, error) {
+	var b [12]byte
+
+	fd, e := Open(path, O_RDONLY)
+	if e != nil {
+		return 0, e
+	}
+	defer Close(fd)
+
+	n, e := Pread(fd, b[:], 0)
+
+	if e != nil {
+		return 0, e
+	}
+
+	m := 0
+	for ; m < n && b[m] == ' '; m++ {
+	}
+
+	return atoi(b[m : n-1]), nil
+}
+
+func Getpid() (pid int) {
+	n, _ := readnum("#c/pid")
+	return int(n)
+}
+
+func Getppid() (ppid int) {
+	n, _ := readnum("#c/ppid")
+	return int(n)
+}
+
+func Read(fd int, p []byte) (n int, err error) {
+	return Pread(fd, p, -1)
+}
+
+func Write(fd int, p []byte) (n int, err error) {
+	return Pwrite(fd, p, -1)
+}
+
+var ioSync int64
+
+//sys	fd2path(fd int, buf []byte) (err error)
+func Fd2path(fd int) (path string, err error) {
+	var buf [512]byte
+
+	e := fd2path(fd, buf[:])
+	if e != nil {
+		return "", e
+	}
+	return cstring(buf[:]), nil
+}
+
+//sys	pipe(p *[2]int32) (err error)
+func Pipe(p []int) (err error) {
+	if len(p) != 2 {
+		return syscall.ErrorString("bad arg in system call")
+	}
+	var pp [2]int32
+	err = pipe(&pp)
+	p[0] = int(pp[0])
+	p[1] = int(pp[1])
+	return
+}
+
+// Underlying system call writes to newoffset via pointer.
+// Implemented in assembly to avoid allocation.
+func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	newoffset, e := seek(0, fd, offset, whence)
+
+	if newoffset == -1 {
+		err = syscall.ErrorString(e)
+	}
+	return
+}
+
+func Mkdir(path string, mode uint32) (err error) {
+	fd, err := Create(path, O_RDONLY, DMDIR|mode)
+
+	if fd != -1 {
+		Close(fd)
+	}
+
+	return
+}
+
+type Waitmsg struct {
+	Pid  int
+	Time [3]uint32
+	Msg  string
+}
+
+func (w Waitmsg) Exited() bool   { return true }
+func (w Waitmsg) Signaled() bool { return false }
+
+func (w Waitmsg) ExitStatus() int {
+	if len(w.Msg) == 0 {
+		// a normal exit returns no message
+		return 0
+	}
+	return 1
+}
+
+//sys	await(s []byte) (n int, err error)
+func Await(w *Waitmsg) (err error) {
+	var buf [512]byte
+	var f [5][]byte
+
+	n, err := await(buf[:])
+
+	if err != nil || w == nil {
+		return
+	}
+
+	nf := 0
+	p := 0
+	for i := 0; i < n && nf < len(f)-1; i++ {
+		if buf[i] == ' ' {
+			f[nf] = buf[p:i]
+			p = i + 1
+			nf++
+		}
+	}
+	f[nf] = buf[p:]
+	nf++
+
+	if nf != len(f) {
+		return syscall.ErrorString("invalid wait message")
+	}
+	w.Pid = int(atoi(f[0]))
+	w.Time[0] = uint32(atoi(f[1]))
+	w.Time[1] = uint32(atoi(f[2]))
+	w.Time[2] = uint32(atoi(f[3]))
+	w.Msg = cstring(f[4])
+	if w.Msg == "''" {
+		// await() returns '' for no error
+		w.Msg = ""
+	}
+	return
+}
+
+func Unmount(name, old string) (err error) {
+	fixwd()
+	oldp, err := BytePtrFromString(old)
+	if err != nil {
+		return err
+	}
+	oldptr := uintptr(unsafe.Pointer(oldp))
+
+	var r0 uintptr
+	var e syscall.ErrorString
+
+	// bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted.
+	if name == "" {
+		r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0)
+	} else {
+		namep, err := BytePtrFromString(name)
+		if err != nil {
+			return err
+		}
+		r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0)
+	}
+
+	if int32(r0) == -1 {
+		err = e
+	}
+	return
+}
+
+func Fchdir(fd int) (err error) {
+	path, err := Fd2path(fd)
+
+	if err != nil {
+		return
+	}
+
+	return Chdir(path)
+}
+
+type Timespec struct {
+	Sec  int32
+	Nsec int32
+}
+
+type Timeval struct {
+	Sec  int32
+	Usec int32
+}
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+	nsec += 999 // round up to microsecond
+	tv.Usec = int32(nsec % 1e9 / 1e3)
+	tv.Sec = int32(nsec / 1e9)
+	return
+}
+
+func nsec() int64 {
+	var scratch int64
+
+	r0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0)
+	// TODO(aram): remove hack after I fix _nsec in the pc64 kernel.
+	if r0 == 0 {
+		return scratch
+	}
+	return int64(r0)
+}
+
+func Gettimeofday(tv *Timeval) error {
+	nsec := nsec()
+	*tv = NsecToTimeval(nsec)
+	return nil
+}
+
+func Getpagesize() int { return 0x1000 }
+
+func Getegid() (egid int) { return -1 }
+func Geteuid() (euid int) { return -1 }
+func Getgid() (gid int)   { return -1 }
+func Getuid() (uid int)   { return -1 }
+
+func Getgroups() (gids []int, err error) {
+	return make([]int, 0), nil
+}
+
+//sys	open(path string, mode int) (fd int, err error)
+func Open(path string, mode int) (fd int, err error) {
+	fixwd()
+	return open(path, mode)
+}
+
+//sys	create(path string, mode int, perm uint32) (fd int, err error)
+func Create(path string, mode int, perm uint32) (fd int, err error) {
+	fixwd()
+	return create(path, mode, perm)
+}
+
+//sys	remove(path string) (err error)
+func Remove(path string) error {
+	fixwd()
+	return remove(path)
+}
+
+//sys	stat(path string, edir []byte) (n int, err error)
+func Stat(path string, edir []byte) (n int, err error) {
+	fixwd()
+	return stat(path, edir)
+}
+
+//sys	bind(name string, old string, flag int) (err error)
+func Bind(name string, old string, flag int) (err error) {
+	fixwd()
+	return bind(name, old, flag)
+}
+
+//sys	mount(fd int, afd int, old string, flag int, aname string) (err error)
+func Mount(fd int, afd int, old string, flag int, aname string) (err error) {
+	fixwd()
+	return mount(fd, afd, old, flag, aname)
+}
+
+//sys	wstat(path string, edir []byte) (err error)
+func Wstat(path string, edir []byte) (err error) {
+	fixwd()
+	return wstat(path, edir)
+}
+
+//sys	chdir(path string) (err error)
+//sys	Dup(oldfd int, newfd int) (fd int, err error)
+//sys	Pread(fd int, p []byte, offset int64) (n int, err error)
+//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
+//sys	Close(fd int) (err error)
+//sys	Fstat(fd int, edir []byte) (n int, err error)
+//sys	Fwstat(fd int, edir []byte) (err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go b/src/cmd/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go
new file mode 100644
index 0000000..6819bc2
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go
@@ -0,0 +1,284 @@
+// go run mksyscall.go -l32 -plan9 -tags plan9,386 syscall_plan9.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build plan9,386
+
+package plan9
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fd2path(fd int, buf []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]int32) (err error) {
+	r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func await(s []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(s) > 0 {
+		_p0 = unsafe.Pointer(&s[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func create(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func remove(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func stat(path string, edir []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(edir) > 0 {
+		_p1 = unsafe.Pointer(&edir[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(name string, old string, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(old)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(fd int, afd int, old string, flag int, aname string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(old)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(aname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wstat(path string, edir []byte) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(edir) > 0 {
+		_p1 = unsafe.Pointer(&edir[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int, newfd int) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, edir []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(edir) > 0 {
+		_p0 = unsafe.Pointer(&edir[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fwstat(fd int, edir []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(edir) > 0 {
+		_p0 = unsafe.Pointer(&edir[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go b/src/cmd/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go
new file mode 100644
index 0000000..418abbb
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go
@@ -0,0 +1,284 @@
+// go run mksyscall.go -l32 -plan9 -tags plan9,amd64 syscall_plan9.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build plan9,amd64
+
+package plan9
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fd2path(fd int, buf []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]int32) (err error) {
+	r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func await(s []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(s) > 0 {
+		_p0 = unsafe.Pointer(&s[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func create(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func remove(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func stat(path string, edir []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(edir) > 0 {
+		_p1 = unsafe.Pointer(&edir[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(name string, old string, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(old)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(fd int, afd int, old string, flag int, aname string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(old)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(aname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wstat(path string, edir []byte) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(edir) > 0 {
+		_p1 = unsafe.Pointer(&edir[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int, newfd int) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, edir []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(edir) > 0 {
+		_p0 = unsafe.Pointer(&edir[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fwstat(fd int, edir []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(edir) > 0 {
+		_p0 = unsafe.Pointer(&edir[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm.go b/src/cmd/vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm.go
new file mode 100644
index 0000000..3e8a1a5
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm.go
@@ -0,0 +1,284 @@
+// go run mksyscall.go -l32 -plan9 -tags plan9,arm syscall_plan9.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build plan9,arm
+
+package plan9
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fd2path(fd int, buf []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]int32) (err error) {
+	r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func await(s []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(s) > 0 {
+		_p0 = unsafe.Pointer(&s[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func create(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func remove(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func stat(path string, edir []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(edir) > 0 {
+		_p1 = unsafe.Pointer(&edir[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(name string, old string, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(old)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(fd int, afd int, old string, flag int, aname string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(old)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(aname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wstat(path string, edir []byte) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(edir) > 0 {
+		_p1 = unsafe.Pointer(&edir[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int, newfd int) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, edir []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(edir) > 0 {
+		_p0 = unsafe.Pointer(&edir[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fwstat(fd int, edir []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(edir) > 0 {
+		_p0 = unsafe.Pointer(&edir[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go b/src/cmd/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go
new file mode 100644
index 0000000..22e8abd
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go
@@ -0,0 +1,49 @@
+// mksysnum_plan9.sh /opt/plan9/sys/src/libc/9syscall/sys.h
+// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+
+package plan9
+
+const (
+	SYS_SYSR1       = 0
+	SYS_BIND        = 2
+	SYS_CHDIR       = 3
+	SYS_CLOSE       = 4
+	SYS_DUP         = 5
+	SYS_ALARM       = 6
+	SYS_EXEC        = 7
+	SYS_EXITS       = 8
+	SYS_FAUTH       = 10
+	SYS_SEGBRK      = 12
+	SYS_OPEN        = 14
+	SYS_OSEEK       = 16
+	SYS_SLEEP       = 17
+	SYS_RFORK       = 19
+	SYS_PIPE        = 21
+	SYS_CREATE      = 22
+	SYS_FD2PATH     = 23
+	SYS_BRK_        = 24
+	SYS_REMOVE      = 25
+	SYS_NOTIFY      = 28
+	SYS_NOTED       = 29
+	SYS_SEGATTACH   = 30
+	SYS_SEGDETACH   = 31
+	SYS_SEGFREE     = 32
+	SYS_SEGFLUSH    = 33
+	SYS_RENDEZVOUS  = 34
+	SYS_UNMOUNT     = 35
+	SYS_SEMACQUIRE  = 37
+	SYS_SEMRELEASE  = 38
+	SYS_SEEK        = 39
+	SYS_FVERSION    = 40
+	SYS_ERRSTR      = 41
+	SYS_STAT        = 42
+	SYS_FSTAT       = 43
+	SYS_WSTAT       = 44
+	SYS_FWSTAT      = 45
+	SYS_MOUNT       = 46
+	SYS_AWAIT       = 47
+	SYS_PREAD       = 50
+	SYS_PWRITE      = 51
+	SYS_TSEMACQUIRE = 52
+	SYS_NSEC        = 53
+)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/aliases.go b/src/cmd/vendor/golang.org/x/sys/unix/aliases.go
index 951fce4..abc89c1 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/aliases.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/aliases.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
 // +build go1.9
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
index 6b4027b..db9171c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 #include "textflag.h"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_386.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_386.s
new file mode 100644
index 0000000..7f29275
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_386.s
@@ -0,0 +1,29 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (darwin || freebsd || netbsd || openbsd) && gc
+// +build darwin freebsd netbsd openbsd
+// +build gc
+
+#include "textflag.h"
+
+// System call support for 386 BSD
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-28
+	JMP	syscall·Syscall(SB)
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-40
+	JMP	syscall·Syscall6(SB)
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-52
+	JMP	syscall·Syscall9(SB)
+
+TEXT	·RawSyscall(SB),NOSPLIT,$0-28
+	JMP	syscall·RawSyscall(SB)
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_amd64.s
new file mode 100644
index 0000000..2b99c34
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_amd64.s
@@ -0,0 +1,29 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && gc
+// +build darwin dragonfly freebsd netbsd openbsd
+// +build gc
+
+#include "textflag.h"
+
+// System call support for AMD64 BSD
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-56
+	JMP	syscall·Syscall(SB)
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-80
+	JMP	syscall·Syscall6(SB)
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-104
+	JMP	syscall·Syscall9(SB)
+
+TEXT	·RawSyscall(SB),NOSPLIT,$0-56
+	JMP	syscall·RawSyscall(SB)
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
+	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_arm.s
new file mode 100644
index 0000000..98ebfad
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_arm.s
@@ -0,0 +1,29 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (darwin || freebsd || netbsd || openbsd) && gc
+// +build darwin freebsd netbsd openbsd
+// +build gc
+
+#include "textflag.h"
+
+// System call support for ARM BSD
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-28
+	B	syscall·Syscall(SB)
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-40
+	B	syscall·Syscall6(SB)
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-52
+	B	syscall·Syscall9(SB)
+
+TEXT	·RawSyscall(SB),NOSPLIT,$0-28
+	B	syscall·RawSyscall(SB)
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	B	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_arm64.s
new file mode 100644
index 0000000..fe36a73
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_arm64.s
@@ -0,0 +1,29 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (darwin || freebsd || netbsd || openbsd) && gc
+// +build darwin freebsd netbsd openbsd
+// +build gc
+
+#include "textflag.h"
+
+// System call support for ARM64 BSD
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-56
+	JMP	syscall·Syscall(SB)
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-80
+	JMP	syscall·Syscall6(SB)
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-104
+	JMP	syscall·Syscall9(SB)
+
+TEXT	·RawSyscall(SB),NOSPLIT,$0-56
+	JMP	syscall·RawSyscall(SB)
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
+	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_386.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_386.s
deleted file mode 100644
index 8a06b87..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_386.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for 386, Darwin
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	JMP	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	JMP	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	JMP	syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
-	JMP	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
deleted file mode 100644
index f2397fd..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for AMD64, Darwin
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	JMP	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-104
-	JMP	syscall·Syscall9(SB)
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-56
-	JMP	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm.s
deleted file mode 100644
index c9e6b6f..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm.s
+++ /dev/null
@@ -1,30 +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.
-
-// +build gc
-// +build arm,darwin
-
-#include "textflag.h"
-
-//
-// System call support for ARM, Darwin
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	B	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	B	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	B	syscall·Syscall9(SB)
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-28
-	B	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	B	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
deleted file mode 100644
index 89843f8..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
+++ /dev/null
@@ -1,30 +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.
-
-// +build gc
-// +build arm64,darwin
-
-#include "textflag.h"
-
-//
-// System call support for AMD64, Darwin
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	B	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	B	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-104
-	B	syscall·Syscall9(SB)
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-56
-	B	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	B	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
deleted file mode 100644
index 27674e1..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for AMD64, DragonFly
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	JMP	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-104
-	JMP	syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
-	JMP	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_386.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_386.s
deleted file mode 100644
index 49f0ac2..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_386.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for 386, FreeBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	JMP	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	JMP	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	JMP	syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
-	JMP	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
deleted file mode 100644
index f2dfc57..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for AMD64, FreeBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	JMP	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-104
-	JMP	syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
-	JMP	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
deleted file mode 100644
index 6d740db..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for ARM, FreeBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	B	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	B	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	B	syscall·Syscall9(SB)
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-28
-	B	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	B	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s
deleted file mode 100644
index a8f5a29..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for ARM64, FreeBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	JMP	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-104
-	JMP	syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
-	JMP	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_386.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_386.s
index 0655ecb..8fd101d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_386.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_386.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 #include "textflag.h"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_amd64.s
index bc3fb6a..7ed38e4 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_amd64.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_amd64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 #include "textflag.h"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm.s
index 55b13c7..8ef1d51 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 #include "textflag.h"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm64.s
index 22a83d8..98ae027 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm64.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && arm64 && gc
 // +build linux
 // +build arm64
 // +build gc
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
index dc222b9..21231d2 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips64 || mips64le) && gc
 // +build linux
 // +build mips64 mips64le
 // +build gc
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
index d333f13..6783b26 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips || mipsle) && gc
 // +build linux
 // +build mips mipsle
 // +build gc
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
index 459a629..19d4989 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (ppc64 || ppc64le) && gc
 // +build linux
 // +build ppc64 ppc64le
 // +build gc
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
index 04d3849..e42eb81 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build riscv64,gc
+//go:build riscv64 && gc
+// +build riscv64
+// +build gc
 
 #include "textflag.h"
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_s390x.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_s390x.s
index cc30398..c46aab3 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_s390x.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_s390x.s
@@ -2,8 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build s390x
+//go:build linux && s390x && gc
 // +build linux
+// +build s390x
 // +build gc
 
 #include "textflag.h"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_386.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_386.s
deleted file mode 100644
index ae7b498..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_386.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for 386, NetBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	JMP	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	JMP	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	JMP	syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
-	JMP	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
deleted file mode 100644
index e57367c..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for AMD64, NetBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	JMP	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-104
-	JMP	syscall·Syscall9(SB)
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-56
-	JMP	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
deleted file mode 100644
index d7da175..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
+++ /dev/null
@@ -1,29 +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 gc
-
-#include "textflag.h"
-
-//
-// System call support for ARM, NetBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	B	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	B	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	B	syscall·Syscall9(SB)
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-28
-	B	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	B	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s
deleted file mode 100644
index e7cbe19..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for ARM64, NetBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	B	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	B	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-104
-	B	syscall·Syscall9(SB)
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-56
-	B	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	B	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_386.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_386.s
deleted file mode 100644
index 2f00b03..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_386.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for 386, OpenBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	JMP	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	JMP	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	JMP	syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
-	JMP	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
deleted file mode 100644
index 07632c9..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for AMD64, OpenBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	JMP	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-104
-	JMP	syscall·Syscall9(SB)
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-56
-	JMP	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s
deleted file mode 100644
index 73e9973..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s
+++ /dev/null
@@ -1,29 +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.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for ARM, OpenBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	B	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	B	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	B	syscall·Syscall9(SB)
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-28
-	B	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	B	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s
deleted file mode 100644
index c47302a..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build gc
-
-#include "textflag.h"
-
-//
-// System call support for arm64, OpenBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	JMP	syscall·Syscall(SB)
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·Syscall6(SB)
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-104
-	JMP	syscall·Syscall9(SB)
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-56
-	JMP	syscall·RawSyscall(SB)
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s
index 47c93fc..5e7a116 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 #include "textflag.h"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
index 1f2c755..f8c5394 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 #include "textflag.h"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_zos_s390x.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_zos_s390x.s
new file mode 100644
index 0000000..3b54e18
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_zos_s390x.s
@@ -0,0 +1,426 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x && gc
+// +build zos
+// +build s390x
+// +build gc
+
+#include "textflag.h"
+
+#define PSALAA            1208(R0)
+#define GTAB64(x)           80(x)
+#define LCA64(x)            88(x)
+#define CAA(x)               8(x)
+#define EDCHPXV(x)        1016(x)       // in the CAA
+#define SAVSTACK_ASYNC(x)  336(x)       // in the LCA
+
+// SS_*, where x=SAVSTACK_ASYNC
+#define SS_LE(x)             0(x)
+#define SS_GO(x)             8(x)
+#define SS_ERRNO(x)         16(x)
+#define SS_ERRNOJR(x)       20(x)
+
+#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6
+
+TEXT ·clearErrno(SB),NOSPLIT,$0-0
+	BL	addrerrno<>(SB)
+	MOVD	$0, 0(R3)
+	RET
+
+// Returns the address of errno in R3.
+TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
+	// Get library control area (LCA).
+	MOVW	PSALAA, R8
+	MOVD	LCA64(R8), R8
+
+	// Get __errno FuncDesc.
+	MOVD	CAA(R8), R9
+	MOVD	EDCHPXV(R9), R9
+	ADD	$(0x156*16), R9
+	LMG	0(R9), R5, R6
+
+	// Switch to saved LE stack.
+	MOVD	SAVSTACK_ASYNC(R8), R9
+	MOVD	0(R9), R4
+	MOVD	$0, 0(R9)
+
+	// Call __errno function.
+	LE_CALL
+	NOPH
+
+	// Switch back to Go stack.
+	XOR	R0, R0      // Restore R0 to $0.
+	MOVD	R4, 0(R9)   // Save stack pointer.
+	RET
+
+TEXT ·syscall_syscall(SB),NOSPLIT,$0-56
+	BL	runtime·entersyscall(SB)
+	MOVD	a1+8(FP), R1
+	MOVD	a2+16(FP), R2
+	MOVD	a3+24(FP), R3
+
+	// Get library control area (LCA).
+	MOVW	PSALAA, R8
+	MOVD	LCA64(R8), R8
+
+	// Get function.
+	MOVD	CAA(R8), R9
+	MOVD	EDCHPXV(R9), R9
+	MOVD	trap+0(FP), R5
+	SLD	$4, R5
+	ADD	R5, R9
+	LMG	0(R9), R5, R6
+
+	// Restore LE stack.
+	MOVD	SAVSTACK_ASYNC(R8), R9
+	MOVD	0(R9), R4
+	MOVD	$0, 0(R9)
+
+	// Call function.
+	LE_CALL
+	NOPH
+	XOR	R0, R0      // Restore R0 to $0.
+	MOVD	R4, 0(R9)   // Save stack pointer.
+
+	MOVD	R3, r1+32(FP)
+	MOVD	R0, r2+40(FP)
+	MOVD	R0, err+48(FP)
+	MOVW	R3, R4
+	CMP	R4, $-1
+	BNE	done
+	BL	addrerrno<>(SB)
+	MOVWZ	0(R3), R3
+	MOVD	R3, err+48(FP)
+done:
+	BL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56
+	MOVD	a1+8(FP), R1
+	MOVD	a2+16(FP), R2
+	MOVD	a3+24(FP), R3
+
+	// Get library control area (LCA).
+	MOVW	PSALAA, R8
+	MOVD	LCA64(R8), R8
+
+	// Get function.
+	MOVD	CAA(R8), R9
+	MOVD	EDCHPXV(R9), R9
+	MOVD	trap+0(FP), R5
+	SLD	$4, R5
+	ADD	R5, R9
+	LMG	0(R9), R5, R6
+
+	// Restore LE stack.
+	MOVD	SAVSTACK_ASYNC(R8), R9
+	MOVD	0(R9), R4
+	MOVD	$0, 0(R9)
+
+	// Call function.
+	LE_CALL
+	NOPH
+	XOR	R0, R0      // Restore R0 to $0.
+	MOVD	R4, 0(R9)   // Save stack pointer.
+
+	MOVD	R3, r1+32(FP)
+	MOVD	R0, r2+40(FP)
+	MOVD	R0, err+48(FP)
+	MOVW	R3, R4
+	CMP	R4, $-1
+	BNE	done
+	BL	addrerrno<>(SB)
+	MOVWZ	0(R3), R3
+	MOVD	R3, err+48(FP)
+done:
+	RET
+
+TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80
+	BL	runtime·entersyscall(SB)
+	MOVD	a1+8(FP), R1
+	MOVD	a2+16(FP), R2
+	MOVD	a3+24(FP), R3
+
+	// Get library control area (LCA).
+	MOVW	PSALAA, R8
+	MOVD	LCA64(R8), R8
+
+	// Get function.
+	MOVD	CAA(R8), R9
+	MOVD	EDCHPXV(R9), R9
+	MOVD	trap+0(FP), R5
+	SLD	$4, R5
+	ADD	R5, R9
+	LMG	0(R9), R5, R6
+
+	// Restore LE stack.
+	MOVD	SAVSTACK_ASYNC(R8), R9
+	MOVD	0(R9), R4
+	MOVD	$0, 0(R9)
+
+	// Fill in parameter list.
+	MOVD	a4+32(FP), R12
+	MOVD	R12, (2176+24)(R4)
+	MOVD	a5+40(FP), R12
+	MOVD	R12, (2176+32)(R4)
+	MOVD	a6+48(FP), R12
+	MOVD	R12, (2176+40)(R4)
+
+	// Call function.
+	LE_CALL
+	NOPH
+	XOR	R0, R0      // Restore R0 to $0.
+	MOVD	R4, 0(R9)   // Save stack pointer.
+
+	MOVD	R3, r1+56(FP)
+	MOVD	R0, r2+64(FP)
+	MOVD	R0, err+72(FP)
+	MOVW	R3, R4
+	CMP	R4, $-1
+	BNE	done
+	BL	addrerrno<>(SB)
+	MOVWZ	0(R3), R3
+	MOVD	R3, err+72(FP)
+done:
+	BL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80
+	MOVD	a1+8(FP), R1
+	MOVD	a2+16(FP), R2
+	MOVD	a3+24(FP), R3
+
+	// Get library control area (LCA).
+	MOVW	PSALAA, R8
+	MOVD	LCA64(R8), R8
+
+	// Get function.
+	MOVD	CAA(R8), R9
+	MOVD	EDCHPXV(R9), R9
+	MOVD	trap+0(FP), R5
+	SLD	$4, R5
+	ADD	R5, R9
+	LMG	0(R9), R5, R6
+
+	// Restore LE stack.
+	MOVD	SAVSTACK_ASYNC(R8), R9
+	MOVD	0(R9), R4
+	MOVD	$0, 0(R9)
+
+	// Fill in parameter list.
+	MOVD	a4+32(FP), R12
+	MOVD	R12, (2176+24)(R4)
+	MOVD	a5+40(FP), R12
+	MOVD	R12, (2176+32)(R4)
+	MOVD	a6+48(FP), R12
+	MOVD	R12, (2176+40)(R4)
+
+	// Call function.
+	LE_CALL
+	NOPH
+	XOR	R0, R0      // Restore R0 to $0.
+	MOVD	R4, 0(R9)   // Save stack pointer.
+
+	MOVD	R3, r1+56(FP)
+	MOVD	R0, r2+64(FP)
+	MOVD	R0, err+72(FP)
+	MOVW	R3, R4
+	CMP	R4, $-1
+	BNE	done
+	BL	·rrno<>(SB)
+	MOVWZ	0(R3), R3
+	MOVD	R3, err+72(FP)
+done:
+	RET
+
+TEXT ·syscall_syscall9(SB),NOSPLIT,$0
+	BL	runtime·entersyscall(SB)
+	MOVD	a1+8(FP), R1
+	MOVD	a2+16(FP), R2
+	MOVD	a3+24(FP), R3
+
+	// Get library control area (LCA).
+	MOVW	PSALAA, R8
+	MOVD	LCA64(R8), R8
+
+	// Get function.
+	MOVD	CAA(R8), R9
+	MOVD	EDCHPXV(R9), R9
+	MOVD	trap+0(FP), R5
+	SLD	$4, R5
+	ADD	R5, R9
+	LMG	0(R9), R5, R6
+
+	// Restore LE stack.
+	MOVD	SAVSTACK_ASYNC(R8), R9
+	MOVD	0(R9), R4
+	MOVD	$0, 0(R9)
+
+	// Fill in parameter list.
+	MOVD	a4+32(FP), R12
+	MOVD	R12, (2176+24)(R4)
+	MOVD	a5+40(FP), R12
+	MOVD	R12, (2176+32)(R4)
+	MOVD	a6+48(FP), R12
+	MOVD	R12, (2176+40)(R4)
+	MOVD	a7+56(FP), R12
+	MOVD	R12, (2176+48)(R4)
+	MOVD	a8+64(FP), R12
+	MOVD	R12, (2176+56)(R4)
+	MOVD	a9+72(FP), R12
+	MOVD	R12, (2176+64)(R4)
+
+	// Call function.
+	LE_CALL
+	NOPH
+	XOR	R0, R0      // Restore R0 to $0.
+	MOVD	R4, 0(R9)   // Save stack pointer.
+
+	MOVD	R3, r1+80(FP)
+	MOVD	R0, r2+88(FP)
+	MOVD	R0, err+96(FP)
+	MOVW	R3, R4
+	CMP	R4, $-1
+	BNE	done
+	BL	addrerrno<>(SB)
+	MOVWZ	0(R3), R3
+	MOVD	R3, err+96(FP)
+done:
+        BL	runtime·exitsyscall(SB)
+        RET
+
+TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0
+	MOVD	a1+8(FP), R1
+	MOVD	a2+16(FP), R2
+	MOVD	a3+24(FP), R3
+
+	// Get library control area (LCA).
+	MOVW	PSALAA, R8
+	MOVD	LCA64(R8), R8
+
+	// Get function.
+	MOVD	CAA(R8), R9
+	MOVD	EDCHPXV(R9), R9
+	MOVD	trap+0(FP), R5
+	SLD	$4, R5
+	ADD	R5, R9
+	LMG	0(R9), R5, R6
+
+	// Restore LE stack.
+	MOVD	SAVSTACK_ASYNC(R8), R9
+	MOVD	0(R9), R4
+	MOVD	$0, 0(R9)
+
+	// Fill in parameter list.
+	MOVD	a4+32(FP), R12
+	MOVD	R12, (2176+24)(R4)
+	MOVD	a5+40(FP), R12
+	MOVD	R12, (2176+32)(R4)
+	MOVD	a6+48(FP), R12
+	MOVD	R12, (2176+40)(R4)
+	MOVD	a7+56(FP), R12
+	MOVD	R12, (2176+48)(R4)
+	MOVD	a8+64(FP), R12
+	MOVD	R12, (2176+56)(R4)
+	MOVD	a9+72(FP), R12
+	MOVD	R12, (2176+64)(R4)
+
+	// Call function.
+	LE_CALL
+	NOPH
+	XOR	R0, R0      // Restore R0 to $0.
+	MOVD	R4, 0(R9)   // Save stack pointer.
+
+	MOVD	R3, r1+80(FP)
+	MOVD	R0, r2+88(FP)
+	MOVD	R0, err+96(FP)
+	MOVW	R3, R4
+	CMP	R4, $-1
+	BNE	done
+	BL	addrerrno<>(SB)
+	MOVWZ	0(R3), R3
+	MOVD	R3, err+96(FP)
+done:
+	RET
+
+// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
+TEXT ·svcCall(SB),NOSPLIT,$0
+	BL	runtime·save_g(SB)   // Save g and stack pointer
+	MOVW	PSALAA, R8
+	MOVD	LCA64(R8), R8
+	MOVD	SAVSTACK_ASYNC(R8), R9
+	MOVD	R15, 0(R9)
+
+	MOVD	argv+8(FP), R1       // Move function arguments into registers
+	MOVD	dsa+16(FP), g
+	MOVD	fnptr+0(FP), R15
+
+	BYTE	$0x0D                // Branch to function
+	BYTE	$0xEF
+
+	BL	runtime·load_g(SB)   // Restore g and stack pointer
+	MOVW	PSALAA, R8
+	MOVD	LCA64(R8), R8
+	MOVD	SAVSTACK_ASYNC(R8), R9
+	MOVD	0(R9), R15
+
+	RET
+
+// func svcLoad(name *byte) unsafe.Pointer
+TEXT ·svcLoad(SB),NOSPLIT,$0
+	MOVD	R15, R2          // Save go stack pointer
+	MOVD	name+0(FP), R0   // Move SVC args into registers
+	MOVD	$0x80000000, R1
+	MOVD	$0, R15
+	BYTE	$0x0A            // SVC 08 LOAD
+	BYTE	$0x08
+	MOVW	R15, R3          // Save return code from SVC
+	MOVD	R2, R15          // Restore go stack pointer
+	CMP	R3, $0           // Check SVC return code
+	BNE	error
+
+	MOVD	$-2, R3          // Reset last bit of entry point to zero
+	AND	R0, R3
+	MOVD	R3, addr+8(FP)   // Return entry point returned by SVC
+	CMP	R0, R3           // Check if last bit of entry point was set
+	BNE	done
+
+	MOVD	R15, R2          // Save go stack pointer
+	MOVD	$0, R15          // Move SVC args into registers (entry point still in r0 from SVC 08)
+	BYTE	$0x0A            // SVC 09 DELETE
+	BYTE	$0x09
+	MOVD	R2, R15          // Restore go stack pointer
+
+error:
+	MOVD	$0, addr+8(FP)   // Return 0 on failure
+done:
+	XOR	R0, R0           // Reset r0 to 0
+	RET
+
+// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
+TEXT ·svcUnload(SB),NOSPLIT,$0
+	MOVD	R15, R2          // Save go stack pointer
+	MOVD	name+0(FP), R0   // Move SVC args into registers
+	MOVD	addr+8(FP), R15
+	BYTE	$0x0A            // SVC 09
+	BYTE	$0x09
+	XOR	R0, R0           // Reset r0 to 0
+	MOVD	R15, R1          // Save SVC return code
+	MOVD	R2, R15          // Restore go stack pointer
+	MOVD	R1, rc+0(FP)     // Return SVC return code
+	RET
+
+// func gettid() uint64
+TEXT ·gettid(SB), NOSPLIT, $0
+	// Get library control area (LCA).
+	MOVW PSALAA, R8
+	MOVD LCA64(R8), R8
+
+	// Get CEECAATHDID
+	MOVD CAA(R8), R9
+	MOVD 0x3D0(R9), R9
+	MOVD R9, ret+0(FP)
+
+	RET
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/cap_freebsd.go b/src/cmd/vendor/golang.org/x/sys/unix/cap_freebsd.go
index df52048..0b7c6ad 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/cap_freebsd.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/cap_freebsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build freebsd
 // +build freebsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/constants.go b/src/cmd/vendor/golang.org/x/sys/unix/constants.go
index 3a6ac64..394a396 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/constants.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/constants.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/dev_aix_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/dev_aix_ppc.go
index 5e5fb45..65a9985 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/dev_aix_ppc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/dev_aix_ppc.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix
-// +build ppc
+//go:build aix && ppc
+// +build aix,ppc
 
 // Functions to access/create device major and minor numbers matching the
 // encoding used by AIX.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/dev_aix_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/dev_aix_ppc64.go
index 8b40124..8fc08ad 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/dev_aix_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/dev_aix_ppc64.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix
-// +build ppc64
+//go:build aix && ppc64
+// +build aix,ppc64
 
 // Functions to access/create device major and minor numbers matching the
 // encoding used AIX.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/dev_zos.go b/src/cmd/vendor/golang.org/x/sys/unix/dev_zos.go
new file mode 100644
index 0000000..a388e59
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/dev_zos.go
@@ -0,0 +1,29 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+// Functions to access/create device major and minor numbers matching the
+// encoding used by z/OS.
+//
+// The information below is extracted and adapted from <sys/stat.h> macros.
+
+package unix
+
+// Major returns the major component of a z/OS device number.
+func Major(dev uint64) uint32 {
+	return uint32((dev >> 16) & 0x0000FFFF)
+}
+
+// Minor returns the minor component of a z/OS device number.
+func Minor(dev uint64) uint32 {
+	return uint32(dev & 0x0000FFFF)
+}
+
+// Mkdev returns a z/OS device number generated from the given major and minor
+// components.
+func Mkdev(major, minor uint32) uint64 {
+	return (uint64(major) << 16) | uint64(minor)
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/dirent.go b/src/cmd/vendor/golang.org/x/sys/unix/dirent.go
index 304016b..e74e5ea 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/dirent.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/dirent.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/endian_big.go b/src/cmd/vendor/golang.org/x/sys/unix/endian_big.go
index 86781ea..a520265 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/endian_big.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/endian_big.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 //
+//go:build armbe || arm64be || m68k || mips || mips64 || mips64p32 || ppc || ppc64 || s390 || s390x || shbe || sparc || sparc64
 // +build armbe arm64be m68k mips mips64 mips64p32 ppc ppc64 s390 s390x shbe sparc sparc64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/endian_little.go b/src/cmd/vendor/golang.org/x/sys/unix/endian_little.go
index 8822d85..4362f47 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/endian_little.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/endian_little.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 //
+//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh
 // +build 386 amd64 amd64p32 alpha arm arm64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/env_unix.go b/src/cmd/vendor/golang.org/x/sys/unix/env_unix.go
index 84178b0..29ccc4d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/env_unix.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/env_unix.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
 
 // Unix environment variables.
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/epoll_zos.go b/src/cmd/vendor/golang.org/x/sys/unix/epoll_zos.go
new file mode 100644
index 0000000..cedaf7e
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/epoll_zos.go
@@ -0,0 +1,221 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+package unix
+
+import (
+	"sync"
+)
+
+// This file simulates epoll on z/OS using poll.
+
+// Analogous to epoll_event on Linux.
+// TODO(neeilan): Pad is because the Linux kernel expects a 96-bit struct. We never pass this to the kernel; remove?
+type EpollEvent struct {
+	Events uint32
+	Fd     int32
+	Pad    int32
+}
+
+const (
+	EPOLLERR      = 0x8
+	EPOLLHUP      = 0x10
+	EPOLLIN       = 0x1
+	EPOLLMSG      = 0x400
+	EPOLLOUT      = 0x4
+	EPOLLPRI      = 0x2
+	EPOLLRDBAND   = 0x80
+	EPOLLRDNORM   = 0x40
+	EPOLLWRBAND   = 0x200
+	EPOLLWRNORM   = 0x100
+	EPOLL_CTL_ADD = 0x1
+	EPOLL_CTL_DEL = 0x2
+	EPOLL_CTL_MOD = 0x3
+	// The following constants are part of the epoll API, but represent
+	// currently unsupported functionality on z/OS.
+	// EPOLL_CLOEXEC  = 0x80000
+	// EPOLLET        = 0x80000000
+	// EPOLLONESHOT   = 0x40000000
+	// EPOLLRDHUP     = 0x2000     // Typically used with edge-triggered notis
+	// EPOLLEXCLUSIVE = 0x10000000 // Exclusive wake-up mode
+	// EPOLLWAKEUP    = 0x20000000 // Relies on Linux's BLOCK_SUSPEND capability
+)
+
+// TODO(neeilan): We can eliminate these epToPoll / pToEpoll calls by using identical mask values for POLL/EPOLL
+// constants where possible The lower 16 bits of epoll events (uint32) can fit any system poll event (int16).
+
+// epToPollEvt converts epoll event field to poll equivalent.
+// In epoll, Events is a 32-bit field, while poll uses 16 bits.
+func epToPollEvt(events uint32) int16 {
+	var ep2p = map[uint32]int16{
+		EPOLLIN:  POLLIN,
+		EPOLLOUT: POLLOUT,
+		EPOLLHUP: POLLHUP,
+		EPOLLPRI: POLLPRI,
+		EPOLLERR: POLLERR,
+	}
+
+	var pollEvts int16 = 0
+	for epEvt, pEvt := range ep2p {
+		if (events & epEvt) != 0 {
+			pollEvts |= pEvt
+		}
+	}
+
+	return pollEvts
+}
+
+// pToEpollEvt converts 16 bit poll event bitfields to 32-bit epoll event fields.
+func pToEpollEvt(revents int16) uint32 {
+	var p2ep = map[int16]uint32{
+		POLLIN:  EPOLLIN,
+		POLLOUT: EPOLLOUT,
+		POLLHUP: EPOLLHUP,
+		POLLPRI: EPOLLPRI,
+		POLLERR: EPOLLERR,
+	}
+
+	var epollEvts uint32 = 0
+	for pEvt, epEvt := range p2ep {
+		if (revents & pEvt) != 0 {
+			epollEvts |= epEvt
+		}
+	}
+
+	return epollEvts
+}
+
+// Per-process epoll implementation.
+type epollImpl struct {
+	mu       sync.Mutex
+	epfd2ep  map[int]*eventPoll
+	nextEpfd int
+}
+
+// eventPoll holds a set of file descriptors being watched by the process. A process can have multiple epoll instances.
+// On Linux, this is an in-kernel data structure accessed through a fd.
+type eventPoll struct {
+	mu  sync.Mutex
+	fds map[int]*EpollEvent
+}
+
+// epoll impl for this process.
+var impl epollImpl = epollImpl{
+	epfd2ep:  make(map[int]*eventPoll),
+	nextEpfd: 0,
+}
+
+func (e *epollImpl) epollcreate(size int) (epfd int, err error) {
+	e.mu.Lock()
+	defer e.mu.Unlock()
+	epfd = e.nextEpfd
+	e.nextEpfd++
+
+	e.epfd2ep[epfd] = &eventPoll{
+		fds: make(map[int]*EpollEvent),
+	}
+	return epfd, nil
+}
+
+func (e *epollImpl) epollcreate1(flag int) (fd int, err error) {
+	return e.epollcreate(4)
+}
+
+func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+	e.mu.Lock()
+	defer e.mu.Unlock()
+
+	ep, ok := e.epfd2ep[epfd]
+	if !ok {
+
+		return EBADF
+	}
+
+	switch op {
+	case EPOLL_CTL_ADD:
+		// TODO(neeilan): When we make epfds and fds disjoint, detect epoll
+		// loops here (instances watching each other) and return ELOOP.
+		if _, ok := ep.fds[fd]; ok {
+			return EEXIST
+		}
+		ep.fds[fd] = event
+	case EPOLL_CTL_MOD:
+		if _, ok := ep.fds[fd]; !ok {
+			return ENOENT
+		}
+		ep.fds[fd] = event
+	case EPOLL_CTL_DEL:
+		if _, ok := ep.fds[fd]; !ok {
+			return ENOENT
+		}
+		delete(ep.fds, fd)
+
+	}
+	return nil
+}
+
+// Must be called while holding ep.mu
+func (ep *eventPoll) getFds() []int {
+	fds := make([]int, len(ep.fds))
+	for fd := range ep.fds {
+		fds = append(fds, fd)
+	}
+	return fds
+}
+
+func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+	e.mu.Lock() // in [rare] case of concurrent epollcreate + epollwait
+	ep, ok := e.epfd2ep[epfd]
+
+	if !ok {
+		e.mu.Unlock()
+		return 0, EBADF
+	}
+
+	pollfds := make([]PollFd, 4)
+	for fd, epollevt := range ep.fds {
+		pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)})
+	}
+	e.mu.Unlock()
+
+	n, err = Poll(pollfds, msec)
+	if err != nil {
+		return n, err
+	}
+
+	i := 0
+	for _, pFd := range pollfds {
+		if pFd.Revents != 0 {
+			events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)}
+			i++
+		}
+
+		if i == n {
+			break
+		}
+	}
+
+	return n, nil
+}
+
+func EpollCreate(size int) (fd int, err error) {
+	return impl.epollcreate(size)
+}
+
+func EpollCreate1(flag int) (fd int, err error) {
+	return impl.epollcreate1(flag)
+}
+
+func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+	return impl.epollctl(epfd, op, fd, event)
+}
+
+// Because EpollWait mutates events, the caller is expected to coordinate
+// concurrent access if calling with the same epfd from multiple goroutines.
+func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+	return impl.epollwait(epfd, events, msec)
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/fcntl.go b/src/cmd/vendor/golang.org/x/sys/unix/fcntl.go
index 4dc5348..e9b9912 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/fcntl.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/fcntl.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || linux || netbsd || openbsd
 // +build dragonfly freebsd linux netbsd openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go b/src/cmd/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go
index 8db48e5..29d4480 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux,386 linux,arm linux,mips linux,mipsle
+//go:build (linux && 386) || (linux && arm) || (linux && mips) || (linux && mipsle) || (linux && ppc)
+// +build linux,386 linux,arm linux,mips linux,mipsle linux,ppc
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/fdset.go b/src/cmd/vendor/golang.org/x/sys/unix/fdset.go
index b27be0a..a8068f9 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/fdset.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/fdset.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/fstatfs_zos.go b/src/cmd/vendor/golang.org/x/sys/unix/fstatfs_zos.go
new file mode 100644
index 0000000..e377cc9
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/fstatfs_zos.go
@@ -0,0 +1,164 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+package unix
+
+import (
+	"unsafe"
+)
+
+// This file simulates fstatfs on z/OS using fstatvfs and w_getmntent.
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	var stat_v Statvfs_t
+	err = Fstatvfs(fd, &stat_v)
+	if err == nil {
+		// populate stat
+		stat.Type = 0
+		stat.Bsize = stat_v.Bsize
+		stat.Blocks = stat_v.Blocks
+		stat.Bfree = stat_v.Bfree
+		stat.Bavail = stat_v.Bavail
+		stat.Files = stat_v.Files
+		stat.Ffree = stat_v.Ffree
+		stat.Fsid = stat_v.Fsid
+		stat.Namelen = stat_v.Namemax
+		stat.Frsize = stat_v.Frsize
+		stat.Flags = stat_v.Flag
+		for passn := 0; passn < 5; passn++ {
+			switch passn {
+			case 0:
+				err = tryGetmntent64(stat)
+				break
+			case 1:
+				err = tryGetmntent128(stat)
+				break
+			case 2:
+				err = tryGetmntent256(stat)
+				break
+			case 3:
+				err = tryGetmntent512(stat)
+				break
+			case 4:
+				err = tryGetmntent1024(stat)
+				break
+			default:
+				break
+			}
+			//proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred)
+			if err == nil || err != nil && err != ERANGE {
+				break
+			}
+		}
+	}
+	return err
+}
+
+func tryGetmntent64(stat *Statfs_t) (err error) {
+	var mnt_ent_buffer struct {
+		header       W_Mnth
+		filesys_info [64]W_Mntent
+	}
+	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
+	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
+	if err != nil {
+		return err
+	}
+	err = ERANGE //return ERANGE if no match is found in this batch
+	for i := 0; i < fs_count; i++ {
+		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
+			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
+			err = nil
+			break
+		}
+	}
+	return err
+}
+
+func tryGetmntent128(stat *Statfs_t) (err error) {
+	var mnt_ent_buffer struct {
+		header       W_Mnth
+		filesys_info [128]W_Mntent
+	}
+	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
+	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
+	if err != nil {
+		return err
+	}
+	err = ERANGE //return ERANGE if no match is found in this batch
+	for i := 0; i < fs_count; i++ {
+		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
+			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
+			err = nil
+			break
+		}
+	}
+	return err
+}
+
+func tryGetmntent256(stat *Statfs_t) (err error) {
+	var mnt_ent_buffer struct {
+		header       W_Mnth
+		filesys_info [256]W_Mntent
+	}
+	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
+	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
+	if err != nil {
+		return err
+	}
+	err = ERANGE //return ERANGE if no match is found in this batch
+	for i := 0; i < fs_count; i++ {
+		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
+			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
+			err = nil
+			break
+		}
+	}
+	return err
+}
+
+func tryGetmntent512(stat *Statfs_t) (err error) {
+	var mnt_ent_buffer struct {
+		header       W_Mnth
+		filesys_info [512]W_Mntent
+	}
+	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
+	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
+	if err != nil {
+		return err
+	}
+	err = ERANGE //return ERANGE if no match is found in this batch
+	for i := 0; i < fs_count; i++ {
+		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
+			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
+			err = nil
+			break
+		}
+	}
+	return err
+}
+
+func tryGetmntent1024(stat *Statfs_t) (err error) {
+	var mnt_ent_buffer struct {
+		header       W_Mnth
+		filesys_info [1024]W_Mntent
+	}
+	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
+	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
+	if err != nil {
+		return err
+	}
+	err = ERANGE //return ERANGE if no match is found in this batch
+	for i := 0; i < fs_count; i++ {
+		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
+			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
+			err = nil
+			break
+		}
+	}
+	return err
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/gccgo.go b/src/cmd/vendor/golang.org/x/sys/unix/gccgo.go
index 86032c1..0dee232 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/gccgo.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/gccgo.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build gccgo
-// +build !aix
+//go:build gccgo && !aix
+// +build gccgo,!aix
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
index 251a977..e60e49a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gccgo && linux && amd64
 // +build gccgo,linux,amd64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ioctl.go b/src/cmd/vendor/golang.org/x/sys/unix/ioctl.go
index 5641678..6c7ad05 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ioctl.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ioctl.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ioctl_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/ioctl_linux.go
new file mode 100644
index 0000000..48773f7
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ioctl_linux.go
@@ -0,0 +1,196 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import (
+	"runtime"
+	"unsafe"
+)
+
+// IoctlRetInt performs an ioctl operation specified by req on a device
+// associated with opened file descriptor fd, and returns a non-negative
+// integer that is returned by the ioctl syscall.
+func IoctlRetInt(fd int, req uint) (int, error) {
+	ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0)
+	if err != 0 {
+		return 0, err
+	}
+	return int(ret), nil
+}
+
+func IoctlGetUint32(fd int, req uint) (uint32, error) {
+	var value uint32
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+	return value, err
+}
+
+func IoctlGetRTCTime(fd int) (*RTCTime, error) {
+	var value RTCTime
+	err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value)))
+	return &value, err
+}
+
+func IoctlSetRTCTime(fd int, value *RTCTime) error {
+	err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value)))
+	runtime.KeepAlive(value)
+	return err
+}
+
+func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) {
+	var value RTCWkAlrm
+	err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value)))
+	return &value, err
+}
+
+func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error {
+	err := ioctl(fd, RTC_WKALM_SET, uintptr(unsafe.Pointer(value)))
+	runtime.KeepAlive(value)
+	return err
+}
+
+type ifreqEthtool struct {
+	name [IFNAMSIZ]byte
+	data unsafe.Pointer
+}
+
+// IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network
+// device specified by ifname.
+func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) {
+	// Leave room for terminating NULL byte.
+	if len(ifname) >= IFNAMSIZ {
+		return nil, EINVAL
+	}
+
+	value := EthtoolDrvinfo{
+		Cmd: ETHTOOL_GDRVINFO,
+	}
+	ifreq := ifreqEthtool{
+		data: unsafe.Pointer(&value),
+	}
+	copy(ifreq.name[:], ifname)
+	err := ioctl(fd, SIOCETHTOOL, uintptr(unsafe.Pointer(&ifreq)))
+	runtime.KeepAlive(ifreq)
+	return &value, err
+}
+
+// IoctlGetWatchdogInfo fetches information about a watchdog device from the
+// Linux watchdog API. For more information, see:
+// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
+func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) {
+	var value WatchdogInfo
+	err := ioctl(fd, WDIOC_GETSUPPORT, uintptr(unsafe.Pointer(&value)))
+	return &value, err
+}
+
+// IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For
+// more information, see:
+// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
+func IoctlWatchdogKeepalive(fd int) error {
+	return ioctl(fd, WDIOC_KEEPALIVE, 0)
+}
+
+// IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the
+// range of data conveyed in value to the file associated with the file
+// descriptor destFd. See the ioctl_ficlonerange(2) man page for details.
+func IoctlFileCloneRange(destFd int, value *FileCloneRange) error {
+	err := ioctl(destFd, FICLONERANGE, uintptr(unsafe.Pointer(value)))
+	runtime.KeepAlive(value)
+	return err
+}
+
+// IoctlFileClone performs an FICLONE ioctl operation to clone the entire file
+// associated with the file description srcFd to the file associated with the
+// file descriptor destFd. See the ioctl_ficlone(2) man page for details.
+func IoctlFileClone(destFd, srcFd int) error {
+	return ioctl(destFd, FICLONE, uintptr(srcFd))
+}
+
+type FileDedupeRange struct {
+	Src_offset uint64
+	Src_length uint64
+	Reserved1  uint16
+	Reserved2  uint32
+	Info       []FileDedupeRangeInfo
+}
+
+type FileDedupeRangeInfo struct {
+	Dest_fd       int64
+	Dest_offset   uint64
+	Bytes_deduped uint64
+	Status        int32
+	Reserved      uint32
+}
+
+// IoctlFileDedupeRange performs an FIDEDUPERANGE ioctl operation to share the
+// range of data conveyed in value from the file associated with the file
+// descriptor srcFd to the value.Info destinations. See the
+// ioctl_fideduperange(2) man page for details.
+func IoctlFileDedupeRange(srcFd int, value *FileDedupeRange) error {
+	buf := make([]byte, SizeofRawFileDedupeRange+
+		len(value.Info)*SizeofRawFileDedupeRangeInfo)
+	rawrange := (*RawFileDedupeRange)(unsafe.Pointer(&buf[0]))
+	rawrange.Src_offset = value.Src_offset
+	rawrange.Src_length = value.Src_length
+	rawrange.Dest_count = uint16(len(value.Info))
+	rawrange.Reserved1 = value.Reserved1
+	rawrange.Reserved2 = value.Reserved2
+
+	for i := range value.Info {
+		rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer(
+			uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) +
+				uintptr(i*SizeofRawFileDedupeRangeInfo)))
+		rawinfo.Dest_fd = value.Info[i].Dest_fd
+		rawinfo.Dest_offset = value.Info[i].Dest_offset
+		rawinfo.Bytes_deduped = value.Info[i].Bytes_deduped
+		rawinfo.Status = value.Info[i].Status
+		rawinfo.Reserved = value.Info[i].Reserved
+	}
+
+	err := ioctl(srcFd, FIDEDUPERANGE, uintptr(unsafe.Pointer(&buf[0])))
+
+	// Output
+	for i := range value.Info {
+		rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer(
+			uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) +
+				uintptr(i*SizeofRawFileDedupeRangeInfo)))
+		value.Info[i].Dest_fd = rawinfo.Dest_fd
+		value.Info[i].Dest_offset = rawinfo.Dest_offset
+		value.Info[i].Bytes_deduped = rawinfo.Bytes_deduped
+		value.Info[i].Status = rawinfo.Status
+		value.Info[i].Reserved = rawinfo.Reserved
+	}
+
+	return err
+}
+
+func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error {
+	err := ioctl(fd, HIDIOCGRDESC, uintptr(unsafe.Pointer(value)))
+	runtime.KeepAlive(value)
+	return err
+}
+
+func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) {
+	var value HIDRawDevInfo
+	err := ioctl(fd, HIDIOCGRAWINFO, uintptr(unsafe.Pointer(&value)))
+	return &value, err
+}
+
+func IoctlHIDGetRawName(fd int) (string, error) {
+	var value [_HIDIOCGRAWNAME_LEN]byte
+	err := ioctl(fd, _HIDIOCGRAWNAME, uintptr(unsafe.Pointer(&value[0])))
+	return ByteSliceToString(value[:]), err
+}
+
+func IoctlHIDGetRawPhys(fd int) (string, error) {
+	var value [_HIDIOCGRAWPHYS_LEN]byte
+	err := ioctl(fd, _HIDIOCGRAWPHYS, uintptr(unsafe.Pointer(&value[0])))
+	return ByteSliceToString(value[:]), err
+}
+
+func IoctlHIDGetRawUniq(fd int) (string, error) {
+	var value [_HIDIOCGRAWUNIQ_LEN]byte
+	err := ioctl(fd, _HIDIOCGRAWUNIQ, uintptr(unsafe.Pointer(&value[0])))
+	return ByteSliceToString(value[:]), err
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ioctl_zos.go b/src/cmd/vendor/golang.org/x/sys/unix/ioctl_zos.go
new file mode 100644
index 0000000..5384e7d
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ioctl_zos.go
@@ -0,0 +1,74 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+package unix
+
+import (
+	"runtime"
+	"unsafe"
+)
+
+// ioctl itself should not be exposed directly, but additional get/set
+// functions for specific types are permissible.
+
+// IoctlSetInt performs an ioctl operation which sets an integer value
+// on fd, using the specified request number.
+func IoctlSetInt(fd int, req uint, value int) error {
+	return ioctl(fd, req, uintptr(value))
+}
+
+// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
+//
+// To change fd's window size, the req argument should be TIOCSWINSZ.
+func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
+	// TODO: if we get the chance, remove the req parameter and
+	// hardcode TIOCSWINSZ.
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
+	runtime.KeepAlive(value)
+	return err
+}
+
+// IoctlSetTermios performs an ioctl on fd with a *Termios.
+//
+// The req value is expected to be TCSETS, TCSETSW, or TCSETSF
+func IoctlSetTermios(fd int, req uint, value *Termios) error {
+	if (req != TCSETS) && (req != TCSETSW) && (req != TCSETSF) {
+		return ENOSYS
+	}
+	err := Tcsetattr(fd, int(req), value)
+	runtime.KeepAlive(value)
+	return err
+}
+
+// IoctlGetInt performs an ioctl operation which gets an integer value
+// from fd, using the specified request number.
+//
+// A few ioctl requests use the return value as an output parameter;
+// for those, IoctlRetInt should be used instead of this function.
+func IoctlGetInt(fd int, req uint) (int, error) {
+	var value int
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+	return value, err
+}
+
+func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
+	var value Winsize
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+	return &value, err
+}
+
+// IoctlGetTermios performs an ioctl on fd with a *Termios.
+//
+// The req value is expected to be TCGETS
+func IoctlGetTermios(fd int, req uint) (*Termios, error) {
+	var value Termios
+	if req != TCGETS {
+		return &value, ENOSYS
+	}
+	err := Tcgetattr(fd, &value)
+	return &value, err
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh b/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh
index d257fac..396aadf 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh
+++ b/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh
@@ -70,23 +70,11 @@
 	mksyscall="go run mksyscall_aix_ppc64.go -aix"
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 	;;
-darwin_386)
-	mkerrors="$mkerrors -m32"
-	mksyscall="go run mksyscall.go -l32"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	mkasm="go run mkasm_darwin.go"
-	;;
 darwin_amd64)
 	mkerrors="$mkerrors -m64"
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 	mkasm="go run mkasm_darwin.go"
 	;;
-darwin_arm)
-	mkerrors="$mkerrors"
-	mksyscall="go run mksyscall.go -l32"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	mkasm="go run mkasm_darwin.go"
-	;;
 darwin_arm64)
 	mkerrors="$mkerrors -m64"
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
@@ -199,7 +187,7 @@
         mksyscall="go run mksyscall_solaris.go"
 	mkerrors=
 	mksysnum=
-	mktypes=
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 	;;
 *)
 	echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh b/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh
index c0f9f2d..007358a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh
+++ b/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -56,6 +56,7 @@
 #define _DARWIN_C_SOURCE
 #define KERNEL
 #define _DARWIN_USE_64_BIT_INODE
+#define __APPLE_USE_RFC_3542
 #include <stdint.h>
 #include <sys/attr.h>
 #include <sys/clonefile.h>
@@ -65,6 +66,7 @@
 #include <sys/ptrace.h>
 #include <sys/select.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <sys/sockio.h>
 #include <sys/sys_domain.h>
 #include <sys/sysctl.h>
@@ -114,6 +116,7 @@
 #include <sys/sched.h>
 #include <sys/select.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <sys/sockio.h>
 #include <sys/stat.h>
 #include <sys/sysctl.h>
@@ -204,6 +207,7 @@
 #include <linux/devlink.h>
 #include <linux/dm-ioctl.h>
 #include <linux/errqueue.h>
+#include <linux/ethtool_netlink.h>
 #include <linux/falloc.h>
 #include <linux/fanotify.h>
 #include <linux/filter.h>
@@ -212,6 +216,8 @@
 #include <linux/fsverity.h>
 #include <linux/genetlink.h>
 #include <linux/hdreg.h>
+#include <linux/hidraw.h>
+#include <linux/icmp.h>
 #include <linux/icmpv6.h>
 #include <linux/if.h>
 #include <linux/if_addr.h>
@@ -222,6 +228,7 @@
 #include <linux/if_tun.h>
 #include <linux/if_packet.h>
 #include <linux/if_xdp.h>
+#include <linux/input.h>
 #include <linux/kexec.h>
 #include <linux/keyctl.h>
 #include <linux/loop.h>
@@ -298,6 +305,17 @@
 // Including linux/l2tp.h here causes conflicts between linux/in.h
 // and netinet/in.h included via net/route.h above.
 #define IPPROTO_L2TP		115
+
+// Copied from linux/hid.h.
+// Keep in sync with the size of the referenced fields.
+#define _HIDIOCGRAWNAME_LEN	128 // sizeof_field(struct hid_device, name)
+#define _HIDIOCGRAWPHYS_LEN	64  // sizeof_field(struct hid_device, phys)
+#define _HIDIOCGRAWUNIQ_LEN	64  // sizeof_field(struct hid_device, uniq)
+
+#define _HIDIOCGRAWNAME		HIDIOCGRAWNAME(_HIDIOCGRAWNAME_LEN)
+#define _HIDIOCGRAWPHYS		HIDIOCGRAWPHYS(_HIDIOCGRAWPHYS_LEN)
+#define _HIDIOCGRAWUNIQ		HIDIOCGRAWUNIQ(_HIDIOCGRAWUNIQ_LEN)
+
 '
 
 includes_NetBSD='
@@ -387,10 +405,11 @@
 #include <net/if_arp.h>
 #include <net/if_types.h>
 #include <net/route.h>
+#include <netinet/icmp6.h>
 #include <netinet/in.h>
-#include <termios.h>
 #include <netinet/ip.h>
 #include <netinet/ip_mroute.h>
+#include <termios.h>
 '
 
 
@@ -445,6 +464,8 @@
 		$2 !~ /^EPROC_/ &&
 		$2 !~ /^EQUIV_/ &&
 		$2 !~ /^EXPR_/ &&
+		$2 !~ /^EVIOC/ &&
+		$2 !~ /^EV_/ &&
 		$2 ~ /^E[A-Z0-9_]+$/ ||
 		$2 ~ /^B[0-9_]+$/ ||
 		$2 ~ /^(OLD|NEW)DEV$/ ||
@@ -479,10 +500,10 @@
 		$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
 		$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
 		$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
-		$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|MCAST|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
+		$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL)_/ ||
 		$2 ~ /^TP_STATUS_/ ||
 		$2 ~ /^FALLOC_/ ||
-		$2 == "ICMPV6_FILTER" ||
+		$2 ~ /^ICMPV?6?_(FILTER|SEC)/ ||
 		$2 == "SOMAXCONN" ||
 		$2 == "NAME_MAX" ||
 		$2 == "IFNAMSIZ" ||
@@ -561,12 +582,17 @@
 		$2 ~ /^(HDIO|WIN|SMART)_/ ||
 		$2 ~ /^CRYPTO_/ ||
 		$2 ~ /^TIPC_/ ||
+		$2 !~  "DEVLINK_RELOAD_LIMITS_VALID_MASK" &&
 		$2 ~ /^DEVLINK_/ ||
+		$2 ~ /^ETHTOOL_/ ||
 		$2 ~ /^LWTUNNEL_IP/ ||
 		$2 !~ "WMESGLEN" &&
 		$2 ~ /^W[A-Z0-9]+$/ ||
 		$2 ~/^PPPIOC/ ||
 		$2 ~ /^FAN_|FANOTIFY_/ ||
+		$2 == "HID_MAX_DESCRIPTOR_SIZE" ||
+		$2 ~ /^_?HIDIOC/ ||
+		$2 ~ /^BUS_(USB|HIL|BLUETOOTH|VIRTUAL)$/ ||
 		$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
 		$2 ~ /^__WCOREFLAG$/ {next}
 		$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
@@ -604,6 +630,7 @@
 echo '// mkerrors.sh' "$@"
 echo '// Code generated by the command above; see README.md. DO NOT EDIT.'
 echo
+echo "//go:build ${GOARCH} && ${GOOS}"
 echo "// +build ${GOARCH},${GOOS}"
 echo
 go tool cgo -godefs -- "$@" _const.go >_error.out
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/pagesize_unix.go b/src/cmd/vendor/golang.org/x/sys/unix/pagesize_unix.go
index bc2f362..53f1b4c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/pagesize_unix.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/pagesize_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 // For Unix, get the pagesize from the runtime.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ptrace_darwin.go b/src/cmd/vendor/golang.org/x/sys/unix/ptrace_darwin.go
new file mode 100644
index 0000000..463c3ef
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ptrace_darwin.go
@@ -0,0 +1,12 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin && !ios
+// +build darwin,!ios
+
+package unix
+
+func ptrace(request int, pid int, addr uintptr, data uintptr) error {
+	return ptrace1(request, pid, addr, data)
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ptrace_ios.go b/src/cmd/vendor/golang.org/x/sys/unix/ptrace_ios.go
new file mode 100644
index 0000000..ed0509a
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ptrace_ios.go
@@ -0,0 +1,12 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build ios
+// +build ios
+
+package unix
+
+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
+	return ENOTSUP
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/race.go b/src/cmd/vendor/golang.org/x/sys/unix/race.go
index 61712b5..6f6c5fe 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/race.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/race.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (darwin && race) || (linux && race) || (freebsd && race)
 // +build darwin,race linux,race freebsd,race
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/race0.go b/src/cmd/vendor/golang.org/x/sys/unix/race0.go
index ad02667..706e132 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/race0.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/race0.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly
+//go:build aix || (darwin && !race) || (linux && !race) || (freebsd && !race) || netbsd || openbsd || solaris || dragonfly || zos
+// +build aix darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly zos
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/readdirent_getdents.go b/src/cmd/vendor/golang.org/x/sys/unix/readdirent_getdents.go
index 3a90aa6..4d62575 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/readdirent_getdents.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/readdirent_getdents.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || dragonfly || freebsd || linux || netbsd || openbsd
 // +build aix dragonfly freebsd linux netbsd openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/readdirent_getdirentries.go b/src/cmd/vendor/golang.org/x/sys/unix/readdirent_getdirentries.go
index 5fdae40..2a4ba47 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/readdirent_getdirentries.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/readdirent_getdirentries.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin
 // +build darwin
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix.go b/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix.go
index 003916e..453a942 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
 
 // Socket control messages
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go b/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go
index 57a0021..0840fe4 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin freebsd linux netbsd openbsd solaris zos
 
 package unix
 
@@ -36,6 +37,10 @@
 		if runtime.GOOS == "netbsd" && runtime.GOARCH == "arm64" {
 			salign = 16
 		}
+	case "zos":
+		// z/OS socket macros use [32-bit] sizeof(int) alignment,
+		// not pointer width.
+		salign = SizeofInt
 	}
 
 	return (salen + salign - 1) & ^(salign - 1)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/str.go b/src/cmd/vendor/golang.org/x/sys/unix/str.go
index 17fb698..8ba89ed 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/str.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/str.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall.go
index ab75ef9..649fa87 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
 
 // Package unix contains an interface to the low-level operating system
 // primitives. OS details vary depending on the underlying system, and
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go
index 4408153..d8efb71 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix
 // +build aix
 
 // Aix system calls.
@@ -251,7 +252,7 @@
 			}
 		}
 
-		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
+		bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
 		sa.Name = string(bytes)
 		return sa, nil
 
@@ -419,8 +420,8 @@
 //sys	Mknod(path string, mode uint32, dev int) (err error)
 //sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
 //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
-//sys   Open(path string, mode int, perm uint32) (fd int, err error) = open64
-//sys   Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
+//sys	Open(path string, mode int, perm uint32) (fd int, err error) = open64
+//sys	Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
 //sys	read(fd int, p []byte) (n int, err error)
 //sys	Readlink(path string, buf []byte) (n int, err error)
 //sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
@@ -439,8 +440,8 @@
 //sysnb	Times(tms *Tms) (ticks uintptr, err error)
 //sysnb	Umask(mask int) (oldmask int)
 //sysnb	Uname(buf *Utsname) (err error)
-//sys   Unlink(path string) (err error)
-//sys   Unlinkat(dirfd int, path string, flags int) (err error)
+//sys	Unlink(path string) (err error)
+//sys	Unlinkat(dirfd int, path string, flags int) (err error)
 //sys	Ustat(dev int, ubuf *Ustat_t) (err error)
 //sys	write(fd int, p []byte) (n int, err error)
 //sys	readlen(fd int, p *byte, np int) (n int, err error) = read
@@ -514,7 +515,7 @@
 //sys	Munlock(b []byte) (err error)
 //sys	Munlockall() (err error)
 
-//sysnb pipe(p *[2]_C_int) (err error)
+//sysnb	pipe(p *[2]_C_int) (err error)
 
 func Pipe(p []int) (err error) {
 	if len(p) != 2 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix_ppc.go
index b3c8e33..e92a0be 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix_ppc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix_ppc.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix
-// +build ppc
+//go:build aix && ppc
+// +build aix,ppc
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go
index 9a6e024..16eed17 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix
-// +build ppc64
+//go:build aix && ppc64
+// +build aix,ppc64
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go
index bc634a2..95ac394 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 // BSD system call wrappers shared by *BSD based systems
@@ -318,7 +319,7 @@
 	return anyToSockaddr(fd, &rsa)
 }
 
-//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
+//sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
 
 // GetsockoptString returns the string value of the socket option opt for the
 // socket associated with fd at the given socket level.
@@ -332,8 +333,8 @@
 	return string(buf[:vallen-1]), nil
 }
 
-//sys   recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
-//sys   sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
+//sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
+//sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
 //sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
 
 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
@@ -626,7 +627,7 @@
 	return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
 }
 
-//sys   poll(fds *PollFd, nfds int, timeout int) (n int, err error)
+//sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
 
 func Poll(fds []PollFd, timeout int) (n int, err error) {
 	if len(fds) == 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go
index b31ef03..b009860 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin && go1.12 && !go1.13
 // +build darwin,go1.12,!go1.13
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go
index ee852f1..1596426 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin && go1.13
 // +build darwin,go1.13
 
 package unix
@@ -16,7 +17,7 @@
 //sys	readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
 
 func fdopendir(fd int) (dir uintptr, err error) {
-	r0, _, e1 := syscall_syscallPtr(funcPC(libc_fdopendir_trampoline), uintptr(fd), 0, 0)
+	r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
 	dir = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -24,7 +25,7 @@
 	return
 }
 
-func libc_fdopendir_trampoline()
+var libc_fdopendir_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go
index b625738..9945e5f 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go
@@ -119,13 +119,16 @@
 	Forkattr    uint32
 }
 
-//sysnb pipe() (r int, w int, err error)
+//sysnb	pipe(p *[2]int32) (err error)
 
 func Pipe(p []int) (err error) {
 	if len(p) != 2 {
 		return EINVAL
 	}
-	p[0], p[1], err = pipe()
+	var x [2]int32
+	err = pipe(&x)
+	p[0] = int(x[0])
+	p[1] = int(x[1])
 	return
 }
 
@@ -269,7 +272,7 @@
 		options)
 }
 
-//sys setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error)
+//sys	setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error)
 
 func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
 	// Darwin doesn't support SYS_UTIMENSAT
@@ -317,7 +320,7 @@
 	return err
 }
 
-//sys   sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL
+//sys	sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL
 
 func Uname(uname *Utsname) error {
 	mib := []_C_int{CTL_KERN, KERN_OSTYPE}
@@ -375,6 +378,26 @@
 	return
 }
 
+func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
+	var value IPMreqn
+	vallen := _Socklen(SizeofIPMreqn)
+	errno := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, errno
+}
+
+func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
+}
+
+// GetsockoptXucred is a getsockopt wrapper that returns an Xucred struct.
+// The usual level and opt are SOL_LOCAL and LOCAL_PEERCRED, respectively.
+func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
+	x := new(Xucred)
+	vallen := _Socklen(SizeofXucred)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen)
+	return x, err
+}
+
 //sys	sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
 
 /*
@@ -469,8 +492,8 @@
 //sys	Unlinkat(dirfd int, path string, flags int) (err error)
 //sys	Unmount(path string, flags int) (err error)
 //sys	write(fd int, p []byte) (n int, err error)
-//sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
-//sys   munmap(addr uintptr, length uintptr) (err error)
+//sys	mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
+//sys	munmap(addr uintptr, length uintptr) (err error)
 //sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
 //sys	writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go
deleted file mode 100644
index 6c1f4ab..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build 386,darwin
-
-package unix
-
-import "syscall"
-
-func setTimespec(sec, nsec int64) Timespec {
-	return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
-}
-
-func setTimeval(sec, usec int64) Timeval {
-	return Timeval{Sec: int32(sec), Usec: int32(usec)}
-}
-
-func SetKevent(k *Kevent_t, fd, mode, flags int) {
-	k.Ident = uint32(fd)
-	k.Filter = int16(mode)
-	k.Flags = uint16(flags)
-}
-
-func (iov *Iovec) SetLen(length int) {
-	iov.Len = uint32(length)
-}
-
-func (msghdr *Msghdr) SetControllen(length int) {
-	msghdr.Controllen = uint32(length)
-}
-
-func (msghdr *Msghdr) SetIovlen(length int) {
-	msghdr.Iovlen = int32(length)
-}
-
-func (cmsg *Cmsghdr) SetLen(length int) {
-	cmsg.Len = uint32(length)
-}
-
-func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
-
-//sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
-//sys	Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
-//sys	Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
-//sys	getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
-//sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
-//sys	ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
-//sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
-//sys	Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
index 0582ae2..b37310c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 && darwin
 // +build amd64,darwin
 
 package unix
@@ -45,6 +46,6 @@
 //sys	Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
 //sys	getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
 //sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
-//sys	ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
+//sys	ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace
 //sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
 //sys	Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go
deleted file mode 100644
index c6a9733..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go
+++ /dev/null
@@ -1,51 +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 unix
-
-import "syscall"
-
-func ptrace(request int, pid int, addr uintptr, data uintptr) error {
-	return ENOTSUP
-}
-
-func setTimespec(sec, nsec int64) Timespec {
-	return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
-}
-
-func setTimeval(sec, usec int64) Timeval {
-	return Timeval{Sec: int32(sec), Usec: int32(usec)}
-}
-
-func SetKevent(k *Kevent_t, fd, mode, flags int) {
-	k.Ident = uint32(fd)
-	k.Filter = int16(mode)
-	k.Flags = uint16(flags)
-}
-
-func (iov *Iovec) SetLen(length int) {
-	iov.Len = uint32(length)
-}
-
-func (msghdr *Msghdr) SetControllen(length int) {
-	msghdr.Controllen = uint32(length)
-}
-
-func (msghdr *Msghdr) SetIovlen(length int) {
-	msghdr.Iovlen = int32(length)
-}
-
-func (cmsg *Cmsghdr) SetLen(length int) {
-	cmsg.Len = uint32(length)
-}
-
-func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic
-
-//sys	Fstat(fd int, stat *Stat_t) (err error)
-//sys	Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
-//sys	Fstatfs(fd int, stat *Statfs_t) (err error)
-//sys	getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT
-//sys	Lstat(path string, stat *Stat_t) (err error)
-//sys	Stat(path string, stat *Stat_t) (err error)
-//sys	Statfs(path string, stat *Statfs_t) (err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go
index 253afa4..d51ec99 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm64 && darwin
 // +build arm64,darwin
 
 package unix
@@ -45,6 +46,6 @@
 //sys	Fstatfs(fd int, stat *Statfs_t) (err error)
 //sys	getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT
 //sys	Lstat(path string, stat *Stat_t) (err error)
-//sys	ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
+//sys	ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace
 //sys	Stat(path string, stat *Stat_t) (err error)
 //sys	Statfs(path string, stat *Statfs_t) (err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go
index f34c86c..53c9664 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go
@@ -2,11 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin && go1.12
 // +build darwin,go1.12
 
 package unix
 
-import "unsafe"
+import _ "unsafe"
 
 // Implemented in the runtime package (runtime/sys_darwin.go)
 func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
@@ -24,10 +25,3 @@
 //go:linkname syscall_rawSyscall syscall.rawSyscall
 //go:linkname syscall_rawSyscall6 syscall.rawSyscall6
 //go:linkname syscall_syscallPtr syscall.syscallPtr
-
-// Find the entry point for f. See comments in runtime/proc.go for the
-// function of the same name.
-//go:nosplit
-func funcPC(f func()) uintptr {
-	return **(**uintptr)(unsafe.Pointer(&f))
-}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
index a4f2944..5af108a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
@@ -95,7 +95,7 @@
 	return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
 }
 
-//sysnb pipe() (r int, w int, err error)
+//sysnb	pipe() (r int, w int, err error)
 
 func Pipe(p []int) (err error) {
 	if len(p) != 2 {
@@ -105,16 +105,16 @@
 	return
 }
 
-//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
+//sysnb	pipe2(p *[2]_C_int, flags int) (r int, w int, err error)
 
-func Pipe2(p []int, flags int) error {
+func Pipe2(p []int, flags int) (err error) {
 	if len(p) != 2 {
 		return EINVAL
 	}
 	var pp [2]_C_int
-	err := pipe2(&pp, flags)
-	p[0] = int(pp[0])
-	p[1] = int(pp[1])
+	// pipe2 on dragonfly takes an fds array as an argument, but still
+	// returns the file descriptors.
+	p[0], p[1], err = pipe2(&pp, flags)
 	return err
 }
 
@@ -170,7 +170,7 @@
 
 //sys	ioctl(fd int, req uint, arg uintptr) (err error)
 
-//sys   sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
+//sys	sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
 
 func sysctlUname(mib []_C_int, old *byte, oldlen *uintptr) error {
 	err := sysctl(mib, old, oldlen, nil, 0)
@@ -337,8 +337,8 @@
 //sys	Unlinkat(dirfd int, path string, flags int) (err error)
 //sys	Unmount(path string, flags int) (err error)
 //sys	write(fd int, p []byte) (n int, err error)
-//sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
-//sys   munmap(addr uintptr, length uintptr) (err error)
+//sys	mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
+//sys	munmap(addr uintptr, length uintptr) (err error)
 //sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
 //sys	writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
 //sys	accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go
index a6b4830..4e2d321 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 && dragonfly
 // +build amd64,dragonfly
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go
index acc00c2..18c392c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go
@@ -126,6 +126,15 @@
 	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
 }
 
+// GetsockoptXucred is a getsockopt wrapper that returns an Xucred struct.
+// The usual level and opt are SOL_LOCAL and LOCAL_PEERCRED, respectively.
+func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
+	x := new(Xucred)
+	vallen := _Socklen(SizeofXucred)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen)
+	return x, err
+}
+
 func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
 	var rsa RawSockaddrAny
 	var len _Socklen = SizeofSockaddrAny
@@ -188,9 +197,9 @@
 	return ENOSYS
 }
 
-//sys   ioctl(fd int, req uint, arg uintptr) (err error)
+//sys	ioctl(fd int, req uint, arg uintptr) (err error)
 
-//sys   sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
+//sys	sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
 
 func Uname(uname *Utsname) error {
 	mib := []_C_int{CTL_KERN, KERN_OSTYPE}
@@ -665,8 +674,8 @@
 //sys	Unlinkat(dirfd int, path string, flags int) (err error)
 //sys	Unmount(path string, flags int) (err error)
 //sys	write(fd int, p []byte) (n int, err error)
-//sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
-//sys   munmap(addr uintptr, length uintptr) (err error)
+//sys	mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
+//sys	munmap(addr uintptr, length uintptr) (err error)
 //sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
 //sys	writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
 //sys	accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
index 72a506d..342fc32 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 && freebsd
 // +build 386,freebsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
index d5e376a..a32d5aa 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 && freebsd
 // +build amd64,freebsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
index 4ea45bc..1e36d39 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm && freebsd
 // +build arm,freebsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go
index aa5326d..a09a153 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm64 && freebsd
 // +build arm64,freebsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go
index bbc4f3e..8c53576 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go
@@ -1,14 +1,19 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // illumos system calls not present on Solaris.
 
+//go:build amd64 && illumos
 // +build amd64,illumos
 
 package unix
 
-import "unsafe"
+import (
+	"fmt"
+	"runtime"
+	"unsafe"
+)
 
 func bytes2iovec(bs [][]byte) []Iovec {
 	iovecs := make([]Iovec, len(bs))
@@ -76,15 +81,98 @@
 	return
 }
 
-//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
+//sys	putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
 
-func Pipe2(p []int, flags int) error {
-	if len(p) != 2 {
-		return EINVAL
+func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
+	var clp, datap *strbuf
+	if len(cl) > 0 {
+		clp = &strbuf{
+			Len: int32(len(cl)),
+			Buf: (*int8)(unsafe.Pointer(&cl[0])),
+		}
 	}
-	var pp [2]_C_int
-	err := pipe2(&pp, flags)
-	p[0] = int(pp[0])
-	p[1] = int(pp[1])
+	if len(data) > 0 {
+		datap = &strbuf{
+			Len: int32(len(data)),
+			Buf: (*int8)(unsafe.Pointer(&data[0])),
+		}
+	}
+	return putmsg(fd, clp, datap, flags)
+}
+
+//sys	getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
+
+func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
+	var clp, datap *strbuf
+	if len(cl) > 0 {
+		clp = &strbuf{
+			Maxlen: int32(len(cl)),
+			Buf:    (*int8)(unsafe.Pointer(&cl[0])),
+		}
+	}
+	if len(data) > 0 {
+		datap = &strbuf{
+			Maxlen: int32(len(data)),
+			Buf:    (*int8)(unsafe.Pointer(&data[0])),
+		}
+	}
+
+	if err = getmsg(fd, clp, datap, &flags); err != nil {
+		return nil, nil, 0, err
+	}
+
+	if len(cl) > 0 {
+		retCl = cl[:clp.Len]
+	}
+	if len(data) > 0 {
+		retData = data[:datap.Len]
+	}
+	return retCl, retData, flags, nil
+}
+
+func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
+	return ioctlRet(fd, req, uintptr(arg))
+}
+
+func IoctlSetString(fd int, req uint, val string) error {
+	bs := make([]byte, len(val)+1)
+	copy(bs[:len(bs)-1], val)
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
+	runtime.KeepAlive(&bs[0])
 	return err
 }
+
+// Lifreq Helpers
+
+func (l *Lifreq) SetName(name string) error {
+	if len(name) >= len(l.Name) {
+		return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
+	}
+	for i := range name {
+		l.Name[i] = int8(name[i])
+	}
+	return nil
+}
+
+func (l *Lifreq) SetLifruInt(d int) {
+	*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
+}
+
+func (l *Lifreq) GetLifruInt() int {
+	return *(*int)(unsafe.Pointer(&l.Lifru[0]))
+}
+
+func IoctlLifreq(fd int, req uint, l *Lifreq) error {
+	return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
+}
+
+// Strioctl Helpers
+
+func (s *Strioctl) SetInt(i int) {
+	s.Len = int32(unsafe.Sizeof(i))
+	s.Dp = (*int8)(unsafe.Pointer(&i))
+}
+
+func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
+	return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go
index 28be130..2dd7c8e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -70,88 +70,7 @@
 
 // ioctl itself should not be exposed directly, but additional get/set
 // functions for specific types are permissible.
-
-// IoctlRetInt performs an ioctl operation specified by req on a device
-// associated with opened file descriptor fd, and returns a non-negative
-// integer that is returned by the ioctl syscall.
-func IoctlRetInt(fd int, req uint) (int, error) {
-	ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0)
-	if err != 0 {
-		return 0, err
-	}
-	return int(ret), nil
-}
-
-func IoctlSetRTCTime(fd int, value *RTCTime) error {
-	err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value)))
-	runtime.KeepAlive(value)
-	return err
-}
-
-func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error {
-	err := ioctl(fd, RTC_WKALM_SET, uintptr(unsafe.Pointer(value)))
-	runtime.KeepAlive(value)
-	return err
-}
-
-func IoctlGetUint32(fd int, req uint) (uint32, error) {
-	var value uint32
-	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
-	return value, err
-}
-
-func IoctlGetRTCTime(fd int) (*RTCTime, error) {
-	var value RTCTime
-	err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value)))
-	return &value, err
-}
-
-// IoctlGetWatchdogInfo fetches information about a watchdog device from the
-// Linux watchdog API. For more information, see:
-// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
-func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) {
-	var value WatchdogInfo
-	err := ioctl(fd, WDIOC_GETSUPPORT, uintptr(unsafe.Pointer(&value)))
-	return &value, err
-}
-
-func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) {
-	var value RTCWkAlrm
-	err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value)))
-	return &value, err
-}
-
-// IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the
-// range of data conveyed in value to the file associated with the file
-// descriptor destFd. See the ioctl_ficlonerange(2) man page for details.
-func IoctlFileCloneRange(destFd int, value *FileCloneRange) error {
-	err := ioctl(destFd, FICLONERANGE, uintptr(unsafe.Pointer(value)))
-	runtime.KeepAlive(value)
-	return err
-}
-
-// IoctlFileClone performs an FICLONE ioctl operation to clone the entire file
-// associated with the file description srcFd to the file associated with the
-// file descriptor destFd. See the ioctl_ficlone(2) man page for details.
-func IoctlFileClone(destFd, srcFd int) error {
-	return ioctl(destFd, FICLONE, uintptr(srcFd))
-}
-
-// IoctlFileDedupeRange performs an FIDEDUPERANGE ioctl operation to share the
-// range of data conveyed in value with the file associated with the file
-// descriptor destFd. See the ioctl_fideduperange(2) man page for details.
-func IoctlFileDedupeRange(destFd int, value *FileDedupeRange) error {
-	err := ioctl(destFd, FIDEDUPERANGE, uintptr(unsafe.Pointer(value)))
-	runtime.KeepAlive(value)
-	return err
-}
-
-// IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For
-// more information, see:
-// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
-func IoctlWatchdogKeepalive(fd int) error {
-	return ioctl(fd, WDIOC_KEEPALIVE, 0)
-}
+// These are defined in ioctl.go and ioctl_linux.go.
 
 //sys	Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
 
@@ -778,16 +697,19 @@
 	// CID and Port specify a context ID and port address for a VM socket.
 	// Guests have a unique CID, and hosts may have a well-known CID of:
 	//  - VMADDR_CID_HYPERVISOR: refers to the hypervisor process.
+	//  - VMADDR_CID_LOCAL: refers to local communication (loopback).
 	//  - VMADDR_CID_HOST: refers to other processes on the host.
-	CID  uint32
-	Port uint32
-	raw  RawSockaddrVM
+	CID   uint32
+	Port  uint32
+	Flags uint8
+	raw   RawSockaddrVM
 }
 
 func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
 	sa.raw.Family = AF_VSOCK
 	sa.raw.Port = sa.Port
 	sa.raw.Cid = sa.CID
+	sa.raw.Flags = sa.Flags
 
 	return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
 }
@@ -1092,8 +1014,9 @@
 	case AF_VSOCK:
 		pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
 		sa := &SockaddrVM{
-			CID:  pp.Cid,
-			Port: pp.Port,
+			CID:   pp.Cid,
+			Port:  pp.Port,
+			Flags: pp.Flags,
 		}
 		return sa, nil
 	case AF_BLUETOOTH:
@@ -1228,7 +1151,11 @@
 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
 	var rsa RawSockaddrAny
 	var len _Socklen = SizeofSockaddrAny
-	nfd, err = accept(fd, &rsa, &len)
+	// Try accept4 first for Android, then try accept for kernel older than 2.6.28
+	nfd, err = accept4(fd, &rsa, &len, 0)
+	if err == ENOSYS {
+		nfd, err = accept(fd, &rsa, &len)
+	}
 	if err != nil {
 		return
 	}
@@ -1482,8 +1409,8 @@
 	return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction)
 }
 
-//sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL
-//sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL
+//sys	keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL
+//sys	keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL
 
 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
 	var msg Msghdr
@@ -1798,6 +1725,7 @@
 //sys	ClockGettime(clockid int32, time *Timespec) (err error)
 //sys	ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error)
 //sys	Close(fd int) (err error)
+//sys	CloseRange(first uint, last uint, flags uint) (err error)
 //sys	CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
 //sys	DeleteModule(name string, flags int) (err error)
 //sys	Dup(oldfd int) (fd int, err error)
@@ -1860,8 +1788,8 @@
 //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
 //sys	PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)
 //sys	PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
-//sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
-//sys   Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
+//sysnb	prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
+//sys	Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
 //sys	Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6
 //sys	read(fd int, p []byte) (n int, err error)
 //sys	Removexattr(path string, attr string) (err error)
@@ -1934,9 +1862,9 @@
 //sys	Syncfs(fd int) (err error)
 //sysnb	Sysinfo(info *Sysinfo_t) (err error)
 //sys	Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
-//sysnb TimerfdCreate(clockid int, flags int) (fd int, err error)
-//sysnb TimerfdGettime(fd int, currValue *ItimerSpec) (err error)
-//sysnb TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error)
+//sysnb	TimerfdCreate(clockid int, flags int) (fd int, err error)
+//sysnb	TimerfdGettime(fd int, currValue *ItimerSpec) (err error)
+//sysnb	TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error)
 //sysnb	Tgkill(tgid int, tid int, sig syscall.Signal) (err error)
 //sysnb	Times(tms *Tms) (ticks uintptr, err error)
 //sysnb	Umask(mask int) (oldmask int)
@@ -2196,8 +2124,8 @@
 	return EACCES
 }
 
-//sys nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT
-//sys openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT
+//sys	nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT
+//sys	openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT
 
 // fileHandle is the argument to nameToHandleAt and openByHandleAt. We
 // originally tried to generate it via unix/linux/types.go with "type
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go
index c97c2ee..7b52e5d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 && linux
 // +build 386,linux
 
 package unix
@@ -31,7 +32,7 @@
 	return
 }
 
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
 
 func Pipe2(p []int, flags int) (err error) {
 	if len(p) != 2 {
@@ -98,7 +99,7 @@
 	Max uint32
 }
 
-//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
+//sysnb	getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
 
 const rlimInf32 = ^uint32(0)
 const rlimInf64 = ^uint64(0)
@@ -129,7 +130,7 @@
 	return
 }
 
-//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
+//sysnb	setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
 
 func Setrlimit(resource int, rlim *Rlimit) (err error) {
 	err = prlimit(0, resource, rlim, nil)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
index 72efe86..28b7641 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 && linux
 // +build amd64,linux
 
 package unix
@@ -138,7 +139,7 @@
 	return
 }
 
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
 
 func Pipe2(p []int, flags int) (err error) {
 	if len(p) != 2 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go
index baa771f..8b0f0f3 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build amd64,linux
-// +build gc
+//go:build amd64 && linux && gc
+// +build amd64,linux,gc
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
index 496837b..6887772 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm && linux
 // +build arm,linux
 
 package unix
@@ -35,7 +36,7 @@
 	return
 }
 
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
 
 func Pipe2(p []int, flags int) (err error) {
 	if len(p) != 2 {
@@ -129,8 +130,8 @@
 
 //sys	utimes(path string, times *[2]Timeval) (err error)
 
-//sys   Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
-//sys   Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
+//sys	Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
+//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
 //sys	Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
 //sys	Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
 
@@ -177,7 +178,7 @@
 	Max uint32
 }
 
-//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_UGETRLIMIT
+//sysnb	getrlimit(resource int, rlim *rlimit32) (err error) = SYS_UGETRLIMIT
 
 const rlimInf32 = ^uint32(0)
 const rlimInf64 = ^uint64(0)
@@ -208,7 +209,7 @@
 	return
 }
 
-//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
+//sysnb	setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
 
 func Setrlimit(resource int, rlim *Rlimit) (err error) {
 	err = prlimit(0, resource, rlim, nil)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
index c6de6b9..7ed7034 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm64 && linux
 // +build arm64,linux
 
 package unix
@@ -155,7 +156,7 @@
 	return
 }
 
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
 
 func Pipe2(p []int, flags int) (err error) {
 	if len(p) != 2 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc.go
index 9edf396..2b1168d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && gc
 // +build linux,gc
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go
index 90e33d8..9843fb4 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && gc && 386
 // +build linux,gc,386
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go
index 1a97baa..a6008fc 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm && gc && linux
 // +build arm,gc,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go
index 308eb7a..7740af2 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && gccgo && 386
 // +build linux,gccgo,386
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go
index aa7fc9e..e16a122 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && gccgo && arm
 // +build linux,gccgo,arm
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
index f028747..06dec06 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips64 || mips64le)
 // +build linux
 // +build mips64 mips64le
 
@@ -104,7 +105,7 @@
 	return
 }
 
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
 
 func Pipe2(p []int, flags int) (err error) {
 	if len(p) != 2 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
index c113281..8f0d0a5 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips || mipsle)
 // +build linux
 // +build mips mipsle
 
@@ -112,7 +113,7 @@
 	return Timeval{Sec: int32(sec), Usec: int32(usec)}
 }
 
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
 
 func Pipe2(p []int, flags int) (err error) {
 	if len(p) != 2 {
@@ -125,7 +126,7 @@
 	return
 }
 
-//sysnb pipe() (p1 int, p2 int, err error)
+//sysnb	pipe() (p1 int, p2 int, err error)
 
 func Pipe(p []int) (err error) {
 	if len(p) != 2 {
@@ -153,7 +154,7 @@
 	Max uint32
 }
 
-//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
+//sysnb	getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
 
 func Getrlimit(resource int, rlim *Rlimit) (err error) {
 	err = prlimit(0, resource, nil, rlim)
@@ -181,7 +182,7 @@
 	return
 }
 
-//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
+//sysnb	setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
 
 func Setrlimit(resource int, rlim *Rlimit) (err error) {
 	err = prlimit(0, resource, rlim, nil)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
new file mode 100644
index 0000000..7e65e08
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
@@ -0,0 +1,272 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && ppc
+// +build linux
+// +build ppc
+
+package unix
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+//sys	dup2(oldfd int, newfd int) (err error)
+//sysnb	EpollCreate(size int) (fd int, err error)
+//sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
+//sys	Fchown(fd int, uid int, gid int) (err error)
+//sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
+//sys	Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
+//sys	Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
+//sysnb	Getegid() (egid int)
+//sysnb	Geteuid() (euid int)
+//sysnb	Getgid() (gid int)
+//sysnb	Getuid() (uid int)
+//sysnb	InotifyInit() (fd int, err error)
+//sys	Ioperm(from int, num int, on int) (err error)
+//sys	Iopl(level int) (err error)
+//sys	Lchown(path string, uid int, gid int) (err error)
+//sys	Listen(s int, n int) (err error)
+//sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
+//sys	Pause() (err error)
+//sys	Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
+//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
+//sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (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_SENDFILE64
+//sys	setfsgid(gid int) (prev int, err error)
+//sys	setfsuid(uid int) (prev int, err error)
+//sysnb	Setregid(rgid int, egid int) (err error)
+//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
+//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
+//sysnb	Setreuid(ruid int, euid int) (err error)
+//sys	Shutdown(fd int, how int) (err error)
+//sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
+//sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
+//sys	Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
+//sys	Ustat(dev int, ubuf *Ustat_t) (err error)
+//sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
+//sys	accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
+//sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
+//sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
+//sysnb	getgroups(n int, list *_Gid_t) (nn int, err error)
+//sysnb	setgroups(n int, list *_Gid_t) (err error)
+//sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
+//sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
+//sysnb	socket(domain int, typ int, proto int) (fd int, err error)
+//sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
+//sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
+//sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
+//sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
+//sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
+//sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
+//sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
+
+//sys	futimesat(dirfd int, path string, times *[2]Timeval) (err error)
+//sysnb	Gettimeofday(tv *Timeval) (err error)
+//sysnb	Time(t *Time_t) (tt Time_t, err error)
+//sys	Utime(path string, buf *Utimbuf) (err error)
+//sys	utimes(path string, times *[2]Timeval) (err error)
+
+func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
+	_, _, e1 := Syscall6(SYS_FADVISE64_64, uintptr(fd), uintptr(advice), uintptr(offset>>32), uintptr(offset), uintptr(length>>32), uintptr(length))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func seek(fd int, offset int64, whence int) (int64, syscall.Errno) {
+	var newoffset int64
+	offsetLow := uint32(offset & 0xffffffff)
+	offsetHigh := uint32((offset >> 32) & 0xffffffff)
+	_, _, err := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0)
+	return newoffset, err
+}
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	newoffset, errno := seek(fd, offset, whence)
+	if errno != 0 {
+		return 0, errno
+	}
+	return newoffset, nil
+}
+
+func Fstatfs(fd int, buf *Statfs_t) (err error) {
+	_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func Statfs(path string, buf *Statfs_t) (err error) {
+	pathp, err := BytePtrFromString(path)
+	if err != nil {
+		return err
+	}
+	_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+//sys	mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
+
+func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
+	page := uintptr(offset / 4096)
+	if offset != int64(page)*4096 {
+		return 0, EINVAL
+	}
+	return mmap2(addr, length, prot, flags, fd, page)
+}
+
+func setTimespec(sec, nsec int64) Timespec {
+	return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
+}
+
+func setTimeval(sec, usec int64) Timeval {
+	return Timeval{Sec: int32(sec), Usec: int32(usec)}
+}
+
+type rlimit32 struct {
+	Cur uint32
+	Max uint32
+}
+
+//sysnb	getrlimit(resource int, rlim *rlimit32) (err error) = SYS_UGETRLIMIT
+
+const rlimInf32 = ^uint32(0)
+const rlimInf64 = ^uint64(0)
+
+func Getrlimit(resource int, rlim *Rlimit) (err error) {
+	err = prlimit(0, resource, nil, rlim)
+	if err != ENOSYS {
+		return err
+	}
+
+	rl := rlimit32{}
+	err = getrlimit(resource, &rl)
+	if err != nil {
+		return
+	}
+
+	if rl.Cur == rlimInf32 {
+		rlim.Cur = rlimInf64
+	} else {
+		rlim.Cur = uint64(rl.Cur)
+	}
+
+	if rl.Max == rlimInf32 {
+		rlim.Max = rlimInf64
+	} else {
+		rlim.Max = uint64(rl.Max)
+	}
+	return
+}
+
+//sysnb	setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
+
+func Setrlimit(resource int, rlim *Rlimit) (err error) {
+	err = prlimit(0, resource, rlim, nil)
+	if err != ENOSYS {
+		return err
+	}
+
+	rl := rlimit32{}
+	if rlim.Cur == rlimInf64 {
+		rl.Cur = rlimInf32
+	} else if rlim.Cur < uint64(rlimInf32) {
+		rl.Cur = uint32(rlim.Cur)
+	} else {
+		return EINVAL
+	}
+	if rlim.Max == rlimInf64 {
+		rl.Max = rlimInf32
+	} else if rlim.Max < uint64(rlimInf32) {
+		rl.Max = uint32(rlim.Max)
+	} else {
+		return EINVAL
+	}
+
+	return setrlimit(resource, &rl)
+}
+
+func (r *PtraceRegs) PC() uint32 { return r.Nip }
+
+func (r *PtraceRegs) SetPC(pc uint32) { r.Nip = pc }
+
+func (iov *Iovec) SetLen(length int) {
+	iov.Len = uint32(length)
+}
+
+func (msghdr *Msghdr) SetControllen(length int) {
+	msghdr.Controllen = uint32(length)
+}
+
+func (msghdr *Msghdr) SetIovlen(length int) {
+	msghdr.Iovlen = uint32(length)
+}
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+	cmsg.Len = uint32(length)
+}
+
+//sysnb	pipe(p *[2]_C_int) (err error)
+
+func Pipe(p []int) (err error) {
+	if len(p) != 2 {
+		return EINVAL
+	}
+	var pp [2]_C_int
+	err = pipe(&pp)
+	p[0] = int(pp[0])
+	p[1] = int(pp[1])
+	return
+}
+
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
+
+func Pipe2(p []int, flags int) (err error) {
+	if len(p) != 2 {
+		return EINVAL
+	}
+	var pp [2]_C_int
+	err = pipe2(&pp, flags)
+	p[0] = int(pp[0])
+	p[1] = int(pp[1])
+	return
+}
+
+//sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
+
+func Poll(fds []PollFd, timeout int) (n int, err error) {
+	if len(fds) == 0 {
+		return poll(nil, 0, timeout)
+	}
+	return poll(&fds[0], len(fds), timeout)
+}
+
+//sys	syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
+
+func SyncFileRange(fd int, off int64, n int64, flags int) error {
+	// The sync_file_range and sync_file_range2 syscalls differ only in the
+	// order of their arguments.
+	return syncFileRange2(fd, flags, off, n)
+}
+
+//sys	kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
+
+func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
+	cmdlineLen := len(cmdline)
+	if cmdlineLen > 0 {
+		// Account for the additional NULL byte added by
+		// BytePtrFromString in kexecFileLoad. The kexec_file_load
+		// syscall expects a NULL-terminated string.
+		cmdlineLen++
+	}
+	return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
index 3493744..0b1f0d6 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (ppc64 || ppc64le)
 // +build linux
 // +build ppc64 ppc64le
 
@@ -99,7 +100,7 @@
 	cmsg.Len = uint64(length)
 }
 
-//sysnb pipe(p *[2]_C_int) (err error)
+//sysnb	pipe(p *[2]_C_int) (err error)
 
 func Pipe(p []int) (err error) {
 	if len(p) != 2 {
@@ -112,7 +113,7 @@
 	return
 }
 
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
 
 func Pipe2(p []int, flags int) (err error) {
 	if len(p) != 2 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
index b0b1505..ce9bcd3 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build riscv64 && linux
 // +build riscv64,linux
 
 package unix
@@ -154,7 +155,7 @@
 	return
 }
 
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
 
 func Pipe2(p []int, flags int) (err error) {
 	if len(p) != 2 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
index 2363f74..a1e4569 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build s390x && linux
 // +build s390x,linux
 
 package unix
@@ -76,7 +77,7 @@
 	return Timeval{Sec: sec, Usec: usec}
 }
 
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
 
 func Pipe(p []int) (err error) {
 	if len(p) != 2 {
@@ -249,7 +250,7 @@
 }
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) error {
-	args := [4]uintptr{uintptr(s), uintptr(level), uintptr(name), uintptr(val)}
+	args := [5]uintptr{uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen}
 	_, _, err := Syscall(SYS_SOCKETCALL, netSetSockOpt, uintptr(unsafe.Pointer(&args)), 0)
 	if err != 0 {
 		return err
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
index d389f15..49055a3 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build sparc64 && linux
 // +build sparc64,linux
 
 package unix
@@ -115,7 +116,7 @@
 	cmsg.Len = uint64(length)
 }
 
-//sysnb pipe(p *[2]_C_int) (err error)
+//sysnb	pipe(p *[2]_C_int) (err error)
 
 func Pipe(p []int) (err error) {
 	if len(p) != 2 {
@@ -128,7 +129,7 @@
 	return
 }
 
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
 
 func Pipe2(p []int, flags int) (err error) {
 	if len(p) != 2 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd.go
index 1e6843b..853d5f0 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd.go
@@ -110,7 +110,8 @@
 	return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
 }
 
-//sysnb pipe() (fd1 int, fd2 int, err error)
+//sysnb	pipe() (fd1 int, fd2 int, err error)
+
 func Pipe(p []int) (err error) {
 	if len(p) != 2 {
 		return EINVAL
@@ -119,7 +120,21 @@
 	return
 }
 
-//sys Getdents(fd int, buf []byte) (n int, err error)
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
+
+func Pipe2(p []int, flags int) error {
+	if len(p) != 2 {
+		return EINVAL
+	}
+	var pp [2]_C_int
+	err := pipe2(&pp, flags)
+	p[0] = int(pp[0])
+	p[1] = int(pp[1])
+	return err
+}
+
+//sys	Getdents(fd int, buf []byte) (n int, err error)
+
 func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
 	n, err = Getdents(fd, buf)
 	if err != nil || basep == nil {
@@ -159,7 +174,7 @@
 
 //sys	ioctl(fd int, req uint, arg uintptr) (err error)
 
-//sys   sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
+//sys	sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
 
 func IoctlGetPtmget(fd int, req uint) (*Ptmget, error) {
 	var value Ptmget
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_386.go
index 24da8b5..5199d28 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_386.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 && netbsd
 // +build 386,netbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go
index 25a0ac8..70a9c52 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 && netbsd
 // +build amd64,netbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go
index 21591ec..3eb5942 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm && netbsd
 // +build arm,netbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_arm64.go
index 8047496..fc6ccfd 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd_arm64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm64 && netbsd
 // +build arm64,netbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd.go
index 6a50b50..22b5503 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd.go
@@ -92,7 +92,7 @@
 	return err
 }
 
-//sys Getdents(fd int, buf []byte) (n int, err error)
+//sys	Getdents(fd int, buf []byte) (n int, err error)
 func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
 	n, err = Getdents(fd, buf)
 	if err != nil || basep == nil {
@@ -154,7 +154,7 @@
 
 //sys	ioctl(fd int, req uint, arg uintptr) (err error)
 
-//sys   sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
+//sys	sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
 
 //sys	ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go
index 42b5a0e..6baabcd 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 && openbsd
 // +build 386,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go
index 6ea4b48..bab2536 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 && openbsd
 // +build amd64,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go
index 1c3d26f..8eed3c4 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm && openbsd
 // +build arm,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go
index a8c458c..483dde9 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm64 && openbsd
 // +build arm64,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go
index fee6e99..77fcde7 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go
@@ -68,6 +68,19 @@
 	return nil
 }
 
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
+
+func Pipe2(p []int, flags int) error {
+	if len(p) != 2 {
+		return EINVAL
+	}
+	var pp [2]_C_int
+	err := pipe2(&pp, flags)
+	p[0] = int(pp[0])
+	p[1] = int(pp[1])
+	return err
+}
+
 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
 	if sa.Port < 0 || sa.Port > 0xFFFF {
 		return nil, 0, EINVAL
@@ -552,7 +565,12 @@
  * Expose the ioctl function
  */
 
-//sys	ioctl(fd int, req uint, arg uintptr) (err error)
+//sys	ioctlRet(fd int, req uint, arg uintptr) (ret int, err error) = libc.ioctl
+
+func ioctl(fd int, req uint, arg uintptr) (err error) {
+	_, err = ioctlRet(fd, req, arg)
+	return err
+}
 
 func IoctlSetTermio(fd int, req uint, value *Termio) error {
 	err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
@@ -566,7 +584,7 @@
 	return &value, err
 }
 
-//sys   poll(fds *PollFd, nfds int, timeout int) (n int, err error)
+//sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
 
 func Poll(fds []PollFd, timeout int) (n int, err error) {
 	if len(fds) == 0 {
@@ -669,6 +687,7 @@
 //sys	Statvfs(path string, vfsstat *Statvfs_t) (err error)
 //sys	Symlink(path string, link string) (err error)
 //sys	Sync() (err error)
+//sys	Sysconf(which int) (n int64, err error)
 //sysnb	Times(tms *Tms) (ticks uintptr, err error)
 //sys	Truncate(path string, length int64) (err error)
 //sys	Fsync(fd int) (err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go
index b22a34d..0bd25ef 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 && solaris
 // +build amd64,solaris
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix.go
index 400ba9f..a7618ce 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go
index 87bd161..5898e9a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go
@@ -2,8 +2,11 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris) && gc && !ppc64le && !ppc64
 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
-// +build gc,!ppc64le,!ppc64
+// +build gc
+// +build !ppc64le
+// +build !ppc64
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go
index d36216c..f6f707a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (ppc64le || ppc64) && gc
 // +build linux
 // +build ppc64le ppc64
 // +build gc
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
new file mode 100644
index 0000000..1ffd8bf
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
@@ -0,0 +1,1829 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+package unix
+
+import (
+	"bytes"
+	"runtime"
+	"sort"
+	"sync"
+	"syscall"
+	"unsafe"
+)
+
+const (
+	O_CLOEXEC = 0       // Dummy value (not supported).
+	AF_LOCAL  = AF_UNIX // AF_LOCAL is an alias for AF_UNIX
+)
+
+func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+func syscall_syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+func syscall_rawsyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+func syscall_syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
+func syscall_rawsyscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
+
+func copyStat(stat *Stat_t, statLE *Stat_LE_t) {
+	stat.Dev = uint64(statLE.Dev)
+	stat.Ino = uint64(statLE.Ino)
+	stat.Nlink = uint64(statLE.Nlink)
+	stat.Mode = uint32(statLE.Mode)
+	stat.Uid = uint32(statLE.Uid)
+	stat.Gid = uint32(statLE.Gid)
+	stat.Rdev = uint64(statLE.Rdev)
+	stat.Size = statLE.Size
+	stat.Atim.Sec = int64(statLE.Atim)
+	stat.Atim.Nsec = 0 //zos doesn't return nanoseconds
+	stat.Mtim.Sec = int64(statLE.Mtim)
+	stat.Mtim.Nsec = 0 //zos doesn't return nanoseconds
+	stat.Ctim.Sec = int64(statLE.Ctim)
+	stat.Ctim.Nsec = 0 //zos doesn't return nanoseconds
+	stat.Blksize = int64(statLE.Blksize)
+	stat.Blocks = statLE.Blocks
+}
+
+func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
+func svcLoad(name *byte) unsafe.Pointer
+func svcUnload(name *byte, fnptr unsafe.Pointer) int64
+
+func (d *Dirent) NameString() string {
+	if d == nil {
+		return ""
+	}
+	return string(d.Name[:d.Namlen])
+}
+
+func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Len = SizeofSockaddrInet4
+	sa.raw.Family = AF_INET
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+	p[0] = byte(sa.Port >> 8)
+	p[1] = byte(sa.Port)
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
+}
+
+func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Len = SizeofSockaddrInet6
+	sa.raw.Family = AF_INET6
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+	p[0] = byte(sa.Port >> 8)
+	p[1] = byte(sa.Port)
+	sa.raw.Scope_id = sa.ZoneId
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
+}
+
+func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	name := sa.Name
+	n := len(name)
+	if n >= len(sa.raw.Path) || n == 0 {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
+	sa.raw.Family = AF_UNIX
+	for i := 0; i < n; i++ {
+		sa.raw.Path[i] = int8(name[i])
+	}
+	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
+}
+
+func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
+	// TODO(neeilan): Implement use of first param (fd)
+	switch rsa.Addr.Family {
+	case AF_UNIX:
+		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
+		sa := new(SockaddrUnix)
+		// For z/OS, only replace NUL with @ when the
+		// length is not zero.
+		if pp.Len != 0 && pp.Path[0] == 0 {
+			// "Abstract" Unix domain socket.
+			// Rewrite leading NUL as @ for textual display.
+			// (This is the standard convention.)
+			// Not friendly to overwrite in place,
+			// but the callers below don't care.
+			pp.Path[0] = '@'
+		}
+
+		// Assume path ends at NUL.
+		//
+		// For z/OS, the length of the name is a field
+		// in the structure. To be on the safe side, we
+		// will still scan the name for a NUL but only
+		// to the length provided in the structure.
+		//
+		// This is not technically the Linux semantics for
+		// abstract Unix domain sockets--they are supposed
+		// to be uninterpreted fixed-size binary blobs--but
+		// everyone uses this convention.
+		n := 0
+		for n < int(pp.Len) && pp.Path[n] != 0 {
+			n++
+		}
+		bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
+		sa.Name = string(bytes)
+		return sa, nil
+
+	case AF_INET:
+		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
+		sa := new(SockaddrInet4)
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+		sa.Port = int(p[0])<<8 + int(p[1])
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+
+	case AF_INET6:
+		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
+		sa := new(SockaddrInet6)
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+		sa.Port = int(p[0])<<8 + int(p[1])
+		sa.ZoneId = pp.Scope_id
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+	}
+	return nil, EAFNOSUPPORT
+}
+
+func Accept(fd int) (nfd int, sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	nfd, err = accept(fd, &rsa, &len)
+	if err != nil {
+		return
+	}
+	// TODO(neeilan): Remove 0 in call
+	sa, err = anyToSockaddr(0, &rsa)
+	if err != nil {
+		Close(nfd)
+		nfd = 0
+	}
+	return
+}
+
+func (iov *Iovec) SetLen(length int) {
+	iov.Len = uint64(length)
+}
+
+func (msghdr *Msghdr) SetControllen(length int) {
+	msghdr.Controllen = int32(length)
+}
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+	cmsg.Len = int32(length)
+}
+
+//sys   fcntl(fd int, cmd int, arg int) (val int, err error)
+//sys	read(fd int, p []byte) (n int, err error)
+//sys   readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
+//sys	write(fd int, p []byte) (n int, err error)
+
+//sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = SYS___ACCEPT_A
+//sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___BIND_A
+//sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___CONNECT_A
+//sysnb	getgroups(n int, list *_Gid_t) (nn int, err error)
+//sysnb	setgroups(n int, list *_Gid_t) (err error)
+//sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
+//sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
+//sysnb	socket(domain int, typ int, proto int) (fd int, err error)
+//sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
+//sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETPEERNAME_A
+//sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETSOCKNAME_A
+//sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = SYS___RECVFROM_A
+//sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = SYS___SENDTO_A
+//sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___RECVMSG_A
+//sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___SENDMSG_A
+//sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) = SYS_MMAP
+//sys   munmap(addr uintptr, length uintptr) (err error) = SYS_MUNMAP
+//sys   ioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL
+
+//sys   Access(path string, mode uint32) (err error) = SYS___ACCESS_A
+//sys   Chdir(path string) (err error) = SYS___CHDIR_A
+//sys	Chown(path string, uid int, gid int) (err error) = SYS___CHOWN_A
+//sys	Chmod(path string, mode uint32) (err error) = SYS___CHMOD_A
+//sys   Creat(path string, mode uint32) (fd int, err error) = SYS___CREAT_A
+//sys	Dup(oldfd int) (fd int, err error)
+//sys	Dup2(oldfd int, newfd int) (err error)
+//sys	Errno2() (er2 int) = SYS___ERRNO2
+//sys	Err2ad() (eadd *int) = SYS___ERR2AD
+//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)
+//sys	FcntlInt(fd uintptr, cmd int, arg int) (retval int, err error) = SYS_FCNTL
+//sys	fstat(fd int, stat *Stat_LE_t) (err error)
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	var statLE Stat_LE_t
+	err = fstat(fd, &statLE)
+	copyStat(stat, &statLE)
+	return
+}
+
+//sys	Fstatvfs(fd int, stat *Statvfs_t) (err error) = SYS_FSTATVFS
+//sys	Fsync(fd int) (err error)
+//sys	Ftruncate(fd int, length int64) (err error)
+//sys   Getpagesize() (pgsize int) = SYS_GETPAGESIZE
+//sys   Mprotect(b []byte, prot int) (err error) = SYS_MPROTECT
+//sys   Msync(b []byte, flags int) (err error) = SYS_MSYNC
+//sys   Poll(fds []PollFd, timeout int) (n int, err error) = SYS_POLL
+//sys   Times(tms *Tms) (ticks uintptr, err error) = SYS_TIMES
+//sys   W_Getmntent(buff *byte, size int) (lastsys int, err error) = SYS_W_GETMNTENT
+//sys   W_Getmntent_A(buff *byte, size int) (lastsys int, err error) = SYS___W_GETMNTENT_A
+
+//sys   mount_LE(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) = SYS___MOUNT_A
+//sys   unmount(filesystem string, mtm int) (err error) = SYS___UMOUNT_A
+//sys   Chroot(path string) (err error) = SYS___CHROOT_A
+//sys   Select(nmsgsfds int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (ret int, err error) = SYS_SELECT
+//sysnb Uname(buf *Utsname) (err error) = SYS___UNAME_A
+
+func Ptsname(fd int) (name string, err error) {
+	r0, _, e1 := syscall_syscall(SYS___PTSNAME_A, uintptr(fd), 0, 0)
+	name = u2s(unsafe.Pointer(r0))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func u2s(cstr unsafe.Pointer) string {
+	str := (*[1024]uint8)(cstr)
+	i := 0
+	for str[i] != 0 {
+		i++
+	}
+	return string(str[:i])
+}
+
+func Close(fd int) (err error) {
+	_, _, e1 := syscall_syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	for i := 0; e1 == EAGAIN && i < 10; i++ {
+		_, _, _ = syscall_syscall(SYS_USLEEP, uintptr(10), 0, 0)
+		_, _, e1 = syscall_syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	}
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var mapper = &mmapper{
+	active: make(map[*byte][]byte),
+	mmap:   mmap,
+	munmap: munmap,
+}
+
+// Dummy function: there are no semantics for Madvise on z/OS
+func Madvise(b []byte, advice int) (err error) {
+	return
+}
+
+func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
+	return mapper.Mmap(fd, offset, length, prot, flags)
+}
+
+func Munmap(b []byte) (err error) {
+	return mapper.Munmap(b)
+}
+
+//sys   Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A
+//sysnb	Getegid() (egid int)
+//sysnb	Geteuid() (uid int)
+//sysnb	Getgid() (gid int)
+//sysnb	Getpid() (pid int)
+//sysnb	Getpgid(pid int) (pgid int, err error) = SYS_GETPGID
+
+func Getpgrp() (pid int) {
+	pid, _ = Getpgid(0)
+	return
+}
+
+//sysnb	Getppid() (pid int)
+//sys	Getpriority(which int, who int) (prio int, err error)
+//sysnb	Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_GETRLIMIT
+
+//sysnb getrusage(who int, rusage *rusage_zos) (err error) = SYS_GETRUSAGE
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	var ruz rusage_zos
+	err = getrusage(who, &ruz)
+	//Only the first two fields of Rusage are set
+	rusage.Utime.Sec = ruz.Utime.Sec
+	rusage.Utime.Usec = int64(ruz.Utime.Usec)
+	rusage.Stime.Sec = ruz.Stime.Sec
+	rusage.Stime.Usec = int64(ruz.Stime.Usec)
+	return
+}
+
+//sysnb Getsid(pid int) (sid int, err error) = SYS_GETSID
+//sysnb	Getuid() (uid int)
+//sysnb	Kill(pid int, sig Signal) (err error)
+//sys	Lchown(path string, uid int, gid int) (err error) = SYS___LCHOWN_A
+//sys	Link(path string, link string) (err error) = SYS___LINK_A
+//sys	Listen(s int, n int) (err error)
+//sys	lstat(path string, stat *Stat_LE_t) (err error) = SYS___LSTAT_A
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var statLE Stat_LE_t
+	err = lstat(path, &statLE)
+	copyStat(stat, &statLE)
+	return
+}
+
+//sys	Mkdir(path string, mode uint32) (err error) = SYS___MKDIR_A
+//sys   Mkfifo(path string, mode uint32) (err error) = SYS___MKFIFO_A
+//sys	Mknod(path string, mode uint32, dev int) (err error) = SYS___MKNOD_A
+//sys	Pread(fd int, p []byte, offset int64) (n int, err error)
+//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
+//sys	Readlink(path string, buf []byte) (n int, err error) = SYS___READLINK_A
+//sys	Rename(from string, to string) (err error) = SYS___RENAME_A
+//sys	Rmdir(path string) (err error) = SYS___RMDIR_A
+//sys   Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
+//sys	Setpriority(which int, who int, prio int) (err error)
+//sysnb	Setpgid(pid int, pgid int) (err error) = SYS_SETPGID
+//sysnb	Setrlimit(resource int, lim *Rlimit) (err error)
+//sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID
+//sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID
+//sysnb	Setsid() (pid int, err error) = SYS_SETSID
+//sys	Setuid(uid int) (err error) = SYS_SETUID
+//sys	Setgid(uid int) (err error) = SYS_SETGID
+//sys	Shutdown(fd int, how int) (err error)
+//sys	stat(path string, statLE *Stat_LE_t) (err error) = SYS___STAT_A
+
+func Stat(path string, sta *Stat_t) (err error) {
+	var statLE Stat_LE_t
+	err = stat(path, &statLE)
+	copyStat(sta, &statLE)
+	return
+}
+
+//sys	Symlink(path string, link string) (err error) = SYS___SYMLINK_A
+//sys	Sync() = SYS_SYNC
+//sys	Truncate(path string, length int64) (err error) = SYS___TRUNCATE_A
+//sys	Tcgetattr(fildes int, termptr *Termios) (err error) = SYS_TCGETATTR
+//sys	Tcsetattr(fildes int, when int, termptr *Termios) (err error) = SYS_TCSETATTR
+//sys	Umask(mask int) (oldmask int)
+//sys	Unlink(path string) (err error) = SYS___UNLINK_A
+//sys	Utime(path string, utim *Utimbuf) (err error) = SYS___UTIME_A
+
+//sys	open(path string, mode int, perm uint32) (fd int, err error) = SYS___OPEN_A
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	return open(path, mode, perm)
+}
+
+func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
+	wd, err := Getwd()
+	if err != nil {
+		return err
+	}
+
+	if err := Fchdir(dirfd); err != nil {
+		return err
+	}
+	defer Chdir(wd)
+
+	return Mkfifo(path, mode)
+}
+
+//sys	remove(path string) (err error)
+
+func Remove(path string) error {
+	return remove(path)
+}
+
+const ImplementsGetwd = true
+
+func Getcwd(buf []byte) (n int, err error) {
+	var p unsafe.Pointer
+	if len(buf) > 0 {
+		p = unsafe.Pointer(&buf[0])
+	} else {
+		p = unsafe.Pointer(&_zero)
+	}
+	_, _, e := syscall_syscall(SYS___GETCWD_A, uintptr(p), uintptr(len(buf)), 0)
+	n = clen(buf) + 1
+	if e != 0 {
+		err = errnoErr(e)
+	}
+	return
+}
+
+func Getwd() (wd string, err error) {
+	var buf [PathMax]byte
+	n, err := Getcwd(buf[0:])
+	if err != nil {
+		return "", err
+	}
+	// Getcwd returns the number of bytes written to buf, including the NUL.
+	if n < 1 || n > len(buf) || buf[n-1] != 0 {
+		return "", EINVAL
+	}
+	return string(buf[0 : n-1]), nil
+}
+
+func Getgroups() (gids []int, err error) {
+	n, err := getgroups(0, nil)
+	if err != nil {
+		return nil, err
+	}
+	if n == 0 {
+		return nil, nil
+	}
+
+	// Sanity check group count.  Max is 1<<16 on Linux.
+	if n < 0 || n > 1<<20 {
+		return nil, EINVAL
+	}
+
+	a := make([]_Gid_t, n)
+	n, err = getgroups(n, &a[0])
+	if err != nil {
+		return nil, err
+	}
+	gids = make([]int, n)
+	for i, v := range a[0:n] {
+		gids[i] = int(v)
+	}
+	return
+}
+
+func Setgroups(gids []int) (err error) {
+	if len(gids) == 0 {
+		return setgroups(0, nil)
+	}
+
+	a := make([]_Gid_t, len(gids))
+	for i, v := range gids {
+		a[i] = _Gid_t(v)
+	}
+	return setgroups(len(a), &a[0])
+}
+
+func gettid() uint64
+
+func Gettid() (tid int) {
+	return int(gettid())
+}
+
+type WaitStatus uint32
+
+// Wait status is 7 bits at bottom, either 0 (exited),
+// 0x7F (stopped), or a signal number that caused an exit.
+// The 0x80 bit is whether there was a core dump.
+// An extra number (exit code, signal causing a stop)
+// is in the high bits.  At least that's the idea.
+// There are various irregularities.  For example, the
+// "continued" status is 0xFFFF, distinguishing itself
+// from stopped via the core dump bit.
+
+const (
+	mask    = 0x7F
+	core    = 0x80
+	exited  = 0x00
+	stopped = 0x7F
+	shift   = 8
+)
+
+func (w WaitStatus) Exited() bool { return w&mask == exited }
+
+func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
+
+func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
+
+func (w WaitStatus) Continued() bool { return w == 0xFFFF }
+
+func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
+
+func (w WaitStatus) ExitStatus() int {
+	if !w.Exited() {
+		return -1
+	}
+	return int(w>>shift) & 0xFF
+}
+
+func (w WaitStatus) Signal() Signal {
+	if !w.Signaled() {
+		return -1
+	}
+	return Signal(w & mask)
+}
+
+func (w WaitStatus) StopSignal() Signal {
+	if !w.Stopped() {
+		return -1
+	}
+	return Signal(w>>shift) & 0xFF
+}
+
+func (w WaitStatus) TrapCause() int { return -1 }
+
+//sys	waitpid(pid int, wstatus *_C_int, options int) (wpid int, err error)
+
+func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
+	// TODO(mundaym): z/OS doesn't have wait4. I don't think getrusage does what we want.
+	// At the moment rusage will not be touched.
+	var status _C_int
+	wpid, err = waitpid(pid, &status, options)
+	if wstatus != nil {
+		*wstatus = WaitStatus(status)
+	}
+	return
+}
+
+//sysnb	gettimeofday(tv *timeval_zos) (err error)
+
+func Gettimeofday(tv *Timeval) (err error) {
+	var tvz timeval_zos
+	err = gettimeofday(&tvz)
+	tv.Sec = tvz.Sec
+	tv.Usec = int64(tvz.Usec)
+	return
+}
+
+func Time(t *Time_t) (tt Time_t, err error) {
+	var tv Timeval
+	err = Gettimeofday(&tv)
+	if err != nil {
+		return 0, err
+	}
+	if t != nil {
+		*t = Time_t(tv.Sec)
+	}
+	return Time_t(tv.Sec), nil
+}
+
+func setTimespec(sec, nsec int64) Timespec {
+	return Timespec{Sec: sec, Nsec: nsec}
+}
+
+func setTimeval(sec, usec int64) Timeval { //fix
+	return Timeval{Sec: sec, Usec: usec}
+}
+
+//sysnb pipe(p *[2]_C_int) (err error)
+
+func Pipe(p []int) (err error) {
+	if len(p) != 2 {
+		return EINVAL
+	}
+	var pp [2]_C_int
+	err = pipe(&pp)
+	p[0] = int(pp[0])
+	p[1] = int(pp[1])
+	return
+}
+
+//sys	utimes(path string, timeval *[2]Timeval) (err error) = SYS___UTIMES_A
+
+func Utimes(path string, tv []Timeval) (err error) {
+	if len(tv) != 2 {
+		return EINVAL
+	}
+	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+}
+
+func UtimesNano(path string, ts []Timespec) error {
+	if len(ts) != 2 {
+		return EINVAL
+	}
+	// Not as efficient as it could be because Timespec and
+	// Timeval have different types in the different OSes
+	tv := [2]Timeval{
+		NsecToTimeval(TimespecToNsec(ts[0])),
+		NsecToTimeval(TimespecToNsec(ts[1])),
+	}
+	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+}
+
+func Getsockname(fd int) (sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	if err = getsockname(fd, &rsa, &len); err != nil {
+		return
+	}
+	// TODO(neeilan) : Remove this 0 ( added to get sys/unix compiling on z/OS )
+	return anyToSockaddr(0, &rsa)
+}
+
+const (
+	// identifier constants
+	nwmHeaderIdentifier    = 0xd5e6d4c8
+	nwmFilterIdentifier    = 0xd5e6d4c6
+	nwmTCPConnIdentifier   = 0xd5e6d4c3
+	nwmRecHeaderIdentifier = 0xd5e6d4d9
+	nwmIPStatsIdentifier   = 0xd5e6d4c9d7e2e340
+	nwmIPGStatsIdentifier  = 0xd5e6d4c9d7c7e2e3
+	nwmTCPStatsIdentifier  = 0xd5e6d4e3c3d7e2e3
+	nwmUDPStatsIdentifier  = 0xd5e6d4e4c4d7e2e3
+	nwmICMPGStatsEntry     = 0xd5e6d4c9c3d4d7c7
+	nwmICMPTStatsEntry     = 0xd5e6d4c9c3d4d7e3
+
+	// nwmHeader constants
+	nwmVersion1   = 1
+	nwmVersion2   = 2
+	nwmCurrentVer = 2
+
+	nwmTCPConnType     = 1
+	nwmGlobalStatsType = 14
+
+	// nwmFilter constants
+	nwmFilterLclAddrMask = 0x20000000 // Local address
+	nwmFilterSrcAddrMask = 0x20000000 // Source address
+	nwmFilterLclPortMask = 0x10000000 // Local port
+	nwmFilterSrcPortMask = 0x10000000 // Source port
+
+	// nwmConnEntry constants
+	nwmTCPStateClosed   = 1
+	nwmTCPStateListen   = 2
+	nwmTCPStateSynSent  = 3
+	nwmTCPStateSynRcvd  = 4
+	nwmTCPStateEstab    = 5
+	nwmTCPStateFinWait1 = 6
+	nwmTCPStateFinWait2 = 7
+	nwmTCPStateClosWait = 8
+	nwmTCPStateLastAck  = 9
+	nwmTCPStateClosing  = 10
+	nwmTCPStateTimeWait = 11
+	nwmTCPStateDeletTCB = 12
+
+	// Existing constants on linux
+	BPF_TCP_CLOSE        = 1
+	BPF_TCP_LISTEN       = 2
+	BPF_TCP_SYN_SENT     = 3
+	BPF_TCP_SYN_RECV     = 4
+	BPF_TCP_ESTABLISHED  = 5
+	BPF_TCP_FIN_WAIT1    = 6
+	BPF_TCP_FIN_WAIT2    = 7
+	BPF_TCP_CLOSE_WAIT   = 8
+	BPF_TCP_LAST_ACK     = 9
+	BPF_TCP_CLOSING      = 10
+	BPF_TCP_TIME_WAIT    = 11
+	BPF_TCP_NEW_SYN_RECV = -1
+	BPF_TCP_MAX_STATES   = -2
+)
+
+type nwmTriplet struct {
+	offset uint32
+	length uint32
+	number uint32
+}
+
+type nwmQuadruplet struct {
+	offset uint32
+	length uint32
+	number uint32
+	match  uint32
+}
+
+type nwmHeader struct {
+	ident       uint32
+	length      uint32
+	version     uint16
+	nwmType     uint16
+	bytesNeeded uint32
+	options     uint32
+	_           [16]byte
+	inputDesc   nwmTriplet
+	outputDesc  nwmQuadruplet
+}
+
+type nwmFilter struct {
+	ident         uint32
+	flags         uint32
+	resourceName  [8]byte
+	resourceId    uint32
+	listenerId    uint32
+	local         [28]byte // union of sockaddr4 and sockaddr6
+	remote        [28]byte // union of sockaddr4 and sockaddr6
+	_             uint16
+	_             uint16
+	asid          uint16
+	_             [2]byte
+	tnLuName      [8]byte
+	tnMonGrp      uint32
+	tnAppl        [8]byte
+	applData      [40]byte
+	nInterface    [16]byte
+	dVipa         [16]byte
+	dVipaPfx      uint16
+	dVipaPort     uint16
+	dVipaFamily   byte
+	_             [3]byte
+	destXCF       [16]byte
+	destXCFPfx    uint16
+	destXCFFamily byte
+	_             [1]byte
+	targIP        [16]byte
+	targIPPfx     uint16
+	targIPFamily  byte
+	_             [1]byte
+	_             [20]byte
+}
+
+type nwmRecHeader struct {
+	ident  uint32
+	length uint32
+	number byte
+	_      [3]byte
+}
+
+type nwmTCPStatsEntry struct {
+	ident             uint64
+	currEstab         uint32
+	activeOpened      uint32
+	passiveOpened     uint32
+	connClosed        uint32
+	estabResets       uint32
+	attemptFails      uint32
+	passiveDrops      uint32
+	timeWaitReused    uint32
+	inSegs            uint64
+	predictAck        uint32
+	predictData       uint32
+	inDupAck          uint32
+	inBadSum          uint32
+	inBadLen          uint32
+	inShort           uint32
+	inDiscOldTime     uint32
+	inAllBeforeWin    uint32
+	inSomeBeforeWin   uint32
+	inAllAfterWin     uint32
+	inSomeAfterWin    uint32
+	inOutOfOrder      uint32
+	inAfterClose      uint32
+	inWinProbes       uint32
+	inWinUpdates      uint32
+	outWinUpdates     uint32
+	outSegs           uint64
+	outDelayAcks      uint32
+	outRsts           uint32
+	retransSegs       uint32
+	retransTimeouts   uint32
+	retransDrops      uint32
+	pmtuRetrans       uint32
+	pmtuErrors        uint32
+	outWinProbes      uint32
+	probeDrops        uint32
+	keepAliveProbes   uint32
+	keepAliveDrops    uint32
+	finwait2Drops     uint32
+	acceptCount       uint64
+	inBulkQSegs       uint64
+	inDiscards        uint64
+	connFloods        uint32
+	connStalls        uint32
+	cfgEphemDef       uint16
+	ephemInUse        uint16
+	ephemHiWater      uint16
+	flags             byte
+	_                 [1]byte
+	ephemExhaust      uint32
+	smcRCurrEstabLnks uint32
+	smcRLnkActTimeOut uint32
+	smcRActLnkOpened  uint32
+	smcRPasLnkOpened  uint32
+	smcRLnksClosed    uint32
+	smcRCurrEstab     uint32
+	smcRActiveOpened  uint32
+	smcRPassiveOpened uint32
+	smcRConnClosed    uint32
+	smcRInSegs        uint64
+	smcROutSegs       uint64
+	smcRInRsts        uint32
+	smcROutRsts       uint32
+	smcDCurrEstabLnks uint32
+	smcDActLnkOpened  uint32
+	smcDPasLnkOpened  uint32
+	smcDLnksClosed    uint32
+	smcDCurrEstab     uint32
+	smcDActiveOpened  uint32
+	smcDPassiveOpened uint32
+	smcDConnClosed    uint32
+	smcDInSegs        uint64
+	smcDOutSegs       uint64
+	smcDInRsts        uint32
+	smcDOutRsts       uint32
+}
+
+type nwmConnEntry struct {
+	ident             uint32
+	local             [28]byte // union of sockaddr4 and sockaddr6
+	remote            [28]byte // union of sockaddr4 and sockaddr6
+	startTime         [8]byte  // uint64, changed to prevent padding from being inserted
+	lastActivity      [8]byte  // uint64
+	bytesIn           [8]byte  // uint64
+	bytesOut          [8]byte  // uint64
+	inSegs            [8]byte  // uint64
+	outSegs           [8]byte  // uint64
+	state             uint16
+	activeOpen        byte
+	flag01            byte
+	outBuffered       uint32
+	inBuffered        uint32
+	maxSndWnd         uint32
+	reXmtCount        uint32
+	congestionWnd     uint32
+	ssThresh          uint32
+	roundTripTime     uint32
+	roundTripVar      uint32
+	sendMSS           uint32
+	sndWnd            uint32
+	rcvBufSize        uint32
+	sndBufSize        uint32
+	outOfOrderCount   uint32
+	lcl0WindowCount   uint32
+	rmt0WindowCount   uint32
+	dupacks           uint32
+	flag02            byte
+	sockOpt6Cont      byte
+	asid              uint16
+	resourceName      [8]byte
+	resourceId        uint32
+	subtask           uint32
+	sockOpt           byte
+	sockOpt6          byte
+	clusterConnFlag   byte
+	proto             byte
+	targetAppl        [8]byte
+	luName            [8]byte
+	clientUserId      [8]byte
+	logMode           [8]byte
+	timeStamp         uint32
+	timeStampAge      uint32
+	serverResourceId  uint32
+	intfName          [16]byte
+	ttlsStatPol       byte
+	ttlsStatConn      byte
+	ttlsSSLProt       uint16
+	ttlsNegCiph       [2]byte
+	ttlsSecType       byte
+	ttlsFIPS140Mode   byte
+	ttlsUserID        [8]byte
+	applData          [40]byte
+	inOldestTime      [8]byte // uint64
+	outOldestTime     [8]byte // uint64
+	tcpTrustedPartner byte
+	_                 [3]byte
+	bulkDataIntfName  [16]byte
+	ttlsNegCiph4      [4]byte
+	smcReason         uint32
+	lclSMCLinkId      uint32
+	rmtSMCLinkId      uint32
+	smcStatus         byte
+	smcFlags          byte
+	_                 [2]byte
+	rcvWnd            uint32
+	lclSMCBufSz       uint32
+	rmtSMCBufSz       uint32
+	ttlsSessID        [32]byte
+	ttlsSessIDLen     int16
+	_                 [1]byte
+	smcDStatus        byte
+	smcDReason        uint32
+}
+
+var svcNameTable [][]byte = [][]byte{
+	[]byte("\xc5\xe9\xc2\xd5\xd4\xc9\xc6\xf4"), // svc_EZBNMIF4
+}
+
+const (
+	svc_EZBNMIF4 = 0
+)
+
+func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
+	jobname := []byte("\x5c\x40\x40\x40\x40\x40\x40\x40") // "*"
+	responseBuffer := [4096]byte{0}
+	var bufferAlet, reasonCode uint32 = 0, 0
+	var bufferLen, returnValue, returnCode int32 = 4096, 0, 0
+
+	dsa := [18]uint64{0}
+	var argv [7]unsafe.Pointer
+	argv[0] = unsafe.Pointer(&jobname[0])
+	argv[1] = unsafe.Pointer(&responseBuffer[0])
+	argv[2] = unsafe.Pointer(&bufferAlet)
+	argv[3] = unsafe.Pointer(&bufferLen)
+	argv[4] = unsafe.Pointer(&returnValue)
+	argv[5] = unsafe.Pointer(&returnCode)
+	argv[6] = unsafe.Pointer(&reasonCode)
+
+	request := (*struct {
+		header nwmHeader
+		filter nwmFilter
+	})(unsafe.Pointer(&responseBuffer[0]))
+
+	EZBNMIF4 := svcLoad(&svcNameTable[svc_EZBNMIF4][0])
+	if EZBNMIF4 == nil {
+		return nil, errnoErr(EINVAL)
+	}
+
+	// GetGlobalStats EZBNMIF4 call
+	request.header.ident = nwmHeaderIdentifier
+	request.header.length = uint32(unsafe.Sizeof(request.header))
+	request.header.version = nwmCurrentVer
+	request.header.nwmType = nwmGlobalStatsType
+	request.header.options = 0x80000000
+
+	svcCall(EZBNMIF4, &argv[0], &dsa[0])
+
+	// outputDesc field is filled by EZBNMIF4 on success
+	if returnCode != 0 || request.header.outputDesc.offset == 0 {
+		return nil, errnoErr(EINVAL)
+	}
+
+	// Check that EZBNMIF4 returned a nwmRecHeader
+	recHeader := (*nwmRecHeader)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
+	if recHeader.ident != nwmRecHeaderIdentifier {
+		return nil, errnoErr(EINVAL)
+	}
+
+	// Parse nwmTriplets to get offsets of returned entries
+	var sections []*uint64
+	var sectionDesc *nwmTriplet = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[0]))
+	for i := uint32(0); i < uint32(recHeader.number); i++ {
+		offset := request.header.outputDesc.offset + uint32(unsafe.Sizeof(*recHeader)) + i*uint32(unsafe.Sizeof(*sectionDesc))
+		sectionDesc = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[offset]))
+		for j := uint32(0); j < sectionDesc.number; j++ {
+			offset = request.header.outputDesc.offset + sectionDesc.offset + j*sectionDesc.length
+			sections = append(sections, (*uint64)(unsafe.Pointer(&responseBuffer[offset])))
+		}
+	}
+
+	// Find nwmTCPStatsEntry in returned entries
+	var tcpStats *nwmTCPStatsEntry = nil
+	for _, ptr := range sections {
+		switch *ptr {
+		case nwmTCPStatsIdentifier:
+			if tcpStats != nil {
+				return nil, errnoErr(EINVAL)
+			}
+			tcpStats = (*nwmTCPStatsEntry)(unsafe.Pointer(ptr))
+		case nwmIPStatsIdentifier:
+		case nwmIPGStatsIdentifier:
+		case nwmUDPStatsIdentifier:
+		case nwmICMPGStatsEntry:
+		case nwmICMPTStatsEntry:
+		default:
+			return nil, errnoErr(EINVAL)
+		}
+	}
+	if tcpStats == nil {
+		return nil, errnoErr(EINVAL)
+	}
+
+	// GetConnectionDetail EZBNMIF4 call
+	responseBuffer = [4096]byte{0}
+	dsa = [18]uint64{0}
+	bufferAlet, reasonCode = 0, 0
+	bufferLen, returnValue, returnCode = 4096, 0, 0
+	nameptr := (*uint32)(unsafe.Pointer(uintptr(0x21c))) // Get jobname of current process
+	nameptr = (*uint32)(unsafe.Pointer(uintptr(*nameptr + 12)))
+	argv[0] = unsafe.Pointer(uintptr(*nameptr))
+
+	request.header.ident = nwmHeaderIdentifier
+	request.header.length = uint32(unsafe.Sizeof(request.header))
+	request.header.version = nwmCurrentVer
+	request.header.nwmType = nwmTCPConnType
+	request.header.options = 0x80000000
+
+	request.filter.ident = nwmFilterIdentifier
+
+	var localSockaddr RawSockaddrAny
+	socklen := _Socklen(SizeofSockaddrAny)
+	err := getsockname(fd, &localSockaddr, &socklen)
+	if err != nil {
+		return nil, errnoErr(EINVAL)
+	}
+	if localSockaddr.Addr.Family == AF_INET {
+		localSockaddr := (*RawSockaddrInet4)(unsafe.Pointer(&localSockaddr.Addr))
+		localSockFilter := (*RawSockaddrInet4)(unsafe.Pointer(&request.filter.local[0]))
+		localSockFilter.Family = AF_INET
+		var i int
+		for i = 0; i < 4; i++ {
+			if localSockaddr.Addr[i] != 0 {
+				break
+			}
+		}
+		if i != 4 {
+			request.filter.flags |= nwmFilterLclAddrMask
+			for i = 0; i < 4; i++ {
+				localSockFilter.Addr[i] = localSockaddr.Addr[i]
+			}
+		}
+		if localSockaddr.Port != 0 {
+			request.filter.flags |= nwmFilterLclPortMask
+			localSockFilter.Port = localSockaddr.Port
+		}
+	} else if localSockaddr.Addr.Family == AF_INET6 {
+		localSockaddr := (*RawSockaddrInet6)(unsafe.Pointer(&localSockaddr.Addr))
+		localSockFilter := (*RawSockaddrInet6)(unsafe.Pointer(&request.filter.local[0]))
+		localSockFilter.Family = AF_INET6
+		var i int
+		for i = 0; i < 16; i++ {
+			if localSockaddr.Addr[i] != 0 {
+				break
+			}
+		}
+		if i != 16 {
+			request.filter.flags |= nwmFilterLclAddrMask
+			for i = 0; i < 16; i++ {
+				localSockFilter.Addr[i] = localSockaddr.Addr[i]
+			}
+		}
+		if localSockaddr.Port != 0 {
+			request.filter.flags |= nwmFilterLclPortMask
+			localSockFilter.Port = localSockaddr.Port
+		}
+	}
+
+	svcCall(EZBNMIF4, &argv[0], &dsa[0])
+
+	// outputDesc field is filled by EZBNMIF4 on success
+	if returnCode != 0 || request.header.outputDesc.offset == 0 {
+		return nil, errnoErr(EINVAL)
+	}
+
+	// Check that EZBNMIF4 returned a nwmConnEntry
+	conn := (*nwmConnEntry)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
+	if conn.ident != nwmTCPConnIdentifier {
+		return nil, errnoErr(EINVAL)
+	}
+
+	// Copy data from the returned data structures into tcpInfo
+	// Stats from nwmConnEntry are specific to that connection.
+	// Stats from nwmTCPStatsEntry are global (to the interface?)
+	// Fields may not be an exact match. Some fields have no equivalent.
+	var tcpinfo TCPInfo
+	tcpinfo.State = uint8(conn.state)
+	tcpinfo.Ca_state = 0 // dummy
+	tcpinfo.Retransmits = uint8(tcpStats.retransSegs)
+	tcpinfo.Probes = uint8(tcpStats.outWinProbes)
+	tcpinfo.Backoff = 0 // dummy
+	tcpinfo.Options = 0 // dummy
+	tcpinfo.Rto = tcpStats.retransTimeouts
+	tcpinfo.Ato = tcpStats.outDelayAcks
+	tcpinfo.Snd_mss = conn.sendMSS
+	tcpinfo.Rcv_mss = conn.sendMSS // dummy
+	tcpinfo.Unacked = 0            // dummy
+	tcpinfo.Sacked = 0             // dummy
+	tcpinfo.Lost = 0               // dummy
+	tcpinfo.Retrans = conn.reXmtCount
+	tcpinfo.Fackets = 0 // dummy
+	tcpinfo.Last_data_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.lastActivity[0])))
+	tcpinfo.Last_ack_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.outOldestTime[0])))
+	tcpinfo.Last_data_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
+	tcpinfo.Last_ack_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
+	tcpinfo.Pmtu = conn.sendMSS // dummy, NWMIfRouteMtu is a candidate
+	tcpinfo.Rcv_ssthresh = conn.ssThresh
+	tcpinfo.Rtt = conn.roundTripTime
+	tcpinfo.Rttvar = conn.roundTripVar
+	tcpinfo.Snd_ssthresh = conn.ssThresh // dummy
+	tcpinfo.Snd_cwnd = conn.congestionWnd
+	tcpinfo.Advmss = conn.sendMSS        // dummy
+	tcpinfo.Reordering = 0               // dummy
+	tcpinfo.Rcv_rtt = conn.roundTripTime // dummy
+	tcpinfo.Rcv_space = conn.sendMSS     // dummy
+	tcpinfo.Total_retrans = conn.reXmtCount
+
+	svcUnload(&svcNameTable[svc_EZBNMIF4][0], EZBNMIF4)
+
+	return &tcpinfo, nil
+}
+
+// GetsockoptString returns the string value of the socket option opt for the
+// socket associated with fd at the given socket level.
+func GetsockoptString(fd, level, opt int) (string, error) {
+	buf := make([]byte, 256)
+	vallen := _Socklen(len(buf))
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
+	if err != nil {
+		return "", err
+	}
+
+	return string(buf[:vallen-1]), nil
+}
+
+func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
+	var msg Msghdr
+	var rsa RawSockaddrAny
+	msg.Name = (*byte)(unsafe.Pointer(&rsa))
+	msg.Namelen = SizeofSockaddrAny
+	var iov Iovec
+	if len(p) > 0 {
+		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
+		iov.SetLen(len(p))
+	}
+	var dummy byte
+	if len(oob) > 0 {
+		// receive at least one normal byte
+		if len(p) == 0 {
+			iov.Base = &dummy
+			iov.SetLen(1)
+		}
+		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.SetControllen(len(oob))
+	}
+	msg.Iov = &iov
+	msg.Iovlen = 1
+	if n, err = recvmsg(fd, &msg, flags); err != nil {
+		return
+	}
+	oobn = int(msg.Controllen)
+	recvflags = int(msg.Flags)
+	// source address is only specified if the socket is unconnected
+	if rsa.Addr.Family != AF_UNSPEC {
+		// TODO(neeilan): Remove 0 arg added to get this compiling on z/OS
+		from, err = anyToSockaddr(0, &rsa)
+	}
+	return
+}
+
+func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
+	_, err = SendmsgN(fd, p, oob, to, flags)
+	return
+}
+
+func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
+	var ptr unsafe.Pointer
+	var salen _Socklen
+	if to != nil {
+		var err error
+		ptr, salen, err = to.sockaddr()
+		if err != nil {
+			return 0, err
+		}
+	}
+	var msg Msghdr
+	msg.Name = (*byte)(unsafe.Pointer(ptr))
+	msg.Namelen = int32(salen)
+	var iov Iovec
+	if len(p) > 0 {
+		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
+		iov.SetLen(len(p))
+	}
+	var dummy byte
+	if len(oob) > 0 {
+		// send at least one normal byte
+		if len(p) == 0 {
+			iov.Base = &dummy
+			iov.SetLen(1)
+		}
+		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.SetControllen(len(oob))
+	}
+	msg.Iov = &iov
+	msg.Iovlen = 1
+	if n, err = sendmsg(fd, &msg, flags); err != nil {
+		return 0, err
+	}
+	if len(oob) > 0 && len(p) == 0 {
+		n = 0
+	}
+	return n, nil
+}
+
+func Opendir(name string) (uintptr, error) {
+	p, err := BytePtrFromString(name)
+	if err != nil {
+		return 0, err
+	}
+	dir, _, e := syscall_syscall(SYS___OPENDIR_A, uintptr(unsafe.Pointer(p)), 0, 0)
+	runtime.KeepAlive(unsafe.Pointer(p))
+	if e != 0 {
+		err = errnoErr(e)
+	}
+	return dir, err
+}
+
+// clearsyscall.Errno resets the errno value to 0.
+func clearErrno()
+
+func Readdir(dir uintptr) (*Dirent, error) {
+	var ent Dirent
+	var res uintptr
+	// __readdir_r_a returns errno at the end of the directory stream, rather than 0.
+	// Therefore to avoid false positives we clear errno before calling it.
+
+	// TODO(neeilan): Commented this out to get sys/unix compiling on z/OS. Uncomment and fix. Error: "undefined: clearsyscall"
+	//clearsyscall.Errno() // TODO(mundaym): check pre-emption rules.
+
+	e, _, _ := syscall_syscall(SYS___READDIR_R_A, dir, uintptr(unsafe.Pointer(&ent)), uintptr(unsafe.Pointer(&res)))
+	var err error
+	if e != 0 {
+		err = errnoErr(Errno(e))
+	}
+	if res == 0 {
+		return nil, err
+	}
+	return &ent, err
+}
+
+func Closedir(dir uintptr) error {
+	_, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0)
+	if e != 0 {
+		return errnoErr(e)
+	}
+	return nil
+}
+
+func Seekdir(dir uintptr, pos int) {
+	_, _, _ = syscall_syscall(SYS_SEEKDIR, dir, uintptr(pos), 0)
+}
+
+func Telldir(dir uintptr) (int, error) {
+	p, _, e := syscall_syscall(SYS_TELLDIR, dir, 0, 0)
+	pos := int(p)
+	if pos == -1 {
+		return pos, errnoErr(e)
+	}
+	return pos, nil
+}
+
+// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
+func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
+	// struct flock is packed on z/OS. We can't emulate that in Go so
+	// instead we pack it here.
+	var flock [24]byte
+	*(*int16)(unsafe.Pointer(&flock[0])) = lk.Type
+	*(*int16)(unsafe.Pointer(&flock[2])) = lk.Whence
+	*(*int64)(unsafe.Pointer(&flock[4])) = lk.Start
+	*(*int64)(unsafe.Pointer(&flock[12])) = lk.Len
+	*(*int32)(unsafe.Pointer(&flock[20])) = lk.Pid
+	_, _, errno := syscall_syscall(SYS_FCNTL, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))
+	lk.Type = *(*int16)(unsafe.Pointer(&flock[0]))
+	lk.Whence = *(*int16)(unsafe.Pointer(&flock[2]))
+	lk.Start = *(*int64)(unsafe.Pointer(&flock[4]))
+	lk.Len = *(*int64)(unsafe.Pointer(&flock[12]))
+	lk.Pid = *(*int32)(unsafe.Pointer(&flock[20]))
+	if errno == 0 {
+		return nil
+	}
+	return errno
+}
+
+func Flock(fd int, how int) error {
+
+	var flock_type int16
+	var fcntl_cmd int
+
+	switch how {
+	case LOCK_SH | LOCK_NB:
+		flock_type = F_RDLCK
+		fcntl_cmd = F_SETLK
+	case LOCK_EX | LOCK_NB:
+		flock_type = F_WRLCK
+		fcntl_cmd = F_SETLK
+	case LOCK_EX:
+		flock_type = F_WRLCK
+		fcntl_cmd = F_SETLKW
+	case LOCK_UN:
+		flock_type = F_UNLCK
+		fcntl_cmd = F_SETLKW
+	default:
+	}
+
+	flock := Flock_t{
+		Type:   int16(flock_type),
+		Whence: int16(0),
+		Start:  int64(0),
+		Len:    int64(0),
+		Pid:    int32(Getppid()),
+	}
+
+	err := FcntlFlock(uintptr(fd), fcntl_cmd, &flock)
+	return err
+}
+
+func Mlock(b []byte) (err error) {
+	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func Mlock2(b []byte, flags int) (err error) {
+	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func Munlock(b []byte) (err error) {
+	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_SWAP, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func Munlockall() (err error) {
+	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_SWAP, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func ClockGettime(clockid int32, ts *Timespec) error {
+
+	var ticks_per_sec uint32 = 100 //TODO(kenan): value is currently hardcoded; need sysconf() call otherwise
+	var nsec_per_sec int64 = 1000000000
+
+	if ts == nil {
+		return EFAULT
+	}
+	if clockid == CLOCK_REALTIME || clockid == CLOCK_MONOTONIC {
+		var nanotime int64 = runtime.Nanotime1()
+		ts.Sec = nanotime / nsec_per_sec
+		ts.Nsec = nanotime % nsec_per_sec
+	} else if clockid == CLOCK_PROCESS_CPUTIME_ID || clockid == CLOCK_THREAD_CPUTIME_ID {
+		var tm Tms
+		_, err := Times(&tm)
+		if err != nil {
+			return EFAULT
+		}
+		ts.Sec = int64(tm.Utime / ticks_per_sec)
+		ts.Nsec = int64(tm.Utime) * nsec_per_sec / int64(ticks_per_sec)
+	} else {
+		return EINVAL
+	}
+	return nil
+}
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	fd, err := open(path, O_RDONLY, 0)
+	defer Close(fd)
+	if err != nil {
+		return err
+	}
+	return Fstatfs(fd, stat)
+}
+
+var (
+	Stdin  = 0
+	Stdout = 1
+	Stderr = 2
+)
+
+// Do the interface allocations only once for common
+// Errno values.
+var (
+	errEAGAIN error = syscall.EAGAIN
+	errEINVAL error = syscall.EINVAL
+	errENOENT error = syscall.ENOENT
+)
+
+var (
+	signalNameMapOnce sync.Once
+	signalNameMap     map[string]syscall.Signal
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e Errno) error {
+	switch e {
+	case 0:
+		return nil
+	case EAGAIN:
+		return errEAGAIN
+	case EINVAL:
+		return errEINVAL
+	case ENOENT:
+		return errENOENT
+	}
+	return e
+}
+
+// ErrnoName returns the error name for error number e.
+func ErrnoName(e Errno) string {
+	i := sort.Search(len(errorList), func(i int) bool {
+		return errorList[i].num >= e
+	})
+	if i < len(errorList) && errorList[i].num == e {
+		return errorList[i].name
+	}
+	return ""
+}
+
+// SignalName returns the signal name for signal number s.
+func SignalName(s syscall.Signal) string {
+	i := sort.Search(len(signalList), func(i int) bool {
+		return signalList[i].num >= s
+	})
+	if i < len(signalList) && signalList[i].num == s {
+		return signalList[i].name
+	}
+	return ""
+}
+
+// SignalNum returns the syscall.Signal for signal named s,
+// or 0 if a signal with such name is not found.
+// The signal name should start with "SIG".
+func SignalNum(s string) syscall.Signal {
+	signalNameMapOnce.Do(func() {
+		signalNameMap = make(map[string]syscall.Signal, len(signalList))
+		for _, signal := range signalList {
+			signalNameMap[signal.name] = signal.num
+		}
+	})
+	return signalNameMap[s]
+}
+
+// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
+func clen(n []byte) int {
+	i := bytes.IndexByte(n, 0)
+	if i == -1 {
+		i = len(n)
+	}
+	return i
+}
+
+// Mmap manager, for use by operating system-specific implementations.
+
+type mmapper struct {
+	sync.Mutex
+	active map[*byte][]byte // active mappings; key is last byte in mapping
+	mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
+	munmap func(addr uintptr, length uintptr) error
+}
+
+func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
+	if length <= 0 {
+		return nil, EINVAL
+	}
+
+	// Map the requested memory.
+	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
+	if errno != nil {
+		return nil, errno
+	}
+
+	// Slice memory layout
+	var sl = struct {
+		addr uintptr
+		len  int
+		cap  int
+	}{addr, length, length}
+
+	// Use unsafe to turn sl into a []byte.
+	b := *(*[]byte)(unsafe.Pointer(&sl))
+
+	// Register mapping in m and return it.
+	p := &b[cap(b)-1]
+	m.Lock()
+	defer m.Unlock()
+	m.active[p] = b
+	return b, nil
+}
+
+func (m *mmapper) Munmap(data []byte) (err error) {
+	if len(data) == 0 || len(data) != cap(data) {
+		return EINVAL
+	}
+
+	// Find the base of the mapping.
+	p := &data[cap(data)-1]
+	m.Lock()
+	defer m.Unlock()
+	b := m.active[p]
+	if b == nil || &b[0] != &data[0] {
+		return EINVAL
+	}
+
+	// Unmap the memory and update m.
+	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
+		return errno
+	}
+	delete(m.active, p)
+	return nil
+}
+
+func Read(fd int, p []byte) (n int, err error) {
+	n, err = read(fd, p)
+	if raceenabled {
+		if n > 0 {
+			raceWriteRange(unsafe.Pointer(&p[0]), n)
+		}
+		if err == nil {
+			raceAcquire(unsafe.Pointer(&ioSync))
+		}
+	}
+	return
+}
+
+func Write(fd int, p []byte) (n int, err error) {
+	if raceenabled {
+		raceReleaseMerge(unsafe.Pointer(&ioSync))
+	}
+	n, err = write(fd, p)
+	if raceenabled && n > 0 {
+		raceReadRange(unsafe.Pointer(&p[0]), n)
+	}
+	return
+}
+
+// For testing: clients can set this flag to force
+// creation of IPv6 sockets to return EAFNOSUPPORT.
+var SocketDisableIPv6 bool
+
+// Sockaddr represents a socket address.
+type Sockaddr interface {
+	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
+}
+
+// SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets.
+type SockaddrInet4 struct {
+	Port int
+	Addr [4]byte
+	raw  RawSockaddrInet4
+}
+
+// SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets.
+type SockaddrInet6 struct {
+	Port   int
+	ZoneId uint32
+	Addr   [16]byte
+	raw    RawSockaddrInet6
+}
+
+// SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets.
+type SockaddrUnix struct {
+	Name string
+	raw  RawSockaddrUnix
+}
+
+func Bind(fd int, sa Sockaddr) (err error) {
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return bind(fd, ptr, n)
+}
+
+func Connect(fd int, sa Sockaddr) (err error) {
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return connect(fd, ptr, n)
+}
+
+func Getpeername(fd int) (sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	if err = getpeername(fd, &rsa, &len); err != nil {
+		return
+	}
+	return anyToSockaddr(fd, &rsa)
+}
+
+func GetsockoptByte(fd, level, opt int) (value byte, err error) {
+	var n byte
+	vallen := _Socklen(1)
+	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
+	return n, err
+}
+
+func GetsockoptInt(fd, level, opt int) (value int, err error) {
+	var n int32
+	vallen := _Socklen(4)
+	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
+	return int(n), err
+}
+
+func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
+	vallen := _Socklen(4)
+	err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
+	return value, err
+}
+
+func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
+	var value IPMreq
+	vallen := _Socklen(SizeofIPMreq)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
+	var value IPv6Mreq
+	vallen := _Socklen(SizeofIPv6Mreq)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
+	var value IPv6MTUInfo
+	vallen := _Socklen(SizeofIPv6MTUInfo)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
+	var value ICMPv6Filter
+	vallen := _Socklen(SizeofICMPv6Filter)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
+	var linger Linger
+	vallen := _Socklen(SizeofLinger)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
+	return &linger, err
+}
+
+func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
+	var tv Timeval
+	vallen := _Socklen(unsafe.Sizeof(tv))
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
+	return &tv, err
+}
+
+func GetsockoptUint64(fd, level, opt int) (value uint64, err error) {
+	var n uint64
+	vallen := _Socklen(8)
+	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
+	return n, err
+}
+
+func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
+		return
+	}
+	if rsa.Addr.Family != AF_UNSPEC {
+		from, err = anyToSockaddr(fd, &rsa)
+	}
+	return
+}
+
+func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
+	ptr, n, err := to.sockaddr()
+	if err != nil {
+		return err
+	}
+	return sendto(fd, p, flags, ptr, n)
+}
+
+func SetsockoptByte(fd, level, opt int, value byte) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
+}
+
+func SetsockoptInt(fd, level, opt int, value int) (err error) {
+	var n = int32(value)
+	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
+}
+
+func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
+}
+
+func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
+}
+
+func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
+}
+
+func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
+	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
+}
+
+func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
+}
+
+func SetsockoptString(fd, level, opt int, s string) (err error) {
+	var p unsafe.Pointer
+	if len(s) > 0 {
+		p = unsafe.Pointer(&[]byte(s)[0])
+	}
+	return setsockopt(fd, level, opt, p, uintptr(len(s)))
+}
+
+func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
+}
+
+func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
+}
+
+func Socket(domain, typ, proto int) (fd int, err error) {
+	if domain == AF_INET6 && SocketDisableIPv6 {
+		return -1, EAFNOSUPPORT
+	}
+	fd, err = socket(domain, typ, proto)
+	return
+}
+
+func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
+	var fdx [2]int32
+	err = socketpair(domain, typ, proto, &fdx)
+	if err == nil {
+		fd[0] = int(fdx[0])
+		fd[1] = int(fdx[1])
+	}
+	return
+}
+
+var ioSync int64
+
+func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
+
+func SetNonblock(fd int, nonblocking bool) (err error) {
+	flag, err := fcntl(fd, F_GETFL, 0)
+	if err != nil {
+		return err
+	}
+	if nonblocking {
+		flag |= O_NONBLOCK
+	} else {
+		flag &= ^O_NONBLOCK
+	}
+	_, err = fcntl(fd, F_SETFL, flag)
+	return err
+}
+
+// Exec calls execve(2), which replaces the calling executable in the process
+// tree. argv0 should be the full path to an executable ("/bin/ls") and the
+// executable name should also be the first argument in argv (["ls", "-l"]).
+// envv are the environment variables that should be passed to the new
+// process (["USER=go", "PWD=/tmp"]).
+func Exec(argv0 string, argv []string, envv []string) error {
+	return syscall.Exec(argv0, argv, envv)
+}
+
+func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
+	if needspace := 8 - len(fstype); needspace <= 0 {
+		fstype = fstype[:8]
+	} else {
+		fstype += "        "[:needspace]
+	}
+	return mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)
+}
+
+func Unmount(name string, mtm int) (err error) {
+	// mountpoint is always a full path and starts with a '/'
+	// check if input string is not a mountpoint but a filesystem name
+	if name[0] != '/' {
+		return unmount(name, mtm)
+	}
+	// treat name as mountpoint
+	b2s := func(arr []byte) string {
+		nulli := bytes.IndexByte(arr, 0)
+		if nulli == -1 {
+			return string(arr)
+		} else {
+			return string(arr[:nulli])
+		}
+	}
+	var buffer struct {
+		header W_Mnth
+		fsinfo [64]W_Mntent
+	}
+	fsCount, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
+	if err != nil {
+		return err
+	}
+	if fsCount == 0 {
+		return EINVAL
+	}
+	for i := 0; i < fsCount; i++ {
+		if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
+			err = unmount(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
+			break
+		}
+	}
+	return err
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/timestruct.go b/src/cmd/vendor/golang.org/x/sys/unix/timestruct.go
index 4a672f5..3d89304 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/timestruct.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/timestruct.go
@@ -2,18 +2,17 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
 
 package unix
 
 import "time"
 
-// TimespecToNsec converts a Timespec value into a number of
-// nanoseconds since the Unix epoch.
-func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
+// TimespecToNSec returns the time stored in ts as nanoseconds.
+func TimespecToNsec(ts Timespec) int64 { return ts.Nano() }
 
-// NsecToTimespec takes a number of nanoseconds since the Unix epoch
-// and returns the corresponding Timespec value.
+// NsecToTimespec converts a number of nanoseconds into a Timespec.
 func NsecToTimespec(nsec int64) Timespec {
 	sec := nsec / 1e9
 	nsec = nsec % 1e9
@@ -42,12 +41,10 @@
 	return ts, nil
 }
 
-// TimevalToNsec converts a Timeval value into a number of nanoseconds
-// since the Unix epoch.
-func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
+// TimevalToNsec returns the time stored in tv as nanoseconds.
+func TimevalToNsec(tv Timeval) int64 { return tv.Nano() }
 
-// NsecToTimeval takes a number of nanoseconds since the Unix epoch
-// and returns the corresponding Timeval value.
+// NsecToTimeval converts a number of nanoseconds into a Timeval.
 func NsecToTimeval(nsec int64) Timeval {
 	nsec += 999 // round up to microsecond
 	usec := nsec % 1e9 / 1e3
@@ -59,24 +56,22 @@
 	return setTimeval(sec, usec)
 }
 
-// Unix returns ts as the number of seconds and nanoseconds elapsed since the
-// Unix epoch.
+// Unix returns the time stored in ts as seconds plus nanoseconds.
 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.
+// Unix returns the time stored in tv as seconds plus nanoseconds.
 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.
+// Nano returns the time stored in ts as nanoseconds.
 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.
+// Nano returns the time stored in tv as nanoseconds.
 func (tv *Timeval) Nano() int64 {
 	return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
 }
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/xattr_bsd.go b/src/cmd/vendor/golang.org/x/sys/unix/xattr_bsd.go
index 30c1d71..25df1e3 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/xattr_bsd.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/xattr_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build freebsd || netbsd
 // +build freebsd netbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go
index 104994b..ca9799b 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -maix32
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build ppc && aix
 // +build ppc,aix
 
 // Created by cgo -godefs - DO NOT EDIT
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go
index 4fc8d30..200c8c2 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -maix64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build ppc64 && aix
 // +build ppc64,aix
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go
deleted file mode 100644
index ec376f5..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go
+++ /dev/null
@@ -1,1788 +0,0 @@
-// mkerrors.sh -m32
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build 386,darwin
-
-// Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -m32 _const.go
-
-package unix
-
-import "syscall"
-
-const (
-	AF_APPLETALK                      = 0x10
-	AF_CCITT                          = 0xa
-	AF_CHAOS                          = 0x5
-	AF_CNT                            = 0x15
-	AF_COIP                           = 0x14
-	AF_DATAKIT                        = 0x9
-	AF_DECnet                         = 0xc
-	AF_DLI                            = 0xd
-	AF_E164                           = 0x1c
-	AF_ECMA                           = 0x8
-	AF_HYLINK                         = 0xf
-	AF_IEEE80211                      = 0x25
-	AF_IMPLINK                        = 0x3
-	AF_INET                           = 0x2
-	AF_INET6                          = 0x1e
-	AF_IPX                            = 0x17
-	AF_ISDN                           = 0x1c
-	AF_ISO                            = 0x7
-	AF_LAT                            = 0xe
-	AF_LINK                           = 0x12
-	AF_LOCAL                          = 0x1
-	AF_MAX                            = 0x28
-	AF_NATM                           = 0x1f
-	AF_NDRV                           = 0x1b
-	AF_NETBIOS                        = 0x21
-	AF_NS                             = 0x6
-	AF_OSI                            = 0x7
-	AF_PPP                            = 0x22
-	AF_PUP                            = 0x4
-	AF_RESERVED_36                    = 0x24
-	AF_ROUTE                          = 0x11
-	AF_SIP                            = 0x18
-	AF_SNA                            = 0xb
-	AF_SYSTEM                         = 0x20
-	AF_SYS_CONTROL                    = 0x2
-	AF_UNIX                           = 0x1
-	AF_UNSPEC                         = 0x0
-	AF_UTUN                           = 0x26
-	ALTWERASE                         = 0x200
-	ATTR_BIT_MAP_COUNT                = 0x5
-	ATTR_CMN_ACCESSMASK               = 0x20000
-	ATTR_CMN_ACCTIME                  = 0x1000
-	ATTR_CMN_ADDEDTIME                = 0x10000000
-	ATTR_CMN_BKUPTIME                 = 0x2000
-	ATTR_CMN_CHGTIME                  = 0x800
-	ATTR_CMN_CRTIME                   = 0x200
-	ATTR_CMN_DATA_PROTECT_FLAGS       = 0x40000000
-	ATTR_CMN_DEVID                    = 0x2
-	ATTR_CMN_DOCUMENT_ID              = 0x100000
-	ATTR_CMN_ERROR                    = 0x20000000
-	ATTR_CMN_EXTENDED_SECURITY        = 0x400000
-	ATTR_CMN_FILEID                   = 0x2000000
-	ATTR_CMN_FLAGS                    = 0x40000
-	ATTR_CMN_FNDRINFO                 = 0x4000
-	ATTR_CMN_FSID                     = 0x4
-	ATTR_CMN_FULLPATH                 = 0x8000000
-	ATTR_CMN_GEN_COUNT                = 0x80000
-	ATTR_CMN_GRPID                    = 0x10000
-	ATTR_CMN_GRPUUID                  = 0x1000000
-	ATTR_CMN_MODTIME                  = 0x400
-	ATTR_CMN_NAME                     = 0x1
-	ATTR_CMN_NAMEDATTRCOUNT           = 0x80000
-	ATTR_CMN_NAMEDATTRLIST            = 0x100000
-	ATTR_CMN_OBJID                    = 0x20
-	ATTR_CMN_OBJPERMANENTID           = 0x40
-	ATTR_CMN_OBJTAG                   = 0x10
-	ATTR_CMN_OBJTYPE                  = 0x8
-	ATTR_CMN_OWNERID                  = 0x8000
-	ATTR_CMN_PARENTID                 = 0x4000000
-	ATTR_CMN_PAROBJID                 = 0x80
-	ATTR_CMN_RETURNED_ATTRS           = 0x80000000
-	ATTR_CMN_SCRIPT                   = 0x100
-	ATTR_CMN_SETMASK                  = 0x41c7ff00
-	ATTR_CMN_USERACCESS               = 0x200000
-	ATTR_CMN_UUID                     = 0x800000
-	ATTR_CMN_VALIDMASK                = 0xffffffff
-	ATTR_CMN_VOLSETMASK               = 0x6700
-	ATTR_FILE_ALLOCSIZE               = 0x4
-	ATTR_FILE_CLUMPSIZE               = 0x10
-	ATTR_FILE_DATAALLOCSIZE           = 0x400
-	ATTR_FILE_DATAEXTENTS             = 0x800
-	ATTR_FILE_DATALENGTH              = 0x200
-	ATTR_FILE_DEVTYPE                 = 0x20
-	ATTR_FILE_FILETYPE                = 0x40
-	ATTR_FILE_FORKCOUNT               = 0x80
-	ATTR_FILE_FORKLIST                = 0x100
-	ATTR_FILE_IOBLOCKSIZE             = 0x8
-	ATTR_FILE_LINKCOUNT               = 0x1
-	ATTR_FILE_RSRCALLOCSIZE           = 0x2000
-	ATTR_FILE_RSRCEXTENTS             = 0x4000
-	ATTR_FILE_RSRCLENGTH              = 0x1000
-	ATTR_FILE_SETMASK                 = 0x20
-	ATTR_FILE_TOTALSIZE               = 0x2
-	ATTR_FILE_VALIDMASK               = 0x37ff
-	ATTR_VOL_ALLOCATIONCLUMP          = 0x40
-	ATTR_VOL_ATTRIBUTES               = 0x40000000
-	ATTR_VOL_CAPABILITIES             = 0x20000
-	ATTR_VOL_DIRCOUNT                 = 0x400
-	ATTR_VOL_ENCODINGSUSED            = 0x10000
-	ATTR_VOL_FILECOUNT                = 0x200
-	ATTR_VOL_FSTYPE                   = 0x1
-	ATTR_VOL_INFO                     = 0x80000000
-	ATTR_VOL_IOBLOCKSIZE              = 0x80
-	ATTR_VOL_MAXOBJCOUNT              = 0x800
-	ATTR_VOL_MINALLOCATION            = 0x20
-	ATTR_VOL_MOUNTEDDEVICE            = 0x8000
-	ATTR_VOL_MOUNTFLAGS               = 0x4000
-	ATTR_VOL_MOUNTPOINT               = 0x1000
-	ATTR_VOL_NAME                     = 0x2000
-	ATTR_VOL_OBJCOUNT                 = 0x100
-	ATTR_VOL_QUOTA_SIZE               = 0x10000000
-	ATTR_VOL_RESERVED_SIZE            = 0x20000000
-	ATTR_VOL_SETMASK                  = 0x80002000
-	ATTR_VOL_SIGNATURE                = 0x2
-	ATTR_VOL_SIZE                     = 0x4
-	ATTR_VOL_SPACEAVAIL               = 0x10
-	ATTR_VOL_SPACEFREE                = 0x8
-	ATTR_VOL_UUID                     = 0x40000
-	ATTR_VOL_VALIDMASK                = 0xf007ffff
-	B0                                = 0x0
-	B110                              = 0x6e
-	B115200                           = 0x1c200
-	B1200                             = 0x4b0
-	B134                              = 0x86
-	B14400                            = 0x3840
-	B150                              = 0x96
-	B1800                             = 0x708
-	B19200                            = 0x4b00
-	B200                              = 0xc8
-	B230400                           = 0x38400
-	B2400                             = 0x960
-	B28800                            = 0x7080
-	B300                              = 0x12c
-	B38400                            = 0x9600
-	B4800                             = 0x12c0
-	B50                               = 0x32
-	B57600                            = 0xe100
-	B600                              = 0x258
-	B7200                             = 0x1c20
-	B75                               = 0x4b
-	B76800                            = 0x12c00
-	B9600                             = 0x2580
-	BIOCFLUSH                         = 0x20004268
-	BIOCGBLEN                         = 0x40044266
-	BIOCGDLT                          = 0x4004426a
-	BIOCGDLTLIST                      = 0xc00c4279
-	BIOCGETIF                         = 0x4020426b
-	BIOCGHDRCMPLT                     = 0x40044274
-	BIOCGRSIG                         = 0x40044272
-	BIOCGRTIMEOUT                     = 0x4008426e
-	BIOCGSEESENT                      = 0x40044276
-	BIOCGSTATS                        = 0x4008426f
-	BIOCIMMEDIATE                     = 0x80044270
-	BIOCPROMISC                       = 0x20004269
-	BIOCSBLEN                         = 0xc0044266
-	BIOCSDLT                          = 0x80044278
-	BIOCSETF                          = 0x80084267
-	BIOCSETFNR                        = 0x8008427e
-	BIOCSETIF                         = 0x8020426c
-	BIOCSHDRCMPLT                     = 0x80044275
-	BIOCSRSIG                         = 0x80044273
-	BIOCSRTIMEOUT                     = 0x8008426d
-	BIOCSSEESENT                      = 0x80044277
-	BIOCVERSION                       = 0x40044271
-	BPF_A                             = 0x10
-	BPF_ABS                           = 0x20
-	BPF_ADD                           = 0x0
-	BPF_ALIGNMENT                     = 0x4
-	BPF_ALU                           = 0x4
-	BPF_AND                           = 0x50
-	BPF_B                             = 0x10
-	BPF_DIV                           = 0x30
-	BPF_H                             = 0x8
-	BPF_IMM                           = 0x0
-	BPF_IND                           = 0x40
-	BPF_JA                            = 0x0
-	BPF_JEQ                           = 0x10
-	BPF_JGE                           = 0x30
-	BPF_JGT                           = 0x20
-	BPF_JMP                           = 0x5
-	BPF_JSET                          = 0x40
-	BPF_K                             = 0x0
-	BPF_LD                            = 0x0
-	BPF_LDX                           = 0x1
-	BPF_LEN                           = 0x80
-	BPF_LSH                           = 0x60
-	BPF_MAJOR_VERSION                 = 0x1
-	BPF_MAXBUFSIZE                    = 0x80000
-	BPF_MAXINSNS                      = 0x200
-	BPF_MEM                           = 0x60
-	BPF_MEMWORDS                      = 0x10
-	BPF_MINBUFSIZE                    = 0x20
-	BPF_MINOR_VERSION                 = 0x1
-	BPF_MISC                          = 0x7
-	BPF_MSH                           = 0xa0
-	BPF_MUL                           = 0x20
-	BPF_NEG                           = 0x80
-	BPF_OR                            = 0x40
-	BPF_RELEASE                       = 0x30bb6
-	BPF_RET                           = 0x6
-	BPF_RSH                           = 0x70
-	BPF_ST                            = 0x2
-	BPF_STX                           = 0x3
-	BPF_SUB                           = 0x10
-	BPF_TAX                           = 0x0
-	BPF_TXA                           = 0x80
-	BPF_W                             = 0x0
-	BPF_X                             = 0x8
-	BRKINT                            = 0x2
-	BS0                               = 0x0
-	BS1                               = 0x8000
-	BSDLY                             = 0x8000
-	CFLUSH                            = 0xf
-	CLOCAL                            = 0x8000
-	CLOCK_MONOTONIC                   = 0x6
-	CLOCK_MONOTONIC_RAW               = 0x4
-	CLOCK_MONOTONIC_RAW_APPROX        = 0x5
-	CLOCK_PROCESS_CPUTIME_ID          = 0xc
-	CLOCK_REALTIME                    = 0x0
-	CLOCK_THREAD_CPUTIME_ID           = 0x10
-	CLOCK_UPTIME_RAW                  = 0x8
-	CLOCK_UPTIME_RAW_APPROX           = 0x9
-	CLONE_NOFOLLOW                    = 0x1
-	CLONE_NOOWNERCOPY                 = 0x2
-	CR0                               = 0x0
-	CR1                               = 0x1000
-	CR2                               = 0x2000
-	CR3                               = 0x3000
-	CRDLY                             = 0x3000
-	CREAD                             = 0x800
-	CRTSCTS                           = 0x30000
-	CS5                               = 0x0
-	CS6                               = 0x100
-	CS7                               = 0x200
-	CS8                               = 0x300
-	CSIZE                             = 0x300
-	CSTART                            = 0x11
-	CSTATUS                           = 0x14
-	CSTOP                             = 0x13
-	CSTOPB                            = 0x400
-	CSUSP                             = 0x1a
-	CTLIOCGINFO                       = 0xc0644e03
-	CTL_HW                            = 0x6
-	CTL_KERN                          = 0x1
-	CTL_MAXNAME                       = 0xc
-	CTL_NET                           = 0x4
-	DLT_A429                          = 0xb8
-	DLT_A653_ICM                      = 0xb9
-	DLT_AIRONET_HEADER                = 0x78
-	DLT_AOS                           = 0xde
-	DLT_APPLE_IP_OVER_IEEE1394        = 0x8a
-	DLT_ARCNET                        = 0x7
-	DLT_ARCNET_LINUX                  = 0x81
-	DLT_ATM_CLIP                      = 0x13
-	DLT_ATM_RFC1483                   = 0xb
-	DLT_AURORA                        = 0x7e
-	DLT_AX25                          = 0x3
-	DLT_AX25_KISS                     = 0xca
-	DLT_BACNET_MS_TP                  = 0xa5
-	DLT_BLUETOOTH_HCI_H4              = 0xbb
-	DLT_BLUETOOTH_HCI_H4_WITH_PHDR    = 0xc9
-	DLT_CAN20B                        = 0xbe
-	DLT_CAN_SOCKETCAN                 = 0xe3
-	DLT_CHAOS                         = 0x5
-	DLT_CHDLC                         = 0x68
-	DLT_CISCO_IOS                     = 0x76
-	DLT_C_HDLC                        = 0x68
-	DLT_C_HDLC_WITH_DIR               = 0xcd
-	DLT_DBUS                          = 0xe7
-	DLT_DECT                          = 0xdd
-	DLT_DOCSIS                        = 0x8f
-	DLT_DVB_CI                        = 0xeb
-	DLT_ECONET                        = 0x73
-	DLT_EN10MB                        = 0x1
-	DLT_EN3MB                         = 0x2
-	DLT_ENC                           = 0x6d
-	DLT_ERF                           = 0xc5
-	DLT_ERF_ETH                       = 0xaf
-	DLT_ERF_POS                       = 0xb0
-	DLT_FC_2                          = 0xe0
-	DLT_FC_2_WITH_FRAME_DELIMS        = 0xe1
-	DLT_FDDI                          = 0xa
-	DLT_FLEXRAY                       = 0xd2
-	DLT_FRELAY                        = 0x6b
-	DLT_FRELAY_WITH_DIR               = 0xce
-	DLT_GCOM_SERIAL                   = 0xad
-	DLT_GCOM_T1E1                     = 0xac
-	DLT_GPF_F                         = 0xab
-	DLT_GPF_T                         = 0xaa
-	DLT_GPRS_LLC                      = 0xa9
-	DLT_GSMTAP_ABIS                   = 0xda
-	DLT_GSMTAP_UM                     = 0xd9
-	DLT_HHDLC                         = 0x79
-	DLT_IBM_SN                        = 0x92
-	DLT_IBM_SP                        = 0x91
-	DLT_IEEE802                       = 0x6
-	DLT_IEEE802_11                    = 0x69
-	DLT_IEEE802_11_RADIO              = 0x7f
-	DLT_IEEE802_11_RADIO_AVS          = 0xa3
-	DLT_IEEE802_15_4                  = 0xc3
-	DLT_IEEE802_15_4_LINUX            = 0xbf
-	DLT_IEEE802_15_4_NOFCS            = 0xe6
-	DLT_IEEE802_15_4_NONASK_PHY       = 0xd7
-	DLT_IEEE802_16_MAC_CPS            = 0xbc
-	DLT_IEEE802_16_MAC_CPS_RADIO      = 0xc1
-	DLT_IPFILTER                      = 0x74
-	DLT_IPMB                          = 0xc7
-	DLT_IPMB_LINUX                    = 0xd1
-	DLT_IPNET                         = 0xe2
-	DLT_IPOIB                         = 0xf2
-	DLT_IPV4                          = 0xe4
-	DLT_IPV6                          = 0xe5
-	DLT_IP_OVER_FC                    = 0x7a
-	DLT_JUNIPER_ATM1                  = 0x89
-	DLT_JUNIPER_ATM2                  = 0x87
-	DLT_JUNIPER_ATM_CEMIC             = 0xee
-	DLT_JUNIPER_CHDLC                 = 0xb5
-	DLT_JUNIPER_ES                    = 0x84
-	DLT_JUNIPER_ETHER                 = 0xb2
-	DLT_JUNIPER_FIBRECHANNEL          = 0xea
-	DLT_JUNIPER_FRELAY                = 0xb4
-	DLT_JUNIPER_GGSN                  = 0x85
-	DLT_JUNIPER_ISM                   = 0xc2
-	DLT_JUNIPER_MFR                   = 0x86
-	DLT_JUNIPER_MLFR                  = 0x83
-	DLT_JUNIPER_MLPPP                 = 0x82
-	DLT_JUNIPER_MONITOR               = 0xa4
-	DLT_JUNIPER_PIC_PEER              = 0xae
-	DLT_JUNIPER_PPP                   = 0xb3
-	DLT_JUNIPER_PPPOE                 = 0xa7
-	DLT_JUNIPER_PPPOE_ATM             = 0xa8
-	DLT_JUNIPER_SERVICES              = 0x88
-	DLT_JUNIPER_SRX_E2E               = 0xe9
-	DLT_JUNIPER_ST                    = 0xc8
-	DLT_JUNIPER_VP                    = 0xb7
-	DLT_JUNIPER_VS                    = 0xe8
-	DLT_LAPB_WITH_DIR                 = 0xcf
-	DLT_LAPD                          = 0xcb
-	DLT_LIN                           = 0xd4
-	DLT_LINUX_EVDEV                   = 0xd8
-	DLT_LINUX_IRDA                    = 0x90
-	DLT_LINUX_LAPD                    = 0xb1
-	DLT_LINUX_PPP_WITHDIRECTION       = 0xa6
-	DLT_LINUX_SLL                     = 0x71
-	DLT_LOOP                          = 0x6c
-	DLT_LTALK                         = 0x72
-	DLT_MATCHING_MAX                  = 0xf5
-	DLT_MATCHING_MIN                  = 0x68
-	DLT_MFR                           = 0xb6
-	DLT_MOST                          = 0xd3
-	DLT_MPEG_2_TS                     = 0xf3
-	DLT_MPLS                          = 0xdb
-	DLT_MTP2                          = 0x8c
-	DLT_MTP2_WITH_PHDR                = 0x8b
-	DLT_MTP3                          = 0x8d
-	DLT_MUX27010                      = 0xec
-	DLT_NETANALYZER                   = 0xf0
-	DLT_NETANALYZER_TRANSPARENT       = 0xf1
-	DLT_NFC_LLCP                      = 0xf5
-	DLT_NFLOG                         = 0xef
-	DLT_NG40                          = 0xf4
-	DLT_NULL                          = 0x0
-	DLT_PCI_EXP                       = 0x7d
-	DLT_PFLOG                         = 0x75
-	DLT_PFSYNC                        = 0x12
-	DLT_PPI                           = 0xc0
-	DLT_PPP                           = 0x9
-	DLT_PPP_BSDOS                     = 0x10
-	DLT_PPP_ETHER                     = 0x33
-	DLT_PPP_PPPD                      = 0xa6
-	DLT_PPP_SERIAL                    = 0x32
-	DLT_PPP_WITH_DIR                  = 0xcc
-	DLT_PPP_WITH_DIRECTION            = 0xa6
-	DLT_PRISM_HEADER                  = 0x77
-	DLT_PRONET                        = 0x4
-	DLT_RAIF1                         = 0xc6
-	DLT_RAW                           = 0xc
-	DLT_RIO                           = 0x7c
-	DLT_SCCP                          = 0x8e
-	DLT_SITA                          = 0xc4
-	DLT_SLIP                          = 0x8
-	DLT_SLIP_BSDOS                    = 0xf
-	DLT_STANAG_5066_D_PDU             = 0xed
-	DLT_SUNATM                        = 0x7b
-	DLT_SYMANTEC_FIREWALL             = 0x63
-	DLT_TZSP                          = 0x80
-	DLT_USB                           = 0xba
-	DLT_USB_LINUX                     = 0xbd
-	DLT_USB_LINUX_MMAPPED             = 0xdc
-	DLT_USER0                         = 0x93
-	DLT_USER1                         = 0x94
-	DLT_USER10                        = 0x9d
-	DLT_USER11                        = 0x9e
-	DLT_USER12                        = 0x9f
-	DLT_USER13                        = 0xa0
-	DLT_USER14                        = 0xa1
-	DLT_USER15                        = 0xa2
-	DLT_USER2                         = 0x95
-	DLT_USER3                         = 0x96
-	DLT_USER4                         = 0x97
-	DLT_USER5                         = 0x98
-	DLT_USER6                         = 0x99
-	DLT_USER7                         = 0x9a
-	DLT_USER8                         = 0x9b
-	DLT_USER9                         = 0x9c
-	DLT_WIHART                        = 0xdf
-	DLT_X2E_SERIAL                    = 0xd5
-	DLT_X2E_XORAYA                    = 0xd6
-	DT_BLK                            = 0x6
-	DT_CHR                            = 0x2
-	DT_DIR                            = 0x4
-	DT_FIFO                           = 0x1
-	DT_LNK                            = 0xa
-	DT_REG                            = 0x8
-	DT_SOCK                           = 0xc
-	DT_UNKNOWN                        = 0x0
-	DT_WHT                            = 0xe
-	ECHO                              = 0x8
-	ECHOCTL                           = 0x40
-	ECHOE                             = 0x2
-	ECHOK                             = 0x4
-	ECHOKE                            = 0x1
-	ECHONL                            = 0x10
-	ECHOPRT                           = 0x20
-	EVFILT_AIO                        = -0x3
-	EVFILT_EXCEPT                     = -0xf
-	EVFILT_FS                         = -0x9
-	EVFILT_MACHPORT                   = -0x8
-	EVFILT_PROC                       = -0x5
-	EVFILT_READ                       = -0x1
-	EVFILT_SIGNAL                     = -0x6
-	EVFILT_SYSCOUNT                   = 0xf
-	EVFILT_THREADMARKER               = 0xf
-	EVFILT_TIMER                      = -0x7
-	EVFILT_USER                       = -0xa
-	EVFILT_VM                         = -0xc
-	EVFILT_VNODE                      = -0x4
-	EVFILT_WRITE                      = -0x2
-	EV_ADD                            = 0x1
-	EV_CLEAR                          = 0x20
-	EV_DELETE                         = 0x2
-	EV_DISABLE                        = 0x8
-	EV_DISPATCH                       = 0x80
-	EV_DISPATCH2                      = 0x180
-	EV_ENABLE                         = 0x4
-	EV_EOF                            = 0x8000
-	EV_ERROR                          = 0x4000
-	EV_FLAG0                          = 0x1000
-	EV_FLAG1                          = 0x2000
-	EV_ONESHOT                        = 0x10
-	EV_OOBAND                         = 0x2000
-	EV_POLL                           = 0x1000
-	EV_RECEIPT                        = 0x40
-	EV_SYSFLAGS                       = 0xf000
-	EV_UDATA_SPECIFIC                 = 0x100
-	EV_VANISHED                       = 0x200
-	EXTA                              = 0x4b00
-	EXTB                              = 0x9600
-	EXTPROC                           = 0x800
-	FD_CLOEXEC                        = 0x1
-	FD_SETSIZE                        = 0x400
-	FF0                               = 0x0
-	FF1                               = 0x4000
-	FFDLY                             = 0x4000
-	FLUSHO                            = 0x800000
-	FSOPT_ATTR_CMN_EXTENDED           = 0x20
-	FSOPT_NOFOLLOW                    = 0x1
-	FSOPT_NOINMEMUPDATE               = 0x2
-	FSOPT_PACK_INVAL_ATTRS            = 0x8
-	FSOPT_REPORT_FULLSIZE             = 0x4
-	F_ADDFILESIGS                     = 0x3d
-	F_ADDFILESIGS_FOR_DYLD_SIM        = 0x53
-	F_ADDFILESIGS_RETURN              = 0x61
-	F_ADDSIGS                         = 0x3b
-	F_ALLOCATEALL                     = 0x4
-	F_ALLOCATECONTIG                  = 0x2
-	F_BARRIERFSYNC                    = 0x55
-	F_CHECK_LV                        = 0x62
-	F_CHKCLEAN                        = 0x29
-	F_DUPFD                           = 0x0
-	F_DUPFD_CLOEXEC                   = 0x43
-	F_FINDSIGS                        = 0x4e
-	F_FLUSH_DATA                      = 0x28
-	F_FREEZE_FS                       = 0x35
-	F_FULLFSYNC                       = 0x33
-	F_GETCODEDIR                      = 0x48
-	F_GETFD                           = 0x1
-	F_GETFL                           = 0x3
-	F_GETLK                           = 0x7
-	F_GETLKPID                        = 0x42
-	F_GETNOSIGPIPE                    = 0x4a
-	F_GETOWN                          = 0x5
-	F_GETPATH                         = 0x32
-	F_GETPATH_MTMINFO                 = 0x47
-	F_GETPROTECTIONCLASS              = 0x3f
-	F_GETPROTECTIONLEVEL              = 0x4d
-	F_GLOBAL_NOCACHE                  = 0x37
-	F_LOG2PHYS                        = 0x31
-	F_LOG2PHYS_EXT                    = 0x41
-	F_NOCACHE                         = 0x30
-	F_NODIRECT                        = 0x3e
-	F_OK                              = 0x0
-	F_PATHPKG_CHECK                   = 0x34
-	F_PEOFPOSMODE                     = 0x3
-	F_PREALLOCATE                     = 0x2a
-	F_PUNCHHOLE                       = 0x63
-	F_RDADVISE                        = 0x2c
-	F_RDAHEAD                         = 0x2d
-	F_RDLCK                           = 0x1
-	F_SETBACKINGSTORE                 = 0x46
-	F_SETFD                           = 0x2
-	F_SETFL                           = 0x4
-	F_SETLK                           = 0x8
-	F_SETLKW                          = 0x9
-	F_SETLKWTIMEOUT                   = 0xa
-	F_SETNOSIGPIPE                    = 0x49
-	F_SETOWN                          = 0x6
-	F_SETPROTECTIONCLASS              = 0x40
-	F_SETSIZE                         = 0x2b
-	F_SINGLE_WRITER                   = 0x4c
-	F_THAW_FS                         = 0x36
-	F_TRANSCODEKEY                    = 0x4b
-	F_TRIM_ACTIVE_FILE                = 0x64
-	F_UNLCK                           = 0x2
-	F_VOLPOSMODE                      = 0x4
-	F_WRLCK                           = 0x3
-	HUPCL                             = 0x4000
-	HW_MACHINE                        = 0x1
-	ICANON                            = 0x100
-	ICMP6_FILTER                      = 0x12
-	ICRNL                             = 0x100
-	IEXTEN                            = 0x400
-	IFF_ALLMULTI                      = 0x200
-	IFF_ALTPHYS                       = 0x4000
-	IFF_BROADCAST                     = 0x2
-	IFF_DEBUG                         = 0x4
-	IFF_LINK0                         = 0x1000
-	IFF_LINK1                         = 0x2000
-	IFF_LINK2                         = 0x4000
-	IFF_LOOPBACK                      = 0x8
-	IFF_MULTICAST                     = 0x8000
-	IFF_NOARP                         = 0x80
-	IFF_NOTRAILERS                    = 0x20
-	IFF_OACTIVE                       = 0x400
-	IFF_POINTOPOINT                   = 0x10
-	IFF_PROMISC                       = 0x100
-	IFF_RUNNING                       = 0x40
-	IFF_SIMPLEX                       = 0x800
-	IFF_UP                            = 0x1
-	IFNAMSIZ                          = 0x10
-	IFT_1822                          = 0x2
-	IFT_AAL5                          = 0x31
-	IFT_ARCNET                        = 0x23
-	IFT_ARCNETPLUS                    = 0x24
-	IFT_ATM                           = 0x25
-	IFT_BRIDGE                        = 0xd1
-	IFT_CARP                          = 0xf8
-	IFT_CELLULAR                      = 0xff
-	IFT_CEPT                          = 0x13
-	IFT_DS3                           = 0x1e
-	IFT_ENC                           = 0xf4
-	IFT_EON                           = 0x19
-	IFT_ETHER                         = 0x6
-	IFT_FAITH                         = 0x38
-	IFT_FDDI                          = 0xf
-	IFT_FRELAY                        = 0x20
-	IFT_FRELAYDCE                     = 0x2c
-	IFT_GIF                           = 0x37
-	IFT_HDH1822                       = 0x3
-	IFT_HIPPI                         = 0x2f
-	IFT_HSSI                          = 0x2e
-	IFT_HY                            = 0xe
-	IFT_IEEE1394                      = 0x90
-	IFT_IEEE8023ADLAG                 = 0x88
-	IFT_ISDNBASIC                     = 0x14
-	IFT_ISDNPRIMARY                   = 0x15
-	IFT_ISO88022LLC                   = 0x29
-	IFT_ISO88023                      = 0x7
-	IFT_ISO88024                      = 0x8
-	IFT_ISO88025                      = 0x9
-	IFT_ISO88026                      = 0xa
-	IFT_L2VLAN                        = 0x87
-	IFT_LAPB                          = 0x10
-	IFT_LOCALTALK                     = 0x2a
-	IFT_LOOP                          = 0x18
-	IFT_MIOX25                        = 0x26
-	IFT_MODEM                         = 0x30
-	IFT_NSIP                          = 0x1b
-	IFT_OTHER                         = 0x1
-	IFT_P10                           = 0xc
-	IFT_P80                           = 0xd
-	IFT_PARA                          = 0x22
-	IFT_PDP                           = 0xff
-	IFT_PFLOG                         = 0xf5
-	IFT_PFSYNC                        = 0xf6
-	IFT_PKTAP                         = 0xfe
-	IFT_PPP                           = 0x17
-	IFT_PROPMUX                       = 0x36
-	IFT_PROPVIRTUAL                   = 0x35
-	IFT_PTPSERIAL                     = 0x16
-	IFT_RS232                         = 0x21
-	IFT_SDLC                          = 0x11
-	IFT_SIP                           = 0x1f
-	IFT_SLIP                          = 0x1c
-	IFT_SMDSDXI                       = 0x2b
-	IFT_SMDSICIP                      = 0x34
-	IFT_SONET                         = 0x27
-	IFT_SONETPATH                     = 0x32
-	IFT_SONETVT                       = 0x33
-	IFT_STARLAN                       = 0xb
-	IFT_STF                           = 0x39
-	IFT_T1                            = 0x12
-	IFT_ULTRA                         = 0x1d
-	IFT_V35                           = 0x2d
-	IFT_X25                           = 0x5
-	IFT_X25DDN                        = 0x4
-	IFT_X25PLE                        = 0x28
-	IFT_XETHER                        = 0x1a
-	IGNBRK                            = 0x1
-	IGNCR                             = 0x80
-	IGNPAR                            = 0x4
-	IMAXBEL                           = 0x2000
-	INLCR                             = 0x40
-	INPCK                             = 0x10
-	IN_CLASSA_HOST                    = 0xffffff
-	IN_CLASSA_MAX                     = 0x80
-	IN_CLASSA_NET                     = 0xff000000
-	IN_CLASSA_NSHIFT                  = 0x18
-	IN_CLASSB_HOST                    = 0xffff
-	IN_CLASSB_MAX                     = 0x10000
-	IN_CLASSB_NET                     = 0xffff0000
-	IN_CLASSB_NSHIFT                  = 0x10
-	IN_CLASSC_HOST                    = 0xff
-	IN_CLASSC_NET                     = 0xffffff00
-	IN_CLASSC_NSHIFT                  = 0x8
-	IN_CLASSD_HOST                    = 0xfffffff
-	IN_CLASSD_NET                     = 0xf0000000
-	IN_CLASSD_NSHIFT                  = 0x1c
-	IN_LINKLOCALNETNUM                = 0xa9fe0000
-	IN_LOOPBACKNET                    = 0x7f
-	IPPROTO_3PC                       = 0x22
-	IPPROTO_ADFS                      = 0x44
-	IPPROTO_AH                        = 0x33
-	IPPROTO_AHIP                      = 0x3d
-	IPPROTO_APES                      = 0x63
-	IPPROTO_ARGUS                     = 0xd
-	IPPROTO_AX25                      = 0x5d
-	IPPROTO_BHA                       = 0x31
-	IPPROTO_BLT                       = 0x1e
-	IPPROTO_BRSATMON                  = 0x4c
-	IPPROTO_CFTP                      = 0x3e
-	IPPROTO_CHAOS                     = 0x10
-	IPPROTO_CMTP                      = 0x26
-	IPPROTO_CPHB                      = 0x49
-	IPPROTO_CPNX                      = 0x48
-	IPPROTO_DDP                       = 0x25
-	IPPROTO_DGP                       = 0x56
-	IPPROTO_DIVERT                    = 0xfe
-	IPPROTO_DONE                      = 0x101
-	IPPROTO_DSTOPTS                   = 0x3c
-	IPPROTO_EGP                       = 0x8
-	IPPROTO_EMCON                     = 0xe
-	IPPROTO_ENCAP                     = 0x62
-	IPPROTO_EON                       = 0x50
-	IPPROTO_ESP                       = 0x32
-	IPPROTO_ETHERIP                   = 0x61
-	IPPROTO_FRAGMENT                  = 0x2c
-	IPPROTO_GGP                       = 0x3
-	IPPROTO_GMTP                      = 0x64
-	IPPROTO_GRE                       = 0x2f
-	IPPROTO_HELLO                     = 0x3f
-	IPPROTO_HMP                       = 0x14
-	IPPROTO_HOPOPTS                   = 0x0
-	IPPROTO_ICMP                      = 0x1
-	IPPROTO_ICMPV6                    = 0x3a
-	IPPROTO_IDP                       = 0x16
-	IPPROTO_IDPR                      = 0x23
-	IPPROTO_IDRP                      = 0x2d
-	IPPROTO_IGMP                      = 0x2
-	IPPROTO_IGP                       = 0x55
-	IPPROTO_IGRP                      = 0x58
-	IPPROTO_IL                        = 0x28
-	IPPROTO_INLSP                     = 0x34
-	IPPROTO_INP                       = 0x20
-	IPPROTO_IP                        = 0x0
-	IPPROTO_IPCOMP                    = 0x6c
-	IPPROTO_IPCV                      = 0x47
-	IPPROTO_IPEIP                     = 0x5e
-	IPPROTO_IPIP                      = 0x4
-	IPPROTO_IPPC                      = 0x43
-	IPPROTO_IPV4                      = 0x4
-	IPPROTO_IPV6                      = 0x29
-	IPPROTO_IRTP                      = 0x1c
-	IPPROTO_KRYPTOLAN                 = 0x41
-	IPPROTO_LARP                      = 0x5b
-	IPPROTO_LEAF1                     = 0x19
-	IPPROTO_LEAF2                     = 0x1a
-	IPPROTO_MAX                       = 0x100
-	IPPROTO_MAXID                     = 0x34
-	IPPROTO_MEAS                      = 0x13
-	IPPROTO_MHRP                      = 0x30
-	IPPROTO_MICP                      = 0x5f
-	IPPROTO_MTP                       = 0x5c
-	IPPROTO_MUX                       = 0x12
-	IPPROTO_ND                        = 0x4d
-	IPPROTO_NHRP                      = 0x36
-	IPPROTO_NONE                      = 0x3b
-	IPPROTO_NSP                       = 0x1f
-	IPPROTO_NVPII                     = 0xb
-	IPPROTO_OSPFIGP                   = 0x59
-	IPPROTO_PGM                       = 0x71
-	IPPROTO_PIGP                      = 0x9
-	IPPROTO_PIM                       = 0x67
-	IPPROTO_PRM                       = 0x15
-	IPPROTO_PUP                       = 0xc
-	IPPROTO_PVP                       = 0x4b
-	IPPROTO_RAW                       = 0xff
-	IPPROTO_RCCMON                    = 0xa
-	IPPROTO_RDP                       = 0x1b
-	IPPROTO_ROUTING                   = 0x2b
-	IPPROTO_RSVP                      = 0x2e
-	IPPROTO_RVD                       = 0x42
-	IPPROTO_SATEXPAK                  = 0x40
-	IPPROTO_SATMON                    = 0x45
-	IPPROTO_SCCSP                     = 0x60
-	IPPROTO_SCTP                      = 0x84
-	IPPROTO_SDRP                      = 0x2a
-	IPPROTO_SEP                       = 0x21
-	IPPROTO_SRPC                      = 0x5a
-	IPPROTO_ST                        = 0x7
-	IPPROTO_SVMTP                     = 0x52
-	IPPROTO_SWIPE                     = 0x35
-	IPPROTO_TCF                       = 0x57
-	IPPROTO_TCP                       = 0x6
-	IPPROTO_TP                        = 0x1d
-	IPPROTO_TPXX                      = 0x27
-	IPPROTO_TRUNK1                    = 0x17
-	IPPROTO_TRUNK2                    = 0x18
-	IPPROTO_TTP                       = 0x54
-	IPPROTO_UDP                       = 0x11
-	IPPROTO_VINES                     = 0x53
-	IPPROTO_VISA                      = 0x46
-	IPPROTO_VMTP                      = 0x51
-	IPPROTO_WBEXPAK                   = 0x4f
-	IPPROTO_WBMON                     = 0x4e
-	IPPROTO_WSN                       = 0x4a
-	IPPROTO_XNET                      = 0xf
-	IPPROTO_XTP                       = 0x24
-	IPV6_2292DSTOPTS                  = 0x17
-	IPV6_2292HOPLIMIT                 = 0x14
-	IPV6_2292HOPOPTS                  = 0x16
-	IPV6_2292NEXTHOP                  = 0x15
-	IPV6_2292PKTINFO                  = 0x13
-	IPV6_2292PKTOPTIONS               = 0x19
-	IPV6_2292RTHDR                    = 0x18
-	IPV6_BINDV6ONLY                   = 0x1b
-	IPV6_BOUND_IF                     = 0x7d
-	IPV6_CHECKSUM                     = 0x1a
-	IPV6_DEFAULT_MULTICAST_HOPS       = 0x1
-	IPV6_DEFAULT_MULTICAST_LOOP       = 0x1
-	IPV6_DEFHLIM                      = 0x40
-	IPV6_FAITH                        = 0x1d
-	IPV6_FLOWINFO_MASK                = 0xffffff0f
-	IPV6_FLOWLABEL_MASK               = 0xffff0f00
-	IPV6_FLOW_ECN_MASK                = 0x300
-	IPV6_FRAGTTL                      = 0x3c
-	IPV6_FW_ADD                       = 0x1e
-	IPV6_FW_DEL                       = 0x1f
-	IPV6_FW_FLUSH                     = 0x20
-	IPV6_FW_GET                       = 0x22
-	IPV6_FW_ZERO                      = 0x21
-	IPV6_HLIMDEC                      = 0x1
-	IPV6_IPSEC_POLICY                 = 0x1c
-	IPV6_JOIN_GROUP                   = 0xc
-	IPV6_LEAVE_GROUP                  = 0xd
-	IPV6_MAXHLIM                      = 0xff
-	IPV6_MAXOPTHDR                    = 0x800
-	IPV6_MAXPACKET                    = 0xffff
-	IPV6_MAX_GROUP_SRC_FILTER         = 0x200
-	IPV6_MAX_MEMBERSHIPS              = 0xfff
-	IPV6_MAX_SOCK_SRC_FILTER          = 0x80
-	IPV6_MIN_MEMBERSHIPS              = 0x1f
-	IPV6_MMTU                         = 0x500
-	IPV6_MULTICAST_HOPS               = 0xa
-	IPV6_MULTICAST_IF                 = 0x9
-	IPV6_MULTICAST_LOOP               = 0xb
-	IPV6_PORTRANGE                    = 0xe
-	IPV6_PORTRANGE_DEFAULT            = 0x0
-	IPV6_PORTRANGE_HIGH               = 0x1
-	IPV6_PORTRANGE_LOW                = 0x2
-	IPV6_RECVTCLASS                   = 0x23
-	IPV6_RTHDR_LOOSE                  = 0x0
-	IPV6_RTHDR_STRICT                 = 0x1
-	IPV6_RTHDR_TYPE_0                 = 0x0
-	IPV6_SOCKOPT_RESERVED1            = 0x3
-	IPV6_TCLASS                       = 0x24
-	IPV6_UNICAST_HOPS                 = 0x4
-	IPV6_V6ONLY                       = 0x1b
-	IPV6_VERSION                      = 0x60
-	IPV6_VERSION_MASK                 = 0xf0
-	IP_ADD_MEMBERSHIP                 = 0xc
-	IP_ADD_SOURCE_MEMBERSHIP          = 0x46
-	IP_BLOCK_SOURCE                   = 0x48
-	IP_BOUND_IF                       = 0x19
-	IP_DEFAULT_MULTICAST_LOOP         = 0x1
-	IP_DEFAULT_MULTICAST_TTL          = 0x1
-	IP_DF                             = 0x4000
-	IP_DROP_MEMBERSHIP                = 0xd
-	IP_DROP_SOURCE_MEMBERSHIP         = 0x47
-	IP_DUMMYNET_CONFIGURE             = 0x3c
-	IP_DUMMYNET_DEL                   = 0x3d
-	IP_DUMMYNET_FLUSH                 = 0x3e
-	IP_DUMMYNET_GET                   = 0x40
-	IP_FAITH                          = 0x16
-	IP_FW_ADD                         = 0x28
-	IP_FW_DEL                         = 0x29
-	IP_FW_FLUSH                       = 0x2a
-	IP_FW_GET                         = 0x2c
-	IP_FW_RESETLOG                    = 0x2d
-	IP_FW_ZERO                        = 0x2b
-	IP_HDRINCL                        = 0x2
-	IP_IPSEC_POLICY                   = 0x15
-	IP_MAXPACKET                      = 0xffff
-	IP_MAX_GROUP_SRC_FILTER           = 0x200
-	IP_MAX_MEMBERSHIPS                = 0xfff
-	IP_MAX_SOCK_MUTE_FILTER           = 0x80
-	IP_MAX_SOCK_SRC_FILTER            = 0x80
-	IP_MF                             = 0x2000
-	IP_MIN_MEMBERSHIPS                = 0x1f
-	IP_MSFILTER                       = 0x4a
-	IP_MSS                            = 0x240
-	IP_MULTICAST_IF                   = 0x9
-	IP_MULTICAST_IFINDEX              = 0x42
-	IP_MULTICAST_LOOP                 = 0xb
-	IP_MULTICAST_TTL                  = 0xa
-	IP_MULTICAST_VIF                  = 0xe
-	IP_NAT__XXX                       = 0x37
-	IP_OFFMASK                        = 0x1fff
-	IP_OLD_FW_ADD                     = 0x32
-	IP_OLD_FW_DEL                     = 0x33
-	IP_OLD_FW_FLUSH                   = 0x34
-	IP_OLD_FW_GET                     = 0x36
-	IP_OLD_FW_RESETLOG                = 0x38
-	IP_OLD_FW_ZERO                    = 0x35
-	IP_OPTIONS                        = 0x1
-	IP_PKTINFO                        = 0x1a
-	IP_PORTRANGE                      = 0x13
-	IP_PORTRANGE_DEFAULT              = 0x0
-	IP_PORTRANGE_HIGH                 = 0x1
-	IP_PORTRANGE_LOW                  = 0x2
-	IP_RECVDSTADDR                    = 0x7
-	IP_RECVIF                         = 0x14
-	IP_RECVOPTS                       = 0x5
-	IP_RECVPKTINFO                    = 0x1a
-	IP_RECVRETOPTS                    = 0x6
-	IP_RECVTOS                        = 0x1b
-	IP_RECVTTL                        = 0x18
-	IP_RETOPTS                        = 0x8
-	IP_RF                             = 0x8000
-	IP_RSVP_OFF                       = 0x10
-	IP_RSVP_ON                        = 0xf
-	IP_RSVP_VIF_OFF                   = 0x12
-	IP_RSVP_VIF_ON                    = 0x11
-	IP_STRIPHDR                       = 0x17
-	IP_TOS                            = 0x3
-	IP_TRAFFIC_MGT_BACKGROUND         = 0x41
-	IP_TTL                            = 0x4
-	IP_UNBLOCK_SOURCE                 = 0x49
-	ISIG                              = 0x80
-	ISTRIP                            = 0x20
-	IUTF8                             = 0x4000
-	IXANY                             = 0x800
-	IXOFF                             = 0x400
-	IXON                              = 0x200
-	KERN_HOSTNAME                     = 0xa
-	KERN_OSRELEASE                    = 0x2
-	KERN_OSTYPE                       = 0x1
-	KERN_VERSION                      = 0x4
-	LOCK_EX                           = 0x2
-	LOCK_NB                           = 0x4
-	LOCK_SH                           = 0x1
-	LOCK_UN                           = 0x8
-	MADV_CAN_REUSE                    = 0x9
-	MADV_DONTNEED                     = 0x4
-	MADV_FREE                         = 0x5
-	MADV_FREE_REUSABLE                = 0x7
-	MADV_FREE_REUSE                   = 0x8
-	MADV_NORMAL                       = 0x0
-	MADV_PAGEOUT                      = 0xa
-	MADV_RANDOM                       = 0x1
-	MADV_SEQUENTIAL                   = 0x2
-	MADV_WILLNEED                     = 0x3
-	MADV_ZERO_WIRED_PAGES             = 0x6
-	MAP_ANON                          = 0x1000
-	MAP_ANONYMOUS                     = 0x1000
-	MAP_COPY                          = 0x2
-	MAP_FILE                          = 0x0
-	MAP_FIXED                         = 0x10
-	MAP_HASSEMAPHORE                  = 0x200
-	MAP_JIT                           = 0x800
-	MAP_NOCACHE                       = 0x400
-	MAP_NOEXTEND                      = 0x100
-	MAP_NORESERVE                     = 0x40
-	MAP_PRIVATE                       = 0x2
-	MAP_RENAME                        = 0x20
-	MAP_RESERVED0080                  = 0x80
-	MAP_RESILIENT_CODESIGN            = 0x2000
-	MAP_RESILIENT_MEDIA               = 0x4000
-	MAP_SHARED                        = 0x1
-	MCL_CURRENT                       = 0x1
-	MCL_FUTURE                        = 0x2
-	MNT_ASYNC                         = 0x40
-	MNT_AUTOMOUNTED                   = 0x400000
-	MNT_CMDFLAGS                      = 0xf0000
-	MNT_CPROTECT                      = 0x80
-	MNT_DEFWRITE                      = 0x2000000
-	MNT_DONTBROWSE                    = 0x100000
-	MNT_DOVOLFS                       = 0x8000
-	MNT_DWAIT                         = 0x4
-	MNT_EXPORTED                      = 0x100
-	MNT_FORCE                         = 0x80000
-	MNT_IGNORE_OWNERSHIP              = 0x200000
-	MNT_JOURNALED                     = 0x800000
-	MNT_LOCAL                         = 0x1000
-	MNT_MULTILABEL                    = 0x4000000
-	MNT_NOATIME                       = 0x10000000
-	MNT_NOBLOCK                       = 0x20000
-	MNT_NODEV                         = 0x10
-	MNT_NOEXEC                        = 0x4
-	MNT_NOSUID                        = 0x8
-	MNT_NOUSERXATTR                   = 0x1000000
-	MNT_NOWAIT                        = 0x2
-	MNT_QUARANTINE                    = 0x400
-	MNT_QUOTA                         = 0x2000
-	MNT_RDONLY                        = 0x1
-	MNT_RELOAD                        = 0x40000
-	MNT_ROOTFS                        = 0x4000
-	MNT_SYNCHRONOUS                   = 0x2
-	MNT_UNION                         = 0x20
-	MNT_UNKNOWNPERMISSIONS            = 0x200000
-	MNT_UPDATE                        = 0x10000
-	MNT_VISFLAGMASK                   = 0x17f0f5ff
-	MNT_WAIT                          = 0x1
-	MSG_CTRUNC                        = 0x20
-	MSG_DONTROUTE                     = 0x4
-	MSG_DONTWAIT                      = 0x80
-	MSG_EOF                           = 0x100
-	MSG_EOR                           = 0x8
-	MSG_FLUSH                         = 0x400
-	MSG_HAVEMORE                      = 0x2000
-	MSG_HOLD                          = 0x800
-	MSG_NEEDSA                        = 0x10000
-	MSG_OOB                           = 0x1
-	MSG_PEEK                          = 0x2
-	MSG_RCVMORE                       = 0x4000
-	MSG_SEND                          = 0x1000
-	MSG_TRUNC                         = 0x10
-	MSG_WAITALL                       = 0x40
-	MSG_WAITSTREAM                    = 0x200
-	MS_ASYNC                          = 0x1
-	MS_DEACTIVATE                     = 0x8
-	MS_INVALIDATE                     = 0x2
-	MS_KILLPAGES                      = 0x4
-	MS_SYNC                           = 0x10
-	NAME_MAX                          = 0xff
-	NET_RT_DUMP                       = 0x1
-	NET_RT_DUMP2                      = 0x7
-	NET_RT_FLAGS                      = 0x2
-	NET_RT_IFLIST                     = 0x3
-	NET_RT_IFLIST2                    = 0x6
-	NET_RT_MAXID                      = 0xa
-	NET_RT_STAT                       = 0x4
-	NET_RT_TRASH                      = 0x5
-	NFDBITS                           = 0x20
-	NL0                               = 0x0
-	NL1                               = 0x100
-	NL2                               = 0x200
-	NL3                               = 0x300
-	NLDLY                             = 0x300
-	NOFLSH                            = 0x80000000
-	NOKERNINFO                        = 0x2000000
-	NOTE_ABSOLUTE                     = 0x8
-	NOTE_ATTRIB                       = 0x8
-	NOTE_BACKGROUND                   = 0x40
-	NOTE_CHILD                        = 0x4
-	NOTE_CRITICAL                     = 0x20
-	NOTE_DELETE                       = 0x1
-	NOTE_EXEC                         = 0x20000000
-	NOTE_EXIT                         = 0x80000000
-	NOTE_EXITSTATUS                   = 0x4000000
-	NOTE_EXIT_CSERROR                 = 0x40000
-	NOTE_EXIT_DECRYPTFAIL             = 0x10000
-	NOTE_EXIT_DETAIL                  = 0x2000000
-	NOTE_EXIT_DETAIL_MASK             = 0x70000
-	NOTE_EXIT_MEMORY                  = 0x20000
-	NOTE_EXIT_REPARENTED              = 0x80000
-	NOTE_EXTEND                       = 0x4
-	NOTE_FFAND                        = 0x40000000
-	NOTE_FFCOPY                       = 0xc0000000
-	NOTE_FFCTRLMASK                   = 0xc0000000
-	NOTE_FFLAGSMASK                   = 0xffffff
-	NOTE_FFNOP                        = 0x0
-	NOTE_FFOR                         = 0x80000000
-	NOTE_FORK                         = 0x40000000
-	NOTE_FUNLOCK                      = 0x100
-	NOTE_LEEWAY                       = 0x10
-	NOTE_LINK                         = 0x10
-	NOTE_LOWAT                        = 0x1
-	NOTE_MACH_CONTINUOUS_TIME         = 0x80
-	NOTE_NONE                         = 0x80
-	NOTE_NSECONDS                     = 0x4
-	NOTE_OOB                          = 0x2
-	NOTE_PCTRLMASK                    = -0x100000
-	NOTE_PDATAMASK                    = 0xfffff
-	NOTE_REAP                         = 0x10000000
-	NOTE_RENAME                       = 0x20
-	NOTE_REVOKE                       = 0x40
-	NOTE_SECONDS                      = 0x1
-	NOTE_SIGNAL                       = 0x8000000
-	NOTE_TRACK                        = 0x1
-	NOTE_TRACKERR                     = 0x2
-	NOTE_TRIGGER                      = 0x1000000
-	NOTE_USECONDS                     = 0x2
-	NOTE_VM_ERROR                     = 0x10000000
-	NOTE_VM_PRESSURE                  = 0x80000000
-	NOTE_VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000
-	NOTE_VM_PRESSURE_TERMINATE        = 0x40000000
-	NOTE_WRITE                        = 0x2
-	OCRNL                             = 0x10
-	OFDEL                             = 0x20000
-	OFILL                             = 0x80
-	ONLCR                             = 0x2
-	ONLRET                            = 0x40
-	ONOCR                             = 0x20
-	ONOEOT                            = 0x8
-	OPOST                             = 0x1
-	OXTABS                            = 0x4
-	O_ACCMODE                         = 0x3
-	O_ALERT                           = 0x20000000
-	O_APPEND                          = 0x8
-	O_ASYNC                           = 0x40
-	O_CLOEXEC                         = 0x1000000
-	O_CREAT                           = 0x200
-	O_DIRECTORY                       = 0x100000
-	O_DP_GETRAWENCRYPTED              = 0x1
-	O_DP_GETRAWUNENCRYPTED            = 0x2
-	O_DSYNC                           = 0x400000
-	O_EVTONLY                         = 0x8000
-	O_EXCL                            = 0x800
-	O_EXLOCK                          = 0x20
-	O_FSYNC                           = 0x80
-	O_NDELAY                          = 0x4
-	O_NOCTTY                          = 0x20000
-	O_NOFOLLOW                        = 0x100
-	O_NONBLOCK                        = 0x4
-	O_POPUP                           = 0x80000000
-	O_RDONLY                          = 0x0
-	O_RDWR                            = 0x2
-	O_SHLOCK                          = 0x10
-	O_SYMLINK                         = 0x200000
-	O_SYNC                            = 0x80
-	O_TRUNC                           = 0x400
-	O_WRONLY                          = 0x1
-	PARENB                            = 0x1000
-	PARMRK                            = 0x8
-	PARODD                            = 0x2000
-	PENDIN                            = 0x20000000
-	PRIO_PGRP                         = 0x1
-	PRIO_PROCESS                      = 0x0
-	PRIO_USER                         = 0x2
-	PROT_EXEC                         = 0x4
-	PROT_NONE                         = 0x0
-	PROT_READ                         = 0x1
-	PROT_WRITE                        = 0x2
-	PT_ATTACH                         = 0xa
-	PT_ATTACHEXC                      = 0xe
-	PT_CONTINUE                       = 0x7
-	PT_DENY_ATTACH                    = 0x1f
-	PT_DETACH                         = 0xb
-	PT_FIRSTMACH                      = 0x20
-	PT_FORCEQUOTA                     = 0x1e
-	PT_KILL                           = 0x8
-	PT_READ_D                         = 0x2
-	PT_READ_I                         = 0x1
-	PT_READ_U                         = 0x3
-	PT_SIGEXC                         = 0xc
-	PT_STEP                           = 0x9
-	PT_THUPDATE                       = 0xd
-	PT_TRACE_ME                       = 0x0
-	PT_WRITE_D                        = 0x5
-	PT_WRITE_I                        = 0x4
-	PT_WRITE_U                        = 0x6
-	RLIMIT_AS                         = 0x5
-	RLIMIT_CORE                       = 0x4
-	RLIMIT_CPU                        = 0x0
-	RLIMIT_CPU_USAGE_MONITOR          = 0x2
-	RLIMIT_DATA                       = 0x2
-	RLIMIT_FSIZE                      = 0x1
-	RLIMIT_MEMLOCK                    = 0x6
-	RLIMIT_NOFILE                     = 0x8
-	RLIMIT_NPROC                      = 0x7
-	RLIMIT_RSS                        = 0x5
-	RLIMIT_STACK                      = 0x3
-	RLIM_INFINITY                     = 0x7fffffffffffffff
-	RTAX_AUTHOR                       = 0x6
-	RTAX_BRD                          = 0x7
-	RTAX_DST                          = 0x0
-	RTAX_GATEWAY                      = 0x1
-	RTAX_GENMASK                      = 0x3
-	RTAX_IFA                          = 0x5
-	RTAX_IFP                          = 0x4
-	RTAX_MAX                          = 0x8
-	RTAX_NETMASK                      = 0x2
-	RTA_AUTHOR                        = 0x40
-	RTA_BRD                           = 0x80
-	RTA_DST                           = 0x1
-	RTA_GATEWAY                       = 0x2
-	RTA_GENMASK                       = 0x8
-	RTA_IFA                           = 0x20
-	RTA_IFP                           = 0x10
-	RTA_NETMASK                       = 0x4
-	RTF_BLACKHOLE                     = 0x1000
-	RTF_BROADCAST                     = 0x400000
-	RTF_CLONING                       = 0x100
-	RTF_CONDEMNED                     = 0x2000000
-	RTF_DELCLONE                      = 0x80
-	RTF_DONE                          = 0x40
-	RTF_DYNAMIC                       = 0x10
-	RTF_GATEWAY                       = 0x2
-	RTF_HOST                          = 0x4
-	RTF_IFREF                         = 0x4000000
-	RTF_IFSCOPE                       = 0x1000000
-	RTF_LLINFO                        = 0x400
-	RTF_LOCAL                         = 0x200000
-	RTF_MODIFIED                      = 0x20
-	RTF_MULTICAST                     = 0x800000
-	RTF_NOIFREF                       = 0x2000
-	RTF_PINNED                        = 0x100000
-	RTF_PRCLONING                     = 0x10000
-	RTF_PROTO1                        = 0x8000
-	RTF_PROTO2                        = 0x4000
-	RTF_PROTO3                        = 0x40000
-	RTF_PROXY                         = 0x8000000
-	RTF_REJECT                        = 0x8
-	RTF_ROUTER                        = 0x10000000
-	RTF_STATIC                        = 0x800
-	RTF_UP                            = 0x1
-	RTF_WASCLONED                     = 0x20000
-	RTF_XRESOLVE                      = 0x200
-	RTM_ADD                           = 0x1
-	RTM_CHANGE                        = 0x3
-	RTM_DELADDR                       = 0xd
-	RTM_DELETE                        = 0x2
-	RTM_DELMADDR                      = 0x10
-	RTM_GET                           = 0x4
-	RTM_GET2                          = 0x14
-	RTM_IFINFO                        = 0xe
-	RTM_IFINFO2                       = 0x12
-	RTM_LOCK                          = 0x8
-	RTM_LOSING                        = 0x5
-	RTM_MISS                          = 0x7
-	RTM_NEWADDR                       = 0xc
-	RTM_NEWMADDR                      = 0xf
-	RTM_NEWMADDR2                     = 0x13
-	RTM_OLDADD                        = 0x9
-	RTM_OLDDEL                        = 0xa
-	RTM_REDIRECT                      = 0x6
-	RTM_RESOLVE                       = 0xb
-	RTM_RTTUNIT                       = 0xf4240
-	RTM_VERSION                       = 0x5
-	RTV_EXPIRE                        = 0x4
-	RTV_HOPCOUNT                      = 0x2
-	RTV_MTU                           = 0x1
-	RTV_RPIPE                         = 0x8
-	RTV_RTT                           = 0x40
-	RTV_RTTVAR                        = 0x80
-	RTV_SPIPE                         = 0x10
-	RTV_SSTHRESH                      = 0x20
-	RUSAGE_CHILDREN                   = -0x1
-	RUSAGE_SELF                       = 0x0
-	SCM_CREDS                         = 0x3
-	SCM_RIGHTS                        = 0x1
-	SCM_TIMESTAMP                     = 0x2
-	SCM_TIMESTAMP_MONOTONIC           = 0x4
-	SHUT_RD                           = 0x0
-	SHUT_RDWR                         = 0x2
-	SHUT_WR                           = 0x1
-	SIOCADDMULTI                      = 0x80206931
-	SIOCAIFADDR                       = 0x8040691a
-	SIOCARPIPLL                       = 0xc0206928
-	SIOCATMARK                        = 0x40047307
-	SIOCAUTOADDR                      = 0xc0206926
-	SIOCAUTONETMASK                   = 0x80206927
-	SIOCDELMULTI                      = 0x80206932
-	SIOCDIFADDR                       = 0x80206919
-	SIOCDIFPHYADDR                    = 0x80206941
-	SIOCGDRVSPEC                      = 0xc01c697b
-	SIOCGETVLAN                       = 0xc020697f
-	SIOCGHIWAT                        = 0x40047301
-	SIOCGIFADDR                       = 0xc0206921
-	SIOCGIFALTMTU                     = 0xc0206948
-	SIOCGIFASYNCMAP                   = 0xc020697c
-	SIOCGIFBOND                       = 0xc0206947
-	SIOCGIFBRDADDR                    = 0xc0206923
-	SIOCGIFCAP                        = 0xc020695b
-	SIOCGIFCONF                       = 0xc0086924
-	SIOCGIFDEVMTU                     = 0xc0206944
-	SIOCGIFDSTADDR                    = 0xc0206922
-	SIOCGIFFLAGS                      = 0xc0206911
-	SIOCGIFGENERIC                    = 0xc020693a
-	SIOCGIFKPI                        = 0xc0206987
-	SIOCGIFMAC                        = 0xc0206982
-	SIOCGIFMEDIA                      = 0xc0286938
-	SIOCGIFMETRIC                     = 0xc0206917
-	SIOCGIFMTU                        = 0xc0206933
-	SIOCGIFNETMASK                    = 0xc0206925
-	SIOCGIFPDSTADDR                   = 0xc0206940
-	SIOCGIFPHYS                       = 0xc0206935
-	SIOCGIFPSRCADDR                   = 0xc020693f
-	SIOCGIFSTATUS                     = 0xc331693d
-	SIOCGIFVLAN                       = 0xc020697f
-	SIOCGIFWAKEFLAGS                  = 0xc0206988
-	SIOCGLOWAT                        = 0x40047303
-	SIOCGPGRP                         = 0x40047309
-	SIOCIFCREATE                      = 0xc0206978
-	SIOCIFCREATE2                     = 0xc020697a
-	SIOCIFDESTROY                     = 0x80206979
-	SIOCIFGCLONERS                    = 0xc00c6981
-	SIOCRSLVMULTI                     = 0xc008693b
-	SIOCSDRVSPEC                      = 0x801c697b
-	SIOCSETVLAN                       = 0x8020697e
-	SIOCSHIWAT                        = 0x80047300
-	SIOCSIFADDR                       = 0x8020690c
-	SIOCSIFALTMTU                     = 0x80206945
-	SIOCSIFASYNCMAP                   = 0x8020697d
-	SIOCSIFBOND                       = 0x80206946
-	SIOCSIFBRDADDR                    = 0x80206913
-	SIOCSIFCAP                        = 0x8020695a
-	SIOCSIFDSTADDR                    = 0x8020690e
-	SIOCSIFFLAGS                      = 0x80206910
-	SIOCSIFGENERIC                    = 0x80206939
-	SIOCSIFKPI                        = 0x80206986
-	SIOCSIFLLADDR                     = 0x8020693c
-	SIOCSIFMAC                        = 0x80206983
-	SIOCSIFMEDIA                      = 0xc0206937
-	SIOCSIFMETRIC                     = 0x80206918
-	SIOCSIFMTU                        = 0x80206934
-	SIOCSIFNETMASK                    = 0x80206916
-	SIOCSIFPHYADDR                    = 0x8040693e
-	SIOCSIFPHYS                       = 0x80206936
-	SIOCSIFVLAN                       = 0x8020697e
-	SIOCSLOWAT                        = 0x80047302
-	SIOCSPGRP                         = 0x80047308
-	SOCK_DGRAM                        = 0x2
-	SOCK_MAXADDRLEN                   = 0xff
-	SOCK_RAW                          = 0x3
-	SOCK_RDM                          = 0x4
-	SOCK_SEQPACKET                    = 0x5
-	SOCK_STREAM                       = 0x1
-	SOL_SOCKET                        = 0xffff
-	SOMAXCONN                         = 0x80
-	SO_ACCEPTCONN                     = 0x2
-	SO_BROADCAST                      = 0x20
-	SO_DEBUG                          = 0x1
-	SO_DONTROUTE                      = 0x10
-	SO_DONTTRUNC                      = 0x2000
-	SO_ERROR                          = 0x1007
-	SO_KEEPALIVE                      = 0x8
-	SO_LABEL                          = 0x1010
-	SO_LINGER                         = 0x80
-	SO_LINGER_SEC                     = 0x1080
-	SO_NETSVC_MARKING_LEVEL           = 0x1119
-	SO_NET_SERVICE_TYPE               = 0x1116
-	SO_NKE                            = 0x1021
-	SO_NOADDRERR                      = 0x1023
-	SO_NOSIGPIPE                      = 0x1022
-	SO_NOTIFYCONFLICT                 = 0x1026
-	SO_NP_EXTENSIONS                  = 0x1083
-	SO_NREAD                          = 0x1020
-	SO_NUMRCVPKT                      = 0x1112
-	SO_NWRITE                         = 0x1024
-	SO_OOBINLINE                      = 0x100
-	SO_PEERLABEL                      = 0x1011
-	SO_RANDOMPORT                     = 0x1082
-	SO_RCVBUF                         = 0x1002
-	SO_RCVLOWAT                       = 0x1004
-	SO_RCVTIMEO                       = 0x1006
-	SO_REUSEADDR                      = 0x4
-	SO_REUSEPORT                      = 0x200
-	SO_REUSESHAREUID                  = 0x1025
-	SO_SNDBUF                         = 0x1001
-	SO_SNDLOWAT                       = 0x1003
-	SO_SNDTIMEO                       = 0x1005
-	SO_TIMESTAMP                      = 0x400
-	SO_TIMESTAMP_MONOTONIC            = 0x800
-	SO_TYPE                           = 0x1008
-	SO_UPCALLCLOSEWAIT                = 0x1027
-	SO_USELOOPBACK                    = 0x40
-	SO_WANTMORE                       = 0x4000
-	SO_WANTOOBFLAG                    = 0x8000
-	S_IEXEC                           = 0x40
-	S_IFBLK                           = 0x6000
-	S_IFCHR                           = 0x2000
-	S_IFDIR                           = 0x4000
-	S_IFIFO                           = 0x1000
-	S_IFLNK                           = 0xa000
-	S_IFMT                            = 0xf000
-	S_IFREG                           = 0x8000
-	S_IFSOCK                          = 0xc000
-	S_IFWHT                           = 0xe000
-	S_IREAD                           = 0x100
-	S_IRGRP                           = 0x20
-	S_IROTH                           = 0x4
-	S_IRUSR                           = 0x100
-	S_IRWXG                           = 0x38
-	S_IRWXO                           = 0x7
-	S_IRWXU                           = 0x1c0
-	S_ISGID                           = 0x400
-	S_ISTXT                           = 0x200
-	S_ISUID                           = 0x800
-	S_ISVTX                           = 0x200
-	S_IWGRP                           = 0x10
-	S_IWOTH                           = 0x2
-	S_IWRITE                          = 0x80
-	S_IWUSR                           = 0x80
-	S_IXGRP                           = 0x8
-	S_IXOTH                           = 0x1
-	S_IXUSR                           = 0x40
-	TAB0                              = 0x0
-	TAB1                              = 0x400
-	TAB2                              = 0x800
-	TAB3                              = 0x4
-	TABDLY                            = 0xc04
-	TCIFLUSH                          = 0x1
-	TCIOFF                            = 0x3
-	TCIOFLUSH                         = 0x3
-	TCION                             = 0x4
-	TCOFLUSH                          = 0x2
-	TCOOFF                            = 0x1
-	TCOON                             = 0x2
-	TCP_CONNECTIONTIMEOUT             = 0x20
-	TCP_CONNECTION_INFO               = 0x106
-	TCP_ENABLE_ECN                    = 0x104
-	TCP_FASTOPEN                      = 0x105
-	TCP_KEEPALIVE                     = 0x10
-	TCP_KEEPCNT                       = 0x102
-	TCP_KEEPINTVL                     = 0x101
-	TCP_MAXHLEN                       = 0x3c
-	TCP_MAXOLEN                       = 0x28
-	TCP_MAXSEG                        = 0x2
-	TCP_MAXWIN                        = 0xffff
-	TCP_MAX_SACK                      = 0x4
-	TCP_MAX_WINSHIFT                  = 0xe
-	TCP_MINMSS                        = 0xd8
-	TCP_MSS                           = 0x200
-	TCP_NODELAY                       = 0x1
-	TCP_NOOPT                         = 0x8
-	TCP_NOPUSH                        = 0x4
-	TCP_NOTSENT_LOWAT                 = 0x201
-	TCP_RXT_CONNDROPTIME              = 0x80
-	TCP_RXT_FINDROP                   = 0x100
-	TCP_SENDMOREACKS                  = 0x103
-	TCSAFLUSH                         = 0x2
-	TIOCCBRK                          = 0x2000747a
-	TIOCCDTR                          = 0x20007478
-	TIOCCONS                          = 0x80047462
-	TIOCDCDTIMESTAMP                  = 0x40087458
-	TIOCDRAIN                         = 0x2000745e
-	TIOCDSIMICROCODE                  = 0x20007455
-	TIOCEXCL                          = 0x2000740d
-	TIOCEXT                           = 0x80047460
-	TIOCFLUSH                         = 0x80047410
-	TIOCGDRAINWAIT                    = 0x40047456
-	TIOCGETA                          = 0x402c7413
-	TIOCGETD                          = 0x4004741a
-	TIOCGPGRP                         = 0x40047477
-	TIOCGWINSZ                        = 0x40087468
-	TIOCIXOFF                         = 0x20007480
-	TIOCIXON                          = 0x20007481
-	TIOCMBIC                          = 0x8004746b
-	TIOCMBIS                          = 0x8004746c
-	TIOCMGDTRWAIT                     = 0x4004745a
-	TIOCMGET                          = 0x4004746a
-	TIOCMODG                          = 0x40047403
-	TIOCMODS                          = 0x80047404
-	TIOCMSDTRWAIT                     = 0x8004745b
-	TIOCMSET                          = 0x8004746d
-	TIOCM_CAR                         = 0x40
-	TIOCM_CD                          = 0x40
-	TIOCM_CTS                         = 0x20
-	TIOCM_DSR                         = 0x100
-	TIOCM_DTR                         = 0x2
-	TIOCM_LE                          = 0x1
-	TIOCM_RI                          = 0x80
-	TIOCM_RNG                         = 0x80
-	TIOCM_RTS                         = 0x4
-	TIOCM_SR                          = 0x10
-	TIOCM_ST                          = 0x8
-	TIOCNOTTY                         = 0x20007471
-	TIOCNXCL                          = 0x2000740e
-	TIOCOUTQ                          = 0x40047473
-	TIOCPKT                           = 0x80047470
-	TIOCPKT_DATA                      = 0x0
-	TIOCPKT_DOSTOP                    = 0x20
-	TIOCPKT_FLUSHREAD                 = 0x1
-	TIOCPKT_FLUSHWRITE                = 0x2
-	TIOCPKT_IOCTL                     = 0x40
-	TIOCPKT_NOSTOP                    = 0x10
-	TIOCPKT_START                     = 0x8
-	TIOCPKT_STOP                      = 0x4
-	TIOCPTYGNAME                      = 0x40807453
-	TIOCPTYGRANT                      = 0x20007454
-	TIOCPTYUNLK                       = 0x20007452
-	TIOCREMOTE                        = 0x80047469
-	TIOCSBRK                          = 0x2000747b
-	TIOCSCONS                         = 0x20007463
-	TIOCSCTTY                         = 0x20007461
-	TIOCSDRAINWAIT                    = 0x80047457
-	TIOCSDTR                          = 0x20007479
-	TIOCSETA                          = 0x802c7414
-	TIOCSETAF                         = 0x802c7416
-	TIOCSETAW                         = 0x802c7415
-	TIOCSETD                          = 0x8004741b
-	TIOCSIG                           = 0x2000745f
-	TIOCSPGRP                         = 0x80047476
-	TIOCSTART                         = 0x2000746e
-	TIOCSTAT                          = 0x20007465
-	TIOCSTI                           = 0x80017472
-	TIOCSTOP                          = 0x2000746f
-	TIOCSWINSZ                        = 0x80087467
-	TIOCTIMESTAMP                     = 0x40087459
-	TIOCUCNTL                         = 0x80047466
-	TOSTOP                            = 0x400000
-	VDISCARD                          = 0xf
-	VDSUSP                            = 0xb
-	VEOF                              = 0x0
-	VEOL                              = 0x1
-	VEOL2                             = 0x2
-	VERASE                            = 0x3
-	VINTR                             = 0x8
-	VKILL                             = 0x5
-	VLNEXT                            = 0xe
-	VMIN                              = 0x10
-	VM_LOADAVG                        = 0x2
-	VM_MACHFACTOR                     = 0x4
-	VM_MAXID                          = 0x6
-	VM_METER                          = 0x1
-	VM_SWAPUSAGE                      = 0x5
-	VQUIT                             = 0x9
-	VREPRINT                          = 0x6
-	VSTART                            = 0xc
-	VSTATUS                           = 0x12
-	VSTOP                             = 0xd
-	VSUSP                             = 0xa
-	VT0                               = 0x0
-	VT1                               = 0x10000
-	VTDLY                             = 0x10000
-	VTIME                             = 0x11
-	VWERASE                           = 0x4
-	WCONTINUED                        = 0x10
-	WCOREFLAG                         = 0x80
-	WEXITED                           = 0x4
-	WNOHANG                           = 0x1
-	WNOWAIT                           = 0x20
-	WORDSIZE                          = 0x20
-	WSTOPPED                          = 0x8
-	WUNTRACED                         = 0x2
-	XATTR_CREATE                      = 0x2
-	XATTR_NODEFAULT                   = 0x10
-	XATTR_NOFOLLOW                    = 0x1
-	XATTR_NOSECURITY                  = 0x8
-	XATTR_REPLACE                     = 0x4
-	XATTR_SHOWCOMPRESSION             = 0x20
-)
-
-// Errors
-const (
-	E2BIG           = syscall.Errno(0x7)
-	EACCES          = syscall.Errno(0xd)
-	EADDRINUSE      = syscall.Errno(0x30)
-	EADDRNOTAVAIL   = syscall.Errno(0x31)
-	EAFNOSUPPORT    = syscall.Errno(0x2f)
-	EAGAIN          = syscall.Errno(0x23)
-	EALREADY        = syscall.Errno(0x25)
-	EAUTH           = syscall.Errno(0x50)
-	EBADARCH        = syscall.Errno(0x56)
-	EBADEXEC        = syscall.Errno(0x55)
-	EBADF           = syscall.Errno(0x9)
-	EBADMACHO       = syscall.Errno(0x58)
-	EBADMSG         = syscall.Errno(0x5e)
-	EBADRPC         = syscall.Errno(0x48)
-	EBUSY           = syscall.Errno(0x10)
-	ECANCELED       = syscall.Errno(0x59)
-	ECHILD          = syscall.Errno(0xa)
-	ECONNABORTED    = syscall.Errno(0x35)
-	ECONNREFUSED    = syscall.Errno(0x3d)
-	ECONNRESET      = syscall.Errno(0x36)
-	EDEADLK         = syscall.Errno(0xb)
-	EDESTADDRREQ    = syscall.Errno(0x27)
-	EDEVERR         = syscall.Errno(0x53)
-	EDOM            = syscall.Errno(0x21)
-	EDQUOT          = syscall.Errno(0x45)
-	EEXIST          = syscall.Errno(0x11)
-	EFAULT          = syscall.Errno(0xe)
-	EFBIG           = syscall.Errno(0x1b)
-	EFTYPE          = syscall.Errno(0x4f)
-	EHOSTDOWN       = syscall.Errno(0x40)
-	EHOSTUNREACH    = syscall.Errno(0x41)
-	EIDRM           = syscall.Errno(0x5a)
-	EILSEQ          = syscall.Errno(0x5c)
-	EINPROGRESS     = syscall.Errno(0x24)
-	EINTR           = syscall.Errno(0x4)
-	EINVAL          = syscall.Errno(0x16)
-	EIO             = syscall.Errno(0x5)
-	EISCONN         = syscall.Errno(0x38)
-	EISDIR          = syscall.Errno(0x15)
-	ELAST           = syscall.Errno(0x6a)
-	ELOOP           = syscall.Errno(0x3e)
-	EMFILE          = syscall.Errno(0x18)
-	EMLINK          = syscall.Errno(0x1f)
-	EMSGSIZE        = syscall.Errno(0x28)
-	EMULTIHOP       = syscall.Errno(0x5f)
-	ENAMETOOLONG    = syscall.Errno(0x3f)
-	ENEEDAUTH       = syscall.Errno(0x51)
-	ENETDOWN        = syscall.Errno(0x32)
-	ENETRESET       = syscall.Errno(0x34)
-	ENETUNREACH     = syscall.Errno(0x33)
-	ENFILE          = syscall.Errno(0x17)
-	ENOATTR         = syscall.Errno(0x5d)
-	ENOBUFS         = syscall.Errno(0x37)
-	ENODATA         = syscall.Errno(0x60)
-	ENODEV          = syscall.Errno(0x13)
-	ENOENT          = syscall.Errno(0x2)
-	ENOEXEC         = syscall.Errno(0x8)
-	ENOLCK          = syscall.Errno(0x4d)
-	ENOLINK         = syscall.Errno(0x61)
-	ENOMEM          = syscall.Errno(0xc)
-	ENOMSG          = syscall.Errno(0x5b)
-	ENOPOLICY       = syscall.Errno(0x67)
-	ENOPROTOOPT     = syscall.Errno(0x2a)
-	ENOSPC          = syscall.Errno(0x1c)
-	ENOSR           = syscall.Errno(0x62)
-	ENOSTR          = syscall.Errno(0x63)
-	ENOSYS          = syscall.Errno(0x4e)
-	ENOTBLK         = syscall.Errno(0xf)
-	ENOTCONN        = syscall.Errno(0x39)
-	ENOTDIR         = syscall.Errno(0x14)
-	ENOTEMPTY       = syscall.Errno(0x42)
-	ENOTRECOVERABLE = syscall.Errno(0x68)
-	ENOTSOCK        = syscall.Errno(0x26)
-	ENOTSUP         = syscall.Errno(0x2d)
-	ENOTTY          = syscall.Errno(0x19)
-	ENXIO           = syscall.Errno(0x6)
-	EOPNOTSUPP      = syscall.Errno(0x66)
-	EOVERFLOW       = syscall.Errno(0x54)
-	EOWNERDEAD      = syscall.Errno(0x69)
-	EPERM           = syscall.Errno(0x1)
-	EPFNOSUPPORT    = syscall.Errno(0x2e)
-	EPIPE           = syscall.Errno(0x20)
-	EPROCLIM        = syscall.Errno(0x43)
-	EPROCUNAVAIL    = syscall.Errno(0x4c)
-	EPROGMISMATCH   = syscall.Errno(0x4b)
-	EPROGUNAVAIL    = syscall.Errno(0x4a)
-	EPROTO          = syscall.Errno(0x64)
-	EPROTONOSUPPORT = syscall.Errno(0x2b)
-	EPROTOTYPE      = syscall.Errno(0x29)
-	EPWROFF         = syscall.Errno(0x52)
-	EQFULL          = syscall.Errno(0x6a)
-	ERANGE          = syscall.Errno(0x22)
-	EREMOTE         = syscall.Errno(0x47)
-	EROFS           = syscall.Errno(0x1e)
-	ERPCMISMATCH    = syscall.Errno(0x49)
-	ESHLIBVERS      = syscall.Errno(0x57)
-	ESHUTDOWN       = syscall.Errno(0x3a)
-	ESOCKTNOSUPPORT = syscall.Errno(0x2c)
-	ESPIPE          = syscall.Errno(0x1d)
-	ESRCH           = syscall.Errno(0x3)
-	ESTALE          = syscall.Errno(0x46)
-	ETIME           = syscall.Errno(0x65)
-	ETIMEDOUT       = syscall.Errno(0x3c)
-	ETOOMANYREFS    = syscall.Errno(0x3b)
-	ETXTBSY         = syscall.Errno(0x1a)
-	EUSERS          = syscall.Errno(0x44)
-	EWOULDBLOCK     = syscall.Errno(0x23)
-	EXDEV           = syscall.Errno(0x12)
-)
-
-// Signals
-const (
-	SIGABRT   = syscall.Signal(0x6)
-	SIGALRM   = syscall.Signal(0xe)
-	SIGBUS    = syscall.Signal(0xa)
-	SIGCHLD   = syscall.Signal(0x14)
-	SIGCONT   = syscall.Signal(0x13)
-	SIGEMT    = syscall.Signal(0x7)
-	SIGFPE    = syscall.Signal(0x8)
-	SIGHUP    = syscall.Signal(0x1)
-	SIGILL    = syscall.Signal(0x4)
-	SIGINFO   = syscall.Signal(0x1d)
-	SIGINT    = syscall.Signal(0x2)
-	SIGIO     = syscall.Signal(0x17)
-	SIGIOT    = syscall.Signal(0x6)
-	SIGKILL   = syscall.Signal(0x9)
-	SIGPIPE   = syscall.Signal(0xd)
-	SIGPROF   = syscall.Signal(0x1b)
-	SIGQUIT   = syscall.Signal(0x3)
-	SIGSEGV   = syscall.Signal(0xb)
-	SIGSTOP   = syscall.Signal(0x11)
-	SIGSYS    = syscall.Signal(0xc)
-	SIGTERM   = syscall.Signal(0xf)
-	SIGTRAP   = syscall.Signal(0x5)
-	SIGTSTP   = syscall.Signal(0x12)
-	SIGTTIN   = syscall.Signal(0x15)
-	SIGTTOU   = syscall.Signal(0x16)
-	SIGURG    = syscall.Signal(0x10)
-	SIGUSR1   = syscall.Signal(0x1e)
-	SIGUSR2   = syscall.Signal(0x1f)
-	SIGVTALRM = syscall.Signal(0x1a)
-	SIGWINCH  = syscall.Signal(0x1c)
-	SIGXCPU   = syscall.Signal(0x18)
-	SIGXFSZ   = syscall.Signal(0x19)
-)
-
-// Error table
-var errorList = [...]struct {
-	num  syscall.Errno
-	name string
-	desc string
-}{
-	{1, "EPERM", "operation not permitted"},
-	{2, "ENOENT", "no such file or directory"},
-	{3, "ESRCH", "no such process"},
-	{4, "EINTR", "interrupted system call"},
-	{5, "EIO", "input/output error"},
-	{6, "ENXIO", "device not configured"},
-	{7, "E2BIG", "argument list too long"},
-	{8, "ENOEXEC", "exec format error"},
-	{9, "EBADF", "bad file descriptor"},
-	{10, "ECHILD", "no child processes"},
-	{11, "EDEADLK", "resource deadlock avoided"},
-	{12, "ENOMEM", "cannot allocate memory"},
-	{13, "EACCES", "permission denied"},
-	{14, "EFAULT", "bad address"},
-	{15, "ENOTBLK", "block device required"},
-	{16, "EBUSY", "resource busy"},
-	{17, "EEXIST", "file exists"},
-	{18, "EXDEV", "cross-device link"},
-	{19, "ENODEV", "operation not supported by device"},
-	{20, "ENOTDIR", "not a directory"},
-	{21, "EISDIR", "is a directory"},
-	{22, "EINVAL", "invalid argument"},
-	{23, "ENFILE", "too many open files in system"},
-	{24, "EMFILE", "too many open files"},
-	{25, "ENOTTY", "inappropriate ioctl for device"},
-	{26, "ETXTBSY", "text file busy"},
-	{27, "EFBIG", "file too large"},
-	{28, "ENOSPC", "no space left on device"},
-	{29, "ESPIPE", "illegal seek"},
-	{30, "EROFS", "read-only file system"},
-	{31, "EMLINK", "too many links"},
-	{32, "EPIPE", "broken pipe"},
-	{33, "EDOM", "numerical argument out of domain"},
-	{34, "ERANGE", "result too large"},
-	{35, "EAGAIN", "resource temporarily unavailable"},
-	{36, "EINPROGRESS", "operation now in progress"},
-	{37, "EALREADY", "operation already in progress"},
-	{38, "ENOTSOCK", "socket operation on non-socket"},
-	{39, "EDESTADDRREQ", "destination address required"},
-	{40, "EMSGSIZE", "message too long"},
-	{41, "EPROTOTYPE", "protocol wrong type for socket"},
-	{42, "ENOPROTOOPT", "protocol not available"},
-	{43, "EPROTONOSUPPORT", "protocol not supported"},
-	{44, "ESOCKTNOSUPPORT", "socket type not supported"},
-	{45, "ENOTSUP", "operation not supported"},
-	{46, "EPFNOSUPPORT", "protocol family not supported"},
-	{47, "EAFNOSUPPORT", "address family not supported by protocol family"},
-	{48, "EADDRINUSE", "address already in use"},
-	{49, "EADDRNOTAVAIL", "can't assign requested address"},
-	{50, "ENETDOWN", "network is down"},
-	{51, "ENETUNREACH", "network is unreachable"},
-	{52, "ENETRESET", "network dropped connection on reset"},
-	{53, "ECONNABORTED", "software caused connection abort"},
-	{54, "ECONNRESET", "connection reset by peer"},
-	{55, "ENOBUFS", "no buffer space available"},
-	{56, "EISCONN", "socket is already connected"},
-	{57, "ENOTCONN", "socket is not connected"},
-	{58, "ESHUTDOWN", "can't send after socket shutdown"},
-	{59, "ETOOMANYREFS", "too many references: can't splice"},
-	{60, "ETIMEDOUT", "operation timed out"},
-	{61, "ECONNREFUSED", "connection refused"},
-	{62, "ELOOP", "too many levels of symbolic links"},
-	{63, "ENAMETOOLONG", "file name too long"},
-	{64, "EHOSTDOWN", "host is down"},
-	{65, "EHOSTUNREACH", "no route to host"},
-	{66, "ENOTEMPTY", "directory not empty"},
-	{67, "EPROCLIM", "too many processes"},
-	{68, "EUSERS", "too many users"},
-	{69, "EDQUOT", "disc quota exceeded"},
-	{70, "ESTALE", "stale NFS file handle"},
-	{71, "EREMOTE", "too many levels of remote in path"},
-	{72, "EBADRPC", "RPC struct is bad"},
-	{73, "ERPCMISMATCH", "RPC version wrong"},
-	{74, "EPROGUNAVAIL", "RPC prog. not avail"},
-	{75, "EPROGMISMATCH", "program version wrong"},
-	{76, "EPROCUNAVAIL", "bad procedure for program"},
-	{77, "ENOLCK", "no locks available"},
-	{78, "ENOSYS", "function not implemented"},
-	{79, "EFTYPE", "inappropriate file type or format"},
-	{80, "EAUTH", "authentication error"},
-	{81, "ENEEDAUTH", "need authenticator"},
-	{82, "EPWROFF", "device power is off"},
-	{83, "EDEVERR", "device error"},
-	{84, "EOVERFLOW", "value too large to be stored in data type"},
-	{85, "EBADEXEC", "bad executable (or shared library)"},
-	{86, "EBADARCH", "bad CPU type in executable"},
-	{87, "ESHLIBVERS", "shared library version mismatch"},
-	{88, "EBADMACHO", "malformed Mach-o file"},
-	{89, "ECANCELED", "operation canceled"},
-	{90, "EIDRM", "identifier removed"},
-	{91, "ENOMSG", "no message of desired type"},
-	{92, "EILSEQ", "illegal byte sequence"},
-	{93, "ENOATTR", "attribute not found"},
-	{94, "EBADMSG", "bad message"},
-	{95, "EMULTIHOP", "EMULTIHOP (Reserved)"},
-	{96, "ENODATA", "no message available on STREAM"},
-	{97, "ENOLINK", "ENOLINK (Reserved)"},
-	{98, "ENOSR", "no STREAM resources"},
-	{99, "ENOSTR", "not a STREAM"},
-	{100, "EPROTO", "protocol error"},
-	{101, "ETIME", "STREAM ioctl timeout"},
-	{102, "EOPNOTSUPP", "operation not supported on socket"},
-	{103, "ENOPOLICY", "policy not found"},
-	{104, "ENOTRECOVERABLE", "state not recoverable"},
-	{105, "EOWNERDEAD", "previous owner died"},
-	{106, "EQFULL", "interface output queue is full"},
-}
-
-// Signal table
-var signalList = [...]struct {
-	num  syscall.Signal
-	name string
-	desc string
-}{
-	{1, "SIGHUP", "hangup"},
-	{2, "SIGINT", "interrupt"},
-	{3, "SIGQUIT", "quit"},
-	{4, "SIGILL", "illegal instruction"},
-	{5, "SIGTRAP", "trace/BPT trap"},
-	{6, "SIGABRT", "abort trap"},
-	{7, "SIGEMT", "EMT trap"},
-	{8, "SIGFPE", "floating point exception"},
-	{9, "SIGKILL", "killed"},
-	{10, "SIGBUS", "bus error"},
-	{11, "SIGSEGV", "segmentation fault"},
-	{12, "SIGSYS", "bad system call"},
-	{13, "SIGPIPE", "broken pipe"},
-	{14, "SIGALRM", "alarm clock"},
-	{15, "SIGTERM", "terminated"},
-	{16, "SIGURG", "urgent I/O condition"},
-	{17, "SIGSTOP", "suspended (signal)"},
-	{18, "SIGTSTP", "suspended"},
-	{19, "SIGCONT", "continued"},
-	{20, "SIGCHLD", "child exited"},
-	{21, "SIGTTIN", "stopped (tty input)"},
-	{22, "SIGTTOU", "stopped (tty output)"},
-	{23, "SIGIO", "I/O possible"},
-	{24, "SIGXCPU", "cputime limit exceeded"},
-	{25, "SIGXFSZ", "filesize limit exceeded"},
-	{26, "SIGVTALRM", "virtual timer expired"},
-	{27, "SIGPROF", "profiling timer expired"},
-	{28, "SIGWINCH", "window size changes"},
-	{29, "SIGINFO", "information request"},
-	{30, "SIGUSR1", "user defined signal 1"},
-	{31, "SIGUSR2", "user defined signal 2"},
-}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go
index fea5dfa..991996b 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && darwin
 // +build amd64,darwin
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
@@ -32,7 +33,7 @@
 	AF_LAT                            = 0xe
 	AF_LINK                           = 0x12
 	AF_LOCAL                          = 0x1
-	AF_MAX                            = 0x28
+	AF_MAX                            = 0x29
 	AF_NATM                           = 0x1f
 	AF_NDRV                           = 0x1b
 	AF_NETBIOS                        = 0x21
@@ -49,6 +50,7 @@
 	AF_UNIX                           = 0x1
 	AF_UNSPEC                         = 0x0
 	AF_UTUN                           = 0x26
+	AF_VSOCK                          = 0x28
 	ALTWERASE                         = 0x200
 	ATTR_BIT_MAP_COUNT                = 0x5
 	ATTR_CMN_ACCESSMASK               = 0x20000
@@ -83,7 +85,7 @@
 	ATTR_CMN_PAROBJID                 = 0x80
 	ATTR_CMN_RETURNED_ATTRS           = 0x80000000
 	ATTR_CMN_SCRIPT                   = 0x100
-	ATTR_CMN_SETMASK                  = 0x41c7ff00
+	ATTR_CMN_SETMASK                  = 0x51c7ff00
 	ATTR_CMN_USERACCESS               = 0x200000
 	ATTR_CMN_UUID                     = 0x800000
 	ATTR_CMN_VALIDMASK                = 0xffffffff
@@ -357,7 +359,7 @@
 	DLT_LINUX_SLL                     = 0x71
 	DLT_LOOP                          = 0x6c
 	DLT_LTALK                         = 0x72
-	DLT_MATCHING_MAX                  = 0xf5
+	DLT_MATCHING_MAX                  = 0x10a
 	DLT_MATCHING_MIN                  = 0x68
 	DLT_MFR                           = 0xb6
 	DLT_MOST                          = 0xd3
@@ -398,6 +400,7 @@
 	DLT_SYMANTEC_FIREWALL             = 0x63
 	DLT_TZSP                          = 0x80
 	DLT_USB                           = 0xba
+	DLT_USB_DARWIN                    = 0x10a
 	DLT_USB_LINUX                     = 0xbd
 	DLT_USB_LINUX_MMAPPED             = 0xdc
 	DLT_USER0                         = 0x93
@@ -442,8 +445,8 @@
 	EVFILT_PROC                       = -0x5
 	EVFILT_READ                       = -0x1
 	EVFILT_SIGNAL                     = -0x6
-	EVFILT_SYSCOUNT                   = 0xf
-	EVFILT_THREADMARKER               = 0xf
+	EVFILT_SYSCOUNT                   = 0x11
+	EVFILT_THREADMARKER               = 0x11
 	EVFILT_TIMER                      = -0x7
 	EVFILT_USER                       = -0xa
 	EVFILT_VM                         = -0xc
@@ -481,9 +484,12 @@
 	FSOPT_NOINMEMUPDATE               = 0x2
 	FSOPT_PACK_INVAL_ATTRS            = 0x8
 	FSOPT_REPORT_FULLSIZE             = 0x4
+	FSOPT_RETURN_REALDEV              = 0x200
 	F_ADDFILESIGS                     = 0x3d
 	F_ADDFILESIGS_FOR_DYLD_SIM        = 0x53
+	F_ADDFILESIGS_INFO                = 0x67
 	F_ADDFILESIGS_RETURN              = 0x61
+	F_ADDFILESUPPL                    = 0x68
 	F_ADDSIGS                         = 0x3b
 	F_ALLOCATEALL                     = 0x4
 	F_ALLOCATECONTIG                  = 0x2
@@ -505,8 +511,10 @@
 	F_GETOWN                          = 0x5
 	F_GETPATH                         = 0x32
 	F_GETPATH_MTMINFO                 = 0x47
+	F_GETPATH_NOFIRMLINK              = 0x66
 	F_GETPROTECTIONCLASS              = 0x3f
 	F_GETPROTECTIONLEVEL              = 0x4d
+	F_GETSIGSINFO                     = 0x69
 	F_GLOBAL_NOCACHE                  = 0x37
 	F_LOG2PHYS                        = 0x31
 	F_LOG2PHYS_EXT                    = 0x41
@@ -531,6 +539,7 @@
 	F_SETPROTECTIONCLASS              = 0x40
 	F_SETSIZE                         = 0x2b
 	F_SINGLE_WRITER                   = 0x4c
+	F_SPECULATIVE_READ                = 0x65
 	F_THAW_FS                         = 0x36
 	F_TRANSCODEKEY                    = 0x4b
 	F_TRIM_ACTIVE_FILE                = 0x64
@@ -562,6 +571,7 @@
 	IFF_UP                            = 0x1
 	IFNAMSIZ                          = 0x10
 	IFT_1822                          = 0x2
+	IFT_6LOWPAN                       = 0x40
 	IFT_AAL5                          = 0x31
 	IFT_ARCNET                        = 0x23
 	IFT_ARCNETPLUS                    = 0x24
@@ -766,16 +776,28 @@
 	IPV6_2292PKTINFO                  = 0x13
 	IPV6_2292PKTOPTIONS               = 0x19
 	IPV6_2292RTHDR                    = 0x18
+	IPV6_3542DSTOPTS                  = 0x32
+	IPV6_3542HOPLIMIT                 = 0x2f
+	IPV6_3542HOPOPTS                  = 0x31
+	IPV6_3542NEXTHOP                  = 0x30
+	IPV6_3542PKTINFO                  = 0x2e
+	IPV6_3542RTHDR                    = 0x33
+	IPV6_ADDR_MC_FLAGS_PREFIX         = 0x20
+	IPV6_ADDR_MC_FLAGS_TRANSIENT      = 0x10
+	IPV6_ADDR_MC_FLAGS_UNICAST_BASED  = 0x30
+	IPV6_AUTOFLOWLABEL                = 0x3b
 	IPV6_BINDV6ONLY                   = 0x1b
 	IPV6_BOUND_IF                     = 0x7d
 	IPV6_CHECKSUM                     = 0x1a
 	IPV6_DEFAULT_MULTICAST_HOPS       = 0x1
 	IPV6_DEFAULT_MULTICAST_LOOP       = 0x1
 	IPV6_DEFHLIM                      = 0x40
+	IPV6_DONTFRAG                     = 0x3e
+	IPV6_DSTOPTS                      = 0x32
 	IPV6_FAITH                        = 0x1d
 	IPV6_FLOWINFO_MASK                = 0xffffff0f
 	IPV6_FLOWLABEL_MASK               = 0xffff0f00
-	IPV6_FLOW_ECN_MASK                = 0x300
+	IPV6_FLOW_ECN_MASK                = 0x3000
 	IPV6_FRAGTTL                      = 0x3c
 	IPV6_FW_ADD                       = 0x1e
 	IPV6_FW_DEL                       = 0x1f
@@ -783,6 +805,8 @@
 	IPV6_FW_GET                       = 0x22
 	IPV6_FW_ZERO                      = 0x21
 	IPV6_HLIMDEC                      = 0x1
+	IPV6_HOPLIMIT                     = 0x2f
+	IPV6_HOPOPTS                      = 0x31
 	IPV6_IPSEC_POLICY                 = 0x1c
 	IPV6_JOIN_GROUP                   = 0xc
 	IPV6_LEAVE_GROUP                  = 0xd
@@ -794,20 +818,34 @@
 	IPV6_MAX_SOCK_SRC_FILTER          = 0x80
 	IPV6_MIN_MEMBERSHIPS              = 0x1f
 	IPV6_MMTU                         = 0x500
+	IPV6_MSFILTER                     = 0x4a
 	IPV6_MULTICAST_HOPS               = 0xa
 	IPV6_MULTICAST_IF                 = 0x9
 	IPV6_MULTICAST_LOOP               = 0xb
+	IPV6_NEXTHOP                      = 0x30
+	IPV6_PATHMTU                      = 0x2c
+	IPV6_PKTINFO                      = 0x2e
 	IPV6_PORTRANGE                    = 0xe
 	IPV6_PORTRANGE_DEFAULT            = 0x0
 	IPV6_PORTRANGE_HIGH               = 0x1
 	IPV6_PORTRANGE_LOW                = 0x2
+	IPV6_PREFER_TEMPADDR              = 0x3f
+	IPV6_RECVDSTOPTS                  = 0x28
+	IPV6_RECVHOPLIMIT                 = 0x25
+	IPV6_RECVHOPOPTS                  = 0x27
+	IPV6_RECVPATHMTU                  = 0x2b
+	IPV6_RECVPKTINFO                  = 0x3d
+	IPV6_RECVRTHDR                    = 0x26
 	IPV6_RECVTCLASS                   = 0x23
+	IPV6_RTHDR                        = 0x33
+	IPV6_RTHDRDSTOPTS                 = 0x39
 	IPV6_RTHDR_LOOSE                  = 0x0
 	IPV6_RTHDR_STRICT                 = 0x1
 	IPV6_RTHDR_TYPE_0                 = 0x0
 	IPV6_SOCKOPT_RESERVED1            = 0x3
 	IPV6_TCLASS                       = 0x24
 	IPV6_UNICAST_HOPS                 = 0x4
+	IPV6_USE_MIN_MTU                  = 0x2a
 	IPV6_V6ONLY                       = 0x1b
 	IPV6_VERSION                      = 0x60
 	IPV6_VERSION_MASK                 = 0xf0
@@ -818,6 +856,7 @@
 	IP_DEFAULT_MULTICAST_LOOP         = 0x1
 	IP_DEFAULT_MULTICAST_TTL          = 0x1
 	IP_DF                             = 0x4000
+	IP_DONTFRAG                       = 0x1c
 	IP_DROP_MEMBERSHIP                = 0xd
 	IP_DROP_SOURCE_MEMBERSHIP         = 0x47
 	IP_DUMMYNET_CONFIGURE             = 0x3c
@@ -889,6 +928,12 @@
 	KERN_OSRELEASE                    = 0x2
 	KERN_OSTYPE                       = 0x1
 	KERN_VERSION                      = 0x4
+	LOCAL_PEERCRED                    = 0x1
+	LOCAL_PEEREPID                    = 0x3
+	LOCAL_PEEREUUID                   = 0x5
+	LOCAL_PEERPID                     = 0x2
+	LOCAL_PEERTOKEN                   = 0x6
+	LOCAL_PEERUUID                    = 0x4
 	LOCK_EX                           = 0x2
 	LOCK_NB                           = 0x4
 	LOCK_SH                           = 0x1
@@ -904,6 +949,7 @@
 	MADV_SEQUENTIAL                   = 0x2
 	MADV_WILLNEED                     = 0x3
 	MADV_ZERO_WIRED_PAGES             = 0x6
+	MAP_32BIT                         = 0x8000
 	MAP_ANON                          = 0x1000
 	MAP_ANONYMOUS                     = 0x1000
 	MAP_COPY                          = 0x2
@@ -920,6 +966,17 @@
 	MAP_RESILIENT_CODESIGN            = 0x2000
 	MAP_RESILIENT_MEDIA               = 0x4000
 	MAP_SHARED                        = 0x1
+	MAP_TRANSLATED_ALLOW_EXECUTE      = 0x20000
+	MAP_UNIX03                        = 0x40000
+	MCAST_BLOCK_SOURCE                = 0x54
+	MCAST_EXCLUDE                     = 0x2
+	MCAST_INCLUDE                     = 0x1
+	MCAST_JOIN_GROUP                  = 0x50
+	MCAST_JOIN_SOURCE_GROUP           = 0x52
+	MCAST_LEAVE_GROUP                 = 0x51
+	MCAST_LEAVE_SOURCE_GROUP          = 0x53
+	MCAST_UNBLOCK_SOURCE              = 0x55
+	MCAST_UNDEFINED                   = 0x0
 	MCL_CURRENT                       = 0x1
 	MCL_FUTURE                        = 0x2
 	MNT_ASYNC                         = 0x40
@@ -931,6 +988,7 @@
 	MNT_DOVOLFS                       = 0x8000
 	MNT_DWAIT                         = 0x4
 	MNT_EXPORTED                      = 0x100
+	MNT_EXT_ROOT_DATA_VOL             = 0x1
 	MNT_FORCE                         = 0x80000
 	MNT_IGNORE_OWNERSHIP              = 0x200000
 	MNT_JOURNALED                     = 0x800000
@@ -947,12 +1005,15 @@
 	MNT_QUOTA                         = 0x2000
 	MNT_RDONLY                        = 0x1
 	MNT_RELOAD                        = 0x40000
+	MNT_REMOVABLE                     = 0x200
 	MNT_ROOTFS                        = 0x4000
+	MNT_SNAPSHOT                      = 0x40000000
+	MNT_STRICTATIME                   = 0x80000000
 	MNT_SYNCHRONOUS                   = 0x2
 	MNT_UNION                         = 0x20
 	MNT_UNKNOWNPERMISSIONS            = 0x200000
 	MNT_UPDATE                        = 0x10000
-	MNT_VISFLAGMASK                   = 0x17f0f5ff
+	MNT_VISFLAGMASK                   = 0xd7f0f7ff
 	MNT_WAIT                          = 0x1
 	MSG_CTRUNC                        = 0x20
 	MSG_DONTROUTE                     = 0x4
@@ -963,6 +1024,7 @@
 	MSG_HAVEMORE                      = 0x2000
 	MSG_HOLD                          = 0x800
 	MSG_NEEDSA                        = 0x10000
+	MSG_NOSIGNAL                      = 0x80000
 	MSG_OOB                           = 0x1
 	MSG_PEEK                          = 0x2
 	MSG_RCVMORE                       = 0x4000
@@ -979,9 +1041,10 @@
 	NET_RT_DUMP                       = 0x1
 	NET_RT_DUMP2                      = 0x7
 	NET_RT_FLAGS                      = 0x2
+	NET_RT_FLAGS_PRIV                 = 0xa
 	NET_RT_IFLIST                     = 0x3
 	NET_RT_IFLIST2                    = 0x6
-	NET_RT_MAXID                      = 0xa
+	NET_RT_MAXID                      = 0xb
 	NET_RT_STAT                       = 0x4
 	NET_RT_TRASH                      = 0x5
 	NFDBITS                           = 0x20
@@ -1019,6 +1082,7 @@
 	NOTE_LEEWAY                       = 0x10
 	NOTE_LINK                         = 0x10
 	NOTE_LOWAT                        = 0x1
+	NOTE_MACHTIME                     = 0x100
 	NOTE_MACH_CONTINUOUS_TIME         = 0x80
 	NOTE_NONE                         = 0x80
 	NOTE_NSECONDS                     = 0x4
@@ -1065,6 +1129,7 @@
 	O_NDELAY                          = 0x4
 	O_NOCTTY                          = 0x20000
 	O_NOFOLLOW                        = 0x100
+	O_NOFOLLOW_ANY                    = 0x20000000
 	O_NONBLOCK                        = 0x4
 	O_POPUP                           = 0x80000000
 	O_RDONLY                          = 0x0
@@ -1136,6 +1201,7 @@
 	RTF_BROADCAST                     = 0x400000
 	RTF_CLONING                       = 0x100
 	RTF_CONDEMNED                     = 0x2000000
+	RTF_DEAD                          = 0x20000000
 	RTF_DELCLONE                      = 0x80
 	RTF_DONE                          = 0x40
 	RTF_DYNAMIC                       = 0x10
@@ -1143,6 +1209,7 @@
 	RTF_HOST                          = 0x4
 	RTF_IFREF                         = 0x4000000
 	RTF_IFSCOPE                       = 0x1000000
+	RTF_LLDATA                        = 0x400
 	RTF_LLINFO                        = 0x400
 	RTF_LOCAL                         = 0x200000
 	RTF_MODIFIED                      = 0x20
@@ -1210,6 +1277,7 @@
 	SIOCGDRVSPEC                      = 0xc028697b
 	SIOCGETVLAN                       = 0xc020697f
 	SIOCGHIWAT                        = 0x40047301
+	SIOCGIF6LOWPAN                    = 0xc02069c5
 	SIOCGIFADDR                       = 0xc0206921
 	SIOCGIFALTMTU                     = 0xc0206948
 	SIOCGIFASYNCMAP                   = 0xc020697c
@@ -1220,6 +1288,7 @@
 	SIOCGIFDEVMTU                     = 0xc0206944
 	SIOCGIFDSTADDR                    = 0xc0206922
 	SIOCGIFFLAGS                      = 0xc0206911
+	SIOCGIFFUNCTIONALTYPE             = 0xc02069ad
 	SIOCGIFGENERIC                    = 0xc020693a
 	SIOCGIFKPI                        = 0xc0206987
 	SIOCGIFMAC                        = 0xc0206982
@@ -1233,6 +1302,7 @@
 	SIOCGIFSTATUS                     = 0xc331693d
 	SIOCGIFVLAN                       = 0xc020697f
 	SIOCGIFWAKEFLAGS                  = 0xc0206988
+	SIOCGIFXMEDIA                     = 0xc02c6948
 	SIOCGLOWAT                        = 0x40047303
 	SIOCGPGRP                         = 0x40047309
 	SIOCIFCREATE                      = 0xc0206978
@@ -1243,6 +1313,7 @@
 	SIOCSDRVSPEC                      = 0x8028697b
 	SIOCSETVLAN                       = 0x8020697e
 	SIOCSHIWAT                        = 0x80047300
+	SIOCSIF6LOWPAN                    = 0x802069c4
 	SIOCSIFADDR                       = 0x8020690c
 	SIOCSIFALTMTU                     = 0x80206945
 	SIOCSIFASYNCMAP                   = 0x8020697d
@@ -1270,6 +1341,7 @@
 	SOCK_RDM                          = 0x4
 	SOCK_SEQPACKET                    = 0x5
 	SOCK_STREAM                       = 0x1
+	SOL_LOCAL                         = 0x0
 	SOL_SOCKET                        = 0xffff
 	SOMAXCONN                         = 0x80
 	SO_ACCEPTCONN                     = 0x2
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go
deleted file mode 100644
index 03feefb..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go
+++ /dev/null
@@ -1,1788 +0,0 @@
-// mkerrors.sh
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build arm,darwin
-
-// Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- _const.go
-
-package unix
-
-import "syscall"
-
-const (
-	AF_APPLETALK                      = 0x10
-	AF_CCITT                          = 0xa
-	AF_CHAOS                          = 0x5
-	AF_CNT                            = 0x15
-	AF_COIP                           = 0x14
-	AF_DATAKIT                        = 0x9
-	AF_DECnet                         = 0xc
-	AF_DLI                            = 0xd
-	AF_E164                           = 0x1c
-	AF_ECMA                           = 0x8
-	AF_HYLINK                         = 0xf
-	AF_IEEE80211                      = 0x25
-	AF_IMPLINK                        = 0x3
-	AF_INET                           = 0x2
-	AF_INET6                          = 0x1e
-	AF_IPX                            = 0x17
-	AF_ISDN                           = 0x1c
-	AF_ISO                            = 0x7
-	AF_LAT                            = 0xe
-	AF_LINK                           = 0x12
-	AF_LOCAL                          = 0x1
-	AF_MAX                            = 0x28
-	AF_NATM                           = 0x1f
-	AF_NDRV                           = 0x1b
-	AF_NETBIOS                        = 0x21
-	AF_NS                             = 0x6
-	AF_OSI                            = 0x7
-	AF_PPP                            = 0x22
-	AF_PUP                            = 0x4
-	AF_RESERVED_36                    = 0x24
-	AF_ROUTE                          = 0x11
-	AF_SIP                            = 0x18
-	AF_SNA                            = 0xb
-	AF_SYSTEM                         = 0x20
-	AF_SYS_CONTROL                    = 0x2
-	AF_UNIX                           = 0x1
-	AF_UNSPEC                         = 0x0
-	AF_UTUN                           = 0x26
-	ALTWERASE                         = 0x200
-	ATTR_BIT_MAP_COUNT                = 0x5
-	ATTR_CMN_ACCESSMASK               = 0x20000
-	ATTR_CMN_ACCTIME                  = 0x1000
-	ATTR_CMN_ADDEDTIME                = 0x10000000
-	ATTR_CMN_BKUPTIME                 = 0x2000
-	ATTR_CMN_CHGTIME                  = 0x800
-	ATTR_CMN_CRTIME                   = 0x200
-	ATTR_CMN_DATA_PROTECT_FLAGS       = 0x40000000
-	ATTR_CMN_DEVID                    = 0x2
-	ATTR_CMN_DOCUMENT_ID              = 0x100000
-	ATTR_CMN_ERROR                    = 0x20000000
-	ATTR_CMN_EXTENDED_SECURITY        = 0x400000
-	ATTR_CMN_FILEID                   = 0x2000000
-	ATTR_CMN_FLAGS                    = 0x40000
-	ATTR_CMN_FNDRINFO                 = 0x4000
-	ATTR_CMN_FSID                     = 0x4
-	ATTR_CMN_FULLPATH                 = 0x8000000
-	ATTR_CMN_GEN_COUNT                = 0x80000
-	ATTR_CMN_GRPID                    = 0x10000
-	ATTR_CMN_GRPUUID                  = 0x1000000
-	ATTR_CMN_MODTIME                  = 0x400
-	ATTR_CMN_NAME                     = 0x1
-	ATTR_CMN_NAMEDATTRCOUNT           = 0x80000
-	ATTR_CMN_NAMEDATTRLIST            = 0x100000
-	ATTR_CMN_OBJID                    = 0x20
-	ATTR_CMN_OBJPERMANENTID           = 0x40
-	ATTR_CMN_OBJTAG                   = 0x10
-	ATTR_CMN_OBJTYPE                  = 0x8
-	ATTR_CMN_OWNERID                  = 0x8000
-	ATTR_CMN_PARENTID                 = 0x4000000
-	ATTR_CMN_PAROBJID                 = 0x80
-	ATTR_CMN_RETURNED_ATTRS           = 0x80000000
-	ATTR_CMN_SCRIPT                   = 0x100
-	ATTR_CMN_SETMASK                  = 0x41c7ff00
-	ATTR_CMN_USERACCESS               = 0x200000
-	ATTR_CMN_UUID                     = 0x800000
-	ATTR_CMN_VALIDMASK                = 0xffffffff
-	ATTR_CMN_VOLSETMASK               = 0x6700
-	ATTR_FILE_ALLOCSIZE               = 0x4
-	ATTR_FILE_CLUMPSIZE               = 0x10
-	ATTR_FILE_DATAALLOCSIZE           = 0x400
-	ATTR_FILE_DATAEXTENTS             = 0x800
-	ATTR_FILE_DATALENGTH              = 0x200
-	ATTR_FILE_DEVTYPE                 = 0x20
-	ATTR_FILE_FILETYPE                = 0x40
-	ATTR_FILE_FORKCOUNT               = 0x80
-	ATTR_FILE_FORKLIST                = 0x100
-	ATTR_FILE_IOBLOCKSIZE             = 0x8
-	ATTR_FILE_LINKCOUNT               = 0x1
-	ATTR_FILE_RSRCALLOCSIZE           = 0x2000
-	ATTR_FILE_RSRCEXTENTS             = 0x4000
-	ATTR_FILE_RSRCLENGTH              = 0x1000
-	ATTR_FILE_SETMASK                 = 0x20
-	ATTR_FILE_TOTALSIZE               = 0x2
-	ATTR_FILE_VALIDMASK               = 0x37ff
-	ATTR_VOL_ALLOCATIONCLUMP          = 0x40
-	ATTR_VOL_ATTRIBUTES               = 0x40000000
-	ATTR_VOL_CAPABILITIES             = 0x20000
-	ATTR_VOL_DIRCOUNT                 = 0x400
-	ATTR_VOL_ENCODINGSUSED            = 0x10000
-	ATTR_VOL_FILECOUNT                = 0x200
-	ATTR_VOL_FSTYPE                   = 0x1
-	ATTR_VOL_INFO                     = 0x80000000
-	ATTR_VOL_IOBLOCKSIZE              = 0x80
-	ATTR_VOL_MAXOBJCOUNT              = 0x800
-	ATTR_VOL_MINALLOCATION            = 0x20
-	ATTR_VOL_MOUNTEDDEVICE            = 0x8000
-	ATTR_VOL_MOUNTFLAGS               = 0x4000
-	ATTR_VOL_MOUNTPOINT               = 0x1000
-	ATTR_VOL_NAME                     = 0x2000
-	ATTR_VOL_OBJCOUNT                 = 0x100
-	ATTR_VOL_QUOTA_SIZE               = 0x10000000
-	ATTR_VOL_RESERVED_SIZE            = 0x20000000
-	ATTR_VOL_SETMASK                  = 0x80002000
-	ATTR_VOL_SIGNATURE                = 0x2
-	ATTR_VOL_SIZE                     = 0x4
-	ATTR_VOL_SPACEAVAIL               = 0x10
-	ATTR_VOL_SPACEFREE                = 0x8
-	ATTR_VOL_UUID                     = 0x40000
-	ATTR_VOL_VALIDMASK                = 0xf007ffff
-	B0                                = 0x0
-	B110                              = 0x6e
-	B115200                           = 0x1c200
-	B1200                             = 0x4b0
-	B134                              = 0x86
-	B14400                            = 0x3840
-	B150                              = 0x96
-	B1800                             = 0x708
-	B19200                            = 0x4b00
-	B200                              = 0xc8
-	B230400                           = 0x38400
-	B2400                             = 0x960
-	B28800                            = 0x7080
-	B300                              = 0x12c
-	B38400                            = 0x9600
-	B4800                             = 0x12c0
-	B50                               = 0x32
-	B57600                            = 0xe100
-	B600                              = 0x258
-	B7200                             = 0x1c20
-	B75                               = 0x4b
-	B76800                            = 0x12c00
-	B9600                             = 0x2580
-	BIOCFLUSH                         = 0x20004268
-	BIOCGBLEN                         = 0x40044266
-	BIOCGDLT                          = 0x4004426a
-	BIOCGDLTLIST                      = 0xc00c4279
-	BIOCGETIF                         = 0x4020426b
-	BIOCGHDRCMPLT                     = 0x40044274
-	BIOCGRSIG                         = 0x40044272
-	BIOCGRTIMEOUT                     = 0x4010426e
-	BIOCGSEESENT                      = 0x40044276
-	BIOCGSTATS                        = 0x4008426f
-	BIOCIMMEDIATE                     = 0x80044270
-	BIOCPROMISC                       = 0x20004269
-	BIOCSBLEN                         = 0xc0044266
-	BIOCSDLT                          = 0x80044278
-	BIOCSETF                          = 0x80104267
-	BIOCSETFNR                        = 0x8010427e
-	BIOCSETIF                         = 0x8020426c
-	BIOCSHDRCMPLT                     = 0x80044275
-	BIOCSRSIG                         = 0x80044273
-	BIOCSRTIMEOUT                     = 0x8010426d
-	BIOCSSEESENT                      = 0x80044277
-	BIOCVERSION                       = 0x40044271
-	BPF_A                             = 0x10
-	BPF_ABS                           = 0x20
-	BPF_ADD                           = 0x0
-	BPF_ALIGNMENT                     = 0x4
-	BPF_ALU                           = 0x4
-	BPF_AND                           = 0x50
-	BPF_B                             = 0x10
-	BPF_DIV                           = 0x30
-	BPF_H                             = 0x8
-	BPF_IMM                           = 0x0
-	BPF_IND                           = 0x40
-	BPF_JA                            = 0x0
-	BPF_JEQ                           = 0x10
-	BPF_JGE                           = 0x30
-	BPF_JGT                           = 0x20
-	BPF_JMP                           = 0x5
-	BPF_JSET                          = 0x40
-	BPF_K                             = 0x0
-	BPF_LD                            = 0x0
-	BPF_LDX                           = 0x1
-	BPF_LEN                           = 0x80
-	BPF_LSH                           = 0x60
-	BPF_MAJOR_VERSION                 = 0x1
-	BPF_MAXBUFSIZE                    = 0x80000
-	BPF_MAXINSNS                      = 0x200
-	BPF_MEM                           = 0x60
-	BPF_MEMWORDS                      = 0x10
-	BPF_MINBUFSIZE                    = 0x20
-	BPF_MINOR_VERSION                 = 0x1
-	BPF_MISC                          = 0x7
-	BPF_MSH                           = 0xa0
-	BPF_MUL                           = 0x20
-	BPF_NEG                           = 0x80
-	BPF_OR                            = 0x40
-	BPF_RELEASE                       = 0x30bb6
-	BPF_RET                           = 0x6
-	BPF_RSH                           = 0x70
-	BPF_ST                            = 0x2
-	BPF_STX                           = 0x3
-	BPF_SUB                           = 0x10
-	BPF_TAX                           = 0x0
-	BPF_TXA                           = 0x80
-	BPF_W                             = 0x0
-	BPF_X                             = 0x8
-	BRKINT                            = 0x2
-	BS0                               = 0x0
-	BS1                               = 0x8000
-	BSDLY                             = 0x8000
-	CFLUSH                            = 0xf
-	CLOCAL                            = 0x8000
-	CLOCK_MONOTONIC                   = 0x6
-	CLOCK_MONOTONIC_RAW               = 0x4
-	CLOCK_MONOTONIC_RAW_APPROX        = 0x5
-	CLOCK_PROCESS_CPUTIME_ID          = 0xc
-	CLOCK_REALTIME                    = 0x0
-	CLOCK_THREAD_CPUTIME_ID           = 0x10
-	CLOCK_UPTIME_RAW                  = 0x8
-	CLOCK_UPTIME_RAW_APPROX           = 0x9
-	CLONE_NOFOLLOW                    = 0x1
-	CLONE_NOOWNERCOPY                 = 0x2
-	CR0                               = 0x0
-	CR1                               = 0x1000
-	CR2                               = 0x2000
-	CR3                               = 0x3000
-	CRDLY                             = 0x3000
-	CREAD                             = 0x800
-	CRTSCTS                           = 0x30000
-	CS5                               = 0x0
-	CS6                               = 0x100
-	CS7                               = 0x200
-	CS8                               = 0x300
-	CSIZE                             = 0x300
-	CSTART                            = 0x11
-	CSTATUS                           = 0x14
-	CSTOP                             = 0x13
-	CSTOPB                            = 0x400
-	CSUSP                             = 0x1a
-	CTLIOCGINFO                       = 0xc0644e03
-	CTL_HW                            = 0x6
-	CTL_KERN                          = 0x1
-	CTL_MAXNAME                       = 0xc
-	CTL_NET                           = 0x4
-	DLT_A429                          = 0xb8
-	DLT_A653_ICM                      = 0xb9
-	DLT_AIRONET_HEADER                = 0x78
-	DLT_AOS                           = 0xde
-	DLT_APPLE_IP_OVER_IEEE1394        = 0x8a
-	DLT_ARCNET                        = 0x7
-	DLT_ARCNET_LINUX                  = 0x81
-	DLT_ATM_CLIP                      = 0x13
-	DLT_ATM_RFC1483                   = 0xb
-	DLT_AURORA                        = 0x7e
-	DLT_AX25                          = 0x3
-	DLT_AX25_KISS                     = 0xca
-	DLT_BACNET_MS_TP                  = 0xa5
-	DLT_BLUETOOTH_HCI_H4              = 0xbb
-	DLT_BLUETOOTH_HCI_H4_WITH_PHDR    = 0xc9
-	DLT_CAN20B                        = 0xbe
-	DLT_CAN_SOCKETCAN                 = 0xe3
-	DLT_CHAOS                         = 0x5
-	DLT_CHDLC                         = 0x68
-	DLT_CISCO_IOS                     = 0x76
-	DLT_C_HDLC                        = 0x68
-	DLT_C_HDLC_WITH_DIR               = 0xcd
-	DLT_DBUS                          = 0xe7
-	DLT_DECT                          = 0xdd
-	DLT_DOCSIS                        = 0x8f
-	DLT_DVB_CI                        = 0xeb
-	DLT_ECONET                        = 0x73
-	DLT_EN10MB                        = 0x1
-	DLT_EN3MB                         = 0x2
-	DLT_ENC                           = 0x6d
-	DLT_ERF                           = 0xc5
-	DLT_ERF_ETH                       = 0xaf
-	DLT_ERF_POS                       = 0xb0
-	DLT_FC_2                          = 0xe0
-	DLT_FC_2_WITH_FRAME_DELIMS        = 0xe1
-	DLT_FDDI                          = 0xa
-	DLT_FLEXRAY                       = 0xd2
-	DLT_FRELAY                        = 0x6b
-	DLT_FRELAY_WITH_DIR               = 0xce
-	DLT_GCOM_SERIAL                   = 0xad
-	DLT_GCOM_T1E1                     = 0xac
-	DLT_GPF_F                         = 0xab
-	DLT_GPF_T                         = 0xaa
-	DLT_GPRS_LLC                      = 0xa9
-	DLT_GSMTAP_ABIS                   = 0xda
-	DLT_GSMTAP_UM                     = 0xd9
-	DLT_HHDLC                         = 0x79
-	DLT_IBM_SN                        = 0x92
-	DLT_IBM_SP                        = 0x91
-	DLT_IEEE802                       = 0x6
-	DLT_IEEE802_11                    = 0x69
-	DLT_IEEE802_11_RADIO              = 0x7f
-	DLT_IEEE802_11_RADIO_AVS          = 0xa3
-	DLT_IEEE802_15_4                  = 0xc3
-	DLT_IEEE802_15_4_LINUX            = 0xbf
-	DLT_IEEE802_15_4_NOFCS            = 0xe6
-	DLT_IEEE802_15_4_NONASK_PHY       = 0xd7
-	DLT_IEEE802_16_MAC_CPS            = 0xbc
-	DLT_IEEE802_16_MAC_CPS_RADIO      = 0xc1
-	DLT_IPFILTER                      = 0x74
-	DLT_IPMB                          = 0xc7
-	DLT_IPMB_LINUX                    = 0xd1
-	DLT_IPNET                         = 0xe2
-	DLT_IPOIB                         = 0xf2
-	DLT_IPV4                          = 0xe4
-	DLT_IPV6                          = 0xe5
-	DLT_IP_OVER_FC                    = 0x7a
-	DLT_JUNIPER_ATM1                  = 0x89
-	DLT_JUNIPER_ATM2                  = 0x87
-	DLT_JUNIPER_ATM_CEMIC             = 0xee
-	DLT_JUNIPER_CHDLC                 = 0xb5
-	DLT_JUNIPER_ES                    = 0x84
-	DLT_JUNIPER_ETHER                 = 0xb2
-	DLT_JUNIPER_FIBRECHANNEL          = 0xea
-	DLT_JUNIPER_FRELAY                = 0xb4
-	DLT_JUNIPER_GGSN                  = 0x85
-	DLT_JUNIPER_ISM                   = 0xc2
-	DLT_JUNIPER_MFR                   = 0x86
-	DLT_JUNIPER_MLFR                  = 0x83
-	DLT_JUNIPER_MLPPP                 = 0x82
-	DLT_JUNIPER_MONITOR               = 0xa4
-	DLT_JUNIPER_PIC_PEER              = 0xae
-	DLT_JUNIPER_PPP                   = 0xb3
-	DLT_JUNIPER_PPPOE                 = 0xa7
-	DLT_JUNIPER_PPPOE_ATM             = 0xa8
-	DLT_JUNIPER_SERVICES              = 0x88
-	DLT_JUNIPER_SRX_E2E               = 0xe9
-	DLT_JUNIPER_ST                    = 0xc8
-	DLT_JUNIPER_VP                    = 0xb7
-	DLT_JUNIPER_VS                    = 0xe8
-	DLT_LAPB_WITH_DIR                 = 0xcf
-	DLT_LAPD                          = 0xcb
-	DLT_LIN                           = 0xd4
-	DLT_LINUX_EVDEV                   = 0xd8
-	DLT_LINUX_IRDA                    = 0x90
-	DLT_LINUX_LAPD                    = 0xb1
-	DLT_LINUX_PPP_WITHDIRECTION       = 0xa6
-	DLT_LINUX_SLL                     = 0x71
-	DLT_LOOP                          = 0x6c
-	DLT_LTALK                         = 0x72
-	DLT_MATCHING_MAX                  = 0xf5
-	DLT_MATCHING_MIN                  = 0x68
-	DLT_MFR                           = 0xb6
-	DLT_MOST                          = 0xd3
-	DLT_MPEG_2_TS                     = 0xf3
-	DLT_MPLS                          = 0xdb
-	DLT_MTP2                          = 0x8c
-	DLT_MTP2_WITH_PHDR                = 0x8b
-	DLT_MTP3                          = 0x8d
-	DLT_MUX27010                      = 0xec
-	DLT_NETANALYZER                   = 0xf0
-	DLT_NETANALYZER_TRANSPARENT       = 0xf1
-	DLT_NFC_LLCP                      = 0xf5
-	DLT_NFLOG                         = 0xef
-	DLT_NG40                          = 0xf4
-	DLT_NULL                          = 0x0
-	DLT_PCI_EXP                       = 0x7d
-	DLT_PFLOG                         = 0x75
-	DLT_PFSYNC                        = 0x12
-	DLT_PPI                           = 0xc0
-	DLT_PPP                           = 0x9
-	DLT_PPP_BSDOS                     = 0x10
-	DLT_PPP_ETHER                     = 0x33
-	DLT_PPP_PPPD                      = 0xa6
-	DLT_PPP_SERIAL                    = 0x32
-	DLT_PPP_WITH_DIR                  = 0xcc
-	DLT_PPP_WITH_DIRECTION            = 0xa6
-	DLT_PRISM_HEADER                  = 0x77
-	DLT_PRONET                        = 0x4
-	DLT_RAIF1                         = 0xc6
-	DLT_RAW                           = 0xc
-	DLT_RIO                           = 0x7c
-	DLT_SCCP                          = 0x8e
-	DLT_SITA                          = 0xc4
-	DLT_SLIP                          = 0x8
-	DLT_SLIP_BSDOS                    = 0xf
-	DLT_STANAG_5066_D_PDU             = 0xed
-	DLT_SUNATM                        = 0x7b
-	DLT_SYMANTEC_FIREWALL             = 0x63
-	DLT_TZSP                          = 0x80
-	DLT_USB                           = 0xba
-	DLT_USB_LINUX                     = 0xbd
-	DLT_USB_LINUX_MMAPPED             = 0xdc
-	DLT_USER0                         = 0x93
-	DLT_USER1                         = 0x94
-	DLT_USER10                        = 0x9d
-	DLT_USER11                        = 0x9e
-	DLT_USER12                        = 0x9f
-	DLT_USER13                        = 0xa0
-	DLT_USER14                        = 0xa1
-	DLT_USER15                        = 0xa2
-	DLT_USER2                         = 0x95
-	DLT_USER3                         = 0x96
-	DLT_USER4                         = 0x97
-	DLT_USER5                         = 0x98
-	DLT_USER6                         = 0x99
-	DLT_USER7                         = 0x9a
-	DLT_USER8                         = 0x9b
-	DLT_USER9                         = 0x9c
-	DLT_WIHART                        = 0xdf
-	DLT_X2E_SERIAL                    = 0xd5
-	DLT_X2E_XORAYA                    = 0xd6
-	DT_BLK                            = 0x6
-	DT_CHR                            = 0x2
-	DT_DIR                            = 0x4
-	DT_FIFO                           = 0x1
-	DT_LNK                            = 0xa
-	DT_REG                            = 0x8
-	DT_SOCK                           = 0xc
-	DT_UNKNOWN                        = 0x0
-	DT_WHT                            = 0xe
-	ECHO                              = 0x8
-	ECHOCTL                           = 0x40
-	ECHOE                             = 0x2
-	ECHOK                             = 0x4
-	ECHOKE                            = 0x1
-	ECHONL                            = 0x10
-	ECHOPRT                           = 0x20
-	EVFILT_AIO                        = -0x3
-	EVFILT_EXCEPT                     = -0xf
-	EVFILT_FS                         = -0x9
-	EVFILT_MACHPORT                   = -0x8
-	EVFILT_PROC                       = -0x5
-	EVFILT_READ                       = -0x1
-	EVFILT_SIGNAL                     = -0x6
-	EVFILT_SYSCOUNT                   = 0xf
-	EVFILT_THREADMARKER               = 0xf
-	EVFILT_TIMER                      = -0x7
-	EVFILT_USER                       = -0xa
-	EVFILT_VM                         = -0xc
-	EVFILT_VNODE                      = -0x4
-	EVFILT_WRITE                      = -0x2
-	EV_ADD                            = 0x1
-	EV_CLEAR                          = 0x20
-	EV_DELETE                         = 0x2
-	EV_DISABLE                        = 0x8
-	EV_DISPATCH                       = 0x80
-	EV_DISPATCH2                      = 0x180
-	EV_ENABLE                         = 0x4
-	EV_EOF                            = 0x8000
-	EV_ERROR                          = 0x4000
-	EV_FLAG0                          = 0x1000
-	EV_FLAG1                          = 0x2000
-	EV_ONESHOT                        = 0x10
-	EV_OOBAND                         = 0x2000
-	EV_POLL                           = 0x1000
-	EV_RECEIPT                        = 0x40
-	EV_SYSFLAGS                       = 0xf000
-	EV_UDATA_SPECIFIC                 = 0x100
-	EV_VANISHED                       = 0x200
-	EXTA                              = 0x4b00
-	EXTB                              = 0x9600
-	EXTPROC                           = 0x800
-	FD_CLOEXEC                        = 0x1
-	FD_SETSIZE                        = 0x400
-	FF0                               = 0x0
-	FF1                               = 0x4000
-	FFDLY                             = 0x4000
-	FLUSHO                            = 0x800000
-	FSOPT_ATTR_CMN_EXTENDED           = 0x20
-	FSOPT_NOFOLLOW                    = 0x1
-	FSOPT_NOINMEMUPDATE               = 0x2
-	FSOPT_PACK_INVAL_ATTRS            = 0x8
-	FSOPT_REPORT_FULLSIZE             = 0x4
-	F_ADDFILESIGS                     = 0x3d
-	F_ADDFILESIGS_FOR_DYLD_SIM        = 0x53
-	F_ADDFILESIGS_RETURN              = 0x61
-	F_ADDSIGS                         = 0x3b
-	F_ALLOCATEALL                     = 0x4
-	F_ALLOCATECONTIG                  = 0x2
-	F_BARRIERFSYNC                    = 0x55
-	F_CHECK_LV                        = 0x62
-	F_CHKCLEAN                        = 0x29
-	F_DUPFD                           = 0x0
-	F_DUPFD_CLOEXEC                   = 0x43
-	F_FINDSIGS                        = 0x4e
-	F_FLUSH_DATA                      = 0x28
-	F_FREEZE_FS                       = 0x35
-	F_FULLFSYNC                       = 0x33
-	F_GETCODEDIR                      = 0x48
-	F_GETFD                           = 0x1
-	F_GETFL                           = 0x3
-	F_GETLK                           = 0x7
-	F_GETLKPID                        = 0x42
-	F_GETNOSIGPIPE                    = 0x4a
-	F_GETOWN                          = 0x5
-	F_GETPATH                         = 0x32
-	F_GETPATH_MTMINFO                 = 0x47
-	F_GETPROTECTIONCLASS              = 0x3f
-	F_GETPROTECTIONLEVEL              = 0x4d
-	F_GLOBAL_NOCACHE                  = 0x37
-	F_LOG2PHYS                        = 0x31
-	F_LOG2PHYS_EXT                    = 0x41
-	F_NOCACHE                         = 0x30
-	F_NODIRECT                        = 0x3e
-	F_OK                              = 0x0
-	F_PATHPKG_CHECK                   = 0x34
-	F_PEOFPOSMODE                     = 0x3
-	F_PREALLOCATE                     = 0x2a
-	F_PUNCHHOLE                       = 0x63
-	F_RDADVISE                        = 0x2c
-	F_RDAHEAD                         = 0x2d
-	F_RDLCK                           = 0x1
-	F_SETBACKINGSTORE                 = 0x46
-	F_SETFD                           = 0x2
-	F_SETFL                           = 0x4
-	F_SETLK                           = 0x8
-	F_SETLKW                          = 0x9
-	F_SETLKWTIMEOUT                   = 0xa
-	F_SETNOSIGPIPE                    = 0x49
-	F_SETOWN                          = 0x6
-	F_SETPROTECTIONCLASS              = 0x40
-	F_SETSIZE                         = 0x2b
-	F_SINGLE_WRITER                   = 0x4c
-	F_THAW_FS                         = 0x36
-	F_TRANSCODEKEY                    = 0x4b
-	F_TRIM_ACTIVE_FILE                = 0x64
-	F_UNLCK                           = 0x2
-	F_VOLPOSMODE                      = 0x4
-	F_WRLCK                           = 0x3
-	HUPCL                             = 0x4000
-	HW_MACHINE                        = 0x1
-	ICANON                            = 0x100
-	ICMP6_FILTER                      = 0x12
-	ICRNL                             = 0x100
-	IEXTEN                            = 0x400
-	IFF_ALLMULTI                      = 0x200
-	IFF_ALTPHYS                       = 0x4000
-	IFF_BROADCAST                     = 0x2
-	IFF_DEBUG                         = 0x4
-	IFF_LINK0                         = 0x1000
-	IFF_LINK1                         = 0x2000
-	IFF_LINK2                         = 0x4000
-	IFF_LOOPBACK                      = 0x8
-	IFF_MULTICAST                     = 0x8000
-	IFF_NOARP                         = 0x80
-	IFF_NOTRAILERS                    = 0x20
-	IFF_OACTIVE                       = 0x400
-	IFF_POINTOPOINT                   = 0x10
-	IFF_PROMISC                       = 0x100
-	IFF_RUNNING                       = 0x40
-	IFF_SIMPLEX                       = 0x800
-	IFF_UP                            = 0x1
-	IFNAMSIZ                          = 0x10
-	IFT_1822                          = 0x2
-	IFT_AAL5                          = 0x31
-	IFT_ARCNET                        = 0x23
-	IFT_ARCNETPLUS                    = 0x24
-	IFT_ATM                           = 0x25
-	IFT_BRIDGE                        = 0xd1
-	IFT_CARP                          = 0xf8
-	IFT_CELLULAR                      = 0xff
-	IFT_CEPT                          = 0x13
-	IFT_DS3                           = 0x1e
-	IFT_ENC                           = 0xf4
-	IFT_EON                           = 0x19
-	IFT_ETHER                         = 0x6
-	IFT_FAITH                         = 0x38
-	IFT_FDDI                          = 0xf
-	IFT_FRELAY                        = 0x20
-	IFT_FRELAYDCE                     = 0x2c
-	IFT_GIF                           = 0x37
-	IFT_HDH1822                       = 0x3
-	IFT_HIPPI                         = 0x2f
-	IFT_HSSI                          = 0x2e
-	IFT_HY                            = 0xe
-	IFT_IEEE1394                      = 0x90
-	IFT_IEEE8023ADLAG                 = 0x88
-	IFT_ISDNBASIC                     = 0x14
-	IFT_ISDNPRIMARY                   = 0x15
-	IFT_ISO88022LLC                   = 0x29
-	IFT_ISO88023                      = 0x7
-	IFT_ISO88024                      = 0x8
-	IFT_ISO88025                      = 0x9
-	IFT_ISO88026                      = 0xa
-	IFT_L2VLAN                        = 0x87
-	IFT_LAPB                          = 0x10
-	IFT_LOCALTALK                     = 0x2a
-	IFT_LOOP                          = 0x18
-	IFT_MIOX25                        = 0x26
-	IFT_MODEM                         = 0x30
-	IFT_NSIP                          = 0x1b
-	IFT_OTHER                         = 0x1
-	IFT_P10                           = 0xc
-	IFT_P80                           = 0xd
-	IFT_PARA                          = 0x22
-	IFT_PDP                           = 0xff
-	IFT_PFLOG                         = 0xf5
-	IFT_PFSYNC                        = 0xf6
-	IFT_PKTAP                         = 0xfe
-	IFT_PPP                           = 0x17
-	IFT_PROPMUX                       = 0x36
-	IFT_PROPVIRTUAL                   = 0x35
-	IFT_PTPSERIAL                     = 0x16
-	IFT_RS232                         = 0x21
-	IFT_SDLC                          = 0x11
-	IFT_SIP                           = 0x1f
-	IFT_SLIP                          = 0x1c
-	IFT_SMDSDXI                       = 0x2b
-	IFT_SMDSICIP                      = 0x34
-	IFT_SONET                         = 0x27
-	IFT_SONETPATH                     = 0x32
-	IFT_SONETVT                       = 0x33
-	IFT_STARLAN                       = 0xb
-	IFT_STF                           = 0x39
-	IFT_T1                            = 0x12
-	IFT_ULTRA                         = 0x1d
-	IFT_V35                           = 0x2d
-	IFT_X25                           = 0x5
-	IFT_X25DDN                        = 0x4
-	IFT_X25PLE                        = 0x28
-	IFT_XETHER                        = 0x1a
-	IGNBRK                            = 0x1
-	IGNCR                             = 0x80
-	IGNPAR                            = 0x4
-	IMAXBEL                           = 0x2000
-	INLCR                             = 0x40
-	INPCK                             = 0x10
-	IN_CLASSA_HOST                    = 0xffffff
-	IN_CLASSA_MAX                     = 0x80
-	IN_CLASSA_NET                     = 0xff000000
-	IN_CLASSA_NSHIFT                  = 0x18
-	IN_CLASSB_HOST                    = 0xffff
-	IN_CLASSB_MAX                     = 0x10000
-	IN_CLASSB_NET                     = 0xffff0000
-	IN_CLASSB_NSHIFT                  = 0x10
-	IN_CLASSC_HOST                    = 0xff
-	IN_CLASSC_NET                     = 0xffffff00
-	IN_CLASSC_NSHIFT                  = 0x8
-	IN_CLASSD_HOST                    = 0xfffffff
-	IN_CLASSD_NET                     = 0xf0000000
-	IN_CLASSD_NSHIFT                  = 0x1c
-	IN_LINKLOCALNETNUM                = 0xa9fe0000
-	IN_LOOPBACKNET                    = 0x7f
-	IPPROTO_3PC                       = 0x22
-	IPPROTO_ADFS                      = 0x44
-	IPPROTO_AH                        = 0x33
-	IPPROTO_AHIP                      = 0x3d
-	IPPROTO_APES                      = 0x63
-	IPPROTO_ARGUS                     = 0xd
-	IPPROTO_AX25                      = 0x5d
-	IPPROTO_BHA                       = 0x31
-	IPPROTO_BLT                       = 0x1e
-	IPPROTO_BRSATMON                  = 0x4c
-	IPPROTO_CFTP                      = 0x3e
-	IPPROTO_CHAOS                     = 0x10
-	IPPROTO_CMTP                      = 0x26
-	IPPROTO_CPHB                      = 0x49
-	IPPROTO_CPNX                      = 0x48
-	IPPROTO_DDP                       = 0x25
-	IPPROTO_DGP                       = 0x56
-	IPPROTO_DIVERT                    = 0xfe
-	IPPROTO_DONE                      = 0x101
-	IPPROTO_DSTOPTS                   = 0x3c
-	IPPROTO_EGP                       = 0x8
-	IPPROTO_EMCON                     = 0xe
-	IPPROTO_ENCAP                     = 0x62
-	IPPROTO_EON                       = 0x50
-	IPPROTO_ESP                       = 0x32
-	IPPROTO_ETHERIP                   = 0x61
-	IPPROTO_FRAGMENT                  = 0x2c
-	IPPROTO_GGP                       = 0x3
-	IPPROTO_GMTP                      = 0x64
-	IPPROTO_GRE                       = 0x2f
-	IPPROTO_HELLO                     = 0x3f
-	IPPROTO_HMP                       = 0x14
-	IPPROTO_HOPOPTS                   = 0x0
-	IPPROTO_ICMP                      = 0x1
-	IPPROTO_ICMPV6                    = 0x3a
-	IPPROTO_IDP                       = 0x16
-	IPPROTO_IDPR                      = 0x23
-	IPPROTO_IDRP                      = 0x2d
-	IPPROTO_IGMP                      = 0x2
-	IPPROTO_IGP                       = 0x55
-	IPPROTO_IGRP                      = 0x58
-	IPPROTO_IL                        = 0x28
-	IPPROTO_INLSP                     = 0x34
-	IPPROTO_INP                       = 0x20
-	IPPROTO_IP                        = 0x0
-	IPPROTO_IPCOMP                    = 0x6c
-	IPPROTO_IPCV                      = 0x47
-	IPPROTO_IPEIP                     = 0x5e
-	IPPROTO_IPIP                      = 0x4
-	IPPROTO_IPPC                      = 0x43
-	IPPROTO_IPV4                      = 0x4
-	IPPROTO_IPV6                      = 0x29
-	IPPROTO_IRTP                      = 0x1c
-	IPPROTO_KRYPTOLAN                 = 0x41
-	IPPROTO_LARP                      = 0x5b
-	IPPROTO_LEAF1                     = 0x19
-	IPPROTO_LEAF2                     = 0x1a
-	IPPROTO_MAX                       = 0x100
-	IPPROTO_MAXID                     = 0x34
-	IPPROTO_MEAS                      = 0x13
-	IPPROTO_MHRP                      = 0x30
-	IPPROTO_MICP                      = 0x5f
-	IPPROTO_MTP                       = 0x5c
-	IPPROTO_MUX                       = 0x12
-	IPPROTO_ND                        = 0x4d
-	IPPROTO_NHRP                      = 0x36
-	IPPROTO_NONE                      = 0x3b
-	IPPROTO_NSP                       = 0x1f
-	IPPROTO_NVPII                     = 0xb
-	IPPROTO_OSPFIGP                   = 0x59
-	IPPROTO_PGM                       = 0x71
-	IPPROTO_PIGP                      = 0x9
-	IPPROTO_PIM                       = 0x67
-	IPPROTO_PRM                       = 0x15
-	IPPROTO_PUP                       = 0xc
-	IPPROTO_PVP                       = 0x4b
-	IPPROTO_RAW                       = 0xff
-	IPPROTO_RCCMON                    = 0xa
-	IPPROTO_RDP                       = 0x1b
-	IPPROTO_ROUTING                   = 0x2b
-	IPPROTO_RSVP                      = 0x2e
-	IPPROTO_RVD                       = 0x42
-	IPPROTO_SATEXPAK                  = 0x40
-	IPPROTO_SATMON                    = 0x45
-	IPPROTO_SCCSP                     = 0x60
-	IPPROTO_SCTP                      = 0x84
-	IPPROTO_SDRP                      = 0x2a
-	IPPROTO_SEP                       = 0x21
-	IPPROTO_SRPC                      = 0x5a
-	IPPROTO_ST                        = 0x7
-	IPPROTO_SVMTP                     = 0x52
-	IPPROTO_SWIPE                     = 0x35
-	IPPROTO_TCF                       = 0x57
-	IPPROTO_TCP                       = 0x6
-	IPPROTO_TP                        = 0x1d
-	IPPROTO_TPXX                      = 0x27
-	IPPROTO_TRUNK1                    = 0x17
-	IPPROTO_TRUNK2                    = 0x18
-	IPPROTO_TTP                       = 0x54
-	IPPROTO_UDP                       = 0x11
-	IPPROTO_VINES                     = 0x53
-	IPPROTO_VISA                      = 0x46
-	IPPROTO_VMTP                      = 0x51
-	IPPROTO_WBEXPAK                   = 0x4f
-	IPPROTO_WBMON                     = 0x4e
-	IPPROTO_WSN                       = 0x4a
-	IPPROTO_XNET                      = 0xf
-	IPPROTO_XTP                       = 0x24
-	IPV6_2292DSTOPTS                  = 0x17
-	IPV6_2292HOPLIMIT                 = 0x14
-	IPV6_2292HOPOPTS                  = 0x16
-	IPV6_2292NEXTHOP                  = 0x15
-	IPV6_2292PKTINFO                  = 0x13
-	IPV6_2292PKTOPTIONS               = 0x19
-	IPV6_2292RTHDR                    = 0x18
-	IPV6_BINDV6ONLY                   = 0x1b
-	IPV6_BOUND_IF                     = 0x7d
-	IPV6_CHECKSUM                     = 0x1a
-	IPV6_DEFAULT_MULTICAST_HOPS       = 0x1
-	IPV6_DEFAULT_MULTICAST_LOOP       = 0x1
-	IPV6_DEFHLIM                      = 0x40
-	IPV6_FAITH                        = 0x1d
-	IPV6_FLOWINFO_MASK                = 0xffffff0f
-	IPV6_FLOWLABEL_MASK               = 0xffff0f00
-	IPV6_FLOW_ECN_MASK                = 0x300
-	IPV6_FRAGTTL                      = 0x3c
-	IPV6_FW_ADD                       = 0x1e
-	IPV6_FW_DEL                       = 0x1f
-	IPV6_FW_FLUSH                     = 0x20
-	IPV6_FW_GET                       = 0x22
-	IPV6_FW_ZERO                      = 0x21
-	IPV6_HLIMDEC                      = 0x1
-	IPV6_IPSEC_POLICY                 = 0x1c
-	IPV6_JOIN_GROUP                   = 0xc
-	IPV6_LEAVE_GROUP                  = 0xd
-	IPV6_MAXHLIM                      = 0xff
-	IPV6_MAXOPTHDR                    = 0x800
-	IPV6_MAXPACKET                    = 0xffff
-	IPV6_MAX_GROUP_SRC_FILTER         = 0x200
-	IPV6_MAX_MEMBERSHIPS              = 0xfff
-	IPV6_MAX_SOCK_SRC_FILTER          = 0x80
-	IPV6_MIN_MEMBERSHIPS              = 0x1f
-	IPV6_MMTU                         = 0x500
-	IPV6_MULTICAST_HOPS               = 0xa
-	IPV6_MULTICAST_IF                 = 0x9
-	IPV6_MULTICAST_LOOP               = 0xb
-	IPV6_PORTRANGE                    = 0xe
-	IPV6_PORTRANGE_DEFAULT            = 0x0
-	IPV6_PORTRANGE_HIGH               = 0x1
-	IPV6_PORTRANGE_LOW                = 0x2
-	IPV6_RECVTCLASS                   = 0x23
-	IPV6_RTHDR_LOOSE                  = 0x0
-	IPV6_RTHDR_STRICT                 = 0x1
-	IPV6_RTHDR_TYPE_0                 = 0x0
-	IPV6_SOCKOPT_RESERVED1            = 0x3
-	IPV6_TCLASS                       = 0x24
-	IPV6_UNICAST_HOPS                 = 0x4
-	IPV6_V6ONLY                       = 0x1b
-	IPV6_VERSION                      = 0x60
-	IPV6_VERSION_MASK                 = 0xf0
-	IP_ADD_MEMBERSHIP                 = 0xc
-	IP_ADD_SOURCE_MEMBERSHIP          = 0x46
-	IP_BLOCK_SOURCE                   = 0x48
-	IP_BOUND_IF                       = 0x19
-	IP_DEFAULT_MULTICAST_LOOP         = 0x1
-	IP_DEFAULT_MULTICAST_TTL          = 0x1
-	IP_DF                             = 0x4000
-	IP_DROP_MEMBERSHIP                = 0xd
-	IP_DROP_SOURCE_MEMBERSHIP         = 0x47
-	IP_DUMMYNET_CONFIGURE             = 0x3c
-	IP_DUMMYNET_DEL                   = 0x3d
-	IP_DUMMYNET_FLUSH                 = 0x3e
-	IP_DUMMYNET_GET                   = 0x40
-	IP_FAITH                          = 0x16
-	IP_FW_ADD                         = 0x28
-	IP_FW_DEL                         = 0x29
-	IP_FW_FLUSH                       = 0x2a
-	IP_FW_GET                         = 0x2c
-	IP_FW_RESETLOG                    = 0x2d
-	IP_FW_ZERO                        = 0x2b
-	IP_HDRINCL                        = 0x2
-	IP_IPSEC_POLICY                   = 0x15
-	IP_MAXPACKET                      = 0xffff
-	IP_MAX_GROUP_SRC_FILTER           = 0x200
-	IP_MAX_MEMBERSHIPS                = 0xfff
-	IP_MAX_SOCK_MUTE_FILTER           = 0x80
-	IP_MAX_SOCK_SRC_FILTER            = 0x80
-	IP_MF                             = 0x2000
-	IP_MIN_MEMBERSHIPS                = 0x1f
-	IP_MSFILTER                       = 0x4a
-	IP_MSS                            = 0x240
-	IP_MULTICAST_IF                   = 0x9
-	IP_MULTICAST_IFINDEX              = 0x42
-	IP_MULTICAST_LOOP                 = 0xb
-	IP_MULTICAST_TTL                  = 0xa
-	IP_MULTICAST_VIF                  = 0xe
-	IP_NAT__XXX                       = 0x37
-	IP_OFFMASK                        = 0x1fff
-	IP_OLD_FW_ADD                     = 0x32
-	IP_OLD_FW_DEL                     = 0x33
-	IP_OLD_FW_FLUSH                   = 0x34
-	IP_OLD_FW_GET                     = 0x36
-	IP_OLD_FW_RESETLOG                = 0x38
-	IP_OLD_FW_ZERO                    = 0x35
-	IP_OPTIONS                        = 0x1
-	IP_PKTINFO                        = 0x1a
-	IP_PORTRANGE                      = 0x13
-	IP_PORTRANGE_DEFAULT              = 0x0
-	IP_PORTRANGE_HIGH                 = 0x1
-	IP_PORTRANGE_LOW                  = 0x2
-	IP_RECVDSTADDR                    = 0x7
-	IP_RECVIF                         = 0x14
-	IP_RECVOPTS                       = 0x5
-	IP_RECVPKTINFO                    = 0x1a
-	IP_RECVRETOPTS                    = 0x6
-	IP_RECVTOS                        = 0x1b
-	IP_RECVTTL                        = 0x18
-	IP_RETOPTS                        = 0x8
-	IP_RF                             = 0x8000
-	IP_RSVP_OFF                       = 0x10
-	IP_RSVP_ON                        = 0xf
-	IP_RSVP_VIF_OFF                   = 0x12
-	IP_RSVP_VIF_ON                    = 0x11
-	IP_STRIPHDR                       = 0x17
-	IP_TOS                            = 0x3
-	IP_TRAFFIC_MGT_BACKGROUND         = 0x41
-	IP_TTL                            = 0x4
-	IP_UNBLOCK_SOURCE                 = 0x49
-	ISIG                              = 0x80
-	ISTRIP                            = 0x20
-	IUTF8                             = 0x4000
-	IXANY                             = 0x800
-	IXOFF                             = 0x400
-	IXON                              = 0x200
-	KERN_HOSTNAME                     = 0xa
-	KERN_OSRELEASE                    = 0x2
-	KERN_OSTYPE                       = 0x1
-	KERN_VERSION                      = 0x4
-	LOCK_EX                           = 0x2
-	LOCK_NB                           = 0x4
-	LOCK_SH                           = 0x1
-	LOCK_UN                           = 0x8
-	MADV_CAN_REUSE                    = 0x9
-	MADV_DONTNEED                     = 0x4
-	MADV_FREE                         = 0x5
-	MADV_FREE_REUSABLE                = 0x7
-	MADV_FREE_REUSE                   = 0x8
-	MADV_NORMAL                       = 0x0
-	MADV_PAGEOUT                      = 0xa
-	MADV_RANDOM                       = 0x1
-	MADV_SEQUENTIAL                   = 0x2
-	MADV_WILLNEED                     = 0x3
-	MADV_ZERO_WIRED_PAGES             = 0x6
-	MAP_ANON                          = 0x1000
-	MAP_ANONYMOUS                     = 0x1000
-	MAP_COPY                          = 0x2
-	MAP_FILE                          = 0x0
-	MAP_FIXED                         = 0x10
-	MAP_HASSEMAPHORE                  = 0x200
-	MAP_JIT                           = 0x800
-	MAP_NOCACHE                       = 0x400
-	MAP_NOEXTEND                      = 0x100
-	MAP_NORESERVE                     = 0x40
-	MAP_PRIVATE                       = 0x2
-	MAP_RENAME                        = 0x20
-	MAP_RESERVED0080                  = 0x80
-	MAP_RESILIENT_CODESIGN            = 0x2000
-	MAP_RESILIENT_MEDIA               = 0x4000
-	MAP_SHARED                        = 0x1
-	MCL_CURRENT                       = 0x1
-	MCL_FUTURE                        = 0x2
-	MNT_ASYNC                         = 0x40
-	MNT_AUTOMOUNTED                   = 0x400000
-	MNT_CMDFLAGS                      = 0xf0000
-	MNT_CPROTECT                      = 0x80
-	MNT_DEFWRITE                      = 0x2000000
-	MNT_DONTBROWSE                    = 0x100000
-	MNT_DOVOLFS                       = 0x8000
-	MNT_DWAIT                         = 0x4
-	MNT_EXPORTED                      = 0x100
-	MNT_FORCE                         = 0x80000
-	MNT_IGNORE_OWNERSHIP              = 0x200000
-	MNT_JOURNALED                     = 0x800000
-	MNT_LOCAL                         = 0x1000
-	MNT_MULTILABEL                    = 0x4000000
-	MNT_NOATIME                       = 0x10000000
-	MNT_NOBLOCK                       = 0x20000
-	MNT_NODEV                         = 0x10
-	MNT_NOEXEC                        = 0x4
-	MNT_NOSUID                        = 0x8
-	MNT_NOUSERXATTR                   = 0x1000000
-	MNT_NOWAIT                        = 0x2
-	MNT_QUARANTINE                    = 0x400
-	MNT_QUOTA                         = 0x2000
-	MNT_RDONLY                        = 0x1
-	MNT_RELOAD                        = 0x40000
-	MNT_ROOTFS                        = 0x4000
-	MNT_SYNCHRONOUS                   = 0x2
-	MNT_UNION                         = 0x20
-	MNT_UNKNOWNPERMISSIONS            = 0x200000
-	MNT_UPDATE                        = 0x10000
-	MNT_VISFLAGMASK                   = 0x17f0f5ff
-	MNT_WAIT                          = 0x1
-	MSG_CTRUNC                        = 0x20
-	MSG_DONTROUTE                     = 0x4
-	MSG_DONTWAIT                      = 0x80
-	MSG_EOF                           = 0x100
-	MSG_EOR                           = 0x8
-	MSG_FLUSH                         = 0x400
-	MSG_HAVEMORE                      = 0x2000
-	MSG_HOLD                          = 0x800
-	MSG_NEEDSA                        = 0x10000
-	MSG_OOB                           = 0x1
-	MSG_PEEK                          = 0x2
-	MSG_RCVMORE                       = 0x4000
-	MSG_SEND                          = 0x1000
-	MSG_TRUNC                         = 0x10
-	MSG_WAITALL                       = 0x40
-	MSG_WAITSTREAM                    = 0x200
-	MS_ASYNC                          = 0x1
-	MS_DEACTIVATE                     = 0x8
-	MS_INVALIDATE                     = 0x2
-	MS_KILLPAGES                      = 0x4
-	MS_SYNC                           = 0x10
-	NAME_MAX                          = 0xff
-	NET_RT_DUMP                       = 0x1
-	NET_RT_DUMP2                      = 0x7
-	NET_RT_FLAGS                      = 0x2
-	NET_RT_IFLIST                     = 0x3
-	NET_RT_IFLIST2                    = 0x6
-	NET_RT_MAXID                      = 0xa
-	NET_RT_STAT                       = 0x4
-	NET_RT_TRASH                      = 0x5
-	NFDBITS                           = 0x20
-	NL0                               = 0x0
-	NL1                               = 0x100
-	NL2                               = 0x200
-	NL3                               = 0x300
-	NLDLY                             = 0x300
-	NOFLSH                            = 0x80000000
-	NOKERNINFO                        = 0x2000000
-	NOTE_ABSOLUTE                     = 0x8
-	NOTE_ATTRIB                       = 0x8
-	NOTE_BACKGROUND                   = 0x40
-	NOTE_CHILD                        = 0x4
-	NOTE_CRITICAL                     = 0x20
-	NOTE_DELETE                       = 0x1
-	NOTE_EXEC                         = 0x20000000
-	NOTE_EXIT                         = 0x80000000
-	NOTE_EXITSTATUS                   = 0x4000000
-	NOTE_EXIT_CSERROR                 = 0x40000
-	NOTE_EXIT_DECRYPTFAIL             = 0x10000
-	NOTE_EXIT_DETAIL                  = 0x2000000
-	NOTE_EXIT_DETAIL_MASK             = 0x70000
-	NOTE_EXIT_MEMORY                  = 0x20000
-	NOTE_EXIT_REPARENTED              = 0x80000
-	NOTE_EXTEND                       = 0x4
-	NOTE_FFAND                        = 0x40000000
-	NOTE_FFCOPY                       = 0xc0000000
-	NOTE_FFCTRLMASK                   = 0xc0000000
-	NOTE_FFLAGSMASK                   = 0xffffff
-	NOTE_FFNOP                        = 0x0
-	NOTE_FFOR                         = 0x80000000
-	NOTE_FORK                         = 0x40000000
-	NOTE_FUNLOCK                      = 0x100
-	NOTE_LEEWAY                       = 0x10
-	NOTE_LINK                         = 0x10
-	NOTE_LOWAT                        = 0x1
-	NOTE_MACH_CONTINUOUS_TIME         = 0x80
-	NOTE_NONE                         = 0x80
-	NOTE_NSECONDS                     = 0x4
-	NOTE_OOB                          = 0x2
-	NOTE_PCTRLMASK                    = -0x100000
-	NOTE_PDATAMASK                    = 0xfffff
-	NOTE_REAP                         = 0x10000000
-	NOTE_RENAME                       = 0x20
-	NOTE_REVOKE                       = 0x40
-	NOTE_SECONDS                      = 0x1
-	NOTE_SIGNAL                       = 0x8000000
-	NOTE_TRACK                        = 0x1
-	NOTE_TRACKERR                     = 0x2
-	NOTE_TRIGGER                      = 0x1000000
-	NOTE_USECONDS                     = 0x2
-	NOTE_VM_ERROR                     = 0x10000000
-	NOTE_VM_PRESSURE                  = 0x80000000
-	NOTE_VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000
-	NOTE_VM_PRESSURE_TERMINATE        = 0x40000000
-	NOTE_WRITE                        = 0x2
-	OCRNL                             = 0x10
-	OFDEL                             = 0x20000
-	OFILL                             = 0x80
-	ONLCR                             = 0x2
-	ONLRET                            = 0x40
-	ONOCR                             = 0x20
-	ONOEOT                            = 0x8
-	OPOST                             = 0x1
-	OXTABS                            = 0x4
-	O_ACCMODE                         = 0x3
-	O_ALERT                           = 0x20000000
-	O_APPEND                          = 0x8
-	O_ASYNC                           = 0x40
-	O_CLOEXEC                         = 0x1000000
-	O_CREAT                           = 0x200
-	O_DIRECTORY                       = 0x100000
-	O_DP_GETRAWENCRYPTED              = 0x1
-	O_DP_GETRAWUNENCRYPTED            = 0x2
-	O_DSYNC                           = 0x400000
-	O_EVTONLY                         = 0x8000
-	O_EXCL                            = 0x800
-	O_EXLOCK                          = 0x20
-	O_FSYNC                           = 0x80
-	O_NDELAY                          = 0x4
-	O_NOCTTY                          = 0x20000
-	O_NOFOLLOW                        = 0x100
-	O_NONBLOCK                        = 0x4
-	O_POPUP                           = 0x80000000
-	O_RDONLY                          = 0x0
-	O_RDWR                            = 0x2
-	O_SHLOCK                          = 0x10
-	O_SYMLINK                         = 0x200000
-	O_SYNC                            = 0x80
-	O_TRUNC                           = 0x400
-	O_WRONLY                          = 0x1
-	PARENB                            = 0x1000
-	PARMRK                            = 0x8
-	PARODD                            = 0x2000
-	PENDIN                            = 0x20000000
-	PRIO_PGRP                         = 0x1
-	PRIO_PROCESS                      = 0x0
-	PRIO_USER                         = 0x2
-	PROT_EXEC                         = 0x4
-	PROT_NONE                         = 0x0
-	PROT_READ                         = 0x1
-	PROT_WRITE                        = 0x2
-	PT_ATTACH                         = 0xa
-	PT_ATTACHEXC                      = 0xe
-	PT_CONTINUE                       = 0x7
-	PT_DENY_ATTACH                    = 0x1f
-	PT_DETACH                         = 0xb
-	PT_FIRSTMACH                      = 0x20
-	PT_FORCEQUOTA                     = 0x1e
-	PT_KILL                           = 0x8
-	PT_READ_D                         = 0x2
-	PT_READ_I                         = 0x1
-	PT_READ_U                         = 0x3
-	PT_SIGEXC                         = 0xc
-	PT_STEP                           = 0x9
-	PT_THUPDATE                       = 0xd
-	PT_TRACE_ME                       = 0x0
-	PT_WRITE_D                        = 0x5
-	PT_WRITE_I                        = 0x4
-	PT_WRITE_U                        = 0x6
-	RLIMIT_AS                         = 0x5
-	RLIMIT_CORE                       = 0x4
-	RLIMIT_CPU                        = 0x0
-	RLIMIT_CPU_USAGE_MONITOR          = 0x2
-	RLIMIT_DATA                       = 0x2
-	RLIMIT_FSIZE                      = 0x1
-	RLIMIT_MEMLOCK                    = 0x6
-	RLIMIT_NOFILE                     = 0x8
-	RLIMIT_NPROC                      = 0x7
-	RLIMIT_RSS                        = 0x5
-	RLIMIT_STACK                      = 0x3
-	RLIM_INFINITY                     = 0x7fffffffffffffff
-	RTAX_AUTHOR                       = 0x6
-	RTAX_BRD                          = 0x7
-	RTAX_DST                          = 0x0
-	RTAX_GATEWAY                      = 0x1
-	RTAX_GENMASK                      = 0x3
-	RTAX_IFA                          = 0x5
-	RTAX_IFP                          = 0x4
-	RTAX_MAX                          = 0x8
-	RTAX_NETMASK                      = 0x2
-	RTA_AUTHOR                        = 0x40
-	RTA_BRD                           = 0x80
-	RTA_DST                           = 0x1
-	RTA_GATEWAY                       = 0x2
-	RTA_GENMASK                       = 0x8
-	RTA_IFA                           = 0x20
-	RTA_IFP                           = 0x10
-	RTA_NETMASK                       = 0x4
-	RTF_BLACKHOLE                     = 0x1000
-	RTF_BROADCAST                     = 0x400000
-	RTF_CLONING                       = 0x100
-	RTF_CONDEMNED                     = 0x2000000
-	RTF_DELCLONE                      = 0x80
-	RTF_DONE                          = 0x40
-	RTF_DYNAMIC                       = 0x10
-	RTF_GATEWAY                       = 0x2
-	RTF_HOST                          = 0x4
-	RTF_IFREF                         = 0x4000000
-	RTF_IFSCOPE                       = 0x1000000
-	RTF_LLINFO                        = 0x400
-	RTF_LOCAL                         = 0x200000
-	RTF_MODIFIED                      = 0x20
-	RTF_MULTICAST                     = 0x800000
-	RTF_NOIFREF                       = 0x2000
-	RTF_PINNED                        = 0x100000
-	RTF_PRCLONING                     = 0x10000
-	RTF_PROTO1                        = 0x8000
-	RTF_PROTO2                        = 0x4000
-	RTF_PROTO3                        = 0x40000
-	RTF_PROXY                         = 0x8000000
-	RTF_REJECT                        = 0x8
-	RTF_ROUTER                        = 0x10000000
-	RTF_STATIC                        = 0x800
-	RTF_UP                            = 0x1
-	RTF_WASCLONED                     = 0x20000
-	RTF_XRESOLVE                      = 0x200
-	RTM_ADD                           = 0x1
-	RTM_CHANGE                        = 0x3
-	RTM_DELADDR                       = 0xd
-	RTM_DELETE                        = 0x2
-	RTM_DELMADDR                      = 0x10
-	RTM_GET                           = 0x4
-	RTM_GET2                          = 0x14
-	RTM_IFINFO                        = 0xe
-	RTM_IFINFO2                       = 0x12
-	RTM_LOCK                          = 0x8
-	RTM_LOSING                        = 0x5
-	RTM_MISS                          = 0x7
-	RTM_NEWADDR                       = 0xc
-	RTM_NEWMADDR                      = 0xf
-	RTM_NEWMADDR2                     = 0x13
-	RTM_OLDADD                        = 0x9
-	RTM_OLDDEL                        = 0xa
-	RTM_REDIRECT                      = 0x6
-	RTM_RESOLVE                       = 0xb
-	RTM_RTTUNIT                       = 0xf4240
-	RTM_VERSION                       = 0x5
-	RTV_EXPIRE                        = 0x4
-	RTV_HOPCOUNT                      = 0x2
-	RTV_MTU                           = 0x1
-	RTV_RPIPE                         = 0x8
-	RTV_RTT                           = 0x40
-	RTV_RTTVAR                        = 0x80
-	RTV_SPIPE                         = 0x10
-	RTV_SSTHRESH                      = 0x20
-	RUSAGE_CHILDREN                   = -0x1
-	RUSAGE_SELF                       = 0x0
-	SCM_CREDS                         = 0x3
-	SCM_RIGHTS                        = 0x1
-	SCM_TIMESTAMP                     = 0x2
-	SCM_TIMESTAMP_MONOTONIC           = 0x4
-	SHUT_RD                           = 0x0
-	SHUT_RDWR                         = 0x2
-	SHUT_WR                           = 0x1
-	SIOCADDMULTI                      = 0x80206931
-	SIOCAIFADDR                       = 0x8040691a
-	SIOCARPIPLL                       = 0xc0206928
-	SIOCATMARK                        = 0x40047307
-	SIOCAUTOADDR                      = 0xc0206926
-	SIOCAUTONETMASK                   = 0x80206927
-	SIOCDELMULTI                      = 0x80206932
-	SIOCDIFADDR                       = 0x80206919
-	SIOCDIFPHYADDR                    = 0x80206941
-	SIOCGDRVSPEC                      = 0xc028697b
-	SIOCGETVLAN                       = 0xc020697f
-	SIOCGHIWAT                        = 0x40047301
-	SIOCGIFADDR                       = 0xc0206921
-	SIOCGIFALTMTU                     = 0xc0206948
-	SIOCGIFASYNCMAP                   = 0xc020697c
-	SIOCGIFBOND                       = 0xc0206947
-	SIOCGIFBRDADDR                    = 0xc0206923
-	SIOCGIFCAP                        = 0xc020695b
-	SIOCGIFCONF                       = 0xc00c6924
-	SIOCGIFDEVMTU                     = 0xc0206944
-	SIOCGIFDSTADDR                    = 0xc0206922
-	SIOCGIFFLAGS                      = 0xc0206911
-	SIOCGIFGENERIC                    = 0xc020693a
-	SIOCGIFKPI                        = 0xc0206987
-	SIOCGIFMAC                        = 0xc0206982
-	SIOCGIFMEDIA                      = 0xc02c6938
-	SIOCGIFMETRIC                     = 0xc0206917
-	SIOCGIFMTU                        = 0xc0206933
-	SIOCGIFNETMASK                    = 0xc0206925
-	SIOCGIFPDSTADDR                   = 0xc0206940
-	SIOCGIFPHYS                       = 0xc0206935
-	SIOCGIFPSRCADDR                   = 0xc020693f
-	SIOCGIFSTATUS                     = 0xc331693d
-	SIOCGIFVLAN                       = 0xc020697f
-	SIOCGIFWAKEFLAGS                  = 0xc0206988
-	SIOCGLOWAT                        = 0x40047303
-	SIOCGPGRP                         = 0x40047309
-	SIOCIFCREATE                      = 0xc0206978
-	SIOCIFCREATE2                     = 0xc020697a
-	SIOCIFDESTROY                     = 0x80206979
-	SIOCIFGCLONERS                    = 0xc0106981
-	SIOCRSLVMULTI                     = 0xc010693b
-	SIOCSDRVSPEC                      = 0x8028697b
-	SIOCSETVLAN                       = 0x8020697e
-	SIOCSHIWAT                        = 0x80047300
-	SIOCSIFADDR                       = 0x8020690c
-	SIOCSIFALTMTU                     = 0x80206945
-	SIOCSIFASYNCMAP                   = 0x8020697d
-	SIOCSIFBOND                       = 0x80206946
-	SIOCSIFBRDADDR                    = 0x80206913
-	SIOCSIFCAP                        = 0x8020695a
-	SIOCSIFDSTADDR                    = 0x8020690e
-	SIOCSIFFLAGS                      = 0x80206910
-	SIOCSIFGENERIC                    = 0x80206939
-	SIOCSIFKPI                        = 0x80206986
-	SIOCSIFLLADDR                     = 0x8020693c
-	SIOCSIFMAC                        = 0x80206983
-	SIOCSIFMEDIA                      = 0xc0206937
-	SIOCSIFMETRIC                     = 0x80206918
-	SIOCSIFMTU                        = 0x80206934
-	SIOCSIFNETMASK                    = 0x80206916
-	SIOCSIFPHYADDR                    = 0x8040693e
-	SIOCSIFPHYS                       = 0x80206936
-	SIOCSIFVLAN                       = 0x8020697e
-	SIOCSLOWAT                        = 0x80047302
-	SIOCSPGRP                         = 0x80047308
-	SOCK_DGRAM                        = 0x2
-	SOCK_MAXADDRLEN                   = 0xff
-	SOCK_RAW                          = 0x3
-	SOCK_RDM                          = 0x4
-	SOCK_SEQPACKET                    = 0x5
-	SOCK_STREAM                       = 0x1
-	SOL_SOCKET                        = 0xffff
-	SOMAXCONN                         = 0x80
-	SO_ACCEPTCONN                     = 0x2
-	SO_BROADCAST                      = 0x20
-	SO_DEBUG                          = 0x1
-	SO_DONTROUTE                      = 0x10
-	SO_DONTTRUNC                      = 0x2000
-	SO_ERROR                          = 0x1007
-	SO_KEEPALIVE                      = 0x8
-	SO_LABEL                          = 0x1010
-	SO_LINGER                         = 0x80
-	SO_LINGER_SEC                     = 0x1080
-	SO_NETSVC_MARKING_LEVEL           = 0x1119
-	SO_NET_SERVICE_TYPE               = 0x1116
-	SO_NKE                            = 0x1021
-	SO_NOADDRERR                      = 0x1023
-	SO_NOSIGPIPE                      = 0x1022
-	SO_NOTIFYCONFLICT                 = 0x1026
-	SO_NP_EXTENSIONS                  = 0x1083
-	SO_NREAD                          = 0x1020
-	SO_NUMRCVPKT                      = 0x1112
-	SO_NWRITE                         = 0x1024
-	SO_OOBINLINE                      = 0x100
-	SO_PEERLABEL                      = 0x1011
-	SO_RANDOMPORT                     = 0x1082
-	SO_RCVBUF                         = 0x1002
-	SO_RCVLOWAT                       = 0x1004
-	SO_RCVTIMEO                       = 0x1006
-	SO_REUSEADDR                      = 0x4
-	SO_REUSEPORT                      = 0x200
-	SO_REUSESHAREUID                  = 0x1025
-	SO_SNDBUF                         = 0x1001
-	SO_SNDLOWAT                       = 0x1003
-	SO_SNDTIMEO                       = 0x1005
-	SO_TIMESTAMP                      = 0x400
-	SO_TIMESTAMP_MONOTONIC            = 0x800
-	SO_TYPE                           = 0x1008
-	SO_UPCALLCLOSEWAIT                = 0x1027
-	SO_USELOOPBACK                    = 0x40
-	SO_WANTMORE                       = 0x4000
-	SO_WANTOOBFLAG                    = 0x8000
-	S_IEXEC                           = 0x40
-	S_IFBLK                           = 0x6000
-	S_IFCHR                           = 0x2000
-	S_IFDIR                           = 0x4000
-	S_IFIFO                           = 0x1000
-	S_IFLNK                           = 0xa000
-	S_IFMT                            = 0xf000
-	S_IFREG                           = 0x8000
-	S_IFSOCK                          = 0xc000
-	S_IFWHT                           = 0xe000
-	S_IREAD                           = 0x100
-	S_IRGRP                           = 0x20
-	S_IROTH                           = 0x4
-	S_IRUSR                           = 0x100
-	S_IRWXG                           = 0x38
-	S_IRWXO                           = 0x7
-	S_IRWXU                           = 0x1c0
-	S_ISGID                           = 0x400
-	S_ISTXT                           = 0x200
-	S_ISUID                           = 0x800
-	S_ISVTX                           = 0x200
-	S_IWGRP                           = 0x10
-	S_IWOTH                           = 0x2
-	S_IWRITE                          = 0x80
-	S_IWUSR                           = 0x80
-	S_IXGRP                           = 0x8
-	S_IXOTH                           = 0x1
-	S_IXUSR                           = 0x40
-	TAB0                              = 0x0
-	TAB1                              = 0x400
-	TAB2                              = 0x800
-	TAB3                              = 0x4
-	TABDLY                            = 0xc04
-	TCIFLUSH                          = 0x1
-	TCIOFF                            = 0x3
-	TCIOFLUSH                         = 0x3
-	TCION                             = 0x4
-	TCOFLUSH                          = 0x2
-	TCOOFF                            = 0x1
-	TCOON                             = 0x2
-	TCP_CONNECTIONTIMEOUT             = 0x20
-	TCP_CONNECTION_INFO               = 0x106
-	TCP_ENABLE_ECN                    = 0x104
-	TCP_FASTOPEN                      = 0x105
-	TCP_KEEPALIVE                     = 0x10
-	TCP_KEEPCNT                       = 0x102
-	TCP_KEEPINTVL                     = 0x101
-	TCP_MAXHLEN                       = 0x3c
-	TCP_MAXOLEN                       = 0x28
-	TCP_MAXSEG                        = 0x2
-	TCP_MAXWIN                        = 0xffff
-	TCP_MAX_SACK                      = 0x4
-	TCP_MAX_WINSHIFT                  = 0xe
-	TCP_MINMSS                        = 0xd8
-	TCP_MSS                           = 0x200
-	TCP_NODELAY                       = 0x1
-	TCP_NOOPT                         = 0x8
-	TCP_NOPUSH                        = 0x4
-	TCP_NOTSENT_LOWAT                 = 0x201
-	TCP_RXT_CONNDROPTIME              = 0x80
-	TCP_RXT_FINDROP                   = 0x100
-	TCP_SENDMOREACKS                  = 0x103
-	TCSAFLUSH                         = 0x2
-	TIOCCBRK                          = 0x2000747a
-	TIOCCDTR                          = 0x20007478
-	TIOCCONS                          = 0x80047462
-	TIOCDCDTIMESTAMP                  = 0x40107458
-	TIOCDRAIN                         = 0x2000745e
-	TIOCDSIMICROCODE                  = 0x20007455
-	TIOCEXCL                          = 0x2000740d
-	TIOCEXT                           = 0x80047460
-	TIOCFLUSH                         = 0x80047410
-	TIOCGDRAINWAIT                    = 0x40047456
-	TIOCGETA                          = 0x40487413
-	TIOCGETD                          = 0x4004741a
-	TIOCGPGRP                         = 0x40047477
-	TIOCGWINSZ                        = 0x40087468
-	TIOCIXOFF                         = 0x20007480
-	TIOCIXON                          = 0x20007481
-	TIOCMBIC                          = 0x8004746b
-	TIOCMBIS                          = 0x8004746c
-	TIOCMGDTRWAIT                     = 0x4004745a
-	TIOCMGET                          = 0x4004746a
-	TIOCMODG                          = 0x40047403
-	TIOCMODS                          = 0x80047404
-	TIOCMSDTRWAIT                     = 0x8004745b
-	TIOCMSET                          = 0x8004746d
-	TIOCM_CAR                         = 0x40
-	TIOCM_CD                          = 0x40
-	TIOCM_CTS                         = 0x20
-	TIOCM_DSR                         = 0x100
-	TIOCM_DTR                         = 0x2
-	TIOCM_LE                          = 0x1
-	TIOCM_RI                          = 0x80
-	TIOCM_RNG                         = 0x80
-	TIOCM_RTS                         = 0x4
-	TIOCM_SR                          = 0x10
-	TIOCM_ST                          = 0x8
-	TIOCNOTTY                         = 0x20007471
-	TIOCNXCL                          = 0x2000740e
-	TIOCOUTQ                          = 0x40047473
-	TIOCPKT                           = 0x80047470
-	TIOCPKT_DATA                      = 0x0
-	TIOCPKT_DOSTOP                    = 0x20
-	TIOCPKT_FLUSHREAD                 = 0x1
-	TIOCPKT_FLUSHWRITE                = 0x2
-	TIOCPKT_IOCTL                     = 0x40
-	TIOCPKT_NOSTOP                    = 0x10
-	TIOCPKT_START                     = 0x8
-	TIOCPKT_STOP                      = 0x4
-	TIOCPTYGNAME                      = 0x40807453
-	TIOCPTYGRANT                      = 0x20007454
-	TIOCPTYUNLK                       = 0x20007452
-	TIOCREMOTE                        = 0x80047469
-	TIOCSBRK                          = 0x2000747b
-	TIOCSCONS                         = 0x20007463
-	TIOCSCTTY                         = 0x20007461
-	TIOCSDRAINWAIT                    = 0x80047457
-	TIOCSDTR                          = 0x20007479
-	TIOCSETA                          = 0x80487414
-	TIOCSETAF                         = 0x80487416
-	TIOCSETAW                         = 0x80487415
-	TIOCSETD                          = 0x8004741b
-	TIOCSIG                           = 0x2000745f
-	TIOCSPGRP                         = 0x80047476
-	TIOCSTART                         = 0x2000746e
-	TIOCSTAT                          = 0x20007465
-	TIOCSTI                           = 0x80017472
-	TIOCSTOP                          = 0x2000746f
-	TIOCSWINSZ                        = 0x80087467
-	TIOCTIMESTAMP                     = 0x40107459
-	TIOCUCNTL                         = 0x80047466
-	TOSTOP                            = 0x400000
-	VDISCARD                          = 0xf
-	VDSUSP                            = 0xb
-	VEOF                              = 0x0
-	VEOL                              = 0x1
-	VEOL2                             = 0x2
-	VERASE                            = 0x3
-	VINTR                             = 0x8
-	VKILL                             = 0x5
-	VLNEXT                            = 0xe
-	VMIN                              = 0x10
-	VM_LOADAVG                        = 0x2
-	VM_MACHFACTOR                     = 0x4
-	VM_MAXID                          = 0x6
-	VM_METER                          = 0x1
-	VM_SWAPUSAGE                      = 0x5
-	VQUIT                             = 0x9
-	VREPRINT                          = 0x6
-	VSTART                            = 0xc
-	VSTATUS                           = 0x12
-	VSTOP                             = 0xd
-	VSUSP                             = 0xa
-	VT0                               = 0x0
-	VT1                               = 0x10000
-	VTDLY                             = 0x10000
-	VTIME                             = 0x11
-	VWERASE                           = 0x4
-	WCONTINUED                        = 0x10
-	WCOREFLAG                         = 0x80
-	WEXITED                           = 0x4
-	WNOHANG                           = 0x1
-	WNOWAIT                           = 0x20
-	WORDSIZE                          = 0x40
-	WSTOPPED                          = 0x8
-	WUNTRACED                         = 0x2
-	XATTR_CREATE                      = 0x2
-	XATTR_NODEFAULT                   = 0x10
-	XATTR_NOFOLLOW                    = 0x1
-	XATTR_NOSECURITY                  = 0x8
-	XATTR_REPLACE                     = 0x4
-	XATTR_SHOWCOMPRESSION             = 0x20
-)
-
-// Errors
-const (
-	E2BIG           = syscall.Errno(0x7)
-	EACCES          = syscall.Errno(0xd)
-	EADDRINUSE      = syscall.Errno(0x30)
-	EADDRNOTAVAIL   = syscall.Errno(0x31)
-	EAFNOSUPPORT    = syscall.Errno(0x2f)
-	EAGAIN          = syscall.Errno(0x23)
-	EALREADY        = syscall.Errno(0x25)
-	EAUTH           = syscall.Errno(0x50)
-	EBADARCH        = syscall.Errno(0x56)
-	EBADEXEC        = syscall.Errno(0x55)
-	EBADF           = syscall.Errno(0x9)
-	EBADMACHO       = syscall.Errno(0x58)
-	EBADMSG         = syscall.Errno(0x5e)
-	EBADRPC         = syscall.Errno(0x48)
-	EBUSY           = syscall.Errno(0x10)
-	ECANCELED       = syscall.Errno(0x59)
-	ECHILD          = syscall.Errno(0xa)
-	ECONNABORTED    = syscall.Errno(0x35)
-	ECONNREFUSED    = syscall.Errno(0x3d)
-	ECONNRESET      = syscall.Errno(0x36)
-	EDEADLK         = syscall.Errno(0xb)
-	EDESTADDRREQ    = syscall.Errno(0x27)
-	EDEVERR         = syscall.Errno(0x53)
-	EDOM            = syscall.Errno(0x21)
-	EDQUOT          = syscall.Errno(0x45)
-	EEXIST          = syscall.Errno(0x11)
-	EFAULT          = syscall.Errno(0xe)
-	EFBIG           = syscall.Errno(0x1b)
-	EFTYPE          = syscall.Errno(0x4f)
-	EHOSTDOWN       = syscall.Errno(0x40)
-	EHOSTUNREACH    = syscall.Errno(0x41)
-	EIDRM           = syscall.Errno(0x5a)
-	EILSEQ          = syscall.Errno(0x5c)
-	EINPROGRESS     = syscall.Errno(0x24)
-	EINTR           = syscall.Errno(0x4)
-	EINVAL          = syscall.Errno(0x16)
-	EIO             = syscall.Errno(0x5)
-	EISCONN         = syscall.Errno(0x38)
-	EISDIR          = syscall.Errno(0x15)
-	ELAST           = syscall.Errno(0x6a)
-	ELOOP           = syscall.Errno(0x3e)
-	EMFILE          = syscall.Errno(0x18)
-	EMLINK          = syscall.Errno(0x1f)
-	EMSGSIZE        = syscall.Errno(0x28)
-	EMULTIHOP       = syscall.Errno(0x5f)
-	ENAMETOOLONG    = syscall.Errno(0x3f)
-	ENEEDAUTH       = syscall.Errno(0x51)
-	ENETDOWN        = syscall.Errno(0x32)
-	ENETRESET       = syscall.Errno(0x34)
-	ENETUNREACH     = syscall.Errno(0x33)
-	ENFILE          = syscall.Errno(0x17)
-	ENOATTR         = syscall.Errno(0x5d)
-	ENOBUFS         = syscall.Errno(0x37)
-	ENODATA         = syscall.Errno(0x60)
-	ENODEV          = syscall.Errno(0x13)
-	ENOENT          = syscall.Errno(0x2)
-	ENOEXEC         = syscall.Errno(0x8)
-	ENOLCK          = syscall.Errno(0x4d)
-	ENOLINK         = syscall.Errno(0x61)
-	ENOMEM          = syscall.Errno(0xc)
-	ENOMSG          = syscall.Errno(0x5b)
-	ENOPOLICY       = syscall.Errno(0x67)
-	ENOPROTOOPT     = syscall.Errno(0x2a)
-	ENOSPC          = syscall.Errno(0x1c)
-	ENOSR           = syscall.Errno(0x62)
-	ENOSTR          = syscall.Errno(0x63)
-	ENOSYS          = syscall.Errno(0x4e)
-	ENOTBLK         = syscall.Errno(0xf)
-	ENOTCONN        = syscall.Errno(0x39)
-	ENOTDIR         = syscall.Errno(0x14)
-	ENOTEMPTY       = syscall.Errno(0x42)
-	ENOTRECOVERABLE = syscall.Errno(0x68)
-	ENOTSOCK        = syscall.Errno(0x26)
-	ENOTSUP         = syscall.Errno(0x2d)
-	ENOTTY          = syscall.Errno(0x19)
-	ENXIO           = syscall.Errno(0x6)
-	EOPNOTSUPP      = syscall.Errno(0x66)
-	EOVERFLOW       = syscall.Errno(0x54)
-	EOWNERDEAD      = syscall.Errno(0x69)
-	EPERM           = syscall.Errno(0x1)
-	EPFNOSUPPORT    = syscall.Errno(0x2e)
-	EPIPE           = syscall.Errno(0x20)
-	EPROCLIM        = syscall.Errno(0x43)
-	EPROCUNAVAIL    = syscall.Errno(0x4c)
-	EPROGMISMATCH   = syscall.Errno(0x4b)
-	EPROGUNAVAIL    = syscall.Errno(0x4a)
-	EPROTO          = syscall.Errno(0x64)
-	EPROTONOSUPPORT = syscall.Errno(0x2b)
-	EPROTOTYPE      = syscall.Errno(0x29)
-	EPWROFF         = syscall.Errno(0x52)
-	EQFULL          = syscall.Errno(0x6a)
-	ERANGE          = syscall.Errno(0x22)
-	EREMOTE         = syscall.Errno(0x47)
-	EROFS           = syscall.Errno(0x1e)
-	ERPCMISMATCH    = syscall.Errno(0x49)
-	ESHLIBVERS      = syscall.Errno(0x57)
-	ESHUTDOWN       = syscall.Errno(0x3a)
-	ESOCKTNOSUPPORT = syscall.Errno(0x2c)
-	ESPIPE          = syscall.Errno(0x1d)
-	ESRCH           = syscall.Errno(0x3)
-	ESTALE          = syscall.Errno(0x46)
-	ETIME           = syscall.Errno(0x65)
-	ETIMEDOUT       = syscall.Errno(0x3c)
-	ETOOMANYREFS    = syscall.Errno(0x3b)
-	ETXTBSY         = syscall.Errno(0x1a)
-	EUSERS          = syscall.Errno(0x44)
-	EWOULDBLOCK     = syscall.Errno(0x23)
-	EXDEV           = syscall.Errno(0x12)
-)
-
-// Signals
-const (
-	SIGABRT   = syscall.Signal(0x6)
-	SIGALRM   = syscall.Signal(0xe)
-	SIGBUS    = syscall.Signal(0xa)
-	SIGCHLD   = syscall.Signal(0x14)
-	SIGCONT   = syscall.Signal(0x13)
-	SIGEMT    = syscall.Signal(0x7)
-	SIGFPE    = syscall.Signal(0x8)
-	SIGHUP    = syscall.Signal(0x1)
-	SIGILL    = syscall.Signal(0x4)
-	SIGINFO   = syscall.Signal(0x1d)
-	SIGINT    = syscall.Signal(0x2)
-	SIGIO     = syscall.Signal(0x17)
-	SIGIOT    = syscall.Signal(0x6)
-	SIGKILL   = syscall.Signal(0x9)
-	SIGPIPE   = syscall.Signal(0xd)
-	SIGPROF   = syscall.Signal(0x1b)
-	SIGQUIT   = syscall.Signal(0x3)
-	SIGSEGV   = syscall.Signal(0xb)
-	SIGSTOP   = syscall.Signal(0x11)
-	SIGSYS    = syscall.Signal(0xc)
-	SIGTERM   = syscall.Signal(0xf)
-	SIGTRAP   = syscall.Signal(0x5)
-	SIGTSTP   = syscall.Signal(0x12)
-	SIGTTIN   = syscall.Signal(0x15)
-	SIGTTOU   = syscall.Signal(0x16)
-	SIGURG    = syscall.Signal(0x10)
-	SIGUSR1   = syscall.Signal(0x1e)
-	SIGUSR2   = syscall.Signal(0x1f)
-	SIGVTALRM = syscall.Signal(0x1a)
-	SIGWINCH  = syscall.Signal(0x1c)
-	SIGXCPU   = syscall.Signal(0x18)
-	SIGXFSZ   = syscall.Signal(0x19)
-)
-
-// Error table
-var errorList = [...]struct {
-	num  syscall.Errno
-	name string
-	desc string
-}{
-	{1, "EPERM", "operation not permitted"},
-	{2, "ENOENT", "no such file or directory"},
-	{3, "ESRCH", "no such process"},
-	{4, "EINTR", "interrupted system call"},
-	{5, "EIO", "input/output error"},
-	{6, "ENXIO", "device not configured"},
-	{7, "E2BIG", "argument list too long"},
-	{8, "ENOEXEC", "exec format error"},
-	{9, "EBADF", "bad file descriptor"},
-	{10, "ECHILD", "no child processes"},
-	{11, "EDEADLK", "resource deadlock avoided"},
-	{12, "ENOMEM", "cannot allocate memory"},
-	{13, "EACCES", "permission denied"},
-	{14, "EFAULT", "bad address"},
-	{15, "ENOTBLK", "block device required"},
-	{16, "EBUSY", "resource busy"},
-	{17, "EEXIST", "file exists"},
-	{18, "EXDEV", "cross-device link"},
-	{19, "ENODEV", "operation not supported by device"},
-	{20, "ENOTDIR", "not a directory"},
-	{21, "EISDIR", "is a directory"},
-	{22, "EINVAL", "invalid argument"},
-	{23, "ENFILE", "too many open files in system"},
-	{24, "EMFILE", "too many open files"},
-	{25, "ENOTTY", "inappropriate ioctl for device"},
-	{26, "ETXTBSY", "text file busy"},
-	{27, "EFBIG", "file too large"},
-	{28, "ENOSPC", "no space left on device"},
-	{29, "ESPIPE", "illegal seek"},
-	{30, "EROFS", "read-only file system"},
-	{31, "EMLINK", "too many links"},
-	{32, "EPIPE", "broken pipe"},
-	{33, "EDOM", "numerical argument out of domain"},
-	{34, "ERANGE", "result too large"},
-	{35, "EAGAIN", "resource temporarily unavailable"},
-	{36, "EINPROGRESS", "operation now in progress"},
-	{37, "EALREADY", "operation already in progress"},
-	{38, "ENOTSOCK", "socket operation on non-socket"},
-	{39, "EDESTADDRREQ", "destination address required"},
-	{40, "EMSGSIZE", "message too long"},
-	{41, "EPROTOTYPE", "protocol wrong type for socket"},
-	{42, "ENOPROTOOPT", "protocol not available"},
-	{43, "EPROTONOSUPPORT", "protocol not supported"},
-	{44, "ESOCKTNOSUPPORT", "socket type not supported"},
-	{45, "ENOTSUP", "operation not supported"},
-	{46, "EPFNOSUPPORT", "protocol family not supported"},
-	{47, "EAFNOSUPPORT", "address family not supported by protocol family"},
-	{48, "EADDRINUSE", "address already in use"},
-	{49, "EADDRNOTAVAIL", "can't assign requested address"},
-	{50, "ENETDOWN", "network is down"},
-	{51, "ENETUNREACH", "network is unreachable"},
-	{52, "ENETRESET", "network dropped connection on reset"},
-	{53, "ECONNABORTED", "software caused connection abort"},
-	{54, "ECONNRESET", "connection reset by peer"},
-	{55, "ENOBUFS", "no buffer space available"},
-	{56, "EISCONN", "socket is already connected"},
-	{57, "ENOTCONN", "socket is not connected"},
-	{58, "ESHUTDOWN", "can't send after socket shutdown"},
-	{59, "ETOOMANYREFS", "too many references: can't splice"},
-	{60, "ETIMEDOUT", "operation timed out"},
-	{61, "ECONNREFUSED", "connection refused"},
-	{62, "ELOOP", "too many levels of symbolic links"},
-	{63, "ENAMETOOLONG", "file name too long"},
-	{64, "EHOSTDOWN", "host is down"},
-	{65, "EHOSTUNREACH", "no route to host"},
-	{66, "ENOTEMPTY", "directory not empty"},
-	{67, "EPROCLIM", "too many processes"},
-	{68, "EUSERS", "too many users"},
-	{69, "EDQUOT", "disc quota exceeded"},
-	{70, "ESTALE", "stale NFS file handle"},
-	{71, "EREMOTE", "too many levels of remote in path"},
-	{72, "EBADRPC", "RPC struct is bad"},
-	{73, "ERPCMISMATCH", "RPC version wrong"},
-	{74, "EPROGUNAVAIL", "RPC prog. not avail"},
-	{75, "EPROGMISMATCH", "program version wrong"},
-	{76, "EPROCUNAVAIL", "bad procedure for program"},
-	{77, "ENOLCK", "no locks available"},
-	{78, "ENOSYS", "function not implemented"},
-	{79, "EFTYPE", "inappropriate file type or format"},
-	{80, "EAUTH", "authentication error"},
-	{81, "ENEEDAUTH", "need authenticator"},
-	{82, "EPWROFF", "device power is off"},
-	{83, "EDEVERR", "device error"},
-	{84, "EOVERFLOW", "value too large to be stored in data type"},
-	{85, "EBADEXEC", "bad executable (or shared library)"},
-	{86, "EBADARCH", "bad CPU type in executable"},
-	{87, "ESHLIBVERS", "shared library version mismatch"},
-	{88, "EBADMACHO", "malformed Mach-o file"},
-	{89, "ECANCELED", "operation canceled"},
-	{90, "EIDRM", "identifier removed"},
-	{91, "ENOMSG", "no message of desired type"},
-	{92, "EILSEQ", "illegal byte sequence"},
-	{93, "ENOATTR", "attribute not found"},
-	{94, "EBADMSG", "bad message"},
-	{95, "EMULTIHOP", "EMULTIHOP (Reserved)"},
-	{96, "ENODATA", "no message available on STREAM"},
-	{97, "ENOLINK", "ENOLINK (Reserved)"},
-	{98, "ENOSR", "no STREAM resources"},
-	{99, "ENOSTR", "not a STREAM"},
-	{100, "EPROTO", "protocol error"},
-	{101, "ETIME", "STREAM ioctl timeout"},
-	{102, "EOPNOTSUPP", "operation not supported on socket"},
-	{103, "ENOPOLICY", "policy not found"},
-	{104, "ENOTRECOVERABLE", "state not recoverable"},
-	{105, "EOWNERDEAD", "previous owner died"},
-	{106, "EQFULL", "interface output queue is full"},
-}
-
-// Signal table
-var signalList = [...]struct {
-	num  syscall.Signal
-	name string
-	desc string
-}{
-	{1, "SIGHUP", "hangup"},
-	{2, "SIGINT", "interrupt"},
-	{3, "SIGQUIT", "quit"},
-	{4, "SIGILL", "illegal instruction"},
-	{5, "SIGTRAP", "trace/BPT trap"},
-	{6, "SIGABRT", "abort trap"},
-	{7, "SIGEMT", "EMT trap"},
-	{8, "SIGFPE", "floating point exception"},
-	{9, "SIGKILL", "killed"},
-	{10, "SIGBUS", "bus error"},
-	{11, "SIGSEGV", "segmentation fault"},
-	{12, "SIGSYS", "bad system call"},
-	{13, "SIGPIPE", "broken pipe"},
-	{14, "SIGALRM", "alarm clock"},
-	{15, "SIGTERM", "terminated"},
-	{16, "SIGURG", "urgent I/O condition"},
-	{17, "SIGSTOP", "suspended (signal)"},
-	{18, "SIGTSTP", "suspended"},
-	{19, "SIGCONT", "continued"},
-	{20, "SIGCHLD", "child exited"},
-	{21, "SIGTTIN", "stopped (tty input)"},
-	{22, "SIGTTOU", "stopped (tty output)"},
-	{23, "SIGIO", "I/O possible"},
-	{24, "SIGXCPU", "cputime limit exceeded"},
-	{25, "SIGXFSZ", "filesize limit exceeded"},
-	{26, "SIGVTALRM", "virtual timer expired"},
-	{27, "SIGPROF", "profiling timer expired"},
-	{28, "SIGWINCH", "window size changes"},
-	{29, "SIGINFO", "information request"},
-	{30, "SIGUSR1", "user defined signal 1"},
-	{31, "SIGUSR2", "user defined signal 2"},
-}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go
index b40fb1f..e644eaf 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && darwin
 // +build arm64,darwin
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
@@ -32,7 +33,7 @@
 	AF_LAT                            = 0xe
 	AF_LINK                           = 0x12
 	AF_LOCAL                          = 0x1
-	AF_MAX                            = 0x28
+	AF_MAX                            = 0x29
 	AF_NATM                           = 0x1f
 	AF_NDRV                           = 0x1b
 	AF_NETBIOS                        = 0x21
@@ -49,6 +50,7 @@
 	AF_UNIX                           = 0x1
 	AF_UNSPEC                         = 0x0
 	AF_UTUN                           = 0x26
+	AF_VSOCK                          = 0x28
 	ALTWERASE                         = 0x200
 	ATTR_BIT_MAP_COUNT                = 0x5
 	ATTR_CMN_ACCESSMASK               = 0x20000
@@ -83,7 +85,7 @@
 	ATTR_CMN_PAROBJID                 = 0x80
 	ATTR_CMN_RETURNED_ATTRS           = 0x80000000
 	ATTR_CMN_SCRIPT                   = 0x100
-	ATTR_CMN_SETMASK                  = 0x41c7ff00
+	ATTR_CMN_SETMASK                  = 0x51c7ff00
 	ATTR_CMN_USERACCESS               = 0x200000
 	ATTR_CMN_UUID                     = 0x800000
 	ATTR_CMN_VALIDMASK                = 0xffffffff
@@ -357,7 +359,7 @@
 	DLT_LINUX_SLL                     = 0x71
 	DLT_LOOP                          = 0x6c
 	DLT_LTALK                         = 0x72
-	DLT_MATCHING_MAX                  = 0xf5
+	DLT_MATCHING_MAX                  = 0x10a
 	DLT_MATCHING_MIN                  = 0x68
 	DLT_MFR                           = 0xb6
 	DLT_MOST                          = 0xd3
@@ -398,6 +400,7 @@
 	DLT_SYMANTEC_FIREWALL             = 0x63
 	DLT_TZSP                          = 0x80
 	DLT_USB                           = 0xba
+	DLT_USB_DARWIN                    = 0x10a
 	DLT_USB_LINUX                     = 0xbd
 	DLT_USB_LINUX_MMAPPED             = 0xdc
 	DLT_USER0                         = 0x93
@@ -442,8 +445,8 @@
 	EVFILT_PROC                       = -0x5
 	EVFILT_READ                       = -0x1
 	EVFILT_SIGNAL                     = -0x6
-	EVFILT_SYSCOUNT                   = 0xf
-	EVFILT_THREADMARKER               = 0xf
+	EVFILT_SYSCOUNT                   = 0x11
+	EVFILT_THREADMARKER               = 0x11
 	EVFILT_TIMER                      = -0x7
 	EVFILT_USER                       = -0xa
 	EVFILT_VM                         = -0xc
@@ -481,9 +484,12 @@
 	FSOPT_NOINMEMUPDATE               = 0x2
 	FSOPT_PACK_INVAL_ATTRS            = 0x8
 	FSOPT_REPORT_FULLSIZE             = 0x4
+	FSOPT_RETURN_REALDEV              = 0x200
 	F_ADDFILESIGS                     = 0x3d
 	F_ADDFILESIGS_FOR_DYLD_SIM        = 0x53
+	F_ADDFILESIGS_INFO                = 0x67
 	F_ADDFILESIGS_RETURN              = 0x61
+	F_ADDFILESUPPL                    = 0x68
 	F_ADDSIGS                         = 0x3b
 	F_ALLOCATEALL                     = 0x4
 	F_ALLOCATECONTIG                  = 0x2
@@ -505,8 +511,10 @@
 	F_GETOWN                          = 0x5
 	F_GETPATH                         = 0x32
 	F_GETPATH_MTMINFO                 = 0x47
+	F_GETPATH_NOFIRMLINK              = 0x66
 	F_GETPROTECTIONCLASS              = 0x3f
 	F_GETPROTECTIONLEVEL              = 0x4d
+	F_GETSIGSINFO                     = 0x69
 	F_GLOBAL_NOCACHE                  = 0x37
 	F_LOG2PHYS                        = 0x31
 	F_LOG2PHYS_EXT                    = 0x41
@@ -531,6 +539,7 @@
 	F_SETPROTECTIONCLASS              = 0x40
 	F_SETSIZE                         = 0x2b
 	F_SINGLE_WRITER                   = 0x4c
+	F_SPECULATIVE_READ                = 0x65
 	F_THAW_FS                         = 0x36
 	F_TRANSCODEKEY                    = 0x4b
 	F_TRIM_ACTIVE_FILE                = 0x64
@@ -562,6 +571,7 @@
 	IFF_UP                            = 0x1
 	IFNAMSIZ                          = 0x10
 	IFT_1822                          = 0x2
+	IFT_6LOWPAN                       = 0x40
 	IFT_AAL5                          = 0x31
 	IFT_ARCNET                        = 0x23
 	IFT_ARCNETPLUS                    = 0x24
@@ -766,16 +776,28 @@
 	IPV6_2292PKTINFO                  = 0x13
 	IPV6_2292PKTOPTIONS               = 0x19
 	IPV6_2292RTHDR                    = 0x18
+	IPV6_3542DSTOPTS                  = 0x32
+	IPV6_3542HOPLIMIT                 = 0x2f
+	IPV6_3542HOPOPTS                  = 0x31
+	IPV6_3542NEXTHOP                  = 0x30
+	IPV6_3542PKTINFO                  = 0x2e
+	IPV6_3542RTHDR                    = 0x33
+	IPV6_ADDR_MC_FLAGS_PREFIX         = 0x20
+	IPV6_ADDR_MC_FLAGS_TRANSIENT      = 0x10
+	IPV6_ADDR_MC_FLAGS_UNICAST_BASED  = 0x30
+	IPV6_AUTOFLOWLABEL                = 0x3b
 	IPV6_BINDV6ONLY                   = 0x1b
 	IPV6_BOUND_IF                     = 0x7d
 	IPV6_CHECKSUM                     = 0x1a
 	IPV6_DEFAULT_MULTICAST_HOPS       = 0x1
 	IPV6_DEFAULT_MULTICAST_LOOP       = 0x1
 	IPV6_DEFHLIM                      = 0x40
+	IPV6_DONTFRAG                     = 0x3e
+	IPV6_DSTOPTS                      = 0x32
 	IPV6_FAITH                        = 0x1d
 	IPV6_FLOWINFO_MASK                = 0xffffff0f
 	IPV6_FLOWLABEL_MASK               = 0xffff0f00
-	IPV6_FLOW_ECN_MASK                = 0x300
+	IPV6_FLOW_ECN_MASK                = 0x3000
 	IPV6_FRAGTTL                      = 0x3c
 	IPV6_FW_ADD                       = 0x1e
 	IPV6_FW_DEL                       = 0x1f
@@ -783,6 +805,8 @@
 	IPV6_FW_GET                       = 0x22
 	IPV6_FW_ZERO                      = 0x21
 	IPV6_HLIMDEC                      = 0x1
+	IPV6_HOPLIMIT                     = 0x2f
+	IPV6_HOPOPTS                      = 0x31
 	IPV6_IPSEC_POLICY                 = 0x1c
 	IPV6_JOIN_GROUP                   = 0xc
 	IPV6_LEAVE_GROUP                  = 0xd
@@ -794,20 +818,34 @@
 	IPV6_MAX_SOCK_SRC_FILTER          = 0x80
 	IPV6_MIN_MEMBERSHIPS              = 0x1f
 	IPV6_MMTU                         = 0x500
+	IPV6_MSFILTER                     = 0x4a
 	IPV6_MULTICAST_HOPS               = 0xa
 	IPV6_MULTICAST_IF                 = 0x9
 	IPV6_MULTICAST_LOOP               = 0xb
+	IPV6_NEXTHOP                      = 0x30
+	IPV6_PATHMTU                      = 0x2c
+	IPV6_PKTINFO                      = 0x2e
 	IPV6_PORTRANGE                    = 0xe
 	IPV6_PORTRANGE_DEFAULT            = 0x0
 	IPV6_PORTRANGE_HIGH               = 0x1
 	IPV6_PORTRANGE_LOW                = 0x2
+	IPV6_PREFER_TEMPADDR              = 0x3f
+	IPV6_RECVDSTOPTS                  = 0x28
+	IPV6_RECVHOPLIMIT                 = 0x25
+	IPV6_RECVHOPOPTS                  = 0x27
+	IPV6_RECVPATHMTU                  = 0x2b
+	IPV6_RECVPKTINFO                  = 0x3d
+	IPV6_RECVRTHDR                    = 0x26
 	IPV6_RECVTCLASS                   = 0x23
+	IPV6_RTHDR                        = 0x33
+	IPV6_RTHDRDSTOPTS                 = 0x39
 	IPV6_RTHDR_LOOSE                  = 0x0
 	IPV6_RTHDR_STRICT                 = 0x1
 	IPV6_RTHDR_TYPE_0                 = 0x0
 	IPV6_SOCKOPT_RESERVED1            = 0x3
 	IPV6_TCLASS                       = 0x24
 	IPV6_UNICAST_HOPS                 = 0x4
+	IPV6_USE_MIN_MTU                  = 0x2a
 	IPV6_V6ONLY                       = 0x1b
 	IPV6_VERSION                      = 0x60
 	IPV6_VERSION_MASK                 = 0xf0
@@ -818,6 +856,7 @@
 	IP_DEFAULT_MULTICAST_LOOP         = 0x1
 	IP_DEFAULT_MULTICAST_TTL          = 0x1
 	IP_DF                             = 0x4000
+	IP_DONTFRAG                       = 0x1c
 	IP_DROP_MEMBERSHIP                = 0xd
 	IP_DROP_SOURCE_MEMBERSHIP         = 0x47
 	IP_DUMMYNET_CONFIGURE             = 0x3c
@@ -889,6 +928,12 @@
 	KERN_OSRELEASE                    = 0x2
 	KERN_OSTYPE                       = 0x1
 	KERN_VERSION                      = 0x4
+	LOCAL_PEERCRED                    = 0x1
+	LOCAL_PEEREPID                    = 0x3
+	LOCAL_PEEREUUID                   = 0x5
+	LOCAL_PEERPID                     = 0x2
+	LOCAL_PEERTOKEN                   = 0x6
+	LOCAL_PEERUUID                    = 0x4
 	LOCK_EX                           = 0x2
 	LOCK_NB                           = 0x4
 	LOCK_SH                           = 0x1
@@ -904,6 +949,7 @@
 	MADV_SEQUENTIAL                   = 0x2
 	MADV_WILLNEED                     = 0x3
 	MADV_ZERO_WIRED_PAGES             = 0x6
+	MAP_32BIT                         = 0x8000
 	MAP_ANON                          = 0x1000
 	MAP_ANONYMOUS                     = 0x1000
 	MAP_COPY                          = 0x2
@@ -920,6 +966,17 @@
 	MAP_RESILIENT_CODESIGN            = 0x2000
 	MAP_RESILIENT_MEDIA               = 0x4000
 	MAP_SHARED                        = 0x1
+	MAP_TRANSLATED_ALLOW_EXECUTE      = 0x20000
+	MAP_UNIX03                        = 0x40000
+	MCAST_BLOCK_SOURCE                = 0x54
+	MCAST_EXCLUDE                     = 0x2
+	MCAST_INCLUDE                     = 0x1
+	MCAST_JOIN_GROUP                  = 0x50
+	MCAST_JOIN_SOURCE_GROUP           = 0x52
+	MCAST_LEAVE_GROUP                 = 0x51
+	MCAST_LEAVE_SOURCE_GROUP          = 0x53
+	MCAST_UNBLOCK_SOURCE              = 0x55
+	MCAST_UNDEFINED                   = 0x0
 	MCL_CURRENT                       = 0x1
 	MCL_FUTURE                        = 0x2
 	MNT_ASYNC                         = 0x40
@@ -931,6 +988,7 @@
 	MNT_DOVOLFS                       = 0x8000
 	MNT_DWAIT                         = 0x4
 	MNT_EXPORTED                      = 0x100
+	MNT_EXT_ROOT_DATA_VOL             = 0x1
 	MNT_FORCE                         = 0x80000
 	MNT_IGNORE_OWNERSHIP              = 0x200000
 	MNT_JOURNALED                     = 0x800000
@@ -947,12 +1005,15 @@
 	MNT_QUOTA                         = 0x2000
 	MNT_RDONLY                        = 0x1
 	MNT_RELOAD                        = 0x40000
+	MNT_REMOVABLE                     = 0x200
 	MNT_ROOTFS                        = 0x4000
+	MNT_SNAPSHOT                      = 0x40000000
+	MNT_STRICTATIME                   = 0x80000000
 	MNT_SYNCHRONOUS                   = 0x2
 	MNT_UNION                         = 0x20
 	MNT_UNKNOWNPERMISSIONS            = 0x200000
 	MNT_UPDATE                        = 0x10000
-	MNT_VISFLAGMASK                   = 0x17f0f5ff
+	MNT_VISFLAGMASK                   = 0xd7f0f7ff
 	MNT_WAIT                          = 0x1
 	MSG_CTRUNC                        = 0x20
 	MSG_DONTROUTE                     = 0x4
@@ -963,6 +1024,7 @@
 	MSG_HAVEMORE                      = 0x2000
 	MSG_HOLD                          = 0x800
 	MSG_NEEDSA                        = 0x10000
+	MSG_NOSIGNAL                      = 0x80000
 	MSG_OOB                           = 0x1
 	MSG_PEEK                          = 0x2
 	MSG_RCVMORE                       = 0x4000
@@ -979,9 +1041,10 @@
 	NET_RT_DUMP                       = 0x1
 	NET_RT_DUMP2                      = 0x7
 	NET_RT_FLAGS                      = 0x2
+	NET_RT_FLAGS_PRIV                 = 0xa
 	NET_RT_IFLIST                     = 0x3
 	NET_RT_IFLIST2                    = 0x6
-	NET_RT_MAXID                      = 0xa
+	NET_RT_MAXID                      = 0xb
 	NET_RT_STAT                       = 0x4
 	NET_RT_TRASH                      = 0x5
 	NFDBITS                           = 0x20
@@ -1019,6 +1082,7 @@
 	NOTE_LEEWAY                       = 0x10
 	NOTE_LINK                         = 0x10
 	NOTE_LOWAT                        = 0x1
+	NOTE_MACHTIME                     = 0x100
 	NOTE_MACH_CONTINUOUS_TIME         = 0x80
 	NOTE_NONE                         = 0x80
 	NOTE_NSECONDS                     = 0x4
@@ -1065,6 +1129,7 @@
 	O_NDELAY                          = 0x4
 	O_NOCTTY                          = 0x20000
 	O_NOFOLLOW                        = 0x100
+	O_NOFOLLOW_ANY                    = 0x20000000
 	O_NONBLOCK                        = 0x4
 	O_POPUP                           = 0x80000000
 	O_RDONLY                          = 0x0
@@ -1136,6 +1201,7 @@
 	RTF_BROADCAST                     = 0x400000
 	RTF_CLONING                       = 0x100
 	RTF_CONDEMNED                     = 0x2000000
+	RTF_DEAD                          = 0x20000000
 	RTF_DELCLONE                      = 0x80
 	RTF_DONE                          = 0x40
 	RTF_DYNAMIC                       = 0x10
@@ -1143,6 +1209,7 @@
 	RTF_HOST                          = 0x4
 	RTF_IFREF                         = 0x4000000
 	RTF_IFSCOPE                       = 0x1000000
+	RTF_LLDATA                        = 0x400
 	RTF_LLINFO                        = 0x400
 	RTF_LOCAL                         = 0x200000
 	RTF_MODIFIED                      = 0x20
@@ -1210,6 +1277,7 @@
 	SIOCGDRVSPEC                      = 0xc028697b
 	SIOCGETVLAN                       = 0xc020697f
 	SIOCGHIWAT                        = 0x40047301
+	SIOCGIF6LOWPAN                    = 0xc02069c5
 	SIOCGIFADDR                       = 0xc0206921
 	SIOCGIFALTMTU                     = 0xc0206948
 	SIOCGIFASYNCMAP                   = 0xc020697c
@@ -1220,6 +1288,7 @@
 	SIOCGIFDEVMTU                     = 0xc0206944
 	SIOCGIFDSTADDR                    = 0xc0206922
 	SIOCGIFFLAGS                      = 0xc0206911
+	SIOCGIFFUNCTIONALTYPE             = 0xc02069ad
 	SIOCGIFGENERIC                    = 0xc020693a
 	SIOCGIFKPI                        = 0xc0206987
 	SIOCGIFMAC                        = 0xc0206982
@@ -1233,6 +1302,7 @@
 	SIOCGIFSTATUS                     = 0xc331693d
 	SIOCGIFVLAN                       = 0xc020697f
 	SIOCGIFWAKEFLAGS                  = 0xc0206988
+	SIOCGIFXMEDIA                     = 0xc02c6948
 	SIOCGLOWAT                        = 0x40047303
 	SIOCGPGRP                         = 0x40047309
 	SIOCIFCREATE                      = 0xc0206978
@@ -1243,6 +1313,7 @@
 	SIOCSDRVSPEC                      = 0x8028697b
 	SIOCSETVLAN                       = 0x8020697e
 	SIOCSHIWAT                        = 0x80047300
+	SIOCSIF6LOWPAN                    = 0x802069c4
 	SIOCSIFADDR                       = 0x8020690c
 	SIOCSIFALTMTU                     = 0x80206945
 	SIOCSIFASYNCMAP                   = 0x8020697d
@@ -1270,6 +1341,7 @@
 	SOCK_RDM                          = 0x4
 	SOCK_SEQPACKET                    = 0x5
 	SOCK_STREAM                       = 0x1
+	SOL_LOCAL                         = 0x0
 	SOL_SOCKET                        = 0xffff
 	SOMAXCONN                         = 0x80
 	SO_ACCEPTCONN                     = 0x2
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go
index f5e91b7..17bba0e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && dragonfly
 // +build amd64,dragonfly
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
index 3689c80..9c7c5e1 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m32
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build 386 && freebsd
 // +build 386,freebsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
@@ -997,6 +998,11 @@
 	KERN_OSRELEASE                 = 0x2
 	KERN_OSTYPE                    = 0x1
 	KERN_VERSION                   = 0x4
+	LOCAL_CONNWAIT                 = 0x4
+	LOCAL_CREDS                    = 0x2
+	LOCAL_CREDS_PERSISTENT         = 0x3
+	LOCAL_PEERCRED                 = 0x1
+	LOCAL_VENDOR                   = 0x80000000
 	LOCK_EX                        = 0x2
 	LOCK_NB                        = 0x4
 	LOCK_SH                        = 0x1
@@ -1375,6 +1381,7 @@
 	SOCK_RDM                       = 0x4
 	SOCK_SEQPACKET                 = 0x5
 	SOCK_STREAM                    = 0x1
+	SOL_LOCAL                      = 0x0
 	SOL_SOCKET                     = 0xffff
 	SOMAXCONN                      = 0x80
 	SO_ACCEPTCONN                  = 0x2
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
index b8f7c3c..b265abb 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && freebsd
 // +build amd64,freebsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
@@ -997,6 +998,11 @@
 	KERN_OSRELEASE                 = 0x2
 	KERN_OSTYPE                    = 0x1
 	KERN_VERSION                   = 0x4
+	LOCAL_CONNWAIT                 = 0x4
+	LOCAL_CREDS                    = 0x2
+	LOCAL_CREDS_PERSISTENT         = 0x3
+	LOCAL_PEERCRED                 = 0x1
+	LOCAL_VENDOR                   = 0x80000000
 	LOCK_EX                        = 0x2
 	LOCK_NB                        = 0x4
 	LOCK_SH                        = 0x1
@@ -1376,6 +1382,7 @@
 	SOCK_RDM                       = 0x4
 	SOCK_SEQPACKET                 = 0x5
 	SOCK_STREAM                    = 0x1
+	SOL_LOCAL                      = 0x0
 	SOL_SOCKET                     = 0xffff
 	SOMAXCONN                      = 0x80
 	SO_ACCEPTCONN                  = 0x2
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
index be14bb1..3df99f2 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
@@ -1,6 +1,7 @@
 // mkerrors.sh
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm && freebsd
 // +build arm,freebsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
@@ -980,6 +981,11 @@
 	KERN_OSRELEASE                 = 0x2
 	KERN_OSTYPE                    = 0x1
 	KERN_VERSION                   = 0x4
+	LOCAL_CONNWAIT                 = 0x4
+	LOCAL_CREDS                    = 0x2
+	LOCAL_CREDS_PERSISTENT         = 0x3
+	LOCAL_PEERCRED                 = 0x1
+	LOCAL_VENDOR                   = 0x80000000
 	LOCK_EX                        = 0x2
 	LOCK_NB                        = 0x4
 	LOCK_SH                        = 0x1
@@ -1016,6 +1022,15 @@
 	MAP_RESERVED0100               = 0x100
 	MAP_SHARED                     = 0x1
 	MAP_STACK                      = 0x400
+	MCAST_BLOCK_SOURCE             = 0x54
+	MCAST_EXCLUDE                  = 0x2
+	MCAST_INCLUDE                  = 0x1
+	MCAST_JOIN_GROUP               = 0x50
+	MCAST_JOIN_SOURCE_GROUP        = 0x52
+	MCAST_LEAVE_GROUP              = 0x51
+	MCAST_LEAVE_SOURCE_GROUP       = 0x53
+	MCAST_UNBLOCK_SOURCE           = 0x55
+	MCAST_UNDEFINED                = 0x0
 	MCL_CURRENT                    = 0x1
 	MCL_FUTURE                     = 0x2
 	MNT_ACLS                       = 0x8000000
@@ -1341,6 +1356,7 @@
 	SOCK_RDM                       = 0x4
 	SOCK_SEQPACKET                 = 0x5
 	SOCK_STREAM                    = 0x1
+	SOL_LOCAL                      = 0x0
 	SOL_SOCKET                     = 0xffff
 	SOMAXCONN                      = 0x80
 	SO_ACCEPTCONN                  = 0x2
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go
index 7ce9c00..218d399 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && freebsd
 // +build arm64,freebsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
@@ -997,6 +998,11 @@
 	KERN_OSRELEASE                 = 0x2
 	KERN_OSTYPE                    = 0x1
 	KERN_VERSION                   = 0x4
+	LOCAL_CONNWAIT                 = 0x4
+	LOCAL_CREDS                    = 0x2
+	LOCAL_CREDS_PERSISTENT         = 0x3
+	LOCAL_PEERCRED                 = 0x1
+	LOCAL_VENDOR                   = 0x80000000
 	LOCK_EX                        = 0x2
 	LOCK_NB                        = 0x4
 	LOCK_SH                        = 0x1
@@ -1376,6 +1382,7 @@
 	SOCK_RDM                       = 0x4
 	SOCK_SEQPACKET                 = 0x5
 	SOCK_STREAM                    = 0x1
+	SOL_LOCAL                      = 0x0
 	SOL_SOCKET                     = 0xffff
 	SOMAXCONN                      = 0x80
 	SO_ACCEPTCONN                  = 0x2
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go
index b461103..47572aa 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go
@@ -1,5 +1,6 @@
 // Code generated by mkmerge.go; DO NOT EDIT.
 
+//go:build linux
 // +build linux
 
 package unix
@@ -65,6 +66,7 @@
 	ALG_OP_ENCRYPT                              = 0x1
 	ALG_SET_AEAD_ASSOCLEN                       = 0x4
 	ALG_SET_AEAD_AUTHSIZE                       = 0x5
+	ALG_SET_DRBG_ENTROPY                        = 0x6
 	ALG_SET_IV                                  = 0x2
 	ALG_SET_KEY                                 = 0x1
 	ALG_SET_OP                                  = 0x3
@@ -164,13 +166,16 @@
 	BPF_ALU64                                   = 0x7
 	BPF_AND                                     = 0x50
 	BPF_ARSH                                    = 0xc0
+	BPF_ATOMIC                                  = 0xc0
 	BPF_B                                       = 0x10
 	BPF_BUILD_ID_SIZE                           = 0x14
 	BPF_CALL                                    = 0x80
+	BPF_CMPXCHG                                 = 0xf1
 	BPF_DIV                                     = 0x30
 	BPF_DW                                      = 0x18
 	BPF_END                                     = 0xd0
 	BPF_EXIT                                    = 0x90
+	BPF_FETCH                                   = 0x1
 	BPF_FROM_BE                                 = 0x8
 	BPF_FROM_LE                                 = 0x0
 	BPF_FS_MAGIC                                = 0xcafe4a11
@@ -179,8 +184,10 @@
 	BPF_F_ANY_ALIGNMENT                         = 0x2
 	BPF_F_QUERY_EFFECTIVE                       = 0x1
 	BPF_F_REPLACE                               = 0x4
+	BPF_F_SLEEPABLE                             = 0x10
 	BPF_F_STRICT_ALIGNMENT                      = 0x1
 	BPF_F_TEST_RND_HI32                         = 0x4
+	BPF_F_TEST_RUN_ON_CPU                       = 0x1
 	BPF_F_TEST_STATE_FREQ                       = 0x8
 	BPF_H                                       = 0x8
 	BPF_IMM                                     = 0x0
@@ -219,6 +226,7 @@
 	BPF_NET_OFF                                 = -0x100000
 	BPF_OBJ_NAME_LEN                            = 0x10
 	BPF_OR                                      = 0x40
+	BPF_PSEUDO_BTF_ID                           = 0x3
 	BPF_PSEUDO_CALL                             = 0x1
 	BPF_PSEUDO_MAP_FD                           = 0x1
 	BPF_PSEUDO_MAP_VALUE                        = 0x2
@@ -235,11 +243,16 @@
 	BPF_W                                       = 0x0
 	BPF_X                                       = 0x8
 	BPF_XADD                                    = 0xc0
+	BPF_XCHG                                    = 0xe1
 	BPF_XOR                                     = 0xa0
 	BRKINT                                      = 0x2
 	BS0                                         = 0x0
 	BTRFS_SUPER_MAGIC                           = 0x9123683e
 	BTRFS_TEST_MAGIC                            = 0x73727279
+	BUS_BLUETOOTH                               = 0x5
+	BUS_HIL                                     = 0x4
+	BUS_USB                                     = 0x3
+	BUS_VIRTUAL                                 = 0x6
 	CAN_BCM                                     = 0x2
 	CAN_EFF_FLAG                                = 0x80000000
 	CAN_EFF_ID_BITS                             = 0x1d
@@ -309,6 +322,7 @@
 	CAN_J1939                                   = 0x7
 	CAN_MAX_DLC                                 = 0x8
 	CAN_MAX_DLEN                                = 0x8
+	CAN_MAX_RAW_DLC                             = 0xf
 	CAN_MCNET                                   = 0x5
 	CAN_MTU                                     = 0x10
 	CAN_NPROTO                                  = 0x8
@@ -429,10 +443,13 @@
 	DEBUGFS_MAGIC                               = 0x64626720
 	DEVLINK_CMD_ESWITCH_MODE_GET                = 0x1d
 	DEVLINK_CMD_ESWITCH_MODE_SET                = 0x1e
+	DEVLINK_FLASH_OVERWRITE_IDENTIFIERS         = 0x2
+	DEVLINK_FLASH_OVERWRITE_SETTINGS            = 0x1
 	DEVLINK_GENL_MCGRP_CONFIG_NAME              = "config"
 	DEVLINK_GENL_NAME                           = "devlink"
 	DEVLINK_GENL_VERSION                        = 0x1
 	DEVLINK_SB_THRESHOLD_TO_ALPHA_MAX           = 0x14
+	DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS  = 0x3
 	DEVMEM_MAGIC                                = 0x454d444d
 	DEVPTS_SUPER_MAGIC                          = 0x1cd1
 	DMA_BUF_MAGIC                               = 0x444d4142
@@ -477,9 +494,9 @@
 	DM_UUID_FLAG                                = 0x4000
 	DM_UUID_LEN                                 = 0x81
 	DM_VERSION                                  = 0xc138fd00
-	DM_VERSION_EXTRA                            = "-ioctl (2020-02-27)"
+	DM_VERSION_EXTRA                            = "-ioctl (2021-02-01)"
 	DM_VERSION_MAJOR                            = 0x4
-	DM_VERSION_MINOR                            = 0x2a
+	DM_VERSION_MINOR                            = 0x2c
 	DM_VERSION_PATCHLEVEL                       = 0x0
 	DT_BLK                                      = 0x6
 	DT_CHR                                      = 0x2
@@ -520,6 +537,119 @@
 	EPOLL_CTL_DEL                               = 0x2
 	EPOLL_CTL_MOD                               = 0x3
 	EROFS_SUPER_MAGIC_V1                        = 0xe0f5e1e2
+	ESP_V4_FLOW                                 = 0xa
+	ESP_V6_FLOW                                 = 0xc
+	ETHER_FLOW                                  = 0x12
+	ETHTOOL_BUSINFO_LEN                         = 0x20
+	ETHTOOL_EROMVERS_LEN                        = 0x20
+	ETHTOOL_FEC_AUTO                            = 0x2
+	ETHTOOL_FEC_BASER                           = 0x10
+	ETHTOOL_FEC_LLRS                            = 0x20
+	ETHTOOL_FEC_NONE                            = 0x1
+	ETHTOOL_FEC_OFF                             = 0x4
+	ETHTOOL_FEC_RS                              = 0x8
+	ETHTOOL_FLAG_ALL                            = 0x7
+	ETHTOOL_FLAG_COMPACT_BITSETS                = 0x1
+	ETHTOOL_FLAG_OMIT_REPLY                     = 0x2
+	ETHTOOL_FLAG_STATS                          = 0x4
+	ETHTOOL_FLASHDEV                            = 0x33
+	ETHTOOL_FLASH_MAX_FILENAME                  = 0x80
+	ETHTOOL_FWVERS_LEN                          = 0x20
+	ETHTOOL_F_COMPAT                            = 0x4
+	ETHTOOL_F_UNSUPPORTED                       = 0x1
+	ETHTOOL_F_WISH                              = 0x2
+	ETHTOOL_GCHANNELS                           = 0x3c
+	ETHTOOL_GCOALESCE                           = 0xe
+	ETHTOOL_GDRVINFO                            = 0x3
+	ETHTOOL_GEEE                                = 0x44
+	ETHTOOL_GEEPROM                             = 0xb
+	ETHTOOL_GENL_NAME                           = "ethtool"
+	ETHTOOL_GENL_VERSION                        = 0x1
+	ETHTOOL_GET_DUMP_DATA                       = 0x40
+	ETHTOOL_GET_DUMP_FLAG                       = 0x3f
+	ETHTOOL_GET_TS_INFO                         = 0x41
+	ETHTOOL_GFEATURES                           = 0x3a
+	ETHTOOL_GFECPARAM                           = 0x50
+	ETHTOOL_GFLAGS                              = 0x25
+	ETHTOOL_GGRO                                = 0x2b
+	ETHTOOL_GGSO                                = 0x23
+	ETHTOOL_GLINK                               = 0xa
+	ETHTOOL_GLINKSETTINGS                       = 0x4c
+	ETHTOOL_GMODULEEEPROM                       = 0x43
+	ETHTOOL_GMODULEINFO                         = 0x42
+	ETHTOOL_GMSGLVL                             = 0x7
+	ETHTOOL_GPAUSEPARAM                         = 0x12
+	ETHTOOL_GPERMADDR                           = 0x20
+	ETHTOOL_GPFLAGS                             = 0x27
+	ETHTOOL_GPHYSTATS                           = 0x4a
+	ETHTOOL_GREGS                               = 0x4
+	ETHTOOL_GRINGPARAM                          = 0x10
+	ETHTOOL_GRSSH                               = 0x46
+	ETHTOOL_GRXCLSRLALL                         = 0x30
+	ETHTOOL_GRXCLSRLCNT                         = 0x2e
+	ETHTOOL_GRXCLSRULE                          = 0x2f
+	ETHTOOL_GRXCSUM                             = 0x14
+	ETHTOOL_GRXFH                               = 0x29
+	ETHTOOL_GRXFHINDIR                          = 0x38
+	ETHTOOL_GRXNTUPLE                           = 0x36
+	ETHTOOL_GRXRINGS                            = 0x2d
+	ETHTOOL_GSET                                = 0x1
+	ETHTOOL_GSG                                 = 0x18
+	ETHTOOL_GSSET_INFO                          = 0x37
+	ETHTOOL_GSTATS                              = 0x1d
+	ETHTOOL_GSTRINGS                            = 0x1b
+	ETHTOOL_GTSO                                = 0x1e
+	ETHTOOL_GTUNABLE                            = 0x48
+	ETHTOOL_GTXCSUM                             = 0x16
+	ETHTOOL_GUFO                                = 0x21
+	ETHTOOL_GWOL                                = 0x5
+	ETHTOOL_MCGRP_MONITOR_NAME                  = "monitor"
+	ETHTOOL_NWAY_RST                            = 0x9
+	ETHTOOL_PERQUEUE                            = 0x4b
+	ETHTOOL_PHYS_ID                             = 0x1c
+	ETHTOOL_PHY_EDPD_DFLT_TX_MSECS              = 0xffff
+	ETHTOOL_PHY_EDPD_DISABLE                    = 0x0
+	ETHTOOL_PHY_EDPD_NO_TX                      = 0xfffe
+	ETHTOOL_PHY_FAST_LINK_DOWN_OFF              = 0xff
+	ETHTOOL_PHY_FAST_LINK_DOWN_ON               = 0x0
+	ETHTOOL_PHY_GTUNABLE                        = 0x4e
+	ETHTOOL_PHY_STUNABLE                        = 0x4f
+	ETHTOOL_RESET                               = 0x34
+	ETHTOOL_RXNTUPLE_ACTION_CLEAR               = -0x2
+	ETHTOOL_RXNTUPLE_ACTION_DROP                = -0x1
+	ETHTOOL_RX_FLOW_SPEC_RING                   = 0xffffffff
+	ETHTOOL_RX_FLOW_SPEC_RING_VF                = 0xff00000000
+	ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF            = 0x20
+	ETHTOOL_SCHANNELS                           = 0x3d
+	ETHTOOL_SCOALESCE                           = 0xf
+	ETHTOOL_SEEE                                = 0x45
+	ETHTOOL_SEEPROM                             = 0xc
+	ETHTOOL_SET_DUMP                            = 0x3e
+	ETHTOOL_SFEATURES                           = 0x3b
+	ETHTOOL_SFECPARAM                           = 0x51
+	ETHTOOL_SFLAGS                              = 0x26
+	ETHTOOL_SGRO                                = 0x2c
+	ETHTOOL_SGSO                                = 0x24
+	ETHTOOL_SLINKSETTINGS                       = 0x4d
+	ETHTOOL_SMSGLVL                             = 0x8
+	ETHTOOL_SPAUSEPARAM                         = 0x13
+	ETHTOOL_SPFLAGS                             = 0x28
+	ETHTOOL_SRINGPARAM                          = 0x11
+	ETHTOOL_SRSSH                               = 0x47
+	ETHTOOL_SRXCLSRLDEL                         = 0x31
+	ETHTOOL_SRXCLSRLINS                         = 0x32
+	ETHTOOL_SRXCSUM                             = 0x15
+	ETHTOOL_SRXFH                               = 0x2a
+	ETHTOOL_SRXFHINDIR                          = 0x39
+	ETHTOOL_SRXNTUPLE                           = 0x35
+	ETHTOOL_SSET                                = 0x2
+	ETHTOOL_SSG                                 = 0x19
+	ETHTOOL_STSO                                = 0x1f
+	ETHTOOL_STUNABLE                            = 0x49
+	ETHTOOL_STXCSUM                             = 0x17
+	ETHTOOL_SUFO                                = 0x22
+	ETHTOOL_SWOL                                = 0x6
+	ETHTOOL_TEST                                = 0x1a
 	ETH_P_1588                                  = 0x88f7
 	ETH_P_8021AD                                = 0x88a8
 	ETH_P_8021AH                                = 0x88e7
@@ -544,6 +674,7 @@
 	ETH_P_CAIF                                  = 0xf7
 	ETH_P_CAN                                   = 0xc
 	ETH_P_CANFD                                 = 0xd
+	ETH_P_CFM                                   = 0x8902
 	ETH_P_CONTROL                               = 0x16
 	ETH_P_CUST                                  = 0x6006
 	ETH_P_DDCMP                                 = 0x6
@@ -714,7 +845,6 @@
 	FSCRYPT_POLICY_FLAGS_PAD_4                  = 0x0
 	FSCRYPT_POLICY_FLAGS_PAD_8                  = 0x1
 	FSCRYPT_POLICY_FLAGS_PAD_MASK               = 0x3
-	FSCRYPT_POLICY_FLAGS_VALID                  = 0x1f
 	FSCRYPT_POLICY_FLAG_DIRECT_KEY              = 0x4
 	FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32          = 0x10
 	FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64          = 0x8
@@ -734,6 +864,7 @@
 	FS_IOC_GET_ENCRYPTION_KEY_STATUS            = 0xc080661a
 	FS_IOC_GET_ENCRYPTION_POLICY_EX             = 0xc0096616
 	FS_IOC_MEASURE_VERITY                       = 0xc0046686
+	FS_IOC_READ_VERITY_METADATA                 = 0xc0286687
 	FS_IOC_REMOVE_ENCRYPTION_KEY                = 0xc0406618
 	FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS      = 0xc0406619
 	FS_KEY_DESCRIPTOR_SIZE                      = 0x8
@@ -745,10 +876,13 @@
 	FS_POLICY_FLAGS_PAD_4                       = 0x0
 	FS_POLICY_FLAGS_PAD_8                       = 0x1
 	FS_POLICY_FLAGS_PAD_MASK                    = 0x3
-	FS_POLICY_FLAGS_VALID                       = 0x1f
+	FS_POLICY_FLAGS_VALID                       = 0x7
 	FS_VERITY_FL                                = 0x100000
 	FS_VERITY_HASH_ALG_SHA256                   = 0x1
 	FS_VERITY_HASH_ALG_SHA512                   = 0x2
+	FS_VERITY_METADATA_TYPE_DESCRIPTOR          = 0x2
+	FS_VERITY_METADATA_TYPE_MERKLE_TREE         = 0x1
+	FS_VERITY_METADATA_TYPE_SIGNATURE           = 0x3
 	FUTEXFS_SUPER_MAGIC                         = 0xbad1dea
 	F_ADD_SEALS                                 = 0x409
 	F_DUPFD                                     = 0x0
@@ -842,11 +976,17 @@
 	HDIO_SET_XFER                               = 0x306
 	HDIO_TRISTATE_HWIF                          = 0x31b
 	HDIO_UNREGISTER_HWIF                        = 0x32a
+	HID_MAX_DESCRIPTOR_SIZE                     = 0x1000
 	HOSTFS_SUPER_MAGIC                          = 0xc0ffee
 	HPFS_SUPER_MAGIC                            = 0xf995e849
 	HUGETLBFS_MAGIC                             = 0x958458f6
 	IBSHIFT                                     = 0x10
 	ICMPV6_FILTER                               = 0x1
+	ICMPV6_FILTER_BLOCK                         = 0x1
+	ICMPV6_FILTER_BLOCKOTHERS                   = 0x3
+	ICMPV6_FILTER_PASS                          = 0x2
+	ICMPV6_FILTER_PASSONLY                      = 0x4
+	ICMP_FILTER                                 = 0x1
 	ICRNL                                       = 0x100
 	IFA_F_DADFAILED                             = 0x8
 	IFA_F_DEPRECATED                            = 0x20
@@ -989,6 +1129,7 @@
 	IPV6_DONTFRAG                               = 0x3e
 	IPV6_DROP_MEMBERSHIP                        = 0x15
 	IPV6_DSTOPTS                                = 0x3b
+	IPV6_FLOW                                   = 0x11
 	IPV6_FREEBIND                               = 0x4e
 	IPV6_HDRINCL                                = 0x24
 	IPV6_HOPLIMIT                               = 0x34
@@ -1017,6 +1158,7 @@
 	IPV6_PMTUDISC_WANT                          = 0x1
 	IPV6_RECVDSTOPTS                            = 0x3a
 	IPV6_RECVERR                                = 0x19
+	IPV6_RECVERR_RFC4884                        = 0x1f
 	IPV6_RECVFRAGSIZE                           = 0x4d
 	IPV6_RECVHOPLIMIT                           = 0x33
 	IPV6_RECVHOPOPTS                            = 0x35
@@ -1038,6 +1180,7 @@
 	IPV6_TRANSPARENT                            = 0x4b
 	IPV6_UNICAST_HOPS                           = 0x10
 	IPV6_UNICAST_IF                             = 0x4c
+	IPV6_USER_FLOW                              = 0xe
 	IPV6_V6ONLY                                 = 0x1a
 	IPV6_XFRM_POLICY                            = 0x23
 	IP_ADD_MEMBERSHIP                           = 0x23
@@ -1080,6 +1223,7 @@
 	IP_PMTUDISC_PROBE                           = 0x3
 	IP_PMTUDISC_WANT                            = 0x1
 	IP_RECVERR                                  = 0xb
+	IP_RECVERR_RFC4884                          = 0x1a
 	IP_RECVFRAGSIZE                             = 0x19
 	IP_RECVOPTS                                 = 0x6
 	IP_RECVORIGDSTADDR                          = 0x14
@@ -1094,6 +1238,7 @@
 	IP_TTL                                      = 0x2
 	IP_UNBLOCK_SOURCE                           = 0x25
 	IP_UNICAST_IF                               = 0x32
+	IP_USER_FLOW                                = 0xd
 	IP_XFRM_POLICY                              = 0x11
 	ISOFS_SUPER_MAGIC                           = 0x9660
 	ISTRIP                                      = 0x20
@@ -1331,6 +1476,7 @@
 	MS_NOREMOTELOCK                             = 0x8000000
 	MS_NOSEC                                    = 0x10000000
 	MS_NOSUID                                   = 0x2
+	MS_NOSYMFOLLOW                              = 0x100
 	MS_NOUSER                                   = -0x80000000
 	MS_POSIXACL                                 = 0x10000
 	MS_PRIVATE                                  = 0x40000
@@ -1535,6 +1681,10 @@
 	PERF_FLAG_PID_CGROUP                        = 0x4
 	PERF_MAX_CONTEXTS_PER_STACK                 = 0x8
 	PERF_MAX_STACK_DEPTH                        = 0x7f
+	PERF_MEM_BLK_ADDR                           = 0x4
+	PERF_MEM_BLK_DATA                           = 0x2
+	PERF_MEM_BLK_NA                             = 0x1
+	PERF_MEM_BLK_SHIFT                          = 0x28
 	PERF_MEM_LOCK_LOCKED                        = 0x2
 	PERF_MEM_LOCK_NA                            = 0x1
 	PERF_MEM_LOCK_SHIFT                         = 0x18
@@ -1572,7 +1722,7 @@
 	PERF_MEM_REMOTE_REMOTE                      = 0x1
 	PERF_MEM_REMOTE_SHIFT                       = 0x25
 	PERF_MEM_SNOOPX_FWD                         = 0x1
-	PERF_MEM_SNOOPX_SHIFT                       = 0x25
+	PERF_MEM_SNOOPX_SHIFT                       = 0x26
 	PERF_MEM_SNOOP_HIT                          = 0x4
 	PERF_MEM_SNOOP_HITM                         = 0x10
 	PERF_MEM_SNOOP_MISS                         = 0x8
@@ -1598,12 +1748,14 @@
 	PERF_RECORD_MISC_GUEST_USER                 = 0x5
 	PERF_RECORD_MISC_HYPERVISOR                 = 0x3
 	PERF_RECORD_MISC_KERNEL                     = 0x1
+	PERF_RECORD_MISC_MMAP_BUILD_ID              = 0x4000
 	PERF_RECORD_MISC_MMAP_DATA                  = 0x2000
 	PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT     = 0x1000
 	PERF_RECORD_MISC_SWITCH_OUT                 = 0x2000
 	PERF_RECORD_MISC_SWITCH_OUT_PREEMPT         = 0x4000
 	PERF_RECORD_MISC_USER                       = 0x2
 	PERF_SAMPLE_BRANCH_PLM_ALL                  = 0x7
+	PERF_SAMPLE_WEIGHT_TYPE                     = 0x1004000
 	PIPEFS_MAGIC                                = 0x50495045
 	PPC_CMM_MAGIC                               = 0xc7571590
 	PPPIOCGNPMODE                               = 0xc008744c
@@ -1672,6 +1824,13 @@
 	PR_MCE_KILL_SET                             = 0x1
 	PR_MPX_DISABLE_MANAGEMENT                   = 0x2c
 	PR_MPX_ENABLE_MANAGEMENT                    = 0x2b
+	PR_MTE_TAG_MASK                             = 0x7fff8
+	PR_MTE_TAG_SHIFT                            = 0x3
+	PR_MTE_TCF_ASYNC                            = 0x4
+	PR_MTE_TCF_MASK                             = 0x6
+	PR_MTE_TCF_NONE                             = 0x0
+	PR_MTE_TCF_SHIFT                            = 0x1
+	PR_MTE_TCF_SYNC                             = 0x2
 	PR_PAC_APDAKEY                              = 0x4
 	PR_PAC_APDBKEY                              = 0x8
 	PR_PAC_APGAKEY                              = 0x10
@@ -1709,6 +1868,7 @@
 	PR_SET_SECCOMP                              = 0x16
 	PR_SET_SECUREBITS                           = 0x1c
 	PR_SET_SPECULATION_CTRL                     = 0x35
+	PR_SET_SYSCALL_USER_DISPATCH                = 0x3b
 	PR_SET_TAGGED_ADDR_CTRL                     = 0x37
 	PR_SET_THP_DISABLE                          = 0x29
 	PR_SET_TIMERSLACK                           = 0x1d
@@ -1728,6 +1888,8 @@
 	PR_SVE_SET_VL_ONEXEC                        = 0x40000
 	PR_SVE_VL_INHERIT                           = 0x20000
 	PR_SVE_VL_LEN_MASK                          = 0xffff
+	PR_SYS_DISPATCH_OFF                         = 0x0
+	PR_SYS_DISPATCH_ON                          = 0x1
 	PR_TAGGED_ADDR_ENABLE                       = 0x1
 	PR_TASK_PERF_EVENTS_DISABLE                 = 0x1f
 	PR_TASK_PERF_EVENTS_ENABLE                  = 0x20
@@ -1847,6 +2009,10 @@
 	RTCF_NAT                                    = 0x800000
 	RTCF_VALVE                                  = 0x200000
 	RTC_AF                                      = 0x20
+	RTC_FEATURE_ALARM                           = 0x0
+	RTC_FEATURE_ALARM_RES_MINUTE                = 0x1
+	RTC_FEATURE_CNT                             = 0x3
+	RTC_FEATURE_NEED_WEEK_DAY                   = 0x2
 	RTC_IRQF                                    = 0x80
 	RTC_MAX_FREQ                                = 0x2000
 	RTC_PF                                      = 0x40
@@ -1920,6 +2086,7 @@
 	RTM_F_LOOKUP_TABLE                          = 0x1000
 	RTM_F_NOTIFY                                = 0x100
 	RTM_F_OFFLOAD                               = 0x4000
+	RTM_F_OFFLOAD_FAILED                        = 0x20000000
 	RTM_F_PREFIX                                = 0x800
 	RTM_F_TRAP                                  = 0x8000
 	RTM_GETACTION                               = 0x32
@@ -1973,12 +2140,13 @@
 	RTM_SETLINK                                 = 0x13
 	RTM_SETNEIGHTBL                             = 0x43
 	RTNH_ALIGNTO                                = 0x4
-	RTNH_COMPARE_MASK                           = 0x19
+	RTNH_COMPARE_MASK                           = 0x59
 	RTNH_F_DEAD                                 = 0x1
 	RTNH_F_LINKDOWN                             = 0x10
 	RTNH_F_OFFLOAD                              = 0x8
 	RTNH_F_ONLINK                               = 0x4
 	RTNH_F_PERVASIVE                            = 0x2
+	RTNH_F_TRAP                                 = 0x40
 	RTNH_F_UNRESOLVED                           = 0x20
 	RTN_MAX                                     = 0xb
 	RTPROT_BABEL                                = 0x2a
@@ -2206,7 +2374,7 @@
 	STATX_ATTR_APPEND                           = 0x20
 	STATX_ATTR_AUTOMOUNT                        = 0x1000
 	STATX_ATTR_COMPRESSED                       = 0x4
-	STATX_ATTR_DAX                              = 0x2000
+	STATX_ATTR_DAX                              = 0x200000
 	STATX_ATTR_ENCRYPTED                        = 0x800
 	STATX_ATTR_IMMUTABLE                        = 0x10
 	STATX_ATTR_MOUNT_ROOT                       = 0x2000
@@ -2325,6 +2493,8 @@
 	TCP_TX_DELAY                                = 0x25
 	TCP_ULP                                     = 0x1f
 	TCP_USER_TIMEOUT                            = 0x12
+	TCP_V4_FLOW                                 = 0x1
+	TCP_V6_FLOW                                 = 0x5
 	TCP_WINDOW_CLAMP                            = 0xa
 	TCP_ZEROCOPY_RECEIVE                        = 0x23
 	TFD_TIMER_ABSTIME                           = 0x1
@@ -2390,6 +2560,7 @@
 	TIPC_NODE_STATE                             = 0x0
 	TIPC_OK                                     = 0x0
 	TIPC_PUBLISHED                              = 0x1
+	TIPC_REKEYING_NOW                           = 0xffffffff
 	TIPC_RESERVED_TYPES                         = 0x40
 	TIPC_RETDATA                                = 0x2
 	TIPC_SERVICE_ADDR                           = 0x2
@@ -2446,10 +2617,12 @@
 	VMADDR_CID_HOST                             = 0x2
 	VMADDR_CID_HYPERVISOR                       = 0x0
 	VMADDR_CID_LOCAL                            = 0x1
+	VMADDR_FLAG_TO_HOST                         = 0x1
 	VMADDR_PORT_ANY                             = 0xffffffff
 	VM_SOCKETS_INVALID_VERSION                  = 0xffffffff
 	VQUIT                                       = 0x1
 	VT0                                         = 0x0
+	WAKE_MAGIC                                  = 0x20
 	WALL                                        = 0x40000000
 	WCLONE                                      = 0x80000000
 	WCONTINUED                                  = 0x8
@@ -2592,6 +2765,9 @@
 	Z3FOLD_MAGIC                                = 0x33
 	ZONEFS_MAGIC                                = 0x5a4f4653
 	ZSMALLOC_MAGIC                              = 0x58295829
+	_HIDIOCGRAWNAME_LEN                         = 0x80
+	_HIDIOCGRAWPHYS_LEN                         = 0x40
+	_HIDIOCGRAWUNIQ_LEN                         = 0x40
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
index dd282c0..e91a1a9 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include -m32
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build 386 && linux
 // +build 386,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 /build/_const.go
 
 package unix
 
@@ -93,6 +94,9 @@
 	F_SETOWN                         = 0x8
 	F_UNLCK                          = 0x2
 	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x80084803
+	HIDIOCGRDESC                     = 0x90044802
+	HIDIOCGRDESCSIZE                 = 0x80044801
 	HUPCL                            = 0x400
 	ICANON                           = 0x2
 	IEXTEN                           = 0x8000
@@ -165,6 +169,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x2405
 	PPPIOCATTACH                     = 0x4004743d
 	PPPIOCATTCHAN                    = 0x40047438
+	PPPIOCBRIDGECHAN                 = 0x40047435
 	PPPIOCCONNECT                    = 0x4004743a
 	PPPIOCDETACH                     = 0x4004743c
 	PPPIOCDISCONN                    = 0x7439
@@ -192,6 +197,7 @@
 	PPPIOCSPASS                      = 0x40087447
 	PPPIOCSRASYNCMAP                 = 0x40047454
 	PPPIOCSXASYNCMAP                 = 0x4020744f
+	PPPIOCUNBRIDGECHAN               = 0x7434
 	PPPIOCXFERUNIT                   = 0x744e
 	PR_SET_PTRACER_ANY               = 0xffffffff
 	PTRACE_GETFPREGS                 = 0xe
@@ -268,6 +274,7 @@
 	SO_BROADCAST                     = 0x6
 	SO_BSDCOMPAT                     = 0xe
 	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
 	SO_CNX_ADVICE                    = 0x35
 	SO_COOKIE                        = 0x39
 	SO_DETACH_REUSEPORT_BPF          = 0x44
@@ -290,6 +297,7 @@
 	SO_PEERCRED                      = 0x11
 	SO_PEERGROUPS                    = 0x3b
 	SO_PEERSEC                       = 0x1f
+	SO_PREFER_BUSY_POLL              = 0x45
 	SO_PROTOCOL                      = 0x26
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
@@ -481,6 +489,9 @@
 	X86_FXSR_MAGIC                   = 0x0
 	XCASE                            = 0x4
 	XTABS                            = 0x1800
+	_HIDIOCGRAWNAME                  = 0x80804804
+	_HIDIOCGRAWPHYS                  = 0x80404805
+	_HIDIOCGRAWUNIQ                  = 0x80404808
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
index 82fc93c..a9cbac6 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && linux
 // +build amd64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 /build/_const.go
 
 package unix
 
@@ -93,6 +94,9 @@
 	F_SETOWN                         = 0x8
 	F_UNLCK                          = 0x2
 	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x80084803
+	HIDIOCGRDESC                     = 0x90044802
+	HIDIOCGRDESCSIZE                 = 0x80044801
 	HUPCL                            = 0x400
 	ICANON                           = 0x2
 	IEXTEN                           = 0x8000
@@ -165,6 +169,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x2405
 	PPPIOCATTACH                     = 0x4004743d
 	PPPIOCATTCHAN                    = 0x40047438
+	PPPIOCBRIDGECHAN                 = 0x40047435
 	PPPIOCCONNECT                    = 0x4004743a
 	PPPIOCDETACH                     = 0x4004743c
 	PPPIOCDISCONN                    = 0x7439
@@ -192,6 +197,7 @@
 	PPPIOCSPASS                      = 0x40107447
 	PPPIOCSRASYNCMAP                 = 0x40047454
 	PPPIOCSXASYNCMAP                 = 0x4020744f
+	PPPIOCUNBRIDGECHAN               = 0x7434
 	PPPIOCXFERUNIT                   = 0x744e
 	PR_SET_PTRACER_ANY               = 0xffffffffffffffff
 	PTRACE_ARCH_PRCTL                = 0x1e
@@ -269,6 +275,7 @@
 	SO_BROADCAST                     = 0x6
 	SO_BSDCOMPAT                     = 0xe
 	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
 	SO_CNX_ADVICE                    = 0x35
 	SO_COOKIE                        = 0x39
 	SO_DETACH_REUSEPORT_BPF          = 0x44
@@ -291,6 +298,7 @@
 	SO_PEERCRED                      = 0x11
 	SO_PEERGROUPS                    = 0x3b
 	SO_PEERSEC                       = 0x1f
+	SO_PREFER_BUSY_POLL              = 0x45
 	SO_PROTOCOL                      = 0x26
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
@@ -481,6 +489,9 @@
 	WORDSIZE                         = 0x40
 	XCASE                            = 0x4
 	XTABS                            = 0x1800
+	_HIDIOCGRAWNAME                  = 0x80804804
+	_HIDIOCGRAWPHYS                  = 0x80404805
+	_HIDIOCGRAWUNIQ                  = 0x80404808
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
index fe7094f..d74f3c1 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm && linux
 // +build arm,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
 
 package unix
 
@@ -92,6 +93,9 @@
 	F_SETOWN                         = 0x8
 	F_UNLCK                          = 0x2
 	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x80084803
+	HIDIOCGRDESC                     = 0x90044802
+	HIDIOCGRDESCSIZE                 = 0x80044801
 	HUPCL                            = 0x400
 	ICANON                           = 0x2
 	IEXTEN                           = 0x8000
@@ -163,6 +167,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x2405
 	PPPIOCATTACH                     = 0x4004743d
 	PPPIOCATTCHAN                    = 0x40047438
+	PPPIOCBRIDGECHAN                 = 0x40047435
 	PPPIOCCONNECT                    = 0x4004743a
 	PPPIOCDETACH                     = 0x4004743c
 	PPPIOCDISCONN                    = 0x7439
@@ -190,6 +195,7 @@
 	PPPIOCSPASS                      = 0x40087447
 	PPPIOCSRASYNCMAP                 = 0x40047454
 	PPPIOCSXASYNCMAP                 = 0x4020744f
+	PPPIOCUNBRIDGECHAN               = 0x7434
 	PPPIOCXFERUNIT                   = 0x744e
 	PR_SET_PTRACER_ANY               = 0xffffffff
 	PTRACE_GETCRUNCHREGS             = 0x19
@@ -275,6 +281,7 @@
 	SO_BROADCAST                     = 0x6
 	SO_BSDCOMPAT                     = 0xe
 	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
 	SO_CNX_ADVICE                    = 0x35
 	SO_COOKIE                        = 0x39
 	SO_DETACH_REUSEPORT_BPF          = 0x44
@@ -297,6 +304,7 @@
 	SO_PEERCRED                      = 0x11
 	SO_PEERGROUPS                    = 0x3b
 	SO_PEERSEC                       = 0x1f
+	SO_PREFER_BUSY_POLL              = 0x45
 	SO_PROTOCOL                      = 0x26
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
@@ -487,6 +495,9 @@
 	WORDSIZE                         = 0x20
 	XCASE                            = 0x4
 	XTABS                            = 0x1800
+	_HIDIOCGRAWNAME                  = 0x80804804
+	_HIDIOCGRAWPHYS                  = 0x80404805
+	_HIDIOCGRAWUNIQ                  = 0x80404808
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
index 3b6cc58..e153899 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include -fsigned-char
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && linux
 // +build arm64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char /build/_const.go
 
 package unix
 
@@ -95,6 +96,9 @@
 	F_SETOWN                         = 0x8
 	F_UNLCK                          = 0x2
 	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x80084803
+	HIDIOCGRDESC                     = 0x90044802
+	HIDIOCGRDESCSIZE                 = 0x80044801
 	HUPCL                            = 0x400
 	ICANON                           = 0x2
 	IEXTEN                           = 0x8000
@@ -166,6 +170,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x2405
 	PPPIOCATTACH                     = 0x4004743d
 	PPPIOCATTCHAN                    = 0x40047438
+	PPPIOCBRIDGECHAN                 = 0x40047435
 	PPPIOCCONNECT                    = 0x4004743a
 	PPPIOCDETACH                     = 0x4004743c
 	PPPIOCDISCONN                    = 0x7439
@@ -193,9 +198,13 @@
 	PPPIOCSPASS                      = 0x40107447
 	PPPIOCSRASYNCMAP                 = 0x40047454
 	PPPIOCSXASYNCMAP                 = 0x4020744f
+	PPPIOCUNBRIDGECHAN               = 0x7434
 	PPPIOCXFERUNIT                   = 0x744e
 	PROT_BTI                         = 0x10
+	PROT_MTE                         = 0x20
 	PR_SET_PTRACER_ANY               = 0xffffffffffffffff
+	PTRACE_PEEKMTETAGS               = 0x21
+	PTRACE_POKEMTETAGS               = 0x22
 	PTRACE_SYSEMU                    = 0x1f
 	PTRACE_SYSEMU_SINGLESTEP         = 0x20
 	RLIMIT_AS                        = 0x9
@@ -262,6 +271,7 @@
 	SO_BROADCAST                     = 0x6
 	SO_BSDCOMPAT                     = 0xe
 	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
 	SO_CNX_ADVICE                    = 0x35
 	SO_COOKIE                        = 0x39
 	SO_DETACH_REUSEPORT_BPF          = 0x44
@@ -284,6 +294,7 @@
 	SO_PEERCRED                      = 0x11
 	SO_PEERGROUPS                    = 0x3b
 	SO_PEERSEC                       = 0x1f
+	SO_PREFER_BUSY_POLL              = 0x45
 	SO_PROTOCOL                      = 0x26
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
@@ -475,6 +486,9 @@
 	WORDSIZE                         = 0x40
 	XCASE                            = 0x4
 	XTABS                            = 0x1800
+	_HIDIOCGRAWNAME                  = 0x80804804
+	_HIDIOCGRAWPHYS                  = 0x80404805
+	_HIDIOCGRAWUNIQ                  = 0x80404808
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
index ce3d9ae..5e8e71f 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mips && linux
 // +build mips,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
 
 package unix
 
@@ -92,6 +93,9 @@
 	F_SETOWN                         = 0x18
 	F_UNLCK                          = 0x2
 	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x40084803
+	HIDIOCGRDESC                     = 0x50044802
+	HIDIOCGRDESCSIZE                 = 0x40044801
 	HUPCL                            = 0x400
 	ICANON                           = 0x2
 	IEXTEN                           = 0x100
@@ -163,6 +167,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x20002405
 	PPPIOCATTACH                     = 0x8004743d
 	PPPIOCATTCHAN                    = 0x80047438
+	PPPIOCBRIDGECHAN                 = 0x80047435
 	PPPIOCCONNECT                    = 0x8004743a
 	PPPIOCDETACH                     = 0x8004743c
 	PPPIOCDISCONN                    = 0x20007439
@@ -190,6 +195,7 @@
 	PPPIOCSPASS                      = 0x80087447
 	PPPIOCSRASYNCMAP                 = 0x80047454
 	PPPIOCSXASYNCMAP                 = 0x8020744f
+	PPPIOCUNBRIDGECHAN               = 0x20007434
 	PPPIOCXFERUNIT                   = 0x2000744e
 	PR_SET_PTRACER_ANY               = 0xffffffff
 	PTRACE_GETFPREGS                 = 0xe
@@ -268,6 +274,7 @@
 	SO_BROADCAST                     = 0x20
 	SO_BSDCOMPAT                     = 0xe
 	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
 	SO_CNX_ADVICE                    = 0x35
 	SO_COOKIE                        = 0x39
 	SO_DETACH_REUSEPORT_BPF          = 0x44
@@ -290,6 +297,7 @@
 	SO_PEERCRED                      = 0x12
 	SO_PEERGROUPS                    = 0x3b
 	SO_PEERSEC                       = 0x1e
+	SO_PREFER_BUSY_POLL              = 0x45
 	SO_PROTOCOL                      = 0x1028
 	SO_RCVBUF                        = 0x1002
 	SO_RCVBUFFORCE                   = 0x21
@@ -483,6 +491,9 @@
 	WORDSIZE                         = 0x20
 	XCASE                            = 0x4
 	XTABS                            = 0x1800
+	_HIDIOCGRAWNAME                  = 0x40804804
+	_HIDIOCGRAWPHYS                  = 0x40404805
+	_HIDIOCGRAWUNIQ                  = 0x40404808
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
index 7a85215..e670ee1 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mips64 && linux
 // +build mips64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
 
 package unix
 
@@ -92,6 +93,9 @@
 	F_SETOWN                         = 0x18
 	F_UNLCK                          = 0x2
 	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x40084803
+	HIDIOCGRDESC                     = 0x50044802
+	HIDIOCGRDESCSIZE                 = 0x40044801
 	HUPCL                            = 0x400
 	ICANON                           = 0x2
 	IEXTEN                           = 0x100
@@ -163,6 +167,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x20002405
 	PPPIOCATTACH                     = 0x8004743d
 	PPPIOCATTCHAN                    = 0x80047438
+	PPPIOCBRIDGECHAN                 = 0x80047435
 	PPPIOCCONNECT                    = 0x8004743a
 	PPPIOCDETACH                     = 0x8004743c
 	PPPIOCDISCONN                    = 0x20007439
@@ -190,6 +195,7 @@
 	PPPIOCSPASS                      = 0x80107447
 	PPPIOCSRASYNCMAP                 = 0x80047454
 	PPPIOCSXASYNCMAP                 = 0x8020744f
+	PPPIOCUNBRIDGECHAN               = 0x20007434
 	PPPIOCXFERUNIT                   = 0x2000744e
 	PR_SET_PTRACER_ANY               = 0xffffffffffffffff
 	PTRACE_GETFPREGS                 = 0xe
@@ -268,6 +274,7 @@
 	SO_BROADCAST                     = 0x20
 	SO_BSDCOMPAT                     = 0xe
 	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
 	SO_CNX_ADVICE                    = 0x35
 	SO_COOKIE                        = 0x39
 	SO_DETACH_REUSEPORT_BPF          = 0x44
@@ -290,6 +297,7 @@
 	SO_PEERCRED                      = 0x12
 	SO_PEERGROUPS                    = 0x3b
 	SO_PEERSEC                       = 0x1e
+	SO_PREFER_BUSY_POLL              = 0x45
 	SO_PROTOCOL                      = 0x1028
 	SO_RCVBUF                        = 0x1002
 	SO_RCVBUFFORCE                   = 0x21
@@ -483,6 +491,9 @@
 	WORDSIZE                         = 0x40
 	XCASE                            = 0x4
 	XTABS                            = 0x1800
+	_HIDIOCGRAWNAME                  = 0x40804804
+	_HIDIOCGRAWPHYS                  = 0x40404805
+	_HIDIOCGRAWUNIQ                  = 0x40404808
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
index 07d4cc1..dd11eac 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mips64le && linux
 // +build mips64le,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
 
 package unix
 
@@ -92,6 +93,9 @@
 	F_SETOWN                         = 0x18
 	F_UNLCK                          = 0x2
 	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x40084803
+	HIDIOCGRDESC                     = 0x50044802
+	HIDIOCGRDESCSIZE                 = 0x40044801
 	HUPCL                            = 0x400
 	ICANON                           = 0x2
 	IEXTEN                           = 0x100
@@ -163,6 +167,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x20002405
 	PPPIOCATTACH                     = 0x8004743d
 	PPPIOCATTCHAN                    = 0x80047438
+	PPPIOCBRIDGECHAN                 = 0x80047435
 	PPPIOCCONNECT                    = 0x8004743a
 	PPPIOCDETACH                     = 0x8004743c
 	PPPIOCDISCONN                    = 0x20007439
@@ -190,6 +195,7 @@
 	PPPIOCSPASS                      = 0x80107447
 	PPPIOCSRASYNCMAP                 = 0x80047454
 	PPPIOCSXASYNCMAP                 = 0x8020744f
+	PPPIOCUNBRIDGECHAN               = 0x20007434
 	PPPIOCXFERUNIT                   = 0x2000744e
 	PR_SET_PTRACER_ANY               = 0xffffffffffffffff
 	PTRACE_GETFPREGS                 = 0xe
@@ -268,6 +274,7 @@
 	SO_BROADCAST                     = 0x20
 	SO_BSDCOMPAT                     = 0xe
 	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
 	SO_CNX_ADVICE                    = 0x35
 	SO_COOKIE                        = 0x39
 	SO_DETACH_REUSEPORT_BPF          = 0x44
@@ -290,6 +297,7 @@
 	SO_PEERCRED                      = 0x12
 	SO_PEERGROUPS                    = 0x3b
 	SO_PEERSEC                       = 0x1e
+	SO_PREFER_BUSY_POLL              = 0x45
 	SO_PROTOCOL                      = 0x1028
 	SO_RCVBUF                        = 0x1002
 	SO_RCVBUFFORCE                   = 0x21
@@ -483,6 +491,9 @@
 	WORDSIZE                         = 0x40
 	XCASE                            = 0x4
 	XTABS                            = 0x1800
+	_HIDIOCGRAWNAME                  = 0x40804804
+	_HIDIOCGRAWPHYS                  = 0x40404805
+	_HIDIOCGRAWUNIQ                  = 0x40404808
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
index d4842ba..a0a5b22 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mipsle && linux
 // +build mipsle,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
 
 package unix
 
@@ -92,6 +93,9 @@
 	F_SETOWN                         = 0x18
 	F_UNLCK                          = 0x2
 	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x40084803
+	HIDIOCGRDESC                     = 0x50044802
+	HIDIOCGRDESCSIZE                 = 0x40044801
 	HUPCL                            = 0x400
 	ICANON                           = 0x2
 	IEXTEN                           = 0x100
@@ -163,6 +167,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x20002405
 	PPPIOCATTACH                     = 0x8004743d
 	PPPIOCATTCHAN                    = 0x80047438
+	PPPIOCBRIDGECHAN                 = 0x80047435
 	PPPIOCCONNECT                    = 0x8004743a
 	PPPIOCDETACH                     = 0x8004743c
 	PPPIOCDISCONN                    = 0x20007439
@@ -190,6 +195,7 @@
 	PPPIOCSPASS                      = 0x80087447
 	PPPIOCSRASYNCMAP                 = 0x80047454
 	PPPIOCSXASYNCMAP                 = 0x8020744f
+	PPPIOCUNBRIDGECHAN               = 0x20007434
 	PPPIOCXFERUNIT                   = 0x2000744e
 	PR_SET_PTRACER_ANY               = 0xffffffff
 	PTRACE_GETFPREGS                 = 0xe
@@ -268,6 +274,7 @@
 	SO_BROADCAST                     = 0x20
 	SO_BSDCOMPAT                     = 0xe
 	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
 	SO_CNX_ADVICE                    = 0x35
 	SO_COOKIE                        = 0x39
 	SO_DETACH_REUSEPORT_BPF          = 0x44
@@ -290,6 +297,7 @@
 	SO_PEERCRED                      = 0x12
 	SO_PEERGROUPS                    = 0x3b
 	SO_PEERSEC                       = 0x1e
+	SO_PREFER_BUSY_POLL              = 0x45
 	SO_PROTOCOL                      = 0x1028
 	SO_RCVBUF                        = 0x1002
 	SO_RCVBUFFORCE                   = 0x21
@@ -483,6 +491,9 @@
 	WORDSIZE                         = 0x20
 	XCASE                            = 0x4
 	XTABS                            = 0x1800
+	_HIDIOCGRAWNAME                  = 0x40804804
+	_HIDIOCGRAWPHYS                  = 0x40404805
+	_HIDIOCGRAWUNIQ                  = 0x40404808
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go
new file mode 100644
index 0000000..d9530e5
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go
@@ -0,0 +1,860 @@
+// mkerrors.sh -Wall -Werror -static -I/tmp/include
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build ppc && linux
+// +build ppc,linux
+
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
+
+package unix
+
+import "syscall"
+
+const (
+	B1000000                         = 0x17
+	B115200                          = 0x11
+	B1152000                         = 0x18
+	B1500000                         = 0x19
+	B2000000                         = 0x1a
+	B230400                          = 0x12
+	B2500000                         = 0x1b
+	B3000000                         = 0x1c
+	B3500000                         = 0x1d
+	B4000000                         = 0x1e
+	B460800                          = 0x13
+	B500000                          = 0x14
+	B57600                           = 0x10
+	B576000                          = 0x15
+	B921600                          = 0x16
+	BLKBSZGET                        = 0x40041270
+	BLKBSZSET                        = 0x80041271
+	BLKFLSBUF                        = 0x20001261
+	BLKFRAGET                        = 0x20001265
+	BLKFRASET                        = 0x20001264
+	BLKGETSIZE                       = 0x20001260
+	BLKGETSIZE64                     = 0x40041272
+	BLKPBSZGET                       = 0x2000127b
+	BLKRAGET                         = 0x20001263
+	BLKRASET                         = 0x20001262
+	BLKROGET                         = 0x2000125e
+	BLKROSET                         = 0x2000125d
+	BLKRRPART                        = 0x2000125f
+	BLKSECTGET                       = 0x20001267
+	BLKSECTSET                       = 0x20001266
+	BLKSSZGET                        = 0x20001268
+	BOTHER                           = 0x1f
+	BS1                              = 0x8000
+	BSDLY                            = 0x8000
+	CBAUD                            = 0xff
+	CBAUDEX                          = 0x0
+	CIBAUD                           = 0xff0000
+	CLOCAL                           = 0x8000
+	CR1                              = 0x1000
+	CR2                              = 0x2000
+	CR3                              = 0x3000
+	CRDLY                            = 0x3000
+	CREAD                            = 0x800
+	CS6                              = 0x100
+	CS7                              = 0x200
+	CS8                              = 0x300
+	CSIZE                            = 0x300
+	CSTOPB                           = 0x400
+	ECHOCTL                          = 0x40
+	ECHOE                            = 0x2
+	ECHOK                            = 0x4
+	ECHOKE                           = 0x1
+	ECHONL                           = 0x10
+	ECHOPRT                          = 0x20
+	EFD_CLOEXEC                      = 0x80000
+	EFD_NONBLOCK                     = 0x800
+	EPOLL_CLOEXEC                    = 0x80000
+	EXTPROC                          = 0x10000000
+	FF1                              = 0x4000
+	FFDLY                            = 0x4000
+	FICLONE                          = 0x80049409
+	FICLONERANGE                     = 0x8020940d
+	FLUSHO                           = 0x800000
+	FS_IOC_ENABLE_VERITY             = 0x80806685
+	FS_IOC_GETFLAGS                  = 0x40046601
+	FS_IOC_GET_ENCRYPTION_NONCE      = 0x4010661b
+	FS_IOC_GET_ENCRYPTION_POLICY     = 0x800c6615
+	FS_IOC_GET_ENCRYPTION_PWSALT     = 0x80106614
+	FS_IOC_SETFLAGS                  = 0x80046602
+	FS_IOC_SET_ENCRYPTION_POLICY     = 0x400c6613
+	F_GETLK                          = 0xc
+	F_GETLK64                        = 0xc
+	F_GETOWN                         = 0x9
+	F_RDLCK                          = 0x0
+	F_SETLK                          = 0xd
+	F_SETLK64                        = 0xd
+	F_SETLKW                         = 0xe
+	F_SETLKW64                       = 0xe
+	F_SETOWN                         = 0x8
+	F_UNLCK                          = 0x2
+	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x40084803
+	HIDIOCGRDESC                     = 0x50044802
+	HIDIOCGRDESCSIZE                 = 0x40044801
+	HUPCL                            = 0x4000
+	ICANON                           = 0x100
+	IEXTEN                           = 0x400
+	IN_CLOEXEC                       = 0x80000
+	IN_NONBLOCK                      = 0x800
+	IOCTL_VM_SOCKETS_GET_LOCAL_CID   = 0x200007b9
+	ISIG                             = 0x80
+	IUCLC                            = 0x1000
+	IXOFF                            = 0x400
+	IXON                             = 0x200
+	MAP_ANON                         = 0x20
+	MAP_ANONYMOUS                    = 0x20
+	MAP_DENYWRITE                    = 0x800
+	MAP_EXECUTABLE                   = 0x1000
+	MAP_GROWSDOWN                    = 0x100
+	MAP_HUGETLB                      = 0x40000
+	MAP_LOCKED                       = 0x80
+	MAP_NONBLOCK                     = 0x10000
+	MAP_NORESERVE                    = 0x40
+	MAP_POPULATE                     = 0x8000
+	MAP_STACK                        = 0x20000
+	MAP_SYNC                         = 0x80000
+	MCL_CURRENT                      = 0x2000
+	MCL_FUTURE                       = 0x4000
+	MCL_ONFAULT                      = 0x8000
+	NFDBITS                          = 0x20
+	NL2                              = 0x200
+	NL3                              = 0x300
+	NLDLY                            = 0x300
+	NOFLSH                           = 0x80000000
+	NS_GET_NSTYPE                    = 0x2000b703
+	NS_GET_OWNER_UID                 = 0x2000b704
+	NS_GET_PARENT                    = 0x2000b702
+	NS_GET_USERNS                    = 0x2000b701
+	OLCUC                            = 0x4
+	ONLCR                            = 0x2
+	O_APPEND                         = 0x400
+	O_ASYNC                          = 0x2000
+	O_CLOEXEC                        = 0x80000
+	O_CREAT                          = 0x40
+	O_DIRECT                         = 0x20000
+	O_DIRECTORY                      = 0x4000
+	O_DSYNC                          = 0x1000
+	O_EXCL                           = 0x80
+	O_FSYNC                          = 0x101000
+	O_LARGEFILE                      = 0x10000
+	O_NDELAY                         = 0x800
+	O_NOATIME                        = 0x40000
+	O_NOCTTY                         = 0x100
+	O_NOFOLLOW                       = 0x8000
+	O_NONBLOCK                       = 0x800
+	O_PATH                           = 0x200000
+	O_RSYNC                          = 0x101000
+	O_SYNC                           = 0x101000
+	O_TMPFILE                        = 0x404000
+	O_TRUNC                          = 0x200
+	PARENB                           = 0x1000
+	PARODD                           = 0x2000
+	PENDIN                           = 0x20000000
+	PERF_EVENT_IOC_DISABLE           = 0x20002401
+	PERF_EVENT_IOC_ENABLE            = 0x20002400
+	PERF_EVENT_IOC_ID                = 0x40042407
+	PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x8004240b
+	PERF_EVENT_IOC_PAUSE_OUTPUT      = 0x80042409
+	PERF_EVENT_IOC_PERIOD            = 0x80082404
+	PERF_EVENT_IOC_QUERY_BPF         = 0xc004240a
+	PERF_EVENT_IOC_REFRESH           = 0x20002402
+	PERF_EVENT_IOC_RESET             = 0x20002403
+	PERF_EVENT_IOC_SET_BPF           = 0x80042408
+	PERF_EVENT_IOC_SET_FILTER        = 0x80042406
+	PERF_EVENT_IOC_SET_OUTPUT        = 0x20002405
+	PPPIOCATTACH                     = 0x8004743d
+	PPPIOCATTCHAN                    = 0x80047438
+	PPPIOCBRIDGECHAN                 = 0x80047435
+	PPPIOCCONNECT                    = 0x8004743a
+	PPPIOCDETACH                     = 0x8004743c
+	PPPIOCDISCONN                    = 0x20007439
+	PPPIOCGASYNCMAP                  = 0x40047458
+	PPPIOCGCHAN                      = 0x40047437
+	PPPIOCGDEBUG                     = 0x40047441
+	PPPIOCGFLAGS                     = 0x4004745a
+	PPPIOCGIDLE                      = 0x4008743f
+	PPPIOCGIDLE32                    = 0x4008743f
+	PPPIOCGIDLE64                    = 0x4010743f
+	PPPIOCGL2TPSTATS                 = 0x40487436
+	PPPIOCGMRU                       = 0x40047453
+	PPPIOCGRASYNCMAP                 = 0x40047455
+	PPPIOCGUNIT                      = 0x40047456
+	PPPIOCGXASYNCMAP                 = 0x40207450
+	PPPIOCSACTIVE                    = 0x80087446
+	PPPIOCSASYNCMAP                  = 0x80047457
+	PPPIOCSCOMPRESS                  = 0x800c744d
+	PPPIOCSDEBUG                     = 0x80047440
+	PPPIOCSFLAGS                     = 0x80047459
+	PPPIOCSMAXCID                    = 0x80047451
+	PPPIOCSMRRU                      = 0x8004743b
+	PPPIOCSMRU                       = 0x80047452
+	PPPIOCSNPMODE                    = 0x8008744b
+	PPPIOCSPASS                      = 0x80087447
+	PPPIOCSRASYNCMAP                 = 0x80047454
+	PPPIOCSXASYNCMAP                 = 0x8020744f
+	PPPIOCUNBRIDGECHAN               = 0x20007434
+	PPPIOCXFERUNIT                   = 0x2000744e
+	PROT_SAO                         = 0x10
+	PR_SET_PTRACER_ANY               = 0xffffffff
+	PTRACE_GETEVRREGS                = 0x14
+	PTRACE_GETFPREGS                 = 0xe
+	PTRACE_GETREGS64                 = 0x16
+	PTRACE_GETVRREGS                 = 0x12
+	PTRACE_GETVSRREGS                = 0x1b
+	PTRACE_GET_DEBUGREG              = 0x19
+	PTRACE_SETEVRREGS                = 0x15
+	PTRACE_SETFPREGS                 = 0xf
+	PTRACE_SETREGS64                 = 0x17
+	PTRACE_SETVRREGS                 = 0x13
+	PTRACE_SETVSRREGS                = 0x1c
+	PTRACE_SET_DEBUGREG              = 0x1a
+	PTRACE_SINGLEBLOCK               = 0x100
+	PTRACE_SYSEMU                    = 0x1d
+	PTRACE_SYSEMU_SINGLESTEP         = 0x1e
+	PT_CCR                           = 0x26
+	PT_CTR                           = 0x23
+	PT_DAR                           = 0x29
+	PT_DSCR                          = 0x2c
+	PT_DSISR                         = 0x2a
+	PT_FPR0                          = 0x30
+	PT_FPR31                         = 0x6e
+	PT_FPSCR                         = 0x71
+	PT_LNK                           = 0x24
+	PT_MQ                            = 0x27
+	PT_MSR                           = 0x21
+	PT_NIP                           = 0x20
+	PT_ORIG_R3                       = 0x22
+	PT_R0                            = 0x0
+	PT_R1                            = 0x1
+	PT_R10                           = 0xa
+	PT_R11                           = 0xb
+	PT_R12                           = 0xc
+	PT_R13                           = 0xd
+	PT_R14                           = 0xe
+	PT_R15                           = 0xf
+	PT_R16                           = 0x10
+	PT_R17                           = 0x11
+	PT_R18                           = 0x12
+	PT_R19                           = 0x13
+	PT_R2                            = 0x2
+	PT_R20                           = 0x14
+	PT_R21                           = 0x15
+	PT_R22                           = 0x16
+	PT_R23                           = 0x17
+	PT_R24                           = 0x18
+	PT_R25                           = 0x19
+	PT_R26                           = 0x1a
+	PT_R27                           = 0x1b
+	PT_R28                           = 0x1c
+	PT_R29                           = 0x1d
+	PT_R3                            = 0x3
+	PT_R30                           = 0x1e
+	PT_R31                           = 0x1f
+	PT_R4                            = 0x4
+	PT_R5                            = 0x5
+	PT_R6                            = 0x6
+	PT_R7                            = 0x7
+	PT_R8                            = 0x8
+	PT_R9                            = 0x9
+	PT_REGS_COUNT                    = 0x2c
+	PT_RESULT                        = 0x2b
+	PT_TRAP                          = 0x28
+	PT_XER                           = 0x25
+	RLIMIT_AS                        = 0x9
+	RLIMIT_MEMLOCK                   = 0x8
+	RLIMIT_NOFILE                    = 0x7
+	RLIMIT_NPROC                     = 0x6
+	RLIMIT_RSS                       = 0x5
+	RNDADDENTROPY                    = 0x80085203
+	RNDADDTOENTCNT                   = 0x80045201
+	RNDCLEARPOOL                     = 0x20005206
+	RNDGETENTCNT                     = 0x40045200
+	RNDGETPOOL                       = 0x40085202
+	RNDRESEEDCRNG                    = 0x20005207
+	RNDZAPENTCNT                     = 0x20005204
+	RTC_AIE_OFF                      = 0x20007002
+	RTC_AIE_ON                       = 0x20007001
+	RTC_ALM_READ                     = 0x40247008
+	RTC_ALM_SET                      = 0x80247007
+	RTC_EPOCH_READ                   = 0x4004700d
+	RTC_EPOCH_SET                    = 0x8004700e
+	RTC_IRQP_READ                    = 0x4004700b
+	RTC_IRQP_SET                     = 0x8004700c
+	RTC_PIE_OFF                      = 0x20007006
+	RTC_PIE_ON                       = 0x20007005
+	RTC_PLL_GET                      = 0x401c7011
+	RTC_PLL_SET                      = 0x801c7012
+	RTC_RD_TIME                      = 0x40247009
+	RTC_SET_TIME                     = 0x8024700a
+	RTC_UIE_OFF                      = 0x20007004
+	RTC_UIE_ON                       = 0x20007003
+	RTC_VL_CLR                       = 0x20007014
+	RTC_VL_READ                      = 0x40047013
+	RTC_WIE_OFF                      = 0x20007010
+	RTC_WIE_ON                       = 0x2000700f
+	RTC_WKALM_RD                     = 0x40287010
+	RTC_WKALM_SET                    = 0x8028700f
+	SCM_TIMESTAMPING                 = 0x25
+	SCM_TIMESTAMPING_OPT_STATS       = 0x36
+	SCM_TIMESTAMPING_PKTINFO         = 0x3a
+	SCM_TIMESTAMPNS                  = 0x23
+	SCM_TXTIME                       = 0x3d
+	SCM_WIFI_STATUS                  = 0x29
+	SFD_CLOEXEC                      = 0x80000
+	SFD_NONBLOCK                     = 0x800
+	SIOCATMARK                       = 0x8905
+	SIOCGPGRP                        = 0x8904
+	SIOCGSTAMPNS_NEW                 = 0x40108907
+	SIOCGSTAMP_NEW                   = 0x40108906
+	SIOCINQ                          = 0x4004667f
+	SIOCOUTQ                         = 0x40047473
+	SIOCSPGRP                        = 0x8902
+	SOCK_CLOEXEC                     = 0x80000
+	SOCK_DGRAM                       = 0x2
+	SOCK_NONBLOCK                    = 0x800
+	SOCK_STREAM                      = 0x1
+	SOL_SOCKET                       = 0x1
+	SO_ACCEPTCONN                    = 0x1e
+	SO_ATTACH_BPF                    = 0x32
+	SO_ATTACH_REUSEPORT_CBPF         = 0x33
+	SO_ATTACH_REUSEPORT_EBPF         = 0x34
+	SO_BINDTODEVICE                  = 0x19
+	SO_BINDTOIFINDEX                 = 0x3e
+	SO_BPF_EXTENSIONS                = 0x30
+	SO_BROADCAST                     = 0x6
+	SO_BSDCOMPAT                     = 0xe
+	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
+	SO_CNX_ADVICE                    = 0x35
+	SO_COOKIE                        = 0x39
+	SO_DETACH_REUSEPORT_BPF          = 0x44
+	SO_DOMAIN                        = 0x27
+	SO_DONTROUTE                     = 0x5
+	SO_ERROR                         = 0x4
+	SO_INCOMING_CPU                  = 0x31
+	SO_INCOMING_NAPI_ID              = 0x38
+	SO_KEEPALIVE                     = 0x9
+	SO_LINGER                        = 0xd
+	SO_LOCK_FILTER                   = 0x2c
+	SO_MARK                          = 0x24
+	SO_MAX_PACING_RATE               = 0x2f
+	SO_MEMINFO                       = 0x37
+	SO_NOFCS                         = 0x2b
+	SO_OOBINLINE                     = 0xa
+	SO_PASSCRED                      = 0x14
+	SO_PASSSEC                       = 0x22
+	SO_PEEK_OFF                      = 0x2a
+	SO_PEERCRED                      = 0x15
+	SO_PEERGROUPS                    = 0x3b
+	SO_PEERSEC                       = 0x1f
+	SO_PREFER_BUSY_POLL              = 0x45
+	SO_PROTOCOL                      = 0x26
+	SO_RCVBUF                        = 0x8
+	SO_RCVBUFFORCE                   = 0x21
+	SO_RCVLOWAT                      = 0x10
+	SO_RCVTIMEO                      = 0x12
+	SO_RCVTIMEO_NEW                  = 0x42
+	SO_RCVTIMEO_OLD                  = 0x12
+	SO_REUSEADDR                     = 0x2
+	SO_REUSEPORT                     = 0xf
+	SO_RXQ_OVFL                      = 0x28
+	SO_SECURITY_AUTHENTICATION       = 0x16
+	SO_SECURITY_ENCRYPTION_NETWORK   = 0x18
+	SO_SECURITY_ENCRYPTION_TRANSPORT = 0x17
+	SO_SELECT_ERR_QUEUE              = 0x2d
+	SO_SNDBUF                        = 0x7
+	SO_SNDBUFFORCE                   = 0x20
+	SO_SNDLOWAT                      = 0x11
+	SO_SNDTIMEO                      = 0x13
+	SO_SNDTIMEO_NEW                  = 0x43
+	SO_SNDTIMEO_OLD                  = 0x13
+	SO_TIMESTAMPING                  = 0x25
+	SO_TIMESTAMPING_NEW              = 0x41
+	SO_TIMESTAMPING_OLD              = 0x25
+	SO_TIMESTAMPNS                   = 0x23
+	SO_TIMESTAMPNS_NEW               = 0x40
+	SO_TIMESTAMPNS_OLD               = 0x23
+	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXTIME                        = 0x3d
+	SO_TYPE                          = 0x3
+	SO_WIFI_STATUS                   = 0x29
+	SO_ZEROCOPY                      = 0x3c
+	TAB1                             = 0x400
+	TAB2                             = 0x800
+	TAB3                             = 0xc00
+	TABDLY                           = 0xc00
+	TCFLSH                           = 0x2000741f
+	TCGETA                           = 0x40147417
+	TCGETS                           = 0x402c7413
+	TCSAFLUSH                        = 0x2
+	TCSBRK                           = 0x2000741d
+	TCSBRKP                          = 0x5425
+	TCSETA                           = 0x80147418
+	TCSETAF                          = 0x8014741c
+	TCSETAW                          = 0x80147419
+	TCSETS                           = 0x802c7414
+	TCSETSF                          = 0x802c7416
+	TCSETSW                          = 0x802c7415
+	TCXONC                           = 0x2000741e
+	TFD_CLOEXEC                      = 0x80000
+	TFD_NONBLOCK                     = 0x800
+	TIOCCBRK                         = 0x5428
+	TIOCCONS                         = 0x541d
+	TIOCEXCL                         = 0x540c
+	TIOCGDEV                         = 0x40045432
+	TIOCGETC                         = 0x40067412
+	TIOCGETD                         = 0x5424
+	TIOCGETP                         = 0x40067408
+	TIOCGEXCL                        = 0x40045440
+	TIOCGICOUNT                      = 0x545d
+	TIOCGISO7816                     = 0x40285442
+	TIOCGLCKTRMIOS                   = 0x5456
+	TIOCGLTC                         = 0x40067474
+	TIOCGPGRP                        = 0x40047477
+	TIOCGPKT                         = 0x40045438
+	TIOCGPTLCK                       = 0x40045439
+	TIOCGPTN                         = 0x40045430
+	TIOCGPTPEER                      = 0x20005441
+	TIOCGRS485                       = 0x542e
+	TIOCGSERIAL                      = 0x541e
+	TIOCGSID                         = 0x5429
+	TIOCGSOFTCAR                     = 0x5419
+	TIOCGWINSZ                       = 0x40087468
+	TIOCINQ                          = 0x4004667f
+	TIOCLINUX                        = 0x541c
+	TIOCMBIC                         = 0x5417
+	TIOCMBIS                         = 0x5416
+	TIOCMGET                         = 0x5415
+	TIOCMIWAIT                       = 0x545c
+	TIOCMSET                         = 0x5418
+	TIOCM_CAR                        = 0x40
+	TIOCM_CD                         = 0x40
+	TIOCM_CTS                        = 0x20
+	TIOCM_DSR                        = 0x100
+	TIOCM_LOOP                       = 0x8000
+	TIOCM_OUT1                       = 0x2000
+	TIOCM_OUT2                       = 0x4000
+	TIOCM_RI                         = 0x80
+	TIOCM_RNG                        = 0x80
+	TIOCM_SR                         = 0x10
+	TIOCM_ST                         = 0x8
+	TIOCNOTTY                        = 0x5422
+	TIOCNXCL                         = 0x540d
+	TIOCOUTQ                         = 0x40047473
+	TIOCPKT                          = 0x5420
+	TIOCSBRK                         = 0x5427
+	TIOCSCTTY                        = 0x540e
+	TIOCSERCONFIG                    = 0x5453
+	TIOCSERGETLSR                    = 0x5459
+	TIOCSERGETMULTI                  = 0x545a
+	TIOCSERGSTRUCT                   = 0x5458
+	TIOCSERGWILD                     = 0x5454
+	TIOCSERSETMULTI                  = 0x545b
+	TIOCSERSWILD                     = 0x5455
+	TIOCSER_TEMT                     = 0x1
+	TIOCSETC                         = 0x80067411
+	TIOCSETD                         = 0x5423
+	TIOCSETN                         = 0x8006740a
+	TIOCSETP                         = 0x80067409
+	TIOCSIG                          = 0x80045436
+	TIOCSISO7816                     = 0xc0285443
+	TIOCSLCKTRMIOS                   = 0x5457
+	TIOCSLTC                         = 0x80067475
+	TIOCSPGRP                        = 0x80047476
+	TIOCSPTLCK                       = 0x80045431
+	TIOCSRS485                       = 0x542f
+	TIOCSSERIAL                      = 0x541f
+	TIOCSSOFTCAR                     = 0x541a
+	TIOCSTART                        = 0x2000746e
+	TIOCSTI                          = 0x5412
+	TIOCSTOP                         = 0x2000746f
+	TIOCSWINSZ                       = 0x80087467
+	TIOCVHANGUP                      = 0x5437
+	TOSTOP                           = 0x400000
+	TUNATTACHFILTER                  = 0x800854d5
+	TUNDETACHFILTER                  = 0x800854d6
+	TUNGETDEVNETNS                   = 0x200054e3
+	TUNGETFEATURES                   = 0x400454cf
+	TUNGETFILTER                     = 0x400854db
+	TUNGETIFF                        = 0x400454d2
+	TUNGETSNDBUF                     = 0x400454d3
+	TUNGETVNETBE                     = 0x400454df
+	TUNGETVNETHDRSZ                  = 0x400454d7
+	TUNGETVNETLE                     = 0x400454dd
+	TUNSETCARRIER                    = 0x800454e2
+	TUNSETDEBUG                      = 0x800454c9
+	TUNSETFILTEREBPF                 = 0x400454e1
+	TUNSETGROUP                      = 0x800454ce
+	TUNSETIFF                        = 0x800454ca
+	TUNSETIFINDEX                    = 0x800454da
+	TUNSETLINK                       = 0x800454cd
+	TUNSETNOCSUM                     = 0x800454c8
+	TUNSETOFFLOAD                    = 0x800454d0
+	TUNSETOWNER                      = 0x800454cc
+	TUNSETPERSIST                    = 0x800454cb
+	TUNSETQUEUE                      = 0x800454d9
+	TUNSETSNDBUF                     = 0x800454d4
+	TUNSETSTEERINGEBPF               = 0x400454e0
+	TUNSETTXFILTER                   = 0x800454d1
+	TUNSETVNETBE                     = 0x800454de
+	TUNSETVNETHDRSZ                  = 0x800454d8
+	TUNSETVNETLE                     = 0x800454dc
+	UBI_IOCATT                       = 0x80186f40
+	UBI_IOCDET                       = 0x80046f41
+	UBI_IOCEBCH                      = 0x80044f02
+	UBI_IOCEBER                      = 0x80044f01
+	UBI_IOCEBISMAP                   = 0x40044f05
+	UBI_IOCEBMAP                     = 0x80084f03
+	UBI_IOCEBUNMAP                   = 0x80044f04
+	UBI_IOCMKVOL                     = 0x80986f00
+	UBI_IOCRMVOL                     = 0x80046f01
+	UBI_IOCRNVOL                     = 0x91106f03
+	UBI_IOCRPEB                      = 0x80046f04
+	UBI_IOCRSVOL                     = 0x800c6f02
+	UBI_IOCSETVOLPROP                = 0x80104f06
+	UBI_IOCSPEB                      = 0x80046f05
+	UBI_IOCVOLCRBLK                  = 0x80804f07
+	UBI_IOCVOLRMBLK                  = 0x20004f08
+	UBI_IOCVOLUP                     = 0x80084f00
+	VDISCARD                         = 0x10
+	VEOF                             = 0x4
+	VEOL                             = 0x6
+	VEOL2                            = 0x8
+	VMIN                             = 0x5
+	VREPRINT                         = 0xb
+	VSTART                           = 0xd
+	VSTOP                            = 0xe
+	VSUSP                            = 0xc
+	VSWTC                            = 0x9
+	VT1                              = 0x10000
+	VTDLY                            = 0x10000
+	VTIME                            = 0x7
+	VWERASE                          = 0xa
+	WDIOC_GETBOOTSTATUS              = 0x40045702
+	WDIOC_GETPRETIMEOUT              = 0x40045709
+	WDIOC_GETSTATUS                  = 0x40045701
+	WDIOC_GETSUPPORT                 = 0x40285700
+	WDIOC_GETTEMP                    = 0x40045703
+	WDIOC_GETTIMELEFT                = 0x4004570a
+	WDIOC_GETTIMEOUT                 = 0x40045707
+	WDIOC_KEEPALIVE                  = 0x40045705
+	WDIOC_SETOPTIONS                 = 0x40045704
+	WORDSIZE                         = 0x20
+	XCASE                            = 0x4000
+	XTABS                            = 0xc00
+	_HIDIOCGRAWNAME                  = 0x40804804
+	_HIDIOCGRAWPHYS                  = 0x40404805
+	_HIDIOCGRAWUNIQ                  = 0x40404808
+)
+
+// Errors
+const (
+	EADDRINUSE      = syscall.Errno(0x62)
+	EADDRNOTAVAIL   = syscall.Errno(0x63)
+	EADV            = syscall.Errno(0x44)
+	EAFNOSUPPORT    = syscall.Errno(0x61)
+	EALREADY        = syscall.Errno(0x72)
+	EBADE           = syscall.Errno(0x34)
+	EBADFD          = syscall.Errno(0x4d)
+	EBADMSG         = syscall.Errno(0x4a)
+	EBADR           = syscall.Errno(0x35)
+	EBADRQC         = syscall.Errno(0x38)
+	EBADSLT         = syscall.Errno(0x39)
+	EBFONT          = syscall.Errno(0x3b)
+	ECANCELED       = syscall.Errno(0x7d)
+	ECHRNG          = syscall.Errno(0x2c)
+	ECOMM           = syscall.Errno(0x46)
+	ECONNABORTED    = syscall.Errno(0x67)
+	ECONNREFUSED    = syscall.Errno(0x6f)
+	ECONNRESET      = syscall.Errno(0x68)
+	EDEADLK         = syscall.Errno(0x23)
+	EDEADLOCK       = syscall.Errno(0x3a)
+	EDESTADDRREQ    = syscall.Errno(0x59)
+	EDOTDOT         = syscall.Errno(0x49)
+	EDQUOT          = syscall.Errno(0x7a)
+	EHOSTDOWN       = syscall.Errno(0x70)
+	EHOSTUNREACH    = syscall.Errno(0x71)
+	EHWPOISON       = syscall.Errno(0x85)
+	EIDRM           = syscall.Errno(0x2b)
+	EILSEQ          = syscall.Errno(0x54)
+	EINPROGRESS     = syscall.Errno(0x73)
+	EISCONN         = syscall.Errno(0x6a)
+	EISNAM          = syscall.Errno(0x78)
+	EKEYEXPIRED     = syscall.Errno(0x7f)
+	EKEYREJECTED    = syscall.Errno(0x81)
+	EKEYREVOKED     = syscall.Errno(0x80)
+	EL2HLT          = syscall.Errno(0x33)
+	EL2NSYNC        = syscall.Errno(0x2d)
+	EL3HLT          = syscall.Errno(0x2e)
+	EL3RST          = syscall.Errno(0x2f)
+	ELIBACC         = syscall.Errno(0x4f)
+	ELIBBAD         = syscall.Errno(0x50)
+	ELIBEXEC        = syscall.Errno(0x53)
+	ELIBMAX         = syscall.Errno(0x52)
+	ELIBSCN         = syscall.Errno(0x51)
+	ELNRNG          = syscall.Errno(0x30)
+	ELOOP           = syscall.Errno(0x28)
+	EMEDIUMTYPE     = syscall.Errno(0x7c)
+	EMSGSIZE        = syscall.Errno(0x5a)
+	EMULTIHOP       = syscall.Errno(0x48)
+	ENAMETOOLONG    = syscall.Errno(0x24)
+	ENAVAIL         = syscall.Errno(0x77)
+	ENETDOWN        = syscall.Errno(0x64)
+	ENETRESET       = syscall.Errno(0x66)
+	ENETUNREACH     = syscall.Errno(0x65)
+	ENOANO          = syscall.Errno(0x37)
+	ENOBUFS         = syscall.Errno(0x69)
+	ENOCSI          = syscall.Errno(0x32)
+	ENODATA         = syscall.Errno(0x3d)
+	ENOKEY          = syscall.Errno(0x7e)
+	ENOLCK          = syscall.Errno(0x25)
+	ENOLINK         = syscall.Errno(0x43)
+	ENOMEDIUM       = syscall.Errno(0x7b)
+	ENOMSG          = syscall.Errno(0x2a)
+	ENONET          = syscall.Errno(0x40)
+	ENOPKG          = syscall.Errno(0x41)
+	ENOPROTOOPT     = syscall.Errno(0x5c)
+	ENOSR           = syscall.Errno(0x3f)
+	ENOSTR          = syscall.Errno(0x3c)
+	ENOSYS          = syscall.Errno(0x26)
+	ENOTCONN        = syscall.Errno(0x6b)
+	ENOTEMPTY       = syscall.Errno(0x27)
+	ENOTNAM         = syscall.Errno(0x76)
+	ENOTRECOVERABLE = syscall.Errno(0x83)
+	ENOTSOCK        = syscall.Errno(0x58)
+	ENOTSUP         = syscall.Errno(0x5f)
+	ENOTUNIQ        = syscall.Errno(0x4c)
+	EOPNOTSUPP      = syscall.Errno(0x5f)
+	EOVERFLOW       = syscall.Errno(0x4b)
+	EOWNERDEAD      = syscall.Errno(0x82)
+	EPFNOSUPPORT    = syscall.Errno(0x60)
+	EPROTO          = syscall.Errno(0x47)
+	EPROTONOSUPPORT = syscall.Errno(0x5d)
+	EPROTOTYPE      = syscall.Errno(0x5b)
+	EREMCHG         = syscall.Errno(0x4e)
+	EREMOTE         = syscall.Errno(0x42)
+	EREMOTEIO       = syscall.Errno(0x79)
+	ERESTART        = syscall.Errno(0x55)
+	ERFKILL         = syscall.Errno(0x84)
+	ESHUTDOWN       = syscall.Errno(0x6c)
+	ESOCKTNOSUPPORT = syscall.Errno(0x5e)
+	ESRMNT          = syscall.Errno(0x45)
+	ESTALE          = syscall.Errno(0x74)
+	ESTRPIPE        = syscall.Errno(0x56)
+	ETIME           = syscall.Errno(0x3e)
+	ETIMEDOUT       = syscall.Errno(0x6e)
+	ETOOMANYREFS    = syscall.Errno(0x6d)
+	EUCLEAN         = syscall.Errno(0x75)
+	EUNATCH         = syscall.Errno(0x31)
+	EUSERS          = syscall.Errno(0x57)
+	EXFULL          = syscall.Errno(0x36)
+)
+
+// Signals
+const (
+	SIGBUS    = syscall.Signal(0x7)
+	SIGCHLD   = syscall.Signal(0x11)
+	SIGCLD    = syscall.Signal(0x11)
+	SIGCONT   = syscall.Signal(0x12)
+	SIGIO     = syscall.Signal(0x1d)
+	SIGPOLL   = syscall.Signal(0x1d)
+	SIGPROF   = syscall.Signal(0x1b)
+	SIGPWR    = syscall.Signal(0x1e)
+	SIGSTKFLT = syscall.Signal(0x10)
+	SIGSTOP   = syscall.Signal(0x13)
+	SIGSYS    = syscall.Signal(0x1f)
+	SIGTSTP   = syscall.Signal(0x14)
+	SIGTTIN   = syscall.Signal(0x15)
+	SIGTTOU   = syscall.Signal(0x16)
+	SIGURG    = syscall.Signal(0x17)
+	SIGUSR1   = syscall.Signal(0xa)
+	SIGUSR2   = syscall.Signal(0xc)
+	SIGVTALRM = syscall.Signal(0x1a)
+	SIGWINCH  = syscall.Signal(0x1c)
+	SIGXCPU   = syscall.Signal(0x18)
+	SIGXFSZ   = syscall.Signal(0x19)
+)
+
+// Error table
+var errorList = [...]struct {
+	num  syscall.Errno
+	name string
+	desc string
+}{
+	{1, "EPERM", "operation not permitted"},
+	{2, "ENOENT", "no such file or directory"},
+	{3, "ESRCH", "no such process"},
+	{4, "EINTR", "interrupted system call"},
+	{5, "EIO", "input/output error"},
+	{6, "ENXIO", "no such device or address"},
+	{7, "E2BIG", "argument list too long"},
+	{8, "ENOEXEC", "exec format error"},
+	{9, "EBADF", "bad file descriptor"},
+	{10, "ECHILD", "no child processes"},
+	{11, "EAGAIN", "resource temporarily unavailable"},
+	{12, "ENOMEM", "cannot allocate memory"},
+	{13, "EACCES", "permission denied"},
+	{14, "EFAULT", "bad address"},
+	{15, "ENOTBLK", "block device required"},
+	{16, "EBUSY", "device or resource busy"},
+	{17, "EEXIST", "file exists"},
+	{18, "EXDEV", "invalid cross-device link"},
+	{19, "ENODEV", "no such device"},
+	{20, "ENOTDIR", "not a directory"},
+	{21, "EISDIR", "is a directory"},
+	{22, "EINVAL", "invalid argument"},
+	{23, "ENFILE", "too many open files in system"},
+	{24, "EMFILE", "too many open files"},
+	{25, "ENOTTY", "inappropriate ioctl for device"},
+	{26, "ETXTBSY", "text file busy"},
+	{27, "EFBIG", "file too large"},
+	{28, "ENOSPC", "no space left on device"},
+	{29, "ESPIPE", "illegal seek"},
+	{30, "EROFS", "read-only file system"},
+	{31, "EMLINK", "too many links"},
+	{32, "EPIPE", "broken pipe"},
+	{33, "EDOM", "numerical argument out of domain"},
+	{34, "ERANGE", "numerical result out of range"},
+	{35, "EDEADLK", "resource deadlock avoided"},
+	{36, "ENAMETOOLONG", "file name too long"},
+	{37, "ENOLCK", "no locks available"},
+	{38, "ENOSYS", "function not implemented"},
+	{39, "ENOTEMPTY", "directory not empty"},
+	{40, "ELOOP", "too many levels of symbolic links"},
+	{42, "ENOMSG", "no message of desired type"},
+	{43, "EIDRM", "identifier removed"},
+	{44, "ECHRNG", "channel number out of range"},
+	{45, "EL2NSYNC", "level 2 not synchronized"},
+	{46, "EL3HLT", "level 3 halted"},
+	{47, "EL3RST", "level 3 reset"},
+	{48, "ELNRNG", "link number out of range"},
+	{49, "EUNATCH", "protocol driver not attached"},
+	{50, "ENOCSI", "no CSI structure available"},
+	{51, "EL2HLT", "level 2 halted"},
+	{52, "EBADE", "invalid exchange"},
+	{53, "EBADR", "invalid request descriptor"},
+	{54, "EXFULL", "exchange full"},
+	{55, "ENOANO", "no anode"},
+	{56, "EBADRQC", "invalid request code"},
+	{57, "EBADSLT", "invalid slot"},
+	{58, "EDEADLOCK", "file locking deadlock error"},
+	{59, "EBFONT", "bad font file format"},
+	{60, "ENOSTR", "device not a stream"},
+	{61, "ENODATA", "no data available"},
+	{62, "ETIME", "timer expired"},
+	{63, "ENOSR", "out of streams resources"},
+	{64, "ENONET", "machine is not on the network"},
+	{65, "ENOPKG", "package not installed"},
+	{66, "EREMOTE", "object is remote"},
+	{67, "ENOLINK", "link has been severed"},
+	{68, "EADV", "advertise error"},
+	{69, "ESRMNT", "srmount error"},
+	{70, "ECOMM", "communication error on send"},
+	{71, "EPROTO", "protocol error"},
+	{72, "EMULTIHOP", "multihop attempted"},
+	{73, "EDOTDOT", "RFS specific error"},
+	{74, "EBADMSG", "bad message"},
+	{75, "EOVERFLOW", "value too large for defined data type"},
+	{76, "ENOTUNIQ", "name not unique on network"},
+	{77, "EBADFD", "file descriptor in bad state"},
+	{78, "EREMCHG", "remote address changed"},
+	{79, "ELIBACC", "can not access a needed shared library"},
+	{80, "ELIBBAD", "accessing a corrupted shared library"},
+	{81, "ELIBSCN", ".lib section in a.out corrupted"},
+	{82, "ELIBMAX", "attempting to link in too many shared libraries"},
+	{83, "ELIBEXEC", "cannot exec a shared library directly"},
+	{84, "EILSEQ", "invalid or incomplete multibyte or wide character"},
+	{85, "ERESTART", "interrupted system call should be restarted"},
+	{86, "ESTRPIPE", "streams pipe error"},
+	{87, "EUSERS", "too many users"},
+	{88, "ENOTSOCK", "socket operation on non-socket"},
+	{89, "EDESTADDRREQ", "destination address required"},
+	{90, "EMSGSIZE", "message too long"},
+	{91, "EPROTOTYPE", "protocol wrong type for socket"},
+	{92, "ENOPROTOOPT", "protocol not available"},
+	{93, "EPROTONOSUPPORT", "protocol not supported"},
+	{94, "ESOCKTNOSUPPORT", "socket type not supported"},
+	{95, "ENOTSUP", "operation not supported"},
+	{96, "EPFNOSUPPORT", "protocol family not supported"},
+	{97, "EAFNOSUPPORT", "address family not supported by protocol"},
+	{98, "EADDRINUSE", "address already in use"},
+	{99, "EADDRNOTAVAIL", "cannot assign requested address"},
+	{100, "ENETDOWN", "network is down"},
+	{101, "ENETUNREACH", "network is unreachable"},
+	{102, "ENETRESET", "network dropped connection on reset"},
+	{103, "ECONNABORTED", "software caused connection abort"},
+	{104, "ECONNRESET", "connection reset by peer"},
+	{105, "ENOBUFS", "no buffer space available"},
+	{106, "EISCONN", "transport endpoint is already connected"},
+	{107, "ENOTCONN", "transport endpoint is not connected"},
+	{108, "ESHUTDOWN", "cannot send after transport endpoint shutdown"},
+	{109, "ETOOMANYREFS", "too many references: cannot splice"},
+	{110, "ETIMEDOUT", "connection timed out"},
+	{111, "ECONNREFUSED", "connection refused"},
+	{112, "EHOSTDOWN", "host is down"},
+	{113, "EHOSTUNREACH", "no route to host"},
+	{114, "EALREADY", "operation already in progress"},
+	{115, "EINPROGRESS", "operation now in progress"},
+	{116, "ESTALE", "stale file handle"},
+	{117, "EUCLEAN", "structure needs cleaning"},
+	{118, "ENOTNAM", "not a XENIX named type file"},
+	{119, "ENAVAIL", "no XENIX semaphores available"},
+	{120, "EISNAM", "is a named type file"},
+	{121, "EREMOTEIO", "remote I/O error"},
+	{122, "EDQUOT", "disk quota exceeded"},
+	{123, "ENOMEDIUM", "no medium found"},
+	{124, "EMEDIUMTYPE", "wrong medium type"},
+	{125, "ECANCELED", "operation canceled"},
+	{126, "ENOKEY", "required key not available"},
+	{127, "EKEYEXPIRED", "key has expired"},
+	{128, "EKEYREVOKED", "key has been revoked"},
+	{129, "EKEYREJECTED", "key was rejected by service"},
+	{130, "EOWNERDEAD", "owner died"},
+	{131, "ENOTRECOVERABLE", "state not recoverable"},
+	{132, "ERFKILL", "operation not possible due to RF-kill"},
+	{133, "EHWPOISON", "memory page has hardware error"},
+}
+
+// Signal table
+var signalList = [...]struct {
+	num  syscall.Signal
+	name string
+	desc string
+}{
+	{1, "SIGHUP", "hangup"},
+	{2, "SIGINT", "interrupt"},
+	{3, "SIGQUIT", "quit"},
+	{4, "SIGILL", "illegal instruction"},
+	{5, "SIGTRAP", "trace/breakpoint trap"},
+	{6, "SIGABRT", "aborted"},
+	{7, "SIGBUS", "bus error"},
+	{8, "SIGFPE", "floating point exception"},
+	{9, "SIGKILL", "killed"},
+	{10, "SIGUSR1", "user defined signal 1"},
+	{11, "SIGSEGV", "segmentation fault"},
+	{12, "SIGUSR2", "user defined signal 2"},
+	{13, "SIGPIPE", "broken pipe"},
+	{14, "SIGALRM", "alarm clock"},
+	{15, "SIGTERM", "terminated"},
+	{16, "SIGSTKFLT", "stack fault"},
+	{17, "SIGCHLD", "child exited"},
+	{18, "SIGCONT", "continued"},
+	{19, "SIGSTOP", "stopped (signal)"},
+	{20, "SIGTSTP", "stopped"},
+	{21, "SIGTTIN", "stopped (tty input)"},
+	{22, "SIGTTOU", "stopped (tty output)"},
+	{23, "SIGURG", "urgent I/O condition"},
+	{24, "SIGXCPU", "CPU time limit exceeded"},
+	{25, "SIGXFSZ", "file size limit exceeded"},
+	{26, "SIGVTALRM", "virtual timer expired"},
+	{27, "SIGPROF", "profiling timer expired"},
+	{28, "SIGWINCH", "window changed"},
+	{29, "SIGIO", "I/O possible"},
+	{30, "SIGPWR", "power failure"},
+	{31, "SIGSYS", "bad system call"},
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
index 941e20d..e60102f 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build ppc64 && linux
 // +build ppc64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
 
 package unix
 
@@ -92,6 +93,9 @@
 	F_SETOWN                         = 0x8
 	F_UNLCK                          = 0x2
 	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x40084803
+	HIDIOCGRDESC                     = 0x50044802
+	HIDIOCGRDESCSIZE                 = 0x40044801
 	HUPCL                            = 0x4000
 	ICANON                           = 0x100
 	IEXTEN                           = 0x400
@@ -165,6 +169,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x20002405
 	PPPIOCATTACH                     = 0x8004743d
 	PPPIOCATTCHAN                    = 0x80047438
+	PPPIOCBRIDGECHAN                 = 0x80047435
 	PPPIOCCONNECT                    = 0x8004743a
 	PPPIOCDETACH                     = 0x8004743c
 	PPPIOCDISCONN                    = 0x20007439
@@ -192,6 +197,7 @@
 	PPPIOCSPASS                      = 0x80107447
 	PPPIOCSRASYNCMAP                 = 0x80047454
 	PPPIOCSXASYNCMAP                 = 0x8020744f
+	PPPIOCUNBRIDGECHAN               = 0x20007434
 	PPPIOCXFERUNIT                   = 0x2000744e
 	PROT_SAO                         = 0x10
 	PR_SET_PTRACER_ANY               = 0xffffffffffffffff
@@ -327,6 +333,7 @@
 	SO_BROADCAST                     = 0x6
 	SO_BSDCOMPAT                     = 0xe
 	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
 	SO_CNX_ADVICE                    = 0x35
 	SO_COOKIE                        = 0x39
 	SO_DETACH_REUSEPORT_BPF          = 0x44
@@ -349,6 +356,7 @@
 	SO_PEERCRED                      = 0x15
 	SO_PEERGROUPS                    = 0x3b
 	SO_PEERSEC                       = 0x1f
+	SO_PREFER_BUSY_POLL              = 0x45
 	SO_PROTOCOL                      = 0x26
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
@@ -543,6 +551,9 @@
 	WORDSIZE                         = 0x40
 	XCASE                            = 0x4000
 	XTABS                            = 0xc00
+	_HIDIOCGRAWNAME                  = 0x40804804
+	_HIDIOCGRAWPHYS                  = 0x40404805
+	_HIDIOCGRAWUNIQ                  = 0x40404808
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
index 63d3bc5..838ff4e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build ppc64le && linux
 // +build ppc64le,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
 
 package unix
 
@@ -92,6 +93,9 @@
 	F_SETOWN                         = 0x8
 	F_UNLCK                          = 0x2
 	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x40084803
+	HIDIOCGRDESC                     = 0x50044802
+	HIDIOCGRDESCSIZE                 = 0x40044801
 	HUPCL                            = 0x4000
 	ICANON                           = 0x100
 	IEXTEN                           = 0x400
@@ -165,6 +169,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x20002405
 	PPPIOCATTACH                     = 0x8004743d
 	PPPIOCATTCHAN                    = 0x80047438
+	PPPIOCBRIDGECHAN                 = 0x80047435
 	PPPIOCCONNECT                    = 0x8004743a
 	PPPIOCDETACH                     = 0x8004743c
 	PPPIOCDISCONN                    = 0x20007439
@@ -192,6 +197,7 @@
 	PPPIOCSPASS                      = 0x80107447
 	PPPIOCSRASYNCMAP                 = 0x80047454
 	PPPIOCSXASYNCMAP                 = 0x8020744f
+	PPPIOCUNBRIDGECHAN               = 0x20007434
 	PPPIOCXFERUNIT                   = 0x2000744e
 	PROT_SAO                         = 0x10
 	PR_SET_PTRACER_ANY               = 0xffffffffffffffff
@@ -327,6 +333,7 @@
 	SO_BROADCAST                     = 0x6
 	SO_BSDCOMPAT                     = 0xe
 	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
 	SO_CNX_ADVICE                    = 0x35
 	SO_COOKIE                        = 0x39
 	SO_DETACH_REUSEPORT_BPF          = 0x44
@@ -349,6 +356,7 @@
 	SO_PEERCRED                      = 0x15
 	SO_PEERGROUPS                    = 0x3b
 	SO_PEERSEC                       = 0x1f
+	SO_PREFER_BUSY_POLL              = 0x45
 	SO_PROTOCOL                      = 0x26
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
@@ -543,6 +551,9 @@
 	WORDSIZE                         = 0x40
 	XCASE                            = 0x4000
 	XTABS                            = 0xc00
+	_HIDIOCGRAWNAME                  = 0x40804804
+	_HIDIOCGRAWPHYS                  = 0x40404805
+	_HIDIOCGRAWUNIQ                  = 0x40404808
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
index 490bee1..7cc98f0 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build riscv64 && linux
 // +build riscv64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
 
 package unix
 
@@ -92,6 +93,9 @@
 	F_SETOWN                         = 0x8
 	F_UNLCK                          = 0x2
 	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x80084803
+	HIDIOCGRDESC                     = 0x90044802
+	HIDIOCGRDESCSIZE                 = 0x80044801
 	HUPCL                            = 0x400
 	ICANON                           = 0x2
 	IEXTEN                           = 0x8000
@@ -163,6 +167,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x2405
 	PPPIOCATTACH                     = 0x4004743d
 	PPPIOCATTCHAN                    = 0x40047438
+	PPPIOCBRIDGECHAN                 = 0x40047435
 	PPPIOCCONNECT                    = 0x4004743a
 	PPPIOCDETACH                     = 0x4004743c
 	PPPIOCDISCONN                    = 0x7439
@@ -190,6 +195,7 @@
 	PPPIOCSPASS                      = 0x40107447
 	PPPIOCSRASYNCMAP                 = 0x40047454
 	PPPIOCSXASYNCMAP                 = 0x4020744f
+	PPPIOCUNBRIDGECHAN               = 0x7434
 	PPPIOCXFERUNIT                   = 0x744e
 	PR_SET_PTRACER_ANY               = 0xffffffffffffffff
 	RLIMIT_AS                        = 0x9
@@ -256,6 +262,7 @@
 	SO_BROADCAST                     = 0x6
 	SO_BSDCOMPAT                     = 0xe
 	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
 	SO_CNX_ADVICE                    = 0x35
 	SO_COOKIE                        = 0x39
 	SO_DETACH_REUSEPORT_BPF          = 0x44
@@ -278,6 +285,7 @@
 	SO_PEERCRED                      = 0x11
 	SO_PEERGROUPS                    = 0x3b
 	SO_PEERSEC                       = 0x1f
+	SO_PREFER_BUSY_POLL              = 0x45
 	SO_PROTOCOL                      = 0x26
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
@@ -468,6 +476,9 @@
 	WORDSIZE                         = 0x40
 	XCASE                            = 0x4
 	XTABS                            = 0x1800
+	_HIDIOCGRAWNAME                  = 0x80804804
+	_HIDIOCGRAWPHYS                  = 0x80404805
+	_HIDIOCGRAWUNIQ                  = 0x80404808
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
index 467b821..6d30e6f 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include -fsigned-char
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build s390x && linux
 // +build s390x,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char /build/_const.go
 
 package unix
 
@@ -92,6 +93,9 @@
 	F_SETOWN                         = 0x8
 	F_UNLCK                          = 0x2
 	F_WRLCK                          = 0x1
+	HIDIOCGRAWINFO                   = 0x80084803
+	HIDIOCGRDESC                     = 0x90044802
+	HIDIOCGRDESCSIZE                 = 0x80044801
 	HUPCL                            = 0x400
 	ICANON                           = 0x2
 	IEXTEN                           = 0x8000
@@ -163,6 +167,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x2405
 	PPPIOCATTACH                     = 0x4004743d
 	PPPIOCATTCHAN                    = 0x40047438
+	PPPIOCBRIDGECHAN                 = 0x40047435
 	PPPIOCCONNECT                    = 0x4004743a
 	PPPIOCDETACH                     = 0x4004743c
 	PPPIOCDISCONN                    = 0x7439
@@ -190,6 +195,7 @@
 	PPPIOCSPASS                      = 0x40107447
 	PPPIOCSRASYNCMAP                 = 0x40047454
 	PPPIOCSXASYNCMAP                 = 0x4020744f
+	PPPIOCUNBRIDGECHAN               = 0x7434
 	PPPIOCXFERUNIT                   = 0x744e
 	PR_SET_PTRACER_ANY               = 0xffffffffffffffff
 	PTRACE_DISABLE_TE                = 0x5010
@@ -206,6 +212,8 @@
 	PTRACE_POKE_SYSTEM_CALL          = 0x5008
 	PTRACE_PROT                      = 0x15
 	PTRACE_SINGLEBLOCK               = 0xc
+	PTRACE_SYSEMU                    = 0x1f
+	PTRACE_SYSEMU_SINGLESTEP         = 0x20
 	PTRACE_TE_ABORT_RAND             = 0x5011
 	PT_ACR0                          = 0x90
 	PT_ACR1                          = 0x94
@@ -329,6 +337,7 @@
 	SO_BROADCAST                     = 0x6
 	SO_BSDCOMPAT                     = 0xe
 	SO_BUSY_POLL                     = 0x2e
+	SO_BUSY_POLL_BUDGET              = 0x46
 	SO_CNX_ADVICE                    = 0x35
 	SO_COOKIE                        = 0x39
 	SO_DETACH_REUSEPORT_BPF          = 0x44
@@ -351,6 +360,7 @@
 	SO_PEERCRED                      = 0x11
 	SO_PEERGROUPS                    = 0x3b
 	SO_PEERSEC                       = 0x1f
+	SO_PREFER_BUSY_POLL              = 0x45
 	SO_PROTOCOL                      = 0x26
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
@@ -541,6 +551,9 @@
 	WORDSIZE                         = 0x40
 	XCASE                            = 0x4
 	XTABS                            = 0x1800
+	_HIDIOCGRAWNAME                  = 0x80804804
+	_HIDIOCGRAWPHYS                  = 0x80404805
+	_HIDIOCGRAWUNIQ                  = 0x80404808
 )
 
 // Errors
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
index 79fbafb..d5e2dc9 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
@@ -1,10 +1,11 @@
 // mkerrors.sh -Wall -Werror -static -I/tmp/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build sparc64 && linux
 // +build sparc64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
 
 package unix
 
@@ -96,6 +97,9 @@
 	F_SETOWN                         = 0x6
 	F_UNLCK                          = 0x3
 	F_WRLCK                          = 0x2
+	HIDIOCGRAWINFO                   = 0x40084803
+	HIDIOCGRDESC                     = 0x50044802
+	HIDIOCGRDESCSIZE                 = 0x40044801
 	HUPCL                            = 0x400
 	ICANON                           = 0x2
 	IEXTEN                           = 0x8000
@@ -168,6 +172,7 @@
 	PERF_EVENT_IOC_SET_OUTPUT        = 0x20002405
 	PPPIOCATTACH                     = 0x8004743d
 	PPPIOCATTCHAN                    = 0x80047438
+	PPPIOCBRIDGECHAN                 = 0x80047435
 	PPPIOCCONNECT                    = 0x8004743a
 	PPPIOCDETACH                     = 0x8004743c
 	PPPIOCDISCONN                    = 0x20007439
@@ -195,6 +200,7 @@
 	PPPIOCSPASS                      = 0x80107447
 	PPPIOCSRASYNCMAP                 = 0x80047454
 	PPPIOCSXASYNCMAP                 = 0x8020744f
+	PPPIOCUNBRIDGECHAN               = 0x20007434
 	PPPIOCXFERUNIT                   = 0x2000744e
 	PR_SET_PTRACER_ANY               = 0xffffffffffffffff
 	PTRACE_GETFPAREGS                = 0x14
@@ -322,6 +328,7 @@
 	SO_BROADCAST                     = 0x20
 	SO_BSDCOMPAT                     = 0x400
 	SO_BUSY_POLL                     = 0x30
+	SO_BUSY_POLL_BUDGET              = 0x49
 	SO_CNX_ADVICE                    = 0x37
 	SO_COOKIE                        = 0x3b
 	SO_DETACH_REUSEPORT_BPF          = 0x47
@@ -344,6 +351,7 @@
 	SO_PEERCRED                      = 0x40
 	SO_PEERGROUPS                    = 0x3d
 	SO_PEERSEC                       = 0x1e
+	SO_PREFER_BUSY_POLL              = 0x48
 	SO_PROTOCOL                      = 0x1028
 	SO_RCVBUF                        = 0x1002
 	SO_RCVBUFFORCE                   = 0x100b
@@ -531,6 +539,9 @@
 	WORDSIZE                         = 0x40
 	XCASE                            = 0x4
 	XTABS                            = 0x1800
+	_HIDIOCGRAWNAME                  = 0x40804804
+	_HIDIOCGRAWPHYS                  = 0x40404805
+	_HIDIOCGRAWUNIQ                  = 0x40404808
 	__TIOCFLUSH                      = 0x80047410
 )
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go
index 20f3a57..72f7420 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m32
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build 386 && netbsd
 // +build 386,netbsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go
index 90b8fcd..8d4eb0c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && netbsd
 // +build amd64,netbsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go
index c5c0399..9eef974 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -marm
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm && netbsd
 // +build arm,netbsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go
index 14dd3c1..3b62ba1 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && netbsd
 // +build arm64,netbsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go
index c865a10..593cc0f 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m32
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build 386 && openbsd
 // +build 386,openbsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go
index 9db6b2f..25cb609 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && openbsd
 // +build amd64,openbsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go
index 7072526..a4e4c22 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go
@@ -1,6 +1,7 @@
 // mkerrors.sh
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm && openbsd
 // +build arm,openbsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go
index ac5efbe..90de7df 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && openbsd
 // +build arm64,openbsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go
index a74639a..f1154ff 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mips64 && openbsd
 // +build mips64,openbsd
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go
index 5312c36..1afee6a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && solaris
 // +build amd64,solaris
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
@@ -365,6 +366,7 @@
 	HUPCL                         = 0x400
 	IBSHIFT                       = 0x10
 	ICANON                        = 0x2
+	ICMP6_FILTER                  = 0x1
 	ICRNL                         = 0x100
 	IEXTEN                        = 0x8000
 	IFF_ADDRCONF                  = 0x80000
@@ -611,6 +613,7 @@
 	IP_RECVPKTINFO                = 0x1a
 	IP_RECVRETOPTS                = 0x6
 	IP_RECVSLLA                   = 0xa
+	IP_RECVTOS                    = 0xc
 	IP_RECVTTL                    = 0xb
 	IP_RETOPTS                    = 0x8
 	IP_REUSEADDR                  = 0x104
@@ -703,6 +706,7 @@
 	O_APPEND                      = 0x8
 	O_CLOEXEC                     = 0x800000
 	O_CREAT                       = 0x100
+	O_DIRECT                      = 0x2000000
 	O_DIRECTORY                   = 0x1000000
 	O_DSYNC                       = 0x40
 	O_EXCL                        = 0x400
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go
new file mode 100644
index 0000000..fc7d050
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go
@@ -0,0 +1,860 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+// Hand edited based on zerrors_linux_s390x.go
+// TODO: auto-generate.
+
+package unix
+
+const (
+	BRKINT                          = 0x0001
+	CLOCK_MONOTONIC                 = 0x1
+	CLOCK_PROCESS_CPUTIME_ID        = 0x2
+	CLOCK_REALTIME                  = 0x0
+	CLOCK_THREAD_CPUTIME_ID         = 0x3
+	CS8                             = 0x0030
+	CSIZE                           = 0x0030
+	ECHO                            = 0x00000008
+	ECHONL                          = 0x00000001
+	FD_CLOEXEC                      = 0x01
+	FD_CLOFORK                      = 0x02
+	FNDELAY                         = 0x04
+	F_CLOSFD                        = 9
+	F_CONTROL_CVT                   = 13
+	F_DUPFD                         = 0
+	F_DUPFD2                        = 8
+	F_GETFD                         = 1
+	F_GETFL                         = 259
+	F_GETLK                         = 5
+	F_GETOWN                        = 10
+	F_OK                            = 0x0
+	F_RDLCK                         = 1
+	F_SETFD                         = 2
+	F_SETFL                         = 4
+	F_SETLK                         = 6
+	F_SETLKW                        = 7
+	F_SETOWN                        = 11
+	F_SETTAG                        = 12
+	F_UNLCK                         = 3
+	F_WRLCK                         = 2
+	FSTYPE_ZFS                      = 0xe9 //"Z"
+	FSTYPE_HFS                      = 0xc8 //"H"
+	FSTYPE_NFS                      = 0xd5 //"N"
+	FSTYPE_TFS                      = 0xe3 //"T"
+	FSTYPE_AUTOMOUNT                = 0xc1 //"A"
+	IP6F_MORE_FRAG                  = 0x0001
+	IP6F_OFF_MASK                   = 0xfff8
+	IP6F_RESERVED_MASK              = 0x0006
+	IP6OPT_JUMBO                    = 0xc2
+	IP6OPT_JUMBO_LEN                = 6
+	IP6OPT_MUTABLE                  = 0x20
+	IP6OPT_NSAP_ADDR                = 0xc3
+	IP6OPT_PAD1                     = 0x00
+	IP6OPT_PADN                     = 0x01
+	IP6OPT_ROUTER_ALERT             = 0x05
+	IP6OPT_TUNNEL_LIMIT             = 0x04
+	IP6OPT_TYPE_DISCARD             = 0x40
+	IP6OPT_TYPE_FORCEICMP           = 0x80
+	IP6OPT_TYPE_ICMP                = 0xc0
+	IP6OPT_TYPE_SKIP                = 0x00
+	IP6_ALERT_AN                    = 0x0002
+	IP6_ALERT_MLD                   = 0x0000
+	IP6_ALERT_RSVP                  = 0x0001
+	IPPORT_RESERVED                 = 1024
+	IPPORT_USERRESERVED             = 5000
+	IPPROTO_AH                      = 51
+	SOL_AH                          = 51
+	IPPROTO_DSTOPTS                 = 60
+	SOL_DSTOPTS                     = 60
+	IPPROTO_EGP                     = 8
+	SOL_EGP                         = 8
+	IPPROTO_ESP                     = 50
+	SOL_ESP                         = 50
+	IPPROTO_FRAGMENT                = 44
+	SOL_FRAGMENT                    = 44
+	IPPROTO_GGP                     = 2
+	SOL_GGP                         = 2
+	IPPROTO_HOPOPTS                 = 0
+	SOL_HOPOPTS                     = 0
+	IPPROTO_ICMP                    = 1
+	SOL_ICMP                        = 1
+	IPPROTO_ICMPV6                  = 58
+	SOL_ICMPV6                      = 58
+	IPPROTO_IDP                     = 22
+	SOL_IDP                         = 22
+	IPPROTO_IP                      = 0
+	SOL_IP                          = 0
+	IPPROTO_IPV6                    = 41
+	SOL_IPV6                        = 41
+	IPPROTO_MAX                     = 256
+	SOL_MAX                         = 256
+	IPPROTO_NONE                    = 59
+	SOL_NONE                        = 59
+	IPPROTO_PUP                     = 12
+	SOL_PUP                         = 12
+	IPPROTO_RAW                     = 255
+	SOL_RAW                         = 255
+	IPPROTO_ROUTING                 = 43
+	SOL_ROUTING                     = 43
+	IPPROTO_TCP                     = 6
+	SOL_TCP                         = 6
+	IPPROTO_UDP                     = 17
+	SOL_UDP                         = 17
+	IPV6_ADDR_PREFERENCES           = 32
+	IPV6_CHECKSUM                   = 19
+	IPV6_DONTFRAG                   = 29
+	IPV6_DSTOPTS                    = 23
+	IPV6_HOPLIMIT                   = 11
+	IPV6_HOPOPTS                    = 22
+	IPV6_JOIN_GROUP                 = 5
+	IPV6_LEAVE_GROUP                = 6
+	IPV6_MULTICAST_HOPS             = 9
+	IPV6_MULTICAST_IF               = 7
+	IPV6_MULTICAST_LOOP             = 4
+	IPV6_NEXTHOP                    = 20
+	IPV6_PATHMTU                    = 12
+	IPV6_PKTINFO                    = 13
+	IPV6_PREFER_SRC_CGA             = 0x10
+	IPV6_PREFER_SRC_COA             = 0x02
+	IPV6_PREFER_SRC_HOME            = 0x01
+	IPV6_PREFER_SRC_NONCGA          = 0x20
+	IPV6_PREFER_SRC_PUBLIC          = 0x08
+	IPV6_PREFER_SRC_TMP             = 0x04
+	IPV6_RECVDSTOPTS                = 28
+	IPV6_RECVHOPLIMIT               = 14
+	IPV6_RECVHOPOPTS                = 26
+	IPV6_RECVPATHMTU                = 16
+	IPV6_RECVPKTINFO                = 15
+	IPV6_RECVRTHDR                  = 25
+	IPV6_RECVTCLASS                 = 31
+	IPV6_RTHDR                      = 21
+	IPV6_RTHDRDSTOPTS               = 24
+	IPV6_RTHDR_TYPE_0               = 0
+	IPV6_TCLASS                     = 30
+	IPV6_UNICAST_HOPS               = 3
+	IPV6_USE_MIN_MTU                = 18
+	IPV6_V6ONLY                     = 10
+	IP_ADD_MEMBERSHIP               = 5
+	IP_ADD_SOURCE_MEMBERSHIP        = 12
+	IP_BLOCK_SOURCE                 = 10
+	IP_DEFAULT_MULTICAST_LOOP       = 1
+	IP_DEFAULT_MULTICAST_TTL        = 1
+	IP_DROP_MEMBERSHIP              = 6
+	IP_DROP_SOURCE_MEMBERSHIP       = 13
+	IP_MAX_MEMBERSHIPS              = 20
+	IP_MULTICAST_IF                 = 7
+	IP_MULTICAST_LOOP               = 4
+	IP_MULTICAST_TTL                = 3
+	IP_OPTIONS                      = 1
+	IP_PKTINFO                      = 101
+	IP_RECVPKTINFO                  = 102
+	IP_TOS                          = 2
+	IP_TTL                          = 3
+	IP_UNBLOCK_SOURCE               = 11
+	ICANON                          = 0x0010
+	ICMP6_FILTER                    = 0x26
+	ICRNL                           = 0x0002
+	IEXTEN                          = 0x0020
+	IGNBRK                          = 0x0004
+	IGNCR                           = 0x0008
+	INLCR                           = 0x0020
+	ISIG                            = 0x0040
+	ISTRIP                          = 0x0080
+	IXON                            = 0x0200
+	IXOFF                           = 0x0100
+	LOCK_SH                         = 0x1 // Not exist on zOS
+	LOCK_EX                         = 0x2 // Not exist on zOS
+	LOCK_NB                         = 0x4 // Not exist on zOS
+	LOCK_UN                         = 0x8 // Not exist on zOS
+	POLLIN                          = 0x0003
+	POLLOUT                         = 0x0004
+	POLLPRI                         = 0x0010
+	POLLERR                         = 0x0020
+	POLLHUP                         = 0x0040
+	POLLNVAL                        = 0x0080
+	PROT_READ                       = 0x1 // mmap - page can be read
+	PROT_WRITE                      = 0x2 // page can be written
+	PROT_NONE                       = 0x4 // can't be accessed
+	PROT_EXEC                       = 0x8 // can be executed
+	MAP_PRIVATE                     = 0x1 // changes are private
+	MAP_SHARED                      = 0x2 // changes are shared
+	MAP_FIXED                       = 0x4 // place exactly
+	MCAST_JOIN_GROUP                = 40
+	MCAST_LEAVE_GROUP               = 41
+	MCAST_JOIN_SOURCE_GROUP         = 42
+	MCAST_LEAVE_SOURCE_GROUP        = 43
+	MCAST_BLOCK_SOURCE              = 44
+	MCAST_UNBLOCK_SOURCE            = 45
+	MS_SYNC                         = 0x1 // msync - synchronous writes
+	MS_ASYNC                        = 0x2 // asynchronous writes
+	MS_INVALIDATE                   = 0x4 // invalidate mappings
+	MTM_RDONLY                      = 0x80000000
+	MTM_RDWR                        = 0x40000000
+	MTM_UMOUNT                      = 0x10000000
+	MTM_IMMED                       = 0x08000000
+	MTM_FORCE                       = 0x04000000
+	MTM_DRAIN                       = 0x02000000
+	MTM_RESET                       = 0x01000000
+	MTM_SAMEMODE                    = 0x00100000
+	MTM_UNQSEFORCE                  = 0x00040000
+	MTM_NOSUID                      = 0x00000400
+	MTM_SYNCHONLY                   = 0x00000200
+	MTM_REMOUNT                     = 0x00000100
+	MTM_NOSECURITY                  = 0x00000080
+	NFDBITS                         = 0x20
+	O_ACCMODE                       = 0x03
+	O_APPEND                        = 0x08
+	O_ASYNCSIG                      = 0x0200
+	O_CREAT                         = 0x80
+	O_EXCL                          = 0x40
+	O_GETFL                         = 0x0F
+	O_LARGEFILE                     = 0x0400
+	O_NONBLOCK                      = 0x04
+	O_RDONLY                        = 0x02
+	O_RDWR                          = 0x03
+	O_SYNC                          = 0x0100
+	O_TRUNC                         = 0x10
+	O_WRONLY                        = 0x01
+	O_NOCTTY                        = 0x20
+	OPOST                           = 0x0001
+	ONLCR                           = 0x0004
+	PARENB                          = 0x0200
+	PARMRK                          = 0x0400
+	QUERYCVT                        = 3
+	RUSAGE_CHILDREN                 = -0x1
+	RUSAGE_SELF                     = 0x0 // RUSAGE_THREAD unsupported on z/OS
+	SEEK_CUR                        = 1
+	SEEK_END                        = 2
+	SEEK_SET                        = 0
+	SETAUTOCVTALL                   = 5
+	SETAUTOCVTON                    = 2
+	SETCVTALL                       = 4
+	SETCVTOFF                       = 0
+	SETCVTON                        = 1
+	AF_APPLETALK                    = 16
+	AF_CCITT                        = 10
+	AF_CHAOS                        = 5
+	AF_DATAKIT                      = 9
+	AF_DLI                          = 13
+	AF_ECMA                         = 8
+	AF_HYLINK                       = 15
+	AF_IMPLINK                      = 3
+	AF_INET                         = 2
+	AF_INET6                        = 19
+	AF_INTF                         = 20
+	AF_IUCV                         = 17
+	AF_LAT                          = 14
+	AF_LINK                         = 18
+	AF_MAX                          = 30
+	AF_NBS                          = 7
+	AF_NDD                          = 23
+	AF_NETWARE                      = 22
+	AF_NS                           = 6
+	AF_PUP                          = 4
+	AF_RIF                          = 21
+	AF_ROUTE                        = 20
+	AF_SNA                          = 11
+	AF_UNIX                         = 1
+	AF_UNSPEC                       = 0
+	IBMTCP_IMAGE                    = 1
+	MSG_ACK_EXPECTED                = 0x10
+	MSG_ACK_GEN                     = 0x40
+	MSG_ACK_TIMEOUT                 = 0x20
+	MSG_CONNTERM                    = 0x80
+	MSG_CTRUNC                      = 0x20
+	MSG_DONTROUTE                   = 0x4
+	MSG_EOF                         = 0x8000
+	MSG_EOR                         = 0x8
+	MSG_MAXIOVLEN                   = 16
+	MSG_NONBLOCK                    = 0x4000
+	MSG_OOB                         = 0x1
+	MSG_PEEK                        = 0x2
+	MSG_TRUNC                       = 0x10
+	MSG_WAITALL                     = 0x40
+	PRIO_PROCESS                    = 1
+	PRIO_PGRP                       = 2
+	PRIO_USER                       = 3
+	RLIMIT_CPU                      = 0
+	RLIMIT_FSIZE                    = 1
+	RLIMIT_DATA                     = 2
+	RLIMIT_STACK                    = 3
+	RLIMIT_CORE                     = 4
+	RLIMIT_AS                       = 5
+	RLIMIT_NOFILE                   = 6
+	RLIMIT_MEMLIMIT                 = 7
+	RLIM_INFINITY                   = 2147483647
+	SCM_RIGHTS                      = 0x01
+	SF_CLOSE                        = 0x00000002
+	SF_REUSE                        = 0x00000001
+	SHUT_RD                         = 0
+	SHUT_RDWR                       = 2
+	SHUT_WR                         = 1
+	SOCK_CONN_DGRAM                 = 6
+	SOCK_DGRAM                      = 2
+	SOCK_RAW                        = 3
+	SOCK_RDM                        = 4
+	SOCK_SEQPACKET                  = 5
+	SOCK_STREAM                     = 1
+	SOL_SOCKET                      = 0xffff
+	SOMAXCONN                       = 10
+	SO_ACCEPTCONN                   = 0x0002
+	SO_ACCEPTECONNABORTED           = 0x0006
+	SO_ACKNOW                       = 0x7700
+	SO_BROADCAST                    = 0x0020
+	SO_BULKMODE                     = 0x8000
+	SO_CKSUMRECV                    = 0x0800
+	SO_CLOSE                        = 0x01
+	SO_CLUSTERCONNTYPE              = 0x00004001
+	SO_CLUSTERCONNTYPE_INTERNAL     = 8
+	SO_CLUSTERCONNTYPE_NOCONN       = 0
+	SO_CLUSTERCONNTYPE_NONE         = 1
+	SO_CLUSTERCONNTYPE_SAME_CLUSTER = 2
+	SO_CLUSTERCONNTYPE_SAME_IMAGE   = 4
+	SO_DEBUG                        = 0x0001
+	SO_DONTROUTE                    = 0x0010
+	SO_ERROR                        = 0x1007
+	SO_IGNOREINCOMINGPUSH           = 0x1
+	SO_IGNORESOURCEVIPA             = 0x0002
+	SO_KEEPALIVE                    = 0x0008
+	SO_LINGER                       = 0x0080
+	SO_NONBLOCKLOCAL                = 0x8001
+	SO_NOREUSEADDR                  = 0x1000
+	SO_OOBINLINE                    = 0x0100
+	SO_OPTACK                       = 0x8004
+	SO_OPTMSS                       = 0x8003
+	SO_RCVBUF                       = 0x1002
+	SO_RCVLOWAT                     = 0x1004
+	SO_RCVTIMEO                     = 0x1006
+	SO_REUSEADDR                    = 0x0004
+	SO_REUSEPORT                    = 0x0200
+	SO_SECINFO                      = 0x00004002
+	SO_SET                          = 0x0200
+	SO_SNDBUF                       = 0x1001
+	SO_SNDLOWAT                     = 0x1003
+	SO_SNDTIMEO                     = 0x1005
+	SO_TYPE                         = 0x1008
+	SO_UNSET                        = 0x0400
+	SO_USELOOPBACK                  = 0x0040
+	SO_USE_IFBUFS                   = 0x0400
+	S_ISUID                         = 0x0800
+	S_ISGID                         = 0x0400
+	S_ISVTX                         = 0x0200
+	S_IRUSR                         = 0x0100
+	S_IWUSR                         = 0x0080
+	S_IXUSR                         = 0x0040
+	S_IRWXU                         = 0x01C0
+	S_IRGRP                         = 0x0020
+	S_IWGRP                         = 0x0010
+	S_IXGRP                         = 0x0008
+	S_IRWXG                         = 0x0038
+	S_IROTH                         = 0x0004
+	S_IWOTH                         = 0x0002
+	S_IXOTH                         = 0x0001
+	S_IRWXO                         = 0x0007
+	S_IREAD                         = S_IRUSR
+	S_IWRITE                        = S_IWUSR
+	S_IEXEC                         = S_IXUSR
+	S_IFDIR                         = 0x01000000
+	S_IFCHR                         = 0x02000000
+	S_IFREG                         = 0x03000000
+	S_IFFIFO                        = 0x04000000
+	S_IFIFO                         = 0x04000000
+	S_IFLNK                         = 0x05000000
+	S_IFBLK                         = 0x06000000
+	S_IFSOCK                        = 0x07000000
+	S_IFVMEXTL                      = 0xFE000000
+	S_IFVMEXTL_EXEC                 = 0x00010000
+	S_IFVMEXTL_DATA                 = 0x00020000
+	S_IFVMEXTL_MEL                  = 0x00030000
+	S_IFEXTL                        = 0x00000001
+	S_IFPROGCTL                     = 0x00000002
+	S_IFAPFCTL                      = 0x00000004
+	S_IFNOSHARE                     = 0x00000008
+	S_IFSHARELIB                    = 0x00000010
+	S_IFMT                          = 0xFF000000
+	S_IFMST                         = 0x00FF0000
+	TCP_KEEPALIVE                   = 0x8
+	TCP_NODELAY                     = 0x1
+	TCP_INFO                        = 0xb
+	TCP_USER_TIMEOUT                = 0x1
+	TIOCGWINSZ                      = 0x4008a368
+	TIOCSWINSZ                      = 0x8008a367
+	TIOCSBRK                        = 0x2000a77b
+	TIOCCBRK                        = 0x2000a77a
+	TIOCSTI                         = 0x8001a772
+	TIOCGPGRP                       = 0x4004a777 // _IOR(167, 119, int)
+	TCSANOW                         = 0
+	TCSETS                          = 0 // equivalent to TCSANOW for tcsetattr
+	TCSADRAIN                       = 1
+	TCSETSW                         = 1 // equivalent to TCSADRAIN for tcsetattr
+	TCSAFLUSH                       = 2
+	TCSETSF                         = 2 // equivalent to TCSAFLUSH for tcsetattr
+	TCGETS                          = 3 // not defined in ioctl.h -- zos golang only
+	TCIFLUSH                        = 0
+	TCOFLUSH                        = 1
+	TCIOFLUSH                       = 2
+	TCOOFF                          = 0
+	TCOON                           = 1
+	TCIOFF                          = 2
+	TCION                           = 3
+	TIOCSPGRP                       = 0x8004a776
+	TIOCNOTTY                       = 0x2000a771
+	TIOCEXCL                        = 0x2000a70d
+	TIOCNXCL                        = 0x2000a70e
+	TIOCGETD                        = 0x4004a700
+	TIOCSETD                        = 0x8004a701
+	TIOCPKT                         = 0x8004a770
+	TIOCSTOP                        = 0x2000a76f
+	TIOCSTART                       = 0x2000a76e
+	TIOCUCNTL                       = 0x8004a766
+	TIOCREMOTE                      = 0x8004a769
+	TIOCMGET                        = 0x4004a76a
+	TIOCMSET                        = 0x8004a76d
+	TIOCMBIC                        = 0x8004a76b
+	TIOCMBIS                        = 0x8004a76c
+	VINTR                           = 0
+	VQUIT                           = 1
+	VERASE                          = 2
+	VKILL                           = 3
+	VEOF                            = 4
+	VEOL                            = 5
+	VMIN                            = 6
+	VSTART                          = 7
+	VSTOP                           = 8
+	VSUSP                           = 9
+	VTIME                           = 10
+	WCONTINUED                      = 0x4
+	WNOHANG                         = 0x1
+	WUNTRACED                       = 0x2
+	_BPX_SWAP                       = 1
+	_BPX_NONSWAP                    = 2
+	MCL_CURRENT                     = 1  // for Linux compatibility -- no zos semantics
+	MCL_FUTURE                      = 2  // for Linux compatibility -- no zos semantics
+	MCL_ONFAULT                     = 3  // for Linux compatibility -- no zos semantics
+	MADV_NORMAL                     = 0  // for Linux compatibility -- no zos semantics
+	MADV_RANDOM                     = 1  // for Linux compatibility -- no zos semantics
+	MADV_SEQUENTIAL                 = 2  // for Linux compatibility -- no zos semantics
+	MADV_WILLNEED                   = 3  // for Linux compatibility -- no zos semantics
+	MADV_REMOVE                     = 4  // for Linux compatibility -- no zos semantics
+	MADV_DONTFORK                   = 5  // for Linux compatibility -- no zos semantics
+	MADV_DOFORK                     = 6  // for Linux compatibility -- no zos semantics
+	MADV_HWPOISON                   = 7  // for Linux compatibility -- no zos semantics
+	MADV_MERGEABLE                  = 8  // for Linux compatibility -- no zos semantics
+	MADV_UNMERGEABLE                = 9  // for Linux compatibility -- no zos semantics
+	MADV_SOFT_OFFLINE               = 10 // for Linux compatibility -- no zos semantics
+	MADV_HUGEPAGE                   = 11 // for Linux compatibility -- no zos semantics
+	MADV_NOHUGEPAGE                 = 12 // for Linux compatibility -- no zos semantics
+	MADV_DONTDUMP                   = 13 // for Linux compatibility -- no zos semantics
+	MADV_DODUMP                     = 14 // for Linux compatibility -- no zos semantics
+	MADV_FREE                       = 15 // for Linux compatibility -- no zos semantics
+	MADV_WIPEONFORK                 = 16 // for Linux compatibility -- no zos semantics
+	MADV_KEEPONFORK                 = 17 // for Linux compatibility -- no zos semantics
+	AT_SYMLINK_NOFOLLOW             = 1  // for Unix  compatibility -- no zos semantics
+	AT_FDCWD                        = 2  // for Unix  compatibility -- no zos semantics
+)
+
+const (
+	EDOM               = Errno(1)
+	ERANGE             = Errno(2)
+	EACCES             = Errno(111)
+	EAGAIN             = Errno(112)
+	EBADF              = Errno(113)
+	EBUSY              = Errno(114)
+	ECHILD             = Errno(115)
+	EDEADLK            = Errno(116)
+	EEXIST             = Errno(117)
+	EFAULT             = Errno(118)
+	EFBIG              = Errno(119)
+	EINTR              = Errno(120)
+	EINVAL             = Errno(121)
+	EIO                = Errno(122)
+	EISDIR             = Errno(123)
+	EMFILE             = Errno(124)
+	EMLINK             = Errno(125)
+	ENAMETOOLONG       = Errno(126)
+	ENFILE             = Errno(127)
+	ENODEV             = Errno(128)
+	ENOENT             = Errno(129)
+	ENOEXEC            = Errno(130)
+	ENOLCK             = Errno(131)
+	ENOMEM             = Errno(132)
+	ENOSPC             = Errno(133)
+	ENOSYS             = Errno(134)
+	ENOTDIR            = Errno(135)
+	ENOTEMPTY          = Errno(136)
+	ENOTTY             = Errno(137)
+	ENXIO              = Errno(138)
+	EPERM              = Errno(139)
+	EPIPE              = Errno(140)
+	EROFS              = Errno(141)
+	ESPIPE             = Errno(142)
+	ESRCH              = Errno(143)
+	EXDEV              = Errno(144)
+	E2BIG              = Errno(145)
+	ELOOP              = Errno(146)
+	EILSEQ             = Errno(147)
+	ENODATA            = Errno(148)
+	EOVERFLOW          = Errno(149)
+	EMVSNOTUP          = Errno(150)
+	ECMSSTORAGE        = Errno(151)
+	EMVSDYNALC         = Errno(151)
+	EMVSCVAF           = Errno(152)
+	EMVSCATLG          = Errno(153)
+	ECMSINITIAL        = Errno(156)
+	EMVSINITIAL        = Errno(156)
+	ECMSERR            = Errno(157)
+	EMVSERR            = Errno(157)
+	EMVSPARM           = Errno(158)
+	ECMSPFSFILE        = Errno(159)
+	EMVSPFSFILE        = Errno(159)
+	EMVSBADCHAR        = Errno(160)
+	ECMSPFSPERM        = Errno(162)
+	EMVSPFSPERM        = Errno(162)
+	EMVSSAFEXTRERR     = Errno(163)
+	EMVSSAF2ERR        = Errno(164)
+	EMVSTODNOTSET      = Errno(165)
+	EMVSPATHOPTS       = Errno(166)
+	EMVSNORTL          = Errno(167)
+	EMVSEXPIRE         = Errno(168)
+	EMVSPASSWORD       = Errno(169)
+	EMVSWLMERROR       = Errno(170)
+	EMVSCPLERROR       = Errno(171)
+	EMVSARMERROR       = Errno(172)
+	ELENOFORK          = Errno(200)
+	ELEMSGERR          = Errno(201)
+	EFPMASKINV         = Errno(202)
+	EFPMODEINV         = Errno(203)
+	EBUFLEN            = Errno(227)
+	EEXTLINK           = Errno(228)
+	ENODD              = Errno(229)
+	ECMSESMERR         = Errno(230)
+	ECPERR             = Errno(231)
+	ELEMULTITHREAD     = Errno(232)
+	ELEFENCE           = Errno(244)
+	EBADDATA           = Errno(245)
+	EUNKNOWN           = Errno(246)
+	ENOTSUP            = Errno(247)
+	EBADNAME           = Errno(248)
+	ENOTSAFE           = Errno(249)
+	ELEMULTITHREADFORK = Errno(257)
+	ECUNNOENV          = Errno(258)
+	ECUNNOCONV         = Errno(259)
+	ECUNNOTALIGNED     = Errno(260)
+	ECUNERR            = Errno(262)
+	EIBMBADCALL        = Errno(1000)
+	EIBMBADPARM        = Errno(1001)
+	EIBMSOCKOUTOFRANGE = Errno(1002)
+	EIBMSOCKINUSE      = Errno(1003)
+	EIBMIUCVERR        = Errno(1004)
+	EOFFLOADboxERROR   = Errno(1005)
+	EOFFLOADboxRESTART = Errno(1006)
+	EOFFLOADboxDOWN    = Errno(1007)
+	EIBMCONFLICT       = Errno(1008)
+	EIBMCANCELLED      = Errno(1009)
+	EIBMBADTCPNAME     = Errno(1011)
+	ENOTBLK            = Errno(1100)
+	ETXTBSY            = Errno(1101)
+	EWOULDBLOCK        = Errno(1102)
+	EINPROGRESS        = Errno(1103)
+	EALREADY           = Errno(1104)
+	ENOTSOCK           = Errno(1105)
+	EDESTADDRREQ       = Errno(1106)
+	EMSGSIZE           = Errno(1107)
+	EPROTOTYPE         = Errno(1108)
+	ENOPROTOOPT        = Errno(1109)
+	EPROTONOSUPPORT    = Errno(1110)
+	ESOCKTNOSUPPORT    = Errno(1111)
+	EOPNOTSUPP         = Errno(1112)
+	EPFNOSUPPORT       = Errno(1113)
+	EAFNOSUPPORT       = Errno(1114)
+	EADDRINUSE         = Errno(1115)
+	EADDRNOTAVAIL      = Errno(1116)
+	ENETDOWN           = Errno(1117)
+	ENETUNREACH        = Errno(1118)
+	ENETRESET          = Errno(1119)
+	ECONNABORTED       = Errno(1120)
+	ECONNRESET         = Errno(1121)
+	ENOBUFS            = Errno(1122)
+	EISCONN            = Errno(1123)
+	ENOTCONN           = Errno(1124)
+	ESHUTDOWN          = Errno(1125)
+	ETOOMANYREFS       = Errno(1126)
+	ETIMEDOUT          = Errno(1127)
+	ECONNREFUSED       = Errno(1128)
+	EHOSTDOWN          = Errno(1129)
+	EHOSTUNREACH       = Errno(1130)
+	EPROCLIM           = Errno(1131)
+	EUSERS             = Errno(1132)
+	EDQUOT             = Errno(1133)
+	ESTALE             = Errno(1134)
+	EREMOTE            = Errno(1135)
+	ENOSTR             = Errno(1136)
+	ETIME              = Errno(1137)
+	ENOSR              = Errno(1138)
+	ENOMSG             = Errno(1139)
+	EBADMSG            = Errno(1140)
+	EIDRM              = Errno(1141)
+	ENONET             = Errno(1142)
+	ERREMOTE           = Errno(1143)
+	ENOLINK            = Errno(1144)
+	EADV               = Errno(1145)
+	ESRMNT             = Errno(1146)
+	ECOMM              = Errno(1147)
+	EPROTO             = Errno(1148)
+	EMULTIHOP          = Errno(1149)
+	EDOTDOT            = Errno(1150)
+	EREMCHG            = Errno(1151)
+	ECANCELED          = Errno(1152)
+	EINTRNODATA        = Errno(1159)
+	ENOREUSE           = Errno(1160)
+	ENOMOVE            = Errno(1161)
+)
+
+// Signals
+const (
+	SIGHUP    = Signal(1)
+	SIGINT    = Signal(2)
+	SIGABRT   = Signal(3)
+	SIGILL    = Signal(4)
+	SIGPOLL   = Signal(5)
+	SIGURG    = Signal(6)
+	SIGSTOP   = Signal(7)
+	SIGFPE    = Signal(8)
+	SIGKILL   = Signal(9)
+	SIGBUS    = Signal(10)
+	SIGSEGV   = Signal(11)
+	SIGSYS    = Signal(12)
+	SIGPIPE   = Signal(13)
+	SIGALRM   = Signal(14)
+	SIGTERM   = Signal(15)
+	SIGUSR1   = Signal(16)
+	SIGUSR2   = Signal(17)
+	SIGABND   = Signal(18)
+	SIGCONT   = Signal(19)
+	SIGCHLD   = Signal(20)
+	SIGTTIN   = Signal(21)
+	SIGTTOU   = Signal(22)
+	SIGIO     = Signal(23)
+	SIGQUIT   = Signal(24)
+	SIGTSTP   = Signal(25)
+	SIGTRAP   = Signal(26)
+	SIGIOERR  = Signal(27)
+	SIGWINCH  = Signal(28)
+	SIGXCPU   = Signal(29)
+	SIGXFSZ   = Signal(30)
+	SIGVTALRM = Signal(31)
+	SIGPROF   = Signal(32)
+	SIGDANGER = Signal(33)
+	SIGTHSTOP = Signal(34)
+	SIGTHCONT = Signal(35)
+	SIGTRACE  = Signal(37)
+	SIGDCE    = Signal(38)
+	SIGDUMP   = Signal(39)
+)
+
+// Error table
+var errorList = [...]struct {
+	num  Errno
+	name string
+	desc string
+}{
+	{1, "EDC5001I", "A domain error occurred."},
+	{2, "EDC5002I", "A range error occurred."},
+	{111, "EDC5111I", "Permission denied."},
+	{112, "EDC5112I", "Resource temporarily unavailable."},
+	{113, "EDC5113I", "Bad file descriptor."},
+	{114, "EDC5114I", "Resource busy."},
+	{115, "EDC5115I", "No child processes."},
+	{116, "EDC5116I", "Resource deadlock avoided."},
+	{117, "EDC5117I", "File exists."},
+	{118, "EDC5118I", "Incorrect address."},
+	{119, "EDC5119I", "File too large."},
+	{120, "EDC5120I", "Interrupted function call."},
+	{121, "EDC5121I", "Invalid argument."},
+	{122, "EDC5122I", "Input/output error."},
+	{123, "EDC5123I", "Is a directory."},
+	{124, "EDC5124I", "Too many open files."},
+	{125, "EDC5125I", "Too many links."},
+	{126, "EDC5126I", "Filename too long."},
+	{127, "EDC5127I", "Too many open files in system."},
+	{128, "EDC5128I", "No such device."},
+	{129, "EDC5129I", "No such file or directory."},
+	{130, "EDC5130I", "Exec format error."},
+	{131, "EDC5131I", "No locks available."},
+	{132, "EDC5132I", "Not enough memory."},
+	{133, "EDC5133I", "No space left on device."},
+	{134, "EDC5134I", "Function not implemented."},
+	{135, "EDC5135I", "Not a directory."},
+	{136, "EDC5136I", "Directory not empty."},
+	{137, "EDC5137I", "Inappropriate I/O control operation."},
+	{138, "EDC5138I", "No such device or address."},
+	{139, "EDC5139I", "Operation not permitted."},
+	{140, "EDC5140I", "Broken pipe."},
+	{141, "EDC5141I", "Read-only file system."},
+	{142, "EDC5142I", "Invalid seek."},
+	{143, "EDC5143I", "No such process."},
+	{144, "EDC5144I", "Improper link."},
+	{145, "EDC5145I", "The parameter list is too long, or the message to receive was too large for the buffer."},
+	{146, "EDC5146I", "Too many levels of symbolic links."},
+	{147, "EDC5147I", "Illegal byte sequence."},
+	{148, "", ""},
+	{149, "EDC5149I", "Value Overflow Error."},
+	{150, "EDC5150I", "UNIX System Services is not active."},
+	{151, "EDC5151I", "Dynamic allocation error."},
+	{152, "EDC5152I", "Common VTOC access facility (CVAF) error."},
+	{153, "EDC5153I", "Catalog obtain error."},
+	{156, "EDC5156I", "Process initialization error."},
+	{157, "EDC5157I", "An internal error has occurred."},
+	{158, "EDC5158I", "Bad parameters were passed to the service."},
+	{159, "EDC5159I", "The Physical File System encountered a permanent file error."},
+	{160, "EDC5160I", "Bad character in environment variable name."},
+	{162, "EDC5162I", "The Physical File System encountered a system error."},
+	{163, "EDC5163I", "SAF/RACF extract error."},
+	{164, "EDC5164I", "SAF/RACF error."},
+	{165, "EDC5165I", "System TOD clock not set."},
+	{166, "EDC5166I", "Access mode argument on function call conflicts with PATHOPTS parameter on JCL DD statement."},
+	{167, "EDC5167I", "Access to the UNIX System Services version of the C RTL is denied."},
+	{168, "EDC5168I", "Password has expired."},
+	{169, "EDC5169I", "Password is invalid."},
+	{170, "EDC5170I", "An error was encountered with WLM."},
+	{171, "EDC5171I", "An error was encountered with CPL."},
+	{172, "EDC5172I", "An error was encountered with Application Response Measurement (ARM) component."},
+	{200, "EDC5200I", "The application contains a Language Environment member language that cannot tolerate a fork()."},
+	{201, "EDC5201I", "The Language Environment message file was not found in the hierarchical file system."},
+	{202, "EDC5202E", "DLL facilities are not supported under SPC environment."},
+	{203, "EDC5203E", "DLL facilities are not supported under POSIX environment."},
+	{227, "EDC5227I", "Buffer is not long enough to contain a path definition"},
+	{228, "EDC5228I", "The file referred to is an external link"},
+	{229, "EDC5229I", "No path definition for ddname in effect"},
+	{230, "EDC5230I", "ESM error."},
+	{231, "EDC5231I", "CP or the external security manager had an error"},
+	{232, "EDC5232I", "The function failed because it was invoked from a multithread environment."},
+	{244, "EDC5244I", "The program, module or DLL is not supported in this environment."},
+	{245, "EDC5245I", "Data is not valid."},
+	{246, "EDC5246I", "Unknown system state."},
+	{247, "EDC5247I", "Operation not supported."},
+	{248, "EDC5248I", "The object name specified is not correct."},
+	{249, "EDC5249I", "The function is not allowed."},
+	{257, "EDC5257I", "Function cannot be called in the child process of a fork() from a multithreaded process until exec() is called."},
+	{258, "EDC5258I", "A CUN_RS_NO_UNI_ENV error was issued by Unicode Services."},
+	{259, "EDC5259I", "A CUN_RS_NO_CONVERSION error was issued by Unicode Services."},
+	{260, "EDC5260I", "A CUN_RS_TABLE_NOT_ALIGNED error was issued by Unicode Services."},
+	{262, "EDC5262I", "An iconv() function encountered an unexpected error while using Unicode Services."},
+	{1000, "EDC8000I", "A bad socket-call constant was found in the IUCV header."},
+	{1001, "EDC8001I", "An error was found in the IUCV header."},
+	{1002, "EDC8002I", "A socket descriptor is out of range."},
+	{1003, "EDC8003I", "A socket descriptor is in use."},
+	{1004, "EDC8004I", "Request failed because of an IUCV error."},
+	{1005, "EDC8005I", "Offload box error."},
+	{1006, "EDC8006I", "Offload box restarted."},
+	{1007, "EDC8007I", "Offload box down."},
+	{1008, "EDC8008I", "Already a conflicting call outstanding on socket."},
+	{1009, "EDC8009I", "Request cancelled using a SOCKcallCANCEL request."},
+	{1011, "EDC8011I", "A name of a PFS was specified that either is not configured or is not a Sockets PFS."},
+	{1100, "EDC8100I", "Block device required."},
+	{1101, "EDC8101I", "Text file busy."},
+	{1102, "EDC8102I", "Operation would block."},
+	{1103, "EDC8103I", "Operation now in progress."},
+	{1104, "EDC8104I", "Connection already in progress."},
+	{1105, "EDC8105I", "Socket operation on non-socket."},
+	{1106, "EDC8106I", "Destination address required."},
+	{1107, "EDC8107I", "Message too long."},
+	{1108, "EDC8108I", "Protocol wrong type for socket."},
+	{1109, "EDC8109I", "Protocol not available."},
+	{1110, "EDC8110I", "Protocol not supported."},
+	{1111, "EDC8111I", "Socket type not supported."},
+	{1112, "EDC8112I", "Operation not supported on socket."},
+	{1113, "EDC8113I", "Protocol family not supported."},
+	{1114, "EDC8114I", "Address family not supported."},
+	{1115, "EDC8115I", "Address already in use."},
+	{1116, "EDC8116I", "Address not available."},
+	{1117, "EDC8117I", "Network is down."},
+	{1118, "EDC8118I", "Network is unreachable."},
+	{1119, "EDC8119I", "Network dropped connection on reset."},
+	{1120, "EDC8120I", "Connection ended abnormally."},
+	{1121, "EDC8121I", "Connection reset."},
+	{1122, "EDC8122I", "No buffer space available."},
+	{1123, "EDC8123I", "Socket already connected."},
+	{1124, "EDC8124I", "Socket not connected."},
+	{1125, "EDC8125I", "Can't send after socket shutdown."},
+	{1126, "EDC8126I", "Too many references; can't splice."},
+	{1127, "EDC8127I", "Connection timed out."},
+	{1128, "EDC8128I", "Connection refused."},
+	{1129, "EDC8129I", "Host is not available."},
+	{1130, "EDC8130I", "Host cannot be reached."},
+	{1131, "EDC8131I", "Too many processes."},
+	{1132, "EDC8132I", "Too many users."},
+	{1133, "EDC8133I", "Disk quota exceeded."},
+	{1134, "EDC8134I", "Stale file handle."},
+	{1135, "", ""},
+	{1136, "EDC8136I", "File is not a STREAM."},
+	{1137, "EDC8137I", "STREAMS ioctl() timeout."},
+	{1138, "EDC8138I", "No STREAMS resources."},
+	{1139, "EDC8139I", "The message identified by set_id and msg_id is not in the message catalog."},
+	{1140, "EDC8140I", "Bad message."},
+	{1141, "EDC8141I", "Identifier removed."},
+	{1142, "", ""},
+	{1143, "", ""},
+	{1144, "EDC8144I", "The link has been severed."},
+	{1145, "", ""},
+	{1146, "", ""},
+	{1147, "", ""},
+	{1148, "EDC8148I", "Protocol error."},
+	{1149, "EDC8149I", "Multihop not allowed."},
+	{1150, "", ""},
+	{1151, "", ""},
+	{1152, "EDC8152I", "The asynchronous I/O request has been canceled."},
+	{1159, "EDC8159I", "Function call was interrupted before any data was received."},
+	{1160, "EDC8160I", "Socket reuse is not supported."},
+	{1161, "EDC8161I", "The file system cannot currently be moved."},
+}
+
+// Signal table
+var signalList = [...]struct {
+	num  Signal
+	name string
+	desc string
+}{
+	{1, "SIGHUP", "hangup"},
+	{2, "SIGINT", "interrupt"},
+	{3, "SIGABT", "aborted"},
+	{4, "SIGILL", "illegal instruction"},
+	{5, "SIGPOLL", "pollable event"},
+	{6, "SIGURG", "urgent I/O condition"},
+	{7, "SIGSTOP", "stop process"},
+	{8, "SIGFPE", "floating point exception"},
+	{9, "SIGKILL", "killed"},
+	{10, "SIGBUS", "bus error"},
+	{11, "SIGSEGV", "segmentation fault"},
+	{12, "SIGSYS", "bad argument to routine"},
+	{13, "SIGPIPE", "broken pipe"},
+	{14, "SIGALRM", "alarm clock"},
+	{15, "SIGTERM", "terminated"},
+	{16, "SIGUSR1", "user defined signal 1"},
+	{17, "SIGUSR2", "user defined signal 2"},
+	{18, "SIGABND", "abend"},
+	{19, "SIGCONT", "continued"},
+	{20, "SIGCHLD", "child exited"},
+	{21, "SIGTTIN", "stopped (tty input)"},
+	{22, "SIGTTOU", "stopped (tty output)"},
+	{23, "SIGIO", "I/O possible"},
+	{24, "SIGQUIT", "quit"},
+	{25, "SIGTSTP", "stopped"},
+	{26, "SIGTRAP", "trace/breakpoint trap"},
+	{27, "SIGIOER", "I/O error"},
+	{28, "SIGWINCH", "window changed"},
+	{29, "SIGXCPU", "CPU time limit exceeded"},
+	{30, "SIGXFSZ", "file size limit exceeded"},
+	{31, "SIGVTALRM", "virtual timer expired"},
+	{32, "SIGPROF", "profiling timer expired"},
+	{33, "SIGDANGER", "danger"},
+	{34, "SIGTHSTOP", "stop thread"},
+	{35, "SIGTHCONT", "continue thread"},
+	{37, "SIGTRACE", "trace"},
+	{38, "", "DCE"},
+	{39, "SIGDUMP", "dump"},
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go
index 89c5920..bd001a6 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go
@@ -1,5 +1,6 @@
 // Code generated by linux/mkall.go generatePtracePair("arm", "arm64"). DO NOT EDIT.
 
+//go:build linux && (arm || arm64)
 // +build linux
 // +build arm arm64
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go
index 24b841e..c34d063 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go
@@ -1,5 +1,6 @@
 // Code generated by linux/mkall.go generatePtracePair("mips", "mips64"). DO NOT EDIT.
 
+//go:build linux && (mips || mips64)
 // +build linux
 // +build mips mips64
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go
index 47b0489..3ccf0c0 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go
@@ -1,5 +1,6 @@
 // Code generated by linux/mkall.go generatePtracePair("mipsle", "mips64le"). DO NOT EDIT.
 
+//go:build linux && (mipsle || mips64le)
 // +build linux
 // +build mipsle mips64le
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zptrace_x86_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/zptrace_x86_linux.go
index ea5d9cb..7d65857 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zptrace_x86_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zptrace_x86_linux.go
@@ -1,5 +1,6 @@
 // Code generated by linux/mkall.go generatePtracePair("386", "amd64"). DO NOT EDIT.
 
+//go:build linux && (386 || amd64)
 // +build linux
 // +build 386 amd64
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go
index ed657ff..91a23cc 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go
@@ -1,6 +1,7 @@
 // go run mksyscall_aix_ppc.go -aix -tags aix,ppc syscall_aix.go syscall_aix_ppc.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build aix && ppc
 // +build aix,ppc
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go
index 664b293..33c2609 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go
@@ -1,6 +1,7 @@
 // go run mksyscall_aix_ppc64.go -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build aix && ppc64
 // +build aix,ppc64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go
index 0550da0..8b737fa 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go
@@ -1,8 +1,8 @@
 // go run mksyscall_aix_ppc64.go -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
-// +build aix,ppc64
-// +build gc
+//go:build aix && ppc64 && gc
+// +build aix,ppc64,gc
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go
index cde4dbc..3c26091 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go
@@ -1,8 +1,8 @@
 // go run mksyscall_aix_ppc64.go -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
-// +build aix,ppc64
-// +build gccgo
+//go:build aix && ppc64 && gccgo
+// +build aix,ppc64,gccgo
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.go
deleted file mode 100644
index c8c142c..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// go run mksyscall.go -l32 -tags darwin,386,go1.13 syscall_darwin.1_13.go
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build darwin,386,go1.13
-
-package unix
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-var _ syscall.Errno
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func closedir(dir uintptr) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_closedir_trampoline), uintptr(dir), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_closedir_trampoline()
-
-//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
-	r0, _, _ := syscall_syscall(funcPC(libc_readdir_r_trampoline), uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
-	res = Errno(r0)
-	return
-}
-
-func libc_readdir_r_trampoline()
-
-//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.s
deleted file mode 100644
index 00da1eb..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.s
+++ /dev/null
@@ -1,12 +0,0 @@
-// go run mkasm_darwin.go 386
-// Code generated by the command above; DO NOT EDIT.
-
-// +build go1.13
-
-#include "textflag.h"
-TEXT ·libc_fdopendir_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fdopendir(SB)
-TEXT ·libc_closedir_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_closedir(SB)
-TEXT ·libc_readdir_r_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_readdir_r(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
deleted file mode 100644
index 7f0f117..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
+++ /dev/null
@@ -1,2432 +0,0 @@
-// go run mksyscall.go -l32 -tags darwin,386,go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_386.go
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build darwin,386,go1.12
-
-package unix
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-var _ syscall.Errno
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getgroups_trampoline()
-
-//go:cgo_import_dynamic libc_getgroups getgroups "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setgroups_trampoline()
-
-//go:cgo_import_dynamic libc_setgroups setgroups "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_wait4_trampoline()
-
-//go:cgo_import_dynamic libc_wait4 wait4 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_accept_trampoline()
-
-//go:cgo_import_dynamic libc_accept accept "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_bind_trampoline()
-
-//go:cgo_import_dynamic libc_bind bind "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_connect_trampoline()
-
-//go:cgo_import_dynamic libc_connect connect "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_socket_trampoline()
-
-//go:cgo_import_dynamic libc_socket socket "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getsockopt_trampoline()
-
-//go:cgo_import_dynamic libc_getsockopt getsockopt "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setsockopt_trampoline()
-
-//go:cgo_import_dynamic libc_setsockopt setsockopt "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getpeername_trampoline()
-
-//go:cgo_import_dynamic libc_getpeername getpeername "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getsockname_trampoline()
-
-//go:cgo_import_dynamic libc_getsockname getsockname "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_shutdown_trampoline()
-
-//go:cgo_import_dynamic libc_shutdown shutdown "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := syscall_rawSyscall6(funcPC(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_socketpair_trampoline()
-
-//go:cgo_import_dynamic libc_socketpair socketpair "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_recvfrom_trampoline()
-
-//go:cgo_import_dynamic libc_recvfrom recvfrom "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_sendto_trampoline()
-
-//go:cgo_import_dynamic libc_sendto sendto "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_recvmsg_trampoline()
-
-//go:cgo_import_dynamic libc_recvmsg recvmsg "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_sendmsg_trampoline()
-
-//go:cgo_import_dynamic libc_sendmsg sendmsg "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_kevent_trampoline()
-
-//go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_utimes_trampoline()
-
-//go:cgo_import_dynamic libc_utimes utimes "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_futimes_trampoline()
-
-//go:cgo_import_dynamic libc_futimes futimes "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_poll_trampoline), uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_poll_trampoline()
-
-//go:cgo_import_dynamic libc_poll poll "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Madvise(b []byte, behav int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_madvise_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(behav))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_madvise_trampoline()
-
-//go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mlock_trampoline()
-
-//go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_mlockall_trampoline), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mlockall_trampoline()
-
-//go:cgo_import_dynamic libc_mlockall mlockall "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mprotect_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mprotect_trampoline()
-
-//go:cgo_import_dynamic libc_mprotect mprotect "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Msync(b []byte, flags int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_msync_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(flags))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_msync_trampoline()
-
-//go:cgo_import_dynamic libc_msync msync "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_munlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_munlock_trampoline()
-
-//go:cgo_import_dynamic libc_munlock munlock "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_munlockall_trampoline), 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_munlockall_trampoline()
-
-//go:cgo_import_dynamic libc_munlockall munlockall "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := syscall_rawSyscall(funcPC(libc_pipe_trampoline), 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_pipe_trampoline()
-
-//go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_getxattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
-	sz = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getxattr_trampoline()
-
-//go:cgo_import_dynamic libc_getxattr getxattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_fgetxattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
-	sz = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fgetxattr_trampoline()
-
-//go:cgo_import_dynamic libc_fgetxattr fgetxattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_setxattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setxattr_trampoline()
-
-//go:cgo_import_dynamic libc_setxattr setxattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fsetxattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fsetxattr_trampoline()
-
-//go:cgo_import_dynamic libc_fsetxattr fsetxattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func removexattr(path string, attr string, options int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_removexattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_removexattr_trampoline()
-
-//go:cgo_import_dynamic libc_removexattr removexattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fremovexattr(fd int, attr string, options int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_fremovexattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fremovexattr_trampoline()
-
-//go:cgo_import_dynamic libc_fremovexattr fremovexattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func listxattr(path string, dest *byte, size int, options int) (sz int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_listxattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0)
-	sz = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_listxattr_trampoline()
-
-//go:cgo_import_dynamic libc_listxattr listxattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_flistxattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0)
-	sz = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_flistxattr_trampoline()
-
-//go:cgo_import_dynamic libc_flistxattr flistxattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_setattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setattrlist_trampoline()
-
-//go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fcntl_trampoline()
-
-//go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kill(pid int, signum int, posix int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_kill_trampoline), uintptr(pid), uintptr(signum), uintptr(posix))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_kill_trampoline()
-
-//go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ioctl(fd int, req uint, arg uintptr) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_ioctl_trampoline()
-
-//go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_sysctl_trampoline()
-
-//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
-	_, _, e1 := syscall_syscall9(funcPC(libc_sendfile_trampoline), uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(offset>>32), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_sendfile_trampoline()
-
-//go:cgo_import_dynamic libc_sendfile sendfile "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_access_trampoline()
-
-//go:cgo_import_dynamic libc_access access "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_adjtime_trampoline()
-
-//go:cgo_import_dynamic libc_adjtime adjtime "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_chdir_trampoline()
-
-//go:cgo_import_dynamic libc_chdir chdir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_chflags_trampoline()
-
-//go:cgo_import_dynamic libc_chflags chflags "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_chmod_trampoline()
-
-//go:cgo_import_dynamic libc_chmod chmod "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_chown_trampoline()
-
-//go:cgo_import_dynamic libc_chown chown "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_chroot_trampoline()
-
-//go:cgo_import_dynamic libc_chroot chroot "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ClockGettime(clockid int32, time *Timespec) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_clock_gettime_trampoline), uintptr(clockid), uintptr(unsafe.Pointer(time)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clock_gettime_trampoline()
-
-//go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_close_trampoline), uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_close_trampoline()
-
-//go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Clonefile(src string, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(src)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_clonefile_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clonefile_trampoline()
-
-//go:cgo_import_dynamic libc_clonefile clonefile "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(src)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_clonefileat_trampoline), uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clonefileat_trampoline()
-
-//go:cgo_import_dynamic libc_clonefileat clonefileat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_dup_trampoline()
-
-//go:cgo_import_dynamic libc_dup dup "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_dup2_trampoline()
-
-//go:cgo_import_dynamic libc_dup2 dup2 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exchangedata(path1 string, path2 string, options int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path1)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(path2)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_exchangedata_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_exchangedata_trampoline()
-
-//go:cgo_import_dynamic libc_exchangedata exchangedata "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	syscall_syscall(funcPC(libc_exit_trampoline), uintptr(code), 0, 0)
-	return
-}
-
-func libc_exit_trampoline()
-
-//go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_faccessat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_faccessat_trampoline()
-
-//go:cgo_import_dynamic libc_faccessat faccessat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchdir_trampoline), uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fchdir_trampoline()
-
-//go:cgo_import_dynamic libc_fchdir fchdir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fchflags_trampoline()
-
-//go:cgo_import_dynamic libc_fchflags fchflags "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fchmod_trampoline()
-
-//go:cgo_import_dynamic libc_fchmod fchmod "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fchmodat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fchmodat_trampoline()
-
-//go:cgo_import_dynamic libc_fchmodat fchmodat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fchown_trampoline()
-
-//go:cgo_import_dynamic libc_fchown fchown "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fchownat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fchownat_trampoline()
-
-//go:cgo_import_dynamic libc_fchownat fchownat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fclonefileat_trampoline), uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fclonefileat_trampoline()
-
-//go:cgo_import_dynamic libc_fclonefileat fclonefileat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_flock_trampoline()
-
-//go:cgo_import_dynamic libc_flock flock "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fpathconf_trampoline()
-
-//go:cgo_import_dynamic libc_fpathconf fpathconf "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fsync_trampoline), uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fsync_trampoline()
-
-//go:cgo_import_dynamic libc_fsync fsync "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), uintptr(length>>32))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_ftruncate_trampoline()
-
-//go:cgo_import_dynamic libc_ftruncate ftruncate "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getcwd(buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getcwd_trampoline()
-
-//go:cgo_import_dynamic libc_getcwd getcwd "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdtablesize() (size int) {
-	r0, _, _ := syscall_syscall(funcPC(libc_getdtablesize_trampoline), 0, 0, 0)
-	size = int(r0)
-	return
-}
-
-func libc_getdtablesize_trampoline()
-
-//go:cgo_import_dynamic libc_getdtablesize getdtablesize "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getegid_trampoline), 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-func libc_getegid_trampoline()
-
-//go:cgo_import_dynamic libc_getegid getegid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_geteuid_trampoline), 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-func libc_geteuid_trampoline()
-
-//go:cgo_import_dynamic libc_geteuid geteuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getgid_trampoline), 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-func libc_getgid_trampoline()
-
-//go:cgo_import_dynamic libc_getgid getgid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_getpgid_trampoline), uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getpgid_trampoline()
-
-//go:cgo_import_dynamic libc_getpgid getpgid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getpgrp_trampoline), 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-func libc_getpgrp_trampoline()
-
-//go:cgo_import_dynamic libc_getpgrp getpgrp "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getpid_trampoline), 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-func libc_getpid_trampoline()
-
-//go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getppid_trampoline), 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-func libc_getppid_trampoline()
-
-//go:cgo_import_dynamic libc_getppid getppid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getpriority_trampoline()
-
-//go:cgo_import_dynamic libc_getpriority getpriority "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getrlimit_trampoline()
-
-//go:cgo_import_dynamic libc_getrlimit getrlimit "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getrusage_trampoline()
-
-//go:cgo_import_dynamic libc_getrusage getrusage "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_getsid_trampoline), uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getsid_trampoline()
-
-//go:cgo_import_dynamic libc_getsid getsid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tp *Timeval) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_gettimeofday_trampoline()
-
-//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-func libc_getuid_trampoline()
-
-//go:cgo_import_dynamic libc_getuid getuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_issetugid_trampoline), 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-func libc_issetugid_trampoline()
-
-//go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_kqueue_trampoline), 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_kqueue_trampoline()
-
-//go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_lchown_trampoline()
-
-//go:cgo_import_dynamic libc_lchown lchown "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_link_trampoline()
-
-//go:cgo_import_dynamic libc_link link "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_linkat_trampoline), uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_linkat_trampoline()
-
-//go:cgo_import_dynamic libc_linkat linkat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_listen_trampoline()
-
-//go:cgo_import_dynamic libc_listen listen "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mkdir_trampoline()
-
-//go:cgo_import_dynamic libc_mkdir mkdir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdirat(dirfd int, path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mkdirat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mkdirat_trampoline()
-
-//go:cgo_import_dynamic libc_mkdirat mkdirat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mkfifo_trampoline()
-
-//go:cgo_import_dynamic libc_mkfifo mkfifo "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mknod_trampoline()
-
-//go:cgo_import_dynamic libc_mknod mknod "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_open_trampoline()
-
-//go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_openat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_openat_trampoline()
-
-//go:cgo_import_dynamic libc_openat openat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_pathconf_trampoline()
-
-//go:cgo_import_dynamic libc_pathconf pathconf "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_pread_trampoline()
-
-//go:cgo_import_dynamic libc_pread pread "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_pwrite_trampoline()
-
-//go:cgo_import_dynamic libc_pwrite pwrite "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_read_trampoline()
-
-//go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_readlink_trampoline()
-
-//go:cgo_import_dynamic libc_readlink readlink "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_readlinkat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_readlinkat_trampoline()
-
-//go:cgo_import_dynamic libc_readlinkat readlinkat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_rename_trampoline()
-
-//go:cgo_import_dynamic libc_rename rename "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Renameat(fromfd int, from string, tofd int, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_renameat_trampoline), uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_renameat_trampoline()
-
-//go:cgo_import_dynamic libc_renameat renameat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_revoke_trampoline()
-
-//go:cgo_import_dynamic libc_revoke revoke "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_rmdir_trampoline()
-
-//go:cgo_import_dynamic libc_rmdir rmdir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := syscall_syscall6(funcPC(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(whence), 0, 0)
-	newoffset = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_lseek_trampoline()
-
-//go:cgo_import_dynamic libc_lseek lseek "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_select_trampoline), 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
-}
-
-func libc_select_trampoline()
-
-//go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_setegid_trampoline), uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setegid_trampoline()
-
-//go:cgo_import_dynamic libc_setegid setegid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_seteuid_trampoline), uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_seteuid_trampoline()
-
-//go:cgo_import_dynamic libc_seteuid seteuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setgid_trampoline), uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setgid_trampoline()
-
-//go:cgo_import_dynamic libc_setgid setgid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setlogin(name string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setlogin_trampoline()
-
-//go:cgo_import_dynamic libc_setlogin setlogin "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setpgid_trampoline()
-
-//go:cgo_import_dynamic libc_setpgid setpgid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setpriority_trampoline()
-
-//go:cgo_import_dynamic libc_setpriority setpriority "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setprivexec(flag int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_setprivexec_trampoline), uintptr(flag), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setprivexec_trampoline()
-
-//go:cgo_import_dynamic libc_setprivexec setprivexec "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setregid_trampoline()
-
-//go:cgo_import_dynamic libc_setregid setregid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setreuid_trampoline()
-
-//go:cgo_import_dynamic libc_setreuid setreuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setrlimit_trampoline()
-
-//go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_setsid_trampoline), 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setsid_trampoline()
-
-//go:cgo_import_dynamic libc_setsid setsid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_settimeofday_trampoline()
-
-//go:cgo_import_dynamic libc_settimeofday settimeofday "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setuid_trampoline), uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setuid_trampoline()
-
-//go:cgo_import_dynamic libc_setuid setuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_symlink_trampoline()
-
-//go:cgo_import_dynamic libc_symlink symlink "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_symlinkat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_symlinkat_trampoline()
-
-//go:cgo_import_dynamic libc_symlinkat symlinkat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_sync_trampoline), 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_sync_trampoline()
-
-//go:cgo_import_dynamic libc_sync sync "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), uintptr(length>>32))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_truncate_trampoline()
-
-//go:cgo_import_dynamic libc_truncate truncate "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := syscall_syscall(funcPC(libc_umask_trampoline), uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-func libc_umask_trampoline()
-
-//go:cgo_import_dynamic libc_umask umask "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Undelete(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_undelete_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_undelete_trampoline()
-
-//go:cgo_import_dynamic libc_undelete undelete "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_unlink_trampoline()
-
-//go:cgo_import_dynamic libc_unlink unlink "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlinkat(dirfd int, path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_unlinkat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_unlinkat_trampoline()
-
-//go:cgo_import_dynamic libc_unlinkat unlinkat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_unmount_trampoline()
-
-//go:cgo_import_dynamic libc_unmount unmount "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_write_trampoline()
-
-//go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := syscall_syscall9(funcPC(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos), uintptr(pos>>32), 0, 0)
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mmap_trampoline()
-
-//go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_munmap_trampoline()
-
-//go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fstat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fstat64_trampoline()
-
-//go:cgo_import_dynamic libc_fstat64 fstat64 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fstatat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fstatat64_trampoline()
-
-//go:cgo_import_dynamic libc_fstatat64 fstatat64 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fstatfs64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fstatfs64_trampoline()
-
-//go:cgo_import_dynamic libc_fstatfs64 fstatfs64 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_getfsstat64_trampoline), uintptr(buf), uintptr(size), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getfsstat64_trampoline()
-
-//go:cgo_import_dynamic libc_getfsstat64 getfsstat64 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_lstat64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_lstat64_trampoline()
-
-//go:cgo_import_dynamic libc_lstat64 lstat64 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_ptrace_trampoline()
-
-//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_stat64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_stat64_trampoline()
-
-//go:cgo_import_dynamic libc_stat64 stat64 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_statfs64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_statfs64_trampoline()
-
-//go:cgo_import_dynamic libc_statfs64 statfs64 "/usr/lib/libSystem.B.dylib"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s
deleted file mode 100644
index 1c53979..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s
+++ /dev/null
@@ -1,290 +0,0 @@
-// go run mkasm_darwin.go 386
-// Code generated by the command above; DO NOT EDIT.
-
-// +build go1.12
-
-#include "textflag.h"
-TEXT ·libc_getgroups_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getgroups(SB)
-TEXT ·libc_setgroups_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setgroups(SB)
-TEXT ·libc_wait4_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_wait4(SB)
-TEXT ·libc_accept_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_accept(SB)
-TEXT ·libc_bind_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_bind(SB)
-TEXT ·libc_connect_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_connect(SB)
-TEXT ·libc_socket_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_socket(SB)
-TEXT ·libc_getsockopt_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getsockopt(SB)
-TEXT ·libc_setsockopt_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setsockopt(SB)
-TEXT ·libc_getpeername_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getpeername(SB)
-TEXT ·libc_getsockname_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getsockname(SB)
-TEXT ·libc_shutdown_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_shutdown(SB)
-TEXT ·libc_socketpair_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_socketpair(SB)
-TEXT ·libc_recvfrom_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_recvfrom(SB)
-TEXT ·libc_sendto_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_sendto(SB)
-TEXT ·libc_recvmsg_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_recvmsg(SB)
-TEXT ·libc_sendmsg_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_sendmsg(SB)
-TEXT ·libc_kevent_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_kevent(SB)
-TEXT ·libc_utimes_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_utimes(SB)
-TEXT ·libc_futimes_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_futimes(SB)
-TEXT ·libc_poll_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_poll(SB)
-TEXT ·libc_madvise_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_madvise(SB)
-TEXT ·libc_mlock_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mlock(SB)
-TEXT ·libc_mlockall_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mlockall(SB)
-TEXT ·libc_mprotect_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mprotect(SB)
-TEXT ·libc_msync_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_msync(SB)
-TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_munlock(SB)
-TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_munlockall(SB)
-TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_pipe(SB)
-TEXT ·libc_getxattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getxattr(SB)
-TEXT ·libc_fgetxattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fgetxattr(SB)
-TEXT ·libc_setxattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setxattr(SB)
-TEXT ·libc_fsetxattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fsetxattr(SB)
-TEXT ·libc_removexattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_removexattr(SB)
-TEXT ·libc_fremovexattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fremovexattr(SB)
-TEXT ·libc_listxattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_listxattr(SB)
-TEXT ·libc_flistxattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_flistxattr(SB)
-TEXT ·libc_setattrlist_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setattrlist(SB)
-TEXT ·libc_fcntl_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fcntl(SB)
-TEXT ·libc_kill_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_kill(SB)
-TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_ioctl(SB)
-TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_sysctl(SB)
-TEXT ·libc_sendfile_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_sendfile(SB)
-TEXT ·libc_access_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_access(SB)
-TEXT ·libc_adjtime_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_adjtime(SB)
-TEXT ·libc_chdir_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_chdir(SB)
-TEXT ·libc_chflags_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_chflags(SB)
-TEXT ·libc_chmod_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_chmod(SB)
-TEXT ·libc_chown_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_chown(SB)
-TEXT ·libc_chroot_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_chroot(SB)
-TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clock_gettime(SB)
-TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_close(SB)
-TEXT ·libc_clonefile_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clonefile(SB)
-TEXT ·libc_clonefileat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clonefileat(SB)
-TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_dup(SB)
-TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_dup2(SB)
-TEXT ·libc_exchangedata_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_exchangedata(SB)
-TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_exit(SB)
-TEXT ·libc_faccessat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_faccessat(SB)
-TEXT ·libc_fchdir_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fchdir(SB)
-TEXT ·libc_fchflags_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fchflags(SB)
-TEXT ·libc_fchmod_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fchmod(SB)
-TEXT ·libc_fchmodat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fchmodat(SB)
-TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fchown(SB)
-TEXT ·libc_fchownat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fchownat(SB)
-TEXT ·libc_fclonefileat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fclonefileat(SB)
-TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_flock(SB)
-TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fpathconf(SB)
-TEXT ·libc_fsync_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fsync(SB)
-TEXT ·libc_ftruncate_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_ftruncate(SB)
-TEXT ·libc_getcwd_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getcwd(SB)
-TEXT ·libc_getdtablesize_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getdtablesize(SB)
-TEXT ·libc_getegid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getegid(SB)
-TEXT ·libc_geteuid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_geteuid(SB)
-TEXT ·libc_getgid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getgid(SB)
-TEXT ·libc_getpgid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getpgid(SB)
-TEXT ·libc_getpgrp_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getpgrp(SB)
-TEXT ·libc_getpid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getpid(SB)
-TEXT ·libc_getppid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getppid(SB)
-TEXT ·libc_getpriority_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getpriority(SB)
-TEXT ·libc_getrlimit_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getrlimit(SB)
-TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getrusage(SB)
-TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getsid(SB)
-TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_gettimeofday(SB)
-TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getuid(SB)
-TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_issetugid(SB)
-TEXT ·libc_kqueue_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_kqueue(SB)
-TEXT ·libc_lchown_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_lchown(SB)
-TEXT ·libc_link_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_link(SB)
-TEXT ·libc_linkat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_linkat(SB)
-TEXT ·libc_listen_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_listen(SB)
-TEXT ·libc_mkdir_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mkdir(SB)
-TEXT ·libc_mkdirat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mkdirat(SB)
-TEXT ·libc_mkfifo_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mkfifo(SB)
-TEXT ·libc_mknod_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mknod(SB)
-TEXT ·libc_open_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_open(SB)
-TEXT ·libc_openat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_openat(SB)
-TEXT ·libc_pathconf_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_pathconf(SB)
-TEXT ·libc_pread_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_pread(SB)
-TEXT ·libc_pwrite_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_pwrite(SB)
-TEXT ·libc_read_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_read(SB)
-TEXT ·libc_readlink_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_readlink(SB)
-TEXT ·libc_readlinkat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_readlinkat(SB)
-TEXT ·libc_rename_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_rename(SB)
-TEXT ·libc_renameat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_renameat(SB)
-TEXT ·libc_revoke_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_revoke(SB)
-TEXT ·libc_rmdir_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_rmdir(SB)
-TEXT ·libc_lseek_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_lseek(SB)
-TEXT ·libc_select_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_select(SB)
-TEXT ·libc_setegid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setegid(SB)
-TEXT ·libc_seteuid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_seteuid(SB)
-TEXT ·libc_setgid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setgid(SB)
-TEXT ·libc_setlogin_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setlogin(SB)
-TEXT ·libc_setpgid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setpgid(SB)
-TEXT ·libc_setpriority_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setpriority(SB)
-TEXT ·libc_setprivexec_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setprivexec(SB)
-TEXT ·libc_setregid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setregid(SB)
-TEXT ·libc_setreuid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setreuid(SB)
-TEXT ·libc_setrlimit_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setrlimit(SB)
-TEXT ·libc_setsid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setsid(SB)
-TEXT ·libc_settimeofday_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_settimeofday(SB)
-TEXT ·libc_setuid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setuid(SB)
-TEXT ·libc_symlink_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_symlink(SB)
-TEXT ·libc_symlinkat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_symlinkat(SB)
-TEXT ·libc_sync_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_sync(SB)
-TEXT ·libc_truncate_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_truncate(SB)
-TEXT ·libc_umask_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_umask(SB)
-TEXT ·libc_undelete_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_undelete(SB)
-TEXT ·libc_unlink_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_unlink(SB)
-TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_unlinkat(SB)
-TEXT ·libc_unmount_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_unmount(SB)
-TEXT ·libc_write_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_write(SB)
-TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mmap(SB)
-TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_munmap(SB)
-TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fstat64(SB)
-TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fstatat64(SB)
-TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fstatfs64(SB)
-TEXT ·libc_getfsstat64_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getfsstat64(SB)
-TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_lstat64(SB)
-TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_ptrace(SB)
-TEXT ·libc_stat64_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_stat64(SB)
-TEXT ·libc_statfs64_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_statfs64(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go
index 8882623..a06eb09 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags darwin,amd64,go1.13 syscall_darwin.1_13.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build darwin && amd64 && go1.13
 // +build darwin,amd64,go1.13
 
 package unix
@@ -15,25 +16,25 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func closedir(dir uintptr) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_closedir_trampoline), uintptr(dir), 0, 0)
+	_, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_closedir_trampoline()
+var libc_closedir_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
-	r0, _, _ := syscall_syscall(funcPC(libc_readdir_r_trampoline), uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
+	r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
 	res = Errno(r0)
 	return
 }
 
-func libc_readdir_r_trampoline()
+var libc_readdir_r_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s
index d671e83..d6c3e25 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s
@@ -1,12 +1,25 @@
 // go run mkasm_darwin.go amd64
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build go1.13
 // +build go1.13
 
 #include "textflag.h"
-TEXT ·libc_fdopendir_trampoline(SB),NOSPLIT,$0-0
+
+TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fdopendir(SB)
-TEXT ·libc_closedir_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fdopendir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB)
+
+TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_closedir(SB)
-TEXT ·libc_readdir_r_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_closedir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB)
+
+TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_readdir_r(SB)
+
+GLOBL	·libc_readdir_r_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
index 2daf0bd..d4efe8d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags darwin,amd64,go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build darwin && amd64 && go1.12
 // +build darwin,amd64,go1.12
 
 package unix
@@ -15,7 +16,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -23,28 +24,28 @@
 	return
 }
 
-func libc_getgroups_trampoline()
+var libc_getgroups_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getgroups getgroups "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setgroups_trampoline()
+var libc_setgroups_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setgroups setgroups "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_wait4_trampoline_addr, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -52,14 +53,14 @@
 	return
 }
 
-func libc_wait4_trampoline()
+var libc_wait4_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_wait4 wait4 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall_syscall(libc_accept_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -67,42 +68,42 @@
 	return
 }
 
-func libc_accept_trampoline()
+var libc_accept_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_accept accept "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_bind_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_bind_trampoline()
+var libc_bind_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_bind bind "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_connect_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_connect_trampoline()
+var libc_connect_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_connect connect "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := syscall_rawSyscall(libc_socket_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -110,91 +111,91 @@
 	return
 }
 
-func libc_socket_trampoline()
+var libc_socket_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_socket socket "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall_syscall6(libc_getsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_getsockopt_trampoline()
+var libc_getsockopt_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getsockopt getsockopt "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall_syscall6(libc_setsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setsockopt_trampoline()
+var libc_setsockopt_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setsockopt setsockopt "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getpeername_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_getpeername_trampoline()
+var libc_getpeername_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getpeername getpeername "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getsockname_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_getsockname_trampoline()
+var libc_getsockname_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getsockname getsockname "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_shutdown_trampoline_addr, uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_shutdown_trampoline()
+var libc_shutdown_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_shutdown shutdown "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := syscall_rawSyscall6(funcPC(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := syscall_rawSyscall6(libc_socketpair_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_socketpair_trampoline()
+var libc_socketpair_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_socketpair socketpair "/usr/lib/libSystem.B.dylib"
 
@@ -207,7 +208,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall_syscall6(libc_recvfrom_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -215,7 +216,7 @@
 	return
 }
 
-func libc_recvfrom_trampoline()
+var libc_recvfrom_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_recvfrom recvfrom "/usr/lib/libSystem.B.dylib"
 
@@ -228,21 +229,21 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall_syscall6(libc_sendto_trampoline_addr, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_sendto_trampoline()
+var libc_sendto_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_sendto sendto "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_recvmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -250,14 +251,14 @@
 	return
 }
 
-func libc_recvmsg_trampoline()
+var libc_recvmsg_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_recvmsg recvmsg "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_sendmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -265,14 +266,14 @@
 	return
 }
 
-func libc_sendmsg_trampoline()
+var libc_sendmsg_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_sendmsg sendmsg "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall_syscall6(libc_kevent_trampoline_addr, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -280,7 +281,7 @@
 	return
 }
 
-func libc_kevent_trampoline()
+var libc_kevent_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib"
 
@@ -292,35 +293,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_utimes_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_utimes_trampoline()
+var libc_utimes_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_utimes utimes "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_futimes_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_futimes_trampoline()
+var libc_futimes_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_futimes futimes "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_poll_trampoline), uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
+	r0, _, e1 := syscall_syscall(libc_poll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -328,7 +329,7 @@
 	return
 }
 
-func libc_poll_trampoline()
+var libc_poll_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_poll poll "/usr/lib/libSystem.B.dylib"
 
@@ -341,14 +342,14 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_madvise_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	_, _, e1 := syscall_syscall(libc_madvise_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(behav))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_madvise_trampoline()
+var libc_madvise_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib"
 
@@ -361,28 +362,28 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_mlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mlock_trampoline()
+var libc_mlock_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlockall(flags int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_mlockall_trampoline), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall(libc_mlockall_trampoline_addr, uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mlockall_trampoline()
+var libc_mlockall_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mlockall mlockall "/usr/lib/libSystem.B.dylib"
 
@@ -395,14 +396,14 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mprotect_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	_, _, e1 := syscall_syscall(libc_mprotect_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(prot))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mprotect_trampoline()
+var libc_mprotect_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mprotect mprotect "/usr/lib/libSystem.B.dylib"
 
@@ -415,14 +416,14 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_msync_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_msync_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_msync_trampoline()
+var libc_msync_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_msync msync "/usr/lib/libSystem.B.dylib"
 
@@ -435,44 +436,42 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_munlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_munlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_munlock_trampoline()
+var libc_munlock_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_munlock munlock "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlockall() (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_munlockall_trampoline), 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_munlockall_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_munlockall_trampoline()
+var libc_munlockall_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_munlockall munlockall "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := syscall_rawSyscall(funcPC(libc_pipe_trampoline), 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
+func pipe(p *[2]int32) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_pipe_trampoline_addr, uintptr(unsafe.Pointer(p)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_pipe_trampoline()
+var libc_pipe_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib"
 
@@ -489,7 +488,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_getxattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
+	r0, _, e1 := syscall_syscall6(libc_getxattr_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
 	sz = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -497,7 +496,7 @@
 	return
 }
 
-func libc_getxattr_trampoline()
+var libc_getxattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getxattr getxattr "/usr/lib/libSystem.B.dylib"
 
@@ -509,7 +508,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_fgetxattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
+	r0, _, e1 := syscall_syscall6(libc_fgetxattr_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
 	sz = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -517,7 +516,7 @@
 	return
 }
 
-func libc_fgetxattr_trampoline()
+var libc_fgetxattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fgetxattr fgetxattr "/usr/lib/libSystem.B.dylib"
 
@@ -534,14 +533,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_setxattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options))
+	_, _, e1 := syscall_syscall6(libc_setxattr_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setxattr_trampoline()
+var libc_setxattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setxattr setxattr "/usr/lib/libSystem.B.dylib"
 
@@ -553,14 +552,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fsetxattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options))
+	_, _, e1 := syscall_syscall6(libc_fsetxattr_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fsetxattr_trampoline()
+var libc_fsetxattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fsetxattr fsetxattr "/usr/lib/libSystem.B.dylib"
 
@@ -577,14 +576,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_removexattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
+	_, _, e1 := syscall_syscall(libc_removexattr_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_removexattr_trampoline()
+var libc_removexattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_removexattr removexattr "/usr/lib/libSystem.B.dylib"
 
@@ -596,14 +595,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_fremovexattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options))
+	_, _, e1 := syscall_syscall(libc_fremovexattr_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fremovexattr_trampoline()
+var libc_fremovexattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fremovexattr fremovexattr "/usr/lib/libSystem.B.dylib"
 
@@ -615,7 +614,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_listxattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_listxattr_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0)
 	sz = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -623,14 +622,14 @@
 	return
 }
 
-func libc_listxattr_trampoline()
+var libc_listxattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_listxattr listxattr "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_flistxattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_flistxattr_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0)
 	sz = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -638,28 +637,28 @@
 	return
 }
 
-func libc_flistxattr_trampoline()
+var libc_flistxattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_flistxattr flistxattr "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_setattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
+	_, _, e1 := syscall_syscall6(libc_setattrlist_trampoline_addr, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setattrlist_trampoline()
+var libc_setattrlist_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+	r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -667,35 +666,35 @@
 	return
 }
 
-func libc_fcntl_trampoline()
+var libc_fcntl_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kill(pid int, signum int, posix int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_kill_trampoline), uintptr(pid), uintptr(signum), uintptr(posix))
+	_, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), uintptr(posix))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_kill_trampoline()
+var libc_kill_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctl(fd int, req uint, arg uintptr) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_ioctl_trampoline()
+var libc_ioctl_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib"
 
@@ -708,28 +707,28 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	_, _, e1 := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_sysctl_trampoline()
+var libc_sysctl_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_sendfile_trampoline), uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
+	_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_sendfile_trampoline()
+var libc_sendfile_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_sendfile sendfile "/usr/lib/libSystem.B.dylib"
 
@@ -741,28 +740,28 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_access_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_access_trampoline()
+var libc_access_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_access access "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall_syscall(libc_adjtime_trampoline_addr, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_adjtime_trampoline()
+var libc_adjtime_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_adjtime adjtime "/usr/lib/libSystem.B.dylib"
 
@@ -774,14 +773,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_chdir_trampoline()
+var libc_chdir_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_chdir chdir "/usr/lib/libSystem.B.dylib"
 
@@ -793,14 +792,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_chflags_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_chflags_trampoline()
+var libc_chflags_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_chflags chflags "/usr/lib/libSystem.B.dylib"
 
@@ -812,14 +811,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_chmod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_chmod_trampoline()
+var libc_chmod_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_chmod chmod "/usr/lib/libSystem.B.dylib"
 
@@ -831,14 +830,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_chown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_chown_trampoline()
+var libc_chown_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_chown chown "/usr/lib/libSystem.B.dylib"
 
@@ -850,42 +849,42 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chroot_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_chroot_trampoline()
+var libc_chroot_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_chroot chroot "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ClockGettime(clockid int32, time *Timespec) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_clock_gettime_trampoline), uintptr(clockid), uintptr(unsafe.Pointer(time)), 0)
+	_, _, e1 := syscall_syscall(libc_clock_gettime_trampoline_addr, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_clock_gettime_trampoline()
+var libc_clock_gettime_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_close_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_close_trampoline()
+var libc_close_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib"
 
@@ -902,14 +901,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_clonefile_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_clonefile_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_clonefile_trampoline()
+var libc_clonefile_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_clonefile clonefile "/usr/lib/libSystem.B.dylib"
 
@@ -926,21 +925,21 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_clonefileat_trampoline), uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_clonefileat_trampoline_addr, uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_clonefileat_trampoline()
+var libc_clonefileat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_clonefileat clonefileat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0)
+	r0, _, e1 := syscall_syscall(libc_dup_trampoline_addr, uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -948,21 +947,21 @@
 	return
 }
 
-func libc_dup_trampoline()
+var libc_dup_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_dup dup "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_dup2_trampoline()
+var libc_dup2_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_dup2 dup2 "/usr/lib/libSystem.B.dylib"
 
@@ -979,25 +978,25 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_exchangedata_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
+	_, _, e1 := syscall_syscall(libc_exchangedata_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_exchangedata_trampoline()
+var libc_exchangedata_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_exchangedata exchangedata "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Exit(code int) {
-	syscall_syscall(funcPC(libc_exit_trampoline), uintptr(code), 0, 0)
+	syscall_syscall(libc_exit_trampoline_addr, uintptr(code), 0, 0)
 	return
 }
 
-func libc_exit_trampoline()
+var libc_exit_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib"
 
@@ -1009,56 +1008,56 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_faccessat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_faccessat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_faccessat_trampoline()
+var libc_faccessat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_faccessat faccessat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchdir_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fchdir_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fchdir_trampoline()
+var libc_fchdir_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fchdir fchdir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_fchflags_trampoline_addr, uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fchflags_trampoline()
+var libc_fchflags_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fchflags fchflags "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_fchmod_trampoline_addr, uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fchmod_trampoline()
+var libc_fchmod_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fchmod fchmod "/usr/lib/libSystem.B.dylib"
 
@@ -1070,28 +1069,28 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fchmodat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fchmodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fchmodat_trampoline()
+var libc_fchmodat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fchmodat fchmodat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_fchown_trampoline_addr, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fchown_trampoline()
+var libc_fchown_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fchown fchown "/usr/lib/libSystem.B.dylib"
 
@@ -1103,14 +1102,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fchownat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_fchownat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fchownat_trampoline()
+var libc_fchownat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fchownat fchownat "/usr/lib/libSystem.B.dylib"
 
@@ -1122,35 +1121,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fclonefileat_trampoline), uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fclonefileat_trampoline_addr, uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fclonefileat_trampoline()
+var libc_fclonefileat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fclonefileat fclonefileat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_flock_trampoline()
+var libc_flock_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_flock flock "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_fpathconf_trampoline_addr, uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1158,35 +1157,35 @@
 	return
 }
 
-func libc_fpathconf_trampoline()
+var libc_fpathconf_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fpathconf fpathconf "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fsync_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fsync_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fsync_trampoline()
+var libc_fsync_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fsync fsync "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), 0)
+	_, _, e1 := syscall_syscall(libc_ftruncate_trampoline_addr, uintptr(fd), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_ftruncate_trampoline()
+var libc_ftruncate_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_ftruncate ftruncate "/usr/lib/libSystem.B.dylib"
 
@@ -1199,7 +1198,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall_syscall(libc_getcwd_trampoline_addr, uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1207,62 +1206,62 @@
 	return
 }
 
-func libc_getcwd_trampoline()
+var libc_getcwd_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getcwd getcwd "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getdtablesize() (size int) {
-	r0, _, _ := syscall_syscall(funcPC(libc_getdtablesize_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_syscall(libc_getdtablesize_trampoline_addr, 0, 0, 0)
 	size = int(r0)
 	return
 }
 
-func libc_getdtablesize_trampoline()
+var libc_getdtablesize_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getdtablesize getdtablesize "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getegid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getegid_trampoline_addr, 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
-func libc_getegid_trampoline()
+var libc_getegid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getegid getegid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_geteuid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_geteuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
-func libc_geteuid_trampoline()
+var libc_geteuid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_geteuid geteuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getgid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getgid_trampoline_addr, 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
-func libc_getgid_trampoline()
+var libc_getgid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getgid getgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_getpgid_trampoline), uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getpgid_trampoline_addr, uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1270,50 +1269,50 @@
 	return
 }
 
-func libc_getpgid_trampoline()
+var libc_getpgid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getpgid getpgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getpgrp_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpgrp_trampoline_addr, 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
-func libc_getpgrp_trampoline()
+var libc_getpgrp_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getpgrp getpgrp "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getpid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
-func libc_getpid_trampoline()
+var libc_getpid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getppid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getppid_trampoline_addr, 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
-func libc_getppid_trampoline()
+var libc_getppid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getppid getppid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall_syscall(libc_getpriority_trampoline_addr, uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1321,42 +1320,42 @@
 	return
 }
 
-func libc_getpriority_trampoline()
+var libc_getpriority_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getpriority getpriority "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_getrlimit_trampoline()
+var libc_getrlimit_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getrlimit getrlimit "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrusage_trampoline_addr, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_getrusage_trampoline()
+var libc_getrusage_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getrusage getrusage "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_getsid_trampoline), uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getsid_trampoline_addr, uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1364,52 +1363,52 @@
 	return
 }
 
-func libc_getsid_trampoline()
+var libc_getsid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getsid getsid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tp *Timeval) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_gettimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_gettimeofday_trampoline()
+var libc_gettimeofday_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
-func libc_getuid_trampoline()
+var libc_getuid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getuid getuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_issetugid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_issetugid_trampoline_addr, 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
-func libc_issetugid_trampoline()
+var libc_issetugid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_kqueue_trampoline), 0, 0, 0)
+	r0, _, e1 := syscall_syscall(libc_kqueue_trampoline_addr, 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1417,7 +1416,7 @@
 	return
 }
 
-func libc_kqueue_trampoline()
+var libc_kqueue_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib"
 
@@ -1429,14 +1428,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_lchown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_lchown_trampoline()
+var libc_lchown_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_lchown lchown "/usr/lib/libSystem.B.dylib"
 
@@ -1453,14 +1452,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_link_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_link_trampoline()
+var libc_link_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_link link "/usr/lib/libSystem.B.dylib"
 
@@ -1477,28 +1476,28 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_linkat_trampoline), uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_linkat_trampoline_addr, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_linkat_trampoline()
+var libc_linkat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_linkat linkat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall_syscall(libc_listen_trampoline_addr, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_listen_trampoline()
+var libc_listen_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_listen listen "/usr/lib/libSystem.B.dylib"
 
@@ -1510,14 +1509,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mkdir_trampoline()
+var libc_mkdir_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mkdir mkdir "/usr/lib/libSystem.B.dylib"
 
@@ -1529,14 +1528,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mkdirat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	_, _, e1 := syscall_syscall(libc_mkdirat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mkdirat_trampoline()
+var libc_mkdirat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mkdirat mkdirat "/usr/lib/libSystem.B.dylib"
 
@@ -1548,14 +1547,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkfifo_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mkfifo_trampoline()
+var libc_mkfifo_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mkfifo mkfifo "/usr/lib/libSystem.B.dylib"
 
@@ -1567,14 +1566,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall_syscall(libc_mknod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mknod_trampoline()
+var libc_mknod_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mknod mknod "/usr/lib/libSystem.B.dylib"
 
@@ -1586,7 +1585,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall_syscall(libc_open_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1594,7 +1593,7 @@
 	return
 }
 
-func libc_open_trampoline()
+var libc_open_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib"
 
@@ -1606,7 +1605,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_openat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_openat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1614,7 +1613,7 @@
 	return
 }
 
-func libc_openat_trampoline()
+var libc_openat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_openat openat "/usr/lib/libSystem.B.dylib"
 
@@ -1626,7 +1625,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_pathconf_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1634,7 +1633,7 @@
 	return
 }
 
-func libc_pathconf_trampoline()
+var libc_pathconf_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_pathconf pathconf "/usr/lib/libSystem.B.dylib"
 
@@ -1647,7 +1646,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_pread_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1655,7 +1654,7 @@
 	return
 }
 
-func libc_pread_trampoline()
+var libc_pread_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_pread pread "/usr/lib/libSystem.B.dylib"
 
@@ -1668,7 +1667,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_pwrite_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1676,7 +1675,7 @@
 	return
 }
 
-func libc_pwrite_trampoline()
+var libc_pwrite_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_pwrite pwrite "/usr/lib/libSystem.B.dylib"
 
@@ -1689,7 +1688,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1697,7 +1696,7 @@
 	return
 }
 
-func libc_read_trampoline()
+var libc_read_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib"
 
@@ -1715,7 +1714,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall_syscall(libc_readlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1723,7 +1722,7 @@
 	return
 }
 
-func libc_readlink_trampoline()
+var libc_readlink_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_readlink readlink "/usr/lib/libSystem.B.dylib"
 
@@ -1741,7 +1740,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_readlinkat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_readlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1749,7 +1748,7 @@
 	return
 }
 
-func libc_readlinkat_trampoline()
+var libc_readlinkat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_readlinkat readlinkat "/usr/lib/libSystem.B.dylib"
 
@@ -1766,14 +1765,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_rename_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_rename_trampoline()
+var libc_rename_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_rename rename "/usr/lib/libSystem.B.dylib"
 
@@ -1790,14 +1789,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_renameat_trampoline), uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_renameat_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_renameat_trampoline()
+var libc_renameat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_renameat renameat "/usr/lib/libSystem.B.dylib"
 
@@ -1809,14 +1808,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_revoke_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_revoke_trampoline()
+var libc_revoke_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_revoke revoke "/usr/lib/libSystem.B.dylib"
 
@@ -1828,21 +1827,21 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_rmdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_rmdir_trampoline()
+var libc_rmdir_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_rmdir rmdir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(whence))
+	r0, _, e1 := syscall_syscall(libc_lseek_trampoline_addr, uintptr(fd), uintptr(offset), uintptr(whence))
 	newoffset = int64(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1850,14 +1849,14 @@
 	return
 }
 
-func libc_lseek_trampoline()
+var libc_lseek_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_lseek lseek "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_select_trampoline), uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	r0, _, e1 := syscall_syscall6(libc_select_trampoline_addr, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1865,49 +1864,49 @@
 	return
 }
 
-func libc_select_trampoline()
+var libc_select_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_setegid_trampoline), uintptr(egid), 0, 0)
+	_, _, e1 := syscall_syscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setegid_trampoline()
+var libc_setegid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setegid setegid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_seteuid_trampoline), uintptr(euid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_seteuid_trampoline_addr, uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_seteuid_trampoline()
+var libc_seteuid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_seteuid seteuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setgid_trampoline), uintptr(gid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgid_trampoline_addr, uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setgid_trampoline()
+var libc_setgid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setgid setgid "/usr/lib/libSystem.B.dylib"
 
@@ -1919,105 +1918,105 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_setlogin_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setlogin_trampoline()
+var libc_setlogin_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setlogin setlogin "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setpgid_trampoline_addr, uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setpgid_trampoline()
+var libc_setpgid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setpgid setpgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall_syscall(libc_setpriority_trampoline_addr, uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setpriority_trampoline()
+var libc_setpriority_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setpriority setpriority "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setprivexec(flag int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_setprivexec_trampoline), uintptr(flag), 0, 0)
+	_, _, e1 := syscall_syscall(libc_setprivexec_trampoline_addr, uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setprivexec_trampoline()
+var libc_setprivexec_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setprivexec setprivexec "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setregid_trampoline_addr, uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setregid_trampoline()
+var libc_setregid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setregid setregid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setreuid_trampoline_addr, uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setreuid_trampoline()
+var libc_setreuid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setreuid setreuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setrlimit_trampoline()
+var libc_setrlimit_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_setsid_trampoline), 0, 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2025,35 +2024,35 @@
 	return
 }
 
-func libc_setsid_trampoline()
+var libc_setsid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setsid setsid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_settimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_settimeofday_trampoline()
+var libc_settimeofday_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_settimeofday settimeofday "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setuid_trampoline), uintptr(uid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setuid_trampoline_addr, uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setuid_trampoline()
+var libc_setuid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setuid setuid "/usr/lib/libSystem.B.dylib"
 
@@ -2070,14 +2069,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_symlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_symlink_trampoline()
+var libc_symlink_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_symlink symlink "/usr/lib/libSystem.B.dylib"
 
@@ -2094,28 +2093,28 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_symlinkat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	_, _, e1 := syscall_syscall(libc_symlinkat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_symlinkat_trampoline()
+var libc_symlinkat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_symlinkat symlinkat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_sync_trampoline), 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_sync_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_sync_trampoline()
+var libc_sync_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_sync sync "/usr/lib/libSystem.B.dylib"
 
@@ -2127,26 +2126,26 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	_, _, e1 := syscall_syscall(libc_truncate_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_truncate_trampoline()
+var libc_truncate_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_truncate truncate "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := syscall_syscall(funcPC(libc_umask_trampoline), uintptr(newmask), 0, 0)
+	r0, _, _ := syscall_syscall(libc_umask_trampoline_addr, uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
-func libc_umask_trampoline()
+var libc_umask_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_umask umask "/usr/lib/libSystem.B.dylib"
 
@@ -2158,14 +2157,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_undelete_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_undelete_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_undelete_trampoline()
+var libc_undelete_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_undelete undelete "/usr/lib/libSystem.B.dylib"
 
@@ -2177,14 +2176,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_unlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_unlink_trampoline()
+var libc_unlink_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_unlink unlink "/usr/lib/libSystem.B.dylib"
 
@@ -2196,14 +2195,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_unlinkat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_unlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_unlinkat_trampoline()
+var libc_unlinkat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_unlinkat unlinkat "/usr/lib/libSystem.B.dylib"
 
@@ -2215,14 +2214,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_unmount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_unmount_trampoline()
+var libc_unmount_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_unmount unmount "/usr/lib/libSystem.B.dylib"
 
@@ -2235,7 +2234,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2243,14 +2242,14 @@
 	return
 }
 
-func libc_write_trampoline()
+var libc_write_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	r0, _, e1 := syscall_syscall6(libc_mmap_trampoline_addr, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2258,28 +2257,28 @@
 	return
 }
 
-func libc_mmap_trampoline()
+var libc_mmap_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall_syscall(libc_munmap_trampoline_addr, uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_munmap_trampoline()
+var libc_munmap_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2290,7 +2289,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2301,14 +2300,14 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fstat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstat64_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fstat64_trampoline()
+var libc_fstat64_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fstat64 fstat64 "/usr/lib/libSystem.B.dylib"
 
@@ -2320,35 +2319,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fstatat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fstatat64_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fstatat64_trampoline()
+var libc_fstatat64_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fstatat64 fstatat64 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fstatfs64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstatfs64_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fstatfs64_trampoline()
+var libc_fstatfs64_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fstatfs64 fstatfs64 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_getfsstat64_trampoline), uintptr(buf), uintptr(size), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_getfsstat64_trampoline_addr, uintptr(buf), uintptr(size), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2356,7 +2355,7 @@
 	return
 }
 
-func libc_getfsstat64_trampoline()
+var libc_getfsstat64_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getfsstat64 getfsstat64 "/usr/lib/libSystem.B.dylib"
 
@@ -2368,28 +2367,28 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_lstat64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_lstat64_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_lstat64_trampoline()
+var libc_lstat64_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_lstat64 lstat64 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+func ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) {
+	_, _, e1 := syscall_syscall6(libc_ptrace_trampoline_addr, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_ptrace_trampoline()
+var libc_ptrace_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
 
@@ -2401,14 +2400,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_stat64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_stat64_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_stat64_trampoline()
+var libc_stat64_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_stat64 stat64 "/usr/lib/libSystem.B.dylib"
 
@@ -2420,13 +2419,13 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_statfs64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_statfs64_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_statfs64_trampoline()
+var libc_statfs64_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_statfs64 statfs64 "/usr/lib/libSystem.B.dylib"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
index c77bd6e..bc169c2 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
@@ -1,290 +1,859 @@
 // go run mkasm_darwin.go amd64
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build go1.12
 // +build go1.12
 
 #include "textflag.h"
-TEXT ·libc_getgroups_trampoline(SB),NOSPLIT,$0-0
+
+TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getgroups(SB)
-TEXT ·libc_setgroups_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getgroups_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB)
+
+TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setgroups(SB)
-TEXT ·libc_wait4_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setgroups_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB)
+
+TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_wait4(SB)
-TEXT ·libc_accept_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_wait4_trampoline_addr(SB), RODATA, $8
+DATA	·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB)
+
+TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_accept(SB)
-TEXT ·libc_bind_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_accept_trampoline_addr(SB), RODATA, $8
+DATA	·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB)
+
+TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_bind(SB)
-TEXT ·libc_connect_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_bind_trampoline_addr(SB), RODATA, $8
+DATA	·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB)
+
+TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_connect(SB)
-TEXT ·libc_socket_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_connect_trampoline_addr(SB), RODATA, $8
+DATA	·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB)
+
+TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_socket(SB)
-TEXT ·libc_getsockopt_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_socket_trampoline_addr(SB), RODATA, $8
+DATA	·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB)
+
+TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getsockopt(SB)
-TEXT ·libc_setsockopt_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getsockopt_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB)
+
+TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setsockopt(SB)
-TEXT ·libc_getpeername_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setsockopt_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB)
+
+TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getpeername(SB)
-TEXT ·libc_getsockname_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getpeername_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB)
+
+TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getsockname(SB)
-TEXT ·libc_shutdown_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getsockname_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB)
+
+TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_shutdown(SB)
-TEXT ·libc_socketpair_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_shutdown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB)
+
+TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_socketpair(SB)
-TEXT ·libc_recvfrom_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_socketpair_trampoline_addr(SB), RODATA, $8
+DATA	·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB)
+
+TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_recvfrom(SB)
-TEXT ·libc_sendto_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_recvfrom_trampoline_addr(SB), RODATA, $8
+DATA	·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB)
+
+TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_sendto(SB)
-TEXT ·libc_recvmsg_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_sendto_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB)
+
+TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_recvmsg(SB)
-TEXT ·libc_sendmsg_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_recvmsg_trampoline_addr(SB), RODATA, $8
+DATA	·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB)
+
+TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_sendmsg(SB)
-TEXT ·libc_kevent_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_sendmsg_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB)
+
+TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_kevent(SB)
-TEXT ·libc_utimes_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_kevent_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB)
+
+TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_utimes(SB)
-TEXT ·libc_futimes_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_utimes_trampoline_addr(SB), RODATA, $8
+DATA	·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB)
+
+TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_futimes(SB)
-TEXT ·libc_poll_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_futimes_trampoline_addr(SB), RODATA, $8
+DATA	·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB)
+
+TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_poll(SB)
-TEXT ·libc_madvise_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_poll_trampoline_addr(SB), RODATA, $8
+DATA	·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB)
+
+TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_madvise(SB)
-TEXT ·libc_mlock_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_madvise_trampoline_addr(SB), RODATA, $8
+DATA	·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB)
+
+TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mlock(SB)
-TEXT ·libc_mlockall_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mlock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB)
+
+TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mlockall(SB)
-TEXT ·libc_mprotect_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mlockall_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB)
+
+TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mprotect(SB)
-TEXT ·libc_msync_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mprotect_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB)
+
+TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_msync(SB)
-TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_msync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB)
+
+TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_munlock(SB)
-TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_munlock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB)
+
+TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_munlockall(SB)
-TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_munlockall_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB)
+
+TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_pipe(SB)
-TEXT ·libc_getxattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_pipe_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pipe_trampoline_addr(SB)/8, $libc_pipe_trampoline<>(SB)
+
+TEXT libc_getxattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getxattr(SB)
-TEXT ·libc_fgetxattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getxattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getxattr_trampoline_addr(SB)/8, $libc_getxattr_trampoline<>(SB)
+
+TEXT libc_fgetxattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fgetxattr(SB)
-TEXT ·libc_setxattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fgetxattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fgetxattr_trampoline_addr(SB)/8, $libc_fgetxattr_trampoline<>(SB)
+
+TEXT libc_setxattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setxattr(SB)
-TEXT ·libc_fsetxattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setxattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setxattr_trampoline_addr(SB)/8, $libc_setxattr_trampoline<>(SB)
+
+TEXT libc_fsetxattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fsetxattr(SB)
-TEXT ·libc_removexattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fsetxattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fsetxattr_trampoline_addr(SB)/8, $libc_fsetxattr_trampoline<>(SB)
+
+TEXT libc_removexattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_removexattr(SB)
-TEXT ·libc_fremovexattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_removexattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_removexattr_trampoline_addr(SB)/8, $libc_removexattr_trampoline<>(SB)
+
+TEXT libc_fremovexattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fremovexattr(SB)
-TEXT ·libc_listxattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fremovexattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fremovexattr_trampoline_addr(SB)/8, $libc_fremovexattr_trampoline<>(SB)
+
+TEXT libc_listxattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_listxattr(SB)
-TEXT ·libc_flistxattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_listxattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_listxattr_trampoline_addr(SB)/8, $libc_listxattr_trampoline<>(SB)
+
+TEXT libc_flistxattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_flistxattr(SB)
-TEXT ·libc_setattrlist_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_flistxattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_flistxattr_trampoline_addr(SB)/8, $libc_flistxattr_trampoline<>(SB)
+
+TEXT libc_setattrlist_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setattrlist(SB)
-TEXT ·libc_fcntl_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setattrlist_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setattrlist_trampoline_addr(SB)/8, $libc_setattrlist_trampoline<>(SB)
+
+TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fcntl(SB)
-TEXT ·libc_kill_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fcntl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
+
+TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_kill(SB)
-TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_kill_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB)
+
+TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_ioctl(SB)
-TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_ioctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB)
+
+TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_sysctl(SB)
-TEXT ·libc_sendfile_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_sysctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+
+TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_sendfile(SB)
-TEXT ·libc_access_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_sendfile_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendfile_trampoline_addr(SB)/8, $libc_sendfile_trampoline<>(SB)
+
+TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_access(SB)
-TEXT ·libc_adjtime_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_access_trampoline_addr(SB), RODATA, $8
+DATA	·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB)
+
+TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_adjtime(SB)
-TEXT ·libc_chdir_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_adjtime_trampoline_addr(SB), RODATA, $8
+DATA	·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB)
+
+TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_chdir(SB)
-TEXT ·libc_chflags_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_chdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB)
+
+TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_chflags(SB)
-TEXT ·libc_chmod_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_chflags_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB)
+
+TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_chmod(SB)
-TEXT ·libc_chown_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_chmod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB)
+
+TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_chown(SB)
-TEXT ·libc_chroot_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_chown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB)
+
+TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_chroot(SB)
-TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_chroot_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB)
+
+TEXT libc_clock_gettime_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_clock_gettime(SB)
-TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_clock_gettime_trampoline_addr(SB), RODATA, $8
+DATA	·libc_clock_gettime_trampoline_addr(SB)/8, $libc_clock_gettime_trampoline<>(SB)
+
+TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_close(SB)
-TEXT ·libc_clonefile_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_close_trampoline_addr(SB), RODATA, $8
+DATA	·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB)
+
+TEXT libc_clonefile_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_clonefile(SB)
-TEXT ·libc_clonefileat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_clonefile_trampoline_addr(SB), RODATA, $8
+DATA	·libc_clonefile_trampoline_addr(SB)/8, $libc_clonefile_trampoline<>(SB)
+
+TEXT libc_clonefileat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_clonefileat(SB)
-TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_clonefileat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_clonefileat_trampoline_addr(SB)/8, $libc_clonefileat_trampoline<>(SB)
+
+TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_dup(SB)
-TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_dup_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB)
+
+TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_dup2(SB)
-TEXT ·libc_exchangedata_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_dup2_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB)
+
+TEXT libc_exchangedata_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_exchangedata(SB)
-TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_exchangedata_trampoline_addr(SB), RODATA, $8
+DATA	·libc_exchangedata_trampoline_addr(SB)/8, $libc_exchangedata_trampoline<>(SB)
+
+TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_exit(SB)
-TEXT ·libc_faccessat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_exit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB)
+
+TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_faccessat(SB)
-TEXT ·libc_fchdir_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_faccessat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB)
+
+TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fchdir(SB)
-TEXT ·libc_fchflags_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fchdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB)
+
+TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fchflags(SB)
-TEXT ·libc_fchmod_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fchflags_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB)
+
+TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fchmod(SB)
-TEXT ·libc_fchmodat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fchmod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB)
+
+TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fchmodat(SB)
-TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fchmodat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB)
+
+TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fchown(SB)
-TEXT ·libc_fchownat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fchown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB)
+
+TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fchownat(SB)
-TEXT ·libc_fclonefileat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fchownat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB)
+
+TEXT libc_fclonefileat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fclonefileat(SB)
-TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fclonefileat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fclonefileat_trampoline_addr(SB)/8, $libc_fclonefileat_trampoline<>(SB)
+
+TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_flock(SB)
-TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_flock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB)
+
+TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fpathconf(SB)
-TEXT ·libc_fsync_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fpathconf_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB)
+
+TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fsync(SB)
-TEXT ·libc_ftruncate_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fsync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB)
+
+TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_ftruncate(SB)
-TEXT ·libc_getcwd_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_ftruncate_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB)
+
+TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getcwd(SB)
-TEXT ·libc_getdtablesize_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getcwd_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB)
+
+TEXT libc_getdtablesize_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getdtablesize(SB)
-TEXT ·libc_getegid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getdtablesize_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getdtablesize_trampoline_addr(SB)/8, $libc_getdtablesize_trampoline<>(SB)
+
+TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getegid(SB)
-TEXT ·libc_geteuid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getegid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB)
+
+TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_geteuid(SB)
-TEXT ·libc_getgid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_geteuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB)
+
+TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getgid(SB)
-TEXT ·libc_getpgid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB)
+
+TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getpgid(SB)
-TEXT ·libc_getpgrp_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getpgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB)
+
+TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getpgrp(SB)
-TEXT ·libc_getpid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getpgrp_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB)
+
+TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getpid(SB)
-TEXT ·libc_getppid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getpid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB)
+
+TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getppid(SB)
-TEXT ·libc_getpriority_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getppid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB)
+
+TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getpriority(SB)
-TEXT ·libc_getrlimit_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getpriority_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB)
+
+TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getrlimit(SB)
-TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getrlimit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB)
+
+TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getrusage(SB)
-TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getrusage_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB)
+
+TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getsid(SB)
-TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getsid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB)
+
+TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_gettimeofday(SB)
-TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_gettimeofday_trampoline_addr(SB), RODATA, $8
+DATA	·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB)
+
+TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getuid(SB)
-TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB)
+
+TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_issetugid(SB)
-TEXT ·libc_kqueue_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_issetugid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB)
+
+TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_kqueue(SB)
-TEXT ·libc_lchown_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_kqueue_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB)
+
+TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_lchown(SB)
-TEXT ·libc_link_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_lchown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB)
+
+TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_link(SB)
-TEXT ·libc_linkat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_link_trampoline_addr(SB), RODATA, $8
+DATA	·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB)
+
+TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_linkat(SB)
-TEXT ·libc_listen_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_linkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB)
+
+TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_listen(SB)
-TEXT ·libc_mkdir_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_listen_trampoline_addr(SB), RODATA, $8
+DATA	·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB)
+
+TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mkdir(SB)
-TEXT ·libc_mkdirat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mkdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB)
+
+TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mkdirat(SB)
-TEXT ·libc_mkfifo_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mkdirat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB)
+
+TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mkfifo(SB)
-TEXT ·libc_mknod_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mkfifo_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB)
+
+TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mknod(SB)
-TEXT ·libc_open_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mknod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB)
+
+TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_open(SB)
-TEXT ·libc_openat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_open_trampoline_addr(SB), RODATA, $8
+DATA	·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB)
+
+TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_openat(SB)
-TEXT ·libc_pathconf_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_openat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB)
+
+TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_pathconf(SB)
-TEXT ·libc_pread_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_pathconf_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB)
+
+TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_pread(SB)
-TEXT ·libc_pwrite_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_pread_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB)
+
+TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_pwrite(SB)
-TEXT ·libc_read_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_pwrite_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB)
+
+TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_read(SB)
-TEXT ·libc_readlink_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_read_trampoline_addr(SB), RODATA, $8
+DATA	·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB)
+
+TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_readlink(SB)
-TEXT ·libc_readlinkat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_readlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB)
+
+TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_readlinkat(SB)
-TEXT ·libc_rename_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_readlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB)
+
+TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_rename(SB)
-TEXT ·libc_renameat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_rename_trampoline_addr(SB), RODATA, $8
+DATA	·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB)
+
+TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_renameat(SB)
-TEXT ·libc_revoke_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_renameat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB)
+
+TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_revoke(SB)
-TEXT ·libc_rmdir_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_revoke_trampoline_addr(SB), RODATA, $8
+DATA	·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB)
+
+TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_rmdir(SB)
-TEXT ·libc_lseek_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_rmdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB)
+
+TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_lseek(SB)
-TEXT ·libc_select_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_lseek_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB)
+
+TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_select(SB)
-TEXT ·libc_setegid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_select_trampoline_addr(SB), RODATA, $8
+DATA	·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB)
+
+TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setegid(SB)
-TEXT ·libc_seteuid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setegid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB)
+
+TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_seteuid(SB)
-TEXT ·libc_setgid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_seteuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB)
+
+TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setgid(SB)
-TEXT ·libc_setlogin_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB)
+
+TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setlogin(SB)
-TEXT ·libc_setpgid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setlogin_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB)
+
+TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setpgid(SB)
-TEXT ·libc_setpriority_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setpgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB)
+
+TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setpriority(SB)
-TEXT ·libc_setprivexec_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setpriority_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB)
+
+TEXT libc_setprivexec_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setprivexec(SB)
-TEXT ·libc_setregid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setprivexec_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setprivexec_trampoline_addr(SB)/8, $libc_setprivexec_trampoline<>(SB)
+
+TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setregid(SB)
-TEXT ·libc_setreuid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setregid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB)
+
+TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setreuid(SB)
-TEXT ·libc_setrlimit_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setreuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB)
+
+TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setrlimit(SB)
-TEXT ·libc_setsid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setrlimit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB)
+
+TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setsid(SB)
-TEXT ·libc_settimeofday_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setsid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB)
+
+TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_settimeofday(SB)
-TEXT ·libc_setuid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_settimeofday_trampoline_addr(SB), RODATA, $8
+DATA	·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB)
+
+TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setuid(SB)
-TEXT ·libc_symlink_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB)
+
+TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_symlink(SB)
-TEXT ·libc_symlinkat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_symlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB)
+
+TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_symlinkat(SB)
-TEXT ·libc_sync_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_symlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB)
+
+TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_sync(SB)
-TEXT ·libc_truncate_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_sync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB)
+
+TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_truncate(SB)
-TEXT ·libc_umask_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_truncate_trampoline_addr(SB), RODATA, $8
+DATA	·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB)
+
+TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_umask(SB)
-TEXT ·libc_undelete_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_umask_trampoline_addr(SB), RODATA, $8
+DATA	·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB)
+
+TEXT libc_undelete_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_undelete(SB)
-TEXT ·libc_unlink_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_undelete_trampoline_addr(SB), RODATA, $8
+DATA	·libc_undelete_trampoline_addr(SB)/8, $libc_undelete_trampoline<>(SB)
+
+TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_unlink(SB)
-TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_unlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB)
+
+TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_unlinkat(SB)
-TEXT ·libc_unmount_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_unlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB)
+
+TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_unmount(SB)
-TEXT ·libc_write_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_unmount_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB)
+
+TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_write(SB)
-TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_write_trampoline_addr(SB), RODATA, $8
+DATA	·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB)
+
+TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mmap(SB)
-TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mmap_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB)
+
+TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_munmap(SB)
-TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_munmap_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB)
+
+TEXT libc_fstat64_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fstat64(SB)
-TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fstat64_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstat64_trampoline_addr(SB)/8, $libc_fstat64_trampoline<>(SB)
+
+TEXT libc_fstatat64_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fstatat64(SB)
-TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fstatat64_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstatat64_trampoline_addr(SB)/8, $libc_fstatat64_trampoline<>(SB)
+
+TEXT libc_fstatfs64_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fstatfs64(SB)
-TEXT ·libc_getfsstat64_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fstatfs64_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstatfs64_trampoline_addr(SB)/8, $libc_fstatfs64_trampoline<>(SB)
+
+TEXT libc_getfsstat64_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getfsstat64(SB)
-TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getfsstat64_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getfsstat64_trampoline_addr(SB)/8, $libc_getfsstat64_trampoline<>(SB)
+
+TEXT libc_lstat64_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_lstat64(SB)
-TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_lstat64_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lstat64_trampoline_addr(SB)/8, $libc_lstat64_trampoline<>(SB)
+
+TEXT libc_ptrace_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_ptrace(SB)
-TEXT ·libc_stat64_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_ptrace_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ptrace_trampoline_addr(SB)/8, $libc_ptrace_trampoline<>(SB)
+
+TEXT libc_stat64_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_stat64(SB)
-TEXT ·libc_statfs64_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_stat64_trampoline_addr(SB), RODATA, $8
+DATA	·libc_stat64_trampoline_addr(SB)/8, $libc_stat64_trampoline<>(SB)
+
+TEXT libc_statfs64_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_statfs64(SB)
+
+GLOBL	·libc_statfs64_trampoline_addr(SB), RODATA, $8
+DATA	·libc_statfs64_trampoline_addr(SB)/8, $libc_statfs64_trampoline<>(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.go
deleted file mode 100644
index de4738f..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// go run mksyscall.go -l32 -tags darwin,arm,go1.13 syscall_darwin.1_13.go
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build darwin,arm,go1.13
-
-package unix
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-var _ syscall.Errno
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func closedir(dir uintptr) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_closedir_trampoline), uintptr(dir), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_closedir_trampoline()
-
-//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
-	r0, _, _ := syscall_syscall(funcPC(libc_readdir_r_trampoline), uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
-	res = Errno(r0)
-	return
-}
-
-func libc_readdir_r_trampoline()
-
-//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.s
deleted file mode 100644
index 488e557..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.s
+++ /dev/null
@@ -1,12 +0,0 @@
-// go run mkasm_darwin.go arm
-// Code generated by the command above; DO NOT EDIT.
-
-// +build go1.13
-
-#include "textflag.h"
-TEXT ·libc_fdopendir_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fdopendir(SB)
-TEXT ·libc_closedir_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_closedir(SB)
-TEXT ·libc_readdir_r_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_readdir_r(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go
deleted file mode 100644
index 8e79ad3..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go
+++ /dev/null
@@ -1,2418 +0,0 @@
-// go run mksyscall.go -l32 -tags darwin,arm,go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_arm.go
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build darwin,arm,go1.12
-
-package unix
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-var _ syscall.Errno
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getgroups_trampoline()
-
-//go:cgo_import_dynamic libc_getgroups getgroups "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setgroups_trampoline()
-
-//go:cgo_import_dynamic libc_setgroups setgroups "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_wait4_trampoline()
-
-//go:cgo_import_dynamic libc_wait4 wait4 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_accept_trampoline()
-
-//go:cgo_import_dynamic libc_accept accept "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_bind_trampoline()
-
-//go:cgo_import_dynamic libc_bind bind "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_connect_trampoline()
-
-//go:cgo_import_dynamic libc_connect connect "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_socket_trampoline()
-
-//go:cgo_import_dynamic libc_socket socket "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getsockopt_trampoline()
-
-//go:cgo_import_dynamic libc_getsockopt getsockopt "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setsockopt_trampoline()
-
-//go:cgo_import_dynamic libc_setsockopt setsockopt "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getpeername_trampoline()
-
-//go:cgo_import_dynamic libc_getpeername getpeername "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getsockname_trampoline()
-
-//go:cgo_import_dynamic libc_getsockname getsockname "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_shutdown_trampoline()
-
-//go:cgo_import_dynamic libc_shutdown shutdown "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := syscall_rawSyscall6(funcPC(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_socketpair_trampoline()
-
-//go:cgo_import_dynamic libc_socketpair socketpair "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_recvfrom_trampoline()
-
-//go:cgo_import_dynamic libc_recvfrom recvfrom "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_sendto_trampoline()
-
-//go:cgo_import_dynamic libc_sendto sendto "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_recvmsg_trampoline()
-
-//go:cgo_import_dynamic libc_recvmsg recvmsg "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_sendmsg_trampoline()
-
-//go:cgo_import_dynamic libc_sendmsg sendmsg "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_kevent_trampoline()
-
-//go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_utimes_trampoline()
-
-//go:cgo_import_dynamic libc_utimes utimes "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_futimes_trampoline()
-
-//go:cgo_import_dynamic libc_futimes futimes "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_poll_trampoline), uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_poll_trampoline()
-
-//go:cgo_import_dynamic libc_poll poll "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Madvise(b []byte, behav int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_madvise_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(behav))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_madvise_trampoline()
-
-//go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mlock_trampoline()
-
-//go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_mlockall_trampoline), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mlockall_trampoline()
-
-//go:cgo_import_dynamic libc_mlockall mlockall "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mprotect_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mprotect_trampoline()
-
-//go:cgo_import_dynamic libc_mprotect mprotect "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Msync(b []byte, flags int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_msync_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(flags))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_msync_trampoline()
-
-//go:cgo_import_dynamic libc_msync msync "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_munlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_munlock_trampoline()
-
-//go:cgo_import_dynamic libc_munlock munlock "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_munlockall_trampoline), 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_munlockall_trampoline()
-
-//go:cgo_import_dynamic libc_munlockall munlockall "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := syscall_rawSyscall(funcPC(libc_pipe_trampoline), 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_pipe_trampoline()
-
-//go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_getxattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
-	sz = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getxattr_trampoline()
-
-//go:cgo_import_dynamic libc_getxattr getxattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_fgetxattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
-	sz = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fgetxattr_trampoline()
-
-//go:cgo_import_dynamic libc_fgetxattr fgetxattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_setxattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setxattr_trampoline()
-
-//go:cgo_import_dynamic libc_setxattr setxattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fsetxattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fsetxattr_trampoline()
-
-//go:cgo_import_dynamic libc_fsetxattr fsetxattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func removexattr(path string, attr string, options int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_removexattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_removexattr_trampoline()
-
-//go:cgo_import_dynamic libc_removexattr removexattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fremovexattr(fd int, attr string, options int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_fremovexattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fremovexattr_trampoline()
-
-//go:cgo_import_dynamic libc_fremovexattr fremovexattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func listxattr(path string, dest *byte, size int, options int) (sz int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_listxattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0)
-	sz = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_listxattr_trampoline()
-
-//go:cgo_import_dynamic libc_listxattr listxattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_flistxattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0)
-	sz = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_flistxattr_trampoline()
-
-//go:cgo_import_dynamic libc_flistxattr flistxattr "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_setattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setattrlist_trampoline()
-
-//go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fcntl_trampoline()
-
-//go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kill(pid int, signum int, posix int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_kill_trampoline), uintptr(pid), uintptr(signum), uintptr(posix))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_kill_trampoline()
-
-//go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ioctl(fd int, req uint, arg uintptr) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_ioctl_trampoline()
-
-//go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_sysctl_trampoline()
-
-//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
-	_, _, e1 := syscall_syscall9(funcPC(libc_sendfile_trampoline), uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(offset>>32), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_sendfile_trampoline()
-
-//go:cgo_import_dynamic libc_sendfile sendfile "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_access_trampoline()
-
-//go:cgo_import_dynamic libc_access access "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_adjtime_trampoline()
-
-//go:cgo_import_dynamic libc_adjtime adjtime "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_chdir_trampoline()
-
-//go:cgo_import_dynamic libc_chdir chdir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_chflags_trampoline()
-
-//go:cgo_import_dynamic libc_chflags chflags "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_chmod_trampoline()
-
-//go:cgo_import_dynamic libc_chmod chmod "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_chown_trampoline()
-
-//go:cgo_import_dynamic libc_chown chown "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_chroot_trampoline()
-
-//go:cgo_import_dynamic libc_chroot chroot "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ClockGettime(clockid int32, time *Timespec) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_clock_gettime_trampoline), uintptr(clockid), uintptr(unsafe.Pointer(time)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clock_gettime_trampoline()
-
-//go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_close_trampoline), uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_close_trampoline()
-
-//go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Clonefile(src string, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(src)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_clonefile_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clonefile_trampoline()
-
-//go:cgo_import_dynamic libc_clonefile clonefile "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(src)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_clonefileat_trampoline), uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clonefileat_trampoline()
-
-//go:cgo_import_dynamic libc_clonefileat clonefileat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_dup_trampoline()
-
-//go:cgo_import_dynamic libc_dup dup "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_dup2_trampoline()
-
-//go:cgo_import_dynamic libc_dup2 dup2 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exchangedata(path1 string, path2 string, options int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path1)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(path2)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_exchangedata_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_exchangedata_trampoline()
-
-//go:cgo_import_dynamic libc_exchangedata exchangedata "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	syscall_syscall(funcPC(libc_exit_trampoline), uintptr(code), 0, 0)
-	return
-}
-
-func libc_exit_trampoline()
-
-//go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_faccessat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_faccessat_trampoline()
-
-//go:cgo_import_dynamic libc_faccessat faccessat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchdir_trampoline), uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fchdir_trampoline()
-
-//go:cgo_import_dynamic libc_fchdir fchdir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fchflags_trampoline()
-
-//go:cgo_import_dynamic libc_fchflags fchflags "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fchmod_trampoline()
-
-//go:cgo_import_dynamic libc_fchmod fchmod "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fchmodat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fchmodat_trampoline()
-
-//go:cgo_import_dynamic libc_fchmodat fchmodat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fchown_trampoline()
-
-//go:cgo_import_dynamic libc_fchown fchown "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fchownat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fchownat_trampoline()
-
-//go:cgo_import_dynamic libc_fchownat fchownat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fclonefileat_trampoline), uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fclonefileat_trampoline()
-
-//go:cgo_import_dynamic libc_fclonefileat fclonefileat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_flock_trampoline()
-
-//go:cgo_import_dynamic libc_flock flock "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fpathconf_trampoline()
-
-//go:cgo_import_dynamic libc_fpathconf fpathconf "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fsync_trampoline), uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fsync_trampoline()
-
-//go:cgo_import_dynamic libc_fsync fsync "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), uintptr(length>>32))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_ftruncate_trampoline()
-
-//go:cgo_import_dynamic libc_ftruncate ftruncate "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getcwd(buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getcwd_trampoline()
-
-//go:cgo_import_dynamic libc_getcwd getcwd "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdtablesize() (size int) {
-	r0, _, _ := syscall_syscall(funcPC(libc_getdtablesize_trampoline), 0, 0, 0)
-	size = int(r0)
-	return
-}
-
-func libc_getdtablesize_trampoline()
-
-//go:cgo_import_dynamic libc_getdtablesize getdtablesize "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getegid_trampoline), 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-func libc_getegid_trampoline()
-
-//go:cgo_import_dynamic libc_getegid getegid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_geteuid_trampoline), 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-func libc_geteuid_trampoline()
-
-//go:cgo_import_dynamic libc_geteuid geteuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getgid_trampoline), 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-func libc_getgid_trampoline()
-
-//go:cgo_import_dynamic libc_getgid getgid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_getpgid_trampoline), uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getpgid_trampoline()
-
-//go:cgo_import_dynamic libc_getpgid getpgid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getpgrp_trampoline), 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-func libc_getpgrp_trampoline()
-
-//go:cgo_import_dynamic libc_getpgrp getpgrp "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getpid_trampoline), 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-func libc_getpid_trampoline()
-
-//go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getppid_trampoline), 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-func libc_getppid_trampoline()
-
-//go:cgo_import_dynamic libc_getppid getppid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getpriority_trampoline()
-
-//go:cgo_import_dynamic libc_getpriority getpriority "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getrlimit_trampoline()
-
-//go:cgo_import_dynamic libc_getrlimit getrlimit "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getrusage_trampoline()
-
-//go:cgo_import_dynamic libc_getrusage getrusage "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_getsid_trampoline), uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getsid_trampoline()
-
-//go:cgo_import_dynamic libc_getsid getsid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tp *Timeval) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_gettimeofday_trampoline()
-
-//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-func libc_getuid_trampoline()
-
-//go:cgo_import_dynamic libc_getuid getuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_issetugid_trampoline), 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-func libc_issetugid_trampoline()
-
-//go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_kqueue_trampoline), 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_kqueue_trampoline()
-
-//go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_lchown_trampoline()
-
-//go:cgo_import_dynamic libc_lchown lchown "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_link_trampoline()
-
-//go:cgo_import_dynamic libc_link link "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_linkat_trampoline), uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_linkat_trampoline()
-
-//go:cgo_import_dynamic libc_linkat linkat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_listen_trampoline()
-
-//go:cgo_import_dynamic libc_listen listen "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mkdir_trampoline()
-
-//go:cgo_import_dynamic libc_mkdir mkdir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdirat(dirfd int, path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mkdirat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mkdirat_trampoline()
-
-//go:cgo_import_dynamic libc_mkdirat mkdirat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mkfifo_trampoline()
-
-//go:cgo_import_dynamic libc_mkfifo mkfifo "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mknod_trampoline()
-
-//go:cgo_import_dynamic libc_mknod mknod "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_open_trampoline()
-
-//go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_openat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_openat_trampoline()
-
-//go:cgo_import_dynamic libc_openat openat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_pathconf_trampoline()
-
-//go:cgo_import_dynamic libc_pathconf pathconf "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_pread_trampoline()
-
-//go:cgo_import_dynamic libc_pread pread "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_pwrite_trampoline()
-
-//go:cgo_import_dynamic libc_pwrite pwrite "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_read_trampoline()
-
-//go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_readlink_trampoline()
-
-//go:cgo_import_dynamic libc_readlink readlink "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_readlinkat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_readlinkat_trampoline()
-
-//go:cgo_import_dynamic libc_readlinkat readlinkat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_rename_trampoline()
-
-//go:cgo_import_dynamic libc_rename rename "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Renameat(fromfd int, from string, tofd int, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_renameat_trampoline), uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_renameat_trampoline()
-
-//go:cgo_import_dynamic libc_renameat renameat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_revoke_trampoline()
-
-//go:cgo_import_dynamic libc_revoke revoke "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_rmdir_trampoline()
-
-//go:cgo_import_dynamic libc_rmdir rmdir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := syscall_syscall6(funcPC(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(whence), 0, 0)
-	newoffset = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_lseek_trampoline()
-
-//go:cgo_import_dynamic libc_lseek lseek "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_select_trampoline), 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
-}
-
-func libc_select_trampoline()
-
-//go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_setegid_trampoline), uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setegid_trampoline()
-
-//go:cgo_import_dynamic libc_setegid setegid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_seteuid_trampoline), uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_seteuid_trampoline()
-
-//go:cgo_import_dynamic libc_seteuid seteuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setgid_trampoline), uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setgid_trampoline()
-
-//go:cgo_import_dynamic libc_setgid setgid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setlogin(name string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setlogin_trampoline()
-
-//go:cgo_import_dynamic libc_setlogin setlogin "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setpgid_trampoline()
-
-//go:cgo_import_dynamic libc_setpgid setpgid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setpriority_trampoline()
-
-//go:cgo_import_dynamic libc_setpriority setpriority "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setprivexec(flag int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_setprivexec_trampoline), uintptr(flag), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setprivexec_trampoline()
-
-//go:cgo_import_dynamic libc_setprivexec setprivexec "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setregid_trampoline()
-
-//go:cgo_import_dynamic libc_setregid setregid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setreuid_trampoline()
-
-//go:cgo_import_dynamic libc_setreuid setreuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setrlimit_trampoline()
-
-//go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_setsid_trampoline), 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setsid_trampoline()
-
-//go:cgo_import_dynamic libc_setsid setsid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_settimeofday_trampoline()
-
-//go:cgo_import_dynamic libc_settimeofday settimeofday "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setuid_trampoline), uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_setuid_trampoline()
-
-//go:cgo_import_dynamic libc_setuid setuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_symlink_trampoline()
-
-//go:cgo_import_dynamic libc_symlink symlink "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_symlinkat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_symlinkat_trampoline()
-
-//go:cgo_import_dynamic libc_symlinkat symlinkat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_sync_trampoline), 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_sync_trampoline()
-
-//go:cgo_import_dynamic libc_sync sync "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), uintptr(length>>32))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_truncate_trampoline()
-
-//go:cgo_import_dynamic libc_truncate truncate "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := syscall_syscall(funcPC(libc_umask_trampoline), uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-func libc_umask_trampoline()
-
-//go:cgo_import_dynamic libc_umask umask "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Undelete(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_undelete_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_undelete_trampoline()
-
-//go:cgo_import_dynamic libc_undelete undelete "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_unlink_trampoline()
-
-//go:cgo_import_dynamic libc_unlink unlink "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlinkat(dirfd int, path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_unlinkat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_unlinkat_trampoline()
-
-//go:cgo_import_dynamic libc_unlinkat unlinkat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_unmount_trampoline()
-
-//go:cgo_import_dynamic libc_unmount unmount "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_write_trampoline()
-
-//go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := syscall_syscall9(funcPC(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos), uintptr(pos>>32), 0, 0)
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_mmap_trampoline()
-
-//go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_munmap_trampoline()
-
-//go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fstat_trampoline()
-
-//go:cgo_import_dynamic libc_fstat fstat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fstatat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fstatat_trampoline()
-
-//go:cgo_import_dynamic libc_fstatat fstatat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fstatfs_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fstatfs_trampoline()
-
-//go:cgo_import_dynamic libc_fstatfs fstatfs "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_getfsstat_trampoline), uintptr(buf), uintptr(size), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_getfsstat_trampoline()
-
-//go:cgo_import_dynamic libc_getfsstat getfsstat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_lstat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_lstat_trampoline()
-
-//go:cgo_import_dynamic libc_lstat lstat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_stat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_stat_trampoline()
-
-//go:cgo_import_dynamic libc_stat stat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_statfs_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_statfs_trampoline()
-
-//go:cgo_import_dynamic libc_statfs statfs "/usr/lib/libSystem.B.dylib"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s
deleted file mode 100644
index 5eec5f1..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s
+++ /dev/null
@@ -1,288 +0,0 @@
-// go run mkasm_darwin.go arm
-// Code generated by the command above; DO NOT EDIT.
-
-// +build go1.12
-
-#include "textflag.h"
-TEXT ·libc_getgroups_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getgroups(SB)
-TEXT ·libc_setgroups_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setgroups(SB)
-TEXT ·libc_wait4_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_wait4(SB)
-TEXT ·libc_accept_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_accept(SB)
-TEXT ·libc_bind_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_bind(SB)
-TEXT ·libc_connect_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_connect(SB)
-TEXT ·libc_socket_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_socket(SB)
-TEXT ·libc_getsockopt_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getsockopt(SB)
-TEXT ·libc_setsockopt_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setsockopt(SB)
-TEXT ·libc_getpeername_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getpeername(SB)
-TEXT ·libc_getsockname_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getsockname(SB)
-TEXT ·libc_shutdown_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_shutdown(SB)
-TEXT ·libc_socketpair_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_socketpair(SB)
-TEXT ·libc_recvfrom_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_recvfrom(SB)
-TEXT ·libc_sendto_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_sendto(SB)
-TEXT ·libc_recvmsg_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_recvmsg(SB)
-TEXT ·libc_sendmsg_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_sendmsg(SB)
-TEXT ·libc_kevent_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_kevent(SB)
-TEXT ·libc_utimes_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_utimes(SB)
-TEXT ·libc_futimes_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_futimes(SB)
-TEXT ·libc_poll_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_poll(SB)
-TEXT ·libc_madvise_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_madvise(SB)
-TEXT ·libc_mlock_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mlock(SB)
-TEXT ·libc_mlockall_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mlockall(SB)
-TEXT ·libc_mprotect_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mprotect(SB)
-TEXT ·libc_msync_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_msync(SB)
-TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_munlock(SB)
-TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_munlockall(SB)
-TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_pipe(SB)
-TEXT ·libc_getxattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getxattr(SB)
-TEXT ·libc_fgetxattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fgetxattr(SB)
-TEXT ·libc_setxattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setxattr(SB)
-TEXT ·libc_fsetxattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fsetxattr(SB)
-TEXT ·libc_removexattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_removexattr(SB)
-TEXT ·libc_fremovexattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fremovexattr(SB)
-TEXT ·libc_listxattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_listxattr(SB)
-TEXT ·libc_flistxattr_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_flistxattr(SB)
-TEXT ·libc_setattrlist_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setattrlist(SB)
-TEXT ·libc_fcntl_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fcntl(SB)
-TEXT ·libc_kill_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_kill(SB)
-TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_ioctl(SB)
-TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_sysctl(SB)
-TEXT ·libc_sendfile_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_sendfile(SB)
-TEXT ·libc_access_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_access(SB)
-TEXT ·libc_adjtime_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_adjtime(SB)
-TEXT ·libc_chdir_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_chdir(SB)
-TEXT ·libc_chflags_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_chflags(SB)
-TEXT ·libc_chmod_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_chmod(SB)
-TEXT ·libc_chown_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_chown(SB)
-TEXT ·libc_chroot_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_chroot(SB)
-TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clock_gettime(SB)
-TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_close(SB)
-TEXT ·libc_clonefile_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clonefile(SB)
-TEXT ·libc_clonefileat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clonefileat(SB)
-TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_dup(SB)
-TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_dup2(SB)
-TEXT ·libc_exchangedata_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_exchangedata(SB)
-TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_exit(SB)
-TEXT ·libc_faccessat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_faccessat(SB)
-TEXT ·libc_fchdir_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fchdir(SB)
-TEXT ·libc_fchflags_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fchflags(SB)
-TEXT ·libc_fchmod_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fchmod(SB)
-TEXT ·libc_fchmodat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fchmodat(SB)
-TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fchown(SB)
-TEXT ·libc_fchownat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fchownat(SB)
-TEXT ·libc_fclonefileat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fclonefileat(SB)
-TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_flock(SB)
-TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fpathconf(SB)
-TEXT ·libc_fsync_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fsync(SB)
-TEXT ·libc_ftruncate_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_ftruncate(SB)
-TEXT ·libc_getcwd_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getcwd(SB)
-TEXT ·libc_getdtablesize_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getdtablesize(SB)
-TEXT ·libc_getegid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getegid(SB)
-TEXT ·libc_geteuid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_geteuid(SB)
-TEXT ·libc_getgid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getgid(SB)
-TEXT ·libc_getpgid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getpgid(SB)
-TEXT ·libc_getpgrp_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getpgrp(SB)
-TEXT ·libc_getpid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getpid(SB)
-TEXT ·libc_getppid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getppid(SB)
-TEXT ·libc_getpriority_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getpriority(SB)
-TEXT ·libc_getrlimit_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getrlimit(SB)
-TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getrusage(SB)
-TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getsid(SB)
-TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_gettimeofday(SB)
-TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getuid(SB)
-TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_issetugid(SB)
-TEXT ·libc_kqueue_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_kqueue(SB)
-TEXT ·libc_lchown_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_lchown(SB)
-TEXT ·libc_link_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_link(SB)
-TEXT ·libc_linkat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_linkat(SB)
-TEXT ·libc_listen_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_listen(SB)
-TEXT ·libc_mkdir_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mkdir(SB)
-TEXT ·libc_mkdirat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mkdirat(SB)
-TEXT ·libc_mkfifo_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mkfifo(SB)
-TEXT ·libc_mknod_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mknod(SB)
-TEXT ·libc_open_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_open(SB)
-TEXT ·libc_openat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_openat(SB)
-TEXT ·libc_pathconf_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_pathconf(SB)
-TEXT ·libc_pread_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_pread(SB)
-TEXT ·libc_pwrite_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_pwrite(SB)
-TEXT ·libc_read_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_read(SB)
-TEXT ·libc_readlink_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_readlink(SB)
-TEXT ·libc_readlinkat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_readlinkat(SB)
-TEXT ·libc_rename_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_rename(SB)
-TEXT ·libc_renameat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_renameat(SB)
-TEXT ·libc_revoke_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_revoke(SB)
-TEXT ·libc_rmdir_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_rmdir(SB)
-TEXT ·libc_lseek_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_lseek(SB)
-TEXT ·libc_select_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_select(SB)
-TEXT ·libc_setegid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setegid(SB)
-TEXT ·libc_seteuid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_seteuid(SB)
-TEXT ·libc_setgid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setgid(SB)
-TEXT ·libc_setlogin_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setlogin(SB)
-TEXT ·libc_setpgid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setpgid(SB)
-TEXT ·libc_setpriority_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setpriority(SB)
-TEXT ·libc_setprivexec_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setprivexec(SB)
-TEXT ·libc_setregid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setregid(SB)
-TEXT ·libc_setreuid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setreuid(SB)
-TEXT ·libc_setrlimit_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setrlimit(SB)
-TEXT ·libc_setsid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setsid(SB)
-TEXT ·libc_settimeofday_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_settimeofday(SB)
-TEXT ·libc_setuid_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_setuid(SB)
-TEXT ·libc_symlink_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_symlink(SB)
-TEXT ·libc_symlinkat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_symlinkat(SB)
-TEXT ·libc_sync_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_sync(SB)
-TEXT ·libc_truncate_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_truncate(SB)
-TEXT ·libc_umask_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_umask(SB)
-TEXT ·libc_undelete_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_undelete(SB)
-TEXT ·libc_unlink_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_unlink(SB)
-TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_unlinkat(SB)
-TEXT ·libc_unmount_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_unmount(SB)
-TEXT ·libc_write_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_write(SB)
-TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_mmap(SB)
-TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_munmap(SB)
-TEXT ·libc_fstat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fstat(SB)
-TEXT ·libc_fstatat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fstatat(SB)
-TEXT ·libc_fstatfs_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fstatfs(SB)
-TEXT ·libc_getfsstat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getfsstat(SB)
-TEXT ·libc_lstat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_lstat(SB)
-TEXT ·libc_stat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_stat(SB)
-TEXT ·libc_statfs_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_statfs(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go
index 870eb37..cec595d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags darwin,arm64,go1.13 syscall_darwin.1_13.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build darwin && arm64 && go1.13
 // +build darwin,arm64,go1.13
 
 package unix
@@ -15,25 +16,25 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func closedir(dir uintptr) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_closedir_trampoline), uintptr(dir), 0, 0)
+	_, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_closedir_trampoline()
+var libc_closedir_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
-	r0, _, _ := syscall_syscall(funcPC(libc_readdir_r_trampoline), uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
+	r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
 	res = Errno(r0)
 	return
 }
 
-func libc_readdir_r_trampoline()
+var libc_readdir_r_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s
index b29dabb..3579897 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s
@@ -1,12 +1,25 @@
 // go run mkasm_darwin.go arm64
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build go1.13
 // +build go1.13
 
 #include "textflag.h"
-TEXT ·libc_fdopendir_trampoline(SB),NOSPLIT,$0-0
+
+TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fdopendir(SB)
-TEXT ·libc_closedir_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fdopendir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB)
+
+TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_closedir(SB)
-TEXT ·libc_readdir_r_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_closedir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB)
+
+TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_readdir_r(SB)
+
+GLOBL	·libc_readdir_r_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
index 23be592..f2ee2bd 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags darwin,arm64,go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_arm64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build darwin && arm64 && go1.12
 // +build darwin,arm64,go1.12
 
 package unix
@@ -15,7 +16,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -23,28 +24,28 @@
 	return
 }
 
-func libc_getgroups_trampoline()
+var libc_getgroups_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getgroups getgroups "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setgroups_trampoline()
+var libc_setgroups_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setgroups setgroups "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_wait4_trampoline_addr, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -52,14 +53,14 @@
 	return
 }
 
-func libc_wait4_trampoline()
+var libc_wait4_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_wait4 wait4 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall_syscall(libc_accept_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -67,42 +68,42 @@
 	return
 }
 
-func libc_accept_trampoline()
+var libc_accept_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_accept accept "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_bind_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_bind_trampoline()
+var libc_bind_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_bind bind "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_connect_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_connect_trampoline()
+var libc_connect_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_connect connect "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := syscall_rawSyscall(libc_socket_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -110,91 +111,91 @@
 	return
 }
 
-func libc_socket_trampoline()
+var libc_socket_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_socket socket "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall_syscall6(libc_getsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_getsockopt_trampoline()
+var libc_getsockopt_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getsockopt getsockopt "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall_syscall6(libc_setsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setsockopt_trampoline()
+var libc_setsockopt_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setsockopt setsockopt "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getpeername_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_getpeername_trampoline()
+var libc_getpeername_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getpeername getpeername "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getsockname_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_getsockname_trampoline()
+var libc_getsockname_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getsockname getsockname "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_shutdown_trampoline_addr, uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_shutdown_trampoline()
+var libc_shutdown_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_shutdown shutdown "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := syscall_rawSyscall6(funcPC(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := syscall_rawSyscall6(libc_socketpair_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_socketpair_trampoline()
+var libc_socketpair_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_socketpair socketpair "/usr/lib/libSystem.B.dylib"
 
@@ -207,7 +208,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall_syscall6(libc_recvfrom_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -215,7 +216,7 @@
 	return
 }
 
-func libc_recvfrom_trampoline()
+var libc_recvfrom_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_recvfrom recvfrom "/usr/lib/libSystem.B.dylib"
 
@@ -228,21 +229,21 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall_syscall6(libc_sendto_trampoline_addr, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_sendto_trampoline()
+var libc_sendto_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_sendto sendto "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_recvmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -250,14 +251,14 @@
 	return
 }
 
-func libc_recvmsg_trampoline()
+var libc_recvmsg_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_recvmsg recvmsg "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_sendmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -265,14 +266,14 @@
 	return
 }
 
-func libc_sendmsg_trampoline()
+var libc_sendmsg_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_sendmsg sendmsg "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall_syscall6(libc_kevent_trampoline_addr, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -280,7 +281,7 @@
 	return
 }
 
-func libc_kevent_trampoline()
+var libc_kevent_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib"
 
@@ -292,35 +293,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_utimes_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_utimes_trampoline()
+var libc_utimes_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_utimes utimes "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_futimes_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_futimes_trampoline()
+var libc_futimes_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_futimes futimes "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_poll_trampoline), uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
+	r0, _, e1 := syscall_syscall(libc_poll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -328,7 +329,7 @@
 	return
 }
 
-func libc_poll_trampoline()
+var libc_poll_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_poll poll "/usr/lib/libSystem.B.dylib"
 
@@ -341,14 +342,14 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_madvise_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	_, _, e1 := syscall_syscall(libc_madvise_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(behav))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_madvise_trampoline()
+var libc_madvise_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib"
 
@@ -361,28 +362,28 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_mlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mlock_trampoline()
+var libc_mlock_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlockall(flags int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_mlockall_trampoline), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall(libc_mlockall_trampoline_addr, uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mlockall_trampoline()
+var libc_mlockall_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mlockall mlockall "/usr/lib/libSystem.B.dylib"
 
@@ -395,14 +396,14 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mprotect_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	_, _, e1 := syscall_syscall(libc_mprotect_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(prot))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mprotect_trampoline()
+var libc_mprotect_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mprotect mprotect "/usr/lib/libSystem.B.dylib"
 
@@ -415,14 +416,14 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_msync_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_msync_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_msync_trampoline()
+var libc_msync_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_msync msync "/usr/lib/libSystem.B.dylib"
 
@@ -435,44 +436,42 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_munlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_munlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_munlock_trampoline()
+var libc_munlock_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_munlock munlock "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlockall() (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_munlockall_trampoline), 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_munlockall_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_munlockall_trampoline()
+var libc_munlockall_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_munlockall munlockall "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := syscall_rawSyscall(funcPC(libc_pipe_trampoline), 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
+func pipe(p *[2]int32) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_pipe_trampoline_addr, uintptr(unsafe.Pointer(p)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_pipe_trampoline()
+var libc_pipe_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib"
 
@@ -489,7 +488,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_getxattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
+	r0, _, e1 := syscall_syscall6(libc_getxattr_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
 	sz = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -497,7 +496,7 @@
 	return
 }
 
-func libc_getxattr_trampoline()
+var libc_getxattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getxattr getxattr "/usr/lib/libSystem.B.dylib"
 
@@ -509,7 +508,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_fgetxattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
+	r0, _, e1 := syscall_syscall6(libc_fgetxattr_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
 	sz = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -517,7 +516,7 @@
 	return
 }
 
-func libc_fgetxattr_trampoline()
+var libc_fgetxattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fgetxattr fgetxattr "/usr/lib/libSystem.B.dylib"
 
@@ -534,14 +533,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_setxattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options))
+	_, _, e1 := syscall_syscall6(libc_setxattr_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setxattr_trampoline()
+var libc_setxattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setxattr setxattr "/usr/lib/libSystem.B.dylib"
 
@@ -553,14 +552,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fsetxattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options))
+	_, _, e1 := syscall_syscall6(libc_fsetxattr_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fsetxattr_trampoline()
+var libc_fsetxattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fsetxattr fsetxattr "/usr/lib/libSystem.B.dylib"
 
@@ -577,14 +576,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_removexattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
+	_, _, e1 := syscall_syscall(libc_removexattr_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_removexattr_trampoline()
+var libc_removexattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_removexattr removexattr "/usr/lib/libSystem.B.dylib"
 
@@ -596,14 +595,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_fremovexattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options))
+	_, _, e1 := syscall_syscall(libc_fremovexattr_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fremovexattr_trampoline()
+var libc_fremovexattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fremovexattr fremovexattr "/usr/lib/libSystem.B.dylib"
 
@@ -615,7 +614,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_listxattr_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_listxattr_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0)
 	sz = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -623,14 +622,14 @@
 	return
 }
 
-func libc_listxattr_trampoline()
+var libc_listxattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_listxattr listxattr "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_flistxattr_trampoline), uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_flistxattr_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0)
 	sz = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -638,28 +637,28 @@
 	return
 }
 
-func libc_flistxattr_trampoline()
+var libc_flistxattr_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_flistxattr flistxattr "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_setattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
+	_, _, e1 := syscall_syscall6(libc_setattrlist_trampoline_addr, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setattrlist_trampoline()
+var libc_setattrlist_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+	r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -667,35 +666,35 @@
 	return
 }
 
-func libc_fcntl_trampoline()
+var libc_fcntl_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kill(pid int, signum int, posix int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_kill_trampoline), uintptr(pid), uintptr(signum), uintptr(posix))
+	_, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), uintptr(posix))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_kill_trampoline()
+var libc_kill_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctl(fd int, req uint, arg uintptr) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_ioctl_trampoline()
+var libc_ioctl_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib"
 
@@ -708,28 +707,28 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	_, _, e1 := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_sysctl_trampoline()
+var libc_sysctl_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_sendfile_trampoline), uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
+	_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_sendfile_trampoline()
+var libc_sendfile_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_sendfile sendfile "/usr/lib/libSystem.B.dylib"
 
@@ -741,28 +740,28 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_access_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_access_trampoline()
+var libc_access_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_access access "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall_syscall(libc_adjtime_trampoline_addr, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_adjtime_trampoline()
+var libc_adjtime_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_adjtime adjtime "/usr/lib/libSystem.B.dylib"
 
@@ -774,14 +773,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_chdir_trampoline()
+var libc_chdir_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_chdir chdir "/usr/lib/libSystem.B.dylib"
 
@@ -793,14 +792,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_chflags_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_chflags_trampoline()
+var libc_chflags_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_chflags chflags "/usr/lib/libSystem.B.dylib"
 
@@ -812,14 +811,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_chmod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_chmod_trampoline()
+var libc_chmod_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_chmod chmod "/usr/lib/libSystem.B.dylib"
 
@@ -831,14 +830,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_chown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_chown_trampoline()
+var libc_chown_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_chown chown "/usr/lib/libSystem.B.dylib"
 
@@ -850,42 +849,42 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chroot_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_chroot_trampoline()
+var libc_chroot_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_chroot chroot "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ClockGettime(clockid int32, time *Timespec) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_clock_gettime_trampoline), uintptr(clockid), uintptr(unsafe.Pointer(time)), 0)
+	_, _, e1 := syscall_syscall(libc_clock_gettime_trampoline_addr, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_clock_gettime_trampoline()
+var libc_clock_gettime_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_close_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_close_trampoline()
+var libc_close_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib"
 
@@ -902,14 +901,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_clonefile_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_clonefile_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_clonefile_trampoline()
+var libc_clonefile_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_clonefile clonefile "/usr/lib/libSystem.B.dylib"
 
@@ -926,21 +925,21 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_clonefileat_trampoline), uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_clonefileat_trampoline_addr, uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_clonefileat_trampoline()
+var libc_clonefileat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_clonefileat clonefileat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0)
+	r0, _, e1 := syscall_syscall(libc_dup_trampoline_addr, uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -948,21 +947,21 @@
 	return
 }
 
-func libc_dup_trampoline()
+var libc_dup_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_dup dup "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_dup2_trampoline()
+var libc_dup2_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_dup2 dup2 "/usr/lib/libSystem.B.dylib"
 
@@ -979,25 +978,25 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_exchangedata_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
+	_, _, e1 := syscall_syscall(libc_exchangedata_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_exchangedata_trampoline()
+var libc_exchangedata_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_exchangedata exchangedata "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Exit(code int) {
-	syscall_syscall(funcPC(libc_exit_trampoline), uintptr(code), 0, 0)
+	syscall_syscall(libc_exit_trampoline_addr, uintptr(code), 0, 0)
 	return
 }
 
-func libc_exit_trampoline()
+var libc_exit_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib"
 
@@ -1009,56 +1008,56 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_faccessat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_faccessat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_faccessat_trampoline()
+var libc_faccessat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_faccessat faccessat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchdir_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fchdir_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fchdir_trampoline()
+var libc_fchdir_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fchdir fchdir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_fchflags_trampoline_addr, uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fchflags_trampoline()
+var libc_fchflags_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fchflags fchflags "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_fchmod_trampoline_addr, uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fchmod_trampoline()
+var libc_fchmod_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fchmod fchmod "/usr/lib/libSystem.B.dylib"
 
@@ -1070,28 +1069,28 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fchmodat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fchmodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fchmodat_trampoline()
+var libc_fchmodat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fchmodat fchmodat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_fchown_trampoline_addr, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fchown_trampoline()
+var libc_fchown_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fchown fchown "/usr/lib/libSystem.B.dylib"
 
@@ -1103,14 +1102,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fchownat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_fchownat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fchownat_trampoline()
+var libc_fchownat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fchownat fchownat "/usr/lib/libSystem.B.dylib"
 
@@ -1122,35 +1121,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fclonefileat_trampoline), uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fclonefileat_trampoline_addr, uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fclonefileat_trampoline()
+var libc_fclonefileat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fclonefileat fclonefileat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_flock_trampoline()
+var libc_flock_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_flock flock "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_fpathconf_trampoline_addr, uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1158,35 +1157,35 @@
 	return
 }
 
-func libc_fpathconf_trampoline()
+var libc_fpathconf_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fpathconf fpathconf "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fsync_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fsync_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fsync_trampoline()
+var libc_fsync_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fsync fsync "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), 0)
+	_, _, e1 := syscall_syscall(libc_ftruncate_trampoline_addr, uintptr(fd), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_ftruncate_trampoline()
+var libc_ftruncate_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_ftruncate ftruncate "/usr/lib/libSystem.B.dylib"
 
@@ -1199,7 +1198,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall_syscall(libc_getcwd_trampoline_addr, uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1207,62 +1206,62 @@
 	return
 }
 
-func libc_getcwd_trampoline()
+var libc_getcwd_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getcwd getcwd "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getdtablesize() (size int) {
-	r0, _, _ := syscall_syscall(funcPC(libc_getdtablesize_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_syscall(libc_getdtablesize_trampoline_addr, 0, 0, 0)
 	size = int(r0)
 	return
 }
 
-func libc_getdtablesize_trampoline()
+var libc_getdtablesize_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getdtablesize getdtablesize "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getegid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getegid_trampoline_addr, 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
-func libc_getegid_trampoline()
+var libc_getegid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getegid getegid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_geteuid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_geteuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
-func libc_geteuid_trampoline()
+var libc_geteuid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_geteuid geteuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getgid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getgid_trampoline_addr, 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
-func libc_getgid_trampoline()
+var libc_getgid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getgid getgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_getpgid_trampoline), uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getpgid_trampoline_addr, uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1270,50 +1269,50 @@
 	return
 }
 
-func libc_getpgid_trampoline()
+var libc_getpgid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getpgid getpgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getpgrp_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpgrp_trampoline_addr, 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
-func libc_getpgrp_trampoline()
+var libc_getpgrp_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getpgrp getpgrp "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getpid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
-func libc_getpid_trampoline()
+var libc_getpid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getppid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getppid_trampoline_addr, 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
-func libc_getppid_trampoline()
+var libc_getppid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getppid getppid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall_syscall(libc_getpriority_trampoline_addr, uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1321,42 +1320,42 @@
 	return
 }
 
-func libc_getpriority_trampoline()
+var libc_getpriority_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getpriority getpriority "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_getrlimit_trampoline()
+var libc_getrlimit_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getrlimit getrlimit "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrusage_trampoline_addr, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_getrusage_trampoline()
+var libc_getrusage_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getrusage getrusage "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_getsid_trampoline), uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getsid_trampoline_addr, uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1364,52 +1363,52 @@
 	return
 }
 
-func libc_getsid_trampoline()
+var libc_getsid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getsid getsid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tp *Timeval) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_gettimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_gettimeofday_trampoline()
+var libc_gettimeofday_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
-func libc_getuid_trampoline()
+var libc_getuid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getuid getuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := syscall_rawSyscall(funcPC(libc_issetugid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_issetugid_trampoline_addr, 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
-func libc_issetugid_trampoline()
+var libc_issetugid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_kqueue_trampoline), 0, 0, 0)
+	r0, _, e1 := syscall_syscall(libc_kqueue_trampoline_addr, 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1417,7 +1416,7 @@
 	return
 }
 
-func libc_kqueue_trampoline()
+var libc_kqueue_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib"
 
@@ -1429,14 +1428,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_lchown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_lchown_trampoline()
+var libc_lchown_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_lchown lchown "/usr/lib/libSystem.B.dylib"
 
@@ -1453,14 +1452,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_link_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_link_trampoline()
+var libc_link_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_link link "/usr/lib/libSystem.B.dylib"
 
@@ -1477,28 +1476,28 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_linkat_trampoline), uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_linkat_trampoline_addr, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_linkat_trampoline()
+var libc_linkat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_linkat linkat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall_syscall(libc_listen_trampoline_addr, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_listen_trampoline()
+var libc_listen_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_listen listen "/usr/lib/libSystem.B.dylib"
 
@@ -1510,14 +1509,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mkdir_trampoline()
+var libc_mkdir_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mkdir mkdir "/usr/lib/libSystem.B.dylib"
 
@@ -1529,14 +1528,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mkdirat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	_, _, e1 := syscall_syscall(libc_mkdirat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mkdirat_trampoline()
+var libc_mkdirat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mkdirat mkdirat "/usr/lib/libSystem.B.dylib"
 
@@ -1548,14 +1547,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkfifo_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mkfifo_trampoline()
+var libc_mkfifo_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mkfifo mkfifo "/usr/lib/libSystem.B.dylib"
 
@@ -1567,14 +1566,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall_syscall(libc_mknod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_mknod_trampoline()
+var libc_mknod_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mknod mknod "/usr/lib/libSystem.B.dylib"
 
@@ -1586,7 +1585,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall_syscall(libc_open_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1594,7 +1593,7 @@
 	return
 }
 
-func libc_open_trampoline()
+var libc_open_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib"
 
@@ -1606,7 +1605,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_openat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_openat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1614,7 +1613,7 @@
 	return
 }
 
-func libc_openat_trampoline()
+var libc_openat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_openat openat "/usr/lib/libSystem.B.dylib"
 
@@ -1626,7 +1625,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_pathconf_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1634,7 +1633,7 @@
 	return
 }
 
-func libc_pathconf_trampoline()
+var libc_pathconf_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_pathconf pathconf "/usr/lib/libSystem.B.dylib"
 
@@ -1647,7 +1646,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_pread_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1655,7 +1654,7 @@
 	return
 }
 
-func libc_pread_trampoline()
+var libc_pread_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_pread pread "/usr/lib/libSystem.B.dylib"
 
@@ -1668,7 +1667,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_pwrite_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1676,7 +1675,7 @@
 	return
 }
 
-func libc_pwrite_trampoline()
+var libc_pwrite_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_pwrite pwrite "/usr/lib/libSystem.B.dylib"
 
@@ -1689,7 +1688,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1697,7 +1696,7 @@
 	return
 }
 
-func libc_read_trampoline()
+var libc_read_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib"
 
@@ -1715,7 +1714,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall_syscall(libc_readlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1723,7 +1722,7 @@
 	return
 }
 
-func libc_readlink_trampoline()
+var libc_readlink_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_readlink readlink "/usr/lib/libSystem.B.dylib"
 
@@ -1741,7 +1740,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall6(funcPC(libc_readlinkat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_readlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1749,7 +1748,7 @@
 	return
 }
 
-func libc_readlinkat_trampoline()
+var libc_readlinkat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_readlinkat readlinkat "/usr/lib/libSystem.B.dylib"
 
@@ -1766,14 +1765,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_rename_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_rename_trampoline()
+var libc_rename_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_rename rename "/usr/lib/libSystem.B.dylib"
 
@@ -1790,14 +1789,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_renameat_trampoline), uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_renameat_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_renameat_trampoline()
+var libc_renameat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_renameat renameat "/usr/lib/libSystem.B.dylib"
 
@@ -1809,14 +1808,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_revoke_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_revoke_trampoline()
+var libc_revoke_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_revoke revoke "/usr/lib/libSystem.B.dylib"
 
@@ -1828,21 +1827,21 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_rmdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_rmdir_trampoline()
+var libc_rmdir_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_rmdir rmdir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(whence))
+	r0, _, e1 := syscall_syscall(libc_lseek_trampoline_addr, uintptr(fd), uintptr(offset), uintptr(whence))
 	newoffset = int64(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1850,14 +1849,14 @@
 	return
 }
 
-func libc_lseek_trampoline()
+var libc_lseek_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_lseek lseek "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_select_trampoline), uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	r0, _, e1 := syscall_syscall6(libc_select_trampoline_addr, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1865,49 +1864,49 @@
 	return
 }
 
-func libc_select_trampoline()
+var libc_select_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_setegid_trampoline), uintptr(egid), 0, 0)
+	_, _, e1 := syscall_syscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setegid_trampoline()
+var libc_setegid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setegid setegid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_seteuid_trampoline), uintptr(euid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_seteuid_trampoline_addr, uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_seteuid_trampoline()
+var libc_seteuid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_seteuid seteuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setgid_trampoline), uintptr(gid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgid_trampoline_addr, uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setgid_trampoline()
+var libc_setgid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setgid setgid "/usr/lib/libSystem.B.dylib"
 
@@ -1919,105 +1918,105 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_setlogin_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setlogin_trampoline()
+var libc_setlogin_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setlogin setlogin "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setpgid_trampoline_addr, uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setpgid_trampoline()
+var libc_setpgid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setpgid setpgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall_syscall(libc_setpriority_trampoline_addr, uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setpriority_trampoline()
+var libc_setpriority_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setpriority setpriority "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setprivexec(flag int) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_setprivexec_trampoline), uintptr(flag), 0, 0)
+	_, _, e1 := syscall_syscall(libc_setprivexec_trampoline_addr, uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setprivexec_trampoline()
+var libc_setprivexec_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setprivexec setprivexec "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setregid_trampoline_addr, uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setregid_trampoline()
+var libc_setregid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setregid setregid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setreuid_trampoline_addr, uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setreuid_trampoline()
+var libc_setreuid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setreuid setreuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setrlimit_trampoline()
+var libc_setrlimit_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := syscall_rawSyscall(funcPC(libc_setsid_trampoline), 0, 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2025,35 +2024,35 @@
 	return
 }
 
-func libc_setsid_trampoline()
+var libc_setsid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setsid setsid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_settimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_settimeofday_trampoline()
+var libc_settimeofday_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_settimeofday settimeofday "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := syscall_rawSyscall(funcPC(libc_setuid_trampoline), uintptr(uid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setuid_trampoline_addr, uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_setuid_trampoline()
+var libc_setuid_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_setuid setuid "/usr/lib/libSystem.B.dylib"
 
@@ -2070,14 +2069,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_symlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_symlink_trampoline()
+var libc_symlink_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_symlink symlink "/usr/lib/libSystem.B.dylib"
 
@@ -2094,28 +2093,28 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_symlinkat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	_, _, e1 := syscall_syscall(libc_symlinkat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_symlinkat_trampoline()
+var libc_symlinkat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_symlinkat symlinkat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_sync_trampoline), 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_sync_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_sync_trampoline()
+var libc_sync_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_sync sync "/usr/lib/libSystem.B.dylib"
 
@@ -2127,26 +2126,26 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	_, _, e1 := syscall_syscall(libc_truncate_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_truncate_trampoline()
+var libc_truncate_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_truncate truncate "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := syscall_syscall(funcPC(libc_umask_trampoline), uintptr(newmask), 0, 0)
+	r0, _, _ := syscall_syscall(libc_umask_trampoline_addr, uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
-func libc_umask_trampoline()
+var libc_umask_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_umask umask "/usr/lib/libSystem.B.dylib"
 
@@ -2158,14 +2157,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_undelete_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_undelete_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_undelete_trampoline()
+var libc_undelete_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_undelete undelete "/usr/lib/libSystem.B.dylib"
 
@@ -2177,14 +2176,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_unlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_unlink_trampoline()
+var libc_unlink_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_unlink unlink "/usr/lib/libSystem.B.dylib"
 
@@ -2196,14 +2195,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_unlinkat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_unlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_unlinkat_trampoline()
+var libc_unlinkat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_unlinkat unlinkat "/usr/lib/libSystem.B.dylib"
 
@@ -2215,14 +2214,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_unmount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_unmount_trampoline()
+var libc_unmount_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_unmount unmount "/usr/lib/libSystem.B.dylib"
 
@@ -2235,7 +2234,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2243,14 +2242,14 @@
 	return
 }
 
-func libc_write_trampoline()
+var libc_write_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := syscall_syscall6(funcPC(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	r0, _, e1 := syscall_syscall6(libc_mmap_trampoline_addr, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2258,28 +2257,28 @@
 	return
 }
 
-func libc_mmap_trampoline()
+var libc_mmap_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall_syscall(libc_munmap_trampoline_addr, uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_munmap_trampoline()
+var libc_munmap_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2290,7 +2289,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2301,14 +2300,14 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fstat_trampoline()
+var libc_fstat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fstat fstat "/usr/lib/libSystem.B.dylib"
 
@@ -2320,35 +2319,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fstatat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fstatat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fstatat_trampoline()
+var libc_fstatat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fstatat fstatat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := syscall_syscall(funcPC(libc_fstatfs_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstatfs_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_fstatfs_trampoline()
+var libc_fstatfs_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_fstatfs fstatfs "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(funcPC(libc_getfsstat_trampoline), uintptr(buf), uintptr(size), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_getfsstat_trampoline_addr, uintptr(buf), uintptr(size), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2356,7 +2355,7 @@
 	return
 }
 
-func libc_getfsstat_trampoline()
+var libc_getfsstat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_getfsstat getfsstat "/usr/lib/libSystem.B.dylib"
 
@@ -2368,28 +2367,28 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_lstat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_lstat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_lstat_trampoline()
+var libc_lstat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_lstat lstat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
-	_, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+func ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) {
+	_, _, e1 := syscall_syscall6(libc_ptrace_trampoline_addr, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_ptrace_trampoline()
+var libc_ptrace_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
 
@@ -2401,14 +2400,14 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_stat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_stat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_stat_trampoline()
+var libc_stat_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_stat stat "/usr/lib/libSystem.B.dylib"
 
@@ -2420,13 +2419,13 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(funcPC(libc_statfs_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_statfs_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-func libc_statfs_trampoline()
+var libc_statfs_trampoline_addr uintptr
 
 //go:cgo_import_dynamic libc_statfs statfs "/usr/lib/libSystem.B.dylib"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
index 53c402b..33e1977 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
@@ -1,290 +1,859 @@
 // go run mkasm_darwin.go arm64
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build go1.12
 // +build go1.12
 
 #include "textflag.h"
-TEXT ·libc_getgroups_trampoline(SB),NOSPLIT,$0-0
+
+TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getgroups(SB)
-TEXT ·libc_setgroups_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getgroups_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB)
+
+TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setgroups(SB)
-TEXT ·libc_wait4_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setgroups_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB)
+
+TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_wait4(SB)
-TEXT ·libc_accept_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_wait4_trampoline_addr(SB), RODATA, $8
+DATA	·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB)
+
+TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_accept(SB)
-TEXT ·libc_bind_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_accept_trampoline_addr(SB), RODATA, $8
+DATA	·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB)
+
+TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_bind(SB)
-TEXT ·libc_connect_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_bind_trampoline_addr(SB), RODATA, $8
+DATA	·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB)
+
+TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_connect(SB)
-TEXT ·libc_socket_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_connect_trampoline_addr(SB), RODATA, $8
+DATA	·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB)
+
+TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_socket(SB)
-TEXT ·libc_getsockopt_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_socket_trampoline_addr(SB), RODATA, $8
+DATA	·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB)
+
+TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getsockopt(SB)
-TEXT ·libc_setsockopt_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getsockopt_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB)
+
+TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setsockopt(SB)
-TEXT ·libc_getpeername_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setsockopt_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB)
+
+TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getpeername(SB)
-TEXT ·libc_getsockname_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getpeername_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB)
+
+TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getsockname(SB)
-TEXT ·libc_shutdown_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getsockname_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB)
+
+TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_shutdown(SB)
-TEXT ·libc_socketpair_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_shutdown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB)
+
+TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_socketpair(SB)
-TEXT ·libc_recvfrom_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_socketpair_trampoline_addr(SB), RODATA, $8
+DATA	·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB)
+
+TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_recvfrom(SB)
-TEXT ·libc_sendto_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_recvfrom_trampoline_addr(SB), RODATA, $8
+DATA	·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB)
+
+TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_sendto(SB)
-TEXT ·libc_recvmsg_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_sendto_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB)
+
+TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_recvmsg(SB)
-TEXT ·libc_sendmsg_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_recvmsg_trampoline_addr(SB), RODATA, $8
+DATA	·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB)
+
+TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_sendmsg(SB)
-TEXT ·libc_kevent_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_sendmsg_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB)
+
+TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_kevent(SB)
-TEXT ·libc_utimes_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_kevent_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB)
+
+TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_utimes(SB)
-TEXT ·libc_futimes_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_utimes_trampoline_addr(SB), RODATA, $8
+DATA	·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB)
+
+TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_futimes(SB)
-TEXT ·libc_poll_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_futimes_trampoline_addr(SB), RODATA, $8
+DATA	·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB)
+
+TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_poll(SB)
-TEXT ·libc_madvise_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_poll_trampoline_addr(SB), RODATA, $8
+DATA	·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB)
+
+TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_madvise(SB)
-TEXT ·libc_mlock_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_madvise_trampoline_addr(SB), RODATA, $8
+DATA	·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB)
+
+TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mlock(SB)
-TEXT ·libc_mlockall_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mlock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB)
+
+TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mlockall(SB)
-TEXT ·libc_mprotect_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mlockall_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB)
+
+TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mprotect(SB)
-TEXT ·libc_msync_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mprotect_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB)
+
+TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_msync(SB)
-TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_msync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB)
+
+TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_munlock(SB)
-TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_munlock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB)
+
+TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_munlockall(SB)
-TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_munlockall_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB)
+
+TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_pipe(SB)
-TEXT ·libc_getxattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_pipe_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pipe_trampoline_addr(SB)/8, $libc_pipe_trampoline<>(SB)
+
+TEXT libc_getxattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getxattr(SB)
-TEXT ·libc_fgetxattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getxattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getxattr_trampoline_addr(SB)/8, $libc_getxattr_trampoline<>(SB)
+
+TEXT libc_fgetxattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fgetxattr(SB)
-TEXT ·libc_setxattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fgetxattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fgetxattr_trampoline_addr(SB)/8, $libc_fgetxattr_trampoline<>(SB)
+
+TEXT libc_setxattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setxattr(SB)
-TEXT ·libc_fsetxattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setxattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setxattr_trampoline_addr(SB)/8, $libc_setxattr_trampoline<>(SB)
+
+TEXT libc_fsetxattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fsetxattr(SB)
-TEXT ·libc_removexattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fsetxattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fsetxattr_trampoline_addr(SB)/8, $libc_fsetxattr_trampoline<>(SB)
+
+TEXT libc_removexattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_removexattr(SB)
-TEXT ·libc_fremovexattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_removexattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_removexattr_trampoline_addr(SB)/8, $libc_removexattr_trampoline<>(SB)
+
+TEXT libc_fremovexattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fremovexattr(SB)
-TEXT ·libc_listxattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fremovexattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fremovexattr_trampoline_addr(SB)/8, $libc_fremovexattr_trampoline<>(SB)
+
+TEXT libc_listxattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_listxattr(SB)
-TEXT ·libc_flistxattr_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_listxattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_listxattr_trampoline_addr(SB)/8, $libc_listxattr_trampoline<>(SB)
+
+TEXT libc_flistxattr_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_flistxattr(SB)
-TEXT ·libc_setattrlist_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_flistxattr_trampoline_addr(SB), RODATA, $8
+DATA	·libc_flistxattr_trampoline_addr(SB)/8, $libc_flistxattr_trampoline<>(SB)
+
+TEXT libc_setattrlist_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setattrlist(SB)
-TEXT ·libc_fcntl_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setattrlist_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setattrlist_trampoline_addr(SB)/8, $libc_setattrlist_trampoline<>(SB)
+
+TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fcntl(SB)
-TEXT ·libc_kill_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fcntl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
+
+TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_kill(SB)
-TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_kill_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB)
+
+TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_ioctl(SB)
-TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_ioctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB)
+
+TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_sysctl(SB)
-TEXT ·libc_sendfile_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_sysctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+
+TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_sendfile(SB)
-TEXT ·libc_access_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_sendfile_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendfile_trampoline_addr(SB)/8, $libc_sendfile_trampoline<>(SB)
+
+TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_access(SB)
-TEXT ·libc_adjtime_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_access_trampoline_addr(SB), RODATA, $8
+DATA	·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB)
+
+TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_adjtime(SB)
-TEXT ·libc_chdir_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_adjtime_trampoline_addr(SB), RODATA, $8
+DATA	·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB)
+
+TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_chdir(SB)
-TEXT ·libc_chflags_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_chdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB)
+
+TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_chflags(SB)
-TEXT ·libc_chmod_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_chflags_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB)
+
+TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_chmod(SB)
-TEXT ·libc_chown_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_chmod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB)
+
+TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_chown(SB)
-TEXT ·libc_chroot_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_chown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB)
+
+TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_chroot(SB)
-TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_chroot_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB)
+
+TEXT libc_clock_gettime_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_clock_gettime(SB)
-TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_clock_gettime_trampoline_addr(SB), RODATA, $8
+DATA	·libc_clock_gettime_trampoline_addr(SB)/8, $libc_clock_gettime_trampoline<>(SB)
+
+TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_close(SB)
-TEXT ·libc_clonefile_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_close_trampoline_addr(SB), RODATA, $8
+DATA	·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB)
+
+TEXT libc_clonefile_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_clonefile(SB)
-TEXT ·libc_clonefileat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_clonefile_trampoline_addr(SB), RODATA, $8
+DATA	·libc_clonefile_trampoline_addr(SB)/8, $libc_clonefile_trampoline<>(SB)
+
+TEXT libc_clonefileat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_clonefileat(SB)
-TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_clonefileat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_clonefileat_trampoline_addr(SB)/8, $libc_clonefileat_trampoline<>(SB)
+
+TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_dup(SB)
-TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_dup_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB)
+
+TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_dup2(SB)
-TEXT ·libc_exchangedata_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_dup2_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB)
+
+TEXT libc_exchangedata_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_exchangedata(SB)
-TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_exchangedata_trampoline_addr(SB), RODATA, $8
+DATA	·libc_exchangedata_trampoline_addr(SB)/8, $libc_exchangedata_trampoline<>(SB)
+
+TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_exit(SB)
-TEXT ·libc_faccessat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_exit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB)
+
+TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_faccessat(SB)
-TEXT ·libc_fchdir_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_faccessat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB)
+
+TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fchdir(SB)
-TEXT ·libc_fchflags_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fchdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB)
+
+TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fchflags(SB)
-TEXT ·libc_fchmod_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fchflags_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB)
+
+TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fchmod(SB)
-TEXT ·libc_fchmodat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fchmod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB)
+
+TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fchmodat(SB)
-TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fchmodat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB)
+
+TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fchown(SB)
-TEXT ·libc_fchownat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fchown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB)
+
+TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fchownat(SB)
-TEXT ·libc_fclonefileat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fchownat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB)
+
+TEXT libc_fclonefileat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fclonefileat(SB)
-TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fclonefileat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fclonefileat_trampoline_addr(SB)/8, $libc_fclonefileat_trampoline<>(SB)
+
+TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_flock(SB)
-TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_flock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB)
+
+TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fpathconf(SB)
-TEXT ·libc_fsync_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fpathconf_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB)
+
+TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fsync(SB)
-TEXT ·libc_ftruncate_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fsync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB)
+
+TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_ftruncate(SB)
-TEXT ·libc_getcwd_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_ftruncate_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB)
+
+TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getcwd(SB)
-TEXT ·libc_getdtablesize_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getcwd_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB)
+
+TEXT libc_getdtablesize_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getdtablesize(SB)
-TEXT ·libc_getegid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getdtablesize_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getdtablesize_trampoline_addr(SB)/8, $libc_getdtablesize_trampoline<>(SB)
+
+TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getegid(SB)
-TEXT ·libc_geteuid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getegid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB)
+
+TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_geteuid(SB)
-TEXT ·libc_getgid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_geteuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB)
+
+TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getgid(SB)
-TEXT ·libc_getpgid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB)
+
+TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getpgid(SB)
-TEXT ·libc_getpgrp_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getpgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB)
+
+TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getpgrp(SB)
-TEXT ·libc_getpid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getpgrp_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB)
+
+TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getpid(SB)
-TEXT ·libc_getppid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getpid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB)
+
+TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getppid(SB)
-TEXT ·libc_getpriority_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getppid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB)
+
+TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getpriority(SB)
-TEXT ·libc_getrlimit_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getpriority_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB)
+
+TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getrlimit(SB)
-TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getrlimit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB)
+
+TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getrusage(SB)
-TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getrusage_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB)
+
+TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getsid(SB)
-TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getsid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB)
+
+TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_gettimeofday(SB)
-TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_gettimeofday_trampoline_addr(SB), RODATA, $8
+DATA	·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB)
+
+TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getuid(SB)
-TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB)
+
+TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_issetugid(SB)
-TEXT ·libc_kqueue_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_issetugid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB)
+
+TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_kqueue(SB)
-TEXT ·libc_lchown_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_kqueue_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB)
+
+TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_lchown(SB)
-TEXT ·libc_link_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_lchown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB)
+
+TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_link(SB)
-TEXT ·libc_linkat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_link_trampoline_addr(SB), RODATA, $8
+DATA	·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB)
+
+TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_linkat(SB)
-TEXT ·libc_listen_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_linkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB)
+
+TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_listen(SB)
-TEXT ·libc_mkdir_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_listen_trampoline_addr(SB), RODATA, $8
+DATA	·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB)
+
+TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mkdir(SB)
-TEXT ·libc_mkdirat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mkdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB)
+
+TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mkdirat(SB)
-TEXT ·libc_mkfifo_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mkdirat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB)
+
+TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mkfifo(SB)
-TEXT ·libc_mknod_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mkfifo_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB)
+
+TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mknod(SB)
-TEXT ·libc_open_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mknod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB)
+
+TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_open(SB)
-TEXT ·libc_openat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_open_trampoline_addr(SB), RODATA, $8
+DATA	·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB)
+
+TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_openat(SB)
-TEXT ·libc_pathconf_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_openat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB)
+
+TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_pathconf(SB)
-TEXT ·libc_pread_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_pathconf_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB)
+
+TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_pread(SB)
-TEXT ·libc_pwrite_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_pread_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB)
+
+TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_pwrite(SB)
-TEXT ·libc_read_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_pwrite_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB)
+
+TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_read(SB)
-TEXT ·libc_readlink_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_read_trampoline_addr(SB), RODATA, $8
+DATA	·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB)
+
+TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_readlink(SB)
-TEXT ·libc_readlinkat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_readlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB)
+
+TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_readlinkat(SB)
-TEXT ·libc_rename_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_readlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB)
+
+TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_rename(SB)
-TEXT ·libc_renameat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_rename_trampoline_addr(SB), RODATA, $8
+DATA	·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB)
+
+TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_renameat(SB)
-TEXT ·libc_revoke_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_renameat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB)
+
+TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_revoke(SB)
-TEXT ·libc_rmdir_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_revoke_trampoline_addr(SB), RODATA, $8
+DATA	·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB)
+
+TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_rmdir(SB)
-TEXT ·libc_lseek_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_rmdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB)
+
+TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_lseek(SB)
-TEXT ·libc_select_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_lseek_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB)
+
+TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_select(SB)
-TEXT ·libc_setegid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_select_trampoline_addr(SB), RODATA, $8
+DATA	·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB)
+
+TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setegid(SB)
-TEXT ·libc_seteuid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setegid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB)
+
+TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_seteuid(SB)
-TEXT ·libc_setgid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_seteuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB)
+
+TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setgid(SB)
-TEXT ·libc_setlogin_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB)
+
+TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setlogin(SB)
-TEXT ·libc_setpgid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setlogin_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB)
+
+TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setpgid(SB)
-TEXT ·libc_setpriority_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setpgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB)
+
+TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setpriority(SB)
-TEXT ·libc_setprivexec_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setpriority_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB)
+
+TEXT libc_setprivexec_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setprivexec(SB)
-TEXT ·libc_setregid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setprivexec_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setprivexec_trampoline_addr(SB)/8, $libc_setprivexec_trampoline<>(SB)
+
+TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setregid(SB)
-TEXT ·libc_setreuid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setregid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB)
+
+TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setreuid(SB)
-TEXT ·libc_setrlimit_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setreuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB)
+
+TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setrlimit(SB)
-TEXT ·libc_setsid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setrlimit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB)
+
+TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setsid(SB)
-TEXT ·libc_settimeofday_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setsid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB)
+
+TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_settimeofday(SB)
-TEXT ·libc_setuid_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_settimeofday_trampoline_addr(SB), RODATA, $8
+DATA	·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB)
+
+TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_setuid(SB)
-TEXT ·libc_symlink_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_setuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB)
+
+TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_symlink(SB)
-TEXT ·libc_symlinkat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_symlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB)
+
+TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_symlinkat(SB)
-TEXT ·libc_sync_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_symlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB)
+
+TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_sync(SB)
-TEXT ·libc_truncate_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_sync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB)
+
+TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_truncate(SB)
-TEXT ·libc_umask_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_truncate_trampoline_addr(SB), RODATA, $8
+DATA	·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB)
+
+TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_umask(SB)
-TEXT ·libc_undelete_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_umask_trampoline_addr(SB), RODATA, $8
+DATA	·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB)
+
+TEXT libc_undelete_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_undelete(SB)
-TEXT ·libc_unlink_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_undelete_trampoline_addr(SB), RODATA, $8
+DATA	·libc_undelete_trampoline_addr(SB)/8, $libc_undelete_trampoline<>(SB)
+
+TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_unlink(SB)
-TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_unlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB)
+
+TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_unlinkat(SB)
-TEXT ·libc_unmount_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_unlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB)
+
+TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_unmount(SB)
-TEXT ·libc_write_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_unmount_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB)
+
+TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_write(SB)
-TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_write_trampoline_addr(SB), RODATA, $8
+DATA	·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB)
+
+TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_mmap(SB)
-TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_mmap_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB)
+
+TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_munmap(SB)
-TEXT ·libc_fstat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_munmap_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB)
+
+TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fstat(SB)
-TEXT ·libc_fstatat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fstat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstat_trampoline_addr(SB)/8, $libc_fstat_trampoline<>(SB)
+
+TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fstatat(SB)
-TEXT ·libc_fstatfs_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fstatat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstatat_trampoline_addr(SB)/8, $libc_fstatat_trampoline<>(SB)
+
+TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_fstatfs(SB)
-TEXT ·libc_getfsstat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_fstatfs_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstatfs_trampoline_addr(SB)/8, $libc_fstatfs_trampoline<>(SB)
+
+TEXT libc_getfsstat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getfsstat(SB)
-TEXT ·libc_lstat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_getfsstat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getfsstat_trampoline_addr(SB)/8, $libc_getfsstat_trampoline<>(SB)
+
+TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_lstat(SB)
-TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_lstat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lstat_trampoline_addr(SB)/8, $libc_lstat_trampoline<>(SB)
+
+TEXT libc_ptrace_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_ptrace(SB)
-TEXT ·libc_stat_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_ptrace_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ptrace_trampoline_addr(SB)/8, $libc_ptrace_trampoline<>(SB)
+
+TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_stat(SB)
-TEXT ·libc_statfs_trampoline(SB),NOSPLIT,$0-0
+
+GLOBL	·libc_stat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_stat_trampoline_addr(SB)/8, $libc_stat_trampoline<>(SB)
+
+TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_statfs(SB)
+
+GLOBL	·libc_statfs_trampoline_addr(SB), RODATA, $8
+DATA	·libc_statfs_trampoline_addr(SB)/8, $libc_statfs_trampoline<>(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go
index 1aaccd3..1b6eedf 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -dragonfly -tags dragonfly,amd64 syscall_bsd.go syscall_dragonfly.go syscall_dragonfly_amd64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build dragonfly && amd64
 // +build dragonfly,amd64
 
 package unix
@@ -362,8 +363,10 @@
 
 // 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)
+func pipe2(p *[2]_C_int, flags int) (r int, w int, err error) {
+	r0, r1, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	r = int(r0)
+	w = int(r1)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
index 600f1d2..3e9bddb 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -l32 -tags freebsd,386 syscall_bsd.go syscall_freebsd.go syscall_freebsd_386.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build freebsd && 386
 // +build freebsd,386
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
index 064934b..c72a462 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags freebsd,amd64 syscall_bsd.go syscall_freebsd.go syscall_freebsd_amd64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build freebsd && amd64
 // +build freebsd,amd64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
index 31d2c46..530d5df 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -l32 -arm -tags freebsd,arm syscall_bsd.go syscall_freebsd.go syscall_freebsd_arm.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build freebsd && arm
 // +build freebsd,arm
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go
index 4adaaa5..71e7df9 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags freebsd,arm64 syscall_bsd.go syscall_freebsd.go syscall_freebsd_arm64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build freebsd && arm64
 // +build freebsd,arm64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go
index d3af083..af5cb06 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go
@@ -1,6 +1,7 @@
 // go run mksyscall_solaris.go -illumos -tags illumos,amd64 syscall_illumos.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build illumos && amd64
 // +build illumos,amd64
 
 package unix
@@ -14,14 +15,16 @@
 //go:cgo_import_dynamic libc_writev writev "libc.so"
 //go:cgo_import_dynamic libc_pwritev pwritev "libc.so"
 //go:cgo_import_dynamic libc_accept4 accept4 "libsocket.so"
-//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
+//go:cgo_import_dynamic libc_putmsg putmsg "libc.so"
+//go:cgo_import_dynamic libc_getmsg getmsg "libc.so"
 
 //go:linkname procreadv libc_readv
 //go:linkname procpreadv libc_preadv
 //go:linkname procwritev libc_writev
 //go:linkname procpwritev libc_pwritev
 //go:linkname procaccept4 libc_accept4
-//go:linkname procpipe2 libc_pipe2
+//go:linkname procputmsg libc_putmsg
+//go:linkname procgetmsg libc_getmsg
 
 var (
 	procreadv,
@@ -29,7 +32,8 @@
 	procwritev,
 	procpwritev,
 	procaccept4,
-	procpipe2 syscallFunc
+	procputmsg,
+	procgetmsg syscallFunc
 )
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -105,8 +109,18 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procpipe2)), 2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0, 0, 0, 0)
+func putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error) {
+	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procputmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error) {
+	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(unsafe.Pointer(flags)), 0, 0)
 	if e1 != 0 {
 		err = e1
 	}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go
index 2fbbbe5..7305cc9 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go
@@ -1,5 +1,6 @@
 // Code generated by mkmerge.go; DO NOT EDIT.
 
+//go:build linux
 // +build linux
 
 package unix
@@ -531,6 +532,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func CloseRange(first uint, last uint, flags uint) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE_RANGE, uintptr(first), uintptr(last), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) {
 	r0, _, e1 := Syscall6(SYS_COPY_FILE_RANGE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
 	n = int(r0)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
index 19ebd3f..e37096e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -l32 -tags linux,386 syscall_linux.go syscall_linux_386.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && 386
 // +build linux,386
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
index 5c56218..9919d84 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags linux,amd64 syscall_linux.go syscall_linux_amd64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && amd64
 // +build linux,amd64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
index dc69d99..076754d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -l32 -arm -tags linux,arm syscall_linux.go syscall_linux_arm.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && arm
 // +build linux,arm
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
index 1b897de..e893f98 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags linux,arm64 syscall_linux.go syscall_linux_arm64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && arm64
 // +build linux,arm64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
index 4918684..4703cf3 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -b32 -arm -tags linux,mips syscall_linux.go syscall_linux_mipsx.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && mips
 // +build linux,mips
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
index 9171d3b..a134f9a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags linux,mips64 syscall_linux.go syscall_linux_mips64x.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && mips64
 // +build linux,mips64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
index 82286f0..b1fff2d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags linux,mips64le syscall_linux.go syscall_linux_mips64x.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && mips64le
 // +build linux,mips64le
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
index 1592062..d13d6da 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -l32 -arm -tags linux,mipsle syscall_linux.go syscall_linux_mipsx.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && mipsle
 // +build linux,mipsle
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go
new file mode 100644
index 0000000..927cf1a
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go
@@ -0,0 +1,762 @@
+// go run mksyscall.go -b32 -tags linux,ppc syscall_linux.go syscall_linux_ppc.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build linux && ppc
+// +build linux,ppc
+
+package unix
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var _ syscall.Errno
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) {
+	_, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask>>32), uintptr(mask), uintptr(dirFd), uintptr(unsafe.Pointer(pathname)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
+	_, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off>>32), uintptr(off), uintptr(len>>32), uintptr(len))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
+	r0, r1, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
+	n = int64(int64(r0)<<32 | int64(r1))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func dup2(oldfd int, newfd int) (err error) {
+	_, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate(size int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(events) > 0 {
+		_p0 = unsafe.Pointer(&events[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall(SYS_FTRUNCATE64, uintptr(fd), uintptr(length>>32), uintptr(length))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (euid int) {
+	r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0)
+	euid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit() (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ioperm(from int, num int, on int) (err error) {
+	_, _, e1 := Syscall(SYS_IOPERM, uintptr(from), uintptr(num), uintptr(on))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Iopl(level int) (err error) {
+	_, _, e1 := Syscall(SYS_IOPL, uintptr(level), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, n int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pause() (err error) {
+	_, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset>>32), uintptr(offset), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset>>32), uintptr(offset), 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 Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS__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)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+	r0, _, e1 := Syscall6(SYS_SENDFILE64, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
+	written = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setfsgid(gid int) (prev int, err error) {
+	r0, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0)
+	prev = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setfsuid(uid int) (prev int, err error) {
+	r0, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0)
+	prev = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresgid(rgid int, egid int, sgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresuid(ruid int, euid int, suid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_TRUNCATE64, uintptr(unsafe.Pointer(_p0)), uintptr(length>>32), uintptr(length))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ustat(dev int, ubuf *Ustat_t) (err error) {
+	_, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
+	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(n int, list *_Gid_t) (nn int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+	nn = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(n int, list *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimesat(dirfd int, path string, times *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Time(t *Time_t) (tt Time_t, err error) {
+	r0, _, e1 := RawSyscall(SYS_TIME, uintptr(unsafe.Pointer(t)), 0, 0)
+	tt = Time_t(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Utime(path string, buf *Utimbuf) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, times *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) {
+	r0, _, e1 := Syscall6(SYS_MMAP2, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(pageOffset))
+	xaddr = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getrlimit(resource int, rlim *rlimit32) (err error) {
+	_, _, e1 := RawSyscall(SYS_UGETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setrlimit(resource int, rlim *rlimit32) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]_C_int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func syncFileRange2(fd int, flags int, off int64, n int64) (err error) {
+	_, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(flags), uintptr(off>>32), uintptr(off), uintptr(n>>32), uintptr(n))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(cmdline)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_KEXEC_FILE_LOAD, uintptr(kernelFd), uintptr(initrdFd), uintptr(cmdlineLen), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
index 73a42e2..da8ec03 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags linux,ppc64 syscall_linux.go syscall_linux_ppc64x.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && ppc64
 // +build linux,ppc64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
index 6b85595..083f493 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags linux,ppc64le syscall_linux.go syscall_linux_ppc64x.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && ppc64le
 // +build linux,ppc64le
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
index b761334..63b393b 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags linux,riscv64 syscall_linux.go syscall_linux_riscv64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && riscv64
 // +build linux,riscv64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
index d7032ab..bb34740 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags linux,s390x syscall_linux.go syscall_linux_s390x.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && s390x
 // +build linux,s390x
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go
index bcbbdd9..8edc517 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -tags linux,sparc64 syscall_linux.go syscall_linux_sparc64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build linux && sparc64
 // +build linux,sparc64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
index 3bbd9e3..4726ab3 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -l32 -netbsd -tags netbsd,386 syscall_bsd.go syscall_netbsd.go syscall_netbsd_386.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build netbsd && 386
 // +build netbsd,386
 
 package unix
@@ -362,6 +363,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getdents(fd int, buf []byte) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
index d8cf501..fe71456 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -netbsd -tags netbsd,amd64 syscall_bsd.go syscall_netbsd.go syscall_netbsd_amd64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build netbsd && amd64
 // +build netbsd,amd64
 
 package unix
@@ -362,6 +363,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getdents(fd int, buf []byte) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
index 1153fe6..0b5b2f0 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -l32 -netbsd -arm -tags netbsd,arm syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build netbsd && arm
 // +build netbsd,arm
 
 package unix
@@ -362,6 +363,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getdents(fd int, buf []byte) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go
index 24b4ebb..bfca286 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -netbsd -tags netbsd,arm64 syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build netbsd && arm64
 // +build netbsd,arm64
 
 package unix
@@ -362,6 +363,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getdents(fd int, buf []byte) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
index b44b31a..8f80f4a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -l32 -openbsd -tags openbsd,386 syscall_bsd.go syscall_openbsd.go syscall_openbsd_386.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build openbsd && 386
 // +build openbsd,386
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
index 67f93ee..3a47aca 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -openbsd -tags openbsd,amd64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_amd64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build openbsd && amd64
 // +build openbsd,amd64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
index d7c878b..883a9b4 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -l32 -openbsd -arm -tags openbsd,arm syscall_bsd.go syscall_openbsd.go syscall_openbsd_arm.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build openbsd && arm
 // +build openbsd,arm
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go
index 8facd69..aac7fdc 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -openbsd -tags openbsd,arm64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_arm64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build openbsd && arm64
 // +build openbsd,arm64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go
index ec6bd5b..8776187 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go
@@ -1,6 +1,7 @@
 // go run mksyscall.go -openbsd -tags openbsd,mips64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_mips64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build openbsd && mips64
 // +build openbsd,mips64
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
index a96165d..4e18d5c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
@@ -1,6 +1,7 @@
 // go run mksyscall_solaris.go -tags solaris,amd64 syscall_solaris.go syscall_solaris_amd64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build solaris && amd64
 // +build solaris,amd64
 
 package unix
@@ -11,6 +12,7 @@
 )
 
 //go:cgo_import_dynamic libc_pipe pipe "libc.so"
+//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
 //go:cgo_import_dynamic libc_getsockname getsockname "libsocket.so"
 //go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
 //go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
@@ -114,6 +116,7 @@
 //go:cgo_import_dynamic libc_statvfs statvfs "libc.so"
 //go:cgo_import_dynamic libc_symlink symlink "libc.so"
 //go:cgo_import_dynamic libc_sync sync "libc.so"
+//go:cgo_import_dynamic libc_sysconf sysconf "libc.so"
 //go:cgo_import_dynamic libc_times times "libc.so"
 //go:cgo_import_dynamic libc_truncate truncate "libc.so"
 //go:cgo_import_dynamic libc_fsync fsync "libc.so"
@@ -140,6 +143,7 @@
 //go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so"
 
 //go:linkname procpipe libc_pipe
+//go:linkname procpipe2 libc_pipe2
 //go:linkname procgetsockname libc_getsockname
 //go:linkname procGetcwd libc_getcwd
 //go:linkname procgetgroups libc_getgroups
@@ -243,6 +247,7 @@
 //go:linkname procStatvfs libc_statvfs
 //go:linkname procSymlink libc_symlink
 //go:linkname procSync libc_sync
+//go:linkname procSysconf libc_sysconf
 //go:linkname procTimes libc_times
 //go:linkname procTruncate libc_truncate
 //go:linkname procFsync libc_fsync
@@ -270,6 +275,7 @@
 
 var (
 	procpipe,
+	procpipe2,
 	procgetsockname,
 	procGetcwd,
 	procgetgroups,
@@ -373,6 +379,7 @@
 	procStatvfs,
 	procSymlink,
 	procSync,
+	procSysconf,
 	procTimes,
 	procTruncate,
 	procFsync,
@@ -412,6 +419,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procpipe2)), 2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
 	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetsockname)), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
 	if e1 != 0 {
@@ -602,8 +619,9 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func ioctl(fd int, req uint, arg uintptr) (err error) {
-	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0)
+func ioctlRet(fd int, req uint, arg uintptr) (ret int, err error) {
+	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0)
+	ret = int(r0)
 	if e1 != 0 {
 		err = e1
 	}
@@ -1674,6 +1692,17 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Sysconf(which int) (n int64, err error) {
+	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procSysconf)), 1, uintptr(which), 0, 0, 0, 0, 0)
+	n = int64(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Times(tms *Tms) (ticks uintptr, err error) {
 	r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procTimes)), 1, uintptr(unsafe.Pointer(tms)), 0, 0, 0, 0, 0)
 	ticks = uintptr(r0)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go
new file mode 100644
index 0000000..f207945
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go
@@ -0,0 +1,1255 @@
+// go run mksyscall.go -tags zos,s390x syscall_zos_s390x.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+package unix
+
+import (
+	"unsafe"
+)
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := syscall_syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := syscall_syscall(SYS___ACCEPT_A, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := syscall_syscall(SYS___BIND_A, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := syscall_syscall(SYS___CONNECT_A, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(n int, list *_Gid_t) (nn int, err error) {
+	r0, _, e1 := syscall_rawsyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+	nn = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(n int, list *_Gid_t) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS_SETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := syscall_syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := syscall_syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := syscall_rawsyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := syscall_rawsyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS___GETPEERNAME_A, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS___GETSOCKNAME_A, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall6(SYS___RECVFROM_A, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall6(SYS___SENDTO_A, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(SYS___RECVMSG_A, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(SYS___SENDMSG_A, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := syscall_syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := syscall_syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ioctl(fd int, req uint, arg uintptr) (err error) {
+	_, _, e1 := syscall_syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___ACCESS_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___CHDIR_A, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___CHOWN_A, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___CHMOD_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Creat(path string, mode uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := syscall_syscall(SYS___CREAT_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int) (fd int, err error) {
+	r0, _, e1 := syscall_syscall(SYS_DUP, uintptr(oldfd), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(oldfd int, newfd int) (err error) {
+	_, _, e1 := syscall_syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Errno2() (er2 int) {
+	uer2, _, _ := syscall_syscall(SYS___ERRNO2, 0, 0, 0)
+	er2 = int(uer2)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Err2ad() (eadd *int) {
+	ueadd, _, _ := syscall_syscall(SYS___ERR2AD, 0, 0, 0)
+	eadd = (*int)(unsafe.Pointer(ueadd))
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	syscall_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_syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := syscall_syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := syscall_syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func FcntlInt(fd uintptr, cmd int, arg int) (retval int, err error) {
+	r0, _, e1 := syscall_syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	retval = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstat(fd int, stat *Stat_LE_t) (err error) {
+	_, _, e1 := syscall_syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatvfs(fd int, stat *Statvfs_t) (err error) {
+	_, _, e1 := syscall_syscall(SYS_FSTATVFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := syscall_syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := syscall_syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpagesize() (pgsize int) {
+	r0, _, _ := syscall_syscall(SYS_GETPAGESIZE, 0, 0, 0)
+	pgsize = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Poll(fds []PollFd, timeout int) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(fds) > 0 {
+		_p0 = unsafe.Pointer(&fds[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(SYS_POLL, uintptr(_p0), uintptr(len(fds)), uintptr(timeout))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Times(tms *Tms) (ticks uintptr, err error) {
+	r0, _, e1 := syscall_syscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
+	ticks = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func W_Getmntent(buff *byte, size int) (lastsys int, err error) {
+	r0, _, e1 := syscall_syscall(SYS_W_GETMNTENT, uintptr(unsafe.Pointer(buff)), uintptr(size), 0)
+	lastsys = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func W_Getmntent_A(buff *byte, size int) (lastsys int, err error) {
+	r0, _, e1 := syscall_syscall(SYS___W_GETMNTENT_A, uintptr(unsafe.Pointer(buff)), uintptr(size), 0)
+	lastsys = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount_LE(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(filesystem)
+	if err != nil {
+		return
+	}
+	var _p2 *byte
+	_p2, err = BytePtrFromString(fstype)
+	if err != nil {
+		return
+	}
+	var _p3 *byte
+	_p3, err = BytePtrFromString(parm)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(SYS___MOUNT_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(mtm), uintptr(parmlen), uintptr(unsafe.Pointer(_p3)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func unmount(filesystem string, mtm int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(filesystem)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___UMOUNT_A, uintptr(unsafe.Pointer(_p0)), uintptr(mtm), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___CHROOT_A, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Uname(buf *Utsname) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS___UNAME_A, uintptr(unsafe.Pointer(buf)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gethostname(buf []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(SYS___GETHOSTNAME_A, uintptr(_p0), uintptr(len(buf)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := syscall_rawsyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := syscall_rawsyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := syscall_rawsyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := syscall_rawsyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := syscall_rawsyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (pid int) {
+	r0, _, _ := syscall_rawsyscall(SYS_GETPPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := syscall_syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(resource int, rlim *Rlimit) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getrusage(who int, rusage *rusage_zos) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := syscall_rawsyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := syscall_rawsyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, sig Signal) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___LCHOWN_A, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___LINK_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, n int) (err error) {
+	_, _, e1 := syscall_syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func lstat(path string, stat *Stat_LE_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___LSTAT_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___MKDIR_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___MKFIFO_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___MKNOD_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(SYS___READLINK_A, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___RENAME_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___RMDIR_A, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (off int64, err error) {
+	r0, _, e1 := syscall_syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
+	off = int64(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := syscall_syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(resource int, lim *Rlimit) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := syscall_rawsyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := syscall_syscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(uid int) (err error) {
+	_, _, e1 := syscall_syscall(SYS_SETGID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(fd int, how int) (err error) {
+	_, _, e1 := syscall_syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func stat(path string, statLE *Stat_LE_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___STAT_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(statLE)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___SYMLINK_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() {
+	syscall_syscall(SYS_SYNC, 0, 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___TRUNCATE_A, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tcgetattr(fildes int, termptr *Termios) (err error) {
+	_, _, e1 := syscall_syscall(SYS_TCGETATTR, uintptr(fildes), uintptr(unsafe.Pointer(termptr)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tcsetattr(fildes int, when int, termptr *Termios) (err error) {
+	_, _, e1 := syscall_syscall(SYS_TCSETATTR, uintptr(fildes), uintptr(when), uintptr(unsafe.Pointer(termptr)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(mask int) (oldmask int) {
+	r0, _, _ := syscall_syscall(SYS_UMASK, uintptr(mask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___UNLINK_A, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Utime(path string, utim *Utimbuf) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___UTIME_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(utim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := syscall_syscall(SYS___OPEN_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func remove(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func waitpid(pid int, wstatus *_C_int, options int) (wpid int, err error) {
+	r0, _, e1 := syscall_syscall(SYS_WAITPID, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options))
+	wpid = 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_zos) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]_C_int) (err error) {
+	_, _, e1 := syscall_rawsyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(SYS___UTIMES_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(nmsgsfds int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (ret int, err error) {
+	r0, _, e1 := syscall_syscall6(SYS_SELECT, uintptr(nmsgsfds), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	ret = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go
index 102f1ab..9e9d0b2 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go
@@ -1,6 +1,7 @@
 // go run mksysctl_openbsd.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build 386 && openbsd
 // +build 386,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go
index 4866fce..adecd09 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go
@@ -1,6 +1,7 @@
 // go run mksysctl_openbsd.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build amd64 && openbsd
 // +build amd64,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go
index d3801eb..8ea52a4 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go
@@ -1,6 +1,7 @@
 // go run mksysctl_openbsd.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build arm && openbsd
 // +build arm,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go
index ba4304f..154b57a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go
@@ -1,6 +1,7 @@
 // go run mksysctl_openbsd.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build arm64 && openbsd
 // +build arm64,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go
index aca34b3..d96bb2b 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go
@@ -1,6 +1,7 @@
 // go run mksysctl_openbsd.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build mips64 && openbsd
 // +build mips64,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go
deleted file mode 100644
index ad62324..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go
+++ /dev/null
@@ -1,437 +0,0 @@
-// go run mksysnum.go /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/sys/syscall.h
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build 386,darwin
-
-package unix
-
-// Deprecated: Use libSystem wrappers instead of direct syscalls.
-const (
-	SYS_SYSCALL                        = 0
-	SYS_EXIT                           = 1
-	SYS_FORK                           = 2
-	SYS_READ                           = 3
-	SYS_WRITE                          = 4
-	SYS_OPEN                           = 5
-	SYS_CLOSE                          = 6
-	SYS_WAIT4                          = 7
-	SYS_LINK                           = 9
-	SYS_UNLINK                         = 10
-	SYS_CHDIR                          = 12
-	SYS_FCHDIR                         = 13
-	SYS_MKNOD                          = 14
-	SYS_CHMOD                          = 15
-	SYS_CHOWN                          = 16
-	SYS_GETFSSTAT                      = 18
-	SYS_GETPID                         = 20
-	SYS_SETUID                         = 23
-	SYS_GETUID                         = 24
-	SYS_GETEUID                        = 25
-	SYS_PTRACE                         = 26
-	SYS_RECVMSG                        = 27
-	SYS_SENDMSG                        = 28
-	SYS_RECVFROM                       = 29
-	SYS_ACCEPT                         = 30
-	SYS_GETPEERNAME                    = 31
-	SYS_GETSOCKNAME                    = 32
-	SYS_ACCESS                         = 33
-	SYS_CHFLAGS                        = 34
-	SYS_FCHFLAGS                       = 35
-	SYS_SYNC                           = 36
-	SYS_KILL                           = 37
-	SYS_GETPPID                        = 39
-	SYS_DUP                            = 41
-	SYS_PIPE                           = 42
-	SYS_GETEGID                        = 43
-	SYS_SIGACTION                      = 46
-	SYS_GETGID                         = 47
-	SYS_SIGPROCMASK                    = 48
-	SYS_GETLOGIN                       = 49
-	SYS_SETLOGIN                       = 50
-	SYS_ACCT                           = 51
-	SYS_SIGPENDING                     = 52
-	SYS_SIGALTSTACK                    = 53
-	SYS_IOCTL                          = 54
-	SYS_REBOOT                         = 55
-	SYS_REVOKE                         = 56
-	SYS_SYMLINK                        = 57
-	SYS_READLINK                       = 58
-	SYS_EXECVE                         = 59
-	SYS_UMASK                          = 60
-	SYS_CHROOT                         = 61
-	SYS_MSYNC                          = 65
-	SYS_VFORK                          = 66
-	SYS_MUNMAP                         = 73
-	SYS_MPROTECT                       = 74
-	SYS_MADVISE                        = 75
-	SYS_MINCORE                        = 78
-	SYS_GETGROUPS                      = 79
-	SYS_SETGROUPS                      = 80
-	SYS_GETPGRP                        = 81
-	SYS_SETPGID                        = 82
-	SYS_SETITIMER                      = 83
-	SYS_SWAPON                         = 85
-	SYS_GETITIMER                      = 86
-	SYS_GETDTABLESIZE                  = 89
-	SYS_DUP2                           = 90
-	SYS_FCNTL                          = 92
-	SYS_SELECT                         = 93
-	SYS_FSYNC                          = 95
-	SYS_SETPRIORITY                    = 96
-	SYS_SOCKET                         = 97
-	SYS_CONNECT                        = 98
-	SYS_GETPRIORITY                    = 100
-	SYS_BIND                           = 104
-	SYS_SETSOCKOPT                     = 105
-	SYS_LISTEN                         = 106
-	SYS_SIGSUSPEND                     = 111
-	SYS_GETTIMEOFDAY                   = 116
-	SYS_GETRUSAGE                      = 117
-	SYS_GETSOCKOPT                     = 118
-	SYS_READV                          = 120
-	SYS_WRITEV                         = 121
-	SYS_SETTIMEOFDAY                   = 122
-	SYS_FCHOWN                         = 123
-	SYS_FCHMOD                         = 124
-	SYS_SETREUID                       = 126
-	SYS_SETREGID                       = 127
-	SYS_RENAME                         = 128
-	SYS_FLOCK                          = 131
-	SYS_MKFIFO                         = 132
-	SYS_SENDTO                         = 133
-	SYS_SHUTDOWN                       = 134
-	SYS_SOCKETPAIR                     = 135
-	SYS_MKDIR                          = 136
-	SYS_RMDIR                          = 137
-	SYS_UTIMES                         = 138
-	SYS_FUTIMES                        = 139
-	SYS_ADJTIME                        = 140
-	SYS_GETHOSTUUID                    = 142
-	SYS_SETSID                         = 147
-	SYS_GETPGID                        = 151
-	SYS_SETPRIVEXEC                    = 152
-	SYS_PREAD                          = 153
-	SYS_PWRITE                         = 154
-	SYS_NFSSVC                         = 155
-	SYS_STATFS                         = 157
-	SYS_FSTATFS                        = 158
-	SYS_UNMOUNT                        = 159
-	SYS_GETFH                          = 161
-	SYS_QUOTACTL                       = 165
-	SYS_MOUNT                          = 167
-	SYS_CSOPS                          = 169
-	SYS_CSOPS_AUDITTOKEN               = 170
-	SYS_WAITID                         = 173
-	SYS_KDEBUG_TYPEFILTER              = 177
-	SYS_KDEBUG_TRACE_STRING            = 178
-	SYS_KDEBUG_TRACE64                 = 179
-	SYS_KDEBUG_TRACE                   = 180
-	SYS_SETGID                         = 181
-	SYS_SETEGID                        = 182
-	SYS_SETEUID                        = 183
-	SYS_SIGRETURN                      = 184
-	SYS_THREAD_SELFCOUNTS              = 186
-	SYS_FDATASYNC                      = 187
-	SYS_STAT                           = 188
-	SYS_FSTAT                          = 189
-	SYS_LSTAT                          = 190
-	SYS_PATHCONF                       = 191
-	SYS_FPATHCONF                      = 192
-	SYS_GETRLIMIT                      = 194
-	SYS_SETRLIMIT                      = 195
-	SYS_GETDIRENTRIES                  = 196
-	SYS_MMAP                           = 197
-	SYS_LSEEK                          = 199
-	SYS_TRUNCATE                       = 200
-	SYS_FTRUNCATE                      = 201
-	SYS_SYSCTL                         = 202
-	SYS_MLOCK                          = 203
-	SYS_MUNLOCK                        = 204
-	SYS_UNDELETE                       = 205
-	SYS_OPEN_DPROTECTED_NP             = 216
-	SYS_GETATTRLIST                    = 220
-	SYS_SETATTRLIST                    = 221
-	SYS_GETDIRENTRIESATTR              = 222
-	SYS_EXCHANGEDATA                   = 223
-	SYS_SEARCHFS                       = 225
-	SYS_DELETE                         = 226
-	SYS_COPYFILE                       = 227
-	SYS_FGETATTRLIST                   = 228
-	SYS_FSETATTRLIST                   = 229
-	SYS_POLL                           = 230
-	SYS_WATCHEVENT                     = 231
-	SYS_WAITEVENT                      = 232
-	SYS_MODWATCH                       = 233
-	SYS_GETXATTR                       = 234
-	SYS_FGETXATTR                      = 235
-	SYS_SETXATTR                       = 236
-	SYS_FSETXATTR                      = 237
-	SYS_REMOVEXATTR                    = 238
-	SYS_FREMOVEXATTR                   = 239
-	SYS_LISTXATTR                      = 240
-	SYS_FLISTXATTR                     = 241
-	SYS_FSCTL                          = 242
-	SYS_INITGROUPS                     = 243
-	SYS_POSIX_SPAWN                    = 244
-	SYS_FFSCTL                         = 245
-	SYS_NFSCLNT                        = 247
-	SYS_FHOPEN                         = 248
-	SYS_MINHERIT                       = 250
-	SYS_SEMSYS                         = 251
-	SYS_MSGSYS                         = 252
-	SYS_SHMSYS                         = 253
-	SYS_SEMCTL                         = 254
-	SYS_SEMGET                         = 255
-	SYS_SEMOP                          = 256
-	SYS_MSGCTL                         = 258
-	SYS_MSGGET                         = 259
-	SYS_MSGSND                         = 260
-	SYS_MSGRCV                         = 261
-	SYS_SHMAT                          = 262
-	SYS_SHMCTL                         = 263
-	SYS_SHMDT                          = 264
-	SYS_SHMGET                         = 265
-	SYS_SHM_OPEN                       = 266
-	SYS_SHM_UNLINK                     = 267
-	SYS_SEM_OPEN                       = 268
-	SYS_SEM_CLOSE                      = 269
-	SYS_SEM_UNLINK                     = 270
-	SYS_SEM_WAIT                       = 271
-	SYS_SEM_TRYWAIT                    = 272
-	SYS_SEM_POST                       = 273
-	SYS_SYSCTLBYNAME                   = 274
-	SYS_OPEN_EXTENDED                  = 277
-	SYS_UMASK_EXTENDED                 = 278
-	SYS_STAT_EXTENDED                  = 279
-	SYS_LSTAT_EXTENDED                 = 280
-	SYS_FSTAT_EXTENDED                 = 281
-	SYS_CHMOD_EXTENDED                 = 282
-	SYS_FCHMOD_EXTENDED                = 283
-	SYS_ACCESS_EXTENDED                = 284
-	SYS_SETTID                         = 285
-	SYS_GETTID                         = 286
-	SYS_SETSGROUPS                     = 287
-	SYS_GETSGROUPS                     = 288
-	SYS_SETWGROUPS                     = 289
-	SYS_GETWGROUPS                     = 290
-	SYS_MKFIFO_EXTENDED                = 291
-	SYS_MKDIR_EXTENDED                 = 292
-	SYS_IDENTITYSVC                    = 293
-	SYS_SHARED_REGION_CHECK_NP         = 294
-	SYS_VM_PRESSURE_MONITOR            = 296
-	SYS_PSYNCH_RW_LONGRDLOCK           = 297
-	SYS_PSYNCH_RW_YIELDWRLOCK          = 298
-	SYS_PSYNCH_RW_DOWNGRADE            = 299
-	SYS_PSYNCH_RW_UPGRADE              = 300
-	SYS_PSYNCH_MUTEXWAIT               = 301
-	SYS_PSYNCH_MUTEXDROP               = 302
-	SYS_PSYNCH_CVBROAD                 = 303
-	SYS_PSYNCH_CVSIGNAL                = 304
-	SYS_PSYNCH_CVWAIT                  = 305
-	SYS_PSYNCH_RW_RDLOCK               = 306
-	SYS_PSYNCH_RW_WRLOCK               = 307
-	SYS_PSYNCH_RW_UNLOCK               = 308
-	SYS_PSYNCH_RW_UNLOCK2              = 309
-	SYS_GETSID                         = 310
-	SYS_SETTID_WITH_PID                = 311
-	SYS_PSYNCH_CVCLRPREPOST            = 312
-	SYS_AIO_FSYNC                      = 313
-	SYS_AIO_RETURN                     = 314
-	SYS_AIO_SUSPEND                    = 315
-	SYS_AIO_CANCEL                     = 316
-	SYS_AIO_ERROR                      = 317
-	SYS_AIO_READ                       = 318
-	SYS_AIO_WRITE                      = 319
-	SYS_LIO_LISTIO                     = 320
-	SYS_IOPOLICYSYS                    = 322
-	SYS_PROCESS_POLICY                 = 323
-	SYS_MLOCKALL                       = 324
-	SYS_MUNLOCKALL                     = 325
-	SYS_ISSETUGID                      = 327
-	SYS___PTHREAD_KILL                 = 328
-	SYS___PTHREAD_SIGMASK              = 329
-	SYS___SIGWAIT                      = 330
-	SYS___DISABLE_THREADSIGNAL         = 331
-	SYS___PTHREAD_MARKCANCEL           = 332
-	SYS___PTHREAD_CANCELED             = 333
-	SYS___SEMWAIT_SIGNAL               = 334
-	SYS_PROC_INFO                      = 336
-	SYS_SENDFILE                       = 337
-	SYS_STAT64                         = 338
-	SYS_FSTAT64                        = 339
-	SYS_LSTAT64                        = 340
-	SYS_STAT64_EXTENDED                = 341
-	SYS_LSTAT64_EXTENDED               = 342
-	SYS_FSTAT64_EXTENDED               = 343
-	SYS_GETDIRENTRIES64                = 344
-	SYS_STATFS64                       = 345
-	SYS_FSTATFS64                      = 346
-	SYS_GETFSSTAT64                    = 347
-	SYS___PTHREAD_CHDIR                = 348
-	SYS___PTHREAD_FCHDIR               = 349
-	SYS_AUDIT                          = 350
-	SYS_AUDITON                        = 351
-	SYS_GETAUID                        = 353
-	SYS_SETAUID                        = 354
-	SYS_GETAUDIT_ADDR                  = 357
-	SYS_SETAUDIT_ADDR                  = 358
-	SYS_AUDITCTL                       = 359
-	SYS_BSDTHREAD_CREATE               = 360
-	SYS_BSDTHREAD_TERMINATE            = 361
-	SYS_KQUEUE                         = 362
-	SYS_KEVENT                         = 363
-	SYS_LCHOWN                         = 364
-	SYS_BSDTHREAD_REGISTER             = 366
-	SYS_WORKQ_OPEN                     = 367
-	SYS_WORKQ_KERNRETURN               = 368
-	SYS_KEVENT64                       = 369
-	SYS___OLD_SEMWAIT_SIGNAL           = 370
-	SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL  = 371
-	SYS_THREAD_SELFID                  = 372
-	SYS_LEDGER                         = 373
-	SYS_KEVENT_QOS                     = 374
-	SYS_KEVENT_ID                      = 375
-	SYS___MAC_EXECVE                   = 380
-	SYS___MAC_SYSCALL                  = 381
-	SYS___MAC_GET_FILE                 = 382
-	SYS___MAC_SET_FILE                 = 383
-	SYS___MAC_GET_LINK                 = 384
-	SYS___MAC_SET_LINK                 = 385
-	SYS___MAC_GET_PROC                 = 386
-	SYS___MAC_SET_PROC                 = 387
-	SYS___MAC_GET_FD                   = 388
-	SYS___MAC_SET_FD                   = 389
-	SYS___MAC_GET_PID                  = 390
-	SYS_PSELECT                        = 394
-	SYS_PSELECT_NOCANCEL               = 395
-	SYS_READ_NOCANCEL                  = 396
-	SYS_WRITE_NOCANCEL                 = 397
-	SYS_OPEN_NOCANCEL                  = 398
-	SYS_CLOSE_NOCANCEL                 = 399
-	SYS_WAIT4_NOCANCEL                 = 400
-	SYS_RECVMSG_NOCANCEL               = 401
-	SYS_SENDMSG_NOCANCEL               = 402
-	SYS_RECVFROM_NOCANCEL              = 403
-	SYS_ACCEPT_NOCANCEL                = 404
-	SYS_MSYNC_NOCANCEL                 = 405
-	SYS_FCNTL_NOCANCEL                 = 406
-	SYS_SELECT_NOCANCEL                = 407
-	SYS_FSYNC_NOCANCEL                 = 408
-	SYS_CONNECT_NOCANCEL               = 409
-	SYS_SIGSUSPEND_NOCANCEL            = 410
-	SYS_READV_NOCANCEL                 = 411
-	SYS_WRITEV_NOCANCEL                = 412
-	SYS_SENDTO_NOCANCEL                = 413
-	SYS_PREAD_NOCANCEL                 = 414
-	SYS_PWRITE_NOCANCEL                = 415
-	SYS_WAITID_NOCANCEL                = 416
-	SYS_POLL_NOCANCEL                  = 417
-	SYS_MSGSND_NOCANCEL                = 418
-	SYS_MSGRCV_NOCANCEL                = 419
-	SYS_SEM_WAIT_NOCANCEL              = 420
-	SYS_AIO_SUSPEND_NOCANCEL           = 421
-	SYS___SIGWAIT_NOCANCEL             = 422
-	SYS___SEMWAIT_SIGNAL_NOCANCEL      = 423
-	SYS___MAC_MOUNT                    = 424
-	SYS___MAC_GET_MOUNT                = 425
-	SYS___MAC_GETFSSTAT                = 426
-	SYS_FSGETPATH                      = 427
-	SYS_AUDIT_SESSION_SELF             = 428
-	SYS_AUDIT_SESSION_JOIN             = 429
-	SYS_FILEPORT_MAKEPORT              = 430
-	SYS_FILEPORT_MAKEFD                = 431
-	SYS_AUDIT_SESSION_PORT             = 432
-	SYS_PID_SUSPEND                    = 433
-	SYS_PID_RESUME                     = 434
-	SYS_PID_HIBERNATE                  = 435
-	SYS_PID_SHUTDOWN_SOCKETS           = 436
-	SYS_SHARED_REGION_MAP_AND_SLIDE_NP = 438
-	SYS_KAS_INFO                       = 439
-	SYS_MEMORYSTATUS_CONTROL           = 440
-	SYS_GUARDED_OPEN_NP                = 441
-	SYS_GUARDED_CLOSE_NP               = 442
-	SYS_GUARDED_KQUEUE_NP              = 443
-	SYS_CHANGE_FDGUARD_NP              = 444
-	SYS_USRCTL                         = 445
-	SYS_PROC_RLIMIT_CONTROL            = 446
-	SYS_CONNECTX                       = 447
-	SYS_DISCONNECTX                    = 448
-	SYS_PEELOFF                        = 449
-	SYS_SOCKET_DELEGATE                = 450
-	SYS_TELEMETRY                      = 451
-	SYS_PROC_UUID_POLICY               = 452
-	SYS_MEMORYSTATUS_GET_LEVEL         = 453
-	SYS_SYSTEM_OVERRIDE                = 454
-	SYS_VFS_PURGE                      = 455
-	SYS_SFI_CTL                        = 456
-	SYS_SFI_PIDCTL                     = 457
-	SYS_COALITION                      = 458
-	SYS_COALITION_INFO                 = 459
-	SYS_NECP_MATCH_POLICY              = 460
-	SYS_GETATTRLISTBULK                = 461
-	SYS_CLONEFILEAT                    = 462
-	SYS_OPENAT                         = 463
-	SYS_OPENAT_NOCANCEL                = 464
-	SYS_RENAMEAT                       = 465
-	SYS_FACCESSAT                      = 466
-	SYS_FCHMODAT                       = 467
-	SYS_FCHOWNAT                       = 468
-	SYS_FSTATAT                        = 469
-	SYS_FSTATAT64                      = 470
-	SYS_LINKAT                         = 471
-	SYS_UNLINKAT                       = 472
-	SYS_READLINKAT                     = 473
-	SYS_SYMLINKAT                      = 474
-	SYS_MKDIRAT                        = 475
-	SYS_GETATTRLISTAT                  = 476
-	SYS_PROC_TRACE_LOG                 = 477
-	SYS_BSDTHREAD_CTL                  = 478
-	SYS_OPENBYID_NP                    = 479
-	SYS_RECVMSG_X                      = 480
-	SYS_SENDMSG_X                      = 481
-	SYS_THREAD_SELFUSAGE               = 482
-	SYS_CSRCTL                         = 483
-	SYS_GUARDED_OPEN_DPROTECTED_NP     = 484
-	SYS_GUARDED_WRITE_NP               = 485
-	SYS_GUARDED_PWRITE_NP              = 486
-	SYS_GUARDED_WRITEV_NP              = 487
-	SYS_RENAMEATX_NP                   = 488
-	SYS_MREMAP_ENCRYPTED               = 489
-	SYS_NETAGENT_TRIGGER               = 490
-	SYS_STACK_SNAPSHOT_WITH_CONFIG     = 491
-	SYS_MICROSTACKSHOT                 = 492
-	SYS_GRAB_PGO_DATA                  = 493
-	SYS_PERSONA                        = 494
-	SYS_WORK_INTERVAL_CTL              = 499
-	SYS_GETENTROPY                     = 500
-	SYS_NECP_OPEN                      = 501
-	SYS_NECP_CLIENT_ACTION             = 502
-	SYS___NEXUS_OPEN                   = 503
-	SYS___NEXUS_REGISTER               = 504
-	SYS___NEXUS_DEREGISTER             = 505
-	SYS___NEXUS_CREATE                 = 506
-	SYS___NEXUS_DESTROY                = 507
-	SYS___NEXUS_GET_OPT                = 508
-	SYS___NEXUS_SET_OPT                = 509
-	SYS___CHANNEL_OPEN                 = 510
-	SYS___CHANNEL_GET_INFO             = 511
-	SYS___CHANNEL_SYNC                 = 512
-	SYS___CHANNEL_GET_OPT              = 513
-	SYS___CHANNEL_SET_OPT              = 514
-	SYS_ULOCK_WAIT                     = 515
-	SYS_ULOCK_WAKE                     = 516
-	SYS_FCLONEFILEAT                   = 517
-	SYS_FS_SNAPSHOT                    = 518
-	SYS_TERMINATE_WITH_PAYLOAD         = 520
-	SYS_ABORT_WITH_PAYLOAD             = 521
-	SYS_NECP_SESSION_OPEN              = 522
-	SYS_NECP_SESSION_ACTION            = 523
-	SYS_SETATTRLISTAT                  = 524
-	SYS_NET_QOS_GUIDELINE              = 525
-	SYS_FMOUNT                         = 526
-	SYS_NTP_ADJTIME                    = 527
-	SYS_NTP_GETTIME                    = 528
-	SYS_OS_FAULT_WITH_PAYLOAD          = 529
-	SYS_MAXSYSCALL                     = 530
-	SYS_INVALID                        = 63
-)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go
index a2fc91d..f8298ff 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/sys/syscall.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && darwin
 // +build amd64,darwin
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go
deleted file mode 100644
index 20d7808..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go
+++ /dev/null
@@ -1,437 +0,0 @@
-// go run mksysnum.go /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.1.sdk/usr/include/sys/syscall.h
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build arm,darwin
-
-package unix
-
-// Deprecated: Use libSystem wrappers instead of direct syscalls.
-const (
-	SYS_SYSCALL                        = 0
-	SYS_EXIT                           = 1
-	SYS_FORK                           = 2
-	SYS_READ                           = 3
-	SYS_WRITE                          = 4
-	SYS_OPEN                           = 5
-	SYS_CLOSE                          = 6
-	SYS_WAIT4                          = 7
-	SYS_LINK                           = 9
-	SYS_UNLINK                         = 10
-	SYS_CHDIR                          = 12
-	SYS_FCHDIR                         = 13
-	SYS_MKNOD                          = 14
-	SYS_CHMOD                          = 15
-	SYS_CHOWN                          = 16
-	SYS_GETFSSTAT                      = 18
-	SYS_GETPID                         = 20
-	SYS_SETUID                         = 23
-	SYS_GETUID                         = 24
-	SYS_GETEUID                        = 25
-	SYS_PTRACE                         = 26
-	SYS_RECVMSG                        = 27
-	SYS_SENDMSG                        = 28
-	SYS_RECVFROM                       = 29
-	SYS_ACCEPT                         = 30
-	SYS_GETPEERNAME                    = 31
-	SYS_GETSOCKNAME                    = 32
-	SYS_ACCESS                         = 33
-	SYS_CHFLAGS                        = 34
-	SYS_FCHFLAGS                       = 35
-	SYS_SYNC                           = 36
-	SYS_KILL                           = 37
-	SYS_GETPPID                        = 39
-	SYS_DUP                            = 41
-	SYS_PIPE                           = 42
-	SYS_GETEGID                        = 43
-	SYS_SIGACTION                      = 46
-	SYS_GETGID                         = 47
-	SYS_SIGPROCMASK                    = 48
-	SYS_GETLOGIN                       = 49
-	SYS_SETLOGIN                       = 50
-	SYS_ACCT                           = 51
-	SYS_SIGPENDING                     = 52
-	SYS_SIGALTSTACK                    = 53
-	SYS_IOCTL                          = 54
-	SYS_REBOOT                         = 55
-	SYS_REVOKE                         = 56
-	SYS_SYMLINK                        = 57
-	SYS_READLINK                       = 58
-	SYS_EXECVE                         = 59
-	SYS_UMASK                          = 60
-	SYS_CHROOT                         = 61
-	SYS_MSYNC                          = 65
-	SYS_VFORK                          = 66
-	SYS_MUNMAP                         = 73
-	SYS_MPROTECT                       = 74
-	SYS_MADVISE                        = 75
-	SYS_MINCORE                        = 78
-	SYS_GETGROUPS                      = 79
-	SYS_SETGROUPS                      = 80
-	SYS_GETPGRP                        = 81
-	SYS_SETPGID                        = 82
-	SYS_SETITIMER                      = 83
-	SYS_SWAPON                         = 85
-	SYS_GETITIMER                      = 86
-	SYS_GETDTABLESIZE                  = 89
-	SYS_DUP2                           = 90
-	SYS_FCNTL                          = 92
-	SYS_SELECT                         = 93
-	SYS_FSYNC                          = 95
-	SYS_SETPRIORITY                    = 96
-	SYS_SOCKET                         = 97
-	SYS_CONNECT                        = 98
-	SYS_GETPRIORITY                    = 100
-	SYS_BIND                           = 104
-	SYS_SETSOCKOPT                     = 105
-	SYS_LISTEN                         = 106
-	SYS_SIGSUSPEND                     = 111
-	SYS_GETTIMEOFDAY                   = 116
-	SYS_GETRUSAGE                      = 117
-	SYS_GETSOCKOPT                     = 118
-	SYS_READV                          = 120
-	SYS_WRITEV                         = 121
-	SYS_SETTIMEOFDAY                   = 122
-	SYS_FCHOWN                         = 123
-	SYS_FCHMOD                         = 124
-	SYS_SETREUID                       = 126
-	SYS_SETREGID                       = 127
-	SYS_RENAME                         = 128
-	SYS_FLOCK                          = 131
-	SYS_MKFIFO                         = 132
-	SYS_SENDTO                         = 133
-	SYS_SHUTDOWN                       = 134
-	SYS_SOCKETPAIR                     = 135
-	SYS_MKDIR                          = 136
-	SYS_RMDIR                          = 137
-	SYS_UTIMES                         = 138
-	SYS_FUTIMES                        = 139
-	SYS_ADJTIME                        = 140
-	SYS_GETHOSTUUID                    = 142
-	SYS_SETSID                         = 147
-	SYS_GETPGID                        = 151
-	SYS_SETPRIVEXEC                    = 152
-	SYS_PREAD                          = 153
-	SYS_PWRITE                         = 154
-	SYS_NFSSVC                         = 155
-	SYS_STATFS                         = 157
-	SYS_FSTATFS                        = 158
-	SYS_UNMOUNT                        = 159
-	SYS_GETFH                          = 161
-	SYS_QUOTACTL                       = 165
-	SYS_MOUNT                          = 167
-	SYS_CSOPS                          = 169
-	SYS_CSOPS_AUDITTOKEN               = 170
-	SYS_WAITID                         = 173
-	SYS_KDEBUG_TYPEFILTER              = 177
-	SYS_KDEBUG_TRACE_STRING            = 178
-	SYS_KDEBUG_TRACE64                 = 179
-	SYS_KDEBUG_TRACE                   = 180
-	SYS_SETGID                         = 181
-	SYS_SETEGID                        = 182
-	SYS_SETEUID                        = 183
-	SYS_SIGRETURN                      = 184
-	SYS_THREAD_SELFCOUNTS              = 186
-	SYS_FDATASYNC                      = 187
-	SYS_STAT                           = 188
-	SYS_FSTAT                          = 189
-	SYS_LSTAT                          = 190
-	SYS_PATHCONF                       = 191
-	SYS_FPATHCONF                      = 192
-	SYS_GETRLIMIT                      = 194
-	SYS_SETRLIMIT                      = 195
-	SYS_GETDIRENTRIES                  = 196
-	SYS_MMAP                           = 197
-	SYS_LSEEK                          = 199
-	SYS_TRUNCATE                       = 200
-	SYS_FTRUNCATE                      = 201
-	SYS_SYSCTL                         = 202
-	SYS_MLOCK                          = 203
-	SYS_MUNLOCK                        = 204
-	SYS_UNDELETE                       = 205
-	SYS_OPEN_DPROTECTED_NP             = 216
-	SYS_GETATTRLIST                    = 220
-	SYS_SETATTRLIST                    = 221
-	SYS_GETDIRENTRIESATTR              = 222
-	SYS_EXCHANGEDATA                   = 223
-	SYS_SEARCHFS                       = 225
-	SYS_DELETE                         = 226
-	SYS_COPYFILE                       = 227
-	SYS_FGETATTRLIST                   = 228
-	SYS_FSETATTRLIST                   = 229
-	SYS_POLL                           = 230
-	SYS_WATCHEVENT                     = 231
-	SYS_WAITEVENT                      = 232
-	SYS_MODWATCH                       = 233
-	SYS_GETXATTR                       = 234
-	SYS_FGETXATTR                      = 235
-	SYS_SETXATTR                       = 236
-	SYS_FSETXATTR                      = 237
-	SYS_REMOVEXATTR                    = 238
-	SYS_FREMOVEXATTR                   = 239
-	SYS_LISTXATTR                      = 240
-	SYS_FLISTXATTR                     = 241
-	SYS_FSCTL                          = 242
-	SYS_INITGROUPS                     = 243
-	SYS_POSIX_SPAWN                    = 244
-	SYS_FFSCTL                         = 245
-	SYS_NFSCLNT                        = 247
-	SYS_FHOPEN                         = 248
-	SYS_MINHERIT                       = 250
-	SYS_SEMSYS                         = 251
-	SYS_MSGSYS                         = 252
-	SYS_SHMSYS                         = 253
-	SYS_SEMCTL                         = 254
-	SYS_SEMGET                         = 255
-	SYS_SEMOP                          = 256
-	SYS_MSGCTL                         = 258
-	SYS_MSGGET                         = 259
-	SYS_MSGSND                         = 260
-	SYS_MSGRCV                         = 261
-	SYS_SHMAT                          = 262
-	SYS_SHMCTL                         = 263
-	SYS_SHMDT                          = 264
-	SYS_SHMGET                         = 265
-	SYS_SHM_OPEN                       = 266
-	SYS_SHM_UNLINK                     = 267
-	SYS_SEM_OPEN                       = 268
-	SYS_SEM_CLOSE                      = 269
-	SYS_SEM_UNLINK                     = 270
-	SYS_SEM_WAIT                       = 271
-	SYS_SEM_TRYWAIT                    = 272
-	SYS_SEM_POST                       = 273
-	SYS_SYSCTLBYNAME                   = 274
-	SYS_OPEN_EXTENDED                  = 277
-	SYS_UMASK_EXTENDED                 = 278
-	SYS_STAT_EXTENDED                  = 279
-	SYS_LSTAT_EXTENDED                 = 280
-	SYS_FSTAT_EXTENDED                 = 281
-	SYS_CHMOD_EXTENDED                 = 282
-	SYS_FCHMOD_EXTENDED                = 283
-	SYS_ACCESS_EXTENDED                = 284
-	SYS_SETTID                         = 285
-	SYS_GETTID                         = 286
-	SYS_SETSGROUPS                     = 287
-	SYS_GETSGROUPS                     = 288
-	SYS_SETWGROUPS                     = 289
-	SYS_GETWGROUPS                     = 290
-	SYS_MKFIFO_EXTENDED                = 291
-	SYS_MKDIR_EXTENDED                 = 292
-	SYS_IDENTITYSVC                    = 293
-	SYS_SHARED_REGION_CHECK_NP         = 294
-	SYS_VM_PRESSURE_MONITOR            = 296
-	SYS_PSYNCH_RW_LONGRDLOCK           = 297
-	SYS_PSYNCH_RW_YIELDWRLOCK          = 298
-	SYS_PSYNCH_RW_DOWNGRADE            = 299
-	SYS_PSYNCH_RW_UPGRADE              = 300
-	SYS_PSYNCH_MUTEXWAIT               = 301
-	SYS_PSYNCH_MUTEXDROP               = 302
-	SYS_PSYNCH_CVBROAD                 = 303
-	SYS_PSYNCH_CVSIGNAL                = 304
-	SYS_PSYNCH_CVWAIT                  = 305
-	SYS_PSYNCH_RW_RDLOCK               = 306
-	SYS_PSYNCH_RW_WRLOCK               = 307
-	SYS_PSYNCH_RW_UNLOCK               = 308
-	SYS_PSYNCH_RW_UNLOCK2              = 309
-	SYS_GETSID                         = 310
-	SYS_SETTID_WITH_PID                = 311
-	SYS_PSYNCH_CVCLRPREPOST            = 312
-	SYS_AIO_FSYNC                      = 313
-	SYS_AIO_RETURN                     = 314
-	SYS_AIO_SUSPEND                    = 315
-	SYS_AIO_CANCEL                     = 316
-	SYS_AIO_ERROR                      = 317
-	SYS_AIO_READ                       = 318
-	SYS_AIO_WRITE                      = 319
-	SYS_LIO_LISTIO                     = 320
-	SYS_IOPOLICYSYS                    = 322
-	SYS_PROCESS_POLICY                 = 323
-	SYS_MLOCKALL                       = 324
-	SYS_MUNLOCKALL                     = 325
-	SYS_ISSETUGID                      = 327
-	SYS___PTHREAD_KILL                 = 328
-	SYS___PTHREAD_SIGMASK              = 329
-	SYS___SIGWAIT                      = 330
-	SYS___DISABLE_THREADSIGNAL         = 331
-	SYS___PTHREAD_MARKCANCEL           = 332
-	SYS___PTHREAD_CANCELED             = 333
-	SYS___SEMWAIT_SIGNAL               = 334
-	SYS_PROC_INFO                      = 336
-	SYS_SENDFILE                       = 337
-	SYS_STAT64                         = 338
-	SYS_FSTAT64                        = 339
-	SYS_LSTAT64                        = 340
-	SYS_STAT64_EXTENDED                = 341
-	SYS_LSTAT64_EXTENDED               = 342
-	SYS_FSTAT64_EXTENDED               = 343
-	SYS_GETDIRENTRIES64                = 344
-	SYS_STATFS64                       = 345
-	SYS_FSTATFS64                      = 346
-	SYS_GETFSSTAT64                    = 347
-	SYS___PTHREAD_CHDIR                = 348
-	SYS___PTHREAD_FCHDIR               = 349
-	SYS_AUDIT                          = 350
-	SYS_AUDITON                        = 351
-	SYS_GETAUID                        = 353
-	SYS_SETAUID                        = 354
-	SYS_GETAUDIT_ADDR                  = 357
-	SYS_SETAUDIT_ADDR                  = 358
-	SYS_AUDITCTL                       = 359
-	SYS_BSDTHREAD_CREATE               = 360
-	SYS_BSDTHREAD_TERMINATE            = 361
-	SYS_KQUEUE                         = 362
-	SYS_KEVENT                         = 363
-	SYS_LCHOWN                         = 364
-	SYS_BSDTHREAD_REGISTER             = 366
-	SYS_WORKQ_OPEN                     = 367
-	SYS_WORKQ_KERNRETURN               = 368
-	SYS_KEVENT64                       = 369
-	SYS___OLD_SEMWAIT_SIGNAL           = 370
-	SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL  = 371
-	SYS_THREAD_SELFID                  = 372
-	SYS_LEDGER                         = 373
-	SYS_KEVENT_QOS                     = 374
-	SYS_KEVENT_ID                      = 375
-	SYS___MAC_EXECVE                   = 380
-	SYS___MAC_SYSCALL                  = 381
-	SYS___MAC_GET_FILE                 = 382
-	SYS___MAC_SET_FILE                 = 383
-	SYS___MAC_GET_LINK                 = 384
-	SYS___MAC_SET_LINK                 = 385
-	SYS___MAC_GET_PROC                 = 386
-	SYS___MAC_SET_PROC                 = 387
-	SYS___MAC_GET_FD                   = 388
-	SYS___MAC_SET_FD                   = 389
-	SYS___MAC_GET_PID                  = 390
-	SYS_PSELECT                        = 394
-	SYS_PSELECT_NOCANCEL               = 395
-	SYS_READ_NOCANCEL                  = 396
-	SYS_WRITE_NOCANCEL                 = 397
-	SYS_OPEN_NOCANCEL                  = 398
-	SYS_CLOSE_NOCANCEL                 = 399
-	SYS_WAIT4_NOCANCEL                 = 400
-	SYS_RECVMSG_NOCANCEL               = 401
-	SYS_SENDMSG_NOCANCEL               = 402
-	SYS_RECVFROM_NOCANCEL              = 403
-	SYS_ACCEPT_NOCANCEL                = 404
-	SYS_MSYNC_NOCANCEL                 = 405
-	SYS_FCNTL_NOCANCEL                 = 406
-	SYS_SELECT_NOCANCEL                = 407
-	SYS_FSYNC_NOCANCEL                 = 408
-	SYS_CONNECT_NOCANCEL               = 409
-	SYS_SIGSUSPEND_NOCANCEL            = 410
-	SYS_READV_NOCANCEL                 = 411
-	SYS_WRITEV_NOCANCEL                = 412
-	SYS_SENDTO_NOCANCEL                = 413
-	SYS_PREAD_NOCANCEL                 = 414
-	SYS_PWRITE_NOCANCEL                = 415
-	SYS_WAITID_NOCANCEL                = 416
-	SYS_POLL_NOCANCEL                  = 417
-	SYS_MSGSND_NOCANCEL                = 418
-	SYS_MSGRCV_NOCANCEL                = 419
-	SYS_SEM_WAIT_NOCANCEL              = 420
-	SYS_AIO_SUSPEND_NOCANCEL           = 421
-	SYS___SIGWAIT_NOCANCEL             = 422
-	SYS___SEMWAIT_SIGNAL_NOCANCEL      = 423
-	SYS___MAC_MOUNT                    = 424
-	SYS___MAC_GET_MOUNT                = 425
-	SYS___MAC_GETFSSTAT                = 426
-	SYS_FSGETPATH                      = 427
-	SYS_AUDIT_SESSION_SELF             = 428
-	SYS_AUDIT_SESSION_JOIN             = 429
-	SYS_FILEPORT_MAKEPORT              = 430
-	SYS_FILEPORT_MAKEFD                = 431
-	SYS_AUDIT_SESSION_PORT             = 432
-	SYS_PID_SUSPEND                    = 433
-	SYS_PID_RESUME                     = 434
-	SYS_PID_HIBERNATE                  = 435
-	SYS_PID_SHUTDOWN_SOCKETS           = 436
-	SYS_SHARED_REGION_MAP_AND_SLIDE_NP = 438
-	SYS_KAS_INFO                       = 439
-	SYS_MEMORYSTATUS_CONTROL           = 440
-	SYS_GUARDED_OPEN_NP                = 441
-	SYS_GUARDED_CLOSE_NP               = 442
-	SYS_GUARDED_KQUEUE_NP              = 443
-	SYS_CHANGE_FDGUARD_NP              = 444
-	SYS_USRCTL                         = 445
-	SYS_PROC_RLIMIT_CONTROL            = 446
-	SYS_CONNECTX                       = 447
-	SYS_DISCONNECTX                    = 448
-	SYS_PEELOFF                        = 449
-	SYS_SOCKET_DELEGATE                = 450
-	SYS_TELEMETRY                      = 451
-	SYS_PROC_UUID_POLICY               = 452
-	SYS_MEMORYSTATUS_GET_LEVEL         = 453
-	SYS_SYSTEM_OVERRIDE                = 454
-	SYS_VFS_PURGE                      = 455
-	SYS_SFI_CTL                        = 456
-	SYS_SFI_PIDCTL                     = 457
-	SYS_COALITION                      = 458
-	SYS_COALITION_INFO                 = 459
-	SYS_NECP_MATCH_POLICY              = 460
-	SYS_GETATTRLISTBULK                = 461
-	SYS_CLONEFILEAT                    = 462
-	SYS_OPENAT                         = 463
-	SYS_OPENAT_NOCANCEL                = 464
-	SYS_RENAMEAT                       = 465
-	SYS_FACCESSAT                      = 466
-	SYS_FCHMODAT                       = 467
-	SYS_FCHOWNAT                       = 468
-	SYS_FSTATAT                        = 469
-	SYS_FSTATAT64                      = 470
-	SYS_LINKAT                         = 471
-	SYS_UNLINKAT                       = 472
-	SYS_READLINKAT                     = 473
-	SYS_SYMLINKAT                      = 474
-	SYS_MKDIRAT                        = 475
-	SYS_GETATTRLISTAT                  = 476
-	SYS_PROC_TRACE_LOG                 = 477
-	SYS_BSDTHREAD_CTL                  = 478
-	SYS_OPENBYID_NP                    = 479
-	SYS_RECVMSG_X                      = 480
-	SYS_SENDMSG_X                      = 481
-	SYS_THREAD_SELFUSAGE               = 482
-	SYS_CSRCTL                         = 483
-	SYS_GUARDED_OPEN_DPROTECTED_NP     = 484
-	SYS_GUARDED_WRITE_NP               = 485
-	SYS_GUARDED_PWRITE_NP              = 486
-	SYS_GUARDED_WRITEV_NP              = 487
-	SYS_RENAMEATX_NP                   = 488
-	SYS_MREMAP_ENCRYPTED               = 489
-	SYS_NETAGENT_TRIGGER               = 490
-	SYS_STACK_SNAPSHOT_WITH_CONFIG     = 491
-	SYS_MICROSTACKSHOT                 = 492
-	SYS_GRAB_PGO_DATA                  = 493
-	SYS_PERSONA                        = 494
-	SYS_WORK_INTERVAL_CTL              = 499
-	SYS_GETENTROPY                     = 500
-	SYS_NECP_OPEN                      = 501
-	SYS_NECP_CLIENT_ACTION             = 502
-	SYS___NEXUS_OPEN                   = 503
-	SYS___NEXUS_REGISTER               = 504
-	SYS___NEXUS_DEREGISTER             = 505
-	SYS___NEXUS_CREATE                 = 506
-	SYS___NEXUS_DESTROY                = 507
-	SYS___NEXUS_GET_OPT                = 508
-	SYS___NEXUS_SET_OPT                = 509
-	SYS___CHANNEL_OPEN                 = 510
-	SYS___CHANNEL_GET_INFO             = 511
-	SYS___CHANNEL_SYNC                 = 512
-	SYS___CHANNEL_GET_OPT              = 513
-	SYS___CHANNEL_SET_OPT              = 514
-	SYS_ULOCK_WAIT                     = 515
-	SYS_ULOCK_WAKE                     = 516
-	SYS_FCLONEFILEAT                   = 517
-	SYS_FS_SNAPSHOT                    = 518
-	SYS_TERMINATE_WITH_PAYLOAD         = 520
-	SYS_ABORT_WITH_PAYLOAD             = 521
-	SYS_NECP_SESSION_OPEN              = 522
-	SYS_NECP_SESSION_ACTION            = 523
-	SYS_SETATTRLISTAT                  = 524
-	SYS_NET_QOS_GUIDELINE              = 525
-	SYS_FMOUNT                         = 526
-	SYS_NTP_ADJTIME                    = 527
-	SYS_NTP_GETTIME                    = 528
-	SYS_OS_FAULT_WITH_PAYLOAD          = 529
-	SYS_MAXSYSCALL                     = 530
-	SYS_INVALID                        = 63
-)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go
index 527b958..5eb433b 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.1.sdk/usr/include/sys/syscall.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && darwin
 // +build arm64,darwin
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go
index 9912c6e..703675c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go https://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && dragonfly
 // +build amd64,dragonfly
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go
index 9474974..59d5dfc 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build 386 && freebsd
 // +build 386,freebsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go
index 48a7bea..342d471 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && freebsd
 // +build amd64,freebsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go
index 4a6dfd4..e2e3d72 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm && freebsd
 // +build arm,freebsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go
index 3e51af8..61ad5ca 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && freebsd
 // +build arm64,freebsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
index 0f5a3f6..fbc59b7 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include -m32 /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build 386 && linux
 // +build 386,linux
 
 package unix
@@ -435,4 +436,7 @@
 	SYS_OPENAT2                      = 437
 	SYS_PIDFD_GETFD                  = 438
 	SYS_FACCESSAT2                   = 439
+	SYS_PROCESS_MADVISE              = 440
+	SYS_EPOLL_PWAIT2                 = 441
+	SYS_MOUNT_SETATTR                = 442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
index 36d5219..04d16d7 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include -m64 /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && linux
 // +build amd64,linux
 
 package unix
@@ -357,4 +358,7 @@
 	SYS_OPENAT2                = 437
 	SYS_PIDFD_GETFD            = 438
 	SYS_FACCESSAT2             = 439
+	SYS_PROCESS_MADVISE        = 440
+	SYS_EPOLL_PWAIT2           = 441
+	SYS_MOUNT_SETATTR          = 442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
index 3622ba1..3b1c105 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm && linux
 // +build arm,linux
 
 package unix
@@ -399,4 +400,7 @@
 	SYS_OPENAT2                      = 437
 	SYS_PIDFD_GETFD                  = 438
 	SYS_FACCESSAT2                   = 439
+	SYS_PROCESS_MADVISE              = 440
+	SYS_EPOLL_PWAIT2                 = 441
+	SYS_MOUNT_SETATTR                = 442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
index 6193c3d..3198adc 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include -fsigned-char /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && linux
 // +build arm64,linux
 
 package unix
@@ -302,4 +303,7 @@
 	SYS_OPENAT2                = 437
 	SYS_PIDFD_GETFD            = 438
 	SYS_FACCESSAT2             = 439
+	SYS_PROCESS_MADVISE        = 440
+	SYS_EPOLL_PWAIT2           = 441
+	SYS_MOUNT_SETATTR          = 442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
index 640b974..c877ec6 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mips && linux
 // +build mips,linux
 
 package unix
@@ -420,4 +421,7 @@
 	SYS_OPENAT2                      = 4437
 	SYS_PIDFD_GETFD                  = 4438
 	SYS_FACCESSAT2                   = 4439
+	SYS_PROCESS_MADVISE              = 4440
+	SYS_EPOLL_PWAIT2                 = 4441
+	SYS_MOUNT_SETATTR                = 4442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
index 3467fbb..b5f2903 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mips64 && linux
 // +build mips64,linux
 
 package unix
@@ -350,4 +351,7 @@
 	SYS_OPENAT2                = 5437
 	SYS_PIDFD_GETFD            = 5438
 	SYS_FACCESSAT2             = 5439
+	SYS_PROCESS_MADVISE        = 5440
+	SYS_EPOLL_PWAIT2           = 5441
+	SYS_MOUNT_SETATTR          = 5442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
index 0fc38d5..4607768 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mips64le && linux
 // +build mips64le,linux
 
 package unix
@@ -350,4 +351,7 @@
 	SYS_OPENAT2                = 5437
 	SYS_PIDFD_GETFD            = 5438
 	SYS_FACCESSAT2             = 5439
+	SYS_PROCESS_MADVISE        = 5440
+	SYS_EPOLL_PWAIT2           = 5441
+	SYS_MOUNT_SETATTR          = 5442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
index 999fd55..80e6696 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mipsle && linux
 // +build mipsle,linux
 
 package unix
@@ -420,4 +421,7 @@
 	SYS_OPENAT2                      = 4437
 	SYS_PIDFD_GETFD                  = 4438
 	SYS_FACCESSAT2                   = 4439
+	SYS_PROCESS_MADVISE              = 4440
+	SYS_EPOLL_PWAIT2                 = 4441
+	SYS_MOUNT_SETATTR                = 4442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go
new file mode 100644
index 0000000..b9d697f
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go
@@ -0,0 +1,434 @@
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build ppc && linux
+// +build ppc,linux
+
+package unix
+
+const (
+	SYS_RESTART_SYSCALL              = 0
+	SYS_EXIT                         = 1
+	SYS_FORK                         = 2
+	SYS_READ                         = 3
+	SYS_WRITE                        = 4
+	SYS_OPEN                         = 5
+	SYS_CLOSE                        = 6
+	SYS_WAITPID                      = 7
+	SYS_CREAT                        = 8
+	SYS_LINK                         = 9
+	SYS_UNLINK                       = 10
+	SYS_EXECVE                       = 11
+	SYS_CHDIR                        = 12
+	SYS_TIME                         = 13
+	SYS_MKNOD                        = 14
+	SYS_CHMOD                        = 15
+	SYS_LCHOWN                       = 16
+	SYS_BREAK                        = 17
+	SYS_OLDSTAT                      = 18
+	SYS_LSEEK                        = 19
+	SYS_GETPID                       = 20
+	SYS_MOUNT                        = 21
+	SYS_UMOUNT                       = 22
+	SYS_SETUID                       = 23
+	SYS_GETUID                       = 24
+	SYS_STIME                        = 25
+	SYS_PTRACE                       = 26
+	SYS_ALARM                        = 27
+	SYS_OLDFSTAT                     = 28
+	SYS_PAUSE                        = 29
+	SYS_UTIME                        = 30
+	SYS_STTY                         = 31
+	SYS_GTTY                         = 32
+	SYS_ACCESS                       = 33
+	SYS_NICE                         = 34
+	SYS_FTIME                        = 35
+	SYS_SYNC                         = 36
+	SYS_KILL                         = 37
+	SYS_RENAME                       = 38
+	SYS_MKDIR                        = 39
+	SYS_RMDIR                        = 40
+	SYS_DUP                          = 41
+	SYS_PIPE                         = 42
+	SYS_TIMES                        = 43
+	SYS_PROF                         = 44
+	SYS_BRK                          = 45
+	SYS_SETGID                       = 46
+	SYS_GETGID                       = 47
+	SYS_SIGNAL                       = 48
+	SYS_GETEUID                      = 49
+	SYS_GETEGID                      = 50
+	SYS_ACCT                         = 51
+	SYS_UMOUNT2                      = 52
+	SYS_LOCK                         = 53
+	SYS_IOCTL                        = 54
+	SYS_FCNTL                        = 55
+	SYS_MPX                          = 56
+	SYS_SETPGID                      = 57
+	SYS_ULIMIT                       = 58
+	SYS_OLDOLDUNAME                  = 59
+	SYS_UMASK                        = 60
+	SYS_CHROOT                       = 61
+	SYS_USTAT                        = 62
+	SYS_DUP2                         = 63
+	SYS_GETPPID                      = 64
+	SYS_GETPGRP                      = 65
+	SYS_SETSID                       = 66
+	SYS_SIGACTION                    = 67
+	SYS_SGETMASK                     = 68
+	SYS_SSETMASK                     = 69
+	SYS_SETREUID                     = 70
+	SYS_SETREGID                     = 71
+	SYS_SIGSUSPEND                   = 72
+	SYS_SIGPENDING                   = 73
+	SYS_SETHOSTNAME                  = 74
+	SYS_SETRLIMIT                    = 75
+	SYS_GETRLIMIT                    = 76
+	SYS_GETRUSAGE                    = 77
+	SYS_GETTIMEOFDAY                 = 78
+	SYS_SETTIMEOFDAY                 = 79
+	SYS_GETGROUPS                    = 80
+	SYS_SETGROUPS                    = 81
+	SYS_SELECT                       = 82
+	SYS_SYMLINK                      = 83
+	SYS_OLDLSTAT                     = 84
+	SYS_READLINK                     = 85
+	SYS_USELIB                       = 86
+	SYS_SWAPON                       = 87
+	SYS_REBOOT                       = 88
+	SYS_READDIR                      = 89
+	SYS_MMAP                         = 90
+	SYS_MUNMAP                       = 91
+	SYS_TRUNCATE                     = 92
+	SYS_FTRUNCATE                    = 93
+	SYS_FCHMOD                       = 94
+	SYS_FCHOWN                       = 95
+	SYS_GETPRIORITY                  = 96
+	SYS_SETPRIORITY                  = 97
+	SYS_PROFIL                       = 98
+	SYS_STATFS                       = 99
+	SYS_FSTATFS                      = 100
+	SYS_IOPERM                       = 101
+	SYS_SOCKETCALL                   = 102
+	SYS_SYSLOG                       = 103
+	SYS_SETITIMER                    = 104
+	SYS_GETITIMER                    = 105
+	SYS_STAT                         = 106
+	SYS_LSTAT                        = 107
+	SYS_FSTAT                        = 108
+	SYS_OLDUNAME                     = 109
+	SYS_IOPL                         = 110
+	SYS_VHANGUP                      = 111
+	SYS_IDLE                         = 112
+	SYS_VM86                         = 113
+	SYS_WAIT4                        = 114
+	SYS_SWAPOFF                      = 115
+	SYS_SYSINFO                      = 116
+	SYS_IPC                          = 117
+	SYS_FSYNC                        = 118
+	SYS_SIGRETURN                    = 119
+	SYS_CLONE                        = 120
+	SYS_SETDOMAINNAME                = 121
+	SYS_UNAME                        = 122
+	SYS_MODIFY_LDT                   = 123
+	SYS_ADJTIMEX                     = 124
+	SYS_MPROTECT                     = 125
+	SYS_SIGPROCMASK                  = 126
+	SYS_CREATE_MODULE                = 127
+	SYS_INIT_MODULE                  = 128
+	SYS_DELETE_MODULE                = 129
+	SYS_GET_KERNEL_SYMS              = 130
+	SYS_QUOTACTL                     = 131
+	SYS_GETPGID                      = 132
+	SYS_FCHDIR                       = 133
+	SYS_BDFLUSH                      = 134
+	SYS_SYSFS                        = 135
+	SYS_PERSONALITY                  = 136
+	SYS_AFS_SYSCALL                  = 137
+	SYS_SETFSUID                     = 138
+	SYS_SETFSGID                     = 139
+	SYS__LLSEEK                      = 140
+	SYS_GETDENTS                     = 141
+	SYS__NEWSELECT                   = 142
+	SYS_FLOCK                        = 143
+	SYS_MSYNC                        = 144
+	SYS_READV                        = 145
+	SYS_WRITEV                       = 146
+	SYS_GETSID                       = 147
+	SYS_FDATASYNC                    = 148
+	SYS__SYSCTL                      = 149
+	SYS_MLOCK                        = 150
+	SYS_MUNLOCK                      = 151
+	SYS_MLOCKALL                     = 152
+	SYS_MUNLOCKALL                   = 153
+	SYS_SCHED_SETPARAM               = 154
+	SYS_SCHED_GETPARAM               = 155
+	SYS_SCHED_SETSCHEDULER           = 156
+	SYS_SCHED_GETSCHEDULER           = 157
+	SYS_SCHED_YIELD                  = 158
+	SYS_SCHED_GET_PRIORITY_MAX       = 159
+	SYS_SCHED_GET_PRIORITY_MIN       = 160
+	SYS_SCHED_RR_GET_INTERVAL        = 161
+	SYS_NANOSLEEP                    = 162
+	SYS_MREMAP                       = 163
+	SYS_SETRESUID                    = 164
+	SYS_GETRESUID                    = 165
+	SYS_QUERY_MODULE                 = 166
+	SYS_POLL                         = 167
+	SYS_NFSSERVCTL                   = 168
+	SYS_SETRESGID                    = 169
+	SYS_GETRESGID                    = 170
+	SYS_PRCTL                        = 171
+	SYS_RT_SIGRETURN                 = 172
+	SYS_RT_SIGACTION                 = 173
+	SYS_RT_SIGPROCMASK               = 174
+	SYS_RT_SIGPENDING                = 175
+	SYS_RT_SIGTIMEDWAIT              = 176
+	SYS_RT_SIGQUEUEINFO              = 177
+	SYS_RT_SIGSUSPEND                = 178
+	SYS_PREAD64                      = 179
+	SYS_PWRITE64                     = 180
+	SYS_CHOWN                        = 181
+	SYS_GETCWD                       = 182
+	SYS_CAPGET                       = 183
+	SYS_CAPSET                       = 184
+	SYS_SIGALTSTACK                  = 185
+	SYS_SENDFILE                     = 186
+	SYS_GETPMSG                      = 187
+	SYS_PUTPMSG                      = 188
+	SYS_VFORK                        = 189
+	SYS_UGETRLIMIT                   = 190
+	SYS_READAHEAD                    = 191
+	SYS_MMAP2                        = 192
+	SYS_TRUNCATE64                   = 193
+	SYS_FTRUNCATE64                  = 194
+	SYS_STAT64                       = 195
+	SYS_LSTAT64                      = 196
+	SYS_FSTAT64                      = 197
+	SYS_PCICONFIG_READ               = 198
+	SYS_PCICONFIG_WRITE              = 199
+	SYS_PCICONFIG_IOBASE             = 200
+	SYS_MULTIPLEXER                  = 201
+	SYS_GETDENTS64                   = 202
+	SYS_PIVOT_ROOT                   = 203
+	SYS_FCNTL64                      = 204
+	SYS_MADVISE                      = 205
+	SYS_MINCORE                      = 206
+	SYS_GETTID                       = 207
+	SYS_TKILL                        = 208
+	SYS_SETXATTR                     = 209
+	SYS_LSETXATTR                    = 210
+	SYS_FSETXATTR                    = 211
+	SYS_GETXATTR                     = 212
+	SYS_LGETXATTR                    = 213
+	SYS_FGETXATTR                    = 214
+	SYS_LISTXATTR                    = 215
+	SYS_LLISTXATTR                   = 216
+	SYS_FLISTXATTR                   = 217
+	SYS_REMOVEXATTR                  = 218
+	SYS_LREMOVEXATTR                 = 219
+	SYS_FREMOVEXATTR                 = 220
+	SYS_FUTEX                        = 221
+	SYS_SCHED_SETAFFINITY            = 222
+	SYS_SCHED_GETAFFINITY            = 223
+	SYS_TUXCALL                      = 225
+	SYS_SENDFILE64                   = 226
+	SYS_IO_SETUP                     = 227
+	SYS_IO_DESTROY                   = 228
+	SYS_IO_GETEVENTS                 = 229
+	SYS_IO_SUBMIT                    = 230
+	SYS_IO_CANCEL                    = 231
+	SYS_SET_TID_ADDRESS              = 232
+	SYS_FADVISE64                    = 233
+	SYS_EXIT_GROUP                   = 234
+	SYS_LOOKUP_DCOOKIE               = 235
+	SYS_EPOLL_CREATE                 = 236
+	SYS_EPOLL_CTL                    = 237
+	SYS_EPOLL_WAIT                   = 238
+	SYS_REMAP_FILE_PAGES             = 239
+	SYS_TIMER_CREATE                 = 240
+	SYS_TIMER_SETTIME                = 241
+	SYS_TIMER_GETTIME                = 242
+	SYS_TIMER_GETOVERRUN             = 243
+	SYS_TIMER_DELETE                 = 244
+	SYS_CLOCK_SETTIME                = 245
+	SYS_CLOCK_GETTIME                = 246
+	SYS_CLOCK_GETRES                 = 247
+	SYS_CLOCK_NANOSLEEP              = 248
+	SYS_SWAPCONTEXT                  = 249
+	SYS_TGKILL                       = 250
+	SYS_UTIMES                       = 251
+	SYS_STATFS64                     = 252
+	SYS_FSTATFS64                    = 253
+	SYS_FADVISE64_64                 = 254
+	SYS_RTAS                         = 255
+	SYS_SYS_DEBUG_SETCONTEXT         = 256
+	SYS_MIGRATE_PAGES                = 258
+	SYS_MBIND                        = 259
+	SYS_GET_MEMPOLICY                = 260
+	SYS_SET_MEMPOLICY                = 261
+	SYS_MQ_OPEN                      = 262
+	SYS_MQ_UNLINK                    = 263
+	SYS_MQ_TIMEDSEND                 = 264
+	SYS_MQ_TIMEDRECEIVE              = 265
+	SYS_MQ_NOTIFY                    = 266
+	SYS_MQ_GETSETATTR                = 267
+	SYS_KEXEC_LOAD                   = 268
+	SYS_ADD_KEY                      = 269
+	SYS_REQUEST_KEY                  = 270
+	SYS_KEYCTL                       = 271
+	SYS_WAITID                       = 272
+	SYS_IOPRIO_SET                   = 273
+	SYS_IOPRIO_GET                   = 274
+	SYS_INOTIFY_INIT                 = 275
+	SYS_INOTIFY_ADD_WATCH            = 276
+	SYS_INOTIFY_RM_WATCH             = 277
+	SYS_SPU_RUN                      = 278
+	SYS_SPU_CREATE                   = 279
+	SYS_PSELECT6                     = 280
+	SYS_PPOLL                        = 281
+	SYS_UNSHARE                      = 282
+	SYS_SPLICE                       = 283
+	SYS_TEE                          = 284
+	SYS_VMSPLICE                     = 285
+	SYS_OPENAT                       = 286
+	SYS_MKDIRAT                      = 287
+	SYS_MKNODAT                      = 288
+	SYS_FCHOWNAT                     = 289
+	SYS_FUTIMESAT                    = 290
+	SYS_FSTATAT64                    = 291
+	SYS_UNLINKAT                     = 292
+	SYS_RENAMEAT                     = 293
+	SYS_LINKAT                       = 294
+	SYS_SYMLINKAT                    = 295
+	SYS_READLINKAT                   = 296
+	SYS_FCHMODAT                     = 297
+	SYS_FACCESSAT                    = 298
+	SYS_GET_ROBUST_LIST              = 299
+	SYS_SET_ROBUST_LIST              = 300
+	SYS_MOVE_PAGES                   = 301
+	SYS_GETCPU                       = 302
+	SYS_EPOLL_PWAIT                  = 303
+	SYS_UTIMENSAT                    = 304
+	SYS_SIGNALFD                     = 305
+	SYS_TIMERFD_CREATE               = 306
+	SYS_EVENTFD                      = 307
+	SYS_SYNC_FILE_RANGE2             = 308
+	SYS_FALLOCATE                    = 309
+	SYS_SUBPAGE_PROT                 = 310
+	SYS_TIMERFD_SETTIME              = 311
+	SYS_TIMERFD_GETTIME              = 312
+	SYS_SIGNALFD4                    = 313
+	SYS_EVENTFD2                     = 314
+	SYS_EPOLL_CREATE1                = 315
+	SYS_DUP3                         = 316
+	SYS_PIPE2                        = 317
+	SYS_INOTIFY_INIT1                = 318
+	SYS_PERF_EVENT_OPEN              = 319
+	SYS_PREADV                       = 320
+	SYS_PWRITEV                      = 321
+	SYS_RT_TGSIGQUEUEINFO            = 322
+	SYS_FANOTIFY_INIT                = 323
+	SYS_FANOTIFY_MARK                = 324
+	SYS_PRLIMIT64                    = 325
+	SYS_SOCKET                       = 326
+	SYS_BIND                         = 327
+	SYS_CONNECT                      = 328
+	SYS_LISTEN                       = 329
+	SYS_ACCEPT                       = 330
+	SYS_GETSOCKNAME                  = 331
+	SYS_GETPEERNAME                  = 332
+	SYS_SOCKETPAIR                   = 333
+	SYS_SEND                         = 334
+	SYS_SENDTO                       = 335
+	SYS_RECV                         = 336
+	SYS_RECVFROM                     = 337
+	SYS_SHUTDOWN                     = 338
+	SYS_SETSOCKOPT                   = 339
+	SYS_GETSOCKOPT                   = 340
+	SYS_SENDMSG                      = 341
+	SYS_RECVMSG                      = 342
+	SYS_RECVMMSG                     = 343
+	SYS_ACCEPT4                      = 344
+	SYS_NAME_TO_HANDLE_AT            = 345
+	SYS_OPEN_BY_HANDLE_AT            = 346
+	SYS_CLOCK_ADJTIME                = 347
+	SYS_SYNCFS                       = 348
+	SYS_SENDMMSG                     = 349
+	SYS_SETNS                        = 350
+	SYS_PROCESS_VM_READV             = 351
+	SYS_PROCESS_VM_WRITEV            = 352
+	SYS_FINIT_MODULE                 = 353
+	SYS_KCMP                         = 354
+	SYS_SCHED_SETATTR                = 355
+	SYS_SCHED_GETATTR                = 356
+	SYS_RENAMEAT2                    = 357
+	SYS_SECCOMP                      = 358
+	SYS_GETRANDOM                    = 359
+	SYS_MEMFD_CREATE                 = 360
+	SYS_BPF                          = 361
+	SYS_EXECVEAT                     = 362
+	SYS_SWITCH_ENDIAN                = 363
+	SYS_USERFAULTFD                  = 364
+	SYS_MEMBARRIER                   = 365
+	SYS_MLOCK2                       = 378
+	SYS_COPY_FILE_RANGE              = 379
+	SYS_PREADV2                      = 380
+	SYS_PWRITEV2                     = 381
+	SYS_KEXEC_FILE_LOAD              = 382
+	SYS_STATX                        = 383
+	SYS_PKEY_ALLOC                   = 384
+	SYS_PKEY_FREE                    = 385
+	SYS_PKEY_MPROTECT                = 386
+	SYS_RSEQ                         = 387
+	SYS_IO_PGETEVENTS                = 388
+	SYS_SEMGET                       = 393
+	SYS_SEMCTL                       = 394
+	SYS_SHMGET                       = 395
+	SYS_SHMCTL                       = 396
+	SYS_SHMAT                        = 397
+	SYS_SHMDT                        = 398
+	SYS_MSGGET                       = 399
+	SYS_MSGSND                       = 400
+	SYS_MSGRCV                       = 401
+	SYS_MSGCTL                       = 402
+	SYS_CLOCK_GETTIME64              = 403
+	SYS_CLOCK_SETTIME64              = 404
+	SYS_CLOCK_ADJTIME64              = 405
+	SYS_CLOCK_GETRES_TIME64          = 406
+	SYS_CLOCK_NANOSLEEP_TIME64       = 407
+	SYS_TIMER_GETTIME64              = 408
+	SYS_TIMER_SETTIME64              = 409
+	SYS_TIMERFD_GETTIME64            = 410
+	SYS_TIMERFD_SETTIME64            = 411
+	SYS_UTIMENSAT_TIME64             = 412
+	SYS_PSELECT6_TIME64              = 413
+	SYS_PPOLL_TIME64                 = 414
+	SYS_IO_PGETEVENTS_TIME64         = 416
+	SYS_RECVMMSG_TIME64              = 417
+	SYS_MQ_TIMEDSEND_TIME64          = 418
+	SYS_MQ_TIMEDRECEIVE_TIME64       = 419
+	SYS_SEMTIMEDOP_TIME64            = 420
+	SYS_RT_SIGTIMEDWAIT_TIME64       = 421
+	SYS_FUTEX_TIME64                 = 422
+	SYS_SCHED_RR_GET_INTERVAL_TIME64 = 423
+	SYS_PIDFD_SEND_SIGNAL            = 424
+	SYS_IO_URING_SETUP               = 425
+	SYS_IO_URING_ENTER               = 426
+	SYS_IO_URING_REGISTER            = 427
+	SYS_OPEN_TREE                    = 428
+	SYS_MOVE_MOUNT                   = 429
+	SYS_FSOPEN                       = 430
+	SYS_FSCONFIG                     = 431
+	SYS_FSMOUNT                      = 432
+	SYS_FSPICK                       = 433
+	SYS_PIDFD_OPEN                   = 434
+	SYS_CLONE3                       = 435
+	SYS_CLOSE_RANGE                  = 436
+	SYS_OPENAT2                      = 437
+	SYS_PIDFD_GETFD                  = 438
+	SYS_FACCESSAT2                   = 439
+	SYS_PROCESS_MADVISE              = 440
+	SYS_EPOLL_PWAIT2                 = 441
+	SYS_MOUNT_SETATTR                = 442
+)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
index 1df0d79..08edc54 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build ppc64 && linux
 // +build ppc64,linux
 
 package unix
@@ -399,4 +400,7 @@
 	SYS_OPENAT2                = 437
 	SYS_PIDFD_GETFD            = 438
 	SYS_FACCESSAT2             = 439
+	SYS_PROCESS_MADVISE        = 440
+	SYS_EPOLL_PWAIT2           = 441
+	SYS_MOUNT_SETATTR          = 442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
index 4db39cc..33b33b0 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build ppc64le && linux
 // +build ppc64le,linux
 
 package unix
@@ -399,4 +400,7 @@
 	SYS_OPENAT2                = 437
 	SYS_PIDFD_GETFD            = 438
 	SYS_FACCESSAT2             = 439
+	SYS_PROCESS_MADVISE        = 440
+	SYS_EPOLL_PWAIT2           = 441
+	SYS_MOUNT_SETATTR          = 442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
index e692740..66c8a8e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build riscv64 && linux
 // +build riscv64,linux
 
 package unix
@@ -301,4 +302,7 @@
 	SYS_OPENAT2                = 437
 	SYS_PIDFD_GETFD            = 438
 	SYS_FACCESSAT2             = 439
+	SYS_PROCESS_MADVISE        = 440
+	SYS_EPOLL_PWAIT2           = 441
+	SYS_MOUNT_SETATTR          = 442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
index a585aec..aea5760 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include -fsigned-char /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build s390x && linux
 // +build s390x,linux
 
 package unix
@@ -364,4 +365,7 @@
 	SYS_OPENAT2                = 437
 	SYS_PIDFD_GETFD            = 438
 	SYS_FACCESSAT2             = 439
+	SYS_PROCESS_MADVISE        = 440
+	SYS_EPOLL_PWAIT2           = 441
+	SYS_MOUNT_SETATTR          = 442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
index d047e56..488ca84 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
@@ -1,6 +1,7 @@
 // go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build sparc64 && linux
 // +build sparc64,linux
 
 package unix
@@ -378,4 +379,7 @@
 	SYS_OPENAT2                = 437
 	SYS_PIDFD_GETFD            = 438
 	SYS_FACCESSAT2             = 439
+	SYS_PROCESS_MADVISE        = 440
+	SYS_EPOLL_PWAIT2           = 441
+	SYS_MOUNT_SETATTR          = 442
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go
index e66a8c9..3a6699e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build 386 && netbsd
 // +build 386,netbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go
index 42c788f..5677cd4 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && netbsd
 // +build amd64,netbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go
index 0a07571..e784cb6 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm && netbsd
 // +build arm,netbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm64.go
index 0291c09..bd4952e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm64.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build arm64 && netbsd
 // +build arm64,netbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go
index b0207d1..817edbf 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build 386 && openbsd
 // +build 386,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go
index f0dec6f..ea45361 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && openbsd
 // +build amd64,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
index 33d1dc5..467971e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm && openbsd
 // +build arm,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go
index fe2b689..32eec5e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && openbsd
 // +build arm64,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go
index 5c08d57..a37f773 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go
@@ -1,6 +1,7 @@
 // go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mips64 && openbsd
 // +build mips64,openbsd
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_zos_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_zos_s390x.go
new file mode 100644
index 0000000..073daad
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_zos_s390x.go
@@ -0,0 +1,2670 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+package unix
+
+// TODO: auto-generate.
+
+const (
+	SYS_ACOSD128                        = 0xB80
+	SYS_ACOSD32                         = 0xB7E
+	SYS_ACOSD64                         = 0xB7F
+	SYS_ACOSHD128                       = 0xB83
+	SYS_ACOSHD32                        = 0xB81
+	SYS_ACOSHD64                        = 0xB82
+	SYS_AIO_FSYNC                       = 0xC69
+	SYS_ASCTIME                         = 0x0AE
+	SYS_ASCTIME64                       = 0xCD7
+	SYS_ASCTIME64_R                     = 0xCD8
+	SYS_ASIND128                        = 0xB86
+	SYS_ASIND32                         = 0xB84
+	SYS_ASIND64                         = 0xB85
+	SYS_ASINHD128                       = 0xB89
+	SYS_ASINHD32                        = 0xB87
+	SYS_ASINHD64                        = 0xB88
+	SYS_ATAN2D128                       = 0xB8F
+	SYS_ATAN2D32                        = 0xB8D
+	SYS_ATAN2D64                        = 0xB8E
+	SYS_ATAND128                        = 0xB8C
+	SYS_ATAND32                         = 0xB8A
+	SYS_ATAND64                         = 0xB8B
+	SYS_ATANHD128                       = 0xB92
+	SYS_ATANHD32                        = 0xB90
+	SYS_ATANHD64                        = 0xB91
+	SYS_BIND2ADDRSEL                    = 0xD59
+	SYS_C16RTOMB                        = 0xD40
+	SYS_C32RTOMB                        = 0xD41
+	SYS_CBRTD128                        = 0xB95
+	SYS_CBRTD32                         = 0xB93
+	SYS_CBRTD64                         = 0xB94
+	SYS_CEILD128                        = 0xB98
+	SYS_CEILD32                         = 0xB96
+	SYS_CEILD64                         = 0xB97
+	SYS_CLEARENV                        = 0x0C9
+	SYS_CLEARERR_UNLOCKED               = 0xCA1
+	SYS_CLOCK                           = 0x0AA
+	SYS_CLOGL                           = 0xA00
+	SYS_CLRMEMF                         = 0x0BD
+	SYS_CONJ                            = 0xA03
+	SYS_CONJF                           = 0xA06
+	SYS_CONJL                           = 0xA09
+	SYS_COPYSIGND128                    = 0xB9E
+	SYS_COPYSIGND32                     = 0xB9C
+	SYS_COPYSIGND64                     = 0xB9D
+	SYS_COSD128                         = 0xBA1
+	SYS_COSD32                          = 0xB9F
+	SYS_COSD64                          = 0xBA0
+	SYS_COSHD128                        = 0xBA4
+	SYS_COSHD32                         = 0xBA2
+	SYS_COSHD64                         = 0xBA3
+	SYS_CPOW                            = 0xA0C
+	SYS_CPOWF                           = 0xA0F
+	SYS_CPOWL                           = 0xA12
+	SYS_CPROJ                           = 0xA15
+	SYS_CPROJF                          = 0xA18
+	SYS_CPROJL                          = 0xA1B
+	SYS_CREAL                           = 0xA1E
+	SYS_CREALF                          = 0xA21
+	SYS_CREALL                          = 0xA24
+	SYS_CSIN                            = 0xA27
+	SYS_CSINF                           = 0xA2A
+	SYS_CSINH                           = 0xA30
+	SYS_CSINHF                          = 0xA33
+	SYS_CSINHL                          = 0xA36
+	SYS_CSINL                           = 0xA2D
+	SYS_CSNAP                           = 0x0C5
+	SYS_CSQRT                           = 0xA39
+	SYS_CSQRTF                          = 0xA3C
+	SYS_CSQRTL                          = 0xA3F
+	SYS_CTAN                            = 0xA42
+	SYS_CTANF                           = 0xA45
+	SYS_CTANH                           = 0xA4B
+	SYS_CTANHF                          = 0xA4E
+	SYS_CTANHL                          = 0xA51
+	SYS_CTANL                           = 0xA48
+	SYS_CTIME                           = 0x0AB
+	SYS_CTIME64                         = 0xCD9
+	SYS_CTIME64_R                       = 0xCDA
+	SYS_CTRACE                          = 0x0C6
+	SYS_DIFFTIME                        = 0x0A7
+	SYS_DIFFTIME64                      = 0xCDB
+	SYS_DLADDR                          = 0xC82
+	SYS_DYNALLOC                        = 0x0C3
+	SYS_DYNFREE                         = 0x0C2
+	SYS_ERFCD128                        = 0xBAA
+	SYS_ERFCD32                         = 0xBA8
+	SYS_ERFCD64                         = 0xBA9
+	SYS_ERFD128                         = 0xBA7
+	SYS_ERFD32                          = 0xBA5
+	SYS_ERFD64                          = 0xBA6
+	SYS_EXP2D128                        = 0xBB0
+	SYS_EXP2D32                         = 0xBAE
+	SYS_EXP2D64                         = 0xBAF
+	SYS_EXPD128                         = 0xBAD
+	SYS_EXPD32                          = 0xBAB
+	SYS_EXPD64                          = 0xBAC
+	SYS_EXPM1D128                       = 0xBB3
+	SYS_EXPM1D32                        = 0xBB1
+	SYS_EXPM1D64                        = 0xBB2
+	SYS_FABSD128                        = 0xBB6
+	SYS_FABSD32                         = 0xBB4
+	SYS_FABSD64                         = 0xBB5
+	SYS_FDELREC_UNLOCKED                = 0xCA2
+	SYS_FDIMD128                        = 0xBB9
+	SYS_FDIMD32                         = 0xBB7
+	SYS_FDIMD64                         = 0xBB8
+	SYS_FDOPEN_UNLOCKED                 = 0xCFC
+	SYS_FECLEAREXCEPT                   = 0xAEA
+	SYS_FEGETENV                        = 0xAEB
+	SYS_FEGETEXCEPTFLAG                 = 0xAEC
+	SYS_FEGETROUND                      = 0xAED
+	SYS_FEHOLDEXCEPT                    = 0xAEE
+	SYS_FEOF_UNLOCKED                   = 0xCA3
+	SYS_FERAISEEXCEPT                   = 0xAEF
+	SYS_FERROR_UNLOCKED                 = 0xCA4
+	SYS_FESETENV                        = 0xAF0
+	SYS_FESETEXCEPTFLAG                 = 0xAF1
+	SYS_FESETROUND                      = 0xAF2
+	SYS_FETCHEP                         = 0x0BF
+	SYS_FETESTEXCEPT                    = 0xAF3
+	SYS_FEUPDATEENV                     = 0xAF4
+	SYS_FE_DEC_GETROUND                 = 0xBBA
+	SYS_FE_DEC_SETROUND                 = 0xBBB
+	SYS_FFLUSH_UNLOCKED                 = 0xCA5
+	SYS_FGETC_UNLOCKED                  = 0xC80
+	SYS_FGETPOS64                       = 0xCEE
+	SYS_FGETPOS64_UNLOCKED              = 0xCF4
+	SYS_FGETPOS_UNLOCKED                = 0xCA6
+	SYS_FGETS_UNLOCKED                  = 0xC7C
+	SYS_FGETWC_UNLOCKED                 = 0xCA7
+	SYS_FGETWS_UNLOCKED                 = 0xCA8
+	SYS_FILENO_UNLOCKED                 = 0xCA9
+	SYS_FLDATA                          = 0x0C1
+	SYS_FLDATA_UNLOCKED                 = 0xCAA
+	SYS_FLOCATE_UNLOCKED                = 0xCAB
+	SYS_FLOORD128                       = 0xBBE
+	SYS_FLOORD32                        = 0xBBC
+	SYS_FLOORD64                        = 0xBBD
+	SYS_FMA                             = 0xA63
+	SYS_FMAD128                         = 0xBC1
+	SYS_FMAD32                          = 0xBBF
+	SYS_FMAD64                          = 0xBC0
+	SYS_FMAF                            = 0xA66
+	SYS_FMAL                            = 0xA69
+	SYS_FMAX                            = 0xA6C
+	SYS_FMAXD128                        = 0xBC4
+	SYS_FMAXD32                         = 0xBC2
+	SYS_FMAXD64                         = 0xBC3
+	SYS_FMAXF                           = 0xA6F
+	SYS_FMAXL                           = 0xA72
+	SYS_FMIN                            = 0xA75
+	SYS_FMIND128                        = 0xBC7
+	SYS_FMIND32                         = 0xBC5
+	SYS_FMIND64                         = 0xBC6
+	SYS_FMINF                           = 0xA78
+	SYS_FMINL                           = 0xA7B
+	SYS_FMODD128                        = 0xBCA
+	SYS_FMODD32                         = 0xBC8
+	SYS_FMODD64                         = 0xBC9
+	SYS_FOPEN64                         = 0xD49
+	SYS_FOPEN64_UNLOCKED                = 0xD4A
+	SYS_FOPEN_UNLOCKED                  = 0xCFA
+	SYS_FPRINTF_UNLOCKED                = 0xCAC
+	SYS_FPUTC_UNLOCKED                  = 0xC81
+	SYS_FPUTS_UNLOCKED                  = 0xC7E
+	SYS_FPUTWC_UNLOCKED                 = 0xCAD
+	SYS_FPUTWS_UNLOCKED                 = 0xCAE
+	SYS_FREAD_NOUPDATE                  = 0xCEC
+	SYS_FREAD_NOUPDATE_UNLOCKED         = 0xCED
+	SYS_FREAD_UNLOCKED                  = 0xC7B
+	SYS_FREEIFADDRS                     = 0xCE6
+	SYS_FREOPEN64                       = 0xD4B
+	SYS_FREOPEN64_UNLOCKED              = 0xD4C
+	SYS_FREOPEN_UNLOCKED                = 0xCFB
+	SYS_FREXPD128                       = 0xBCE
+	SYS_FREXPD32                        = 0xBCC
+	SYS_FREXPD64                        = 0xBCD
+	SYS_FSCANF_UNLOCKED                 = 0xCAF
+	SYS_FSEEK64                         = 0xCEF
+	SYS_FSEEK64_UNLOCKED                = 0xCF5
+	SYS_FSEEKO64                        = 0xCF0
+	SYS_FSEEKO64_UNLOCKED               = 0xCF6
+	SYS_FSEEKO_UNLOCKED                 = 0xCB1
+	SYS_FSEEK_UNLOCKED                  = 0xCB0
+	SYS_FSETPOS64                       = 0xCF1
+	SYS_FSETPOS64_UNLOCKED              = 0xCF7
+	SYS_FSETPOS_UNLOCKED                = 0xCB3
+	SYS_FTELL64                         = 0xCF2
+	SYS_FTELL64_UNLOCKED                = 0xCF8
+	SYS_FTELLO64                        = 0xCF3
+	SYS_FTELLO64_UNLOCKED               = 0xCF9
+	SYS_FTELLO_UNLOCKED                 = 0xCB5
+	SYS_FTELL_UNLOCKED                  = 0xCB4
+	SYS_FUPDATE                         = 0x0B5
+	SYS_FUPDATE_UNLOCKED                = 0xCB7
+	SYS_FWIDE_UNLOCKED                  = 0xCB8
+	SYS_FWPRINTF_UNLOCKED               = 0xCB9
+	SYS_FWRITE_UNLOCKED                 = 0xC7A
+	SYS_FWSCANF_UNLOCKED                = 0xCBA
+	SYS_GETDATE64                       = 0xD4F
+	SYS_GETIFADDRS                      = 0xCE7
+	SYS_GETIPV4SOURCEFILTER             = 0xC77
+	SYS_GETSOURCEFILTER                 = 0xC79
+	SYS_GETSYNTX                        = 0x0FD
+	SYS_GETS_UNLOCKED                   = 0xC7D
+	SYS_GETTIMEOFDAY64                  = 0xD50
+	SYS_GETWCHAR_UNLOCKED               = 0xCBC
+	SYS_GETWC_UNLOCKED                  = 0xCBB
+	SYS_GMTIME                          = 0x0B0
+	SYS_GMTIME64                        = 0xCDC
+	SYS_GMTIME64_R                      = 0xCDD
+	SYS_HYPOTD128                       = 0xBD1
+	SYS_HYPOTD32                        = 0xBCF
+	SYS_HYPOTD64                        = 0xBD0
+	SYS_ILOGBD128                       = 0xBD4
+	SYS_ILOGBD32                        = 0xBD2
+	SYS_ILOGBD64                        = 0xBD3
+	SYS_ILOGBF                          = 0xA7E
+	SYS_ILOGBL                          = 0xA81
+	SYS_INET6_IS_SRCADDR                = 0xD5A
+	SYS_ISBLANK                         = 0x0FE
+	SYS_ISWALNUM                        = 0x0FF
+	SYS_LDEXPD128                       = 0xBD7
+	SYS_LDEXPD32                        = 0xBD5
+	SYS_LDEXPD64                        = 0xBD6
+	SYS_LGAMMAD128                      = 0xBDA
+	SYS_LGAMMAD32                       = 0xBD8
+	SYS_LGAMMAD64                       = 0xBD9
+	SYS_LIO_LISTIO                      = 0xC6A
+	SYS_LLRINT                          = 0xA84
+	SYS_LLRINTD128                      = 0xBDD
+	SYS_LLRINTD32                       = 0xBDB
+	SYS_LLRINTD64                       = 0xBDC
+	SYS_LLRINTF                         = 0xA87
+	SYS_LLRINTL                         = 0xA8A
+	SYS_LLROUND                         = 0xA8D
+	SYS_LLROUNDD128                     = 0xBE0
+	SYS_LLROUNDD32                      = 0xBDE
+	SYS_LLROUNDD64                      = 0xBDF
+	SYS_LLROUNDF                        = 0xA90
+	SYS_LLROUNDL                        = 0xA93
+	SYS_LOCALTIM                        = 0x0B1
+	SYS_LOCALTIME                       = 0x0B1
+	SYS_LOCALTIME64                     = 0xCDE
+	SYS_LOCALTIME64_R                   = 0xCDF
+	SYS_LOG10D128                       = 0xBE6
+	SYS_LOG10D32                        = 0xBE4
+	SYS_LOG10D64                        = 0xBE5
+	SYS_LOG1PD128                       = 0xBE9
+	SYS_LOG1PD32                        = 0xBE7
+	SYS_LOG1PD64                        = 0xBE8
+	SYS_LOG2D128                        = 0xBEC
+	SYS_LOG2D32                         = 0xBEA
+	SYS_LOG2D64                         = 0xBEB
+	SYS_LOGBD128                        = 0xBEF
+	SYS_LOGBD32                         = 0xBED
+	SYS_LOGBD64                         = 0xBEE
+	SYS_LOGBF                           = 0xA96
+	SYS_LOGBL                           = 0xA99
+	SYS_LOGD128                         = 0xBE3
+	SYS_LOGD32                          = 0xBE1
+	SYS_LOGD64                          = 0xBE2
+	SYS_LRINT                           = 0xA9C
+	SYS_LRINTD128                       = 0xBF2
+	SYS_LRINTD32                        = 0xBF0
+	SYS_LRINTD64                        = 0xBF1
+	SYS_LRINTF                          = 0xA9F
+	SYS_LRINTL                          = 0xAA2
+	SYS_LROUNDD128                      = 0xBF5
+	SYS_LROUNDD32                       = 0xBF3
+	SYS_LROUNDD64                       = 0xBF4
+	SYS_LROUNDL                         = 0xAA5
+	SYS_MBLEN                           = 0x0AF
+	SYS_MBRTOC16                        = 0xD42
+	SYS_MBRTOC32                        = 0xD43
+	SYS_MEMSET                          = 0x0A3
+	SYS_MKTIME                          = 0x0AC
+	SYS_MKTIME64                        = 0xCE0
+	SYS_MODFD128                        = 0xBF8
+	SYS_MODFD32                         = 0xBF6
+	SYS_MODFD64                         = 0xBF7
+	SYS_NAN                             = 0xAA8
+	SYS_NAND128                         = 0xBFB
+	SYS_NAND32                          = 0xBF9
+	SYS_NAND64                          = 0xBFA
+	SYS_NANF                            = 0xAAA
+	SYS_NANL                            = 0xAAC
+	SYS_NEARBYINT                       = 0xAAE
+	SYS_NEARBYINTD128                   = 0xBFE
+	SYS_NEARBYINTD32                    = 0xBFC
+	SYS_NEARBYINTD64                    = 0xBFD
+	SYS_NEARBYINTF                      = 0xAB1
+	SYS_NEARBYINTL                      = 0xAB4
+	SYS_NEXTAFTERD128                   = 0xC01
+	SYS_NEXTAFTERD32                    = 0xBFF
+	SYS_NEXTAFTERD64                    = 0xC00
+	SYS_NEXTAFTERF                      = 0xAB7
+	SYS_NEXTAFTERL                      = 0xABA
+	SYS_NEXTTOWARD                      = 0xABD
+	SYS_NEXTTOWARDD128                  = 0xC04
+	SYS_NEXTTOWARDD32                   = 0xC02
+	SYS_NEXTTOWARDD64                   = 0xC03
+	SYS_NEXTTOWARDF                     = 0xAC0
+	SYS_NEXTTOWARDL                     = 0xAC3
+	SYS_NL_LANGINFO                     = 0x0FC
+	SYS_PERROR_UNLOCKED                 = 0xCBD
+	SYS_POSIX_FALLOCATE                 = 0xCE8
+	SYS_POSIX_MEMALIGN                  = 0xCE9
+	SYS_POSIX_OPENPT                    = 0xC66
+	SYS_POWD128                         = 0xC07
+	SYS_POWD32                          = 0xC05
+	SYS_POWD64                          = 0xC06
+	SYS_PRINTF_UNLOCKED                 = 0xCBE
+	SYS_PSELECT                         = 0xC67
+	SYS_PTHREAD_ATTR_GETSTACK           = 0xB3E
+	SYS_PTHREAD_ATTR_SETSTACK           = 0xB3F
+	SYS_PTHREAD_SECURITY_APPLID_NP      = 0xCE4
+	SYS_PUTS_UNLOCKED                   = 0xC7F
+	SYS_PUTWCHAR_UNLOCKED               = 0xCC0
+	SYS_PUTWC_UNLOCKED                  = 0xCBF
+	SYS_QUANTEXPD128                    = 0xD46
+	SYS_QUANTEXPD32                     = 0xD44
+	SYS_QUANTEXPD64                     = 0xD45
+	SYS_QUANTIZED128                    = 0xC0A
+	SYS_QUANTIZED32                     = 0xC08
+	SYS_QUANTIZED64                     = 0xC09
+	SYS_REMAINDERD128                   = 0xC0D
+	SYS_REMAINDERD32                    = 0xC0B
+	SYS_REMAINDERD64                    = 0xC0C
+	SYS_RESIZE_ALLOC                    = 0xCEB
+	SYS_REWIND_UNLOCKED                 = 0xCC1
+	SYS_RINTD128                        = 0xC13
+	SYS_RINTD32                         = 0xC11
+	SYS_RINTD64                         = 0xC12
+	SYS_RINTF                           = 0xACB
+	SYS_RINTL                           = 0xACD
+	SYS_ROUND                           = 0xACF
+	SYS_ROUNDD128                       = 0xC16
+	SYS_ROUNDD32                        = 0xC14
+	SYS_ROUNDD64                        = 0xC15
+	SYS_ROUNDF                          = 0xAD2
+	SYS_ROUNDL                          = 0xAD5
+	SYS_SAMEQUANTUMD128                 = 0xC19
+	SYS_SAMEQUANTUMD32                  = 0xC17
+	SYS_SAMEQUANTUMD64                  = 0xC18
+	SYS_SCALBLN                         = 0xAD8
+	SYS_SCALBLND128                     = 0xC1C
+	SYS_SCALBLND32                      = 0xC1A
+	SYS_SCALBLND64                      = 0xC1B
+	SYS_SCALBLNF                        = 0xADB
+	SYS_SCALBLNL                        = 0xADE
+	SYS_SCALBND128                      = 0xC1F
+	SYS_SCALBND32                       = 0xC1D
+	SYS_SCALBND64                       = 0xC1E
+	SYS_SCALBNF                         = 0xAE3
+	SYS_SCALBNL                         = 0xAE6
+	SYS_SCANF_UNLOCKED                  = 0xCC2
+	SYS_SCHED_YIELD                     = 0xB32
+	SYS_SETENV                          = 0x0C8
+	SYS_SETIPV4SOURCEFILTER             = 0xC76
+	SYS_SETSOURCEFILTER                 = 0xC78
+	SYS_SHM_OPEN                        = 0xC8C
+	SYS_SHM_UNLINK                      = 0xC8D
+	SYS_SIND128                         = 0xC22
+	SYS_SIND32                          = 0xC20
+	SYS_SIND64                          = 0xC21
+	SYS_SINHD128                        = 0xC25
+	SYS_SINHD32                         = 0xC23
+	SYS_SINHD64                         = 0xC24
+	SYS_SIZEOF_ALLOC                    = 0xCEA
+	SYS_SOCKATMARK                      = 0xC68
+	SYS_SQRTD128                        = 0xC28
+	SYS_SQRTD32                         = 0xC26
+	SYS_SQRTD64                         = 0xC27
+	SYS_STRCHR                          = 0x0A0
+	SYS_STRCSPN                         = 0x0A1
+	SYS_STRERROR                        = 0x0A8
+	SYS_STRERROR_R                      = 0xB33
+	SYS_STRFTIME                        = 0x0B2
+	SYS_STRLEN                          = 0x0A9
+	SYS_STRPBRK                         = 0x0A2
+	SYS_STRSPN                          = 0x0A4
+	SYS_STRSTR                          = 0x0A5
+	SYS_STRTOD128                       = 0xC2B
+	SYS_STRTOD32                        = 0xC29
+	SYS_STRTOD64                        = 0xC2A
+	SYS_STRTOK                          = 0x0A6
+	SYS_TAND128                         = 0xC2E
+	SYS_TAND32                          = 0xC2C
+	SYS_TAND64                          = 0xC2D
+	SYS_TANHD128                        = 0xC31
+	SYS_TANHD32                         = 0xC2F
+	SYS_TANHD64                         = 0xC30
+	SYS_TGAMMAD128                      = 0xC34
+	SYS_TGAMMAD32                       = 0xC32
+	SYS_TGAMMAD64                       = 0xC33
+	SYS_TIME                            = 0x0AD
+	SYS_TIME64                          = 0xCE1
+	SYS_TMPFILE64                       = 0xD4D
+	SYS_TMPFILE64_UNLOCKED              = 0xD4E
+	SYS_TMPFILE_UNLOCKED                = 0xCFD
+	SYS_TRUNCD128                       = 0xC40
+	SYS_TRUNCD32                        = 0xC3E
+	SYS_TRUNCD64                        = 0xC3F
+	SYS_UNGETC_UNLOCKED                 = 0xCC3
+	SYS_UNGETWC_UNLOCKED                = 0xCC4
+	SYS_UNSETENV                        = 0xB34
+	SYS_VFPRINTF_UNLOCKED               = 0xCC5
+	SYS_VFSCANF_UNLOCKED                = 0xCC7
+	SYS_VFWPRINTF_UNLOCKED              = 0xCC9
+	SYS_VFWSCANF_UNLOCKED               = 0xCCB
+	SYS_VPRINTF_UNLOCKED                = 0xCCD
+	SYS_VSCANF_UNLOCKED                 = 0xCCF
+	SYS_VWPRINTF_UNLOCKED               = 0xCD1
+	SYS_VWSCANF_UNLOCKED                = 0xCD3
+	SYS_WCSTOD128                       = 0xC43
+	SYS_WCSTOD32                        = 0xC41
+	SYS_WCSTOD64                        = 0xC42
+	SYS_WPRINTF_UNLOCKED                = 0xCD5
+	SYS_WSCANF_UNLOCKED                 = 0xCD6
+	SYS__FLUSHLBF                       = 0xD68
+	SYS__FLUSHLBF_UNLOCKED              = 0xD6F
+	SYS___ACOSHF_H                      = 0xA54
+	SYS___ACOSHL_H                      = 0xA55
+	SYS___ASINHF_H                      = 0xA56
+	SYS___ASINHL_H                      = 0xA57
+	SYS___ATANPID128                    = 0xC6D
+	SYS___ATANPID32                     = 0xC6B
+	SYS___ATANPID64                     = 0xC6C
+	SYS___CBRTF_H                       = 0xA58
+	SYS___CBRTL_H                       = 0xA59
+	SYS___CDUMP                         = 0x0C4
+	SYS___CLASS                         = 0xAFA
+	SYS___CLASS2                        = 0xB99
+	SYS___CLASS2D128                    = 0xC99
+	SYS___CLASS2D32                     = 0xC97
+	SYS___CLASS2D64                     = 0xC98
+	SYS___CLASS2F                       = 0xC91
+	SYS___CLASS2F_B                     = 0xC93
+	SYS___CLASS2F_H                     = 0xC94
+	SYS___CLASS2L                       = 0xC92
+	SYS___CLASS2L_B                     = 0xC95
+	SYS___CLASS2L_H                     = 0xC96
+	SYS___CLASS2_B                      = 0xB9A
+	SYS___CLASS2_H                      = 0xB9B
+	SYS___CLASS_B                       = 0xAFB
+	SYS___CLASS_H                       = 0xAFC
+	SYS___CLOGL_B                       = 0xA01
+	SYS___CLOGL_H                       = 0xA02
+	SYS___CLRENV                        = 0x0C9
+	SYS___CLRMF                         = 0x0BD
+	SYS___CODEPAGE_INFO                 = 0xC64
+	SYS___CONJF_B                       = 0xA07
+	SYS___CONJF_H                       = 0xA08
+	SYS___CONJL_B                       = 0xA0A
+	SYS___CONJL_H                       = 0xA0B
+	SYS___CONJ_B                        = 0xA04
+	SYS___CONJ_H                        = 0xA05
+	SYS___COPYSIGN_B                    = 0xA5A
+	SYS___COPYSIGN_H                    = 0xAF5
+	SYS___COSPID128                     = 0xC70
+	SYS___COSPID32                      = 0xC6E
+	SYS___COSPID64                      = 0xC6F
+	SYS___CPOWF_B                       = 0xA10
+	SYS___CPOWF_H                       = 0xA11
+	SYS___CPOWL_B                       = 0xA13
+	SYS___CPOWL_H                       = 0xA14
+	SYS___CPOW_B                        = 0xA0D
+	SYS___CPOW_H                        = 0xA0E
+	SYS___CPROJF_B                      = 0xA19
+	SYS___CPROJF_H                      = 0xA1A
+	SYS___CPROJL_B                      = 0xA1C
+	SYS___CPROJL_H                      = 0xA1D
+	SYS___CPROJ_B                       = 0xA16
+	SYS___CPROJ_H                       = 0xA17
+	SYS___CREALF_B                      = 0xA22
+	SYS___CREALF_H                      = 0xA23
+	SYS___CREALL_B                      = 0xA25
+	SYS___CREALL_H                      = 0xA26
+	SYS___CREAL_B                       = 0xA1F
+	SYS___CREAL_H                       = 0xA20
+	SYS___CSINF_B                       = 0xA2B
+	SYS___CSINF_H                       = 0xA2C
+	SYS___CSINHF_B                      = 0xA34
+	SYS___CSINHF_H                      = 0xA35
+	SYS___CSINHL_B                      = 0xA37
+	SYS___CSINHL_H                      = 0xA38
+	SYS___CSINH_B                       = 0xA31
+	SYS___CSINH_H                       = 0xA32
+	SYS___CSINL_B                       = 0xA2E
+	SYS___CSINL_H                       = 0xA2F
+	SYS___CSIN_B                        = 0xA28
+	SYS___CSIN_H                        = 0xA29
+	SYS___CSNAP                         = 0x0C5
+	SYS___CSQRTF_B                      = 0xA3D
+	SYS___CSQRTF_H                      = 0xA3E
+	SYS___CSQRTL_B                      = 0xA40
+	SYS___CSQRTL_H                      = 0xA41
+	SYS___CSQRT_B                       = 0xA3A
+	SYS___CSQRT_H                       = 0xA3B
+	SYS___CTANF_B                       = 0xA46
+	SYS___CTANF_H                       = 0xA47
+	SYS___CTANHF_B                      = 0xA4F
+	SYS___CTANHF_H                      = 0xA50
+	SYS___CTANHL_B                      = 0xA52
+	SYS___CTANHL_H                      = 0xA53
+	SYS___CTANH_B                       = 0xA4C
+	SYS___CTANH_H                       = 0xA4D
+	SYS___CTANL_B                       = 0xA49
+	SYS___CTANL_H                       = 0xA4A
+	SYS___CTAN_B                        = 0xA43
+	SYS___CTAN_H                        = 0xA44
+	SYS___CTEST                         = 0x0C7
+	SYS___CTRACE                        = 0x0C6
+	SYS___D1TOP                         = 0xC9B
+	SYS___D2TOP                         = 0xC9C
+	SYS___D4TOP                         = 0xC9D
+	SYS___DYNALL                        = 0x0C3
+	SYS___DYNFRE                        = 0x0C2
+	SYS___EXP2F_H                       = 0xA5E
+	SYS___EXP2L_H                       = 0xA5F
+	SYS___EXP2_H                        = 0xA5D
+	SYS___EXPM1F_H                      = 0xA5B
+	SYS___EXPM1L_H                      = 0xA5C
+	SYS___FBUFSIZE                      = 0xD60
+	SYS___FLBF                          = 0xD62
+	SYS___FLDATA                        = 0x0C1
+	SYS___FMAF_B                        = 0xA67
+	SYS___FMAF_H                        = 0xA68
+	SYS___FMAL_B                        = 0xA6A
+	SYS___FMAL_H                        = 0xA6B
+	SYS___FMAXF_B                       = 0xA70
+	SYS___FMAXF_H                       = 0xA71
+	SYS___FMAXL_B                       = 0xA73
+	SYS___FMAXL_H                       = 0xA74
+	SYS___FMAX_B                        = 0xA6D
+	SYS___FMAX_H                        = 0xA6E
+	SYS___FMA_B                         = 0xA64
+	SYS___FMA_H                         = 0xA65
+	SYS___FMINF_B                       = 0xA79
+	SYS___FMINF_H                       = 0xA7A
+	SYS___FMINL_B                       = 0xA7C
+	SYS___FMINL_H                       = 0xA7D
+	SYS___FMIN_B                        = 0xA76
+	SYS___FMIN_H                        = 0xA77
+	SYS___FPENDING                      = 0xD61
+	SYS___FPENDING_UNLOCKED             = 0xD6C
+	SYS___FPURGE                        = 0xD69
+	SYS___FPURGE_UNLOCKED               = 0xD70
+	SYS___FP_CAST_D                     = 0xBCB
+	SYS___FREADABLE                     = 0xD63
+	SYS___FREADAHEAD                    = 0xD6A
+	SYS___FREADAHEAD_UNLOCKED           = 0xD71
+	SYS___FREADING                      = 0xD65
+	SYS___FREADING_UNLOCKED             = 0xD6D
+	SYS___FSEEK2                        = 0xB3C
+	SYS___FSETERR                       = 0xD6B
+	SYS___FSETLOCKING                   = 0xD67
+	SYS___FTCHEP                        = 0x0BF
+	SYS___FTELL2                        = 0xB3B
+	SYS___FUPDT                         = 0x0B5
+	SYS___FWRITABLE                     = 0xD64
+	SYS___FWRITING                      = 0xD66
+	SYS___FWRITING_UNLOCKED             = 0xD6E
+	SYS___GETCB                         = 0x0B4
+	SYS___GETGRGID1                     = 0xD5B
+	SYS___GETGRNAM1                     = 0xD5C
+	SYS___GETTHENT                      = 0xCE5
+	SYS___GETTOD                        = 0xD3E
+	SYS___HYPOTF_H                      = 0xAF6
+	SYS___HYPOTL_H                      = 0xAF7
+	SYS___ILOGBF_B                      = 0xA7F
+	SYS___ILOGBF_H                      = 0xA80
+	SYS___ILOGBL_B                      = 0xA82
+	SYS___ILOGBL_H                      = 0xA83
+	SYS___ISBLANK_A                     = 0xB2E
+	SYS___ISBLNK                        = 0x0FE
+	SYS___ISWBLANK_A                    = 0xB2F
+	SYS___LE_CEEGTJS                    = 0xD72
+	SYS___LE_TRACEBACK                  = 0xB7A
+	SYS___LGAMMAL_H                     = 0xA62
+	SYS___LGAMMA_B_C99                  = 0xB39
+	SYS___LGAMMA_H_C99                  = 0xB38
+	SYS___LGAMMA_R_C99                  = 0xB3A
+	SYS___LLRINTF_B                     = 0xA88
+	SYS___LLRINTF_H                     = 0xA89
+	SYS___LLRINTL_B                     = 0xA8B
+	SYS___LLRINTL_H                     = 0xA8C
+	SYS___LLRINT_B                      = 0xA85
+	SYS___LLRINT_H                      = 0xA86
+	SYS___LLROUNDF_B                    = 0xA91
+	SYS___LLROUNDF_H                    = 0xA92
+	SYS___LLROUNDL_B                    = 0xA94
+	SYS___LLROUNDL_H                    = 0xA95
+	SYS___LLROUND_B                     = 0xA8E
+	SYS___LLROUND_H                     = 0xA8F
+	SYS___LOCALE_CTL                    = 0xD47
+	SYS___LOG1PF_H                      = 0xA60
+	SYS___LOG1PL_H                      = 0xA61
+	SYS___LOGBF_B                       = 0xA97
+	SYS___LOGBF_H                       = 0xA98
+	SYS___LOGBL_B                       = 0xA9A
+	SYS___LOGBL_H                       = 0xA9B
+	SYS___LOGIN_APPLID                  = 0xCE2
+	SYS___LRINTF_B                      = 0xAA0
+	SYS___LRINTF_H                      = 0xAA1
+	SYS___LRINTL_B                      = 0xAA3
+	SYS___LRINTL_H                      = 0xAA4
+	SYS___LRINT_B                       = 0xA9D
+	SYS___LRINT_H                       = 0xA9E
+	SYS___LROUNDF_FIXUP                 = 0xB31
+	SYS___LROUNDL_B                     = 0xAA6
+	SYS___LROUNDL_H                     = 0xAA7
+	SYS___LROUND_FIXUP                  = 0xB30
+	SYS___MOSERVICES                    = 0xD3D
+	SYS___MUST_STAY_CLEAN               = 0xB7C
+	SYS___NANF_B                        = 0xAAB
+	SYS___NANL_B                        = 0xAAD
+	SYS___NAN_B                         = 0xAA9
+	SYS___NEARBYINTF_B                  = 0xAB2
+	SYS___NEARBYINTF_H                  = 0xAB3
+	SYS___NEARBYINTL_B                  = 0xAB5
+	SYS___NEARBYINTL_H                  = 0xAB6
+	SYS___NEARBYINT_B                   = 0xAAF
+	SYS___NEARBYINT_H                   = 0xAB0
+	SYS___NEXTAFTERF_B                  = 0xAB8
+	SYS___NEXTAFTERF_H                  = 0xAB9
+	SYS___NEXTAFTERL_B                  = 0xABB
+	SYS___NEXTAFTERL_H                  = 0xABC
+	SYS___NEXTTOWARDF_B                 = 0xAC1
+	SYS___NEXTTOWARDF_H                 = 0xAC2
+	SYS___NEXTTOWARDL_B                 = 0xAC4
+	SYS___NEXTTOWARDL_H                 = 0xAC5
+	SYS___NEXTTOWARD_B                  = 0xABE
+	SYS___NEXTTOWARD_H                  = 0xABF
+	SYS___O_ENV                         = 0xB7D
+	SYS___PASSWD_APPLID                 = 0xCE3
+	SYS___PTOD1                         = 0xC9E
+	SYS___PTOD2                         = 0xC9F
+	SYS___PTOD4                         = 0xCA0
+	SYS___REGCOMP_STD                   = 0x0EA
+	SYS___REMAINDERF_H                  = 0xAC6
+	SYS___REMAINDERL_H                  = 0xAC7
+	SYS___REMQUOD128                    = 0xC10
+	SYS___REMQUOD32                     = 0xC0E
+	SYS___REMQUOD64                     = 0xC0F
+	SYS___REMQUOF_H                     = 0xAC9
+	SYS___REMQUOL_H                     = 0xACA
+	SYS___REMQUO_H                      = 0xAC8
+	SYS___RINTF_B                       = 0xACC
+	SYS___RINTL_B                       = 0xACE
+	SYS___ROUNDF_B                      = 0xAD3
+	SYS___ROUNDF_H                      = 0xAD4
+	SYS___ROUNDL_B                      = 0xAD6
+	SYS___ROUNDL_H                      = 0xAD7
+	SYS___ROUND_B                       = 0xAD0
+	SYS___ROUND_H                       = 0xAD1
+	SYS___SCALBLNF_B                    = 0xADC
+	SYS___SCALBLNF_H                    = 0xADD
+	SYS___SCALBLNL_B                    = 0xADF
+	SYS___SCALBLNL_H                    = 0xAE0
+	SYS___SCALBLN_B                     = 0xAD9
+	SYS___SCALBLN_H                     = 0xADA
+	SYS___SCALBNF_B                     = 0xAE4
+	SYS___SCALBNF_H                     = 0xAE5
+	SYS___SCALBNL_B                     = 0xAE7
+	SYS___SCALBNL_H                     = 0xAE8
+	SYS___SCALBN_B                      = 0xAE1
+	SYS___SCALBN_H                      = 0xAE2
+	SYS___SETENV                        = 0x0C8
+	SYS___SINPID128                     = 0xC73
+	SYS___SINPID32                      = 0xC71
+	SYS___SINPID64                      = 0xC72
+	SYS___SMF_RECORD2                   = 0xD48
+	SYS___STATIC_REINIT                 = 0xB3D
+	SYS___TGAMMAF_H_C99                 = 0xB79
+	SYS___TGAMMAL_H                     = 0xAE9
+	SYS___TGAMMA_H_C99                  = 0xB78
+	SYS___TOCSNAME2                     = 0xC9A
+	SYS_CEIL                            = 0x01F
+	SYS_CHAUDIT                         = 0x1E0
+	SYS_EXP                             = 0x01A
+	SYS_FCHAUDIT                        = 0x1E1
+	SYS_FREXP                           = 0x01D
+	SYS_GETGROUPSBYNAME                 = 0x1E2
+	SYS_GETPWUID                        = 0x1A0
+	SYS_GETUID                          = 0x1A1
+	SYS_ISATTY                          = 0x1A3
+	SYS_KILL                            = 0x1A4
+	SYS_LDEXP                           = 0x01E
+	SYS_LINK                            = 0x1A5
+	SYS_LOG10                           = 0x01C
+	SYS_LSEEK                           = 0x1A6
+	SYS_LSTAT                           = 0x1A7
+	SYS_MKDIR                           = 0x1A8
+	SYS_MKFIFO                          = 0x1A9
+	SYS_MKNOD                           = 0x1AA
+	SYS_MODF                            = 0x01B
+	SYS_MOUNT                           = 0x1AB
+	SYS_OPEN                            = 0x1AC
+	SYS_OPENDIR                         = 0x1AD
+	SYS_PATHCONF                        = 0x1AE
+	SYS_PAUSE                           = 0x1AF
+	SYS_PIPE                            = 0x1B0
+	SYS_PTHREAD_ATTR_DESTROY            = 0x1E7
+	SYS_PTHREAD_ATTR_GETDETACHSTATE     = 0x1EB
+	SYS_PTHREAD_ATTR_GETSTACKSIZE       = 0x1E9
+	SYS_PTHREAD_ATTR_GETWEIGHT_NP       = 0x1ED
+	SYS_PTHREAD_ATTR_INIT               = 0x1E6
+	SYS_PTHREAD_ATTR_SETDETACHSTATE     = 0x1EA
+	SYS_PTHREAD_ATTR_SETSTACKSIZE       = 0x1E8
+	SYS_PTHREAD_ATTR_SETWEIGHT_NP       = 0x1EC
+	SYS_PTHREAD_CANCEL                  = 0x1EE
+	SYS_PTHREAD_CLEANUP_POP             = 0x1F0
+	SYS_PTHREAD_CLEANUP_PUSH            = 0x1EF
+	SYS_PTHREAD_CONDATTR_DESTROY        = 0x1F2
+	SYS_PTHREAD_CONDATTR_INIT           = 0x1F1
+	SYS_PTHREAD_COND_BROADCAST          = 0x1F6
+	SYS_PTHREAD_COND_DESTROY            = 0x1F4
+	SYS_PTHREAD_COND_INIT               = 0x1F3
+	SYS_PTHREAD_COND_SIGNAL             = 0x1F5
+	SYS_PTHREAD_COND_TIMEDWAIT          = 0x1F8
+	SYS_PTHREAD_COND_WAIT               = 0x1F7
+	SYS_PTHREAD_CREATE                  = 0x1F9
+	SYS_PTHREAD_DETACH                  = 0x1FA
+	SYS_PTHREAD_EQUAL                   = 0x1FB
+	SYS_PTHREAD_EXIT                    = 0x1E4
+	SYS_PTHREAD_GETSPECIFIC             = 0x1FC
+	SYS_PTHREAD_JOIN                    = 0x1FD
+	SYS_PTHREAD_KEY_CREATE              = 0x1FE
+	SYS_PTHREAD_KILL                    = 0x1E5
+	SYS_PTHREAD_MUTEXATTR_INIT          = 0x1FF
+	SYS_READ                            = 0x1B2
+	SYS_READDIR                         = 0x1B3
+	SYS_READLINK                        = 0x1B4
+	SYS_REWINDDIR                       = 0x1B5
+	SYS_RMDIR                           = 0x1B6
+	SYS_SETEGID                         = 0x1B7
+	SYS_SETEUID                         = 0x1B8
+	SYS_SETGID                          = 0x1B9
+	SYS_SETPGID                         = 0x1BA
+	SYS_SETSID                          = 0x1BB
+	SYS_SETUID                          = 0x1BC
+	SYS_SIGACTION                       = 0x1BD
+	SYS_SIGADDSET                       = 0x1BE
+	SYS_SIGDELSET                       = 0x1BF
+	SYS_SIGEMPTYSET                     = 0x1C0
+	SYS_SIGFILLSET                      = 0x1C1
+	SYS_SIGISMEMBER                     = 0x1C2
+	SYS_SIGLONGJMP                      = 0x1C3
+	SYS_SIGPENDING                      = 0x1C4
+	SYS_SIGPROCMASK                     = 0x1C5
+	SYS_SIGSETJMP                       = 0x1C6
+	SYS_SIGSUSPEND                      = 0x1C7
+	SYS_SIGWAIT                         = 0x1E3
+	SYS_SLEEP                           = 0x1C8
+	SYS_STAT                            = 0x1C9
+	SYS_SYMLINK                         = 0x1CB
+	SYS_SYSCONF                         = 0x1CC
+	SYS_TCDRAIN                         = 0x1CD
+	SYS_TCFLOW                          = 0x1CE
+	SYS_TCFLUSH                         = 0x1CF
+	SYS_TCGETATTR                       = 0x1D0
+	SYS_TCGETPGRP                       = 0x1D1
+	SYS_TCSENDBREAK                     = 0x1D2
+	SYS_TCSETATTR                       = 0x1D3
+	SYS_TCSETPGRP                       = 0x1D4
+	SYS_TIMES                           = 0x1D5
+	SYS_TTYNAME                         = 0x1D6
+	SYS_TZSET                           = 0x1D7
+	SYS_UMASK                           = 0x1D8
+	SYS_UMOUNT                          = 0x1D9
+	SYS_UNAME                           = 0x1DA
+	SYS_UNLINK                          = 0x1DB
+	SYS_UTIME                           = 0x1DC
+	SYS_WAIT                            = 0x1DD
+	SYS_WAITPID                         = 0x1DE
+	SYS_WRITE                           = 0x1DF
+	SYS_W_GETPSENT                      = 0x1B1
+	SYS_W_IOCTL                         = 0x1A2
+	SYS_W_STATFS                        = 0x1CA
+	SYS_A64L                            = 0x2EF
+	SYS_BCMP                            = 0x2B9
+	SYS_BCOPY                           = 0x2BA
+	SYS_BZERO                           = 0x2BB
+	SYS_CATCLOSE                        = 0x2B6
+	SYS_CATGETS                         = 0x2B7
+	SYS_CATOPEN                         = 0x2B8
+	SYS_CRYPT                           = 0x2AC
+	SYS_DBM_CLEARERR                    = 0x2F7
+	SYS_DBM_CLOSE                       = 0x2F8
+	SYS_DBM_DELETE                      = 0x2F9
+	SYS_DBM_ERROR                       = 0x2FA
+	SYS_DBM_FETCH                       = 0x2FB
+	SYS_DBM_FIRSTKEY                    = 0x2FC
+	SYS_DBM_NEXTKEY                     = 0x2FD
+	SYS_DBM_OPEN                        = 0x2FE
+	SYS_DBM_STORE                       = 0x2FF
+	SYS_DRAND48                         = 0x2B2
+	SYS_ENCRYPT                         = 0x2AD
+	SYS_ENDUTXENT                       = 0x2E1
+	SYS_ERAND48                         = 0x2B3
+	SYS_ERF                             = 0x02C
+	SYS_ERFC                            = 0x02D
+	SYS_FCHDIR                          = 0x2D9
+	SYS_FFS                             = 0x2BC
+	SYS_FMTMSG                          = 0x2E5
+	SYS_FSTATVFS                        = 0x2B4
+	SYS_FTIME                           = 0x2F5
+	SYS_GAMMA                           = 0x02E
+	SYS_GETDATE                         = 0x2A6
+	SYS_GETPAGESIZE                     = 0x2D8
+	SYS_GETTIMEOFDAY                    = 0x2F6
+	SYS_GETUTXENT                       = 0x2E0
+	SYS_GETUTXID                        = 0x2E2
+	SYS_GETUTXLINE                      = 0x2E3
+	SYS_HCREATE                         = 0x2C6
+	SYS_HDESTROY                        = 0x2C7
+	SYS_HSEARCH                         = 0x2C8
+	SYS_HYPOT                           = 0x02B
+	SYS_INDEX                           = 0x2BD
+	SYS_INITSTATE                       = 0x2C2
+	SYS_INSQUE                          = 0x2CF
+	SYS_ISASCII                         = 0x2ED
+	SYS_JRAND48                         = 0x2E6
+	SYS_L64A                            = 0x2F0
+	SYS_LCONG48                         = 0x2EA
+	SYS_LFIND                           = 0x2C9
+	SYS_LRAND48                         = 0x2E7
+	SYS_LSEARCH                         = 0x2CA
+	SYS_MEMCCPY                         = 0x2D4
+	SYS_MRAND48                         = 0x2E8
+	SYS_NRAND48                         = 0x2E9
+	SYS_PCLOSE                          = 0x2D2
+	SYS_POPEN                           = 0x2D1
+	SYS_PUTUTXLINE                      = 0x2E4
+	SYS_RANDOM                          = 0x2C4
+	SYS_REMQUE                          = 0x2D0
+	SYS_RINDEX                          = 0x2BE
+	SYS_SEED48                          = 0x2EC
+	SYS_SETKEY                          = 0x2AE
+	SYS_SETSTATE                        = 0x2C3
+	SYS_SETUTXENT                       = 0x2DF
+	SYS_SRAND48                         = 0x2EB
+	SYS_SRANDOM                         = 0x2C5
+	SYS_STATVFS                         = 0x2B5
+	SYS_STRCASECMP                      = 0x2BF
+	SYS_STRDUP                          = 0x2C0
+	SYS_STRNCASECMP                     = 0x2C1
+	SYS_SWAB                            = 0x2D3
+	SYS_TDELETE                         = 0x2CB
+	SYS_TFIND                           = 0x2CC
+	SYS_TOASCII                         = 0x2EE
+	SYS_TSEARCH                         = 0x2CD
+	SYS_TWALK                           = 0x2CE
+	SYS_UALARM                          = 0x2F1
+	SYS_USLEEP                          = 0x2F2
+	SYS_WAIT3                           = 0x2A7
+	SYS_WAITID                          = 0x2A8
+	SYS_Y1                              = 0x02A
+	SYS___ATOE                          = 0x2DB
+	SYS___ATOE_L                        = 0x2DC
+	SYS___CATTRM                        = 0x2A9
+	SYS___CNVBLK                        = 0x2AF
+	SYS___CRYTRM                        = 0x2B0
+	SYS___DLGHT                         = 0x2A1
+	SYS___ECRTRM                        = 0x2B1
+	SYS___ETOA                          = 0x2DD
+	SYS___ETOA_L                        = 0x2DE
+	SYS___GDTRM                         = 0x2AA
+	SYS___OCLCK                         = 0x2DA
+	SYS___OPARGF                        = 0x2A2
+	SYS___OPERRF                        = 0x2A5
+	SYS___OPINDF                        = 0x2A4
+	SYS___OPOPTF                        = 0x2A3
+	SYS___RNDTRM                        = 0x2AB
+	SYS___SRCTRM                        = 0x2F4
+	SYS___TZONE                         = 0x2A0
+	SYS___UTXTRM                        = 0x2F3
+	SYS_ASIN                            = 0x03E
+	SYS_ISXDIGIT                        = 0x03B
+	SYS_SETLOCAL                        = 0x03A
+	SYS_SETLOCALE                       = 0x03A
+	SYS_SIN                             = 0x03F
+	SYS_TOLOWER                         = 0x03C
+	SYS_TOUPPER                         = 0x03D
+	SYS_ACCEPT_AND_RECV                 = 0x4F7
+	SYS_ATOL                            = 0x04E
+	SYS_CHECKSCH                        = 0x4BC
+	SYS_CHECKSCHENV                     = 0x4BC
+	SYS_CLEARERR                        = 0x04C
+	SYS_CONNECTS                        = 0x4B5
+	SYS_CONNECTSERVER                   = 0x4B5
+	SYS_CONNECTW                        = 0x4B4
+	SYS_CONNECTWORKMGR                  = 0x4B4
+	SYS_CONTINUE                        = 0x4B3
+	SYS_CONTINUEWORKUNIT                = 0x4B3
+	SYS_COPYSIGN                        = 0x4C2
+	SYS_CREATEWO                        = 0x4B2
+	SYS_CREATEWORKUNIT                  = 0x4B2
+	SYS_DELETEWO                        = 0x4B9
+	SYS_DELETEWORKUNIT                  = 0x4B9
+	SYS_DISCONNE                        = 0x4B6
+	SYS_DISCONNECTSERVER                = 0x4B6
+	SYS_FEOF                            = 0x04D
+	SYS_FERROR                          = 0x04A
+	SYS_FINITE                          = 0x4C8
+	SYS_GAMMA_R                         = 0x4E2
+	SYS_JOINWORK                        = 0x4B7
+	SYS_JOINWORKUNIT                    = 0x4B7
+	SYS_LEAVEWOR                        = 0x4B8
+	SYS_LEAVEWORKUNIT                   = 0x4B8
+	SYS_LGAMMA_R                        = 0x4EB
+	SYS_MATHERR                         = 0x4D0
+	SYS_PERROR                          = 0x04F
+	SYS_QUERYMET                        = 0x4BA
+	SYS_QUERYMETRICS                    = 0x4BA
+	SYS_QUERYSCH                        = 0x4BB
+	SYS_QUERYSCHENV                     = 0x4BB
+	SYS_REWIND                          = 0x04B
+	SYS_SCALBN                          = 0x4D4
+	SYS_SIGNIFIC                        = 0x4D5
+	SYS_SIGNIFICAND                     = 0x4D5
+	SYS___ACOSH_B                       = 0x4DA
+	SYS___ACOS_B                        = 0x4D9
+	SYS___ASINH_B                       = 0x4BE
+	SYS___ASIN_B                        = 0x4DB
+	SYS___ATAN2_B                       = 0x4DC
+	SYS___ATANH_B                       = 0x4DD
+	SYS___ATAN_B                        = 0x4BF
+	SYS___CBRT_B                        = 0x4C0
+	SYS___CEIL_B                        = 0x4C1
+	SYS___COSH_B                        = 0x4DE
+	SYS___COS_B                         = 0x4C3
+	SYS___DGHT                          = 0x4A8
+	SYS___ENVN                          = 0x4B0
+	SYS___ERFC_B                        = 0x4C5
+	SYS___ERF_B                         = 0x4C4
+	SYS___EXPM1_B                       = 0x4C6
+	SYS___EXP_B                         = 0x4DF
+	SYS___FABS_B                        = 0x4C7
+	SYS___FLOOR_B                       = 0x4C9
+	SYS___FMOD_B                        = 0x4E0
+	SYS___FP_SETMODE                    = 0x4F8
+	SYS___FREXP_B                       = 0x4CA
+	SYS___GAMMA_B                       = 0x4E1
+	SYS___GDRR                          = 0x4A1
+	SYS___HRRNO                         = 0x4A2
+	SYS___HYPOT_B                       = 0x4E3
+	SYS___ILOGB_B                       = 0x4CB
+	SYS___ISNAN_B                       = 0x4CC
+	SYS___J0_B                          = 0x4E4
+	SYS___J1_B                          = 0x4E6
+	SYS___JN_B                          = 0x4E8
+	SYS___LDEXP_B                       = 0x4CD
+	SYS___LGAMMA_B                      = 0x4EA
+	SYS___LOG10_B                       = 0x4ED
+	SYS___LOG1P_B                       = 0x4CE
+	SYS___LOGB_B                        = 0x4CF
+	SYS___LOGIN                         = 0x4F5
+	SYS___LOG_B                         = 0x4EC
+	SYS___MLOCKALL                      = 0x4B1
+	SYS___MODF_B                        = 0x4D1
+	SYS___NEXTAFTER_B                   = 0x4D2
+	SYS___OPENDIR2                      = 0x4F3
+	SYS___OPEN_STAT                     = 0x4F6
+	SYS___OPND                          = 0x4A5
+	SYS___OPPT                          = 0x4A6
+	SYS___OPRG                          = 0x4A3
+	SYS___OPRR                          = 0x4A4
+	SYS___PID_AFFINITY                  = 0x4BD
+	SYS___POW_B                         = 0x4EE
+	SYS___READDIR2                      = 0x4F4
+	SYS___REMAINDER_B                   = 0x4EF
+	SYS___RINT_B                        = 0x4D3
+	SYS___SCALB_B                       = 0x4F0
+	SYS___SIGACTIONSET                  = 0x4FB
+	SYS___SIGGM                         = 0x4A7
+	SYS___SINH_B                        = 0x4F1
+	SYS___SIN_B                         = 0x4D6
+	SYS___SQRT_B                        = 0x4F2
+	SYS___TANH_B                        = 0x4D8
+	SYS___TAN_B                         = 0x4D7
+	SYS___TRRNO                         = 0x4AF
+	SYS___TZNE                          = 0x4A9
+	SYS___TZZN                          = 0x4AA
+	SYS___UCREATE                       = 0x4FC
+	SYS___UFREE                         = 0x4FE
+	SYS___UHEAPREPORT                   = 0x4FF
+	SYS___UMALLOC                       = 0x4FD
+	SYS___Y0_B                          = 0x4E5
+	SYS___Y1_B                          = 0x4E7
+	SYS___YN_B                          = 0x4E9
+	SYS_ABORT                           = 0x05C
+	SYS_ASCTIME_R                       = 0x5E0
+	SYS_ATEXIT                          = 0x05D
+	SYS_CONNECTE                        = 0x5AE
+	SYS_CONNECTEXPORTIMPORT             = 0x5AE
+	SYS_CTIME_R                         = 0x5E1
+	SYS_DN_COMP                         = 0x5DF
+	SYS_DN_EXPAND                       = 0x5DD
+	SYS_DN_SKIPNAME                     = 0x5DE
+	SYS_EXIT                            = 0x05A
+	SYS_EXPORTWO                        = 0x5A1
+	SYS_EXPORTWORKUNIT                  = 0x5A1
+	SYS_EXTRACTW                        = 0x5A5
+	SYS_EXTRACTWORKUNIT                 = 0x5A5
+	SYS_FSEEKO                          = 0x5C9
+	SYS_FTELLO                          = 0x5C8
+	SYS_GETGRGID_R                      = 0x5E7
+	SYS_GETGRNAM_R                      = 0x5E8
+	SYS_GETLOGIN_R                      = 0x5E9
+	SYS_GETPWNAM_R                      = 0x5EA
+	SYS_GETPWUID_R                      = 0x5EB
+	SYS_GMTIME_R                        = 0x5E2
+	SYS_IMPORTWO                        = 0x5A3
+	SYS_IMPORTWORKUNIT                  = 0x5A3
+	SYS_INET_NTOP                       = 0x5D3
+	SYS_INET_PTON                       = 0x5D4
+	SYS_LLABS                           = 0x5CE
+	SYS_LLDIV                           = 0x5CB
+	SYS_LOCALTIME_R                     = 0x5E3
+	SYS_PTHREAD_ATFORK                  = 0x5ED
+	SYS_PTHREAD_ATTR_GETDETACHSTATE_U98 = 0x5FB
+	SYS_PTHREAD_ATTR_GETGUARDSIZE       = 0x5EE
+	SYS_PTHREAD_ATTR_GETSCHEDPARAM      = 0x5F9
+	SYS_PTHREAD_ATTR_GETSTACKADDR       = 0x5EF
+	SYS_PTHREAD_ATTR_SETDETACHSTATE_U98 = 0x5FC
+	SYS_PTHREAD_ATTR_SETGUARDSIZE       = 0x5F0
+	SYS_PTHREAD_ATTR_SETSCHEDPARAM      = 0x5FA
+	SYS_PTHREAD_ATTR_SETSTACKADDR       = 0x5F1
+	SYS_PTHREAD_CONDATTR_GETPSHARED     = 0x5F2
+	SYS_PTHREAD_CONDATTR_SETPSHARED     = 0x5F3
+	SYS_PTHREAD_DETACH_U98              = 0x5FD
+	SYS_PTHREAD_GETCONCURRENCY          = 0x5F4
+	SYS_PTHREAD_GETSPECIFIC_U98         = 0x5FE
+	SYS_PTHREAD_KEY_DELETE              = 0x5F5
+	SYS_PTHREAD_SETCANCELSTATE          = 0x5FF
+	SYS_PTHREAD_SETCONCURRENCY          = 0x5F6
+	SYS_PTHREAD_SIGMASK                 = 0x5F7
+	SYS_QUERYENC                        = 0x5AD
+	SYS_QUERYWORKUNITCLASSIFICATION     = 0x5AD
+	SYS_RAISE                           = 0x05E
+	SYS_RAND_R                          = 0x5E4
+	SYS_READDIR_R                       = 0x5E6
+	SYS_REALLOC                         = 0x05B
+	SYS_RES_INIT                        = 0x5D8
+	SYS_RES_MKQUERY                     = 0x5D7
+	SYS_RES_QUERY                       = 0x5D9
+	SYS_RES_QUERYDOMAIN                 = 0x5DC
+	SYS_RES_SEARCH                      = 0x5DA
+	SYS_RES_SEND                        = 0x5DB
+	SYS_SETJMP                          = 0x05F
+	SYS_SIGQUEUE                        = 0x5A9
+	SYS_STRTOK_R                        = 0x5E5
+	SYS_STRTOLL                         = 0x5B0
+	SYS_STRTOULL                        = 0x5B1
+	SYS_TTYNAME_R                       = 0x5EC
+	SYS_UNDOEXPO                        = 0x5A2
+	SYS_UNDOEXPORTWORKUNIT              = 0x5A2
+	SYS_UNDOIMPO                        = 0x5A4
+	SYS_UNDOIMPORTWORKUNIT              = 0x5A4
+	SYS_WCSTOLL                         = 0x5CC
+	SYS_WCSTOULL                        = 0x5CD
+	SYS___ABORT                         = 0x05C
+	SYS___CONSOLE2                      = 0x5D2
+	SYS___CPL                           = 0x5A6
+	SYS___DISCARDDATA                   = 0x5F8
+	SYS___DSA_PREV                      = 0x5B2
+	SYS___EP_FIND                       = 0x5B3
+	SYS___FP_SWAPMODE                   = 0x5AF
+	SYS___GETUSERID                     = 0x5AB
+	SYS___GET_CPUID                     = 0x5B9
+	SYS___GET_SYSTEM_SETTINGS           = 0x5BA
+	SYS___IPDOMAINNAME                  = 0x5AC
+	SYS___MAP_INIT                      = 0x5A7
+	SYS___MAP_SERVICE                   = 0x5A8
+	SYS___MOUNT                         = 0x5AA
+	SYS___MSGRCV_TIMED                  = 0x5B7
+	SYS___RES                           = 0x5D6
+	SYS___SEMOP_TIMED                   = 0x5B8
+	SYS___SERVER_THREADS_QUERY          = 0x5B4
+	SYS_FPRINTF                         = 0x06D
+	SYS_FSCANF                          = 0x06A
+	SYS_PRINTF                          = 0x06F
+	SYS_SETBUF                          = 0x06B
+	SYS_SETVBUF                         = 0x06C
+	SYS_SSCANF                          = 0x06E
+	SYS___CATGETS_A                     = 0x6C0
+	SYS___CHAUDIT_A                     = 0x6F4
+	SYS___CHMOD_A                       = 0x6E8
+	SYS___COLLATE_INIT_A                = 0x6AC
+	SYS___CREAT_A                       = 0x6F6
+	SYS___CTYPE_INIT_A                  = 0x6AF
+	SYS___DLLLOAD_A                     = 0x6DF
+	SYS___DLLQUERYFN_A                  = 0x6E0
+	SYS___DLLQUERYVAR_A                 = 0x6E1
+	SYS___E2A_L                         = 0x6E3
+	SYS___EXECLE_A                      = 0x6A0
+	SYS___EXECLP_A                      = 0x6A4
+	SYS___EXECVE_A                      = 0x6C1
+	SYS___EXECVP_A                      = 0x6C2
+	SYS___EXECV_A                       = 0x6B1
+	SYS___FPRINTF_A                     = 0x6FA
+	SYS___GETADDRINFO_A                 = 0x6BF
+	SYS___GETNAMEINFO_A                 = 0x6C4
+	SYS___GET_WCTYPE_STD_A              = 0x6AE
+	SYS___ICONV_OPEN_A                  = 0x6DE
+	SYS___IF_INDEXTONAME_A              = 0x6DC
+	SYS___IF_NAMETOINDEX_A              = 0x6DB
+	SYS___ISWCTYPE_A                    = 0x6B0
+	SYS___IS_WCTYPE_STD_A               = 0x6B2
+	SYS___LOCALECONV_A                  = 0x6B8
+	SYS___LOCALECONV_STD_A              = 0x6B9
+	SYS___LOCALE_INIT_A                 = 0x6B7
+	SYS___LSTAT_A                       = 0x6EE
+	SYS___LSTAT_O_A                     = 0x6EF
+	SYS___MKDIR_A                       = 0x6E9
+	SYS___MKFIFO_A                      = 0x6EC
+	SYS___MKNOD_A                       = 0x6F0
+	SYS___MONETARY_INIT_A               = 0x6BC
+	SYS___MOUNT_A                       = 0x6F1
+	SYS___NL_CSINFO_A                   = 0x6D6
+	SYS___NL_LANGINFO_A                 = 0x6BA
+	SYS___NL_LNAGINFO_STD_A             = 0x6BB
+	SYS___NL_MONINFO_A                  = 0x6D7
+	SYS___NL_NUMINFO_A                  = 0x6D8
+	SYS___NL_RESPINFO_A                 = 0x6D9
+	SYS___NL_TIMINFO_A                  = 0x6DA
+	SYS___NUMERIC_INIT_A                = 0x6C6
+	SYS___OPEN_A                        = 0x6F7
+	SYS___PRINTF_A                      = 0x6DD
+	SYS___RESP_INIT_A                   = 0x6C7
+	SYS___RPMATCH_A                     = 0x6C8
+	SYS___RPMATCH_C_A                   = 0x6C9
+	SYS___RPMATCH_STD_A                 = 0x6CA
+	SYS___SETLOCALE_A                   = 0x6F9
+	SYS___SPAWNP_A                      = 0x6C5
+	SYS___SPAWN_A                       = 0x6C3
+	SYS___SPRINTF_A                     = 0x6FB
+	SYS___STAT_A                        = 0x6EA
+	SYS___STAT_O_A                      = 0x6EB
+	SYS___STRCOLL_STD_A                 = 0x6A1
+	SYS___STRFMON_A                     = 0x6BD
+	SYS___STRFMON_STD_A                 = 0x6BE
+	SYS___STRFTIME_A                    = 0x6CC
+	SYS___STRFTIME_STD_A                = 0x6CD
+	SYS___STRPTIME_A                    = 0x6CE
+	SYS___STRPTIME_STD_A                = 0x6CF
+	SYS___STRXFRM_A                     = 0x6A2
+	SYS___STRXFRM_C_A                   = 0x6A3
+	SYS___STRXFRM_STD_A                 = 0x6A5
+	SYS___SYNTAX_INIT_A                 = 0x6D4
+	SYS___TIME_INIT_A                   = 0x6CB
+	SYS___TOD_INIT_A                    = 0x6D5
+	SYS___TOWLOWER_A                    = 0x6B3
+	SYS___TOWLOWER_STD_A                = 0x6B4
+	SYS___TOWUPPER_A                    = 0x6B5
+	SYS___TOWUPPER_STD_A                = 0x6B6
+	SYS___UMOUNT_A                      = 0x6F2
+	SYS___VFPRINTF_A                    = 0x6FC
+	SYS___VPRINTF_A                     = 0x6FD
+	SYS___VSPRINTF_A                    = 0x6FE
+	SYS___VSWPRINTF_A                   = 0x6FF
+	SYS___WCSCOLL_A                     = 0x6A6
+	SYS___WCSCOLL_C_A                   = 0x6A7
+	SYS___WCSCOLL_STD_A                 = 0x6A8
+	SYS___WCSFTIME_A                    = 0x6D0
+	SYS___WCSFTIME_STD_A                = 0x6D1
+	SYS___WCSXFRM_A                     = 0x6A9
+	SYS___WCSXFRM_C_A                   = 0x6AA
+	SYS___WCSXFRM_STD_A                 = 0x6AB
+	SYS___WCTYPE_A                      = 0x6AD
+	SYS___W_GETMNTENT_A                 = 0x6F5
+	SYS_____CCSIDTYPE_A                 = 0x6E6
+	SYS_____CHATTR_A                    = 0x6E2
+	SYS_____CSNAMETYPE_A                = 0x6E7
+	SYS_____OPEN_STAT_A                 = 0x6ED
+	SYS_____SPAWN2_A                    = 0x6D2
+	SYS_____SPAWNP2_A                   = 0x6D3
+	SYS_____TOCCSID_A                   = 0x6E4
+	SYS_____TOCSNAME_A                  = 0x6E5
+	SYS_ACL_FREE                        = 0x7FF
+	SYS_ACL_INIT                        = 0x7FE
+	SYS_FWIDE                           = 0x7DF
+	SYS_FWPRINTF                        = 0x7D1
+	SYS_FWRITE                          = 0x07E
+	SYS_FWSCANF                         = 0x7D5
+	SYS_GETCHAR                         = 0x07B
+	SYS_GETS                            = 0x07C
+	SYS_M_CREATE_LAYOUT                 = 0x7C9
+	SYS_M_DESTROY_LAYOUT                = 0x7CA
+	SYS_M_GETVALUES_LAYOUT              = 0x7CB
+	SYS_M_SETVALUES_LAYOUT              = 0x7CC
+	SYS_M_TRANSFORM_LAYOUT              = 0x7CD
+	SYS_M_WTRANSFORM_LAYOUT             = 0x7CE
+	SYS_PREAD                           = 0x7C7
+	SYS_PUTC                            = 0x07D
+	SYS_PUTCHAR                         = 0x07A
+	SYS_PUTS                            = 0x07F
+	SYS_PWRITE                          = 0x7C8
+	SYS_TOWCTRAN                        = 0x7D8
+	SYS_TOWCTRANS                       = 0x7D8
+	SYS_UNATEXIT                        = 0x7B5
+	SYS_VFWPRINT                        = 0x7D3
+	SYS_VFWPRINTF                       = 0x7D3
+	SYS_VWPRINTF                        = 0x7D4
+	SYS_WCTRANS                         = 0x7D7
+	SYS_WPRINTF                         = 0x7D2
+	SYS_WSCANF                          = 0x7D6
+	SYS___ASCTIME_R_A                   = 0x7A1
+	SYS___BASENAME_A                    = 0x7DC
+	SYS___BTOWC_A                       = 0x7E4
+	SYS___CDUMP_A                       = 0x7B7
+	SYS___CEE3DMP_A                     = 0x7B6
+	SYS___CEILF_H                       = 0x7F4
+	SYS___CEILL_H                       = 0x7F5
+	SYS___CEIL_H                        = 0x7EA
+	SYS___CRYPT_A                       = 0x7BE
+	SYS___CSNAP_A                       = 0x7B8
+	SYS___CTEST_A                       = 0x7B9
+	SYS___CTIME_R_A                     = 0x7A2
+	SYS___CTRACE_A                      = 0x7BA
+	SYS___DBM_OPEN_A                    = 0x7E6
+	SYS___DIRNAME_A                     = 0x7DD
+	SYS___FABSF_H                       = 0x7FA
+	SYS___FABSL_H                       = 0x7FB
+	SYS___FABS_H                        = 0x7ED
+	SYS___FGETWC_A                      = 0x7AA
+	SYS___FGETWS_A                      = 0x7AD
+	SYS___FLOORF_H                      = 0x7F6
+	SYS___FLOORL_H                      = 0x7F7
+	SYS___FLOOR_H                       = 0x7EB
+	SYS___FPUTWC_A                      = 0x7A5
+	SYS___FPUTWS_A                      = 0x7A8
+	SYS___GETTIMEOFDAY_A                = 0x7AE
+	SYS___GETWCHAR_A                    = 0x7AC
+	SYS___GETWC_A                       = 0x7AB
+	SYS___GLOB_A                        = 0x7DE
+	SYS___GMTIME_A                      = 0x7AF
+	SYS___GMTIME_R_A                    = 0x7B0
+	SYS___INET_PTON_A                   = 0x7BC
+	SYS___J0_H                          = 0x7EE
+	SYS___J1_H                          = 0x7EF
+	SYS___JN_H                          = 0x7F0
+	SYS___LOCALTIME_A                   = 0x7B1
+	SYS___LOCALTIME_R_A                 = 0x7B2
+	SYS___MALLOC24                      = 0x7FC
+	SYS___MALLOC31                      = 0x7FD
+	SYS___MKTIME_A                      = 0x7B3
+	SYS___MODFF_H                       = 0x7F8
+	SYS___MODFL_H                       = 0x7F9
+	SYS___MODF_H                        = 0x7EC
+	SYS___OPENDIR_A                     = 0x7C2
+	SYS___OSNAME                        = 0x7E0
+	SYS___PUTWCHAR_A                    = 0x7A7
+	SYS___PUTWC_A                       = 0x7A6
+	SYS___READDIR_A                     = 0x7C3
+	SYS___STRTOLL_A                     = 0x7A3
+	SYS___STRTOULL_A                    = 0x7A4
+	SYS___SYSLOG_A                      = 0x7BD
+	SYS___TZZNA                         = 0x7B4
+	SYS___UNGETWC_A                     = 0x7A9
+	SYS___UTIME_A                       = 0x7A0
+	SYS___VFPRINTF2_A                   = 0x7E7
+	SYS___VPRINTF2_A                    = 0x7E8
+	SYS___VSPRINTF2_A                   = 0x7E9
+	SYS___VSWPRNTF2_A                   = 0x7BB
+	SYS___WCSTOD_A                      = 0x7D9
+	SYS___WCSTOL_A                      = 0x7DA
+	SYS___WCSTOUL_A                     = 0x7DB
+	SYS___WCTOB_A                       = 0x7E5
+	SYS___Y0_H                          = 0x7F1
+	SYS___Y1_H                          = 0x7F2
+	SYS___YN_H                          = 0x7F3
+	SYS_____OPENDIR2_A                  = 0x7BF
+	SYS_____OSNAME_A                    = 0x7E1
+	SYS_____READDIR2_A                  = 0x7C0
+	SYS_DLCLOSE                         = 0x8DF
+	SYS_DLERROR                         = 0x8E0
+	SYS_DLOPEN                          = 0x8DD
+	SYS_DLSYM                           = 0x8DE
+	SYS_FLOCKFILE                       = 0x8D3
+	SYS_FTRYLOCKFILE                    = 0x8D4
+	SYS_FUNLOCKFILE                     = 0x8D5
+	SYS_GETCHAR_UNLOCKED                = 0x8D7
+	SYS_GETC_UNLOCKED                   = 0x8D6
+	SYS_PUTCHAR_UNLOCKED                = 0x8D9
+	SYS_PUTC_UNLOCKED                   = 0x8D8
+	SYS_SNPRINTF                        = 0x8DA
+	SYS_VSNPRINTF                       = 0x8DB
+	SYS_WCSCSPN                         = 0x08B
+	SYS_WCSLEN                          = 0x08C
+	SYS_WCSNCAT                         = 0x08D
+	SYS_WCSNCMP                         = 0x08A
+	SYS_WCSNCPY                         = 0x08F
+	SYS_WCSSPN                          = 0x08E
+	SYS___ABSF_H                        = 0x8E7
+	SYS___ABSL_H                        = 0x8E8
+	SYS___ABS_H                         = 0x8E6
+	SYS___ACOSF_H                       = 0x8EA
+	SYS___ACOSH_H                       = 0x8EC
+	SYS___ACOSL_H                       = 0x8EB
+	SYS___ACOS_H                        = 0x8E9
+	SYS___ASINF_H                       = 0x8EE
+	SYS___ASINH_H                       = 0x8F0
+	SYS___ASINL_H                       = 0x8EF
+	SYS___ASIN_H                        = 0x8ED
+	SYS___ATAN2F_H                      = 0x8F8
+	SYS___ATAN2L_H                      = 0x8F9
+	SYS___ATAN2_H                       = 0x8F7
+	SYS___ATANF_H                       = 0x8F2
+	SYS___ATANHF_H                      = 0x8F5
+	SYS___ATANHL_H                      = 0x8F6
+	SYS___ATANH_H                       = 0x8F4
+	SYS___ATANL_H                       = 0x8F3
+	SYS___ATAN_H                        = 0x8F1
+	SYS___CBRT_H                        = 0x8FA
+	SYS___COPYSIGNF_H                   = 0x8FB
+	SYS___COPYSIGNL_H                   = 0x8FC
+	SYS___COSF_H                        = 0x8FE
+	SYS___COSL_H                        = 0x8FF
+	SYS___COS_H                         = 0x8FD
+	SYS___DLERROR_A                     = 0x8D2
+	SYS___DLOPEN_A                      = 0x8D0
+	SYS___DLSYM_A                       = 0x8D1
+	SYS___GETUTXENT_A                   = 0x8C6
+	SYS___GETUTXID_A                    = 0x8C7
+	SYS___GETUTXLINE_A                  = 0x8C8
+	SYS___ITOA                          = 0x8AA
+	SYS___ITOA_A                        = 0x8B0
+	SYS___LE_CONDITION_TOKEN_BUILD      = 0x8A5
+	SYS___LE_MSG_ADD_INSERT             = 0x8A6
+	SYS___LE_MSG_GET                    = 0x8A7
+	SYS___LE_MSG_GET_AND_WRITE          = 0x8A8
+	SYS___LE_MSG_WRITE                  = 0x8A9
+	SYS___LLTOA                         = 0x8AE
+	SYS___LLTOA_A                       = 0x8B4
+	SYS___LTOA                          = 0x8AC
+	SYS___LTOA_A                        = 0x8B2
+	SYS___PUTCHAR_UNLOCKED_A            = 0x8CC
+	SYS___PUTC_UNLOCKED_A               = 0x8CB
+	SYS___PUTUTXLINE_A                  = 0x8C9
+	SYS___RESET_EXCEPTION_HANDLER       = 0x8E3
+	SYS___REXEC_A                       = 0x8C4
+	SYS___REXEC_AF_A                    = 0x8C5
+	SYS___SET_EXCEPTION_HANDLER         = 0x8E2
+	SYS___SNPRINTF_A                    = 0x8CD
+	SYS___SUPERKILL                     = 0x8A4
+	SYS___TCGETATTR_A                   = 0x8A1
+	SYS___TCSETATTR_A                   = 0x8A2
+	SYS___ULLTOA                        = 0x8AF
+	SYS___ULLTOA_A                      = 0x8B5
+	SYS___ULTOA                         = 0x8AD
+	SYS___ULTOA_A                       = 0x8B3
+	SYS___UTOA                          = 0x8AB
+	SYS___UTOA_A                        = 0x8B1
+	SYS___VHM_EVENT                     = 0x8E4
+	SYS___VSNPRINTF_A                   = 0x8CE
+	SYS_____GETENV_A                    = 0x8C3
+	SYS_____UTMPXNAME_A                 = 0x8CA
+	SYS_CACOSH                          = 0x9A0
+	SYS_CACOSHF                         = 0x9A3
+	SYS_CACOSHL                         = 0x9A6
+	SYS_CARG                            = 0x9A9
+	SYS_CARGF                           = 0x9AC
+	SYS_CARGL                           = 0x9AF
+	SYS_CASIN                           = 0x9B2
+	SYS_CASINF                          = 0x9B5
+	SYS_CASINH                          = 0x9BB
+	SYS_CASINHF                         = 0x9BE
+	SYS_CASINHL                         = 0x9C1
+	SYS_CASINL                          = 0x9B8
+	SYS_CATAN                           = 0x9C4
+	SYS_CATANF                          = 0x9C7
+	SYS_CATANH                          = 0x9CD
+	SYS_CATANHF                         = 0x9D0
+	SYS_CATANHL                         = 0x9D3
+	SYS_CATANL                          = 0x9CA
+	SYS_CCOS                            = 0x9D6
+	SYS_CCOSF                           = 0x9D9
+	SYS_CCOSH                           = 0x9DF
+	SYS_CCOSHF                          = 0x9E2
+	SYS_CCOSHL                          = 0x9E5
+	SYS_CCOSL                           = 0x9DC
+	SYS_CEXP                            = 0x9E8
+	SYS_CEXPF                           = 0x9EB
+	SYS_CEXPL                           = 0x9EE
+	SYS_CIMAG                           = 0x9F1
+	SYS_CIMAGF                          = 0x9F4
+	SYS_CIMAGL                          = 0x9F7
+	SYS_CLOGF                           = 0x9FD
+	SYS_MEMCHR                          = 0x09B
+	SYS_MEMCMP                          = 0x09A
+	SYS_STRCOLL                         = 0x09C
+	SYS_STRNCMP                         = 0x09D
+	SYS_STRRCHR                         = 0x09F
+	SYS_STRXFRM                         = 0x09E
+	SYS___CACOSHF_B                     = 0x9A4
+	SYS___CACOSHF_H                     = 0x9A5
+	SYS___CACOSHL_B                     = 0x9A7
+	SYS___CACOSHL_H                     = 0x9A8
+	SYS___CACOSH_B                      = 0x9A1
+	SYS___CACOSH_H                      = 0x9A2
+	SYS___CARGF_B                       = 0x9AD
+	SYS___CARGF_H                       = 0x9AE
+	SYS___CARGL_B                       = 0x9B0
+	SYS___CARGL_H                       = 0x9B1
+	SYS___CARG_B                        = 0x9AA
+	SYS___CARG_H                        = 0x9AB
+	SYS___CASINF_B                      = 0x9B6
+	SYS___CASINF_H                      = 0x9B7
+	SYS___CASINHF_B                     = 0x9BF
+	SYS___CASINHF_H                     = 0x9C0
+	SYS___CASINHL_B                     = 0x9C2
+	SYS___CASINHL_H                     = 0x9C3
+	SYS___CASINH_B                      = 0x9BC
+	SYS___CASINH_H                      = 0x9BD
+	SYS___CASINL_B                      = 0x9B9
+	SYS___CASINL_H                      = 0x9BA
+	SYS___CASIN_B                       = 0x9B3
+	SYS___CASIN_H                       = 0x9B4
+	SYS___CATANF_B                      = 0x9C8
+	SYS___CATANF_H                      = 0x9C9
+	SYS___CATANHF_B                     = 0x9D1
+	SYS___CATANHF_H                     = 0x9D2
+	SYS___CATANHL_B                     = 0x9D4
+	SYS___CATANHL_H                     = 0x9D5
+	SYS___CATANH_B                      = 0x9CE
+	SYS___CATANH_H                      = 0x9CF
+	SYS___CATANL_B                      = 0x9CB
+	SYS___CATANL_H                      = 0x9CC
+	SYS___CATAN_B                       = 0x9C5
+	SYS___CATAN_H                       = 0x9C6
+	SYS___CCOSF_B                       = 0x9DA
+	SYS___CCOSF_H                       = 0x9DB
+	SYS___CCOSHF_B                      = 0x9E3
+	SYS___CCOSHF_H                      = 0x9E4
+	SYS___CCOSHL_B                      = 0x9E6
+	SYS___CCOSHL_H                      = 0x9E7
+	SYS___CCOSH_B                       = 0x9E0
+	SYS___CCOSH_H                       = 0x9E1
+	SYS___CCOSL_B                       = 0x9DD
+	SYS___CCOSL_H                       = 0x9DE
+	SYS___CCOS_B                        = 0x9D7
+	SYS___CCOS_H                        = 0x9D8
+	SYS___CEXPF_B                       = 0x9EC
+	SYS___CEXPF_H                       = 0x9ED
+	SYS___CEXPL_B                       = 0x9EF
+	SYS___CEXPL_H                       = 0x9F0
+	SYS___CEXP_B                        = 0x9E9
+	SYS___CEXP_H                        = 0x9EA
+	SYS___CIMAGF_B                      = 0x9F5
+	SYS___CIMAGF_H                      = 0x9F6
+	SYS___CIMAGL_B                      = 0x9F8
+	SYS___CIMAGL_H                      = 0x9F9
+	SYS___CIMAG_B                       = 0x9F2
+	SYS___CIMAG_H                       = 0x9F3
+	SYS___CLOG                          = 0x9FA
+	SYS___CLOGF_B                       = 0x9FE
+	SYS___CLOGF_H                       = 0x9FF
+	SYS___CLOG_B                        = 0x9FB
+	SYS___CLOG_H                        = 0x9FC
+	SYS_ISWCTYPE                        = 0x10C
+	SYS_ISWXDIGI                        = 0x10A
+	SYS_ISWXDIGIT                       = 0x10A
+	SYS_MBSINIT                         = 0x10F
+	SYS_TOWLOWER                        = 0x10D
+	SYS_TOWUPPER                        = 0x10E
+	SYS_WCTYPE                          = 0x10B
+	SYS_WCSSTR                          = 0x11B
+	SYS___RPMTCH                        = 0x11A
+	SYS_WCSTOD                          = 0x12E
+	SYS_WCSTOK                          = 0x12C
+	SYS_WCSTOL                          = 0x12D
+	SYS_WCSTOUL                         = 0x12F
+	SYS_FGETWC                          = 0x13C
+	SYS_FGETWS                          = 0x13D
+	SYS_FPUTWC                          = 0x13E
+	SYS_FPUTWS                          = 0x13F
+	SYS_REGERROR                        = 0x13B
+	SYS_REGFREE                         = 0x13A
+	SYS_COLLEQUIV                       = 0x14F
+	SYS_COLLTOSTR                       = 0x14E
+	SYS_ISMCCOLLEL                      = 0x14C
+	SYS_STRTOCOLL                       = 0x14D
+	SYS_DLLFREE                         = 0x16F
+	SYS_DLLQUERYFN                      = 0x16D
+	SYS_DLLQUERYVAR                     = 0x16E
+	SYS_GETMCCOLL                       = 0x16A
+	SYS_GETWMCCOLL                      = 0x16B
+	SYS___ERR2AD                        = 0x16C
+	SYS_CFSETOSPEED                     = 0x17A
+	SYS_CHDIR                           = 0x17B
+	SYS_CHMOD                           = 0x17C
+	SYS_CHOWN                           = 0x17D
+	SYS_CLOSE                           = 0x17E
+	SYS_CLOSEDIR                        = 0x17F
+	SYS_LOG                             = 0x017
+	SYS_COSH                            = 0x018
+	SYS_FCHMOD                          = 0x18A
+	SYS_FCHOWN                          = 0x18B
+	SYS_FCNTL                           = 0x18C
+	SYS_FILENO                          = 0x18D
+	SYS_FORK                            = 0x18E
+	SYS_FPATHCONF                       = 0x18F
+	SYS_GETLOGIN                        = 0x19A
+	SYS_GETPGRP                         = 0x19C
+	SYS_GETPID                          = 0x19D
+	SYS_GETPPID                         = 0x19E
+	SYS_GETPWNAM                        = 0x19F
+	SYS_TANH                            = 0x019
+	SYS_W_GETMNTENT                     = 0x19B
+	SYS_POW                             = 0x020
+	SYS_PTHREAD_SELF                    = 0x20A
+	SYS_PTHREAD_SETINTR                 = 0x20B
+	SYS_PTHREAD_SETINTRTYPE             = 0x20C
+	SYS_PTHREAD_SETSPECIFIC             = 0x20D
+	SYS_PTHREAD_TESTINTR                = 0x20E
+	SYS_PTHREAD_YIELD                   = 0x20F
+	SYS_SQRT                            = 0x021
+	SYS_FLOOR                           = 0x022
+	SYS_J1                              = 0x023
+	SYS_WCSPBRK                         = 0x23F
+	SYS_BSEARCH                         = 0x24C
+	SYS_FABS                            = 0x024
+	SYS_GETENV                          = 0x24A
+	SYS_LDIV                            = 0x24D
+	SYS_SYSTEM                          = 0x24B
+	SYS_FMOD                            = 0x025
+	SYS___RETHROW                       = 0x25F
+	SYS___THROW                         = 0x25E
+	SYS_J0                              = 0x026
+	SYS_PUTENV                          = 0x26A
+	SYS___GETENV                        = 0x26F
+	SYS_SEMCTL                          = 0x27A
+	SYS_SEMGET                          = 0x27B
+	SYS_SEMOP                           = 0x27C
+	SYS_SHMAT                           = 0x27D
+	SYS_SHMCTL                          = 0x27E
+	SYS_SHMDT                           = 0x27F
+	SYS_YN                              = 0x027
+	SYS_JN                              = 0x028
+	SYS_SIGALTSTACK                     = 0x28A
+	SYS_SIGHOLD                         = 0x28B
+	SYS_SIGIGNORE                       = 0x28C
+	SYS_SIGINTERRUPT                    = 0x28D
+	SYS_SIGPAUSE                        = 0x28E
+	SYS_SIGRELSE                        = 0x28F
+	SYS_GETOPT                          = 0x29A
+	SYS_GETSUBOPT                       = 0x29D
+	SYS_LCHOWN                          = 0x29B
+	SYS_SETPGRP                         = 0x29E
+	SYS_TRUNCATE                        = 0x29C
+	SYS_Y0                              = 0x029
+	SYS___GDERR                         = 0x29F
+	SYS_ISALPHA                         = 0x030
+	SYS_VFORK                           = 0x30F
+	SYS__LONGJMP                        = 0x30D
+	SYS__SETJMP                         = 0x30E
+	SYS_GLOB                            = 0x31A
+	SYS_GLOBFREE                        = 0x31B
+	SYS_ISALNUM                         = 0x031
+	SYS_PUTW                            = 0x31C
+	SYS_SEEKDIR                         = 0x31D
+	SYS_TELLDIR                         = 0x31E
+	SYS_TEMPNAM                         = 0x31F
+	SYS_GETTIMEOFDAY_R                  = 0x32E
+	SYS_ISLOWER                         = 0x032
+	SYS_LGAMMA                          = 0x32C
+	SYS_REMAINDER                       = 0x32A
+	SYS_SCALB                           = 0x32B
+	SYS_SYNC                            = 0x32F
+	SYS_TTYSLOT                         = 0x32D
+	SYS_ENDPROTOENT                     = 0x33A
+	SYS_ENDSERVENT                      = 0x33B
+	SYS_GETHOSTBYADDR                   = 0x33D
+	SYS_GETHOSTBYADDR_R                 = 0x33C
+	SYS_GETHOSTBYNAME                   = 0x33F
+	SYS_GETHOSTBYNAME_R                 = 0x33E
+	SYS_ISCNTRL                         = 0x033
+	SYS_GETSERVBYNAME                   = 0x34A
+	SYS_GETSERVBYPORT                   = 0x34B
+	SYS_GETSERVENT                      = 0x34C
+	SYS_GETSOCKNAME                     = 0x34D
+	SYS_GETSOCKOPT                      = 0x34E
+	SYS_INET_ADDR                       = 0x34F
+	SYS_ISDIGIT                         = 0x034
+	SYS_ISGRAPH                         = 0x035
+	SYS_SELECT                          = 0x35B
+	SYS_SELECTEX                        = 0x35C
+	SYS_SEND                            = 0x35D
+	SYS_SENDTO                          = 0x35F
+	SYS_CHROOT                          = 0x36A
+	SYS_ISNAN                           = 0x36D
+	SYS_ISUPPER                         = 0x036
+	SYS_ULIMIT                          = 0x36C
+	SYS_UTIMES                          = 0x36E
+	SYS_W_STATVFS                       = 0x36B
+	SYS___H_ERRNO                       = 0x36F
+	SYS_GRANTPT                         = 0x37A
+	SYS_ISPRINT                         = 0x037
+	SYS_TCGETSID                        = 0x37C
+	SYS_UNLOCKPT                        = 0x37B
+	SYS___TCGETCP                       = 0x37D
+	SYS___TCSETCP                       = 0x37E
+	SYS___TCSETTABLES                   = 0x37F
+	SYS_ISPUNCT                         = 0x038
+	SYS_NLIST                           = 0x38C
+	SYS___IPDBCS                        = 0x38D
+	SYS___IPDSPX                        = 0x38E
+	SYS___IPMSGC                        = 0x38F
+	SYS___STHOSTENT                     = 0x38B
+	SYS___STSERVENT                     = 0x38A
+	SYS_ISSPACE                         = 0x039
+	SYS_COS                             = 0x040
+	SYS_T_ALLOC                         = 0x40A
+	SYS_T_BIND                          = 0x40B
+	SYS_T_CLOSE                         = 0x40C
+	SYS_T_CONNECT                       = 0x40D
+	SYS_T_ERROR                         = 0x40E
+	SYS_T_FREE                          = 0x40F
+	SYS_TAN                             = 0x041
+	SYS_T_RCVREL                        = 0x41A
+	SYS_T_RCVUDATA                      = 0x41B
+	SYS_T_RCVUDERR                      = 0x41C
+	SYS_T_SND                           = 0x41D
+	SYS_T_SNDDIS                        = 0x41E
+	SYS_T_SNDREL                        = 0x41F
+	SYS_GETPMSG                         = 0x42A
+	SYS_ISASTREAM                       = 0x42B
+	SYS_PUTMSG                          = 0x42C
+	SYS_PUTPMSG                         = 0x42D
+	SYS_SINH                            = 0x042
+	SYS___ISPOSIXON                     = 0x42E
+	SYS___OPENMVSREL                    = 0x42F
+	SYS_ACOS                            = 0x043
+	SYS_ATAN                            = 0x044
+	SYS_ATAN2                           = 0x045
+	SYS_FTELL                           = 0x046
+	SYS_FGETPOS                         = 0x047
+	SYS_SOCK_DEBUG                      = 0x47A
+	SYS_SOCK_DO_TESTSTOR                = 0x47D
+	SYS_TAKESOCKET                      = 0x47E
+	SYS___SERVER_INIT                   = 0x47F
+	SYS_FSEEK                           = 0x048
+	SYS___IPHOST                        = 0x48B
+	SYS___IPNODE                        = 0x48C
+	SYS___SERVER_CLASSIFY_CREATE        = 0x48D
+	SYS___SERVER_CLASSIFY_DESTROY       = 0x48E
+	SYS___SERVER_CLASSIFY_RESET         = 0x48F
+	SYS___SMF_RECORD                    = 0x48A
+	SYS_FSETPOS                         = 0x049
+	SYS___FNWSA                         = 0x49B
+	SYS___SPAWN2                        = 0x49D
+	SYS___SPAWNP2                       = 0x49E
+	SYS_ATOF                            = 0x050
+	SYS_PTHREAD_MUTEXATTR_GETPSHARED    = 0x50A
+	SYS_PTHREAD_MUTEXATTR_SETPSHARED    = 0x50B
+	SYS_PTHREAD_RWLOCK_DESTROY          = 0x50C
+	SYS_PTHREAD_RWLOCK_INIT             = 0x50D
+	SYS_PTHREAD_RWLOCK_RDLOCK           = 0x50E
+	SYS_PTHREAD_RWLOCK_TRYRDLOCK        = 0x50F
+	SYS_ATOI                            = 0x051
+	SYS___FP_CLASS                      = 0x51D
+	SYS___FP_CLR_FLAG                   = 0x51A
+	SYS___FP_FINITE                     = 0x51E
+	SYS___FP_ISNAN                      = 0x51F
+	SYS___FP_RAISE_XCP                  = 0x51C
+	SYS___FP_READ_FLAG                  = 0x51B
+	SYS_RAND                            = 0x052
+	SYS_SIGTIMEDWAIT                    = 0x52D
+	SYS_SIGWAITINFO                     = 0x52E
+	SYS___CHKBFP                        = 0x52F
+	SYS___FPC_RS                        = 0x52C
+	SYS___FPC_RW                        = 0x52A
+	SYS___FPC_SM                        = 0x52B
+	SYS_STRTOD                          = 0x053
+	SYS_STRTOL                          = 0x054
+	SYS_STRTOUL                         = 0x055
+	SYS_MALLOC                          = 0x056
+	SYS_SRAND                           = 0x057
+	SYS_CALLOC                          = 0x058
+	SYS_FREE                            = 0x059
+	SYS___OSENV                         = 0x59F
+	SYS___W_PIOCTL                      = 0x59E
+	SYS_LONGJMP                         = 0x060
+	SYS___FLOORF_B                      = 0x60A
+	SYS___FLOORL_B                      = 0x60B
+	SYS___FREXPF_B                      = 0x60C
+	SYS___FREXPL_B                      = 0x60D
+	SYS___LDEXPF_B                      = 0x60E
+	SYS___LDEXPL_B                      = 0x60F
+	SYS_SIGNAL                          = 0x061
+	SYS___ATAN2F_B                      = 0x61A
+	SYS___ATAN2L_B                      = 0x61B
+	SYS___COSHF_B                       = 0x61C
+	SYS___COSHL_B                       = 0x61D
+	SYS___EXPF_B                        = 0x61E
+	SYS___EXPL_B                        = 0x61F
+	SYS_TMPNAM                          = 0x062
+	SYS___ABSF_B                        = 0x62A
+	SYS___ABSL_B                        = 0x62C
+	SYS___ABS_B                         = 0x62B
+	SYS___FMODF_B                       = 0x62D
+	SYS___FMODL_B                       = 0x62E
+	SYS___MODFF_B                       = 0x62F
+	SYS_ATANL                           = 0x63A
+	SYS_CEILF                           = 0x63B
+	SYS_CEILL                           = 0x63C
+	SYS_COSF                            = 0x63D
+	SYS_COSHF                           = 0x63F
+	SYS_COSL                            = 0x63E
+	SYS_REMOVE                          = 0x063
+	SYS_POWL                            = 0x64A
+	SYS_RENAME                          = 0x064
+	SYS_SINF                            = 0x64B
+	SYS_SINHF                           = 0x64F
+	SYS_SINL                            = 0x64C
+	SYS_SQRTF                           = 0x64D
+	SYS_SQRTL                           = 0x64E
+	SYS_BTOWC                           = 0x65F
+	SYS_FREXPL                          = 0x65A
+	SYS_LDEXPF                          = 0x65B
+	SYS_LDEXPL                          = 0x65C
+	SYS_MODFF                           = 0x65D
+	SYS_MODFL                           = 0x65E
+	SYS_TMPFILE                         = 0x065
+	SYS_FREOPEN                         = 0x066
+	SYS___CHARMAP_INIT_A                = 0x66E
+	SYS___GETHOSTBYADDR_R_A             = 0x66C
+	SYS___GETHOSTBYNAME_A               = 0x66A
+	SYS___GETHOSTBYNAME_R_A             = 0x66D
+	SYS___MBLEN_A                       = 0x66F
+	SYS___RES_INIT_A                    = 0x66B
+	SYS_FCLOSE                          = 0x067
+	SYS___GETGRGID_R_A                  = 0x67D
+	SYS___WCSTOMBS_A                    = 0x67A
+	SYS___WCSTOMBS_STD_A                = 0x67B
+	SYS___WCSWIDTH_A                    = 0x67C
+	SYS___WCSWIDTH_ASIA                 = 0x67F
+	SYS___WCSWIDTH_STD_A                = 0x67E
+	SYS_FFLUSH                          = 0x068
+	SYS___GETLOGIN_R_A                  = 0x68E
+	SYS___GETPWNAM_R_A                  = 0x68C
+	SYS___GETPWUID_R_A                  = 0x68D
+	SYS___TTYNAME_R_A                   = 0x68F
+	SYS___WCWIDTH_ASIA                  = 0x68B
+	SYS___WCWIDTH_STD_A                 = 0x68A
+	SYS_FOPEN                           = 0x069
+	SYS___REGEXEC_A                     = 0x69A
+	SYS___REGEXEC_STD_A                 = 0x69B
+	SYS___REGFREE_A                     = 0x69C
+	SYS___REGFREE_STD_A                 = 0x69D
+	SYS___STRCOLL_A                     = 0x69E
+	SYS___STRCOLL_C_A                   = 0x69F
+	SYS_SCANF                           = 0x070
+	SYS___A64L_A                        = 0x70C
+	SYS___ECVT_A                        = 0x70D
+	SYS___FCVT_A                        = 0x70E
+	SYS___GCVT_A                        = 0x70F
+	SYS___STRTOUL_A                     = 0x70A
+	SYS_____AE_CORRESTBL_QUERY_A        = 0x70B
+	SYS_SPRINTF                         = 0x071
+	SYS___ACCESS_A                      = 0x71F
+	SYS___CATOPEN_A                     = 0x71E
+	SYS___GETOPT_A                      = 0x71D
+	SYS___REALPATH_A                    = 0x71A
+	SYS___SETENV_A                      = 0x71B
+	SYS___SYSTEM_A                      = 0x71C
+	SYS_FGETC                           = 0x072
+	SYS___GAI_STRERROR_A                = 0x72F
+	SYS___RMDIR_A                       = 0x72A
+	SYS___STATVFS_A                     = 0x72B
+	SYS___SYMLINK_A                     = 0x72C
+	SYS___TRUNCATE_A                    = 0x72D
+	SYS___UNLINK_A                      = 0x72E
+	SYS_VFPRINTF                        = 0x073
+	SYS___ISSPACE_A                     = 0x73A
+	SYS___ISUPPER_A                     = 0x73B
+	SYS___ISWALNUM_A                    = 0x73F
+	SYS___ISXDIGIT_A                    = 0x73C
+	SYS___TOLOWER_A                     = 0x73D
+	SYS___TOUPPER_A                     = 0x73E
+	SYS_VPRINTF                         = 0x074
+	SYS___CONFSTR_A                     = 0x74B
+	SYS___FDOPEN_A                      = 0x74E
+	SYS___FLDATA_A                      = 0x74F
+	SYS___FTOK_A                        = 0x74C
+	SYS___ISWXDIGIT_A                   = 0x74A
+	SYS___MKTEMP_A                      = 0x74D
+	SYS_VSPRINTF                        = 0x075
+	SYS___GETGRGID_A                    = 0x75A
+	SYS___GETGRNAM_A                    = 0x75B
+	SYS___GETGROUPSBYNAME_A             = 0x75C
+	SYS___GETHOSTENT_A                  = 0x75D
+	SYS___GETHOSTNAME_A                 = 0x75E
+	SYS___GETLOGIN_A                    = 0x75F
+	SYS_GETC                            = 0x076
+	SYS___CREATEWORKUNIT_A              = 0x76A
+	SYS___CTERMID_A                     = 0x76B
+	SYS___FMTMSG_A                      = 0x76C
+	SYS___INITGROUPS_A                  = 0x76D
+	SYS___MSGRCV_A                      = 0x76F
+	SYS_____LOGIN_A                     = 0x76E
+	SYS_FGETS                           = 0x077
+	SYS___STRCASECMP_A                  = 0x77B
+	SYS___STRNCASECMP_A                 = 0x77C
+	SYS___TTYNAME_A                     = 0x77D
+	SYS___UNAME_A                       = 0x77E
+	SYS___UTIMES_A                      = 0x77F
+	SYS_____SERVER_PWU_A                = 0x77A
+	SYS_FPUTC                           = 0x078
+	SYS___CREAT_O_A                     = 0x78E
+	SYS___ENVNA                         = 0x78F
+	SYS___FREAD_A                       = 0x78A
+	SYS___FWRITE_A                      = 0x78B
+	SYS___ISASCII                       = 0x78D
+	SYS___OPEN_O_A                      = 0x78C
+	SYS_FPUTS                           = 0x079
+	SYS___ASCTIME_A                     = 0x79C
+	SYS___CTIME_A                       = 0x79D
+	SYS___GETDATE_A                     = 0x79E
+	SYS___GETSERVBYPORT_A               = 0x79A
+	SYS___GETSERVENT_A                  = 0x79B
+	SYS___TZSET_A                       = 0x79F
+	SYS_ACL_FROM_TEXT                   = 0x80C
+	SYS_ACL_SET_FD                      = 0x80A
+	SYS_ACL_SET_FILE                    = 0x80B
+	SYS_ACL_SORT                        = 0x80E
+	SYS_ACL_TO_TEXT                     = 0x80D
+	SYS_UNGETC                          = 0x080
+	SYS___SHUTDOWN_REGISTRATION         = 0x80F
+	SYS_FREAD                           = 0x081
+	SYS_FREEADDRINFO                    = 0x81A
+	SYS_GAI_STRERROR                    = 0x81B
+	SYS_REXEC_AF                        = 0x81C
+	SYS___DYNALLOC_A                    = 0x81F
+	SYS___POE                           = 0x81D
+	SYS_WCSTOMBS                        = 0x082
+	SYS___INET_ADDR_A                   = 0x82F
+	SYS___NLIST_A                       = 0x82A
+	SYS_____TCGETCP_A                   = 0x82B
+	SYS_____TCSETCP_A                   = 0x82C
+	SYS_____W_PIOCTL_A                  = 0x82E
+	SYS_MBTOWC                          = 0x083
+	SYS___CABEND                        = 0x83D
+	SYS___LE_CIB_GET                    = 0x83E
+	SYS___RECVMSG_A                     = 0x83B
+	SYS___SENDMSG_A                     = 0x83A
+	SYS___SET_LAA_FOR_JIT               = 0x83F
+	SYS_____LCHATTR_A                   = 0x83C
+	SYS_WCTOMB                          = 0x084
+	SYS___CBRTL_B                       = 0x84A
+	SYS___COPYSIGNF_B                   = 0x84B
+	SYS___COPYSIGNL_B                   = 0x84C
+	SYS___COTANF_B                      = 0x84D
+	SYS___COTANL_B                      = 0x84F
+	SYS___COTAN_B                       = 0x84E
+	SYS_MBSTOWCS                        = 0x085
+	SYS___LOG1PL_B                      = 0x85A
+	SYS___LOG2F_B                       = 0x85B
+	SYS___LOG2L_B                       = 0x85D
+	SYS___LOG2_B                        = 0x85C
+	SYS___REMAINDERF_B                  = 0x85E
+	SYS___REMAINDERL_B                  = 0x85F
+	SYS_ACOSHF                          = 0x86E
+	SYS_ACOSHL                          = 0x86F
+	SYS_WCSCPY                          = 0x086
+	SYS___ERFCF_B                       = 0x86D
+	SYS___ERFF_B                        = 0x86C
+	SYS___LROUNDF_B                     = 0x86A
+	SYS___LROUND_B                      = 0x86B
+	SYS_COTANL                          = 0x87A
+	SYS_EXP2F                           = 0x87B
+	SYS_EXP2L                           = 0x87C
+	SYS_EXPM1F                          = 0x87D
+	SYS_EXPM1L                          = 0x87E
+	SYS_FDIMF                           = 0x87F
+	SYS_WCSCAT                          = 0x087
+	SYS___COTANL                        = 0x87A
+	SYS_REMAINDERF                      = 0x88A
+	SYS_REMAINDERL                      = 0x88B
+	SYS_REMAINDF                        = 0x88A
+	SYS_REMAINDL                        = 0x88B
+	SYS_REMQUO                          = 0x88D
+	SYS_REMQUOF                         = 0x88C
+	SYS_REMQUOL                         = 0x88E
+	SYS_TGAMMAF                         = 0x88F
+	SYS_WCSCHR                          = 0x088
+	SYS_ERFCF                           = 0x89B
+	SYS_ERFCL                           = 0x89C
+	SYS_ERFL                            = 0x89A
+	SYS_EXP2                            = 0x89E
+	SYS_WCSCMP                          = 0x089
+	SYS___EXP2_B                        = 0x89D
+	SYS___FAR_JUMP                      = 0x89F
+	SYS_ABS                             = 0x090
+	SYS___ERFCL_H                       = 0x90A
+	SYS___EXPF_H                        = 0x90C
+	SYS___EXPL_H                        = 0x90D
+	SYS___EXPM1_H                       = 0x90E
+	SYS___EXP_H                         = 0x90B
+	SYS___FDIM_H                        = 0x90F
+	SYS_DIV                             = 0x091
+	SYS___LOG2F_H                       = 0x91F
+	SYS___LOG2_H                        = 0x91E
+	SYS___LOGB_H                        = 0x91D
+	SYS___LOGF_H                        = 0x91B
+	SYS___LOGL_H                        = 0x91C
+	SYS___LOG_H                         = 0x91A
+	SYS_LABS                            = 0x092
+	SYS___POWL_H                        = 0x92A
+	SYS___REMAINDER_H                   = 0x92B
+	SYS___RINT_H                        = 0x92C
+	SYS___SCALB_H                       = 0x92D
+	SYS___SINF_H                        = 0x92F
+	SYS___SIN_H                         = 0x92E
+	SYS_STRNCPY                         = 0x093
+	SYS___TANHF_H                       = 0x93B
+	SYS___TANHL_H                       = 0x93C
+	SYS___TANH_H                        = 0x93A
+	SYS___TGAMMAF_H                     = 0x93E
+	SYS___TGAMMA_H                      = 0x93D
+	SYS___TRUNC_H                       = 0x93F
+	SYS_MEMCPY                          = 0x094
+	SYS_VFWSCANF                        = 0x94A
+	SYS_VSWSCANF                        = 0x94E
+	SYS_VWSCANF                         = 0x94C
+	SYS_INET6_RTH_ADD                   = 0x95D
+	SYS_INET6_RTH_INIT                  = 0x95C
+	SYS_INET6_RTH_REVERSE               = 0x95E
+	SYS_INET6_RTH_SEGMENTS              = 0x95F
+	SYS_INET6_RTH_SPACE                 = 0x95B
+	SYS_MEMMOVE                         = 0x095
+	SYS_WCSTOLD                         = 0x95A
+	SYS_STRCPY                          = 0x096
+	SYS_STRCMP                          = 0x097
+	SYS_CABS                            = 0x98E
+	SYS_STRCAT                          = 0x098
+	SYS___CABS_B                        = 0x98F
+	SYS___POW_II                        = 0x98A
+	SYS___POW_II_B                      = 0x98B
+	SYS___POW_II_H                      = 0x98C
+	SYS_CACOSF                          = 0x99A
+	SYS_CACOSL                          = 0x99D
+	SYS_STRNCAT                         = 0x099
+	SYS___CACOSF_B                      = 0x99B
+	SYS___CACOSF_H                      = 0x99C
+	SYS___CACOSL_B                      = 0x99E
+	SYS___CACOSL_H                      = 0x99F
+	SYS_ISWALPHA                        = 0x100
+	SYS_ISWBLANK                        = 0x101
+	SYS___ISWBLK                        = 0x101
+	SYS_ISWCNTRL                        = 0x102
+	SYS_ISWDIGIT                        = 0x103
+	SYS_ISWGRAPH                        = 0x104
+	SYS_ISWLOWER                        = 0x105
+	SYS_ISWPRINT                        = 0x106
+	SYS_ISWPUNCT                        = 0x107
+	SYS_ISWSPACE                        = 0x108
+	SYS_ISWUPPER                        = 0x109
+	SYS_WCTOB                           = 0x110
+	SYS_MBRLEN                          = 0x111
+	SYS_MBRTOWC                         = 0x112
+	SYS_MBSRTOWC                        = 0x113
+	SYS_MBSRTOWCS                       = 0x113
+	SYS_WCRTOMB                         = 0x114
+	SYS_WCSRTOMB                        = 0x115
+	SYS_WCSRTOMBS                       = 0x115
+	SYS___CSID                          = 0x116
+	SYS___WCSID                         = 0x117
+	SYS_STRPTIME                        = 0x118
+	SYS___STRPTM                        = 0x118
+	SYS_STRFMON                         = 0x119
+	SYS_WCSCOLL                         = 0x130
+	SYS_WCSXFRM                         = 0x131
+	SYS_WCSWIDTH                        = 0x132
+	SYS_WCWIDTH                         = 0x133
+	SYS_WCSFTIME                        = 0x134
+	SYS_SWPRINTF                        = 0x135
+	SYS_VSWPRINT                        = 0x136
+	SYS_VSWPRINTF                       = 0x136
+	SYS_SWSCANF                         = 0x137
+	SYS_REGCOMP                         = 0x138
+	SYS_REGEXEC                         = 0x139
+	SYS_GETWC                           = 0x140
+	SYS_GETWCHAR                        = 0x141
+	SYS_PUTWC                           = 0x142
+	SYS_PUTWCHAR                        = 0x143
+	SYS_UNGETWC                         = 0x144
+	SYS_ICONV_OPEN                      = 0x145
+	SYS_ICONV                           = 0x146
+	SYS_ICONV_CLOSE                     = 0x147
+	SYS_COLLRANGE                       = 0x150
+	SYS_CCLASS                          = 0x151
+	SYS_COLLORDER                       = 0x152
+	SYS___DEMANGLE                      = 0x154
+	SYS_FDOPEN                          = 0x155
+	SYS___ERRNO                         = 0x156
+	SYS___ERRNO2                        = 0x157
+	SYS___TERROR                        = 0x158
+	SYS_MAXCOLL                         = 0x169
+	SYS_DLLLOAD                         = 0x170
+	SYS__EXIT                           = 0x174
+	SYS_ACCESS                          = 0x175
+	SYS_ALARM                           = 0x176
+	SYS_CFGETISPEED                     = 0x177
+	SYS_CFGETOSPEED                     = 0x178
+	SYS_CFSETISPEED                     = 0x179
+	SYS_CREAT                           = 0x180
+	SYS_CTERMID                         = 0x181
+	SYS_DUP                             = 0x182
+	SYS_DUP2                            = 0x183
+	SYS_EXECL                           = 0x184
+	SYS_EXECLE                          = 0x185
+	SYS_EXECLP                          = 0x186
+	SYS_EXECV                           = 0x187
+	SYS_EXECVE                          = 0x188
+	SYS_EXECVP                          = 0x189
+	SYS_FSTAT                           = 0x190
+	SYS_FSYNC                           = 0x191
+	SYS_FTRUNCATE                       = 0x192
+	SYS_GETCWD                          = 0x193
+	SYS_GETEGID                         = 0x194
+	SYS_GETEUID                         = 0x195
+	SYS_GETGID                          = 0x196
+	SYS_GETGRGID                        = 0x197
+	SYS_GETGRNAM                        = 0x198
+	SYS_GETGROUPS                       = 0x199
+	SYS_PTHREAD_MUTEXATTR_DESTROY       = 0x200
+	SYS_PTHREAD_MUTEXATTR_SETKIND_NP    = 0x201
+	SYS_PTHREAD_MUTEXATTR_GETKIND_NP    = 0x202
+	SYS_PTHREAD_MUTEX_INIT              = 0x203
+	SYS_PTHREAD_MUTEX_DESTROY           = 0x204
+	SYS_PTHREAD_MUTEX_LOCK              = 0x205
+	SYS_PTHREAD_MUTEX_TRYLOCK           = 0x206
+	SYS_PTHREAD_MUTEX_UNLOCK            = 0x207
+	SYS_PTHREAD_ONCE                    = 0x209
+	SYS_TW_OPEN                         = 0x210
+	SYS_TW_FCNTL                        = 0x211
+	SYS_PTHREAD_JOIN_D4_NP              = 0x212
+	SYS_PTHREAD_CONDATTR_SETKIND_NP     = 0x213
+	SYS_PTHREAD_CONDATTR_GETKIND_NP     = 0x214
+	SYS_EXTLINK_NP                      = 0x215
+	SYS___PASSWD                        = 0x216
+	SYS_SETGROUPS                       = 0x217
+	SYS_INITGROUPS                      = 0x218
+	SYS_WCSRCHR                         = 0x240
+	SYS_SVC99                           = 0x241
+	SYS___SVC99                         = 0x241
+	SYS_WCSWCS                          = 0x242
+	SYS_LOCALECO                        = 0x243
+	SYS_LOCALECONV                      = 0x243
+	SYS___LIBREL                        = 0x244
+	SYS_RELEASE                         = 0x245
+	SYS___RLSE                          = 0x245
+	SYS_FLOCATE                         = 0x246
+	SYS___FLOCT                         = 0x246
+	SYS_FDELREC                         = 0x247
+	SYS___FDLREC                        = 0x247
+	SYS_FETCH                           = 0x248
+	SYS___FETCH                         = 0x248
+	SYS_QSORT                           = 0x249
+	SYS___CLEANUPCATCH                  = 0x260
+	SYS___CATCHMATCH                    = 0x261
+	SYS___CLEAN2UPCATCH                 = 0x262
+	SYS_GETPRIORITY                     = 0x270
+	SYS_NICE                            = 0x271
+	SYS_SETPRIORITY                     = 0x272
+	SYS_GETITIMER                       = 0x273
+	SYS_SETITIMER                       = 0x274
+	SYS_MSGCTL                          = 0x275
+	SYS_MSGGET                          = 0x276
+	SYS_MSGRCV                          = 0x277
+	SYS_MSGSND                          = 0x278
+	SYS_MSGXRCV                         = 0x279
+	SYS___MSGXR                         = 0x279
+	SYS_SHMGET                          = 0x280
+	SYS___GETIPC                        = 0x281
+	SYS_SETGRENT                        = 0x282
+	SYS_GETGRENT                        = 0x283
+	SYS_ENDGRENT                        = 0x284
+	SYS_SETPWENT                        = 0x285
+	SYS_GETPWENT                        = 0x286
+	SYS_ENDPWENT                        = 0x287
+	SYS_BSD_SIGNAL                      = 0x288
+	SYS_KILLPG                          = 0x289
+	SYS_SIGSET                          = 0x290
+	SYS_SIGSTACK                        = 0x291
+	SYS_GETRLIMIT                       = 0x292
+	SYS_SETRLIMIT                       = 0x293
+	SYS_GETRUSAGE                       = 0x294
+	SYS_MMAP                            = 0x295
+	SYS_MPROTECT                        = 0x296
+	SYS_MSYNC                           = 0x297
+	SYS_MUNMAP                          = 0x298
+	SYS_CONFSTR                         = 0x299
+	SYS___NDMTRM                        = 0x300
+	SYS_FTOK                            = 0x301
+	SYS_BASENAME                        = 0x302
+	SYS_DIRNAME                         = 0x303
+	SYS_GETDTABLESIZE                   = 0x304
+	SYS_MKSTEMP                         = 0x305
+	SYS_MKTEMP                          = 0x306
+	SYS_NFTW                            = 0x307
+	SYS_GETWD                           = 0x308
+	SYS_LOCKF                           = 0x309
+	SYS_WORDEXP                         = 0x310
+	SYS_WORDFREE                        = 0x311
+	SYS_GETPGID                         = 0x312
+	SYS_GETSID                          = 0x313
+	SYS___UTMPXNAME                     = 0x314
+	SYS_CUSERID                         = 0x315
+	SYS_GETPASS                         = 0x316
+	SYS_FNMATCH                         = 0x317
+	SYS_FTW                             = 0x318
+	SYS_GETW                            = 0x319
+	SYS_ACOSH                           = 0x320
+	SYS_ASINH                           = 0x321
+	SYS_ATANH                           = 0x322
+	SYS_CBRT                            = 0x323
+	SYS_EXPM1                           = 0x324
+	SYS_ILOGB                           = 0x325
+	SYS_LOGB                            = 0x326
+	SYS_LOG1P                           = 0x327
+	SYS_NEXTAFTER                       = 0x328
+	SYS_RINT                            = 0x329
+	SYS_SPAWN                           = 0x330
+	SYS_SPAWNP                          = 0x331
+	SYS_GETLOGIN_UU                     = 0x332
+	SYS_ECVT                            = 0x333
+	SYS_FCVT                            = 0x334
+	SYS_GCVT                            = 0x335
+	SYS_ACCEPT                          = 0x336
+	SYS_BIND                            = 0x337
+	SYS_CONNECT                         = 0x338
+	SYS_ENDHOSTENT                      = 0x339
+	SYS_GETHOSTENT                      = 0x340
+	SYS_GETHOSTID                       = 0x341
+	SYS_GETHOSTNAME                     = 0x342
+	SYS_GETNETBYADDR                    = 0x343
+	SYS_GETNETBYNAME                    = 0x344
+	SYS_GETNETENT                       = 0x345
+	SYS_GETPEERNAME                     = 0x346
+	SYS_GETPROTOBYNAME                  = 0x347
+	SYS_GETPROTOBYNUMBER                = 0x348
+	SYS_GETPROTOENT                     = 0x349
+	SYS_INET_LNAOF                      = 0x350
+	SYS_INET_MAKEADDR                   = 0x351
+	SYS_INET_NETOF                      = 0x352
+	SYS_INET_NETWORK                    = 0x353
+	SYS_INET_NTOA                       = 0x354
+	SYS_IOCTL                           = 0x355
+	SYS_LISTEN                          = 0x356
+	SYS_READV                           = 0x357
+	SYS_RECV                            = 0x358
+	SYS_RECVFROM                        = 0x359
+	SYS_SETHOSTENT                      = 0x360
+	SYS_SETNETENT                       = 0x361
+	SYS_SETPEER                         = 0x362
+	SYS_SETPROTOENT                     = 0x363
+	SYS_SETSERVENT                      = 0x364
+	SYS_SETSOCKOPT                      = 0x365
+	SYS_SHUTDOWN                        = 0x366
+	SYS_SOCKET                          = 0x367
+	SYS_SOCKETPAIR                      = 0x368
+	SYS_WRITEV                          = 0x369
+	SYS_ENDNETENT                       = 0x370
+	SYS_CLOSELOG                        = 0x371
+	SYS_OPENLOG                         = 0x372
+	SYS_SETLOGMASK                      = 0x373
+	SYS_SYSLOG                          = 0x374
+	SYS_PTSNAME                         = 0x375
+	SYS_SETREUID                        = 0x376
+	SYS_SETREGID                        = 0x377
+	SYS_REALPATH                        = 0x378
+	SYS___SIGNGAM                       = 0x379
+	SYS_POLL                            = 0x380
+	SYS_REXEC                           = 0x381
+	SYS___ISASCII2                      = 0x382
+	SYS___TOASCII2                      = 0x383
+	SYS_CHPRIORITY                      = 0x384
+	SYS_PTHREAD_ATTR_SETSYNCTYPE_NP     = 0x385
+	SYS_PTHREAD_ATTR_GETSYNCTYPE_NP     = 0x386
+	SYS_PTHREAD_SET_LIMIT_NP            = 0x387
+	SYS___STNETENT                      = 0x388
+	SYS___STPROTOENT                    = 0x389
+	SYS___SELECT1                       = 0x390
+	SYS_PTHREAD_SECURITY_NP             = 0x391
+	SYS___CHECK_RESOURCE_AUTH_NP        = 0x392
+	SYS___CONVERT_ID_NP                 = 0x393
+	SYS___OPENVMREL                     = 0x394
+	SYS_WMEMCHR                         = 0x395
+	SYS_WMEMCMP                         = 0x396
+	SYS_WMEMCPY                         = 0x397
+	SYS_WMEMMOVE                        = 0x398
+	SYS_WMEMSET                         = 0x399
+	SYS___FPUTWC                        = 0x400
+	SYS___PUTWC                         = 0x401
+	SYS___PWCHAR                        = 0x402
+	SYS___WCSFTM                        = 0x403
+	SYS___WCSTOK                        = 0x404
+	SYS___WCWDTH                        = 0x405
+	SYS_T_ACCEPT                        = 0x409
+	SYS_T_GETINFO                       = 0x410
+	SYS_T_GETPROTADDR                   = 0x411
+	SYS_T_GETSTATE                      = 0x412
+	SYS_T_LISTEN                        = 0x413
+	SYS_T_LOOK                          = 0x414
+	SYS_T_OPEN                          = 0x415
+	SYS_T_OPTMGMT                       = 0x416
+	SYS_T_RCV                           = 0x417
+	SYS_T_RCVCONNECT                    = 0x418
+	SYS_T_RCVDIS                        = 0x419
+	SYS_T_SNDUDATA                      = 0x420
+	SYS_T_STRERROR                      = 0x421
+	SYS_T_SYNC                          = 0x422
+	SYS_T_UNBIND                        = 0x423
+	SYS___T_ERRNO                       = 0x424
+	SYS___RECVMSG2                      = 0x425
+	SYS___SENDMSG2                      = 0x426
+	SYS_FATTACH                         = 0x427
+	SYS_FDETACH                         = 0x428
+	SYS_GETMSG                          = 0x429
+	SYS_GETCONTEXT                      = 0x430
+	SYS_SETCONTEXT                      = 0x431
+	SYS_MAKECONTEXT                     = 0x432
+	SYS_SWAPCONTEXT                     = 0x433
+	SYS_PTHREAD_GETSPECIFIC_D8_NP       = 0x434
+	SYS_GETCLIENTID                     = 0x470
+	SYS___GETCLIENTID                   = 0x471
+	SYS_GETSTABLESIZE                   = 0x472
+	SYS_GETIBMOPT                       = 0x473
+	SYS_GETIBMSOCKOPT                   = 0x474
+	SYS_GIVESOCKET                      = 0x475
+	SYS_IBMSFLUSH                       = 0x476
+	SYS_MAXDESC                         = 0x477
+	SYS_SETIBMOPT                       = 0x478
+	SYS_SETIBMSOCKOPT                   = 0x479
+	SYS___SERVER_PWU                    = 0x480
+	SYS_PTHREAD_TAG_NP                  = 0x481
+	SYS___CONSOLE                       = 0x482
+	SYS___WSINIT                        = 0x483
+	SYS___IPTCPN                        = 0x489
+	SYS___SERVER_CLASSIFY               = 0x490
+	SYS___HEAPRPT                       = 0x496
+	SYS___ISBFP                         = 0x500
+	SYS___FP_CAST                       = 0x501
+	SYS___CERTIFICATE                   = 0x502
+	SYS_SEND_FILE                       = 0x503
+	SYS_AIO_CANCEL                      = 0x504
+	SYS_AIO_ERROR                       = 0x505
+	SYS_AIO_READ                        = 0x506
+	SYS_AIO_RETURN                      = 0x507
+	SYS_AIO_SUSPEND                     = 0x508
+	SYS_AIO_WRITE                       = 0x509
+	SYS_PTHREAD_RWLOCK_TRYWRLOCK        = 0x510
+	SYS_PTHREAD_RWLOCK_UNLOCK           = 0x511
+	SYS_PTHREAD_RWLOCK_WRLOCK           = 0x512
+	SYS_PTHREAD_RWLOCKATTR_GETPSHARED   = 0x513
+	SYS_PTHREAD_RWLOCKATTR_SETPSHARED   = 0x514
+	SYS_PTHREAD_RWLOCKATTR_INIT         = 0x515
+	SYS_PTHREAD_RWLOCKATTR_DESTROY      = 0x516
+	SYS___CTTBL                         = 0x517
+	SYS_PTHREAD_MUTEXATTR_SETTYPE       = 0x518
+	SYS_PTHREAD_MUTEXATTR_GETTYPE       = 0x519
+	SYS___FP_UNORDERED                  = 0x520
+	SYS___FP_READ_RND                   = 0x521
+	SYS___FP_READ_RND_B                 = 0x522
+	SYS___FP_SWAP_RND                   = 0x523
+	SYS___FP_SWAP_RND_B                 = 0x524
+	SYS___FP_LEVEL                      = 0x525
+	SYS___FP_BTOH                       = 0x526
+	SYS___FP_HTOB                       = 0x527
+	SYS___FPC_RD                        = 0x528
+	SYS___FPC_WR                        = 0x529
+	SYS_PTHREAD_SETCANCELTYPE           = 0x600
+	SYS_PTHREAD_TESTCANCEL              = 0x601
+	SYS___ATANF_B                       = 0x602
+	SYS___ATANL_B                       = 0x603
+	SYS___CEILF_B                       = 0x604
+	SYS___CEILL_B                       = 0x605
+	SYS___COSF_B                        = 0x606
+	SYS___COSL_B                        = 0x607
+	SYS___FABSF_B                       = 0x608
+	SYS___FABSL_B                       = 0x609
+	SYS___SINF_B                        = 0x610
+	SYS___SINL_B                        = 0x611
+	SYS___TANF_B                        = 0x612
+	SYS___TANL_B                        = 0x613
+	SYS___TANHF_B                       = 0x614
+	SYS___TANHL_B                       = 0x615
+	SYS___ACOSF_B                       = 0x616
+	SYS___ACOSL_B                       = 0x617
+	SYS___ASINF_B                       = 0x618
+	SYS___ASINL_B                       = 0x619
+	SYS___LOGF_B                        = 0x620
+	SYS___LOGL_B                        = 0x621
+	SYS___LOG10F_B                      = 0x622
+	SYS___LOG10L_B                      = 0x623
+	SYS___POWF_B                        = 0x624
+	SYS___POWL_B                        = 0x625
+	SYS___SINHF_B                       = 0x626
+	SYS___SINHL_B                       = 0x627
+	SYS___SQRTF_B                       = 0x628
+	SYS___SQRTL_B                       = 0x629
+	SYS___MODFL_B                       = 0x630
+	SYS_ABSF                            = 0x631
+	SYS_ABSL                            = 0x632
+	SYS_ACOSF                           = 0x633
+	SYS_ACOSL                           = 0x634
+	SYS_ASINF                           = 0x635
+	SYS_ASINL                           = 0x636
+	SYS_ATAN2F                          = 0x637
+	SYS_ATAN2L                          = 0x638
+	SYS_ATANF                           = 0x639
+	SYS_COSHL                           = 0x640
+	SYS_EXPF                            = 0x641
+	SYS_EXPL                            = 0x642
+	SYS_TANHF                           = 0x643
+	SYS_TANHL                           = 0x644
+	SYS_LOG10F                          = 0x645
+	SYS_LOG10L                          = 0x646
+	SYS_LOGF                            = 0x647
+	SYS_LOGL                            = 0x648
+	SYS_POWF                            = 0x649
+	SYS_SINHL                           = 0x650
+	SYS_TANF                            = 0x651
+	SYS_TANL                            = 0x652
+	SYS_FABSF                           = 0x653
+	SYS_FABSL                           = 0x654
+	SYS_FLOORF                          = 0x655
+	SYS_FLOORL                          = 0x656
+	SYS_FMODF                           = 0x657
+	SYS_FMODL                           = 0x658
+	SYS_FREXPF                          = 0x659
+	SYS___CHATTR                        = 0x660
+	SYS___FCHATTR                       = 0x661
+	SYS___TOCCSID                       = 0x662
+	SYS___CSNAMETYPE                    = 0x663
+	SYS___TOCSNAME                      = 0x664
+	SYS___CCSIDTYPE                     = 0x665
+	SYS___AE_CORRESTBL_QUERY            = 0x666
+	SYS___AE_AUTOCONVERT_STATE          = 0x667
+	SYS_DN_FIND                         = 0x668
+	SYS___GETHOSTBYADDR_A               = 0x669
+	SYS___MBLEN_SB_A                    = 0x670
+	SYS___MBLEN_STD_A                   = 0x671
+	SYS___MBLEN_UTF                     = 0x672
+	SYS___MBSTOWCS_A                    = 0x673
+	SYS___MBSTOWCS_STD_A                = 0x674
+	SYS___MBTOWC_A                      = 0x675
+	SYS___MBTOWC_ISO1                   = 0x676
+	SYS___MBTOWC_SBCS                   = 0x677
+	SYS___MBTOWC_MBCS                   = 0x678
+	SYS___MBTOWC_UTF                    = 0x679
+	SYS___CSID_A                        = 0x680
+	SYS___CSID_STD_A                    = 0x681
+	SYS___WCSID_A                       = 0x682
+	SYS___WCSID_STD_A                   = 0x683
+	SYS___WCTOMB_A                      = 0x684
+	SYS___WCTOMB_ISO1                   = 0x685
+	SYS___WCTOMB_STD_A                  = 0x686
+	SYS___WCTOMB_UTF                    = 0x687
+	SYS___WCWIDTH_A                     = 0x688
+	SYS___GETGRNAM_R_A                  = 0x689
+	SYS___READDIR_R_A                   = 0x690
+	SYS___E2A_S                         = 0x691
+	SYS___FNMATCH_A                     = 0x692
+	SYS___FNMATCH_C_A                   = 0x693
+	SYS___EXECL_A                       = 0x694
+	SYS___FNMATCH_STD_A                 = 0x695
+	SYS___REGCOMP_A                     = 0x696
+	SYS___REGCOMP_STD_A                 = 0x697
+	SYS___REGERROR_A                    = 0x698
+	SYS___REGERROR_STD_A                = 0x699
+	SYS___SWPRINTF_A                    = 0x700
+	SYS___FSCANF_A                      = 0x701
+	SYS___SCANF_A                       = 0x702
+	SYS___SSCANF_A                      = 0x703
+	SYS___SWSCANF_A                     = 0x704
+	SYS___ATOF_A                        = 0x705
+	SYS___ATOI_A                        = 0x706
+	SYS___ATOL_A                        = 0x707
+	SYS___STRTOD_A                      = 0x708
+	SYS___STRTOL_A                      = 0x709
+	SYS___L64A_A                        = 0x710
+	SYS___STRERROR_A                    = 0x711
+	SYS___PERROR_A                      = 0x712
+	SYS___FETCH_A                       = 0x713
+	SYS___GETENV_A                      = 0x714
+	SYS___MKSTEMP_A                     = 0x717
+	SYS___PTSNAME_A                     = 0x718
+	SYS___PUTENV_A                      = 0x719
+	SYS___CHDIR_A                       = 0x720
+	SYS___CHOWN_A                       = 0x721
+	SYS___CHROOT_A                      = 0x722
+	SYS___GETCWD_A                      = 0x723
+	SYS___GETWD_A                       = 0x724
+	SYS___LCHOWN_A                      = 0x725
+	SYS___LINK_A                        = 0x726
+	SYS___PATHCONF_A                    = 0x727
+	SYS___IF_NAMEINDEX_A                = 0x728
+	SYS___READLINK_A                    = 0x729
+	SYS___EXTLINK_NP_A                  = 0x730
+	SYS___ISALNUM_A                     = 0x731
+	SYS___ISALPHA_A                     = 0x732
+	SYS___A2E_S                         = 0x733
+	SYS___ISCNTRL_A                     = 0x734
+	SYS___ISDIGIT_A                     = 0x735
+	SYS___ISGRAPH_A                     = 0x736
+	SYS___ISLOWER_A                     = 0x737
+	SYS___ISPRINT_A                     = 0x738
+	SYS___ISPUNCT_A                     = 0x739
+	SYS___ISWALPHA_A                    = 0x740
+	SYS___A2E_L                         = 0x741
+	SYS___ISWCNTRL_A                    = 0x742
+	SYS___ISWDIGIT_A                    = 0x743
+	SYS___ISWGRAPH_A                    = 0x744
+	SYS___ISWLOWER_A                    = 0x745
+	SYS___ISWPRINT_A                    = 0x746
+	SYS___ISWPUNCT_A                    = 0x747
+	SYS___ISWSPACE_A                    = 0x748
+	SYS___ISWUPPER_A                    = 0x749
+	SYS___REMOVE_A                      = 0x750
+	SYS___RENAME_A                      = 0x751
+	SYS___TMPNAM_A                      = 0x752
+	SYS___FOPEN_A                       = 0x753
+	SYS___FREOPEN_A                     = 0x754
+	SYS___CUSERID_A                     = 0x755
+	SYS___POPEN_A                       = 0x756
+	SYS___TEMPNAM_A                     = 0x757
+	SYS___FTW_A                         = 0x758
+	SYS___GETGRENT_A                    = 0x759
+	SYS___INET_NTOP_A                   = 0x760
+	SYS___GETPASS_A                     = 0x761
+	SYS___GETPWENT_A                    = 0x762
+	SYS___GETPWNAM_A                    = 0x763
+	SYS___GETPWUID_A                    = 0x764
+	SYS_____CHECK_RESOURCE_AUTH_NP_A    = 0x765
+	SYS___CHECKSCHENV_A                 = 0x766
+	SYS___CONNECTSERVER_A               = 0x767
+	SYS___CONNECTWORKMGR_A              = 0x768
+	SYS_____CONSOLE_A                   = 0x769
+	SYS___MSGSND_A                      = 0x770
+	SYS___MSGXRCV_A                     = 0x771
+	SYS___NFTW_A                        = 0x772
+	SYS_____PASSWD_A                    = 0x773
+	SYS___PTHREAD_SECURITY_NP_A         = 0x774
+	SYS___QUERYMETRICS_A                = 0x775
+	SYS___QUERYSCHENV                   = 0x776
+	SYS___READV_A                       = 0x777
+	SYS_____SERVER_CLASSIFY_A           = 0x778
+	SYS_____SERVER_INIT_A               = 0x779
+	SYS___W_GETPSENT_A                  = 0x780
+	SYS___WRITEV_A                      = 0x781
+	SYS___W_STATFS_A                    = 0x782
+	SYS___W_STATVFS_A                   = 0x783
+	SYS___FPUTC_A                       = 0x784
+	SYS___PUTCHAR_A                     = 0x785
+	SYS___PUTS_A                        = 0x786
+	SYS___FGETS_A                       = 0x787
+	SYS___GETS_A                        = 0x788
+	SYS___FPUTS_A                       = 0x789
+	SYS___PUTC_A                        = 0x790
+	SYS___AE_THREAD_SETMODE             = 0x791
+	SYS___AE_THREAD_SWAPMODE            = 0x792
+	SYS___GETNETBYADDR_A                = 0x793
+	SYS___GETNETBYNAME_A                = 0x794
+	SYS___GETNETENT_A                   = 0x795
+	SYS___GETPROTOBYNAME_A              = 0x796
+	SYS___GETPROTOBYNUMBER_A            = 0x797
+	SYS___GETPROTOENT_A                 = 0x798
+	SYS___GETSERVBYNAME_A               = 0x799
+	SYS_ACL_FIRST_ENTRY                 = 0x800
+	SYS_ACL_GET_ENTRY                   = 0x801
+	SYS_ACL_VALID                       = 0x802
+	SYS_ACL_CREATE_ENTRY                = 0x803
+	SYS_ACL_DELETE_ENTRY                = 0x804
+	SYS_ACL_UPDATE_ENTRY                = 0x805
+	SYS_ACL_DELETE_FD                   = 0x806
+	SYS_ACL_DELETE_FILE                 = 0x807
+	SYS_ACL_GET_FD                      = 0x808
+	SYS_ACL_GET_FILE                    = 0x809
+	SYS___ERFL_B                        = 0x810
+	SYS___ERFCL_B                       = 0x811
+	SYS___LGAMMAL_B                     = 0x812
+	SYS___SETHOOKEVENTS                 = 0x813
+	SYS_IF_NAMETOINDEX                  = 0x814
+	SYS_IF_INDEXTONAME                  = 0x815
+	SYS_IF_NAMEINDEX                    = 0x816
+	SYS_IF_FREENAMEINDEX                = 0x817
+	SYS_GETADDRINFO                     = 0x818
+	SYS_GETNAMEINFO                     = 0x819
+	SYS___DYNFREE_A                     = 0x820
+	SYS___RES_QUERY_A                   = 0x821
+	SYS___RES_SEARCH_A                  = 0x822
+	SYS___RES_QUERYDOMAIN_A             = 0x823
+	SYS___RES_MKQUERY_A                 = 0x824
+	SYS___RES_SEND_A                    = 0x825
+	SYS___DN_EXPAND_A                   = 0x826
+	SYS___DN_SKIPNAME_A                 = 0x827
+	SYS___DN_COMP_A                     = 0x828
+	SYS___DN_FIND_A                     = 0x829
+	SYS___INET_NTOA_A                   = 0x830
+	SYS___INET_NETWORK_A                = 0x831
+	SYS___ACCEPT_A                      = 0x832
+	SYS___ACCEPT_AND_RECV_A             = 0x833
+	SYS___BIND_A                        = 0x834
+	SYS___CONNECT_A                     = 0x835
+	SYS___GETPEERNAME_A                 = 0x836
+	SYS___GETSOCKNAME_A                 = 0x837
+	SYS___RECVFROM_A                    = 0x838
+	SYS___SENDTO_A                      = 0x839
+	SYS___LCHATTR                       = 0x840
+	SYS___WRITEDOWN                     = 0x841
+	SYS_PTHREAD_MUTEX_INIT2             = 0x842
+	SYS___ACOSHF_B                      = 0x843
+	SYS___ACOSHL_B                      = 0x844
+	SYS___ASINHF_B                      = 0x845
+	SYS___ASINHL_B                      = 0x846
+	SYS___ATANHF_B                      = 0x847
+	SYS___ATANHL_B                      = 0x848
+	SYS___CBRTF_B                       = 0x849
+	SYS___EXP2F_B                       = 0x850
+	SYS___EXP2L_B                       = 0x851
+	SYS___EXPM1F_B                      = 0x852
+	SYS___EXPM1L_B                      = 0x853
+	SYS___FDIMF_B                       = 0x854
+	SYS___FDIM_B                        = 0x855
+	SYS___FDIML_B                       = 0x856
+	SYS___HYPOTF_B                      = 0x857
+	SYS___HYPOTL_B                      = 0x858
+	SYS___LOG1PF_B                      = 0x859
+	SYS___REMQUOF_B                     = 0x860
+	SYS___REMQUO_B                      = 0x861
+	SYS___REMQUOL_B                     = 0x862
+	SYS___TGAMMAF_B                     = 0x863
+	SYS___TGAMMA_B                      = 0x864
+	SYS___TGAMMAL_B                     = 0x865
+	SYS___TRUNCF_B                      = 0x866
+	SYS___TRUNC_B                       = 0x867
+	SYS___TRUNCL_B                      = 0x868
+	SYS___LGAMMAF_B                     = 0x869
+	SYS_ASINHF                          = 0x870
+	SYS_ASINHL                          = 0x871
+	SYS_ATANHF                          = 0x872
+	SYS_ATANHL                          = 0x873
+	SYS_CBRTF                           = 0x874
+	SYS_CBRTL                           = 0x875
+	SYS_COPYSIGNF                       = 0x876
+	SYS_CPYSIGNF                        = 0x876
+	SYS_COPYSIGNL                       = 0x877
+	SYS_CPYSIGNL                        = 0x877
+	SYS_COTANF                          = 0x878
+	SYS___COTANF                        = 0x878
+	SYS_COTAN                           = 0x879
+	SYS___COTAN                         = 0x879
+	SYS_FDIM                            = 0x881
+	SYS_FDIML                           = 0x882
+	SYS_HYPOTF                          = 0x883
+	SYS_HYPOTL                          = 0x884
+	SYS_LOG1PF                          = 0x885
+	SYS_LOG1PL                          = 0x886
+	SYS_LOG2F                           = 0x887
+	SYS_LOG2                            = 0x888
+	SYS_LOG2L                           = 0x889
+	SYS_TGAMMA                          = 0x890
+	SYS_TGAMMAL                         = 0x891
+	SYS_TRUNCF                          = 0x892
+	SYS_TRUNC                           = 0x893
+	SYS_TRUNCL                          = 0x894
+	SYS_LGAMMAF                         = 0x895
+	SYS_LGAMMAL                         = 0x896
+	SYS_LROUNDF                         = 0x897
+	SYS_LROUND                          = 0x898
+	SYS_ERFF                            = 0x899
+	SYS___COSHF_H                       = 0x900
+	SYS___COSHL_H                       = 0x901
+	SYS___COTAN_H                       = 0x902
+	SYS___COTANF_H                      = 0x903
+	SYS___COTANL_H                      = 0x904
+	SYS___ERF_H                         = 0x905
+	SYS___ERFF_H                        = 0x906
+	SYS___ERFL_H                        = 0x907
+	SYS___ERFC_H                        = 0x908
+	SYS___ERFCF_H                       = 0x909
+	SYS___FDIMF_H                       = 0x910
+	SYS___FDIML_H                       = 0x911
+	SYS___FMOD_H                        = 0x912
+	SYS___FMODF_H                       = 0x913
+	SYS___FMODL_H                       = 0x914
+	SYS___GAMMA_H                       = 0x915
+	SYS___HYPOT_H                       = 0x916
+	SYS___ILOGB_H                       = 0x917
+	SYS___LGAMMA_H                      = 0x918
+	SYS___LGAMMAF_H                     = 0x919
+	SYS___LOG2L_H                       = 0x920
+	SYS___LOG1P_H                       = 0x921
+	SYS___LOG10_H                       = 0x922
+	SYS___LOG10F_H                      = 0x923
+	SYS___LOG10L_H                      = 0x924
+	SYS___LROUND_H                      = 0x925
+	SYS___LROUNDF_H                     = 0x926
+	SYS___NEXTAFTER_H                   = 0x927
+	SYS___POW_H                         = 0x928
+	SYS___POWF_H                        = 0x929
+	SYS___SINL_H                        = 0x930
+	SYS___SINH_H                        = 0x931
+	SYS___SINHF_H                       = 0x932
+	SYS___SINHL_H                       = 0x933
+	SYS___SQRT_H                        = 0x934
+	SYS___SQRTF_H                       = 0x935
+	SYS___SQRTL_H                       = 0x936
+	SYS___TAN_H                         = 0x937
+	SYS___TANF_H                        = 0x938
+	SYS___TANL_H                        = 0x939
+	SYS___TRUNCF_H                      = 0x940
+	SYS___TRUNCL_H                      = 0x941
+	SYS___COSH_H                        = 0x942
+	SYS___LE_DEBUG_SET_RESUME_MCH       = 0x943
+	SYS_VFSCANF                         = 0x944
+	SYS_VSCANF                          = 0x946
+	SYS_VSSCANF                         = 0x948
+	SYS_IMAXABS                         = 0x950
+	SYS_IMAXDIV                         = 0x951
+	SYS_STRTOIMAX                       = 0x952
+	SYS_STRTOUMAX                       = 0x953
+	SYS_WCSTOIMAX                       = 0x954
+	SYS_WCSTOUMAX                       = 0x955
+	SYS_ATOLL                           = 0x956
+	SYS_STRTOF                          = 0x957
+	SYS_STRTOLD                         = 0x958
+	SYS_WCSTOF                          = 0x959
+	SYS_INET6_RTH_GETADDR               = 0x960
+	SYS_INET6_OPT_INIT                  = 0x961
+	SYS_INET6_OPT_APPEND                = 0x962
+	SYS_INET6_OPT_FINISH                = 0x963
+	SYS_INET6_OPT_SET_VAL               = 0x964
+	SYS_INET6_OPT_NEXT                  = 0x965
+	SYS_INET6_OPT_FIND                  = 0x966
+	SYS_INET6_OPT_GET_VAL               = 0x967
+	SYS___POW_I                         = 0x987
+	SYS___POW_I_B                       = 0x988
+	SYS___POW_I_H                       = 0x989
+	SYS___CABS_H                        = 0x990
+	SYS_CABSF                           = 0x991
+	SYS___CABSF_B                       = 0x992
+	SYS___CABSF_H                       = 0x993
+	SYS_CABSL                           = 0x994
+	SYS___CABSL_B                       = 0x995
+	SYS___CABSL_H                       = 0x996
+	SYS_CACOS                           = 0x997
+	SYS___CACOS_B                       = 0x998
+	SYS___CACOS_H                       = 0x999
+)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_aix_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_aix_ppc.go
index 2c1f815..7a8161c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_aix_ppc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_aix_ppc.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_aix.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build ppc && aix
 // +build ppc,aix
 
 package unix
@@ -219,6 +220,7 @@
 	SizeofSockaddrUnix     = 0x401
 	SizeofSockaddrDatalink = 0x80
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x8
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofIPv6MTUInfo      = 0x20
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go
index b4a069e..07ed733 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_aix.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build ppc64 && aix
 // +build ppc64,aix
 
 package unix
@@ -223,6 +224,7 @@
 	SizeofSockaddrUnix     = 0x401
 	SizeofSockaddrDatalink = 0x80
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofIPv6MTUInfo      = 0x20
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go
deleted file mode 100644
index 725b4be..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go
+++ /dev/null
@@ -1,516 +0,0 @@
-// cgo -godefs types_darwin.go | go run mkpost.go
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build 386,darwin
-
-package unix
-
-const (
-	SizeofPtr      = 0x4
-	SizeofShort    = 0x2
-	SizeofInt      = 0x4
-	SizeofLong     = 0x4
-	SizeofLongLong = 0x8
-)
-
-type (
-	_C_short     int16
-	_C_int       int32
-	_C_long      int32
-	_C_long_long int64
-)
-
-type Timespec struct {
-	Sec  int32
-	Nsec int32
-}
-
-type Timeval struct {
-	Sec  int32
-	Usec int32
-}
-
-type Timeval32 struct{}
-
-type Rusage struct {
-	Utime    Timeval
-	Stime    Timeval
-	Maxrss   int32
-	Ixrss    int32
-	Idrss    int32
-	Isrss    int32
-	Minflt   int32
-	Majflt   int32
-	Nswap    int32
-	Inblock  int32
-	Oublock  int32
-	Msgsnd   int32
-	Msgrcv   int32
-	Nsignals int32
-	Nvcsw    int32
-	Nivcsw   int32
-}
-
-type Rlimit struct {
-	Cur uint64
-	Max uint64
-}
-
-type _Gid_t uint32
-
-type Stat_t struct {
-	Dev     int32
-	Mode    uint16
-	Nlink   uint16
-	Ino     uint64
-	Uid     uint32
-	Gid     uint32
-	Rdev    int32
-	Atim    Timespec
-	Mtim    Timespec
-	Ctim    Timespec
-	Btim    Timespec
-	Size    int64
-	Blocks  int64
-	Blksize int32
-	Flags   uint32
-	Gen     uint32
-	Lspare  int32
-	Qspare  [2]int64
-}
-
-type Statfs_t struct {
-	Bsize       uint32
-	Iosize      int32
-	Blocks      uint64
-	Bfree       uint64
-	Bavail      uint64
-	Files       uint64
-	Ffree       uint64
-	Fsid        Fsid
-	Owner       uint32
-	Type        uint32
-	Flags       uint32
-	Fssubtype   uint32
-	Fstypename  [16]byte
-	Mntonname   [1024]byte
-	Mntfromname [1024]byte
-	Reserved    [8]uint32
-}
-
-type Flock_t struct {
-	Start  int64
-	Len    int64
-	Pid    int32
-	Type   int16
-	Whence int16
-}
-
-type Fstore_t struct {
-	Flags      uint32
-	Posmode    int32
-	Offset     int64
-	Length     int64
-	Bytesalloc int64
-}
-
-type Radvisory_t struct {
-	Offset int64
-	Count  int32
-}
-
-type Fbootstraptransfer_t struct {
-	Offset int64
-	Length uint32
-	Buffer *byte
-}
-
-type Log2phys_t struct {
-	Flags       uint32
-	Contigbytes int64
-	Devoffset   int64
-}
-
-type Fsid struct {
-	Val [2]int32
-}
-
-type Dirent struct {
-	Ino     uint64
-	Seekoff uint64
-	Reclen  uint16
-	Namlen  uint16
-	Type    uint8
-	Name    [1024]int8
-	_       [3]byte
-}
-
-const (
-	PathMax = 0x400
-)
-
-type RawSockaddrInet4 struct {
-	Len    uint8
-	Family uint8
-	Port   uint16
-	Addr   [4]byte /* in_addr */
-	Zero   [8]int8
-}
-
-type RawSockaddrInet6 struct {
-	Len      uint8
-	Family   uint8
-	Port     uint16
-	Flowinfo uint32
-	Addr     [16]byte /* in6_addr */
-	Scope_id uint32
-}
-
-type RawSockaddrUnix struct {
-	Len    uint8
-	Family uint8
-	Path   [104]int8
-}
-
-type RawSockaddrDatalink struct {
-	Len    uint8
-	Family uint8
-	Index  uint16
-	Type   uint8
-	Nlen   uint8
-	Alen   uint8
-	Slen   uint8
-	Data   [12]int8
-}
-
-type RawSockaddr struct {
-	Len    uint8
-	Family uint8
-	Data   [14]int8
-}
-
-type RawSockaddrAny struct {
-	Addr RawSockaddr
-	Pad  [92]int8
-}
-
-type RawSockaddrCtl struct {
-	Sc_len      uint8
-	Sc_family   uint8
-	Ss_sysaddr  uint16
-	Sc_id       uint32
-	Sc_unit     uint32
-	Sc_reserved [5]uint32
-}
-
-type _Socklen uint32
-
-type Linger struct {
-	Onoff  int32
-	Linger int32
-}
-
-type Iovec struct {
-	Base *byte
-	Len  uint32
-}
-
-type IPMreq struct {
-	Multiaddr [4]byte /* in_addr */
-	Interface [4]byte /* in_addr */
-}
-
-type IPv6Mreq struct {
-	Multiaddr [16]byte /* in6_addr */
-	Interface uint32
-}
-
-type Msghdr struct {
-	Name       *byte
-	Namelen    uint32
-	Iov        *Iovec
-	Iovlen     int32
-	Control    *byte
-	Controllen uint32
-	Flags      int32
-}
-
-type Cmsghdr struct {
-	Len   uint32
-	Level int32
-	Type  int32
-}
-
-type Inet4Pktinfo struct {
-	Ifindex  uint32
-	Spec_dst [4]byte /* in_addr */
-	Addr     [4]byte /* in_addr */
-}
-
-type Inet6Pktinfo struct {
-	Addr    [16]byte /* in6_addr */
-	Ifindex uint32
-}
-
-type IPv6MTUInfo struct {
-	Addr RawSockaddrInet6
-	Mtu  uint32
-}
-
-type ICMPv6Filter struct {
-	Filt [8]uint32
-}
-
-const (
-	SizeofSockaddrInet4    = 0x10
-	SizeofSockaddrInet6    = 0x1c
-	SizeofSockaddrAny      = 0x6c
-	SizeofSockaddrUnix     = 0x6a
-	SizeofSockaddrDatalink = 0x14
-	SizeofSockaddrCtl      = 0x20
-	SizeofLinger           = 0x8
-	SizeofIovec            = 0x8
-	SizeofIPMreq           = 0x8
-	SizeofIPv6Mreq         = 0x14
-	SizeofMsghdr           = 0x1c
-	SizeofCmsghdr          = 0xc
-	SizeofInet4Pktinfo     = 0xc
-	SizeofInet6Pktinfo     = 0x14
-	SizeofIPv6MTUInfo      = 0x20
-	SizeofICMPv6Filter     = 0x20
-)
-
-const (
-	PTRACE_TRACEME = 0x0
-	PTRACE_CONT    = 0x7
-	PTRACE_KILL    = 0x8
-)
-
-type Kevent_t struct {
-	Ident  uint32
-	Filter int16
-	Flags  uint16
-	Fflags uint32
-	Data   int32
-	Udata  *byte
-}
-
-type FdSet struct {
-	Bits [32]int32
-}
-
-const (
-	SizeofIfMsghdr    = 0x70
-	SizeofIfData      = 0x60
-	SizeofIfaMsghdr   = 0x14
-	SizeofIfmaMsghdr  = 0x10
-	SizeofIfmaMsghdr2 = 0x14
-	SizeofRtMsghdr    = 0x5c
-	SizeofRtMetrics   = 0x38
-)
-
-type IfMsghdr struct {
-	Msglen  uint16
-	Version uint8
-	Type    uint8
-	Addrs   int32
-	Flags   int32
-	Index   uint16
-	Data    IfData
-}
-
-type IfData struct {
-	Type       uint8
-	Typelen    uint8
-	Physical   uint8
-	Addrlen    uint8
-	Hdrlen     uint8
-	Recvquota  uint8
-	Xmitquota  uint8
-	Unused1    uint8
-	Mtu        uint32
-	Metric     uint32
-	Baudrate   uint32
-	Ipackets   uint32
-	Ierrors    uint32
-	Opackets   uint32
-	Oerrors    uint32
-	Collisions uint32
-	Ibytes     uint32
-	Obytes     uint32
-	Imcasts    uint32
-	Omcasts    uint32
-	Iqdrops    uint32
-	Noproto    uint32
-	Recvtiming uint32
-	Xmittiming uint32
-	Lastchange Timeval
-	Unused2    uint32
-	Hwassist   uint32
-	Reserved1  uint32
-	Reserved2  uint32
-}
-
-type IfaMsghdr struct {
-	Msglen  uint16
-	Version uint8
-	Type    uint8
-	Addrs   int32
-	Flags   int32
-	Index   uint16
-	Metric  int32
-}
-
-type IfmaMsghdr struct {
-	Msglen  uint16
-	Version uint8
-	Type    uint8
-	Addrs   int32
-	Flags   int32
-	Index   uint16
-	_       [2]byte
-}
-
-type IfmaMsghdr2 struct {
-	Msglen   uint16
-	Version  uint8
-	Type     uint8
-	Addrs    int32
-	Flags    int32
-	Index    uint16
-	Refcount int32
-}
-
-type RtMsghdr struct {
-	Msglen  uint16
-	Version uint8
-	Type    uint8
-	Index   uint16
-	Flags   int32
-	Addrs   int32
-	Pid     int32
-	Seq     int32
-	Errno   int32
-	Use     int32
-	Inits   uint32
-	Rmx     RtMetrics
-}
-
-type RtMetrics struct {
-	Locks    uint32
-	Mtu      uint32
-	Hopcount uint32
-	Expire   int32
-	Recvpipe uint32
-	Sendpipe uint32
-	Ssthresh uint32
-	Rtt      uint32
-	Rttvar   uint32
-	Pksent   uint32
-	State    uint32
-	Filler   [3]uint32
-}
-
-const (
-	SizeofBpfVersion = 0x4
-	SizeofBpfStat    = 0x8
-	SizeofBpfProgram = 0x8
-	SizeofBpfInsn    = 0x8
-	SizeofBpfHdr     = 0x14
-)
-
-type BpfVersion struct {
-	Major uint16
-	Minor uint16
-}
-
-type BpfStat struct {
-	Recv uint32
-	Drop uint32
-}
-
-type BpfProgram struct {
-	Len   uint32
-	Insns *BpfInsn
-}
-
-type BpfInsn struct {
-	Code uint16
-	Jt   uint8
-	Jf   uint8
-	K    uint32
-}
-
-type BpfHdr struct {
-	Tstamp  Timeval
-	Caplen  uint32
-	Datalen uint32
-	Hdrlen  uint16
-	_       [2]byte
-}
-
-type Termios struct {
-	Iflag  uint32
-	Oflag  uint32
-	Cflag  uint32
-	Lflag  uint32
-	Cc     [20]uint8
-	Ispeed uint32
-	Ospeed uint32
-}
-
-type Winsize struct {
-	Row    uint16
-	Col    uint16
-	Xpixel uint16
-	Ypixel uint16
-}
-
-const (
-	AT_FDCWD            = -0x2
-	AT_REMOVEDIR        = 0x80
-	AT_SYMLINK_FOLLOW   = 0x40
-	AT_SYMLINK_NOFOLLOW = 0x20
-)
-
-type PollFd struct {
-	Fd      int32
-	Events  int16
-	Revents int16
-}
-
-const (
-	POLLERR    = 0x8
-	POLLHUP    = 0x10
-	POLLIN     = 0x1
-	POLLNVAL   = 0x20
-	POLLOUT    = 0x4
-	POLLPRI    = 0x2
-	POLLRDBAND = 0x80
-	POLLRDNORM = 0x40
-	POLLWRBAND = 0x100
-	POLLWRNORM = 0x4
-)
-
-type Utsname struct {
-	Sysname  [256]byte
-	Nodename [256]byte
-	Release  [256]byte
-	Version  [256]byte
-	Machine  [256]byte
-}
-
-const SizeofClockinfo = 0x14
-
-type Clockinfo struct {
-	Hz      int32
-	Tick    int32
-	Tickadj int32
-	Stathz  int32
-	Profhz  int32
-}
-
-type CtlInfo struct {
-	Id   uint32
-	Name [96]byte
-}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go
index 080ffce..2673e6c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_darwin.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && darwin
 // +build amd64,darwin
 
 package unix
@@ -210,6 +211,13 @@
 
 type _Socklen uint32
 
+type Xucred struct {
+	Version uint32
+	Uid     uint32
+	Ngroups int16
+	Groups  [16]uint32
+}
+
 type Linger struct {
 	Onoff  int32
 	Linger int32
@@ -225,6 +233,12 @@
 	Interface [4]byte /* in_addr */
 }
 
+type IPMreqn struct {
+	Multiaddr [4]byte /* in_addr */
+	Address   [4]byte /* in_addr */
+	Ifindex   int32
+}
+
 type IPv6Mreq struct {
 	Multiaddr [16]byte /* in6_addr */
 	Interface uint32
@@ -273,9 +287,11 @@
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x14
 	SizeofSockaddrCtl      = 0x20
+	SizeofXucred           = 0x4c
 	SizeofLinger           = 0x8
 	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
+	SizeofIPMreqn          = 0xc
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x30
 	SizeofCmsghdr          = 0xc
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go
deleted file mode 100644
index f2a77bc..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go
+++ /dev/null
@@ -1,516 +0,0 @@
-// cgo -godefs types_darwin.go | go run mkpost.go
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build arm,darwin
-
-package unix
-
-const (
-	SizeofPtr      = 0x4
-	SizeofShort    = 0x2
-	SizeofInt      = 0x4
-	SizeofLong     = 0x4
-	SizeofLongLong = 0x8
-)
-
-type (
-	_C_short     int16
-	_C_int       int32
-	_C_long      int32
-	_C_long_long int64
-)
-
-type Timespec struct {
-	Sec  int32
-	Nsec int32
-}
-
-type Timeval struct {
-	Sec  int32
-	Usec int32
-}
-
-type Timeval32 struct{}
-
-type Rusage struct {
-	Utime    Timeval
-	Stime    Timeval
-	Maxrss   int32
-	Ixrss    int32
-	Idrss    int32
-	Isrss    int32
-	Minflt   int32
-	Majflt   int32
-	Nswap    int32
-	Inblock  int32
-	Oublock  int32
-	Msgsnd   int32
-	Msgrcv   int32
-	Nsignals int32
-	Nvcsw    int32
-	Nivcsw   int32
-}
-
-type Rlimit struct {
-	Cur uint64
-	Max uint64
-}
-
-type _Gid_t uint32
-
-type Stat_t struct {
-	Dev     int32
-	Mode    uint16
-	Nlink   uint16
-	Ino     uint64
-	Uid     uint32
-	Gid     uint32
-	Rdev    int32
-	Atim    Timespec
-	Mtim    Timespec
-	Ctim    Timespec
-	Btim    Timespec
-	Size    int64
-	Blocks  int64
-	Blksize int32
-	Flags   uint32
-	Gen     uint32
-	Lspare  int32
-	Qspare  [2]int64
-}
-
-type Statfs_t struct {
-	Bsize       uint32
-	Iosize      int32
-	Blocks      uint64
-	Bfree       uint64
-	Bavail      uint64
-	Files       uint64
-	Ffree       uint64
-	Fsid        Fsid
-	Owner       uint32
-	Type        uint32
-	Flags       uint32
-	Fssubtype   uint32
-	Fstypename  [16]byte
-	Mntonname   [1024]byte
-	Mntfromname [1024]byte
-	Reserved    [8]uint32
-}
-
-type Flock_t struct {
-	Start  int64
-	Len    int64
-	Pid    int32
-	Type   int16
-	Whence int16
-}
-
-type Fstore_t struct {
-	Flags      uint32
-	Posmode    int32
-	Offset     int64
-	Length     int64
-	Bytesalloc int64
-}
-
-type Radvisory_t struct {
-	Offset int64
-	Count  int32
-}
-
-type Fbootstraptransfer_t struct {
-	Offset int64
-	Length uint32
-	Buffer *byte
-}
-
-type Log2phys_t struct {
-	Flags       uint32
-	Contigbytes int64
-	Devoffset   int64
-}
-
-type Fsid struct {
-	Val [2]int32
-}
-
-type Dirent struct {
-	Ino     uint64
-	Seekoff uint64
-	Reclen  uint16
-	Namlen  uint16
-	Type    uint8
-	Name    [1024]int8
-	_       [3]byte
-}
-
-const (
-	PathMax = 0x400
-)
-
-type RawSockaddrInet4 struct {
-	Len    uint8
-	Family uint8
-	Port   uint16
-	Addr   [4]byte /* in_addr */
-	Zero   [8]int8
-}
-
-type RawSockaddrInet6 struct {
-	Len      uint8
-	Family   uint8
-	Port     uint16
-	Flowinfo uint32
-	Addr     [16]byte /* in6_addr */
-	Scope_id uint32
-}
-
-type RawSockaddrUnix struct {
-	Len    uint8
-	Family uint8
-	Path   [104]int8
-}
-
-type RawSockaddrDatalink struct {
-	Len    uint8
-	Family uint8
-	Index  uint16
-	Type   uint8
-	Nlen   uint8
-	Alen   uint8
-	Slen   uint8
-	Data   [12]int8
-}
-
-type RawSockaddr struct {
-	Len    uint8
-	Family uint8
-	Data   [14]int8
-}
-
-type RawSockaddrAny struct {
-	Addr RawSockaddr
-	Pad  [92]int8
-}
-
-type RawSockaddrCtl struct {
-	Sc_len      uint8
-	Sc_family   uint8
-	Ss_sysaddr  uint16
-	Sc_id       uint32
-	Sc_unit     uint32
-	Sc_reserved [5]uint32
-}
-
-type _Socklen uint32
-
-type Linger struct {
-	Onoff  int32
-	Linger int32
-}
-
-type Iovec struct {
-	Base *byte
-	Len  uint32
-}
-
-type IPMreq struct {
-	Multiaddr [4]byte /* in_addr */
-	Interface [4]byte /* in_addr */
-}
-
-type IPv6Mreq struct {
-	Multiaddr [16]byte /* in6_addr */
-	Interface uint32
-}
-
-type Msghdr struct {
-	Name       *byte
-	Namelen    uint32
-	Iov        *Iovec
-	Iovlen     int32
-	Control    *byte
-	Controllen uint32
-	Flags      int32
-}
-
-type Cmsghdr struct {
-	Len   uint32
-	Level int32
-	Type  int32
-}
-
-type Inet4Pktinfo struct {
-	Ifindex  uint32
-	Spec_dst [4]byte /* in_addr */
-	Addr     [4]byte /* in_addr */
-}
-
-type Inet6Pktinfo struct {
-	Addr    [16]byte /* in6_addr */
-	Ifindex uint32
-}
-
-type IPv6MTUInfo struct {
-	Addr RawSockaddrInet6
-	Mtu  uint32
-}
-
-type ICMPv6Filter struct {
-	Filt [8]uint32
-}
-
-const (
-	SizeofSockaddrInet4    = 0x10
-	SizeofSockaddrInet6    = 0x1c
-	SizeofSockaddrAny      = 0x6c
-	SizeofSockaddrUnix     = 0x6a
-	SizeofSockaddrDatalink = 0x14
-	SizeofSockaddrCtl      = 0x20
-	SizeofLinger           = 0x8
-	SizeofIovec            = 0x8
-	SizeofIPMreq           = 0x8
-	SizeofIPv6Mreq         = 0x14
-	SizeofMsghdr           = 0x1c
-	SizeofCmsghdr          = 0xc
-	SizeofInet4Pktinfo     = 0xc
-	SizeofInet6Pktinfo     = 0x14
-	SizeofIPv6MTUInfo      = 0x20
-	SizeofICMPv6Filter     = 0x20
-)
-
-const (
-	PTRACE_TRACEME = 0x0
-	PTRACE_CONT    = 0x7
-	PTRACE_KILL    = 0x8
-)
-
-type Kevent_t struct {
-	Ident  uint32
-	Filter int16
-	Flags  uint16
-	Fflags uint32
-	Data   int32
-	Udata  *byte
-}
-
-type FdSet struct {
-	Bits [32]int32
-}
-
-const (
-	SizeofIfMsghdr    = 0x70
-	SizeofIfData      = 0x60
-	SizeofIfaMsghdr   = 0x14
-	SizeofIfmaMsghdr  = 0x10
-	SizeofIfmaMsghdr2 = 0x14
-	SizeofRtMsghdr    = 0x5c
-	SizeofRtMetrics   = 0x38
-)
-
-type IfMsghdr struct {
-	Msglen  uint16
-	Version uint8
-	Type    uint8
-	Addrs   int32
-	Flags   int32
-	Index   uint16
-	Data    IfData
-}
-
-type IfData struct {
-	Type       uint8
-	Typelen    uint8
-	Physical   uint8
-	Addrlen    uint8
-	Hdrlen     uint8
-	Recvquota  uint8
-	Xmitquota  uint8
-	Unused1    uint8
-	Mtu        uint32
-	Metric     uint32
-	Baudrate   uint32
-	Ipackets   uint32
-	Ierrors    uint32
-	Opackets   uint32
-	Oerrors    uint32
-	Collisions uint32
-	Ibytes     uint32
-	Obytes     uint32
-	Imcasts    uint32
-	Omcasts    uint32
-	Iqdrops    uint32
-	Noproto    uint32
-	Recvtiming uint32
-	Xmittiming uint32
-	Lastchange Timeval
-	Unused2    uint32
-	Hwassist   uint32
-	Reserved1  uint32
-	Reserved2  uint32
-}
-
-type IfaMsghdr struct {
-	Msglen  uint16
-	Version uint8
-	Type    uint8
-	Addrs   int32
-	Flags   int32
-	Index   uint16
-	Metric  int32
-}
-
-type IfmaMsghdr struct {
-	Msglen  uint16
-	Version uint8
-	Type    uint8
-	Addrs   int32
-	Flags   int32
-	Index   uint16
-	_       [2]byte
-}
-
-type IfmaMsghdr2 struct {
-	Msglen   uint16
-	Version  uint8
-	Type     uint8
-	Addrs    int32
-	Flags    int32
-	Index    uint16
-	Refcount int32
-}
-
-type RtMsghdr struct {
-	Msglen  uint16
-	Version uint8
-	Type    uint8
-	Index   uint16
-	Flags   int32
-	Addrs   int32
-	Pid     int32
-	Seq     int32
-	Errno   int32
-	Use     int32
-	Inits   uint32
-	Rmx     RtMetrics
-}
-
-type RtMetrics struct {
-	Locks    uint32
-	Mtu      uint32
-	Hopcount uint32
-	Expire   int32
-	Recvpipe uint32
-	Sendpipe uint32
-	Ssthresh uint32
-	Rtt      uint32
-	Rttvar   uint32
-	Pksent   uint32
-	State    uint32
-	Filler   [3]uint32
-}
-
-const (
-	SizeofBpfVersion = 0x4
-	SizeofBpfStat    = 0x8
-	SizeofBpfProgram = 0x8
-	SizeofBpfInsn    = 0x8
-	SizeofBpfHdr     = 0x14
-)
-
-type BpfVersion struct {
-	Major uint16
-	Minor uint16
-}
-
-type BpfStat struct {
-	Recv uint32
-	Drop uint32
-}
-
-type BpfProgram struct {
-	Len   uint32
-	Insns *BpfInsn
-}
-
-type BpfInsn struct {
-	Code uint16
-	Jt   uint8
-	Jf   uint8
-	K    uint32
-}
-
-type BpfHdr struct {
-	Tstamp  Timeval
-	Caplen  uint32
-	Datalen uint32
-	Hdrlen  uint16
-	_       [2]byte
-}
-
-type Termios struct {
-	Iflag  uint32
-	Oflag  uint32
-	Cflag  uint32
-	Lflag  uint32
-	Cc     [20]uint8
-	Ispeed uint32
-	Ospeed uint32
-}
-
-type Winsize struct {
-	Row    uint16
-	Col    uint16
-	Xpixel uint16
-	Ypixel uint16
-}
-
-const (
-	AT_FDCWD            = -0x2
-	AT_REMOVEDIR        = 0x80
-	AT_SYMLINK_FOLLOW   = 0x40
-	AT_SYMLINK_NOFOLLOW = 0x20
-)
-
-type PollFd struct {
-	Fd      int32
-	Events  int16
-	Revents int16
-}
-
-const (
-	POLLERR    = 0x8
-	POLLHUP    = 0x10
-	POLLIN     = 0x1
-	POLLNVAL   = 0x20
-	POLLOUT    = 0x4
-	POLLPRI    = 0x2
-	POLLRDBAND = 0x80
-	POLLRDNORM = 0x40
-	POLLWRBAND = 0x100
-	POLLWRNORM = 0x4
-)
-
-type Utsname struct {
-	Sysname  [256]byte
-	Nodename [256]byte
-	Release  [256]byte
-	Version  [256]byte
-	Machine  [256]byte
-}
-
-const SizeofClockinfo = 0x14
-
-type Clockinfo struct {
-	Hz      int32
-	Tick    int32
-	Tickadj int32
-	Stathz  int32
-	Profhz  int32
-}
-
-type CtlInfo struct {
-	Id   uint32
-	Name [96]byte
-}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go
index c949242..1465cbc 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_darwin.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && darwin
 // +build arm64,darwin
 
 package unix
@@ -210,6 +211,13 @@
 
 type _Socklen uint32
 
+type Xucred struct {
+	Version uint32
+	Uid     uint32
+	Ngroups int16
+	Groups  [16]uint32
+}
+
 type Linger struct {
 	Onoff  int32
 	Linger int32
@@ -225,6 +233,12 @@
 	Interface [4]byte /* in_addr */
 }
 
+type IPMreqn struct {
+	Multiaddr [4]byte /* in_addr */
+	Address   [4]byte /* in_addr */
+	Ifindex   int32
+}
+
 type IPv6Mreq struct {
 	Multiaddr [16]byte /* in6_addr */
 	Interface uint32
@@ -273,9 +287,11 @@
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x14
 	SizeofSockaddrCtl      = 0x20
+	SizeofXucred           = 0x4c
 	SizeofLinger           = 0x8
 	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
+	SizeofIPMreqn          = 0xc
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x30
 	SizeofCmsghdr          = 0xc
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go
index c4772df..1d049d7 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_dragonfly.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && dragonfly
 // +build amd64,dragonfly
 
 package unix
@@ -234,6 +235,7 @@
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x36
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x30
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
index 2a3ec61..c51bc88 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_freebsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build 386 && freebsd
 // +build 386,freebsd
 
 package unix
@@ -250,6 +251,14 @@
 
 type _Socklen uint32
 
+type Xucred struct {
+	Version uint32
+	Uid     uint32
+	Ngroups int16
+	Groups  [16]uint32
+	_       *byte
+}
+
 type Linger struct {
 	Onoff  int32
 	Linger int32
@@ -312,7 +321,9 @@
 	SizeofSockaddrAny      = 0x6c
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x36
+	SizeofXucred           = 0x50
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x8
 	SizeofIPMreq           = 0x8
 	SizeofIPMreqn          = 0xc
 	SizeofIPv6Mreq         = 0x14
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
index e11e954..395b691 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_freebsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && freebsd
 // +build amd64,freebsd
 
 package unix
@@ -246,6 +247,14 @@
 
 type _Socklen uint32
 
+type Xucred struct {
+	Version uint32
+	Uid     uint32
+	Ngroups int16
+	Groups  [16]uint32
+	_       *byte
+}
+
 type Linger struct {
 	Onoff  int32
 	Linger int32
@@ -308,7 +317,9 @@
 	SizeofSockaddrAny      = 0x6c
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x36
+	SizeofXucred           = 0x58
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
 	SizeofIPMreqn          = 0xc
 	SizeofIPv6Mreq         = 0x14
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
index b91c2ae..d3f9d25 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
@@ -1,6 +1,7 @@
 // cgo -godefs -- -fsigned-char types_freebsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm && freebsd
 // +build arm,freebsd
 
 package unix
@@ -248,6 +249,14 @@
 
 type _Socklen uint32
 
+type Xucred struct {
+	Version uint32
+	Uid     uint32
+	Ngroups int16
+	Groups  [16]uint32
+	_       *byte
+}
+
 type Linger struct {
 	Onoff  int32
 	Linger int32
@@ -310,7 +319,9 @@
 	SizeofSockaddrAny      = 0x6c
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x36
+	SizeofXucred           = 0x50
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x8
 	SizeofIPMreq           = 0x8
 	SizeofIPMreqn          = 0xc
 	SizeofIPv6Mreq         = 0x14
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go
index c6fe1d0..434d6e8 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go
@@ -1,6 +1,7 @@
 // cgo -godefs -- -fsigned-char types_freebsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && freebsd
 // +build arm64,freebsd
 
 package unix
@@ -246,6 +247,14 @@
 
 type _Socklen uint32
 
+type Xucred struct {
+	Version uint32
+	Uid     uint32
+	Ngroups int16
+	Groups  [16]uint32
+	_       *byte
+}
+
 type Linger struct {
 	Onoff  int32
 	Linger int32
@@ -308,7 +317,9 @@
 	SizeofSockaddrAny      = 0x6c
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x36
+	SizeofXucred           = 0x58
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
 	SizeofIPMreqn          = 0xc
 	SizeofIPv6Mreq         = 0x14
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go
new file mode 100644
index 0000000..236f37e
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go
@@ -0,0 +1,40 @@
+// cgo -godefs types_illumos.go | go run mkpost.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build amd64 && illumos
+// +build amd64,illumos
+
+package unix
+
+const (
+	TUNNEWPPA = 0x540001
+	TUNSETPPA = 0x540002
+
+	I_STR     = 0x5308
+	I_POP     = 0x5303
+	I_PUSH    = 0x5302
+	I_PLINK   = 0x5316
+	I_PUNLINK = 0x5317
+
+	IF_UNITSEL = -0x7ffb8cca
+)
+
+type strbuf struct {
+	Maxlen int32
+	Len    int32
+	Buf    *int8
+}
+
+type Strioctl struct {
+	Cmd    int32
+	Timout int32
+	Len    int32
+	Dp     *int8
+}
+
+type Lifreq struct {
+	Name   [32]int8
+	Lifru1 [4]byte
+	Type   uint32
+	Lifru  [336]byte
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go
index 504ef13..0873235 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go
@@ -1,5 +1,6 @@
 // Code generated by mkmerge.go; DO NOT EDIT.
 
+//go:build linux
 // +build linux
 
 package unix
@@ -83,7 +84,7 @@
 	Dest_offset uint64
 }
 
-type FileDedupeRange struct {
+type RawFileDedupeRange struct {
 	Src_offset uint64
 	Src_length uint64
 	Dest_count uint16
@@ -91,6 +92,21 @@
 	Reserved2  uint32
 }
 
+type RawFileDedupeRangeInfo struct {
+	Dest_fd       int64
+	Dest_offset   uint64
+	Bytes_deduped uint64
+	Status        int32
+	Reserved      uint32
+}
+
+const (
+	SizeofRawFileDedupeRange     = 0x18
+	SizeofRawFileDedupeRangeInfo = 0x20
+	FILE_DEDUPE_RANGE_SAME       = 0x0
+	FILE_DEDUPE_RANGE_DIFFERS    = 0x1
+)
+
 type FscryptPolicy struct {
 	Version                   uint8
 	Contents_encryption_mode  uint8
@@ -288,7 +304,8 @@
 	Reserved1 uint16
 	Port      uint32
 	Cid       uint32
-	Zero      [4]uint8
+	Flags     uint8
+	Zero      [3]uint8
 }
 
 type RawSockaddrXDP struct {
@@ -999,7 +1016,10 @@
 	PERF_SAMPLE_PHYS_ADDR                 = 0x80000
 	PERF_SAMPLE_AUX                       = 0x100000
 	PERF_SAMPLE_CGROUP                    = 0x200000
-	PERF_SAMPLE_MAX                       = 0x400000
+	PERF_SAMPLE_DATA_PAGE_SIZE            = 0x400000
+	PERF_SAMPLE_CODE_PAGE_SIZE            = 0x800000
+	PERF_SAMPLE_WEIGHT_STRUCT             = 0x1000000
+	PERF_SAMPLE_MAX                       = 0x2000000
 	PERF_SAMPLE_BRANCH_USER_SHIFT         = 0x0
 	PERF_SAMPLE_BRANCH_KERNEL_SHIFT       = 0x1
 	PERF_SAMPLE_BRANCH_HV_SHIFT           = 0x2
@@ -1381,6 +1401,11 @@
 	IFLA_PROP_LIST                             = 0x34
 	IFLA_ALT_IFNAME                            = 0x35
 	IFLA_PERM_ADDRESS                          = 0x36
+	IFLA_PROTO_DOWN_REASON                     = 0x37
+	IFLA_PROTO_DOWN_REASON_UNSPEC              = 0x0
+	IFLA_PROTO_DOWN_REASON_MASK                = 0x1
+	IFLA_PROTO_DOWN_REASON_VALUE               = 0x2
+	IFLA_PROTO_DOWN_REASON_MAX                 = 0x2
 	IFLA_INET_UNSPEC                           = 0x0
 	IFLA_INET_CONF                             = 0x1
 	IFLA_INET6_UNSPEC                          = 0x0
@@ -1475,6 +1500,7 @@
 	IFLA_BRPORT_ISOLATED                       = 0x21
 	IFLA_BRPORT_BACKUP_PORT                    = 0x22
 	IFLA_BRPORT_MRP_RING_OPEN                  = 0x23
+	IFLA_BRPORT_MRP_IN_OPEN                    = 0x24
 	IFLA_INFO_UNSPEC                           = 0x0
 	IFLA_INFO_KIND                             = 0x1
 	IFLA_INFO_DATA                             = 0x2
@@ -1673,6 +1699,7 @@
 	IFLA_HSR_SUPERVISION_ADDR                  = 0x4
 	IFLA_HSR_SEQ_NR                            = 0x5
 	IFLA_HSR_VERSION                           = 0x6
+	IFLA_HSR_PROTOCOL                          = 0x7
 	IFLA_STATS_UNSPEC                          = 0x0
 	IFLA_STATS_LINK_64                         = 0x1
 	IFLA_STATS_LINK_XSTATS                     = 0x2
@@ -2217,10 +2244,12 @@
 )
 
 const (
-	NETNSA_NONE = 0x0
-	NETNSA_NSID = 0x1
-	NETNSA_PID  = 0x2
-	NETNSA_FD   = 0x3
+	NETNSA_NONE         = 0x0
+	NETNSA_NSID         = 0x1
+	NETNSA_PID          = 0x2
+	NETNSA_FD           = 0x3
+	NETNSA_TARGET_NSID  = 0x4
+	NETNSA_CURRENT_NSID = 0x5
 )
 
 type XDPRingOffset struct {
@@ -2370,281 +2399,309 @@
 )
 
 const (
-	BPF_REG_0                               = 0x0
-	BPF_REG_1                               = 0x1
-	BPF_REG_2                               = 0x2
-	BPF_REG_3                               = 0x3
-	BPF_REG_4                               = 0x4
-	BPF_REG_5                               = 0x5
-	BPF_REG_6                               = 0x6
-	BPF_REG_7                               = 0x7
-	BPF_REG_8                               = 0x8
-	BPF_REG_9                               = 0x9
-	BPF_REG_10                              = 0xa
-	BPF_MAP_CREATE                          = 0x0
-	BPF_MAP_LOOKUP_ELEM                     = 0x1
-	BPF_MAP_UPDATE_ELEM                     = 0x2
-	BPF_MAP_DELETE_ELEM                     = 0x3
-	BPF_MAP_GET_NEXT_KEY                    = 0x4
-	BPF_PROG_LOAD                           = 0x5
-	BPF_OBJ_PIN                             = 0x6
-	BPF_OBJ_GET                             = 0x7
-	BPF_PROG_ATTACH                         = 0x8
-	BPF_PROG_DETACH                         = 0x9
-	BPF_PROG_TEST_RUN                       = 0xa
-	BPF_PROG_GET_NEXT_ID                    = 0xb
-	BPF_MAP_GET_NEXT_ID                     = 0xc
-	BPF_PROG_GET_FD_BY_ID                   = 0xd
-	BPF_MAP_GET_FD_BY_ID                    = 0xe
-	BPF_OBJ_GET_INFO_BY_FD                  = 0xf
-	BPF_PROG_QUERY                          = 0x10
-	BPF_RAW_TRACEPOINT_OPEN                 = 0x11
-	BPF_BTF_LOAD                            = 0x12
-	BPF_BTF_GET_FD_BY_ID                    = 0x13
-	BPF_TASK_FD_QUERY                       = 0x14
-	BPF_MAP_LOOKUP_AND_DELETE_ELEM          = 0x15
-	BPF_MAP_FREEZE                          = 0x16
-	BPF_BTF_GET_NEXT_ID                     = 0x17
-	BPF_MAP_LOOKUP_BATCH                    = 0x18
-	BPF_MAP_LOOKUP_AND_DELETE_BATCH         = 0x19
-	BPF_MAP_UPDATE_BATCH                    = 0x1a
-	BPF_MAP_DELETE_BATCH                    = 0x1b
-	BPF_LINK_CREATE                         = 0x1c
-	BPF_LINK_UPDATE                         = 0x1d
-	BPF_LINK_GET_FD_BY_ID                   = 0x1e
-	BPF_LINK_GET_NEXT_ID                    = 0x1f
-	BPF_ENABLE_STATS                        = 0x20
-	BPF_ITER_CREATE                         = 0x21
-	BPF_MAP_TYPE_UNSPEC                     = 0x0
-	BPF_MAP_TYPE_HASH                       = 0x1
-	BPF_MAP_TYPE_ARRAY                      = 0x2
-	BPF_MAP_TYPE_PROG_ARRAY                 = 0x3
-	BPF_MAP_TYPE_PERF_EVENT_ARRAY           = 0x4
-	BPF_MAP_TYPE_PERCPU_HASH                = 0x5
-	BPF_MAP_TYPE_PERCPU_ARRAY               = 0x6
-	BPF_MAP_TYPE_STACK_TRACE                = 0x7
-	BPF_MAP_TYPE_CGROUP_ARRAY               = 0x8
-	BPF_MAP_TYPE_LRU_HASH                   = 0x9
-	BPF_MAP_TYPE_LRU_PERCPU_HASH            = 0xa
-	BPF_MAP_TYPE_LPM_TRIE                   = 0xb
-	BPF_MAP_TYPE_ARRAY_OF_MAPS              = 0xc
-	BPF_MAP_TYPE_HASH_OF_MAPS               = 0xd
-	BPF_MAP_TYPE_DEVMAP                     = 0xe
-	BPF_MAP_TYPE_SOCKMAP                    = 0xf
-	BPF_MAP_TYPE_CPUMAP                     = 0x10
-	BPF_MAP_TYPE_XSKMAP                     = 0x11
-	BPF_MAP_TYPE_SOCKHASH                   = 0x12
-	BPF_MAP_TYPE_CGROUP_STORAGE             = 0x13
-	BPF_MAP_TYPE_REUSEPORT_SOCKARRAY        = 0x14
-	BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE      = 0x15
-	BPF_MAP_TYPE_QUEUE                      = 0x16
-	BPF_MAP_TYPE_STACK                      = 0x17
-	BPF_MAP_TYPE_SK_STORAGE                 = 0x18
-	BPF_MAP_TYPE_DEVMAP_HASH                = 0x19
-	BPF_MAP_TYPE_STRUCT_OPS                 = 0x1a
-	BPF_MAP_TYPE_RINGBUF                    = 0x1b
-	BPF_PROG_TYPE_UNSPEC                    = 0x0
-	BPF_PROG_TYPE_SOCKET_FILTER             = 0x1
-	BPF_PROG_TYPE_KPROBE                    = 0x2
-	BPF_PROG_TYPE_SCHED_CLS                 = 0x3
-	BPF_PROG_TYPE_SCHED_ACT                 = 0x4
-	BPF_PROG_TYPE_TRACEPOINT                = 0x5
-	BPF_PROG_TYPE_XDP                       = 0x6
-	BPF_PROG_TYPE_PERF_EVENT                = 0x7
-	BPF_PROG_TYPE_CGROUP_SKB                = 0x8
-	BPF_PROG_TYPE_CGROUP_SOCK               = 0x9
-	BPF_PROG_TYPE_LWT_IN                    = 0xa
-	BPF_PROG_TYPE_LWT_OUT                   = 0xb
-	BPF_PROG_TYPE_LWT_XMIT                  = 0xc
-	BPF_PROG_TYPE_SOCK_OPS                  = 0xd
-	BPF_PROG_TYPE_SK_SKB                    = 0xe
-	BPF_PROG_TYPE_CGROUP_DEVICE             = 0xf
-	BPF_PROG_TYPE_SK_MSG                    = 0x10
-	BPF_PROG_TYPE_RAW_TRACEPOINT            = 0x11
-	BPF_PROG_TYPE_CGROUP_SOCK_ADDR          = 0x12
-	BPF_PROG_TYPE_LWT_SEG6LOCAL             = 0x13
-	BPF_PROG_TYPE_LIRC_MODE2                = 0x14
-	BPF_PROG_TYPE_SK_REUSEPORT              = 0x15
-	BPF_PROG_TYPE_FLOW_DISSECTOR            = 0x16
-	BPF_PROG_TYPE_CGROUP_SYSCTL             = 0x17
-	BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE   = 0x18
-	BPF_PROG_TYPE_CGROUP_SOCKOPT            = 0x19
-	BPF_PROG_TYPE_TRACING                   = 0x1a
-	BPF_PROG_TYPE_STRUCT_OPS                = 0x1b
-	BPF_PROG_TYPE_EXT                       = 0x1c
-	BPF_PROG_TYPE_LSM                       = 0x1d
-	BPF_CGROUP_INET_INGRESS                 = 0x0
-	BPF_CGROUP_INET_EGRESS                  = 0x1
-	BPF_CGROUP_INET_SOCK_CREATE             = 0x2
-	BPF_CGROUP_SOCK_OPS                     = 0x3
-	BPF_SK_SKB_STREAM_PARSER                = 0x4
-	BPF_SK_SKB_STREAM_VERDICT               = 0x5
-	BPF_CGROUP_DEVICE                       = 0x6
-	BPF_SK_MSG_VERDICT                      = 0x7
-	BPF_CGROUP_INET4_BIND                   = 0x8
-	BPF_CGROUP_INET6_BIND                   = 0x9
-	BPF_CGROUP_INET4_CONNECT                = 0xa
-	BPF_CGROUP_INET6_CONNECT                = 0xb
-	BPF_CGROUP_INET4_POST_BIND              = 0xc
-	BPF_CGROUP_INET6_POST_BIND              = 0xd
-	BPF_CGROUP_UDP4_SENDMSG                 = 0xe
-	BPF_CGROUP_UDP6_SENDMSG                 = 0xf
-	BPF_LIRC_MODE2                          = 0x10
-	BPF_FLOW_DISSECTOR                      = 0x11
-	BPF_CGROUP_SYSCTL                       = 0x12
-	BPF_CGROUP_UDP4_RECVMSG                 = 0x13
-	BPF_CGROUP_UDP6_RECVMSG                 = 0x14
-	BPF_CGROUP_GETSOCKOPT                   = 0x15
-	BPF_CGROUP_SETSOCKOPT                   = 0x16
-	BPF_TRACE_RAW_TP                        = 0x17
-	BPF_TRACE_FENTRY                        = 0x18
-	BPF_TRACE_FEXIT                         = 0x19
-	BPF_MODIFY_RETURN                       = 0x1a
-	BPF_LSM_MAC                             = 0x1b
-	BPF_TRACE_ITER                          = 0x1c
-	BPF_CGROUP_INET4_GETPEERNAME            = 0x1d
-	BPF_CGROUP_INET6_GETPEERNAME            = 0x1e
-	BPF_CGROUP_INET4_GETSOCKNAME            = 0x1f
-	BPF_CGROUP_INET6_GETSOCKNAME            = 0x20
-	BPF_XDP_DEVMAP                          = 0x21
-	BPF_LINK_TYPE_UNSPEC                    = 0x0
-	BPF_LINK_TYPE_RAW_TRACEPOINT            = 0x1
-	BPF_LINK_TYPE_TRACING                   = 0x2
-	BPF_LINK_TYPE_CGROUP                    = 0x3
-	BPF_LINK_TYPE_ITER                      = 0x4
-	BPF_LINK_TYPE_NETNS                     = 0x5
-	BPF_ANY                                 = 0x0
-	BPF_NOEXIST                             = 0x1
-	BPF_EXIST                               = 0x2
-	BPF_F_LOCK                              = 0x4
-	BPF_F_NO_PREALLOC                       = 0x1
-	BPF_F_NO_COMMON_LRU                     = 0x2
-	BPF_F_NUMA_NODE                         = 0x4
-	BPF_F_RDONLY                            = 0x8
-	BPF_F_WRONLY                            = 0x10
-	BPF_F_STACK_BUILD_ID                    = 0x20
-	BPF_F_ZERO_SEED                         = 0x40
-	BPF_F_RDONLY_PROG                       = 0x80
-	BPF_F_WRONLY_PROG                       = 0x100
-	BPF_F_CLONE                             = 0x200
-	BPF_F_MMAPABLE                          = 0x400
-	BPF_STATS_RUN_TIME                      = 0x0
-	BPF_STACK_BUILD_ID_EMPTY                = 0x0
-	BPF_STACK_BUILD_ID_VALID                = 0x1
-	BPF_STACK_BUILD_ID_IP                   = 0x2
-	BPF_F_RECOMPUTE_CSUM                    = 0x1
-	BPF_F_INVALIDATE_HASH                   = 0x2
-	BPF_F_HDR_FIELD_MASK                    = 0xf
-	BPF_F_PSEUDO_HDR                        = 0x10
-	BPF_F_MARK_MANGLED_0                    = 0x20
-	BPF_F_MARK_ENFORCE                      = 0x40
-	BPF_F_INGRESS                           = 0x1
-	BPF_F_TUNINFO_IPV6                      = 0x1
-	BPF_F_SKIP_FIELD_MASK                   = 0xff
-	BPF_F_USER_STACK                        = 0x100
-	BPF_F_FAST_STACK_CMP                    = 0x200
-	BPF_F_REUSE_STACKID                     = 0x400
-	BPF_F_USER_BUILD_ID                     = 0x800
-	BPF_F_ZERO_CSUM_TX                      = 0x2
-	BPF_F_DONT_FRAGMENT                     = 0x4
-	BPF_F_SEQ_NUMBER                        = 0x8
-	BPF_F_INDEX_MASK                        = 0xffffffff
-	BPF_F_CURRENT_CPU                       = 0xffffffff
-	BPF_F_CTXLEN_MASK                       = 0xfffff00000000
-	BPF_F_CURRENT_NETNS                     = -0x1
-	BPF_CSUM_LEVEL_QUERY                    = 0x0
-	BPF_CSUM_LEVEL_INC                      = 0x1
-	BPF_CSUM_LEVEL_DEC                      = 0x2
-	BPF_CSUM_LEVEL_RESET                    = 0x3
-	BPF_F_ADJ_ROOM_FIXED_GSO                = 0x1
-	BPF_F_ADJ_ROOM_ENCAP_L3_IPV4            = 0x2
-	BPF_F_ADJ_ROOM_ENCAP_L3_IPV6            = 0x4
-	BPF_F_ADJ_ROOM_ENCAP_L4_GRE             = 0x8
-	BPF_F_ADJ_ROOM_ENCAP_L4_UDP             = 0x10
-	BPF_F_ADJ_ROOM_NO_CSUM_RESET            = 0x20
-	BPF_ADJ_ROOM_ENCAP_L2_MASK              = 0xff
-	BPF_ADJ_ROOM_ENCAP_L2_SHIFT             = 0x38
-	BPF_F_SYSCTL_BASE_NAME                  = 0x1
-	BPF_SK_STORAGE_GET_F_CREATE             = 0x1
-	BPF_F_GET_BRANCH_RECORDS_SIZE           = 0x1
-	BPF_RB_NO_WAKEUP                        = 0x1
-	BPF_RB_FORCE_WAKEUP                     = 0x2
-	BPF_RB_AVAIL_DATA                       = 0x0
-	BPF_RB_RING_SIZE                        = 0x1
-	BPF_RB_CONS_POS                         = 0x2
-	BPF_RB_PROD_POS                         = 0x3
-	BPF_RINGBUF_BUSY_BIT                    = 0x80000000
-	BPF_RINGBUF_DISCARD_BIT                 = 0x40000000
-	BPF_RINGBUF_HDR_SZ                      = 0x8
-	BPF_ADJ_ROOM_NET                        = 0x0
-	BPF_ADJ_ROOM_MAC                        = 0x1
-	BPF_HDR_START_MAC                       = 0x0
-	BPF_HDR_START_NET                       = 0x1
-	BPF_LWT_ENCAP_SEG6                      = 0x0
-	BPF_LWT_ENCAP_SEG6_INLINE               = 0x1
-	BPF_LWT_ENCAP_IP                        = 0x2
-	BPF_OK                                  = 0x0
-	BPF_DROP                                = 0x2
-	BPF_REDIRECT                            = 0x7
-	BPF_LWT_REROUTE                         = 0x80
-	BPF_SOCK_OPS_RTO_CB_FLAG                = 0x1
-	BPF_SOCK_OPS_RETRANS_CB_FLAG            = 0x2
-	BPF_SOCK_OPS_STATE_CB_FLAG              = 0x4
-	BPF_SOCK_OPS_RTT_CB_FLAG                = 0x8
-	BPF_SOCK_OPS_ALL_CB_FLAGS               = 0xf
-	BPF_SOCK_OPS_VOID                       = 0x0
-	BPF_SOCK_OPS_TIMEOUT_INIT               = 0x1
-	BPF_SOCK_OPS_RWND_INIT                  = 0x2
-	BPF_SOCK_OPS_TCP_CONNECT_CB             = 0x3
-	BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB      = 0x4
-	BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB     = 0x5
-	BPF_SOCK_OPS_NEEDS_ECN                  = 0x6
-	BPF_SOCK_OPS_BASE_RTT                   = 0x7
-	BPF_SOCK_OPS_RTO_CB                     = 0x8
-	BPF_SOCK_OPS_RETRANS_CB                 = 0x9
-	BPF_SOCK_OPS_STATE_CB                   = 0xa
-	BPF_SOCK_OPS_TCP_LISTEN_CB              = 0xb
-	BPF_SOCK_OPS_RTT_CB                     = 0xc
-	BPF_TCP_ESTABLISHED                     = 0x1
-	BPF_TCP_SYN_SENT                        = 0x2
-	BPF_TCP_SYN_RECV                        = 0x3
-	BPF_TCP_FIN_WAIT1                       = 0x4
-	BPF_TCP_FIN_WAIT2                       = 0x5
-	BPF_TCP_TIME_WAIT                       = 0x6
-	BPF_TCP_CLOSE                           = 0x7
-	BPF_TCP_CLOSE_WAIT                      = 0x8
-	BPF_TCP_LAST_ACK                        = 0x9
-	BPF_TCP_LISTEN                          = 0xa
-	BPF_TCP_CLOSING                         = 0xb
-	BPF_TCP_NEW_SYN_RECV                    = 0xc
-	BPF_TCP_MAX_STATES                      = 0xd
-	TCP_BPF_IW                              = 0x3e9
-	TCP_BPF_SNDCWND_CLAMP                   = 0x3ea
-	BPF_DEVCG_ACC_MKNOD                     = 0x1
-	BPF_DEVCG_ACC_READ                      = 0x2
-	BPF_DEVCG_ACC_WRITE                     = 0x4
-	BPF_DEVCG_DEV_BLOCK                     = 0x1
-	BPF_DEVCG_DEV_CHAR                      = 0x2
-	BPF_FIB_LOOKUP_DIRECT                   = 0x1
-	BPF_FIB_LOOKUP_OUTPUT                   = 0x2
-	BPF_FIB_LKUP_RET_SUCCESS                = 0x0
-	BPF_FIB_LKUP_RET_BLACKHOLE              = 0x1
-	BPF_FIB_LKUP_RET_UNREACHABLE            = 0x2
-	BPF_FIB_LKUP_RET_PROHIBIT               = 0x3
-	BPF_FIB_LKUP_RET_NOT_FWDED              = 0x4
-	BPF_FIB_LKUP_RET_FWD_DISABLED           = 0x5
-	BPF_FIB_LKUP_RET_UNSUPP_LWT             = 0x6
-	BPF_FIB_LKUP_RET_NO_NEIGH               = 0x7
-	BPF_FIB_LKUP_RET_FRAG_NEEDED            = 0x8
-	BPF_FD_TYPE_RAW_TRACEPOINT              = 0x0
-	BPF_FD_TYPE_TRACEPOINT                  = 0x1
-	BPF_FD_TYPE_KPROBE                      = 0x2
-	BPF_FD_TYPE_KRETPROBE                   = 0x3
-	BPF_FD_TYPE_UPROBE                      = 0x4
-	BPF_FD_TYPE_URETPROBE                   = 0x5
-	BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG     = 0x1
-	BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL = 0x2
-	BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP      = 0x4
+	BPF_REG_0                                  = 0x0
+	BPF_REG_1                                  = 0x1
+	BPF_REG_2                                  = 0x2
+	BPF_REG_3                                  = 0x3
+	BPF_REG_4                                  = 0x4
+	BPF_REG_5                                  = 0x5
+	BPF_REG_6                                  = 0x6
+	BPF_REG_7                                  = 0x7
+	BPF_REG_8                                  = 0x8
+	BPF_REG_9                                  = 0x9
+	BPF_REG_10                                 = 0xa
+	BPF_MAP_CREATE                             = 0x0
+	BPF_MAP_LOOKUP_ELEM                        = 0x1
+	BPF_MAP_UPDATE_ELEM                        = 0x2
+	BPF_MAP_DELETE_ELEM                        = 0x3
+	BPF_MAP_GET_NEXT_KEY                       = 0x4
+	BPF_PROG_LOAD                              = 0x5
+	BPF_OBJ_PIN                                = 0x6
+	BPF_OBJ_GET                                = 0x7
+	BPF_PROG_ATTACH                            = 0x8
+	BPF_PROG_DETACH                            = 0x9
+	BPF_PROG_TEST_RUN                          = 0xa
+	BPF_PROG_GET_NEXT_ID                       = 0xb
+	BPF_MAP_GET_NEXT_ID                        = 0xc
+	BPF_PROG_GET_FD_BY_ID                      = 0xd
+	BPF_MAP_GET_FD_BY_ID                       = 0xe
+	BPF_OBJ_GET_INFO_BY_FD                     = 0xf
+	BPF_PROG_QUERY                             = 0x10
+	BPF_RAW_TRACEPOINT_OPEN                    = 0x11
+	BPF_BTF_LOAD                               = 0x12
+	BPF_BTF_GET_FD_BY_ID                       = 0x13
+	BPF_TASK_FD_QUERY                          = 0x14
+	BPF_MAP_LOOKUP_AND_DELETE_ELEM             = 0x15
+	BPF_MAP_FREEZE                             = 0x16
+	BPF_BTF_GET_NEXT_ID                        = 0x17
+	BPF_MAP_LOOKUP_BATCH                       = 0x18
+	BPF_MAP_LOOKUP_AND_DELETE_BATCH            = 0x19
+	BPF_MAP_UPDATE_BATCH                       = 0x1a
+	BPF_MAP_DELETE_BATCH                       = 0x1b
+	BPF_LINK_CREATE                            = 0x1c
+	BPF_LINK_UPDATE                            = 0x1d
+	BPF_LINK_GET_FD_BY_ID                      = 0x1e
+	BPF_LINK_GET_NEXT_ID                       = 0x1f
+	BPF_ENABLE_STATS                           = 0x20
+	BPF_ITER_CREATE                            = 0x21
+	BPF_LINK_DETACH                            = 0x22
+	BPF_PROG_BIND_MAP                          = 0x23
+	BPF_MAP_TYPE_UNSPEC                        = 0x0
+	BPF_MAP_TYPE_HASH                          = 0x1
+	BPF_MAP_TYPE_ARRAY                         = 0x2
+	BPF_MAP_TYPE_PROG_ARRAY                    = 0x3
+	BPF_MAP_TYPE_PERF_EVENT_ARRAY              = 0x4
+	BPF_MAP_TYPE_PERCPU_HASH                   = 0x5
+	BPF_MAP_TYPE_PERCPU_ARRAY                  = 0x6
+	BPF_MAP_TYPE_STACK_TRACE                   = 0x7
+	BPF_MAP_TYPE_CGROUP_ARRAY                  = 0x8
+	BPF_MAP_TYPE_LRU_HASH                      = 0x9
+	BPF_MAP_TYPE_LRU_PERCPU_HASH               = 0xa
+	BPF_MAP_TYPE_LPM_TRIE                      = 0xb
+	BPF_MAP_TYPE_ARRAY_OF_MAPS                 = 0xc
+	BPF_MAP_TYPE_HASH_OF_MAPS                  = 0xd
+	BPF_MAP_TYPE_DEVMAP                        = 0xe
+	BPF_MAP_TYPE_SOCKMAP                       = 0xf
+	BPF_MAP_TYPE_CPUMAP                        = 0x10
+	BPF_MAP_TYPE_XSKMAP                        = 0x11
+	BPF_MAP_TYPE_SOCKHASH                      = 0x12
+	BPF_MAP_TYPE_CGROUP_STORAGE                = 0x13
+	BPF_MAP_TYPE_REUSEPORT_SOCKARRAY           = 0x14
+	BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE         = 0x15
+	BPF_MAP_TYPE_QUEUE                         = 0x16
+	BPF_MAP_TYPE_STACK                         = 0x17
+	BPF_MAP_TYPE_SK_STORAGE                    = 0x18
+	BPF_MAP_TYPE_DEVMAP_HASH                   = 0x19
+	BPF_MAP_TYPE_STRUCT_OPS                    = 0x1a
+	BPF_MAP_TYPE_RINGBUF                       = 0x1b
+	BPF_MAP_TYPE_INODE_STORAGE                 = 0x1c
+	BPF_PROG_TYPE_UNSPEC                       = 0x0
+	BPF_PROG_TYPE_SOCKET_FILTER                = 0x1
+	BPF_PROG_TYPE_KPROBE                       = 0x2
+	BPF_PROG_TYPE_SCHED_CLS                    = 0x3
+	BPF_PROG_TYPE_SCHED_ACT                    = 0x4
+	BPF_PROG_TYPE_TRACEPOINT                   = 0x5
+	BPF_PROG_TYPE_XDP                          = 0x6
+	BPF_PROG_TYPE_PERF_EVENT                   = 0x7
+	BPF_PROG_TYPE_CGROUP_SKB                   = 0x8
+	BPF_PROG_TYPE_CGROUP_SOCK                  = 0x9
+	BPF_PROG_TYPE_LWT_IN                       = 0xa
+	BPF_PROG_TYPE_LWT_OUT                      = 0xb
+	BPF_PROG_TYPE_LWT_XMIT                     = 0xc
+	BPF_PROG_TYPE_SOCK_OPS                     = 0xd
+	BPF_PROG_TYPE_SK_SKB                       = 0xe
+	BPF_PROG_TYPE_CGROUP_DEVICE                = 0xf
+	BPF_PROG_TYPE_SK_MSG                       = 0x10
+	BPF_PROG_TYPE_RAW_TRACEPOINT               = 0x11
+	BPF_PROG_TYPE_CGROUP_SOCK_ADDR             = 0x12
+	BPF_PROG_TYPE_LWT_SEG6LOCAL                = 0x13
+	BPF_PROG_TYPE_LIRC_MODE2                   = 0x14
+	BPF_PROG_TYPE_SK_REUSEPORT                 = 0x15
+	BPF_PROG_TYPE_FLOW_DISSECTOR               = 0x16
+	BPF_PROG_TYPE_CGROUP_SYSCTL                = 0x17
+	BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE      = 0x18
+	BPF_PROG_TYPE_CGROUP_SOCKOPT               = 0x19
+	BPF_PROG_TYPE_TRACING                      = 0x1a
+	BPF_PROG_TYPE_STRUCT_OPS                   = 0x1b
+	BPF_PROG_TYPE_EXT                          = 0x1c
+	BPF_PROG_TYPE_LSM                          = 0x1d
+	BPF_PROG_TYPE_SK_LOOKUP                    = 0x1e
+	BPF_CGROUP_INET_INGRESS                    = 0x0
+	BPF_CGROUP_INET_EGRESS                     = 0x1
+	BPF_CGROUP_INET_SOCK_CREATE                = 0x2
+	BPF_CGROUP_SOCK_OPS                        = 0x3
+	BPF_SK_SKB_STREAM_PARSER                   = 0x4
+	BPF_SK_SKB_STREAM_VERDICT                  = 0x5
+	BPF_CGROUP_DEVICE                          = 0x6
+	BPF_SK_MSG_VERDICT                         = 0x7
+	BPF_CGROUP_INET4_BIND                      = 0x8
+	BPF_CGROUP_INET6_BIND                      = 0x9
+	BPF_CGROUP_INET4_CONNECT                   = 0xa
+	BPF_CGROUP_INET6_CONNECT                   = 0xb
+	BPF_CGROUP_INET4_POST_BIND                 = 0xc
+	BPF_CGROUP_INET6_POST_BIND                 = 0xd
+	BPF_CGROUP_UDP4_SENDMSG                    = 0xe
+	BPF_CGROUP_UDP6_SENDMSG                    = 0xf
+	BPF_LIRC_MODE2                             = 0x10
+	BPF_FLOW_DISSECTOR                         = 0x11
+	BPF_CGROUP_SYSCTL                          = 0x12
+	BPF_CGROUP_UDP4_RECVMSG                    = 0x13
+	BPF_CGROUP_UDP6_RECVMSG                    = 0x14
+	BPF_CGROUP_GETSOCKOPT                      = 0x15
+	BPF_CGROUP_SETSOCKOPT                      = 0x16
+	BPF_TRACE_RAW_TP                           = 0x17
+	BPF_TRACE_FENTRY                           = 0x18
+	BPF_TRACE_FEXIT                            = 0x19
+	BPF_MODIFY_RETURN                          = 0x1a
+	BPF_LSM_MAC                                = 0x1b
+	BPF_TRACE_ITER                             = 0x1c
+	BPF_CGROUP_INET4_GETPEERNAME               = 0x1d
+	BPF_CGROUP_INET6_GETPEERNAME               = 0x1e
+	BPF_CGROUP_INET4_GETSOCKNAME               = 0x1f
+	BPF_CGROUP_INET6_GETSOCKNAME               = 0x20
+	BPF_XDP_DEVMAP                             = 0x21
+	BPF_CGROUP_INET_SOCK_RELEASE               = 0x22
+	BPF_XDP_CPUMAP                             = 0x23
+	BPF_SK_LOOKUP                              = 0x24
+	BPF_XDP                                    = 0x25
+	BPF_LINK_TYPE_UNSPEC                       = 0x0
+	BPF_LINK_TYPE_RAW_TRACEPOINT               = 0x1
+	BPF_LINK_TYPE_TRACING                      = 0x2
+	BPF_LINK_TYPE_CGROUP                       = 0x3
+	BPF_LINK_TYPE_ITER                         = 0x4
+	BPF_LINK_TYPE_NETNS                        = 0x5
+	BPF_LINK_TYPE_XDP                          = 0x6
+	BPF_ANY                                    = 0x0
+	BPF_NOEXIST                                = 0x1
+	BPF_EXIST                                  = 0x2
+	BPF_F_LOCK                                 = 0x4
+	BPF_F_NO_PREALLOC                          = 0x1
+	BPF_F_NO_COMMON_LRU                        = 0x2
+	BPF_F_NUMA_NODE                            = 0x4
+	BPF_F_RDONLY                               = 0x8
+	BPF_F_WRONLY                               = 0x10
+	BPF_F_STACK_BUILD_ID                       = 0x20
+	BPF_F_ZERO_SEED                            = 0x40
+	BPF_F_RDONLY_PROG                          = 0x80
+	BPF_F_WRONLY_PROG                          = 0x100
+	BPF_F_CLONE                                = 0x200
+	BPF_F_MMAPABLE                             = 0x400
+	BPF_F_PRESERVE_ELEMS                       = 0x800
+	BPF_F_INNER_MAP                            = 0x1000
+	BPF_STATS_RUN_TIME                         = 0x0
+	BPF_STACK_BUILD_ID_EMPTY                   = 0x0
+	BPF_STACK_BUILD_ID_VALID                   = 0x1
+	BPF_STACK_BUILD_ID_IP                      = 0x2
+	BPF_F_RECOMPUTE_CSUM                       = 0x1
+	BPF_F_INVALIDATE_HASH                      = 0x2
+	BPF_F_HDR_FIELD_MASK                       = 0xf
+	BPF_F_PSEUDO_HDR                           = 0x10
+	BPF_F_MARK_MANGLED_0                       = 0x20
+	BPF_F_MARK_ENFORCE                         = 0x40
+	BPF_F_INGRESS                              = 0x1
+	BPF_F_TUNINFO_IPV6                         = 0x1
+	BPF_F_SKIP_FIELD_MASK                      = 0xff
+	BPF_F_USER_STACK                           = 0x100
+	BPF_F_FAST_STACK_CMP                       = 0x200
+	BPF_F_REUSE_STACKID                        = 0x400
+	BPF_F_USER_BUILD_ID                        = 0x800
+	BPF_F_ZERO_CSUM_TX                         = 0x2
+	BPF_F_DONT_FRAGMENT                        = 0x4
+	BPF_F_SEQ_NUMBER                           = 0x8
+	BPF_F_INDEX_MASK                           = 0xffffffff
+	BPF_F_CURRENT_CPU                          = 0xffffffff
+	BPF_F_CTXLEN_MASK                          = 0xfffff00000000
+	BPF_F_CURRENT_NETNS                        = -0x1
+	BPF_CSUM_LEVEL_QUERY                       = 0x0
+	BPF_CSUM_LEVEL_INC                         = 0x1
+	BPF_CSUM_LEVEL_DEC                         = 0x2
+	BPF_CSUM_LEVEL_RESET                       = 0x3
+	BPF_F_ADJ_ROOM_FIXED_GSO                   = 0x1
+	BPF_F_ADJ_ROOM_ENCAP_L3_IPV4               = 0x2
+	BPF_F_ADJ_ROOM_ENCAP_L3_IPV6               = 0x4
+	BPF_F_ADJ_ROOM_ENCAP_L4_GRE                = 0x8
+	BPF_F_ADJ_ROOM_ENCAP_L4_UDP                = 0x10
+	BPF_F_ADJ_ROOM_NO_CSUM_RESET               = 0x20
+	BPF_ADJ_ROOM_ENCAP_L2_MASK                 = 0xff
+	BPF_ADJ_ROOM_ENCAP_L2_SHIFT                = 0x38
+	BPF_F_SYSCTL_BASE_NAME                     = 0x1
+	BPF_LOCAL_STORAGE_GET_F_CREATE             = 0x1
+	BPF_SK_STORAGE_GET_F_CREATE                = 0x1
+	BPF_F_GET_BRANCH_RECORDS_SIZE              = 0x1
+	BPF_RB_NO_WAKEUP                           = 0x1
+	BPF_RB_FORCE_WAKEUP                        = 0x2
+	BPF_RB_AVAIL_DATA                          = 0x0
+	BPF_RB_RING_SIZE                           = 0x1
+	BPF_RB_CONS_POS                            = 0x2
+	BPF_RB_PROD_POS                            = 0x3
+	BPF_RINGBUF_BUSY_BIT                       = 0x80000000
+	BPF_RINGBUF_DISCARD_BIT                    = 0x40000000
+	BPF_RINGBUF_HDR_SZ                         = 0x8
+	BPF_SK_LOOKUP_F_REPLACE                    = 0x1
+	BPF_SK_LOOKUP_F_NO_REUSEPORT               = 0x2
+	BPF_ADJ_ROOM_NET                           = 0x0
+	BPF_ADJ_ROOM_MAC                           = 0x1
+	BPF_HDR_START_MAC                          = 0x0
+	BPF_HDR_START_NET                          = 0x1
+	BPF_LWT_ENCAP_SEG6                         = 0x0
+	BPF_LWT_ENCAP_SEG6_INLINE                  = 0x1
+	BPF_LWT_ENCAP_IP                           = 0x2
+	BPF_OK                                     = 0x0
+	BPF_DROP                                   = 0x2
+	BPF_REDIRECT                               = 0x7
+	BPF_LWT_REROUTE                            = 0x80
+	BPF_SOCK_OPS_RTO_CB_FLAG                   = 0x1
+	BPF_SOCK_OPS_RETRANS_CB_FLAG               = 0x2
+	BPF_SOCK_OPS_STATE_CB_FLAG                 = 0x4
+	BPF_SOCK_OPS_RTT_CB_FLAG                   = 0x8
+	BPF_SOCK_OPS_PARSE_ALL_HDR_OPT_CB_FLAG     = 0x10
+	BPF_SOCK_OPS_PARSE_UNKNOWN_HDR_OPT_CB_FLAG = 0x20
+	BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG         = 0x40
+	BPF_SOCK_OPS_ALL_CB_FLAGS                  = 0x7f
+	BPF_SOCK_OPS_VOID                          = 0x0
+	BPF_SOCK_OPS_TIMEOUT_INIT                  = 0x1
+	BPF_SOCK_OPS_RWND_INIT                     = 0x2
+	BPF_SOCK_OPS_TCP_CONNECT_CB                = 0x3
+	BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB         = 0x4
+	BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB        = 0x5
+	BPF_SOCK_OPS_NEEDS_ECN                     = 0x6
+	BPF_SOCK_OPS_BASE_RTT                      = 0x7
+	BPF_SOCK_OPS_RTO_CB                        = 0x8
+	BPF_SOCK_OPS_RETRANS_CB                    = 0x9
+	BPF_SOCK_OPS_STATE_CB                      = 0xa
+	BPF_SOCK_OPS_TCP_LISTEN_CB                 = 0xb
+	BPF_SOCK_OPS_RTT_CB                        = 0xc
+	BPF_SOCK_OPS_PARSE_HDR_OPT_CB              = 0xd
+	BPF_SOCK_OPS_HDR_OPT_LEN_CB                = 0xe
+	BPF_SOCK_OPS_WRITE_HDR_OPT_CB              = 0xf
+	BPF_TCP_ESTABLISHED                        = 0x1
+	BPF_TCP_SYN_SENT                           = 0x2
+	BPF_TCP_SYN_RECV                           = 0x3
+	BPF_TCP_FIN_WAIT1                          = 0x4
+	BPF_TCP_FIN_WAIT2                          = 0x5
+	BPF_TCP_TIME_WAIT                          = 0x6
+	BPF_TCP_CLOSE                              = 0x7
+	BPF_TCP_CLOSE_WAIT                         = 0x8
+	BPF_TCP_LAST_ACK                           = 0x9
+	BPF_TCP_LISTEN                             = 0xa
+	BPF_TCP_CLOSING                            = 0xb
+	BPF_TCP_NEW_SYN_RECV                       = 0xc
+	BPF_TCP_MAX_STATES                         = 0xd
+	TCP_BPF_IW                                 = 0x3e9
+	TCP_BPF_SNDCWND_CLAMP                      = 0x3ea
+	TCP_BPF_DELACK_MAX                         = 0x3eb
+	TCP_BPF_RTO_MIN                            = 0x3ec
+	TCP_BPF_SYN                                = 0x3ed
+	TCP_BPF_SYN_IP                             = 0x3ee
+	TCP_BPF_SYN_MAC                            = 0x3ef
+	BPF_LOAD_HDR_OPT_TCP_SYN                   = 0x1
+	BPF_WRITE_HDR_TCP_CURRENT_MSS              = 0x1
+	BPF_WRITE_HDR_TCP_SYNACK_COOKIE            = 0x2
+	BPF_DEVCG_ACC_MKNOD                        = 0x1
+	BPF_DEVCG_ACC_READ                         = 0x2
+	BPF_DEVCG_ACC_WRITE                        = 0x4
+	BPF_DEVCG_DEV_BLOCK                        = 0x1
+	BPF_DEVCG_DEV_CHAR                         = 0x2
+	BPF_FIB_LOOKUP_DIRECT                      = 0x1
+	BPF_FIB_LOOKUP_OUTPUT                      = 0x2
+	BPF_FIB_LKUP_RET_SUCCESS                   = 0x0
+	BPF_FIB_LKUP_RET_BLACKHOLE                 = 0x1
+	BPF_FIB_LKUP_RET_UNREACHABLE               = 0x2
+	BPF_FIB_LKUP_RET_PROHIBIT                  = 0x3
+	BPF_FIB_LKUP_RET_NOT_FWDED                 = 0x4
+	BPF_FIB_LKUP_RET_FWD_DISABLED              = 0x5
+	BPF_FIB_LKUP_RET_UNSUPP_LWT                = 0x6
+	BPF_FIB_LKUP_RET_NO_NEIGH                  = 0x7
+	BPF_FIB_LKUP_RET_FRAG_NEEDED               = 0x8
+	BPF_FD_TYPE_RAW_TRACEPOINT                 = 0x0
+	BPF_FD_TYPE_TRACEPOINT                     = 0x1
+	BPF_FD_TYPE_KPROBE                         = 0x2
+	BPF_FD_TYPE_KRETPROBE                      = 0x3
+	BPF_FD_TYPE_UPROBE                         = 0x4
+	BPF_FD_TYPE_URETPROBE                      = 0x5
+	BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG        = 0x1
+	BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL    = 0x2
+	BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP         = 0x4
 )
 
 const (
@@ -2681,6 +2738,7 @@
 	RTNLGRP_IPV4_MROUTE_R = 0x1e
 	RTNLGRP_IPV6_MROUTE_R = 0x1f
 	RTNLGRP_NEXTHOP       = 0x20
+	RTNLGRP_BRVLAN        = 0x21
 )
 
 type CapUserHeader struct {
@@ -2775,132 +2833,320 @@
 )
 
 const (
-	DEVLINK_CMD_UNSPEC                        = 0x0
-	DEVLINK_CMD_GET                           = 0x1
-	DEVLINK_CMD_SET                           = 0x2
-	DEVLINK_CMD_NEW                           = 0x3
-	DEVLINK_CMD_DEL                           = 0x4
-	DEVLINK_CMD_PORT_GET                      = 0x5
-	DEVLINK_CMD_PORT_SET                      = 0x6
-	DEVLINK_CMD_PORT_NEW                      = 0x7
-	DEVLINK_CMD_PORT_DEL                      = 0x8
-	DEVLINK_CMD_PORT_SPLIT                    = 0x9
-	DEVLINK_CMD_PORT_UNSPLIT                  = 0xa
-	DEVLINK_CMD_SB_GET                        = 0xb
-	DEVLINK_CMD_SB_SET                        = 0xc
-	DEVLINK_CMD_SB_NEW                        = 0xd
-	DEVLINK_CMD_SB_DEL                        = 0xe
-	DEVLINK_CMD_SB_POOL_GET                   = 0xf
-	DEVLINK_CMD_SB_POOL_SET                   = 0x10
-	DEVLINK_CMD_SB_POOL_NEW                   = 0x11
-	DEVLINK_CMD_SB_POOL_DEL                   = 0x12
-	DEVLINK_CMD_SB_PORT_POOL_GET              = 0x13
-	DEVLINK_CMD_SB_PORT_POOL_SET              = 0x14
-	DEVLINK_CMD_SB_PORT_POOL_NEW              = 0x15
-	DEVLINK_CMD_SB_PORT_POOL_DEL              = 0x16
-	DEVLINK_CMD_SB_TC_POOL_BIND_GET           = 0x17
-	DEVLINK_CMD_SB_TC_POOL_BIND_SET           = 0x18
-	DEVLINK_CMD_SB_TC_POOL_BIND_NEW           = 0x19
-	DEVLINK_CMD_SB_TC_POOL_BIND_DEL           = 0x1a
-	DEVLINK_CMD_SB_OCC_SNAPSHOT               = 0x1b
-	DEVLINK_CMD_SB_OCC_MAX_CLEAR              = 0x1c
-	DEVLINK_CMD_ESWITCH_GET                   = 0x1d
-	DEVLINK_CMD_ESWITCH_SET                   = 0x1e
-	DEVLINK_CMD_DPIPE_TABLE_GET               = 0x1f
-	DEVLINK_CMD_DPIPE_ENTRIES_GET             = 0x20
-	DEVLINK_CMD_DPIPE_HEADERS_GET             = 0x21
-	DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET      = 0x22
-	DEVLINK_CMD_MAX                           = 0x48
-	DEVLINK_PORT_TYPE_NOTSET                  = 0x0
-	DEVLINK_PORT_TYPE_AUTO                    = 0x1
-	DEVLINK_PORT_TYPE_ETH                     = 0x2
-	DEVLINK_PORT_TYPE_IB                      = 0x3
-	DEVLINK_SB_POOL_TYPE_INGRESS              = 0x0
-	DEVLINK_SB_POOL_TYPE_EGRESS               = 0x1
-	DEVLINK_SB_THRESHOLD_TYPE_STATIC          = 0x0
-	DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC         = 0x1
-	DEVLINK_ESWITCH_MODE_LEGACY               = 0x0
-	DEVLINK_ESWITCH_MODE_SWITCHDEV            = 0x1
-	DEVLINK_ESWITCH_INLINE_MODE_NONE          = 0x0
-	DEVLINK_ESWITCH_INLINE_MODE_LINK          = 0x1
-	DEVLINK_ESWITCH_INLINE_MODE_NETWORK       = 0x2
-	DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT     = 0x3
-	DEVLINK_ESWITCH_ENCAP_MODE_NONE           = 0x0
-	DEVLINK_ESWITCH_ENCAP_MODE_BASIC          = 0x1
-	DEVLINK_ATTR_UNSPEC                       = 0x0
-	DEVLINK_ATTR_BUS_NAME                     = 0x1
-	DEVLINK_ATTR_DEV_NAME                     = 0x2
-	DEVLINK_ATTR_PORT_INDEX                   = 0x3
-	DEVLINK_ATTR_PORT_TYPE                    = 0x4
-	DEVLINK_ATTR_PORT_DESIRED_TYPE            = 0x5
-	DEVLINK_ATTR_PORT_NETDEV_IFINDEX          = 0x6
-	DEVLINK_ATTR_PORT_NETDEV_NAME             = 0x7
-	DEVLINK_ATTR_PORT_IBDEV_NAME              = 0x8
-	DEVLINK_ATTR_PORT_SPLIT_COUNT             = 0x9
-	DEVLINK_ATTR_PORT_SPLIT_GROUP             = 0xa
-	DEVLINK_ATTR_SB_INDEX                     = 0xb
-	DEVLINK_ATTR_SB_SIZE                      = 0xc
-	DEVLINK_ATTR_SB_INGRESS_POOL_COUNT        = 0xd
-	DEVLINK_ATTR_SB_EGRESS_POOL_COUNT         = 0xe
-	DEVLINK_ATTR_SB_INGRESS_TC_COUNT          = 0xf
-	DEVLINK_ATTR_SB_EGRESS_TC_COUNT           = 0x10
-	DEVLINK_ATTR_SB_POOL_INDEX                = 0x11
-	DEVLINK_ATTR_SB_POOL_TYPE                 = 0x12
-	DEVLINK_ATTR_SB_POOL_SIZE                 = 0x13
-	DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE       = 0x14
-	DEVLINK_ATTR_SB_THRESHOLD                 = 0x15
-	DEVLINK_ATTR_SB_TC_INDEX                  = 0x16
-	DEVLINK_ATTR_SB_OCC_CUR                   = 0x17
-	DEVLINK_ATTR_SB_OCC_MAX                   = 0x18
-	DEVLINK_ATTR_ESWITCH_MODE                 = 0x19
-	DEVLINK_ATTR_ESWITCH_INLINE_MODE          = 0x1a
-	DEVLINK_ATTR_DPIPE_TABLES                 = 0x1b
-	DEVLINK_ATTR_DPIPE_TABLE                  = 0x1c
-	DEVLINK_ATTR_DPIPE_TABLE_NAME             = 0x1d
-	DEVLINK_ATTR_DPIPE_TABLE_SIZE             = 0x1e
-	DEVLINK_ATTR_DPIPE_TABLE_MATCHES          = 0x1f
-	DEVLINK_ATTR_DPIPE_TABLE_ACTIONS          = 0x20
-	DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED = 0x21
-	DEVLINK_ATTR_DPIPE_ENTRIES                = 0x22
-	DEVLINK_ATTR_DPIPE_ENTRY                  = 0x23
-	DEVLINK_ATTR_DPIPE_ENTRY_INDEX            = 0x24
-	DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES     = 0x25
-	DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES    = 0x26
-	DEVLINK_ATTR_DPIPE_ENTRY_COUNTER          = 0x27
-	DEVLINK_ATTR_DPIPE_MATCH                  = 0x28
-	DEVLINK_ATTR_DPIPE_MATCH_VALUE            = 0x29
-	DEVLINK_ATTR_DPIPE_MATCH_TYPE             = 0x2a
-	DEVLINK_ATTR_DPIPE_ACTION                 = 0x2b
-	DEVLINK_ATTR_DPIPE_ACTION_VALUE           = 0x2c
-	DEVLINK_ATTR_DPIPE_ACTION_TYPE            = 0x2d
-	DEVLINK_ATTR_DPIPE_VALUE                  = 0x2e
-	DEVLINK_ATTR_DPIPE_VALUE_MASK             = 0x2f
-	DEVLINK_ATTR_DPIPE_VALUE_MAPPING          = 0x30
-	DEVLINK_ATTR_DPIPE_HEADERS                = 0x31
-	DEVLINK_ATTR_DPIPE_HEADER                 = 0x32
-	DEVLINK_ATTR_DPIPE_HEADER_NAME            = 0x33
-	DEVLINK_ATTR_DPIPE_HEADER_ID              = 0x34
-	DEVLINK_ATTR_DPIPE_HEADER_FIELDS          = 0x35
-	DEVLINK_ATTR_DPIPE_HEADER_GLOBAL          = 0x36
-	DEVLINK_ATTR_DPIPE_HEADER_INDEX           = 0x37
-	DEVLINK_ATTR_DPIPE_FIELD                  = 0x38
-	DEVLINK_ATTR_DPIPE_FIELD_NAME             = 0x39
-	DEVLINK_ATTR_DPIPE_FIELD_ID               = 0x3a
-	DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH         = 0x3b
-	DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE     = 0x3c
-	DEVLINK_ATTR_PAD                          = 0x3d
-	DEVLINK_ATTR_ESWITCH_ENCAP_MODE           = 0x3e
-	DEVLINK_ATTR_MAX                          = 0x94
-	DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE     = 0x0
-	DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX  = 0x1
-	DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT      = 0x0
-	DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY    = 0x0
-	DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC      = 0x0
-	DEVLINK_DPIPE_FIELD_IPV4_DST_IP           = 0x0
-	DEVLINK_DPIPE_FIELD_IPV6_DST_IP           = 0x0
-	DEVLINK_DPIPE_HEADER_ETHERNET             = 0x0
-	DEVLINK_DPIPE_HEADER_IPV4                 = 0x1
-	DEVLINK_DPIPE_HEADER_IPV6                 = 0x2
+	DEVLINK_CMD_UNSPEC                                 = 0x0
+	DEVLINK_CMD_GET                                    = 0x1
+	DEVLINK_CMD_SET                                    = 0x2
+	DEVLINK_CMD_NEW                                    = 0x3
+	DEVLINK_CMD_DEL                                    = 0x4
+	DEVLINK_CMD_PORT_GET                               = 0x5
+	DEVLINK_CMD_PORT_SET                               = 0x6
+	DEVLINK_CMD_PORT_NEW                               = 0x7
+	DEVLINK_CMD_PORT_DEL                               = 0x8
+	DEVLINK_CMD_PORT_SPLIT                             = 0x9
+	DEVLINK_CMD_PORT_UNSPLIT                           = 0xa
+	DEVLINK_CMD_SB_GET                                 = 0xb
+	DEVLINK_CMD_SB_SET                                 = 0xc
+	DEVLINK_CMD_SB_NEW                                 = 0xd
+	DEVLINK_CMD_SB_DEL                                 = 0xe
+	DEVLINK_CMD_SB_POOL_GET                            = 0xf
+	DEVLINK_CMD_SB_POOL_SET                            = 0x10
+	DEVLINK_CMD_SB_POOL_NEW                            = 0x11
+	DEVLINK_CMD_SB_POOL_DEL                            = 0x12
+	DEVLINK_CMD_SB_PORT_POOL_GET                       = 0x13
+	DEVLINK_CMD_SB_PORT_POOL_SET                       = 0x14
+	DEVLINK_CMD_SB_PORT_POOL_NEW                       = 0x15
+	DEVLINK_CMD_SB_PORT_POOL_DEL                       = 0x16
+	DEVLINK_CMD_SB_TC_POOL_BIND_GET                    = 0x17
+	DEVLINK_CMD_SB_TC_POOL_BIND_SET                    = 0x18
+	DEVLINK_CMD_SB_TC_POOL_BIND_NEW                    = 0x19
+	DEVLINK_CMD_SB_TC_POOL_BIND_DEL                    = 0x1a
+	DEVLINK_CMD_SB_OCC_SNAPSHOT                        = 0x1b
+	DEVLINK_CMD_SB_OCC_MAX_CLEAR                       = 0x1c
+	DEVLINK_CMD_ESWITCH_GET                            = 0x1d
+	DEVLINK_CMD_ESWITCH_SET                            = 0x1e
+	DEVLINK_CMD_DPIPE_TABLE_GET                        = 0x1f
+	DEVLINK_CMD_DPIPE_ENTRIES_GET                      = 0x20
+	DEVLINK_CMD_DPIPE_HEADERS_GET                      = 0x21
+	DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET               = 0x22
+	DEVLINK_CMD_RESOURCE_SET                           = 0x23
+	DEVLINK_CMD_RESOURCE_DUMP                          = 0x24
+	DEVLINK_CMD_RELOAD                                 = 0x25
+	DEVLINK_CMD_PARAM_GET                              = 0x26
+	DEVLINK_CMD_PARAM_SET                              = 0x27
+	DEVLINK_CMD_PARAM_NEW                              = 0x28
+	DEVLINK_CMD_PARAM_DEL                              = 0x29
+	DEVLINK_CMD_REGION_GET                             = 0x2a
+	DEVLINK_CMD_REGION_SET                             = 0x2b
+	DEVLINK_CMD_REGION_NEW                             = 0x2c
+	DEVLINK_CMD_REGION_DEL                             = 0x2d
+	DEVLINK_CMD_REGION_READ                            = 0x2e
+	DEVLINK_CMD_PORT_PARAM_GET                         = 0x2f
+	DEVLINK_CMD_PORT_PARAM_SET                         = 0x30
+	DEVLINK_CMD_PORT_PARAM_NEW                         = 0x31
+	DEVLINK_CMD_PORT_PARAM_DEL                         = 0x32
+	DEVLINK_CMD_INFO_GET                               = 0x33
+	DEVLINK_CMD_HEALTH_REPORTER_GET                    = 0x34
+	DEVLINK_CMD_HEALTH_REPORTER_SET                    = 0x35
+	DEVLINK_CMD_HEALTH_REPORTER_RECOVER                = 0x36
+	DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE               = 0x37
+	DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET               = 0x38
+	DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR             = 0x39
+	DEVLINK_CMD_FLASH_UPDATE                           = 0x3a
+	DEVLINK_CMD_FLASH_UPDATE_END                       = 0x3b
+	DEVLINK_CMD_FLASH_UPDATE_STATUS                    = 0x3c
+	DEVLINK_CMD_TRAP_GET                               = 0x3d
+	DEVLINK_CMD_TRAP_SET                               = 0x3e
+	DEVLINK_CMD_TRAP_NEW                               = 0x3f
+	DEVLINK_CMD_TRAP_DEL                               = 0x40
+	DEVLINK_CMD_TRAP_GROUP_GET                         = 0x41
+	DEVLINK_CMD_TRAP_GROUP_SET                         = 0x42
+	DEVLINK_CMD_TRAP_GROUP_NEW                         = 0x43
+	DEVLINK_CMD_TRAP_GROUP_DEL                         = 0x44
+	DEVLINK_CMD_TRAP_POLICER_GET                       = 0x45
+	DEVLINK_CMD_TRAP_POLICER_SET                       = 0x46
+	DEVLINK_CMD_TRAP_POLICER_NEW                       = 0x47
+	DEVLINK_CMD_TRAP_POLICER_DEL                       = 0x48
+	DEVLINK_CMD_HEALTH_REPORTER_TEST                   = 0x49
+	DEVLINK_CMD_MAX                                    = 0x49
+	DEVLINK_PORT_TYPE_NOTSET                           = 0x0
+	DEVLINK_PORT_TYPE_AUTO                             = 0x1
+	DEVLINK_PORT_TYPE_ETH                              = 0x2
+	DEVLINK_PORT_TYPE_IB                               = 0x3
+	DEVLINK_SB_POOL_TYPE_INGRESS                       = 0x0
+	DEVLINK_SB_POOL_TYPE_EGRESS                        = 0x1
+	DEVLINK_SB_THRESHOLD_TYPE_STATIC                   = 0x0
+	DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC                  = 0x1
+	DEVLINK_ESWITCH_MODE_LEGACY                        = 0x0
+	DEVLINK_ESWITCH_MODE_SWITCHDEV                     = 0x1
+	DEVLINK_ESWITCH_INLINE_MODE_NONE                   = 0x0
+	DEVLINK_ESWITCH_INLINE_MODE_LINK                   = 0x1
+	DEVLINK_ESWITCH_INLINE_MODE_NETWORK                = 0x2
+	DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT              = 0x3
+	DEVLINK_ESWITCH_ENCAP_MODE_NONE                    = 0x0
+	DEVLINK_ESWITCH_ENCAP_MODE_BASIC                   = 0x1
+	DEVLINK_PORT_FLAVOUR_PHYSICAL                      = 0x0
+	DEVLINK_PORT_FLAVOUR_CPU                           = 0x1
+	DEVLINK_PORT_FLAVOUR_DSA                           = 0x2
+	DEVLINK_PORT_FLAVOUR_PCI_PF                        = 0x3
+	DEVLINK_PORT_FLAVOUR_PCI_VF                        = 0x4
+	DEVLINK_PORT_FLAVOUR_VIRTUAL                       = 0x5
+	DEVLINK_PORT_FLAVOUR_UNUSED                        = 0x6
+	DEVLINK_PARAM_CMODE_RUNTIME                        = 0x0
+	DEVLINK_PARAM_CMODE_DRIVERINIT                     = 0x1
+	DEVLINK_PARAM_CMODE_PERMANENT                      = 0x2
+	DEVLINK_PARAM_CMODE_MAX                            = 0x2
+	DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DRIVER          = 0x0
+	DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH           = 0x1
+	DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DISK            = 0x2
+	DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_UNKNOWN         = 0x3
+	DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_UNKNOWN = 0x0
+	DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_ALWAYS  = 0x1
+	DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_NEVER   = 0x2
+	DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_DISK    = 0x3
+	DEVLINK_ATTR_STATS_RX_PACKETS                      = 0x0
+	DEVLINK_ATTR_STATS_RX_BYTES                        = 0x1
+	DEVLINK_ATTR_STATS_RX_DROPPED                      = 0x2
+	DEVLINK_ATTR_STATS_MAX                             = 0x2
+	DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT               = 0x0
+	DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT            = 0x1
+	DEVLINK_FLASH_OVERWRITE_MAX_BIT                    = 0x1
+	DEVLINK_TRAP_ACTION_DROP                           = 0x0
+	DEVLINK_TRAP_ACTION_TRAP                           = 0x1
+	DEVLINK_TRAP_ACTION_MIRROR                         = 0x2
+	DEVLINK_TRAP_TYPE_DROP                             = 0x0
+	DEVLINK_TRAP_TYPE_EXCEPTION                        = 0x1
+	DEVLINK_TRAP_TYPE_CONTROL                          = 0x2
+	DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT            = 0x0
+	DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE          = 0x1
+	DEVLINK_RELOAD_ACTION_UNSPEC                       = 0x0
+	DEVLINK_RELOAD_ACTION_DRIVER_REINIT                = 0x1
+	DEVLINK_RELOAD_ACTION_FW_ACTIVATE                  = 0x2
+	DEVLINK_RELOAD_ACTION_MAX                          = 0x2
+	DEVLINK_RELOAD_LIMIT_UNSPEC                        = 0x0
+	DEVLINK_RELOAD_LIMIT_NO_RESET                      = 0x1
+	DEVLINK_RELOAD_LIMIT_MAX                           = 0x1
+	DEVLINK_ATTR_UNSPEC                                = 0x0
+	DEVLINK_ATTR_BUS_NAME                              = 0x1
+	DEVLINK_ATTR_DEV_NAME                              = 0x2
+	DEVLINK_ATTR_PORT_INDEX                            = 0x3
+	DEVLINK_ATTR_PORT_TYPE                             = 0x4
+	DEVLINK_ATTR_PORT_DESIRED_TYPE                     = 0x5
+	DEVLINK_ATTR_PORT_NETDEV_IFINDEX                   = 0x6
+	DEVLINK_ATTR_PORT_NETDEV_NAME                      = 0x7
+	DEVLINK_ATTR_PORT_IBDEV_NAME                       = 0x8
+	DEVLINK_ATTR_PORT_SPLIT_COUNT                      = 0x9
+	DEVLINK_ATTR_PORT_SPLIT_GROUP                      = 0xa
+	DEVLINK_ATTR_SB_INDEX                              = 0xb
+	DEVLINK_ATTR_SB_SIZE                               = 0xc
+	DEVLINK_ATTR_SB_INGRESS_POOL_COUNT                 = 0xd
+	DEVLINK_ATTR_SB_EGRESS_POOL_COUNT                  = 0xe
+	DEVLINK_ATTR_SB_INGRESS_TC_COUNT                   = 0xf
+	DEVLINK_ATTR_SB_EGRESS_TC_COUNT                    = 0x10
+	DEVLINK_ATTR_SB_POOL_INDEX                         = 0x11
+	DEVLINK_ATTR_SB_POOL_TYPE                          = 0x12
+	DEVLINK_ATTR_SB_POOL_SIZE                          = 0x13
+	DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE                = 0x14
+	DEVLINK_ATTR_SB_THRESHOLD                          = 0x15
+	DEVLINK_ATTR_SB_TC_INDEX                           = 0x16
+	DEVLINK_ATTR_SB_OCC_CUR                            = 0x17
+	DEVLINK_ATTR_SB_OCC_MAX                            = 0x18
+	DEVLINK_ATTR_ESWITCH_MODE                          = 0x19
+	DEVLINK_ATTR_ESWITCH_INLINE_MODE                   = 0x1a
+	DEVLINK_ATTR_DPIPE_TABLES                          = 0x1b
+	DEVLINK_ATTR_DPIPE_TABLE                           = 0x1c
+	DEVLINK_ATTR_DPIPE_TABLE_NAME                      = 0x1d
+	DEVLINK_ATTR_DPIPE_TABLE_SIZE                      = 0x1e
+	DEVLINK_ATTR_DPIPE_TABLE_MATCHES                   = 0x1f
+	DEVLINK_ATTR_DPIPE_TABLE_ACTIONS                   = 0x20
+	DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED          = 0x21
+	DEVLINK_ATTR_DPIPE_ENTRIES                         = 0x22
+	DEVLINK_ATTR_DPIPE_ENTRY                           = 0x23
+	DEVLINK_ATTR_DPIPE_ENTRY_INDEX                     = 0x24
+	DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES              = 0x25
+	DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES             = 0x26
+	DEVLINK_ATTR_DPIPE_ENTRY_COUNTER                   = 0x27
+	DEVLINK_ATTR_DPIPE_MATCH                           = 0x28
+	DEVLINK_ATTR_DPIPE_MATCH_VALUE                     = 0x29
+	DEVLINK_ATTR_DPIPE_MATCH_TYPE                      = 0x2a
+	DEVLINK_ATTR_DPIPE_ACTION                          = 0x2b
+	DEVLINK_ATTR_DPIPE_ACTION_VALUE                    = 0x2c
+	DEVLINK_ATTR_DPIPE_ACTION_TYPE                     = 0x2d
+	DEVLINK_ATTR_DPIPE_VALUE                           = 0x2e
+	DEVLINK_ATTR_DPIPE_VALUE_MASK                      = 0x2f
+	DEVLINK_ATTR_DPIPE_VALUE_MAPPING                   = 0x30
+	DEVLINK_ATTR_DPIPE_HEADERS                         = 0x31
+	DEVLINK_ATTR_DPIPE_HEADER                          = 0x32
+	DEVLINK_ATTR_DPIPE_HEADER_NAME                     = 0x33
+	DEVLINK_ATTR_DPIPE_HEADER_ID                       = 0x34
+	DEVLINK_ATTR_DPIPE_HEADER_FIELDS                   = 0x35
+	DEVLINK_ATTR_DPIPE_HEADER_GLOBAL                   = 0x36
+	DEVLINK_ATTR_DPIPE_HEADER_INDEX                    = 0x37
+	DEVLINK_ATTR_DPIPE_FIELD                           = 0x38
+	DEVLINK_ATTR_DPIPE_FIELD_NAME                      = 0x39
+	DEVLINK_ATTR_DPIPE_FIELD_ID                        = 0x3a
+	DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH                  = 0x3b
+	DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE              = 0x3c
+	DEVLINK_ATTR_PAD                                   = 0x3d
+	DEVLINK_ATTR_ESWITCH_ENCAP_MODE                    = 0x3e
+	DEVLINK_ATTR_RESOURCE_LIST                         = 0x3f
+	DEVLINK_ATTR_RESOURCE                              = 0x40
+	DEVLINK_ATTR_RESOURCE_NAME                         = 0x41
+	DEVLINK_ATTR_RESOURCE_ID                           = 0x42
+	DEVLINK_ATTR_RESOURCE_SIZE                         = 0x43
+	DEVLINK_ATTR_RESOURCE_SIZE_NEW                     = 0x44
+	DEVLINK_ATTR_RESOURCE_SIZE_VALID                   = 0x45
+	DEVLINK_ATTR_RESOURCE_SIZE_MIN                     = 0x46
+	DEVLINK_ATTR_RESOURCE_SIZE_MAX                     = 0x47
+	DEVLINK_ATTR_RESOURCE_SIZE_GRAN                    = 0x48
+	DEVLINK_ATTR_RESOURCE_UNIT                         = 0x49
+	DEVLINK_ATTR_RESOURCE_OCC                          = 0x4a
+	DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID               = 0x4b
+	DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS            = 0x4c
+	DEVLINK_ATTR_PORT_FLAVOUR                          = 0x4d
+	DEVLINK_ATTR_PORT_NUMBER                           = 0x4e
+	DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER             = 0x4f
+	DEVLINK_ATTR_PARAM                                 = 0x50
+	DEVLINK_ATTR_PARAM_NAME                            = 0x51
+	DEVLINK_ATTR_PARAM_GENERIC                         = 0x52
+	DEVLINK_ATTR_PARAM_TYPE                            = 0x53
+	DEVLINK_ATTR_PARAM_VALUES_LIST                     = 0x54
+	DEVLINK_ATTR_PARAM_VALUE                           = 0x55
+	DEVLINK_ATTR_PARAM_VALUE_DATA                      = 0x56
+	DEVLINK_ATTR_PARAM_VALUE_CMODE                     = 0x57
+	DEVLINK_ATTR_REGION_NAME                           = 0x58
+	DEVLINK_ATTR_REGION_SIZE                           = 0x59
+	DEVLINK_ATTR_REGION_SNAPSHOTS                      = 0x5a
+	DEVLINK_ATTR_REGION_SNAPSHOT                       = 0x5b
+	DEVLINK_ATTR_REGION_SNAPSHOT_ID                    = 0x5c
+	DEVLINK_ATTR_REGION_CHUNKS                         = 0x5d
+	DEVLINK_ATTR_REGION_CHUNK                          = 0x5e
+	DEVLINK_ATTR_REGION_CHUNK_DATA                     = 0x5f
+	DEVLINK_ATTR_REGION_CHUNK_ADDR                     = 0x60
+	DEVLINK_ATTR_REGION_CHUNK_LEN                      = 0x61
+	DEVLINK_ATTR_INFO_DRIVER_NAME                      = 0x62
+	DEVLINK_ATTR_INFO_SERIAL_NUMBER                    = 0x63
+	DEVLINK_ATTR_INFO_VERSION_FIXED                    = 0x64
+	DEVLINK_ATTR_INFO_VERSION_RUNNING                  = 0x65
+	DEVLINK_ATTR_INFO_VERSION_STORED                   = 0x66
+	DEVLINK_ATTR_INFO_VERSION_NAME                     = 0x67
+	DEVLINK_ATTR_INFO_VERSION_VALUE                    = 0x68
+	DEVLINK_ATTR_SB_POOL_CELL_SIZE                     = 0x69
+	DEVLINK_ATTR_FMSG                                  = 0x6a
+	DEVLINK_ATTR_FMSG_OBJ_NEST_START                   = 0x6b
+	DEVLINK_ATTR_FMSG_PAIR_NEST_START                  = 0x6c
+	DEVLINK_ATTR_FMSG_ARR_NEST_START                   = 0x6d
+	DEVLINK_ATTR_FMSG_NEST_END                         = 0x6e
+	DEVLINK_ATTR_FMSG_OBJ_NAME                         = 0x6f
+	DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE                   = 0x70
+	DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA                   = 0x71
+	DEVLINK_ATTR_HEALTH_REPORTER                       = 0x72
+	DEVLINK_ATTR_HEALTH_REPORTER_NAME                  = 0x73
+	DEVLINK_ATTR_HEALTH_REPORTER_STATE                 = 0x74
+	DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT             = 0x75
+	DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT         = 0x76
+	DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS               = 0x77
+	DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD       = 0x78
+	DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER          = 0x79
+	DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME                = 0x7a
+	DEVLINK_ATTR_FLASH_UPDATE_COMPONENT                = 0x7b
+	DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG               = 0x7c
+	DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE              = 0x7d
+	DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL             = 0x7e
+	DEVLINK_ATTR_PORT_PCI_PF_NUMBER                    = 0x7f
+	DEVLINK_ATTR_PORT_PCI_VF_NUMBER                    = 0x80
+	DEVLINK_ATTR_STATS                                 = 0x81
+	DEVLINK_ATTR_TRAP_NAME                             = 0x82
+	DEVLINK_ATTR_TRAP_ACTION                           = 0x83
+	DEVLINK_ATTR_TRAP_TYPE                             = 0x84
+	DEVLINK_ATTR_TRAP_GENERIC                          = 0x85
+	DEVLINK_ATTR_TRAP_METADATA                         = 0x86
+	DEVLINK_ATTR_TRAP_GROUP_NAME                       = 0x87
+	DEVLINK_ATTR_RELOAD_FAILED                         = 0x88
+	DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS            = 0x89
+	DEVLINK_ATTR_NETNS_FD                              = 0x8a
+	DEVLINK_ATTR_NETNS_PID                             = 0x8b
+	DEVLINK_ATTR_NETNS_ID                              = 0x8c
+	DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP             = 0x8d
+	DEVLINK_ATTR_TRAP_POLICER_ID                       = 0x8e
+	DEVLINK_ATTR_TRAP_POLICER_RATE                     = 0x8f
+	DEVLINK_ATTR_TRAP_POLICER_BURST                    = 0x90
+	DEVLINK_ATTR_PORT_FUNCTION                         = 0x91
+	DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER              = 0x92
+	DEVLINK_ATTR_PORT_LANES                            = 0x93
+	DEVLINK_ATTR_PORT_SPLITTABLE                       = 0x94
+	DEVLINK_ATTR_PORT_EXTERNAL                         = 0x95
+	DEVLINK_ATTR_PORT_CONTROLLER_NUMBER                = 0x96
+	DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT           = 0x97
+	DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK           = 0x98
+	DEVLINK_ATTR_RELOAD_ACTION                         = 0x99
+	DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED              = 0x9a
+	DEVLINK_ATTR_RELOAD_LIMITS                         = 0x9b
+	DEVLINK_ATTR_DEV_STATS                             = 0x9c
+	DEVLINK_ATTR_RELOAD_STATS                          = 0x9d
+	DEVLINK_ATTR_RELOAD_STATS_ENTRY                    = 0x9e
+	DEVLINK_ATTR_RELOAD_STATS_LIMIT                    = 0x9f
+	DEVLINK_ATTR_RELOAD_STATS_VALUE                    = 0xa0
+	DEVLINK_ATTR_REMOTE_RELOAD_STATS                   = 0xa1
+	DEVLINK_ATTR_RELOAD_ACTION_INFO                    = 0xa2
+	DEVLINK_ATTR_RELOAD_ACTION_STATS                   = 0xa3
+	DEVLINK_ATTR_PORT_PCI_SF_NUMBER                    = 0xa4
+	DEVLINK_ATTR_MAX                                   = 0xa4
+	DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE              = 0x0
+	DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX           = 0x1
+	DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT               = 0x0
+	DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY             = 0x0
+	DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC               = 0x0
+	DEVLINK_DPIPE_FIELD_IPV4_DST_IP                    = 0x0
+	DEVLINK_DPIPE_FIELD_IPV6_DST_IP                    = 0x0
+	DEVLINK_DPIPE_HEADER_ETHERNET                      = 0x0
+	DEVLINK_DPIPE_HEADER_IPV4                          = 0x1
+	DEVLINK_DPIPE_HEADER_IPV6                          = 0x2
+	DEVLINK_RESOURCE_UNIT_ENTRY                        = 0x0
+	DEVLINK_PORT_FUNCTION_ATTR_UNSPEC                  = 0x0
+	DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR                 = 0x1
+	DEVLINK_PORT_FN_ATTR_STATE                         = 0x2
+	DEVLINK_PORT_FN_ATTR_OPSTATE                       = 0x3
+	DEVLINK_PORT_FUNCTION_ATTR_MAX                     = 0x3
 )
 
 type FsverityDigest struct {
@@ -2999,3 +3245,500 @@
 	MPLS_IPTUNNEL_TTL    = 0x2
 	MPLS_IPTUNNEL_MAX    = 0x2
 )
+
+const (
+	ETHTOOL_ID_UNSPEC                                                       = 0x0
+	ETHTOOL_RX_COPYBREAK                                                    = 0x1
+	ETHTOOL_TX_COPYBREAK                                                    = 0x2
+	ETHTOOL_PFC_PREVENTION_TOUT                                             = 0x3
+	ETHTOOL_TUNABLE_UNSPEC                                                  = 0x0
+	ETHTOOL_TUNABLE_U8                                                      = 0x1
+	ETHTOOL_TUNABLE_U16                                                     = 0x2
+	ETHTOOL_TUNABLE_U32                                                     = 0x3
+	ETHTOOL_TUNABLE_U64                                                     = 0x4
+	ETHTOOL_TUNABLE_STRING                                                  = 0x5
+	ETHTOOL_TUNABLE_S8                                                      = 0x6
+	ETHTOOL_TUNABLE_S16                                                     = 0x7
+	ETHTOOL_TUNABLE_S32                                                     = 0x8
+	ETHTOOL_TUNABLE_S64                                                     = 0x9
+	ETHTOOL_PHY_ID_UNSPEC                                                   = 0x0
+	ETHTOOL_PHY_DOWNSHIFT                                                   = 0x1
+	ETHTOOL_PHY_FAST_LINK_DOWN                                              = 0x2
+	ETHTOOL_PHY_EDPD                                                        = 0x3
+	ETHTOOL_LINK_EXT_STATE_AUTONEG                                          = 0x0
+	ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE                            = 0x1
+	ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH                            = 0x2
+	ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY                             = 0x3
+	ETHTOOL_LINK_EXT_STATE_NO_CABLE                                         = 0x4
+	ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE                                      = 0x5
+	ETHTOOL_LINK_EXT_STATE_EEPROM_ISSUE                                     = 0x6
+	ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE                              = 0x7
+	ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED                            = 0x8
+	ETHTOOL_LINK_EXT_STATE_OVERHEAT                                         = 0x9
+	ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED                        = 0x1
+	ETHTOOL_LINK_EXT_SUBSTATE_AN_ACK_NOT_RECEIVED                           = 0x2
+	ETHTOOL_LINK_EXT_SUBSTATE_AN_NEXT_PAGE_EXCHANGE_FAILED                  = 0x3
+	ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED_FORCE_MODE             = 0x4
+	ETHTOOL_LINK_EXT_SUBSTATE_AN_FEC_MISMATCH_DURING_OVERRIDE               = 0x5
+	ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_HCD                                     = 0x6
+	ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_FRAME_LOCK_NOT_ACQUIRED                 = 0x1
+	ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_INHIBIT_TIMEOUT                    = 0x2
+	ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_PARTNER_DID_NOT_SET_RECEIVER_READY = 0x3
+	ETHTOOL_LINK_EXT_SUBSTATE_LT_REMOTE_FAULT                               = 0x4
+	ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_BLOCK_LOCK            = 0x1
+	ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_AM_LOCK               = 0x2
+	ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_GET_ALIGN_STATUS              = 0x3
+	ETHTOOL_LINK_EXT_SUBSTATE_LLM_FC_FEC_IS_NOT_LOCKED                      = 0x4
+	ETHTOOL_LINK_EXT_SUBSTATE_LLM_RS_FEC_IS_NOT_LOCKED                      = 0x5
+	ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS           = 0x1
+	ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE                          = 0x2
+	ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE                          = 0x1
+	ETHTOOL_LINK_EXT_SUBSTATE_CI_CABLE_TEST_FAILURE                         = 0x2
+	ETHTOOL_FLASH_ALL_REGIONS                                               = 0x0
+	ETHTOOL_F_UNSUPPORTED__BIT                                              = 0x0
+	ETHTOOL_F_WISH__BIT                                                     = 0x1
+	ETHTOOL_F_COMPAT__BIT                                                   = 0x2
+	ETHTOOL_FEC_NONE_BIT                                                    = 0x0
+	ETHTOOL_FEC_AUTO_BIT                                                    = 0x1
+	ETHTOOL_FEC_OFF_BIT                                                     = 0x2
+	ETHTOOL_FEC_RS_BIT                                                      = 0x3
+	ETHTOOL_FEC_BASER_BIT                                                   = 0x4
+	ETHTOOL_FEC_LLRS_BIT                                                    = 0x5
+	ETHTOOL_LINK_MODE_10baseT_Half_BIT                                      = 0x0
+	ETHTOOL_LINK_MODE_10baseT_Full_BIT                                      = 0x1
+	ETHTOOL_LINK_MODE_100baseT_Half_BIT                                     = 0x2
+	ETHTOOL_LINK_MODE_100baseT_Full_BIT                                     = 0x3
+	ETHTOOL_LINK_MODE_1000baseT_Half_BIT                                    = 0x4
+	ETHTOOL_LINK_MODE_1000baseT_Full_BIT                                    = 0x5
+	ETHTOOL_LINK_MODE_Autoneg_BIT                                           = 0x6
+	ETHTOOL_LINK_MODE_TP_BIT                                                = 0x7
+	ETHTOOL_LINK_MODE_AUI_BIT                                               = 0x8
+	ETHTOOL_LINK_MODE_MII_BIT                                               = 0x9
+	ETHTOOL_LINK_MODE_FIBRE_BIT                                             = 0xa
+	ETHTOOL_LINK_MODE_BNC_BIT                                               = 0xb
+	ETHTOOL_LINK_MODE_10000baseT_Full_BIT                                   = 0xc
+	ETHTOOL_LINK_MODE_Pause_BIT                                             = 0xd
+	ETHTOOL_LINK_MODE_Asym_Pause_BIT                                        = 0xe
+	ETHTOOL_LINK_MODE_2500baseX_Full_BIT                                    = 0xf
+	ETHTOOL_LINK_MODE_Backplane_BIT                                         = 0x10
+	ETHTOOL_LINK_MODE_1000baseKX_Full_BIT                                   = 0x11
+	ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT                                 = 0x12
+	ETHTOOL_LINK_MODE_10000baseKR_Full_BIT                                  = 0x13
+	ETHTOOL_LINK_MODE_10000baseR_FEC_BIT                                    = 0x14
+	ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT                                = 0x15
+	ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT                                 = 0x16
+	ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT                                 = 0x17
+	ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT                                 = 0x18
+	ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT                                 = 0x19
+	ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT                                 = 0x1a
+	ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT                                 = 0x1b
+	ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT                                 = 0x1c
+	ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT                                 = 0x1d
+	ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT                                 = 0x1e
+	ETHTOOL_LINK_MODE_25000baseCR_Full_BIT                                  = 0x1f
+	ETHTOOL_LINK_MODE_25000baseKR_Full_BIT                                  = 0x20
+	ETHTOOL_LINK_MODE_25000baseSR_Full_BIT                                  = 0x21
+	ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT                                 = 0x22
+	ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT                                 = 0x23
+	ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT                                = 0x24
+	ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT                                = 0x25
+	ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT                                = 0x26
+	ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT                            = 0x27
+	ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT                                 = 0x28
+	ETHTOOL_LINK_MODE_1000baseX_Full_BIT                                    = 0x29
+	ETHTOOL_LINK_MODE_10000baseCR_Full_BIT                                  = 0x2a
+	ETHTOOL_LINK_MODE_10000baseSR_Full_BIT                                  = 0x2b
+	ETHTOOL_LINK_MODE_10000baseLR_Full_BIT                                  = 0x2c
+	ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT                                 = 0x2d
+	ETHTOOL_LINK_MODE_10000baseER_Full_BIT                                  = 0x2e
+	ETHTOOL_LINK_MODE_2500baseT_Full_BIT                                    = 0x2f
+	ETHTOOL_LINK_MODE_5000baseT_Full_BIT                                    = 0x30
+	ETHTOOL_LINK_MODE_FEC_NONE_BIT                                          = 0x31
+	ETHTOOL_LINK_MODE_FEC_RS_BIT                                            = 0x32
+	ETHTOOL_LINK_MODE_FEC_BASER_BIT                                         = 0x33
+	ETHTOOL_LINK_MODE_50000baseKR_Full_BIT                                  = 0x34
+	ETHTOOL_LINK_MODE_50000baseSR_Full_BIT                                  = 0x35
+	ETHTOOL_LINK_MODE_50000baseCR_Full_BIT                                  = 0x36
+	ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT                            = 0x37
+	ETHTOOL_LINK_MODE_50000baseDR_Full_BIT                                  = 0x38
+	ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT                                = 0x39
+	ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT                                = 0x3a
+	ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT                                = 0x3b
+	ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT                        = 0x3c
+	ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT                                = 0x3d
+	ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT                                = 0x3e
+	ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT                                = 0x3f
+	ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT                        = 0x40
+	ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT                                = 0x41
+	ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT                                = 0x42
+	ETHTOOL_LINK_MODE_100baseT1_Full_BIT                                    = 0x43
+	ETHTOOL_LINK_MODE_1000baseT1_Full_BIT                                   = 0x44
+	ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT                                = 0x45
+	ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT                                = 0x46
+	ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT                        = 0x47
+	ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT                                = 0x48
+	ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT                                = 0x49
+	ETHTOOL_LINK_MODE_FEC_LLRS_BIT                                          = 0x4a
+	ETHTOOL_LINK_MODE_100000baseKR_Full_BIT                                 = 0x4b
+	ETHTOOL_LINK_MODE_100000baseSR_Full_BIT                                 = 0x4c
+	ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT                           = 0x4d
+	ETHTOOL_LINK_MODE_100000baseCR_Full_BIT                                 = 0x4e
+	ETHTOOL_LINK_MODE_100000baseDR_Full_BIT                                 = 0x4f
+	ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT                                = 0x50
+	ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT                                = 0x51
+	ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT                        = 0x52
+	ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT                                = 0x53
+	ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT                                = 0x54
+	ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT                                = 0x55
+	ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT                                = 0x56
+	ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT                        = 0x57
+	ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT                                = 0x58
+	ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT                                = 0x59
+	ETHTOOL_LINK_MODE_100baseFX_Half_BIT                                    = 0x5a
+	ETHTOOL_LINK_MODE_100baseFX_Full_BIT                                    = 0x5b
+
+	ETHTOOL_MSG_USER_NONE                     = 0x0
+	ETHTOOL_MSG_STRSET_GET                    = 0x1
+	ETHTOOL_MSG_LINKINFO_GET                  = 0x2
+	ETHTOOL_MSG_LINKINFO_SET                  = 0x3
+	ETHTOOL_MSG_LINKMODES_GET                 = 0x4
+	ETHTOOL_MSG_LINKMODES_SET                 = 0x5
+	ETHTOOL_MSG_LINKSTATE_GET                 = 0x6
+	ETHTOOL_MSG_DEBUG_GET                     = 0x7
+	ETHTOOL_MSG_DEBUG_SET                     = 0x8
+	ETHTOOL_MSG_WOL_GET                       = 0x9
+	ETHTOOL_MSG_WOL_SET                       = 0xa
+	ETHTOOL_MSG_FEATURES_GET                  = 0xb
+	ETHTOOL_MSG_FEATURES_SET                  = 0xc
+	ETHTOOL_MSG_PRIVFLAGS_GET                 = 0xd
+	ETHTOOL_MSG_PRIVFLAGS_SET                 = 0xe
+	ETHTOOL_MSG_RINGS_GET                     = 0xf
+	ETHTOOL_MSG_RINGS_SET                     = 0x10
+	ETHTOOL_MSG_CHANNELS_GET                  = 0x11
+	ETHTOOL_MSG_CHANNELS_SET                  = 0x12
+	ETHTOOL_MSG_COALESCE_GET                  = 0x13
+	ETHTOOL_MSG_COALESCE_SET                  = 0x14
+	ETHTOOL_MSG_PAUSE_GET                     = 0x15
+	ETHTOOL_MSG_PAUSE_SET                     = 0x16
+	ETHTOOL_MSG_EEE_GET                       = 0x17
+	ETHTOOL_MSG_EEE_SET                       = 0x18
+	ETHTOOL_MSG_TSINFO_GET                    = 0x19
+	ETHTOOL_MSG_CABLE_TEST_ACT                = 0x1a
+	ETHTOOL_MSG_CABLE_TEST_TDR_ACT            = 0x1b
+	ETHTOOL_MSG_TUNNEL_INFO_GET               = 0x1c
+	ETHTOOL_MSG_USER_MAX                      = 0x1c
+	ETHTOOL_MSG_KERNEL_NONE                   = 0x0
+	ETHTOOL_MSG_STRSET_GET_REPLY              = 0x1
+	ETHTOOL_MSG_LINKINFO_GET_REPLY            = 0x2
+	ETHTOOL_MSG_LINKINFO_NTF                  = 0x3
+	ETHTOOL_MSG_LINKMODES_GET_REPLY           = 0x4
+	ETHTOOL_MSG_LINKMODES_NTF                 = 0x5
+	ETHTOOL_MSG_LINKSTATE_GET_REPLY           = 0x6
+	ETHTOOL_MSG_DEBUG_GET_REPLY               = 0x7
+	ETHTOOL_MSG_DEBUG_NTF                     = 0x8
+	ETHTOOL_MSG_WOL_GET_REPLY                 = 0x9
+	ETHTOOL_MSG_WOL_NTF                       = 0xa
+	ETHTOOL_MSG_FEATURES_GET_REPLY            = 0xb
+	ETHTOOL_MSG_FEATURES_SET_REPLY            = 0xc
+	ETHTOOL_MSG_FEATURES_NTF                  = 0xd
+	ETHTOOL_MSG_PRIVFLAGS_GET_REPLY           = 0xe
+	ETHTOOL_MSG_PRIVFLAGS_NTF                 = 0xf
+	ETHTOOL_MSG_RINGS_GET_REPLY               = 0x10
+	ETHTOOL_MSG_RINGS_NTF                     = 0x11
+	ETHTOOL_MSG_CHANNELS_GET_REPLY            = 0x12
+	ETHTOOL_MSG_CHANNELS_NTF                  = 0x13
+	ETHTOOL_MSG_COALESCE_GET_REPLY            = 0x14
+	ETHTOOL_MSG_COALESCE_NTF                  = 0x15
+	ETHTOOL_MSG_PAUSE_GET_REPLY               = 0x16
+	ETHTOOL_MSG_PAUSE_NTF                     = 0x17
+	ETHTOOL_MSG_EEE_GET_REPLY                 = 0x18
+	ETHTOOL_MSG_EEE_NTF                       = 0x19
+	ETHTOOL_MSG_TSINFO_GET_REPLY              = 0x1a
+	ETHTOOL_MSG_CABLE_TEST_NTF                = 0x1b
+	ETHTOOL_MSG_CABLE_TEST_TDR_NTF            = 0x1c
+	ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY         = 0x1d
+	ETHTOOL_MSG_KERNEL_MAX                    = 0x1d
+	ETHTOOL_A_HEADER_UNSPEC                   = 0x0
+	ETHTOOL_A_HEADER_DEV_INDEX                = 0x1
+	ETHTOOL_A_HEADER_DEV_NAME                 = 0x2
+	ETHTOOL_A_HEADER_FLAGS                    = 0x3
+	ETHTOOL_A_HEADER_MAX                      = 0x3
+	ETHTOOL_A_BITSET_BIT_UNSPEC               = 0x0
+	ETHTOOL_A_BITSET_BIT_INDEX                = 0x1
+	ETHTOOL_A_BITSET_BIT_NAME                 = 0x2
+	ETHTOOL_A_BITSET_BIT_VALUE                = 0x3
+	ETHTOOL_A_BITSET_BIT_MAX                  = 0x3
+	ETHTOOL_A_BITSET_BITS_UNSPEC              = 0x0
+	ETHTOOL_A_BITSET_BITS_BIT                 = 0x1
+	ETHTOOL_A_BITSET_BITS_MAX                 = 0x1
+	ETHTOOL_A_BITSET_UNSPEC                   = 0x0
+	ETHTOOL_A_BITSET_NOMASK                   = 0x1
+	ETHTOOL_A_BITSET_SIZE                     = 0x2
+	ETHTOOL_A_BITSET_BITS                     = 0x3
+	ETHTOOL_A_BITSET_VALUE                    = 0x4
+	ETHTOOL_A_BITSET_MASK                     = 0x5
+	ETHTOOL_A_BITSET_MAX                      = 0x5
+	ETHTOOL_A_STRING_UNSPEC                   = 0x0
+	ETHTOOL_A_STRING_INDEX                    = 0x1
+	ETHTOOL_A_STRING_VALUE                    = 0x2
+	ETHTOOL_A_STRING_MAX                      = 0x2
+	ETHTOOL_A_STRINGS_UNSPEC                  = 0x0
+	ETHTOOL_A_STRINGS_STRING                  = 0x1
+	ETHTOOL_A_STRINGS_MAX                     = 0x1
+	ETHTOOL_A_STRINGSET_UNSPEC                = 0x0
+	ETHTOOL_A_STRINGSET_ID                    = 0x1
+	ETHTOOL_A_STRINGSET_COUNT                 = 0x2
+	ETHTOOL_A_STRINGSET_STRINGS               = 0x3
+	ETHTOOL_A_STRINGSET_MAX                   = 0x3
+	ETHTOOL_A_STRINGSETS_UNSPEC               = 0x0
+	ETHTOOL_A_STRINGSETS_STRINGSET            = 0x1
+	ETHTOOL_A_STRINGSETS_MAX                  = 0x1
+	ETHTOOL_A_STRSET_UNSPEC                   = 0x0
+	ETHTOOL_A_STRSET_HEADER                   = 0x1
+	ETHTOOL_A_STRSET_STRINGSETS               = 0x2
+	ETHTOOL_A_STRSET_COUNTS_ONLY              = 0x3
+	ETHTOOL_A_STRSET_MAX                      = 0x3
+	ETHTOOL_A_LINKINFO_UNSPEC                 = 0x0
+	ETHTOOL_A_LINKINFO_HEADER                 = 0x1
+	ETHTOOL_A_LINKINFO_PORT                   = 0x2
+	ETHTOOL_A_LINKINFO_PHYADDR                = 0x3
+	ETHTOOL_A_LINKINFO_TP_MDIX                = 0x4
+	ETHTOOL_A_LINKINFO_TP_MDIX_CTRL           = 0x5
+	ETHTOOL_A_LINKINFO_TRANSCEIVER            = 0x6
+	ETHTOOL_A_LINKINFO_MAX                    = 0x6
+	ETHTOOL_A_LINKMODES_UNSPEC                = 0x0
+	ETHTOOL_A_LINKMODES_HEADER                = 0x1
+	ETHTOOL_A_LINKMODES_AUTONEG               = 0x2
+	ETHTOOL_A_LINKMODES_OURS                  = 0x3
+	ETHTOOL_A_LINKMODES_PEER                  = 0x4
+	ETHTOOL_A_LINKMODES_SPEED                 = 0x5
+	ETHTOOL_A_LINKMODES_DUPLEX                = 0x6
+	ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG      = 0x7
+	ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE    = 0x8
+	ETHTOOL_A_LINKMODES_LANES                 = 0x9
+	ETHTOOL_A_LINKMODES_MAX                   = 0x9
+	ETHTOOL_A_LINKSTATE_UNSPEC                = 0x0
+	ETHTOOL_A_LINKSTATE_HEADER                = 0x1
+	ETHTOOL_A_LINKSTATE_LINK                  = 0x2
+	ETHTOOL_A_LINKSTATE_SQI                   = 0x3
+	ETHTOOL_A_LINKSTATE_SQI_MAX               = 0x4
+	ETHTOOL_A_LINKSTATE_EXT_STATE             = 0x5
+	ETHTOOL_A_LINKSTATE_EXT_SUBSTATE          = 0x6
+	ETHTOOL_A_LINKSTATE_MAX                   = 0x6
+	ETHTOOL_A_DEBUG_UNSPEC                    = 0x0
+	ETHTOOL_A_DEBUG_HEADER                    = 0x1
+	ETHTOOL_A_DEBUG_MSGMASK                   = 0x2
+	ETHTOOL_A_DEBUG_MAX                       = 0x2
+	ETHTOOL_A_WOL_UNSPEC                      = 0x0
+	ETHTOOL_A_WOL_HEADER                      = 0x1
+	ETHTOOL_A_WOL_MODES                       = 0x2
+	ETHTOOL_A_WOL_SOPASS                      = 0x3
+	ETHTOOL_A_WOL_MAX                         = 0x3
+	ETHTOOL_A_FEATURES_UNSPEC                 = 0x0
+	ETHTOOL_A_FEATURES_HEADER                 = 0x1
+	ETHTOOL_A_FEATURES_HW                     = 0x2
+	ETHTOOL_A_FEATURES_WANTED                 = 0x3
+	ETHTOOL_A_FEATURES_ACTIVE                 = 0x4
+	ETHTOOL_A_FEATURES_NOCHANGE               = 0x5
+	ETHTOOL_A_FEATURES_MAX                    = 0x5
+	ETHTOOL_A_PRIVFLAGS_UNSPEC                = 0x0
+	ETHTOOL_A_PRIVFLAGS_HEADER                = 0x1
+	ETHTOOL_A_PRIVFLAGS_FLAGS                 = 0x2
+	ETHTOOL_A_PRIVFLAGS_MAX                   = 0x2
+	ETHTOOL_A_RINGS_UNSPEC                    = 0x0
+	ETHTOOL_A_RINGS_HEADER                    = 0x1
+	ETHTOOL_A_RINGS_RX_MAX                    = 0x2
+	ETHTOOL_A_RINGS_RX_MINI_MAX               = 0x3
+	ETHTOOL_A_RINGS_RX_JUMBO_MAX              = 0x4
+	ETHTOOL_A_RINGS_TX_MAX                    = 0x5
+	ETHTOOL_A_RINGS_RX                        = 0x6
+	ETHTOOL_A_RINGS_RX_MINI                   = 0x7
+	ETHTOOL_A_RINGS_RX_JUMBO                  = 0x8
+	ETHTOOL_A_RINGS_TX                        = 0x9
+	ETHTOOL_A_RINGS_MAX                       = 0x9
+	ETHTOOL_A_CHANNELS_UNSPEC                 = 0x0
+	ETHTOOL_A_CHANNELS_HEADER                 = 0x1
+	ETHTOOL_A_CHANNELS_RX_MAX                 = 0x2
+	ETHTOOL_A_CHANNELS_TX_MAX                 = 0x3
+	ETHTOOL_A_CHANNELS_OTHER_MAX              = 0x4
+	ETHTOOL_A_CHANNELS_COMBINED_MAX           = 0x5
+	ETHTOOL_A_CHANNELS_RX_COUNT               = 0x6
+	ETHTOOL_A_CHANNELS_TX_COUNT               = 0x7
+	ETHTOOL_A_CHANNELS_OTHER_COUNT            = 0x8
+	ETHTOOL_A_CHANNELS_COMBINED_COUNT         = 0x9
+	ETHTOOL_A_CHANNELS_MAX                    = 0x9
+	ETHTOOL_A_COALESCE_UNSPEC                 = 0x0
+	ETHTOOL_A_COALESCE_HEADER                 = 0x1
+	ETHTOOL_A_COALESCE_RX_USECS               = 0x2
+	ETHTOOL_A_COALESCE_RX_MAX_FRAMES          = 0x3
+	ETHTOOL_A_COALESCE_RX_USECS_IRQ           = 0x4
+	ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ      = 0x5
+	ETHTOOL_A_COALESCE_TX_USECS               = 0x6
+	ETHTOOL_A_COALESCE_TX_MAX_FRAMES          = 0x7
+	ETHTOOL_A_COALESCE_TX_USECS_IRQ           = 0x8
+	ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ      = 0x9
+	ETHTOOL_A_COALESCE_STATS_BLOCK_USECS      = 0xa
+	ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX        = 0xb
+	ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX        = 0xc
+	ETHTOOL_A_COALESCE_PKT_RATE_LOW           = 0xd
+	ETHTOOL_A_COALESCE_RX_USECS_LOW           = 0xe
+	ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW      = 0xf
+	ETHTOOL_A_COALESCE_TX_USECS_LOW           = 0x10
+	ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW      = 0x11
+	ETHTOOL_A_COALESCE_PKT_RATE_HIGH          = 0x12
+	ETHTOOL_A_COALESCE_RX_USECS_HIGH          = 0x13
+	ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH     = 0x14
+	ETHTOOL_A_COALESCE_TX_USECS_HIGH          = 0x15
+	ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH     = 0x16
+	ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL   = 0x17
+	ETHTOOL_A_COALESCE_MAX                    = 0x17
+	ETHTOOL_A_PAUSE_UNSPEC                    = 0x0
+	ETHTOOL_A_PAUSE_HEADER                    = 0x1
+	ETHTOOL_A_PAUSE_AUTONEG                   = 0x2
+	ETHTOOL_A_PAUSE_RX                        = 0x3
+	ETHTOOL_A_PAUSE_TX                        = 0x4
+	ETHTOOL_A_PAUSE_STATS                     = 0x5
+	ETHTOOL_A_PAUSE_MAX                       = 0x5
+	ETHTOOL_A_PAUSE_STAT_UNSPEC               = 0x0
+	ETHTOOL_A_PAUSE_STAT_PAD                  = 0x1
+	ETHTOOL_A_PAUSE_STAT_TX_FRAMES            = 0x2
+	ETHTOOL_A_PAUSE_STAT_RX_FRAMES            = 0x3
+	ETHTOOL_A_PAUSE_STAT_MAX                  = 0x3
+	ETHTOOL_A_EEE_UNSPEC                      = 0x0
+	ETHTOOL_A_EEE_HEADER                      = 0x1
+	ETHTOOL_A_EEE_MODES_OURS                  = 0x2
+	ETHTOOL_A_EEE_MODES_PEER                  = 0x3
+	ETHTOOL_A_EEE_ACTIVE                      = 0x4
+	ETHTOOL_A_EEE_ENABLED                     = 0x5
+	ETHTOOL_A_EEE_TX_LPI_ENABLED              = 0x6
+	ETHTOOL_A_EEE_TX_LPI_TIMER                = 0x7
+	ETHTOOL_A_EEE_MAX                         = 0x7
+	ETHTOOL_A_TSINFO_UNSPEC                   = 0x0
+	ETHTOOL_A_TSINFO_HEADER                   = 0x1
+	ETHTOOL_A_TSINFO_TIMESTAMPING             = 0x2
+	ETHTOOL_A_TSINFO_TX_TYPES                 = 0x3
+	ETHTOOL_A_TSINFO_RX_FILTERS               = 0x4
+	ETHTOOL_A_TSINFO_PHC_INDEX                = 0x5
+	ETHTOOL_A_TSINFO_MAX                      = 0x5
+	ETHTOOL_A_CABLE_TEST_UNSPEC               = 0x0
+	ETHTOOL_A_CABLE_TEST_HEADER               = 0x1
+	ETHTOOL_A_CABLE_TEST_MAX                  = 0x1
+	ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC        = 0x0
+	ETHTOOL_A_CABLE_RESULT_CODE_OK            = 0x1
+	ETHTOOL_A_CABLE_RESULT_CODE_OPEN          = 0x2
+	ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT    = 0x3
+	ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT   = 0x4
+	ETHTOOL_A_CABLE_PAIR_A                    = 0x0
+	ETHTOOL_A_CABLE_PAIR_B                    = 0x1
+	ETHTOOL_A_CABLE_PAIR_C                    = 0x2
+	ETHTOOL_A_CABLE_PAIR_D                    = 0x3
+	ETHTOOL_A_CABLE_RESULT_UNSPEC             = 0x0
+	ETHTOOL_A_CABLE_RESULT_PAIR               = 0x1
+	ETHTOOL_A_CABLE_RESULT_CODE               = 0x2
+	ETHTOOL_A_CABLE_RESULT_MAX                = 0x2
+	ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC       = 0x0
+	ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR         = 0x1
+	ETHTOOL_A_CABLE_FAULT_LENGTH_CM           = 0x2
+	ETHTOOL_A_CABLE_FAULT_LENGTH_MAX          = 0x2
+	ETHTOOL_A_CABLE_TEST_NTF_STATUS_UNSPEC    = 0x0
+	ETHTOOL_A_CABLE_TEST_NTF_STATUS_STARTED   = 0x1
+	ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED = 0x2
+	ETHTOOL_A_CABLE_NEST_UNSPEC               = 0x0
+	ETHTOOL_A_CABLE_NEST_RESULT               = 0x1
+	ETHTOOL_A_CABLE_NEST_FAULT_LENGTH         = 0x2
+	ETHTOOL_A_CABLE_NEST_MAX                  = 0x2
+	ETHTOOL_A_CABLE_TEST_NTF_UNSPEC           = 0x0
+	ETHTOOL_A_CABLE_TEST_NTF_HEADER           = 0x1
+	ETHTOOL_A_CABLE_TEST_NTF_STATUS           = 0x2
+	ETHTOOL_A_CABLE_TEST_NTF_NEST             = 0x3
+	ETHTOOL_A_CABLE_TEST_NTF_MAX              = 0x3
+	ETHTOOL_A_CABLE_TEST_TDR_CFG_UNSPEC       = 0x0
+	ETHTOOL_A_CABLE_TEST_TDR_CFG_FIRST        = 0x1
+	ETHTOOL_A_CABLE_TEST_TDR_CFG_LAST         = 0x2
+	ETHTOOL_A_CABLE_TEST_TDR_CFG_STEP         = 0x3
+	ETHTOOL_A_CABLE_TEST_TDR_CFG_PAIR         = 0x4
+	ETHTOOL_A_CABLE_TEST_TDR_CFG_MAX          = 0x4
+	ETHTOOL_A_CABLE_TEST_TDR_UNSPEC           = 0x0
+	ETHTOOL_A_CABLE_TEST_TDR_HEADER           = 0x1
+	ETHTOOL_A_CABLE_TEST_TDR_CFG              = 0x2
+	ETHTOOL_A_CABLE_TEST_TDR_MAX              = 0x2
+	ETHTOOL_A_CABLE_AMPLITUDE_UNSPEC          = 0x0
+	ETHTOOL_A_CABLE_AMPLITUDE_PAIR            = 0x1
+	ETHTOOL_A_CABLE_AMPLITUDE_mV              = 0x2
+	ETHTOOL_A_CABLE_AMPLITUDE_MAX             = 0x2
+	ETHTOOL_A_CABLE_PULSE_UNSPEC              = 0x0
+	ETHTOOL_A_CABLE_PULSE_mV                  = 0x1
+	ETHTOOL_A_CABLE_PULSE_MAX                 = 0x1
+	ETHTOOL_A_CABLE_STEP_UNSPEC               = 0x0
+	ETHTOOL_A_CABLE_STEP_FIRST_DISTANCE       = 0x1
+	ETHTOOL_A_CABLE_STEP_LAST_DISTANCE        = 0x2
+	ETHTOOL_A_CABLE_STEP_STEP_DISTANCE        = 0x3
+	ETHTOOL_A_CABLE_STEP_MAX                  = 0x3
+	ETHTOOL_A_CABLE_TDR_NEST_UNSPEC           = 0x0
+	ETHTOOL_A_CABLE_TDR_NEST_STEP             = 0x1
+	ETHTOOL_A_CABLE_TDR_NEST_AMPLITUDE        = 0x2
+	ETHTOOL_A_CABLE_TDR_NEST_PULSE            = 0x3
+	ETHTOOL_A_CABLE_TDR_NEST_MAX              = 0x3
+	ETHTOOL_A_CABLE_TEST_TDR_NTF_UNSPEC       = 0x0
+	ETHTOOL_A_CABLE_TEST_TDR_NTF_HEADER       = 0x1
+	ETHTOOL_A_CABLE_TEST_TDR_NTF_STATUS       = 0x2
+	ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST         = 0x3
+	ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX          = 0x3
+	ETHTOOL_UDP_TUNNEL_TYPE_VXLAN             = 0x0
+	ETHTOOL_UDP_TUNNEL_TYPE_GENEVE            = 0x1
+	ETHTOOL_UDP_TUNNEL_TYPE_VXLAN_GPE         = 0x2
+	ETHTOOL_A_TUNNEL_UDP_ENTRY_UNSPEC         = 0x0
+	ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT           = 0x1
+	ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE           = 0x2
+	ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX            = 0x2
+	ETHTOOL_A_TUNNEL_UDP_TABLE_UNSPEC         = 0x0
+	ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE           = 0x1
+	ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES          = 0x2
+	ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY          = 0x3
+	ETHTOOL_A_TUNNEL_UDP_TABLE_MAX            = 0x3
+	ETHTOOL_A_TUNNEL_UDP_UNSPEC               = 0x0
+	ETHTOOL_A_TUNNEL_UDP_TABLE                = 0x1
+	ETHTOOL_A_TUNNEL_UDP_MAX                  = 0x1
+	ETHTOOL_A_TUNNEL_INFO_UNSPEC              = 0x0
+	ETHTOOL_A_TUNNEL_INFO_HEADER              = 0x1
+	ETHTOOL_A_TUNNEL_INFO_UDP_PORTS           = 0x2
+	ETHTOOL_A_TUNNEL_INFO_MAX                 = 0x2
+)
+
+type EthtoolDrvinfo struct {
+	Cmd          uint32
+	Driver       [32]byte
+	Version      [32]byte
+	Fw_version   [32]byte
+	Bus_info     [32]byte
+	Erom_version [32]byte
+	Reserved2    [12]byte
+	N_priv_flags uint32
+	N_stats      uint32
+	Testinfo_len uint32
+	Eedump_len   uint32
+	Regdump_len  uint32
+}
+
+type (
+	HIDRawReportDescriptor struct {
+		Size  uint32
+		Value [4096]uint8
+	}
+	HIDRawDevInfo struct {
+		Bustype uint32
+		Vendor  int16
+		Product int16
+	}
+)
+
+const (
+	CLOSE_RANGE_UNSHARE = 0x2
+	CLOSE_RANGE_CLOEXEC = 0x4
+)
+
+const (
+	NLMSGERR_ATTR_MSG    = 0x1
+	NLMSGERR_ATTR_OFFS   = 0x2
+	NLMSGERR_ATTR_COOKIE = 0x3
+)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
index d54618a..4d4d283 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build 386 && linux
 // +build 386,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
index 741d25b..8a2eed5 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && linux
 // +build amd64,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
index e8d982c..94b34ad 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm && linux
 // +build arm,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
index 311cf21..2143de4 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && linux
 // +build arm64,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
index 1312bdf..a40216e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mips && linux
 // +build mips,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
index 2a99348..e834b06 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mips64 && linux
 // +build mips64,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
index f964307..e31083b 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mips64le && linux
 // +build mips64le,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
index ca0fab2..42811f7 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mipsle && linux
 // +build mipsle,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go
new file mode 100644
index 0000000..af7a720
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go
@@ -0,0 +1,627 @@
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/linux/types.go | go run mkpost.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build ppc && linux
+// +build ppc,linux
+
+package unix
+
+const (
+	SizeofPtr  = 0x4
+	SizeofLong = 0x4
+)
+
+type (
+	_C_long int32
+)
+
+type Timespec struct {
+	Sec  int32
+	Nsec int32
+}
+
+type Timeval struct {
+	Sec  int32
+	Usec int32
+}
+
+type Timex struct {
+	Modes     uint32
+	Offset    int32
+	Freq      int32
+	Maxerror  int32
+	Esterror  int32
+	Status    int32
+	Constant  int32
+	Precision int32
+	Tolerance int32
+	Time      Timeval
+	Tick      int32
+	Ppsfreq   int32
+	Jitter    int32
+	Shift     int32
+	Stabil    int32
+	Jitcnt    int32
+	Calcnt    int32
+	Errcnt    int32
+	Stbcnt    int32
+	Tai       int32
+	_         [44]byte
+}
+
+type Time_t int32
+
+type Tms struct {
+	Utime  int32
+	Stime  int32
+	Cutime int32
+	Cstime int32
+}
+
+type Utimbuf struct {
+	Actime  int32
+	Modtime int32
+}
+
+type Rusage struct {
+	Utime    Timeval
+	Stime    Timeval
+	Maxrss   int32
+	Ixrss    int32
+	Idrss    int32
+	Isrss    int32
+	Minflt   int32
+	Majflt   int32
+	Nswap    int32
+	Inblock  int32
+	Oublock  int32
+	Msgsnd   int32
+	Msgrcv   int32
+	Nsignals int32
+	Nvcsw    int32
+	Nivcsw   int32
+}
+
+type Stat_t struct {
+	Dev     uint64
+	Ino     uint64
+	Mode    uint32
+	Nlink   uint32
+	Uid     uint32
+	Gid     uint32
+	Rdev    uint64
+	_       uint16
+	_       [4]byte
+	Size    int64
+	Blksize int32
+	_       [4]byte
+	Blocks  int64
+	Atim    Timespec
+	Mtim    Timespec
+	Ctim    Timespec
+	_       uint32
+	_       uint32
+}
+
+type Dirent struct {
+	Ino    uint64
+	Off    int64
+	Reclen uint16
+	Type   uint8
+	Name   [256]uint8
+	_      [5]byte
+}
+
+type Flock_t struct {
+	Type   int16
+	Whence int16
+	_      [4]byte
+	Start  int64
+	Len    int64
+	Pid    int32
+	_      [4]byte
+}
+
+type DmNameList struct {
+	Dev  uint64
+	Next uint32
+	Name [0]byte
+	_    [4]byte
+}
+
+const (
+	FADV_DONTNEED = 0x4
+	FADV_NOREUSE  = 0x5
+)
+
+type RawSockaddr struct {
+	Family uint16
+	Data   [14]uint8
+}
+
+type RawSockaddrAny struct {
+	Addr RawSockaddr
+	Pad  [96]uint8
+}
+
+type Iovec struct {
+	Base *byte
+	Len  uint32
+}
+
+type Msghdr struct {
+	Name       *byte
+	Namelen    uint32
+	Iov        *Iovec
+	Iovlen     uint32
+	Control    *byte
+	Controllen uint32
+	Flags      int32
+}
+
+type Cmsghdr struct {
+	Len   uint32
+	Level int32
+	Type  int32
+}
+
+const (
+	SizeofIovec   = 0x8
+	SizeofMsghdr  = 0x1c
+	SizeofCmsghdr = 0xc
+)
+
+const (
+	SizeofSockFprog = 0x8
+)
+
+type PtraceRegs struct {
+	Gpr       [32]uint32
+	Nip       uint32
+	Msr       uint32
+	Orig_gpr3 uint32
+	Ctr       uint32
+	Link      uint32
+	Xer       uint32
+	Ccr       uint32
+	Mq        uint32
+	Trap      uint32
+	Dar       uint32
+	Dsisr     uint32
+	Result    uint32
+}
+
+type FdSet struct {
+	Bits [32]int32
+}
+
+type Sysinfo_t struct {
+	Uptime    int32
+	Loads     [3]uint32
+	Totalram  uint32
+	Freeram   uint32
+	Sharedram uint32
+	Bufferram uint32
+	Totalswap uint32
+	Freeswap  uint32
+	Procs     uint16
+	Pad       uint16
+	Totalhigh uint32
+	Freehigh  uint32
+	Unit      uint32
+	_         [8]uint8
+}
+
+type Ustat_t struct {
+	Tfree  int32
+	Tinode uint32
+	Fname  [6]uint8
+	Fpack  [6]uint8
+}
+
+type EpollEvent struct {
+	Events uint32
+	_      int32
+	Fd     int32
+	Pad    int32
+}
+
+const (
+	POLLRDHUP = 0x2000
+)
+
+type Sigset_t struct {
+	Val [32]uint32
+}
+
+const _C__NSIG = 0x41
+
+type Termios struct {
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Cc     [19]uint8
+	Line   uint8
+	Ispeed uint32
+	Ospeed uint32
+}
+
+type Taskstats struct {
+	Version                   uint16
+	Ac_exitcode               uint32
+	Ac_flag                   uint8
+	Ac_nice                   uint8
+	_                         [4]byte
+	Cpu_count                 uint64
+	Cpu_delay_total           uint64
+	Blkio_count               uint64
+	Blkio_delay_total         uint64
+	Swapin_count              uint64
+	Swapin_delay_total        uint64
+	Cpu_run_real_total        uint64
+	Cpu_run_virtual_total     uint64
+	Ac_comm                   [32]uint8
+	Ac_sched                  uint8
+	Ac_pad                    [3]uint8
+	_                         [4]byte
+	Ac_uid                    uint32
+	Ac_gid                    uint32
+	Ac_pid                    uint32
+	Ac_ppid                   uint32
+	Ac_btime                  uint32
+	_                         [4]byte
+	Ac_etime                  uint64
+	Ac_utime                  uint64
+	Ac_stime                  uint64
+	Ac_minflt                 uint64
+	Ac_majflt                 uint64
+	Coremem                   uint64
+	Virtmem                   uint64
+	Hiwater_rss               uint64
+	Hiwater_vm                uint64
+	Read_char                 uint64
+	Write_char                uint64
+	Read_syscalls             uint64
+	Write_syscalls            uint64
+	Read_bytes                uint64
+	Write_bytes               uint64
+	Cancelled_write_bytes     uint64
+	Nvcsw                     uint64
+	Nivcsw                    uint64
+	Ac_utimescaled            uint64
+	Ac_stimescaled            uint64
+	Cpu_scaled_run_real_total uint64
+	Freepages_count           uint64
+	Freepages_delay_total     uint64
+	Thrashing_count           uint64
+	Thrashing_delay_total     uint64
+	Ac_btime64                uint64
+}
+
+type cpuMask uint32
+
+const (
+	_NCPUBITS = 0x20
+)
+
+const (
+	CBitFieldMaskBit0  = 0x8000000000000000
+	CBitFieldMaskBit1  = 0x4000000000000000
+	CBitFieldMaskBit2  = 0x2000000000000000
+	CBitFieldMaskBit3  = 0x1000000000000000
+	CBitFieldMaskBit4  = 0x800000000000000
+	CBitFieldMaskBit5  = 0x400000000000000
+	CBitFieldMaskBit6  = 0x200000000000000
+	CBitFieldMaskBit7  = 0x100000000000000
+	CBitFieldMaskBit8  = 0x80000000000000
+	CBitFieldMaskBit9  = 0x40000000000000
+	CBitFieldMaskBit10 = 0x20000000000000
+	CBitFieldMaskBit11 = 0x10000000000000
+	CBitFieldMaskBit12 = 0x8000000000000
+	CBitFieldMaskBit13 = 0x4000000000000
+	CBitFieldMaskBit14 = 0x2000000000000
+	CBitFieldMaskBit15 = 0x1000000000000
+	CBitFieldMaskBit16 = 0x800000000000
+	CBitFieldMaskBit17 = 0x400000000000
+	CBitFieldMaskBit18 = 0x200000000000
+	CBitFieldMaskBit19 = 0x100000000000
+	CBitFieldMaskBit20 = 0x80000000000
+	CBitFieldMaskBit21 = 0x40000000000
+	CBitFieldMaskBit22 = 0x20000000000
+	CBitFieldMaskBit23 = 0x10000000000
+	CBitFieldMaskBit24 = 0x8000000000
+	CBitFieldMaskBit25 = 0x4000000000
+	CBitFieldMaskBit26 = 0x2000000000
+	CBitFieldMaskBit27 = 0x1000000000
+	CBitFieldMaskBit28 = 0x800000000
+	CBitFieldMaskBit29 = 0x400000000
+	CBitFieldMaskBit30 = 0x200000000
+	CBitFieldMaskBit31 = 0x100000000
+	CBitFieldMaskBit32 = 0x80000000
+	CBitFieldMaskBit33 = 0x40000000
+	CBitFieldMaskBit34 = 0x20000000
+	CBitFieldMaskBit35 = 0x10000000
+	CBitFieldMaskBit36 = 0x8000000
+	CBitFieldMaskBit37 = 0x4000000
+	CBitFieldMaskBit38 = 0x2000000
+	CBitFieldMaskBit39 = 0x1000000
+	CBitFieldMaskBit40 = 0x800000
+	CBitFieldMaskBit41 = 0x400000
+	CBitFieldMaskBit42 = 0x200000
+	CBitFieldMaskBit43 = 0x100000
+	CBitFieldMaskBit44 = 0x80000
+	CBitFieldMaskBit45 = 0x40000
+	CBitFieldMaskBit46 = 0x20000
+	CBitFieldMaskBit47 = 0x10000
+	CBitFieldMaskBit48 = 0x8000
+	CBitFieldMaskBit49 = 0x4000
+	CBitFieldMaskBit50 = 0x2000
+	CBitFieldMaskBit51 = 0x1000
+	CBitFieldMaskBit52 = 0x800
+	CBitFieldMaskBit53 = 0x400
+	CBitFieldMaskBit54 = 0x200
+	CBitFieldMaskBit55 = 0x100
+	CBitFieldMaskBit56 = 0x80
+	CBitFieldMaskBit57 = 0x40
+	CBitFieldMaskBit58 = 0x20
+	CBitFieldMaskBit59 = 0x10
+	CBitFieldMaskBit60 = 0x8
+	CBitFieldMaskBit61 = 0x4
+	CBitFieldMaskBit62 = 0x2
+	CBitFieldMaskBit63 = 0x1
+)
+
+type SockaddrStorage struct {
+	Family uint16
+	_      [122]uint8
+	_      uint32
+}
+
+type HDGeometry struct {
+	Heads     uint8
+	Sectors   uint8
+	Cylinders uint16
+	Start     uint32
+}
+
+type Statfs_t struct {
+	Type    int32
+	Bsize   int32
+	Blocks  uint64
+	Bfree   uint64
+	Bavail  uint64
+	Files   uint64
+	Ffree   uint64
+	Fsid    Fsid
+	Namelen int32
+	Frsize  int32
+	Flags   int32
+	Spare   [4]int32
+	_       [4]byte
+}
+
+type TpacketHdr struct {
+	Status  uint32
+	Len     uint32
+	Snaplen uint32
+	Mac     uint16
+	Net     uint16
+	Sec     uint32
+	Usec    uint32
+}
+
+const (
+	SizeofTpacketHdr = 0x18
+)
+
+type RTCPLLInfo struct {
+	Ctrl    int32
+	Value   int32
+	Max     int32
+	Min     int32
+	Posmult int32
+	Negmult int32
+	Clock   int32
+}
+
+type BlkpgPartition struct {
+	Start   int64
+	Length  int64
+	Pno     int32
+	Devname [64]uint8
+	Volname [64]uint8
+	_       [4]byte
+}
+
+const (
+	BLKPG = 0x20001269
+)
+
+type XDPUmemReg struct {
+	Addr     uint64
+	Len      uint64
+	Size     uint32
+	Headroom uint32
+	Flags    uint32
+	_        [4]byte
+}
+
+type CryptoUserAlg struct {
+	Name        [64]uint8
+	Driver_name [64]uint8
+	Module_name [64]uint8
+	Type        uint32
+	Mask        uint32
+	Refcnt      uint32
+	Flags       uint32
+}
+
+type CryptoStatAEAD struct {
+	Type         [64]uint8
+	Encrypt_cnt  uint64
+	Encrypt_tlen uint64
+	Decrypt_cnt  uint64
+	Decrypt_tlen uint64
+	Err_cnt      uint64
+}
+
+type CryptoStatAKCipher struct {
+	Type         [64]uint8
+	Encrypt_cnt  uint64
+	Encrypt_tlen uint64
+	Decrypt_cnt  uint64
+	Decrypt_tlen uint64
+	Verify_cnt   uint64
+	Sign_cnt     uint64
+	Err_cnt      uint64
+}
+
+type CryptoStatCipher struct {
+	Type         [64]uint8
+	Encrypt_cnt  uint64
+	Encrypt_tlen uint64
+	Decrypt_cnt  uint64
+	Decrypt_tlen uint64
+	Err_cnt      uint64
+}
+
+type CryptoStatCompress struct {
+	Type            [64]uint8
+	Compress_cnt    uint64
+	Compress_tlen   uint64
+	Decompress_cnt  uint64
+	Decompress_tlen uint64
+	Err_cnt         uint64
+}
+
+type CryptoStatHash struct {
+	Type      [64]uint8
+	Hash_cnt  uint64
+	Hash_tlen uint64
+	Err_cnt   uint64
+}
+
+type CryptoStatKPP struct {
+	Type                      [64]uint8
+	Setsecret_cnt             uint64
+	Generate_public_key_cnt   uint64
+	Compute_shared_secret_cnt uint64
+	Err_cnt                   uint64
+}
+
+type CryptoStatRNG struct {
+	Type          [64]uint8
+	Generate_cnt  uint64
+	Generate_tlen uint64
+	Seed_cnt      uint64
+	Err_cnt       uint64
+}
+
+type CryptoStatLarval struct {
+	Type [64]uint8
+}
+
+type CryptoReportLarval struct {
+	Type [64]uint8
+}
+
+type CryptoReportHash struct {
+	Type       [64]uint8
+	Blocksize  uint32
+	Digestsize uint32
+}
+
+type CryptoReportCipher struct {
+	Type        [64]uint8
+	Blocksize   uint32
+	Min_keysize uint32
+	Max_keysize uint32
+}
+
+type CryptoReportBlkCipher struct {
+	Type        [64]uint8
+	Geniv       [64]uint8
+	Blocksize   uint32
+	Min_keysize uint32
+	Max_keysize uint32
+	Ivsize      uint32
+}
+
+type CryptoReportAEAD struct {
+	Type        [64]uint8
+	Geniv       [64]uint8
+	Blocksize   uint32
+	Maxauthsize uint32
+	Ivsize      uint32
+}
+
+type CryptoReportComp struct {
+	Type [64]uint8
+}
+
+type CryptoReportRNG struct {
+	Type     [64]uint8
+	Seedsize uint32
+}
+
+type CryptoReportAKCipher struct {
+	Type [64]uint8
+}
+
+type CryptoReportKPP struct {
+	Type [64]uint8
+}
+
+type CryptoReportAcomp struct {
+	Type [64]uint8
+}
+
+type LoopInfo struct {
+	Number           int32
+	Device           uint32
+	Inode            uint32
+	Rdevice          uint32
+	Offset           int32
+	Encrypt_type     int32
+	Encrypt_key_size int32
+	Flags            int32
+	Name             [64]uint8
+	Encrypt_key      [32]uint8
+	Init             [2]uint32
+	Reserved         [4]uint8
+}
+
+type TIPCSubscr struct {
+	Seq     TIPCServiceRange
+	Timeout uint32
+	Filter  uint32
+	Handle  [8]uint8
+}
+
+type TIPCSIOCLNReq struct {
+	Peer     uint32
+	Id       uint32
+	Linkname [68]uint8
+}
+
+type TIPCSIOCNodeIDReq struct {
+	Peer uint32
+	Id   [16]uint8
+}
+
+type PPSKInfo struct {
+	Assert_sequence uint32
+	Clear_sequence  uint32
+	Assert_tu       PPSKTime
+	Clear_tu        PPSKTime
+	Current_mode    int32
+	_               [4]byte
+}
+
+const (
+	PPS_GETPARAMS = 0x400470a1
+	PPS_SETPARAMS = 0x800470a2
+	PPS_GETCAP    = 0x400470a3
+	PPS_FETCH     = 0xc00470a4
+)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
index 257e004..2a3afba 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build ppc64 && linux
 // +build ppc64,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
index 980dd31..c0de30a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build ppc64le && linux
 // +build ppc64le,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
index d9fdab2..74faf2e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build riscv64 && linux
 // +build riscv64,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
index c25de8c..9a8f0c2 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build s390x && linux
 // +build s390x,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go
index 97fca65..72cdda7 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go
@@ -1,6 +1,7 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build sparc64 && linux
 // +build sparc64,linux
 
 package unix
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go
index a89100c..b10e73a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_netbsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build 386 && netbsd
 // +build 386,netbsd
 
 package unix
@@ -248,6 +249,7 @@
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x14
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x8
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x1c
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go
index 289184e..28ed6d5 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_netbsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && netbsd
 // +build amd64,netbsd
 
 package unix
@@ -255,6 +256,7 @@
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x14
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x30
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go
index 428c450..4ba196e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_netbsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm && netbsd
 // +build arm,netbsd
 
 package unix
@@ -253,6 +254,7 @@
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x14
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x8
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x1c
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go
index 6f1f284..dd642bd 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_netbsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && netbsd
 // +build arm64,netbsd
 
 package unix
@@ -255,6 +256,7 @@
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x14
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x30
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go
index 61ea001..1fdb0e5 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_openbsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build 386 && openbsd
 // +build 386,openbsd
 
 package unix
@@ -231,6 +232,7 @@
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x20
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x8
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x1c
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go
index 87a493f..e2fc93c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_openbsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && openbsd
 // +build amd64,openbsd
 
 package unix
@@ -235,6 +236,7 @@
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x20
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x30
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go
index d80836e..8d34b5a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go
@@ -1,6 +1,7 @@
 // cgo -godefs -- -fsigned-char types_openbsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm && openbsd
 // +build arm,openbsd
 
 package unix
@@ -235,6 +236,7 @@
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x20
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x8
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x1c
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go
index 4e15874..ea8f1a0 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go
@@ -1,6 +1,7 @@
 // cgo -godefs -- -fsigned-char types_openbsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build arm64 && openbsd
 // +build arm64,openbsd
 
 package unix
@@ -231,6 +232,7 @@
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x20
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x30
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go
index 992a1f8..ec6e8bc 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go
@@ -1,6 +1,7 @@
 // cgo -godefs -- -fsigned-char types_openbsd.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build mips64 && openbsd
 // +build mips64,openbsd
 
 package unix
@@ -231,6 +232,7 @@
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x20
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x30
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go
index db817f3..85effef 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go
@@ -1,6 +1,7 @@
 // cgo -godefs types_solaris.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
+//go:build amd64 && solaris
 // +build amd64,solaris
 
 package unix
@@ -234,6 +235,7 @@
 	SizeofSockaddrUnix     = 0x6e
 	SizeofSockaddrDatalink = 0xfc
 	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
 	SizeofIPv6Mreq         = 0x14
 	SizeofMsghdr           = 0x30
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go
new file mode 100644
index 0000000..4ab638c
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go
@@ -0,0 +1,406 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+// Hand edited based on ztypes_linux_s390x.go
+// TODO: auto-generate.
+
+package unix
+
+const (
+	SizeofPtr      = 0x8
+	SizeofShort    = 0x2
+	SizeofInt      = 0x4
+	SizeofLong     = 0x8
+	SizeofLongLong = 0x8
+	PathMax        = 0x1000
+)
+
+const (
+	SizeofSockaddrAny   = 128
+	SizeofCmsghdr       = 12
+	SizeofIPMreq        = 8
+	SizeofIPv6Mreq      = 20
+	SizeofICMPv6Filter  = 32
+	SizeofIPv6MTUInfo   = 32
+	SizeofLinger        = 8
+	SizeofSockaddrInet4 = 16
+	SizeofSockaddrInet6 = 28
+	SizeofTCPInfo       = 0x68
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int64
+	_C_long_long int64
+)
+
+type Timespec struct {
+	Sec  int64
+	Nsec int64
+}
+
+type Timeval struct {
+	Sec  int64
+	Usec int64
+}
+
+type timeval_zos struct { //correct (with padding and all)
+	Sec  int64
+	_    [4]byte // pad
+	Usec int32
+}
+
+type Tms struct { //clock_t is 4-byte unsigned int in zos
+	Utime  uint32
+	Stime  uint32
+	Cutime uint32
+	Cstime uint32
+}
+
+type Time_t int64
+
+type Utimbuf struct {
+	Actime  int64
+	Modtime int64
+}
+
+type Utsname struct {
+	Sysname    [65]byte
+	Nodename   [65]byte
+	Release    [65]byte
+	Version    [65]byte
+	Machine    [65]byte
+	Domainname [65]byte
+}
+
+type RawSockaddrInet4 struct {
+	Len    uint8
+	Family uint8
+	Port   uint16
+	Addr   [4]byte /* in_addr */
+	Zero   [8]uint8
+}
+
+type RawSockaddrInet6 struct {
+	Len      uint8
+	Family   uint8
+	Port     uint16
+	Flowinfo uint32
+	Addr     [16]byte /* in6_addr */
+	Scope_id uint32
+}
+
+type RawSockaddrUnix struct {
+	Len    uint8
+	Family uint8
+	Path   [108]int8
+}
+
+type RawSockaddr struct {
+	Len    uint8
+	Family uint8
+	Data   [14]uint8
+}
+
+type RawSockaddrAny struct {
+	Addr RawSockaddr
+	_    [112]uint8 // pad
+}
+
+type _Socklen uint32
+
+type Linger struct {
+	Onoff  int32
+	Linger int32
+}
+
+type Iovec struct {
+	Base *byte
+	Len  uint64
+}
+
+type IPMreq struct {
+	Multiaddr [4]byte /* in_addr */
+	Interface [4]byte /* in_addr */
+}
+
+type IPv6Mreq struct {
+	Multiaddr [16]byte /* in6_addr */
+	Interface uint32
+}
+
+type Msghdr struct {
+	Name       *byte
+	Iov        *Iovec
+	Control    *byte
+	Flags      int32
+	Namelen    int32
+	Iovlen     int32
+	Controllen int32
+}
+
+type Cmsghdr struct {
+	Len   int32
+	Level int32
+	Type  int32
+}
+
+type Inet4Pktinfo struct {
+	Addr    [4]byte /* in_addr */
+	Ifindex uint32
+}
+
+type Inet6Pktinfo struct {
+	Addr    [16]byte /* in6_addr */
+	Ifindex uint32
+}
+
+type IPv6MTUInfo struct {
+	Addr RawSockaddrInet6
+	Mtu  uint32
+}
+
+type ICMPv6Filter struct {
+	Data [8]uint32
+}
+
+type TCPInfo struct {
+	State          uint8
+	Ca_state       uint8
+	Retransmits    uint8
+	Probes         uint8
+	Backoff        uint8
+	Options        uint8
+	Rto            uint32
+	Ato            uint32
+	Snd_mss        uint32
+	Rcv_mss        uint32
+	Unacked        uint32
+	Sacked         uint32
+	Lost           uint32
+	Retrans        uint32
+	Fackets        uint32
+	Last_data_sent uint32
+	Last_ack_sent  uint32
+	Last_data_recv uint32
+	Last_ack_recv  uint32
+	Pmtu           uint32
+	Rcv_ssthresh   uint32
+	Rtt            uint32
+	Rttvar         uint32
+	Snd_ssthresh   uint32
+	Snd_cwnd       uint32
+	Advmss         uint32
+	Reordering     uint32
+	Rcv_rtt        uint32
+	Rcv_space      uint32
+	Total_retrans  uint32
+}
+
+type _Gid_t uint32
+
+type rusage_zos struct {
+	Utime timeval_zos
+	Stime timeval_zos
+}
+
+type Rusage struct {
+	Utime    Timeval
+	Stime    Timeval
+	Maxrss   int64
+	Ixrss    int64
+	Idrss    int64
+	Isrss    int64
+	Minflt   int64
+	Majflt   int64
+	Nswap    int64
+	Inblock  int64
+	Oublock  int64
+	Msgsnd   int64
+	Msgrcv   int64
+	Nsignals int64
+	Nvcsw    int64
+	Nivcsw   int64
+}
+
+type Rlimit struct {
+	Cur uint64
+	Max uint64
+}
+
+// { int, short, short } in poll.h
+type PollFd struct {
+	Fd      int32
+	Events  int16
+	Revents int16
+}
+
+type Stat_t struct { //Linux Definition
+	Dev     uint64
+	Ino     uint64
+	Nlink   uint64
+	Mode    uint32
+	Uid     uint32
+	Gid     uint32
+	_       int32
+	Rdev    uint64
+	Size    int64
+	Atim    Timespec
+	Mtim    Timespec
+	Ctim    Timespec
+	Blksize int64
+	Blocks  int64
+	_       [3]int64
+}
+
+type Stat_LE_t struct {
+	_            [4]byte // eye catcher
+	Length       uint16
+	Version      uint16
+	Mode         int32
+	Ino          uint32
+	Dev          uint32
+	Nlink        int32
+	Uid          int32
+	Gid          int32
+	Size         int64
+	Atim31       [4]byte
+	Mtim31       [4]byte
+	Ctim31       [4]byte
+	Rdev         uint32
+	Auditoraudit uint32
+	Useraudit    uint32
+	Blksize      int32
+	Creatim31    [4]byte
+	AuditID      [16]byte
+	_            [4]byte // rsrvd1
+	File_tag     struct {
+		Ccsid   uint16
+		Txtflag uint16 // aggregating Txflag:1 deferred:1 rsvflags:14
+	}
+	CharsetID [8]byte
+	Blocks    int64
+	Genvalue  uint32
+	Reftim31  [4]byte
+	Fid       [8]byte
+	Filefmt   byte
+	Fspflag2  byte
+	_         [2]byte // rsrvd2
+	Ctimemsec int32
+	Seclabel  [8]byte
+	_         [4]byte // rsrvd3
+	_         [4]byte // rsrvd4
+	Atim      Time_t
+	Mtim      Time_t
+	Ctim      Time_t
+	Creatim   Time_t
+	Reftim    Time_t
+	_         [24]byte // rsrvd5
+}
+
+type Statvfs_t struct {
+	ID          [4]byte
+	Len         int32
+	Bsize       uint64
+	Blocks      uint64
+	Usedspace   uint64
+	Bavail      uint64
+	Flag        uint64
+	Maxfilesize int64
+	_           [16]byte
+	Frsize      uint64
+	Bfree       uint64
+	Files       uint32
+	Ffree       uint32
+	Favail      uint32
+	Namemax31   uint32
+	Invarsec    uint32
+	_           [4]byte
+	Fsid        uint64
+	Namemax     uint64
+}
+
+type Statfs_t struct {
+	Type    uint32
+	Bsize   uint64
+	Blocks  uint64
+	Bfree   uint64
+	Bavail  uint64
+	Files   uint32
+	Ffree   uint32
+	Fsid    uint64
+	Namelen uint64
+	Frsize  uint64
+	Flags   uint64
+}
+
+type Dirent struct {
+	Reclen uint16
+	Namlen uint16
+	Ino    uint32
+	Extra  uintptr
+	Name   [256]byte
+}
+
+type FdSet struct {
+	Bits [64]int32
+}
+
+// This struct is packed on z/OS so it can't be used directly.
+type Flock_t struct {
+	Type   int16
+	Whence int16
+	Start  int64
+	Len    int64
+	Pid    int32
+}
+
+type Termios struct {
+	Cflag uint32
+	Iflag uint32
+	Lflag uint32
+	Oflag uint32
+	Cc    [11]uint8
+}
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
+type W_Mnth struct {
+	Hid   [4]byte
+	Size  int32
+	Cur1  int32 //32bit pointer
+	Cur2  int32 //^
+	Devno uint32
+	_     [4]byte
+}
+
+type W_Mntent struct {
+	Fstype       uint32
+	Mode         uint32
+	Dev          uint32
+	Parentdev    uint32
+	Rootino      uint32
+	Status       byte
+	Ddname       [9]byte
+	Fstname      [9]byte
+	Fsname       [45]byte
+	Pathlen      uint32
+	Mountpoint   [1024]byte
+	Jobname      [8]byte
+	PID          int32
+	Parmoffset   int32
+	Parmlen      int16
+	Owner        [8]byte
+	Quiesceowner [8]byte
+	_            [38]byte
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/empty.s b/src/cmd/vendor/golang.org/x/sys/windows/empty.s
index 69309e4..fdbbbcd 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/empty.s
+++ b/src/cmd/vendor/golang.org/x/sys/windows/empty.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !go1.12
 // +build !go1.12
 
 // This file is here to allow bodyless functions with go:linkname for Go 1.11
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/exec_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/exec_windows.go
index 3606c3a..9eb1fb6 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/exec_windows.go
+++ b/src/cmd/vendor/golang.org/x/sys/windows/exec_windows.go
@@ -6,6 +6,11 @@
 
 package windows
 
+import (
+	errorspkg "errors"
+	"unsafe"
+)
+
 // EscapeArg rewrites command line argument s as prescribed
 // in http://msdn.microsoft.com/en-us/library/ms880421.
 // This function returns "" (2 double quotes) if s is empty.
@@ -95,3 +100,33 @@
 		}
 	}
 }
+
+// NewProcThreadAttributeList allocates a new ProcThreadAttributeList, with the requested maximum number of attributes.
+func NewProcThreadAttributeList(maxAttrCount uint32) (*ProcThreadAttributeList, error) {
+	var size uintptr
+	err := initializeProcThreadAttributeList(nil, maxAttrCount, 0, &size)
+	if err != ERROR_INSUFFICIENT_BUFFER {
+		if err == nil {
+			return nil, errorspkg.New("unable to query buffer size from InitializeProcThreadAttributeList")
+		}
+		return nil, err
+	}
+	const psize = unsafe.Sizeof(uintptr(0))
+	// size is guaranteed to be ≥1 by InitializeProcThreadAttributeList.
+	al := (*ProcThreadAttributeList)(unsafe.Pointer(&make([]unsafe.Pointer, (size+psize-1)/psize)[0]))
+	err = initializeProcThreadAttributeList(al, maxAttrCount, 0, &size)
+	if err != nil {
+		return nil, err
+	}
+	return al, err
+}
+
+// Update modifies the ProcThreadAttributeList using UpdateProcThreadAttribute.
+func (al *ProcThreadAttributeList) Update(attribute uintptr, flags uint32, value unsafe.Pointer, size uintptr, prevValue unsafe.Pointer, returnedSize *uintptr) error {
+	return updateProcThreadAttribute(al, flags, attribute, value, size, prevValue, returnedSize)
+}
+
+// Delete frees ProcThreadAttributeList's resources.
+func (al *ProcThreadAttributeList) Delete() {
+	deleteProcThreadAttributeList(al)
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/mkerrors.bash b/src/cmd/vendor/golang.org/x/sys/windows/mkerrors.bash
index 2163843..58e0188 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/mkerrors.bash
+++ b/src/cmd/vendor/golang.org/x/sys/windows/mkerrors.bash
@@ -9,6 +9,8 @@
 
 winerror="$(printf '%s\n' "/mnt/c/Program Files (x86)/Windows Kits/"/*/Include/*/shared/winerror.h | sort -Vr | head -n 1)"
 [[ -n $winerror ]] || { echo "Unable to find winerror.h" >&2; exit 1; }
+ntstatus="$(printf '%s\n' "/mnt/c/Program Files (x86)/Windows Kits/"/*/Include/*/shared/ntstatus.h | sort -Vr | head -n 1)"
+[[ -n $ntstatus ]] || { echo "Unable to find ntstatus.h" >&2; exit 1; }
 
 declare -A errors
 
@@ -59,5 +61,10 @@
 		echo "$key $vtype = $value"
 	done < "$winerror"
 
+	while read -r line; do
+		[[ $line =~ ^#define\ (STATUS_[^\s]+)\ +\(\(NTSTATUS\)((0x)?[0-9a-fA-F]+)L?\) ]] || continue
+		echo "${BASH_REMATCH[1]} NTStatus = ${BASH_REMATCH[2]}"
+	done < "$ntstatus"
+
 	echo ")"
 } | gofmt > "zerrors_windows.go"
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/security_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/security_windows.go
index 69eb462..111c10d 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/security_windows.go
+++ b/src/cmd/vendor/golang.org/x/sys/windows/security_windows.go
@@ -908,6 +908,19 @@
 	dacl     *ACL
 }
 
+type SECURITY_QUALITY_OF_SERVICE struct {
+	Length              uint32
+	ImpersonationLevel  uint32
+	ContextTrackingMode byte
+	EffectiveOnly       byte
+}
+
+// Constants for the ContextTrackingMode field of SECURITY_QUALITY_OF_SERVICE.
+const (
+	SECURITY_STATIC_TRACKING  = 0
+	SECURITY_DYNAMIC_TRACKING = 1
+)
+
 type SecurityAttributes struct {
 	Length             uint32
 	SecurityDescriptor *SECURITY_DESCRIPTOR
@@ -1321,7 +1334,11 @@
 }
 
 func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() *SECURITY_DESCRIPTOR {
-	sdLen := (int)(selfRelativeSD.Length())
+	sdLen := int(selfRelativeSD.Length())
+	const min = int(unsafe.Sizeof(SECURITY_DESCRIPTOR{}))
+	if sdLen < min {
+		sdLen = min
+	}
 
 	var src []byte
 	h := (*unsafeheader.Slice)(unsafe.Pointer(&src))
@@ -1329,7 +1346,15 @@
 	h.Len = sdLen
 	h.Cap = sdLen
 
-	dst := make([]byte, sdLen)
+	const psize = int(unsafe.Sizeof(uintptr(0)))
+
+	var dst []byte
+	h = (*unsafeheader.Slice)(unsafe.Pointer(&dst))
+	alloc := make([]uintptr, (sdLen+psize-1)/psize)
+	h.Data = (*unsafeheader.Slice)(unsafe.Pointer(&alloc)).Data
+	h.Len = sdLen
+	h.Cap = sdLen
+
 	copy(dst, src)
 	return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0]))
 }
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go
index c71bad1..bb6aaf8 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go
+++ b/src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go
@@ -8,6 +8,8 @@
 
 import (
 	errorspkg "errors"
+	"fmt"
+	"runtime"
 	"sync"
 	"syscall"
 	"time"
@@ -18,9 +20,11 @@
 )
 
 type Handle uintptr
+type HWND uintptr
 
 const (
 	InvalidHandle = ^Handle(0)
+	InvalidHWND   = ^HWND(0)
 
 	// Flags for DefineDosDevice.
 	DDD_EXACT_MATCH_ON_REMOVE = 0x00000004
@@ -63,9 +67,8 @@
 	LOCKFILE_FAIL_IMMEDIATELY = 0x00000001
 	LOCKFILE_EXCLUSIVE_LOCK   = 0x00000002
 
-	// Return values of SleepEx and other APC functions
-	STATUS_USER_APC    = 0x000000C0
-	WAIT_IO_COMPLETION = STATUS_USER_APC
+	// Return value of SleepEx and other APC functions
+	WAIT_IO_COMPLETION = 0x000000C0
 )
 
 // StringToUTF16 is deprecated. Use UTF16FromString instead.
@@ -178,6 +181,11 @@
 //sys	IsWow64Process(handle Handle, isWow64 *bool) (err error) = IsWow64Process
 //sys	IsWow64Process2(handle Handle, processMachine *uint16, nativeMachine *uint16) (err error) = IsWow64Process2?
 //sys	CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
+//sys	CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error)  [failretval==InvalidHandle] = CreateNamedPipeW
+//sys	ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error)
+//sys	GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error)
+//sys	GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
+//sys	SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) = SetNamedPipeHandleState
 //sys	ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
 //sys	WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
 //sys	GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error)
@@ -206,14 +214,21 @@
 //sys	GetSystemTimeAsFileTime(time *Filetime)
 //sys	GetSystemTimePreciseAsFileTime(time *Filetime)
 //sys	GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
-//sys	CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error)
-//sys	GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error)
-//sys	PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error)
+//sys	CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uintptr, threadcnt uint32) (handle Handle, err error)
+//sys	GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uintptr, overlapped **Overlapped, timeout uint32) (err error)
+//sys	PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uintptr, overlapped *Overlapped) (err error)
 //sys	CancelIo(s Handle) (err error)
 //sys	CancelIoEx(s Handle, o *Overlapped) (err error)
 //sys	CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW
+//sys   initializeProcThreadAttributeList(attrlist *ProcThreadAttributeList, attrcount uint32, flags uint32, size *uintptr) (err error) = InitializeProcThreadAttributeList
+//sys   deleteProcThreadAttributeList(attrlist *ProcThreadAttributeList) = DeleteProcThreadAttributeList
+//sys   updateProcThreadAttribute(attrlist *ProcThreadAttributeList, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) = UpdateProcThreadAttribute
 //sys	OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error)
 //sys	ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) [failretval<=32] = shell32.ShellExecuteW
+//sys	GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) = user32.GetWindowThreadProcessId
+//sys	GetShellWindow() (shellWindow HWND) = user32.GetShellWindow
+//sys	MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) [failretval==0] = user32.MessageBoxW
+//sys	ExitWindowsEx(flags uint32, reason uint32) (err error) = user32.ExitWindowsEx
 //sys	shGetKnownFolderPath(id *KNOWNFOLDERID, flags uint32, token Token, path **uint16) (ret error) = shell32.SHGetKnownFolderPath
 //sys	TerminateProcess(handle Handle, exitcode uint32) (err error)
 //sys	GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
@@ -242,13 +257,14 @@
 //sys	GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW
 //sys	CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW
 //sys	LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0]
+//sys	LocalAlloc(flags uint32, length uint32) (ptr uintptr, err error)
 //sys	SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error)
 //sys	FlushFileBuffers(handle Handle) (err error)
 //sys	GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW
 //sys	GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW
 //sys	GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW
 //sys	GetFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) = kernel32.GetFinalPathNameByHandleW
-//sys	CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW
+//sys	CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) [failretval == 0 || e1 == ERROR_ALREADY_EXISTS] = kernel32.CreateFileMappingW
 //sys	MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error)
 //sys	UnmapViewOfFile(addr uintptr) (err error)
 //sys	FlushViewOfFile(addr uintptr, length uintptr) (err error)
@@ -259,22 +275,38 @@
 //sys	VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) = kernel32.VirtualProtect
 //sys	TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile
 //sys	ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW
+//sys	FindFirstChangeNotification(path string, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.FindFirstChangeNotificationW
+//sys	FindNextChangeNotification(handle Handle) (err error)
+//sys	FindCloseChangeNotification(handle Handle) (err error)
 //sys	CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW
-//sys   CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) = crypt32.CertOpenStore
+//sys	CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) = crypt32.CertOpenStore
 //sys	CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore
-//sys   CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore
+//sys	CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore
 //sys	CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore
 //sys	CertDeleteCertificateFromStore(certContext *CertContext) (err error) = crypt32.CertDeleteCertificateFromStore
-//sys   CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain
-//sys   CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain
-//sys   CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext
-//sys   CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext
-//sys   CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy
+//sys	CertDuplicateCertificateContext(certContext *CertContext) (dupContext *CertContext) = crypt32.CertDuplicateCertificateContext
+//sys	PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (store Handle, err error) = crypt32.PFXImportCertStore
+//sys	CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain
+//sys	CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain
+//sys	CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext
+//sys	CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext
+//sys	CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy
+//sys	CertGetNameString(certContext *CertContext, nameType uint32, flags uint32, typePara unsafe.Pointer, name *uint16, size uint32) (chars uint32) = crypt32.CertGetNameStringW
+//sys	CertFindExtension(objId *byte, countExtensions uint32, extensions *CertExtension) (ret *CertExtension) = crypt32.CertFindExtension
+//sys   CertFindCertificateInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevCertContext *CertContext) (cert *CertContext, err error) [failretval==nil] = crypt32.CertFindCertificateInStore
+//sys   CertFindChainInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevChainContext *CertChainContext) (certchain *CertChainContext, err error) [failretval==nil] = crypt32.CertFindChainInStore
+//sys   CryptAcquireCertificatePrivateKey(cert *CertContext, flags uint32, parameters unsafe.Pointer, cryptProvOrNCryptKey *Handle, keySpec *uint32, callerFreeProvOrNCryptKey *bool) (err error) = crypt32.CryptAcquireCertificatePrivateKey
+//sys	CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentTypeFlags uint32, expectedFormatTypeFlags uint32, flags uint32, msgAndCertEncodingType *uint32, contentType *uint32, formatType *uint32, certStore *Handle, msg *Handle, context *unsafe.Pointer) (err error) = crypt32.CryptQueryObject
+//sys	CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte, lenEncodedBytes uint32, flags uint32, decoded unsafe.Pointer, decodedLen *uint32) (err error) = crypt32.CryptDecodeObject
+//sys	CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) = crypt32.CryptProtectData
+//sys	CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) = crypt32.CryptUnprotectData
+//sys	WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) = wintrust.WinVerifyTrustEx
 //sys	RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW
 //sys	RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey
 //sys	RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW
 //sys	RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW
 //sys	RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW
+//sys	RegNotifyChangeKeyValue(key Handle, watchSubtree bool, notifyFilter uint32, event Handle, asynchronous bool) (regerrno error) = advapi32.RegNotifyChangeKeyValue
 //sys	GetCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId
 //sys	ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) = kernel32.ProcessIdToSessionId
 //sys	GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode
@@ -293,14 +325,14 @@
 //sys	CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW
 //sys	CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW
 //sys	GetCurrentThreadId() (id uint32)
-//sys	CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) = kernel32.CreateEventW
-//sys	CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) = kernel32.CreateEventExW
+//sys	CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) [failretval == 0 || e1 == ERROR_ALREADY_EXISTS] = kernel32.CreateEventW
+//sys	CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) [failretval == 0 || e1 == ERROR_ALREADY_EXISTS] = kernel32.CreateEventExW
 //sys	OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) = kernel32.OpenEventW
 //sys	SetEvent(event Handle) (err error) = kernel32.SetEvent
 //sys	ResetEvent(event Handle) (err error) = kernel32.ResetEvent
 //sys	PulseEvent(event Handle) (err error) = kernel32.PulseEvent
-//sys	CreateMutex(mutexAttrs *SecurityAttributes, initialOwner bool, name *uint16) (handle Handle, err error) = kernel32.CreateMutexW
-//sys	CreateMutexEx(mutexAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) = kernel32.CreateMutexExW
+//sys	CreateMutex(mutexAttrs *SecurityAttributes, initialOwner bool, name *uint16) (handle Handle, err error) [failretval == 0 || e1 == ERROR_ALREADY_EXISTS] = kernel32.CreateMutexW
+//sys	CreateMutexEx(mutexAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) [failretval == 0 || e1 == ERROR_ALREADY_EXISTS] = kernel32.CreateMutexExW
 //sys	OpenMutex(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) = kernel32.OpenMutexW
 //sys	ReleaseMutex(mutex Handle) (err error) = kernel32.ReleaseMutex
 //sys	SleepEx(milliseconds uint32, alertable bool) (ret uint32) = kernel32.SleepEx
@@ -315,10 +347,13 @@
 //sys	SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error)
 //sys	GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err error)
 //sys	GetProcessId(process Handle) (id uint32, err error)
+//sys	QueryFullProcessImageName(proc Handle, flags uint32, exeName *uint16, size *uint32) (err error) = kernel32.QueryFullProcessImageNameW
 //sys	OpenThread(desiredAccess uint32, inheritHandle bool, threadId uint32) (handle Handle, err error)
 //sys	SetProcessPriorityBoost(process Handle, disable bool) (err error) = kernel32.SetProcessPriorityBoost
 //sys	GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32)
 //sys	SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error)
+//sys	GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error)
+//sys	SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error)
 
 // Volume Management Functions
 //sys	DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW
@@ -341,8 +376,6 @@
 //sys	QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) [failretval==0] = QueryDosDeviceW
 //sys	SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) = SetVolumeLabelW
 //sys	SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) = SetVolumeMountPointW
-//sys	MessageBox(hwnd Handle, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) [failretval==0] = user32.MessageBoxW
-//sys	ExitWindowsEx(flags uint32, reason uint32) (err error) = user32.ExitWindowsEx
 //sys	InitiateSystemShutdownEx(machineName *uint16, message *uint16, timeout uint32, forceAppsClosed bool, rebootAfterShutdown bool, reason uint32) (err error) = advapi32.InitiateSystemShutdownExW
 //sys	SetProcessShutdownParameters(level uint32, flags uint32) (err error) = kernel32.SetProcessShutdownParameters
 //sys	GetProcessShutdownParameters(level *uint32, flags *uint32) (err error) = kernel32.GetProcessShutdownParameters
@@ -350,16 +383,36 @@
 //sys	stringFromGUID2(rguid *GUID, lpsz *uint16, cchMax int32) (chars int32) = ole32.StringFromGUID2
 //sys	coCreateGuid(pguid *GUID) (ret error) = ole32.CoCreateGuid
 //sys	CoTaskMemFree(address unsafe.Pointer) = ole32.CoTaskMemFree
-//sys	rtlGetVersion(info *OsVersionInfoEx) (ret error) = ntdll.RtlGetVersion
-//sys	rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) = ntdll.RtlGetNtVersionNumbers
+//sys	CoInitializeEx(reserved uintptr, coInit uint32) (ret error) = ole32.CoInitializeEx
+//sys	CoUninitialize() = ole32.CoUninitialize
+//sys	CoGetObject(name *uint16, bindOpts *BIND_OPTS3, guid *GUID, functionTable **uintptr) (ret error) = ole32.CoGetObject
 //sys	getProcessPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetProcessPreferredUILanguages
 //sys	getThreadPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetThreadPreferredUILanguages
 //sys	getUserPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetUserPreferredUILanguages
 //sys	getSystemPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetSystemPreferredUILanguages
+//sys	findResource(module Handle, name uintptr, resType uintptr) (resInfo Handle, err error) = kernel32.FindResourceW
+//sys	SizeofResource(module Handle, resInfo Handle) (size uint32, err error) = kernel32.SizeofResource
+//sys	LoadResource(module Handle, resInfo Handle) (resData Handle, err error) = kernel32.LoadResource
+//sys	LockResource(resData Handle) (addr uintptr, err error) = kernel32.LockResource
 
 // Process Status API (PSAPI)
 //sys	EnumProcesses(processIds []uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses
 
+// NT Native APIs
+//sys	rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) = ntdll.RtlNtStatusToDosErrorNoTeb
+//sys	rtlGetVersion(info *OsVersionInfoEx) (ntstatus error) = ntdll.RtlGetVersion
+//sys	rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) = ntdll.RtlGetNtVersionNumbers
+//sys	RtlGetCurrentPeb() (peb *PEB) = ntdll.RtlGetCurrentPeb
+//sys	RtlInitUnicodeString(destinationString *NTUnicodeString, sourceString *uint16) = ntdll.RtlInitUnicodeString
+//sys	RtlInitString(destinationString *NTString, sourceString *byte) = ntdll.RtlInitString
+//sys	NtCreateFile(handle *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, allocationSize *int64, attributes uint32, share uint32, disposition uint32, options uint32, eabuffer uintptr, ealength uint32) (ntstatus error) = ntdll.NtCreateFile
+//sys	NtCreateNamedPipeFile(pipe *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (ntstatus error) = ntdll.NtCreateNamedPipeFile
+//sys	RtlDosPathNameToNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) = ntdll.RtlDosPathNameToNtPathName_U_WithStatus
+//sys	RtlDosPathNameToRelativeNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) = ntdll.RtlDosPathNameToRelativeNtPathName_U_WithStatus
+//sys	RtlDefaultNpAcl(acl **ACL) (ntstatus error) = ntdll.RtlDefaultNpAcl
+//sys	NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32, retLen *uint32) (ntstatus error) = ntdll.NtQueryInformationProcess
+//sys	NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32) (ntstatus error) = ntdll.NtSetInformationProcess
+
 // syscall interface implementation for other packages
 
 // GetCurrentProcess returns the handle for the current process.
@@ -753,6 +806,7 @@
 //sys	WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend
 //sys	WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32,  from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom
 //sys	WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32,  overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo
+//sys	WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.WSASocketW
 //sys	GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname
 //sys	GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname
 //sys	Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
@@ -766,6 +820,7 @@
 //sys	GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo
 //sys	SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes
 //sys	WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW
+//sys	WSAGetOverlappedResult(h Handle, o *Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult
 //sys	GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses
 //sys	GetACP() (acp uint32) = kernel32.GetACP
 //sys	MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
@@ -1488,3 +1543,129 @@
 func SetConsoleCursorPosition(console Handle, position Coord) error {
 	return setConsoleCursorPosition(console, *((*uint32)(unsafe.Pointer(&position))))
 }
+
+func (s NTStatus) Errno() syscall.Errno {
+	return rtlNtStatusToDosErrorNoTeb(s)
+}
+
+func langID(pri, sub uint16) uint32 { return uint32(sub)<<10 | uint32(pri) }
+
+func (s NTStatus) Error() string {
+	b := make([]uint16, 300)
+	n, err := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_FROM_HMODULE|FORMAT_MESSAGE_ARGUMENT_ARRAY, modntdll.Handle(), uint32(s), langID(LANG_ENGLISH, SUBLANG_ENGLISH_US), b, nil)
+	if err != nil {
+		return fmt.Sprintf("NTSTATUS 0x%08x", uint32(s))
+	}
+	// trim terminating \r and \n
+	for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- {
+	}
+	return string(utf16.Decode(b[:n]))
+}
+
+// NewNTUnicodeString returns a new NTUnicodeString structure for use with native
+// NT APIs that work over the NTUnicodeString type. Note that most Windows APIs
+// do not use NTUnicodeString, and instead UTF16PtrFromString should be used for
+// the more common *uint16 string type.
+func NewNTUnicodeString(s string) (*NTUnicodeString, error) {
+	var u NTUnicodeString
+	s16, err := UTF16PtrFromString(s)
+	if err != nil {
+		return nil, err
+	}
+	RtlInitUnicodeString(&u, s16)
+	return &u, nil
+}
+
+// Slice returns a uint16 slice that aliases the data in the NTUnicodeString.
+func (s *NTUnicodeString) Slice() []uint16 {
+	var slice []uint16
+	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&slice))
+	hdr.Data = unsafe.Pointer(s.Buffer)
+	hdr.Len = int(s.Length)
+	hdr.Cap = int(s.MaximumLength)
+	return slice
+}
+
+func (s *NTUnicodeString) String() string {
+	return UTF16ToString(s.Slice())
+}
+
+// NewNTString returns a new NTString structure for use with native
+// NT APIs that work over the NTString type. Note that most Windows APIs
+// do not use NTString, and instead UTF16PtrFromString should be used for
+// the more common *uint16 string type.
+func NewNTString(s string) (*NTString, error) {
+	var nts NTString
+	s8, err := BytePtrFromString(s)
+	if err != nil {
+		return nil, err
+	}
+	RtlInitString(&nts, s8)
+	return &nts, nil
+}
+
+// Slice returns a byte slice that aliases the data in the NTString.
+func (s *NTString) Slice() []byte {
+	var slice []byte
+	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&slice))
+	hdr.Data = unsafe.Pointer(s.Buffer)
+	hdr.Len = int(s.Length)
+	hdr.Cap = int(s.MaximumLength)
+	return slice
+}
+
+func (s *NTString) String() string {
+	return ByteSliceToString(s.Slice())
+}
+
+// FindResource resolves a resource of the given name and resource type.
+func FindResource(module Handle, name, resType ResourceIDOrString) (Handle, error) {
+	var namePtr, resTypePtr uintptr
+	var name16, resType16 *uint16
+	var err error
+	resolvePtr := func(i interface{}, keep **uint16) (uintptr, error) {
+		switch v := i.(type) {
+		case string:
+			*keep, err = UTF16PtrFromString(v)
+			if err != nil {
+				return 0, err
+			}
+			return uintptr(unsafe.Pointer(*keep)), nil
+		case ResourceID:
+			return uintptr(v), nil
+		}
+		return 0, errorspkg.New("parameter must be a ResourceID or a string")
+	}
+	namePtr, err = resolvePtr(name, &name16)
+	if err != nil {
+		return 0, err
+	}
+	resTypePtr, err = resolvePtr(resType, &resType16)
+	if err != nil {
+		return 0, err
+	}
+	resInfo, err := findResource(module, namePtr, resTypePtr)
+	runtime.KeepAlive(name16)
+	runtime.KeepAlive(resType16)
+	return resInfo, err
+}
+
+func LoadResourceData(module, resInfo Handle) (data []byte, err error) {
+	size, err := SizeofResource(module, resInfo)
+	if err != nil {
+		return
+	}
+	resData, err := LoadResource(module, resInfo)
+	if err != nil {
+		return
+	}
+	ptr, err := LockResource(resData)
+	if err != nil {
+		return
+	}
+	h := (*unsafeheader.Slice)(unsafe.Pointer(&data))
+	h.Data = unsafe.Pointer(ptr)
+	h.Len = int(size)
+	h.Cap = int(size)
+	return
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/types_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/types_windows.go
index 265d797..23fe18e 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/types_windows.go
+++ b/src/cmd/vendor/golang.org/x/sys/windows/types_windows.go
@@ -10,6 +10,10 @@
 	"unsafe"
 )
 
+// NTStatus corresponds with NTSTATUS, error values returned by ntdll.dll and
+// other native functions.
+type NTStatus uint32
+
 const (
 	// Invented values to support what package os expects.
 	O_RDONLY   = 0x00000
@@ -216,6 +220,18 @@
 )
 
 const (
+	// attributes for ProcThreadAttributeList
+	PROC_THREAD_ATTRIBUTE_PARENT_PROCESS    = 0x00020000
+	PROC_THREAD_ATTRIBUTE_HANDLE_LIST       = 0x00020002
+	PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY    = 0x00030003
+	PROC_THREAD_ATTRIBUTE_PREFERRED_NODE    = 0x00020004
+	PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR   = 0x00030005
+	PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = 0x00020007
+	PROC_THREAD_ATTRIBUTE_UMS_THREAD        = 0x00030006
+	PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL  = 0x0002000b
+)
+
+const (
 	// flags for CreateToolhelp32Snapshot
 	TH32CS_SNAPHEAPLIST = 0x01
 	TH32CS_SNAPPROCESS  = 0x02
@@ -227,7 +243,7 @@
 )
 
 const (
-	// filters for ReadDirectoryChangesW
+	// filters for ReadDirectoryChangesW and FindFirstChangeNotificationW
 	FILE_NOTIFY_CHANGE_FILE_NAME   = 0x001
 	FILE_NOTIFY_CHANGE_DIR_NAME    = 0x002
 	FILE_NOTIFY_CHANGE_ATTRIBUTES  = 0x004
@@ -249,24 +265,27 @@
 
 const (
 	// wincrypt.h
-	PROV_RSA_FULL                    = 1
-	PROV_RSA_SIG                     = 2
-	PROV_DSS                         = 3
-	PROV_FORTEZZA                    = 4
-	PROV_MS_EXCHANGE                 = 5
-	PROV_SSL                         = 6
-	PROV_RSA_SCHANNEL                = 12
-	PROV_DSS_DH                      = 13
-	PROV_EC_ECDSA_SIG                = 14
-	PROV_EC_ECNRA_SIG                = 15
-	PROV_EC_ECDSA_FULL               = 16
-	PROV_EC_ECNRA_FULL               = 17
-	PROV_DH_SCHANNEL                 = 18
-	PROV_SPYRUS_LYNKS                = 20
-	PROV_RNG                         = 21
-	PROV_INTEL_SEC                   = 22
-	PROV_REPLACE_OWF                 = 23
-	PROV_RSA_AES                     = 24
+	/* certenrolld_begin -- PROV_RSA_*/
+	PROV_RSA_FULL      = 1
+	PROV_RSA_SIG       = 2
+	PROV_DSS           = 3
+	PROV_FORTEZZA      = 4
+	PROV_MS_EXCHANGE   = 5
+	PROV_SSL           = 6
+	PROV_RSA_SCHANNEL  = 12
+	PROV_DSS_DH        = 13
+	PROV_EC_ECDSA_SIG  = 14
+	PROV_EC_ECNRA_SIG  = 15
+	PROV_EC_ECDSA_FULL = 16
+	PROV_EC_ECNRA_FULL = 17
+	PROV_DH_SCHANNEL   = 18
+	PROV_SPYRUS_LYNKS  = 20
+	PROV_RNG           = 21
+	PROV_INTEL_SEC     = 22
+	PROV_REPLACE_OWF   = 23
+	PROV_RSA_AES       = 24
+
+	/* dwFlags definitions for CryptAcquireContext */
 	CRYPT_VERIFYCONTEXT              = 0xF0000000
 	CRYPT_NEWKEYSET                  = 0x00000008
 	CRYPT_DELETEKEYSET               = 0x00000010
@@ -274,6 +293,34 @@
 	CRYPT_SILENT                     = 0x00000040
 	CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080
 
+	/* Flags for PFXImportCertStore */
+	CRYPT_EXPORTABLE                   = 0x00000001
+	CRYPT_USER_PROTECTED               = 0x00000002
+	CRYPT_USER_KEYSET                  = 0x00001000
+	PKCS12_PREFER_CNG_KSP              = 0x00000100
+	PKCS12_ALWAYS_CNG_KSP              = 0x00000200
+	PKCS12_ALLOW_OVERWRITE_KEY         = 0x00004000
+	PKCS12_NO_PERSIST_KEY              = 0x00008000
+	PKCS12_INCLUDE_EXTENDED_PROPERTIES = 0x00000010
+
+	/* Flags for CryptAcquireCertificatePrivateKey */
+	CRYPT_ACQUIRE_CACHE_FLAG             = 0x00000001
+	CRYPT_ACQUIRE_USE_PROV_INFO_FLAG     = 0x00000002
+	CRYPT_ACQUIRE_COMPARE_KEY_FLAG       = 0x00000004
+	CRYPT_ACQUIRE_NO_HEALING             = 0x00000008
+	CRYPT_ACQUIRE_SILENT_FLAG            = 0x00000040
+	CRYPT_ACQUIRE_WINDOW_HANDLE_FLAG     = 0x00000080
+	CRYPT_ACQUIRE_NCRYPT_KEY_FLAGS_MASK  = 0x00070000
+	CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG  = 0x00010000
+	CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG = 0x00020000
+	CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG   = 0x00040000
+
+	/* pdwKeySpec for CryptAcquireCertificatePrivateKey */
+	AT_KEYEXCHANGE       = 1
+	AT_SIGNATURE         = 2
+	CERT_NCRYPT_KEY_SPEC = 0xFFFFFFFF
+
+	/* Default usage match type is AND with value zero */
 	USAGE_MATCH_TYPE_AND = 0
 	USAGE_MATCH_TYPE_OR  = 1
 
@@ -398,6 +445,89 @@
 	CERT_TRUST_IS_CA_TRUSTED                 = 0x00004000
 	CERT_TRUST_IS_COMPLEX_CHAIN              = 0x00010000
 
+	/* Certificate Information Flags */
+	CERT_INFO_VERSION_FLAG                 = 1
+	CERT_INFO_SERIAL_NUMBER_FLAG           = 2
+	CERT_INFO_SIGNATURE_ALGORITHM_FLAG     = 3
+	CERT_INFO_ISSUER_FLAG                  = 4
+	CERT_INFO_NOT_BEFORE_FLAG              = 5
+	CERT_INFO_NOT_AFTER_FLAG               = 6
+	CERT_INFO_SUBJECT_FLAG                 = 7
+	CERT_INFO_SUBJECT_PUBLIC_KEY_INFO_FLAG = 8
+	CERT_INFO_ISSUER_UNIQUE_ID_FLAG        = 9
+	CERT_INFO_SUBJECT_UNIQUE_ID_FLAG       = 10
+	CERT_INFO_EXTENSION_FLAG               = 11
+
+	/* dwFindType for CertFindCertificateInStore  */
+	CERT_COMPARE_MASK                     = 0xFFFF
+	CERT_COMPARE_SHIFT                    = 16
+	CERT_COMPARE_ANY                      = 0
+	CERT_COMPARE_SHA1_HASH                = 1
+	CERT_COMPARE_NAME                     = 2
+	CERT_COMPARE_ATTR                     = 3
+	CERT_COMPARE_MD5_HASH                 = 4
+	CERT_COMPARE_PROPERTY                 = 5
+	CERT_COMPARE_PUBLIC_KEY               = 6
+	CERT_COMPARE_HASH                     = CERT_COMPARE_SHA1_HASH
+	CERT_COMPARE_NAME_STR_A               = 7
+	CERT_COMPARE_NAME_STR_W               = 8
+	CERT_COMPARE_KEY_SPEC                 = 9
+	CERT_COMPARE_ENHKEY_USAGE             = 10
+	CERT_COMPARE_CTL_USAGE                = CERT_COMPARE_ENHKEY_USAGE
+	CERT_COMPARE_SUBJECT_CERT             = 11
+	CERT_COMPARE_ISSUER_OF                = 12
+	CERT_COMPARE_EXISTING                 = 13
+	CERT_COMPARE_SIGNATURE_HASH           = 14
+	CERT_COMPARE_KEY_IDENTIFIER           = 15
+	CERT_COMPARE_CERT_ID                  = 16
+	CERT_COMPARE_CROSS_CERT_DIST_POINTS   = 17
+	CERT_COMPARE_PUBKEY_MD5_HASH          = 18
+	CERT_COMPARE_SUBJECT_INFO_ACCESS      = 19
+	CERT_COMPARE_HASH_STR                 = 20
+	CERT_COMPARE_HAS_PRIVATE_KEY          = 21
+	CERT_FIND_ANY                         = (CERT_COMPARE_ANY << CERT_COMPARE_SHIFT)
+	CERT_FIND_SHA1_HASH                   = (CERT_COMPARE_SHA1_HASH << CERT_COMPARE_SHIFT)
+	CERT_FIND_MD5_HASH                    = (CERT_COMPARE_MD5_HASH << CERT_COMPARE_SHIFT)
+	CERT_FIND_SIGNATURE_HASH              = (CERT_COMPARE_SIGNATURE_HASH << CERT_COMPARE_SHIFT)
+	CERT_FIND_KEY_IDENTIFIER              = (CERT_COMPARE_KEY_IDENTIFIER << CERT_COMPARE_SHIFT)
+	CERT_FIND_HASH                        = CERT_FIND_SHA1_HASH
+	CERT_FIND_PROPERTY                    = (CERT_COMPARE_PROPERTY << CERT_COMPARE_SHIFT)
+	CERT_FIND_PUBLIC_KEY                  = (CERT_COMPARE_PUBLIC_KEY << CERT_COMPARE_SHIFT)
+	CERT_FIND_SUBJECT_NAME                = (CERT_COMPARE_NAME<<CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
+	CERT_FIND_SUBJECT_ATTR                = (CERT_COMPARE_ATTR<<CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
+	CERT_FIND_ISSUER_NAME                 = (CERT_COMPARE_NAME<<CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
+	CERT_FIND_ISSUER_ATTR                 = (CERT_COMPARE_ATTR<<CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
+	CERT_FIND_SUBJECT_STR_A               = (CERT_COMPARE_NAME_STR_A<<CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
+	CERT_FIND_SUBJECT_STR_W               = (CERT_COMPARE_NAME_STR_W<<CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
+	CERT_FIND_SUBJECT_STR                 = CERT_FIND_SUBJECT_STR_W
+	CERT_FIND_ISSUER_STR_A                = (CERT_COMPARE_NAME_STR_A<<CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
+	CERT_FIND_ISSUER_STR_W                = (CERT_COMPARE_NAME_STR_W<<CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
+	CERT_FIND_ISSUER_STR                  = CERT_FIND_ISSUER_STR_W
+	CERT_FIND_KEY_SPEC                    = (CERT_COMPARE_KEY_SPEC << CERT_COMPARE_SHIFT)
+	CERT_FIND_ENHKEY_USAGE                = (CERT_COMPARE_ENHKEY_USAGE << CERT_COMPARE_SHIFT)
+	CERT_FIND_CTL_USAGE                   = CERT_FIND_ENHKEY_USAGE
+	CERT_FIND_SUBJECT_CERT                = (CERT_COMPARE_SUBJECT_CERT << CERT_COMPARE_SHIFT)
+	CERT_FIND_ISSUER_OF                   = (CERT_COMPARE_ISSUER_OF << CERT_COMPARE_SHIFT)
+	CERT_FIND_EXISTING                    = (CERT_COMPARE_EXISTING << CERT_COMPARE_SHIFT)
+	CERT_FIND_CERT_ID                     = (CERT_COMPARE_CERT_ID << CERT_COMPARE_SHIFT)
+	CERT_FIND_CROSS_CERT_DIST_POINTS      = (CERT_COMPARE_CROSS_CERT_DIST_POINTS << CERT_COMPARE_SHIFT)
+	CERT_FIND_PUBKEY_MD5_HASH             = (CERT_COMPARE_PUBKEY_MD5_HASH << CERT_COMPARE_SHIFT)
+	CERT_FIND_SUBJECT_INFO_ACCESS         = (CERT_COMPARE_SUBJECT_INFO_ACCESS << CERT_COMPARE_SHIFT)
+	CERT_FIND_HASH_STR                    = (CERT_COMPARE_HASH_STR << CERT_COMPARE_SHIFT)
+	CERT_FIND_HAS_PRIVATE_KEY             = (CERT_COMPARE_HAS_PRIVATE_KEY << CERT_COMPARE_SHIFT)
+	CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG  = 0x1
+	CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG  = 0x2
+	CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG = 0x4
+	CERT_FIND_NO_ENHKEY_USAGE_FLAG        = 0x8
+	CERT_FIND_OR_ENHKEY_USAGE_FLAG        = 0x10
+	CERT_FIND_VALID_ENHKEY_USAGE_FLAG     = 0x20
+	CERT_FIND_OPTIONAL_CTL_USAGE_FLAG     = CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG
+	CERT_FIND_EXT_ONLY_CTL_USAGE_FLAG     = CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG
+	CERT_FIND_PROP_ONLY_CTL_USAGE_FLAG    = CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG
+	CERT_FIND_NO_CTL_USAGE_FLAG           = CERT_FIND_NO_ENHKEY_USAGE_FLAG
+	CERT_FIND_OR_CTL_USAGE_FLAG           = CERT_FIND_OR_ENHKEY_USAGE_FLAG
+	CERT_FIND_VALID_CTL_USAGE_FLAG        = CERT_FIND_VALID_ENHKEY_USAGE_FLAG
+
 	/* policyOID values for CertVerifyCertificateChainPolicy function */
 	CERT_CHAIN_POLICY_BASE              = 1
 	CERT_CHAIN_POLICY_AUTHENTICODE      = 2
@@ -409,6 +539,82 @@
 	CERT_CHAIN_POLICY_EV                = 8
 	CERT_CHAIN_POLICY_SSL_F12           = 9
 
+	/* flag for dwFindType CertFindChainInStore  */
+	CERT_CHAIN_FIND_BY_ISSUER = 1
+
+	/* dwFindFlags for CertFindChainInStore when dwFindType == CERT_CHAIN_FIND_BY_ISSUER */
+	CERT_CHAIN_FIND_BY_ISSUER_COMPARE_KEY_FLAG    = 0x0001
+	CERT_CHAIN_FIND_BY_ISSUER_COMPLEX_CHAIN_FLAG  = 0x0002
+	CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_URL_FLAG = 0x0004
+	CERT_CHAIN_FIND_BY_ISSUER_LOCAL_MACHINE_FLAG  = 0x0008
+	CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG         = 0x4000
+	CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_FLAG     = 0x8000
+
+	/* Certificate Store close flags */
+	CERT_CLOSE_STORE_FORCE_FLAG = 0x00000001
+	CERT_CLOSE_STORE_CHECK_FLAG = 0x00000002
+
+	/* CryptQueryObject object type */
+	CERT_QUERY_OBJECT_FILE = 1
+	CERT_QUERY_OBJECT_BLOB = 2
+
+	/* CryptQueryObject content type flags */
+	CERT_QUERY_CONTENT_CERT                    = 1
+	CERT_QUERY_CONTENT_CTL                     = 2
+	CERT_QUERY_CONTENT_CRL                     = 3
+	CERT_QUERY_CONTENT_SERIALIZED_STORE        = 4
+	CERT_QUERY_CONTENT_SERIALIZED_CERT         = 5
+	CERT_QUERY_CONTENT_SERIALIZED_CTL          = 6
+	CERT_QUERY_CONTENT_SERIALIZED_CRL          = 7
+	CERT_QUERY_CONTENT_PKCS7_SIGNED            = 8
+	CERT_QUERY_CONTENT_PKCS7_UNSIGNED          = 9
+	CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED      = 10
+	CERT_QUERY_CONTENT_PKCS10                  = 11
+	CERT_QUERY_CONTENT_PFX                     = 12
+	CERT_QUERY_CONTENT_CERT_PAIR               = 13
+	CERT_QUERY_CONTENT_PFX_AND_LOAD            = 14
+	CERT_QUERY_CONTENT_FLAG_CERT               = (1 << CERT_QUERY_CONTENT_CERT)
+	CERT_QUERY_CONTENT_FLAG_CTL                = (1 << CERT_QUERY_CONTENT_CTL)
+	CERT_QUERY_CONTENT_FLAG_CRL                = (1 << CERT_QUERY_CONTENT_CRL)
+	CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE   = (1 << CERT_QUERY_CONTENT_SERIALIZED_STORE)
+	CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT    = (1 << CERT_QUERY_CONTENT_SERIALIZED_CERT)
+	CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL     = (1 << CERT_QUERY_CONTENT_SERIALIZED_CTL)
+	CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL     = (1 << CERT_QUERY_CONTENT_SERIALIZED_CRL)
+	CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED       = (1 << CERT_QUERY_CONTENT_PKCS7_SIGNED)
+	CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED     = (1 << CERT_QUERY_CONTENT_PKCS7_UNSIGNED)
+	CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED = (1 << CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED)
+	CERT_QUERY_CONTENT_FLAG_PKCS10             = (1 << CERT_QUERY_CONTENT_PKCS10)
+	CERT_QUERY_CONTENT_FLAG_PFX                = (1 << CERT_QUERY_CONTENT_PFX)
+	CERT_QUERY_CONTENT_FLAG_CERT_PAIR          = (1 << CERT_QUERY_CONTENT_CERT_PAIR)
+	CERT_QUERY_CONTENT_FLAG_PFX_AND_LOAD       = (1 << CERT_QUERY_CONTENT_PFX_AND_LOAD)
+	CERT_QUERY_CONTENT_FLAG_ALL                = (CERT_QUERY_CONTENT_FLAG_CERT | CERT_QUERY_CONTENT_FLAG_CTL | CERT_QUERY_CONTENT_FLAG_CRL | CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE | CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT | CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL | CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL | CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED | CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED | CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED | CERT_QUERY_CONTENT_FLAG_PKCS10 | CERT_QUERY_CONTENT_FLAG_PFX | CERT_QUERY_CONTENT_FLAG_CERT_PAIR)
+	CERT_QUERY_CONTENT_FLAG_ALL_ISSUER_CERT    = (CERT_QUERY_CONTENT_FLAG_CERT | CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE | CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT | CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED | CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED)
+
+	/* CryptQueryObject format type flags */
+	CERT_QUERY_FORMAT_BINARY                     = 1
+	CERT_QUERY_FORMAT_BASE64_ENCODED             = 2
+	CERT_QUERY_FORMAT_ASN_ASCII_HEX_ENCODED      = 3
+	CERT_QUERY_FORMAT_FLAG_BINARY                = (1 << CERT_QUERY_FORMAT_BINARY)
+	CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED        = (1 << CERT_QUERY_FORMAT_BASE64_ENCODED)
+	CERT_QUERY_FORMAT_FLAG_ASN_ASCII_HEX_ENCODED = (1 << CERT_QUERY_FORMAT_ASN_ASCII_HEX_ENCODED)
+	CERT_QUERY_FORMAT_FLAG_ALL                   = (CERT_QUERY_FORMAT_FLAG_BINARY | CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED | CERT_QUERY_FORMAT_FLAG_ASN_ASCII_HEX_ENCODED)
+
+	/* CertGetNameString name types */
+	CERT_NAME_EMAIL_TYPE            = 1
+	CERT_NAME_RDN_TYPE              = 2
+	CERT_NAME_ATTR_TYPE             = 3
+	CERT_NAME_SIMPLE_DISPLAY_TYPE   = 4
+	CERT_NAME_FRIENDLY_DISPLAY_TYPE = 5
+	CERT_NAME_DNS_TYPE              = 6
+	CERT_NAME_URL_TYPE              = 7
+	CERT_NAME_UPN_TYPE              = 8
+
+	/* CertGetNameString flags */
+	CERT_NAME_ISSUER_FLAG              = 0x1
+	CERT_NAME_DISABLE_IE4_UTF8_FLAG    = 0x10000
+	CERT_NAME_SEARCH_ALL_NAMES_FLAG    = 0x2
+	CERT_NAME_STR_ENABLE_PUNYCODE_FLAG = 0x00200000
+
 	/* AuthType values for SSLExtraCertChainPolicyPara struct */
 	AUTHTYPE_CLIENT = 1
 	AUTHTYPE_SERVER = 2
@@ -419,6 +625,22 @@
 	SECURITY_FLAG_IGNORE_WRONG_USAGE       = 0x00000200
 	SECURITY_FLAG_IGNORE_CERT_CN_INVALID   = 0x00001000
 	SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000
+
+	/* Flags for Crypt[Un]ProtectData */
+	CRYPTPROTECT_UI_FORBIDDEN      = 0x1
+	CRYPTPROTECT_LOCAL_MACHINE     = 0x4
+	CRYPTPROTECT_CRED_SYNC         = 0x8
+	CRYPTPROTECT_AUDIT             = 0x10
+	CRYPTPROTECT_NO_RECOVERY       = 0x20
+	CRYPTPROTECT_VERIFY_PROTECTION = 0x40
+	CRYPTPROTECT_CRED_REGENERATE   = 0x80
+
+	/* Flags for CryptProtectPromptStruct */
+	CRYPTPROTECT_PROMPT_ON_UNPROTECT   = 1
+	CRYPTPROTECT_PROMPT_ON_PROTECT     = 2
+	CRYPTPROTECT_PROMPT_RESERVED       = 4
+	CRYPTPROTECT_PROMPT_STRONG         = 8
+	CRYPTPROTECT_PROMPT_REQUIRE_STRONG = 16
 )
 
 const (
@@ -441,10 +663,58 @@
 	REALTIME_PRIORITY_CLASS       = 0x00000100
 )
 
+/* wintrust.h constants for WinVerifyTrustEx */
+const (
+	WTD_UI_ALL    = 1
+	WTD_UI_NONE   = 2
+	WTD_UI_NOBAD  = 3
+	WTD_UI_NOGOOD = 4
+
+	WTD_REVOKE_NONE       = 0
+	WTD_REVOKE_WHOLECHAIN = 1
+
+	WTD_CHOICE_FILE    = 1
+	WTD_CHOICE_CATALOG = 2
+	WTD_CHOICE_BLOB    = 3
+	WTD_CHOICE_SIGNER  = 4
+	WTD_CHOICE_CERT    = 5
+
+	WTD_STATEACTION_IGNORE           = 0x00000000
+	WTD_STATEACTION_VERIFY           = 0x00000010
+	WTD_STATEACTION_CLOSE            = 0x00000002
+	WTD_STATEACTION_AUTO_CACHE       = 0x00000003
+	WTD_STATEACTION_AUTO_CACHE_FLUSH = 0x00000004
+
+	WTD_USE_IE4_TRUST_FLAG                  = 0x1
+	WTD_NO_IE4_CHAIN_FLAG                   = 0x2
+	WTD_NO_POLICY_USAGE_FLAG                = 0x4
+	WTD_REVOCATION_CHECK_NONE               = 0x10
+	WTD_REVOCATION_CHECK_END_CERT           = 0x20
+	WTD_REVOCATION_CHECK_CHAIN              = 0x40
+	WTD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x80
+	WTD_SAFER_FLAG                          = 0x100
+	WTD_HASH_ONLY_FLAG                      = 0x200
+	WTD_USE_DEFAULT_OSVER_CHECK             = 0x400
+	WTD_LIFETIME_SIGNING_FLAG               = 0x800
+	WTD_CACHE_ONLY_URL_RETRIEVAL            = 0x1000
+	WTD_DISABLE_MD2_MD4                     = 0x2000
+	WTD_MOTW                                = 0x4000
+
+	WTD_UICONTEXT_EXECUTE = 0
+	WTD_UICONTEXT_INSTALL = 1
+)
+
 var (
 	OID_PKIX_KP_SERVER_AUTH = []byte("1.3.6.1.5.5.7.3.1\x00")
 	OID_SERVER_GATED_CRYPTO = []byte("1.3.6.1.4.1.311.10.3.3\x00")
 	OID_SGC_NETSCAPE        = []byte("2.16.840.1.113730.4.1\x00")
+
+	WINTRUST_ACTION_GENERIC_VERIFY_V2 = GUID{
+		Data1: 0xaac56b,
+		Data2: 0xcd44,
+		Data3: 0x11d0,
+		Data4: [8]byte{0x8c, 0xc2, 0x0, 0xc0, 0x4f, 0xc2, 0x95, 0xee},
+	}
 )
 
 // Pointer represents a pointer to an arbitrary Windows type.
@@ -540,6 +810,14 @@
 	Reserved1         uint32
 	FileName          [MAX_PATH]uint16
 	AlternateFileName [14]uint16
+
+	// The Microsoft documentation for this struct¹ describes three additional
+	// fields: dwFileType, dwCreatorType, and wFinderFlags. However, those fields
+	// are empirically only present in the macOS port of the Win32 API,² and thus
+	// not needed for binaries built for Windows.
+	//
+	// ¹ https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-win32_find_dataw describe
+	// ² https://golang.org/issue/42637#issuecomment-760715755.
 }
 
 func copyFindData(dst *Win32finddata, src *win32finddata1) {
@@ -624,6 +902,23 @@
 	StdErr        Handle
 }
 
+type StartupInfoEx struct {
+	StartupInfo
+	ProcThreadAttributeList *ProcThreadAttributeList
+}
+
+// ProcThreadAttributeList is a placeholder type to represent a PROC_THREAD_ATTRIBUTE_LIST.
+//
+// To create a *ProcThreadAttributeList, use NewProcThreadAttributeList, and
+// free its memory using ProcThreadAttributeList.Delete.
+type ProcThreadAttributeList struct {
+	// This is of type unsafe.Pointer, not of type byte or uintptr, because
+	// the contents of it is mostly a list of pointers, and in most cases,
+	// that's a list of pointers to Go-allocated objects. In order to keep
+	// the GC from collecting these objects, we declare this as unsafe.Pointer.
+	_ [1]unsafe.Pointer
+}
+
 type ProcessInformation struct {
 	Process   Handle
 	Thread    Handle
@@ -725,6 +1020,7 @@
 
 	// cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460
 
+	IP_HDRINCL         = 0x2
 	IP_TOS             = 0x3
 	IP_TTL             = 0x4
 	IP_MULTICAST_IF    = 0x9
@@ -732,6 +1028,7 @@
 	IP_MULTICAST_LOOP  = 0xb
 	IP_ADD_MEMBERSHIP  = 0xc
 	IP_DROP_MEMBERSHIP = 0xd
+	IP_PKTINFO         = 0x13
 
 	IPV6_V6ONLY         = 0x1b
 	IPV6_UNICAST_HOPS   = 0x4
@@ -740,6 +1037,7 @@
 	IPV6_MULTICAST_LOOP = 0xb
 	IPV6_JOIN_GROUP     = 0xc
 	IPV6_LEAVE_GROUP    = 0xd
+	IPV6_PKTINFO        = 0x13
 
 	MSG_OOB       = 0x1
 	MSG_PEEK      = 0x2
@@ -777,6 +1075,18 @@
 	Flags       uint32
 }
 
+// Flags for WSASocket
+const (
+	WSA_FLAG_OVERLAPPED             = 0x01
+	WSA_FLAG_MULTIPOINT_C_ROOT      = 0x02
+	WSA_FLAG_MULTIPOINT_C_LEAF      = 0x04
+	WSA_FLAG_MULTIPOINT_D_ROOT      = 0x08
+	WSA_FLAG_MULTIPOINT_D_LEAF      = 0x10
+	WSA_FLAG_ACCESS_SYSTEM_SECURITY = 0x40
+	WSA_FLAG_NO_HANDLE_INHERIT      = 0x80
+	WSA_FLAG_REGISTERED_IO          = 0x100
+)
+
 // Invented values to support what package os expects.
 const (
 	S_IFMT   = 0x1f000
@@ -1033,7 +1343,57 @@
 }
 
 type CertInfo struct {
-	// Not implemented
+	Version              uint32
+	SerialNumber         CryptIntegerBlob
+	SignatureAlgorithm   CryptAlgorithmIdentifier
+	Issuer               CertNameBlob
+	NotBefore            Filetime
+	NotAfter             Filetime
+	Subject              CertNameBlob
+	SubjectPublicKeyInfo CertPublicKeyInfo
+	IssuerUniqueId       CryptBitBlob
+	SubjectUniqueId      CryptBitBlob
+	CountExtensions      uint32
+	Extensions           *CertExtension
+}
+
+type CertExtension struct {
+	ObjId    *byte
+	Critical int32
+	Value    CryptObjidBlob
+}
+
+type CryptAlgorithmIdentifier struct {
+	ObjId      *byte
+	Parameters CryptObjidBlob
+}
+
+type CertPublicKeyInfo struct {
+	Algorithm CryptAlgorithmIdentifier
+	PublicKey CryptBitBlob
+}
+
+type DataBlob struct {
+	Size uint32
+	Data *byte
+}
+type CryptIntegerBlob DataBlob
+type CryptUintBlob DataBlob
+type CryptObjidBlob DataBlob
+type CertNameBlob DataBlob
+type CertRdnValueBlob DataBlob
+type CertBlob DataBlob
+type CrlBlob DataBlob
+type CryptDataBlob DataBlob
+type CryptHashBlob DataBlob
+type CryptDigestBlob DataBlob
+type CryptDerBlob DataBlob
+type CryptAttrBlob DataBlob
+
+type CryptBitBlob struct {
+	Size       uint32
+	Data       *byte
+	UnusedBits uint32
 }
 
 type CertContext struct {
@@ -1139,6 +1499,79 @@
 	ExtraPolicyStatus Pointer
 }
 
+type CertPolicyInfo struct {
+	Identifier      *byte
+	CountQualifiers uint32
+	Qualifiers      *CertPolicyQualifierInfo
+}
+
+type CertPoliciesInfo struct {
+	Count       uint32
+	PolicyInfos *CertPolicyInfo
+}
+
+type CertPolicyQualifierInfo struct {
+	// Not implemented
+}
+
+type CertStrongSignPara struct {
+	Size                      uint32
+	InfoChoice                uint32
+	InfoOrSerializedInfoOrOID unsafe.Pointer
+}
+
+type CryptProtectPromptStruct struct {
+	Size        uint32
+	PromptFlags uint32
+	App         HWND
+	Prompt      *uint16
+}
+
+type CertChainFindByIssuerPara struct {
+	Size                   uint32
+	UsageIdentifier        *byte
+	KeySpec                uint32
+	AcquirePrivateKeyFlags uint32
+	IssuerCount            uint32
+	Issuer                 Pointer
+	FindCallback           Pointer
+	FindArg                Pointer
+	IssuerChainIndex       *uint32
+	IssuerElementIndex     *uint32
+}
+
+type WinTrustData struct {
+	Size                            uint32
+	PolicyCallbackData              uintptr
+	SIPClientData                   uintptr
+	UIChoice                        uint32
+	RevocationChecks                uint32
+	UnionChoice                     uint32
+	FileOrCatalogOrBlobOrSgnrOrCert unsafe.Pointer
+	StateAction                     uint32
+	StateData                       Handle
+	URLReference                    *uint16
+	ProvFlags                       uint32
+	UIContext                       uint32
+	SignatureSettings               *WinTrustSignatureSettings
+}
+
+type WinTrustFileInfo struct {
+	Size         uint32
+	FilePath     *uint16
+	File         Handle
+	KnownSubject *GUID
+}
+
+type WinTrustSignatureSettings struct {
+	Size             uint32
+	Index            uint32
+	Flags            uint32
+	SecondarySigs    uint32
+	VerifiedSigIndex uint32
+	CryptoPolicy     *CertStrongSignPara
+}
+
 const (
 	// do not reorder
 	HKEY_CLASSES_ROOT = 0x80000000 + iota
@@ -1820,3 +2253,522 @@
 	LOAD_LIBRARY_SEARCH_SYSTEM32_NO_FORWARDER = 0x00004000
 	LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY      = 0x00008000
 )
+
+// RegNotifyChangeKeyValue notifyFilter flags.
+const (
+	// REG_NOTIFY_CHANGE_NAME notifies the caller if a subkey is added or deleted.
+	REG_NOTIFY_CHANGE_NAME = 0x00000001
+
+	// REG_NOTIFY_CHANGE_ATTRIBUTES notifies the caller of changes to the attributes of the key, such as the security descriptor information.
+	REG_NOTIFY_CHANGE_ATTRIBUTES = 0x00000002
+
+	// REG_NOTIFY_CHANGE_LAST_SET notifies the caller of changes to a value of the key. This can include adding or deleting a value, or changing an existing value.
+	REG_NOTIFY_CHANGE_LAST_SET = 0x00000004
+
+	// REG_NOTIFY_CHANGE_SECURITY notifies the caller of changes to the security descriptor of the key.
+	REG_NOTIFY_CHANGE_SECURITY = 0x00000008
+
+	// REG_NOTIFY_THREAD_AGNOSTIC indicates that the lifetime of the registration must not be tied to the lifetime of the thread issuing the RegNotifyChangeKeyValue call. Note: This flag value is only supported in Windows 8 and later.
+	REG_NOTIFY_THREAD_AGNOSTIC = 0x10000000
+)
+
+type CommTimeouts struct {
+	ReadIntervalTimeout         uint32
+	ReadTotalTimeoutMultiplier  uint32
+	ReadTotalTimeoutConstant    uint32
+	WriteTotalTimeoutMultiplier uint32
+	WriteTotalTimeoutConstant   uint32
+}
+
+// NTUnicodeString is a UTF-16 string for NT native APIs, corresponding to UNICODE_STRING.
+type NTUnicodeString struct {
+	Length        uint16
+	MaximumLength uint16
+	Buffer        *uint16
+}
+
+// NTString is an ANSI string for NT native APIs, corresponding to STRING.
+type NTString struct {
+	Length        uint16
+	MaximumLength uint16
+	Buffer        *byte
+}
+
+type LIST_ENTRY struct {
+	Flink *LIST_ENTRY
+	Blink *LIST_ENTRY
+}
+
+type LDR_DATA_TABLE_ENTRY struct {
+	reserved1          [2]uintptr
+	InMemoryOrderLinks LIST_ENTRY
+	reserved2          [2]uintptr
+	DllBase            uintptr
+	reserved3          [2]uintptr
+	FullDllName        NTUnicodeString
+	reserved4          [8]byte
+	reserved5          [3]uintptr
+	reserved6          uintptr
+	TimeDateStamp      uint32
+}
+
+type PEB_LDR_DATA struct {
+	reserved1               [8]byte
+	reserved2               [3]uintptr
+	InMemoryOrderModuleList LIST_ENTRY
+}
+
+type CURDIR struct {
+	DosPath NTUnicodeString
+	Handle  Handle
+}
+
+type RTL_DRIVE_LETTER_CURDIR struct {
+	Flags     uint16
+	Length    uint16
+	TimeStamp uint32
+	DosPath   NTString
+}
+
+type RTL_USER_PROCESS_PARAMETERS struct {
+	MaximumLength, Length uint32
+
+	Flags, DebugFlags uint32
+
+	ConsoleHandle                                Handle
+	ConsoleFlags                                 uint32
+	StandardInput, StandardOutput, StandardError Handle
+
+	CurrentDirectory CURDIR
+	DllPath          NTUnicodeString
+	ImagePathName    NTUnicodeString
+	CommandLine      NTUnicodeString
+	Environment      unsafe.Pointer
+
+	StartingX, StartingY, CountX, CountY, CountCharsX, CountCharsY, FillAttribute uint32
+
+	WindowFlags, ShowWindowFlags                     uint32
+	WindowTitle, DesktopInfo, ShellInfo, RuntimeData NTUnicodeString
+	CurrentDirectories                               [32]RTL_DRIVE_LETTER_CURDIR
+
+	EnvironmentSize, EnvironmentVersion uintptr
+
+	PackageDependencyData unsafe.Pointer
+	ProcessGroupId        uint32
+	LoaderThreads         uint32
+
+	RedirectionDllName               NTUnicodeString
+	HeapPartitionName                NTUnicodeString
+	DefaultThreadpoolCpuSetMasks     uintptr
+	DefaultThreadpoolCpuSetMaskCount uint32
+}
+
+type PEB struct {
+	reserved1              [2]byte
+	BeingDebugged          byte
+	BitField               byte
+	reserved3              uintptr
+	ImageBaseAddress       uintptr
+	Ldr                    *PEB_LDR_DATA
+	ProcessParameters      *RTL_USER_PROCESS_PARAMETERS
+	reserved4              [3]uintptr
+	AtlThunkSListPtr       uintptr
+	reserved5              uintptr
+	reserved6              uint32
+	reserved7              uintptr
+	reserved8              uint32
+	AtlThunkSListPtr32     uint32
+	reserved9              [45]uintptr
+	reserved10             [96]byte
+	PostProcessInitRoutine uintptr
+	reserved11             [128]byte
+	reserved12             [1]uintptr
+	SessionId              uint32
+}
+
+type OBJECT_ATTRIBUTES struct {
+	Length             uint32
+	RootDirectory      Handle
+	ObjectName         *NTUnicodeString
+	Attributes         uint32
+	SecurityDescriptor *SECURITY_DESCRIPTOR
+	SecurityQoS        *SECURITY_QUALITY_OF_SERVICE
+}
+
+// Values for the Attributes member of OBJECT_ATTRIBUTES.
+const (
+	OBJ_INHERIT                       = 0x00000002
+	OBJ_PERMANENT                     = 0x00000010
+	OBJ_EXCLUSIVE                     = 0x00000020
+	OBJ_CASE_INSENSITIVE              = 0x00000040
+	OBJ_OPENIF                        = 0x00000080
+	OBJ_OPENLINK                      = 0x00000100
+	OBJ_KERNEL_HANDLE                 = 0x00000200
+	OBJ_FORCE_ACCESS_CHECK            = 0x00000400
+	OBJ_IGNORE_IMPERSONATED_DEVICEMAP = 0x00000800
+	OBJ_DONT_REPARSE                  = 0x00001000
+	OBJ_VALID_ATTRIBUTES              = 0x00001FF2
+)
+
+type IO_STATUS_BLOCK struct {
+	Status      NTStatus
+	Information uintptr
+}
+
+type RTLP_CURDIR_REF struct {
+	RefCount int32
+	Handle   Handle
+}
+
+type RTL_RELATIVE_NAME struct {
+	RelativeName        NTUnicodeString
+	ContainingDirectory Handle
+	CurDirRef           *RTLP_CURDIR_REF
+}
+
+const (
+	// CreateDisposition flags for NtCreateFile and NtCreateNamedPipeFile.
+	FILE_SUPERSEDE           = 0x00000000
+	FILE_OPEN                = 0x00000001
+	FILE_CREATE              = 0x00000002
+	FILE_OPEN_IF             = 0x00000003
+	FILE_OVERWRITE           = 0x00000004
+	FILE_OVERWRITE_IF        = 0x00000005
+	FILE_MAXIMUM_DISPOSITION = 0x00000005
+
+	// CreateOptions flags for NtCreateFile and NtCreateNamedPipeFile.
+	FILE_DIRECTORY_FILE            = 0x00000001
+	FILE_WRITE_THROUGH             = 0x00000002
+	FILE_SEQUENTIAL_ONLY           = 0x00000004
+	FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008
+	FILE_SYNCHRONOUS_IO_ALERT      = 0x00000010
+	FILE_SYNCHRONOUS_IO_NONALERT   = 0x00000020
+	FILE_NON_DIRECTORY_FILE        = 0x00000040
+	FILE_CREATE_TREE_CONNECTION    = 0x00000080
+	FILE_COMPLETE_IF_OPLOCKED      = 0x00000100
+	FILE_NO_EA_KNOWLEDGE           = 0x00000200
+	FILE_OPEN_REMOTE_INSTANCE      = 0x00000400
+	FILE_RANDOM_ACCESS             = 0x00000800
+	FILE_DELETE_ON_CLOSE           = 0x00001000
+	FILE_OPEN_BY_FILE_ID           = 0x00002000
+	FILE_OPEN_FOR_BACKUP_INTENT    = 0x00004000
+	FILE_NO_COMPRESSION            = 0x00008000
+	FILE_OPEN_REQUIRING_OPLOCK     = 0x00010000
+	FILE_DISALLOW_EXCLUSIVE        = 0x00020000
+	FILE_RESERVE_OPFILTER          = 0x00100000
+	FILE_OPEN_REPARSE_POINT        = 0x00200000
+	FILE_OPEN_NO_RECALL            = 0x00400000
+	FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000
+
+	// Parameter constants for NtCreateNamedPipeFile.
+
+	FILE_PIPE_BYTE_STREAM_TYPE = 0x00000000
+	FILE_PIPE_MESSAGE_TYPE     = 0x00000001
+
+	FILE_PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000
+	FILE_PIPE_REJECT_REMOTE_CLIENTS = 0x00000002
+
+	FILE_PIPE_TYPE_VALID_MASK = 0x00000003
+
+	FILE_PIPE_BYTE_STREAM_MODE = 0x00000000
+	FILE_PIPE_MESSAGE_MODE     = 0x00000001
+
+	FILE_PIPE_QUEUE_OPERATION    = 0x00000000
+	FILE_PIPE_COMPLETE_OPERATION = 0x00000001
+
+	FILE_PIPE_INBOUND     = 0x00000000
+	FILE_PIPE_OUTBOUND    = 0x00000001
+	FILE_PIPE_FULL_DUPLEX = 0x00000002
+
+	FILE_PIPE_DISCONNECTED_STATE = 0x00000001
+	FILE_PIPE_LISTENING_STATE    = 0x00000002
+	FILE_PIPE_CONNECTED_STATE    = 0x00000003
+	FILE_PIPE_CLOSING_STATE      = 0x00000004
+
+	FILE_PIPE_CLIENT_END = 0x00000000
+	FILE_PIPE_SERVER_END = 0x00000001
+)
+
+// ProcessInformationClasses for NtQueryInformationProcess and NtSetInformationProcess.
+const (
+	ProcessBasicInformation = iota
+	ProcessQuotaLimits
+	ProcessIoCounters
+	ProcessVmCounters
+	ProcessTimes
+	ProcessBasePriority
+	ProcessRaisePriority
+	ProcessDebugPort
+	ProcessExceptionPort
+	ProcessAccessToken
+	ProcessLdtInformation
+	ProcessLdtSize
+	ProcessDefaultHardErrorMode
+	ProcessIoPortHandlers
+	ProcessPooledUsageAndLimits
+	ProcessWorkingSetWatch
+	ProcessUserModeIOPL
+	ProcessEnableAlignmentFaultFixup
+	ProcessPriorityClass
+	ProcessWx86Information
+	ProcessHandleCount
+	ProcessAffinityMask
+	ProcessPriorityBoost
+	ProcessDeviceMap
+	ProcessSessionInformation
+	ProcessForegroundInformation
+	ProcessWow64Information
+	ProcessImageFileName
+	ProcessLUIDDeviceMapsEnabled
+	ProcessBreakOnTermination
+	ProcessDebugObjectHandle
+	ProcessDebugFlags
+	ProcessHandleTracing
+	ProcessIoPriority
+	ProcessExecuteFlags
+	ProcessTlsInformation
+	ProcessCookie
+	ProcessImageInformation
+	ProcessCycleTime
+	ProcessPagePriority
+	ProcessInstrumentationCallback
+	ProcessThreadStackAllocation
+	ProcessWorkingSetWatchEx
+	ProcessImageFileNameWin32
+	ProcessImageFileMapping
+	ProcessAffinityUpdateMode
+	ProcessMemoryAllocationMode
+	ProcessGroupInformation
+	ProcessTokenVirtualizationEnabled
+	ProcessConsoleHostProcess
+	ProcessWindowInformation
+	ProcessHandleInformation
+	ProcessMitigationPolicy
+	ProcessDynamicFunctionTableInformation
+	ProcessHandleCheckingMode
+	ProcessKeepAliveCount
+	ProcessRevokeFileHandles
+	ProcessWorkingSetControl
+	ProcessHandleTable
+	ProcessCheckStackExtentsMode
+	ProcessCommandLineInformation
+	ProcessProtectionInformation
+	ProcessMemoryExhaustion
+	ProcessFaultInformation
+	ProcessTelemetryIdInformation
+	ProcessCommitReleaseInformation
+	ProcessDefaultCpuSetsInformation
+	ProcessAllowedCpuSetsInformation
+	ProcessSubsystemProcess
+	ProcessJobMemoryInformation
+	ProcessInPrivate
+	ProcessRaiseUMExceptionOnInvalidHandleClose
+	ProcessIumChallengeResponse
+	ProcessChildProcessInformation
+	ProcessHighGraphicsPriorityInformation
+	ProcessSubsystemInformation
+	ProcessEnergyValues
+	ProcessActivityThrottleState
+	ProcessActivityThrottlePolicy
+	ProcessWin32kSyscallFilterInformation
+	ProcessDisableSystemAllowedCpuSets
+	ProcessWakeInformation
+	ProcessEnergyTrackingState
+	ProcessManageWritesToExecutableMemory
+	ProcessCaptureTrustletLiveDump
+	ProcessTelemetryCoverage
+	ProcessEnclaveInformation
+	ProcessEnableReadWriteVmLogging
+	ProcessUptimeInformation
+	ProcessImageSection
+	ProcessDebugAuthInformation
+	ProcessSystemResourceManagement
+	ProcessSequenceNumber
+	ProcessLoaderDetour
+	ProcessSecurityDomainInformation
+	ProcessCombineSecurityDomainsInformation
+	ProcessEnableLogging
+	ProcessLeapSecondInformation
+	ProcessFiberShadowStackAllocation
+	ProcessFreeFiberShadowStackAllocation
+	ProcessAltSystemCallInformation
+	ProcessDynamicEHContinuationTargets
+	ProcessDynamicEnforcedCetCompatibleRanges
+)
+
+type PROCESS_BASIC_INFORMATION struct {
+	ExitStatus                   NTStatus
+	PebBaseAddress               *PEB
+	AffinityMask                 uintptr
+	BasePriority                 int32
+	UniqueProcessId              uintptr
+	InheritedFromUniqueProcessId uintptr
+}
+
+// Constants for LocalAlloc flags.
+const (
+	LMEM_FIXED          = 0x0
+	LMEM_MOVEABLE       = 0x2
+	LMEM_NOCOMPACT      = 0x10
+	LMEM_NODISCARD      = 0x20
+	LMEM_ZEROINIT       = 0x40
+	LMEM_MODIFY         = 0x80
+	LMEM_DISCARDABLE    = 0xf00
+	LMEM_VALID_FLAGS    = 0xf72
+	LMEM_INVALID_HANDLE = 0x8000
+	LHND                = LMEM_MOVEABLE | LMEM_ZEROINIT
+	LPTR                = LMEM_FIXED | LMEM_ZEROINIT
+	NONZEROLHND         = LMEM_MOVEABLE
+	NONZEROLPTR         = LMEM_FIXED
+)
+
+// Constants for the CreateNamedPipe-family of functions.
+const (
+	PIPE_ACCESS_INBOUND  = 0x1
+	PIPE_ACCESS_OUTBOUND = 0x2
+	PIPE_ACCESS_DUPLEX   = 0x3
+
+	PIPE_CLIENT_END = 0x0
+	PIPE_SERVER_END = 0x1
+
+	PIPE_WAIT                  = 0x0
+	PIPE_NOWAIT                = 0x1
+	PIPE_READMODE_BYTE         = 0x0
+	PIPE_READMODE_MESSAGE      = 0x2
+	PIPE_TYPE_BYTE             = 0x0
+	PIPE_TYPE_MESSAGE          = 0x4
+	PIPE_ACCEPT_REMOTE_CLIENTS = 0x0
+	PIPE_REJECT_REMOTE_CLIENTS = 0x8
+
+	PIPE_UNLIMITED_INSTANCES = 255
+)
+
+// Constants for security attributes when opening named pipes.
+const (
+	SECURITY_ANONYMOUS      = SecurityAnonymous << 16
+	SECURITY_IDENTIFICATION = SecurityIdentification << 16
+	SECURITY_IMPERSONATION  = SecurityImpersonation << 16
+	SECURITY_DELEGATION     = SecurityDelegation << 16
+
+	SECURITY_CONTEXT_TRACKING = 0x40000
+	SECURITY_EFFECTIVE_ONLY   = 0x80000
+
+	SECURITY_SQOS_PRESENT     = 0x100000
+	SECURITY_VALID_SQOS_FLAGS = 0x1f0000
+)
+
+// ResourceID represents a 16-bit resource identifier, traditionally created with the MAKEINTRESOURCE macro.
+type ResourceID uint16
+
+// ResourceIDOrString must be either a ResourceID, to specify a resource or resource type by ID,
+// or a string, to specify a resource or resource type by name.
+type ResourceIDOrString interface{}
+
+// Predefined resource names and types.
+var (
+	// Predefined names.
+	CREATEPROCESS_MANIFEST_RESOURCE_ID                 ResourceID = 1
+	ISOLATIONAWARE_MANIFEST_RESOURCE_ID                ResourceID = 2
+	ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID ResourceID = 3
+	ISOLATIONPOLICY_MANIFEST_RESOURCE_ID               ResourceID = 4
+	ISOLATIONPOLICY_BROWSER_MANIFEST_RESOURCE_ID       ResourceID = 5
+	MINIMUM_RESERVED_MANIFEST_RESOURCE_ID              ResourceID = 1  // inclusive
+	MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID              ResourceID = 16 // inclusive
+
+	// Predefined types.
+	RT_CURSOR       ResourceID = 1
+	RT_BITMAP       ResourceID = 2
+	RT_ICON         ResourceID = 3
+	RT_MENU         ResourceID = 4
+	RT_DIALOG       ResourceID = 5
+	RT_STRING       ResourceID = 6
+	RT_FONTDIR      ResourceID = 7
+	RT_FONT         ResourceID = 8
+	RT_ACCELERATOR  ResourceID = 9
+	RT_RCDATA       ResourceID = 10
+	RT_MESSAGETABLE ResourceID = 11
+	RT_GROUP_CURSOR ResourceID = 12
+	RT_GROUP_ICON   ResourceID = 14
+	RT_VERSION      ResourceID = 16
+	RT_DLGINCLUDE   ResourceID = 17
+	RT_PLUGPLAY     ResourceID = 19
+	RT_VXD          ResourceID = 20
+	RT_ANICURSOR    ResourceID = 21
+	RT_ANIICON      ResourceID = 22
+	RT_HTML         ResourceID = 23
+	RT_MANIFEST     ResourceID = 24
+)
+
+type COAUTHIDENTITY struct {
+	User           *uint16
+	UserLength     uint32
+	Domain         *uint16
+	DomainLength   uint32
+	Password       *uint16
+	PasswordLength uint32
+	Flags          uint32
+}
+
+type COAUTHINFO struct {
+	AuthnSvc           uint32
+	AuthzSvc           uint32
+	ServerPrincName    *uint16
+	AuthnLevel         uint32
+	ImpersonationLevel uint32
+	AuthIdentityData   *COAUTHIDENTITY
+	Capabilities       uint32
+}
+
+type COSERVERINFO struct {
+	Reserved1 uint32
+	Aame      *uint16
+	AuthInfo  *COAUTHINFO
+	Reserved2 uint32
+}
+
+type BIND_OPTS3 struct {
+	CbStruct          uint32
+	Flags             uint32
+	Mode              uint32
+	TickCountDeadline uint32
+	TrackFlags        uint32
+	ClassContext      uint32
+	Locale            uint32
+	ServerInfo        *COSERVERINFO
+	Hwnd              HWND
+}
+
+const (
+	CLSCTX_INPROC_SERVER          = 0x1
+	CLSCTX_INPROC_HANDLER         = 0x2
+	CLSCTX_LOCAL_SERVER           = 0x4
+	CLSCTX_INPROC_SERVER16        = 0x8
+	CLSCTX_REMOTE_SERVER          = 0x10
+	CLSCTX_INPROC_HANDLER16       = 0x20
+	CLSCTX_RESERVED1              = 0x40
+	CLSCTX_RESERVED2              = 0x80
+	CLSCTX_RESERVED3              = 0x100
+	CLSCTX_RESERVED4              = 0x200
+	CLSCTX_NO_CODE_DOWNLOAD       = 0x400
+	CLSCTX_RESERVED5              = 0x800
+	CLSCTX_NO_CUSTOM_MARSHAL      = 0x1000
+	CLSCTX_ENABLE_CODE_DOWNLOAD   = 0x2000
+	CLSCTX_NO_FAILURE_LOG         = 0x4000
+	CLSCTX_DISABLE_AAA            = 0x8000
+	CLSCTX_ENABLE_AAA             = 0x10000
+	CLSCTX_FROM_DEFAULT_CONTEXT   = 0x20000
+	CLSCTX_ACTIVATE_32_BIT_SERVER = 0x40000
+	CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000
+	CLSCTX_ENABLE_CLOAKING        = 0x100000
+	CLSCTX_APPCONTAINER           = 0x400000
+	CLSCTX_ACTIVATE_AAA_AS_IU     = 0x800000
+	CLSCTX_PS_DLL                 = 0x80000000
+
+	COINIT_MULTITHREADED     = 0x0
+	COINIT_APARTMENTTHREADED = 0x2
+	COINIT_DISABLE_OLE1DDE   = 0x4
+	COINIT_SPEED_OVER_MEMORY = 0x8
+)
+
+// Flag for QueryFullProcessImageName.
+const PROCESS_NAME_NATIVE = 1
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/types_windows_arm64.go b/src/cmd/vendor/golang.org/x/sys/windows/types_windows_arm64.go
new file mode 100644
index 0000000..fdddc0c
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/windows/types_windows_arm64.go
@@ -0,0 +1,34 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+type WSAData struct {
+	Version      uint16
+	HighVersion  uint16
+	MaxSockets   uint16
+	MaxUdpDg     uint16
+	VendorInfo   *byte
+	Description  [WSADESCRIPTION_LEN + 1]byte
+	SystemStatus [WSASYS_STATUS_LEN + 1]byte
+}
+
+type Servent struct {
+	Name    *byte
+	Aliases **byte
+	Proto   *byte
+	Port    uint16
+}
+
+type JOBOBJECT_BASIC_LIMIT_INFORMATION struct {
+	PerProcessUserTimeLimit int64
+	PerJobUserTimeLimit     int64
+	LimitFlags              uint32
+	MinimumWorkingSetSize   uintptr
+	MaximumWorkingSetSize   uintptr
+	ActiveProcessLimit      uint32
+	Affinity                uintptr
+	PriorityClass           uint32
+	SchedulingClass         uint32
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/zerrors_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/zerrors_windows.go
index f021200..0cf658f 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/zerrors_windows.go
+++ b/src/cmd/vendor/golang.org/x/sys/windows/zerrors_windows.go
@@ -146,6 +146,7 @@
 	FACILITY_WEP                                                                            = 2049
 	FACILITY_SYNCENGINE                                                                     = 2050
 	FACILITY_XBOX                                                                           = 2339
+	FACILITY_GAME                                                                           = 2340
 	FACILITY_PIX                                                                            = 2748
 	ERROR_SUCCESS                                                             syscall.Errno = 0
 	NO_ERROR                                                                                = 0
@@ -469,9 +470,18 @@
 	ERROR_STORAGE_RESERVE_NOT_EMPTY                                           syscall.Errno = 419
 	ERROR_NOT_A_DAX_VOLUME                                                    syscall.Errno = 420
 	ERROR_NOT_DAX_MAPPABLE                                                    syscall.Errno = 421
-	ERROR_TIME_CRITICAL_THREAD                                                syscall.Errno = 422
+	ERROR_TIME_SENSITIVE_THREAD                                               syscall.Errno = 422
 	ERROR_DPL_NOT_SUPPORTED_FOR_USER                                          syscall.Errno = 423
 	ERROR_CASE_DIFFERING_NAMES_IN_DIR                                         syscall.Errno = 424
+	ERROR_FILE_NOT_SUPPORTED                                                  syscall.Errno = 425
+	ERROR_CLOUD_FILE_REQUEST_TIMEOUT                                          syscall.Errno = 426
+	ERROR_NO_TASK_QUEUE                                                       syscall.Errno = 427
+	ERROR_SRC_SRV_DLL_LOAD_FAILED                                             syscall.Errno = 428
+	ERROR_NOT_SUPPORTED_WITH_BTT                                              syscall.Errno = 429
+	ERROR_ENCRYPTION_DISABLED                                                 syscall.Errno = 430
+	ERROR_ENCRYPTING_METADATA_DISALLOWED                                      syscall.Errno = 431
+	ERROR_CANT_CLEAR_ENCRYPTION_FLAG                                          syscall.Errno = 432
+	ERROR_NO_SUCH_DEVICE                                                      syscall.Errno = 433
 	ERROR_CAPAUTHZ_NOT_DEVUNLOCKED                                            syscall.Errno = 450
 	ERROR_CAPAUTHZ_CHANGE_TYPE                                                syscall.Errno = 451
 	ERROR_CAPAUTHZ_NOT_PROVISIONED                                            syscall.Errno = 452
@@ -1593,6 +1603,8 @@
 	ERROR_SYSTEM_INTEGRITY_POLICY_VIOLATION                                   syscall.Errno = 4551
 	ERROR_SYSTEM_INTEGRITY_INVALID_POLICY                                     syscall.Errno = 4552
 	ERROR_SYSTEM_INTEGRITY_POLICY_NOT_SIGNED                                  syscall.Errno = 4553
+	ERROR_SYSTEM_INTEGRITY_TOO_MANY_POLICIES                                  syscall.Errno = 4554
+	ERROR_SYSTEM_INTEGRITY_SUPPLEMENTAL_POLICY_NOT_AUTHORIZED                 syscall.Errno = 4555
 	ERROR_VSM_NOT_INITIALIZED                                                 syscall.Errno = 4560
 	ERROR_VSM_DMA_PROTECTION_NOT_IN_USE                                       syscall.Errno = 4561
 	ERROR_PLATFORM_MANIFEST_NOT_AUTHORIZED                                    syscall.Errno = 4570
@@ -1824,6 +1836,7 @@
 	ERROR_CS_ENCRYPTION_NEW_ENCRYPTED_FILE                                    syscall.Errno = 6020
 	ERROR_CS_ENCRYPTION_FILE_NOT_CSE                                          syscall.Errno = 6021
 	ERROR_ENCRYPTION_POLICY_DENIES_OPERATION                                  syscall.Errno = 6022
+	ERROR_WIP_ENCRYPTION_FAILED                                               syscall.Errno = 6023
 	ERROR_NO_BROWSER_SERVERS_FOUND                                            syscall.Errno = 6118
 	SCHED_E_SERVICE_NOT_LOCALSYSTEM                                           syscall.Errno = 6200
 	ERROR_LOG_SECTOR_INVALID                                                  syscall.Errno = 6600
@@ -3000,6 +3013,7 @@
 	ERROR_SMI_PRIMITIVE_INSTALLER_FAILED                                      syscall.Errno = 14108
 	ERROR_GENERIC_COMMAND_FAILED                                              syscall.Errno = 14109
 	ERROR_SXS_FILE_HASH_MISSING                                               syscall.Errno = 14110
+	ERROR_SXS_DUPLICATE_ACTIVATABLE_CLASS                                     syscall.Errno = 14111
 	ERROR_EVT_INVALID_CHANNEL_PATH                                            syscall.Errno = 15000
 	ERROR_EVT_INVALID_QUERY                                                   syscall.Errno = 15001
 	ERROR_EVT_PUBLISHER_METADATA_NOT_FOUND                                    syscall.Errno = 15002
@@ -3093,6 +3107,7 @@
 	ERROR_PRI_MERGE_RESOURCE_PACKAGE_REQUIRED                                 syscall.Errno = 15157
 	ERROR_PRI_MERGE_INVALID_FILE_NAME                                         syscall.Errno = 15158
 	ERROR_MRM_PACKAGE_NOT_FOUND                                               syscall.Errno = 15159
+	ERROR_MRM_MISSING_DEFAULT_LANGUAGE                                        syscall.Errno = 15160
 	ERROR_MCA_INVALID_CAPABILITIES_STRING                                     syscall.Errno = 15200
 	ERROR_MCA_INVALID_VCP_VERSION                                             syscall.Errno = 15201
 	ERROR_MCA_MONITOR_VIOLATES_MCCS_SPECIFICATION                             syscall.Errno = 15202
@@ -3167,6 +3182,15 @@
 	ERROR_DEPLOYMENT_OPTION_NOT_SUPPORTED                                     syscall.Errno = 15645
 	ERROR_APPINSTALLER_ACTIVATION_BLOCKED                                     syscall.Errno = 15646
 	ERROR_REGISTRATION_FROM_REMOTE_DRIVE_NOT_SUPPORTED                        syscall.Errno = 15647
+	ERROR_APPX_RAW_DATA_WRITE_FAILED                                          syscall.Errno = 15648
+	ERROR_DEPLOYMENT_BLOCKED_BY_VOLUME_POLICY_PACKAGE                         syscall.Errno = 15649
+	ERROR_DEPLOYMENT_BLOCKED_BY_VOLUME_POLICY_MACHINE                         syscall.Errno = 15650
+	ERROR_DEPLOYMENT_BLOCKED_BY_PROFILE_POLICY                                syscall.Errno = 15651
+	ERROR_DEPLOYMENT_FAILED_CONFLICTING_MUTABLE_PACKAGE_DIRECTORY             syscall.Errno = 15652
+	ERROR_SINGLETON_RESOURCE_INSTALLED_IN_ACTIVE_USER                         syscall.Errno = 15653
+	ERROR_DIFFERENT_VERSION_OF_PACKAGED_SERVICE_INSTALLED                     syscall.Errno = 15654
+	ERROR_SERVICE_EXISTS_AS_NON_PACKAGED_SERVICE                              syscall.Errno = 15655
+	ERROR_PACKAGED_SERVICE_REQUIRES_ADMIN_PRIVILEGES                          syscall.Errno = 15656
 	APPMODEL_ERROR_NO_PACKAGE                                                 syscall.Errno = 15700
 	APPMODEL_ERROR_PACKAGE_RUNTIME_CORRUPT                                    syscall.Errno = 15701
 	APPMODEL_ERROR_PACKAGE_IDENTITY_CORRUPT                                   syscall.Errno = 15702
@@ -3174,6 +3198,7 @@
 	APPMODEL_ERROR_DYNAMIC_PROPERTY_READ_FAILED                               syscall.Errno = 15704
 	APPMODEL_ERROR_DYNAMIC_PROPERTY_INVALID                                   syscall.Errno = 15705
 	APPMODEL_ERROR_PACKAGE_NOT_AVAILABLE                                      syscall.Errno = 15706
+	APPMODEL_ERROR_NO_MUTABLE_DIRECTORY                                       syscall.Errno = 15707
 	ERROR_STATE_LOAD_STORE_FAILED                                             syscall.Errno = 15800
 	ERROR_STATE_GET_VERSION_FAILED                                            syscall.Errno = 15801
 	ERROR_STATE_SET_VERSION_FAILED                                            syscall.Errno = 15802
@@ -3204,7 +3229,8 @@
 	E_NOT_SET                                                                               = ERROR_NOT_FOUND
 	E_NOT_VALID_STATE                                                                       = ERROR_INVALID_STATE
 	E_NOT_SUFFICIENT_BUFFER                                                                 = ERROR_INSUFFICIENT_BUFFER
-	E_TIME_CRITICAL_THREAD                                                                  = ERROR_TIME_CRITICAL_THREAD
+	E_TIME_SENSITIVE_THREAD                                                                 = ERROR_TIME_SENSITIVE_THREAD
+	E_NO_TASK_QUEUE                                                                         = ERROR_NO_TASK_QUEUE
 	NOERROR                                                                   syscall.Errno = 0
 	E_UNEXPECTED                                                              Handle        = 0x8000FFFF
 	E_NOTIMPL                                                                 Handle        = 0x80004001
@@ -3966,6 +3992,7 @@
 	SEC_I_COMPLETE_NEEDED                                                     Handle        = 0x00090313
 	SEC_I_COMPLETE_AND_CONTINUE                                               Handle        = 0x00090314
 	SEC_I_LOCAL_LOGON                                                         Handle        = 0x00090315
+	SEC_I_GENERIC_EXTENSION_RECEIVED                                          Handle        = 0x00090316
 	SEC_E_BAD_PKGID                                                           Handle        = 0x80090316
 	SEC_E_CONTEXT_EXPIRED                                                     Handle        = 0x80090317
 	SEC_I_CONTEXT_EXPIRED                                                     Handle        = 0x00090317
@@ -4033,6 +4060,8 @@
 	SEC_E_APPLICATION_PROTOCOL_MISMATCH                                       Handle        = 0x80090367
 	SEC_I_ASYNC_CALL_PENDING                                                  Handle        = 0x00090368
 	SEC_E_INVALID_UPN_NAME                                                    Handle        = 0x80090369
+	SEC_E_EXT_BUFFER_TOO_SMALL                                                Handle        = 0x8009036A
+	SEC_E_INSUFFICIENT_BUFFERS                                                Handle        = 0x8009036B
 	SEC_E_NO_SPM                                                                            = SEC_E_INTERNAL_ERROR
 	SEC_E_NOT_SUPPORTED                                                                     = SEC_E_UNSUPPORTED_FUNCTION
 	CRYPT_E_MSG_ERROR                                                         Handle        = 0x80091001
@@ -4637,6 +4666,8 @@
 	ERROR_GRAPHICS_PRESENT_INVALID_WINDOW                                     Handle        = 0xC026200F
 	ERROR_GRAPHICS_PRESENT_BUFFER_NOT_BOUND                                   Handle        = 0xC0262010
 	ERROR_GRAPHICS_VAIL_STATE_CHANGED                                         Handle        = 0xC0262011
+	ERROR_GRAPHICS_INDIRECT_DISPLAY_ABANDON_SWAPCHAIN                         Handle        = 0xC0262012
+	ERROR_GRAPHICS_INDIRECT_DISPLAY_DEVICE_STOPPED                            Handle        = 0xC0262013
 	ERROR_GRAPHICS_NO_VIDEO_MEMORY                                            Handle        = 0xC0262100
 	ERROR_GRAPHICS_CANT_LOCK_MEMORY                                           Handle        = 0xC0262101
 	ERROR_GRAPHICS_ALLOCATION_BUSY                                            Handle        = 0xC0262102
@@ -5393,6 +5424,13 @@
 	FVE_E_NOT_DE_VOLUME                                                       Handle        = 0x803100D7
 	FVE_E_PROTECTION_CANNOT_BE_DISABLED                                       Handle        = 0x803100D8
 	FVE_E_OSV_KSR_NOT_ALLOWED                                                 Handle        = 0x803100D9
+	FVE_E_AD_BACKUP_REQUIRED_POLICY_NOT_SET_OS_DRIVE                          Handle        = 0x803100DA
+	FVE_E_AD_BACKUP_REQUIRED_POLICY_NOT_SET_FIXED_DRIVE                       Handle        = 0x803100DB
+	FVE_E_AD_BACKUP_REQUIRED_POLICY_NOT_SET_REMOVABLE_DRIVE                   Handle        = 0x803100DC
+	FVE_E_KEY_ROTATION_NOT_SUPPORTED                                          Handle        = 0x803100DD
+	FVE_E_EXECUTE_REQUEST_SENT_TOO_SOON                                       Handle        = 0x803100DE
+	FVE_E_KEY_ROTATION_NOT_ENABLED                                            Handle        = 0x803100DF
+	FVE_E_DEVICE_NOT_JOINED                                                   Handle        = 0x803100E0
 	FWP_E_CALLOUT_NOT_FOUND                                                   Handle        = 0x80320001
 	FWP_E_CONDITION_NOT_FOUND                                                 Handle        = 0x80320002
 	FWP_E_FILTER_NOT_FOUND                                                    Handle        = 0x80320003
@@ -5881,6 +5919,12 @@
 	GCN_E_NETCOMPARTMENT_NOT_FOUND                                            Handle        = 0x803B0027
 	GCN_E_NETINTERFACE_NOT_FOUND                                              Handle        = 0x803B0028
 	GCN_E_DEFAULTNAMESPACE_EXISTS                                             Handle        = 0x803B0029
+	HCN_E_ICS_DISABLED                                                        Handle        = 0x803B002A
+	HCN_E_ENDPOINT_NAMESPACE_ALREADY_EXISTS                                   Handle        = 0x803B002B
+	HCN_E_ENTITY_HAS_REFERENCES                                               Handle        = 0x803B002C
+	HCN_E_INVALID_INTERNAL_PORT                                               Handle        = 0x803B002D
+	HCN_E_NAMESPACE_ATTACH_FAILED                                             Handle        = 0x803B002E
+	HCN_E_ADDR_INVALID_OR_RESERVED                                            Handle        = 0x803B002F
 	SDIAG_E_CANCELLED                                                         syscall.Errno = 0x803C0100
 	SDIAG_E_SCRIPT                                                            syscall.Errno = 0x803C0101
 	SDIAG_E_POWERSHELL                                                        syscall.Errno = 0x803C0102
@@ -6846,8 +6890,2579 @@
 	UTC_E_INSUFFICIENT_SPACE_TO_START_TRACE                                   Handle        = 0x87C51059
 	UTC_E_ESCALATION_CANCELLED_AT_SHUTDOWN                                    Handle        = 0x87C5105A
 	UTC_E_GETFILEINFOACTION_FILE_NOT_APPROVED                                 Handle        = 0x87C5105B
+	UTC_E_SETREGKEYACTION_TYPE_NOT_APPROVED                                   Handle        = 0x87C5105C
 	WINML_ERR_INVALID_DEVICE                                                  Handle        = 0x88900001
 	WINML_ERR_INVALID_BINDING                                                 Handle        = 0x88900002
 	WINML_ERR_VALUE_NOTFOUND                                                  Handle        = 0x88900003
 	WINML_ERR_SIZE_MISMATCH                                                   Handle        = 0x88900004
+	STATUS_WAIT_0                                                             NTStatus      = 0x00000000
+	STATUS_SUCCESS                                                            NTStatus      = 0x00000000
+	STATUS_WAIT_1                                                             NTStatus      = 0x00000001
+	STATUS_WAIT_2                                                             NTStatus      = 0x00000002
+	STATUS_WAIT_3                                                             NTStatus      = 0x00000003
+	STATUS_WAIT_63                                                            NTStatus      = 0x0000003F
+	STATUS_ABANDONED                                                          NTStatus      = 0x00000080
+	STATUS_ABANDONED_WAIT_0                                                   NTStatus      = 0x00000080
+	STATUS_ABANDONED_WAIT_63                                                  NTStatus      = 0x000000BF
+	STATUS_USER_APC                                                           NTStatus      = 0x000000C0
+	STATUS_ALREADY_COMPLETE                                                   NTStatus      = 0x000000FF
+	STATUS_KERNEL_APC                                                         NTStatus      = 0x00000100
+	STATUS_ALERTED                                                            NTStatus      = 0x00000101
+	STATUS_TIMEOUT                                                            NTStatus      = 0x00000102
+	STATUS_PENDING                                                            NTStatus      = 0x00000103
+	STATUS_REPARSE                                                            NTStatus      = 0x00000104
+	STATUS_MORE_ENTRIES                                                       NTStatus      = 0x00000105
+	STATUS_NOT_ALL_ASSIGNED                                                   NTStatus      = 0x00000106
+	STATUS_SOME_NOT_MAPPED                                                    NTStatus      = 0x00000107
+	STATUS_OPLOCK_BREAK_IN_PROGRESS                                           NTStatus      = 0x00000108
+	STATUS_VOLUME_MOUNTED                                                     NTStatus      = 0x00000109
+	STATUS_RXACT_COMMITTED                                                    NTStatus      = 0x0000010A
+	STATUS_NOTIFY_CLEANUP                                                     NTStatus      = 0x0000010B
+	STATUS_NOTIFY_ENUM_DIR                                                    NTStatus      = 0x0000010C
+	STATUS_NO_QUOTAS_FOR_ACCOUNT                                              NTStatus      = 0x0000010D
+	STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED                                   NTStatus      = 0x0000010E
+	STATUS_PAGE_FAULT_TRANSITION                                              NTStatus      = 0x00000110
+	STATUS_PAGE_FAULT_DEMAND_ZERO                                             NTStatus      = 0x00000111
+	STATUS_PAGE_FAULT_COPY_ON_WRITE                                           NTStatus      = 0x00000112
+	STATUS_PAGE_FAULT_GUARD_PAGE                                              NTStatus      = 0x00000113
+	STATUS_PAGE_FAULT_PAGING_FILE                                             NTStatus      = 0x00000114
+	STATUS_CACHE_PAGE_LOCKED                                                  NTStatus      = 0x00000115
+	STATUS_CRASH_DUMP                                                         NTStatus      = 0x00000116
+	STATUS_BUFFER_ALL_ZEROS                                                   NTStatus      = 0x00000117
+	STATUS_REPARSE_OBJECT                                                     NTStatus      = 0x00000118
+	STATUS_RESOURCE_REQUIREMENTS_CHANGED                                      NTStatus      = 0x00000119
+	STATUS_TRANSLATION_COMPLETE                                               NTStatus      = 0x00000120
+	STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY                                    NTStatus      = 0x00000121
+	STATUS_NOTHING_TO_TERMINATE                                               NTStatus      = 0x00000122
+	STATUS_PROCESS_NOT_IN_JOB                                                 NTStatus      = 0x00000123
+	STATUS_PROCESS_IN_JOB                                                     NTStatus      = 0x00000124
+	STATUS_VOLSNAP_HIBERNATE_READY                                            NTStatus      = 0x00000125
+	STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY                                 NTStatus      = 0x00000126
+	STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED                                 NTStatus      = 0x00000127
+	STATUS_INTERRUPT_STILL_CONNECTED                                          NTStatus      = 0x00000128
+	STATUS_PROCESS_CLONED                                                     NTStatus      = 0x00000129
+	STATUS_FILE_LOCKED_WITH_ONLY_READERS                                      NTStatus      = 0x0000012A
+	STATUS_FILE_LOCKED_WITH_WRITERS                                           NTStatus      = 0x0000012B
+	STATUS_VALID_IMAGE_HASH                                                   NTStatus      = 0x0000012C
+	STATUS_VALID_CATALOG_HASH                                                 NTStatus      = 0x0000012D
+	STATUS_VALID_STRONG_CODE_HASH                                             NTStatus      = 0x0000012E
+	STATUS_GHOSTED                                                            NTStatus      = 0x0000012F
+	STATUS_DATA_OVERWRITTEN                                                   NTStatus      = 0x00000130
+	STATUS_RESOURCEMANAGER_READ_ONLY                                          NTStatus      = 0x00000202
+	STATUS_RING_PREVIOUSLY_EMPTY                                              NTStatus      = 0x00000210
+	STATUS_RING_PREVIOUSLY_FULL                                               NTStatus      = 0x00000211
+	STATUS_RING_PREVIOUSLY_ABOVE_QUOTA                                        NTStatus      = 0x00000212
+	STATUS_RING_NEWLY_EMPTY                                                   NTStatus      = 0x00000213
+	STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT                                      NTStatus      = 0x00000214
+	STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE                                      NTStatus      = 0x00000215
+	STATUS_OPLOCK_HANDLE_CLOSED                                               NTStatus      = 0x00000216
+	STATUS_WAIT_FOR_OPLOCK                                                    NTStatus      = 0x00000367
+	STATUS_REPARSE_GLOBAL                                                     NTStatus      = 0x00000368
+	STATUS_FLT_IO_COMPLETE                                                    NTStatus      = 0x001C0001
+	STATUS_OBJECT_NAME_EXISTS                                                 NTStatus      = 0x40000000
+	STATUS_THREAD_WAS_SUSPENDED                                               NTStatus      = 0x40000001
+	STATUS_WORKING_SET_LIMIT_RANGE                                            NTStatus      = 0x40000002
+	STATUS_IMAGE_NOT_AT_BASE                                                  NTStatus      = 0x40000003
+	STATUS_RXACT_STATE_CREATED                                                NTStatus      = 0x40000004
+	STATUS_SEGMENT_NOTIFICATION                                               NTStatus      = 0x40000005
+	STATUS_LOCAL_USER_SESSION_KEY                                             NTStatus      = 0x40000006
+	STATUS_BAD_CURRENT_DIRECTORY                                              NTStatus      = 0x40000007
+	STATUS_SERIAL_MORE_WRITES                                                 NTStatus      = 0x40000008
+	STATUS_REGISTRY_RECOVERED                                                 NTStatus      = 0x40000009
+	STATUS_FT_READ_RECOVERY_FROM_BACKUP                                       NTStatus      = 0x4000000A
+	STATUS_FT_WRITE_RECOVERY                                                  NTStatus      = 0x4000000B
+	STATUS_SERIAL_COUNTER_TIMEOUT                                             NTStatus      = 0x4000000C
+	STATUS_NULL_LM_PASSWORD                                                   NTStatus      = 0x4000000D
+	STATUS_IMAGE_MACHINE_TYPE_MISMATCH                                        NTStatus      = 0x4000000E
+	STATUS_RECEIVE_PARTIAL                                                    NTStatus      = 0x4000000F
+	STATUS_RECEIVE_EXPEDITED                                                  NTStatus      = 0x40000010
+	STATUS_RECEIVE_PARTIAL_EXPEDITED                                          NTStatus      = 0x40000011
+	STATUS_EVENT_DONE                                                         NTStatus      = 0x40000012
+	STATUS_EVENT_PENDING                                                      NTStatus      = 0x40000013
+	STATUS_CHECKING_FILE_SYSTEM                                               NTStatus      = 0x40000014
+	STATUS_FATAL_APP_EXIT                                                     NTStatus      = 0x40000015
+	STATUS_PREDEFINED_HANDLE                                                  NTStatus      = 0x40000016
+	STATUS_WAS_UNLOCKED                                                       NTStatus      = 0x40000017
+	STATUS_SERVICE_NOTIFICATION                                               NTStatus      = 0x40000018
+	STATUS_WAS_LOCKED                                                         NTStatus      = 0x40000019
+	STATUS_LOG_HARD_ERROR                                                     NTStatus      = 0x4000001A
+	STATUS_ALREADY_WIN32                                                      NTStatus      = 0x4000001B
+	STATUS_WX86_UNSIMULATE                                                    NTStatus      = 0x4000001C
+	STATUS_WX86_CONTINUE                                                      NTStatus      = 0x4000001D
+	STATUS_WX86_SINGLE_STEP                                                   NTStatus      = 0x4000001E
+	STATUS_WX86_BREAKPOINT                                                    NTStatus      = 0x4000001F
+	STATUS_WX86_EXCEPTION_CONTINUE                                            NTStatus      = 0x40000020
+	STATUS_WX86_EXCEPTION_LASTCHANCE                                          NTStatus      = 0x40000021
+	STATUS_WX86_EXCEPTION_CHAIN                                               NTStatus      = 0x40000022
+	STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE                                    NTStatus      = 0x40000023
+	STATUS_NO_YIELD_PERFORMED                                                 NTStatus      = 0x40000024
+	STATUS_TIMER_RESUME_IGNORED                                               NTStatus      = 0x40000025
+	STATUS_ARBITRATION_UNHANDLED                                              NTStatus      = 0x40000026
+	STATUS_CARDBUS_NOT_SUPPORTED                                              NTStatus      = 0x40000027
+	STATUS_WX86_CREATEWX86TIB                                                 NTStatus      = 0x40000028
+	STATUS_MP_PROCESSOR_MISMATCH                                              NTStatus      = 0x40000029
+	STATUS_HIBERNATED                                                         NTStatus      = 0x4000002A
+	STATUS_RESUME_HIBERNATION                                                 NTStatus      = 0x4000002B
+	STATUS_FIRMWARE_UPDATED                                                   NTStatus      = 0x4000002C
+	STATUS_DRIVERS_LEAKING_LOCKED_PAGES                                       NTStatus      = 0x4000002D
+	STATUS_MESSAGE_RETRIEVED                                                  NTStatus      = 0x4000002E
+	STATUS_SYSTEM_POWERSTATE_TRANSITION                                       NTStatus      = 0x4000002F
+	STATUS_ALPC_CHECK_COMPLETION_LIST                                         NTStatus      = 0x40000030
+	STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION                               NTStatus      = 0x40000031
+	STATUS_ACCESS_AUDIT_BY_POLICY                                             NTStatus      = 0x40000032
+	STATUS_ABANDON_HIBERFILE                                                  NTStatus      = 0x40000033
+	STATUS_BIZRULES_NOT_ENABLED                                               NTStatus      = 0x40000034
+	STATUS_FT_READ_FROM_COPY                                                  NTStatus      = 0x40000035
+	STATUS_IMAGE_AT_DIFFERENT_BASE                                            NTStatus      = 0x40000036
+	STATUS_PATCH_DEFERRED                                                     NTStatus      = 0x40000037
+	STATUS_HEURISTIC_DAMAGE_POSSIBLE                                          NTStatus      = 0x40190001
+	STATUS_GUARD_PAGE_VIOLATION                                               NTStatus      = 0x80000001
+	STATUS_DATATYPE_MISALIGNMENT                                              NTStatus      = 0x80000002
+	STATUS_BREAKPOINT                                                         NTStatus      = 0x80000003
+	STATUS_SINGLE_STEP                                                        NTStatus      = 0x80000004
+	STATUS_BUFFER_OVERFLOW                                                    NTStatus      = 0x80000005
+	STATUS_NO_MORE_FILES                                                      NTStatus      = 0x80000006
+	STATUS_WAKE_SYSTEM_DEBUGGER                                               NTStatus      = 0x80000007
+	STATUS_HANDLES_CLOSED                                                     NTStatus      = 0x8000000A
+	STATUS_NO_INHERITANCE                                                     NTStatus      = 0x8000000B
+	STATUS_GUID_SUBSTITUTION_MADE                                             NTStatus      = 0x8000000C
+	STATUS_PARTIAL_COPY                                                       NTStatus      = 0x8000000D
+	STATUS_DEVICE_PAPER_EMPTY                                                 NTStatus      = 0x8000000E
+	STATUS_DEVICE_POWERED_OFF                                                 NTStatus      = 0x8000000F
+	STATUS_DEVICE_OFF_LINE                                                    NTStatus      = 0x80000010
+	STATUS_DEVICE_BUSY                                                        NTStatus      = 0x80000011
+	STATUS_NO_MORE_EAS                                                        NTStatus      = 0x80000012
+	STATUS_INVALID_EA_NAME                                                    NTStatus      = 0x80000013
+	STATUS_EA_LIST_INCONSISTENT                                               NTStatus      = 0x80000014
+	STATUS_INVALID_EA_FLAG                                                    NTStatus      = 0x80000015
+	STATUS_VERIFY_REQUIRED                                                    NTStatus      = 0x80000016
+	STATUS_EXTRANEOUS_INFORMATION                                             NTStatus      = 0x80000017
+	STATUS_RXACT_COMMIT_NECESSARY                                             NTStatus      = 0x80000018
+	STATUS_NO_MORE_ENTRIES                                                    NTStatus      = 0x8000001A
+	STATUS_FILEMARK_DETECTED                                                  NTStatus      = 0x8000001B
+	STATUS_MEDIA_CHANGED                                                      NTStatus      = 0x8000001C
+	STATUS_BUS_RESET                                                          NTStatus      = 0x8000001D
+	STATUS_END_OF_MEDIA                                                       NTStatus      = 0x8000001E
+	STATUS_BEGINNING_OF_MEDIA                                                 NTStatus      = 0x8000001F
+	STATUS_MEDIA_CHECK                                                        NTStatus      = 0x80000020
+	STATUS_SETMARK_DETECTED                                                   NTStatus      = 0x80000021
+	STATUS_NO_DATA_DETECTED                                                   NTStatus      = 0x80000022
+	STATUS_REDIRECTOR_HAS_OPEN_HANDLES                                        NTStatus      = 0x80000023
+	STATUS_SERVER_HAS_OPEN_HANDLES                                            NTStatus      = 0x80000024
+	STATUS_ALREADY_DISCONNECTED                                               NTStatus      = 0x80000025
+	STATUS_LONGJUMP                                                           NTStatus      = 0x80000026
+	STATUS_CLEANER_CARTRIDGE_INSTALLED                                        NTStatus      = 0x80000027
+	STATUS_PLUGPLAY_QUERY_VETOED                                              NTStatus      = 0x80000028
+	STATUS_UNWIND_CONSOLIDATE                                                 NTStatus      = 0x80000029
+	STATUS_REGISTRY_HIVE_RECOVERED                                            NTStatus      = 0x8000002A
+	STATUS_DLL_MIGHT_BE_INSECURE                                              NTStatus      = 0x8000002B
+	STATUS_DLL_MIGHT_BE_INCOMPATIBLE                                          NTStatus      = 0x8000002C
+	STATUS_STOPPED_ON_SYMLINK                                                 NTStatus      = 0x8000002D
+	STATUS_CANNOT_GRANT_REQUESTED_OPLOCK                                      NTStatus      = 0x8000002E
+	STATUS_NO_ACE_CONDITION                                                   NTStatus      = 0x8000002F
+	STATUS_DEVICE_SUPPORT_IN_PROGRESS                                         NTStatus      = 0x80000030
+	STATUS_DEVICE_POWER_CYCLE_REQUIRED                                        NTStatus      = 0x80000031
+	STATUS_NO_WORK_DONE                                                       NTStatus      = 0x80000032
+	STATUS_CLUSTER_NODE_ALREADY_UP                                            NTStatus      = 0x80130001
+	STATUS_CLUSTER_NODE_ALREADY_DOWN                                          NTStatus      = 0x80130002
+	STATUS_CLUSTER_NETWORK_ALREADY_ONLINE                                     NTStatus      = 0x80130003
+	STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE                                    NTStatus      = 0x80130004
+	STATUS_CLUSTER_NODE_ALREADY_MEMBER                                        NTStatus      = 0x80130005
+	STATUS_FLT_BUFFER_TOO_SMALL                                               NTStatus      = 0x801C0001
+	STATUS_FVE_PARTIAL_METADATA                                               NTStatus      = 0x80210001
+	STATUS_FVE_TRANSIENT_STATE                                                NTStatus      = 0x80210002
+	STATUS_CLOUD_FILE_PROPERTY_BLOB_CHECKSUM_MISMATCH                         NTStatus      = 0x8000CF00
+	STATUS_UNSUCCESSFUL                                                       NTStatus      = 0xC0000001
+	STATUS_NOT_IMPLEMENTED                                                    NTStatus      = 0xC0000002
+	STATUS_INVALID_INFO_CLASS                                                 NTStatus      = 0xC0000003
+	STATUS_INFO_LENGTH_MISMATCH                                               NTStatus      = 0xC0000004
+	STATUS_ACCESS_VIOLATION                                                   NTStatus      = 0xC0000005
+	STATUS_IN_PAGE_ERROR                                                      NTStatus      = 0xC0000006
+	STATUS_PAGEFILE_QUOTA                                                     NTStatus      = 0xC0000007
+	STATUS_INVALID_HANDLE                                                     NTStatus      = 0xC0000008
+	STATUS_BAD_INITIAL_STACK                                                  NTStatus      = 0xC0000009
+	STATUS_BAD_INITIAL_PC                                                     NTStatus      = 0xC000000A
+	STATUS_INVALID_CID                                                        NTStatus      = 0xC000000B
+	STATUS_TIMER_NOT_CANCELED                                                 NTStatus      = 0xC000000C
+	STATUS_INVALID_PARAMETER                                                  NTStatus      = 0xC000000D
+	STATUS_NO_SUCH_DEVICE                                                     NTStatus      = 0xC000000E
+	STATUS_NO_SUCH_FILE                                                       NTStatus      = 0xC000000F
+	STATUS_INVALID_DEVICE_REQUEST                                             NTStatus      = 0xC0000010
+	STATUS_END_OF_FILE                                                        NTStatus      = 0xC0000011
+	STATUS_WRONG_VOLUME                                                       NTStatus      = 0xC0000012
+	STATUS_NO_MEDIA_IN_DEVICE                                                 NTStatus      = 0xC0000013
+	STATUS_UNRECOGNIZED_MEDIA                                                 NTStatus      = 0xC0000014
+	STATUS_NONEXISTENT_SECTOR                                                 NTStatus      = 0xC0000015
+	STATUS_MORE_PROCESSING_REQUIRED                                           NTStatus      = 0xC0000016
+	STATUS_NO_MEMORY                                                          NTStatus      = 0xC0000017
+	STATUS_CONFLICTING_ADDRESSES                                              NTStatus      = 0xC0000018
+	STATUS_NOT_MAPPED_VIEW                                                    NTStatus      = 0xC0000019
+	STATUS_UNABLE_TO_FREE_VM                                                  NTStatus      = 0xC000001A
+	STATUS_UNABLE_TO_DELETE_SECTION                                           NTStatus      = 0xC000001B
+	STATUS_INVALID_SYSTEM_SERVICE                                             NTStatus      = 0xC000001C
+	STATUS_ILLEGAL_INSTRUCTION                                                NTStatus      = 0xC000001D
+	STATUS_INVALID_LOCK_SEQUENCE                                              NTStatus      = 0xC000001E
+	STATUS_INVALID_VIEW_SIZE                                                  NTStatus      = 0xC000001F
+	STATUS_INVALID_FILE_FOR_SECTION                                           NTStatus      = 0xC0000020
+	STATUS_ALREADY_COMMITTED                                                  NTStatus      = 0xC0000021
+	STATUS_ACCESS_DENIED                                                      NTStatus      = 0xC0000022
+	STATUS_BUFFER_TOO_SMALL                                                   NTStatus      = 0xC0000023
+	STATUS_OBJECT_TYPE_MISMATCH                                               NTStatus      = 0xC0000024
+	STATUS_NONCONTINUABLE_EXCEPTION                                           NTStatus      = 0xC0000025
+	STATUS_INVALID_DISPOSITION                                                NTStatus      = 0xC0000026
+	STATUS_UNWIND                                                             NTStatus      = 0xC0000027
+	STATUS_BAD_STACK                                                          NTStatus      = 0xC0000028
+	STATUS_INVALID_UNWIND_TARGET                                              NTStatus      = 0xC0000029
+	STATUS_NOT_LOCKED                                                         NTStatus      = 0xC000002A
+	STATUS_PARITY_ERROR                                                       NTStatus      = 0xC000002B
+	STATUS_UNABLE_TO_DECOMMIT_VM                                              NTStatus      = 0xC000002C
+	STATUS_NOT_COMMITTED                                                      NTStatus      = 0xC000002D
+	STATUS_INVALID_PORT_ATTRIBUTES                                            NTStatus      = 0xC000002E
+	STATUS_PORT_MESSAGE_TOO_LONG                                              NTStatus      = 0xC000002F
+	STATUS_INVALID_PARAMETER_MIX                                              NTStatus      = 0xC0000030
+	STATUS_INVALID_QUOTA_LOWER                                                NTStatus      = 0xC0000031
+	STATUS_DISK_CORRUPT_ERROR                                                 NTStatus      = 0xC0000032
+	STATUS_OBJECT_NAME_INVALID                                                NTStatus      = 0xC0000033
+	STATUS_OBJECT_NAME_NOT_FOUND                                              NTStatus      = 0xC0000034
+	STATUS_OBJECT_NAME_COLLISION                                              NTStatus      = 0xC0000035
+	STATUS_PORT_DO_NOT_DISTURB                                                NTStatus      = 0xC0000036
+	STATUS_PORT_DISCONNECTED                                                  NTStatus      = 0xC0000037
+	STATUS_DEVICE_ALREADY_ATTACHED                                            NTStatus      = 0xC0000038
+	STATUS_OBJECT_PATH_INVALID                                                NTStatus      = 0xC0000039
+	STATUS_OBJECT_PATH_NOT_FOUND                                              NTStatus      = 0xC000003A
+	STATUS_OBJECT_PATH_SYNTAX_BAD                                             NTStatus      = 0xC000003B
+	STATUS_DATA_OVERRUN                                                       NTStatus      = 0xC000003C
+	STATUS_DATA_LATE_ERROR                                                    NTStatus      = 0xC000003D
+	STATUS_DATA_ERROR                                                         NTStatus      = 0xC000003E
+	STATUS_CRC_ERROR                                                          NTStatus      = 0xC000003F
+	STATUS_SECTION_TOO_BIG                                                    NTStatus      = 0xC0000040
+	STATUS_PORT_CONNECTION_REFUSED                                            NTStatus      = 0xC0000041
+	STATUS_INVALID_PORT_HANDLE                                                NTStatus      = 0xC0000042
+	STATUS_SHARING_VIOLATION                                                  NTStatus      = 0xC0000043
+	STATUS_QUOTA_EXCEEDED                                                     NTStatus      = 0xC0000044
+	STATUS_INVALID_PAGE_PROTECTION                                            NTStatus      = 0xC0000045
+	STATUS_MUTANT_NOT_OWNED                                                   NTStatus      = 0xC0000046
+	STATUS_SEMAPHORE_LIMIT_EXCEEDED                                           NTStatus      = 0xC0000047
+	STATUS_PORT_ALREADY_SET                                                   NTStatus      = 0xC0000048
+	STATUS_SECTION_NOT_IMAGE                                                  NTStatus      = 0xC0000049
+	STATUS_SUSPEND_COUNT_EXCEEDED                                             NTStatus      = 0xC000004A
+	STATUS_THREAD_IS_TERMINATING                                              NTStatus      = 0xC000004B
+	STATUS_BAD_WORKING_SET_LIMIT                                              NTStatus      = 0xC000004C
+	STATUS_INCOMPATIBLE_FILE_MAP                                              NTStatus      = 0xC000004D
+	STATUS_SECTION_PROTECTION                                                 NTStatus      = 0xC000004E
+	STATUS_EAS_NOT_SUPPORTED                                                  NTStatus      = 0xC000004F
+	STATUS_EA_TOO_LARGE                                                       NTStatus      = 0xC0000050
+	STATUS_NONEXISTENT_EA_ENTRY                                               NTStatus      = 0xC0000051
+	STATUS_NO_EAS_ON_FILE                                                     NTStatus      = 0xC0000052
+	STATUS_EA_CORRUPT_ERROR                                                   NTStatus      = 0xC0000053
+	STATUS_FILE_LOCK_CONFLICT                                                 NTStatus      = 0xC0000054
+	STATUS_LOCK_NOT_GRANTED                                                   NTStatus      = 0xC0000055
+	STATUS_DELETE_PENDING                                                     NTStatus      = 0xC0000056
+	STATUS_CTL_FILE_NOT_SUPPORTED                                             NTStatus      = 0xC0000057
+	STATUS_UNKNOWN_REVISION                                                   NTStatus      = 0xC0000058
+	STATUS_REVISION_MISMATCH                                                  NTStatus      = 0xC0000059
+	STATUS_INVALID_OWNER                                                      NTStatus      = 0xC000005A
+	STATUS_INVALID_PRIMARY_GROUP                                              NTStatus      = 0xC000005B
+	STATUS_NO_IMPERSONATION_TOKEN                                             NTStatus      = 0xC000005C
+	STATUS_CANT_DISABLE_MANDATORY                                             NTStatus      = 0xC000005D
+	STATUS_NO_LOGON_SERVERS                                                   NTStatus      = 0xC000005E
+	STATUS_NO_SUCH_LOGON_SESSION                                              NTStatus      = 0xC000005F
+	STATUS_NO_SUCH_PRIVILEGE                                                  NTStatus      = 0xC0000060
+	STATUS_PRIVILEGE_NOT_HELD                                                 NTStatus      = 0xC0000061
+	STATUS_INVALID_ACCOUNT_NAME                                               NTStatus      = 0xC0000062
+	STATUS_USER_EXISTS                                                        NTStatus      = 0xC0000063
+	STATUS_NO_SUCH_USER                                                       NTStatus      = 0xC0000064
+	STATUS_GROUP_EXISTS                                                       NTStatus      = 0xC0000065
+	STATUS_NO_SUCH_GROUP                                                      NTStatus      = 0xC0000066
+	STATUS_MEMBER_IN_GROUP                                                    NTStatus      = 0xC0000067
+	STATUS_MEMBER_NOT_IN_GROUP                                                NTStatus      = 0xC0000068
+	STATUS_LAST_ADMIN                                                         NTStatus      = 0xC0000069
+	STATUS_WRONG_PASSWORD                                                     NTStatus      = 0xC000006A
+	STATUS_ILL_FORMED_PASSWORD                                                NTStatus      = 0xC000006B
+	STATUS_PASSWORD_RESTRICTION                                               NTStatus      = 0xC000006C
+	STATUS_LOGON_FAILURE                                                      NTStatus      = 0xC000006D
+	STATUS_ACCOUNT_RESTRICTION                                                NTStatus      = 0xC000006E
+	STATUS_INVALID_LOGON_HOURS                                                NTStatus      = 0xC000006F
+	STATUS_INVALID_WORKSTATION                                                NTStatus      = 0xC0000070
+	STATUS_PASSWORD_EXPIRED                                                   NTStatus      = 0xC0000071
+	STATUS_ACCOUNT_DISABLED                                                   NTStatus      = 0xC0000072
+	STATUS_NONE_MAPPED                                                        NTStatus      = 0xC0000073
+	STATUS_TOO_MANY_LUIDS_REQUESTED                                           NTStatus      = 0xC0000074
+	STATUS_LUIDS_EXHAUSTED                                                    NTStatus      = 0xC0000075
+	STATUS_INVALID_SUB_AUTHORITY                                              NTStatus      = 0xC0000076
+	STATUS_INVALID_ACL                                                        NTStatus      = 0xC0000077
+	STATUS_INVALID_SID                                                        NTStatus      = 0xC0000078
+	STATUS_INVALID_SECURITY_DESCR                                             NTStatus      = 0xC0000079
+	STATUS_PROCEDURE_NOT_FOUND                                                NTStatus      = 0xC000007A
+	STATUS_INVALID_IMAGE_FORMAT                                               NTStatus      = 0xC000007B
+	STATUS_NO_TOKEN                                                           NTStatus      = 0xC000007C
+	STATUS_BAD_INHERITANCE_ACL                                                NTStatus      = 0xC000007D
+	STATUS_RANGE_NOT_LOCKED                                                   NTStatus      = 0xC000007E
+	STATUS_DISK_FULL                                                          NTStatus      = 0xC000007F
+	STATUS_SERVER_DISABLED                                                    NTStatus      = 0xC0000080
+	STATUS_SERVER_NOT_DISABLED                                                NTStatus      = 0xC0000081
+	STATUS_TOO_MANY_GUIDS_REQUESTED                                           NTStatus      = 0xC0000082
+	STATUS_GUIDS_EXHAUSTED                                                    NTStatus      = 0xC0000083
+	STATUS_INVALID_ID_AUTHORITY                                               NTStatus      = 0xC0000084
+	STATUS_AGENTS_EXHAUSTED                                                   NTStatus      = 0xC0000085
+	STATUS_INVALID_VOLUME_LABEL                                               NTStatus      = 0xC0000086
+	STATUS_SECTION_NOT_EXTENDED                                               NTStatus      = 0xC0000087
+	STATUS_NOT_MAPPED_DATA                                                    NTStatus      = 0xC0000088
+	STATUS_RESOURCE_DATA_NOT_FOUND                                            NTStatus      = 0xC0000089
+	STATUS_RESOURCE_TYPE_NOT_FOUND                                            NTStatus      = 0xC000008A
+	STATUS_RESOURCE_NAME_NOT_FOUND                                            NTStatus      = 0xC000008B
+	STATUS_ARRAY_BOUNDS_EXCEEDED                                              NTStatus      = 0xC000008C
+	STATUS_FLOAT_DENORMAL_OPERAND                                             NTStatus      = 0xC000008D
+	STATUS_FLOAT_DIVIDE_BY_ZERO                                               NTStatus      = 0xC000008E
+	STATUS_FLOAT_INEXACT_RESULT                                               NTStatus      = 0xC000008F
+	STATUS_FLOAT_INVALID_OPERATION                                            NTStatus      = 0xC0000090
+	STATUS_FLOAT_OVERFLOW                                                     NTStatus      = 0xC0000091
+	STATUS_FLOAT_STACK_CHECK                                                  NTStatus      = 0xC0000092
+	STATUS_FLOAT_UNDERFLOW                                                    NTStatus      = 0xC0000093
+	STATUS_INTEGER_DIVIDE_BY_ZERO                                             NTStatus      = 0xC0000094
+	STATUS_INTEGER_OVERFLOW                                                   NTStatus      = 0xC0000095
+	STATUS_PRIVILEGED_INSTRUCTION                                             NTStatus      = 0xC0000096
+	STATUS_TOO_MANY_PAGING_FILES                                              NTStatus      = 0xC0000097
+	STATUS_FILE_INVALID                                                       NTStatus      = 0xC0000098
+	STATUS_ALLOTTED_SPACE_EXCEEDED                                            NTStatus      = 0xC0000099
+	STATUS_INSUFFICIENT_RESOURCES                                             NTStatus      = 0xC000009A
+	STATUS_DFS_EXIT_PATH_FOUND                                                NTStatus      = 0xC000009B
+	STATUS_DEVICE_DATA_ERROR                                                  NTStatus      = 0xC000009C
+	STATUS_DEVICE_NOT_CONNECTED                                               NTStatus      = 0xC000009D
+	STATUS_DEVICE_POWER_FAILURE                                               NTStatus      = 0xC000009E
+	STATUS_FREE_VM_NOT_AT_BASE                                                NTStatus      = 0xC000009F
+	STATUS_MEMORY_NOT_ALLOCATED                                               NTStatus      = 0xC00000A0
+	STATUS_WORKING_SET_QUOTA                                                  NTStatus      = 0xC00000A1
+	STATUS_MEDIA_WRITE_PROTECTED                                              NTStatus      = 0xC00000A2
+	STATUS_DEVICE_NOT_READY                                                   NTStatus      = 0xC00000A3
+	STATUS_INVALID_GROUP_ATTRIBUTES                                           NTStatus      = 0xC00000A4
+	STATUS_BAD_IMPERSONATION_LEVEL                                            NTStatus      = 0xC00000A5
+	STATUS_CANT_OPEN_ANONYMOUS                                                NTStatus      = 0xC00000A6
+	STATUS_BAD_VALIDATION_CLASS                                               NTStatus      = 0xC00000A7
+	STATUS_BAD_TOKEN_TYPE                                                     NTStatus      = 0xC00000A8
+	STATUS_BAD_MASTER_BOOT_RECORD                                             NTStatus      = 0xC00000A9
+	STATUS_INSTRUCTION_MISALIGNMENT                                           NTStatus      = 0xC00000AA
+	STATUS_INSTANCE_NOT_AVAILABLE                                             NTStatus      = 0xC00000AB
+	STATUS_PIPE_NOT_AVAILABLE                                                 NTStatus      = 0xC00000AC
+	STATUS_INVALID_PIPE_STATE                                                 NTStatus      = 0xC00000AD
+	STATUS_PIPE_BUSY                                                          NTStatus      = 0xC00000AE
+	STATUS_ILLEGAL_FUNCTION                                                   NTStatus      = 0xC00000AF
+	STATUS_PIPE_DISCONNECTED                                                  NTStatus      = 0xC00000B0
+	STATUS_PIPE_CLOSING                                                       NTStatus      = 0xC00000B1
+	STATUS_PIPE_CONNECTED                                                     NTStatus      = 0xC00000B2
+	STATUS_PIPE_LISTENING                                                     NTStatus      = 0xC00000B3
+	STATUS_INVALID_READ_MODE                                                  NTStatus      = 0xC00000B4
+	STATUS_IO_TIMEOUT                                                         NTStatus      = 0xC00000B5
+	STATUS_FILE_FORCED_CLOSED                                                 NTStatus      = 0xC00000B6
+	STATUS_PROFILING_NOT_STARTED                                              NTStatus      = 0xC00000B7
+	STATUS_PROFILING_NOT_STOPPED                                              NTStatus      = 0xC00000B8
+	STATUS_COULD_NOT_INTERPRET                                                NTStatus      = 0xC00000B9
+	STATUS_FILE_IS_A_DIRECTORY                                                NTStatus      = 0xC00000BA
+	STATUS_NOT_SUPPORTED                                                      NTStatus      = 0xC00000BB
+	STATUS_REMOTE_NOT_LISTENING                                               NTStatus      = 0xC00000BC
+	STATUS_DUPLICATE_NAME                                                     NTStatus      = 0xC00000BD
+	STATUS_BAD_NETWORK_PATH                                                   NTStatus      = 0xC00000BE
+	STATUS_NETWORK_BUSY                                                       NTStatus      = 0xC00000BF
+	STATUS_DEVICE_DOES_NOT_EXIST                                              NTStatus      = 0xC00000C0
+	STATUS_TOO_MANY_COMMANDS                                                  NTStatus      = 0xC00000C1
+	STATUS_ADAPTER_HARDWARE_ERROR                                             NTStatus      = 0xC00000C2
+	STATUS_INVALID_NETWORK_RESPONSE                                           NTStatus      = 0xC00000C3
+	STATUS_UNEXPECTED_NETWORK_ERROR                                           NTStatus      = 0xC00000C4
+	STATUS_BAD_REMOTE_ADAPTER                                                 NTStatus      = 0xC00000C5
+	STATUS_PRINT_QUEUE_FULL                                                   NTStatus      = 0xC00000C6
+	STATUS_NO_SPOOL_SPACE                                                     NTStatus      = 0xC00000C7
+	STATUS_PRINT_CANCELLED                                                    NTStatus      = 0xC00000C8
+	STATUS_NETWORK_NAME_DELETED                                               NTStatus      = 0xC00000C9
+	STATUS_NETWORK_ACCESS_DENIED                                              NTStatus      = 0xC00000CA
+	STATUS_BAD_DEVICE_TYPE                                                    NTStatus      = 0xC00000CB
+	STATUS_BAD_NETWORK_NAME                                                   NTStatus      = 0xC00000CC
+	STATUS_TOO_MANY_NAMES                                                     NTStatus      = 0xC00000CD
+	STATUS_TOO_MANY_SESSIONS                                                  NTStatus      = 0xC00000CE
+	STATUS_SHARING_PAUSED                                                     NTStatus      = 0xC00000CF
+	STATUS_REQUEST_NOT_ACCEPTED                                               NTStatus      = 0xC00000D0
+	STATUS_REDIRECTOR_PAUSED                                                  NTStatus      = 0xC00000D1
+	STATUS_NET_WRITE_FAULT                                                    NTStatus      = 0xC00000D2
+	STATUS_PROFILING_AT_LIMIT                                                 NTStatus      = 0xC00000D3
+	STATUS_NOT_SAME_DEVICE                                                    NTStatus      = 0xC00000D4
+	STATUS_FILE_RENAMED                                                       NTStatus      = 0xC00000D5
+	STATUS_VIRTUAL_CIRCUIT_CLOSED                                             NTStatus      = 0xC00000D6
+	STATUS_NO_SECURITY_ON_OBJECT                                              NTStatus      = 0xC00000D7
+	STATUS_CANT_WAIT                                                          NTStatus      = 0xC00000D8
+	STATUS_PIPE_EMPTY                                                         NTStatus      = 0xC00000D9
+	STATUS_CANT_ACCESS_DOMAIN_INFO                                            NTStatus      = 0xC00000DA
+	STATUS_CANT_TERMINATE_SELF                                                NTStatus      = 0xC00000DB
+	STATUS_INVALID_SERVER_STATE                                               NTStatus      = 0xC00000DC
+	STATUS_INVALID_DOMAIN_STATE                                               NTStatus      = 0xC00000DD
+	STATUS_INVALID_DOMAIN_ROLE                                                NTStatus      = 0xC00000DE
+	STATUS_NO_SUCH_DOMAIN                                                     NTStatus      = 0xC00000DF
+	STATUS_DOMAIN_EXISTS                                                      NTStatus      = 0xC00000E0
+	STATUS_DOMAIN_LIMIT_EXCEEDED                                              NTStatus      = 0xC00000E1
+	STATUS_OPLOCK_NOT_GRANTED                                                 NTStatus      = 0xC00000E2
+	STATUS_INVALID_OPLOCK_PROTOCOL                                            NTStatus      = 0xC00000E3
+	STATUS_INTERNAL_DB_CORRUPTION                                             NTStatus      = 0xC00000E4
+	STATUS_INTERNAL_ERROR                                                     NTStatus      = 0xC00000E5
+	STATUS_GENERIC_NOT_MAPPED                                                 NTStatus      = 0xC00000E6
+	STATUS_BAD_DESCRIPTOR_FORMAT                                              NTStatus      = 0xC00000E7
+	STATUS_INVALID_USER_BUFFER                                                NTStatus      = 0xC00000E8
+	STATUS_UNEXPECTED_IO_ERROR                                                NTStatus      = 0xC00000E9
+	STATUS_UNEXPECTED_MM_CREATE_ERR                                           NTStatus      = 0xC00000EA
+	STATUS_UNEXPECTED_MM_MAP_ERROR                                            NTStatus      = 0xC00000EB
+	STATUS_UNEXPECTED_MM_EXTEND_ERR                                           NTStatus      = 0xC00000EC
+	STATUS_NOT_LOGON_PROCESS                                                  NTStatus      = 0xC00000ED
+	STATUS_LOGON_SESSION_EXISTS                                               NTStatus      = 0xC00000EE
+	STATUS_INVALID_PARAMETER_1                                                NTStatus      = 0xC00000EF
+	STATUS_INVALID_PARAMETER_2                                                NTStatus      = 0xC00000F0
+	STATUS_INVALID_PARAMETER_3                                                NTStatus      = 0xC00000F1
+	STATUS_INVALID_PARAMETER_4                                                NTStatus      = 0xC00000F2
+	STATUS_INVALID_PARAMETER_5                                                NTStatus      = 0xC00000F3
+	STATUS_INVALID_PARAMETER_6                                                NTStatus      = 0xC00000F4
+	STATUS_INVALID_PARAMETER_7                                                NTStatus      = 0xC00000F5
+	STATUS_INVALID_PARAMETER_8                                                NTStatus      = 0xC00000F6
+	STATUS_INVALID_PARAMETER_9                                                NTStatus      = 0xC00000F7
+	STATUS_INVALID_PARAMETER_10                                               NTStatus      = 0xC00000F8
+	STATUS_INVALID_PARAMETER_11                                               NTStatus      = 0xC00000F9
+	STATUS_INVALID_PARAMETER_12                                               NTStatus      = 0xC00000FA
+	STATUS_REDIRECTOR_NOT_STARTED                                             NTStatus      = 0xC00000FB
+	STATUS_REDIRECTOR_STARTED                                                 NTStatus      = 0xC00000FC
+	STATUS_STACK_OVERFLOW                                                     NTStatus      = 0xC00000FD
+	STATUS_NO_SUCH_PACKAGE                                                    NTStatus      = 0xC00000FE
+	STATUS_BAD_FUNCTION_TABLE                                                 NTStatus      = 0xC00000FF
+	STATUS_VARIABLE_NOT_FOUND                                                 NTStatus      = 0xC0000100
+	STATUS_DIRECTORY_NOT_EMPTY                                                NTStatus      = 0xC0000101
+	STATUS_FILE_CORRUPT_ERROR                                                 NTStatus      = 0xC0000102
+	STATUS_NOT_A_DIRECTORY                                                    NTStatus      = 0xC0000103
+	STATUS_BAD_LOGON_SESSION_STATE                                            NTStatus      = 0xC0000104
+	STATUS_LOGON_SESSION_COLLISION                                            NTStatus      = 0xC0000105
+	STATUS_NAME_TOO_LONG                                                      NTStatus      = 0xC0000106
+	STATUS_FILES_OPEN                                                         NTStatus      = 0xC0000107
+	STATUS_CONNECTION_IN_USE                                                  NTStatus      = 0xC0000108
+	STATUS_MESSAGE_NOT_FOUND                                                  NTStatus      = 0xC0000109
+	STATUS_PROCESS_IS_TERMINATING                                             NTStatus      = 0xC000010A
+	STATUS_INVALID_LOGON_TYPE                                                 NTStatus      = 0xC000010B
+	STATUS_NO_GUID_TRANSLATION                                                NTStatus      = 0xC000010C
+	STATUS_CANNOT_IMPERSONATE                                                 NTStatus      = 0xC000010D
+	STATUS_IMAGE_ALREADY_LOADED                                               NTStatus      = 0xC000010E
+	STATUS_ABIOS_NOT_PRESENT                                                  NTStatus      = 0xC000010F
+	STATUS_ABIOS_LID_NOT_EXIST                                                NTStatus      = 0xC0000110
+	STATUS_ABIOS_LID_ALREADY_OWNED                                            NTStatus      = 0xC0000111
+	STATUS_ABIOS_NOT_LID_OWNER                                                NTStatus      = 0xC0000112
+	STATUS_ABIOS_INVALID_COMMAND                                              NTStatus      = 0xC0000113
+	STATUS_ABIOS_INVALID_LID                                                  NTStatus      = 0xC0000114
+	STATUS_ABIOS_SELECTOR_NOT_AVAILABLE                                       NTStatus      = 0xC0000115
+	STATUS_ABIOS_INVALID_SELECTOR                                             NTStatus      = 0xC0000116
+	STATUS_NO_LDT                                                             NTStatus      = 0xC0000117
+	STATUS_INVALID_LDT_SIZE                                                   NTStatus      = 0xC0000118
+	STATUS_INVALID_LDT_OFFSET                                                 NTStatus      = 0xC0000119
+	STATUS_INVALID_LDT_DESCRIPTOR                                             NTStatus      = 0xC000011A
+	STATUS_INVALID_IMAGE_NE_FORMAT                                            NTStatus      = 0xC000011B
+	STATUS_RXACT_INVALID_STATE                                                NTStatus      = 0xC000011C
+	STATUS_RXACT_COMMIT_FAILURE                                               NTStatus      = 0xC000011D
+	STATUS_MAPPED_FILE_SIZE_ZERO                                              NTStatus      = 0xC000011E
+	STATUS_TOO_MANY_OPENED_FILES                                              NTStatus      = 0xC000011F
+	STATUS_CANCELLED                                                          NTStatus      = 0xC0000120
+	STATUS_CANNOT_DELETE                                                      NTStatus      = 0xC0000121
+	STATUS_INVALID_COMPUTER_NAME                                              NTStatus      = 0xC0000122
+	STATUS_FILE_DELETED                                                       NTStatus      = 0xC0000123
+	STATUS_SPECIAL_ACCOUNT                                                    NTStatus      = 0xC0000124
+	STATUS_SPECIAL_GROUP                                                      NTStatus      = 0xC0000125
+	STATUS_SPECIAL_USER                                                       NTStatus      = 0xC0000126
+	STATUS_MEMBERS_PRIMARY_GROUP                                              NTStatus      = 0xC0000127
+	STATUS_FILE_CLOSED                                                        NTStatus      = 0xC0000128
+	STATUS_TOO_MANY_THREADS                                                   NTStatus      = 0xC0000129
+	STATUS_THREAD_NOT_IN_PROCESS                                              NTStatus      = 0xC000012A
+	STATUS_TOKEN_ALREADY_IN_USE                                               NTStatus      = 0xC000012B
+	STATUS_PAGEFILE_QUOTA_EXCEEDED                                            NTStatus      = 0xC000012C
+	STATUS_COMMITMENT_LIMIT                                                   NTStatus      = 0xC000012D
+	STATUS_INVALID_IMAGE_LE_FORMAT                                            NTStatus      = 0xC000012E
+	STATUS_INVALID_IMAGE_NOT_MZ                                               NTStatus      = 0xC000012F
+	STATUS_INVALID_IMAGE_PROTECT                                              NTStatus      = 0xC0000130
+	STATUS_INVALID_IMAGE_WIN_16                                               NTStatus      = 0xC0000131
+	STATUS_LOGON_SERVER_CONFLICT                                              NTStatus      = 0xC0000132
+	STATUS_TIME_DIFFERENCE_AT_DC                                              NTStatus      = 0xC0000133
+	STATUS_SYNCHRONIZATION_REQUIRED                                           NTStatus      = 0xC0000134
+	STATUS_DLL_NOT_FOUND                                                      NTStatus      = 0xC0000135
+	STATUS_OPEN_FAILED                                                        NTStatus      = 0xC0000136
+	STATUS_IO_PRIVILEGE_FAILED                                                NTStatus      = 0xC0000137
+	STATUS_ORDINAL_NOT_FOUND                                                  NTStatus      = 0xC0000138
+	STATUS_ENTRYPOINT_NOT_FOUND                                               NTStatus      = 0xC0000139
+	STATUS_CONTROL_C_EXIT                                                     NTStatus      = 0xC000013A
+	STATUS_LOCAL_DISCONNECT                                                   NTStatus      = 0xC000013B
+	STATUS_REMOTE_DISCONNECT                                                  NTStatus      = 0xC000013C
+	STATUS_REMOTE_RESOURCES                                                   NTStatus      = 0xC000013D
+	STATUS_LINK_FAILED                                                        NTStatus      = 0xC000013E
+	STATUS_LINK_TIMEOUT                                                       NTStatus      = 0xC000013F
+	STATUS_INVALID_CONNECTION                                                 NTStatus      = 0xC0000140
+	STATUS_INVALID_ADDRESS                                                    NTStatus      = 0xC0000141
+	STATUS_DLL_INIT_FAILED                                                    NTStatus      = 0xC0000142
+	STATUS_MISSING_SYSTEMFILE                                                 NTStatus      = 0xC0000143
+	STATUS_UNHANDLED_EXCEPTION                                                NTStatus      = 0xC0000144
+	STATUS_APP_INIT_FAILURE                                                   NTStatus      = 0xC0000145
+	STATUS_PAGEFILE_CREATE_FAILED                                             NTStatus      = 0xC0000146
+	STATUS_NO_PAGEFILE                                                        NTStatus      = 0xC0000147
+	STATUS_INVALID_LEVEL                                                      NTStatus      = 0xC0000148
+	STATUS_WRONG_PASSWORD_CORE                                                NTStatus      = 0xC0000149
+	STATUS_ILLEGAL_FLOAT_CONTEXT                                              NTStatus      = 0xC000014A
+	STATUS_PIPE_BROKEN                                                        NTStatus      = 0xC000014B
+	STATUS_REGISTRY_CORRUPT                                                   NTStatus      = 0xC000014C
+	STATUS_REGISTRY_IO_FAILED                                                 NTStatus      = 0xC000014D
+	STATUS_NO_EVENT_PAIR                                                      NTStatus      = 0xC000014E
+	STATUS_UNRECOGNIZED_VOLUME                                                NTStatus      = 0xC000014F
+	STATUS_SERIAL_NO_DEVICE_INITED                                            NTStatus      = 0xC0000150
+	STATUS_NO_SUCH_ALIAS                                                      NTStatus      = 0xC0000151
+	STATUS_MEMBER_NOT_IN_ALIAS                                                NTStatus      = 0xC0000152
+	STATUS_MEMBER_IN_ALIAS                                                    NTStatus      = 0xC0000153
+	STATUS_ALIAS_EXISTS                                                       NTStatus      = 0xC0000154
+	STATUS_LOGON_NOT_GRANTED                                                  NTStatus      = 0xC0000155
+	STATUS_TOO_MANY_SECRETS                                                   NTStatus      = 0xC0000156
+	STATUS_SECRET_TOO_LONG                                                    NTStatus      = 0xC0000157
+	STATUS_INTERNAL_DB_ERROR                                                  NTStatus      = 0xC0000158
+	STATUS_FULLSCREEN_MODE                                                    NTStatus      = 0xC0000159
+	STATUS_TOO_MANY_CONTEXT_IDS                                               NTStatus      = 0xC000015A
+	STATUS_LOGON_TYPE_NOT_GRANTED                                             NTStatus      = 0xC000015B
+	STATUS_NOT_REGISTRY_FILE                                                  NTStatus      = 0xC000015C
+	STATUS_NT_CROSS_ENCRYPTION_REQUIRED                                       NTStatus      = 0xC000015D
+	STATUS_DOMAIN_CTRLR_CONFIG_ERROR                                          NTStatus      = 0xC000015E
+	STATUS_FT_MISSING_MEMBER                                                  NTStatus      = 0xC000015F
+	STATUS_ILL_FORMED_SERVICE_ENTRY                                           NTStatus      = 0xC0000160
+	STATUS_ILLEGAL_CHARACTER                                                  NTStatus      = 0xC0000161
+	STATUS_UNMAPPABLE_CHARACTER                                               NTStatus      = 0xC0000162
+	STATUS_UNDEFINED_CHARACTER                                                NTStatus      = 0xC0000163
+	STATUS_FLOPPY_VOLUME                                                      NTStatus      = 0xC0000164
+	STATUS_FLOPPY_ID_MARK_NOT_FOUND                                           NTStatus      = 0xC0000165
+	STATUS_FLOPPY_WRONG_CYLINDER                                              NTStatus      = 0xC0000166
+	STATUS_FLOPPY_UNKNOWN_ERROR                                               NTStatus      = 0xC0000167
+	STATUS_FLOPPY_BAD_REGISTERS                                               NTStatus      = 0xC0000168
+	STATUS_DISK_RECALIBRATE_FAILED                                            NTStatus      = 0xC0000169
+	STATUS_DISK_OPERATION_FAILED                                              NTStatus      = 0xC000016A
+	STATUS_DISK_RESET_FAILED                                                  NTStatus      = 0xC000016B
+	STATUS_SHARED_IRQ_BUSY                                                    NTStatus      = 0xC000016C
+	STATUS_FT_ORPHANING                                                       NTStatus      = 0xC000016D
+	STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT                                   NTStatus      = 0xC000016E
+	STATUS_PARTITION_FAILURE                                                  NTStatus      = 0xC0000172
+	STATUS_INVALID_BLOCK_LENGTH                                               NTStatus      = 0xC0000173
+	STATUS_DEVICE_NOT_PARTITIONED                                             NTStatus      = 0xC0000174
+	STATUS_UNABLE_TO_LOCK_MEDIA                                               NTStatus      = 0xC0000175
+	STATUS_UNABLE_TO_UNLOAD_MEDIA                                             NTStatus      = 0xC0000176
+	STATUS_EOM_OVERFLOW                                                       NTStatus      = 0xC0000177
+	STATUS_NO_MEDIA                                                           NTStatus      = 0xC0000178
+	STATUS_NO_SUCH_MEMBER                                                     NTStatus      = 0xC000017A
+	STATUS_INVALID_MEMBER                                                     NTStatus      = 0xC000017B
+	STATUS_KEY_DELETED                                                        NTStatus      = 0xC000017C
+	STATUS_NO_LOG_SPACE                                                       NTStatus      = 0xC000017D
+	STATUS_TOO_MANY_SIDS                                                      NTStatus      = 0xC000017E
+	STATUS_LM_CROSS_ENCRYPTION_REQUIRED                                       NTStatus      = 0xC000017F
+	STATUS_KEY_HAS_CHILDREN                                                   NTStatus      = 0xC0000180
+	STATUS_CHILD_MUST_BE_VOLATILE                                             NTStatus      = 0xC0000181
+	STATUS_DEVICE_CONFIGURATION_ERROR                                         NTStatus      = 0xC0000182
+	STATUS_DRIVER_INTERNAL_ERROR                                              NTStatus      = 0xC0000183
+	STATUS_INVALID_DEVICE_STATE                                               NTStatus      = 0xC0000184
+	STATUS_IO_DEVICE_ERROR                                                    NTStatus      = 0xC0000185
+	STATUS_DEVICE_PROTOCOL_ERROR                                              NTStatus      = 0xC0000186
+	STATUS_BACKUP_CONTROLLER                                                  NTStatus      = 0xC0000187
+	STATUS_LOG_FILE_FULL                                                      NTStatus      = 0xC0000188
+	STATUS_TOO_LATE                                                           NTStatus      = 0xC0000189
+	STATUS_NO_TRUST_LSA_SECRET                                                NTStatus      = 0xC000018A
+	STATUS_NO_TRUST_SAM_ACCOUNT                                               NTStatus      = 0xC000018B
+	STATUS_TRUSTED_DOMAIN_FAILURE                                             NTStatus      = 0xC000018C
+	STATUS_TRUSTED_RELATIONSHIP_FAILURE                                       NTStatus      = 0xC000018D
+	STATUS_EVENTLOG_FILE_CORRUPT                                              NTStatus      = 0xC000018E
+	STATUS_EVENTLOG_CANT_START                                                NTStatus      = 0xC000018F
+	STATUS_TRUST_FAILURE                                                      NTStatus      = 0xC0000190
+	STATUS_MUTANT_LIMIT_EXCEEDED                                              NTStatus      = 0xC0000191
+	STATUS_NETLOGON_NOT_STARTED                                               NTStatus      = 0xC0000192
+	STATUS_ACCOUNT_EXPIRED                                                    NTStatus      = 0xC0000193
+	STATUS_POSSIBLE_DEADLOCK                                                  NTStatus      = 0xC0000194
+	STATUS_NETWORK_CREDENTIAL_CONFLICT                                        NTStatus      = 0xC0000195
+	STATUS_REMOTE_SESSION_LIMIT                                               NTStatus      = 0xC0000196
+	STATUS_EVENTLOG_FILE_CHANGED                                              NTStatus      = 0xC0000197
+	STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT                                  NTStatus      = 0xC0000198
+	STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT                                  NTStatus      = 0xC0000199
+	STATUS_NOLOGON_SERVER_TRUST_ACCOUNT                                       NTStatus      = 0xC000019A
+	STATUS_DOMAIN_TRUST_INCONSISTENT                                          NTStatus      = 0xC000019B
+	STATUS_FS_DRIVER_REQUIRED                                                 NTStatus      = 0xC000019C
+	STATUS_IMAGE_ALREADY_LOADED_AS_DLL                                        NTStatus      = 0xC000019D
+	STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING               NTStatus      = 0xC000019E
+	STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME                                  NTStatus      = 0xC000019F
+	STATUS_SECURITY_STREAM_IS_INCONSISTENT                                    NTStatus      = 0xC00001A0
+	STATUS_INVALID_LOCK_RANGE                                                 NTStatus      = 0xC00001A1
+	STATUS_INVALID_ACE_CONDITION                                              NTStatus      = 0xC00001A2
+	STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT                                        NTStatus      = 0xC00001A3
+	STATUS_NOTIFICATION_GUID_ALREADY_DEFINED                                  NTStatus      = 0xC00001A4
+	STATUS_INVALID_EXCEPTION_HANDLER                                          NTStatus      = 0xC00001A5
+	STATUS_DUPLICATE_PRIVILEGES                                               NTStatus      = 0xC00001A6
+	STATUS_NOT_ALLOWED_ON_SYSTEM_FILE                                         NTStatus      = 0xC00001A7
+	STATUS_REPAIR_NEEDED                                                      NTStatus      = 0xC00001A8
+	STATUS_QUOTA_NOT_ENABLED                                                  NTStatus      = 0xC00001A9
+	STATUS_NO_APPLICATION_PACKAGE                                             NTStatus      = 0xC00001AA
+	STATUS_FILE_METADATA_OPTIMIZATION_IN_PROGRESS                             NTStatus      = 0xC00001AB
+	STATUS_NOT_SAME_OBJECT                                                    NTStatus      = 0xC00001AC
+	STATUS_FATAL_MEMORY_EXHAUSTION                                            NTStatus      = 0xC00001AD
+	STATUS_ERROR_PROCESS_NOT_IN_JOB                                           NTStatus      = 0xC00001AE
+	STATUS_CPU_SET_INVALID                                                    NTStatus      = 0xC00001AF
+	STATUS_IO_DEVICE_INVALID_DATA                                             NTStatus      = 0xC00001B0
+	STATUS_IO_UNALIGNED_WRITE                                                 NTStatus      = 0xC00001B1
+	STATUS_NETWORK_OPEN_RESTRICTION                                           NTStatus      = 0xC0000201
+	STATUS_NO_USER_SESSION_KEY                                                NTStatus      = 0xC0000202
+	STATUS_USER_SESSION_DELETED                                               NTStatus      = 0xC0000203
+	STATUS_RESOURCE_LANG_NOT_FOUND                                            NTStatus      = 0xC0000204
+	STATUS_INSUFF_SERVER_RESOURCES                                            NTStatus      = 0xC0000205
+	STATUS_INVALID_BUFFER_SIZE                                                NTStatus      = 0xC0000206
+	STATUS_INVALID_ADDRESS_COMPONENT                                          NTStatus      = 0xC0000207
+	STATUS_INVALID_ADDRESS_WILDCARD                                           NTStatus      = 0xC0000208
+	STATUS_TOO_MANY_ADDRESSES                                                 NTStatus      = 0xC0000209
+	STATUS_ADDRESS_ALREADY_EXISTS                                             NTStatus      = 0xC000020A
+	STATUS_ADDRESS_CLOSED                                                     NTStatus      = 0xC000020B
+	STATUS_CONNECTION_DISCONNECTED                                            NTStatus      = 0xC000020C
+	STATUS_CONNECTION_RESET                                                   NTStatus      = 0xC000020D
+	STATUS_TOO_MANY_NODES                                                     NTStatus      = 0xC000020E
+	STATUS_TRANSACTION_ABORTED                                                NTStatus      = 0xC000020F
+	STATUS_TRANSACTION_TIMED_OUT                                              NTStatus      = 0xC0000210
+	STATUS_TRANSACTION_NO_RELEASE                                             NTStatus      = 0xC0000211
+	STATUS_TRANSACTION_NO_MATCH                                               NTStatus      = 0xC0000212
+	STATUS_TRANSACTION_RESPONDED                                              NTStatus      = 0xC0000213
+	STATUS_TRANSACTION_INVALID_ID                                             NTStatus      = 0xC0000214
+	STATUS_TRANSACTION_INVALID_TYPE                                           NTStatus      = 0xC0000215
+	STATUS_NOT_SERVER_SESSION                                                 NTStatus      = 0xC0000216
+	STATUS_NOT_CLIENT_SESSION                                                 NTStatus      = 0xC0000217
+	STATUS_CANNOT_LOAD_REGISTRY_FILE                                          NTStatus      = 0xC0000218
+	STATUS_DEBUG_ATTACH_FAILED                                                NTStatus      = 0xC0000219
+	STATUS_SYSTEM_PROCESS_TERMINATED                                          NTStatus      = 0xC000021A
+	STATUS_DATA_NOT_ACCEPTED                                                  NTStatus      = 0xC000021B
+	STATUS_NO_BROWSER_SERVERS_FOUND                                           NTStatus      = 0xC000021C
+	STATUS_VDM_HARD_ERROR                                                     NTStatus      = 0xC000021D
+	STATUS_DRIVER_CANCEL_TIMEOUT                                              NTStatus      = 0xC000021E
+	STATUS_REPLY_MESSAGE_MISMATCH                                             NTStatus      = 0xC000021F
+	STATUS_MAPPED_ALIGNMENT                                                   NTStatus      = 0xC0000220
+	STATUS_IMAGE_CHECKSUM_MISMATCH                                            NTStatus      = 0xC0000221
+	STATUS_LOST_WRITEBEHIND_DATA                                              NTStatus      = 0xC0000222
+	STATUS_CLIENT_SERVER_PARAMETERS_INVALID                                   NTStatus      = 0xC0000223
+	STATUS_PASSWORD_MUST_CHANGE                                               NTStatus      = 0xC0000224
+	STATUS_NOT_FOUND                                                          NTStatus      = 0xC0000225
+	STATUS_NOT_TINY_STREAM                                                    NTStatus      = 0xC0000226
+	STATUS_RECOVERY_FAILURE                                                   NTStatus      = 0xC0000227
+	STATUS_STACK_OVERFLOW_READ                                                NTStatus      = 0xC0000228
+	STATUS_FAIL_CHECK                                                         NTStatus      = 0xC0000229
+	STATUS_DUPLICATE_OBJECTID                                                 NTStatus      = 0xC000022A
+	STATUS_OBJECTID_EXISTS                                                    NTStatus      = 0xC000022B
+	STATUS_CONVERT_TO_LARGE                                                   NTStatus      = 0xC000022C
+	STATUS_RETRY                                                              NTStatus      = 0xC000022D
+	STATUS_FOUND_OUT_OF_SCOPE                                                 NTStatus      = 0xC000022E
+	STATUS_ALLOCATE_BUCKET                                                    NTStatus      = 0xC000022F
+	STATUS_PROPSET_NOT_FOUND                                                  NTStatus      = 0xC0000230
+	STATUS_MARSHALL_OVERFLOW                                                  NTStatus      = 0xC0000231
+	STATUS_INVALID_VARIANT                                                    NTStatus      = 0xC0000232
+	STATUS_DOMAIN_CONTROLLER_NOT_FOUND                                        NTStatus      = 0xC0000233
+	STATUS_ACCOUNT_LOCKED_OUT                                                 NTStatus      = 0xC0000234
+	STATUS_HANDLE_NOT_CLOSABLE                                                NTStatus      = 0xC0000235
+	STATUS_CONNECTION_REFUSED                                                 NTStatus      = 0xC0000236
+	STATUS_GRACEFUL_DISCONNECT                                                NTStatus      = 0xC0000237
+	STATUS_ADDRESS_ALREADY_ASSOCIATED                                         NTStatus      = 0xC0000238
+	STATUS_ADDRESS_NOT_ASSOCIATED                                             NTStatus      = 0xC0000239
+	STATUS_CONNECTION_INVALID                                                 NTStatus      = 0xC000023A
+	STATUS_CONNECTION_ACTIVE                                                  NTStatus      = 0xC000023B
+	STATUS_NETWORK_UNREACHABLE                                                NTStatus      = 0xC000023C
+	STATUS_HOST_UNREACHABLE                                                   NTStatus      = 0xC000023D
+	STATUS_PROTOCOL_UNREACHABLE                                               NTStatus      = 0xC000023E
+	STATUS_PORT_UNREACHABLE                                                   NTStatus      = 0xC000023F
+	STATUS_REQUEST_ABORTED                                                    NTStatus      = 0xC0000240
+	STATUS_CONNECTION_ABORTED                                                 NTStatus      = 0xC0000241
+	STATUS_BAD_COMPRESSION_BUFFER                                             NTStatus      = 0xC0000242
+	STATUS_USER_MAPPED_FILE                                                   NTStatus      = 0xC0000243
+	STATUS_AUDIT_FAILED                                                       NTStatus      = 0xC0000244
+	STATUS_TIMER_RESOLUTION_NOT_SET                                           NTStatus      = 0xC0000245
+	STATUS_CONNECTION_COUNT_LIMIT                                             NTStatus      = 0xC0000246
+	STATUS_LOGIN_TIME_RESTRICTION                                             NTStatus      = 0xC0000247
+	STATUS_LOGIN_WKSTA_RESTRICTION                                            NTStatus      = 0xC0000248
+	STATUS_IMAGE_MP_UP_MISMATCH                                               NTStatus      = 0xC0000249
+	STATUS_INSUFFICIENT_LOGON_INFO                                            NTStatus      = 0xC0000250
+	STATUS_BAD_DLL_ENTRYPOINT                                                 NTStatus      = 0xC0000251
+	STATUS_BAD_SERVICE_ENTRYPOINT                                             NTStatus      = 0xC0000252
+	STATUS_LPC_REPLY_LOST                                                     NTStatus      = 0xC0000253
+	STATUS_IP_ADDRESS_CONFLICT1                                               NTStatus      = 0xC0000254
+	STATUS_IP_ADDRESS_CONFLICT2                                               NTStatus      = 0xC0000255
+	STATUS_REGISTRY_QUOTA_LIMIT                                               NTStatus      = 0xC0000256
+	STATUS_PATH_NOT_COVERED                                                   NTStatus      = 0xC0000257
+	STATUS_NO_CALLBACK_ACTIVE                                                 NTStatus      = 0xC0000258
+	STATUS_LICENSE_QUOTA_EXCEEDED                                             NTStatus      = 0xC0000259
+	STATUS_PWD_TOO_SHORT                                                      NTStatus      = 0xC000025A
+	STATUS_PWD_TOO_RECENT                                                     NTStatus      = 0xC000025B
+	STATUS_PWD_HISTORY_CONFLICT                                               NTStatus      = 0xC000025C
+	STATUS_PLUGPLAY_NO_DEVICE                                                 NTStatus      = 0xC000025E
+	STATUS_UNSUPPORTED_COMPRESSION                                            NTStatus      = 0xC000025F
+	STATUS_INVALID_HW_PROFILE                                                 NTStatus      = 0xC0000260
+	STATUS_INVALID_PLUGPLAY_DEVICE_PATH                                       NTStatus      = 0xC0000261
+	STATUS_DRIVER_ORDINAL_NOT_FOUND                                           NTStatus      = 0xC0000262
+	STATUS_DRIVER_ENTRYPOINT_NOT_FOUND                                        NTStatus      = 0xC0000263
+	STATUS_RESOURCE_NOT_OWNED                                                 NTStatus      = 0xC0000264
+	STATUS_TOO_MANY_LINKS                                                     NTStatus      = 0xC0000265
+	STATUS_QUOTA_LIST_INCONSISTENT                                            NTStatus      = 0xC0000266
+	STATUS_FILE_IS_OFFLINE                                                    NTStatus      = 0xC0000267
+	STATUS_EVALUATION_EXPIRATION                                              NTStatus      = 0xC0000268
+	STATUS_ILLEGAL_DLL_RELOCATION                                             NTStatus      = 0xC0000269
+	STATUS_LICENSE_VIOLATION                                                  NTStatus      = 0xC000026A
+	STATUS_DLL_INIT_FAILED_LOGOFF                                             NTStatus      = 0xC000026B
+	STATUS_DRIVER_UNABLE_TO_LOAD                                              NTStatus      = 0xC000026C
+	STATUS_DFS_UNAVAILABLE                                                    NTStatus      = 0xC000026D
+	STATUS_VOLUME_DISMOUNTED                                                  NTStatus      = 0xC000026E
+	STATUS_WX86_INTERNAL_ERROR                                                NTStatus      = 0xC000026F
+	STATUS_WX86_FLOAT_STACK_CHECK                                             NTStatus      = 0xC0000270
+	STATUS_VALIDATE_CONTINUE                                                  NTStatus      = 0xC0000271
+	STATUS_NO_MATCH                                                           NTStatus      = 0xC0000272
+	STATUS_NO_MORE_MATCHES                                                    NTStatus      = 0xC0000273
+	STATUS_NOT_A_REPARSE_POINT                                                NTStatus      = 0xC0000275
+	STATUS_IO_REPARSE_TAG_INVALID                                             NTStatus      = 0xC0000276
+	STATUS_IO_REPARSE_TAG_MISMATCH                                            NTStatus      = 0xC0000277
+	STATUS_IO_REPARSE_DATA_INVALID                                            NTStatus      = 0xC0000278
+	STATUS_IO_REPARSE_TAG_NOT_HANDLED                                         NTStatus      = 0xC0000279
+	STATUS_PWD_TOO_LONG                                                       NTStatus      = 0xC000027A
+	STATUS_STOWED_EXCEPTION                                                   NTStatus      = 0xC000027B
+	STATUS_CONTEXT_STOWED_EXCEPTION                                           NTStatus      = 0xC000027C
+	STATUS_REPARSE_POINT_NOT_RESOLVED                                         NTStatus      = 0xC0000280
+	STATUS_DIRECTORY_IS_A_REPARSE_POINT                                       NTStatus      = 0xC0000281
+	STATUS_RANGE_LIST_CONFLICT                                                NTStatus      = 0xC0000282
+	STATUS_SOURCE_ELEMENT_EMPTY                                               NTStatus      = 0xC0000283
+	STATUS_DESTINATION_ELEMENT_FULL                                           NTStatus      = 0xC0000284
+	STATUS_ILLEGAL_ELEMENT_ADDRESS                                            NTStatus      = 0xC0000285
+	STATUS_MAGAZINE_NOT_PRESENT                                               NTStatus      = 0xC0000286
+	STATUS_REINITIALIZATION_NEEDED                                            NTStatus      = 0xC0000287
+	STATUS_DEVICE_REQUIRES_CLEANING                                           NTStatus      = 0x80000288
+	STATUS_DEVICE_DOOR_OPEN                                                   NTStatus      = 0x80000289
+	STATUS_ENCRYPTION_FAILED                                                  NTStatus      = 0xC000028A
+	STATUS_DECRYPTION_FAILED                                                  NTStatus      = 0xC000028B
+	STATUS_RANGE_NOT_FOUND                                                    NTStatus      = 0xC000028C
+	STATUS_NO_RECOVERY_POLICY                                                 NTStatus      = 0xC000028D
+	STATUS_NO_EFS                                                             NTStatus      = 0xC000028E
+	STATUS_WRONG_EFS                                                          NTStatus      = 0xC000028F
+	STATUS_NO_USER_KEYS                                                       NTStatus      = 0xC0000290
+	STATUS_FILE_NOT_ENCRYPTED                                                 NTStatus      = 0xC0000291
+	STATUS_NOT_EXPORT_FORMAT                                                  NTStatus      = 0xC0000292
+	STATUS_FILE_ENCRYPTED                                                     NTStatus      = 0xC0000293
+	STATUS_WAKE_SYSTEM                                                        NTStatus      = 0x40000294
+	STATUS_WMI_GUID_NOT_FOUND                                                 NTStatus      = 0xC0000295
+	STATUS_WMI_INSTANCE_NOT_FOUND                                             NTStatus      = 0xC0000296
+	STATUS_WMI_ITEMID_NOT_FOUND                                               NTStatus      = 0xC0000297
+	STATUS_WMI_TRY_AGAIN                                                      NTStatus      = 0xC0000298
+	STATUS_SHARED_POLICY                                                      NTStatus      = 0xC0000299
+	STATUS_POLICY_OBJECT_NOT_FOUND                                            NTStatus      = 0xC000029A
+	STATUS_POLICY_ONLY_IN_DS                                                  NTStatus      = 0xC000029B
+	STATUS_VOLUME_NOT_UPGRADED                                                NTStatus      = 0xC000029C
+	STATUS_REMOTE_STORAGE_NOT_ACTIVE                                          NTStatus      = 0xC000029D
+	STATUS_REMOTE_STORAGE_MEDIA_ERROR                                         NTStatus      = 0xC000029E
+	STATUS_NO_TRACKING_SERVICE                                                NTStatus      = 0xC000029F
+	STATUS_SERVER_SID_MISMATCH                                                NTStatus      = 0xC00002A0
+	STATUS_DS_NO_ATTRIBUTE_OR_VALUE                                           NTStatus      = 0xC00002A1
+	STATUS_DS_INVALID_ATTRIBUTE_SYNTAX                                        NTStatus      = 0xC00002A2
+	STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED                                        NTStatus      = 0xC00002A3
+	STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS                                       NTStatus      = 0xC00002A4
+	STATUS_DS_BUSY                                                            NTStatus      = 0xC00002A5
+	STATUS_DS_UNAVAILABLE                                                     NTStatus      = 0xC00002A6
+	STATUS_DS_NO_RIDS_ALLOCATED                                               NTStatus      = 0xC00002A7
+	STATUS_DS_NO_MORE_RIDS                                                    NTStatus      = 0xC00002A8
+	STATUS_DS_INCORRECT_ROLE_OWNER                                            NTStatus      = 0xC00002A9
+	STATUS_DS_RIDMGR_INIT_ERROR                                               NTStatus      = 0xC00002AA
+	STATUS_DS_OBJ_CLASS_VIOLATION                                             NTStatus      = 0xC00002AB
+	STATUS_DS_CANT_ON_NON_LEAF                                                NTStatus      = 0xC00002AC
+	STATUS_DS_CANT_ON_RDN                                                     NTStatus      = 0xC00002AD
+	STATUS_DS_CANT_MOD_OBJ_CLASS                                              NTStatus      = 0xC00002AE
+	STATUS_DS_CROSS_DOM_MOVE_FAILED                                           NTStatus      = 0xC00002AF
+	STATUS_DS_GC_NOT_AVAILABLE                                                NTStatus      = 0xC00002B0
+	STATUS_DIRECTORY_SERVICE_REQUIRED                                         NTStatus      = 0xC00002B1
+	STATUS_REPARSE_ATTRIBUTE_CONFLICT                                         NTStatus      = 0xC00002B2
+	STATUS_CANT_ENABLE_DENY_ONLY                                              NTStatus      = 0xC00002B3
+	STATUS_FLOAT_MULTIPLE_FAULTS                                              NTStatus      = 0xC00002B4
+	STATUS_FLOAT_MULTIPLE_TRAPS                                               NTStatus      = 0xC00002B5
+	STATUS_DEVICE_REMOVED                                                     NTStatus      = 0xC00002B6
+	STATUS_JOURNAL_DELETE_IN_PROGRESS                                         NTStatus      = 0xC00002B7
+	STATUS_JOURNAL_NOT_ACTIVE                                                 NTStatus      = 0xC00002B8
+	STATUS_NOINTERFACE                                                        NTStatus      = 0xC00002B9
+	STATUS_DS_RIDMGR_DISABLED                                                 NTStatus      = 0xC00002BA
+	STATUS_DS_ADMIN_LIMIT_EXCEEDED                                            NTStatus      = 0xC00002C1
+	STATUS_DRIVER_FAILED_SLEEP                                                NTStatus      = 0xC00002C2
+	STATUS_MUTUAL_AUTHENTICATION_FAILED                                       NTStatus      = 0xC00002C3
+	STATUS_CORRUPT_SYSTEM_FILE                                                NTStatus      = 0xC00002C4
+	STATUS_DATATYPE_MISALIGNMENT_ERROR                                        NTStatus      = 0xC00002C5
+	STATUS_WMI_READ_ONLY                                                      NTStatus      = 0xC00002C6
+	STATUS_WMI_SET_FAILURE                                                    NTStatus      = 0xC00002C7
+	STATUS_COMMITMENT_MINIMUM                                                 NTStatus      = 0xC00002C8
+	STATUS_REG_NAT_CONSUMPTION                                                NTStatus      = 0xC00002C9
+	STATUS_TRANSPORT_FULL                                                     NTStatus      = 0xC00002CA
+	STATUS_DS_SAM_INIT_FAILURE                                                NTStatus      = 0xC00002CB
+	STATUS_ONLY_IF_CONNECTED                                                  NTStatus      = 0xC00002CC
+	STATUS_DS_SENSITIVE_GROUP_VIOLATION                                       NTStatus      = 0xC00002CD
+	STATUS_PNP_RESTART_ENUMERATION                                            NTStatus      = 0xC00002CE
+	STATUS_JOURNAL_ENTRY_DELETED                                              NTStatus      = 0xC00002CF
+	STATUS_DS_CANT_MOD_PRIMARYGROUPID                                         NTStatus      = 0xC00002D0
+	STATUS_SYSTEM_IMAGE_BAD_SIGNATURE                                         NTStatus      = 0xC00002D1
+	STATUS_PNP_REBOOT_REQUIRED                                                NTStatus      = 0xC00002D2
+	STATUS_POWER_STATE_INVALID                                                NTStatus      = 0xC00002D3
+	STATUS_DS_INVALID_GROUP_TYPE                                              NTStatus      = 0xC00002D4
+	STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN                              NTStatus      = 0xC00002D5
+	STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN                               NTStatus      = 0xC00002D6
+	STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER                                   NTStatus      = 0xC00002D7
+	STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER                               NTStatus      = 0xC00002D8
+	STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER                                NTStatus      = 0xC00002D9
+	STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER                             NTStatus      = 0xC00002DA
+	STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER                        NTStatus      = 0xC00002DB
+	STATUS_DS_HAVE_PRIMARY_MEMBERS                                            NTStatus      = 0xC00002DC
+	STATUS_WMI_NOT_SUPPORTED                                                  NTStatus      = 0xC00002DD
+	STATUS_INSUFFICIENT_POWER                                                 NTStatus      = 0xC00002DE
+	STATUS_SAM_NEED_BOOTKEY_PASSWORD                                          NTStatus      = 0xC00002DF
+	STATUS_SAM_NEED_BOOTKEY_FLOPPY                                            NTStatus      = 0xC00002E0
+	STATUS_DS_CANT_START                                                      NTStatus      = 0xC00002E1
+	STATUS_DS_INIT_FAILURE                                                    NTStatus      = 0xC00002E2
+	STATUS_SAM_INIT_FAILURE                                                   NTStatus      = 0xC00002E3
+	STATUS_DS_GC_REQUIRED                                                     NTStatus      = 0xC00002E4
+	STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY                                      NTStatus      = 0xC00002E5
+	STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS                                      NTStatus      = 0xC00002E6
+	STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED                                  NTStatus      = 0xC00002E7
+	STATUS_MULTIPLE_FAULT_VIOLATION                                           NTStatus      = 0xC00002E8
+	STATUS_CURRENT_DOMAIN_NOT_ALLOWED                                         NTStatus      = 0xC00002E9
+	STATUS_CANNOT_MAKE                                                        NTStatus      = 0xC00002EA
+	STATUS_SYSTEM_SHUTDOWN                                                    NTStatus      = 0xC00002EB
+	STATUS_DS_INIT_FAILURE_CONSOLE                                            NTStatus      = 0xC00002EC
+	STATUS_DS_SAM_INIT_FAILURE_CONSOLE                                        NTStatus      = 0xC00002ED
+	STATUS_UNFINISHED_CONTEXT_DELETED                                         NTStatus      = 0xC00002EE
+	STATUS_NO_TGT_REPLY                                                       NTStatus      = 0xC00002EF
+	STATUS_OBJECTID_NOT_FOUND                                                 NTStatus      = 0xC00002F0
+	STATUS_NO_IP_ADDRESSES                                                    NTStatus      = 0xC00002F1
+	STATUS_WRONG_CREDENTIAL_HANDLE                                            NTStatus      = 0xC00002F2
+	STATUS_CRYPTO_SYSTEM_INVALID                                              NTStatus      = 0xC00002F3
+	STATUS_MAX_REFERRALS_EXCEEDED                                             NTStatus      = 0xC00002F4
+	STATUS_MUST_BE_KDC                                                        NTStatus      = 0xC00002F5
+	STATUS_STRONG_CRYPTO_NOT_SUPPORTED                                        NTStatus      = 0xC00002F6
+	STATUS_TOO_MANY_PRINCIPALS                                                NTStatus      = 0xC00002F7
+	STATUS_NO_PA_DATA                                                         NTStatus      = 0xC00002F8
+	STATUS_PKINIT_NAME_MISMATCH                                               NTStatus      = 0xC00002F9
+	STATUS_SMARTCARD_LOGON_REQUIRED                                           NTStatus      = 0xC00002FA
+	STATUS_KDC_INVALID_REQUEST                                                NTStatus      = 0xC00002FB
+	STATUS_KDC_UNABLE_TO_REFER                                                NTStatus      = 0xC00002FC
+	STATUS_KDC_UNKNOWN_ETYPE                                                  NTStatus      = 0xC00002FD
+	STATUS_SHUTDOWN_IN_PROGRESS                                               NTStatus      = 0xC00002FE
+	STATUS_SERVER_SHUTDOWN_IN_PROGRESS                                        NTStatus      = 0xC00002FF
+	STATUS_NOT_SUPPORTED_ON_SBS                                               NTStatus      = 0xC0000300
+	STATUS_WMI_GUID_DISCONNECTED                                              NTStatus      = 0xC0000301
+	STATUS_WMI_ALREADY_DISABLED                                               NTStatus      = 0xC0000302
+	STATUS_WMI_ALREADY_ENABLED                                                NTStatus      = 0xC0000303
+	STATUS_MFT_TOO_FRAGMENTED                                                 NTStatus      = 0xC0000304
+	STATUS_COPY_PROTECTION_FAILURE                                            NTStatus      = 0xC0000305
+	STATUS_CSS_AUTHENTICATION_FAILURE                                         NTStatus      = 0xC0000306
+	STATUS_CSS_KEY_NOT_PRESENT                                                NTStatus      = 0xC0000307
+	STATUS_CSS_KEY_NOT_ESTABLISHED                                            NTStatus      = 0xC0000308
+	STATUS_CSS_SCRAMBLED_SECTOR                                               NTStatus      = 0xC0000309
+	STATUS_CSS_REGION_MISMATCH                                                NTStatus      = 0xC000030A
+	STATUS_CSS_RESETS_EXHAUSTED                                               NTStatus      = 0xC000030B
+	STATUS_PASSWORD_CHANGE_REQUIRED                                           NTStatus      = 0xC000030C
+	STATUS_LOST_MODE_LOGON_RESTRICTION                                        NTStatus      = 0xC000030D
+	STATUS_PKINIT_FAILURE                                                     NTStatus      = 0xC0000320
+	STATUS_SMARTCARD_SUBSYSTEM_FAILURE                                        NTStatus      = 0xC0000321
+	STATUS_NO_KERB_KEY                                                        NTStatus      = 0xC0000322
+	STATUS_HOST_DOWN                                                          NTStatus      = 0xC0000350
+	STATUS_UNSUPPORTED_PREAUTH                                                NTStatus      = 0xC0000351
+	STATUS_EFS_ALG_BLOB_TOO_BIG                                               NTStatus      = 0xC0000352
+	STATUS_PORT_NOT_SET                                                       NTStatus      = 0xC0000353
+	STATUS_DEBUGGER_INACTIVE                                                  NTStatus      = 0xC0000354
+	STATUS_DS_VERSION_CHECK_FAILURE                                           NTStatus      = 0xC0000355
+	STATUS_AUDITING_DISABLED                                                  NTStatus      = 0xC0000356
+	STATUS_PRENT4_MACHINE_ACCOUNT                                             NTStatus      = 0xC0000357
+	STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER                                   NTStatus      = 0xC0000358
+	STATUS_INVALID_IMAGE_WIN_32                                               NTStatus      = 0xC0000359
+	STATUS_INVALID_IMAGE_WIN_64                                               NTStatus      = 0xC000035A
+	STATUS_BAD_BINDINGS                                                       NTStatus      = 0xC000035B
+	STATUS_NETWORK_SESSION_EXPIRED                                            NTStatus      = 0xC000035C
+	STATUS_APPHELP_BLOCK                                                      NTStatus      = 0xC000035D
+	STATUS_ALL_SIDS_FILTERED                                                  NTStatus      = 0xC000035E
+	STATUS_NOT_SAFE_MODE_DRIVER                                               NTStatus      = 0xC000035F
+	STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT                                  NTStatus      = 0xC0000361
+	STATUS_ACCESS_DISABLED_BY_POLICY_PATH                                     NTStatus      = 0xC0000362
+	STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER                                NTStatus      = 0xC0000363
+	STATUS_ACCESS_DISABLED_BY_POLICY_OTHER                                    NTStatus      = 0xC0000364
+	STATUS_FAILED_DRIVER_ENTRY                                                NTStatus      = 0xC0000365
+	STATUS_DEVICE_ENUMERATION_ERROR                                           NTStatus      = 0xC0000366
+	STATUS_MOUNT_POINT_NOT_RESOLVED                                           NTStatus      = 0xC0000368
+	STATUS_INVALID_DEVICE_OBJECT_PARAMETER                                    NTStatus      = 0xC0000369
+	STATUS_MCA_OCCURED                                                        NTStatus      = 0xC000036A
+	STATUS_DRIVER_BLOCKED_CRITICAL                                            NTStatus      = 0xC000036B
+	STATUS_DRIVER_BLOCKED                                                     NTStatus      = 0xC000036C
+	STATUS_DRIVER_DATABASE_ERROR                                              NTStatus      = 0xC000036D
+	STATUS_SYSTEM_HIVE_TOO_LARGE                                              NTStatus      = 0xC000036E
+	STATUS_INVALID_IMPORT_OF_NON_DLL                                          NTStatus      = 0xC000036F
+	STATUS_DS_SHUTTING_DOWN                                                   NTStatus      = 0x40000370
+	STATUS_NO_SECRETS                                                         NTStatus      = 0xC0000371
+	STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY                              NTStatus      = 0xC0000372
+	STATUS_FAILED_STACK_SWITCH                                                NTStatus      = 0xC0000373
+	STATUS_HEAP_CORRUPTION                                                    NTStatus      = 0xC0000374
+	STATUS_SMARTCARD_WRONG_PIN                                                NTStatus      = 0xC0000380
+	STATUS_SMARTCARD_CARD_BLOCKED                                             NTStatus      = 0xC0000381
+	STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED                                   NTStatus      = 0xC0000382
+	STATUS_SMARTCARD_NO_CARD                                                  NTStatus      = 0xC0000383
+	STATUS_SMARTCARD_NO_KEY_CONTAINER                                         NTStatus      = 0xC0000384
+	STATUS_SMARTCARD_NO_CERTIFICATE                                           NTStatus      = 0xC0000385
+	STATUS_SMARTCARD_NO_KEYSET                                                NTStatus      = 0xC0000386
+	STATUS_SMARTCARD_IO_ERROR                                                 NTStatus      = 0xC0000387
+	STATUS_DOWNGRADE_DETECTED                                                 NTStatus      = 0xC0000388
+	STATUS_SMARTCARD_CERT_REVOKED                                             NTStatus      = 0xC0000389
+	STATUS_ISSUING_CA_UNTRUSTED                                               NTStatus      = 0xC000038A
+	STATUS_REVOCATION_OFFLINE_C                                               NTStatus      = 0xC000038B
+	STATUS_PKINIT_CLIENT_FAILURE                                              NTStatus      = 0xC000038C
+	STATUS_SMARTCARD_CERT_EXPIRED                                             NTStatus      = 0xC000038D
+	STATUS_DRIVER_FAILED_PRIOR_UNLOAD                                         NTStatus      = 0xC000038E
+	STATUS_SMARTCARD_SILENT_CONTEXT                                           NTStatus      = 0xC000038F
+	STATUS_PER_USER_TRUST_QUOTA_EXCEEDED                                      NTStatus      = 0xC0000401
+	STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED                                      NTStatus      = 0xC0000402
+	STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED                                   NTStatus      = 0xC0000403
+	STATUS_DS_NAME_NOT_UNIQUE                                                 NTStatus      = 0xC0000404
+	STATUS_DS_DUPLICATE_ID_FOUND                                              NTStatus      = 0xC0000405
+	STATUS_DS_GROUP_CONVERSION_ERROR                                          NTStatus      = 0xC0000406
+	STATUS_VOLSNAP_PREPARE_HIBERNATE                                          NTStatus      = 0xC0000407
+	STATUS_USER2USER_REQUIRED                                                 NTStatus      = 0xC0000408
+	STATUS_STACK_BUFFER_OVERRUN                                               NTStatus      = 0xC0000409
+	STATUS_NO_S4U_PROT_SUPPORT                                                NTStatus      = 0xC000040A
+	STATUS_CROSSREALM_DELEGATION_FAILURE                                      NTStatus      = 0xC000040B
+	STATUS_REVOCATION_OFFLINE_KDC                                             NTStatus      = 0xC000040C
+	STATUS_ISSUING_CA_UNTRUSTED_KDC                                           NTStatus      = 0xC000040D
+	STATUS_KDC_CERT_EXPIRED                                                   NTStatus      = 0xC000040E
+	STATUS_KDC_CERT_REVOKED                                                   NTStatus      = 0xC000040F
+	STATUS_PARAMETER_QUOTA_EXCEEDED                                           NTStatus      = 0xC0000410
+	STATUS_HIBERNATION_FAILURE                                                NTStatus      = 0xC0000411
+	STATUS_DELAY_LOAD_FAILED                                                  NTStatus      = 0xC0000412
+	STATUS_AUTHENTICATION_FIREWALL_FAILED                                     NTStatus      = 0xC0000413
+	STATUS_VDM_DISALLOWED                                                     NTStatus      = 0xC0000414
+	STATUS_HUNG_DISPLAY_DRIVER_THREAD                                         NTStatus      = 0xC0000415
+	STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE            NTStatus      = 0xC0000416
+	STATUS_INVALID_CRUNTIME_PARAMETER                                         NTStatus      = 0xC0000417
+	STATUS_NTLM_BLOCKED                                                       NTStatus      = 0xC0000418
+	STATUS_DS_SRC_SID_EXISTS_IN_FOREST                                        NTStatus      = 0xC0000419
+	STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST                                    NTStatus      = 0xC000041A
+	STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST                                      NTStatus      = 0xC000041B
+	STATUS_INVALID_USER_PRINCIPAL_NAME                                        NTStatus      = 0xC000041C
+	STATUS_FATAL_USER_CALLBACK_EXCEPTION                                      NTStatus      = 0xC000041D
+	STATUS_ASSERTION_FAILURE                                                  NTStatus      = 0xC0000420
+	STATUS_VERIFIER_STOP                                                      NTStatus      = 0xC0000421
+	STATUS_CALLBACK_POP_STACK                                                 NTStatus      = 0xC0000423
+	STATUS_INCOMPATIBLE_DRIVER_BLOCKED                                        NTStatus      = 0xC0000424
+	STATUS_HIVE_UNLOADED                                                      NTStatus      = 0xC0000425
+	STATUS_COMPRESSION_DISABLED                                               NTStatus      = 0xC0000426
+	STATUS_FILE_SYSTEM_LIMITATION                                             NTStatus      = 0xC0000427
+	STATUS_INVALID_IMAGE_HASH                                                 NTStatus      = 0xC0000428
+	STATUS_NOT_CAPABLE                                                        NTStatus      = 0xC0000429
+	STATUS_REQUEST_OUT_OF_SEQUENCE                                            NTStatus      = 0xC000042A
+	STATUS_IMPLEMENTATION_LIMIT                                               NTStatus      = 0xC000042B
+	STATUS_ELEVATION_REQUIRED                                                 NTStatus      = 0xC000042C
+	STATUS_NO_SECURITY_CONTEXT                                                NTStatus      = 0xC000042D
+	STATUS_PKU2U_CERT_FAILURE                                                 NTStatus      = 0xC000042F
+	STATUS_BEYOND_VDL                                                         NTStatus      = 0xC0000432
+	STATUS_ENCOUNTERED_WRITE_IN_PROGRESS                                      NTStatus      = 0xC0000433
+	STATUS_PTE_CHANGED                                                        NTStatus      = 0xC0000434
+	STATUS_PURGE_FAILED                                                       NTStatus      = 0xC0000435
+	STATUS_CRED_REQUIRES_CONFIRMATION                                         NTStatus      = 0xC0000440
+	STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE                              NTStatus      = 0xC0000441
+	STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER                                   NTStatus      = 0xC0000442
+	STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE                              NTStatus      = 0xC0000443
+	STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE                                   NTStatus      = 0xC0000444
+	STATUS_CS_ENCRYPTION_FILE_NOT_CSE                                         NTStatus      = 0xC0000445
+	STATUS_INVALID_LABEL                                                      NTStatus      = 0xC0000446
+	STATUS_DRIVER_PROCESS_TERMINATED                                          NTStatus      = 0xC0000450
+	STATUS_AMBIGUOUS_SYSTEM_DEVICE                                            NTStatus      = 0xC0000451
+	STATUS_SYSTEM_DEVICE_NOT_FOUND                                            NTStatus      = 0xC0000452
+	STATUS_RESTART_BOOT_APPLICATION                                           NTStatus      = 0xC0000453
+	STATUS_INSUFFICIENT_NVRAM_RESOURCES                                       NTStatus      = 0xC0000454
+	STATUS_INVALID_SESSION                                                    NTStatus      = 0xC0000455
+	STATUS_THREAD_ALREADY_IN_SESSION                                          NTStatus      = 0xC0000456
+	STATUS_THREAD_NOT_IN_SESSION                                              NTStatus      = 0xC0000457
+	STATUS_INVALID_WEIGHT                                                     NTStatus      = 0xC0000458
+	STATUS_REQUEST_PAUSED                                                     NTStatus      = 0xC0000459
+	STATUS_NO_RANGES_PROCESSED                                                NTStatus      = 0xC0000460
+	STATUS_DISK_RESOURCES_EXHAUSTED                                           NTStatus      = 0xC0000461
+	STATUS_NEEDS_REMEDIATION                                                  NTStatus      = 0xC0000462
+	STATUS_DEVICE_FEATURE_NOT_SUPPORTED                                       NTStatus      = 0xC0000463
+	STATUS_DEVICE_UNREACHABLE                                                 NTStatus      = 0xC0000464
+	STATUS_INVALID_TOKEN                                                      NTStatus      = 0xC0000465
+	STATUS_SERVER_UNAVAILABLE                                                 NTStatus      = 0xC0000466
+	STATUS_FILE_NOT_AVAILABLE                                                 NTStatus      = 0xC0000467
+	STATUS_DEVICE_INSUFFICIENT_RESOURCES                                      NTStatus      = 0xC0000468
+	STATUS_PACKAGE_UPDATING                                                   NTStatus      = 0xC0000469
+	STATUS_NOT_READ_FROM_COPY                                                 NTStatus      = 0xC000046A
+	STATUS_FT_WRITE_FAILURE                                                   NTStatus      = 0xC000046B
+	STATUS_FT_DI_SCAN_REQUIRED                                                NTStatus      = 0xC000046C
+	STATUS_OBJECT_NOT_EXTERNALLY_BACKED                                       NTStatus      = 0xC000046D
+	STATUS_EXTERNAL_BACKING_PROVIDER_UNKNOWN                                  NTStatus      = 0xC000046E
+	STATUS_COMPRESSION_NOT_BENEFICIAL                                         NTStatus      = 0xC000046F
+	STATUS_DATA_CHECKSUM_ERROR                                                NTStatus      = 0xC0000470
+	STATUS_INTERMIXED_KERNEL_EA_OPERATION                                     NTStatus      = 0xC0000471
+	STATUS_TRIM_READ_ZERO_NOT_SUPPORTED                                       NTStatus      = 0xC0000472
+	STATUS_TOO_MANY_SEGMENT_DESCRIPTORS                                       NTStatus      = 0xC0000473
+	STATUS_INVALID_OFFSET_ALIGNMENT                                           NTStatus      = 0xC0000474
+	STATUS_INVALID_FIELD_IN_PARAMETER_LIST                                    NTStatus      = 0xC0000475
+	STATUS_OPERATION_IN_PROGRESS                                              NTStatus      = 0xC0000476
+	STATUS_INVALID_INITIATOR_TARGET_PATH                                      NTStatus      = 0xC0000477
+	STATUS_SCRUB_DATA_DISABLED                                                NTStatus      = 0xC0000478
+	STATUS_NOT_REDUNDANT_STORAGE                                              NTStatus      = 0xC0000479
+	STATUS_RESIDENT_FILE_NOT_SUPPORTED                                        NTStatus      = 0xC000047A
+	STATUS_COMPRESSED_FILE_NOT_SUPPORTED                                      NTStatus      = 0xC000047B
+	STATUS_DIRECTORY_NOT_SUPPORTED                                            NTStatus      = 0xC000047C
+	STATUS_IO_OPERATION_TIMEOUT                                               NTStatus      = 0xC000047D
+	STATUS_SYSTEM_NEEDS_REMEDIATION                                           NTStatus      = 0xC000047E
+	STATUS_APPX_INTEGRITY_FAILURE_CLR_NGEN                                    NTStatus      = 0xC000047F
+	STATUS_SHARE_UNAVAILABLE                                                  NTStatus      = 0xC0000480
+	STATUS_APISET_NOT_HOSTED                                                  NTStatus      = 0xC0000481
+	STATUS_APISET_NOT_PRESENT                                                 NTStatus      = 0xC0000482
+	STATUS_DEVICE_HARDWARE_ERROR                                              NTStatus      = 0xC0000483
+	STATUS_FIRMWARE_SLOT_INVALID                                              NTStatus      = 0xC0000484
+	STATUS_FIRMWARE_IMAGE_INVALID                                             NTStatus      = 0xC0000485
+	STATUS_STORAGE_TOPOLOGY_ID_MISMATCH                                       NTStatus      = 0xC0000486
+	STATUS_WIM_NOT_BOOTABLE                                                   NTStatus      = 0xC0000487
+	STATUS_BLOCKED_BY_PARENTAL_CONTROLS                                       NTStatus      = 0xC0000488
+	STATUS_NEEDS_REGISTRATION                                                 NTStatus      = 0xC0000489
+	STATUS_QUOTA_ACTIVITY                                                     NTStatus      = 0xC000048A
+	STATUS_CALLBACK_INVOKE_INLINE                                             NTStatus      = 0xC000048B
+	STATUS_BLOCK_TOO_MANY_REFERENCES                                          NTStatus      = 0xC000048C
+	STATUS_MARKED_TO_DISALLOW_WRITES                                          NTStatus      = 0xC000048D
+	STATUS_NETWORK_ACCESS_DENIED_EDP                                          NTStatus      = 0xC000048E
+	STATUS_ENCLAVE_FAILURE                                                    NTStatus      = 0xC000048F
+	STATUS_PNP_NO_COMPAT_DRIVERS                                              NTStatus      = 0xC0000490
+	STATUS_PNP_DRIVER_PACKAGE_NOT_FOUND                                       NTStatus      = 0xC0000491
+	STATUS_PNP_DRIVER_CONFIGURATION_NOT_FOUND                                 NTStatus      = 0xC0000492
+	STATUS_PNP_DRIVER_CONFIGURATION_INCOMPLETE                                NTStatus      = 0xC0000493
+	STATUS_PNP_FUNCTION_DRIVER_REQUIRED                                       NTStatus      = 0xC0000494
+	STATUS_PNP_DEVICE_CONFIGURATION_PENDING                                   NTStatus      = 0xC0000495
+	STATUS_DEVICE_HINT_NAME_BUFFER_TOO_SMALL                                  NTStatus      = 0xC0000496
+	STATUS_PACKAGE_NOT_AVAILABLE                                              NTStatus      = 0xC0000497
+	STATUS_DEVICE_IN_MAINTENANCE                                              NTStatus      = 0xC0000499
+	STATUS_NOT_SUPPORTED_ON_DAX                                               NTStatus      = 0xC000049A
+	STATUS_FREE_SPACE_TOO_FRAGMENTED                                          NTStatus      = 0xC000049B
+	STATUS_DAX_MAPPING_EXISTS                                                 NTStatus      = 0xC000049C
+	STATUS_CHILD_PROCESS_BLOCKED                                              NTStatus      = 0xC000049D
+	STATUS_STORAGE_LOST_DATA_PERSISTENCE                                      NTStatus      = 0xC000049E
+	STATUS_VRF_CFG_ENABLED                                                    NTStatus      = 0xC000049F
+	STATUS_PARTITION_TERMINATING                                              NTStatus      = 0xC00004A0
+	STATUS_EXTERNAL_SYSKEY_NOT_SUPPORTED                                      NTStatus      = 0xC00004A1
+	STATUS_ENCLAVE_VIOLATION                                                  NTStatus      = 0xC00004A2
+	STATUS_FILE_PROTECTED_UNDER_DPL                                           NTStatus      = 0xC00004A3
+	STATUS_VOLUME_NOT_CLUSTER_ALIGNED                                         NTStatus      = 0xC00004A4
+	STATUS_NO_PHYSICALLY_ALIGNED_FREE_SPACE_FOUND                             NTStatus      = 0xC00004A5
+	STATUS_APPX_FILE_NOT_ENCRYPTED                                            NTStatus      = 0xC00004A6
+	STATUS_RWRAW_ENCRYPTED_FILE_NOT_ENCRYPTED                                 NTStatus      = 0xC00004A7
+	STATUS_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILEOFFSET                       NTStatus      = 0xC00004A8
+	STATUS_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILERANGE                        NTStatus      = 0xC00004A9
+	STATUS_RWRAW_ENCRYPTED_INVALID_EDATAINFO_PARAMETER                        NTStatus      = 0xC00004AA
+	STATUS_FT_READ_FAILURE                                                    NTStatus      = 0xC00004AB
+	STATUS_PATCH_CONFLICT                                                     NTStatus      = 0xC00004AC
+	STATUS_STORAGE_RESERVE_ID_INVALID                                         NTStatus      = 0xC00004AD
+	STATUS_STORAGE_RESERVE_DOES_NOT_EXIST                                     NTStatus      = 0xC00004AE
+	STATUS_STORAGE_RESERVE_ALREADY_EXISTS                                     NTStatus      = 0xC00004AF
+	STATUS_STORAGE_RESERVE_NOT_EMPTY                                          NTStatus      = 0xC00004B0
+	STATUS_NOT_A_DAX_VOLUME                                                   NTStatus      = 0xC00004B1
+	STATUS_NOT_DAX_MAPPABLE                                                   NTStatus      = 0xC00004B2
+	STATUS_CASE_DIFFERING_NAMES_IN_DIR                                        NTStatus      = 0xC00004B3
+	STATUS_FILE_NOT_SUPPORTED                                                 NTStatus      = 0xC00004B4
+	STATUS_NOT_SUPPORTED_WITH_BTT                                             NTStatus      = 0xC00004B5
+	STATUS_ENCRYPTION_DISABLED                                                NTStatus      = 0xC00004B6
+	STATUS_ENCRYPTING_METADATA_DISALLOWED                                     NTStatus      = 0xC00004B7
+	STATUS_CANT_CLEAR_ENCRYPTION_FLAG                                         NTStatus      = 0xC00004B8
+	STATUS_INVALID_TASK_NAME                                                  NTStatus      = 0xC0000500
+	STATUS_INVALID_TASK_INDEX                                                 NTStatus      = 0xC0000501
+	STATUS_THREAD_ALREADY_IN_TASK                                             NTStatus      = 0xC0000502
+	STATUS_CALLBACK_BYPASS                                                    NTStatus      = 0xC0000503
+	STATUS_UNDEFINED_SCOPE                                                    NTStatus      = 0xC0000504
+	STATUS_INVALID_CAP                                                        NTStatus      = 0xC0000505
+	STATUS_NOT_GUI_PROCESS                                                    NTStatus      = 0xC0000506
+	STATUS_DEVICE_HUNG                                                        NTStatus      = 0xC0000507
+	STATUS_CONTAINER_ASSIGNED                                                 NTStatus      = 0xC0000508
+	STATUS_JOB_NO_CONTAINER                                                   NTStatus      = 0xC0000509
+	STATUS_DEVICE_UNRESPONSIVE                                                NTStatus      = 0xC000050A
+	STATUS_REPARSE_POINT_ENCOUNTERED                                          NTStatus      = 0xC000050B
+	STATUS_ATTRIBUTE_NOT_PRESENT                                              NTStatus      = 0xC000050C
+	STATUS_NOT_A_TIERED_VOLUME                                                NTStatus      = 0xC000050D
+	STATUS_ALREADY_HAS_STREAM_ID                                              NTStatus      = 0xC000050E
+	STATUS_JOB_NOT_EMPTY                                                      NTStatus      = 0xC000050F
+	STATUS_ALREADY_INITIALIZED                                                NTStatus      = 0xC0000510
+	STATUS_ENCLAVE_NOT_TERMINATED                                             NTStatus      = 0xC0000511
+	STATUS_ENCLAVE_IS_TERMINATING                                             NTStatus      = 0xC0000512
+	STATUS_SMB1_NOT_AVAILABLE                                                 NTStatus      = 0xC0000513
+	STATUS_SMR_GARBAGE_COLLECTION_REQUIRED                                    NTStatus      = 0xC0000514
+	STATUS_INTERRUPTED                                                        NTStatus      = 0xC0000515
+	STATUS_THREAD_NOT_RUNNING                                                 NTStatus      = 0xC0000516
+	STATUS_FAIL_FAST_EXCEPTION                                                NTStatus      = 0xC0000602
+	STATUS_IMAGE_CERT_REVOKED                                                 NTStatus      = 0xC0000603
+	STATUS_DYNAMIC_CODE_BLOCKED                                               NTStatus      = 0xC0000604
+	STATUS_IMAGE_CERT_EXPIRED                                                 NTStatus      = 0xC0000605
+	STATUS_STRICT_CFG_VIOLATION                                               NTStatus      = 0xC0000606
+	STATUS_SET_CONTEXT_DENIED                                                 NTStatus      = 0xC000060A
+	STATUS_CROSS_PARTITION_VIOLATION                                          NTStatus      = 0xC000060B
+	STATUS_PORT_CLOSED                                                        NTStatus      = 0xC0000700
+	STATUS_MESSAGE_LOST                                                       NTStatus      = 0xC0000701
+	STATUS_INVALID_MESSAGE                                                    NTStatus      = 0xC0000702
+	STATUS_REQUEST_CANCELED                                                   NTStatus      = 0xC0000703
+	STATUS_RECURSIVE_DISPATCH                                                 NTStatus      = 0xC0000704
+	STATUS_LPC_RECEIVE_BUFFER_EXPECTED                                        NTStatus      = 0xC0000705
+	STATUS_LPC_INVALID_CONNECTION_USAGE                                       NTStatus      = 0xC0000706
+	STATUS_LPC_REQUESTS_NOT_ALLOWED                                           NTStatus      = 0xC0000707
+	STATUS_RESOURCE_IN_USE                                                    NTStatus      = 0xC0000708
+	STATUS_HARDWARE_MEMORY_ERROR                                              NTStatus      = 0xC0000709
+	STATUS_THREADPOOL_HANDLE_EXCEPTION                                        NTStatus      = 0xC000070A
+	STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED                          NTStatus      = 0xC000070B
+	STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED                  NTStatus      = 0xC000070C
+	STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED                      NTStatus      = 0xC000070D
+	STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED                       NTStatus      = 0xC000070E
+	STATUS_THREADPOOL_RELEASED_DURING_OPERATION                               NTStatus      = 0xC000070F
+	STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING                              NTStatus      = 0xC0000710
+	STATUS_APC_RETURNED_WHILE_IMPERSONATING                                   NTStatus      = 0xC0000711
+	STATUS_PROCESS_IS_PROTECTED                                               NTStatus      = 0xC0000712
+	STATUS_MCA_EXCEPTION                                                      NTStatus      = 0xC0000713
+	STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE                                     NTStatus      = 0xC0000714
+	STATUS_SYMLINK_CLASS_DISABLED                                             NTStatus      = 0xC0000715
+	STATUS_INVALID_IDN_NORMALIZATION                                          NTStatus      = 0xC0000716
+	STATUS_NO_UNICODE_TRANSLATION                                             NTStatus      = 0xC0000717
+	STATUS_ALREADY_REGISTERED                                                 NTStatus      = 0xC0000718
+	STATUS_CONTEXT_MISMATCH                                                   NTStatus      = 0xC0000719
+	STATUS_PORT_ALREADY_HAS_COMPLETION_LIST                                   NTStatus      = 0xC000071A
+	STATUS_CALLBACK_RETURNED_THREAD_PRIORITY                                  NTStatus      = 0xC000071B
+	STATUS_INVALID_THREAD                                                     NTStatus      = 0xC000071C
+	STATUS_CALLBACK_RETURNED_TRANSACTION                                      NTStatus      = 0xC000071D
+	STATUS_CALLBACK_RETURNED_LDR_LOCK                                         NTStatus      = 0xC000071E
+	STATUS_CALLBACK_RETURNED_LANG                                             NTStatus      = 0xC000071F
+	STATUS_CALLBACK_RETURNED_PRI_BACK                                         NTStatus      = 0xC0000720
+	STATUS_CALLBACK_RETURNED_THREAD_AFFINITY                                  NTStatus      = 0xC0000721
+	STATUS_LPC_HANDLE_COUNT_EXCEEDED                                          NTStatus      = 0xC0000722
+	STATUS_EXECUTABLE_MEMORY_WRITE                                            NTStatus      = 0xC0000723
+	STATUS_KERNEL_EXECUTABLE_MEMORY_WRITE                                     NTStatus      = 0xC0000724
+	STATUS_ATTACHED_EXECUTABLE_MEMORY_WRITE                                   NTStatus      = 0xC0000725
+	STATUS_TRIGGERED_EXECUTABLE_MEMORY_WRITE                                  NTStatus      = 0xC0000726
+	STATUS_DISK_REPAIR_DISABLED                                               NTStatus      = 0xC0000800
+	STATUS_DS_DOMAIN_RENAME_IN_PROGRESS                                       NTStatus      = 0xC0000801
+	STATUS_DISK_QUOTA_EXCEEDED                                                NTStatus      = 0xC0000802
+	STATUS_DATA_LOST_REPAIR                                                   NTStatus      = 0x80000803
+	STATUS_CONTENT_BLOCKED                                                    NTStatus      = 0xC0000804
+	STATUS_BAD_CLUSTERS                                                       NTStatus      = 0xC0000805
+	STATUS_VOLUME_DIRTY                                                       NTStatus      = 0xC0000806
+	STATUS_DISK_REPAIR_REDIRECTED                                             NTStatus      = 0x40000807
+	STATUS_DISK_REPAIR_UNSUCCESSFUL                                           NTStatus      = 0xC0000808
+	STATUS_CORRUPT_LOG_OVERFULL                                               NTStatus      = 0xC0000809
+	STATUS_CORRUPT_LOG_CORRUPTED                                              NTStatus      = 0xC000080A
+	STATUS_CORRUPT_LOG_UNAVAILABLE                                            NTStatus      = 0xC000080B
+	STATUS_CORRUPT_LOG_DELETED_FULL                                           NTStatus      = 0xC000080C
+	STATUS_CORRUPT_LOG_CLEARED                                                NTStatus      = 0xC000080D
+	STATUS_ORPHAN_NAME_EXHAUSTED                                              NTStatus      = 0xC000080E
+	STATUS_PROACTIVE_SCAN_IN_PROGRESS                                         NTStatus      = 0xC000080F
+	STATUS_ENCRYPTED_IO_NOT_POSSIBLE                                          NTStatus      = 0xC0000810
+	STATUS_CORRUPT_LOG_UPLEVEL_RECORDS                                        NTStatus      = 0xC0000811
+	STATUS_FILE_CHECKED_OUT                                                   NTStatus      = 0xC0000901
+	STATUS_CHECKOUT_REQUIRED                                                  NTStatus      = 0xC0000902
+	STATUS_BAD_FILE_TYPE                                                      NTStatus      = 0xC0000903
+	STATUS_FILE_TOO_LARGE                                                     NTStatus      = 0xC0000904
+	STATUS_FORMS_AUTH_REQUIRED                                                NTStatus      = 0xC0000905
+	STATUS_VIRUS_INFECTED                                                     NTStatus      = 0xC0000906
+	STATUS_VIRUS_DELETED                                                      NTStatus      = 0xC0000907
+	STATUS_BAD_MCFG_TABLE                                                     NTStatus      = 0xC0000908
+	STATUS_CANNOT_BREAK_OPLOCK                                                NTStatus      = 0xC0000909
+	STATUS_BAD_KEY                                                            NTStatus      = 0xC000090A
+	STATUS_BAD_DATA                                                           NTStatus      = 0xC000090B
+	STATUS_NO_KEY                                                             NTStatus      = 0xC000090C
+	STATUS_FILE_HANDLE_REVOKED                                                NTStatus      = 0xC0000910
+	STATUS_WOW_ASSERTION                                                      NTStatus      = 0xC0009898
+	STATUS_INVALID_SIGNATURE                                                  NTStatus      = 0xC000A000
+	STATUS_HMAC_NOT_SUPPORTED                                                 NTStatus      = 0xC000A001
+	STATUS_AUTH_TAG_MISMATCH                                                  NTStatus      = 0xC000A002
+	STATUS_INVALID_STATE_TRANSITION                                           NTStatus      = 0xC000A003
+	STATUS_INVALID_KERNEL_INFO_VERSION                                        NTStatus      = 0xC000A004
+	STATUS_INVALID_PEP_INFO_VERSION                                           NTStatus      = 0xC000A005
+	STATUS_HANDLE_REVOKED                                                     NTStatus      = 0xC000A006
+	STATUS_EOF_ON_GHOSTED_RANGE                                               NTStatus      = 0xC000A007
+	STATUS_IPSEC_QUEUE_OVERFLOW                                               NTStatus      = 0xC000A010
+	STATUS_ND_QUEUE_OVERFLOW                                                  NTStatus      = 0xC000A011
+	STATUS_HOPLIMIT_EXCEEDED                                                  NTStatus      = 0xC000A012
+	STATUS_PROTOCOL_NOT_SUPPORTED                                             NTStatus      = 0xC000A013
+	STATUS_FASTPATH_REJECTED                                                  NTStatus      = 0xC000A014
+	STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED                         NTStatus      = 0xC000A080
+	STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR                         NTStatus      = 0xC000A081
+	STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR                             NTStatus      = 0xC000A082
+	STATUS_XML_PARSE_ERROR                                                    NTStatus      = 0xC000A083
+	STATUS_XMLDSIG_ERROR                                                      NTStatus      = 0xC000A084
+	STATUS_WRONG_COMPARTMENT                                                  NTStatus      = 0xC000A085
+	STATUS_AUTHIP_FAILURE                                                     NTStatus      = 0xC000A086
+	STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS                              NTStatus      = 0xC000A087
+	STATUS_DS_OID_NOT_FOUND                                                   NTStatus      = 0xC000A088
+	STATUS_INCORRECT_ACCOUNT_TYPE                                             NTStatus      = 0xC000A089
+	STATUS_HASH_NOT_SUPPORTED                                                 NTStatus      = 0xC000A100
+	STATUS_HASH_NOT_PRESENT                                                   NTStatus      = 0xC000A101
+	STATUS_SECONDARY_IC_PROVIDER_NOT_REGISTERED                               NTStatus      = 0xC000A121
+	STATUS_GPIO_CLIENT_INFORMATION_INVALID                                    NTStatus      = 0xC000A122
+	STATUS_GPIO_VERSION_NOT_SUPPORTED                                         NTStatus      = 0xC000A123
+	STATUS_GPIO_INVALID_REGISTRATION_PACKET                                   NTStatus      = 0xC000A124
+	STATUS_GPIO_OPERATION_DENIED                                              NTStatus      = 0xC000A125
+	STATUS_GPIO_INCOMPATIBLE_CONNECT_MODE                                     NTStatus      = 0xC000A126
+	STATUS_GPIO_INTERRUPT_ALREADY_UNMASKED                                    NTStatus      = 0x8000A127
+	STATUS_CANNOT_SWITCH_RUNLEVEL                                             NTStatus      = 0xC000A141
+	STATUS_INVALID_RUNLEVEL_SETTING                                           NTStatus      = 0xC000A142
+	STATUS_RUNLEVEL_SWITCH_TIMEOUT                                            NTStatus      = 0xC000A143
+	STATUS_SERVICES_FAILED_AUTOSTART                                          NTStatus      = 0x4000A144
+	STATUS_RUNLEVEL_SWITCH_AGENT_TIMEOUT                                      NTStatus      = 0xC000A145
+	STATUS_RUNLEVEL_SWITCH_IN_PROGRESS                                        NTStatus      = 0xC000A146
+	STATUS_NOT_APPCONTAINER                                                   NTStatus      = 0xC000A200
+	STATUS_NOT_SUPPORTED_IN_APPCONTAINER                                      NTStatus      = 0xC000A201
+	STATUS_INVALID_PACKAGE_SID_LENGTH                                         NTStatus      = 0xC000A202
+	STATUS_LPAC_ACCESS_DENIED                                                 NTStatus      = 0xC000A203
+	STATUS_ADMINLESS_ACCESS_DENIED                                            NTStatus      = 0xC000A204
+	STATUS_APP_DATA_NOT_FOUND                                                 NTStatus      = 0xC000A281
+	STATUS_APP_DATA_EXPIRED                                                   NTStatus      = 0xC000A282
+	STATUS_APP_DATA_CORRUPT                                                   NTStatus      = 0xC000A283
+	STATUS_APP_DATA_LIMIT_EXCEEDED                                            NTStatus      = 0xC000A284
+	STATUS_APP_DATA_REBOOT_REQUIRED                                           NTStatus      = 0xC000A285
+	STATUS_OFFLOAD_READ_FLT_NOT_SUPPORTED                                     NTStatus      = 0xC000A2A1
+	STATUS_OFFLOAD_WRITE_FLT_NOT_SUPPORTED                                    NTStatus      = 0xC000A2A2
+	STATUS_OFFLOAD_READ_FILE_NOT_SUPPORTED                                    NTStatus      = 0xC000A2A3
+	STATUS_OFFLOAD_WRITE_FILE_NOT_SUPPORTED                                   NTStatus      = 0xC000A2A4
+	STATUS_WOF_WIM_HEADER_CORRUPT                                             NTStatus      = 0xC000A2A5
+	STATUS_WOF_WIM_RESOURCE_TABLE_CORRUPT                                     NTStatus      = 0xC000A2A6
+	STATUS_WOF_FILE_RESOURCE_TABLE_CORRUPT                                    NTStatus      = 0xC000A2A7
+	STATUS_FILE_SYSTEM_VIRTUALIZATION_UNAVAILABLE                             NTStatus      = 0xC000CE01
+	STATUS_FILE_SYSTEM_VIRTUALIZATION_METADATA_CORRUPT                        NTStatus      = 0xC000CE02
+	STATUS_FILE_SYSTEM_VIRTUALIZATION_BUSY                                    NTStatus      = 0xC000CE03
+	STATUS_FILE_SYSTEM_VIRTUALIZATION_PROVIDER_UNKNOWN                        NTStatus      = 0xC000CE04
+	STATUS_FILE_SYSTEM_VIRTUALIZATION_INVALID_OPERATION                       NTStatus      = 0xC000CE05
+	STATUS_CLOUD_FILE_SYNC_ROOT_METADATA_CORRUPT                              NTStatus      = 0xC000CF00
+	STATUS_CLOUD_FILE_PROVIDER_NOT_RUNNING                                    NTStatus      = 0xC000CF01
+	STATUS_CLOUD_FILE_METADATA_CORRUPT                                        NTStatus      = 0xC000CF02
+	STATUS_CLOUD_FILE_METADATA_TOO_LARGE                                      NTStatus      = 0xC000CF03
+	STATUS_CLOUD_FILE_PROPERTY_BLOB_TOO_LARGE                                 NTStatus      = 0x8000CF04
+	STATUS_CLOUD_FILE_TOO_MANY_PROPERTY_BLOBS                                 NTStatus      = 0x8000CF05
+	STATUS_CLOUD_FILE_PROPERTY_VERSION_NOT_SUPPORTED                          NTStatus      = 0xC000CF06
+	STATUS_NOT_A_CLOUD_FILE                                                   NTStatus      = 0xC000CF07
+	STATUS_CLOUD_FILE_NOT_IN_SYNC                                             NTStatus      = 0xC000CF08
+	STATUS_CLOUD_FILE_ALREADY_CONNECTED                                       NTStatus      = 0xC000CF09
+	STATUS_CLOUD_FILE_NOT_SUPPORTED                                           NTStatus      = 0xC000CF0A
+	STATUS_CLOUD_FILE_INVALID_REQUEST                                         NTStatus      = 0xC000CF0B
+	STATUS_CLOUD_FILE_READ_ONLY_VOLUME                                        NTStatus      = 0xC000CF0C
+	STATUS_CLOUD_FILE_CONNECTED_PROVIDER_ONLY                                 NTStatus      = 0xC000CF0D
+	STATUS_CLOUD_FILE_VALIDATION_FAILED                                       NTStatus      = 0xC000CF0E
+	STATUS_CLOUD_FILE_AUTHENTICATION_FAILED                                   NTStatus      = 0xC000CF0F
+	STATUS_CLOUD_FILE_INSUFFICIENT_RESOURCES                                  NTStatus      = 0xC000CF10
+	STATUS_CLOUD_FILE_NETWORK_UNAVAILABLE                                     NTStatus      = 0xC000CF11
+	STATUS_CLOUD_FILE_UNSUCCESSFUL                                            NTStatus      = 0xC000CF12
+	STATUS_CLOUD_FILE_NOT_UNDER_SYNC_ROOT                                     NTStatus      = 0xC000CF13
+	STATUS_CLOUD_FILE_IN_USE                                                  NTStatus      = 0xC000CF14
+	STATUS_CLOUD_FILE_PINNED                                                  NTStatus      = 0xC000CF15
+	STATUS_CLOUD_FILE_REQUEST_ABORTED                                         NTStatus      = 0xC000CF16
+	STATUS_CLOUD_FILE_PROPERTY_CORRUPT                                        NTStatus      = 0xC000CF17
+	STATUS_CLOUD_FILE_ACCESS_DENIED                                           NTStatus      = 0xC000CF18
+	STATUS_CLOUD_FILE_INCOMPATIBLE_HARDLINKS                                  NTStatus      = 0xC000CF19
+	STATUS_CLOUD_FILE_PROPERTY_LOCK_CONFLICT                                  NTStatus      = 0xC000CF1A
+	STATUS_CLOUD_FILE_REQUEST_CANCELED                                        NTStatus      = 0xC000CF1B
+	STATUS_CLOUD_FILE_PROVIDER_TERMINATED                                     NTStatus      = 0xC000CF1D
+	STATUS_NOT_A_CLOUD_SYNC_ROOT                                              NTStatus      = 0xC000CF1E
+	STATUS_CLOUD_FILE_REQUEST_TIMEOUT                                         NTStatus      = 0xC000CF1F
+	STATUS_ACPI_INVALID_OPCODE                                                NTStatus      = 0xC0140001
+	STATUS_ACPI_STACK_OVERFLOW                                                NTStatus      = 0xC0140002
+	STATUS_ACPI_ASSERT_FAILED                                                 NTStatus      = 0xC0140003
+	STATUS_ACPI_INVALID_INDEX                                                 NTStatus      = 0xC0140004
+	STATUS_ACPI_INVALID_ARGUMENT                                              NTStatus      = 0xC0140005
+	STATUS_ACPI_FATAL                                                         NTStatus      = 0xC0140006
+	STATUS_ACPI_INVALID_SUPERNAME                                             NTStatus      = 0xC0140007
+	STATUS_ACPI_INVALID_ARGTYPE                                               NTStatus      = 0xC0140008
+	STATUS_ACPI_INVALID_OBJTYPE                                               NTStatus      = 0xC0140009
+	STATUS_ACPI_INVALID_TARGETTYPE                                            NTStatus      = 0xC014000A
+	STATUS_ACPI_INCORRECT_ARGUMENT_COUNT                                      NTStatus      = 0xC014000B
+	STATUS_ACPI_ADDRESS_NOT_MAPPED                                            NTStatus      = 0xC014000C
+	STATUS_ACPI_INVALID_EVENTTYPE                                             NTStatus      = 0xC014000D
+	STATUS_ACPI_HANDLER_COLLISION                                             NTStatus      = 0xC014000E
+	STATUS_ACPI_INVALID_DATA                                                  NTStatus      = 0xC014000F
+	STATUS_ACPI_INVALID_REGION                                                NTStatus      = 0xC0140010
+	STATUS_ACPI_INVALID_ACCESS_SIZE                                           NTStatus      = 0xC0140011
+	STATUS_ACPI_ACQUIRE_GLOBAL_LOCK                                           NTStatus      = 0xC0140012
+	STATUS_ACPI_ALREADY_INITIALIZED                                           NTStatus      = 0xC0140013
+	STATUS_ACPI_NOT_INITIALIZED                                               NTStatus      = 0xC0140014
+	STATUS_ACPI_INVALID_MUTEX_LEVEL                                           NTStatus      = 0xC0140015
+	STATUS_ACPI_MUTEX_NOT_OWNED                                               NTStatus      = 0xC0140016
+	STATUS_ACPI_MUTEX_NOT_OWNER                                               NTStatus      = 0xC0140017
+	STATUS_ACPI_RS_ACCESS                                                     NTStatus      = 0xC0140018
+	STATUS_ACPI_INVALID_TABLE                                                 NTStatus      = 0xC0140019
+	STATUS_ACPI_REG_HANDLER_FAILED                                            NTStatus      = 0xC0140020
+	STATUS_ACPI_POWER_REQUEST_FAILED                                          NTStatus      = 0xC0140021
+	STATUS_CTX_WINSTATION_NAME_INVALID                                        NTStatus      = 0xC00A0001
+	STATUS_CTX_INVALID_PD                                                     NTStatus      = 0xC00A0002
+	STATUS_CTX_PD_NOT_FOUND                                                   NTStatus      = 0xC00A0003
+	STATUS_CTX_CDM_CONNECT                                                    NTStatus      = 0x400A0004
+	STATUS_CTX_CDM_DISCONNECT                                                 NTStatus      = 0x400A0005
+	STATUS_CTX_CLOSE_PENDING                                                  NTStatus      = 0xC00A0006
+	STATUS_CTX_NO_OUTBUF                                                      NTStatus      = 0xC00A0007
+	STATUS_CTX_MODEM_INF_NOT_FOUND                                            NTStatus      = 0xC00A0008
+	STATUS_CTX_INVALID_MODEMNAME                                              NTStatus      = 0xC00A0009
+	STATUS_CTX_RESPONSE_ERROR                                                 NTStatus      = 0xC00A000A
+	STATUS_CTX_MODEM_RESPONSE_TIMEOUT                                         NTStatus      = 0xC00A000B
+	STATUS_CTX_MODEM_RESPONSE_NO_CARRIER                                      NTStatus      = 0xC00A000C
+	STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE                                     NTStatus      = 0xC00A000D
+	STATUS_CTX_MODEM_RESPONSE_BUSY                                            NTStatus      = 0xC00A000E
+	STATUS_CTX_MODEM_RESPONSE_VOICE                                           NTStatus      = 0xC00A000F
+	STATUS_CTX_TD_ERROR                                                       NTStatus      = 0xC00A0010
+	STATUS_CTX_LICENSE_CLIENT_INVALID                                         NTStatus      = 0xC00A0012
+	STATUS_CTX_LICENSE_NOT_AVAILABLE                                          NTStatus      = 0xC00A0013
+	STATUS_CTX_LICENSE_EXPIRED                                                NTStatus      = 0xC00A0014
+	STATUS_CTX_WINSTATION_NOT_FOUND                                           NTStatus      = 0xC00A0015
+	STATUS_CTX_WINSTATION_NAME_COLLISION                                      NTStatus      = 0xC00A0016
+	STATUS_CTX_WINSTATION_BUSY                                                NTStatus      = 0xC00A0017
+	STATUS_CTX_BAD_VIDEO_MODE                                                 NTStatus      = 0xC00A0018
+	STATUS_CTX_GRAPHICS_INVALID                                               NTStatus      = 0xC00A0022
+	STATUS_CTX_NOT_CONSOLE                                                    NTStatus      = 0xC00A0024
+	STATUS_CTX_CLIENT_QUERY_TIMEOUT                                           NTStatus      = 0xC00A0026
+	STATUS_CTX_CONSOLE_DISCONNECT                                             NTStatus      = 0xC00A0027
+	STATUS_CTX_CONSOLE_CONNECT                                                NTStatus      = 0xC00A0028
+	STATUS_CTX_SHADOW_DENIED                                                  NTStatus      = 0xC00A002A
+	STATUS_CTX_WINSTATION_ACCESS_DENIED                                       NTStatus      = 0xC00A002B
+	STATUS_CTX_INVALID_WD                                                     NTStatus      = 0xC00A002E
+	STATUS_CTX_WD_NOT_FOUND                                                   NTStatus      = 0xC00A002F
+	STATUS_CTX_SHADOW_INVALID                                                 NTStatus      = 0xC00A0030
+	STATUS_CTX_SHADOW_DISABLED                                                NTStatus      = 0xC00A0031
+	STATUS_RDP_PROTOCOL_ERROR                                                 NTStatus      = 0xC00A0032
+	STATUS_CTX_CLIENT_LICENSE_NOT_SET                                         NTStatus      = 0xC00A0033
+	STATUS_CTX_CLIENT_LICENSE_IN_USE                                          NTStatus      = 0xC00A0034
+	STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE                                    NTStatus      = 0xC00A0035
+	STATUS_CTX_SHADOW_NOT_RUNNING                                             NTStatus      = 0xC00A0036
+	STATUS_CTX_LOGON_DISABLED                                                 NTStatus      = 0xC00A0037
+	STATUS_CTX_SECURITY_LAYER_ERROR                                           NTStatus      = 0xC00A0038
+	STATUS_TS_INCOMPATIBLE_SESSIONS                                           NTStatus      = 0xC00A0039
+	STATUS_TS_VIDEO_SUBSYSTEM_ERROR                                           NTStatus      = 0xC00A003A
+	STATUS_PNP_BAD_MPS_TABLE                                                  NTStatus      = 0xC0040035
+	STATUS_PNP_TRANSLATION_FAILED                                             NTStatus      = 0xC0040036
+	STATUS_PNP_IRQ_TRANSLATION_FAILED                                         NTStatus      = 0xC0040037
+	STATUS_PNP_INVALID_ID                                                     NTStatus      = 0xC0040038
+	STATUS_IO_REISSUE_AS_CACHED                                               NTStatus      = 0xC0040039
+	STATUS_MUI_FILE_NOT_FOUND                                                 NTStatus      = 0xC00B0001
+	STATUS_MUI_INVALID_FILE                                                   NTStatus      = 0xC00B0002
+	STATUS_MUI_INVALID_RC_CONFIG                                              NTStatus      = 0xC00B0003
+	STATUS_MUI_INVALID_LOCALE_NAME                                            NTStatus      = 0xC00B0004
+	STATUS_MUI_INVALID_ULTIMATEFALLBACK_NAME                                  NTStatus      = 0xC00B0005
+	STATUS_MUI_FILE_NOT_LOADED                                                NTStatus      = 0xC00B0006
+	STATUS_RESOURCE_ENUM_USER_STOP                                            NTStatus      = 0xC00B0007
+	STATUS_FLT_NO_HANDLER_DEFINED                                             NTStatus      = 0xC01C0001
+	STATUS_FLT_CONTEXT_ALREADY_DEFINED                                        NTStatus      = 0xC01C0002
+	STATUS_FLT_INVALID_ASYNCHRONOUS_REQUEST                                   NTStatus      = 0xC01C0003
+	STATUS_FLT_DISALLOW_FAST_IO                                               NTStatus      = 0xC01C0004
+	STATUS_FLT_INVALID_NAME_REQUEST                                           NTStatus      = 0xC01C0005
+	STATUS_FLT_NOT_SAFE_TO_POST_OPERATION                                     NTStatus      = 0xC01C0006
+	STATUS_FLT_NOT_INITIALIZED                                                NTStatus      = 0xC01C0007
+	STATUS_FLT_FILTER_NOT_READY                                               NTStatus      = 0xC01C0008
+	STATUS_FLT_POST_OPERATION_CLEANUP                                         NTStatus      = 0xC01C0009
+	STATUS_FLT_INTERNAL_ERROR                                                 NTStatus      = 0xC01C000A
+	STATUS_FLT_DELETING_OBJECT                                                NTStatus      = 0xC01C000B
+	STATUS_FLT_MUST_BE_NONPAGED_POOL                                          NTStatus      = 0xC01C000C
+	STATUS_FLT_DUPLICATE_ENTRY                                                NTStatus      = 0xC01C000D
+	STATUS_FLT_CBDQ_DISABLED                                                  NTStatus      = 0xC01C000E
+	STATUS_FLT_DO_NOT_ATTACH                                                  NTStatus      = 0xC01C000F
+	STATUS_FLT_DO_NOT_DETACH                                                  NTStatus      = 0xC01C0010
+	STATUS_FLT_INSTANCE_ALTITUDE_COLLISION                                    NTStatus      = 0xC01C0011
+	STATUS_FLT_INSTANCE_NAME_COLLISION                                        NTStatus      = 0xC01C0012
+	STATUS_FLT_FILTER_NOT_FOUND                                               NTStatus      = 0xC01C0013
+	STATUS_FLT_VOLUME_NOT_FOUND                                               NTStatus      = 0xC01C0014
+	STATUS_FLT_INSTANCE_NOT_FOUND                                             NTStatus      = 0xC01C0015
+	STATUS_FLT_CONTEXT_ALLOCATION_NOT_FOUND                                   NTStatus      = 0xC01C0016
+	STATUS_FLT_INVALID_CONTEXT_REGISTRATION                                   NTStatus      = 0xC01C0017
+	STATUS_FLT_NAME_CACHE_MISS                                                NTStatus      = 0xC01C0018
+	STATUS_FLT_NO_DEVICE_OBJECT                                               NTStatus      = 0xC01C0019
+	STATUS_FLT_VOLUME_ALREADY_MOUNTED                                         NTStatus      = 0xC01C001A
+	STATUS_FLT_ALREADY_ENLISTED                                               NTStatus      = 0xC01C001B
+	STATUS_FLT_CONTEXT_ALREADY_LINKED                                         NTStatus      = 0xC01C001C
+	STATUS_FLT_NO_WAITER_FOR_REPLY                                            NTStatus      = 0xC01C0020
+	STATUS_FLT_REGISTRATION_BUSY                                              NTStatus      = 0xC01C0023
+	STATUS_SXS_SECTION_NOT_FOUND                                              NTStatus      = 0xC0150001
+	STATUS_SXS_CANT_GEN_ACTCTX                                                NTStatus      = 0xC0150002
+	STATUS_SXS_INVALID_ACTCTXDATA_FORMAT                                      NTStatus      = 0xC0150003
+	STATUS_SXS_ASSEMBLY_NOT_FOUND                                             NTStatus      = 0xC0150004
+	STATUS_SXS_MANIFEST_FORMAT_ERROR                                          NTStatus      = 0xC0150005
+	STATUS_SXS_MANIFEST_PARSE_ERROR                                           NTStatus      = 0xC0150006
+	STATUS_SXS_ACTIVATION_CONTEXT_DISABLED                                    NTStatus      = 0xC0150007
+	STATUS_SXS_KEY_NOT_FOUND                                                  NTStatus      = 0xC0150008
+	STATUS_SXS_VERSION_CONFLICT                                               NTStatus      = 0xC0150009
+	STATUS_SXS_WRONG_SECTION_TYPE                                             NTStatus      = 0xC015000A
+	STATUS_SXS_THREAD_QUERIES_DISABLED                                        NTStatus      = 0xC015000B
+	STATUS_SXS_ASSEMBLY_MISSING                                               NTStatus      = 0xC015000C
+	STATUS_SXS_RELEASE_ACTIVATION_CONTEXT                                     NTStatus      = 0x4015000D
+	STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET                                    NTStatus      = 0xC015000E
+	STATUS_SXS_EARLY_DEACTIVATION                                             NTStatus      = 0xC015000F
+	STATUS_SXS_INVALID_DEACTIVATION                                           NTStatus      = 0xC0150010
+	STATUS_SXS_MULTIPLE_DEACTIVATION                                          NTStatus      = 0xC0150011
+	STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY                        NTStatus      = 0xC0150012
+	STATUS_SXS_PROCESS_TERMINATION_REQUESTED                                  NTStatus      = 0xC0150013
+	STATUS_SXS_CORRUPT_ACTIVATION_STACK                                       NTStatus      = 0xC0150014
+	STATUS_SXS_CORRUPTION                                                     NTStatus      = 0xC0150015
+	STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE                               NTStatus      = 0xC0150016
+	STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME                                NTStatus      = 0xC0150017
+	STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE                                   NTStatus      = 0xC0150018
+	STATUS_SXS_IDENTITY_PARSE_ERROR                                           NTStatus      = 0xC0150019
+	STATUS_SXS_COMPONENT_STORE_CORRUPT                                        NTStatus      = 0xC015001A
+	STATUS_SXS_FILE_HASH_MISMATCH                                             NTStatus      = 0xC015001B
+	STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT                  NTStatus      = 0xC015001C
+	STATUS_SXS_IDENTITIES_DIFFERENT                                           NTStatus      = 0xC015001D
+	STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT                                   NTStatus      = 0xC015001E
+	STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY                                      NTStatus      = 0xC015001F
+	STATUS_ADVANCED_INSTALLER_FAILED                                          NTStatus      = 0xC0150020
+	STATUS_XML_ENCODING_MISMATCH                                              NTStatus      = 0xC0150021
+	STATUS_SXS_MANIFEST_TOO_BIG                                               NTStatus      = 0xC0150022
+	STATUS_SXS_SETTING_NOT_REGISTERED                                         NTStatus      = 0xC0150023
+	STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE                                 NTStatus      = 0xC0150024
+	STATUS_SMI_PRIMITIVE_INSTALLER_FAILED                                     NTStatus      = 0xC0150025
+	STATUS_GENERIC_COMMAND_FAILED                                             NTStatus      = 0xC0150026
+	STATUS_SXS_FILE_HASH_MISSING                                              NTStatus      = 0xC0150027
+	STATUS_CLUSTER_INVALID_NODE                                               NTStatus      = 0xC0130001
+	STATUS_CLUSTER_NODE_EXISTS                                                NTStatus      = 0xC0130002
+	STATUS_CLUSTER_JOIN_IN_PROGRESS                                           NTStatus      = 0xC0130003
+	STATUS_CLUSTER_NODE_NOT_FOUND                                             NTStatus      = 0xC0130004
+	STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND                                       NTStatus      = 0xC0130005
+	STATUS_CLUSTER_NETWORK_EXISTS                                             NTStatus      = 0xC0130006
+	STATUS_CLUSTER_NETWORK_NOT_FOUND                                          NTStatus      = 0xC0130007
+	STATUS_CLUSTER_NETINTERFACE_EXISTS                                        NTStatus      = 0xC0130008
+	STATUS_CLUSTER_NETINTERFACE_NOT_FOUND                                     NTStatus      = 0xC0130009
+	STATUS_CLUSTER_INVALID_REQUEST                                            NTStatus      = 0xC013000A
+	STATUS_CLUSTER_INVALID_NETWORK_PROVIDER                                   NTStatus      = 0xC013000B
+	STATUS_CLUSTER_NODE_DOWN                                                  NTStatus      = 0xC013000C
+	STATUS_CLUSTER_NODE_UNREACHABLE                                           NTStatus      = 0xC013000D
+	STATUS_CLUSTER_NODE_NOT_MEMBER                                            NTStatus      = 0xC013000E
+	STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS                                       NTStatus      = 0xC013000F
+	STATUS_CLUSTER_INVALID_NETWORK                                            NTStatus      = 0xC0130010
+	STATUS_CLUSTER_NO_NET_ADAPTERS                                            NTStatus      = 0xC0130011
+	STATUS_CLUSTER_NODE_UP                                                    NTStatus      = 0xC0130012
+	STATUS_CLUSTER_NODE_PAUSED                                                NTStatus      = 0xC0130013
+	STATUS_CLUSTER_NODE_NOT_PAUSED                                            NTStatus      = 0xC0130014
+	STATUS_CLUSTER_NO_SECURITY_CONTEXT                                        NTStatus      = 0xC0130015
+	STATUS_CLUSTER_NETWORK_NOT_INTERNAL                                       NTStatus      = 0xC0130016
+	STATUS_CLUSTER_POISONED                                                   NTStatus      = 0xC0130017
+	STATUS_CLUSTER_NON_CSV_PATH                                               NTStatus      = 0xC0130018
+	STATUS_CLUSTER_CSV_VOLUME_NOT_LOCAL                                       NTStatus      = 0xC0130019
+	STATUS_CLUSTER_CSV_READ_OPLOCK_BREAK_IN_PROGRESS                          NTStatus      = 0xC0130020
+	STATUS_CLUSTER_CSV_AUTO_PAUSE_ERROR                                       NTStatus      = 0xC0130021
+	STATUS_CLUSTER_CSV_REDIRECTED                                             NTStatus      = 0xC0130022
+	STATUS_CLUSTER_CSV_NOT_REDIRECTED                                         NTStatus      = 0xC0130023
+	STATUS_CLUSTER_CSV_VOLUME_DRAINING                                        NTStatus      = 0xC0130024
+	STATUS_CLUSTER_CSV_SNAPSHOT_CREATION_IN_PROGRESS                          NTStatus      = 0xC0130025
+	STATUS_CLUSTER_CSV_VOLUME_DRAINING_SUCCEEDED_DOWNLEVEL                    NTStatus      = 0xC0130026
+	STATUS_CLUSTER_CSV_NO_SNAPSHOTS                                           NTStatus      = 0xC0130027
+	STATUS_CSV_IO_PAUSE_TIMEOUT                                               NTStatus      = 0xC0130028
+	STATUS_CLUSTER_CSV_INVALID_HANDLE                                         NTStatus      = 0xC0130029
+	STATUS_CLUSTER_CSV_SUPPORTED_ONLY_ON_COORDINATOR                          NTStatus      = 0xC0130030
+	STATUS_CLUSTER_CAM_TICKET_REPLAY_DETECTED                                 NTStatus      = 0xC0130031
+	STATUS_TRANSACTIONAL_CONFLICT                                             NTStatus      = 0xC0190001
+	STATUS_INVALID_TRANSACTION                                                NTStatus      = 0xC0190002
+	STATUS_TRANSACTION_NOT_ACTIVE                                             NTStatus      = 0xC0190003
+	STATUS_TM_INITIALIZATION_FAILED                                           NTStatus      = 0xC0190004
+	STATUS_RM_NOT_ACTIVE                                                      NTStatus      = 0xC0190005
+	STATUS_RM_METADATA_CORRUPT                                                NTStatus      = 0xC0190006
+	STATUS_TRANSACTION_NOT_JOINED                                             NTStatus      = 0xC0190007
+	STATUS_DIRECTORY_NOT_RM                                                   NTStatus      = 0xC0190008
+	STATUS_COULD_NOT_RESIZE_LOG                                               NTStatus      = 0x80190009
+	STATUS_TRANSACTIONS_UNSUPPORTED_REMOTE                                    NTStatus      = 0xC019000A
+	STATUS_LOG_RESIZE_INVALID_SIZE                                            NTStatus      = 0xC019000B
+	STATUS_REMOTE_FILE_VERSION_MISMATCH                                       NTStatus      = 0xC019000C
+	STATUS_CRM_PROTOCOL_ALREADY_EXISTS                                        NTStatus      = 0xC019000F
+	STATUS_TRANSACTION_PROPAGATION_FAILED                                     NTStatus      = 0xC0190010
+	STATUS_CRM_PROTOCOL_NOT_FOUND                                             NTStatus      = 0xC0190011
+	STATUS_TRANSACTION_SUPERIOR_EXISTS                                        NTStatus      = 0xC0190012
+	STATUS_TRANSACTION_REQUEST_NOT_VALID                                      NTStatus      = 0xC0190013
+	STATUS_TRANSACTION_NOT_REQUESTED                                          NTStatus      = 0xC0190014
+	STATUS_TRANSACTION_ALREADY_ABORTED                                        NTStatus      = 0xC0190015
+	STATUS_TRANSACTION_ALREADY_COMMITTED                                      NTStatus      = 0xC0190016
+	STATUS_TRANSACTION_INVALID_MARSHALL_BUFFER                                NTStatus      = 0xC0190017
+	STATUS_CURRENT_TRANSACTION_NOT_VALID                                      NTStatus      = 0xC0190018
+	STATUS_LOG_GROWTH_FAILED                                                  NTStatus      = 0xC0190019
+	STATUS_OBJECT_NO_LONGER_EXISTS                                            NTStatus      = 0xC0190021
+	STATUS_STREAM_MINIVERSION_NOT_FOUND                                       NTStatus      = 0xC0190022
+	STATUS_STREAM_MINIVERSION_NOT_VALID                                       NTStatus      = 0xC0190023
+	STATUS_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION                NTStatus      = 0xC0190024
+	STATUS_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT                           NTStatus      = 0xC0190025
+	STATUS_CANT_CREATE_MORE_STREAM_MINIVERSIONS                               NTStatus      = 0xC0190026
+	STATUS_HANDLE_NO_LONGER_VALID                                             NTStatus      = 0xC0190028
+	STATUS_NO_TXF_METADATA                                                    NTStatus      = 0x80190029
+	STATUS_LOG_CORRUPTION_DETECTED                                            NTStatus      = 0xC0190030
+	STATUS_CANT_RECOVER_WITH_HANDLE_OPEN                                      NTStatus      = 0x80190031
+	STATUS_RM_DISCONNECTED                                                    NTStatus      = 0xC0190032
+	STATUS_ENLISTMENT_NOT_SUPERIOR                                            NTStatus      = 0xC0190033
+	STATUS_RECOVERY_NOT_NEEDED                                                NTStatus      = 0x40190034
+	STATUS_RM_ALREADY_STARTED                                                 NTStatus      = 0x40190035
+	STATUS_FILE_IDENTITY_NOT_PERSISTENT                                       NTStatus      = 0xC0190036
+	STATUS_CANT_BREAK_TRANSACTIONAL_DEPENDENCY                                NTStatus      = 0xC0190037
+	STATUS_CANT_CROSS_RM_BOUNDARY                                             NTStatus      = 0xC0190038
+	STATUS_TXF_DIR_NOT_EMPTY                                                  NTStatus      = 0xC0190039
+	STATUS_INDOUBT_TRANSACTIONS_EXIST                                         NTStatus      = 0xC019003A
+	STATUS_TM_VOLATILE                                                        NTStatus      = 0xC019003B
+	STATUS_ROLLBACK_TIMER_EXPIRED                                             NTStatus      = 0xC019003C
+	STATUS_TXF_ATTRIBUTE_CORRUPT                                              NTStatus      = 0xC019003D
+	STATUS_EFS_NOT_ALLOWED_IN_TRANSACTION                                     NTStatus      = 0xC019003E
+	STATUS_TRANSACTIONAL_OPEN_NOT_ALLOWED                                     NTStatus      = 0xC019003F
+	STATUS_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE                              NTStatus      = 0xC0190040
+	STATUS_TXF_METADATA_ALREADY_PRESENT                                       NTStatus      = 0x80190041
+	STATUS_TRANSACTION_SCOPE_CALLBACKS_NOT_SET                                NTStatus      = 0x80190042
+	STATUS_TRANSACTION_REQUIRED_PROMOTION                                     NTStatus      = 0xC0190043
+	STATUS_CANNOT_EXECUTE_FILE_IN_TRANSACTION                                 NTStatus      = 0xC0190044
+	STATUS_TRANSACTIONS_NOT_FROZEN                                            NTStatus      = 0xC0190045
+	STATUS_TRANSACTION_FREEZE_IN_PROGRESS                                     NTStatus      = 0xC0190046
+	STATUS_NOT_SNAPSHOT_VOLUME                                                NTStatus      = 0xC0190047
+	STATUS_NO_SAVEPOINT_WITH_OPEN_FILES                                       NTStatus      = 0xC0190048
+	STATUS_SPARSE_NOT_ALLOWED_IN_TRANSACTION                                  NTStatus      = 0xC0190049
+	STATUS_TM_IDENTITY_MISMATCH                                               NTStatus      = 0xC019004A
+	STATUS_FLOATED_SECTION                                                    NTStatus      = 0xC019004B
+	STATUS_CANNOT_ACCEPT_TRANSACTED_WORK                                      NTStatus      = 0xC019004C
+	STATUS_CANNOT_ABORT_TRANSACTIONS                                          NTStatus      = 0xC019004D
+	STATUS_TRANSACTION_NOT_FOUND                                              NTStatus      = 0xC019004E
+	STATUS_RESOURCEMANAGER_NOT_FOUND                                          NTStatus      = 0xC019004F
+	STATUS_ENLISTMENT_NOT_FOUND                                               NTStatus      = 0xC0190050
+	STATUS_TRANSACTIONMANAGER_NOT_FOUND                                       NTStatus      = 0xC0190051
+	STATUS_TRANSACTIONMANAGER_NOT_ONLINE                                      NTStatus      = 0xC0190052
+	STATUS_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION                         NTStatus      = 0xC0190053
+	STATUS_TRANSACTION_NOT_ROOT                                               NTStatus      = 0xC0190054
+	STATUS_TRANSACTION_OBJECT_EXPIRED                                         NTStatus      = 0xC0190055
+	STATUS_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION                             NTStatus      = 0xC0190056
+	STATUS_TRANSACTION_RESPONSE_NOT_ENLISTED                                  NTStatus      = 0xC0190057
+	STATUS_TRANSACTION_RECORD_TOO_LONG                                        NTStatus      = 0xC0190058
+	STATUS_NO_LINK_TRACKING_IN_TRANSACTION                                    NTStatus      = 0xC0190059
+	STATUS_OPERATION_NOT_SUPPORTED_IN_TRANSACTION                             NTStatus      = 0xC019005A
+	STATUS_TRANSACTION_INTEGRITY_VIOLATED                                     NTStatus      = 0xC019005B
+	STATUS_TRANSACTIONMANAGER_IDENTITY_MISMATCH                               NTStatus      = 0xC019005C
+	STATUS_RM_CANNOT_BE_FROZEN_FOR_SNAPSHOT                                   NTStatus      = 0xC019005D
+	STATUS_TRANSACTION_MUST_WRITETHROUGH                                      NTStatus      = 0xC019005E
+	STATUS_TRANSACTION_NO_SUPERIOR                                            NTStatus      = 0xC019005F
+	STATUS_EXPIRED_HANDLE                                                     NTStatus      = 0xC0190060
+	STATUS_TRANSACTION_NOT_ENLISTED                                           NTStatus      = 0xC0190061
+	STATUS_LOG_SECTOR_INVALID                                                 NTStatus      = 0xC01A0001
+	STATUS_LOG_SECTOR_PARITY_INVALID                                          NTStatus      = 0xC01A0002
+	STATUS_LOG_SECTOR_REMAPPED                                                NTStatus      = 0xC01A0003
+	STATUS_LOG_BLOCK_INCOMPLETE                                               NTStatus      = 0xC01A0004
+	STATUS_LOG_INVALID_RANGE                                                  NTStatus      = 0xC01A0005
+	STATUS_LOG_BLOCKS_EXHAUSTED                                               NTStatus      = 0xC01A0006
+	STATUS_LOG_READ_CONTEXT_INVALID                                           NTStatus      = 0xC01A0007
+	STATUS_LOG_RESTART_INVALID                                                NTStatus      = 0xC01A0008
+	STATUS_LOG_BLOCK_VERSION                                                  NTStatus      = 0xC01A0009
+	STATUS_LOG_BLOCK_INVALID                                                  NTStatus      = 0xC01A000A
+	STATUS_LOG_READ_MODE_INVALID                                              NTStatus      = 0xC01A000B
+	STATUS_LOG_NO_RESTART                                                     NTStatus      = 0x401A000C
+	STATUS_LOG_METADATA_CORRUPT                                               NTStatus      = 0xC01A000D
+	STATUS_LOG_METADATA_INVALID                                               NTStatus      = 0xC01A000E
+	STATUS_LOG_METADATA_INCONSISTENT                                          NTStatus      = 0xC01A000F
+	STATUS_LOG_RESERVATION_INVALID                                            NTStatus      = 0xC01A0010
+	STATUS_LOG_CANT_DELETE                                                    NTStatus      = 0xC01A0011
+	STATUS_LOG_CONTAINER_LIMIT_EXCEEDED                                       NTStatus      = 0xC01A0012
+	STATUS_LOG_START_OF_LOG                                                   NTStatus      = 0xC01A0013
+	STATUS_LOG_POLICY_ALREADY_INSTALLED                                       NTStatus      = 0xC01A0014
+	STATUS_LOG_POLICY_NOT_INSTALLED                                           NTStatus      = 0xC01A0015
+	STATUS_LOG_POLICY_INVALID                                                 NTStatus      = 0xC01A0016
+	STATUS_LOG_POLICY_CONFLICT                                                NTStatus      = 0xC01A0017
+	STATUS_LOG_PINNED_ARCHIVE_TAIL                                            NTStatus      = 0xC01A0018
+	STATUS_LOG_RECORD_NONEXISTENT                                             NTStatus      = 0xC01A0019
+	STATUS_LOG_RECORDS_RESERVED_INVALID                                       NTStatus      = 0xC01A001A
+	STATUS_LOG_SPACE_RESERVED_INVALID                                         NTStatus      = 0xC01A001B
+	STATUS_LOG_TAIL_INVALID                                                   NTStatus      = 0xC01A001C
+	STATUS_LOG_FULL                                                           NTStatus      = 0xC01A001D
+	STATUS_LOG_MULTIPLEXED                                                    NTStatus      = 0xC01A001E
+	STATUS_LOG_DEDICATED                                                      NTStatus      = 0xC01A001F
+	STATUS_LOG_ARCHIVE_NOT_IN_PROGRESS                                        NTStatus      = 0xC01A0020
+	STATUS_LOG_ARCHIVE_IN_PROGRESS                                            NTStatus      = 0xC01A0021
+	STATUS_LOG_EPHEMERAL                                                      NTStatus      = 0xC01A0022
+	STATUS_LOG_NOT_ENOUGH_CONTAINERS                                          NTStatus      = 0xC01A0023
+	STATUS_LOG_CLIENT_ALREADY_REGISTERED                                      NTStatus      = 0xC01A0024
+	STATUS_LOG_CLIENT_NOT_REGISTERED                                          NTStatus      = 0xC01A0025
+	STATUS_LOG_FULL_HANDLER_IN_PROGRESS                                       NTStatus      = 0xC01A0026
+	STATUS_LOG_CONTAINER_READ_FAILED                                          NTStatus      = 0xC01A0027
+	STATUS_LOG_CONTAINER_WRITE_FAILED                                         NTStatus      = 0xC01A0028
+	STATUS_LOG_CONTAINER_OPEN_FAILED                                          NTStatus      = 0xC01A0029
+	STATUS_LOG_CONTAINER_STATE_INVALID                                        NTStatus      = 0xC01A002A
+	STATUS_LOG_STATE_INVALID                                                  NTStatus      = 0xC01A002B
+	STATUS_LOG_PINNED                                                         NTStatus      = 0xC01A002C
+	STATUS_LOG_METADATA_FLUSH_FAILED                                          NTStatus      = 0xC01A002D
+	STATUS_LOG_INCONSISTENT_SECURITY                                          NTStatus      = 0xC01A002E
+	STATUS_LOG_APPENDED_FLUSH_FAILED                                          NTStatus      = 0xC01A002F
+	STATUS_LOG_PINNED_RESERVATION                                             NTStatus      = 0xC01A0030
+	STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD                                   NTStatus      = 0xC01B00EA
+	STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD_RECOVERED                         NTStatus      = 0x801B00EB
+	STATUS_VIDEO_DRIVER_DEBUG_REPORT_REQUEST                                  NTStatus      = 0x401B00EC
+	STATUS_MONITOR_NO_DESCRIPTOR                                              NTStatus      = 0xC01D0001
+	STATUS_MONITOR_UNKNOWN_DESCRIPTOR_FORMAT                                  NTStatus      = 0xC01D0002
+	STATUS_MONITOR_INVALID_DESCRIPTOR_CHECKSUM                                NTStatus      = 0xC01D0003
+	STATUS_MONITOR_INVALID_STANDARD_TIMING_BLOCK                              NTStatus      = 0xC01D0004
+	STATUS_MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED                          NTStatus      = 0xC01D0005
+	STATUS_MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK                         NTStatus      = 0xC01D0006
+	STATUS_MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK                         NTStatus      = 0xC01D0007
+	STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA                                    NTStatus      = 0xC01D0008
+	STATUS_MONITOR_INVALID_DETAILED_TIMING_BLOCK                              NTStatus      = 0xC01D0009
+	STATUS_MONITOR_INVALID_MANUFACTURE_DATE                                   NTStatus      = 0xC01D000A
+	STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER                                  NTStatus      = 0xC01E0000
+	STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER                                   NTStatus      = 0xC01E0001
+	STATUS_GRAPHICS_INVALID_DISPLAY_ADAPTER                                   NTStatus      = 0xC01E0002
+	STATUS_GRAPHICS_ADAPTER_WAS_RESET                                         NTStatus      = 0xC01E0003
+	STATUS_GRAPHICS_INVALID_DRIVER_MODEL                                      NTStatus      = 0xC01E0004
+	STATUS_GRAPHICS_PRESENT_MODE_CHANGED                                      NTStatus      = 0xC01E0005
+	STATUS_GRAPHICS_PRESENT_OCCLUDED                                          NTStatus      = 0xC01E0006
+	STATUS_GRAPHICS_PRESENT_DENIED                                            NTStatus      = 0xC01E0007
+	STATUS_GRAPHICS_CANNOTCOLORCONVERT                                        NTStatus      = 0xC01E0008
+	STATUS_GRAPHICS_DRIVER_MISMATCH                                           NTStatus      = 0xC01E0009
+	STATUS_GRAPHICS_PARTIAL_DATA_POPULATED                                    NTStatus      = 0x401E000A
+	STATUS_GRAPHICS_PRESENT_REDIRECTION_DISABLED                              NTStatus      = 0xC01E000B
+	STATUS_GRAPHICS_PRESENT_UNOCCLUDED                                        NTStatus      = 0xC01E000C
+	STATUS_GRAPHICS_WINDOWDC_NOT_AVAILABLE                                    NTStatus      = 0xC01E000D
+	STATUS_GRAPHICS_WINDOWLESS_PRESENT_DISABLED                               NTStatus      = 0xC01E000E
+	STATUS_GRAPHICS_PRESENT_INVALID_WINDOW                                    NTStatus      = 0xC01E000F
+	STATUS_GRAPHICS_PRESENT_BUFFER_NOT_BOUND                                  NTStatus      = 0xC01E0010
+	STATUS_GRAPHICS_VAIL_STATE_CHANGED                                        NTStatus      = 0xC01E0011
+	STATUS_GRAPHICS_INDIRECT_DISPLAY_ABANDON_SWAPCHAIN                        NTStatus      = 0xC01E0012
+	STATUS_GRAPHICS_INDIRECT_DISPLAY_DEVICE_STOPPED                           NTStatus      = 0xC01E0013
+	STATUS_GRAPHICS_NO_VIDEO_MEMORY                                           NTStatus      = 0xC01E0100
+	STATUS_GRAPHICS_CANT_LOCK_MEMORY                                          NTStatus      = 0xC01E0101
+	STATUS_GRAPHICS_ALLOCATION_BUSY                                           NTStatus      = 0xC01E0102
+	STATUS_GRAPHICS_TOO_MANY_REFERENCES                                       NTStatus      = 0xC01E0103
+	STATUS_GRAPHICS_TRY_AGAIN_LATER                                           NTStatus      = 0xC01E0104
+	STATUS_GRAPHICS_TRY_AGAIN_NOW                                             NTStatus      = 0xC01E0105
+	STATUS_GRAPHICS_ALLOCATION_INVALID                                        NTStatus      = 0xC01E0106
+	STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE                          NTStatus      = 0xC01E0107
+	STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED                          NTStatus      = 0xC01E0108
+	STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION                              NTStatus      = 0xC01E0109
+	STATUS_GRAPHICS_INVALID_ALLOCATION_USAGE                                  NTStatus      = 0xC01E0110
+	STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION                             NTStatus      = 0xC01E0111
+	STATUS_GRAPHICS_ALLOCATION_CLOSED                                         NTStatus      = 0xC01E0112
+	STATUS_GRAPHICS_INVALID_ALLOCATION_INSTANCE                               NTStatus      = 0xC01E0113
+	STATUS_GRAPHICS_INVALID_ALLOCATION_HANDLE                                 NTStatus      = 0xC01E0114
+	STATUS_GRAPHICS_WRONG_ALLOCATION_DEVICE                                   NTStatus      = 0xC01E0115
+	STATUS_GRAPHICS_ALLOCATION_CONTENT_LOST                                   NTStatus      = 0xC01E0116
+	STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE                                   NTStatus      = 0xC01E0200
+	STATUS_GRAPHICS_SKIP_ALLOCATION_PREPARATION                               NTStatus      = 0x401E0201
+	STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY                                    NTStatus      = 0xC01E0300
+	STATUS_GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED                              NTStatus      = 0xC01E0301
+	STATUS_GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED                    NTStatus      = 0xC01E0302
+	STATUS_GRAPHICS_INVALID_VIDPN                                             NTStatus      = 0xC01E0303
+	STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE                              NTStatus      = 0xC01E0304
+	STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET                              NTStatus      = 0xC01E0305
+	STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED                              NTStatus      = 0xC01E0306
+	STATUS_GRAPHICS_MODE_NOT_PINNED                                           NTStatus      = 0x401E0307
+	STATUS_GRAPHICS_INVALID_VIDPN_SOURCEMODESET                               NTStatus      = 0xC01E0308
+	STATUS_GRAPHICS_INVALID_VIDPN_TARGETMODESET                               NTStatus      = 0xC01E0309
+	STATUS_GRAPHICS_INVALID_FREQUENCY                                         NTStatus      = 0xC01E030A
+	STATUS_GRAPHICS_INVALID_ACTIVE_REGION                                     NTStatus      = 0xC01E030B
+	STATUS_GRAPHICS_INVALID_TOTAL_REGION                                      NTStatus      = 0xC01E030C
+	STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE                         NTStatus      = 0xC01E0310
+	STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE                         NTStatus      = 0xC01E0311
+	STATUS_GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET                            NTStatus      = 0xC01E0312
+	STATUS_GRAPHICS_PATH_ALREADY_IN_TOPOLOGY                                  NTStatus      = 0xC01E0313
+	STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET                                   NTStatus      = 0xC01E0314
+	STATUS_GRAPHICS_INVALID_VIDEOPRESENTSOURCESET                             NTStatus      = 0xC01E0315
+	STATUS_GRAPHICS_INVALID_VIDEOPRESENTTARGETSET                             NTStatus      = 0xC01E0316
+	STATUS_GRAPHICS_SOURCE_ALREADY_IN_SET                                     NTStatus      = 0xC01E0317
+	STATUS_GRAPHICS_TARGET_ALREADY_IN_SET                                     NTStatus      = 0xC01E0318
+	STATUS_GRAPHICS_INVALID_VIDPN_PRESENT_PATH                                NTStatus      = 0xC01E0319
+	STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY                             NTStatus      = 0xC01E031A
+	STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET                         NTStatus      = 0xC01E031B
+	STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE                            NTStatus      = 0xC01E031C
+	STATUS_GRAPHICS_FREQUENCYRANGE_NOT_IN_SET                                 NTStatus      = 0xC01E031D
+	STATUS_GRAPHICS_NO_PREFERRED_MODE                                         NTStatus      = 0x401E031E
+	STATUS_GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET                             NTStatus      = 0xC01E031F
+	STATUS_GRAPHICS_STALE_MODESET                                             NTStatus      = 0xC01E0320
+	STATUS_GRAPHICS_INVALID_MONITOR_SOURCEMODESET                             NTStatus      = 0xC01E0321
+	STATUS_GRAPHICS_INVALID_MONITOR_SOURCE_MODE                               NTStatus      = 0xC01E0322
+	STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN                           NTStatus      = 0xC01E0323
+	STATUS_GRAPHICS_MODE_ID_MUST_BE_UNIQUE                                    NTStatus      = 0xC01E0324
+	STATUS_GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION           NTStatus      = 0xC01E0325
+	STATUS_GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES                   NTStatus      = 0xC01E0326
+	STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY                                      NTStatus      = 0xC01E0327
+	STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE                     NTStatus      = 0xC01E0328
+	STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET                     NTStatus      = 0xC01E0329
+	STATUS_GRAPHICS_INVALID_MONITORDESCRIPTORSET                              NTStatus      = 0xC01E032A
+	STATUS_GRAPHICS_INVALID_MONITORDESCRIPTOR                                 NTStatus      = 0xC01E032B
+	STATUS_GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET                              NTStatus      = 0xC01E032C
+	STATUS_GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET                          NTStatus      = 0xC01E032D
+	STATUS_GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE                       NTStatus      = 0xC01E032E
+	STATUS_GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE                          NTStatus      = 0xC01E032F
+	STATUS_GRAPHICS_RESOURCES_NOT_RELATED                                     NTStatus      = 0xC01E0330
+	STATUS_GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE                                  NTStatus      = 0xC01E0331
+	STATUS_GRAPHICS_TARGET_ID_MUST_BE_UNIQUE                                  NTStatus      = 0xC01E0332
+	STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET                                 NTStatus      = 0xC01E0333
+	STATUS_GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER              NTStatus      = 0xC01E0334
+	STATUS_GRAPHICS_NO_VIDPNMGR                                               NTStatus      = 0xC01E0335
+	STATUS_GRAPHICS_NO_ACTIVE_VIDPN                                           NTStatus      = 0xC01E0336
+	STATUS_GRAPHICS_STALE_VIDPN_TOPOLOGY                                      NTStatus      = 0xC01E0337
+	STATUS_GRAPHICS_MONITOR_NOT_CONNECTED                                     NTStatus      = 0xC01E0338
+	STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY                                    NTStatus      = 0xC01E0339
+	STATUS_GRAPHICS_INVALID_PRIMARYSURFACE_SIZE                               NTStatus      = 0xC01E033A
+	STATUS_GRAPHICS_INVALID_VISIBLEREGION_SIZE                                NTStatus      = 0xC01E033B
+	STATUS_GRAPHICS_INVALID_STRIDE                                            NTStatus      = 0xC01E033C
+	STATUS_GRAPHICS_INVALID_PIXELFORMAT                                       NTStatus      = 0xC01E033D
+	STATUS_GRAPHICS_INVALID_COLORBASIS                                        NTStatus      = 0xC01E033E
+	STATUS_GRAPHICS_INVALID_PIXELVALUEACCESSMODE                              NTStatus      = 0xC01E033F
+	STATUS_GRAPHICS_TARGET_NOT_IN_TOPOLOGY                                    NTStatus      = 0xC01E0340
+	STATUS_GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT                        NTStatus      = 0xC01E0341
+	STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE                                       NTStatus      = 0xC01E0342
+	STATUS_GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN                                  NTStatus      = 0xC01E0343
+	STATUS_GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL                           NTStatus      = 0xC01E0344
+	STATUS_GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION              NTStatus      = 0xC01E0345
+	STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED        NTStatus      = 0xC01E0346
+	STATUS_GRAPHICS_INVALID_GAMMA_RAMP                                        NTStatus      = 0xC01E0347
+	STATUS_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED                                  NTStatus      = 0xC01E0348
+	STATUS_GRAPHICS_MULTISAMPLING_NOT_SUPPORTED                               NTStatus      = 0xC01E0349
+	STATUS_GRAPHICS_MODE_NOT_IN_MODESET                                       NTStatus      = 0xC01E034A
+	STATUS_GRAPHICS_DATASET_IS_EMPTY                                          NTStatus      = 0x401E034B
+	STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET                               NTStatus      = 0x401E034C
+	STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON              NTStatus      = 0xC01E034D
+	STATUS_GRAPHICS_INVALID_PATH_CONTENT_TYPE                                 NTStatus      = 0xC01E034E
+	STATUS_GRAPHICS_INVALID_COPYPROTECTION_TYPE                               NTStatus      = 0xC01E034F
+	STATUS_GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS                         NTStatus      = 0xC01E0350
+	STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_PINNED           NTStatus      = 0x401E0351
+	STATUS_GRAPHICS_INVALID_SCANLINE_ORDERING                                 NTStatus      = 0xC01E0352
+	STATUS_GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED                              NTStatus      = 0xC01E0353
+	STATUS_GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS                          NTStatus      = 0xC01E0354
+	STATUS_GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT                               NTStatus      = 0xC01E0355
+	STATUS_GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM                            NTStatus      = 0xC01E0356
+	STATUS_GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN                         NTStatus      = 0xC01E0357
+	STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT                 NTStatus      = 0xC01E0358
+	STATUS_GRAPHICS_MAX_NUM_PATHS_REACHED                                     NTStatus      = 0xC01E0359
+	STATUS_GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION                        NTStatus      = 0xC01E035A
+	STATUS_GRAPHICS_INVALID_CLIENT_TYPE                                       NTStatus      = 0xC01E035B
+	STATUS_GRAPHICS_CLIENTVIDPN_NOT_SET                                       NTStatus      = 0xC01E035C
+	STATUS_GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED                         NTStatus      = 0xC01E0400
+	STATUS_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED                            NTStatus      = 0xC01E0401
+	STATUS_GRAPHICS_UNKNOWN_CHILD_STATUS                                      NTStatus      = 0x401E042F
+	STATUS_GRAPHICS_NOT_A_LINKED_ADAPTER                                      NTStatus      = 0xC01E0430
+	STATUS_GRAPHICS_LEADLINK_NOT_ENUMERATED                                   NTStatus      = 0xC01E0431
+	STATUS_GRAPHICS_CHAINLINKS_NOT_ENUMERATED                                 NTStatus      = 0xC01E0432
+	STATUS_GRAPHICS_ADAPTER_CHAIN_NOT_READY                                   NTStatus      = 0xC01E0433
+	STATUS_GRAPHICS_CHAINLINKS_NOT_STARTED                                    NTStatus      = 0xC01E0434
+	STATUS_GRAPHICS_CHAINLINKS_NOT_POWERED_ON                                 NTStatus      = 0xC01E0435
+	STATUS_GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE                            NTStatus      = 0xC01E0436
+	STATUS_GRAPHICS_LEADLINK_START_DEFERRED                                   NTStatus      = 0x401E0437
+	STATUS_GRAPHICS_NOT_POST_DEVICE_DRIVER                                    NTStatus      = 0xC01E0438
+	STATUS_GRAPHICS_POLLING_TOO_FREQUENTLY                                    NTStatus      = 0x401E0439
+	STATUS_GRAPHICS_START_DEFERRED                                            NTStatus      = 0x401E043A
+	STATUS_GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED                               NTStatus      = 0xC01E043B
+	STATUS_GRAPHICS_DEPENDABLE_CHILD_STATUS                                   NTStatus      = 0x401E043C
+	STATUS_GRAPHICS_OPM_NOT_SUPPORTED                                         NTStatus      = 0xC01E0500
+	STATUS_GRAPHICS_COPP_NOT_SUPPORTED                                        NTStatus      = 0xC01E0501
+	STATUS_GRAPHICS_UAB_NOT_SUPPORTED                                         NTStatus      = 0xC01E0502
+	STATUS_GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS                          NTStatus      = 0xC01E0503
+	STATUS_GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST                            NTStatus      = 0xC01E0505
+	STATUS_GRAPHICS_OPM_INTERNAL_ERROR                                        NTStatus      = 0xC01E050B
+	STATUS_GRAPHICS_OPM_INVALID_HANDLE                                        NTStatus      = 0xC01E050C
+	STATUS_GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH                            NTStatus      = 0xC01E050E
+	STATUS_GRAPHICS_OPM_SPANNING_MODE_ENABLED                                 NTStatus      = 0xC01E050F
+	STATUS_GRAPHICS_OPM_THEATER_MODE_ENABLED                                  NTStatus      = 0xC01E0510
+	STATUS_GRAPHICS_PVP_HFS_FAILED                                            NTStatus      = 0xC01E0511
+	STATUS_GRAPHICS_OPM_INVALID_SRM                                           NTStatus      = 0xC01E0512
+	STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP                          NTStatus      = 0xC01E0513
+	STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP                           NTStatus      = 0xC01E0514
+	STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA                         NTStatus      = 0xC01E0515
+	STATUS_GRAPHICS_OPM_HDCP_SRM_NEVER_SET                                    NTStatus      = 0xC01E0516
+	STATUS_GRAPHICS_OPM_RESOLUTION_TOO_HIGH                                   NTStatus      = 0xC01E0517
+	STATUS_GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE                      NTStatus      = 0xC01E0518
+	STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS                     NTStatus      = 0xC01E051A
+	STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS         NTStatus      = 0xC01E051C
+	STATUS_GRAPHICS_OPM_INVALID_INFORMATION_REQUEST                           NTStatus      = 0xC01E051D
+	STATUS_GRAPHICS_OPM_DRIVER_INTERNAL_ERROR                                 NTStatus      = 0xC01E051E
+	STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS          NTStatus      = 0xC01E051F
+	STATUS_GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED                               NTStatus      = 0xC01E0520
+	STATUS_GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST                         NTStatus      = 0xC01E0521
+	STATUS_GRAPHICS_I2C_NOT_SUPPORTED                                         NTStatus      = 0xC01E0580
+	STATUS_GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST                                 NTStatus      = 0xC01E0581
+	STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA                               NTStatus      = 0xC01E0582
+	STATUS_GRAPHICS_I2C_ERROR_RECEIVING_DATA                                  NTStatus      = 0xC01E0583
+	STATUS_GRAPHICS_DDCCI_VCP_NOT_SUPPORTED                                   NTStatus      = 0xC01E0584
+	STATUS_GRAPHICS_DDCCI_INVALID_DATA                                        NTStatus      = 0xC01E0585
+	STATUS_GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE         NTStatus      = 0xC01E0586
+	STATUS_GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING                         NTStatus      = 0xC01E0587
+	STATUS_GRAPHICS_MCA_INTERNAL_ERROR                                        NTStatus      = 0xC01E0588
+	STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND                             NTStatus      = 0xC01E0589
+	STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH                              NTStatus      = 0xC01E058A
+	STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM                            NTStatus      = 0xC01E058B
+	STATUS_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE                           NTStatus      = 0xC01E058C
+	STATUS_GRAPHICS_MONITOR_NO_LONGER_EXISTS                                  NTStatus      = 0xC01E058D
+	STATUS_GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED                            NTStatus      = 0xC01E05E0
+	STATUS_GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME                     NTStatus      = 0xC01E05E1
+	STATUS_GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP                    NTStatus      = 0xC01E05E2
+	STATUS_GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED                           NTStatus      = 0xC01E05E3
+	STATUS_GRAPHICS_INVALID_POINTER                                           NTStatus      = 0xC01E05E4
+	STATUS_GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE                  NTStatus      = 0xC01E05E5
+	STATUS_GRAPHICS_PARAMETER_ARRAY_TOO_SMALL                                 NTStatus      = 0xC01E05E6
+	STATUS_GRAPHICS_INTERNAL_ERROR                                            NTStatus      = 0xC01E05E7
+	STATUS_GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS                           NTStatus      = 0xC01E05E8
+	STATUS_FVE_LOCKED_VOLUME                                                  NTStatus      = 0xC0210000
+	STATUS_FVE_NOT_ENCRYPTED                                                  NTStatus      = 0xC0210001
+	STATUS_FVE_BAD_INFORMATION                                                NTStatus      = 0xC0210002
+	STATUS_FVE_TOO_SMALL                                                      NTStatus      = 0xC0210003
+	STATUS_FVE_FAILED_WRONG_FS                                                NTStatus      = 0xC0210004
+	STATUS_FVE_BAD_PARTITION_SIZE                                             NTStatus      = 0xC0210005
+	STATUS_FVE_FS_NOT_EXTENDED                                                NTStatus      = 0xC0210006
+	STATUS_FVE_FS_MOUNTED                                                     NTStatus      = 0xC0210007
+	STATUS_FVE_NO_LICENSE                                                     NTStatus      = 0xC0210008
+	STATUS_FVE_ACTION_NOT_ALLOWED                                             NTStatus      = 0xC0210009
+	STATUS_FVE_BAD_DATA                                                       NTStatus      = 0xC021000A
+	STATUS_FVE_VOLUME_NOT_BOUND                                               NTStatus      = 0xC021000B
+	STATUS_FVE_NOT_DATA_VOLUME                                                NTStatus      = 0xC021000C
+	STATUS_FVE_CONV_READ_ERROR                                                NTStatus      = 0xC021000D
+	STATUS_FVE_CONV_WRITE_ERROR                                               NTStatus      = 0xC021000E
+	STATUS_FVE_OVERLAPPED_UPDATE                                              NTStatus      = 0xC021000F
+	STATUS_FVE_FAILED_SECTOR_SIZE                                             NTStatus      = 0xC0210010
+	STATUS_FVE_FAILED_AUTHENTICATION                                          NTStatus      = 0xC0210011
+	STATUS_FVE_NOT_OS_VOLUME                                                  NTStatus      = 0xC0210012
+	STATUS_FVE_KEYFILE_NOT_FOUND                                              NTStatus      = 0xC0210013
+	STATUS_FVE_KEYFILE_INVALID                                                NTStatus      = 0xC0210014
+	STATUS_FVE_KEYFILE_NO_VMK                                                 NTStatus      = 0xC0210015
+	STATUS_FVE_TPM_DISABLED                                                   NTStatus      = 0xC0210016
+	STATUS_FVE_TPM_SRK_AUTH_NOT_ZERO                                          NTStatus      = 0xC0210017
+	STATUS_FVE_TPM_INVALID_PCR                                                NTStatus      = 0xC0210018
+	STATUS_FVE_TPM_NO_VMK                                                     NTStatus      = 0xC0210019
+	STATUS_FVE_PIN_INVALID                                                    NTStatus      = 0xC021001A
+	STATUS_FVE_AUTH_INVALID_APPLICATION                                       NTStatus      = 0xC021001B
+	STATUS_FVE_AUTH_INVALID_CONFIG                                            NTStatus      = 0xC021001C
+	STATUS_FVE_DEBUGGER_ENABLED                                               NTStatus      = 0xC021001D
+	STATUS_FVE_DRY_RUN_FAILED                                                 NTStatus      = 0xC021001E
+	STATUS_FVE_BAD_METADATA_POINTER                                           NTStatus      = 0xC021001F
+	STATUS_FVE_OLD_METADATA_COPY                                              NTStatus      = 0xC0210020
+	STATUS_FVE_REBOOT_REQUIRED                                                NTStatus      = 0xC0210021
+	STATUS_FVE_RAW_ACCESS                                                     NTStatus      = 0xC0210022
+	STATUS_FVE_RAW_BLOCKED                                                    NTStatus      = 0xC0210023
+	STATUS_FVE_NO_AUTOUNLOCK_MASTER_KEY                                       NTStatus      = 0xC0210024
+	STATUS_FVE_MOR_FAILED                                                     NTStatus      = 0xC0210025
+	STATUS_FVE_NO_FEATURE_LICENSE                                             NTStatus      = 0xC0210026
+	STATUS_FVE_POLICY_USER_DISABLE_RDV_NOT_ALLOWED                            NTStatus      = 0xC0210027
+	STATUS_FVE_CONV_RECOVERY_FAILED                                           NTStatus      = 0xC0210028
+	STATUS_FVE_VIRTUALIZED_SPACE_TOO_BIG                                      NTStatus      = 0xC0210029
+	STATUS_FVE_INVALID_DATUM_TYPE                                             NTStatus      = 0xC021002A
+	STATUS_FVE_VOLUME_TOO_SMALL                                               NTStatus      = 0xC0210030
+	STATUS_FVE_ENH_PIN_INVALID                                                NTStatus      = 0xC0210031
+	STATUS_FVE_FULL_ENCRYPTION_NOT_ALLOWED_ON_TP_STORAGE                      NTStatus      = 0xC0210032
+	STATUS_FVE_WIPE_NOT_ALLOWED_ON_TP_STORAGE                                 NTStatus      = 0xC0210033
+	STATUS_FVE_NOT_ALLOWED_ON_CSV_STACK                                       NTStatus      = 0xC0210034
+	STATUS_FVE_NOT_ALLOWED_ON_CLUSTER                                         NTStatus      = 0xC0210035
+	STATUS_FVE_NOT_ALLOWED_TO_UPGRADE_WHILE_CONVERTING                        NTStatus      = 0xC0210036
+	STATUS_FVE_WIPE_CANCEL_NOT_APPLICABLE                                     NTStatus      = 0xC0210037
+	STATUS_FVE_EDRIVE_DRY_RUN_FAILED                                          NTStatus      = 0xC0210038
+	STATUS_FVE_SECUREBOOT_DISABLED                                            NTStatus      = 0xC0210039
+	STATUS_FVE_SECUREBOOT_CONFIG_CHANGE                                       NTStatus      = 0xC021003A
+	STATUS_FVE_DEVICE_LOCKEDOUT                                               NTStatus      = 0xC021003B
+	STATUS_FVE_VOLUME_EXTEND_PREVENTS_EOW_DECRYPT                             NTStatus      = 0xC021003C
+	STATUS_FVE_NOT_DE_VOLUME                                                  NTStatus      = 0xC021003D
+	STATUS_FVE_PROTECTION_DISABLED                                            NTStatus      = 0xC021003E
+	STATUS_FVE_PROTECTION_CANNOT_BE_DISABLED                                  NTStatus      = 0xC021003F
+	STATUS_FVE_OSV_KSR_NOT_ALLOWED                                            NTStatus      = 0xC0210040
+	STATUS_FWP_CALLOUT_NOT_FOUND                                              NTStatus      = 0xC0220001
+	STATUS_FWP_CONDITION_NOT_FOUND                                            NTStatus      = 0xC0220002
+	STATUS_FWP_FILTER_NOT_FOUND                                               NTStatus      = 0xC0220003
+	STATUS_FWP_LAYER_NOT_FOUND                                                NTStatus      = 0xC0220004
+	STATUS_FWP_PROVIDER_NOT_FOUND                                             NTStatus      = 0xC0220005
+	STATUS_FWP_PROVIDER_CONTEXT_NOT_FOUND                                     NTStatus      = 0xC0220006
+	STATUS_FWP_SUBLAYER_NOT_FOUND                                             NTStatus      = 0xC0220007
+	STATUS_FWP_NOT_FOUND                                                      NTStatus      = 0xC0220008
+	STATUS_FWP_ALREADY_EXISTS                                                 NTStatus      = 0xC0220009
+	STATUS_FWP_IN_USE                                                         NTStatus      = 0xC022000A
+	STATUS_FWP_DYNAMIC_SESSION_IN_PROGRESS                                    NTStatus      = 0xC022000B
+	STATUS_FWP_WRONG_SESSION                                                  NTStatus      = 0xC022000C
+	STATUS_FWP_NO_TXN_IN_PROGRESS                                             NTStatus      = 0xC022000D
+	STATUS_FWP_TXN_IN_PROGRESS                                                NTStatus      = 0xC022000E
+	STATUS_FWP_TXN_ABORTED                                                    NTStatus      = 0xC022000F
+	STATUS_FWP_SESSION_ABORTED                                                NTStatus      = 0xC0220010
+	STATUS_FWP_INCOMPATIBLE_TXN                                               NTStatus      = 0xC0220011
+	STATUS_FWP_TIMEOUT                                                        NTStatus      = 0xC0220012
+	STATUS_FWP_NET_EVENTS_DISABLED                                            NTStatus      = 0xC0220013
+	STATUS_FWP_INCOMPATIBLE_LAYER                                             NTStatus      = 0xC0220014
+	STATUS_FWP_KM_CLIENTS_ONLY                                                NTStatus      = 0xC0220015
+	STATUS_FWP_LIFETIME_MISMATCH                                              NTStatus      = 0xC0220016
+	STATUS_FWP_BUILTIN_OBJECT                                                 NTStatus      = 0xC0220017
+	STATUS_FWP_TOO_MANY_CALLOUTS                                              NTStatus      = 0xC0220018
+	STATUS_FWP_NOTIFICATION_DROPPED                                           NTStatus      = 0xC0220019
+	STATUS_FWP_TRAFFIC_MISMATCH                                               NTStatus      = 0xC022001A
+	STATUS_FWP_INCOMPATIBLE_SA_STATE                                          NTStatus      = 0xC022001B
+	STATUS_FWP_NULL_POINTER                                                   NTStatus      = 0xC022001C
+	STATUS_FWP_INVALID_ENUMERATOR                                             NTStatus      = 0xC022001D
+	STATUS_FWP_INVALID_FLAGS                                                  NTStatus      = 0xC022001E
+	STATUS_FWP_INVALID_NET_MASK                                               NTStatus      = 0xC022001F
+	STATUS_FWP_INVALID_RANGE                                                  NTStatus      = 0xC0220020
+	STATUS_FWP_INVALID_INTERVAL                                               NTStatus      = 0xC0220021
+	STATUS_FWP_ZERO_LENGTH_ARRAY                                              NTStatus      = 0xC0220022
+	STATUS_FWP_NULL_DISPLAY_NAME                                              NTStatus      = 0xC0220023
+	STATUS_FWP_INVALID_ACTION_TYPE                                            NTStatus      = 0xC0220024
+	STATUS_FWP_INVALID_WEIGHT                                                 NTStatus      = 0xC0220025
+	STATUS_FWP_MATCH_TYPE_MISMATCH                                            NTStatus      = 0xC0220026
+	STATUS_FWP_TYPE_MISMATCH                                                  NTStatus      = 0xC0220027
+	STATUS_FWP_OUT_OF_BOUNDS                                                  NTStatus      = 0xC0220028
+	STATUS_FWP_RESERVED                                                       NTStatus      = 0xC0220029
+	STATUS_FWP_DUPLICATE_CONDITION                                            NTStatus      = 0xC022002A
+	STATUS_FWP_DUPLICATE_KEYMOD                                               NTStatus      = 0xC022002B
+	STATUS_FWP_ACTION_INCOMPATIBLE_WITH_LAYER                                 NTStatus      = 0xC022002C
+	STATUS_FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER                              NTStatus      = 0xC022002D
+	STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER                                NTStatus      = 0xC022002E
+	STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT                              NTStatus      = 0xC022002F
+	STATUS_FWP_INCOMPATIBLE_AUTH_METHOD                                       NTStatus      = 0xC0220030
+	STATUS_FWP_INCOMPATIBLE_DH_GROUP                                          NTStatus      = 0xC0220031
+	STATUS_FWP_EM_NOT_SUPPORTED                                               NTStatus      = 0xC0220032
+	STATUS_FWP_NEVER_MATCH                                                    NTStatus      = 0xC0220033
+	STATUS_FWP_PROVIDER_CONTEXT_MISMATCH                                      NTStatus      = 0xC0220034
+	STATUS_FWP_INVALID_PARAMETER                                              NTStatus      = 0xC0220035
+	STATUS_FWP_TOO_MANY_SUBLAYERS                                             NTStatus      = 0xC0220036
+	STATUS_FWP_CALLOUT_NOTIFICATION_FAILED                                    NTStatus      = 0xC0220037
+	STATUS_FWP_INVALID_AUTH_TRANSFORM                                         NTStatus      = 0xC0220038
+	STATUS_FWP_INVALID_CIPHER_TRANSFORM                                       NTStatus      = 0xC0220039
+	STATUS_FWP_INCOMPATIBLE_CIPHER_TRANSFORM                                  NTStatus      = 0xC022003A
+	STATUS_FWP_INVALID_TRANSFORM_COMBINATION                                  NTStatus      = 0xC022003B
+	STATUS_FWP_DUPLICATE_AUTH_METHOD                                          NTStatus      = 0xC022003C
+	STATUS_FWP_INVALID_TUNNEL_ENDPOINT                                        NTStatus      = 0xC022003D
+	STATUS_FWP_L2_DRIVER_NOT_READY                                            NTStatus      = 0xC022003E
+	STATUS_FWP_KEY_DICTATOR_ALREADY_REGISTERED                                NTStatus      = 0xC022003F
+	STATUS_FWP_KEY_DICTATION_INVALID_KEYING_MATERIAL                          NTStatus      = 0xC0220040
+	STATUS_FWP_CONNECTIONS_DISABLED                                           NTStatus      = 0xC0220041
+	STATUS_FWP_INVALID_DNS_NAME                                               NTStatus      = 0xC0220042
+	STATUS_FWP_STILL_ON                                                       NTStatus      = 0xC0220043
+	STATUS_FWP_IKEEXT_NOT_RUNNING                                             NTStatus      = 0xC0220044
+	STATUS_FWP_TCPIP_NOT_READY                                                NTStatus      = 0xC0220100
+	STATUS_FWP_INJECT_HANDLE_CLOSING                                          NTStatus      = 0xC0220101
+	STATUS_FWP_INJECT_HANDLE_STALE                                            NTStatus      = 0xC0220102
+	STATUS_FWP_CANNOT_PEND                                                    NTStatus      = 0xC0220103
+	STATUS_FWP_DROP_NOICMP                                                    NTStatus      = 0xC0220104
+	STATUS_NDIS_CLOSING                                                       NTStatus      = 0xC0230002
+	STATUS_NDIS_BAD_VERSION                                                   NTStatus      = 0xC0230004
+	STATUS_NDIS_BAD_CHARACTERISTICS                                           NTStatus      = 0xC0230005
+	STATUS_NDIS_ADAPTER_NOT_FOUND                                             NTStatus      = 0xC0230006
+	STATUS_NDIS_OPEN_FAILED                                                   NTStatus      = 0xC0230007
+	STATUS_NDIS_DEVICE_FAILED                                                 NTStatus      = 0xC0230008
+	STATUS_NDIS_MULTICAST_FULL                                                NTStatus      = 0xC0230009
+	STATUS_NDIS_MULTICAST_EXISTS                                              NTStatus      = 0xC023000A
+	STATUS_NDIS_MULTICAST_NOT_FOUND                                           NTStatus      = 0xC023000B
+	STATUS_NDIS_REQUEST_ABORTED                                               NTStatus      = 0xC023000C
+	STATUS_NDIS_RESET_IN_PROGRESS                                             NTStatus      = 0xC023000D
+	STATUS_NDIS_NOT_SUPPORTED                                                 NTStatus      = 0xC02300BB
+	STATUS_NDIS_INVALID_PACKET                                                NTStatus      = 0xC023000F
+	STATUS_NDIS_ADAPTER_NOT_READY                                             NTStatus      = 0xC0230011
+	STATUS_NDIS_INVALID_LENGTH                                                NTStatus      = 0xC0230014
+	STATUS_NDIS_INVALID_DATA                                                  NTStatus      = 0xC0230015
+	STATUS_NDIS_BUFFER_TOO_SHORT                                              NTStatus      = 0xC0230016
+	STATUS_NDIS_INVALID_OID                                                   NTStatus      = 0xC0230017
+	STATUS_NDIS_ADAPTER_REMOVED                                               NTStatus      = 0xC0230018
+	STATUS_NDIS_UNSUPPORTED_MEDIA                                             NTStatus      = 0xC0230019
+	STATUS_NDIS_GROUP_ADDRESS_IN_USE                                          NTStatus      = 0xC023001A
+	STATUS_NDIS_FILE_NOT_FOUND                                                NTStatus      = 0xC023001B
+	STATUS_NDIS_ERROR_READING_FILE                                            NTStatus      = 0xC023001C
+	STATUS_NDIS_ALREADY_MAPPED                                                NTStatus      = 0xC023001D
+	STATUS_NDIS_RESOURCE_CONFLICT                                             NTStatus      = 0xC023001E
+	STATUS_NDIS_MEDIA_DISCONNECTED                                            NTStatus      = 0xC023001F
+	STATUS_NDIS_INVALID_ADDRESS                                               NTStatus      = 0xC0230022
+	STATUS_NDIS_INVALID_DEVICE_REQUEST                                        NTStatus      = 0xC0230010
+	STATUS_NDIS_PAUSED                                                        NTStatus      = 0xC023002A
+	STATUS_NDIS_INTERFACE_NOT_FOUND                                           NTStatus      = 0xC023002B
+	STATUS_NDIS_UNSUPPORTED_REVISION                                          NTStatus      = 0xC023002C
+	STATUS_NDIS_INVALID_PORT                                                  NTStatus      = 0xC023002D
+	STATUS_NDIS_INVALID_PORT_STATE                                            NTStatus      = 0xC023002E
+	STATUS_NDIS_LOW_POWER_STATE                                               NTStatus      = 0xC023002F
+	STATUS_NDIS_REINIT_REQUIRED                                               NTStatus      = 0xC0230030
+	STATUS_NDIS_NO_QUEUES                                                     NTStatus      = 0xC0230031
+	STATUS_NDIS_DOT11_AUTO_CONFIG_ENABLED                                     NTStatus      = 0xC0232000
+	STATUS_NDIS_DOT11_MEDIA_IN_USE                                            NTStatus      = 0xC0232001
+	STATUS_NDIS_DOT11_POWER_STATE_INVALID                                     NTStatus      = 0xC0232002
+	STATUS_NDIS_PM_WOL_PATTERN_LIST_FULL                                      NTStatus      = 0xC0232003
+	STATUS_NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL                                 NTStatus      = 0xC0232004
+	STATUS_NDIS_DOT11_AP_CHANNEL_CURRENTLY_NOT_AVAILABLE                      NTStatus      = 0xC0232005
+	STATUS_NDIS_DOT11_AP_BAND_CURRENTLY_NOT_AVAILABLE                         NTStatus      = 0xC0232006
+	STATUS_NDIS_DOT11_AP_CHANNEL_NOT_ALLOWED                                  NTStatus      = 0xC0232007
+	STATUS_NDIS_DOT11_AP_BAND_NOT_ALLOWED                                     NTStatus      = 0xC0232008
+	STATUS_NDIS_INDICATION_REQUIRED                                           NTStatus      = 0x40230001
+	STATUS_NDIS_OFFLOAD_POLICY                                                NTStatus      = 0xC023100F
+	STATUS_NDIS_OFFLOAD_CONNECTION_REJECTED                                   NTStatus      = 0xC0231012
+	STATUS_NDIS_OFFLOAD_PATH_REJECTED                                         NTStatus      = 0xC0231013
+	STATUS_TPM_ERROR_MASK                                                     NTStatus      = 0xC0290000
+	STATUS_TPM_AUTHFAIL                                                       NTStatus      = 0xC0290001
+	STATUS_TPM_BADINDEX                                                       NTStatus      = 0xC0290002
+	STATUS_TPM_BAD_PARAMETER                                                  NTStatus      = 0xC0290003
+	STATUS_TPM_AUDITFAILURE                                                   NTStatus      = 0xC0290004
+	STATUS_TPM_CLEAR_DISABLED                                                 NTStatus      = 0xC0290005
+	STATUS_TPM_DEACTIVATED                                                    NTStatus      = 0xC0290006
+	STATUS_TPM_DISABLED                                                       NTStatus      = 0xC0290007
+	STATUS_TPM_DISABLED_CMD                                                   NTStatus      = 0xC0290008
+	STATUS_TPM_FAIL                                                           NTStatus      = 0xC0290009
+	STATUS_TPM_BAD_ORDINAL                                                    NTStatus      = 0xC029000A
+	STATUS_TPM_INSTALL_DISABLED                                               NTStatus      = 0xC029000B
+	STATUS_TPM_INVALID_KEYHANDLE                                              NTStatus      = 0xC029000C
+	STATUS_TPM_KEYNOTFOUND                                                    NTStatus      = 0xC029000D
+	STATUS_TPM_INAPPROPRIATE_ENC                                              NTStatus      = 0xC029000E
+	STATUS_TPM_MIGRATEFAIL                                                    NTStatus      = 0xC029000F
+	STATUS_TPM_INVALID_PCR_INFO                                               NTStatus      = 0xC0290010
+	STATUS_TPM_NOSPACE                                                        NTStatus      = 0xC0290011
+	STATUS_TPM_NOSRK                                                          NTStatus      = 0xC0290012
+	STATUS_TPM_NOTSEALED_BLOB                                                 NTStatus      = 0xC0290013
+	STATUS_TPM_OWNER_SET                                                      NTStatus      = 0xC0290014
+	STATUS_TPM_RESOURCES                                                      NTStatus      = 0xC0290015
+	STATUS_TPM_SHORTRANDOM                                                    NTStatus      = 0xC0290016
+	STATUS_TPM_SIZE                                                           NTStatus      = 0xC0290017
+	STATUS_TPM_WRONGPCRVAL                                                    NTStatus      = 0xC0290018
+	STATUS_TPM_BAD_PARAM_SIZE                                                 NTStatus      = 0xC0290019
+	STATUS_TPM_SHA_THREAD                                                     NTStatus      = 0xC029001A
+	STATUS_TPM_SHA_ERROR                                                      NTStatus      = 0xC029001B
+	STATUS_TPM_FAILEDSELFTEST                                                 NTStatus      = 0xC029001C
+	STATUS_TPM_AUTH2FAIL                                                      NTStatus      = 0xC029001D
+	STATUS_TPM_BADTAG                                                         NTStatus      = 0xC029001E
+	STATUS_TPM_IOERROR                                                        NTStatus      = 0xC029001F
+	STATUS_TPM_ENCRYPT_ERROR                                                  NTStatus      = 0xC0290020
+	STATUS_TPM_DECRYPT_ERROR                                                  NTStatus      = 0xC0290021
+	STATUS_TPM_INVALID_AUTHHANDLE                                             NTStatus      = 0xC0290022
+	STATUS_TPM_NO_ENDORSEMENT                                                 NTStatus      = 0xC0290023
+	STATUS_TPM_INVALID_KEYUSAGE                                               NTStatus      = 0xC0290024
+	STATUS_TPM_WRONG_ENTITYTYPE                                               NTStatus      = 0xC0290025
+	STATUS_TPM_INVALID_POSTINIT                                               NTStatus      = 0xC0290026
+	STATUS_TPM_INAPPROPRIATE_SIG                                              NTStatus      = 0xC0290027
+	STATUS_TPM_BAD_KEY_PROPERTY                                               NTStatus      = 0xC0290028
+	STATUS_TPM_BAD_MIGRATION                                                  NTStatus      = 0xC0290029
+	STATUS_TPM_BAD_SCHEME                                                     NTStatus      = 0xC029002A
+	STATUS_TPM_BAD_DATASIZE                                                   NTStatus      = 0xC029002B
+	STATUS_TPM_BAD_MODE                                                       NTStatus      = 0xC029002C
+	STATUS_TPM_BAD_PRESENCE                                                   NTStatus      = 0xC029002D
+	STATUS_TPM_BAD_VERSION                                                    NTStatus      = 0xC029002E
+	STATUS_TPM_NO_WRAP_TRANSPORT                                              NTStatus      = 0xC029002F
+	STATUS_TPM_AUDITFAIL_UNSUCCESSFUL                                         NTStatus      = 0xC0290030
+	STATUS_TPM_AUDITFAIL_SUCCESSFUL                                           NTStatus      = 0xC0290031
+	STATUS_TPM_NOTRESETABLE                                                   NTStatus      = 0xC0290032
+	STATUS_TPM_NOTLOCAL                                                       NTStatus      = 0xC0290033
+	STATUS_TPM_BAD_TYPE                                                       NTStatus      = 0xC0290034
+	STATUS_TPM_INVALID_RESOURCE                                               NTStatus      = 0xC0290035
+	STATUS_TPM_NOTFIPS                                                        NTStatus      = 0xC0290036
+	STATUS_TPM_INVALID_FAMILY                                                 NTStatus      = 0xC0290037
+	STATUS_TPM_NO_NV_PERMISSION                                               NTStatus      = 0xC0290038
+	STATUS_TPM_REQUIRES_SIGN                                                  NTStatus      = 0xC0290039
+	STATUS_TPM_KEY_NOTSUPPORTED                                               NTStatus      = 0xC029003A
+	STATUS_TPM_AUTH_CONFLICT                                                  NTStatus      = 0xC029003B
+	STATUS_TPM_AREA_LOCKED                                                    NTStatus      = 0xC029003C
+	STATUS_TPM_BAD_LOCALITY                                                   NTStatus      = 0xC029003D
+	STATUS_TPM_READ_ONLY                                                      NTStatus      = 0xC029003E
+	STATUS_TPM_PER_NOWRITE                                                    NTStatus      = 0xC029003F
+	STATUS_TPM_FAMILYCOUNT                                                    NTStatus      = 0xC0290040
+	STATUS_TPM_WRITE_LOCKED                                                   NTStatus      = 0xC0290041
+	STATUS_TPM_BAD_ATTRIBUTES                                                 NTStatus      = 0xC0290042
+	STATUS_TPM_INVALID_STRUCTURE                                              NTStatus      = 0xC0290043
+	STATUS_TPM_KEY_OWNER_CONTROL                                              NTStatus      = 0xC0290044
+	STATUS_TPM_BAD_COUNTER                                                    NTStatus      = 0xC0290045
+	STATUS_TPM_NOT_FULLWRITE                                                  NTStatus      = 0xC0290046
+	STATUS_TPM_CONTEXT_GAP                                                    NTStatus      = 0xC0290047
+	STATUS_TPM_MAXNVWRITES                                                    NTStatus      = 0xC0290048
+	STATUS_TPM_NOOPERATOR                                                     NTStatus      = 0xC0290049
+	STATUS_TPM_RESOURCEMISSING                                                NTStatus      = 0xC029004A
+	STATUS_TPM_DELEGATE_LOCK                                                  NTStatus      = 0xC029004B
+	STATUS_TPM_DELEGATE_FAMILY                                                NTStatus      = 0xC029004C
+	STATUS_TPM_DELEGATE_ADMIN                                                 NTStatus      = 0xC029004D
+	STATUS_TPM_TRANSPORT_NOTEXCLUSIVE                                         NTStatus      = 0xC029004E
+	STATUS_TPM_OWNER_CONTROL                                                  NTStatus      = 0xC029004F
+	STATUS_TPM_DAA_RESOURCES                                                  NTStatus      = 0xC0290050
+	STATUS_TPM_DAA_INPUT_DATA0                                                NTStatus      = 0xC0290051
+	STATUS_TPM_DAA_INPUT_DATA1                                                NTStatus      = 0xC0290052
+	STATUS_TPM_DAA_ISSUER_SETTINGS                                            NTStatus      = 0xC0290053
+	STATUS_TPM_DAA_TPM_SETTINGS                                               NTStatus      = 0xC0290054
+	STATUS_TPM_DAA_STAGE                                                      NTStatus      = 0xC0290055
+	STATUS_TPM_DAA_ISSUER_VALIDITY                                            NTStatus      = 0xC0290056
+	STATUS_TPM_DAA_WRONG_W                                                    NTStatus      = 0xC0290057
+	STATUS_TPM_BAD_HANDLE                                                     NTStatus      = 0xC0290058
+	STATUS_TPM_BAD_DELEGATE                                                   NTStatus      = 0xC0290059
+	STATUS_TPM_BADCONTEXT                                                     NTStatus      = 0xC029005A
+	STATUS_TPM_TOOMANYCONTEXTS                                                NTStatus      = 0xC029005B
+	STATUS_TPM_MA_TICKET_SIGNATURE                                            NTStatus      = 0xC029005C
+	STATUS_TPM_MA_DESTINATION                                                 NTStatus      = 0xC029005D
+	STATUS_TPM_MA_SOURCE                                                      NTStatus      = 0xC029005E
+	STATUS_TPM_MA_AUTHORITY                                                   NTStatus      = 0xC029005F
+	STATUS_TPM_PERMANENTEK                                                    NTStatus      = 0xC0290061
+	STATUS_TPM_BAD_SIGNATURE                                                  NTStatus      = 0xC0290062
+	STATUS_TPM_NOCONTEXTSPACE                                                 NTStatus      = 0xC0290063
+	STATUS_TPM_20_E_ASYMMETRIC                                                NTStatus      = 0xC0290081
+	STATUS_TPM_20_E_ATTRIBUTES                                                NTStatus      = 0xC0290082
+	STATUS_TPM_20_E_HASH                                                      NTStatus      = 0xC0290083
+	STATUS_TPM_20_E_VALUE                                                     NTStatus      = 0xC0290084
+	STATUS_TPM_20_E_HIERARCHY                                                 NTStatus      = 0xC0290085
+	STATUS_TPM_20_E_KEY_SIZE                                                  NTStatus      = 0xC0290087
+	STATUS_TPM_20_E_MGF                                                       NTStatus      = 0xC0290088
+	STATUS_TPM_20_E_MODE                                                      NTStatus      = 0xC0290089
+	STATUS_TPM_20_E_TYPE                                                      NTStatus      = 0xC029008A
+	STATUS_TPM_20_E_HANDLE                                                    NTStatus      = 0xC029008B
+	STATUS_TPM_20_E_KDF                                                       NTStatus      = 0xC029008C
+	STATUS_TPM_20_E_RANGE                                                     NTStatus      = 0xC029008D
+	STATUS_TPM_20_E_AUTH_FAIL                                                 NTStatus      = 0xC029008E
+	STATUS_TPM_20_E_NONCE                                                     NTStatus      = 0xC029008F
+	STATUS_TPM_20_E_PP                                                        NTStatus      = 0xC0290090
+	STATUS_TPM_20_E_SCHEME                                                    NTStatus      = 0xC0290092
+	STATUS_TPM_20_E_SIZE                                                      NTStatus      = 0xC0290095
+	STATUS_TPM_20_E_SYMMETRIC                                                 NTStatus      = 0xC0290096
+	STATUS_TPM_20_E_TAG                                                       NTStatus      = 0xC0290097
+	STATUS_TPM_20_E_SELECTOR                                                  NTStatus      = 0xC0290098
+	STATUS_TPM_20_E_INSUFFICIENT                                              NTStatus      = 0xC029009A
+	STATUS_TPM_20_E_SIGNATURE                                                 NTStatus      = 0xC029009B
+	STATUS_TPM_20_E_KEY                                                       NTStatus      = 0xC029009C
+	STATUS_TPM_20_E_POLICY_FAIL                                               NTStatus      = 0xC029009D
+	STATUS_TPM_20_E_INTEGRITY                                                 NTStatus      = 0xC029009F
+	STATUS_TPM_20_E_TICKET                                                    NTStatus      = 0xC02900A0
+	STATUS_TPM_20_E_RESERVED_BITS                                             NTStatus      = 0xC02900A1
+	STATUS_TPM_20_E_BAD_AUTH                                                  NTStatus      = 0xC02900A2
+	STATUS_TPM_20_E_EXPIRED                                                   NTStatus      = 0xC02900A3
+	STATUS_TPM_20_E_POLICY_CC                                                 NTStatus      = 0xC02900A4
+	STATUS_TPM_20_E_BINDING                                                   NTStatus      = 0xC02900A5
+	STATUS_TPM_20_E_CURVE                                                     NTStatus      = 0xC02900A6
+	STATUS_TPM_20_E_ECC_POINT                                                 NTStatus      = 0xC02900A7
+	STATUS_TPM_20_E_INITIALIZE                                                NTStatus      = 0xC0290100
+	STATUS_TPM_20_E_FAILURE                                                   NTStatus      = 0xC0290101
+	STATUS_TPM_20_E_SEQUENCE                                                  NTStatus      = 0xC0290103
+	STATUS_TPM_20_E_PRIVATE                                                   NTStatus      = 0xC029010B
+	STATUS_TPM_20_E_HMAC                                                      NTStatus      = 0xC0290119
+	STATUS_TPM_20_E_DISABLED                                                  NTStatus      = 0xC0290120
+	STATUS_TPM_20_E_EXCLUSIVE                                                 NTStatus      = 0xC0290121
+	STATUS_TPM_20_E_ECC_CURVE                                                 NTStatus      = 0xC0290123
+	STATUS_TPM_20_E_AUTH_TYPE                                                 NTStatus      = 0xC0290124
+	STATUS_TPM_20_E_AUTH_MISSING                                              NTStatus      = 0xC0290125
+	STATUS_TPM_20_E_POLICY                                                    NTStatus      = 0xC0290126
+	STATUS_TPM_20_E_PCR                                                       NTStatus      = 0xC0290127
+	STATUS_TPM_20_E_PCR_CHANGED                                               NTStatus      = 0xC0290128
+	STATUS_TPM_20_E_UPGRADE                                                   NTStatus      = 0xC029012D
+	STATUS_TPM_20_E_TOO_MANY_CONTEXTS                                         NTStatus      = 0xC029012E
+	STATUS_TPM_20_E_AUTH_UNAVAILABLE                                          NTStatus      = 0xC029012F
+	STATUS_TPM_20_E_REBOOT                                                    NTStatus      = 0xC0290130
+	STATUS_TPM_20_E_UNBALANCED                                                NTStatus      = 0xC0290131
+	STATUS_TPM_20_E_COMMAND_SIZE                                              NTStatus      = 0xC0290142
+	STATUS_TPM_20_E_COMMAND_CODE                                              NTStatus      = 0xC0290143
+	STATUS_TPM_20_E_AUTHSIZE                                                  NTStatus      = 0xC0290144
+	STATUS_TPM_20_E_AUTH_CONTEXT                                              NTStatus      = 0xC0290145
+	STATUS_TPM_20_E_NV_RANGE                                                  NTStatus      = 0xC0290146
+	STATUS_TPM_20_E_NV_SIZE                                                   NTStatus      = 0xC0290147
+	STATUS_TPM_20_E_NV_LOCKED                                                 NTStatus      = 0xC0290148
+	STATUS_TPM_20_E_NV_AUTHORIZATION                                          NTStatus      = 0xC0290149
+	STATUS_TPM_20_E_NV_UNINITIALIZED                                          NTStatus      = 0xC029014A
+	STATUS_TPM_20_E_NV_SPACE                                                  NTStatus      = 0xC029014B
+	STATUS_TPM_20_E_NV_DEFINED                                                NTStatus      = 0xC029014C
+	STATUS_TPM_20_E_BAD_CONTEXT                                               NTStatus      = 0xC0290150
+	STATUS_TPM_20_E_CPHASH                                                    NTStatus      = 0xC0290151
+	STATUS_TPM_20_E_PARENT                                                    NTStatus      = 0xC0290152
+	STATUS_TPM_20_E_NEEDS_TEST                                                NTStatus      = 0xC0290153
+	STATUS_TPM_20_E_NO_RESULT                                                 NTStatus      = 0xC0290154
+	STATUS_TPM_20_E_SENSITIVE                                                 NTStatus      = 0xC0290155
+	STATUS_TPM_COMMAND_BLOCKED                                                NTStatus      = 0xC0290400
+	STATUS_TPM_INVALID_HANDLE                                                 NTStatus      = 0xC0290401
+	STATUS_TPM_DUPLICATE_VHANDLE                                              NTStatus      = 0xC0290402
+	STATUS_TPM_EMBEDDED_COMMAND_BLOCKED                                       NTStatus      = 0xC0290403
+	STATUS_TPM_EMBEDDED_COMMAND_UNSUPPORTED                                   NTStatus      = 0xC0290404
+	STATUS_TPM_RETRY                                                          NTStatus      = 0xC0290800
+	STATUS_TPM_NEEDS_SELFTEST                                                 NTStatus      = 0xC0290801
+	STATUS_TPM_DOING_SELFTEST                                                 NTStatus      = 0xC0290802
+	STATUS_TPM_DEFEND_LOCK_RUNNING                                            NTStatus      = 0xC0290803
+	STATUS_TPM_COMMAND_CANCELED                                               NTStatus      = 0xC0291001
+	STATUS_TPM_TOO_MANY_CONTEXTS                                              NTStatus      = 0xC0291002
+	STATUS_TPM_NOT_FOUND                                                      NTStatus      = 0xC0291003
+	STATUS_TPM_ACCESS_DENIED                                                  NTStatus      = 0xC0291004
+	STATUS_TPM_INSUFFICIENT_BUFFER                                            NTStatus      = 0xC0291005
+	STATUS_TPM_PPI_FUNCTION_UNSUPPORTED                                       NTStatus      = 0xC0291006
+	STATUS_PCP_ERROR_MASK                                                     NTStatus      = 0xC0292000
+	STATUS_PCP_DEVICE_NOT_READY                                               NTStatus      = 0xC0292001
+	STATUS_PCP_INVALID_HANDLE                                                 NTStatus      = 0xC0292002
+	STATUS_PCP_INVALID_PARAMETER                                              NTStatus      = 0xC0292003
+	STATUS_PCP_FLAG_NOT_SUPPORTED                                             NTStatus      = 0xC0292004
+	STATUS_PCP_NOT_SUPPORTED                                                  NTStatus      = 0xC0292005
+	STATUS_PCP_BUFFER_TOO_SMALL                                               NTStatus      = 0xC0292006
+	STATUS_PCP_INTERNAL_ERROR                                                 NTStatus      = 0xC0292007
+	STATUS_PCP_AUTHENTICATION_FAILED                                          NTStatus      = 0xC0292008
+	STATUS_PCP_AUTHENTICATION_IGNORED                                         NTStatus      = 0xC0292009
+	STATUS_PCP_POLICY_NOT_FOUND                                               NTStatus      = 0xC029200A
+	STATUS_PCP_PROFILE_NOT_FOUND                                              NTStatus      = 0xC029200B
+	STATUS_PCP_VALIDATION_FAILED                                              NTStatus      = 0xC029200C
+	STATUS_PCP_DEVICE_NOT_FOUND                                               NTStatus      = 0xC029200D
+	STATUS_PCP_WRONG_PARENT                                                   NTStatus      = 0xC029200E
+	STATUS_PCP_KEY_NOT_LOADED                                                 NTStatus      = 0xC029200F
+	STATUS_PCP_NO_KEY_CERTIFICATION                                           NTStatus      = 0xC0292010
+	STATUS_PCP_KEY_NOT_FINALIZED                                              NTStatus      = 0xC0292011
+	STATUS_PCP_ATTESTATION_CHALLENGE_NOT_SET                                  NTStatus      = 0xC0292012
+	STATUS_PCP_NOT_PCR_BOUND                                                  NTStatus      = 0xC0292013
+	STATUS_PCP_KEY_ALREADY_FINALIZED                                          NTStatus      = 0xC0292014
+	STATUS_PCP_KEY_USAGE_POLICY_NOT_SUPPORTED                                 NTStatus      = 0xC0292015
+	STATUS_PCP_KEY_USAGE_POLICY_INVALID                                       NTStatus      = 0xC0292016
+	STATUS_PCP_SOFT_KEY_ERROR                                                 NTStatus      = 0xC0292017
+	STATUS_PCP_KEY_NOT_AUTHENTICATED                                          NTStatus      = 0xC0292018
+	STATUS_PCP_KEY_NOT_AIK                                                    NTStatus      = 0xC0292019
+	STATUS_PCP_KEY_NOT_SIGNING_KEY                                            NTStatus      = 0xC029201A
+	STATUS_PCP_LOCKED_OUT                                                     NTStatus      = 0xC029201B
+	STATUS_PCP_CLAIM_TYPE_NOT_SUPPORTED                                       NTStatus      = 0xC029201C
+	STATUS_PCP_TPM_VERSION_NOT_SUPPORTED                                      NTStatus      = 0xC029201D
+	STATUS_PCP_BUFFER_LENGTH_MISMATCH                                         NTStatus      = 0xC029201E
+	STATUS_PCP_IFX_RSA_KEY_CREATION_BLOCKED                                   NTStatus      = 0xC029201F
+	STATUS_PCP_TICKET_MISSING                                                 NTStatus      = 0xC0292020
+	STATUS_PCP_RAW_POLICY_NOT_SUPPORTED                                       NTStatus      = 0xC0292021
+	STATUS_PCP_KEY_HANDLE_INVALIDATED                                         NTStatus      = 0xC0292022
+	STATUS_PCP_UNSUPPORTED_PSS_SALT                                           NTStatus      = 0x40292023
+	STATUS_RTPM_CONTEXT_CONTINUE                                              NTStatus      = 0x00293000
+	STATUS_RTPM_CONTEXT_COMPLETE                                              NTStatus      = 0x00293001
+	STATUS_RTPM_NO_RESULT                                                     NTStatus      = 0xC0293002
+	STATUS_RTPM_PCR_READ_INCOMPLETE                                           NTStatus      = 0xC0293003
+	STATUS_RTPM_INVALID_CONTEXT                                               NTStatus      = 0xC0293004
+	STATUS_RTPM_UNSUPPORTED_CMD                                               NTStatus      = 0xC0293005
+	STATUS_TPM_ZERO_EXHAUST_ENABLED                                           NTStatus      = 0xC0294000
+	STATUS_HV_INVALID_HYPERCALL_CODE                                          NTStatus      = 0xC0350002
+	STATUS_HV_INVALID_HYPERCALL_INPUT                                         NTStatus      = 0xC0350003
+	STATUS_HV_INVALID_ALIGNMENT                                               NTStatus      = 0xC0350004
+	STATUS_HV_INVALID_PARAMETER                                               NTStatus      = 0xC0350005
+	STATUS_HV_ACCESS_DENIED                                                   NTStatus      = 0xC0350006
+	STATUS_HV_INVALID_PARTITION_STATE                                         NTStatus      = 0xC0350007
+	STATUS_HV_OPERATION_DENIED                                                NTStatus      = 0xC0350008
+	STATUS_HV_UNKNOWN_PROPERTY                                                NTStatus      = 0xC0350009
+	STATUS_HV_PROPERTY_VALUE_OUT_OF_RANGE                                     NTStatus      = 0xC035000A
+	STATUS_HV_INSUFFICIENT_MEMORY                                             NTStatus      = 0xC035000B
+	STATUS_HV_PARTITION_TOO_DEEP                                              NTStatus      = 0xC035000C
+	STATUS_HV_INVALID_PARTITION_ID                                            NTStatus      = 0xC035000D
+	STATUS_HV_INVALID_VP_INDEX                                                NTStatus      = 0xC035000E
+	STATUS_HV_INVALID_PORT_ID                                                 NTStatus      = 0xC0350011
+	STATUS_HV_INVALID_CONNECTION_ID                                           NTStatus      = 0xC0350012
+	STATUS_HV_INSUFFICIENT_BUFFERS                                            NTStatus      = 0xC0350013
+	STATUS_HV_NOT_ACKNOWLEDGED                                                NTStatus      = 0xC0350014
+	STATUS_HV_INVALID_VP_STATE                                                NTStatus      = 0xC0350015
+	STATUS_HV_ACKNOWLEDGED                                                    NTStatus      = 0xC0350016
+	STATUS_HV_INVALID_SAVE_RESTORE_STATE                                      NTStatus      = 0xC0350017
+	STATUS_HV_INVALID_SYNIC_STATE                                             NTStatus      = 0xC0350018
+	STATUS_HV_OBJECT_IN_USE                                                   NTStatus      = 0xC0350019
+	STATUS_HV_INVALID_PROXIMITY_DOMAIN_INFO                                   NTStatus      = 0xC035001A
+	STATUS_HV_NO_DATA                                                         NTStatus      = 0xC035001B
+	STATUS_HV_INACTIVE                                                        NTStatus      = 0xC035001C
+	STATUS_HV_NO_RESOURCES                                                    NTStatus      = 0xC035001D
+	STATUS_HV_FEATURE_UNAVAILABLE                                             NTStatus      = 0xC035001E
+	STATUS_HV_INSUFFICIENT_BUFFER                                             NTStatus      = 0xC0350033
+	STATUS_HV_INSUFFICIENT_DEVICE_DOMAINS                                     NTStatus      = 0xC0350038
+	STATUS_HV_CPUID_FEATURE_VALIDATION_ERROR                                  NTStatus      = 0xC035003C
+	STATUS_HV_CPUID_XSAVE_FEATURE_VALIDATION_ERROR                            NTStatus      = 0xC035003D
+	STATUS_HV_PROCESSOR_STARTUP_TIMEOUT                                       NTStatus      = 0xC035003E
+	STATUS_HV_SMX_ENABLED                                                     NTStatus      = 0xC035003F
+	STATUS_HV_INVALID_LP_INDEX                                                NTStatus      = 0xC0350041
+	STATUS_HV_INVALID_REGISTER_VALUE                                          NTStatus      = 0xC0350050
+	STATUS_HV_INVALID_VTL_STATE                                               NTStatus      = 0xC0350051
+	STATUS_HV_NX_NOT_DETECTED                                                 NTStatus      = 0xC0350055
+	STATUS_HV_INVALID_DEVICE_ID                                               NTStatus      = 0xC0350057
+	STATUS_HV_INVALID_DEVICE_STATE                                            NTStatus      = 0xC0350058
+	STATUS_HV_PENDING_PAGE_REQUESTS                                           NTStatus      = 0x00350059
+	STATUS_HV_PAGE_REQUEST_INVALID                                            NTStatus      = 0xC0350060
+	STATUS_HV_INVALID_CPU_GROUP_ID                                            NTStatus      = 0xC035006F
+	STATUS_HV_INVALID_CPU_GROUP_STATE                                         NTStatus      = 0xC0350070
+	STATUS_HV_OPERATION_FAILED                                                NTStatus      = 0xC0350071
+	STATUS_HV_NOT_ALLOWED_WITH_NESTED_VIRT_ACTIVE                             NTStatus      = 0xC0350072
+	STATUS_HV_INSUFFICIENT_ROOT_MEMORY                                        NTStatus      = 0xC0350073
+	STATUS_HV_NOT_PRESENT                                                     NTStatus      = 0xC0351000
+	STATUS_VID_DUPLICATE_HANDLER                                              NTStatus      = 0xC0370001
+	STATUS_VID_TOO_MANY_HANDLERS                                              NTStatus      = 0xC0370002
+	STATUS_VID_QUEUE_FULL                                                     NTStatus      = 0xC0370003
+	STATUS_VID_HANDLER_NOT_PRESENT                                            NTStatus      = 0xC0370004
+	STATUS_VID_INVALID_OBJECT_NAME                                            NTStatus      = 0xC0370005
+	STATUS_VID_PARTITION_NAME_TOO_LONG                                        NTStatus      = 0xC0370006
+	STATUS_VID_MESSAGE_QUEUE_NAME_TOO_LONG                                    NTStatus      = 0xC0370007
+	STATUS_VID_PARTITION_ALREADY_EXISTS                                       NTStatus      = 0xC0370008
+	STATUS_VID_PARTITION_DOES_NOT_EXIST                                       NTStatus      = 0xC0370009
+	STATUS_VID_PARTITION_NAME_NOT_FOUND                                       NTStatus      = 0xC037000A
+	STATUS_VID_MESSAGE_QUEUE_ALREADY_EXISTS                                   NTStatus      = 0xC037000B
+	STATUS_VID_EXCEEDED_MBP_ENTRY_MAP_LIMIT                                   NTStatus      = 0xC037000C
+	STATUS_VID_MB_STILL_REFERENCED                                            NTStatus      = 0xC037000D
+	STATUS_VID_CHILD_GPA_PAGE_SET_CORRUPTED                                   NTStatus      = 0xC037000E
+	STATUS_VID_INVALID_NUMA_SETTINGS                                          NTStatus      = 0xC037000F
+	STATUS_VID_INVALID_NUMA_NODE_INDEX                                        NTStatus      = 0xC0370010
+	STATUS_VID_NOTIFICATION_QUEUE_ALREADY_ASSOCIATED                          NTStatus      = 0xC0370011
+	STATUS_VID_INVALID_MEMORY_BLOCK_HANDLE                                    NTStatus      = 0xC0370012
+	STATUS_VID_PAGE_RANGE_OVERFLOW                                            NTStatus      = 0xC0370013
+	STATUS_VID_INVALID_MESSAGE_QUEUE_HANDLE                                   NTStatus      = 0xC0370014
+	STATUS_VID_INVALID_GPA_RANGE_HANDLE                                       NTStatus      = 0xC0370015
+	STATUS_VID_NO_MEMORY_BLOCK_NOTIFICATION_QUEUE                             NTStatus      = 0xC0370016
+	STATUS_VID_MEMORY_BLOCK_LOCK_COUNT_EXCEEDED                               NTStatus      = 0xC0370017
+	STATUS_VID_INVALID_PPM_HANDLE                                             NTStatus      = 0xC0370018
+	STATUS_VID_MBPS_ARE_LOCKED                                                NTStatus      = 0xC0370019
+	STATUS_VID_MESSAGE_QUEUE_CLOSED                                           NTStatus      = 0xC037001A
+	STATUS_VID_VIRTUAL_PROCESSOR_LIMIT_EXCEEDED                               NTStatus      = 0xC037001B
+	STATUS_VID_STOP_PENDING                                                   NTStatus      = 0xC037001C
+	STATUS_VID_INVALID_PROCESSOR_STATE                                        NTStatus      = 0xC037001D
+	STATUS_VID_EXCEEDED_KM_CONTEXT_COUNT_LIMIT                                NTStatus      = 0xC037001E
+	STATUS_VID_KM_INTERFACE_ALREADY_INITIALIZED                               NTStatus      = 0xC037001F
+	STATUS_VID_MB_PROPERTY_ALREADY_SET_RESET                                  NTStatus      = 0xC0370020
+	STATUS_VID_MMIO_RANGE_DESTROYED                                           NTStatus      = 0xC0370021
+	STATUS_VID_INVALID_CHILD_GPA_PAGE_SET                                     NTStatus      = 0xC0370022
+	STATUS_VID_RESERVE_PAGE_SET_IS_BEING_USED                                 NTStatus      = 0xC0370023
+	STATUS_VID_RESERVE_PAGE_SET_TOO_SMALL                                     NTStatus      = 0xC0370024
+	STATUS_VID_MBP_ALREADY_LOCKED_USING_RESERVED_PAGE                         NTStatus      = 0xC0370025
+	STATUS_VID_MBP_COUNT_EXCEEDED_LIMIT                                       NTStatus      = 0xC0370026
+	STATUS_VID_SAVED_STATE_CORRUPT                                            NTStatus      = 0xC0370027
+	STATUS_VID_SAVED_STATE_UNRECOGNIZED_ITEM                                  NTStatus      = 0xC0370028
+	STATUS_VID_SAVED_STATE_INCOMPATIBLE                                       NTStatus      = 0xC0370029
+	STATUS_VID_VTL_ACCESS_DENIED                                              NTStatus      = 0xC037002A
+	STATUS_VID_REMOTE_NODE_PARENT_GPA_PAGES_USED                              NTStatus      = 0x80370001
+	STATUS_IPSEC_BAD_SPI                                                      NTStatus      = 0xC0360001
+	STATUS_IPSEC_SA_LIFETIME_EXPIRED                                          NTStatus      = 0xC0360002
+	STATUS_IPSEC_WRONG_SA                                                     NTStatus      = 0xC0360003
+	STATUS_IPSEC_REPLAY_CHECK_FAILED                                          NTStatus      = 0xC0360004
+	STATUS_IPSEC_INVALID_PACKET                                               NTStatus      = 0xC0360005
+	STATUS_IPSEC_INTEGRITY_CHECK_FAILED                                       NTStatus      = 0xC0360006
+	STATUS_IPSEC_CLEAR_TEXT_DROP                                              NTStatus      = 0xC0360007
+	STATUS_IPSEC_AUTH_FIREWALL_DROP                                           NTStatus      = 0xC0360008
+	STATUS_IPSEC_THROTTLE_DROP                                                NTStatus      = 0xC0360009
+	STATUS_IPSEC_DOSP_BLOCK                                                   NTStatus      = 0xC0368000
+	STATUS_IPSEC_DOSP_RECEIVED_MULTICAST                                      NTStatus      = 0xC0368001
+	STATUS_IPSEC_DOSP_INVALID_PACKET                                          NTStatus      = 0xC0368002
+	STATUS_IPSEC_DOSP_STATE_LOOKUP_FAILED                                     NTStatus      = 0xC0368003
+	STATUS_IPSEC_DOSP_MAX_ENTRIES                                             NTStatus      = 0xC0368004
+	STATUS_IPSEC_DOSP_KEYMOD_NOT_ALLOWED                                      NTStatus      = 0xC0368005
+	STATUS_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES                             NTStatus      = 0xC0368006
+	STATUS_VOLMGR_INCOMPLETE_REGENERATION                                     NTStatus      = 0x80380001
+	STATUS_VOLMGR_INCOMPLETE_DISK_MIGRATION                                   NTStatus      = 0x80380002
+	STATUS_VOLMGR_DATABASE_FULL                                               NTStatus      = 0xC0380001
+	STATUS_VOLMGR_DISK_CONFIGURATION_CORRUPTED                                NTStatus      = 0xC0380002
+	STATUS_VOLMGR_DISK_CONFIGURATION_NOT_IN_SYNC                              NTStatus      = 0xC0380003
+	STATUS_VOLMGR_PACK_CONFIG_UPDATE_FAILED                                   NTStatus      = 0xC0380004
+	STATUS_VOLMGR_DISK_CONTAINS_NON_SIMPLE_VOLUME                             NTStatus      = 0xC0380005
+	STATUS_VOLMGR_DISK_DUPLICATE                                              NTStatus      = 0xC0380006
+	STATUS_VOLMGR_DISK_DYNAMIC                                                NTStatus      = 0xC0380007
+	STATUS_VOLMGR_DISK_ID_INVALID                                             NTStatus      = 0xC0380008
+	STATUS_VOLMGR_DISK_INVALID                                                NTStatus      = 0xC0380009
+	STATUS_VOLMGR_DISK_LAST_VOTER                                             NTStatus      = 0xC038000A
+	STATUS_VOLMGR_DISK_LAYOUT_INVALID                                         NTStatus      = 0xC038000B
+	STATUS_VOLMGR_DISK_LAYOUT_NON_BASIC_BETWEEN_BASIC_PARTITIONS              NTStatus      = 0xC038000C
+	STATUS_VOLMGR_DISK_LAYOUT_NOT_CYLINDER_ALIGNED                            NTStatus      = 0xC038000D
+	STATUS_VOLMGR_DISK_LAYOUT_PARTITIONS_TOO_SMALL                            NTStatus      = 0xC038000E
+	STATUS_VOLMGR_DISK_LAYOUT_PRIMARY_BETWEEN_LOGICAL_PARTITIONS              NTStatus      = 0xC038000F
+	STATUS_VOLMGR_DISK_LAYOUT_TOO_MANY_PARTITIONS                             NTStatus      = 0xC0380010
+	STATUS_VOLMGR_DISK_MISSING                                                NTStatus      = 0xC0380011
+	STATUS_VOLMGR_DISK_NOT_EMPTY                                              NTStatus      = 0xC0380012
+	STATUS_VOLMGR_DISK_NOT_ENOUGH_SPACE                                       NTStatus      = 0xC0380013
+	STATUS_VOLMGR_DISK_REVECTORING_FAILED                                     NTStatus      = 0xC0380014
+	STATUS_VOLMGR_DISK_SECTOR_SIZE_INVALID                                    NTStatus      = 0xC0380015
+	STATUS_VOLMGR_DISK_SET_NOT_CONTAINED                                      NTStatus      = 0xC0380016
+	STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_MEMBERS                               NTStatus      = 0xC0380017
+	STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_PLEXES                                NTStatus      = 0xC0380018
+	STATUS_VOLMGR_DYNAMIC_DISK_NOT_SUPPORTED                                  NTStatus      = 0xC0380019
+	STATUS_VOLMGR_EXTENT_ALREADY_USED                                         NTStatus      = 0xC038001A
+	STATUS_VOLMGR_EXTENT_NOT_CONTIGUOUS                                       NTStatus      = 0xC038001B
+	STATUS_VOLMGR_EXTENT_NOT_IN_PUBLIC_REGION                                 NTStatus      = 0xC038001C
+	STATUS_VOLMGR_EXTENT_NOT_SECTOR_ALIGNED                                   NTStatus      = 0xC038001D
+	STATUS_VOLMGR_EXTENT_OVERLAPS_EBR_PARTITION                               NTStatus      = 0xC038001E
+	STATUS_VOLMGR_EXTENT_VOLUME_LENGTHS_DO_NOT_MATCH                          NTStatus      = 0xC038001F
+	STATUS_VOLMGR_FAULT_TOLERANT_NOT_SUPPORTED                                NTStatus      = 0xC0380020
+	STATUS_VOLMGR_INTERLEAVE_LENGTH_INVALID                                   NTStatus      = 0xC0380021
+	STATUS_VOLMGR_MAXIMUM_REGISTERED_USERS                                    NTStatus      = 0xC0380022
+	STATUS_VOLMGR_MEMBER_IN_SYNC                                              NTStatus      = 0xC0380023
+	STATUS_VOLMGR_MEMBER_INDEX_DUPLICATE                                      NTStatus      = 0xC0380024
+	STATUS_VOLMGR_MEMBER_INDEX_INVALID                                        NTStatus      = 0xC0380025
+	STATUS_VOLMGR_MEMBER_MISSING                                              NTStatus      = 0xC0380026
+	STATUS_VOLMGR_MEMBER_NOT_DETACHED                                         NTStatus      = 0xC0380027
+	STATUS_VOLMGR_MEMBER_REGENERATING                                         NTStatus      = 0xC0380028
+	STATUS_VOLMGR_ALL_DISKS_FAILED                                            NTStatus      = 0xC0380029
+	STATUS_VOLMGR_NO_REGISTERED_USERS                                         NTStatus      = 0xC038002A
+	STATUS_VOLMGR_NO_SUCH_USER                                                NTStatus      = 0xC038002B
+	STATUS_VOLMGR_NOTIFICATION_RESET                                          NTStatus      = 0xC038002C
+	STATUS_VOLMGR_NUMBER_OF_MEMBERS_INVALID                                   NTStatus      = 0xC038002D
+	STATUS_VOLMGR_NUMBER_OF_PLEXES_INVALID                                    NTStatus      = 0xC038002E
+	STATUS_VOLMGR_PACK_DUPLICATE                                              NTStatus      = 0xC038002F
+	STATUS_VOLMGR_PACK_ID_INVALID                                             NTStatus      = 0xC0380030
+	STATUS_VOLMGR_PACK_INVALID                                                NTStatus      = 0xC0380031
+	STATUS_VOLMGR_PACK_NAME_INVALID                                           NTStatus      = 0xC0380032
+	STATUS_VOLMGR_PACK_OFFLINE                                                NTStatus      = 0xC0380033
+	STATUS_VOLMGR_PACK_HAS_QUORUM                                             NTStatus      = 0xC0380034
+	STATUS_VOLMGR_PACK_WITHOUT_QUORUM                                         NTStatus      = 0xC0380035
+	STATUS_VOLMGR_PARTITION_STYLE_INVALID                                     NTStatus      = 0xC0380036
+	STATUS_VOLMGR_PARTITION_UPDATE_FAILED                                     NTStatus      = 0xC0380037
+	STATUS_VOLMGR_PLEX_IN_SYNC                                                NTStatus      = 0xC0380038
+	STATUS_VOLMGR_PLEX_INDEX_DUPLICATE                                        NTStatus      = 0xC0380039
+	STATUS_VOLMGR_PLEX_INDEX_INVALID                                          NTStatus      = 0xC038003A
+	STATUS_VOLMGR_PLEX_LAST_ACTIVE                                            NTStatus      = 0xC038003B
+	STATUS_VOLMGR_PLEX_MISSING                                                NTStatus      = 0xC038003C
+	STATUS_VOLMGR_PLEX_REGENERATING                                           NTStatus      = 0xC038003D
+	STATUS_VOLMGR_PLEX_TYPE_INVALID                                           NTStatus      = 0xC038003E
+	STATUS_VOLMGR_PLEX_NOT_RAID5                                              NTStatus      = 0xC038003F
+	STATUS_VOLMGR_PLEX_NOT_SIMPLE                                             NTStatus      = 0xC0380040
+	STATUS_VOLMGR_STRUCTURE_SIZE_INVALID                                      NTStatus      = 0xC0380041
+	STATUS_VOLMGR_TOO_MANY_NOTIFICATION_REQUESTS                              NTStatus      = 0xC0380042
+	STATUS_VOLMGR_TRANSACTION_IN_PROGRESS                                     NTStatus      = 0xC0380043
+	STATUS_VOLMGR_UNEXPECTED_DISK_LAYOUT_CHANGE                               NTStatus      = 0xC0380044
+	STATUS_VOLMGR_VOLUME_CONTAINS_MISSING_DISK                                NTStatus      = 0xC0380045
+	STATUS_VOLMGR_VOLUME_ID_INVALID                                           NTStatus      = 0xC0380046
+	STATUS_VOLMGR_VOLUME_LENGTH_INVALID                                       NTStatus      = 0xC0380047
+	STATUS_VOLMGR_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE                      NTStatus      = 0xC0380048
+	STATUS_VOLMGR_VOLUME_NOT_MIRRORED                                         NTStatus      = 0xC0380049
+	STATUS_VOLMGR_VOLUME_NOT_RETAINED                                         NTStatus      = 0xC038004A
+	STATUS_VOLMGR_VOLUME_OFFLINE                                              NTStatus      = 0xC038004B
+	STATUS_VOLMGR_VOLUME_RETAINED                                             NTStatus      = 0xC038004C
+	STATUS_VOLMGR_NUMBER_OF_EXTENTS_INVALID                                   NTStatus      = 0xC038004D
+	STATUS_VOLMGR_DIFFERENT_SECTOR_SIZE                                       NTStatus      = 0xC038004E
+	STATUS_VOLMGR_BAD_BOOT_DISK                                               NTStatus      = 0xC038004F
+	STATUS_VOLMGR_PACK_CONFIG_OFFLINE                                         NTStatus      = 0xC0380050
+	STATUS_VOLMGR_PACK_CONFIG_ONLINE                                          NTStatus      = 0xC0380051
+	STATUS_VOLMGR_NOT_PRIMARY_PACK                                            NTStatus      = 0xC0380052
+	STATUS_VOLMGR_PACK_LOG_UPDATE_FAILED                                      NTStatus      = 0xC0380053
+	STATUS_VOLMGR_NUMBER_OF_DISKS_IN_PLEX_INVALID                             NTStatus      = 0xC0380054
+	STATUS_VOLMGR_NUMBER_OF_DISKS_IN_MEMBER_INVALID                           NTStatus      = 0xC0380055
+	STATUS_VOLMGR_VOLUME_MIRRORED                                             NTStatus      = 0xC0380056
+	STATUS_VOLMGR_PLEX_NOT_SIMPLE_SPANNED                                     NTStatus      = 0xC0380057
+	STATUS_VOLMGR_NO_VALID_LOG_COPIES                                         NTStatus      = 0xC0380058
+	STATUS_VOLMGR_PRIMARY_PACK_PRESENT                                        NTStatus      = 0xC0380059
+	STATUS_VOLMGR_NUMBER_OF_DISKS_INVALID                                     NTStatus      = 0xC038005A
+	STATUS_VOLMGR_MIRROR_NOT_SUPPORTED                                        NTStatus      = 0xC038005B
+	STATUS_VOLMGR_RAID5_NOT_SUPPORTED                                         NTStatus      = 0xC038005C
+	STATUS_BCD_NOT_ALL_ENTRIES_IMPORTED                                       NTStatus      = 0x80390001
+	STATUS_BCD_TOO_MANY_ELEMENTS                                              NTStatus      = 0xC0390002
+	STATUS_BCD_NOT_ALL_ENTRIES_SYNCHRONIZED                                   NTStatus      = 0x80390003
+	STATUS_VHD_DRIVE_FOOTER_MISSING                                           NTStatus      = 0xC03A0001
+	STATUS_VHD_DRIVE_FOOTER_CHECKSUM_MISMATCH                                 NTStatus      = 0xC03A0002
+	STATUS_VHD_DRIVE_FOOTER_CORRUPT                                           NTStatus      = 0xC03A0003
+	STATUS_VHD_FORMAT_UNKNOWN                                                 NTStatus      = 0xC03A0004
+	STATUS_VHD_FORMAT_UNSUPPORTED_VERSION                                     NTStatus      = 0xC03A0005
+	STATUS_VHD_SPARSE_HEADER_CHECKSUM_MISMATCH                                NTStatus      = 0xC03A0006
+	STATUS_VHD_SPARSE_HEADER_UNSUPPORTED_VERSION                              NTStatus      = 0xC03A0007
+	STATUS_VHD_SPARSE_HEADER_CORRUPT                                          NTStatus      = 0xC03A0008
+	STATUS_VHD_BLOCK_ALLOCATION_FAILURE                                       NTStatus      = 0xC03A0009
+	STATUS_VHD_BLOCK_ALLOCATION_TABLE_CORRUPT                                 NTStatus      = 0xC03A000A
+	STATUS_VHD_INVALID_BLOCK_SIZE                                             NTStatus      = 0xC03A000B
+	STATUS_VHD_BITMAP_MISMATCH                                                NTStatus      = 0xC03A000C
+	STATUS_VHD_PARENT_VHD_NOT_FOUND                                           NTStatus      = 0xC03A000D
+	STATUS_VHD_CHILD_PARENT_ID_MISMATCH                                       NTStatus      = 0xC03A000E
+	STATUS_VHD_CHILD_PARENT_TIMESTAMP_MISMATCH                                NTStatus      = 0xC03A000F
+	STATUS_VHD_METADATA_READ_FAILURE                                          NTStatus      = 0xC03A0010
+	STATUS_VHD_METADATA_WRITE_FAILURE                                         NTStatus      = 0xC03A0011
+	STATUS_VHD_INVALID_SIZE                                                   NTStatus      = 0xC03A0012
+	STATUS_VHD_INVALID_FILE_SIZE                                              NTStatus      = 0xC03A0013
+	STATUS_VIRTDISK_PROVIDER_NOT_FOUND                                        NTStatus      = 0xC03A0014
+	STATUS_VIRTDISK_NOT_VIRTUAL_DISK                                          NTStatus      = 0xC03A0015
+	STATUS_VHD_PARENT_VHD_ACCESS_DENIED                                       NTStatus      = 0xC03A0016
+	STATUS_VHD_CHILD_PARENT_SIZE_MISMATCH                                     NTStatus      = 0xC03A0017
+	STATUS_VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED                              NTStatus      = 0xC03A0018
+	STATUS_VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT                             NTStatus      = 0xC03A0019
+	STATUS_VIRTUAL_DISK_LIMITATION                                            NTStatus      = 0xC03A001A
+	STATUS_VHD_INVALID_TYPE                                                   NTStatus      = 0xC03A001B
+	STATUS_VHD_INVALID_STATE                                                  NTStatus      = 0xC03A001C
+	STATUS_VIRTDISK_UNSUPPORTED_DISK_SECTOR_SIZE                              NTStatus      = 0xC03A001D
+	STATUS_VIRTDISK_DISK_ALREADY_OWNED                                        NTStatus      = 0xC03A001E
+	STATUS_VIRTDISK_DISK_ONLINE_AND_WRITABLE                                  NTStatus      = 0xC03A001F
+	STATUS_CTLOG_TRACKING_NOT_INITIALIZED                                     NTStatus      = 0xC03A0020
+	STATUS_CTLOG_LOGFILE_SIZE_EXCEEDED_MAXSIZE                                NTStatus      = 0xC03A0021
+	STATUS_CTLOG_VHD_CHANGED_OFFLINE                                          NTStatus      = 0xC03A0022
+	STATUS_CTLOG_INVALID_TRACKING_STATE                                       NTStatus      = 0xC03A0023
+	STATUS_CTLOG_INCONSISTENT_TRACKING_FILE                                   NTStatus      = 0xC03A0024
+	STATUS_VHD_METADATA_FULL                                                  NTStatus      = 0xC03A0028
+	STATUS_VHD_INVALID_CHANGE_TRACKING_ID                                     NTStatus      = 0xC03A0029
+	STATUS_VHD_CHANGE_TRACKING_DISABLED                                       NTStatus      = 0xC03A002A
+	STATUS_VHD_MISSING_CHANGE_TRACKING_INFORMATION                            NTStatus      = 0xC03A0030
+	STATUS_VHD_RESIZE_WOULD_TRUNCATE_DATA                                     NTStatus      = 0xC03A0031
+	STATUS_VHD_COULD_NOT_COMPUTE_MINIMUM_VIRTUAL_SIZE                         NTStatus      = 0xC03A0032
+	STATUS_VHD_ALREADY_AT_OR_BELOW_MINIMUM_VIRTUAL_SIZE                       NTStatus      = 0xC03A0033
+	STATUS_QUERY_STORAGE_ERROR                                                NTStatus      = 0x803A0001
+	STATUS_GDI_HANDLE_LEAK                                                    NTStatus      = 0x803F0001
+	STATUS_RKF_KEY_NOT_FOUND                                                  NTStatus      = 0xC0400001
+	STATUS_RKF_DUPLICATE_KEY                                                  NTStatus      = 0xC0400002
+	STATUS_RKF_BLOB_FULL                                                      NTStatus      = 0xC0400003
+	STATUS_RKF_STORE_FULL                                                     NTStatus      = 0xC0400004
+	STATUS_RKF_FILE_BLOCKED                                                   NTStatus      = 0xC0400005
+	STATUS_RKF_ACTIVE_KEY                                                     NTStatus      = 0xC0400006
+	STATUS_RDBSS_RESTART_OPERATION                                            NTStatus      = 0xC0410001
+	STATUS_RDBSS_CONTINUE_OPERATION                                           NTStatus      = 0xC0410002
+	STATUS_RDBSS_POST_OPERATION                                               NTStatus      = 0xC0410003
+	STATUS_RDBSS_RETRY_LOOKUP                                                 NTStatus      = 0xC0410004
+	STATUS_BTH_ATT_INVALID_HANDLE                                             NTStatus      = 0xC0420001
+	STATUS_BTH_ATT_READ_NOT_PERMITTED                                         NTStatus      = 0xC0420002
+	STATUS_BTH_ATT_WRITE_NOT_PERMITTED                                        NTStatus      = 0xC0420003
+	STATUS_BTH_ATT_INVALID_PDU                                                NTStatus      = 0xC0420004
+	STATUS_BTH_ATT_INSUFFICIENT_AUTHENTICATION                                NTStatus      = 0xC0420005
+	STATUS_BTH_ATT_REQUEST_NOT_SUPPORTED                                      NTStatus      = 0xC0420006
+	STATUS_BTH_ATT_INVALID_OFFSET                                             NTStatus      = 0xC0420007
+	STATUS_BTH_ATT_INSUFFICIENT_AUTHORIZATION                                 NTStatus      = 0xC0420008
+	STATUS_BTH_ATT_PREPARE_QUEUE_FULL                                         NTStatus      = 0xC0420009
+	STATUS_BTH_ATT_ATTRIBUTE_NOT_FOUND                                        NTStatus      = 0xC042000A
+	STATUS_BTH_ATT_ATTRIBUTE_NOT_LONG                                         NTStatus      = 0xC042000B
+	STATUS_BTH_ATT_INSUFFICIENT_ENCRYPTION_KEY_SIZE                           NTStatus      = 0xC042000C
+	STATUS_BTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH                             NTStatus      = 0xC042000D
+	STATUS_BTH_ATT_UNLIKELY                                                   NTStatus      = 0xC042000E
+	STATUS_BTH_ATT_INSUFFICIENT_ENCRYPTION                                    NTStatus      = 0xC042000F
+	STATUS_BTH_ATT_UNSUPPORTED_GROUP_TYPE                                     NTStatus      = 0xC0420010
+	STATUS_BTH_ATT_INSUFFICIENT_RESOURCES                                     NTStatus      = 0xC0420011
+	STATUS_BTH_ATT_UNKNOWN_ERROR                                              NTStatus      = 0xC0421000
+	STATUS_SECUREBOOT_ROLLBACK_DETECTED                                       NTStatus      = 0xC0430001
+	STATUS_SECUREBOOT_POLICY_VIOLATION                                        NTStatus      = 0xC0430002
+	STATUS_SECUREBOOT_INVALID_POLICY                                          NTStatus      = 0xC0430003
+	STATUS_SECUREBOOT_POLICY_PUBLISHER_NOT_FOUND                              NTStatus      = 0xC0430004
+	STATUS_SECUREBOOT_POLICY_NOT_SIGNED                                       NTStatus      = 0xC0430005
+	STATUS_SECUREBOOT_NOT_ENABLED                                             NTStatus      = 0x80430006
+	STATUS_SECUREBOOT_FILE_REPLACED                                           NTStatus      = 0xC0430007
+	STATUS_SECUREBOOT_POLICY_NOT_AUTHORIZED                                   NTStatus      = 0xC0430008
+	STATUS_SECUREBOOT_POLICY_UNKNOWN                                          NTStatus      = 0xC0430009
+	STATUS_SECUREBOOT_POLICY_MISSING_ANTIROLLBACKVERSION                      NTStatus      = 0xC043000A
+	STATUS_SECUREBOOT_PLATFORM_ID_MISMATCH                                    NTStatus      = 0xC043000B
+	STATUS_SECUREBOOT_POLICY_ROLLBACK_DETECTED                                NTStatus      = 0xC043000C
+	STATUS_SECUREBOOT_POLICY_UPGRADE_MISMATCH                                 NTStatus      = 0xC043000D
+	STATUS_SECUREBOOT_REQUIRED_POLICY_FILE_MISSING                            NTStatus      = 0xC043000E
+	STATUS_SECUREBOOT_NOT_BASE_POLICY                                         NTStatus      = 0xC043000F
+	STATUS_SECUREBOOT_NOT_SUPPLEMENTAL_POLICY                                 NTStatus      = 0xC0430010
+	STATUS_PLATFORM_MANIFEST_NOT_AUTHORIZED                                   NTStatus      = 0xC0EB0001
+	STATUS_PLATFORM_MANIFEST_INVALID                                          NTStatus      = 0xC0EB0002
+	STATUS_PLATFORM_MANIFEST_FILE_NOT_AUTHORIZED                              NTStatus      = 0xC0EB0003
+	STATUS_PLATFORM_MANIFEST_CATALOG_NOT_AUTHORIZED                           NTStatus      = 0xC0EB0004
+	STATUS_PLATFORM_MANIFEST_BINARY_ID_NOT_FOUND                              NTStatus      = 0xC0EB0005
+	STATUS_PLATFORM_MANIFEST_NOT_ACTIVE                                       NTStatus      = 0xC0EB0006
+	STATUS_PLATFORM_MANIFEST_NOT_SIGNED                                       NTStatus      = 0xC0EB0007
+	STATUS_SYSTEM_INTEGRITY_ROLLBACK_DETECTED                                 NTStatus      = 0xC0E90001
+	STATUS_SYSTEM_INTEGRITY_POLICY_VIOLATION                                  NTStatus      = 0xC0E90002
+	STATUS_SYSTEM_INTEGRITY_INVALID_POLICY                                    NTStatus      = 0xC0E90003
+	STATUS_SYSTEM_INTEGRITY_POLICY_NOT_SIGNED                                 NTStatus      = 0xC0E90004
+	STATUS_SYSTEM_INTEGRITY_TOO_MANY_POLICIES                                 NTStatus      = 0xC0E90005
+	STATUS_SYSTEM_INTEGRITY_SUPPLEMENTAL_POLICY_NOT_AUTHORIZED                NTStatus      = 0xC0E90006
+	STATUS_NO_APPLICABLE_APP_LICENSES_FOUND                                   NTStatus      = 0xC0EA0001
+	STATUS_CLIP_LICENSE_NOT_FOUND                                             NTStatus      = 0xC0EA0002
+	STATUS_CLIP_DEVICE_LICENSE_MISSING                                        NTStatus      = 0xC0EA0003
+	STATUS_CLIP_LICENSE_INVALID_SIGNATURE                                     NTStatus      = 0xC0EA0004
+	STATUS_CLIP_KEYHOLDER_LICENSE_MISSING_OR_INVALID                          NTStatus      = 0xC0EA0005
+	STATUS_CLIP_LICENSE_EXPIRED                                               NTStatus      = 0xC0EA0006
+	STATUS_CLIP_LICENSE_SIGNED_BY_UNKNOWN_SOURCE                              NTStatus      = 0xC0EA0007
+	STATUS_CLIP_LICENSE_NOT_SIGNED                                            NTStatus      = 0xC0EA0008
+	STATUS_CLIP_LICENSE_HARDWARE_ID_OUT_OF_TOLERANCE                          NTStatus      = 0xC0EA0009
+	STATUS_CLIP_LICENSE_DEVICE_ID_MISMATCH                                    NTStatus      = 0xC0EA000A
+	STATUS_AUDIO_ENGINE_NODE_NOT_FOUND                                        NTStatus      = 0xC0440001
+	STATUS_HDAUDIO_EMPTY_CONNECTION_LIST                                      NTStatus      = 0xC0440002
+	STATUS_HDAUDIO_CONNECTION_LIST_NOT_SUPPORTED                              NTStatus      = 0xC0440003
+	STATUS_HDAUDIO_NO_LOGICAL_DEVICES_CREATED                                 NTStatus      = 0xC0440004
+	STATUS_HDAUDIO_NULL_LINKED_LIST_ENTRY                                     NTStatus      = 0xC0440005
+	STATUS_SPACES_REPAIRED                                                    NTStatus      = 0x00E70000
+	STATUS_SPACES_PAUSE                                                       NTStatus      = 0x00E70001
+	STATUS_SPACES_COMPLETE                                                    NTStatus      = 0x00E70002
+	STATUS_SPACES_REDIRECT                                                    NTStatus      = 0x00E70003
+	STATUS_SPACES_FAULT_DOMAIN_TYPE_INVALID                                   NTStatus      = 0xC0E70001
+	STATUS_SPACES_RESILIENCY_TYPE_INVALID                                     NTStatus      = 0xC0E70003
+	STATUS_SPACES_DRIVE_SECTOR_SIZE_INVALID                                   NTStatus      = 0xC0E70004
+	STATUS_SPACES_DRIVE_REDUNDANCY_INVALID                                    NTStatus      = 0xC0E70006
+	STATUS_SPACES_NUMBER_OF_DATA_COPIES_INVALID                               NTStatus      = 0xC0E70007
+	STATUS_SPACES_INTERLEAVE_LENGTH_INVALID                                   NTStatus      = 0xC0E70009
+	STATUS_SPACES_NUMBER_OF_COLUMNS_INVALID                                   NTStatus      = 0xC0E7000A
+	STATUS_SPACES_NOT_ENOUGH_DRIVES                                           NTStatus      = 0xC0E7000B
+	STATUS_SPACES_EXTENDED_ERROR                                              NTStatus      = 0xC0E7000C
+	STATUS_SPACES_PROVISIONING_TYPE_INVALID                                   NTStatus      = 0xC0E7000D
+	STATUS_SPACES_ALLOCATION_SIZE_INVALID                                     NTStatus      = 0xC0E7000E
+	STATUS_SPACES_ENCLOSURE_AWARE_INVALID                                     NTStatus      = 0xC0E7000F
+	STATUS_SPACES_WRITE_CACHE_SIZE_INVALID                                    NTStatus      = 0xC0E70010
+	STATUS_SPACES_NUMBER_OF_GROUPS_INVALID                                    NTStatus      = 0xC0E70011
+	STATUS_SPACES_DRIVE_OPERATIONAL_STATE_INVALID                             NTStatus      = 0xC0E70012
+	STATUS_SPACES_UPDATE_COLUMN_STATE                                         NTStatus      = 0xC0E70013
+	STATUS_SPACES_MAP_REQUIRED                                                NTStatus      = 0xC0E70014
+	STATUS_SPACES_UNSUPPORTED_VERSION                                         NTStatus      = 0xC0E70015
+	STATUS_SPACES_CORRUPT_METADATA                                            NTStatus      = 0xC0E70016
+	STATUS_SPACES_DRT_FULL                                                    NTStatus      = 0xC0E70017
+	STATUS_SPACES_INCONSISTENCY                                               NTStatus      = 0xC0E70018
+	STATUS_SPACES_LOG_NOT_READY                                               NTStatus      = 0xC0E70019
+	STATUS_SPACES_NO_REDUNDANCY                                               NTStatus      = 0xC0E7001A
+	STATUS_SPACES_DRIVE_NOT_READY                                             NTStatus      = 0xC0E7001B
+	STATUS_SPACES_DRIVE_SPLIT                                                 NTStatus      = 0xC0E7001C
+	STATUS_SPACES_DRIVE_LOST_DATA                                             NTStatus      = 0xC0E7001D
+	STATUS_SPACES_ENTRY_INCOMPLETE                                            NTStatus      = 0xC0E7001E
+	STATUS_SPACES_ENTRY_INVALID                                               NTStatus      = 0xC0E7001F
+	STATUS_SPACES_MARK_DIRTY                                                  NTStatus      = 0xC0E70020
+	STATUS_VOLSNAP_BOOTFILE_NOT_VALID                                         NTStatus      = 0xC0500003
+	STATUS_VOLSNAP_ACTIVATION_TIMEOUT                                         NTStatus      = 0xC0500004
+	STATUS_IO_PREEMPTED                                                       NTStatus      = 0xC0510001
+	STATUS_SVHDX_ERROR_STORED                                                 NTStatus      = 0xC05C0000
+	STATUS_SVHDX_ERROR_NOT_AVAILABLE                                          NTStatus      = 0xC05CFF00
+	STATUS_SVHDX_UNIT_ATTENTION_AVAILABLE                                     NTStatus      = 0xC05CFF01
+	STATUS_SVHDX_UNIT_ATTENTION_CAPACITY_DATA_CHANGED                         NTStatus      = 0xC05CFF02
+	STATUS_SVHDX_UNIT_ATTENTION_RESERVATIONS_PREEMPTED                        NTStatus      = 0xC05CFF03
+	STATUS_SVHDX_UNIT_ATTENTION_RESERVATIONS_RELEASED                         NTStatus      = 0xC05CFF04
+	STATUS_SVHDX_UNIT_ATTENTION_REGISTRATIONS_PREEMPTED                       NTStatus      = 0xC05CFF05
+	STATUS_SVHDX_UNIT_ATTENTION_OPERATING_DEFINITION_CHANGED                  NTStatus      = 0xC05CFF06
+	STATUS_SVHDX_RESERVATION_CONFLICT                                         NTStatus      = 0xC05CFF07
+	STATUS_SVHDX_WRONG_FILE_TYPE                                              NTStatus      = 0xC05CFF08
+	STATUS_SVHDX_VERSION_MISMATCH                                             NTStatus      = 0xC05CFF09
+	STATUS_VHD_SHARED                                                         NTStatus      = 0xC05CFF0A
+	STATUS_SVHDX_NO_INITIATOR                                                 NTStatus      = 0xC05CFF0B
+	STATUS_VHDSET_BACKING_STORAGE_NOT_FOUND                                   NTStatus      = 0xC05CFF0C
+	STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP                              NTStatus      = 0xC05D0000
+	STATUS_SMB_BAD_CLUSTER_DIALECT                                            NTStatus      = 0xC05D0001
+	STATUS_SMB_GUEST_LOGON_BLOCKED                                            NTStatus      = 0xC05D0002
+	STATUS_SECCORE_INVALID_COMMAND                                            NTStatus      = 0xC0E80000
+	STATUS_VSM_NOT_INITIALIZED                                                NTStatus      = 0xC0450000
+	STATUS_VSM_DMA_PROTECTION_NOT_IN_USE                                      NTStatus      = 0xC0450001
+	STATUS_APPEXEC_CONDITION_NOT_SATISFIED                                    NTStatus      = 0xC0EC0000
+	STATUS_APPEXEC_HANDLE_INVALIDATED                                         NTStatus      = 0xC0EC0001
+	STATUS_APPEXEC_INVALID_HOST_GENERATION                                    NTStatus      = 0xC0EC0002
+	STATUS_APPEXEC_UNEXPECTED_PROCESS_REGISTRATION                            NTStatus      = 0xC0EC0003
+	STATUS_APPEXEC_INVALID_HOST_STATE                                         NTStatus      = 0xC0EC0004
+	STATUS_APPEXEC_NO_DONOR                                                   NTStatus      = 0xC0EC0005
+	STATUS_APPEXEC_HOST_ID_MISMATCH                                           NTStatus      = 0xC0EC0006
+	STATUS_APPEXEC_UNKNOWN_USER                                               NTStatus      = 0xC0EC0007
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go
index a933c0e..559bc84 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go
+++ b/src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go
@@ -51,6 +51,7 @@
 	modshell32  = NewLazySystemDLL("shell32.dll")
 	moduser32   = NewLazySystemDLL("user32.dll")
 	moduserenv  = NewLazySystemDLL("userenv.dll")
+	modwintrust = NewLazySystemDLL("wintrust.dll")
 	modws2_32   = NewLazySystemDLL("ws2_32.dll")
 	modwtsapi32 = NewLazySystemDLL("wtsapi32.dll")
 
@@ -117,6 +118,7 @@
 	procQueryServiceStatusEx                                 = modadvapi32.NewProc("QueryServiceStatusEx")
 	procRegCloseKey                                          = modadvapi32.NewProc("RegCloseKey")
 	procRegEnumKeyExW                                        = modadvapi32.NewProc("RegEnumKeyExW")
+	procRegNotifyChangeKeyValue                              = modadvapi32.NewProc("RegNotifyChangeKeyValue")
 	procRegOpenKeyExW                                        = modadvapi32.NewProc("RegOpenKeyExW")
 	procRegQueryInfoKeyW                                     = modadvapi32.NewProc("RegQueryInfoKeyW")
 	procRegQueryValueExW                                     = modadvapi32.NewProc("RegQueryValueExW")
@@ -142,13 +144,24 @@
 	procCertCloseStore                                       = modcrypt32.NewProc("CertCloseStore")
 	procCertCreateCertificateContext                         = modcrypt32.NewProc("CertCreateCertificateContext")
 	procCertDeleteCertificateFromStore                       = modcrypt32.NewProc("CertDeleteCertificateFromStore")
+	procCertDuplicateCertificateContext                      = modcrypt32.NewProc("CertDuplicateCertificateContext")
 	procCertEnumCertificatesInStore                          = modcrypt32.NewProc("CertEnumCertificatesInStore")
+	procCertFindCertificateInStore                           = modcrypt32.NewProc("CertFindCertificateInStore")
+	procCertFindChainInStore                                 = modcrypt32.NewProc("CertFindChainInStore")
+	procCertFindExtension                                    = modcrypt32.NewProc("CertFindExtension")
 	procCertFreeCertificateChain                             = modcrypt32.NewProc("CertFreeCertificateChain")
 	procCertFreeCertificateContext                           = modcrypt32.NewProc("CertFreeCertificateContext")
 	procCertGetCertificateChain                              = modcrypt32.NewProc("CertGetCertificateChain")
+	procCertGetNameStringW                                   = modcrypt32.NewProc("CertGetNameStringW")
 	procCertOpenStore                                        = modcrypt32.NewProc("CertOpenStore")
 	procCertOpenSystemStoreW                                 = modcrypt32.NewProc("CertOpenSystemStoreW")
 	procCertVerifyCertificateChainPolicy                     = modcrypt32.NewProc("CertVerifyCertificateChainPolicy")
+	procCryptAcquireCertificatePrivateKey                    = modcrypt32.NewProc("CryptAcquireCertificatePrivateKey")
+	procCryptDecodeObject                                    = modcrypt32.NewProc("CryptDecodeObject")
+	procCryptProtectData                                     = modcrypt32.NewProc("CryptProtectData")
+	procCryptQueryObject                                     = modcrypt32.NewProc("CryptQueryObject")
+	procCryptUnprotectData                                   = modcrypt32.NewProc("CryptUnprotectData")
+	procPFXImportCertStore                                   = modcrypt32.NewProc("PFXImportCertStore")
 	procDnsNameCompare_W                                     = moddnsapi.NewProc("DnsNameCompare_W")
 	procDnsQuery_W                                           = moddnsapi.NewProc("DnsQuery_W")
 	procDnsRecordListFree                                    = moddnsapi.NewProc("DnsRecordListFree")
@@ -159,6 +172,7 @@
 	procCancelIo                                             = modkernel32.NewProc("CancelIo")
 	procCancelIoEx                                           = modkernel32.NewProc("CancelIoEx")
 	procCloseHandle                                          = modkernel32.NewProc("CloseHandle")
+	procConnectNamedPipe                                     = modkernel32.NewProc("ConnectNamedPipe")
 	procCreateDirectoryW                                     = modkernel32.NewProc("CreateDirectoryW")
 	procCreateEventExW                                       = modkernel32.NewProc("CreateEventExW")
 	procCreateEventW                                         = modkernel32.NewProc("CreateEventW")
@@ -169,23 +183,29 @@
 	procCreateJobObjectW                                     = modkernel32.NewProc("CreateJobObjectW")
 	procCreateMutexExW                                       = modkernel32.NewProc("CreateMutexExW")
 	procCreateMutexW                                         = modkernel32.NewProc("CreateMutexW")
+	procCreateNamedPipeW                                     = modkernel32.NewProc("CreateNamedPipeW")
 	procCreatePipe                                           = modkernel32.NewProc("CreatePipe")
 	procCreateProcessW                                       = modkernel32.NewProc("CreateProcessW")
 	procCreateSymbolicLinkW                                  = modkernel32.NewProc("CreateSymbolicLinkW")
 	procCreateToolhelp32Snapshot                             = modkernel32.NewProc("CreateToolhelp32Snapshot")
 	procDefineDosDeviceW                                     = modkernel32.NewProc("DefineDosDeviceW")
 	procDeleteFileW                                          = modkernel32.NewProc("DeleteFileW")
+	procDeleteProcThreadAttributeList                        = modkernel32.NewProc("DeleteProcThreadAttributeList")
 	procDeleteVolumeMountPointW                              = modkernel32.NewProc("DeleteVolumeMountPointW")
 	procDeviceIoControl                                      = modkernel32.NewProc("DeviceIoControl")
 	procDuplicateHandle                                      = modkernel32.NewProc("DuplicateHandle")
 	procExitProcess                                          = modkernel32.NewProc("ExitProcess")
 	procFindClose                                            = modkernel32.NewProc("FindClose")
+	procFindCloseChangeNotification                          = modkernel32.NewProc("FindCloseChangeNotification")
+	procFindFirstChangeNotificationW                         = modkernel32.NewProc("FindFirstChangeNotificationW")
 	procFindFirstFileW                                       = modkernel32.NewProc("FindFirstFileW")
 	procFindFirstVolumeMountPointW                           = modkernel32.NewProc("FindFirstVolumeMountPointW")
 	procFindFirstVolumeW                                     = modkernel32.NewProc("FindFirstVolumeW")
+	procFindNextChangeNotification                           = modkernel32.NewProc("FindNextChangeNotification")
 	procFindNextFileW                                        = modkernel32.NewProc("FindNextFileW")
 	procFindNextVolumeMountPointW                            = modkernel32.NewProc("FindNextVolumeMountPointW")
 	procFindNextVolumeW                                      = modkernel32.NewProc("FindNextVolumeW")
+	procFindResourceW                                        = modkernel32.NewProc("FindResourceW")
 	procFindVolumeClose                                      = modkernel32.NewProc("FindVolumeClose")
 	procFindVolumeMountPointClose                            = modkernel32.NewProc("FindVolumeMountPointClose")
 	procFlushFileBuffers                                     = modkernel32.NewProc("FlushFileBuffers")
@@ -195,6 +215,7 @@
 	procFreeLibrary                                          = modkernel32.NewProc("FreeLibrary")
 	procGenerateConsoleCtrlEvent                             = modkernel32.NewProc("GenerateConsoleCtrlEvent")
 	procGetACP                                               = modkernel32.NewProc("GetACP")
+	procGetCommTimeouts                                      = modkernel32.NewProc("GetCommTimeouts")
 	procGetCommandLineW                                      = modkernel32.NewProc("GetCommandLineW")
 	procGetComputerNameExW                                   = modkernel32.NewProc("GetComputerNameExW")
 	procGetComputerNameW                                     = modkernel32.NewProc("GetComputerNameW")
@@ -221,6 +242,8 @@
 	procGetLongPathNameW                                     = modkernel32.NewProc("GetLongPathNameW")
 	procGetModuleFileNameW                                   = modkernel32.NewProc("GetModuleFileNameW")
 	procGetModuleHandleExW                                   = modkernel32.NewProc("GetModuleHandleExW")
+	procGetNamedPipeHandleStateW                             = modkernel32.NewProc("GetNamedPipeHandleStateW")
+	procGetNamedPipeInfo                                     = modkernel32.NewProc("GetNamedPipeInfo")
 	procGetOverlappedResult                                  = modkernel32.NewProc("GetOverlappedResult")
 	procGetPriorityClass                                     = modkernel32.NewProc("GetPriorityClass")
 	procGetProcAddress                                       = modkernel32.NewProc("GetProcAddress")
@@ -250,12 +273,16 @@
 	procGetVolumePathNameW                                   = modkernel32.NewProc("GetVolumePathNameW")
 	procGetVolumePathNamesForVolumeNameW                     = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW")
 	procGetWindowsDirectoryW                                 = modkernel32.NewProc("GetWindowsDirectoryW")
+	procInitializeProcThreadAttributeList                    = modkernel32.NewProc("InitializeProcThreadAttributeList")
 	procIsWow64Process                                       = modkernel32.NewProc("IsWow64Process")
 	procIsWow64Process2                                      = modkernel32.NewProc("IsWow64Process2")
 	procLoadLibraryExW                                       = modkernel32.NewProc("LoadLibraryExW")
 	procLoadLibraryW                                         = modkernel32.NewProc("LoadLibraryW")
+	procLoadResource                                         = modkernel32.NewProc("LoadResource")
+	procLocalAlloc                                           = modkernel32.NewProc("LocalAlloc")
 	procLocalFree                                            = modkernel32.NewProc("LocalFree")
 	procLockFileEx                                           = modkernel32.NewProc("LockFileEx")
+	procLockResource                                         = modkernel32.NewProc("LockResource")
 	procMapViewOfFile                                        = modkernel32.NewProc("MapViewOfFile")
 	procMoveFileExW                                          = modkernel32.NewProc("MoveFileExW")
 	procMoveFileW                                            = modkernel32.NewProc("MoveFileW")
@@ -270,6 +297,7 @@
 	procProcessIdToSessionId                                 = modkernel32.NewProc("ProcessIdToSessionId")
 	procPulseEvent                                           = modkernel32.NewProc("PulseEvent")
 	procQueryDosDeviceW                                      = modkernel32.NewProc("QueryDosDeviceW")
+	procQueryFullProcessImageNameW                           = modkernel32.NewProc("QueryFullProcessImageNameW")
 	procQueryInformationJobObject                            = modkernel32.NewProc("QueryInformationJobObject")
 	procReadConsoleW                                         = modkernel32.NewProc("ReadConsoleW")
 	procReadDirectoryChangesW                                = modkernel32.NewProc("ReadDirectoryChangesW")
@@ -278,6 +306,7 @@
 	procRemoveDirectoryW                                     = modkernel32.NewProc("RemoveDirectoryW")
 	procResetEvent                                           = modkernel32.NewProc("ResetEvent")
 	procResumeThread                                         = modkernel32.NewProc("ResumeThread")
+	procSetCommTimeouts                                      = modkernel32.NewProc("SetCommTimeouts")
 	procSetConsoleCursorPosition                             = modkernel32.NewProc("SetConsoleCursorPosition")
 	procSetConsoleMode                                       = modkernel32.NewProc("SetConsoleMode")
 	procSetCurrentDirectoryW                                 = modkernel32.NewProc("SetCurrentDirectoryW")
@@ -294,6 +323,7 @@
 	procSetFileTime                                          = modkernel32.NewProc("SetFileTime")
 	procSetHandleInformation                                 = modkernel32.NewProc("SetHandleInformation")
 	procSetInformationJobObject                              = modkernel32.NewProc("SetInformationJobObject")
+	procSetNamedPipeHandleState                              = modkernel32.NewProc("SetNamedPipeHandleState")
 	procSetPriorityClass                                     = modkernel32.NewProc("SetPriorityClass")
 	procSetProcessPriorityBoost                              = modkernel32.NewProc("SetProcessPriorityBoost")
 	procSetProcessShutdownParameters                         = modkernel32.NewProc("SetProcessShutdownParameters")
@@ -301,6 +331,7 @@
 	procSetStdHandle                                         = modkernel32.NewProc("SetStdHandle")
 	procSetVolumeLabelW                                      = modkernel32.NewProc("SetVolumeLabelW")
 	procSetVolumeMountPointW                                 = modkernel32.NewProc("SetVolumeMountPointW")
+	procSizeofResource                                       = modkernel32.NewProc("SizeofResource")
 	procSleepEx                                              = modkernel32.NewProc("SleepEx")
 	procTerminateJobObject                                   = modkernel32.NewProc("TerminateJobObject")
 	procTerminateProcess                                     = modkernel32.NewProc("TerminateProcess")
@@ -308,6 +339,7 @@
 	procThread32Next                                         = modkernel32.NewProc("Thread32Next")
 	procUnlockFileEx                                         = modkernel32.NewProc("UnlockFileEx")
 	procUnmapViewOfFile                                      = modkernel32.NewProc("UnmapViewOfFile")
+	procUpdateProcThreadAttribute                            = modkernel32.NewProc("UpdateProcThreadAttribute")
 	procVirtualAlloc                                         = modkernel32.NewProc("VirtualAlloc")
 	procVirtualFree                                          = modkernel32.NewProc("VirtualFree")
 	procVirtualLock                                          = modkernel32.NewProc("VirtualLock")
@@ -323,11 +355,25 @@
 	procNetApiBufferFree                                     = modnetapi32.NewProc("NetApiBufferFree")
 	procNetGetJoinInformation                                = modnetapi32.NewProc("NetGetJoinInformation")
 	procNetUserGetInfo                                       = modnetapi32.NewProc("NetUserGetInfo")
+	procNtCreateFile                                         = modntdll.NewProc("NtCreateFile")
+	procNtCreateNamedPipeFile                                = modntdll.NewProc("NtCreateNamedPipeFile")
+	procNtQueryInformationProcess                            = modntdll.NewProc("NtQueryInformationProcess")
+	procNtSetInformationProcess                              = modntdll.NewProc("NtSetInformationProcess")
+	procRtlDefaultNpAcl                                      = modntdll.NewProc("RtlDefaultNpAcl")
+	procRtlDosPathNameToNtPathName_U_WithStatus              = modntdll.NewProc("RtlDosPathNameToNtPathName_U_WithStatus")
+	procRtlDosPathNameToRelativeNtPathName_U_WithStatus      = modntdll.NewProc("RtlDosPathNameToRelativeNtPathName_U_WithStatus")
+	procRtlGetCurrentPeb                                     = modntdll.NewProc("RtlGetCurrentPeb")
 	procRtlGetNtVersionNumbers                               = modntdll.NewProc("RtlGetNtVersionNumbers")
 	procRtlGetVersion                                        = modntdll.NewProc("RtlGetVersion")
+	procRtlInitString                                        = modntdll.NewProc("RtlInitString")
+	procRtlInitUnicodeString                                 = modntdll.NewProc("RtlInitUnicodeString")
+	procRtlNtStatusToDosErrorNoTeb                           = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
 	procCLSIDFromString                                      = modole32.NewProc("CLSIDFromString")
 	procCoCreateGuid                                         = modole32.NewProc("CoCreateGuid")
+	procCoGetObject                                          = modole32.NewProc("CoGetObject")
+	procCoInitializeEx                                       = modole32.NewProc("CoInitializeEx")
 	procCoTaskMemFree                                        = modole32.NewProc("CoTaskMemFree")
+	procCoUninitialize                                       = modole32.NewProc("CoUninitialize")
 	procStringFromGUID2                                      = modole32.NewProc("StringFromGUID2")
 	procEnumProcesses                                        = modpsapi.NewProc("EnumProcesses")
 	procSubscribeServiceChangeNotifications                  = modsechost.NewProc("SubscribeServiceChangeNotifications")
@@ -338,19 +384,24 @@
 	procSHGetKnownFolderPath                                 = modshell32.NewProc("SHGetKnownFolderPath")
 	procShellExecuteW                                        = modshell32.NewProc("ShellExecuteW")
 	procExitWindowsEx                                        = moduser32.NewProc("ExitWindowsEx")
+	procGetShellWindow                                       = moduser32.NewProc("GetShellWindow")
+	procGetWindowThreadProcessId                             = moduser32.NewProc("GetWindowThreadProcessId")
 	procMessageBoxW                                          = moduser32.NewProc("MessageBoxW")
 	procCreateEnvironmentBlock                               = moduserenv.NewProc("CreateEnvironmentBlock")
 	procDestroyEnvironmentBlock                              = moduserenv.NewProc("DestroyEnvironmentBlock")
 	procGetUserProfileDirectoryW                             = moduserenv.NewProc("GetUserProfileDirectoryW")
+	procWinVerifyTrustEx                                     = modwintrust.NewProc("WinVerifyTrustEx")
 	procFreeAddrInfoW                                        = modws2_32.NewProc("FreeAddrInfoW")
 	procGetAddrInfoW                                         = modws2_32.NewProc("GetAddrInfoW")
 	procWSACleanup                                           = modws2_32.NewProc("WSACleanup")
 	procWSAEnumProtocolsW                                    = modws2_32.NewProc("WSAEnumProtocolsW")
+	procWSAGetOverlappedResult                               = modws2_32.NewProc("WSAGetOverlappedResult")
 	procWSAIoctl                                             = modws2_32.NewProc("WSAIoctl")
 	procWSARecv                                              = modws2_32.NewProc("WSARecv")
 	procWSARecvFrom                                          = modws2_32.NewProc("WSARecvFrom")
 	procWSASend                                              = modws2_32.NewProc("WSASend")
 	procWSASendTo                                            = modws2_32.NewProc("WSASendTo")
+	procWSASocketW                                           = modws2_32.NewProc("WSASocketW")
 	procWSAStartup                                           = modws2_32.NewProc("WSAStartup")
 	procbind                                                 = modws2_32.NewProc("bind")
 	procclosesocket                                          = modws2_32.NewProc("closesocket")
@@ -931,6 +982,22 @@
 	return
 }
 
+func RegNotifyChangeKeyValue(key Handle, watchSubtree bool, notifyFilter uint32, event Handle, asynchronous bool) (regerrno error) {
+	var _p0 uint32
+	if watchSubtree {
+		_p0 = 1
+	}
+	var _p1 uint32
+	if asynchronous {
+		_p1 = 1
+	}
+	r0, _, _ := syscall.Syscall6(procRegNotifyChangeKeyValue.Addr(), 5, uintptr(key), uintptr(_p0), uintptr(notifyFilter), uintptr(event), uintptr(_p1), 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
 func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) {
 	r0, _, _ := syscall.Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0)
 	if r0 != 0 {
@@ -1163,6 +1230,12 @@
 	return
 }
 
+func CertDuplicateCertificateContext(certContext *CertContext) (dupContext *CertContext) {
+	r0, _, _ := syscall.Syscall(procCertDuplicateCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(certContext)), 0, 0)
+	dupContext = (*CertContext)(unsafe.Pointer(r0))
+	return
+}
+
 func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) {
 	r0, _, e1 := syscall.Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0)
 	context = (*CertContext)(unsafe.Pointer(r0))
@@ -1172,6 +1245,30 @@
 	return
 }
 
+func CertFindCertificateInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevCertContext *CertContext) (cert *CertContext, err error) {
+	r0, _, e1 := syscall.Syscall6(procCertFindCertificateInStore.Addr(), 6, uintptr(store), uintptr(certEncodingType), uintptr(findFlags), uintptr(findType), uintptr(findPara), uintptr(unsafe.Pointer(prevCertContext)))
+	cert = (*CertContext)(unsafe.Pointer(r0))
+	if cert == nil {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func CertFindChainInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevChainContext *CertChainContext) (certchain *CertChainContext, err error) {
+	r0, _, e1 := syscall.Syscall6(procCertFindChainInStore.Addr(), 6, uintptr(store), uintptr(certEncodingType), uintptr(findFlags), uintptr(findType), uintptr(findPara), uintptr(unsafe.Pointer(prevChainContext)))
+	certchain = (*CertChainContext)(unsafe.Pointer(r0))
+	if certchain == nil {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func CertFindExtension(objId *byte, countExtensions uint32, extensions *CertExtension) (ret *CertExtension) {
+	r0, _, _ := syscall.Syscall(procCertFindExtension.Addr(), 3, uintptr(unsafe.Pointer(objId)), uintptr(countExtensions), uintptr(unsafe.Pointer(extensions)))
+	ret = (*CertExtension)(unsafe.Pointer(r0))
+	return
+}
+
 func CertFreeCertificateChain(ctx *CertChainContext) {
 	syscall.Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
 	return
@@ -1193,6 +1290,12 @@
 	return
 }
 
+func CertGetNameString(certContext *CertContext, nameType uint32, flags uint32, typePara unsafe.Pointer, name *uint16, size uint32) (chars uint32) {
+	r0, _, _ := syscall.Syscall6(procCertGetNameStringW.Addr(), 6, uintptr(unsafe.Pointer(certContext)), uintptr(nameType), uintptr(flags), uintptr(typePara), uintptr(unsafe.Pointer(name)), uintptr(size))
+	chars = uint32(r0)
+	return
+}
+
 func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) {
 	r0, _, e1 := syscall.Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0)
 	handle = Handle(r0)
@@ -1219,6 +1322,60 @@
 	return
 }
 
+func CryptAcquireCertificatePrivateKey(cert *CertContext, flags uint32, parameters unsafe.Pointer, cryptProvOrNCryptKey *Handle, keySpec *uint32, callerFreeProvOrNCryptKey *bool) (err error) {
+	var _p0 uint32
+	if *callerFreeProvOrNCryptKey {
+		_p0 = 1
+	}
+	r1, _, e1 := syscall.Syscall6(procCryptAcquireCertificatePrivateKey.Addr(), 6, uintptr(unsafe.Pointer(cert)), uintptr(flags), uintptr(parameters), uintptr(unsafe.Pointer(cryptProvOrNCryptKey)), uintptr(unsafe.Pointer(keySpec)), uintptr(unsafe.Pointer(&_p0)))
+	*callerFreeProvOrNCryptKey = _p0 != 0
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte, lenEncodedBytes uint32, flags uint32, decoded unsafe.Pointer, decodedLen *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall9(procCryptDecodeObject.Addr(), 7, uintptr(encodingType), uintptr(unsafe.Pointer(structType)), uintptr(unsafe.Pointer(encodedBytes)), uintptr(lenEncodedBytes), uintptr(flags), uintptr(decoded), uintptr(unsafe.Pointer(decodedLen)), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) {
+	r1, _, e1 := syscall.Syscall9(procCryptProtectData.Addr(), 7, uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut)), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentTypeFlags uint32, expectedFormatTypeFlags uint32, flags uint32, msgAndCertEncodingType *uint32, contentType *uint32, formatType *uint32, certStore *Handle, msg *Handle, context *unsafe.Pointer) (err error) {
+	r1, _, e1 := syscall.Syscall12(procCryptQueryObject.Addr(), 11, uintptr(objectType), uintptr(object), uintptr(expectedContentTypeFlags), uintptr(expectedFormatTypeFlags), uintptr(flags), uintptr(unsafe.Pointer(msgAndCertEncodingType)), uintptr(unsafe.Pointer(contentType)), uintptr(unsafe.Pointer(formatType)), uintptr(unsafe.Pointer(certStore)), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(context)), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) {
+	r1, _, e1 := syscall.Syscall9(procCryptUnprotectData.Addr(), 7, uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut)), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (store Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procPFXImportCertStore.Addr(), 3, uintptr(unsafe.Pointer(pfx)), uintptr(unsafe.Pointer(password)), uintptr(flags))
+	store = Handle(r0)
+	if store == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) {
 	r0, _, _ := syscall.Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0)
 	same = r0 != 0
@@ -1303,6 +1460,14 @@
 	return
 }
 
+func ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) {
+	r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) {
 	r1, _, e1 := syscall.Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0)
 	if r1 == 0 {
@@ -1314,7 +1479,7 @@
 func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) {
 	r0, _, e1 := syscall.Syscall6(procCreateEventExW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0)
 	handle = Handle(r0)
-	if handle == 0 {
+	if handle == 0 || e1 == ERROR_ALREADY_EXISTS {
 		err = errnoErr(e1)
 	}
 	return
@@ -1323,7 +1488,7 @@
 func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) {
 	r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0)
 	handle = Handle(r0)
-	if handle == 0 {
+	if handle == 0 || e1 == ERROR_ALREADY_EXISTS {
 		err = errnoErr(e1)
 	}
 	return
@@ -1332,7 +1497,7 @@
 func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
 	r0, _, e1 := syscall.Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
 	handle = Handle(r0)
-	if handle == 0 {
+	if handle == 0 || e1 == ERROR_ALREADY_EXISTS {
 		err = errnoErr(e1)
 	}
 	return
@@ -1355,7 +1520,7 @@
 	return
 }
 
-func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) {
+func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uintptr, threadcnt uint32) (handle Handle, err error) {
 	r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0)
 	handle = Handle(r0)
 	if handle == 0 {
@@ -1376,7 +1541,7 @@
 func CreateMutexEx(mutexAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) {
 	r0, _, e1 := syscall.Syscall6(procCreateMutexExW.Addr(), 4, uintptr(unsafe.Pointer(mutexAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0)
 	handle = Handle(r0)
-	if handle == 0 {
+	if handle == 0 || e1 == ERROR_ALREADY_EXISTS {
 		err = errnoErr(e1)
 	}
 	return
@@ -1389,7 +1554,16 @@
 	}
 	r0, _, e1 := syscall.Syscall(procCreateMutexW.Addr(), 3, uintptr(unsafe.Pointer(mutexAttrs)), uintptr(_p0), uintptr(unsafe.Pointer(name)))
 	handle = Handle(r0)
-	if handle == 0 {
+	if handle == 0 || e1 == ERROR_ALREADY_EXISTS {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
 		err = errnoErr(e1)
 	}
 	return
@@ -1448,6 +1622,11 @@
 	return
 }
 
+func deleteProcThreadAttributeList(attrlist *ProcThreadAttributeList) {
+	syscall.Syscall(procDeleteProcThreadAttributeList.Addr(), 1, uintptr(unsafe.Pointer(attrlist)), 0, 0)
+	return
+}
+
 func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) {
 	r1, _, e1 := syscall.Syscall(procDeleteVolumeMountPointW.Addr(), 1, uintptr(unsafe.Pointer(volumeMountPoint)), 0, 0)
 	if r1 == 0 {
@@ -1489,6 +1668,36 @@
 	return
 }
 
+func FindCloseChangeNotification(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procFindCloseChangeNotification.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func FindFirstChangeNotification(path string, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) {
+	var _p0 *uint16
+	_p0, err = syscall.UTF16PtrFromString(path)
+	if err != nil {
+		return
+	}
+	return _FindFirstChangeNotification(_p0, watchSubtree, notifyFilter)
+}
+
+func _FindFirstChangeNotification(path *uint16, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) {
+	var _p1 uint32
+	if watchSubtree {
+		_p1 = 1
+	}
+	r0, _, e1 := syscall.Syscall(procFindFirstChangeNotificationW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(_p1), uintptr(notifyFilter))
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) {
 	r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0)
 	handle = Handle(r0)
@@ -1516,6 +1725,14 @@
 	return
 }
 
+func FindNextChangeNotification(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procFindNextChangeNotification.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func findNextFile1(handle Handle, data *win32finddata1) (err error) {
 	r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
 	if r1 == 0 {
@@ -1540,6 +1757,15 @@
 	return
 }
 
+func findResource(module Handle, name uintptr, resType uintptr) (resInfo Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procFindResourceW.Addr(), 3, uintptr(module), uintptr(name), uintptr(resType))
+	resInfo = Handle(r0)
+	if resInfo == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func FindVolumeClose(findVolume Handle) (err error) {
 	r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(findVolume), 0, 0)
 	if r1 == 0 {
@@ -1615,6 +1841,14 @@
 	return
 }
 
+func GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func GetCommandLine() (cmd *uint16) {
 	r0, _, _ := syscall.Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0)
 	cmd = (*uint16)(unsafe.Pointer(r0))
@@ -1826,6 +2060,22 @@
 	return
 }
 
+func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
+	r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) {
 	var _p0 uint32
 	if wait {
@@ -1903,7 +2153,7 @@
 	return
 }
 
-func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) {
+func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uintptr, overlapped **Overlapped, timeout uint32) (err error) {
 	r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0)
 	if r1 == 0 {
 		err = errnoErr(e1)
@@ -2071,6 +2321,14 @@
 	return
 }
 
+func initializeProcThreadAttributeList(attrlist *ProcThreadAttributeList, attrcount uint32, flags uint32, size *uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall6(procInitializeProcThreadAttributeList.Addr(), 4, uintptr(unsafe.Pointer(attrlist)), uintptr(attrcount), uintptr(flags), uintptr(unsafe.Pointer(size)), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func IsWow64Process(handle Handle, isWow64 *bool) (err error) {
 	var _p0 uint32
 	if *isWow64 {
@@ -2132,6 +2390,24 @@
 	return
 }
 
+func LoadResource(module Handle, resInfo Handle) (resData Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procLoadResource.Addr(), 2, uintptr(module), uintptr(resInfo), 0)
+	resData = Handle(r0)
+	if resData == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func LocalAlloc(flags uint32, length uint32) (ptr uintptr, err error) {
+	r0, _, e1 := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(flags), uintptr(length), 0)
+	ptr = uintptr(r0)
+	if ptr == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func LocalFree(hmem Handle) (handle Handle, err error) {
 	r0, _, e1 := syscall.Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0)
 	handle = Handle(r0)
@@ -2149,6 +2425,15 @@
 	return
 }
 
+func LockResource(resData Handle) (addr uintptr, err error) {
+	r0, _, e1 := syscall.Syscall(procLockResource.Addr(), 1, uintptr(resData), 0, 0)
+	addr = uintptr(r0)
+	if addr == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) {
 	r0, _, e1 := syscall.Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0)
 	addr = uintptr(r0)
@@ -2235,7 +2520,7 @@
 	return
 }
 
-func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) {
+func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uintptr, overlapped *Overlapped) (err error) {
 	r1, _, e1 := syscall.Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0)
 	if r1 == 0 {
 		err = errnoErr(e1)
@@ -2284,6 +2569,14 @@
 	return
 }
 
+func QueryFullProcessImageName(proc Handle, flags uint32, exeName *uint16, size *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procQueryFullProcessImageNameW.Addr(), 4, uintptr(proc), uintptr(flags), uintptr(unsafe.Pointer(exeName)), uintptr(unsafe.Pointer(size)), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobObjectInformation uintptr, JobObjectInformationLength uint32, retlen *uint32) (err error) {
 	r1, _, e1 := syscall.Syscall6(procQueryInformationJobObject.Addr(), 5, uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), uintptr(unsafe.Pointer(retlen)), 0)
 	if r1 == 0 {
@@ -2357,6 +2650,14 @@
 	return
 }
 
+func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func setConsoleCursorPosition(console Handle, position uint32) (err error) {
 	r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0)
 	if r1 == 0 {
@@ -2494,6 +2795,14 @@
 	return
 }
 
+func SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procSetNamedPipeHandleState.Addr(), 4, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func SetPriorityClass(process Handle, priorityClass uint32) (err error) {
 	r1, _, e1 := syscall.Syscall(procSetPriorityClass.Addr(), 2, uintptr(process), uintptr(priorityClass), 0)
 	if r1 == 0 {
@@ -2554,6 +2863,15 @@
 	return
 }
 
+func SizeofResource(module Handle, resInfo Handle) (size uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procSizeofResource.Addr(), 2, uintptr(module), uintptr(resInfo), 0)
+	size = uint32(r0)
+	if size == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func SleepEx(milliseconds uint32, alertable bool) (ret uint32) {
 	var _p0 uint32
 	if alertable {
@@ -2612,6 +2930,14 @@
 	return
 }
 
+func updateProcThreadAttribute(attrlist *ProcThreadAttributeList, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall9(procUpdateProcThreadAttribute.Addr(), 7, uintptr(unsafe.Pointer(attrlist)), uintptr(flags), uintptr(attr), uintptr(value), uintptr(size), uintptr(prevvalue), uintptr(unsafe.Pointer(returnedsize)), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) {
 	r0, _, e1 := syscall.Syscall6(procVirtualAlloc.Addr(), 4, uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect), 0, 0)
 	value = uintptr(r0)
@@ -2740,19 +3066,97 @@
 	return
 }
 
+func NtCreateFile(handle *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, allocationSize *int64, attributes uint32, share uint32, disposition uint32, options uint32, eabuffer uintptr, ealength uint32) (ntstatus error) {
+	r0, _, _ := syscall.Syscall12(procNtCreateFile.Addr(), 11, uintptr(unsafe.Pointer(handle)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(allocationSize)), uintptr(attributes), uintptr(share), uintptr(disposition), uintptr(options), uintptr(eabuffer), uintptr(ealength), 0)
+	if r0 != 0 {
+		ntstatus = NTStatus(r0)
+	}
+	return
+}
+
+func NtCreateNamedPipeFile(pipe *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (ntstatus error) {
+	r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0)
+	if r0 != 0 {
+		ntstatus = NTStatus(r0)
+	}
+	return
+}
+
+func NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32, retLen *uint32) (ntstatus error) {
+	r0, _, _ := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen), uintptr(unsafe.Pointer(retLen)), 0)
+	if r0 != 0 {
+		ntstatus = NTStatus(r0)
+	}
+	return
+}
+
+func NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32) (ntstatus error) {
+	r0, _, _ := syscall.Syscall6(procNtSetInformationProcess.Addr(), 4, uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen), 0, 0)
+	if r0 != 0 {
+		ntstatus = NTStatus(r0)
+	}
+	return
+}
+
+func RtlDefaultNpAcl(acl **ACL) (ntstatus error) {
+	r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(acl)), 0, 0)
+	if r0 != 0 {
+		ntstatus = NTStatus(r0)
+	}
+	return
+}
+
+func RtlDosPathNameToNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) {
+	r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U_WithStatus.Addr(), 4, uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName)), 0, 0)
+	if r0 != 0 {
+		ntstatus = NTStatus(r0)
+	}
+	return
+}
+
+func RtlDosPathNameToRelativeNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) {
+	r0, _, _ := syscall.Syscall6(procRtlDosPathNameToRelativeNtPathName_U_WithStatus.Addr(), 4, uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName)), 0, 0)
+	if r0 != 0 {
+		ntstatus = NTStatus(r0)
+	}
+	return
+}
+
+func RtlGetCurrentPeb() (peb *PEB) {
+	r0, _, _ := syscall.Syscall(procRtlGetCurrentPeb.Addr(), 0, 0, 0, 0)
+	peb = (*PEB)(unsafe.Pointer(r0))
+	return
+}
+
 func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) {
 	syscall.Syscall(procRtlGetNtVersionNumbers.Addr(), 3, uintptr(unsafe.Pointer(majorVersion)), uintptr(unsafe.Pointer(minorVersion)), uintptr(unsafe.Pointer(buildNumber)))
 	return
 }
 
-func rtlGetVersion(info *OsVersionInfoEx) (ret error) {
+func rtlGetVersion(info *OsVersionInfoEx) (ntstatus error) {
 	r0, _, _ := syscall.Syscall(procRtlGetVersion.Addr(), 1, uintptr(unsafe.Pointer(info)), 0, 0)
 	if r0 != 0 {
-		ret = syscall.Errno(r0)
+		ntstatus = NTStatus(r0)
 	}
 	return
 }
 
+func RtlInitString(destinationString *NTString, sourceString *byte) {
+	syscall.Syscall(procRtlInitString.Addr(), 2, uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString)), 0)
+	return
+}
+
+func RtlInitUnicodeString(destinationString *NTUnicodeString, sourceString *uint16) {
+	syscall.Syscall(procRtlInitUnicodeString.Addr(), 2, uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString)), 0)
+	return
+}
+
+func rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) {
+	r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(ntstatus), 0, 0)
+	ret = syscall.Errno(r0)
+	return
+}
+
 func clsidFromString(lpsz *uint16, pclsid *GUID) (ret error) {
 	r0, _, _ := syscall.Syscall(procCLSIDFromString.Addr(), 2, uintptr(unsafe.Pointer(lpsz)), uintptr(unsafe.Pointer(pclsid)), 0)
 	if r0 != 0 {
@@ -2769,11 +3173,32 @@
 	return
 }
 
+func CoGetObject(name *uint16, bindOpts *BIND_OPTS3, guid *GUID, functionTable **uintptr) (ret error) {
+	r0, _, _ := syscall.Syscall6(procCoGetObject.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bindOpts)), uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(functionTable)), 0, 0)
+	if r0 != 0 {
+		ret = syscall.Errno(r0)
+	}
+	return
+}
+
+func CoInitializeEx(reserved uintptr, coInit uint32) (ret error) {
+	r0, _, _ := syscall.Syscall(procCoInitializeEx.Addr(), 2, uintptr(reserved), uintptr(coInit), 0)
+	if r0 != 0 {
+		ret = syscall.Errno(r0)
+	}
+	return
+}
+
 func CoTaskMemFree(address unsafe.Pointer) {
 	syscall.Syscall(procCoTaskMemFree.Addr(), 1, uintptr(address), 0, 0)
 	return
 }
 
+func CoUninitialize() {
+	syscall.Syscall(procCoUninitialize.Addr(), 0, 0, 0, 0)
+	return
+}
+
 func stringFromGUID2(rguid *GUID, lpsz *uint16, cchMax int32) (chars int32) {
 	r0, _, _ := syscall.Syscall(procStringFromGUID2.Addr(), 3, uintptr(unsafe.Pointer(rguid)), uintptr(unsafe.Pointer(lpsz)), uintptr(cchMax))
 	chars = int32(r0)
@@ -2862,7 +3287,22 @@
 	return
 }
 
-func MessageBox(hwnd Handle, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) {
+func GetShellWindow() (shellWindow HWND) {
+	r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0)
+	shellWindow = HWND(r0)
+	return
+}
+
+func GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetWindowThreadProcessId.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(pid)), 0)
+	tid = uint32(r0)
+	if tid == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) {
 	r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0)
 	ret = int32(r0)
 	if ret == 0 {
@@ -2899,6 +3339,14 @@
 	return
 }
 
+func WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) {
+	r0, _, _ := syscall.Syscall(procWinVerifyTrustEx.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(actionId)), uintptr(unsafe.Pointer(data)))
+	if r0 != 0 {
+		ret = syscall.Errno(r0)
+	}
+	return
+}
+
 func FreeAddrInfoW(addrinfo *AddrinfoW) {
 	syscall.Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0)
 	return
@@ -2929,6 +3377,18 @@
 	return
 }
 
+func WSAGetOverlappedResult(h Handle, o *Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
+	var _p0 uint32
+	if wait {
+		_p0 = 1
+	}
+	r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
 	r1, _, e1 := syscall.Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine))
 	if r1 == socket_error {
@@ -2969,6 +3429,15 @@
 	return
 }
 
+func WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall6(procWSASocketW.Addr(), 6, uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protoInfo)), uintptr(group), uintptr(flags))
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func WSAStartup(verreq uint32, data *WSAData) (sockerr error) {
 	r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
 	if r0 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/term/AUTHORS b/src/cmd/vendor/golang.org/x/term/AUTHORS
new file mode 100644
index 0000000..15167cd
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.
diff --git a/src/cmd/vendor/golang.org/x/term/CONTRIBUTING.md b/src/cmd/vendor/golang.org/x/term/CONTRIBUTING.md
new file mode 100644
index 0000000..d0485e8
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/CONTRIBUTING.md
@@ -0,0 +1,26 @@
+# Contributing to Go
+
+Go is an open source project.
+
+It is the work of hundreds of contributors. We appreciate your help!
+
+## Filing issues
+
+When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions:
+
+1.  What version of Go are you using (`go version`)?
+2.  What operating system and processor architecture are you using?
+3.  What did you do?
+4.  What did you expect to see?
+5.  What did you see instead?
+
+General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
+The gophers there will answer or ask you to file an issue if you've tripped over a bug.
+
+## Contributing code
+
+Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
+before sending patches.
+
+Unless otherwise noted, the Go source files are distributed under
+the BSD-style license found in the LICENSE file.
diff --git a/src/cmd/vendor/golang.org/x/term/CONTRIBUTORS b/src/cmd/vendor/golang.org/x/term/CONTRIBUTORS
new file mode 100644
index 0000000..1c4577e
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/src/cmd/vendor/golang.org/x/term/LICENSE b/src/cmd/vendor/golang.org/x/term/LICENSE
new file mode 100644
index 0000000..6a66aea
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/cmd/vendor/golang.org/x/term/PATENTS b/src/cmd/vendor/golang.org/x/term/PATENTS
new file mode 100644
index 0000000..7330990
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go.  This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation.  If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/src/cmd/vendor/golang.org/x/term/README.md b/src/cmd/vendor/golang.org/x/term/README.md
new file mode 100644
index 0000000..d03d0ae
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/README.md
@@ -0,0 +1,19 @@
+# Go terminal/console support
+
+[![Go Reference](https://pkg.go.dev/badge/golang.org/x/term.svg)](https://pkg.go.dev/golang.org/x/term)
+
+This repository provides Go terminal and console support packages.
+
+## Download/Install
+
+The easiest way to install is to run `go get -u golang.org/x/term`. You can
+also manually git clone the repository to `$GOPATH/src/golang.org/x/term`.
+
+## Report Issues / Send Patches
+
+This repository uses Gerrit for code changes. To learn how to submit changes to
+this repository, see https://golang.org/doc/contribute.html.
+
+The main issue tracker for the term repository is located at
+https://github.com/golang/go/issues. Prefix your issue with "x/term:" in the
+subject line, so it is easy to find.
diff --git a/src/cmd/vendor/golang.org/x/term/term.go b/src/cmd/vendor/golang.org/x/term/term.go
new file mode 100644
index 0000000..1f6a38f
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/term.go
@@ -0,0 +1,58 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package term provides support functions for dealing with terminals, as
+// commonly found on UNIX systems.
+//
+// Putting a terminal into raw mode is the most common requirement:
+//
+// 	oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
+// 	if err != nil {
+// 	        panic(err)
+// 	}
+// 	defer term.Restore(int(os.Stdin.Fd()), oldState)
+package term
+
+// State contains the state of a terminal.
+type State struct {
+	state
+}
+
+// IsTerminal returns whether the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+	return isTerminal(fd)
+}
+
+// MakeRaw puts the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd int) (*State, error) {
+	return makeRaw(fd)
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+	return getState(fd)
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, oldState *State) error {
+	return restore(fd, oldState)
+}
+
+// GetSize returns the visible dimensions of the given terminal.
+//
+// These dimensions don't include any scrollback buffer height.
+func GetSize(fd int) (width, height int, err error) {
+	return getSize(fd)
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+	return readPassword(fd)
+}
diff --git a/src/cmd/vendor/golang.org/x/term/term_plan9.go b/src/cmd/vendor/golang.org/x/term/term_plan9.go
new file mode 100644
index 0000000..21afa55
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/term_plan9.go
@@ -0,0 +1,42 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package term
+
+import (
+	"fmt"
+	"runtime"
+
+	"golang.org/x/sys/plan9"
+)
+
+type state struct{}
+
+func isTerminal(fd int) bool {
+	path, err := plan9.Fd2path(fd)
+	if err != nil {
+		return false
+	}
+	return path == "/dev/cons" || path == "/mnt/term/dev/cons"
+}
+
+func makeRaw(fd int) (*State, error) {
+	return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getState(fd int) (*State, error) {
+	return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func restore(fd int, state *State) error {
+	return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getSize(fd int) (width, height int, err error) {
+	return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func readPassword(fd int) ([]byte, error) {
+	return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
diff --git a/src/cmd/vendor/golang.org/x/term/term_unix.go b/src/cmd/vendor/golang.org/x/term/term_unix.go
new file mode 100644
index 0000000..a4e31ab
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/term_unix.go
@@ -0,0 +1,92 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package term
+
+import (
+	"golang.org/x/sys/unix"
+)
+
+type state struct {
+	termios unix.Termios
+}
+
+func isTerminal(fd int) bool {
+	_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+	return err == nil
+}
+
+func makeRaw(fd int) (*State, error) {
+	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+	if err != nil {
+		return nil, err
+	}
+
+	oldState := State{state{termios: *termios}}
+
+	// This attempts to replicate the behaviour documented for cfmakeraw in
+	// the termios(3) manpage.
+	termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
+	termios.Oflag &^= unix.OPOST
+	termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
+	termios.Cflag &^= unix.CSIZE | unix.PARENB
+	termios.Cflag |= unix.CS8
+	termios.Cc[unix.VMIN] = 1
+	termios.Cc[unix.VTIME] = 0
+	if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, termios); err != nil {
+		return nil, err
+	}
+
+	return &oldState, nil
+}
+
+func getState(fd int) (*State, error) {
+	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+	if err != nil {
+		return nil, err
+	}
+
+	return &State{state{termios: *termios}}, nil
+}
+
+func restore(fd int, state *State) error {
+	return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios)
+}
+
+func getSize(fd int) (width, height int, err error) {
+	ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
+	if err != nil {
+		return -1, -1, err
+	}
+	return int(ws.Col), int(ws.Row), nil
+}
+
+// passwordReader is an io.Reader that reads from a specific file descriptor.
+type passwordReader int
+
+func (r passwordReader) Read(buf []byte) (int, error) {
+	return unix.Read(int(r), buf)
+}
+
+func readPassword(fd int) ([]byte, error) {
+	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+	if err != nil {
+		return nil, err
+	}
+
+	newState := *termios
+	newState.Lflag &^= unix.ECHO
+	newState.Lflag |= unix.ICANON | unix.ISIG
+	newState.Iflag |= unix.ICRNL
+	if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newState); err != nil {
+		return nil, err
+	}
+
+	defer unix.IoctlSetTermios(fd, ioctlWriteTermios, termios)
+
+	return readPasswordLine(passwordReader(fd))
+}
diff --git a/src/cmd/vendor/golang.org/x/term/term_unix_bsd.go b/src/cmd/vendor/golang.org/x/term/term_unix_bsd.go
new file mode 100644
index 0000000..853b3d6
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/term_unix_bsd.go
@@ -0,0 +1,13 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package term
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TIOCGETA
+const ioctlWriteTermios = unix.TIOCSETA
diff --git a/src/cmd/vendor/golang.org/x/term/term_unix_other.go b/src/cmd/vendor/golang.org/x/term/term_unix_other.go
new file mode 100644
index 0000000..1e8955c
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/term_unix_other.go
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || linux || solaris || zos
+// +build aix linux solaris zos
+
+package term
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TCGETS
+const ioctlWriteTermios = unix.TCSETS
diff --git a/src/cmd/vendor/golang.org/x/term/term_unsupported.go b/src/cmd/vendor/golang.org/x/term/term_unsupported.go
new file mode 100644
index 0000000..f1df850
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/term_unsupported.go
@@ -0,0 +1,39 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !zos && !windows && !solaris && !plan9
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!zos,!windows,!solaris,!plan9
+
+package term
+
+import (
+	"fmt"
+	"runtime"
+)
+
+type state struct{}
+
+func isTerminal(fd int) bool {
+	return false
+}
+
+func makeRaw(fd int) (*State, error) {
+	return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getState(fd int) (*State, error) {
+	return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func restore(fd int, state *State) error {
+	return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getSize(fd int) (width, height int, err error) {
+	return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func readPassword(fd int) ([]byte, error) {
+	return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
diff --git a/src/cmd/vendor/golang.org/x/term/term_windows.go b/src/cmd/vendor/golang.org/x/term/term_windows.go
new file mode 100644
index 0000000..465f560
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/term_windows.go
@@ -0,0 +1,79 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package term
+
+import (
+	"os"
+
+	"golang.org/x/sys/windows"
+)
+
+type state struct {
+	mode uint32
+}
+
+func isTerminal(fd int) bool {
+	var st uint32
+	err := windows.GetConsoleMode(windows.Handle(fd), &st)
+	return err == nil
+}
+
+func makeRaw(fd int) (*State, error) {
+	var st uint32
+	if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+		return nil, err
+	}
+	raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
+	if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil {
+		return nil, err
+	}
+	return &State{state{st}}, nil
+}
+
+func getState(fd int) (*State, error) {
+	var st uint32
+	if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+		return nil, err
+	}
+	return &State{state{st}}, nil
+}
+
+func restore(fd int, state *State) error {
+	return windows.SetConsoleMode(windows.Handle(fd), state.mode)
+}
+
+func getSize(fd int) (width, height int, err error) {
+	var info windows.ConsoleScreenBufferInfo
+	if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
+		return 0, 0, err
+	}
+	return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil
+}
+
+func readPassword(fd int) ([]byte, error) {
+	var st uint32
+	if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+		return nil, err
+	}
+	old := st
+
+	st &^= (windows.ENABLE_ECHO_INPUT | windows.ENABLE_LINE_INPUT)
+	st |= (windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_PROCESSED_INPUT)
+	if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil {
+		return nil, err
+	}
+
+	defer windows.SetConsoleMode(windows.Handle(fd), old)
+
+	var h windows.Handle
+	p, _ := windows.GetCurrentProcess()
+	if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil {
+		return nil, err
+	}
+
+	f := os.NewFile(uintptr(h), "stdin")
+	defer f.Close()
+	return readPasswordLine(f)
+}
diff --git a/src/cmd/vendor/golang.org/x/term/terminal.go b/src/cmd/vendor/golang.org/x/term/terminal.go
new file mode 100644
index 0000000..535ab82
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/term/terminal.go
@@ -0,0 +1,987 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package term
+
+import (
+	"bytes"
+	"io"
+	"runtime"
+	"strconv"
+	"sync"
+	"unicode/utf8"
+)
+
+// EscapeCodes contains escape sequences that can be written to the terminal in
+// order to achieve different styles of text.
+type EscapeCodes struct {
+	// Foreground colors
+	Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte
+
+	// Reset all attributes
+	Reset []byte
+}
+
+var vt100EscapeCodes = EscapeCodes{
+	Black:   []byte{keyEscape, '[', '3', '0', 'm'},
+	Red:     []byte{keyEscape, '[', '3', '1', 'm'},
+	Green:   []byte{keyEscape, '[', '3', '2', 'm'},
+	Yellow:  []byte{keyEscape, '[', '3', '3', 'm'},
+	Blue:    []byte{keyEscape, '[', '3', '4', 'm'},
+	Magenta: []byte{keyEscape, '[', '3', '5', 'm'},
+	Cyan:    []byte{keyEscape, '[', '3', '6', 'm'},
+	White:   []byte{keyEscape, '[', '3', '7', 'm'},
+
+	Reset: []byte{keyEscape, '[', '0', 'm'},
+}
+
+// Terminal contains the state for running a VT100 terminal that is capable of
+// reading lines of input.
+type Terminal struct {
+	// AutoCompleteCallback, if non-null, is called for each keypress with
+	// the full input line and the current position of the cursor (in
+	// bytes, as an index into |line|). If it returns ok=false, the key
+	// press is processed normally. Otherwise it returns a replacement line
+	// and the new cursor position.
+	AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
+
+	// Escape contains a pointer to the escape codes for this terminal.
+	// It's always a valid pointer, although the escape codes themselves
+	// may be empty if the terminal doesn't support them.
+	Escape *EscapeCodes
+
+	// lock protects the terminal and the state in this object from
+	// concurrent processing of a key press and a Write() call.
+	lock sync.Mutex
+
+	c      io.ReadWriter
+	prompt []rune
+
+	// line is the current line being entered.
+	line []rune
+	// pos is the logical position of the cursor in line
+	pos int
+	// echo is true if local echo is enabled
+	echo bool
+	// pasteActive is true iff there is a bracketed paste operation in
+	// progress.
+	pasteActive bool
+
+	// cursorX contains the current X value of the cursor where the left
+	// edge is 0. cursorY contains the row number where the first row of
+	// the current line is 0.
+	cursorX, cursorY int
+	// maxLine is the greatest value of cursorY so far.
+	maxLine int
+
+	termWidth, termHeight int
+
+	// outBuf contains the terminal data to be sent.
+	outBuf []byte
+	// remainder contains the remainder of any partial key sequences after
+	// a read. It aliases into inBuf.
+	remainder []byte
+	inBuf     [256]byte
+
+	// history contains previously entered commands so that they can be
+	// accessed with the up and down keys.
+	history stRingBuffer
+	// historyIndex stores the currently accessed history entry, where zero
+	// means the immediately previous entry.
+	historyIndex int
+	// When navigating up and down the history it's possible to return to
+	// the incomplete, initial line. That value is stored in
+	// historyPending.
+	historyPending string
+}
+
+// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
+// a local terminal, that terminal must first have been put into raw mode.
+// prompt is a string that is written at the start of each input line (i.e.
+// "> ").
+func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
+	return &Terminal{
+		Escape:       &vt100EscapeCodes,
+		c:            c,
+		prompt:       []rune(prompt),
+		termWidth:    80,
+		termHeight:   24,
+		echo:         true,
+		historyIndex: -1,
+	}
+}
+
+const (
+	keyCtrlC     = 3
+	keyCtrlD     = 4
+	keyCtrlU     = 21
+	keyEnter     = '\r'
+	keyEscape    = 27
+	keyBackspace = 127
+	keyUnknown   = 0xd800 /* UTF-16 surrogate area */ + iota
+	keyUp
+	keyDown
+	keyLeft
+	keyRight
+	keyAltLeft
+	keyAltRight
+	keyHome
+	keyEnd
+	keyDeleteWord
+	keyDeleteLine
+	keyClearScreen
+	keyPasteStart
+	keyPasteEnd
+)
+
+var (
+	crlf       = []byte{'\r', '\n'}
+	pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'}
+	pasteEnd   = []byte{keyEscape, '[', '2', '0', '1', '~'}
+)
+
+// bytesToKey tries to parse a key sequence from b. If successful, it returns
+// the key and the remainder of the input. Otherwise it returns utf8.RuneError.
+func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
+	if len(b) == 0 {
+		return utf8.RuneError, nil
+	}
+
+	if !pasteActive {
+		switch b[0] {
+		case 1: // ^A
+			return keyHome, b[1:]
+		case 2: // ^B
+			return keyLeft, b[1:]
+		case 5: // ^E
+			return keyEnd, b[1:]
+		case 6: // ^F
+			return keyRight, b[1:]
+		case 8: // ^H
+			return keyBackspace, b[1:]
+		case 11: // ^K
+			return keyDeleteLine, b[1:]
+		case 12: // ^L
+			return keyClearScreen, b[1:]
+		case 23: // ^W
+			return keyDeleteWord, b[1:]
+		case 14: // ^N
+			return keyDown, b[1:]
+		case 16: // ^P
+			return keyUp, b[1:]
+		}
+	}
+
+	if b[0] != keyEscape {
+		if !utf8.FullRune(b) {
+			return utf8.RuneError, b
+		}
+		r, l := utf8.DecodeRune(b)
+		return r, b[l:]
+	}
+
+	if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' {
+		switch b[2] {
+		case 'A':
+			return keyUp, b[3:]
+		case 'B':
+			return keyDown, b[3:]
+		case 'C':
+			return keyRight, b[3:]
+		case 'D':
+			return keyLeft, b[3:]
+		case 'H':
+			return keyHome, b[3:]
+		case 'F':
+			return keyEnd, b[3:]
+		}
+	}
+
+	if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' {
+		switch b[5] {
+		case 'C':
+			return keyAltRight, b[6:]
+		case 'D':
+			return keyAltLeft, b[6:]
+		}
+	}
+
+	if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) {
+		return keyPasteStart, b[6:]
+	}
+
+	if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) {
+		return keyPasteEnd, b[6:]
+	}
+
+	// If we get here then we have a key that we don't recognise, or a
+	// partial sequence. It's not clear how one should find the end of a
+	// sequence without knowing them all, but it seems that [a-zA-Z~] only
+	// appears at the end of a sequence.
+	for i, c := range b[0:] {
+		if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' {
+			return keyUnknown, b[i+1:]
+		}
+	}
+
+	return utf8.RuneError, b
+}
+
+// queue appends data to the end of t.outBuf
+func (t *Terminal) queue(data []rune) {
+	t.outBuf = append(t.outBuf, []byte(string(data))...)
+}
+
+var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'}
+var space = []rune{' '}
+
+func isPrintable(key rune) bool {
+	isInSurrogateArea := key >= 0xd800 && key <= 0xdbff
+	return key >= 32 && !isInSurrogateArea
+}
+
+// moveCursorToPos appends data to t.outBuf which will move the cursor to the
+// given, logical position in the text.
+func (t *Terminal) moveCursorToPos(pos int) {
+	if !t.echo {
+		return
+	}
+
+	x := visualLength(t.prompt) + pos
+	y := x / t.termWidth
+	x = x % t.termWidth
+
+	up := 0
+	if y < t.cursorY {
+		up = t.cursorY - y
+	}
+
+	down := 0
+	if y > t.cursorY {
+		down = y - t.cursorY
+	}
+
+	left := 0
+	if x < t.cursorX {
+		left = t.cursorX - x
+	}
+
+	right := 0
+	if x > t.cursorX {
+		right = x - t.cursorX
+	}
+
+	t.cursorX = x
+	t.cursorY = y
+	t.move(up, down, left, right)
+}
+
+func (t *Terminal) move(up, down, left, right int) {
+	m := []rune{}
+
+	// 1 unit up can be expressed as ^[[A or ^[A
+	// 5 units up can be expressed as ^[[5A
+
+	if up == 1 {
+		m = append(m, keyEscape, '[', 'A')
+	} else if up > 1 {
+		m = append(m, keyEscape, '[')
+		m = append(m, []rune(strconv.Itoa(up))...)
+		m = append(m, 'A')
+	}
+
+	if down == 1 {
+		m = append(m, keyEscape, '[', 'B')
+	} else if down > 1 {
+		m = append(m, keyEscape, '[')
+		m = append(m, []rune(strconv.Itoa(down))...)
+		m = append(m, 'B')
+	}
+
+	if right == 1 {
+		m = append(m, keyEscape, '[', 'C')
+	} else if right > 1 {
+		m = append(m, keyEscape, '[')
+		m = append(m, []rune(strconv.Itoa(right))...)
+		m = append(m, 'C')
+	}
+
+	if left == 1 {
+		m = append(m, keyEscape, '[', 'D')
+	} else if left > 1 {
+		m = append(m, keyEscape, '[')
+		m = append(m, []rune(strconv.Itoa(left))...)
+		m = append(m, 'D')
+	}
+
+	t.queue(m)
+}
+
+func (t *Terminal) clearLineToRight() {
+	op := []rune{keyEscape, '[', 'K'}
+	t.queue(op)
+}
+
+const maxLineLength = 4096
+
+func (t *Terminal) setLine(newLine []rune, newPos int) {
+	if t.echo {
+		t.moveCursorToPos(0)
+		t.writeLine(newLine)
+		for i := len(newLine); i < len(t.line); i++ {
+			t.writeLine(space)
+		}
+		t.moveCursorToPos(newPos)
+	}
+	t.line = newLine
+	t.pos = newPos
+}
+
+func (t *Terminal) advanceCursor(places int) {
+	t.cursorX += places
+	t.cursorY += t.cursorX / t.termWidth
+	if t.cursorY > t.maxLine {
+		t.maxLine = t.cursorY
+	}
+	t.cursorX = t.cursorX % t.termWidth
+
+	if places > 0 && t.cursorX == 0 {
+		// Normally terminals will advance the current position
+		// when writing a character. But that doesn't happen
+		// for the last character in a line. However, when
+		// writing a character (except a new line) that causes
+		// a line wrap, the position will be advanced two
+		// places.
+		//
+		// So, if we are stopping at the end of a line, we
+		// need to write a newline so that our cursor can be
+		// advanced to the next line.
+		t.outBuf = append(t.outBuf, '\r', '\n')
+	}
+}
+
+func (t *Terminal) eraseNPreviousChars(n int) {
+	if n == 0 {
+		return
+	}
+
+	if t.pos < n {
+		n = t.pos
+	}
+	t.pos -= n
+	t.moveCursorToPos(t.pos)
+
+	copy(t.line[t.pos:], t.line[n+t.pos:])
+	t.line = t.line[:len(t.line)-n]
+	if t.echo {
+		t.writeLine(t.line[t.pos:])
+		for i := 0; i < n; i++ {
+			t.queue(space)
+		}
+		t.advanceCursor(n)
+		t.moveCursorToPos(t.pos)
+	}
+}
+
+// countToLeftWord returns then number of characters from the cursor to the
+// start of the previous word.
+func (t *Terminal) countToLeftWord() int {
+	if t.pos == 0 {
+		return 0
+	}
+
+	pos := t.pos - 1
+	for pos > 0 {
+		if t.line[pos] != ' ' {
+			break
+		}
+		pos--
+	}
+	for pos > 0 {
+		if t.line[pos] == ' ' {
+			pos++
+			break
+		}
+		pos--
+	}
+
+	return t.pos - pos
+}
+
+// countToRightWord returns then number of characters from the cursor to the
+// start of the next word.
+func (t *Terminal) countToRightWord() int {
+	pos := t.pos
+	for pos < len(t.line) {
+		if t.line[pos] == ' ' {
+			break
+		}
+		pos++
+	}
+	for pos < len(t.line) {
+		if t.line[pos] != ' ' {
+			break
+		}
+		pos++
+	}
+	return pos - t.pos
+}
+
+// visualLength returns the number of visible glyphs in s.
+func visualLength(runes []rune) int {
+	inEscapeSeq := false
+	length := 0
+
+	for _, r := range runes {
+		switch {
+		case inEscapeSeq:
+			if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') {
+				inEscapeSeq = false
+			}
+		case r == '\x1b':
+			inEscapeSeq = true
+		default:
+			length++
+		}
+	}
+
+	return length
+}
+
+// handleKey processes the given key and, optionally, returns a line of text
+// that the user has entered.
+func (t *Terminal) handleKey(key rune) (line string, ok bool) {
+	if t.pasteActive && key != keyEnter {
+		t.addKeyToLine(key)
+		return
+	}
+
+	switch key {
+	case keyBackspace:
+		if t.pos == 0 {
+			return
+		}
+		t.eraseNPreviousChars(1)
+	case keyAltLeft:
+		// move left by a word.
+		t.pos -= t.countToLeftWord()
+		t.moveCursorToPos(t.pos)
+	case keyAltRight:
+		// move right by a word.
+		t.pos += t.countToRightWord()
+		t.moveCursorToPos(t.pos)
+	case keyLeft:
+		if t.pos == 0 {
+			return
+		}
+		t.pos--
+		t.moveCursorToPos(t.pos)
+	case keyRight:
+		if t.pos == len(t.line) {
+			return
+		}
+		t.pos++
+		t.moveCursorToPos(t.pos)
+	case keyHome:
+		if t.pos == 0 {
+			return
+		}
+		t.pos = 0
+		t.moveCursorToPos(t.pos)
+	case keyEnd:
+		if t.pos == len(t.line) {
+			return
+		}
+		t.pos = len(t.line)
+		t.moveCursorToPos(t.pos)
+	case keyUp:
+		entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1)
+		if !ok {
+			return "", false
+		}
+		if t.historyIndex == -1 {
+			t.historyPending = string(t.line)
+		}
+		t.historyIndex++
+		runes := []rune(entry)
+		t.setLine(runes, len(runes))
+	case keyDown:
+		switch t.historyIndex {
+		case -1:
+			return
+		case 0:
+			runes := []rune(t.historyPending)
+			t.setLine(runes, len(runes))
+			t.historyIndex--
+		default:
+			entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1)
+			if ok {
+				t.historyIndex--
+				runes := []rune(entry)
+				t.setLine(runes, len(runes))
+			}
+		}
+	case keyEnter:
+		t.moveCursorToPos(len(t.line))
+		t.queue([]rune("\r\n"))
+		line = string(t.line)
+		ok = true
+		t.line = t.line[:0]
+		t.pos = 0
+		t.cursorX = 0
+		t.cursorY = 0
+		t.maxLine = 0
+	case keyDeleteWord:
+		// Delete zero or more spaces and then one or more characters.
+		t.eraseNPreviousChars(t.countToLeftWord())
+	case keyDeleteLine:
+		// Delete everything from the current cursor position to the
+		// end of line.
+		for i := t.pos; i < len(t.line); i++ {
+			t.queue(space)
+			t.advanceCursor(1)
+		}
+		t.line = t.line[:t.pos]
+		t.moveCursorToPos(t.pos)
+	case keyCtrlD:
+		// Erase the character under the current position.
+		// The EOF case when the line is empty is handled in
+		// readLine().
+		if t.pos < len(t.line) {
+			t.pos++
+			t.eraseNPreviousChars(1)
+		}
+	case keyCtrlU:
+		t.eraseNPreviousChars(t.pos)
+	case keyClearScreen:
+		// Erases the screen and moves the cursor to the home position.
+		t.queue([]rune("\x1b[2J\x1b[H"))
+		t.queue(t.prompt)
+		t.cursorX, t.cursorY = 0, 0
+		t.advanceCursor(visualLength(t.prompt))
+		t.setLine(t.line, t.pos)
+	default:
+		if t.AutoCompleteCallback != nil {
+			prefix := string(t.line[:t.pos])
+			suffix := string(t.line[t.pos:])
+
+			t.lock.Unlock()
+			newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key)
+			t.lock.Lock()
+
+			if completeOk {
+				t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos]))
+				return
+			}
+		}
+		if !isPrintable(key) {
+			return
+		}
+		if len(t.line) == maxLineLength {
+			return
+		}
+		t.addKeyToLine(key)
+	}
+	return
+}
+
+// addKeyToLine inserts the given key at the current position in the current
+// line.
+func (t *Terminal) addKeyToLine(key rune) {
+	if len(t.line) == cap(t.line) {
+		newLine := make([]rune, len(t.line), 2*(1+len(t.line)))
+		copy(newLine, t.line)
+		t.line = newLine
+	}
+	t.line = t.line[:len(t.line)+1]
+	copy(t.line[t.pos+1:], t.line[t.pos:])
+	t.line[t.pos] = key
+	if t.echo {
+		t.writeLine(t.line[t.pos:])
+	}
+	t.pos++
+	t.moveCursorToPos(t.pos)
+}
+
+func (t *Terminal) writeLine(line []rune) {
+	for len(line) != 0 {
+		remainingOnLine := t.termWidth - t.cursorX
+		todo := len(line)
+		if todo > remainingOnLine {
+			todo = remainingOnLine
+		}
+		t.queue(line[:todo])
+		t.advanceCursor(visualLength(line[:todo]))
+		line = line[todo:]
+	}
+}
+
+// writeWithCRLF writes buf to w but replaces all occurrences of \n with \r\n.
+func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) {
+	for len(buf) > 0 {
+		i := bytes.IndexByte(buf, '\n')
+		todo := len(buf)
+		if i >= 0 {
+			todo = i
+		}
+
+		var nn int
+		nn, err = w.Write(buf[:todo])
+		n += nn
+		if err != nil {
+			return n, err
+		}
+		buf = buf[todo:]
+
+		if i >= 0 {
+			if _, err = w.Write(crlf); err != nil {
+				return n, err
+			}
+			n++
+			buf = buf[1:]
+		}
+	}
+
+	return n, nil
+}
+
+func (t *Terminal) Write(buf []byte) (n int, err error) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	if t.cursorX == 0 && t.cursorY == 0 {
+		// This is the easy case: there's nothing on the screen that we
+		// have to move out of the way.
+		return writeWithCRLF(t.c, buf)
+	}
+
+	// We have a prompt and possibly user input on the screen. We
+	// have to clear it first.
+	t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */)
+	t.cursorX = 0
+	t.clearLineToRight()
+
+	for t.cursorY > 0 {
+		t.move(1 /* up */, 0, 0, 0)
+		t.cursorY--
+		t.clearLineToRight()
+	}
+
+	if _, err = t.c.Write(t.outBuf); err != nil {
+		return
+	}
+	t.outBuf = t.outBuf[:0]
+
+	if n, err = writeWithCRLF(t.c, buf); err != nil {
+		return
+	}
+
+	t.writeLine(t.prompt)
+	if t.echo {
+		t.writeLine(t.line)
+	}
+
+	t.moveCursorToPos(t.pos)
+
+	if _, err = t.c.Write(t.outBuf); err != nil {
+		return
+	}
+	t.outBuf = t.outBuf[:0]
+	return
+}
+
+// ReadPassword temporarily changes the prompt and reads a password, without
+// echo, from the terminal.
+func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	oldPrompt := t.prompt
+	t.prompt = []rune(prompt)
+	t.echo = false
+
+	line, err = t.readLine()
+
+	t.prompt = oldPrompt
+	t.echo = true
+
+	return
+}
+
+// ReadLine returns a line of input from the terminal.
+func (t *Terminal) ReadLine() (line string, err error) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	return t.readLine()
+}
+
+func (t *Terminal) readLine() (line string, err error) {
+	// t.lock must be held at this point
+
+	if t.cursorX == 0 && t.cursorY == 0 {
+		t.writeLine(t.prompt)
+		t.c.Write(t.outBuf)
+		t.outBuf = t.outBuf[:0]
+	}
+
+	lineIsPasted := t.pasteActive
+
+	for {
+		rest := t.remainder
+		lineOk := false
+		for !lineOk {
+			var key rune
+			key, rest = bytesToKey(rest, t.pasteActive)
+			if key == utf8.RuneError {
+				break
+			}
+			if !t.pasteActive {
+				if key == keyCtrlD {
+					if len(t.line) == 0 {
+						return "", io.EOF
+					}
+				}
+				if key == keyCtrlC {
+					return "", io.EOF
+				}
+				if key == keyPasteStart {
+					t.pasteActive = true
+					if len(t.line) == 0 {
+						lineIsPasted = true
+					}
+					continue
+				}
+			} else if key == keyPasteEnd {
+				t.pasteActive = false
+				continue
+			}
+			if !t.pasteActive {
+				lineIsPasted = false
+			}
+			line, lineOk = t.handleKey(key)
+		}
+		if len(rest) > 0 {
+			n := copy(t.inBuf[:], rest)
+			t.remainder = t.inBuf[:n]
+		} else {
+			t.remainder = nil
+		}
+		t.c.Write(t.outBuf)
+		t.outBuf = t.outBuf[:0]
+		if lineOk {
+			if t.echo {
+				t.historyIndex = -1
+				t.history.Add(line)
+			}
+			if lineIsPasted {
+				err = ErrPasteIndicator
+			}
+			return
+		}
+
+		// t.remainder is a slice at the beginning of t.inBuf
+		// containing a partial key sequence
+		readBuf := t.inBuf[len(t.remainder):]
+		var n int
+
+		t.lock.Unlock()
+		n, err = t.c.Read(readBuf)
+		t.lock.Lock()
+
+		if err != nil {
+			return
+		}
+
+		t.remainder = t.inBuf[:n+len(t.remainder)]
+	}
+}
+
+// SetPrompt sets the prompt to be used when reading subsequent lines.
+func (t *Terminal) SetPrompt(prompt string) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	t.prompt = []rune(prompt)
+}
+
+func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) {
+	// Move cursor to column zero at the start of the line.
+	t.move(t.cursorY, 0, t.cursorX, 0)
+	t.cursorX, t.cursorY = 0, 0
+	t.clearLineToRight()
+	for t.cursorY < numPrevLines {
+		// Move down a line
+		t.move(0, 1, 0, 0)
+		t.cursorY++
+		t.clearLineToRight()
+	}
+	// Move back to beginning.
+	t.move(t.cursorY, 0, 0, 0)
+	t.cursorX, t.cursorY = 0, 0
+
+	t.queue(t.prompt)
+	t.advanceCursor(visualLength(t.prompt))
+	t.writeLine(t.line)
+	t.moveCursorToPos(t.pos)
+}
+
+func (t *Terminal) SetSize(width, height int) error {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	if width == 0 {
+		width = 1
+	}
+
+	oldWidth := t.termWidth
+	t.termWidth, t.termHeight = width, height
+
+	switch {
+	case width == oldWidth:
+		// If the width didn't change then nothing else needs to be
+		// done.
+		return nil
+	case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0:
+		// If there is nothing on current line and no prompt printed,
+		// just do nothing
+		return nil
+	case width < oldWidth:
+		// Some terminals (e.g. xterm) will truncate lines that were
+		// too long when shinking. Others, (e.g. gnome-terminal) will
+		// attempt to wrap them. For the former, repainting t.maxLine
+		// works great, but that behaviour goes badly wrong in the case
+		// of the latter because they have doubled every full line.
+
+		// We assume that we are working on a terminal that wraps lines
+		// and adjust the cursor position based on every previous line
+		// wrapping and turning into two. This causes the prompt on
+		// xterms to move upwards, which isn't great, but it avoids a
+		// huge mess with gnome-terminal.
+		if t.cursorX >= t.termWidth {
+			t.cursorX = t.termWidth - 1
+		}
+		t.cursorY *= 2
+		t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2)
+	case width > oldWidth:
+		// If the terminal expands then our position calculations will
+		// be wrong in the future because we think the cursor is
+		// |t.pos| chars into the string, but there will be a gap at
+		// the end of any wrapped line.
+		//
+		// But the position will actually be correct until we move, so
+		// we can move back to the beginning and repaint everything.
+		t.clearAndRepaintLinePlusNPrevious(t.maxLine)
+	}
+
+	_, err := t.c.Write(t.outBuf)
+	t.outBuf = t.outBuf[:0]
+	return err
+}
+
+type pasteIndicatorError struct{}
+
+func (pasteIndicatorError) Error() string {
+	return "terminal: ErrPasteIndicator not correctly handled"
+}
+
+// ErrPasteIndicator may be returned from ReadLine as the error, in addition
+// to valid line data. It indicates that bracketed paste mode is enabled and
+// that the returned line consists only of pasted data. Programs may wish to
+// interpret pasted data more literally than typed data.
+var ErrPasteIndicator = pasteIndicatorError{}
+
+// SetBracketedPasteMode requests that the terminal bracket paste operations
+// with markers. Not all terminals support this but, if it is supported, then
+// enabling this mode will stop any autocomplete callback from running due to
+// pastes. Additionally, any lines that are completely pasted will be returned
+// from ReadLine with the error set to ErrPasteIndicator.
+func (t *Terminal) SetBracketedPasteMode(on bool) {
+	if on {
+		io.WriteString(t.c, "\x1b[?2004h")
+	} else {
+		io.WriteString(t.c, "\x1b[?2004l")
+	}
+}
+
+// stRingBuffer is a ring buffer of strings.
+type stRingBuffer struct {
+	// entries contains max elements.
+	entries []string
+	max     int
+	// head contains the index of the element most recently added to the ring.
+	head int
+	// size contains the number of elements in the ring.
+	size int
+}
+
+func (s *stRingBuffer) Add(a string) {
+	if s.entries == nil {
+		const defaultNumEntries = 100
+		s.entries = make([]string, defaultNumEntries)
+		s.max = defaultNumEntries
+	}
+
+	s.head = (s.head + 1) % s.max
+	s.entries[s.head] = a
+	if s.size < s.max {
+		s.size++
+	}
+}
+
+// NthPreviousEntry returns the value passed to the nth previous call to Add.
+// If n is zero then the immediately prior value is returned, if one, then the
+// next most recent, and so on. If such an element doesn't exist then ok is
+// false.
+func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
+	if n >= s.size {
+		return "", false
+	}
+	index := s.head - n
+	if index < 0 {
+		index += s.max
+	}
+	return s.entries[index], true
+}
+
+// readPasswordLine reads from reader until it finds \n or io.EOF.
+// The slice returned does not include the \n.
+// readPasswordLine also ignores any \r it finds.
+// Windows uses \r as end of line. So, on Windows, readPasswordLine
+// reads until it finds \r and ignores any \n it finds during processing.
+func readPasswordLine(reader io.Reader) ([]byte, error) {
+	var buf [1]byte
+	var ret []byte
+
+	for {
+		n, err := reader.Read(buf[:])
+		if n > 0 {
+			switch buf[0] {
+			case '\b':
+				if len(ret) > 0 {
+					ret = ret[:len(ret)-1]
+				}
+			case '\n':
+				if runtime.GOOS != "windows" {
+					return ret, nil
+				}
+				// otherwise ignore \n
+			case '\r':
+				if runtime.GOOS == "windows" {
+					return ret, nil
+				}
+				// otherwise ignore \r
+			default:
+				ret = append(ret, buf[0])
+			}
+			continue
+		}
+		if err != nil {
+			if err == io.EOF && len(ret) > 0 {
+				return ret, nil
+			}
+			return ret, err
+		}
+	}
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/cover/profile.go b/src/cmd/vendor/golang.org/x/tools/cover/profile.go
new file mode 100644
index 0000000..5719577
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/tools/cover/profile.go
@@ -0,0 +1,261 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package cover provides support for parsing coverage profiles
+// generated by "go test -coverprofile=cover.out".
+package cover // import "golang.org/x/tools/cover"
+
+import (
+	"bufio"
+	"errors"
+	"fmt"
+	"math"
+	"os"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+// Profile represents the profiling data for a specific file.
+type Profile struct {
+	FileName string
+	Mode     string
+	Blocks   []ProfileBlock
+}
+
+// ProfileBlock represents a single block of profiling data.
+type ProfileBlock struct {
+	StartLine, StartCol int
+	EndLine, EndCol     int
+	NumStmt, Count      int
+}
+
+type byFileName []*Profile
+
+func (p byFileName) Len() int           { return len(p) }
+func (p byFileName) Less(i, j int) bool { return p[i].FileName < p[j].FileName }
+func (p byFileName) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+// ParseProfiles parses profile data in the specified file and returns a
+// Profile for each source file described therein.
+func ParseProfiles(fileName string) ([]*Profile, error) {
+	pf, err := os.Open(fileName)
+	if err != nil {
+		return nil, err
+	}
+	defer pf.Close()
+
+	files := make(map[string]*Profile)
+	buf := bufio.NewReader(pf)
+	// First line is "mode: foo", where foo is "set", "count", or "atomic".
+	// Rest of file is in the format
+	//	encoding/base64/base64.go:34.44,37.40 3 1
+	// where the fields are: name.go:line.column,line.column numberOfStatements count
+	s := bufio.NewScanner(buf)
+	mode := ""
+	for s.Scan() {
+		line := s.Text()
+		if mode == "" {
+			const p = "mode: "
+			if !strings.HasPrefix(line, p) || line == p {
+				return nil, fmt.Errorf("bad mode line: %v", line)
+			}
+			mode = line[len(p):]
+			continue
+		}
+		fn, b, err := parseLine(line)
+		if err != nil {
+			return nil, fmt.Errorf("line %q doesn't match expected format: %v", line, err)
+		}
+		p := files[fn]
+		if p == nil {
+			p = &Profile{
+				FileName: fn,
+				Mode:     mode,
+			}
+			files[fn] = p
+		}
+		p.Blocks = append(p.Blocks, b)
+	}
+	if err := s.Err(); err != nil {
+		return nil, err
+	}
+	for _, p := range files {
+		sort.Sort(blocksByStart(p.Blocks))
+		// Merge samples from the same location.
+		j := 1
+		for i := 1; i < len(p.Blocks); i++ {
+			b := p.Blocks[i]
+			last := p.Blocks[j-1]
+			if b.StartLine == last.StartLine &&
+				b.StartCol == last.StartCol &&
+				b.EndLine == last.EndLine &&
+				b.EndCol == last.EndCol {
+				if b.NumStmt != last.NumStmt {
+					return nil, fmt.Errorf("inconsistent NumStmt: changed from %d to %d", last.NumStmt, b.NumStmt)
+				}
+				if mode == "set" {
+					p.Blocks[j-1].Count |= b.Count
+				} else {
+					p.Blocks[j-1].Count += b.Count
+				}
+				continue
+			}
+			p.Blocks[j] = b
+			j++
+		}
+		p.Blocks = p.Blocks[:j]
+	}
+	// Generate a sorted slice.
+	profiles := make([]*Profile, 0, len(files))
+	for _, profile := range files {
+		profiles = append(profiles, profile)
+	}
+	sort.Sort(byFileName(profiles))
+	return profiles, nil
+}
+
+// parseLine parses a line from a coverage file.
+// It is equivalent to the regex
+// ^(.+):([0-9]+)\.([0-9]+),([0-9]+)\.([0-9]+) ([0-9]+) ([0-9]+)$
+//
+// However, it is much faster: https://golang.org/cl/179377
+func parseLine(l string) (fileName string, block ProfileBlock, err error) {
+	end := len(l)
+
+	b := ProfileBlock{}
+	b.Count, end, err = seekBack(l, ' ', end, "Count")
+	if err != nil {
+		return "", b, err
+	}
+	b.NumStmt, end, err = seekBack(l, ' ', end, "NumStmt")
+	if err != nil {
+		return "", b, err
+	}
+	b.EndCol, end, err = seekBack(l, '.', end, "EndCol")
+	if err != nil {
+		return "", b, err
+	}
+	b.EndLine, end, err = seekBack(l, ',', end, "EndLine")
+	if err != nil {
+		return "", b, err
+	}
+	b.StartCol, end, err = seekBack(l, '.', end, "StartCol")
+	if err != nil {
+		return "", b, err
+	}
+	b.StartLine, end, err = seekBack(l, ':', end, "StartLine")
+	if err != nil {
+		return "", b, err
+	}
+	fn := l[0:end]
+	if fn == "" {
+		return "", b, errors.New("a FileName cannot be blank")
+	}
+	return fn, b, nil
+}
+
+// seekBack searches backwards from end to find sep in l, then returns the
+// value between sep and end as an integer.
+// If seekBack fails, the returned error will reference what.
+func seekBack(l string, sep byte, end int, what string) (value int, nextSep int, err error) {
+	// Since we're seeking backwards and we know only ASCII is legal for these values,
+	// we can ignore the possibility of non-ASCII characters.
+	for start := end - 1; start >= 0; start-- {
+		if l[start] == sep {
+			i, err := strconv.Atoi(l[start+1 : end])
+			if err != nil {
+				return 0, 0, fmt.Errorf("couldn't parse %q: %v", what, err)
+			}
+			if i < 0 {
+				return 0, 0, fmt.Errorf("negative values are not allowed for %s, found %d", what, i)
+			}
+			return i, start, nil
+		}
+	}
+	return 0, 0, fmt.Errorf("couldn't find a %s before %s", string(sep), what)
+}
+
+type blocksByStart []ProfileBlock
+
+func (b blocksByStart) Len() int      { return len(b) }
+func (b blocksByStart) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
+func (b blocksByStart) Less(i, j int) bool {
+	bi, bj := b[i], b[j]
+	return bi.StartLine < bj.StartLine || bi.StartLine == bj.StartLine && bi.StartCol < bj.StartCol
+}
+
+// Boundary represents the position in a source file of the beginning or end of a
+// block as reported by the coverage profile. In HTML mode, it will correspond to
+// the opening or closing of a <span> tag and will be used to colorize the source
+type Boundary struct {
+	Offset int     // Location as a byte offset in the source file.
+	Start  bool    // Is this the start of a block?
+	Count  int     // Event count from the cover profile.
+	Norm   float64 // Count normalized to [0..1].
+	Index  int     // Order in input file.
+}
+
+// Boundaries returns a Profile as a set of Boundary objects within the provided src.
+func (p *Profile) Boundaries(src []byte) (boundaries []Boundary) {
+	// Find maximum count.
+	max := 0
+	for _, b := range p.Blocks {
+		if b.Count > max {
+			max = b.Count
+		}
+	}
+	// Divisor for normalization.
+	divisor := math.Log(float64(max))
+
+	// boundary returns a Boundary, populating the Norm field with a normalized Count.
+	index := 0
+	boundary := func(offset int, start bool, count int) Boundary {
+		b := Boundary{Offset: offset, Start: start, Count: count, Index: index}
+		index++
+		if !start || count == 0 {
+			return b
+		}
+		if max <= 1 {
+			b.Norm = 0.8 // Profile is in"set" mode; we want a heat map. Use cov8 in the CSS.
+		} else if count > 0 {
+			b.Norm = math.Log(float64(count)) / divisor
+		}
+		return b
+	}
+
+	line, col := 1, 2 // TODO: Why is this 2?
+	for si, bi := 0, 0; si < len(src) && bi < len(p.Blocks); {
+		b := p.Blocks[bi]
+		if b.StartLine == line && b.StartCol == col {
+			boundaries = append(boundaries, boundary(si, true, b.Count))
+		}
+		if b.EndLine == line && b.EndCol == col || line > b.EndLine {
+			boundaries = append(boundaries, boundary(si, false, 0))
+			bi++
+			continue // Don't advance through src; maybe the next block starts here.
+		}
+		if src[si] == '\n' {
+			line++
+			col = 0
+		}
+		col++
+		si++
+	}
+	sort.Sort(boundariesByPos(boundaries))
+	return
+}
+
+type boundariesByPos []Boundary
+
+func (b boundariesByPos) Len() int      { return len(b) }
+func (b boundariesByPos) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
+func (b boundariesByPos) Less(i, j int) bool {
+	if b[i].Offset == b[j].Offset {
+		// Boundaries at the same offset should be ordered according to
+		// their original position.
+		return b[i].Index < b[j].Index
+	}
+	return b[i].Offset < b[j].Offset
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go
index 841b928..c4407ad 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go
@@ -2,14 +2,17 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.16
+// +build go1.16
+
 // Package buildtag defines an Analyzer that checks build tags.
 package buildtag
 
 import (
-	"bytes"
-	"fmt"
 	"go/ast"
+	"go/build/constraint"
 	"go/parser"
+	"go/token"
 	"strings"
 	"unicode"
 
@@ -52,118 +55,313 @@
 }
 
 func checkGoFile(pass *analysis.Pass, f *ast.File) {
-	pastCutoff := false
+	var check checker
+	check.init(pass)
+	defer check.finish()
+
 	for _, group := range f.Comments {
 		// A +build comment is ignored after or adjoining the package declaration.
 		if group.End()+1 >= f.Package {
-			pastCutoff = true
+			check.plusBuildOK = false
 		}
-
-		// "+build" is ignored within or after a /*...*/ comment.
-		if !strings.HasPrefix(group.List[0].Text, "//") {
-			pastCutoff = true
-			continue
+		// A //go:build comment is ignored after the package declaration
+		// (but adjoining it is OK, in contrast to +build comments).
+		if group.Pos() >= f.Package {
+			check.goBuildOK = false
 		}
 
 		// Check each line of a //-comment.
 		for _, c := range group.List {
-			if !strings.Contains(c.Text, "+build") {
-				continue
+			// "+build" is ignored within or after a /*...*/ comment.
+			if !strings.HasPrefix(c.Text, "//") {
+				check.plusBuildOK = false
 			}
-			if err := checkLine(c.Text, pastCutoff); err != nil {
-				pass.Reportf(c.Pos(), "%s", err)
-			}
+			check.comment(c.Slash, c.Text)
 		}
 	}
 }
 
 func checkOtherFile(pass *analysis.Pass, filename string) error {
+	var check checker
+	check.init(pass)
+	defer check.finish()
+
+	// We cannot use the Go parser, since this may not be a Go source file.
+	// Read the raw bytes instead.
 	content, tf, err := analysisutil.ReadFile(pass.Fset, filename)
 	if err != nil {
 		return err
 	}
 
-	// We must look at the raw lines, as build tags may appear in non-Go
-	// files such as assembly files.
-	lines := bytes.SplitAfter(content, nl)
+	check.file(token.Pos(tf.Base()), string(content))
+	return nil
+}
 
+type checker struct {
+	pass         *analysis.Pass
+	plusBuildOK  bool            // "+build" lines still OK
+	goBuildOK    bool            // "go:build" lines still OK
+	crossCheck   bool            // cross-check go:build and +build lines when done reading file
+	inStar       bool            // currently in a /* */ comment
+	goBuildPos   token.Pos       // position of first go:build line found
+	plusBuildPos token.Pos       // position of first "+build" line found
+	goBuild      constraint.Expr // go:build constraint found
+	plusBuild    constraint.Expr // AND of +build constraints found
+}
+
+func (check *checker) init(pass *analysis.Pass) {
+	check.pass = pass
+	check.goBuildOK = true
+	check.plusBuildOK = true
+	check.crossCheck = true
+}
+
+func (check *checker) file(pos token.Pos, text string) {
 	// Determine cutpoint where +build comments are no longer valid.
 	// They are valid in leading // comments in the file followed by
 	// a blank line.
 	//
 	// This must be done as a separate pass because of the
 	// requirement that the comment be followed by a blank line.
-	var cutoff int
-	for i, line := range lines {
-		line = bytes.TrimSpace(line)
-		if !bytes.HasPrefix(line, slashSlash) {
-			if len(line) > 0 {
-				break
+	var plusBuildCutoff int
+	fullText := text
+	for text != "" {
+		i := strings.Index(text, "\n")
+		if i < 0 {
+			i = len(text)
+		} else {
+			i++
+		}
+		offset := len(fullText) - len(text)
+		line := text[:i]
+		text = text[i:]
+		line = strings.TrimSpace(line)
+		if !strings.HasPrefix(line, "//") && line != "" {
+			break
+		}
+		if line == "" {
+			plusBuildCutoff = offset
+		}
+	}
+
+	// Process each line.
+	// Must stop once we hit goBuildOK == false
+	text = fullText
+	check.inStar = false
+	for text != "" {
+		i := strings.Index(text, "\n")
+		if i < 0 {
+			i = len(text)
+		} else {
+			i++
+		}
+		offset := len(fullText) - len(text)
+		line := text[:i]
+		text = text[i:]
+		check.plusBuildOK = offset < plusBuildCutoff
+
+		if strings.HasPrefix(line, "//") {
+			check.comment(pos+token.Pos(offset), line)
+			continue
+		}
+
+		// Keep looking for the point at which //go:build comments
+		// stop being allowed. Skip over, cut out any /* */ comments.
+		for {
+			line = strings.TrimSpace(line)
+			if check.inStar {
+				i := strings.Index(line, "*/")
+				if i < 0 {
+					line = ""
+					break
+				}
+				line = line[i+len("*/"):]
+				check.inStar = false
+				continue
 			}
-			cutoff = i
+			if strings.HasPrefix(line, "/*") {
+				check.inStar = true
+				line = line[len("/*"):]
+				continue
+			}
+			break
+		}
+		if line != "" {
+			// Found non-comment non-blank line.
+			// Ends space for valid //go:build comments,
+			// but also ends the fraction of the file we can
+			// reliably parse. From this point on we might
+			// incorrectly flag "comments" inside multiline
+			// string constants or anything else (this might
+			// not even be a Go program). So stop.
+			break
 		}
 	}
-
-	for i, line := range lines {
-		line = bytes.TrimSpace(line)
-		if !bytes.HasPrefix(line, slashSlash) {
-			continue
-		}
-		if !bytes.Contains(line, []byte("+build")) {
-			continue
-		}
-		if err := checkLine(string(line), i >= cutoff); err != nil {
-			pass.Reportf(analysisutil.LineStart(tf, i+1), "%s", err)
-			continue
-		}
-	}
-	return nil
 }
 
-// checkLine checks a line that starts with "//" and contains "+build".
-func checkLine(line string, pastCutoff bool) error {
-	line = strings.TrimPrefix(line, "//")
-	line = strings.TrimSpace(line)
+func (check *checker) comment(pos token.Pos, text string) {
+	if strings.HasPrefix(text, "//") {
+		if strings.Contains(text, "+build") {
+			check.plusBuildLine(pos, text)
+		}
+		if strings.Contains(text, "//go:build") {
+			check.goBuildLine(pos, text)
+		}
+	}
+	if strings.HasPrefix(text, "/*") {
+		if i := strings.Index(text, "\n"); i >= 0 {
+			// multiline /* */ comment - process interior lines
+			check.inStar = true
+			i++
+			pos += token.Pos(i)
+			text = text[i:]
+			for text != "" {
+				i := strings.Index(text, "\n")
+				if i < 0 {
+					i = len(text)
+				} else {
+					i++
+				}
+				line := text[:i]
+				if strings.HasPrefix(line, "//") {
+					check.comment(pos, line)
+				}
+				pos += token.Pos(i)
+				text = text[i:]
+			}
+			check.inStar = false
+		}
+	}
+}
 
-	if strings.HasPrefix(line, "+build") {
-		fields := strings.Fields(line)
-		if fields[0] != "+build" {
-			// Comment is something like +buildasdf not +build.
-			return fmt.Errorf("possible malformed +build comment")
+func (check *checker) goBuildLine(pos token.Pos, line string) {
+	if !constraint.IsGoBuild(line) {
+		if !strings.HasPrefix(line, "//go:build") && constraint.IsGoBuild("//"+strings.TrimSpace(line[len("//"):])) {
+			check.pass.Reportf(pos, "malformed //go:build line (space between // and go:build)")
 		}
-		if pastCutoff {
-			return fmt.Errorf("+build comment must appear before package clause and be followed by a blank line")
-		}
-		if err := checkArguments(fields); err != nil {
-			return err
-		}
+		return
+	}
+	if !check.goBuildOK || check.inStar {
+		check.pass.Reportf(pos, "misplaced //go:build comment")
+		check.crossCheck = false
+		return
+	}
+
+	if check.goBuildPos == token.NoPos {
+		check.goBuildPos = pos
 	} else {
-		// Comment with +build but not at beginning.
-		if !pastCutoff {
-			return fmt.Errorf("possible malformed +build comment")
-		}
+		check.pass.Reportf(pos, "unexpected extra //go:build line")
+		check.crossCheck = false
 	}
-	return nil
+
+	// testing hack: stop at // ERROR
+	if i := strings.Index(line, " // ERROR "); i >= 0 {
+		line = line[:i]
+	}
+
+	x, err := constraint.Parse(line)
+	if err != nil {
+		check.pass.Reportf(pos, "%v", err)
+		check.crossCheck = false
+		return
+	}
+
+	if check.goBuild == nil {
+		check.goBuild = x
+	}
 }
 
-func checkArguments(fields []string) error {
+func (check *checker) plusBuildLine(pos token.Pos, line string) {
+	line = strings.TrimSpace(line)
+	if !constraint.IsPlusBuild(line) {
+		// Comment with +build but not at beginning.
+		// Only report early in file.
+		if check.plusBuildOK && !strings.HasPrefix(line, "// want") {
+			check.pass.Reportf(pos, "possible malformed +build comment")
+		}
+		return
+	}
+	if !check.plusBuildOK { // inStar implies !plusBuildOK
+		check.pass.Reportf(pos, "misplaced +build comment")
+		check.crossCheck = false
+	}
+
+	if check.plusBuildPos == token.NoPos {
+		check.plusBuildPos = pos
+	}
+
+	// testing hack: stop at // ERROR
+	if i := strings.Index(line, " // ERROR "); i >= 0 {
+		line = line[:i]
+	}
+
+	fields := strings.Fields(line[len("//"):])
+	// IsPlusBuildConstraint check above implies fields[0] == "+build"
 	for _, arg := range fields[1:] {
 		for _, elem := range strings.Split(arg, ",") {
 			if strings.HasPrefix(elem, "!!") {
-				return fmt.Errorf("invalid double negative in build constraint: %s", arg)
+				check.pass.Reportf(pos, "invalid double negative in build constraint: %s", arg)
+				check.crossCheck = false
+				continue
 			}
 			elem = strings.TrimPrefix(elem, "!")
 			for _, c := range elem {
 				if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
-					return fmt.Errorf("invalid non-alphanumeric build constraint: %s", arg)
+					check.pass.Reportf(pos, "invalid non-alphanumeric build constraint: %s", arg)
+					check.crossCheck = false
+					break
 				}
 			}
 		}
 	}
-	return nil
+
+	if check.crossCheck {
+		y, err := constraint.Parse(line)
+		if err != nil {
+			// Should never happen - constraint.Parse never rejects a // +build line.
+			// Also, we just checked the syntax above.
+			// Even so, report.
+			check.pass.Reportf(pos, "%v", err)
+			check.crossCheck = false
+			return
+		}
+		if check.plusBuild == nil {
+			check.plusBuild = y
+		} else {
+			check.plusBuild = &constraint.AndExpr{X: check.plusBuild, Y: y}
+		}
+	}
 }
 
-var (
-	nl         = []byte("\n")
-	slashSlash = []byte("//")
-)
+func (check *checker) finish() {
+	if !check.crossCheck || check.plusBuildPos == token.NoPos || check.goBuildPos == token.NoPos {
+		return
+	}
+
+	// Have both //go:build and // +build,
+	// with no errors found (crossCheck still true).
+	// Check they match.
+	var want constraint.Expr
+	lines, err := constraint.PlusBuildLines(check.goBuild)
+	if err != nil {
+		check.pass.Reportf(check.goBuildPos, "%v", err)
+		return
+	}
+	for _, line := range lines {
+		y, err := constraint.Parse(line)
+		if err != nil {
+			// Definitely should not happen, but not the user's fault.
+			// Do not report.
+			return
+		}
+		if want == nil {
+			want = y
+		} else {
+			want = &constraint.AndExpr{X: want, Y: y}
+		}
+	}
+	if want.String() != check.plusBuild.String() {
+		check.pass.Reportf(check.plusBuildPos, "+build lines do not match //go:build condition")
+		return
+	}
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag_old.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag_old.go
new file mode 100644
index 0000000..e923492
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag_old.go
@@ -0,0 +1,174 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Delete this file once Go 1.17 comes out and we can retire Go 1.15 support.
+
+//go:build !go1.16
+// +build !go1.16
+
+// Package buildtag defines an Analyzer that checks build tags.
+package buildtag
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"strings"
+	"unicode"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
+)
+
+const Doc = "check that +build tags are well-formed and correctly located"
+
+var Analyzer = &analysis.Analyzer{
+	Name: "buildtag",
+	Doc:  Doc,
+	Run:  runBuildTag,
+}
+
+func runBuildTag(pass *analysis.Pass) (interface{}, error) {
+	for _, f := range pass.Files {
+		checkGoFile(pass, f)
+	}
+	for _, name := range pass.OtherFiles {
+		if err := checkOtherFile(pass, name); err != nil {
+			return nil, err
+		}
+	}
+	for _, name := range pass.IgnoredFiles {
+		if strings.HasSuffix(name, ".go") {
+			f, err := parser.ParseFile(pass.Fset, name, nil, parser.ParseComments)
+			if err != nil {
+				// Not valid Go source code - not our job to diagnose, so ignore.
+				return nil, nil
+			}
+			checkGoFile(pass, f)
+		} else {
+			if err := checkOtherFile(pass, name); err != nil {
+				return nil, err
+			}
+		}
+	}
+	return nil, nil
+}
+
+func checkGoFile(pass *analysis.Pass, f *ast.File) {
+	pastCutoff := false
+	for _, group := range f.Comments {
+		// A +build comment is ignored after or adjoining the package declaration.
+		if group.End()+1 >= f.Package {
+			pastCutoff = true
+		}
+
+		// "+build" is ignored within or after a /*...*/ comment.
+		if !strings.HasPrefix(group.List[0].Text, "//") {
+			pastCutoff = true
+			continue
+		}
+
+		// Check each line of a //-comment.
+		for _, c := range group.List {
+			if !strings.Contains(c.Text, "+build") {
+				continue
+			}
+			if err := checkLine(c.Text, pastCutoff); err != nil {
+				pass.Reportf(c.Pos(), "%s", err)
+			}
+		}
+	}
+}
+
+func checkOtherFile(pass *analysis.Pass, filename string) error {
+	content, tf, err := analysisutil.ReadFile(pass.Fset, filename)
+	if err != nil {
+		return err
+	}
+
+	// We must look at the raw lines, as build tags may appear in non-Go
+	// files such as assembly files.
+	lines := bytes.SplitAfter(content, nl)
+
+	// Determine cutpoint where +build comments are no longer valid.
+	// They are valid in leading // comments in the file followed by
+	// a blank line.
+	//
+	// This must be done as a separate pass because of the
+	// requirement that the comment be followed by a blank line.
+	var cutoff int
+	for i, line := range lines {
+		line = bytes.TrimSpace(line)
+		if !bytes.HasPrefix(line, slashSlash) {
+			if len(line) > 0 {
+				break
+			}
+			cutoff = i
+		}
+	}
+
+	for i, line := range lines {
+		line = bytes.TrimSpace(line)
+		if !bytes.HasPrefix(line, slashSlash) {
+			continue
+		}
+		if !bytes.Contains(line, []byte("+build")) {
+			continue
+		}
+		if err := checkLine(string(line), i >= cutoff); err != nil {
+			pass.Reportf(analysisutil.LineStart(tf, i+1), "%s", err)
+			continue
+		}
+	}
+	return nil
+}
+
+// checkLine checks a line that starts with "//" and contains "+build".
+func checkLine(line string, pastCutoff bool) error {
+	line = strings.TrimPrefix(line, "//")
+	line = strings.TrimSpace(line)
+
+	if strings.HasPrefix(line, "+build") {
+		fields := strings.Fields(line)
+		if fields[0] != "+build" {
+			// Comment is something like +buildasdf not +build.
+			return fmt.Errorf("possible malformed +build comment")
+		}
+		if pastCutoff {
+			return fmt.Errorf("+build comment must appear before package clause and be followed by a blank line")
+		}
+		if err := checkArguments(fields); err != nil {
+			return err
+		}
+	} else {
+		// Comment with +build but not at beginning.
+		if !pastCutoff {
+			return fmt.Errorf("possible malformed +build comment")
+		}
+	}
+	return nil
+}
+
+func checkArguments(fields []string) error {
+	for _, arg := range fields[1:] {
+		for _, elem := range strings.Split(arg, ",") {
+			if strings.HasPrefix(elem, "!!") {
+				return fmt.Errorf("invalid double negative in build constraint: %s", arg)
+			}
+			elem = strings.TrimPrefix(elem, "!")
+			for _, c := range elem {
+				if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
+					return fmt.Errorf("invalid non-alphanumeric build constraint: %s", arg)
+				}
+			}
+		}
+	}
+	return nil
+}
+
+var (
+	nl         = []byte("\n")
+	slashSlash = []byte("//")
+)
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go
index 2856df1..4bb652a 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go
@@ -3,8 +3,8 @@
 // license that can be found in the LICENSE file.
 
 // Package inspect defines an Analyzer that provides an AST inspector
-// (golang.org/x/tools/go/ast/inspect.Inspect) for the syntax trees of a
-// package. It is only a building block for other analyzers.
+// (golang.org/x/tools/go/ast/inspector.Inspector) for the syntax trees
+// of a package. It is only a building block for other analyzers.
 //
 // Example of use in another analysis:
 //
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go
index a14e7eb..3ea9157 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go
@@ -8,22 +8,14 @@
 
 import (
 	"go/ast"
+	"go/types"
 
 	"golang.org/x/tools/go/analysis"
 	"golang.org/x/tools/go/analysis/passes/inspect"
 	"golang.org/x/tools/go/ast/inspector"
+	"golang.org/x/tools/go/types/typeutil"
 )
 
-// TODO(adonovan): also report an error for the following structure,
-// which is often used to ensure that deferred calls do not accumulate
-// in a loop:
-//
-//	for i, x := range c {
-//		func() {
-//			...reference to i or x...
-//		}()
-//	}
-
 const Doc = `check references to loop variables from within nested functions
 
 This analyzer checks for references to loop variables from within a
@@ -95,16 +87,19 @@
 		if len(body.List) == 0 {
 			return
 		}
-		var last *ast.CallExpr
+		// The function invoked in the last return statement.
+		var fun ast.Expr
 		switch s := body.List[len(body.List)-1].(type) {
 		case *ast.GoStmt:
-			last = s.Call
+			fun = s.Call.Fun
 		case *ast.DeferStmt:
-			last = s.Call
-		default:
-			return
+			fun = s.Call.Fun
+		case *ast.ExprStmt: // check for errgroup.Group.Go()
+			if call, ok := s.X.(*ast.CallExpr); ok {
+				fun = goInvokes(pass.TypesInfo, call)
+			}
 		}
-		lit, ok := last.Fun.(*ast.FuncLit)
+		lit, ok := fun.(*ast.FuncLit)
 		if !ok {
 			return
 		}
@@ -128,3 +123,43 @@
 	})
 	return nil, nil
 }
+
+// goInvokes returns a function expression that would be called asynchronously
+// (but not awaited) in another goroutine as a consequence of the call.
+// For example, given the g.Go call below, it returns the function literal expression.
+//
+//   import "sync/errgroup"
+//   var g errgroup.Group
+//   g.Go(func() error { ... })
+//
+// Currently only "golang.org/x/sync/errgroup.Group()" is considered.
+func goInvokes(info *types.Info, call *ast.CallExpr) ast.Expr {
+	f := typeutil.StaticCallee(info, call)
+	// Note: Currently only supports: golang.org/x/sync/errgroup.Go.
+	if f == nil || f.Name() != "Go" {
+		return nil
+	}
+	recv := f.Type().(*types.Signature).Recv()
+	if recv == nil {
+		return nil
+	}
+	rtype, ok := recv.Type().(*types.Pointer)
+	if !ok {
+		return nil
+	}
+	named, ok := rtype.Elem().(*types.Named)
+	if !ok {
+		return nil
+	}
+	if named.Obj().Name() != "Group" {
+		return nil
+	}
+	pkg := f.Pkg()
+	if pkg == nil {
+		return nil
+	}
+	if pkg.Path() != "golang.org/x/sync/errgroup" {
+		return nil
+	}
+	return call.Args[0]
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
index ddad4c7..822820f 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
@@ -590,7 +590,7 @@
 		}
 		if state.verb == 'w' {
 			if kind != KindErrorf {
-				pass.Reportf(call.Pos(), "%s call has error-wrapping directive %%w", state.name)
+				pass.Reportf(call.Pos(), "%s call has error-wrapping directive %%w, which is only supported by Errorf", state.name)
 				return
 			}
 			if anyW {
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/sigchanyzer/sigchanyzer.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/sigchanyzer/sigchanyzer.go
new file mode 100644
index 0000000..0d6c8eb
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/sigchanyzer/sigchanyzer.go
@@ -0,0 +1,154 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package sigchanyzer defines an Analyzer that detects
+// misuse of unbuffered signal as argument to signal.Notify.
+package sigchanyzer
+
+import (
+	"bytes"
+	"go/ast"
+	"go/format"
+	"go/token"
+	"go/types"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+const Doc = `check for unbuffered channel of os.Signal
+
+This checker reports call expression of the form signal.Notify(c <-chan os.Signal, sig ...os.Signal),
+where c is an unbuffered channel, which can be at risk of missing the signal.`
+
+// Analyzer describes sigchanyzer analysis function detector.
+var Analyzer = &analysis.Analyzer{
+	Name:     "sigchanyzer",
+	Doc:      Doc,
+	Requires: []*analysis.Analyzer{inspect.Analyzer},
+	Run:      run,
+}
+
+func run(pass *analysis.Pass) (interface{}, error) {
+	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+
+	nodeFilter := []ast.Node{
+		(*ast.CallExpr)(nil),
+	}
+	inspect.Preorder(nodeFilter, func(n ast.Node) {
+		call := n.(*ast.CallExpr)
+		if !isSignalNotify(pass.TypesInfo, call) {
+			return
+		}
+		var chanDecl *ast.CallExpr
+		switch arg := call.Args[0].(type) {
+		case *ast.Ident:
+			if decl, ok := findDecl(arg).(*ast.CallExpr); ok {
+				chanDecl = decl
+			}
+		case *ast.CallExpr:
+			// Only signal.Notify(make(chan os.Signal), os.Interrupt) is safe,
+			// conservatively treate others as not safe, see golang/go#45043
+			if isBuiltinMake(pass.TypesInfo, arg) {
+				return
+			}
+			chanDecl = arg
+		}
+		if chanDecl == nil || len(chanDecl.Args) != 1 {
+			return
+		}
+
+		// Make a copy of the channel's declaration to avoid
+		// mutating the AST. See https://golang.org/issue/46129.
+		chanDeclCopy := &ast.CallExpr{}
+		*chanDeclCopy = *chanDecl
+		chanDeclCopy.Args = append([]ast.Expr(nil), chanDecl.Args...)
+		chanDeclCopy.Args = append(chanDeclCopy.Args, &ast.BasicLit{
+			Kind:  token.INT,
+			Value: "1",
+		})
+
+		var buf bytes.Buffer
+		if err := format.Node(&buf, token.NewFileSet(), chanDeclCopy); err != nil {
+			return
+		}
+		pass.Report(analysis.Diagnostic{
+			Pos:     call.Pos(),
+			End:     call.End(),
+			Message: "misuse of unbuffered os.Signal channel as argument to signal.Notify",
+			SuggestedFixes: []analysis.SuggestedFix{{
+				Message: "Change to buffer channel",
+				TextEdits: []analysis.TextEdit{{
+					Pos:     chanDecl.Pos(),
+					End:     chanDecl.End(),
+					NewText: buf.Bytes(),
+				}},
+			}},
+		})
+	})
+	return nil, nil
+}
+
+func isSignalNotify(info *types.Info, call *ast.CallExpr) bool {
+	check := func(id *ast.Ident) bool {
+		obj := info.ObjectOf(id)
+		return obj.Name() == "Notify" && obj.Pkg().Path() == "os/signal"
+	}
+	switch fun := call.Fun.(type) {
+	case *ast.SelectorExpr:
+		return check(fun.Sel)
+	case *ast.Ident:
+		if fun, ok := findDecl(fun).(*ast.SelectorExpr); ok {
+			return check(fun.Sel)
+		}
+		return false
+	default:
+		return false
+	}
+}
+
+func findDecl(arg *ast.Ident) ast.Node {
+	if arg.Obj == nil {
+		return nil
+	}
+	switch as := arg.Obj.Decl.(type) {
+	case *ast.AssignStmt:
+		if len(as.Lhs) != len(as.Rhs) {
+			return nil
+		}
+		for i, lhs := range as.Lhs {
+			lid, ok := lhs.(*ast.Ident)
+			if !ok {
+				continue
+			}
+			if lid.Obj == arg.Obj {
+				return as.Rhs[i]
+			}
+		}
+	case *ast.ValueSpec:
+		if len(as.Names) != len(as.Values) {
+			return nil
+		}
+		for i, name := range as.Names {
+			if name.Obj == arg.Obj {
+				return as.Values[i]
+			}
+		}
+	}
+	return nil
+}
+
+func isBuiltinMake(info *types.Info, call *ast.CallExpr) bool {
+	typVal := info.Types[call.Fun]
+	if !typVal.IsBuiltin() {
+		return false
+	}
+	switch fun := call.Fun.(type) {
+	case *ast.Ident:
+		return info.ObjectOf(fun).Name() == "make"
+	default:
+		return false
+	}
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go
index 856c6ae..64a28ac 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go
@@ -61,10 +61,12 @@
 // we let it go. But if it does have a fmt.ScanState, then the
 // rest has to match.
 var canonicalMethods = map[string]struct{ args, results []string }{
+	"As": {[]string{"interface{}"}, []string{"bool"}}, // errors.As
 	// "Flush": {{}, {"error"}}, // http.Flusher and jpeg.writer conflict
 	"Format":        {[]string{"=fmt.State", "rune"}, []string{}},                      // fmt.Formatter
 	"GobDecode":     {[]string{"[]byte"}, []string{"error"}},                           // gob.GobDecoder
 	"GobEncode":     {[]string{}, []string{"[]byte", "error"}},                         // gob.GobEncoder
+	"Is":            {[]string{"error"}, []string{"bool"}},                             // errors.Is
 	"MarshalJSON":   {[]string{}, []string{"[]byte", "error"}},                         // json.Marshaler
 	"MarshalXML":    {[]string{"*xml.Encoder", "xml.StartElement"}, []string{"error"}}, // xml.Marshaler
 	"ReadByte":      {[]string{}, []string{"byte", "error"}},                           // io.ByteReader
@@ -76,6 +78,7 @@
 	"UnmarshalXML":  {[]string{"*xml.Decoder", "xml.StartElement"}, []string{"error"}}, // xml.Unmarshaler
 	"UnreadByte":    {[]string{}, []string{"error"}},
 	"UnreadRune":    {[]string{}, []string{"error"}},
+	"Unwrap":        {[]string{}, []string{"error"}},                      // errors.Unwrap
 	"WriteByte":     {[]string{"byte"}, []string{"error"}},                // jpeg.writer (matching bufio.Writer)
 	"WriteTo":       {[]string{"=io.Writer"}, []string{"int64", "error"}}, // io.WriterTo
 }
@@ -123,6 +126,14 @@
 		return
 	}
 
+	// Special case: Is, As and Unwrap only apply when type
+	// implements error.
+	if id.Name == "Is" || id.Name == "As" || id.Name == "Unwrap" {
+		if recv := sign.Recv(); recv == nil || !implementsError(recv.Type()) {
+			return
+		}
+	}
+
 	// Do the =s (if any) all match?
 	if !matchParams(pass, expect.args, args, "=") || !matchParams(pass, expect.results, results, "=") {
 		return
@@ -185,3 +196,9 @@
 	// Overkill but easy.
 	return typeString(actual) == expect
 }
+
+var errorType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface)
+
+func implementsError(actual types.Type) bool {
+	return types.Implements(actual, errorType)
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
index 713e138..5424489 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
@@ -97,7 +97,7 @@
 
 Usage of %[1]s:
 	%.16[1]s unit.cfg	# execute analysis specified by config file
-	%.16[1]s help    	# general help
+	%.16[1]s help    	# general help, including listing analyzers and flags
 	%.16[1]s help name	# help on specific analyzer and its flags
 `, progname)
 		os.Exit(1)
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go
index 9051456..3180f4a 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.12
 // +build go1.12
 
 package unitchecker
diff --git a/src/cmd/vendor/golang.org/x/xerrors/go.mod b/src/cmd/vendor/golang.org/x/xerrors/go.mod
deleted file mode 100644
index 870d4f6..0000000
--- a/src/cmd/vendor/golang.org/x/xerrors/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module golang.org/x/xerrors
-
-go 1.11
diff --git a/src/cmd/vendor/modules.txt b/src/cmd/vendor/modules.txt
index ae2c0a0..34dbdaf 100644
--- a/src/cmd/vendor/modules.txt
+++ b/src/cmd/vendor/modules.txt
@@ -1,5 +1,5 @@
-# github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2
-## explicit
+# github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a
+## explicit; go 1.14
 github.com/google/pprof/driver
 github.com/google/pprof/internal/binutils
 github.com/google/pprof/internal/driver
@@ -16,20 +16,20 @@
 github.com/google/pprof/third_party/d3flamegraph
 github.com/google/pprof/third_party/svgpan
 # github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639
-github.com/ianlancetaylor/demangle
-# golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
 ## explicit
+github.com/ianlancetaylor/demangle
+# golang.org/x/arch v0.0.0-20210502124803-cbf565b21d1e
+## explicit; go 1.17
 golang.org/x/arch/arm/armasm
 golang.org/x/arch/arm64/arm64asm
 golang.org/x/arch/ppc64/ppc64asm
 golang.org/x/arch/x86/x86asm
-# golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
-## explicit
+# golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e
+## explicit; go 1.17
 golang.org/x/crypto/ed25519
 golang.org/x/crypto/ed25519/internal/edwards25519
-golang.org/x/crypto/ssh/terminal
-# golang.org/x/mod v0.4.2-0.20210325185522-dbbbf8a3c6ea
-## explicit
+# golang.org/x/mod v0.4.3-0.20210608190319-0f08993efd8a
+## explicit; go 1.17
 golang.org/x/mod/internal/lazyregexp
 golang.org/x/mod/modfile
 golang.org/x/mod/module
@@ -39,13 +39,18 @@
 golang.org/x/mod/sumdb/note
 golang.org/x/mod/sumdb/tlog
 golang.org/x/mod/zip
-# golang.org/x/sys v0.0.0-20201204225414-ed752295db88
-## explicit
+# golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744
+## explicit; go 1.17
 golang.org/x/sys/internal/unsafeheader
+golang.org/x/sys/plan9
 golang.org/x/sys/unix
 golang.org/x/sys/windows
-# golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff
-## explicit
+# golang.org/x/term v0.0.0-20210503060354-a79de5458b56
+## explicit; go 1.17
+golang.org/x/term
+# golang.org/x/tools v0.1.2-0.20210519160823-49064d2332f9
+## explicit; go 1.17
+golang.org/x/tools/cover
 golang.org/x/tools/go/analysis
 golang.org/x/tools/go/analysis/internal/analysisflags
 golang.org/x/tools/go/analysis/internal/facts
@@ -69,6 +74,7 @@
 golang.org/x/tools/go/analysis/passes/nilfunc
 golang.org/x/tools/go/analysis/passes/printf
 golang.org/x/tools/go/analysis/passes/shift
+golang.org/x/tools/go/analysis/passes/sigchanyzer
 golang.org/x/tools/go/analysis/passes/stdmethods
 golang.org/x/tools/go/analysis/passes/stringintconv
 golang.org/x/tools/go/analysis/passes/structtag
@@ -87,5 +93,6 @@
 golang.org/x/tools/internal/analysisinternal
 golang.org/x/tools/internal/lsp/fuzzy
 # golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
+## explicit; go 1.11
 golang.org/x/xerrors
 golang.org/x/xerrors/internal
diff --git a/src/cmd/vet/main.go b/src/cmd/vet/main.go
index d50c45d..7da8606 100644
--- a/src/cmd/vet/main.go
+++ b/src/cmd/vet/main.go
@@ -1,3 +1,7 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package main
 
 import (
@@ -22,6 +26,7 @@
 	"golang.org/x/tools/go/analysis/passes/nilfunc"
 	"golang.org/x/tools/go/analysis/passes/printf"
 	"golang.org/x/tools/go/analysis/passes/shift"
+	"golang.org/x/tools/go/analysis/passes/sigchanyzer"
 	"golang.org/x/tools/go/analysis/passes/stdmethods"
 	"golang.org/x/tools/go/analysis/passes/stringintconv"
 	"golang.org/x/tools/go/analysis/passes/structtag"
@@ -54,6 +59,7 @@
 		nilfunc.Analyzer,
 		printf.Analyzer,
 		shift.Analyzer,
+		sigchanyzer.Analyzer,
 		stdmethods.Analyzer,
 		stringintconv.Analyzer,
 		structtag.Analyzer,
diff --git a/src/cmd/vet/testdata/asm/asm1.s b/src/cmd/vet/testdata/asm/asm1.s
index a5bb6dd..050c498 100644
--- a/src/cmd/vet/testdata/asm/asm1.s
+++ b/src/cmd/vet/testdata/asm/asm1.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64
 // +build amd64
 
 TEXT ·arg1(SB),0,$0-2
diff --git a/src/cmd/vet/testdata/buildtag/buildtag.go b/src/cmd/vet/testdata/buildtag/buildtag.go
index c2fd6aa..7371e6e 100644
--- a/src/cmd/vet/testdata/buildtag/buildtag.go
+++ b/src/cmd/vet/testdata/buildtag/buildtag.go
@@ -4,12 +4,14 @@
 
 // This file contains tests for the buildtag checker.
 
-// +builder // ERROR "possible malformed \+build comment"
+// ERRORNEXT "possible malformed [+]build comment"
+// +builder
 // +build !ignore
 
 package testdata
 
-// +build toolate // ERROR "build comment must appear before package clause and be followed by a blank line$"
+// ERRORNEXT "misplaced \+build comment"
+// +build toolate
 
 var _ = 3
 
diff --git a/src/cmd/vet/testdata/buildtag/buildtag2.go b/src/cmd/vet/testdata/buildtag/buildtag2.go
new file mode 100644
index 0000000..d8808dd
--- /dev/null
+++ b/src/cmd/vet/testdata/buildtag/buildtag2.go
@@ -0,0 +1,22 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains tests for the buildtag checker.
+
+// ERRORNEXT "possible malformed [+]build comment"
+// +builder
+// +build !ignore
+
+package testdata
+
+// ERRORNEXT "misplaced \+build comment"
+// +build toolate
+// ERRORNEXT "misplaced //go:build comment"
+//go:build toolate
+
+var _ = 3
+
+var _ = `
+// +build notacomment
+`
diff --git a/src/cmd/vet/testdata/buildtag/buildtag3.go b/src/cmd/vet/testdata/buildtag/buildtag3.go
new file mode 100644
index 0000000..241a7db
--- /dev/null
+++ b/src/cmd/vet/testdata/buildtag/buildtag3.go
@@ -0,0 +1,15 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains tests for the buildtag checker.
+
+//go:build good
+// ERRORNEXT "[+]build lines do not match //go:build condition"
+// +build bad
+
+package testdata
+
+var _ = `
+// +build notacomment
+`
diff --git a/src/cmd/vet/testdata/buildtag/buildtag4.go b/src/cmd/vet/testdata/buildtag/buildtag4.go
new file mode 100644
index 0000000..5b40d69
--- /dev/null
+++ b/src/cmd/vet/testdata/buildtag/buildtag4.go
@@ -0,0 +1,11 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains tests for the buildtag checker.
+
+//go:build !(bad || worse)
+// +build !bad
+// +build !worse
+
+package testdata
diff --git a/src/cmd/vet/testdata/buildtag/buildtag5.go b/src/cmd/vet/testdata/buildtag/buildtag5.go
new file mode 100644
index 0000000..12aeb82
--- /dev/null
+++ b/src/cmd/vet/testdata/buildtag/buildtag5.go
@@ -0,0 +1,11 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains tests for the buildtag checker.
+
+//go:build !(bad || worse)
+
+package testdata
+
+// +build other // ERROR "misplaced \+build comment"
diff --git a/src/cmd/vet/testdata/buildtag/buildtag6.s b/src/cmd/vet/testdata/buildtag/buildtag6.s
new file mode 100644
index 0000000..40fe14c
--- /dev/null
+++ b/src/cmd/vet/testdata/buildtag/buildtag6.s
@@ -0,0 +1,9 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "go_asm.h"
+
+// ok because we cannot parse assembly files.
+// +build no
+
diff --git a/src/cmd/vet/testdata/buildtag/buildtag7.s b/src/cmd/vet/testdata/buildtag/buildtag7.s
new file mode 100644
index 0000000..b622d48
--- /dev/null
+++ b/src/cmd/vet/testdata/buildtag/buildtag7.s
@@ -0,0 +1,11 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+#include "go_asm.h"
+
+// ok because we cannot parse assembly files
+// the assembler would complain if we did assemble this file.
+//go:build no
diff --git a/src/cmd/vet/testdata/copylock/copylock.go b/src/cmd/vet/testdata/copylock/copylock.go
index 8079cf3..7cfafe6 100644
--- a/src/cmd/vet/testdata/copylock/copylock.go
+++ b/src/cmd/vet/testdata/copylock/copylock.go
@@ -1,3 +1,7 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package copylock
 
 import "sync"
diff --git a/src/cmd/vet/testdata/httpresponse/httpresponse.go b/src/cmd/vet/testdata/httpresponse/httpresponse.go
index 6141f6e..98e394a 100644
--- a/src/cmd/vet/testdata/httpresponse/httpresponse.go
+++ b/src/cmd/vet/testdata/httpresponse/httpresponse.go
@@ -1,3 +1,7 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package httpresponse
 
 import (
diff --git a/src/cmd/vet/testdata/tagtest/file1.go b/src/cmd/vet/testdata/tagtest/file1.go
index 47fe3c8..2204524 100644
--- a/src/cmd/vet/testdata/tagtest/file1.go
+++ b/src/cmd/vet/testdata/tagtest/file1.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build testtag
 // +build testtag
 
 package main
diff --git a/src/cmd/vet/testdata/tagtest/file2.go b/src/cmd/vet/testdata/tagtest/file2.go
index 1f45efc..979b0d4 100644
--- a/src/cmd/vet/testdata/tagtest/file2.go
+++ b/src/cmd/vet/testdata/tagtest/file2.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !testtag
 // +build !testtag
 
 package main
diff --git a/src/cmd/vet/testdata/testingpkg/tests.go b/src/cmd/vet/testdata/testingpkg/tests.go
index 69d29d3..8f4674d 100644
--- a/src/cmd/vet/testdata/testingpkg/tests.go
+++ b/src/cmd/vet/testdata/testingpkg/tests.go
@@ -1 +1,5 @@
+// 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 testdata
diff --git a/src/cmd/vet/testdata/testingpkg/tests_test.go b/src/cmd/vet/testdata/testingpkg/tests_test.go
index 09bb98d..815dcc8 100644
--- a/src/cmd/vet/testdata/testingpkg/tests_test.go
+++ b/src/cmd/vet/testdata/testingpkg/tests_test.go
@@ -1,3 +1,7 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package testdata
 
 func Example_BadSuffix() {} // ERROR "Example_BadSuffix has malformed example suffix: BadSuffix"
diff --git a/src/cmd/vet/vet_test.go b/src/cmd/vet/vet_test.go
index d15d1ce..50dd073 100644
--- a/src/cmd/vet/vet_test.go
+++ b/src/cmd/vet/vet_test.go
@@ -334,8 +334,8 @@
 }
 
 var (
-	errRx       = regexp.MustCompile(`// (?:GC_)?ERROR (.*)`)
-	errAutoRx   = regexp.MustCompile(`// (?:GC_)?ERRORAUTO (.*)`)
+	errRx       = regexp.MustCompile(`// (?:GC_)?ERROR(NEXT)? (.*)`)
+	errAutoRx   = regexp.MustCompile(`// (?:GC_)?ERRORAUTO(NEXT)? (.*)`)
 	errQuotesRx = regexp.MustCompile(`"([^"]*)"`)
 	lineRx      = regexp.MustCompile(`LINE(([+-])([0-9]+))?`)
 )
@@ -364,7 +364,10 @@
 		if m == nil {
 			continue
 		}
-		all := m[1]
+		if m[1] == "NEXT" {
+			lineNum++
+		}
+		all := m[2]
 		mm := errQuotesRx.FindAllStringSubmatch(all, -1)
 		if mm == nil {
 			log.Fatalf("%s:%d: invalid errchk line: %s", file, lineNum, line)
diff --git a/src/compress/lzw/reader.go b/src/compress/lzw/reader.go
index f080211..952870a 100644
--- a/src/compress/lzw/reader.go
+++ b/src/compress/lzw/reader.go
@@ -42,15 +42,15 @@
 	flushBuffer        = 1 << maxWidth
 )
 
-// decoder is the state from which the readXxx method converts a byte
-// stream into a code stream.
-type decoder struct {
+// Reader is an io.Reader which can be used to read compressed data in the
+// LZW format.
+type Reader struct {
 	r        io.ByteReader
 	bits     uint32
 	nBits    uint
 	width    uint
-	read     func(*decoder) (uint16, error) // readLSB or readMSB
-	litWidth int                            // width in bits of literal codes
+	read     func(*Reader) (uint16, error) // readLSB or readMSB
+	litWidth int                           // width in bits of literal codes
 	err      error
 
 	// The first 1<<litWidth codes are literal codes.
@@ -87,148 +87,158 @@
 }
 
 // readLSB returns the next code for "Least Significant Bits first" data.
-func (d *decoder) readLSB() (uint16, error) {
-	for d.nBits < d.width {
-		x, err := d.r.ReadByte()
+func (r *Reader) readLSB() (uint16, error) {
+	for r.nBits < r.width {
+		x, err := r.r.ReadByte()
 		if err != nil {
 			return 0, err
 		}
-		d.bits |= uint32(x) << d.nBits
-		d.nBits += 8
+		r.bits |= uint32(x) << r.nBits
+		r.nBits += 8
 	}
-	code := uint16(d.bits & (1<<d.width - 1))
-	d.bits >>= d.width
-	d.nBits -= d.width
+	code := uint16(r.bits & (1<<r.width - 1))
+	r.bits >>= r.width
+	r.nBits -= r.width
 	return code, nil
 }
 
 // readMSB returns the next code for "Most Significant Bits first" data.
-func (d *decoder) readMSB() (uint16, error) {
-	for d.nBits < d.width {
-		x, err := d.r.ReadByte()
+func (r *Reader) readMSB() (uint16, error) {
+	for r.nBits < r.width {
+		x, err := r.r.ReadByte()
 		if err != nil {
 			return 0, err
 		}
-		d.bits |= uint32(x) << (24 - d.nBits)
-		d.nBits += 8
+		r.bits |= uint32(x) << (24 - r.nBits)
+		r.nBits += 8
 	}
-	code := uint16(d.bits >> (32 - d.width))
-	d.bits <<= d.width
-	d.nBits -= d.width
+	code := uint16(r.bits >> (32 - r.width))
+	r.bits <<= r.width
+	r.nBits -= r.width
 	return code, nil
 }
 
-func (d *decoder) Read(b []byte) (int, error) {
+// Read implements io.Reader, reading uncompressed bytes from its underlying Reader.
+func (r *Reader) Read(b []byte) (int, error) {
 	for {
-		if len(d.toRead) > 0 {
-			n := copy(b, d.toRead)
-			d.toRead = d.toRead[n:]
+		if len(r.toRead) > 0 {
+			n := copy(b, r.toRead)
+			r.toRead = r.toRead[n:]
 			return n, nil
 		}
-		if d.err != nil {
-			return 0, d.err
+		if r.err != nil {
+			return 0, r.err
 		}
-		d.decode()
+		r.decode()
 	}
 }
 
 // decode decompresses bytes from r and leaves them in d.toRead.
 // read specifies how to decode bytes into codes.
 // litWidth is the width in bits of literal codes.
-func (d *decoder) decode() {
+func (r *Reader) decode() {
 	// Loop over the code stream, converting codes into decompressed bytes.
 loop:
 	for {
-		code, err := d.read(d)
+		code, err := r.read(r)
 		if err != nil {
 			if err == io.EOF {
 				err = io.ErrUnexpectedEOF
 			}
-			d.err = err
+			r.err = err
 			break
 		}
 		switch {
-		case code < d.clear:
+		case code < r.clear:
 			// We have a literal code.
-			d.output[d.o] = uint8(code)
-			d.o++
-			if d.last != decoderInvalidCode {
+			r.output[r.o] = uint8(code)
+			r.o++
+			if r.last != decoderInvalidCode {
 				// Save what the hi code expands to.
-				d.suffix[d.hi] = uint8(code)
-				d.prefix[d.hi] = d.last
+				r.suffix[r.hi] = uint8(code)
+				r.prefix[r.hi] = r.last
 			}
-		case code == d.clear:
-			d.width = 1 + uint(d.litWidth)
-			d.hi = d.eof
-			d.overflow = 1 << d.width
-			d.last = decoderInvalidCode
+		case code == r.clear:
+			r.width = 1 + uint(r.litWidth)
+			r.hi = r.eof
+			r.overflow = 1 << r.width
+			r.last = decoderInvalidCode
 			continue
-		case code == d.eof:
-			d.err = io.EOF
+		case code == r.eof:
+			r.err = io.EOF
 			break loop
-		case code <= d.hi:
-			c, i := code, len(d.output)-1
-			if code == d.hi && d.last != decoderInvalidCode {
+		case code <= r.hi:
+			c, i := code, len(r.output)-1
+			if code == r.hi && r.last != decoderInvalidCode {
 				// code == hi is a special case which expands to the last expansion
 				// followed by the head of the last expansion. To find the head, we walk
 				// the prefix chain until we find a literal code.
-				c = d.last
-				for c >= d.clear {
-					c = d.prefix[c]
+				c = r.last
+				for c >= r.clear {
+					c = r.prefix[c]
 				}
-				d.output[i] = uint8(c)
+				r.output[i] = uint8(c)
 				i--
-				c = d.last
+				c = r.last
 			}
 			// Copy the suffix chain into output and then write that to w.
-			for c >= d.clear {
-				d.output[i] = d.suffix[c]
+			for c >= r.clear {
+				r.output[i] = r.suffix[c]
 				i--
-				c = d.prefix[c]
+				c = r.prefix[c]
 			}
-			d.output[i] = uint8(c)
-			d.o += copy(d.output[d.o:], d.output[i:])
-			if d.last != decoderInvalidCode {
+			r.output[i] = uint8(c)
+			r.o += copy(r.output[r.o:], r.output[i:])
+			if r.last != decoderInvalidCode {
 				// Save what the hi code expands to.
-				d.suffix[d.hi] = uint8(c)
-				d.prefix[d.hi] = d.last
+				r.suffix[r.hi] = uint8(c)
+				r.prefix[r.hi] = r.last
 			}
 		default:
-			d.err = errors.New("lzw: invalid code")
+			r.err = errors.New("lzw: invalid code")
 			break loop
 		}
-		d.last, d.hi = code, d.hi+1
-		if d.hi >= d.overflow {
-			if d.hi > d.overflow {
+		r.last, r.hi = code, r.hi+1
+		if r.hi >= r.overflow {
+			if r.hi > r.overflow {
 				panic("unreachable")
 			}
-			if d.width == maxWidth {
-				d.last = decoderInvalidCode
+			if r.width == maxWidth {
+				r.last = decoderInvalidCode
 				// Undo the d.hi++ a few lines above, so that (1) we maintain
 				// the invariant that d.hi < d.overflow, and (2) d.hi does not
 				// eventually overflow a uint16.
-				d.hi--
+				r.hi--
 			} else {
-				d.width++
-				d.overflow = 1 << d.width
+				r.width++
+				r.overflow = 1 << r.width
 			}
 		}
-		if d.o >= flushBuffer {
+		if r.o >= flushBuffer {
 			break
 		}
 	}
 	// Flush pending output.
-	d.toRead = d.output[:d.o]
-	d.o = 0
+	r.toRead = r.output[:r.o]
+	r.o = 0
 }
 
 var errClosed = errors.New("lzw: reader/writer is closed")
 
-func (d *decoder) Close() error {
-	d.err = errClosed // in case any Reads come along
+// Close closes the Reader and returns an error for any future read operation.
+// It does not close the underlying io.Reader.
+func (r *Reader) Close() error {
+	r.err = errClosed // in case any Reads come along
 	return nil
 }
 
+// Reset clears the Reader's state and allows it to be reused again
+// as a new Reader.
+func (r *Reader) Reset(src io.Reader, order Order, litWidth int) {
+	*r = Reader{}
+	r.init(src, order, litWidth)
+}
+
 // NewReader creates a new io.ReadCloser.
 // Reads from the returned io.ReadCloser read and decompress data from r.
 // If r does not also implement io.ByteReader,
@@ -238,32 +248,43 @@
 // The number of bits to use for literal codes, litWidth, must be in the
 // range [2,8] and is typically 8. It must equal the litWidth
 // used during compression.
+//
+// It is guaranteed that the underlying type of the returned io.ReadCloser
+// is a *Reader.
 func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser {
-	d := new(decoder)
+	return newReader(r, order, litWidth)
+}
+
+func newReader(src io.Reader, order Order, litWidth int) *Reader {
+	r := new(Reader)
+	r.init(src, order, litWidth)
+	return r
+}
+
+func (r *Reader) init(src io.Reader, order Order, litWidth int) {
 	switch order {
 	case LSB:
-		d.read = (*decoder).readLSB
+		r.read = (*Reader).readLSB
 	case MSB:
-		d.read = (*decoder).readMSB
+		r.read = (*Reader).readMSB
 	default:
-		d.err = errors.New("lzw: unknown order")
-		return d
+		r.err = errors.New("lzw: unknown order")
+		return
 	}
 	if litWidth < 2 || 8 < litWidth {
-		d.err = fmt.Errorf("lzw: litWidth %d out of range", litWidth)
-		return d
+		r.err = fmt.Errorf("lzw: litWidth %d out of range", litWidth)
+		return
 	}
-	if br, ok := r.(io.ByteReader); ok {
-		d.r = br
-	} else {
-		d.r = bufio.NewReader(r)
-	}
-	d.litWidth = litWidth
-	d.width = 1 + uint(litWidth)
-	d.clear = uint16(1) << uint(litWidth)
-	d.eof, d.hi = d.clear+1, d.clear+1
-	d.overflow = uint16(1) << d.width
-	d.last = decoderInvalidCode
 
-	return d
+	br, ok := src.(io.ByteReader)
+	if !ok && src != nil {
+		br = bufio.NewReader(src)
+	}
+	r.r = br
+	r.litWidth = litWidth
+	r.width = 1 + uint(litWidth)
+	r.clear = uint16(1) << uint(litWidth)
+	r.eof, r.hi = r.clear+1, r.clear+1
+	r.overflow = uint16(1) << r.width
+	r.last = decoderInvalidCode
 }
diff --git a/src/compress/lzw/reader_test.go b/src/compress/lzw/reader_test.go
index d1eb76d..9a2a477 100644
--- a/src/compress/lzw/reader_test.go
+++ b/src/compress/lzw/reader_test.go
@@ -120,6 +120,53 @@
 	}
 }
 
+func TestReaderReset(t *testing.T) {
+	var b bytes.Buffer
+	for _, tt := range lzwTests {
+		d := strings.Split(tt.desc, ";")
+		var order Order
+		switch d[1] {
+		case "LSB":
+			order = LSB
+		case "MSB":
+			order = MSB
+		default:
+			t.Errorf("%s: bad order %q", tt.desc, d[1])
+		}
+		litWidth, _ := strconv.Atoi(d[2])
+		rc := NewReader(strings.NewReader(tt.compressed), order, litWidth)
+		defer rc.Close()
+		b.Reset()
+		n, err := io.Copy(&b, rc)
+		b1 := b.Bytes()
+		if err != nil {
+			if err != tt.err {
+				t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)
+			}
+			if err == io.ErrUnexpectedEOF {
+				// Even if the input is truncated, we should still return the
+				// partial decoded result.
+				if n == 0 || !strings.HasPrefix(tt.raw, b.String()) {
+					t.Errorf("got %d bytes (%q), want a non-empty prefix of %q", n, b.String(), tt.raw)
+				}
+			}
+			continue
+		}
+
+		b.Reset()
+		rc.(*Reader).Reset(strings.NewReader(tt.compressed), order, litWidth)
+		n, err = io.Copy(&b, rc)
+		b2 := b.Bytes()
+		if err != nil {
+			t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, nil)
+			continue
+		}
+		if !bytes.Equal(b1, b2) {
+			t.Errorf("bytes read were not the same")
+		}
+	}
+}
+
 type devZero struct{}
 
 func (devZero) Read(p []byte) (int, error) {
@@ -131,7 +178,7 @@
 
 func TestHiCodeDoesNotOverflow(t *testing.T) {
 	r := NewReader(devZero{}, LSB, 8)
-	d := r.(*decoder)
+	d := r.(*Reader)
 	buf := make([]byte, 1024)
 	oldHi := uint16(0)
 	for i := 0; i < 100; i++ {
@@ -226,28 +273,43 @@
 		b.Fatalf("test file has no data")
 	}
 
+	getInputBuf := func(buf []byte, n int) []byte {
+		compressed := new(bytes.Buffer)
+		w := NewWriter(compressed, LSB, 8)
+		for i := 0; i < n; i += len(buf) {
+			if len(buf) > n-i {
+				buf = buf[:n-i]
+			}
+			w.Write(buf)
+		}
+		w.Close()
+		return compressed.Bytes()
+	}
+
 	for e := 4; e <= 6; e++ {
 		n := int(math.Pow10(e))
 		b.Run(fmt.Sprint("1e", e), func(b *testing.B) {
 			b.StopTimer()
 			b.SetBytes(int64(n))
-			buf0 := buf
-			compressed := new(bytes.Buffer)
-			w := NewWriter(compressed, LSB, 8)
-			for i := 0; i < n; i += len(buf0) {
-				if len(buf0) > n-i {
-					buf0 = buf0[:n-i]
-				}
-				w.Write(buf0)
-			}
-			w.Close()
-			buf1 := compressed.Bytes()
-			buf0, compressed, w = nil, nil, nil
+			buf1 := getInputBuf(buf, n)
 			runtime.GC()
 			b.StartTimer()
 			for i := 0; i < b.N; i++ {
 				io.Copy(io.Discard, NewReader(bytes.NewReader(buf1), LSB, 8))
 			}
 		})
+		b.Run(fmt.Sprint("1e-Reuse", e), func(b *testing.B) {
+			b.StopTimer()
+			b.SetBytes(int64(n))
+			buf1 := getInputBuf(buf, n)
+			runtime.GC()
+			b.StartTimer()
+			r := NewReader(bytes.NewReader(buf1), LSB, 8)
+			for i := 0; i < b.N; i++ {
+				io.Copy(io.Discard, r)
+				r.Close()
+				r.(*Reader).Reset(bytes.NewReader(buf1), LSB, 8)
+			}
+		})
 	}
 }
diff --git a/src/compress/lzw/writer.go b/src/compress/lzw/writer.go
index 6ddb335..552bdc2 100644
--- a/src/compress/lzw/writer.go
+++ b/src/compress/lzw/writer.go
@@ -17,19 +17,6 @@
 	Flush() error
 }
 
-// An errWriteCloser is an io.WriteCloser that always returns a given error.
-type errWriteCloser struct {
-	err error
-}
-
-func (e *errWriteCloser) Write([]byte) (int, error) {
-	return 0, e.err
-}
-
-func (e *errWriteCloser) Close() error {
-	return e.err
-}
-
 const (
 	// A code is a 12 bit value, stored as a uint32 when encoding to avoid
 	// type conversions when shifting bits.
@@ -44,14 +31,15 @@
 	invalidEntry = 0
 )
 
-// encoder is LZW compressor.
-type encoder struct {
+// Writer is an LZW compressor. It writes the compressed form of the data
+// to an underlying writer (see NewWriter).
+type Writer struct {
 	// w is the writer that compressed bytes are written to.
 	w writer
 	// order, write, bits, nBits and width are the state for
 	// converting a code stream into a byte stream.
 	order Order
-	write func(*encoder, uint32) error
+	write func(*Writer, uint32) error
 	bits  uint32
 	nBits uint
 	width uint
@@ -63,7 +51,7 @@
 	// savedCode is the accumulated code at the end of the most recent Write
 	// call. It is equal to invalidCode if there was no such call.
 	savedCode uint32
-	// err is the first error encountered during writing. Closing the encoder
+	// err is the first error encountered during writing. Closing the writer
 	// will make any future Write calls return errClosed
 	err error
 	// table is the hash table from 20-bit keys to 12-bit values. Each table
@@ -74,80 +62,80 @@
 }
 
 // writeLSB writes the code c for "Least Significant Bits first" data.
-func (e *encoder) writeLSB(c uint32) error {
-	e.bits |= c << e.nBits
-	e.nBits += e.width
-	for e.nBits >= 8 {
-		if err := e.w.WriteByte(uint8(e.bits)); err != nil {
+func (w *Writer) writeLSB(c uint32) error {
+	w.bits |= c << w.nBits
+	w.nBits += w.width
+	for w.nBits >= 8 {
+		if err := w.w.WriteByte(uint8(w.bits)); err != nil {
 			return err
 		}
-		e.bits >>= 8
-		e.nBits -= 8
+		w.bits >>= 8
+		w.nBits -= 8
 	}
 	return nil
 }
 
 // writeMSB writes the code c for "Most Significant Bits first" data.
-func (e *encoder) writeMSB(c uint32) error {
-	e.bits |= c << (32 - e.width - e.nBits)
-	e.nBits += e.width
-	for e.nBits >= 8 {
-		if err := e.w.WriteByte(uint8(e.bits >> 24)); err != nil {
+func (w *Writer) writeMSB(c uint32) error {
+	w.bits |= c << (32 - w.width - w.nBits)
+	w.nBits += w.width
+	for w.nBits >= 8 {
+		if err := w.w.WriteByte(uint8(w.bits >> 24)); err != nil {
 			return err
 		}
-		e.bits <<= 8
-		e.nBits -= 8
+		w.bits <<= 8
+		w.nBits -= 8
 	}
 	return nil
 }
 
-// errOutOfCodes is an internal error that means that the encoder has run out
+// errOutOfCodes is an internal error that means that the writer has run out
 // of unused codes and a clear code needs to be sent next.
 var errOutOfCodes = errors.New("lzw: out of codes")
 
 // incHi increments e.hi and checks for both overflow and running out of
 // unused codes. In the latter case, incHi sends a clear code, resets the
-// encoder state and returns errOutOfCodes.
-func (e *encoder) incHi() error {
-	e.hi++
-	if e.hi == e.overflow {
-		e.width++
-		e.overflow <<= 1
+// writer state and returns errOutOfCodes.
+func (w *Writer) incHi() error {
+	w.hi++
+	if w.hi == w.overflow {
+		w.width++
+		w.overflow <<= 1
 	}
-	if e.hi == maxCode {
-		clear := uint32(1) << e.litWidth
-		if err := e.write(e, clear); err != nil {
+	if w.hi == maxCode {
+		clear := uint32(1) << w.litWidth
+		if err := w.write(w, clear); err != nil {
 			return err
 		}
-		e.width = e.litWidth + 1
-		e.hi = clear + 1
-		e.overflow = clear << 1
-		for i := range e.table {
-			e.table[i] = invalidEntry
+		w.width = w.litWidth + 1
+		w.hi = clear + 1
+		w.overflow = clear << 1
+		for i := range w.table {
+			w.table[i] = invalidEntry
 		}
 		return errOutOfCodes
 	}
 	return nil
 }
 
-// Write writes a compressed representation of p to e's underlying writer.
-func (e *encoder) Write(p []byte) (n int, err error) {
-	if e.err != nil {
-		return 0, e.err
+// Write writes a compressed representation of p to w's underlying writer.
+func (w *Writer) Write(p []byte) (n int, err error) {
+	if w.err != nil {
+		return 0, w.err
 	}
 	if len(p) == 0 {
 		return 0, nil
 	}
-	if maxLit := uint8(1<<e.litWidth - 1); maxLit != 0xff {
+	if maxLit := uint8(1<<w.litWidth - 1); maxLit != 0xff {
 		for _, x := range p {
 			if x > maxLit {
-				e.err = errors.New("lzw: input byte too large for the litWidth")
-				return 0, e.err
+				w.err = errors.New("lzw: input byte too large for the litWidth")
+				return 0, w.err
 			}
 		}
 	}
 	n = len(p)
-	code := e.savedCode
+	code := w.savedCode
 	if code == invalidCode {
 		// The first code sent is always a literal code.
 		code, p = uint32(p[0]), p[1:]
@@ -159,77 +147,84 @@
 		// If there is a hash table hit for this key then we continue the loop
 		// and do not emit a code yet.
 		hash := (key>>12 ^ key) & tableMask
-		for h, t := hash, e.table[hash]; t != invalidEntry; {
+		for h, t := hash, w.table[hash]; t != invalidEntry; {
 			if key == t>>12 {
 				code = t & maxCode
 				continue loop
 			}
 			h = (h + 1) & tableMask
-			t = e.table[h]
+			t = w.table[h]
 		}
 		// Otherwise, write the current code, and literal becomes the start of
 		// the next emitted code.
-		if e.err = e.write(e, code); e.err != nil {
-			return 0, e.err
+		if w.err = w.write(w, code); w.err != nil {
+			return 0, w.err
 		}
 		code = literal
 		// Increment e.hi, the next implied code. If we run out of codes, reset
-		// the encoder state (including clearing the hash table) and continue.
-		if err1 := e.incHi(); err1 != nil {
+		// the writer state (including clearing the hash table) and continue.
+		if err1 := w.incHi(); err1 != nil {
 			if err1 == errOutOfCodes {
 				continue
 			}
-			e.err = err1
-			return 0, e.err
+			w.err = err1
+			return 0, w.err
 		}
 		// Otherwise, insert key -> e.hi into the map that e.table represents.
 		for {
-			if e.table[hash] == invalidEntry {
-				e.table[hash] = (key << 12) | e.hi
+			if w.table[hash] == invalidEntry {
+				w.table[hash] = (key << 12) | w.hi
 				break
 			}
 			hash = (hash + 1) & tableMask
 		}
 	}
-	e.savedCode = code
+	w.savedCode = code
 	return n, nil
 }
 
-// Close closes the encoder, flushing any pending output. It does not close or
-// flush e's underlying writer.
-func (e *encoder) Close() error {
-	if e.err != nil {
-		if e.err == errClosed {
+// Close closes the Writer, flushing any pending output. It does not close
+// w's underlying writer.
+func (w *Writer) Close() error {
+	if w.err != nil {
+		if w.err == errClosed {
 			return nil
 		}
-		return e.err
+		return w.err
 	}
 	// Make any future calls to Write return errClosed.
-	e.err = errClosed
+	w.err = errClosed
 	// Write the savedCode if valid.
-	if e.savedCode != invalidCode {
-		if err := e.write(e, e.savedCode); err != nil {
+	if w.savedCode != invalidCode {
+		if err := w.write(w, w.savedCode); err != nil {
 			return err
 		}
-		if err := e.incHi(); err != nil && err != errOutOfCodes {
+		if err := w.incHi(); err != nil && err != errOutOfCodes {
 			return err
 		}
 	}
 	// Write the eof code.
-	eof := uint32(1)<<e.litWidth + 1
-	if err := e.write(e, eof); err != nil {
+	eof := uint32(1)<<w.litWidth + 1
+	if err := w.write(w, eof); err != nil {
 		return err
 	}
 	// Write the final bits.
-	if e.nBits > 0 {
-		if e.order == MSB {
-			e.bits >>= 24
+	if w.nBits > 0 {
+		if w.order == MSB {
+			w.bits >>= 24
 		}
-		if err := e.w.WriteByte(uint8(e.bits)); err != nil {
+		if err := w.w.WriteByte(uint8(w.bits)); err != nil {
 			return err
 		}
 	}
-	return e.w.Flush()
+	return w.w.Flush()
+}
+
+// Reset clears the Writer's state and allows it to be reused again
+// as a new Writer.
+func (w *Writer) Reset(dst io.Writer, order Order, litWidth int) {
+	*w = Writer{}
+	w.init(dst, order, litWidth)
 }
 
 // NewWriter creates a new io.WriteCloser.
@@ -238,32 +233,43 @@
 // finished writing.
 // The number of bits to use for literal codes, litWidth, must be in the
 // range [2,8] and is typically 8. Input bytes must be less than 1<<litWidth.
+//
+// It is guaranteed that the underlying type of the returned io.WriteCloser
+// is a *Writer.
 func NewWriter(w io.Writer, order Order, litWidth int) io.WriteCloser {
-	var write func(*encoder, uint32) error
+	return newWriter(w, order, litWidth)
+}
+
+func newWriter(dst io.Writer, order Order, litWidth int) *Writer {
+	w := new(Writer)
+	w.init(dst, order, litWidth)
+	return w
+}
+
+func (w *Writer) init(dst io.Writer, order Order, litWidth int) {
 	switch order {
 	case LSB:
-		write = (*encoder).writeLSB
+		w.write = (*Writer).writeLSB
 	case MSB:
-		write = (*encoder).writeMSB
+		w.write = (*Writer).writeMSB
 	default:
-		return &errWriteCloser{errors.New("lzw: unknown order")}
+		w.err = errors.New("lzw: unknown order")
+		return
 	}
 	if litWidth < 2 || 8 < litWidth {
-		return &errWriteCloser{fmt.Errorf("lzw: litWidth %d out of range", litWidth)}
+		w.err = fmt.Errorf("lzw: litWidth %d out of range", litWidth)
+		return
 	}
-	bw, ok := w.(writer)
-	if !ok {
-		bw = bufio.NewWriter(w)
+	bw, ok := dst.(writer)
+	if !ok && dst != nil {
+		bw = bufio.NewWriter(dst)
 	}
+	w.w = bw
 	lw := uint(litWidth)
-	return &encoder{
-		w:         bw,
-		order:     order,
-		write:     write,
-		width:     1 + lw,
-		litWidth:  lw,
-		hi:        1<<lw + 1,
-		overflow:  1 << (lw + 1),
-		savedCode: invalidCode,
-	}
+	w.order = order
+	w.width = 1 + lw
+	w.litWidth = lw
+	w.hi = 1<<lw + 1
+	w.overflow = 1 << (lw + 1)
+	w.savedCode = invalidCode
 }
diff --git a/src/compress/lzw/writer_test.go b/src/compress/lzw/writer_test.go
index 1a5dbca..9f59c8b 100644
--- a/src/compress/lzw/writer_test.go
+++ b/src/compress/lzw/writer_test.go
@@ -5,6 +5,7 @@
 package lzw
 
 import (
+	"bytes"
 	"fmt"
 	"internal/testenv"
 	"io"
@@ -105,6 +106,50 @@
 	}
 }
 
+func TestWriterReset(t *testing.T) {
+	for _, order := range [...]Order{LSB, MSB} {
+		t.Run(fmt.Sprintf("Order %d", order), func(t *testing.T) {
+			for litWidth := 6; litWidth <= 8; litWidth++ {
+				t.Run(fmt.Sprintf("LitWidth %d", litWidth), func(t *testing.T) {
+					var data []byte
+					if litWidth == 6 {
+						data = []byte{1, 2, 3}
+					} else {
+						data = []byte(`lorem ipsum dolor sit amet`)
+					}
+					var buf bytes.Buffer
+					w := NewWriter(&buf, order, litWidth)
+					if _, err := w.Write(data); err != nil {
+						t.Errorf("write: %v: %v", string(data), err)
+					}
+
+					if err := w.Close(); err != nil {
+						t.Errorf("close: %v", err)
+					}
+
+					b1 := buf.Bytes()
+					buf.Reset()
+
+					w.(*Writer).Reset(&buf, order, litWidth)
+
+					if _, err := w.Write(data); err != nil {
+						t.Errorf("write: %v: %v", string(data), err)
+					}
+
+					if err := w.Close(); err != nil {
+						t.Errorf("close: %v", err)
+					}
+					b2 := buf.Bytes()
+
+					if !bytes.Equal(b1, b2) {
+						t.Errorf("bytes written were not same")
+					}
+				})
+			}
+		})
+	}
+}
+
 func TestWriterReturnValues(t *testing.T) {
 	w := NewWriter(io.Discard, LSB, 8)
 	n, err := w.Write([]byte("asdf"))
@@ -152,5 +197,14 @@
 				w.Close()
 			}
 		})
+		b.Run(fmt.Sprint("1e-Reuse", e), func(b *testing.B) {
+			b.SetBytes(int64(n))
+			w := NewWriter(io.Discard, LSB, 8)
+			for i := 0; i < b.N; i++ {
+				w.Write(buf1)
+				w.Close()
+				w.(*Writer).Reset(io.Discard, LSB, 8)
+			}
+		})
 	}
 }
diff --git a/src/context/benchmark_test.go b/src/context/benchmark_test.go
index 5d56863..69d75ff 100644
--- a/src/context/benchmark_test.go
+++ b/src/context/benchmark_test.go
@@ -138,3 +138,17 @@
 		}
 	})
 }
+
+func BenchmarkContextCancelDone(b *testing.B) {
+	ctx, cancel := WithCancel(Background())
+	defer cancel()
+
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			select {
+			case <-ctx.Done():
+			default:
+			}
+		}
+	})
+}
diff --git a/src/context/context.go b/src/context/context.go
index b3fdb82..733c5f5 100644
--- a/src/context/context.go
+++ b/src/context/context.go
@@ -303,10 +303,8 @@
 	if !ok {
 		return nil, false
 	}
-	p.mu.Lock()
-	ok = p.done == done
-	p.mu.Unlock()
-	if !ok {
+	pdone, _ := p.done.Load().(chan struct{})
+	if pdone != done {
 		return nil, false
 	}
 	return p, true
@@ -345,7 +343,7 @@
 	Context
 
 	mu       sync.Mutex            // protects following fields
-	done     chan struct{}         // created lazily, closed by first cancel call
+	done     atomic.Value          // of chan struct{}, created lazily, closed by first cancel call
 	children map[canceler]struct{} // set to nil by the first cancel call
 	err      error                 // set to non-nil by the first cancel call
 }
@@ -358,13 +356,18 @@
 }
 
 func (c *cancelCtx) Done() <-chan struct{} {
-	c.mu.Lock()
-	if c.done == nil {
-		c.done = make(chan struct{})
+	d := c.done.Load()
+	if d != nil {
+		return d.(chan struct{})
 	}
-	d := c.done
-	c.mu.Unlock()
-	return d
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	d = c.done.Load()
+	if d == nil {
+		d = make(chan struct{})
+		c.done.Store(d)
+	}
+	return d.(chan struct{})
 }
 
 func (c *cancelCtx) Err() error {
@@ -401,10 +404,11 @@
 		return // already canceled
 	}
 	c.err = err
-	if c.done == nil {
-		c.done = closedchan
+	d, _ := c.done.Load().(chan struct{})
+	if d == nil {
+		c.done.Store(closedchan)
 	} else {
-		close(c.done)
+		close(d)
 	}
 	for child := range c.children {
 		// NOTE: acquiring the child's lock while holding parent's lock.
diff --git a/src/context/context_test.go b/src/context/context_test.go
index 6b392a2..a2e2324 100644
--- a/src/context/context_test.go
+++ b/src/context/context_test.go
@@ -525,7 +525,7 @@
 	parent, cancelParent := WithCancel(Background())
 	child, cancelChild := WithCancel(parent)
 	go func() {
-		parent.Done()
+		<-parent.Done()
 		cancelChild()
 	}()
 	cancelParent()
@@ -661,7 +661,7 @@
 		t.Errorf("child not done immediately upon construction")
 	}
 	if got, want := c.Err(), Canceled; got != want {
-		t.Errorf("child not cancelled; got = %v, want = %v", got, want)
+		t.Errorf("child not canceled; got = %v, want = %v", got, want)
 	}
 }
 
@@ -779,7 +779,7 @@
 	defer cancel6()
 	checkNoGoroutine()
 
-	// Check applied to cancelled context.
+	// Check applied to canceled context.
 	cancel6()
 	cancel1()
 	_, cancel7 := WithCancel(ctx5)
diff --git a/src/crypto/aes/aes_gcm.go b/src/crypto/aes/aes_gcm.go
index 49b78c3..1de0e45 100644
--- a/src/crypto/aes/aes_gcm.go
+++ b/src/crypto/aes/aes_gcm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 || arm64
 // +build amd64 arm64
 
 package aes
diff --git a/src/crypto/aes/cipher_asm.go b/src/crypto/aes/cipher_asm.go
index 646bdfa..4251805 100644
--- a/src/crypto/aes/cipher_asm.go
+++ b/src/crypto/aes/cipher_asm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 || arm64
 // +build amd64 arm64
 
 package aes
diff --git a/src/crypto/aes/cipher_generic.go b/src/crypto/aes/cipher_generic.go
index 80a68b4..22ce3be 100644
--- a/src/crypto/aes/cipher_generic.go
+++ b/src/crypto/aes/cipher_generic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !amd64 && !s390x && !ppc64le && !arm64
 // +build !amd64,!s390x,!ppc64le,!arm64
 
 package aes
diff --git a/src/crypto/aes/gcm_ppc64le.go b/src/crypto/aes/gcm_ppc64le.go
index 084eddd..01b4e08 100644
--- a/src/crypto/aes/gcm_ppc64le.go
+++ b/src/crypto/aes/gcm_ppc64le.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64le
 // +build ppc64le
 
 package aes
diff --git a/src/crypto/cipher/benchmark_test.go b/src/crypto/cipher/benchmark_test.go
index 90d0cd7..eb02cd0 100644
--- a/src/crypto/cipher/benchmark_test.go
+++ b/src/crypto/cipher/benchmark_test.go
@@ -7,28 +7,15 @@
 import (
 	"crypto/aes"
 	"crypto/cipher"
+	"strconv"
 	"testing"
 )
 
-func benchmarkAESGCMSign(b *testing.B, buf []byte) {
+func benchmarkAESGCMSeal(b *testing.B, buf []byte, keySize int) {
+	b.ReportAllocs()
 	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)))
-
-	var key [16]byte
+	var key = make([]byte, keySize)
 	var nonce [12]byte
 	var ad [13]byte
 	aes, _ := aes.NewCipher(key[:])
@@ -41,44 +28,41 @@
 	}
 }
 
-func benchmarkAESGCMOpen(b *testing.B, buf []byte) {
+func benchmarkAESGCMOpen(b *testing.B, buf []byte, keySize int) {
+	b.ReportAllocs()
 	b.SetBytes(int64(len(buf)))
 
-	var key [16]byte
+	var key = make([]byte, keySize)
 	var nonce [12]byte
 	var ad [13]byte
 	aes, _ := aes.NewCipher(key[:])
 	aesgcm, _ := cipher.NewGCM(aes)
 	var out []byte
-	out = aesgcm.Seal(out[:0], nonce[:], buf, ad[:])
+
+	ct := aesgcm.Seal(nil, nonce[:], buf[:], ad[:])
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		_, err := aesgcm.Open(buf[:0], nonce[:], out, ad[:])
-		if err != nil {
-			b.Errorf("Open: %v", err)
-		}
+		out, _ = aesgcm.Open(out[:0], nonce[:], ct, ad[:])
 	}
 }
 
-func BenchmarkAESGCMSeal1K(b *testing.B) {
-	benchmarkAESGCMSeal(b, make([]byte, 1024))
-}
+func BenchmarkAESGCM(b *testing.B) {
+	for _, length := range []int{64, 1350, 8 * 1024} {
+		b.Run("Open-128-"+strconv.Itoa(length), func(b *testing.B) {
+			benchmarkAESGCMOpen(b, make([]byte, length), 128/8)
+		})
+		b.Run("Seal-128-"+strconv.Itoa(length), func(b *testing.B) {
+			benchmarkAESGCMSeal(b, make([]byte, length), 128/8)
+		})
 
-func BenchmarkAESGCMOpen1K(b *testing.B) {
-	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))
-}
-
-func BenchmarkAESGCMOpen8K(b *testing.B) {
-	benchmarkAESGCMOpen(b, make([]byte, 8*1024))
+		b.Run("Open-256-"+strconv.Itoa(length), func(b *testing.B) {
+			benchmarkAESGCMOpen(b, make([]byte, length), 256/8)
+		})
+		b.Run("Seal-256-"+strconv.Itoa(length), func(b *testing.B) {
+			benchmarkAESGCMSeal(b, make([]byte, length), 256/8)
+		})
+	}
 }
 
 func benchmarkAESStream(b *testing.B, mode func(cipher.Block, []byte) cipher.Stream, buf []byte) {
diff --git a/src/crypto/cipher/xor_generic.go b/src/crypto/cipher/xor_generic.go
index ca9c4bb..0320840 100644
--- a/src/crypto/cipher/xor_generic.go
+++ b/src/crypto/cipher/xor_generic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !amd64 && !ppc64 && !ppc64le && !arm64
 // +build !amd64,!ppc64,!ppc64le,!arm64
 
 package cipher
diff --git a/src/crypto/cipher/xor_ppc64x.go b/src/crypto/cipher/xor_ppc64x.go
index 8d2e43d..f520208 100644
--- a/src/crypto/cipher/xor_ppc64x.go
+++ b/src/crypto/cipher/xor_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 package cipher
diff --git a/src/crypto/cipher/xor_ppc64x.s b/src/crypto/cipher/xor_ppc64x.s
index 4cef31d..2ba6d96 100644
--- a/src/crypto/cipher/xor_ppc64x.s
+++ b/src/crypto/cipher/xor_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "textflag.h"
diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go
index ccce873..2194369 100644
--- a/src/crypto/ecdsa/ecdsa.go
+++ b/src/crypto/ecdsa/ecdsa.go
@@ -17,7 +17,7 @@
 //   [Coron]
 //     https://cs.nyu.edu/~dodis/ps/merkle.pdf
 //   [Larsson]
-//     https://www.nada.kth.se/kurser/kth/2D1441/semteo03/lecturenotes/assump.pdf
+//     https://web.archive.org/web/20040719170906/https://www.nada.kth.se/kurser/kth/2D1441/semteo03/lecturenotes/assump.pdf
 package ecdsa
 
 // Further references:
diff --git a/src/crypto/ecdsa/ecdsa_noasm.go b/src/crypto/ecdsa/ecdsa_noasm.go
index 7219621..68670a4 100644
--- a/src/crypto/ecdsa/ecdsa_noasm.go
+++ b/src/crypto/ecdsa/ecdsa_noasm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !s390x
 // +build !s390x
 
 package ecdsa
diff --git a/src/crypto/ecdsa/ecdsa_s390x.go b/src/crypto/ecdsa/ecdsa_s390x.go
index 0a1d73e..1480d1b 100644
--- a/src/crypto/ecdsa/ecdsa_s390x.go
+++ b/src/crypto/ecdsa/ecdsa_s390x.go
@@ -21,12 +21,18 @@
 //go:noescape
 func kdsa(fc uint64, params *[4096]byte) (errn uint64)
 
+// testingDisableKDSA forces the generic fallback path. It must only be set in tests.
+var testingDisableKDSA bool
+
 // canUseKDSA checks if KDSA instruction is available, and if it is, it checks
 // the name of the curve to see if it matches the curves supported(P-256, P-384, P-521).
 // Then, based on the curve name, a function code and a block size will be assigned.
 // If KDSA instruction is not available or if the curve is not supported, canUseKDSA
 // will set ok to false.
 func canUseKDSA(c elliptic.Curve) (functionCode uint64, blockSize int, ok bool) {
+	if testingDisableKDSA {
+		return 0, 0, false
+	}
 	if !cpu.S390X.HasECDSA {
 		return 0, 0, false
 	}
diff --git a/src/crypto/ecdsa/ecdsa_s390x_test.go b/src/crypto/ecdsa/ecdsa_s390x_test.go
index a434575..f5633fb 100644
--- a/src/crypto/ecdsa/ecdsa_s390x_test.go
+++ b/src/crypto/ecdsa/ecdsa_s390x_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build s390x
 // +build s390x
 
 package ecdsa
@@ -12,6 +13,9 @@
 )
 
 func TestNoAsm(t *testing.T) {
+	testingDisableKDSA = true
+	defer func() { testingDisableKDSA = false }()
+
 	curves := [...]elliptic.Curve{
 		elliptic.P256(),
 		elliptic.P384(),
@@ -19,15 +23,11 @@
 	}
 
 	for _, curve := range curves {
-		// override the name of the curve to stop the assembly path being taken
-		params := *curve.Params()
-		name := params.Name
-		params.Name = name + "_GENERIC_OVERRIDE"
-
-		testKeyGeneration(t, &params, name)
-		testSignAndVerify(t, &params, name)
-		testNonceSafety(t, &params, name)
-		testINDCCA(t, &params, name)
-		testNegativeInputs(t, &params, name)
+		name := curve.Params().Name
+		t.Run(name, func(t *testing.T) { testKeyGeneration(t, curve) })
+		t.Run(name, func(t *testing.T) { testSignAndVerify(t, curve) })
+		t.Run(name, func(t *testing.T) { testNonceSafety(t, curve) })
+		t.Run(name, func(t *testing.T) { testINDCCA(t, curve) })
+		t.Run(name, func(t *testing.T) { testNegativeInputs(t, curve) })
 	}
 }
diff --git a/src/crypto/ecdsa/ecdsa_test.go b/src/crypto/ecdsa/ecdsa_test.go
index 0c1ff6d..556818a 100644
--- a/src/crypto/ecdsa/ecdsa_test.go
+++ b/src/crypto/ecdsa/ecdsa_test.go
@@ -21,218 +21,150 @@
 	"testing"
 )
 
-func testKeyGeneration(t *testing.T, c elliptic.Curve, tag string) {
-	priv, err := GenerateKey(c, rand.Reader)
-	if err != nil {
-		t.Errorf("%s: error: %s", tag, err)
-		return
+func testAllCurves(t *testing.T, f func(*testing.T, elliptic.Curve)) {
+	tests := []struct {
+		name  string
+		curve elliptic.Curve
+	}{
+		{"P256", elliptic.P256()},
+		{"P224", elliptic.P224()},
+		{"P384", elliptic.P384()},
+		{"P521", elliptic.P521()},
 	}
-	if !c.IsOnCurve(priv.PublicKey.X, priv.PublicKey.Y) {
-		t.Errorf("%s: public key invalid: %s", tag, err)
+	if testing.Short() {
+		tests = tests[:1]
+	}
+	for _, test := range tests {
+		curve := test.curve
+		t.Run(test.name, func(t *testing.T) {
+			t.Parallel()
+			f(t, curve)
+		})
 	}
 }
 
 func TestKeyGeneration(t *testing.T) {
-	testKeyGeneration(t, elliptic.P224(), "p224")
-	if testing.Short() {
-		return
+	testAllCurves(t, testKeyGeneration)
+}
+
+func testKeyGeneration(t *testing.T, c elliptic.Curve) {
+	priv, err := GenerateKey(c, rand.Reader)
+	if err != nil {
+		t.Fatal(err)
 	}
-	testKeyGeneration(t, elliptic.P256(), "p256")
-	testKeyGeneration(t, elliptic.P384(), "p384")
-	testKeyGeneration(t, elliptic.P521(), "p521")
+	if !c.IsOnCurve(priv.PublicKey.X, priv.PublicKey.Y) {
+		t.Errorf("public key invalid: %s", err)
+	}
 }
 
-func BenchmarkSignP256(b *testing.B) {
-	b.ResetTimer()
-	p256 := elliptic.P256()
-	hashed := []byte("testing")
-	priv, _ := GenerateKey(p256, rand.Reader)
-
-	b.ReportAllocs()
-	b.ResetTimer()
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			_, _, _ = Sign(rand.Reader, priv, hashed)
-		}
-	})
+func TestSignAndVerify(t *testing.T) {
+	testAllCurves(t, testSignAndVerify)
 }
 
-func BenchmarkSignP384(b *testing.B) {
-	b.ResetTimer()
-	p384 := elliptic.P384()
-	hashed := []byte("testing")
-	priv, _ := GenerateKey(p384, rand.Reader)
-
-	b.ReportAllocs()
-	b.ResetTimer()
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			_, _, _ = Sign(rand.Reader, priv, hashed)
-		}
-	})
-}
-
-func BenchmarkVerifyP256(b *testing.B) {
-	b.ResetTimer()
-	p256 := elliptic.P256()
-	hashed := []byte("testing")
-	priv, _ := GenerateKey(p256, rand.Reader)
-	r, s, _ := Sign(rand.Reader, priv, hashed)
-
-	b.ReportAllocs()
-	b.ResetTimer()
-	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()
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			GenerateKey(p256, rand.Reader)
-		}
-	})
-}
-
-func testSignAndVerify(t *testing.T, c elliptic.Curve, tag string) {
+func testSignAndVerify(t *testing.T, c elliptic.Curve) {
 	priv, _ := GenerateKey(c, rand.Reader)
 
 	hashed := []byte("testing")
 	r, s, err := Sign(rand.Reader, priv, hashed)
 	if err != nil {
-		t.Errorf("%s: error signing: %s", tag, err)
+		t.Errorf("error signing: %s", err)
 		return
 	}
 
 	if !Verify(&priv.PublicKey, hashed, r, s) {
-		t.Errorf("%s: Verify failed", tag)
+		t.Errorf("Verify failed")
 	}
 
 	hashed[0] ^= 0xff
 	if Verify(&priv.PublicKey, hashed, r, s) {
-		t.Errorf("%s: Verify always works!", tag)
+		t.Errorf("Verify always works!")
 	}
 }
 
-func TestSignAndVerify(t *testing.T) {
-	testSignAndVerify(t, elliptic.P224(), "p224")
-	if testing.Short() {
-		return
-	}
-	testSignAndVerify(t, elliptic.P256(), "p256")
-	testSignAndVerify(t, elliptic.P384(), "p384")
-	testSignAndVerify(t, elliptic.P521(), "p521")
+func TestSignAndVerifyASN1(t *testing.T) {
+	testAllCurves(t, testSignAndVerifyASN1)
 }
 
-func testSignAndVerifyASN1(t *testing.T, c elliptic.Curve, tag string) {
+func testSignAndVerifyASN1(t *testing.T, c elliptic.Curve) {
 	priv, _ := GenerateKey(c, rand.Reader)
 
 	hashed := []byte("testing")
 	sig, err := SignASN1(rand.Reader, priv, hashed)
 	if err != nil {
-		t.Errorf("%s: error signing: %s", tag, err)
+		t.Errorf("error signing: %s", err)
 		return
 	}
 
 	if !VerifyASN1(&priv.PublicKey, hashed, sig) {
-		t.Errorf("%s: VerifyASN1 failed", tag)
+		t.Errorf("VerifyASN1 failed")
 	}
 
 	hashed[0] ^= 0xff
 	if VerifyASN1(&priv.PublicKey, hashed, sig) {
-		t.Errorf("%s: VerifyASN1 always works!", tag)
+		t.Errorf("VerifyASN1 always works!")
 	}
 }
 
-func TestSignAndVerifyASN1(t *testing.T) {
-	testSignAndVerifyASN1(t, elliptic.P224(), "p224")
-	if testing.Short() {
-		return
-	}
-	testSignAndVerifyASN1(t, elliptic.P256(), "p256")
-	testSignAndVerifyASN1(t, elliptic.P384(), "p384")
-	testSignAndVerifyASN1(t, elliptic.P521(), "p521")
+func TestNonceSafety(t *testing.T) {
+	testAllCurves(t, testNonceSafety)
 }
 
-func testNonceSafety(t *testing.T, c elliptic.Curve, tag string) {
+func testNonceSafety(t *testing.T, c elliptic.Curve) {
 	priv, _ := GenerateKey(c, rand.Reader)
 
 	hashed := []byte("testing")
 	r0, s0, err := Sign(zeroReader, priv, hashed)
 	if err != nil {
-		t.Errorf("%s: error signing: %s", tag, err)
+		t.Errorf("error signing: %s", err)
 		return
 	}
 
 	hashed = []byte("testing...")
 	r1, s1, err := Sign(zeroReader, priv, hashed)
 	if err != nil {
-		t.Errorf("%s: error signing: %s", tag, err)
+		t.Errorf("error signing: %s", err)
 		return
 	}
 
 	if s0.Cmp(s1) == 0 {
 		// This should never happen.
-		t.Errorf("%s: the signatures on two different messages were the same", tag)
+		t.Errorf("the signatures on two different messages were the same")
 	}
 
 	if r0.Cmp(r1) == 0 {
-		t.Errorf("%s: the nonce used for two different messages was the same", tag)
+		t.Errorf("the nonce used for two different messages was the same")
 	}
 }
 
-func TestNonceSafety(t *testing.T) {
-	testNonceSafety(t, elliptic.P224(), "p224")
-	if testing.Short() {
-		return
-	}
-	testNonceSafety(t, elliptic.P256(), "p256")
-	testNonceSafety(t, elliptic.P384(), "p384")
-	testNonceSafety(t, elliptic.P521(), "p521")
+func TestINDCCA(t *testing.T) {
+	testAllCurves(t, testINDCCA)
 }
 
-func testINDCCA(t *testing.T, c elliptic.Curve, tag string) {
+func testINDCCA(t *testing.T, c elliptic.Curve) {
 	priv, _ := GenerateKey(c, rand.Reader)
 
 	hashed := []byte("testing")
 	r0, s0, err := Sign(rand.Reader, priv, hashed)
 	if err != nil {
-		t.Errorf("%s: error signing: %s", tag, err)
+		t.Errorf("error signing: %s", err)
 		return
 	}
 
 	r1, s1, err := Sign(rand.Reader, priv, hashed)
 	if err != nil {
-		t.Errorf("%s: error signing: %s", tag, err)
+		t.Errorf("error signing: %s", err)
 		return
 	}
 
 	if s0.Cmp(s1) == 0 {
-		t.Errorf("%s: two signatures of the same message produced the same result", tag)
+		t.Errorf("two signatures of the same message produced the same result")
 	}
 
 	if r0.Cmp(r1) == 0 {
-		t.Errorf("%s: two signatures of the same message produced the same nonce", tag)
+		t.Errorf("two signatures of the same message produced the same nonce")
 	}
 }
 
-func TestINDCCA(t *testing.T) {
-	testINDCCA(t, elliptic.P224(), "p224")
-	if testing.Short() {
-		return
-	}
-	testINDCCA(t, elliptic.P256(), "p256")
-	testINDCCA(t, elliptic.P384(), "p384")
-	testINDCCA(t, elliptic.P521(), "p521")
-}
-
 func fromHex(s string) *big.Int {
 	r, ok := new(big.Int).SetString(s, 16)
 	if !ok {
@@ -351,10 +283,14 @@
 	}
 }
 
-func testNegativeInputs(t *testing.T, curve elliptic.Curve, tag string) {
+func TestNegativeInputs(t *testing.T) {
+	testAllCurves(t, testNegativeInputs)
+}
+
+func testNegativeInputs(t *testing.T, curve elliptic.Curve) {
 	key, err := GenerateKey(curve, rand.Reader)
 	if err != nil {
-		t.Errorf("failed to generate key for %q", tag)
+		t.Errorf("failed to generate key")
 	}
 
 	var hash [32]byte
@@ -363,35 +299,103 @@
 	r.Neg(r)
 
 	if Verify(&key.PublicKey, hash[:], r, r) {
-		t.Errorf("bogus signature accepted for %q", tag)
+		t.Errorf("bogus signature accepted")
 	}
 }
 
-func TestNegativeInputs(t *testing.T) {
-	testNegativeInputs(t, elliptic.P224(), "p224")
-	testNegativeInputs(t, elliptic.P256(), "p256")
-	testNegativeInputs(t, elliptic.P384(), "p384")
-	testNegativeInputs(t, elliptic.P521(), "p521")
-}
-
 func TestZeroHashSignature(t *testing.T) {
+	testAllCurves(t, testZeroHashSignature)
+}
+
+func testZeroHashSignature(t *testing.T, curve elliptic.Curve) {
 	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)
-		}
+	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)
+	}
+}
+
+func benchmarkAllCurves(t *testing.B, f func(*testing.B, elliptic.Curve)) {
+	tests := []struct {
+		name  string
+		curve elliptic.Curve
+	}{
+		{"P256", elliptic.P256()},
+		{"P224", elliptic.P224()},
+		{"P384", elliptic.P384()},
+		{"P521", elliptic.P521()},
+	}
+	for _, test := range tests {
+		curve := test.curve
+		t.Run(test.name, func(t *testing.B) {
+			f(t, curve)
+		})
+	}
+}
+
+func BenchmarkSign(b *testing.B) {
+	benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
+		priv, err := GenerateKey(curve, rand.Reader)
+		if err != nil {
+			b.Fatal(err)
+		}
+		hashed := []byte("testing")
+
+		b.ReportAllocs()
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			sig, err := SignASN1(rand.Reader, priv, hashed)
+			if err != nil {
+				b.Fatal(err)
+			}
+			// Prevent the compiler from optimizing out the operation.
+			hashed[0] = sig[0]
+		}
+	})
+}
+
+func BenchmarkVerify(b *testing.B) {
+	benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
+		priv, err := GenerateKey(curve, rand.Reader)
+		if err != nil {
+			b.Fatal(err)
+		}
+		hashed := []byte("testing")
+		r, s, err := Sign(rand.Reader, priv, hashed)
+		if err != nil {
+			b.Fatal(err)
+		}
+
+		b.ReportAllocs()
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			if !Verify(&priv.PublicKey, hashed, r, s) {
+				b.Fatal("verify failed")
+			}
+		}
+	})
+}
+
+func BenchmarkGenerateKey(b *testing.B) {
+	benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
+		b.ReportAllocs()
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			if _, err := GenerateKey(curve, rand.Reader); err != nil {
+				b.Fatal(err)
+			}
+		}
+	})
 }
diff --git a/src/crypto/ed25519/ed25519.go b/src/crypto/ed25519/ed25519.go
index 6f59bb5..09c5269 100644
--- a/src/crypto/ed25519/ed25519.go
+++ b/src/crypto/ed25519/ed25519.go
@@ -12,9 +12,6 @@
 // 8032 private key as the “seed”.
 package ed25519
 
-// This code is a port of the public domain, “ref10” implementation of ed25519
-// from SUPERCOP.
-
 import (
 	"bytes"
 	"crypto"
@@ -128,20 +125,14 @@
 		panic("ed25519: bad seed length: " + strconv.Itoa(l))
 	}
 
-	digest := sha512.Sum512(seed)
-	digest[0] &= 248
-	digest[31] &= 127
-	digest[31] |= 64
+	h := sha512.Sum512(seed)
+	s := edwards25519.NewScalar().SetBytesWithClamping(h[:32])
+	A := (&edwards25519.Point{}).ScalarBaseMult(s)
 
-	var A edwards25519.ExtendedGroupElement
-	var hBytes [32]byte
-	copy(hBytes[:], digest[:])
-	edwards25519.GeScalarMultBase(&A, &hBytes)
-	var publicKeyBytes [32]byte
-	A.ToBytes(&publicKeyBytes)
+	publicKey := A.Bytes()
 
 	copy(privateKey, seed)
-	copy(privateKey[32:], publicKeyBytes[:])
+	copy(privateKey[32:], publicKey)
 }
 
 // Sign signs the message with privateKey and returns a signature. It will
@@ -158,44 +149,33 @@
 	if l := len(privateKey); l != PrivateKeySize {
 		panic("ed25519: bad private key length: " + strconv.Itoa(l))
 	}
+	seed, publicKey := privateKey[:SeedSize], privateKey[SeedSize:]
 
-	h := sha512.New()
-	h.Write(privateKey[:32])
+	h := sha512.Sum512(seed)
+	s := edwards25519.NewScalar().SetBytesWithClamping(h[:32])
+	prefix := h[32:]
 
-	var digest1, messageDigest, hramDigest [64]byte
-	var expandedSecretKey [32]byte
-	h.Sum(digest1[:0])
-	copy(expandedSecretKey[:], digest1[:])
-	expandedSecretKey[0] &= 248
-	expandedSecretKey[31] &= 63
-	expandedSecretKey[31] |= 64
+	mh := sha512.New()
+	mh.Write(prefix)
+	mh.Write(message)
+	messageDigest := make([]byte, 0, sha512.Size)
+	messageDigest = mh.Sum(messageDigest)
+	r := edwards25519.NewScalar().SetUniformBytes(messageDigest)
 
-	h.Reset()
-	h.Write(digest1[32:])
-	h.Write(message)
-	h.Sum(messageDigest[:0])
+	R := (&edwards25519.Point{}).ScalarBaseMult(r)
 
-	var messageDigestReduced [32]byte
-	edwards25519.ScReduce(&messageDigestReduced, &messageDigest)
-	var R edwards25519.ExtendedGroupElement
-	edwards25519.GeScalarMultBase(&R, &messageDigestReduced)
+	kh := sha512.New()
+	kh.Write(R.Bytes())
+	kh.Write(publicKey)
+	kh.Write(message)
+	hramDigest := make([]byte, 0, sha512.Size)
+	hramDigest = kh.Sum(hramDigest)
+	k := edwards25519.NewScalar().SetUniformBytes(hramDigest)
 
-	var encodedR [32]byte
-	R.ToBytes(&encodedR)
+	S := edwards25519.NewScalar().MultiplyAdd(k, s, r)
 
-	h.Reset()
-	h.Write(encodedR[:])
-	h.Write(privateKey[32:])
-	h.Write(message)
-	h.Sum(hramDigest[:0])
-	var hramDigestReduced [32]byte
-	edwards25519.ScReduce(&hramDigestReduced, &hramDigest)
-
-	var s [32]byte
-	edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced)
-
-	copy(signature[:], encodedR[:])
-	copy(signature[32:], s[:])
+	copy(signature[:32], R.Bytes())
+	copy(signature[32:], S.Bytes())
 }
 
 // Verify reports whether sig is a valid signature of message by publicKey. It
@@ -209,38 +189,27 @@
 		return false
 	}
 
-	var A edwards25519.ExtendedGroupElement
-	var publicKeyBytes [32]byte
-	copy(publicKeyBytes[:], publicKey)
-	if !A.FromBytes(&publicKeyBytes) {
-		return false
-	}
-	edwards25519.FeNeg(&A.X, &A.X)
-	edwards25519.FeNeg(&A.T, &A.T)
-
-	h := sha512.New()
-	h.Write(sig[:32])
-	h.Write(publicKey[:])
-	h.Write(message)
-	var digest [64]byte
-	h.Sum(digest[:0])
-
-	var hReduced [32]byte
-	edwards25519.ScReduce(&hReduced, &digest)
-
-	var R edwards25519.ProjectiveGroupElement
-	var s [32]byte
-	copy(s[:], sig[32:])
-
-	// https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in
-	// the range [0, order) in order to prevent signature malleability.
-	if !edwards25519.ScMinimal(&s) {
+	A, err := (&edwards25519.Point{}).SetBytes(publicKey)
+	if err != nil {
 		return false
 	}
 
-	edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &s)
+	kh := sha512.New()
+	kh.Write(sig[:32])
+	kh.Write(publicKey)
+	kh.Write(message)
+	hramDigest := make([]byte, 0, sha512.Size)
+	hramDigest = kh.Sum(hramDigest)
+	k := edwards25519.NewScalar().SetUniformBytes(hramDigest)
 
-	var checkR [32]byte
-	R.ToBytes(&checkR)
-	return bytes.Equal(sig[:32], checkR[:])
+	S, err := edwards25519.NewScalar().SetCanonicalBytes(sig[32:])
+	if err != nil {
+		return false
+	}
+
+	// [S]B = R + [k]A --> [k](-A) + [S]B = R
+	minusA := (&edwards25519.Point{}).Negate(A)
+	R := (&edwards25519.Point{}).VarTimeDoubleScalarBaseMult(k, minusA, S)
+
+	return bytes.Equal(sig[:32], R.Bytes())
 }
diff --git a/src/crypto/ed25519/ed25519_test.go b/src/crypto/ed25519/ed25519_test.go
index adb09e4..8a973b3 100644
--- a/src/crypto/ed25519/ed25519_test.go
+++ b/src/crypto/ed25519/ed25519_test.go
@@ -9,7 +9,6 @@
 	"bytes"
 	"compress/gzip"
 	"crypto"
-	"crypto/ed25519/internal/edwards25519"
 	"crypto/rand"
 	"encoding/hex"
 	"os"
@@ -26,24 +25,6 @@
 	return len(buf), nil
 }
 
-func TestUnmarshalMarshal(t *testing.T) {
-	pub, _, _ := GenerateKey(rand.Reader)
-
-	var A edwards25519.ExtendedGroupElement
-	var pubBytes [32]byte
-	copy(pubBytes[:], pub)
-	if !A.FromBytes(&pubBytes) {
-		t.Fatalf("ExtendedGroupElement.FromBytes failed")
-	}
-
-	var pub2 [32]byte
-	A.ToBytes(&pub2)
-
-	if pubBytes != pub2 {
-		t.Errorf("FromBytes(%v)->ToBytes does not round-trip, got %x\n", pubBytes, pub2)
-	}
-}
-
 func TestSignVerify(t *testing.T) {
 	var zero zeroReader
 	public, private, _ := GenerateKey(zero)
@@ -204,6 +185,24 @@
 	}
 }
 
+func TestAllocations(t *testing.T) {
+	if strings.HasSuffix(os.Getenv("GO_BUILDER_NAME"), "-noopt") {
+		t.Skip("skipping allocations test without relevant optimizations")
+	}
+	if allocs := testing.AllocsPerRun(100, func() {
+		seed := make([]byte, SeedSize)
+		message := []byte("Hello, world!")
+		priv := NewKeyFromSeed(seed)
+		pub := priv.Public().(PublicKey)
+		signature := Sign(priv, message)
+		if !Verify(pub, message, signature) {
+			t.Fatal("signature didn't verify")
+		}
+	}); allocs > 0 {
+		t.Errorf("expected zero allocations, got %0.1v", allocs)
+	}
+}
+
 func BenchmarkKeyGeneration(b *testing.B) {
 	var zero zeroReader
 	for i := 0; i < b.N; i++ {
@@ -215,7 +214,6 @@
 
 func BenchmarkNewKeyFromSeed(b *testing.B) {
 	seed := make([]byte, SeedSize)
-	b.ReportAllocs()
 	for i := 0; i < b.N; i++ {
 		_ = NewKeyFromSeed(seed)
 	}
@@ -228,7 +226,6 @@
 		b.Fatal(err)
 	}
 	message := []byte("Hello, world!")
-	b.ReportAllocs()
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Sign(priv, message)
diff --git a/src/crypto/ed25519/ed25519vectors_test.go b/src/crypto/ed25519/ed25519vectors_test.go
new file mode 100644
index 0000000..74fcdcd
--- /dev/null
+++ b/src/crypto/ed25519/ed25519vectors_test.go
@@ -0,0 +1,109 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ed25519_test
+
+import (
+	"crypto/ed25519"
+	"encoding/hex"
+	"encoding/json"
+	"internal/testenv"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"testing"
+)
+
+// TestEd25519Vectors runs a very large set of test vectors that exercise all
+// combinations of low-order points, low-order components, and non-canonical
+// encodings. These vectors lock in unspecified and spec-divergent behaviors in
+// edge cases that are not security relevant in most contexts, but that can
+// cause issues in consensus applications if changed.
+//
+// Our behavior matches the "classic" unwritten verification rules of the
+// "ref10" reference implementation.
+//
+// Note that although we test for these edge cases, they are not covered by the
+// Go 1 Compatibility Promise. Applications that need stable verification rules
+// should use github.com/hdevalence/ed25519consensus.
+//
+// See https://hdevalence.ca/blog/2020-10-04-its-25519am for more details.
+func TestEd25519Vectors(t *testing.T) {
+	jsonVectors := downloadEd25519Vectors(t)
+	var vectors []struct {
+		A, R, S, M string
+		Flags      []string
+	}
+	if err := json.Unmarshal(jsonVectors, &vectors); err != nil {
+		t.Fatal(err)
+	}
+	for i, v := range vectors {
+		expectedToVerify := true
+		for _, f := range v.Flags {
+			switch f {
+			// We use the simplified verification formula that doesn't multiply
+			// by the cofactor, so any low order residue will cause the
+			// signature not to verify.
+			//
+			// This is allowed, but not required, by RFC 8032.
+			case "LowOrderResidue":
+				expectedToVerify = false
+			// Our point decoding allows non-canonical encodings (in violation
+			// of RFC 8032) but R is not decoded: instead, R is recomputed and
+			// compared bytewise against the canonical encoding.
+			case "NonCanonicalR":
+				expectedToVerify = false
+			}
+		}
+
+		publicKey := decodeHex(t, v.A)
+		signature := append(decodeHex(t, v.R), decodeHex(t, v.S)...)
+		message := []byte(v.M)
+
+		didVerify := ed25519.Verify(publicKey, message, signature)
+		if didVerify && !expectedToVerify {
+			t.Errorf("#%d: vector with flags %s unexpectedly verified", i, v.Flags)
+		}
+		if !didVerify && expectedToVerify {
+			t.Errorf("#%d: vector with flags %s unexpectedly rejected", i, v.Flags)
+		}
+	}
+}
+
+func downloadEd25519Vectors(t *testing.T) []byte {
+	testenv.MustHaveExternalNetwork(t)
+
+	// Download the JSON test file from the GOPROXY with `go mod download`,
+	// pinning the version so test and module caching works as expected.
+	goTool := testenv.GoToolPath(t)
+	path := "filippo.io/mostly-harmless/ed25519vectors@v0.0.0-20210322192420-30a2d7243a94"
+	cmd := exec.Command(goTool, "mod", "download", "-json", path)
+	// TODO: enable the sumdb once the TryBots proxy supports it.
+	cmd.Env = append(os.Environ(), "GONOSUMDB=*")
+	output, err := cmd.Output()
+	if err != nil {
+		t.Fatalf("failed to run `go mod download -json %s`, output: %s", path, output)
+	}
+	var dm struct {
+		Dir string // absolute path to cached source root directory
+	}
+	if err := json.Unmarshal(output, &dm); err != nil {
+		t.Fatal(err)
+	}
+
+	jsonVectors, err := os.ReadFile(filepath.Join(dm.Dir, "ed25519vectors.json"))
+	if err != nil {
+		t.Fatalf("failed to read ed25519vectors.json: %v", err)
+	}
+	return jsonVectors
+}
+
+func decodeHex(t *testing.T, s string) []byte {
+	t.Helper()
+	b, err := hex.DecodeString(s)
+	if err != nil {
+		t.Errorf("invalid hex: %v", err)
+	}
+	return b
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/const.go b/src/crypto/ed25519/internal/edwards25519/const.go
deleted file mode 100644
index e39f086..0000000
--- a/src/crypto/ed25519/internal/edwards25519/const.go
+++ /dev/null
@@ -1,1422 +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.
-
-package edwards25519
-
-// These values are from the public domain, “ref10” implementation of ed25519
-// from SUPERCOP.
-
-// d is a constant in the Edwards curve equation.
-var d = FieldElement{
-	-10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116,
-}
-
-// d2 is 2*d.
-var d2 = FieldElement{
-	-21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199,
-}
-
-// SqrtM1 is the square-root of -1 in the field.
-var SqrtM1 = FieldElement{
-	-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482,
-}
-
-// A is a constant in the Montgomery-form of curve25519.
-var A = FieldElement{
-	486662, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-}
-
-// bi contains precomputed multiples of the base-point. See the Ed25519 paper
-// for a discussion about how these values are used.
-var bi = [8]PreComputedGroupElement{
-	{
-		FieldElement{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605},
-		FieldElement{-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378},
-		FieldElement{-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546},
-	},
-	{
-		FieldElement{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024},
-		FieldElement{16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574},
-		FieldElement{30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357},
-	},
-	{
-		FieldElement{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380},
-		FieldElement{4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306},
-		FieldElement{19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942},
-	},
-	{
-		FieldElement{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766},
-		FieldElement{-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701},
-		FieldElement{28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300},
-	},
-	{
-		FieldElement{-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877},
-		FieldElement{-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951},
-		FieldElement{4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784},
-	},
-	{
-		FieldElement{-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436},
-		FieldElement{25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918},
-		FieldElement{23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877},
-	},
-	{
-		FieldElement{-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800},
-		FieldElement{-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305},
-		FieldElement{-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300},
-	},
-	{
-		FieldElement{-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876},
-		FieldElement{-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619},
-		FieldElement{-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683},
-	},
-}
-
-// base contains precomputed multiples of the base-point. See the Ed25519 paper
-// for a discussion about how these values are used.
-var base = [32][8]PreComputedGroupElement{
-	{
-		{
-			FieldElement{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605},
-			FieldElement{-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378},
-			FieldElement{-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546},
-		},
-		{
-			FieldElement{-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303},
-			FieldElement{-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081},
-			FieldElement{26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697},
-		},
-		{
-			FieldElement{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024},
-			FieldElement{16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574},
-			FieldElement{30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357},
-		},
-		{
-			FieldElement{-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540},
-			FieldElement{23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397},
-			FieldElement{7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325},
-		},
-		{
-			FieldElement{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380},
-			FieldElement{4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306},
-			FieldElement{19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942},
-		},
-		{
-			FieldElement{-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777},
-			FieldElement{-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737},
-			FieldElement{-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652},
-		},
-		{
-			FieldElement{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766},
-			FieldElement{-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701},
-			FieldElement{28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300},
-		},
-		{
-			FieldElement{14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726},
-			FieldElement{-7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955},
-			FieldElement{27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425},
-		},
-	},
-	{
-		{
-			FieldElement{-13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171},
-			FieldElement{27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510},
-			FieldElement{17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660},
-		},
-		{
-			FieldElement{-10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639},
-			FieldElement{29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963},
-			FieldElement{5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950},
-		},
-		{
-			FieldElement{-27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568},
-			FieldElement{12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335},
-			FieldElement{25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628},
-		},
-		{
-			FieldElement{-26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007},
-			FieldElement{-2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772},
-			FieldElement{-22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653},
-		},
-		{
-			FieldElement{2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567},
-			FieldElement{13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686},
-			FieldElement{21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372},
-		},
-		{
-			FieldElement{-13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887},
-			FieldElement{-23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954},
-			FieldElement{-29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953},
-		},
-		{
-			FieldElement{24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833},
-			FieldElement{-16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532},
-			FieldElement{-22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876},
-		},
-		{
-			FieldElement{2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268},
-			FieldElement{33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214},
-			FieldElement{1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038},
-		},
-	},
-	{
-		{
-			FieldElement{6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800},
-			FieldElement{4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645},
-			FieldElement{-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664},
-		},
-		{
-			FieldElement{1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933},
-			FieldElement{-25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182},
-			FieldElement{-17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222},
-		},
-		{
-			FieldElement{-18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991},
-			FieldElement{20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880},
-			FieldElement{9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092},
-		},
-		{
-			FieldElement{-16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295},
-			FieldElement{19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788},
-			FieldElement{8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553},
-		},
-		{
-			FieldElement{-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026},
-			FieldElement{11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347},
-			FieldElement{-18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033},
-		},
-		{
-			FieldElement{-23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395},
-			FieldElement{-27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278},
-			FieldElement{1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890},
-		},
-		{
-			FieldElement{32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995},
-			FieldElement{-30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596},
-			FieldElement{-11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891},
-		},
-		{
-			FieldElement{31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060},
-			FieldElement{11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608},
-			FieldElement{-20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606},
-		},
-	},
-	{
-		{
-			FieldElement{7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389},
-			FieldElement{-19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016},
-			FieldElement{-11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341},
-		},
-		{
-			FieldElement{-22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505},
-			FieldElement{14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553},
-			FieldElement{-28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655},
-		},
-		{
-			FieldElement{15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220},
-			FieldElement{12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631},
-			FieldElement{-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099},
-		},
-		{
-			FieldElement{26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556},
-			FieldElement{14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749},
-			FieldElement{236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930},
-		},
-		{
-			FieldElement{1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391},
-			FieldElement{5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253},
-			FieldElement{20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066},
-		},
-		{
-			FieldElement{24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958},
-			FieldElement{-11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082},
-			FieldElement{-28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383},
-		},
-		{
-			FieldElement{-30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521},
-			FieldElement{-11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807},
-			FieldElement{23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948},
-		},
-		{
-			FieldElement{9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134},
-			FieldElement{-32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455},
-			FieldElement{27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629},
-		},
-	},
-	{
-		{
-			FieldElement{-8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069},
-			FieldElement{-32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746},
-			FieldElement{24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919},
-		},
-		{
-			FieldElement{11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837},
-			FieldElement{8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906},
-			FieldElement{-28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771},
-		},
-		{
-			FieldElement{-25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817},
-			FieldElement{10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098},
-			FieldElement{10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409},
-		},
-		{
-			FieldElement{-12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504},
-			FieldElement{-26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727},
-			FieldElement{28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420},
-		},
-		{
-			FieldElement{-32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003},
-			FieldElement{-1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605},
-			FieldElement{-30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384},
-		},
-		{
-			FieldElement{-26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701},
-			FieldElement{-23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683},
-			FieldElement{29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708},
-		},
-		{
-			FieldElement{-3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563},
-			FieldElement{-19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260},
-			FieldElement{-5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387},
-		},
-		{
-			FieldElement{-19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672},
-			FieldElement{23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686},
-			FieldElement{-24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665},
-		},
-	},
-	{
-		{
-			FieldElement{11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182},
-			FieldElement{-31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277},
-			FieldElement{14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628},
-		},
-		{
-			FieldElement{-4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474},
-			FieldElement{-26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539},
-			FieldElement{-25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822},
-		},
-		{
-			FieldElement{-10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970},
-			FieldElement{19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756},
-			FieldElement{-24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508},
-		},
-		{
-			FieldElement{-26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683},
-			FieldElement{-10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655},
-			FieldElement{-20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158},
-		},
-		{
-			FieldElement{-4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125},
-			FieldElement{-15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839},
-			FieldElement{-20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664},
-		},
-		{
-			FieldElement{27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294},
-			FieldElement{-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899},
-			FieldElement{-11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070},
-		},
-		{
-			FieldElement{3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294},
-			FieldElement{-15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949},
-			FieldElement{-21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083},
-		},
-		{
-			FieldElement{31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420},
-			FieldElement{-5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940},
-			FieldElement{29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396},
-		},
-	},
-	{
-		{
-			FieldElement{-12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567},
-			FieldElement{20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127},
-			FieldElement{-16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294},
-		},
-		{
-			FieldElement{-12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887},
-			FieldElement{22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964},
-			FieldElement{16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195},
-		},
-		{
-			FieldElement{9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244},
-			FieldElement{24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999},
-			FieldElement{-1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762},
-		},
-		{
-			FieldElement{-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274},
-			FieldElement{-33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236},
-			FieldElement{-16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605},
-		},
-		{
-			FieldElement{-13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761},
-			FieldElement{-22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884},
-			FieldElement{-6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482},
-		},
-		{
-			FieldElement{-24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638},
-			FieldElement{-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490},
-			FieldElement{-32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170},
-		},
-		{
-			FieldElement{5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736},
-			FieldElement{10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124},
-			FieldElement{-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392},
-		},
-		{
-			FieldElement{8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029},
-			FieldElement{6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048},
-			FieldElement{28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958},
-		},
-	},
-	{
-		{
-			FieldElement{24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593},
-			FieldElement{26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071},
-			FieldElement{-11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692},
-		},
-		{
-			FieldElement{11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687},
-			FieldElement{-160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441},
-			FieldElement{-20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001},
-		},
-		{
-			FieldElement{-938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460},
-			FieldElement{-19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007},
-			FieldElement{-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762},
-		},
-		{
-			FieldElement{15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005},
-			FieldElement{-9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674},
-			FieldElement{4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035},
-		},
-		{
-			FieldElement{7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590},
-			FieldElement{-2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957},
-			FieldElement{-30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812},
-		},
-		{
-			FieldElement{33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740},
-			FieldElement{-18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122},
-			FieldElement{-27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158},
-		},
-		{
-			FieldElement{8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885},
-			FieldElement{26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140},
-			FieldElement{19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857},
-		},
-		{
-			FieldElement{801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155},
-			FieldElement{19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260},
-			FieldElement{19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483},
-		},
-	},
-	{
-		{
-			FieldElement{-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677},
-			FieldElement{32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815},
-			FieldElement{22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751},
-		},
-		{
-			FieldElement{-16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203},
-			FieldElement{-11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208},
-			FieldElement{1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230},
-		},
-		{
-			FieldElement{16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850},
-			FieldElement{-21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389},
-			FieldElement{-9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968},
-		},
-		{
-			FieldElement{-11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689},
-			FieldElement{14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880},
-			FieldElement{5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304},
-		},
-		{
-			FieldElement{30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632},
-			FieldElement{-3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412},
-			FieldElement{20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566},
-		},
-		{
-			FieldElement{-20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038},
-			FieldElement{-26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232},
-			FieldElement{-1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943},
-		},
-		{
-			FieldElement{17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856},
-			FieldElement{23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738},
-			FieldElement{15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971},
-		},
-		{
-			FieldElement{-27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718},
-			FieldElement{-13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697},
-			FieldElement{-11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883},
-		},
-	},
-	{
-		{
-			FieldElement{5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912},
-			FieldElement{-26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358},
-			FieldElement{3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849},
-		},
-		{
-			FieldElement{29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307},
-			FieldElement{-14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977},
-			FieldElement{-6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335},
-		},
-		{
-			FieldElement{-29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644},
-			FieldElement{-22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616},
-			FieldElement{-27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735},
-		},
-		{
-			FieldElement{-21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099},
-			FieldElement{29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341},
-			FieldElement{-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336},
-		},
-		{
-			FieldElement{-23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646},
-			FieldElement{31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425},
-			FieldElement{-17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388},
-		},
-		{
-			FieldElement{-31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743},
-			FieldElement{-16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822},
-			FieldElement{-8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462},
-		},
-		{
-			FieldElement{18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985},
-			FieldElement{9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702},
-			FieldElement{-22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797},
-		},
-		{
-			FieldElement{21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293},
-			FieldElement{27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100},
-			FieldElement{19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688},
-		},
-	},
-	{
-		{
-			FieldElement{12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186},
-			FieldElement{2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610},
-			FieldElement{-2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707},
-		},
-		{
-			FieldElement{7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220},
-			FieldElement{915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025},
-			FieldElement{32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044},
-		},
-		{
-			FieldElement{32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992},
-			FieldElement{-4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027},
-			FieldElement{21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197},
-		},
-		{
-			FieldElement{8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901},
-			FieldElement{31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952},
-			FieldElement{19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878},
-		},
-		{
-			FieldElement{-28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390},
-			FieldElement{32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730},
-			FieldElement{2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730},
-		},
-		{
-			FieldElement{-19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180},
-			FieldElement{-30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272},
-			FieldElement{-15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715},
-		},
-		{
-			FieldElement{-22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970},
-			FieldElement{-31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772},
-			FieldElement{-17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865},
-		},
-		{
-			FieldElement{15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750},
-			FieldElement{20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373},
-			FieldElement{32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348},
-		},
-	},
-	{
-		{
-			FieldElement{9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144},
-			FieldElement{-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195},
-			FieldElement{5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086},
-		},
-		{
-			FieldElement{-13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684},
-			FieldElement{-8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518},
-			FieldElement{-2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233},
-		},
-		{
-			FieldElement{-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793},
-			FieldElement{-2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794},
-			FieldElement{580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435},
-		},
-		{
-			FieldElement{23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921},
-			FieldElement{13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518},
-			FieldElement{2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563},
-		},
-		{
-			FieldElement{14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278},
-			FieldElement{-27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024},
-			FieldElement{4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030},
-		},
-		{
-			FieldElement{10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783},
-			FieldElement{27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717},
-			FieldElement{6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844},
-		},
-		{
-			FieldElement{14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333},
-			FieldElement{16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048},
-			FieldElement{22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760},
-		},
-		{
-			FieldElement{-4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760},
-			FieldElement{-15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757},
-			FieldElement{-2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112},
-		},
-	},
-	{
-		{
-			FieldElement{-19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468},
-			FieldElement{3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184},
-			FieldElement{10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289},
-		},
-		{
-			FieldElement{15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066},
-			FieldElement{24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882},
-			FieldElement{13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226},
-		},
-		{
-			FieldElement{16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101},
-			FieldElement{29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279},
-			FieldElement{-6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811},
-		},
-		{
-			FieldElement{27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709},
-			FieldElement{20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714},
-			FieldElement{-2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121},
-		},
-		{
-			FieldElement{9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464},
-			FieldElement{12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847},
-			FieldElement{13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400},
-		},
-		{
-			FieldElement{4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414},
-			FieldElement{-15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158},
-			FieldElement{17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045},
-		},
-		{
-			FieldElement{-461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415},
-			FieldElement{-5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459},
-			FieldElement{-31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079},
-		},
-		{
-			FieldElement{21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412},
-			FieldElement{-20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743},
-			FieldElement{-14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836},
-		},
-	},
-	{
-		{
-			FieldElement{12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022},
-			FieldElement{18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429},
-			FieldElement{-6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065},
-		},
-		{
-			FieldElement{30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861},
-			FieldElement{10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000},
-			FieldElement{-33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101},
-		},
-		{
-			FieldElement{32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815},
-			FieldElement{29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642},
-			FieldElement{10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966},
-		},
-		{
-			FieldElement{25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574},
-			FieldElement{-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742},
-			FieldElement{-18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689},
-		},
-		{
-			FieldElement{12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020},
-			FieldElement{-10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772},
-			FieldElement{3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982},
-		},
-		{
-			FieldElement{-14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953},
-			FieldElement{-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218},
-			FieldElement{-17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265},
-		},
-		{
-			FieldElement{29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073},
-			FieldElement{-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325},
-			FieldElement{-11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798},
-		},
-		{
-			FieldElement{-4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870},
-			FieldElement{-7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863},
-			FieldElement{-13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927},
-		},
-	},
-	{
-		{
-			FieldElement{-2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267},
-			FieldElement{-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663},
-			FieldElement{22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862},
-		},
-		{
-			FieldElement{-25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673},
-			FieldElement{15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943},
-			FieldElement{15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020},
-		},
-		{
-			FieldElement{-4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238},
-			FieldElement{11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064},
-			FieldElement{14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795},
-		},
-		{
-			FieldElement{15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052},
-			FieldElement{-10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904},
-			FieldElement{29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531},
-		},
-		{
-			FieldElement{-13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979},
-			FieldElement{-5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841},
-			FieldElement{10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431},
-		},
-		{
-			FieldElement{10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324},
-			FieldElement{-31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940},
-			FieldElement{10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320},
-		},
-		{
-			FieldElement{-15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184},
-			FieldElement{14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114},
-			FieldElement{30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878},
-		},
-		{
-			FieldElement{12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784},
-			FieldElement{-2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091},
-			FieldElement{-16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585},
-		},
-	},
-	{
-		{
-			FieldElement{-8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208},
-			FieldElement{10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864},
-			FieldElement{17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661},
-		},
-		{
-			FieldElement{7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233},
-			FieldElement{26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212},
-			FieldElement{-12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525},
-		},
-		{
-			FieldElement{-24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068},
-			FieldElement{9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397},
-			FieldElement{-8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988},
-		},
-		{
-			FieldElement{5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889},
-			FieldElement{32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038},
-			FieldElement{14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697},
-		},
-		{
-			FieldElement{20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875},
-			FieldElement{-25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905},
-			FieldElement{-25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656},
-		},
-		{
-			FieldElement{11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818},
-			FieldElement{27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714},
-			FieldElement{10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203},
-		},
-		{
-			FieldElement{20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931},
-			FieldElement{-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024},
-			FieldElement{-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084},
-		},
-		{
-			FieldElement{-1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204},
-			FieldElement{20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817},
-			FieldElement{27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667},
-		},
-	},
-	{
-		{
-			FieldElement{11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504},
-			FieldElement{-12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768},
-			FieldElement{-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255},
-		},
-		{
-			FieldElement{6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790},
-			FieldElement{1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438},
-			FieldElement{-22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333},
-		},
-		{
-			FieldElement{17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971},
-			FieldElement{31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905},
-			FieldElement{29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409},
-		},
-		{
-			FieldElement{12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409},
-			FieldElement{6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499},
-			FieldElement{-8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363},
-		},
-		{
-			FieldElement{28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664},
-			FieldElement{-11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324},
-			FieldElement{-21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940},
-		},
-		{
-			FieldElement{13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990},
-			FieldElement{-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914},
-			FieldElement{-25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290},
-		},
-		{
-			FieldElement{24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257},
-			FieldElement{-6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433},
-			FieldElement{-16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236},
-		},
-		{
-			FieldElement{-12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045},
-			FieldElement{11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093},
-			FieldElement{-1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347},
-		},
-	},
-	{
-		{
-			FieldElement{-28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191},
-			FieldElement{-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507},
-			FieldElement{-12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906},
-		},
-		{
-			FieldElement{3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018},
-			FieldElement{-16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109},
-			FieldElement{-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926},
-		},
-		{
-			FieldElement{-24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528},
-			FieldElement{8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625},
-			FieldElement{-32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286},
-		},
-		{
-			FieldElement{2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033},
-			FieldElement{27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866},
-			FieldElement{21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896},
-		},
-		{
-			FieldElement{30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075},
-			FieldElement{26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347},
-			FieldElement{-22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437},
-		},
-		{
-			FieldElement{-5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165},
-			FieldElement{-18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588},
-			FieldElement{-32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193},
-		},
-		{
-			FieldElement{-19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017},
-			FieldElement{-28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883},
-			FieldElement{21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961},
-		},
-		{
-			FieldElement{8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043},
-			FieldElement{29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663},
-			FieldElement{-20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362},
-		},
-	},
-	{
-		{
-			FieldElement{-33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860},
-			FieldElement{2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466},
-			FieldElement{-24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063},
-		},
-		{
-			FieldElement{-26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997},
-			FieldElement{-1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295},
-			FieldElement{-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369},
-		},
-		{
-			FieldElement{9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385},
-			FieldElement{18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109},
-			FieldElement{2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906},
-		},
-		{
-			FieldElement{4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424},
-			FieldElement{-19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185},
-			FieldElement{7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962},
-		},
-		{
-			FieldElement{-7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325},
-			FieldElement{10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593},
-			FieldElement{696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404},
-		},
-		{
-			FieldElement{-11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644},
-			FieldElement{17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801},
-			FieldElement{26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804},
-		},
-		{
-			FieldElement{-31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884},
-			FieldElement{-586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577},
-			FieldElement{-9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849},
-		},
-		{
-			FieldElement{32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473},
-			FieldElement{-8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644},
-			FieldElement{-2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319},
-		},
-	},
-	{
-		{
-			FieldElement{-11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599},
-			FieldElement{-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768},
-			FieldElement{-27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084},
-		},
-		{
-			FieldElement{-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328},
-			FieldElement{-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369},
-			FieldElement{20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920},
-		},
-		{
-			FieldElement{12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815},
-			FieldElement{-32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025},
-			FieldElement{-21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397},
-		},
-		{
-			FieldElement{-20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448},
-			FieldElement{6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981},
-			FieldElement{30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165},
-		},
-		{
-			FieldElement{32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501},
-			FieldElement{17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073},
-			FieldElement{-1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861},
-		},
-		{
-			FieldElement{14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845},
-			FieldElement{-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211},
-			FieldElement{18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870},
-		},
-		{
-			FieldElement{10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096},
-			FieldElement{33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803},
-			FieldElement{-32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168},
-		},
-		{
-			FieldElement{30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965},
-			FieldElement{-14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505},
-			FieldElement{18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598},
-		},
-	},
-	{
-		{
-			FieldElement{5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782},
-			FieldElement{5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900},
-			FieldElement{-31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479},
-		},
-		{
-			FieldElement{-12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208},
-			FieldElement{8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232},
-			FieldElement{17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719},
-		},
-		{
-			FieldElement{16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271},
-			FieldElement{-4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326},
-			FieldElement{-8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132},
-		},
-		{
-			FieldElement{14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300},
-			FieldElement{8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570},
-			FieldElement{15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670},
-		},
-		{
-			FieldElement{-2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994},
-			FieldElement{-12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913},
-			FieldElement{31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317},
-		},
-		{
-			FieldElement{-25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730},
-			FieldElement{842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096},
-			FieldElement{-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078},
-		},
-		{
-			FieldElement{-15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411},
-			FieldElement{-19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905},
-			FieldElement{-9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654},
-		},
-		{
-			FieldElement{-28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870},
-			FieldElement{-23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498},
-			FieldElement{12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579},
-		},
-	},
-	{
-		{
-			FieldElement{14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677},
-			FieldElement{10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647},
-			FieldElement{-2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743},
-		},
-		{
-			FieldElement{-25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468},
-			FieldElement{21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375},
-			FieldElement{-25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155},
-		},
-		{
-			FieldElement{6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725},
-			FieldElement{-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612},
-			FieldElement{-10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943},
-		},
-		{
-			FieldElement{-30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944},
-			FieldElement{30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928},
-			FieldElement{9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406},
-		},
-		{
-			FieldElement{22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139},
-			FieldElement{-8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963},
-			FieldElement{-31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693},
-		},
-		{
-			FieldElement{1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734},
-			FieldElement{-448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680},
-			FieldElement{-24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410},
-		},
-		{
-			FieldElement{-9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931},
-			FieldElement{-16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654},
-			FieldElement{22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710},
-		},
-		{
-			FieldElement{29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180},
-			FieldElement{-26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684},
-			FieldElement{-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895},
-		},
-	},
-	{
-		{
-			FieldElement{22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501},
-			FieldElement{-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413},
-			FieldElement{6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880},
-		},
-		{
-			FieldElement{-8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874},
-			FieldElement{22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962},
-			FieldElement{-7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899},
-		},
-		{
-			FieldElement{21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152},
-			FieldElement{9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063},
-			FieldElement{7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080},
-		},
-		{
-			FieldElement{-9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146},
-			FieldElement{-17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183},
-			FieldElement{-19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133},
-		},
-		{
-			FieldElement{-32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421},
-			FieldElement{-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622},
-			FieldElement{-4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197},
-		},
-		{
-			FieldElement{2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663},
-			FieldElement{31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753},
-			FieldElement{4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755},
-		},
-		{
-			FieldElement{-9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862},
-			FieldElement{-26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118},
-			FieldElement{26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171},
-		},
-		{
-			FieldElement{15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380},
-			FieldElement{16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824},
-			FieldElement{28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270},
-		},
-	},
-	{
-		{
-			FieldElement{-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438},
-			FieldElement{-31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584},
-			FieldElement{-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562},
-		},
-		{
-			FieldElement{30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471},
-			FieldElement{18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610},
-			FieldElement{19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269},
-		},
-		{
-			FieldElement{-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650},
-			FieldElement{14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369},
-			FieldElement{19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461},
-		},
-		{
-			FieldElement{30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462},
-			FieldElement{-5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793},
-			FieldElement{-2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218},
-		},
-		{
-			FieldElement{-24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226},
-			FieldElement{18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019},
-			FieldElement{-15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037},
-		},
-		{
-			FieldElement{31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171},
-			FieldElement{-17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132},
-			FieldElement{-28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841},
-		},
-		{
-			FieldElement{21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181},
-			FieldElement{-33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210},
-			FieldElement{-1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040},
-		},
-		{
-			FieldElement{3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935},
-			FieldElement{24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105},
-			FieldElement{-28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814},
-		},
-	},
-	{
-		{
-			FieldElement{793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852},
-			FieldElement{5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581},
-			FieldElement{-4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646},
-		},
-		{
-			FieldElement{10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844},
-			FieldElement{10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025},
-			FieldElement{27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453},
-		},
-		{
-			FieldElement{-23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068},
-			FieldElement{4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192},
-			FieldElement{-17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921},
-		},
-		{
-			FieldElement{-9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259},
-			FieldElement{-12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426},
-			FieldElement{-5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072},
-		},
-		{
-			FieldElement{-17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305},
-			FieldElement{13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832},
-			FieldElement{28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943},
-		},
-		{
-			FieldElement{-16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011},
-			FieldElement{24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447},
-			FieldElement{17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494},
-		},
-		{
-			FieldElement{-28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245},
-			FieldElement{-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859},
-			FieldElement{28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915},
-		},
-		{
-			FieldElement{16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707},
-			FieldElement{10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848},
-			FieldElement{-11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224},
-		},
-	},
-	{
-		{
-			FieldElement{-25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391},
-			FieldElement{15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215},
-			FieldElement{-23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101},
-		},
-		{
-			FieldElement{23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713},
-			FieldElement{21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849},
-			FieldElement{-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930},
-		},
-		{
-			FieldElement{-29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940},
-			FieldElement{-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031},
-			FieldElement{-17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404},
-		},
-		{
-			FieldElement{-25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243},
-			FieldElement{-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116},
-			FieldElement{-24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525},
-		},
-		{
-			FieldElement{-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509},
-			FieldElement{-10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883},
-			FieldElement{15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865},
-		},
-		{
-			FieldElement{-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660},
-			FieldElement{4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273},
-			FieldElement{-28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138},
-		},
-		{
-			FieldElement{-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560},
-			FieldElement{-10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135},
-			FieldElement{2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941},
-		},
-		{
-			FieldElement{-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739},
-			FieldElement{18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756},
-			FieldElement{-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819},
-		},
-	},
-	{
-		{
-			FieldElement{-6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347},
-			FieldElement{-27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028},
-			FieldElement{21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075},
-		},
-		{
-			FieldElement{16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799},
-			FieldElement{-2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609},
-			FieldElement{-25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817},
-		},
-		{
-			FieldElement{-23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989},
-			FieldElement{-30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523},
-			FieldElement{4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278},
-		},
-		{
-			FieldElement{31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045},
-			FieldElement{19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377},
-			FieldElement{24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480},
-		},
-		{
-			FieldElement{17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016},
-			FieldElement{510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426},
-			FieldElement{18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525},
-		},
-		{
-			FieldElement{13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396},
-			FieldElement{9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080},
-			FieldElement{12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892},
-		},
-		{
-			FieldElement{15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275},
-			FieldElement{11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074},
-			FieldElement{20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140},
-		},
-		{
-			FieldElement{-16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717},
-			FieldElement{-1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101},
-			FieldElement{24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127},
-		},
-	},
-	{
-		{
-			FieldElement{-12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632},
-			FieldElement{-26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415},
-			FieldElement{-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160},
-		},
-		{
-			FieldElement{31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876},
-			FieldElement{22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625},
-			FieldElement{-15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478},
-		},
-		{
-			FieldElement{27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164},
-			FieldElement{26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595},
-			FieldElement{-7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248},
-		},
-		{
-			FieldElement{-16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858},
-			FieldElement{15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193},
-			FieldElement{8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184},
-		},
-		{
-			FieldElement{-18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942},
-			FieldElement{-1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635},
-			FieldElement{21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948},
-		},
-		{
-			FieldElement{11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935},
-			FieldElement{-25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415},
-			FieldElement{-15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416},
-		},
-		{
-			FieldElement{-7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018},
-			FieldElement{4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778},
-			FieldElement{366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659},
-		},
-		{
-			FieldElement{-24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385},
-			FieldElement{18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503},
-			FieldElement{476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329},
-		},
-	},
-	{
-		{
-			FieldElement{20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056},
-			FieldElement{-13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838},
-			FieldElement{24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948},
-		},
-		{
-			FieldElement{-3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691},
-			FieldElement{-15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118},
-			FieldElement{-23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517},
-		},
-		{
-			FieldElement{-20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269},
-			FieldElement{-6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904},
-			FieldElement{-23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589},
-		},
-		{
-			FieldElement{-28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193},
-			FieldElement{-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910},
-			FieldElement{-30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930},
-		},
-		{
-			FieldElement{-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667},
-			FieldElement{25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481},
-			FieldElement{-9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876},
-		},
-		{
-			FieldElement{22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640},
-			FieldElement{-8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278},
-			FieldElement{-21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112},
-		},
-		{
-			FieldElement{26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272},
-			FieldElement{17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012},
-			FieldElement{-10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221},
-		},
-		{
-			FieldElement{30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046},
-			FieldElement{13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345},
-			FieldElement{-19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310},
-		},
-	},
-	{
-		{
-			FieldElement{19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937},
-			FieldElement{31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636},
-			FieldElement{-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008},
-		},
-		{
-			FieldElement{-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429},
-			FieldElement{-15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576},
-			FieldElement{31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066},
-		},
-		{
-			FieldElement{-9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490},
-			FieldElement{-12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104},
-			FieldElement{33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053},
-		},
-		{
-			FieldElement{31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275},
-			FieldElement{-20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511},
-			FieldElement{22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095},
-		},
-		{
-			FieldElement{-28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439},
-			FieldElement{23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939},
-			FieldElement{-23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424},
-		},
-		{
-			FieldElement{2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310},
-			FieldElement{3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608},
-			FieldElement{-32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079},
-		},
-		{
-			FieldElement{-23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101},
-			FieldElement{21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418},
-			FieldElement{18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576},
-		},
-		{
-			FieldElement{30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356},
-			FieldElement{9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996},
-			FieldElement{-26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099},
-		},
-	},
-	{
-		{
-			FieldElement{-26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728},
-			FieldElement{-13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658},
-			FieldElement{-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242},
-		},
-		{
-			FieldElement{-21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001},
-			FieldElement{-4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766},
-			FieldElement{18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373},
-		},
-		{
-			FieldElement{26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458},
-			FieldElement{-17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628},
-			FieldElement{-13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657},
-		},
-		{
-			FieldElement{-23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062},
-			FieldElement{25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616},
-			FieldElement{31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014},
-		},
-		{
-			FieldElement{24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383},
-			FieldElement{-25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814},
-			FieldElement{-20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718},
-		},
-		{
-			FieldElement{30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417},
-			FieldElement{2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222},
-			FieldElement{33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444},
-		},
-		{
-			FieldElement{-20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597},
-			FieldElement{23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970},
-			FieldElement{1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799},
-		},
-		{
-			FieldElement{-5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647},
-			FieldElement{13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511},
-			FieldElement{-29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032},
-		},
-	},
-	{
-		{
-			FieldElement{9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834},
-			FieldElement{-23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461},
-			FieldElement{29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062},
-		},
-		{
-			FieldElement{-25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516},
-			FieldElement{-20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547},
-			FieldElement{-24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240},
-		},
-		{
-			FieldElement{-17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038},
-			FieldElement{-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741},
-			FieldElement{16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103},
-		},
-		{
-			FieldElement{-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747},
-			FieldElement{-1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323},
-			FieldElement{31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016},
-		},
-		{
-			FieldElement{-14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373},
-			FieldElement{15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228},
-			FieldElement{-2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141},
-		},
-		{
-			FieldElement{16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399},
-			FieldElement{11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831},
-			FieldElement{-185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376},
-		},
-		{
-			FieldElement{-32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313},
-			FieldElement{-18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958},
-			FieldElement{-6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577},
-		},
-		{
-			FieldElement{-22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743},
-			FieldElement{29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684},
-			FieldElement{-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476},
-		},
-	},
-}
diff --git a/src/crypto/ed25519/internal/edwards25519/doc.go b/src/crypto/ed25519/internal/edwards25519/doc.go
new file mode 100644
index 0000000..ff31cd2
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/doc.go
@@ -0,0 +1,22 @@
+// Copyright (c) 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package edwards25519 implements group logic for the twisted Edwards curve
+//
+//     -x^2 + y^2 = 1 + -(121665/121666)*x^2*y^2
+//
+// This is better known as the Edwards curve equivalent to Curve25519, and is
+// the curve used by the Ed25519 signature scheme.
+//
+// Most users don't need this package, and should instead use crypto/ed25519 for
+// signatures, golang.org/x/crypto/curve25519 for Diffie-Hellman, or
+// github.com/gtank/ristretto255 for prime order group logic.
+//
+// However, developers who do need to interact with low-level edwards25519
+// operations can use filippo.io/edwards25519, an extended version of this
+// package repackaged as an importable module.
+//
+// (Note that filippo.io/edwards25519 and github.com/gtank/ristretto255 are not
+// maintained by the Go team and are not covered by the Go 1 Compatibility Promise.)
+package edwards25519
diff --git a/src/crypto/ed25519/internal/edwards25519/edwards25519.go b/src/crypto/ed25519/internal/edwards25519/edwards25519.go
index b091481..313e6c2 100644
--- a/src/crypto/ed25519/internal/edwards25519/edwards25519.go
+++ b/src/crypto/ed25519/internal/edwards25519/edwards25519.go
@@ -1,1793 +1,427 @@
-// Copyright 2016 The Go Authors. All rights reserved.
+// Copyright (c) 2017 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 package edwards25519
 
-import "encoding/binary"
+import (
+	"crypto/ed25519/internal/edwards25519/field"
+	"errors"
+)
 
-// This code is a port of the public domain, “ref10” implementation of ed25519
-// from SUPERCOP.
+// Point types.
 
-// FieldElement represents an element of the field GF(2^255 - 19).  An element
-// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
-// t[3]+2^102 t[4]+...+2^230 t[9].  Bounds on each t[i] vary depending on
-// context.
-type FieldElement [10]int32
-
-var zero FieldElement
-
-func FeZero(fe *FieldElement) {
-	copy(fe[:], zero[:])
+type projP1xP1 struct {
+	X, Y, Z, T field.Element
 }
 
-func FeOne(fe *FieldElement) {
-	FeZero(fe)
-	fe[0] = 1
+type projP2 struct {
+	X, Y, Z field.Element
 }
 
-func FeAdd(dst, a, b *FieldElement) {
-	dst[0] = a[0] + b[0]
-	dst[1] = a[1] + b[1]
-	dst[2] = a[2] + b[2]
-	dst[3] = a[3] + b[3]
-	dst[4] = a[4] + b[4]
-	dst[5] = a[5] + b[5]
-	dst[6] = a[6] + b[6]
-	dst[7] = a[7] + b[7]
-	dst[8] = a[8] + b[8]
-	dst[9] = a[9] + b[9]
-}
-
-func FeSub(dst, a, b *FieldElement) {
-	dst[0] = a[0] - b[0]
-	dst[1] = a[1] - b[1]
-	dst[2] = a[2] - b[2]
-	dst[3] = a[3] - b[3]
-	dst[4] = a[4] - b[4]
-	dst[5] = a[5] - b[5]
-	dst[6] = a[6] - b[6]
-	dst[7] = a[7] - b[7]
-	dst[8] = a[8] - b[8]
-	dst[9] = a[9] - b[9]
-}
-
-func FeCopy(dst, src *FieldElement) {
-	copy(dst[:], src[:])
-}
-
-// Replace (f,g) with (g,g) if b == 1;
-// replace (f,g) with (f,g) if b == 0.
+// Point represents a point on the edwards25519 curve.
 //
-// Preconditions: b in {0,1}.
-func FeCMove(f, g *FieldElement, b int32) {
-	b = -b
-	f[0] ^= b & (f[0] ^ g[0])
-	f[1] ^= b & (f[1] ^ g[1])
-	f[2] ^= b & (f[2] ^ g[2])
-	f[3] ^= b & (f[3] ^ g[3])
-	f[4] ^= b & (f[4] ^ g[4])
-	f[5] ^= b & (f[5] ^ g[5])
-	f[6] ^= b & (f[6] ^ g[6])
-	f[7] ^= b & (f[7] ^ g[7])
-	f[8] ^= b & (f[8] ^ g[8])
-	f[9] ^= b & (f[9] ^ g[9])
-}
-
-func load3(in []byte) int64 {
-	var r int64
-	r = int64(in[0])
-	r |= int64(in[1]) << 8
-	r |= int64(in[2]) << 16
-	return r
-}
-
-func load4(in []byte) int64 {
-	var r int64
-	r = int64(in[0])
-	r |= int64(in[1]) << 8
-	r |= int64(in[2]) << 16
-	r |= int64(in[3]) << 24
-	return r
-}
-
-func FeFromBytes(dst *FieldElement, src *[32]byte) {
-	h0 := load4(src[:])
-	h1 := load3(src[4:]) << 6
-	h2 := load3(src[7:]) << 5
-	h3 := load3(src[10:]) << 3
-	h4 := load3(src[13:]) << 2
-	h5 := load4(src[16:])
-	h6 := load3(src[20:]) << 7
-	h7 := load3(src[23:]) << 5
-	h8 := load3(src[26:]) << 4
-	h9 := (load3(src[29:]) & 8388607) << 2
-
-	FeCombine(dst, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9)
-}
-
-// FeToBytes marshals h to s.
-// Preconditions:
-//   |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+// This type works similarly to math/big.Int, and all arguments and receivers
+// are allowed to alias.
 //
-// Write p=2^255-19; q=floor(h/p).
-// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
-//
-// Proof:
-//   Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
-//   Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.
-//
-//   Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
-//   Then 0<y<1.
-//
-//   Write r=h-pq.
-//   Have 0<=r<=p-1=2^255-20.
-//   Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
-//
-//   Write x=r+19(2^-255)r+y.
-//   Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
-//
-//   Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
-//   so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
-func FeToBytes(s *[32]byte, h *FieldElement) {
-	var carry [10]int32
+// The zero value is NOT valid, and it may be used only as a receiver.
+type Point struct {
+	// The point is internally represented in extended coordinates (X, Y, Z, T)
+	// where x = X/Z, y = Y/Z, and xy = T/Z per https://eprint.iacr.org/2008/522.
+	x, y, z, t field.Element
 
-	q := (19*h[9] + (1 << 24)) >> 25
-	q = (h[0] + q) >> 26
-	q = (h[1] + q) >> 25
-	q = (h[2] + q) >> 26
-	q = (h[3] + q) >> 25
-	q = (h[4] + q) >> 26
-	q = (h[5] + q) >> 25
-	q = (h[6] + q) >> 26
-	q = (h[7] + q) >> 25
-	q = (h[8] + q) >> 26
-	q = (h[9] + q) >> 25
-
-	// Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20.
-	h[0] += 19 * q
-	// Goal: Output h-2^255 q, which is between 0 and 2^255-20.
-
-	carry[0] = h[0] >> 26
-	h[1] += carry[0]
-	h[0] -= carry[0] << 26
-	carry[1] = h[1] >> 25
-	h[2] += carry[1]
-	h[1] -= carry[1] << 25
-	carry[2] = h[2] >> 26
-	h[3] += carry[2]
-	h[2] -= carry[2] << 26
-	carry[3] = h[3] >> 25
-	h[4] += carry[3]
-	h[3] -= carry[3] << 25
-	carry[4] = h[4] >> 26
-	h[5] += carry[4]
-	h[4] -= carry[4] << 26
-	carry[5] = h[5] >> 25
-	h[6] += carry[5]
-	h[5] -= carry[5] << 25
-	carry[6] = h[6] >> 26
-	h[7] += carry[6]
-	h[6] -= carry[6] << 26
-	carry[7] = h[7] >> 25
-	h[8] += carry[7]
-	h[7] -= carry[7] << 25
-	carry[8] = h[8] >> 26
-	h[9] += carry[8]
-	h[8] -= carry[8] << 26
-	carry[9] = h[9] >> 25
-	h[9] -= carry[9] << 25
-	// h10 = carry9
-
-	// Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
-	// Have h[0]+...+2^230 h[9] between 0 and 2^255-1;
-	// evidently 2^255 h10-2^255 q = 0.
-	// Goal: Output h[0]+...+2^230 h[9].
-
-	s[0] = byte(h[0] >> 0)
-	s[1] = byte(h[0] >> 8)
-	s[2] = byte(h[0] >> 16)
-	s[3] = byte((h[0] >> 24) | (h[1] << 2))
-	s[4] = byte(h[1] >> 6)
-	s[5] = byte(h[1] >> 14)
-	s[6] = byte((h[1] >> 22) | (h[2] << 3))
-	s[7] = byte(h[2] >> 5)
-	s[8] = byte(h[2] >> 13)
-	s[9] = byte((h[2] >> 21) | (h[3] << 5))
-	s[10] = byte(h[3] >> 3)
-	s[11] = byte(h[3] >> 11)
-	s[12] = byte((h[3] >> 19) | (h[4] << 6))
-	s[13] = byte(h[4] >> 2)
-	s[14] = byte(h[4] >> 10)
-	s[15] = byte(h[4] >> 18)
-	s[16] = byte(h[5] >> 0)
-	s[17] = byte(h[5] >> 8)
-	s[18] = byte(h[5] >> 16)
-	s[19] = byte((h[5] >> 24) | (h[6] << 1))
-	s[20] = byte(h[6] >> 7)
-	s[21] = byte(h[6] >> 15)
-	s[22] = byte((h[6] >> 23) | (h[7] << 3))
-	s[23] = byte(h[7] >> 5)
-	s[24] = byte(h[7] >> 13)
-	s[25] = byte((h[7] >> 21) | (h[8] << 4))
-	s[26] = byte(h[8] >> 4)
-	s[27] = byte(h[8] >> 12)
-	s[28] = byte((h[8] >> 20) | (h[9] << 6))
-	s[29] = byte(h[9] >> 2)
-	s[30] = byte(h[9] >> 10)
-	s[31] = byte(h[9] >> 18)
+	// Make the type not comparable (i.e. used with == or as a map key), as
+	// equivalent points can be represented by different Go values.
+	_ incomparable
 }
 
-func FeIsNegative(f *FieldElement) byte {
-	var s [32]byte
-	FeToBytes(&s, f)
-	return s[0] & 1
-}
+type incomparable [0]func()
 
-func FeIsNonZero(f *FieldElement) int32 {
-	var s [32]byte
-	FeToBytes(&s, f)
-	var x uint8
-	for _, b := range s {
-		x |= b
-	}
-	x |= x >> 4
-	x |= x >> 2
-	x |= x >> 1
-	return int32(x & 1)
-}
-
-// FeNeg sets h = -f
-//
-// Preconditions:
-//    |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-//
-// Postconditions:
-//    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-func FeNeg(h, f *FieldElement) {
-	h[0] = -f[0]
-	h[1] = -f[1]
-	h[2] = -f[2]
-	h[3] = -f[3]
-	h[4] = -f[4]
-	h[5] = -f[5]
-	h[6] = -f[6]
-	h[7] = -f[7]
-	h[8] = -f[8]
-	h[9] = -f[9]
-}
-
-func FeCombine(h *FieldElement, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 int64) {
-	var c0, c1, c2, c3, c4, c5, c6, c7, c8, c9 int64
-
-	/*
-	  |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38))
-	    i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8
-	  |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19))
-	    i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9
-	*/
-
-	c0 = (h0 + (1 << 25)) >> 26
-	h1 += c0
-	h0 -= c0 << 26
-	c4 = (h4 + (1 << 25)) >> 26
-	h5 += c4
-	h4 -= c4 << 26
-	/* |h0| <= 2^25 */
-	/* |h4| <= 2^25 */
-	/* |h1| <= 1.51*2^58 */
-	/* |h5| <= 1.51*2^58 */
-
-	c1 = (h1 + (1 << 24)) >> 25
-	h2 += c1
-	h1 -= c1 << 25
-	c5 = (h5 + (1 << 24)) >> 25
-	h6 += c5
-	h5 -= c5 << 25
-	/* |h1| <= 2^24; from now on fits into int32 */
-	/* |h5| <= 2^24; from now on fits into int32 */
-	/* |h2| <= 1.21*2^59 */
-	/* |h6| <= 1.21*2^59 */
-
-	c2 = (h2 + (1 << 25)) >> 26
-	h3 += c2
-	h2 -= c2 << 26
-	c6 = (h6 + (1 << 25)) >> 26
-	h7 += c6
-	h6 -= c6 << 26
-	/* |h2| <= 2^25; from now on fits into int32 unchanged */
-	/* |h6| <= 2^25; from now on fits into int32 unchanged */
-	/* |h3| <= 1.51*2^58 */
-	/* |h7| <= 1.51*2^58 */
-
-	c3 = (h3 + (1 << 24)) >> 25
-	h4 += c3
-	h3 -= c3 << 25
-	c7 = (h7 + (1 << 24)) >> 25
-	h8 += c7
-	h7 -= c7 << 25
-	/* |h3| <= 2^24; from now on fits into int32 unchanged */
-	/* |h7| <= 2^24; from now on fits into int32 unchanged */
-	/* |h4| <= 1.52*2^33 */
-	/* |h8| <= 1.52*2^33 */
-
-	c4 = (h4 + (1 << 25)) >> 26
-	h5 += c4
-	h4 -= c4 << 26
-	c8 = (h8 + (1 << 25)) >> 26
-	h9 += c8
-	h8 -= c8 << 26
-	/* |h4| <= 2^25; from now on fits into int32 unchanged */
-	/* |h8| <= 2^25; from now on fits into int32 unchanged */
-	/* |h5| <= 1.01*2^24 */
-	/* |h9| <= 1.51*2^58 */
-
-	c9 = (h9 + (1 << 24)) >> 25
-	h0 += c9 * 19
-	h9 -= c9 << 25
-	/* |h9| <= 2^24; from now on fits into int32 unchanged */
-	/* |h0| <= 1.8*2^37 */
-
-	c0 = (h0 + (1 << 25)) >> 26
-	h1 += c0
-	h0 -= c0 << 26
-	/* |h0| <= 2^25; from now on fits into int32 unchanged */
-	/* |h1| <= 1.01*2^24 */
-
-	h[0] = int32(h0)
-	h[1] = int32(h1)
-	h[2] = int32(h2)
-	h[3] = int32(h3)
-	h[4] = int32(h4)
-	h[5] = int32(h5)
-	h[6] = int32(h6)
-	h[7] = int32(h7)
-	h[8] = int32(h8)
-	h[9] = int32(h9)
-}
-
-// FeMul calculates h = f * g
-// Can overlap h with f or g.
-//
-// Preconditions:
-//    |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
-//    |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
-//
-// Postconditions:
-//    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-//
-// Notes on implementation strategy:
-//
-// Using schoolbook multiplication.
-// Karatsuba would save a little in some cost models.
-//
-// Most multiplications by 2 and 19 are 32-bit precomputations;
-// cheaper than 64-bit postcomputations.
-//
-// There is one remaining multiplication by 19 in the carry chain;
-// one *19 precomputation can be merged into this,
-// but the resulting data flow is considerably less clean.
-//
-// There are 12 carries below.
-// 10 of them are 2-way parallelizable and vectorizable.
-// Can get away with 11 carries, but then data flow is much deeper.
-//
-// With tighter constraints on inputs, can squeeze carries into int32.
-func FeMul(h, f, g *FieldElement) {
-	f0 := int64(f[0])
-	f1 := int64(f[1])
-	f2 := int64(f[2])
-	f3 := int64(f[3])
-	f4 := int64(f[4])
-	f5 := int64(f[5])
-	f6 := int64(f[6])
-	f7 := int64(f[7])
-	f8 := int64(f[8])
-	f9 := int64(f[9])
-
-	f1_2 := int64(2 * f[1])
-	f3_2 := int64(2 * f[3])
-	f5_2 := int64(2 * f[5])
-	f7_2 := int64(2 * f[7])
-	f9_2 := int64(2 * f[9])
-
-	g0 := int64(g[0])
-	g1 := int64(g[1])
-	g2 := int64(g[2])
-	g3 := int64(g[3])
-	g4 := int64(g[4])
-	g5 := int64(g[5])
-	g6 := int64(g[6])
-	g7 := int64(g[7])
-	g8 := int64(g[8])
-	g9 := int64(g[9])
-
-	g1_19 := int64(19 * g[1]) /* 1.4*2^29 */
-	g2_19 := int64(19 * g[2]) /* 1.4*2^30; still ok */
-	g3_19 := int64(19 * g[3])
-	g4_19 := int64(19 * g[4])
-	g5_19 := int64(19 * g[5])
-	g6_19 := int64(19 * g[6])
-	g7_19 := int64(19 * g[7])
-	g8_19 := int64(19 * g[8])
-	g9_19 := int64(19 * g[9])
-
-	h0 := f0*g0 + f1_2*g9_19 + f2*g8_19 + f3_2*g7_19 + f4*g6_19 + f5_2*g5_19 + f6*g4_19 + f7_2*g3_19 + f8*g2_19 + f9_2*g1_19
-	h1 := f0*g1 + f1*g0 + f2*g9_19 + f3*g8_19 + f4*g7_19 + f5*g6_19 + f6*g5_19 + f7*g4_19 + f8*g3_19 + f9*g2_19
-	h2 := f0*g2 + f1_2*g1 + f2*g0 + f3_2*g9_19 + f4*g8_19 + f5_2*g7_19 + f6*g6_19 + f7_2*g5_19 + f8*g4_19 + f9_2*g3_19
-	h3 := f0*g3 + f1*g2 + f2*g1 + f3*g0 + f4*g9_19 + f5*g8_19 + f6*g7_19 + f7*g6_19 + f8*g5_19 + f9*g4_19
-	h4 := f0*g4 + f1_2*g3 + f2*g2 + f3_2*g1 + f4*g0 + f5_2*g9_19 + f6*g8_19 + f7_2*g7_19 + f8*g6_19 + f9_2*g5_19
-	h5 := f0*g5 + f1*g4 + f2*g3 + f3*g2 + f4*g1 + f5*g0 + f6*g9_19 + f7*g8_19 + f8*g7_19 + f9*g6_19
-	h6 := f0*g6 + f1_2*g5 + f2*g4 + f3_2*g3 + f4*g2 + f5_2*g1 + f6*g0 + f7_2*g9_19 + f8*g8_19 + f9_2*g7_19
-	h7 := f0*g7 + f1*g6 + f2*g5 + f3*g4 + f4*g3 + f5*g2 + f6*g1 + f7*g0 + f8*g9_19 + f9*g8_19
-	h8 := f0*g8 + f1_2*g7 + f2*g6 + f3_2*g5 + f4*g4 + f5_2*g3 + f6*g2 + f7_2*g1 + f8*g0 + f9_2*g9_19
-	h9 := f0*g9 + f1*g8 + f2*g7 + f3*g6 + f4*g5 + f5*g4 + f6*g3 + f7*g2 + f8*g1 + f9*g0
-
-	FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9)
-}
-
-func feSquare(f *FieldElement) (h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 int64) {
-	f0 := int64(f[0])
-	f1 := int64(f[1])
-	f2 := int64(f[2])
-	f3 := int64(f[3])
-	f4 := int64(f[4])
-	f5 := int64(f[5])
-	f6 := int64(f[6])
-	f7 := int64(f[7])
-	f8 := int64(f[8])
-	f9 := int64(f[9])
-	f0_2 := int64(2 * f[0])
-	f1_2 := int64(2 * f[1])
-	f2_2 := int64(2 * f[2])
-	f3_2 := int64(2 * f[3])
-	f4_2 := int64(2 * f[4])
-	f5_2 := int64(2 * f[5])
-	f6_2 := int64(2 * f[6])
-	f7_2 := int64(2 * f[7])
-	f5_38 := 38 * f5 // 1.31*2^30
-	f6_19 := 19 * f6 // 1.31*2^30
-	f7_38 := 38 * f7 // 1.31*2^30
-	f8_19 := 19 * f8 // 1.31*2^30
-	f9_38 := 38 * f9 // 1.31*2^30
-
-	h0 = f0*f0 + f1_2*f9_38 + f2_2*f8_19 + f3_2*f7_38 + f4_2*f6_19 + f5*f5_38
-	h1 = f0_2*f1 + f2*f9_38 + f3_2*f8_19 + f4*f7_38 + f5_2*f6_19
-	h2 = f0_2*f2 + f1_2*f1 + f3_2*f9_38 + f4_2*f8_19 + f5_2*f7_38 + f6*f6_19
-	h3 = f0_2*f3 + f1_2*f2 + f4*f9_38 + f5_2*f8_19 + f6*f7_38
-	h4 = f0_2*f4 + f1_2*f3_2 + f2*f2 + f5_2*f9_38 + f6_2*f8_19 + f7*f7_38
-	h5 = f0_2*f5 + f1_2*f4 + f2_2*f3 + f6*f9_38 + f7_2*f8_19
-	h6 = f0_2*f6 + f1_2*f5_2 + f2_2*f4 + f3_2*f3 + f7_2*f9_38 + f8*f8_19
-	h7 = f0_2*f7 + f1_2*f6 + f2_2*f5 + f3_2*f4 + f8*f9_38
-	h8 = f0_2*f8 + f1_2*f7_2 + f2_2*f6 + f3_2*f5_2 + f4*f4 + f9*f9_38
-	h9 = f0_2*f9 + f1_2*f8 + f2_2*f7 + f3_2*f6 + f4_2*f5
-
-	return
-}
-
-// FeSquare calculates h = f*f. Can overlap h with f.
-//
-// Preconditions:
-//    |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
-//
-// Postconditions:
-//    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-func FeSquare(h, f *FieldElement) {
-	h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 := feSquare(f)
-	FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9)
-}
-
-// FeSquare2 sets h = 2 * f * f
-//
-// Can overlap h with f.
-//
-// Preconditions:
-//    |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
-//
-// Postconditions:
-//    |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
-// See fe_mul.c for discussion of implementation strategy.
-func FeSquare2(h, f *FieldElement) {
-	h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 := feSquare(f)
-
-	h0 += h0
-	h1 += h1
-	h2 += h2
-	h3 += h3
-	h4 += h4
-	h5 += h5
-	h6 += h6
-	h7 += h7
-	h8 += h8
-	h9 += h9
-
-	FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9)
-}
-
-func FeInvert(out, z *FieldElement) {
-	var t0, t1, t2, t3 FieldElement
-	var i int
-
-	FeSquare(&t0, z)        // 2^1
-	FeSquare(&t1, &t0)      // 2^2
-	for i = 1; i < 2; i++ { // 2^3
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t1, z, &t1)      // 2^3 + 2^0
-	FeMul(&t0, &t0, &t1)    // 2^3 + 2^1 + 2^0
-	FeSquare(&t2, &t0)      // 2^4 + 2^2 + 2^1
-	FeMul(&t1, &t1, &t2)    // 2^4 + 2^3 + 2^2 + 2^1 + 2^0
-	FeSquare(&t2, &t1)      // 5,4,3,2,1
-	for i = 1; i < 5; i++ { // 9,8,7,6,5
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t1, &t2, &t1)     // 9,8,7,6,5,4,3,2,1,0
-	FeSquare(&t2, &t1)       // 10..1
-	for i = 1; i < 10; i++ { // 19..10
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t2, &t2, &t1)     // 19..0
-	FeSquare(&t3, &t2)       // 20..1
-	for i = 1; i < 20; i++ { // 39..20
-		FeSquare(&t3, &t3)
-	}
-	FeMul(&t2, &t3, &t2)     // 39..0
-	FeSquare(&t2, &t2)       // 40..1
-	for i = 1; i < 10; i++ { // 49..10
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t1, &t2, &t1)     // 49..0
-	FeSquare(&t2, &t1)       // 50..1
-	for i = 1; i < 50; i++ { // 99..50
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t2, &t2, &t1)      // 99..0
-	FeSquare(&t3, &t2)        // 100..1
-	for i = 1; i < 100; i++ { // 199..100
-		FeSquare(&t3, &t3)
-	}
-	FeMul(&t2, &t3, &t2)     // 199..0
-	FeSquare(&t2, &t2)       // 200..1
-	for i = 1; i < 50; i++ { // 249..50
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t1, &t2, &t1)    // 249..0
-	FeSquare(&t1, &t1)      // 250..1
-	for i = 1; i < 5; i++ { // 254..5
-		FeSquare(&t1, &t1)
-	}
-	FeMul(out, &t1, &t0) // 254..5,3,1,0
-}
-
-func fePow22523(out, z *FieldElement) {
-	var t0, t1, t2 FieldElement
-	var i int
-
-	FeSquare(&t0, z)
-	for i = 1; i < 1; i++ {
-		FeSquare(&t0, &t0)
-	}
-	FeSquare(&t1, &t0)
-	for i = 1; i < 2; i++ {
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t1, z, &t1)
-	FeMul(&t0, &t0, &t1)
-	FeSquare(&t0, &t0)
-	for i = 1; i < 1; i++ {
-		FeSquare(&t0, &t0)
-	}
-	FeMul(&t0, &t1, &t0)
-	FeSquare(&t1, &t0)
-	for i = 1; i < 5; i++ {
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t0, &t1, &t0)
-	FeSquare(&t1, &t0)
-	for i = 1; i < 10; i++ {
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t1, &t1, &t0)
-	FeSquare(&t2, &t1)
-	for i = 1; i < 20; i++ {
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t1, &t2, &t1)
-	FeSquare(&t1, &t1)
-	for i = 1; i < 10; i++ {
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t0, &t1, &t0)
-	FeSquare(&t1, &t0)
-	for i = 1; i < 50; i++ {
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t1, &t1, &t0)
-	FeSquare(&t2, &t1)
-	for i = 1; i < 100; i++ {
-		FeSquare(&t2, &t2)
-	}
-	FeMul(&t1, &t2, &t1)
-	FeSquare(&t1, &t1)
-	for i = 1; i < 50; i++ {
-		FeSquare(&t1, &t1)
-	}
-	FeMul(&t0, &t1, &t0)
-	FeSquare(&t0, &t0)
-	for i = 1; i < 2; i++ {
-		FeSquare(&t0, &t0)
-	}
-	FeMul(out, &t0, z)
-}
-
-// Group elements are members of the elliptic curve -x^2 + y^2 = 1 + d * x^2 *
-// y^2 where d = -121665/121666.
-//
-// Several representations are used:
-//   ProjectiveGroupElement: (X:Y:Z) satisfying x=X/Z, y=Y/Z
-//   ExtendedGroupElement: (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
-//   CompletedGroupElement: ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
-//   PreComputedGroupElement: (y+x,y-x,2dxy)
-
-type ProjectiveGroupElement struct {
-	X, Y, Z FieldElement
-}
-
-type ExtendedGroupElement struct {
-	X, Y, Z, T FieldElement
-}
-
-type CompletedGroupElement struct {
-	X, Y, Z, T FieldElement
-}
-
-type PreComputedGroupElement struct {
-	yPlusX, yMinusX, xy2d FieldElement
-}
-
-type CachedGroupElement struct {
-	yPlusX, yMinusX, Z, T2d FieldElement
-}
-
-func (p *ProjectiveGroupElement) Zero() {
-	FeZero(&p.X)
-	FeOne(&p.Y)
-	FeOne(&p.Z)
-}
-
-func (p *ProjectiveGroupElement) Double(r *CompletedGroupElement) {
-	var t0 FieldElement
-
-	FeSquare(&r.X, &p.X)
-	FeSquare(&r.Z, &p.Y)
-	FeSquare2(&r.T, &p.Z)
-	FeAdd(&r.Y, &p.X, &p.Y)
-	FeSquare(&t0, &r.Y)
-	FeAdd(&r.Y, &r.Z, &r.X)
-	FeSub(&r.Z, &r.Z, &r.X)
-	FeSub(&r.X, &t0, &r.Y)
-	FeSub(&r.T, &r.T, &r.Z)
-}
-
-func (p *ProjectiveGroupElement) ToBytes(s *[32]byte) {
-	var recip, x, y FieldElement
-
-	FeInvert(&recip, &p.Z)
-	FeMul(&x, &p.X, &recip)
-	FeMul(&y, &p.Y, &recip)
-	FeToBytes(s, &y)
-	s[31] ^= FeIsNegative(&x) << 7
-}
-
-func (p *ExtendedGroupElement) Zero() {
-	FeZero(&p.X)
-	FeOne(&p.Y)
-	FeOne(&p.Z)
-	FeZero(&p.T)
-}
-
-func (p *ExtendedGroupElement) Double(r *CompletedGroupElement) {
-	var q ProjectiveGroupElement
-	p.ToProjective(&q)
-	q.Double(r)
-}
-
-func (p *ExtendedGroupElement) ToCached(r *CachedGroupElement) {
-	FeAdd(&r.yPlusX, &p.Y, &p.X)
-	FeSub(&r.yMinusX, &p.Y, &p.X)
-	FeCopy(&r.Z, &p.Z)
-	FeMul(&r.T2d, &p.T, &d2)
-}
-
-func (p *ExtendedGroupElement) ToProjective(r *ProjectiveGroupElement) {
-	FeCopy(&r.X, &p.X)
-	FeCopy(&r.Y, &p.Y)
-	FeCopy(&r.Z, &p.Z)
-}
-
-func (p *ExtendedGroupElement) ToBytes(s *[32]byte) {
-	var recip, x, y FieldElement
-
-	FeInvert(&recip, &p.Z)
-	FeMul(&x, &p.X, &recip)
-	FeMul(&y, &p.Y, &recip)
-	FeToBytes(s, &y)
-	s[31] ^= FeIsNegative(&x) << 7
-}
-
-func (p *ExtendedGroupElement) FromBytes(s *[32]byte) bool {
-	var u, v, v3, vxx, check FieldElement
-
-	FeFromBytes(&p.Y, s)
-	FeOne(&p.Z)
-	FeSquare(&u, &p.Y)
-	FeMul(&v, &u, &d)
-	FeSub(&u, &u, &p.Z) // u = y^2-1
-	FeAdd(&v, &v, &p.Z) // v = dy^2+1
-
-	FeSquare(&v3, &v)
-	FeMul(&v3, &v3, &v) // v3 = v^3
-	FeSquare(&p.X, &v3)
-	FeMul(&p.X, &p.X, &v)
-	FeMul(&p.X, &p.X, &u) // x = uv^7
-
-	fePow22523(&p.X, &p.X) // x = (uv^7)^((q-5)/8)
-	FeMul(&p.X, &p.X, &v3)
-	FeMul(&p.X, &p.X, &u) // x = uv^3(uv^7)^((q-5)/8)
-
-	var tmpX, tmp2 [32]byte
-
-	FeSquare(&vxx, &p.X)
-	FeMul(&vxx, &vxx, &v)
-	FeSub(&check, &vxx, &u) // vx^2-u
-	if FeIsNonZero(&check) == 1 {
-		FeAdd(&check, &vxx, &u) // vx^2+u
-		if FeIsNonZero(&check) == 1 {
-			return false
-		}
-		FeMul(&p.X, &p.X, &SqrtM1)
-
-		FeToBytes(&tmpX, &p.X)
-		for i, v := range tmpX {
-			tmp2[31-i] = v
-		}
-	}
-
-	if FeIsNegative(&p.X) != (s[31] >> 7) {
-		FeNeg(&p.X, &p.X)
-	}
-
-	FeMul(&p.T, &p.X, &p.Y)
-	return true
-}
-
-func (p *CompletedGroupElement) ToProjective(r *ProjectiveGroupElement) {
-	FeMul(&r.X, &p.X, &p.T)
-	FeMul(&r.Y, &p.Y, &p.Z)
-	FeMul(&r.Z, &p.Z, &p.T)
-}
-
-func (p *CompletedGroupElement) ToExtended(r *ExtendedGroupElement) {
-	FeMul(&r.X, &p.X, &p.T)
-	FeMul(&r.Y, &p.Y, &p.Z)
-	FeMul(&r.Z, &p.Z, &p.T)
-	FeMul(&r.T, &p.X, &p.Y)
-}
-
-func (p *PreComputedGroupElement) Zero() {
-	FeOne(&p.yPlusX)
-	FeOne(&p.yMinusX)
-	FeZero(&p.xy2d)
-}
-
-func geAdd(r *CompletedGroupElement, p *ExtendedGroupElement, q *CachedGroupElement) {
-	var t0 FieldElement
-
-	FeAdd(&r.X, &p.Y, &p.X)
-	FeSub(&r.Y, &p.Y, &p.X)
-	FeMul(&r.Z, &r.X, &q.yPlusX)
-	FeMul(&r.Y, &r.Y, &q.yMinusX)
-	FeMul(&r.T, &q.T2d, &p.T)
-	FeMul(&r.X, &p.Z, &q.Z)
-	FeAdd(&t0, &r.X, &r.X)
-	FeSub(&r.X, &r.Z, &r.Y)
-	FeAdd(&r.Y, &r.Z, &r.Y)
-	FeAdd(&r.Z, &t0, &r.T)
-	FeSub(&r.T, &t0, &r.T)
-}
-
-func geSub(r *CompletedGroupElement, p *ExtendedGroupElement, q *CachedGroupElement) {
-	var t0 FieldElement
-
-	FeAdd(&r.X, &p.Y, &p.X)
-	FeSub(&r.Y, &p.Y, &p.X)
-	FeMul(&r.Z, &r.X, &q.yMinusX)
-	FeMul(&r.Y, &r.Y, &q.yPlusX)
-	FeMul(&r.T, &q.T2d, &p.T)
-	FeMul(&r.X, &p.Z, &q.Z)
-	FeAdd(&t0, &r.X, &r.X)
-	FeSub(&r.X, &r.Z, &r.Y)
-	FeAdd(&r.Y, &r.Z, &r.Y)
-	FeSub(&r.Z, &t0, &r.T)
-	FeAdd(&r.T, &t0, &r.T)
-}
-
-func geMixedAdd(r *CompletedGroupElement, p *ExtendedGroupElement, q *PreComputedGroupElement) {
-	var t0 FieldElement
-
-	FeAdd(&r.X, &p.Y, &p.X)
-	FeSub(&r.Y, &p.Y, &p.X)
-	FeMul(&r.Z, &r.X, &q.yPlusX)
-	FeMul(&r.Y, &r.Y, &q.yMinusX)
-	FeMul(&r.T, &q.xy2d, &p.T)
-	FeAdd(&t0, &p.Z, &p.Z)
-	FeSub(&r.X, &r.Z, &r.Y)
-	FeAdd(&r.Y, &r.Z, &r.Y)
-	FeAdd(&r.Z, &t0, &r.T)
-	FeSub(&r.T, &t0, &r.T)
-}
-
-func geMixedSub(r *CompletedGroupElement, p *ExtendedGroupElement, q *PreComputedGroupElement) {
-	var t0 FieldElement
-
-	FeAdd(&r.X, &p.Y, &p.X)
-	FeSub(&r.Y, &p.Y, &p.X)
-	FeMul(&r.Z, &r.X, &q.yMinusX)
-	FeMul(&r.Y, &r.Y, &q.yPlusX)
-	FeMul(&r.T, &q.xy2d, &p.T)
-	FeAdd(&t0, &p.Z, &p.Z)
-	FeSub(&r.X, &r.Z, &r.Y)
-	FeAdd(&r.Y, &r.Z, &r.Y)
-	FeSub(&r.Z, &t0, &r.T)
-	FeAdd(&r.T, &t0, &r.T)
-}
-
-func slide(r *[256]int8, a *[32]byte) {
-	for i := range r {
-		r[i] = int8(1 & (a[i>>3] >> uint(i&7)))
-	}
-
-	for i := range r {
-		if r[i] != 0 {
-			for b := 1; b <= 6 && i+b < 256; b++ {
-				if r[i+b] != 0 {
-					if r[i]+(r[i+b]<<uint(b)) <= 15 {
-						r[i] += r[i+b] << uint(b)
-						r[i+b] = 0
-					} else if r[i]-(r[i+b]<<uint(b)) >= -15 {
-						r[i] -= r[i+b] << uint(b)
-						for k := i + b; k < 256; k++ {
-							if r[k] == 0 {
-								r[k] = 1
-								break
-							}
-							r[k] = 0
-						}
-					} else {
-						break
-					}
-				}
-			}
+func checkInitialized(points ...*Point) {
+	for _, p := range points {
+		if p.x == (field.Element{}) && p.y == (field.Element{}) {
+			panic("edwards25519: use of uninitialized Point")
 		}
 	}
 }
 
-// GeDoubleScalarMultVartime sets r = a*A + b*B
-// where a = a[0]+256*a[1]+...+256^31 a[31].
-// and b = b[0]+256*b[1]+...+256^31 b[31].
-// B is the Ed25519 base point (x,4/5) with x positive.
-func GeDoubleScalarMultVartime(r *ProjectiveGroupElement, a *[32]byte, A *ExtendedGroupElement, b *[32]byte) {
-	var aSlide, bSlide [256]int8
-	var Ai [8]CachedGroupElement // A,3A,5A,7A,9A,11A,13A,15A
-	var t CompletedGroupElement
-	var u, A2 ExtendedGroupElement
-	var i int
-
-	slide(&aSlide, a)
-	slide(&bSlide, b)
-
-	A.ToCached(&Ai[0])
-	A.Double(&t)
-	t.ToExtended(&A2)
-
-	for i := 0; i < 7; i++ {
-		geAdd(&t, &A2, &Ai[i])
-		t.ToExtended(&u)
-		u.ToCached(&Ai[i+1])
-	}
-
-	r.Zero()
-
-	for i = 255; i >= 0; i-- {
-		if aSlide[i] != 0 || bSlide[i] != 0 {
-			break
-		}
-	}
-
-	for ; i >= 0; i-- {
-		r.Double(&t)
-
-		if aSlide[i] > 0 {
-			t.ToExtended(&u)
-			geAdd(&t, &u, &Ai[aSlide[i]/2])
-		} else if aSlide[i] < 0 {
-			t.ToExtended(&u)
-			geSub(&t, &u, &Ai[(-aSlide[i])/2])
-		}
-
-		if bSlide[i] > 0 {
-			t.ToExtended(&u)
-			geMixedAdd(&t, &u, &bi[bSlide[i]/2])
-		} else if bSlide[i] < 0 {
-			t.ToExtended(&u)
-			geMixedSub(&t, &u, &bi[(-bSlide[i])/2])
-		}
-
-		t.ToProjective(r)
-	}
+type projCached struct {
+	YplusX, YminusX, Z, T2d field.Element
 }
 
-// equal returns 1 if b == c and 0 otherwise, assuming that b and c are
-// non-negative.
-func equal(b, c int32) int32 {
-	x := uint32(b ^ c)
-	x--
-	return int32(x >> 31)
+type affineCached struct {
+	YplusX, YminusX, T2d field.Element
 }
 
-// negative returns 1 if b < 0 and 0 otherwise.
-func negative(b int32) int32 {
-	return (b >> 31) & 1
+// Constructors.
+
+func (v *projP2) Zero() *projP2 {
+	v.X.Zero()
+	v.Y.One()
+	v.Z.One()
+	return v
 }
 
-func PreComputedGroupElementCMove(t, u *PreComputedGroupElement, b int32) {
-	FeCMove(&t.yPlusX, &u.yPlusX, b)
-	FeCMove(&t.yMinusX, &u.yMinusX, b)
-	FeCMove(&t.xy2d, &u.xy2d, b)
+// identity is the point at infinity.
+var identity, _ = new(Point).SetBytes([]byte{
+	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
+
+// NewIdentityPoint returns a new Point set to the identity.
+func NewIdentityPoint() *Point {
+	return new(Point).Set(identity)
 }
 
-func selectPoint(t *PreComputedGroupElement, pos int32, b int32) {
-	var minusT PreComputedGroupElement
-	bNegative := negative(b)
-	bAbs := b - (((-bNegative) & b) << 1)
+// generator is the canonical curve basepoint. See TestGenerator for the
+// correspondence of this encoding with the values in RFC 8032.
+var generator, _ = new(Point).SetBytes([]byte{
+	0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66})
 
-	t.Zero()
-	for i := int32(0); i < 8; i++ {
-		PreComputedGroupElementCMove(t, &base[pos][i], equal(bAbs, i+1))
-	}
-	FeCopy(&minusT.yPlusX, &t.yMinusX)
-	FeCopy(&minusT.yMinusX, &t.yPlusX)
-	FeNeg(&minusT.xy2d, &t.xy2d)
-	PreComputedGroupElementCMove(t, &minusT, bNegative)
+// NewGeneratorPoint returns a new Point set to the canonical generator.
+func NewGeneratorPoint() *Point {
+	return new(Point).Set(generator)
 }
 
-// GeScalarMultBase computes h = a*B, where
-//   a = a[0]+256*a[1]+...+256^31 a[31]
-//   B is the Ed25519 base point (x,4/5) with x positive.
+func (v *projCached) Zero() *projCached {
+	v.YplusX.One()
+	v.YminusX.One()
+	v.Z.One()
+	v.T2d.Zero()
+	return v
+}
+
+func (v *affineCached) Zero() *affineCached {
+	v.YplusX.One()
+	v.YminusX.One()
+	v.T2d.Zero()
+	return v
+}
+
+// Assignments.
+
+// Set sets v = u, and returns v.
+func (v *Point) Set(u *Point) *Point {
+	*v = *u
+	return v
+}
+
+// Encoding.
+
+// Bytes returns the canonical 32-byte encoding of v, according to RFC 8032,
+// Section 5.1.2.
+func (v *Point) Bytes() []byte {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var buf [32]byte
+	return v.bytes(&buf)
+}
+
+func (v *Point) bytes(buf *[32]byte) []byte {
+	checkInitialized(v)
+
+	var zInv, x, y field.Element
+	zInv.Invert(&v.z)       // zInv = 1 / Z
+	x.Multiply(&v.x, &zInv) // x = X / Z
+	y.Multiply(&v.y, &zInv) // y = Y / Z
+
+	out := copyFieldElement(buf, &y)
+	out[31] |= byte(x.IsNegative() << 7)
+	return out
+}
+
+var feOne = new(field.Element).One()
+
+// SetBytes sets v = x, where x is a 32-byte encoding of v. If x does not
+// represent a valid point on the curve, SetBytes returns nil and an error and
+// the receiver is unchanged. Otherwise, SetBytes returns v.
 //
-// Preconditions:
-//   a[31] <= 127
-func GeScalarMultBase(h *ExtendedGroupElement, a *[32]byte) {
-	var e [64]int8
+// Note that SetBytes accepts all non-canonical encodings of valid points.
+// That is, it follows decoding rules that match most implementations in
+// the ecosystem rather than RFC 8032.
+func (v *Point) SetBytes(x []byte) (*Point, error) {
+	// Specifically, the non-canonical encodings that are accepted are
+	//   1) the ones where the field element is not reduced (see the
+	//      (*field.Element).SetBytes docs) and
+	//   2) the ones where the x-coordinate is zero and the sign bit is set.
+	//
+	// This is consistent with crypto/ed25519/internal/edwards25519. Read more
+	// at https://hdevalence.ca/blog/2020-10-04-its-25519am, specifically the
+	// "Canonical A, R" section.
 
-	for i, v := range a {
-		e[2*i] = int8(v & 15)
-		e[2*i+1] = int8((v >> 4) & 15)
+	if len(x) != 32 {
+		return nil, errors.New("edwards25519: invalid point encoding length")
+	}
+	y := new(field.Element).SetBytes(x)
+
+	// -x² + y² = 1 + dx²y²
+	// x² + dx²y² = x²(dy² + 1) = y² - 1
+	// x² = (y² - 1) / (dy² + 1)
+
+	// u = y² - 1
+	y2 := new(field.Element).Square(y)
+	u := new(field.Element).Subtract(y2, feOne)
+
+	// v = dy² + 1
+	vv := new(field.Element).Multiply(y2, d)
+	vv = vv.Add(vv, feOne)
+
+	// x = +√(u/v)
+	xx, wasSquare := new(field.Element).SqrtRatio(u, vv)
+	if wasSquare == 0 {
+		return nil, errors.New("edwards25519: invalid point encoding")
 	}
 
-	// each e[i] is between 0 and 15 and e[63] is between 0 and 7.
+	// Select the negative square root if the sign bit is set.
+	xxNeg := new(field.Element).Negate(xx)
+	xx = xx.Select(xxNeg, xx, int(x[31]>>7))
 
-	carry := int8(0)
-	for i := 0; i < 63; i++ {
-		e[i] += carry
-		carry = (e[i] + 8) >> 4
-		e[i] -= carry << 4
-	}
-	e[63] += carry
-	// each e[i] is between -8 and 8.
+	v.x.Set(xx)
+	v.y.Set(y)
+	v.z.One()
+	v.t.Multiply(xx, y) // xy = T / Z
 
-	h.Zero()
-	var t PreComputedGroupElement
-	var r CompletedGroupElement
-	for i := int32(1); i < 64; i += 2 {
-		selectPoint(&t, i/2, int32(e[i]))
-		geMixedAdd(&r, h, &t)
-		r.ToExtended(h)
-	}
-
-	var s ProjectiveGroupElement
-
-	h.Double(&r)
-	r.ToProjective(&s)
-	s.Double(&r)
-	r.ToProjective(&s)
-	s.Double(&r)
-	r.ToProjective(&s)
-	s.Double(&r)
-	r.ToExtended(h)
-
-	for i := int32(0); i < 64; i += 2 {
-		selectPoint(&t, i/2, int32(e[i]))
-		geMixedAdd(&r, h, &t)
-		r.ToExtended(h)
-	}
+	return v, nil
 }
 
-// The scalars are GF(2^252 + 27742317777372353535851937790883648493).
-
-// Input:
-//   a[0]+256*a[1]+...+256^31*a[31] = a
-//   b[0]+256*b[1]+...+256^31*b[31] = b
-//   c[0]+256*c[1]+...+256^31*c[31] = c
-//
-// Output:
-//   s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
-//   where l = 2^252 + 27742317777372353535851937790883648493.
-func ScMulAdd(s, a, b, c *[32]byte) {
-	a0 := 2097151 & load3(a[:])
-	a1 := 2097151 & (load4(a[2:]) >> 5)
-	a2 := 2097151 & (load3(a[5:]) >> 2)
-	a3 := 2097151 & (load4(a[7:]) >> 7)
-	a4 := 2097151 & (load4(a[10:]) >> 4)
-	a5 := 2097151 & (load3(a[13:]) >> 1)
-	a6 := 2097151 & (load4(a[15:]) >> 6)
-	a7 := 2097151 & (load3(a[18:]) >> 3)
-	a8 := 2097151 & load3(a[21:])
-	a9 := 2097151 & (load4(a[23:]) >> 5)
-	a10 := 2097151 & (load3(a[26:]) >> 2)
-	a11 := (load4(a[28:]) >> 7)
-	b0 := 2097151 & load3(b[:])
-	b1 := 2097151 & (load4(b[2:]) >> 5)
-	b2 := 2097151 & (load3(b[5:]) >> 2)
-	b3 := 2097151 & (load4(b[7:]) >> 7)
-	b4 := 2097151 & (load4(b[10:]) >> 4)
-	b5 := 2097151 & (load3(b[13:]) >> 1)
-	b6 := 2097151 & (load4(b[15:]) >> 6)
-	b7 := 2097151 & (load3(b[18:]) >> 3)
-	b8 := 2097151 & load3(b[21:])
-	b9 := 2097151 & (load4(b[23:]) >> 5)
-	b10 := 2097151 & (load3(b[26:]) >> 2)
-	b11 := (load4(b[28:]) >> 7)
-	c0 := 2097151 & load3(c[:])
-	c1 := 2097151 & (load4(c[2:]) >> 5)
-	c2 := 2097151 & (load3(c[5:]) >> 2)
-	c3 := 2097151 & (load4(c[7:]) >> 7)
-	c4 := 2097151 & (load4(c[10:]) >> 4)
-	c5 := 2097151 & (load3(c[13:]) >> 1)
-	c6 := 2097151 & (load4(c[15:]) >> 6)
-	c7 := 2097151 & (load3(c[18:]) >> 3)
-	c8 := 2097151 & load3(c[21:])
-	c9 := 2097151 & (load4(c[23:]) >> 5)
-	c10 := 2097151 & (load3(c[26:]) >> 2)
-	c11 := (load4(c[28:]) >> 7)
-	var carry [23]int64
-
-	s0 := c0 + a0*b0
-	s1 := c1 + a0*b1 + a1*b0
-	s2 := c2 + a0*b2 + a1*b1 + a2*b0
-	s3 := c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0
-	s4 := c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0
-	s5 := c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0
-	s6 := c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0
-	s7 := c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0
-	s8 := c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0
-	s9 := c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0
-	s10 := c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0
-	s11 := c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0
-	s12 := a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1
-	s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2
-	s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3
-	s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4
-	s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5
-	s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6
-	s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7
-	s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8
-	s20 := a9*b11 + a10*b10 + a11*b9
-	s21 := a10*b11 + a11*b10
-	s22 := a11 * b11
-	s23 := int64(0)
-
-	carry[0] = (s0 + (1 << 20)) >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[2] = (s2 + (1 << 20)) >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[4] = (s4 + (1 << 20)) >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[12] = (s12 + (1 << 20)) >> 21
-	s13 += carry[12]
-	s12 -= carry[12] << 21
-	carry[14] = (s14 + (1 << 20)) >> 21
-	s15 += carry[14]
-	s14 -= carry[14] << 21
-	carry[16] = (s16 + (1 << 20)) >> 21
-	s17 += carry[16]
-	s16 -= carry[16] << 21
-	carry[18] = (s18 + (1 << 20)) >> 21
-	s19 += carry[18]
-	s18 -= carry[18] << 21
-	carry[20] = (s20 + (1 << 20)) >> 21
-	s21 += carry[20]
-	s20 -= carry[20] << 21
-	carry[22] = (s22 + (1 << 20)) >> 21
-	s23 += carry[22]
-	s22 -= carry[22] << 21
-
-	carry[1] = (s1 + (1 << 20)) >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[3] = (s3 + (1 << 20)) >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[5] = (s5 + (1 << 20)) >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-	carry[13] = (s13 + (1 << 20)) >> 21
-	s14 += carry[13]
-	s13 -= carry[13] << 21
-	carry[15] = (s15 + (1 << 20)) >> 21
-	s16 += carry[15]
-	s15 -= carry[15] << 21
-	carry[17] = (s17 + (1 << 20)) >> 21
-	s18 += carry[17]
-	s17 -= carry[17] << 21
-	carry[19] = (s19 + (1 << 20)) >> 21
-	s20 += carry[19]
-	s19 -= carry[19] << 21
-	carry[21] = (s21 + (1 << 20)) >> 21
-	s22 += carry[21]
-	s21 -= carry[21] << 21
-
-	s11 += s23 * 666643
-	s12 += s23 * 470296
-	s13 += s23 * 654183
-	s14 -= s23 * 997805
-	s15 += s23 * 136657
-	s16 -= s23 * 683901
-	s23 = 0
-
-	s10 += s22 * 666643
-	s11 += s22 * 470296
-	s12 += s22 * 654183
-	s13 -= s22 * 997805
-	s14 += s22 * 136657
-	s15 -= s22 * 683901
-	s22 = 0
-
-	s9 += s21 * 666643
-	s10 += s21 * 470296
-	s11 += s21 * 654183
-	s12 -= s21 * 997805
-	s13 += s21 * 136657
-	s14 -= s21 * 683901
-	s21 = 0
-
-	s8 += s20 * 666643
-	s9 += s20 * 470296
-	s10 += s20 * 654183
-	s11 -= s20 * 997805
-	s12 += s20 * 136657
-	s13 -= s20 * 683901
-	s20 = 0
-
-	s7 += s19 * 666643
-	s8 += s19 * 470296
-	s9 += s19 * 654183
-	s10 -= s19 * 997805
-	s11 += s19 * 136657
-	s12 -= s19 * 683901
-	s19 = 0
-
-	s6 += s18 * 666643
-	s7 += s18 * 470296
-	s8 += s18 * 654183
-	s9 -= s18 * 997805
-	s10 += s18 * 136657
-	s11 -= s18 * 683901
-	s18 = 0
-
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[12] = (s12 + (1 << 20)) >> 21
-	s13 += carry[12]
-	s12 -= carry[12] << 21
-	carry[14] = (s14 + (1 << 20)) >> 21
-	s15 += carry[14]
-	s14 -= carry[14] << 21
-	carry[16] = (s16 + (1 << 20)) >> 21
-	s17 += carry[16]
-	s16 -= carry[16] << 21
-
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-	carry[13] = (s13 + (1 << 20)) >> 21
-	s14 += carry[13]
-	s13 -= carry[13] << 21
-	carry[15] = (s15 + (1 << 20)) >> 21
-	s16 += carry[15]
-	s15 -= carry[15] << 21
-
-	s5 += s17 * 666643
-	s6 += s17 * 470296
-	s7 += s17 * 654183
-	s8 -= s17 * 997805
-	s9 += s17 * 136657
-	s10 -= s17 * 683901
-	s17 = 0
-
-	s4 += s16 * 666643
-	s5 += s16 * 470296
-	s6 += s16 * 654183
-	s7 -= s16 * 997805
-	s8 += s16 * 136657
-	s9 -= s16 * 683901
-	s16 = 0
-
-	s3 += s15 * 666643
-	s4 += s15 * 470296
-	s5 += s15 * 654183
-	s6 -= s15 * 997805
-	s7 += s15 * 136657
-	s8 -= s15 * 683901
-	s15 = 0
-
-	s2 += s14 * 666643
-	s3 += s14 * 470296
-	s4 += s14 * 654183
-	s5 -= s14 * 997805
-	s6 += s14 * 136657
-	s7 -= s14 * 683901
-	s14 = 0
-
-	s1 += s13 * 666643
-	s2 += s13 * 470296
-	s3 += s13 * 654183
-	s4 -= s13 * 997805
-	s5 += s13 * 136657
-	s6 -= s13 * 683901
-	s13 = 0
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = (s0 + (1 << 20)) >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[2] = (s2 + (1 << 20)) >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[4] = (s4 + (1 << 20)) >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-
-	carry[1] = (s1 + (1 << 20)) >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[3] = (s3 + (1 << 20)) >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[5] = (s5 + (1 << 20)) >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = s0 >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[1] = s1 >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[2] = s2 >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[3] = s3 >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[4] = s4 >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[5] = s5 >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[6] = s6 >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[7] = s7 >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[8] = s8 >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[9] = s9 >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[10] = s10 >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[11] = s11 >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = s0 >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[1] = s1 >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[2] = s2 >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[3] = s3 >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[4] = s4 >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[5] = s5 >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[6] = s6 >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[7] = s7 >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[8] = s8 >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[9] = s9 >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[10] = s10 >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-
-	s[0] = byte(s0 >> 0)
-	s[1] = byte(s0 >> 8)
-	s[2] = byte((s0 >> 16) | (s1 << 5))
-	s[3] = byte(s1 >> 3)
-	s[4] = byte(s1 >> 11)
-	s[5] = byte((s1 >> 19) | (s2 << 2))
-	s[6] = byte(s2 >> 6)
-	s[7] = byte((s2 >> 14) | (s3 << 7))
-	s[8] = byte(s3 >> 1)
-	s[9] = byte(s3 >> 9)
-	s[10] = byte((s3 >> 17) | (s4 << 4))
-	s[11] = byte(s4 >> 4)
-	s[12] = byte(s4 >> 12)
-	s[13] = byte((s4 >> 20) | (s5 << 1))
-	s[14] = byte(s5 >> 7)
-	s[15] = byte((s5 >> 15) | (s6 << 6))
-	s[16] = byte(s6 >> 2)
-	s[17] = byte(s6 >> 10)
-	s[18] = byte((s6 >> 18) | (s7 << 3))
-	s[19] = byte(s7 >> 5)
-	s[20] = byte(s7 >> 13)
-	s[21] = byte(s8 >> 0)
-	s[22] = byte(s8 >> 8)
-	s[23] = byte((s8 >> 16) | (s9 << 5))
-	s[24] = byte(s9 >> 3)
-	s[25] = byte(s9 >> 11)
-	s[26] = byte((s9 >> 19) | (s10 << 2))
-	s[27] = byte(s10 >> 6)
-	s[28] = byte((s10 >> 14) | (s11 << 7))
-	s[29] = byte(s11 >> 1)
-	s[30] = byte(s11 >> 9)
-	s[31] = byte(s11 >> 17)
+func copyFieldElement(buf *[32]byte, v *field.Element) []byte {
+	copy(buf[:], v.Bytes())
+	return buf[:]
 }
 
-// Input:
-//   s[0]+256*s[1]+...+256^63*s[63] = s
-//
-// Output:
-//   s[0]+256*s[1]+...+256^31*s[31] = s mod l
-//   where l = 2^252 + 27742317777372353535851937790883648493.
-func ScReduce(out *[32]byte, s *[64]byte) {
-	s0 := 2097151 & load3(s[:])
-	s1 := 2097151 & (load4(s[2:]) >> 5)
-	s2 := 2097151 & (load3(s[5:]) >> 2)
-	s3 := 2097151 & (load4(s[7:]) >> 7)
-	s4 := 2097151 & (load4(s[10:]) >> 4)
-	s5 := 2097151 & (load3(s[13:]) >> 1)
-	s6 := 2097151 & (load4(s[15:]) >> 6)
-	s7 := 2097151 & (load3(s[18:]) >> 3)
-	s8 := 2097151 & load3(s[21:])
-	s9 := 2097151 & (load4(s[23:]) >> 5)
-	s10 := 2097151 & (load3(s[26:]) >> 2)
-	s11 := 2097151 & (load4(s[28:]) >> 7)
-	s12 := 2097151 & (load4(s[31:]) >> 4)
-	s13 := 2097151 & (load3(s[34:]) >> 1)
-	s14 := 2097151 & (load4(s[36:]) >> 6)
-	s15 := 2097151 & (load3(s[39:]) >> 3)
-	s16 := 2097151 & load3(s[42:])
-	s17 := 2097151 & (load4(s[44:]) >> 5)
-	s18 := 2097151 & (load3(s[47:]) >> 2)
-	s19 := 2097151 & (load4(s[49:]) >> 7)
-	s20 := 2097151 & (load4(s[52:]) >> 4)
-	s21 := 2097151 & (load3(s[55:]) >> 1)
-	s22 := 2097151 & (load4(s[57:]) >> 6)
-	s23 := (load4(s[60:]) >> 3)
+// Conversions.
 
-	s11 += s23 * 666643
-	s12 += s23 * 470296
-	s13 += s23 * 654183
-	s14 -= s23 * 997805
-	s15 += s23 * 136657
-	s16 -= s23 * 683901
-	s23 = 0
-
-	s10 += s22 * 666643
-	s11 += s22 * 470296
-	s12 += s22 * 654183
-	s13 -= s22 * 997805
-	s14 += s22 * 136657
-	s15 -= s22 * 683901
-	s22 = 0
-
-	s9 += s21 * 666643
-	s10 += s21 * 470296
-	s11 += s21 * 654183
-	s12 -= s21 * 997805
-	s13 += s21 * 136657
-	s14 -= s21 * 683901
-	s21 = 0
-
-	s8 += s20 * 666643
-	s9 += s20 * 470296
-	s10 += s20 * 654183
-	s11 -= s20 * 997805
-	s12 += s20 * 136657
-	s13 -= s20 * 683901
-	s20 = 0
-
-	s7 += s19 * 666643
-	s8 += s19 * 470296
-	s9 += s19 * 654183
-	s10 -= s19 * 997805
-	s11 += s19 * 136657
-	s12 -= s19 * 683901
-	s19 = 0
-
-	s6 += s18 * 666643
-	s7 += s18 * 470296
-	s8 += s18 * 654183
-	s9 -= s18 * 997805
-	s10 += s18 * 136657
-	s11 -= s18 * 683901
-	s18 = 0
-
-	var carry [17]int64
-
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[12] = (s12 + (1 << 20)) >> 21
-	s13 += carry[12]
-	s12 -= carry[12] << 21
-	carry[14] = (s14 + (1 << 20)) >> 21
-	s15 += carry[14]
-	s14 -= carry[14] << 21
-	carry[16] = (s16 + (1 << 20)) >> 21
-	s17 += carry[16]
-	s16 -= carry[16] << 21
-
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-	carry[13] = (s13 + (1 << 20)) >> 21
-	s14 += carry[13]
-	s13 -= carry[13] << 21
-	carry[15] = (s15 + (1 << 20)) >> 21
-	s16 += carry[15]
-	s15 -= carry[15] << 21
-
-	s5 += s17 * 666643
-	s6 += s17 * 470296
-	s7 += s17 * 654183
-	s8 -= s17 * 997805
-	s9 += s17 * 136657
-	s10 -= s17 * 683901
-	s17 = 0
-
-	s4 += s16 * 666643
-	s5 += s16 * 470296
-	s6 += s16 * 654183
-	s7 -= s16 * 997805
-	s8 += s16 * 136657
-	s9 -= s16 * 683901
-	s16 = 0
-
-	s3 += s15 * 666643
-	s4 += s15 * 470296
-	s5 += s15 * 654183
-	s6 -= s15 * 997805
-	s7 += s15 * 136657
-	s8 -= s15 * 683901
-	s15 = 0
-
-	s2 += s14 * 666643
-	s3 += s14 * 470296
-	s4 += s14 * 654183
-	s5 -= s14 * 997805
-	s6 += s14 * 136657
-	s7 -= s14 * 683901
-	s14 = 0
-
-	s1 += s13 * 666643
-	s2 += s13 * 470296
-	s3 += s13 * 654183
-	s4 -= s13 * 997805
-	s5 += s13 * 136657
-	s6 -= s13 * 683901
-	s13 = 0
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = (s0 + (1 << 20)) >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[2] = (s2 + (1 << 20)) >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[4] = (s4 + (1 << 20)) >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-
-	carry[1] = (s1 + (1 << 20)) >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[3] = (s3 + (1 << 20)) >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[5] = (s5 + (1 << 20)) >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = s0 >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[1] = s1 >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[2] = s2 >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[3] = s3 >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[4] = s4 >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[5] = s5 >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[6] = s6 >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[7] = s7 >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[8] = s8 >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[9] = s9 >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[10] = s10 >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[11] = s11 >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = s0 >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[1] = s1 >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[2] = s2 >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[3] = s3 >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[4] = s4 >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[5] = s5 >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[6] = s6 >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[7] = s7 >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[8] = s8 >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[9] = s9 >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[10] = s10 >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-
-	out[0] = byte(s0 >> 0)
-	out[1] = byte(s0 >> 8)
-	out[2] = byte((s0 >> 16) | (s1 << 5))
-	out[3] = byte(s1 >> 3)
-	out[4] = byte(s1 >> 11)
-	out[5] = byte((s1 >> 19) | (s2 << 2))
-	out[6] = byte(s2 >> 6)
-	out[7] = byte((s2 >> 14) | (s3 << 7))
-	out[8] = byte(s3 >> 1)
-	out[9] = byte(s3 >> 9)
-	out[10] = byte((s3 >> 17) | (s4 << 4))
-	out[11] = byte(s4 >> 4)
-	out[12] = byte(s4 >> 12)
-	out[13] = byte((s4 >> 20) | (s5 << 1))
-	out[14] = byte(s5 >> 7)
-	out[15] = byte((s5 >> 15) | (s6 << 6))
-	out[16] = byte(s6 >> 2)
-	out[17] = byte(s6 >> 10)
-	out[18] = byte((s6 >> 18) | (s7 << 3))
-	out[19] = byte(s7 >> 5)
-	out[20] = byte(s7 >> 13)
-	out[21] = byte(s8 >> 0)
-	out[22] = byte(s8 >> 8)
-	out[23] = byte((s8 >> 16) | (s9 << 5))
-	out[24] = byte(s9 >> 3)
-	out[25] = byte(s9 >> 11)
-	out[26] = byte((s9 >> 19) | (s10 << 2))
-	out[27] = byte(s10 >> 6)
-	out[28] = byte((s10 >> 14) | (s11 << 7))
-	out[29] = byte(s11 >> 1)
-	out[30] = byte(s11 >> 9)
-	out[31] = byte(s11 >> 17)
+func (v *projP2) FromP1xP1(p *projP1xP1) *projP2 {
+	v.X.Multiply(&p.X, &p.T)
+	v.Y.Multiply(&p.Y, &p.Z)
+	v.Z.Multiply(&p.Z, &p.T)
+	return v
 }
 
-// order is the order of Curve25519 in little-endian form.
-var order = [4]uint64{0x5812631a5cf5d3ed, 0x14def9dea2f79cd6, 0, 0x1000000000000000}
+func (v *projP2) FromP3(p *Point) *projP2 {
+	v.X.Set(&p.x)
+	v.Y.Set(&p.y)
+	v.Z.Set(&p.z)
+	return v
+}
 
-// ScMinimal returns true if the given scalar is less than the order of the
-// curve.
-func ScMinimal(scalar *[32]byte) bool {
-	for i := 3; ; i-- {
-		v := binary.LittleEndian.Uint64(scalar[i*8:])
-		if v > order[i] {
-			return false
-		} else if v < order[i] {
-			break
-		} else if i == 0 {
-			return false
-		}
-	}
+func (v *Point) fromP1xP1(p *projP1xP1) *Point {
+	v.x.Multiply(&p.X, &p.T)
+	v.y.Multiply(&p.Y, &p.Z)
+	v.z.Multiply(&p.Z, &p.T)
+	v.t.Multiply(&p.X, &p.Y)
+	return v
+}
 
-	return true
+func (v *Point) fromP2(p *projP2) *Point {
+	v.x.Multiply(&p.X, &p.Z)
+	v.y.Multiply(&p.Y, &p.Z)
+	v.z.Square(&p.Z)
+	v.t.Multiply(&p.X, &p.Y)
+	return v
+}
+
+// d is a constant in the curve equation.
+var d = new(field.Element).SetBytes([]byte{
+	0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
+	0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
+	0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
+	0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52})
+var d2 = new(field.Element).Add(d, d)
+
+func (v *projCached) FromP3(p *Point) *projCached {
+	v.YplusX.Add(&p.y, &p.x)
+	v.YminusX.Subtract(&p.y, &p.x)
+	v.Z.Set(&p.z)
+	v.T2d.Multiply(&p.t, d2)
+	return v
+}
+
+func (v *affineCached) FromP3(p *Point) *affineCached {
+	v.YplusX.Add(&p.y, &p.x)
+	v.YminusX.Subtract(&p.y, &p.x)
+	v.T2d.Multiply(&p.t, d2)
+
+	var invZ field.Element
+	invZ.Invert(&p.z)
+	v.YplusX.Multiply(&v.YplusX, &invZ)
+	v.YminusX.Multiply(&v.YminusX, &invZ)
+	v.T2d.Multiply(&v.T2d, &invZ)
+	return v
+}
+
+// (Re)addition and subtraction.
+
+// Add sets v = p + q, and returns v.
+func (v *Point) Add(p, q *Point) *Point {
+	checkInitialized(p, q)
+	qCached := new(projCached).FromP3(q)
+	result := new(projP1xP1).Add(p, qCached)
+	return v.fromP1xP1(result)
+}
+
+// Subtract sets v = p - q, and returns v.
+func (v *Point) Subtract(p, q *Point) *Point {
+	checkInitialized(p, q)
+	qCached := new(projCached).FromP3(q)
+	result := new(projP1xP1).Sub(p, qCached)
+	return v.fromP1xP1(result)
+}
+
+func (v *projP1xP1) Add(p *Point, q *projCached) *projP1xP1 {
+	var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element
+
+	YplusX.Add(&p.y, &p.x)
+	YminusX.Subtract(&p.y, &p.x)
+
+	PP.Multiply(&YplusX, &q.YplusX)
+	MM.Multiply(&YminusX, &q.YminusX)
+	TT2d.Multiply(&p.t, &q.T2d)
+	ZZ2.Multiply(&p.z, &q.Z)
+
+	ZZ2.Add(&ZZ2, &ZZ2)
+
+	v.X.Subtract(&PP, &MM)
+	v.Y.Add(&PP, &MM)
+	v.Z.Add(&ZZ2, &TT2d)
+	v.T.Subtract(&ZZ2, &TT2d)
+	return v
+}
+
+func (v *projP1xP1) Sub(p *Point, q *projCached) *projP1xP1 {
+	var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element
+
+	YplusX.Add(&p.y, &p.x)
+	YminusX.Subtract(&p.y, &p.x)
+
+	PP.Multiply(&YplusX, &q.YminusX) // flipped sign
+	MM.Multiply(&YminusX, &q.YplusX) // flipped sign
+	TT2d.Multiply(&p.t, &q.T2d)
+	ZZ2.Multiply(&p.z, &q.Z)
+
+	ZZ2.Add(&ZZ2, &ZZ2)
+
+	v.X.Subtract(&PP, &MM)
+	v.Y.Add(&PP, &MM)
+	v.Z.Subtract(&ZZ2, &TT2d) // flipped sign
+	v.T.Add(&ZZ2, &TT2d)      // flipped sign
+	return v
+}
+
+func (v *projP1xP1) AddAffine(p *Point, q *affineCached) *projP1xP1 {
+	var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element
+
+	YplusX.Add(&p.y, &p.x)
+	YminusX.Subtract(&p.y, &p.x)
+
+	PP.Multiply(&YplusX, &q.YplusX)
+	MM.Multiply(&YminusX, &q.YminusX)
+	TT2d.Multiply(&p.t, &q.T2d)
+
+	Z2.Add(&p.z, &p.z)
+
+	v.X.Subtract(&PP, &MM)
+	v.Y.Add(&PP, &MM)
+	v.Z.Add(&Z2, &TT2d)
+	v.T.Subtract(&Z2, &TT2d)
+	return v
+}
+
+func (v *projP1xP1) SubAffine(p *Point, q *affineCached) *projP1xP1 {
+	var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element
+
+	YplusX.Add(&p.y, &p.x)
+	YminusX.Subtract(&p.y, &p.x)
+
+	PP.Multiply(&YplusX, &q.YminusX) // flipped sign
+	MM.Multiply(&YminusX, &q.YplusX) // flipped sign
+	TT2d.Multiply(&p.t, &q.T2d)
+
+	Z2.Add(&p.z, &p.z)
+
+	v.X.Subtract(&PP, &MM)
+	v.Y.Add(&PP, &MM)
+	v.Z.Subtract(&Z2, &TT2d) // flipped sign
+	v.T.Add(&Z2, &TT2d)      // flipped sign
+	return v
+}
+
+// Doubling.
+
+func (v *projP1xP1) Double(p *projP2) *projP1xP1 {
+	var XX, YY, ZZ2, XplusYsq field.Element
+
+	XX.Square(&p.X)
+	YY.Square(&p.Y)
+	ZZ2.Square(&p.Z)
+	ZZ2.Add(&ZZ2, &ZZ2)
+	XplusYsq.Add(&p.X, &p.Y)
+	XplusYsq.Square(&XplusYsq)
+
+	v.Y.Add(&YY, &XX)
+	v.Z.Subtract(&YY, &XX)
+
+	v.X.Subtract(&XplusYsq, &v.Y)
+	v.T.Subtract(&ZZ2, &v.Z)
+	return v
+}
+
+// Negation.
+
+// Negate sets v = -p, and returns v.
+func (v *Point) Negate(p *Point) *Point {
+	checkInitialized(p)
+	v.x.Negate(&p.x)
+	v.y.Set(&p.y)
+	v.z.Set(&p.z)
+	v.t.Negate(&p.t)
+	return v
+}
+
+// Equal returns 1 if v is equivalent to u, and 0 otherwise.
+func (v *Point) Equal(u *Point) int {
+	checkInitialized(v, u)
+
+	var t1, t2, t3, t4 field.Element
+	t1.Multiply(&v.x, &u.z)
+	t2.Multiply(&u.x, &v.z)
+	t3.Multiply(&v.y, &u.z)
+	t4.Multiply(&u.y, &v.z)
+
+	return t1.Equal(&t2) & t3.Equal(&t4)
+}
+
+// Constant-time operations
+
+// Select sets v to a if cond == 1 and to b if cond == 0.
+func (v *projCached) Select(a, b *projCached, cond int) *projCached {
+	v.YplusX.Select(&a.YplusX, &b.YplusX, cond)
+	v.YminusX.Select(&a.YminusX, &b.YminusX, cond)
+	v.Z.Select(&a.Z, &b.Z, cond)
+	v.T2d.Select(&a.T2d, &b.T2d, cond)
+	return v
+}
+
+// Select sets v to a if cond == 1 and to b if cond == 0.
+func (v *affineCached) Select(a, b *affineCached, cond int) *affineCached {
+	v.YplusX.Select(&a.YplusX, &b.YplusX, cond)
+	v.YminusX.Select(&a.YminusX, &b.YminusX, cond)
+	v.T2d.Select(&a.T2d, &b.T2d, cond)
+	return v
+}
+
+// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0.
+func (v *projCached) CondNeg(cond int) *projCached {
+	v.YplusX.Swap(&v.YminusX, cond)
+	v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond)
+	return v
+}
+
+// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0.
+func (v *affineCached) CondNeg(cond int) *affineCached {
+	v.YplusX.Swap(&v.YminusX, cond)
+	v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond)
+	return v
 }
diff --git a/src/crypto/ed25519/internal/edwards25519/edwards25519_test.go b/src/crypto/ed25519/internal/edwards25519/edwards25519_test.go
new file mode 100644
index 0000000..8031256
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/edwards25519_test.go
@@ -0,0 +1,304 @@
+// Copyright (c) 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package edwards25519
+
+import (
+	"crypto/ed25519/internal/edwards25519/field"
+	"encoding/hex"
+	"os"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+var B = NewGeneratorPoint()
+var I = NewIdentityPoint()
+
+func checkOnCurve(t *testing.T, points ...*Point) {
+	t.Helper()
+	for i, p := range points {
+		var XX, YY, ZZ, ZZZZ field.Element
+		XX.Square(&p.x)
+		YY.Square(&p.y)
+		ZZ.Square(&p.z)
+		ZZZZ.Square(&ZZ)
+		// -x² + y² = 1 + dx²y²
+		// -(X/Z)² + (Y/Z)² = 1 + d(X/Z)²(Y/Z)²
+		// (-X² + Y²)/Z² = 1 + (dX²Y²)/Z⁴
+		// (-X² + Y²)*Z² = Z⁴ + dX²Y²
+		var lhs, rhs field.Element
+		lhs.Subtract(&YY, &XX).Multiply(&lhs, &ZZ)
+		rhs.Multiply(d, &XX).Multiply(&rhs, &YY).Add(&rhs, &ZZZZ)
+		if lhs.Equal(&rhs) != 1 {
+			t.Errorf("X, Y, and Z do not specify a point on the curve\nX = %v\nY = %v\nZ = %v", p.x, p.y, p.z)
+		}
+		// xy = T/Z
+		lhs.Multiply(&p.x, &p.y)
+		rhs.Multiply(&p.z, &p.t)
+		if lhs.Equal(&rhs) != 1 {
+			t.Errorf("point %d is not valid\nX = %v\nY = %v\nZ = %v", i, p.x, p.y, p.z)
+		}
+	}
+}
+
+func TestGenerator(t *testing.T) {
+	// These are the coordinates of B from RFC 8032, Section 5.1, converted to
+	// little endian hex.
+	x := "1ad5258f602d56c9b2a7259560c72c695cdcd6fd31e2a4c0fe536ecdd3366921"
+	y := "5866666666666666666666666666666666666666666666666666666666666666"
+	if got := hex.EncodeToString(B.x.Bytes()); got != x {
+		t.Errorf("wrong B.x: got %s, expected %s", got, x)
+	}
+	if got := hex.EncodeToString(B.y.Bytes()); got != y {
+		t.Errorf("wrong B.y: got %s, expected %s", got, y)
+	}
+	if B.z.Equal(feOne) != 1 {
+		t.Errorf("wrong B.z: got %v, expected 1", B.z)
+	}
+	// Check that t is correct.
+	checkOnCurve(t, B)
+}
+
+func TestAddSubNegOnBasePoint(t *testing.T) {
+	checkLhs, checkRhs := &Point{}, &Point{}
+
+	checkLhs.Add(B, B)
+	tmpP2 := new(projP2).FromP3(B)
+	tmpP1xP1 := new(projP1xP1).Double(tmpP2)
+	checkRhs.fromP1xP1(tmpP1xP1)
+	if checkLhs.Equal(checkRhs) != 1 {
+		t.Error("B + B != [2]B")
+	}
+	checkOnCurve(t, checkLhs, checkRhs)
+
+	checkLhs.Subtract(B, B)
+	Bneg := new(Point).Negate(B)
+	checkRhs.Add(B, Bneg)
+	if checkLhs.Equal(checkRhs) != 1 {
+		t.Error("B - B != B + (-B)")
+	}
+	if I.Equal(checkLhs) != 1 {
+		t.Error("B - B != 0")
+	}
+	if I.Equal(checkRhs) != 1 {
+		t.Error("B + (-B) != 0")
+	}
+	checkOnCurve(t, checkLhs, checkRhs, Bneg)
+}
+
+func TestComparable(t *testing.T) {
+	if reflect.TypeOf(Point{}).Comparable() {
+		t.Error("Point is unexpectedly comparable")
+	}
+}
+
+func TestInvalidEncodings(t *testing.T) {
+	// An invalid point, that also happens to have y > p.
+	invalid := "efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f"
+	p := NewGeneratorPoint()
+	if out, err := p.SetBytes(decodeHex(invalid)); err == nil {
+		t.Error("expected error for invalid point")
+	} else if out != nil {
+		t.Error("SetBytes did not return nil on an invalid encoding")
+	} else if p.Equal(B) != 1 {
+		t.Error("the Point was modified while decoding an invalid encoding")
+	}
+	checkOnCurve(t, p)
+}
+
+func TestNonCanonicalPoints(t *testing.T) {
+	type test struct {
+		name                string
+		encoding, canonical string
+	}
+	tests := []test{
+		// Points with x = 0 and the sign bit set. With x = 0 the curve equation
+		// gives y² = 1, so y = ±1. 1 has two valid encodings.
+		{
+			"y=1,sign-",
+			"0100000000000000000000000000000000000000000000000000000000000080",
+			"0100000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p+1,sign-",
+			"eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"0100000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p-1,sign-",
+			"ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+		},
+
+		// Non-canonical y encodings with values 2²⁵⁵-19 (p) to 2²⁵⁵-1 (p+18).
+		{
+			"y=p,sign+",
+			"edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+			"0000000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p,sign-",
+			"edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"0000000000000000000000000000000000000000000000000000000000000080",
+		},
+		{
+			"y=p+1,sign+",
+			"eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+			"0100000000000000000000000000000000000000000000000000000000000000",
+		},
+		// "y=p+1,sign-" is already tested above.
+		// p+2 is not a valid y-coordinate.
+		{
+			"y=p+3,sign+",
+			"f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+			"0300000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p+3,sign-",
+			"f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"0300000000000000000000000000000000000000000000000000000000000080",
+		},
+		{
+			"y=p+4,sign+",
+			"f1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+			"0400000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p+4,sign-",
+			"f1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"0400000000000000000000000000000000000000000000000000000000000080",
+		},
+		{
+			"y=p+5,sign+",
+			"f2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+			"0500000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p+5,sign-",
+			"f2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"0500000000000000000000000000000000000000000000000000000000000080",
+		},
+		{
+			"y=p+6,sign+",
+			"f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+			"0600000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p+6,sign-",
+			"f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"0600000000000000000000000000000000000000000000000000000000000080",
+		},
+		// p+7 is not a valid y-coordinate.
+		// p+8 is not a valid y-coordinate.
+		{
+			"y=p+9,sign+",
+			"f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+			"0900000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p+9,sign-",
+			"f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"0900000000000000000000000000000000000000000000000000000000000080",
+		},
+		{
+			"y=p+10,sign+",
+			"f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+			"0a00000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p+10,sign-",
+			"f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"0a00000000000000000000000000000000000000000000000000000000000080",
+		},
+		// p+11 is not a valid y-coordinate.
+		// p+12 is not a valid y-coordinate.
+		// p+13 is not a valid y-coordinate.
+		{
+			"y=p+14,sign+",
+			"fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+			"0e00000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p+14,sign-",
+			"fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"0e00000000000000000000000000000000000000000000000000000000000080",
+		},
+		{
+			"y=p+15,sign+",
+			"fcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+			"0f00000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p+15,sign-",
+			"fcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"0f00000000000000000000000000000000000000000000000000000000000080",
+		},
+		{
+			"y=p+16,sign+",
+			"fdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+			"1000000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p+16,sign-",
+			"fdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"1000000000000000000000000000000000000000000000000000000000000080",
+		},
+		// p+17 is not a valid y-coordinate.
+		{
+			"y=p+18,sign+",
+			"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+			"1200000000000000000000000000000000000000000000000000000000000000",
+		},
+		{
+			"y=p+18,sign-",
+			"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+			"1200000000000000000000000000000000000000000000000000000000000080",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			p1, err := new(Point).SetBytes(decodeHex(tt.encoding))
+			if err != nil {
+				t.Fatalf("error decoding non-canonical point: %v", err)
+			}
+			p2, err := new(Point).SetBytes(decodeHex(tt.canonical))
+			if err != nil {
+				t.Fatalf("error decoding canonical point: %v", err)
+			}
+			if p1.Equal(p2) != 1 {
+				t.Errorf("equivalent points are not equal: %v, %v", p1, p2)
+			}
+			if encoding := hex.EncodeToString(p1.Bytes()); encoding != tt.canonical {
+				t.Errorf("re-encoding does not match canonical; got %q, expected %q", encoding, tt.canonical)
+			}
+			checkOnCurve(t, p1, p2)
+		})
+	}
+}
+
+var testAllocationsSink byte
+
+func TestAllocations(t *testing.T) {
+	if strings.HasSuffix(os.Getenv("GO_BUILDER_NAME"), "-noopt") {
+		t.Skip("skipping allocations test without relevant optimizations")
+	}
+	if allocs := testing.AllocsPerRun(100, func() {
+		p := NewIdentityPoint()
+		p.Add(p, NewGeneratorPoint())
+		s := NewScalar()
+		testAllocationsSink ^= s.Bytes()[0]
+		testAllocationsSink ^= p.Bytes()[0]
+	}); allocs > 0 {
+		t.Errorf("expected zero allocations, got %0.1v", allocs)
+	}
+}
+
+func decodeHex(s string) []byte {
+	b, err := hex.DecodeString(s)
+	if err != nil {
+		panic(err)
+	}
+	return b
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/field/_asm/fe_amd64_asm.go b/src/crypto/ed25519/internal/edwards25519/field/_asm/fe_amd64_asm.go
new file mode 100644
index 0000000..fbc0cce
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/_asm/fe_amd64_asm.go
@@ -0,0 +1,294 @@
+// Copyright (c) 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+
+	. "github.com/mmcloughlin/avo/build"
+	. "github.com/mmcloughlin/avo/gotypes"
+	. "github.com/mmcloughlin/avo/operand"
+	. "github.com/mmcloughlin/avo/reg"
+)
+
+//go:generate go run . -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field
+
+func main() {
+	Package("crypto/ed25519/internal/edwards25519/field")
+	ConstraintExpr("amd64,gc,!purego")
+	feMul()
+	feSquare()
+	Generate()
+}
+
+type namedComponent struct {
+	Component
+	name string
+}
+
+func (c namedComponent) String() string { return c.name }
+
+type uint128 struct {
+	name   string
+	hi, lo GPVirtual
+}
+
+func (c uint128) String() string { return c.name }
+
+func feSquare() {
+	TEXT("feSquare", NOSPLIT, "func(out, a *Element)")
+	Doc("feSquare sets out = a * a. It works like feSquareGeneric.")
+	Pragma("noescape")
+
+	a := Dereference(Param("a"))
+	l0 := namedComponent{a.Field("l0"), "l0"}
+	l1 := namedComponent{a.Field("l1"), "l1"}
+	l2 := namedComponent{a.Field("l2"), "l2"}
+	l3 := namedComponent{a.Field("l3"), "l3"}
+	l4 := namedComponent{a.Field("l4"), "l4"}
+
+	// r0 = l0×l0 + 19×2×(l1×l4 + l2×l3)
+	r0 := uint128{"r0", GP64(), GP64()}
+	mul64(r0, 1, l0, l0)
+	addMul64(r0, 38, l1, l4)
+	addMul64(r0, 38, l2, l3)
+
+	// r1 = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
+	r1 := uint128{"r1", GP64(), GP64()}
+	mul64(r1, 2, l0, l1)
+	addMul64(r1, 38, l2, l4)
+	addMul64(r1, 19, l3, l3)
+
+	// r2 = = 2×l0×l2 + l1×l1 + 19×2×l3×l4
+	r2 := uint128{"r2", GP64(), GP64()}
+	mul64(r2, 2, l0, l2)
+	addMul64(r2, 1, l1, l1)
+	addMul64(r2, 38, l3, l4)
+
+	// r3 = = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
+	r3 := uint128{"r3", GP64(), GP64()}
+	mul64(r3, 2, l0, l3)
+	addMul64(r3, 2, l1, l2)
+	addMul64(r3, 19, l4, l4)
+
+	// r4 = = 2×l0×l4 + 2×l1×l3 + l2×l2
+	r4 := uint128{"r4", GP64(), GP64()}
+	mul64(r4, 2, l0, l4)
+	addMul64(r4, 2, l1, l3)
+	addMul64(r4, 1, l2, l2)
+
+	Comment("First reduction chain")
+	maskLow51Bits := GP64()
+	MOVQ(Imm((1<<51)-1), maskLow51Bits)
+	c0, r0lo := shiftRightBy51(&r0)
+	c1, r1lo := shiftRightBy51(&r1)
+	c2, r2lo := shiftRightBy51(&r2)
+	c3, r3lo := shiftRightBy51(&r3)
+	c4, r4lo := shiftRightBy51(&r4)
+	maskAndAdd(r0lo, maskLow51Bits, c4, 19)
+	maskAndAdd(r1lo, maskLow51Bits, c0, 1)
+	maskAndAdd(r2lo, maskLow51Bits, c1, 1)
+	maskAndAdd(r3lo, maskLow51Bits, c2, 1)
+	maskAndAdd(r4lo, maskLow51Bits, c3, 1)
+
+	Comment("Second reduction chain (carryPropagate)")
+	// c0 = r0 >> 51
+	MOVQ(r0lo, c0)
+	SHRQ(Imm(51), c0)
+	// c1 = r1 >> 51
+	MOVQ(r1lo, c1)
+	SHRQ(Imm(51), c1)
+	// c2 = r2 >> 51
+	MOVQ(r2lo, c2)
+	SHRQ(Imm(51), c2)
+	// c3 = r3 >> 51
+	MOVQ(r3lo, c3)
+	SHRQ(Imm(51), c3)
+	// c4 = r4 >> 51
+	MOVQ(r4lo, c4)
+	SHRQ(Imm(51), c4)
+	maskAndAdd(r0lo, maskLow51Bits, c4, 19)
+	maskAndAdd(r1lo, maskLow51Bits, c0, 1)
+	maskAndAdd(r2lo, maskLow51Bits, c1, 1)
+	maskAndAdd(r3lo, maskLow51Bits, c2, 1)
+	maskAndAdd(r4lo, maskLow51Bits, c3, 1)
+
+	Comment("Store output")
+	out := Dereference(Param("out"))
+	Store(r0lo, out.Field("l0"))
+	Store(r1lo, out.Field("l1"))
+	Store(r2lo, out.Field("l2"))
+	Store(r3lo, out.Field("l3"))
+	Store(r4lo, out.Field("l4"))
+
+	RET()
+}
+
+func feMul() {
+	TEXT("feMul", NOSPLIT, "func(out, a, b *Element)")
+	Doc("feMul sets out = a * b. It works like feMulGeneric.")
+	Pragma("noescape")
+
+	a := Dereference(Param("a"))
+	a0 := namedComponent{a.Field("l0"), "a0"}
+	a1 := namedComponent{a.Field("l1"), "a1"}
+	a2 := namedComponent{a.Field("l2"), "a2"}
+	a3 := namedComponent{a.Field("l3"), "a3"}
+	a4 := namedComponent{a.Field("l4"), "a4"}
+
+	b := Dereference(Param("b"))
+	b0 := namedComponent{b.Field("l0"), "b0"}
+	b1 := namedComponent{b.Field("l1"), "b1"}
+	b2 := namedComponent{b.Field("l2"), "b2"}
+	b3 := namedComponent{b.Field("l3"), "b3"}
+	b4 := namedComponent{b.Field("l4"), "b4"}
+
+	// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
+	r0 := uint128{"r0", GP64(), GP64()}
+	mul64(r0, 1, a0, b0)
+	addMul64(r0, 19, a1, b4)
+	addMul64(r0, 19, a2, b3)
+	addMul64(r0, 19, a3, b2)
+	addMul64(r0, 19, a4, b1)
+
+	// r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
+	r1 := uint128{"r1", GP64(), GP64()}
+	mul64(r1, 1, a0, b1)
+	addMul64(r1, 1, a1, b0)
+	addMul64(r1, 19, a2, b4)
+	addMul64(r1, 19, a3, b3)
+	addMul64(r1, 19, a4, b2)
+
+	// r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
+	r2 := uint128{"r2", GP64(), GP64()}
+	mul64(r2, 1, a0, b2)
+	addMul64(r2, 1, a1, b1)
+	addMul64(r2, 1, a2, b0)
+	addMul64(r2, 19, a3, b4)
+	addMul64(r2, 19, a4, b3)
+
+	// r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
+	r3 := uint128{"r3", GP64(), GP64()}
+	mul64(r3, 1, a0, b3)
+	addMul64(r3, 1, a1, b2)
+	addMul64(r3, 1, a2, b1)
+	addMul64(r3, 1, a3, b0)
+	addMul64(r3, 19, a4, b4)
+
+	// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
+	r4 := uint128{"r4", GP64(), GP64()}
+	mul64(r4, 1, a0, b4)
+	addMul64(r4, 1, a1, b3)
+	addMul64(r4, 1, a2, b2)
+	addMul64(r4, 1, a3, b1)
+	addMul64(r4, 1, a4, b0)
+
+	Comment("First reduction chain")
+	maskLow51Bits := GP64()
+	MOVQ(Imm((1<<51)-1), maskLow51Bits)
+	c0, r0lo := shiftRightBy51(&r0)
+	c1, r1lo := shiftRightBy51(&r1)
+	c2, r2lo := shiftRightBy51(&r2)
+	c3, r3lo := shiftRightBy51(&r3)
+	c4, r4lo := shiftRightBy51(&r4)
+	maskAndAdd(r0lo, maskLow51Bits, c4, 19)
+	maskAndAdd(r1lo, maskLow51Bits, c0, 1)
+	maskAndAdd(r2lo, maskLow51Bits, c1, 1)
+	maskAndAdd(r3lo, maskLow51Bits, c2, 1)
+	maskAndAdd(r4lo, maskLow51Bits, c3, 1)
+
+	Comment("Second reduction chain (carryPropagate)")
+	// c0 = r0 >> 51
+	MOVQ(r0lo, c0)
+	SHRQ(Imm(51), c0)
+	// c1 = r1 >> 51
+	MOVQ(r1lo, c1)
+	SHRQ(Imm(51), c1)
+	// c2 = r2 >> 51
+	MOVQ(r2lo, c2)
+	SHRQ(Imm(51), c2)
+	// c3 = r3 >> 51
+	MOVQ(r3lo, c3)
+	SHRQ(Imm(51), c3)
+	// c4 = r4 >> 51
+	MOVQ(r4lo, c4)
+	SHRQ(Imm(51), c4)
+	maskAndAdd(r0lo, maskLow51Bits, c4, 19)
+	maskAndAdd(r1lo, maskLow51Bits, c0, 1)
+	maskAndAdd(r2lo, maskLow51Bits, c1, 1)
+	maskAndAdd(r3lo, maskLow51Bits, c2, 1)
+	maskAndAdd(r4lo, maskLow51Bits, c3, 1)
+
+	Comment("Store output")
+	out := Dereference(Param("out"))
+	Store(r0lo, out.Field("l0"))
+	Store(r1lo, out.Field("l1"))
+	Store(r2lo, out.Field("l2"))
+	Store(r3lo, out.Field("l3"))
+	Store(r4lo, out.Field("l4"))
+
+	RET()
+}
+
+// mul64 sets r to i * aX * bX.
+func mul64(r uint128, i int, aX, bX namedComponent) {
+	switch i {
+	case 1:
+		Comment(fmt.Sprintf("%s = %s×%s", r, aX, bX))
+		Load(aX, RAX)
+	case 2:
+		Comment(fmt.Sprintf("%s = 2×%s×%s", r, aX, bX))
+		Load(aX, RAX)
+		SHLQ(Imm(1), RAX)
+	default:
+		panic("unsupported i value")
+	}
+	MULQ(mustAddr(bX)) // RDX, RAX = RAX * bX
+	MOVQ(RAX, r.lo)
+	MOVQ(RDX, r.hi)
+}
+
+// addMul64 sets r to r + i * aX * bX.
+func addMul64(r uint128, i uint64, aX, bX namedComponent) {
+	switch i {
+	case 1:
+		Comment(fmt.Sprintf("%s += %s×%s", r, aX, bX))
+		Load(aX, RAX)
+	default:
+		Comment(fmt.Sprintf("%s += %d×%s×%s", r, i, aX, bX))
+		IMUL3Q(Imm(i), Load(aX, GP64()), RAX)
+	}
+	MULQ(mustAddr(bX)) // RDX, RAX = RAX * bX
+	ADDQ(RAX, r.lo)
+	ADCQ(RDX, r.hi)
+}
+
+// shiftRightBy51 returns r >> 51 and r.lo.
+//
+// After this function is called, the uint128 may not be used anymore.
+func shiftRightBy51(r *uint128) (out, lo GPVirtual) {
+	out = r.hi
+	lo = r.lo
+	SHLQ(Imm(64-51), r.lo, r.hi)
+	r.lo, r.hi = nil, nil // make sure the uint128 is unusable
+	return
+}
+
+// maskAndAdd sets r = r&mask + c*i.
+func maskAndAdd(r, mask, c GPVirtual, i uint64) {
+	ANDQ(mask, r)
+	if i != 1 {
+		IMUL3Q(Imm(i), c, c)
+	}
+	ADDQ(c, r)
+}
+
+func mustAddr(c Component) Op {
+	b, err := c.Resolve()
+	if err != nil {
+		panic(err)
+	}
+	return b.Addr
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/field/_asm/go.mod b/src/crypto/ed25519/internal/edwards25519/field/_asm/go.mod
new file mode 100644
index 0000000..1127ade
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/_asm/go.mod
@@ -0,0 +1,5 @@
+module asm
+
+go 1.16
+
+require github.com/mmcloughlin/avo v0.2.0
diff --git a/src/crypto/ed25519/internal/edwards25519/field/_asm/go.sum b/src/crypto/ed25519/internal/edwards25519/field/_asm/go.sum
new file mode 100644
index 0000000..dae4777
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/_asm/go.sum
@@ -0,0 +1,31 @@
+github.com/mmcloughlin/avo v0.2.0 h1:6vhoSaKtxb6f4RiH+LK2qL6GSMpFzhEwJYTTSZNy09w=
+github.com/mmcloughlin/avo v0.2.0/go.mod h1:5tidO2Z9Z7N6X7UMcGg+1KTj51O8OxYDCMHxCZTVpEA=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+golang.org/x/arch v0.0.0-20210405154355-08b684f594a5/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
+golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe.go b/src/crypto/ed25519/internal/edwards25519/field/fe.go
new file mode 100644
index 0000000..dbe8659
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/fe.go
@@ -0,0 +1,416 @@
+// Copyright (c) 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package field implements fast arithmetic modulo 2^255-19.
+package field
+
+import (
+	"crypto/subtle"
+	"encoding/binary"
+	"math/bits"
+)
+
+// Element represents an element of the field GF(2^255-19). Note that this
+// is not a cryptographically secure group, and should only be used to interact
+// with edwards25519.Point coordinates.
+//
+// This type works similarly to math/big.Int, and all arguments and receivers
+// are allowed to alias.
+//
+// The zero value is a valid zero element.
+type Element struct {
+	// An element t represents the integer
+	//     t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204
+	//
+	// Between operations, all limbs are expected to be lower than 2^52.
+	l0 uint64
+	l1 uint64
+	l2 uint64
+	l3 uint64
+	l4 uint64
+}
+
+const maskLow51Bits uint64 = (1 << 51) - 1
+
+var feZero = &Element{0, 0, 0, 0, 0}
+
+// Zero sets v = 0, and returns v.
+func (v *Element) Zero() *Element {
+	*v = *feZero
+	return v
+}
+
+var feOne = &Element{1, 0, 0, 0, 0}
+
+// One sets v = 1, and returns v.
+func (v *Element) One() *Element {
+	*v = *feOne
+	return v
+}
+
+// reduce reduces v modulo 2^255 - 19 and returns it.
+func (v *Element) reduce() *Element {
+	v.carryPropagate()
+
+	// After the light reduction we now have a field element representation
+	// v < 2^255 + 2^13 * 19, but need v < 2^255 - 19.
+
+	// If v >= 2^255 - 19, then v + 19 >= 2^255, which would overflow 2^255 - 1,
+	// generating a carry. That is, c will be 0 if v < 2^255 - 19, and 1 otherwise.
+	c := (v.l0 + 19) >> 51
+	c = (v.l1 + c) >> 51
+	c = (v.l2 + c) >> 51
+	c = (v.l3 + c) >> 51
+	c = (v.l4 + c) >> 51
+
+	// If v < 2^255 - 19 and c = 0, this will be a no-op. Otherwise, it's
+	// effectively applying the reduction identity to the carry.
+	v.l0 += 19 * c
+
+	v.l1 += v.l0 >> 51
+	v.l0 = v.l0 & maskLow51Bits
+	v.l2 += v.l1 >> 51
+	v.l1 = v.l1 & maskLow51Bits
+	v.l3 += v.l2 >> 51
+	v.l2 = v.l2 & maskLow51Bits
+	v.l4 += v.l3 >> 51
+	v.l3 = v.l3 & maskLow51Bits
+	// no additional carry
+	v.l4 = v.l4 & maskLow51Bits
+
+	return v
+}
+
+// Add sets v = a + b, and returns v.
+func (v *Element) Add(a, b *Element) *Element {
+	v.l0 = a.l0 + b.l0
+	v.l1 = a.l1 + b.l1
+	v.l2 = a.l2 + b.l2
+	v.l3 = a.l3 + b.l3
+	v.l4 = a.l4 + b.l4
+	// Using the generic implementation here is actually faster than the
+	// assembly. Probably because the body of this function is so simple that
+	// the compiler can figure out better optimizations by inlining the carry
+	// propagation.
+	return v.carryPropagateGeneric()
+}
+
+// Subtract sets v = a - b, and returns v.
+func (v *Element) Subtract(a, b *Element) *Element {
+	// We first add 2 * p, to guarantee the subtraction won't underflow, and
+	// then subtract b (which can be up to 2^255 + 2^13 * 19).
+	v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0
+	v.l1 = (a.l1 + 0xFFFFFFFFFFFFE) - b.l1
+	v.l2 = (a.l2 + 0xFFFFFFFFFFFFE) - b.l2
+	v.l3 = (a.l3 + 0xFFFFFFFFFFFFE) - b.l3
+	v.l4 = (a.l4 + 0xFFFFFFFFFFFFE) - b.l4
+	return v.carryPropagate()
+}
+
+// Negate sets v = -a, and returns v.
+func (v *Element) Negate(a *Element) *Element {
+	return v.Subtract(feZero, a)
+}
+
+// Invert sets v = 1/z mod p, and returns v.
+//
+// If z == 0, Invert returns v = 0.
+func (v *Element) Invert(z *Element) *Element {
+	// Inversion is implemented as exponentiation with exponent p − 2. It uses the
+	// same sequence of 255 squarings and 11 multiplications as [Curve25519].
+	var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t Element
+
+	z2.Square(z)             // 2
+	t.Square(&z2)            // 4
+	t.Square(&t)             // 8
+	z9.Multiply(&t, z)       // 9
+	z11.Multiply(&z9, &z2)   // 11
+	t.Square(&z11)           // 22
+	z2_5_0.Multiply(&t, &z9) // 31 = 2^5 - 2^0
+
+	t.Square(&z2_5_0) // 2^6 - 2^1
+	for i := 0; i < 4; i++ {
+		t.Square(&t) // 2^10 - 2^5
+	}
+	z2_10_0.Multiply(&t, &z2_5_0) // 2^10 - 2^0
+
+	t.Square(&z2_10_0) // 2^11 - 2^1
+	for i := 0; i < 9; i++ {
+		t.Square(&t) // 2^20 - 2^10
+	}
+	z2_20_0.Multiply(&t, &z2_10_0) // 2^20 - 2^0
+
+	t.Square(&z2_20_0) // 2^21 - 2^1
+	for i := 0; i < 19; i++ {
+		t.Square(&t) // 2^40 - 2^20
+	}
+	t.Multiply(&t, &z2_20_0) // 2^40 - 2^0
+
+	t.Square(&t) // 2^41 - 2^1
+	for i := 0; i < 9; i++ {
+		t.Square(&t) // 2^50 - 2^10
+	}
+	z2_50_0.Multiply(&t, &z2_10_0) // 2^50 - 2^0
+
+	t.Square(&z2_50_0) // 2^51 - 2^1
+	for i := 0; i < 49; i++ {
+		t.Square(&t) // 2^100 - 2^50
+	}
+	z2_100_0.Multiply(&t, &z2_50_0) // 2^100 - 2^0
+
+	t.Square(&z2_100_0) // 2^101 - 2^1
+	for i := 0; i < 99; i++ {
+		t.Square(&t) // 2^200 - 2^100
+	}
+	t.Multiply(&t, &z2_100_0) // 2^200 - 2^0
+
+	t.Square(&t) // 2^201 - 2^1
+	for i := 0; i < 49; i++ {
+		t.Square(&t) // 2^250 - 2^50
+	}
+	t.Multiply(&t, &z2_50_0) // 2^250 - 2^0
+
+	t.Square(&t) // 2^251 - 2^1
+	t.Square(&t) // 2^252 - 2^2
+	t.Square(&t) // 2^253 - 2^3
+	t.Square(&t) // 2^254 - 2^4
+	t.Square(&t) // 2^255 - 2^5
+
+	return v.Multiply(&t, &z11) // 2^255 - 21
+}
+
+// Set sets v = a, and returns v.
+func (v *Element) Set(a *Element) *Element {
+	*v = *a
+	return v
+}
+
+// SetBytes sets v to x, which must be a 32-byte little-endian encoding.
+//
+// Consistent with RFC 7748, the most significant bit (the high bit of the
+// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1)
+// are accepted. Note that this is laxer than specified by RFC 8032.
+func (v *Element) SetBytes(x []byte) *Element {
+	if len(x) != 32 {
+		panic("edwards25519: invalid field element input size")
+	}
+
+	// Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51).
+	v.l0 = binary.LittleEndian.Uint64(x[0:8])
+	v.l0 &= maskLow51Bits
+	// Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51).
+	v.l1 = binary.LittleEndian.Uint64(x[6:14]) >> 3
+	v.l1 &= maskLow51Bits
+	// Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51).
+	v.l2 = binary.LittleEndian.Uint64(x[12:20]) >> 6
+	v.l2 &= maskLow51Bits
+	// Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51).
+	v.l3 = binary.LittleEndian.Uint64(x[19:27]) >> 1
+	v.l3 &= maskLow51Bits
+	// Bits 204:251 (bytes 24:32, bits 192:256, shift 12, mask 51).
+	// Note: not bytes 25:33, shift 4, to avoid overread.
+	v.l4 = binary.LittleEndian.Uint64(x[24:32]) >> 12
+	v.l4 &= maskLow51Bits
+
+	return v
+}
+
+// Bytes returns the canonical 32-byte little-endian encoding of v.
+func (v *Element) Bytes() []byte {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var out [32]byte
+	return v.bytes(&out)
+}
+
+func (v *Element) bytes(out *[32]byte) []byte {
+	t := *v
+	t.reduce()
+
+	var buf [8]byte
+	for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} {
+		bitsOffset := i * 51
+		binary.LittleEndian.PutUint64(buf[:], l<<uint(bitsOffset%8))
+		for i, bb := range buf {
+			off := bitsOffset/8 + i
+			if off >= len(out) {
+				break
+			}
+			out[off] |= bb
+		}
+	}
+
+	return out[:]
+}
+
+// Equal returns 1 if v and u are equal, and 0 otherwise.
+func (v *Element) Equal(u *Element) int {
+	sa, sv := u.Bytes(), v.Bytes()
+	return subtle.ConstantTimeCompare(sa, sv)
+}
+
+// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise.
+func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) }
+
+// Select sets v to a if cond == 1, and to b if cond == 0.
+func (v *Element) Select(a, b *Element, cond int) *Element {
+	m := mask64Bits(cond)
+	v.l0 = (m & a.l0) | (^m & b.l0)
+	v.l1 = (m & a.l1) | (^m & b.l1)
+	v.l2 = (m & a.l2) | (^m & b.l2)
+	v.l3 = (m & a.l3) | (^m & b.l3)
+	v.l4 = (m & a.l4) | (^m & b.l4)
+	return v
+}
+
+// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
+func (v *Element) Swap(u *Element, cond int) {
+	m := mask64Bits(cond)
+	t := m & (v.l0 ^ u.l0)
+	v.l0 ^= t
+	u.l0 ^= t
+	t = m & (v.l1 ^ u.l1)
+	v.l1 ^= t
+	u.l1 ^= t
+	t = m & (v.l2 ^ u.l2)
+	v.l2 ^= t
+	u.l2 ^= t
+	t = m & (v.l3 ^ u.l3)
+	v.l3 ^= t
+	u.l3 ^= t
+	t = m & (v.l4 ^ u.l4)
+	v.l4 ^= t
+	u.l4 ^= t
+}
+
+// IsNegative returns 1 if v is negative, and 0 otherwise.
+func (v *Element) IsNegative() int {
+	return int(v.Bytes()[0] & 1)
+}
+
+// Absolute sets v to |u|, and returns v.
+func (v *Element) Absolute(u *Element) *Element {
+	return v.Select(new(Element).Negate(u), u, u.IsNegative())
+}
+
+// Multiply sets v = x * y, and returns v.
+func (v *Element) Multiply(x, y *Element) *Element {
+	feMul(v, x, y)
+	return v
+}
+
+// Square sets v = x * x, and returns v.
+func (v *Element) Square(x *Element) *Element {
+	feSquare(v, x)
+	return v
+}
+
+// Mult32 sets v = x * y, and returns v.
+func (v *Element) Mult32(x *Element, y uint32) *Element {
+	x0lo, x0hi := mul51(x.l0, y)
+	x1lo, x1hi := mul51(x.l1, y)
+	x2lo, x2hi := mul51(x.l2, y)
+	x3lo, x3hi := mul51(x.l3, y)
+	x4lo, x4hi := mul51(x.l4, y)
+	v.l0 = x0lo + 19*x4hi // carried over per the reduction identity
+	v.l1 = x1lo + x0hi
+	v.l2 = x2lo + x1hi
+	v.l3 = x3lo + x2hi
+	v.l4 = x4lo + x3hi
+	// The hi portions are going to be only 32 bits, plus any previous excess,
+	// so we can skip the carry propagation.
+	return v
+}
+
+// mul51 returns lo + hi * 2⁵¹ = a * b.
+func mul51(a uint64, b uint32) (lo uint64, hi uint64) {
+	mh, ml := bits.Mul64(a, uint64(b))
+	lo = ml & maskLow51Bits
+	hi = (mh << 13) | (ml >> 51)
+	return
+}
+
+// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
+func (v *Element) Pow22523(x *Element) *Element {
+	var t0, t1, t2 Element
+
+	t0.Square(x)             // x^2
+	t1.Square(&t0)           // x^4
+	t1.Square(&t1)           // x^8
+	t1.Multiply(x, &t1)      // x^9
+	t0.Multiply(&t0, &t1)    // x^11
+	t0.Square(&t0)           // x^22
+	t0.Multiply(&t1, &t0)    // x^31
+	t1.Square(&t0)           // x^62
+	for i := 1; i < 5; i++ { // x^992
+		t1.Square(&t1)
+	}
+	t0.Multiply(&t1, &t0)     // x^1023 -> 1023 = 2^10 - 1
+	t1.Square(&t0)            // 2^11 - 2
+	for i := 1; i < 10; i++ { // 2^20 - 2^10
+		t1.Square(&t1)
+	}
+	t1.Multiply(&t1, &t0)     // 2^20 - 1
+	t2.Square(&t1)            // 2^21 - 2
+	for i := 1; i < 20; i++ { // 2^40 - 2^20
+		t2.Square(&t2)
+	}
+	t1.Multiply(&t2, &t1)     // 2^40 - 1
+	t1.Square(&t1)            // 2^41 - 2
+	for i := 1; i < 10; i++ { // 2^50 - 2^10
+		t1.Square(&t1)
+	}
+	t0.Multiply(&t1, &t0)     // 2^50 - 1
+	t1.Square(&t0)            // 2^51 - 2
+	for i := 1; i < 50; i++ { // 2^100 - 2^50
+		t1.Square(&t1)
+	}
+	t1.Multiply(&t1, &t0)      // 2^100 - 1
+	t2.Square(&t1)             // 2^101 - 2
+	for i := 1; i < 100; i++ { // 2^200 - 2^100
+		t2.Square(&t2)
+	}
+	t1.Multiply(&t2, &t1)     // 2^200 - 1
+	t1.Square(&t1)            // 2^201 - 2
+	for i := 1; i < 50; i++ { // 2^250 - 2^50
+		t1.Square(&t1)
+	}
+	t0.Multiply(&t1, &t0)     // 2^250 - 1
+	t0.Square(&t0)            // 2^251 - 2
+	t0.Square(&t0)            // 2^252 - 4
+	return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3)
+}
+
+// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion.
+var sqrtM1 = &Element{1718705420411056, 234908883556509,
+	2233514472574048, 2117202627021982, 765476049583133}
+
+// SqrtRatio sets r to the non-negative square root of the ratio of u and v.
+//
+// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio
+// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00,
+// and returns r and 0.
+func (r *Element) SqrtRatio(u, v *Element) (rr *Element, wasSquare int) {
+	var a, b Element
+
+	// r = (u * v3) * (u * v7)^((p-5)/8)
+	v2 := a.Square(v)
+	uv3 := b.Multiply(u, b.Multiply(v2, v))
+	uv7 := a.Multiply(uv3, a.Square(v2))
+	r.Multiply(uv3, r.Pow22523(uv7))
+
+	check := a.Multiply(v, a.Square(r)) // check = v * r^2
+
+	uNeg := b.Negate(u)
+	correctSignSqrt := check.Equal(u)
+	flippedSignSqrt := check.Equal(uNeg)
+	flippedSignSqrtI := check.Equal(uNeg.Multiply(uNeg, sqrtM1))
+
+	rPrime := b.Multiply(r, sqrtM1) // r_prime = SQRT_M1 * r
+	// r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r)
+	r.Select(rPrime, r, flippedSignSqrt|flippedSignSqrtI)
+
+	r.Absolute(r) // Choose the nonnegative square root.
+	return r, correctSignSqrt | flippedSignSqrt
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe_alias_test.go b/src/crypto/ed25519/internal/edwards25519/field/fe_alias_test.go
new file mode 100644
index 0000000..5ad81df
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/fe_alias_test.go
@@ -0,0 +1,126 @@
+// Copyright (c) 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package field
+
+import (
+	"testing"
+	"testing/quick"
+)
+
+func checkAliasingOneArg(f func(v, x *Element) *Element) func(v, x Element) bool {
+	return func(v, x Element) bool {
+		x1, v1 := x, x
+
+		// Calculate a reference f(x) without aliasing.
+		if out := f(&v, &x); out != &v && isInBounds(out) {
+			return false
+		}
+
+		// Test aliasing the argument and the receiver.
+		if out := f(&v1, &v1); out != &v1 || v1 != v {
+			return false
+		}
+
+		// Ensure the arguments was not modified.
+		return x == x1
+	}
+}
+
+func checkAliasingTwoArgs(f func(v, x, y *Element) *Element) func(v, x, y Element) bool {
+	return func(v, x, y Element) bool {
+		x1, y1, v1 := x, y, Element{}
+
+		// Calculate a reference f(x, y) without aliasing.
+		if out := f(&v, &x, &y); out != &v && isInBounds(out) {
+			return false
+		}
+
+		// Test aliasing the first argument and the receiver.
+		v1 = x
+		if out := f(&v1, &v1, &y); out != &v1 || v1 != v {
+			return false
+		}
+		// Test aliasing the second argument and the receiver.
+		v1 = y
+		if out := f(&v1, &x, &v1); out != &v1 || v1 != v {
+			return false
+		}
+
+		// Calculate a reference f(x, x) without aliasing.
+		if out := f(&v, &x, &x); out != &v {
+			return false
+		}
+
+		// Test aliasing the first argument and the receiver.
+		v1 = x
+		if out := f(&v1, &v1, &x); out != &v1 || v1 != v {
+			return false
+		}
+		// Test aliasing the second argument and the receiver.
+		v1 = x
+		if out := f(&v1, &x, &v1); out != &v1 || v1 != v {
+			return false
+		}
+		// Test aliasing both arguments and the receiver.
+		v1 = x
+		if out := f(&v1, &v1, &v1); out != &v1 || v1 != v {
+			return false
+		}
+
+		// Ensure the arguments were not modified.
+		return x == x1 && y == y1
+	}
+}
+
+// TestAliasing checks that receivers and arguments can alias each other without
+// leading to incorrect results. That is, it ensures that it's safe to write
+//
+//     v.Invert(v)
+//
+// or
+//
+//     v.Add(v, v)
+//
+// without any of the inputs getting clobbered by the output being written.
+func TestAliasing(t *testing.T) {
+	type target struct {
+		name     string
+		oneArgF  func(v, x *Element) *Element
+		twoArgsF func(v, x, y *Element) *Element
+	}
+	for _, tt := range []target{
+		{name: "Absolute", oneArgF: (*Element).Absolute},
+		{name: "Invert", oneArgF: (*Element).Invert},
+		{name: "Negate", oneArgF: (*Element).Negate},
+		{name: "Set", oneArgF: (*Element).Set},
+		{name: "Square", oneArgF: (*Element).Square},
+		{name: "Multiply", twoArgsF: (*Element).Multiply},
+		{name: "Add", twoArgsF: (*Element).Add},
+		{name: "Subtract", twoArgsF: (*Element).Subtract},
+		{
+			name: "Select0",
+			twoArgsF: func(v, x, y *Element) *Element {
+				return (*Element).Select(v, x, y, 0)
+			},
+		},
+		{
+			name: "Select1",
+			twoArgsF: func(v, x, y *Element) *Element {
+				return (*Element).Select(v, x, y, 1)
+			},
+		},
+	} {
+		var err error
+		switch {
+		case tt.oneArgF != nil:
+			err = quick.Check(checkAliasingOneArg(tt.oneArgF), &quick.Config{MaxCountScale: 1 << 8})
+		case tt.twoArgsF != nil:
+			err = quick.Check(checkAliasingTwoArgs(tt.twoArgsF), &quick.Config{MaxCountScale: 1 << 8})
+		}
+		if err != nil {
+			t.Errorf("%v: %v", tt.name, err)
+		}
+	}
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go b/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go
new file mode 100644
index 0000000..8fe5839
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go
@@ -0,0 +1,14 @@
+// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
+
+//go:build amd64 && gc && !purego
+// +build amd64,gc,!purego
+
+package field
+
+// feMul sets out = a * b. It works like feMulGeneric.
+//go:noescape
+func feMul(out *Element, a *Element, b *Element)
+
+// feSquare sets out = a * a. It works like feSquareGeneric.
+//go:noescape
+func feSquare(out *Element, a *Element)
diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.s b/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.s
new file mode 100644
index 0000000..0aa1e86
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.s
@@ -0,0 +1,378 @@
+// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
+
+// +build amd64,gc,!purego
+
+#include "textflag.h"
+
+// func feMul(out *Element, a *Element, b *Element)
+TEXT ·feMul(SB), NOSPLIT, $0-24
+	MOVQ a+8(FP), CX
+	MOVQ b+16(FP), BX
+
+	// r0 = a0×b0
+	MOVQ (CX), AX
+	MULQ (BX)
+	MOVQ AX, DI
+	MOVQ DX, SI
+
+	// r0 += 19×a1×b4
+	MOVQ   8(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(BX)
+	ADDQ   AX, DI
+	ADCQ   DX, SI
+
+	// r0 += 19×a2×b3
+	MOVQ   16(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   24(BX)
+	ADDQ   AX, DI
+	ADCQ   DX, SI
+
+	// r0 += 19×a3×b2
+	MOVQ   24(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   16(BX)
+	ADDQ   AX, DI
+	ADCQ   DX, SI
+
+	// r0 += 19×a4×b1
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   8(BX)
+	ADDQ   AX, DI
+	ADCQ   DX, SI
+
+	// r1 = a0×b1
+	MOVQ (CX), AX
+	MULQ 8(BX)
+	MOVQ AX, R9
+	MOVQ DX, R8
+
+	// r1 += a1×b0
+	MOVQ 8(CX), AX
+	MULQ (BX)
+	ADDQ AX, R9
+	ADCQ DX, R8
+
+	// r1 += 19×a2×b4
+	MOVQ   16(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(BX)
+	ADDQ   AX, R9
+	ADCQ   DX, R8
+
+	// r1 += 19×a3×b3
+	MOVQ   24(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   24(BX)
+	ADDQ   AX, R9
+	ADCQ   DX, R8
+
+	// r1 += 19×a4×b2
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   16(BX)
+	ADDQ   AX, R9
+	ADCQ   DX, R8
+
+	// r2 = a0×b2
+	MOVQ (CX), AX
+	MULQ 16(BX)
+	MOVQ AX, R11
+	MOVQ DX, R10
+
+	// r2 += a1×b1
+	MOVQ 8(CX), AX
+	MULQ 8(BX)
+	ADDQ AX, R11
+	ADCQ DX, R10
+
+	// r2 += a2×b0
+	MOVQ 16(CX), AX
+	MULQ (BX)
+	ADDQ AX, R11
+	ADCQ DX, R10
+
+	// r2 += 19×a3×b4
+	MOVQ   24(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(BX)
+	ADDQ   AX, R11
+	ADCQ   DX, R10
+
+	// r2 += 19×a4×b3
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   24(BX)
+	ADDQ   AX, R11
+	ADCQ   DX, R10
+
+	// r3 = a0×b3
+	MOVQ (CX), AX
+	MULQ 24(BX)
+	MOVQ AX, R13
+	MOVQ DX, R12
+
+	// r3 += a1×b2
+	MOVQ 8(CX), AX
+	MULQ 16(BX)
+	ADDQ AX, R13
+	ADCQ DX, R12
+
+	// r3 += a2×b1
+	MOVQ 16(CX), AX
+	MULQ 8(BX)
+	ADDQ AX, R13
+	ADCQ DX, R12
+
+	// r3 += a3×b0
+	MOVQ 24(CX), AX
+	MULQ (BX)
+	ADDQ AX, R13
+	ADCQ DX, R12
+
+	// r3 += 19×a4×b4
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(BX)
+	ADDQ   AX, R13
+	ADCQ   DX, R12
+
+	// r4 = a0×b4
+	MOVQ (CX), AX
+	MULQ 32(BX)
+	MOVQ AX, R15
+	MOVQ DX, R14
+
+	// r4 += a1×b3
+	MOVQ 8(CX), AX
+	MULQ 24(BX)
+	ADDQ AX, R15
+	ADCQ DX, R14
+
+	// r4 += a2×b2
+	MOVQ 16(CX), AX
+	MULQ 16(BX)
+	ADDQ AX, R15
+	ADCQ DX, R14
+
+	// r4 += a3×b1
+	MOVQ 24(CX), AX
+	MULQ 8(BX)
+	ADDQ AX, R15
+	ADCQ DX, R14
+
+	// r4 += a4×b0
+	MOVQ 32(CX), AX
+	MULQ (BX)
+	ADDQ AX, R15
+	ADCQ DX, R14
+
+	// First reduction chain
+	MOVQ   $0x0007ffffffffffff, AX
+	SHLQ   $0x0d, DI, SI
+	SHLQ   $0x0d, R9, R8
+	SHLQ   $0x0d, R11, R10
+	SHLQ   $0x0d, R13, R12
+	SHLQ   $0x0d, R15, R14
+	ANDQ   AX, DI
+	IMUL3Q $0x13, R14, R14
+	ADDQ   R14, DI
+	ANDQ   AX, R9
+	ADDQ   SI, R9
+	ANDQ   AX, R11
+	ADDQ   R8, R11
+	ANDQ   AX, R13
+	ADDQ   R10, R13
+	ANDQ   AX, R15
+	ADDQ   R12, R15
+
+	// Second reduction chain (carryPropagate)
+	MOVQ   DI, SI
+	SHRQ   $0x33, SI
+	MOVQ   R9, R8
+	SHRQ   $0x33, R8
+	MOVQ   R11, R10
+	SHRQ   $0x33, R10
+	MOVQ   R13, R12
+	SHRQ   $0x33, R12
+	MOVQ   R15, R14
+	SHRQ   $0x33, R14
+	ANDQ   AX, DI
+	IMUL3Q $0x13, R14, R14
+	ADDQ   R14, DI
+	ANDQ   AX, R9
+	ADDQ   SI, R9
+	ANDQ   AX, R11
+	ADDQ   R8, R11
+	ANDQ   AX, R13
+	ADDQ   R10, R13
+	ANDQ   AX, R15
+	ADDQ   R12, R15
+
+	// Store output
+	MOVQ out+0(FP), AX
+	MOVQ DI, (AX)
+	MOVQ R9, 8(AX)
+	MOVQ R11, 16(AX)
+	MOVQ R13, 24(AX)
+	MOVQ R15, 32(AX)
+	RET
+
+// func feSquare(out *Element, a *Element)
+TEXT ·feSquare(SB), NOSPLIT, $0-16
+	MOVQ a+8(FP), CX
+
+	// r0 = l0×l0
+	MOVQ (CX), AX
+	MULQ (CX)
+	MOVQ AX, SI
+	MOVQ DX, BX
+
+	// r0 += 38×l1×l4
+	MOVQ   8(CX), AX
+	IMUL3Q $0x26, AX, AX
+	MULQ   32(CX)
+	ADDQ   AX, SI
+	ADCQ   DX, BX
+
+	// r0 += 38×l2×l3
+	MOVQ   16(CX), AX
+	IMUL3Q $0x26, AX, AX
+	MULQ   24(CX)
+	ADDQ   AX, SI
+	ADCQ   DX, BX
+
+	// r1 = 2×l0×l1
+	MOVQ (CX), AX
+	SHLQ $0x01, AX
+	MULQ 8(CX)
+	MOVQ AX, R8
+	MOVQ DX, DI
+
+	// r1 += 38×l2×l4
+	MOVQ   16(CX), AX
+	IMUL3Q $0x26, AX, AX
+	MULQ   32(CX)
+	ADDQ   AX, R8
+	ADCQ   DX, DI
+
+	// r1 += 19×l3×l3
+	MOVQ   24(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   24(CX)
+	ADDQ   AX, R8
+	ADCQ   DX, DI
+
+	// r2 = 2×l0×l2
+	MOVQ (CX), AX
+	SHLQ $0x01, AX
+	MULQ 16(CX)
+	MOVQ AX, R10
+	MOVQ DX, R9
+
+	// r2 += l1×l1
+	MOVQ 8(CX), AX
+	MULQ 8(CX)
+	ADDQ AX, R10
+	ADCQ DX, R9
+
+	// r2 += 38×l3×l4
+	MOVQ   24(CX), AX
+	IMUL3Q $0x26, AX, AX
+	MULQ   32(CX)
+	ADDQ   AX, R10
+	ADCQ   DX, R9
+
+	// r3 = 2×l0×l3
+	MOVQ (CX), AX
+	SHLQ $0x01, AX
+	MULQ 24(CX)
+	MOVQ AX, R12
+	MOVQ DX, R11
+
+	// r3 += 2×l1×l2
+	MOVQ   8(CX), AX
+	IMUL3Q $0x02, AX, AX
+	MULQ   16(CX)
+	ADDQ   AX, R12
+	ADCQ   DX, R11
+
+	// r3 += 19×l4×l4
+	MOVQ   32(CX), AX
+	IMUL3Q $0x13, AX, AX
+	MULQ   32(CX)
+	ADDQ   AX, R12
+	ADCQ   DX, R11
+
+	// r4 = 2×l0×l4
+	MOVQ (CX), AX
+	SHLQ $0x01, AX
+	MULQ 32(CX)
+	MOVQ AX, R14
+	MOVQ DX, R13
+
+	// r4 += 2×l1×l3
+	MOVQ   8(CX), AX
+	IMUL3Q $0x02, AX, AX
+	MULQ   24(CX)
+	ADDQ   AX, R14
+	ADCQ   DX, R13
+
+	// r4 += l2×l2
+	MOVQ 16(CX), AX
+	MULQ 16(CX)
+	ADDQ AX, R14
+	ADCQ DX, R13
+
+	// First reduction chain
+	MOVQ   $0x0007ffffffffffff, AX
+	SHLQ   $0x0d, SI, BX
+	SHLQ   $0x0d, R8, DI
+	SHLQ   $0x0d, R10, R9
+	SHLQ   $0x0d, R12, R11
+	SHLQ   $0x0d, R14, R13
+	ANDQ   AX, SI
+	IMUL3Q $0x13, R13, R13
+	ADDQ   R13, SI
+	ANDQ   AX, R8
+	ADDQ   BX, R8
+	ANDQ   AX, R10
+	ADDQ   DI, R10
+	ANDQ   AX, R12
+	ADDQ   R9, R12
+	ANDQ   AX, R14
+	ADDQ   R11, R14
+
+	// Second reduction chain (carryPropagate)
+	MOVQ   SI, BX
+	SHRQ   $0x33, BX
+	MOVQ   R8, DI
+	SHRQ   $0x33, DI
+	MOVQ   R10, R9
+	SHRQ   $0x33, R9
+	MOVQ   R12, R11
+	SHRQ   $0x33, R11
+	MOVQ   R14, R13
+	SHRQ   $0x33, R13
+	ANDQ   AX, SI
+	IMUL3Q $0x13, R13, R13
+	ADDQ   R13, SI
+	ANDQ   AX, R8
+	ADDQ   BX, R8
+	ANDQ   AX, R10
+	ADDQ   DI, R10
+	ANDQ   AX, R12
+	ADDQ   R9, R12
+	ANDQ   AX, R14
+	ADDQ   R11, R14
+
+	// Store output
+	MOVQ out+0(FP), AX
+	MOVQ SI, (AX)
+	MOVQ R8, 8(AX)
+	MOVQ R10, 16(AX)
+	MOVQ R12, 24(AX)
+	MOVQ R14, 32(AX)
+	RET
diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe_amd64_noasm.go b/src/crypto/ed25519/internal/edwards25519/field/fe_amd64_noasm.go
new file mode 100644
index 0000000..ddb6c9b
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/fe_amd64_noasm.go
@@ -0,0 +1,12 @@
+// Copyright (c) 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 || !gc || purego
+// +build !amd64 !gc purego
+
+package field
+
+func feMul(v, x, y *Element) { feMulGeneric(v, x, y) }
+
+func feSquare(v, x *Element) { feSquareGeneric(v, x) }
diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe_arm64.go b/src/crypto/ed25519/internal/edwards25519/field/fe_arm64.go
new file mode 100644
index 0000000..af459ef
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/fe_arm64.go
@@ -0,0 +1,16 @@
+// Copyright (c) 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build arm64 && gc && !purego
+// +build arm64,gc,!purego
+
+package field
+
+//go:noescape
+func carryPropagate(v *Element)
+
+func (v *Element) carryPropagate() *Element {
+	carryPropagate(v)
+	return v
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe_arm64.s b/src/crypto/ed25519/internal/edwards25519/field/fe_arm64.s
new file mode 100644
index 0000000..751ab2a
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/fe_arm64.s
@@ -0,0 +1,42 @@
+// Copyright (c) 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build arm64,gc,!purego
+
+#include "textflag.h"
+
+// carryPropagate works exactly like carryPropagateGeneric and uses the
+// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but
+// avoids loading R0-R4 twice and uses LDP and STP.
+//
+// See https://golang.org/issues/43145 for the main compiler issue.
+//
+// func carryPropagate(v *Element)
+TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8
+	MOVD v+0(FP), R20
+
+	LDP 0(R20), (R0, R1)
+	LDP 16(R20), (R2, R3)
+	MOVD 32(R20), R4
+
+	AND $0x7ffffffffffff, R0, R10
+	AND $0x7ffffffffffff, R1, R11
+	AND $0x7ffffffffffff, R2, R12
+	AND $0x7ffffffffffff, R3, R13
+	AND $0x7ffffffffffff, R4, R14
+
+	ADD R0>>51, R11, R11
+	ADD R1>>51, R12, R12
+	ADD R2>>51, R13, R13
+	ADD R3>>51, R14, R14
+	// R4>>51 * 19 + R10 -> R10
+	LSR $51, R4, R21
+	MOVD $19, R22
+	MADD R22, R10, R21, R10
+
+	STP (R10, R11), 0(R20)
+	STP (R12, R13), 16(R20)
+	MOVD R14, 32(R20)
+
+	RET
diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe_arm64_noasm.go b/src/crypto/ed25519/internal/edwards25519/field/fe_arm64_noasm.go
new file mode 100644
index 0000000..234a5b2
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/fe_arm64_noasm.go
@@ -0,0 +1,12 @@
+// Copyright (c) 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !arm64 || !gc || purego
+// +build !arm64 !gc purego
+
+package field
+
+func (v *Element) carryPropagate() *Element {
+	return v.carryPropagateGeneric()
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe_bench_test.go b/src/crypto/ed25519/internal/edwards25519/field/fe_bench_test.go
new file mode 100644
index 0000000..77dc06c
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/fe_bench_test.go
@@ -0,0 +1,36 @@
+// Copyright (c) 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package field
+
+import "testing"
+
+func BenchmarkAdd(b *testing.B) {
+	var x, y Element
+	x.One()
+	y.Add(feOne, feOne)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		x.Add(&x, &y)
+	}
+}
+
+func BenchmarkMultiply(b *testing.B) {
+	var x, y Element
+	x.One()
+	y.Add(feOne, feOne)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		x.Multiply(&x, &y)
+	}
+}
+
+func BenchmarkMult32(b *testing.B) {
+	var x Element
+	x.One()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		x.Mult32(&x, 0xaa42aa42)
+	}
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe_generic.go b/src/crypto/ed25519/internal/edwards25519/field/fe_generic.go
new file mode 100644
index 0000000..bccf851
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/fe_generic.go
@@ -0,0 +1,264 @@
+// Copyright (c) 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package field
+
+import "math/bits"
+
+// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
+// bits.Mul64 and bits.Add64 intrinsics.
+type uint128 struct {
+	lo, hi uint64
+}
+
+// mul64 returns a * b.
+func mul64(a, b uint64) uint128 {
+	hi, lo := bits.Mul64(a, b)
+	return uint128{lo, hi}
+}
+
+// addMul64 returns v + a * b.
+func addMul64(v uint128, a, b uint64) uint128 {
+	hi, lo := bits.Mul64(a, b)
+	lo, c := bits.Add64(lo, v.lo, 0)
+	hi, _ = bits.Add64(hi, v.hi, c)
+	return uint128{lo, hi}
+}
+
+// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits.
+func shiftRightBy51(a uint128) uint64 {
+	return (a.hi << (64 - 51)) | (a.lo >> 51)
+}
+
+func feMulGeneric(v, a, b *Element) {
+	a0 := a.l0
+	a1 := a.l1
+	a2 := a.l2
+	a3 := a.l3
+	a4 := a.l4
+
+	b0 := b.l0
+	b1 := b.l1
+	b2 := b.l2
+	b3 := b.l3
+	b4 := b.l4
+
+	// Limb multiplication works like pen-and-paper columnar multiplication, but
+	// with 51-bit limbs instead of digits.
+	//
+	//                          a4   a3   a2   a1   a0  x
+	//                          b4   b3   b2   b1   b0  =
+	//                         ------------------------
+	//                        a4b0 a3b0 a2b0 a1b0 a0b0  +
+	//                   a4b1 a3b1 a2b1 a1b1 a0b1       +
+	//              a4b2 a3b2 a2b2 a1b2 a0b2            +
+	//         a4b3 a3b3 a2b3 a1b3 a0b3                 +
+	//    a4b4 a3b4 a2b4 a1b4 a0b4                      =
+	//   ----------------------------------------------
+	//      r8   r7   r6   r5   r4   r3   r2   r1   r0
+	//
+	// We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to
+	// reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5,
+	// r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc.
+	//
+	// Reduction can be carried out simultaneously to multiplication. For
+	// example, we do not compute r5: whenever the result of a multiplication
+	// belongs to r5, like a1b4, we multiply it by 19 and add the result to r0.
+	//
+	//            a4b0    a3b0    a2b0    a1b0    a0b0  +
+	//            a3b1    a2b1    a1b1    a0b1 19×a4b1  +
+	//            a2b2    a1b2    a0b2 19×a4b2 19×a3b2  +
+	//            a1b3    a0b3 19×a4b3 19×a3b3 19×a2b3  +
+	//            a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4  =
+	//           --------------------------------------
+	//              r4      r3      r2      r1      r0
+	//
+	// Finally we add up the columns into wide, overlapping limbs.
+
+	a1_19 := a1 * 19
+	a2_19 := a2 * 19
+	a3_19 := a3 * 19
+	a4_19 := a4 * 19
+
+	// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
+	r0 := mul64(a0, b0)
+	r0 = addMul64(r0, a1_19, b4)
+	r0 = addMul64(r0, a2_19, b3)
+	r0 = addMul64(r0, a3_19, b2)
+	r0 = addMul64(r0, a4_19, b1)
+
+	// r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
+	r1 := mul64(a0, b1)
+	r1 = addMul64(r1, a1, b0)
+	r1 = addMul64(r1, a2_19, b4)
+	r1 = addMul64(r1, a3_19, b3)
+	r1 = addMul64(r1, a4_19, b2)
+
+	// r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
+	r2 := mul64(a0, b2)
+	r2 = addMul64(r2, a1, b1)
+	r2 = addMul64(r2, a2, b0)
+	r2 = addMul64(r2, a3_19, b4)
+	r2 = addMul64(r2, a4_19, b3)
+
+	// r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
+	r3 := mul64(a0, b3)
+	r3 = addMul64(r3, a1, b2)
+	r3 = addMul64(r3, a2, b1)
+	r3 = addMul64(r3, a3, b0)
+	r3 = addMul64(r3, a4_19, b4)
+
+	// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
+	r4 := mul64(a0, b4)
+	r4 = addMul64(r4, a1, b3)
+	r4 = addMul64(r4, a2, b2)
+	r4 = addMul64(r4, a3, b1)
+	r4 = addMul64(r4, a4, b0)
+
+	// After the multiplication, we need to reduce (carry) the five coefficients
+	// to obtain a result with limbs that are at most slightly larger than 2⁵¹,
+	// to respect the Element invariant.
+	//
+	// Overall, the reduction works the same as carryPropagate, except with
+	// wider inputs: we take the carry for each coefficient by shifting it right
+	// by 51, and add it to the limb above it. The top carry is multiplied by 19
+	// according to the reduction identity and added to the lowest limb.
+	//
+	// The largest coefficient (r0) will be at most 111 bits, which guarantees
+	// that all carries are at most 111 - 51 = 60 bits, which fits in a uint64.
+	//
+	//     r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
+	//     r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²)
+	//     r0 < (1 + 19 × 4) × 2⁵² × 2⁵²
+	//     r0 < 2⁷ × 2⁵² × 2⁵²
+	//     r0 < 2¹¹¹
+	//
+	// Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most
+	// 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and
+	// allows us to easily apply the reduction identity.
+	//
+	//     r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
+	//     r4 < 5 × 2⁵² × 2⁵²
+	//     r4 < 2¹⁰⁷
+	//
+
+	c0 := shiftRightBy51(r0)
+	c1 := shiftRightBy51(r1)
+	c2 := shiftRightBy51(r2)
+	c3 := shiftRightBy51(r3)
+	c4 := shiftRightBy51(r4)
+
+	rr0 := r0.lo&maskLow51Bits + c4*19
+	rr1 := r1.lo&maskLow51Bits + c0
+	rr2 := r2.lo&maskLow51Bits + c1
+	rr3 := r3.lo&maskLow51Bits + c2
+	rr4 := r4.lo&maskLow51Bits + c3
+
+	// Now all coefficients fit into 64-bit registers but are still too large to
+	// be passed around as a Element. We therefore do one last carry chain,
+	// where the carries will be small enough to fit in the wiggle room above 2⁵¹.
+	*v = Element{rr0, rr1, rr2, rr3, rr4}
+	v.carryPropagate()
+}
+
+func feSquareGeneric(v, a *Element) {
+	l0 := a.l0
+	l1 := a.l1
+	l2 := a.l2
+	l3 := a.l3
+	l4 := a.l4
+
+	// Squaring works precisely like multiplication above, but thanks to its
+	// symmetry we get to group a few terms together.
+	//
+	//                          l4   l3   l2   l1   l0  x
+	//                          l4   l3   l2   l1   l0  =
+	//                         ------------------------
+	//                        l4l0 l3l0 l2l0 l1l0 l0l0  +
+	//                   l4l1 l3l1 l2l1 l1l1 l0l1       +
+	//              l4l2 l3l2 l2l2 l1l2 l0l2            +
+	//         l4l3 l3l3 l2l3 l1l3 l0l3                 +
+	//    l4l4 l3l4 l2l4 l1l4 l0l4                      =
+	//   ----------------------------------------------
+	//      r8   r7   r6   r5   r4   r3   r2   r1   r0
+	//
+	//            l4l0    l3l0    l2l0    l1l0    l0l0  +
+	//            l3l1    l2l1    l1l1    l0l1 19×l4l1  +
+	//            l2l2    l1l2    l0l2 19×l4l2 19×l3l2  +
+	//            l1l3    l0l3 19×l4l3 19×l3l3 19×l2l3  +
+	//            l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4  =
+	//           --------------------------------------
+	//              r4      r3      r2      r1      r0
+	//
+	// With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with
+	// only three Mul64 and four Add64, instead of five and eight.
+
+	l0_2 := l0 * 2
+	l1_2 := l1 * 2
+
+	l1_38 := l1 * 38
+	l2_38 := l2 * 38
+	l3_38 := l3 * 38
+
+	l3_19 := l3 * 19
+	l4_19 := l4 * 19
+
+	// r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3)
+	r0 := mul64(l0, l0)
+	r0 = addMul64(r0, l1_38, l4)
+	r0 = addMul64(r0, l2_38, l3)
+
+	// r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
+	r1 := mul64(l0_2, l1)
+	r1 = addMul64(r1, l2_38, l4)
+	r1 = addMul64(r1, l3_19, l3)
+
+	// r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4
+	r2 := mul64(l0_2, l2)
+	r2 = addMul64(r2, l1, l1)
+	r2 = addMul64(r2, l3_38, l4)
+
+	// r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
+	r3 := mul64(l0_2, l3)
+	r3 = addMul64(r3, l1_2, l2)
+	r3 = addMul64(r3, l4_19, l4)
+
+	// r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2
+	r4 := mul64(l0_2, l4)
+	r4 = addMul64(r4, l1_2, l3)
+	r4 = addMul64(r4, l2, l2)
+
+	c0 := shiftRightBy51(r0)
+	c1 := shiftRightBy51(r1)
+	c2 := shiftRightBy51(r2)
+	c3 := shiftRightBy51(r3)
+	c4 := shiftRightBy51(r4)
+
+	rr0 := r0.lo&maskLow51Bits + c4*19
+	rr1 := r1.lo&maskLow51Bits + c0
+	rr2 := r2.lo&maskLow51Bits + c1
+	rr3 := r3.lo&maskLow51Bits + c2
+	rr4 := r4.lo&maskLow51Bits + c3
+
+	*v = Element{rr0, rr1, rr2, rr3, rr4}
+	v.carryPropagate()
+}
+
+// carryPropagate brings the limbs below 52 bits by applying the reduction
+// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry.
+func (v *Element) carryPropagateGeneric() *Element {
+	c0 := v.l0 >> 51
+	c1 := v.l1 >> 51
+	c2 := v.l2 >> 51
+	c3 := v.l3 >> 51
+	c4 := v.l4 >> 51
+
+	v.l0 = v.l0&maskLow51Bits + c4*19
+	v.l1 = v.l1&maskLow51Bits + c0
+	v.l2 = v.l2&maskLow51Bits + c1
+	v.l3 = v.l3&maskLow51Bits + c2
+	v.l4 = v.l4&maskLow51Bits + c3
+
+	return v
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe_test.go b/src/crypto/ed25519/internal/edwards25519/field/fe_test.go
new file mode 100644
index 0000000..b484459
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/field/fe_test.go
@@ -0,0 +1,558 @@
+// Copyright (c) 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package field
+
+import (
+	"bytes"
+	"crypto/rand"
+	"encoding/hex"
+	"io"
+	"math/big"
+	"math/bits"
+	mathrand "math/rand"
+	"reflect"
+	"testing"
+	"testing/quick"
+)
+
+func (v Element) String() string {
+	return hex.EncodeToString(v.Bytes())
+}
+
+// quickCheckConfig1024 will make each quickcheck test run (1024 * -quickchecks)
+// times. The default value of -quickchecks is 100.
+var quickCheckConfig1024 = &quick.Config{MaxCountScale: 1 << 10}
+
+func generateFieldElement(rand *mathrand.Rand) Element {
+	const maskLow52Bits = (1 << 52) - 1
+	return Element{
+		rand.Uint64() & maskLow52Bits,
+		rand.Uint64() & maskLow52Bits,
+		rand.Uint64() & maskLow52Bits,
+		rand.Uint64() & maskLow52Bits,
+		rand.Uint64() & maskLow52Bits,
+	}
+}
+
+// weirdLimbs can be combined to generate a range of edge-case field elements.
+// 0 and -1 are intentionally more weighted, as they combine well.
+var (
+	weirdLimbs51 = []uint64{
+		0, 0, 0, 0,
+		1,
+		19 - 1,
+		19,
+		0x2aaaaaaaaaaaa,
+		0x5555555555555,
+		(1 << 51) - 20,
+		(1 << 51) - 19,
+		(1 << 51) - 1, (1 << 51) - 1,
+		(1 << 51) - 1, (1 << 51) - 1,
+	}
+	weirdLimbs52 = []uint64{
+		0, 0, 0, 0, 0, 0,
+		1,
+		19 - 1,
+		19,
+		0x2aaaaaaaaaaaa,
+		0x5555555555555,
+		(1 << 51) - 20,
+		(1 << 51) - 19,
+		(1 << 51) - 1, (1 << 51) - 1,
+		(1 << 51) - 1, (1 << 51) - 1,
+		(1 << 51) - 1, (1 << 51) - 1,
+		1 << 51,
+		(1 << 51) + 1,
+		(1 << 52) - 19,
+		(1 << 52) - 1,
+	}
+)
+
+func generateWeirdFieldElement(rand *mathrand.Rand) Element {
+	return Element{
+		weirdLimbs52[rand.Intn(len(weirdLimbs52))],
+		weirdLimbs51[rand.Intn(len(weirdLimbs51))],
+		weirdLimbs51[rand.Intn(len(weirdLimbs51))],
+		weirdLimbs51[rand.Intn(len(weirdLimbs51))],
+		weirdLimbs51[rand.Intn(len(weirdLimbs51))],
+	}
+}
+
+func (Element) Generate(rand *mathrand.Rand, size int) reflect.Value {
+	if rand.Intn(2) == 0 {
+		return reflect.ValueOf(generateWeirdFieldElement(rand))
+	}
+	return reflect.ValueOf(generateFieldElement(rand))
+}
+
+// isInBounds returns whether the element is within the expected bit size bounds
+// after a light reduction.
+func isInBounds(x *Element) bool {
+	return bits.Len64(x.l0) <= 52 &&
+		bits.Len64(x.l1) <= 52 &&
+		bits.Len64(x.l2) <= 52 &&
+		bits.Len64(x.l3) <= 52 &&
+		bits.Len64(x.l4) <= 52
+}
+
+func TestMultiplyDistributesOverAdd(t *testing.T) {
+	multiplyDistributesOverAdd := func(x, y, z Element) bool {
+		// Compute t1 = (x+y)*z
+		t1 := new(Element)
+		t1.Add(&x, &y)
+		t1.Multiply(t1, &z)
+
+		// Compute t2 = x*z + y*z
+		t2 := new(Element)
+		t3 := new(Element)
+		t2.Multiply(&x, &z)
+		t3.Multiply(&y, &z)
+		t2.Add(t2, t3)
+
+		return t1.Equal(t2) == 1 && isInBounds(t1) && isInBounds(t2)
+	}
+
+	if err := quick.Check(multiplyDistributesOverAdd, quickCheckConfig1024); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestMul64to128(t *testing.T) {
+	a := uint64(5)
+	b := uint64(5)
+	r := mul64(a, b)
+	if r.lo != 0x19 || r.hi != 0 {
+		t.Errorf("lo-range wide mult failed, got %d + %d*(2**64)", r.lo, r.hi)
+	}
+
+	a = uint64(18014398509481983) // 2^54 - 1
+	b = uint64(18014398509481983) // 2^54 - 1
+	r = mul64(a, b)
+	if r.lo != 0xff80000000000001 || r.hi != 0xfffffffffff {
+		t.Errorf("hi-range wide mult failed, got %d + %d*(2**64)", r.lo, r.hi)
+	}
+
+	a = uint64(1125899906842661)
+	b = uint64(2097155)
+	r = mul64(a, b)
+	r = addMul64(r, a, b)
+	r = addMul64(r, a, b)
+	r = addMul64(r, a, b)
+	r = addMul64(r, a, b)
+	if r.lo != 16888498990613035 || r.hi != 640 {
+		t.Errorf("wrong answer: %d + %d*(2**64)", r.lo, r.hi)
+	}
+}
+
+func TestSetBytesRoundTrip(t *testing.T) {
+	f1 := func(in [32]byte, fe Element) bool {
+		fe.SetBytes(in[:])
+
+		// Mask the most significant bit as it's ignored by SetBytes. (Now
+		// instead of earlier so we check the masking in SetBytes is working.)
+		in[len(in)-1] &= (1 << 7) - 1
+
+		return bytes.Equal(in[:], fe.Bytes()) && isInBounds(&fe)
+	}
+	if err := quick.Check(f1, nil); err != nil {
+		t.Errorf("failed bytes->FE->bytes round-trip: %v", err)
+	}
+
+	f2 := func(fe, r Element) bool {
+		r.SetBytes(fe.Bytes())
+
+		// Intentionally not using Equal not to go through Bytes again.
+		// Calling reduce because both Generate and SetBytes can produce
+		// non-canonical representations.
+		fe.reduce()
+		r.reduce()
+		return fe == r
+	}
+	if err := quick.Check(f2, nil); err != nil {
+		t.Errorf("failed FE->bytes->FE round-trip: %v", err)
+	}
+
+	// Check some fixed vectors from dalek
+	type feRTTest struct {
+		fe Element
+		b  []byte
+	}
+	var tests = []feRTTest{
+		{
+			fe: Element{358744748052810, 1691584618240980, 977650209285361, 1429865912637724, 560044844278676},
+			b:  []byte{74, 209, 69, 197, 70, 70, 161, 222, 56, 226, 229, 19, 112, 60, 25, 92, 187, 74, 222, 56, 50, 153, 51, 233, 40, 74, 57, 6, 160, 185, 213, 31},
+		},
+		{
+			fe: Element{84926274344903, 473620666599931, 365590438845504, 1028470286882429, 2146499180330972},
+			b:  []byte{199, 23, 106, 112, 61, 77, 216, 79, 186, 60, 11, 118, 13, 16, 103, 15, 42, 32, 83, 250, 44, 57, 204, 198, 78, 199, 253, 119, 146, 172, 3, 122},
+		},
+	}
+
+	for _, tt := range tests {
+		b := tt.fe.Bytes()
+		if !bytes.Equal(b, tt.b) || new(Element).SetBytes(tt.b).Equal(&tt.fe) != 1 {
+			t.Errorf("Failed fixed roundtrip: %v", tt)
+		}
+	}
+}
+
+func swapEndianness(buf []byte) []byte {
+	for i := 0; i < len(buf)/2; i++ {
+		buf[i], buf[len(buf)-i-1] = buf[len(buf)-i-1], buf[i]
+	}
+	return buf
+}
+
+func TestBytesBigEquivalence(t *testing.T) {
+	f1 := func(in [32]byte, fe, fe1 Element) bool {
+		fe.SetBytes(in[:])
+
+		in[len(in)-1] &= (1 << 7) - 1 // mask the most significant bit
+		b := new(big.Int).SetBytes(swapEndianness(in[:]))
+		fe1.fromBig(b)
+
+		if fe != fe1 {
+			return false
+		}
+
+		buf := make([]byte, 32) // pad with zeroes
+		copy(buf, swapEndianness(fe1.toBig().Bytes()))
+
+		return bytes.Equal(fe.Bytes(), buf) && isInBounds(&fe) && isInBounds(&fe1)
+	}
+	if err := quick.Check(f1, nil); err != nil {
+		t.Error(err)
+	}
+}
+
+// fromBig sets v = n, and returns v. The bit length of n must not exceed 256.
+func (v *Element) fromBig(n *big.Int) *Element {
+	if n.BitLen() > 32*8 {
+		panic("edwards25519: invalid field element input size")
+	}
+
+	buf := make([]byte, 0, 32)
+	for _, word := range n.Bits() {
+		for i := 0; i < bits.UintSize; i += 8 {
+			if len(buf) >= cap(buf) {
+				break
+			}
+			buf = append(buf, byte(word))
+			word >>= 8
+		}
+	}
+
+	return v.SetBytes(buf[:32])
+}
+
+func (v *Element) fromDecimal(s string) *Element {
+	n, ok := new(big.Int).SetString(s, 10)
+	if !ok {
+		panic("not a valid decimal: " + s)
+	}
+	return v.fromBig(n)
+}
+
+// toBig returns v as a big.Int.
+func (v *Element) toBig() *big.Int {
+	buf := v.Bytes()
+
+	words := make([]big.Word, 32*8/bits.UintSize)
+	for n := range words {
+		for i := 0; i < bits.UintSize; i += 8 {
+			if len(buf) == 0 {
+				break
+			}
+			words[n] |= big.Word(buf[0]) << big.Word(i)
+			buf = buf[1:]
+		}
+	}
+
+	return new(big.Int).SetBits(words)
+}
+
+func TestDecimalConstants(t *testing.T) {
+	sqrtM1String := "19681161376707505956807079304988542015446066515923890162744021073123829784752"
+	if exp := new(Element).fromDecimal(sqrtM1String); sqrtM1.Equal(exp) != 1 {
+		t.Errorf("sqrtM1 is %v, expected %v", sqrtM1, exp)
+	}
+	// d is in the parent package, and we don't want to expose d or fromDecimal.
+	// dString := "37095705934669439343138083508754565189542113879843219016388785533085940283555"
+	// if exp := new(Element).fromDecimal(dString); d.Equal(exp) != 1 {
+	// 	t.Errorf("d is %v, expected %v", d, exp)
+	// }
+}
+
+func TestSetBytesRoundTripEdgeCases(t *testing.T) {
+	// TODO: values close to 0, close to 2^255-19, between 2^255-19 and 2^255-1,
+	// and between 2^255 and 2^256-1. Test both the documented SetBytes
+	// behavior, and that Bytes reduces them.
+}
+
+// Tests self-consistency between Multiply and Square.
+func TestConsistency(t *testing.T) {
+	var x Element
+	var x2, x2sq Element
+
+	x = Element{1, 1, 1, 1, 1}
+	x2.Multiply(&x, &x)
+	x2sq.Square(&x)
+
+	if x2 != x2sq {
+		t.Fatalf("all ones failed\nmul: %x\nsqr: %x\n", x2, x2sq)
+	}
+
+	var bytes [32]byte
+
+	_, err := io.ReadFull(rand.Reader, bytes[:])
+	if err != nil {
+		t.Fatal(err)
+	}
+	x.SetBytes(bytes[:])
+
+	x2.Multiply(&x, &x)
+	x2sq.Square(&x)
+
+	if x2 != x2sq {
+		t.Fatalf("all ones failed\nmul: %x\nsqr: %x\n", x2, x2sq)
+	}
+}
+
+func TestEqual(t *testing.T) {
+	x := Element{1, 1, 1, 1, 1}
+	y := Element{5, 4, 3, 2, 1}
+
+	eq := x.Equal(&x)
+	if eq != 1 {
+		t.Errorf("wrong about equality")
+	}
+
+	eq = x.Equal(&y)
+	if eq != 0 {
+		t.Errorf("wrong about inequality")
+	}
+}
+
+func TestInvert(t *testing.T) {
+	x := Element{1, 1, 1, 1, 1}
+	one := Element{1, 0, 0, 0, 0}
+	var xinv, r Element
+
+	xinv.Invert(&x)
+	r.Multiply(&x, &xinv)
+	r.reduce()
+
+	if one != r {
+		t.Errorf("inversion identity failed, got: %x", r)
+	}
+
+	var bytes [32]byte
+
+	_, err := io.ReadFull(rand.Reader, bytes[:])
+	if err != nil {
+		t.Fatal(err)
+	}
+	x.SetBytes(bytes[:])
+
+	xinv.Invert(&x)
+	r.Multiply(&x, &xinv)
+	r.reduce()
+
+	if one != r {
+		t.Errorf("random inversion identity failed, got: %x for field element %x", r, x)
+	}
+
+	zero := Element{}
+	x.Set(&zero)
+	if xx := xinv.Invert(&x); xx != &xinv {
+		t.Errorf("inverting zero did not return the receiver")
+	} else if xinv.Equal(&zero) != 1 {
+		t.Errorf("inverting zero did not return zero")
+	}
+}
+
+func TestSelectSwap(t *testing.T) {
+	a := Element{358744748052810, 1691584618240980, 977650209285361, 1429865912637724, 560044844278676}
+	b := Element{84926274344903, 473620666599931, 365590438845504, 1028470286882429, 2146499180330972}
+
+	var c, d Element
+
+	c.Select(&a, &b, 1)
+	d.Select(&a, &b, 0)
+
+	if c.Equal(&a) != 1 || d.Equal(&b) != 1 {
+		t.Errorf("Select failed")
+	}
+
+	c.Swap(&d, 0)
+
+	if c.Equal(&a) != 1 || d.Equal(&b) != 1 {
+		t.Errorf("Swap failed")
+	}
+
+	c.Swap(&d, 1)
+
+	if c.Equal(&b) != 1 || d.Equal(&a) != 1 {
+		t.Errorf("Swap failed")
+	}
+}
+
+func TestMult32(t *testing.T) {
+	mult32EquivalentToMul := func(x Element, y uint32) bool {
+		t1 := new(Element)
+		for i := 0; i < 100; i++ {
+			t1.Mult32(&x, y)
+		}
+
+		ty := new(Element)
+		ty.l0 = uint64(y)
+
+		t2 := new(Element)
+		for i := 0; i < 100; i++ {
+			t2.Multiply(&x, ty)
+		}
+
+		return t1.Equal(t2) == 1 && isInBounds(t1) && isInBounds(t2)
+	}
+
+	if err := quick.Check(mult32EquivalentToMul, quickCheckConfig1024); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestSqrtRatio(t *testing.T) {
+	// From draft-irtf-cfrg-ristretto255-decaf448-00, Appendix A.4.
+	type test struct {
+		u, v      string
+		wasSquare int
+		r         string
+	}
+	var tests = []test{
+		// If u is 0, the function is defined to return (0, TRUE), even if v
+		// is zero. Note that where used in this package, the denominator v
+		// is never zero.
+		{
+			"0000000000000000000000000000000000000000000000000000000000000000",
+			"0000000000000000000000000000000000000000000000000000000000000000",
+			1, "0000000000000000000000000000000000000000000000000000000000000000",
+		},
+		// 0/1 == 0²
+		{
+			"0000000000000000000000000000000000000000000000000000000000000000",
+			"0100000000000000000000000000000000000000000000000000000000000000",
+			1, "0000000000000000000000000000000000000000000000000000000000000000",
+		},
+		// If u is non-zero and v is zero, defined to return (0, FALSE).
+		{
+			"0100000000000000000000000000000000000000000000000000000000000000",
+			"0000000000000000000000000000000000000000000000000000000000000000",
+			0, "0000000000000000000000000000000000000000000000000000000000000000",
+		},
+		// 2/1 is not square in this field.
+		{
+			"0200000000000000000000000000000000000000000000000000000000000000",
+			"0100000000000000000000000000000000000000000000000000000000000000",
+			0, "3c5ff1b5d8e4113b871bd052f9e7bcd0582804c266ffb2d4f4203eb07fdb7c54",
+		},
+		// 4/1 == 2²
+		{
+			"0400000000000000000000000000000000000000000000000000000000000000",
+			"0100000000000000000000000000000000000000000000000000000000000000",
+			1, "0200000000000000000000000000000000000000000000000000000000000000",
+		},
+		// 1/4 == (2⁻¹)² == (2^(p-2))² per Euler's theorem
+		{
+			"0100000000000000000000000000000000000000000000000000000000000000",
+			"0400000000000000000000000000000000000000000000000000000000000000",
+			1, "f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f",
+		},
+	}
+
+	for i, tt := range tests {
+		u := new(Element).SetBytes(decodeHex(tt.u))
+		v := new(Element).SetBytes(decodeHex(tt.v))
+		want := new(Element).SetBytes(decodeHex(tt.r))
+		got, wasSquare := new(Element).SqrtRatio(u, v)
+		if got.Equal(want) == 0 || wasSquare != tt.wasSquare {
+			t.Errorf("%d: got (%v, %v), want (%v, %v)", i, got, wasSquare, want, tt.wasSquare)
+		}
+	}
+}
+
+func TestCarryPropagate(t *testing.T) {
+	asmLikeGeneric := func(a [5]uint64) bool {
+		t1 := &Element{a[0], a[1], a[2], a[3], a[4]}
+		t2 := &Element{a[0], a[1], a[2], a[3], a[4]}
+
+		t1.carryPropagate()
+		t2.carryPropagateGeneric()
+
+		if *t1 != *t2 {
+			t.Logf("got: %#v,\nexpected: %#v", t1, t2)
+		}
+
+		return *t1 == *t2 && isInBounds(t2)
+	}
+
+	if err := quick.Check(asmLikeGeneric, quickCheckConfig1024); err != nil {
+		t.Error(err)
+	}
+
+	if !asmLikeGeneric([5]uint64{0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}) {
+		t.Errorf("failed for {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}")
+	}
+}
+
+func TestFeSquare(t *testing.T) {
+	asmLikeGeneric := func(a Element) bool {
+		t1 := a
+		t2 := a
+
+		feSquareGeneric(&t1, &t1)
+		feSquare(&t2, &t2)
+
+		if t1 != t2 {
+			t.Logf("got: %#v,\nexpected: %#v", t1, t2)
+		}
+
+		return t1 == t2 && isInBounds(&t2)
+	}
+
+	if err := quick.Check(asmLikeGeneric, quickCheckConfig1024); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestFeMul(t *testing.T) {
+	asmLikeGeneric := func(a, b Element) bool {
+		a1 := a
+		a2 := a
+		b1 := b
+		b2 := b
+
+		feMulGeneric(&a1, &a1, &b1)
+		feMul(&a2, &a2, &b2)
+
+		if a1 != a2 || b1 != b2 {
+			t.Logf("got: %#v,\nexpected: %#v", a1, a2)
+			t.Logf("got: %#v,\nexpected: %#v", b1, b2)
+		}
+
+		return a1 == a2 && isInBounds(&a2) &&
+			b1 == b2 && isInBounds(&b2)
+	}
+
+	if err := quick.Check(asmLikeGeneric, quickCheckConfig1024); err != nil {
+		t.Error(err)
+	}
+}
+
+func decodeHex(s string) []byte {
+	b, err := hex.DecodeString(s)
+	if err != nil {
+		panic(err)
+	}
+	return b
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/scalar.go b/src/crypto/ed25519/internal/edwards25519/scalar.go
new file mode 100644
index 0000000..889acaa
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/scalar.go
@@ -0,0 +1,1025 @@
+// Copyright (c) 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 edwards25519
+
+import (
+	"crypto/subtle"
+	"encoding/binary"
+	"errors"
+)
+
+// A Scalar is an integer modulo
+//
+//     l = 2^252 + 27742317777372353535851937790883648493
+//
+// which is the prime order of the edwards25519 group.
+//
+// This type works similarly to math/big.Int, and all arguments and
+// receivers are allowed to alias.
+//
+// The zero value is a valid zero element.
+type Scalar struct {
+	// s is the Scalar value in little-endian. The value is always reduced
+	// between operations.
+	s [32]byte
+}
+
+var (
+	scZero = Scalar{[32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+
+	scOne = Scalar{[32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+
+	scMinusOne = Scalar{[32]byte{236, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16}}
+)
+
+// NewScalar returns a new zero Scalar.
+func NewScalar() *Scalar {
+	return &Scalar{}
+}
+
+// MultiplyAdd sets s = x * y + z mod l, and returns s.
+func (s *Scalar) MultiplyAdd(x, y, z *Scalar) *Scalar {
+	scMulAdd(&s.s, &x.s, &y.s, &z.s)
+	return s
+}
+
+// Add sets s = x + y mod l, and returns s.
+func (s *Scalar) Add(x, y *Scalar) *Scalar {
+	// s = 1 * x + y mod l
+	scMulAdd(&s.s, &scOne.s, &x.s, &y.s)
+	return s
+}
+
+// Subtract sets s = x - y mod l, and returns s.
+func (s *Scalar) Subtract(x, y *Scalar) *Scalar {
+	// s = -1 * y + x mod l
+	scMulAdd(&s.s, &scMinusOne.s, &y.s, &x.s)
+	return s
+}
+
+// Negate sets s = -x mod l, and returns s.
+func (s *Scalar) Negate(x *Scalar) *Scalar {
+	// s = -1 * x + 0 mod l
+	scMulAdd(&s.s, &scMinusOne.s, &x.s, &scZero.s)
+	return s
+}
+
+// Multiply sets s = x * y mod l, and returns s.
+func (s *Scalar) Multiply(x, y *Scalar) *Scalar {
+	// s = x * y + 0 mod l
+	scMulAdd(&s.s, &x.s, &y.s, &scZero.s)
+	return s
+}
+
+// Set sets s = x, and returns s.
+func (s *Scalar) Set(x *Scalar) *Scalar {
+	*s = *x
+	return s
+}
+
+// SetUniformBytes sets s to an uniformly distributed value given 64 uniformly
+// distributed random bytes.
+func (s *Scalar) SetUniformBytes(x []byte) *Scalar {
+	if len(x) != 64 {
+		panic("edwards25519: invalid SetUniformBytes input length")
+	}
+	var wideBytes [64]byte
+	copy(wideBytes[:], x[:])
+	scReduce(&s.s, &wideBytes)
+	return s
+}
+
+// SetCanonicalBytes sets s = x, where x is a 32-byte little-endian encoding of
+// s, and returns s. If x is not a canonical encoding of s, SetCanonicalBytes
+// returns nil and an error, and the receiver is unchanged.
+func (s *Scalar) SetCanonicalBytes(x []byte) (*Scalar, error) {
+	if len(x) != 32 {
+		return nil, errors.New("invalid scalar length")
+	}
+	ss := &Scalar{}
+	copy(ss.s[:], x)
+	if !isReduced(ss) {
+		return nil, errors.New("invalid scalar encoding")
+	}
+	s.s = ss.s
+	return s, nil
+}
+
+// isReduced returns whether the given scalar is reduced modulo l.
+func isReduced(s *Scalar) bool {
+	for i := len(s.s) - 1; i >= 0; i-- {
+		switch {
+		case s.s[i] > scMinusOne.s[i]:
+			return false
+		case s.s[i] < scMinusOne.s[i]:
+			return true
+		}
+	}
+	return true
+}
+
+// SetBytesWithClamping applies the buffer pruning described in RFC 8032,
+// Section 5.1.5 (also known as clamping) and sets s to the result. The input
+// must be 32 bytes, and it is not modified.
+//
+// Note that since Scalar values are always reduced modulo the prime order of
+// the curve, the resulting value will not preserve any of the cofactor-clearing
+// properties that clamping is meant to provide. It will however work as
+// expected as long as it is applied to points on the prime order subgroup, like
+// in Ed25519. In fact, it is lost to history why RFC 8032 adopted the
+// irrelevant RFC 7748 clamping, but it is now required for compatibility.
+func (s *Scalar) SetBytesWithClamping(x []byte) *Scalar {
+	// The description above omits the purpose of the high bits of the clamping
+	// for brevity, but those are also lost to reductions, and are also
+	// irrelevant to edwards25519 as they protect against a specific
+	// implementation bug that was once observed in a generic Montgomery ladder.
+	if len(x) != 32 {
+		panic("edwards25519: invalid SetBytesWithClamping input length")
+	}
+	var wideBytes [64]byte
+	copy(wideBytes[:], x[:])
+	wideBytes[0] &= 248
+	wideBytes[31] &= 63
+	wideBytes[31] |= 64
+	scReduce(&s.s, &wideBytes)
+	return s
+}
+
+// Bytes returns the canonical 32-byte little-endian encoding of s.
+func (s *Scalar) Bytes() []byte {
+	buf := make([]byte, 32)
+	copy(buf, s.s[:])
+	return buf
+}
+
+// Equal returns 1 if s and t are equal, and 0 otherwise.
+func (s *Scalar) Equal(t *Scalar) int {
+	return subtle.ConstantTimeCompare(s.s[:], t.s[:])
+}
+
+// scMulAdd and scReduce are ported from the public domain, “ref10”
+// implementation of ed25519 from SUPERCOP.
+
+func load3(in []byte) int64 {
+	r := int64(in[0])
+	r |= int64(in[1]) << 8
+	r |= int64(in[2]) << 16
+	return r
+}
+
+func load4(in []byte) int64 {
+	r := int64(in[0])
+	r |= int64(in[1]) << 8
+	r |= int64(in[2]) << 16
+	r |= int64(in[3]) << 24
+	return r
+}
+
+// Input:
+//   a[0]+256*a[1]+...+256^31*a[31] = a
+//   b[0]+256*b[1]+...+256^31*b[31] = b
+//   c[0]+256*c[1]+...+256^31*c[31] = c
+//
+// Output:
+//   s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
+//   where l = 2^252 + 27742317777372353535851937790883648493.
+func scMulAdd(s, a, b, c *[32]byte) {
+	a0 := 2097151 & load3(a[:])
+	a1 := 2097151 & (load4(a[2:]) >> 5)
+	a2 := 2097151 & (load3(a[5:]) >> 2)
+	a3 := 2097151 & (load4(a[7:]) >> 7)
+	a4 := 2097151 & (load4(a[10:]) >> 4)
+	a5 := 2097151 & (load3(a[13:]) >> 1)
+	a6 := 2097151 & (load4(a[15:]) >> 6)
+	a7 := 2097151 & (load3(a[18:]) >> 3)
+	a8 := 2097151 & load3(a[21:])
+	a9 := 2097151 & (load4(a[23:]) >> 5)
+	a10 := 2097151 & (load3(a[26:]) >> 2)
+	a11 := (load4(a[28:]) >> 7)
+	b0 := 2097151 & load3(b[:])
+	b1 := 2097151 & (load4(b[2:]) >> 5)
+	b2 := 2097151 & (load3(b[5:]) >> 2)
+	b3 := 2097151 & (load4(b[7:]) >> 7)
+	b4 := 2097151 & (load4(b[10:]) >> 4)
+	b5 := 2097151 & (load3(b[13:]) >> 1)
+	b6 := 2097151 & (load4(b[15:]) >> 6)
+	b7 := 2097151 & (load3(b[18:]) >> 3)
+	b8 := 2097151 & load3(b[21:])
+	b9 := 2097151 & (load4(b[23:]) >> 5)
+	b10 := 2097151 & (load3(b[26:]) >> 2)
+	b11 := (load4(b[28:]) >> 7)
+	c0 := 2097151 & load3(c[:])
+	c1 := 2097151 & (load4(c[2:]) >> 5)
+	c2 := 2097151 & (load3(c[5:]) >> 2)
+	c3 := 2097151 & (load4(c[7:]) >> 7)
+	c4 := 2097151 & (load4(c[10:]) >> 4)
+	c5 := 2097151 & (load3(c[13:]) >> 1)
+	c6 := 2097151 & (load4(c[15:]) >> 6)
+	c7 := 2097151 & (load3(c[18:]) >> 3)
+	c8 := 2097151 & load3(c[21:])
+	c9 := 2097151 & (load4(c[23:]) >> 5)
+	c10 := 2097151 & (load3(c[26:]) >> 2)
+	c11 := (load4(c[28:]) >> 7)
+	var carry [23]int64
+
+	s0 := c0 + a0*b0
+	s1 := c1 + a0*b1 + a1*b0
+	s2 := c2 + a0*b2 + a1*b1 + a2*b0
+	s3 := c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0
+	s4 := c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0
+	s5 := c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0
+	s6 := c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0
+	s7 := c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0
+	s8 := c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0
+	s9 := c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0
+	s10 := c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0
+	s11 := c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0
+	s12 := a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1
+	s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2
+	s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3
+	s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4
+	s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5
+	s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6
+	s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7
+	s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8
+	s20 := a9*b11 + a10*b10 + a11*b9
+	s21 := a10*b11 + a11*b10
+	s22 := a11 * b11
+	s23 := int64(0)
+
+	carry[0] = (s0 + (1 << 20)) >> 21
+	s1 += carry[0]
+	s0 -= carry[0] << 21
+	carry[2] = (s2 + (1 << 20)) >> 21
+	s3 += carry[2]
+	s2 -= carry[2] << 21
+	carry[4] = (s4 + (1 << 20)) >> 21
+	s5 += carry[4]
+	s4 -= carry[4] << 21
+	carry[6] = (s6 + (1 << 20)) >> 21
+	s7 += carry[6]
+	s6 -= carry[6] << 21
+	carry[8] = (s8 + (1 << 20)) >> 21
+	s9 += carry[8]
+	s8 -= carry[8] << 21
+	carry[10] = (s10 + (1 << 20)) >> 21
+	s11 += carry[10]
+	s10 -= carry[10] << 21
+	carry[12] = (s12 + (1 << 20)) >> 21
+	s13 += carry[12]
+	s12 -= carry[12] << 21
+	carry[14] = (s14 + (1 << 20)) >> 21
+	s15 += carry[14]
+	s14 -= carry[14] << 21
+	carry[16] = (s16 + (1 << 20)) >> 21
+	s17 += carry[16]
+	s16 -= carry[16] << 21
+	carry[18] = (s18 + (1 << 20)) >> 21
+	s19 += carry[18]
+	s18 -= carry[18] << 21
+	carry[20] = (s20 + (1 << 20)) >> 21
+	s21 += carry[20]
+	s20 -= carry[20] << 21
+	carry[22] = (s22 + (1 << 20)) >> 21
+	s23 += carry[22]
+	s22 -= carry[22] << 21
+
+	carry[1] = (s1 + (1 << 20)) >> 21
+	s2 += carry[1]
+	s1 -= carry[1] << 21
+	carry[3] = (s3 + (1 << 20)) >> 21
+	s4 += carry[3]
+	s3 -= carry[3] << 21
+	carry[5] = (s5 + (1 << 20)) >> 21
+	s6 += carry[5]
+	s5 -= carry[5] << 21
+	carry[7] = (s7 + (1 << 20)) >> 21
+	s8 += carry[7]
+	s7 -= carry[7] << 21
+	carry[9] = (s9 + (1 << 20)) >> 21
+	s10 += carry[9]
+	s9 -= carry[9] << 21
+	carry[11] = (s11 + (1 << 20)) >> 21
+	s12 += carry[11]
+	s11 -= carry[11] << 21
+	carry[13] = (s13 + (1 << 20)) >> 21
+	s14 += carry[13]
+	s13 -= carry[13] << 21
+	carry[15] = (s15 + (1 << 20)) >> 21
+	s16 += carry[15]
+	s15 -= carry[15] << 21
+	carry[17] = (s17 + (1 << 20)) >> 21
+	s18 += carry[17]
+	s17 -= carry[17] << 21
+	carry[19] = (s19 + (1 << 20)) >> 21
+	s20 += carry[19]
+	s19 -= carry[19] << 21
+	carry[21] = (s21 + (1 << 20)) >> 21
+	s22 += carry[21]
+	s21 -= carry[21] << 21
+
+	s11 += s23 * 666643
+	s12 += s23 * 470296
+	s13 += s23 * 654183
+	s14 -= s23 * 997805
+	s15 += s23 * 136657
+	s16 -= s23 * 683901
+	s23 = 0
+
+	s10 += s22 * 666643
+	s11 += s22 * 470296
+	s12 += s22 * 654183
+	s13 -= s22 * 997805
+	s14 += s22 * 136657
+	s15 -= s22 * 683901
+	s22 = 0
+
+	s9 += s21 * 666643
+	s10 += s21 * 470296
+	s11 += s21 * 654183
+	s12 -= s21 * 997805
+	s13 += s21 * 136657
+	s14 -= s21 * 683901
+	s21 = 0
+
+	s8 += s20 * 666643
+	s9 += s20 * 470296
+	s10 += s20 * 654183
+	s11 -= s20 * 997805
+	s12 += s20 * 136657
+	s13 -= s20 * 683901
+	s20 = 0
+
+	s7 += s19 * 666643
+	s8 += s19 * 470296
+	s9 += s19 * 654183
+	s10 -= s19 * 997805
+	s11 += s19 * 136657
+	s12 -= s19 * 683901
+	s19 = 0
+
+	s6 += s18 * 666643
+	s7 += s18 * 470296
+	s8 += s18 * 654183
+	s9 -= s18 * 997805
+	s10 += s18 * 136657
+	s11 -= s18 * 683901
+	s18 = 0
+
+	carry[6] = (s6 + (1 << 20)) >> 21
+	s7 += carry[6]
+	s6 -= carry[6] << 21
+	carry[8] = (s8 + (1 << 20)) >> 21
+	s9 += carry[8]
+	s8 -= carry[8] << 21
+	carry[10] = (s10 + (1 << 20)) >> 21
+	s11 += carry[10]
+	s10 -= carry[10] << 21
+	carry[12] = (s12 + (1 << 20)) >> 21
+	s13 += carry[12]
+	s12 -= carry[12] << 21
+	carry[14] = (s14 + (1 << 20)) >> 21
+	s15 += carry[14]
+	s14 -= carry[14] << 21
+	carry[16] = (s16 + (1 << 20)) >> 21
+	s17 += carry[16]
+	s16 -= carry[16] << 21
+
+	carry[7] = (s7 + (1 << 20)) >> 21
+	s8 += carry[7]
+	s7 -= carry[7] << 21
+	carry[9] = (s9 + (1 << 20)) >> 21
+	s10 += carry[9]
+	s9 -= carry[9] << 21
+	carry[11] = (s11 + (1 << 20)) >> 21
+	s12 += carry[11]
+	s11 -= carry[11] << 21
+	carry[13] = (s13 + (1 << 20)) >> 21
+	s14 += carry[13]
+	s13 -= carry[13] << 21
+	carry[15] = (s15 + (1 << 20)) >> 21
+	s16 += carry[15]
+	s15 -= carry[15] << 21
+
+	s5 += s17 * 666643
+	s6 += s17 * 470296
+	s7 += s17 * 654183
+	s8 -= s17 * 997805
+	s9 += s17 * 136657
+	s10 -= s17 * 683901
+	s17 = 0
+
+	s4 += s16 * 666643
+	s5 += s16 * 470296
+	s6 += s16 * 654183
+	s7 -= s16 * 997805
+	s8 += s16 * 136657
+	s9 -= s16 * 683901
+	s16 = 0
+
+	s3 += s15 * 666643
+	s4 += s15 * 470296
+	s5 += s15 * 654183
+	s6 -= s15 * 997805
+	s7 += s15 * 136657
+	s8 -= s15 * 683901
+	s15 = 0
+
+	s2 += s14 * 666643
+	s3 += s14 * 470296
+	s4 += s14 * 654183
+	s5 -= s14 * 997805
+	s6 += s14 * 136657
+	s7 -= s14 * 683901
+	s14 = 0
+
+	s1 += s13 * 666643
+	s2 += s13 * 470296
+	s3 += s13 * 654183
+	s4 -= s13 * 997805
+	s5 += s13 * 136657
+	s6 -= s13 * 683901
+	s13 = 0
+
+	s0 += s12 * 666643
+	s1 += s12 * 470296
+	s2 += s12 * 654183
+	s3 -= s12 * 997805
+	s4 += s12 * 136657
+	s5 -= s12 * 683901
+	s12 = 0
+
+	carry[0] = (s0 + (1 << 20)) >> 21
+	s1 += carry[0]
+	s0 -= carry[0] << 21
+	carry[2] = (s2 + (1 << 20)) >> 21
+	s3 += carry[2]
+	s2 -= carry[2] << 21
+	carry[4] = (s4 + (1 << 20)) >> 21
+	s5 += carry[4]
+	s4 -= carry[4] << 21
+	carry[6] = (s6 + (1 << 20)) >> 21
+	s7 += carry[6]
+	s6 -= carry[6] << 21
+	carry[8] = (s8 + (1 << 20)) >> 21
+	s9 += carry[8]
+	s8 -= carry[8] << 21
+	carry[10] = (s10 + (1 << 20)) >> 21
+	s11 += carry[10]
+	s10 -= carry[10] << 21
+
+	carry[1] = (s1 + (1 << 20)) >> 21
+	s2 += carry[1]
+	s1 -= carry[1] << 21
+	carry[3] = (s3 + (1 << 20)) >> 21
+	s4 += carry[3]
+	s3 -= carry[3] << 21
+	carry[5] = (s5 + (1 << 20)) >> 21
+	s6 += carry[5]
+	s5 -= carry[5] << 21
+	carry[7] = (s7 + (1 << 20)) >> 21
+	s8 += carry[7]
+	s7 -= carry[7] << 21
+	carry[9] = (s9 + (1 << 20)) >> 21
+	s10 += carry[9]
+	s9 -= carry[9] << 21
+	carry[11] = (s11 + (1 << 20)) >> 21
+	s12 += carry[11]
+	s11 -= carry[11] << 21
+
+	s0 += s12 * 666643
+	s1 += s12 * 470296
+	s2 += s12 * 654183
+	s3 -= s12 * 997805
+	s4 += s12 * 136657
+	s5 -= s12 * 683901
+	s12 = 0
+
+	carry[0] = s0 >> 21
+	s1 += carry[0]
+	s0 -= carry[0] << 21
+	carry[1] = s1 >> 21
+	s2 += carry[1]
+	s1 -= carry[1] << 21
+	carry[2] = s2 >> 21
+	s3 += carry[2]
+	s2 -= carry[2] << 21
+	carry[3] = s3 >> 21
+	s4 += carry[3]
+	s3 -= carry[3] << 21
+	carry[4] = s4 >> 21
+	s5 += carry[4]
+	s4 -= carry[4] << 21
+	carry[5] = s5 >> 21
+	s6 += carry[5]
+	s5 -= carry[5] << 21
+	carry[6] = s6 >> 21
+	s7 += carry[6]
+	s6 -= carry[6] << 21
+	carry[7] = s7 >> 21
+	s8 += carry[7]
+	s7 -= carry[7] << 21
+	carry[8] = s8 >> 21
+	s9 += carry[8]
+	s8 -= carry[8] << 21
+	carry[9] = s9 >> 21
+	s10 += carry[9]
+	s9 -= carry[9] << 21
+	carry[10] = s10 >> 21
+	s11 += carry[10]
+	s10 -= carry[10] << 21
+	carry[11] = s11 >> 21
+	s12 += carry[11]
+	s11 -= carry[11] << 21
+
+	s0 += s12 * 666643
+	s1 += s12 * 470296
+	s2 += s12 * 654183
+	s3 -= s12 * 997805
+	s4 += s12 * 136657
+	s5 -= s12 * 683901
+	s12 = 0
+
+	carry[0] = s0 >> 21
+	s1 += carry[0]
+	s0 -= carry[0] << 21
+	carry[1] = s1 >> 21
+	s2 += carry[1]
+	s1 -= carry[1] << 21
+	carry[2] = s2 >> 21
+	s3 += carry[2]
+	s2 -= carry[2] << 21
+	carry[3] = s3 >> 21
+	s4 += carry[3]
+	s3 -= carry[3] << 21
+	carry[4] = s4 >> 21
+	s5 += carry[4]
+	s4 -= carry[4] << 21
+	carry[5] = s5 >> 21
+	s6 += carry[5]
+	s5 -= carry[5] << 21
+	carry[6] = s6 >> 21
+	s7 += carry[6]
+	s6 -= carry[6] << 21
+	carry[7] = s7 >> 21
+	s8 += carry[7]
+	s7 -= carry[7] << 21
+	carry[8] = s8 >> 21
+	s9 += carry[8]
+	s8 -= carry[8] << 21
+	carry[9] = s9 >> 21
+	s10 += carry[9]
+	s9 -= carry[9] << 21
+	carry[10] = s10 >> 21
+	s11 += carry[10]
+	s10 -= carry[10] << 21
+
+	s[0] = byte(s0 >> 0)
+	s[1] = byte(s0 >> 8)
+	s[2] = byte((s0 >> 16) | (s1 << 5))
+	s[3] = byte(s1 >> 3)
+	s[4] = byte(s1 >> 11)
+	s[5] = byte((s1 >> 19) | (s2 << 2))
+	s[6] = byte(s2 >> 6)
+	s[7] = byte((s2 >> 14) | (s3 << 7))
+	s[8] = byte(s3 >> 1)
+	s[9] = byte(s3 >> 9)
+	s[10] = byte((s3 >> 17) | (s4 << 4))
+	s[11] = byte(s4 >> 4)
+	s[12] = byte(s4 >> 12)
+	s[13] = byte((s4 >> 20) | (s5 << 1))
+	s[14] = byte(s5 >> 7)
+	s[15] = byte((s5 >> 15) | (s6 << 6))
+	s[16] = byte(s6 >> 2)
+	s[17] = byte(s6 >> 10)
+	s[18] = byte((s6 >> 18) | (s7 << 3))
+	s[19] = byte(s7 >> 5)
+	s[20] = byte(s7 >> 13)
+	s[21] = byte(s8 >> 0)
+	s[22] = byte(s8 >> 8)
+	s[23] = byte((s8 >> 16) | (s9 << 5))
+	s[24] = byte(s9 >> 3)
+	s[25] = byte(s9 >> 11)
+	s[26] = byte((s9 >> 19) | (s10 << 2))
+	s[27] = byte(s10 >> 6)
+	s[28] = byte((s10 >> 14) | (s11 << 7))
+	s[29] = byte(s11 >> 1)
+	s[30] = byte(s11 >> 9)
+	s[31] = byte(s11 >> 17)
+}
+
+// Input:
+//   s[0]+256*s[1]+...+256^63*s[63] = s
+//
+// Output:
+//   s[0]+256*s[1]+...+256^31*s[31] = s mod l
+//   where l = 2^252 + 27742317777372353535851937790883648493.
+func scReduce(out *[32]byte, s *[64]byte) {
+	s0 := 2097151 & load3(s[:])
+	s1 := 2097151 & (load4(s[2:]) >> 5)
+	s2 := 2097151 & (load3(s[5:]) >> 2)
+	s3 := 2097151 & (load4(s[7:]) >> 7)
+	s4 := 2097151 & (load4(s[10:]) >> 4)
+	s5 := 2097151 & (load3(s[13:]) >> 1)
+	s6 := 2097151 & (load4(s[15:]) >> 6)
+	s7 := 2097151 & (load3(s[18:]) >> 3)
+	s8 := 2097151 & load3(s[21:])
+	s9 := 2097151 & (load4(s[23:]) >> 5)
+	s10 := 2097151 & (load3(s[26:]) >> 2)
+	s11 := 2097151 & (load4(s[28:]) >> 7)
+	s12 := 2097151 & (load4(s[31:]) >> 4)
+	s13 := 2097151 & (load3(s[34:]) >> 1)
+	s14 := 2097151 & (load4(s[36:]) >> 6)
+	s15 := 2097151 & (load3(s[39:]) >> 3)
+	s16 := 2097151 & load3(s[42:])
+	s17 := 2097151 & (load4(s[44:]) >> 5)
+	s18 := 2097151 & (load3(s[47:]) >> 2)
+	s19 := 2097151 & (load4(s[49:]) >> 7)
+	s20 := 2097151 & (load4(s[52:]) >> 4)
+	s21 := 2097151 & (load3(s[55:]) >> 1)
+	s22 := 2097151 & (load4(s[57:]) >> 6)
+	s23 := (load4(s[60:]) >> 3)
+
+	s11 += s23 * 666643
+	s12 += s23 * 470296
+	s13 += s23 * 654183
+	s14 -= s23 * 997805
+	s15 += s23 * 136657
+	s16 -= s23 * 683901
+	s23 = 0
+
+	s10 += s22 * 666643
+	s11 += s22 * 470296
+	s12 += s22 * 654183
+	s13 -= s22 * 997805
+	s14 += s22 * 136657
+	s15 -= s22 * 683901
+	s22 = 0
+
+	s9 += s21 * 666643
+	s10 += s21 * 470296
+	s11 += s21 * 654183
+	s12 -= s21 * 997805
+	s13 += s21 * 136657
+	s14 -= s21 * 683901
+	s21 = 0
+
+	s8 += s20 * 666643
+	s9 += s20 * 470296
+	s10 += s20 * 654183
+	s11 -= s20 * 997805
+	s12 += s20 * 136657
+	s13 -= s20 * 683901
+	s20 = 0
+
+	s7 += s19 * 666643
+	s8 += s19 * 470296
+	s9 += s19 * 654183
+	s10 -= s19 * 997805
+	s11 += s19 * 136657
+	s12 -= s19 * 683901
+	s19 = 0
+
+	s6 += s18 * 666643
+	s7 += s18 * 470296
+	s8 += s18 * 654183
+	s9 -= s18 * 997805
+	s10 += s18 * 136657
+	s11 -= s18 * 683901
+	s18 = 0
+
+	var carry [17]int64
+
+	carry[6] = (s6 + (1 << 20)) >> 21
+	s7 += carry[6]
+	s6 -= carry[6] << 21
+	carry[8] = (s8 + (1 << 20)) >> 21
+	s9 += carry[8]
+	s8 -= carry[8] << 21
+	carry[10] = (s10 + (1 << 20)) >> 21
+	s11 += carry[10]
+	s10 -= carry[10] << 21
+	carry[12] = (s12 + (1 << 20)) >> 21
+	s13 += carry[12]
+	s12 -= carry[12] << 21
+	carry[14] = (s14 + (1 << 20)) >> 21
+	s15 += carry[14]
+	s14 -= carry[14] << 21
+	carry[16] = (s16 + (1 << 20)) >> 21
+	s17 += carry[16]
+	s16 -= carry[16] << 21
+
+	carry[7] = (s7 + (1 << 20)) >> 21
+	s8 += carry[7]
+	s7 -= carry[7] << 21
+	carry[9] = (s9 + (1 << 20)) >> 21
+	s10 += carry[9]
+	s9 -= carry[9] << 21
+	carry[11] = (s11 + (1 << 20)) >> 21
+	s12 += carry[11]
+	s11 -= carry[11] << 21
+	carry[13] = (s13 + (1 << 20)) >> 21
+	s14 += carry[13]
+	s13 -= carry[13] << 21
+	carry[15] = (s15 + (1 << 20)) >> 21
+	s16 += carry[15]
+	s15 -= carry[15] << 21
+
+	s5 += s17 * 666643
+	s6 += s17 * 470296
+	s7 += s17 * 654183
+	s8 -= s17 * 997805
+	s9 += s17 * 136657
+	s10 -= s17 * 683901
+	s17 = 0
+
+	s4 += s16 * 666643
+	s5 += s16 * 470296
+	s6 += s16 * 654183
+	s7 -= s16 * 997805
+	s8 += s16 * 136657
+	s9 -= s16 * 683901
+	s16 = 0
+
+	s3 += s15 * 666643
+	s4 += s15 * 470296
+	s5 += s15 * 654183
+	s6 -= s15 * 997805
+	s7 += s15 * 136657
+	s8 -= s15 * 683901
+	s15 = 0
+
+	s2 += s14 * 666643
+	s3 += s14 * 470296
+	s4 += s14 * 654183
+	s5 -= s14 * 997805
+	s6 += s14 * 136657
+	s7 -= s14 * 683901
+	s14 = 0
+
+	s1 += s13 * 666643
+	s2 += s13 * 470296
+	s3 += s13 * 654183
+	s4 -= s13 * 997805
+	s5 += s13 * 136657
+	s6 -= s13 * 683901
+	s13 = 0
+
+	s0 += s12 * 666643
+	s1 += s12 * 470296
+	s2 += s12 * 654183
+	s3 -= s12 * 997805
+	s4 += s12 * 136657
+	s5 -= s12 * 683901
+	s12 = 0
+
+	carry[0] = (s0 + (1 << 20)) >> 21
+	s1 += carry[0]
+	s0 -= carry[0] << 21
+	carry[2] = (s2 + (1 << 20)) >> 21
+	s3 += carry[2]
+	s2 -= carry[2] << 21
+	carry[4] = (s4 + (1 << 20)) >> 21
+	s5 += carry[4]
+	s4 -= carry[4] << 21
+	carry[6] = (s6 + (1 << 20)) >> 21
+	s7 += carry[6]
+	s6 -= carry[6] << 21
+	carry[8] = (s8 + (1 << 20)) >> 21
+	s9 += carry[8]
+	s8 -= carry[8] << 21
+	carry[10] = (s10 + (1 << 20)) >> 21
+	s11 += carry[10]
+	s10 -= carry[10] << 21
+
+	carry[1] = (s1 + (1 << 20)) >> 21
+	s2 += carry[1]
+	s1 -= carry[1] << 21
+	carry[3] = (s3 + (1 << 20)) >> 21
+	s4 += carry[3]
+	s3 -= carry[3] << 21
+	carry[5] = (s5 + (1 << 20)) >> 21
+	s6 += carry[5]
+	s5 -= carry[5] << 21
+	carry[7] = (s7 + (1 << 20)) >> 21
+	s8 += carry[7]
+	s7 -= carry[7] << 21
+	carry[9] = (s9 + (1 << 20)) >> 21
+	s10 += carry[9]
+	s9 -= carry[9] << 21
+	carry[11] = (s11 + (1 << 20)) >> 21
+	s12 += carry[11]
+	s11 -= carry[11] << 21
+
+	s0 += s12 * 666643
+	s1 += s12 * 470296
+	s2 += s12 * 654183
+	s3 -= s12 * 997805
+	s4 += s12 * 136657
+	s5 -= s12 * 683901
+	s12 = 0
+
+	carry[0] = s0 >> 21
+	s1 += carry[0]
+	s0 -= carry[0] << 21
+	carry[1] = s1 >> 21
+	s2 += carry[1]
+	s1 -= carry[1] << 21
+	carry[2] = s2 >> 21
+	s3 += carry[2]
+	s2 -= carry[2] << 21
+	carry[3] = s3 >> 21
+	s4 += carry[3]
+	s3 -= carry[3] << 21
+	carry[4] = s4 >> 21
+	s5 += carry[4]
+	s4 -= carry[4] << 21
+	carry[5] = s5 >> 21
+	s6 += carry[5]
+	s5 -= carry[5] << 21
+	carry[6] = s6 >> 21
+	s7 += carry[6]
+	s6 -= carry[6] << 21
+	carry[7] = s7 >> 21
+	s8 += carry[7]
+	s7 -= carry[7] << 21
+	carry[8] = s8 >> 21
+	s9 += carry[8]
+	s8 -= carry[8] << 21
+	carry[9] = s9 >> 21
+	s10 += carry[9]
+	s9 -= carry[9] << 21
+	carry[10] = s10 >> 21
+	s11 += carry[10]
+	s10 -= carry[10] << 21
+	carry[11] = s11 >> 21
+	s12 += carry[11]
+	s11 -= carry[11] << 21
+
+	s0 += s12 * 666643
+	s1 += s12 * 470296
+	s2 += s12 * 654183
+	s3 -= s12 * 997805
+	s4 += s12 * 136657
+	s5 -= s12 * 683901
+	s12 = 0
+
+	carry[0] = s0 >> 21
+	s1 += carry[0]
+	s0 -= carry[0] << 21
+	carry[1] = s1 >> 21
+	s2 += carry[1]
+	s1 -= carry[1] << 21
+	carry[2] = s2 >> 21
+	s3 += carry[2]
+	s2 -= carry[2] << 21
+	carry[3] = s3 >> 21
+	s4 += carry[3]
+	s3 -= carry[3] << 21
+	carry[4] = s4 >> 21
+	s5 += carry[4]
+	s4 -= carry[4] << 21
+	carry[5] = s5 >> 21
+	s6 += carry[5]
+	s5 -= carry[5] << 21
+	carry[6] = s6 >> 21
+	s7 += carry[6]
+	s6 -= carry[6] << 21
+	carry[7] = s7 >> 21
+	s8 += carry[7]
+	s7 -= carry[7] << 21
+	carry[8] = s8 >> 21
+	s9 += carry[8]
+	s8 -= carry[8] << 21
+	carry[9] = s9 >> 21
+	s10 += carry[9]
+	s9 -= carry[9] << 21
+	carry[10] = s10 >> 21
+	s11 += carry[10]
+	s10 -= carry[10] << 21
+
+	out[0] = byte(s0 >> 0)
+	out[1] = byte(s0 >> 8)
+	out[2] = byte((s0 >> 16) | (s1 << 5))
+	out[3] = byte(s1 >> 3)
+	out[4] = byte(s1 >> 11)
+	out[5] = byte((s1 >> 19) | (s2 << 2))
+	out[6] = byte(s2 >> 6)
+	out[7] = byte((s2 >> 14) | (s3 << 7))
+	out[8] = byte(s3 >> 1)
+	out[9] = byte(s3 >> 9)
+	out[10] = byte((s3 >> 17) | (s4 << 4))
+	out[11] = byte(s4 >> 4)
+	out[12] = byte(s4 >> 12)
+	out[13] = byte((s4 >> 20) | (s5 << 1))
+	out[14] = byte(s5 >> 7)
+	out[15] = byte((s5 >> 15) | (s6 << 6))
+	out[16] = byte(s6 >> 2)
+	out[17] = byte(s6 >> 10)
+	out[18] = byte((s6 >> 18) | (s7 << 3))
+	out[19] = byte(s7 >> 5)
+	out[20] = byte(s7 >> 13)
+	out[21] = byte(s8 >> 0)
+	out[22] = byte(s8 >> 8)
+	out[23] = byte((s8 >> 16) | (s9 << 5))
+	out[24] = byte(s9 >> 3)
+	out[25] = byte(s9 >> 11)
+	out[26] = byte((s9 >> 19) | (s10 << 2))
+	out[27] = byte(s10 >> 6)
+	out[28] = byte((s10 >> 14) | (s11 << 7))
+	out[29] = byte(s11 >> 1)
+	out[30] = byte(s11 >> 9)
+	out[31] = byte(s11 >> 17)
+}
+
+// nonAdjacentForm computes a width-w non-adjacent form for this scalar.
+//
+// w must be between 2 and 8, or nonAdjacentForm will panic.
+func (s *Scalar) nonAdjacentForm(w uint) [256]int8 {
+	// This implementation is adapted from the one
+	// in curve25519-dalek and is documented there:
+	// https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871
+	if s.s[31] > 127 {
+		panic("scalar has high bit set illegally")
+	}
+	if w < 2 {
+		panic("w must be at least 2 by the definition of NAF")
+	} else if w > 8 {
+		panic("NAF digits must fit in int8")
+	}
+
+	var naf [256]int8
+	var digits [5]uint64
+
+	for i := 0; i < 4; i++ {
+		digits[i] = binary.LittleEndian.Uint64(s.s[i*8:])
+	}
+
+	width := uint64(1 << w)
+	windowMask := uint64(width - 1)
+
+	pos := uint(0)
+	carry := uint64(0)
+	for pos < 256 {
+		indexU64 := pos / 64
+		indexBit := pos % 64
+		var bitBuf uint64
+		if indexBit < 64-w {
+			// This window's bits are contained in a single u64
+			bitBuf = digits[indexU64] >> indexBit
+		} else {
+			// Combine the current 64 bits with bits from the next 64
+			bitBuf = (digits[indexU64] >> indexBit) | (digits[1+indexU64] << (64 - indexBit))
+		}
+
+		// Add carry into the current window
+		window := carry + (bitBuf & windowMask)
+
+		if window&1 == 0 {
+			// If the window value is even, preserve the carry and continue.
+			// Why is the carry preserved?
+			// If carry == 0 and window & 1 == 0,
+			//    then the next carry should be 0
+			// If carry == 1 and window & 1 == 0,
+			//    then bit_buf & 1 == 1 so the next carry should be 1
+			pos += 1
+			continue
+		}
+
+		if window < width/2 {
+			carry = 0
+			naf[pos] = int8(window)
+		} else {
+			carry = 1
+			naf[pos] = int8(window) - int8(width)
+		}
+
+		pos += w
+	}
+	return naf
+}
+
+func (s *Scalar) signedRadix16() [64]int8 {
+	if s.s[31] > 127 {
+		panic("scalar has high bit set illegally")
+	}
+
+	var digits [64]int8
+
+	// Compute unsigned radix-16 digits:
+	for i := 0; i < 32; i++ {
+		digits[2*i] = int8(s.s[i] & 15)
+		digits[2*i+1] = int8((s.s[i] >> 4) & 15)
+	}
+
+	// Recenter coefficients:
+	for i := 0; i < 63; i++ {
+		carry := (digits[i] + 8) >> 4
+		digits[i] -= carry << 4
+		digits[i+1] += carry
+	}
+
+	return digits
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/scalar_alias_test.go b/src/crypto/ed25519/internal/edwards25519/scalar_alias_test.go
new file mode 100644
index 0000000..18d800d
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/scalar_alias_test.go
@@ -0,0 +1,93 @@
+// Copyright (c) 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package edwards25519
+
+import (
+	"testing"
+	"testing/quick"
+)
+
+func TestScalarAliasing(t *testing.T) {
+	checkAliasingOneArg := func(f func(v, x *Scalar) *Scalar, v, x Scalar) bool {
+		x1, v1 := x, x
+
+		// Calculate a reference f(x) without aliasing.
+		if out := f(&v, &x); out != &v || !isReduced(out) {
+			return false
+		}
+
+		// Test aliasing the argument and the receiver.
+		if out := f(&v1, &v1); out != &v1 || v1 != v || !isReduced(out) {
+			return false
+		}
+
+		// Ensure the arguments was not modified.
+		return x == x1
+	}
+
+	checkAliasingTwoArgs := func(f func(v, x, y *Scalar) *Scalar, v, x, y Scalar) bool {
+		x1, y1, v1 := x, y, Scalar{}
+
+		// Calculate a reference f(x, y) without aliasing.
+		if out := f(&v, &x, &y); out != &v || !isReduced(out) {
+			return false
+		}
+
+		// Test aliasing the first argument and the receiver.
+		v1 = x
+		if out := f(&v1, &v1, &y); out != &v1 || v1 != v || !isReduced(out) {
+			return false
+		}
+		// Test aliasing the second argument and the receiver.
+		v1 = y
+		if out := f(&v1, &x, &v1); out != &v1 || v1 != v || !isReduced(out) {
+			return false
+		}
+
+		// Calculate a reference f(x, x) without aliasing.
+		if out := f(&v, &x, &x); out != &v || !isReduced(out) {
+			return false
+		}
+
+		// Test aliasing the first argument and the receiver.
+		v1 = x
+		if out := f(&v1, &v1, &x); out != &v1 || v1 != v || !isReduced(out) {
+			return false
+		}
+		// Test aliasing the second argument and the receiver.
+		v1 = x
+		if out := f(&v1, &x, &v1); out != &v1 || v1 != v || !isReduced(out) {
+			return false
+		}
+		// Test aliasing both arguments and the receiver.
+		v1 = x
+		if out := f(&v1, &v1, &v1); out != &v1 || v1 != v || !isReduced(out) {
+			return false
+		}
+
+		// Ensure the arguments were not modified.
+		return x == x1 && y == y1
+	}
+
+	for name, f := range map[string]interface{}{
+		"Negate": func(v, x Scalar) bool {
+			return checkAliasingOneArg((*Scalar).Negate, v, x)
+		},
+		"Multiply": func(v, x, y Scalar) bool {
+			return checkAliasingTwoArgs((*Scalar).Multiply, v, x, y)
+		},
+		"Add": func(v, x, y Scalar) bool {
+			return checkAliasingTwoArgs((*Scalar).Add, v, x, y)
+		},
+		"Subtract": func(v, x, y Scalar) bool {
+			return checkAliasingTwoArgs((*Scalar).Subtract, v, x, y)
+		},
+	} {
+		err := quick.Check(f, &quick.Config{MaxCountScale: 1 << 5})
+		if err != nil {
+			t.Errorf("%v: %v", name, err)
+		}
+	}
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/scalar_test.go b/src/crypto/ed25519/internal/edwards25519/scalar_test.go
new file mode 100644
index 0000000..704caff
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/scalar_test.go
@@ -0,0 +1,233 @@
+// Copyright (c) 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package edwards25519
+
+import (
+	"bytes"
+	"encoding/hex"
+	"math/big"
+	mathrand "math/rand"
+	"reflect"
+	"testing"
+	"testing/quick"
+)
+
+// Generate returns a valid (reduced modulo l) Scalar with a distribution
+// weighted towards high, low, and edge values.
+func (Scalar) Generate(rand *mathrand.Rand, size int) reflect.Value {
+	s := scZero
+	diceRoll := rand.Intn(100)
+	switch {
+	case diceRoll == 0:
+	case diceRoll == 1:
+		s = scOne
+	case diceRoll == 2:
+		s = scMinusOne
+	case diceRoll < 5:
+		// Generate a low scalar in [0, 2^125).
+		rand.Read(s.s[:16])
+		s.s[15] &= (1 << 5) - 1
+	case diceRoll < 10:
+		// Generate a high scalar in [2^252, 2^252 + 2^124).
+		s.s[31] = 1 << 4
+		rand.Read(s.s[:16])
+		s.s[15] &= (1 << 4) - 1
+	default:
+		// Generate a valid scalar in [0, l) by returning [0, 2^252) which has a
+		// negligibly different distribution (the former has a 2^-127.6 chance
+		// of being out of the latter range).
+		rand.Read(s.s[:])
+		s.s[31] &= (1 << 4) - 1
+	}
+	return reflect.ValueOf(s)
+}
+
+// quickCheckConfig1024 will make each quickcheck test run (1024 * -quickchecks)
+// times. The default value of -quickchecks is 100.
+var quickCheckConfig1024 = &quick.Config{MaxCountScale: 1 << 10}
+
+func TestScalarGenerate(t *testing.T) {
+	f := func(sc Scalar) bool {
+		return isReduced(&sc)
+	}
+	if err := quick.Check(f, quickCheckConfig1024); err != nil {
+		t.Errorf("generated unreduced scalar: %v", err)
+	}
+}
+
+func TestScalarSetCanonicalBytes(t *testing.T) {
+	f1 := func(in [32]byte, sc Scalar) bool {
+		// Mask out top 4 bits to guarantee value falls in [0, l).
+		in[len(in)-1] &= (1 << 4) - 1
+		if _, err := sc.SetCanonicalBytes(in[:]); err != nil {
+			return false
+		}
+		return bytes.Equal(in[:], sc.Bytes()) && isReduced(&sc)
+	}
+	if err := quick.Check(f1, quickCheckConfig1024); err != nil {
+		t.Errorf("failed bytes->scalar->bytes round-trip: %v", err)
+	}
+
+	f2 := func(sc1, sc2 Scalar) bool {
+		if _, err := sc2.SetCanonicalBytes(sc1.Bytes()); err != nil {
+			return false
+		}
+		return sc1 == sc2
+	}
+	if err := quick.Check(f2, quickCheckConfig1024); err != nil {
+		t.Errorf("failed scalar->bytes->scalar round-trip: %v", err)
+	}
+
+	b := scMinusOne.s
+	b[31] += 1
+	s := scOne
+	if out, err := s.SetCanonicalBytes(b[:]); err == nil {
+		t.Errorf("SetCanonicalBytes worked on a non-canonical value")
+	} else if s != scOne {
+		t.Errorf("SetCanonicalBytes modified its receiver")
+	} else if out != nil {
+		t.Errorf("SetCanonicalBytes did not return nil with an error")
+	}
+}
+
+func TestScalarSetUniformBytes(t *testing.T) {
+	mod, _ := new(big.Int).SetString("27742317777372353535851937790883648493", 10)
+	mod.Add(mod, new(big.Int).Lsh(big.NewInt(1), 252))
+	f := func(in [64]byte, sc Scalar) bool {
+		sc.SetUniformBytes(in[:])
+		if !isReduced(&sc) {
+			return false
+		}
+		scBig := bigIntFromLittleEndianBytes(sc.s[:])
+		inBig := bigIntFromLittleEndianBytes(in[:])
+		return inBig.Mod(inBig, mod).Cmp(scBig) == 0
+	}
+	if err := quick.Check(f, quickCheckConfig1024); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestScalarSetBytesWithClamping(t *testing.T) {
+	// Generated with libsodium.js 1.0.18 crypto_scalarmult_ed25519_base.
+
+	random := "633d368491364dc9cd4c1bf891b1d59460face1644813240a313e61f2c88216e"
+	s := new(Scalar).SetBytesWithClamping(decodeHex(random))
+	p := new(Point).ScalarBaseMult(s)
+	want := "1d87a9026fd0126a5736fe1628c95dd419172b5b618457e041c9c861b2494a94"
+	if got := hex.EncodeToString(p.Bytes()); got != want {
+		t.Errorf("random: got %q, want %q", got, want)
+	}
+
+	zero := "0000000000000000000000000000000000000000000000000000000000000000"
+	s = new(Scalar).SetBytesWithClamping(decodeHex(zero))
+	p = new(Point).ScalarBaseMult(s)
+	want = "693e47972caf527c7883ad1b39822f026f47db2ab0e1919955b8993aa04411d1"
+	if got := hex.EncodeToString(p.Bytes()); got != want {
+		t.Errorf("zero: got %q, want %q", got, want)
+	}
+
+	one := "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+	s = new(Scalar).SetBytesWithClamping(decodeHex(one))
+	p = new(Point).ScalarBaseMult(s)
+	want = "12e9a68b73fd5aacdbcaf3e88c46fea6ebedb1aa84eed1842f07f8edab65e3a7"
+	if got := hex.EncodeToString(p.Bytes()); got != want {
+		t.Errorf("one: got %q, want %q", got, want)
+	}
+}
+
+func bigIntFromLittleEndianBytes(b []byte) *big.Int {
+	bb := make([]byte, len(b))
+	for i := range b {
+		bb[i] = b[len(b)-i-1]
+	}
+	return new(big.Int).SetBytes(bb)
+}
+
+func TestScalarMultiplyDistributesOverAdd(t *testing.T) {
+	multiplyDistributesOverAdd := func(x, y, z Scalar) bool {
+		// Compute t1 = (x+y)*z
+		var t1 Scalar
+		t1.Add(&x, &y)
+		t1.Multiply(&t1, &z)
+
+		// Compute t2 = x*z + y*z
+		var t2 Scalar
+		var t3 Scalar
+		t2.Multiply(&x, &z)
+		t3.Multiply(&y, &z)
+		t2.Add(&t2, &t3)
+
+		return t1 == t2 && isReduced(&t1) && isReduced(&t3)
+	}
+
+	if err := quick.Check(multiplyDistributesOverAdd, quickCheckConfig1024); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestScalarAddLikeSubNeg(t *testing.T) {
+	addLikeSubNeg := func(x, y Scalar) bool {
+		// Compute t1 = x - y
+		var t1 Scalar
+		t1.Subtract(&x, &y)
+
+		// Compute t2 = -y + x
+		var t2 Scalar
+		t2.Negate(&y)
+		t2.Add(&t2, &x)
+
+		return t1 == t2 && isReduced(&t1)
+	}
+
+	if err := quick.Check(addLikeSubNeg, quickCheckConfig1024); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestScalarNonAdjacentForm(t *testing.T) {
+	s := Scalar{[32]byte{
+		0x1a, 0x0e, 0x97, 0x8a, 0x90, 0xf6, 0x62, 0x2d,
+		0x37, 0x47, 0x02, 0x3f, 0x8a, 0xd8, 0x26, 0x4d,
+		0xa7, 0x58, 0xaa, 0x1b, 0x88, 0xe0, 0x40, 0xd1,
+		0x58, 0x9e, 0x7b, 0x7f, 0x23, 0x76, 0xef, 0x09,
+	}}
+	expectedNaf := [256]int8{
+		0, 13, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, -9, 0, 0, 0, 0, -11, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1,
+		0, 0, 0, 0, 9, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 11, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0,
+		-9, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 9, 0,
+		0, 0, 0, -15, 0, 0, 0, 0, -7, 0, 0, 0, 0, -9, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, -3, 0,
+		0, 0, 0, -11, 0, 0, 0, 0, -7, 0, 0, 0, 0, -13, 0, 0, 0, 0, 11, 0, 0, 0, 0, -9, 0, 0, 0, 0, 0, 1, 0, 0,
+		0, 0, 0, -15, 0, 0, 0, 0, 1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 13, 0, 0, 0,
+		0, 0, 0, 11, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, -9, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 7,
+		0, 0, 0, 0, 0, -15, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 15, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
+	}
+
+	sNaf := s.nonAdjacentForm(5)
+
+	for i := 0; i < 256; i++ {
+		if expectedNaf[i] != sNaf[i] {
+			t.Errorf("Wrong digit at position %d, got %d, expected %d", i, sNaf[i], expectedNaf[i])
+		}
+	}
+}
+
+type notZeroScalar Scalar
+
+func (notZeroScalar) Generate(rand *mathrand.Rand, size int) reflect.Value {
+	var s Scalar
+	for s == scZero {
+		s = Scalar{}.Generate(rand, size).Interface().(Scalar)
+	}
+	return reflect.ValueOf(notZeroScalar(s))
+}
+
+func TestScalarEqual(t *testing.T) {
+	if scOne.Equal(&scMinusOne) == 1 {
+		t.Errorf("scOne.Equal(&scMinusOne) is true")
+	}
+	if scMinusOne.Equal(&scMinusOne) == 0 {
+		t.Errorf("scMinusOne.Equal(&scMinusOne) is false")
+	}
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/scalarmult.go b/src/crypto/ed25519/internal/edwards25519/scalarmult.go
new file mode 100644
index 0000000..f7ca3ce
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/scalarmult.go
@@ -0,0 +1,214 @@
+// Copyright (c) 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package edwards25519
+
+import "sync"
+
+// basepointTable is a set of 32 affineLookupTables, where table i is generated
+// from 256i * basepoint. It is precomputed the first time it's used.
+func basepointTable() *[32]affineLookupTable {
+	basepointTablePrecomp.initOnce.Do(func() {
+		p := NewGeneratorPoint()
+		for i := 0; i < 32; i++ {
+			basepointTablePrecomp.table[i].FromP3(p)
+			for j := 0; j < 8; j++ {
+				p.Add(p, p)
+			}
+		}
+	})
+	return &basepointTablePrecomp.table
+}
+
+var basepointTablePrecomp struct {
+	table    [32]affineLookupTable
+	initOnce sync.Once
+}
+
+// ScalarBaseMult sets v = x * B, where B is the canonical generator, and
+// returns v.
+//
+// The scalar multiplication is done in constant time.
+func (v *Point) ScalarBaseMult(x *Scalar) *Point {
+	basepointTable := basepointTable()
+
+	// Write x = sum(x_i * 16^i) so  x*B = sum( B*x_i*16^i )
+	// as described in the Ed25519 paper
+	//
+	// Group even and odd coefficients
+	// x*B     = x_0*16^0*B + x_2*16^2*B + ... + x_62*16^62*B
+	//         + x_1*16^1*B + x_3*16^3*B + ... + x_63*16^63*B
+	// x*B     = x_0*16^0*B + x_2*16^2*B + ... + x_62*16^62*B
+	//    + 16*( x_1*16^0*B + x_3*16^2*B + ... + x_63*16^62*B)
+	//
+	// We use a lookup table for each i to get x_i*16^(2*i)*B
+	// and do four doublings to multiply by 16.
+	digits := x.signedRadix16()
+
+	multiple := &affineCached{}
+	tmp1 := &projP1xP1{}
+	tmp2 := &projP2{}
+
+	// Accumulate the odd components first
+	v.Set(NewIdentityPoint())
+	for i := 1; i < 64; i += 2 {
+		basepointTable[i/2].SelectInto(multiple, digits[i])
+		tmp1.AddAffine(v, multiple)
+		v.fromP1xP1(tmp1)
+	}
+
+	// Multiply by 16
+	tmp2.FromP3(v)       // tmp2 =    v in P2 coords
+	tmp1.Double(tmp2)    // tmp1 =  2*v in P1xP1 coords
+	tmp2.FromP1xP1(tmp1) // tmp2 =  2*v in P2 coords
+	tmp1.Double(tmp2)    // tmp1 =  4*v in P1xP1 coords
+	tmp2.FromP1xP1(tmp1) // tmp2 =  4*v in P2 coords
+	tmp1.Double(tmp2)    // tmp1 =  8*v in P1xP1 coords
+	tmp2.FromP1xP1(tmp1) // tmp2 =  8*v in P2 coords
+	tmp1.Double(tmp2)    // tmp1 = 16*v in P1xP1 coords
+	v.fromP1xP1(tmp1)    // now v = 16*(odd components)
+
+	// Accumulate the even components
+	for i := 0; i < 64; i += 2 {
+		basepointTable[i/2].SelectInto(multiple, digits[i])
+		tmp1.AddAffine(v, multiple)
+		v.fromP1xP1(tmp1)
+	}
+
+	return v
+}
+
+// ScalarMult sets v = x * q, and returns v.
+//
+// The scalar multiplication is done in constant time.
+func (v *Point) ScalarMult(x *Scalar, q *Point) *Point {
+	checkInitialized(q)
+
+	var table projLookupTable
+	table.FromP3(q)
+
+	// Write x = sum(x_i * 16^i)
+	// so  x*Q = sum( Q*x_i*16^i )
+	//         = Q*x_0 + 16*(Q*x_1 + 16*( ... + Q*x_63) ... )
+	//           <------compute inside out---------
+	//
+	// We use the lookup table to get the x_i*Q values
+	// and do four doublings to compute 16*Q
+	digits := x.signedRadix16()
+
+	// Unwrap first loop iteration to save computing 16*identity
+	multiple := &projCached{}
+	tmp1 := &projP1xP1{}
+	tmp2 := &projP2{}
+	table.SelectInto(multiple, digits[63])
+
+	v.Set(NewIdentityPoint())
+	tmp1.Add(v, multiple) // tmp1 = x_63*Q in P1xP1 coords
+	for i := 62; i >= 0; i-- {
+		tmp2.FromP1xP1(tmp1) // tmp2 =    (prev) in P2 coords
+		tmp1.Double(tmp2)    // tmp1 =  2*(prev) in P1xP1 coords
+		tmp2.FromP1xP1(tmp1) // tmp2 =  2*(prev) in P2 coords
+		tmp1.Double(tmp2)    // tmp1 =  4*(prev) in P1xP1 coords
+		tmp2.FromP1xP1(tmp1) // tmp2 =  4*(prev) in P2 coords
+		tmp1.Double(tmp2)    // tmp1 =  8*(prev) in P1xP1 coords
+		tmp2.FromP1xP1(tmp1) // tmp2 =  8*(prev) in P2 coords
+		tmp1.Double(tmp2)    // tmp1 = 16*(prev) in P1xP1 coords
+		v.fromP1xP1(tmp1)    //    v = 16*(prev) in P3 coords
+		table.SelectInto(multiple, digits[i])
+		tmp1.Add(v, multiple) // tmp1 = x_i*Q + 16*(prev) in P1xP1 coords
+	}
+	v.fromP1xP1(tmp1)
+	return v
+}
+
+// basepointNafTable is the nafLookupTable8 for the basepoint.
+// It is precomputed the first time it's used.
+func basepointNafTable() *nafLookupTable8 {
+	basepointNafTablePrecomp.initOnce.Do(func() {
+		basepointNafTablePrecomp.table.FromP3(NewGeneratorPoint())
+	})
+	return &basepointNafTablePrecomp.table
+}
+
+var basepointNafTablePrecomp struct {
+	table    nafLookupTable8
+	initOnce sync.Once
+}
+
+// VarTimeDoubleScalarBaseMult sets v = a * A + b * B, where B is the canonical
+// generator, and returns v.
+//
+// Execution time depends on the inputs.
+func (v *Point) VarTimeDoubleScalarBaseMult(a *Scalar, A *Point, b *Scalar) *Point {
+	checkInitialized(A)
+
+	// Similarly to the single variable-base approach, we compute
+	// digits and use them with a lookup table.  However, because
+	// we are allowed to do variable-time operations, we don't
+	// need constant-time lookups or constant-time digit
+	// computations.
+	//
+	// So we use a non-adjacent form of some width w instead of
+	// radix 16.  This is like a binary representation (one digit
+	// for each binary place) but we allow the digits to grow in
+	// magnitude up to 2^{w-1} so that the nonzero digits are as
+	// sparse as possible.  Intuitively, this "condenses" the
+	// "mass" of the scalar onto sparse coefficients (meaning
+	// fewer additions).
+
+	basepointNafTable := basepointNafTable()
+	var aTable nafLookupTable5
+	aTable.FromP3(A)
+	// Because the basepoint is fixed, we can use a wider NAF
+	// corresponding to a bigger table.
+	aNaf := a.nonAdjacentForm(5)
+	bNaf := b.nonAdjacentForm(8)
+
+	// Find the first nonzero coefficient.
+	i := 255
+	for j := i; j >= 0; j-- {
+		if aNaf[j] != 0 || bNaf[j] != 0 {
+			break
+		}
+	}
+
+	multA := &projCached{}
+	multB := &affineCached{}
+	tmp1 := &projP1xP1{}
+	tmp2 := &projP2{}
+	tmp2.Zero()
+
+	// Move from high to low bits, doubling the accumulator
+	// at each iteration and checking whether there is a nonzero
+	// coefficient to look up a multiple of.
+	for ; i >= 0; i-- {
+		tmp1.Double(tmp2)
+
+		// Only update v if we have a nonzero coeff to add in.
+		if aNaf[i] > 0 {
+			v.fromP1xP1(tmp1)
+			aTable.SelectInto(multA, aNaf[i])
+			tmp1.Add(v, multA)
+		} else if aNaf[i] < 0 {
+			v.fromP1xP1(tmp1)
+			aTable.SelectInto(multA, -aNaf[i])
+			tmp1.Sub(v, multA)
+		}
+
+		if bNaf[i] > 0 {
+			v.fromP1xP1(tmp1)
+			basepointNafTable.SelectInto(multB, bNaf[i])
+			tmp1.AddAffine(v, multB)
+		} else if bNaf[i] < 0 {
+			v.fromP1xP1(tmp1)
+			basepointNafTable.SelectInto(multB, -bNaf[i])
+			tmp1.SubAffine(v, multB)
+		}
+
+		tmp2.FromP1xP1(tmp1)
+	}
+
+	v.fromP2(tmp2)
+	return v
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/scalarmult_test.go b/src/crypto/ed25519/internal/edwards25519/scalarmult_test.go
new file mode 100644
index 0000000..c2027f5
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/scalarmult_test.go
@@ -0,0 +1,209 @@
+// Copyright (c) 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package edwards25519
+
+import (
+	"testing"
+	"testing/quick"
+)
+
+var (
+	// quickCheckConfig32 will make each quickcheck test run (32 * -quickchecks)
+	// times. The default value of -quickchecks is 100.
+	quickCheckConfig32 = &quick.Config{MaxCountScale: 1 << 5}
+
+	// a random scalar generated using dalek.
+	dalekScalar = Scalar{[32]byte{219, 106, 114, 9, 174, 249, 155, 89, 69, 203, 201, 93, 92, 116, 234, 187, 78, 115, 103, 172, 182, 98, 62, 103, 187, 136, 13, 100, 248, 110, 12, 4}}
+	// the above, times the edwards25519 basepoint.
+	dalekScalarBasepoint, _ = new(Point).SetBytes([]byte{0xf4, 0xef, 0x7c, 0xa, 0x34, 0x55, 0x7b, 0x9f, 0x72, 0x3b, 0xb6, 0x1e, 0xf9, 0x46, 0x9, 0x91, 0x1c, 0xb9, 0xc0, 0x6c, 0x17, 0x28, 0x2d, 0x8b, 0x43, 0x2b, 0x5, 0x18, 0x6a, 0x54, 0x3e, 0x48})
+)
+
+func TestScalarMultSmallScalars(t *testing.T) {
+	var z Scalar
+	var p Point
+	p.ScalarMult(&z, B)
+	if I.Equal(&p) != 1 {
+		t.Error("0*B != 0")
+	}
+	checkOnCurve(t, &p)
+
+	z = Scalar{[32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+	p.ScalarMult(&z, B)
+	if B.Equal(&p) != 1 {
+		t.Error("1*B != 1")
+	}
+	checkOnCurve(t, &p)
+}
+
+func TestScalarMultVsDalek(t *testing.T) {
+	var p Point
+	p.ScalarMult(&dalekScalar, B)
+	if dalekScalarBasepoint.Equal(&p) != 1 {
+		t.Error("Scalar mul does not match dalek")
+	}
+	checkOnCurve(t, &p)
+}
+
+func TestBaseMultVsDalek(t *testing.T) {
+	var p Point
+	p.ScalarBaseMult(&dalekScalar)
+	if dalekScalarBasepoint.Equal(&p) != 1 {
+		t.Error("Scalar mul does not match dalek")
+	}
+	checkOnCurve(t, &p)
+}
+
+func TestVarTimeDoubleBaseMultVsDalek(t *testing.T) {
+	var p Point
+	var z Scalar
+	p.VarTimeDoubleScalarBaseMult(&dalekScalar, B, &z)
+	if dalekScalarBasepoint.Equal(&p) != 1 {
+		t.Error("VarTimeDoubleScalarBaseMult fails with b=0")
+	}
+	checkOnCurve(t, &p)
+	p.VarTimeDoubleScalarBaseMult(&z, B, &dalekScalar)
+	if dalekScalarBasepoint.Equal(&p) != 1 {
+		t.Error("VarTimeDoubleScalarBaseMult fails with a=0")
+	}
+	checkOnCurve(t, &p)
+}
+
+func TestScalarMultDistributesOverAdd(t *testing.T) {
+	scalarMultDistributesOverAdd := func(x, y Scalar) bool {
+		var z Scalar
+		z.Add(&x, &y)
+		var p, q, r, check Point
+		p.ScalarMult(&x, B)
+		q.ScalarMult(&y, B)
+		r.ScalarMult(&z, B)
+		check.Add(&p, &q)
+		checkOnCurve(t, &p, &q, &r, &check)
+		return check.Equal(&r) == 1
+	}
+
+	if err := quick.Check(scalarMultDistributesOverAdd, quickCheckConfig32); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestScalarMultNonIdentityPoint(t *testing.T) {
+	// Check whether p.ScalarMult and q.ScalaBaseMult give the same,
+	// when p and q are originally set to the base point.
+
+	scalarMultNonIdentityPoint := func(x Scalar) bool {
+		var p, q Point
+		p.Set(B)
+		q.Set(B)
+
+		p.ScalarMult(&x, B)
+		q.ScalarBaseMult(&x)
+
+		checkOnCurve(t, &p, &q)
+
+		return p.Equal(&q) == 1
+	}
+
+	if err := quick.Check(scalarMultNonIdentityPoint, quickCheckConfig32); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestBasepointTableGeneration(t *testing.T) {
+	// The basepoint table is 32 affineLookupTables,
+	// corresponding to (16^2i)*B for table i.
+	basepointTable := basepointTable()
+
+	tmp1 := &projP1xP1{}
+	tmp2 := &projP2{}
+	tmp3 := &Point{}
+	tmp3.Set(B)
+	table := make([]affineLookupTable, 32)
+	for i := 0; i < 32; i++ {
+		// Build the table
+		table[i].FromP3(tmp3)
+		// Assert equality with the hardcoded one
+		if table[i] != basepointTable[i] {
+			t.Errorf("Basepoint table %d does not match", i)
+		}
+
+		// Set p = (16^2)*p = 256*p = 2^8*p
+		tmp2.FromP3(tmp3)
+		for j := 0; j < 7; j++ {
+			tmp1.Double(tmp2)
+			tmp2.FromP1xP1(tmp1)
+		}
+		tmp1.Double(tmp2)
+		tmp3.fromP1xP1(tmp1)
+		checkOnCurve(t, tmp3)
+	}
+}
+
+func TestScalarMultMatchesBaseMult(t *testing.T) {
+	scalarMultMatchesBaseMult := func(x Scalar) bool {
+		var p, q Point
+		p.ScalarMult(&x, B)
+		q.ScalarBaseMult(&x)
+		checkOnCurve(t, &p, &q)
+		return p.Equal(&q) == 1
+	}
+
+	if err := quick.Check(scalarMultMatchesBaseMult, quickCheckConfig32); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestBasepointNafTableGeneration(t *testing.T) {
+	var table nafLookupTable8
+	table.FromP3(B)
+
+	if table != *basepointNafTable() {
+		t.Error("BasepointNafTable does not match")
+	}
+}
+
+func TestVarTimeDoubleBaseMultMatchesBaseMult(t *testing.T) {
+	varTimeDoubleBaseMultMatchesBaseMult := func(x, y Scalar) bool {
+		var p, q1, q2, check Point
+
+		p.VarTimeDoubleScalarBaseMult(&x, B, &y)
+
+		q1.ScalarBaseMult(&x)
+		q2.ScalarBaseMult(&y)
+		check.Add(&q1, &q2)
+
+		checkOnCurve(t, &p, &check, &q1, &q2)
+		return p.Equal(&check) == 1
+	}
+
+	if err := quick.Check(varTimeDoubleBaseMultMatchesBaseMult, quickCheckConfig32); err != nil {
+		t.Error(err)
+	}
+}
+
+// Benchmarks.
+
+func BenchmarkScalarBaseMult(t *testing.B) {
+	var p Point
+
+	for i := 0; i < t.N; i++ {
+		p.ScalarBaseMult(&dalekScalar)
+	}
+}
+
+func BenchmarkScalarMult(t *testing.B) {
+	var p Point
+
+	for i := 0; i < t.N; i++ {
+		p.ScalarMult(&dalekScalar, B)
+	}
+}
+
+func BenchmarkVarTimeDoubleScalarBaseMult(t *testing.B) {
+	var p Point
+
+	for i := 0; i < t.N; i++ {
+		p.VarTimeDoubleScalarBaseMult(&dalekScalar, B, &dalekScalar)
+	}
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/tables.go b/src/crypto/ed25519/internal/edwards25519/tables.go
new file mode 100644
index 0000000..beec956
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/tables.go
@@ -0,0 +1,129 @@
+// Copyright (c) 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package edwards25519
+
+import (
+	"crypto/subtle"
+)
+
+// A dynamic lookup table for variable-base, constant-time scalar muls.
+type projLookupTable struct {
+	points [8]projCached
+}
+
+// A precomputed lookup table for fixed-base, constant-time scalar muls.
+type affineLookupTable struct {
+	points [8]affineCached
+}
+
+// A dynamic lookup table for variable-base, variable-time scalar muls.
+type nafLookupTable5 struct {
+	points [8]projCached
+}
+
+// A precomputed lookup table for fixed-base, variable-time scalar muls.
+type nafLookupTable8 struct {
+	points [64]affineCached
+}
+
+// Constructors.
+
+// Builds a lookup table at runtime. Fast.
+func (v *projLookupTable) FromP3(q *Point) {
+	// Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q
+	// This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q
+	v.points[0].FromP3(q)
+	tmpP3 := Point{}
+	tmpP1xP1 := projP1xP1{}
+	for i := 0; i < 7; i++ {
+		// Compute (i+1)*Q as Q + i*Q and convert to a ProjCached
+		// This is needlessly complicated because the API has explicit
+		// recievers instead of creating stack objects and relying on RVO
+		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(q, &v.points[i])))
+	}
+}
+
+// This is not optimised for speed; fixed-base tables should be precomputed.
+func (v *affineLookupTable) FromP3(q *Point) {
+	// Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q
+	// This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q
+	v.points[0].FromP3(q)
+	tmpP3 := Point{}
+	tmpP1xP1 := projP1xP1{}
+	for i := 0; i < 7; i++ {
+		// Compute (i+1)*Q as Q + i*Q and convert to AffineCached
+		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(q, &v.points[i])))
+	}
+}
+
+// Builds a lookup table at runtime. Fast.
+func (v *nafLookupTable5) FromP3(q *Point) {
+	// Goal: v.points[i] = (2*i+1)*Q, i.e., Q, 3Q, 5Q, ..., 15Q
+	// This allows lookup of -15Q, ..., -3Q, -Q, 0, Q, 3Q, ..., 15Q
+	v.points[0].FromP3(q)
+	q2 := Point{}
+	q2.Add(q, q)
+	tmpP3 := Point{}
+	tmpP1xP1 := projP1xP1{}
+	for i := 0; i < 7; i++ {
+		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(&q2, &v.points[i])))
+	}
+}
+
+// This is not optimised for speed; fixed-base tables should be precomputed.
+func (v *nafLookupTable8) FromP3(q *Point) {
+	v.points[0].FromP3(q)
+	q2 := Point{}
+	q2.Add(q, q)
+	tmpP3 := Point{}
+	tmpP1xP1 := projP1xP1{}
+	for i := 0; i < 63; i++ {
+		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(&q2, &v.points[i])))
+	}
+}
+
+// Selectors.
+
+// Set dest to x*Q, where -8 <= x <= 8, in constant time.
+func (v *projLookupTable) SelectInto(dest *projCached, x int8) {
+	// Compute xabs = |x|
+	xmask := x >> 7
+	xabs := uint8((x + xmask) ^ xmask)
+
+	dest.Zero()
+	for j := 1; j <= 8; j++ {
+		// Set dest = j*Q if |x| = j
+		cond := subtle.ConstantTimeByteEq(xabs, uint8(j))
+		dest.Select(&v.points[j-1], dest, cond)
+	}
+	// Now dest = |x|*Q, conditionally negate to get x*Q
+	dest.CondNeg(int(xmask & 1))
+}
+
+// Set dest to x*Q, where -8 <= x <= 8, in constant time.
+func (v *affineLookupTable) SelectInto(dest *affineCached, x int8) {
+	// Compute xabs = |x|
+	xmask := x >> 7
+	xabs := uint8((x + xmask) ^ xmask)
+
+	dest.Zero()
+	for j := 1; j <= 8; j++ {
+		// Set dest = j*Q if |x| = j
+		cond := subtle.ConstantTimeByteEq(xabs, uint8(j))
+		dest.Select(&v.points[j-1], dest, cond)
+	}
+	// Now dest = |x|*Q, conditionally negate to get x*Q
+	dest.CondNeg(int(xmask & 1))
+}
+
+// Given odd x with 0 < x < 2^4, return x*Q (in variable time).
+func (v *nafLookupTable5) SelectInto(dest *projCached, x int8) {
+	*dest = v.points[x/2]
+}
+
+// Given odd x with 0 < x < 2^7, return x*Q (in variable time).
+func (v *nafLookupTable8) SelectInto(dest *affineCached, x int8) {
+	*dest = v.points[x/2]
+}
diff --git a/src/crypto/ed25519/internal/edwards25519/tables_test.go b/src/crypto/ed25519/internal/edwards25519/tables_test.go
new file mode 100644
index 0000000..b5d161a
--- /dev/null
+++ b/src/crypto/ed25519/internal/edwards25519/tables_test.go
@@ -0,0 +1,119 @@
+// Copyright (c) 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package edwards25519
+
+import (
+	"testing"
+)
+
+func TestProjLookupTable(t *testing.T) {
+	var table projLookupTable
+	table.FromP3(B)
+
+	var tmp1, tmp2, tmp3 projCached
+	table.SelectInto(&tmp1, 6)
+	table.SelectInto(&tmp2, -2)
+	table.SelectInto(&tmp3, -4)
+	// Expect T1 + T2 + T3 = identity
+
+	var accP1xP1 projP1xP1
+	accP3 := NewIdentityPoint()
+
+	accP1xP1.Add(accP3, &tmp1)
+	accP3.fromP1xP1(&accP1xP1)
+	accP1xP1.Add(accP3, &tmp2)
+	accP3.fromP1xP1(&accP1xP1)
+	accP1xP1.Add(accP3, &tmp3)
+	accP3.fromP1xP1(&accP1xP1)
+
+	if accP3.Equal(I) != 1 {
+		t.Errorf("Consistency check on ProjLookupTable.SelectInto failed!  %x %x %x", tmp1, tmp2, tmp3)
+	}
+}
+
+func TestAffineLookupTable(t *testing.T) {
+	var table affineLookupTable
+	table.FromP3(B)
+
+	var tmp1, tmp2, tmp3 affineCached
+	table.SelectInto(&tmp1, 3)
+	table.SelectInto(&tmp2, -7)
+	table.SelectInto(&tmp3, 4)
+	// Expect T1 + T2 + T3 = identity
+
+	var accP1xP1 projP1xP1
+	accP3 := NewIdentityPoint()
+
+	accP1xP1.AddAffine(accP3, &tmp1)
+	accP3.fromP1xP1(&accP1xP1)
+	accP1xP1.AddAffine(accP3, &tmp2)
+	accP3.fromP1xP1(&accP1xP1)
+	accP1xP1.AddAffine(accP3, &tmp3)
+	accP3.fromP1xP1(&accP1xP1)
+
+	if accP3.Equal(I) != 1 {
+		t.Errorf("Consistency check on ProjLookupTable.SelectInto failed!  %x %x %x", tmp1, tmp2, tmp3)
+	}
+}
+
+func TestNafLookupTable5(t *testing.T) {
+	var table nafLookupTable5
+	table.FromP3(B)
+
+	var tmp1, tmp2, tmp3, tmp4 projCached
+	table.SelectInto(&tmp1, 9)
+	table.SelectInto(&tmp2, 11)
+	table.SelectInto(&tmp3, 7)
+	table.SelectInto(&tmp4, 13)
+	// Expect T1 + T2 = T3 + T4
+
+	var accP1xP1 projP1xP1
+	lhs := NewIdentityPoint()
+	rhs := NewIdentityPoint()
+
+	accP1xP1.Add(lhs, &tmp1)
+	lhs.fromP1xP1(&accP1xP1)
+	accP1xP1.Add(lhs, &tmp2)
+	lhs.fromP1xP1(&accP1xP1)
+
+	accP1xP1.Add(rhs, &tmp3)
+	rhs.fromP1xP1(&accP1xP1)
+	accP1xP1.Add(rhs, &tmp4)
+	rhs.fromP1xP1(&accP1xP1)
+
+	if lhs.Equal(rhs) != 1 {
+		t.Errorf("Consistency check on nafLookupTable5 failed")
+	}
+}
+
+func TestNafLookupTable8(t *testing.T) {
+	var table nafLookupTable8
+	table.FromP3(B)
+
+	var tmp1, tmp2, tmp3, tmp4 affineCached
+	table.SelectInto(&tmp1, 49)
+	table.SelectInto(&tmp2, 11)
+	table.SelectInto(&tmp3, 35)
+	table.SelectInto(&tmp4, 25)
+	// Expect T1 + T2 = T3 + T4
+
+	var accP1xP1 projP1xP1
+	lhs := NewIdentityPoint()
+	rhs := NewIdentityPoint()
+
+	accP1xP1.AddAffine(lhs, &tmp1)
+	lhs.fromP1xP1(&accP1xP1)
+	accP1xP1.AddAffine(lhs, &tmp2)
+	lhs.fromP1xP1(&accP1xP1)
+
+	accP1xP1.AddAffine(rhs, &tmp3)
+	rhs.fromP1xP1(&accP1xP1)
+	accP1xP1.AddAffine(rhs, &tmp4)
+	rhs.fromP1xP1(&accP1xP1)
+
+	if lhs.Equal(rhs) != 1 {
+		t.Errorf("Consistency check on nafLookupTable8 failed")
+	}
+}
diff --git a/src/crypto/elliptic/elliptic.go b/src/crypto/elliptic/elliptic.go
index f93dc16..f072960 100644
--- a/src/crypto/elliptic/elliptic.go
+++ b/src/crypto/elliptic/elliptic.go
@@ -40,6 +40,15 @@
 	ScalarBaseMult(k []byte) (x, y *big.Int)
 }
 
+func matchesSpecificCurve(params *CurveParams, available ...Curve) (Curve, bool) {
+	for _, c := range available {
+		if params == c.Params() {
+			return c, true
+		}
+	}
+	return nil, false
+}
+
 // CurveParams contains the parameters of an elliptic curve and also provides
 // a generic, non-constant time implementation of Curve.
 type CurveParams struct {
@@ -71,6 +80,12 @@
 }
 
 func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool {
+	// If there is a dedicated constant-time implementation for this curve operation,
+	// use that instead of the generic one.
+	if specific, ok := matchesSpecificCurve(curve, p224, p521); ok {
+		return specific.IsOnCurve(x, y)
+	}
+
 	// y² = x³ - 3x + b
 	y2 := new(big.Int).Mul(y, y)
 	y2.Mod(y2, curve.P)
@@ -108,6 +123,12 @@
 }
 
 func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
+	// If there is a dedicated constant-time implementation for this curve operation,
+	// use that instead of the generic one.
+	if specific, ok := matchesSpecificCurve(curve, p224, p521); ok {
+		return specific.Add(x1, y1, x2, y2)
+	}
+
 	z1 := zForAffine(x1, y1)
 	z2 := zForAffine(x2, y2)
 	return curve.affineFromJacobian(curve.addJacobian(x1, y1, z1, x2, y2, z2))
@@ -192,6 +213,12 @@
 }
 
 func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
+	// If there is a dedicated constant-time implementation for this curve operation,
+	// use that instead of the generic one.
+	if specific, ok := matchesSpecificCurve(curve, p224, p521); ok {
+		return specific.Double(x1, y1)
+	}
+
 	z1 := zForAffine(x1, y1)
 	return curve.affineFromJacobian(curve.doubleJacobian(x1, y1, z1))
 }
@@ -258,6 +285,12 @@
 }
 
 func (curve *CurveParams) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
+	// If there is a dedicated constant-time implementation for this curve operation,
+	// use that instead of the generic one.
+	if specific, ok := matchesSpecificCurve(curve, p224, p256, p521); ok {
+		return specific.ScalarMult(Bx, By, k)
+	}
+
 	Bz := new(big.Int).SetInt64(1)
 	x, y, z := new(big.Int), new(big.Int), new(big.Int)
 
@@ -275,6 +308,12 @@
 }
 
 func (curve *CurveParams) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
+	// If there is a dedicated constant-time implementation for this curve operation,
+	// use that instead of the generic one.
+	if specific, ok := matchesSpecificCurve(curve, p224, p256, p521); ok {
+		return specific.ScalarBaseMult(k)
+	}
+
 	return curve.ScalarMult(curve.Gx, curve.Gy, k)
 }
 
@@ -390,7 +429,6 @@
 
 var initonce sync.Once
 var p384 *CurveParams
-var p521 *CurveParams
 
 func initAll() {
 	initP224()
@@ -410,17 +448,6 @@
 	p384.BitSize = 384
 }
 
-func initP521() {
-	// See FIPS 186-3, section D.2.5
-	p521 = &CurveParams{Name: "P-521"}
-	p521.P, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", 10)
-	p521.N, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449", 10)
-	p521.B, _ = new(big.Int).SetString("051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", 16)
-	p521.Gx, _ = new(big.Int).SetString("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 16)
-	p521.Gy, _ = new(big.Int).SetString("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 16)
-	p521.BitSize = 521
-}
-
 // P256 returns a Curve which implements NIST P-256 (FIPS 186-3, section D.2.3),
 // also known as secp256r1 or prime256v1. The CurveParams.Name of this Curve is
 // "P-256".
@@ -428,7 +455,7 @@
 // Multiple invocations of this function will return the same value, so it can
 // be used for equality checks and switch statements.
 //
-// The cryptographic operations are implemented using constant-time algorithms.
+// ScalarMult and ScalarBaseMult are implemented using constant-time algorithms.
 func P256() Curve {
 	initonce.Do(initAll)
 	return p256
@@ -452,7 +479,7 @@
 // Multiple invocations of this function will return the same value, so it can
 // be used for equality checks and switch statements.
 //
-// The cryptographic operations do not use constant-time algorithms.
+// The cryptographic operations are implemented using constant-time algorithms.
 func P521() Curve {
 	initonce.Do(initAll)
 	return p521
diff --git a/src/crypto/elliptic/elliptic_test.go b/src/crypto/elliptic/elliptic_test.go
index e80e773..183861a 100644
--- a/src/crypto/elliptic/elliptic_test.go
+++ b/src/crypto/elliptic/elliptic_test.go
@@ -8,414 +8,70 @@
 	"bytes"
 	"crypto/rand"
 	"encoding/hex"
-	"fmt"
 	"math/big"
 	"testing"
 )
 
-func TestOnCurve(t *testing.T) {
-	p224 := P224()
-	if !p224.IsOnCurve(p224.Params().Gx, p224.Params().Gy) {
-		t.Errorf("FAIL")
+// genericParamsForCurve returns the dereferenced CurveParams for
+// the specified curve. This is used to avoid the logic for
+// upgrading a curve to it's specific implementation, forcing
+// usage of the generic implementation. This is only relevant
+// for the P224, P256, and P521 curves.
+func genericParamsForCurve(c Curve) *CurveParams {
+	d := *(c.Params())
+	return &d
+}
+
+func testAllCurves(t *testing.T, f func(*testing.T, Curve)) {
+	tests := []struct {
+		name  string
+		curve Curve
+	}{
+		{"P256", P256()},
+		{"P256/Params", genericParamsForCurve(P256())},
+		{"P224", P224()},
+		{"P224/Params", genericParamsForCurve(P224())},
+		{"P384", P384()},
+		{"P384/Params", genericParamsForCurve(P384())},
+		{"P521", P521()},
+		{"P521/Params", genericParamsForCurve(P521())},
 	}
+	if testing.Short() {
+		tests = tests[:1]
+	}
+	for _, test := range tests {
+		curve := test.curve
+		t.Run(test.name, func(t *testing.T) {
+			t.Parallel()
+			f(t, curve)
+		})
+	}
+}
+
+func TestOnCurve(t *testing.T) {
+	testAllCurves(t, func(t *testing.T, curve Curve) {
+		if !curve.IsOnCurve(curve.Params().Gx, curve.Params().Gy) {
+			t.Error("basepoint is not on the curve")
+		}
+	})
 }
 
 func TestOffCurve(t *testing.T) {
-	p224 := P224()
-	x, y := new(big.Int).SetInt64(1), new(big.Int).SetInt64(1)
-	if p224.IsOnCurve(x, y) {
-		t.Errorf("FAIL: point off curve is claimed to be on the curve")
-	}
-	b := Marshal(p224, x, y)
-	x1, y1 := Unmarshal(p224, b)
-	if x1 != nil || y1 != nil {
-		t.Errorf("FAIL: unmarshaling a point not on the curve succeeded")
-	}
+	testAllCurves(t, func(t *testing.T, curve Curve) {
+		x, y := new(big.Int).SetInt64(1), new(big.Int).SetInt64(1)
+		if curve.IsOnCurve(x, y) {
+			t.Errorf("point off curve is claimed to be on the curve")
+		}
+		b := Marshal(curve, x, y)
+		x1, y1 := Unmarshal(curve, b)
+		if x1 != nil || y1 != nil {
+			t.Errorf("unmarshaling a point not on the curve succeeded")
+		}
+	})
 }
 
-type baseMultTest struct {
-	k    string
-	x, y string
-}
-
-var p224BaseMultTests = []baseMultTest{
-	{
-		"1",
-		"b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
-		"bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
-	},
-	{
-		"2",
-		"706a46dc76dcb76798e60e6d89474788d16dc18032d268fd1a704fa6",
-		"1c2b76a7bc25e7702a704fa986892849fca629487acf3709d2e4e8bb",
-	},
-	{
-		"3",
-		"df1b1d66a551d0d31eff822558b9d2cc75c2180279fe0d08fd896d04",
-		"a3f7f03cadd0be444c0aa56830130ddf77d317344e1af3591981a925",
-	},
-	{
-		"4",
-		"ae99feebb5d26945b54892092a8aee02912930fa41cd114e40447301",
-		"482580a0ec5bc47e88bc8c378632cd196cb3fa058a7114eb03054c9",
-	},
-	{
-		"5",
-		"31c49ae75bce7807cdff22055d94ee9021fedbb5ab51c57526f011aa",
-		"27e8bff1745635ec5ba0c9f1c2ede15414c6507d29ffe37e790a079b",
-	},
-	{
-		"6",
-		"1f2483f82572251fca975fea40db821df8ad82a3c002ee6c57112408",
-		"89faf0ccb750d99b553c574fad7ecfb0438586eb3952af5b4b153c7e",
-	},
-	{
-		"7",
-		"db2f6be630e246a5cf7d99b85194b123d487e2d466b94b24a03c3e28",
-		"f3a30085497f2f611ee2517b163ef8c53b715d18bb4e4808d02b963",
-	},
-	{
-		"8",
-		"858e6f9cc6c12c31f5df124aa77767b05c8bc021bd683d2b55571550",
-		"46dcd3ea5c43898c5c5fc4fdac7db39c2f02ebee4e3541d1e78047a",
-	},
-	{
-		"9",
-		"2fdcccfee720a77ef6cb3bfbb447f9383117e3daa4a07e36ed15f78d",
-		"371732e4f41bf4f7883035e6a79fcedc0e196eb07b48171697517463",
-	},
-	{
-		"10",
-		"aea9e17a306517eb89152aa7096d2c381ec813c51aa880e7bee2c0fd",
-		"39bb30eab337e0a521b6cba1abe4b2b3a3e524c14a3fe3eb116b655f",
-	},
-	{
-		"11",
-		"ef53b6294aca431f0f3c22dc82eb9050324f1d88d377e716448e507c",
-		"20b510004092e96636cfb7e32efded8265c266dfb754fa6d6491a6da",
-	},
-	{
-		"12",
-		"6e31ee1dc137f81b056752e4deab1443a481033e9b4c93a3044f4f7a",
-		"207dddf0385bfdeab6e9acda8da06b3bbef224a93ab1e9e036109d13",
-	},
-	{
-		"13",
-		"34e8e17a430e43289793c383fac9774247b40e9ebd3366981fcfaeca",
-		"252819f71c7fb7fbcb159be337d37d3336d7feb963724fdfb0ecb767",
-	},
-	{
-		"14",
-		"a53640c83dc208603ded83e4ecf758f24c357d7cf48088b2ce01e9fa",
-		"d5814cd724199c4a5b974a43685fbf5b8bac69459c9469bc8f23ccaf",
-	},
-	{
-		"15",
-		"baa4d8635511a7d288aebeedd12ce529ff102c91f97f867e21916bf9",
-		"979a5f4759f80f4fb4ec2e34f5566d595680a11735e7b61046127989",
-	},
-	{
-		"16",
-		"b6ec4fe1777382404ef679997ba8d1cc5cd8e85349259f590c4c66d",
-		"3399d464345906b11b00e363ef429221f2ec720d2f665d7dead5b482",
-	},
-	{
-		"17",
-		"b8357c3a6ceef288310e17b8bfeff9200846ca8c1942497c484403bc",
-		"ff149efa6606a6bd20ef7d1b06bd92f6904639dce5174db6cc554a26",
-	},
-	{
-		"18",
-		"c9ff61b040874c0568479216824a15eab1a838a797d189746226e4cc",
-		"ea98d60e5ffc9b8fcf999fab1df7e7ef7084f20ddb61bb045a6ce002",
-	},
-	{
-		"19",
-		"a1e81c04f30ce201c7c9ace785ed44cc33b455a022f2acdbc6cae83c",
-		"dcf1f6c3db09c70acc25391d492fe25b4a180babd6cea356c04719cd",
-	},
-	{
-		"20",
-		"fcc7f2b45df1cd5a3c0c0731ca47a8af75cfb0347e8354eefe782455",
-		"d5d7110274cba7cdee90e1a8b0d394c376a5573db6be0bf2747f530",
-	},
-	{
-		"112233445566778899",
-		"61f077c6f62ed802dad7c2f38f5c67f2cc453601e61bd076bb46179e",
-		"2272f9e9f5933e70388ee652513443b5e289dd135dcc0d0299b225e4",
-	},
-	{
-		"112233445566778899112233445566778899",
-		"29895f0af496bfc62b6ef8d8a65c88c613949b03668aab4f0429e35",
-		"3ea6e53f9a841f2019ec24bde1a75677aa9b5902e61081c01064de93",
-	},
-	{
-		"6950511619965839450988900688150712778015737983940691968051900319680",
-		"ab689930bcae4a4aa5f5cb085e823e8ae30fd365eb1da4aba9cf0379",
-		"3345a121bbd233548af0d210654eb40bab788a03666419be6fbd34e7",
-	},
-	{
-		"13479972933410060327035789020509431695094902435494295338570602119423",
-		"bdb6a8817c1f89da1c2f3dd8e97feb4494f2ed302a4ce2bc7f5f4025",
-		"4c7020d57c00411889462d77a5438bb4e97d177700bf7243a07f1680",
-	},
-	{
-		"13479971751745682581351455311314208093898607229429740618390390702079",
-		"d58b61aa41c32dd5eba462647dba75c5d67c83606c0af2bd928446a9",
-		"d24ba6a837be0460dd107ae77725696d211446c5609b4595976b16bd",
-	},
-	{
-		"13479972931865328106486971546324465392952975980343228160962702868479",
-		"dc9fa77978a005510980e929a1485f63716df695d7a0c18bb518df03",
-		"ede2b016f2ddffc2a8c015b134928275ce09e5661b7ab14ce0d1d403",
-	},
-	{
-		"11795773708834916026404142434151065506931607341523388140225443265536",
-		"499d8b2829cfb879c901f7d85d357045edab55028824d0f05ba279ba",
-		"bf929537b06e4015919639d94f57838fa33fc3d952598dcdbb44d638",
-	},
-	{
-		"784254593043826236572847595991346435467177662189391577090",
-		"8246c999137186632c5f9eddf3b1b0e1764c5e8bd0e0d8a554b9cb77",
-		"e80ed8660bc1cb17ac7d845be40a7a022d3306f116ae9f81fea65947",
-	},
-	{
-		"13479767645505654746623887797783387853576174193480695826442858012671",
-		"6670c20afcceaea672c97f75e2e9dd5c8460e54bb38538ebb4bd30eb",
-		"f280d8008d07a4caf54271f993527d46ff3ff46fd1190a3f1faa4f74",
-	},
-	{
-		"205688069665150753842126177372015544874550518966168735589597183",
-		"eca934247425cfd949b795cb5ce1eff401550386e28d1a4c5a8eb",
-		"d4c01040dba19628931bc8855370317c722cbd9ca6156985f1c2e9ce",
-	},
-	{
-		"13479966930919337728895168462090683249159702977113823384618282123295",
-		"ef353bf5c73cd551b96d596fbc9a67f16d61dd9fe56af19de1fba9cd",
-		"21771b9cdce3e8430c09b3838be70b48c21e15bc09ee1f2d7945b91f",
-	},
-	{
-		"50210731791415612487756441341851895584393717453129007497216",
-		"4036052a3091eb481046ad3289c95d3ac905ca0023de2c03ecd451cf",
-		"d768165a38a2b96f812586a9d59d4136035d9c853a5bf2e1c86a4993",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368041",
-		"fcc7f2b45df1cd5a3c0c0731ca47a8af75cfb0347e8354eefe782455",
-		"f2a28eefd8b345832116f1e574f2c6b2c895aa8c24941f40d8b80ad1",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368042",
-		"a1e81c04f30ce201c7c9ace785ed44cc33b455a022f2acdbc6cae83c",
-		"230e093c24f638f533dac6e2b6d01da3b5e7f45429315ca93fb8e634",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368043",
-		"c9ff61b040874c0568479216824a15eab1a838a797d189746226e4cc",
-		"156729f1a003647030666054e208180f8f7b0df2249e44fba5931fff",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368044",
-		"b8357c3a6ceef288310e17b8bfeff9200846ca8c1942497c484403bc",
-		"eb610599f95942df1082e4f9426d086fb9c6231ae8b24933aab5db",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368045",
-		"b6ec4fe1777382404ef679997ba8d1cc5cd8e85349259f590c4c66d",
-		"cc662b9bcba6f94ee4ff1c9c10bd6ddd0d138df2d099a282152a4b7f",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368046",
-		"baa4d8635511a7d288aebeedd12ce529ff102c91f97f867e21916bf9",
-		"6865a0b8a607f0b04b13d1cb0aa992a5a97f5ee8ca1849efb9ed8678",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368047",
-		"a53640c83dc208603ded83e4ecf758f24c357d7cf48088b2ce01e9fa",
-		"2a7eb328dbe663b5a468b5bc97a040a3745396ba636b964370dc3352",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368048",
-		"34e8e17a430e43289793c383fac9774247b40e9ebd3366981fcfaeca",
-		"dad7e608e380480434ea641cc82c82cbc92801469c8db0204f13489a",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368049",
-		"6e31ee1dc137f81b056752e4deab1443a481033e9b4c93a3044f4f7a",
-		"df82220fc7a4021549165325725f94c3410ddb56c54e161fc9ef62ee",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368050",
-		"ef53b6294aca431f0f3c22dc82eb9050324f1d88d377e716448e507c",
-		"df4aefffbf6d1699c930481cd102127c9a3d992048ab05929b6e5927",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368051",
-		"aea9e17a306517eb89152aa7096d2c381ec813c51aa880e7bee2c0fd",
-		"c644cf154cc81f5ade49345e541b4d4b5c1adb3eb5c01c14ee949aa2",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368052",
-		"2fdcccfee720a77ef6cb3bfbb447f9383117e3daa4a07e36ed15f78d",
-		"c8e8cd1b0be40b0877cfca1958603122f1e6914f84b7e8e968ae8b9e",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368053",
-		"858e6f9cc6c12c31f5df124aa77767b05c8bc021bd683d2b55571550",
-		"fb9232c15a3bc7673a3a03b0253824c53d0fd1411b1cabe2e187fb87",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368054",
-		"db2f6be630e246a5cf7d99b85194b123d487e2d466b94b24a03c3e28",
-		"f0c5cff7ab680d09ee11dae84e9c1072ac48ea2e744b1b7f72fd469e",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368055",
-		"1f2483f82572251fca975fea40db821df8ad82a3c002ee6c57112408",
-		"76050f3348af2664aac3a8b05281304ebc7a7914c6ad50a4b4eac383",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368056",
-		"31c49ae75bce7807cdff22055d94ee9021fedbb5ab51c57526f011aa",
-		"d817400e8ba9ca13a45f360e3d121eaaeb39af82d6001c8186f5f866",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368057",
-		"ae99feebb5d26945b54892092a8aee02912930fa41cd114e40447301",
-		"fb7da7f5f13a43b81774373c879cd32d6934c05fa758eeb14fcfab38",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368058",
-		"df1b1d66a551d0d31eff822558b9d2cc75c2180279fe0d08fd896d04",
-		"5c080fc3522f41bbb3f55a97cfecf21f882ce8cbb1e50ca6e67e56dc",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368059",
-		"706a46dc76dcb76798e60e6d89474788d16dc18032d268fd1a704fa6",
-		"e3d4895843da188fd58fb0567976d7b50359d6b78530c8f62d1b1746",
-	},
-	{
-		"26959946667150639794667015087019625940457807714424391721682722368060",
-		"b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
-		"42c89c774a08dc04b3dd201932bc8a5ea5f8b89bbb2a7e667aff81cd",
-	},
-}
-
-type scalarMultTest struct {
-	k          string
-	xIn, yIn   string
-	xOut, yOut string
-}
-
-var p256MultTests = []scalarMultTest{
-	{
-		"2a265f8bcbdcaf94d58519141e578124cb40d64a501fba9c11847b28965bc737",
-		"023819813ac969847059028ea88a1f30dfbcde03fc791d3a252c6b41211882ea",
-		"f93e4ae433cc12cf2a43fc0ef26400c0e125508224cdb649380f25479148a4ad",
-		"4d4de80f1534850d261075997e3049321a0864082d24a917863366c0724f5ae3",
-		"a22d2b7f7818a3563e0f7a76c9bf0921ac55e06e2e4d11795b233824b1db8cc0",
-	},
-	{
-		"313f72ff9fe811bf573176231b286a3bdb6f1b14e05c40146590727a71c3bccd",
-		"cc11887b2d66cbae8f4d306627192522932146b42f01d3c6f92bd5c8ba739b06",
-		"a2f08a029cd06b46183085bae9248b0ed15b70280c7ef13a457f5af382426031",
-		"831c3f6b5f762d2f461901577af41354ac5f228c2591f84f8a6e51e2e3f17991",
-		"93f90934cd0ef2c698cc471c60a93524e87ab31ca2412252337f364513e43684",
-	},
-}
-
-func TestBaseMult(t *testing.T) {
-	p224 := P224()
-	for i, e := range p224BaseMultTests {
-		k, ok := new(big.Int).SetString(e.k, 10)
-		if !ok {
-			t.Errorf("%d: bad value for k: %s", i, e.k)
-		}
-		x, y := p224.ScalarBaseMult(k.Bytes())
-		if fmt.Sprintf("%x", x) != e.x || fmt.Sprintf("%x", y) != e.y {
-			t.Errorf("%d: bad output for k=%s: got (%x, %x), want (%s, %s)", i, e.k, x, y, e.x, e.y)
-		}
-		if testing.Short() && i > 5 {
-			break
-		}
-	}
-}
-
-func TestGenericBaseMult(t *testing.T) {
-	// We use the P224 CurveParams directly in order to test the generic implementation.
-	p224 := P224().Params()
-	for i, e := range p224BaseMultTests {
-		k, ok := new(big.Int).SetString(e.k, 10)
-		if !ok {
-			t.Errorf("%d: bad value for k: %s", i, e.k)
-		}
-		x, y := p224.ScalarBaseMult(k.Bytes())
-		if fmt.Sprintf("%x", x) != e.x || fmt.Sprintf("%x", y) != e.y {
-			t.Errorf("%d: bad output for k=%s: got (%x, %x), want (%s, %s)", i, e.k, x, y, e.x, e.y)
-		}
-		if testing.Short() && i > 5 {
-			break
-		}
-	}
-}
-
-func TestP256BaseMult(t *testing.T) {
-	p256 := P256()
-	p256Generic := p256.Params()
-
-	scalars := make([]*big.Int, 0, len(p224BaseMultTests)+1)
-	for _, e := range p224BaseMultTests {
-		k, _ := new(big.Int).SetString(e.k, 10)
-		scalars = append(scalars, k)
-	}
-	k := new(big.Int).SetInt64(1)
-	k.Lsh(k, 500)
-	scalars = append(scalars, k)
-
-	for i, k := range scalars {
-		x, y := p256.ScalarBaseMult(k.Bytes())
-		x2, y2 := p256Generic.ScalarBaseMult(k.Bytes())
-		if x.Cmp(x2) != 0 || y.Cmp(y2) != 0 {
-			t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, x, y, x2, y2)
-		}
-
-		if testing.Short() && i > 5 {
-			break
-		}
-	}
-}
-
-func TestP256Mult(t *testing.T) {
-	p256 := P256()
-	p256Generic := p256.Params()
-
-	for i, e := range p224BaseMultTests {
-		x, _ := new(big.Int).SetString(e.x, 16)
-		y, _ := new(big.Int).SetString(e.y, 16)
-		k, _ := new(big.Int).SetString(e.k, 10)
-
-		xx, yy := p256.ScalarMult(x, y, k.Bytes())
-		xx2, yy2 := p256Generic.ScalarMult(x, y, k.Bytes())
-		if xx.Cmp(xx2) != 0 || yy.Cmp(yy2) != 0 {
-			t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, xx, yy, xx2, yy2)
-		}
-		if testing.Short() && i > 5 {
-			break
-		}
-	}
-
-	for i, e := range p256MultTests {
-		x, _ := new(big.Int).SetString(e.xIn, 16)
-		y, _ := new(big.Int).SetString(e.yIn, 16)
-		k, _ := new(big.Int).SetString(e.k, 16)
-		expectedX, _ := new(big.Int).SetString(e.xOut, 16)
-		expectedY, _ := new(big.Int).SetString(e.yOut, 16)
-
-		xx, yy := p256.ScalarMult(x, y, k.Bytes())
-		if xx.Cmp(expectedX) != 0 || yy.Cmp(expectedY) != 0 {
-			t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, xx, yy, expectedX, expectedY)
-		}
-	}
+func TestInfinity(t *testing.T) {
+	testAllCurves(t, testInfinity)
 }
 
 func testInfinity(t *testing.T, curve Curve) {
@@ -455,199 +111,66 @@
 	}
 }
 
-func TestInfinity(t *testing.T) {
-	tests := []struct {
-		name  string
-		curve Curve
-	}{
-		{"P-224", P224()},
-		{"P-256", P256()},
-		{"P-256/Generic", P256().Params()},
-		{"P-384", P384()},
-		{"P-521", P521()},
-	}
-	if testing.Short() {
-		tests = tests[:1]
-	}
-	for _, test := range tests {
-		curve := test.curve
-		t.Run(test.name, func(t *testing.T) {
-			testInfinity(t, curve)
-		})
-	}
-}
-
-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()
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			p224.ScalarBaseMult(k.Bytes())
-		}
-	})
-}
-
-func BenchmarkBaseMultP256(b *testing.B) {
-	b.ResetTimer()
-	p256 := P256()
-	e := p224BaseMultTests[25]
-	k, _ := new(big.Int).SetString(e.k, 10)
-	b.ReportAllocs()
-	b.StartTimer()
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			p256.ScalarBaseMult(k.Bytes())
-		}
-	})
-}
-
-func BenchmarkScalarMultP256(b *testing.B) {
-	b.ResetTimer()
-	p256 := P256()
-	_, x, y, _ := GenerateKey(p256, rand.Reader)
-	priv, _, _, _ := GenerateKey(p256, rand.Reader)
-
-	b.ReportAllocs()
-	b.StartTimer()
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			p256.ScalarMult(x, y, priv)
-		}
-	})
-}
-
 func TestMarshal(t *testing.T) {
-	p224 := P224()
-	_, x, y, err := GenerateKey(p224, rand.Reader)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-	serialized := Marshal(p224, x, y)
-	xx, yy := Unmarshal(p224, serialized)
-	if xx == nil {
-		t.Error("failed to unmarshal")
-		return
-	}
-	if xx.Cmp(x) != 0 || yy.Cmp(y) != 0 {
-		t.Error("unmarshal returned different values")
-		return
-	}
+	testAllCurves(t, func(t *testing.T, curve Curve) {
+		_, x, y, err := GenerateKey(curve, rand.Reader)
+		if err != nil {
+			t.Fatal(err)
+		}
+		serialized := Marshal(curve, x, y)
+		xx, yy := Unmarshal(curve, serialized)
+		if xx == nil {
+			t.Fatal("failed to unmarshal")
+		}
+		if xx.Cmp(x) != 0 || yy.Cmp(y) != 0 {
+			t.Fatal("unmarshal returned different values")
+		}
+	})
 }
 
-func TestP224Overflow(t *testing.T) {
-	// This tests for a specific bug in the P224 implementation.
-	p224 := P224()
-	pointData, _ := hex.DecodeString("049B535B45FB0A2072398A6831834624C7E32CCFD5A4B933BCEAF77F1DD945E08BBE5178F5EDF5E733388F196D2A631D2E075BB16CBFEEA15B")
-	x, y := Unmarshal(p224, pointData)
-	if !p224.IsOnCurve(x, y) {
-		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
+	// See https://golang.org/issues/20482.
+	testAllCurves(t, testUnmarshalToLargeCoordinates)
+}
 
-	invalidX, invalidY := make([]byte, 65), make([]byte, 65)
-	invalidX[0], invalidY[0] = 4, 4 // uncompressed encoding
+func testUnmarshalToLargeCoordinates(t *testing.T, curve Curve) {
+	p := curve.Params().P
+	byteLen := (p.BitLen() + 7) / 8
 
 	// 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)
+	y := curve.Params().polynomial(x)
+	y.ModSqrt(y, p)
 
-	copy(invalidX[1:], x.Bytes())
-	copy(invalidX[33:], y.Bytes())
+	invalid := make([]byte, byteLen*2+1)
+	invalid[0] = 4 // uncompressed encoding
+	x.FillBytes(invalid[1 : 1+byteLen])
+	y.FillBytes(invalid[1+byteLen:])
 
-	if X, Y := Unmarshal(curve, invalidX); X != nil || Y != nil {
+	if X, Y := Unmarshal(curve, invalid); X != nil || Y != nil {
 		t.Errorf("Unmarshal accepts 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 curve == p256 {
+		// 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")
-	}
+		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())
+		// marshal
+		x.FillBytes(invalid[1 : 1+byteLen])
+		y.FillBytes(invalid[1+byteLen:])
 
-	if X, Y := Unmarshal(curve, invalidY); X != nil || Y != nil {
-		t.Errorf("Unmarshal accepts invalid Y coordinate")
+		if X, Y := Unmarshal(curve, invalid); X != nil || Y != nil {
+			t.Errorf("Unmarshal accepts invalid Y coordinate")
+		}
 	}
 }
 
@@ -677,27 +200,14 @@
 		t.Skip("skipping other curves on short test")
 	}
 
-	t.Run("P-224", func(t *testing.T) {
-		_, x, y, err := GenerateKey(P224(), rand.Reader)
+	testAllCurves(t, func(t *testing.T, curve Curve) {
+		_, x, y, err := GenerateKey(curve, rand.Reader)
 		if err != nil {
 			t.Fatal(err)
 		}
-		testMarshalCompressed(t, P224(), x, y, nil)
+		testMarshalCompressed(t, curve, x, y, nil)
 	})
-	t.Run("P-384", func(t *testing.T) {
-		_, x, y, err := GenerateKey(P384(), rand.Reader)
-		if err != nil {
-			t.Fatal(err)
-		}
-		testMarshalCompressed(t, P384(), x, y, nil)
-	})
-	t.Run("P-521", func(t *testing.T) {
-		_, x, y, err := GenerateKey(P521(), rand.Reader)
-		if err != nil {
-			t.Fatal(err)
-		}
-		testMarshalCompressed(t, P521(), x, y, nil)
-	})
+
 }
 
 func testMarshalCompressed(t *testing.T, curve Curve, x, y *big.Int, want []byte) {
@@ -721,3 +231,46 @@
 		t.Errorf("point did not round-trip correctly: got (%v, %v), want (%v, %v)", X, Y, x, y)
 	}
 }
+
+func benchmarkAllCurves(t *testing.B, f func(*testing.B, Curve)) {
+	tests := []struct {
+		name  string
+		curve Curve
+	}{
+		{"P256", P256()},
+		{"P224", P224()},
+		{"P384", P384()},
+		{"P521", P521()},
+	}
+	for _, test := range tests {
+		curve := test.curve
+		t.Run(test.name, func(t *testing.B) {
+			f(t, curve)
+		})
+	}
+}
+
+func BenchmarkScalarBaseMult(b *testing.B) {
+	benchmarkAllCurves(b, func(b *testing.B, curve Curve) {
+		priv, _, _, _ := GenerateKey(curve, rand.Reader)
+		b.ReportAllocs()
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			x, _ := curve.ScalarBaseMult(priv)
+			// Prevent the compiler from optimizing out the operation.
+			priv[0] ^= byte(x.Bits()[0])
+		}
+	})
+}
+
+func BenchmarkScalarMult(b *testing.B) {
+	benchmarkAllCurves(b, func(b *testing.B, curve Curve) {
+		_, x, y, _ := GenerateKey(curve, rand.Reader)
+		priv, _, _, _ := GenerateKey(curve, rand.Reader)
+		b.ReportAllocs()
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			x, y = curve.ScalarMult(x, y, priv)
+		}
+	})
+}
diff --git a/src/crypto/elliptic/fuzz_test.go b/src/crypto/elliptic/fuzz_test.go
index b9209a7..8ff3bf3 100644
--- a/src/crypto/elliptic/fuzz_test.go
+++ b/src/crypto/elliptic/fuzz_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 || arm64 || ppc64le
 // +build amd64 arm64 ppc64le
 
 package elliptic
@@ -13,7 +14,6 @@
 )
 
 func TestFuzz(t *testing.T) {
-
 	p256 := P256()
 	p256Generic := p256.Params()
 
diff --git a/src/crypto/elliptic/internal/fiat/Dockerfile b/src/crypto/elliptic/internal/fiat/Dockerfile
new file mode 100644
index 0000000..7b5ece0
--- /dev/null
+++ b/src/crypto/elliptic/internal/fiat/Dockerfile
@@ -0,0 +1,12 @@
+# Copyright 2021 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+FROM coqorg/coq:8.13.2
+
+RUN git clone https://github.com/mit-plv/fiat-crypto
+RUN cd fiat-crypto && git checkout c076f3550bea2bb7f4cb5766a32594b9e67694f2
+RUN cd fiat-crypto && git submodule update --init --recursive
+RUN cd fiat-crypto && eval $(opam env) && make -j4 standalone-ocaml SKIP_BEDROCK2=1
+
+ENTRYPOINT ["fiat-crypto/src/ExtractionOCaml/unsaturated_solinas"]
diff --git a/src/crypto/elliptic/internal/fiat/README b/src/crypto/elliptic/internal/fiat/README
new file mode 100644
index 0000000..171f57a
--- /dev/null
+++ b/src/crypto/elliptic/internal/fiat/README
@@ -0,0 +1,39 @@
+The code in this package was autogenerated by the fiat-crypto project
+at commit c076f3550 from a formally verified model.
+
+    docker build -t fiat-crypto:c076f3550 .
+    docker run fiat-crypto:c076f3550 --lang Go --no-wide-int --cmovznz-by-mul \
+        --internal-static --public-function-case camelCase --public-type-case camelCase \
+        --private-function-case camelCase --private-type-case camelCase \
+        --no-prefix-fiat --package-name fiat --doc-text-before-function-name '' \
+        --doc-prepend-header 'Code generated by Fiat Cryptography. DO NOT EDIT.' \
+        --doc-newline-before-package-declaration p521 64 9 '2^521 - 1' \
+        carry_mul carry_square carry add sub to_bytes from_bytes selectznz \
+        > p521_fiat64.go
+
+It comes under the following license.
+
+    Copyright (c) 2015-2020 The fiat-crypto Authors. All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are
+    met:
+
+        1. Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+    THIS SOFTWARE IS PROVIDED BY the fiat-crypto authors "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design,
+    Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The authors are listed at
+
+    https://github.com/mit-plv/fiat-crypto/blob/master/AUTHORS
diff --git a/src/crypto/elliptic/internal/fiat/p521.go b/src/crypto/elliptic/internal/fiat/p521.go
new file mode 100644
index 0000000..dc67732
--- /dev/null
+++ b/src/crypto/elliptic/internal/fiat/p521.go
@@ -0,0 +1,197 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package fiat implements prime order fields using formally verified algorithms
+// from the Fiat Cryptography project.
+package fiat
+
+import (
+	"crypto/subtle"
+	"errors"
+)
+
+// P521Element is an integer modulo 2^521 - 1.
+//
+// The zero value is a valid zero element.
+type P521Element struct {
+	// This element has the following bounds, which are tighter than
+	// the output bounds of some operations. Those operations must be
+	// followed by a carry.
+	//
+	// [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000],
+	// [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000],
+	// [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x200000000000000]
+	x [9]uint64
+}
+
+// One sets e = 1, and returns e.
+func (e *P521Element) One() *P521Element {
+	*e = P521Element{}
+	e.x[0] = 1
+	return e
+}
+
+// Equal returns 1 if e == t, and zero otherwise.
+func (e *P521Element) Equal(t *P521Element) int {
+	eBytes := e.Bytes()
+	tBytes := t.Bytes()
+	return subtle.ConstantTimeCompare(eBytes, tBytes)
+}
+
+var p521ZeroEncoding = new(P521Element).Bytes()
+
+// IsZero returns 1 if e == 0, and zero otherwise.
+func (e *P521Element) IsZero() int {
+	eBytes := e.Bytes()
+	return subtle.ConstantTimeCompare(eBytes, p521ZeroEncoding)
+}
+
+// Set sets e = t, and returns e.
+func (e *P521Element) Set(t *P521Element) *P521Element {
+	e.x = t.x
+	return e
+}
+
+// Bytes returns the 66-byte little-endian encoding of e.
+func (e *P521Element) Bytes() []byte {
+	// This function must be inlined to move the allocation to the parent and
+	// save it from escaping to the heap.
+	var out [66]byte
+	p521ToBytes(&out, &e.x)
+	return out[:]
+}
+
+// SetBytes sets e = v, where v is a little-endian 66-byte encoding, and returns
+// e. If v is not 66 bytes or it encodes a value higher than 2^521 - 1, SetBytes
+// returns nil and an error, and e is unchanged.
+func (e *P521Element) SetBytes(v []byte) (*P521Element, error) {
+	if len(v) != 66 || v[65] > 1 {
+		return nil, errors.New("invalid P-521 field encoding")
+	}
+	var in [66]byte
+	copy(in[:], v)
+	p521FromBytes(&e.x, &in)
+	return e, nil
+}
+
+// Add sets e = t1 + t2, and returns e.
+func (e *P521Element) Add(t1, t2 *P521Element) *P521Element {
+	p521Add(&e.x, &t1.x, &t2.x)
+	p521Carry(&e.x, &e.x)
+	return e
+}
+
+// Sub sets e = t1 - t2, and returns e.
+func (e *P521Element) Sub(t1, t2 *P521Element) *P521Element {
+	p521Sub(&e.x, &t1.x, &t2.x)
+	p521Carry(&e.x, &e.x)
+	return e
+}
+
+// Mul sets e = t1 * t2, and returns e.
+func (e *P521Element) Mul(t1, t2 *P521Element) *P521Element {
+	p521CarryMul(&e.x, &t1.x, &t2.x)
+	return e
+}
+
+// Square sets e = t * t, and returns e.
+func (e *P521Element) Square(t *P521Element) *P521Element {
+	p521CarrySquare(&e.x, &t.x)
+	return e
+}
+
+// Select sets e to a if cond == 1, and to b if cond == 0.
+func (v *P521Element) Select(a, b *P521Element, cond int) *P521Element {
+	p521Selectznz(&v.x, p521Uint1(cond), &b.x, &a.x)
+	return v
+}
+
+// Invert sets e = 1/t, and returns e.
+//
+// If t == 0, Invert returns e = 0.
+func (e *P521Element) Invert(t *P521Element) *P521Element {
+	// Inversion is implemented as exponentiation with exponent p − 2.
+	// The sequence of multiplications and squarings was generated with
+	// github.com/mmcloughlin/addchain v0.2.0.
+
+	var t1, t2 = new(P521Element), new(P521Element)
+
+	// _10 = 2 * 1
+	t1.Square(t)
+
+	// _11 = 1 + _10
+	t1.Mul(t, t1)
+
+	// _1100 = _11 << 2
+	t2.Square(t1)
+	t2.Square(t2)
+
+	// _1111 = _11 + _1100
+	t1.Mul(t1, t2)
+
+	// _11110000 = _1111 << 4
+	t2.Square(t1)
+	for i := 0; i < 3; i++ {
+		t2.Square(t2)
+	}
+
+	// _11111111 = _1111 + _11110000
+	t1.Mul(t1, t2)
+
+	// x16 = _11111111<<8 + _11111111
+	t2.Square(t1)
+	for i := 0; i < 7; i++ {
+		t2.Square(t2)
+	}
+	t1.Mul(t1, t2)
+
+	// x32 = x16<<16 + x16
+	t2.Square(t1)
+	for i := 0; i < 15; i++ {
+		t2.Square(t2)
+	}
+	t1.Mul(t1, t2)
+
+	// x64 = x32<<32 + x32
+	t2.Square(t1)
+	for i := 0; i < 31; i++ {
+		t2.Square(t2)
+	}
+	t1.Mul(t1, t2)
+
+	// x65 = 2*x64 + 1
+	t2.Square(t1)
+	t2.Mul(t2, t)
+
+	// x129 = x65<<64 + x64
+	for i := 0; i < 64; i++ {
+		t2.Square(t2)
+	}
+	t1.Mul(t1, t2)
+
+	// x130 = 2*x129 + 1
+	t2.Square(t1)
+	t2.Mul(t2, t)
+
+	// x259 = x130<<129 + x129
+	for i := 0; i < 129; i++ {
+		t2.Square(t2)
+	}
+	t1.Mul(t1, t2)
+
+	// x260 = 2*x259 + 1
+	t2.Square(t1)
+	t2.Mul(t2, t)
+
+	// x519 = x260<<259 + x259
+	for i := 0; i < 259; i++ {
+		t2.Square(t2)
+	}
+	t1.Mul(t1, t2)
+
+	// return x519<<2 + 1
+	t1.Square(t1)
+	t1.Square(t1)
+	return e.Mul(t1, t)
+}
diff --git a/src/crypto/elliptic/internal/fiat/p521_fiat64.go b/src/crypto/elliptic/internal/fiat/p521_fiat64.go
new file mode 100644
index 0000000..f86283b
--- /dev/null
+++ b/src/crypto/elliptic/internal/fiat/p521_fiat64.go
@@ -0,0 +1,1856 @@
+// Code generated by Fiat Cryptography. DO NOT EDIT.
+//
+// Autogenerated: 'fiat-crypto/src/ExtractionOCaml/unsaturated_solinas' --lang Go --no-wide-int --cmovznz-by-mul --internal-static --public-function-case camelCase --public-type-case camelCase --private-function-case camelCase --private-type-case camelCase --no-prefix-fiat --package-name fiat --doc-text-before-function-name '' --doc-prepend-header 'Code generated by Fiat Cryptography. DO NOT EDIT.' --doc-newline-before-package-declaration p521 64 9 '2^521 - 1' carry_mul carry_square carry add sub to_bytes from_bytes selectznz
+//
+// curve description: p521
+//
+// machine_wordsize = 64 (from "64")
+//
+// requested operations: carry_mul, carry_square, carry, add, sub, to_bytes, from_bytes, selectznz
+//
+// n = 9 (from "9")
+//
+// s-c = 2^521 - [(1, 1)] (from "2^521 - 1")
+//
+// tight_bounds_multiplier = 1 (from "")
+//
+//
+//
+// Computed values:
+//
+//   carry_chain = [0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1]
+//
+//   eval z = z[0] + (z[1] << 58) + (z[2] << 116) + (z[3] << 174) + (z[4] << 232) + (z[5] << 0x122) + (z[6] << 0x15c) + (z[7] << 0x196) + (z[8] << 0x1d0)
+//
+//   bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) + (z[32] << 256) + (z[33] << 0x108) + (z[34] << 0x110) + (z[35] << 0x118) + (z[36] << 0x120) + (z[37] << 0x128) + (z[38] << 0x130) + (z[39] << 0x138) + (z[40] << 0x140) + (z[41] << 0x148) + (z[42] << 0x150) + (z[43] << 0x158) + (z[44] << 0x160) + (z[45] << 0x168) + (z[46] << 0x170) + (z[47] << 0x178) + (z[48] << 0x180) + (z[49] << 0x188) + (z[50] << 0x190) + (z[51] << 0x198) + (z[52] << 0x1a0) + (z[53] << 0x1a8) + (z[54] << 0x1b0) + (z[55] << 0x1b8) + (z[56] << 0x1c0) + (z[57] << 0x1c8) + (z[58] << 0x1d0) + (z[59] << 0x1d8) + (z[60] << 0x1e0) + (z[61] << 0x1e8) + (z[62] << 0x1f0) + (z[63] << 0x1f8) + (z[64] << 2^9) + (z[65] << 0x208)
+//
+//   balance = [0x7fffffffffffffe, 0x7fffffffffffffe, 0x7fffffffffffffe, 0x7fffffffffffffe, 0x7fffffffffffffe, 0x7fffffffffffffe, 0x7fffffffffffffe, 0x7fffffffffffffe, 0x3fffffffffffffe]
+
+package fiat
+
+import "math/bits"
+
+type p521Uint1 uint8
+type p521Int1 int8
+
+// p521AddcarryxU64 is a thin wrapper around bits.Add64 that uses p521Uint1 rather than uint64
+func p521AddcarryxU64(x uint64, y uint64, carry p521Uint1) (uint64, p521Uint1) {
+	sum, carryOut := bits.Add64(x, y, uint64(carry))
+	return sum, p521Uint1(carryOut)
+}
+
+// p521SubborrowxU64 is a thin wrapper around bits.Sub64 that uses p521Uint1 rather than uint64
+func p521SubborrowxU64(x uint64, y uint64, carry p521Uint1) (uint64, p521Uint1) {
+	sum, carryOut := bits.Sub64(x, y, uint64(carry))
+	return sum, p521Uint1(carryOut)
+}
+
+// p521AddcarryxU58 is an addition with carry.
+//
+// Postconditions:
+//   out1 = (arg1 + arg2 + arg3) mod 2^58
+//   out2 = ⌊(arg1 + arg2 + arg3) / 2^58⌋
+//
+// Input Bounds:
+//   arg1: [0x0 ~> 0x1]
+//   arg2: [0x0 ~> 0x3ffffffffffffff]
+//   arg3: [0x0 ~> 0x3ffffffffffffff]
+// Output Bounds:
+//   out1: [0x0 ~> 0x3ffffffffffffff]
+//   out2: [0x0 ~> 0x1]
+func p521AddcarryxU58(out1 *uint64, out2 *p521Uint1, arg1 p521Uint1, arg2 uint64, arg3 uint64) {
+	x1 := ((uint64(arg1) + arg2) + arg3)
+	x2 := (x1 & 0x3ffffffffffffff)
+	x3 := p521Uint1((x1 >> 58))
+	*out1 = x2
+	*out2 = x3
+}
+
+// p521SubborrowxU58 is a subtraction with borrow.
+//
+// Postconditions:
+//   out1 = (-arg1 + arg2 + -arg3) mod 2^58
+//   out2 = -⌊(-arg1 + arg2 + -arg3) / 2^58⌋
+//
+// Input Bounds:
+//   arg1: [0x0 ~> 0x1]
+//   arg2: [0x0 ~> 0x3ffffffffffffff]
+//   arg3: [0x0 ~> 0x3ffffffffffffff]
+// Output Bounds:
+//   out1: [0x0 ~> 0x3ffffffffffffff]
+//   out2: [0x0 ~> 0x1]
+func p521SubborrowxU58(out1 *uint64, out2 *p521Uint1, arg1 p521Uint1, arg2 uint64, arg3 uint64) {
+	x1 := ((int64(arg2) - int64(arg1)) - int64(arg3))
+	x2 := p521Int1((x1 >> 58))
+	x3 := (uint64(x1) & 0x3ffffffffffffff)
+	*out1 = x3
+	*out2 = (0x0 - p521Uint1(x2))
+}
+
+// p521AddcarryxU57 is an addition with carry.
+//
+// Postconditions:
+//   out1 = (arg1 + arg2 + arg3) mod 2^57
+//   out2 = ⌊(arg1 + arg2 + arg3) / 2^57⌋
+//
+// Input Bounds:
+//   arg1: [0x0 ~> 0x1]
+//   arg2: [0x0 ~> 0x1ffffffffffffff]
+//   arg3: [0x0 ~> 0x1ffffffffffffff]
+// Output Bounds:
+//   out1: [0x0 ~> 0x1ffffffffffffff]
+//   out2: [0x0 ~> 0x1]
+func p521AddcarryxU57(out1 *uint64, out2 *p521Uint1, arg1 p521Uint1, arg2 uint64, arg3 uint64) {
+	x1 := ((uint64(arg1) + arg2) + arg3)
+	x2 := (x1 & 0x1ffffffffffffff)
+	x3 := p521Uint1((x1 >> 57))
+	*out1 = x2
+	*out2 = x3
+}
+
+// p521SubborrowxU57 is a subtraction with borrow.
+//
+// Postconditions:
+//   out1 = (-arg1 + arg2 + -arg3) mod 2^57
+//   out2 = -⌊(-arg1 + arg2 + -arg3) / 2^57⌋
+//
+// Input Bounds:
+//   arg1: [0x0 ~> 0x1]
+//   arg2: [0x0 ~> 0x1ffffffffffffff]
+//   arg3: [0x0 ~> 0x1ffffffffffffff]
+// Output Bounds:
+//   out1: [0x0 ~> 0x1ffffffffffffff]
+//   out2: [0x0 ~> 0x1]
+func p521SubborrowxU57(out1 *uint64, out2 *p521Uint1, arg1 p521Uint1, arg2 uint64, arg3 uint64) {
+	x1 := ((int64(arg2) - int64(arg1)) - int64(arg3))
+	x2 := p521Int1((x1 >> 57))
+	x3 := (uint64(x1) & 0x1ffffffffffffff)
+	*out1 = x3
+	*out2 = (0x0 - p521Uint1(x2))
+}
+
+// p521CmovznzU64 is a single-word conditional move.
+//
+// Postconditions:
+//   out1 = (if arg1 = 0 then arg2 else arg3)
+//
+// Input Bounds:
+//   arg1: [0x0 ~> 0x1]
+//   arg2: [0x0 ~> 0xffffffffffffffff]
+//   arg3: [0x0 ~> 0xffffffffffffffff]
+// Output Bounds:
+//   out1: [0x0 ~> 0xffffffffffffffff]
+func p521CmovznzU64(out1 *uint64, arg1 p521Uint1, arg2 uint64, arg3 uint64) {
+	x1 := (uint64(arg1) * 0xffffffffffffffff)
+	x2 := ((x1 & arg3) | ((^x1) & arg2))
+	*out1 = x2
+}
+
+// p521CarryMul multiplies two field elements and reduces the result.
+//
+// Postconditions:
+//   eval out1 mod m = (eval arg1 * eval arg2) mod m
+//
+// Input Bounds:
+//   arg1: [[0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0x600000000000000]]
+//   arg2: [[0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0x600000000000000]]
+// Output Bounds:
+//   out1: [[0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x200000000000000]]
+func p521CarryMul(out1 *[9]uint64, arg1 *[9]uint64, arg2 *[9]uint64) {
+	var x1 uint64
+	var x2 uint64
+	x2, x1 = bits.Mul64(arg1[8], (arg2[8] * 0x2))
+	var x3 uint64
+	var x4 uint64
+	x4, x3 = bits.Mul64(arg1[8], (arg2[7] * 0x2))
+	var x5 uint64
+	var x6 uint64
+	x6, x5 = bits.Mul64(arg1[8], (arg2[6] * 0x2))
+	var x7 uint64
+	var x8 uint64
+	x8, x7 = bits.Mul64(arg1[8], (arg2[5] * 0x2))
+	var x9 uint64
+	var x10 uint64
+	x10, x9 = bits.Mul64(arg1[8], (arg2[4] * 0x2))
+	var x11 uint64
+	var x12 uint64
+	x12, x11 = bits.Mul64(arg1[8], (arg2[3] * 0x2))
+	var x13 uint64
+	var x14 uint64
+	x14, x13 = bits.Mul64(arg1[8], (arg2[2] * 0x2))
+	var x15 uint64
+	var x16 uint64
+	x16, x15 = bits.Mul64(arg1[8], (arg2[1] * 0x2))
+	var x17 uint64
+	var x18 uint64
+	x18, x17 = bits.Mul64(arg1[7], (arg2[8] * 0x2))
+	var x19 uint64
+	var x20 uint64
+	x20, x19 = bits.Mul64(arg1[7], (arg2[7] * 0x2))
+	var x21 uint64
+	var x22 uint64
+	x22, x21 = bits.Mul64(arg1[7], (arg2[6] * 0x2))
+	var x23 uint64
+	var x24 uint64
+	x24, x23 = bits.Mul64(arg1[7], (arg2[5] * 0x2))
+	var x25 uint64
+	var x26 uint64
+	x26, x25 = bits.Mul64(arg1[7], (arg2[4] * 0x2))
+	var x27 uint64
+	var x28 uint64
+	x28, x27 = bits.Mul64(arg1[7], (arg2[3] * 0x2))
+	var x29 uint64
+	var x30 uint64
+	x30, x29 = bits.Mul64(arg1[7], (arg2[2] * 0x2))
+	var x31 uint64
+	var x32 uint64
+	x32, x31 = bits.Mul64(arg1[6], (arg2[8] * 0x2))
+	var x33 uint64
+	var x34 uint64
+	x34, x33 = bits.Mul64(arg1[6], (arg2[7] * 0x2))
+	var x35 uint64
+	var x36 uint64
+	x36, x35 = bits.Mul64(arg1[6], (arg2[6] * 0x2))
+	var x37 uint64
+	var x38 uint64
+	x38, x37 = bits.Mul64(arg1[6], (arg2[5] * 0x2))
+	var x39 uint64
+	var x40 uint64
+	x40, x39 = bits.Mul64(arg1[6], (arg2[4] * 0x2))
+	var x41 uint64
+	var x42 uint64
+	x42, x41 = bits.Mul64(arg1[6], (arg2[3] * 0x2))
+	var x43 uint64
+	var x44 uint64
+	x44, x43 = bits.Mul64(arg1[5], (arg2[8] * 0x2))
+	var x45 uint64
+	var x46 uint64
+	x46, x45 = bits.Mul64(arg1[5], (arg2[7] * 0x2))
+	var x47 uint64
+	var x48 uint64
+	x48, x47 = bits.Mul64(arg1[5], (arg2[6] * 0x2))
+	var x49 uint64
+	var x50 uint64
+	x50, x49 = bits.Mul64(arg1[5], (arg2[5] * 0x2))
+	var x51 uint64
+	var x52 uint64
+	x52, x51 = bits.Mul64(arg1[5], (arg2[4] * 0x2))
+	var x53 uint64
+	var x54 uint64
+	x54, x53 = bits.Mul64(arg1[4], (arg2[8] * 0x2))
+	var x55 uint64
+	var x56 uint64
+	x56, x55 = bits.Mul64(arg1[4], (arg2[7] * 0x2))
+	var x57 uint64
+	var x58 uint64
+	x58, x57 = bits.Mul64(arg1[4], (arg2[6] * 0x2))
+	var x59 uint64
+	var x60 uint64
+	x60, x59 = bits.Mul64(arg1[4], (arg2[5] * 0x2))
+	var x61 uint64
+	var x62 uint64
+	x62, x61 = bits.Mul64(arg1[3], (arg2[8] * 0x2))
+	var x63 uint64
+	var x64 uint64
+	x64, x63 = bits.Mul64(arg1[3], (arg2[7] * 0x2))
+	var x65 uint64
+	var x66 uint64
+	x66, x65 = bits.Mul64(arg1[3], (arg2[6] * 0x2))
+	var x67 uint64
+	var x68 uint64
+	x68, x67 = bits.Mul64(arg1[2], (arg2[8] * 0x2))
+	var x69 uint64
+	var x70 uint64
+	x70, x69 = bits.Mul64(arg1[2], (arg2[7] * 0x2))
+	var x71 uint64
+	var x72 uint64
+	x72, x71 = bits.Mul64(arg1[1], (arg2[8] * 0x2))
+	var x73 uint64
+	var x74 uint64
+	x74, x73 = bits.Mul64(arg1[8], arg2[0])
+	var x75 uint64
+	var x76 uint64
+	x76, x75 = bits.Mul64(arg1[7], arg2[1])
+	var x77 uint64
+	var x78 uint64
+	x78, x77 = bits.Mul64(arg1[7], arg2[0])
+	var x79 uint64
+	var x80 uint64
+	x80, x79 = bits.Mul64(arg1[6], arg2[2])
+	var x81 uint64
+	var x82 uint64
+	x82, x81 = bits.Mul64(arg1[6], arg2[1])
+	var x83 uint64
+	var x84 uint64
+	x84, x83 = bits.Mul64(arg1[6], arg2[0])
+	var x85 uint64
+	var x86 uint64
+	x86, x85 = bits.Mul64(arg1[5], arg2[3])
+	var x87 uint64
+	var x88 uint64
+	x88, x87 = bits.Mul64(arg1[5], arg2[2])
+	var x89 uint64
+	var x90 uint64
+	x90, x89 = bits.Mul64(arg1[5], arg2[1])
+	var x91 uint64
+	var x92 uint64
+	x92, x91 = bits.Mul64(arg1[5], arg2[0])
+	var x93 uint64
+	var x94 uint64
+	x94, x93 = bits.Mul64(arg1[4], arg2[4])
+	var x95 uint64
+	var x96 uint64
+	x96, x95 = bits.Mul64(arg1[4], arg2[3])
+	var x97 uint64
+	var x98 uint64
+	x98, x97 = bits.Mul64(arg1[4], arg2[2])
+	var x99 uint64
+	var x100 uint64
+	x100, x99 = bits.Mul64(arg1[4], arg2[1])
+	var x101 uint64
+	var x102 uint64
+	x102, x101 = bits.Mul64(arg1[4], arg2[0])
+	var x103 uint64
+	var x104 uint64
+	x104, x103 = bits.Mul64(arg1[3], arg2[5])
+	var x105 uint64
+	var x106 uint64
+	x106, x105 = bits.Mul64(arg1[3], arg2[4])
+	var x107 uint64
+	var x108 uint64
+	x108, x107 = bits.Mul64(arg1[3], arg2[3])
+	var x109 uint64
+	var x110 uint64
+	x110, x109 = bits.Mul64(arg1[3], arg2[2])
+	var x111 uint64
+	var x112 uint64
+	x112, x111 = bits.Mul64(arg1[3], arg2[1])
+	var x113 uint64
+	var x114 uint64
+	x114, x113 = bits.Mul64(arg1[3], arg2[0])
+	var x115 uint64
+	var x116 uint64
+	x116, x115 = bits.Mul64(arg1[2], arg2[6])
+	var x117 uint64
+	var x118 uint64
+	x118, x117 = bits.Mul64(arg1[2], arg2[5])
+	var x119 uint64
+	var x120 uint64
+	x120, x119 = bits.Mul64(arg1[2], arg2[4])
+	var x121 uint64
+	var x122 uint64
+	x122, x121 = bits.Mul64(arg1[2], arg2[3])
+	var x123 uint64
+	var x124 uint64
+	x124, x123 = bits.Mul64(arg1[2], arg2[2])
+	var x125 uint64
+	var x126 uint64
+	x126, x125 = bits.Mul64(arg1[2], arg2[1])
+	var x127 uint64
+	var x128 uint64
+	x128, x127 = bits.Mul64(arg1[2], arg2[0])
+	var x129 uint64
+	var x130 uint64
+	x130, x129 = bits.Mul64(arg1[1], arg2[7])
+	var x131 uint64
+	var x132 uint64
+	x132, x131 = bits.Mul64(arg1[1], arg2[6])
+	var x133 uint64
+	var x134 uint64
+	x134, x133 = bits.Mul64(arg1[1], arg2[5])
+	var x135 uint64
+	var x136 uint64
+	x136, x135 = bits.Mul64(arg1[1], arg2[4])
+	var x137 uint64
+	var x138 uint64
+	x138, x137 = bits.Mul64(arg1[1], arg2[3])
+	var x139 uint64
+	var x140 uint64
+	x140, x139 = bits.Mul64(arg1[1], arg2[2])
+	var x141 uint64
+	var x142 uint64
+	x142, x141 = bits.Mul64(arg1[1], arg2[1])
+	var x143 uint64
+	var x144 uint64
+	x144, x143 = bits.Mul64(arg1[1], arg2[0])
+	var x145 uint64
+	var x146 uint64
+	x146, x145 = bits.Mul64(arg1[0], arg2[8])
+	var x147 uint64
+	var x148 uint64
+	x148, x147 = bits.Mul64(arg1[0], arg2[7])
+	var x149 uint64
+	var x150 uint64
+	x150, x149 = bits.Mul64(arg1[0], arg2[6])
+	var x151 uint64
+	var x152 uint64
+	x152, x151 = bits.Mul64(arg1[0], arg2[5])
+	var x153 uint64
+	var x154 uint64
+	x154, x153 = bits.Mul64(arg1[0], arg2[4])
+	var x155 uint64
+	var x156 uint64
+	x156, x155 = bits.Mul64(arg1[0], arg2[3])
+	var x157 uint64
+	var x158 uint64
+	x158, x157 = bits.Mul64(arg1[0], arg2[2])
+	var x159 uint64
+	var x160 uint64
+	x160, x159 = bits.Mul64(arg1[0], arg2[1])
+	var x161 uint64
+	var x162 uint64
+	x162, x161 = bits.Mul64(arg1[0], arg2[0])
+	var x163 uint64
+	var x164 p521Uint1
+	x163, x164 = p521AddcarryxU64(x29, x15, 0x0)
+	var x165 uint64
+	x165, _ = p521AddcarryxU64(x30, x16, x164)
+	var x167 uint64
+	var x168 p521Uint1
+	x167, x168 = p521AddcarryxU64(x41, x163, 0x0)
+	var x169 uint64
+	x169, _ = p521AddcarryxU64(x42, x165, x168)
+	var x171 uint64
+	var x172 p521Uint1
+	x171, x172 = p521AddcarryxU64(x51, x167, 0x0)
+	var x173 uint64
+	x173, _ = p521AddcarryxU64(x52, x169, x172)
+	var x175 uint64
+	var x176 p521Uint1
+	x175, x176 = p521AddcarryxU64(x59, x171, 0x0)
+	var x177 uint64
+	x177, _ = p521AddcarryxU64(x60, x173, x176)
+	var x179 uint64
+	var x180 p521Uint1
+	x179, x180 = p521AddcarryxU64(x65, x175, 0x0)
+	var x181 uint64
+	x181, _ = p521AddcarryxU64(x66, x177, x180)
+	var x183 uint64
+	var x184 p521Uint1
+	x183, x184 = p521AddcarryxU64(x69, x179, 0x0)
+	var x185 uint64
+	x185, _ = p521AddcarryxU64(x70, x181, x184)
+	var x187 uint64
+	var x188 p521Uint1
+	x187, x188 = p521AddcarryxU64(x71, x183, 0x0)
+	var x189 uint64
+	x189, _ = p521AddcarryxU64(x72, x185, x188)
+	var x191 uint64
+	var x192 p521Uint1
+	x191, x192 = p521AddcarryxU64(x161, x187, 0x0)
+	var x193 uint64
+	x193, _ = p521AddcarryxU64(x162, x189, x192)
+	x195 := ((x191 >> 58) | ((x193 << 6) & 0xffffffffffffffff))
+	x196 := (x193 >> 58)
+	x197 := (x191 & 0x3ffffffffffffff)
+	var x198 uint64
+	var x199 p521Uint1
+	x198, x199 = p521AddcarryxU64(x75, x73, 0x0)
+	var x200 uint64
+	x200, _ = p521AddcarryxU64(x76, x74, x199)
+	var x202 uint64
+	var x203 p521Uint1
+	x202, x203 = p521AddcarryxU64(x79, x198, 0x0)
+	var x204 uint64
+	x204, _ = p521AddcarryxU64(x80, x200, x203)
+	var x206 uint64
+	var x207 p521Uint1
+	x206, x207 = p521AddcarryxU64(x85, x202, 0x0)
+	var x208 uint64
+	x208, _ = p521AddcarryxU64(x86, x204, x207)
+	var x210 uint64
+	var x211 p521Uint1
+	x210, x211 = p521AddcarryxU64(x93, x206, 0x0)
+	var x212 uint64
+	x212, _ = p521AddcarryxU64(x94, x208, x211)
+	var x214 uint64
+	var x215 p521Uint1
+	x214, x215 = p521AddcarryxU64(x103, x210, 0x0)
+	var x216 uint64
+	x216, _ = p521AddcarryxU64(x104, x212, x215)
+	var x218 uint64
+	var x219 p521Uint1
+	x218, x219 = p521AddcarryxU64(x115, x214, 0x0)
+	var x220 uint64
+	x220, _ = p521AddcarryxU64(x116, x216, x219)
+	var x222 uint64
+	var x223 p521Uint1
+	x222, x223 = p521AddcarryxU64(x129, x218, 0x0)
+	var x224 uint64
+	x224, _ = p521AddcarryxU64(x130, x220, x223)
+	var x226 uint64
+	var x227 p521Uint1
+	x226, x227 = p521AddcarryxU64(x145, x222, 0x0)
+	var x228 uint64
+	x228, _ = p521AddcarryxU64(x146, x224, x227)
+	var x230 uint64
+	var x231 p521Uint1
+	x230, x231 = p521AddcarryxU64(x77, x1, 0x0)
+	var x232 uint64
+	x232, _ = p521AddcarryxU64(x78, x2, x231)
+	var x234 uint64
+	var x235 p521Uint1
+	x234, x235 = p521AddcarryxU64(x81, x230, 0x0)
+	var x236 uint64
+	x236, _ = p521AddcarryxU64(x82, x232, x235)
+	var x238 uint64
+	var x239 p521Uint1
+	x238, x239 = p521AddcarryxU64(x87, x234, 0x0)
+	var x240 uint64
+	x240, _ = p521AddcarryxU64(x88, x236, x239)
+	var x242 uint64
+	var x243 p521Uint1
+	x242, x243 = p521AddcarryxU64(x95, x238, 0x0)
+	var x244 uint64
+	x244, _ = p521AddcarryxU64(x96, x240, x243)
+	var x246 uint64
+	var x247 p521Uint1
+	x246, x247 = p521AddcarryxU64(x105, x242, 0x0)
+	var x248 uint64
+	x248, _ = p521AddcarryxU64(x106, x244, x247)
+	var x250 uint64
+	var x251 p521Uint1
+	x250, x251 = p521AddcarryxU64(x117, x246, 0x0)
+	var x252 uint64
+	x252, _ = p521AddcarryxU64(x118, x248, x251)
+	var x254 uint64
+	var x255 p521Uint1
+	x254, x255 = p521AddcarryxU64(x131, x250, 0x0)
+	var x256 uint64
+	x256, _ = p521AddcarryxU64(x132, x252, x255)
+	var x258 uint64
+	var x259 p521Uint1
+	x258, x259 = p521AddcarryxU64(x147, x254, 0x0)
+	var x260 uint64
+	x260, _ = p521AddcarryxU64(x148, x256, x259)
+	var x262 uint64
+	var x263 p521Uint1
+	x262, x263 = p521AddcarryxU64(x17, x3, 0x0)
+	var x264 uint64
+	x264, _ = p521AddcarryxU64(x18, x4, x263)
+	var x266 uint64
+	var x267 p521Uint1
+	x266, x267 = p521AddcarryxU64(x83, x262, 0x0)
+	var x268 uint64
+	x268, _ = p521AddcarryxU64(x84, x264, x267)
+	var x270 uint64
+	var x271 p521Uint1
+	x270, x271 = p521AddcarryxU64(x89, x266, 0x0)
+	var x272 uint64
+	x272, _ = p521AddcarryxU64(x90, x268, x271)
+	var x274 uint64
+	var x275 p521Uint1
+	x274, x275 = p521AddcarryxU64(x97, x270, 0x0)
+	var x276 uint64
+	x276, _ = p521AddcarryxU64(x98, x272, x275)
+	var x278 uint64
+	var x279 p521Uint1
+	x278, x279 = p521AddcarryxU64(x107, x274, 0x0)
+	var x280 uint64
+	x280, _ = p521AddcarryxU64(x108, x276, x279)
+	var x282 uint64
+	var x283 p521Uint1
+	x282, x283 = p521AddcarryxU64(x119, x278, 0x0)
+	var x284 uint64
+	x284, _ = p521AddcarryxU64(x120, x280, x283)
+	var x286 uint64
+	var x287 p521Uint1
+	x286, x287 = p521AddcarryxU64(x133, x282, 0x0)
+	var x288 uint64
+	x288, _ = p521AddcarryxU64(x134, x284, x287)
+	var x290 uint64
+	var x291 p521Uint1
+	x290, x291 = p521AddcarryxU64(x149, x286, 0x0)
+	var x292 uint64
+	x292, _ = p521AddcarryxU64(x150, x288, x291)
+	var x294 uint64
+	var x295 p521Uint1
+	x294, x295 = p521AddcarryxU64(x19, x5, 0x0)
+	var x296 uint64
+	x296, _ = p521AddcarryxU64(x20, x6, x295)
+	var x298 uint64
+	var x299 p521Uint1
+	x298, x299 = p521AddcarryxU64(x31, x294, 0x0)
+	var x300 uint64
+	x300, _ = p521AddcarryxU64(x32, x296, x299)
+	var x302 uint64
+	var x303 p521Uint1
+	x302, x303 = p521AddcarryxU64(x91, x298, 0x0)
+	var x304 uint64
+	x304, _ = p521AddcarryxU64(x92, x300, x303)
+	var x306 uint64
+	var x307 p521Uint1
+	x306, x307 = p521AddcarryxU64(x99, x302, 0x0)
+	var x308 uint64
+	x308, _ = p521AddcarryxU64(x100, x304, x307)
+	var x310 uint64
+	var x311 p521Uint1
+	x310, x311 = p521AddcarryxU64(x109, x306, 0x0)
+	var x312 uint64
+	x312, _ = p521AddcarryxU64(x110, x308, x311)
+	var x314 uint64
+	var x315 p521Uint1
+	x314, x315 = p521AddcarryxU64(x121, x310, 0x0)
+	var x316 uint64
+	x316, _ = p521AddcarryxU64(x122, x312, x315)
+	var x318 uint64
+	var x319 p521Uint1
+	x318, x319 = p521AddcarryxU64(x135, x314, 0x0)
+	var x320 uint64
+	x320, _ = p521AddcarryxU64(x136, x316, x319)
+	var x322 uint64
+	var x323 p521Uint1
+	x322, x323 = p521AddcarryxU64(x151, x318, 0x0)
+	var x324 uint64
+	x324, _ = p521AddcarryxU64(x152, x320, x323)
+	var x326 uint64
+	var x327 p521Uint1
+	x326, x327 = p521AddcarryxU64(x21, x7, 0x0)
+	var x328 uint64
+	x328, _ = p521AddcarryxU64(x22, x8, x327)
+	var x330 uint64
+	var x331 p521Uint1
+	x330, x331 = p521AddcarryxU64(x33, x326, 0x0)
+	var x332 uint64
+	x332, _ = p521AddcarryxU64(x34, x328, x331)
+	var x334 uint64
+	var x335 p521Uint1
+	x334, x335 = p521AddcarryxU64(x43, x330, 0x0)
+	var x336 uint64
+	x336, _ = p521AddcarryxU64(x44, x332, x335)
+	var x338 uint64
+	var x339 p521Uint1
+	x338, x339 = p521AddcarryxU64(x101, x334, 0x0)
+	var x340 uint64
+	x340, _ = p521AddcarryxU64(x102, x336, x339)
+	var x342 uint64
+	var x343 p521Uint1
+	x342, x343 = p521AddcarryxU64(x111, x338, 0x0)
+	var x344 uint64
+	x344, _ = p521AddcarryxU64(x112, x340, x343)
+	var x346 uint64
+	var x347 p521Uint1
+	x346, x347 = p521AddcarryxU64(x123, x342, 0x0)
+	var x348 uint64
+	x348, _ = p521AddcarryxU64(x124, x344, x347)
+	var x350 uint64
+	var x351 p521Uint1
+	x350, x351 = p521AddcarryxU64(x137, x346, 0x0)
+	var x352 uint64
+	x352, _ = p521AddcarryxU64(x138, x348, x351)
+	var x354 uint64
+	var x355 p521Uint1
+	x354, x355 = p521AddcarryxU64(x153, x350, 0x0)
+	var x356 uint64
+	x356, _ = p521AddcarryxU64(x154, x352, x355)
+	var x358 uint64
+	var x359 p521Uint1
+	x358, x359 = p521AddcarryxU64(x23, x9, 0x0)
+	var x360 uint64
+	x360, _ = p521AddcarryxU64(x24, x10, x359)
+	var x362 uint64
+	var x363 p521Uint1
+	x362, x363 = p521AddcarryxU64(x35, x358, 0x0)
+	var x364 uint64
+	x364, _ = p521AddcarryxU64(x36, x360, x363)
+	var x366 uint64
+	var x367 p521Uint1
+	x366, x367 = p521AddcarryxU64(x45, x362, 0x0)
+	var x368 uint64
+	x368, _ = p521AddcarryxU64(x46, x364, x367)
+	var x370 uint64
+	var x371 p521Uint1
+	x370, x371 = p521AddcarryxU64(x53, x366, 0x0)
+	var x372 uint64
+	x372, _ = p521AddcarryxU64(x54, x368, x371)
+	var x374 uint64
+	var x375 p521Uint1
+	x374, x375 = p521AddcarryxU64(x113, x370, 0x0)
+	var x376 uint64
+	x376, _ = p521AddcarryxU64(x114, x372, x375)
+	var x378 uint64
+	var x379 p521Uint1
+	x378, x379 = p521AddcarryxU64(x125, x374, 0x0)
+	var x380 uint64
+	x380, _ = p521AddcarryxU64(x126, x376, x379)
+	var x382 uint64
+	var x383 p521Uint1
+	x382, x383 = p521AddcarryxU64(x139, x378, 0x0)
+	var x384 uint64
+	x384, _ = p521AddcarryxU64(x140, x380, x383)
+	var x386 uint64
+	var x387 p521Uint1
+	x386, x387 = p521AddcarryxU64(x155, x382, 0x0)
+	var x388 uint64
+	x388, _ = p521AddcarryxU64(x156, x384, x387)
+	var x390 uint64
+	var x391 p521Uint1
+	x390, x391 = p521AddcarryxU64(x25, x11, 0x0)
+	var x392 uint64
+	x392, _ = p521AddcarryxU64(x26, x12, x391)
+	var x394 uint64
+	var x395 p521Uint1
+	x394, x395 = p521AddcarryxU64(x37, x390, 0x0)
+	var x396 uint64
+	x396, _ = p521AddcarryxU64(x38, x392, x395)
+	var x398 uint64
+	var x399 p521Uint1
+	x398, x399 = p521AddcarryxU64(x47, x394, 0x0)
+	var x400 uint64
+	x400, _ = p521AddcarryxU64(x48, x396, x399)
+	var x402 uint64
+	var x403 p521Uint1
+	x402, x403 = p521AddcarryxU64(x55, x398, 0x0)
+	var x404 uint64
+	x404, _ = p521AddcarryxU64(x56, x400, x403)
+	var x406 uint64
+	var x407 p521Uint1
+	x406, x407 = p521AddcarryxU64(x61, x402, 0x0)
+	var x408 uint64
+	x408, _ = p521AddcarryxU64(x62, x404, x407)
+	var x410 uint64
+	var x411 p521Uint1
+	x410, x411 = p521AddcarryxU64(x127, x406, 0x0)
+	var x412 uint64
+	x412, _ = p521AddcarryxU64(x128, x408, x411)
+	var x414 uint64
+	var x415 p521Uint1
+	x414, x415 = p521AddcarryxU64(x141, x410, 0x0)
+	var x416 uint64
+	x416, _ = p521AddcarryxU64(x142, x412, x415)
+	var x418 uint64
+	var x419 p521Uint1
+	x418, x419 = p521AddcarryxU64(x157, x414, 0x0)
+	var x420 uint64
+	x420, _ = p521AddcarryxU64(x158, x416, x419)
+	var x422 uint64
+	var x423 p521Uint1
+	x422, x423 = p521AddcarryxU64(x27, x13, 0x0)
+	var x424 uint64
+	x424, _ = p521AddcarryxU64(x28, x14, x423)
+	var x426 uint64
+	var x427 p521Uint1
+	x426, x427 = p521AddcarryxU64(x39, x422, 0x0)
+	var x428 uint64
+	x428, _ = p521AddcarryxU64(x40, x424, x427)
+	var x430 uint64
+	var x431 p521Uint1
+	x430, x431 = p521AddcarryxU64(x49, x426, 0x0)
+	var x432 uint64
+	x432, _ = p521AddcarryxU64(x50, x428, x431)
+	var x434 uint64
+	var x435 p521Uint1
+	x434, x435 = p521AddcarryxU64(x57, x430, 0x0)
+	var x436 uint64
+	x436, _ = p521AddcarryxU64(x58, x432, x435)
+	var x438 uint64
+	var x439 p521Uint1
+	x438, x439 = p521AddcarryxU64(x63, x434, 0x0)
+	var x440 uint64
+	x440, _ = p521AddcarryxU64(x64, x436, x439)
+	var x442 uint64
+	var x443 p521Uint1
+	x442, x443 = p521AddcarryxU64(x67, x438, 0x0)
+	var x444 uint64
+	x444, _ = p521AddcarryxU64(x68, x440, x443)
+	var x446 uint64
+	var x447 p521Uint1
+	x446, x447 = p521AddcarryxU64(x143, x442, 0x0)
+	var x448 uint64
+	x448, _ = p521AddcarryxU64(x144, x444, x447)
+	var x450 uint64
+	var x451 p521Uint1
+	x450, x451 = p521AddcarryxU64(x159, x446, 0x0)
+	var x452 uint64
+	x452, _ = p521AddcarryxU64(x160, x448, x451)
+	var x454 uint64
+	var x455 p521Uint1
+	x454, x455 = p521AddcarryxU64(x195, x450, 0x0)
+	var x456 uint64
+	x456, _ = p521AddcarryxU64(x196, x452, x455)
+	x458 := ((x454 >> 58) | ((x456 << 6) & 0xffffffffffffffff))
+	x459 := (x456 >> 58)
+	x460 := (x454 & 0x3ffffffffffffff)
+	var x461 uint64
+	var x462 p521Uint1
+	x461, x462 = p521AddcarryxU64(x458, x418, 0x0)
+	var x463 uint64
+	x463, _ = p521AddcarryxU64(x459, x420, x462)
+	x465 := ((x461 >> 58) | ((x463 << 6) & 0xffffffffffffffff))
+	x466 := (x463 >> 58)
+	x467 := (x461 & 0x3ffffffffffffff)
+	var x468 uint64
+	var x469 p521Uint1
+	x468, x469 = p521AddcarryxU64(x465, x386, 0x0)
+	var x470 uint64
+	x470, _ = p521AddcarryxU64(x466, x388, x469)
+	x472 := ((x468 >> 58) | ((x470 << 6) & 0xffffffffffffffff))
+	x473 := (x470 >> 58)
+	x474 := (x468 & 0x3ffffffffffffff)
+	var x475 uint64
+	var x476 p521Uint1
+	x475, x476 = p521AddcarryxU64(x472, x354, 0x0)
+	var x477 uint64
+	x477, _ = p521AddcarryxU64(x473, x356, x476)
+	x479 := ((x475 >> 58) | ((x477 << 6) & 0xffffffffffffffff))
+	x480 := (x477 >> 58)
+	x481 := (x475 & 0x3ffffffffffffff)
+	var x482 uint64
+	var x483 p521Uint1
+	x482, x483 = p521AddcarryxU64(x479, x322, 0x0)
+	var x484 uint64
+	x484, _ = p521AddcarryxU64(x480, x324, x483)
+	x486 := ((x482 >> 58) | ((x484 << 6) & 0xffffffffffffffff))
+	x487 := (x484 >> 58)
+	x488 := (x482 & 0x3ffffffffffffff)
+	var x489 uint64
+	var x490 p521Uint1
+	x489, x490 = p521AddcarryxU64(x486, x290, 0x0)
+	var x491 uint64
+	x491, _ = p521AddcarryxU64(x487, x292, x490)
+	x493 := ((x489 >> 58) | ((x491 << 6) & 0xffffffffffffffff))
+	x494 := (x491 >> 58)
+	x495 := (x489 & 0x3ffffffffffffff)
+	var x496 uint64
+	var x497 p521Uint1
+	x496, x497 = p521AddcarryxU64(x493, x258, 0x0)
+	var x498 uint64
+	x498, _ = p521AddcarryxU64(x494, x260, x497)
+	x500 := ((x496 >> 58) | ((x498 << 6) & 0xffffffffffffffff))
+	x501 := (x498 >> 58)
+	x502 := (x496 & 0x3ffffffffffffff)
+	var x503 uint64
+	var x504 p521Uint1
+	x503, x504 = p521AddcarryxU64(x500, x226, 0x0)
+	var x505 uint64
+	x505, _ = p521AddcarryxU64(x501, x228, x504)
+	x507 := ((x503 >> 57) | ((x505 << 7) & 0xffffffffffffffff))
+	x508 := (x505 >> 57)
+	x509 := (x503 & 0x1ffffffffffffff)
+	var x510 uint64
+	var x511 p521Uint1
+	x510, x511 = p521AddcarryxU64(x197, x507, 0x0)
+	x512 := (uint64(x511) + x508)
+	x513 := ((x510 >> 58) | ((x512 << 6) & 0xffffffffffffffff))
+	x514 := (x510 & 0x3ffffffffffffff)
+	x515 := (x513 + x460)
+	x516 := p521Uint1((x515 >> 58))
+	x517 := (x515 & 0x3ffffffffffffff)
+	x518 := (uint64(x516) + x467)
+	out1[0] = x514
+	out1[1] = x517
+	out1[2] = x518
+	out1[3] = x474
+	out1[4] = x481
+	out1[5] = x488
+	out1[6] = x495
+	out1[7] = x502
+	out1[8] = x509
+}
+
+// p521CarrySquare squares a field element and reduces the result.
+//
+// Postconditions:
+//   eval out1 mod m = (eval arg1 * eval arg1) mod m
+//
+// Input Bounds:
+//   arg1: [[0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0x600000000000000]]
+// Output Bounds:
+//   out1: [[0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x200000000000000]]
+func p521CarrySquare(out1 *[9]uint64, arg1 *[9]uint64) {
+	x1 := arg1[8]
+	x2 := (x1 * 0x2)
+	x3 := (arg1[8] * 0x2)
+	x4 := arg1[7]
+	x5 := (x4 * 0x2)
+	x6 := (arg1[7] * 0x2)
+	x7 := arg1[6]
+	x8 := (x7 * 0x2)
+	x9 := (arg1[6] * 0x2)
+	x10 := arg1[5]
+	x11 := (x10 * 0x2)
+	x12 := (arg1[5] * 0x2)
+	x13 := (arg1[4] * 0x2)
+	x14 := (arg1[3] * 0x2)
+	x15 := (arg1[2] * 0x2)
+	x16 := (arg1[1] * 0x2)
+	var x17 uint64
+	var x18 uint64
+	x18, x17 = bits.Mul64(arg1[8], (x1 * 0x2))
+	var x19 uint64
+	var x20 uint64
+	x20, x19 = bits.Mul64(arg1[7], (x2 * 0x2))
+	var x21 uint64
+	var x22 uint64
+	x22, x21 = bits.Mul64(arg1[7], (x4 * 0x2))
+	var x23 uint64
+	var x24 uint64
+	x24, x23 = bits.Mul64(arg1[6], (x2 * 0x2))
+	var x25 uint64
+	var x26 uint64
+	x26, x25 = bits.Mul64(arg1[6], (x5 * 0x2))
+	var x27 uint64
+	var x28 uint64
+	x28, x27 = bits.Mul64(arg1[6], (x7 * 0x2))
+	var x29 uint64
+	var x30 uint64
+	x30, x29 = bits.Mul64(arg1[5], (x2 * 0x2))
+	var x31 uint64
+	var x32 uint64
+	x32, x31 = bits.Mul64(arg1[5], (x5 * 0x2))
+	var x33 uint64
+	var x34 uint64
+	x34, x33 = bits.Mul64(arg1[5], (x8 * 0x2))
+	var x35 uint64
+	var x36 uint64
+	x36, x35 = bits.Mul64(arg1[5], (x10 * 0x2))
+	var x37 uint64
+	var x38 uint64
+	x38, x37 = bits.Mul64(arg1[4], (x2 * 0x2))
+	var x39 uint64
+	var x40 uint64
+	x40, x39 = bits.Mul64(arg1[4], (x5 * 0x2))
+	var x41 uint64
+	var x42 uint64
+	x42, x41 = bits.Mul64(arg1[4], (x8 * 0x2))
+	var x43 uint64
+	var x44 uint64
+	x44, x43 = bits.Mul64(arg1[4], (x11 * 0x2))
+	var x45 uint64
+	var x46 uint64
+	x46, x45 = bits.Mul64(arg1[4], arg1[4])
+	var x47 uint64
+	var x48 uint64
+	x48, x47 = bits.Mul64(arg1[3], (x2 * 0x2))
+	var x49 uint64
+	var x50 uint64
+	x50, x49 = bits.Mul64(arg1[3], (x5 * 0x2))
+	var x51 uint64
+	var x52 uint64
+	x52, x51 = bits.Mul64(arg1[3], (x8 * 0x2))
+	var x53 uint64
+	var x54 uint64
+	x54, x53 = bits.Mul64(arg1[3], x12)
+	var x55 uint64
+	var x56 uint64
+	x56, x55 = bits.Mul64(arg1[3], x13)
+	var x57 uint64
+	var x58 uint64
+	x58, x57 = bits.Mul64(arg1[3], arg1[3])
+	var x59 uint64
+	var x60 uint64
+	x60, x59 = bits.Mul64(arg1[2], (x2 * 0x2))
+	var x61 uint64
+	var x62 uint64
+	x62, x61 = bits.Mul64(arg1[2], (x5 * 0x2))
+	var x63 uint64
+	var x64 uint64
+	x64, x63 = bits.Mul64(arg1[2], x9)
+	var x65 uint64
+	var x66 uint64
+	x66, x65 = bits.Mul64(arg1[2], x12)
+	var x67 uint64
+	var x68 uint64
+	x68, x67 = bits.Mul64(arg1[2], x13)
+	var x69 uint64
+	var x70 uint64
+	x70, x69 = bits.Mul64(arg1[2], x14)
+	var x71 uint64
+	var x72 uint64
+	x72, x71 = bits.Mul64(arg1[2], arg1[2])
+	var x73 uint64
+	var x74 uint64
+	x74, x73 = bits.Mul64(arg1[1], (x2 * 0x2))
+	var x75 uint64
+	var x76 uint64
+	x76, x75 = bits.Mul64(arg1[1], x6)
+	var x77 uint64
+	var x78 uint64
+	x78, x77 = bits.Mul64(arg1[1], x9)
+	var x79 uint64
+	var x80 uint64
+	x80, x79 = bits.Mul64(arg1[1], x12)
+	var x81 uint64
+	var x82 uint64
+	x82, x81 = bits.Mul64(arg1[1], x13)
+	var x83 uint64
+	var x84 uint64
+	x84, x83 = bits.Mul64(arg1[1], x14)
+	var x85 uint64
+	var x86 uint64
+	x86, x85 = bits.Mul64(arg1[1], x15)
+	var x87 uint64
+	var x88 uint64
+	x88, x87 = bits.Mul64(arg1[1], arg1[1])
+	var x89 uint64
+	var x90 uint64
+	x90, x89 = bits.Mul64(arg1[0], x3)
+	var x91 uint64
+	var x92 uint64
+	x92, x91 = bits.Mul64(arg1[0], x6)
+	var x93 uint64
+	var x94 uint64
+	x94, x93 = bits.Mul64(arg1[0], x9)
+	var x95 uint64
+	var x96 uint64
+	x96, x95 = bits.Mul64(arg1[0], x12)
+	var x97 uint64
+	var x98 uint64
+	x98, x97 = bits.Mul64(arg1[0], x13)
+	var x99 uint64
+	var x100 uint64
+	x100, x99 = bits.Mul64(arg1[0], x14)
+	var x101 uint64
+	var x102 uint64
+	x102, x101 = bits.Mul64(arg1[0], x15)
+	var x103 uint64
+	var x104 uint64
+	x104, x103 = bits.Mul64(arg1[0], x16)
+	var x105 uint64
+	var x106 uint64
+	x106, x105 = bits.Mul64(arg1[0], arg1[0])
+	var x107 uint64
+	var x108 p521Uint1
+	x107, x108 = p521AddcarryxU64(x51, x43, 0x0)
+	var x109 uint64
+	x109, _ = p521AddcarryxU64(x52, x44, x108)
+	var x111 uint64
+	var x112 p521Uint1
+	x111, x112 = p521AddcarryxU64(x61, x107, 0x0)
+	var x113 uint64
+	x113, _ = p521AddcarryxU64(x62, x109, x112)
+	var x115 uint64
+	var x116 p521Uint1
+	x115, x116 = p521AddcarryxU64(x73, x111, 0x0)
+	var x117 uint64
+	x117, _ = p521AddcarryxU64(x74, x113, x116)
+	var x119 uint64
+	var x120 p521Uint1
+	x119, x120 = p521AddcarryxU64(x105, x115, 0x0)
+	var x121 uint64
+	x121, _ = p521AddcarryxU64(x106, x117, x120)
+	x123 := ((x119 >> 58) | ((x121 << 6) & 0xffffffffffffffff))
+	x124 := (x121 >> 58)
+	x125 := (x119 & 0x3ffffffffffffff)
+	var x126 uint64
+	var x127 p521Uint1
+	x126, x127 = p521AddcarryxU64(x53, x45, 0x0)
+	var x128 uint64
+	x128, _ = p521AddcarryxU64(x54, x46, x127)
+	var x130 uint64
+	var x131 p521Uint1
+	x130, x131 = p521AddcarryxU64(x63, x126, 0x0)
+	var x132 uint64
+	x132, _ = p521AddcarryxU64(x64, x128, x131)
+	var x134 uint64
+	var x135 p521Uint1
+	x134, x135 = p521AddcarryxU64(x75, x130, 0x0)
+	var x136 uint64
+	x136, _ = p521AddcarryxU64(x76, x132, x135)
+	var x138 uint64
+	var x139 p521Uint1
+	x138, x139 = p521AddcarryxU64(x89, x134, 0x0)
+	var x140 uint64
+	x140, _ = p521AddcarryxU64(x90, x136, x139)
+	var x142 uint64
+	var x143 p521Uint1
+	x142, x143 = p521AddcarryxU64(x55, x17, 0x0)
+	var x144 uint64
+	x144, _ = p521AddcarryxU64(x56, x18, x143)
+	var x146 uint64
+	var x147 p521Uint1
+	x146, x147 = p521AddcarryxU64(x65, x142, 0x0)
+	var x148 uint64
+	x148, _ = p521AddcarryxU64(x66, x144, x147)
+	var x150 uint64
+	var x151 p521Uint1
+	x150, x151 = p521AddcarryxU64(x77, x146, 0x0)
+	var x152 uint64
+	x152, _ = p521AddcarryxU64(x78, x148, x151)
+	var x154 uint64
+	var x155 p521Uint1
+	x154, x155 = p521AddcarryxU64(x91, x150, 0x0)
+	var x156 uint64
+	x156, _ = p521AddcarryxU64(x92, x152, x155)
+	var x158 uint64
+	var x159 p521Uint1
+	x158, x159 = p521AddcarryxU64(x57, x19, 0x0)
+	var x160 uint64
+	x160, _ = p521AddcarryxU64(x58, x20, x159)
+	var x162 uint64
+	var x163 p521Uint1
+	x162, x163 = p521AddcarryxU64(x67, x158, 0x0)
+	var x164 uint64
+	x164, _ = p521AddcarryxU64(x68, x160, x163)
+	var x166 uint64
+	var x167 p521Uint1
+	x166, x167 = p521AddcarryxU64(x79, x162, 0x0)
+	var x168 uint64
+	x168, _ = p521AddcarryxU64(x80, x164, x167)
+	var x170 uint64
+	var x171 p521Uint1
+	x170, x171 = p521AddcarryxU64(x93, x166, 0x0)
+	var x172 uint64
+	x172, _ = p521AddcarryxU64(x94, x168, x171)
+	var x174 uint64
+	var x175 p521Uint1
+	x174, x175 = p521AddcarryxU64(x23, x21, 0x0)
+	var x176 uint64
+	x176, _ = p521AddcarryxU64(x24, x22, x175)
+	var x178 uint64
+	var x179 p521Uint1
+	x178, x179 = p521AddcarryxU64(x69, x174, 0x0)
+	var x180 uint64
+	x180, _ = p521AddcarryxU64(x70, x176, x179)
+	var x182 uint64
+	var x183 p521Uint1
+	x182, x183 = p521AddcarryxU64(x81, x178, 0x0)
+	var x184 uint64
+	x184, _ = p521AddcarryxU64(x82, x180, x183)
+	var x186 uint64
+	var x187 p521Uint1
+	x186, x187 = p521AddcarryxU64(x95, x182, 0x0)
+	var x188 uint64
+	x188, _ = p521AddcarryxU64(x96, x184, x187)
+	var x190 uint64
+	var x191 p521Uint1
+	x190, x191 = p521AddcarryxU64(x29, x25, 0x0)
+	var x192 uint64
+	x192, _ = p521AddcarryxU64(x30, x26, x191)
+	var x194 uint64
+	var x195 p521Uint1
+	x194, x195 = p521AddcarryxU64(x71, x190, 0x0)
+	var x196 uint64
+	x196, _ = p521AddcarryxU64(x72, x192, x195)
+	var x198 uint64
+	var x199 p521Uint1
+	x198, x199 = p521AddcarryxU64(x83, x194, 0x0)
+	var x200 uint64
+	x200, _ = p521AddcarryxU64(x84, x196, x199)
+	var x202 uint64
+	var x203 p521Uint1
+	x202, x203 = p521AddcarryxU64(x97, x198, 0x0)
+	var x204 uint64
+	x204, _ = p521AddcarryxU64(x98, x200, x203)
+	var x206 uint64
+	var x207 p521Uint1
+	x206, x207 = p521AddcarryxU64(x31, x27, 0x0)
+	var x208 uint64
+	x208, _ = p521AddcarryxU64(x32, x28, x207)
+	var x210 uint64
+	var x211 p521Uint1
+	x210, x211 = p521AddcarryxU64(x37, x206, 0x0)
+	var x212 uint64
+	x212, _ = p521AddcarryxU64(x38, x208, x211)
+	var x214 uint64
+	var x215 p521Uint1
+	x214, x215 = p521AddcarryxU64(x85, x210, 0x0)
+	var x216 uint64
+	x216, _ = p521AddcarryxU64(x86, x212, x215)
+	var x218 uint64
+	var x219 p521Uint1
+	x218, x219 = p521AddcarryxU64(x99, x214, 0x0)
+	var x220 uint64
+	x220, _ = p521AddcarryxU64(x100, x216, x219)
+	var x222 uint64
+	var x223 p521Uint1
+	x222, x223 = p521AddcarryxU64(x39, x33, 0x0)
+	var x224 uint64
+	x224, _ = p521AddcarryxU64(x40, x34, x223)
+	var x226 uint64
+	var x227 p521Uint1
+	x226, x227 = p521AddcarryxU64(x47, x222, 0x0)
+	var x228 uint64
+	x228, _ = p521AddcarryxU64(x48, x224, x227)
+	var x230 uint64
+	var x231 p521Uint1
+	x230, x231 = p521AddcarryxU64(x87, x226, 0x0)
+	var x232 uint64
+	x232, _ = p521AddcarryxU64(x88, x228, x231)
+	var x234 uint64
+	var x235 p521Uint1
+	x234, x235 = p521AddcarryxU64(x101, x230, 0x0)
+	var x236 uint64
+	x236, _ = p521AddcarryxU64(x102, x232, x235)
+	var x238 uint64
+	var x239 p521Uint1
+	x238, x239 = p521AddcarryxU64(x41, x35, 0x0)
+	var x240 uint64
+	x240, _ = p521AddcarryxU64(x42, x36, x239)
+	var x242 uint64
+	var x243 p521Uint1
+	x242, x243 = p521AddcarryxU64(x49, x238, 0x0)
+	var x244 uint64
+	x244, _ = p521AddcarryxU64(x50, x240, x243)
+	var x246 uint64
+	var x247 p521Uint1
+	x246, x247 = p521AddcarryxU64(x59, x242, 0x0)
+	var x248 uint64
+	x248, _ = p521AddcarryxU64(x60, x244, x247)
+	var x250 uint64
+	var x251 p521Uint1
+	x250, x251 = p521AddcarryxU64(x103, x246, 0x0)
+	var x252 uint64
+	x252, _ = p521AddcarryxU64(x104, x248, x251)
+	var x254 uint64
+	var x255 p521Uint1
+	x254, x255 = p521AddcarryxU64(x123, x250, 0x0)
+	var x256 uint64
+	x256, _ = p521AddcarryxU64(x124, x252, x255)
+	x258 := ((x254 >> 58) | ((x256 << 6) & 0xffffffffffffffff))
+	x259 := (x256 >> 58)
+	x260 := (x254 & 0x3ffffffffffffff)
+	var x261 uint64
+	var x262 p521Uint1
+	x261, x262 = p521AddcarryxU64(x258, x234, 0x0)
+	var x263 uint64
+	x263, _ = p521AddcarryxU64(x259, x236, x262)
+	x265 := ((x261 >> 58) | ((x263 << 6) & 0xffffffffffffffff))
+	x266 := (x263 >> 58)
+	x267 := (x261 & 0x3ffffffffffffff)
+	var x268 uint64
+	var x269 p521Uint1
+	x268, x269 = p521AddcarryxU64(x265, x218, 0x0)
+	var x270 uint64
+	x270, _ = p521AddcarryxU64(x266, x220, x269)
+	x272 := ((x268 >> 58) | ((x270 << 6) & 0xffffffffffffffff))
+	x273 := (x270 >> 58)
+	x274 := (x268 & 0x3ffffffffffffff)
+	var x275 uint64
+	var x276 p521Uint1
+	x275, x276 = p521AddcarryxU64(x272, x202, 0x0)
+	var x277 uint64
+	x277, _ = p521AddcarryxU64(x273, x204, x276)
+	x279 := ((x275 >> 58) | ((x277 << 6) & 0xffffffffffffffff))
+	x280 := (x277 >> 58)
+	x281 := (x275 & 0x3ffffffffffffff)
+	var x282 uint64
+	var x283 p521Uint1
+	x282, x283 = p521AddcarryxU64(x279, x186, 0x0)
+	var x284 uint64
+	x284, _ = p521AddcarryxU64(x280, x188, x283)
+	x286 := ((x282 >> 58) | ((x284 << 6) & 0xffffffffffffffff))
+	x287 := (x284 >> 58)
+	x288 := (x282 & 0x3ffffffffffffff)
+	var x289 uint64
+	var x290 p521Uint1
+	x289, x290 = p521AddcarryxU64(x286, x170, 0x0)
+	var x291 uint64
+	x291, _ = p521AddcarryxU64(x287, x172, x290)
+	x293 := ((x289 >> 58) | ((x291 << 6) & 0xffffffffffffffff))
+	x294 := (x291 >> 58)
+	x295 := (x289 & 0x3ffffffffffffff)
+	var x296 uint64
+	var x297 p521Uint1
+	x296, x297 = p521AddcarryxU64(x293, x154, 0x0)
+	var x298 uint64
+	x298, _ = p521AddcarryxU64(x294, x156, x297)
+	x300 := ((x296 >> 58) | ((x298 << 6) & 0xffffffffffffffff))
+	x301 := (x298 >> 58)
+	x302 := (x296 & 0x3ffffffffffffff)
+	var x303 uint64
+	var x304 p521Uint1
+	x303, x304 = p521AddcarryxU64(x300, x138, 0x0)
+	var x305 uint64
+	x305, _ = p521AddcarryxU64(x301, x140, x304)
+	x307 := ((x303 >> 57) | ((x305 << 7) & 0xffffffffffffffff))
+	x308 := (x305 >> 57)
+	x309 := (x303 & 0x1ffffffffffffff)
+	var x310 uint64
+	var x311 p521Uint1
+	x310, x311 = p521AddcarryxU64(x125, x307, 0x0)
+	x312 := (uint64(x311) + x308)
+	x313 := ((x310 >> 58) | ((x312 << 6) & 0xffffffffffffffff))
+	x314 := (x310 & 0x3ffffffffffffff)
+	x315 := (x313 + x260)
+	x316 := p521Uint1((x315 >> 58))
+	x317 := (x315 & 0x3ffffffffffffff)
+	x318 := (uint64(x316) + x267)
+	out1[0] = x314
+	out1[1] = x317
+	out1[2] = x318
+	out1[3] = x274
+	out1[4] = x281
+	out1[5] = x288
+	out1[6] = x295
+	out1[7] = x302
+	out1[8] = x309
+}
+
+// p521Carry reduces a field element.
+//
+// Postconditions:
+//   eval out1 mod m = eval arg1 mod m
+//
+// Input Bounds:
+//   arg1: [[0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0x600000000000000]]
+// Output Bounds:
+//   out1: [[0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x200000000000000]]
+func p521Carry(out1 *[9]uint64, arg1 *[9]uint64) {
+	x1 := arg1[0]
+	x2 := ((x1 >> 58) + arg1[1])
+	x3 := ((x2 >> 58) + arg1[2])
+	x4 := ((x3 >> 58) + arg1[3])
+	x5 := ((x4 >> 58) + arg1[4])
+	x6 := ((x5 >> 58) + arg1[5])
+	x7 := ((x6 >> 58) + arg1[6])
+	x8 := ((x7 >> 58) + arg1[7])
+	x9 := ((x8 >> 58) + arg1[8])
+	x10 := ((x1 & 0x3ffffffffffffff) + (x9 >> 57))
+	x11 := (uint64(p521Uint1((x10 >> 58))) + (x2 & 0x3ffffffffffffff))
+	x12 := (x10 & 0x3ffffffffffffff)
+	x13 := (x11 & 0x3ffffffffffffff)
+	x14 := (uint64(p521Uint1((x11 >> 58))) + (x3 & 0x3ffffffffffffff))
+	x15 := (x4 & 0x3ffffffffffffff)
+	x16 := (x5 & 0x3ffffffffffffff)
+	x17 := (x6 & 0x3ffffffffffffff)
+	x18 := (x7 & 0x3ffffffffffffff)
+	x19 := (x8 & 0x3ffffffffffffff)
+	x20 := (x9 & 0x1ffffffffffffff)
+	out1[0] = x12
+	out1[1] = x13
+	out1[2] = x14
+	out1[3] = x15
+	out1[4] = x16
+	out1[5] = x17
+	out1[6] = x18
+	out1[7] = x19
+	out1[8] = x20
+}
+
+// p521Add adds two field elements.
+//
+// Postconditions:
+//   eval out1 mod m = (eval arg1 + eval arg2) mod m
+//
+// Input Bounds:
+//   arg1: [[0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x200000000000000]]
+//   arg2: [[0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x200000000000000]]
+// Output Bounds:
+//   out1: [[0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0x600000000000000]]
+func p521Add(out1 *[9]uint64, arg1 *[9]uint64, arg2 *[9]uint64) {
+	x1 := (arg1[0] + arg2[0])
+	x2 := (arg1[1] + arg2[1])
+	x3 := (arg1[2] + arg2[2])
+	x4 := (arg1[3] + arg2[3])
+	x5 := (arg1[4] + arg2[4])
+	x6 := (arg1[5] + arg2[5])
+	x7 := (arg1[6] + arg2[6])
+	x8 := (arg1[7] + arg2[7])
+	x9 := (arg1[8] + arg2[8])
+	out1[0] = x1
+	out1[1] = x2
+	out1[2] = x3
+	out1[3] = x4
+	out1[4] = x5
+	out1[5] = x6
+	out1[6] = x7
+	out1[7] = x8
+	out1[8] = x9
+}
+
+// p521Sub subtracts two field elements.
+//
+// Postconditions:
+//   eval out1 mod m = (eval arg1 - eval arg2) mod m
+//
+// Input Bounds:
+//   arg1: [[0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x200000000000000]]
+//   arg2: [[0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x200000000000000]]
+// Output Bounds:
+//   out1: [[0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0xc00000000000000], [0x0 ~> 0x600000000000000]]
+func p521Sub(out1 *[9]uint64, arg1 *[9]uint64, arg2 *[9]uint64) {
+	x1 := ((0x7fffffffffffffe + arg1[0]) - arg2[0])
+	x2 := ((0x7fffffffffffffe + arg1[1]) - arg2[1])
+	x3 := ((0x7fffffffffffffe + arg1[2]) - arg2[2])
+	x4 := ((0x7fffffffffffffe + arg1[3]) - arg2[3])
+	x5 := ((0x7fffffffffffffe + arg1[4]) - arg2[4])
+	x6 := ((0x7fffffffffffffe + arg1[5]) - arg2[5])
+	x7 := ((0x7fffffffffffffe + arg1[6]) - arg2[6])
+	x8 := ((0x7fffffffffffffe + arg1[7]) - arg2[7])
+	x9 := ((0x3fffffffffffffe + arg1[8]) - arg2[8])
+	out1[0] = x1
+	out1[1] = x2
+	out1[2] = x3
+	out1[3] = x4
+	out1[4] = x5
+	out1[5] = x6
+	out1[6] = x7
+	out1[7] = x8
+	out1[8] = x9
+}
+
+// p521ToBytes serializes a field element to bytes in little-endian order.
+//
+// Postconditions:
+//   out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..65]
+//
+// Input Bounds:
+//   arg1: [[0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x200000000000000]]
+// Output Bounds:
+//   out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x1]]
+func p521ToBytes(out1 *[66]uint8, arg1 *[9]uint64) {
+	var x1 uint64
+	var x2 p521Uint1
+	p521SubborrowxU58(&x1, &x2, 0x0, arg1[0], 0x3ffffffffffffff)
+	var x3 uint64
+	var x4 p521Uint1
+	p521SubborrowxU58(&x3, &x4, x2, arg1[1], 0x3ffffffffffffff)
+	var x5 uint64
+	var x6 p521Uint1
+	p521SubborrowxU58(&x5, &x6, x4, arg1[2], 0x3ffffffffffffff)
+	var x7 uint64
+	var x8 p521Uint1
+	p521SubborrowxU58(&x7, &x8, x6, arg1[3], 0x3ffffffffffffff)
+	var x9 uint64
+	var x10 p521Uint1
+	p521SubborrowxU58(&x9, &x10, x8, arg1[4], 0x3ffffffffffffff)
+	var x11 uint64
+	var x12 p521Uint1
+	p521SubborrowxU58(&x11, &x12, x10, arg1[5], 0x3ffffffffffffff)
+	var x13 uint64
+	var x14 p521Uint1
+	p521SubborrowxU58(&x13, &x14, x12, arg1[6], 0x3ffffffffffffff)
+	var x15 uint64
+	var x16 p521Uint1
+	p521SubborrowxU58(&x15, &x16, x14, arg1[7], 0x3ffffffffffffff)
+	var x17 uint64
+	var x18 p521Uint1
+	p521SubborrowxU57(&x17, &x18, x16, arg1[8], 0x1ffffffffffffff)
+	var x19 uint64
+	p521CmovznzU64(&x19, x18, uint64(0x0), 0xffffffffffffffff)
+	var x20 uint64
+	var x21 p521Uint1
+	p521AddcarryxU58(&x20, &x21, 0x0, x1, (x19 & 0x3ffffffffffffff))
+	var x22 uint64
+	var x23 p521Uint1
+	p521AddcarryxU58(&x22, &x23, x21, x3, (x19 & 0x3ffffffffffffff))
+	var x24 uint64
+	var x25 p521Uint1
+	p521AddcarryxU58(&x24, &x25, x23, x5, (x19 & 0x3ffffffffffffff))
+	var x26 uint64
+	var x27 p521Uint1
+	p521AddcarryxU58(&x26, &x27, x25, x7, (x19 & 0x3ffffffffffffff))
+	var x28 uint64
+	var x29 p521Uint1
+	p521AddcarryxU58(&x28, &x29, x27, x9, (x19 & 0x3ffffffffffffff))
+	var x30 uint64
+	var x31 p521Uint1
+	p521AddcarryxU58(&x30, &x31, x29, x11, (x19 & 0x3ffffffffffffff))
+	var x32 uint64
+	var x33 p521Uint1
+	p521AddcarryxU58(&x32, &x33, x31, x13, (x19 & 0x3ffffffffffffff))
+	var x34 uint64
+	var x35 p521Uint1
+	p521AddcarryxU58(&x34, &x35, x33, x15, (x19 & 0x3ffffffffffffff))
+	var x36 uint64
+	var x37 p521Uint1
+	p521AddcarryxU57(&x36, &x37, x35, x17, (x19 & 0x1ffffffffffffff))
+	x38 := (x34 << 6)
+	x39 := (x32 << 4)
+	x40 := (x30 << 2)
+	x41 := (x26 << 6)
+	x42 := (x24 << 4)
+	x43 := (x22 << 2)
+	x44 := (uint8(x20) & 0xff)
+	x45 := (x20 >> 8)
+	x46 := (uint8(x45) & 0xff)
+	x47 := (x45 >> 8)
+	x48 := (uint8(x47) & 0xff)
+	x49 := (x47 >> 8)
+	x50 := (uint8(x49) & 0xff)
+	x51 := (x49 >> 8)
+	x52 := (uint8(x51) & 0xff)
+	x53 := (x51 >> 8)
+	x54 := (uint8(x53) & 0xff)
+	x55 := (x53 >> 8)
+	x56 := (uint8(x55) & 0xff)
+	x57 := uint8((x55 >> 8))
+	x58 := (x43 + uint64(x57))
+	x59 := (uint8(x58) & 0xff)
+	x60 := (x58 >> 8)
+	x61 := (uint8(x60) & 0xff)
+	x62 := (x60 >> 8)
+	x63 := (uint8(x62) & 0xff)
+	x64 := (x62 >> 8)
+	x65 := (uint8(x64) & 0xff)
+	x66 := (x64 >> 8)
+	x67 := (uint8(x66) & 0xff)
+	x68 := (x66 >> 8)
+	x69 := (uint8(x68) & 0xff)
+	x70 := (x68 >> 8)
+	x71 := (uint8(x70) & 0xff)
+	x72 := uint8((x70 >> 8))
+	x73 := (x42 + uint64(x72))
+	x74 := (uint8(x73) & 0xff)
+	x75 := (x73 >> 8)
+	x76 := (uint8(x75) & 0xff)
+	x77 := (x75 >> 8)
+	x78 := (uint8(x77) & 0xff)
+	x79 := (x77 >> 8)
+	x80 := (uint8(x79) & 0xff)
+	x81 := (x79 >> 8)
+	x82 := (uint8(x81) & 0xff)
+	x83 := (x81 >> 8)
+	x84 := (uint8(x83) & 0xff)
+	x85 := (x83 >> 8)
+	x86 := (uint8(x85) & 0xff)
+	x87 := uint8((x85 >> 8))
+	x88 := (x41 + uint64(x87))
+	x89 := (uint8(x88) & 0xff)
+	x90 := (x88 >> 8)
+	x91 := (uint8(x90) & 0xff)
+	x92 := (x90 >> 8)
+	x93 := (uint8(x92) & 0xff)
+	x94 := (x92 >> 8)
+	x95 := (uint8(x94) & 0xff)
+	x96 := (x94 >> 8)
+	x97 := (uint8(x96) & 0xff)
+	x98 := (x96 >> 8)
+	x99 := (uint8(x98) & 0xff)
+	x100 := (x98 >> 8)
+	x101 := (uint8(x100) & 0xff)
+	x102 := uint8((x100 >> 8))
+	x103 := (uint8(x28) & 0xff)
+	x104 := (x28 >> 8)
+	x105 := (uint8(x104) & 0xff)
+	x106 := (x104 >> 8)
+	x107 := (uint8(x106) & 0xff)
+	x108 := (x106 >> 8)
+	x109 := (uint8(x108) & 0xff)
+	x110 := (x108 >> 8)
+	x111 := (uint8(x110) & 0xff)
+	x112 := (x110 >> 8)
+	x113 := (uint8(x112) & 0xff)
+	x114 := (x112 >> 8)
+	x115 := (uint8(x114) & 0xff)
+	x116 := uint8((x114 >> 8))
+	x117 := (x40 + uint64(x116))
+	x118 := (uint8(x117) & 0xff)
+	x119 := (x117 >> 8)
+	x120 := (uint8(x119) & 0xff)
+	x121 := (x119 >> 8)
+	x122 := (uint8(x121) & 0xff)
+	x123 := (x121 >> 8)
+	x124 := (uint8(x123) & 0xff)
+	x125 := (x123 >> 8)
+	x126 := (uint8(x125) & 0xff)
+	x127 := (x125 >> 8)
+	x128 := (uint8(x127) & 0xff)
+	x129 := (x127 >> 8)
+	x130 := (uint8(x129) & 0xff)
+	x131 := uint8((x129 >> 8))
+	x132 := (x39 + uint64(x131))
+	x133 := (uint8(x132) & 0xff)
+	x134 := (x132 >> 8)
+	x135 := (uint8(x134) & 0xff)
+	x136 := (x134 >> 8)
+	x137 := (uint8(x136) & 0xff)
+	x138 := (x136 >> 8)
+	x139 := (uint8(x138) & 0xff)
+	x140 := (x138 >> 8)
+	x141 := (uint8(x140) & 0xff)
+	x142 := (x140 >> 8)
+	x143 := (uint8(x142) & 0xff)
+	x144 := (x142 >> 8)
+	x145 := (uint8(x144) & 0xff)
+	x146 := uint8((x144 >> 8))
+	x147 := (x38 + uint64(x146))
+	x148 := (uint8(x147) & 0xff)
+	x149 := (x147 >> 8)
+	x150 := (uint8(x149) & 0xff)
+	x151 := (x149 >> 8)
+	x152 := (uint8(x151) & 0xff)
+	x153 := (x151 >> 8)
+	x154 := (uint8(x153) & 0xff)
+	x155 := (x153 >> 8)
+	x156 := (uint8(x155) & 0xff)
+	x157 := (x155 >> 8)
+	x158 := (uint8(x157) & 0xff)
+	x159 := (x157 >> 8)
+	x160 := (uint8(x159) & 0xff)
+	x161 := uint8((x159 >> 8))
+	x162 := (uint8(x36) & 0xff)
+	x163 := (x36 >> 8)
+	x164 := (uint8(x163) & 0xff)
+	x165 := (x163 >> 8)
+	x166 := (uint8(x165) & 0xff)
+	x167 := (x165 >> 8)
+	x168 := (uint8(x167) & 0xff)
+	x169 := (x167 >> 8)
+	x170 := (uint8(x169) & 0xff)
+	x171 := (x169 >> 8)
+	x172 := (uint8(x171) & 0xff)
+	x173 := (x171 >> 8)
+	x174 := (uint8(x173) & 0xff)
+	x175 := p521Uint1((x173 >> 8))
+	out1[0] = x44
+	out1[1] = x46
+	out1[2] = x48
+	out1[3] = x50
+	out1[4] = x52
+	out1[5] = x54
+	out1[6] = x56
+	out1[7] = x59
+	out1[8] = x61
+	out1[9] = x63
+	out1[10] = x65
+	out1[11] = x67
+	out1[12] = x69
+	out1[13] = x71
+	out1[14] = x74
+	out1[15] = x76
+	out1[16] = x78
+	out1[17] = x80
+	out1[18] = x82
+	out1[19] = x84
+	out1[20] = x86
+	out1[21] = x89
+	out1[22] = x91
+	out1[23] = x93
+	out1[24] = x95
+	out1[25] = x97
+	out1[26] = x99
+	out1[27] = x101
+	out1[28] = x102
+	out1[29] = x103
+	out1[30] = x105
+	out1[31] = x107
+	out1[32] = x109
+	out1[33] = x111
+	out1[34] = x113
+	out1[35] = x115
+	out1[36] = x118
+	out1[37] = x120
+	out1[38] = x122
+	out1[39] = x124
+	out1[40] = x126
+	out1[41] = x128
+	out1[42] = x130
+	out1[43] = x133
+	out1[44] = x135
+	out1[45] = x137
+	out1[46] = x139
+	out1[47] = x141
+	out1[48] = x143
+	out1[49] = x145
+	out1[50] = x148
+	out1[51] = x150
+	out1[52] = x152
+	out1[53] = x154
+	out1[54] = x156
+	out1[55] = x158
+	out1[56] = x160
+	out1[57] = x161
+	out1[58] = x162
+	out1[59] = x164
+	out1[60] = x166
+	out1[61] = x168
+	out1[62] = x170
+	out1[63] = x172
+	out1[64] = x174
+	out1[65] = uint8(x175)
+}
+
+// p521FromBytes deserializes a field element from bytes in little-endian order.
+//
+// Postconditions:
+//   eval out1 mod m = bytes_eval arg1 mod m
+//
+// Input Bounds:
+//   arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x1]]
+// Output Bounds:
+//   out1: [[0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x400000000000000], [0x0 ~> 0x200000000000000]]
+func p521FromBytes(out1 *[9]uint64, arg1 *[66]uint8) {
+	x1 := (uint64(p521Uint1(arg1[65])) << 56)
+	x2 := (uint64(arg1[64]) << 48)
+	x3 := (uint64(arg1[63]) << 40)
+	x4 := (uint64(arg1[62]) << 32)
+	x5 := (uint64(arg1[61]) << 24)
+	x6 := (uint64(arg1[60]) << 16)
+	x7 := (uint64(arg1[59]) << 8)
+	x8 := arg1[58]
+	x9 := (uint64(arg1[57]) << 50)
+	x10 := (uint64(arg1[56]) << 42)
+	x11 := (uint64(arg1[55]) << 34)
+	x12 := (uint64(arg1[54]) << 26)
+	x13 := (uint64(arg1[53]) << 18)
+	x14 := (uint64(arg1[52]) << 10)
+	x15 := (uint64(arg1[51]) << 2)
+	x16 := (uint64(arg1[50]) << 52)
+	x17 := (uint64(arg1[49]) << 44)
+	x18 := (uint64(arg1[48]) << 36)
+	x19 := (uint64(arg1[47]) << 28)
+	x20 := (uint64(arg1[46]) << 20)
+	x21 := (uint64(arg1[45]) << 12)
+	x22 := (uint64(arg1[44]) << 4)
+	x23 := (uint64(arg1[43]) << 54)
+	x24 := (uint64(arg1[42]) << 46)
+	x25 := (uint64(arg1[41]) << 38)
+	x26 := (uint64(arg1[40]) << 30)
+	x27 := (uint64(arg1[39]) << 22)
+	x28 := (uint64(arg1[38]) << 14)
+	x29 := (uint64(arg1[37]) << 6)
+	x30 := (uint64(arg1[36]) << 56)
+	x31 := (uint64(arg1[35]) << 48)
+	x32 := (uint64(arg1[34]) << 40)
+	x33 := (uint64(arg1[33]) << 32)
+	x34 := (uint64(arg1[32]) << 24)
+	x35 := (uint64(arg1[31]) << 16)
+	x36 := (uint64(arg1[30]) << 8)
+	x37 := arg1[29]
+	x38 := (uint64(arg1[28]) << 50)
+	x39 := (uint64(arg1[27]) << 42)
+	x40 := (uint64(arg1[26]) << 34)
+	x41 := (uint64(arg1[25]) << 26)
+	x42 := (uint64(arg1[24]) << 18)
+	x43 := (uint64(arg1[23]) << 10)
+	x44 := (uint64(arg1[22]) << 2)
+	x45 := (uint64(arg1[21]) << 52)
+	x46 := (uint64(arg1[20]) << 44)
+	x47 := (uint64(arg1[19]) << 36)
+	x48 := (uint64(arg1[18]) << 28)
+	x49 := (uint64(arg1[17]) << 20)
+	x50 := (uint64(arg1[16]) << 12)
+	x51 := (uint64(arg1[15]) << 4)
+	x52 := (uint64(arg1[14]) << 54)
+	x53 := (uint64(arg1[13]) << 46)
+	x54 := (uint64(arg1[12]) << 38)
+	x55 := (uint64(arg1[11]) << 30)
+	x56 := (uint64(arg1[10]) << 22)
+	x57 := (uint64(arg1[9]) << 14)
+	x58 := (uint64(arg1[8]) << 6)
+	x59 := (uint64(arg1[7]) << 56)
+	x60 := (uint64(arg1[6]) << 48)
+	x61 := (uint64(arg1[5]) << 40)
+	x62 := (uint64(arg1[4]) << 32)
+	x63 := (uint64(arg1[3]) << 24)
+	x64 := (uint64(arg1[2]) << 16)
+	x65 := (uint64(arg1[1]) << 8)
+	x66 := arg1[0]
+	x67 := (x65 + uint64(x66))
+	x68 := (x64 + x67)
+	x69 := (x63 + x68)
+	x70 := (x62 + x69)
+	x71 := (x61 + x70)
+	x72 := (x60 + x71)
+	x73 := (x59 + x72)
+	x74 := (x73 & 0x3ffffffffffffff)
+	x75 := uint8((x73 >> 58))
+	x76 := (x58 + uint64(x75))
+	x77 := (x57 + x76)
+	x78 := (x56 + x77)
+	x79 := (x55 + x78)
+	x80 := (x54 + x79)
+	x81 := (x53 + x80)
+	x82 := (x52 + x81)
+	x83 := (x82 & 0x3ffffffffffffff)
+	x84 := uint8((x82 >> 58))
+	x85 := (x51 + uint64(x84))
+	x86 := (x50 + x85)
+	x87 := (x49 + x86)
+	x88 := (x48 + x87)
+	x89 := (x47 + x88)
+	x90 := (x46 + x89)
+	x91 := (x45 + x90)
+	x92 := (x91 & 0x3ffffffffffffff)
+	x93 := uint8((x91 >> 58))
+	x94 := (x44 + uint64(x93))
+	x95 := (x43 + x94)
+	x96 := (x42 + x95)
+	x97 := (x41 + x96)
+	x98 := (x40 + x97)
+	x99 := (x39 + x98)
+	x100 := (x38 + x99)
+	x101 := (x36 + uint64(x37))
+	x102 := (x35 + x101)
+	x103 := (x34 + x102)
+	x104 := (x33 + x103)
+	x105 := (x32 + x104)
+	x106 := (x31 + x105)
+	x107 := (x30 + x106)
+	x108 := (x107 & 0x3ffffffffffffff)
+	x109 := uint8((x107 >> 58))
+	x110 := (x29 + uint64(x109))
+	x111 := (x28 + x110)
+	x112 := (x27 + x111)
+	x113 := (x26 + x112)
+	x114 := (x25 + x113)
+	x115 := (x24 + x114)
+	x116 := (x23 + x115)
+	x117 := (x116 & 0x3ffffffffffffff)
+	x118 := uint8((x116 >> 58))
+	x119 := (x22 + uint64(x118))
+	x120 := (x21 + x119)
+	x121 := (x20 + x120)
+	x122 := (x19 + x121)
+	x123 := (x18 + x122)
+	x124 := (x17 + x123)
+	x125 := (x16 + x124)
+	x126 := (x125 & 0x3ffffffffffffff)
+	x127 := uint8((x125 >> 58))
+	x128 := (x15 + uint64(x127))
+	x129 := (x14 + x128)
+	x130 := (x13 + x129)
+	x131 := (x12 + x130)
+	x132 := (x11 + x131)
+	x133 := (x10 + x132)
+	x134 := (x9 + x133)
+	x135 := (x7 + uint64(x8))
+	x136 := (x6 + x135)
+	x137 := (x5 + x136)
+	x138 := (x4 + x137)
+	x139 := (x3 + x138)
+	x140 := (x2 + x139)
+	x141 := (x1 + x140)
+	out1[0] = x74
+	out1[1] = x83
+	out1[2] = x92
+	out1[3] = x100
+	out1[4] = x108
+	out1[5] = x117
+	out1[6] = x126
+	out1[7] = x134
+	out1[8] = x141
+}
+
+// p521Selectznz is a multi-limb conditional select.
+//
+// Postconditions:
+//   eval out1 = (if arg1 = 0 then eval arg2 else eval arg3)
+//
+// Input Bounds:
+//   arg1: [0x0 ~> 0x1]
+//   arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
+//   arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
+// Output Bounds:
+//   out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
+func p521Selectznz(out1 *[9]uint64, arg1 p521Uint1, arg2 *[9]uint64, arg3 *[9]uint64) {
+	var x1 uint64
+	p521CmovznzU64(&x1, arg1, arg2[0], arg3[0])
+	var x2 uint64
+	p521CmovznzU64(&x2, arg1, arg2[1], arg3[1])
+	var x3 uint64
+	p521CmovznzU64(&x3, arg1, arg2[2], arg3[2])
+	var x4 uint64
+	p521CmovznzU64(&x4, arg1, arg2[3], arg3[3])
+	var x5 uint64
+	p521CmovznzU64(&x5, arg1, arg2[4], arg3[4])
+	var x6 uint64
+	p521CmovznzU64(&x6, arg1, arg2[5], arg3[5])
+	var x7 uint64
+	p521CmovznzU64(&x7, arg1, arg2[6], arg3[6])
+	var x8 uint64
+	p521CmovznzU64(&x8, arg1, arg2[7], arg3[7])
+	var x9 uint64
+	p521CmovznzU64(&x9, arg1, arg2[8], arg3[8])
+	out1[0] = x1
+	out1[1] = x2
+	out1[2] = x3
+	out1[3] = x4
+	out1[4] = x5
+	out1[5] = x6
+	out1[6] = x7
+	out1[7] = x8
+	out1[8] = x9
+}
diff --git a/src/crypto/elliptic/internal/fiat/p521_test.go b/src/crypto/elliptic/internal/fiat/p521_test.go
new file mode 100644
index 0000000..661bde3
--- /dev/null
+++ b/src/crypto/elliptic/internal/fiat/p521_test.go
@@ -0,0 +1,37 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fiat_test
+
+import (
+	"crypto/elliptic/internal/fiat"
+	"crypto/rand"
+	"testing"
+)
+
+func p521Random(t *testing.T) *fiat.P521Element {
+	buf := make([]byte, 66)
+	if _, err := rand.Read(buf); err != nil {
+		t.Fatal(err)
+	}
+	buf[65] &= 1
+	e, err := new(fiat.P521Element).SetBytes(buf)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return e
+}
+
+func TestP521Invert(t *testing.T) {
+	a := p521Random(t)
+	inv := new(fiat.P521Element).Invert(a)
+	one := new(fiat.P521Element).Mul(a, inv)
+	if new(fiat.P521Element).One().Equal(one) != 1 {
+		t.Errorf("a * 1/a != 1; got %x for %x", one.Bytes(), a.Bytes())
+	}
+	inv.Invert(new(fiat.P521Element))
+	if new(fiat.P521Element).Equal(inv) != 1 {
+		t.Errorf("1/0 != 0; got %x", inv.Bytes())
+	}
+}
diff --git a/src/crypto/elliptic/p224_test.go b/src/crypto/elliptic/p224_test.go
index c3141b6..b213b27 100644
--- a/src/crypto/elliptic/p224_test.go
+++ b/src/crypto/elliptic/p224_test.go
@@ -5,6 +5,8 @@
 package elliptic
 
 import (
+	"encoding/hex"
+	"fmt"
 	"math/big"
 	"math/bits"
 	"math/rand"
@@ -312,3 +314,316 @@
 		t.Errorf("p224Invert(a) * a = %x, expected 1", out)
 	}
 }
+
+type baseMultTest struct {
+	k    string
+	x, y string
+}
+
+var p224BaseMultTests = []baseMultTest{
+	{
+		"1",
+		"b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
+		"bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
+	},
+	{
+		"2",
+		"706a46dc76dcb76798e60e6d89474788d16dc18032d268fd1a704fa6",
+		"1c2b76a7bc25e7702a704fa986892849fca629487acf3709d2e4e8bb",
+	},
+	{
+		"3",
+		"df1b1d66a551d0d31eff822558b9d2cc75c2180279fe0d08fd896d04",
+		"a3f7f03cadd0be444c0aa56830130ddf77d317344e1af3591981a925",
+	},
+	{
+		"4",
+		"ae99feebb5d26945b54892092a8aee02912930fa41cd114e40447301",
+		"482580a0ec5bc47e88bc8c378632cd196cb3fa058a7114eb03054c9",
+	},
+	{
+		"5",
+		"31c49ae75bce7807cdff22055d94ee9021fedbb5ab51c57526f011aa",
+		"27e8bff1745635ec5ba0c9f1c2ede15414c6507d29ffe37e790a079b",
+	},
+	{
+		"6",
+		"1f2483f82572251fca975fea40db821df8ad82a3c002ee6c57112408",
+		"89faf0ccb750d99b553c574fad7ecfb0438586eb3952af5b4b153c7e",
+	},
+	{
+		"7",
+		"db2f6be630e246a5cf7d99b85194b123d487e2d466b94b24a03c3e28",
+		"f3a30085497f2f611ee2517b163ef8c53b715d18bb4e4808d02b963",
+	},
+	{
+		"8",
+		"858e6f9cc6c12c31f5df124aa77767b05c8bc021bd683d2b55571550",
+		"46dcd3ea5c43898c5c5fc4fdac7db39c2f02ebee4e3541d1e78047a",
+	},
+	{
+		"9",
+		"2fdcccfee720a77ef6cb3bfbb447f9383117e3daa4a07e36ed15f78d",
+		"371732e4f41bf4f7883035e6a79fcedc0e196eb07b48171697517463",
+	},
+	{
+		"10",
+		"aea9e17a306517eb89152aa7096d2c381ec813c51aa880e7bee2c0fd",
+		"39bb30eab337e0a521b6cba1abe4b2b3a3e524c14a3fe3eb116b655f",
+	},
+	{
+		"11",
+		"ef53b6294aca431f0f3c22dc82eb9050324f1d88d377e716448e507c",
+		"20b510004092e96636cfb7e32efded8265c266dfb754fa6d6491a6da",
+	},
+	{
+		"12",
+		"6e31ee1dc137f81b056752e4deab1443a481033e9b4c93a3044f4f7a",
+		"207dddf0385bfdeab6e9acda8da06b3bbef224a93ab1e9e036109d13",
+	},
+	{
+		"13",
+		"34e8e17a430e43289793c383fac9774247b40e9ebd3366981fcfaeca",
+		"252819f71c7fb7fbcb159be337d37d3336d7feb963724fdfb0ecb767",
+	},
+	{
+		"14",
+		"a53640c83dc208603ded83e4ecf758f24c357d7cf48088b2ce01e9fa",
+		"d5814cd724199c4a5b974a43685fbf5b8bac69459c9469bc8f23ccaf",
+	},
+	{
+		"15",
+		"baa4d8635511a7d288aebeedd12ce529ff102c91f97f867e21916bf9",
+		"979a5f4759f80f4fb4ec2e34f5566d595680a11735e7b61046127989",
+	},
+	{
+		"16",
+		"b6ec4fe1777382404ef679997ba8d1cc5cd8e85349259f590c4c66d",
+		"3399d464345906b11b00e363ef429221f2ec720d2f665d7dead5b482",
+	},
+	{
+		"17",
+		"b8357c3a6ceef288310e17b8bfeff9200846ca8c1942497c484403bc",
+		"ff149efa6606a6bd20ef7d1b06bd92f6904639dce5174db6cc554a26",
+	},
+	{
+		"18",
+		"c9ff61b040874c0568479216824a15eab1a838a797d189746226e4cc",
+		"ea98d60e5ffc9b8fcf999fab1df7e7ef7084f20ddb61bb045a6ce002",
+	},
+	{
+		"19",
+		"a1e81c04f30ce201c7c9ace785ed44cc33b455a022f2acdbc6cae83c",
+		"dcf1f6c3db09c70acc25391d492fe25b4a180babd6cea356c04719cd",
+	},
+	{
+		"20",
+		"fcc7f2b45df1cd5a3c0c0731ca47a8af75cfb0347e8354eefe782455",
+		"d5d7110274cba7cdee90e1a8b0d394c376a5573db6be0bf2747f530",
+	},
+	{
+		"112233445566778899",
+		"61f077c6f62ed802dad7c2f38f5c67f2cc453601e61bd076bb46179e",
+		"2272f9e9f5933e70388ee652513443b5e289dd135dcc0d0299b225e4",
+	},
+	{
+		"112233445566778899112233445566778899",
+		"29895f0af496bfc62b6ef8d8a65c88c613949b03668aab4f0429e35",
+		"3ea6e53f9a841f2019ec24bde1a75677aa9b5902e61081c01064de93",
+	},
+	{
+		"6950511619965839450988900688150712778015737983940691968051900319680",
+		"ab689930bcae4a4aa5f5cb085e823e8ae30fd365eb1da4aba9cf0379",
+		"3345a121bbd233548af0d210654eb40bab788a03666419be6fbd34e7",
+	},
+	{
+		"13479972933410060327035789020509431695094902435494295338570602119423",
+		"bdb6a8817c1f89da1c2f3dd8e97feb4494f2ed302a4ce2bc7f5f4025",
+		"4c7020d57c00411889462d77a5438bb4e97d177700bf7243a07f1680",
+	},
+	{
+		"13479971751745682581351455311314208093898607229429740618390390702079",
+		"d58b61aa41c32dd5eba462647dba75c5d67c83606c0af2bd928446a9",
+		"d24ba6a837be0460dd107ae77725696d211446c5609b4595976b16bd",
+	},
+	{
+		"13479972931865328106486971546324465392952975980343228160962702868479",
+		"dc9fa77978a005510980e929a1485f63716df695d7a0c18bb518df03",
+		"ede2b016f2ddffc2a8c015b134928275ce09e5661b7ab14ce0d1d403",
+	},
+	{
+		"11795773708834916026404142434151065506931607341523388140225443265536",
+		"499d8b2829cfb879c901f7d85d357045edab55028824d0f05ba279ba",
+		"bf929537b06e4015919639d94f57838fa33fc3d952598dcdbb44d638",
+	},
+	{
+		"784254593043826236572847595991346435467177662189391577090",
+		"8246c999137186632c5f9eddf3b1b0e1764c5e8bd0e0d8a554b9cb77",
+		"e80ed8660bc1cb17ac7d845be40a7a022d3306f116ae9f81fea65947",
+	},
+	{
+		"13479767645505654746623887797783387853576174193480695826442858012671",
+		"6670c20afcceaea672c97f75e2e9dd5c8460e54bb38538ebb4bd30eb",
+		"f280d8008d07a4caf54271f993527d46ff3ff46fd1190a3f1faa4f74",
+	},
+	{
+		"205688069665150753842126177372015544874550518966168735589597183",
+		"eca934247425cfd949b795cb5ce1eff401550386e28d1a4c5a8eb",
+		"d4c01040dba19628931bc8855370317c722cbd9ca6156985f1c2e9ce",
+	},
+	{
+		"13479966930919337728895168462090683249159702977113823384618282123295",
+		"ef353bf5c73cd551b96d596fbc9a67f16d61dd9fe56af19de1fba9cd",
+		"21771b9cdce3e8430c09b3838be70b48c21e15bc09ee1f2d7945b91f",
+	},
+	{
+		"50210731791415612487756441341851895584393717453129007497216",
+		"4036052a3091eb481046ad3289c95d3ac905ca0023de2c03ecd451cf",
+		"d768165a38a2b96f812586a9d59d4136035d9c853a5bf2e1c86a4993",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368041",
+		"fcc7f2b45df1cd5a3c0c0731ca47a8af75cfb0347e8354eefe782455",
+		"f2a28eefd8b345832116f1e574f2c6b2c895aa8c24941f40d8b80ad1",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368042",
+		"a1e81c04f30ce201c7c9ace785ed44cc33b455a022f2acdbc6cae83c",
+		"230e093c24f638f533dac6e2b6d01da3b5e7f45429315ca93fb8e634",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368043",
+		"c9ff61b040874c0568479216824a15eab1a838a797d189746226e4cc",
+		"156729f1a003647030666054e208180f8f7b0df2249e44fba5931fff",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368044",
+		"b8357c3a6ceef288310e17b8bfeff9200846ca8c1942497c484403bc",
+		"eb610599f95942df1082e4f9426d086fb9c6231ae8b24933aab5db",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368045",
+		"b6ec4fe1777382404ef679997ba8d1cc5cd8e85349259f590c4c66d",
+		"cc662b9bcba6f94ee4ff1c9c10bd6ddd0d138df2d099a282152a4b7f",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368046",
+		"baa4d8635511a7d288aebeedd12ce529ff102c91f97f867e21916bf9",
+		"6865a0b8a607f0b04b13d1cb0aa992a5a97f5ee8ca1849efb9ed8678",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368047",
+		"a53640c83dc208603ded83e4ecf758f24c357d7cf48088b2ce01e9fa",
+		"2a7eb328dbe663b5a468b5bc97a040a3745396ba636b964370dc3352",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368048",
+		"34e8e17a430e43289793c383fac9774247b40e9ebd3366981fcfaeca",
+		"dad7e608e380480434ea641cc82c82cbc92801469c8db0204f13489a",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368049",
+		"6e31ee1dc137f81b056752e4deab1443a481033e9b4c93a3044f4f7a",
+		"df82220fc7a4021549165325725f94c3410ddb56c54e161fc9ef62ee",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368050",
+		"ef53b6294aca431f0f3c22dc82eb9050324f1d88d377e716448e507c",
+		"df4aefffbf6d1699c930481cd102127c9a3d992048ab05929b6e5927",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368051",
+		"aea9e17a306517eb89152aa7096d2c381ec813c51aa880e7bee2c0fd",
+		"c644cf154cc81f5ade49345e541b4d4b5c1adb3eb5c01c14ee949aa2",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368052",
+		"2fdcccfee720a77ef6cb3bfbb447f9383117e3daa4a07e36ed15f78d",
+		"c8e8cd1b0be40b0877cfca1958603122f1e6914f84b7e8e968ae8b9e",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368053",
+		"858e6f9cc6c12c31f5df124aa77767b05c8bc021bd683d2b55571550",
+		"fb9232c15a3bc7673a3a03b0253824c53d0fd1411b1cabe2e187fb87",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368054",
+		"db2f6be630e246a5cf7d99b85194b123d487e2d466b94b24a03c3e28",
+		"f0c5cff7ab680d09ee11dae84e9c1072ac48ea2e744b1b7f72fd469e",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368055",
+		"1f2483f82572251fca975fea40db821df8ad82a3c002ee6c57112408",
+		"76050f3348af2664aac3a8b05281304ebc7a7914c6ad50a4b4eac383",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368056",
+		"31c49ae75bce7807cdff22055d94ee9021fedbb5ab51c57526f011aa",
+		"d817400e8ba9ca13a45f360e3d121eaaeb39af82d6001c8186f5f866",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368057",
+		"ae99feebb5d26945b54892092a8aee02912930fa41cd114e40447301",
+		"fb7da7f5f13a43b81774373c879cd32d6934c05fa758eeb14fcfab38",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368058",
+		"df1b1d66a551d0d31eff822558b9d2cc75c2180279fe0d08fd896d04",
+		"5c080fc3522f41bbb3f55a97cfecf21f882ce8cbb1e50ca6e67e56dc",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368059",
+		"706a46dc76dcb76798e60e6d89474788d16dc18032d268fd1a704fa6",
+		"e3d4895843da188fd58fb0567976d7b50359d6b78530c8f62d1b1746",
+	},
+	{
+		"26959946667150639794667015087019625940457807714424391721682722368060",
+		"b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
+		"42c89c774a08dc04b3dd201932bc8a5ea5f8b89bbb2a7e667aff81cd",
+	},
+}
+
+func TestP224BaseMult(t *testing.T) {
+	p224 := P224()
+	for i, e := range p224BaseMultTests {
+		k, ok := new(big.Int).SetString(e.k, 10)
+		if !ok {
+			t.Errorf("%d: bad value for k: %s", i, e.k)
+		}
+		x, y := p224.ScalarBaseMult(k.Bytes())
+		if fmt.Sprintf("%x", x) != e.x || fmt.Sprintf("%x", y) != e.y {
+			t.Errorf("%d: bad output for k=%s: got (%x, %x), want (%s, %s)", i, e.k, x, y, e.x, e.y)
+		}
+		if testing.Short() && i > 5 {
+			break
+		}
+	}
+}
+
+func TestP224GenericBaseMult(t *testing.T) {
+	// We use the P224 CurveParams directly in order to test the generic implementation.
+	p224 := P224().Params()
+	for i, e := range p224BaseMultTests {
+		k, ok := new(big.Int).SetString(e.k, 10)
+		if !ok {
+			t.Errorf("%d: bad value for k: %s", i, e.k)
+		}
+		x, y := p224.ScalarBaseMult(k.Bytes())
+		if fmt.Sprintf("%x", x) != e.x || fmt.Sprintf("%x", y) != e.y {
+			t.Errorf("%d: bad output for k=%s: got (%x, %x), want (%s, %s)", i, e.k, x, y, e.x, e.y)
+		}
+		if testing.Short() && i > 5 {
+			break
+		}
+	}
+}
+
+func TestP224Overflow(t *testing.T) {
+	// This tests for a specific bug in the P224 implementation.
+	p224 := P224()
+	pointData, _ := hex.DecodeString("049B535B45FB0A2072398A6831834624C7E32CCFD5A4B933BCEAF77F1DD945E08BBE5178F5EDF5E733388F196D2A631D2E075BB16CBFEEA15B")
+	x, y := Unmarshal(p224, pointData)
+	if !p224.IsOnCurve(x, y) {
+		t.Error("P224 failed to validate a correct point")
+	}
+}
diff --git a/src/crypto/elliptic/p256.go b/src/crypto/elliptic/p256.go
index c23e414..b2b12c8 100644
--- a/src/crypto/elliptic/p256.go
+++ b/src/crypto/elliptic/p256.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !amd64 && !arm64
 // +build !amd64,!arm64
 
 package elliptic
@@ -326,7 +327,7 @@
 	var tmp2 [18]uint32
 	var carry, x, xMask uint32
 
-	// tmp contains 64-bit words with the same 29,28,29-bit positions as an
+	// tmp contains 64-bit words with the same 29,28,29-bit positions as a
 	// field element. So the top of an element of tmp might overlap with
 	// another element two positions down. The following loop eliminates
 	// this overlap.
diff --git a/src/crypto/elliptic/p256_asm.go b/src/crypto/elliptic/p256_asm.go
index 6cf7742..9a808f2 100644
--- a/src/crypto/elliptic/p256_asm.go
+++ b/src/crypto/elliptic/p256_asm.go
@@ -10,13 +10,13 @@
 // https://link.springer.com/article/10.1007%2Fs13389-014-0090-x
 // https://eprint.iacr.org/2013/816.pdf
 
+//go:build amd64 || arm64
 // +build amd64 arm64
 
 package elliptic
 
 import (
 	"math/big"
-	"sync"
 )
 
 type (
@@ -29,11 +29,7 @@
 	}
 )
 
-var (
-	p256            p256Curve
-	p256Precomputed *[43][32 * 8]uint64
-	precomputeOnce  sync.Once
-)
+var p256 p256Curve
 
 func initP256() {
 	// See FIPS 186-3, section D.2.3
@@ -411,53 +407,7 @@
 	return int(d), int(s & 1)
 }
 
-func initTable() {
-	p256Precomputed = new([43][32 * 8]uint64)
-
-	basePoint := []uint64{
-		0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510, 0x18905f76a53755c6,
-		0xddf25357ce95560a, 0x8b4ab8e4ba19e45c, 0xd2e88688dd21f325, 0x8571ff1825885d85,
-		0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe,
-	}
-	t1 := make([]uint64, 12)
-	t2 := make([]uint64, 12)
-	copy(t2, basePoint)
-
-	zInv := make([]uint64, 4)
-	zInvSq := make([]uint64, 4)
-	for j := 0; j < 32; j++ {
-		copy(t1, t2)
-		for i := 0; i < 43; i++ {
-			// The window size is 6 so we need to double 6 times.
-			if i != 0 {
-				for k := 0; k < 6; k++ {
-					p256PointDoubleAsm(t1, t1)
-				}
-			}
-			// Convert the point to affine form. (Its values are
-			// still in Montgomery form however.)
-			p256Inverse(zInv, t1[8:12])
-			p256Sqr(zInvSq, zInv, 1)
-			p256Mul(zInv, zInv, zInvSq)
-
-			p256Mul(t1[:4], t1[:4], zInvSq)
-			p256Mul(t1[4:8], t1[4:8], zInv)
-
-			copy(t1[8:12], basePoint[8:12])
-			// Update the table entry
-			copy(p256Precomputed[i][j*8:], t1[:8])
-		}
-		if j == 0 {
-			p256PointDoubleAsm(t2, basePoint)
-		} else {
-			p256PointAddAsm(t2, t2, basePoint)
-		}
-	}
-}
-
 func (p *p256Point) p256BaseMult(scalar []uint64) {
-	precomputeOnce.Do(initTable)
-
 	wvalue := (scalar[0] << 1) & 0x7f
 	sel, sign := boothW6(uint(wvalue))
 	p256SelectBase(p.xyz[0:8], p256Precomputed[0][0:], sel)
diff --git a/src/crypto/elliptic/p256_asm_ppc64le.s b/src/crypto/elliptic/p256_asm_ppc64le.s
index 924e365..69e96e2 100644
--- a/src/crypto/elliptic/p256_asm_ppc64le.s
+++ b/src/crypto/elliptic/p256_asm_ppc64le.s
@@ -870,7 +870,7 @@
  *                                                                *Mi obra de arte de siglo XXI @vpaprots
  *
  *
- * First group is special, doesnt get the two inputs:
+ * First group is special, doesn't get the two inputs:
  *                                             +--------+--------+<-+
  *                                     +-------|  ADD2  |  ADD1  |--|-----+
  *                                     |       +--------+--------+  |     |
diff --git a/src/crypto/elliptic/p256_asm_table.go b/src/crypto/elliptic/p256_asm_table.go
new file mode 100644
index 0000000..16a4b4f
--- /dev/null
+++ b/src/crypto/elliptic/p256_asm_table.go
@@ -0,0 +1,1473 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 || arm64
+// +build amd64 arm64
+
+package elliptic
+
+var p256Precomputed = &[43][32 * 8]uint64{
+	{
+		8784043285714375740, 8483257759279461889, 8789745728267363600, 1770019616739251654, 15992936863339206154, 10037038012062884956, 15197544864945402661, 9615747158586711429,
+		9583737883674400333, 12279877754802111101, 8296198976379850969, 17778859909846088251, 3401986641240187301, 1525831644595056632, 1849003687033449918, 8702493044913179195,
+		18423170064697770279, 12693387071620743675, 7398701556189346968, 2779682216903406718, 12703629940499916779, 6358598532389273114, 8683512038509439374, 15415938252666293255,
+		8408419572923862476, 5066733120953500019, 926242532005776114, 6301489109130024811, 3285079390283344806, 1685054835664548935, 7740622190510199342, 9561507292862134371,
+		13698695174800826869, 10442832251048252285, 10672604962207744524, 14485711676978308040, 16947216143812808464, 8342189264337602603, 3837253281927274344, 8331789856935110934,
+		4627808394696681034, 6174000022702321214, 15351247319787348909, 1371147458593240691, 10651965436787680331, 2998319090323362997, 17592419471314886417, 11874181791118522207,
+		524165018444839759, 3157588572894920951, 17599692088379947784, 1421537803477597699, 2902517390503550285, 7440776657136679901, 17263207614729765269, 16928425260420958311,
+		2878166099891431311, 5056053391262430293, 10345032411278802027, 13214556496570163981, 17698482058276194679, 2441850938900527637, 1314061001345252336, 6263402014353842038,
+		8487436533858443496, 12386798851261442113, 3224748875345095424, 16166568617729909099, 2213369110503306004, 6246347469485852131, 3129440554298978074, 605269941184323483,
+		3177531230451277512, 11022989490494865721, 8321856985295555401, 14727273563873821327, 876865438755954294, 14139765236890058248, 6880705719513638354, 8678887646434118325,
+		16896703203004244996, 11377226897030111200, 2302364246994590389, 4499255394192625779, 1906858144627445384, 2670515414718439880, 868537809054295101, 7535366755622172814,
+		339769604981749608, 12384581172556225075, 2596838235904096350, 5684069910326796630, 913125548148611907, 1661497269948077623, 2892028918424825190, 9220412792897768138,
+		14754959387565938441, 1023838193204581133, 13599978343236540433, 8323909593307920217, 3852032956982813055, 7526785533690696419, 8993798556223495105, 18140648187477079959,
+		11692087196810962506, 1328079167955601379, 1664008958165329504, 18063501818261063470, 2861243404839114859, 13702578580056324034, 16781565866279299035, 1524194541633674171,
+		8267721299596412251, 273633183929630283, 17164190306640434032, 16332882679719778825, 4663567915067622493, 15521151801790569253, 7273215397645141911, 2324445691280731636,
+		9262509587234749312, 6377906816499461739, 15415592259881792841, 6113140067088447267, 17505803833889144731, 3922849788840338823, 6180172597177093790, 7272741317181956640,
+		10883262735810583709, 17399134577381480315, 12750035195491397119, 13953097270363313998, 2485196748577282439, 393430759246706702, 3408702096065201083, 16993508724217005008,
+		6863012803048745338, 5403358912802668606, 12029756355518540153, 7447472859343023066, 7395681837001497117, 5416243410959797052, 2749045697176435642, 7813683613416962381,
+		18350218749545913064, 7509253999860752750, 13295789896366834092, 18326374111226872828, 3258048562491844971, 6342797029666289605, 9612474478300039361, 17807494771134060923,
+		9986610307523639857, 6419466267862117340, 324428332031706042, 16344106992423140174, 9434790811884847197, 11733262517030341550, 10475871084940451430, 6836751077061091536,
+		6209985515928007176, 8422208926220809341, 7866188125456775984, 17071696982741312252, 17482363193291892153, 1949968206030126177, 8823961512355572132, 13873010936602132387,
+		1136614876084383862, 14528605954969250458, 7641208364604111421, 18286716654189762724, 10711679476846124804, 7209187038097309348, 11378652158954714549, 8736575389915992180,
+		17651988839102959720, 4019365809979531118, 15024676458991206505, 12622721674297982786, 243375780477240745, 16572583194372185930, 5189991834753707889, 9498206494038386287,
+		7870185149723322393, 7858065912377481781, 7050328012468471455, 17977001023138181397, 11912539230960339911, 1290924823368819542, 8532615064753763585, 6439520053123840906,
+		11863354073576605599, 8052916203396229040, 16399182063316628399, 10837704607074036270, 5444229620349428264, 10866168931038804304, 1298875461760659950, 8904898233335519592,
+		7053953350607273992, 16629865408105641272, 1929728580699289339, 11046110151029488400, 9569890690274721816, 6501378768832742664, 1512621765961532661, 17084264658609527495,
+		300662505135603380, 15234062183651308307, 5319536121171934679, 11496182741145732970, 10520610739189276272, 4310163027157056344, 3285324287508696251, 3261468597637865009,
+		5427469457023618335, 8296698312021944466, 10882999905197052907, 16825284839961451415, 2106903142647479713, 12008841566652934760, 5361688498494289694, 12228623597691228792,
+		6799789383171367218, 17419525584795621504, 10685476378747845090, 16314000862057872712, 11014509959317588121, 10396318154903722147, 9986284919279346079, 4005974039875805723,
+		12980531573372269379, 11790791377897350561, 14264262096731994829, 14999393269362129980, 15405842559289002684, 13147503876582120266, 15449556979080143937, 5047767509783027570,
+		16354606995222167433, 15941889353688553446, 10301254747221876749, 10704428461746587572, 15702361407127630489, 3283718562982354984, 18081088275079496700, 17549094608770385733,
+		15620168851912893400, 13762314693487747007, 13577625382054330775, 4116976667540664996, 712200332640207605, 9098568002202933512, 8905476951567380032, 7075673514150314660,
+	},
+	{
+		15811459837282651008, 4038049993244767161, 9054218236388056577, 10807376403937048775, 11113869110590438959, 10336442539492421506, 9228056645601479672, 2983388754829658480,
+		7189376137127712298, 9147574701720272724, 3983921661449444789, 12479790317447783959, 13221020976679959405, 13001868979553711359, 17918176319017234744, 18030393246529651080,
+		13903368497828271814, 8050546449078305498, 6932373216915935575, 16010012759059004304, 15451708272653450375, 211711129247219149, 10435723642185827585, 17790507800712341232,
+		5218985848865375996, 5835476376320976237, 9096499658845542933, 8952489298840360492, 16605895184424459659, 505731104315931813, 17784248872812610986, 4151555707609374291,
+		2650786429127545939, 15186825834659456704, 6983758297535957561, 1268007525252235269, 11433489869282443481, 12352824209154665189, 14555720778982121964, 3578659908492218328,
+		4038120750249579469, 8304001815287976437, 251700810512667658, 17170873737273596918, 12809642145843734737, 5765073376623244019, 7923401246629348462, 5401634486288115286,
+		12830329023522940651, 1302336131164509751, 7011936976469244509, 8446680306499168806, 1386043952588989461, 9057741950701319559, 6719607413978812889, 17371065020414280890,
+		4963953120977916566, 6585250545846301109, 4490972754776862709, 10674499592300479120, 17494988318349821345, 1814042777264686189, 8938395423478059768, 9062966010283426056,
+		4683683785459765575, 8782133909400988812, 7201726172249963453, 16855412996123591560, 12016536526053703526, 6004686128951599125, 4323130180079993082, 7578596978943754924,
+		13272384473390546409, 15052793429857194942, 3597944793474963009, 5659515835454510338, 18013102402609680655, 15096936721974473248, 9096406212198787674, 948405832772983882,
+		7533214627823316056, 8009521942734148665, 15370181949218639901, 17395801240657257383, 13217990616373936619, 16323510521919428293, 10737557422966235859, 11113837024463125316,
+		3879469818714011415, 11493820457829716643, 10091807027724827301, 5032134849078736052, 18015749204009276046, 9667758283246223357, 4629693773460610802, 3807196436109718946,
+		3214144211600931504, 9454007581819416365, 15275469051811991033, 18196204074031746058, 14853793468372596948, 7707818604949749658, 3266782539036976530, 12810995382868348472,
+		17461133192060813135, 16870745208936545685, 5903437034120721004, 9683544852742219696, 7903581348090948266, 13461951083275541722, 2454715926022970060, 11781268272016425522,
+		3026443193966185195, 8027125782547146632, 17998666917527163386, 17214321347454260227, 10230244243647560419, 8728893474426972780, 16205038544687771303, 13771356055080873468,
+		5724217930909760221, 15420221591912350415, 9910465013739250802, 12511683773790779491, 2841532862707547306, 16614426471009646589, 407574220261191228, 17422057170120224031,
+		17151505459068312604, 2041124098660595410, 3221606782120899146, 1382742171848704850, 17222534050501711510, 3195635935311449393, 17295393886051199723, 6296241746423654238,
+		16510537668852450348, 15650518534057329304, 475704671950317376, 782416820485820540, 10970369699990900408, 16601298147057372792, 1599283701215392453, 8464446359559369186,
+		602848212987973622, 9275953159572178443, 15133444738457385545, 7264639569553811785, 14831517002293569763, 4277078717758211028, 12880437544322007232, 16339691585101354857,
+		3725101809714764432, 2995111022132376824, 9338883729618021504, 8824923738291347476, 3745497072215538317, 3576446898425965872, 2350077748663612773, 15793255155885543355,
+		8020669822852194733, 5865488997462325879, 13508617967776537887, 12934930135071898613, 11708185641249600577, 14265801329217514207, 10451671488560352734, 13251349632343744236,
+		10155392082337432799, 16725751190167983672, 17791070776350679280, 6653785531179322348, 10087876256887835780, 8422365820961469204, 13614411778251983480, 11687935452237305960,
+		6094298050768263419, 13949448434836272414, 14194554169090099223, 2625524360834828424, 2823844915913169919, 14077211807091283985, 15592587505996634401, 6562949920171518305,
+		12904339001067417585, 1972265247859388742, 8908590936681392405, 10320719400504224158, 8298368064038407143, 2105745729886511647, 16509751074757847095, 15156289751671616565,
+		13922601558154971179, 10541544592627074316, 9996345160543671471, 2956094548427827774, 3384122842786043431, 7003441038438960180, 11945730502649377204, 14797331669618433927,
+		533287349958250211, 13929395807878461602, 10036169742264959424, 18402398814900480008, 8793706913568807269, 4438954128288889267, 13996827050589647592, 6637236830429213437,
+		4308464751705576538, 12193581114161194913, 7322672375339219540, 329737085274484939, 15312435499764491079, 1530264129038944128, 1545025965426980152, 14559433923601957161,
+		885617946245226760, 17871561572095909264, 16413308527330544768, 2938750343525834336, 6332736376778563648, 16772687696658236231, 9760470695949399178, 17420556823805232882,
+		15040671962589188567, 5841393164221253498, 8923415548773111750, 17449640982747951473, 541686588805328549, 9579487672246868564, 12793813917570150236, 5744918442591934533,
+		12406806484060734474, 4655292039647906135, 5745141229449178147, 12923621608907306732, 1329768221522217568, 16293616079741201891, 16309603918079351385, 8282635243638078478,
+		10842935462043546322, 9397166878596340773, 5807145729199489911, 17083242467628861919, 11473470924584853882, 15220945465200609206, 10470712526179658906, 8129601297261864071,
+		4407657041250297528, 13832960959347315977, 15056546959967740939, 4350443362134191429, 8013419913016572733, 8888684099801298477, 15401479253620745715, 18279947201669400847,
+	},
+	{
+		7454214833719424418, 2128900810399984335, 8254953962723841408, 5341529923812819418, 11486532916552139238, 4528331821405917357, 5048485034448492541, 4189495710753944825,
+		9223539587116638677, 879142711399260546, 2878829560233905572, 13081522393987952773, 3067261963348061547, 16008150780594711643, 5466468631453287640, 16659147898971349582,
+		8047766502132608624, 8715815570878148809, 9093649079884580138, 3437267783531715968, 17562225708466062266, 3512667182749067601, 9223059995161026858, 1366690634827047376,
+		17929132376737482163, 5565926714491294456, 5252303555134107501, 8169975563698132305, 1829326230943509100, 13780918661853274468, 17736665596871232627, 4246797342334307384,
+		5113556452592134569, 7304867793218750141, 6016631926489320290, 16471860203547627727, 3444471410714850041, 16571738096215232488, 2003912224952639024, 4203884000388032492,
+		16858425223672505353, 3192567884201479579, 1688923188642613263, 4159042130811153987, 14900413503869744297, 7521485042788722327, 14038093805562042641, 14713051866364662650,
+		3738774192924465076, 14037618828827556145, 12882915396530927286, 10882862194263941815, 13115222579444494605, 18244214260845794346, 17217867059738274194, 2458870331386500577,
+		8768788172344064509, 2761897497254272960, 1400167175024837359, 2591319596670212133, 1499652044223484974, 6820326453941021707, 9701009499879906773, 6897435972338565418,
+		8314355711464256163, 8435944020779763783, 1814803522962187872, 1875253356755380905, 8214588085484192137, 18062045700553127821, 6649947905482043494, 3119726140944397531,
+		11881571666857493523, 6300786026612414187, 4928573492087752294, 18343550313462089203, 6770642120472453960, 11296815027803718740, 17312916793783562794, 13028515123652649961,
+		583508939637547757, 3195115082527873085, 8497784022800549923, 15135719419829981016, 1180291993378114150, 5447281494912347899, 4710517655176242215, 606503081693490000,
+		17732293765863716052, 853971165248416821, 2022886284923413326, 7522564752651732633, 1417954193520965954, 5046659528429172066, 11426939225844711305, 17687206690616539318,
+		6518552374736169438, 7940416740434530770, 15228615103587329007, 10662504584317997513, 18370800756791469891, 5564085264882124489, 51043856061444814, 11996026931884728651,
+		7009195269496826002, 18330778751427846129, 7903886241001925539, 8198930484643879628, 5453546027419466587, 10378692433982210944, 2242412603379120569, 14762161396393277464,
+		6146718865488327808, 8559779132928137805, 14001994895150170346, 9915701789711858841, 17119408219089522083, 4345363585985782988, 7559492126634131602, 17074565022279033371,
+		1081257522368061155, 16144982029632101790, 2280210790959566458, 5000326950136078873, 10441086845859171982, 5717080014740953823, 16816253740467637151, 5185838557034755093,
+		5835900675852976641, 14850646160621635240, 7784412869482958370, 2550282385659033114, 5102457400165153071, 16480738116286616710, 10726825595752219296, 3297564208881065856,
+		1801069609044825811, 12940364451588241698, 11725236374887225564, 4731241880784054295, 8874695411069669852, 10719836334830130110, 12983549127094653526, 3498884940869443564,
+		5044718241380586525, 9152928988998314956, 13274353997717834972, 5731942246653336838, 9453579625340936273, 6013700107129234092, 8535405089994224035, 12024982282827680252,
+		8296339816955798913, 17352704937535250450, 11768204246645005024, 263391795317009517, 6622964609352808474, 14563414288208376628, 17887389278697258458, 1552357122641071119,
+		13193447428787140357, 6701071088186218635, 17090465712567125397, 13844922841372559745, 4526664599449630663, 11321311100342816810, 2490532976442445147, 12506579957986846905,
+		15880983134955361922, 12396434033732989105, 16113831675045409693, 2288598422068078002, 2992425583703267972, 5056435264545116829, 12961420259857080621, 3600697676136115398,
+		12817090821406743193, 18109694174173693756, 17050997692981853333, 15796663317536421728, 15462568940214327094, 15151767385082666402, 17711108405932879054, 4030072071760424157,
+		15725012875727498089, 7622633481063722008, 2241559275264867670, 4018985714167034871, 6507661741395512701, 13435865773135624096, 9564553262368888543, 2283482276790194513,
+		2968718708369505078, 5001470555537559034, 985353756026354700, 3145435598301843880, 16410370922030326027, 13981261173663429189, 12565590835494971812, 222252377400865123,
+		3096505383227168071, 9129898186148780825, 13266305466206099845, 16135309871416543685, 17993464782237414425, 8124413037611692960, 8497190057115012501, 16568064870411415344,
+		7703394153241465824, 2740794419858297964, 4228931976096177316, 11207299659959318490, 3319492324515199082, 15611937984154016609, 3431896575019701337, 10686234123352138088,
+		9979039962499030832, 11759414020433216431, 15164411293105859178, 2834464820255498467, 10716371968480406389, 2722055037405581557, 9240657586762413776, 267811388229104916,
+		8385388272348876655, 16035999427286017211, 11255427708348651444, 18402964994101916340, 17964277099260928049, 16377129731672778885, 12034488763192562427, 15854195461740399790,
+		14134352329607480415, 2406779189916280288, 1148342927890148438, 15859735140823564382, 12055096645840568482, 16044304241162505738, 7466809979198503617, 4519925955244504432,
+		576546655711744206, 7729660311499709518, 16864252562359023573, 10537888397995064025, 11828992107618549830, 875843272290362538, 5328675038336932433, 3162100370899364658,
+		3897734650128449985, 3892478283047854402, 153850176068596076, 4448963435449755938, 9911011406822436713, 6379744721342779297, 360324666931028426, 8002086405015565067,
+	},
+	{
+		18068291112584812890, 10288580446655316879, 16866690514199445805, 15458664010538199871, 17175925202246173890, 12208778610361755998, 927739404697616036, 10330183209424493139,
+		17095781462759061506, 13984950766342782369, 7038608479806172868, 7073471193601880894, 9212126909381119712, 15865851343492198107, 3874039137971369196, 15366505242302572319,
+		3235058267792568155, 8030551941244615429, 12851363585510555514, 9786973022560471711, 4901414898060251968, 13240438628487941170, 4707852389766057435, 6503805666511566831,
+		12081034000518110752, 2773740877021737013, 6429475399936543899, 6804412599792308979, 16082860502313571182, 10013838454082912732, 7176778953927883654, 8065751639278576331,
+		2577328127707636877, 17299987330349518428, 15104751346159263209, 15422444943335124822, 7934601464470854115, 2803659700354182364, 186161376356596699, 10049927908892587253,
+		14226302346438044875, 11259466681405724608, 3945860952925292329, 3287876564263331089, 9461394118536996000, 12404803552046013762, 16569223065554335449, 15881973563254196893,
+		6665552777203645232, 5302850683863152336, 7778922028047389493, 14212904863357452615, 15966527672828304861, 3802704091320278344, 10517530714917238300, 3742971938824724276,
+		17741525051518363144, 1374267330336191942, 4677891169679898540, 9639823611685431337, 5482431056894095950, 6629146695374718376, 3884574854221819712, 13266790928096813258,
+		16028684877412556061, 13405436055762225966, 12268280467958284214, 17956874998292211440, 8610745336676661311, 2945210828327041653, 7889492068658434371, 8032335517518163423,
+		17096678157067198548, 11751872841896846778, 14951591239724148110, 14946797103632354342, 15001812923533485850, 1354666869219009884, 15934246013528228877, 17674533676709494379,
+		5120889077991995845, 1349360562851394781, 7965752316528770369, 16276575673105864366, 16613052983770261287, 11454051240568463780, 16146905806612132291, 15806571503343623359,
+		17505459029376928465, 14087658194607915364, 12240552390931686885, 1809009366037859941, 9468395484396723291, 9446052656478984520, 3720796795453397330, 18035355127900871187,
+		10937782812576841853, 2203021845094443505, 9622750764486021477, 5518948515641487288, 8021555402800950130, 8884074473434139094, 3925095588129480413, 6199533424090268508,
+		3824657730049729815, 4646911366274335188, 5283751816651713473, 16396970607630079440, 9102362834410101425, 3641728106404110497, 5923630184251416230, 13179374259571264822,
+		656781601862662976, 13284523818709348938, 14255949685810234815, 17662122984572331094, 14005272187244763785, 2769973460677437621, 9745740172208222044, 4399769039990314590,
+		18221138344920380175, 16761112742545021198, 14421639991115588619, 9419167563943683547, 6237248361283446238, 889754338720059891, 2289880386545166424, 4280148734121099084,
+		8456687949810928719, 6224977199672540221, 9826855484829367341, 10345583292656523462, 715642447678891171, 10791247680314230673, 4390153264475025171, 6710036254773432312,
+		11434352627810350015, 2720291857616706675, 15035363195148805272, 2358906741960696657, 9439888337759970778, 9654563570832962181, 6013570511081660799, 12742404245236356978,
+		16538557679183724426, 6137267799072203525, 13879005145532324670, 14569289845201353615, 13784903266526414562, 1051135786146476033, 9343275973150690259, 18338317230916899584,
+		5259165122317589354, 6306061166879114159, 2622163270351284906, 15212813592118086979, 11497359168652342849, 7085380391293263482, 11799059272489792659, 4912160901181298022,
+		10956239956289671191, 12649697329483184719, 17174497942073298839, 16454040570484021598, 1964314354536023134, 15533681501854792750, 11384243972598433754, 14387731385073008825,
+		1627256545355657442, 9010013556811110994, 14616120598404631231, 8391972858400276155, 244817907132802237, 1484397967210729699, 2663560284299448875, 4820353472962713985,
+		6567121006858416952, 17119959301239619281, 3965303761563489817, 10211688306206007722, 724618943950031080, 16749575186941231354, 9181397347361086360, 470616631211702666,
+		10512473611770099290, 11735037909076331019, 2922606398008539984, 2599799834378751770, 10226702495047936424, 6109026252412854338, 15572556822827169237, 11993701786788749663,
+		12951512375864063487, 9270845327881823041, 13198171264747338719, 9240466821667660686, 14918848310897324032, 10111918274408213257, 9869937817792431868, 11316967879062014936,
+		5691364106926740802, 2782311978438620206, 13067832493996441150, 12682941211395745221, 10515041347274706648, 9910726429809603026, 10540072260993990483, 15078586909891471233,
+		10892036011159420575, 9833543566604313963, 15176473361412960115, 14504845496732895720, 15845034940445278100, 5364672156984348678, 308167090528488415, 12390239901799634313,
+		5106897453764491321, 10540479232768400094, 3938246597140945859, 13156157265138481529, 4932443191001849637, 11374218582626530502, 2907557293167002437, 6807344711257391317,
+		5413712686694380670, 13147753106081951274, 2960292187746417883, 13977097845105551070, 17642067093469099040, 7699556298723812469, 11597002672863564976, 12392265705126521509,
+		4607947077536257852, 17763906282816835996, 11288463953418287893, 18299911648497821660, 3194698850612319839, 13371221457376435780, 10047718724723936081, 4488868185988157408,
+		13742985513958274859, 14201726926009534105, 2183997556320958457, 2564950343266657518, 8846625471673389624, 10147673280504740463, 186524308060896613, 16409126738088317791,
+		3993197157612782947, 14810882170056329119, 3476738916713041107, 1512933700383846542, 17820889751141311776, 9132720567660500233, 17598924894608972696, 9704537908665702455,
+	},
+	{
+		15695265447782578013, 15506558718447241194, 12341861439298989232, 18400958156300100845, 13704811286967591150, 5802260047239067846, 3266013253411255445, 9892957742319181954,
+		6053458788987550519, 3243549259991905443, 17990025476026266205, 3918149716414968130, 562225565996136148, 12175287017902713154, 16317970834262634990, 5431198806775607012,
+		15123186170178367264, 3054913246068400920, 8130663466272395280, 2852812622149318730, 6747630551931917110, 18302049774259156971, 3663865061939346221, 12340091610704678811,
+		17453312277789785069, 1148609799196055657, 5931758962926317381, 5297597381576544508, 9136842287749269744, 3007653173299649609, 12364677607049679091, 3656932227466449489,
+		17732801126130995365, 16093023291975796560, 17028512234142609413, 6293028118993952199, 4019599708379609715, 3557632583507755601, 16737140015288442165, 7041678499288317736,
+		5187842645752673199, 14914432544387315508, 4944360914161982641, 4177329533692612281, 18423887817846407126, 11935898134550505219, 9191754399457615042, 962223885189306707,
+		5467152559317256227, 13407023128339380091, 656806207084558176, 10823228592509573890, 282802378108427873, 13003319652664166176, 11501612671901244594, 8595770155487539951,
+		1805255869285898834, 11676967700876044626, 3486630203654875772, 8366336693945605431, 17874084888474647879, 8803709150655606891, 680993178667234696, 1603785777136148315,
+		3637712241808318043, 1673622542455477465, 14468899013751477571, 6607241816357171779, 2332200248940843815, 14077155355848738174, 17298155509321457563, 13624623885136011130,
+		12550073596584561722, 13898852145577133829, 31360866049197404, 12629522544897401454, 4563446134761510332, 7272813487383198495, 16767195814334178362, 13600498026689482359,
+		5170414136067325373, 10875290278133558518, 7331268231382198947, 4082234313337835514, 11725295114019619895, 6488017511603508543, 11399466652931338200, 2898113599278666684,
+		7553418756944942759, 2324485560009697358, 16004009784734101843, 8345371056076551939, 7377284629098981027, 11049718262343754276, 8021605820736410979, 8175349759714152494,
+		805625092558946929, 11996029844853502332, 1725029464967101849, 8189609560660709539, 10396089572662865065, 1756007811373736605, 7645529329516777410, 2608132938055260111,
+		17014595621244604813, 1574499958190108567, 8684546755761322906, 9997538531915911005, 5652402150243592363, 6315865356369667235, 8687115108443972047, 12369176255146729475,
+		5117004045853299762, 2238407612548002914, 12392667457861900490, 10614312910576266709, 6446577503758597410, 3767883614425995197, 17954966454260719539, 5233322901463099,
+		9194523390605857831, 2335161171394626054, 12290490336543843159, 12464172604156286188, 15842196578033029974, 9081285134201585379, 6123406461662038242, 5504260508195082396,
+		5345718195770885739, 10397124463462860788, 13439280718993427040, 15556816356929214653, 17286785976489019906, 13891416634083443852, 16346644312573564447, 917629419222512011,
+		7892626957952656865, 11229871638807701267, 5249460237065799805, 9529842808650392581, 11803106868201977918, 4600784567377577444, 7178870186583927975, 13829108773971861655,
+		1289703927368007546, 16175369390684210381, 2195306032582966573, 11284704298115036296, 4385727852306374408, 6915138269030006111, 13440775052829788601, 7742359656861485339,
+		1418252737937945274, 10664598666472920539, 5146625453081549320, 7716408631061669307, 15481216546649435253, 9087869057854823101, 8438781502742166926, 16066665509570633845,
+		13091912700111633391, 15443255616678375884, 11338466119311799740, 9641919445273031117, 12359044485240987114, 7665168466660756789, 13845183791692700257, 10700410793152785934,
+		8528578803314347534, 18126789418189181716, 6819229450418907940, 10542951903574211724, 10335954505229790439, 773396809431100386, 763679854573261611, 7782804492252573047,
+		14102889564247144327, 15479515297699126743, 6400257822506917934, 12400211936189844586, 8190162441518233318, 16489757979266243333, 11074854544980782334, 5650848136444824725,
+		49299995316533601, 1658812626798186796, 14321322055030354, 1062750633396640947, 11458188738562323084, 10319462683954522885, 15398455357851813321, 9473384090828584828,
+		17723857482947114516, 17563952877363564604, 3160294749187111891, 15485369139883303866, 7487527166185553604, 9661144290316674030, 16387431126208996705, 7499766964252214921,
+		18331281993562501191, 16034836629143884193, 11149238385567891503, 1413880911197321245, 513884082842080653, 462183409527465946, 404977499728878854, 1459875951423441439,
+		17249202826373649180, 11151860661862313351, 13606113651347187963, 13653298062695357606, 12346841931589648448, 10659825520992339734, 17857177794617595021, 12846976930859175746,
+		7421386827645898229, 4567141110780940726, 9022716764262477732, 7287282267953917487, 12950322172330872807, 2675202024861592519, 18339036521791481203, 7003909904344391740,
+		13539440097944399044, 7108271818419613260, 13229113021954558930, 14920952138366964142, 11082363944167072746, 16156446445495173622, 15515349862819133984, 12359827931233605745,
+		17013104138257181849, 6982996767213561282, 16259302607976830987, 1579942890487532721, 8635464047344487404, 10435012080572068738, 2976844365866972753, 9471858478345924179,
+		2347775782107812070, 311367032040459687, 10852128873404113998, 1338612296059509077, 1599132038614432432, 11533828746166635650, 14264087792956755961, 13004615331499537807,
+		9599159247384506427, 13011559959971256245, 6331802547989957841, 2642320882309956905, 9140255367820630480, 6883541786494880896, 9560822438260750771, 9273862677291701694,
+	},
+	{
+		6185067974942684922, 6452325785873503452, 15247257292915812252, 3689324664200339196, 3264129576054154137, 14977721630214750038, 10720913377937894256, 15914487080763816378,
+		5498621600689515064, 11498885804037952971, 12697073118321478539, 13999008478737234463, 4324885099420360642, 14021182496192299466, 10763088992583373843, 12898585157666243299,
+		11622402383521841588, 18271726976204770291, 4805501248621435402, 13483122453682180759, 9288143526654965614, 4688427612851085031, 3280806057528512375, 2249349779106893174,
+		2317249352525369754, 15030797481081533168, 12237590576308284360, 15660076992611440873, 11341015819700735887, 8280257602754365719, 9212501234696283343, 9673375202141178099,
+		1576552382781604867, 14644873134348781157, 9860879950368557094, 12941927431704225849, 11959666739052502184, 16171152369226594315, 18364294470656574060, 15172859394935215584,
+		7521577570681641021, 410124023045579310, 13806534589183327176, 2731801491329207875, 9959087943014269549, 16205635445474657221, 12069145915768935630, 14906463509471682144,
+		13803661539609326912, 3233094883493439444, 13409742688319755923, 4298169788674760921, 12847636671560067434, 6702365884489797170, 5650404576647289813, 7380374625644226212,
+		9762534010701623728, 15349113802811029024, 8305297169667044246, 18013018210154476198, 18414050009163335761, 2190126859433916996, 5444481274452218807, 13415988647365667724,
+		12538763466834894269, 1385338113050483955, 17489001033590767373, 12734464941837886525, 5762578105750980174, 1466528690684075875, 4231060025049573530, 11218444849081704286,
+		13520439252664960951, 3770430920651384098, 18274623217805904547, 11545267616883260257, 4084783424859113779, 13863968977657663867, 10237835480648574698, 7395611844854084274,
+		12891185742908997266, 2889148203703402614, 663579373261619221, 7616112456816883701, 9002890885722034437, 10753730807791931375, 3553894671829778441, 4368240432504457389,
+		11641532224340210206, 71261001011952801, 2321745415903209397, 6595984444855093239, 10341299657770272718, 11529878689049370930, 14381510695605158203, 6869272773579747365,
+		18407769999912340511, 13801873415230385184, 8080153703167941484, 14143463895182697871, 5248006623352376562, 9271982788122934275, 11225161179021692620, 5076519449784098178,
+		2388868518767189674, 381125256886459269, 11316805024982236485, 11671355336111917711, 3564177948445768908, 5245093046097324328, 16144139891410041039, 1201010948447708436,
+		16591032462856670656, 533850935988668408, 2263232738784171066, 5572124915367282948, 12583782854491678471, 15015562207264407653, 1167486851113549964, 2987176661273439670,
+		1073778278665127828, 301289653767944933, 11482324780950168317, 10626716202328004967, 7258024014655363102, 12597648090458567878, 2617914106162603499, 12324652644266476584,
+		3803745429517922765, 1699256829990081513, 2179986933466617785, 4330084096014112280, 10403896221616386733, 11682369673591069651, 3879392495596713886, 17249085256521020624,
+		13938687445393525296, 13822790166673492712, 13216892716897321740, 2165870280409061482, 9147830602451471293, 16339144108911449834, 17837507766320968023, 15340710005345158245,
+		4485838034764604283, 8426970493386126530, 7709201418726935942, 13468796449943783583, 16441091014185628843, 2374269830239737237, 13423059086148485716, 17132218391020520330,
+		13957732574177025801, 1100344278733481546, 12156946932617203965, 2007756425747006287, 16454508610548016441, 18058668363064769203, 15619001054652658323, 1201476243910931863,
+		1292412381963708933, 10908631677673353277, 15138649576688192753, 10741579086621436813, 16534963566169304684, 10228646729525192055, 4256608246548223655, 16176814322718522963,
+		3012125536603284881, 5466178753014623970, 16598422155702380175, 9902071731736699653, 13861556771123036741, 9534711573278556274, 9805898455743897538, 14683694395093520838,
+		9125214754744730198, 143353181770418225, 8976042597473555858, 13405481215779362056, 2863125481657826330, 12333764090388731260, 15250359513836914002, 5086706595778559056,
+		16341334571424533804, 4657494880554316004, 18092783076286521475, 19832895869027143, 8667365497283429486, 11501953273367138162, 5832487631687776985, 664754160781757174,
+		13604774408440609080, 12660956565879820101, 4535452877362385626, 8063311919592303330, 4591511734775484245, 5164119991271568303, 5282209033000495913, 15181017218549722334,
+		5070228782679699429, 277881850788922387, 17424210585510719837, 13586569401109299583, 16661809787463692974, 11543434536078774133, 2062889565117549061, 14261113517104795690,
+		17683343658262519228, 13727986689138309987, 9352982220536939533, 7578301410191413286, 7970586266869249410, 14357824150096386968, 4381700479561442130, 13217807763329274501,
+		13524719886605363170, 11553593166914861649, 12034020205580665813, 985175984881624722, 11040631342644137311, 12107496606245418129, 7328748654066365904, 14741972847454326011,
+		9790251609380109406, 2449588380962781369, 4694893010228180943, 5172145489692928848, 5411277023198532852, 12752098113265127406, 4559500999103209672, 14921033543082064351,
+		2248082728820243864, 8720404853152831367, 12431505213690884811, 14883031570121462817, 2278273022936639560, 14988529405400451352, 16732922988142595529, 1071232319627396164,
+		8793441611217807824, 13198147137434605751, 8167936709747999601, 7685928882032231744, 8779182451658438210, 8059106577297479923, 18394590909567718507, 15508315617300242773,
+		12828567388121500364, 2264959796189127526, 6222205589523394088, 8827682270015065013, 2619170858745203321, 14835030117099398518, 5960028394532808010, 2233397097850889639,
+	},
+	{
+		16319476863352440541, 10283930715856640343, 17675054544532098447, 11261132162985242084, 13712716897981761400, 2681907143459288706, 6930256922080133347, 1445069157579547822,
+		16928574868467385886, 166417019993787654, 5882811520342817815, 14106304179344008065, 3747123724781081800, 197109533566874475, 14303280595714789450, 15457633026018307066,
+		10773597511592584859, 12552868588431074640, 13500771767160426835, 8002499270056378440, 13792839099998553174, 12949371255843262119, 1713974340992291550, 16150173130483658061,
+		14745984256428057001, 9333707338036985191, 15365925315303462, 11789129028059619744, 7873100217437235208, 5289763977161829145, 17731215200358323788, 8876377479309635703,
+		265950821974454804, 5047467530470542278, 17523044368516619801, 10054436503372765176, 10321185867287373431, 1212061937729015591, 15311258419138633926, 11236518538207084768,
+		10904693956407098222, 9013418755007070130, 15510005599846320670, 995378633446250700, 12234095025518917836, 6689106237771514188, 2809193993744369126, 548124799387888260,
+		267350765778774337, 2853877351938464055, 3677119082593358544, 7685335121077514739, 6491980094762370981, 1384870316654548002, 10568872345228996498, 241629538659623878,
+		5839400175629113441, 5238299193248381245, 16787876416022887315, 6051613843621920008, 9219569873668974552, 5916753090530931032, 13390630214643423749, 3265335490455191268,
+		1507475744849985303, 2597075068965622770, 14968669113917266926, 597606442423659891, 44293923912414886, 3832651144752540816, 17438860065613195810, 782112340603343331,
+		9050896199196733903, 6427608033444590004, 13787696679536621857, 9682087046920409188, 4519093754155995429, 13564098392055667371, 10512507082236058799, 5289934424008191746,
+		3477191607403300916, 18283244229745029067, 8462159792484018099, 3056576498976014760, 7259283167233712785, 12530251965039903998, 10232104933720625111, 14190745998092156987,
+		15759362035410895911, 16075598437961371531, 4651513528876405575, 7694151626503869614, 14468862724637972284, 1838601521755586245, 4168957446435305706, 8694905613027663664,
+		14825552838983151434, 8639609968952840931, 15547914584352392016, 2313507499500708287, 6902543375698033684, 9987468886016348918, 9068175779860656258, 6899641689193116297,
+		7449110402827616954, 5689206471789540768, 12722069021950813669, 16017131401246233663, 2240977975275954837, 4794705713606614946, 5734937900461809607, 118285984764445639,
+		13917685647531721740, 2432096911145792817, 17733637484624159521, 3848601825403209903, 8192433211051054683, 17388066421914150767, 14336306308847565282, 7501625553608785022,
+		9844707592410952215, 8167497709587672711, 18115463401502884199, 8471563375691441535, 17525405040226359165, 2460181803833371342, 3375780580907171205, 3024376384135966552,
+		15446204978718816914, 10131769697256428720, 10937168660849553757, 12174257400309926241, 4774490771219074715, 13764876998736771340, 14299051476546774038, 11409551629093945893,
+		5471366060803425265, 5927845172343647238, 13321967429805195545, 1981489848211999240, 3657997933879283852, 1341488083977381854, 11001000434984172675, 12666440712128450303,
+		2127920575549495889, 8861781778185702064, 10501256952986753134, 8967441017586595593, 12224364761159418844, 11856305587178745520, 8176487286367052930, 4988165299911239066,
+		12279712962388998309, 7552494563001503282, 7388800608466198128, 15704167671257743517, 17781278773093632973, 6688613358271814698, 12261263098366698895, 2585757657252460656,
+		17064077609211627595, 14437064866605257652, 14386408901468621215, 14935685266532365200, 16350265985491822570, 5195856143474093260, 4623415440658404410, 2936315929072503688,
+		18399447684263070219, 11294713679768342649, 1600242588657342501, 2841752419388937826, 15111313732750279467, 8179471361906256467, 10611923788752807866, 10823997080784081293,
+		15607034385960553579, 6934034624930683639, 13318618594774430459, 7552865293216027192, 13692640408995992185, 11143313220936824014, 16721999332340829387, 6993089466645938014,
+		1749509641415861857, 8597876492914031095, 17942224190138398306, 1760222146515426983, 1030117883582412628, 6655464189981098460, 14222900139576809037, 13041171493967200019,
+		12415333505074758067, 16988669193263876033, 10482573641416551070, 368049292090348794, 16109255925523895167, 4949934055388640387, 12038479532506656790, 10829864449693781036,
+		8355401100656399994, 16963696462538033761, 10131652431024537917, 4166156454906166144, 12888240412190236596, 8396312458335953166, 445297814986468978, 10512295830234020744,
+		14405236772348157690, 6950094157338825845, 13379457125020057613, 11396720859761560260, 14063367153572826959, 4476298515903789197, 12708437873915498860, 8163633089770520638,
+		6432708226771955694, 7524978005081948959, 6442046223716866789, 4082077252385606982, 13626979819841658005, 4264573835620574342, 14788317690584235128, 4710414518172449402,
+		9592766374657389840, 3206081438027351157, 16013702689312533501, 15788528722601567812, 18314198451066123850, 13236688692074994659, 3229858297074852748, 2968037605940641303,
+		148470760067500612, 10319937899190593880, 7185467485673911733, 13041030391924988650, 17119842693824847662, 10989053172849710331, 16048294708726813099, 6612710923681979611,
+		17408606709137505005, 4263600430695220256, 8941719936291239640, 6115030817534063286, 838024703679813150, 9772071103323550178, 14394690179107421621, 8621372196164819917,
+		18138724984190926809, 4154767406604950048, 5209478936276366634, 15469512148904762872, 3613429290324777670, 12631812917445459751, 10280179062385049041, 19656860716268566,
+	},
+	{
+		12030193727051241373, 13981191132445467472, 18205169646206905593, 12162181194046583886, 10929925499200074058, 15291772758590352491, 8452344520852919320, 8199821440451878776,
+		9876482463501409337, 17331045017548147052, 17542726936580732548, 8299195336372136083, 12891767721269002608, 14062358772374813347, 4165127680073507756, 16350672737379495431,
+		7595271959296927018, 15286771623821390629, 980612661413312852, 5738158184597378995, 6972117550390447038, 6246497134979772260, 2935831443692029059, 12837371529160496660,
+		10228366644420455452, 12084265406352277347, 10265869676493821892, 3560143954870272139, 14368775225608592689, 13173522067191372913, 3592475039513249949, 11243554718624931135,
+		15959892157814064696, 1882528744932347842, 3354709518288681174, 14147909176429982637, 12969888425264095514, 12509610747258602648, 10437226619684632037, 7605683691113295811,
+		5697384515599291245, 14896081221061315030, 4329502046122948975, 16301954510440819492, 5191621061031169335, 12944691824816066027, 8080452646904372453, 793075614214301908,
+		2662373477940179766, 8950125653339535995, 15717799081080898304, 7088593450282143511, 11723351531494404904, 38673945663198753, 5289769381065195334, 1742280067441486108,
+		6543255501112359319, 6063422531520498671, 17228726254778244409, 7570754775709645369, 18222396492501523182, 14903937974816691813, 1216646642383641441, 7602781158453005929,
+		3007861146695764376, 8267227185027440857, 3177625538211272080, 3144345182124760000, 9215753228267875296, 1342253891473772992, 8185239004636232247, 14951188427081280984,
+		10569785547248986188, 3109435167722572449, 13661123218513357442, 4646373703143839998, 9712828426076586682, 11389514152975496268, 9796826623781200498, 234067627740956181,
+		2188380882990542468, 9914251329861595119, 13616219875099353594, 16135919125023820218, 10732193797566088293, 7172996278550642736, 8531638916719074975, 14749121691457005349,
+		14568782576170814716, 17582848432122737506, 1079387064102681806, 17278567874821675408, 3094302191119669899, 3730448048895347901, 3508894590334961422, 14091660942919228106,
+		8414395549498864629, 370884714015114625, 9859130251236103342, 17120282094084970181, 15213286581037020029, 2737545283554254673, 12422648607044275574, 10601123825482591606,
+		7332173975514924017, 6689389428877729175, 15162654177270425320, 17333672210015736765, 10717615330136876266, 15245080807947386155, 9830331968044142933, 16156512094344185621,
+		9151817936103586393, 3495709317444898385, 10881665308947458223, 7087755261386867019, 18372828768905212167, 12873774245490293443, 12750361906770763255, 17688389897350887716,
+		13329033749048978810, 4765695903433858377, 4452680451529163940, 5638854187414651620, 7897503022043776206, 17187635538005569019, 17766753195497526986, 13201529234556380285,
+		3638940913491383692, 16533217388164981609, 4668956005988168087, 14053696531704823982, 12029006663244142834, 12043309283447175601, 7840964186868745782, 5691369519440953069,
+		8500871974974230561, 6371833132372813539, 4002756625312698938, 7281624589760047276, 8813214993155334737, 7738842112797657395, 12616064385239668311, 11875709199633531753,
+		13080663957403320059, 7305658810888170771, 12002632153917673214, 14713338572031413494, 11629178662016777533, 11669230410217642326, 6563025945717173284, 15889630204666511658,
+		8934119620399766972, 4226481091885914732, 16000709195004445297, 14687868180928846933, 16269913392757896907, 18294005838441325342, 17625669613551023126, 10864307042201644469,
+		1539179629859629979, 3357767843775461146, 2101360073251832751, 17234081431682678130, 10847284171622250162, 2314478515498414576, 17530153382031867644, 16210890762511619844,
+		16932765725476234252, 17974885539458965712, 40892050255466590, 13934027942808790590, 6621543269907021363, 11796852321134174354, 16673775773384613137, 3370296079966463186,
+		16962514259432373133, 4639769064050336100, 16965148588326727680, 2922022742538957808, 16752379982369550296, 12896050752492664079, 2708685629936199207, 17894058559833424187,
+		14722530431277419104, 12333728409662476827, 4162946257347548625, 7052045338975163666, 16435875989376103923, 527141841571514699, 8480360258792897962, 4322786951393806781,
+		17366230017999184054, 3121469063237497918, 16903979375392804254, 8204447732627807538, 10469007462907301028, 1938243801077680483, 10156223751968769092, 14290141776757271674,
+		2576841693080637380, 17952976066680364360, 4927209893946473523, 12406446420948698970, 18104668447274679200, 11321546081935789882, 11763004760954725540, 7488613143173641394,
+		7566233859107262691, 14065899052643539237, 17156645465457086529, 11936850757897686493, 17529993825395532749, 17145245039398670236, 17597009579379584432, 3472628483897995694,
+		14380803034817149259, 11042134597430846555, 9992762805140200547, 9895143575678511242, 3228768306004664915, 16153114680219541243, 12036181641761325912, 491369524302296324,
+		6378343037075212083, 4634622317247307316, 3415247351446435530, 5939760313513758783, 9540802244218497398, 2134082884335789009, 15623633842188443713, 6824600547587227473,
+		2021901489047050575, 4365578779519871721, 8603845379677060773, 8929020214929242215, 13010370953605249273, 8071113541575997356, 10681914788594101574, 13369522272664029829,
+		4241327321249984516, 12810477007632864750, 16880581634097860698, 3630333431846970294, 3439918565119627078, 6613942714960548236, 8647431674406387604, 13352599355545805355,
+		12320933424684960076, 8906954611339502145, 16931708732547376267, 6446897311644431583, 13749563256713530203, 11522599770043814384, 14455556215959342791, 9022955938835504923,
+	},
+	{
+		14734199666349771791, 4159865781008764547, 4413963548436270853, 4489431649937855880, 2824856157476907519, 5111945927271461159, 9825486821405155220, 7657332565522279292,
+		8798422177670065832, 1250388939918922012, 5145324733132743026, 3716299737175574168, 14387202892738514375, 10255681359895407489, 8563822744122397080, 18430417713920116013,
+		7857399215288147901, 2593284350589299949, 10086687882410147351, 14407837835956327624, 4469878646287387405, 6845712208092605310, 3019047164798827279, 2760591274816994522,
+		10930605176025081830, 5850835312463207607, 9603163404664606781, 15623771803942139684, 4096748595672894276, 13060617166821837740, 11222939712741281346, 18445178894593253710,
+		7976335583419810431, 16568954524837045521, 5581116346602990350, 18369129318179031997, 1930478946186473631, 14255806344323769850, 5302512325798050097, 10008570767203424472,
+		929118050943456183, 445163760697913504, 7208246135487165437, 13565354217377841149, 3835063466770003968, 8214155842021576753, 2078717035803259674, 12502657820500987763,
+		17741004372977419914, 16320851348541958575, 11853008901690968430, 9954777341381304447, 14274892887030297417, 10721339848307167540, 8731332510371325649, 13676383433520290197,
+		6251805914672095769, 1063060143452094078, 16647397170554915088, 15454955736319919321, 11509235104607349098, 8441647766544589978, 956121464218389431, 10752793912033728149,
+		14879603883666664508, 11158422912437249402, 8667988090392051507, 12702057193823135575, 13234479167199208223, 13752955092077643608, 1117550756888145931, 1184967682872965330,
+		7004802666964716824, 395433501626287206, 16674151908279399004, 2279551165611331131, 18032555740803644790, 3573953642384243989, 9892480504006025100, 2397759375236735831,
+		15032723931727013905, 4176673226777913017, 7270920367565154969, 8867675920919464620, 8174119413251699506, 15030539680120439131, 12325981936900309518, 2932283844656871802,
+		3227890727136855788, 10772277744280338071, 10065219931092397730, 17233706446636791341, 1372997838851103811, 14430098741859995846, 3290287064497023581, 13054133915521430696,
+		3404625123065318735, 11884832674715736469, 16513753127836546671, 2355202492840722899, 2182039060332057784, 17942518439766613327, 16731345075928062112, 5501869092504492134,
+		15704211025163561149, 14596679078416770266, 10262177146233936833, 12443005669252298316, 1541294166390346144, 2952804996209068760, 15358481016273272880, 1321729586231860999,
+		6862865331233391228, 15106279167311639122, 3283008666555627541, 13405610967904725343, 9845239597399801983, 10764942720093673542, 6506992344666983370, 2483131164245259278,
+		9508384588323002196, 4786531415304518048, 2690306308552249535, 12208815515689370850, 5145548243685871201, 1536915039528215765, 709289946127949333, 7152734178531880864,
+		1555309551759198315, 13156609441579560529, 3264147002083956017, 13629162110016732793, 10295903344220946201, 13835148808782379287, 15646840234722388037, 5850505683234532491,
+		13348528763144385986, 8174978337870000956, 261860806345683810, 4561309263594732686, 973813267913726588, 5812176512716041479, 14361848397565071235, 9009461390894364897,
+		4179825720483458009, 3146850391122074949, 16612045757277946305, 5253713786583408340, 5426943015912173764, 17275032103121420023, 8467860410750483621, 18150546576917688519,
+		12762630566060098764, 9762645120146998728, 3635705124656800121, 3295681695622364165, 1764654124266477879, 16610065552429288987, 12182970194869512424, 1144643512390613083,
+		10286763540130161498, 3400614528650953395, 16801086752981339314, 5746334081386875705, 4489937467701177898, 9249554406360134002, 8258038249111147700, 1922443676251769427,
+		5981893063992017591, 11780456280008557800, 6865399120670384939, 6192294124015342683, 12388377965276278882, 754882660516751393, 13476094069874573591, 1000347292494612314,
+		12753947115797128456, 1864834899756446490, 12873792436322150068, 15420857687427067065, 6214698061215951246, 11174167031334850459, 16378107708672199269, 13073812080094584194,
+		3531275996684891316, 11764951512033875164, 12239314899306115751, 12701224435273087197, 152051042384837402, 47099568832954431, 766394328496626388, 666084094458729910,
+		145223485883456390, 2445564470200462527, 6482144922631612251, 2316071592874761856, 16548688346252111305, 342430477320199814, 17819268336019413198, 9112976726726029531,
+		8272548370610798443, 13910434751574602849, 4252192981011400377, 9590519351704710983, 4172183866405471444, 5567646223402949380, 6059725713353637560, 7169982539312028092,
+		8422701298619809502, 5749403137850675219, 16696307763582818287, 7683947097864552851, 8685161999810728314, 15931494353777534155, 21629333141204286, 14374464903502564030,
+		2354260355218724624, 2822702976206523812, 15817484232297668127, 8389777239766813455, 7962301702220496539, 8489354871723216960, 6637394823950686331, 5853452396705295777,
+		5949957329602421631, 18059540496274524007, 301304345046470155, 15775279105880040289, 15979581939040500554, 7142046514802237176, 9965619645220287167, 14369754349691428035,
+		8777708254369249245, 17882304730732025188, 3127583543205765491, 17274466425160820249, 12870181470212293464, 5881181695848312122, 15338161852429951632, 7245877162563127935,
+		2634466441339054819, 13057158409330115380, 7410310056430957860, 16362149248469660371, 1435827663585128427, 8005375008235415486, 10865470829924734253, 3177600727860863968,
+		9627905753364576437, 12776456422166281355, 2851899644189834214, 16998174196920379994, 9001602524188761177, 8960294999163663712, 6580949973363012183, 7568306074815116797,
+	},
+	{
+		13345381996769253014, 6278048669175242345, 15990349685835870151, 16358261962292186792, 8505261070637963021, 9396725065098564446, 15331953351049782155, 16194796339208321205,
+		7076257175157660597, 13221730879315432464, 4499548735964119085, 7559253754663705944, 10196808438730350168, 2391718471837563931, 914409564589897387, 6649744842278078706,
+		5502356275170104522, 12750322860129485966, 9581277511584938955, 3872282844937972630, 13668854758739140874, 15020438121087800965, 4581631138384430657, 13296613956093963588,
+		14380343880230315251, 6834909096379668102, 15975839936772635678, 7738230945027714388, 7971648870467745046, 8320128435052726628, 10820026056424631461, 7058118462476293754,
+		7264036154081699231, 1304060579978677195, 18166928140052040308, 12593450560996175288, 16027666629366472835, 3677101504316839585, 1477956412235870359, 11566116495906585190,
+		5990066097615398579, 2092999434824845091, 774626818169813708, 12815491981614523669, 6993666706115136402, 17707947501239782961, 4907798919001453899, 8644498548438963907,
+		10893744790193607860, 5425031394266373727, 7829758685118664025, 11448863214220512751, 12538690882574195219, 5021176303769859871, 5820297470465439264, 5119144562842414323,
+		11165438517321289842, 8661037418831619311, 4401480924846865713, 9355650368902126256, 14352422544185763829, 12268031594529744663, 17607497268577344783, 12698954426769962214,
+		5383780168621648368, 3613813760948797485, 5757643543708300439, 11434310585555684688, 2345981080034027974, 17817292757133028083, 18327982597027759229, 3812144950722314021,
+		8792386854586041066, 18039588893139878329, 5501406599000558473, 17117814302557684702, 7341401626090786647, 13233670006052290433, 2192568639640447778, 8946253989965365943,
+		16557600339807647183, 3024845786116641335, 415867109882960964, 5024769423994345740, 6707880221250244075, 1889203596997453159, 2063004021323938442, 15149146696320496954,
+		5091534986326281709, 8005812102849517353, 17366496686564185717, 3658878980438307796, 8455810244524637026, 7649393961871195909, 8629386422022530934, 507133797409068858,
+		8757568869745664865, 18237318628906764926, 3340648953867756474, 561136277959994100, 7271097445297070958, 2011054670254573698, 5452809131990689118, 13469888024447314143,
+		609640447772904263, 18299734743899574512, 9082773418653747144, 17312950936823165983, 8565594704932296493, 366163155689429929, 12596423288683198842, 6787120926470876217,
+		18404298100226778075, 8425329164435445437, 7431919288426595458, 10680902470574406179, 7944931189168061880, 9822761000408762356, 794258562727155839, 14627123549563592012,
+		10098955144981013765, 4095621933458866623, 313357785962326778, 14880249056209398407, 10605627454111004262, 7841561005378789988, 5015399193497762029, 5818383539901203899,
+		486788682374900660, 17535646661984222270, 10786441143551223569, 9744277172896797168, 3600223448942144865, 8847805713765285452, 15255336563751266306, 14792236445425212896,
+		1569380763811592357, 16850350231819425451, 14974316825768144065, 2974893813338477794, 16726324408135381195, 15000665607479486464, 886632233152598796, 3783793991897659851,
+		17267037371866619240, 16498595171305365582, 6453906744948258368, 17267405673163971478, 1676214913570622682, 5051819157163581842, 4315279707026326708, 15525840981760267164,
+		829322392873083372, 3459913121476606612, 4547714508342797986, 5801286056105229312, 11591136160675314269, 17965845487226778560, 7022309609363885527, 5990586084398664157,
+		17415594387520595717, 1453256163777911406, 8242859112004661961, 17561205531134219898, 4881570838375824387, 8392772608437744175, 8797957464506597080, 3142154188155936579,
+		6248409301753564092, 912147011448492506, 10413108318416902948, 3349445377400918439, 15887909530347096066, 5138859116738406557, 10990929831134698266, 5911273060564729281,
+		5197581879950405305, 3001975514736631403, 1919678782193534342, 16811100109848336275, 13086769249238533805, 4351245282425706500, 18281601243717625371, 16799537683941038764,
+		6288277991521986035, 12231480617236286340, 8633990423689180869, 13535190275290488690, 13419223868164389899, 17622732596713666209, 10071779220640400024, 9451660464882303005,
+		14029940454474238624, 4957972603307996503, 6311878080193524221, 7485203809274562760, 14450074580092843779, 16845073066403496624, 15870387052570816676, 15700883809468229388,
+		6623653867803819118, 1037643671564549885, 1236506073247459642, 2997396263933967582, 6182371056378366305, 9773995232878719062, 3356495419149379609, 10710833980055523526,
+		9965766500412107699, 16895652751136174589, 7310937934566947318, 17649841370865305295, 5052693369483848536, 8093060855248113928, 15777336335257114359, 4642979535698186085,
+		11761084765182152401, 9226969173242076459, 5445719591917489914, 9371133174853825566, 18381867235964583187, 17262888224001222346, 1934253649802391267, 3574888052111089863,
+		7862401495691359736, 674970329153306547, 14447324101549742216, 15408908436196428001, 5339840774639473099, 15542473999923245378, 17353380999887736706, 17787369898686553525,
+		2301964326759931592, 17775852221342579469, 345763078096690431, 5079606662887837532, 14863722102334084051, 8905941255852264870, 3806200576416892831, 6668327519801544161,
+		3672519063263749482, 11898207454593385701, 2364050348970898536, 3761861796987022528, 8159458273489411574, 3231262679605967088, 17179214124164291006, 8770284079122589350,
+		15270079546607712667, 8471883658965202468, 10333206241569264742, 7414741159725097798, 7709713706668701850, 4461310100162632915, 10099194304024685274, 4760203118683828795,
+	},
+	{
+		7237168574323016859, 17908810107504968137, 16225708127838178121, 11127095986977103648, 9346291308317410251, 7381283458277047010, 15168602815371846943, 9193719743691734294,
+		9607254959726458411, 16837156817186931862, 16178143308706847393, 10970721795101931539, 10840376278605273092, 8298765077094727469, 15520543037910966843, 11484620381947762562,
+		17395070963094117711, 7608132718922490881, 6531178971071758016, 1302814667007331361, 4002629363862769670, 14649492495298089937, 6868174210142585697, 15456170652716048683,
+		3688308493559609536, 5123828159813683938, 6245436817220183971, 13062234263274605325, 1313395302496832996, 4961840797708687855, 4990192311341859196, 5283131006216350959,
+		16952735659396950704, 1249482796824289329, 17859504101404809981, 13260403650830168625, 1583343855370236084, 11389120333403185826, 13676599385745755008, 5066667130137739346,
+		4799264864906918301, 18347145714884655971, 17034125441088681346, 11828378178487279470, 1759038296522081901, 9582407833575609381, 4195817009050503354, 12618256395967210055,
+		6486755100213398364, 5270923715575268322, 9268255346880651103, 3147724493117082267, 16710318779269985633, 1240462642985509644, 2400811796254219369, 13670743068809614358,
+		11437779990773246594, 13609113239383378152, 31268927496646090, 11618772705165035208, 3078024460365036167, 12138983306908962712, 4779157919015181380, 11901698850260672002,
+		14642787507945832432, 16258081639927585935, 2560321462542164242, 16286882196975458174, 4328159372518768969, 14313553865397841147, 13769372656320240568, 8950675126435331579,
+		1309709344837422378, 18403288028608342631, 17102350491414677993, 1133523394849437315, 12526496222782003755, 5447309058259018864, 17311120581405946631, 3760058661125144368,
+		17891474172606596407, 320094264574086461, 93927075222964142, 14355817838636249140, 1777882427773785068, 8237021421587560510, 11520559469641852991, 10567910693910023157,
+		9164300764173563614, 12322279811717869943, 2768902015676238485, 7761799112151133995, 5740162933856370894, 8043946608495226840, 8923704438836381869, 15189322655373943849,
+		12046275966378825708, 5909386969214935556, 1201990704907881028, 12128549009950617306, 10773478878317625320, 4554854625564648958, 14029736945871573056, 1353247251064221090,
+		11909123603272307101, 5517949035179831783, 3295386484950432959, 5605137795524476293, 10718654547602473221, 4984952409581272095, 883267724006996723, 17328431094026829348,
+		13671210467347025770, 9980617617519781731, 8339868735163579231, 2150724314757661915, 8571153021065445899, 9146903697769397191, 9122246102814640373, 7744779513085605450,
+		5733697799130763963, 962857090393715865, 10538932452511329419, 3413281437172590207, 6635428480179771287, 4404718679994229138, 329074170931436370, 17746708206910902139,
+		465623292609655544, 12740391094094156750, 15600221933467635716, 10712500242632508096, 4760789577759901270, 408323003115848014, 464706673403009712, 11801112998381624421,
+		5545681129476190458, 8725689673989867696, 2143812364199804063, 12133065347666807143, 14072918710585286097, 9027361966934517640, 12608281386782336413, 2053972384317260152,
+		11862793362110657447, 2615766363986534825, 5065170482898519596, 2878903691735623036, 5204682974850023849, 3382494556217615091, 15421437169807703253, 14936317525837021790,
+		12363228588136583724, 15035239525394825264, 16312817933687103988, 5294641777817034798, 1197907056067071148, 13084871057903003628, 5240492218216802394, 13798739245031559476,
+		16167519903361647970, 13106036157861122437, 2112866661358918425, 941609107359251234, 7240286582201258992, 17783018133711208779, 10433192833270769862, 4303514224506582113,
+		1549168540255262874, 7958641388293572779, 17867057222043259063, 1752211085999288773, 11828273580240483781, 11712913016012991853, 2373360154803731890, 6779610934665321824,
+		6633997178003959408, 145323909693817907, 2198452664824754574, 2920221908918689777, 11047294234593305837, 16840329825128198329, 5479733463453508239, 14054694221361300990,
+		7908792292118068471, 2703859967221946473, 6268006869726038724, 9406994672213611166, 12424098071734234719, 11900750387777467409, 10724482893673149484, 3191937460539390989,
+		7635348735946750413, 15019610708452651937, 107671898858364780, 16808612119435524257, 6120109999123152232, 2251481693156523545, 10792076820325151003, 12924551065805570215,
+		11225852067204798645, 7665324911993544151, 10402215331683389905, 2856131542917118235, 14152013119539822346, 12731746180172488022, 16402457225039188820, 11129045951416314666,
+		13009066459618795885, 9636541685854928780, 4783713672495759319, 13224924194053497016, 8044695420996588716, 4054951559323242873, 8718047667110955699, 13479622910466265834,
+		4333570709684826136, 3188483692974505359, 17976757824852085147, 12585927226835238762, 16665346689006249776, 14033419552450595393, 12216049696243171604, 447536030797427204,
+		14100792221456700414, 11757964686555543320, 3971513799111193530, 224065891283865758, 1282520657830780512, 9120233956471705454, 13711191981326748211, 3725543277190035504,
+		12094220323799678341, 16876894723130932646, 14806566188177921577, 2283878370700345373, 12254260799985999571, 12764268124075139223, 2425316412794046071, 2088679341162220742,
+		172600248248909168, 4338060849169481673, 12046085844143054569, 16220699277291497444, 10358794035289405365, 6739081270984238196, 16079387007561085178, 13471688054064884318,
+		179238781994802586, 9017860544212172426, 16179187983079961859, 1380105261896053495, 6187003332254463653, 9896593306091975718, 17181949235068293496, 6820143159816507763,
+	},
+	{
+		11156900805411912784, 1737275748212365168, 16993486692205800040, 12538938066475152524, 13167476167764338790, 17373319366642541595, 6054831428930905282, 7118452124011953000,
+		743288751022377974, 9226164090128370715, 17669221687181604232, 1117842260351396541, 17697784451833850722, 14382209306891991103, 16951372733687268016, 188390802712613066,
+		13268209255833199938, 16633146482265079265, 6044233937395578074, 1733872861371247406, 14239198956565602758, 4036306057099495106, 1778912298053970082, 6174082695927204648,
+		6390361653475754940, 1093882175267357438, 3784079074949811167, 17343872969822169769, 3359715652121662979, 16808529787251986583, 5169730697018536870, 52766949850965558,
+		1403521870654810721, 11668153767441183906, 12890534559297323775, 13255750643204945388, 8838011266491753399, 8488733891344199335, 7468199299966346977, 10645543722243906719,
+		17019046551094178629, 3055711824867115856, 10841870683594132444, 382072777978364200, 725450988418371589, 12501774248954630111, 10130164067258601487, 7823254091037946722,
+		1866199290196467180, 554488389245696218, 15654194385091454776, 6131785419830586829, 17856850737824439617, 17602611196814472081, 18244498160243832872, 5819736122106091373,
+		13147212495082910072, 5628914243538540648, 439989514095330941, 7620472329041817834, 4272251824771633288, 16564977601507013119, 5441117136715882317, 5622571730905974389,
+		8706277077547369587, 4848592786700984858, 11350018329458740004, 143688324288835298, 16536982722430328270, 6522962371020150117, 9511378862712142567, 18221873727623821967,
+		3985496688414455558, 11118602672015528143, 5383196298446424580, 6116994806363767576, 4051800833472889243, 12236802048340231756, 2619572929682123355, 6008593592518397571,
+		18159379849046931840, 11283007389905902377, 7465803490016928282, 7730454089227756796, 3569936088077890000, 2804205711716327520, 14107136042131448408, 12050401455009236937,
+		4207421531032215145, 7924589143024019458, 5496622772676523695, 7061817399179278712, 7371689806847905735, 8282663810521090335, 11422487361383982601, 6397294642072086677,
+		15924576759579234055, 9923512276109397968, 6142441356128988365, 11189756906743802872, 17790684027455851021, 14143953977451478354, 4002828116425422775, 7521923183240026608,
+		8349314793194266723, 8850246337652136896, 16635419760398709839, 12466509089914036008, 2686508850003621675, 15822032015692543407, 2211302095278204426, 12550915236378020964,
+		3844358527917324404, 15045102416646491178, 558560187822263769, 119801275176287297, 15593003307431898979, 12817356186703401527, 531419248069516921, 7957931139148417935,
+		960381383357168877, 16774709963697143275, 17896181076874992240, 1150415168189819777, 5498481130530161530, 6895900060791069290, 2079514944189747822, 3428689507902936354,
+		8525743843643076774, 6014251588524085384, 16423924202355808346, 2605496565158241796, 16676209604549923678, 4870342652354143869, 8337072895802905281, 2478197702680510974,
+		17076629945963768258, 7647523525256473652, 3999707005939039144, 9578933944626939348, 10469359763046002307, 17515033080264359276, 14272203721184987484, 9979666177276073145,
+		3896303254672567310, 17167309259158926479, 13231865857998180315, 2260217573257466310, 15465674863730076330, 4460025914284098438, 718707264700157542, 7215235109325196153,
+		12056920178557394302, 5131253251712581899, 16251877995882633963, 10883064494054484051, 9473274815269607947, 8874308005470196739, 4412709653190846630, 16469366225886156991,
+		13309932065155297376, 11504232979548718747, 14366229841750030472, 12797870458094162590, 12894694064456675527, 16977997035748966590, 15080606548583635864, 9292471759789693596,
+		1226107676031264801, 2683510924831720521, 4344623677417870872, 6581244316153602113, 12516966236091151915, 6758725397469564403, 3190083750600883646, 13018714111448482165,
+		877612159223846777, 1550479938877814973, 11850498481046386377, 18144061425551419288, 6811504328538189985, 16351446194603329949, 14495016749549056145, 15394017693349630053,
+		3547198835521135552, 9940690805769919242, 15170549880149605690, 10701681269101530298, 5914809102954412895, 15790219349994701461, 13664049285300230863, 5735249081148743651,
+		12395092509541605535, 2320592554345067500, 14213227630916688382, 12847883717490005600, 10192971941898238362, 18392117086623245662, 14369915478097042954, 9636190568462370402,
+		13308009076055104849, 9679299541833059768, 1512845037409468381, 18211703514703978816, 8337549295001075127, 15882458005321062689, 1212364284844818969, 13856780176955551126,
+		7602636613718406141, 2678224565451628558, 6976331354727208830, 7414684104929828967, 13536889690553324858, 13086024708711030952, 3748455179863046304, 1853373561223967487,
+		14753645881295168970, 9410794713982813264, 13485977523338061503, 14267793994973767571, 15813187206361118954, 16449603969001878152, 17705410933007144731, 10960511750491378082,
+		42380674434071200, 10068881872338405083, 14327149378182272744, 18264050153181932597, 8600790433943161385, 2952021171158508784, 13461070885471956301, 9633226987835715039,
+		10360728550079953555, 8471248683929284652, 6673003382103023756, 8972723925695500528, 5941683993959582947, 13500073059240140624, 17856131583218769324, 16799784995825923732,
+		7292102941225494742, 4807816512907139693, 11271815982004383122, 1065441269547643077, 5279915279332961503, 12100441009657772185, 10448964764090871372, 2944169874578456259,
+		4669722990542640772, 10017368027073540045, 13392819319228640800, 1070815632453829996, 7274130058405640448, 4460835865761538026, 15283885107956150892, 5815884817303156137,
+	},
+	{
+		987127652983079722, 6872208513691823695, 10110578719299008714, 16457381243184327116, 10779072738879347999, 5965282398006505989, 18251577267494363268, 9321323379108563422,
+		6119049170407437179, 12938407708038792521, 10105420405825346383, 3416306788177016826, 330648587825212481, 125568991290568141, 13857127346570918649, 4376080986981308805,
+		5930434126597036589, 11240994623469578584, 839346533006694594, 10015087329724081709, 6285097815938761787, 17244606485954860090, 11523249727882012981, 7178451948850151803,
+		16733615335426327004, 14833564736134873977, 15736159435317472941, 17560193966711884894, 4670172300306758374, 9477713670983496835, 14243955354032737980, 6459864769649694970,
+		16053517698989562256, 2069464650596796670, 18305730134729303993, 1090863611964008044, 10595928817546105363, 11743183506441120484, 8584767248013363683, 9187452830514379903,
+		6938579711827578880, 16268282168771714072, 4567473305742437221, 754548046014059669, 7773636946295303572, 8132380485366854656, 5054542590195827722, 6074347500754248128,
+		3955857908381474930, 11852678900999621852, 13783017203403417097, 13616745777931267488, 13189924588414196918, 14519927295809952876, 9334100965942760501, 15172548734242885286,
+		4869852132020793901, 14921212823114724347, 14342559113353033349, 13336827701782657309, 11168346789878684452, 9790480725902426052, 9171116079841529936, 9268902731763220711,
+		4417372365016540659, 17280138652899703220, 6650972319709075180, 11252221422799491438, 6825784270383052414, 18308562203755695191, 4237445205082731447, 8485872406483449772,
+		11718726714045105993, 2624508790343569765, 5794111482300008213, 12819216567095091385, 285329842793152354, 17257707863943097374, 16912487373614458842, 9501952033607497057,
+		13074643344738491288, 8505193022029238118, 9932652098552590323, 267408114280737600, 14802861246220332716, 17506028737327736269, 15929083591675282371, 10937680132245212187,
+		16688733766460131050, 12777635326299184071, 7769405825716531061, 12435979606514844725, 2767987141420672349, 6723940414217341603, 16114182069580717377, 4541113259200434040,
+		8506371389960537559, 18031198550689409305, 11510251852995503442, 1923472385053944821, 6189904387119195613, 345664413118550356, 6439003191582953600, 18344385760549575361,
+		5320548958745018096, 8341561189829530680, 3327828110998403156, 17981346269177513223, 14254804273025688074, 11111147827704077234, 9093333670517437191, 7272552282364063165,
+		7587268797387514088, 4402481408866840263, 11260815389095334885, 14391444701764948710, 4224880318604689771, 2472148458660279030, 961218007313548745, 13826356220879831691,
+		4477325369345373420, 299141931133875776, 6787652129916359301, 2498016036564260464, 13342319943892943548, 11124287719737492205, 2456333599771808442, 5084719026388755304,
+		11208298545009109072, 9361672558653085726, 11597473974277116433, 9123409098329262113, 2315750487079392743, 14788891796020803799, 16477373474431052867, 6394267218565388055,
+		15099803091969065643, 7815556206466442264, 10304177785190927723, 6493522556494567776, 14386173575053274652, 4399768637448990408, 2996083572119906777, 9762267038999270167,
+		204205141115459509, 15145142808374731170, 1678672167166598389, 12032976094920574395, 7472791648310888425, 3687068899306742850, 2661021646792225638, 13705804163602287184,
+		9320611303424530507, 7295004960403065170, 15749376924513664173, 11543669941217924178, 3710258597217352196, 11371260298937340150, 3902566672028686120, 17983841473999282668,
+		11814188798674654097, 13017429106091059634, 11079902218909650978, 9064898043690914606, 12023954026861289442, 3592879256613061321, 9997625973577562433, 16073808232708438680,
+		15365030910001289574, 8789654976305207659, 3460532362538090307, 12992239135084766157, 11449242863169591803, 5418502644558230048, 7981056000757137731, 13021725301900406539,
+		7782773734814780443, 9390379677704432300, 7130223982341575476, 6496906770393189740, 5095392170846288421, 11058865093605824851, 11021902438459302094, 6088242418938968652,
+		5966014717657529537, 5136588784988696205, 6360472729290909457, 4447169061266082500, 12506934948427595318, 16433395045878253504, 5116318868244944213, 6640832565780621049,
+		4132920736998081103, 11827975663170283136, 379030309731223785, 3149051804072184938, 12035317616979166548, 9642536337674500310, 15531497803043399747, 14399049832547796531,
+		5493097462539196248, 1629980144571354138, 13641173578972112594, 11096917099468924214, 10934169048860132281, 11269991112518485434, 11206050457519414207, 7939067479736521906,
+		3806755078949823895, 15988975666336042818, 8246267395645554105, 9703363749164024623, 7795606269507901456, 451102251659512683, 5865831186929065346, 81064915983990550,
+		5810137226573964106, 8424253088401255706, 4543883508937971494, 7386148745257823512, 1348150366217548727, 2103092839740150931, 8353010273955146981, 16831854467863536537,
+		5095778754322493440, 16577416628492146129, 12288076721910512064, 10563487622054214075, 14620553808255752273, 8159958565993701874, 6712100880095874267, 13203797993773281759,
+		9640010815039549413, 17460773950401928956, 18229977265837445092, 9252634318278265623, 16798979334068219458, 11731856767337519419, 1551975378671663669, 14320102155496153821,
+		10528988339881191052, 3808685834232068820, 1064376960475785008, 6466670187430364599, 16860839938395945578, 8876458447995837267, 7897541112736965607, 10283235741250763328,
+		12246932755942887931, 10842213418139067847, 1827392608284960926, 6961756951208563550, 14626966634382828071, 12653808277900379805, 3359368990539585596, 1190255644328095727,
+	},
+	{
+		10836955050615624183, 6228108794259714192, 3769609579318360527, 1481673673659326756, 301329772189110029, 3574710782304999603, 3037244905687722509, 14442941761397229485,
+		7739110373965523311, 11019153332996240080, 7346010155518751797, 14853737521111213548, 2542883237207113209, 11015136828834421504, 1998601666328316353, 1540417751495800469,
+		599034134015360884, 11263317530774995092, 6667501365379084069, 9844276013103312691, 7566306886180438990, 13702768345615509363, 12525031963170717968, 8463786212988210464,
+		16430555432520738762, 11225321696360643709, 11777973654353154098, 13133115227828884393, 17678738157022850345, 1586660156856830642, 840647763693221003, 8645742354464326466,
+		8067725618510810414, 6229041032854057836, 8025364837156161898, 1290443646630661359, 10991323655842003728, 9346782840170054789, 8939059450584871902, 4772347025802041241,
+		8187379062828795656, 14744366698824202673, 17014663804743197103, 7704635785366672415, 17162645929628468457, 12942442527592695216, 13291710923558633295, 5800071247768119960,
+		3552067877931717181, 590108493628737243, 497390871097272557, 12785795808441396281, 5561451613221796230, 14263823913216836845, 10481729699001112354, 7818094022046194698,
+		3598736754916501501, 4827022662021197854, 8203180748141933720, 10283251600632599041, 16186680658340956808, 15183393398087319142, 8714402370450665212, 13217902016653171217,
+		13766344083396522552, 3843491774288631026, 1174164282483810421, 6398024882371290634, 5459580537585379131, 5871096222069618377, 9611875286525007701, 1940221124144536452,
+		11598781954647517543, 15695098933552070478, 14976427118847622464, 7147358677856872160, 17135524627354123951, 8338407198954935663, 18099467407613897492, 9025371359994313919,
+		11451018285787631498, 11710749546511767589, 12969419493657624536, 2338911230088800542, 17492614411321910750, 15274296072504110502, 1258801445108685875, 15178229640559232741,
+		11743016372336018414, 6125536020759642301, 16563280170798047733, 14529052521060111789, 15253502329174644388, 1556763737841306861, 3041940064290508531, 18020881359462953336,
+		3035547704692483898, 462291414338050452, 4209186193642705826, 929930084709639338, 5246348806539841852, 16407585218848843770, 6076996892610687611, 16547395936238439809,
+		7781914900266335582, 17967080065814694611, 14677062197599091614, 6667353926398988267, 5658765839564756939, 15807817354312473921, 7476371642206655552, 1194561222317134506,
+		10645607622061780068, 11583886495890779582, 6879987349345299140, 5119348262235800038, 6546217876212430196, 5534845503308945424, 2003680599532879233, 2824480091030475274,
+		2297585344913389180, 13965959247788377604, 11341378863608387800, 9890953382689640379, 10443523266835246852, 9631856696811288063, 6944503116553031744, 10030824122780966395,
+		2699238910420203023, 13176131497943324759, 2961070701879546988, 1511208990650977146, 13153451530298458944, 254163587562261430, 6668642257003911712, 9040693998431169077,
+		5596789796292416136, 10505785820531892681, 3803057245175025164, 13601446877323203658, 7939638174866660891, 14141848241206986005, 13782885912650943563, 6287188921995938212,
+		12999700407775352603, 2664314004284450753, 7085329252118415126, 17472483363754271126, 15550759073378819069, 7572177503239633527, 15705617684783232308, 8586972133880335199,
+		6636244234467769744, 18284390012667441869, 722929822219329257, 3274166388651987221, 13177791837760949480, 2568122970128111127, 3477167651270374316, 11371867850093288299,
+		4065583279544717744, 15575999213135020408, 1319417044854511604, 14713082471342741360, 9399053450949627084, 8900637792268080986, 13511414538589410393, 601556817111475086,
+		9243142430859561073, 14638657859832212223, 15324499241122936340, 14477761753578941934, 14699832840191454785, 5114873517253108658, 7427057898915535537, 12536800031182849473,
+		11775949216482616439, 9736654184925478086, 2941126957776086651, 11331303510371804917, 3535865528819665754, 2488682969529955908, 922100556888217739, 17904958255578472855,
+		12876460969864886954, 4692925517843901006, 17390372170975588763, 14692578774429957295, 1759864963511373267, 12016553435172103063, 13015881292003590351, 16187569590073958370,
+		15154092100094191059, 8103665941237580228, 3265383210728928809, 8341136973870067643, 17281635732314163959, 16433737305161442677, 9130496888060417111, 7070932927684908859,
+		2129695226164849659, 15163429615374108928, 2225893409909150746, 7870945454511315288, 11525457118388411301, 10519485231888976311, 17601979933176863246, 5257431126828903605,
+		8898009465920717074, 9418463821940622934, 3166596280515383312, 14529914354665032916, 17743784337460844568, 15964972678726654742, 17116339264937332927, 17098426671353029801,
+		5868176722765418764, 8429364877332796959, 7785756492654137899, 14975349488807886278, 3272010964035218775, 8946396491617515063, 3774503492701710541, 2113917870331282160,
+		8185651664029868180, 7343199417670698200, 16586532029502206227, 1531724981369431299, 5596507566645246686, 1033673521199123313, 6075312368002387319, 6988496924054716781,
+		4604669688530289732, 1867259042549585024, 16180237500272383882, 3296394050993129267, 4326520583229998770, 6557569103657179065, 4126356691591689646, 8674328613473447843,
+		18057076842177382833, 13020419432300857029, 13646402493577420410, 16962268104464192344, 5358581430340252761, 16443104373870300795, 10099216829282619724, 14890543634568831960,
+		13276631120161396750, 16968574704982977753, 2376454925072971568, 9477134218094425043, 13784622991820528988, 2074505569780291922, 14294803056569335889, 8759684036994631222,
+	},
+	{
+		16549155412115374305, 75977962737081600, 8870825488941031605, 7403557657089993256, 5825394234709429518, 11978746413791918409, 1876293130790608838, 9416631623519692610,
+		12346821858361333862, 6352722970730511156, 9920942104315084988, 10492373916708072181, 11163323626947992791, 17035282992056675772, 835685192553490421, 12792459312570503983,
+		10447922451077327640, 1515090998837129975, 13498807582085718212, 1212623301098019779, 11573518650162536086, 4823461685803772444, 7289704908733783271, 13167881392748327839,
+		16959954449957105311, 11051594981465026138, 16062472412226411858, 1976004115345602080, 3630495248560019222, 12698191555196404138, 10107923614229901155, 1597725222698864118,
+		3416019089997140849, 3011417601086561495, 6275242351124667286, 14197557183081060761, 5633711018871057458, 9723496411345030748, 13910057756335530832, 7285051335492395815,
+		16774605620279328247, 10223834398868957807, 15781733027568799739, 2607095622729296315, 16499590296954181006, 7576646116121533069, 16638313875339315529, 14296194207652471696,
+		12874411821611501068, 1998417862388106640, 13882642435422318946, 5791129521978463837, 7512934139125398199, 6966283273373526248, 5475728301311080129, 13542211842758381589,
+		7798993150530415596, 3288770257171840452, 13373286069558329631, 9784279046496345014, 15725032660238528813, 16038931923358478835, 6921788930154218900, 6093507035435214187,
+		12194839527972802101, 8376199250979271449, 9055995864116790217, 8125030124567662718, 1070812422878398727, 3950906148308170707, 10121516919638719072, 813471384549762068,
+		7610605259962047827, 14617655900985224117, 16089669078196617440, 10594009761533811214, 3425971360520359121, 1245021768718221594, 16690372892586114152, 9933179766195044175,
+		15142732720676276463, 17435583143726694663, 6030257647680338377, 243683009289621849, 3064238900429394982, 7655019927497549159, 4484400084400458429, 11650860345018651068,
+		16203650576183697977, 17614744533772112337, 1119292890050870301, 4574885263986729787, 8108207498737924504, 9708434439316056191, 10676823369888368482, 1078311554675991883,
+		6876202174636220158, 18057502510666060150, 7821730895845187783, 8882321799602877790, 16220624224336230256, 15562800387021280583, 3043825293109091520, 697130162105054983,
+		5394549491776704087, 14795348078061113966, 14206080764200897220, 4623073019242398493, 5850602047109930316, 13783531993760979209, 14764346975698048641, 8951680172224205890,
+		7302725075484262769, 12572584665857403749, 6499691362933905099, 14476353114356185371, 7381716148644532401, 1573798302334388880, 8128390307766282880, 14547454176248589604,
+		12109367644744157376, 18037756988516427980, 814572839386760074, 913616818805172815, 12974490864633240943, 5228203788953366069, 11458421156905635350, 14534725545904442520,
+		7717994192616957513, 12204841747568567286, 3911093871228418198, 11236736110419819217, 3283907124458179474, 11742518530965881218, 15033771683298452989, 5201173013910789542,
+		13950307561490203211, 2109530041534182225, 16966608361725322273, 17050013487213560977, 6582524050666171954, 8348662591649610062, 18257068567217206885, 12084557407109908164,
+		18134052713971906645, 13522834551049471624, 11796035797088472898, 4408384297249203940, 13184035659663315829, 10318594606381671372, 43784547091343099, 5864759723778872652,
+		273751009786971880, 17433500308695913052, 14095169299451888252, 9384697581863180516, 3670310635026975567, 7512955195757960238, 1061441390592395566, 8687976820410979119,
+		5847434943730572861, 6139588162124989313, 16640425042872222986, 2868461478718351559, 4582082172412426839, 15999623457772192080, 3911979819012561187, 2157661418664981538,
+		1679437503202036379, 3357369754420384657, 14227038694942012893, 10849243658636382261, 14698996273665673323, 15473144682787301630, 12886363027445513063, 4218522843946321369,
+		4305571301049736163, 7569433164869749160, 9286896219015408706, 3061813620853218759, 13836461093317197944, 12893856993043908140, 17368798334120212403, 3507360881370918016,
+		17887381848254057882, 5080557806347717197, 10977337278063191668, 13725230338861893934, 12618602415751234016, 7913767807930932665, 7119689779124353718, 14253582440914432409,
+		16180079775228731323, 7952167928403988663, 17529082815577219791, 14568667835887326401, 80331144542697157, 16190739578357987369, 8688615216852085496, 16668129019590270615,
+		7430615013050690552, 16490141830322172211, 9793941851666815428, 12678643730925993658, 248986629347794843, 14250412400606998841, 7671639316274744213, 198890803142183275,
+		14099347485199617889, 10490379547566026579, 2979540189595374423, 1947868558918413664, 14807112327541983728, 2275659819146309375, 14464189275380358394, 11448352451702208893,
+		6508543885912264241, 11768683250765503158, 10952591955476802447, 13816638967602836229, 15422608700909569544, 2270147616630940233, 11179267547770249728, 10448962907285827304,
+		16734703714440778657, 5221611440144584595, 14517195248502569256, 17256223341936104100, 13260411672715241049, 15406026631864099983, 13737383554048659263, 15455560302156741675,
+		1751310744149771156, 13066379976997527874, 3353407191478085130, 1488844206746128853, 5630044290904406795, 14205180196532348798, 10021323252656730909, 4177092513333669169,
+		16120743770319899284, 12307096057555293266, 15459231763664176764, 889710173957193674, 4419259815443372538, 17256024223837463177, 6105822529166486288, 14459703836399905847,
+		13918155529832261002, 12953608416498491778, 4285102780598248527, 15853935066983430239, 2610351403194505517, 14905969693015035277, 12043976761492019990, 3883507340167876094,
+	},
+	{
+		10994470105201067642, 16033352651464686189, 15774427704233149170, 4596106024708523955, 8854068685612048031, 13529126595187822090, 11509928293490788309, 11620850709434334690,
+		2068337952936280662, 6856444059219131741, 17213926210819196459, 513413453513211652, 5520465604253824995, 12970886588014924605, 12296275668437451137, 16808287251356954962,
+		3413637388791433603, 16937929882486384885, 11215805046681294327, 11559398419268924015, 11697258172757450737, 6137795229387768085, 3190984692021653574, 15347236891154706739,
+		17955247196574331290, 285928599571507431, 11902987704297070981, 2841167725097799100, 9281167410796848363, 16444340476026142274, 3423202423051178709, 9101021305726472246,
+		7129792976024548817, 11116052691850916690, 13765136177550464799, 15815419857669199536, 3490265904262366633, 3075105190264147815, 13090337405102529529, 3772589223509323910,
+		1865569627339845981, 14405510401062639678, 16548248891153314376, 18134729633170718083, 7342289204282809135, 13678804825671892797, 11309594694670555920, 6482941613725556691,
+		15861081392207208208, 8373665453512079014, 1489270058265748447, 3594001972161344915, 1115942979837741628, 11080512787291988167, 8129036993725083225, 3358115086982889477,
+		8869273893561412239, 10349812081309865197, 8913824872487209090, 3148808685596180274, 530908416884501807, 10284103744075805979, 13606889938905754722, 2418062398586758364,
+		12413212040240282991, 7478703750955930147, 1623142090654002287, 3800351594986125089, 483782039790230646, 7823394007049468275, 7643246613581822171, 15001087565682987468,
+		4027740097060141621, 11299467443664320327, 11151439614540606708, 866223440636939151, 3440384894029167420, 3873155505711856537, 5954029035616033594, 15381861683078360474,
+		536906646315848696, 4762701494256722953, 3244970900590282998, 13809219136128336072, 6259009038800226590, 15448401588227595780, 5228638796256712654, 52817644221507266,
+		2298603653884322501, 601221199968240092, 1285112712738261659, 13882709760355308533, 13563254433762438170, 13447718334658435053, 13493687958886238103, 11032778298151679283,
+		17130548285854289846, 13389656739579236890, 11825243553071488462, 3295650559395515332, 5681593832990094932, 1986112566735995333, 6900923912677810734, 12885634718618182763,
+		5991348986251844787, 10652959958005297329, 4727138097613835700, 11665606181484659859, 17818486388489237050, 17381457056943650121, 11483713831771420728, 14346336385265122549,
+		6806904066777263417, 13464056321884738018, 6982639430167685380, 7669355554060154277, 5859444273628884163, 13073052226541367148, 9082949662405155834, 12390918296713433257,
+		8626760324117733843, 16403951745962159364, 5837394731212322914, 6847167719031297053, 2888142337636247281, 3409818743436360750, 1677113113408664401, 1222157560539217476,
+		2099068961815044779, 12562181036171628906, 16101890713848274666, 6017764396716978009, 13064414845499489050, 8419967306079989759, 18212218073753486044, 1008986649080828268,
+		14883940931343463293, 12319376897638542821, 12367185247284838739, 5861252096374912155, 10018798299303262817, 6422772579819453330, 2070123940915480886, 12141302052520620302,
+		7347211048650261526, 4324486111460763452, 1238262417801832007, 7620393213816116173, 13629115925647807355, 17975185632155863015, 6751253893269214002, 3530207280414557051,
+		2294668553308381923, 17165287249067859297, 9897724011823072967, 17409851874231284314, 13888575318617508639, 12092766090379658603, 8412268183255186961, 8046572777745318483,
+		4493498909328627892, 14652253245762410953, 5345262207345951514, 3970988687199074488, 2208768899312608620, 1510839623981662369, 642580537527653605, 14940785106713466054,
+		12480576687390709541, 11249304546887636239, 6075047530003410694, 6121669232248820705, 10309256543424460776, 101796817907499847, 2110451750984093184, 10778335615512351243,
+		2885395260584376454, 612553588199732392, 17978615338185945515, 10414937982597482385, 6078565000469652304, 11381998957121196965, 1536418226678270090, 15114446343888525079,
+		13178439025428734594, 16388038968589028071, 16165750006742628176, 17903639397633243161, 9560319088110737392, 7888974492854359310, 16116323630343158496, 10177829649622711030,
+		12866004572891901059, 10190228418101288877, 4717913135317392922, 13460871068228811018, 4756401774767581561, 7711771325649205249, 13695132008344052711, 13361851345229950778,
+		938191787235564236, 14328703178349042628, 10217257468952800498, 10415924210674864240, 7171739159943819214, 6502538915112206091, 3300616451202954689, 9576887970605726107,
+		17259872866446195810, 3694244894150718459, 3214322135693408389, 15571503654130046642, 2332159362399220208, 14087696453363417437, 14318693886833071484, 6131092646618026480,
+		2378363646789710539, 494954399989334038, 6915496914984330558, 757197055392642378, 9097171378505823650, 12104288338329241488, 1905673690814481722, 13011078677095066032,
+		8123217305309052526, 2527408826476194625, 10072980201182378784, 15489255866670747761, 12978131276673936002, 8312787524887306087, 13561211528259491689, 6311660759462081662,
+		16247831307849916845, 8654394682758927217, 1180998443932568506, 3847327552938166714, 17658215545137701161, 11975413369861829206, 10679985684889599173, 14928266362876119222,
+		7605162785889302718, 5718899840342120733, 6057249397801266401, 9486440247354542717, 10618370743126190918, 16153494357430969850, 16785070420314699787, 11277000340020413902,
+		12712274459771886808, 15748114764509451764, 1994630377849062253, 564390855806287868, 135493276425567450, 4305883520257541088, 4842008929542073044, 7035106970720249617,
+	},
+	{
+		5757832545805155636, 17609080533053427627, 13855662030602089892, 9622498683452213297, 12281586442064581946, 610529441714948581, 14740357477019436626, 16983190111725558863,
+		8470173855499872166, 15915210069852758660, 12368087246231545517, 3867174158581293223, 9082358201271846042, 16663463402757176964, 13740908859955866819, 7748969412274962298,
+		13375424826931892789, 8508645806391261552, 18359272328758476903, 16433208398005282080, 13071423254987294580, 7999383023651164492, 14514701556577587750, 4848295889377673720,
+		1020519568493754982, 10467781020270669620, 17607771250627508499, 6620300538436640218, 3858527175523168333, 13798129597334232823, 12495322651937391008, 3926713306087152023,
+		5116038770086590715, 9943789276328255827, 13715439407309914230, 4887040860130243503, 18288477612078228131, 7640050573721350378, 14537362862524718973, 1658575506924200900,
+		18400486168653423966, 18026904540891591040, 2037921821724043966, 18010956304511658647, 3751340308708032971, 16275459031633957091, 17177866831427164840, 1635431811339422016,
+		3897330996014812355, 14347736534650088376, 16862404119462964612, 12216005411754788835, 11561909516001453735, 6261639657930189859, 9101978764314050064, 12280333151331067982,
+		910276569977357717, 2872810615152156462, 1942106118995935911, 8734004121981822024, 13862118436432879698, 1912639548162720505, 13060137938875924732, 10642216911059510120,
+		5132232031613377471, 3053931945527415993, 2695169719602504430, 11855046366025891084, 16462491222215366712, 16664416596202206835, 3077124688577987843, 7109495326459366311,
+		3858762384693274897, 7520194928987242278, 4496744297661574884, 16159343214247089321, 6441167128044578145, 3604951495694157848, 3072075325567814428, 1964798869371174506,
+		13689578474000942304, 8998724267038772595, 3350174507425430811, 15015413657749135511, 4848907595494161497, 7935644131326131098, 385849363817229511, 10087353746314516691,
+		6067717601858189468, 10438404859927821308, 9991403870358837471, 17728358586134467771, 13476949968946830198, 7311235997042381570, 4429835371823736972, 17463216455983091974,
+		3446799583712077997, 6763499387263152328, 9231082163128267527, 7733182914440272884, 17225092062157610409, 8163842076250628108, 14230171836718858439, 8195740716303697476,
+		57759226194841354, 14962480748390190557, 2047254208877381876, 2830450574091058648, 14905486147404440754, 15792397930637469157, 16383409053580142957, 8686506861607761226,
+		11120178572139812895, 11534611317577597022, 10437856602660752754, 13925966850017814278, 16776862023867799947, 17362554889424346260, 3408825299914455645, 2606150045870067742,
+		1119490156854665483, 16772836556735128526, 8607715508817325509, 9931017263385440911, 8799481055779587022, 11740562709785257943, 1956849872282864970, 595288629437737005,
+		2281206023740505682, 9926719762453358166, 4061056930877891291, 15576657447058286418, 2614863633636977404, 2206334532799385250, 3474210873232711865, 8477734925846980028,
+		3340305349427486363, 5188523629566097463, 6160790887356413747, 9863988255192204305, 14066826366866912046, 11932779567129411871, 12863116515340321220, 15222969978942513045,
+		12758642615291604404, 3209096496454847183, 11182564090025111575, 1931382908005123647, 15151007707308352245, 5954868822601995640, 15742433078711209582, 3347972315985628205,
+		16490337555999239547, 8990885971520264447, 10360258506616249745, 6630482203535351500, 16999397485942558889, 6788531264412870316, 7229988042452941955, 9856917486277085502,
+		10734804718395003162, 14385908274213668346, 6022876926209575383, 371182857232839872, 7412466195447558077, 7961511694540082231, 8030758761844457080, 8046696009323575767,
+		6399666206029163609, 17663811097734928631, 11470778017516778751, 17702646621253134508, 14876192013866833082, 12935280981291312476, 1467399042175927183, 8848908916563618579,
+		14359906986235888744, 4587839368531771442, 10497105860390751463, 14244616431904836676, 14906421794748569105, 7955760173743833219, 17152550002849021490, 138081467951201370,
+		2349932829525749283, 14749355610935637731, 14751838563606808702, 18058355029195133983, 8461199524627795693, 4219910612621001507, 12776964042319070094, 15905069451612157329,
+		1355498131832429384, 15975585519420207244, 15757549940022310945, 11357394570768845273, 8197697208897202922, 1901621009956576265, 4290101364365692172, 11947148614241269523,
+		5840762872471677309, 7514977007446174348, 1527060545570586419, 16609099121469101859, 9320342325870097548, 13965331598495025936, 9683433385601741715, 8845290689278472178,
+		14119395813630029665, 8634138112335652518, 4658233985292819043, 9622846971166516113, 996353694479629398, 7404001202059682426, 18145845493517798921, 6449664057746980028,
+		16521775738375440178, 14142357232938693849, 10990147202113110230, 9959066954415780230, 13034621383041722634, 5025797339352139456, 10322111864643366459, 2614961497496501105,
+		12557910439954509999, 12230084394391362713, 8427020226737465235, 12518021396913122088, 7134271418642259845, 3905501389650646356, 15707807001177039585, 2909191175572717037,
+		769225015796913609, 8753059944613840368, 1611869096690868003, 11449828005116201197, 11517191665323762104, 2697717476879599241, 11188965056705006770, 6249359019890699508,
+		15594613737645580981, 3037156291483237329, 5604071908229825169, 1604475019228431078, 7766918222574600204, 9339455406279970318, 16266564745812517195, 4799424886612563329,
+		11601570184515356415, 11247678357869162156, 8415095559389686315, 9625816053586466047, 11807876143163335372, 15690209134241397733, 8684637224468015605, 15974968144193406020,
+	},
+	{
+		11275984449259340674, 14922638629881602958, 17186426309348732477, 2094500549052461127, 1245672419927595636, 7529921141299797945, 3181089597449057707, 7749529014968942143,
+		12842581296013847382, 7845624487558348664, 8747439372999364825, 849305823897878133, 2217292264321907974, 8173534404179332054, 3588643190593022889, 12047811416592660080,
+		6959527445237219799, 17170778245769606301, 807762173031474321, 9151445233487017286, 15103411489939446333, 7976669669591851659, 14824323986579638641, 1535817133122800221,
+		2365455792963674834, 2249234228455309648, 5237136544555745182, 8814246419234451463, 13017813702607013347, 2241193992640629733, 17982226236989862510, 9800528153239873634,
+		14106286229675768856, 13210380707737857536, 8049798856134302097, 9734560649539497957, 1623205786926824588, 14287958304696241706, 1800854015662052826, 1212925137572581937,
+		3026947385483276729, 13169758424754896088, 6834174387382969128, 7206544572805916922, 6934064062491731757, 10620406409375153308, 5194048681860016706, 1469688754160716493,
+		12993558037376222988, 4669474265806332952, 4832324179281001408, 4413085485243863075, 5405837906169635761, 10091776239975644239, 5290719555562061144, 4213669820858776415,
+		17271890190678399664, 284117971978206043, 14999643475704678808, 6264699496666119083, 8859934981351804429, 8300880062060532031, 3667839168820458685, 17133003164910522197,
+		2997449698566957466, 7884833253198684528, 12498695470674374226, 3115564300965505022, 13376506794876055601, 17895331353362057251, 16990581103090492269, 4674862843410794096,
+		5006430925084708381, 16053115139414023422, 7049813739763202517, 6676629839394309180, 2410666182773729148, 8945309185393628712, 17674821778351929167, 2683163960153153804,
+		14505459891908974624, 1849503921080779239, 13990490450160111440, 5181610498614712941, 8653117877167770474, 8814499350344722617, 5343755460620184433, 243401361005198353,
+		17791633957402883820, 5938849497629314459, 8356801465373786047, 3163889445599730677, 9723709910898285412, 2841967670768995554, 10896757438566636700, 7434996874241771203,
+		7372440365321345784, 2862880403174214663, 8420116322934238724, 2818552325655576635, 111342786192022359, 74705672003306783, 6591511741514218962, 13124391319573921957,
+		9931074113040228488, 15362193958291437280, 6613002366394890474, 5258448208225327677, 5126245224005997831, 8755434042915330962, 4405830479557957055, 13343591337768921462,
+		9242810916685205316, 2838356272544913798, 10099476622515682546, 15551100165305852662, 737838832976059770, 11188026425234857295, 10166119013055947704, 8628233674684143419,
+		14086272070125896854, 12009239107306499026, 6592816798466831203, 11371087141421707743, 16277593907837607793, 16449564916599232060, 17471042072158213549, 11953382410698485455,
+		823047236880870350, 7830286704456953572, 6464058012664717582, 15521380082330968365, 10182202815901986450, 18143527955004661429, 3207725716803325445, 3193887560605396493,
+		15569872930692175382, 5346306686087630019, 6632365629111827330, 15865883909120927399, 7200040798106687333, 5723169387900917854, 15027071603483375844, 11018037359110138454,
+		741009114382240162, 13879961246490269823, 4790141947869766711, 4479737908710468090, 4979904969974036721, 634413885118778288, 101727670723732801, 3160663692354720401,
+		14613304240735929191, 7658770973133328064, 3028731168325633068, 1486737152001467114, 16715835021406106944, 15214200823642287507, 18441898204110447697, 5669963154424393607,
+		4313074171267006471, 16217697149498819074, 2027993870023154350, 18018610229517524263, 117205923522590215, 1784380715025232199, 307956084870608716, 4140912860495129528,
+		3938313265660748839, 13018885466029447230, 12461354215832959401, 14495299413345669177, 16234805331742830462, 1578184208291171741, 17168468892394781152, 12575003872292801090,
+		10424668870965277693, 8952352824982702795, 18017430252932614600, 14101949308713937413, 16342352613992153502, 6862842966642668923, 7238655696295295374, 11216037980129705353,
+		8381651800836461905, 275661552864412688, 5548629401959193001, 7174991431295718071, 7441251258233899268, 14052832476485122412, 301250917807487282, 17797202428295526090,
+		5173263645506172639, 7621852612520351243, 4670271322283433581, 8663786927624336026, 14433502423455668413, 6926265712671351075, 9776903322968672826, 542207238644018218,
+		9588056942118198784, 14024040464098859998, 17712446698584877455, 17945455593410056285, 18104078100936060946, 9565731894604896153, 13213845893767817606, 16043575675737450101,
+		3436179376183792489, 8124476612946977721, 2169106928994773725, 8589833084708985039, 15137137534993478994, 12789920909097626916, 6767184505234754407, 8369097443031908183,
+		16448089571044203401, 1396460397790470601, 9796571033221459545, 8162511506983092708, 13893406727199803081, 16188892369453405032, 16023105002157964343, 7061289566170423383,
+		10448117565485426152, 8145533940921335838, 1579413779055052019, 14761309857236492983, 9815666466018583851, 15131106965446764630, 16986514923298225288, 3751380281663155649,
+		2224143503200162255, 9410177163066991107, 7157489123570995878, 13420515130397093319, 2675717750075873421, 6702938999067232257, 394050047437199204, 11922372120263518221,
+		9930837889018815244, 11397955329795684905, 6931891256005909739, 516538601500853702, 923444815286512108, 16665363217941733257, 1377231042965759902, 8439923996651310778,
+		8743817608749172620, 7804846024944300667, 507107926259802795, 5258061329638283805, 15071070675288472598, 1848743106176521296, 16295570828486620412, 7409462376590083349,
+	},
+	{
+		10223936123327786454, 2321887803300626936, 13607747528117965743, 10456421630388400123, 3266519591187534953, 1053691207967834494, 7151443045753788549, 18124688636664828399,
+		6946488664257064464, 9775328903143754150, 58700362449753229, 7901817271072273406, 5074738678159003249, 18397239731906005785, 15911102965988125888, 9277654580204145348,
+		1874700306906525099, 7337351570334852732, 7954195906114335343, 17230226427261850070, 5181329498860909261, 107167242193237170, 4364856176182710332, 14611171841443342914,
+		10990327814895720476, 16588412771027628390, 2850177278998422188, 11569813740328484871, 3922148781422941186, 3581659216490446242, 3646872304052351376, 10887870617200051198,
+		8175121141368087217, 15079393830876652065, 16766987879267543828, 10582796406546815217, 16832256009371376870, 10042650470778064892, 17867163453935683780, 7123418345572641116,
+		1782651072016504775, 11033882508408412333, 11105300284232190625, 3276372405089292929, 6399472468041061588, 15319690780388315076, 4928530863063375966, 11596222198340277418,
+		5452424185619067445, 12050433097586021281, 15018766900844679217, 273234254926088220, 15426383635547379531, 5213762666043737626, 2829185842069118470, 3230799283770935127,
+		280030342772428106, 17354882606189694746, 17455445295460080284, 18076709382926018941, 9895982528034548913, 13681172423928175330, 1656433131309057012, 11935757350437721114,
+		14437472586336929440, 17387041914242263390, 14861577074379746687, 5146556788377906297, 13036814755814090195, 15108836859245573802, 1667563994642521213, 14722845469958372258,
+		7781061995240980266, 2066078418484154391, 4089376589847114892, 2434843609506038666, 18376509832460312721, 7187709121160627756, 2455436656049651823, 14419116837518875372,
+		1270185079976403265, 9214436628411717184, 15450450827683432913, 2880014804806096082, 15448799931519826757, 10080240282127928735, 10673974088219619287, 12998944469117087518,
+		18028691745165748687, 8931519595829275195, 18379893031942930865, 12120980098075498008, 9596371470855895261, 4133427878071274570, 13159312399982591699, 1639865074052258019,
+		1661696187746428348, 2656198437014978712, 13769477291975851694, 12512848714492869444, 5980926616932344693, 15821983893144953005, 5816015630031200526, 15887565799959254415,
+		16463929919291729278, 14920112063826664828, 10056471508435050704, 10696267144984026763, 12049530292963090991, 11926086636123189182, 9464890378472966538, 9719194510330239601,
+		18110249193861022779, 5612784685592189906, 11360454032996393150, 6795401682138043705, 1961398978248902107, 8999847457729547905, 8941741619641401180, 6086938661427918241,
+		10153847769616409178, 16591913677701651064, 11369151065084080884, 9493662847124813178, 14299126668179023903, 2451525064998641745, 16055696673728703463, 7600736037142850105,
+		3331094657189179723, 8579232659787725167, 11007434086335446933, 7488529659250917009, 17217317841029490639, 7202184784979805220, 10955913831459448069, 9000508720500651545,
+		12966352809478736412, 9643078159289928329, 1577471789984999485, 3065864601417367655, 13683627106599504109, 12782093364215596525, 12883456287502344466, 384144415368165580,
+		2010495664660209855, 15520744321638216967, 5385447087428594566, 12897496516555487055, 7343279016502952747, 11323820480524965410, 3414484402519450292, 2497721392671865580,
+		16065061175628739123, 13981641072236579791, 6942197664821630380, 1667302033233547783, 11254994815452647404, 5265777633437443003, 1242523090981771320, 11333562630675377559,
+		13967113064180443992, 10679621597408504672, 16223869620849920309, 8813286726524283182, 2000697484240530777, 5417120625530117302, 12109041278382745291, 13257693171778388584,
+		11737174095432286870, 13459661128718998448, 4655386724404378836, 3119616752887818891, 13324285182058113375, 1078137740985006431, 1610820303976884986, 10433300853468291587,
+		13552049979590080822, 4379357932546858489, 7594644709024650108, 7268811721525297059, 6728671136192921869, 8183021491392757516, 6569378188404015319, 6481294988812800823,
+		6071501855022377789, 3805172128285889052, 6802689634429908933, 11713310861536728752, 18291420299754708339, 7582277238191809023, 6183429490206797252, 10452668103640934631,
+		16083971675285095468, 2965035896159234764, 9379493912871845724, 13109394112987303523, 231416620515766991, 630445729708227114, 10015412267172773636, 18104521419340860951,
+		13169770634232644390, 12462964563528956096, 2689434882719314440, 5936289129999384022, 17773436345927091892, 2631892834965929605, 8167719122803587721, 2458223071457452931,
+		10744932251818515465, 13367480890778627284, 15909410072235544918, 9252559547875570290, 16355895225285344183, 5115003811789024567, 7369371640924666845, 4586532908333332092,
+		15999516281080615520, 10972478396135936147, 9002100275598932738, 9043399249857967875, 4975188939801806064, 14240375126510021504, 4497218436093285729, 899858725260616391,
+		4788026362409273347, 8940774760122210910, 66616358927988247, 13054723206705508289, 6256911511259454580, 589353691478007084, 17831732841616807303, 10847300659030294141,
+		3016120727980669767, 340560476433708073, 10516500208515875331, 14933811541787518485, 9941997565508314935, 9752941942651093949, 1928238223054143159, 16147782066840428568,
+		8953947187833770878, 6627103431982157573, 1279114735725952920, 5378128106441279737, 15447712974588571571, 10552843735673449739, 14956126644414569830, 1994513099978508850,
+		3339871688614476269, 2937156932445032796, 2071344655111136329, 509603454456841298, 10929109734329673813, 4531629375826317764, 1802431569220697099, 7971315018970882891,
+	},
+	{
+		4307546666223047416, 13914498777427309061, 6812156124789414732, 1680174913762530491, 6756325174405757110, 2535144759174364990, 11263393915003278429, 14767595249676286403,
+		6981289090623415465, 8930069945493884157, 8223216504978132408, 796477795300774057, 3120155459209743472, 14825603392456550470, 3711879425019804830, 11041054473536223927,
+		14135544350792474553, 6171419888118563156, 12495035851387242130, 2843310747449412555, 5668766087526340552, 10117858698838396246, 5181027414039980750, 13247490124270426,
+		10847249691051757241, 13332329214721571156, 12457628412284474075, 17044657510482764070, 5218221397478351943, 6922630493693541156, 6207927102810766143, 5644846665334649748,
+		3169200533952511826, 13123046990387029463, 10303462306703730135, 3315008874027436174, 12427067008037332041, 13190195608614554888, 11930408619792340463, 12881268563913740396,
+		6700154625941523096, 796110091507466427, 5388163944686450548, 3113104467109529928, 12930558649635882086, 7536049463980825715, 11851825635055645132, 2654888532632283214,
+		17530163750522835336, 9722612350417778827, 13244522480616169491, 13740964907388846002, 793235549667461791, 1998252773625399730, 9697911491069876538, 3365596945186794622,
+		6506371904134856034, 9541373683805144018, 3149037850125132851, 7111810601994573897, 16732445693192247884, 4994069681898274622, 7223719243730104348, 5649174084086150712,
+		4640203560336739679, 9900565149463137003, 1093715346388527458, 17169722430093991108, 14911871124664548213, 8091096017016862097, 2911569128494944136, 10192934055727569503,
+		13251895658744991883, 18083873142202267221, 8241707078409323349, 5240943892375002838, 7329419846032881810, 17784005510850539551, 14034072243705748841, 10459194866755836024,
+		16396304393792022741, 510358226971662693, 2002127643935690257, 14681425695950046262, 481902649451190280, 1717807040845239061, 3358903321435525144, 12361252150277163759,
+		16562962997045986629, 1977585352264948582, 15588655103333244279, 253344970359156714, 12939363813291366775, 12548224526376199974, 14450582788883748364, 5869541533939881460,
+		15346378007864735078, 9904337403373774864, 17933855382993937953, 9391248304932723816, 2250334275383247202, 5978804056136420670, 1528238852592364099, 6491566547950141733,
+		8439860020828526478, 8674532462170555517, 13889716766953024111, 1166696901054897271, 3599113965286446905, 3276801695553601157, 6631284861504552600, 757022358659145685,
+		1117291222568805017, 7148845117809308441, 4044258438241699262, 16593433123496068718, 13992202310165134218, 2998204381658279116, 11137382784909083266, 11972581616612094469,
+		13970586842647892965, 3680317572634289692, 3416494470839852757, 8341497967750607131, 5522860734580749818, 6847292760525096386, 9317394708872196559, 8522252330730808934,
+		7951036477225560362, 3718789111033607646, 11667291286820266731, 6927579620295878614, 6796746225018555970, 2070061401518338268, 2452626412419851405, 6130352643925327785,
+		128317967134069640, 18241952544586374251, 10689311587315723515, 16537482248073764435, 15914436258832414511, 15518344078557945167, 15883120902045970449, 16251109112716994957,
+		11957637677355945602, 8965882791601648704, 9390723380463051523, 15025038333096274711, 14983844148312808973, 14488574793452236487, 15795526425513195718, 11651978879566144360,
+		6838341670149165895, 12326189699069923388, 9258908232339348843, 17297038041466207989, 5242182985453021593, 9648294165629935142, 9715128265517308395, 2662662536493743894,
+		11289660454922592938, 470300170724369955, 4571871646010841181, 8724229358245178735, 10173959190953118810, 3611286966550223594, 10810806064515103403, 13571898391208639897,
+		6782514579206442308, 893150666351200058, 2099535232722538223, 300696716419619813, 4778737709473194628, 16786610674618434170, 1751624209281870237, 1677055321500839173,
+		8950755642341912951, 1974922263791844623, 5333377426024439800, 13909803085973342843, 7639604505882407937, 16195074617613125552, 8954461446680048430, 6823359994465290754,
+		6790869670806738567, 4499989093713728199, 17496748050437205626, 7194829324969293638, 18432532588985091708, 12041300075343806904, 7788543067151959941, 13703334460383638224,
+		15088053026772564466, 18172984562199594382, 3119317310593433742, 13835498717175822656, 10015747176747842576, 11008571041665092033, 9377877781626879674, 10465443099481589185,
+		8933481722931715231, 10811948483433850165, 16314247813274714890, 503147444786527544, 2533443680646505069, 7617720894972668760, 12477410920355308950, 422423516920457876,
+		1501843276089632258, 18180777013307233967, 2535426997299341256, 5318958493284100856, 16758265544916918856, 8118598628492446123, 2511013049335776232, 11181447982017705826,
+		5996381448168274884, 8108757135223610234, 8067369725584584297, 7184925262427750366, 8199341143188441284, 13031376443169557016, 16036606349050125404, 11958720833222295864,
+		15336831835795822898, 6806921200736832713, 5959923980569572002, 16835674225684329982, 9985579070716031367, 6517360043741716503, 16609518082836868591, 15878184747124924573,
+		4786224758360153905, 10283234398763800487, 13695837902615591472, 7260571034197533442, 9225062953237806971, 5969706575516748564, 6537573986766117532, 15754484267739133126,
+		5004791824134844360, 4971286291135250424, 1811371968353107289, 15772458387007519716, 17381493577383518445, 14326903440006940586, 14237922492359728234, 6234116464684325431,
+		9293668142017263584, 17134656749295164870, 5879480323258506465, 4788695233340705697, 17809277710857366810, 15157733645094688870, 14143869691462709080, 3162286338158090229,
+	},
+	{
+		4471613312912718060, 13601785177495103328, 8083849806888905297, 9053545412554844461, 1876605639999952155, 6124537911475118673, 16877891074567085688, 16541720065079132344,
+		18138305348849897995, 11498878557125400853, 14125346336359365201, 11991638807788804369, 13935355764550912568, 16209147067155729660, 11086190285777019292, 16727288863943596410,
+		8873152377611229668, 6260821826956744083, 11489383533808918262, 6585112195310961861, 7365821041919648819, 1936165695028211587, 16164747634991415711, 17957320776652490392,
+		13065030057172289846, 7278765836407486850, 383827150208081081, 7832055893191054601, 5249323286889945617, 1631661912887095912, 4431088469837785451, 2866263172993336891,
+		6140213328062333551, 16704025329777067037, 5839832043209342792, 9196354634862869885, 2735762290983671190, 5323501742548818139, 3199127466610501482, 6719610946615763192,
+		4032564124345275293, 240208626666701335, 10264845378648897042, 15608289126091352415, 17866864241918154829, 6207477318890336372, 491708931325462670, 7002400618323099260,
+		11507747783030541234, 13683043390668171754, 9924966309328785763, 5549516466627385909, 3724001483041449858, 2408778220985427590, 10510707601023430105, 12862520912519186496,
+		5012372868660694231, 12033652755433827667, 5960732801180177919, 6089487525155575261, 18400192045204062277, 12754175136438960528, 6170965736016609163, 10141374482047067946,
+		11781193922347227447, 16937876011211881637, 2982972111293427964, 1728244726890919596, 3327997232304084768, 4754833121145407334, 5871027825507908591, 15772493911709624273,
+		5862944033912881884, 11132730978666088350, 12167180155548291888, 16449838286695349787, 14399676610730016345, 17071083123672650337, 13727728787831175379, 7507765123422748291,
+		4883057314704644529, 6606742732149784343, 16070555141087563722, 8408294891669305261, 4298316003054547788, 1573237855902568238, 5357176885445018289, 5855732582172939202,
+		11721126538980357625, 7216004194033429913, 12765889884935948315, 6003399149613653734, 4571046290325663920, 15023470461830485075, 11463513436288928362, 16135217522406374542,
+		14300855104129153291, 11491527690078786162, 5674183453812271017, 5044682546652747711, 9153978680942338831, 400454762074409409, 12351470849648616331, 10559229320903248832,
+		11839166519633311143, 16489041153719856002, 4820713204385149226, 13768001962143023630, 13107713406478328396, 15471245828032402460, 6733652296473831544, 7665657127090105428,
+		6114372925011600760, 13061069979571997963, 12156991017966837826, 12403009591138383583, 5761958709898299258, 1907771304051897263, 3007439379929412593, 18410854883912163962,
+		14408045416865494124, 2442199381796557002, 10475326303775862953, 13637445125954159957, 3778313603630758744, 9247460369874272772, 17572237597883145087, 11338350096360776602,
+		16486104352829691584, 11856560607954368882, 7574789609701925021, 12240083183242127118, 9872957337376856275, 11508929285199799229, 12084460294902152451, 5537978390111837838,
+		17987471707896681874, 13038244305326284081, 6130570860032709721, 13697749322780057427, 15250226813583295859, 11214437899623632196, 11227424166765094355, 16073863048822462466,
+		12399110995748365941, 8259021120978314016, 13249466772279340115, 11201772702582865107, 6680428295197296613, 14825065014187212998, 11638499193934854444, 13944483483619391536,
+		12792956896156056673, 17521293339475028823, 5738513258925006248, 7070317930523546296, 11175557000762820214, 15356683721815441509, 3038847573301969409, 3712495274059632476,
+		9703339902904468931, 6903532388259237787, 6598718994389707957, 3524767540333384210, 17230409287786477986, 398508689507908728, 12956323124513250470, 3050411724956364887,
+		9936181795041159997, 16502578966693139346, 12331385558134766329, 16368402633574222539, 17549179704234998175, 16732353056786161257, 7018642409136068141, 13907639522324102590,
+		3202436334590923936, 10521323531132496064, 17087322194145514933, 2557934785422493682, 1054672647095378624, 13197226692868722325, 1089249862965154915, 6479925079582112772,
+		3880905381896902231, 16702686708922296685, 9815623322445801304, 3275100382267252573, 6882533095211022198, 11000715667767797665, 17615808190378608947, 7418883369171949489,
+		15109802007060416273, 6172716471862133951, 10675428021956965140, 5719399515177959211, 13414568332401128475, 15437234656470291881, 15174397947571718085, 15093134682110367825,
+		12767354263003560893, 9423701226679222965, 15980976879563466685, 16370172902785037004, 8843543841582241065, 16817827501960591898, 1524531339915785994, 11624580276885598157,
+		17147068462804570503, 413038056092618151, 5178874804057490245, 6267545065511948977, 17573054445714024932, 7120476833739422223, 5707115123830922617, 10971108972695387841,
+		12546478152711337402, 3213958910433616233, 1066524299473173792, 6276669942370566610, 14816818963020520773, 7372806616674468946, 12220278123497641030, 4953625488417522128,
+		9443607421568920607, 2583030461169574647, 9900905053299561307, 15892418329702922907, 1184158607153919924, 17842123060489837980, 2681791639846598155, 14394984710894548047,
+		17363678829105605076, 3907856148144141388, 7535915338133892356, 4354053943074081189, 9644954727645503986, 6816908226661921388, 15867806610099035654, 13874346146744695721,
+		2654416582410062512, 9232324386948815478, 13864516581612906345, 17132638924861000235, 16875312639179645137, 11536057026563830119, 1090137303802556590, 15667188983774010898,
+		4336697789732072031, 16054848662858822197, 17934449813415035557, 14518380622432694666, 14100582434152190048, 6262866632984449325, 18069160441815400774, 9798342103009260692,
+	},
+	{
+		687104890149081183, 1938816743979859301, 11342071981175913904, 4270322127259097184, 4964776270155503160, 17849333582861534767, 15814479527332819692, 8083943565773123408,
+		3986890035154628803, 15316660330065019741, 11560940574529263780, 12576851520091035878, 10883944418224886092, 9908329441525486205, 11238684990962507809, 12900626758810151662,
+		4077800412543228484, 7173833470188867493, 4604439809988262876, 8090706047559948234, 6117166546062912279, 15748537214854486946, 16719594636199001564, 563850925691991999,
+		7109145612337154341, 10502845970727626855, 6527587047878193251, 7049690136888681718, 16750703006415156202, 2559311261501721445, 1222802194566919230, 18019462938525560766,
+		322982839910423931, 2590270731903609206, 14012397059804449007, 4254569016772908483, 8508420263334539908, 9175848619353159735, 9777676085150569067, 51565612432741329,
+		10233009747926770582, 4858065366607044068, 17837971428933010861, 10016544790726166742, 15260359301638740999, 5101999662344938158, 8809855615759524306, 15369468763003019252,
+		4549989329927399868, 4866130696079291940, 2784467031729859937, 12617898982021887868, 2721301974598150044, 1014232218549205942, 5446756626431953863, 7315134179045561903,
+		2592184418896595488, 1723751460114310463, 11198512454461769811, 6203707848404803677, 2601731234271436477, 18186700975610533226, 4757569424831899615, 13359873383138312209,
+		7339520839328992093, 3349084091338116256, 16532710170417471614, 4425958052714174548, 16833748535746803845, 12665172019028452441, 11274971974705134171, 6504206221872290467,
+		17921256304121537300, 16573867650874642543, 18439217559900658467, 2917797231317530012, 2415475159165597656, 2027542924210178369, 13542535558170959524, 9428931592662127870,
+		17821420552135083528, 332847653840014838, 11832506312426064436, 8314663852639826188, 5744960486691350299, 8069724388577179929, 7949740770152910898, 7431049632429535950,
+		13904640252203718708, 10747313134117021792, 14667070697514384141, 2600977347774743546, 15498986940124021079, 14740645313274577011, 17403811028932224808, 8060102076475954685,
+		3517334016249952489, 10826317205305313746, 9664766330892822745, 4145357045596983962, 123566849370572650, 6452080295201963409, 15558941970553263818, 1191650177320171029,
+		13303794914626036653, 12135860919529132656, 3620217653879289461, 5443663950311568399, 9020744500355505374, 11953955628401776228, 2101814526784564259, 18218598416910848525,
+		306945432061418036, 3150552227215797902, 12928374347433953916, 13299101042862573370, 13702883318367407795, 4879985767563062391, 17591048490944890593, 5088664549487213106,
+		12990649636107730851, 13002224935892458030, 4380799638612122791, 7935443787987894924, 10438069978940053126, 302419699431148366, 551508078777729872, 366155636877501719,
+		1657628676376133571, 11398060401420699070, 15376723048512638551, 9875623386041366116, 9978954704196888739, 13768323245406799962, 3568095027938899541, 11120740210192996096,
+		15561317952331530901, 10479759083279078649, 16536004935523752634, 2928518661531554130, 736056663469575928, 6131440330717529370, 11275149343392851570, 9601030074480228347,
+		2397968519718544666, 7793046606567840651, 8971792946996316712, 16581860514259510747, 9067804351225143661, 12322425857061932421, 10680196669251962457, 7226521395530060461,
+		14734735764746786753, 1378251478826083755, 13509550209468602124, 14458158239096821346, 5681313138148713219, 9054039627425609375, 4235536482830620712, 1502753755874778370,
+		10053374816829223121, 5956370573575798562, 6842782625116195714, 6646143553705917790, 10487617951080656190, 3930886288654953669, 13141858447548326172, 6966039733711006320,
+		3565931266726110263, 10142260659118036168, 18315406451571961983, 16857333990691080595, 6889519058362658033, 11812045051361479600, 12503117299646153207, 7223531498406875484,
+		15243128568488310595, 13798032762330794140, 4456440673105474920, 17896260893739107970, 5519537045179649847, 11908888770632658821, 5444504459295913107, 5588728973482930155,
+		8914021876030553161, 9071747156187788379, 14974736924255494885, 17070198435868341999, 3643991391224035758, 260637732328275649, 17609644917816078225, 2302996326941944665,
+		1293835161492069734, 5795029109259991590, 6978986253519330084, 10360755458408067486, 9467742127861782141, 9197981630801498774, 6297600026339958279, 1375635441408481019,
+		16875086338187280639, 18188722331528885957, 2047282716697647836, 17808297209051779725, 4756860180475663362, 16103863616340614471, 4416311024167936572, 6340715229216403079,
+		14261984008515151673, 8778722476581699445, 1624620854396291363, 8490568310899028272, 6147263592092458803, 3717414274397202281, 3449154725620836174, 13526832985450537957,
+		5888744936142942064, 17277140802638358763, 10290028650289820825, 1940657436863195045, 10796401239257150661, 7788083050548605852, 13474393003015663489, 8961936186303685357,
+		81364364291228199, 11636155122637141142, 927710893705810893, 1403208391464987879, 4332234662194589819, 7913319387647351094, 2589089673930123808, 5387282875974124558,
+		10611669207938469024, 4491327257859270050, 14129391883837344111, 13924810848449766461, 8792187899775727862, 15048142623570073200, 3933861866144269656, 1162055633060412126,
+		6883724061714130987, 10416279294253729103, 12247033224345499651, 10291073256885105234, 4480789666471481188, 6022169887991948086, 3778647272347441051, 9527380466585130391,
+		16407225233842256953, 13423683834633513951, 17454464203550700633, 6033758555290610449, 5063673994339442907, 12250392784929419939, 5954485814444410119, 10099095370725442279,
+	},
+	{
+		7669790431656261769, 2776517632462593286, 11694025667665633506, 9533794089008895277, 2895611631120558023, 11551410655448788956, 10026541900772270925, 6243136875017000843,
+		9434484992529186384, 16435748047660609525, 16190660694150989986, 7083965852434071085, 4216306437741910756, 2698742177539497614, 5199793642504009017, 17298424769819019160,
+		4041169394784902550, 5699517344009382913, 5306272267462320559, 15846674482556330025, 2606351264228884283, 4162585980422107281, 3715151019132039005, 6607223447043258693,
+		8168579295855409503, 16727569921530031841, 6182114460261837773, 8940603165471931374, 6081572078077526926, 5890840443923124563, 11215305828294759727, 2875117534361804712,
+		9045974983664041829, 905036705033699463, 6962033946652121779, 3027264198782618401, 13786415307358010100, 3643342525745067473, 13641958783381681886, 15675065537779359584,
+		7507377696839752642, 1061259379811757443, 10276590160392917813, 6889137095037822679, 16373913505782725550, 12287733095803524526, 5695917172259210496, 6360958736925918808,
+		7459854586357006968, 702429387211615855, 8231296036461604410, 628323703857882004, 1059802628602873385, 12517208225099517507, 2368172548334856593, 4792344750094708709,
+		18352334786472886037, 7096021570596476676, 17045407505128867173, 2467670847537319400, 2225663888244226889, 1876713214939672742, 5329943993157142620, 12168650975912182188,
+		6639850268372381409, 2284514769224558945, 15390110317831975716, 13933785559694229008, 12787641603764341997, 793886210532292741, 3222136169196008839, 11104892506868626444,
+		12660547967989039787, 2109392063597767300, 9889743271997754037, 11803327596624324036, 6940409327849314286, 1466399127363116843, 2572333022681966275, 4216097356402537802,
+		16858757460581672909, 5838407119753001493, 4453405435911954669, 2828665451507432751, 13657966632733241760, 6875986784381874300, 2390233934255482553, 17386653779125555159,
+		2976756344404126744, 17032556609402836559, 16348907464011574182, 2196781021202618892, 8270822867494340805, 4738372358350764889, 6088256422707334932, 17121369334507507505,
+		2081729301541563384, 5577186154173396778, 1865152567701500436, 1422284589642218069, 2489023909725140903, 276494395149046869, 17420927169263487236, 8292343688801608074,
+		7819174654675104600, 12778055482430336726, 14615848543490171611, 17498415175263742825, 4785899184222234034, 5227136636239697699, 1570704808469050246, 2858953380860123257,
+		4323577007857413306, 10524228743339400397, 5418808897687027557, 5939367271366264075, 3569359126353670574, 12961495213964770607, 8906990808988099905, 261084295374207271,
+		13937553904380032591, 9165760362893872288, 14159606902675650669, 7794101517494576908, 11994596892880464164, 16211278212275417034, 1568324133241165712, 6579463633356173526,
+		3784436423124943604, 14504130598322564217, 13343318845201913758, 2617267381187565844, 10063945174501910869, 8584806992850354016, 17494557973113338328, 16987450461117846543,
+		3191556545349441897, 4780077336463115599, 102121356289129288, 18353108394754479957, 10099934050411322327, 10323433488737585897, 1480832277301232858, 8304664509429164326,
+		16494820005379860880, 1719281141269927630, 2983529566257876158, 15928721259545722550, 3714203000118655889, 15922105900709017310, 17662263539397115758, 1577461381995722723,
+		3426958921435818822, 395886748655323570, 280632942609884625, 4361473570148050146, 6600885194277340683, 16668323952296831943, 10057749804882861513, 5701592287343868424,
+		6951585494335471689, 15680855848517030170, 9776921814538436791, 17640230976984644473, 5777838393869379647, 2176689364164694052, 10884627395386092313, 17656310368333301757,
+		215205608065278414, 15361057989137229644, 6756215047166430628, 12215084297877052825, 7185815532109454500, 3394755837885079236, 1778980761557523977, 1861969072415300655,
+		1535235777601157298, 8875662482214652105, 15404846185148709157, 6538418983879634448, 8341745508628160868, 7582603669233291629, 13003716464169800826, 13309194956036155778,
+		4791947847339351337, 15204996809755844932, 11672964318683763318, 13067259871945801803, 2139419248113049376, 18195694858089271989, 7208559250123396675, 4671149208567820584,
+		7276586425415793787, 14549539461274532692, 7381249250982432115, 3215735370879771405, 9197833835152018601, 17236122023193655371, 5029275100388702506, 10829687080866991082,
+		15533362570521057331, 6942829144635570952, 9572990445468151820, 6294042535380467396, 9052929167426522790, 18293430694900525497, 9076155092724374912, 6410242671697688127,
+		16930844972313552415, 9009509357611549679, 10722442939705348974, 4686888495512108749, 6326319203058274828, 2590592779822711917, 12876493112068819735, 12372064322375408146,
+		11938822647496400962, 15333527667419199710, 2385985954862343680, 14776415112244140169, 12817753724474105460, 5129368568396757194, 607898027127847045, 3917240453172744497,
+		47211231428738650, 9333275559955619158, 7534434473427098199, 8557232404317963052, 11597011861056629671, 15926835677212702441, 17943276685960195536, 2513989430679125485,
+		2903417389682946131, 15905578940823611094, 4910425097773753648, 10817415382143821768, 16356392378927186116, 1174713154793914656, 9176413825070952738, 17779105524945038711,
+		18302140065591767046, 6334261306636966429, 4203057092695998640, 2740754645452686340, 10020911575632378009, 5906713384548665207, 13902791548718280892, 2505591245136304093,
+		369660229032730089, 11851915833529805698, 13485269529443969890, 1270120511649175022, 9128783725626301238, 6173048611666804214, 14151404531169195672, 18241008099921643437,
+	},
+	{
+		16226789363155700046, 13734705589524056856, 9629995513492843231, 2636144377026081617, 1233405076007260313, 2119672919365858964, 4932766292290315579, 4185117177904214366,
+		16996170392430604056, 2476294162951949891, 6677439492116109133, 1649550562276235959, 7307278264575968221, 17128676264244010843, 9768062299436691373, 3825325732056225433,
+		5861627228365499618, 5011684805137210454, 1579621475012951778, 11535371650014354624, 12847902922833318241, 4997014846790385136, 9875988184618650628, 13094082946822736823,
+		17224650011872599657, 11430188086182976152, 12892063618843720029, 5912993124689510433, 7069617917494051681, 1298012103142698333, 7943359430865057535, 9329776843721719539,
+		9091412025380293893, 8622355764644651307, 8718353412518918238, 12338548766610785709, 5241721208413391572, 6315749100915178625, 17919741546105181107, 13677847475856526539,
+		17388254638056933809, 5422523708003180288, 16851423629233109043, 5504298365310420423, 15145549220326540137, 5184279399795985462, 2201159255780420815, 12506121988996036804,
+		4460258780042860751, 1816027820333214126, 7778555198679811350, 8155451943744426012, 18392325810806023014, 3955295139981696248, 17141295608995204052, 14206938573418983337,
+		9464085603669036454, 7848014338005901108, 2368914226155404065, 11578416111848517850, 6323647866244499941, 14399589996703947996, 2824522520842155768, 391310842153371124,
+		17489550078249576530, 13418700716683405568, 8265132837103985034, 8386855948619700037, 4642739669076635265, 1941217860224507563, 7402267177254210690, 9863923110146355168,
+		6176679707488254741, 4307819088229734202, 7082712522654871200, 14603822721598353371, 4115674343542702663, 4132348830250348245, 5992042367418590636, 15937819366199058986,
+		11008669567537833607, 14841150752801539889, 5253470025479549456, 5665837575328478629, 4601810548582757669, 6173003636576141170, 6899193615399367692, 968231402917393055,
+		9948650801233133770, 5836115460383443197, 11404170696974449207, 4791020823967734476, 423024247809958592, 11251668387880260801, 5562546584223492723, 578572156618131794,
+		13456676488167240303, 17121749146829956377, 17370555398500311209, 5041791432274350681, 4009412063225388868, 2407629981571159579, 13052555280728877038, 11483117063845312302,
+		13421089948800544371, 5001604265596626568, 15312985179876036482, 16032805766802337150, 12508684642650694186, 10422897636519090240, 3970071218688010847, 17419166239676042564,
+		400453640980208069, 15220637399286523210, 17321057148174216619, 14860227640908306879, 8047994708253288483, 10174040071518845057, 3280567772472213687, 5651529697807929627,
+		13988854693674964723, 10817154032069031941, 3171651998645961547, 5518712225783687705, 14706905091132091970, 13960758460934966876, 12141035142079693145, 3149939820435101269,
+		17047631647660916802, 11327141967045825261, 6773994317182166280, 5064726840218426586, 11921340002806613391, 9067034595359929709, 16499225867422892436, 9333282251383805811,
+		16851791401266483516, 3629537449474963381, 9616439067014312078, 17691280261538133313, 13915291913519800282, 4229243823856128517, 5998682815524220834, 18293451622818510596,
+		13740317056016164038, 15410121987858832401, 12080671504470100936, 11635316325777860129, 2584464163154495637, 9849046399519426256, 7991103215010751716, 2109987257001640948,
+		2505301881938098126, 9962323478923652140, 9312199523950444342, 12957822502673689705, 8060810607849163143, 737408553843844193, 8143568733429881786, 18003168270780769476,
+		18361695650419575705, 15964191128341330249, 14834821085064012697, 12512940671502931238, 11592194993753547188, 14358438239394059598, 2876909840522954216, 13154864917311376528,
+		1919485747906370662, 5250174270363591951, 6270889482486194520, 726576673961648732, 5067680336545953003, 3152041783219682891, 15674051618916413369, 12438966377512424334,
+		7755405178378312585, 2001220826274540277, 13276328134279740680, 5464764824709243977, 5374818714652367118, 7988129049563289676, 13996688354532099099, 14091540329663446637,
+		4460927228453411137, 16058422703785787527, 8016770980039986075, 11450941100964860520, 2742597710491507274, 16940752978671801273, 5897441526901650840, 5926672707007682446,
+		11513132526446047688, 2371334524276946445, 2461552185903242316, 2195417192784351355, 8821293936856062699, 17392142102281287994, 4066797133115509650, 10704373174879556404,
+		15778536817306082589, 5755579035239870289, 2105368957367433938, 16043807797277162048, 14990960263520315004, 15618512283659189876, 1020703273079622517, 9735594589053383212,
+		11529096471626785524, 13217557548494128192, 6973227637542883184, 17901194406865837244, 2414269359614891938, 9165268075797348071, 1013041849562373861, 17525420894350269712,
+		5772778048593061508, 15424756817708323928, 11842041259277183807, 17669952685051160523, 5405007811515938363, 4415223809135251038, 2223192286456742546, 15742105795795272774,
+		2844957165101842208, 5188198001787563362, 17071130520794983821, 6691797472842348899, 4294126956896299534, 5788827614077663481, 16267876196920424765, 10795461545625002360,
+		4405006158507706423, 8343317561528812223, 7851955346465616798, 14568481075913348758, 4391527082463073614, 13997921112025001396, 15259963045788570485, 6787776208020191083,
+		4002627348223514978, 16231148554725644698, 9578235186329928114, 14741034641204805809, 14651073646349829984, 1797163177099497214, 982043220105120238, 9027434646723092211,
+		11809342655313500273, 16822704101813284237, 13097372075606737923, 5463281428453250615, 11967866991673525562, 6828790575157689223, 12568831962097805646, 8385980093725157349,
+	},
+	{
+		9246769514475702626, 5788284997389507365, 15857897362850327403, 13864676801095094218, 12881526722328523267, 2620841421323221200, 12599981775316397124, 12820989846844560040,
+		13066648645100247757, 16727492115601921665, 15749471761440498106, 937594351871983779, 8381111811209734349, 10884357918725639691, 781591570669492079, 12778743765298428266,
+		1797915488494232282, 17274756142259274463, 14207994319179101777, 9405903752538915237, 9001743317941152797, 15048752608061590843, 4925745663463425863, 17143694017177138485,
+		11613437975225156304, 8619196433402562266, 11907033287998837424, 5056904365610561965, 7637552956459333558, 2827449950719061527, 9998507085256853501, 9238562885525900325,
+		13246436769495027717, 5445015753017977819, 16266739009580878036, 15566606095998238977, 12196078605380432771, 4854324313875295137, 10974170498288217052, 6425550765546527417,
+		14574824159194628650, 16992289415800830701, 3499062703303067574, 11220872042664151226, 18135860701984580530, 13630928571014923388, 2913126838766947469, 15869180955632349704,
+		10621010745328025245, 14637275395423748577, 12928463178963493980, 3270672471462681194, 11765440832075775157, 8138439106739837848, 10004644076263261924, 12582897670868871780,
+		9605391611675301152, 14014632424042523224, 4638465078692570733, 3013469722048440965, 10972600060210514686, 4497572559400894366, 2652629676209366276, 15827846806499715082,
+		216774559418075105, 7056732230404238374, 4342481467357759950, 16143194646968227790, 12304857685680249595, 5021239809847286634, 745754913624924064, 1603290801266214539,
+		2784418922013631805, 3554650219010546629, 8896448905401216908, 13445015286698819482, 6508982623352460996, 3322529327934132311, 18417788670080975365, 17554108945303789353,
+		17620122226715347133, 9738429733440215024, 15577771434516492888, 12422193389576942718, 18383756008252443605, 12736926759685644351, 16981429110294392086, 11999528928951986433,
+		14489177617081844909, 15995916840320959685, 6361381313838994395, 11146176143708648759, 17190512001934479207, 8406914945663974955, 18073221191428103088, 14075266763636071788,
+		11493260321718935244, 7134447477334726345, 10489281872281557152, 6145540581503915475, 4002857892747271740, 5167943945955725680, 2892864850826359384, 16887114279977647596,
+		16493058314197913501, 14642843949567816202, 8421201635021034279, 3645913604138483317, 6127272877310948153, 3660286308390076870, 14343325047340052700, 5355450922054278073,
+		8426383571761073988, 17627146217941553397, 7396223609641674418, 2402241526082789613, 4067059813672963823, 10306840429023537942, 18342506396531908477, 7249869764848707701,
+		17055119974261943875, 6266720893662254540, 13102139953381148874, 5249314164321788611, 7157525732140787612, 15381277459195914226, 17265025258266710353, 17573500432599548120,
+		11703325491493519624, 6756922948215553472, 10849241105791329449, 4442124988071574400, 13193138084274485850, 11408181130174894537, 16602978650637017500, 4282478513876287613,
+		15849352004835856215, 7022332658299393045, 2753527422472509447, 2508636546397160815, 18156018186852519542, 13445036260276495365, 6279372959444826452, 4487789154840943220,
+		6912674041294744283, 18177825269025993506, 2129493844567951509, 6833453501368177831, 1878514166200306112, 12873954541639117785, 7984716702294892278, 1590286870058148425,
+		13310953099825480439, 942949035351116482, 7073926138905956784, 7700580694019269362, 3135382872993338421, 14860196563555722941, 10662854588851556233, 5736680857908686906,
+		3285730769783013255, 5648284582450022694, 16712547815126338303, 16508335566005209527, 12272617736405465053, 6690178916455692547, 3481505327914964440, 9148348679521508925,
+		5445751308732564169, 15671537507319596886, 17721221564106627243, 379590599139121791, 11923849517192812255, 11794879354344258105, 4802202540817083733, 9502952511912834734,
+		10387170863530151921, 5325952605083195756, 9255511257002170523, 413412942592261158, 2693041233704004652, 14135620291598275670, 11595337134421837671, 1965085859594934829,
+		10567751951694288416, 10466024270444644770, 17138727632883910786, 12652567654757797118, 13864111438265559205, 2552332838857882141, 3739570066357761968, 1439381288436968019,
+		14926469836092482784, 1974273958550553776, 10770915481273902280, 4033929759715842024, 15461883773070197251, 5631323369668498153, 13319268013678629907, 16483196656661792008,
+		5825598074470439590, 15514383036808278765, 836600073173284669, 17006029483641514808, 2253041172677940136, 10109282146738215012, 2050330973627959134, 13783991480192211446,
+		7361422649689322835, 16012782899552425604, 10324124765039044621, 12319908523309013390, 17065808121376215422, 14844145564675640794, 2754581529304803758, 1149534055082731343,
+		5371192675994106473, 15892724499541682278, 3862864290653799361, 15759456296270265029, 12018492462347307225, 11503979417352537931, 1894695486127847219, 15184833349947874986,
+		14711143160318482298, 15515618319260581947, 10015362293284733112, 1169298538214120845, 14481541537099551545, 10304547737174682912, 9351439436434829996, 15807708290724844107,
+		16946643895530263911, 6110142153011856496, 6857516759047242219, 2026267735072107620, 10338469980804248611, 8224240981205716101, 12739986350836865860, 6828408496869642385,
+		18199296108774357398, 10154672256889745380, 1190269705881674139, 2317654455984851716, 6948704988682993246, 7864433505284017226, 12371653445644439372, 16432795124971446509,
+		940679263188661008, 14653357165718140350, 15439920797347843673, 9415587255510557494, 18115037054677722678, 8165849408798239027, 17369387099667572407, 17619066457126678815,
+	},
+	{
+		11047138821675365077, 8918121441180891972, 26692501222219426, 15248413052700323978, 7305399157133896461, 7065644238942265367, 3949166834387057064, 14178248206708015607,
+		69860179712677448, 15464996655458230480, 15095351218136595554, 3792171085643513009, 3187131848664503636, 12713332789590787064, 6278731049699775392, 1597379696359884724,
+		3952205381894147962, 11371446109407143937, 7231851263356642380, 11612512368538303138, 5227214975837085115, 10737565048439707166, 6333629542995218640, 12386725921557807638,
+		3631886121917081375, 14286411187847401959, 1546298555066841633, 4790996540037176549, 9541492152219486842, 12304868498960755609, 11426775785781090329, 10793898029125361155,
+		16970032026045908366, 4739834790205788500, 11604777595337607879, 7222013010088766249, 5472916641327283117, 4172262758310864960, 5724466588558015820, 1116300519629843659,
+		15795014995613238211, 14290583239597353888, 2490895887909073495, 11130992987297321872, 17554999787604367088, 3420129662095546057, 11472786435923282727, 16869713476687852227,
+		15035061229930585935, 453017670704522761, 13269498238801130975, 9381945743239523058, 2560842189862328725, 6461599464735341542, 12067824007347016987, 254830492191366350,
+		10932352970046201499, 5875690226460998551, 3699681560657289718, 8665743594825198441, 10232089728487302472, 15664572298733091969, 7267222702489958195, 10552093353886118696,
+		15492342672675114391, 415437554733257587, 12890781990283079094, 13204935186176658494, 16394061615709463286, 5115734945762570776, 10421418042968619739, 5523853293632283162,
+		11813086056645720947, 8830149648607040713, 12579056778157665738, 8379445845509747387, 11968812374998926933, 7579079245215672446, 18392522237039663466, 14209436550919930092,
+		10567400467353853420, 12039111362360014956, 9752698954159464580, 974455144078370581, 16749750902684349652, 7431880327875076520, 16572811640260132367, 197121614392940749,
+		4008236965647744142, 8547116629188387980, 13874587567755370880, 12696453513706541959, 10752386832421030566, 365775083075323708, 14295272684753058141, 11024897725724291722,
+		9389823976782902582, 12987864137510618346, 14351996708263571593, 9397276818616280108, 8943695845699072910, 16761881794918812428, 14395546039428720745, 9608138420173912436,
+		1876375509629583057, 3290820252719995988, 488255726920613097, 12524692306565281959, 1588481057230489293, 2737168321842385117, 3787136521155591587, 2297952115270241626,
+		14002797112021507101, 15941913959379016886, 13373428680779564378, 905956693320605119, 14911807685762669378, 13046351903511292109, 5010776430112230246, 13569296078340893444,
+		2399232949134869057, 16408469118941953277, 17229778225562184411, 15990256768949242309, 10694906341686584836, 2816242351659628719, 10794163145486835660, 15601904974333104002,
+		11025280186920123511, 2638544612389113264, 14138782464677956897, 8182901095979048555, 11304014986311338849, 5418181013691186545, 4702887342992202530, 10901371551431733592,
+		7470028071605003558, 15552389775050890646, 8285175978626575302, 11755261053723122966, 10951094485216236078, 5507384267235142469, 13239757172982680465, 16153920989213321821,
+		18058993449364903238, 13898361855323379776, 4830208064835445821, 2108287244297002782, 403367259355957679, 5208097191763320114, 5105753392567780820, 6874403921011777407,
+		1158521281204350113, 6232098057848694897, 12517518152351190341, 17852831094628421272, 11653774695260269881, 4420518556213490728, 13835371272800239099, 12119809446886544909,
+		13202632776652821767, 12444449950521044637, 11128589812117041029, 13640351754206364654, 12210309609173025143, 2998033188714623978, 2790558847086549679, 1412882974937756344,
+		8872627396983903111, 13010748252899511409, 9503554222158928531, 17266043773425260257, 14299273669130129568, 8206060595465248374, 2391269797717981426, 11490348680137544215,
+		5625434013536513462, 11006046905736534335, 12974260386406529669, 9092861657954444193, 9064784322822166467, 388172762639483312, 7975459140038679785, 16519143691087724914,
+		5143546864201185527, 6400878864024957342, 15513803558106064076, 6712861984922181478, 15623960351786428150, 3094277713920675576, 6184647748693682810, 7857605928718754519,
+		17306606255667524897, 5112741148301782470, 12807238528895999857, 15137864759480529337, 14604908573844046691, 17945466774813936069, 8840495514948749443, 11197321446299638637,
+		17220811598578674405, 4438480777123093236, 3563461541688367236, 3111403934731489046, 16319666149508644048, 11775149819643332554, 6467838040542164752, 1567553021477840718,
+		5384669083154912160, 17619132083131362037, 8938889855576647487, 9107335704092137106, 10077424566800668390, 15550874273916351174, 15171215175982142697, 15277375103802490853,
+		2219152199405421709, 5367881810186787185, 9606063680551349934, 18233690822105957780, 9941441403610160291, 14996958158691873775, 4936282940888570414, 16608409936766385729,
+		3344228690528365773, 14741103791830625697, 12105806333035047780, 4814603778329751458, 15692542571489717296, 4074467482166609769, 11583878004635312071, 15057041878895842153,
+		12046059187840675577, 1106267261822046486, 4800396230944794513, 6983782857932290361, 12630891077786998995, 18331269049237387531, 8843236455524152484, 8233277245902259517,
+		4072376012468301087, 15956856707868364136, 6651399164294705117, 9169559249495366525, 8774931051408681195, 7328702764302633441, 3821510551720221090, 13559321821383641691,
+		13270099407878039596, 11569032926557804346, 7759575992876193458, 8239088820951102451, 9633607727685959064, 9775909232917811341, 12297921731498614906, 14756100221590046549,
+	},
+	{
+		5228416958727036186, 12534300056259911378, 6859045937063682340, 16561718753727911412, 9427589074776024847, 4167904055656501509, 10156691045253563236, 17557096561606923049,
+		12847261474293104380, 15935635664155479706, 11956861064550631146, 11743590506948225647, 15973092866215748716, 8269726904881958353, 15639962392523441528, 15171417818360069012,
+		2605212343977737441, 18393471024186189813, 2302707671753008158, 8606549841034095192, 3842822953634987820, 3094721493917442423, 6408313759447502937, 13486364200254727287,
+		2191808101092881088, 128992526124656216, 738676021426139131, 10157323147642681558, 11221959943853120586, 18255489816550713347, 10885231659068427649, 12104397395119665023,
+		7707807226411417919, 16609863548699265350, 17639371636697428128, 8755472387723764172, 164779854477783265, 9714199241756765614, 3491355372893948450, 17683742455036967163,
+		13595758632462338296, 14515163666150177917, 6720823780841221770, 15071435664343609336, 9016075014492765983, 16881277609836316886, 6969993988115170067, 15419704786434737070,
+		14933348768149415725, 8499210770493553168, 6778840616148281272, 13282837866452012488, 12007326272174861053, 11172739862019218274, 15202495365302649711, 8797477675597086120,
+		17862558746132168231, 4941846130090682869, 17131557654945008226, 5312800819142473968, 5818269467205924209, 13458582047859447022, 2683428091382447153, 12956887954464730664,
+		11820752998821943867, 5623379642132478491, 11666807493120740820, 7241997274572162616, 17165010508995490690, 1769225877906480182, 3814296306467163522, 1913823003062817434,
+		11936813336110488997, 3878433838529606580, 6540053284493149566, 10610279324743393563, 14079852809920102066, 9176732841330794388, 14287311909822853963, 7146204303626670196,
+		1222343790928490335, 2199405396044383670, 14080919887213592148, 7341303626667347624, 11784881532696657518, 17307742911086150556, 6036132721599132043, 12167106497065306941,
+		13817073203406999359, 7220729284169210756, 14908407498603601482, 13536224989620701632, 1615171540711527931, 2063856048260214664, 10622581435417474559, 16378505765730768032,
+		6855676470217754770, 9517149712286624325, 11080380031068971680, 667425509348698033, 6136243307299269825, 5326577850303193160, 16120190278345757447, 1982981965726975383,
+		15399454106099176868, 3988744407816581672, 3596277710300384050, 15129113714633923498, 1554582462382333698, 3164553872715651710, 12729140363982748426, 16366728035709811784,
+		11647936211409428873, 14704462653811533865, 10005129575282387925, 1526194796943187368, 10906326807488904308, 18256878690674435807, 13093574545395154003, 12352810226542367406,
+		15290817014272444879, 8012864091692295774, 7591940515496590516, 9299619125326026848, 7297256232167521068, 17861204372399797627, 3100022958796565106, 15313770879200204613,
+		10190931844127971311, 4449277895844944513, 18060903840299422620, 5786504870079014862, 13877878835839147302, 17536010013969819055, 12266576574650233794, 3344384108564085445,
+		10406231172694378191, 12785551100938284935, 12210880209800471137, 16615829503150405150, 11718424737227538631, 2245674303359461903, 9283401225508960391, 7699506693893764319,
+		2278745583218618906, 10638058115573097116, 5685140621618740987, 7758115175926730915, 9043786871908073988, 11442680114439652875, 15805407285446479015, 17615595308217319903,
+		17127838629068819444, 14692086977823146619, 2491742894643214379, 3238012827598604955, 4066194902402629617, 3613111175737094005, 3296022969960608152, 4860674720288543209,
+		3753308721541654311, 13160824061458819791, 11298768140351857216, 14042645015841972579, 10518697187157549363, 9641851844202952198, 9254393371864075771, 11429987449073904258,
+		2566815986599406395, 7824829323439900657, 14465315986665451243, 2957504741164666523, 2280672126115151165, 14999624386740200468, 6090063205272921919, 3478652904863279960,
+		18131467168461028363, 16471039226156513736, 14133684792391617163, 7137732710914086892, 17299189471163637576, 17270681183882183871, 9046519354210103502, 16091721986926209161,
+		6572875037492082093, 18318192911446580882, 18107990043035854610, 13573958681720538720, 2821064027974708708, 13000417359062035623, 18286430707379660800, 13070676610179458046,
+		8521670721910745896, 7440450230382417926, 13794050882540606099, 3657777690979179248, 15466400576048586018, 7802926536345945651, 11932698778931413693, 4291944108972289013,
+		16729016738422946915, 4082443597391481873, 2238453914102498318, 1806710580451019071, 18305396377745213463, 2262209146853870557, 17240603302299977012, 1540474707615687112,
+		16013022710115947086, 8748688582020024424, 10921431579160628425, 2228053349060750948, 7024441100951863599, 15816203310189470753, 9078141084316010447, 9841344410499582933,
+		13377311905703150010, 6352753896568161822, 11086576920416079356, 7629848369702522073, 5472036379742160857, 6535781794177956975, 7671272114437903042, 5056286897725243410,
+		14579350500102276494, 5882738271691348624, 7188200631561491668, 3605286077046581049, 8957701412704914688, 10347270272487533128, 5995825272041784807, 18321189862831103872,
+		2376178340116743056, 2263593380938083722, 1990228394694589285, 13477447633165073333, 9023956677421314778, 7820910817739139038, 5288765314200405868, 13070699273589738968,
+		6765952613794178887, 347733275422001747, 7640026333627494061, 12925707101320796635, 5670472934143686904, 15041817307271371058, 18176041895529109656, 6838891343875575060,
+		9902363248877274636, 15776195244792726061, 1935342462634574355, 16572507349421626602, 7503944294807242065, 7454248748618678609, 2837392985175901475, 16494567631149775512,
+	},
+	{
+		12299242278498309265, 117303082144788574, 18382936515565701803, 7941141688858846015, 14923823358299367958, 15681089039073030752, 16878721085421212785, 3933697483394042011,
+		2878536922988449879, 8819365314325664735, 2696760638950720974, 11357179421800829605, 14730809809256560583, 16277258726425730599, 13189689275745970592, 13769784951430309444,
+		10292669945637125918, 13595563061674492799, 18301330068714272653, 16981073598172019270, 4022713583718555211, 847970754090163894, 12867993617169467387, 10021141621864633865,
+		15254713655124736464, 6283719686609422435, 5417864180357938798, 14010638809605797246, 10873690600705871523, 15014239467130590294, 15765460219545280655, 6048061577845125750,
+		13465802402879986040, 12777495579796377113, 11251142258511736751, 8312965145580158560, 223338793373356823, 813747086573652373, 534790745256052224, 3658554932030960904,
+		223170064814687698, 12938716002978051117, 3848816111228150666, 17463649319617382466, 12886402189488467296, 9605942357133455486, 12272689261734151433, 9916808458308982839,
+		2879267873712146919, 1770061136847768757, 3497337219301780129, 17065005588401306579, 7675751531915094916, 4337540836976665798, 12505868586426061855, 16929961945120117126,
+		12012729503226546642, 4811951115754240681, 2652621264600062520, 1108958391967017223, 2508980100759035797, 9023233544151778447, 11183557587641545146, 10726727280840759519,
+		7189877122763725514, 14656082750550993666, 13508306914749420120, 4564443784575285318, 15450566991657647015, 14019683331552104148, 7751003035652012225, 960642801291306739,
+		4621870789074053275, 2699296606556701282, 17510056683561737074, 14554735156054608866, 9556940770704438829, 10801168482998872433, 2280142648958056556, 4982572404720159279,
+		14621729774738200671, 16850208728798178903, 2650832773786164628, 8325244333065591089, 17692120343646193143, 2242845836784335580, 9386711085286369304, 517979059098779699,
+		396296174223428093, 16763788748988621834, 10606803701784640909, 2399987183687936561, 3641562114746393614, 8536687357022564742, 14532545286961725758, 14658331097531946901,
+		13237433907493396869, 4990918623816750268, 17673032790739307275, 15907935024302716062, 8613470231259845273, 9346326052910147032, 17747177708802561938, 4490130127498754807,
+		13867405496809412712, 7002613759387491643, 13033935552806967378, 67437088702121131, 1528641041740753990, 7001198041125832592, 6102137699349551632, 11527483925092226802,
+		5535652777947676324, 1216916140919282417, 343617165825197489, 10806931059627863289, 3212291315152120591, 3351900116486367965, 8595828725191802110, 15621077401736893558,
+		2386026063595321071, 9144724461940169335, 13121187420621518554, 17351696676224980491, 143495028693925520, 4590642171152119027, 8655406817079059692, 10005507077955932112,
+		6982427644490593208, 5211219672384700779, 14348546115682624722, 5876199850746516331, 18396840586595761484, 1465795856184232635, 9374516147960853174, 11803025633575966436,
+		16374709377982692229, 2545295070586009694, 17366393861359867323, 18067336234259281315, 9181658491221440805, 16188192004088261717, 13669686513572099673, 2044092029751770484,
+		7308293641399229883, 9813539775451467496, 4837144575100457648, 14073521030008335794, 12371724228966966456, 9185074727660313894, 7387427551441329556, 1866580457929037678,
+		2047964090310465728, 14133690277069748515, 8287749071957055844, 16821270580974431218, 10324684883587585565, 9652498187344172497, 2461802306013063247, 15048850312040680643,
+		9659170831875656345, 4251587871822599596, 12391279033133774782, 7346556824831912968, 2133114137534468833, 8694105814921565301, 1000087733076615381, 3478818915231998954,
+		15832320183998834886, 898251865651859288, 16874504161383651033, 18425166917936355349, 13387271833996394553, 808054572728974308, 2281828182196149100, 14620221246129351423,
+		2755242181069093228, 16155597320469161129, 17375128328249992589, 13376690667170223367, 12825454052191060221, 13625129606409283552, 5627148592782580041, 3092789333954796605,
+		105705035058376953, 7541598459498134635, 6627685529861836787, 5724525771392188178, 13865897118300842617, 627652561624109853, 167084371112939132, 14192831153344015422,
+		15618434900514973465, 14267977447705810206, 8823759714826430108, 7918740515193061263, 1664424041430494212, 9076733744947861202, 12010737794701759719, 13920688631446302868,
+		14823160144680924028, 15690572793903331709, 1101762466949115887, 19462496059060771, 6099422315003219574, 4300077459158116870, 1282001407902323746, 5792772971400374848,
+		11488321122368726901, 14632273370344181937, 12984850848826263218, 1857014998357880446, 13897135914532207935, 15925630222053677390, 11992050787349110965, 10072349923584966035,
+		12837696619944805389, 13470316523008526719, 3074966674353053986, 2630814767089382743, 13353767941686870870, 11405513520090968568, 3071969598389884693, 8212421686942839224,
+		7866179127856055582, 11874624506147226333, 5793384221044709375, 4411967221310302622, 3004913667339358722, 12230878672003882045, 7395980261120250376, 5188846147165419817,
+		16160221386626609076, 2876994290210606255, 6065036384672004173, 14696333348949573335, 2667009584785381424, 12100192661844794919, 12401945669155059163, 12847772853650923808,
+		2286437117905535902, 3130250324287833414, 3662253455746154641, 13229041365675585947, 3663813013822489770, 3093300797589723687, 11507645566517710232, 3715061633580408995,
+		3464453985305889088, 7486900500389940957, 8944303108517222303, 18319933556403836918, 6782476025105836770, 12822840946923377510, 2799592944286097404, 8737598030273298051,
+	},
+	{
+		2754563581284692865, 11257360722362829387, 8254261291934606879, 10023569920325096229, 7980898855627864603, 17162063449612285703, 9275759455936104363, 15936804738099638644,
+		303387668469489035, 7978391052264888020, 15413722057350324494, 508608987485166058, 5585753287556892522, 1344134516582665443, 15144279405777509214, 17014353449841567149,
+		12518577022215294774, 11347384788122950558, 17122718824958020364, 5431993665805279177, 1445831254446028321, 9845654210244803480, 18315778529692612284, 930563922336183289,
+		4894710987714215219, 15704993603878996107, 1606204036324478223, 14308635149530198932, 5026736228773269251, 2911689442372084137, 9004077539360196849, 7770049130277452000,
+		2745120518194234905, 17255944807561408883, 7371907591838942770, 11781525288383871227, 7814952754785494862, 15022715213812536212, 4112388658963418656, 13703771908397991335,
+		17455440140812341569, 16738670164475421762, 13259904130186215994, 2168106064304872507, 1969289843772256992, 9025317999701057831, 5835661391798891929, 3826587698101558069,
+		9149648374608464235, 7248346993716635643, 17283919168525322365, 10107681064815728795, 12176813938029507719, 15110337574289033068, 2436453685316043712, 5876967059744625564,
+		6197919059881189313, 3300993078638782623, 9357667752372201437, 17688129755135009447, 5477090746558113696, 12602024521188880300, 15889961935507293355, 7135039746373941272,
+		12561063426893244305, 3079971284510744316, 15695857190375815873, 16730673956207425338, 12065477821845465116, 13846158368121919228, 2126156187526559500, 3005167441915916768,
+		3858987859895327040, 17043903959888117395, 5861237635520080595, 3292646198413575902, 14286644557048422360, 14346409530388980974, 12583555046601155161, 4665981927428063991,
+		7657686120974201842, 2388299767028319466, 17934808017791217639, 16708640707026372313, 14122341266134976486, 9547124998857374491, 11194069918436025923, 14657538980930727877,
+		18115789712912297420, 6543740714573413570, 1955886376702349613, 14736853369719086334, 3914330395250768396, 7607848156418885173, 18220633528980056514, 11930952850158858930,
+		17010681753474701341, 6961088634819162945, 18395881317121515295, 11611411242007267179, 7996717433149311639, 2687736005475404867, 15340214362731923149, 7116441414289074727,
+		14302198697220662403, 11915041511943922518, 12363437164440173650, 4047410026894059083, 11439743031696133447, 8776097395071907030, 6851061783357383945, 16484733576581941012,
+		2861660066704264713, 16453202148771053225, 10039035813504063627, 6275446616881871868, 7150609984920482782, 11100941755544354363, 6219760433202580646, 2875377482232912143,
+		16477698187919702699, 2757160833848759781, 5976267476122243443, 7375951277779829055, 6525111513935493528, 9969722922172879681, 12582700753056539952, 3861958159147836631,
+		4207324524057007052, 13478421263392765917, 13318275642734768006, 8504333045658265535, 3960720256367501697, 1601661680373853468, 7704205542213854353, 1552780884856863914,
+		11788483659211580527, 8739274750400900816, 17562450707643849072, 2113004873311762141, 8542099133996522813, 5273956141012313478, 15661081976505113338, 2290009483289921559,
+		7730337285529332076, 910421998453976119, 1242962796308775978, 15931313183507922513, 296811920445331257, 5821874870466240960, 3843405649348506130, 9007082448812181532,
+		7200777231000974420, 15816416455380831370, 12932038056359512011, 16422801186386616731, 489979647738684819, 8269568123908387407, 11617965045895762979, 10069799398667455631,
+		8245819835927284113, 5237630684564909794, 16572245571184457585, 13396211619915630497, 9177789877937729597, 7598297211302983411, 3133511073496333246, 16553020037702090576,
+		13441991323065749602, 15441570013111011986, 291172418860690999, 765089869758770890, 15943751395897588683, 1887511823199710563, 15452188663399676440, 15028027691170546376,
+		11009923302693800320, 5465227554242327455, 6511134004216481185, 2187999546010819375, 8387421071023131689, 174295266381833460, 6010935117399493668, 3340537243300033200,
+		270646782953286316, 6635640130829923909, 12717598479778596267, 3198506535831522029, 2605714695474737827, 14548588937126505914, 10448279824323025574, 16008560590494788290,
+		11460241048816176102, 6557818897531989327, 6948658872009630691, 12506263743501199667, 1813031030961999507, 18320107449706503757, 16783076453582799039, 10113937529079967843,
+		3096618551325580575, 16427990761832670936, 11792441105446619028, 682188988823121368, 15606025696371121549, 15395362449248397023, 10158149307437310549, 4442375503593769727,
+		5486499432056098253, 3811951715772590831, 3856863699598204250, 559724736042732093, 13251752681229681959, 3173330346541355882, 3597530263899943500, 11567248716558420280,
+		12822024566847931229, 14487146762942136806, 1361688279016339671, 2776885758026394514, 13616222293131162973, 4629388276054227930, 8304132204812769256, 15188275451670510949,
+		3676452641243730693, 10839008248003066479, 7676518604603740317, 18384275325050378660, 7827069556104560937, 14335741841451672783, 1145975213382205474, 13691620069378415495,
+		2513451633312793643, 17331457978938147928, 11588204658848186728, 8824497684232939293, 5956154520546906549, 14434958079241686709, 11798870987920360447, 5875117843056165993,
+		11313908033360767461, 14678575871510948417, 8479250768537158849, 13854183783158898926, 9413525381201650053, 10077438283140087199, 11413783222317729281, 4418417663988371635,
+		6001837395299394988, 7545846298204709215, 6662102781970969966, 12696054550672669874, 7436995610194789060, 9042605089262227561, 11621508125069628605, 7289479057360149973,
+	},
+	{
+		15555649500689005370, 7857014165815014600, 4664069234996337119, 8058230521837307501, 18090421626009183450, 9278179697462444898, 17138879353097908770, 18285223269807746171,
+		12741225973381753432, 5461579923265799106, 4348015554411389960, 14970536173310927872, 11568371199139699619, 11748662751675667230, 15495664823061891700, 670495577617908409,
+		9865772269601493999, 7325690007062740244, 18437964667185475354, 9546360111100619473, 6266116854923135821, 295905071295541234, 16037468634731642095, 16602609756229843150,
+		13266892287530449189, 2232961926857263527, 5934654989155432442, 5415975493246016158, 17117784386882463158, 3875398271691758986, 15755743581177209843, 11380746535012415659,
+		2047267291755864302, 5637045342080349843, 15779859211873634959, 2415175423642772217, 8664113127182901077, 3032959071705433205, 4250761979529656864, 8729259992491925346,
+		16559648310139278090, 4796731467175572814, 9267555165184254828, 1400425639375650333, 5199035239208036114, 7994153995816640929, 15677746297407711038, 16338895562326287438,
+		1740700879164022194, 8442598604870387302, 14969965175291161450, 3086786406508018865, 12097766404705693713, 3199218739761578935, 1744290654371906763, 3672816528005113908,
+		10162459499000477259, 7534168794800651527, 6320985751131807192, 9263840233901040421, 12178625283764017250, 13143797113231152006, 13089053551699608219, 13480464010111258056,
+		6572275813002629593, 15328678880838895837, 4281489161088939969, 17996597009627631572, 10405019085582914256, 4773602940383417103, 1455403777441353089, 14766164051850429812,
+		3886207141264898075, 4215113531127552656, 14283840761174092490, 11161507022796293343, 11235510295695006534, 2260082644337974884, 3781681413610409735, 5577127823856153222,
+		15609337727165147542, 5725010295752332028, 10091444858515990726, 16162855978360002823, 2478705273652882251, 11394669968372227148, 512641267828429208, 581410050368207889,
+		11426681347395118622, 17135867298562042628, 10870734720453621112, 13803364322975322217, 9740527283062276630, 13765238480893165263, 4792349632705804116, 18359029140065847048,
+		15215482935039834459, 3553551735757600990, 2471323651039083728, 11355669733892999598, 15830640053604899661, 1625382463038435804, 11969247519895019474, 14372668755409420943,
+		11113773299077372683, 16618589175113863833, 12580653821785550146, 8264195478884998326, 13569468260761711850, 16539804400793525042, 14464540796871846551, 7710175783216723569,
+		17565888320840294282, 12018783137972195797, 12159604578082686310, 3210316551614996638, 7700243787046971168, 8307491254792612954, 18022719331150542511, 15890872243361196004,
+		1420251412241033168, 6449255753238336368, 7468624722117319576, 5716072259994197219, 8165015263320602150, 4757529151848960259, 2040364517493350115, 11069642333484542749,
+		6861520668253090597, 14998859189233167760, 4851545815068976365, 594940747993801912, 8473464707442482665, 2316305389548210767, 3995416902578245152, 15770229481630179441,
+		7316766449463697051, 1410976281384361962, 2878678490331118371, 17638505404208445694, 1130528985192221086, 7544558337870473835, 12071909234624857373, 436426448500115731,
+		17436263074416557505, 4339627812592344328, 1076653379358004720, 4996950998108333398, 8528954985898069924, 8259369611572362613, 7869239207308554342, 3592003501289265534,
+		9434687670958330812, 4808705744496679962, 13910334628239183613, 2628594509406050235, 10055911465166862298, 8069256921143792190, 11886968715847498191, 6351594160398684406,
+		9865961381837093259, 9590584894285774485, 10674927452501376239, 13861388033657872936, 808108663597281834, 16581187679405825998, 490312642991375167, 11352102610468872412,
+		12888468148530619065, 542846015600866106, 2086677842713697080, 2758534484095407635, 15767123419143795297, 7077908316515201321, 10297306681753168866, 4641656730233236179,
+		104445550853777927, 3829969899624802332, 4713997522991885393, 677661257782477991, 12383280183673921457, 4373178143111769979, 6375181113677777933, 18335077047046332699,
+		5472832021993175857, 6120966193470238758, 13156950075464061259, 14833372202848630444, 5760885723102571027, 18022572190906170343, 9870918995920897221, 9546055667466056471,
+		9516299398994303577, 11139435630263588724, 7364473923787049608, 15378275072059759415, 7378721410182635028, 2461490895435109307, 2579531356642691202, 11061693189962996686,
+		17380308085259417126, 12584808641030185141, 15485460243194852460, 16172215807782473427, 690761937231979275, 17570908286361380250, 3347059970688467328, 10404397759606846636,
+		1302709369035452282, 7149637102192386111, 11659118804203241786, 13909758997057192683, 4361167997834561257, 2300569874961985919, 1609719848856066643, 9866395233709297503,
+		17124591880405051324, 3379747334483646957, 2084957978131092947, 2413497199486596627, 2867893699156486423, 1357836849049583382, 13607307985344221035, 18039194570940763745,
+		831259058391834318, 12782538711785697535, 12640197944141330321, 11004378265133697847, 13622812183191119169, 5878590957416415562, 4810392157669422629, 11128662835376944411,
+		2248775486830407244, 1550340755758127506, 8399436463450785695, 11063895076440303538, 2168511054719571959, 12238498894267955838, 10824266376477587807, 1073243669335517712,
+		13568560319245254019, 17615770913976878569, 13214159705850440913, 7542574047209989510, 7392331519546111377, 2685908847786414772, 14835825677444128105, 11347648758435372538,
+		13230815692170010235, 10662664037814374845, 10120384214921531334, 8892863196093018212, 4443096401408136417, 1896901619181196514, 739574867683694091, 11233952771600927581,
+	},
+	{
+		10708602749843635238, 8046488591192123621, 11391158257016334553, 2512908912806916201, 14760224624269838038, 2631910198880826809, 2387247811669872033, 2048193899742148806,
+		17392983665205025720, 12603331233691760840, 3752711326309791976, 8281544857330094164, 17004651346561270106, 10399322540256775923, 9721299450284863176, 3725182263994944884,
+		13643198694788276032, 8127425924819487897, 14165945065582850538, 16520977003164405917, 1941948502806705647, 12390949208067741787, 17112117376594486408, 10232906951259490042,
+		74190110112564319, 11227229657066745164, 10151080599595091944, 16591051376074591375, 8256332495682655293, 7127985739945537626, 5708687346183367016, 18310921046455023281,
+		10040565835468209502, 3986586816478505371, 7957179672896506016, 13347112914739722590, 14099734293320932556, 13921950344400895005, 17478414833301838037, 961445463330402797,
+		10553899634420153414, 4215979268474142438, 3643081140297634139, 11620906704125380460, 17733628678553828301, 137473878710304143, 6211837577294956591, 13926110616399428016,
+		15203257341351417031, 11597829209697937782, 17317571979811895272, 15929491640570317745, 5731227916276913121, 17093153916149088230, 3908757069480556294, 18211818355208735794,
+		6887629766078662088, 15330755394432598442, 14144608177273202986, 13258654996547018856, 8975611270007504091, 16869834856279102361, 12707970875852047823, 8520055680055874514,
+		1643407997152867899, 5400650551136488814, 14663391437159245064, 4743209938058826866, 1728998201888511561, 11238331920657195520, 11617984741897247805, 13858029141809651878,
+		14003691155137683825, 14641672309228817657, 4031783205073356111, 7414359968614421153, 8166814052414482491, 5209260157266028169, 17555696996149558694, 9780166780476833956,
+		16029688335186691281, 4244772808651443261, 6450459413414527821, 695875191412722741, 11104054226249884864, 146461617619843327, 17480214580411209436, 11285418463967817315,
+		4922928863857449168, 7226901725606965824, 7568276305032368752, 6253457805758596797, 14345040877576203078, 1718759302498746946, 3544444746772280646, 17880302727399449566,
+		10693864548794383214, 736148233485985101, 5241869061152863453, 7166954323782542739, 16861482585847848251, 11483636939866570861, 5950529069765100144, 700887039653157350,
+		3906969739692830848, 5546431121705298614, 10491799900914853406, 5871175286230239238, 2851574662174517162, 5511397532379144624, 17409985391224790540, 319012646822749823,
+		15269778527761027251, 16471737837294177924, 8830398856035267114, 8206807757132984992, 1421214226977370752, 14233751335943482739, 9668238787333455452, 8700964319357541954,
+		17561670470565298976, 9524122142014309347, 12619871254022879995, 4098610542031538614, 8338691110372464881, 4378598564044777665, 16435680634249352743, 12067828180476756532,
+		17102475410743425567, 16244272017711449252, 17598420420289880464, 17858587557620312875, 7275673248698358659, 13952444068457447282, 14004356855576602555, 15776401868125266614,
+		9848210305813205280, 13777844361911806961, 874096498600831552, 6286216140019341540, 1229781121487503670, 1221366673976886811, 4534525466071627057, 12966848050780717673,
+		14890015174575641658, 7082696407720868596, 14546372439063914434, 18306301153433516531, 14360952638570231274, 5387283652784509262, 7246876761413034655, 4917620254108676720,
+		16572428185201836512, 15535161956998457706, 3118508753345802652, 1036719175817464914, 9929541174185476740, 17658764424885337186, 3038747611544544975, 9299826573437432057,
+		4068144934809412921, 10422353259330469599, 10820596685747357573, 18174251490011716747, 14838047097904304200, 6494279871501263445, 10908514990777375627, 2395220126873880030,
+		8963350163641627638, 7331858013030906816, 15047142507680204097, 6113080618647404016, 7520779807516814683, 10255234845683676901, 12010823325949652354, 4005195924244758895,
+		14455661618497189876, 980858168361168621, 5057114595071838088, 9447128440518577562, 17115933446433165191, 2063106073840638313, 5944852338857186064, 14601740796836275216,
+		12750698494453238590, 822220438401342753, 12735466470750534773, 15168985403101776640, 17837672477921333079, 5413174218886573483, 8340507718774735027, 3796235681866322764,
+		3366536195244539993, 13901131415620358879, 9146606194544531067, 7568835872371146677, 7101767951356426039, 1958938171972212156, 3871412404872561111, 6437054924013233533,
+		12849284342518738377, 6061751293342567452, 15168528907847693260, 2071752334274992986, 338461453751559028, 17270401493472349305, 14152214298057413781, 14074152302209367061,
+		3814267663972523036, 16047424572869508620, 328411057776532579, 2321721854548154476, 14950895796162035951, 2381867458906113095, 3121132178592915484, 11019696935452271225,
+		17929201703034060485, 15478512769360046037, 11652099424221007544, 8436785170867890275, 16340404489137765730, 13705192502407972039, 9464924753010269658, 17372624212933856135,
+		11237648987477338397, 850109691127167972, 6566350160877169296, 8028073340740368222, 4445151747345891893, 7753144690511205475, 7551118086710031441, 16785474804106433438,
+		3919851124685189663, 16028223238454025712, 9008783533564802058, 15647028843636411071, 2029953422298604024, 361326896057539567, 7653333452646403127, 9211397293968688243,
+		1817762546790624760, 15025271080704836746, 5761603182050280401, 10355268146728370750, 12900583599325924868, 1488036927944469046, 3405173852255315327, 5600132277974719103,
+		12574920924242276218, 18146097977073890534, 18281543194137545725, 4432773597060264867, 797962164984225968, 13432184750641235201, 12394976215803938078, 3054137600383896411,
+	},
+	{
+		18270562314314829224, 17574550722906577917, 15522987576586641271, 4200899284963891561, 15719788437321868967, 18390235318178988753, 17371818886753265385, 4583380351670429228,
+		10102001197913431240, 6211688443233768420, 1986665099237206297, 9248907879269017005, 3081890249882755206, 7828527646248386813, 12676034092230326487, 14655968027461080131,
+		11464797300361906821, 1444449385286554508, 12433005157477847389, 964895564896662942, 8457290958728547067, 7044433897330872257, 12292673928275053405, 13679355097865192207,
+		5841260956815214452, 9461234662498869948, 4761949640006529525, 18229823346336752572, 16055957459773168413, 4272222475092786627, 18249888117586812770, 4531982814021269346,
+		6528332072572425694, 15678657170585498065, 14462305190193144746, 10159286562616704237, 8919172138248087686, 13247073064443362933, 3056992278576665488, 8216417459286092432,
+		15095644792163717355, 9931529712396800935, 8608932369590222253, 17019087735655287783, 17120516184457264144, 16412592485673181957, 11221555966650765276, 6815162077372858604,
+		2239262553722461896, 16518231021003046485, 12875479040073845800, 5243141733462514317, 12216971859495819530, 8917663622006068692, 2606734295032613674, 11237688605489138628,
+		7270238601276019194, 7318279377964882079, 5226788506940171017, 16838449902078450273, 3375184937745100689, 16320655850583231520, 2173229791272659780, 9816381971766204380,
+		11061652864259684005, 3625039563689831268, 4435107405432574197, 17570841169180914890, 13981724030179216670, 4992487505540472327, 12893808204753555435, 12899171569920731024,
+		12002788024483301555, 629439982201171214, 13749214763651595011, 7164215996082938159, 63895081825959000, 7006379700570403491, 11929054672290963822, 14290981753366049931,
+		13554823979828564217, 15627748053816803157, 12924111102804720301, 3165135223777020148, 16345805559363705538, 17656153856991335888, 5211305829410935273, 17846236012427517420,
+		17113448198982970082, 8879656883528014268, 15215762680430094206, 15232212751792759071, 13699137317730183483, 11815206710130297569, 12298409691055054593, 2192455093917691024,
+		6973243752017383665, 15334919534387330350, 12203459507012560294, 1880762698376948842, 13008085926447766632, 11695961991328184563, 1311309249708428072, 11981691262998313807,
+		9209757463013140118, 6782250604095077195, 7896297860376631775, 11500117438976638113, 9099678680126826621, 11908588510950302487, 16863479726536938776, 6368086884375751995,
+		6220904427249143299, 4501361418756965744, 13907877383736656540, 4499586229279778873, 7233050316216252450, 2775027076708404645, 5669561106187108564, 13951461080947060780,
+		9742819322069712752, 8779224519997661749, 2591205872359340025, 9144644967919881415, 10495832103710459914, 4557264342687723360, 935865282128150338, 7120324256648044882,
+		10780007491891304021, 14382731247791652187, 3296810302419712004, 12567831906993651128, 13933396378746555124, 9754754796778422405, 2905077741505886450, 1522919492210831578,
+		7282056954663740402, 4915867300034445627, 234865561845141598, 8874426225092097899, 196269165389812019, 8951904020835594063, 6908903359164319029, 14062039535595890356,
+		17922518107542393156, 17388335427727081004, 9077910363057082196, 15157438705071651749, 5615196861086779767, 17404239261681991687, 9772161835068093639, 8380484042808490346,
+		4683169301229531061, 14940390399739549639, 13128742567354398401, 15222231511210090535, 7352694898928671332, 1221555526903686446, 8697118143614336514, 14515400523185205597,
+		1119145169329993209, 3453487026721044641, 13723232966162256192, 15282444658208236515, 17806849942057939434, 158876409507122147, 11954364486113732203, 17566268785944006600,
+		1443798830844295330, 5744920153630226551, 15739845606128975055, 10458513157123726949, 14711103578835123416, 13886988522344422595, 4454455988362290346, 3507977514728491242,
+		15328194945269186082, 16398971046683442289, 16293780909421539295, 14488637138080135219, 1108438550767062231, 16291467684905586857, 11891067917592351245, 10459212739896579624,
+		10239864229747754958, 12477284975467600510, 14054830413782031834, 17752968481181892755, 16082713391521411762, 17191329716867535304, 11245514405315337909, 15159733745232554536,
+		4102022129275956496, 9361580273813141387, 13824110615577377618, 17115977884930866990, 15058705994968389537, 8039281695081359531, 7179945727911625126, 17628825480910826356,
+		2477336341361304271, 18030759410783456479, 1164757311756325043, 14195508307731677040, 9794350654156795137, 1135232100348022155, 16693007636113380448, 17770308235375345497,
+		7064407865619227176, 13284912648471743270, 9099541805618279168, 7383718461788433067, 3311987567268438113, 10943963018398042859, 8038765968977300792, 11039205462473399718,
+		15444441705629456398, 12030687282161152512, 16500102437404896225, 11467410246278043769, 14031300093087427598, 14458597378298191386, 9434445586505481169, 18221119130471329822,
+		2269899977501467759, 9674818903084386596, 11781166634280447465, 11752600152694102168, 14011747753002945247, 1084585411243442928, 15614695372212325691, 17196679090968022414,
+		5062812993852092949, 13193601915773858975, 12910718608861476282, 447390754333146274, 18393090736120037653, 13231946117349235609, 13365030203093499221, 9724404925244523782,
+		18064151108813428175, 3928735035534454387, 186686833744587171, 18406101378699384605, 16477405641027895528, 697258480673566897, 8958117283476321666, 6970167016227017231,
+		12694666558858009121, 10992313774737315187, 6046508760845509477, 16818819584649823054, 10464090160691032219, 1221502600750419478, 8658907655588546849, 16110628890984509877,
+	},
+	{
+		6266830413981331818, 10890859480409122410, 738708598357264321, 9241173142142102299, 9152169484987657321, 12122430118903337055, 14270062735458703743, 13877635605034675649,
+		4572419849863661964, 16330741525817240677, 5456771007607263420, 8798510164381810403, 16547183593064549865, 11355135595370359779, 17581910791451710925, 11684604415749005488,
+		2766130068233451740, 15909689412657372214, 3272828023364980896, 12907534005596438003, 7065629942275705493, 10609982651084321649, 17330343421617897811, 1746246157222856918,
+		13168953859078137190, 9072500190247791267, 11090199374278127099, 3503847851309060744, 14395788825673846582, 15073993563711333791, 12879874391706003251, 15417028700542288171,
+		2686132933630431595, 334448852204016400, 5636563341880055087, 3897420469445246068, 10569177829735084588, 8244586887721364305, 17973493209847502315, 18083956436923498083,
+		15514509130323617046, 9833490355170899102, 12028021566105512521, 6349458533674010018, 13470024118569549588, 7867188201997717819, 6110792121234766402, 9917858515766574695,
+		8273062939911446888, 1936638151089648185, 44602505720759914, 7839132833110815763, 13045756168264521992, 5375972549477973022, 16964151563535745964, 2871770426902555432,
+		14164643693563803212, 6386904235704679249, 931435629437735510, 4496152555914735639, 820099532545743339, 13419988718062417698, 8948965620484833159, 7238410427920554862,
+		4387941928212462673, 8023190031094282215, 12322462122895470016, 17311901330042910195, 16445894183838823370, 690424095855074674, 12820742226551488738, 227935274674223825,
+		17437729542205914525, 8439533239207225162, 2862942422640746698, 7340866642549630610, 6770451500989398335, 17262212260581413381, 2156505157624055602, 12195119268846383898,
+		13685370053507732180, 8304030489296890211, 7042719123662732989, 12115154796394040286, 10496877583013829980, 8909625177349683785, 5268451666475070682, 8910488385056259560,
+		8874918984373509240, 6652428549855789281, 14866714872885601270, 12093494664302554643, 10149999253136441007, 1611873554177023520, 10271627298853910516, 15171882630355491729,
+		17085353800722834618, 3271271583189511718, 9338466116389304614, 4685545953421459012, 5059702655119414343, 201476627889215522, 6388612869673101372, 8357217932305360896,
+		1836621694151238424, 11438765101326043062, 5537182303007083642, 2657011195641217678, 15370176245454161308, 1478361893117141052, 8729368992402422055, 4807782542738120272,
+		5084555197036037383, 500829604818691390, 8128181767026348964, 17895639808733462562, 4138748420878083709, 267892430674902987, 8954358455330696651, 1946224964877667668,
+		9440495138081785154, 17328162383695942099, 1870751290505230781, 17987066187778049275, 9952223038481207705, 10126409487298126876, 1181369784146909444, 8158422380540037915,
+		13005094963168549814, 7254364757817833162, 3708127625424981603, 13214729399033107803, 14306349749849146051, 6983270854272831328, 14340019638575491596, 704963281855585401,
+		14561080905697443279, 7640393429462623622, 15685656608213407004, 6317405842945074950, 4586197269496115618, 4352991463721324184, 18421865732314202847, 13679296167045126011,
+		5024751682397066348, 16464187416447039066, 17561916915150311869, 1553872229528720506, 3971081625989469183, 16363381852589102144, 270446294712200212, 4668332646727035585,
+		4623922898967168175, 14927682190770218553, 18082407698612059245, 8156136453512346914, 17256761355350416250, 16185397881787027880, 15277309552707416345, 5991448876439153037,
+		1334994484802978518, 6876293985013000163, 4439518198423905531, 18287119869714109760, 10942138263490204506, 13981840082343935999, 186527448590996253, 11759869552919496944,
+		12652601656062843187, 3947181446273381189, 6235196886760030384, 10531746495897900463, 13249616872107073217, 7937663398525899211, 8701780810784627798, 5901496026068341468,
+		1059285256835989485, 18284969105568513488, 8222225088165109003, 1178299600673068913, 16068875143685216551, 17849596766342630525, 1648308197824141718, 6344465813776674352,
+		13850247359965870279, 17391106451201459411, 9882112511974412840, 9027485913083134379, 2654737707750698953, 2829872619210764000, 10765067664204983675, 6008367494734883394,
+		3596754664049660092, 4049565277418079196, 14294713401434678004, 682517403208603499, 13234861305501540306, 2878761138137340816, 7563571058666806838, 10752984583868770507,
+		16399575624290910947, 4698193514990054887, 16222170007882213172, 6300376482027477465, 11587700570984519002, 4408509191665524069, 8909599698892352923, 15110169407475815879,
+		13814725956725513903, 11675366986709837701, 8008867936756292473, 9627238521208818281, 500674066787171963, 7307892989752288627, 16701476208533897826, 13745712031279374379,
+		14988991093658383268, 6586109441484875615, 1456715231981080716, 10587865765103526958, 7439504550868615754, 430398141621608230, 17710495017725824018, 1267747579289674850,
+		7939033276966801601, 2952159422351169438, 10439776924885737877, 13630489377585028212, 1779349587540144503, 17209739673050012100, 4174716919431642272, 4986592555205663040,
+		7110204405213656469, 5225260473696365908, 13544564684169074596, 10807318789744351361, 16301252682064971136, 5046748520130689465, 7049174921499294642, 433785658536711265,
+		14622798677938552282, 10254953149954221954, 2609148400899865119, 8197897294400569748, 11784700166516996756, 18107483989994737564, 5332550435198791193, 13389061302706010047,
+		10892870009313407934, 5709686117526627488, 16343828906887149047, 16063790174205876315, 9076070192754075075, 4639156357669822592, 4904064385440242264, 5942264027390072320,
+	},
+	{
+		17271984572727555145, 2097715321690717305, 5328035183708920909, 13206781766168781008, 5915693606819932446, 3870849056297265622, 18070792155150730518, 7786839743829304936,
+		7939886940063870939, 3597929036186322512, 12732772396498766041, 13300425267730247515, 2345112231224079293, 12327614629296314761, 17106102937162407683, 1702694317559034053,
+		8821632341545057929, 16708916351043551467, 9171560460858577216, 5711973041149612575, 15808302665077457285, 8412173943543358851, 12602476370021215716, 4778674887660148537,
+		2707032230021934480, 14943945588296447659, 13333962501998857701, 10603744732015256400, 3386903941135274495, 8507451908469049716, 9231176235773710950, 995464562185179329,
+		1251633503842168929, 8646405730060859011, 7525758827556699239, 12781503299321323139, 3762059070509735358, 12904588764985510882, 518456268741331092, 2752400776174997580,
+		2965193395248314453, 17005383961540689211, 2510904953800463288, 14582093408745785683, 14930278391247460535, 15319775861672772086, 7915822626743762260, 10481055458185028303,
+		750419144665626202, 4009275022270511551, 4810013488865977907, 13090697535304919393, 17408171061427940566, 13469810562978287715, 3952372983235223818, 12596642250700034956,
+		1497127512412966214, 11292269970549257426, 13920714718237672232, 1363993524078475237, 3687544717271789391, 14097532154250414203, 8367320351336033564, 11089672460564007700,
+		3927746316404254574, 9973240942982210953, 14122301504960485144, 13249357693517290445, 4259646940372475995, 13156585130751616020, 424701295260668232, 13006066175253059189,
+		10308406270137410351, 18444509448482991837, 12509509048086126555, 8343613342319774737, 7902938427788958534, 9924925722974851885, 3762983399809982874, 3397026083592781307,
+		2116063253535766674, 12792173758770945620, 11357854367169339661, 4502375174987631263, 11374536277081101446, 718846097450449491, 6555869089578359747, 8571702699293548804,
+		16993953276024768829, 12025590727803527383, 2672535181364381995, 2183111709986676538, 14822521615475063339, 10618745739454592027, 9957515072444869664, 4797521918890127374,
+		4582720743315312164, 18280419827142252016, 13380629421749133990, 16786942173448683921, 5929601960379909803, 6715621236552343797, 11192523517069751956, 228125323996215945,
+		11861176681909235996, 830114321507110720, 13132205092670772295, 15318287322892364044, 9027539547229346224, 17629383881225964174, 17167841317952050345, 2169650970520181403,
+		11366374573920831312, 81590945660392134, 3339836125719372590, 6176339191258224503, 13498384602634172923, 17380518646558253069, 6505222573402454298, 3404196177841425416,
+		18097777493026370528, 398882723487597643, 10462164796529820357, 7704526739683689547, 12438059168025171393, 8163001730991802064, 3319372757738711275, 11518015261707325261,
+		11235814273447729629, 17827792960634604769, 10951458440780869321, 13957342734404907932, 7344502969085321880, 15052563297577817908, 9276707332138855229, 16077312904856138176,
+		10945312442787809330, 8353703025227023259, 2523779015225839136, 5997809042199398051, 5595238423081509301, 1901941038793828090, 983256298544496123, 929860142706986099,
+		1859865867925261002, 7171610585558961405, 1708769301690637951, 1669524125723022855, 1126574755172968332, 2284167219201068318, 14925928881489847288, 4349400324295146347,
+		7809927122217534998, 6003738786706135597, 16541272992243715653, 11352602417510156921, 6070703545889058045, 3742828100079104877, 9416263310824977145, 1406892456840131842,
+		15907861713154660116, 1789008941779432664, 1086909323248385272, 5337878342158043460, 16405416607888113885, 8262005873603178297, 12775015438669465500, 18394022127507526579,
+		9832954710628449545, 14612341389215489179, 8860090710725054989, 501948203387806263, 9969784653624607958, 8524029089859194791, 18028069685553315869, 7863046312587606086,
+		940114737935470576, 15661699274328042324, 2496303902262203344, 17900779334646110602, 10928989106385540880, 11160326060698033088, 6591628982832414200, 12860480197090465356,
+		4005088727670892586, 10215872293486093012, 7634075494800881158, 7707144163086802537, 7085702388211248163, 12168208652772836726, 16347414703478252736, 9386623607672009940,
+		10720163442173876242, 185901255673735804, 189524655270248212, 17937598483325200462, 9672767027914841820, 10911520298114954717, 17238190140596785520, 12302850034563751398,
+		1819872496749425461, 5856173707582412777, 8519855762092470428, 16315722646681962500, 11554620938156340375, 11822224388003836169, 8221825485736638318, 8413608007099273503,
+		16265754830488408124, 13716061973016396515, 6050948709307262401, 7654402024031530787, 149712175032162058, 8319305312043679388, 6115793437696694706, 9669523344165801010,
+		16530167766100505402, 14672843572926881623, 10752276706209340624, 6888427606311779724, 9060900993058482991, 10439396339124215720, 17640982730425880863, 12916411341252677116,
+		13182242421100666863, 5267519287044706312, 1780278156705475292, 12839545421803851420, 9724873776343820617, 11742602593528879231, 7598735248774560112, 4512374343657017031,
+		15080601286098047668, 6570749562833033851, 17494147260115946401, 4878559727303047850, 2259644365338981526, 4232993783633913284, 3035566741498855042, 4306414296080197928,
+		3878740698199360708, 1631626027682263021, 10479957065093850273, 1678395573475248815, 9964111965340163993, 8992208313996775841, 8147773940555378986, 6205594793300838098,
+		11776245660806714247, 18129100488268011560, 15389929343761297429, 14544292652959164154, 18063319363114104433, 13433144948667100183, 462314076175867487, 1862686058702915115,
+	},
+	{
+		17596113920958619489, 11920824479658301378, 3786905428099710821, 11112764289322906111, 8817260450068629272, 6518847791514184438, 14593687325057339783, 18018581321332807475,
+		2056254186648603335, 12143016575009965669, 3290271983033386616, 4338404082685850854, 12660444972475266123, 6345409453044955404, 13278869140778657354, 10063005167581762786,
+		5303950317664091150, 17409642188139937758, 12135894348302287058, 16444741243419918751, 13935885817311324323, 8496908197501732703, 12163317723288843510, 16891353436915314685,
+		4168420842704770545, 338440394515115377, 2102734009665481092, 9772725684473416465, 1247616337419130000, 4222072446972129729, 4836898447189504007, 9154346000276664999,
+		14649401370738987318, 10044081678892811795, 1306517740393103656, 16586067283450489622, 8211832777731897494, 12849393859171286949, 17327526552807783018, 14171704619529498238,
+		12849053390245557890, 12693731077061619694, 5891211584023409476, 1008960642219209210, 15593393872187214387, 7381248773473326001, 16559656086795428559, 2106025108820858934,
+		4347667984894353308, 2129883711661222690, 1076488804494872856, 15059968377755299195, 12380937310378496242, 16425480883270944108, 4769192332535557551, 10388305045430499744,
+		8553482596123775980, 12627020622203381515, 10774788686070344669, 6271789114731522097, 6270586844349642345, 5584690155569770537, 9478526526319537174, 3405597782572827563,
+		10255408065071335198, 2384996481315588922, 10679447117297819075, 3734157461055440416, 1635042286365643780, 11321809677772938996, 2373960964139986040, 4869129159740273704,
+		16681657814739017038, 2045405432090866328, 9473434018957974472, 5549808619751464269, 3650191693776946828, 15805634549736708741, 16764187297356548667, 6849534466635874363,
+		15295973549776084894, 8150873746601283651, 8017271980921908229, 4899654767305073834, 15257501950484641691, 17365331272978440066, 14582514748324426172, 14727798284858071666,
+		3180828552573045472, 17698570278585440462, 8986722854533057232, 4518665117523514004, 1718699978312382231, 16973074530347269964, 5684175730451960274, 17228649521631238473,
+		2897180423141326703, 13691273076814343144, 2967066815351306232, 1032540647518716635, 16365716239989474776, 9503666134295232767, 4599017511227366879, 14475021161770955579,
+		4512626226592149712, 13575110216387069176, 13488662643497927183, 9673147324484250604, 143936220816719815, 2307325398241477161, 468315224038772027, 17743582630124600591,
+		1476494936296433813, 3408612621327299295, 11632756669813257564, 14296719897220703576, 2241234207239321749, 12237974399755684219, 16253635131573079566, 11892871179872526079,
+		8492025373682814159, 9341562763134230960, 10104358220305514878, 17545404790574939459, 15737064134098795026, 3880597485411313924, 388663918823974597, 15032915458906101183,
+		965170717686924337, 17890763357610871180, 17588999527212997589, 13975763809893342952, 5109669798963414493, 7891916061794044612, 4789971769354067287, 13049661741280223048,
+		13047125712251887103, 6463859133854403980, 12163714608926575519, 1018022589444930561, 1736262463418943433, 15665908585957261569, 8814123147308650486, 4798595000205497714,
+		7506024921976923590, 5624217973379693717, 1727881279508834884, 6843292805721229768, 14721392495779901462, 15739256886195814859, 4955780690636679890, 7941019297099640360,
+		1679075860853192334, 11512607379850785303, 8606478479964129549, 11355506676698290554, 8638706560448426692, 11314948425220125007, 192055228531777598, 1407009579456262795,
+		13286048494307428802, 9003344338654830342, 14153483128501604993, 18443414499226619410, 1307798988667786279, 4422280407538765508, 1295189585361403916, 13026087054487841568,
+		2784400402546744378, 15890015749743051151, 2721137876244951114, 5096506081391833837, 7797931926335359630, 11689452583898581132, 14104784079353186010, 3188967683935096888,
+		11330231400343362000, 12540174755074499088, 10360616188128925049, 3458938550662172118, 9983547038346979353, 14986318734459319551, 6345635939240236679, 6320686366534231970,
+		14746231842102190633, 3622710091833101572, 12626649920759262265, 7005023704205322451, 8825692535315999015, 4515463777365688013, 9604411949030284505, 440641657645532650,
+		15551627195111259367, 17849357920181562395, 12870839822102241674, 13056924324197787476, 15109676201265834798, 12974964680406025093, 12841612415554457877, 2986633967268013902,
+		16172780290314506283, 6024364507532794579, 11981052290745212925, 14235100278052078327, 12912505872017936022, 4228821405313065812, 2097279962856941481, 5542690235350104224,
+		6815123236701278368, 6160442936745831892, 8260371745376005388, 715614132817606668, 7741929556783214361, 6266561134278568728, 13996537792746468394, 13116379830815883328,
+		2212637711439965528, 14217650183061928416, 540869510933311267, 6195450915592159668, 14904187357299823445, 5215400274033728644, 6907285779833076435, 15804222685871187391,
+		11124404141552478131, 15318338152189072517, 4067893425297764249, 1697503410612817642, 219476584157335935, 13106826093753036522, 13049745208482785760, 11832231199490391669,
+		10493328169052594634, 10627081887813813659, 11388663495964140754, 1823051796271862577, 12476400584366298768, 13709148086980681224, 4023418280354022922, 7805776130903851852,
+		11989040498741265687, 10985482710426001838, 598034896692782488, 12230542700168560619, 1496676485546951232, 6833695919100964828, 527254545105454187, 6276811762216173921,
+		9452334891928331309, 15207477416486363718, 8081596400773698461, 7528187414539292243, 4773782664413845594, 9435822414884353799, 2722451711480791323, 13642248100035410269,
+	},
+	{
+		16570512961992288509, 15784840936011612960, 17797638261217375128, 10589124475671334830, 16848440972121709899, 697679021479737566, 1456738239410270672, 7214966028857473701,
+		11434157439953722433, 9090860151661100670, 8407869262026581159, 17882547383849407986, 5277257988019769029, 11463853580825342183, 13607489835500075467, 16878800997498950751,
+		16059297404709367406, 8426877510924536482, 15269952608796785555, 6256768900860981984, 13142655793714702073, 14566340391957173918, 17147065283704191109, 879106195264399,
+		1169887957113173798, 4936710663791789838, 8029349457377894665, 3317691225106441967, 3622769674498678594, 1954144360900150482, 1432045977341997899, 934737636789214593,
+		3519438486034584001, 16935008858078961013, 11197550931955434437, 14100007087636813411, 11096181469792598416, 1355325916242161182, 3003143504356161310, 5855778258533244174,
+		3469569649879539425, 2734409579230557820, 11243101718460963222, 14449395552625174865, 2832531264658408884, 12736053595733579053, 8514265014627300817, 4646556172848350801,
+		1035318057221356651, 16671259128991069733, 933190532640544326, 10073090919720429370, 16298191828003546946, 89465711115503243, 1726024123088964037, 6293688775358665990,
+		9646181593082190523, 16068017411165381498, 13319927590045936565, 6113055520205251774, 5576373032696512038, 13880344501714804196, 12022206929479211261, 7387979357081975315,
+		14353322331225872624, 14137906560696321406, 9597841809127146330, 14479164716385450316, 18390885446667453601, 13789601367024187697, 10599569472420906075, 2183893278236533867,
+		17984045804937170919, 3008713646989855019, 11485907798025297413, 14380740919052976941, 3447658178143557676, 9095585806057103587, 698302327819557146, 7922185712178340950,
+		12592522203651044465, 1491459000495558958, 16988036704095888812, 4620491143241098446, 3378886739158384486, 4601357523445825298, 7994566595487207192, 4507705687201434902,
+		13553890993911526641, 1237937561304731611, 11053651340854998814, 8737874920379363783, 15414508226001886918, 9311523317130687807, 12080742822716708234, 4715194040021784977,
+		11413808093931937231, 8917864246709968658, 13554307490245863526, 2827250138133094370, 7637229863299622584, 6947884496333162143, 4815638417787805223, 10291803792760846879,
+		12634048591085853546, 14321728045924893987, 12328747445286182403, 436433860116637979, 5910966881246245784, 11478152401127002379, 15956760875311888867, 9580341487614973173,
+		5405380974793160831, 17240616607222875763, 18407061562244315632, 1777973921117407170, 6264824459040652928, 18267228171835175724, 1278124974392461846, 16099414790431742315,
+		17182132836049601530, 1486820395924546410, 14089047182364760490, 5375431386740917568, 2352352269256972682, 6220398075470064021, 11444733678216077372, 8173002234516562536,
+		2862732059898640615, 16485439906762588046, 8431038226899400253, 8931540904642954995, 792388953489761723, 9296018986570869365, 406447163304028453, 13270392174836298982,
+		7772216409762031099, 334915652033124323, 9705063888720244418, 9829080877134570370, 13800256788887079067, 6121678265481939341, 11747955988727867922, 15561904257519022219,
+		11919247213871390231, 15058232650937578711, 16509435050946309716, 4585646383560577121, 7109079914182671169, 11070600764446172401, 13212464399509938674, 18057628120939602025,
+		7896339057146013415, 17613745684396593735, 4238258305077796259, 15438639564771394288, 1482402451684594916, 3104492350488980260, 5195487229736262641, 1361150797580203482,
+		16473144777827648385, 1226441665397311636, 11587851779002173636, 5723433682141598491, 3818559725806959172, 9177247615754603193, 9531025756553277601, 1716800965379459594,
+		10276432666086031385, 14627452075834666747, 18000674623336885291, 15328386422432799237, 18139556051577750412, 2213209867616444127, 9597214736611625280, 2458176131336755868,
+		17117806110792423322, 15887422186644000204, 18208397717053970445, 7361598408210891485, 13818554723430207838, 12816010025806087198, 17883064936092688211, 1716893191215908273,
+		15949855327936545010, 15892613064802301412, 7776232754624386979, 2193423430757249310, 10751855334513902678, 13772090376350944100, 5644047706587449960, 370992037484721524,
+		10797607675141630710, 16625594903133516890, 4419277245854893028, 2258389314023537326, 16758443963306613299, 15289730903996513589, 17124263661185245991, 15862017582286958991,
+		12272869926038995590, 4569089761627301260, 6495211060884501138, 11124576322292919277, 18314798224925096163, 13232331582712038213, 4402693571738173484, 9384301049965683996,
+		9611026793910805538, 11152002731283498747, 12528844591327054806, 1485961507414531975, 12820893906402770618, 16248407567081091370, 15794078730898691457, 18231302945982292403,
+		16329953561108738383, 14553061366216182492, 5112198484879130320, 1893048255589705004, 11469678860036344015, 8992526488267920066, 18208245559304821518, 8980963391041920447,
+		17694621707784163170, 16317870945177246022, 9173265111786762052, 761657177655159269, 4876597178189658673, 8185879737091523833, 7520213092991049248, 6827963030155074898,
+		4104149897263226969, 1008830393844825523, 1692548451180187046, 10984924503299463085, 3526468436911084942, 18012043951628458646, 15181223987778535698, 18016160796635284569,
+		1524865955503524054, 7479709667052337482, 1064851658558537015, 14404181438374010311, 192685278892740648, 38546070651855709, 17006752915941498851, 7120034574635007914,
+		5783711159088718530, 3503029393593618754, 10736192136662142256, 15443859608128978668, 271805305647187927, 8244170003029416464, 17017071503038388446, 2536084345379259313,
+	},
+	{
+		11535283160083833975, 15102917952496589829, 12909095696891909745, 4611119212602854744, 4195756524232932570, 3754603965149529000, 11539276962358607816, 4401424391553230481,
+		6842993463058627120, 2708745114617181146, 3832382691810282630, 10333834458057320812, 15028197197004077388, 7681293343255119354, 16227537691626587485, 6703363869832495607,
+		17567108285065737529, 8693245930330183070, 4025672038042952121, 3491067119247522844, 2100799837993193702, 9579542950705774054, 5091525285265581997, 1806757015709820088,
+		7757354840118131559, 16227348978414023262, 5800861674805516343, 16486235803248700961, 15646700163023677309, 504258765210816549, 13724147899924699697, 13588899538317277096,
+		15895596198730294923, 12513494396374459899, 13552575153453342654, 11312160635199213507, 12446618129881485796, 11286186116805515445, 1584191291800429567, 10188741008566636830,
+		10157626021970320469, 6580688164585715207, 17158416694471177787, 2873484006255074946, 14852216457444863041, 7463041347566136496, 2190030775722958628, 1116223035803602728,
+		8598875756176012541, 2146658618778432566, 17575736667490551813, 3602654209723135985, 7223347129734689099, 7256921024940026570, 12249118963297692963, 18168532365040819099,
+		7585174044375463988, 2491923406404093282, 9355733262044036112, 11484079611349577325, 13145030009254943291, 1234932884591406048, 479845670619308618, 87735010308690865,
+		17307641427543377277, 5862898330718319545, 485176909118483750, 9845223919324484076, 4293549583740204024, 12765124043303931186, 17870894781132657382, 6508172378961793849,
+		14234156373312856400, 16210939788814051708, 6478880037923038392, 10435512103812909561, 18142844321802359753, 3243996803126554757, 395603619159523019, 10213589535656704607,
+		13256075137060741204, 991285459654295161, 7857174835799942102, 16201105040554625727, 18398612085349994216, 4512860776717176840, 3521452275695011919, 10622137733045360311,
+		14993897771652736376, 3320388672992783302, 18421556740970114213, 7438967127794745135, 15048397725789819354, 12721899159423777001, 1135125102123667189, 6637485660805148630,
+		205606553319362431, 15484041062449893984, 12896720585684759529, 16675624014916513672, 7579112430564108390, 4602460356900251082, 2677787525524280838, 16723483619407414479,
+		17981939084373319995, 3989926231875116241, 15342509934701840045, 12999252495311233519, 15389919024942778009, 6136335679373143315, 4117381415379544275, 13342256463740646775,
+		7622769999043907199, 15227992053145045634, 2719412067263856950, 17811161335980566241, 15036003689029442301, 4919601685231030712, 6756893600905532338, 18029567067112075531,
+		15804957839814547154, 7924193945337173678, 1080401129055171214, 10816444561878528576, 13171610473229361771, 8099842733764406841, 9284741070210451667, 9245195215372025289,
+		7352706423771400643, 11698139248518535945, 12836997796963939813, 5747451345763534394, 7572033904536738295, 17752330422795919668, 16404760947165813434, 13477251724246705199,
+		13700661979310397040, 11172816633936827025, 7087232997755437759, 601317374152115944, 16028751590837491967, 2749566595186093629, 4445248645671399873, 14714182958477634997,
+		9630153311383545953, 6436885924177487891, 2150319761793765423, 3799049242167098053, 13902640603080497957, 13121685068446422901, 10099985117244683905, 10692630753099650856,
+		15680946025356791729, 10935239212262708062, 15255596602338430716, 15502989798538458360, 906862139952472300, 16128362872146694687, 9038121313842477036, 18304772087255114926,
+		16961332967315316395, 2872796507989583018, 18145413156795763341, 6377517922859730669, 3543621377523624979, 10701607653242580646, 17747200374013876449, 15987594633077120628,
+		3487728992359467218, 11271201736509774853, 5968332690756574092, 3519182420015237550, 17144214368301394415, 1805926423542721773, 13696269518209159134, 942126126861202483,
+		16211326119697754410, 9043490763746629445, 13119640043033532883, 9720862297941999125, 12662669665140843415, 2188499520755532048, 2671631563874698813, 621164898587943254,
+		4804461736506692241, 10698651491947798952, 3524135800884470917, 11451653751986650957, 10424912129082359813, 6912080226482239953, 10357808719970986526, 11757540241185558439,
+		1841157911016607198, 17522398974331009019, 17392843956059453556, 10510758656389762948, 7666344868273530034, 10739409534839380580, 18010518965344703872, 14478457810678500914,
+		1617286442811984718, 4008909641875477702, 9328654790542709745, 12015676532404599710, 1763241944305573436, 9348325841675336084, 4072126498552363080, 17245688939115723821,
+		17277555838655940279, 16604852268187595492, 11674181070138727191, 9847423407697994070, 13562477602392929772, 8181792789545038731, 6999326623175714057, 1227784795779857129,
+		14923095901189736698, 90760593075377861, 11732533481504731510, 6000651333412910877, 7847865090059184838, 16859539404919901595, 2709105957383645337, 10263820965340474390,
+		3161036642361826348, 5744405044938832483, 8939741099437920817, 9766097724147073614, 12117283480449144394, 14632688836103128438, 9491651214417380913, 13676064073123352224,
+		4673738700738845848, 2758750364605631228, 16596306154038523740, 4124917668203310922, 2170509910405778957, 4178077301639210933, 5109055439238993109, 9627760120514410208,
+		7259236533647228872, 9608619771663043870, 4148523959415435806, 8831501534166306825, 7919036824652396994, 13625969543100731176, 2546426055029800579, 14852443398434563210,
+		7185947197544988797, 13306809398790059447, 11440959253278285287, 15084384140482244570, 5059824327869316332, 7585354587200615362, 6801884469610571467, 6427162399794357267,
+	},
+	{
+		1453348772281274490, 13028088570940491471, 16100623112750251840, 5210244400259879874, 9443916155735416174, 16869520919318450506, 7479400208826706574, 14374970913352602458,
+		10149597276931117465, 5778043705364022356, 13888443605241209218, 6889225091714429810, 16209363638493043975, 8516350006446457646, 9214830076046105138, 8894115046323798175,
+		13026208197163596446, 1935567165776196957, 17296090833026336866, 8461284827078097590, 14545382879887213077, 3302103559307506085, 16026840048628844803, 4599071908983273604,
+		16375505785562641226, 4903074653735993511, 10355787845763031761, 3188849033041803587, 3145147452182864049, 13878747873108378466, 2798650520315922121, 2325962694441538199,
+		3587824003578414733, 14942115314012282784, 5312737955169054323, 12478174640832111702, 7866537714619856949, 1076672758151595875, 12163513815501875048, 8343003998956997868,
+		1392855790923554429, 928317148609633070, 18064469091536763974, 13446092366984636072, 1975222540660444795, 15443703204026028192, 4016450768356916736, 16656367700821047808,
+		11505659892372808762, 10322665279031813234, 16948868760451861492, 13706671779256832515, 1968671033447691229, 2446599110590827903, 13721045634744350023, 11053432744256776013,
+		11530583608023224967, 15979155166527001287, 592931868138800645, 5361781029549479856, 11246418752830406096, 11882251984248471436, 12026389461944629423, 12289077922798223820,
+		7685868633977346753, 12528120620943035447, 18394735788313062922, 8523101916703102094, 14261596878655792929, 6364753027040158382, 6433482955677830548, 11538026548937002170,
+		16221339092185577802, 2285289075757313223, 1151823739515800834, 1010537560193450047, 10651328720714490261, 426599792903611671, 7181136719074122463, 15350479907287263858,
+		7559201271967630136, 3561344874280275357, 16379496429080959327, 9662226613694502966, 10995850494788192620, 14875349277152338391, 730989400822814422, 14352408679782573731,
+		1328339467113622233, 13374824154992864223, 12057132015324007824, 8507647484414695512, 9286016370798146986, 9083798709648036612, 4312959727577073260, 3732271624824420608,
+		13007262390446754395, 5631627784562092966, 2644488352265945851, 15340614364643014664, 6692152810984634488, 3903120388658969320, 2513009101887784188, 11999681442010831364,
+		8301343575202991577, 7108394080005777057, 3477086484634015274, 8772644795325835021, 14747670046873500269, 11068536909552811695, 12349879357573378133, 8898863927320049679,
+		5231654281125841638, 5181061730027800171, 10657176101406080919, 2548241936122768256, 17140253194139059526, 17961047717804458883, 12407260567549658707, 1464243167234637194,
+		14129872794455315922, 16354810591314135702, 3177417010197743958, 16494351130927698692, 16557765056328447818, 3139394196704738651, 16891813998271303650, 7374470997276173905,
+		18244279644122204437, 10097660526910786400, 9270181538098732492, 362243376823712218, 12369863141977485111, 2550957813014523686, 7768963959853738595, 470330801228165919,
+		14632133560934390222, 13844843545192224059, 12232948338847787315, 18223343336729121487, 5219716370019749202, 2729037467284418866, 4546118556621109595, 12191675540034649671,
+		15868991745937371466, 12686820201922367283, 14799186526268126508, 1241626948050017911, 7080072468753824165, 10793537086099229143, 7855065677501047369, 9747396305344084667,
+		1547814412223404746, 14194709348405912167, 15771028929623393801, 10945048172868684389, 11234483878611528405, 9542605377580701681, 4555391547268120796, 14916872217451960022,
+		398873176015355134, 17609838001051405497, 3752252377312468061, 10441993652683449973, 5218696730429184844, 6514361533063264268, 16024112124035725701, 13453525984055386124,
+		3452753233449684767, 8937677805622461008, 15346651759545553711, 17055791435062851045, 7025089132368408239, 7345356702153522862, 17760529714295220737, 10772604293313163303,
+		9940223451501501487, 13671810088603813912, 1432075826781639138, 8145669182511487125, 852664959675237493, 11640273224943853609, 16220508798123490173, 12787926729706993802,
+		15490131882364039637, 5140304620645573547, 9403655757498826823, 9824850954989176893, 6366139388903157264, 1981838834216345294, 14659870286877979556, 12091578124492612524,
+		9672198938588933438, 1848525214318852627, 6500329435429402369, 8547555101599185897, 4282139019453982058, 13391782461875853462, 956960429753408730, 1865393350316759140,
+		9155847368519787501, 17397005067762861574, 9943535970799289809, 16365250691105460494, 13595148040475375224, 8300668237654861875, 7149654787413440141, 9226755501324961219,
+		9359301870380673800, 9344500253098672841, 282669288080771734, 1996492472861301505, 4777949892950526502, 1374151996531969836, 1529729047243522545, 3371309923165192567,
+		6832171775190531128, 7903951882621813138, 13717573220828409267, 15400575122727850054, 6101307565293576434, 17226772767105983314, 3485283905347036760, 18439321272895583847,
+		5095761409418784463, 15484673138064200869, 7743962634971666154, 9119597914470879266, 17978461537972396088, 11490423388734028778, 6537551181013090408, 11706370534703673937,
+		6635008658379780815, 11428304571924124070, 392068559161657302, 16314310970878215293, 13769492864572584674, 16880907685897496637, 2877983831559338706, 10391660973242662710,
+		16861266984653213659, 1968749328591656132, 13301499995824894911, 14523175695360471336, 15130688872832023531, 1794208537894703529, 10525607764904270704, 14288604199111912452,
+		6289130721434350290, 16129337673129720846, 6648351866142453445, 7705983837166554199, 8120136556582544814, 7924417299222764443, 7821995671300500892, 17697662726179084739,
+	},
+	{
+		14086745261650819748, 17953107869776717888, 1777725846494438428, 2765314406831814212, 2603997194371852991, 2223517025105045134, 15579901335531749634, 6571733615332171148,
+		5478465698516556930, 287443454357750768, 12201204663663129285, 782849770204658255, 11270045035009204251, 18152683972363144337, 10463300037926642739, 14363641589598863851,
+		3790592075869665284, 5120320091554329756, 15361581282394028709, 14360464660911164915, 15249656958991931940, 2563751872827049233, 13745792006936646733, 14572943674933168173,
+		3167679014977537749, 3417445004776702290, 1709246158507866266, 5861367897285174360, 8437429877561342262, 17231607446243478748, 16047596399306766948, 17656438585829685897,
+		12977336347094692192, 13723871955002954132, 17399919575273038847, 16163973860244779675, 14997921584659740746, 6543247361992425067, 4675926398794487109, 17580512382853194054,
+		10778828023580771765, 9812611440536367405, 14168149065325522570, 6692229110872358750, 11010962724400581057, 13055203605065073902, 11396463140731730116, 16969789651736772232,
+		3285258013801327520, 14114268241282882888, 5367399533198476395, 17277410244918727028, 2751895479568588421, 751309667192066167, 13038472116718581917, 16013586354334596135,
+		12364168614988940500, 13194367252463423118, 12223406606527741280, 5014139294736037086, 11244699482831816093, 5336498572491451990, 14268404582568856142, 14502318820969599316,
+		13295673091232554814, 313981772853781347, 11829785736449464030, 13341198421333360997, 16787450350663111566, 6525407229623764159, 2012189087039636323, 2110887590404698758,
+		16984895766311549717, 1057465499230843916, 13565444352859773343, 1019268943988786852, 2190009140530404855, 10045598732295352970, 4789803496780829836, 10700158388954091321,
+		14840255112988420500, 10066628133368048408, 6527354835873855384, 16106607076894419125, 3989024604987083046, 10713316697020150694, 16811389107269552264, 11294596059797019619,
+		622403023838932676, 11423409007234191765, 17086830255702454786, 1213655124481948199, 3976593910085142945, 6315875935390432543, 17947502153968859628, 18031540937011531543,
+		342675887578148289, 18366454547938469828, 3853530442390999217, 7499455395579634652, 768597405171336502, 1636271570683567151, 16786205337983572309, 13056241332863199715,
+		15991153618414855143, 803325462494472241, 5709347424437559249, 10138502962472290727, 4675124205115228106, 9599016746550345197, 2769443894695609085, 12311020551315051087,
+		11470964304318784059, 17313372553735202469, 10686997186364536871, 9228453594798060121, 57933324335302024, 8931389936300346353, 17823596478938529898, 1126996688113949835,
+		10457697409306668434, 7830477435299250296, 7772379952622394912, 6109610138112185532, 4382803614711332911, 286231563340803504, 14408860285425706036, 9445290615796219321,
+		17536503470234411585, 10755841521760916925, 15905055604395954066, 10842889504280336728, 10780689817551616331, 12490302644719656914, 14399349211478895553, 6458867531104408547,
+		18263696007238300109, 14344529985676987842, 12351733186419515951, 14648750128188787544, 3817061805140294292, 13460439592176294955, 2651602395003150964, 17613970291099197676,
+		1107162420032075035, 14270134754120385897, 4090584027509443635, 16066949131129832709, 10961641187652236678, 5480069976143996625, 8549185711954755645, 3125346629140152790,
+		18337941236561689695, 2899707239319273137, 10519944305927777790, 6913088845356962577, 13796383125935684169, 2756403850320695444, 10018647980137529204, 15185795467001072323,
+		678732289042224133, 4682655677430115166, 4806112367076139288, 7101473987708012826, 9907594813802528406, 5572757906434657546, 17819688309930892783, 8734990255058630746,
+		4831187103439262344, 8323117365987697459, 10690753367486223100, 8744079000061869982, 12737295198832254982, 8667406752954112119, 7942221205780634447, 12612313636795726189,
+		16544756691464009983, 3413196415113664237, 18442955254149959801, 10193439941306925215, 15178607176290875326, 10962146035584651400, 11757614026658646304, 16241528460556234026,
+		9593194029396792148, 6376573619820601945, 14694667798662125868, 473733746941891591, 662607401339043361, 12105576520816361855, 16629740468317868384, 12416206001206121129,
+		6655696780366945398, 12313066500177107654, 15308290012322636383, 2159880960357061128, 12374858353753840133, 11331956329091160239, 11794840094276473821, 14170553661155653327,
+		3336445037682266403, 3746885541049520962, 12688476435907418892, 7399089272376853858, 4625608774712059624, 1535040330210000507, 6878676093546636363, 14533846142831376645,
+		6250279356724130049, 3901672557903829499, 4884397030724371499, 17385695093365573379, 1240675257703364805, 9703149291204612490, 10295741452056015824, 7249917314998921510,
+		3336800790505577062, 319907795530586958, 15852045830964927276, 5538471989976998401, 16558766045222360422, 3135574045680866961, 7590873965560972285, 17191236425969884848,
+		542161999237385999, 11197034618748267807, 9595673564043235773, 16351524685431643264, 17127456926935032059, 15448416181819692483, 2035065584045934249, 10976830957530152324,
+		3230012351101746458, 1662948417350421518, 16062645290454019168, 6021730506322388306, 9903225699788133023, 8549278993611431648, 16267339446315716903, 9759051179942016620,
+		14281696762614162345, 14970002486407845832, 14940104843292093805, 7021313216295048550, 18131586729996841512, 13957742754718859034, 14322894803959804982, 12861731196696133597,
+		8838210194055479741, 16190279688839291456, 16520121358582757556, 16768959728701970634, 17279896910204983538, 3582816187015369256, 372137484481226748, 12972230207718993241,
+	},
+	{
+		11480031272463364121, 2525856087688686375, 5875255653057452580, 5606696614467440464, 12094715534218447962, 6173479337351577758, 18244015404482482803, 13199349349511499695,
+		6097225965006328457, 2630336000831717722, 7049638698786526134, 4203465038263485233, 4677974565964393904, 16044036678123636261, 7266049959100300634, 11339674070148504929,
+		1979992348876614621, 7494083465935166973, 16035723662722831744, 6820849908885211777, 16740735239901023053, 2017530162004533409, 3087262288875984227, 9072904925376793991,
+		1830819081327272165, 11951292080860646547, 18002500803418629938, 13317986695217403840, 5005574200470766330, 10138179785738652504, 1610518863105278224, 13309443265578956954,
+		8383241685301818332, 6629521234420338478, 8997316634951392497, 9976633096395028594, 5171570735720385772, 8129153749198218776, 10596302915145665067, 3726383961188926740,
+		14494271933981109919, 9056473564311980628, 10557807473422306929, 1549747977888697589, 4534184223615087698, 12977118933167042558, 11930457930026683843, 8346041661496792064,
+		7756665146227128459, 15140824521273386708, 693427108108819556, 14819189462601222526, 4507393341357475468, 8710020646873218244, 4535796033535410044, 11884504632761707946,
+		14192194428653714479, 11578618567931657764, 6032668189933768881, 15981535562386193924, 8925792218631314923, 9408714146004183681, 8859017894477140398, 1675606340537058506,
+		13447287279335601133, 7792625320709870803, 5347956615552953057, 335662974452886013, 892825083599137885, 1017154417323307505, 11923254597349925339, 13818364932306372202,
+		15945578153358602744, 6304522416189552358, 2545503746231186920, 14563857419242252397, 9711931929315762229, 7949505077082864287, 8780199792032437102, 10109661610848827442,
+		1628958128919487289, 9818701341087940523, 16480240737841185501, 12633108361335093100, 7982147509828265471, 17959437456356197928, 14370416793872407673, 3577532534573396628,
+		3265119697568866078, 13753322853248061974, 15435163376825672274, 13646180516491714938, 15620545622955090250, 18241486585498394565, 459566729126467878, 9728217493753855944,
+		3187267754295885454, 7928049460349917700, 737484733736740002, 16459695106656291329, 13000947522838718027, 11933371771659873912, 4720706464557996274, 7997020276574823784,
+		12655797542121172150, 16574741514838026101, 13532097913031715162, 13578832971779600350, 18171552525916232035, 1516234640889581592, 13625693062693291889, 3869929504544890755,
+		5134589228918179333, 5186584327613952853, 4114726195152833642, 578924708883784650, 9128473117392713984, 17390547319520768186, 15077700332150016764, 8707446714183162237,
+		9883406233903270985, 17184231210468300584, 5498903678702785900, 6903833261382863389, 11489138095102981636, 9021901931786177471, 3227433089132150317, 16639455550797627042,
+		2873811051246262545, 12759149028054319339, 17920917684786397179, 2576455203420292139, 3181713670456310447, 1109589489775958300, 8920119044838278090, 16056330702164227666,
+		14277712977137303378, 3896132440952049994, 13252040000848248790, 7844779060499908154, 8651912177362107995, 5527615699397299219, 17688189207278018869, 14560189235973121390,
+		10861951673021959044, 16820848382034483641, 6761027571816469843, 3555385088072119757, 9363319138244920099, 14172742116400795253, 9535965929584057049, 15628517769546199992,
+		839045372102318861, 2032615141683118500, 1921816835840256924, 504869150737570005, 15932184001422473505, 7849475855313305697, 1189994394722618598, 9874798350548229684,
+		11973862230325381876, 7670835358390713178, 2113918814334481709, 2289514490388170400, 4570586695077036349, 9449360682811675838, 16506880875578470116, 13723444740920888736,
+		14210428465641691143, 15330786835024186142, 14173742373807858721, 15041216914246450688, 6027140311333696225, 17929849776014561356, 3955935517651718925, 12080548003455651805,
+		1974142217308765297, 2347591555456293560, 9029256828390326937, 15561672734848339972, 4719329765359230610, 1924866103348851009, 4950258359754995181, 3245952633715281425,
+		4636201671610663345, 16662311204732135584, 12398897461787695675, 1355753199357412657, 14695655628527768564, 1692838776852698754, 7346906782826540912, 14869028424564984700,
+		7242751356102425321, 7770223857340282376, 14976092066160539655, 389604327668352376, 3472336298605227213, 11456496863560248128, 14597769228654187922, 17838672631901123288,
+		10997764239928568735, 16648935573721932916, 13735964592293716412, 1364388817619955667, 2511134998006929958, 811167458534120344, 9371523327214092569, 9359553283016173792,
+		15311627918891973770, 17170652974122329165, 12620036374776436604, 17439165699070911984, 18124482726761033947, 18390083820175794165, 5492125340791896125, 16506113603670143446,
+		14240080119980315297, 4751983902385717684, 7941412103662252178, 4796803816695225123, 9327986654018000413, 15111345676387005726, 3582558555283734415, 11913156735178831102,
+		2000999613038609412, 1070613390669459171, 595743672188217500, 9169968884291187666, 17960105939867090032, 13927107353795575459, 17872593051171658925, 11087013461789649235,
+		2280207936513065312, 11704149285124951522, 2138093032627822381, 6816805886026674440, 12141709925796155041, 12164596600353477920, 5711177504477877148, 17211856235678509153,
+		6061025098309340877, 4060747063380827182, 15186975689243681841, 18380882388949786706, 927262408801716090, 7447789770541113239, 14074172896745727729, 15372475239996145400,
+		12915868875134296756, 3071143582305760275, 10848717856747030010, 10973183887638314967, 5983269487036236823, 9885184706933333413, 14509493669845681951, 9669608065801379977,
+	},
+	{
+		1190044221726873109, 732025666411072563, 7781096808432277694, 13079879637655900365, 9048680577986693793, 12528346194104542124, 10575369576322629835, 14068913038053465964,
+		3297775431071502652, 7947266993949467566, 6161673381820779563, 10604626734847205996, 17669018066064502925, 2386071939136502354, 1076023928806956187, 16075459682742916440,
+		12387028018538599950, 5791681577936683396, 7536922194386052138, 15377770247350254336, 6564316170002440575, 10629371267149545956, 16125760269901494382, 16051398044897962024,
+		6237354803374899565, 1782400080026955610, 16115027077529639342, 17907259814836219524, 13179234383592426160, 7302978467158243198, 13607720993463749225, 6693531817169120736,
+		9659467198848065929, 13765104107473534739, 820057324758632016, 16604163594878267405, 15321524555426147294, 14524167419333362957, 157291234996957911, 3689488130722730671,
+		13896531645245568605, 13598412639648980920, 3875086557856143664, 9242105512956135595, 17410265178284161091, 14904754836127450463, 2354327747158525902, 3858493849578874654,
+		17288438225198818690, 15275190140700748774, 14532856272428522409, 2192294551011758591, 4275966798014984695, 13252812474545742114, 8604705074440591847, 504054699541924162,
+		3623027910997185067, 15957466839356832933, 3504133700071704955, 4135728439139397021, 1160600455691338871, 4431928072859292239, 1542956305318065546, 14109181184369694855,
+		9135041378474229537, 15626265487594878380, 2645257479784082878, 8105679948445763432, 8579715781576202730, 13437359533149316300, 4344754720520585005, 13326372852934103673,
+		11341622086474305983, 17104958945811183278, 8154944722722765678, 6696975609844549775, 10895966360082878017, 2277686037575837054, 12236842881540344526, 2086470279064067791,
+		2942668817124399651, 11439025398519255779, 17477264434671471242, 9606507094132585461, 1771475584689465869, 10791261379080046759, 12901998265727968789, 16423426725595035468,
+		555419805011031621, 13715683285513290290, 15526654591995532751, 7023761423093873354, 15093366433178982304, 8625749648874372840, 6412297471587129206, 12161114204724955762,
+		9362623422820895267, 6491356159483508885, 8543224082493101588, 17290929683278258587, 17348088672546490894, 3323350644823701753, 398525379151271104, 17794417664139368677,
+		5880914635028486784, 2898124605786107494, 7953506026198179840, 2189477357380899574, 11207122442953694293, 9288539232660208671, 13527697625010979453, 448462453367651162,
+		11262205719433170585, 7539606872920196479, 492385789142086954, 16036594120332851267, 8084547797138041354, 10063336189771527714, 2484395715469739911, 4879298610504146231,
+		194633990068625151, 1028128699653523895, 7436102537486268753, 1855520454959348468, 5098690958966904466, 3342676718901330604, 6942212660412942406, 16510188838209674083,
+		8847926418142642416, 13342814936333556870, 7082971165114489981, 9307541560233171550, 3013250253632606412, 289291445038948658, 2146586262066552853, 17331519863134074479,
+		13747350589043267381, 6342477793304440894, 10087817302474912962, 18076409030930122816, 240893790090129194, 16364025156922886538, 13518167316464590136, 8034023137744309866,
+		14013962864860194917, 5900268096329749317, 578665371390927342, 1407477069341362927, 15142181569643383319, 5217173950329651840, 7999234477517614232, 14722759409199120103,
+		857809728583972424, 12785911478120621636, 11351522624307635957, 6288237507210579634, 15030282678317951238, 5521516375915920991, 1243458350248005764, 3567973108073272461,
+		2834660673354035229, 10728451420162645120, 13396052377701115268, 5730788601228223475, 1616452754395208882, 18236419625072278846, 1179103743668306981, 9179882267624091153,
+		14087439523312437665, 7814060325531094731, 16777382811045908592, 16916500419494378884, 16312259370378381991, 15848836870251345077, 16352246673954213424, 5228629139249919486,
+		16889782864065172884, 4486233301301317202, 12424854171669138635, 12490430652425390015, 17335301435940798099, 9685877269515541824, 8728054940414220990, 12781228698496150916,
+		15949574575791239459, 10394047428873141717, 15915386168603191086, 11400139144838475744, 17198578050070482368, 10505386377385262682, 11269920026804647377, 6796664536515856824,
+		3285292208372623455, 3132524240856145976, 9712372580979649457, 10523781046601368064, 4797168047433466290, 11748687702182632788, 4177442610271848350, 8549047039673741703,
+		6897143822689085584, 12727238507037725105, 12692443686524496083, 1187606781546544862, 11016254758711515442, 15622643445771261724, 16669571628491989170, 7099030384210775042,
+		3541342827520921014, 12596176563952906070, 5209816272233406534, 17158219989390045881, 9096207539532607151, 12291463442559161708, 5188945441827912424, 12721126884401346746,
+		8137171114112655022, 6980210601071561830, 10156197453074241467, 4481350962546197264, 1902625885079226055, 18310954340184922140, 10624840172920793227, 121304340390125189,
+		5261036238619130144, 1418912875050883205, 4741122621962383610, 17995804738511375239, 15493968366750472633, 8417505178158780382, 14685111207483504618, 9729483826733360559,
+		13434828863770210135, 2940287993177646896, 18241509923298296610, 7613631401252601295, 16815829390381900683, 8566309323681786413, 11094402941539790077, 8442864581771174862,
+		17650059733379916650, 4260524072883785227, 8351659371377110706, 710338300032970720, 5512358883882849029, 15533759462039713914, 14352344066268876816, 16708588250954382269,
+		7963995066277321795, 14986230345162551366, 10616366460602472778, 16186943329215681149, 9522855644164647723, 9858336437877021178, 16344942402271072884, 18027353494090590022,
+	},
+	{
+		13175608910844763921, 11168387468381338510, 5555873864224342205, 17780559602571640345, 1582669533588472814, 8145133762789622706, 1625372887980692455, 4576809104068554285,
+		2900978533555060931, 1749946807863203576, 11705734511931072459, 4446980691693419424, 14437524160594907241, 12795912566640000773, 10400036254697939154, 8356113088668925361,
+		8900726473285671992, 890209742292473781, 16059468388719373167, 16577940938542233221, 17381766864962227733, 231915274132518769, 16477817024012878700, 15646021286310268545,
+		17511864284462479051, 4391315454785363822, 16633389246499252566, 4290325975494843430, 15912670649662225191, 14172733821603328367, 12709802627494541709, 9648238681838878635,
+		4196883387800999444, 11261069840079702254, 7135968036494594517, 14537849011631244070, 1930221875891546479, 3029378442249928630, 6219774718328347890, 5922417028077454069,
+		12470404961188516783, 10420863874252801995, 1369334550763670666, 4781925915058005676, 13086538845357988031, 11031029468188842766, 15252022305121561855, 10497770692868889659,
+		8808726441417268278, 8201526072266158452, 1136378216494101481, 15014143365043073153, 9752793532008788265, 18423606089906807282, 12708377698545978413, 13697405528655748691,
+		12840624483048662115, 13614226123606379619, 15087571995173849344, 1395488309690794621, 7173958427217959878, 1198561064176820332, 16821886260165681626, 10019479169661217935,
+		8089335244564816024, 4652396396372834438, 8473523796721514770, 4493469844513366216, 5448577418901909194, 13487502520341193870, 17978888920023381084, 13125222810420128122,
+		11369140159803973135, 8391820975236191093, 4865145203995472561, 14899728882581231165, 11169032718524058736, 14532440521453562763, 7464998467530340358, 14981246381757614771,
+		1242992129726403300, 2014928170416925311, 6341058783517690890, 11690291498253019630, 15951586247597589423, 14033993236702971559, 16963725291567059464, 15075124616754319226,
+		9901328250515532535, 12796305315632203942, 10819069447660403847, 12542238242508661240, 17077777737462854238, 4364294351375777648, 8335244153165894685, 8863541604979427311,
+		12648774127830238318, 5576880401343711606, 11786867566889606858, 7421038047404952574, 1037620897405863409, 16680872357246325645, 10443290127564886223, 9718182896013830581,
+		15199007294286606824, 10225517367964809030, 12827778649823141649, 16046039393887815140, 284741135347255597, 4015036609703147909, 3902771329647468314, 5128707935422024078,
+		16953148044626345363, 5101833106541998042, 7655361325113312133, 15948906743291877728, 11619404274756349415, 7521254459857915559, 14978040810149334918, 18392994517091959591,
+		11029520456752683158, 2297291237551781454, 7934683676555855479, 1563954733146546128, 2252805128528536255, 10523375695822939112, 4598652721256818062, 17493379105069761435,
+		1717382065475436420, 12444276194160330384, 3605273785657402256, 17503422605669121015, 12066457002913396306, 18109827202111882684, 11555238022219952400, 1993655497207863497,
+		14852223665677610379, 4743851404709775958, 8525514757892437524, 10402777181498591725, 17096034999928466604, 4289543339828736175, 4306145672261807290, 15366124999227707930,
+		9159996652502914864, 10301349423202296392, 13530090903323000632, 4082840779249202050, 8824726775176314063, 16033767772359951785, 9181204573557660412, 7582747879080399183,
+		2747551692916263132, 3151123035150683281, 13938314333309683791, 11970864255483579560, 7894236725861110998, 10515613623232567716, 10445557830757066839, 11155097727742050955,
+		511773909731247800, 2463012923954369656, 15859141716591041471, 4940781664379556792, 12435624343534748284, 10278084527750129328, 13178135781125832492, 5930328346313533490,
+		9122100956633732655, 4007876149211873275, 8339438668849688737, 7791075492023424820, 1771434463088769532, 17441254147665904787, 9470298561063283873, 16552350513326886351,
+		2842235074681099572, 6045955093828210410, 12534027406207583719, 9023829328537353058, 1661393615224515538, 3265308219651631507, 14825441620546235307, 6190486519065164472,
+		9569762631377921701, 10341967309273270300, 4697570564829842013, 16684762125903667303, 5281929071085172097, 13027961546412671127, 18398764602992176314, 3872796039504642974,
+		3625046733403850478, 18072436321985678348, 12926724831909767455, 17260889391923475120, 2205546675974800411, 4823605748727161314, 11756378320036258430, 12725625915588142865,
+		3620769638269480452, 531680461898170, 10213227252513668871, 15446816035938502695, 15189868868814686765, 8689079054027125562, 10767300823767661010, 12185259819280811201,
+		2954211398425891878, 887045055614004603, 17024961552904496644, 11183183814128062689, 2275500228939836642, 8454621353771976628, 13706050871317440521, 13152782683288296426,
+		5035609627965208105, 6338722048255995169, 11594969687968475335, 5639340633771742838, 6928934109570365590, 11589609913085167707, 18353534295019770247, 6879412911232288750,
+		13223374340976842384, 5803903047180226505, 10382392856292138950, 6807712794865416975, 7273350714698980002, 16071615116869102753, 11130104866208195846, 17099222713467268806,
+		4288395624114587260, 10186593737807119648, 5970871638851383523, 17274628153010076591, 11083355019391773968, 15571651381840416650, 7269503864920933911, 34314525388851272,
+		13518907013113787435, 13799188114963266222, 10949327997049617616, 12851874981220611149, 14245323937486085594, 18324803746062213911, 13224741762315864830, 15910543010675195930,
+		10042008593756684008, 6713471518385846030, 10961845838926538977, 855334359173719954, 7598642325962297361, 18006511265377032901, 6844179774752820363, 248341098560552116,
+	},
+	{
+		9259451175701532574, 15597985540941612547, 4541553034987877619, 8927802479718285609, 14672230714928802576, 14284617950605306700, 13339970812390782046, 787078889494395850,
+		18165439414433063919, 14693282888419586094, 14992616289789993230, 13232208150801553912, 16850347485914337693, 223364064845089224, 7302899015436300563, 4391216311540396088,
+		12558388403188680537, 10687978569513354810, 9373570856564649772, 4079327722512691465, 5372437374337150740, 3297421622932790851, 9326853593823854687, 8305371884938201251,
+		13121472331750731303, 323745485980480220, 15110308702528119977, 4696302365805118372, 9859094500834571602, 5315656270700787939, 4187063204400651801, 1695695129564818327,
+		12817586844019849804, 15425488216915741929, 15293562913126043054, 11770898970765978555, 6806103820345670787, 17789094149138630459, 3807781571713999192, 5823254011289457198,
+		10112524230916015604, 13571143908656270599, 6031089010487808103, 5774558171390644848, 1808959243244841573, 14071312530426692155, 9241399242704553402, 9836150050655369231,
+		14083007972403535491, 16009534514129505275, 12481249112231139039, 10309390659262581143, 5782517315325366794, 16717384553294759530, 4578392002424884134, 239005024949492645,
+		1836857790164349346, 11263074778654917115, 4786985732596838094, 10525445084936097674, 1484357665966453236, 3110871407036679558, 1668700683093601768, 2736269131339849752,
+		9249362594190920246, 8088172462140746331, 4080107866285682736, 16205599538438551353, 18312943145606312277, 9100632964181080418, 3969991115337154345, 5340098959750368315,
+		12122448407048035645, 2891250339380982359, 12794212052932523400, 7166035112141500392, 15777441312724841162, 4552528682229856831, 2210391301762911476, 16410254680957321386,
+		6910044784455706429, 11951245774670922855, 207795885948948810, 3884359690300962405, 4578772752480772344, 2948797025787714138, 16774444535658202808, 1388183483009000463,
+		16561979129019905420, 1881862411760441386, 15441950514711322010, 12933020223458438856, 5570341451312029630, 18172638959728259059, 9074261777549091198, 6171200053222754816,
+		10126435102176037237, 1545112930055760251, 11563139991870561593, 10766754172364938834, 5116781688621052838, 14471715119500781375, 4724882615229687192, 10031687030722046325,
+		15016829467434780812, 6777508689306592732, 3811682306063049290, 11475361222871876387, 6080948654298953274, 11612742274762615033, 5268311600240325047, 9147351973710519861,
+		12130203770930472759, 3880998309361490881, 8807462332494735511, 9291388074337055133, 18165312304248982432, 12733144434841535979, 18090195697688236271, 5825342884125782172,
+		13034385644450400616, 16498936039876211302, 13019014556329727588, 17911110193068084415, 2034190024798401134, 1526884555531436223, 8108814142164064795, 4075908755148182733,
+		6404489603451030675, 16601749455344583377, 12907740667428956072, 8446383351289364752, 698035388979141580, 3593914367189873571, 6744392605914028800, 18168078953147292456,
+		14484703498492722699, 6030798911934842161, 15931002029256202288, 13491601992324491240, 8585568434702372483, 9113555433818303018, 6375455514164501736, 1476639189214882947,
+		5209683814158663472, 16895526973128357178, 10457488910391635027, 17530003042232440701, 4030542539553991812, 9445656287872984963, 4212489101708176016, 837886727556721620,
+		2983790309644332360, 11276772732994425347, 1310621139116895737, 3131558545024164284, 3529698629777893989, 13271773334458143370, 8171825923423406479, 305718858162497191,
+		12347543988562572522, 4315642616923374215, 17586477762860427847, 1037334149869395772, 18311071546005132724, 1489505092175764848, 8926409949339059078, 10260307609945070716,
+		1253128470325829265, 917180526219408600, 10471425074479693158, 12658678264459355332, 8502334428811982364, 3789675096428271759, 4531393894096863308, 12176495757901795513,
+		15081766794595471636, 3944913291385975654, 14507832069904091484, 3624606168811123851, 11476968507677098110, 1056328247986567681, 15246608002200052960, 6566558379177875405,
+		652315099041528631, 4287214618428297946, 11730560225433863449, 7935915607867430686, 15979159466809939008, 9209839549459543141, 9501045239358734673, 15490773728258884277,
+		14281001444503113096, 9253803478538227873, 3842669056581745692, 18399990656305827164, 11841387504710944221, 16052361836589007383, 831115622826254867, 8219898649601530197,
+		2339128600785774471, 1426373723429876004, 3299581455481810683, 16966544600853047157, 8419320331267538738, 8376963013864643226, 1996128805959565963, 2376766970819731241,
+		10963611841695254911, 2914831079289063424, 15884256460390936367, 8724520571578171796, 329402220949313078, 8905943304651682982, 1280899166177109409, 6980213851983339340,
+		5524321102331478758, 2149164875175284006, 10897639484514200325, 14605181792035620644, 316829907946955098, 13776780818927038502, 18167912441745301047, 16845612593885106452,
+		15817940025107036888, 14405005201957074368, 11647077937228007305, 13795438792777593442, 9813339145840642083, 13196196205982926907, 5981408724994946624, 12303812818084690125,
+		11821409230485627325, 1934768678832528678, 15798397330147151183, 2089418311766868031, 16206123311846842647, 10276976147555604745, 14858750786699873336, 2500482310681473276,
+		9502861285700748804, 12163827978530279544, 9383068907817479934, 5717811606328725851, 12416198015020836733, 15689586164720677894, 14337921697724349521, 9392403465642971279,
+		6696074876763293236, 10302972695440286968, 16647054763285662245, 7841147641486000427, 10612636854719975349, 3592516733641215266, 14172459823963607855, 1290213042793222575,
+	},
+}
diff --git a/src/crypto/elliptic/p256_asm_table_test.go b/src/crypto/elliptic/p256_asm_table_test.go
new file mode 100644
index 0000000..6b64f26
--- /dev/null
+++ b/src/crypto/elliptic/p256_asm_table_test.go
@@ -0,0 +1,59 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 || arm64
+// +build amd64 arm64
+
+package elliptic
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestP256PrecomputedTable(t *testing.T) {
+
+	basePoint := []uint64{
+		0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510, 0x18905f76a53755c6,
+		0xddf25357ce95560a, 0x8b4ab8e4ba19e45c, 0xd2e88688dd21f325, 0x8571ff1825885d85,
+		0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe,
+	}
+	t1 := make([]uint64, 12)
+	t2 := make([]uint64, 12)
+	copy(t2, basePoint)
+
+	zInv := make([]uint64, 4)
+	zInvSq := make([]uint64, 4)
+	for j := 0; j < 32; j++ {
+		copy(t1, t2)
+		for i := 0; i < 43; i++ {
+			// The window size is 6 so we need to double 6 times.
+			if i != 0 {
+				for k := 0; k < 6; k++ {
+					p256PointDoubleAsm(t1, t1)
+				}
+			}
+			// Convert the point to affine form. (Its values are
+			// still in Montgomery form however.)
+			p256Inverse(zInv, t1[8:12])
+			p256Sqr(zInvSq, zInv, 1)
+			p256Mul(zInv, zInv, zInvSq)
+
+			p256Mul(t1[:4], t1[:4], zInvSq)
+			p256Mul(t1[4:8], t1[4:8], zInv)
+
+			copy(t1[8:12], basePoint[8:12])
+
+			if got, want := p256Precomputed[i][j*8:(j*8)+8], t1[:8]; !reflect.DeepEqual(got, want) {
+				t.Fatalf("Unexpected table entry at [%d][%d:%d]: got %v, want %v", i, j*8, (j*8)+8, got, want)
+			}
+		}
+		if j == 0 {
+			p256PointDoubleAsm(t2, basePoint)
+		} else {
+			p256PointAddAsm(t2, t2, basePoint)
+		}
+	}
+
+}
diff --git a/src/crypto/elliptic/p256_generic.go b/src/crypto/elliptic/p256_generic.go
index f74c607..25762a8 100644
--- a/src/crypto/elliptic/p256_generic.go
+++ b/src/crypto/elliptic/p256_generic.go
@@ -2,13 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !amd64 && !s390x && !arm64 && !ppc64le
 // +build !amd64,!s390x,!arm64,!ppc64le
 
 package elliptic
 
-var (
-	p256 p256Curve
-)
+var p256 p256Curve
 
 func initP256Arch() {
 	// Use pure Go implementation.
diff --git a/src/crypto/elliptic/p256_ppc64le.go b/src/crypto/elliptic/p256_ppc64le.go
index 160bdb1..40d9ed9 100644
--- a/src/crypto/elliptic/p256_ppc64le.go
+++ b/src/crypto/elliptic/p256_ppc64le.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64le
 // +build ppc64le
 
 package elliptic
diff --git a/src/crypto/elliptic/p256_s390x.go b/src/crypto/elliptic/p256_s390x.go
index 0d9478b..91e613b 100644
--- a/src/crypto/elliptic/p256_s390x.go
+++ b/src/crypto/elliptic/p256_s390x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build s390x
 // +build s390x
 
 package elliptic
diff --git a/src/crypto/elliptic/p256_test.go b/src/crypto/elliptic/p256_test.go
new file mode 100644
index 0000000..1435f5e
--- /dev/null
+++ b/src/crypto/elliptic/p256_test.go
@@ -0,0 +1,155 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package elliptic
+
+import (
+	"math/big"
+	"testing"
+)
+
+type scalarMultTest struct {
+	k          string
+	xIn, yIn   string
+	xOut, yOut string
+}
+
+var p256MultTests = []scalarMultTest{
+	{
+		"2a265f8bcbdcaf94d58519141e578124cb40d64a501fba9c11847b28965bc737",
+		"023819813ac969847059028ea88a1f30dfbcde03fc791d3a252c6b41211882ea",
+		"f93e4ae433cc12cf2a43fc0ef26400c0e125508224cdb649380f25479148a4ad",
+		"4d4de80f1534850d261075997e3049321a0864082d24a917863366c0724f5ae3",
+		"a22d2b7f7818a3563e0f7a76c9bf0921ac55e06e2e4d11795b233824b1db8cc0",
+	},
+	{
+		"313f72ff9fe811bf573176231b286a3bdb6f1b14e05c40146590727a71c3bccd",
+		"cc11887b2d66cbae8f4d306627192522932146b42f01d3c6f92bd5c8ba739b06",
+		"a2f08a029cd06b46183085bae9248b0ed15b70280c7ef13a457f5af382426031",
+		"831c3f6b5f762d2f461901577af41354ac5f228c2591f84f8a6e51e2e3f17991",
+		"93f90934cd0ef2c698cc471c60a93524e87ab31ca2412252337f364513e43684",
+	},
+}
+
+func TestP256BaseMult(t *testing.T) {
+	p256 := P256()
+	p256Generic := p256.Params()
+
+	scalars := make([]*big.Int, 0, len(p224BaseMultTests)+1)
+	for _, e := range p224BaseMultTests {
+		k, _ := new(big.Int).SetString(e.k, 10)
+		scalars = append(scalars, k)
+	}
+	k := new(big.Int).SetInt64(1)
+	k.Lsh(k, 500)
+	scalars = append(scalars, k)
+
+	for i, k := range scalars {
+		x, y := p256.ScalarBaseMult(k.Bytes())
+		x2, y2 := p256Generic.ScalarBaseMult(k.Bytes())
+		if x.Cmp(x2) != 0 || y.Cmp(y2) != 0 {
+			t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, x, y, x2, y2)
+		}
+
+		if testing.Short() && i > 5 {
+			break
+		}
+	}
+}
+
+func TestP256Mult(t *testing.T) {
+	p256 := P256()
+	p256Generic := p256.Params()
+
+	for i, e := range p224BaseMultTests {
+		x, _ := new(big.Int).SetString(e.x, 16)
+		y, _ := new(big.Int).SetString(e.y, 16)
+		k, _ := new(big.Int).SetString(e.k, 10)
+
+		xx, yy := p256.ScalarMult(x, y, k.Bytes())
+		xx2, yy2 := p256Generic.ScalarMult(x, y, k.Bytes())
+		if xx.Cmp(xx2) != 0 || yy.Cmp(yy2) != 0 {
+			t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, xx, yy, xx2, yy2)
+		}
+		if testing.Short() && i > 5 {
+			break
+		}
+	}
+
+	for i, e := range p256MultTests {
+		x, _ := new(big.Int).SetString(e.xIn, 16)
+		y, _ := new(big.Int).SetString(e.yIn, 16)
+		k, _ := new(big.Int).SetString(e.k, 16)
+		expectedX, _ := new(big.Int).SetString(e.xOut, 16)
+		expectedY, _ := new(big.Int).SetString(e.yOut, 16)
+
+		xx, yy := p256.ScalarMult(x, y, k.Bytes())
+		if xx.Cmp(expectedX) != 0 || yy.Cmp(expectedY) != 0 {
+			t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, xx, yy, expectedX, expectedY)
+		}
+	}
+}
+
+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 TestP256CombinedMult(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)
+	}
+}
diff --git a/src/crypto/elliptic/p521.go b/src/crypto/elliptic/p521.go
new file mode 100644
index 0000000..3d35594
--- /dev/null
+++ b/src/crypto/elliptic/p521.go
@@ -0,0 +1,259 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package elliptic
+
+import (
+	"crypto/elliptic/internal/fiat"
+	"math/big"
+)
+
+type p521Curve struct {
+	*CurveParams
+}
+
+var p521 p521Curve
+var p521Params *CurveParams
+
+func initP521() {
+	// See FIPS 186-3, section D.2.5
+	p521.CurveParams = &CurveParams{Name: "P-521"}
+	p521.P, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", 10)
+	p521.N, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449", 10)
+	p521.B, _ = new(big.Int).SetString("051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", 16)
+	p521.Gx, _ = new(big.Int).SetString("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 16)
+	p521.Gy, _ = new(big.Int).SetString("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 16)
+	p521.BitSize = 521
+}
+
+func (curve p521Curve) Params() *CurveParams {
+	return curve.CurveParams
+}
+
+func (curve p521Curve) IsOnCurve(x, y *big.Int) bool {
+	x1 := bigIntToFiatP521(x)
+	y1 := bigIntToFiatP521(y)
+	b := bigIntToFiatP521(curve.B) // TODO: precompute this value.
+
+	// x³ - 3x + b.
+	x3 := new(fiat.P521Element).Square(x1)
+	x3.Mul(x3, x1)
+
+	threeX := new(fiat.P521Element).Add(x1, x1)
+	threeX.Add(threeX, x1)
+
+	x3.Sub(x3, threeX)
+	x3.Add(x3, b)
+
+	// y² = x³ - 3x + b
+	y2 := new(fiat.P521Element).Square(y1)
+
+	return x3.Equal(y2) == 1
+}
+
+type p521Point struct {
+	x, y, z *fiat.P521Element
+}
+
+func fiatP521ToBigInt(x *fiat.P521Element) *big.Int {
+	xBytes := x.Bytes()
+	for i := range xBytes[:len(xBytes)/2] {
+		xBytes[i], xBytes[len(xBytes)-i-1] = xBytes[len(xBytes)-i-1], xBytes[i]
+	}
+	return new(big.Int).SetBytes(xBytes)
+}
+
+// affineFromJacobian brings a point in Jacobian coordinates back to affine
+// coordinates, with (0, 0) representing infinity by convention. It also goes
+// back to big.Int values to match the exposed API.
+func (curve p521Curve) affineFromJacobian(p *p521Point) (x, y *big.Int) {
+	if p.z.IsZero() == 1 {
+		return new(big.Int), new(big.Int)
+	}
+
+	zinv := new(fiat.P521Element).Invert(p.z)
+	zinvsq := new(fiat.P521Element).Mul(zinv, zinv)
+
+	xx := new(fiat.P521Element).Mul(p.x, zinvsq)
+	zinvsq.Mul(zinvsq, zinv)
+	yy := new(fiat.P521Element).Mul(p.y, zinvsq)
+
+	return fiatP521ToBigInt(xx), fiatP521ToBigInt(yy)
+}
+
+func bigIntToFiatP521(x *big.Int) *fiat.P521Element {
+	xBytes := new(big.Int).Mod(x, p521.P).FillBytes(make([]byte, 66))
+	for i := range xBytes[:len(xBytes)/2] {
+		xBytes[i], xBytes[len(xBytes)-i-1] = xBytes[len(xBytes)-i-1], xBytes[i]
+	}
+	x1, err := new(fiat.P521Element).SetBytes(xBytes)
+	if err != nil {
+		// The input is reduced modulo P and encoded in a fixed size bytes
+		// slice, this should be impossible.
+		panic("internal error: bigIntToFiatP521")
+	}
+	return x1
+}
+
+// jacobianFromAffine converts (x, y) affine coordinates into (x, y, z) Jacobian
+// coordinates. It also converts from big.Int to fiat, which is necessarily a
+// messy and variable-time operation, which we can't avoid due to the exposed API.
+func (curve p521Curve) jacobianFromAffine(x, y *big.Int) *p521Point {
+	// (0, 0) is by convention the point at infinity, which can't be represented
+	// in affine coordinates, but is (0, 0, 0) in Jacobian.
+	if x.Sign() == 0 && y.Sign() == 0 {
+		return &p521Point{
+			x: new(fiat.P521Element),
+			y: new(fiat.P521Element),
+			z: new(fiat.P521Element),
+		}
+	}
+	return &p521Point{
+		x: bigIntToFiatP521(x),
+		y: bigIntToFiatP521(y),
+		z: new(fiat.P521Element).One(),
+	}
+}
+
+func (curve p521Curve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
+	p1 := curve.jacobianFromAffine(x1, y1)
+	p2 := curve.jacobianFromAffine(x2, y2)
+	return curve.affineFromJacobian(p1.addJacobian(p1, p2))
+}
+
+// addJacobian sets q = p1 + p2, and returns q. The points may overlap.
+func (q *p521Point) addJacobian(p1, p2 *p521Point) *p521Point {
+	// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
+	z1IsZero := p1.z.IsZero()
+	z2IsZero := p2.z.IsZero()
+
+	z1z1 := new(fiat.P521Element).Square(p1.z)
+	z2z2 := new(fiat.P521Element).Square(p2.z)
+
+	u1 := new(fiat.P521Element).Mul(p1.x, z2z2)
+	u2 := new(fiat.P521Element).Mul(p2.x, z1z1)
+	h := new(fiat.P521Element).Sub(u2, u1)
+	xEqual := h.IsZero() == 1
+	i := new(fiat.P521Element).Add(h, h)
+	i.Square(i)
+	j := new(fiat.P521Element).Mul(h, i)
+
+	s1 := new(fiat.P521Element).Mul(p1.y, p2.z)
+	s1.Mul(s1, z2z2)
+	s2 := new(fiat.P521Element).Mul(p2.y, p1.z)
+	s2.Mul(s2, z1z1)
+	r := new(fiat.P521Element).Sub(s2, s1)
+	yEqual := r.IsZero() == 1
+	if xEqual && yEqual && z1IsZero == 0 && z2IsZero == 0 {
+		return q.doubleJacobian(p1)
+	}
+	r.Add(r, r)
+	v := new(fiat.P521Element).Mul(u1, i)
+
+	x := new(fiat.P521Element).Set(r)
+	x.Square(x)
+	x.Sub(x, j)
+	x.Sub(x, v)
+	x.Sub(x, v)
+
+	y := new(fiat.P521Element).Set(r)
+	v.Sub(v, x)
+	y.Mul(y, v)
+	s1.Mul(s1, j)
+	s1.Add(s1, s1)
+	y.Sub(y, s1)
+
+	z := new(fiat.P521Element).Add(p1.z, p2.z)
+	z.Square(z)
+	z.Sub(z, z1z1)
+	z.Sub(z, z2z2)
+	z.Mul(z, h)
+
+	x.Select(p2.x, x, z1IsZero)
+	x.Select(p1.x, x, z2IsZero)
+	y.Select(p2.y, y, z1IsZero)
+	y.Select(p1.y, y, z2IsZero)
+	z.Select(p2.z, z, z1IsZero)
+	z.Select(p1.z, z, z2IsZero)
+
+	q.x.Set(x)
+	q.y.Set(y)
+	q.z.Set(z)
+	return q
+}
+
+func (curve p521Curve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
+	p := curve.jacobianFromAffine(x1, y1)
+	return curve.affineFromJacobian(p.doubleJacobian(p))
+}
+
+// doubleJacobian sets q = p + p, and returns q. The points may overlap.
+func (q *p521Point) doubleJacobian(p *p521Point) *p521Point {
+	// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+	delta := new(fiat.P521Element).Square(p.z)
+	gamma := new(fiat.P521Element).Square(p.y)
+	alpha := new(fiat.P521Element).Sub(p.x, delta)
+	alpha2 := new(fiat.P521Element).Add(p.x, delta)
+	alpha.Mul(alpha, alpha2)
+	alpha2.Set(alpha)
+	alpha.Add(alpha, alpha)
+	alpha.Add(alpha, alpha2)
+
+	beta := alpha2.Mul(p.x, gamma)
+
+	q.x.Square(alpha)
+	beta8 := new(fiat.P521Element).Add(beta, beta)
+	beta8.Add(beta8, beta8)
+	beta8.Add(beta8, beta8)
+	q.x.Sub(q.x, beta8)
+
+	q.z.Add(p.y, p.z)
+	q.z.Square(q.z)
+	q.z.Sub(q.z, gamma)
+	q.z.Sub(q.z, delta)
+
+	beta.Add(beta, beta)
+	beta.Add(beta, beta)
+	beta.Sub(beta, q.x)
+	q.y.Mul(alpha, beta)
+
+	gamma.Square(gamma)
+	gamma.Add(gamma, gamma)
+	gamma.Add(gamma, gamma)
+	gamma.Add(gamma, gamma)
+
+	q.y.Sub(q.y, gamma)
+
+	return q
+}
+
+func (curve p521Curve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
+	B := curve.jacobianFromAffine(Bx, By)
+	p, t := &p521Point{
+		x: new(fiat.P521Element),
+		y: new(fiat.P521Element),
+		z: new(fiat.P521Element),
+	}, &p521Point{
+		x: new(fiat.P521Element),
+		y: new(fiat.P521Element),
+		z: new(fiat.P521Element),
+	}
+
+	for _, byte := range scalar {
+		for bitNum := 0; bitNum < 8; bitNum++ {
+			p.doubleJacobian(p)
+			bit := (byte >> (7 - bitNum)) & 1
+			t.addJacobian(p, B)
+			p.x.Select(t.x, p.x, int(bit))
+			p.y.Select(t.y, p.y, int(bit))
+			p.z.Select(t.z, p.z, int(bit))
+		}
+	}
+
+	return curve.affineFromJacobian(p)
+}
+
+func (curve p521Curve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
+	return curve.ScalarMult(curve.Gx, curve.Gy, k)
+}
diff --git a/src/crypto/internal/subtle/aliasing.go b/src/crypto/internal/subtle/aliasing.go
index 812ce3c..86e0f3c 100644
--- a/src/crypto/internal/subtle/aliasing.go
+++ b/src/crypto/internal/subtle/aliasing.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !appengine
 // +build !appengine
 
 // Package subtle implements functions that are often useful in cryptographic
diff --git a/src/crypto/internal/subtle/aliasing_appengine.go b/src/crypto/internal/subtle/aliasing_appengine.go
index 844f901..35b442f 100644
--- a/src/crypto/internal/subtle/aliasing_appengine.go
+++ b/src/crypto/internal/subtle/aliasing_appengine.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build appengine
 // +build appengine
 
 // Package subtle implements functions that are often useful in cryptographic
diff --git a/src/crypto/md5/gen.go b/src/crypto/md5/gen.go
index 1468924..29729fa 100644
--- a/src/crypto/md5/gen.go
+++ b/src/crypto/md5/gen.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // This program generates md5block.go
diff --git a/src/crypto/md5/md5_test.go b/src/crypto/md5/md5_test.go
index 282ba1b..acd456a 100644
--- a/src/crypto/md5/md5_test.go
+++ b/src/crypto/md5/md5_test.go
@@ -157,7 +157,7 @@
 // Tests for unmarshaling hashes that have hashed a large amount of data
 // The initial hash generation is omitted from the test, because it takes a long time.
 // The test contains some already-generated states, and their expected sums
-// Tests a problem that is outlined in Github issue #29541
+// Tests a problem that is outlined in GitHub issue #29541
 // The problem is triggered when an amount of data has been hashed for which
 // the data length has a 1 in the 32nd bit. When casted to int, this changes
 // the sign of the value, and causes the modulus operation to return a
@@ -212,7 +212,7 @@
 }
 
 var bench = New()
-var buf = make([]byte, 8192+1)
+var buf = make([]byte, 1024*1024*8+1)
 var sum = make([]byte, bench.Size())
 
 func benchmarkSize(b *testing.B, size int, unaligned bool) {
@@ -235,6 +235,22 @@
 	benchmarkSize(b, 8, false)
 }
 
+func BenchmarkHash64(b *testing.B) {
+	benchmarkSize(b, 64, false)
+}
+
+func BenchmarkHash128(b *testing.B) {
+	benchmarkSize(b, 128, false)
+}
+
+func BenchmarkHash256(b *testing.B) {
+	benchmarkSize(b, 256, false)
+}
+
+func BenchmarkHash512(b *testing.B) {
+	benchmarkSize(b, 512, false)
+}
+
 func BenchmarkHash1K(b *testing.B) {
 	benchmarkSize(b, 1024, false)
 }
@@ -243,6 +259,14 @@
 	benchmarkSize(b, 8192, false)
 }
 
+func BenchmarkHash1M(b *testing.B) {
+	benchmarkSize(b, 1024*1024, false)
+}
+
+func BenchmarkHash8M(b *testing.B) {
+	benchmarkSize(b, 8*1024*1024, false)
+}
+
 func BenchmarkHash8BytesUnaligned(b *testing.B) {
 	benchmarkSize(b, 8, true)
 }
diff --git a/src/crypto/md5/md5block_decl.go b/src/crypto/md5/md5block_decl.go
index f251e03..bc2d58c 100644
--- a/src/crypto/md5/md5block_decl.go
+++ b/src/crypto/md5/md5block_decl.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 || 386 || arm || ppc64le || ppc64 || s390x || arm64
 // +build amd64 386 arm ppc64le ppc64 s390x arm64
 
 package md5
diff --git a/src/crypto/md5/md5block_generic.go b/src/crypto/md5/md5block_generic.go
index 0b46e70..ea4fbcd 100644
--- a/src/crypto/md5/md5block_generic.go
+++ b/src/crypto/md5/md5block_generic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !amd64 && !386 && !arm && !ppc64le && !ppc64 && !s390x && !arm64
 // +build !amd64,!386,!arm,!ppc64le,!ppc64,!s390x,!arm64
 
 package md5
diff --git a/src/crypto/md5/md5block_ppc64x.s b/src/crypto/md5/md5block_ppc64x.s
index f309a14..8c28ec2 100644
--- a/src/crypto/md5/md5block_ppc64x.s
+++ b/src/crypto/md5/md5block_ppc64x.s
@@ -10,6 +10,7 @@
 // Licence: I hereby disclaim the copyright on this code and place it
 // in the public domain.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "textflag.h"
@@ -28,169 +29,179 @@
 	MOVWBR	(idx)(ptr), dst
 #endif
 
+#define M00 R18
+#define M01 R19
+#define M02 R20
+#define M03 R24
+#define M04 R25
+#define M05 R26
+#define M06 R27
+#define M07 R28
+#define M08 R29
+#define M09 R21
+#define M10 R11
+#define M11 R8
+#define M12 R7
+#define M13 R12
+#define M14 R23
+#define M15 R10
+
+#define ROUND1(a, b, c, d, index, const, shift) \
+	ADD	$const, index, R9; \
+	ADD	R9, a; \
+	AND     b, c, R9; \
+	ANDN    b, d, R31; \
+	OR	R9, R31, R9; \
+	ADD	R9, a; \
+	ROTLW	$shift, a; \
+	ADD	b, a;
+
+#define ROUND2(a, b, c, d, index, const, shift) \
+	ADD	$const, index, R9; \
+	ADD	R9, a; \
+	AND	b, d, R31; \
+	ANDN	d, c, R9; \
+	OR	R9, R31; \
+	ADD	R31, a; \
+	ROTLW	$shift, a; \
+	ADD	b, a;
+
+#define ROUND3(a, b, c, d, index, const, shift) \
+	ADD	$const, index, R9; \
+	ADD	R9, a; \
+	XOR	d, c, R31; \
+	XOR	b, R31; \
+	ADD	R31, a; \
+	ROTLW	$shift, a; \
+	ADD	b, a;
+
+#define ROUND4(a, b, c, d, index, const, shift) \
+	ADD	$const, index, R9; \
+	ADD	R9, a; \
+	ORN     d, b, R31; \
+	XOR	c, R31; \
+	ADD	R31, a; \
+	ROTLW	$shift, a; \
+	ADD	b, a;
+
+
 TEXT ·block(SB),NOSPLIT,$0-32
 	MOVD	dig+0(FP), R10
 	MOVD	p+8(FP), R6
 	MOVD	p_len+16(FP), R5
-	SLD	$6, R5
-	SRD	$6, R5
-	ADD	R6, R5, R7
+
+	// We assume p_len >= 64
+	SRD 	$6, R5
+	MOVD	R5, CTR
 
 	MOVWZ	0(R10), R22
 	MOVWZ	4(R10), R3
 	MOVWZ	8(R10), R4
 	MOVWZ	12(R10), R5
-	CMP	R6, R7
-	BEQ	end
 
 loop:
-	MOVWZ	R22, R14
-	MOVWZ	R3, R15
-	MOVWZ	R4, R16
-	MOVWZ	R5, R17
+	MOVD	R22, R14
+	MOVD	R3, R15
+	MOVD	R4, R16
+	MOVD	R5, R17
 
-	ENDIAN_MOVE(0,R6,R8,R21)
-	MOVWZ	R5, R9
+	ENDIAN_MOVE( 0,R6,M00,M15)
+	ENDIAN_MOVE( 4,R6,M01,M15)
+	ENDIAN_MOVE( 8,R6,M02,M15)
+	ENDIAN_MOVE(12,R6,M03,M15)
 
-#define ROUND1(a, b, c, d, index, const, shift) \
-	XOR	c, R9; \
-	ADD	$const, a; \
-	ADD	R8, a; \
-	AND	b, R9; \
-	XOR	d, R9; \
-	ENDIAN_MOVE(index*4,R6,R8,R21); \
-	ADD	R9, a; \
-	RLWMI	$shift, a, $0xffffffff, a; \
-	MOVWZ	c, R9; \
-	ADD	b, a; \
-	MOVWZ	a, a
+	ROUND1(R22,R3,R4,R5,M00,0xd76aa478, 7);
+	ROUND1(R5,R22,R3,R4,M01,0xe8c7b756,12);
+	ROUND1(R4,R5,R22,R3,M02,0x242070db,17);
+	ROUND1(R3,R4,R5,R22,M03,0xc1bdceee,22);
 
-	ROUND1(R22,R3,R4,R5, 1,0xd76aa478, 7);
-	ROUND1(R5,R22,R3,R4, 2,0xe8c7b756,12);
-	ROUND1(R4,R5,R22,R3, 3,0x242070db,17);
-	ROUND1(R3,R4,R5,R22, 4,0xc1bdceee,22);
-	ROUND1(R22,R3,R4,R5, 5,0xf57c0faf, 7);
-	ROUND1(R5,R22,R3,R4, 6,0x4787c62a,12);
-	ROUND1(R4,R5,R22,R3, 7,0xa8304613,17);
-	ROUND1(R3,R4,R5,R22, 8,0xfd469501,22);
-	ROUND1(R22,R3,R4,R5, 9,0x698098d8, 7);
-	ROUND1(R5,R22,R3,R4,10,0x8b44f7af,12);
-	ROUND1(R4,R5,R22,R3,11,0xffff5bb1,17);
-	ROUND1(R3,R4,R5,R22,12,0x895cd7be,22);
-	ROUND1(R22,R3,R4,R5,13,0x6b901122, 7);
-	ROUND1(R5,R22,R3,R4,14,0xfd987193,12);
-	ROUND1(R4,R5,R22,R3,15,0xa679438e,17);
-	ROUND1(R3,R4,R5,R22, 0,0x49b40821,22);
+	ENDIAN_MOVE(16,R6,M04,M15)
+	ENDIAN_MOVE(20,R6,M05,M15)
+	ENDIAN_MOVE(24,R6,M06,M15)
+	ENDIAN_MOVE(28,R6,M07,M15)
 
-	ENDIAN_MOVE(1*4,R6,R8,R21)
-	MOVWZ	R5, R9
-	MOVWZ	R5, R10
+	ROUND1(R22,R3,R4,R5,M04,0xf57c0faf, 7);
+	ROUND1(R5,R22,R3,R4,M05,0x4787c62a,12);
+	ROUND1(R4,R5,R22,R3,M06,0xa8304613,17);
+	ROUND1(R3,R4,R5,R22,M07,0xfd469501,22);
 
-#define ROUND2(a, b, c, d, index, const, shift) \
-	XOR	$0xffffffff, R9; \ // NOTW R9
-	ADD	$const, a; \
-	ADD	R8, a; \
-	AND	b, R10; \
-	AND	c, R9; \
-	ENDIAN_MOVE(index*4,R6,R8,R21); \
-	OR	R9, R10; \
-	MOVWZ	c, R9; \
-	ADD	R10, a; \
-	MOVWZ	c, R10; \
-	RLWMI	$shift, a, $0xffffffff, a; \
-	ADD	b, a; \
-	MOVWZ	a, a
+	ENDIAN_MOVE(32,R6,M08,M15)
+	ENDIAN_MOVE(36,R6,M09,M15)
+	ENDIAN_MOVE(40,R6,M10,M15)
+	ENDIAN_MOVE(44,R6,M11,M15)
 
-	ROUND2(R22,R3,R4,R5, 6,0xf61e2562, 5);
-	ROUND2(R5,R22,R3,R4,11,0xc040b340, 9);
-	ROUND2(R4,R5,R22,R3, 0,0x265e5a51,14);
-	ROUND2(R3,R4,R5,R22, 5,0xe9b6c7aa,20);
-	ROUND2(R22,R3,R4,R5,10,0xd62f105d, 5);
-	ROUND2(R5,R22,R3,R4,15, 0x2441453, 9);
-	ROUND2(R4,R5,R22,R3, 4,0xd8a1e681,14);
-	ROUND2(R3,R4,R5,R22, 9,0xe7d3fbc8,20);
-	ROUND2(R22,R3,R4,R5,14,0x21e1cde6, 5);
-	ROUND2(R5,R22,R3,R4, 3,0xc33707d6, 9);
-	ROUND2(R4,R5,R22,R3, 8,0xf4d50d87,14);
-	ROUND2(R3,R4,R5,R22,13,0x455a14ed,20);
-	ROUND2(R22,R3,R4,R5, 2,0xa9e3e905, 5);
-	ROUND2(R5,R22,R3,R4, 7,0xfcefa3f8, 9);
-	ROUND2(R4,R5,R22,R3,12,0x676f02d9,14);
-	ROUND2(R3,R4,R5,R22, 0,0x8d2a4c8a,20);
+	ROUND1(R22,R3,R4,R5,M08,0x698098d8, 7);
+	ROUND1(R5,R22,R3,R4,M09,0x8b44f7af,12);
+	ROUND1(R4,R5,R22,R3,M10,0xffff5bb1,17);
+	ROUND1(R3,R4,R5,R22,M11,0x895cd7be,22);
 
-	ENDIAN_MOVE(5*4,R6,R8,R21)
-	MOVWZ	R4, R9
+	ENDIAN_MOVE(48,R6,M12,M15)
+	ENDIAN_MOVE(52,R6,M13,M15)
+	ENDIAN_MOVE(56,R6,M14,M15)
+	ENDIAN_MOVE(60,R6,M15,M15)
 
-#define ROUND3(a, b, c, d, index, const, shift) \
-	ADD	$const, a; \
-	ADD	R8, a; \
-	ENDIAN_MOVE(index*4,R6,R8,R21); \
-	XOR	d, R9; \
-	XOR	b, R9; \
-	ADD	R9, a; \
-	RLWMI	$shift, a, $0xffffffff, a; \
-	MOVWZ	b, R9; \
-	ADD	b, a; \
-	MOVWZ	a, a
+	ROUND1(R22,R3,R4,R5,M12,0x6b901122, 7);
+	ROUND1(R5,R22,R3,R4,M13,0xfd987193,12);
+	ROUND1(R4,R5,R22,R3,M14,0xa679438e,17);
+	ROUND1(R3,R4,R5,R22,M15,0x49b40821,22);
 
-	ROUND3(R22,R3,R4,R5, 8,0xfffa3942, 4);
-	ROUND3(R5,R22,R3,R4,11,0x8771f681,11);
-	ROUND3(R4,R5,R22,R3,14,0x6d9d6122,16);
-	ROUND3(R3,R4,R5,R22, 1,0xfde5380c,23);
-	ROUND3(R22,R3,R4,R5, 4,0xa4beea44, 4);
-	ROUND3(R5,R22,R3,R4, 7,0x4bdecfa9,11);
-	ROUND3(R4,R5,R22,R3,10,0xf6bb4b60,16);
-	ROUND3(R3,R4,R5,R22,13,0xbebfbc70,23);
-	ROUND3(R22,R3,R4,R5, 0,0x289b7ec6, 4);
-	ROUND3(R5,R22,R3,R4, 3,0xeaa127fa,11);
-	ROUND3(R4,R5,R22,R3, 6,0xd4ef3085,16);
-	ROUND3(R3,R4,R5,R22, 9, 0x4881d05,23);
-	ROUND3(R22,R3,R4,R5,12,0xd9d4d039, 4);
-	ROUND3(R5,R22,R3,R4,15,0xe6db99e5,11);
-	ROUND3(R4,R5,R22,R3, 2,0x1fa27cf8,16);
-	ROUND3(R3,R4,R5,R22, 0,0xc4ac5665,23);
+	ROUND2(R22,R3,R4,R5,M01,0xf61e2562, 5);
+	ROUND2(R5,R22,R3,R4,M06,0xc040b340, 9);
+	ROUND2(R4,R5,R22,R3,M11,0x265e5a51,14);
+	ROUND2(R3,R4,R5,R22,M00,0xe9b6c7aa,20);
+	ROUND2(R22,R3,R4,R5,M05,0xd62f105d, 5);
+	ROUND2(R5,R22,R3,R4,M10, 0x2441453, 9);
+	ROUND2(R4,R5,R22,R3,M15,0xd8a1e681,14);
+	ROUND2(R3,R4,R5,R22,M04,0xe7d3fbc8,20);
+	ROUND2(R22,R3,R4,R5,M09,0x21e1cde6, 5);
+	ROUND2(R5,R22,R3,R4,M14,0xc33707d6, 9);
+	ROUND2(R4,R5,R22,R3,M03,0xf4d50d87,14);
+	ROUND2(R3,R4,R5,R22,M08,0x455a14ed,20);
+	ROUND2(R22,R3,R4,R5,M13,0xa9e3e905, 5);
+	ROUND2(R5,R22,R3,R4,M02,0xfcefa3f8, 9);
+	ROUND2(R4,R5,R22,R3,M07,0x676f02d9,14);
+	ROUND2(R3,R4,R5,R22,M12,0x8d2a4c8a,20);
 
-	ENDIAN_MOVE(0,R6,R8,R21)
-	MOVWZ	$0xffffffff, R9
-	XOR	R5, R9
+	ROUND3(R22,R3,R4,R5,M05,0xfffa3942, 4);
+	ROUND3(R5,R22,R3,R4,M08,0x8771f681,11);
+	ROUND3(R4,R5,R22,R3,M11,0x6d9d6122,16);
+	ROUND3(R3,R4,R5,R22,M14,0xfde5380c,23);
+	ROUND3(R22,R3,R4,R5,M01,0xa4beea44, 4);
+	ROUND3(R5,R22,R3,R4,M04,0x4bdecfa9,11);
+	ROUND3(R4,R5,R22,R3,M07,0xf6bb4b60,16);
+	ROUND3(R3,R4,R5,R22,M10,0xbebfbc70,23);
+	ROUND3(R22,R3,R4,R5,M13,0x289b7ec6, 4);
+	ROUND3(R5,R22,R3,R4,M00,0xeaa127fa,11);
+	ROUND3(R4,R5,R22,R3,M03,0xd4ef3085,16);
+	ROUND3(R3,R4,R5,R22,M06, 0x4881d05,23);
+	ROUND3(R22,R3,R4,R5,M09,0xd9d4d039, 4);
+	ROUND3(R5,R22,R3,R4,M12,0xe6db99e5,11);
+	ROUND3(R4,R5,R22,R3,M15,0x1fa27cf8,16);
+	ROUND3(R3,R4,R5,R22,M02,0xc4ac5665,23);
 
-#define ROUND4(a, b, c, d, index, const, shift) \
-	ADD	$const, a; \
-	ADD	R8, a; \
-	OR	b, R9; \
-	XOR	c, R9; \
-	ADD	R9, a; \
-	ENDIAN_MOVE(index*4,R6,R8,R21); \
-	MOVWZ	$0xffffffff, R9; \
-	RLWMI	$shift, a, $0xffffffff, a; \
-	XOR	c, R9; \
-	ADD	b, a; \
-	MOVWZ	a, a
-
-	ROUND4(R22,R3,R4,R5, 7,0xf4292244, 6);
-	ROUND4(R5,R22,R3,R4,14,0x432aff97,10);
-	ROUND4(R4,R5,R22,R3, 5,0xab9423a7,15);
-	ROUND4(R3,R4,R5,R22,12,0xfc93a039,21);
-	ROUND4(R22,R3,R4,R5, 3,0x655b59c3, 6);
-	ROUND4(R5,R22,R3,R4,10,0x8f0ccc92,10);
-	ROUND4(R4,R5,R22,R3, 1,0xffeff47d,15);
-	ROUND4(R3,R4,R5,R22, 8,0x85845dd1,21);
-	ROUND4(R22,R3,R4,R5,15,0x6fa87e4f, 6);
-	ROUND4(R5,R22,R3,R4, 6,0xfe2ce6e0,10);
-	ROUND4(R4,R5,R22,R3,13,0xa3014314,15);
-	ROUND4(R3,R4,R5,R22, 4,0x4e0811a1,21);
-	ROUND4(R22,R3,R4,R5,11,0xf7537e82, 6);
-	ROUND4(R5,R22,R3,R4, 2,0xbd3af235,10);
-	ROUND4(R4,R5,R22,R3, 9,0x2ad7d2bb,15);
-	ROUND4(R3,R4,R5,R22, 0,0xeb86d391,21);
+	ROUND4(R22,R3,R4,R5,M00,0xf4292244, 6);
+	ROUND4(R5,R22,R3,R4,M07,0x432aff97,10);
+	ROUND4(R4,R5,R22,R3,M14,0xab9423a7,15);
+	ROUND4(R3,R4,R5,R22,M05,0xfc93a039,21);
+	ROUND4(R22,R3,R4,R5,M12,0x655b59c3, 6);
+	ROUND4(R5,R22,R3,R4,M03,0x8f0ccc92,10);
+	ROUND4(R4,R5,R22,R3,M10,0xffeff47d,15);
+	ROUND4(R3,R4,R5,R22,M01,0x85845dd1,21);
+	ROUND4(R22,R3,R4,R5,M08,0x6fa87e4f, 6);
+	ROUND4(R5,R22,R3,R4,M15,0xfe2ce6e0,10);
+	ROUND4(R4,R5,R22,R3,M06,0xa3014314,15);
+	ROUND4(R3,R4,R5,R22,M13,0x4e0811a1,21);
+	ROUND4(R22,R3,R4,R5,M04,0xf7537e82, 6);
+	ROUND4(R5,R22,R3,R4,M11,0xbd3af235,10);
+	ROUND4(R4,R5,R22,R3,M02,0x2ad7d2bb,15);
+	ROUND4(R3,R4,R5,R22,M09,0xeb86d391,21);
 
 	ADD	R14, R22
 	ADD	R15, R3
 	ADD	R16, R4
 	ADD	R17, R5
 	ADD	$64, R6
-	CMP	R6, R7
-	BLT	loop
+	BC	16, 0, loop // bdnz
 
 end:
 	MOVD	dig+0(FP), R10
@@ -198,4 +209,5 @@
 	MOVWZ	R3, 4(R10)
 	MOVWZ	R4, 8(R10)
 	MOVWZ	R5, 12(R10)
+
 	RET
diff --git a/src/crypto/rand/eagain.go b/src/crypto/rand/eagain.go
index c949971..85d4d9d 100644
--- a/src/crypto/rand/eagain.go
+++ b/src/crypto/rand/eagain.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package rand
diff --git a/src/crypto/rand/rand_batched.go b/src/crypto/rand/rand_batched.go
index 60267fd..d7c5bf3 100644
--- a/src/crypto/rand/rand_batched.go
+++ b/src/crypto/rand/rand_batched.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux freebsd
+//go:build linux || freebsd || dragonfly || solaris
+// +build linux freebsd dragonfly solaris
 
 package rand
 
diff --git a/src/crypto/rand/rand_batched_test.go b/src/crypto/rand/rand_batched_test.go
index 837db83..2d20922 100644
--- a/src/crypto/rand/rand_batched_test.go
+++ b/src/crypto/rand/rand_batched_test.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux freebsd
+//go:build linux || freebsd || dragonfly || solaris
+// +build linux freebsd dragonfly solaris
 
 package rand
 
diff --git a/src/crypto/rand/rand_dragonfly.go b/src/crypto/rand/rand_dragonfly.go
new file mode 100644
index 0000000..8a36fea
--- /dev/null
+++ b/src/crypto/rand/rand_dragonfly.go
@@ -0,0 +1,9 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package rand
+
+// maxGetRandomRead is the maximum number of bytes to ask for in one call to the
+// getrandom() syscall. In DragonFlyBSD at most 256 bytes will be returned per call.
+const maxGetRandomRead = 1 << 8
diff --git a/src/crypto/rand/rand_getentropy.go b/src/crypto/rand/rand_getentropy.go
new file mode 100644
index 0000000..f82018a
--- /dev/null
+++ b/src/crypto/rand/rand_getentropy.go
@@ -0,0 +1,31 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin || openbsd
+// +build darwin openbsd
+
+package rand
+
+import (
+	"internal/syscall/unix"
+)
+
+func init() {
+	altGetRandom = getEntropy
+}
+
+func getEntropy(p []byte) (ok bool) {
+	// getentropy(2) returns a maximum of 256 bytes per call
+	for i := 0; i < len(p); i += 256 {
+		end := i + 256
+		if len(p) < end {
+			end = len(p)
+		}
+		err := unix.GetEntropy(p[i:end])
+		if err != nil {
+			return false
+		}
+	}
+	return true
+}
diff --git a/src/crypto/rand/rand_js.go b/src/crypto/rand/rand_js.go
index 7e93974..7ddc2b6 100644
--- a/src/crypto/rand/rand_js.go
+++ b/src/crypto/rand/rand_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package rand
diff --git a/src/crypto/rand/rand_openbsd.go b/src/crypto/rand/rand_openbsd.go
deleted file mode 100644
index 9cc39f7..0000000
--- a/src/crypto/rand/rand_openbsd.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.
-
-package rand
-
-import (
-	"internal/syscall/unix"
-)
-
-func init() {
-	altGetRandom = getRandomOpenBSD
-}
-
-func getRandomOpenBSD(p []byte) (ok bool) {
-	// getentropy(2) returns a maximum of 256 bytes per call
-	for i := 0; i < len(p); i += 256 {
-		end := i + 256
-		if len(p) < end {
-			end = len(p)
-		}
-		err := unix.GetEntropy(p[i:end])
-		if err != nil {
-			return false
-		}
-	}
-	return true
-}
diff --git a/src/crypto/rand/rand_solaris.go b/src/crypto/rand/rand_solaris.go
new file mode 100644
index 0000000..bbad0fe
--- /dev/null
+++ b/src/crypto/rand/rand_solaris.go
@@ -0,0 +1,10 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package rand
+
+// maxGetRandomRead is the maximum number of bytes to ask for in one call to the
+// getrandom() syscall. Across all the Solaris platforms, 256 bytes is the
+// lowest number of bytes returned atomically per call.
+const maxGetRandomRead = 1 << 8
diff --git a/src/crypto/rand/rand_unix.go b/src/crypto/rand/rand_unix.go
index 548a5e4..81277eb 100644
--- a/src/crypto/rand/rand_unix.go
+++ b/src/crypto/rand/rand_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || plan9 || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd plan9 solaris
 
 // Unix cryptographically secure pseudorandom number
diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go
index b2adbed..814522d 100644
--- a/src/crypto/rsa/pss.go
+++ b/src/crypto/rsa/pss.go
@@ -269,7 +269,7 @@
 	saltLength := opts.saltLength()
 	switch saltLength {
 	case PSSSaltLengthAuto:
-		saltLength = priv.Size() - 2 - hash.Size()
+		saltLength = (priv.N.BitLen()-1+7)/8 - 2 - hash.Size()
 	case PSSSaltLengthEqualsHash:
 		saltLength = hash.Size()
 	}
diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go
index dfa8d8b..c3a6d46 100644
--- a/src/crypto/rsa/pss_test.go
+++ b/src/crypto/rsa/pss_test.go
@@ -12,7 +12,7 @@
 	_ "crypto/md5"
 	"crypto/rand"
 	"crypto/sha1"
-	_ "crypto/sha256"
+	"crypto/sha256"
 	"encoding/hex"
 	"math/big"
 	"os"
@@ -233,6 +233,24 @@
 	}
 }
 
+func TestSignWithPSSSaltLengthAuto(t *testing.T) {
+	key, err := GenerateKey(rand.Reader, 513)
+	if err != nil {
+		t.Fatal(err)
+	}
+	digest := sha256.Sum256([]byte("message"))
+	signature, err := key.Sign(rand.Reader, digest[:], &PSSOptions{
+		SaltLength: PSSSaltLengthAuto,
+		Hash:       crypto.SHA256,
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(signature) == 0 {
+		t.Fatal("empty signature returned")
+	}
+}
+
 func bigFromHex(hex string) *big.Int {
 	n, ok := new(big.Int).SetString(hex, 16)
 	if !ok {
diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go
index 178ade6..6fd59b3 100644
--- a/src/crypto/rsa/rsa.go
+++ b/src/crypto/rsa/rsa.go
@@ -401,7 +401,7 @@
 //
 // The label parameter may contain arbitrary data that will not be encrypted,
 // but which gives important context to the message. For example, if a given
-// public key is used to decrypt two types of messages then distinct label
+// public key is used to encrypt two types of messages then distinct label
 // values could be used to ensure that a ciphertext for one purpose cannot be
 // used for another by an attacker. If not required it can be empty.
 //
diff --git a/src/crypto/sha1/fallback_test.go b/src/crypto/sha1/fallback_test.go
index 08acd04..4bb8b33 100644
--- a/src/crypto/sha1/fallback_test.go
+++ b/src/crypto/sha1/fallback_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build s390x
 // +build s390x
 
 package sha1
diff --git a/src/crypto/sha1/issue15617_test.go b/src/crypto/sha1/issue15617_test.go
index 98038e5..436f78c 100644
--- a/src/crypto/sha1/issue15617_test.go
+++ b/src/crypto/sha1/issue15617_test.go
@@ -1,3 +1,4 @@
+//go:build amd64 && (linux || darwin)
 // +build amd64
 // +build linux darwin
 
diff --git a/src/crypto/sha1/sha1_test.go b/src/crypto/sha1/sha1_test.go
index 681e928..c3e6010 100644
--- a/src/crypto/sha1/sha1_test.go
+++ b/src/crypto/sha1/sha1_test.go
@@ -156,7 +156,7 @@
 // Tests for unmarshaling hashes that have hashed a large amount of data
 // The initial hash generation is omitted from the test, because it takes a long time.
 // The test contains some already-generated states, and their expected sums
-// Tests a problem that is outlined in Github issue #29543
+// Tests a problem that is outlined in GitHub issue #29543
 // The problem is triggered when an amount of data has been hashed for which
 // the data length has a 1 in the 32nd bit. When casted to int, this changes
 // the sign of the value, and causes the modulus operation to return a
diff --git a/src/crypto/sha1/sha1block_decl.go b/src/crypto/sha1/sha1block_decl.go
index 9c7df4e..93054ef 100644
--- a/src/crypto/sha1/sha1block_decl.go
+++ b/src/crypto/sha1/sha1block_decl.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm || 386 || s390x
 // +build arm 386 s390x
 
 package sha1
diff --git a/src/crypto/sha1/sha1block_generic.go b/src/crypto/sha1/sha1block_generic.go
index f95ea0e..feaba5a 100644
--- a/src/crypto/sha1/sha1block_generic.go
+++ b/src/crypto/sha1/sha1block_generic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !amd64 && !386 && !arm && !s390x && !arm64
 // +build !amd64,!386,!arm,!s390x,!arm64
 
 package sha1
diff --git a/src/crypto/sha256/fallback_test.go b/src/crypto/sha256/fallback_test.go
index 5917a48..7ce88cb 100644
--- a/src/crypto/sha256/fallback_test.go
+++ b/src/crypto/sha256/fallback_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build s390x
 // +build s390x
 
 package sha256
diff --git a/src/crypto/sha256/sha256_test.go b/src/crypto/sha256/sha256_test.go
index 433c5a4..a2794b0 100644
--- a/src/crypto/sha256/sha256_test.go
+++ b/src/crypto/sha256/sha256_test.go
@@ -229,7 +229,7 @@
 // Tests for unmarshaling hashes that have hashed a large amount of data
 // The initial hash generation is omitted from the test, because it takes a long time.
 // The test contains some already-generated states, and their expected sums
-// Tests a problem that is outlined in Github issue #29517
+// Tests a problem that is outlined in GitHub issue #29517
 // The problem is triggered when an amount of data has been hashed for which
 // the data length has a 1 in the 32nd bit. When casted to int, this changes
 // the sign of the value, and causes the modulus operation to return a
diff --git a/src/crypto/sha256/sha256block_decl.go b/src/crypto/sha256/sha256block_decl.go
index fe07e53..a6bb396 100644
--- a/src/crypto/sha256/sha256block_decl.go
+++ b/src/crypto/sha256/sha256block_decl.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 || amd64 || s390x || ppc64le
 // +build 386 amd64 s390x ppc64le
 
 package sha256
diff --git a/src/crypto/sha256/sha256block_generic.go b/src/crypto/sha256/sha256block_generic.go
index 61362f4..620c048 100644
--- a/src/crypto/sha256/sha256block_generic.go
+++ b/src/crypto/sha256/sha256block_generic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !amd64 && !386 && !s390x && !ppc64le && !arm64
 // +build !amd64,!386,!s390x,!ppc64le,!arm64
 
 package sha256
diff --git a/src/crypto/sha512/fallback_test.go b/src/crypto/sha512/fallback_test.go
index 9024ce6..faf7326 100644
--- a/src/crypto/sha512/fallback_test.go
+++ b/src/crypto/sha512/fallback_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build s390x
 // +build s390x
 
 package sha512
diff --git a/src/crypto/sha512/sha512_test.go b/src/crypto/sha512/sha512_test.go
index 59998b1..0e1528f 100644
--- a/src/crypto/sha512/sha512_test.go
+++ b/src/crypto/sha512/sha512_test.go
@@ -788,7 +788,7 @@
 			}
 
 			if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err == nil {
-				t.Errorf("i=%d, j=%d: got no error , expected one: %v", i, j, err)
+				t.Errorf("i=%d, j=%d: got no error, expected one: %v", i, j, err)
 			}
 		}
 	}
@@ -835,7 +835,7 @@
 // Tests for unmarshaling hashes that have hashed a large amount of data
 // The initial hash generation is omitted from the test, because it takes a long time.
 // The test contains some already-generated states, and their expected sums
-// Tests a problem that is outlined in Github issue #29541
+// Tests a problem that is outlined in GitHub issue #29541
 // The problem is triggered when an amount of data has been hashed for which
 // the data length has a 1 in the 32nd bit. When casted to int, this changes
 // the sign of the value, and causes the modulus operation to return a
diff --git a/src/crypto/sha512/sha512block_amd64.go b/src/crypto/sha512/sha512block_amd64.go
index 18151ce..e2386f2 100644
--- a/src/crypto/sha512/sha512block_amd64.go
+++ b/src/crypto/sha512/sha512block_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64
 // +build amd64
 
 package sha512
diff --git a/src/crypto/sha512/sha512block_decl.go b/src/crypto/sha512/sha512block_decl.go
index 613d1e0..6c22f44 100644
--- a/src/crypto/sha512/sha512block_decl.go
+++ b/src/crypto/sha512/sha512block_decl.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build s390x || ppc64le
 // +build s390x ppc64le
 
 package sha512
diff --git a/src/crypto/sha512/sha512block_generic.go b/src/crypto/sha512/sha512block_generic.go
index 3eabd2c..865a735 100644
--- a/src/crypto/sha512/sha512block_generic.go
+++ b/src/crypto/sha512/sha512block_generic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !amd64 && !s390x && !ppc64le
 // +build !amd64,!s390x,!ppc64le
 
 package sha512
diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go
index 9a35675..4bf0646 100644
--- a/src/crypto/tls/cipher_suites.go
+++ b/src/crypto/tls/cipher_suites.go
@@ -13,9 +13,10 @@
 	"crypto/rc4"
 	"crypto/sha1"
 	"crypto/sha256"
-	"crypto/x509"
 	"fmt"
 	"hash"
+	"internal/cpu"
+	"runtime"
 
 	"golang.org/x/crypto/chacha20poly1305"
 )
@@ -46,10 +47,10 @@
 // InsecureCipherSuites.
 //
 // The list is sorted by ID. Note that the default cipher suites selected by
-// this package might depend on logic that can't be captured by a static list.
+// this package might depend on logic that can't be captured by a static list,
+// and might not match those returned by this function.
 func CipherSuites() []*CipherSuite {
 	return []*CipherSuite{
-		{TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, false},
 		{TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
 		{TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
 		{TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
@@ -61,7 +62,6 @@
 
 		{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
 		{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
-		{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, false},
 		{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
 		{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
 		{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
@@ -79,13 +79,15 @@
 // Most applications should not use the cipher suites in this list, and should
 // only use those returned by CipherSuites.
 func InsecureCipherSuites() []*CipherSuite {
-	// RC4 suites are broken because RC4 is.
-	// CBC-SHA256 suites have no Lucky13 countermeasures.
+	// This list includes RC4, CBC_SHA256, and 3DES cipher suites. See
+	// cipherSuitesPreferenceOrder for details.
 	return []*CipherSuite{
 		{TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
+		{TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
 		{TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
 		{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
 		{TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
+		{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
 		{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
 		{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
 	}
@@ -108,25 +110,6 @@
 	return fmt.Sprintf("0x%04X", id)
 }
 
-// a keyAgreement implements the client and server side of a TLS key agreement
-// protocol by generating and processing key exchange messages.
-type keyAgreement interface {
-	// On the server side, the first two methods are called in order.
-
-	// In the case that the key agreement protocol doesn't use a
-	// ServerKeyExchange message, generateServerKeyExchange can return nil,
-	// nil.
-	generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
-	processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
-
-	// On the client side, the next two methods are called in order.
-
-	// This method may not be called if the server doesn't send a
-	// ServerKeyExchange message.
-	processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
-	generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
-}
-
 const (
 	// suiteECDHE indicates that the cipher suite involves elliptic curve
 	// Diffie-Hellman. This means that it should only be selected when the
@@ -144,12 +127,10 @@
 	// suiteSHA384 indicates that the cipher suite uses SHA384 as the
 	// handshake hash.
 	suiteSHA384
-	// suiteDefaultOff indicates that this cipher suite is not included by
-	// default.
-	suiteDefaultOff
 )
 
-// A cipherSuite is a specific combination of key agreement, cipher and MAC function.
+// A cipherSuite is a TLS 1.0–1.2 cipher suite, and defines the key exchange
+// mechanism, as well as the cipher+MAC pair or the AEAD.
 type cipherSuite struct {
 	id uint16
 	// the lengths, in bytes, of the key material needed for each component.
@@ -164,37 +145,33 @@
 	aead   func(key, fixedNonce []byte) aead
 }
 
-var cipherSuites = []*cipherSuite{
-	// Ciphersuite order is chosen so that ECDHE comes before plain RSA and
-	// AEADs are the top preference.
+var cipherSuites = []*cipherSuite{ // TODO: replace with a map, since the order doesn't matter.
 	{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
 	{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
 	{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
 	{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadAESGCM},
 	{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
 	{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
-	{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
+	{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil},
 	{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
-	{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
+	{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, cipherAES, macSHA256, nil},
 	{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
 	{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
 	{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
 	{TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
 	{TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
-	{TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
+	{TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil},
 	{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
 	{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
 	{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
 	{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
-
-	// RC4-based cipher suites are disabled by default.
-	{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, suiteDefaultOff, cipherRC4, macSHA1, nil},
-	{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE | suiteDefaultOff, cipherRC4, macSHA1, nil},
-	{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteDefaultOff, cipherRC4, macSHA1, nil},
+	{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil},
+	{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil},
+	{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherRC4, macSHA1, nil},
 }
 
-// selectCipherSuite returns the first cipher suite from ids which is also in
-// supportedIDs and passes the ok filter.
+// selectCipherSuite returns the first TLS 1.0–1.2 cipher suite from ids which
+// is also in supportedIDs and passes the ok filter.
 func selectCipherSuite(ids, supportedIDs []uint16, ok func(*cipherSuite) bool) *cipherSuite {
 	for _, id := range ids {
 		candidate := cipherSuiteByID(id)
@@ -220,12 +197,208 @@
 	hash   crypto.Hash
 }
 
-var cipherSuitesTLS13 = []*cipherSuiteTLS13{
+var cipherSuitesTLS13 = []*cipherSuiteTLS13{ // TODO: replace with a map.
 	{TLS_AES_128_GCM_SHA256, 16, aeadAESGCMTLS13, crypto.SHA256},
 	{TLS_CHACHA20_POLY1305_SHA256, 32, aeadChaCha20Poly1305, crypto.SHA256},
 	{TLS_AES_256_GCM_SHA384, 32, aeadAESGCMTLS13, crypto.SHA384},
 }
 
+// cipherSuitesPreferenceOrder is the order in which we'll select (on the
+// server) or advertise (on the client) TLS 1.0–1.2 cipher suites.
+//
+// Cipher suites are filtered but not reordered based on the application and
+// peer's preferences, meaning we'll never select a suite lower in this list if
+// any higher one is available. This makes it more defensible to keep weaker
+// cipher suites enabled, especially on the server side where we get the last
+// word, since there are no known downgrade attacks on cipher suites selection.
+//
+// The list is sorted by applying the following priority rules, stopping at the
+// first (most important) applicable one:
+//
+//   - Anything else comes before RC4
+//
+//       RC4 has practically exploitable biases. See https://www.rc4nomore.com.
+//
+//   - Anything else comes before CBC_SHA256
+//
+//       SHA-256 variants of the CBC ciphersuites don't implement any Lucky13
+//       countermeasures. See http://www.isg.rhul.ac.uk/tls/Lucky13.html and
+//       https://www.imperialviolet.org/2013/02/04/luckythirteen.html.
+//
+//   - Anything else comes before 3DES
+//
+//       3DES has 64-bit blocks, which makes it fundamentally susceptible to
+//       birthday attacks. See https://sweet32.info.
+//
+//   - ECDHE comes before anything else
+//
+//       Once we got the broken stuff out of the way, the most important
+//       property a cipher suite can have is forward secrecy. We don't
+//       implement FFDHE, so that means ECDHE.
+//
+//   - AEADs come before CBC ciphers
+//
+//       Even with Lucky13 countermeasures, MAC-then-Encrypt CBC cipher suites
+//       are fundamentally fragile, and suffered from an endless sequence of
+//       padding oracle attacks. See https://eprint.iacr.org/2015/1129,
+//       https://www.imperialviolet.org/2014/12/08/poodleagain.html, and
+//       https://blog.cloudflare.com/yet-another-padding-oracle-in-openssl-cbc-ciphersuites/.
+//
+//   - AES comes before ChaCha20
+//
+//       When AES hardware is available, AES-128-GCM and AES-256-GCM are faster
+//       than ChaCha20Poly1305.
+//
+//       When AES hardware is not available, AES-128-GCM is one or more of: much
+//       slower, way more complex, and less safe (because not constant time)
+//       than ChaCha20Poly1305.
+//
+//       We use this list if we think both peers have AES hardware, and
+//       cipherSuitesPreferenceOrderNoAES otherwise.
+//
+//   - AES-128 comes before AES-256
+//
+//       The only potential advantages of AES-256 are better multi-target
+//       margins, and hypothetical post-quantum properties. Neither apply to
+//       TLS, and AES-256 is slower due to its four extra rounds (which don't
+//       contribute to the advantages above).
+//
+//   - ECDSA comes before RSA
+//
+//       The relative order of ECDSA and RSA cipher suites doesn't matter,
+//       as they depend on the certificate. Pick one to get a stable order.
+//
+var cipherSuitesPreferenceOrder = []uint16{
+	// AEADs w/ ECDHE
+	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+	TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+	TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+
+	// CBC w/ ECDHE
+	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+	TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+
+	// AEADs w/o ECDHE
+	TLS_RSA_WITH_AES_128_GCM_SHA256,
+	TLS_RSA_WITH_AES_256_GCM_SHA384,
+
+	// CBC w/o ECDHE
+	TLS_RSA_WITH_AES_128_CBC_SHA,
+	TLS_RSA_WITH_AES_256_CBC_SHA,
+
+	// 3DES
+	TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+	TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+
+	// CBC_SHA256
+	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+	TLS_RSA_WITH_AES_128_CBC_SHA256,
+
+	// RC4
+	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+	TLS_RSA_WITH_RC4_128_SHA,
+}
+
+var cipherSuitesPreferenceOrderNoAES = []uint16{
+	// ChaCha20Poly1305
+	TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+
+	// AES-GCM w/ ECDHE
+	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+	TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+
+	// The rest of cipherSuitesPreferenceOrder.
+	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+	TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+	TLS_RSA_WITH_AES_128_GCM_SHA256,
+	TLS_RSA_WITH_AES_256_GCM_SHA384,
+	TLS_RSA_WITH_AES_128_CBC_SHA,
+	TLS_RSA_WITH_AES_256_CBC_SHA,
+	TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+	TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+	TLS_RSA_WITH_AES_128_CBC_SHA256,
+	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+	TLS_RSA_WITH_RC4_128_SHA,
+}
+
+// disabledCipherSuites are not used unless explicitly listed in
+// Config.CipherSuites. They MUST be at the end of cipherSuitesPreferenceOrder.
+var disabledCipherSuites = []uint16{
+	// CBC_SHA256
+	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+	TLS_RSA_WITH_AES_128_CBC_SHA256,
+
+	// RC4
+	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+	TLS_RSA_WITH_RC4_128_SHA,
+}
+
+var (
+	defaultCipherSuitesLen = len(cipherSuitesPreferenceOrder) - len(disabledCipherSuites)
+	defaultCipherSuites    = cipherSuitesPreferenceOrder[:defaultCipherSuitesLen]
+)
+
+// defaultCipherSuitesTLS13 is also the preference order, since there are no
+// disabled by default TLS 1.3 cipher suites. The same AES vs ChaCha20 logic as
+// cipherSuitesPreferenceOrder applies.
+var defaultCipherSuitesTLS13 = []uint16{
+	TLS_AES_128_GCM_SHA256,
+	TLS_AES_256_GCM_SHA384,
+	TLS_CHACHA20_POLY1305_SHA256,
+}
+
+var defaultCipherSuitesTLS13NoAES = []uint16{
+	TLS_CHACHA20_POLY1305_SHA256,
+	TLS_AES_128_GCM_SHA256,
+	TLS_AES_256_GCM_SHA384,
+}
+
+var (
+	hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ
+	hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
+	// Keep in sync with crypto/aes/cipher_s390x.go.
+	hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR &&
+		(cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)
+
+	hasAESGCMHardwareSupport = runtime.GOARCH == "amd64" && hasGCMAsmAMD64 ||
+		runtime.GOARCH == "arm64" && hasGCMAsmARM64 ||
+		runtime.GOARCH == "s390x" && hasGCMAsmS390X
+)
+
+var aesgcmCiphers = map[uint16]bool{
+	// TLS 1.2
+	TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:   true,
+	TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:   true,
+	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true,
+	TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true,
+	// TLS 1.3
+	TLS_AES_128_GCM_SHA256: true,
+	TLS_AES_256_GCM_SHA384: true,
+}
+
+var nonAESGCMAEADCiphers = map[uint16]bool{
+	// TLS 1.2
+	TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:   true,
+	TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: true,
+	// TLS 1.3
+	TLS_CHACHA20_POLY1305_SHA256: true,
+}
+
+// aesgcmPreferred returns whether the first known cipher in the preference list
+// is an AES-GCM cipher, implying the peer has hardware support for it.
+func aesgcmPreferred(ciphers []uint16) bool {
+	for _, cID := range ciphers {
+		if c := cipherSuiteByID(cID); c != nil {
+			return aesgcmCiphers[cID]
+		}
+		if c := cipherSuiteTLS13ByID(cID); c != nil {
+			return aesgcmCiphers[cID]
+		}
+	}
+	return false
+}
+
 func cipherRC4(key, iv []byte, isRead bool) interface{} {
 	cipher, _ := rc4.NewCipher(key)
 	return cipher
diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go
index eec6e1e..d561e61 100644
--- a/src/crypto/tls/common.go
+++ b/src/crypto/tls/common.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"container/list"
+	"context"
 	"crypto"
 	"crypto/ecdsa"
 	"crypto/ed25519"
@@ -17,11 +18,8 @@
 	"crypto/x509"
 	"errors"
 	"fmt"
-	"internal/cpu"
 	"io"
 	"net"
-	"runtime"
-	"sort"
 	"strings"
 	"sync"
 	"time"
@@ -443,6 +441,16 @@
 	// config is embedded by the GetCertificate or GetConfigForClient caller,
 	// for use with SupportsCertificate.
 	config *Config
+
+	// ctx is the context of the handshake that is in progress.
+	ctx context.Context
+}
+
+// Context returns the context of the handshake that is in progress.
+// This context is a child of the context passed to HandshakeContext,
+// if any, and is canceled when the handshake concludes.
+func (c *ClientHelloInfo) Context() context.Context {
+	return c.ctx
 }
 
 // CertificateRequestInfo contains information from a server's
@@ -461,6 +469,16 @@
 
 	// Version is the TLS version that was negotiated for this connection.
 	Version uint16
+
+	// ctx is the context of the handshake that is in progress.
+	ctx context.Context
+}
+
+// Context returns the context of the handshake that is in progress.
+// This context is a child of the context passed to HandshakeContext,
+// if any, and is canceled when the handshake concludes.
+func (c *CertificateRequestInfo) Context() context.Context {
+	return c.ctx
 }
 
 // RenegotiationSupport enumerates the different levels of support for TLS
@@ -597,7 +615,11 @@
 	RootCAs *x509.CertPool
 
 	// NextProtos is a list of supported application level protocols, in
-	// order of preference.
+	// order of preference. If both peers support ALPN, the selected
+	// protocol will be one from this list, and the connection will fail
+	// if there is no mutually supported protocol. If NextProtos is empty
+	// or the peer doesn't support ALPN, the connection will succeed and
+	// ConnectionState.NegotiatedProtocol will be empty.
 	NextProtos []string
 
 	// ServerName is used to verify the hostname on the returned
@@ -623,17 +645,21 @@
 	// testing or in combination with VerifyConnection or VerifyPeerCertificate.
 	InsecureSkipVerify bool
 
-	// CipherSuites is a list of supported cipher suites for TLS versions up to
-	// TLS 1.2. If CipherSuites is nil, a default list of secure cipher suites
-	// is used, with a preference order based on hardware performance. The
-	// default cipher suites might change over Go versions. Note that TLS 1.3
-	// ciphersuites are not configurable.
+	// CipherSuites is a list of enabled TLS 1.0–1.2 cipher suites. The order of
+	// the list is ignored. Note that TLS 1.3 ciphersuites are not configurable.
+	//
+	// If CipherSuites is nil, a safe default list is used. The default cipher
+	// suites might change over time.
 	CipherSuites []uint16
 
-	// PreferServerCipherSuites controls whether the server selects the
-	// client's most preferred ciphersuite, or the server's most preferred
-	// ciphersuite. If true then the server's preference, as expressed in
-	// the order of elements in CipherSuites, is used.
+	// PreferServerCipherSuites is a legacy field and has no effect.
+	//
+	// It used to control whether the server would follow the client's or the
+	// server's preference. Servers now select the best mutually supported
+	// cipher suite based on logic that takes into account inferred client
+	// hardware, server hardware, and security.
+	//
+	// Deprected: PreferServerCipherSuites is ignored.
 	PreferServerCipherSuites bool
 
 	// SessionTicketsDisabled may be set to true to disable session ticket and
@@ -925,11 +951,10 @@
 }
 
 func (c *Config) cipherSuites() []uint16 {
-	s := c.CipherSuites
-	if s == nil {
-		s = defaultCipherSuites()
+	if c.CipherSuites != nil {
+		return c.CipherSuites
 	}
-	return s
+	return defaultCipherSuites
 }
 
 var supportedVersions = []uint16{
@@ -1419,87 +1444,6 @@
 	return &emptyConfig
 }
 
-var (
-	once                        sync.Once
-	varDefaultCipherSuites      []uint16
-	varDefaultCipherSuitesTLS13 []uint16
-)
-
-func defaultCipherSuites() []uint16 {
-	once.Do(initDefaultCipherSuites)
-	return varDefaultCipherSuites
-}
-
-func defaultCipherSuitesTLS13() []uint16 {
-	once.Do(initDefaultCipherSuites)
-	return varDefaultCipherSuitesTLS13
-}
-
-var (
-	hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ
-	hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
-	// Keep in sync with crypto/aes/cipher_s390x.go.
-	hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)
-
-	hasAESGCMHardwareSupport = runtime.GOARCH == "amd64" && hasGCMAsmAMD64 ||
-		runtime.GOARCH == "arm64" && hasGCMAsmARM64 ||
-		runtime.GOARCH == "s390x" && hasGCMAsmS390X
-)
-
-func initDefaultCipherSuites() {
-	var topCipherSuites []uint16
-
-	if hasAESGCMHardwareSupport {
-		// If AES-GCM hardware is provided then prioritise AES-GCM
-		// cipher suites.
-		topCipherSuites = []uint16{
-			TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-			TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
-			TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
-			TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
-			TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-			TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
-		}
-		varDefaultCipherSuitesTLS13 = []uint16{
-			TLS_AES_128_GCM_SHA256,
-			TLS_CHACHA20_POLY1305_SHA256,
-			TLS_AES_256_GCM_SHA384,
-		}
-	} else {
-		// Without AES-GCM hardware, we put the ChaCha20-Poly1305
-		// cipher suites first.
-		topCipherSuites = []uint16{
-			TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-			TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
-			TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-			TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
-			TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
-			TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
-		}
-		varDefaultCipherSuitesTLS13 = []uint16{
-			TLS_CHACHA20_POLY1305_SHA256,
-			TLS_AES_128_GCM_SHA256,
-			TLS_AES_256_GCM_SHA384,
-		}
-	}
-
-	varDefaultCipherSuites = make([]uint16, 0, len(cipherSuites))
-	varDefaultCipherSuites = append(varDefaultCipherSuites, topCipherSuites...)
-
-NextCipherSuite:
-	for _, suite := range cipherSuites {
-		if suite.flags&suiteDefaultOff != 0 {
-			continue
-		}
-		for _, existing := range varDefaultCipherSuites {
-			if existing == suite.id {
-				continue NextCipherSuite
-			}
-		}
-		varDefaultCipherSuites = append(varDefaultCipherSuites, suite.id)
-	}
-}
-
 func unexpectedMessageError(wanted, got interface{}) error {
 	return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted)
 }
@@ -1512,51 +1456,3 @@
 	}
 	return false
 }
-
-var aesgcmCiphers = map[uint16]bool{
-	// 1.2
-	TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:   true,
-	TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:   true,
-	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true,
-	TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true,
-	// 1.3
-	TLS_AES_128_GCM_SHA256: true,
-	TLS_AES_256_GCM_SHA384: true,
-}
-
-var nonAESGCMAEADCiphers = map[uint16]bool{
-	// 1.2
-	TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:   true,
-	TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: true,
-	// 1.3
-	TLS_CHACHA20_POLY1305_SHA256: true,
-}
-
-// aesgcmPreferred returns whether the first valid cipher in the preference list
-// is an AES-GCM cipher, implying the peer has hardware support for it.
-func aesgcmPreferred(ciphers []uint16) bool {
-	for _, cID := range ciphers {
-		c := cipherSuiteByID(cID)
-		if c == nil {
-			c13 := cipherSuiteTLS13ByID(cID)
-			if c13 == nil {
-				continue
-			}
-			return aesgcmCiphers[cID]
-		}
-		return aesgcmCiphers[cID]
-	}
-	return false
-}
-
-// deprioritizeAES reorders cipher preference lists by rearranging
-// adjacent AEAD ciphers such that AES-GCM based ciphers are moved
-// after other AEAD ciphers. It returns a fresh slice.
-func deprioritizeAES(ciphers []uint16) []uint16 {
-	reordered := make([]uint16, len(ciphers))
-	copy(reordered, ciphers)
-	sort.SliceStable(reordered, func(i, j int) bool {
-		return nonAESGCMAEADCiphers[reordered[i]] && aesgcmCiphers[reordered[j]]
-	})
-	return reordered
-}
diff --git a/src/crypto/tls/conn.go b/src/crypto/tls/conn.go
index 72ad52c..969f357 100644
--- a/src/crypto/tls/conn.go
+++ b/src/crypto/tls/conn.go
@@ -8,6 +8,7 @@
 
 import (
 	"bytes"
+	"context"
 	"crypto/cipher"
 	"crypto/subtle"
 	"crypto/x509"
@@ -27,7 +28,7 @@
 	// constant
 	conn        net.Conn
 	isClient    bool
-	handshakeFn func() error // (*Conn).clientHandshake or serverHandshake
+	handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake
 
 	// handshakeStatus is 1 if the connection is currently transferring
 	// application data (i.e. is not currently processing a handshake).
@@ -1190,7 +1191,7 @@
 	defer c.handshakeMutex.Unlock()
 
 	atomic.StoreUint32(&c.handshakeStatus, 0)
-	if c.handshakeErr = c.clientHandshake(); c.handshakeErr == nil {
+	if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil {
 		c.handshakes++
 	}
 	return c.handshakeErr
@@ -1373,8 +1374,61 @@
 // first Read or Write will call it automatically.
 //
 // For control over canceling or setting a timeout on a handshake, use
-// the Dialer's DialContext method.
+// HandshakeContext or the Dialer's DialContext method instead.
 func (c *Conn) Handshake() error {
+	return c.HandshakeContext(context.Background())
+}
+
+// HandshakeContext runs the client or server handshake
+// protocol if it has not yet been run.
+//
+// The provided Context must be non-nil. If the context is canceled before
+// the handshake is complete, the handshake is interrupted and an error is returned.
+// Once the handshake has completed, cancellation of the context will not affect the
+// connection.
+//
+// Most uses of this package need not call HandshakeContext explicitly: the
+// first Read or Write will call it automatically.
+func (c *Conn) HandshakeContext(ctx context.Context) error {
+	// Delegate to unexported method for named return
+	// without confusing documented signature.
+	return c.handshakeContext(ctx)
+}
+
+func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
+	handshakeCtx, cancel := context.WithCancel(ctx)
+	// Note: defer this before starting the "interrupter" goroutine
+	// so that we can tell the difference between the input being canceled and
+	// this cancellation. In the former case, we need to close the connection.
+	defer cancel()
+
+	// Start the "interrupter" goroutine, if this context might be canceled.
+	// (The background context cannot).
+	//
+	// The interrupter goroutine waits for the input context to be done and
+	// closes the connection if this happens before the function returns.
+	if ctx.Done() != nil {
+		done := make(chan struct{})
+		interruptRes := make(chan error, 1)
+		defer func() {
+			close(done)
+			if ctxErr := <-interruptRes; ctxErr != nil {
+				// Return context error to user.
+				ret = ctxErr
+			}
+		}()
+		go func() {
+			select {
+			case <-handshakeCtx.Done():
+				// Close the connection, discarding the error
+				_ = c.conn.Close()
+				interruptRes <- handshakeCtx.Err()
+			case <-done:
+				interruptRes <- nil
+			}
+		}()
+	}
+
 	c.handshakeMutex.Lock()
 	defer c.handshakeMutex.Unlock()
 
@@ -1388,7 +1442,7 @@
 	c.in.Lock()
 	defer c.in.Unlock()
 
-	c.handshakeErr = c.handshakeFn()
+	c.handshakeErr = c.handshakeFn(handshakeCtx)
 	if c.handshakeErr == nil {
 		c.handshakes++
 	} else {
diff --git a/src/crypto/tls/generate_cert.go b/src/crypto/tls/generate_cert.go
index 1857185..7ea90f8 100644
--- a/src/crypto/tls/generate_cert.go
+++ b/src/crypto/tls/generate_cert.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // Generate a self-signed X.509 certificate for a TLS server. Outputs to
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
index e684b21..4af3d99 100644
--- a/src/crypto/tls/handshake_client.go
+++ b/src/crypto/tls/handshake_client.go
@@ -6,6 +6,7 @@
 
 import (
 	"bytes"
+	"context"
 	"crypto"
 	"crypto/ecdsa"
 	"crypto/ed25519"
@@ -24,6 +25,7 @@
 
 type clientHandshakeState struct {
 	c            *Conn
+	ctx          context.Context
 	serverHello  *serverHelloMsg
 	hello        *clientHelloMsg
 	suite        *cipherSuite
@@ -82,22 +84,24 @@
 		hello.secureRenegotiation = c.clientFinished[:]
 	}
 
-	possibleCipherSuites := config.cipherSuites()
-	hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
+	preferenceOrder := cipherSuitesPreferenceOrder
+	if !hasAESGCMHardwareSupport {
+		preferenceOrder = cipherSuitesPreferenceOrderNoAES
+	}
+	configCipherSuites := config.cipherSuites()
+	hello.cipherSuites = make([]uint16, 0, len(configCipherSuites))
 
-	for _, suiteId := range possibleCipherSuites {
-		for _, suite := range cipherSuites {
-			if suite.id != suiteId {
-				continue
-			}
-			// Don't advertise TLS 1.2-only cipher suites unless
-			// we're attempting TLS 1.2.
-			if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
-				break
-			}
-			hello.cipherSuites = append(hello.cipherSuites, suiteId)
-			break
+	for _, suiteId := range preferenceOrder {
+		suite := mutualCipherSuite(configCipherSuites, suiteId)
+		if suite == nil {
+			continue
 		}
+		// Don't advertise TLS 1.2-only cipher suites unless
+		// we're attempting TLS 1.2.
+		if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
+			continue
+		}
+		hello.cipherSuites = append(hello.cipherSuites, suiteId)
 	}
 
 	_, err := io.ReadFull(config.rand(), hello.random)
@@ -118,7 +122,11 @@
 
 	var params ecdheParameters
 	if hello.supportedVersions[0] == VersionTLS13 {
-		hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13()...)
+		if hasAESGCMHardwareSupport {
+			hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
+		} else {
+			hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...)
+		}
 
 		curveID := config.curvePreferences()[0]
 		if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
@@ -134,7 +142,7 @@
 	return hello, params, nil
 }
 
-func (c *Conn) clientHandshake() (err error) {
+func (c *Conn) clientHandshake(ctx context.Context) (err error) {
 	if c.config == nil {
 		c.config = defaultConfig()
 	}
@@ -198,6 +206,7 @@
 	if c.vers == VersionTLS13 {
 		hs := &clientHandshakeStateTLS13{
 			c:           c,
+			ctx:         ctx,
 			serverHello: serverHello,
 			hello:       hello,
 			ecdheParams: ecdheParams,
@@ -212,6 +221,7 @@
 
 	hs := &clientHandshakeState{
 		c:           c,
+		ctx:         ctx,
 		serverHello: serverHello,
 		hello:       hello,
 		session:     session,
@@ -540,7 +550,7 @@
 		certRequested = true
 		hs.finishedHash.Write(certReq.marshal())
 
-		cri := certificateRequestInfoFromMsg(c.vers, certReq)
+		cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq)
 		if chainToSend, err = c.getClientCertificate(cri); err != nil {
 			c.sendAlert(alertInternalError)
 			return err
@@ -701,17 +711,11 @@
 		}
 	}
 
-	if hs.serverHello.alpnProtocol != "" {
-		if len(hs.hello.alpnProtocols) == 0 {
-			c.sendAlert(alertUnsupportedExtension)
-			return false, errors.New("tls: server advertised unrequested ALPN extension")
-		}
-		if mutualProtocol([]string{hs.serverHello.alpnProtocol}, hs.hello.alpnProtocols) == "" {
-			c.sendAlert(alertUnsupportedExtension)
-			return false, errors.New("tls: server selected unadvertised ALPN protocol")
-		}
-		c.clientProtocol = hs.serverHello.alpnProtocol
+	if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol); err != nil {
+		c.sendAlert(alertUnsupportedExtension)
+		return false, err
 	}
+	c.clientProtocol = hs.serverHello.alpnProtocol
 
 	c.scts = hs.serverHello.scts
 
@@ -743,6 +747,23 @@
 	return true, nil
 }
 
+// checkALPN ensure that the server's choice of ALPN protocol is compatible with
+// the protocols that we advertised in the Client Hello.
+func checkALPN(clientProtos []string, serverProto string) error {
+	if serverProto == "" {
+		return nil
+	}
+	if len(clientProtos) == 0 {
+		return errors.New("tls: server advertised unrequested ALPN extension")
+	}
+	for _, proto := range clientProtos {
+		if proto == serverProto {
+			return nil
+		}
+	}
+	return errors.New("tls: server selected unadvertised ALPN protocol")
+}
+
 func (hs *clientHandshakeState) readFinished(out []byte) error {
 	c := hs.c
 
@@ -880,10 +901,11 @@
 
 // certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS
 // <= 1.2 CertificateRequest, making an effort to fill in missing information.
-func certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
+func certificateRequestInfoFromMsg(ctx context.Context, vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
 	cri := &CertificateRequestInfo{
 		AcceptableCAs: certReq.certificateAuthorities,
 		Version:       vers,
+		ctx:           ctx,
 	}
 
 	var rsaAvail, ecAvail bool
@@ -968,19 +990,6 @@
 	return serverAddr.String()
 }
 
-// mutualProtocol finds the mutual ALPN protocol given list of possible
-// protocols and a list of the preference order.
-func mutualProtocol(protos, preferenceProtos []string) string {
-	for _, s := range preferenceProtos {
-		for _, c := range protos {
-			if s == c {
-				return s
-			}
-		}
-	}
-	return ""
-}
-
 // hostnameInSNI converts name into an appropriate hostname for SNI.
 // Literal IP addresses and absolute FQDNs are not permitted as SNI values.
 // See RFC 6066, Section 3.
diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go
index 12b0254..b6eb488 100644
--- a/src/crypto/tls/handshake_client_test.go
+++ b/src/crypto/tls/handshake_client_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bytes"
+	"context"
 	"crypto/rsa"
 	"crypto/x509"
 	"encoding/base64"
@@ -20,6 +21,7 @@
 	"os/exec"
 	"path/filepath"
 	"reflect"
+	"runtime"
 	"strconv"
 	"strings"
 	"testing"
@@ -42,7 +44,7 @@
 	// opensslSentinel on the connection.
 	opensslSendSentinel
 
-	// opensslKeyUpdate causes OpenSSL to send send a key update message to the
+	// opensslKeyUpdate causes OpenSSL to send a key update message to the
 	// client and request one back.
 	opensslKeyUpdate
 )
@@ -1222,6 +1224,56 @@
 	runClientTestTLS13(t, test)
 }
 
+func TestServerSelectingUnconfiguredApplicationProtocol(t *testing.T) {
+	// This checks that the server can't select an application protocol that the
+	// client didn't offer.
+
+	c, s := localPipe(t)
+	errChan := make(chan error, 1)
+
+	go func() {
+		client := Client(c, &Config{
+			ServerName:   "foo",
+			CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+			NextProtos:   []string{"http", "something-else"},
+		})
+		errChan <- client.Handshake()
+	}()
+
+	var header [5]byte
+	if _, err := io.ReadFull(s, header[:]); err != nil {
+		t.Fatal(err)
+	}
+	recordLen := int(header[3])<<8 | int(header[4])
+
+	record := make([]byte, recordLen)
+	if _, err := io.ReadFull(s, record); err != nil {
+		t.Fatal(err)
+	}
+
+	serverHello := &serverHelloMsg{
+		vers:         VersionTLS12,
+		random:       make([]byte, 32),
+		cipherSuite:  TLS_RSA_WITH_AES_128_GCM_SHA256,
+		alpnProtocol: "how-about-this",
+	}
+	serverHelloBytes := serverHello.marshal()
+
+	s.Write([]byte{
+		byte(recordTypeHandshake),
+		byte(VersionTLS12 >> 8),
+		byte(VersionTLS12 & 0xff),
+		byte(len(serverHelloBytes) >> 8),
+		byte(len(serverHelloBytes)),
+	})
+	s.Write(serverHelloBytes)
+	s.Close()
+
+	if err := <-errChan; !strings.Contains(err.Error(), "server selected unadvertised ALPN protocol") {
+		t.Fatalf("Expected error about unconfigured cipher suite but got %q", err)
+	}
+}
+
 // sctsBase64 contains data from `openssl s_client -serverinfo 18 -connect ritter.vg:443`
 const sctsBase64 = "ABIBaQFnAHUApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFHl5nuFgAABAMARjBEAiAcS4JdlW5nW9sElUv2zvQyPoZ6ejKrGGB03gjaBZFMLwIgc1Qbbn+hsH0RvObzhS+XZhr3iuQQJY8S9G85D9KeGPAAdgBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAUeX4bVwAAAEAwBHMEUCIDIhFDgG2HIuADBkGuLobU5a4dlCHoJLliWJ1SYT05z6AiEAjxIoZFFPRNWMGGIjskOTMwXzQ1Wh2e7NxXE1kd1J0QsAdgDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAUhcZIqHAAAEAwBHMEUCICmJ1rBT09LpkbzxtUC+Hi7nXLR0J+2PmwLp+sJMuqK+AiEAr0NkUnEVKVhAkccIFpYDqHOlZaBsuEhWWrYpg2RtKp0="
 
@@ -1528,7 +1580,7 @@
 					}
 					if c.DidResume {
 						return nil
-						// The SCTs and OCSP Responce are dropped on resumption.
+						// The SCTs and OCSP Response are dropped on resumption.
 						// See http://golang.org/issue/39075.
 					}
 					if len(c.OCSPResponse) == 0 {
@@ -1569,7 +1621,7 @@
 					}
 					if c.DidResume {
 						return nil
-						// The SCTs and OCSP Responce are dropped on resumption.
+						// The SCTs and OCSP Response are dropped on resumption.
 						// See http://golang.org/issue/39075.
 					}
 					if len(c.OCSPResponse) == 0 {
@@ -1619,7 +1671,7 @@
 					}
 					if c.DidResume {
 						return nil
-						// The SCTs and OCSP Responce are dropped on resumption.
+						// The SCTs and OCSP Response are dropped on resumption.
 						// See http://golang.org/issue/39075.
 					}
 					if len(c.OCSPResponse) == 0 {
@@ -2511,3 +2563,35 @@
 			serverConfig.Certificates[0].SignedCertificateTimestamps, ccs.SignedCertificateTimestamps)
 	}
 }
+
+// TestClientHandshakeContextCancellation tests that cancelling
+// the context given to the client side conn.HandshakeContext
+// interrupts the in-progress handshake.
+func TestClientHandshakeContextCancellation(t *testing.T) {
+	c, s := localPipe(t)
+	ctx, cancel := context.WithCancel(context.Background())
+	unblockServer := make(chan struct{})
+	defer close(unblockServer)
+	go func() {
+		cancel()
+		<-unblockServer
+		_ = s.Close()
+	}()
+	cli := Client(c, testConfig)
+	// Initiates client side handshake, which will block until the client hello is read
+	// by the server, unless the cancellation works.
+	err := cli.HandshakeContext(ctx)
+	if err == nil {
+		t.Fatal("Client handshake did not error when the context was canceled")
+	}
+	if err != context.Canceled {
+		t.Errorf("Unexpected client handshake error: %v", err)
+	}
+	if runtime.GOARCH == "wasm" {
+		t.Skip("conn.Close does not error as expected when called multiple times on WASM")
+	}
+	err = cli.Close()
+	if err == nil {
+		t.Error("Client connection was not closed when the context was canceled")
+	}
+}
diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go
index daa5d97..eb59ac9 100644
--- a/src/crypto/tls/handshake_client_tls13.go
+++ b/src/crypto/tls/handshake_client_tls13.go
@@ -6,6 +6,7 @@
 
 import (
 	"bytes"
+	"context"
 	"crypto"
 	"crypto/hmac"
 	"crypto/rsa"
@@ -17,6 +18,7 @@
 
 type clientHandshakeStateTLS13 struct {
 	c           *Conn
+	ctx         context.Context
 	serverHello *serverHelloMsg
 	hello       *clientHelloMsg
 	ecdheParams ecdheParameters
@@ -394,17 +396,11 @@
 	}
 	hs.transcript.Write(encryptedExtensions.marshal())
 
-	if encryptedExtensions.alpnProtocol != "" {
-		if len(hs.hello.alpnProtocols) == 0 {
-			c.sendAlert(alertUnsupportedExtension)
-			return errors.New("tls: server advertised unrequested ALPN extension")
-		}
-		if mutualProtocol([]string{encryptedExtensions.alpnProtocol}, hs.hello.alpnProtocols) == "" {
-			c.sendAlert(alertUnsupportedExtension)
-			return errors.New("tls: server selected unadvertised ALPN protocol")
-		}
-		c.clientProtocol = encryptedExtensions.alpnProtocol
+	if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol); err != nil {
+		c.sendAlert(alertUnsupportedExtension)
+		return err
 	}
+	c.clientProtocol = encryptedExtensions.alpnProtocol
 
 	return nil
 }
@@ -555,6 +551,7 @@
 		AcceptableCAs:    hs.certReq.certificateAuthorities,
 		SignatureSchemes: hs.certReq.supportedSignatureAlgorithms,
 		Version:          c.vers,
+		ctx:              hs.ctx,
 	})
 	if err != nil {
 		return err
diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go
index 9c3e0f6..43f30e2 100644
--- a/src/crypto/tls/handshake_server.go
+++ b/src/crypto/tls/handshake_server.go
@@ -5,6 +5,7 @@
 package tls
 
 import (
+	"context"
 	"crypto"
 	"crypto/ecdsa"
 	"crypto/ed25519"
@@ -23,6 +24,7 @@
 // It's discarded once the handshake has completed.
 type serverHandshakeState struct {
 	c            *Conn
+	ctx          context.Context
 	clientHello  *clientHelloMsg
 	hello        *serverHelloMsg
 	suite        *cipherSuite
@@ -37,8 +39,8 @@
 }
 
 // serverHandshake performs a TLS handshake as a server.
-func (c *Conn) serverHandshake() error {
-	clientHello, err := c.readClientHello()
+func (c *Conn) serverHandshake(ctx context.Context) error {
+	clientHello, err := c.readClientHello(ctx)
 	if err != nil {
 		return err
 	}
@@ -46,6 +48,7 @@
 	if c.vers == VersionTLS13 {
 		hs := serverHandshakeStateTLS13{
 			c:           c,
+			ctx:         ctx,
 			clientHello: clientHello,
 		}
 		return hs.handshake()
@@ -53,6 +56,7 @@
 
 	hs := serverHandshakeState{
 		c:           c,
+		ctx:         ctx,
 		clientHello: clientHello,
 	}
 	return hs.handshake()
@@ -124,7 +128,7 @@
 }
 
 // readClientHello reads a ClientHello message and selects the protocol version.
-func (c *Conn) readClientHello() (*clientHelloMsg, error) {
+func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
 	msg, err := c.readHandshake()
 	if err != nil {
 		return nil, err
@@ -138,7 +142,7 @@
 	var configForClient *Config
 	originalConfig := c.config
 	if c.config.GetConfigForClient != nil {
-		chi := clientHelloInfo(c, clientHello)
+		chi := clientHelloInfo(ctx, c, clientHello)
 		if configForClient, err = c.config.GetConfigForClient(chi); err != nil {
 			c.sendAlert(alertInternalError)
 			return nil, err
@@ -213,14 +217,15 @@
 		c.serverName = hs.clientHello.serverName
 	}
 
-	if len(hs.clientHello.alpnProtocols) > 0 {
-		if selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); selectedProto != "" {
-			hs.hello.alpnProtocol = selectedProto
-			c.clientProtocol = selectedProto
-		}
+	selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
+	if err != nil {
+		c.sendAlert(alertNoApplicationProtocol)
+		return err
 	}
+	hs.hello.alpnProtocol = selectedProto
+	c.clientProtocol = selectedProto
 
-	hs.cert, err = c.config.getCertificate(clientHelloInfo(c, hs.clientHello))
+	hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
 	if err != nil {
 		if err == errNoCertificates {
 			c.sendAlert(alertUnrecognizedName)
@@ -270,6 +275,34 @@
 	return nil
 }
 
+// negotiateALPN picks a shared ALPN protocol that both sides support in server
+// preference order. If ALPN is not configured or the peer doesn't support it,
+// it returns "" and no error.
+func negotiateALPN(serverProtos, clientProtos []string) (string, error) {
+	if len(serverProtos) == 0 || len(clientProtos) == 0 {
+		return "", nil
+	}
+	var http11fallback bool
+	for _, s := range serverProtos {
+		for _, c := range clientProtos {
+			if s == c {
+				return s, nil
+			}
+			if s == "h2" && c == "http/1.1" {
+				http11fallback = true
+			}
+		}
+	}
+	// As a special case, let http/1.1 clients connect to h2 servers as if they
+	// didn't support ALPN. We used not to enforce protocol overlap, so over
+	// time a number of HTTP servers were configured with only "h2", but
+	// expected to accept connections from "http/1.1" clients. See Issue 46310.
+	if http11fallback {
+		return "", nil
+	}
+	return "", fmt.Errorf("tls: client requested unsupported application protocols (%s)", clientProtos)
+}
+
 // supportsECDHE returns whether ECDHE key exchanges can be used with this
 // pre-TLS 1.3 client.
 func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8) bool {
@@ -295,30 +328,23 @@
 func (hs *serverHandshakeState) pickCipherSuite() error {
 	c := hs.c
 
-	var preferenceList, supportedList []uint16
-	if c.config.PreferServerCipherSuites {
-		preferenceList = c.config.cipherSuites()
-		supportedList = hs.clientHello.cipherSuites
+	preferenceOrder := cipherSuitesPreferenceOrder
+	if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
+		preferenceOrder = cipherSuitesPreferenceOrderNoAES
+	}
 
-		// If the client does not seem to have hardware support for AES-GCM,
-		// and the application did not specify a cipher suite preference order,
-		// prefer other AEAD ciphers even if we prioritized AES-GCM ciphers
-		// by default.
-		if c.config.CipherSuites == nil && !aesgcmPreferred(hs.clientHello.cipherSuites) {
-			preferenceList = deprioritizeAES(preferenceList)
-		}
-	} else {
-		preferenceList = hs.clientHello.cipherSuites
-		supportedList = c.config.cipherSuites()
-
-		// If we don't have hardware support for AES-GCM, prefer other AEAD
-		// ciphers even if the client prioritized AES-GCM.
-		if !hasAESGCMHardwareSupport {
-			preferenceList = deprioritizeAES(preferenceList)
+	configCipherSuites := c.config.cipherSuites()
+	preferenceList := make([]uint16, 0, len(configCipherSuites))
+	for _, suiteID := range preferenceOrder {
+		for _, id := range configCipherSuites {
+			if id == suiteID {
+				preferenceList = append(preferenceList, id)
+				break
+			}
 		}
 	}
 
-	hs.suite = selectCipherSuite(preferenceList, supportedList, hs.cipherSuiteOk)
+	hs.suite = selectCipherSuite(preferenceList, hs.clientHello.cipherSuites, hs.cipherSuiteOk)
 	if hs.suite == nil {
 		c.sendAlert(alertHandshakeFailure)
 		return errors.New("tls: no cipher suite supported by both client and server")
@@ -828,7 +854,7 @@
 	return nil
 }
 
-func clientHelloInfo(c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
+func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
 	supportedVersions := clientHello.supportedVersions
 	if len(clientHello.supportedVersions) == 0 {
 		supportedVersions = supportedVersionsFromMax(clientHello.vers)
@@ -844,5 +870,6 @@
 		SupportedVersions: supportedVersions,
 		Conn:              c.conn,
 		config:            c.config,
+		ctx:               ctx,
 	}
 }
diff --git a/src/crypto/tls/handshake_server_test.go b/src/crypto/tls/handshake_server_test.go
index d6bf9e4..f61b4c8 100644
--- a/src/crypto/tls/handshake_server_test.go
+++ b/src/crypto/tls/handshake_server_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bytes"
+	"context"
 	"crypto"
 	"crypto/elliptic"
 	"crypto/x509"
@@ -17,6 +18,7 @@
 	"os"
 	"os/exec"
 	"path/filepath"
+	"runtime"
 	"strings"
 	"testing"
 	"time"
@@ -38,10 +40,12 @@
 		cli.writeRecord(recordTypeHandshake, m.marshal())
 		c.Close()
 	}()
+	ctx := context.Background()
 	conn := Server(s, serverConfig)
-	ch, err := conn.readClientHello()
+	ch, err := conn.readClientHello(ctx)
 	hs := serverHandshakeState{
 		c:           conn,
+		ctx:         ctx,
 		clientHello: ch,
 	}
 	if err == nil {
@@ -393,30 +397,30 @@
 
 func TestCipherSuitePreference(t *testing.T) {
 	serverConfig := &Config{
-		CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+		CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_AES_128_GCM_SHA256,
+			TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
 		Certificates: testConfig.Certificates,
-		MaxVersion:   VersionTLS11,
+		MaxVersion:   VersionTLS12,
+		GetConfigForClient: func(chi *ClientHelloInfo) (*Config, error) {
+			if chi.CipherSuites[0] != TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 {
+				t.Error("the advertised order should not depend on Config.CipherSuites")
+			}
+			if len(chi.CipherSuites) != 2+len(defaultCipherSuitesTLS13) {
+				t.Error("the advertised TLS 1.2 suites should be filtered by Config.CipherSuites")
+			}
+			return nil, nil
+		},
 	}
 	clientConfig := &Config{
-		CipherSuites:       []uint16{TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_RC4_128_SHA},
+		CipherSuites:       []uint16{TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
 		InsecureSkipVerify: true,
 	}
 	state, _, err := testHandshake(t, clientConfig, serverConfig)
 	if err != nil {
 		t.Fatalf("handshake failed: %s", err)
 	}
-	if state.CipherSuite != TLS_RSA_WITH_AES_128_CBC_SHA {
-		// By default the server should use the client's preference.
-		t.Fatalf("Client's preference was not used, got %x", state.CipherSuite)
-	}
-
-	serverConfig.PreferServerCipherSuites = true
-	state, _, err = testHandshake(t, clientConfig, serverConfig)
-	if err != nil {
-		t.Fatalf("handshake failed: %s", err)
-	}
-	if state.CipherSuite != TLS_RSA_WITH_RC4_128_SHA {
-		t.Fatalf("Server's preference was not used, got %x", state.CipherSuite)
+	if state.CipherSuite != TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 {
+		t.Error("the preference order should not depend on Config.CipherSuites")
 	}
 }
 
@@ -916,13 +920,48 @@
 		name: "ALPN-NoMatch",
 		// Note that this needs OpenSSL 1.0.2 because that is the first
 		// version that supports the -alpn flag.
+		command:                       []string{"openssl", "s_client", "-alpn", "proto2,proto1", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+		config:                        config,
+		expectHandshakeErrorIncluding: "client requested unsupported application protocol",
+	}
+	runServerTestTLS12(t, test)
+	runServerTestTLS13(t, test)
+}
+
+func TestHandshakeServerALPNNotConfigured(t *testing.T) {
+	config := testConfig.Clone()
+	config.NextProtos = nil
+
+	test := &serverTest{
+		name: "ALPN-NotConfigured",
+		// Note that this needs OpenSSL 1.0.2 because that is the first
+		// version that supports the -alpn flag.
 		command: []string{"openssl", "s_client", "-alpn", "proto2,proto1", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
 		config:  config,
 		validate: func(state ConnectionState) error {
-			// Rather than reject the connection, Go doesn't select
-			// a protocol when there is no overlap.
 			if state.NegotiatedProtocol != "" {
-				return fmt.Errorf("Got protocol %q, wanted ''", state.NegotiatedProtocol)
+				return fmt.Errorf("Got protocol %q, wanted nothing", state.NegotiatedProtocol)
+			}
+			return nil
+		},
+	}
+	runServerTestTLS12(t, test)
+	runServerTestTLS13(t, test)
+}
+
+func TestHandshakeServerALPNFallback(t *testing.T) {
+	config := testConfig.Clone()
+	config.NextProtos = []string{"proto1", "h2", "proto2"}
+
+	test := &serverTest{
+		name: "ALPN-Fallback",
+		// Note that this needs OpenSSL 1.0.2 because that is the first
+		// version that supports the -alpn flag.
+		command: []string{"openssl", "s_client", "-alpn", "proto3,http/1.1,proto4", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+		config:  config,
+		validate: func(state ConnectionState) error {
+			if state.NegotiatedProtocol != "" {
+				return fmt.Errorf("Got protocol %q, wanted nothing", state.NegotiatedProtocol)
 			}
 			return nil
 		},
@@ -1032,37 +1071,6 @@
 	testClientHelloFailure(t, serverConfig, clientHello, "no certificates")
 }
 
-// TestCipherSuiteCertPreferance ensures that we select an RSA ciphersuite with
-// an RSA certificate and an ECDSA ciphersuite with an ECDSA certificate.
-func TestCipherSuiteCertPreferenceECDSA(t *testing.T) {
-	config := testConfig.Clone()
-	config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}
-	config.PreferServerCipherSuites = true
-
-	test := &serverTest{
-		name:   "CipherSuiteCertPreferenceRSA",
-		config: config,
-	}
-	runServerTestTLS12(t, test)
-
-	config = testConfig.Clone()
-	config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}
-	config.Certificates = []Certificate{
-		{
-			Certificate: [][]byte{testECDSACertificate},
-			PrivateKey:  testECDSAPrivateKey,
-		},
-	}
-	config.BuildNameToCertificate()
-	config.PreferServerCipherSuites = true
-
-	test = &serverTest{
-		name:   "CipherSuiteCertPreferenceECDSA",
-		config: config,
-	}
-	runServerTestTLS12(t, test)
-}
-
 func TestServerResumption(t *testing.T) {
 	sessionFilePath := tempFile("")
 	defer os.Remove(sessionFilePath)
@@ -1160,7 +1168,7 @@
 func TestHandshakeServerExportKeyingMaterial(t *testing.T) {
 	test := &serverTest{
 		name:    "ExportKeyingMaterial",
-		command: []string{"openssl", "s_client", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+		command: []string{"openssl", "s_client", "-cipher", "ECDHE-RSA-AES256-SHA", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
 		config:  testConfig.Clone(),
 		validate: func(state ConnectionState) error {
 			if km, err := state.ExportKeyingMaterial("test", nil, 42); err != nil {
@@ -1421,9 +1429,11 @@
 		c.Close()
 	}()
 	conn := Server(s, serverConfig)
-	ch, err := conn.readClientHello()
+	ctx := context.Background()
+	ch, err := conn.readClientHello(ctx)
 	hs := serverHandshakeState{
 		c:           conn,
+		ctx:         ctx,
 		clientHello: ch,
 	}
 	if err == nil {
@@ -1679,15 +1689,14 @@
 
 func TestAESCipherReordering(t *testing.T) {
 	currentAESSupport := hasAESGCMHardwareSupport
-	defer func() { hasAESGCMHardwareSupport = currentAESSupport; initDefaultCipherSuites() }()
+	defer func() { hasAESGCMHardwareSupport = currentAESSupport }()
 
 	tests := []struct {
-		name                     string
-		clientCiphers            []uint16
-		serverHasAESGCM          bool
-		preferServerCipherSuites bool
-		serverCiphers            []uint16
-		expectedCipher           uint16
+		name            string
+		clientCiphers   []uint16
+		serverHasAESGCM bool
+		serverCiphers   []uint16
+		expectedCipher  uint16
 	}{
 		{
 			name: "server has hardware AES, client doesn't (pick ChaCha)",
@@ -1696,25 +1705,8 @@
 				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
 				TLS_RSA_WITH_AES_128_CBC_SHA,
 			},
-			serverHasAESGCM:          true,
-			preferServerCipherSuites: true,
-			expectedCipher:           TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-		},
-		{
-			name: "server strongly prefers AES-GCM, client doesn't (pick AES-GCM)",
-			clientCiphers: []uint16{
-				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-				TLS_RSA_WITH_AES_128_CBC_SHA,
-			},
-			serverHasAESGCM:          true,
-			preferServerCipherSuites: true,
-			serverCiphers: []uint16{
-				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-				TLS_RSA_WITH_AES_128_CBC_SHA,
-			},
-			expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+			serverHasAESGCM: true,
+			expectedCipher:  TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
 		},
 		{
 			name: "client prefers AES-GCM, server doesn't have hardware AES (pick ChaCha)",
@@ -1758,14 +1750,14 @@
 			expectedCipher:  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
 		},
 		{
-			name: "client prefers AES-GCM and AES-CBC over ChaCha, server doesn't have hardware AES (pick AES-GCM)",
+			name: "client prefers AES-GCM and AES-CBC over ChaCha, server doesn't have hardware AES (pick ChaCha)",
 			clientCiphers: []uint16{
 				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
 				TLS_RSA_WITH_AES_128_CBC_SHA,
 				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
 			},
 			serverHasAESGCM: false,
-			expectedCipher:  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+			expectedCipher:  TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
 		},
 		{
 			name: "client prefers AES-GCM over ChaCha and sends GREASE, server doesn't have hardware AES (pick ChaCha)",
@@ -1779,7 +1771,7 @@
 			expectedCipher:  TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
 		},
 		{
-			name: "client supports multiple AES-GCM, server doesn't have hardware AES and doesn't support ChaCha (pick corrent AES-GCM)",
+			name: "client supports multiple AES-GCM, server doesn't have hardware AES and doesn't support ChaCha (AES-GCM)",
 			clientCiphers: []uint16{
 				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
 				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
@@ -1790,19 +1782,30 @@
 				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
 				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
 			},
-			expectedCipher: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+			expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+		},
+		{
+			name: "client prefers AES-GCM, server has hardware but doesn't support AES (pick ChaCha)",
+			clientCiphers: []uint16{
+				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+				TLS_RSA_WITH_AES_128_CBC_SHA,
+			},
+			serverHasAESGCM: true,
+			serverCiphers: []uint16{
+				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+			},
+			expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
 		},
 	}
 
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
 			hasAESGCMHardwareSupport = tc.serverHasAESGCM
-			initDefaultCipherSuites()
 			hs := &serverHandshakeState{
 				c: &Conn{
 					config: &Config{
-						PreferServerCipherSuites: tc.preferServerCipherSuites,
-						CipherSuites:             tc.serverCiphers,
+						CipherSuites: tc.serverCiphers,
 					},
 					vers: VersionTLS12,
 				},
@@ -1827,16 +1830,15 @@
 	}
 }
 
-func TestAESCipherReordering13(t *testing.T) {
+func TestAESCipherReorderingTLS13(t *testing.T) {
 	currentAESSupport := hasAESGCMHardwareSupport
-	defer func() { hasAESGCMHardwareSupport = currentAESSupport; initDefaultCipherSuites() }()
+	defer func() { hasAESGCMHardwareSupport = currentAESSupport }()
 
 	tests := []struct {
-		name                     string
-		clientCiphers            []uint16
-		serverHasAESGCM          bool
-		preferServerCipherSuites bool
-		expectedCipher           uint16
+		name            string
+		clientCiphers   []uint16
+		serverHasAESGCM bool
+		expectedCipher  uint16
 	}{
 		{
 			name: "server has hardware AES, client doesn't (pick ChaCha)",
@@ -1844,9 +1846,8 @@
 				TLS_CHACHA20_POLY1305_SHA256,
 				TLS_AES_128_GCM_SHA256,
 			},
-			serverHasAESGCM:          true,
-			preferServerCipherSuites: true,
-			expectedCipher:           TLS_CHACHA20_POLY1305_SHA256,
+			serverHasAESGCM: true,
+			expectedCipher:  TLS_CHACHA20_POLY1305_SHA256,
 		},
 		{
 			name: "neither server nor client have hardware AES (pick ChaCha)",
@@ -1854,37 +1855,25 @@
 				TLS_CHACHA20_POLY1305_SHA256,
 				TLS_AES_128_GCM_SHA256,
 			},
-			serverHasAESGCM:          false,
-			preferServerCipherSuites: true,
-			expectedCipher:           TLS_CHACHA20_POLY1305_SHA256,
+			serverHasAESGCM: false,
+			expectedCipher:  TLS_CHACHA20_POLY1305_SHA256,
 		},
 		{
-			name: "client prefers AES, server doesn't have hardware, prefer server ciphers (pick ChaCha)",
+			name: "client prefers AES, server doesn't have hardware (pick ChaCha)",
 			clientCiphers: []uint16{
 				TLS_AES_128_GCM_SHA256,
 				TLS_CHACHA20_POLY1305_SHA256,
 			},
-			serverHasAESGCM:          false,
-			preferServerCipherSuites: true,
-			expectedCipher:           TLS_CHACHA20_POLY1305_SHA256,
+			serverHasAESGCM: false,
+			expectedCipher:  TLS_CHACHA20_POLY1305_SHA256,
 		},
 		{
-			name: "client prefers AES and sends GREASE, server doesn't have hardware, prefer server ciphers (pick ChaCha)",
+			name: "client prefers AES and sends GREASE, server doesn't have hardware (pick ChaCha)",
 			clientCiphers: []uint16{
 				0x0A0A, // GREASE value
 				TLS_AES_128_GCM_SHA256,
 				TLS_CHACHA20_POLY1305_SHA256,
 			},
-			serverHasAESGCM:          false,
-			preferServerCipherSuites: true,
-			expectedCipher:           TLS_CHACHA20_POLY1305_SHA256,
-		},
-		{
-			name: "client prefers AES, server doesn't (pick ChaCha)",
-			clientCiphers: []uint16{
-				TLS_AES_128_GCM_SHA256,
-				TLS_CHACHA20_POLY1305_SHA256,
-			},
 			serverHasAESGCM: false,
 			expectedCipher:  TLS_CHACHA20_POLY1305_SHA256,
 		},
@@ -1912,13 +1901,10 @@
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
 			hasAESGCMHardwareSupport = tc.serverHasAESGCM
-			initDefaultCipherSuites()
 			hs := &serverHandshakeStateTLS13{
 				c: &Conn{
-					config: &Config{
-						PreferServerCipherSuites: tc.preferServerCipherSuites,
-					},
-					vers: VersionTLS13,
+					config: &Config{},
+					vers:   VersionTLS13,
 				},
 				clientHello: &clientHelloMsg{
 					cipherSuites:       tc.clientCiphers,
@@ -1939,3 +1925,104 @@
 		})
 	}
 }
+
+// TestServerHandshakeContextCancellation tests that cancelling
+// the context given to the server side conn.HandshakeContext
+// interrupts the in-progress handshake.
+func TestServerHandshakeContextCancellation(t *testing.T) {
+	c, s := localPipe(t)
+	ctx, cancel := context.WithCancel(context.Background())
+	unblockClient := make(chan struct{})
+	defer close(unblockClient)
+	go func() {
+		cancel()
+		<-unblockClient
+		_ = c.Close()
+	}()
+	conn := Server(s, testConfig)
+	// Initiates server side handshake, which will block until a client hello is read
+	// unless the cancellation works.
+	err := conn.HandshakeContext(ctx)
+	if err == nil {
+		t.Fatal("Server handshake did not error when the context was canceled")
+	}
+	if err != context.Canceled {
+		t.Errorf("Unexpected server handshake error: %v", err)
+	}
+	if runtime.GOARCH == "wasm" {
+		t.Skip("conn.Close does not error as expected when called multiple times on WASM")
+	}
+	err = conn.Close()
+	if err == nil {
+		t.Error("Server connection was not closed when the context was canceled")
+	}
+}
+
+// TestHandshakeContextHierarchy tests whether the contexts
+// available to GetClientCertificate and GetCertificate are
+// derived from the context provided to HandshakeContext, and
+// that those contexts are canceled after HandshakeContext has
+// returned.
+func TestHandshakeContextHierarchy(t *testing.T) {
+	c, s := localPipe(t)
+	clientErr := make(chan error, 1)
+	clientConfig := testConfig.Clone()
+	serverConfig := testConfig.Clone()
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+	key := struct{}{}
+	ctx = context.WithValue(ctx, key, true)
+	go func() {
+		defer close(clientErr)
+		defer c.Close()
+		var innerCtx context.Context
+		clientConfig.Certificates = nil
+		clientConfig.GetClientCertificate = func(certificateRequest *CertificateRequestInfo) (*Certificate, error) {
+			if val, ok := certificateRequest.Context().Value(key).(bool); !ok || !val {
+				t.Errorf("GetClientCertificate context was not child of HandshakeContext")
+			}
+			innerCtx = certificateRequest.Context()
+			return &Certificate{
+				Certificate: [][]byte{testRSACertificate},
+				PrivateKey:  testRSAPrivateKey,
+			}, nil
+		}
+		cli := Client(c, clientConfig)
+		err := cli.HandshakeContext(ctx)
+		if err != nil {
+			clientErr <- err
+			return
+		}
+		select {
+		case <-innerCtx.Done():
+		default:
+			t.Errorf("GetClientCertificate context was not canceled after HandshakeContext returned.")
+		}
+	}()
+	var innerCtx context.Context
+	serverConfig.Certificates = nil
+	serverConfig.ClientAuth = RequestClientCert
+	serverConfig.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
+		if val, ok := clientHello.Context().Value(key).(bool); !ok || !val {
+			t.Errorf("GetClientCertificate context was not child of HandshakeContext")
+		}
+		innerCtx = clientHello.Context()
+		return &Certificate{
+			Certificate: [][]byte{testRSACertificate},
+			PrivateKey:  testRSAPrivateKey,
+		}, nil
+	}
+	conn := Server(s, serverConfig)
+	err := conn.HandshakeContext(ctx)
+	if err != nil {
+		t.Errorf("Unexpected server handshake error: %v", err)
+	}
+	select {
+	case <-innerCtx.Done():
+	default:
+		t.Errorf("GetCertificate context was not canceled after HandshakeContext returned.")
+	}
+	if err := <-clientErr; err != nil {
+		t.Errorf("Unexpected client error: %v", err)
+	}
+}
diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go
index c2c288a..08251b8 100644
--- a/src/crypto/tls/handshake_server_tls13.go
+++ b/src/crypto/tls/handshake_server_tls13.go
@@ -6,6 +6,7 @@
 
 import (
 	"bytes"
+	"context"
 	"crypto"
 	"crypto/hmac"
 	"crypto/rsa"
@@ -23,6 +24,7 @@
 
 type serverHandshakeStateTLS13 struct {
 	c               *Conn
+	ctx             context.Context
 	clientHello     *clientHelloMsg
 	hello           *serverHelloMsg
 	sentDummyCCS    bool
@@ -147,29 +149,12 @@
 	hs.hello.sessionId = hs.clientHello.sessionId
 	hs.hello.compressionMethod = compressionNone
 
-	var preferenceList, supportedList []uint16
-	if c.config.PreferServerCipherSuites {
-		preferenceList = defaultCipherSuitesTLS13()
-		supportedList = hs.clientHello.cipherSuites
-
-		// If the client does not seem to have hardware support for AES-GCM,
-		// prefer other AEAD ciphers even if we prioritized AES-GCM ciphers
-		// by default.
-		if !aesgcmPreferred(hs.clientHello.cipherSuites) {
-			preferenceList = deprioritizeAES(preferenceList)
-		}
-	} else {
-		preferenceList = hs.clientHello.cipherSuites
-		supportedList = defaultCipherSuitesTLS13()
-
-		// If we don't have hardware support for AES-GCM, prefer other AEAD
-		// ciphers even if the client prioritized AES-GCM.
-		if !hasAESGCMHardwareSupport {
-			preferenceList = deprioritizeAES(preferenceList)
-		}
+	preferenceList := defaultCipherSuitesTLS13
+	if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
+		preferenceList = defaultCipherSuitesTLS13NoAES
 	}
 	for _, suiteID := range preferenceList {
-		hs.suite = mutualCipherSuiteTLS13(supportedList, suiteID)
+		hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID)
 		if hs.suite != nil {
 			break
 		}
@@ -374,7 +359,7 @@
 		return c.sendAlert(alertMissingExtension)
 	}
 
-	certificate, err := c.config.getCertificate(clientHelloInfo(c, hs.clientHello))
+	certificate, err := c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
 	if err != nil {
 		if err == errNoCertificates {
 			c.sendAlert(alertUnrecognizedName)
@@ -565,12 +550,13 @@
 
 	encryptedExtensions := new(encryptedExtensionsMsg)
 
-	if len(hs.clientHello.alpnProtocols) > 0 {
-		if selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); selectedProto != "" {
-			encryptedExtensions.alpnProtocol = selectedProto
-			c.clientProtocol = selectedProto
-		}
+	selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
+	if err != nil {
+		c.sendAlert(alertNoApplicationProtocol)
+		return err
 	}
+	encryptedExtensions.alpnProtocol = selectedProto
+	c.clientProtocol = selectedProto
 
 	hs.transcript.Write(encryptedExtensions.marshal())
 	if _, err := c.writeRecord(recordTypeHandshake, encryptedExtensions.marshal()); err != nil {
diff --git a/src/crypto/tls/handshake_test.go b/src/crypto/tls/handshake_test.go
index d9ff9fe..9bfb117 100644
--- a/src/crypto/tls/handshake_test.go
+++ b/src/crypto/tls/handshake_test.go
@@ -335,15 +335,9 @@
 }
 
 func runMain(m *testing.M) int {
-	// TLS 1.3 cipher suites preferences are not configurable and change based
-	// on the architecture. Force them to the version with AES acceleration for
-	// test consistency.
-	once.Do(initDefaultCipherSuites)
-	varDefaultCipherSuitesTLS13 = []uint16{
-		TLS_AES_128_GCM_SHA256,
-		TLS_CHACHA20_POLY1305_SHA256,
-		TLS_AES_256_GCM_SHA384,
-	}
+	// Cipher suites preferences change based on the architecture. Force them to
+	// the version without AES acceleration for test consistency.
+	hasAESGCMHardwareSupport = false
 
 	// Set up localPipe.
 	l, err := net.Listen("tcp", "127.0.0.1:0")
diff --git a/src/crypto/tls/handshake_unix_test.go b/src/crypto/tls/handshake_unix_test.go
index 7271854..19fc698 100644
--- a/src/crypto/tls/handshake_unix_test.go
+++ b/src/crypto/tls/handshake_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package tls
diff --git a/src/crypto/tls/key_agreement.go b/src/crypto/tls/key_agreement.go
index 7e6534b..c28a64f 100644
--- a/src/crypto/tls/key_agreement.go
+++ b/src/crypto/tls/key_agreement.go
@@ -15,6 +15,25 @@
 	"io"
 )
 
+// a keyAgreement implements the client and server side of a TLS key agreement
+// protocol by generating and processing key exchange messages.
+type keyAgreement interface {
+	// On the server side, the first two methods are called in order.
+
+	// In the case that the key agreement protocol doesn't use a
+	// ServerKeyExchange message, generateServerKeyExchange can return nil,
+	// nil.
+	generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
+	processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
+
+	// On the client side, the next two methods are called in order.
+
+	// This method may not be called if the server doesn't send a
+	// ServerKeyExchange message.
+	processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
+	generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
+}
+
 var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
 var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message")
 
@@ -67,7 +86,11 @@
 		return nil, nil, err
 	}
 
-	encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)
+	rsaKey, ok := cert.PublicKey.(*rsa.PublicKey)
+	if !ok {
+		return nil, nil, errors.New("tls: server certificate contains incorrect key type for selected ciphersuite")
+	}
+	encrypted, err := rsa.EncryptPKCS1v15(config.rand(), rsaKey, preMasterSecret)
 	if err != nil {
 		return nil, nil, err
 	}
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
index 9de3f14..c7fa530 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 94 1f ba 79 da  |....Y...U.....y.|
-00000010  4b 58 3e 08 2c c5 31 36  a4 7e 32 bf e1 a0 f7 71  |KX>.,.16.~2....q|
-00000020  01 48 63 3c 5f cb 08 7a  25 80 c7 20 35 0c c0 8b  |.Hc<_..z%.. 5...|
-00000030  df 30 fc dc 3d f1 48 96  0d b6 ff a8 cd 35 29 57  |.0..=.H......5)W|
-00000040  7d 3f c2 9d e2 32 b1 c2  4c 05 5e 3b c0 09 00 00  |}?...2..L.^;....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 92 4c b7 e6 07  |....Y...U...L...|
+00000010  09 b4 4a 47 6a 29 c7 79  18 0d 43 37 86 26 21 5a  |..JGj).y..C7.&!Z|
+00000020  25 35 db 5f ae d0 20 0d  85 67 f7 20 75 e5 cb 25  |%5._.. ..g. u..%|
+00000030  4b 5d 95 87 78 00 fc 3f  78 26 e8 77 b5 0d d4 0e  |K]..x..?x&.w....|
+00000040  54 06 66 b4 14 dc 6b db  f2 af f3 2a c0 09 00 00  |T.f...k....*....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -55,18 +55,18 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 01 00 b5 0c 00  00 b1 03 00 1d 20 1a 74  |*............ .t|
-00000280  c4 96 9e 65 45 9a 0a 01  7c ed 7b 51 01 d8 ba 5b  |...eE...|.{Q...[|
-00000290  3e 2f b1 4b 36 69 e8 47  75 7e 27 be b3 2f 00 8b  |>/.K6i.Gu~'../..|
-000002a0  30 81 88 02 42 01 cb 20  d9 1e ae 05 6f 1f 37 ce  |0...B.. ....o.7.|
-000002b0  dc 38 20 2f 8f 52 9a 92  f6 80 d6 f9 97 99 a5 8b  |.8 /.R..........|
-000002c0  6e 73 0b 95 a4 4e 82 67  bd 1a 34 d9 5c 4e b4 d7  |ns...N.g..4.\N..|
-000002d0  35 e6 45 81 14 23 9c 4e  5a 4c 1b 93 fd 7f 43 18  |5.E..#.NZL....C.|
-000002e0  db 54 4b e0 d1 d3 fa 02  42 00 ab 8e 34 d5 c2 04  |.TK.....B...4...|
-000002f0  d0 a4 44 b1 b3 25 a0 af  c8 80 b3 88 ae da b3 c6  |..D..%..........|
-00000300  4f 57 ae 31 54 c6 d9 ee  4e 21 56 01 cc b9 6a e9  |OW.1T...N!V...j.|
-00000310  e9 7e 62 2a 64 0e a4 a0  79 1e a3 64 52 70 b1 a5  |.~b*d...y..dRp..|
-00000320  19 2c a4 6d 4b 3b a3 63  ed 56 2f 16 03 01 00 0a  |.,.mK;.c.V/.....|
+00000270  2a 16 03 01 00 b5 0c 00  00 b1 03 00 1d 20 d7 b5  |*............ ..|
+00000280  51 8e b5 01 4f 02 2f 43  11 2b de 94 7d 82 e6 49  |Q...O./C.+..}..I|
+00000290  1b a6 ee a0 7f 12 35 a2  3a 62 46 ce 07 25 00 8b  |......5.:bF..%..|
+000002a0  30 81 88 02 42 00 83 45  db 03 db b9 74 ce 77 35  |0...B..E....t.w5|
+000002b0  1b e5 76 18 dc 3a d3 ee  32 18 f3 16 a6 c3 62 be  |..v..:..2.....b.|
+000002c0  46 47 40 80 2d a0 08 c5  1e 5a 4a 42 69 8c ee e5  |FG@.-....ZJBi...|
+000002d0  70 b5 71 30 2f 54 32 54  5f 5b 26 62 e1 81 52 9e  |p.q0/T2T_[&b..R.|
+000002e0  49 70 d4 81 e4 76 f1 02  42 01 70 f6 87 84 bb 58  |Ip...v..B.p....X|
+000002f0  5d e4 a1 72 87 d5 35 53  99 9c 3f 30 2b 80 7e c9  |]..r..5S..?0+.~.|
+00000300  79 eb d8 97 3c 82 ff 37  a5 8d 36 bc 27 c1 51 58  |y...<..7..6.'.QX|
+00000310  e6 2a 48 05 bf 9b a4 a5  b1 7f 77 b8 d9 3e 37 c6  |.*H.......w..>7.|
+00000320  67 ad ef 8c 72 ea f6 ba  bb af 00 16 03 01 00 0a  |g...r...........|
 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)
@@ -105,30 +105,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 90 0f 00  |...._X.;t.......|
-00000240  00 8c 00 8a 30 81 87 02  42 01 89 0f 43 df a8 34  |....0...B...C..4|
-00000250  dd d7 c9 d4 2b 8d ec 29  77 7b 64 d0 0e 8c e8 2b  |....+..)w{d....+|
-00000260  e3 25 1c ed 0a 1b 05 e0  66 42 37 c0 e6 fa 3e 81  |.%......fB7...>.|
-00000270  ec e1 06 99 f4 62 3f ea  55 79 ae 68 56 9e e3 3c  |.....b?.Uy.hV..<|
-00000280  83 ba 9b 1c 65 b9 eb a6  e7 f7 4e 02 41 61 2c 52  |....e.....N.Aa,R|
-00000290  4c 48 92 b0 93 d8 31 58  c3 90 b0 e3 7d 55 94 fc  |LH....1X....}U..|
-000002a0  70 bf 18 42 51 73 d0 45  17 2e 0e 00 b0 12 76 0d  |p..BQs.E......v.|
-000002b0  35 78 cb fd 34 60 36 ff  ed 19 ef 0a 1e 21 cc 4c  |5x..4`6......!.L|
-000002c0  9a ff a0 f7 cf 72 03 cd  00 bb 73 0d 1d e5 14 03  |.....r....s.....|
-000002d0  01 00 01 01 16 03 01 00  30 69 76 1f 5b 81 5f 62  |........0iv.[._b|
-000002e0  cf d5 d9 2c 19 71 80 d0  2a 97 8a 89 21 7f 6d 02  |...,.q..*...!.m.|
-000002f0  b6 01 a4 ed fe 18 9f 34  ae 95 f6 a1 29 0b 9a 1c  |.......4....)...|
-00000300  04 b6 ce c7 d1 0c 5a b5  3f                       |......Z.?|
+00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 01 00 91 0f 00  |...._X.;t.......|
+00000240  00 8d 00 8b 30 81 88 02  42 01 f0 c3 b2 6e e2 a3  |....0...B....n..|
+00000250  cd 76 02 7a d5 b5 66 fa  b6 66 4e 4b a0 17 d6 bd  |.v.z..f..fNK....|
+00000260  ec f6 8c 1f f9 b4 32 18  a9 ba 66 a8 67 a4 fa c8  |......2...f.g...|
+00000270  f7 73 5f 22 fb f2 22 e2  4d a1 f6 30 a2 55 76 51  |.s_"..".M..0.UvQ|
+00000280  b7 61 7d 13 68 0a 89 9d  34 31 46 02 42 01 fa 8b  |.a}.h...41F.B...|
+00000290  61 f6 91 8e 88 ca 84 e6  33 e0 da 92 7e ee 21 1c  |a.......3...~.!.|
+000002a0  df 47 c2 5d 07 d8 ae 1b  04 58 f9 50 16 13 74 ea  |.G.].....X.P..t.|
+000002b0  04 cc 18 2d 2b 9a 08 89  24 e8 b8 01 bb c6 84 6c  |...-+...$......l|
+000002c0  e6 9a c6 8a 44 74 1c 3a  79 0c e9 3c 11 ba 1b 14  |....Dt.:y..<....|
+000002d0  03 01 00 01 01 16 03 01  00 30 1d 4b df 00 de 1c  |.........0.K....|
+000002e0  b5 30 7b ea 64 a0 09 89  8c c5 be fc 9b 07 7e 45  |.0{.d.........~E|
+000002f0  27 00 e7 78 da 3e a3 04  97 87 b0 c2 17 32 01 91  |'..x.>.......2..|
+00000300  6e 66 7b dd 9e 28 bc cc  66 65                    |nf{..(..fe|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 7d 4b fc 73 20  |..........0}K.s |
-00000010  e4 ac c4 39 15 79 e3 89  e1 24 ce 28 30 e5 f1 87  |...9.y...$.(0...|
-00000020  cd c0 cc 39 a8 77 3b 06  a5 f9 b0 a1 3d 54 53 3b  |...9.w;.....=TS;|
-00000030  53 ec ac b2 ea 24 1b 2d  6a ef c3                 |S....$.-j..|
+00000000  14 03 01 00 01 01 16 03  01 00 30 51 68 ca 97 63  |..........0Qh..c|
+00000010  c6 c0 24 1c 87 20 70 ac  f7 47 16 45 44 17 cc 92  |..$.. p..G.ED...|
+00000020  b3 6d 8b fa d1 3c b8 10  d7 da e4 a7 35 3c a2 d0  |.m...<......5<..|
+00000030  da 4b 50 e4 89 94 4b bc  20 6b e3                 |.KP...K. k.|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 9d 57 d2  4b 5b 7e 7d 7c 28 f7 8e  |.... .W.K[~}|(..|
-00000010  00 0a b6 1c 3c 6b df 4d  06 c0 f8 db 86 2e 8f 8e  |....<k.M........|
-00000020  28 a9 ab 6c c2 17 03 01  00 20 b4 4e cc 55 14 1c  |(..l..... .N.U..|
-00000030  64 a4 3d 69 1a dc 3b 12  8e d8 15 f2 31 3a 71 1f  |d.=i..;.....1:q.|
-00000040  eb fe c3 b3 22 f7 2c 6e  01 e9 15 03 01 00 20 2a  |....".,n...... *|
-00000050  2e 34 ca 96 e5 a3 a0 53  c4 0c e2 0a b1 14 a3 c8  |.4.....S........|
-00000060  a5 db 72 09 31 25 11 11  2f ce 61 3a 55 48 0c     |..r.1%../.a:UH.|
+00000000  17 03 01 00 20 fc fa 90  90 d0 51 0d 35 0f 6a 6d  |.... .....Q.5.jm|
+00000010  c2 32 ec 92 46 9f d7 e9  66 37 02 2a f6 c6 2e e2  |.2..F...f7.*....|
+00000020  13 aa fa fa d3 17 03 01  00 20 45 a9 36 19 7d a8  |......... E.6.}.|
+00000030  44 4c 8b aa 4e 47 c8 79  0c 97 a5 20 fa 6f 1f f7  |DL..NG.y... .o..|
+00000040  d3 bc d7 6d c2 67 23 c8  d6 05 15 03 01 00 20 f1  |...m.g#....... .|
+00000050  f1 ed f9 fc c2 f6 61 c8  42 9d c9 8a b0 d0 de d3  |......a.B.......|
+00000060  42 c7 04 64 eb 9e eb 58  3b c3 7d 0d 4d 16 d4     |B..d...X;.}.M..|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
index 754b76e..81e5191 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 97 0c 7e fc 7f  |....Y...U....~..|
-00000010  96 47 02 21 a7 19 45 a5  79 5c 5e fc c2 15 b3 fa  |.G.!..E.y\^.....|
-00000020  84 98 7d 67 65 c8 48 58  a1 5d 67 20 ad 2a c6 b3  |..}ge.HX.]g .*..|
-00000030  a4 17 82 12 4a c5 97 af  12 6b 7d f6 9e 49 f1 38  |....J....k}..I.8|
-00000040  d0 56 76 bc 81 23 ad 3a  3e 7f bc 2d c0 13 00 00  |.Vv..#.:>..-....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 ca 72 6a a1 69  |....Y...U...rj.i|
+00000010  18 a4 f8 76 4a c3 5c e8  d5 c1 fb 06 c6 9a 14 67  |...vJ.\........g|
+00000020  ce e4 f6 52 67 ab 64 48  28 5a 63 20 55 ea ff 87  |...Rg.dH(Zc U...|
+00000030  5a 78 5c cb 21 af 83 a5  ed 1b d3 2c 39 81 e5 ca  |Zx\.!......,9...|
+00000040  63 d2 5c 57 27 1d d0 f9  41 40 43 b0 c0 13 00 00  |c.\W'...A@C.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,17 +60,17 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |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 a4 24 f7 67 e3 da fa  |........ .$.g...|
-000002d0  10 33 95 b4 46 00 c0 3c  cd 74 12 e4 a3 3b 01 70  |.3..F..<.t...;.p|
-000002e0  fb 98 01 9a e9 2d d0 18  7b 00 80 ce c5 7b 4b 87  |.....-..{....{K.|
-000002f0  cd bc 5d 63 09 7e d4 ce  09 53 7a 1b e5 b4 10 54  |..]c.~...Sz....T|
-00000300  89 52 ac 82 9c 78 88 ed  e8 1a 8c 3a 7a 2c 9a c5  |.R...x.....:z,..|
-00000310  2b 97 1c 79 43 bd b1 ee  93 6f 4c 4d fc 3c 47 91  |+..yC....oLM.<G.|
-00000320  a6 ac ad be a9 39 12 98  40 f7 6a a3 e7 21 76 90  |.....9..@.j..!v.|
-00000330  c9 80 2b bc 80 3f 7e 60  59 7d cd 38 84 a8 53 2a  |..+..?~`Y}.8..S*|
-00000340  92 24 08 8f 84 da cd 9a  86 80 10 05 8f 1b fd 86  |.$..............|
-00000350  93 b6 ef 13 70 e5 6a d5  0e a5 bf 80 bf 50 a8 d4  |....p.j......P..|
-00000360  87 99 b8 d6 f0 4f 45 d5  e6 8b e1 16 03 01 00 0a  |.....OE.........|
+000002c0  aa 0c 00 00 a6 03 00 1d  20 e8 a5 9c e4 73 3d 75  |........ ....s=u|
+000002d0  0c 3e f2 de 21 9c 0f 91  b4 fd 94 f0 27 f6 d9 7d  |.>..!.......'..}|
+000002e0  cd 0c 4c 50 b0 47 db dd  12 00 80 04 c0 be d5 bb  |..LP.G..........|
+000002f0  e8 e2 a2 2e d9 2e 75 fa  b6 07 d0 f7 75 52 fb 2f  |......u.....uR./|
+00000300  50 cd 43 68 bd 42 11 6d  d6 9f a3 d1 00 fd a9 14  |P.Ch.B.m........|
+00000310  0c 2a dd 76 ea 73 21 52  00 3a 83 cf d7 07 c7 bd  |.*.v.s!R.:......|
+00000320  78 21 ce 35 80 b3 06 22  f1 96 a7 20 41 f8 aa 61  |x!.5..."... A..a|
+00000330  94 b4 77 d4 d9 92 f2 66  c5 1c d1 82 f3 b9 e2 9d  |..w....f........|
+00000340  a9 30 1c e2 4e ec 0d 32  3d 0d 61 22 c8 e5 95 9f  |.0..N..2=.a"....|
+00000350  cf 3e fc a8 c5 c3 f8 45  45 29 ea a7 e7 b7 a6 17  |.>.....EE)......|
+00000360  9e 5f 83 d4 b3 f0 da 31  73 94 f2 16 03 01 00 0a  |._.....1s.......|
 00000370  0d 00 00 06 03 01 02 40  00 00 16 03 01 00 04 0e  |.......@........|
 00000380  00 00 00                                          |...|
 >>> Flow 3 (client to server)
@@ -110,29 +110,29 @@
 00000210  03 01 00 25 10 00 00 21  20 2f e5 7d a3 47 cd 62  |...%...! /.}.G.b|
 00000220  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
 00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 01 00 91 0f 00  |...._X.;t.......|
-00000240  00 8d 00 8b 30 81 88 02  42 01 71 f3 c4 3a 85 08  |....0...B.q..:..|
-00000250  3b 18 26 48 5c 3f c3 8a  4f e9 d7 29 48 59 1a 35  |;.&H\?..O..)HY.5|
-00000260  ee b3 0d 5e 29 03 1d 34  95 0e 40 73 85 13 14 d0  |...^)..4..@s....|
-00000270  fb fb 96 77 21 fb d8 43  d7 e2 bf 2c 95 7b 75 5d  |...w!..C...,.{u]|
-00000280  59 15 81 71 d2 b6 82 96  d9 cc 78 02 42 01 d3 51  |Y..q......x.B..Q|
-00000290  af 25 d0 f8 a4 e2 e7 8e  7e 46 56 53 8f d1 09 f6  |.%......~FVS....|
-000002a0  76 88 5a 42 83 89 92 7b  c7 e4 40 9c 3d 05 ac 43  |v.ZB...{..@.=..C|
-000002b0  bf 6e 24 14 fe 36 f8 43  a6 90 8e a1 bd e2 92 84  |.n$..6.C........|
-000002c0  60 e3 92 34 1c 7b 53 d5  57 6d 23 32 12 a8 23 14  |`..4.{S.Wm#2..#.|
-000002d0  03 01 00 01 01 16 03 01  00 30 6f 06 c7 84 fa 7f  |.........0o.....|
-000002e0  c9 66 a9 6f 26 37 45 db  42 c8 8f 63 c3 5b 05 07  |.f.o&7E.B..c.[..|
-000002f0  ef 07 41 be 71 60 35 d3  16 8f 92 f6 89 cb c7 dc  |..A.q`5.........|
-00000300  4e 45 61 99 31 45 66 40  36 86                    |NEa.1Ef@6.|
+00000240  00 8d 00 8b 30 81 88 02  42 00 9a b9 f6 98 e3 ed  |....0...B.......|
+00000250  ed 0d a3 0e 54 51 9f 73  d4 87 40 4e a9 39 4b 2d  |....TQ.s..@N.9K-|
+00000260  2a b9 4d 8d e3 46 c3 b6  39 f2 ca a9 c9 0f 79 c1  |*.M..F..9.....y.|
+00000270  0c 90 6f de 58 97 72 fc  a8 c1 4c 12 aa a4 85 57  |..o.X.r...L....W|
+00000280  50 7c a0 02 8a 12 c5 80  aa b6 39 02 42 00 9c b7  |P|........9.B...|
+00000290  95 b4 04 83 5b 3a e1 ac  da 78 86 11 f5 30 75 4a  |....[:...x...0uJ|
+000002a0  25 67 6c fd ef 5a d8 56  d3 60 93 cf 65 07 2b 1f  |%gl..Z.V.`..e.+.|
+000002b0  a9 40 a8 ba cd 0e 41 2d  10 43 a4 61 93 b7 0a 11  |.@....A-.C.a....|
+000002c0  78 d1 72 2b 20 07 49 5a  76 02 17 57 87 78 c7 14  |x.r+ .IZv..W.x..|
+000002d0  03 01 00 01 01 16 03 01  00 30 93 de 1b 64 0e 56  |.........0...d.V|
+000002e0  d9 a8 da f7 37 cb ac ac  3e f5 e2 f9 87 19 f2 79  |....7...>......y|
+000002f0  24 76 19 a4 a2 41 d6 9e  7d ca aa 3e 1d d7 22 dd  |$v...A..}..>..".|
+00000300  05 aa dd 74 03 db fd a2  de ee                    |...t......|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 d3 83 ac 08 7f  |..........0.....|
-00000010  a1 91 51 7c b7 99 6f 24  cd b1 cd 31 7b 12 20 47  |..Q|..o$...1{. G|
-00000020  66 08 22 f6 28 ea 81 fe  92 b5 c8 40 60 bc 5b 19  |f.".(......@`.[.|
-00000030  e0 2b d1 26 fd 4c 12 22  c5 13 9a                 |.+.&.L."...|
+00000000  14 03 01 00 01 01 16 03  01 00 30 4d 4f d6 67 05  |..........0MO.g.|
+00000010  32 8c 16 cb 19 35 b3 b9  02 d8 5e 24 b6 c8 b7 3a  |2....5....^$...:|
+00000020  17 34 98 77 e1 73 e0 cd  a9 30 a8 15 60 8c f4 9a  |.4.w.s...0..`...|
+00000030  dc cf 7a fd 86 85 1c 2b  33 21 e8                 |..z....+3!.|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 79 06 89  7e e0 17 9a e3 dc 4c ee  |.... y..~.....L.|
-00000010  70 63 13 bc 27 f5 43 fa  f8 90 49 d9 89 43 7a 15  |pc..'.C...I..Cz.|
-00000020  d4 e2 a8 e6 3e 17 03 01  00 20 ea 84 0e 21 62 d5  |....>.... ...!b.|
-00000030  ee 26 5e fc 3e 0c 83 3b  91 01 c4 a7 8e 9b c4 1a  |.&^.>..;........|
-00000040  86 f8 a0 44 21 44 2f 31  cf a1 15 03 01 00 20 c6  |...D!D/1...... .|
-00000050  11 f1 65 ea f3 39 d1 d2  ac 95 1f 81 36 ae db b1  |..e..9......6...|
-00000060  88 a8 42 25 86 ec 1b c1  7e 12 60 a9 6b 7f 66     |..B%....~.`.k.f|
+00000000  17 03 01 00 20 b8 c5 17  b7 92 d8 93 7a b2 fd 4f  |.... .......z..O|
+00000010  15 d1 db b9 47 54 00 a0  f6 77 92 03 a8 89 e5 ba  |....GT...w......|
+00000020  cc eb d9 bd 27 17 03 01  00 20 57 d5 9a f6 36 b2  |....'.... W...6.|
+00000030  57 ba cd 64 77 36 b9 74  fb bd 95 51 03 61 e8 45  |W..dw6.t...Q.a.E|
+00000040  cb b8 35 f0 05 17 b3 08  c6 cb 15 03 01 00 20 28  |..5........... (|
+00000050  43 03 ab 3f e2 f5 d0 33  4c 7f 50 a4 ee 7b 46 e6  |C..?...3L.P..{F.|
+00000060  12 76 d0 fd c3 99 5c 63  a4 04 ea 4b e3 bd 99     |.v....\c...K...|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
index 641ab1b..3ee661e 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 3b 4c b9 76 d2  |....Y...U..;L.v.|
-00000010  c3 d1 ea 81 71 1a 10 e1  b1 69 5c 54 c2 df 17 0a  |....q....i\T....|
-00000020  de 41 cb d1 69 c3 9a da  90 fd 25 20 1e 02 11 16  |.A..i.....% ....|
-00000030  ab 66 13 56 3d 94 00 a9  80 7c d8 57 12 99 1c 5f  |.f.V=....|.W..._|
-00000040  7a b2 02 8c 23 f3 76 b8  59 5e 16 dd c0 09 00 00  |z...#.v.Y^......|
+00000000  16 03 01 00 59 02 00 00  55 03 01 b4 ff c0 49 36  |....Y...U.....I6|
+00000010  1d 31 9a a7 f6 33 f5 16  78 d7 10 9e 19 eb 1d 67  |.1...3..x......g|
+00000020  20 39 f8 73 7e 27 e2 dc  d1 ab 03 20 79 64 67 f7  | 9.s~'..... ydg.|
+00000030  8b c8 97 f0 b4 87 0e 2d  4b 22 6c ed 92 48 85 52  |.......-K"l..H.R|
+00000040  eb 57 56 a8 cf 19 9f 4d  e3 38 5e a0 c0 09 00 00  |.WV....M.8^.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -55,20 +55,20 @@
 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 16 64  |*............ .d|
-00000280  ca 24 70 6f 61 2f 9e 2d  43 0a 73 ac 67 f0 7a e5  |.$poa/.-C.s.g.z.|
-00000290  c7 4e c4 1f ad 13 0d eb  df ff 0d ff a3 27 00 8b  |.N...........'..|
-000002a0  30 81 88 02 42 01 1a 33  8b 88 78 ed 5c c1 56 0d  |0...B..3..x.\.V.|
-000002b0  75 51 69 a0 e7 45 6d ae  b0 67 55 3f be 23 3e 92  |uQi..Em..gU?.#>.|
-000002c0  fe 26 68 a2 30 84 2f b3  33 66 f6 dd 71 67 99 5e  |.&h.0./.3f..qg.^|
-000002d0  1c 6f bf 87 ed 33 a0 87  69 f6 35 65 8d cb 3a 7e  |.o...3..i.5e..:~|
-000002e0  95 a7 a4 40 54 cb 97 02  42 00 a3 fe 50 34 68 9f  |...@T...B...P4h.|
-000002f0  f2 43 98 23 e4 24 ad 36  e9 d3 e0 75 2c 11 46 6c  |.C.#.$.6...u,.Fl|
-00000300  48 33 c5 bc 2d 04 ff cc  bb ec 38 ec f4 b3 55 31  |H3..-.....8...U1|
-00000310  8a 6e 38 a5 6d a0 9c fc  f6 98 75 48 c6 79 53 de  |.n8.m.....uH.yS.|
-00000320  dd 91 49 f0 b6 32 83 45  61 89 4e 16 03 01 00 0a  |..I..2.Ea.N.....|
-00000330  0d 00 00 06 03 01 02 40  00 00 16 03 01 00 04 0e  |.......@........|
-00000340  00 00 00                                          |...|
+00000270  2a 16 03 01 00 b4 0c 00  00 b0 03 00 1d 20 ec 38  |*............ .8|
+00000280  f7 41 d0 f3 f4 6a ca 47  18 74 f1 22 2c 47 ee 39  |.A...j.G.t.",G.9|
+00000290  c9 a2 db 64 05 01 ae 5d  08 65 53 7f 24 78 00 8a  |...d...].eS.$x..|
+000002a0  30 81 87 02 41 64 39 65  56 fa d4 69 e7 c5 a5 32  |0...Ad9eV..i...2|
+000002b0  4c 52 55 96 fe 01 cd 41  3c 18 ed df fd 09 c3 89  |LRU....A<.......|
+000002c0  80 bd 88 9e d7 a1 85 16  d1 a4 5a f0 9a 76 e9 2f  |..........Z..v./|
+000002d0  d2 a4 42 a4 89 98 6c 87  64 b1 49 4e 6a 68 d2 43  |..B...l.d.INjh.C|
+000002e0  41 a2 c7 a6 2f f7 02 42  01 6c bb 32 c0 47 7e 08  |A.../..B.l.2.G~.|
+000002f0  6b 7a 44 18 b7 5d 4c 4d  6d 80 92 bb e5 65 98 1b  |kzD..]LMm....e..|
+00000300  d7 a6 a3 1b b5 f3 46 1a  e7 e0 89 04 40 b0 29 aa  |......F.....@.).|
+00000310  fe 85 6a 9a 4b 18 75 ab  00 52 71 54 41 8d eb 31  |..j.K.u..RqTA..1|
+00000320  47 69 9b 9d dc 3b 1b 3e  76 27 16 03 01 00 0a 0d  |Gi...;.>v'......|
+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)
 00000000  16 03 01 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.......\.|
@@ -105,29 +105,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 90  68 a8 2f 6f 2b 70 e4 25  |........h./o+p.%|
-00000240  7d fb b7 85 db 44 ec 1a  ad 6d 84 fb 95 21 fa 24  |}....D...m...!.$|
-00000250  7b 31 6a 97 4f 06 ee 87  22 c3 7c 81 70 ed e3 2a  |{1j.O...".|.p..*|
-00000260  d5 2c d1 4e 6d f0 12 52  2f 98 05 08 af 41 fa 87  |.,.Nm..R/....A..|
-00000270  d1 62 98 6c 06 47 ec 7a  44 e0 7d ae 7a 7d ef 1b  |.b.l.G.zD.}.z}..|
-00000280  d5 2c fa 1b 70 a3 fb 9a  5d 8c 60 b4 44 6a e5 b8  |.,..p...].`.Dj..|
-00000290  80 4c 29 fc f1 2d f1 11  46 81 c4 01 e4 11 2e 05  |.L)..-..F.......|
-000002a0  cb 2b ca d9 4a 14 39 06  93 77 19 db 80 03 82 38  |.+..J.9..w.....8|
-000002b0  e5 c1 0f 11 17 47 a7 14  03 01 00 01 01 16 03 01  |.....G..........|
-000002c0  00 30 a6 68 28 50 75 6d  eb f4 32 c8 a3 57 3f b1  |.0.h(Pum..2..W?.|
-000002d0  37 84 8e 7e 1d 1d 93 7d  9f ec ff ac 1c 8d bf 30  |7..~...}.......0|
-000002e0  d2 b0 0f 3f 02 c3 ef ac  a3 62 94 26 1c 8f 7e 8d  |...?.....b.&..~.|
-000002f0  74 99                                             |t.|
+00000230  86 0f 00 00 82 00 80 05  7e 70 eb cb ef e3 d9 6f  |........~p.....o|
+00000240  59 29 b5 da f2 07 f5 42  62 4e 74 9b cf 00 e1 5c  |Y).....BbNt....\|
+00000250  69 a5 67 3a b0 b2 ca f2  10 ed 1c b4 81 5d 7d 9e  |i.g:.........]}.|
+00000260  1a 45 69 42 13 c5 b0 86  dc 3d 60 e5 cf fd ae 0f  |.EiB.....=`.....|
+00000270  17 bb 4a ed d7 06 eb f1  6d 47 98 b7 e8 87 eb 3c  |..J.....mG.....<|
+00000280  12 55 2c 06 de 55 48 c7  59 85 cb 62 d6 e7 1d 05  |.U,..UH.Y..b....|
+00000290  1e 6d 69 84 cd 16 8e dd  ed 5b 5a 2f f2 97 b7 78  |.mi......[Z/...x|
+000002a0  93 c1 fb 75 26 c8 b5 58  43 17 c7 52 54 20 4f 7d  |...u&..XC..RT O}|
+000002b0  7c 46 89 65 fe 51 29 14  03 01 00 01 01 16 03 01  ||F.e.Q).........|
+000002c0  00 30 d9 59 e6 7e c0 a6  2a af 36 0c 2e cf 0f 42  |.0.Y.~..*.6....B|
+000002d0  54 d4 41 c6 3c f8 84 d9  2a a6 82 94 22 2d ac ae  |T.A.<...*..."-..|
+000002e0  d9 f7 68 22 f6 f0 2e 56  c1 97 80 73 0d b3 f0 70  |..h"...V...s...p|
+000002f0  49 78                                             |Ix|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 80 3e 0d 50 13  |..........0.>.P.|
-00000010  5f 00 ba 2e 47 46 5d 63  1b 72 a8 02 24 1c 3e 1f  |_...GF]c.r..$.>.|
-00000020  ed e2 3a 45 d7 7d 3a f2  33 97 c3 ab 13 9b 0e 4a  |..:E.}:.3......J|
-00000030  04 f0 08 48 ab d3 46 0b  40 7d 5c                 |...H..F.@}\|
+00000000  14 03 01 00 01 01 16 03  01 00 30 06 19 79 49 41  |..........0..yIA|
+00000010  f9 9c 75 84 73 95 96 bd  1e 25 56 a9 49 ed 8e 38  |..u.s....%V.I..8|
+00000020  34 40 60 dc f0 2d f3 6c  cf 5b 80 84 2b 81 db 5f  |4@`..-.l.[..+.._|
+00000030  f4 27 03 ad b8 8d 80 0c  99 69 6f                 |.'.......io|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 f7 32 e7  36 4f 77 2f 4a 05 fd 27  |.... .2.6Ow/J..'|
-00000010  19 57 52 f7 8a 0c 7f fb  14 78 b2 06 bf ca 86 73  |.WR......x.....s|
-00000020  32 13 33 04 91 17 03 01  00 20 7e e4 fe c5 6d f7  |2.3...... ~...m.|
-00000030  d4 69 30 57 89 a0 76 70  40 a7 b5 17 74 2f 5d 16  |.i0W..vp@...t/].|
-00000040  c1 19 30 73 f8 37 c4 10  5b b7 15 03 01 00 20 08  |..0s.7..[..... .|
-00000050  41 5e 0b 9f 36 23 bd 9a  09 f7 58 9d a3 d7 26 3a  |A^..6#....X...&:|
-00000060  f4 5e 6b bf 9c d4 6f 0c  d3 9e cd de cb 95 57     |.^k...o.......W|
+00000000  17 03 01 00 20 20 67 bd  ff 84 9b 0e 58 f3 45 1e  |....  g.....X.E.|
+00000010  7a 25 d5 ae f0 26 4b 42  c7 f3 a5 77 7b 2f 42 21  |z%...&KB...w{/B!|
+00000020  2e c6 c9 81 23 17 03 01  00 20 69 1c 2a b9 05 16  |....#.... i.*...|
+00000030  8b 71 3a c2 18 76 bd 25  1f de 83 e9 14 e2 a3 5c  |.q:..v.%.......\|
+00000040  9b 33 ee 14 39 da e2 e7  a3 a7 15 03 01 00 20 e9  |.3..9......... .|
+00000050  dc 16 0c 13 56 7a e5 fd  ce b9 4f d1 c7 20 3f ca  |....Vz....O.. ?.|
+00000060  72 20 15 f7 11 81 fe 88  ab 90 4c dc 0b a5 11     |r ........L....|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
index c46a967..980f933 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 97 fe 7f 92 37  |....Y...U......7|
-00000010  67 99 e0 d8 62 a9 31 80  bd 1f 31 8e 7d 0b 08 0a  |g...b.1...1.}...|
-00000020  de a5 82 a2 f2 d0 c1 35  66 34 6e 20 39 46 b1 b0  |.......5f4n 9F..|
-00000030  6e 2d 0e fe 8c 48 ea ab  1c c4 49 ee f4 21 cf cb  |n-...H....I..!..|
-00000040  2a 20 57 78 18 99 a1 b9  7f 88 4f 64 c0 13 00 00  |* Wx......Od....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 4d 6d 71 59 6b  |....Y...U..MmqYk|
+00000010  cd 8c 6e b0 11 bf 4a 9e  25 90 12 cc ac b4 3f be  |..n...J.%.....?.|
+00000020  86 1b 13 47 a6 be 3d a0  8f 0b 77 20 6b b5 57 6d  |...G..=...w k.Wm|
+00000030  39 74 b0 9d b4 ae 2e 72  7e 90 d2 ab ed 32 fa 65  |9t.....r~....2.e|
+00000040  ed 85 63 d2 16 ef 47 af  a6 37 17 88 c0 13 00 00  |..c...G..7......|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,17 +60,17 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |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 07 80 79 40 4b b1 0e  |........ ..y@K..|
-000002d0  05 ce e4 ca 9d f5 d7 ad  a6 98 f2 40 f9 b9 66 a8  |...........@..f.|
-000002e0  04 6e ae b5 da 99 67 09  69 00 80 01 4a f2 c1 c9  |.n....g.i...J...|
-000002f0  2f 46 4f b8 9e 8b 2c c4  a1 32 44 3c dc 2c 5e b9  |/FO...,..2D<.,^.|
-00000300  76 5f 41 20 23 1b 82 dd  ec 37 b4 24 68 6d a7 39  |v_A #....7.$hm.9|
-00000310  4f f2 e5 97 09 75 64 2a  64 16 b8 99 04 8a 74 77  |O....ud*d.....tw|
-00000320  19 bb 12 5f 27 f6 41 09  f7 2e 1c 33 80 3b 01 57  |..._'.A....3.;.W|
-00000330  5c f9 20 6e 0c 48 76 59  e1 8b 1f bb 2a 33 1a 28  |\. n.HvY....*3.(|
-00000340  a0 5a 05 44 94 eb 35 62  5e ae 7f e4 01 76 b6 b4  |.Z.D..5b^....v..|
-00000350  64 91 bf 25 09 ff 88 8a  af 73 00 d0 7e ea 0f ca  |d..%.....s..~...|
-00000360  4a 2b d4 6f 02 26 98 28  5a ed 11 16 03 01 00 0a  |J+.o.&.(Z.......|
+000002c0  aa 0c 00 00 a6 03 00 1d  20 96 0b 2f 57 e1 1e 07  |........ ../W...|
+000002d0  e0 7f a4 91 67 97 d0 a0  19 d3 9a b2 49 79 f9 5f  |....g.......Iy._|
+000002e0  7f b5 65 d4 3a 89 92 8f  11 00 80 08 29 72 0b f7  |..e.:.......)r..|
+000002f0  7b 68 38 5e 47 15 89 f1  ee be f3 a9 26 a4 9c 6d  |{h8^G.......&..m|
+00000300  2c 2a ff f0 d6 2d 25 a5  b0 93 66 7d 8c fb fe a5  |,*...-%...f}....|
+00000310  3b cc b6 71 f4 1b 55 c4  ef 08 73 b1 49 47 2c e6  |;..q..U...s.IG,.|
+00000320  a1 ef 53 ca bb 15 e3 25  ea e7 48 44 18 88 e1 d2  |..S....%..HD....|
+00000330  3b e9 f6 92 61 5e 5c 06  44 83 37 6c e6 b6 26 32  |;...a^\.D.7l..&2|
+00000340  fd d6 00 fc 87 a2 37 e3  84 d2 ad 2d 99 0d e1 ba  |......7....-....|
+00000350  bb 2f 3b 0b dd 56 5c c2  14 af 86 58 2c 8b f8 64  |./;..V\....X,..d|
+00000360  75 ab d3 35 41 59 fa fe  a5 48 26 16 03 01 00 0a  |u..5AY...H&.....|
 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)
@@ -109,29 +109,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 81  aa 68 1f a9 a4 de f1 4d  |.........h.....M|
-00000240  30 9a fe e6 a5 f6 f6 18  b6 3e d2 c7 f1 e6 77 e3  |0........>....w.|
-00000250  6a cd 61 01 81 3a 02 31  a5 aa d6 db b6 02 9d 4b  |j.a..:.1.......K|
-00000260  f5 78 50 c3 95 fe 43 88  33 3a 95 32 bc e8 02 1a  |.xP...C.3:.2....|
-00000270  e6 f4 d5 54 b9 fc e0 4a  4e f0 92 21 35 4b de c8  |...T...JN..!5K..|
-00000280  a4 b0 01 c3 ca 3a 87 ed  cb 21 1c ce c2 14 7b 8d  |.....:...!....{.|
-00000290  90 68 b9 21 49 13 dd cd  e7 68 83 41 7c 84 6a 75  |.h.!I....h.A|.ju|
-000002a0  76 ee 19 8b fa d5 a6 57  3d a7 f1 f1 6f 11 ca 77  |v......W=...o..w|
-000002b0  95 0e b5 c7 3d 99 d4 14  03 01 00 01 01 16 03 01  |....=...........|
-000002c0  00 30 5e be 40 82 f8 db  05 20 23 45 a4 42 48 e8  |.0^.@.... #E.BH.|
-000002d0  06 69 eb 4c ef 79 53 52  4a 5a 3a ba cc d6 99 59  |.i.L.ySRJZ:....Y|
-000002e0  4d c2 b0 34 0f 14 68 03  93 8b a4 95 7e cf 26 f8  |M..4..h.....~.&.|
-000002f0  5c 8a                                             |\.|
+00000230  86 0f 00 00 82 00 80 8f  5d a5 27 13 09 5e 49 5f  |........].'..^I_|
+00000240  ff fd d6 88 75 83 cc 74  f3 e1 af 44 76 6a 35 16  |....u..t...Dvj5.|
+00000250  e8 36 5f b7 dc 21 69 77  61 12 c5 69 f7 0d 98 1f  |.6_..!iwa..i....|
+00000260  d5 15 f1 e8 88 c5 30 e8  b5 c3 2a e5 26 93 cc a4  |......0...*.&...|
+00000270  eb 31 c6 d7 f5 f4 7c d5  f7 a2 3f 1f 75 cd b2 b2  |.1....|...?.u...|
+00000280  82 3a 03 8c 5e 15 0a d2  98 b8 65 cb 5f d5 db d0  |.:..^.....e._...|
+00000290  b6 36 8c 89 7e 48 fa 3a  9f 9a bd c1 48 e7 d6 20  |.6..~H.:....H.. |
+000002a0  ef 45 5b 24 32 04 58 82  b3 7b 42 fd fe ba 78 32  |.E[$2.X..{B...x2|
+000002b0  2a f5 b7 81 33 da db 14  03 01 00 01 01 16 03 01  |*...3...........|
+000002c0  00 30 5f 96 98 94 17 6d  ff 84 72 d3 63 fd 14 59  |.0_....m..r.c..Y|
+000002d0  eb bf 5f 3e 8f dc f1 c1  dc 77 8a 33 f6 2e a2 4a  |.._>.....w.3...J|
+000002e0  15 d1 2e a4 ec 0d 3c 0b  18 07 09 6c 0d 09 34 2e  |......<....l..4.|
+000002f0  a4 6f                                             |.o|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 ef 9b 5c da 0a  |..........0..\..|
-00000010  2e c4 79 fa ea 8a 9c 78  4a 1f 08 77 56 73 6e fa  |..y....xJ..wVsn.|
-00000020  3a 5b 3c cd cd e9 0c a8  bb 59 9e 22 ab 67 2c 03  |:[<......Y.".g,.|
-00000030  de ad 7c e4 cb 85 d7 8f  c1 1c e3                 |..|........|
+00000000  14 03 01 00 01 01 16 03  01 00 30 b7 4a 5c 0c e6  |..........0.J\..|
+00000010  7c d9 43 7c e7 b4 2f d7  b5 c6 5e 36 c7 87 dd 82  ||.C|../...^6....|
+00000020  da d3 b2 4e 05 ae f5 8c  b0 4d db c2 53 62 55 73  |...N.....M..SbUs|
+00000030  8c 2a 1b d5 df e4 7c a4  cf db 8b                 |.*....|....|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 48 1a 1a  1c 6c 7d 6c 2a e0 b2 e3  |.... H...l}l*...|
-00000010  b3 9f ec 39 a8 cd 9a f9  a2 3e 2d 46 3b cf 17 ed  |...9.....>-F;...|
-00000020  70 99 ce d7 3c 17 03 01  00 20 69 27 e9 89 78 e6  |p...<.... i'..x.|
-00000030  64 c0 a9 40 4f 0d 97 53  b2 2e 15 f3 2b 54 3b 77  |d..@O..S....+T;w|
-00000040  f2 24 2c 94 dc b3 8b f0  c4 ce 15 03 01 00 20 1b  |.$,........... .|
-00000050  50 55 83 d8 6b b4 04 b2  f0 2d 1c 9c 0d fa de 58  |PU..k....-.....X|
-00000060  cd 0a 1d 55 d6 36 f4 a4  fb cc 55 c5 b1 f3 d3     |...U.6....U....|
+00000000  17 03 01 00 20 b9 26 60  87 38 9c d9 c4 65 17 8e  |.... .&`.8...e..|
+00000010  3c 7f 1a b4 23 cd 27 fd  4e 92 ee 0e f2 11 dc e2  |<...#.'.N.......|
+00000020  23 e4 26 f3 55 17 03 01  00 20 5e 89 33 21 f0 dc  |#.&.U.... ^.3!..|
+00000030  e8 4f 33 1c 66 56 99 38  a5 4c 0e 0e 93 41 b7 48  |.O3.fV.8.L...A.H|
+00000040  5d ce 49 d0 d2 8a 56 a6  2d 68 15 03 01 00 20 05  |].I...V.-h.... .|
+00000050  e0 ed f9 c2 56 ec 64 e5  e7 0b f4 8a e2 41 96 9e  |....V.d......A..|
+00000060  ed 94 c8 95 69 d7 ce 2d  0e bb 5b 18 5f 30 52     |....i..-..[._0R|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
index 7d6683c..6fc506f 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
+++ b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 a7 ea 63 8c 7d  |....Y...U....c.}|
-00000010  54 70 04 d5 5e a2 2e 8b  75 4f 17 c8 a8 8c 3d bc  |Tp..^...uO....=.|
-00000020  08 aa 82 48 85 ed 1a ff  42 e1 54 20 3b 77 9d 32  |...H....B.T ;w.2|
-00000030  4d 60 f2 81 f8 20 aa d2  b0 eb ea 7c 6a 39 52 20  |M`... .....|j9R |
-00000040  94 4a 2a 88 05 8a fe 6c  50 5c 95 39 c0 09 00 00  |.J*....lP\.9....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 a3 4e 79 27 af  |....Y...U...Ny'.|
+00000010  c8 a3 15 a4 c2 7a 54 58  54 0e 0d 93 c2 ff e1 f9  |.....zTXT.......|
+00000020  55 ab 2c ea 32 cf d2 47  2e d7 8e 20 49 08 d1 66  |U.,.2..G... I..f|
+00000030  9b 9e aa af c9 90 95 ec  cb 64 2e 3d f6 27 d5 f6  |.........d.=.'..|
+00000040  23 10 d5 6e 50 5f bc 89  fe c7 d7 de c0 09 00 00  |#..nP_..........|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -55,37 +55,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 3a 1f  |*............ :.|
-00000280  18 e9 f2 09 3e 79 4b a0  62 73 ef 87 0d ea 90 51  |....>yK.bs.....Q|
-00000290  7f 9d d2 79 59 e4 11 7f  69 f7 a9 d7 78 7f 00 8b  |...yY...i...x...|
-000002a0  30 81 88 02 42 01 65 ac  eb e6 b0 86 73 95 a4 27  |0...B.e.....s..'|
-000002b0  e3 82 55 cf 88 16 80 c2  68 4b 39 77 2a b1 a9 d3  |..U.....hK9w*...|
-000002c0  08 d5 ac 77 ce 5b 16 73  2c ad b5 57 2a 7a 75 34  |...w.[.s,..W*zu4|
-000002d0  ec 99 23 bd df b2 27 36  5a 4b 40 e0 d3 b0 d2 31  |..#...'6ZK@....1|
-000002e0  9b c7 9e 0a cb 5b 69 02  42 00 88 d7 5a 6a 9e 4c  |.....[i.B...Zj.L|
-000002f0  c5 7b 2c 8e 93 3b 75 27  b4 00 11 88 ba cf 99 8c  |.{,..;u'........|
-00000300  e5 f2 60 22 de f2 fe 86  a6 48 86 9c 40 31 08 75  |..`".....H..@1.u|
-00000310  aa bc 5d 6d fa 2e a4 a9  a1 0d fc e1 d9 5a a1 60  |..]m.........Z.`|
-00000320  93 b9 69 c7 c2 3e f5 a9  cb 31 41 16 03 01 00 04  |..i..>...1A.....|
+00000270  2a 16 03 01 00 b5 0c 00  00 b1 03 00 1d 20 4a 7c  |*............ J||
+00000280  0a 86 8a 81 f2 60 4a 3c  ac d7 7d 3b fc 00 a5 b4  |.....`J<..};....|
+00000290  85 45 45 45 fb 09 53 d7  4a cf 24 9d c8 1a 00 8b  |.EEE..S.J.$.....|
+000002a0  30 81 88 02 42 01 7a c9  c0 76 8c 26 98 63 4e a3  |0...B.z..v.&.cN.|
+000002b0  ad 4f 4e a3 d7 c7 d6 4a  69 28 cf d2 7b 0b 36 fb  |.ON....Ji(..{.6.|
+000002c0  a3 ae 2f e1 83 ea ea 4a  b7 2d ef a8 2d 13 96 e4  |../....J.-..-...|
+000002d0  73 83 66 70 5e 5c d9 5a  d1 1c d1 33 18 0b b3 30  |s.fp^\.Z...3...0|
+000002e0  2a 21 d7 78 d8 70 18 02  42 00 c4 ab 80 33 8f f1  |*!.x.p..B....3..|
+000002f0  c2 74 1b 58 2f 59 d4 27  a1 19 42 bf 14 ea a8 a2  |.t.X/Y.'..B.....|
+00000300  cb bf 96 2d 60 7b 84 40  cc 31 f5 c4 e8 51 87 b8  |...-`{.@.1...Q..|
+00000310  7b 47 ec c4 c0 4a 9b 09  59 1e f8 b5 9a e1 45 a4  |{G...J..Y.....E.|
+00000320  a1 9b ee 78 55 f8 f5 fa  1a fb c5 16 03 01 00 04  |...xU...........|
 00000330  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 30 25 15  82 a1 7f 11 32 13 52 17  |....00%.....2.R.|
-00000040  b8 bd 5b b9 1e 69 88 0b  b3 5f 12 40 e3 4b 03 cb  |..[..i..._.@.K..|
-00000050  cd 07 3c 43 4f ab f7 5d  2c 6a a3 02 a9 64 d0 77  |..<CO..],j...d.w|
-00000060  27 dc 4a ae 8a                                    |'.J..|
+00000030  16 03 01 00 30 b0 5e 4a  8a 07 e3 86 43 05 16 68  |....0.^J....C..h|
+00000040  0e d1 58 a6 05 49 e9 a6  42 89 2c 3f 33 68 8b 26  |..X..I..B.,?3h.&|
+00000050  23 21 3b 62 ab 7a 21 74  d8 49 15 03 b3 1e c6 53  |#!;b.z!t.I.....S|
+00000060  74 1e 1c 4e 0f                                    |t..N.|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 b5 3e 18 97 a1  |..........0.>...|
-00000010  ca 2e 7f 5f b9 72 cb aa  d4 f6 85 86 d3 27 40 13  |..._.r.......'@.|
-00000020  e3 99 35 13 67 a8 9e 6e  bb 63 15 97 96 42 e4 b3  |..5.g..n.c...B..|
-00000030  fc 15 ee b7 d8 cb a2 64  3d 55 b8                 |.......d=U.|
+00000000  14 03 01 00 01 01 16 03  01 00 30 64 4b 3c 1a e3  |..........0dK<..|
+00000010  7d bb bb bb 64 d8 51 c3  eb 92 65 65 58 35 dd 7b  |}...d.Q...eeX5.{|
+00000020  d2 fd f0 0c c1 10 71 a5  a8 f7 14 84 69 b4 81 18  |......q.....i...|
+00000030  1e 0d d3 19 b6 23 72 1a  a7 43 0e                 |.....#r..C.|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 12 6c bf  f2 39 2d e6 ad a8 38 d5  |.... .l..9-...8.|
-00000010  1c ea 5b 79 e5 c7 4a 41  eb 58 70 f0 7d f7 60 e7  |..[y..JA.Xp.}.`.|
-00000020  ee 77 98 75 f2 17 03 01  00 20 ac 5e 6d b0 81 0b  |.w.u..... .^m...|
-00000030  14 ca c2 70 53 d8 6d 55  49 63 da 8a 61 66 80 2d  |...pS.mUIc..af.-|
-00000040  e4 7c 2e 60 1f eb 3c f2  27 66 15 03 01 00 20 7a  |.|.`..<.'f.... z|
-00000050  2b 80 f8 00 0f 06 f5 6e  fe b7 b7 6b 12 6c 8d 8e  |+......n...k.l..|
-00000060  c4 11 23 2b a2 bb 16 93  b4 e0 e0 fd 8c 42 db     |..#+.........B.|
+00000000  17 03 01 00 20 c3 e6 70  2c 44 4f 04 0c fb 0b 7f  |.... ..p,DO.....|
+00000010  1d 2c ef 4d cc c3 21 ba  a2 db 74 76 46 ea 00 40  |.,.M..!...tvF..@|
+00000020  54 2d 4a fe 59 17 03 01  00 20 0c 6b 39 0d b5 f3  |T-J.Y.... .k9...|
+00000030  ed 7e d0 de 01 18 0c 32  4e 59 93 46 d3 c5 4f c0  |.~.....2NY.F..O.|
+00000040  f5 fd f1 d2 79 07 7d 07  b0 24 15 03 01 00 20 1d  |....y.}..$.... .|
+00000050  f7 53 a2 e7 3f 88 87 35  01 6e a5 b1 d6 81 37 5b  |.S..?..5.n....7[|
+00000060  a7 64 4c 29 f4 71 59 a1  36 c1 1a 24 93 31 7d     |.dL).qY.6..$.1}|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
index c0e842d..24da556 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
+++ b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 16 f4 24 01 94  |....Y...U....$..|
-00000010  68 d2 0f 15 4d d6 65 54  84 73 ab 2c b2 11 c5 64  |h...M.eT.s.,...d|
-00000020  d8 93 66 50 cd b0 f0 ab  11 5c 72 20 b1 13 c1 f5  |..fP.....\r ....|
-00000030  63 ed 70 0b 21 52 85 36  84 99 1d b6 bb dc d3 1c  |c.p.!R.6........|
-00000040  b3 76 13 d9 ef 47 c4 c0  18 57 23 3b c0 13 00 00  |.v...G...W#;....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 63 68 ea 52 0b  |....Y...U..ch.R.|
+00000010  dc 68 c7 d0 75 3e 7d 6f  0b 8c cb 25 48 b0 bb df  |.h..u>}o...%H...|
+00000020  7a 56 93 a9 d5 4f 0c 3a  e2 37 ab 20 1f 0f a4 d3  |zV...O.:.7. ....|
+00000030  b4 f6 66 6f 39 6f 62 fb  6a 1f 41 09 4b 02 5c 15  |..fo9ob.j.A.K.\.|
+00000040  a0 ba cb a6 f9 bd 3b ec  cb 76 6e ea c0 13 00 00  |......;..vn.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,36 +60,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 7e aa 30 94 7b fb 09  |........ ~.0.{..|
-000002d0  b5 55 ce b3 e9 e0 5b 55  82 f4 e6 7c d0 e4 57 eb  |.U....[U...|..W.|
-000002e0  9b ec 82 48 d6 0e 2a bb  16 00 80 80 da c5 75 4f  |...H..*.......uO|
-000002f0  82 95 ee 47 28 af 09 08  d5 13 68 33 5d 91 dd 13  |...G(.....h3]...|
-00000300  43 84 e9 54 d9 e7 39 7c  38 74 d5 92 8f 46 37 86  |C..T..9|8t...F7.|
-00000310  44 68 ae c7 3a ad e1 33  5f cd d8 c6 a5 7c 5e 83  |Dh..:..3_....|^.|
-00000320  44 ba b1 09 44 ec 42 7f  41 80 d6 b6 4c 6d ae 24  |D...D.B.A...Lm.$|
-00000330  a9 3b 53 87 2f 3b 3a 1f  da 87 2b 7d cf 9e ed a5  |.;S./;:...+}....|
-00000340  04 54 ad c2 3c 7b 21 60  55 67 41 47 60 02 1e 62  |.T..<{!`UgAG`..b|
-00000350  bb 9f ee 2c 6e 79 20 6e  65 e2 d0 ae 73 70 3e a7  |...,ny ne...sp>.|
-00000360  3f 74 96 8e 2a 6e a6 7e  7a e0 e4 16 03 01 00 04  |?t..*n.~z.......|
+000002c0  aa 0c 00 00 a6 03 00 1d  20 04 9f 8b 4f 13 83 26  |........ ...O..&|
+000002d0  a3 cf 08 6e 59 bf b5 49  b8 ff 95 94 21 8d 2a 56  |...nY..I....!.*V|
+000002e0  2e 4b be ad ac 89 6e 52  4d 00 80 5f 63 93 43 a2  |.K....nRM.._c.C.|
+000002f0  a6 fb 53 b0 ac 93 3f 55  1d c1 0f 71 1e 96 ba 9f  |..S...?U...q....|
+00000300  86 19 f3 83 7d 90 ce 06  24 9a 60 69 f0 35 24 5d  |....}...$.`i.5$]|
+00000310  9d ce 49 0d 6f ba 31 59  3c f2 64 27 66 76 0e f1  |..I.o.1Y<.d'fv..|
+00000320  33 eb b8 70 61 d3 0c 93  a3 62 c7 5e c2 06 9d 48  |3..pa....b.^...H|
+00000330  16 2e a6 62 50 18 f6 c0  79 c2 09 f3 d5 74 bf db  |...bP...y....t..|
+00000340  b8 d4 25 06 a7 be 4a b0  62 82 86 d0 00 86 5e a2  |..%...J.b.....^.|
+00000350  34 49 9b 37 37 9a b6 eb  cc b9 8b 17 1f 29 4b a3  |4I.77........)K.|
+00000360  51 e3 c3 e8 3e 6e df c4  1d e5 48 16 03 01 00 04  |Q...>n....H.....|
 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 5a cb 36  c8 1c 43 a8 e1 88 db c9  |....0Z.6..C.....|
-00000040  ae 78 b0 af 97 e4 c3 f6  25 51 8e 4d 57 94 ee ca  |.x......%Q.MW...|
-00000050  a4 8b 3f 4d 17 75 34 58  c3 fa a6 6f d4 e5 ae 3a  |..?M.u4X...o...:|
-00000060  cb 5a cb 11 ef                                    |.Z...|
+00000030  16 03 01 00 30 a6 3a 66  02 e6 09 6a dd 68 56 bc  |....0.:f...j.hV.|
+00000040  aa ec 82 c4 69 9b b9 45  44 ec e2 c2 5b 49 5d 9b  |....i..ED...[I].|
+00000050  f8 0e 81 1e 23 9e 13 72  d1 d2 0c 24 01 4f 35 aa  |....#..r...$.O5.|
+00000060  27 fc b3 cc 08                                    |'....|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 96 92 50 6f f0  |..........0..Po.|
-00000010  d1 ff 7c 39 fb 75 0c 8b  c9 d7 29 7d 9d 32 4c 19  |..|9.u....)}.2L.|
-00000020  2e 93 ea 11 87 07 fc 5a  7d 3c 30 e1 bd 64 7f 90  |.......Z}<0..d..|
-00000030  fd 70 1d 50 eb ec f2 d6  de 09 61                 |.p.P......a|
+00000000  14 03 01 00 01 01 16 03  01 00 30 0e 25 d7 a9 c0  |..........0.%...|
+00000010  18 3b bf 55 c0 47 3a 95  2d cb 6f c2 2c de e3 94  |.;.U.G:.-.o.,...|
+00000020  32 d3 eb e2 b6 6b 5f 42  9c 1e 47 d6 76 0c eb 95  |2....k_B..G.v...|
+00000030  fd 2d c3 9a ee ee 83 87  e8 8d 83                 |.-.........|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 fd a4 ba  f1 78 a9 a2 45 d3 d2 5a  |.... ....x..E..Z|
-00000010  1e 41 6b 89 8d bd a4 21  69 03 a1 7c b8 56 ff df  |.Ak....!i..|.V..|
-00000020  67 bc 85 5e 21 17 03 01  00 20 a7 6d 4c 11 d0 f3  |g..^!.... .mL...|
-00000030  7d e2 f0 69 18 7c 42 71  78 e4 3b 71 7d 13 27 bb  |}..i.|Bqx.;q}.'.|
-00000040  79 fd d7 b2 d7 28 ca 92  83 f1 15 03 01 00 20 10  |y....(........ .|
-00000050  b3 79 d4 1d 70 db b7 6c  f2 15 05 3c 4d 65 ba ec  |.y..p..l...<Me..|
-00000060  e8 0e 6a ba 88 90 53 2e  6e 29 9c 56 9f 52 5e     |..j...S.n).V.R^|
+00000000  17 03 01 00 20 ba b0 c4  22 ee 52 81 ca 55 97 4d  |.... ...".R..U.M|
+00000010  39 16 b9 37 bf df 7b d1  ae 4b 47 ac 10 12 a9 77  |9..7..{..KG....w|
+00000020  69 50 f3 60 13 17 03 01  00 20 90 d5 17 e4 96 38  |iP.`..... .....8|
+00000030  cd f7 30 6e 19 45 4e 32  ad 5f 1b 00 bf 22 9d c2  |..0n.EN2._..."..|
+00000040  16 30 fe 92 c7 fc 91 38  29 30 15 03 01 00 20 c0  |.0.....8)0.... .|
+00000050  02 ff 81 82 c9 25 c6 b0  06 ee 18 61 19 c8 d2 20  |.....%.....a... |
+00000060  d8 4e 7b a4 a5 57 17 64  4d ad 1e 1e 16 1e 52     |.N{..W.dM.....R|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial b/src/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial
index 1c65914..6a40d83 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial
+++ b/src/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 7a a4 22 4f 19  |....Y...U..z."O.|
-00000010  54 37 47 cb e5 dd b4 54  86 9e 9e d6 3f f1 bd ca  |T7G....T....?...|
-00000020  9a 3e 16 3c 7e 1a 29 22  0d c8 95 20 ac 85 42 c1  |.>.<~.)"... ..B.|
-00000030  e7 f3 38 62 38 24 a8 24  d2 67 bd 0d 06 44 74 cf  |..8b8$.$.g...Dt.|
-00000040  3d a4 37 17 bc 8c 5d 41  9f 5a 74 69 c0 13 00 00  |=.7...]A.Zti....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 05 31 9d 41 04  |....Y...U...1.A.|
+00000010  c0 d4 34 1a fc 0f 63 26  47 d6 13 7f a0 d8 aa bf  |..4...c&G.......|
+00000020  28 92 04 80 02 75 58 e6  01 e1 30 20 3c fc b0 02  |(....uX...0 <...|
+00000030  8b a4 9e 9e b2 5c 17 3c  48 0b 96 6f 15 80 d5 38  |.....\.<H..o...8|
+00000040  25 a2 f8 fb 6b fd 47 27  c2 53 6c 60 c0 13 00 00  |%...k.G'.Sl`....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,36 +60,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 71 52 12 72 a7 56 0b  |........ qR.r.V.|
-000002d0  51 81 af 9f e1 95 43 44  54 0e 9e 3d cc 6f 3c 4c  |Q.....CDT..=.o<L|
-000002e0  d7 9c e4 ae d5 ad 13 8b  28 00 80 46 29 b1 46 71  |........(..F).Fq|
-000002f0  ba 0a 3d be 29 0f 57 43  02 05 4e 49 a4 5b cd 39  |..=.).WC..NI.[.9|
-00000300  1c 44 6d 84 02 60 84 b6  7f ff 4e d8 0e e7 16 5a  |.Dm..`....N....Z|
-00000310  dd 3b 5a e0 e5 d0 b6 2c  fb 95 35 94 a0 b6 97 24  |.;Z....,..5....$|
-00000320  92 d7 b1 71 78 ee 15 6f  b2 47 fd c7 a6 a4 94 eb  |...qx..o.G......|
-00000330  44 61 9f 96 83 1d 89 a6  62 d9 9e 5b b2 3d 69 9d  |Da......b..[.=i.|
-00000340  59 c5 a4 4e e0 33 69 0c  56 6f 86 6c 6b e5 be c4  |Y..N.3i.Vo.lk...|
-00000350  ed e4 39 53 f3 fd ea 60  d2 b7 d9 5e 90 fd a3 3e  |..9S...`...^...>|
-00000360  cb 59 5d 81 da 58 07 83  e7 af 25 16 03 01 00 04  |.Y]..X....%.....|
+000002c0  aa 0c 00 00 a6 03 00 1d  20 a4 50 9a 0d c7 2a 1b  |........ .P...*.|
+000002d0  f6 d4 78 49 68 ac 5f 8b  e7 78 68 05 4b f8 c6 b3  |..xIh._..xh.K...|
+000002e0  eb 28 79 96 d5 e6 aa c1  54 00 80 22 66 ec fd 14  |.(y.....T.."f...|
+000002f0  83 7b 03 86 14 75 84 a4  a6 d0 ee d3 d0 f7 95 d8  |.{...u..........|
+00000300  43 48 a4 eb 83 af 96 ac  cf e8 65 20 05 c3 18 9a  |CH........e ....|
+00000310  54 63 f5 2f b7 17 06 e0  2a b3 65 6a 2f cc cd 93  |Tc./....*.ej/...|
+00000320  1e b3 5a 4d 09 da 70 b0  12 46 60 11 e4 9f ee 9f  |..ZM..p..F`.....|
+00000330  3b 6f ef df bc db 69 22  5e e8 4c 41 d6 b7 7b 06  |;o....i"^.LA..{.|
+00000340  b6 99 1c 6d 01 5a 61 7c  4e 3a af 3e 01 7e 46 bd  |...m.Za|N:.>.~F.|
+00000350  c8 15 28 ba 7f b3 d6 9d  95 74 04 36 6c 38 16 86  |..(......t.6l8..|
+00000360  d2 1d 8a 85 d1 21 5c 33  17 50 a1 16 03 01 00 04  |.....!\3.P......|
 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 c3 26 49  92 5a 8c d0 da 48 ba 60  |....0.&I.Z...H.`|
-00000040  29 c0 5c d5 44 04 11 7a  25 b5 d6 9f a4 cf fe bf  |).\.D..z%.......|
-00000050  33 a7 ba c2 96 2b 4d c1  fb dc 4c ba b8 2b 6f 20  |3....+M...L..+o |
-00000060  2d 2a 02 ee 17                                    |-*...|
+00000030  16 03 01 00 30 f0 15 ea  81 0f a6 22 0a cd a5 a1  |....0......"....|
+00000040  38 4a da 1b 6c 81 19 d5  35 b7 af e9 ec 16 4d 98  |8J..l...5.....M.|
+00000050  21 c2 0e f7 0b fb ff d8  1e 2d 8b 04 56 82 48 c4  |!........-..V.H.|
+00000060  e5 f9 38 8c d2                                    |..8..|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 f4 4e 0a ea 58  |..........0.N..X|
-00000010  18 c6 9d 5f aa 5d f0 03  d4 63 0d e7 83 cb a8 18  |..._.]...c......|
-00000020  06 fa b6 82 da df 16 89  5c 8b 5d 92 87 b1 42 da  |........\.]...B.|
-00000030  cd 2a ee dc 43 08 f1 0d  1f 18 5c                 |.*..C.....\|
+00000000  14 03 01 00 01 01 16 03  01 00 30 f0 b5 a3 bb bb  |..........0.....|
+00000010  9d 85 7d 6f e7 a9 17 31  65 74 82 69 56 a9 33 21  |..}o...1et.iV.3!|
+00000020  16 9d 75 3a 28 88 a5 c2  a9 e1 a7 43 6e 03 26 96  |..u:(......Cn.&.|
+00000030  37 4b de 63 be 49 cb c8  d4 a2 b6                 |7K.c.I.....|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 e6 95 10  e0 98 07 9f 2b 42 06 b8  |.... .......+B..|
-00000010  2a 6c 5d 4a 95 2a 2c 17  d5 cc 68 42 18 bd 72 58  |*l]J.*,...hB..rX|
-00000020  c1 39 73 05 75 17 03 01  00 20 d4 ae 70 ee a0 ed  |.9s.u.... ..p...|
-00000030  3e dd f9 aa 93 03 ff f5  a4 f6 f3 0d e7 a6 59 a9  |>.............Y.|
-00000040  40 b4 f6 ad a5 46 0b eb  ee 0e 15 03 01 00 20 7c  |@....F........ ||
-00000050  1a 29 f3 49 60 47 2e 52  ec 00 4a 62 44 30 93 5f  |.).I`G.R..JbD0._|
-00000060  df 73 2f 44 65 3f 77 c1  3d 04 32 c8 bb 86 ed     |.s/De?w.=.2....|
+00000000  17 03 01 00 20 a9 9c 8f  74 ce f9 77 bc b3 86 2e  |.... ...t..w....|
+00000010  a5 8e 94 3d 08 a6 96 bf  25 0b 10 c4 66 c2 59 9a  |...=....%...f.Y.|
+00000020  4a 1a b4 77 12 17 03 01  00 20 03 72 60 38 58 88  |J..w..... .r`8X.|
+00000030  86 20 20 3f 18 52 c5 ca  55 3c 04 04 c7 e1 74 6f  |.  ?.R..U<....to|
+00000040  ca 1f cd 27 64 f2 51 12  9c ee 15 03 01 00 20 30  |...'d.Q....... 0|
+00000050  71 2a 78 bf 8b d5 11 7c  63 11 c7 25 0e 56 25 ce  |q*x....|c..%.V%.|
+00000060  24 d5 d7 de a0 ba c7 ba  e6 dc db 8e e3 93 a6     |$..............|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4 b/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4
index 1fe13b9..dcc18ad 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4
+++ b/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 51 02 00 00  4d 03 01 5a 4f 78 41 d5  |....Q...M..ZOxA.|
-00000010  86 2f d2 0a c6 05 bc c9  8e cc bd b2 39 ac a5 78  |./..........9..x|
-00000020  e3 e5 31 b9 cb 01 af cb  ca fc 88 20 c9 61 c6 91  |..1........ .a..|
-00000030  b2 e5 70 df ca d0 41 a8  20 61 ab 08 f6 dc fe c0  |..p...A. a......|
-00000040  cc ea 1e 80 89 02 6a 26  ea f0 c8 71 00 05 00 00  |......j&...q....|
+00000000  16 03 01 00 51 02 00 00  4d 03 01 2a 09 26 d2 61  |....Q...M..*.&.a|
+00000010  ac 38 91 3d 18 3f f7 a9  3c 34 91 b0 b1 e1 29 68  |.8.=.?..<4....)h|
+00000020  dd cb b9 a9 d8 39 0b 64  c6 93 7d 20 ea 51 ff 63  |.....9.d..} .Q.c|
+00000030  97 03 b2 6f a3 d6 55 0d  64 65 2a 5d 3a fe e9 3e  |...o..U.de*]:..>|
+00000040  47 c1 7d c5 d8 03 c6 22  19 2f 6c 5a 00 05 00 00  |G.}...."./lZ....|
 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..|
@@ -70,15 +70,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 48 fd  e6 fc 4a 94 33 82 22 ff  |.....$H...J.3.".|
-000000a0  af c3 44 98 d2 c6 4e 8a  39 43 dd 4b 2a 11 2b 4e  |..D...N.9C.K*.+N|
-000000b0  5b d9 a4 fc 6c 95 d7 69  05 f9                    |[...l..i..|
+00000090  01 16 03 01 00 24 29 ee  6c 54 d6 21 5e 31 30 9e  |.....$).lT.!^10.|
+000000a0  fd 02 69 bb 32 c2 9e ad  28 b1 2d 94 49 0a 12 0c  |..i.2...(.-.I...|
+000000b0  a1 12 b0 98 a6 33 eb 63  2b e4                    |.....3.c+.|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 24 61 d2 68 5e 12  |..........$a.h^.|
-00000010  91 6e 7f fe bf b7 42 58  e9 06 38 09 c1 16 34 e5  |.n....BX..8...4.|
-00000020  a1 46 d6 cf 23 ca 48 c1  ed 76 f9 48 a1 9a 2a     |.F..#.H..v.H..*|
+00000000  14 03 01 00 01 01 16 03  01 00 24 32 3e 45 f2 3a  |..........$2>E.:|
+00000010  01 05 50 db 37 25 f6 b5  67 8e 38 3d f5 ba b7 90  |..P.7%..g.8=....|
+00000020  e0 05 a8 cb e0 33 1a 79  ab 44 86 d5 0c fd 86     |.....3.y.D.....|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 1a 3a e1 39  7c fe 25 50 dc 66 3f b6  |.....:.9|.%P.f?.|
-00000010  6f fd 79 3b 12 83 af 89  b1 c5 f6 75 56 ad a1 15  |o.y;.......uV...|
-00000020  03 01 00 16 07 d1 d3 7a  54 1c 71 0b c8 64 10 46  |.......zT.q..d.F|
-00000030  30 d0 bf df 75 a6 dc 10  b1 d1                    |0...u.....|
+00000000  17 03 01 00 1a ac 0c 1f  12 4e d4 31 10 dd c1 04  |.........N.1....|
+00000010  8b 55 a2 2e a5 f4 e4 80  aa 23 7e bd 79 b0 ee 15  |.U.......#~.y...|
+00000020  03 01 00 16 fa d9 ff 50  7d 41 01 2a d2 13 ee 33  |.......P}A.*...3|
+00000030  52 ab 20 c5 e7 73 81 5d  81 60                    |R. ..s.].`|
diff --git a/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
index 9d18cd6..92cdc4c 100644
--- a/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
+++ b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 59 02 00 00  55 03 02 23 a8 e7 14 3f  |....Y...U..#...?|
-00000010  64 61 3c ee 80 a2 94 84  ab b8 66 76 30 84 06 78  |da<.......fv0..x|
-00000020  96 ba a7 d3 1e 81 1b 16  64 76 88 20 3d 21 21 b3  |........dv. =!!.|
-00000030  45 dd fe cb 5b d7 9a 86  39 ee 4f f8 60 eb 95 ea  |E...[...9.O.`...|
-00000040  ab 64 48 14 74 16 fd e9  47 07 66 60 c0 09 00 00  |.dH.t...G.f`....|
+00000000  16 03 02 00 59 02 00 00  55 03 02 bf ac 6b 91 53  |....Y...U....k.S|
+00000010  dc 1f d6 ee 0e 71 d6 a4  f5 a2 7c f0 10 69 41 dd  |.....q....|..iA.|
+00000020  4a b7 30 53 e6 28 07 31  34 8f e5 20 59 d1 bd e1  |J.0S.(.14.. Y...|
+00000030  20 44 c4 05 07 e9 07 90  5d de 08 73 72 55 04 a6  | D......]..srU..|
+00000040  11 20 bf 32 e0 dd 46 d4  1d ed 45 62 c0 09 00 00  |. .2..F...Eb....|
 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....|
@@ -55,39 +55,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 b4 0c 00  00 b0 03 00 1d 20 a7 a4  |*............ ..|
-00000280  33 20 48 6a 74 8e 07 fc  c0 b6 10 61 84 d6 67 d1  |3 Hjt......a..g.|
-00000290  ae cf 65 36 4d d5 13 a1  07 fc 1f aa 77 44 00 8a  |..e6M.......wD..|
-000002a0  30 81 87 02 42 01 02 5b  f9 4a af 8d 0a d5 a3 de  |0...B..[.J......|
-000002b0  11 62 d8 f1 db 49 7a 0c  34 3e 2d 61 f9 6f 6b c2  |.b...Iz.4>-a.ok.|
-000002c0  1d 32 4b 88 93 9b 22 b0  3d 09 c3 93 9e 25 31 d6  |.2K...".=....%1.|
-000002d0  5f 06 3a f0 4a 61 0b 06  03 5d 6c 0e b3 5e 48 5a  |_.:.Ja...]l..^HZ|
-000002e0  f0 5b 21 48 58 8f b2 02  41 1c 57 f1 51 04 d6 f8  |.[!HX...A.W.Q...|
-000002f0  a2 51 e6 e6 3e e0 99 63  aa d2 1c 7b 92 be 44 ec  |.Q..>..c...{..D.|
-00000300  86 c3 31 fa e7 9b 98 1a  59 a5 93 3e a9 73 f0 ec  |..1.....Y..>.s..|
-00000310  03 22 37 19 db 78 30 27  ab bf 52 07 6c 3a 79 f5  |."7..x0'..R.l:y.|
-00000320  ad 70 59 76 84 44 f0 47  e0 3d 16 03 02 00 04 0e  |.pYv.D.G.=......|
-00000330  00 00 00                                          |...|
+00000270  2a 16 03 02 00 b5 0c 00  00 b1 03 00 1d 20 ab ea  |*............ ..|
+00000280  ff 17 1e b1 ef f6 22 03  40 8b e1 1a fa ab 01 cf  |......".@.......|
+00000290  0f f0 b0 6d 43 3c 1f 03  a1 d6 4a 9d 79 43 00 8b  |...mC<....J.yC..|
+000002a0  30 81 88 02 42 00 a1 b4  50 4b 9b a3 a5 ec ef dc  |0...B...PK......|
+000002b0  bf c1 a2 65 24 2a 6c aa  ab 26 01 ed d1 ad 2e 37  |...e$*l..&.....7|
+000002c0  4f f5 8b ff 98 ac ef 15  3e d9 46 07 a3 d2 35 de  |O.......>.F...5.|
+000002d0  91 bc 3d a0 1f f1 68 55  28 ef 60 ad 13 05 ac 65  |..=...hU(.`....e|
+000002e0  e5 67 02 3f 85 8b 1b 02  42 01 26 3f fc 62 e3 93  |.g.?....B.&?.b..|
+000002f0  8e fa fb 93 0f 0b ff 68  25 46 ea 71 16 ae 6e d4  |.......h%F.q..n.|
+00000300  36 9e 48 2c 77 2b d8 f5  f6 1d 69 68 ed 28 8f e7  |6.H,w+....ih.(..|
+00000310  79 7e 78 56 52 ff e8 62  fc e2 bd 2e c7 e8 9f 3f  |y~xVR..b.......?|
+00000320  93 47 d2 62 6c f6 5c 0e  a2 b8 fe 16 03 02 00 04  |.G.bl.\.........|
+00000330  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 ef 0f 92  ac 11 fe 97 1a 46 69 e4  |.............Fi.|
-00000050  b3 26 8d d7 92 46 02 25  5b 2e 86 3e 96 3d 64 ed  |.&...F.%[..>.=d.|
-00000060  37 92 dd ae a5 a6 9f 03  f0 c2 42 78 9f b9 78 ac  |7.........Bx..x.|
-00000070  97 ab 82 25 e2                                    |...%.|
+00000040  00 00 00 00 00 0f 55 37  4b 93 d5 ce b1 1c 6f a3  |......U7K.....o.|
+00000050  6d 56 32 f5 de 19 f6 a3  15 b0 6a 90 06 92 60 ca  |mV2.......j...`.|
+00000060  ec 0e 2b d4 24 16 0a 26  f3 bd 3d ca c5 9f d2 9b  |..+.$..&..=.....|
+00000070  79 2f af b6 b0                                    |y/...|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 40 df a9 23 37 74  |..........@..#7t|
-00000010  47 d8 98 87 53 b4 0a 4d  b0 a5 fb cb d6 37 c8 7c  |G...S..M.....7.||
-00000020  61 95 81 ef b3 63 78 2b  53 c2 86 fc 39 df c4 5f  |a....cx+S...9.._|
-00000030  e4 4b af 1d fe bc 4c fe  1b 6a 28 c3 46 6f 24 94  |.K....L..j(.Fo$.|
-00000040  a8 bf ef ce e8 e8 ad 2c  d9 10 32                 |.......,..2|
+00000000  14 03 02 00 01 01 16 03  02 00 40 4d e3 a9 af 51  |..........@M...Q|
+00000010  f5 d1 cd 04 f1 cf c5 48  0f 2e 0b 6e 57 4c 11 28  |.......H...nWL.(|
+00000020  dd 89 19 14 98 8e 2e 92  db 3c a4 0f 85 32 90 7e  |.........<...2.~|
+00000030  49 13 17 a0 85 fa c6 25  79 24 13 90 86 dc ec 45  |I......%y$.....E|
+00000040  7c 74 35 92 e4 89 04 c2  51 27 66                 ||t5.....Q'f|
 >>> 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 34 50 ce  9c 7f f5 2d a2 c1 e4 5c  |.....4P....-...\|
-00000020  fa d1 a0 f4 38 e8 4f 51  54 36 07 da f1 af 6d ef  |....8.OQT6....m.|
-00000030  b8 b0 bc bc a6 15 03 02  00 30 00 00 00 00 00 00  |.........0......|
-00000040  00 00 00 00 00 00 00 00  00 00 0b d4 8e e8 69 64  |..............id|
-00000050  53 38 7c 72 d8 1d 9f d5  8a 83 74 a7 37 6b e2 c0  |S8|r......t.7k..|
-00000060  8f 26 e7 5d 0e 06 ae e0  db fb                    |.&.]......|
+00000010  00 00 00 00 00 f9 ac 17  1f 08 b7 80 fb 70 87 e2  |.............p..|
+00000020  53 00 27 60 78 6c 80 5b  57 e7 70 72 8a e3 1b 32  |S.'`xl.[W.pr...2|
+00000030  8c f0 67 82 82 15 03 02  00 30 00 00 00 00 00 00  |..g......0......|
+00000040  00 00 00 00 00 00 00 00  00 00 01 e1 86 47 7f 65  |.............G.e|
+00000050  a9 d2 1c 22 7d 99 7c 41  dc 17 f5 16 40 5b b3 7f  |..."}.|A....@[..|
+00000060  cc 0b 97 41 0c ae 1f 0c  39 e0                    |...A....9.|
diff --git a/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
index 4cc9610..b2b7ecb 100644
--- a/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
+++ b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 59 02 00 00  55 03 02 6e ff 3b 26 66  |....Y...U..n.;&f|
-00000010  7c 32 3f 42 fd 92 7c 12  db 26 b2 45 6e 28 b9 49  ||2?B..|..&.En(.I|
-00000020  86 6b 00 54 92 3b 65 a6  02 6d 94 20 ea 44 db 5c  |.k.T.;e..m. .D.\|
-00000030  d1 39 35 b2 ea 1c 6d 3e  94 bb 47 60 25 1e 9c 74  |.95...m>..G`%..t|
-00000040  e7 bd 54 cc 2b 36 14 6a  12 54 5b 6c c0 13 00 00  |..T.+6.j.T[l....|
+00000000  16 03 02 00 59 02 00 00  55 03 02 95 6e 24 5a ab  |....Y...U...n$Z.|
+00000010  ae 3c 73 52 9d 31 63 50  cf f9 50 99 3c e4 94 22  |.<sR.1cP..P.<.."|
+00000020  5b 6f 0e f8 e3 a8 64 4c  d2 8c 00 20 8b 2d 25 47  |[o....dL... .-%G|
+00000030  f9 74 41 93 b1 82 b5 c5  fc 3e 42 c9 35 fc 68 27  |.tA......>B.5.h'|
+00000040  c4 2b 35 0f f8 1c e3 28  e6 8a 59 dc c0 13 00 00  |.+5....(..Y.....|
 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..............|
@@ -60,38 +60,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 82 3b d2 56 dd cd d8  |........ .;.V...|
-000002d0  e1 98 a7 90 d1 08 2d 37  dc e8 21 cd 29 af 29 a5  |......-7..!.).).|
-000002e0  78 8e 59 9e 4c ac c9 d2  4b 00 80 25 20 91 4e 0d  |x.Y.L...K..% .N.|
-000002f0  74 12 9e 1c 98 fb 5f 4b  ad fd c8 68 df 6b 82 98  |t....._K...h.k..|
-00000300  a8 7c ee 17 44 47 91 2a  42 c1 82 d0 ce aa cd f8  |.|..DG.*B.......|
-00000310  69 1e 85 79 27 fe ef 5a  a2 e1 35 30 9a 2d c6 b0  |i..y'..Z..50.-..|
-00000320  43 84 39 7f 8d 68 09 d6  6c 1a 84 0f c0 9a c0 9f  |C.9..h..l.......|
-00000330  64 56 cb fc 32 f2 4a a3  26 e8 c2 5f d7 16 3e 7c  |dV..2.J.&.._..>||
-00000340  4e 8b 89 f8 7f f4 c2 26  fe 01 cd 48 b6 61 9c 93  |N......&...H.a..|
-00000350  1a bc a1 d1 01 c5 bf ef  43 b4 ca 86 62 37 b4 99  |........C...b7..|
-00000360  54 69 db 74 51 92 92 dd  c1 b1 75 16 03 02 00 04  |Ti.tQ.....u.....|
+000002c0  aa 0c 00 00 a6 03 00 1d  20 b5 75 ee e5 26 6b c0  |........ .u..&k.|
+000002d0  af 34 8a 24 f7 c5 25 58  29 38 4c 08 d3 a2 0c 48  |.4.$..%X)8L....H|
+000002e0  18 eb a0 5b e8 64 62 62  78 00 80 d0 1c 9c 11 1a  |...[.dbbx.......|
+000002f0  58 4c 46 5f 18 03 d7 d7  76 47 d5 56 7a bb bd 95  |XLF_....vG.Vz...|
+00000300  16 46 e8 0b 28 6e df 15  65 1a f6 95 fb 4a 6c 42  |.F..(n..e....JlB|
+00000310  1b 4c 5c 30 c5 de d0 83  08 d3 2e 4d 59 7e 7b 1b  |.L\0.......MY~{.|
+00000320  20 9e b5 19 76 fe a3 dd  87 04 f4 9a 3e 3c c0 4a  | ...v.......><.J|
+00000330  16 7f e3 4e 9a 1f 0a 36  1d f5 09 b4 88 09 b1 1b  |...N...6........|
+00000340  9b 60 97 dc d7 ea 97 f4  d6 06 16 45 98 ee 5c 39  |.`.........E..\9|
+00000350  62 3f 7c 82 7b c3 52 59  01 d4 89 8c a6 e2 d5 eb  |b?|.{.RY........|
+00000360  e8 30 a6 78 49 1e ec a5  92 ad 24 16 03 02 00 04  |.0.xI.....$.....|
 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 c5 bf e6  b3 86 12 92 df 68 fa 75  |.............h.u|
-00000050  79 5f ee fe 60 91 d1 fd  8a 48 3b 97 b4 da 7f 58  |y_..`....H;....X|
-00000060  3e 7e 40 d7 93 1d 6b e2  0e 2a a4 45 20 e0 9d f9  |>~@...k..*.E ...|
-00000070  b6 5e b1 f1 4f                                    |.^..O|
+00000040  00 00 00 00 00 28 ab ed  77 d3 56 29 a8 4a 38 c8  |.....(..w.V).J8.|
+00000050  64 1c a5 d9 4e f9 6b 0e  fa 82 42 ad 0d be 15 69  |d...N.k...B....i|
+00000060  9a ff 79 64 db 8f 3e 16  b3 86 93 82 6f 78 c4 2e  |..yd..>.....ox..|
+00000070  7c 54 6c 4f 90                                    ||TlO.|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 40 bf 58 92 80 02  |..........@.X...|
-00000010  75 91 40 30 35 e0 16 76  f4 97 bd 77 46 a3 a3 4e  |u.@05..v...wF..N|
-00000020  f1 be 53 eb b8 56 45 b1  71 c9 f8 a9 bf c6 9a 00  |..S..VE.q.......|
-00000030  83 46 91 88 d5 7b 72 95  27 33 80 43 3f 3e f6 60  |.F...{r.'3.C?>.`|
-00000040  c6 55 90 6a 87 8e 7d 48  27 e2 40                 |.U.j..}H'.@|
+00000000  14 03 02 00 01 01 16 03  02 00 40 15 e9 c5 15 59  |..........@....Y|
+00000010  b3 0d 46 22 0c ae a6 41  02 b4 f3 da 11 dc 85 79  |..F"...A.......y|
+00000020  bb d9 3f 23 38 51 24 1a  08 b5 a0 63 dc 4b 86 50  |..?#8Q$....c.K.P|
+00000030  ef b2 32 07 fd b5 e1 01  06 19 42 ce ba 69 ab 1a  |..2.......B..i..|
+00000040  c9 bb db 7d d0 9f f9 7c  f2 6c 18                 |...}...|.l.|
 >>> 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 f5 6b bc  6d 2c 70 b1 c0 f0 ab 78  |......k.m,p....x|
-00000020  44 c9 97 f6 59 ef 15 e4  05 cf e0 55 ee a4 68 8c  |D...Y......U..h.|
-00000030  86 57 82 bd 84 15 03 02  00 30 00 00 00 00 00 00  |.W.......0......|
-00000040  00 00 00 00 00 00 00 00  00 00 ef b2 a9 a5 bb a3  |................|
-00000050  6e e5 d1 2b ef 83 1d 11  de 29 d2 30 2c fc 78 73  |n..+.....).0,.xs|
-00000060  6b 6e 0a d2 55 67 5c d4  58 b3                    |kn..Ug\.X.|
+00000010  00 00 00 00 00 67 ef de  df a4 91 69 58 b8 3f 06  |.....g.....iX.?.|
+00000020  c4 05 4e ad 88 9b c5 12  35 cf 63 39 3a 61 e9 4c  |..N.....5.c9:a.L|
+00000030  49 22 93 f4 10 15 03 02  00 30 00 00 00 00 00 00  |I".......0......|
+00000040  00 00 00 00 00 00 00 00  00 00 00 2a 5a ba 39 7e  |...........*Z.9~|
+00000050  a8 be 2e 72 f3 ba 7e 0a  32 b5 8c d8 f5 1b 93 6c  |...r..~.2......l|
+00000060  3e 35 d8 ba cc f3 9f f4  19 74                    |>5.......t|
diff --git a/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4 b/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4
index 9dae5dd..aeba311 100644
--- a/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4
+++ b/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 51 02 00 00  4d 03 02 96 ca 2a e7 23  |....Q...M....*.#|
-00000010  af 2e 45 62 15 fa 5a 84  bc aa 7c 79 03 1b 37 69  |..Eb..Z...|y..7i|
-00000020  a0 77 ce 03 81 b7 e5 7d  31 34 6e 20 93 83 5d 7c  |.w.....}14n ..]||
-00000030  e8 c7 48 f9 67 ec 97 b1  27 b6 de de 89 07 5a cf  |..H.g...'.....Z.|
-00000040  44 77 48 4b e9 62 43 e3  87 fd de 87 00 05 00 00  |DwHK.bC.........|
+00000000  16 03 02 00 51 02 00 00  4d 03 02 82 5b 12 ac 33  |....Q...M...[..3|
+00000010  08 d4 28 8c 91 6e 52 c4  c6 09 13 24 bf 42 d2 37  |..(..nR....$.B.7|
+00000020  6d 78 60 b0 ea bd 9e b3  08 99 43 20 05 5a 93 f9  |mx`.......C .Z..|
+00000030  a4 39 43 4f c4 e3 27 20  7d 4c fa 7a 28 c1 c7 33  |.9CO..' }L.z(..3|
+00000040  72 fa 14 b8 ba c3 89 b0  a5 54 a3 7c 00 05 00 00  |r........T.|....|
 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..|
@@ -70,15 +70,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 33 5d  7f cb 6e 36 19 8b db 35  |.....$3]..n6...5|
-000000a0  88 16 87 7a 9d 5a 51 27  51 13 17 64 0e 57 d5 e1  |...z.ZQ'Q..d.W..|
-000000b0  6e 34 8d e6 99 a8 38 b2  e7 3a                    |n4....8..:|
+00000090  01 16 03 02 00 24 e1 1a  bf e9 fd 4c fb 56 41 82  |.....$.....L.VA.|
+000000a0  c2 48 fc ca d9 d5 ec 2a  0a ee 63 25 e0 5f 53 cf  |.H.....*..c%._S.|
+000000b0  24 ff fe da 6f f5 8b 61  b7 b9                    |$...o..a..|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 24 e0 8b 90 9b 83  |..........$.....|
-00000010  f5 3d 00 e9 cf 7b 1d 75  cf c8 16 f2 29 8d de 0b  |.=...{.u....)...|
-00000020  75 82 b1 c4 6e 1c 1f ab  e9 90 74 31 99 f2 ad     |u...n.....t1...|
+00000000  14 03 02 00 01 01 16 03  02 00 24 99 2c e7 fa d0  |..........$.,...|
+00000010  29 d9 92 07 39 56 b0 0c  ad 23 30 c8 d7 0b 38 da  |)...9V...#0...8.|
+00000020  6f d3 c7 f9 66 d2 ec 8c  52 85 cb db a6 22 50     |o...f...R...."P|
 >>> Flow 5 (client to server)
-00000000  17 03 02 00 1a ca 2a 95  13 de 40 0d af 44 a4 aa  |......*...@..D..|
-00000010  9a 35 d7 38 c7 9f 74 4f  3a bf d1 9c cd 9e ee 15  |.5.8..tO:.......|
-00000020  03 02 00 16 d3 a4 32 78  a9 00 1b 7a 48 3e 7c 2b  |......2x...zH>|+|
-00000030  f9 3b 92 32 20 0b f4 16  39 18                    |.;.2 ...9.|
+00000000  17 03 02 00 1a 9f 70 c4  77 f3 0a a8 e0 1a 75 87  |......p.w.....u.|
+00000010  ab 2a f1 23 52 79 9f 5c  8e af 5d ba 27 45 f9 15  |.*.#Ry.\..].'E..|
+00000020  03 02 00 16 f0 28 f3 71  a0 97 6b ba 7e 97 81 85  |.....(.q..k.~...|
+00000030  11 59 1b c9 fa a0 48 32  e9 65                    |.Y....H2.e|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA256 b/src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA256
index 4412f53..ce92872 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA256
+++ b/src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA256
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 51 02 00 00  4d 03 03 1d be be 1e eb  |....Q...M.......|
-00000010  59 2c d5 07 b9 7a 64 47  95 84 ef cf d9 3e 82 4c  |Y,...zdG.....>.L|
-00000020  00 c0 0a 69 8a 01 2a b3  42 78 02 20 5e 32 5c 88  |...i..*.Bx. ^2\.|
-00000030  50 ed d5 44 41 4f bf a9  4e 49 83 5d aa 7c 2e 5d  |P..DAO..NI.].|.]|
-00000040  85 e8 64 92 5e 49 5d 8a  d0 0e 89 eb 00 9c 00 00  |..d.^I].........|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 a4 26 bb e9 70  |....Q...M...&..p|
+00000010  57 4e ec f8 ea 23 01 75  c3 f3 a9 d4 d6 e8 71 2b  |WN...#.u......q+|
+00000020  01 5e c0 73 19 2b b9 d8  8e 3e d1 20 c8 c3 0a 22  |.^.s.+...>. ..."|
+00000030  7b ee cd 2e c9 e8 95 db  90 db 70 f5 59 e6 90 65  |{.........p.Y..e|
+00000040  35 87 a6 d4 bb dd 85 34  43 e8 66 49 00 9c 00 00  |5......4C.fI....|
 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..|
@@ -70,17 +70,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 69 38  |.....(........i8|
-000000a0  97 84 2e 77 5c b8 58 82  b5 78 85 2e f3 7b 92 81  |...w\.X..x...{..|
-000000b0  00 72 91 23 41 ae 59 6c  18 64 f0 62 f2 c9        |.r.#A.Yl.d.b..|
+00000090  01 16 03 03 00 28 00 00  00 00 00 00 00 00 64 6c  |.....(........dl|
+000000a0  08 78 1d 03 0c ed dd 01  30 d4 fb 7c 3f 24 45 cc  |.x......0..|?$E.|
+000000b0  f6 b2 e3 42 07 93 8f 34  a8 21 d1 b0 08 e3        |...B...4.!....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 37 f7 98 2f 78  |..........(7../x|
-00000010  54 85 5f 2e cb a9 b7 bf  4b 2d 62 06 e2 32 cd 18  |T._.....K-b..2..|
-00000020  de f5 54 c8 e0 54 2d c5  b4 98 07 7e c7 b7 79 a0  |..T..T-....~..y.|
-00000030  75 af 5c                                          |u.\|
+00000000  14 03 03 00 01 01 16 03  03 00 28 75 9b 91 cd 7d  |..........(u...}|
+00000010  8d f7 3c a0 d6 5e d4 f2  24 1a 0a f3 04 b1 d9 0b  |..<..^..$.......|
+00000020  1d 31 ca 1c 8b e7 38 c0  8e 7d 12 19 89 33 28 4d  |.1....8..}...3(M|
+00000030  83 28 b6                                          |.(.|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 78 c1 c0  |.............x..|
-00000010  7d 1b a8 b2 80 0e a3 64  cf e0 fa 71 9d 37 5d 32  |}......d...q.7]2|
-00000020  8d 36 38 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.68.............|
-00000030  c2 f3 41 1a 2c a4 4f 48  fa 61 14 40 60 51 e5 99  |..A.,.OH.a.@`Q..|
-00000040  c6 e5                                             |..|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 7d fe 53  |.............}.S|
+00000010  73 aa ca 3d f3 27 b7 01  56 9e e7 c9 6d 79 2a 97  |s..=.'..V...my*.|
+00000020  b2 21 42 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.!B.............|
+00000030  de bd 3e 9e 8f c0 98 ec  bd b4 9b 89 90 a2 26 a8  |..>...........&.|
+00000040  28 97                                             |(.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-AES128-SHA256 b/src/crypto/tls/testdata/Client-TLSv12-AES128-SHA256
index d756884..15394c7 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-AES128-SHA256
+++ b/src/crypto/tls/testdata/Client-TLSv12-AES128-SHA256
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 51 02 00 00  4d 03 03 c3 41 d7 9c 1b  |....Q...M...A...|
-00000010  9a ff f8 17 af 41 df 8d  96 70 bb b8 f6 9a 4c a2  |.....A...p....L.|
-00000020  03 25 31 2c 58 fa 05 5b  12 85 6a 20 18 3c 34 d6  |.%1,X..[..j .<4.|
-00000030  08 44 46 a5 5c b1 40 0d  38 33 c0 2d ea a6 46 53  |.DF.\.@.83.-..FS|
-00000040  0e 09 39 6f 11 35 02 63  cf 21 74 c2 00 3c 00 00  |..9o.5.c.!t..<..|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 8a a8 2c 00 d8  |....Q...M....,..|
+00000010  d8 87 53 14 1e 7b ff ca  19 a2 6d bc 47 6f 73 12  |..S..{....m.Gos.|
+00000020  0d 54 6e 33 21 80 01 86  f8 81 9f 20 46 f6 8c e8  |.Tn3!...... F...|
+00000030  8b 90 02 b2 da e2 83 3a  2a 0f b3 f7 96 2b f8 96  |.......:*....+..|
+00000040  56 77 39 52 9e a1 bd 74  1e 2e b1 b0 00 3c 00 00  |Vw9R...t.....<..|
 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..|
@@ -71,25 +71,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 88 20  99 51 5e fb 72 79 7f f8  |....... .Q^.ry..|
-000000b0  b2 a9 56 96 a3 03 1d a0  e0 38 1a be 4c ea 80 f9  |..V......8..L...|
-000000c0  c0 ef 45 81 91 7f b9 1b  f7 91 3b 4e 05 87 d6 73  |..E.......;N...s|
-000000d0  c0 27 94 50 4f 00 ee c1  02 af 5f 6f 4c a5 0e 5b  |.'.PO....._oL..[|
-000000e0  6c 76 87 28 b4 bf                                 |lv.(..|
+000000a0  00 00 00 00 00 00 8f d8  ac 7f ec 16 9e d8 e9 f2  |................|
+000000b0  ce 30 51 dc 87 e0 f9 80  57 66 d9 87 20 77 3a b1  |.0Q.....Wf.. w:.|
+000000c0  43 db fc 36 f5 64 6e 96  e9 b8 e2 ab bb 00 48 36  |C..6.dn.......H6|
+000000d0  60 9c 5a 7c 38 3f 13 e1  9c ef d9 15 96 91 56 e2  |`.Z|8?........V.|
+000000e0  87 2e 23 1a 98 40                                 |..#..@|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 50 93 14 a5 13 16  |..........P.....|
-00000010  d7 af 14 81 94 33 2d ae  f7 7a b1 b1 a5 38 fb e8  |.....3-..z...8..|
-00000020  c8 38 b3 ce f1 eb 70 e7  84 b6 fc 25 25 32 a9 09  |.8....p....%%2..|
-00000030  d1 0d 2d 59 57 6d d0 42  e8 c1 81 92 d0 af fb 5a  |..-YWm.B.......Z|
-00000040  08 7e 0f 3d 10 e5 42 6d  27 cd 8c 32 b2 20 4b 0a  |.~.=..Bm'..2. K.|
-00000050  75 76 ed 08 54 fe 74 94  72 35 9e                 |uv..T.t.r5.|
+00000000  14 03 03 00 01 01 16 03  03 00 50 80 01 08 cc d8  |..........P.....|
+00000010  08 a8 81 20 b2 bb 5b 50  79 74 4a b5 10 c4 7a 30  |... ..[PytJ...z0|
+00000020  6c 46 d6 e5 36 6e 4d cc  e5 0c 2c ab 3b de 92 45  |lF..6nM...,.;..E|
+00000030  ee 20 58 a9 0f 03 26 3e  6c 05 a7 ef f2 7c a7 9b  |. X...&>l....|..|
+00000040  57 c0 20 8d d0 69 0e b0  5a cc e6 26 5f e2 c3 24  |W. ..i..Z..&_..$|
+00000050  c4 db df 20 03 08 e1 aa  59 2b d2                 |... ....Y+.|
 >>> 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 53 91 38  34 33 20 94 0d 76 d7 72  |.....S.843 ..v.r|
-00000020  48 f3 17 34 01 ae 0e 89  db 60 f1 4e 64 a5 cf 0c  |H..4.....`.Nd...|
-00000030  32 52 3f a0 18 f8 c5 57  ed 3a d1 41 19 81 cf 0a  |2R?....W.:.A....|
-00000040  f2 d8 90 4b ba 15 03 03  00 40 00 00 00 00 00 00  |...K.....@......|
-00000050  00 00 00 00 00 00 00 00  00 00 05 2b 31 3c 1b a2  |...........+1<..|
-00000060  11 87 5f 0f 49 72 bb 67  e6 75 18 9c b1 f4 6c ed  |.._.Ir.g.u....l.|
-00000070  4d 01 58 35 30 43 44 e8  ee 1d f2 81 9d 67 6d 77  |M.X50CD......gmw|
-00000080  1e 36 61 7f f3 32 3d 60  73 6d                    |.6a..2=`sm|
+00000010  00 00 00 00 00 a2 dd a6  ff 57 60 80 dd 97 cf 20  |.........W`.... |
+00000020  10 04 60 80 53 17 37 ce  ce 39 b6 21 f4 06 61 aa  |..`.S.7..9.!..a.|
+00000030  49 7b f0 d5 e0 72 4c 6f  38 d2 ab af 1c 94 bd 5b  |I{...rLo8......[|
+00000040  1b ee 8a 9b e3 15 03 03  00 40 00 00 00 00 00 00  |.........@......|
+00000050  00 00 00 00 00 00 00 00  00 00 ba 18 32 e7 6d f5  |............2.m.|
+00000060  fa 2e 61 55 cc fe 3c 4d  19 fd 84 6d c4 2a 46 92  |..aU..<M...m.*F.|
+00000070  ae b7 f3 67 c8 3c ce cd  b0 66 de ee 5d 3f 07 3b  |...g.<...f..]?.;|
+00000080  a9 85 a1 93 1f 98 f7 95  c9 ac                    |..........|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA384 b/src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA384
index 2f552cb..766bf95 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA384
+++ b/src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA384
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 51 02 00 00  4d 03 03 2b 59 94 f3 9e  |....Q...M..+Y...|
-00000010  23 ae d3 58 82 1f 2e be  38 1d 14 e4 4c a4 b8 ed  |#..X....8...L...|
-00000020  95 08 b9 44 60 02 4b 0b  a9 6e ae 20 9b 43 e5 2a  |...D`.K..n. .C.*|
-00000030  0f 08 8e a4 c1 c0 15 79  9f af a5 ab a3 67 9d 09  |.......y.....g..|
-00000040  23 0e 8e 96 a9 aa 7d 26  74 d8 0c 9a 00 9d 00 00  |#.....}&t.......|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 de 7a 77 5b eb  |....Q...M...zw[.|
+00000010  fa 84 a0 ac ba 3b ca 25  dc b3 c0 06 44 da 31 5c  |.....;.%....D.1\|
+00000020  27 e0 4e af be 47 07 5a  a5 ab 20 20 72 b2 67 0c  |'.N..G.Z..  r.g.|
+00000030  7e 71 5d e3 55 89 91 27  7f 65 ac 71 c6 e8 a5 4a  |~q].U..'.e.q...J|
+00000040  ae e1 a2 0d 3f a6 62 08  17 7e 26 fd 00 9d 00 00  |....?.b..~&.....|
 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..|
@@ -70,17 +70,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 59 fc  |.....(........Y.|
-000000a0  aa b1 84 ab 09 82 00 88  8e e4 82 6e cd 24 9f b5  |...........n.$..|
-000000b0  01 95 d3 c3 f4 a2 16 54  25 91 77 76 fc f0        |.......T%.wv..|
+00000090  01 16 03 03 00 28 00 00  00 00 00 00 00 00 0b 7d  |.....(.........}|
+000000a0  83 0f 79 e2 4b ef d3 0e  ff 57 d2 55 cd ea e9 be  |..y.K....W.U....|
+000000b0  8b 38 1e 33 b0 6a eb e3  aa 51 52 82 e6 15        |.8.3.j...QR...|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 67 ac 20 d9 b6  |..........(g. ..|
-00000010  a9 f0 ec f6 7b 34 31 3a  5e 06 20 0f 5b 32 86 1b  |....{41:^. .[2..|
-00000020  da 5a c5 54 47 d0 ad 4f  95 2c b5 1f 17 3f ec 17  |.Z.TG..O.,...?..|
-00000030  a3 01 fc                                          |...|
+00000000  14 03 03 00 01 01 16 03  03 00 28 1a a3 bb d4 c4  |..........(.....|
+00000010  53 c7 5c 09 8c fb e7 51  41 73 d5 76 ef e6 40 9a  |S.\....QAs.v..@.|
+00000020  06 27 c6 e8 9f 1b 25 f5  d1 7b 39 b7 74 ab e8 83  |.'....%..{9.t...|
+00000030  26 f6 40                                          |&.@|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 6c 9c 0a  |.............l..|
-00000010  ae 0b 40 57 8b 24 6d 09  77 ae 2f 14 be 06 26 9e  |..@W.$m.w./...&.|
-00000020  0a bf 18 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
-00000030  32 50 20 68 3d 05 68 ed  0c ac 7a db 24 21 7e e0  |2P h=.h...z.$!~.|
-00000040  9e f0                                             |..|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 1c 0d 06  |................|
+00000010  d2 25 8a 06 d9 b4 d6 76  89 1c c6 b7 22 9f 44 63  |.%.....v....".Dc|
+00000020  a3 f9 89 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
+00000030  cb 34 e8 4b f7 b1 ab 1a  74 60 2c 2d cf a4 7d 9f  |.4.K....t`,-..}.|
+00000040  f4 b4                                             |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ALPN b/src/crypto/tls/testdata/Client-TLSv12-ALPN
index 358b211..8b9a510 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ALPN
+++ b/src/crypto/tls/testdata/Client-TLSv12-ALPN
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 8f 00 05 00 05  01 00 00 00 00 00 0a 00  |................|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -18,11 +18,11 @@
 00000100  bb 29 07 30 ff f6 84 af  c4 cf c2 ed 90 99 5f 58  |.).0.........._X|
 00000110  cb 3b 74                                          |.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 66 02 00 00  62 03 03 95 14 55 52 0b  |....f...b....UR.|
-00000010  e7 c1 15 6b dc 19 3b 17  9e bb 6a b7 61 82 dc 59  |...k..;...j.a..Y|
-00000020  d3 a4 7c e1 c3 83 cc e2  e5 56 e0 20 3c 82 0d 54  |..|......V. <..T|
-00000030  2b 78 fe 50 cb 4e c1 69  d7 6f b3 9f ac 2e 27 c8  |+x.P.N.i.o....'.|
-00000040  c6 7a 70 27 1e 14 67 43  4c f1 7d d7 cc a8 00 00  |.zp'..gCL.}.....|
+00000000  16 03 03 00 66 02 00 00  62 03 03 2d b3 e1 a8 44  |....f...b..-...D|
+00000010  c6 3e 20 b9 50 49 ab b8  48 c3 bf d6 f3 7b 2e 0a  |.> .PI..H....{..|
+00000020  8c 49 ba e5 8e 54 5e 02  59 01 75 20 f0 a0 60 c2  |.I...T^.Y.u ..`.|
+00000030  81 df 62 f9 f8 7d 3c 3c  ee 1e 0c 1d c2 11 58 7f  |..b..}<<......X.|
+00000040  e0 dc b1 6c 17 9e 19 60  ca c2 40 84 cc a8 00 00  |...l...`..@.....|
 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.|
@@ -63,31 +63,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 c3 e3  43 9c 5d 0f 09 61 ae 18  |..... ..C.]..a..|
-000002e0  66 05 b1 7d c1 9f e5 26  9c a7 97 d6 1f 9a 7c ff  |f..}...&......|.|
-000002f0  8c 34 a1 32 a2 35 08 04  00 80 6c 50 a1 80 d9 20  |.4.2.5....lP... |
-00000300  56 08 da d9 5b 77 4d ad  43 66 71 15 ec fe db 02  |V...[wM.Cfq.....|
-00000310  fb 40 d8 8d 67 22 e2 1b  ec 8d b9 4e ba 65 01 8b  |.@..g".....N.e..|
-00000320  70 e0 83 bc 06 1b 14 8f  07 cf a6 08 58 c3 77 94  |p...........X.w.|
-00000330  0f 94 53 62 54 6c 1f 92  22 9d ae f8 5a ad d5 f3  |..SbTl.."...Z...|
-00000340  8a f7 e6 93 8c 0e 48 1b  23 89 d8 bd e9 5c 50 cd  |......H.#....\P.|
-00000350  07 3d 7e 8e b0 d6 65 44  58 62 03 a1 d9 94 72 f0  |.=~...eDXb....r.|
-00000360  25 a9 e0 c1 be ac 32 05  59 f7 7f 6e 13 23 70 5a  |%.....2.Y..n.#pZ|
-00000370  65 ba a2 d7 da 3c a2 9e  6b 13 16 03 03 00 04 0e  |e....<..k.......|
+000002d0  00 a8 03 00 1d 20 7b 47  ec ef 4d 39 ec 65 b9 7c  |..... {G..M9.e.||
+000002e0  08 da b5 41 0d 62 0b 52  29 24 25 3d 39 21 ed d3  |...A.b.R)$%=9!..|
+000002f0  30 37 0c 15 66 49 08 04  00 80 4b 01 8e 80 78 ed  |07..fI....K...x.|
+00000300  d1 44 e5 98 a4 43 9a 73  b7 dc 67 72 83 29 f3 e3  |.D...C.s..gr.)..|
+00000310  5b 72 ee d6 36 12 db bf  ab d6 86 fd a8 54 a5 a0  |[r..6........T..|
+00000320  0e 76 ca ea a7 f5 f2 e1  87 94 a7 c5 d8 69 b7 58  |.v...........i.X|
+00000330  d2 f0 10 08 8c 08 ac bd  aa 60 f5 45 20 15 77 71  |.........`.E .wq|
+00000340  5a bb 2a 8b 0a 4b a3 08  71 88 82 01 3c bc 54 ba  |Z.*..K..q...<.T.|
+00000350  f4 42 7a 08 64 d7 57 5b  dc ea 6a 72 e1 7d ca 96  |.Bz.d.W[..jr.}..|
+00000360  d9 89 eb 60 9e d2 a4 f5  cb d5 45 d1 4d 09 4e 18  |...`......E.M.N.|
+00000370  a2 4f 0f 59 97 a1 5f 7f  65 4f 16 03 03 00 04 0e  |.O.Y.._.eO......|
 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 5e 91 45  7d ab 7c b7 6f 57 a6 d0  |.... ^.E}.|.oW..|
-00000040  17 83 cb 40 1b 76 6b 5e  80 39 03 2f 6d 2f 10 8e  |...@.vk^.9./m/..|
-00000050  74 33 12 54 8d                                    |t3.T.|
+00000030  16 03 03 00 20 b9 f7 58  6f d3 29 b8 41 35 06 b7  |.... ..Xo.).A5..|
+00000040  55 85 c1 f0 63 fe 4f 5f  87 01 cc 67 0b f1 4c b4  |U...c.O_...g..L.|
+00000050  ca 92 bd c0 6d                                    |....m|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 f1 3c 7a 28 eb  |.......... .<z(.|
-00000010  0a b1 bf 42 28 de 07 83  76 c6 2c 94 b7 d5 ef f3  |...B(...v.,.....|
-00000020  0b 9c 0c 2e d3 ab 8a a9  03 d2 c0                 |...........|
+00000000  14 03 03 00 01 01 16 03  03 00 20 68 92 93 84 bd  |.......... h....|
+00000010  0e de 33 1b db ca 54 b8  a0 2f 53 c5 76 de d2 c5  |..3...T../S.v...|
+00000020  7a 54 bb db 0c 08 86 79  d2 6c 58                 |zT.....y.lX|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 dc f6 18  54 22 e0 9c 08 bf db a8  |........T"......|
-00000010  62 2a 64 9e 06 43 0f 22  18 0e 34 15 03 03 00 12  |b*d..C."..4.....|
-00000020  20 2f f4 76 cd dc 82 eb  30 f9 e0 42 6b 29 16 ed  | /.v....0..Bk)..|
-00000030  7c f0                                             ||.|
+00000000  17 03 03 00 16 79 38 07  9b be 83 44 9a 3e 11 1a  |.....y8....D.>..|
+00000010  99 2f f2 4e 33 84 0b c7  8e ed c3 15 03 03 00 12  |./.N3...........|
+00000020  ca bd 7e 59 04 8c e0 52  80 1e 56 1e af c1 5f 61  |..~Y...R..V..._a|
+00000030  6c 6a                                             |lj|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
index e40999f..e1fb8a8 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 08 a4 b1 ad 21  |....Y...U......!|
-00000010  3a 60 7a d3 3b 60 67 48  5d de da ff 3f a8 55 a9  |:`z.;`gH]...?.U.|
-00000020  c4 72 69 32 12 c1 d1 4e  d4 78 e1 20 6e 9f ed 1e  |.ri2...N.x. n...|
-00000030  50 9a 31 e2 ae e2 6a f4  01 cc 94 21 25 73 f3 a5  |P.1...j....!%s..|
-00000040  f6 28 b3 c6 6b c1 b3 2d  fc 0c d3 66 c0 09 00 00  |.(..k..-...f....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 36 60 84 12 26  |....Y...U..6`..&|
+00000010  51 e4 32 33 26 ef c3 31  bf ea ac 27 0f c3 fb cb  |Q.23&..1...'....|
+00000020  05 89 af df 56 a9 3f 14  6e 5e 2c 20 ad 6e 60 2d  |....V.?.n^, .n`-|
+00000030  94 aa e5 73 22 eb 68 92  77 1c 6c cb f4 5a 14 f2  |...s".h.w.l..Z..|
+00000040  29 85 88 aa 2e 56 2a ad  80 e1 f0 b1 c0 09 00 00  |)....V*.........|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -55,18 +55,18 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 ec f3  |*............ ..|
-00000280  2b 3b be 93 68 53 f2 ab  6c 97 5a fa 9b 8c bf eb  |+;..hS..l.Z.....|
-00000290  37 6f af d7 b8 02 f3 8c  0b f9 75 29 11 32 04 03  |7o........u).2..|
-000002a0  00 8b 30 81 88 02 42 01  9d 90 aa b3 19 d2 9d cf  |..0...B.........|
-000002b0  92 c1 64 05 89 db d0 dd  80 f3 a4 7e 09 ec 36 22  |..d........~..6"|
-000002c0  95 79 c4 36 0e 21 80 7d  4b 72 a5 38 a4 b0 a7 5f  |.y.6.!.}Kr.8..._|
-000002d0  fb ae f7 66 23 82 91 c2  f8 95 df 60 ce dc e8 1a  |...f#......`....|
-000002e0  3f 2b 2c fa 5e 58 67 98  78 02 42 00 fa 88 7f ae  |?+,.^Xg.x.B.....|
-000002f0  00 55 2c a1 c2 47 ed c8  11 74 64 e7 c6 30 63 fb  |.U,..G...td..0c.|
-00000300  bb 42 2a 02 9b 80 60 88  e7 3f af 17 a3 7f 1e f6  |.B*...`..?......|
-00000310  31 9c 1f 8c 89 e5 a0 b1  01 2a 4e d8 d2 1e 9f 11  |1........*N.....|
-00000320  f5 e3 35 38 3e b0 da 30  f1 fb ed e5 d1 16 03 03  |..58>..0........|
+00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 87 2c  |*............ .,|
+00000280  f2 fd 8e b9 3d 5f 1c c8  bb 04 f5 1e 01 a8 ba d8  |....=_..........|
+00000290  b6 8e 61 78 15 9e 3b a7  da 96 8e 77 d7 70 04 03  |..ax..;....w.p..|
+000002a0  00 8b 30 81 88 02 42 01  dc e2 26 f9 18 39 da 7d  |..0...B...&..9.}|
+000002b0  bd a1 30 c6 6f dd cd aa  a0 4f 71 cf 42 76 61 ba  |..0.o....Oq.Bva.|
+000002c0  e7 9f 09 b5 05 f2 76 c7  db 2a 93 83 3b 0b 3a cf  |......v..*..;.:.|
+000002d0  60 96 24 c8 af de 2c db  5a 29 1c 62 67 28 e9 d7  |`.$...,.Z).bg(..|
+000002e0  57 5f 54 18 cc bf ee d1  d9 02 42 01 04 cf 67 0b  |W_T.......B...g.|
+000002f0  62 2c c2 17 a3 f4 f1 32  0f c5 b9 ae 3b 52 36 2b  |b,.....2....;R6+|
+00000300  f0 c0 60 49 08 e0 bf f5  7c 09 13 e4 b8 ba 08 c7  |..`I....|.......|
+00000310  ea 74 a0 f5 88 45 e4 35  f1 c5 4e df fe 45 bc ca  |.t...E.5..N..E..|
+00000320  9c 5f c8 84 66 13 8f b3  c9 7e b2 ba d6 16 03 03  |._..f....~......|
 00000330  00 3a 0d 00 00 36 03 01  02 40 00 2e 04 03 05 03  |.:...6...@......|
 00000340  06 03 08 07 08 08 08 09  08 0a 08 0b 08 04 08 05  |................|
 00000350  08 06 04 01 05 01 06 01  03 03 02 03 03 01 02 01  |................|
@@ -108,32 +108,32 @@
 00000200  e4 fa cc b1 8a ce e2 23  a0 87 f0 e1 67 51 eb 16  |.......#....gQ..|
 00000210  03 03 00 25 10 00 00 21  20 2f e5 7d a3 47 cd 62  |...%...! /.}.G.b|
 00000220  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
-00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 03 00 93 0f 00  |...._X.;t.......|
-00000240  00 8f 04 03 00 8b 30 81  88 02 42 01 e6 0a ff de  |......0...B.....|
-00000250  af a6 d2 7a 5f 4e f8 eb  c8 19 74 53 5c e8 bc 2d  |...z_N....tS\..-|
-00000260  72 24 11 d2 11 ec ec cd  a1 9c 3d 10 a2 de f8 8b  |r$........=.....|
-00000270  22 98 d3 33 c2 13 3b 93  89 ae ca a6 a8 94 70 fe  |"..3..;.......p.|
-00000280  76 2f 04 bc ac fb 66 79  3b 76 7f 6d 96 02 42 01  |v/....fy;v.m..B.|
-00000290  df f6 30 14 7c 7e a1 0b  f6 b8 8b d7 75 b8 bd 0e  |..0.|~......u...|
-000002a0  63 8a bd 8b ec 75 70 db  d9 37 d7 53 f3 8b a2 ae  |c....up..7.S....|
-000002b0  60 96 69 74 eb bb 3d a6  9a 7d 46 51 73 ff 78 cf  |`.it..=..}FQs.x.|
-000002c0  7f 49 d9 27 5e 9f f9 d2  11 cc 0e e4 dc 04 fe d5  |.I.'^...........|
-000002d0  d2 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 7a db 34 e9  |............z.4.|
-000002f0  98 f8 c1 f0 38 c3 33 22  5c c3 45 b0 a3 10 3c 77  |....8.3"\.E...<w|
-00000300  7f d2 06 c5 f8 13 b6 f4  ee 7e 53 0b 07 0b c3 c9  |.........~S.....|
-00000310  89 9a a9 bb 3b af 79 09  59 ce 10 41              |....;.y.Y..A|
+00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 03 00 92 0f 00  |...._X.;t.......|
+00000240  00 8e 04 03 00 8a 30 81  87 02 42 01 8f ff aa 8c  |......0...B.....|
+00000250  bd 0c 94 39 34 e5 39 7b  d2 12 26 8e 94 4a fd 68  |...94.9{..&..J.h|
+00000260  f2 f5 5b 30 69 e1 42 3a  74 cd 9a 37 75 5c d2 a6  |..[0i.B:t..7u\..|
+00000270  c9 7b b1 83 c1 d9 c5 55  1a af 3d 19 64 02 43 c0  |.{.....U..=.d.C.|
+00000280  0a 1c 0e ff f4 42 85 fb  d1 aa a2 52 1a 02 41 2f  |.....B.....R..A/|
+00000290  c6 23 d7 37 f1 36 75 0c  0f b4 49 14 c4 b4 d9 28  |.#.7.6u...I....(|
+000002a0  c1 00 2d e4 d6 93 fd a0  f5 59 4e 45 0c a4 28 d4  |..-......YNE..(.|
+000002b0  dc aa 7b 0b 28 29 12 94  f6 db 8c 23 af 81 7e ab  |..{.().....#..~.|
+000002c0  fd 12 ba 11 27 b2 10 87  89 61 9f 5d 6d 18 79 c5  |....'....a.]m.y.|
+000002d0  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
+000002e0  00 00 00 00 00 00 00 00  00 00 00 2d 3e 6e 02 fb  |...........->n..|
+000002f0  50 cc 37 62 77 17 08 ef  71 e6 06 23 82 ba 97 b7  |P.7bw...q..#....|
+00000300  0f 38 f9 5e 05 63 4c c9  04 6e bd e4 78 76 32 3b  |.8.^.cL..n..xv2;|
+00000310  3a a7 9b de 30 ca ed fb  17 dc 40                 |:...0.....@|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 18 c0 f3 96 7b  |..........@....{|
-00000010  45 91 6d 5b 1c 67 4f 37  74 b7 db 72 45 57 09 25  |E.m[.gO7t..rEW.%|
-00000020  4a 14 68 4d 78 6c c7 15  6a b1 57 e6 ff 53 c4 58  |J.hMxl..j.W..S.X|
-00000030  41 c5 6b 08 3c 5a 8c b9  04 d0 27 62 ee a6 e3 36  |A.k.<Z....'b...6|
-00000040  96 87 db 09 e3 88 d9 a2  0f 7d 9a                 |.........}.|
+00000000  14 03 03 00 01 01 16 03  03 00 40 19 62 a8 82 26  |..........@.b..&|
+00000010  0f 0c 84 b4 31 6a 5d 12  65 dc b9 bc de 5c cb 77  |....1j].e....\.w|
+00000020  5d 04 7e a8 10 1a a5 05  e5 ca 04 68 a2 81 ef f5  |].~........h....|
+00000030  ae 4e bd f1 f3 ba 3f 6a  81 ae 71 9a 2f 31 e2 79  |.N....?j..q./1.y|
+00000040  f1 4d 6c 0e a4 be 4b f7  80 6f 97                 |.Ml...K..o.|
 >>> 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 a6 c2 ef  07 bb 38 4a e4 8f 0c 12  |..........8J....|
-00000020  19 1a 96 62 22 57 57 a2  b5 b3 06 70 95 28 a7 f7  |...b"WW....p.(..|
-00000030  0d 42 69 37 7f 15 03 03  00 30 00 00 00 00 00 00  |.Bi7.....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 04 ed 3e 68 40 eb  |............>h@.|
-00000050  a0 7e 57 da 27 e7 f5 e8  6c e5 6d 58 c8 a5 18 47  |.~W.'...l.mX...G|
-00000060  92 5a 43 90 de 07 9e 9a  3b cc                    |.ZC.....;.|
+00000010  00 00 00 00 00 e9 f4 51  fe c1 02 35 de 6e 72 c3  |.......Q...5.nr.|
+00000020  58 f3 01 4a f0 9d f2 34  df fc 0e 93 ef 46 2e 45  |X..J...4.....F.E|
+00000030  5e 60 43 52 33 15 03 03  00 30 00 00 00 00 00 00  |^`CR3....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 ac 82 d6 47 42 40  |.............GB@|
+00000050  d6 6c 6d e3 b6 c6 4a b7  83 ce 6f 3f 33 ad e7 eb  |.lm...J...o?3...|
+00000060  bf 59 82 50 8a 18 e3 13  46 6c                    |.Y.P....Fl|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
index f5fae45..7ae186d 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 be ba ac 2a 81  |....Y...U.....*.|
-00000010  33 b1 6e 4d 8b 9b 29 f9  16 86 bc cd b2 03 50 72  |3.nM..).......Pr|
-00000020  91 9a 93 f9 e1 d6 27 55  8b b8 6c 20 84 c2 21 9e  |......'U..l ..!.|
-00000030  60 aa b3 f0 ec 2f 66 0d  59 31 02 08 9e 68 68 c0  |`..../f.Y1...hh.|
-00000040  58 9a 8e 6c 25 ce 4d e3  3f 9d dc 91 c0 2f 00 00  |X..l%.M.?..../..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 2a 52 95 57 8c  |....Y...U..*R.W.|
+00000010  55 3f d7 82 f0 3f af 57  a1 82 86 00 3a 6b c0 07  |U?...?.W....:k..|
+00000020  4d c3 0e 80 cc 37 2d 51  f4 d3 e2 20 4a f6 c9 8a  |M....7-Q... J...|
+00000030  d2 98 4a ff 22 66 11 da  6f 9a a0 17 b9 96 b0 86  |..J."f..o.......|
+00000040  29 e0 39 86 0a 00 42 78  30 60 61 99 c0 2f 00 00  |).9...Bx0`a../..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,17 +60,17 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |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 82 89 54 65 64 97 8d  |........ ..Ted..|
-000002d0  e8 63 a2 5b 4f 16 56 7c  cf 8b 0a 75 46 52 7e b6  |.c.[O.V|...uFR~.|
-000002e0  99 2a e9 52 1f 11 46 85  36 08 04 00 80 cd a5 84  |.*.R..F.6.......|
-000002f0  ff 9a 79 b5 04 85 88 fb  1e 1c d6 6b 78 e8 4d a5  |..y........kx.M.|
-00000300  10 38 25 8e 8d de 71 51  b5 fd a6 2a f8 8b 5c 6d  |.8%...qQ...*..\m|
-00000310  1e 88 f7 d8 12 24 ff f7  7e dd 05 1c bf 71 7d 4f  |.....$..~....q}O|
-00000320  26 2f 2e 27 d8 e1 a8 8b  d2 42 2b a6 d9 4e e6 60  |&/.'.....B+..N.`|
-00000330  48 57 38 5d 3b f3 94 74  2c 8f ba e0 84 54 1c c0  |HW8];..t,....T..|
-00000340  10 51 a0 31 1a d0 ec 72  01 f1 d3 65 73 c7 40 25  |.Q.1...r...es.@%|
-00000350  af cd 10 18 29 2c 1a 52  e0 c9 a6 de 85 8c 96 e6  |....),.R........|
-00000360  7d 85 0a 64 86 59 39 25  8f 8c 36 4c 37 16 03 03  |}..d.Y9%..6L7...|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 fa 3a 8f b7 50 10 38  |........ .:..P.8|
+000002d0  04 9d fb c4 e4 76 6d 93  86 b2 8a d7 5b 8f 8d 45  |.....vm.....[..E|
+000002e0  41 b7 ba 54 bc cc 7b 07  3c 08 04 00 80 a1 14 65  |A..T..{.<......e|
+000002f0  f6 48 29 ba 08 86 52 65  dd 08 ef b8 b8 77 ef fd  |.H)...Re.....w..|
+00000300  8a ca dc 37 f8 69 fa 04  69 73 84 07 b2 45 f0 a2  |...7.i..is...E..|
+00000310  8c 69 f7 7c 4c 5c 95 c5  66 80 ad 93 04 67 4b 3d  |.i.|L\..f....gK=|
+00000320  f8 53 a9 33 b3 c0 40 17  62 34 f0 f3 1e d2 23 93  |.S.3..@.b4....#.|
+00000330  29 52 bc f4 f0 72 58 b9  76 9c 7b 54 b0 d5 d1 ab  |)R...rX.v.{T....|
+00000340  b3 1b ae f7 f3 46 6a 07  7f f4 91 ee 46 d6 85 43  |.....Fj.....F..C|
+00000350  ea c6 f9 f5 47 89 85 39  72 35 af b4 03 e9 a2 ea  |....G..9r5......|
+00000360  a8 19 09 ea b3 d2 c2 38  59 65 d1 2c 18 16 03 03  |.......8Ye.,....|
 00000370  00 3a 0d 00 00 36 03 01  02 40 00 2e 04 03 05 03  |.:...6...@......|
 00000380  06 03 08 07 08 08 08 09  08 0a 08 0b 08 04 08 05  |................|
 00000390  08 06 04 01 05 01 06 01  03 03 02 03 03 01 02 01  |................|
@@ -112,28 +112,28 @@
 00000200  e4 fa cc b1 8a ce e2 23  a0 87 f0 e1 67 51 eb 16  |.......#....gQ..|
 00000210  03 03 00 25 10 00 00 21  20 2f e5 7d a3 47 cd 62  |...%...! /.}.G.b|
 00000220  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
-00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 03 00 92 0f 00  |...._X.;t.......|
-00000240  00 8e 04 03 00 8a 30 81  87 02 41 72 16 75 7d 08  |......0...Ar.u}.|
-00000250  42 7b 33 e7 59 51 ef 3c  54 e7 81 e4 10 31 ab 5d  |B{3.YQ.<T....1.]|
-00000260  df 17 52 e0 a9 9f b5 43  e0 33 0e 52 b2 19 a2 a8  |..R....C.3.R....|
-00000270  0b b9 8b e3 0b 51 1d 65  c9 7b 7c 67 66 d4 98 77  |.....Q.e.{|gf..w|
-00000280  34 06 07 fc 8f 84 85 36  c3 fd f9 12 02 42 01 ad  |4......6.....B..|
-00000290  a7 25 ed c2 e8 2d c0 a3  12 0b 79 b2 32 e2 c3 70  |.%...-....y.2..p|
-000002a0  2b 5d 99 1b 24 45 60 68  8b b3 28 5c 96 1a 26 89  |+]..$E`h..(\..&.|
-000002b0  24 53 20 f5 fc 6f 98 b1  64 0b ba f5 ad ea 1e 33  |$S ..o..d......3|
-000002c0  4f 64 fd 43 37 80 24 f0  7d e3 7d 63 76 7e 60 e3  |Od.C7.$.}.}cv~`.|
-000002d0  14 03 03 00 01 01 16 03  03 00 28 00 00 00 00 00  |..........(.....|
-000002e0  00 00 00 27 0b ff 3a 92  88 b6 86 86 0e c2 f5 94  |...'..:.........|
-000002f0  d5 29 a4 6d 95 12 e1 d8  ec d9 a4 3c 1c db 52 76  |.).m.......<..Rv|
-00000300  2a 72 29                                          |*r)|
+00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 03 00 91 0f 00  |...._X.;t.......|
+00000240  00 8d 04 03 00 89 30 81  86 02 41 63 34 72 b4 70  |......0...Ac4r.p|
+00000250  45 46 9c 3c 06 2c f5 ab  d4 dd a7 91 69 9c 65 0f  |EF.<.,......i.e.|
+00000260  4b d9 2d 90 3d d1 f2 4d  2a 6a 43 4f a7 fd b5 22  |K.-.=..M*jCO..."|
+00000270  83 61 e2 14 33 8c bc 8a  81 52 a1 f4 69 a7 12 c9  |.a..3....R..i...|
+00000280  c3 28 69 85 6d c1 b0 5d  d3 5e ac 4e 02 41 35 cd  |.(i.m..].^.N.A5.|
+00000290  3b c3 f6 ea 9e df 2a a1  ea 80 55 40 d2 13 d3 ff  |;.....*...U@....|
+000002a0  b2 59 bb a0 c7 10 67 6e  9b dc 6c 3c 97 08 07 e0  |.Y....gn..l<....|
+000002b0  db da 79 6b 0e 6c a0 23  13 b1 02 32 ab ee 62 69  |..yk.l.#...2..bi|
+000002c0  f9 d5 7f 24 2e 26 94 36  a4 36 53 63 dd 90 20 14  |...$.&.6.6Sc.. .|
+000002d0  03 03 00 01 01 16 03 03  00 28 00 00 00 00 00 00  |.........(......|
+000002e0  00 00 a7 30 0e b0 f7 ba  51 35 c9 4c c2 24 90 5e  |...0....Q5.L.$.^|
+000002f0  b2 59 57 5d 96 9d ad d1  1e 7d b0 35 09 9c c5 49  |.YW].....}.5...I|
+00000300  bd 82                                             |..|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 b8 e9 dd 30 75  |..........(...0u|
-00000010  40 7d 71 76 db 9a 95 92  81 02 3a 9e 36 d5 15 ca  |@}qv......:.6...|
-00000020  5d 63 a1 0f 8c 53 c9 1c  37 56 b2 0d 54 15 a2 dc  |]c...S..7V..T...|
-00000030  03 d6 2e                                          |...|
+00000000  14 03 03 00 01 01 16 03  03 00 28 09 ff 53 e8 0f  |..........(..S..|
+00000010  ad 86 30 ca 96 54 da 72  45 13 7a cd 51 f6 b3 a5  |..0..T.rE.z.Q...|
+00000020  27 4c 7c 26 81 6d 76 6f  19 8e f3 13 77 49 59 73  |'L|&.mvo....wIYs|
+00000030  4e 98 3e                                          |N.>|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 01 85 96  |................|
-00000010  67 b2 4b d3 e3 27 80 9f  2d a8 f4 bf 47 91 58 6e  |g.K..'..-...G.Xn|
-00000020  47 d8 98 15 03 03 00 1a  00 00 00 00 00 00 00 02  |G...............|
-00000030  36 54 82 d1 a2 0f 2a c3  53 f6 09 d0 5c 78 46 97  |6T....*.S...\xF.|
-00000040  20 41                                             | A|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 99 7b 4c  |..............{L|
+00000010  1d 0a b1 89 0d ac fa a7  39 eb 9a ff 8f 06 60 d1  |........9.....`.|
+00000020  88 e8 ef 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
+00000030  99 42 7f c8 35 79 f3 a0  10 5c 05 25 c1 ac ab aa  |.B..5y...\.%....|
+00000040  d5 9e                                             |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-Ed25519 b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-Ed25519
index e415b12..9ecd8e3 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-Ed25519
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-Ed25519
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 1c 50 4e 50 35  |....Y...U...PNP5|
-00000010  51 02 a9 62 ba 82 a5 d3  fa 40 4e f3 28 9b 50 a6  |Q..b.....@N.(.P.|
-00000020  f0 75 30 e9 fe be a3 42  1d 1c f5 20 9e 88 46 57  |.u0....B... ..FW|
-00000030  c5 b4 a3 a3 fc 88 bb e0  1c 5e ea 77 a0 75 93 5a  |.........^.w.u.Z|
-00000040  6d 4c c7 57 6f 3a 05 af  3f 3f ac 75 cc a8 00 00  |mL.Wo:..??.u....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 5c 37 b1 d2 6c  |....Y...U..\7..l|
+00000010  bc dd 26 8c 4e f7 04 80  09 3c fd 76 23 d4 52 16  |..&.N....<.v#.R.|
+00000020  df 0e 79 ab f4 cf 8c f3  61 31 c6 20 7d 7a 1d 8f  |..y.....a1. }z..|
+00000030  09 3e 2b 25 04 7f 0f 0a  a7 0c 03 fd 9c 09 f3 5d  |.>+%...........]|
+00000040  96 75 f8 da 5b 6b 1b fb  ca d7 ec 7a cc a8 00 00  |.u..[k.....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..............|
@@ -60,17 +60,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 82 c1 f5 7b 68 eb 7a  |........ ...{h.z|
-000002d0  cf 02 c9 95 28 4b 31 76  a9 84 93 a9 1f 5b f4 2a  |....(K1v.....[.*|
-000002e0  5c a5 31 94 5f f0 e0 ed  2e 08 04 00 80 7a 99 38  |\.1._........z.8|
-000002f0  7f d0 25 4b bf a9 e0 2b  db ce 17 9d 30 4b 82 9e  |..%K...+....0K..|
-00000300  b1 50 84 fc dd b0 a8 5c  39 20 00 40 5b 92 dc 7c  |.P.....\9 .@[..||
-00000310  25 3b 53 7d 5a 4b ad 05  6f 3a 4f e5 84 b6 3a e2  |%;S}ZK..o:O...:.|
-00000320  fb bf cb c8 94 39 a5 28  ad c8 5f 94 53 90 0e 61  |.....9.(.._.S..a|
-00000330  af f2 92 2c 3b ec 3c bf  1d d3 8b a5 65 58 5b bf  |...,;.<.....eX[.|
-00000340  5a 21 3d cd 40 7c 9e 1d  e9 62 3c 67 71 7c ec b4  |Z!=.@|...b<gq|..|
-00000350  25 d0 4a 6a 85 1d c4 e8  44 d6 25 1a 2c 29 ae d7  |%.Jj....D.%.,)..|
-00000360  d7 24 fb 5a 62 f7 50 52  12 1b c7 3e b0 16 03 03  |.$.Zb.PR...>....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 aa c7 43 e7 1e 3b 2b  |........ ..C..;+|
+000002d0  28 c2 68 aa 83 cc 85 63  68 c4 b8 4d fb 18 fa b9  |(.h....ch..M....|
+000002e0  3e 9a f2 7c 04 33 7f 48  6b 08 04 00 80 28 28 c7  |>..|.3.Hk....((.|
+000002f0  84 79 65 11 07 43 7a ce  f1 d6 cb 0e fe 6a 24 2c  |.ye..Cz......j$,|
+00000300  f3 f0 e5 9c 80 a6 c7 41  c7 51 f2 84 be 6e 58 df  |.......A.Q...nX.|
+00000310  f2 d2 d4 d9 62 08 c8 35  75 b9 8e 49 c2 98 b0 9d  |....b..5u..I....|
+00000320  32 aa db bf 03 c1 61 83  f7 20 d7 ec 07 27 5e 45  |2.....a.. ...'^E|
+00000330  dc d6 92 4c a1 4f 4e 7c  53 c5 ca 42 48 40 0f 83  |...L.ON|S..BH@..|
+00000340  fc 9d 60 a1 7c 43 d1 f5  f8 3f fe 50 3f d0 03 bc  |..`.|C...?.P?...|
+00000350  3e 8b ac 69 8f ae b6 9a  c8 d4 98 84 30 f1 79 9b  |>..i........0.y.|
+00000360  af 5d 4e 41 2a 7c 46 22  df 46 42 74 f6 16 03 03  |.]NA*|F".FBt....|
 00000370  00 3a 0d 00 00 36 03 01  02 40 00 2e 04 03 05 03  |.:...6...@......|
 00000380  06 03 08 07 08 08 08 09  08 0a 08 0b 08 04 08 05  |................|
 00000390  08 06 04 01 05 01 06 01  03 03 02 03 03 01 02 01  |................|
@@ -100,20 +100,20 @@
 00000140  08 16 03 03 00 25 10 00  00 21 20 2f e5 7d a3 47  |.....%...! /.}.G|
 00000150  cd 62 43 15 28 da ac 5f  bb 29 07 30 ff f6 84 af  |.bC.(.._.).0....|
 00000160  c4 cf c2 ed 90 99 5f 58  cb 3b 74 16 03 03 00 48  |......_X.;t....H|
-00000170  0f 00 00 44 08 07 00 40  af a6 03 14 53 7a 4f 75  |...D...@....SzOu|
-00000180  9d cc 2f e3 e7 2a 51 16  16 b0 1d 28 e0 2a 59 f0  |../..*Q....(.*Y.|
-00000190  3c df cc 18 dd b8 ef d1  9f 9d 03 8e 59 00 27 d1  |<...........Y.'.|
-000001a0  39 2f 3b 33 53 1f b2 f0  22 1d 06 f6 50 0b a7 98  |9/;3S..."...P...|
-000001b0  cc fa 78 53 bf 8e ff 0b  14 03 03 00 01 01 16 03  |..xS............|
-000001c0  03 00 20 e5 81 3e a3 34  29 52 14 19 49 cf 04 82  |.. ..>.4)R..I...|
-000001d0  8b e7 83 aa 6c db 96 ec  97 29 b4 a3 db 87 21 2e  |....l....)....!.|
-000001e0  a5 c0 66                                          |..f|
+00000170  0f 00 00 44 08 07 00 40  07 e0 a5 14 ca cf 31 d7  |...D...@......1.|
+00000180  99 96 c7 c7 d8 d8 a7 f7  82 e7 c6 c0 12 5d 91 5a  |.............].Z|
+00000190  bc eb 4a c0 59 c6 5b 7b  03 df 2a ff 48 ca 55 d8  |..J.Y.[{..*.H.U.|
+000001a0  3e 10 c1 94 2c 03 b2 e7  16 83 4d e5 5a 3d 8a 48  |>...,.....M.Z=.H|
+000001b0  2f e5 c4 59 de 6f 47 05  14 03 03 00 01 01 16 03  |/..Y.oG.........|
+000001c0  03 00 20 ae 35 81 df 88  0e a3 2e 67 3f 33 02 3d  |.. .5......g?3.=|
+000001d0  b8 7e 47 db cb be 05 c7  ba 43 dc 5b 52 3b 4b ca  |.~G......C.[R;K.|
+000001e0  c0 dc 78                                          |..x|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 84 67 d4 ce cf  |.......... .g...|
-00000010  fb 54 2c dc f7 53 31 8a  aa 03 60 37 3d 33 f2 79  |.T,..S1...`7=3.y|
-00000020  d0 65 2e 3f 0e f9 1a d3  6e 6d 8e                 |.e.?....nm.|
+00000000  14 03 03 00 01 01 16 03  03 00 20 63 23 49 7c 83  |.......... c#I|.|
+00000010  1a 8b cd 48 02 e7 86 4d  ab 8b 3c 4f 40 27 a6 48  |...H...M..<O@'.H|
+00000020  95 d5 80 8a 7a e0 56 0b  e6 34 70                 |....z.V..4p|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 e5 b7 4c  92 05 fc 81 cf 11 ef cd  |.......L........|
-00000010  0f 4b df ef a1 54 ae 26  4e ec aa 15 03 03 00 12  |.K...T.&N.......|
-00000020  0a f3 5b 06 63 84 a6 eb  d4 73 94 db fe d8 e0 ae  |..[.c....s......|
-00000030  d6 fc                                             |..|
+00000000  17 03 03 00 16 aa b4 5b  75 04 96 c5 4a e3 2a fb  |.......[u...J.*.|
+00000010  be 29 32 9e c5 e4 15 bd  38 df 69 15 03 03 00 12  |.)2.....8.i.....|
+00000020  50 4d b6 c0 95 e6 5a db  f2 b7 ea 02 cb 3e 01 ea  |PM....Z......>..|
+00000030  35 0d                                             |5.|
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 3975b07..35ec347 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
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 d4 20 b3 4c 6a  |....Y...U... .Lj|
-00000010  69 44 3f f7 ab 15 35 85  ca 71 02 b0 70 18 8e d6  |iD?...5..q..p...|
-00000020  61 d5 34 08 42 de cf a1  57 32 96 20 8c b4 72 dd  |a.4.B...W2. ..r.|
-00000030  63 93 e6 13 9d 4a ec 75  d9 a1 a6 9e 5e 02 f5 63  |c....J.u....^..c|
-00000040  29 1a 78 9f 94 9f 6c 58  b5 91 ae 63 c0 30 00 00  |).x...lX...c.0..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 16 f7 21 0a 97  |....Y...U....!..|
+00000010  89 11 ec c3 c4 05 41 79  72 60 40 6d ec 78 90 26  |......Ayr`@m.x.&|
+00000020  0c a4 f8 5d d5 27 e9 70  bb 40 21 20 b0 bb 98 5d  |...].'.p.@! ...]|
+00000030  a2 27 08 1e 4a fe f9 e1  cf a5 79 d3 eb c6 40 f7  |.'..J.....y...@.|
+00000040  ee 4f 0b fa a1 bb 09 62  07 24 30 b7 c0 30 00 00  |.O.....b.$0..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..............|
@@ -60,17 +60,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 a2 bd 95 3e 0c 9f ad  |........ ...>...|
-000002d0  11 59 e0 6a c1 21 0c 6c  86 cc f1 ce bd a0 30 5d  |.Y.j.!.l......0]|
-000002e0  53 1e 75 f9 55 af 49 7b  31 08 04 00 80 d4 8b 11  |S.u.U.I{1.......|
-000002f0  ca 22 14 79 a3 e8 b6 c7  d0 d6 1b 17 42 93 47 30  |.".y........B.G0|
-00000300  ab 50 0e c9 0c 92 88 96  b4 63 4e 4e ac 7f dd c8  |.P.......cNN....|
-00000310  8f 85 07 5b 95 c5 0a c0  4e 6d 4f 51 ba d8 d7 db  |...[....NmOQ....|
-00000320  14 70 80 4f 68 d9 b4 39  e7 48 27 21 76 4c 79 a4  |.p.Oh..9.H'!vLy.|
-00000330  60 91 d7 2f 75 69 04 1a  da 71 ff b8 4d 78 d8 e7  |`../ui...q..Mx..|
-00000340  ca f2 f2 1e 71 21 b3 a0  44 a7 6c 99 16 a1 c9 f8  |....q!..D.l.....|
-00000350  f0 de e8 99 12 7b 3d a2  e3 15 fa 63 62 e9 1b 72  |.....{=....cb..r|
-00000360  c8 bb 27 38 4a 48 66 1d  dd fb ef 6f d1 16 03 03  |..'8JHf....o....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 39 1f 7e 66 c8 20 24  |........ 9.~f. $|
+000002d0  cf 8e 51 f6 bf 2a 01 a9  3b 51 19 f1 9d 32 b6 fa  |..Q..*..;Q...2..|
+000002e0  05 3b 90 c9 a3 8b 49 92  2a 08 04 00 80 da 65 ad  |.;....I.*.....e.|
+000002f0  fa f9 d5 f6 d7 13 34 d2  ab ac ea 57 37 69 c6 b1  |......4....W7i..|
+00000300  91 ee 89 b7 04 6b 17 fb  80 23 df df ef a1 62 9b  |.....k...#....b.|
+00000310  e4 0a 4e ca b0 35 b2 d3  2a cf 4f c1 e3 d9 37 78  |..N..5..*.O...7x|
+00000320  aa c8 59 f8 25 c7 43 51  19 6c c7 50 90 a4 2c 92  |..Y.%.CQ.l.P..,.|
+00000330  01 0e 8d ff f0 88 4b af  1d 03 ee 51 8b 18 e4 ee  |......K....Q....|
+00000340  35 48 16 e7 4c 26 1d d8  af 91 b1 75 38 b5 65 42  |5H..L&.....u8.eB|
+00000350  8e 60 c7 f9 25 a7 85 35  72 41 6f f6 c4 61 1d c0  |.`..%..5rAo..a..|
+00000360  c8 cf da ae 31 5e 2e d6  9c ca f1 d6 31 16 03 03  |....1^......1...|
 00000370  00 3a 0d 00 00 36 03 01  02 40 00 2e 04 03 05 03  |.:...6...@......|
 00000380  06 03 08 07 08 08 08 09  08 0a 08 0b 08 04 08 05  |................|
 00000390  08 06 04 01 05 01 06 01  03 03 02 03 03 01 02 01  |................|
@@ -112,26 +112,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 08 04 00  80 2e bf 05 22 82 a7 d6  |............"...|
-00000240  e9 08 ff 9b 10 d3 4a 6c  c4 73 5c 78 88 05 0c 15  |......Jl.s\x....|
-00000250  b7 8c 78 49 64 2d 58 67  ef 8f db c0 67 fa 32 6e  |..xId-Xg....g.2n|
-00000260  65 45 90 a0 69 5c fb ba  e0 16 1c d4 81 1d 24 89  |eE..i\........$.|
-00000270  35 27 14 15 19 0b 86 ee  6a f2 b4 a5 27 61 5f 1f  |5'......j...'a_.|
-00000280  cc 47 7c 01 ed a9 ff ed  61 45 3f 53 1c 82 c8 cd  |.G|.....aE?S....|
-00000290  48 e4 89 82 12 d7 d2 ff  fa 32 b3 e6 9d ce 75 75  |H........2....uu|
-000002a0  d1 cd b2 a8 56 a6 a6 63  da 8d ed 27 13 01 9a 56  |....V..c...'...V|
-000002b0  a2 26 b4 6c af 27 f6 4f  1b 14 03 03 00 01 01 16  |.&.l.'.O........|
-000002c0  03 03 00 28 00 00 00 00  00 00 00 00 f0 e8 32 33  |...(..........23|
-000002d0  50 df 73 17 3c 58 f2 c9  30 2e 5d e9 00 4f 4b 33  |P.s.<X..0.]..OK3|
-000002e0  22 12 f7 f0 62 d0 62 3e  ed 36 b8 58              |"...b.b>.6.X|
+00000230  88 0f 00 00 84 08 04 00  80 56 1c 58 51 d8 51 bc  |.........V.XQ.Q.|
+00000240  8e 4b b8 24 64 85 81 d2  26 9b 38 bf 13 19 e7 0a  |.K.$d...&.8.....|
+00000250  f7 94 e8 b5 94 bf 6f ae  f2 07 1a 46 24 38 7b 8b  |......o....F$8{.|
+00000260  2f a6 da 91 1a 5f 7d 3f  cf c4 1b 14 9c 44 8e 6a  |/...._}?.....D.j|
+00000270  6b c8 c4 60 c6 15 e6 f2  c0 45 e7 46 c4 32 06 b1  |k..`.....E.F.2..|
+00000280  46 5e 25 1d ba f7 d8 81  b0 6b 50 40 81 b1 93 89  |F^%......kP@....|
+00000290  cb 90 ae 10 b1 db 08 99  e6 0e 8f 17 0f 4d a7 a7  |.............M..|
+000002a0  f5 42 8a be ca d6 75 c4  32 44 22 ab df cf 22 f7  |.B....u.2D"...".|
+000002b0  58 d9 9f 52 c2 04 c0 81  59 14 03 03 00 01 01 16  |X..R....Y.......|
+000002c0  03 03 00 28 00 00 00 00  00 00 00 00 eb 5a 97 41  |...(.........Z.A|
+000002d0  1d da 2b 81 da 7a b7 9a  f8 5e fe 50 75 e5 a4 6a  |..+..z...^.Pu..j|
+000002e0  21 90 b7 3d 4e bc 44 cf  86 8f cd c3              |!..=N.D.....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 14 ce b1 86 0e  |..........(.....|
-00000010  9f ce 73 25 44 b7 3e a9  25 db a8 93 d9 39 33 75  |..s%D.>.%....93u|
-00000020  2f a9 7f 97 6a 76 28 fe  e2 84 5f 1e 84 66 b4 c8  |/...jv(..._..f..|
-00000030  45 e7 64                                          |E.d|
+00000000  14 03 03 00 01 01 16 03  03 00 28 93 a5 d4 a8 16  |..........(.....|
+00000010  4e a2 b2 c3 b9 ce dd 0e  57 49 7c eb 92 e4 e7 e3  |N.......WI|.....|
+00000020  a8 55 3a 56 54 53 92 b8  ce 15 e3 c3 c2 da 52 01  |.U:VTS........R.|
+00000030  6f 35 fd                                          |o5.|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 3b 17 73  |.............;.s|
-00000010  78 d6 3a b4 6d 3a 61 52  f6 a5 8c dd 18 3e ff 04  |x.:.m:aR.....>..|
-00000020  d9 3f 22 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.?".............|
-00000030  32 8d 5d 07 14 a9 d2 1c  dd 1e 2f 3d 89 a9 8f 1d  |2.]......./=....|
-00000040  08 0f                                             |..|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 5b 20 4f  |.............[ O|
+00000010  e9 3f 09 28 6e 88 5d 1d  57 90 2c 35 74 37 d1 df  |.?.(n.].W.,5t7..|
+00000020  aa 39 9b 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.9..............|
+00000030  bb e3 77 62 e5 c9 78 f4  a5 09 93 b0 20 9a 1b a4  |..wb..x..... ...|
+00000040  48 44                                             |HD|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
index 2d608a7..110f689 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 3c ba b1 d8 8d  |....Y...U..<....|
-00000010  f5 52 f4 a4 70 fc 12 54  20 85 eb 23 bc b8 0b e0  |.R..p..T ..#....|
-00000020  80 b6 ab 9b c5 34 84 57  bc ae 95 20 e3 51 8d 40  |.....4.W... .Q.@|
-00000030  93 cc 9f e4 fd 77 82 c8  12 54 6a 23 08 db ff e5  |.....w...Tj#....|
-00000040  87 8d 72 41 60 51 6a 11  5f 0a 9a d2 c0 09 00 00  |..rA`Qj._.......|
+00000000  16 03 03 00 59 02 00 00  55 03 03 68 dc 2e 5e 8e  |....Y...U..h..^.|
+00000010  80 38 0e 65 a3 b0 f6 a0  c0 8f 1e 62 ef 1d 5a 54  |.8.e.......b..ZT|
+00000020  82 dc 9c 68 77 88 57 dd  f3 9d c2 20 4e 56 dd 44  |...hw.W.... NV.D|
+00000030  a0 46 67 4c 09 2b d5 e6  fe 15 fb b3 8e 19 ef a3  |.FgL.+..........|
+00000040  8e 5c a9 70 00 cf 96 d7  3b 8b c9 64 c0 09 00 00  |.\.p....;..d....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -55,23 +55,23 @@
 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 86 f3  |*............ ..|
-00000280  1e c5 fb 1f 91 44 0e e5  e4 3e 0a cd 75 a2 fb 4c  |.....D...>..u..L|
-00000290  a2 b9 07 f7 33 ce cc cd  61 a5 8c ba 6a 35 04 03  |....3...a...j5..|
-000002a0  00 8b 30 81 88 02 42 01  f4 8d 4f 3e c8 73 b5 b4  |..0...B...O>.s..|
-000002b0  b5 2b ac 2a 27 68 56 a1  45 ce b6 1d c6 37 ce de  |.+.*'hV.E....7..|
-000002c0  bd 96 90 5e e2 1c c8 84  b2 84 57 25 81 d4 c3 7a  |...^......W%...z|
-000002d0  db b2 3d 24 2b 17 3a 4a  7e 92 1a bb 0c fb b6 05  |..=$+.:J~.......|
-000002e0  cd 0e 85 4c 3d 4b 24 2a  2a 02 42 00 f6 91 d6 82  |...L=K$**.B.....|
-000002f0  9e 81 98 5f 64 59 ce 16  85 fc 65 19 0c 50 ca ea  |..._dY....e..P..|
-00000300  8a ba 1e 61 a8 71 cf 2c  eb 94 24 ac 34 75 6e 5c  |...a.q.,..$.4un\|
-00000310  dc 92 ba b8 bd 42 75 ef  6d 67 5f 06 5c e3 6c c2  |.....Bu.mg_.\.l.|
-00000320  aa 5e 29 25 66 00 68 c8  5d 9c 6f bb e0 16 03 03  |.^)%f.h.].o.....|
-00000330  00 3a 0d 00 00 36 03 01  02 40 00 2e 04 03 05 03  |.:...6...@......|
-00000340  06 03 08 07 08 08 08 09  08 0a 08 0b 08 04 08 05  |................|
-00000350  08 06 04 01 05 01 06 01  03 03 02 03 03 01 02 01  |................|
-00000360  03 02 02 02 04 02 05 02  06 02 00 00 16 03 03 00  |................|
-00000370  04 0e 00 00 00                                    |.....|
+00000270  2a 16 03 03 00 b6 0c 00  00 b2 03 00 1d 20 24 d0  |*............ $.|
+00000280  e5 11 4c 95 2c 96 58 62  01 df 20 c8 24 ce 29 a2  |..L.,.Xb.. .$.).|
+00000290  1a 3e 97 e2 df 29 49 e6  3a e8 c2 d3 72 49 04 03  |.>...)I.:...rI..|
+000002a0  00 8a 30 81 87 02 41 71  15 8d 50 f6 69 40 d7 cd  |..0...Aq..P.i@..|
+000002b0  da c9 c3 ee 37 c2 5f c3  89 62 23 e0 ef 37 f9 9e  |....7._..b#..7..|
+000002c0  2a 26 85 10 56 28 08 de  49 3b fa 03 f3 14 4b 3a  |*&..V(..I;....K:|
+000002d0  b2 3d de 84 d2 08 8d 4e  59 3e 80 8f 6a 44 af 6f  |.=.....NY>..jD.o|
+000002e0  be ee 08 ae 35 40 42 bc  02 42 00 f3 e9 89 a5 7f  |....5@B..B......|
+000002f0  9c 50 7c 07 34 e4 cf f0  2b 0f cf f7 68 57 fa fd  |.P|.4...+...hW..|
+00000300  2f 52 04 f8 90 7b 97 eb  c3 e0 cc 68 f7 bf 22 21  |/R...{.....h.."!|
+00000310  62 b3 51 c8 a4 30 38 c5  88 46 df 55 21 21 d0 4f  |b.Q..08..F.U!!.O|
+00000320  6f 95 7b 5f 5a c6 98 dd  2d d1 0a 95 16 03 03 00  |o.{_Z...-.......|
+00000330  3a 0d 00 00 36 03 01 02  40 00 2e 04 03 05 03 06  |:...6...@.......|
+00000340  03 08 07 08 08 08 09 08  0a 08 0b 08 04 08 05 08  |................|
+00000350  06 04 01 05 01 06 01 03  03 02 03 03 01 02 01 03  |................|
+00000360  02 02 02 04 02 05 02 06  02 00 00 16 03 03 00 04  |................|
+00000370  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.......\.|
@@ -108,31 +108,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 08 04 00  80 53 85 ea dc a6 86 2d  |.........S.....-|
-00000240  e7 8c 0b 68 f9 57 7f f5  77 d8 fe 35 28 91 e7 2f  |...h.W..w..5(../|
-00000250  8a 2c 36 cf d7 8c 9f 3d  f2 e2 99 41 11 b2 3c a2  |.,6....=...A..<.|
-00000260  5e f3 68 1f b5 d4 f8 90  8a e2 5e 02 48 00 2b eb  |^.h.......^.H.+.|
-00000270  f0 e6 8c 28 af 11 80 82  ea 35 06 fd 0a 5f d7 1a  |...(.....5..._..|
-00000280  e9 63 29 08 8c aa 18 1e  7c 08 81 21 c8 aa 86 b1  |.c).....|..!....|
-00000290  cf 94 db f6 8d 15 dc cc  ae cf 41 2c 32 b1 3f 0c  |..........A,2.?.|
-000002a0  96 0e 5c ed 82 74 cc fc  35 f4 38 80 29 00 c1 3a  |..\..t..5.8.)..:|
-000002b0  70 d4 07 07 9c 49 9e 7b  91 14 03 03 00 01 01 16  |p....I.{........|
+00000230  88 0f 00 00 84 08 04 00  80 84 38 78 4d dd 9f 84  |..........8xM...|
+00000240  ae cb b8 2f e9 f3 76 66  41 56 f6 ed a5 fb 8b f2  |.../..vfAV......|
+00000250  43 0f 27 56 9e 7d a8 06  3e 8f ad b0 17 d5 d6 52  |C.'V.}..>......R|
+00000260  f4 88 e5 af 55 5b 55 fc  26 c1 a9 d5 a9 34 2b 50  |....U[U.&....4+P|
+00000270  96 09 db 59 cc f4 e8 cf  84 6f 9d b1 fd 3b a4 66  |...Y.....o...;.f|
+00000280  66 43 74 6d 4f e5 52 2c  22 2d c9 4c 67 3d ff 3d  |fCtmO.R,"-.Lg=.=|
+00000290  c2 79 b3 b1 85 56 08 cc  02 7c 53 a7 be 39 04 21  |.y...V...|S..9.!|
+000002a0  fb db fe ff 1b a6 c7 7a  e9 4c 11 c3 34 a6 7c 4f  |.......z.L..4.|O|
+000002b0  23 61 d9 47 b0 6c ae cb  72 14 03 03 00 01 01 16  |#a.G.l..r.......|
 000002c0  03 03 00 40 00 00 00 00  00 00 00 00 00 00 00 00  |...@............|
-000002d0  00 00 00 00 f3 da dc d7  12 d6 f6 19 75 a8 02 68  |............u..h|
-000002e0  57 0e e1 90 75 d1 fc b8  32 a3 34 16 d6 8d 2a f5  |W...u...2.4...*.|
-000002f0  65 f2 a7 67 2c 2c a4 73  6a b6 f2 ad 2d 7f 8a ce  |e..g,,.sj...-...|
-00000300  a7 12 16 97                                       |....|
+000002d0  00 00 00 00 d3 95 4a 65  d9 8e 3d 9c 2b 18 67 aa  |......Je..=.+.g.|
+000002e0  e0 d7 a6 dd fb af 42 06  0d 56 cc 3d 12 3e 7e 95  |......B..V.=.>~.|
+000002f0  18 6e 97 d6 cc 84 eb 90  a1 c3 b6 6e 3c 42 d1 2e  |.n.........n<B..|
+00000300  7a dc 41 81                                       |z.A.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 dc 11 a1 a2 fb  |..........@.....|
-00000010  55 0c 9e e0 e2 55 1a ca  cd 5b df 1f 39 9e 08 51  |U....U...[..9..Q|
-00000020  bd 6b 72 40 93 f8 23 7a  32 9d 85 18 20 b7 39 b0  |.kr@..#z2... .9.|
-00000030  03 d3 10 6a 8e 66 6d e6  d5 38 03 c6 e5 b8 dc d7  |...j.fm..8......|
-00000040  3c 27 1d d2 a9 59 f9 18  7d 15 90                 |<'...Y..}..|
+00000000  14 03 03 00 01 01 16 03  03 00 40 71 ee 1d 4f 55  |..........@q..OU|
+00000010  b4 47 3d 26 52 5a 00 a5  ce 0e 31 6c 2d 09 95 df  |.G=&RZ....1l-...|
+00000020  fb 74 30 89 32 3d 47 29  58 ee 61 70 74 18 8c 01  |.t0.2=G)X.apt...|
+00000030  e3 16 d7 6e 3d a1 30 75  61 b8 99 e4 c5 82 82 d5  |...n=.0ua.......|
+00000040  75 f6 e1 b4 f8 97 77 92  00 64 06                 |u.....w..d.|
 >>> 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 c2 92 ee  96 31 60 90 d5 ee a6 1c  |.........1`.....|
-00000020  ed 3c 03 40 8c e7 0c db  7f b0 11 dc 7e 58 e1 aa  |.<.@........~X..|
-00000030  4c d7 68 2a 91 15 03 03  00 30 00 00 00 00 00 00  |L.h*.....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 b6 61 51 ac 66 a5  |...........aQ.f.|
-00000050  d1 ef d3 ee c8 d3 48 72  d5 e0 ef 7d ca 6a ec b2  |......Hr...}.j..|
-00000060  77 ff 2d a8 32 6d be 6e  a7 42                    |w.-.2m.n.B|
+00000010  00 00 00 00 00 e2 68 77  75 6a f8 3c 3d 2c 96 52  |......hwuj.<=,.R|
+00000020  2d fc d5 3b d3 17 c0 29  df 99 f1 09 23 13 9f 89  |-..;...)....#...|
+00000030  dd 21 15 23 36 15 03 03  00 30 00 00 00 00 00 00  |.!.#6....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 37 4e ac 91 80 02  |..........7N....|
+00000050  4f 4a 9f b4 3c 0e 24 87  c8 d0 41 24 ce 01 e2 bb  |OJ..<.$...A$....|
+00000060  18 af bc ce 09 4b 41 f6  db 08                    |.....KA...|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
index cdc7104..cbc4bcc 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 f3 28 ca c9 ac  |....Y...U...(...|
-00000010  29 bb 15 80 56 d2 37 09  fa 7d 23 04 d4 79 e7 1d  |)...V.7..}#..y..|
-00000020  bb 4e c5 60 c8 44 39 02  6a e9 e0 20 b5 ae 39 87  |.N.`.D9.j.. ..9.|
-00000030  4e 24 2f 33 02 fe 72 d6  2a 4d 0c 8c da 36 7b 28  |N$/3..r.*M...6{(|
-00000040  3c 06 aa b2 60 68 91 7a  ae d8 7b e2 c0 2f 00 00  |<...`h.z..{../..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 b6 96 f2 bc ed  |....Y...U.......|
+00000010  1b 14 73 de 12 10 cc e9  4d f2 c7 8b 46 d8 63 55  |..s.....M...F.cU|
+00000020  8f 04 33 ec 89 b5 70 93  01 1c f2 20 72 82 e1 16  |..3...p.... r...|
+00000030  9c 0e 70 25 84 2c 09 a6  4f 19 c0 ed 44 d6 98 13  |..p%.,..O...D...|
+00000040  97 f6 19 08 d4 b6 d3 ad  82 96 ef db c0 2f 00 00  |............./..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,17 +60,17 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |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 d4 df 5d 10 ee ba a6  |........ ..]....|
-000002d0  51 d7 1b fb bf ed bc d6  b9 34 44 e7 af 23 0e 9b  |Q........4D..#..|
-000002e0  45 af ba 7a 89 63 03 a9  4c 08 04 00 80 30 2c 0f  |E..z.c..L....0,.|
-000002f0  2e d9 e4 1d c2 90 01 1c  cc cf d4 fe 06 6d c3 aa  |.............m..|
-00000300  59 d9 d9 bc 16 2f 2c b1  be 90 a3 93 a7 be bc 4d  |Y..../,........M|
-00000310  d8 f4 ac 21 36 59 a8 21  94 ef d3 c4 53 14 34 18  |...!6Y.!....S.4.|
-00000320  c9 10 d5 77 fd 1e ad 15  0f 23 d7 73 90 7a c0 7b  |...w.....#.s.z.{|
-00000330  b3 b2 e2 df 15 42 35 ce  38 05 52 02 77 b7 b2 2b  |.....B5.8.R.w..+|
-00000340  6b 88 6a ce d4 20 99 9d  e4 fe e8 38 1e 01 b7 78  |k.j.. .....8...x|
-00000350  3c ea ac 8e ef 2f 7e e8  22 08 78 42 b7 db 84 80  |<..../~.".xB....|
-00000360  8c 61 8a c5 cc d7 1f 6a  8d 5c 1d 2d 0d 16 03 03  |.a.....j.\.-....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 21 1b d1 91 16 9c c1  |........ !......|
+000002d0  51 52 39 07 6b 6d ab 07  28 f7 d0 ae 02 13 5e 73  |QR9.km..(.....^s|
+000002e0  5b 51 30 96 27 57 56 e5  37 08 04 00 80 6a 13 82  |[Q0.'WV.7....j..|
+000002f0  97 81 ea 32 51 cb cb 8e  3b ee e5 dd 4f 80 20 50  |...2Q...;...O. P|
+00000300  c9 f0 19 9b d5 1b ae 21  f7 e6 24 4e a3 22 ec b9  |.......!..$N."..|
+00000310  25 6e 77 19 12 08 16 8a  c7 c1 db 29 e9 be 05 55  |%nw........)...U|
+00000320  09 c1 6e 44 c3 d7 bd 18  80 c8 1f 42 53 3b e6 09  |..nD.......BS;..|
+00000330  00 29 20 c4 94 04 97 6f  f7 e6 f4 3b 66 77 2f e5  |.) ....o...;fw/.|
+00000340  de 96 6f c3 67 c5 ce 4b  5e 4b 0e 90 02 fc 32 7f  |..o.g..K^K....2.|
+00000350  71 f4 63 76 37 57 75 30  fb 1b f5 99 98 5f c3 b1  |q.cv7Wu0....._..|
+00000360  fb e3 76 ad 8e 2f 7a 72  86 ed 34 18 98 16 03 03  |..v../zr..4.....|
 00000370  00 3a 0d 00 00 36 03 01  02 40 00 2e 04 03 05 03  |.:...6...@......|
 00000380  06 03 08 07 08 08 08 09  08 0a 08 0b 08 04 08 05  |................|
 00000390  08 06 04 01 05 01 06 01  03 03 02 03 03 01 02 01  |................|
@@ -112,26 +112,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 08 04 00  80 b8 96 b3 c8 66 a9 fb  |.............f..|
-00000240  da 1b 82 65 9d 57 e5 e5  e5 60 c9 43 df 6e 99 53  |...e.W...`.C.n.S|
-00000250  45 95 b8 58 d1 19 05 50  e1 a7 3c e8 07 ad 57 09  |E..X...P..<...W.|
-00000260  9c 95 13 ea 80 24 53 56  b1 13 2d 59 9d e9 60 0f  |.....$SV..-Y..`.|
-00000270  75 97 d3 4f 82 3a b5 41  3e 90 75 ea 28 97 00 e7  |u..O.:.A>.u.(...|
-00000280  74 c9 04 1d d0 16 ba 40  75 9c ae a0 bd 00 b1 a9  |t......@u.......|
-00000290  86 d5 1a f2 30 45 72 99  ea b2 eb 61 b1 63 72 c5  |....0Er....a.cr.|
-000002a0  ad b1 60 a8 fa bd 95 95  17 03 4c 8e 87 4b 44 e5  |..`.......L..KD.|
-000002b0  ec f3 e0 48 33 b8 a9 74  78 14 03 03 00 01 01 16  |...H3..tx.......|
-000002c0  03 03 00 28 00 00 00 00  00 00 00 00 e6 a6 db ee  |...(............|
-000002d0  7d fb 48 9f 81 a6 78 6a  db a1 9a bb c8 da 7b b2  |}.H...xj......{.|
-000002e0  6a 01 66 fb 85 a7 2f 35  40 77 b6 b2              |j.f.../5@w..|
+00000230  88 0f 00 00 84 08 04 00  80 90 53 1e fc 7c 63 b0  |..........S..|c.|
+00000240  98 c5 19 40 fb 4f cf c3  53 51 81 68 54 c7 49 38  |...@.O..SQ.hT.I8|
+00000250  0c 41 f0 12 7d a6 e4 8a  4e 77 97 49 5a 07 7d 30  |.A..}...Nw.IZ.}0|
+00000260  fa df 77 2f 51 cf 37 65  07 0b 2c 91 15 43 1d c9  |..w/Q.7e..,..C..|
+00000270  69 46 e2 26 66 72 98 ec  62 1a 22 ae e8 3e 3a 28  |iF.&fr..b."..>:(|
+00000280  17 83 b9 74 57 59 a2 ec  31 95 17 1f c3 ec 9a 01  |...tWY..1.......|
+00000290  f2 d4 07 d5 ee d5 0e f2  f4 75 3b d6 b8 df aa ad  |.........u;.....|
+000002a0  0b 87 37 30 43 7e c1 b1  e1 0d 7e 90 3d 87 9d 93  |..70C~....~.=...|
+000002b0  d7 06 57 18 5c 12 c2 32  0d 14 03 03 00 01 01 16  |..W.\..2........|
+000002c0  03 03 00 28 00 00 00 00  00 00 00 00 ff 2a ae f8  |...(.........*..|
+000002d0  c9 1c bd 3f 62 0e 68 42  e7 96 ec ee c0 fa 71 34  |...?b.hB......q4|
+000002e0  f1 e2 67 76 82 cf c3 2a  fb b2 5a c1              |..gv...*..Z.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 b3 9c 30 b6 a2  |..........(..0..|
-00000010  cb cf 75 38 10 e7 80 39  0e 87 39 9c d9 da 2c 53  |..u8...9..9...,S|
-00000020  1a 64 2d 33 ff 21 25 e9  3c f2 ec 6d a4 59 f4 30  |.d-3.!%.<..m.Y.0|
-00000030  ea 41 24                                          |.A$|
+00000000  14 03 03 00 01 01 16 03  03 00 28 da 70 e7 aa 1b  |..........(.p...|
+00000010  6c 66 cb 9b 07 d9 4e 87  6f 87 60 fb 46 f5 e9 33  |lf....N.o.`.F..3|
+00000020  48 59 ff 3e b5 bf 0b 0c  b2 39 79 64 f6 3c 2e 95  |HY.>.....9yd.<..|
+00000030  04 51 87                                          |.Q.|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 65 72 8f  |.............er.|
-00000010  4a 5f 08 c1 f9 37 5d 30  bc c6 e6 5f a8 23 35 69  |J_...7]0..._.#5i|
-00000020  d3 3c 7a 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.<z.............|
-00000030  b0 48 2e 2e ed 4d 9c db  3a fc ff e6 57 83 fc 90  |.H...M..:...W...|
-00000040  aa 78                                             |.x|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 21 29 d2  |.............!).|
+00000010  27 05 2d b4 a2 bf ea f2  96 8a 61 c9 91 75 9f 0f  |'.-.......a..u..|
+00000020  50 4a 76 15 03 03 00 1a  00 00 00 00 00 00 00 02  |PJv.............|
+00000030  a9 40 eb 86 b2 f0 85 a2  75 bc 4e 09 8c c9 ca 31  |.@......u.N....1|
+00000040  e5 49                                             |.I|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPKCS1v15 b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPKCS1v15
index 26308fc..b8ecfff 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPKCS1v15
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPKCS1v15
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 97 f2 cb de f1  |....Y...U.......|
-00000010  bb cf 9a 6c 6d 7e e2 94  af 9d 0b ed 02 cf fc b2  |...lm~..........|
-00000020  80 b2 7b 41 2c a6 83 e7  52 62 93 20 63 23 7f 48  |..{A,...Rb. c#.H|
-00000030  be c1 7f d3 75 34 fe 3a  ad 27 f5 99 b0 73 91 df  |....u4.:.'...s..|
-00000040  b3 e9 82 95 cd 1b f9 08  b6 3d 4f 9b c0 2f 00 00  |.........=O../..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 ad e1 a7 5e 0b  |....Y...U.....^.|
+00000010  b8 bd 9d 05 c2 8e 6c f2  ea 7d a1 c8 32 cc d1 74  |......l..}..2..t|
+00000020  ba 86 75 98 33 27 39 c3  0a 6f 49 20 2b 37 9a 0f  |..u.3'9..oI +7..|
+00000030  9b de 1f 1d 5f 2b 45 29  6c 9b 33 c6 bc c1 15 a4  |...._+E)l.3.....|
+00000040  19 9b 70 6c 15 eb 4a 92  92 5f b7 6b c0 2f 00 00  |..pl..J.._.k./..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,17 +60,17 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |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 f8 3a 6c 5b 6f 88 48  |........ .:l[o.H|
-000002d0  19 c5 a2 e7 4a d9 6d 21  56 23 63 1b 1f 95 aa bc  |....J.m!V#c.....|
-000002e0  33 ac aa 3b bb f8 35 ba  1a 04 01 00 80 98 6d 7b  |3..;..5.......m{|
-000002f0  7d 40 13 81 6b 70 ec ac  60 ee 1d 3e 37 36 bc f4  |}@..kp..`..>76..|
-00000300  c1 9f 3c 13 b7 06 3d 38  be 4f 8c 3e e2 2e f2 b5  |..<...=8.O.>....|
-00000310  de 16 ec a0 5b 64 00 5c  c3 50 cc 79 a2 f7 e0 8d  |....[d.\.P.y....|
-00000320  68 e6 6b 1b b8 57 a4 15  d0 2c d7 4a be 97 26 26  |h.k..W...,.J..&&|
-00000330  8c 5c 4e 26 36 96 48 b5  0f 88 7b 37 43 e4 d1 24  |.\N&6.H...{7C..$|
-00000340  01 3c 70 38 99 c6 e2 2f  66 e7 db 57 30 f2 72 d0  |.<p8.../f..W0.r.|
-00000350  17 fd ad 09 a7 bd ee de  ca fd 57 15 de 25 b6 1f  |..........W..%..|
-00000360  ed 45 86 22 83 4e 64 54  56 17 1f 81 4f 16 03 03  |.E.".NdTV...O...|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 ba ad fb 1e 28 95 96  |........ ....(..|
+000002d0  f3 62 9d 97 87 0f fd fc  a9 91 a2 4b 8d 69 ec 8f  |.b.........K.i..|
+000002e0  7d 49 08 6e fe 7d b3 5b  03 04 01 00 80 86 57 23  |}I.n.}.[......W#|
+000002f0  58 bb 9a 50 d8 bb 99 d9  f5 cc 66 43 38 f0 14 8a  |X..P......fC8...|
+00000300  cb 6d 8b c0 83 52 f8 53  75 94 07 e3 12 2c 10 bb  |.m...R.Su....,..|
+00000310  f3 9b 74 84 1f 11 f3 06  c3 f4 df db f0 1e 0a cd  |..t.............|
+00000320  1b 45 18 44 88 67 79 ca  3e 6e 2b 73 c2 10 84 d8  |.E.D.gy.>n+s....|
+00000330  7b c5 2e 81 7d 53 19 46  09 35 35 8b 66 8a a8 cc  |{...}S.F.55.f...|
+00000340  20 ba 20 15 9f d1 27 9c  6b 3c bb 48 79 4a 7e 11  | . ...'.k<.HyJ~.|
+00000350  da e3 26 5b 3a 95 da 4d  bd 86 3e 8c 97 55 7c 22  |..&[:..M..>..U|"|
+00000360  a1 d3 88 61 ae e1 3b 51  25 c6 01 7e 10 16 03 03  |...a..;Q%..~....|
 00000370  00 0c 0d 00 00 08 01 01  00 02 04 01 00 00 16 03  |................|
 00000380  03 00 04 0e 00 00 00                              |.......|
 >>> Flow 3 (client to server)
@@ -109,26 +109,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 04 01 00  80 a8 12 9d 84 c2 17 0a  |................|
-00000240  03 ae bd 87 9a b6 6f 65  2f 7a 04 1f 69 2a 41 f4  |......oe/z..i*A.|
-00000250  d0 9a 4d a4 5b 6e d2 d3  42 c3 77 4f 04 28 ce e6  |..M.[n..B.wO.(..|
-00000260  d4 25 c5 81 1b 78 91 e9  1e 93 90 57 b2 58 6f 26  |.%...x.....W.Xo&|
-00000270  ed 20 15 62 ff e9 c6 c1  52 4a 9a 05 a6 cd 17 22  |. .b....RJ....."|
-00000280  75 c8 81 da a4 96 af c6  83 b5 5c 81 93 59 44 26  |u.........\..YD&|
-00000290  5b 03 59 9d ab 93 ee c7  37 61 74 e7 4a 22 1c ec  |[.Y.....7at.J"..|
-000002a0  96 fb a2 c9 ea 2d 4b 8d  d3 a7 e4 60 57 10 be b7  |.....-K....`W...|
-000002b0  60 80 4f ee 8e 21 6b a2  13 14 03 03 00 01 01 16  |`.O..!k.........|
-000002c0  03 03 00 28 00 00 00 00  00 00 00 00 16 82 4a c0  |...(..........J.|
-000002d0  98 7b 62 3e 9b da a9 ac  31 f2 32 a9 23 13 2f e3  |.{b>....1.2.#./.|
-000002e0  77 c9 1e ca 39 9f 4c 8a  10 58 33 67              |w...9.L..X3g|
+00000230  88 0f 00 00 84 04 01 00  80 12 a4 42 13 85 6f 92  |...........B..o.|
+00000240  6d 26 5d 05 3c b7 80 ab  a9 e0 74 3d 89 67 79 a0  |m&].<.....t=.gy.|
+00000250  9f e1 a9 20 d8 82 e2 22  99 38 03 fe 32 d9 1f c7  |... ...".8..2...|
+00000260  39 1e 27 31 59 05 eb aa  bc 2c 10 eb f0 82 65 65  |9.'1Y....,....ee|
+00000270  ce b2 e9 83 67 21 43 03  19 2d 14 9f c3 db bc dc  |....g!C..-......|
+00000280  59 66 95 d7 4e 09 3c f0  f2 4a 39 f7 db c4 0c 4e  |Yf..N.<..J9....N|
+00000290  73 e2 d6 59 f1 bc 06 d8  75 df 32 b7 f1 b4 01 98  |s..Y....u.2.....|
+000002a0  4f 93 43 a3 a6 09 da cd  1c ee 26 65 ab d1 2a 56  |O.C.......&e..*V|
+000002b0  74 32 24 46 27 f3 d9 6a  df 14 03 03 00 01 01 16  |t2$F'..j........|
+000002c0  03 03 00 28 00 00 00 00  00 00 00 00 68 27 5e 44  |...(........h'^D|
+000002d0  d7 73 26 f6 51 86 01 f5  f3 5d 61 a0 05 cd c3 00  |.s&.Q....]a.....|
+000002e0  85 6f ea 56 85 1e 7a c3  4c d3 6d 64              |.o.V..z.L.md|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 8e 56 d0 9c 38  |..........(.V..8|
-00000010  4f d9 df 12 9b dd 96 05  94 77 2f 6d 24 a8 cb 56  |O........w/m$..V|
-00000020  91 f9 bc ec 00 b5 cc 71  c4 f4 36 42 be 68 37 78  |.......q..6B.h7x|
-00000030  8f 6e 8c                                          |.n.|
+00000000  14 03 03 00 01 01 16 03  03 00 28 81 f3 33 d8 2a  |..........(..3.*|
+00000010  57 45 53 2c ee 68 8b 79  ed 07 dc 90 c3 a7 84 38  |WES,.h.y.......8|
+00000020  8c 33 03 e9 c6 51 04 b2  73 8a 8b 81 12 eb 6c 5f  |.3...Q..s.....l_|
+00000030  a3 8f 5e                                          |..^|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 1c 19 9e  |................|
-00000010  a5 40 f6 d7 8b 80 23 8a  0b fa 14 65 08 6a 3c 66  |.@....#....e.j<f|
-00000020  07 c4 d2 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
-00000030  16 7c e2 68 a5 d4 df 64  f4 1c 7d 17 b6 14 0a 4c  |.|.h...d..}....L|
-00000040  40 8e                                             |@.|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 e5 c6 d7  |................|
+00000010  4d e0 d1 0c ff a0 66 c4  71 53 af 7e 16 01 3d 2e  |M.....f.qS.~..=.|
+00000020  6c ab 90 15 03 03 00 1a  00 00 00 00 00 00 00 02  |l...............|
+00000030  92 12 87 24 c8 7e 74 23  df f7 23 49 01 9a dd 3b  |...$.~t#..#I...;|
+00000040  2c 68                                             |,h|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPSS b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPSS
index 3f74080..de05fec 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPSS
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPSS
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 29 bc e2 fe ae  |....Y...U..)....|
-00000010  0a db 37 e6 39 d5 48 24  3d 0f e5 d7 6b a3 69 dd  |..7.9.H$=...k.i.|
-00000020  ce 09 fd 28 03 c2 7e 38  db c9 ec 20 d2 5e 3f 94  |...(..~8... .^?.|
-00000030  b0 2c 5e 4c 77 c2 94 c3  f2 a9 d0 91 4f 96 45 0e  |.,^Lw.......O.E.|
-00000040  d3 34 fc 9f e0 a5 e6 fc  1e 8a c1 00 c0 2f 00 00  |.4.........../..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 61 fe 1e 35 33  |....Y...U..a..53|
+00000010  4b b4 dd 9b 0f 55 58 f4  0c c5 b2 73 51 7b 84 e7  |K....UX....sQ{..|
+00000020  25 f7 8f 12 5a 12 11 e1  7b e6 52 20 ad 86 a9 f9  |%...Z...{.R ....|
+00000030  7f 6a 30 da 79 23 c3 c4  dc 88 f6 19 1d cc 16 8b  |.j0.y#..........|
+00000040  96 74 84 ce 53 56 65 e2  cb 94 61 0c c0 2f 00 00  |.t..SVe...a../..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 66 0b 00 02 62 00  02 5f 00 02 5c 30 82 02  |..f...b.._..\0..|
 00000070  58 30 82 01 8d a0 03 02  01 02 02 11 00 f2 99 26  |X0.............&|
@@ -61,17 +61,17 @@
 000002a0  11 89 66 79 d1 8e 88 0e  0b a0 9e 30 2a c0 67 ef  |..fy.......0*.g.|
 000002b0  ca 46 02 88 e9 53 81 22  69 22 97 ad 80 93 d4 f7  |.F...S."i"......|
 000002c0  dd 70 14 24 d7 70 0a 46  a1 16 03 03 00 ac 0c 00  |.p.$.p.F........|
-000002d0  00 a8 03 00 1d 20 9e e4  39 3a b3 d5 f9 51 16 d4  |..... ..9:...Q..|
-000002e0  a8 e1 0a 6d ad 3c ca 01  97 d6 a1 ce 03 2a 67 4a  |...m.<.......*gJ|
-000002f0  49 06 eb ed c6 24 08 04  00 80 b3 b7 9e fd 97 9b  |I....$..........|
-00000300  b0 d6 35 89 21 53 ff a8  4b 59 59 26 37 ac 2f 36  |..5.!S..KYY&7./6|
-00000310  27 3d 5a 04 3f 50 ed 36  e0 5f 1a d7 1b 36 47 94  |'=Z.?P.6._...6G.|
-00000320  45 ec 8c 0b 8f 0f fc df  ec 3c 56 f0 d0 28 45 94  |E........<V..(E.|
-00000330  96 c7 35 bb 42 31 a6 6e  eb 27 cf cf 7e 21 cf 2f  |..5.B1.n.'..~!./|
-00000340  a1 90 5d 2b 32 23 b3 de  40 a7 b6 56 c1 73 29 56  |..]+2#..@..V.s)V|
-00000350  3d 73 fe 34 b2 0b 58 97  16 e6 a1 1c 47 0e 24 a7  |=s.4..X.....G.$.|
-00000360  0d c9 a0 51 70 82 b1 d1  a6 a1 bc b4 49 77 c4 c4  |...Qp.......Iw..|
-00000370  87 ae c8 49 e6 80 ae d0  dd ca 16 03 03 00 0c 0d  |...I............|
+000002d0  00 a8 03 00 1d 20 e0 90  02 58 37 69 79 d6 78 e5  |..... ...X7iy.x.|
+000002e0  1d c6 7e a0 c6 38 1b ff  47 72 d6 c2 52 cb 6c 52  |..~..8..Gr..R.lR|
+000002f0  36 7e 03 c3 35 1d 08 04  00 80 79 5f 23 fd b1 ee  |6~..5.....y_#...|
+00000300  ac 62 c8 72 09 52 1f 9a  0f ac 95 3e 4e e4 97 d2  |.b.r.R.....>N...|
+00000310  a3 04 ae 19 3f 25 ad 3e  b7 78 1f d9 79 5f c8 26  |....?%.>.x..y_.&|
+00000320  f0 26 e5 ee 54 46 4a 05  84 15 01 4f 7a 7e 60 bd  |.&..TFJ....Oz~`.|
+00000330  86 74 78 d7 7c 86 91 2b  4f 76 b6 aa 78 27 c8 21  |.tx.|..+Ov..x'.!|
+00000340  7e df 88 2f 26 f0 9d 3c  a2 e8 95 f6 9f 5a a4 5e  |~../&..<.....Z.^|
+00000350  18 dc cd 0d 70 e8 85 b7  e5 57 f6 c2 f4 33 28 1c  |....p....W...3(.|
+00000360  58 7b 94 b0 9e ee d8 b3  42 b5 f3 63 78 a1 30 f3  |X{......B..cx.0.|
+00000370  f7 e4 5e 72 64 6f 80 32  70 4e 16 03 03 00 0c 0d  |..^rdo.2pN......|
 00000380  00 00 08 01 01 00 02 08  04 00 00 16 03 03 00 04  |................|
 00000390  0e 00 00 00                                       |....|
 >>> Flow 3 (client to server)
@@ -117,26 +117,26 @@
 00000270  10 00 00 21 20 2f e5 7d  a3 47 cd 62 43 15 28 da  |...! /.}.G.bC.(.|
 00000280  ac 5f bb 29 07 30 ff f6  84 af c4 cf c2 ed 90 99  |._.).0..........|
 00000290  5f 58 cb 3b 74 16 03 03  00 88 0f 00 00 84 08 04  |_X.;t...........|
-000002a0  00 80 a6 6b 99 15 5e 97  33 4f a8 0e 59 af 15 22  |...k..^.3O..Y.."|
-000002b0  f3 6e be 02 6e e4 20 d5  81 c0 b4 74 5a e2 20 32  |.n..n. ....tZ. 2|
-000002c0  2b 7f 9c e6 94 32 4d 30  bf 93 86 9b 75 4d f1 9f  |+....2M0....uM..|
-000002d0  e4 48 28 00 27 fa 7c 45  2e fe d7 0b dc 03 c4 6b  |.H(.'.|E.......k|
-000002e0  42 ad a2 32 d7 9d ea d6  52 05 3f ed 87 fd b9 9d  |B..2....R.?.....|
-000002f0  58 fd d6 9f 28 6d 45 07  de 5b 4a 8e f4 4d 19 0b  |X...(mE..[J..M..|
-00000300  cf 4e 64 75 73 ae cd e9  ae f9 af 27 d0 b9 eb 4c  |.Ndus......'...L|
-00000310  98 ad 66 6d 4e bf 2c 39  87 f3 72 3e 4e bc a1 8f  |..fmN.,9..r>N...|
-00000320  a8 1e 14 03 03 00 01 01  16 03 03 00 28 00 00 00  |............(...|
-00000330  00 00 00 00 00 04 3c cc  ae cd 19 52 6b 1e 0e cc  |......<....Rk...|
-00000340  dd a9 ac 2f 2a c6 94 4c  09 f3 ee 2f b5 5a 13 1e  |.../*..L.../.Z..|
-00000350  4f 54 a0 ae c2                                    |OT...|
+000002a0  00 80 b2 c4 60 82 75 ca  be 40 dc 28 ec 6d 14 6f  |....`.u..@.(.m.o|
+000002b0  6c 88 ca 9a d7 ae ce 94  26 a7 10 ad d8 c3 b9 a6  |l.......&.......|
+000002c0  48 4e 01 7d ee 6e f8 e0  15 d9 72 c4 79 8d ac 25  |HN.}.n....r.y..%|
+000002d0  37 29 83 fc e6 f1 2e 4f  76 49 6a 36 b9 1e b4 58  |7).....OvIj6...X|
+000002e0  a2 3e f7 ff 96 5e d9 17  f2 40 05 1f ec bb 5b f5  |.>...^...@....[.|
+000002f0  28 86 d2 fc 0e 7e 70 3a  3d 90 4c 46 a5 3e bc 57  |(....~p:=.LF.>.W|
+00000300  24 4c ee 35 23 99 6f 21  12 db ba d8 3a 5f 37 1f  |$L.5#.o!....:_7.|
+00000310  da 3d c2 c9 bf b6 11 8b  b9 b9 43 0b 52 ff 6d 2a  |.=........C.R.m*|
+00000320  74 a7 14 03 03 00 01 01  16 03 03 00 28 00 00 00  |t...........(...|
+00000330  00 00 00 00 00 34 bd 90  a0 3f 1c 0c 11 5c 8a e4  |.....4...?...\..|
+00000340  28 82 c4 57 59 73 fd a4  dc a9 91 4b df 2a c6 b5  |(..WYs.....K.*..|
+00000350  f0 6e cf 41 70                                    |.n.Ap|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 6d 44 cb 35 8b  |..........(mD.5.|
-00000010  15 5c f9 f8 1e ae 4f 8c  8c d9 90 9e 6c cf 13 f6  |.\....O.....l...|
-00000020  12 29 f5 f7 d6 ff da e2  48 7d 68 ec ad 1a 6c 39  |.)......H}h...l9|
-00000030  c5 77 6c                                          |.wl|
+00000000  14 03 03 00 01 01 16 03  03 00 28 e2 44 81 59 e4  |..........(.D.Y.|
+00000010  6c cf e2 e7 04 78 61 02  36 29 2c 5c c4 6f 13 0b  |l....xa.6),\.o..|
+00000020  29 ba 74 b0 13 e8 8f 67  39 b5 ea d1 9d 99 d2 f6  |).t....g9.......|
+00000030  f7 32 be                                          |.2.|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 2a ce da  |.............*..|
-00000010  11 1c 7d 49 0d aa 44 d4  d6 d4 7f 64 2b 49 47 20  |..}I..D....d+IG |
-00000020  5a 21 bb 15 03 03 00 1a  00 00 00 00 00 00 00 02  |Z!..............|
-00000030  fc 10 75 a7 22 f9 74 1c  3a d2 b2 a8 04 2d 37 5f  |..u.".t.:....-7_|
-00000040  c2 76                                             |.v|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 5c 7b 38  |.............\{8|
+00000010  46 af 57 57 05 5a c5 cb  83 f3 fd 17 d4 c3 2e 93  |F.WW.Z..........|
+00000020  d7 70 52 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.pR.............|
+00000030  df 2b d8 62 ec 97 c6 ab  be d4 7f c9 91 f4 fe 55  |.+.b...........U|
+00000040  ac bd                                             |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
index 95781c6..d21e9b3 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 eb a2 77 eb b6  |....Y...U....w..|
-00000010  1e e4 5c 2c ed 5a dc 93  1b 7e 8a 75 a1 8c ac a6  |..\,.Z...~.u....|
-00000020  69 13 f6 f6 a4 69 07 93  99 cf 12 20 37 d7 f8 26  |i....i..... 7..&|
-00000030  46 ea 3a 21 03 d0 25 0f  22 84 8d 24 2f 98 3d 42  |F.:!..%."..$/.=B|
-00000040  eb 47 1d de 0c 12 ab 95  7a 55 46 f7 c0 09 00 00  |.G......zUF.....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 ec 4a 6a f8 c5  |....Y...U...Jj..|
+00000010  42 65 f9 d3 4f 65 6f 14  6b bd ae a9 82 5d 06 9b  |Be..Oeo.k....]..|
+00000020  9d 03 bb 67 eb ba 52 70  74 c3 01 20 f2 ef 69 54  |...g..Rpt.. ..iT|
+00000030  1f 4b 79 f7 5b d5 08 b4  18 4c af 8e 55 58 45 22  |.Ky.[....L..UXE"|
+00000040  c1 c9 6f cf 36 67 45 20  c7 c5 3a af c0 09 00 00  |..o.6gE ..:.....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -55,39 +55,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 b7 0c 00  00 b3 03 00 1d 20 90 68  |*............ .h|
-00000280  81 8b 1d 7f d5 69 36 d3  4e 63 40 fa 3a 21 ee a4  |.....i6.Nc@.:!..|
-00000290  c7 b4 09 bc 34 51 89 df  d5 d2 79 51 34 32 04 03  |....4Q....yQ42..|
-000002a0  00 8b 30 81 88 02 42 01  b4 69 6b 1c e6 35 99 81  |..0...B..ik..5..|
-000002b0  fb aa cb b4 2d e9 e0 48  6a 6c 5e 14 54 77 b7 9d  |....-..Hjl^.Tw..|
-000002c0  df a3 c2 1b 53 8c d2 46  6d 2e ae 83 3a db 7c 86  |....S..Fm...:.|.|
-000002d0  4a 45 c7 51 cd 30 d6 8c  f5 4f ea 37 cb 1e 27 18  |JE.Q.0...O.7..'.|
-000002e0  ba df d5 5f 11 ae 0e af  75 02 42 01 2b 37 2e 6d  |..._....u.B.+7.m|
-000002f0  7c 11 57 b7 b7 8b 90 73  cd e0 c9 38 3c ee aa d5  ||.W....s...8<...|
-00000300  f2 cd ff b9 66 6a be 62  70 74 ee a4 f4 e3 fb 4f  |....fj.bpt.....O|
-00000310  ed 2e d5 a7 b5 a4 53 c8  1b 17 9e e9 48 e1 dd a6  |......S.....H...|
-00000320  e8 6a 05 cf 73 b2 85 11  13 37 be e0 26 16 03 03  |.j..s....7..&...|
+00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 7f e5  |*............ ..|
+00000280  3b 03 9e 6a 77 11 1b 0f  bc 4a db 44 7c 3b 81 1c  |;..jw....J.D|;..|
+00000290  03 8b 15 a6 f3 16 a0 58  5b 13 c5 1e d2 2c 04 03  |.......X[....,..|
+000002a0  00 8b 30 81 88 02 42 00  cc 7c 76 94 81 89 8f 25  |..0...B..|v....%|
+000002b0  16 e2 a0 0d 80 4f 7a 8f  8c 83 23 53 23 45 9c c1  |.....Oz...#S#E..|
+000002c0  39 e3 0c c2 1b 4d f3 78  cd ea b9 c8 d4 b6 30 bb  |9....M.x......0.|
+000002d0  ff d7 ad 6c b2 fd 62 4d  8a 05 19 cf 58 ec 81 17  |...l..bM....X...|
+000002e0  21 7c 71 a1 d7 ad 87 11  8d 02 42 01 a2 9e c8 e4  |!|q.......B.....|
+000002f0  04 7c 75 22 df 14 97 94  8a 1b a1 34 95 95 dd 4c  |.|u".......4...L|
+00000300  9f 1a c7 c7 96 db ef 87  82 27 9a 27 3a 3d 75 26  |.........'.':=u&|
+00000310  04 47 66 eb 55 60 9f 93  4e b2 09 14 fa 71 5b 3f  |.Gf.U`..N....q[?|
+00000320  33 37 3f 0c f2 5c 4f 1e  cc fa b1 6f 70 16 03 03  |37?..\O....op...|
 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 40 00 00 00  00 00 00 00 00 00 00 00  |....@...........|
-00000040  00 00 00 00 00 7f 83 b7  cd 14 66 fb c3 2a f9 9f  |..........f..*..|
-00000050  79 ec 40 e5 dd 15 46 f3  25 8d dd b2 8e d5 78 97  |y.@...F.%.....x.|
-00000060  e5 d6 4e 1a 2e 35 21 b2  aa ac 28 6f 2c 36 a6 6e  |..N..5!...(o,6.n|
-00000070  44 92 84 1b b9                                    |D....|
+00000040  00 00 00 00 00 d6 67 cb  d5 7c 95 9b 16 e2 3b 86  |......g..|....;.|
+00000050  22 bd 8c c7 40 36 9b b6  7e 0a 77 78 38 14 37 3c  |"...@6..~.wx8.7<|
+00000060  48 42 37 a7 07 31 bb 57  c4 e9 f5 e5 a7 58 71 f8  |HB7..1.W.....Xq.|
+00000070  82 f7 12 97 72                                    |....r|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 db ee f8 c1 0e  |..........@.....|
-00000010  7f 23 b4 cb e6 db 03 2a  fb 68 40 78 85 03 9e dc  |.#.....*.h@x....|
-00000020  ac f8 f0 b5 65 8d 7c 01  4a ce 86 29 a9 c5 c3 b2  |....e.|.J..)....|
-00000030  12 8d d1 58 af e7 21 75  e4 be f3 c0 03 55 f8 bb  |...X..!u.....U..|
-00000040  71 bd 85 ee 46 87 a0 32  75 ee 4c                 |q...F..2u.L|
+00000000  14 03 03 00 01 01 16 03  03 00 40 56 45 5c a3 b3  |..........@VE\..|
+00000010  64 43 54 7f b5 90 1a 34  ab 2b 68 25 49 41 bf 78  |dCT....4.+h%IA.x|
+00000020  50 b0 66 35 20 76 e1 d0  5c 8a 82 2e 03 83 cf c6  |P.f5 v..\.......|
+00000030  b7 48 3d 2c c4 cf f5 31  c1 ab 9a 3b 09 3a 75 e3  |.H=,...1...;.:u.|
+00000040  b2 05 fa d9 79 cc 1b 0e  30 44 e1                 |....y...0D.|
 >>> 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 48 95 f8  a1 0e a7 d0 50 dd cf 8f  |.....H......P...|
-00000020  c4 af ec 49 89 bf 5d 8b  a0 d0 60 7b 38 5a 83 e4  |...I..]...`{8Z..|
-00000030  72 47 7f 81 bd 15 03 03  00 30 00 00 00 00 00 00  |rG.......0......|
-00000040  00 00 00 00 00 00 00 00  00 00 48 06 f1 30 61 dd  |..........H..0a.|
-00000050  e2 97 aa 9c 5f a7 07 bb  44 a4 fb d6 6a 7c aa f5  |...._...D...j|..|
-00000060  16 ae 38 1a 98 e5 f5 28  c2 57                    |..8....(.W|
+00000010  00 00 00 00 00 76 5f 1f  ec 55 ec f4 87 06 91 b4  |.....v_..U......|
+00000020  ba 71 4f 7f 9c ce e1 c7  e6 3d 75 05 fd ba 98 c4  |.qO......=u.....|
+00000030  d0 39 24 b8 d4 15 03 03  00 30 00 00 00 00 00 00  |.9$......0......|
+00000040  00 00 00 00 00 00 00 00  00 00 e8 4e 09 a1 5f db  |...........N.._.|
+00000050  91 d5 5b e8 6a 86 7a 6c  7d 4a e1 94 8a 7d 99 52  |..[.j.zl}J...}.R|
+00000060  e6 5d d8 35 7c a0 68 8f  09 f9                    |.].5|.h...|
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 7214747..02bad39 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 c9 a1 8b 70 59  |....Y...U.....pY|
-00000010  8b 88 41 56 b7 bc 9a 1f  50 57 46 7d 79 d8 ef b2  |..AV....PWF}y...|
-00000020  15 3f ad ad bb 48 09 ce  e1 c2 2c 20 84 43 65 e7  |.?...H...., .Ce.|
-00000030  3f 2f d8 13 9a 79 ac 54  ee b9 13 a1 7c a7 05 f7  |?/...y.T....|...|
-00000040  c8 b4 fc bd 20 40 17 ca  15 cd 91 1e c0 2b 00 00  |.... @.......+..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 d4 97 12 a8 e7  |....Y...U.......|
+00000010  be a9 2d 80 f0 db 01 49  07 04 f4 d1 02 db 3d 4a  |..-....I......=J|
+00000020  f0 af 31 38 39 d7 4c 1a  d3 74 71 20 0f a3 76 14  |..189.L..tq ..v.|
+00000030  73 ff 25 1b ef 29 b3 5e  0b 8f fe ee a6 19 d3 31  |s.%..).^.......1|
+00000040  5d 2e 71 ab 74 58 e9 d6  c5 9b f4 93 c0 2b 00 00  |].q.tX.......+..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -55,34 +55,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 58 f9  |*............ X.|
-00000280  2e 03 90 fa 3d 33 0d 3e  e1 3a b1 5a 45 ec 5c ee  |....=3.>.:.ZE.\.|
-00000290  9f 47 51 4b 93 89 33 11  e0 63 86 fd b2 3b 04 03  |.GQK..3..c...;..|
-000002a0  00 8b 30 81 88 02 42 01  c2 fa 7b f8 ed 6b a5 0f  |..0...B...{..k..|
-000002b0  33 87 02 35 5b 8e 5d 31  5e 92 df c2 90 ae 58 24  |3..5[.]1^.....X$|
-000002c0  43 0f ba e3 b8 77 12 7a  97 c3 77 15 62 d3 f2 cc  |C....w.z..w.b...|
-000002d0  10 cd a9 be b6 b2 37 93  b1 ce 8b b2 6c fa 93 74  |......7.....l..t|
-000002e0  5e 14 8e ba 9e d7 66 48  b8 02 42 01 8e 9a 10 1d  |^.....fH..B.....|
-000002f0  7d e0 d3 cf 0d d0 3c bc  34 1c 16 20 85 50 03 3f  |}.....<.4.. .P.?|
-00000300  e1 6d a3 a0 d4 6e d8 fd  7e df b4 c1 84 29 c3 68  |.m...n..~....).h|
-00000310  c2 01 dd 77 fc 2c a5 8f  3b 74 c6 e4 32 20 b7 a0  |...w.,..;t..2 ..|
-00000320  8c 1b 2d 93 6a 9c 8a ed  21 b5 9a e0 cb 16 03 03  |..-.j...!.......|
+00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 a8 15  |*............ ..|
+00000280  13 40 df f8 dc 39 f0 af  90 53 a8 34 a9 61 68 c8  |.@...9...S.4.ah.|
+00000290  ad be 4f 02 0e d2 83 fd  2e 35 bf 8c 8e 13 04 03  |..O......5......|
+000002a0  00 8b 30 81 88 02 42 00  bc 69 df 5b ec 9f 17 ff  |..0...B..i.[....|
+000002b0  e6 e5 24 71 f6 2b a5 88  40 78 12 ef f3 dc 25 a9  |..$q.+..@x....%.|
+000002c0  7c 89 24 0d c7 46 b2 db  ae 72 b4 2a 87 87 fe 7e  ||.$..F...r.*...~|
+000002d0  22 8f e6 d4 c4 7b 61 14  c3 04 39 98 87 6f 1f 54  |"....{a...9..o.T|
+000002e0  e0 50 16 0b 52 8e d6 1e  0a 02 42 00 b7 40 26 a8  |.P..R.....B..@&.|
+000002f0  11 09 77 ec 36 e5 88 26  6d 83 6f e7 c3 b1 98 c3  |..w.6..&m.o.....|
+00000300  4b 83 92 48 65 31 87 68  ee 49 25 ec 95 59 82 b5  |K..He1.h.I%..Y..|
+00000310  93 92 c8 17 d6 d9 1c 99  60 48 1b 18 50 b4 e7 df  |........`H..P...|
+00000320  ed 75 1a f2 08 e8 3d 93  99 27 ef 4d e3 16 03 03  |.u....=..'.M....|
 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 c2 14 2d  |....(..........-|
-00000040  fc d7 a2 cb 18 b9 2a ae  38 70 b7 78 7c 88 97 d3  |......*.8p.x|...|
-00000050  ff 7f df 12 23 96 ab 4d  6c 5c 67 72 c4           |....#..Ml\gr.|
+00000030  16 03 03 00 28 00 00 00  00 00 00 00 00 30 f1 a9  |....(........0..|
+00000040  4a 7e 86 a1 5d b7 db 2f  c6 e2 ec 36 41 83 66 75  |J~..]../...6A.fu|
+00000050  a3 6c 7d e7 61 36 ac f7  76 f8 8e d8 81           |.l}.a6..v....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 2a dd b3 5b c6  |..........(*..[.|
-00000010  76 e7 c0 ac 8c 70 77 d6  d8 4e 79 4a 04 3d 91 a9  |v....pw..NyJ.=..|
-00000020  ad 79 ef c9 22 78 17 9e  ef b0 03 c8 e6 85 b7 8c  |.y.."x..........|
-00000030  e5 74 95                                          |.t.|
+00000000  14 03 03 00 01 01 16 03  03 00 28 2c 78 86 13 dc  |..........(,x...|
+00000010  a4 b9 bf ad 50 45 a3 d9  b3 df 33 a2 79 b1 1b 25  |....PE....3.y..%|
+00000020  12 94 97 99 07 6b 52 c4  52 64 ab 89 40 8c 93 4a  |.....kR.Rd..@..J|
+00000030  e3 cc d9                                          |...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 84 b5 0f  |................|
-00000010  1f ed f9 4c 0d a1 f3 7b  8e 23 87 65 b1 39 98 50  |...L...{.#.e.9.P|
-00000020  3d ff 1b 15 03 03 00 1a  00 00 00 00 00 00 00 02  |=...............|
-00000030  aa 34 cc f1 4a d3 de 4c  42 bc 2c 0f 3e 71 af 6b  |.4..J..LB.,.>q.k|
-00000040  3c fc                                             |<.|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 fa 9e 8b  |................|
+00000010  92 8c f5 32 e6 d4 11 46  b4 73 62 56 f6 83 15 6f  |...2...F.sbV...o|
+00000020  ce de 2d 15 03 03 00 1a  00 00 00 00 00 00 00 02  |..-.............|
+00000030  93 24 68 83 67 b6 f9 27  b5 26 52 78 5d f3 c9 d2  |.$h.g..'.&Rx]...|
+00000040  26 a0                                             |&.|
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 96f6218..4946fe4 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES128-SHA256
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES128-SHA256
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 87 87 6f ce 44  |....Y...U....o.D|
-00000010  94 5f 2f cc 94 03 50 68  a7 4f 37 70 8a d4 cf e3  |._/...Ph.O7p....|
-00000020  23 7f 11 f5 93 c7 3f 96  87 49 45 20 9c d4 96 b2  |#.....?..IE ....|
-00000030  dc 8c 16 c5 fb cc 2f 8e  0e a5 ef a3 ea cf 57 d0  |....../.......W.|
-00000040  09 70 bd 16 c4 d9 e4 1b  a0 40 f7 f3 c0 23 00 00  |.p.......@...#..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 d1 af 88 61 b7  |....Y...U.....a.|
+00000010  b3 01 16 1a 44 26 1c a1  4f 2d 8a f6 9c f2 7e 1a  |....D&..O-....~.|
+00000020  1f ce cb dd 5b f0 c6 2f  16 5e 4a 20 b3 c7 ae 3f  |....[../.^J ...?|
+00000030  de d0 d8 9e 48 3e 87 23  f0 9d 43 10 50 3c 66 8b  |....H>.#..C.P<f.|
+00000040  7f d2 9b 4f f5 e4 b3 53  db d6 65 d0 c0 23 00 00  |...O...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....|
@@ -55,43 +55,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 b6 0c 00  00 b2 03 00 1d 20 3f a6  |*............ ?.|
-00000280  d1 0d ae 8d c0 06 14 ca  da 2c 69 1c f1 84 c4 dd  |.........,i.....|
-00000290  14 f4 0e a6 ce b5 d6 37  9d 9f a5 ba 7b 74 04 03  |.......7....{t..|
-000002a0  00 8a 30 81 87 02 42 00  b5 2b 9a 32 9d af b9 cc  |..0...B..+.2....|
-000002b0  0d b6 f1 9b 87 35 af d7  dc 04 0f 1b 04 d7 fa 62  |.....5.........b|
-000002c0  20 bd 2c 31 41 17 e7 c0  ea 22 78 e4 de 37 14 a8  | .,1A...."x..7..|
-000002d0  f9 f3 f1 3e 0c 55 59 b3  e3 0e 31 26 ce d0 c1 19  |...>.UY...1&....|
-000002e0  b8 17 07 2a 23 98 7b 17  0f 02 41 41 d5 51 80 4d  |...*#.{...AA.Q.M|
-000002f0  8a 14 56 b1 39 7b 8b 37  24 ef e0 ec 43 44 5a cc  |..V.9{.7$...CDZ.|
-00000300  9b ab dc 63 e7 cc 7b 29  c0 66 ae 9c 23 c5 1b 98  |...c..{).f..#...|
-00000310  6e 35 64 97 12 43 16 73  a6 6b c8 09 2c 26 7c f5  |n5d..C.s.k..,&|.|
-00000320  b1 1f 9f 55 04 9e 53 33  c1 89 7a d0 16 03 03 00  |...U..S3..z.....|
+00000270  2a 16 03 03 00 b6 0c 00  00 b2 03 00 1d 20 dc 43  |*............ .C|
+00000280  15 b7 95 81 41 bf e2 bd  56 82 23 46 05 29 05 95  |....A...V.#F.)..|
+00000290  ae 67 08 38 9f 10 70 25  21 92 b4 a0 82 4e 04 03  |.g.8..p%!....N..|
+000002a0  00 8a 30 81 87 02 41 5d  ca d6 a2 fd e3 e2 be 2f  |..0...A]......./|
+000002b0  69 b5 7d 5c a3 2b 36 4c  8b 81 05 89 12 e1 30 26  |i.}\.+6L......0&|
+000002c0  fa ae 82 b9 4f 8e ba ac  ee 7b 62 d5 60 f8 df a4  |....O....{b.`...|
+000002d0  c1 a1 15 73 f8 fb 0b 47  64 b3 34 4a 44 02 a6 32  |...s...Gd.4JD..2|
+000002e0  bc 0d 7b a5 c1 84 cf 77  02 42 01 f3 e5 7f d1 47  |..{....w.B.....G|
+000002f0  bc be 0a ec cd d6 4f 2c  26 5a 95 d3 0f 9b c3 c6  |......O,&Z......|
+00000300  05 b5 5e d7 f6 ca 64 17  94 aa a5 e6 b1 88 57 21  |..^...d.......W!|
+00000310  f8 da 02 de 32 8c ea 5b  7c 36 c9 93 e1 96 38 93  |....2..[|6....8.|
+00000320  9b f9 e5 44 47 a6 74 fa  0e 5f 8f 22 16 03 03 00  |...DG.t.._."....|
 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 d3 72 3f  9d 37 ba 97 55 83 b4 f0  |......r?.7..U...|
-00000050  ad 0b f0 48 98 16 05 f1  b5 6e da a4 79 e4 d9 8e  |...H.....n..y...|
-00000060  62 af b9 a1 d1 a4 5c 04  d2 b1 86 32 af 64 ac 89  |b.....\....2.d..|
-00000070  d3 47 5f 61 ae f4 21 5b  8d 4b ff 74 c1 b8 9c de  |.G_a..![.K.t....|
-00000080  fd 74 a0 99 c1                                    |.t...|
+00000040  00 00 00 00 00 85 db ae  c1 37 85 25 3d ee 5f f5  |.........7.%=._.|
+00000050  12 95 df ee 29 4a f7 3a  80 ca bd c2 b3 d8 f3 8c  |....)J.:........|
+00000060  56 62 d2 68 13 1d 73 51  09 93 a3 b9 43 4a 2c 0f  |Vb.h..sQ....CJ,.|
+00000070  bf 3c 96 76 08 a9 17 68  e2 9a 3f 39 e7 04 76 f8  |.<.v...h..?9..v.|
+00000080  8f fe e8 f5 ce                                    |.....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 50 09 3b 3e 7e 2e  |..........P.;>~.|
-00000010  d8 46 04 ac b0 3d c9 7e  ec 28 8c bd 6c 0f a8 b5  |.F...=.~.(..l...|
-00000020  af 8c 86 ed 64 81 6c d4  98 9e 56 2a 48 0d 03 40  |....d.l...V*H..@|
-00000030  64 3e 25 58 6f 03 6a 4e  be a2 11 6f 6f e7 2f c2  |d>%Xo.jN...oo./.|
-00000040  8f 78 c4 11 a1 07 21 91  9d 34 01 08 39 0d 07 d2  |.x....!..4..9...|
-00000050  d4 a2 cc 2f 25 ea ee 8d  8b 91 f9                 |.../%......|
+00000000  14 03 03 00 01 01 16 03  03 00 50 fa 85 cc bc dd  |..........P.....|
+00000010  0e 16 86 b1 5c 51 8a b9  cc 78 cd cd 64 5d 23 ca  |....\Q...x..d]#.|
+00000020  59 84 b3 42 dd ae a7 98  43 05 21 4f 35 43 75 5c  |Y..B....C.!O5Cu\|
+00000030  13 c8 e0 b6 66 0f 55 32  69 7a 8b 8f cd c2 37 38  |....f.U2iz....78|
+00000040  f6 fa 0b 66 cf 46 91 3e  9f f5 43 44 f5 c7 2b e1  |...f.F.>..CD..+.|
+00000050  39 3a f7 3c f2 03 c4 85  dc 58 66                 |9:.<.....Xf|
 >>> 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 1d 76 4c  fb 46 f8 02 9a bc 07 8d  |......vL.F......|
-00000020  b0 52 40 44 58 da ad be  3c a6 d7 44 0f 59 98 f3  |.R@DX...<..D.Y..|
-00000030  ae 5c d2 04 bb 07 ee f6  99 9d 2c 14 44 3b 90 bc  |.\........,.D;..|
-00000040  2b e9 bc 37 59 15 03 03  00 40 00 00 00 00 00 00  |+..7Y....@......|
-00000050  00 00 00 00 00 00 00 00  00 00 c4 ef 97 87 35 a2  |..............5.|
-00000060  2f cc c2 6f 3d d5 f5 6f  fd 74 56 50 37 f8 10 e8  |/..o=..o.tVP7...|
-00000070  36 f5 fb 6f 7b 5d 20 07  0d 2f 72 46 a7 3a e0 de  |6..o{] ../rF.:..|
-00000080  39 b3 76 0e 4f c0 e7 85  4b bb                    |9.v.O...K.|
+00000010  00 00 00 00 00 44 e6 99  40 ae 12 bc d9 92 c5 ae  |.....D..@.......|
+00000020  fb 4d 5f 64 7a 77 0f 80  8e a4 be d0 ba ba 41 b1  |.M_dzw........A.|
+00000030  0d 40 e9 0e 50 32 dc 35  2d 5e 5c 8a ef 20 75 80  |.@..P2.5-^\.. u.|
+00000040  a0 e5 9c 61 49 15 03 03  00 40 00 00 00 00 00 00  |...aI....@......|
+00000050  00 00 00 00 00 00 00 00  00 00 57 91 40 2a a5 f7  |..........W.@*..|
+00000060  9f 29 0f 02 8e 50 ac 4b  2e 55 9a 78 72 f0 d7 c5  |.)...P.K.U.xr...|
+00000070  3b f2 cd 28 4d 8b 49 d8  50 a6 22 96 de df 16 d6  |;..(M.I.P.".....|
+00000080  61 4b 23 5c 5d de a1 0a  5b 16                    |aK#\]...[.|
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 90a1639..14af5ae 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
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 b8 16 bd ae 15  |....Y...U.......|
-00000010  a3 33 52 cc 60 dc 6c fe  7c f3 82 b9 1e 13 ab 87  |.3R.`.l.|.......|
-00000020  22 d8 c3 38 dc 8a 76 bb  a0 a3 fd 20 8a d1 92 d1  |"..8..v.... ....|
-00000030  d6 f3 76 e0 e2 76 32 95  32 a0 eb 5b dc e4 42 81  |..v..v2.2..[..B.|
-00000040  14 bb 58 ab b8 e8 9d ee  fa 32 58 05 c0 2c 00 00  |..X......2X..,..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 bb 8a 66 ee 44  |....Y...U....f.D|
+00000010  42 dc 59 c7 a7 7b a8 57  8e 63 21 f0 4e 31 f4 5c  |B.Y..{.W.c!.N1.\|
+00000020  1d d3 42 e5 de eb 8c 78  3a 01 01 20 9b 89 05 d6  |..B....x:.. ....|
+00000030  d2 07 38 8b 4c 5f 6d 62  9f 43 a0 cd d3 40 0f 77  |..8.L_mb.C...@.w|
+00000040  17 ff 43 4a 5c b3 8c 83  b7 4b c7 e7 c0 2c 00 00  |..CJ\....K...,..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -55,34 +55,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 5c 9b  |*............ \.|
-00000280  9b 29 5c 83 36 b8 20 47  2b 04 0d 1b ab f5 f7 81  |.)\.6. G+.......|
-00000290  aa 89 b4 93 37 aa 28 4e  44 e1 22 26 b6 46 04 03  |....7.(ND."&.F..|
-000002a0  00 8a 30 81 87 02 42 01  2c 87 df 1f 07 86 36 c8  |..0...B.,.....6.|
-000002b0  f6 aa 41 c1 8e 99 6e 12  08 5f e2 62 4b 3a 9b ad  |..A...n.._.bK:..|
-000002c0  e8 26 1c 95 f9 62 c6 f6  c7 e4 f7 db 3b 23 e5 4f  |.&...b......;#.O|
-000002d0  03 a1 c6 89 74 cb bd 2a  4e 47 3f 0f bf 28 bb 6d  |....t..*NG?..(.m|
-000002e0  c0 c6 53 4c 02 0b 9a 30  2d 02 41 0c 6f 26 a5 4c  |..SL...0-.A.o&.L|
-000002f0  b6 6c 8c ab 82 32 19 a0  f0 1b 41 2d 9d 1d 12 1b  |.l...2....A-....|
-00000300  91 62 6a 3d 17 92 79 f6  59 45 21 2f 6b d0 cb 7b  |.bj=..y.YE!/k..{|
-00000310  22 b3 79 80 90 90 81 97  06 c8 59 fd 8b 40 f9 ec  |".y.......Y..@..|
-00000320  80 58 db fc 5e a2 67 9a  96 01 53 d4 16 03 03 00  |.X..^.g...S.....|
-00000330  04 0e 00 00 00                                    |.....|
+00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 fd 71  |*............ .q|
+00000280  c1 3a 6a a3 69 6a 34 f3  02 c5 1d e5 db 63 f4 eb  |.:j.ij4......c..|
+00000290  97 4c 70 bc b3 4e 9d 2c  2f b2 b9 9d ac 3f 04 03  |.Lp..N.,/....?..|
+000002a0  00 8b 30 81 88 02 42 01  bd 9d ad 24 37 b9 60 55  |..0...B....$7.`U|
+000002b0  e4 cc bc 49 c3 88 3b ed  ac e4 42 8e fa 81 01 d9  |...I..;...B.....|
+000002c0  39 4c f0 1c 7d 39 a2 81  8a e1 17 0e 8d 37 76 96  |9L..}9.......7v.|
+000002d0  37 13 3a 1e 2e fd 0d 0a  3c 90 9d 43 3d 06 c0 b1  |7.:.....<..C=...|
+000002e0  4e 07 3e c3 9f f2 43 40  0b 02 42 01 d6 d0 20 ad  |N.>...C@..B... .|
+000002f0  48 09 c0 9b 5d c8 84 46  3b 98 37 9b 5a 91 4a 07  |H...]..F;.7.Z.J.|
+00000300  79 68 71 92 76 dc 70 0f  5c 44 7e 81 c3 c6 3f 19  |yhq.v.p.\D~...?.|
+00000310  f4 0f 6a 0b aa cc bb 65  e7 34 b5 e9 67 2d 32 98  |..j....e.4..g-2.|
+00000320  1c f6 76 4c 96 73 df 21  d6 e1 ea 34 86 16 03 03  |..vL.s.!...4....|
+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 17 be e6  |....(...........|
-00000040  ba 39 2d 82 38 6e 09 2c  1c ef d5 1f ad 8e e0 47  |.9-.8n.,.......G|
-00000050  2d bc 74 f8 3b ed 86 89  9e e9 a5 01 40           |-.t.;.......@|
+00000030  16 03 03 00 28 00 00 00  00 00 00 00 00 27 fd 98  |....(........'..|
+00000040  47 79 56 f9 e8 0e fd 18  c2 8f 2d 32 51 f7 19 b5  |GyV.......-2Q...|
+00000050  ab 2f 81 ed b6 cf 6f b5  65 81 81 f1 44           |./....o.e...D|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 42 3b b0 5e 66  |..........(B;.^f|
-00000010  3e ef a5 3d 49 64 42 34  b1 21 d6 43 d3 f6 f5 84  |>..=IdB4.!.C....|
-00000020  21 96 b4 7b ed 73 b5 23  b6 40 cf 86 ab 71 59 58  |!..{.s.#.@...qYX|
-00000030  3a bf 79                                          |:.y|
+00000000  14 03 03 00 01 01 16 03  03 00 28 a9 b7 63 61 57  |..........(..caW|
+00000010  54 57 f0 b2 60 58 e3 dc  6e e1 40 3e 67 b4 99 8f  |TW..`X..n.@>g...|
+00000020  e9 6b 11 f1 1a 54 bd c1  d3 b9 5b 01 12 27 a4 0b  |.k...T....[..'..|
+00000030  e9 ec 01                                          |...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 8d 3c f7  |..............<.|
-00000010  9e da 91 15 35 10 5f a4  29 32 3f 6a 8c 1d bc 13  |....5._.)2?j....|
-00000020  8a 35 2b 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.5+.............|
-00000030  1f b3 e3 e3 24 ac 7a a6  ee 81 e7 cc 9e 70 34 2c  |....$.z......p4,|
-00000040  d2 28                                             |.(|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 e0 8a 6e  |...............n|
+00000010  62 5d e3 db 99 10 d2 53  b6 21 2e 79 31 cf 71 1d  |b].....S.!.y1.q.|
+00000020  34 71 2a 15 03 03 00 1a  00 00 00 00 00 00 00 02  |4q*.............|
+00000030  e7 4a 8d b9 2f 1b b1 70  72 da 7f d8 fa 4f 9f d6  |.J../..pr....O..|
+00000040  ca f3                                             |..|
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 1b3c37b..3113b3c 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-CHACHA20-POLY1305
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-CHACHA20-POLY1305
@@ -4,7 +4,7 @@
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 08 cc a9  |................|
-00000050  13 01 13 03 13 02 01 00  00 7b 00 05 00 05 01 00  |.........{......|
+00000050  13 03 13 01 13 02 01 00  00 7b 00 05 00 05 01 00  |.........{......|
 00000060  00 00 00 00 0a 00 0a 00  08 00 1d 00 17 00 18 00  |................|
 00000070  19 00 0b 00 02 01 00 00  0d 00 1a 00 18 08 04 04  |................|
 00000080  03 08 07 08 05 08 06 04  01 05 01 06 01 05 03 06  |................|
@@ -14,11 +14,11 @@
 000000c0  ac 5f bb 29 07 30 ff f6  84 af c4 cf c2 ed 90 99  |._.).0..........|
 000000d0  5f 58 cb 3b 74                                    |_X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 ea 73 50 31 e4  |....Y...U...sP1.|
-00000010  7a c7 e2 05 23 a0 22 e3  1a cd 6d b5 0f e7 f2 5e  |z...#."...m....^|
-00000020  d6 cb 6c 70 05 04 a9 63  4a a3 fc 20 a2 c5 68 f2  |..lp...cJ.. ..h.|
-00000030  9b 56 6e 83 66 c1 7f 85  02 b6 6d 37 12 0f 12 5a  |.Vn.f.....m7...Z|
-00000040  41 7e c3 c9 44 85 3c 00  50 6f c7 f9 cc a9 00 00  |A~..D.<.Po......|
+00000000  16 03 03 00 59 02 00 00  55 03 03 e1 cc 3c 49 04  |....Y...U....<I.|
+00000010  bb 5b 18 c7 44 8f 52 62  d9 74 84 94 fa 61 3f 12  |.[..D.Rb.t...a?.|
+00000020  c8 23 50 0b 8a 5c 81 23  c2 9d 3d 20 1f b2 67 b0  |.#P..\.#..= ..g.|
+00000030  e9 2d a9 ed 35 4e ab b9  73 59 32 2f 49 ed 1e 60  |.-..5N..sY2/I..`|
+00000040  4c 31 11 6e 27 79 e0 62  e0 e4 ca 16 cc a9 00 00  |L1.n'y.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....|
@@ -53,32 +53,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 a4 6a  |*............ .j|
-00000280  0d ab f2 7c 1a 31 2a 7d  51 b7 fe 69 cd 59 f5 c1  |...|.1*}Q..i.Y..|
-00000290  10 94 a0 b2 6f 6f c4 48  48 9b 20 1e 46 2a 04 03  |....oo.HH. .F*..|
-000002a0  00 8b 30 81 88 02 42 00  84 2a 96 88 a4 7a 86 7f  |..0...B..*...z..|
-000002b0  cf 86 20 37 17 de 54 0c  c2 89 5e 27 f4 3b a4 ec  |.. 7..T...^'.;..|
-000002c0  ce 25 34 4e c7 a8 7d f5  56 6d 96 2c d0 53 ae 42  |.%4N..}.Vm.,.S.B|
-000002d0  b5 87 a9 20 9c 4f c9 67  7e ca f6 fc 2f 61 72 35  |... .O.g~.../ar5|
-000002e0  78 fe 54 32 1e a1 90 88  c2 02 42 01 a6 7b 98 de  |x.T2......B..{..|
-000002f0  fd 01 4b 4a 8f 1a e8 18  dd 07 bb 0b 38 41 7f 22  |..KJ........8A."|
-00000300  62 3b 7e 37 67 b7 18 46  a7 32 43 1b c9 a9 8a a6  |b;~7g..F.2C.....|
-00000310  d7 8a 2f 7b c5 14 f3 33  96 fe 0a fc 22 d0 a5 02  |../{...3...."...|
-00000320  37 a5 31 5f b9 6b d2 3b  f6 d0 d1 7b a1 16 03 03  |7.1_.k.;...{....|
-00000330  00 04 0e 00 00 00                                 |......|
+00000270  2a 16 03 03 00 b6 0c 00  00 b2 03 00 1d 20 cc a1  |*............ ..|
+00000280  4d a4 b1 22 86 e5 91 9b  e2 1a 28 c6 66 06 1a 89  |M.."......(.f...|
+00000290  a9 62 23 93 09 54 ae 67  a8 ab 18 ac 67 37 04 03  |.b#..T.g....g7..|
+000002a0  00 8a 30 81 87 02 42 01  f0 46 f3 3f 13 a7 1d 84  |..0...B..F.?....|
+000002b0  73 65 9e 91 16 6c 3d 8f  21 ab 17 db 24 34 21 8c  |se...l=.!...$4!.|
+000002c0  a9 e1 9b a6 17 c8 0d 7a  b4 8e f0 46 cd c5 b9 b2  |.......z...F....|
+000002d0  5e 64 7f 9f 9d 03 14 7a  23 5d 55 70 ae d1 ff 08  |^d.....z#]Up....|
+000002e0  e8 70 f5 5d 55 90 74 04  0d 02 41 09 ca 7d 60 ea  |.p.]U.t...A..}`.|
+000002f0  13 17 42 e8 53 e7 c5 31  15 4a 58 14 d6 54 f5 40  |..B.S..1.JX..T.@|
+00000300  a1 aa fe 4b 13 f5 29 04  05 cc 12 26 e2 b7 e5 a6  |...K..)....&....|
+00000310  90 7c 5e 66 2f ed 41 7c  97 a1 72 87 5e 46 5a 5b  |.|^f/.A|..r.^FZ[|
+00000320  1b d1 7b 3c 34 ba 3f 47  7d a9 84 33 16 03 03 00  |..{<4.?G}..3....|
+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 f5 a0 28  0a 7e d4 8b a2 b6 e1 af  |.... ..(.~......|
-00000040  83 e2 50 e8 fc 7e f0 59  21 ed 3d 0d a8 ef a9 b1  |..P..~.Y!.=.....|
-00000050  5a 13 2a 1b 2c                                    |Z.*.,|
+00000030  16 03 03 00 20 7f ab 78  f0 a6 b6 57 bd c3 b9 32  |.... ..x...W...2|
+00000040  96 3f 7c 9d a0 4d dc 74  c9 e8 1a 88 c4 b2 10 27  |.?|..M.t.......'|
+00000050  e3 9c 1e 9b e1                                    |.....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 44 15 68 4d e0  |.......... D.hM.|
-00000010  3b 34 c5 77 b2 25 f2 e9  35 75 08 f5 a9 53 c9 65  |;4.w.%..5u...S.e|
-00000020  19 36 49 fe 43 e4 f5 48  ac 7c d7                 |.6I.C..H.|.|
+00000000  14 03 03 00 01 01 16 03  03 00 20 0c b7 0c 47 8e  |.......... ...G.|
+00000010  40 6b 9f 9c d2 cd 24 25  db 12 e8 0c 50 be f3 98  |@k....$%....P...|
+00000020  4a 6f f9 42 58 07 b9 64  d0 00 91                 |Jo.BX..d...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 f7 fd 2a  83 90 01 f3 d2 82 dc bd  |.......*........|
-00000010  6c 33 31 a3 92 0f a4 f5  9c fa f4 15 03 03 00 12  |l31.............|
-00000020  9e 60 18 02 f1 0d 2f f5  5f 68 69 ae 62 93 04 6a  |.`..../._hi.b..j|
-00000030  41 f0                                             |A.|
+00000000  17 03 03 00 16 1d 32 1c  ef 0b 1f a4 ba 39 a3 63  |......2......9.c|
+00000010  04 29 e5 67 1e bb 5a 6e  c7 3c c1 15 03 03 00 12  |.).g..Zn.<......|
+00000020  0e 0b 0f 49 30 fe d4 c3  35 85 e3 db 6e 65 e3 2d  |...I0...5...ne.-|
+00000030  d1 1d                                             |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
index eff5b97..ea6c787 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 f1 07 97 47 f7  |....Y...U.....G.|
-00000010  b8 42 f5 ce 2b b5 ec 5a  d3 74 f1 fa 1f ea ec 6d  |.B..+..Z.t.....m|
-00000020  49 4e cf 2e 47 8b 2e 80  9b 8a ed 20 89 ca 35 4a  |IN..G...... ..5J|
-00000030  f4 35 5e b7 ed b2 96 ad  e1 66 1d 43 9d 07 ba ed  |.5^......f.C....|
-00000040  ff 9d 47 65 c8 7d 91 32  4b 88 4d 83 c0 13 00 00  |..Ge.}.2K.M.....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 1e 2f 6f fa 02  |....Y...U.../o..|
+00000010  44 3e 0d d0 3e b5 e6 0c  a2 d6 aa 04 5b ba 93 39  |D>..>.......[..9|
+00000020  29 dd e7 7e b8 11 f9 85  97 a5 e4 20 9c 64 e9 47  |)..~....... .d.G|
+00000030  cb 7c 0c 77 9d 83 5a c4  e8 05 62 40 95 8e 8e aa  |.|.w..Z...b@....|
+00000040  39 bb 24 8f b7 29 75 77  18 66 60 29 c0 13 00 00  |9.$..)uw.f`)....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,38 +60,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 78 22 92 20 a9 be 78  |........ x". ..x|
-000002d0  12 0f e6 83 13 3d 13 91  16 11 ca 26 9f b7 37 d5  |.....=.....&..7.|
-000002e0  f0 97 f9 f2 01 fd 08 4f  42 08 04 00 80 2c f1 4e  |.......OB....,.N|
-000002f0  79 63 f2 d9 54 1c 0c 56  fd 56 4d e0 37 ee 5d bb  |yc..T..V.VM.7.].|
-00000300  22 90 fd ee d9 0f e6 d9  85 41 b9 8d d6 76 5f 05  |"........A...v_.|
-00000310  1b 8c d7 4e c5 e8 4e 69  b9 5d de 73 c0 ed 4f 3e  |...N..Ni.].s..O>|
-00000320  09 9d b0 10 d6 61 87 d8  f9 c2 5b 48 f9 ef dd 65  |.....a....[H...e|
-00000330  e6 f8 b0 d2 71 f6 e9 ae  b1 c0 ea 90 dc 33 c6 72  |....q........3.r|
-00000340  3e 9f 31 d4 ae 78 23 54  7a 4f 02 69 72 c1 06 2f  |>.1..x#TzO.ir../|
-00000350  3f 3c 7b f2 d8 17 40 a6  95 6d 46 62 6b 54 f1 cf  |?<{...@..mFbkT..|
-00000360  60 08 63 89 f7 a5 2a 52  3b 0e 0c d6 34 16 03 03  |`.c...*R;...4...|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 92 ed 81 60 d9 51 c2  |........ ...`.Q.|
+000002d0  00 3d 99 84 82 c5 83 67  60 b3 11 59 0c c5 5d ff  |.=.....g`..Y..].|
+000002e0  d6 28 79 68 2d 73 7f 84  40 08 04 00 80 b6 a0 4b  |.(yh-s..@......K|
+000002f0  3d fb e1 e6 76 cc ae e3  59 d0 1c 50 5c 09 5d 80  |=...v...Y..P\.].|
+00000300  c2 58 0d 36 d7 1a 78 e3  c2 66 73 3a 14 06 37 6f  |.X.6..x..fs:..7o|
+00000310  3a 95 2e 2a eb cc e5 e3  f7 30 eb 0d 33 04 51 6e  |:..*.....0..3.Qn|
+00000320  06 86 8f 53 6d fd 97 75  b3 13 2e 4e ee 8f 03 68  |...Sm..u...N...h|
+00000330  23 32 83 96 af 01 ed b0  21 a7 13 06 47 f4 08 b9  |#2......!...G...|
+00000340  8a 47 cc 12 99 20 c6 31  77 28 2c 2e d6 a0 20 8c  |.G... .1w(,... .|
+00000350  e6 67 c7 70 23 ed 98 9c  c9 47 1c e0 37 95 42 aa  |.g.p#....G..7.B.|
+00000360  c2 19 1b 55 09 5c 58 fb  ef 67 a9 b5 65 16 03 03  |...U.\X..g..e...|
 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 96 55 d3  bd a1 b6 de 93 68 19 ed  |......U......h..|
-00000050  4a 3a cc 42 7c c4 41 1e  b5 37 65 d5 84 10 60 3d  |J:.B|.A..7e...`=|
-00000060  e9 57 29 28 79 54 da 6c  1b 36 6b b1 75 f4 bb 32  |.W)(yT.l.6k.u..2|
-00000070  47 8d de c8 7d                                    |G...}|
+00000040  00 00 00 00 00 dd 81 23  e0 a3 01 33 bb 87 0d 93  |.......#...3....|
+00000050  b2 61 16 01 e3 87 e0 05  cc b0 ec 15 56 df ff 9c  |.a..........V...|
+00000060  e6 9c 6a 57 79 8a 0b 86  f9 fb 60 3f ca 0d ef f2  |..jWy.....`?....|
+00000070  81 c0 5e 22 bf                                    |..^".|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 db ed ec 54 4a  |..........@...TJ|
-00000010  20 d8 a7 ee 12 04 e2 e4  95 b4 a4 a7 e1 80 c8 40  | ..............@|
-00000020  81 00 6d 3e 58 26 7c d4  26 84 86 ee b4 fc c5 50  |..m>X&|.&......P|
-00000030  46 31 e7 4c 1e fd ed 10  7e 72 45 18 43 db 4c 0d  |F1.L....~rE.C.L.|
-00000040  b5 49 6c 31 04 f0 85 a7  f8 02 e1                 |.Il1.......|
+00000000  14 03 03 00 01 01 16 03  03 00 40 d4 d3 ba 7f 4c  |..........@....L|
+00000010  1a ee d9 ca 66 a0 5b d7  08 78 5d 5c fd 17 32 71  |....f.[..x]\..2q|
+00000020  7f 8c 2e eb 80 bc 82 0f  0c ed 71 ac 34 59 71 d1  |..........q.4Yq.|
+00000030  aa d3 fd 0c 50 7d 4b 1b  01 5d 4c 03 9f 6c 16 8f  |....P}K..]L..l..|
+00000040  5d f7 8d c0 4b 3f 01 96  23 40 22                 |]...K?..#@"|
 >>> 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 90 f7 06  a7 05 8d de 51 21 88 95  |............Q!..|
-00000020  47 61 fb 8d a9 c9 6d 59  ca 92 8d 07 8b 9d 82 4e  |Ga....mY.......N|
-00000030  fd e9 ae 3d b0 15 03 03  00 30 00 00 00 00 00 00  |...=.....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 12 77 0c 5f 12 4b  |...........w._.K|
-00000050  96 ab 64 58 6e f5 82 09  6c 18 ae 1f a2 fb 0a 3b  |..dXn...l......;|
-00000060  71 17 25 8b c8 72 d0 13  fb e8                    |q.%..r....|
+00000010  00 00 00 00 00 36 49 0e  f6 26 13 f7 69 15 54 27  |.....6I..&..i.T'|
+00000020  5a e6 f2 fb 7d ad e0 30  d3 cd ed 08 24 74 5f 77  |Z...}..0....$t_w|
+00000030  f7 8b 3f bf 94 15 03 03  00 30 00 00 00 00 00 00  |..?......0......|
+00000040  00 00 00 00 00 00 00 00  00 00 28 09 ed 2f d8 6f  |..........(../.o|
+00000050  95 fc db 9e ec d8 81 7e  a4 d4 8e c5 ec d3 24 bc  |.......~......$.|
+00000060  ab 52 e6 01 75 98 b9 e5  9f d9                    |.R..u.....|
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 4f8f49e..88d0d01 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES128-SHA256
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES128-SHA256
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 9e d4 c1 3e c6  |....Y...U.....>.|
-00000010  3d 44 eb a7 b8 c5 c8 e0  ab 16 06 83 67 5e b2 d6  |=D..........g^..|
-00000020  67 50 4b f3 24 17 97 19  76 7e 71 20 5a 2b dc 15  |gPK.$...v~q Z+..|
-00000030  87 37 be bb c7 9c 38 cd  3e 55 4e 33 32 a0 01 1b  |.7....8.>UN32...|
-00000040  79 13 87 6a 19 09 42 4c  fb 59 97 a8 c0 27 00 00  |y..j..BL.Y...'..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 e6 04 5e a9 bb  |....Y...U....^..|
+00000010  23 56 bd cc e7 72 9f 10  b1 fc 23 48 22 19 cb 27  |#V...r....#H"..'|
+00000020  3e c4 22 ec b9 7a 9c 81  60 c5 55 20 b9 7f 8a 0e  |>."..z..`.U ....|
+00000030  6b d6 cf cb 35 85 52 f3  9f 28 00 87 22 88 6d 7c  |k...5.R..(..".m||
+00000040  35 0e f6 af 7c 28 b4 71  cc 46 c1 b5 c0 27 00 00  |5...|(.q.F...'..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,42 +60,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 57 62 97 e9 c8 c6 17  |........ Wb.....|
-000002d0  73 d2 9e 31 a6 f8 be 03  65 86 af 6b e2 64 bf 7c  |s..1....e..k.d.||
-000002e0  4a f1 b9 fb 84 21 10 76  66 08 04 00 80 2d 08 24  |J....!.vf....-.$|
-000002f0  06 2a a3 c5 28 c4 22 5b  fe 79 4f 91 56 9e 40 6f  |.*..(."[.yO.V.@o|
-00000300  e6 0c e8 70 e0 35 9e 55  91 51 86 ec ad ff 6b 3f  |...p.5.U.Q....k?|
-00000310  a7 19 fa 6f 74 47 8a 86  04 b5 8a f0 0a d5 e5 5f  |...otG........._|
-00000320  ea 30 cc 79 77 3d ac 99  da 41 7f 25 3b da cd da  |.0.yw=...A.%;...|
-00000330  aa 4e 2a 54 b5 d3 13 4f  e4 e9 cb 76 86 fb 0b b5  |.N*T...O...v....|
-00000340  0d a3 be ab d2 e6 6e f6  77 7c 60 a7 50 56 43 60  |......n.w|`.PVC`|
-00000350  95 ba 95 c4 b5 1a 8d 6a  f7 a5 9f 03 27 93 9f 23  |.......j....'..#|
-00000360  44 27 88 f0 d5 51 0f ba  43 84 5c 02 14 16 03 03  |D'...Q..C.\.....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 55 af 53 a0 54 77 df  |........ U.S.Tw.|
+000002d0  ca 8f 49 1a 4d d0 9b 24  a6 a9 2b b2 2a 33 46 b8  |..I.M..$..+.*3F.|
+000002e0  01 d6 4e fd fb c1 e4 e6  64 08 04 00 80 5c da 2f  |..N.....d....\./|
+000002f0  01 2b 10 b9 e9 35 f2 b1  2a 28 4f 78 58 7b 3d 9a  |.+...5..*(OxX{=.|
+00000300  13 e4 7c 77 41 95 fa 7a  90 1f eb f5 20 55 7c 76  |..|wA..z.... U|v|
+00000310  dd c5 66 08 88 eb ba 17  f0 de f3 0c a5 a6 3c 21  |..f...........<!|
+00000320  52 89 25 b1 4d 86 e3 0b  8a 14 dc 8b a6 76 41 25  |R.%.M........vA%|
+00000330  9e d3 20 b6 61 8a 26 8b  0d b7 cb 98 ac 45 e0 3b  |.. .a.&......E.;|
+00000340  6f d6 b2 52 8b a2 31 63  c8 44 1d 2a 3a c1 35 87  |o..R..1c.D.*:.5.|
+00000350  7a 7b 2a fa dd ab d3 48  9b e2 fa e1 93 7c 09 f7  |z{*....H.....|..|
+00000360  e1 72 83 f8 23 07 30 3a  4a 4f 56 97 1b 16 03 03  |.r..#.0:JOV.....|
 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 02 19 fd  3e 06 0d 12 0d 03 42 da  |........>.....B.|
-00000050  76 6f e2 e3 96 eb 42 d9  96 b7 0b ae d6 a0 06 fa  |vo....B.........|
-00000060  57 4e ff 62 85 dd 3f ab  63 f9 73 87 8d 71 6a c6  |WN.b..?.c.s..qj.|
-00000070  f4 ef ce f5 55 5b d2 1f  b5 33 fd 12 32 bd 5e 1e  |....U[...3..2.^.|
-00000080  d5 32 91 9a ae                                    |.2...|
+00000040  00 00 00 00 00 91 c1 82  23 f0 03 79 83 38 ef d0  |........#..y.8..|
+00000050  73 71 9b 7d 55 5e 53 3b  d3 cf 86 48 60 2f 42 97  |sq.}U^S;...H`/B.|
+00000060  63 e8 4b 20 4c 92 3e 2f  aa b3 32 46 8a 96 69 42  |c.K L.>/..2F..iB|
+00000070  96 9a 4b bd 04 f2 3d b6  5f f9 37 4f a4 3d f1 cb  |..K...=._.7O.=..|
+00000080  d5 57 fc 5e 8e                                    |.W.^.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 50 77 80 95 42 a3  |..........Pw..B.|
-00000010  2b 1c 16 0f 3b f4 78 2a  bd ab 6e d1 33 1e 0e a5  |+...;.x*..n.3...|
-00000020  c7 f4 e9 92 82 00 da 44  0f b6 4e f9 1f ef 67 3b  |.......D..N...g;|
-00000030  de 5c dc 93 07 68 99 1a  70 7f 92 a7 d7 da f3 60  |.\...h..p......`|
-00000040  cf d5 f1 f0 5e 75 68 a1  0b 32 eb d2 96 de e6 34  |....^uh..2.....4|
-00000050  c3 e3 26 43 1f a2 8d e7  1b fc 76                 |..&C......v|
+00000000  14 03 03 00 01 01 16 03  03 00 50 e1 91 69 dc 7b  |..........P..i.{|
+00000010  5f a4 c7 7a 8f ba bb 8d  98 c3 0e 3f 10 f1 3e 3f  |_..z.......?..>?|
+00000020  37 6f 11 81 3f c5 7c 22  6f 22 a3 94 ae 3a 77 17  |7o..?.|"o"...:w.|
+00000030  a2 7b cc 8e 5e 6e 9b 4b  98 fd 16 f8 46 9e 78 19  |.{..^n.K....F.x.|
+00000040  43 e6 da e3 05 9a 0a 49  b0 09 c7 e5 4b 41 dc b4  |C......I....KA..|
+00000050  c0 81 9b 46 7e dd c3 64  2e f8 6e                 |...F~..d..n|
 >>> 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 f8 35 11  b8 23 cf d9 ec a7 d3 b9  |......5..#......|
-00000020  60 1e 34 01 20 49 73 ec  72 78 58 24 3b fc a8 42  |`.4. Is.rxX$;..B|
-00000030  b2 a9 69 69 40 65 5a c2  8b 9f 0b 0e 70 ab ac 22  |..ii@eZ.....p.."|
-00000040  1a ac d6 04 06 15 03 03  00 40 00 00 00 00 00 00  |.........@......|
-00000050  00 00 00 00 00 00 00 00  00 00 fe ed 19 a0 84 06  |................|
-00000060  8b f0 e8 4e 30 7a 3c 89  a0 a8 59 74 a5 92 73 f3  |...N0z<...Yt..s.|
-00000070  df 1b f0 c6 5a 95 d5 1c  b6 57 4a 1b 8f 24 59 87  |....Z....WJ..$Y.|
-00000080  b4 2b 7f 6f 89 03 e8 6d  e5 d9                    |.+.o...m..|
+00000010  00 00 00 00 00 65 4c 71  31 d4 47 4d 0b 81 1f 75  |.....eLq1.GM...u|
+00000020  b6 71 64 4a e6 a8 80 a1  f1 e2 0a 14 77 af a4 c6  |.qdJ........w...|
+00000030  1d 6a 7d 79 6a 15 a1 0e  86 6c 8e e1 32 64 0b 5d  |.j}yj....l..2d.]|
+00000040  af e0 f5 05 91 15 03 03  00 40 00 00 00 00 00 00  |.........@......|
+00000050  00 00 00 00 00 00 00 00  00 00 ca 46 1b 95 2a 41  |...........F..*A|
+00000060  ce dc 30 d6 e0 cf 2f 2b  1f 61 81 33 a4 58 e7 af  |..0.../+.a.3.X..|
+00000070  90 9c 15 42 9b ab 26 64  d1 39 46 45 6b 74 b9 c4  |...B..&d.9FEkt..|
+00000080  21 d9 ef 2d 69 51 dc e7  8a 6b                    |!..-iQ...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 38fb4a0..2c2cb45 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-CHACHA20-POLY1305
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-CHACHA20-POLY1305
@@ -4,7 +4,7 @@
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 08 cc a8  |................|
-00000050  13 01 13 03 13 02 01 00  00 7b 00 05 00 05 01 00  |.........{......|
+00000050  13 03 13 01 13 02 01 00  00 7b 00 05 00 05 01 00  |.........{......|
 00000060  00 00 00 00 0a 00 0a 00  08 00 1d 00 17 00 18 00  |................|
 00000070  19 00 0b 00 02 01 00 00  0d 00 1a 00 18 08 04 04  |................|
 00000080  03 08 07 08 05 08 06 04  01 05 01 06 01 05 03 06  |................|
@@ -14,11 +14,11 @@
 000000c0  ac 5f bb 29 07 30 ff f6  84 af c4 cf c2 ed 90 99  |._.).0..........|
 000000d0  5f 58 cb 3b 74                                    |_X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 4e fb dc 04 6f  |....Y...U..N...o|
-00000010  5a 52 37 a3 55 58 26 e5  cd a0 67 4c 0f 87 1a 3a  |ZR7.UX&...gL...:|
-00000020  f6 84 33 2f 2e 52 d0 48  7c 5b 64 20 6e d0 bc ca  |..3/.R.H|[d n...|
-00000030  c9 a5 87 8d 99 c5 ec 85  84 89 f0 22 ab 63 55 f4  |...........".cU.|
-00000040  70 d7 02 93 b5 fe d7 38  fb c1 b2 da cc a8 00 00  |p......8........|
+00000000  16 03 03 00 59 02 00 00  55 03 03 2a 76 db 4b d5  |....Y...U..*v.K.|
+00000010  10 f3 21 f2 4b 29 a2 2e  7a 7d 0b 86 c4 af 60 95  |..!.K)..z}....`.|
+00000020  5b 11 84 27 8a 59 7f af  a0 27 de 20 02 f7 dc 9b  |[..'.Y...'. ....|
+00000030  63 8e 2e da 48 b5 73 81  8e 76 13 da dd 2e 17 2b  |c...H.s..v.....+|
+00000040  ff 18 ad d7 9d f3 44 ed  b6 60 0e 42 cc a8 00 00  |......D..`.B....|
 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..............|
@@ -58,31 +58,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 fc 4b 92 ab d2 cb 4f  |........ .K....O|
-000002d0  61 aa 86 12 1a 1d 75 be  31 dd b8 ee 6c a6 db bd  |a.....u.1...l...|
-000002e0  0b ea b2 d5 27 49 42 eb  5a 08 04 00 80 02 ad 71  |....'IB.Z......q|
-000002f0  e2 e8 f6 44 3c a6 18 6f  76 ee 9a eb 0e d9 ff cb  |...D<..ov.......|
-00000300  6d 1e 64 dd 29 1d 8c c8  f6 14 40 c0 12 46 74 4c  |m.d.).....@..FtL|
-00000310  41 2d 71 5f 9c b7 86 0b  fc 66 1e 14 cb 26 d0 d7  |A-q_.....f...&..|
-00000320  21 b4 bd c2 04 38 77 90  6a f0 01 18 bd 1c 17 45  |!....8w.j......E|
-00000330  7e 38 46 4c 2e 97 ba 11  01 1f 20 cc df f2 6b 5b  |~8FL...... ...k[|
-00000340  a7 29 c0 52 52 9c 2f 23  bd 1c 72 c2 f2 99 d1 dc  |.).RR./#..r.....|
-00000350  6a 6c ac 8e 87 8a 00 74  47 2e 99 8d 3f 79 04 60  |jl.....tG...?y.`|
-00000360  5e dc ba 86 1c f4 f9 03  22 38 96 a7 b3 16 03 03  |^......."8......|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 0d c3 c2 b5 73 da 39  |........ ....s.9|
+000002d0  82 e5 8c 18 0d 8d 16 c2  a5 e7 3e 39 fd 25 00 18  |..........>9.%..|
+000002e0  25 16 c0 a7 6e c6 dd bb  01 08 04 00 80 b3 bd 01  |%...n...........|
+000002f0  ae dd b1 c8 2a 5d 0e 66  6d 1e b3 92 f4 01 63 59  |....*].fm.....cY|
+00000300  0c c1 62 df 75 8f 4f 19  5a cf 2f 63 79 d0 06 31  |..b.u.O.Z./cy..1|
+00000310  c0 60 6a 4f db 70 18 bd  80 8b 30 94 40 dd 13 39  |.`jO.p....0.@..9|
+00000320  4f db 2b 54 a4 97 f7 ef  a5 a3 ff f5 14 3d e2 2d  |O.+T.........=.-|
+00000330  0c 0e 71 4a bd a8 59 48  ab 06 55 53 45 2a ee 3e  |..qJ..YH..USE*.>|
+00000340  65 1f 47 ee 8d e3 f6 4e  2e b1 4c d0 af 50 15 02  |e.G....N..L..P..|
+00000350  5e 84 fe 76 d5 f3 c5 fb  2a 91 44 f0 92 32 ee ea  |^..v....*.D..2..|
+00000360  a0 26 77 5c 94 88 24 e3  2f 75 e3 fd b7 16 03 03  |.&w\..$./u......|
 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 0a 17 ee  70 8c 50 24 7c 00 b9 6f  |.... ...p.P$|..o|
-00000040  82 71 ed 2b 8c 0b 4b ff  bb 38 bc 12 7e 0c a5 3e  |.q.+..K..8..~..>|
-00000050  71 a2 ad f8 52                                    |q...R|
+00000030  16 03 03 00 20 0b 58 fe  b5 63 ac 28 f8 34 d6 72  |.... .X..c.(.4.r|
+00000040  1a a3 ec 26 91 70 07 8d  6a 3a 3b 3a 94 5e a3 fa  |...&.p..j:;:.^..|
+00000050  6e 92 3a 15 65                                    |n.:.e|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 e9 87 55 12 a8  |.......... ..U..|
-00000010  ad 68 42 0c 60 12 be 2f  2c e5 00 2d 01 cf 86 a2  |.hB.`../,..-....|
-00000020  1b 06 b3 86 bf 88 48 73  7a d3 cc                 |......Hsz..|
+00000000  14 03 03 00 01 01 16 03  03 00 20 01 fa e1 2f 29  |.......... .../)|
+00000010  ee f6 d4 e8 22 b6 e0 8f  82 37 81 83 1b 03 4d 5f  |...."....7....M_|
+00000020  00 80 cb eb 9a 3a 01 c7  aa e9 9a                 |.....:.....|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 96 75 4c  c6 ba b1 ad ae 2f 44 9d  |......uL...../D.|
-00000010  10 c3 ef e5 dc fb 0a 3e  af 6b 6a 15 03 03 00 12  |.......>.kj.....|
-00000020  30 13 8f e5 a1 0f 38 67  b9 53 4e 6a 66 ec ee 45  |0.....8g.SNjf..E|
-00000030  c2 b2                                             |..|
+00000000  17 03 03 00 16 43 6a e8  f2 ca f9 4f 3c 6d ff 5e  |.....Cj....O<m.^|
+00000010  f3 19 eb ee 96 1c d8 68  c5 53 86 15 03 03 00 12  |.......h.S......|
+00000020  c2 72 4e 3c 33 93 fa f3  21 32 bb fd e3 c4 ef 1a  |.rN<3...!2......|
+00000030  46 df                                             |F.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-Ed25519 b/src/crypto/tls/testdata/Client-TLSv12-Ed25519
index 35513ad..72d564f 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-Ed25519
+++ b/src/crypto/tls/testdata/Client-TLSv12-Ed25519
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 66 49 2a a6 a4  |....Y...U..fI*..|
-00000010  75 60 58 bb 5f 5e 82 cd  e5 c0 9f 6d a4 fd 39 3b  |u`X._^.....m..9;|
-00000020  d9 17 80 14 89 ea 51 c1  b0 43 d6 20 b2 6b 72 81  |......Q..C. .kr.|
-00000030  f6 63 20 22 e2 b6 d2 61  aa 87 b6 67 ae 56 78 44  |.c "...a...g.VxD|
-00000040  5d 10 8c cf ea 32 cf 9e  92 e5 59 70 cc a9 00 00  |]....2....Yp....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 6c 5f 04 9e a6  |....Y...U..l_...|
+00000010  c6 41 0c ee a2 2c af 45  f0 bc de 67 2d 20 1c 9c  |.A...,.E...g- ..|
+00000020  82 33 fd 86 86 b3 50 04  77 ec da 20 f3 09 fb 8c  |.3....P.w.. ....|
+00000030  79 83 f9 82 58 b9 76 bb  d3 58 44 3d 52 0c 37 ae  |y...X.v..XD=R.7.|
+00000040  18 98 84 9a 56 af 5d 2b  68 68 c7 30 cc a9 00 00  |....V.]+hh.0....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 01 3c 0b 00 01 38 00  01 35 00 01 32 30 82 01  |..<...8..5..20..|
 00000070  2e 30 81 e1 a0 03 02 01  02 02 10 0f 43 1c 42 57  |.0..........C.BW|
@@ -42,27 +42,27 @@
 00000170  90 95 39 e5 0d c1 55 ff  2c 16 b7 1d fc ab 7d 4d  |..9...U.,.....}M|
 00000180  d4 e0 93 13 d0 a9 42 e0  b6 6b fe 5d 67 48 d7 9f  |......B..k.]gH..|
 00000190  50 bc 6c cd 4b 03 83 7c  f2 08 58 cd ac cf 0c 16  |P.l.K..|..X.....|
-000001a0  03 03 00 6c 0c 00 00 68  03 00 1d 20 c4 8c b8 a2  |...l...h... ....|
-000001b0  32 92 b8 22 1f 4c f1 96  00 64 35 47 4e f8 3d 08  |2..".L...d5GN.=.|
-000001c0  83 12 fe 95 a8 e4 8e c9  30 27 5c 39 08 07 00 40  |........0'\9...@|
-000001d0  7f 90 cf e0 87 69 e3 50  e6 fa 5e 28 a1 0f 79 0a  |.....i.P..^(..y.|
-000001e0  6e cf f4 87 e8 2f 55 b2  dd cb 5e 8f 9a 14 bd c2  |n..../U...^.....|
-000001f0  2b 2b 2d ed 72 40 23 5d  6d f4 89 3a ff 09 82 ec  |++-.r@#]m..:....|
-00000200  b6 4b 27 9a 08 ea e9 73  94 b4 31 1f e1 39 86 0e  |.K'....s..1..9..|
+000001a0  03 03 00 6c 0c 00 00 68  03 00 1d 20 a7 28 ef 3e  |...l...h... .(.>|
+000001b0  1c 65 9f 8e 9a 80 0b 7d  ac 9c ce d6 1e 97 54 30  |.e.....}......T0|
+000001c0  53 9b e6 0c 61 e0 ea 9c  ae 70 f2 78 08 07 00 40  |S...a....p.x...@|
+000001d0  0c 49 38 23 a0 75 28 fb  ec 71 a4 89 79 45 d1 ca  |.I8#.u(..q..yE..|
+000001e0  83 6f 5d dd 01 d4 c6 63  53 5d 6e 8f 06 09 80 a1  |.o]....cS]n.....|
+000001f0  f7 ef af 2d 29 af aa 10  86 1c 18 19 3f be bb 90  |...-).......?...|
+00000200  0e c3 9d 1e 6e 60 49 7f  fc c8 42 61 89 c2 e3 04  |....n`I...Ba....|
 00000210  16 03 03 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 8f 97 36  bd 59 ef 8e 2f 11 28 b0  |.... ..6.Y../.(.|
-00000040  d7 20 79 bf 04 07 45 f9  89 de b0 c7 55 1a ad 80  |. y...E.....U...|
-00000050  0f 8c ef 1d c6                                    |.....|
+00000030  16 03 03 00 20 b2 7f b6  1b 9c ec bf 2e ae a5 70  |.... ..........p|
+00000040  d5 33 9b 63 02 66 77 7d  00 ec 86 e4 bb d4 57 68  |.3.c.fw}......Wh|
+00000050  49 2a d3 be e7                                    |I*...|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 47 6c 1f 86 47  |.......... Gl..G|
-00000010  72 03 94 e0 43 f8 e5 ca  03 7d f5 d5 dd 70 05 f5  |r...C....}...p..|
-00000020  98 5d 51 b4 11 49 71 7a  fd 37 9a                 |.]Q..Iqz.7.|
+00000000  14 03 03 00 01 01 16 03  03 00 20 4c 7d ef ed ea  |.......... L}...|
+00000010  ab 8d 4f 38 46 6e 8f 56  b4 1d f2 1f 2c df 57 c0  |..O8Fn.V....,.W.|
+00000020  f9 8a c2 71 f8 6d df b7  c7 1e 23                 |...q.m....#|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 b7 a2 f5  8e 7c d3 7d 61 af 29 1c  |.........|.}a.).|
-00000010  77 0c 8d b4 5b d3 be 77  a6 a5 99 15 03 03 00 12  |w...[..w........|
-00000020  d8 23 dc a8 99 fe 1c 6e  f2 2f 41 8e df 40 11 4f  |.#.....n./A..@.O|
-00000030  6b 92                                             |k.|
+00000000  17 03 03 00 16 26 f1 7c  ee c8 3a 61 b0 f7 5a bd  |.....&.|..:a..Z.|
+00000010  b7 61 61 60 69 db cd ea  10 ee 63 15 03 03 00 12  |.aa`i.....c.....|
+00000020  22 c0 65 a4 5d 0e 48 9c  56 f8 54 17 82 5f 29 97  |".e.].H.V.T.._).|
+00000030  be 6b                                             |.k|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial b/src/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial
index c900aa6..adf1f72 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial
+++ b/src/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 7c c1 7b 30 03  |....Y...U..|.{0.|
-00000010  3c d7 63 5f 47 1c b1 13  56 56 b4 fd 55 e2 27 3e  |<.c_G...VV..U.'>|
-00000020  39 bb ce 9b 5b 2c 1e 17  33 e1 da 20 65 8b 26 42  |9...[,..3.. e.&B|
-00000030  a4 38 29 c7 9a 25 13 fc  1d 69 cb 10 63 c6 26 fc  |.8)..%...i..c.&.|
-00000040  f4 46 64 31 28 06 b3 a5  a4 c2 f6 5a cc a8 00 00  |.Fd1(......Z....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 79 92 2e 86 bc  |....Y...U..y....|
+00000010  c0 b7 56 2a 25 58 75 b3  25 ac 58 1d 8d 8e d5 87  |..V*%Xu.%.X.....|
+00000020  2d 67 8e 6e d4 d4 b6 67  b1 42 96 20 91 75 0b fa  |-g.n...g.B. .u..|
+00000030  d0 6f ab 91 4a c3 15 07  1d 6c 8e e5 55 f2 26 aa  |.o..J....l..U.&.|
+00000040  4d 5c 57 3b 93 a6 fc 46  c9 f6 80 1e cc a8 00 00  |M\W;...F........|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,31 +60,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 f7 a2 97 2f 50 e4 e2  |........ .../P..|
-000002d0  fa ef 80 67 78 1c aa 6c  03 aa 05 3b 6f 98 97 11  |...gx..l...;o...|
-000002e0  7e 55 3d 50 f3 a9 9b 21  65 08 04 00 80 34 4a 4b  |~U=P...!e....4JK|
-000002f0  4b 6e 86 01 1b 6b 8e 3e  84 01 75 b8 05 c3 b2 52  |Kn...k.>..u....R|
-00000300  16 ee ac 61 83 dd 09 32  d5 55 6a 5d d6 6b 4a 1a  |...a...2.Uj].kJ.|
-00000310  2b f7 09 33 6f 3d 4f c1  e3 aa 03 27 fe af cd 6d  |+..3o=O....'...m|
-00000320  b8 76 00 02 42 98 e6 f6  b7 ed fb 35 35 29 23 b1  |.v..B......55)#.|
-00000330  4d 48 0a ba a1 1b e3 8e  a2 cb 80 11 ec 92 20 df  |MH............ .|
-00000340  1f a4 5e 5d 70 85 8e 5d  85 62 81 1f b3 3a 0d 8d  |..^]p..].b...:..|
-00000350  9a 07 d3 99 a5 3c 6c c2  52 08 f0 be 50 ed d2 4d  |.....<l.R...P..M|
-00000360  44 ed e7 40 06 64 4e 17  fe 4a 0e 1b d6 16 03 03  |D..@.dN..J......|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 5f 3c a6 bb 4e 32 85  |........ _<..N2.|
+000002d0  69 4b 23 df 18 9c 07 ac  0b a8 dd 9b 59 33 00 02  |iK#.........Y3..|
+000002e0  99 de 4e 66 1e 04 3b ce  4b 08 04 00 80 82 41 7c  |..Nf..;.K.....A||
+000002f0  7b b8 ee d4 23 08 c3 23  8d b1 ea 27 43 e7 8e f1  |{...#..#...'C...|
+00000300  7b 87 b0 88 ab f7 b1 15  2e 45 c5 50 e7 cd 05 31  |{........E.P...1|
+00000310  bf 99 30 c8 ff 6a 23 ec  9d e5 c8 09 fa ec 50 a8  |..0..j#.......P.|
+00000320  fa b3 54 b7 c5 61 99 f6  94 12 e6 34 4a 59 e3 dd  |..T..a.....4JY..|
+00000330  e5 7f f4 88 c9 2a 4c 09  65 d9 75 a6 ce 12 96 82  |.....*L.e.u.....|
+00000340  a2 36 f2 5e 93 f2 4e 1c  05 91 a7 5a 67 36 e9 3d  |.6.^..N....Zg6.=|
+00000350  33 cd 6a 77 9c 8d 14 95  80 41 61 bd 80 ed 7b 51  |3.jw.....Aa...{Q|
+00000360  cf 76 87 4d ac dc 5f c1  5d 52 a7 f9 51 16 03 03  |.v.M.._.]R..Q...|
 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 30 8b ea  ef 6c 35 97 5b 26 5f ef  |.... 0...l5.[&_.|
-00000040  bc 28 fd e9 23 73 bb b3  ae 41 0c be 5f 83 a5 f7  |.(..#s...A.._...|
-00000050  96 07 8d 81 67                                    |....g|
+00000030  16 03 03 00 20 bc c3 7c  c2 cc a4 4e 8f d0 79 7a  |.... ..|...N..yz|
+00000040  a4 7d 4c 3d 17 8c 19 93  4f 49 03 50 f6 71 4d 16  |.}L=....OI.P.qM.|
+00000050  97 bb 18 88 67                                    |....g|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 29 fa a8 de f2  |.......... )....|
-00000010  8f 94 16 fc be 84 93 e9  34 98 c2 44 08 9b 2e 37  |........4..D...7|
-00000020  1f 41 61 53 fa 9c 23 ff  d8 6d c3                 |.AaS..#..m.|
+00000000  14 03 03 00 01 01 16 03  03 00 20 00 c4 8a f9 1e  |.......... .....|
+00000010  c0 66 ab ef 39 ae 41 7a  05 9c e3 06 e4 4d 00 bb  |.f..9.Az.....M..|
+00000020  d4 ef 21 71 a3 54 23 fe  db 4a 86                 |..!q.T#..J.|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 ab 6d 32  1c 16 cc 29 b1 21 4c b1  |......m2...).!L.|
-00000010  74 4c 50 e3 1f c5 f1 05  6a 8a 92 15 03 03 00 12  |tLP.....j.......|
-00000020  18 88 3d 23 81 d7 ba c5  1e 9a c4 3a 1b c8 cd 5b  |..=#.......:...[|
-00000030  c5 fa                                             |..|
+00000000  17 03 03 00 16 0c d3 9a  f5 1d f4 5f b2 45 c7 7c  |..........._.E.||
+00000010  38 59 6e df 6e 59 d5 94  8b a9 bb 15 03 03 00 12  |8Yn.nY..........|
+00000020  9e 74 a5 0e c1 7f 33 52  be 17 f6 f5 4d 9f 3d d1  |.t....3R....M.=.|
+00000030  b5 65                                             |.e|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-P256-ECDHE b/src/crypto/tls/testdata/Client-TLSv12-P256-ECDHE
index d75b670..3331435 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-P256-ECDHE
+++ b/src/crypto/tls/testdata/Client-TLSv12-P256-ECDHE
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 96 00 05 00 05  01 00 00 00 00 00 0a 00  |................|
 00000090  04 00 02 00 17 00 0b 00  02 01 00 00 0d 00 1a 00  |................|
 000000a0  18 08 04 04 03 08 07 08  05 08 06 04 01 05 01 06  |................|
@@ -18,11 +18,11 @@
 00000100  07 9f 6c 4b 5b 83 56 e2  32 42 e9 58 b6 d7 49 a6  |..lK[.V.2B.X..I.|
 00000110  b5 68 1a 41 03 56 6b dc  5a 89                    |.h.A.Vk.Z.|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 b8 7d f5 69 c3  |....Y...U...}.i.|
-00000010  6a ca 8b df f3 30 2c 39  47 2e 74 2e 4f 89 4c 1e  |j....0,9G.t.O.L.|
-00000020  f0 eb 10 0e 06 1d 2c 4e  de 2e 8f 20 6c a0 5b 66  |......,N... l.[f|
-00000030  fc a6 05 df 29 6b ce 72  92 e7 d7 78 f5 46 38 f9  |....)k.r...x.F8.|
-00000040  91 1c 9a 08 4c b1 9a 41  e5 0c d2 cd c0 2f 00 00  |....L..A...../..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 0b f0 3e a1 66  |....Y...U....>.f|
+00000010  13 35 53 83 59 3c 9e 2a  0f 0b b0 9a 42 de e4 f1  |.5S.Y<.*....B...|
+00000020  8a 2d 34 ef 15 fe 28 55  42 d8 bf 20 aa 27 5c 5f  |.-4...(UB.. .'\_|
+00000030  24 59 17 ef 43 f3 18 f8  40 97 8f 1a 6a f4 e4 4a  |$Y..C...@...j..J|
+00000040  a3 b7 11 39 01 bd 98 8c  61 08 d9 50 c0 2f 00 00  |...9....a..P./..|
 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..............|
@@ -62,19 +62,19 @@
 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  cd 0c 00 00 c9 03 00 17  41 04 3e 87 67 8b 87 08  |........A.>.g...|
-000002d0  fe 4e 4c c3 6b 42 4b 97  ad f4 1c 83 35 72 db 4f  |.NL.kBK.....5r.O|
-000002e0  39 83 ea 14 69 bb 8c 87  58 c5 a4 a8 8c d7 9d af  |9...i...X.......|
-000002f0  7a 5e 58 59 31 4d f2 01  4a 23 51 24 1b 04 0c e3  |z^XY1M..J#Q$....|
-00000300  94 9e 1b 6c ad aa 83 fd  2d 36 08 04 00 80 ab e9  |...l....-6......|
-00000310  ff 6d 7a cd 3b a7 da ff  d5 bd 27 49 68 53 f5 45  |.mz.;.....'IhS.E|
-00000320  c3 dd 5b a2 99 fb 8f 24  37 49 d3 08 87 d1 06 98  |..[....$7I......|
-00000330  39 72 25 78 b3 05 fb a2  c9 ac f9 c8 f7 fc ea 8a  |9r%x............|
-00000340  98 ce 78 83 64 f6 e0 c7  44 62 af a7 d5 26 df f1  |..x.d...Db...&..|
-00000350  2c cc ce 11 8b 03 4a e1  81 54 3f e1 6e 52 c9 1a  |,.....J..T?.nR..|
-00000360  d8 95 52 e0 3f a5 e3 c8  12 9a c7 57 5d 46 7a ce  |..R.?......W]Fz.|
-00000370  56 8a 90 0f 0d 1b ba 58  cf 1c a3 4b 39 5a 08 ee  |V......X...K9Z..|
-00000380  8a 61 bb 0f 7d f7 0e f2  1f 73 e0 c8 6f 54 16 03  |.a..}....s..oT..|
+000002c0  cd 0c 00 00 c9 03 00 17  41 04 79 6a df 70 26 49  |........A.yj.p&I|
+000002d0  c0 5a 39 fc 7c 80 d1 2c  cd 76 d0 4c 6f a7 7d bc  |.Z9.|..,.v.Lo.}.|
+000002e0  32 c6 54 c6 76 58 e2 0f  3f 33 ad 92 61 33 11 16  |2.T.vX..?3..a3..|
+000002f0  d7 42 a8 ba 2a 8f 22 2a  eb 88 3e 74 78 2a 67 de  |.B..*."*..>tx*g.|
+00000300  39 75 63 2c 1d 2e da 33  77 a5 08 04 00 80 61 f5  |9uc,...3w.....a.|
+00000310  ed 56 5b f1 dd 78 a0 c4  8a 9b ac 28 c5 91 0c bd  |.V[..x.....(....|
+00000320  f1 d5 c1 f6 31 2e 8c c3  d5 84 3a 15 e8 6d f1 bc  |....1.....:..m..|
+00000330  9e a6 04 fd 95 2f 51 60  2f c6 ff 99 cf 38 24 bf  |...../Q`/....8$.|
+00000340  a4 32 a2 1f a1 6b bd 27  98 00 14 23 0d 12 66 67  |.2...k.'...#..fg|
+00000350  48 33 92 51 e7 e7 3c f5  ef 13 ca 46 3c 39 53 70  |H3.Q..<....F<9Sp|
+00000360  41 78 4a 02 70 87 48 ce  b0 31 02 33 0b 06 78 b9  |AxJ.p.H..1.3..x.|
+00000370  87 0b 07 e0 f7 15 c8 3e  27 a1 a3 20 24 9e 20 93  |.......>'.. $. .|
+00000380  7f b5 53 7b 18 88 96 87  2b df 02 ba 0c d8 16 03  |..S{....+.......|
 00000390  03 00 04 0e 00 00 00                              |.......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
@@ -82,17 +82,17 @@
 00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
-00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 b8 16  |.....(..........|
-00000060  ce 7d df 64 13 07 9e d8  37 bb 3f 9c 9e 2b 3c 0e  |.}.d....7.?..+<.|
-00000070  26 a7 9d 32 e5 44 b8 d6  66 bc 05 7b 27 7a        |&..2.D..f..{'z|
+00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 c1 90  |.....(..........|
+00000060  a0 8b 53 87 a8 e3 56 4c  5c ad 5f dc 00 af 29 5f  |..S...VL\._...)_|
+00000070  11 53 7d 49 25 f8 74 16  dc 84 5f 3b c6 24        |.S}I%.t..._;.$|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 c0 73 5c 27 1b  |..........(.s\'.|
-00000010  19 d0 66 68 ea c5 ad 7d  a8 03 37 d2 9a ff 00 c4  |..fh...}..7.....|
-00000020  70 65 98 3b 88 59 c0 ca  e3 c0 d6 32 0e 8d 15 3c  |pe.;.Y.....2...<|
-00000030  e2 c3 f3                                          |...|
+00000000  14 03 03 00 01 01 16 03  03 00 28 00 f9 b2 51 85  |..........(...Q.|
+00000010  72 7e ec 79 72 59 90 ae  69 51 79 61 10 3b 4e 4b  |r~.yrY..iQya.;NK|
+00000020  45 d6 a5 9a c0 1a 69 c9  9f 1c ee cd ad 6a e8 ea  |E.....i......j..|
+00000030  c4 9e f1                                          |...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 28 ef 47  |.............(.G|
-00000010  ad 7f 40 4b 34 78 f3 1e  01 a7 f4 20 0a d5 c1 41  |..@K4x..... ...A|
-00000020  f7 be 41 15 03 03 00 1a  00 00 00 00 00 00 00 02  |..A.............|
-00000030  fb fc eb 14 f2 a6 e7 2e  80 d6 93 31 25 01 e9 d2  |...........1%...|
-00000040  c3 ae                                             |..|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 86 5a 45  |..............ZE|
+00000010  24 60 90 dc bc b3 f6 61  6f db 60 02 99 f9 e2 93  |$`.....ao.`.....|
+00000020  07 85 0d 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
+00000030  36 86 b0 60 b5 5d dd 28  64 c6 5b c7 ed 01 07 b1  |6..`.].(d.[.....|
+00000040  12 39                                             |.9|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4 b/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4
index ab2c4eb..12fb594 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4
+++ b/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 51 02 00 00  4d 03 03 34 50 1f 52 15  |....Q...M..4P.R.|
-00000010  85 c7 85 2c 4d a9 b2 0c  49 e5 a3 ea 57 21 96 39  |...,M...I...W!.9|
-00000020  db c9 97 b6 c4 d0 81 9a  39 a3 e8 20 59 f5 b9 db  |........9.. Y...|
-00000030  58 2e ef 1c b3 85 96 27  6a 23 71 3f 5c 72 ce cf  |X......'j#q?\r..|
-00000040  c5 b7 fe 05 00 f4 65 06  54 c1 2e 7c 00 05 00 00  |......e.T..|....|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 b0 e7 ee 09 45  |....Q...M......E|
+00000010  36 f1 7a 92 be 9e d8 9d  ae cd c1 4e b2 12 94 3e  |6.z........N...>|
+00000020  6c 34 71 ed 5f e0 97 7f  25 e4 dd 20 f4 43 01 03  |l4q._...%.. .C..|
+00000030  88 33 26 7f 48 c1 f2 d1  4d d3 f8 1a bd 86 4c 50  |.3&.H...M.....LP|
+00000040  18 89 dc 08 99 f1 51 c5  84 be b9 fd 00 05 00 00  |......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..|
@@ -70,15 +70,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 ab 48  84 ae 77 f9 8b 82 44 52  |.....$.H..w...DR|
-000000a0  3e 65 94 27 cc f2 08 a7  f2 e5 21 0c 02 d0 89 ac  |>e.'......!.....|
-000000b0  50 be 69 57 c9 7c a0 f2  7f 6d                    |P.iW.|...m|
+00000090  01 16 03 03 00 24 08 65  01 80 0d 59 b8 ac 0f 09  |.....$.e...Y....|
+000000a0  bf 61 31 32 e0 74 e9 f4  72 e3 2c 79 11 4d b2 a2  |.a12.t..r.,y.M..|
+000000b0  55 65 94 c8 cd 0a 61 99  07 b8                    |Ue....a...|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 61 94 21 65 0f  |..........$a.!e.|
-00000010  10 ba 0c a6 d9 e3 08 54  86 ae f9 64 c7 e7 f4 4b  |.......T...d...K|
-00000020  aa f5 19 ca 2a 0d 50 88  85 42 32 14 04 29 d9     |....*.P..B2..).|
+00000000  14 03 03 00 01 01 16 03  03 00 24 04 20 46 cd fb  |..........$. F..|
+00000010  6c 46 9c 47 21 03 fe 9b  a4 c6 da 2c 71 2f db 92  |lF.G!......,q/..|
+00000020  40 da 7d 46 2e e4 9c 81  86 89 7f 53 46 91 28     |@.}F.......SF.(|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1a cb 1d 43  67 de 7a 20 c7 ed 46 99  |.......Cg.z ..F.|
-00000010  86 1f b9 61 9f c6 34 9a  07 37 3c 94 45 b4 40 15  |...a..4..7<.E.@.|
-00000020  03 03 00 16 4e ac d3 12  23 b4 33 bc 5b 03 91 7e  |....N...#.3.[..~|
-00000030  d9 d0 7f d7 48 3e 8c 16  16 ec                    |....H>....|
+00000000  17 03 03 00 1a 89 2b 2e  49 21 19 b7 d0 df 85 da  |......+.I!......|
+00000010  b8 a7 f3 73 5f fe 44 e5  0c a1 af 16 74 93 bc 15  |...s_.D.....t...|
+00000020  03 03 00 16 5f 9e 64 d0  91 50 34 44 cf f6 1f e0  |...._.d..P4D....|
+00000030  e0 13 b9 67 da 5c 99 16  f1 b3                    |...g.\....|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce
index 48a99ed..06752de 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 f1 d8 72 0c 79  |....Y...U....r.y|
-00000010  e2 ca 92 11 1c 30 cc 45  00 9b ea 3d a3 ed 23 d5  |.....0.E...=..#.|
-00000020  22 f0 da 9c 03 32 7b c3  13 d3 df 20 8f 7a 61 43  |"....2{.... .zaC|
-00000030  cb 72 46 5e c1 39 78 42  32 97 cc 2b 90 2e 53 59  |.rF^.9xB2..+..SY|
-00000040  31 38 ec 7b 2b 8a f3 80  e0 03 f0 0e cc a8 00 00  |18.{+...........|
+00000000  16 03 03 00 59 02 00 00  55 03 03 5b 4b bb c4 39  |....Y...U..[K..9|
+00000010  fb 45 5c 54 03 30 0f 71  c3 2e 48 25 33 fd 6d 40  |.E\T.0.q..H%3.m@|
+00000020  18 6e 75 43 66 9e 08 fb  6a a1 f8 20 34 3c c4 2a  |.nuCf...j.. 4<.*|
+00000030  b5 9b 65 b0 cd b9 fc ce  cf 51 f8 cc a1 5d 00 ed  |..e......Q...]..|
+00000040  49 5b 43 9a ff c4 cf 6b  d8 2a ea e5 cc a8 00 00  |I[C....k.*......|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,185 +60,185 @@
 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 96 cb 1d cd f6 2f ff  |........ ...../.|
-000002d0  fe 32 ef d6 18 a2 6b 57  66 cd 3d 50 42 56 dc a4  |.2....kWf.=PBV..|
-000002e0  5f fe e4 91 ce d1 17 34  3c 08 04 00 80 b1 47 de  |_......4<.....G.|
-000002f0  b3 19 b0 fd 02 35 eb 3c  a1 04 d3 6b 53 84 20 c7  |.....5.<...kS. .|
-00000300  08 4b 96 12 23 ae bf ca  a8 83 1d 90 16 ae d3 7c  |.K..#..........||
-00000310  fa 1b b4 f0 bb bb 4e 3f  70 13 2f 40 6c d4 76 61  |......N?p./@l.va|
-00000320  5b 23 85 3f e7 37 ef e1  55 47 8d 01 e1 24 22 7f  |[#.?.7..UG...$".|
-00000330  a4 2c 6f 97 47 5f d6 69  bf b4 db 4b b8 a1 ad 66  |.,o.G_.i...K...f|
-00000340  5f d5 5d b6 06 ac 93 ed  d7 06 cb b5 a4 d4 4b a7  |_.]...........K.|
-00000350  7b de f7 73 60 af ad 23  f4 6a f1 bf 2a ee 5b 4e  |{..s`..#.j..*.[N|
-00000360  83 94 d7 95 3b e5 5e a5  3d 1a 0a 7a 9e 16 03 03  |....;.^.=..z....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 76 c4 f4 ec a2 d6 c1  |........ v......|
+000002d0  b1 d8 b0 41 71 8a ee e9  8a 17 06 90 6b 0c 05 66  |...Aq.......k..f|
+000002e0  54 d8 a6 ad 50 95 11 f0  03 08 04 00 80 46 0b da  |T...P........F..|
+000002f0  0b 0c 6c 1a 2e a2 7e 28  40 1b 40 9a b4 5c 36 88  |..l...~(@.@..\6.|
+00000300  c1 ad cd 45 be 23 17 a6  98 e5 11 fe a8 78 c6 21  |...E.#.......x.!|
+00000310  17 a6 a8 7d ce 28 c4 ef  51 76 f8 b1 b1 75 31 04  |...}.(..Qv...u1.|
+00000320  b9 14 bc 3b bf 59 50 b8  e1 ad c6 86 45 3c e1 70  |...;.YP.....E<.p|
+00000330  fb cd 69 8c 0a 5f f6 2d  bd 10 95 30 ed 4c 9a 47  |..i.._.-...0.L.G|
+00000340  73 8b 39 72 00 0a 7e 8f  a9 42 27 01 6f 3d 37 f9  |s.9r..~..B'.o=7.|
+00000350  7d d4 1b a2 6a 07 37 dc  5e 6c 8b b1 d5 75 3a 9b  |}...j.7.^l...u:.|
+00000360  d1 45 c5 d8 e0 90 f0 62  3d d5 01 00 9e 16 03 03  |.E.....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 20 f2 6f 2e  79 5c db 90 b8 2e cf 59  |.... .o.y\.....Y|
-00000040  0a 56 69 86 f1 71 0c ff  a9 7c 0b a0 e7 c9 8d 17  |.Vi..q...|......|
-00000050  65 ad a5 6c 82                                    |e..l.|
+00000030  16 03 03 00 20 bb f4 78  64 23 f7 31 50 42 3d 97  |.... ..xd#.1PB=.|
+00000040  8f 73 89 b9 90 8f 74 b6  e4 7d 58 27 65 25 59 8a  |.s....t..}X'e%Y.|
+00000050  5a 8d 8f fa bd                                    |Z....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 d5 90 08 84 71  |.......... ....q|
-00000010  bc 09 48 be ad 59 11 76  c6 39 bb 94 8c 60 80 29  |..H..Y.v.9...`.)|
-00000020  44 1a 0d fe 5c 00 4c bc  47 3c 1e                 |D...\.L.G<.|
+00000000  14 03 03 00 01 01 16 03  03 00 20 0a 43 74 53 47  |.......... .CtSG|
+00000010  41 4b 0a f1 f7 75 51 a9  22 c9 e0 5c 53 90 6b d7  |AK...uQ."..\S.k.|
+00000020  97 18 c6 ef c3 85 32 f5  7c 26 97                 |......2.|&.|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 42 cd 1c  e5 91 35 b0 c1 4d df e4  |.....B....5..M..|
-00000010  b0 ca f3 8a 7a 41 85 31  7a 7d 59                 |....zA.1z}Y|
+00000000  17 03 03 00 16 8e 83 1a  32 53 02 1c fa 84 89 4f  |........2S.....O|
+00000010  25 fb 5f 85 4f bd ee ae  9f 0f ea                 |%._.O......|
 >>> Flow 6 (server to client)
-00000000  16 03 03 00 14 3b 0f 40  64 9f ff 8f b9 85 18 af  |.....;.@d.......|
-00000010  b4 bc e7 33 8a 9b 03 de  ed                       |...3.....|
+00000000  16 03 03 00 14 96 76 32  c4 6d e6 23 bf 21 a8 09  |......v2.m.#.!..|
+00000010  a3 8b 69 98 cd c3 c9 ce  73                       |..i.....s|
 >>> Flow 7 (client to server)
-00000000  16 03 03 01 16 17 a7 61  5b 22 97 6e eb dd 43 84  |.......a[".n..C.|
-00000010  b9 ac 15 c2 76 7d 1f c0  e3 46 11 af c0 59 7d cc  |....v}...F...Y}.|
-00000020  d4 5d 02 90 28 bb b3 7c  85 76 46 34 7c bf 2b bf  |.]..(..|.vF4|.+.|
-00000030  c4 e9 e1 46 b0 15 7e af  c1 03 4a 17 b3 7a 03 cd  |...F..~...J..z..|
-00000040  e0 90 b1 1b 59 ac 1f 33  b0 41 c3 47 ee 58 af 5b  |....Y..3.A.G.X.[|
-00000050  5b c4 7a 92 02 e2 34 8d  cd 70 20 c4 59 5e 25 f2  |[.z...4..p .Y^%.|
-00000060  28 b1 f2 a5 e0 c4 f9 d0  ae cc 2b 1e ea d4 5a fe  |(.........+...Z.|
-00000070  62 97 bc d7 57 94 5c b8  ce 4c 62 1a e5 29 02 1e  |b...W.\..Lb..)..|
-00000080  0e 68 1d 8a 17 f9 47 55  ac 65 cf 13 88 d3 95 0d  |.h....GU.e......|
-00000090  d7 e0 d8 03 f8 f6 6f 9c  5b de 5c 80 c3 34 7e 82  |......o.[.\..4~.|
-000000a0  5c 8b c4 a3 99 c8 1e f0  f2 e5 6e 73 40 62 31 8e  |\.........ns@b1.|
-000000b0  3b 08 62 ba a8 b9 18 c4  84 a0 b4 9f 68 81 2f ae  |;.b.........h./.|
-000000c0  8d 7c cc 54 ba 4a ec 26  a5 8a 9b a7 bd 36 17 2c  |.|.T.J.&.....6.,|
-000000d0  52 69 4c 57 81 64 e6 34  88 27 81 d2 32 eb d2 8d  |RiLW.d.4.'..2...|
-000000e0  4d 8d c1 8b 14 b3 07 19  63 f8 d6 4a 9a 7d 3f c1  |M.......c..J.}?.|
-000000f0  af 18 72 f7 2d c8 7e 82  52 28 51 80 59 0c 9b 9f  |..r.-.~.R(Q.Y...|
-00000100  ac 40 69 25 0e 6d d7 4a  72 b5 18 f8 78 b9 52 c3  |.@i%.m.Jr...x.R.|
-00000110  d6 32 6c 7d 29 70 a8 33  18 d0 4b                 |.2l})p.3..K|
+00000000  16 03 03 01 16 72 5b d9  30 b2 b0 91 e2 3d 2b 12  |.....r[.0....=+.|
+00000010  2c c9 43 f1 67 ae 54 ee  ce a1 15 12 12 9a 27 46  |,.C.g.T.......'F|
+00000020  7e 47 90 d4 f2 7d b9 98  ec f8 61 b8 84 52 9f 21  |~G...}....a..R.!|
+00000030  c1 83 6a ce 1a 68 fc 5b  25 42 f3 8f 55 ee 92 45  |..j..h.[%B..U..E|
+00000040  af a4 d1 c4 a6 b5 0e 58  3d 70 76 98 ec 47 af 6f  |.......X=pv..G.o|
+00000050  e3 4f 9f ef 52 a3 aa 33  75 83 f6 57 33 a8 dc f5  |.O..R..3u..W3...|
+00000060  36 49 09 1c 72 31 c1 43  52 64 4a b5 ca ce 06 f5  |6I..r1.CRdJ.....|
+00000070  91 18 90 85 f0 c9 96 4f  bf 4c de 9e 50 a2 1c de  |.......O.L..P...|
+00000080  86 51 1f 0b 73 e1 df 1d  2d 90 6d 7f a2 f1 28 e8  |.Q..s...-.m...(.|
+00000090  5f 2a 78 2d 8e ab f2 05  19 85 4e 92 a8 cf cd 16  |_*x-......N.....|
+000000a0  1e df 1d 51 ee 8b ba 72  cd ac d2 01 4b 84 46 62  |...Q...r....K.Fb|
+000000b0  1c 28 4d 3f 44 c1 62 12  13 4f f8 73 f4 da c0 98  |.(M?D.b..O.s....|
+000000c0  14 da 31 6a 48 0d 1d bb  24 6c ef 0f 98 c0 3c 86  |..1jH...$l....<.|
+000000d0  c6 d6 8e ab bd 20 bd 06  e9 ba aa ce 3a 88 25 95  |..... ......:.%.|
+000000e0  54 15 fb c6 49 c7 98 ff  27 92 c0 60 6a 3c f8 26  |T...I...'..`j<.&|
+000000f0  fd 28 ac c4 8f 5c 4f 15  24 10 45 3c 07 3d 3f 50  |.(...\O.$.E<.=?P|
+00000100  e5 db cf 78 bd b0 d2 24  a2 4b 3e a6 9c 2d 3b 0d  |...x...$.K>..-;.|
+00000110  d8 1b 86 88 dc 0c 3c 9c  16 cf ea                 |......<....|
 >>> Flow 8 (server to client)
-00000000  16 03 03 00 81 8b e2 a1  f5 15 55 13 f6 f2 fa 95  |..........U.....|
-00000010  3b bb 0f 3d 3e 9b 3c b1  60 cb 69 7f 63 62 2d 9b  |;..=>.<.`.i.cb-.|
-00000020  20 47 3a 7d 5e d0 98 38  49 c3 94 f8 1d 56 1d 69  | G:}^..8I....V.i|
-00000030  27 65 bc ca 63 22 65 61  60 67 49 35 f0 eb 83 1b  |'e..c"ea`gI5....|
-00000040  44 c4 f0 91 64 5a 81 b5  06 4b 3e 3a ef 3b 5c b0  |D...dZ...K>:.;\.|
-00000050  81 b4 36 df f3 0d a3 0a  1c 40 03 fa 81 48 42 70  |..6......@...HBp|
-00000060  bf 4c b3 6b 67 19 7b 83  05 a1 31 a3 1c 79 49 2c  |.L.kg.{...1..yI,|
-00000070  1f 58 bc 7d 98 4e 5b 64  44 3d 3c 43 fb 77 c7 7c  |.X.}.N[dD=<C.w.||
-00000080  65 aa 0a 3d 49 a1 16 03  03 02 69 de 2a 3b 96 9f  |e..=I.....i.*;..|
-00000090  21 b4 5d de 2b b6 c5 03  ec ab 79 35 eb da 8b 1f  |!.].+.....y5....|
-000000a0  f8 c4 58 7c d1 af 3d 6e  f9 73 63 2b dc 2e a5 4f  |..X|..=n.sc+...O|
-000000b0  88 93 24 5e d7 2a ab 0a  a5 0f bf 5d 2d 74 9c 19  |..$^.*.....]-t..|
-000000c0  3a 97 88 f7 17 25 ad 6a  81 3a f1 e3 bb 4c 7a b6  |:....%.j.:...Lz.|
-000000d0  4c b0 f3 25 e5 66 06 14  b0 a3 3d 3a 25 36 4c e1  |L..%.f....=:%6L.|
-000000e0  62 25 fc ac 22 7b 25 0d  f9 5f 5b a6 1b 7f b9 14  |b%.."{%.._[.....|
-000000f0  4d 71 81 6b de 9d 6a 40  80 ba 88 20 60 c6 e2 50  |Mq.k..j@... `..P|
-00000100  c6 a6 3d 01 ee 04 dc ad  3c 95 a7 ef a7 dd 3a 6c  |..=.....<.....:l|
-00000110  0f f2 c2 c2 e0 fc 3c d2  75 88 ad 1a 23 94 2a 69  |......<.u...#.*i|
-00000120  28 66 c2 8a 5c 34 69 da  cc 5d 13 dd 86 fc 66 13  |(f..\4i..]....f.|
-00000130  de c2 c6 86 6d 4a b4 ea  b0 99 61 38 72 1e 7f 36  |....mJ....a8r..6|
-00000140  df 32 4b a7 12 23 8f f3  d1 8d d7 2f d1 65 67 4f  |.2K..#...../.egO|
-00000150  10 07 03 6a b2 87 aa a4  b0 41 c9 20 f4 84 5e b7  |...j.....A. ..^.|
-00000160  5e 4d 47 d4 7f 6c 8d 2e  a5 bb 7d 07 1b 5b e5 50  |^MG..l....}..[.P|
-00000170  5d 27 c0 8b f8 5e a7 a8  ef d7 f3 b0 6d 07 7a 9b  |]'...^......m.z.|
-00000180  1d 54 5a 18 c7 4f 6f b8  92 44 16 ec 92 43 1a 1a  |.TZ..Oo..D...C..|
-00000190  a8 d0 a3 40 25 b0 ff 35  9c b7 4c f9 cd 06 59 a6  |...@%..5..L...Y.|
-000001a0  25 ca 4a b7 34 31 0a 23  29 3a 09 8b 7b 05 15 b0  |%.J.41.#):..{...|
-000001b0  67 ae 1b 8b f4 67 16 e0  c1 67 a1 58 09 c9 10 f0  |g....g...g.X....|
-000001c0  f0 62 02 52 14 6d 02 3d  e6 ab 16 fb 7f 38 69 7c  |.b.R.m.=.....8i||
-000001d0  d1 f3 db 69 3c cd 78 28  b2 fa 94 1c a0 2f b7 bb  |...i<.x(...../..|
-000001e0  31 4f f6 56 2a 98 5a d1  bf 5d e4 0d ec 8f 47 42  |1O.V*.Z..]....GB|
-000001f0  62 a6 59 39 77 d8 bd 11  71 64 b4 2b 65 2a 10 5d  |b.Y9w...qd.+e*.]|
-00000200  46 51 bf 8d b6 13 df 61  b8 1e 37 ad fc c0 86 a9  |FQ.....a..7.....|
-00000210  b4 09 2f 33 8e 93 4a 5b  32 f4 f9 7d 01 a8 b8 09  |../3..J[2..}....|
-00000220  8e da 90 8f a7 fb 82 76  fd 6b 7e 93 57 13 e1 99  |.......v.k~.W...|
-00000230  cb b8 12 0a da c2 62 0e  0c 65 53 d4 5b 75 c2 22  |......b..eS.[u."|
-00000240  3f 91 5c e6 c4 12 48 78  c4 6d 2c 1f 45 dc a2 a1  |?.\...Hx.m,.E...|
-00000250  73 cf 69 97 8b 64 42 d5  22 06 de 04 4b 8c f5 5f  |s.i..dB."...K.._|
-00000260  d6 97 1a 73 4f 4e d2 55  e1 8d 8c 21 fd 7f 26 1c  |...sON.U...!..&.|
-00000270  53 9f 69 c9 01 11 be 4e  d0 ab 78 56 af bb 0a 0f  |S.i....N..xV....|
-00000280  73 cb c5 d2 07 4a 16 a0  71 9f dd 46 17 0e 86 5e  |s....J..q..F...^|
-00000290  e2 90 34 7d af b1 86 6c  e3 33 cf ff 2f bf ea 8e  |..4}...l.3../...|
-000002a0  62 7e 7f b9 f7 c4 1b 4c  61 b6 8d 6f a9 b4 56 27  |b~.....La..o..V'|
-000002b0  0a 0d fa d7 d9 ce 6a 1a  e3 4e 4d f8 04 c8 74 75  |......j..NM...tu|
-000002c0  07 6f 38 96 c7 04 df a4  e0 6a 08 c5 5b 93 b7 c1  |.o8......j..[...|
-000002d0  fb 4d 4f 01 67 3c 8b 03  93 f7 46 c2 db 2f 41 2d  |.MO.g<....F../A-|
-000002e0  e1 d6 dd 39 d5 0c dc 6a  10 c2 50 fe 34 64 79 9a  |...9...j..P.4dy.|
-000002f0  5e 88 35 89 16 03 03 00  bc d1 42 6c 11 23 45 dd  |^.5.......Bl.#E.|
-00000300  41 9e 81 0a 3d d1 c1 99  6f 91 b5 16 96 e6 d3 eb  |A...=...o.......|
-00000310  9b 8f c3 30 14 7f 19 d5  9a fa ea 9c de 53 23 7c  |...0.........S#||
-00000320  d8 49 d2 c5 e7 7c ff 96  22 0a 57 fc 11 ed b9 ca  |.I...|..".W.....|
-00000330  2e 18 a5 30 7e 3a d2 86  70 de 48 28 83 a1 3b 65  |...0~:..p.H(..;e|
-00000340  67 b9 2e 89 87 92 0e eb  b5 70 1d 36 7b 98 4b 8e  |g........p.6{.K.|
-00000350  12 49 db 85 18 dc e1 f4  51 a9 bb e4 5c ae 56 31  |.I......Q...\.V1|
-00000360  c1 56 84 bb e5 42 ec d1  41 e7 a7 4e 08 d7 5f 1d  |.V...B..A..N.._.|
-00000370  67 9a ed 10 b6 80 ff ea  36 70 ac a0 a9 ec 4a e3  |g.......6p....J.|
-00000380  37 ae bf f3 bd a9 aa 3f  b0 14 f6 0b 05 18 09 dd  |7......?........|
-00000390  29 b4 97 55 88 24 59 ce  5b 42 e2 b5 1f 04 76 f3  |)..U.$Y.[B....v.|
-000003a0  f1 c0 49 7d 47 ef 5e 6c  c3 ed 30 2c a0 a1 df c6  |..I}G.^l..0,....|
-000003b0  12 13 22 8b 65 16 03 03  00 4a 3e 6c f8 63 5b 93  |..".e....J>l.c[.|
-000003c0  f0 c6 3a 58 e0 6c 6b 70  46 d0 be 6f 13 34 7a 30  |..:X.lkpF..o.4z0|
-000003d0  e6 e4 b2 fd 39 ee 79 b1  7e 73 5e 9b 2d d9 3f 4f  |....9.y.~s^.-.?O|
-000003e0  61 d5 53 37 79 57 15 a3  3a 7c b7 02 cc 76 25 1d  |a.S7yW..:|...v%.|
-000003f0  96 8b dd 9e 32 8b 1a 9e  37 b1 1a b8 f2 4f ef 3c  |....2...7....O.<|
-00000400  78 e1 b9 07 16 03 03 00  14 bf da c1 d4 16 fd 48  |x..............H|
-00000410  a9 ad 59 6d 8c dc e1 6c  fd 73 ca 9c 1b           |..Ym...l.s...|
+00000000  16 03 03 00 81 2e c9 cd  ad df 75 cf b6 8d 7f 8c  |..........u.....|
+00000010  c6 bb 5b e6 2b 40 a0 36  45 13 ae 93 f1 04 bf f3  |..[.+@.6E.......|
+00000020  62 bd c8 62 d9 cf 05 a3  4c e9 37 af 35 a6 83 8e  |b..b....L.7.5...|
+00000030  71 46 b8 2a 5b 02 3b 81  d5 15 b8 17 72 c4 1e 00  |qF.*[.;.....r...|
+00000040  78 d9 4a 04 a7 b3 5b 80  bd 1f 88 ba fa 22 b5 0e  |x.J...[......"..|
+00000050  ca 44 55 27 c0 67 ce 37  4c 9a 9a d7 77 da 58 35  |.DU'.g.7L...w.X5|
+00000060  83 b3 39 90 8d e2 7f 08  2e cc 5a 8e 5e a8 c3 bb  |..9.......Z.^...|
+00000070  db e5 a2 56 56 04 37 13  f3 b1 71 2d ea 0a 56 00  |...VV.7...q-..V.|
+00000080  6e 8d 8b 20 79 30 16 03  03 02 69 76 4b a4 c6 5e  |n.. y0....ivK..^|
+00000090  0a a2 3c 89 24 f6 93 94  25 4e 0b 8a d2 33 2f 03  |..<.$...%N...3/.|
+000000a0  ab 20 22 33 ad 84 6d aa  31 6b 5a 10 0e 42 1b dd  |. "3..m.1kZ..B..|
+000000b0  35 9b a0 dc 31 f8 65 91  c4 14 78 2e 74 2e 1d 46  |5...1.e...x.t..F|
+000000c0  3a 66 41 f0 a3 9a 4e ae  bc 9b 55 f9 d1 9c c5 6e  |:fA...N...U....n|
+000000d0  38 24 19 15 fb e6 c3 85  de ef f0 97 a2 a1 db ed  |8$..............|
+000000e0  b8 d0 05 ae 93 77 d7 45  50 a5 4e 8a 83 84 07 fb  |.....w.EP.N.....|
+000000f0  3a 80 c6 69 3c 6e b2 e3  e0 97 f7 03 93 76 dd 32  |:..i<n.......v.2|
+00000100  0c 5d a2 e6 1f 82 90 8b  dd 93 06 ef eb b7 e0 74  |.].............t|
+00000110  1a 7d 8f 37 c2 c1 41 9c  30 74 ca 37 17 5e 71 a0  |.}.7..A.0t.7.^q.|
+00000120  cb d6 00 47 9d 14 93 aa  fe 57 56 10 ae 88 13 65  |...G.....WV....e|
+00000130  f4 6c 20 4e f9 14 87 73  36 5e d5 20 93 34 db 87  |.l N...s6^. .4..|
+00000140  e7 f8 84 6e 36 9d 60 20  b5 8f 47 33 84 94 22 e1  |...n6.` ..G3..".|
+00000150  5d c6 1c 35 39 61 71 47  90 a9 b4 c6 5e 31 58 d1  |]..59aqG....^1X.|
+00000160  40 d8 22 22 23 c2 53 e3  75 1f 98 1c cc 7f 2d 11  |@.""#.S.u.....-.|
+00000170  31 5e 49 a1 2c d9 c8 db  6e 4e 9d da 57 e1 c9 32  |1^I.,...nN..W..2|
+00000180  03 6c f0 9b df c2 03 d5  b7 e2 04 77 e8 87 bc 14  |.l.........w....|
+00000190  73 66 b0 fb d1 d6 26 0c  36 90 2c 20 43 16 c6 68  |sf....&.6., C..h|
+000001a0  6c c0 ee be 2c da 6f 4f  95 1e cf a0 31 e8 40 48  |l...,.oO....1.@H|
+000001b0  88 61 26 7b 53 5b 42 14  2a 89 a3 1e 03 01 16 9d  |.a&{S[B.*.......|
+000001c0  41 6d de 60 75 1d 36 12  cd 16 8b 1c 93 da 17 79  |Am.`u.6........y|
+000001d0  4b d2 1d 78 64 da 6c cc  5c 7c e3 f9 4d 70 a2 07  |K..xd.l.\|..Mp..|
+000001e0  b4 24 33 de 19 bc d2 1a  43 42 f4 26 8b c0 81 e4  |.$3.....CB.&....|
+000001f0  a3 32 97 09 ec 6f 39 d7  ca c9 c5 ee 38 fd 91 dd  |.2...o9.....8...|
+00000200  c4 dc 3c 53 38 60 c7 b6  60 c6 a9 ff ae 81 e9 8c  |..<S8`..`.......|
+00000210  ea 49 19 3f fe 0e 8e b8  e6 7c ec 4b 63 66 d8 7a  |.I.?.....|.Kcf.z|
+00000220  82 51 7f 24 51 ae ad 91  5d 0e 2c aa ee fa 9f d3  |.Q.$Q...].,.....|
+00000230  22 1a 8b 8d 12 48 bb 3a  7c ea f0 09 af 1a 7e 7e  |"....H.:|.....~~|
+00000240  47 74 b9 b9 1f 97 8e 64  62 52 ae 08 d5 f1 13 cb  |Gt.....dbR......|
+00000250  51 64 b0 6a 33 1f 48 78  c1 91 91 91 a7 75 29 cb  |Qd.j3.Hx.....u).|
+00000260  32 60 96 d4 27 3f a4 8f  12 e9 5d 79 4d fd f9 19  |2`..'?....]yM...|
+00000270  b8 f7 39 d8 53 e5 45 96  0f c6 4f f2 27 c6 e6 07  |..9.S.E...O.'...|
+00000280  40 47 29 94 b9 6a 38 9e  24 bf 9e 92 f6 67 3f e3  |@G)..j8.$....g?.|
+00000290  48 0f 3b 3a d7 7b 14 4e  34 a3 8a 25 b4 a2 d6 15  |H.;:.{.N4..%....|
+000002a0  3f 38 9e ba fa 7e 33 fd  a4 4c ed e7 58 93 65 7d  |?8...~3..L..X.e}|
+000002b0  90 48 fc 70 7e 10 a5 d0  0a ec 96 c4 cf 26 ae 94  |.H.p~........&..|
+000002c0  d7 3f 92 40 2f ad ed c8  bb 69 b1 3e 0b ab 4f 4e  |.?.@/....i.>..ON|
+000002d0  73 91 a6 05 2b a7 89 e8  63 28 39 51 53 8d 2c 5e  |s...+...c(9QS.,^|
+000002e0  c8 64 90 c3 b7 2d ee 00  aa 7f 38 ca 57 ab b8 aa  |.d...-....8.W...|
+000002f0  93 12 af c5 16 03 03 00  bc 0e 58 31 64 e6 68 e6  |..........X1d.h.|
+00000300  10 81 2f 79 e3 49 3a d9  cc 70 09 7e b6 b5 61 c4  |../y.I:..p.~..a.|
+00000310  92 16 22 d0 e5 af b8 b8  91 2e 72 7c cf 95 cb ef  |..".......r|....|
+00000320  14 81 73 33 34 98 65 1b  69 db 2c 9d eb 1c ce be  |..s34.e.i.,.....|
+00000330  1f ce 48 b4 22 8d f0 6e  48 21 8e aa af 83 43 d2  |..H."..nH!....C.|
+00000340  65 54 0f 57 6b ce b1 24  ef 09 bf 7f 23 92 35 07  |eT.Wk..$....#.5.|
+00000350  55 2f 2f e7 b7 d7 72 d2  7c 5f 71 d6 20 9a 68 e8  |U//...r.|_q. .h.|
+00000360  1b 90 0b 13 f7 37 e2 35  0d fc 04 ea 32 50 2d 04  |.....7.5....2P-.|
+00000370  72 1a db d9 71 e1 4e d1  76 7c c3 f5 22 97 92 c5  |r...q.N.v|.."...|
+00000380  61 19 e0 40 b1 14 de 37  9d 8e e7 fd fe 2b 28 97  |a..@...7.....+(.|
+00000390  91 77 8f a7 d4 b1 db bc  a2 78 65 5c a8 8d 41 21  |.w.......xe\..A!|
+000003a0  0e 56 6b ac 0b da a9 dd  b1 51 84 19 20 ab e5 eb  |.Vk......Q.. ...|
+000003b0  f2 52 8d 48 a2 16 03 03  00 4a 69 44 32 65 c2 09  |.R.H.....JiD2e..|
+000003c0  9c c1 d6 66 06 29 c3 a6  c3 10 2e d9 9e d6 0a d3  |...f.)..........|
+000003d0  06 a3 d2 d2 67 52 bd 19  26 a8 ef 08 ed 9f 2b e8  |....gR..&.....+.|
+000003e0  96 ea 08 b7 46 a2 36 e3  c1 84 4b c2 a2 b5 34 9c  |....F.6...K...4.|
+000003f0  83 ea 94 51 e6 ca 9c 0b  e1 e3 86 13 b7 1b 1f 4e  |...Q...........N|
+00000400  ee a1 10 70 16 03 03 00  14 5a 1c c1 14 fd d9 ff  |...p.....Z......|
+00000410  e3 46 ac 89 3b b3 e1 8e  6b 90 41 44 1f           |.F..;...k.AD.|
 >>> Flow 9 (client to server)
-00000000  16 03 03 02 69 11 1e 53  9b b7 57 6d ea 89 bb 37  |....i..S..Wm...7|
-00000010  1b c6 01 bd 27 db fa 17  cc 5d 20 be ee 5b a9 64  |....'....] ..[.d|
-00000020  48 4e 4a 4c 82 65 8e 3d  42 d6 ce 5c a8 50 d4 fa  |HNJL.e.=B..\.P..|
-00000030  0f 02 b2 19 90 b5 4e ae  6c e9 d6 b7 b8 64 ca 0e  |......N.l....d..|
-00000040  09 2d a9 7b ab 0f b8 83  97 b6 e0 eb bf 03 5a 1c  |.-.{..........Z.|
-00000050  e7 16 31 67 30 46 60 26  df 19 cf 5f fa 40 36 43  |..1g0F`&..._.@6C|
-00000060  91 d5 7c 2f 5f 29 74 03  e0 90 cd 55 25 e5 1e fe  |..|/_)t....U%...|
-00000070  6b 13 ec 58 29 b0 f4 a3  b2 8d ba 4e 3b f1 11 d8  |k..X)......N;...|
-00000080  85 49 50 b9 e0 03 89 a1  0f da ce 57 83 aa 4a 8c  |.IP........W..J.|
-00000090  3b 15 d5 10 47 01 22 32  4f 78 87 69 4c bf a6 6e  |;...G."2Ox.iL..n|
-000000a0  d4 e6 a5 1e fa 5b ff b0  38 a5 fa 83 1d 45 c5 18  |.....[..8....E..|
-000000b0  72 65 91 6c 41 d2 21 be  5b 1d e9 f5 19 eb d0 5a  |re.lA.!.[......Z|
-000000c0  7e 0d 81 c9 ca f0 97 9e  cc 9b 5c 77 6b 9c 15 d3  |~.........\wk...|
-000000d0  bd 43 4d 42 e5 f9 82 a9  d6 f2 44 93 ae 74 a3 fd  |.CMB......D..t..|
-000000e0  c5 1f 15 13 a0 ea d2 f3  4c 4c ea 2d fe 3b 6e 7b  |........LL.-.;n{|
-000000f0  f4 11 f7 2e 7d 45 26 a0  d9 29 4e 4d ec 90 e2 3e  |....}E&..)NM...>|
-00000100  51 52 dd 6e e1 b5 77 b1  a2 f5 17 b5 34 7f e8 8f  |QR.n..w.....4...|
-00000110  38 9c d6 1c b5 6c 2d 99  00 a1 41 95 15 c5 e5 bf  |8....l-...A.....|
-00000120  c1 67 fb ea 53 6c a8 85  8c c4 a6 74 e3 dc f7 90  |.g..Sl.....t....|
-00000130  b8 cc 99 39 1a a1 c6 51  db 65 e9 b8 ad 2b 1f 35  |...9...Q.e...+.5|
-00000140  b5 90 ae f7 af c2 d0 a9  92 eb 63 21 24 4f 5e 62  |..........c!$O^b|
-00000150  ba 69 ce 1a c8 41 79 db  c0 6c ef bc cf 19 4a 2c  |.i...Ay..l....J,|
-00000160  e0 66 6e 72 97 2d 75 e5  ee 14 82 e8 26 98 fe c4  |.fnr.-u.....&...|
-00000170  8a 17 c4 fb 48 2a d7 7e  d9 3e 5b f9 d4 7d 0e da  |....H*.~.>[..}..|
-00000180  56 44 5e 33 9d 5f 97 ab  d1 60 a8 ee 3d 16 6a 2a  |VD^3._...`..=.j*|
-00000190  33 b1 7d e2 e6 86 cd 88  ac e1 48 49 4e 19 a2 b0  |3.}.......HIN...|
-000001a0  16 53 ec ff b8 a4 f7 35  2d a7 7a 04 86 66 42 52  |.S.....5-.z..fBR|
-000001b0  51 3d 21 62 c5 35 9c e5  cb f9 bf 7b d1 12 b0 18  |Q=!b.5.....{....|
-000001c0  7b 6f 88 d9 ef d2 1a 45  3e 51 ac 3e c8 87 8c 47  |{o.....E>Q.>...G|
-000001d0  08 d0 90 b5 66 f6 4e c3  75 74 68 c8 7d 14 3a 2b  |....f.N.uth.}.:+|
-000001e0  83 7d 12 78 37 9e 11 02  3d 63 ba 78 b6 ba 6d 26  |.}.x7...=c.x..m&|
-000001f0  30 b0 bf a9 23 1e 83 aa  3d a8 02 5b 77 5f 2a 95  |0...#...=..[w_*.|
-00000200  d0 b9 c8 22 a3 a9 fe b0  32 99 8a 46 67 10 b3 d9  |..."....2..Fg...|
-00000210  3e 84 02 ec a2 68 7e 69  db 51 99 37 ee 49 66 0b  |>....h~i.Q.7.If.|
-00000220  af e1 cd b0 25 74 dc ce  29 ed 70 1c 3a bb f2 99  |....%t..).p.:...|
-00000230  03 86 6d af 3f 78 4a 86  70 b8 85 15 02 91 be f6  |..m.?xJ.p.......|
-00000240  4f f2 73 98 00 c6 76 20  c2 19 c6 e9 6c d0 e5 09  |O.s...v ....l...|
-00000250  5c 12 c8 1c a1 3d b7 41  18 26 cb ea d0 92 61 53  |\....=.A.&....aS|
-00000260  06 7c f8 5e a8 27 de 76  4e 83 49 2a ab 82 16 03  |.|.^.'.vN.I*....|
-00000270  03 00 35 4f b7 51 7c c8  51 25 a4 58 de 8b 4a e2  |..5O.Q|.Q%.X..J.|
-00000280  97 cc 48 d0 4d be 9b 8a  44 3b 22 43 b9 82 a4 a5  |..H.M...D;"C....|
-00000290  76 38 0b ae 91 d3 20 75  18 50 f3 1b eb 11 fd 86  |v8.... u.P......|
-000002a0  4a 1a f1 e8 2a f8 e0 60  16 03 03 00 98 ae e6 1b  |J...*..`........|
-000002b0  b1 00 f9 14 93 55 be 63  ea 5b 5e d4 18 37 6b 14  |.....U.c.[^..7k.|
-000002c0  5c 8e fb 82 51 e1 57 24  b7 4a 8b 55 74 79 70 55  |\...Q.W$.J.UtypU|
-000002d0  de 33 82 14 0a 39 0d 91  92 9a 11 c0 4a dd 12 49  |.3...9......J..I|
-000002e0  ea 1a 41 df fd f2 4a 79  c3 0a d5 93 5c ea 82 ff  |..A...Jy....\...|
-000002f0  16 4a 20 91 25 34 5d 72  9d ea 0e 40 dd 6d 86 fd  |.J .%4]r...@.m..|
-00000300  e9 d1 d9 db 61 e6 62 17  6b 09 47 c4 a7 32 1c 22  |....a.b.k.G..2."|
-00000310  f6 e4 41 2a 3e 2b d0 c3  92 56 c5 b8 5f 6d 25 44  |..A*>+...V.._m%D|
-00000320  81 e7 1a ed 70 6a a6 94  89 d1 ad 8d d1 c0 df a2  |....pj..........|
-00000330  26 6f 20 0b 0e 51 15 dd  05 86 36 88 72 3f e1 5d  |&o ..Q....6.r?.]|
-00000340  da 9d d3 76 e4 14 03 03  00 11 52 70 cd 84 39 32  |...v......Rp..92|
-00000350  7c c0 58 53 9b 32 00 96  14 b6 57 16 03 03 00 20  ||.XS.2....W.... |
-00000360  98 94 aa 9f 77 71 42 3e  48 e8 74 8e 27 60 54 c2  |....wqB>H.t.'`T.|
-00000370  55 ac 52 99 37 21 f3 1e  30 93 5f 71 06 19 e5 1c  |U.R.7!..0._q....|
+00000000  16 03 03 02 69 c8 db 54  92 d3 ea 2f 24 47 f9 24  |....i..T.../$G.$|
+00000010  53 c1 d4 6a e8 dd 1d 71  d6 fb 2c 7e 3a 41 75 f6  |S..j...q..,~:Au.|
+00000020  0c 08 70 b6 f9 0a 12 4b  0d 3d 34 03 a9 36 9e f1  |..p....K.=4..6..|
+00000030  c7 93 dc 51 e4 15 3d fd  a7 67 28 24 32 fe ff d3  |...Q..=..g($2...|
+00000040  cd 69 d6 4a 5d 11 78 3b  aa 07 8d 1e c4 97 22 34  |.i.J].x;......"4|
+00000050  df 03 f2 37 fd 4f 76 c3  04 a6 a6 0f 35 1c 0f 13  |...7.Ov.....5...|
+00000060  7e 0a b9 5e 47 d2 9a 8c  d8 a3 f4 7a e4 92 5f 12  |~..^G......z.._.|
+00000070  a6 20 fb 51 16 af eb 55  d0 23 4e b5 f9 e8 cc 33  |. .Q...U.#N....3|
+00000080  bd d1 52 27 21 96 06 05  67 fa 68 0e ab 2c 84 05  |..R'!...g.h..,..|
+00000090  c9 97 6a db 69 57 a8 5c  55 a9 e1 cf 33 01 28 9a  |..j.iW.\U...3.(.|
+000000a0  76 09 64 a4 a3 31 36 13  72 27 0c 85 e9 59 47 27  |v.d..16.r'...YG'|
+000000b0  89 07 ee e2 e0 68 a6 f0  fa d5 c3 8b 2f 75 68 d0  |.....h....../uh.|
+000000c0  8e d8 fe ae 1d 0d af 0b  40 3d 9f ec 85 03 24 20  |........@=....$ |
+000000d0  c5 11 30 aa 25 ee 2c 86  42 ae 4f 0d 6b 18 70 1d  |..0.%.,.B.O.k.p.|
+000000e0  5f ae 1e cf 99 a7 0e c8  9b b3 63 58 cd b6 7d be  |_.........cX..}.|
+000000f0  01 43 96 37 87 45 5f 2f  aa 9c 12 48 ef 3b c8 d9  |.C.7.E_/...H.;..|
+00000100  60 20 26 69 68 56 48 aa  64 59 9e 41 ed 7e 8d c3  |` &ihVH.dY.A.~..|
+00000110  0f cd 0e 19 7a 76 89 95  f8 20 68 cd f9 81 e9 a0  |....zv... h.....|
+00000120  21 ff 60 e5 0f 6d dd 73  d2 19 1e 2a 76 f7 9a 46  |!.`..m.s...*v..F|
+00000130  5d d5 6b b2 19 28 c2 ac  9c e0 35 c8 d2 2a 53 fa  |].k..(....5..*S.|
+00000140  3e 58 9e f2 05 7e 6b ce  51 6d 3d 2a ce 2e 9b 59  |>X...~k.Qm=*...Y|
+00000150  aa d4 8d cc ad 1f 82 e7  ca 5a ef a6 87 d5 41 0b  |.........Z....A.|
+00000160  8d 27 6d 09 4d 40 c3 26  a3 a9 91 dd 1b 37 5d ff  |.'m.M@.&.....7].|
+00000170  8f c3 c7 b1 bf be f5 d1  19 4d 93 86 a7 5f 5e 8f  |.........M..._^.|
+00000180  14 34 82 50 76 25 42 04  b8 4b d3 da 15 ee 60 d1  |.4.Pv%B..K....`.|
+00000190  35 56 4c 63 0d ba 64 13  4f 3d 12 87 84 5a 45 41  |5VLc..d.O=...ZEA|
+000001a0  14 b6 6f 91 c4 b9 4f 97  c1 10 d6 3e b3 99 21 18  |..o...O....>..!.|
+000001b0  c3 91 82 e4 b6 91 3e bb  01 89 9a f0 60 ac 8e 7d  |......>.....`..}|
+000001c0  cf c2 f9 b4 4f da 40 e3  5e 83 a1 8f b4 fa 28 aa  |....O.@.^.....(.|
+000001d0  c9 ae 7b 8f 7d c9 d1 f8  7b b2 b5 3f 0a 9b 00 9e  |..{.}...{..?....|
+000001e0  1d fa 59 ff 39 b7 85 4d  2a b9 b8 67 03 df a0 f9  |..Y.9..M*..g....|
+000001f0  f1 7e 9d 27 1c 55 a9 76  44 9e f1 13 78 7d 34 4d  |.~.'.U.vD...x}4M|
+00000200  c9 23 07 e6 db 93 d7 70  3c 1b 5d 89 ed 8d 3d 43  |.#.....p<.]...=C|
+00000210  2e 89 f6 14 83 ff 87 db  26 a5 9a cd 98 5d 32 24  |........&....]2$|
+00000220  70 d2 e0 72 a7 6f a4 b4  2b 37 db 7e 39 4f d7 37  |p..r.o..+7.~9O.7|
+00000230  ea 68 b5 98 33 0e 23 21  3f 43 b3 ff 18 8e df 85  |.h..3.#!?C......|
+00000240  ba 15 48 3a fe 09 9b b6  27 40 d4 60 a8 3e 55 a3  |..H:....'@.`.>U.|
+00000250  75 c9 32 38 b5 21 46 ab  41 99 24 e6 09 3f 64 e6  |u.28.!F.A.$..?d.|
+00000260  09 40 cb 93 25 ab 1a 90  c7 d5 a6 40 36 a0 16 03  |.@..%......@6...|
+00000270  03 00 35 0f c7 e4 c3 16  c0 4f 7f 25 04 06 63 e7  |..5......O.%..c.|
+00000280  79 79 f9 4f c9 66 ca cd  ba e3 af 4a 50 a3 3d c3  |yy.O.f.....JP.=.|
+00000290  79 0c 71 d9 2f df 93 79  30 8f 6b 0f 54 f9 be 07  |y.q./..y0.k.T...|
+000002a0  f3 d6 9b c0 2a 3a 0a a1  16 03 03 00 98 b8 f1 fc  |....*:..........|
+000002b0  87 62 e9 6b 40 fd 50 ac  b7 fa 52 69 51 66 ae 9b  |.b.k@.P...RiQf..|
+000002c0  05 7e f2 38 73 27 d8 0c  2a 53 37 30 62 76 5d e9  |.~.8s'..*S70bv].|
+000002d0  fd 95 c6 14 d2 9d 34 13  e9 4c a5 7c c0 b6 e0 c4  |......4..L.|....|
+000002e0  97 ef 01 c0 f9 38 39 ee  17 c0 20 01 76 4f a7 10  |.....89... .vO..|
+000002f0  b0 45 9d c7 c3 cd a9 47  14 4a ed 00 1f 06 70 5b  |.E.....G.J....p[|
+00000300  f5 04 8b 77 ad af 1e 77  7a 9d cc fc a4 1f d2 8d  |...w...wz.......|
+00000310  8f e3 31 d3 3c de e6 85  f3 3d c0 ae 78 f7 22 c6  |..1.<....=..x.".|
+00000320  ec 2e a2 f0 5f ed 95 33  54 8c 89 35 c9 e4 25 4b  |...._..3T..5..%K|
+00000330  84 5e 31 83 04 d0 f1 67  69 73 8b 7f 24 ae e0 87  |.^1....gis..$...|
+00000340  6b f7 ba f0 23 14 03 03  00 11 7a c7 6a 32 2b 9b  |k...#.....z.j2+.|
+00000350  25 c2 d2 ee 37 b2 8d 7b  f2 90 6d 16 03 03 00 20  |%...7..{..m.... |
+00000360  c1 1c 9d 18 a9 41 92 fc  05 19 93 7c 7e 2f b2 39  |.....A.....|~/.9|
+00000370  8c 76 4b 29 5a 67 cc f5  55 9f c0 e3 8f ad ee 3c  |.vK)Zg..U......<|
 >>> Flow 10 (server to client)
-00000000  14 03 03 00 11 45 8e f9  74 04 d0 44 c6 94 80 60  |.....E..t..D...`|
-00000010  c1 50 7d b2 64 76 16 03  03 00 20 d5 65 8a b9 26  |.P}.dv.... .e..&|
-00000020  54 70 26 de c6 8a 8f 61  a3 b1 9e 8b 49 40 f7 24  |Tp&....a....I@.$|
-00000030  4f 75 e0 94 e6 e7 68 51  38 8a 37 17 03 03 00 19  |Ou....hQ8.7.....|
-00000040  42 7e 5a e2 46 7b ba 7d  0d 07 20 2a c0 56 fe aa  |B~Z.F{.}.. *.V..|
-00000050  01 eb ca d2 29 1d ff 85  10                       |....)....|
+00000000  14 03 03 00 11 49 66 13  ec 09 83 0d 47 82 45 61  |.....If.....G.Ea|
+00000010  06 14 cc f5 da 41 16 03  03 00 20 34 d4 0c bd 86  |.....A.... 4....|
+00000020  6d ef a9 b6 97 68 e6 88  84 ed 1c 9d a1 8d 2b c9  |m....h........+.|
+00000030  2f 45 75 5b e5 6a 08 72  71 a9 c6 17 03 03 00 19  |/Eu[.j.rq.......|
+00000040  e8 83 4c f5 19 ea d1 ef  e3 27 25 f9 af d2 f0 a6  |..L......'%.....|
+00000050  b3 62 15 66 ec 72 ce 4e  e2                       |.b.f.r.N.|
 >>> Flow 11 (client to server)
-00000000  15 03 03 00 12 1d 01 c7  d5 d5 d1 ce 8c 52 15 8f  |.............R..|
-00000010  75 1e 97 fa 38 5c 65                              |u...8\e|
+00000000  15 03 03 00 12 2e 39 ba  ca ad 7c a9 ae 3f 6a 78  |......9...|..?jx|
+00000010  b6 31 d2 d0 4e 1f dc                              |.1..N..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice
index 006e2d7..20aa6c9 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 47 d0 f5 d9 f0  |....Y...U..G....|
-00000010  59 d1 bf 28 d0 39 36 c0  bc d1 25 fd 5a 63 18 06  |Y..(.96...%.Zc..|
-00000020  1e 8a 5c a6 6f d0 f9 b4  02 23 e1 20 df a0 2a 74  |..\.o....#. ..*t|
-00000030  1a 52 8b d9 90 01 c2 86  69 12 b8 13 58 aa 59 b0  |.R......i...X.Y.|
-00000040  66 79 ff 01 9b 9a 72 1c  a6 83 e6 91 cc a8 00 00  |fy....r.........|
+00000000  16 03 03 00 59 02 00 00  55 03 03 68 39 1d 0e 5a  |....Y...U..h9..Z|
+00000010  22 ba 13 5f b6 c1 52 5d  13 e5 07 18 aa ec 24 0f  |".._..R]......$.|
+00000020  c9 56 3a 83 a1 32 a1 7f  02 e8 7b 20 31 e2 f8 c4  |.V:..2....{ 1...|
+00000030  5b c2 57 9a 1d a4 6f a7  9c 1c 93 b1 9f 19 c3 cb  |[.W...o.........|
+00000040  e1 73 87 1b a8 88 d9 4c  67 2f 44 aa cc a8 00 00  |.s.....Lg/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..............|
@@ -60,284 +60,284 @@
 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 20 97 bd 85 2f cb 85  |........  .../..|
-000002d0  be a8 9c e3 ae 6b 23 a5  5b 18 65 5c f5 cc 24 2b  |.....k#.[.e\..$+|
-000002e0  34 2c 5f c8 4d e9 86 35  0b 08 04 00 80 d2 b6 ee  |4,_.M..5........|
-000002f0  86 76 aa 1d 9c 1c ee ef  0e 59 63 1d ec f1 cf a1  |.v.......Yc.....|
-00000300  f3 5b 6d da 99 9c 40 07  bf 28 ad 72 cd 80 6c 9d  |.[m...@..(.r..l.|
-00000310  bf a2 20 33 2d d0 67 ef  90 28 88 2b d0 8e c6 9d  |.. 3-.g..(.+....|
-00000320  87 7a 18 8f 80 ce 25 92  13 8d ef 38 0a 14 f9 67  |.z....%....8...g|
-00000330  88 94 ef af 97 d2 21 90  9e 24 2f af 1e bb fa 10  |......!..$/.....|
-00000340  4c a7 9f f5 27 63 e6 d8  1a 86 53 c6 3c 15 a8 6c  |L...'c....S.<..l|
-00000350  b9 bc 8f c4 38 1a 4b 34  36 ec af b2 1e d0 bf 58  |....8.K46......X|
-00000360  74 36 ad fb e4 f0 fd 9d  6d 01 cf 51 6c 16 03 03  |t6......m..Ql...|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 57 22 18 98 ed 7f 12  |........ W".....|
+000002d0  e7 e3 83 6b 42 82 ff 49  54 f8 0b 7d 93 3d 11 42  |...kB..IT..}.=.B|
+000002e0  67 cf 89 47 77 31 c5 59  4a 08 04 00 80 69 d4 13  |g..Gw1.YJ....i..|
+000002f0  f8 1c 68 9d 40 10 c8 aa  e6 44 0e 14 b9 38 6e ca  |..h.@....D...8n.|
+00000300  a9 50 05 4a ce a0 03 ea  02 92 e4 5a ed 42 6f 70  |.P.J.......Z.Bop|
+00000310  e1 c1 99 49 a4 34 20 6b  5e 14 e8 a1 d3 27 ff 0d  |...I.4 k^....'..|
+00000320  0c d7 47 49 1e 8f 8a 3a  62 1d c9 81 3c 5f a3 16  |..GI...:b...<_..|
+00000330  16 34 a0 53 a7 01 1d 09  f7 d9 d4 62 b2 0a 1c 1f  |.4.S.......b....|
+00000340  b2 e5 24 1b 7e 78 35 43  ed 47 f8 62 53 2d 04 ec  |..$.~x5C.G.bS-..|
+00000350  81 b5 68 11 3a 2d ee 88  ef 86 eb 71 d0 5e 31 42  |..h.:-.....q.^1B|
+00000360  57 6d b6 f2 be 32 4c 38  f8 2a 93 2f db 16 03 03  |Wm...2L8.*./....|
 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 e8 d5 df  da 49 9a 94 10 30 90 81  |.... ....I...0..|
-00000040  c6 19 54 d4 0d e2 0d e0  d9 a3 c0 21 7f a6 d1 cc  |..T........!....|
-00000050  ea 75 2e 17 01                                    |.u...|
+00000030  16 03 03 00 20 2a 03 0a  58 36 31 ec 26 df e5 7c  |.... *..X61.&..||
+00000040  88 b5 d1 f7 6d fc 4b 0a  91 54 4a e7 8c 83 a3 54  |....m.K..TJ....T|
+00000050  0a 10 5b ff 69                                    |..[.i|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 f3 92 03 fb 7b  |.......... ....{|
-00000010  0f 32 0b 5b dd 9e eb c3  26 2c 92 4d 58 35 a8 96  |.2.[....&,.MX5..|
-00000020  74 d6 d8 0f 61 b2 7d b6  8d ec e6                 |t...a.}....|
+00000000  14 03 03 00 01 01 16 03  03 00 20 27 b0 69 0c 67  |.......... '.i.g|
+00000010  c7 3a ec c1 aa 02 20 cf  f9 e8 22 86 3b d3 e1 4f  |.:.... ...".;..O|
+00000020  bc fd 04 40 19 77 bf bd  38 28 56                 |...@.w..8(V|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 ab 69 44  d0 fe 95 93 ae f9 1b d7  |......iD........|
-00000010  33 6c 59 a5 41 cc d2 1b  ca 2c 63                 |3lY.A....,c|
+00000000  17 03 03 00 16 8a 2c 24  1b b8 53 01 54 c8 bd f3  |......,$..S.T...|
+00000010  e1 ec a9 ab 83 a0 66 a9  29 1c 4e                 |......f.).N|
 >>> Flow 6 (server to client)
-00000000  16 03 03 00 14 99 96 92  c4 82 c8 27 77 a6 f4 ca  |...........'w...|
-00000010  e5 5b ff 78 bc 54 b6 d7  cd                       |.[.x.T...|
+00000000  16 03 03 00 14 c5 e3 03  06 89 d8 47 1a 66 18 0e  |...........G.f..|
+00000010  8d 36 c5 f4 30 80 7e 72  a2                       |.6..0.~r.|
 >>> Flow 7 (client to server)
-00000000  16 03 03 01 16 d9 6a 26  33 e5 d8 df 32 d1 f5 84  |......j&3...2...|
-00000010  1f 37 7f 07 6a ae be 20  84 20 dc 28 31 8e 46 32  |.7..j.. . .(1.F2|
-00000020  0b 96 c8 22 28 fb 98 d9  8e 6f 6d 97 66 55 e2 1e  |..."(....om.fU..|
-00000030  b5 b8 e4 9b 52 25 28 c2  72 cb 9e 14 4c ba 58 6c  |....R%(.r...L.Xl|
-00000040  3b 33 da 56 db fe 14 d3  4c b4 ce a9 57 64 ae 4e  |;3.V....L...Wd.N|
-00000050  5f c5 a7 e6 f4 01 51 d7  81 f4 1d ca fa 3f 86 e7  |_.....Q......?..|
-00000060  9f 64 28 6e 3f e4 ef 79  77 20 64 45 ed a2 16 e1  |.d(n?..yw dE....|
-00000070  b4 63 99 9f 62 6d b7 6d  f4 ad 1f fe d9 de 00 84  |.c..bm.m........|
-00000080  4b bb 0c bc c8 82 a8 1d  8a ac f6 10 2d 5d d4 c7  |K...........-]..|
-00000090  37 f8 fc 89 24 ea c4 b8  87 f4 f4 f0 4b cd db e2  |7...$.......K...|
-000000a0  15 03 95 1e c1 10 7c e8  6d 99 6c e0 bc e1 0a a5  |......|.m.l.....|
-000000b0  d8 36 eb 59 93 6d 1c 96  1c 61 1b 11 36 04 58 6b  |.6.Y.m...a..6.Xk|
-000000c0  c5 b0 fb 8e 9f 21 4a 25  a1 59 ee 5d 1b e3 e3 98  |.....!J%.Y.]....|
-000000d0  71 0a d8 3f 18 f2 b2 1c  6f ec 6d 87 13 b9 d3 25  |q..?....o.m....%|
-000000e0  53 c1 00 78 be 99 82 f6  27 05 24 01 10 1c 59 19  |S..x....'.$...Y.|
-000000f0  94 6a af 7e e5 ae c5 03  14 04 e2 fe 5e 59 e8 e0  |.j.~........^Y..|
-00000100  45 3d af c0 40 ea 84 0a  13 9c d3 0f d4 69 3f 3e  |E=..@........i?>|
-00000110  97 83 ac b5 b9 07 56 9a  19 44 ca                 |......V..D.|
+00000000  16 03 03 01 16 7e eb a3  b5 ea 58 e3 4a 26 35 7d  |.....~....X.J&5}|
+00000010  54 15 93 74 e8 e4 63 34  38 d9 e0 02 3d 28 f8 98  |T..t..c48...=(..|
+00000020  0f 24 6b ca 08 7f b6 77  68 ec 85 c3 4a 6b 69 c3  |.$k....wh...Jki.|
+00000030  8d 8e 1b 8b 41 11 9b 0d  d1 c8 99 2b c9 d2 4c f1  |....A......+..L.|
+00000040  fd 82 e5 35 ba a3 3b f3  6d 47 82 45 08 e7 02 bb  |...5..;.mG.E....|
+00000050  10 a6 7b 76 83 78 e0 aa  5a 78 24 59 1c db ae a3  |..{v.x..Zx$Y....|
+00000060  37 20 b3 12 98 48 68 d3  b3 72 9f 4f d4 de 50 b4  |7 ...Hh..r.O..P.|
+00000070  4a c1 37 93 e0 55 ae e8  37 2a 40 de ac 30 e1 1d  |J.7..U..7*@..0..|
+00000080  f0 03 19 8c af 77 f5 26  98 af a8 a8 d2 72 6c 68  |.....w.&.....rlh|
+00000090  75 00 32 10 e6 3f 91 a8  24 a7 d8 05 23 04 52 23  |u.2..?..$...#.R#|
+000000a0  e7 e6 83 ac 37 1b 36 a7  ca d4 7e d5 21 4c ab 38  |....7.6...~.!L.8|
+000000b0  23 cb 7c a9 f4 66 26 5e  7f 3e d6 ab 7a ac 34 38  |#.|..f&^.>..z.48|
+000000c0  95 16 df e2 e4 cf 3a 62  82 78 cb 71 32 06 6d 07  |......:b.x.q2.m.|
+000000d0  84 91 0c e9 d0 63 88 9e  d1 b5 f0 fb 43 2b 07 0b  |.....c......C+..|
+000000e0  32 d7 20 af b8 76 17 da  ee cc e6 03 bb 7a 0b f2  |2. ..v.......z..|
+000000f0  61 4f db 7f a3 66 b0 05  a8 88 b8 0b b3 6e 9c df  |aO...f.......n..|
+00000100  48 8b 7e eb 42 cd ea eb  1d bb 63 a0 e4 ee df 21  |H.~.B.....c....!|
+00000110  20 67 11 26 dd f1 47 1b  15 2b a0                 | g.&..G..+.|
 >>> Flow 8 (server to client)
-00000000  16 03 03 00 81 4b d8 09  ef 6a 5b a2 c2 e0 2c b3  |.....K...j[...,.|
-00000010  fa e9 21 b3 64 c7 51 8d  d4 14 14 ba 7b 2f f8 1a  |..!.d.Q.....{/..|
-00000020  e9 f8 7a 69 8b 0b b4 5f  26 c5 b6 2e dd c9 90 04  |..zi..._&.......|
-00000030  7d af fd 56 f7 9a 0d 56  09 6c 74 48 49 74 90 71  |}..V...V.ltHIt.q|
-00000040  e1 ee 66 4c 1a da 66 43  50 fa 94 2c 84 21 10 f0  |..fL..fCP..,.!..|
-00000050  00 85 a7 c2 ea 73 19 52  b7 f2 2a e8 17 17 23 67  |.....s.R..*...#g|
-00000060  b6 80 d6 3f e0 a1 ed 81  66 89 0a 0d 48 9f 7f dc  |...?....f...H...|
-00000070  79 c4 27 9b c0 b8 68 ef  2a 5b ab df 8f 82 d6 ff  |y.'...h.*[......|
-00000080  84 38 f8 a4 f2 98 16 03  03 02 69 1f c6 1c dc 85  |.8........i.....|
-00000090  f1 66 8d 7f 7f aa 36 cd  c6 d4 cc 38 c8 8d 98 75  |.f....6....8...u|
-000000a0  92 d2 db b4 49 0c 09 cc  af e6 5b 07 64 76 34 c8  |....I.....[.dv4.|
-000000b0  41 49 85 5e b4 68 ac 35  04 72 00 70 33 f7 5f a7  |AI.^.h.5.r.p3._.|
-000000c0  84 40 34 03 2f 89 25 06  a1 50 dc ea d7 c4 29 57  |.@4./.%..P....)W|
-000000d0  f9 5b 57 63 14 02 1e 74  db 5d 02 cf c4 f1 89 f6  |.[Wc...t.]......|
-000000e0  6a 77 ce 87 5c 3a 61 b8  7d 02 f0 0e 6e 85 2a 51  |jw..\:a.}...n.*Q|
-000000f0  d8 ad 4a 9f 65 04 4c 00  d0 35 76 01 dc 03 cf ca  |..J.e.L..5v.....|
-00000100  6b 11 83 9e 70 33 82 f6  cb eb 4c da 44 76 89 ab  |k...p3....L.Dv..|
-00000110  d4 65 01 e6 08 7b 2a 3d  49 02 39 85 e8 ff 53 fd  |.e...{*=I.9...S.|
-00000120  d0 ce 2a f0 11 3c 02 8f  bd b8 2f ea 81 a1 64 10  |..*..<..../...d.|
-00000130  7b c2 8b 72 f3 32 7b 36  80 13 17 8b 83 dc ce 3a  |{..r.2{6.......:|
-00000140  29 44 06 66 c9 c3 83 cc  28 38 c5 02 7c 3d b6 30  |)D.f....(8..|=.0|
-00000150  55 07 a0 08 bb b3 e1 1e  a8 a5 74 60 51 be ee dd  |U.........t`Q...|
-00000160  aa 83 09 e9 f3 c7 a5 1e  20 fc 6d d5 82 af f5 b6  |........ .m.....|
-00000170  5b 23 dd 81 ce 78 5a 3c  92 c3 96 e1 aa e5 ad 24  |[#...xZ<.......$|
-00000180  da 89 41 44 8b 0b 42 df  e5 28 11 8e 9a e0 06 51  |..AD..B..(.....Q|
-00000190  80 93 15 31 ec 8c 3e 60  92 ab a5 ec 25 5c c5 10  |...1..>`....%\..|
-000001a0  ac 0f 01 1b c4 36 d5 f0  52 c7 0b f7 9b 40 9b c0  |.....6..R....@..|
-000001b0  18 ad 1c eb 49 ed 8e 27  b6 35 b4 20 e0 e6 df 04  |....I..'.5. ....|
-000001c0  69 d6 b5 56 04 30 d4 3d  b0 9f e6 21 66 e7 97 cb  |i..V.0.=...!f...|
-000001d0  2f bd b2 b2 c1 be 4b 4f  6e 88 60 a1 cb eb b4 86  |/.....KOn.`.....|
-000001e0  92 07 da 3c fa 8b 1a de  1c e7 6b c0 53 70 e7 ee  |...<......k.Sp..|
-000001f0  2f 70 4f e0 2a a3 b4 dc  af 64 4f 5a 44 f9 ff fc  |/pO.*....dOZD...|
-00000200  7f 2f 7e 22 13 47 ed f4  ec 0c fa 01 21 e3 c1 d6  |./~".G......!...|
-00000210  c7 53 f4 de 6c 91 c5 85  bd 3c a7 f3 d6 e7 f3 31  |.S..l....<.....1|
-00000220  13 59 b7 ee 0b f7 6a 88  76 94 ab 45 41 9e ab d7  |.Y....j.v..EA...|
-00000230  71 59 7e 45 ed 4d a0 12  4a 81 6a 15 05 a9 21 94  |qY~E.M..J.j...!.|
-00000240  40 f0 1d aa 7e b3 d4 6d  a6 ff 46 94 e6 d0 16 46  |@...~..m..F....F|
-00000250  60 ac c5 15 94 d5 f7 76  1e 8b 90 e6 17 ff 5c 21  |`......v......\!|
-00000260  d0 f9 98 25 0f 98 8b 6c  0f 2c 2a 92 0a f0 90 3d  |...%...l.,*....=|
-00000270  ef 9a 40 67 21 83 f7 5c  95 24 97 f6 45 51 81 4c  |..@g!..\.$..EQ.L|
-00000280  4b e1 64 0a f5 dd 02 fd  8d 21 d1 ef f8 96 70 4b  |K.d......!....pK|
-00000290  58 aa 3c f9 b1 f1 e9 fd  31 ea fc 68 4b c9 fa 79  |X.<.....1..hK..y|
-000002a0  6d 2e 54 d7 1c 9d 5d 62  fc 43 2f cb 6a 48 4d 2e  |m.T...]b.C/.jHM.|
-000002b0  07 71 7b f2 b3 e6 08 8b  13 ca f0 e9 c1 d2 cc 7a  |.q{............z|
-000002c0  9a 49 e9 7b aa e8 bb d2  cf 97 73 b8 9a 3f 8b 01  |.I.{......s..?..|
-000002d0  b9 cf c6 81 fd 99 fc c9  43 08 35 2c a0 fb 38 32  |........C.5,..82|
-000002e0  8b d8 5b d4 20 41 a0 57  e6 34 c1 d8 66 6e 16 e7  |..[. A.W.4..fn..|
-000002f0  78 4f e8 58 16 03 03 00  bc d3 91 f3 88 2f ec 1c  |xO.X........./..|
-00000300  da 94 cb b0 69 70 a2 41  4c fd 40 0d a0 97 01 34  |....ip.AL.@....4|
-00000310  35 83 e6 3f a8 b0 c9 26  8d f1 8a c1 f6 a6 ab a4  |5..?...&........|
-00000320  63 65 5a 10 38 d2 87 a7  8d ae ca 9e c6 23 7e c6  |ceZ.8........#~.|
-00000330  c8 45 37 e8 7c 4b 40 5a  5b 68 19 bb 36 83 81 41  |.E7.|K@Z[h..6..A|
-00000340  b2 fe 7c 39 7e 9f 95 3a  45 2e 9f 96 35 26 81 73  |..|9~..:E...5&.s|
-00000350  4d 0f c3 09 61 32 eb 64  4b 46 76 c1 0e ca cf 02  |M...a2.dKFv.....|
-00000360  6a f3 75 f3 bf aa b0 f8  43 e3 6b d1 c4 27 3e fe  |j.u.....C.k..'>.|
-00000370  06 a2 49 e4 bb 56 c5 c0  5d 36 81 06 97 ed ff a2  |..I..V..]6......|
-00000380  99 78 43 0a c5 20 df a3  ac b7 8f 61 a2 ff 48 66  |.xC.. .....a..Hf|
-00000390  ea c1 b6 57 38 fc 36 7c  dd 30 b5 ce 58 b1 18 82  |...W8.6|.0..X...|
-000003a0  e5 2a 54 d8 4d da f1 fc  98 06 97 43 d5 dc d9 3e  |.*T.M......C...>|
-000003b0  d4 f8 a3 76 9c 16 03 03  00 4a 78 c0 f2 02 60 a4  |...v.....Jx...`.|
-000003c0  8e 9a cd 31 30 e9 16 df  ce 98 bb 95 50 a0 05 48  |...10.......P..H|
-000003d0  6c c2 ce c5 e2 77 f2 4a  d0 45 80 97 98 d4 38 d1  |l....w.J.E....8.|
-000003e0  90 04 91 48 cb 52 40 d3  a4 cb 8d 68 dc 64 9c 07  |...H.R@....h.d..|
-000003f0  cb 8c b9 3b f8 44 fe 47  69 67 fb 2d ab 44 db d0  |...;.D.Gig.-.D..|
-00000400  58 55 83 81 16 03 03 00  14 51 82 e0 57 8e cb 4a  |XU.......Q..W..J|
-00000410  d4 59 6e 58 f7 6d 44 3f  f5 83 64 52 51           |.YnX.mD?..dRQ|
+00000000  16 03 03 00 81 60 70 d6  32 5a 0a 8f df ed cd f2  |.....`p.2Z......|
+00000010  d7 bf d0 da fd 53 63 65  bf f5 26 83 0c f5 6e e9  |.....Sce..&...n.|
+00000020  78 9b 03 7b 17 5f f4 d2  af 2a a3 85 13 92 be 00  |x..{._...*......|
+00000030  93 3f b3 f1 cb 04 aa 55  f8 ed c8 e6 9c 32 08 79  |.?.....U.....2.y|
+00000040  86 84 ef ac 72 bd 93 07  9c ca d2 e7 74 dd 51 a0  |....r.......t.Q.|
+00000050  6d 0e d3 32 3c 33 9d 58  aa 46 a9 ff 22 08 bc 2c  |m..2<3.X.F.."..,|
+00000060  de 81 aa a8 5a 3c f8 36  93 d3 12 06 79 61 1f 71  |....Z<.6....ya.q|
+00000070  5f 45 d7 99 b2 55 10 22  db 56 d9 39 64 57 ad c3  |_E...U.".V.9dW..|
+00000080  59 a9 bd cb f2 22 16 03  03 02 69 34 e7 f2 7a bc  |Y...."....i4..z.|
+00000090  0b 90 72 a3 3b 6b 38 a3  f8 7a 19 39 ff b4 d6 8c  |..r.;k8..z.9....|
+000000a0  c9 92 4f a3 23 1a f0 89  bb 01 e4 b2 24 f7 db 3d  |..O.#.......$..=|
+000000b0  f4 4b 02 75 d0 ca 3c ed  e8 d9 13 61 c5 61 4e 7c  |.K.u..<....a.aN||
+000000c0  fe b9 49 69 63 cc 23 5f  9b 23 85 ec 86 e5 17 28  |..Iic.#_.#.....(|
+000000d0  8a 1e 0c 45 e5 4d c2 be  66 92 47 88 28 ec 52 eb  |...E.M..f.G.(.R.|
+000000e0  72 e5 30 89 58 8d 15 2b  98 eb cd e2 18 7c 53 f2  |r.0.X..+.....|S.|
+000000f0  89 ba 71 a5 91 20 64 17  7c 56 f1 01 8a 52 17 66  |..q.. d.|V...R.f|
+00000100  ef d7 bc 5b ff 54 53 13  2e 80 53 4c 84 6d a2 20  |...[.TS...SL.m. |
+00000110  0f e6 3d 33 90 7a 5b 1a  50 29 ce 1e af 74 a5 b3  |..=3.z[.P)...t..|
+00000120  0e 29 c8 e5 c1 50 b6 5d  c8 bb e4 b5 f5 6b 04 a8  |.)...P.].....k..|
+00000130  24 a6 a8 cc 77 7c 72 d5  b1 f3 6a 1c 2e d7 7e e0  |$...w|r...j...~.|
+00000140  4c 46 3f 26 61 2e 54 7d  ab d8 d6 ec 1e b0 0d d1  |LF?&a.T}........|
+00000150  02 57 00 7f 29 aa d3 1d  a4 40 73 d7 21 12 76 58  |.W..)....@s.!.vX|
+00000160  7d 79 a5 c1 d2 57 63 48  0e 63 5f 24 49 8a 57 ba  |}y...WcH.c_$I.W.|
+00000170  26 1c 39 4a f8 b3 89 79  e2 be 4e 8e 37 ae 16 75  |&.9J...y..N.7..u|
+00000180  42 5e 2e 9b 14 d5 b3 06  5f b9 c8 f7 16 8f eb 1c  |B^......_.......|
+00000190  48 0a da 1e b3 4a 78 f7  f8 b4 35 bf 7d 3f c5 8d  |H....Jx...5.}?..|
+000001a0  fa 7d c0 b7 52 af d3 13  de 96 39 76 fd 49 80 55  |.}..R.....9v.I.U|
+000001b0  bb b3 0f 5b 0c 84 4d 8b  da 62 8a 20 4b a1 28 28  |...[..M..b. K.((|
+000001c0  3d 74 cc 34 9d 95 8e af  c0 05 a2 5c 73 9d 73 d8  |=t.4.......\s.s.|
+000001d0  6c 4e 77 25 c5 8c 22 07  c6 b9 55 47 0c b2 12 73  |lNw%.."...UG...s|
+000001e0  2e f5 95 f7 28 c3 e4 24  2c fd 05 ac e2 3e df 93  |....(..$,....>..|
+000001f0  5a 28 66 aa d4 86 8a 48  e2 c8 69 01 18 90 54 10  |Z(f....H..i...T.|
+00000200  67 80 a1 be a8 9a 7f f3  17 ee dc 83 06 7a 70 6c  |g............zpl|
+00000210  59 c2 2d 8f ff 79 a7 e5  e2 f2 f3 f3 5b 44 42 25  |Y.-..y......[DB%|
+00000220  a3 8c a0 83 07 5c f6 73  e9 bd f5 6b 86 89 b4 11  |.....\.s...k....|
+00000230  7b 9a 28 52 4f 55 70 4a  75 00 73 cc 84 fa 4a ef  |{.(ROUpJu.s...J.|
+00000240  f8 8a 8d f9 18 e2 bc 13  48 cb 80 4d 6f fc d7 23  |........H..Mo..#|
+00000250  3a 9c 6c fd 46 27 94 8a  3d 9d fb 17 f5 06 4d a1  |:.l.F'..=.....M.|
+00000260  18 75 a7 9b 08 f8 47 b5  52 b4 19 4b b7 0f a4 e0  |.u....G.R..K....|
+00000270  78 f8 8b a4 cc eb d3 85  e1 ad 21 29 0f c7 09 28  |x.........!)...(|
+00000280  3f 21 12 6c fd 76 05 13  10 a0 c1 ce ba 7c e8 6f  |?!.l.v.......|.o|
+00000290  e9 99 67 0a 9d 3a 7f f1  a6 8a 53 56 f1 09 22 21  |..g..:....SV.."!|
+000002a0  24 23 6e bc 77 fc 56 3b  31 15 58 1b e9 03 a1 bf  |$#n.w.V;1.X.....|
+000002b0  0a 06 a0 fb 47 77 b7 ad  01 db ee 6a bc a4 a1 77  |....Gw.....j...w|
+000002c0  6f 3e 70 84 4c a6 21 ec  ff fa f0 f0 68 ee 7d b1  |o>p.L.!.....h.}.|
+000002d0  e6 37 f1 1c aa 43 c7 b9  0e c4 52 7d 54 d8 f7 c5  |.7...C....R}T...|
+000002e0  16 21 99 89 cb 02 d0 54  b8 0e 91 2e 58 25 32 6e  |.!.....T....X%2n|
+000002f0  fa ae 62 c9 16 03 03 00  bc 0c 2f 7e 22 d8 7f 21  |..b......./~"..!|
+00000300  0c 1a ec e1 37 72 3f 03  1d cc 73 f9 63 95 cd 47  |....7r?...s.c..G|
+00000310  66 17 60 8c da b4 35 a2  44 b1 d8 d1 1c 98 5b 8b  |f.`...5.D.....[.|
+00000320  c8 9b c8 cb c4 15 0d 8d  08 1e 7c 3a 6b 20 3a f1  |..........|:k :.|
+00000330  d1 86 ae 08 bb fd 74 c5  62 9a 50 74 07 96 10 0e  |......t.b.Pt....|
+00000340  e0 e4 a4 da c4 9d d1 f4  15 97 7d 21 0f 6f cb 39  |..........}!.o.9|
+00000350  8e 4e 40 1a 2a 7f 15 88  94 52 bc fd 61 b8 37 d1  |.N@.*....R..a.7.|
+00000360  48 62 bc 53 a3 a6 62 ec  0e c3 1f 82 67 19 71 fa  |Hb.S..b.....g.q.|
+00000370  99 16 c3 cf d6 82 44 36  9e 0b f0 41 12 ca 7b 67  |......D6...A..{g|
+00000380  c3 a6 2d f7 13 14 0f d1  16 f9 2a 5a dd 43 45 c6  |..-.......*Z.CE.|
+00000390  c0 f4 17 36 64 11 fc ed  e6 66 b6 0c e2 3d fb 72  |...6d....f...=.r|
+000003a0  93 27 46 20 db 1b 24 f9  69 a0 c7 71 e2 27 6a 93  |.'F ..$.i..q.'j.|
+000003b0  36 73 71 10 bd 16 03 03  00 4a cb 15 91 9c 22 96  |6sq......J....".|
+000003c0  f0 c8 b9 4d 9a 6c b0 eb  1a c5 d4 06 12 89 44 1b  |...M.l........D.|
+000003d0  52 cd fb 32 3f 2c 25 f4  d3 88 0f e4 9c 18 91 59  |R..2?,%........Y|
+000003e0  42 98 a8 65 35 62 f7 ce  fa a3 56 46 c5 b1 da ac  |B..e5b....VF....|
+000003f0  9e 4e de 8d 14 fc 3c f3  94 74 50 99 1d 65 6b a6  |.N....<..tP..ek.|
+00000400  a9 38 93 9f 16 03 03 00  14 d7 5b 68 ca 4c 80 92  |.8........[h.L..|
+00000410  f8 13 5d fe 14 22 6f 9a  42 3a 27 de c8           |..].."o.B:'..|
 >>> Flow 9 (client to server)
-00000000  16 03 03 02 69 96 85 13  d5 b1 07 ec bb 1c c1 be  |....i...........|
-00000010  a3 42 10 c8 e0 ec f8 f1  67 29 d5 52 ef bb 32 e8  |.B......g).R..2.|
-00000020  7b e5 a7 3f ab 71 2d 74  20 f7 8a a7 1f bf 7c 4b  |{..?.q-t .....|K|
-00000030  8b 95 db 07 3c ad 86 5e  b3 98 32 e9 5a ce 96 08  |....<..^..2.Z...|
-00000040  c5 64 44 27 fb bc 44 29  49 44 32 3f 64 e8 86 1b  |.dD'..D)ID2?d...|
-00000050  54 63 74 3d a1 99 4d 4a  3e 5a 76 71 39 81 de df  |Tct=..MJ>Zvq9...|
-00000060  90 e4 f6 ac 96 15 0b 70  ad 7e 8a 1d 69 86 65 6e  |.......p.~..i.en|
-00000070  63 bf fb f2 6f 21 d5 66  ad f1 b1 09 05 04 f9 09  |c...o!.f........|
-00000080  0e 0c 12 74 c1 cd f1 5e  fa f1 1b cd 3b 2b 13 8f  |...t...^....;+..|
-00000090  fb f6 fd b0 ca ea 73 1b  38 ad db 6b fd 29 34 db  |......s.8..k.)4.|
-000000a0  51 4a 44 97 a7 2f 2a 98  d6 cc d5 c4 b9 17 23 ab  |QJD../*.......#.|
-000000b0  09 27 15 a5 35 3b 2b 7e  b2 3b fd 12 1b 11 90 4d  |.'..5;+~.;.....M|
-000000c0  81 1b 84 bb fd 72 09 31  5e 78 0e f6 b6 60 44 bb  |.....r.1^x...`D.|
-000000d0  6c 06 72 0b ba ba 60 f6  c1 cb 7e 45 a9 25 44 3d  |l.r...`...~E.%D=|
-000000e0  ba da 71 99 bb 79 b3 73  ef eb c2 cc 07 87 76 f5  |..q..y.s......v.|
-000000f0  e9 7c d9 47 8c fc 7d b7  a0 70 72 04 1e 3d 9b 2f  |.|.G..}..pr..=./|
-00000100  85 9f c8 2f d9 20 4e 00  97 d6 dd dc ae a1 04 96  |.../. N.........|
-00000110  83 e1 4f f3 0d ad 9c ce  5f e7 7b 88 7a b7 d2 ce  |..O....._.{.z...|
-00000120  0a 61 95 d2 78 e3 45 a8  10 5e d9 ae d2 e1 22 bf  |.a..x.E..^....".|
-00000130  59 9c 4a 2c 28 fb c1 b6  89 3b 65 8c 94 a9 f0 7c  |Y.J,(....;e....||
-00000140  86 98 8f 22 c4 18 47 e4  f0 b9 42 dd 34 ab 2a 8e  |..."..G...B.4.*.|
-00000150  fc 8f ce 09 ec 6f 57 6b  d1 ab 32 fd 84 e2 9f 7e  |.....oWk..2....~|
-00000160  f5 b7 5d 26 aa 37 da e9  f3 18 6f 56 74 03 ff 1e  |..]&.7....oVt...|
-00000170  87 95 fb 93 57 2e 32 fb  b3 cf d2 0d 42 02 4f 6a  |....W.2.....B.Oj|
-00000180  9e de ee 6a e6 7e e5 d2  ba cb 00 5d ff b4 6d 7f  |...j.~.....]..m.|
-00000190  23 5e 93 be e9 3a c1 b4  78 30 53 90 07 e4 a7 af  |#^...:..x0S.....|
-000001a0  da e1 29 7d 50 a5 76 ec  a8 5e 96 50 45 26 c4 9d  |..)}P.v..^.PE&..|
-000001b0  c1 99 98 c6 1a bf 93 c1  63 b3 0a 2d af c8 29 7d  |........c..-..)}|
-000001c0  ef b2 d3 8f aa 93 fb be  39 c0 a1 65 51 e8 6e c4  |........9..eQ.n.|
-000001d0  45 cb 2a 52 b7 ec e0 48  c0 b2 cc c7 72 12 18 e0  |E.*R...H....r...|
-000001e0  c7 9f fa 09 97 95 16 9f  f4 5d 70 c5 d6 7f 23 d5  |.........]p...#.|
-000001f0  53 98 d0 80 50 9b 52 46  11 d4 97 ea 47 26 f5 6f  |S...P.RF....G&.o|
-00000200  66 7b 8a cc f8 8d 70 c7  ec fa 72 de ba ac d4 b2  |f{....p...r.....|
-00000210  be 7d d8 78 44 dd de 66  53 26 f4 c0 8a 67 61 cb  |.}.xD..fS&...ga.|
-00000220  46 34 3d 6f 9e 9b dc ee  4a b9 5c 67 2b d9 87 2a  |F4=o....J.\g+..*|
-00000230  35 42 1c 3e b8 08 c9 32  13 a6 6f fc 4d cc be dd  |5B.>...2..o.M...|
-00000240  ad 76 19 1c 2d b3 6e 04  a1 17 05 93 b9 69 27 42  |.v..-.n......i'B|
-00000250  23 13 7b c0 f1 53 9c b5  1d 8e 5c f6 40 7e 5a e9  |#.{..S....\.@~Z.|
-00000260  20 dd 18 7a 0c f2 7b 5a  ec 3d 4e 3b 29 b2 16 03  | ..z..{Z.=N;)...|
-00000270  03 00 35 15 15 54 38 4e  87 f1 c1 9a 90 b2 74 df  |..5..T8N......t.|
-00000280  72 34 aa 0b 41 f3 df b4  c5 fd 50 00 2a 36 a8 d5  |r4..A.....P.*6..|
-00000290  c4 49 ac b8 58 3e 89 48  cb a9 4e b1 a9 0f ee 51  |.I..X>.H..N....Q|
-000002a0  37 d3 60 ca 23 76 68 0b  16 03 03 00 98 53 3c 0e  |7.`.#vh......S<.|
-000002b0  d5 3b d3 78 9f 47 5d 9e  1b b6 04 5f d4 04 66 55  |.;.x.G]...._..fU|
-000002c0  68 bd d7 ab 54 b7 e5 9a  12 9b 0c 1d 75 7b c7 35  |h...T.......u{.5|
-000002d0  e3 9e 9d a0 8f 61 7a 32  d1 a7 23 2a b6 ba 48 7c  |.....az2..#*..H||
-000002e0  1a 62 66 61 b4 3d e8 e3  a9 4e 85 7a 8d 5b f3 69  |.bfa.=...N.z.[.i|
-000002f0  c8 bc 0a 8a c7 e4 df 78  9b a8 cf 1d 37 14 90 a5  |.......x....7...|
-00000300  a8 ce f7 1f e7 a3 e5 d8  97 be 95 fd d3 c0 d0 81  |................|
-00000310  bf a6 e1 b3 6b 29 ee c6  16 3c 4c 68 6e b4 42 72  |....k)...<Lhn.Br|
-00000320  84 a0 97 0f 0e b2 44 0c  4f c6 df 04 b7 bf d8 e7  |......D.O.......|
-00000330  08 af 33 35 56 ed 6b cc  42 a8 9f 8e 59 9c 9c 32  |..35V.k.B...Y..2|
-00000340  29 77 87 6e d6 14 03 03  00 11 97 7a db d1 50 96  |)w.n.......z..P.|
-00000350  68 b7 04 90 79 fd f3 79  ed f3 de 16 03 03 00 20  |h...y..y....... |
-00000360  16 57 80 e9 30 65 46 29  74 09 32 70 13 1f f8 5d  |.W..0eF)t.2p...]|
-00000370  54 3f 14 4b af a1 51 b3  cd 1f e6 01 d6 68 11 fc  |T?.K..Q......h..|
+00000000  16 03 03 02 69 aa 39 9e  c8 e7 89 97 7f 22 3c 28  |....i.9......"<(|
+00000010  76 ac d9 48 51 e0 cd 22  53 a1 6d e7 b4 00 27 7d  |v..HQ.."S.m...'}|
+00000020  89 4b f0 54 d8 39 d0 a3  fc 35 a6 36 4b 3c eb 3a  |.K.T.9...5.6K<.:|
+00000030  00 b0 c1 17 9d c8 13 a5  58 ba 16 9e cb 21 50 dd  |........X....!P.|
+00000040  8a e0 2d 57 dd a6 bf 4d  6e b3 21 3b 46 f4 c3 77  |..-W...Mn.!;F..w|
+00000050  a1 86 07 c7 db e9 0a cb  2d 0f ff b5 1b ad 6b c4  |........-.....k.|
+00000060  c4 a4 4e 14 cf cb b2 6c  07 65 17 d2 db 30 e9 ec  |..N....l.e...0..|
+00000070  41 4e 78 26 12 27 08 a6  a7 84 39 c0 4b e7 4b 23  |ANx&.'....9.K.K#|
+00000080  2f ca ff 1e 41 9a e8 44  fc 5d a0 34 4e ca a8 6d  |/...A..D.].4N..m|
+00000090  31 51 57 c9 7e d1 0a 42  22 f2 b4 f9 a7 f9 28 d8  |1QW.~..B".....(.|
+000000a0  2a dd 19 0d 90 8b e1 78  b1 1c da 3a bb 5e 05 54  |*......x...:.^.T|
+000000b0  0d 0e f8 73 ed 01 e2 e4  d4 c1 f8 fa c3 d6 6f 42  |...s..........oB|
+000000c0  cc cb 99 99 97 18 b0 fb  ab 51 42 66 45 67 b6 29  |.........QBfEg.)|
+000000d0  02 60 ab 74 30 db f6 16  8a 8f 8e 9c cc d5 47 fa  |.`.t0.........G.|
+000000e0  f5 af 94 4f b1 94 40 57  ab 85 59 e4 3e cc c5 a0  |...O..@W..Y.>...|
+000000f0  61 b7 64 f9 dc 96 40 ae  fb 4c 57 39 9e 9a 23 8e  |a.d...@..LW9..#.|
+00000100  c9 36 6c 75 11 c7 6e 54  c3 1c e9 25 6a a0 f8 bb  |.6lu..nT...%j...|
+00000110  6b 5c ca 5c 06 6c 03 88  01 27 4c 89 02 e6 b6 1a  |k\.\.l...'L.....|
+00000120  92 99 4d 15 c1 1a aa 58  20 49 d7 4a f9 09 34 1e  |..M....X I.J..4.|
+00000130  d7 d8 31 79 9f d8 b3 a0  76 ba 96 77 77 77 5b 80  |..1y....v..www[.|
+00000140  88 ab a0 90 c7 5f 3d 82  e1 23 29 6e 3a 4d 9b f0  |....._=..#)n:M..|
+00000150  7b 6a b1 9d 78 ba 4c 7e  02 1f a0 73 3e 91 cf 75  |{j..x.L~...s>..u|
+00000160  c6 52 2d c6 79 be 85 65  0e e4 73 39 fe 53 6d e0  |.R-.y..e..s9.Sm.|
+00000170  a3 18 d5 69 80 ca f1 c8  ad f5 f4 fb b5 40 2e f8  |...i.........@..|
+00000180  30 82 ca 2c 46 6a ab a6  b2 83 9f a8 95 95 30 e3  |0..,Fj........0.|
+00000190  e3 30 6d f5 7c 83 96 af  12 d8 d6 d6 f9 6a ad bd  |.0m.|........j..|
+000001a0  bb 96 83 99 99 d8 6d 20  0e e1 be da 58 05 44 88  |......m ....X.D.|
+000001b0  a6 07 47 84 d4 77 fc 9b  fb d7 ac 60 70 0b e7 76  |..G..w.....`p..v|
+000001c0  13 c7 38 d9 3d 60 eb a6  9f a5 6d fc 5c d5 f6 2f  |..8.=`....m.\../|
+000001d0  31 02 38 65 8d be 04 06  84 95 86 b1 84 d9 ce c7  |1.8e............|
+000001e0  30 b9 d3 85 9f 1b 12 0f  5c 0e d6 8d e3 a0 15 04  |0.......\.......|
+000001f0  03 62 9d 52 7b e7 f4 13  aa 02 64 d9 d4 4b fd 6f  |.b.R{.....d..K.o|
+00000200  de ea 4a aa 91 60 e7 78  af 84 b5 9d c3 d2 c6 3a  |..J..`.x.......:|
+00000210  2a 9f 9b c6 8d 9e 5e 2c  90 6c d3 9d c1 be 96 5a  |*.....^,.l.....Z|
+00000220  60 d8 73 6c 49 50 c8 03  ec 58 73 bc b3 8c 30 c1  |`.slIP...Xs...0.|
+00000230  f4 a2 7d 74 3d 8d 7e 64  c1 a7 b6 24 13 06 72 1b  |..}t=.~d...$..r.|
+00000240  d0 87 22 af df 2a e7 fe  57 fa db e7 00 ba 74 35  |.."..*..W.....t5|
+00000250  16 34 20 3f 75 69 35 5f  64 7e 26 56 7c 93 05 4e  |.4 ?ui5_d~&V|..N|
+00000260  42 65 b8 bf 59 8e 82 13  f1 d0 05 95 c2 3d 16 03  |Be..Y........=..|
+00000270  03 00 35 99 1d 52 84 73  d6 e7 90 f6 41 9e 69 07  |..5..R.s....A.i.|
+00000280  39 0b bc b6 c7 f4 f2 a0  93 80 b9 c7 bb b4 a6 06  |9...............|
+00000290  50 5b 5d 75 97 cf c5 dc  2d 07 3d 8f 9e ae fa bf  |P[]u....-.=.....|
+000002a0  5b 6b 3e 98 02 fd e4 7d  16 03 03 00 98 80 ac e9  |[k>....}........|
+000002b0  4e e0 f8 b5 8c c2 2e 84  ec e0 3b eb b7 a0 14 2d  |N.........;....-|
+000002c0  ff d2 bf 35 14 20 06 00  2e 48 c7 f8 a3 fd 4f 50  |...5. ...H....OP|
+000002d0  4a 04 3e c7 07 50 90 72  29 f0 5c ac e1 fd 9d 3f  |J.>..P.r).\....?|
+000002e0  42 99 77 32 a9 79 24 7f  9e cc 84 1c d0 db 87 1c  |B.w2.y$.........|
+000002f0  3c 9a ae e3 45 e5 67 83  5f 75 e9 27 f3 ef 8a 15  |<...E.g._u.'....|
+00000300  88 2b 3f cc 6f 6f a4 78  d5 b2 96 3e 72 d4 c8 43  |.+?.oo.x...>r..C|
+00000310  98 a7 60 ae 38 8e fe 21  49 5b c2 80 d6 ef 6f 9b  |..`.8..!I[....o.|
+00000320  08 18 07 c2 64 00 a1 a0  09 8b b4 b7 eb 0c 68 30  |....d.........h0|
+00000330  26 87 f9 99 85 63 35 81  5a e4 31 19 9e f8 b8 7b  |&....c5.Z.1....{|
+00000340  81 aa 24 ff cd 14 03 03  00 11 84 c7 e1 8f 74 66  |..$...........tf|
+00000350  e6 bd 14 55 a8 d3 67 30  2d c4 fb 16 03 03 00 20  |...U..g0-...... |
+00000360  3a 63 a5 86 f3 78 f1 62  18 77 f7 25 71 52 56 17  |:c...x.b.w.%qRV.|
+00000370  d2 a5 e4 fa bc bb 44 07  85 37 cb 36 84 c7 6a 97  |......D..7.6..j.|
 >>> Flow 10 (server to client)
-00000000  14 03 03 00 11 1b a8 a8  a9 c6 a8 85 60 bc 14 0d  |............`...|
-00000010  86 ce a5 0f 45 17 16 03  03 00 20 cb 3a 73 db 55  |....E..... .:s.U|
-00000020  05 7e 3e 4b 6d d0 eb ca  68 39 bf 71 ba 6c e5 0c  |.~>Km...h9.q.l..|
-00000030  a7 90 d6 c1 b8 55 87 c6  20 40 35 17 03 03 00 19  |.....U.. @5.....|
-00000040  28 50 71 7c f0 7c 1e 61  fb de 5d d1 bb 77 f6 c8  |(Pq|.|.a..]..w..|
-00000050  a4 76 8d ab d4 c2 fe 27  96 16 03 03 00 14 e4 7e  |.v.....'.......~|
-00000060  51 bb 26 a8 9c 0c b0 25  7a 57 b9 98 c2 20 5a 50  |Q.&....%zW... ZP|
-00000070  07 ca                                             |..|
+00000000  14 03 03 00 11 9e 99 89  2d 10 21 a1 38 04 77 1a  |........-.!.8.w.|
+00000010  f8 1d b4 01 d1 9f 16 03  03 00 20 2a cb 67 8b 1b  |.......... *.g..|
+00000020  44 26 41 7b c4 6d a1 f4  cb ee 15 87 01 65 18 5a  |D&A{.m.......e.Z|
+00000030  c7 2d 10 e4 91 01 cb 22  e8 92 1a 17 03 03 00 19  |.-....."........|
+00000040  1a 46 a0 9a c5 1a 27 0c  e2 f9 03 55 3a e8 43 a7  |.F....'....U:.C.|
+00000050  d7 47 a5 95 6a e7 a1 12  69 16 03 03 00 14 d6 e0  |.G..j...i.......|
+00000060  1d 89 e0 c2 9a 52 d5 bc  d4 08 3e f6 81 dd 57 a2  |.....R....>...W.|
+00000070  25 f6                                             |%.|
 >>> Flow 11 (client to server)
-00000000  16 03 03 01 16 66 3c 1a  62 c3 4a f9 e4 66 01 d4  |.....f<.b.J..f..|
-00000010  f7 e8 5a fb 95 c4 40 33  d4 af 61 78 d6 54 91 2b  |..Z...@3..ax.T.+|
-00000020  62 72 d5 7b b8 2c 71 11  4e 0c 2d 79 6d 41 b1 9e  |br.{.,q.N.-ymA..|
-00000030  df 59 d8 e0 5c 72 98 b5  29 55 1e 9b 01 a5 af 2c  |.Y..\r..)U.....,|
-00000040  c3 87 4b f0 c8 ca 4d 56  fb 3a 7e 04 e5 b6 4f 6d  |..K...MV.:~...Om|
-00000050  1e 53 26 5d af fb 17 ee  97 87 45 2f df 1b 21 80  |.S&]......E/..!.|
-00000060  21 81 2b 18 2d 2d e9 3c  c4 01 32 91 b7 88 27 9e  |!.+.--.<..2...'.|
-00000070  26 40 e7 6a 27 c5 a0 b4  a3 ed 4d 4b a4 e3 0b c7  |&@.j'.....MK....|
-00000080  49 42 ca ef e9 16 5c 98  8d ab fc 7d 00 83 03 89  |IB....\....}....|
-00000090  a4 97 1e 3f 9e d8 ba c5  f5 2a 0b 0a ed a0 a5 59  |...?.....*.....Y|
-000000a0  27 03 36 7e 94 d8 9a 3c  fc f6 f6 52 b6 a7 fa 36  |'.6~...<...R...6|
-000000b0  04 83 2f e7 99 e5 1c 56  27 48 13 a0 59 ca ca 3b  |../....V'H..Y..;|
-000000c0  36 2d 25 e8 6f 6a cb 07  74 f8 1b 7d ba 3e 6e e1  |6-%.oj..t..}.>n.|
-000000d0  1d 3e 93 c6 23 f4 eb bf  ad 62 21 1a da 53 e1 13  |.>..#....b!..S..|
-000000e0  0a 3a 9c 57 48 d5 ee d3  72 af c3 74 fc 74 67 7d  |.:.WH...r..t.tg}|
-000000f0  b4 76 fc 21 55 67 49 92  fc 71 5d 42 69 d6 01 b5  |.v.!UgI..q]Bi...|
-00000100  83 4e b8 cd f9 ed 28 41  ae 95 2f d6 69 b0 d3 b8  |.N....(A../.i...|
-00000110  bd 06 d6 00 74 44 c9 47  aa 8e 1d                 |....tD.G...|
+00000000  16 03 03 01 16 27 50 ce  c0 8e 5a e2 54 55 cb c0  |.....'P...Z.TU..|
+00000010  08 c7 20 87 7e 78 c6 da  a6 7a 62 fd 7f f5 87 b3  |.. .~x...zb.....|
+00000020  83 a0 c8 70 ab 57 9b ca  bf 4c 07 06 f1 89 b9 b6  |...p.W...L......|
+00000030  24 f0 ae 72 e1 36 31 9f  74 ed 06 ad 44 3b 51 2c  |$..r.61.t...D;Q,|
+00000040  ed f0 c2 d8 9b 27 d2 9a  ec 44 88 80 7c 5a d0 66  |.....'...D..|Z.f|
+00000050  3d 84 e3 7c 24 89 b9 dd  8c eb 86 cd ce 69 0d e3  |=..|$........i..|
+00000060  97 ee ad 74 53 7f 9c f0  05 31 43 2a 8c 09 c4 11  |...tS....1C*....|
+00000070  46 3e 82 2c 3c 69 91 d1  eb 4b 8a ab a9 cb 24 00  |F>.,<i...K....$.|
+00000080  00 25 bd 26 d3 85 19 ff  3b 2b 92 3f 43 b0 9f 24  |.%.&....;+.?C..$|
+00000090  59 4f 3d a6 ce 65 27 5c  75 47 92 7b 4a d3 ca 55  |YO=..e'\uG.{J..U|
+000000a0  38 00 ac 37 0c 6e 2d 04  bc 6e fe 3a 9a 43 b6 7f  |8..7.n-..n.:.C..|
+000000b0  18 c1 a6 ce 49 b4 61 d3  97 8d a2 c9 fb fb cd 23  |....I.a........#|
+000000c0  f6 2f 0c 0b 2a b8 31 9e  fd ff 9f 44 1e 33 c3 23  |./..*.1....D.3.#|
+000000d0  bf 09 d2 de 90 b6 61 9c  33 33 33 46 bc 00 7e 16  |......a.333F..~.|
+000000e0  3c bd 82 2d 31 51 5b 11  87 ec 7f 25 d8 95 f9 9c  |<..-1Q[....%....|
+000000f0  df 00 54 40 f3 c1 08 fa  ef ba bc 5d b1 96 ae 8f  |..T@.......]....|
+00000100  35 0e 43 b2 50 c7 7e c4  b2 71 2e 40 3a b7 90 2b  |5.C.P.~..q.@:..+|
+00000110  81 ac 00 14 9d da d8 ca  5e 25 62                 |........^%b|
 >>> Flow 12 (server to client)
-00000000  16 03 03 00 81 d3 99 6f  14 2b a1 f4 d7 45 c9 94  |.......o.+...E..|
-00000010  69 0b b3 72 f4 2c 2e 5c  80 96 09 20 2f 63 a1 e4  |i..r.,.\... /c..|
-00000020  8b df d7 22 11 71 bd 17  db da 2d c6 78 e8 9a 95  |...".q....-.x...|
-00000030  6b 39 34 a2 13 7f 39 77  8b e5 1b 6c 4b 20 79 40  |k94...9w...lK y@|
-00000040  a1 d9 69 89 b1 e2 60 8a  75 88 ae 83 b9 4f 42 a4  |..i...`.u....OB.|
-00000050  c9 c7 44 ac 0d 3f 1c ca  49 f9 a7 05 e2 c7 05 cd  |..D..?..I.......|
-00000060  30 30 d2 f9 c2 87 60 33  3b 25 d0 e0 5e c2 bd 98  |00....`3;%..^...|
-00000070  9c 51 d8 38 c9 ef 04 f4  39 30 50 b6 35 53 f6 95  |.Q.8....90P.5S..|
-00000080  eb 5d 67 05 62 9a 16 03  03 02 69 39 94 a1 8d 01  |.]g.b.....i9....|
-00000090  37 64 c6 be bb 9c 22 9d  56 e8 68 ab 0f 7a 3a e7  |7d....".V.h..z:.|
-000000a0  2d 26 b7 ba 3e 54 38 b3  32 9d 7b d7 43 c4 d2 b3  |-&..>T8.2.{.C...|
-000000b0  9a 84 62 73 03 7a f2 68  ec 3e 41 d2 68 c9 22 1a  |..bs.z.h.>A.h.".|
-000000c0  e9 4d 9c e8 80 6a a9 9e  6a bd 67 5d 77 97 8b f7  |.M...j..j.g]w...|
-000000d0  32 cb 3a cb c2 c0 a1 40  7e 63 81 5f 19 a5 71 20  |2.:....@~c._..q |
-000000e0  c3 76 88 ae 5c d4 bd 54  08 e7 7e e7 77 7e 3d 91  |.v..\..T..~.w~=.|
-000000f0  b5 40 f7 7e 95 d5 e3 f2  e5 4a 57 f6 d9 94 df 07  |.@.~.....JW.....|
-00000100  56 45 09 c4 bc 65 05 04  57 f4 00 c5 91 4c dc 4d  |VE...e..W....L.M|
-00000110  a0 1e c6 e2 37 35 d0 5a  e9 79 ce f5 91 6d 3e 39  |....75.Z.y...m>9|
-00000120  c3 68 6a 76 6d f3 29 1d  e0 ef b2 20 3e 2a ac 11  |.hjvm.).... >*..|
-00000130  7e 11 2d a3 84 60 94 b5  8e 3a e6 4b 34 70 aa f8  |~.-..`...:.K4p..|
-00000140  e3 f9 0f 2c a4 bf 5b 27  7e c9 5e 6f c0 11 b4 ff  |...,..['~.^o....|
-00000150  53 6b 98 ee 20 77 87 87  fc 8e 30 1b 8f 74 29 af  |Sk.. w....0..t).|
-00000160  a2 c7 e8 c1 da e5 d7 0f  70 ec 27 23 46 3f 16 b1  |........p.'#F?..|
-00000170  59 bd 43 76 09 1d 8c f4  eb 17 10 a5 c1 1a e0 c6  |Y.Cv............|
-00000180  45 e2 d2 dc 6d f4 9a 87  36 ef 71 18 5c 1d e7 7c  |E...m...6.q.\..||
-00000190  40 d6 4c 16 ee 58 75 d7  56 9f 2e 17 80 1d 74 1c  |@.L..Xu.V.....t.|
-000001a0  fd 86 7c 2b 05 ac ef 07  18 a3 98 73 fa 9c 16 6c  |..|+.......s...l|
-000001b0  14 95 37 91 1e a2 c7 47  a8 87 11 35 30 d8 ed 60  |..7....G...50..`|
-000001c0  ba 65 ee 66 2b 1f db 67  c2 d0 71 26 3d ae 17 94  |.e.f+..g..q&=...|
-000001d0  f0 f6 65 01 bb 1d 85 7e  b3 d8 2c f1 96 c5 d5 e0  |..e....~..,.....|
-000001e0  97 a4 3e df 97 ff 8f 4b  e3 72 49 c4 5b 87 4e 06  |..>....K.rI.[.N.|
-000001f0  93 11 75 04 7b 80 9d 1c  a7 85 a3 2c f1 16 8a b9  |..u.{......,....|
-00000200  78 6b 27 1e 9a e3 86 eb  f9 42 95 10 02 d5 b6 01  |xk'......B......|
-00000210  b3 94 04 63 49 50 9e 11  71 07 aa a1 d6 9d d1 db  |...cIP..q.......|
-00000220  f4 ea 2e bb fa ca 1e 00  53 75 70 de 0a 72 eb 55  |........Sup..r.U|
-00000230  ab b7 ff 30 ad 5e 7e 13  90 75 42 5d 07 07 21 0f  |...0.^~..uB]..!.|
-00000240  db a6 f4 61 9c bf 31 34  e4 98 bb c4 ac 41 2d 76  |...a..14.....A-v|
-00000250  fb 6c 30 b0 e2 98 5f ed  d9 a8 42 d7 75 a1 bc 36  |.l0..._...B.u..6|
-00000260  f2 3e c5 ac 50 ae c7 2e  42 35 6c 1a 47 aa 1f 0a  |.>..P...B5l.G...|
-00000270  2f ff 6e 0a a5 c4 b5 a5  92 3f 54 d0 4e 62 6e 3e  |/.n......?T.Nbn>|
-00000280  cb 07 2d 4d 1a fb 94 5b  f8 d0 5b 26 34 2b 1b 26  |..-M...[..[&4+.&|
-00000290  8c dd 91 a7 66 21 89 d0  11 24 a5 5f 99 ae 62 84  |....f!...$._..b.|
-000002a0  34 9c d2 45 71 74 8c 68  db 8b ad 6f df 08 35 38  |4..Eqt.h...o..58|
-000002b0  ed 5c 3b 3e 55 a1 c3 16  b6 61 f4 4d 6d d0 2a 5d  |.\;>U....a.Mm.*]|
-000002c0  10 fb 64 c9 6f 87 6f 3d  ff d1 a0 97 64 b4 12 f9  |..d.o.o=....d...|
-000002d0  2a a8 46 59 1b e4 6b d8  c9 3e ac 14 00 4f 1a e6  |*.FY..k..>...O..|
-000002e0  26 9b 86 32 a3 9b 37 eb  c1 cf 9a 70 16 2e 4a b0  |&..2..7....p..J.|
-000002f0  6e e5 fc c2 16 03 03 00  bc bf c4 ea e0 dc be fe  |n...............|
-00000300  33 7f ef 2b d9 50 f7 87  d5 30 2b 09 bb 63 1e 4c  |3..+.P...0+..c.L|
-00000310  9c 3c a9 10 4e 04 e1 85  29 44 f9 ea 32 61 12 6e  |.<..N...)D..2a.n|
-00000320  63 0f d9 e7 e9 c8 81 a0  eb 4e fe 90 bf f4 f4 af  |c........N......|
-00000330  22 66 21 86 dc 2c f6 ed  b1 be eb b1 ac 14 f5 ce  |"f!..,..........|
-00000340  6c b9 a8 45 e4 3f 09 d1  b1 f3 69 f7 df c4 f0 6c  |l..E.?....i....l|
-00000350  48 f6 15 80 8a b8 b0 39  0e e9 22 9a 5c 72 f9 fa  |H......9..".\r..|
-00000360  95 01 9d ca e4 68 ef 72  e2 34 28 a5 04 5d d2 30  |.....h.r.4(..].0|
-00000370  c6 33 80 a8 f1 8f fb 6c  ec 15 c3 7c 68 7c a2 2e  |.3.....l...|h|..|
-00000380  4d ba 64 af fb f5 b8 f7  6b 6b 8c 5c 56 dc dd 69  |M.d.....kk.\V..i|
-00000390  39 d8 73 75 e3 be 17 09  3f 80 ed cc 12 5b ca d9  |9.su....?....[..|
-000003a0  e6 e2 50 88 41 0b 39 8e  84 6f fb 6a c3 8e 4f fc  |..P.A.9..o.j..O.|
-000003b0  dc 18 ca 02 18 16 03 03  00 14 5e ac 52 4d 0b 89  |..........^.RM..|
-000003c0  33 7d fe 1c d9 b5 1d 1c  2b 6d d4 4f 12 33        |3}......+m.O.3|
+00000000  16 03 03 00 81 37 3a f4  1b 6a 43 d2 6a 02 02 33  |.....7:..jC.j..3|
+00000010  b9 d5 9a 5c d1 3b 52 73  f2 27 a6 c0 f0 9b dd f3  |...\.;Rs.'......|
+00000020  d7 cd 89 ec 21 e0 d3 2f  4d 6c b0 cf 50 a7 39 43  |....!../Ml..P.9C|
+00000030  c2 56 d2 f8 45 d7 3c a6  b6 b9 06 3f ca a7 f8 37  |.V..E.<....?...7|
+00000040  4c 89 01 49 82 5f 27 15  3c bf f0 86 7c 1a 84 03  |L..I._'.<...|...|
+00000050  5a 90 77 03 01 fd b8 60  2a be cc 60 c6 54 b5 ec  |Z.w....`*..`.T..|
+00000060  c1 5d 6b e6 f0 2c 8c e6  7e e3 b6 c3 8b 63 3c 69  |.]k..,..~....c<i|
+00000070  ac 2c 9a 24 a7 77 5f 0c  36 08 68 6c 8b 76 f1 80  |.,.$.w_.6.hl.v..|
+00000080  4a bf f7 e6 15 5b 16 03  03 02 69 a1 ce a6 de 44  |J....[....i....D|
+00000090  cf d6 f7 88 f4 da 01 06  2b e5 cf 54 8d f6 78 ab  |........+..T..x.|
+000000a0  53 c5 ea d9 97 4b 94 22  24 9b 98 ba ba ee 42 9d  |S....K."$.....B.|
+000000b0  c3 e4 12 e3 be 35 24 86  3d 38 a0 6e b7 e6 cf dc  |.....5$.=8.n....|
+000000c0  e7 5c e1 0d 7c 05 bb 63  7c 8b c4 a4 db 9a 85 a4  |.\..|..c|.......|
+000000d0  ba d6 d4 79 38 79 01 52  2d cf c1 c7 6e 09 64 ff  |...y8y.R-...n.d.|
+000000e0  e9 b6 3e f2 a0 2b 4c 91  3f e2 fe 1a 40 4b 14 ea  |..>..+L.?...@K..|
+000000f0  77 8f 40 1c a2 96 7c d3  ce 34 5e d8 13 5a 82 33  |w.@...|..4^..Z.3|
+00000100  41 59 fa d9 81 1c 85 41  9c 61 b9 ca d5 46 e2 77  |AY.....A.a...F.w|
+00000110  3d a9 50 4f 11 b1 34 aa  ae fd e5 ec fe 12 e6 10  |=.PO..4.........|
+00000120  36 84 fb 25 f8 a4 6f 44  e3 ac 89 67 e4 9a 02 c4  |6..%..oD...g....|
+00000130  8f a9 4a d0 f4 64 e2 de  da 80 02 60 cb a9 2d e0  |..J..d.....`..-.|
+00000140  fa d9 b9 ee 43 e1 3e ed  79 79 6b 21 62 3d 6f b0  |....C.>.yyk!b=o.|
+00000150  77 53 db 26 60 e1 d6 ff  a7 01 2b b7 f0 49 df b8  |wS.&`.....+..I..|
+00000160  bc d9 ac 77 80 f8 53 66  16 8d 3a 8d 63 fa 12 e1  |...w..Sf..:.c...|
+00000170  ed f7 8b c0 40 46 16 70  e3 db f3 38 87 9f 11 eb  |....@F.p...8....|
+00000180  0b f5 b3 44 e4 16 e1 ed  85 e6 67 d5 35 60 20 99  |...D......g.5` .|
+00000190  7d bd 9f 65 b9 52 68 6c  6b 83 f9 06 e3 a7 3e 0f  |}..e.Rhlk.....>.|
+000001a0  9e 7c a5 ac 87 7a 45 53  a5 3f 27 5b 99 a9 34 c2  |.|...zES.?'[..4.|
+000001b0  5a 44 9a 30 08 30 c6 ff  60 8a a5 72 f7 49 d3 7c  |ZD.0.0..`..r.I.||
+000001c0  1f f9 8b 74 a0 b1 c8 65  84 6d 91 86 ab 1e 82 3b  |...t...e.m.....;|
+000001d0  d5 c4 bb 06 b3 31 61 bb  0e 65 3e 18 4d 0c c1 c1  |.....1a..e>.M...|
+000001e0  9d 7f ea ad cf 53 2e 9c  1c 7e aa c8 84 9e 0d ce  |.....S...~......|
+000001f0  91 53 3c d4 05 7e 57 d1  8b 55 ea e4 6e 57 90 4c  |.S<..~W..U..nW.L|
+00000200  bb 74 9c 87 1c 6a 89 cf  2c 50 8d 04 04 e6 18 c8  |.t...j..,P......|
+00000210  0c 9f 38 84 f4 f4 94 8d  33 2b a1 27 0b 5c 6a 2a  |..8.....3+.'.\j*|
+00000220  0c 13 b7 07 b7 a0 c9 e5  3c 9d 5a 7e 96 c9 53 fc  |........<.Z~..S.|
+00000230  ff c4 3a 8f 16 1f 2d 64  50 1d 13 c3 55 fb af d2  |..:...-dP...U...|
+00000240  0e f9 e6 18 e3 62 ce 6a  8f 96 ff 00 0e fe 27 53  |.....b.j......'S|
+00000250  70 57 53 2d fd f3 02 c7  fe b3 19 49 88 27 7e a2  |pWS-.......I.'~.|
+00000260  42 7b 22 d0 77 4e e5 04  aa 0d b6 9d b9 48 97 ab  |B{".wN.......H..|
+00000270  33 e7 14 97 65 82 f9 2c  dc 71 9e 4b eb ed 42 73  |3...e..,.q.K..Bs|
+00000280  c6 c8 93 8a 3a 24 bd f9  b4 6a 95 c1 1b 22 1d f5  |....:$...j..."..|
+00000290  c8 33 c5 38 1e a7 2e 91  68 35 4c 0a 37 57 ac e2  |.3.8....h5L.7W..|
+000002a0  c9 37 9e d9 1c b8 76 73  c2 d2 0c d0 c4 a1 c0 d5  |.7....vs........|
+000002b0  72 39 bf 03 f7 8d db e0  8f fe e2 d6 d0 d4 cc bb  |r9..............|
+000002c0  7d 78 c6 c5 13 a8 4e 45  1e 66 60 77 fe 26 4d 18  |}x....NE.f`w.&M.|
+000002d0  90 e8 e1 0c 5b 2b 25 9b  ee 6d 76 3f f6 23 a2 26  |....[+%..mv?.#.&|
+000002e0  52 8d a9 4e 7f ed 8e e2  6d 7c b4 eb 25 46 54 27  |R..N....m|..%FT'|
+000002f0  e2 2d 2c 59 16 03 03 00  bc 6e c1 fb 66 55 ca ea  |.-,Y.....n..fU..|
+00000300  56 62 78 2f fd c4 ff da  78 dd e7 4d 34 59 a5 8f  |Vbx/....x..M4Y..|
+00000310  05 ab ac 7f 80 35 f6 de  9d 3f fe 4b d4 79 07 3b  |.....5...?.K.y.;|
+00000320  c0 8d 02 b8 1a 28 b5 eb  9b 55 6c 26 12 8d 38 01  |.....(...Ul&..8.|
+00000330  55 ed 28 68 aa 48 13 61  d3 fe 29 f0 fe 18 4e ae  |U.(h.H.a..)...N.|
+00000340  6e f9 47 7c 65 91 f9 5e  17 80 68 fd 19 4d ed 17  |n.G|e..^..h..M..|
+00000350  7f 11 c4 15 5d 4b fc ea  a7 5c df 76 a0 08 2e 15  |....]K...\.v....|
+00000360  d1 c6 ae 7b 0d 1f 79 d7  0c 59 6b 53 46 b6 c0 2b  |...{..y..YkSF..+|
+00000370  ce 09 39 12 7a df f6 7d  a2 4b 86 2a df ab b8 7c  |..9.z..}.K.*...||
+00000380  07 10 3c 34 cd 15 4c ac  68 a4 28 8a f8 fc 30 a4  |..<4..L.h.(...0.|
+00000390  4f 15 77 b4 91 ca 02 ee  bb 64 36 90 1b 4b 9d 2b  |O.w......d6..K.+|
+000003a0  72 e7 dc 10 bd 83 97 18  3c 56 68 58 c9 e3 22 df  |r.......<VhX..".|
+000003b0  33 43 81 7d 5f 16 03 03  00 14 a8 eb 40 73 19 19  |3C.}_.......@s..|
+000003c0  22 10 63 ed f0 6d 73 8c  f4 bd f9 ba ad 2e        |".c..ms.......|
 >>> Flow 13 (client to server)
-00000000  16 03 03 00 35 a4 b8 43  07 6e 71 c9 b4 fa e1 9c  |....5..C.nq.....|
-00000010  a7 9d 0b 47 d8 ea 8b bd  ea c2 f5 bf 36 fa 88 95  |...G........6...|
-00000020  3b 98 b3 7e 19 21 9b 0f  58 76 e8 de 5b 24 d3 b5  |;..~.!..Xv..[$..|
-00000030  81 bd 11 ce 86 02 b0 d1  3b ac 14 03 03 00 11 3f  |........;......?|
-00000040  4e a4 96 06 71 44 5f 57  30 5e 1a bc 22 8d 42 97  |N...qD_W0^..".B.|
-00000050  16 03 03 00 20 23 e7 90  a5 0a 32 b4 69 06 d7 77  |.... #....2.i..w|
-00000060  df ef f6 2f b8 d8 22 39  08 4f 39 02 e0 7f 62 93  |.../.."9.O9...b.|
-00000070  02 b9 8e a5 b6                                    |.....|
+00000000  16 03 03 00 35 67 14 4b  ca 21 7f d2 82 1d 2e b3  |....5g.K.!......|
+00000010  1a 82 ae 2d d9 d6 7c 76  94 78 d4 ec 0e 4d fe 5c  |...-..|v.x...M.\|
+00000020  d5 56 5e 6d 32 f4 a0 64  50 1e f6 e4 32 28 92 80  |.V^m2..dP...2(..|
+00000030  d4 15 1c d5 f6 52 fc ca  c0 e7 14 03 03 00 11 df  |.....R..........|
+00000040  9d f3 d1 64 92 92 7e 11  77 64 e5 67 01 33 49 17  |...d..~.wd.g.3I.|
+00000050  16 03 03 00 20 c8 0f d9  d2 c8 b7 d6 a5 ac 2c 33  |.... .........,3|
+00000060  f8 77 8f b1 df db 16 de  43 6c e6 5a eb a0 6e ff  |.w......Cl.Z..n.|
+00000070  be 1d 69 ab 30                                    |..i.0|
 >>> Flow 14 (server to client)
-00000000  14 03 03 00 11 0e 2d 1e  73 95 29 15 86 03 a2 da  |......-.s.).....|
-00000010  6c f4 d2 02 2c 57 16 03  03 00 20 cd a2 f5 b6 da  |l...,W.... .....|
-00000020  0c 35 45 96 54 c3 96 5d  d8 e6 03 49 7b 5c d4 6f  |.5E.T..]...I{\.o|
-00000030  02 da 27 9e 2f a7 09 57  1b de 7b 17 03 03 00 19  |..'./..W..{.....|
-00000040  18 06 7d aa 5c 93 a9 b3  d3 14 0b 76 78 a2 57 73  |..}.\......vx.Ws|
-00000050  2f a3 4f 66 c4 b3 ee 21  95                       |/.Of...!.|
+00000000  14 03 03 00 11 6e 2c 51  c5 dd fa 70 2a 34 e0 cc  |.....n,Q...p*4..|
+00000010  3c 9f b8 66 15 e6 16 03  03 00 20 78 02 96 c6 24  |<..f...... x...$|
+00000020  57 ca 4a 60 47 68 f6 5a  13 8b 3b ce 90 60 d2 e3  |W.J`Gh.Z..;..`..|
+00000030  1b d8 ab 1c df d4 5e c2  8d 5c 5b 17 03 03 00 19  |......^..\[.....|
+00000040  b7 15 fb 91 10 48 ae 25  0c cd 4f 06 fa 2a 59 49  |.....H.%..O..*YI|
+00000050  2f 18 5e 7e 36 1b 2e cb  3a                       |/.^~6...:|
 >>> Flow 15 (client to server)
-00000000  15 03 03 00 12 55 f7 2f  b2 a2 e7 59 6c f6 a9 2d  |.....U./...Yl..-|
-00000010  d1 17 88 01 49 c6 f2                              |....I..|
+00000000  15 03 03 00 12 c3 ff f7  b3 dc d4 b3 f5 d4 7c a3  |..............|.|
+00000010  18 db 08 a2 50 ad 75                              |....P.u|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected
index 441fa0f..784bcef 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 bb ec 39 c5 f2  |....Y...U....9..|
-00000010  dd a8 26 56 80 09 60 f5  d8 0a 93 6d 08 c4 30 c2  |..&V..`....m..0.|
-00000020  cf 0c 44 86 49 a3 19 84  20 38 98 20 0d 8b 81 b5  |..D.I... 8. ....|
-00000030  a7 42 37 27 1b 9c be 36  8f 9b 49 31 4f 73 67 a7  |.B7'...6..I1Osg.|
-00000040  78 9f 46 e5 9e 3b 45 ff  e9 16 11 ca cc a8 00 00  |x.F..;E.........|
+00000000  16 03 03 00 59 02 00 00  55 03 03 96 8a 79 30 8b  |....Y...U....y0.|
+00000010  13 f5 d3 1c 09 45 76 83  d7 2e e5 ad e3 ee e1 c4  |.....Ev.........|
+00000020  d4 b4 4c 37 93 cb 90 e1  9a 5e 52 20 fb 25 91 ea  |..L7.....^R .%..|
+00000030  1a 96 b6 fb 1f 0c a8 62  06 a0 fe 51 68 c0 fb a5  |.......b...Qh...|
+00000040  f1 05 28 02 be dc 87 31  e6 ff 90 1a cc a8 00 00  |..(....1........|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,188 +60,188 @@
 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 2f ad 87 a5 c9 9e c7  |........ /......|
-000002d0  f6 f1 05 9a 44 97 57 34  6b 3a 30 54 4c 0e 47 5e  |....D.W4k:0TL.G^|
-000002e0  16 d3 c9 c2 25 a8 47 e5  63 08 04 00 80 9f 54 b4  |....%.G.c.....T.|
-000002f0  c1 aa bb 15 07 5c b1 52  ef bd 26 fa ec ce 70 31  |.....\.R..&...p1|
-00000300  90 fb f5 4d d2 26 0c 64  6f b3 9f 7f 27 c7 a5 b2  |...M.&.do...'...|
-00000310  d1 6d cf 0e 9c 91 e3 c4  20 f7 e3 ae 95 ff 6d ce  |.m...... .....m.|
-00000320  80 b5 30 89 6c a2 dd 31  26 5b 24 19 7a 30 f7 43  |..0.l..1&[$.z0.C|
-00000330  71 a8 e9 1a 27 ee 46 86  44 56 b1 f3 2e e1 bd d5  |q...'.F.DV......|
-00000340  79 99 34 0c 9b 01 e6 bb  0f ad 96 4a 68 0f 10 79  |y.4........Jh..y|
-00000350  e9 91 7f 06 e6 02 32 ba  8c b6 a2 0c 4b 6d 09 f6  |......2.....Km..|
-00000360  28 8f 94 e8 10 e1 ca 48  6c de 56 c2 5c 16 03 03  |(......Hl.V.\...|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 ad 8e 56 2a c0 d0 7c  |........ ..V*..||
+000002d0  e1 cb 6b 20 0b 3e 53 33  28 25 37 42 5b 13 3c d5  |..k .>S3(%7B[.<.|
+000002e0  26 98 9e 0f df 45 6d 27  67 08 04 00 80 72 49 21  |&....Em'g....rI!|
+000002f0  f0 02 02 a3 7c e1 2a 18  d0 d0 21 8e 50 17 ad 0c  |....|.*...!.P...|
+00000300  3c a2 6d 65 b5 cb bc 7f  9e 7d 7f e2 36 3d b6 c8  |<.me.....}..6=..|
+00000310  df 7e b9 28 ab 01 99 2a  68 a4 be 46 11 94 9f 8c  |.~.(...*h..F....|
+00000320  67 02 92 1e 3c 51 78 f3  7a 35 ed f4 bb 8b fe b3  |g...<Qx.z5......|
+00000330  8c 32 aa c1 05 4f 99 68  b0 8a 75 65 1d e6 d6 6a  |.2...O.h..ue...j|
+00000340  61 65 aa 00 01 6b 29 06  99 d4 5b c7 c3 d2 0c 17  |ae...k)...[.....|
+00000350  74 59 d4 ee 99 b8 ef 5b  53 ff 33 df 9e 05 49 4f  |tY.....[S.3...IO|
+00000360  31 c6 95 81 67 c2 52 8a  0c e9 6a 46 22 16 03 03  |1...g.R...jF"...|
 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 d5 77 86  8e 32 60 6b 0f 0f 36 33  |.... .w..2`k..63|
-00000040  89 fe 51 b8 69 3a 1f 37  b3 d1 eb 43 ab e0 f6 db  |..Q.i:.7...C....|
-00000050  8b 9d 3c 0d 9a                                    |..<..|
+00000030  16 03 03 00 20 b8 c8 5d  3d b8 b8 2b c7 06 94 ec  |.... ..]=..+....|
+00000040  cc 92 01 22 3d cd 38 d8  aa 9f 1f 18 ef a0 ee 59  |..."=.8........Y|
+00000050  c0 3b 04 56 49                                    |.;.VI|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 ed 78 35 a3 71  |.......... .x5.q|
-00000010  34 a9 40 b2 be 15 dc a9  10 86 e0 de 94 23 e9 51  |4.@..........#.Q|
-00000020  2c 01 1e 34 19 07 53 20  59 ac f9                 |,..4..S Y..|
+00000000  14 03 03 00 01 01 16 03  03 00 20 be 6c dd f4 ef  |.......... .l...|
+00000010  71 1d 9c a7 24 ef 74 81  c4 01 1e e0 ef ac 78 90  |q...$.t.......x.|
+00000020  4e 51 fd 8a ca 83 e7 57  95 07 fa                 |NQ.....W...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 f3 a2 5f  da 1c 09 70 76 af 14 83  |......._...pv...|
-00000010  e5 7f 6f c9 9a 61 7f d9  e6 86 3c                 |..o..a....<|
+00000000  17 03 03 00 16 35 96 43  38 06 49 b1 3f 01 ae 85  |.....5.C8.I.?...|
+00000010  1a ee 4b 2b fe c0 75 76  b6 4a b0                 |..K+..uv.J.|
 >>> Flow 6 (server to client)
-00000000  16 03 03 00 14 71 23 15  46 93 87 94 38 01 d0 1b  |.....q#.F...8...|
-00000010  1a 34 db 58 17 d0 ac 62  87                       |.4.X...b.|
+00000000  16 03 03 00 14 df 6c d7  78 02 f5 a7 cb d8 2f fb  |......l.x...../.|
+00000010  04 dc 30 bc 28 51 f9 ec  b8                       |..0.(Q...|
 >>> Flow 7 (client to server)
-00000000  16 03 03 01 16 46 70 b5  5f 98 fc af a8 cb d6 7c  |.....Fp._......||
-00000010  8c 1e 60 c3 68 25 20 7b  95 9a 0c 04 b3 2c 52 b2  |..`.h% {.....,R.|
-00000020  30 f9 db cf 64 48 0a 46  9b 7a 11 76 11 5c 22 0c  |0...dH.F.z.v.\".|
-00000030  ef fa e6 6e a1 90 29 b3  64 aa ff 4d cb 7d 4d 91  |...n..).d..M.}M.|
-00000040  c0 05 99 a0 3d 25 b2 1e  7c c4 d2 94 6b bf f0 f7  |....=%..|...k...|
-00000050  0f 6a 3b 4c 66 c7 8a 26  9e 4f 79 68 50 5c f9 92  |.j;Lf..&.OyhP\..|
-00000060  97 e1 a5 86 aa f2 e9 d5  8a a1 96 a7 37 82 71 7d  |............7.q}|
-00000070  7d 7e b6 77 a3 3d 84 40  58 0d 66 cd 52 6c 9b 18  |}~.w.=.@X.f.Rl..|
-00000080  e2 c4 f0 dc 3d 9e 0e b8  49 ca 64 f3 71 c5 24 34  |....=...I.d.q.$4|
-00000090  e7 ca c3 87 f6 b9 2c 6a  95 12 4d 9d 4a 4d fe 8a  |......,j..M.JM..|
-000000a0  51 16 6e c9 00 64 c0 d1  da ae e6 14 66 d2 a8 80  |Q.n..d......f...|
-000000b0  35 ae 86 f6 64 f8 56 87  8a 40 46 43 ae d1 d1 fb  |5...d.V..@FC....|
-000000c0  64 1d 00 a1 3d e9 d9 7a  b5 fb 71 2a db 76 5a 74  |d...=..z..q*.vZt|
-000000d0  03 c3 79 df e6 90 e9 7e  de f9 0e 70 7a 65 3c 68  |..y....~...pze<h|
-000000e0  4f 2e c0 b8 13 e6 9d 1b  86 b8 65 57 fa dc 46 a7  |O.........eW..F.|
-000000f0  26 ba c3 64 fa b3 6f d5  e8 98 1f 10 d5 a5 1f 3e  |&..d..o........>|
-00000100  cc f9 8d a6 56 37 0d ff  92 8f 1b 36 b3 3d 0b f5  |....V7.....6.=..|
-00000110  5b fb fb 1e 4d c8 cb 84  39 5b 87                 |[...M...9[.|
+00000000  16 03 03 01 16 8c 2a 91  5b 60 aa 44 e7 b7 7e b8  |......*.[`.D..~.|
+00000010  ee c2 3e f3 c4 2f 6a 75  8e 25 07 5a 5c 42 81 fd  |..>../ju.%.Z\B..|
+00000020  65 4c 2a fb a9 80 f0 ba  33 1b 06 a8 79 a8 15 8e  |eL*.....3...y...|
+00000030  3a c4 08 95 a5 23 f0 ba  fb 43 58 26 84 b5 9d 17  |:....#...CX&....|
+00000040  03 e5 e7 08 ce 8b 79 9c  5e fb c6 6e a6 b8 12 cf  |......y.^..n....|
+00000050  b9 6e 4a 2a 90 d0 6b 65  93 bf 41 31 25 7f 3a 7c  |.nJ*..ke..A1%.:||
+00000060  75 1f d6 4e 22 d3 90 7b  71 14 57 c6 b6 89 ef 79  |u..N"..{q.W....y|
+00000070  74 7e 63 79 b9 63 d6 ef  02 b7 54 4b 53 0e 7f 70  |t~cy.c....TKS..p|
+00000080  8a 34 b1 85 98 ae a7 05  b8 41 9d 49 a3 ca eb 7d  |.4.......A.I...}|
+00000090  8b 64 e7 5d ca 11 71 93  e0 ff 6e 43 37 b4 e9 ec  |.d.]..q...nC7...|
+000000a0  23 6f d6 c6 bc cb ef a2  0b d0 4b ba 4f 40 b0 4b  |#o........K.O@.K|
+000000b0  ec 57 cb 8a 10 ae fe cd  14 70 42 a0 b9 1c 81 f6  |.W.......pB.....|
+000000c0  d2 79 47 31 4a b8 aa ac  89 98 cf ae 4e 8f 3d 36  |.yG1J.......N.=6|
+000000d0  c5 41 0e d8 e6 f3 88 2a  19 e5 e7 71 e2 2f 32 93  |.A.....*...q./2.|
+000000e0  ae 05 95 25 8f ec 4e 10  25 7e 53 60 6e c2 f2 72  |...%..N.%~S`n..r|
+000000f0  fc 7a 69 c1 93 e9 b8 2e  94 f3 19 31 5b 23 7c fd  |.zi........1[#|.|
+00000100  04 5d 59 ca 00 cc 37 0b  05 0d 50 10 50 3f b0 86  |.]Y...7...P.P?..|
+00000110  84 d4 fc 6a 0a 94 dc ba  88 fe ad                 |...j.......|
 >>> Flow 8 (server to client)
-00000000  16 03 03 00 81 25 44 f6  91 ed d5 01 fa 88 d6 74  |.....%D........t|
-00000010  f7 cd 6d ba 85 76 1d bd  ef 7b 31 51 db b4 42 a3  |..m..v...{1Q..B.|
-00000020  0a 89 3f 47 dc ca 18 39  84 5d 5a 4e d2 cd ba 75  |..?G...9.]ZN...u|
-00000030  b9 75 53 28 8c 85 6e 84  02 39 0a d2 59 ee ac 2f  |.uS(..n..9..Y../|
-00000040  fe a3 e4 fb 8c a1 72 e3  9f 28 8b 13 92 a8 5b 70  |......r..(....[p|
-00000050  24 f0 1b 6d 19 aa f1 b2  bf 8a 1f e2 3a 3e 3f e2  |$..m........:>?.|
-00000060  57 16 12 9e e8 21 11 66  b9 96 71 36 46 e1 2e fc  |W....!.f..q6F...|
-00000070  1e 40 a2 e2 6a 4d 4b 91  7a 50 0b d0 87 d1 04 16  |.@..jMK.zP......|
-00000080  2f 47 4d f2 c9 68 16 03  03 02 69 9a 28 7b f7 fc  |/GM..h....i.({..|
-00000090  8b e7 2b 40 88 1c 30 c1  5a f6 1d 51 a9 a8 5e 70  |..+@..0.Z..Q..^p|
-000000a0  73 1c 43 a7 3c 11 7e d5  92 78 b1 4f fd 5d 55 c6  |s.C.<.~..x.O.]U.|
-000000b0  5a ef 83 88 b2 e2 33 2a  27 cd 2e e8 d2 f4 2b d4  |Z.....3*'.....+.|
-000000c0  d5 b0 35 54 f6 a1 9c 07  75 10 8b 5d b9 dc bb 83  |..5T....u..]....|
-000000d0  76 43 f6 7e 70 2f 7c fe  8e 64 ca 00 65 df a4 e1  |vC.~p/|..d..e...|
-000000e0  a9 ad 71 79 d6 83 21 f6  9c 1b 88 d4 bb 51 3c 8a  |..qy..!......Q<.|
-000000f0  8c e5 c2 13 30 bd 6b 60  29 01 3e a0 cc 19 69 54  |....0.k`).>...iT|
-00000100  f0 2d dd a9 a1 24 a3 cc  13 9b 9a 8b f5 06 88 a9  |.-...$..........|
-00000110  9d ec c1 6f 0c b2 dd b3  60 be 23 ee 67 26 2d 65  |...o....`.#.g&-e|
-00000120  b1 99 9a 5b 92 c5 06 79  47 c6 4d 39 36 83 3b 4b  |...[...yG.M96.;K|
-00000130  96 f0 03 41 5c f9 fa 7c  3e d5 bf 67 1c a3 cf 6f  |...A\..|>..g...o|
-00000140  26 98 e0 2a 2d 64 60 c2  71 b1 b3 35 ba 8a 38 00  |&..*-d`.q..5..8.|
-00000150  88 cf 5a a5 2b 89 83 f3  04 ad 24 97 fa 34 69 fd  |..Z.+.....$..4i.|
-00000160  d7 70 00 09 ce 0f 60 f7  84 7d e3 5e 19 a9 1b dd  |.p....`..}.^....|
-00000170  45 3f 34 ae d4 c5 5c 1f  32 81 69 ea 22 44 1d c6  |E?4...\.2.i."D..|
-00000180  a3 ca 99 c5 44 09 76 cb  e2 ed 2e fd 23 09 d4 ea  |....D.v.....#...|
-00000190  62 cf cb 93 88 02 ca 8c  90 05 c9 0e 8d ff 8f e1  |b...............|
-000001a0  2d ef 52 1c ed 01 53 ef  a6 ee 11 11 b7 2b c8 b4  |-.R...S......+..|
-000001b0  6e 32 8c 54 7a 2b 19 e1  32 3e d0 92 87 81 76 04  |n2.Tz+..2>....v.|
-000001c0  c0 fd 99 3b 04 00 fb 76  d7 ed b0 81 e3 81 8c 1f  |...;...v........|
-000001d0  2b a0 59 d6 41 cd 8d 7d  b6 62 9d ab 60 33 24 f5  |+.Y.A..}.b..`3$.|
-000001e0  ec 70 8b b2 46 60 8f 53  c8 a3 f1 47 df e0 e8 b0  |.p..F`.S...G....|
-000001f0  9a cf 61 d4 d0 f5 0b b6  cd 85 47 1b b2 26 7d f2  |..a.......G..&}.|
-00000200  0a 32 af 5c 25 2a cc d2  66 9a 36 a1 68 95 34 18  |.2.\%*..f.6.h.4.|
-00000210  2d 9a 5a 62 a7 39 be 00  70 59 63 38 6a f9 53 b7  |-.Zb.9..pYc8j.S.|
-00000220  6d dd d4 cd c4 d2 12 b0  67 06 b5 d3 28 06 e4 43  |m.......g...(..C|
-00000230  98 b5 13 9f 1a d5 5e 07  70 f9 96 3c 66 a0 60 d6  |......^.p..<f.`.|
-00000240  79 1f 67 98 0b 38 ab 5a  1c 6f b0 31 e9 d9 6e 58  |y.g..8.Z.o.1..nX|
-00000250  28 c4 c5 82 9f 57 12 ae  35 12 c5 5c 29 f9 50 93  |(....W..5..\).P.|
-00000260  07 d8 e4 b8 36 5a 1e 10  a9 ee 33 5d ce 9c fe b8  |....6Z....3]....|
-00000270  78 11 99 2a 88 9d ce 49  6f 1c 73 41 65 5f c2 d5  |x..*...Io.sAe_..|
-00000280  46 a7 25 27 bc 3d 69 25  04 3a 37 ee e6 8a c0 d8  |F.%'.=i%.:7.....|
-00000290  e8 72 7a a9 21 03 9a 63  c9 f5 16 76 c4 11 b9 12  |.rz.!..c...v....|
-000002a0  03 cf ec 91 a0 6b 90 24  ba 0b f6 f2 4a 41 0d 9f  |.....k.$....JA..|
-000002b0  32 23 a3 df 3c ff c3 44  01 9c 77 5a 01 3f 00 d0  |2#..<..D..wZ.?..|
-000002c0  44 4d 48 23 58 9f 18 99  97 9c 32 7f cb 40 bb 35  |DMH#X.....2..@.5|
-000002d0  1f b8 06 07 28 7d 39 5a  47 66 12 95 30 07 24 b1  |....(}9ZGf..0.$.|
-000002e0  81 bc ea c0 6d 10 15 82  5f fe 68 50 1d aa 61 19  |....m..._.hP..a.|
-000002f0  c9 47 7c dc 16 03 03 00  bc e8 5f 40 20 1a cd d8  |.G|......._@ ...|
-00000300  5b b7 1e db 9d c0 10 96  e2 11 86 bc 0c e1 5f bd  |[............._.|
-00000310  9c cc 70 37 85 87 94 3c  cd 7d 0a c3 56 1e 18 9a  |..p7...<.}..V...|
-00000320  dc 21 4b e6 e1 63 c0 e6  2e 32 69 96 7e a0 cf cc  |.!K..c...2i.~...|
-00000330  58 74 a9 31 97 c1 e4 87  79 7f e7 7e 94 32 93 8d  |Xt.1....y..~.2..|
-00000340  31 97 51 27 26 cf ac e9  f9 34 ae 3e 1d f0 e9 5a  |1.Q'&....4.>...Z|
-00000350  71 82 05 10 8e be 0b 83  39 44 28 45 c6 e1 4a 85  |q.......9D(E..J.|
-00000360  c0 bf 3f 80 9b 61 97 82  d1 54 37 5f bc b2 f7 1f  |..?..a...T7_....|
-00000370  a1 ef 0f c5 be 74 96 3b  e8 89 30 3f d7 06 18 77  |.....t.;..0?...w|
-00000380  ed 3b aa 6e df 0c 15 e1  3e b1 36 ae 85 23 7d 9a  |.;.n....>.6..#}.|
-00000390  17 c3 f4 91 3a ac b1 64  03 a9 59 19 89 c2 d9 ad  |....:..d..Y.....|
-000003a0  82 d7 8e 85 36 cb 81 61  0d 3a 24 a1 84 55 37 bb  |....6..a.:$..U7.|
-000003b0  13 80 61 38 ef 16 03 03  00 4a 88 8d 13 b9 32 18  |..a8.....J....2.|
-000003c0  3c e2 72 b5 5c 0b 81 87  a0 ef 87 53 89 b1 f4 8b  |<.r.\......S....|
-000003d0  6a 87 68 c4 7d 59 2c 44  46 bb b1 40 8e 0a 45 4e  |j.h.}Y,DF..@..EN|
-000003e0  b8 a1 ba 72 bb 71 f9 52  55 c7 44 cd b3 56 82 68  |...r.q.RU.D..V.h|
-000003f0  8c 57 39 58 0b 40 12 4f  5d a2 91 3a ab 68 55 19  |.W9X.@.O]..:.hU.|
-00000400  26 dc ed 30 16 03 03 00  14 52 f8 53 d9 fc a6 a3  |&..0.....R.S....|
-00000410  89 c4 5a 2d 66 46 17 16  c3 bb f9 3c ca           |..Z-fF.....<.|
+00000000  16 03 03 00 81 41 25 27  5b 76 24 a0 4f f0 bf ca  |.....A%'[v$.O...|
+00000010  c4 4f f8 7c c6 e8 2a d4  d1 ed f1 b8 34 84 d6 d5  |.O.|..*.....4...|
+00000020  93 20 70 7d 8e 75 c5 16  a8 ff 5c e6 de 16 ea 96  |. p}.u....\.....|
+00000030  3f 86 3b bd 6d fa 96 3d  27 18 34 b8 18 86 ee 65  |?.;.m..='.4....e|
+00000040  7f f2 cc 7a b9 f8 2e 5a  32 f3 16 e2 a2 27 fd 4b  |...z...Z2....'.K|
+00000050  31 19 e6 81 d9 ef 02 10  ac b6 55 d3 0b e2 b0 09  |1.........U.....|
+00000060  56 ea 50 5a 96 b3 ff 07  78 48 df 77 3f 15 c9 ff  |V.PZ....xH.w?...|
+00000070  a7 24 af 28 ec 99 1a c9  36 09 16 9c 7c 5a c0 85  |.$.(....6...|Z..|
+00000080  7c 93 e4 61 2e 5b 16 03  03 02 69 ef 17 31 d5 9c  ||..a.[....i..1..|
+00000090  bc 09 f9 b7 75 e2 c8 ea  93 6f b7 49 e3 0e af bb  |....u....o.I....|
+000000a0  84 d6 3b 20 e2 89 13 6f  7a d1 73 a7 cb d5 03 b2  |..; ...oz.s.....|
+000000b0  20 40 40 76 d9 5d 3b 23  cb 48 ba 3c 1b e7 5d de  | @@v.];#.H.<..].|
+000000c0  16 be 82 91 39 d0 b4 83  3e 4c b8 a0 66 56 47 6c  |....9...>L..fVGl|
+000000d0  08 03 b1 0f be 3f d3 5e  7e b4 40 db db 5b ce 61  |.....?.^~.@..[.a|
+000000e0  d9 dc 02 7d ea df ea 43  08 2c b0 1c af 76 8f d3  |...}...C.,...v..|
+000000f0  cd af 51 cd 17 df 70 58  90 bd 83 aa 4b e5 fe cd  |..Q...pX....K...|
+00000100  90 30 e0 b5 d0 95 49 c2  10 06 8c 5a dd a2 37 ad  |.0....I....Z..7.|
+00000110  d5 d1 0e 73 c7 92 a9 ab  67 51 da 9d a4 62 6d a6  |...s....gQ...bm.|
+00000120  d7 89 22 2b 97 59 ad 02  65 e9 1d 48 44 07 c9 c0  |.."+.Y..e..HD...|
+00000130  c4 1f 7f da 64 0c 35 19  16 b3 70 41 d8 61 c3 47  |....d.5...pA.a.G|
+00000140  59 4d c2 e6 07 86 55 92  b9 98 8e 5c 86 d2 d5 51  |YM....U....\...Q|
+00000150  6a 50 19 99 75 0a cf 6e  49 cc 8a 76 b5 2b 20 48  |jP..u..nI..v.+ H|
+00000160  2b 11 d4 54 a2 ea 98 ce  d8 56 22 c8 f8 eb e5 25  |+..T.....V"....%|
+00000170  c8 cf ec 86 95 09 51 7e  18 89 bb 8f d4 66 b8 44  |......Q~.....f.D|
+00000180  c2 78 f4 4d ad eb 2d 79  f8 f6 02 4f d2 35 d4 71  |.x.M..-y...O.5.q|
+00000190  b3 ae e6 7d f6 45 6c 99  07 57 3c 01 bb c1 fb f1  |...}.El..W<.....|
+000001a0  1a ac ba 92 b6 60 52 63  8b 21 eb bf 77 02 c6 29  |.....`Rc.!..w..)|
+000001b0  7f 10 f7 11 ac a2 90 a9  8b 47 da c1 2c 41 c9 da  |.........G..,A..|
+000001c0  3f 18 ab be f0 eb 20 98  80 c6 d2 14 9e 8e d3 41  |?..... ........A|
+000001d0  c3 37 ab 12 5b cc d0 25  bd af 16 49 4e 89 a1 92  |.7..[..%...IN...|
+000001e0  d1 09 49 59 dc cf f8 6c  73 02 cb 72 6d 28 6e 28  |..IY...ls..rm(n(|
+000001f0  c5 a8 84 20 e6 f8 1b ad  c1 6c 8f b0 30 b2 49 84  |... .....l..0.I.|
+00000200  22 42 7d ec e1 c7 ab 29  de 1c 84 1f cf 59 c6 80  |"B}....).....Y..|
+00000210  7e 13 13 d7 c5 e5 f2 e0  3b 9d 81 c9 3f 86 21 27  |~.......;...?.!'|
+00000220  d7 c8 45 c1 25 f6 19 8d  0a f6 e9 5a 9b d5 64 a1  |..E.%......Z..d.|
+00000230  e4 6d fe 6a cf d1 c3 1b  d4 ea d9 1f 6b dc f9 a7  |.m.j........k...|
+00000240  e9 d2 6c 31 19 db e1 f4  f8 82 6e 8b da fd b1 fd  |..l1......n.....|
+00000250  0a 56 84 73 db 25 5f bb  12 61 70 de 67 34 28 1c  |.V.s.%_..ap.g4(.|
+00000260  c3 e6 eb 81 c8 94 55 ca  52 25 e8 72 bf a1 c5 88  |......U.R%.r....|
+00000270  b8 ce 72 8d 64 6c 38 d9  19 07 f3 51 51 91 84 f2  |..r.dl8....QQ...|
+00000280  c4 76 7f 8b 57 09 71 94  38 aa f1 64 51 6f 62 50  |.v..W.q.8..dQobP|
+00000290  c8 50 68 82 b9 54 b1 28  54 99 21 26 7d 75 c7 c7  |.Ph..T.(T.!&}u..|
+000002a0  79 e7 65 93 72 a4 39 2d  4c ec ba b2 4c 92 ae ee  |y.e.r.9-L...L...|
+000002b0  34 a2 22 2f f9 b9 75 a9  27 77 63 2d ac 27 87 ce  |4."/..u.'wc-.'..|
+000002c0  ee 37 c0 c7 c1 b6 4c 13  d7 78 97 64 dc af ea 0d  |.7....L..x.d....|
+000002d0  7c 12 0e 7b 0b 26 77 01  e4 1c 24 e8 9f fc 19 2f  ||..{.&w...$..../|
+000002e0  46 a2 81 3d 0d c7 16 7e  49 25 b4 c1 0f 0a 71 05  |F..=...~I%....q.|
+000002f0  25 eb 53 e4 16 03 03 00  bc 0b 79 2d c6 0a 63 68  |%.S.......y-..ch|
+00000300  f0 21 37 d0 42 4a 0f 2f  7d 2f a0 7d 3d c3 94 c4  |.!7.BJ./}/.}=...|
+00000310  36 f5 a6 db e1 ad 0f 94  07 67 57 54 d4 57 86 50  |6........gWT.W.P|
+00000320  a2 e1 78 09 f2 e3 7b bc  6d 1b c0 fe 16 eb d3 ef  |..x...{.m.......|
+00000330  fb ec 22 44 ee 2f 78 99  84 e2 c1 4c f7 0d 4f bc  |.."D./x....L..O.|
+00000340  ca 57 be de 5f 52 08 33  b0 e1 1d 7b 45 9e 5d 17  |.W.._R.3...{E.].|
+00000350  41 2c 10 43 44 18 84 38  f3 0b 6a a1 76 bf 75 c9  |A,.CD..8..j.v.u.|
+00000360  56 b2 53 4c 98 39 c0 6f  30 13 96 8a 27 59 12 03  |V.SL.9.o0...'Y..|
+00000370  60 64 ce 28 54 c0 03 f4  c4 d1 df 94 e3 6e 43 61  |`d.(T........nCa|
+00000380  fa 43 40 e5 05 3b 26 dc  c4 41 bd 73 c3 9e a0 db  |.C@..;&..A.s....|
+00000390  fb c9 50 b4 4a d9 2d 71  cf e8 ff 3d 17 9e 29 35  |..P.J.-q...=..)5|
+000003a0  61 6c ab 11 ac 21 fa 90  6b 75 1f 0a 9d 30 3f 13  |al...!..ku...0?.|
+000003b0  fa c3 97 7a 74 16 03 03  00 4a 3d ca 3b 3d c8 6f  |...zt....J=.;=.o|
+000003c0  44 4e 53 3d 05 27 97 aa  bd 58 33 d6 ad 4a 34 71  |DNS=.'...X3..J4q|
+000003d0  22 d9 36 96 17 a5 ba 6b  b3 20 2e da 64 65 14 c7  |".6....k. ..de..|
+000003e0  6a c7 07 39 55 db bb ad  e2 49 84 09 5e 78 88 b5  |j..9U....I..^x..|
+000003f0  4b d5 23 fa 17 c5 f2 b8  2a c6 e5 1e 15 47 01 36  |K.#.....*....G.6|
+00000400  ef 7f 0a 14 16 03 03 00  14 28 e3 58 7e b9 36 d6  |.........(.X~.6.|
+00000410  ef 65 c8 bc fb 10 57 3d  48 70 7f 68 7d           |.e....W=Hp.h}|
 >>> Flow 9 (client to server)
-00000000  16 03 03 02 69 fe 0d 45  cb 57 12 fa 9e 10 d7 b3  |....i..E.W......|
-00000010  a5 dd 33 0e 39 41 77 63  8e 99 e0 5b b9 5e 94 0a  |..3.9Awc...[.^..|
-00000020  48 b2 6b e9 61 ab f2 74  6b 5e a3 f9 3f 9c 29 0b  |H.k.a..tk^..?.).|
-00000030  6b 34 29 92 d8 c8 2c 61  84 f2 3b 0f c2 5c e5 19  |k4)...,a..;..\..|
-00000040  6a f0 e2 03 e3 93 a6 1e  4e 87 79 6b 07 dc 18 d2  |j.......N.yk....|
-00000050  9a 25 be f3 d6 ab 2a be  f8 68 65 68 92 8a 80 04  |.%....*..heh....|
-00000060  26 eb 62 ae 6b bc 81 27  82 76 25 e0 6b ac 04 e9  |&.b.k..'.v%.k...|
-00000070  67 68 13 f6 7b 7e 24 c2  75 27 8a c9 3a 7a 2f aa  |gh..{~$.u'..:z/.|
-00000080  a2 37 d9 73 97 bc 4b 09  ba 1b 2c ba 08 85 c6 82  |.7.s..K...,.....|
-00000090  50 a3 e0 00 6e a8 7c 14  ab 38 ae c4 82 ee 05 4b  |P...n.|..8.....K|
-000000a0  9a c0 19 62 1e de ef 7f  8c a4 a0 0e 29 0f b4 09  |...b........)...|
-000000b0  f1 b9 39 ae 09 1b 6e 6f  ee 3d 31 72 70 09 51 44  |..9...no.=1rp.QD|
-000000c0  1c 33 64 6d ae 8d da a5  e0 7b a3 49 19 2c 3f dd  |.3dm.....{.I.,?.|
-000000d0  6b 1e d1 a7 bb 8a 13 8c  e9 aa 5f b3 fd 88 89 5a  |k........._....Z|
-000000e0  4a 30 dd d0 1e 6a 8c 8a  0d 35 82 01 64 c1 42 ff  |J0...j...5..d.B.|
-000000f0  60 ac 3d 62 bf 31 3e ab  42 7e b0 da 4a cc 9c d8  |`.=b.1>.B~..J...|
-00000100  0e 92 97 a2 40 48 48 ce  66 49 bd 1b 8a ee ed 46  |....@HH.fI.....F|
-00000110  18 98 b9 43 b8 76 e8 93  07 3c 38 6e c2 cd 9c ce  |...C.v...<8n....|
-00000120  e2 38 f0 d7 ee ad c7 4a  c4 ed 3b fd 2e f2 9b 43  |.8.....J..;....C|
-00000130  6c fe 75 d7 4d 61 2a c5  16 e2 3d af 98 5b 76 f5  |l.u.Ma*...=..[v.|
-00000140  3e 96 b9 81 b3 cb 0c 91  89 44 6e d6 66 c4 f2 dd  |>........Dn.f...|
-00000150  c9 21 09 91 95 f2 99 29  62 54 44 03 b0 fe 84 bb  |.!.....)bTD.....|
-00000160  96 86 c4 ca 6e 7f c9 f9  1a 80 38 42 7d 54 b3 6f  |....n.....8B}T.o|
-00000170  2a 2d c3 19 54 60 3f fb  00 95 65 6a 85 4b a2 8f  |*-..T`?...ej.K..|
-00000180  6a 3d 38 61 e9 36 c2 25  92 3b 53 f2 ea bb 60 42  |j=8a.6.%.;S...`B|
-00000190  ab 83 83 c0 2e 95 6d 5a  19 61 9f b3 29 ee b2 52  |......mZ.a..)..R|
-000001a0  5f 27 16 46 d9 ad 62 45  d5 81 9a 93 ef a1 4f e7  |_'.F..bE......O.|
-000001b0  0e e0 71 bf cd 49 68 e7  13 f1 71 59 8c f5 2d 05  |..q..Ih...qY..-.|
-000001c0  5d 65 c4 6e 2c 91 c5 d3  40 c4 2f df c8 f6 59 55  |]e.n,...@./...YU|
-000001d0  05 6b c1 b7 59 15 8e b8  85 1b 75 dd 44 9e b7 f3  |.k..Y.....u.D...|
-000001e0  00 73 bf c6 93 d4 43 27  bd 60 79 1a 28 93 2d 64  |.s....C'.`y.(.-d|
-000001f0  fb 2f 77 a6 79 22 54 f3  c3 3c 3f cd 4d ea 79 3b  |./w.y"T..<?.M.y;|
-00000200  aa 4c e6 86 55 8d e0 5c  ce 00 1e d4 fa ab bb de  |.L..U..\........|
-00000210  8f 41 95 15 d3 6a 21 02  cb 4a f5 b6 2d 8c da 99  |.A...j!..J..-...|
-00000220  93 1f 9f 81 cf 77 f8 01  0a ab 77 03 5c a3 bd 3a  |.....w....w.\..:|
-00000230  ba 07 51 17 50 06 c9 51  f8 f1 ec 3f 60 44 df 1b  |..Q.P..Q...?`D..|
-00000240  06 05 bd 8f 17 99 00 73  38 e5 bb fb 08 1b e7 ea  |.......s8.......|
-00000250  b5 36 e0 4e 67 d9 11 90  5e d9 8e 63 7b f9 03 4b  |.6.Ng...^..c{..K|
-00000260  ef cd 4d 2c d9 4b eb 8a  bb 62 85 03 16 e2 16 03  |..M,.K...b......|
-00000270  03 00 35 d1 39 57 66 1b  70 63 8f 6a b4 1d 5f 5e  |..5.9Wf.pc.j.._^|
-00000280  dd 31 7e 5b 0e e3 d5 98  90 8b 60 33 0c 10 7c 01  |.1~[......`3..|.|
-00000290  4c 40 88 e9 a3 8c 61 ab  dc 4a e2 ce 0a fc 56 7b  |L@....a..J....V{|
-000002a0  ef e3 19 60 62 18 97 7c  16 03 03 00 98 2f 65 76  |...`b..|...../ev|
-000002b0  15 2e 76 82 e8 70 6d c4  17 72 e7 30 9c 14 af d4  |..v..pm..r.0....|
-000002c0  0f 1e ec b5 5c 80 31 dc  15 fc 81 06 20 f1 e5 99  |....\.1..... ...|
-000002d0  67 c6 eb cc 77 57 2c 55  85 dc f9 9f 6f 19 7a d0  |g...wW,U....o.z.|
-000002e0  a0 45 17 b9 8c e4 19 46  ef dc 28 e1 e7 87 93 e0  |.E.....F..(.....|
-000002f0  c5 83 70 28 23 90 b9 c2  53 a3 67 d8 09 1f 47 0e  |..p(#...S.g...G.|
-00000300  a3 de bf a3 07 2d e7 3b  a5 e9 11 c4 30 59 fb cd  |.....-.;....0Y..|
-00000310  5d 6a d0 47 6f 43 a4 bd  2f 56 67 7d b2 c8 f5 2a  |]j.GoC../Vg}...*|
-00000320  9b ce ea 10 ec 83 f8 bc  87 19 c8 97 a9 ee 80 3c  |...............<|
-00000330  cb de 1a 22 60 ed 77 f7  57 5f 20 54 62 ca b0 e7  |..."`.w.W_ Tb...|
-00000340  75 a0 ba fc 32 14 03 03  00 11 86 a9 6a 14 1a 4c  |u...2.......j..L|
-00000350  1d 21 1f 3c c2 19 85 02  88 f5 f6 16 03 03 00 20  |.!.<........... |
-00000360  03 f9 fc ed cf 15 ed 86  d2 69 49 d7 e2 01 06 96  |.........iI.....|
-00000370  42 74 89 3f bf 98 56 0f  c1 1b 61 b6 36 3b ae 87  |Bt.?..V...a.6;..|
+00000000  16 03 03 02 69 d8 c1 81  7e a9 d7 70 97 62 c7 68  |....i...~..p.b.h|
+00000010  df 02 01 9d cc dc 38 d0  d6 bb 48 03 1d 0b be 73  |......8...H....s|
+00000020  b3 1a 88 91 a0 1b 55 91  51 a5 d7 54 58 c4 ea 50  |......U.Q..TX..P|
+00000030  e5 67 b1 60 78 b6 e2 7f  d7 6c b4 76 d7 24 fd af  |.g.`x....l.v.$..|
+00000040  f6 68 90 8c de 71 cd 15  4f d0 c8 f6 ba 89 ce 05  |.h...q..O.......|
+00000050  be 35 e8 9e 7a 8b 8d 0d  23 d4 5a bd 3a 9e d0 bf  |.5..z...#.Z.:...|
+00000060  80 08 f5 ad 7d 84 f1 8a  16 de 97 6b b2 75 8e 49  |....}......k.u.I|
+00000070  0f d7 8b 10 57 f7 21 1f  c0 87 de 06 c5 ae ae dd  |....W.!.........|
+00000080  9c 22 92 a1 6c c7 46 8d  e2 be 43 32 9c be 47 6b  |."..l.F...C2..Gk|
+00000090  4d 2a 60 f0 b6 3a 09 16  d6 16 a1 92 4a 2d 2d 72  |M*`..:......J--r|
+000000a0  00 8f 40 7c 3e a9 61 be  35 c8 f8 48 b4 1c 90 61  |..@|>.a.5..H...a|
+000000b0  90 c5 aa f8 ae aa d4 8a  15 74 b2 5d aa 24 cf 45  |.........t.].$.E|
+000000c0  ef 02 bd 29 b9 50 b4 fe  83 05 fa 4a a5 82 10 28  |...).P.....J...(|
+000000d0  b7 ab c3 ca c3 65 bb 51  a4 7c ac 57 03 78 28 e3  |.....e.Q.|.W.x(.|
+000000e0  91 9f c1 ce 02 08 70 84  8c 11 1f ae 35 a5 06 12  |......p.....5...|
+000000f0  f8 78 5b 38 0a 11 c8 1c  2d 1b 0c 21 66 d9 41 b2  |.x[8....-..!f.A.|
+00000100  ed 66 3c 47 f2 dc ab c1  59 7d 65 df bb 80 37 1c  |.f<G....Y}e...7.|
+00000110  5e 9b 41 e1 1d 5f b5 24  e4 77 61 3b e8 36 93 03  |^.A.._.$.wa;.6..|
+00000120  6d 87 17 e9 d7 77 35 b1  83 a3 b9 80 4d 40 20 82  |m....w5.....M@ .|
+00000130  94 36 53 94 ad 6b b3 ad  0a 70 fd 11 ce 81 56 ca  |.6S..k...p....V.|
+00000140  c2 5d 16 69 e3 59 7e 37  3b cd f3 54 1e b8 5e 1a  |.].i.Y~7;..T..^.|
+00000150  64 3f bf c6 ba ff fa b5  bf 4b c2 8e 5a 4d 43 1f  |d?.......K..ZMC.|
+00000160  8e 50 bc 7a 82 13 c7 25  aa b4 a8 97 45 49 12 25  |.P.z...%....EI.%|
+00000170  f5 4d 52 df 90 e5 74 0f  a0 d2 fd c3 6f bd 41 ed  |.MR...t.....o.A.|
+00000180  ff 78 e8 97 f2 e2 d1 5b  7c e6 27 01 16 27 1d b6  |.x.....[|.'..'..|
+00000190  8a cf c6 5b 8d b3 d8 8e  0c ee 2a d5 21 f6 4b d3  |...[......*.!.K.|
+000001a0  5a 74 7e 3d c6 fb 0e 35  97 de e7 52 c0 b2 c3 37  |Zt~=...5...R...7|
+000001b0  94 28 41 e0 3b 65 56 f1  4f 60 03 48 88 1d db fc  |.(A.;eV.O`.H....|
+000001c0  60 9f 33 e1 4d 37 eb 22  36 b2 76 ae 1c 3d 1c 5e  |`.3.M7."6.v..=.^|
+000001d0  3a c5 5b 00 eb 72 8b 54  ba 76 d1 71 77 5f 76 54  |:.[..r.T.v.qw_vT|
+000001e0  5f fd 0e d1 3a 50 ad b1  55 4a db 6d bf 2f 33 90  |_...:P..UJ.m./3.|
+000001f0  fc 42 de cd e4 a9 dd 11  25 d1 9f 56 1e 8a 2b 5c  |.B......%..V..+\|
+00000200  6c ed e7 51 84 42 6b ab  7d 77 b4 95 c3 75 b3 24  |l..Q.Bk.}w...u.$|
+00000210  ce 70 b0 e1 63 7f ec b0  ea 6a a4 a1 d5 e8 3e 96  |.p..c....j....>.|
+00000220  65 99 40 46 73 c8 e1 6e  86 65 92 bf 3d 92 a3 4f  |e.@Fs..n.e..=..O|
+00000230  37 6d bb 80 33 a5 7d aa  d3 a9 37 77 a6 4e 5b d6  |7m..3.}...7w.N[.|
+00000240  f3 f9 b2 42 75 18 1f 5a  58 f3 08 35 bc f4 2b 93  |...Bu..ZX..5..+.|
+00000250  62 0b 8a 83 f9 44 d0 e1  1a 44 b2 66 45 6f de b3  |b....D...D.fEo..|
+00000260  d2 ec 34 ac 15 89 76 b4  da dd 95 ca 44 5b 16 03  |..4...v.....D[..|
+00000270  03 00 35 39 e8 06 21 47  85 b5 53 96 03 0b 08 3b  |..59..!G..S....;|
+00000280  d2 9d 55 1f 23 4f 3a c0  be 4f e0 e0 0a f1 65 6f  |..U.#O:..O....eo|
+00000290  78 22 c4 10 6b d0 96 dc  04 78 e8 d3 95 f6 9a 78  |x"..k....x.....x|
+000002a0  09 f2 42 d3 79 57 99 c4  16 03 03 00 98 37 6b 75  |..B.yW.......7ku|
+000002b0  79 17 fa 67 7f 94 2e aa  88 61 91 97 dc 10 1e e6  |y..g.....a......|
+000002c0  6d 6d fa d5 64 17 f4 ec  ba 01 43 99 88 e2 a7 13  |mm..d.....C.....|
+000002d0  e0 9e 6a e9 97 c7 b3 ec  b9 c9 72 51 3d 01 eb c0  |..j.......rQ=...|
+000002e0  03 0f 08 48 90 27 36 6b  bd e7 0d 4e 41 6a ef 11  |...H.'6k...NAj..|
+000002f0  42 5b ae d1 16 ec 8f b7  47 a2 f5 b4 6a d4 32 bb  |B[......G...j.2.|
+00000300  0c cc 4f 2a e0 be 44 47  c8 77 09 f5 78 4b d6 ec  |..O*..DG.w..xK..|
+00000310  87 95 dc e1 74 75 54 af  45 bb 7a f5 2e f7 ac 3d  |....tuT.E.z....=|
+00000320  d1 b2 31 5a c0 24 c7 7c  25 36 62 a7 48 73 66 44  |..1Z.$.|%6b.HsfD|
+00000330  c1 78 47 f3 48 c5 a0 f7  66 3e 78 27 2c 3c dc 83  |.xG.H...f>x',<..|
+00000340  f5 6c e1 09 31 14 03 03  00 11 79 32 99 fd 2d 8d  |.l..1.....y2..-.|
+00000350  14 33 fd 1b 1b a8 3d 99  4b 0a b7 16 03 03 00 20  |.3....=.K...... |
+00000360  76 25 53 83 f2 c5 bf a6  fa 2e d3 5a 62 67 5b 1d  |v%S........Zbg[.|
+00000370  23 9a 9c b3 16 01 3f 6a  e9 4c ea e1 d4 d1 09 42  |#.....?j.L.....B|
 >>> Flow 10 (server to client)
-00000000  14 03 03 00 11 00 e4 ef  62 c1 c0 72 f3 98 4d 5a  |........b..r..MZ|
-00000010  6a c8 7e 29 92 b8 16 03  03 00 20 ff 7e fc cb b5  |j.~)...... .~...|
-00000020  07 5f ea 8a 89 2a 46 1b  c6 33 41 fe f9 f4 1e 3a  |._...*F..3A....:|
-00000030  9d 8b 1d 8f 9b 7b 89 07  b4 e8 59 17 03 03 00 19  |.....{....Y.....|
-00000040  a3 ba 0c 9b 54 cd 59 6a  e1 db 33 80 38 a9 95 a1  |....T.Yj..3.8...|
-00000050  95 5b a5 5f ad 3c d0 52  f7 16 03 03 00 14 e6 22  |.[._.<.R......."|
-00000060  84 a7 02 10 1e ee 58 88  a5 b8 e8 bf 0a 9b 61 46  |......X.......aF|
-00000070  0c ae                                             |..|
+00000000  14 03 03 00 11 a7 38 2a  4e 04 a5 b7 df d6 05 bb  |......8*N.......|
+00000010  b5 93 38 bc 9e 62 16 03  03 00 20 f3 d3 e1 7d 80  |..8..b.... ...}.|
+00000020  41 ce 05 99 92 c7 47 fe  b5 08 3b 78 9d ae b0 5f  |A.....G...;x..._|
+00000030  2c ed bd 0b 90 e0 94 9e  0b b0 a5 17 03 03 00 19  |,...............|
+00000040  27 f0 6a 55 af 3f c1 82  85 1a 6b 28 e1 cd dc 59  |'.jU.?....k(...Y|
+00000050  43 be c7 18 16 30 08 b2  9e 16 03 03 00 14 c1 c5  |C....0..........|
+00000060  64 ef 72 4f 6c 96 f1 f6  5b 70 29 e4 59 36 0a cd  |d.rOl...[p).Y6..|
+00000070  d2 a3                                             |..|
 >>> Flow 11 (client to server)
-00000000  15 03 03 00 12 7f 90 91  7b 93 4e 24 25 5e cb 35  |........{.N$%^.5|
-00000010  2c eb ee 29 6a b3 a3 15  03 03 00 12 3d b7 30 fe  |,..)j.......=.0.|
-00000020  63 90 c3 2d 17 a0 e1 ed  8d bb a4 f6 f6 17        |c..-..........|
+00000000  15 03 03 00 12 af 73 0e  40 39 dd 1e 04 99 3e 10  |......s.@9....>.|
+00000010  c9 62 b3 78 77 9b 56 15  03 03 00 12 25 8b 87 29  |.b.xw.V.....%..)|
+00000020  82 d0 9f 5e 9a 27 bd c1  bf b7 a2 f0 92 ac        |...^.'........|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected b/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected
index 3502977..f7a7668 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 9c d0 eb d6 42  |....Y...U......B|
-00000010  2e ff 6e 5a 19 33 6d 12  97 56 56 2b f5 1b 86 c8  |..nZ.3m..VV+....|
-00000020  38 83 59 37 ac 17 46 ed  73 53 43 20 e4 94 9b 71  |8.Y7..F.sSC ...q|
-00000030  f4 94 d9 d9 3a a1 e1 99  1e b4 a5 55 46 88 e0 0a  |....:......UF...|
-00000040  af 0a 0e ff 81 10 e2 e0  63 21 ae 2a cc a8 00 00  |........c!.*....|
+00000000  16 03 03 00 59 02 00 00  55 03 03 a3 55 d2 e2 bd  |....Y...U...U...|
+00000010  94 8f 04 51 26 1c a6 61  b1 ed 05 e2 39 44 33 05  |...Q&..a....9D3.|
+00000020  79 14 b7 1f 89 1e bb ba  53 0d 12 20 09 29 6d 26  |y.......S.. .)m&|
+00000030  04 70 4a 5d 01 90 f2 c6  28 df 11 6a 64 23 ec 9e  |.pJ]....(..jd#..|
+00000040  9f 2b 15 33 dc 88 26 35  3a b0 86 92 cc a8 00 00  |.+.3..&5:.......|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,36 +60,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 9b 89 08 0d ea c2 d3  |........ .......|
-000002d0  4f 73 77 a0 e3 0e 1a 68  13 2c 5c a5 ec 39 75 1b  |Osw....h.,\..9u.|
-000002e0  c2 95 fe b8 fe 58 f4 bb  16 08 04 00 80 d4 e8 d3  |.....X..........|
-000002f0  d4 5b 1f ee ff 60 f5 86  b1 f4 06 c0 a8 ab 90 b0  |.[...`..........|
-00000300  26 15 d5 4e 3f d6 a5 e2  a3 3a e0 0f 9a 92 bd 96  |&..N?....:......|
-00000310  9d 98 15 f3 95 82 a9 5d  9f 1d 9b 4f 2e 77 58 40  |.......]...O.wX@|
-00000320  58 3d fd 8f a6 09 1c fa  61 77 2e 87 df e7 76 8b  |X=......aw....v.|
-00000330  bf f1 dd 29 f8 70 c0 6d  db e5 a0 55 92 77 44 75  |...).p.m...U.wDu|
-00000340  d9 95 a6 17 67 93 47 8e  1f 61 50 65 31 94 d3 79  |....g.G..aPe1..y|
-00000350  5f 25 a6 f0 3e 19 9a c8  ad b9 1a af 5b 50 2c 97  |_%..>.......[P,.|
-00000360  78 1e 71 3a e0 fa 7c 44  1e d1 32 56 4e 16 03 03  |x.q:..|D..2VN...|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 43 6b 44 5b 79 c9 38  |........ CkD[y.8|
+000002d0  dc e4 ab fa 88 fa e6 06  89 b1 4e ff ab 8d d6 f7  |..........N.....|
+000002e0  21 b4 ff 9d a0 c8 54 cc  63 08 04 00 80 cd f4 d6  |!.....T.c.......|
+000002f0  c8 ad 03 e7 f0 e8 f4 c9  f0 e6 28 db cd 3b 7c bf  |..........(..;|.|
+00000300  05 af 3d fe c1 f9 f1 7a  ec 41 bf 1f a8 95 6d ee  |..=....z.A....m.|
+00000310  e6 92 cb c0 ff fd c1 ed  86 b0 59 45 3e 2d 1d 66  |..........YE>-.f|
+00000320  56 d1 9f e2 b7 79 ac aa  81 6d b0 42 36 96 80 4d  |V....y...m.B6..M|
+00000330  ca 36 29 1b 65 03 73 3f  85 ec 59 cb b4 a5 a0 c0  |.6).e.s?..Y.....|
+00000340  0c 16 ad e2 6b 35 3c ab  1e da 69 19 7d a2 63 a7  |....k5<...i.}.c.|
+00000350  69 2a d2 3f 12 17 bf 4c  ed 8a f7 75 fe ce d4 2b  |i*.?...L...u...+|
+00000360  4d 35 bf 65 d6 9e 01 69  a8 0a 73 26 34 16 03 03  |M5.e...i..s&4...|
 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 88 fe 97  82 bd a7 99 c6 a6 2f c1  |.... ........./.|
-00000040  1a a8 54 8c e5 c6 39 0a  6b 07 9b 1a 05 f4 fb e3  |..T...9.k.......|
-00000050  67 f5 c8 6e 17                                    |g..n.|
+00000030  16 03 03 00 20 b8 d8 22  20 8d 69 23 05 34 eb 69  |.... .." .i#.4.i|
+00000040  92 a0 a9 6c cd 94 3b 72  49 91 72 8e 65 79 ca 62  |...l..;rI.r.ey.b|
+00000050  14 cf da 2e b6                                    |.....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 3b 6d ac 1c 8b  |.......... ;m...|
-00000010  1b 46 3a 4e 03 75 51 9e  99 6e 5a a8 4f 07 91 a3  |.F:N.uQ..nZ.O...|
-00000020  18 2c bf 88 92 17 e5 13  65 a3 6c                 |.,......e.l|
+00000000  14 03 03 00 01 01 16 03  03 00 20 31 25 d4 c7 92  |.......... 1%...|
+00000010  16 0b 92 2d a2 20 8b b2  c7 96 a6 b7 b6 b3 82 3a  |...-. .........:|
+00000020  4d a1 a8 96 29 fb 99 e9  ea 04 6c                 |M...).....l|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 c7 94 fc  be 3d 73 fd ec ce b2 f6  |.........=s.....|
-00000010  bf 17 bf 52 3e b4 98 39  43 c0 0a                 |...R>..9C..|
+00000000  17 03 03 00 16 8b 92 f3  f8 99 bf a3 7c c4 03 d8  |............|...|
+00000010  4d e7 1b ad 50 e1 99 17  33 68 e2                 |M...P...3h.|
 >>> Flow 6 (server to client)
-00000000  16 03 03 00 14 cf 01 f5  e6 eb 60 e3 49 c4 fb 84  |..........`.I...|
-00000010  e1 11 69 e1 91 c0 02 d2  e3                       |..i......|
+00000000  16 03 03 00 14 91 99 15  68 ae 92 52 bd 13 75 45  |........h..R..uE|
+00000010  6d a9 f0 2d ee f5 c3 9b  e7                       |m..-.....|
 >>> Flow 7 (client to server)
-00000000  15 03 03 00 12 4d 7f de  01 23 f7 3f 0d e6 1a f1  |.....M...#.?....|
-00000010  19 a2 cd 58 1a 25 f5 15  03 03 00 12 95 78 52 00  |...X.%.......xR.|
-00000020  65 aa 6d 77 5a 66 d5 95  c4 5a 9b 1b 05 b2        |e.mwZf...Z....|
+00000000  15 03 03 00 12 be 8b 4b  a6 a7 7a 62 45 32 ff db  |.......K..zbE2..|
+00000010  07 ad a0 1b 46 9d c9 15  03 03 00 12 16 da d4 86  |....F...........|
+00000020  4f c8 26 5a d0 34 82 fe  47 34 ae 31 db a7        |O.&Z.4..G4.1..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-SCT b/src/crypto/tls/testdata/Client-TLSv12-SCT
index d12e263..8492ee9 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-SCT
+++ b/src/crypto/tls/testdata/Client-TLSv12-SCT
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 01 c6 02 00 01  c2 03 03 d8 a9 75 cc 9a  |.............u..|
-00000010  81 df 5a a0 3b ba 51 74  52 50 72 08 35 02 35 77  |..Z.;.QtRPr.5.5w|
-00000020  28 ff 44 e6 d9 c6 8b f8  54 67 b4 20 62 80 60 cc  |(.D.....Tg. b.`.|
-00000030  09 90 52 66 75 72 a2 c5  dc 8d 18 ce 9a d5 7e cd  |..Rfur........~.|
-00000040  a5 36 2a 2e 65 72 6f f0  dd b0 8c 14 cc a8 00 01  |.6*.ero.........|
+00000000  16 03 03 01 c6 02 00 01  c2 03 03 b0 59 eb bc ae  |............Y...|
+00000010  f3 42 03 d1 fe 2c 7d 6f  0e ff e4 0c 9e 13 00 b9  |.B...,}o........|
+00000020  46 99 e2 84 49 64 a9 05  05 8a fb 20 16 12 dc b7  |F...Id..... ....|
+00000030  e0 09 a2 a6 56 83 43 54  de 40 53 47 43 f0 2f c9  |....V.CT.@SGC./.|
+00000040  2d 92 5e a0 9d a3 6a c4  55 17 01 cb cc a8 00 01  |-.^...j.U.......|
 00000050  7a 00 12 01 69 01 67 00  75 00 a4 b9 09 90 b4 18  |z...i.g.u.......|
 00000060  58 14 87 bb 13 a2 cc 67  70 0a 3c 35 98 04 f9 1b  |X......gp.<5....|
 00000070  df b8 e3 77 cd 0e c8 0d  dc 10 00 00 01 47 97 99  |...w.........G..|
@@ -83,31 +83,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 cd 2a  10 ee 97 4a 83 7b 0e 6d  |..... .*...J.{.m|
-00000440  e7 00 5a ce bc d8 1c 57  fa f6 ec 52 0d 0f be 6d  |..Z....W...R...m|
-00000450  c8 5d 27 3c 8c 1b 08 04  00 80 a9 4c bb 3a 0a d7  |.]'<.......L.:..|
-00000460  db 72 3d 88 49 a6 0b f7  dc d5 e1 d0 07 e8 6c fa  |.r=.I.........l.|
-00000470  b0 5e 0b 13 27 29 6f 1f  1e b9 05 60 16 cc ea 7b  |.^..')o....`...{|
-00000480  46 d7 12 58 03 43 b0 fe  8e 7b 83 3b ee 11 78 8c  |F..X.C...{.;..x.|
-00000490  60 0f 9c 76 63 60 01 78  a0 9b 19 b9 32 99 a9 9d  |`..vc`.x....2...|
-000004a0  42 b8 1f f1 8b 87 07 32  fa 5e 74 d5 3e 5e ba 21  |B......2.^t.>^.!|
-000004b0  ff 63 b7 c6 68 bc b3 f9  52 1a ea 23 c7 f2 ec ff  |.c..h...R..#....|
-000004c0  d4 10 0d f8 76 2f bc 0d  e5 12 7f ee d3 8d 9e 6b  |....v/.........k|
-000004d0  5e 22 78 d6 fa 5e 6a 53  16 44 16 03 03 00 04 0e  |^"x..^jS.D......|
+00000430  00 a8 03 00 1d 20 4c 46  c9 9f ed 2e 81 0f 8c 4b  |..... LF.......K|
+00000440  bc 05 53 74 c6 c8 76 99  21 94 1b 8f 93 c6 64 ce  |..St..v.!.....d.|
+00000450  e9 9d 6b 1d 66 51 08 04  00 80 09 9e c2 21 89 93  |..k.fQ.......!..|
+00000460  1f c5 2e 2c fa 67 7b 42  23 e1 e0 67 5c 6d e9 1e  |...,.g{B#..g\m..|
+00000470  e8 a2 ac d7 cf f4 12 98  f6 e6 3d 51 0c 2c 29 ad  |..........=Q.,).|
+00000480  f8 8e 24 2a a3 99 2e f3  b2 a7 fe a9 6c e9 00 d8  |..$*........l...|
+00000490  6a 7f 41 12 84 a0 d6 19  38 b1 5a 13 b6 71 cf bd  |j.A.....8.Z..q..|
+000004a0  e2 6e 04 01 c8 cd 83 12  71 85 ae bc 94 b1 e4 4d  |.n......q......M|
+000004b0  a5 5f 9e a5 5d 95 76 fe  f5 d6 a9 f0 4c 07 c9 6e  |._..].v.....L..n|
+000004c0  fc 4a 56 2b 56 4e 9c ec  2c fe bc 9c 9e 57 f3 90  |.JV+VN..,....W..|
+000004d0  c6 6e 77 5a cf 8c 1a 15  cd 90 16 03 03 00 04 0e  |.nwZ............|
 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 5c 1a 1b  0e 7e 83 4f 9b f6 8e 9f  |.... \...~.O....|
-00000040  ca 95 86 c3 7b 60 73 d3  8d 3c 6d 18 6a eb 70 a3  |....{`s..<m.j.p.|
-00000050  d9 08 f7 77 a3                                    |...w.|
+00000030  16 03 03 00 20 19 bf ac  05 d4 bb 8a 6d 11 f4 98  |.... .......m...|
+00000040  0d af 78 57 49 74 5c 44  45 9e 2c 92 26 b9 10 b5  |..xWIt\DE.,.&...|
+00000050  6d 5f 24 bc a6                                    |m_$..|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 20 1f a2 50 dd c5  |.......... ..P..|
-00000010  ba 96 4a 63 e1 cc b6 45  77 09 c1 49 cb 5f eb 4b  |..Jc...Ew..I._.K|
-00000020  38 9b b1 40 1c af b1 a2  dc 7c ba                 |8..@.....|.|
+00000000  14 03 03 00 01 01 16 03  03 00 20 69 3a c4 9c ee  |.......... i:...|
+00000010  91 6b bc 33 39 82 64 c2  0a f0 a4 dd 85 16 3c ce  |.k.39.d.......<.|
+00000020  39 c4 98 37 77 47 1e c2  c6 d8 f6                 |9..7wG.....|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 e7 54 f6  bf 56 39 57 c4 b2 ac f2  |......T..V9W....|
-00000010  b1 f4 b1 2f ad ae d7 87  21 ff 1c 15 03 03 00 12  |.../....!.......|
-00000020  5d b6 56 77 55 99 b6 7b  a4 0b d8 8e 8d 93 b6 35  |].VwU..{.......5|
-00000030  ce 9a                                             |..|
+00000000  17 03 03 00 16 92 25 9b  97 11 08 71 63 b2 c1 35  |......%....qc..5|
+00000010  14 3b e7 15 f6 05 67 51  46 db ba 15 03 03 00 12  |.;....gQF.......|
+00000020  b2 53 a1 ec a8 cf 79 7d  f8 86 70 05 e5 81 a1 6c  |.S....y}..p....l|
+00000030  41 ab                                             |A.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE b/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE
index d58a32f..3d3de61 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE
+++ b/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 75 00 05 00 05  01 00 00 00 00 00 0a 00  |...u............|
 00000090  04 00 02 00 1d 00 0b 00  02 01 00 00 0d 00 1a 00  |................|
 000000a0  18 08 04 04 03 08 07 08  05 08 06 04 01 05 01 06  |................|
@@ -16,11 +16,11 @@
 000000e0  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
 000000f0  c2 ed 90 99 5f 58 cb 3b  74                       |...._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 e0 c7 ce be 3a  |....Y...U......:|
-00000010  a6 34 5f b7 c5 ec f1 f3  09 df 4d db 39 60 71 93  |.4_.......M.9`q.|
-00000020  db 7c 30 e0 81 93 f0 19  57 6b 6b 20 9e 4b e2 1e  |.|0.....Wkk .K..|
-00000030  27 8d d3 f6 0c f3 3d bc  67 3e 79 33 fd c9 cc 55  |'.....=.g>y3...U|
-00000040  36 55 a5 aa 89 94 fe b2  51 cf 24 56 c0 2f 00 00  |6U......Q.$V./..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 f7 79 97 18 3c  |....Y...U...y..<|
+00000010  fa 52 c6 d2 6b 1e de a5  60 da d5 e2 0b f6 23 a8  |.R..k...`.....#.|
+00000020  48 94 e8 1f fb b9 76 43  94 e8 98 20 31 a5 85 d5  |H.....vC... 1...|
+00000030  2f c4 93 b1 ae aa 50 bc  14 9e 57 79 18 85 cd ef  |/.....P...Wy....|
+00000040  b4 f0 42 c9 6c b1 86 c1  03 27 ca df c0 2f 00 00  |..B.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..............|
@@ -60,33 +60,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 9b 73 58 2f 9a aa 8b  |........ .sX/...|
-000002d0  3e 80 1c b1 8e e5 d4 54  c2 d0 b1 94 16 86 e2 4b  |>......T.......K|
-000002e0  9c ab d7 ce 2c e5 26 20  04 08 04 00 80 d8 c0 18  |....,.& ........|
-000002f0  90 8e 06 d8 d6 4c af a1  ae 5e ca 4b a1 18 bb 31  |.....L...^.K...1|
-00000300  f5 3a 75 c3 d7 73 69 a7  e0 0f 8e f2 c5 92 0a bd  |.:u..si.........|
-00000310  7f 91 36 6c 01 c3 eb 08  9a 3b 25 2c bd 86 88 05  |..6l.....;%,....|
-00000320  64 e0 38 5b 75 01 10 1f  1b d5 34 09 04 2e 34 6d  |d.8[u.....4...4m|
-00000330  71 d2 6c b6 f3 7a 1e ed  a9 9d 28 60 13 fc 02 6f  |q.l..z....(`...o|
-00000340  f6 17 99 52 7b 19 60 e5  a6 11 d4 b3 4c 52 03 b5  |...R{.`.....LR..|
-00000350  3e 28 91 c6 66 87 25 df  10 c6 cf b9 5f 92 0e d7  |>(..f.%....._...|
-00000360  b6 19 f0 19 b9 f6 e9 e9  24 74 35 3b c6 16 03 03  |........$t5;....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 90 95 bd 82 cf 8a cc  |........ .......|
+000002d0  08 b4 09 09 8d 59 2d 03  7a bb 92 4a c4 5c 08 4d  |.....Y-.z..J.\.M|
+000002e0  42 a3 ba cb 9a 43 ae f0  22 08 04 00 80 a0 97 ac  |B....C..".......|
+000002f0  01 a5 c8 7b 4c 73 7e 70  7a 9a fc 9d 71 2f fe 67  |...{Ls~pz...q/.g|
+00000300  ca dd 6b 43 db 64 0f 64  52 e7 d3 5d 6d b2 7c 50  |..kC.d.dR..]m.|P|
+00000310  74 7e 80 d5 22 77 3f fb  c2 e8 dc 92 37 4f 1e 1e  |t~.."w?.....7O..|
+00000320  e7 13 f2 01 33 80 32 66  4f c2 17 8e ec 4f ed 4a  |....3.2fO....O.J|
+00000330  15 6c e8 86 ec df d5 46  6c a5 43 0d 40 fe a0 c8  |.l.....Fl.C.@...|
+00000340  65 b4 76 46 b8 36 2c da  87 7c 60 87 db 39 4c 2e  |e.vF.6,..|`..9L.|
+00000350  0f e4 72 32 11 26 99 7e  c8 7a c0 bc 9c a7 29 57  |..r2.&.~.z....)W|
+00000360  9d 27 37 4e ec c5 bb fd  a1 3c f3 66 63 16 03 03  |.'7N.....<.fc...|
 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 01 e4 5a  |....(..........Z|
-00000040  e9 dc dd 98 cd 5f d2 d2  eb 84 12 c9 96 ca 91 d7  |....._..........|
-00000050  ae f4 db 44 a4 37 f3 a3  b2 8d db ed 3d           |...D.7......=|
+00000030  16 03 03 00 28 00 00 00  00 00 00 00 00 81 b1 2c  |....(..........,|
+00000040  a2 3b 38 34 a6 66 57 02  e3 67 1b ee 73 95 50 de  |.;84.fW..g..s.P.|
+00000050  dd 5a fd 4e 0d ee b7 a6  46 1a 34 61 73           |.Z.N....F.4as|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 c2 2d 32 ba 46  |..........(.-2.F|
-00000010  27 8d 87 13 7f b9 49 04  64 2f 6e cc 32 81 f8 3c  |'.....I.d/n.2..<|
-00000020  7f 0f 19 13 5c 11 33 a1  05 5f 91 bc 97 30 64 84  |....\.3.._...0d.|
-00000030  57 69 90                                          |Wi.|
+00000000  14 03 03 00 01 01 16 03  03 00 28 2f a9 80 36 d8  |..........(/..6.|
+00000010  d0 74 e4 39 46 04 88 8e  91 ea fd 96 ed 1f 89 9f  |.t.9F...........|
+00000020  a4 e9 24 0e ca 48 2b 5c  5d f1 cc 57 ce 92 1a ad  |..$..H+\]..W....|
+00000030  b9 10 11                                          |...|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 fd 0f a5  |................|
-00000010  74 98 c4 98 ee 67 74 d4  c1 d4 fe d3 c7 e2 1b 2c  |t....gt........,|
-00000020  e5 3c be 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.<..............|
-00000030  f8 d4 60 41 13 6a 9c e3  0e 56 e2 ab 96 45 7e 06  |..`A.j...V...E~.|
-00000040  87 63                                             |.c|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 da be 68  |...............h|
+00000010  97 b4 a4 72 d0 ed 75 66  6a a9 6f 39 8a 08 a9 db  |...r..ufj.o9....|
+00000020  de 4d e1 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.M..............|
+00000030  14 90 0e 1d 26 5c 18 c6  5c 93 66 c4 90 78 a8 91  |....&\..\.f..x..|
+00000040  cb fd                                             |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-AES128-SHA256 b/src/crypto/tls/testdata/Client-TLSv13-AES128-SHA256
index 4273484..f8a733e 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-AES128-SHA256
+++ b/src/crypto/tls/testdata/Client-TLSv13-AES128-SHA256
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,75 +16,75 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 f7 30 f3 d1 e7  |....z...v...0...|
-00000010  eb 94 97 a2 c6 d5 be 74  e0 6c 08 80 2f ad 11 6b  |.......t.l../..k|
-00000020  b3 ce 22 59 06 a9 eb 41  9c 97 a8 20 00 00 00 00  |.."Y...A... ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 f1 4c f4 16 24  |....z...v...L..$|
+00000010  e5 c6 b5 ce 72 08 3b 33  9f 1f 1f 80 2c 10 0b 34  |....r.;3....,..4|
+00000020  01 99 85 ba b0 3c 85 50  3d bf 73 20 00 00 00 00  |.....<.P=.s ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 c0  |..+.....3.$... .|
-00000060  47 7e ad a1 41 53 e5 25  ec 74 46 bc 9e 80 08 3b  |G~..AS.%.tF....;|
-00000070  0b f5 7e fb 71 1f 00 d5  4b 27 51 22 4a 5e 5f 14  |..~.q...K'Q"J^_.|
-00000080  03 03 00 01 01 17 03 03  00 17 e9 e8 56 00 26 9e  |............V.&.|
-00000090  92 60 84 6c 07 3d b1 ef  e4 63 51 ba 48 ee d7 fe  |.`.l.=...cQ.H...|
-000000a0  57 17 03 03 02 6d 2e d4  bb bf a2 e8 3b 84 47 2e  |W....m......;.G.|
-000000b0  22 66 c1 98 ea 11 6b a3  4d 1b 64 c0 02 32 76 9b  |"f....k.M.d..2v.|
-000000c0  29 8a 4a 96 68 5b d1 fd  a0 0f a6 9b 70 20 c7 08  |).J.h[......p ..|
-000000d0  7b 25 07 d1 54 8c b1 bb  4e ba 32 65 2c 1e 16 29  |{%..T...N.2e,..)|
-000000e0  e7 d2 df e3 84 60 e1 43  07 99 35 4d 95 7c 27 96  |.....`.C..5M.|'.|
-000000f0  be f4 bf 0a e9 3b 9d 60  7a 6e 34 82 1f 03 ca 17  |.....;.`zn4.....|
-00000100  ac d1 a1 b5 dc 3f 20 7b  42 f6 94 43 60 ff 3f 1b  |.....? {B..C`.?.|
-00000110  b1 2e 2d 71 55 07 fb 65  40 56 59 82 1e 31 83 c9  |..-qU..e@VY..1..|
-00000120  35 6c 28 ad c1 bd 88 55  1b b6 1e 89 af 64 7f 11  |5l(....U.....d..|
-00000130  53 80 3a 62 ef 34 a7 d0  ce 38 9b 19 d6 5f 78 0d  |S.:b.4...8..._x.|
-00000140  66 73 b2 bd b6 a6 f8 70  c8 40 f9 aa a2 86 f4 48  |fs.....p.@.....H|
-00000150  0d 6c 54 67 c6 3c 91 97  ff 94 4d 9a 01 d5 e1 c9  |.lTg.<....M.....|
-00000160  8f 27 d3 8d b3 72 cd 34  eb 7a 6d 48 84 f3 8b 84  |.'...r.4.zmH....|
-00000170  34 d2 68 bd 26 bc 6d e5  46 41 cc 86 d4 7a b6 31  |4.h.&.m.FA...z.1|
-00000180  05 b3 bc a4 fe e1 5c d4  eb 8b fe 64 0e be 89 c4  |......\....d....|
-00000190  ce e0 49 a0 ba 7a 83 b6  fb 31 17 42 fd b4 e3 59  |..I..z...1.B...Y|
-000001a0  48 df f6 a8 e4 5c d1 77  77 cb c2 31 85 8a 26 65  |H....\.ww..1..&e|
-000001b0  20 fa 05 90 ae 66 95 7a  75 4b bc 93 15 dd a0 13  | ....f.zuK......|
-000001c0  61 d5 99 fb b2 27 bd ec  fd 10 b5 d2 c7 18 ac b9  |a....'..........|
-000001d0  bd bc 35 72 d0 42 6c f7  5a e0 67 46 45 10 f7 50  |..5r.Bl.Z.gFE..P|
-000001e0  e4 14 47 ac 39 5a 05 38  b9 25 4a 43 fa 57 b2 51  |..G.9Z.8.%JC.W.Q|
-000001f0  b7 3e f7 ef d5 b5 de 2e  2f 5c d0 d7 00 23 ac 4b  |.>....../\...#.K|
-00000200  65 8d 6c f4 ab 6f ef 1e  c2 66 c5 b2 cb 1a 51 4c  |e.l..o...f....QL|
-00000210  ef 96 8f 28 65 2f 50 9c  91 1f 73 87 fc 81 db 90  |...(e/P...s.....|
-00000220  16 69 00 06 98 6b 00 33  41 e1 e6 12 89 cb c9 f3  |.i...k.3A.......|
-00000230  23 2c 28 83 00 ca 4f 42  f5 26 bc 94 39 3b 18 31  |#,(...OB.&..9;.1|
-00000240  41 a9 19 4a 60 e8 de 8f  1d d0 e8 96 77 c0 49 bd  |A..J`.......w.I.|
-00000250  a2 98 bd b1 0a 6f bd 27  79 1d c4 33 50 37 a8 eb  |.....o.'y..3P7..|
-00000260  a5 4e 59 87 58 cd f0 a0  34 4e 2b 9d ee 03 e4 8a  |.NY.X...4N+.....|
-00000270  24 94 86 11 e1 94 f0 2b  3e 27 9a 92 1c 17 d3 96  |$......+>'......|
-00000280  c0 71 ab ee 75 5f 99 ca  0e 42 65 5d ed 48 0c 7a  |.q..u_...Be].H.z|
-00000290  95 8a d9 da f7 60 ee de  46 f2 f4 7a d6 ce 38 41  |.....`..F..z..8A|
-000002a0  fa e8 1f 3e 77 be 02 53  0c 33 96 5b 0d 38 bb 08  |...>w..S.3.[.8..|
-000002b0  5e 92 1a 81 f1 be c7 9a  e2 02 80 09 3b b7 62 b0  |^...........;.b.|
-000002c0  7c a7 85 3a d9 52 34 23  4f a3 04 e7 35 98 9e 18  ||..:.R4#O...5...|
-000002d0  13 0b 71 12 6d a4 2e 11  bf 39 8c 94 ef 15 96 27  |..q.m....9.....'|
-000002e0  9e be 81 d9 55 5a 8b 14  c5 49 dd 6e 6e 7b 6b c2  |....UZ...I.nn{k.|
-000002f0  f3 7d ef 24 88 b9 eb a6  15 3e aa a8 3e eb 37 54  |.}.$.....>..>.7T|
-00000300  fc 86 9f 51 30 5f 9c a5  fc 7a af f6 1b a5 a4 27  |...Q0_...z.....'|
-00000310  51 78 f7 17 03 03 00 99  79 14 63 10 91 cd 73 f5  |Qx......y.c...s.|
-00000320  a8 62 c3 92 a3 04 c2 3d  58 5e d3 6e 93 eb 9b b1  |.b.....=X^.n....|
-00000330  11 f0 3c c6 96 9f c6 c8  9b de 2c d5 12 c2 bd d1  |..<.......,.....|
-00000340  2a 68 89 4a 07 1e 23 d2  45 ca a1 0f 92 71 b7 f7  |*h.J..#.E....q..|
-00000350  d0 2f 2a be d0 5e 0c 5d  13 8f b0 7f df b8 52 2e  |./*..^.]......R.|
-00000360  7a 5e c8 eb 84 06 46 81  d0 f7 09 18 52 fb ce fd  |z^....F.....R...|
-00000370  22 d8 74 71 e8 7d 41 5f  3a 5d e5 f9 bb e6 99 03  |".tq.}A_:]......|
-00000380  32 d1 58 e8 5a 58 d8 b2  39 61 01 33 72 7d d2 11  |2.X.ZX..9a.3r}..|
-00000390  8f f7 58 55 c8 f2 64 63  33 9b 78 36 bf 9b 8b 40  |..XU..dc3.x6...@|
-000003a0  8c ec 7b a2 bb 51 ed b1  fe 74 c2 c9 1f b4 2b cb  |..{..Q...t....+.|
-000003b0  fd 17 03 03 00 35 75 46  88 74 06 9b 5e 88 c2 0d  |.....5uF.t..^...|
-000003c0  fc 7d 29 bd 6c 1c 23 2f  06 3f 14 b1 55 e4 98 b1  |.}).l.#/.?..U...|
-000003d0  ed c3 9a ed ea be 29 60  15 ac 80 c7 a8 f7 9b ce  |......)`........|
-000003e0  f3 79 b3 be ad ff ab b4  a7 45 57                 |.y.......EW|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 69  |..+.....3.$... i|
+00000060  94 3b 83 cd 1f 93 53 53  82 de 14 cb 76 2a 19 62  |.;....SS....v*.b|
+00000070  0f f8 9e d1 e3 e0 a9 d5  23 ac 07 64 53 27 4b 14  |........#..dS'K.|
+00000080  03 03 00 01 01 17 03 03  00 17 ef 24 2c ea 6f 05  |...........$,.o.|
+00000090  c2 07 7a d2 12 30 ce 01  f4 96 b8 dc e6 c2 27 02  |..z..0........'.|
+000000a0  bd 17 03 03 02 6d 99 2b  cb 79 43 01 66 24 eb f1  |.....m.+.yC.f$..|
+000000b0  14 d2 ea 1e 57 67 81 e3  a0 9c 99 1b 1f d5 f0 c7  |....Wg..........|
+000000c0  78 48 61 01 42 25 85 0b  cd a1 b1 75 3c 50 01 cc  |xHa.B%.....u<P..|
+000000d0  69 09 22 a5 fb db 43 76  2f 4e 34 4e 14 a3 e4 89  |i."...Cv/N4N....|
+000000e0  f7 d7 cd 66 da b3 1d fd  f0 98 60 18 41 09 a5 22  |...f......`.A.."|
+000000f0  6d c9 21 bc c3 cd 53 ca  c3 a5 d7 24 57 b4 f5 bc  |m.!...S....$W...|
+00000100  ec b1 48 70 12 55 a5 a6  01 10 68 0f c4 e5 de 89  |..Hp.U....h.....|
+00000110  f9 0d ab 48 92 d4 12 d7  75 77 c3 2f ae 2f 6f 58  |...H....uw././oX|
+00000120  2d 6e ad 72 43 dc ce 4b  c9 74 3d eb db da 37 2c  |-n.rC..K.t=...7,|
+00000130  1e a2 86 c4 b3 64 69 f6  84 ce 52 b5 32 c6 b9 c2  |.....di...R.2...|
+00000140  49 2d 08 f9 d4 9a 29 09  5b 71 09 81 a3 19 c2 4d  |I-....).[q.....M|
+00000150  8c 48 2c e3 c6 cb 81 d4  7f 10 b3 c8 2b 21 ad 83  |.H,.........+!..|
+00000160  97 d2 bd 11 90 39 1e f4  de 65 e2 e8 e8 c7 ce f9  |.....9...e......|
+00000170  6d ad b0 60 5c 4b 59 c4  96 ce b3 a1 83 b2 7c 71  |m..`\KY.......|q|
+00000180  74 e6 a9 a7 89 bf 8d 0d  6c 8d b5 04 33 38 ff 68  |t.......l...38.h|
+00000190  42 0e 84 da d2 b2 16 29  83 66 82 a9 2a d2 67 1b  |B......).f..*.g.|
+000001a0  18 a6 7d e3 f1 d3 f1 b4  cc 6c 14 e2 cd 2d 96 7b  |..}......l...-.{|
+000001b0  76 dd b0 1d 24 7f ea c0  14 24 d7 37 00 7c cd e3  |v...$....$.7.|..|
+000001c0  20 33 a4 3a 22 2a be 3e  e8 f8 7c 0d 3e 51 f7 6b  | 3.:"*.>..|.>Q.k|
+000001d0  ce f3 51 cf 7e ae 55 40  bb ab 0e 40 6b d9 8a 3b  |..Q.~.U@...@k..;|
+000001e0  d5 f2 1f 76 6a 05 9b 87  e2 3b db fa cc e8 93 8a  |...vj....;......|
+000001f0  d9 ba 2b 63 77 77 62 f1  22 ce 11 a9 26 b5 e8 a2  |..+cwwb."...&...|
+00000200  ec 3f 98 44 01 27 d7 e1  39 26 33 e3 86 00 60 f7  |.?.D.'..9&3...`.|
+00000210  a7 91 07 45 f8 3f 78 dc  88 71 30 26 0c f9 0d 51  |...E.?x..q0&...Q|
+00000220  2a c5 ce 33 ac b7 91 a9  74 2e 46 68 80 6e 62 cd  |*..3....t.Fh.nb.|
+00000230  2d 5e 43 fe bd d1 37 07  71 85 5d c7 38 17 50 3a  |-^C...7.q.].8.P:|
+00000240  1c 5e 9f cf 1e 3c 96 d0  26 5d 4c 82 78 a8 69 e7  |.^...<..&]L.x.i.|
+00000250  d3 9a 81 e5 85 66 c3 d9  74 a1 82 9d fb 24 81 13  |.....f..t....$..|
+00000260  0d ce cb 43 61 3c 3a a7  d1 80 7f 1d 41 d8 62 43  |...Ca<:.....A.bC|
+00000270  c6 08 5d 91 05 ed 2c 50  04 42 8c db 2a 11 61 96  |..]...,P.B..*.a.|
+00000280  9b d2 1d 40 af 83 ed 93  06 ba 65 22 0a a5 e8 a6  |...@......e"....|
+00000290  b9 4a 63 6f c0 ac da 72  10 24 c6 ed 08 86 c8 a1  |.Jco...r.$......|
+000002a0  92 5e d0 d8 8b 04 b7 43  50 0b 03 41 3f f9 96 16  |.^.....CP..A?...|
+000002b0  a3 c8 09 e8 ac 91 b2 45  d5 58 5f 41 05 7c b3 88  |.......E.X_A.|..|
+000002c0  7a 59 cd 1a 00 86 29 72  77 a5 19 43 32 79 fc d6  |zY....)rw..C2y..|
+000002d0  d7 e9 81 08 e3 d9 d9 56  39 59 7c 1e d3 10 3e a4  |.......V9Y|...>.|
+000002e0  c6 80 d3 8b 9b 36 51 c5  d3 14 64 a6 65 e2 1a 26  |.....6Q...d.e..&|
+000002f0  c4 a8 31 07 bb 58 8c 9b  d8 7d 86 fd 54 6c c9 ae  |..1..X...}..Tl..|
+00000300  7d 88 4b 13 0f 52 10 41  d6 be 01 32 f2 42 47 0f  |}.K..R.A...2.BG.|
+00000310  7a 8c 7e 17 03 03 00 99  8b ce c4 db 9c 9c 88 e3  |z.~.............|
+00000320  88 58 de 8f 10 e9 fb 4a  c7 26 96 60 48 84 2c b1  |.X.....J.&.`H.,.|
+00000330  2b 6c 35 70 8a d7 39 91  51 d7 3f db 81 f0 41 07  |+l5p..9.Q.?...A.|
+00000340  a2 c9 c1 74 76 62 58 f1  cb e2 50 48 57 bb 6e 3d  |...tvbX...PHW.n=|
+00000350  ee ee 4a 53 e7 3c 66 aa  e3 d9 c1 f1 74 1a 93 b9  |..JS.<f.....t...|
+00000360  44 90 f6 a5 a4 da f5 6b  75 01 38 52 8f 9c ab 01  |D......ku.8R....|
+00000370  78 88 a6 cc 65 15 61 a8  8c cc 14 59 07 ea 6f 25  |x...e.a....Y..o%|
+00000380  5c 86 89 16 eb e7 da 20  82 d7 96 e4 78 7a c3 36  |\...... ....xz.6|
+00000390  b3 5c e7 17 1b 07 30 a2  72 ca a2 f3 dc 7e 45 c9  |.\....0.r....~E.|
+000003a0  7f 94 f8 a1 7b bb 2a 30  d7 bc 51 03 fb e6 2a fa  |....{.*0..Q...*.|
+000003b0  17 17 03 03 00 35 c1 a0  76 b6 35 4b 5c 26 94 c6  |.....5..v.5K\&..|
+000003c0  ba b1 7b b1 13 00 f2 2c  17 ed ac ab 47 9a a1 8d  |..{....,....G...|
+000003d0  3a 1c 78 44 14 a1 04 31  3d eb 9a 8d bb 2f 73 46  |:.xD...1=..../sF|
+000003e0  cb 5c f6 86 81 fa 56 fb  39 8c 55                 |.\....V.9.U|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 00 35 b5 22 19 23 49  |..........5.".#I|
-00000010  48 33 a5 f3 b2 72 2b 31  ab 89 27 f9 eb 1b b7 b1  |H3...r+1..'.....|
-00000020  bc 2b 99 9e 73 24 42 c4  2a 68 2c 76 e1 45 61 09  |.+..s$B.*h,v.Ea.|
-00000030  18 c7 44 45 9a 05 86 4c  90 c1 41 c6 fd 6a c2 95  |..DE...L..A..j..|
-00000040  17 03 03 00 17 ee 18 4e  d9 94 15 50 a9 99 4a 82  |.......N...P..J.|
-00000050  10 13 26 7b 74 10 db ef  fe b8 96 f6 17 03 03 00  |..&{t...........|
-00000060  13 2a 4c 52 8d c3 c5 af  d0 cd 5a 7d 0d a5 59 90  |.*LR......Z}..Y.|
-00000070  ce 59 3b af                                       |.Y;.|
+00000000  14 03 03 00 01 01 17 03  03 00 35 97 2c 39 3a a5  |..........5.,9:.|
+00000010  32 33 e5 74 43 97 98 ef  ef 30 de 27 8b f7 b5 ab  |23.tC....0.'....|
+00000020  dd af 87 7c a5 5e 76 cf  50 2a 03 f8 94 a4 7a df  |...|.^v.P*....z.|
+00000030  14 0a 2d 39 57 3b 02 97  c5 d7 63 85 21 3f 55 27  |..-9W;....c.!?U'|
+00000040  17 03 03 00 17 7c b4 8b  82 f0 0a ec 6f fa 60 ef  |.....|......o.`.|
+00000050  4c 0a 1c 0b ad 99 c3 89  fb a4 40 2c 17 03 03 00  |L.........@,....|
+00000060  13 f2 d5 58 ba 6b ca e8  f4 14 4c 66 23 38 f2 e8  |...X.k....Lf#8..|
+00000070  ea a9 ba c1                                       |....|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-AES256-SHA384 b/src/crypto/tls/testdata/Client-TLSv13-AES256-SHA384
index 7fecc79..8ea3ed6 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-AES256-SHA384
+++ b/src/crypto/tls/testdata/Client-TLSv13-AES256-SHA384
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,77 +16,77 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 dd df 8d 85 da  |....z...v.......|
-00000010  3c 99 a3 0c 01 90 5f ec  b8 3d 28 ce e4 32 c0 e8  |<....._..=(..2..|
-00000020  fe 77 03 ad 0f e1 33 1f  dc 89 cb 20 00 00 00 00  |.w....3.... ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 71 00 90 30 07  |....z...v..q..0.|
+00000010  24 01 ae 33 b2 e8 4f 1f  9a 2c 83 e5 7b 30 1e a2  |$..3..O..,..{0..|
+00000020  8e 4a d0 df d1 ec 23 b5  ba aa 75 20 00 00 00 00  |.J....#...u ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 02 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 03  |..+.....3.$... .|
-00000060  6b 91 90 36 f0 54 da 66  8e 47 9b 26 9f 9f ae 30  |k..6.T.f.G.&...0|
-00000070  69 9e a2 6a 70 fb ef b2  f1 76 2b 32 90 0e 63 14  |i..jp....v+2..c.|
-00000080  03 03 00 01 01 17 03 03  00 17 46 47 2e ae ea 9b  |..........FG....|
-00000090  78 7b 0c d4 74 e2 b5 bf  7b 64 da c3 d3 c9 55 7f  |x{..t...{d....U.|
-000000a0  e3 17 03 03 02 6d a8 c1  57 27 66 9d 16 f6 4f 1b  |.....m..W'f...O.|
-000000b0  17 b6 5d 8c 3c fe f5 d5  4a d3 c6 8d e2 a8 2d d0  |..].<...J.....-.|
-000000c0  01 8d db 18 e8 c8 69 74  eb 81 9e 97 20 01 60 d5  |......it.... .`.|
-000000d0  96 d1 8f 9c de 09 ff 1d  e7 45 97 97 36 fa 89 77  |.........E..6..w|
-000000e0  88 20 30 c6 5b 42 d6 0e  85 9a 11 43 60 a1 86 34  |. 0.[B.....C`..4|
-000000f0  22 47 25 23 a5 35 87 a9  74 5d fe eb c9 70 32 44  |"G%#.5..t]...p2D|
-00000100  17 60 55 99 7a 93 b5 92  8b 66 31 ce dc e0 39 f2  |.`U.z....f1...9.|
-00000110  6a b3 db 43 5d 3f ba e5  12 12 1f 0e 3c 35 3b 72  |j..C]?......<5;r|
-00000120  9f 9d 69 d5 d6 cb ac b5  9e f4 af f5 74 68 67 f4  |..i.........thg.|
-00000130  e9 5f a4 4a d7 27 5b a5  2a 39 b7 30 49 4d 64 bb  |._.J.'[.*9.0IMd.|
-00000140  5d 89 10 ff a6 2c 42 a1  4a 2a 0c 28 c6 cd 4a e8  |]....,B.J*.(..J.|
-00000150  7d 24 d0 75 ff 61 08 3f  3b 05 ec f3 d6 61 ed 43  |}$.u.a.?;....a.C|
-00000160  08 5e 07 1c f2 15 96 22  2a c0 3c 5f 04 d1 17 82  |.^....."*.<_....|
-00000170  ea ee ee c7 49 cc 3e e4  65 15 97 6e 6f 36 24 a9  |....I.>.e..no6$.|
-00000180  27 34 3a 75 dc 07 1e 4c  f1 29 d1 e3 22 31 7d 84  |'4:u...L.).."1}.|
-00000190  a8 2a 7f 37 03 ab 13 ae  15 e2 74 50 bd 54 5b 32  |.*.7......tP.T[2|
-000001a0  ea 75 10 ed 39 5c 69 90  f6 74 09 53 c1 ce 44 49  |.u..9\i..t.S..DI|
-000001b0  64 fb f2 c6 bd 93 b2 07  06 96 94 04 a5 9e ed 67  |d..............g|
-000001c0  10 cb 01 fc 85 45 d7 22  76 3c c6 2f 14 4c 31 e1  |.....E."v<./.L1.|
-000001d0  73 81 7b 8b 6b 54 d6 34  15 d2 eb d0 03 10 c7 3d  |s.{.kT.4.......=|
-000001e0  f5 07 48 cc 72 9b e9 48  ee 13 9f 80 b5 13 86 77  |..H.r..H.......w|
-000001f0  33 91 79 6f f2 13 17 68  ca 72 6b 0d 93 9a 20 30  |3.yo...h.rk... 0|
-00000200  70 c3 30 ab 13 7e 14 39  97 4b ce c5 3d 8b 03 7f  |p.0..~.9.K..=...|
-00000210  cd 4b 67 c4 c5 79 0c bb  cd ba 17 c5 d5 15 51 cb  |.Kg..y........Q.|
-00000220  ac b7 f7 19 43 ff f5 c4  09 8c 44 67 ca e6 a1 5f  |....C.....Dg..._|
-00000230  1d 27 29 63 f2 0d 75 6d  b7 62 52 c9 1d 8e 0e 3b  |.')c..um.bR....;|
-00000240  6c cb 04 3e f7 13 74 bb  03 35 2e 4e 41 9a b7 72  |l..>..t..5.NA..r|
-00000250  15 ed 02 79 c7 bc 38 b3  65 75 0a 8e 82 dc d4 79  |...y..8.eu.....y|
-00000260  1c 10 3f 78 8c be 78 b0  73 18 cc 52 1d 3b 91 66  |..?x..x.s..R.;.f|
-00000270  33 fe 63 b2 ec 19 92 44  8f 06 4e 20 85 94 5c b4  |3.c....D..N ..\.|
-00000280  ad 22 16 a0 b3 76 03 dc  62 e9 0c ac 8c e1 67 c9  |."...v..b.....g.|
-00000290  d8 6f 40 51 b5 39 9a 61  b6 63 e0 d5 60 6a 27 78  |.o@Q.9.a.c..`j'x|
-000002a0  62 ec 94 1c 75 2c 38 f2  a6 f2 f0 c4 8f 98 ad cc  |b...u,8.........|
-000002b0  2e ce 7d 13 76 f4 4f 94  78 3f 85 cf ea 52 c4 6e  |..}.v.O.x?...R.n|
-000002c0  16 65 f9 48 5e f9 0b 07  bc 3e 38 91 06 e1 b0 76  |.e.H^....>8....v|
-000002d0  82 60 25 03 36 9c 3e 5e  54 73 8d cf df 91 19 33  |.`%.6.>^Ts.....3|
-000002e0  a7 18 96 d4 86 ea 7c 00  88 e6 a3 fe ea a1 14 db  |......|.........|
-000002f0  ae da 07 ef 1e 6f 16 bb  ad fb c0 f4 60 2f 75 5c  |.....o......`/u\|
-00000300  a4 43 a0 fc 3c d6 5e 89  cf 6e 1a c6 de 61 65 34  |.C..<.^..n...ae4|
-00000310  03 e5 cd 17 03 03 00 99  0a f3 a2 45 fe 53 22 37  |...........E.S"7|
-00000320  cd 31 9d 67 31 56 f9 99  c2 d1 bc 6d 47 de 9a e7  |.1.g1V.....mG...|
-00000330  67 c0 89 84 ac bf 27 b5  32 f0 e9 a5 9d f2 e0 ad  |g.....'.2.......|
-00000340  fd 12 6a a4 5d 50 4c b9  ed f1 f4 0e c0 c0 6c c4  |..j.]PL.......l.|
-00000350  39 9b 10 02 fa 10 64 a6  8b af 9d 6e d9 40 6d 0c  |9.....d....n.@m.|
-00000360  b0 6c b8 8d d5 b0 14 f0  ed 85 d6 66 8f 6f 61 43  |.l.........f.oaC|
-00000370  49 dd 95 08 94 2e a8 a6  19 b9 7b 6b 99 09 af 4c  |I.........{k...L|
-00000380  5f 41 48 da 10 b6 cf ee  68 b6 6e 03 d7 29 93 8e  |_AH.....h.n..)..|
-00000390  1a ab d1 ad d4 bf 33 2a  53 87 92 05 d1 1a de c0  |......3*S.......|
-000003a0  aa ef b9 9c 4d 2d f6 b1  72 60 22 80 bb 46 24 75  |....M-..r`"..F$u|
-000003b0  35 17 03 03 00 45 46 9e  b3 7f d0 82 b6 ef 45 1f  |5....EF.......E.|
-000003c0  18 6d 3b b6 23 f5 c9 f4  54 e3 08 d0 8b 30 c7 31  |.m;.#...T....0.1|
-000003d0  af 98 26 69 b7 6e 08 1d  1f be 1a 7e 5b 97 91 28  |..&i.n.....~[..(|
-000003e0  fa b7 78 05 ee 3f a1 9e  a0 79 fc 45 51 4c 96 fb  |..x..?...y.EQL..|
-000003f0  03 46 24 7d fe ec a4 40  51 d6 73                 |.F$}...@Q.s|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 06  |..+.....3.$... .|
+00000060  2a 26 bd 81 c2 90 9b 17  6e d0 b5 ab 72 e6 93 ce  |*&......n...r...|
+00000070  53 6d 8c 54 b5 a4 50 91  93 32 6e 88 e6 b2 69 14  |Sm.T..P..2n...i.|
+00000080  03 03 00 01 01 17 03 03  00 17 7d 11 37 f0 18 b1  |..........}.7...|
+00000090  53 55 38 bb 12 7c e8 b3  89 bc 35 fb 2a 36 d1 0f  |SU8..|....5.*6..|
+000000a0  3a 17 03 03 02 6d a0 fa  dc 8e ac a6 90 5a 20 0e  |:....m.......Z .|
+000000b0  ee 22 89 7b 69 5b c9 1a  a1 c6 43 b9 40 f6 85 78  |.".{i[....C.@..x|
+000000c0  61 0b 14 c6 e6 3b a9 ac  4c 7a 96 9b 7b 87 d0 ce  |a....;..Lz..{...|
+000000d0  42 cc 75 9d fc 06 44 3e  e8 12 3a 94 b7 de 86 c4  |B.u...D>..:.....|
+000000e0  b5 66 e1 f5 48 21 f7 f1  58 7f 23 6c 3f 76 a0 cb  |.f..H!..X.#l?v..|
+000000f0  a7 f6 72 34 07 fa c1 55  3e 61 cf 72 c4 6c f1 ca  |..r4...U>a.r.l..|
+00000100  dd dc ec 66 3d 7b f6 cf  53 3b 28 bd 27 1b aa a6  |...f={..S;(.'...|
+00000110  28 2a ab fa 48 a5 08 67  b5 49 c7 c7 5d f8 2c ec  |(*..H..g.I..].,.|
+00000120  83 af 58 33 42 6c c1 4c  94 17 7e 36 1c a9 48 34  |..X3Bl.L..~6..H4|
+00000130  5f 26 78 f6 69 88 3a a5  1b d1 76 ad 88 63 25 33  |_&x.i.:...v..c%3|
+00000140  0d e3 d0 34 6b 7f fc 96  2b 8d 22 6f 3f 21 8a 14  |...4k...+."o?!..|
+00000150  01 e0 5c 54 6c c3 b8 12  f9 17 f5 4c ce e0 bd 10  |..\Tl......L....|
+00000160  e7 e1 29 24 73 94 c2 5e  b0 ad d3 91 9e 87 ea 23  |..)$s..^.......#|
+00000170  4d fd 8f 12 ca 87 ff 2e  93 9f 16 a8 18 e1 66 8f  |M.............f.|
+00000180  50 76 15 cd 70 5c a2 1d  91 51 e5 54 13 5f 73 d3  |Pv..p\...Q.T._s.|
+00000190  b2 6e b1 27 80 0b 3d 64  d5 fa f3 a4 fb 77 33 cb  |.n.'..=d.....w3.|
+000001a0  ac 93 54 36 2d 71 c3 9e  dd 37 02 a9 9d b0 9b ac  |..T6-q...7......|
+000001b0  f8 c5 dc 43 9b d8 db c7  d0 fb cf 69 fa 62 e4 9d  |...C.......i.b..|
+000001c0  b7 04 f8 49 d3 a7 8d bd  cf 8a e3 4a 62 cb bb 29  |...I.......Jb..)|
+000001d0  b5 db 21 80 76 eb 28 67  34 1e 40 0b 83 83 19 10  |..!.v.(g4.@.....|
+000001e0  46 8f bd 78 d6 7c 05 c2  19 82 1c e8 7d 84 f2 79  |F..x.|......}..y|
+000001f0  c4 a6 e0 f7 7e df 70 7f  42 48 9f e4 99 03 7f 9e  |....~.p.BH......|
+00000200  e8 fd 75 c3 8a 55 55 8e  08 2e 62 28 a5 16 b7 11  |..u..UU...b(....|
+00000210  d8 9a 11 48 46 ad d3 ba  4f 91 c8 fd 72 d9 df 98  |...HF...O...r...|
+00000220  1a 59 51 55 af ab 73 b9  f3 bf fe 7d 55 7d 44 54  |.YQU..s....}U}DT|
+00000230  cd bb f3 eb 6e ff 5a 09  e9 b9 c1 66 97 8e a5 7c  |....n.Z....f...||
+00000240  89 4a 51 1d 8b e4 40 fb  97 ce ef 9d 7c 02 e4 db  |.JQ...@.....|...|
+00000250  f1 ca 01 d9 05 b4 de 10  23 33 92 ff 26 3b 09 8f  |........#3..&;..|
+00000260  11 7c 37 ad fb 58 ed 7a  10 08 fd df 98 dd d6 c5  |.|7..X.z........|
+00000270  b8 fd 59 37 21 1d 6e 27  8a 56 24 45 e7 64 61 0b  |..Y7!.n'.V$E.da.|
+00000280  20 2d bc 79 89 fa 6d 7a  06 77 61 0c 60 25 e2 79  | -.y..mz.wa.`%.y|
+00000290  6a 54 9e 5b 4b 33 68 17  da 63 ba a7 f9 ad 2c 84  |jT.[K3h..c....,.|
+000002a0  52 e9 27 85 71 74 d2 5f  c9 f8 8e 67 f7 47 58 f5  |R.'.qt._...g.GX.|
+000002b0  e4 72 a7 bd 1c 94 4b 4d  13 5a 62 69 d9 6f 3a 51  |.r....KM.Zbi.o:Q|
+000002c0  f0 18 90 e5 b6 21 23 97  70 74 93 ba 9b bc dc e4  |.....!#.pt......|
+000002d0  3d 9c 52 3f 93 f0 48 05  e8 50 d0 b4 98 92 7a 18  |=.R?..H..P....z.|
+000002e0  3f 39 ba f8 f7 ee 19 b0  ce ac d0 ab 9e 83 ee 0e  |?9..............|
+000002f0  5d 2a 72 74 a8 8b 4d de  6b a9 91 ad b4 a4 26 99  |]*rt..M.k.....&.|
+00000300  4e aa 6d 48 77 83 78 78  be 96 f1 17 d6 96 74 4a  |N.mHw.xx......tJ|
+00000310  80 d1 5b 17 03 03 00 99  d9 40 96 5c fb 5d 65 69  |..[......@.\.]ei|
+00000320  db 54 a8 f6 8c b7 d3 25  8d 2d c5 f1 40 5b f2 26  |.T.....%.-..@[.&|
+00000330  f3 86 9e 61 6a a5 b9 66  b1 27 b1 20 6b 2c 64 84  |...aj..f.'. k,d.|
+00000340  3f 48 24 5d d9 90 4b d1  ed 1b 0e 05 84 7f ad 0e  |?H$]..K.........|
+00000350  e6 75 f6 f9 33 90 73 7c  88 10 d7 e9 74 41 4b c3  |.u..3.s|....tAK.|
+00000360  19 8e e1 a8 a6 7c 3c 9a  bc 69 a7 e7 bb d6 af 98  |.....|<..i......|
+00000370  f1 49 53 14 95 80 d6 95  81 5a 5e 88 2c 29 70 df  |.IS......Z^.,)p.|
+00000380  b2 df fe f3 17 03 e7 de  af 12 57 c5 7a ef 70 eb  |..........W.z.p.|
+00000390  8a c6 c3 05 de 5b 15 af  5f 54 8c 7b 23 b7 e1 f1  |.....[.._T.{#...|
+000003a0  30 b1 ed 34 4c 59 f5 68  c2 50 e8 c3 83 78 1d 1f  |0..4LY.h.P...x..|
+000003b0  eb 17 03 03 00 45 1a d4  61 ba 4a a5 1e 02 80 04  |.....E..a.J.....|
+000003c0  2a 19 11 af 8c e9 bd ab  22 6b 75 41 a8 40 de 57  |*......."kuA.@.W|
+000003d0  54 8c dc 09 cc 57 76 82  27 5e 59 0c 30 f7 9d c4  |T....Wv.'^Y.0...|
+000003e0  fe 1c 09 f2 f4 5f e0 79  ac 02 06 80 f3 60 c4 92  |....._.y.....`..|
+000003f0  cd 6a df b6 46 7c de 90  8d bb 94                 |.j..F|.....|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 00 45 44 15 b9 ed d8  |..........ED....|
-00000010  10 2c 88 80 79 f3 38 a4  bc 42 9b 22 09 44 d9 19  |.,..y.8..B.".D..|
-00000020  e1 0a ec 15 aa d5 15 e9  19 6d b8 6b 71 63 86 ce  |.........m.kqc..|
-00000030  e7 16 0d 8e 3f 9a 3b 52  25 1e 96 f6 d9 d1 6c dd  |....?.;R%.....l.|
-00000040  e3 20 e9 97 f9 60 81 f5  4a b2 26 b5 d3 9e 84 46  |. ...`..J.&....F|
-00000050  17 03 03 00 17 de 4a e9  44 21 88 ef ce 78 35 6d  |......J.D!...x5m|
-00000060  b2 e4 78 47 39 8d 1f fd  9b 2d a4 47 17 03 03 00  |..xG9....-.G....|
-00000070  13 98 f9 1c 9c d4 b1 42  f7 e7 a1 9b 6d b1 b1 cb  |.......B....m...|
-00000080  86 e3 c2 27                                       |...'|
+00000000  14 03 03 00 01 01 17 03  03 00 45 8c 37 d5 7e 3e  |..........E.7.~>|
+00000010  c4 24 64 8b fa fc 8d 03  a7 92 34 35 c3 2c f2 54  |.$d.......45.,.T|
+00000020  43 06 5d 8a c9 c0 e8 7d  22 d3 99 58 01 0e 44 aa  |C.]....}"..X..D.|
+00000030  3c 26 eb 68 45 14 cd bf  6c 61 bb 31 91 9d b4 57  |<&.hE...la.1...W|
+00000040  42 79 14 8c 67 c6 65 52  15 07 c8 f3 c3 9f 23 ef  |By..g.eR......#.|
+00000050  17 03 03 00 17 21 51 dd  67 e4 be f8 7c 7b 84 0d  |.....!Q.g...|{..|
+00000060  78 3c 7f ac 50 f8 34 7b  fb 38 09 d0 17 03 03 00  |x<..P.4{.8......|
+00000070  13 35 1a 52 9d de 4a 74  1f 01 70 de 05 c5 c3 b9  |.5.R..Jt..p.....|
+00000080  e6 de 9c 0f                                       |....|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ALPN b/src/crypto/tls/testdata/Client-TLSv13-ALPN
index 0ac9b36..1d8da26 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-ALPN
+++ b/src/crypto/tls/testdata/Client-TLSv13-ALPN
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 8f 00 05 00 05  01 00 00 00 00 00 0a 00  |................|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -18,76 +18,76 @@
 00000100  bb 29 07 30 ff f6 84 af  c4 cf c2 ed 90 99 5f 58  |.).0.........._X|
 00000110  cb 3b 74                                          |.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 23 c5 c4 0c 4a  |....z...v..#...J|
-00000010  d2 5f 0b f6 ea 21 7a d1  a0 7d 21 26 b5 a3 94 ca  |._...!z..}!&....|
-00000020  91 6c 13 58 60 4f 39 cc  1a f7 c0 20 00 00 00 00  |.l.X`O9.... ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 c2 91 70 7a 7a  |....z...v....pzz|
+00000010  d4 c9 46 7a e9 44 d1 c0  92 a6 0a 43 34 08 b2 ce  |..Fz.D.....C4...|
+00000020  14 99 8f 6c f7 37 fb a1  28 00 ae 20 00 00 00 00  |...l.7..(.. ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 f9  |..+.....3.$... .|
-00000060  64 7e 54 8f 64 ec 3d 7c  17 f1 96 3c 44 ca cd d7  |d~T.d.=|...<D...|
-00000070  3d 92 02 06 5a f8 ab dc  f3 50 fe 5c ab 04 6b 14  |=...Z....P.\..k.|
-00000080  03 03 00 01 01 17 03 03  00 24 9f 15 ee 1e 43 26  |.........$....C&|
-00000090  31 53 01 8b a0 a7 e9 ac  96 51 a7 bc fe 46 6c 60  |1S.......Q...Fl`|
-000000a0  d1 8b c4 a9 34 cd 93 13  51 50 e9 02 f9 ce 17 03  |....4...QP......|
-000000b0  03 02 6d c3 ad 14 a8 d3  81 87 26 7d a0 60 57 2c  |..m.......&}.`W,|
-000000c0  d2 65 f5 a5 fc a8 c4 dd  2e e2 04 57 1f 94 a4 4a  |.e.........W...J|
-000000d0  3a 43 92 f4 f5 58 e9 11  d7 b1 62 0d d1 f4 d5 43  |:C...X....b....C|
-000000e0  4a c8 fa d9 28 18 ca 74  1a b2 39 e2 9b 95 40 0e  |J...(..t..9...@.|
-000000f0  63 ed 11 52 9b 61 36 0c  c3 a6 7b de 4d 68 48 55  |c..R.a6...{.MhHU|
-00000100  e2 05 e8 59 e1 df 51 08  06 a8 09 a0 d5 e7 14 e9  |...Y..Q.........|
-00000110  13 c6 a4 6d ff 7b b0 98  50 ef 81 1b 64 6f 44 c1  |...m.{..P...doD.|
-00000120  cd da 85 a0 80 0c da 54  90 8e a1 7d 4b 1d 16 fc  |.......T...}K...|
-00000130  40 ba e3 25 e3 c2 52 29  7a 23 50 2a 43 3f 7e 32  |@..%..R)z#P*C?~2|
-00000140  73 e0 5a a5 3f 09 b0 3a  b8 90 8b 36 06 ac fc ef  |s.Z.?..:...6....|
-00000150  e8 9c ba f3 fb 8e 2d ab  b3 c6 f4 d0 1d eb 7b 20  |......-.......{ |
-00000160  2b 68 1f e9 25 49 c9 2a  45 6e 2b a5 00 12 54 b2  |+h..%I.*En+...T.|
-00000170  a7 16 2f 00 72 d4 ed 7d  ea 7e cb b1 0a 03 c6 3b  |../.r..}.~.....;|
-00000180  b8 fe 97 59 6a b4 07 d3  2c b1 cc ca e8 46 24 97  |...Yj...,....F$.|
-00000190  d2 b8 a5 8e 7d 6f 78 7f  bd ee 7d 5a f6 ec 07 50  |....}ox...}Z...P|
-000001a0  00 c4 63 33 03 e5 09 44  c3 68 61 ec 5b 52 f8 67  |..c3...D.ha.[R.g|
-000001b0  66 60 fd 68 fe d7 b7 df  96 2c 1b 00 93 89 24 58  |f`.h.....,....$X|
-000001c0  20 2d 0a c1 c4 80 fc 03  8c 16 d1 83 11 a9 e7 70  | -.............p|
-000001d0  69 3f cf c2 dc 90 40 70  1a 1e d9 8e 36 02 61 57  |i?....@p....6.aW|
-000001e0  49 60 2d ba 59 76 fb 26  50 c8 db 82 b3 62 e5 d7  |I`-.Yv.&P....b..|
-000001f0  fb c6 91 9b 99 6e d2 d7  e1 8a da ec 87 e9 d8 71  |.....n.........q|
-00000200  3a 01 01 c9 9c da 3c 81  67 bc fb 30 0c 81 31 62  |:.....<.g..0..1b|
-00000210  c2 ff 1f ee db 27 e2 07  59 51 fb e2 64 89 e5 0e  |.....'..YQ..d...|
-00000220  0a 37 06 07 8a 96 34 b9  53 8d 0a ed 60 02 cb f5  |.7....4.S...`...|
-00000230  af b2 9c 77 27 2a 23 69  5f 58 cc 46 32 ab 76 df  |...w'*#i_X.F2.v.|
-00000240  1b c1 17 98 6e fb 9e 15  e0 7f e1 00 75 6d b2 cf  |....n.......um..|
-00000250  ce 6e dd 6c 00 b6 81 14  bb 06 60 b4 47 07 2a cf  |.n.l......`.G.*.|
-00000260  dc 87 72 07 7e 1d 76 fc  17 14 8a d7 5c 32 9b d2  |..r.~.v.....\2..|
-00000270  c6 45 24 d5 d0 ea a4 c6  b5 6e 63 fc c7 12 0c a7  |.E$......nc.....|
-00000280  0a 73 70 89 ce 3d 1f aa  d5 ad ba bc 16 e8 15 80  |.sp..=..........|
-00000290  14 16 84 f6 06 38 23 b7  21 ec 27 50 a8 76 cf 0c  |.....8#.!.'P.v..|
-000002a0  4f 58 f7 57 7f b3 bd 55  0c f4 53 6e 9f f4 f2 12  |OX.W...U..Sn....|
-000002b0  5b c4 e7 68 9c 17 8b 76  88 1e 42 1b 32 e0 81 4d  |[..h...v..B.2..M|
-000002c0  ce 16 73 59 74 bd 56 be  fd fe 42 21 07 bd f4 e9  |..sYt.V...B!....|
-000002d0  ff 83 f3 97 a8 9e d4 c6  3c 6f 43 9d 0b 3c dc 35  |........<oC..<.5|
-000002e0  29 e4 bd b1 75 a4 70 30  8d bd fa 25 74 6c 11 ea  |)...u.p0...%tl..|
-000002f0  44 38 b5 8f f9 7a 71 c6  f8 ea c7 2c 23 d2 29 6d  |D8...zq....,#.)m|
-00000300  dc 8f e5 f7 c6 80 3b 8d  47 da 19 da 28 26 26 e6  |......;.G...(&&.|
-00000310  0f 83 d5 e9 33 42 0b 21  f4 1c 48 c0 19 ed e6 84  |....3B.!..H.....|
-00000320  17 03 03 00 99 d6 56 fb  52 63 57 c0 61 ec 30 04  |......V.RcW.a.0.|
-00000330  0a ee 10 39 7b e4 6a 38  8b 29 9a 6c 40 88 1d a1  |...9{.j8.).l@...|
-00000340  8b 53 2b fe 47 66 75 70  5b 03 33 fc ca e6 4f 8d  |.S+.Gfup[.3...O.|
-00000350  f1 40 63 c2 24 97 b4 c8  dd b1 20 27 e0 28 03 7a  |.@c.$..... '.(.z|
-00000360  f1 cd b3 df 8a 93 39 fa  b9 f9 0e 62 4c 47 24 69  |......9....bLG$i|
-00000370  9a f3 a5 7b 0d 14 33 00  c3 ab ae 4a 46 c2 40 42  |...{..3....JF.@B|
-00000380  d7 36 c1 74 7a c6 1a 42  d2 e0 fe e6 4b 5c 96 1a  |.6.tz..B....K\..|
-00000390  24 05 13 2c ad aa 25 02  ae 1b 3a 87 a7 60 1c d4  |$..,..%...:..`..|
-000003a0  98 53 ee 33 e9 36 37 d0  97 c2 e9 2d b9 a0 ac 4f  |.S.3.67....-...O|
-000003b0  c8 82 d8 a4 28 2e e4 db  a1 8f 71 cb ee 28 17 03  |....(.....q..(..|
-000003c0  03 00 35 5d 41 7c b0 af  b5 49 e8 dc 8a 7f c8 1f  |..5]A|...I......|
-000003d0  af 70 8b c4 35 7b 7b 57  3a 49 f2 ef 75 4c 27 39  |.p..5{{W:I..uL'9|
-000003e0  bf a6 45 fd 9c 64 b2 6e  7c c0 d3 c0 c7 a6 25 2f  |..E..d.n|.....%/|
-000003f0  f7 48 6d 7c a4 33 ad 61                           |.Hm|.3.a|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 60  |..+.....3.$... `|
+00000060  96 62 c2 30 4e ae b6 89  f2 06 e0 4e 8e 32 27 04  |.b.0N......N.2'.|
+00000070  b5 74 80 d8 c3 f5 76 7d  0e 0e e1 8d bc 2c 2c 14  |.t....v}.....,,.|
+00000080  03 03 00 01 01 17 03 03  00 24 45 c7 50 3e a9 63  |.........$E.P>.c|
+00000090  24 0b e9 80 3f 59 bb be  23 8a 5d 46 eb ee 17 9c  |$...?Y..#.]F....|
+000000a0  70 6f 52 1f 18 f3 9f 72  d6 35 44 55 91 d2 17 03  |poR....r.5DU....|
+000000b0  03 02 6d c2 c0 1f 53 2a  0c 3c 7f 08 c3 cb 53 4e  |..m...S*.<....SN|
+000000c0  b2 f5 b3 2d a5 10 e1 97  00 89 67 db 4e df ad 75  |...-......g.N..u|
+000000d0  94 b4 56 c4 8a a3 49 41  43 a1 3f aa 9b 8e e1 8d  |..V...IAC.?.....|
+000000e0  4c 9c 36 f6 80 da 4e 7f  00 10 c0 81 3e 45 1b a0  |L.6...N.....>E..|
+000000f0  b7 7f 2c bd eb 2a 8b c4  e6 fa c8 b3 59 28 f6 b8  |..,..*......Y(..|
+00000100  0a 93 cb b3 bf 28 e7 1a  ae a0 f5 ff 3a 42 f5 64  |.....(......:B.d|
+00000110  92 2c dd c2 24 77 2f a6  7e 23 63 3f 24 16 b3 d5  |.,..$w/.~#c?$...|
+00000120  b7 df 3f 30 23 a4 aa c9  14 78 6c f2 82 45 52 df  |..?0#....xl..ER.|
+00000130  cf a1 1d 35 fd 2a 30 89  14 38 5a 23 b1 63 2c c1  |...5.*0..8Z#.c,.|
+00000140  6d 6b 07 d0 41 38 4f 4c  87 d3 bd f1 ec ed 29 52  |mk..A8OL......)R|
+00000150  3d c7 74 3d e9 d3 ce 47  1c 24 d5 78 19 c9 5e 01  |=.t=...G.$.x..^.|
+00000160  66 a0 f1 8f ea a6 c1 e4  b4 e0 c2 2e d7 d6 64 36  |f.............d6|
+00000170  c9 bc d1 27 33 6f 26 a8  c6 aa 0d bc ae f9 2e bc  |...'3o&.........|
+00000180  f1 a7 82 42 09 83 62 88  c0 9f 20 95 a9 38 50 b4  |...B..b... ..8P.|
+00000190  55 d6 e9 f4 c6 a1 e6 67  a9 5f e4 15 97 44 13 ef  |U......g._...D..|
+000001a0  d3 50 8b 61 38 5e 89 75  b1 cf 6a 6f 0c c5 26 13  |.P.a8^.u..jo..&.|
+000001b0  2c 5a 26 c9 81 98 88 cd  ec 8c 2c 99 a0 ff 55 8f  |,Z&.......,...U.|
+000001c0  3f 9b c3 3b 52 d0 a3 3a  f9 b8 f0 17 81 53 00 f3  |?..;R..:.....S..|
+000001d0  ef 72 b3 4e b9 65 28 8f  a2 48 dc dd 6b 16 61 c3  |.r.N.e(..H..k.a.|
+000001e0  4e 0e c0 1c ac 8c 40 28  27 63 66 c7 74 40 8d 93  |N.....@('cf.t@..|
+000001f0  71 e9 f6 3f d8 8d 5d c6  28 11 4f ac 55 6f 80 1b  |q..?..].(.O.Uo..|
+00000200  2e 84 05 94 e0 4f e7 63  62 65 c7 52 99 49 2f 5d  |.....O.cbe.R.I/]|
+00000210  b4 99 d3 c3 fa b9 f5 83  aa 28 2e 9d ce af 72 7f  |.........(....r.|
+00000220  57 ea 81 f3 bf b5 d7 93  3a 1f a0 83 4d 8a 91 85  |W.......:...M...|
+00000230  fe b7 a1 b3 cb 1d b1 85  9b bb 36 1b 12 9f ed 13  |..........6.....|
+00000240  09 55 31 bd ee 61 06 57  b4 07 4d c6 1e fa b9 7f  |.U1..a.W..M.....|
+00000250  c7 b6 60 70 92 b7 9a ff  80 7d da 7f 2a 62 89 be  |..`p.....}..*b..|
+00000260  79 43 d3 ae 9c f1 00 6d  68 6c a3 f6 48 6e e0 48  |yC.....mhl..Hn.H|
+00000270  97 0f 5c 44 43 9f a8 88  27 96 fc 53 a0 e1 f2 7a  |..\DC...'..S...z|
+00000280  a6 a7 d9 96 2e 3d c4 e0  d9 18 79 ec 83 c2 9b da  |.....=....y.....|
+00000290  0b d4 8b 87 c5 98 f5 8b  e7 e3 d1 bd 2b 2b 42 e2  |............++B.|
+000002a0  4b 3e 64 88 4b 72 d0 35  cc c3 e6 68 c6 f6 4f 23  |K>d.Kr.5...h..O#|
+000002b0  39 a7 94 8d f3 e6 bd cd  d5 e9 8c 53 83 a7 87 09  |9..........S....|
+000002c0  15 fe ea eb 2e 56 da 6b  d9 5b b7 b1 c5 c4 ba 65  |.....V.k.[.....e|
+000002d0  39 89 16 f5 f6 4e e6 3a  63 34 1b 5d f5 fa 6b 8d  |9....N.:c4.]..k.|
+000002e0  c3 49 07 88 12 ca 18 c5  50 da 74 44 c0 c0 33 bd  |.I......P.tD..3.|
+000002f0  2e 45 94 af e1 40 90 00  11 2d 08 7b fc e4 3b f0  |.E...@...-.{..;.|
+00000300  94 fd 5a 0c 3a f9 76 df  3b 5e a3 0d 0f e7 2d df  |..Z.:.v.;^....-.|
+00000310  fd e9 ce 45 5a 13 36 a6  18 ae 46 30 00 fc d5 e3  |...EZ.6...F0....|
+00000320  17 03 03 00 99 0e 35 b6  91 ad cd a6 62 6e 79 12  |......5.....bny.|
+00000330  53 d5 f0 78 72 c5 dd 94  00 e3 75 2c 11 a3 72 f6  |S..xr.....u,..r.|
+00000340  b7 b3 5e d9 51 79 d5 a9  1e 21 2f df 0d 53 9a c8  |..^.Qy...!/..S..|
+00000350  43 a9 58 e2 a9 3d 9a b4  b4 72 bb 62 65 4b 83 f8  |C.X..=...r.beK..|
+00000360  cd 1b 58 e0 69 d9 87 3b  8d 05 42 e1 22 23 e9 5b  |..X.i..;..B."#.[|
+00000370  3a 5a 38 17 17 fb 3a 56  de fc 56 f8 77 12 31 4a  |:Z8...:V..V.w.1J|
+00000380  c5 38 ec 69 72 54 e5 63  2a a0 1e b4 7d 86 43 29  |.8.irT.c*...}.C)|
+00000390  21 ba 56 c2 d9 1b 9f a4  c1 02 f3 83 c1 9a 56 69  |!.V...........Vi|
+000003a0  5c 9e 5f ae 94 9d 6f 03  ec 75 7a 19 98 cd a9 dd  |\._...o..uz.....|
+000003b0  4a 01 41 72 2e 60 9f ca  4c d2 27 d9 0f 4f 17 03  |J.Ar.`..L.'..O..|
+000003c0  03 00 35 5d 61 3c 07 70  2f 35 ba d0 93 44 16 bd  |..5]a<.p/5...D..|
+000003d0  73 4b a0 fb 05 52 6a cc  5a 2e f2 94 d6 77 98 03  |sK...Rj.Z....w..|
+000003e0  c3 2e 8e a9 d1 38 14 d2  cd e6 e3 b6 ad ec d6 a0  |.....8..........|
+000003f0  cf b0 58 5f 8f d3 43 4b                           |..X_..CK|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 00 35 3e e7 50 e1 d1  |..........5>.P..|
-00000010  4d 9f 84 fe ca 83 c4 3b  a6 86 45 c2 7e e7 af 00  |M......;..E.~...|
-00000020  db e6 23 3c 06 b8 a3 1e  36 2e ab 45 7e d8 07 8c  |..#<....6..E~...|
-00000030  66 bf 5a 0f ff e6 3f 09  a4 d3 cf 74 1c d6 cf c7  |f.Z...?....t....|
-00000040  17 03 03 00 17 4c db af  a7 f3 73 b3 84 b9 a7 d1  |.....L....s.....|
-00000050  1c 2f cb 27 d8 ba 2c c6  84 48 88 18 17 03 03 00  |./.'..,..H......|
-00000060  13 a3 41 6f fb da f5 5a  4d 85 0c e0 ff 3a fb 91  |..Ao...ZM....:..|
-00000070  e2 5e ab 96                                       |.^..|
+00000000  14 03 03 00 01 01 17 03  03 00 35 3d 0a fd 33 39  |..........5=..39|
+00000010  b6 94 43 53 ae ee 3f 4e  c6 2d a2 3a f0 ef 94 7d  |..CS..?N.-.:...}|
+00000020  32 0a b6 90 cd a1 6f 29  88 ff 3c 91 c1 e5 e5 ae  |2.....o)..<.....|
+00000030  b7 a0 0b b3 c0 e6 37 9d  06 8b d8 ae 06 c0 0e 7b  |......7........{|
+00000040  17 03 03 00 17 c2 a1 82  db df fa 54 28 79 a0 0c  |...........T(y..|
+00000050  97 8c 82 ee 22 c9 b9 35  32 7a 21 4b 17 03 03 00  |...."..52z!K....|
+00000060  13 87 2b f8 38 81 df fa  e5 2e ff e2 d2 51 3e bc  |..+.8........Q>.|
+00000070  dd d3 e8 62                                       |...b|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-CHACHA20-SHA256 b/src/crypto/tls/testdata/Client-TLSv13-CHACHA20-SHA256
index 6d7b508..69749f0 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-CHACHA20-SHA256
+++ b/src/crypto/tls/testdata/Client-TLSv13-CHACHA20-SHA256
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,75 +16,75 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 43 b1 e8 d9 c3  |....z...v..C....|
-00000010  22 a0 a3 08 df 7f 37 34  7a fe 7a 47 98 ee ed 51  |".....74z.zG...Q|
-00000020  c2 ae 5c c6 b1 43 3d ff  f7 91 68 20 00 00 00 00  |..\..C=...h ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 39 b2 74 80 d8  |....z...v..9.t..|
+00000010  49 72 79 63 9b 7b da d7  cf b4 29 20 f8 80 ed d9  |Iryc.{....) ....|
+00000020  66 09 65 22 b6 27 16 c5  a7 6f 8b 20 00 00 00 00  |f.e".'...o. ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 63  |..+.....3.$... c|
-00000060  0f 66 ec 2d fa 67 d4 eb  94 47 8d 88 0b eb ed ec  |.f.-.g...G......|
-00000070  5b ac 22 f7 46 85 c5 1c  2b 5e e8 57 e2 d3 6f 14  |[.".F...+^.W..o.|
-00000080  03 03 00 01 01 17 03 03  00 17 d0 f8 1f 06 59 8d  |..............Y.|
-00000090  a0 40 21 8f 3e 36 3b 1d  6a 6e f7 77 44 fb b3 8e  |.@!.>6;.jn.wD...|
-000000a0  e2 17 03 03 02 6d 22 6b  63 ae 47 fd 66 f9 95 f6  |.....m"kc.G.f...|
-000000b0  63 ea e8 16 61 a3 64 82  39 82 76 1c 2c 04 9b 29  |c...a.d.9.v.,..)|
-000000c0  0f 8a ff 77 9b e6 2c ce  04 09 5f 91 f3 b6 2e 8d  |...w..,..._.....|
-000000d0  be 42 94 7e 5a 28 4b 9f  e9 7b 38 0a 3c de 90 77  |.B.~Z(K..{8.<..w|
-000000e0  c1 bf 97 bf 35 6c 77 98  4b 38 b4 8d 7f 1f 4b c0  |....5lw.K8....K.|
-000000f0  23 c5 73 08 90 fa 21 5c  cd cb 84 5b 0e 89 86 ce  |#.s...!\...[....|
-00000100  83 78 d5 1c 2b b9 b1 24  45 ad ab 9c 68 9f c2 28  |.x..+..$E...h..(|
-00000110  40 d6 c2 ac a2 0c 86 cd  75 92 43 d5 22 3f 61 9d  |@.......u.C."?a.|
-00000120  e8 56 b8 7c 71 db 25 cc  2e 74 52 74 da 6b d4 a1  |.V.|q.%..tRt.k..|
-00000130  2c 32 d2 d8 9c 74 41 9d  78 98 94 3b 87 99 8e 17  |,2...tA.x..;....|
-00000140  df df d6 c3 6d ef 58 13  5c 1e 20 2d ed 77 bd 5c  |....m.X.\. -.w.\|
-00000150  d6 5c 9a 6d 0f 19 77 e1  4f 79 b0 ed 9d 0b f5 e8  |.\.m..w.Oy......|
-00000160  42 d0 f4 90 88 97 a9 84  af 92 3c 41 fe fd 67 6e  |B.........<A..gn|
-00000170  33 77 8e 02 83 b4 6f c0  14 d2 ee 38 79 ca 45 61  |3w....o....8y.Ea|
-00000180  59 05 3b 76 4b ef 55 b9  18 43 9f c4 42 02 31 8e  |Y.;vK.U..C..B.1.|
-00000190  88 c1 b6 0b 5d c4 20 59  91 57 f3 81 b9 d0 ec 25  |....]. Y.W.....%|
-000001a0  26 72 37 e0 e0 c8 34 83  58 fe 15 bd aa 4d 49 f8  |&r7...4.X....MI.|
-000001b0  ba 8f 1d 8d 37 9c 18 88  cd 69 23 00 93 0f 64 e0  |....7....i#...d.|
-000001c0  ed 0d a7 a0 fc bd f3 7d  0b b0 50 6b cd e6 25 b8  |.......}..Pk..%.|
-000001d0  50 3a bf 37 d7 18 60 a7  de ba c7 ff b7 26 8a 20  |P:.7..`......&. |
-000001e0  ad d3 f9 5a 5f 61 37 2f  b0 9b d6 2a 4c 39 08 34  |...Z_a7/...*L9.4|
-000001f0  31 15 19 1e 72 d3 fc 72  63 0e d5 71 04 82 b3 80  |1...r..rc..q....|
-00000200  ec aa 51 0f 73 5f 2c dd  42 fd 40 b8 e3 1d 9e 31  |..Q.s_,.B.@....1|
-00000210  13 01 3b 6b 88 f2 52 17  fa 0b 9d 45 1e f2 f0 c1  |..;k..R....E....|
-00000220  5b 3f 14 23 41 e7 a2 2e  fa e4 9b 01 9b a4 99 43  |[?.#A..........C|
-00000230  32 85 fc c9 30 2a 5d ca  2a fa c5 7f 81 89 31 02  |2...0*].*.....1.|
-00000240  0a c6 89 f0 98 1b 92 08  96 d0 90 c7 18 b0 d4 e9  |................|
-00000250  5d 29 71 3b c6 2f c5 ff  2c be db f8 ef 56 d6 e0  |])q;./..,....V..|
-00000260  9b a6 21 b1 92 b1 58 26  e9 e2 3b 97 1b 95 b2 ba  |..!...X&..;.....|
-00000270  62 66 a5 df a1 a8 82 25  1e ae 85 98 94 d7 96 c5  |bf.....%........|
-00000280  3b 30 4c bd 04 23 45 3d  86 c9 7e 0e 47 5b 5f 14  |;0L..#E=..~.G[_.|
-00000290  b5 c5 29 31 1e cd a4 e0  6a b2 78 51 f0 7b b2 21  |..)1....j.xQ.{.!|
-000002a0  1f 10 0d 0d 7f 01 f1 06  4a 87 7d 4a 90 63 59 f3  |........J.}J.cY.|
-000002b0  6d 16 0f 07 9e 00 3a d2  c7 01 37 cc 39 6e 07 6e  |m.....:...7.9n.n|
-000002c0  9e 64 df 47 65 04 4c 72  59 ad 3b 3e 52 8e e4 b6  |.d.Ge.LrY.;>R...|
-000002d0  fc ba 9c f0 82 13 ba 25  11 c7 5d 38 00 cf 83 14  |.......%..]8....|
-000002e0  30 a9 72 48 d1 e8 4e 1b  ed 04 ed cf b7 5b 2e 72  |0.rH..N......[.r|
-000002f0  1c a2 03 ae 60 54 d6 cf  2f fb 11 a3 b1 8d d6 47  |....`T../......G|
-00000300  e8 9f 96 08 90 ae 3c 3c  c0 8c d8 c4 ef 30 18 ea  |......<<.....0..|
-00000310  2a 1a 15 17 03 03 00 99  85 b3 e4 18 6f 8d 34 c7  |*...........o.4.|
-00000320  3d 66 49 b8 f6 f5 aa 7a  e1 ca ba cb 48 53 15 bb  |=fI....z....HS..|
-00000330  e9 ec 74 91 c3 b5 d3 6b  bc 84 81 d8 e1 a4 31 62  |..t....k......1b|
-00000340  d5 19 6d 2f 15 4c f3 8a  3b ec 41 12 89 be d3 cc  |..m/.L..;.A.....|
-00000350  ab 08 59 a7 79 5d 77 14  ce b1 98 b4 ce 71 7b ad  |..Y.y]w......q{.|
-00000360  ba 41 3a 7f 9a f8 23 5c  c6 fb b5 7b cc eb 0e 7a  |.A:...#\...{...z|
-00000370  ee af 3d ff 4d 03 ba c2  2a af ac fd b5 e8 5b 43  |..=.M...*.....[C|
-00000380  3e 37 ef 84 3d 66 af 3c  8e 1d 0d 36 bd df 25 dc  |>7..=f.<...6..%.|
-00000390  74 89 9c e6 da 18 c4 c8  b5 6c 3c 4c a6 ac 10 28  |t........l<L...(|
-000003a0  67 c0 a7 02 6c d4 8c a1  ca 66 ec 30 65 a6 af f7  |g...l....f.0e...|
-000003b0  e3 17 03 03 00 35 46 33  9b 78 59 93 b5 3d 99 22  |.....5F3.xY..=."|
-000003c0  56 3b 26 82 9c d4 08 36  5a 07 c6 d7 5b 4f c8 d9  |V;&....6Z...[O..|
-000003d0  32 8b cd f1 e7 81 58 a8  98 b6 61 f6 9e 75 0c 52  |2.....X...a..u.R|
-000003e0  5a a1 e8 b1 97 8c 94 52  82 5e e8                 |Z......R.^.|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 42  |..+.....3.$... B|
+00000060  80 fb 4a d3 49 53 a5 9f  f6 da ca 64 f8 5d 2c f5  |..J.IS.....d.],.|
+00000070  45 4d f1 a5 ec c3 c6 fc  d2 ff 56 b1 63 53 1a 14  |EM........V.cS..|
+00000080  03 03 00 01 01 17 03 03  00 17 f8 d8 e1 1a e0 c8  |................|
+00000090  75 f9 40 90 da 16 a0 41  4f 8c 23 e7 47 43 89 cf  |u.@....AO.#.GC..|
+000000a0  d4 17 03 03 02 6d d6 23  1d c6 c0 d4 5e a3 fe 2b  |.....m.#....^..+|
+000000b0  03 04 6c 88 d1 4a ac 9b  dd 90 e5 18 c5 35 9c 4a  |..l..J.......5.J|
+000000c0  f3 c4 64 e2 c2 40 62 fb  68 b3 22 37 9f f4 eb ae  |..d..@b.h."7....|
+000000d0  45 d9 a8 be f4 1e 89 16  88 b5 10 e3 5c 2e 42 15  |E...........\.B.|
+000000e0  34 24 f3 bd dd 73 6d 6b  d1 db 3e 69 b0 0a 54 e6  |4$...smk..>i..T.|
+000000f0  b7 2c b7 80 86 93 91 d5  26 02 77 bf 10 38 ee 40  |.,......&.w..8.@|
+00000100  22 4d 3f 67 02 6b f8 1c  4a ad 2b c7 f6 19 d4 36  |"M?g.k..J.+....6|
+00000110  9b ff c4 08 73 e1 48 0a  a6 e8 80 3b 88 8a c2 e8  |....s.H....;....|
+00000120  c6 4a ae da a1 4f 3b 9e  fb 80 3b 78 ca 80 42 00  |.J...O;...;x..B.|
+00000130  a4 5c 9d a0 6c 63 a7 66  e6 26 b7 14 d8 8b ba 1a  |.\..lc.f.&......|
+00000140  4b 13 81 3c e4 76 4e ac  6c 2f b4 71 e9 dc c4 c8  |K..<.vN.l/.q....|
+00000150  ef f0 61 22 f4 6b 83 ae  d8 d0 a7 c6 d9 ea 95 85  |..a".k..........|
+00000160  77 90 0f 22 a0 50 cb ff  50 a5 98 ee de e4 89 f3  |w..".P..P.......|
+00000170  20 f2 63 a2 45 3a 48 33  d5 b9 ff 5e f8 7d c5 2d  | .c.E:H3...^.}.-|
+00000180  b9 9c b2 65 bf d5 13 36  46 a5 96 9f f4 de 7c 1c  |...e...6F.....|.|
+00000190  78 3f 1a 0a 62 14 13 8e  55 7e cd 47 87 1b 7e a8  |x?..b...U~.G..~.|
+000001a0  7f 03 ec 1c d3 72 eb e5  94 d9 9d 95 d6 f5 ad 2c  |.....r.........,|
+000001b0  e9 7d 0f 2c ea 7b 1e 8e  d7 b4 f1 5d 12 be d7 cf  |.}.,.{.....]....|
+000001c0  b7 43 89 65 e9 04 0e f8  b4 b4 4d 9c 9c 42 3c 50  |.C.e......M..B<P|
+000001d0  a7 91 d0 7f c0 de fb 99  08 ce 5c fd 67 3a cb 1a  |..........\.g:..|
+000001e0  d3 1a 4c a2 2e 7d 73 01  2b 5f bb a2 86 7d 0e e0  |..L..}s.+_...}..|
+000001f0  a1 c9 06 c0 4a 0a f6 c6  c4 b5 53 51 3e 2f f4 60  |....J.....SQ>/.`|
+00000200  1d 41 55 9d c4 88 f3 76  4f 92 b5 03 98 23 6b c4  |.AU....vO....#k.|
+00000210  c3 62 bd 12 dd 3a bc 37  d0 18 64 c6 e1 2c cb 62  |.b...:.7..d..,.b|
+00000220  f6 d3 24 35 47 e7 cf 15  d3 53 9d ac 3f 97 48 c1  |..$5G....S..?.H.|
+00000230  b8 d3 a3 2c 9f cd 2b 72  bc bd a6 8a b1 54 48 7b  |...,..+r.....TH{|
+00000240  e0 b7 a2 2e 46 04 cc e5  29 1d 73 c7 67 f8 f0 d8  |....F...).s.g...|
+00000250  e0 88 f0 7b 11 ff e1 1d  95 6c 85 c4 08 72 3e 94  |...{.....l...r>.|
+00000260  92 4b 8a 58 62 04 10 83  7c 5e 65 20 a7 5d 6d 16  |.K.Xb...|^e .]m.|
+00000270  30 64 fc aa 7f 8f 06 ed  4e 3c 86 c8 10 92 fb 0d  |0d......N<......|
+00000280  7b 81 10 07 cf 30 7f 6b  11 63 60 2a 61 92 cb 74  |{....0.k.c`*a..t|
+00000290  82 a4 04 cf 23 43 21 55  45 2a 29 93 42 0f 0c f6  |....#C!UE*).B...|
+000002a0  9b 14 b5 96 09 25 1b bc  b0 7b 72 e2 6f b8 55 74  |.....%...{r.o.Ut|
+000002b0  00 bb 1c 7c b1 9b 58 63  97 bb 6d c5 fb a4 da 24  |...|..Xc..m....$|
+000002c0  1e b2 97 18 75 ab 8b a2  77 50 38 4d f8 a0 39 58  |....u...wP8M..9X|
+000002d0  8c 2d 3e ba 27 03 e9 51  87 0a 95 e0 08 40 5d e6  |.->.'..Q.....@].|
+000002e0  6a dd 10 1d 6d 8c 32 88  a8 32 ee dd 44 9c 9b b0  |j...m.2..2..D...|
+000002f0  6f f5 4b 08 60 9d 83 1e  ab 83 c0 92 10 c7 aa 90  |o.K.`...........|
+00000300  d2 b2 61 5e 12 b5 e8 ea  a7 68 59 17 a4 f4 15 f7  |..a^.....hY.....|
+00000310  dc 10 81 17 03 03 00 99  8a 61 79 8f 33 51 7b a9  |.........ay.3Q{.|
+00000320  ce 3f 82 2b bb da 40 2e  73 c8 d9 6e 7d 72 ba 94  |.?.+..@.s..n}r..|
+00000330  7d ad fb b7 ba 9c 74 00  0b c9 1d b6 8d 54 b9 48  |}.....t......T.H|
+00000340  eb 49 78 c3 1a 75 b8 16  22 5d 50 f5 4a 81 59 d3  |.Ix..u.."]P.J.Y.|
+00000350  38 79 38 c1 35 11 55 69  6b d2 86 3c 0f 12 26 57  |8y8.5.Uik..<..&W|
+00000360  f5 84 d7 dd 74 61 6f b8  08 66 e9 3c f7 43 29 a5  |....tao..f.<.C).|
+00000370  94 9e ab af 68 04 c1 6a  ae 9d 12 2d 57 e9 ff 30  |....h..j...-W..0|
+00000380  7d 80 35 65 cc df c8 65  0b a1 f9 6d 6b a5 0b df  |}.5e...e...mk...|
+00000390  0c 1a 04 0a 00 8f ac 2b  29 60 92 4e 91 d3 42 25  |.......+)`.N..B%|
+000003a0  b4 a5 0a 1a 5f 83 ec 9a  f0 0a 2c 6d 65 00 24 d3  |...._.....,me.$.|
+000003b0  e1 17 03 03 00 35 e4 72  aa 9e 6c a8 93 7b e4 49  |.....5.r..l..{.I|
+000003c0  1e 23 7c 50 18 59 00 08  3b f1 c1 5f 20 ba 51 56  |.#|P.Y..;.._ .QV|
+000003d0  fe bb 93 99 52 e6 5e 6d  26 cc 60 11 c2 a1 c8 18  |....R.^m&.`.....|
+000003e0  2e 72 bd ee 36 ca 41 25  73 f2 30                 |.r..6.A%s.0|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 00 35 55 88 37 f3 ee  |..........5U.7..|
-00000010  c5 1b 20 ac fe bc a3 f8  c9 59 3f 5f c0 81 40 8f  |.. ......Y?_..@.|
-00000020  1e a9 44 c8 10 16 69 8a  76 45 17 51 06 9e f0 55  |..D...i.vE.Q...U|
-00000030  a2 f2 56 98 7d a1 4d 95  5a c3 1f 51 cf 31 20 ca  |..V.}.M.Z..Q.1 .|
-00000040  17 03 03 00 17 81 2a 8e  32 29 ec 9b 92 c3 fd 98  |......*.2)......|
-00000050  64 aa 47 2a a5 0c d6 77  7f b1 8f 12 17 03 03 00  |d.G*...w........|
-00000060  13 60 8c fb 98 e1 03 b6  20 c8 45 4e d9 4b a8 17  |.`...... .EN.K..|
-00000070  10 79 5f b6                                       |.y_.|
+00000000  14 03 03 00 01 01 17 03  03 00 35 b6 c3 b9 b1 52  |..........5....R|
+00000010  88 d2 78 2b ec 1c 63 e8  d5 08 0e 4e d6 51 b9 02  |..x+..c....N.Q..|
+00000020  ba cc a8 ca b6 da 45 a9  7c 1a 18 39 47 84 db 34  |......E.|..9G..4|
+00000030  d6 05 6f e5 16 19 57 6f  65 0b 7a e7 37 b5 d3 28  |..o...Woe.z.7..(|
+00000040  17 03 03 00 17 dc b8 e2  1c aa b8 f5 cb b6 fd ba  |................|
+00000050  29 34 73 bb c6 e0 3a fc  3e fb d3 01 17 03 03 00  |)4s...:.>.......|
+00000060  13 eb 66 ab 47 38 1b 01  96 6c 59 46 c2 ad bf 2d  |..f.G8...lYF...-|
+00000070  36 22 97 19                                       |6"..|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA
index c8e95c8..251e339 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,124 +16,124 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 98 9a 92 3f c6  |....z...v.....?.|
-00000010  67 f5 96 5b 2f 5e 70 89  2d f6 1e ce 6f 6a e5 91  |g..[/^p.-...oj..|
-00000020  4b 4b 6f 98 cc f7 78 4a  b1 54 4a 20 00 00 00 00  |KKo...xJ.TJ ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 ce 38 98 c9 b7  |....z...v...8...|
+00000010  f8 67 af 0d 29 52 88 a4  d0 c2 a8 10 c4 8e 80 26  |.g..)R.........&|
+00000020  43 84 0e 60 06 ce f0 b7  b1 cd 29 20 00 00 00 00  |C..`......) ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 58  |..+.....3.$... X|
-00000060  96 37 c3 41 35 73 13 21  fc 31 e3 09 33 48 15 be  |.7.A5s.!.1..3H..|
-00000070  31 fb 57 61 b2 c9 60 31  2d 68 83 d5 7c d1 3a 14  |1.Wa..`1-h..|.:.|
-00000080  03 03 00 01 01 17 03 03  00 17 1d ce 7d b7 ca e3  |............}...|
-00000090  10 82 cb f6 1d 52 61 41  29 57 e3 7e e5 88 5c 47  |.....RaA)W.~..\G|
-000000a0  16 17 03 03 00 42 1b 49  e1 4a d7 73 57 cd e9 b7  |.....B.I.J.sW...|
-000000b0  e2 47 d3 74 21 6a 14 1d  1b 8d f5 aa 4c 1b f8 61  |.G.t!j......L..a|
-000000c0  8c 3a e4 2e 9d ff 3f 7d  b2 4d 79 6e 1d 02 05 ce  |.:....?}.Myn....|
-000000d0  c3 ad e6 f9 2b 2b dd 75  3b 6f 3e 0b 29 07 09 74  |....++.u;o>.)..t|
-000000e0  d1 37 68 9b 8a b6 8d 2b  17 03 03 02 6d d1 1b 9f  |.7h....+....m...|
-000000f0  75 ba cf 2d 10 4b f0 4e  09 58 fa ff 06 e8 c9 d5  |u..-.K.N.X......|
-00000100  a0 51 c8 d4 6f b2 c5 c1  d5 f3 ff 12 1f 43 d8 74  |.Q..o........C.t|
-00000110  33 d9 9b e5 f3 34 26 0e  89 dc 00 54 67 17 d2 f3  |3....4&....Tg...|
-00000120  c9 9e be f8 4c 77 8a 63  b1 64 5a b4 d7 57 d2 89  |....Lw.c.dZ..W..|
-00000130  ce 68 d1 f7 93 01 6c 36  b7 c9 4d 50 d0 4b df 5e  |.h....l6..MP.K.^|
-00000140  8a bb 6c d9 54 57 9b b9  c9 ec d8 49 c7 51 3c e5  |..l.TW.....I.Q<.|
-00000150  7b fb 48 0f fd 1b dd 0f  57 d3 a8 ee f6 51 ba 78  |{.H.....W....Q.x|
-00000160  c0 60 f1 d9 c1 d2 65 b4  a7 98 99 fb 64 83 4c 2c  |.`....e.....d.L,|
-00000170  a6 e9 19 ef 0e 88 68 f8  21 a4 2b bd 95 e9 52 d5  |......h.!.+...R.|
-00000180  fb 12 d3 36 06 a2 13 f9  e2 35 6a 06 dd 49 d9 42  |...6.....5j..I.B|
-00000190  89 d9 f0 24 5c 36 b8 6d  95 35 21 b3 9c 3b ee 08  |...$\6.m.5!..;..|
-000001a0  06 06 4d aa 74 eb fc 1b  c1 fd cf 07 24 74 44 2d  |..M.t.......$tD-|
-000001b0  54 d5 c5 d3 4e c4 eb 09  6e 90 8f 3d c0 c5 1c 21  |T...N...n..=...!|
-000001c0  7c 32 1b bc 4b 85 2b f0  b0 f5 cd 61 3d dd 31 03  ||2..K.+....a=.1.|
-000001d0  5e e0 5e 06 1a 37 61 1a  58 fa ed e8 cf 0c 4f da  |^.^..7a.X.....O.|
-000001e0  73 69 42 3a f4 ed dc ad  e5 e7 9b fd 54 16 77 85  |siB:........T.w.|
-000001f0  ae 84 41 10 be 84 ad 28  ef e6 13 2a e9 9f 9f 2f  |..A....(...*.../|
-00000200  c5 d0 65 c6 f5 58 b3 39  9b 5e 07 ba 95 be 5e 75  |..e..X.9.^....^u|
-00000210  68 17 ba 9d 2a 69 6d b8  ed d4 4b 6a ce 30 b1 82  |h...*im...Kj.0..|
-00000220  ae ec 68 9a 26 13 6b 05  38 0f 38 c9 94 01 d0 0b  |..h.&.k.8.8.....|
-00000230  7b bb ca 70 86 6c e4 f1  eb 81 05 25 33 c0 3e e3  |{..p.l.....%3.>.|
-00000240  2a 25 8e 32 eb d5 03 c7  c4 d8 22 22 ef 99 5a a3  |*%.2......""..Z.|
-00000250  01 6a b5 65 9a 55 6e fb  84 83 aa 43 ae 4a 3e da  |.j.e.Un....C.J>.|
-00000260  40 7e 09 e1 3b 15 ad 33  66 5a 3d 30 62 72 86 54  |@~..;..3fZ=0br.T|
-00000270  cd a2 6a bf 82 61 17 87  84 c5 3f f3 1e 86 a2 b1  |..j..a....?.....|
-00000280  2c 1a f9 ba 8c a2 21 5b  93 b2 16 b4 81 ae 7d 98  |,.....![......}.|
-00000290  d6 db 0a 56 14 c9 f7 48  c1 c7 3c 7e 63 8e bc 50  |...V...H..<~c..P|
-000002a0  6a 64 e1 1d 04 ba d3 cc  6a 61 60 4b d2 97 d5 ba  |jd......ja`K....|
-000002b0  23 1a 69 76 86 db 96 39  04 f6 ec e9 96 79 6a 25  |#.iv...9.....yj%|
-000002c0  ff 39 dd 19 08 34 4d c3  f6 7c 91 f2 6b 3a e1 0f  |.9...4M..|..k:..|
-000002d0  66 6d 14 5d 82 21 0b e3  e0 c3 f1 a1 70 e1 2c bc  |fm.].!......p.,.|
-000002e0  fb 54 aa 85 3c a0 7c 9a  35 00 e2 a1 4f 83 3e f1  |.T..<.|.5...O.>.|
-000002f0  64 83 ab c5 e6 31 c7 00  eb 36 f1 bc 41 f3 eb d4  |d....1...6..A...|
-00000300  97 30 4d 7f d2 d1 e7 1a  9e a2 53 31 35 6a 16 d1  |.0M.......S15j..|
-00000310  65 be d7 d3 93 2a be d2  27 dc 1b 8c 09 16 30 d4  |e....*..'.....0.|
-00000320  cb eb e0 bb 42 50 ff 59  c3 81 81 36 88 09 c2 23  |....BP.Y...6...#|
-00000330  dc dd 80 63 bb 78 19 6b  6a 70 4b b5 17 bf ed 6c  |...c.x.kjpK....l|
-00000340  58 f1 15 a9 16 66 c8 45  f5 5f 99 05 b1 3b be e6  |X....f.E._...;..|
-00000350  66 d7 45 df 19 16 9d c7  dd 4d 17 03 03 00 99 38  |f.E......M.....8|
-00000360  70 9e 16 94 07 67 7c ce  90 67 99 46 5e d9 61 b5  |p....g|..g.F^.a.|
-00000370  9b b8 31 fc cc 80 a3 07  30 c9 f5 f9 90 fb e2 0d  |..1.....0.......|
-00000380  dc 93 ab de 38 25 83 f8  77 0c 94 53 75 68 c7 71  |....8%..w..Suh.q|
-00000390  72 6f 61 77 a7 d7 c7 ed  5c d3 08 18 9f 64 f4 6e  |roaw....\....d.n|
-000003a0  30 dc 05 b1 65 11 79 08  66 34 8c 06 99 a9 00 26  |0...e.y.f4.....&|
-000003b0  86 2c e4 b5 6d cf db b1  03 f0 d0 c5 c0 f5 50 04  |.,..m.........P.|
-000003c0  f7 27 97 3e 31 19 aa a8  58 c4 78 43 a9 e3 76 0d  |.'.>1...X.xC..v.|
-000003d0  98 88 20 07 11 4c d6 8a  66 31 72 2e ed 47 66 71  |.. ..L..f1r..Gfq|
-000003e0  9a 3e 9c 0d 1c 17 df ab  6a 52 b4 43 a6 c2 64 30  |.>......jR.C..d0|
-000003f0  45 08 b8 de 59 be 3a f9  17 03 03 00 35 94 9b 02  |E...Y.:.....5...|
-00000400  47 a6 e3 55 9f 95 8a 8d  35 3b bb 56 ec 10 ab dd  |G..U....5;.V....|
-00000410  a3 ca fe ad bf 25 90 76  c4 15 a0 c0 73 d5 96 96  |.....%.v....s...|
-00000420  44 bc ba e9 09 f5 8e e7  e7 7d db f2 e7 9f 99 d2  |D........}......|
-00000430  dc e7                                             |..|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 aa  |..+.....3.$... .|
+00000060  00 03 6d 16 04 54 48 55  4d f9 04 e8 29 ca 9c 5d  |..m..THUM...)..]|
+00000070  14 94 a2 7a 2e 0a 4e 75  12 2d 63 cf 19 81 21 14  |...z..Nu.-c...!.|
+00000080  03 03 00 01 01 17 03 03  00 17 7b 90 e1 af 77 ca  |..........{...w.|
+00000090  a1 3b a6 e0 9f ea 4b f6  3f 45 a0 78 1c fb af 51  |.;....K.?E.x...Q|
+000000a0  30 17 03 03 00 42 ff 27  8b 9c fd 65 d7 b1 d4 43  |0....B.'...e...C|
+000000b0  eb 8f c3 ca b4 57 be 35  35 75 35 cf 43 73 d6 14  |.....W.55u5.Cs..|
+000000c0  7e 2d b4 f8 31 60 1b 35  2a 38 91 32 40 8b f0 ab  |~-..1`.5*8.2@...|
+000000d0  a8 b0 dc 2b db b9 63 92  28 dc f2 c2 95 d3 4a 63  |...+..c.(.....Jc|
+000000e0  69 e7 58 0c e5 9c d5 22  17 03 03 02 6d 7c 70 9b  |i.X...."....m|p.|
+000000f0  e1 81 3a 0d 6e 7f 5c 30  2e 09 1d 82 ac 48 a6 7e  |..:.n.\0.....H.~|
+00000100  03 ce d0 ce e2 e8 9e 8b  2b ee af 1a b1 6a 3a 27  |........+....j:'|
+00000110  04 53 73 d2 d4 28 68 19  96 3a 3d 89 df 2c e3 2b  |.Ss..(h..:=..,.+|
+00000120  45 c8 5e 60 42 b0 4d f2  9c 8a 8d 83 f6 97 e0 b0  |E.^`B.M.........|
+00000130  02 39 37 46 2b 07 28 8b  e8 d8 c2 e3 ba 58 9b dc  |.97F+.(......X..|
+00000140  62 c4 e6 cb b4 97 f0 67  2b b3 40 4b 64 3e 73 3f  |b......g+.@Kd>s?|
+00000150  a1 1f 6e fe 7f ba af 7d  bd c4 7c 37 60 c0 94 d6  |..n....}..|7`...|
+00000160  bc 14 70 a9 95 a6 b7 88  9d 50 cf 9f 36 0c 38 c4  |..p......P..6.8.|
+00000170  97 ba ea 43 16 e8 fd 72  22 3c 09 4a 97 1c 97 70  |...C...r"<.J...p|
+00000180  88 6d d4 f3 9d b9 5a f3  67 f5 7b da 3e ed 1a 66  |.m....Z.g.{.>..f|
+00000190  4c 62 50 ff cd 92 08 d8  5c 2e 11 de ea 44 16 91  |LbP.....\....D..|
+000001a0  3e 44 d7 8c dd 2a b4 c7  2b 4d 40 a2 f9 7e 49 a9  |>D...*..+M@..~I.|
+000001b0  d8 51 a1 27 b3 34 75 59  04 04 cd 52 d6 37 34 e6  |.Q.'.4uY...R.74.|
+000001c0  41 32 36 45 c0 65 fb 5c  e2 21 77 7f 35 db 9d 34  |A26E.e.\.!w.5..4|
+000001d0  0d 6e 9d a7 9e 00 ec e3  3e 9c 50 50 13 5b ad b9  |.n......>.PP.[..|
+000001e0  b3 47 44 f8 9b 12 ab 50  7f a7 df 35 c5 d6 78 3c  |.GD....P...5..x<|
+000001f0  c1 04 41 db 99 18 cd 8c  05 3f 08 ae 2b 41 c9 46  |..A......?..+A.F|
+00000200  16 9a e3 a9 5b d3 9c 00  56 0e e2 d1 da 6d 6b 20  |....[...V....mk |
+00000210  65 1b 55 1f 4f b1 eb 94  c6 48 e3 50 d6 14 c5 62  |e.U.O....H.P...b|
+00000220  5e fc d2 cf df f4 68 90  c9 bb 80 54 f3 f3 a3 78  |^.....h....T...x|
+00000230  af 1f 6f ef e1 d5 64 24  04 e5 d4 59 bc 4d 7b a0  |..o...d$...Y.M{.|
+00000240  1a 23 e1 81 b7 c4 bb 52  86 f4 2a 85 d2 d0 7a ed  |.#.....R..*...z.|
+00000250  c0 5d 27 07 4b df 52 c4  ea c8 c9 9c f0 48 35 71  |.]'.K.R......H5q|
+00000260  bd 04 65 65 47 e3 21 88  ff 08 6c 6a f3 6c dd 81  |..eeG.!...lj.l..|
+00000270  3f 50 21 66 34 49 07 a0  e0 6d 80 54 77 8b 27 81  |?P!f4I...m.Tw.'.|
+00000280  4f b9 59 60 0a b0 c7 00  6a 7b 26 33 f6 5e ad 37  |O.Y`....j{&3.^.7|
+00000290  bf ea 87 e4 3c e7 b8 20  b0 89 88 ac 5a a4 af f7  |....<.. ....Z...|
+000002a0  23 3c 0a d0 ab 74 fc 49  d2 e5 51 a7 a5 4e 21 5f  |#<...t.I..Q..N!_|
+000002b0  90 9a 65 36 9f e1 e3 9e  3d 67 d6 93 f1 b8 f0 4b  |..e6....=g.....K|
+000002c0  c6 d8 ca 50 fb cc 92 ab  47 b5 8c 21 02 4a ee 42  |...P....G..!.J.B|
+000002d0  35 a3 52 41 04 94 19 cd  23 c6 33 b0 84 0d 88 97  |5.RA....#.3.....|
+000002e0  5a e0 3e 4c 6d 99 ec 6d  11 3f 19 e7 77 60 3b de  |Z.>Lm..m.?..w`;.|
+000002f0  6d 04 b8 ab bc 83 4f 51  a5 ba 56 56 d6 e3 ff 0e  |m.....OQ..VV....|
+00000300  d5 4b 75 29 6a f9 4b c6  ef fd 62 25 89 76 f1 fd  |.Ku)j.K...b%.v..|
+00000310  84 3f e9 93 63 cf eb 47  85 b1 aa a2 4c 94 6b 99  |.?..c..G....L.k.|
+00000320  98 6e 1a 19 85 0b 90 d2  9f 0f ec d4 36 1e 22 a0  |.n..........6.".|
+00000330  4e 7f a1 ae 90 15 68 8a  48 c5 06 01 aa b9 56 cb  |N.....h.H.....V.|
+00000340  e0 62 53 d8 96 56 61 1d  81 96 b8 66 ae 94 c8 5f  |.bS..Va....f..._|
+00000350  86 47 fe ca 27 8d 7f 8e  f8 74 17 03 03 00 99 ac  |.G..'....t......|
+00000360  2b 09 0b 44 a5 33 27 19  86 59 ca 75 5c df 59 fc  |+..D.3'..Y.u\.Y.|
+00000370  34 57 08 11 4f d8 1a c6  7c 76 d5 0a 36 91 f2 3a  |4W..O...|v..6..:|
+00000380  d1 96 58 64 29 3a d1 05  e3 cb 6f ea 92 4a f6 3b  |..Xd):....o..J.;|
+00000390  54 4c 16 41 99 6e 0f e9  c3 9a ac a3 59 ee fa c9  |TL.A.n......Y...|
+000003a0  4d 58 ae 23 58 58 b5 b5  d6 6a dd b4 0c 24 bf e1  |MX.#XX...j...$..|
+000003b0  d4 16 53 f2 2d e1 78 d0  ea 70 59 ac a3 e4 e4 6f  |..S.-.x..pY....o|
+000003c0  65 93 28 ad e1 64 83 11  05 42 a3 a0 11 d5 f2 af  |e.(..d...B......|
+000003d0  7e 03 93 80 82 48 e0 84  2e 1c 50 98 65 22 49 f1  |~....H....P.e"I.|
+000003e0  df 41 03 83 b2 5c 1c 56  cb b7 f3 72 04 d6 09 cf  |.A...\.V...r....|
+000003f0  f9 3a 5d e8 35 80 b6 a2  17 03 03 00 35 b4 b5 c3  |.:].5.......5...|
+00000400  43 78 3d e8 eb 66 7d 1c  36 8e a1 9f 26 ab 5a aa  |Cx=..f}.6...&.Z.|
+00000410  63 b6 2f 7a a5 f6 7d 89  1e 5d c5 a1 bf b4 3b 4a  |c./z..}..]....;J|
+00000420  89 1f 96 74 e3 c4 d8 72  57 a5 c7 99 a9 f3 77 16  |...t...rW.....w.|
+00000430  f3 25                                             |.%|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 02 1e 64 ba 97 ba 8d  |...........d....|
-00000010  3f 1b d5 5b c5 2e e5 b9  10 01 37 c9 5c e5 ed 39  |?..[......7.\..9|
-00000020  7f 9c 8b f8 ef 50 64 5e  30 05 16 ac 80 51 96 78  |.....Pd^0....Q.x|
-00000030  2a 50 0f 1e d8 76 ab fd  bd 7f 3b 17 7e 1d e9 f5  |*P...v....;.~...|
-00000040  03 76 1b 66 3d 15 dc f3  65 a2 aa a9 23 89 09 e9  |.v.f=...e...#...|
-00000050  dc de a6 27 fc 21 d9 97  d4 08 05 9a 1c 49 8c ee  |...'.!.......I..|
-00000060  fc bd f1 9f e2 4e 3a e3  ee 07 39 d0 34 05 cb 18  |.....N:...9.4...|
-00000070  83 2b 68 45 df 84 4b b2  c3 79 42 73 b9 f1 1c f2  |.+hE..K..yBs....|
-00000080  5f d9 5c f5 7c 4e 86 5e  97 78 ea 0a fa e7 60 68  |_.\.|N.^.x....`h|
-00000090  80 c3 17 5f e7 92 9d 6e  9a 92 37 84 92 4b 83 9c  |..._...n..7..K..|
-000000a0  fa 4c 2a 82 23 eb 67 d0  b2 cc 9e 59 8f 2c e7 bc  |.L*.#.g....Y.,..|
-000000b0  b3 4f 2a 0c 93 bf 17 b8  48 70 5e 0a 85 92 6d 2a  |.O*.....Hp^...m*|
-000000c0  ac 81 9e cd 2c 59 fc a7  e3 5b 82 d5 e3 f5 cd c2  |....,Y...[......|
-000000d0  8a 68 b8 e9 36 e2 08 0b  f7 09 9c 17 95 a3 5e 3d  |.h..6.........^=|
-000000e0  ef 7c c6 5c fe 32 9e 9d  31 c9 b7 76 5a 71 c3 d7  |.|.\.2..1..vZq..|
-000000f0  cd e3 c6 70 e5 2f 07 df  1d b4 34 56 0b ed 52 13  |...p./....4V..R.|
-00000100  bc b2 ac 66 0c 84 b0 2e  32 93 08 f2 04 91 8e e3  |...f....2.......|
-00000110  7b 7f 22 2a a9 04 50 5c  78 f1 06 c5 fd 2c 4c 77  |{."*..P\x....,Lw|
-00000120  a9 17 b5 a8 42 6d f2 0e  87 32 d3 7f be 9e 1d 09  |....Bm...2......|
-00000130  50 10 25 9d f1 a5 25 c3  c2 be 0d 8d 8e 96 5e 1c  |P.%...%.......^.|
-00000140  83 06 45 bc f0 5b 6f b5  0a 02 2a cc ce ac 7e 62  |..E..[o...*...~b|
-00000150  f0 b1 89 25 30 bc 12 d2  da f9 1d d0 46 55 97 4c  |...%0.......FU.L|
-00000160  09 39 e1 a5 1f 4d e1 aa  bd 6f 1f 0d 79 4a aa 49  |.9...M...o..yJ.I|
-00000170  73 25 dc a5 bd f7 2b 64  3c 84 ed b0 ef 13 c5 6c  |s%....+d<......l|
-00000180  16 8b 27 bf a5 3d 15 f2  4a 3b 53 ad ba e9 9e 2a  |..'..=..J;S....*|
-00000190  6d f2 44 5c 66 69 04 94  27 99 08 8e c2 7e c6 69  |m.D\fi..'....~.i|
-000001a0  f7 65 1d 0b a5 8c 35 52  0b f1 bd 59 ca d1 bf 44  |.e....5R...Y...D|
-000001b0  47 b0 7b f8 3b a0 84 55  73 c2 83 bb 9d e0 bc ed  |G.{.;..Us.......|
-000001c0  60 07 32 ce 71 b3 60 12  ef ca 28 bb 6c fb bb c7  |`.2.q.`...(.l...|
-000001d0  3e eb 05 65 a5 26 1a 6c  40 c8 b4 4e 31 12 a0 96  |>..e.&.l@..N1...|
-000001e0  19 66 86 f5 1e f8 bd 6d  f4 2e 98 60 fe ff 22 1e  |.f.....m...`..".|
-000001f0  a9 27 49 87 77 7d b4 5d  ea f8 bc 3a 10 15 84 8c  |.'I.w}.]...:....|
-00000200  cd aa 2c e8 94 93 a5 ee  db 7a d8 96 e9 d5 68 e9  |..,......z....h.|
-00000210  34 68 40 5b dd 18 dc f0  ef b7 17 72 fd 06 70 d1  |4h@[.......r..p.|
-00000220  b6 89 ae 66 40 40 f7 61  0b 17 03 03 00 a4 26 c1  |...f@@.a......&.|
-00000230  3c d9 6c 83 52 e3 5e 64  46 7f 12 1d 3d c7 7d 0f  |<.l.R.^dF...=.}.|
-00000240  a9 8f d3 45 f5 81 46 16  24 c6 c3 7e 5f e4 25 be  |...E..F.$..~_.%.|
-00000250  00 33 7a 1c 35 d4 5c 64  54 56 08 66 4d 2f 68 15  |.3z.5.\dTV.fM/h.|
-00000260  1b 71 d9 aa c9 9e e0 cc  d2 73 a9 99 41 9b 08 1f  |.q.......s..A...|
-00000270  d4 41 de e5 4f 1f 30 65  61 02 8e 6f 79 d7 47 86  |.A..O.0ea..oy.G.|
-00000280  2f e6 0e 65 9e 06 e8 98  d1 fe bc 89 b4 bc f4 9b  |/..e............|
-00000290  70 02 06 e4 9d 37 dd 1b  63 b6 06 62 1a c7 45 30  |p....7..c..b..E0|
-000002a0  9d 08 64 35 8b 96 88 9a  1e 58 2f d0 ef 44 39 04  |..d5.....X/..D9.|
-000002b0  3c bf e2 e6 c4 73 de f9  b0 10 ed 56 eb 04 bd 4e  |<....s.....V...N|
-000002c0  89 38 50 3b e7 e5 12 7c  8e 74 b2 a5 79 2d 88 7b  |.8P;...|.t..y-.{|
-000002d0  e5 1b 17 03 03 00 35 42  b2 61 24 4c 38 b5 d1 42  |......5B.a$L8..B|
-000002e0  93 12 66 c5 be 3c f0 b1  b2 6b 86 07 99 7d f3 e4  |..f..<...k...}..|
-000002f0  74 2b 43 98 38 df 70 7a  e5 f7 67 cf c3 08 23 19  |t+C.8.pz..g...#.|
-00000300  4a cf 06 26 fe 56 4a 97  4a 82 70 09 17 03 03 00  |J..&.VJ.J.p.....|
-00000310  17 9b 3f bb 09 7d 4f c9  05 42 f7 d1 a7 59 0c a7  |..?..}O..B...Y..|
-00000320  c6 9b 36 e1 46 ad 9b 89  17 03 03 00 13 ae a5 51  |..6.F..........Q|
-00000330  76 d8 3a 77 a8 a0 38 70  bf be c8 fb ff fe 53 09  |v.:w..8p......S.|
+00000000  14 03 03 00 01 01 17 03  03 02 1e 2e 1c 18 ac 6e  |...............n|
+00000010  bd d7 35 f8 21 6f 36 d7  13 94 53 3b 56 5d 03 8e  |..5.!o6...S;V]..|
+00000020  2d 92 fa cb 17 d3 75 55  13 84 9c aa be f7 34 9e  |-.....uU......4.|
+00000030  35 67 9b 90 bc 76 5d 65  c0 23 b0 04 d0 ba 15 b5  |5g...v]e.#......|
+00000040  30 70 4d 8d d2 38 73 0a  3a 58 c3 bc da a4 f5 ae  |0pM..8s.:X......|
+00000050  05 ee 0c 06 bd 06 fe ab  1b 31 cf 4d 46 63 cc ee  |.........1.MFc..|
+00000060  8f 8a 0d e9 32 50 4d a0  f6 f2 ce c5 be 41 c2 16  |....2PM......A..|
+00000070  a7 c3 b3 8a 5c 27 4a fd  37 2d 32 d9 76 25 27 12  |....\'J.7-2.v%'.|
+00000080  03 b9 e7 ef bc c8 59 e1  16 80 dc b2 16 ae 05 b6  |......Y.........|
+00000090  cf 8e 99 0d f8 ed 5a b1  bb c1 05 d5 35 fe fd 2d  |......Z.....5..-|
+000000a0  97 c6 19 d8 2d 1a a9 30  d1 4a 6d 27 45 93 5f 5d  |....-..0.Jm'E._]|
+000000b0  45 f4 98 a8 d8 88 27 8f  f2 ad 1e 24 6e c8 8f 12  |E.....'....$n...|
+000000c0  f7 32 b5 3d 3c e3 e0 32  56 4e 80 a8 5f 27 f0 d0  |.2.=<..2VN.._'..|
+000000d0  a1 c2 d0 22 2d 3a 36 0f  bd 7b 94 9f ca 8d c1 ea  |..."-:6..{......|
+000000e0  c6 1f d8 87 4a 75 bd 3e  0f ae 2f e1 78 ae 3f 00  |....Ju.>../.x.?.|
+000000f0  f4 3a 82 dd ec 3f 61 43  bf 4b f8 01 a3 32 df 13  |.:...?aC.K...2..|
+00000100  61 45 ca bb e0 9a 17 85  45 90 c6 fb 5d 79 1b 58  |aE......E...]y.X|
+00000110  54 ca 84 e9 a9 11 c4 74  82 f7 da e4 b3 4f 05 a1  |T......t.....O..|
+00000120  23 72 9f 63 b8 4c 55 e6  da 33 b9 1c b0 fe 28 72  |#r.c.LU..3....(r|
+00000130  f0 02 b6 ec 70 ae 27 d4  21 51 32 56 32 4e e7 7d  |....p.'.!Q2V2N.}|
+00000140  b8 0d 75 25 45 5c 68 83  4f e3 3e 8a 87 7c 06 81  |..u%E\h.O.>..|..|
+00000150  ac ff 23 44 0e bd e7 0a  76 64 45 c4 04 df 35 db  |..#D....vdE...5.|
+00000160  ab 8a 38 87 f5 e5 35 75  7a 92 85 3d 14 9e aa 19  |..8...5uz..=....|
+00000170  4d 94 25 8f c0 c3 37 ca  63 f3 dd 48 4a 6a 6b f5  |M.%...7.c..HJjk.|
+00000180  fa 52 67 30 ab ff 56 9f  58 bd cd 66 d4 83 85 d8  |.Rg0..V.X..f....|
+00000190  85 6c 6d 3c 56 e5 17 75  fc dc a7 3d ed 18 a1 3b  |.lm<V..u...=...;|
+000001a0  6c e6 54 95 75 38 77 77  90 34 81 cb 1c cb e9 04  |l.T.u8ww.4......|
+000001b0  c8 d2 12 04 36 a8 9b f6  9b 6a 81 8d f5 b1 e2 ca  |....6....j......|
+000001c0  31 37 27 f2 84 bd 5c 3a  1c 6c 64 83 35 94 89 ee  |17'...\:.ld.5...|
+000001d0  08 42 1d 05 52 67 e6 4d  7f bb d2 21 82 8c 15 6b  |.B..Rg.M...!...k|
+000001e0  e9 f9 6d bc b3 1f 5a df  b8 55 aa 9d f6 aa d2 7c  |..m...Z..U.....||
+000001f0  41 76 3b 1b b2 f5 b8 49  32 be bb f8 0e d3 74 be  |Av;....I2.....t.|
+00000200  eb 0d 9b e2 57 b6 ec e5  61 d7 09 80 a8 63 b4 cf  |....W...a....c..|
+00000210  bb 0a 14 9d 39 1c 08 58  22 c4 ae d5 4f 42 97 14  |....9..X"...OB..|
+00000220  71 e1 c0 a5 5e 8e 2f 89  27 17 03 03 00 a3 f0 96  |q...^./.'.......|
+00000230  d3 9e 8c 19 84 9a 42 d3  84 64 a6 89 40 6f d6 c9  |......B..d..@o..|
+00000240  50 90 bb 9d 16 90 9d fb  aa 85 28 ab 25 63 78 a9  |P.........(.%cx.|
+00000250  dd dc 35 03 73 08 26 2b  30 53 84 f8 74 66 f2 6f  |..5.s.&+0S..tf.o|
+00000260  d7 0a f0 e2 c4 10 a4 46  cf 77 ea cb b7 b7 a9 81  |.......F.w......|
+00000270  5f 09 4a 6a a5 16 a4 79  dc b0 c9 ae 5a ff 2a 7b  |_.Jj...y....Z.*{|
+00000280  3f bd 7a 15 b3 02 ad 3e  90 37 46 51 71 fc 6d d0  |?.z....>.7FQq.m.|
+00000290  9f 38 42 95 1a 88 ac 5f  83 a1 8a 59 59 62 cc 4a  |.8B...._...YYb.J|
+000002a0  57 d2 3e 1e 7e 1d c0 4d  41 23 85 5f 92 f4 63 16  |W.>.~..MA#._..c.|
+000002b0  df df 6e 3d d7 c1 e6 21  22 0f e1 13 82 29 a6 e3  |..n=...!"....)..|
+000002c0  f8 8c a4 a3 72 1d 61 c1  2a 9d a8 2d 13 8a 4f 87  |....r.a.*..-..O.|
+000002d0  91 17 03 03 00 35 9d 35  c8 ac 1e c6 46 8d e1 42  |.....5.5....F..B|
+000002e0  68 e5 79 77 64 15 e2 13  c0 70 1a 47 59 d0 1e c3  |h.ywd....p.GY...|
+000002f0  68 f7 5a fe 11 a2 3d e4  6e 2c b5 7d ea 98 e7 75  |h.Z...=.n,.}...u|
+00000300  7c 54 a4 35 9b 1f c9 ba  72 b1 94 17 03 03 00 17  ||T.5....r.......|
+00000310  a3 81 17 ac 97 a9 f0 91  b5 7a 04 38 ff fd 8e d3  |.........z.8....|
+00000320  d8 7b c4 40 7e d3 ea 17  03 03 00 13 a8 b1 06 94  |.{.@~...........|
+00000330  90 83 62 d5 be a8 23 d5  8b af 77 0d 90 13 98     |..b...#...w....|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-Ed25519 b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-Ed25519
index 26f76bc..689c287 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-Ed25519
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-Ed25519
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,107 +16,107 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 a5 5b a0 2c f5  |....z...v...[.,.|
-00000010  57 cc 49 88 64 7d ea 7c  ee 61 cf fc 94 9f d4 5c  |W.I.d}.|.a.....\|
-00000020  bb 83 80 5a f5 7c a3 fc  0a c8 61 20 00 00 00 00  |...Z.|....a ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 4e 4c 01 f1 4e  |....z...v..NL..N|
+00000010  49 97 ec eb df ce 50 4d  1c 9c d0 35 92 10 97 0a  |I.....PM...5....|
+00000020  dd fb a8 4f 39 c6 14 21  d6 42 ac 20 00 00 00 00  |...O9..!.B. ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 fe  |..+.....3.$... .|
-00000060  e1 43 bd 10 b3 f6 3b 4d  7c 46 8f a3 bc 7d 08 08  |.C....;M|F...}..|
-00000070  22 ed aa 9b 7b 89 f3 87  13 7e fe 6c b0 db 3f 14  |"...{....~.l..?.|
-00000080  03 03 00 01 01 17 03 03  00 17 2b ce 52 22 34 c5  |..........+.R"4.|
-00000090  d9 2c ae d0 23 4d 0c 6e  b4 f0 c8 58 11 22 54 bb  |.,..#M.n...X."T.|
-000000a0  15 17 03 03 00 42 96 b4  72 be f0 6b d3 b0 82 7c  |.....B..r..k...||
-000000b0  dc d2 67 69 2c d4 40 a1  7a 3d 9a 39 a5 29 ca 64  |..gi,.@.z=.9.).d|
-000000c0  c5 0b d2 ba 7c c3 73 e2  93 0d 44 e3 64 ce ec b2  |....|.s...D.d...|
-000000d0  90 ae e2 df 18 f8 f5 93  5f 91 80 c2 b4 00 e7 de  |........_.......|
-000000e0  f5 3f 4d c8 de 4c 5f f0  17 03 03 02 6d c6 df 33  |.?M..L_.....m..3|
-000000f0  1e 12 40 02 7f 46 67 d8  4b 98 d7 5e f7 0a bf dc  |..@..Fg.K..^....|
-00000100  fe 3c 7f 00 2d 74 31 cb  10 35 e2 eb 16 11 d1 2f  |.<..-t1..5...../|
-00000110  10 bf 8c 4d 37 c7 1b f6  23 a3 3e 68 87 1a 50 53  |...M7...#.>h..PS|
-00000120  64 7c 0d fd 0d 06 32 93  17 85 da e0 d4 86 2c 5f  |d|....2.......,_|
-00000130  0a 91 9a fd 00 87 f1 f4  fc 18 22 a1 2e 21 44 7d  |.........."..!D}|
-00000140  6c ca 2c 0d f2 38 15 d1  9d 86 9b 67 b6 b4 06 6d  |l.,..8.....g...m|
-00000150  30 07 a8 b1 b8 7a 5d 1d  17 d0 c5 1a 40 a3 42 b5  |0....z].....@.B.|
-00000160  dc 56 c8 ec c3 c3 4e ff  5f 7c ce 27 fa a6 82 2a  |.V....N._|.'...*|
-00000170  b9 85 47 4e 0b d1 84 17  92 a6 42 86 9a 65 1c a9  |..GN......B..e..|
-00000180  45 be af a7 95 03 0b db  84 fa 5d 1b 7e 57 72 40  |E.........].~Wr@|
-00000190  ab a3 9e 46 50 3f c7 03  94 9a 4a 02 bd 9a 90 1c  |...FP?....J.....|
-000001a0  42 c9 98 e9 81 cd e8 73  a6 82 42 20 24 89 d5 8d  |B......s..B $...|
-000001b0  48 20 df d4 f4 d2 15 e4  c0 28 ee d8 2a 1b ad b8  |H .......(..*...|
-000001c0  1d a4 86 e1 b4 89 97 e8  36 63 aa 9c f4 7e 65 c6  |........6c...~e.|
-000001d0  12 86 41 54 b3 4a 79 9f  48 33 fc fc 0d f5 14 47  |..AT.Jy.H3.....G|
-000001e0  ba ae d3 20 64 37 f1 cd  9e 1b cc b2 27 68 e6 f2  |... d7......'h..|
-000001f0  95 0c 29 59 f2 15 2e 97  60 f3 8d 1b b1 65 cd 4f  |..)Y....`....e.O|
-00000200  0d a5 0a 34 59 63 20 f0  71 e6 d5 13 f2 4e dc 73  |...4Yc .q....N.s|
-00000210  5b 1a 36 d7 6a aa b0 30  f4 ff 68 ad f5 5e f0 12  |[.6.j..0..h..^..|
-00000220  0c 34 a8 4d 91 03 8e 4a  30 07 23 49 41 7a fe 19  |.4.M...J0.#IAz..|
-00000230  62 5b 6a a0 4d d5 54 a1  1f 45 91 86 b3 a1 c3 32  |b[j.M.T..E.....2|
-00000240  62 79 a8 93 b3 d4 43 0c  a8 12 10 4f f5 53 c3 3b  |by....C....O.S.;|
-00000250  d9 73 ef 42 be 1d f5 70  fd 9f ca 54 20 3a 33 c9  |.s.B...p...T :3.|
-00000260  f6 e8 55 13 b3 ab 45 c8  bb 5c 6b b9 39 a9 04 ac  |..U...E..\k.9...|
-00000270  1c 3c 5a aa b7 91 2c 0c  f6 74 ea 6b 2d e2 9a 3c  |.<Z...,..t.k-..<|
-00000280  d0 30 d8 14 e5 8c bf 06  2c d3 89 2e 0d ad df c5  |.0......,.......|
-00000290  5b 6d fa 8f 0c 64 cc 40  04 12 97 ab ab ff be d8  |[m...d.@........|
-000002a0  a6 fc 78 1d d4 18 90 bf  b4 8e ce 09 40 8c dd 8a  |..x.........@...|
-000002b0  a8 cc 86 ce 6d a8 0c f8  79 66 f6 0b 46 2b 0d 4c  |....m...yf..F+.L|
-000002c0  73 14 dd cd 2c 56 77 f7  1f 4d 85 d0 1c 16 da 26  |s...,Vw..M.....&|
-000002d0  b0 65 39 31 b5 cd f3 7a  80 52 96 6d 81 1e 65 98  |.e91...z.R.m..e.|
-000002e0  b2 a3 12 22 52 68 c5 59  19 a1 9a be 80 5c 25 57  |..."Rh.Y.....\%W|
-000002f0  9b 60 e9 95 28 4b 77 a0  70 ce 4b 5b 70 37 0a e3  |.`..(Kw.p.K[p7..|
-00000300  7e 2c c7 0e 1c 6b 3a 54  2c 0d b3 53 0c f4 12 66  |~,...k:T,..S...f|
-00000310  c6 17 04 88 f5 12 58 d8  2c 70 54 85 2b 71 ee 98  |......X.,pT.+q..|
-00000320  75 8d e4 57 7c 96 a2 44  12 77 f0 6d 8a 12 89 b3  |u..W|..D.w.m....|
-00000330  8b 85 bf 33 d9 ee de 24  b5 7d d5 cb 0d d4 9b bf  |...3...$.}......|
-00000340  c6 e3 27 44 f2 35 35 09  00 86 eb 8b 34 c4 c4 6a  |..'D.55.....4..j|
-00000350  fe 95 e9 80 58 4f 3e 99  24 f8 17 03 03 00 99 de  |....XO>.$.......|
-00000360  1b f5 7a dc 63 8d 5e 75  de 72 cf 41 ca 75 ab d9  |..z.c.^u.r.A.u..|
-00000370  55 b0 b5 81 a9 6c a9 f6  1d ea 66 dd dd 86 f5 03  |U....l....f.....|
-00000380  12 08 9d b4 07 48 eb 8b  45 f1 35 b1 31 bd 5d f3  |.....H..E.5.1.].|
-00000390  e2 34 73 9a e5 87 b7 8b  0b 8b ab 7e 05 db 56 db  |.4s........~..V.|
-000003a0  4f 4c 52 1a 3b 5d 4c 53  b1 49 40 81 5e 73 af 26  |OLR.;]LS.I@.^s.&|
-000003b0  21 e6 e3 5c 4a a6 f6 07  56 de f5 76 5c 67 d8 d5  |!..\J...V..v\g..|
-000003c0  eb f3 6a fb 6d b7 00 bc  6b 28 c9 63 4d 58 76 97  |..j.m...k(.cMXv.|
-000003d0  aa 51 2b f3 03 9c 70 3b  3e b2 a4 16 a0 a0 e0 43  |.Q+...p;>......C|
-000003e0  77 da 88 2d 48 3b 07 e2  8d a6 e2 80 85 68 ac dc  |w..-H;.......h..|
-000003f0  ce 66 2f 97 20 9e 4e 33  17 03 03 00 35 f6 ce 98  |.f/. .N3....5...|
-00000400  8b 01 f5 75 8e 98 42 02  b1 b8 90 f3 08 96 e8 5a  |...u..B........Z|
-00000410  d4 7c ef d1 62 1e b3 36  39 d9 b2 59 1f 1f cc 74  |.|..b..69..Y...t|
-00000420  f2 a8 62 11 00 28 31 fa  d9 5a 27 10 7b 93 ff de  |..b..(1..Z'.{...|
-00000430  a0 ec                                             |..|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 c1  |..+.....3.$... .|
+00000060  c2 ca 32 aa 48 d8 52 bc  c8 23 6d 98 18 3e 15 b6  |..2.H.R..#m..>..|
+00000070  0b 25 db f9 6f a7 e1 75  95 a1 46 d3 47 4a 0e 14  |.%..o..u..F.GJ..|
+00000080  03 03 00 01 01 17 03 03  00 17 87 10 92 da b4 9a  |................|
+00000090  03 a5 0f 73 e6 93 cb 71  1d 58 6e 5d 27 eb ee b6  |...s...q.Xn]'...|
+000000a0  c7 17 03 03 00 42 89 8d  57 16 95 5b f0 98 ad c7  |.....B..W..[....|
+000000b0  d7 94 ba 4d 7e 88 b9 8d  13 26 a6 6c 81 90 a6 1e  |...M~....&.l....|
+000000c0  2b 4e 91 70 e2 da 9d a2  0d 6f 9b 5b ee 69 58 a1  |+N.p.....o.[.iX.|
+000000d0  4c c3 59 57 28 62 b3 ed  26 15 79 db 01 8c 88 e3  |L.YW(b..&.y.....|
+000000e0  63 1f bc b0 01 c9 82 ca  17 03 03 02 6d e5 d6 77  |c...........m..w|
+000000f0  4e d3 af c3 5e 01 e9 1b  31 63 a4 84 d3 cc 2d f8  |N...^...1c....-.|
+00000100  5d 73 f9 3e 83 03 c5 c5  cd 95 00 7b f2 b5 79 fa  |]s.>.......{..y.|
+00000110  47 e5 07 89 a9 22 49 7a  7e 7e 6e d2 3b 68 e8 9c  |G...."Iz~~n.;h..|
+00000120  40 1c 86 2a 48 ee 59 8e  1c 04 8b 91 20 68 65 31  |@..*H.Y..... he1|
+00000130  e7 76 dc 6c 5a ce cb 32  d3 e8 71 7f 93 08 b5 01  |.v.lZ..2..q.....|
+00000140  84 0a b4 ec 80 68 69 9b  b3 4a 4a 4d 56 16 eb 42  |.....hi..JJMV..B|
+00000150  29 93 4d b4 76 f6 e0 15  fe 25 b1 cb 5a da 22 4b  |).M.v....%..Z."K|
+00000160  88 4c ec 66 48 09 e1 d1  0f 3e 3a ad 65 d7 d7 85  |.L.fH....>:.e...|
+00000170  1d cb 35 2c 84 60 ec a1  6d f1 60 cf c6 c7 82 1a  |..5,.`..m.`.....|
+00000180  7c 91 40 2e 3e 88 1f ff  79 2e 6e 97 c5 45 9f e1  ||.@.>...y.n..E..|
+00000190  bf 33 ad 65 df f3 ce 1a  d7 57 7e db f2 28 79 a9  |.3.e.....W~..(y.|
+000001a0  9e 4f 9e 8a ce 02 5a 18  bb f1 ac 72 5b 3f 4c 6b  |.O....Z....r[?Lk|
+000001b0  97 14 14 f9 82 8a 4f 99  21 98 db af 3e 08 ab 4f  |......O.!...>..O|
+000001c0  d8 3f f6 cc da 76 77 eb  02 39 0a 00 23 a5 e0 92  |.?...vw..9..#...|
+000001d0  01 10 3f 76 ab 1a 38 8e  f9 a1 d0 25 c3 9d 50 a4  |..?v..8....%..P.|
+000001e0  ef a5 8c f8 5d bc d9 fd  dd 25 cd 42 38 52 d1 cd  |....]....%.B8R..|
+000001f0  d2 1b fc ba 7d 8b bd 82  05 23 c3 9d 02 ff 1b 4e  |....}....#.....N|
+00000200  08 e1 f3 7c 35 15 0f e8  0e b7 8a e5 4a 2b da 45  |...|5.......J+.E|
+00000210  4a 72 9a 32 7e 55 52 65  d2 a8 32 90 53 bf 25 29  |Jr.2~URe..2.S.%)|
+00000220  1e 8d d7 a3 22 d6 40 19  95 58 a8 37 af a8 52 e7  |....".@..X.7..R.|
+00000230  79 b9 4e 61 d8 f0 7d d2  69 25 99 28 3f 31 f6 b2  |y.Na..}.i%.(?1..|
+00000240  44 65 1f 9c 41 08 17 c9  01 5d 20 ea ab fe 06 64  |De..A....] ....d|
+00000250  9a f4 d0 24 e0 b5 88 0a  2b 96 e9 71 11 a8 49 b4  |...$....+..q..I.|
+00000260  40 62 1b 45 15 47 cb a5  fc 4f 07 58 2b ef d4 5d  |@b.E.G...O.X+..]|
+00000270  df 40 38 6c 6e ca 63 c5  95 2d 79 26 86 ff 33 02  |.@8ln.c..-y&..3.|
+00000280  da 5a 85 0c 8f 7f 58 ba  ea 88 cf bc 51 92 12 86  |.Z....X.....Q...|
+00000290  f1 c1 f9 0a d0 6e cc b4  2b 16 98 ad f8 11 ad 63  |.....n..+......c|
+000002a0  82 d7 4e ea a5 ee 78 a2  9a 35 b6 b3 d9 24 cf 66  |..N...x..5...$.f|
+000002b0  03 d2 25 1f 15 37 c7 b5  8e bb 0a 40 0f 28 c2 16  |..%..7.....@.(..|
+000002c0  90 a4 61 9e dd fd b5 ad  97 39 0d 66 e7 fa 5b e2  |..a......9.f..[.|
+000002d0  c2 ef 44 5d 44 07 d6 c3  ed e2 89 6e 4c ed 79 42  |..D]D......nL.yB|
+000002e0  86 3b f4 94 0c 82 5e 52  ce 00 ab 5c 20 b4 18 db  |.;....^R...\ ...|
+000002f0  c9 fe 8b be 8d da e9 86  13 62 6b 8d 0d 57 c8 fe  |.........bk..W..|
+00000300  a6 4b 82 52 d5 d8 05 18  2f a0 43 d6 c8 89 fb e7  |.K.R..../.C.....|
+00000310  72 17 61 89 36 5b e0 aa  4d 6c 20 ee 68 db 32 e4  |r.a.6[..Ml .h.2.|
+00000320  97 9f 18 26 7c 1a cd e8  b9 05 ae fd 86 bf 0e 47  |...&|..........G|
+00000330  09 06 bd de 2d b9 50 6a  0c a6 27 04 5e aa e0 ce  |....-.Pj..'.^...|
+00000340  e7 cf 98 f9 7e 7d b9 4d  77 9a 88 3a d4 41 07 cc  |....~}.Mw..:.A..|
+00000350  87 b6 41 53 8b 8c 79 8e  07 b9 17 03 03 00 99 0b  |..AS..y.........|
+00000360  63 4e d8 79 d7 11 f2 46  00 6c 5d d2 9e 49 df 7e  |cN.y...F.l]..I.~|
+00000370  f2 96 1a 68 9d 6a 05 dc  61 45 47 a4 18 5c 65 04  |...h.j..aEG..\e.|
+00000380  00 38 d1 25 0c ff a3 a2  c0 c2 82 7f b1 1b a1 c6  |.8.%............|
+00000390  7b ac fb 71 48 b6 e4 e2  7b c4 d0 44 8e 22 d6 91  |{..qH...{..D."..|
+000003a0  99 87 a2 88 3d bb b4 80  13 57 2a 6a b0 2d 52 16  |....=....W*j.-R.|
+000003b0  d3 f2 e4 cd d0 79 9a 31  ce 68 65 b3 61 67 a0 b9  |.....y.1.he.ag..|
+000003c0  1e 6b 9f 73 dc 46 be 5e  df d7 c2 30 d5 60 b5 e5  |.k.s.F.^...0.`..|
+000003d0  60 cc 10 ae 9a f9 b6 9a  fd 14 b9 1e b7 3c 1d 3e  |`............<.>|
+000003e0  34 a6 49 d2 48 f7 24 56  29 c9 98 f1 33 b1 e5 5e  |4.I.H.$V)...3..^|
+000003f0  2c 7b bb 5f b6 53 6a c8  17 03 03 00 35 d9 af 32  |,{._.Sj.....5..2|
+00000400  1f a5 09 3f 8a 10 df a7  34 9b f8 ec 07 81 80 73  |...?....4......s|
+00000410  dc ba 09 fc 40 e4 1e df  f6 de 02 54 3c 7d ea 49  |....@......T<}.I|
+00000420  91 16 72 70 8e 1a 21 76  c6 00 0e 03 9f 0a 82 fe  |..rp..!v........|
+00000430  4c 18                                             |L.|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 01 50 57 2a 94 d7 c1  |..........PW*...|
-00000010  40 42 d3 aa e3 d8 b3 e4  13 ff 51 ee 8a 52 9d 9c  |@B........Q..R..|
-00000020  c4 a4 40 91 72 0f c9 4e  fe 56 22 89 ea fb 6d 05  |..@.r..N.V"...m.|
-00000030  a2 96 97 4b fa ef ec 13  b6 13 3b 69 6c 65 c0 74  |...K......;ile.t|
-00000040  e5 54 df a4 97 50 f7 85  a1 c7 fb 52 84 56 98 16  |.T...P.....R.V..|
-00000050  52 b6 eb 5a d0 72 6e 65  98 81 bb f5 2a 4c ed 1a  |R..Z.rne....*L..|
-00000060  90 e1 01 a6 2b eb e0 1d  06 ba 8a d4 47 45 90 f0  |....+.......GE..|
-00000070  91 bd c4 d7 54 ba 44 30  78 42 15 42 74 59 1c c7  |....T.D0xB.BtY..|
-00000080  56 34 39 64 8e f8 0a 0f  2b 35 0f 06 97 34 3e 5e  |V49d....+5...4>^|
-00000090  00 00 5a f0 07 0a f5 66  46 86 94 8c 0b 62 1c fd  |..Z....fF....b..|
-000000a0  cc cf fd 5d 06 96 1e 21  9e 20 d5 07 5f 5a 00 9f  |...]...!. .._Z..|
-000000b0  6f 80 36 5e aa 56 d0 07  00 20 08 55 48 fe 6c a1  |o.6^.V... .UH.l.|
-000000c0  b1 22 f3 94 54 7e 7e d5  e9 f0 71 69 01 fc bd 14  |."..T~~...qi....|
-000000d0  a1 de 38 e4 b4 02 88 3e  66 77 3b f7 aa cd 57 a3  |..8....>fw;...W.|
-000000e0  cf 6a 40 7d 93 75 79 3b  95 07 33 69 b2 8d 2a 37  |.j@}.uy;..3i..*7|
-000000f0  94 d3 8d d5 b5 8a f0 94  8d 1e b4 9e 02 4f 7d 83  |.............O}.|
-00000100  05 c6 c7 c8 a0 74 f1 88  f7 68 bf 4b e4 18 3b 6f  |.....t...h.K..;o|
-00000110  0c 6c a6 e7 75 50 b9 f6  68 2e 05 67 a3 47 df 22  |.l..uP..h..g.G."|
-00000120  fa ae c1 4f a8 3d f3 bb  dc 66 c3 b6 98 b7 8c 5b  |...O.=...f.....[|
-00000130  48 51 57 d7 43 b2 13 25  9e d5 82 6c 70 5c 42 53  |HQW.C..%...lp\BS|
-00000140  a9 e8 8a 12 26 cd 3a f8  f8 e5 97 84 55 89 09 d4  |....&.:.....U...|
-00000150  d4 20 40 d7 2d 6f 66 36  63 f6 53 17 03 03 00 59  |. @.-of6c.S....Y|
-00000160  2f f6 22 ce f3 86 f8 ee  b1 f6 49 de c8 bf 91 9c  |/.".......I.....|
-00000170  bc 2f fa 75 af 51 bc ee  b7 a5 a9 82 35 3b 83 9d  |./.u.Q......5;..|
-00000180  3d 9f 57 10 07 4b af 01  66 f0 39 dd f0 4a a7 90  |=.W..K..f.9..J..|
-00000190  f3 6c 28 97 80 0d a5 74  2d 22 a3 81 cd 64 2b 1a  |.l(....t-"...d+.|
-000001a0  d1 4e 2d 9e 8e 69 38 f8  11 9c 17 1f e6 c9 01 4e  |.N-..i8........N|
-000001b0  48 1f 80 43 26 d4 5a 82  30 17 03 03 00 35 e9 25  |H..C&.Z.0....5.%|
-000001c0  b9 01 8e 0d 51 be 9d d1  b4 2b 0a ee 36 69 85 1a  |....Q....+..6i..|
-000001d0  10 a8 ff 36 e7 21 b7 f2  54 75 ca 07 52 88 48 d0  |...6.!..Tu..R.H.|
-000001e0  ad 67 0b 92 52 70 fa 14  bc 7e 1d 43 f0 a2 7b df  |.g..Rp...~.C..{.|
-000001f0  ac 0c 19 17 03 03 00 17  98 76 d7 52 06 90 ef 00  |.........v.R....|
-00000200  21 5e ec ed 0e 35 77 ef  5c f1 32 58 33 0f 06 17  |!^...5w.\.2X3...|
-00000210  03 03 00 13 05 fb b3 c3  4d b5 a4 9c 52 ea bc d2  |........M...R...|
-00000220  86 08 26 b8 df 5c 4c                              |..&..\L|
+00000000  14 03 03 00 01 01 17 03  03 01 50 1d 6e 16 0d 4e  |..........P.n..N|
+00000010  c0 a2 41 c3 a2 84 c9 80  c0 f0 ef c0 5d 3a 3b f2  |..A.........]:;.|
+00000020  bf 1c 9e 79 d7 d3 94 0b  41 2d bc 50 eb 0f 60 f4  |...y....A-.P..`.|
+00000030  bd cd f6 03 22 7b 68 68  44 34 c9 0f 23 ca 76 6f  |...."{hhD4..#.vo|
+00000040  f2 97 38 07 43 56 7e b7  ce 67 68 67 37 34 d0 f7  |..8.CV~..ghg74..|
+00000050  c5 92 fd 65 98 b8 7e 5f  48 a8 a3 aa a8 96 65 b5  |...e..~_H.....e.|
+00000060  48 be 91 99 67 0a 37 c7  31 b4 43 ba 26 bb 87 98  |H...g.7.1.C.&...|
+00000070  3c 55 e4 63 b0 33 ca ee  0a a5 fe 36 88 ef cf f0  |<U.c.3.....6....|
+00000080  ab 6b 7d e8 f6 1f 14 12  49 f7 14 b7 12 bb d8 1e  |.k}.....I.......|
+00000090  e0 be ed 56 75 b9 ab 8a  20 75 d9 6f 45 2d 71 b3  |...Vu... u.oE-q.|
+000000a0  2f b7 cd 9c c5 16 ed 37  0e 08 15 a5 49 18 7c 13  |/......7....I.|.|
+000000b0  8e 0b 66 01 b1 8c 1d 89  d4 91 9e 5a 6b 94 f6 fa  |..f........Zk...|
+000000c0  7b a8 14 1c a7 20 55 c5  e4 0e 9d e0 5b d6 d4 b7  |{.... U.....[...|
+000000d0  1d 93 2b 7c 25 46 28 11  06 57 a3 cb 2f 4b 39 cf  |..+|%F(..W../K9.|
+000000e0  61 be 60 9a fd f1 6e e1  a2 a7 20 f2 fd 50 a2 d2  |a.`...n... ..P..|
+000000f0  17 db 16 4f 3f 8c 20 e4  4d 56 37 3b c2 42 17 cc  |...O?. .MV7;.B..|
+00000100  5d 99 06 fc 18 0d 1a 88  e8 f9 6f cf 7d 2e 57 73  |].........o.}.Ws|
+00000110  85 47 ed d0 2d b3 9a 05  cf 0c 7d e6 ed 29 95 f4  |.G..-.....}..)..|
+00000120  d5 e0 96 6a 1d 67 3e 5f  43 9f b5 f6 66 f5 84 63  |...j.g>_C...f..c|
+00000130  bd 42 a6 f8 ef 38 42 8a  d8 28 dc 55 e5 88 03 76  |.B...8B..(.U...v|
+00000140  96 ba 89 35 63 7e 6c da  39 d8 9a 27 04 ab d5 0e  |...5c~l.9..'....|
+00000150  48 89 cc 81 25 44 61 16  2c b2 69 17 03 03 00 59  |H...%Da.,.i....Y|
+00000160  81 8f 94 30 8d fc 47 13  7e 84 06 9b 4a 85 2c bb  |...0..G.~...J.,.|
+00000170  b3 a0 0d 4f 50 6a cb 0b  9b 40 ef cc 84 70 1f 69  |...OPj...@...p.i|
+00000180  b9 3e a6 c4 ba 66 eb a9  6f 78 83 7f d4 1f d8 c4  |.>...f..ox......|
+00000190  b0 f6 9b 03 29 7f b1 f8  60 40 0b 28 91 32 2c 03  |....)...`@.(.2,.|
+000001a0  aa 9e 7b fb 99 c2 11 51  1f a7 81 69 16 39 f4 52  |..{....Q...i.9.R|
+000001b0  ca d8 d0 f3 87 6f 58 ab  9a 17 03 03 00 35 de 03  |.....oX......5..|
+000001c0  88 61 50 5c 08 88 77 28  6a 1d 28 44 3d 49 8b 79  |.aP\..w(j.(D=I.y|
+000001d0  d1 a2 13 67 95 0f 7c 18  fe e2 e0 07 f1 ce b9 be  |...g..|.........|
+000001e0  79 aa 40 d6 cf 66 53 ac  15 ae 2a 14 a9 63 98 55  |y.@..fS...*..c.U|
+000001f0  96 16 6f 17 03 03 00 17  a8 ac 17 c5 eb d9 8e 77  |..o............w|
+00000200  9e 4b e0 20 c6 0c 34 b6  c3 ab c4 b6 8b b2 77 17  |.K. ..4.......w.|
+00000210  03 03 00 13 58 d4 7b 8f  ca 20 41 e3 3f d1 ae cf  |....X.{.. A.?...|
+00000220  3d e1 86 91 c0 a1 08                              |=......|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-ECDSA
index 09de5cc..8e361ea 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-ECDSA
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-ECDSA
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,119 +16,119 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 cc a2 2d 09 42  |....z...v....-.B|
-00000010  f0 11 87 04 64 83 e4 d8  80 a5 0f 88 69 ae f1 d2  |....d.......i...|
-00000020  12 05 d2 08 75 15 86 b7  d8 69 e7 20 00 00 00 00  |....u....i. ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 30 0a c5 df b0  |....z...v..0....|
+00000010  90 3a 48 4b 20 f1 89 62  be 1f 1b 64 c2 7e 69 25  |.:HK ..b...d.~i%|
+00000020  9f b7 f9 2c 86 e7 40 e7  e8 10 fa 20 00 00 00 00  |...,..@.... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 c9  |..+.....3.$... .|
-00000060  b4 93 8b 5b b0 ae 93 4a  01 26 0c fb db 3f 53 0b  |...[...J.&...?S.|
-00000070  04 ca 65 63 3f d7 d9 f9  fc ca ea 4c f2 08 3c 14  |..ec?......L..<.|
-00000080  03 03 00 01 01 17 03 03  00 17 85 f6 ff f8 58 7f  |..............X.|
-00000090  2a d9 e0 12 82 d6 31 64  29 70 05 24 0f 17 1e 9f  |*.....1d)p.$....|
-000000a0  dc 17 03 03 00 42 16 7b  d5 fa a6 30 94 8e a0 a7  |.....B.{...0....|
-000000b0  24 59 b9 3d 85 b0 2f d9  25 c6 5a b5 7f 51 ca 54  |$Y.=../.%.Z..Q.T|
-000000c0  4a f7 f0 72 bb dd 5e 70  14 6d 46 3f b3 86 6f c1  |J..r..^p.mF?..o.|
-000000d0  a4 5f 6d ba 97 f3 38 c0  24 4a 9f de 7b b9 49 12  |._m...8.$J..{.I.|
-000000e0  71 02 f8 bc bc 65 5a ea  17 03 03 02 22 f9 92 7e  |q....eZ....."..~|
-000000f0  34 eb b3 a4 03 8e ec 48  30 a0 9b ac a6 7b b3 a5  |4......H0....{..|
-00000100  d0 4a 89 2c 92 6a c6 04  de b2 86 72 0a f1 97 61  |.J.,.j.....r...a|
-00000110  da 70 ef 25 5a a3 f1 b3  3d 78 f1 ec 2b 8f 34 2b  |.p.%Z...=x..+.4+|
-00000120  c9 94 e7 d2 9e 2f 09 5d  7a e3 2e fc 6e e1 ef 80  |...../.]z...n...|
-00000130  e6 0c e9 3e 07 bb b7 0e  74 0c e8 19 fe 7f d8 d0  |...>....t.......|
-00000140  fa 70 03 c1 31 c2 76 51  c3 d0 ed a6 a1 0d 20 74  |.p..1.vQ...... t|
-00000150  86 15 99 51 71 f8 3d 8e  1c 8c a8 19 0a 9c ac 4a  |...Qq.=........J|
-00000160  ab 0e e6 cc 52 a0 a8 ca  d9 71 54 aa 2c 8b 6f 5b  |....R....qT.,.o[|
-00000170  f9 46 07 0d 86 40 d9 54  33 8e de 54 a5 c2 6e 36  |.F...@.T3..T..n6|
-00000180  14 0e e3 52 78 05 56 90  98 2c e1 ec 26 f6 bd 6a  |...Rx.V..,..&..j|
-00000190  e5 0b 31 e1 a4 2a 2a 96  1b d6 57 87 ac a8 07 71  |..1..**...W....q|
-000001a0  83 d9 70 1e 5e 63 9b d1  01 83 e7 c9 c8 1c 5a 34  |..p.^c........Z4|
-000001b0  05 c0 7b da 1c ca 5f 99  49 9a 04 da c9 1c 9b ed  |..{..._.I.......|
-000001c0  b4 af 9d ff 36 71 1b 3a  00 e8 6a c4 6e 47 d9 4a  |....6q.:..j.nG.J|
-000001d0  64 f5 c1 07 ab 19 c8 65  a3 33 26 99 be 53 c3 86  |d......e.3&..S..|
-000001e0  97 10 ef c1 54 8e 69 6c  b1 29 aa 7d c1 63 67 ba  |....T.il.).}.cg.|
-000001f0  d7 72 7c 74 83 58 bd 5a  a8 a8 5f 49 38 ee 1e 34  |.r|t.X.Z.._I8..4|
-00000200  c8 98 19 73 97 2d 76 e6  d7 0d 15 75 a0 98 1f 15  |...s.-v....u....|
-00000210  c9 b8 3d 3f cb 92 a1 39  4b 91 ca e0 d2 0e 38 c2  |..=?...9K.....8.|
-00000220  20 eb f2 b5 04 64 fa d8  e2 d7 2f ba 88 7e f4 37  | ....d..../..~.7|
-00000230  c1 68 c4 2f c9 54 a1 21  5d 4b e7 67 3b 2e 6a 06  |.h./.T.!]K.g;.j.|
-00000240  55 ba d4 8d fe 0e b1 b7  2d cf c2 82 ed 27 3d 5b  |U.......-....'=[|
-00000250  9b 3b 28 a9 d4 c4 3c a0  45 b1 77 37 8b f8 7e f0  |.;(...<.E.w7..~.|
-00000260  51 90 fe 7a 74 14 ac f7  59 8b ed be 79 b0 4b 89  |Q..zt...Y...y.K.|
-00000270  d9 0c 39 fe 45 9d 15 0c  a6 96 26 0d b2 29 b0 a4  |..9.E.....&..)..|
-00000280  29 62 df 4b c0 a0 05 f1  e8 8b 16 af ea 42 8b 58  |)b.K.........B.X|
-00000290  5a ae f6 28 d8 40 09 d1  1e 21 b3 c7 a8 e2 30 4a  |Z..(.@...!....0J|
-000002a0  27 e6 c4 ba ff 62 91 7b  ab 64 18 65 02 e2 10 68  |'....b.{.d.e...h|
-000002b0  87 35 c2 09 5b 23 a4 eb  96 19 a7 1e 75 85 6e 17  |.5..[#......u.n.|
-000002c0  0e bc 11 1a f5 49 05 92  f7 0e e4 c7 85 da 4e 26  |.....I........N&|
-000002d0  5b de f2 dc 36 fb dc dd  c6 42 23 0c a7 de 8d ad  |[...6....B#.....|
-000002e0  f5 2a 8b ff b4 5d c6 ca  ec e3 83 a4 1e 23 3a 2d  |.*...].......#:-|
-000002f0  1a 52 51 11 f5 3b 93 47  89 c8 fc 21 b0 a3 4f b3  |.RQ..;.G...!..O.|
-00000300  6e d2 83 ca 20 75 fc 43  43 e5 1d 5d 57 c9 7c 17  |n... u.CC..]W.|.|
-00000310  03 03 00 a4 dc 79 73 47  d4 f5 72 c9 12 46 ed 3c  |.....ysG..r..F.<|
-00000320  d0 61 20 81 a9 ad 64 f3  f1 77 7f f1 74 09 67 80  |.a ...d..w..t.g.|
-00000330  c1 08 07 9c 50 b8 7d f5  70 f5 c6 a1 5f ba 37 78  |....P.}.p..._.7x|
-00000340  58 37 e3 f4 3f 03 1d 69  6f af 2f 2b 8b 10 95 5a  |X7..?..io./+...Z|
-00000350  be a1 5c b8 42 61 65 5a  27 35 f6 b4 57 3d 3a 6b  |..\.BaeZ'5..W=:k|
-00000360  f4 e9 90 88 7b e3 7c bf  be 51 19 0e 51 53 cd 10  |....{.|..Q..QS..|
-00000370  2c 70 76 9e d1 32 28 8f  c4 6c 01 2c 46 8f 4d 14  |,pv..2(..l.,F.M.|
-00000380  21 a2 63 39 44 b3 03 0d  a3 9d a0 c8 f4 cf 5d 7e  |!.c9D.........]~|
-00000390  d2 17 05 ee 9c 5c 1a 2e  43 dc 3f 6d d9 f2 54 5d  |.....\..C.?m..T]|
-000003a0  64 ff d2 1c 21 73 66 b1  2c 21 9d 3f bf fe f8 a5  |d...!sf.,!.?....|
-000003b0  79 54 fe 8a d5 3d 5f f6  17 03 03 00 35 0f 01 eb  |yT...=_.....5...|
-000003c0  f8 46 f8 07 7a 06 69 45  e2 47 4d b0 eb 9c 82 8b  |.F..z.iE.GM.....|
-000003d0  5d d0 59 66 d1 b5 a2 7b  b2 f0 72 6f 34 8b 2c 05  |].Yf...{..ro4.,.|
-000003e0  84 53 1c 7b 24 d8 f0 cd  a3 46 d1 ed 08 22 bb e6  |.S.{$....F..."..|
-000003f0  38 98                                             |8.|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 94  |..+.....3.$... .|
+00000060  e8 ab 87 65 c8 dd 6f ee  b4 d6 0b bb fd 18 9a 2d  |...e..o........-|
+00000070  e4 bc c6 20 98 09 71 65  7d 54 35 73 22 99 1b 14  |... ..qe}T5s"...|
+00000080  03 03 00 01 01 17 03 03  00 17 37 b7 eb eb a2 9f  |..........7.....|
+00000090  7f 00 8c 9d a9 50 7c 0c  15 31 63 71 45 7a 3d ee  |.....P|..1cqEz=.|
+000000a0  5e 17 03 03 00 42 9f 23  07 cf d0 bc e8 bb 95 01  |^....B.#........|
+000000b0  37 94 18 2e 05 02 8a eb  0a 37 10 79 51 a9 d4 43  |7........7.yQ..C|
+000000c0  18 18 e6 00 9d 68 ff 74  f3 9c 19 bf 5e 51 0c 47  |.....h.t....^Q.G|
+000000d0  61 35 8c b2 58 5f 32 bc  88 c4 fb 5a 22 61 14 98  |a5..X_2....Z"a..|
+000000e0  28 26 8c 75 9d 1d 19 05  17 03 03 02 22 d2 2c 1a  |(&.u........".,.|
+000000f0  e5 58 0d d7 0b c4 66 b2  06 90 bc 92 0f 05 34 5d  |.X....f.......4]|
+00000100  2b 20 26 02 cc ac 90 40  a0 f1 5f 0e b9 99 7c 0f  |+ &....@.._...|.|
+00000110  c9 3e 60 0b 39 ec 6c 94  3a d4 f7 b7 49 5e c7 6e  |.>`.9.l.:...I^.n|
+00000120  df 3b cc 33 cb 32 41 53  dd 09 8e 91 97 d2 e0 06  |.;.3.2AS........|
+00000130  5e 0c 4c 49 46 18 83 fc  ac b4 f8 76 2d 18 ee 0b  |^.LIF......v-...|
+00000140  b6 4a b9 aa eb ee db 7a  aa 6d 04 84 ed 8e 15 bc  |.J.....z.m......|
+00000150  bf 6f a1 29 bc 0b 9f ba  05 a5 42 82 fd 1c 30 c9  |.o.)......B...0.|
+00000160  20 df 8e ba 28 ab 0b a2  42 09 5e e8 c1 61 d2 25  | ...(...B.^..a.%|
+00000170  fc 05 53 62 91 45 29 54  60 31 b8 4f 01 9c 7b 6a  |..Sb.E)T`1.O..{j|
+00000180  04 27 df bc e0 a0 3d b3  80 73 22 ca 9b 41 be b6  |.'....=..s"..A..|
+00000190  09 22 67 1e 54 52 ce 14  b5 56 7a ca 3f a8 3e 01  |."g.TR...Vz.?.>.|
+000001a0  d2 e4 36 18 87 f6 08 19  55 d2 ba 3c a3 c5 11 84  |..6.....U..<....|
+000001b0  62 2a 09 c6 67 de cd ab  66 12 dd 0a 23 77 18 b7  |b*..g...f...#w..|
+000001c0  73 c1 29 61 52 32 95 eb  a0 db 72 ae b7 ff 2a b2  |s.)aR2....r...*.|
+000001d0  08 f6 d7 69 32 c2 f8 8b  e1 40 a9 d0 fe 11 64 a2  |...i2....@....d.|
+000001e0  a2 dd a7 e6 a6 dd 5d 79  49 df bb c0 83 da 56 7a  |......]yI.....Vz|
+000001f0  a5 22 8e 60 df 89 48 e0  e2 e9 5f d5 fe dd ba 34  |.".`..H..._....4|
+00000200  ad 91 52 d8 2f 7e a4 73  50 e8 b7 83 e2 d9 5e 05  |..R./~.sP.....^.|
+00000210  96 08 e4 d4 bb 01 39 99  aa 1d fd 74 1b dc ca c2  |......9....t....|
+00000220  8f bb b8 bf c4 eb 00 6f  cc 70 eb 7c c7 29 e4 64  |.......o.p.|.).d|
+00000230  8c 76 a7 b5 79 ea b6 96  fe eb 8f e7 81 9b d1 d0  |.v..y...........|
+00000240  41 16 db ef 9e 55 2a 77  6c 34 54 22 48 6a ca 78  |A....U*wl4T"Hj.x|
+00000250  31 6e d2 00 7f 54 93 65  ec 28 42 66 7b 74 4d 58  |1n...T.e.(Bf{tMX|
+00000260  fe 25 74 bd 9f a4 ff f2  45 06 c6 63 1f 11 68 a4  |.%t.....E..c..h.|
+00000270  fb fe 62 2b f8 19 e3 32  2c cc 5d 71 37 21 05 82  |..b+...2,.]q7!..|
+00000280  c9 c7 30 c7 74 64 d9 f9  6b c2 ae d8 15 2b 2a 79  |..0.td..k....+*y|
+00000290  a0 2d a3 18 1f d7 20 99  96 86 52 32 cf 84 bd 73  |.-.... ...R2...s|
+000002a0  63 85 82 a3 64 fb e3 ea  1b 31 f5 df 1c 74 06 48  |c...d....1...t.H|
+000002b0  69 8a e3 f0 72 8c 59 8b  de 0b 06 02 47 54 4c 2d  |i...r.Y.....GTL-|
+000002c0  46 ac d4 f5 4d 5c fe 0d  bf af d0 37 58 82 3e d2  |F...M\.....7X.>.|
+000002d0  4e c1 7e 0f b0 21 f7 8e  2c 88 db 83 43 ed ad 5b  |N.~..!..,...C..[|
+000002e0  0f a2 ce 47 e4 3f dd 1b  71 fe f0 a7 a1 8d 8c dc  |...G.?..q.......|
+000002f0  75 e0 7a 89 f7 14 5b 37  9d 35 f6 23 91 a8 d2 1a  |u.z...[7.5.#....|
+00000300  96 07 1b 5b 9c 35 27 b8  b9 0c 92 1e cf 1b 3c 17  |...[.5'.......<.|
+00000310  03 03 00 a4 f0 59 e1 1d  62 39 69 c5 53 ae 66 85  |.....Y..b9i.S.f.|
+00000320  df ea 32 73 ca 94 e2 b5  14 d4 30 07 dd fd 2f 9a  |..2s......0.../.|
+00000330  16 fc e9 71 4a 20 b8 d2  7e 17 26 ff a9 55 56 24  |...qJ ..~.&..UV$|
+00000340  31 85 bc ea 19 1c 37 b7  fe 8b 47 5f a3 99 0f 5d  |1.....7...G_...]|
+00000350  17 92 4b 2a 4c b5 6c db  8f bb 46 ee 89 31 53 79  |..K*L.l...F..1Sy|
+00000360  aa 34 9d 9b e8 9b e7 82  55 a3 92 f6 53 53 d3 72  |.4......U...SS.r|
+00000370  17 23 33 01 e8 75 7e 8d  63 91 a0 67 8f a5 f0 15  |.#3..u~.c..g....|
+00000380  8c f5 81 e2 c4 08 ff 14  1d 96 cf ef 4e 09 18 a1  |............N...|
+00000390  2c 38 0a f7 33 f0 1d ef  9d 12 4d 8c 25 f0 80 a2  |,8..3.....M.%...|
+000003a0  aa a7 cf e4 7c e6 44 58  6d 30 70 48 55 3b b5 79  |....|.DXm0pHU;.y|
+000003b0  55 aa 03 ed 14 ea e5 ee  17 03 03 00 35 72 1a ca  |U...........5r..|
+000003c0  5c 3d 3b 75 29 cc a9 09  85 67 89 37 18 91 c0 af  |\=;u)....g.7....|
+000003d0  28 d2 0c c9 8b 05 94 04  3a 68 38 f0 c3 db 95 89  |(.......:h8.....|
+000003e0  c8 28 fc 07 4b 49 7d b6  25 36 05 53 96 e0 d9 35  |.(..KI}.%6.S...5|
+000003f0  e5 7c                                             |.||
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 02 11 ce 65 5f 9d 1a  |............e_..|
-00000010  c6 5f 48 ea da 02 77 1d  79 b2 82 1a da c4 75 aa  |._H...w.y.....u.|
-00000020  11 af ae 1f e4 7e d7 6f  ed 75 48 56 de c8 36 05  |.....~.o.uHV..6.|
-00000030  6a 97 5e 49 49 55 25 6f  ef 3e ed 40 3f 91 9a ae  |j.^IIU%o.>.@?...|
-00000040  f4 a1 d3 02 d3 15 60 23  1b 7a 80 ef ef 60 bb 62  |......`#.z...`.b|
-00000050  a3 8d 6b 24 1a 11 7d 8e  00 76 54 69 f1 b5 df 77  |..k$..}..vTi...w|
-00000060  c0 3a a3 8d 9d a3 56 e7  4d 2d 68 fe 38 49 6d 42  |.:....V.M-h.8ImB|
-00000070  3d 2c 69 fd 8c 53 44 af  13 8b 1d cb dc 04 16 6e  |=,i..SD........n|
-00000080  5a ab 0a 00 19 cf a0 8a  ee bd 71 24 68 ee 18 2a  |Z.........q$h..*|
-00000090  ec 04 fe 0f 12 15 8e 09  e0 87 de 4e c4 2a a1 a5  |...........N.*..|
-000000a0  6d be 79 6e 25 15 11 64  8c 35 71 97 fa a4 43 e2  |m.yn%..d.5q...C.|
-000000b0  dd cd a1 da b3 75 5d d5  36 fb b4 6b 12 30 a7 f6  |.....u].6..k.0..|
-000000c0  d7 7c 72 e1 f8 6a 8b 3e  38 13 9c da ee 07 3d 6a  |.|r..j.>8.....=j|
-000000d0  f5 1b 26 73 ff 24 03 1f  ea dc f3 ed 6b c2 0d fe  |..&s.$......k...|
-000000e0  3e 03 c4 22 93 c9 9b fe  22 5c 1e fb 07 2b 1b 7f  |>.."...."\...+..|
-000000f0  34 ff c6 1b 24 32 4b b1  ee 4c 0b 08 b6 3b 1e aa  |4...$2K..L...;..|
-00000100  49 f3 04 b7 9a 42 e5 42  5a df a2 92 d3 2f 62 54  |I....B.BZ..../bT|
-00000110  e1 21 08 ee ce 64 80 48  d3 6a 15 67 8c 5e d1 ac  |.!...d.H.j.g.^..|
-00000120  a2 64 f9 10 67 2c 27 7e  10 11 d7 09 13 2f 61 a7  |.d..g,'~...../a.|
-00000130  d7 9d 2a 18 0f a8 93 c6  fc 75 5c 31 68 42 22 e6  |..*......u\1hB".|
-00000140  5c e8 4d 7d 82 73 ba 97  5c d7 6a a2 14 37 85 93  |\.M}.s..\.j..7..|
-00000150  48 a7 50 9c fc 66 7b 82  a8 b6 99 0f 8c 9e 40 b5  |H.P..f{.......@.|
-00000160  e4 4f 98 01 db 56 03 44  f9 9f 52 a3 33 ac 77 2a  |.O...V.D..R.3.w*|
-00000170  b6 0a de d5 68 a5 df 67  41 8d 4c 53 9d c4 8d b7  |....h..gA.LS....|
-00000180  2e 3d 1f 93 1c 23 e3 81  76 5a 99 7c 90 60 d8 4d  |.=...#..vZ.|.`.M|
-00000190  e4 a5 00 7d f9 2c c5 19  bc 3c a3 73 c3 83 ff 31  |...}.,...<.s...1|
-000001a0  6a 67 88 32 d3 90 7f ab  20 19 1f 55 72 e4 08 bc  |jg.2.... ..Ur...|
-000001b0  c4 d6 24 e6 00 2d 85 be  d4 9b 2c e5 7b ee 26 6b  |..$..-....,.{.&k|
-000001c0  49 ed 94 3d d6 ee fd 9d  da 39 be 02 23 aa b9 78  |I..=.....9..#..x|
-000001d0  f2 41 97 0a d9 66 15 1e  e1 a2 49 f3 09 f0 25 91  |.A...f....I...%.|
-000001e0  8a ea f5 38 87 ea 66 ae  dc d2 04 d1 02 92 ab 6c  |...8..f........l|
-000001f0  a4 1a cc 1b ba 48 d5 8e  27 c4 c5 34 08 8f c2 c8  |.....H..'..4....|
-00000200  e1 e6 a8 98 48 9c 43 6c  f1 34 ba c0 ff 8e 22 14  |....H.Cl.4....".|
-00000210  f7 f9 93 38 96 1e 73 57  28 5b 25 3e 17 03 03 00  |...8..sW([%>....|
-00000220  99 c7 8d 1d 62 23 f3 c1  31 3d 45 bc d5 59 ff 47  |....b#..1=E..Y.G|
-00000230  8e 34 3d 1d 06 cc e0 05  ea 38 87 f0 fd c3 84 53  |.4=......8.....S|
-00000240  47 6b fb 7b 9b c2 a4 f2  1f e0 61 ab 17 32 d0 57  |Gk.{......a..2.W|
-00000250  34 dd fb 42 9b ad 4c d7  20 ff b1 58 34 e0 0c b1  |4..B..L. ..X4...|
-00000260  44 0c cf d3 05 be 3b 8e  a2 d5 39 44 c8 22 64 ad  |D.....;...9D."d.|
-00000270  61 80 df 5d fd 40 0e c0  c2 41 4f a7 e5 4f b3 7f  |a..].@...AO..O..|
-00000280  0b db d6 ac fe ba c0 8b  24 8e e8 b2 d6 93 3d 12  |........$.....=.|
-00000290  75 41 85 1d b5 4a e2 e0  f8 a1 23 8f 13 24 c6 b6  |uA...J....#..$..|
-000002a0  e5 db 06 3f d8 d5 2f b5  e5 24 59 76 53 dd aa 0a  |...?../..$YvS...|
-000002b0  26 ba 72 23 63 ac 4d 5c  92 13 17 03 03 00 35 47  |&.r#c.M\......5G|
-000002c0  59 18 68 11 0a 9a 0b 66  d3 c0 26 72 da 51 0e 00  |Y.h....f..&r.Q..|
-000002d0  b0 78 8b 6a ef df 75 94  94 b0 aa 9b 77 e3 9c d8  |.x.j..u.....w...|
-000002e0  23 9d 74 ce 85 55 c0 30  4c 96 5b 59 7a f6 03 2e  |#.t..U.0L.[Yz...|
-000002f0  d8 9c 0e 11 17 03 03 00  17 74 ed 13 0b 6a 15 18  |.........t...j..|
-00000300  5e d4 5e 8a c6 e6 5c 0b  3c d0 1b 3d 68 86 2a 07  |^.^...\.<..=h.*.|
-00000310  17 03 03 00 13 6f e2 fe  a0 b8 95 d4 aa fd 11 2b  |.....o.........+|
-00000320  e8 6d 42 28 d1 ca 1c 5e                           |.mB(...^|
+00000000  14 03 03 00 01 01 17 03  03 02 11 6a 55 c4 ff 7a  |...........jU..z|
+00000010  5b c4 b7 cb 8d ad ae 53  53 3d 41 3a fc 16 44 fd  |[......SS=A:..D.|
+00000020  c8 5f 39 c3 5e 6b ee 7d  ea 88 9c a9 78 f9 dc 51  |._9.^k.}....x..Q|
+00000030  b2 90 68 7d ae 2c b7 90  6e 79 cf f4 97 50 95 87  |..h}.,..ny...P..|
+00000040  f1 f6 2c 14 bc 2b a3 68  0d e6 c8 66 2f 3b 89 72  |..,..+.h...f/;.r|
+00000050  67 4d d8 e9 8d 6a 89 2a  f9 e4 c1 b5 c0 92 16 25  |gM...j.*.......%|
+00000060  61 a6 98 ec b6 6b 52 8b  a5 80 5a 9e 6d 03 ad 42  |a....kR...Z.m..B|
+00000070  a9 46 2f d8 e5 67 c9 8d  89 f7 34 93 82 7c a3 bb  |.F/..g....4..|..|
+00000080  48 62 06 90 5c 5a aa fd  7c 71 88 24 22 f9 6a 2c  |Hb..\Z..|q.$".j,|
+00000090  d1 d9 7e 0a 4c 39 11 e8  c0 17 1d 83 64 f2 2b c6  |..~.L9......d.+.|
+000000a0  c0 81 8c 6a 39 a9 09 aa  1e 58 eb 30 88 59 4d f2  |...j9....X.0.YM.|
+000000b0  d2 64 9f 4c 90 29 c0 66  94 e3 df 12 9c 75 33 24  |.d.L.).f.....u3$|
+000000c0  fb 14 bc 70 e1 b5 de 54  28 b0 3f 01 2c 2e 5f 35  |...p...T(.?.,._5|
+000000d0  e3 01 59 2a 3f ce ca 11  bb 29 97 03 f6 f4 30 b9  |..Y*?....)....0.|
+000000e0  66 db 3c f7 06 41 7b e8  f8 af 3e 03 65 2f 5f 88  |f.<..A{...>.e/_.|
+000000f0  fd 30 45 7a c9 b4 9f bf  03 eb c9 dd 06 ac 82 06  |.0Ez............|
+00000100  e8 81 8e ea 29 45 78 5c  0f 8e 21 8a fb 0b 95 c1  |....)Ex\..!.....|
+00000110  63 e9 18 c1 9a a4 c6 7d  56 4b 9a de 96 dd 37 54  |c......}VK....7T|
+00000120  92 ef 71 42 a8 66 e7 df  e7 ea ec 4e 3c b3 8e 7d  |..qB.f.....N<..}|
+00000130  ed 92 da 86 e5 fa 51 f8  e4 b0 09 f3 06 4d 38 f1  |......Q......M8.|
+00000140  d5 5f d2 72 1e 5f c3 1e  1d fd 96 70 e7 9c ae ea  |._.r._.....p....|
+00000150  62 ce e4 a9 31 34 47 bc  f0 9f 1c c7 b6 66 f0 70  |b...14G......f.p|
+00000160  7a e1 c5 a9 76 64 d4 25  0f 56 cd 36 17 67 bd 4d  |z...vd.%.V.6.g.M|
+00000170  c7 78 d8 23 46 4b ac 46  34 1a d2 2d c5 e6 67 55  |.x.#FK.F4..-..gU|
+00000180  11 ec 8c f0 67 84 bf 89  ce 3c 71 4e 3a ab ff 22  |....g....<qN:.."|
+00000190  59 23 00 54 4b b6 9e c4  01 a1 9f e1 46 a6 a6 f3  |Y#.TK.......F...|
+000001a0  24 58 0c b4 6e 85 4c c1  8a d6 f8 02 c9 54 fb 85  |$X..n.L......T..|
+000001b0  c7 63 9b 47 28 10 a0 2d  b6 c2 83 16 71 ae a7 c2  |.c.G(..-....q...|
+000001c0  e0 dc 8b 6d 57 e0 4b a2  a8 5d 4d 8b ed 72 31 d6  |...mW.K..]M..r1.|
+000001d0  54 33 78 df bb 4a f9 58  9f 8c 2b 11 36 29 a0 f0  |T3x..J.X..+.6)..|
+000001e0  8a 95 20 d8 f1 8c 08 e1  54 0a 81 79 33 20 23 de  |.. .....T..y3 #.|
+000001f0  34 c8 2b 45 3a 59 c5 78  39 65 ea 70 e2 fe 59 4c  |4.+E:Y.x9e.p..YL|
+00000200  ed 7f 07 07 25 a7 ff fa  c9 c3 1f 33 55 c4 16 bb  |....%......3U...|
+00000210  c9 b9 e0 2e ff 94 7c de  84 30 60 d6 17 03 03 00  |......|..0`.....|
+00000220  99 53 44 d2 12 38 c4 a7  7e f5 f5 67 b3 79 cf 8a  |.SD..8..~..g.y..|
+00000230  34 0f 5d 49 0f bb 5f 30  c8 36 13 61 8d b5 b1 b0  |4.]I.._0.6.a....|
+00000240  dc 73 2f 1a 51 2f d4 8e  25 71 e1 46 af 11 96 19  |.s/.Q/..%q.F....|
+00000250  f7 fe 09 d9 6e 70 d5 fc  b9 5b 1c ae ed 06 37 af  |....np...[....7.|
+00000260  a1 bf 35 c6 6b 30 33 a2  c4 f6 c8 d4 73 34 73 8e  |..5.k03.....s4s.|
+00000270  69 08 be 91 2c 8d 01 52  30 14 b3 d3 a0 7d 8a 9d  |i...,..R0....}..|
+00000280  e9 af b2 77 64 eb 16 c1  8e 19 72 ad 4a fd d4 c9  |...wd.....r.J...|
+00000290  08 d0 54 6c f1 06 8c 70  2f e6 ef 23 23 67 96 db  |..Tl...p/..##g..|
+000002a0  5f aa 81 6c 41 17 6b f4  30 ce 00 d6 a2 d8 28 f8  |_..lA.k.0.....(.|
+000002b0  be 9f 04 94 fa e3 fa 76  d0 30 17 03 03 00 35 9b  |.......v.0....5.|
+000002c0  43 c4 8f dc b7 a1 44 4e  00 66 0a 95 a6 d7 46 79  |C.....DN.f....Fy|
+000002d0  30 2d 57 51 4e 21 a7 ed  43 e7 22 2d eb 07 9b 7d  |0-WQN!..C."-...}|
+000002e0  ea a4 ff 14 5d 97 1f d5  e8 f1 3d 8d e3 13 b6 79  |....].....=....y|
+000002f0  36 ce 83 e8 17 03 03 00  17 d5 98 a6 a3 b7 40 2b  |6.............@+|
+00000300  26 87 2f 4f 64 95 f1 2d  e0 7b e3 98 c2 81 dc 7b  |&./Od..-.{.....{|
+00000310  17 03 03 00 13 5b ab 65  e4 b1 d0 bd e9 c6 b2 3a  |.....[.e.......:|
+00000320  4b 66 ce eb 25 0c bc 7d                           |Kf..%..}|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-RSAPSS b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-RSAPSS
index 9488dd6..2367a39 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-RSAPSS
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-RSAPSS
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,128 +16,128 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 6d 36 ae 02 a9  |....z...v..m6...|
-00000010  74 ad e5 4d 55 b6 4a 70  c6 f5 cf d5 68 d9 2a 5f  |t..MU.Jp....h.*_|
-00000020  9b 4b 23 ce 38 9b f3 da  44 72 7d 20 00 00 00 00  |.K#.8...Dr} ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 a9 f1 13 c3 3c  |....z...v......<|
+00000010  1c dd c9 3a a1 ad 92 92  f1 f4 16 39 be 14 64 9c  |...:.......9..d.|
+00000020  66 d8 28 cd b7 bb 40 43  ec f4 67 20 00 00 00 00  |f.(...@C..g ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 ba  |..+.....3.$... .|
-00000060  2a 76 cb fb 6c 6b bb 30  fb ef 87 6f e5 06 5c 6f  |*v..lk.0...o..\o|
-00000070  78 a7 44 41 93 c0 33 89  be 32 8c 0f fa 5c 43 14  |x.DA..3..2...\C.|
-00000080  03 03 00 01 01 17 03 03  00 17 ac 3e 8a 31 22 16  |...........>.1".|
-00000090  d3 69 bf 1d b5 2e 18 23  b3 21 00 17 23 a4 3f 9a  |.i.....#.!..#.?.|
-000000a0  0b 17 03 03 00 20 aa f0  51 64 b5 44 f0 28 ab 56  |..... ..Qd.D.(.V|
-000000b0  da 34 2d 62 77 4d 88 07  b6 82 ad 64 df e6 59 c9  |.4-bwM.....d..Y.|
-000000c0  91 e5 f8 f2 67 88 17 03  03 02 7a cf 2d 71 db 3f  |....g.....z.-q.?|
-000000d0  05 45 b8 68 18 1c b9 66  b6 00 f8 dc 9d ae e5 d2  |.E.h...f........|
-000000e0  a3 a8 02 5f ac e4 95 a6  fc 96 78 7b fd 0a 21 62  |..._......x{..!b|
-000000f0  ff 7c 15 2c fb f1 21 15  1e 8d 9e f9 71 62 43 e4  |.|.,..!.....qbC.|
-00000100  c9 69 e4 fe 87 f0 9d 9e  aa a4 5c d8 4e ae 3c 38  |.i........\.N.<8|
-00000110  e5 76 21 7b 03 a8 70 6f  e8 96 39 34 e7 3c b9 51  |.v!{..po..94.<.Q|
-00000120  b4 ef ce 7d 0b 1e 57 7d  62 de 47 6a 0a b0 97 6d  |...}..W}b.Gj...m|
-00000130  49 fe ae 6f c9 d6 e4 4a  54 60 3d 55 53 06 aa 28  |I..o...JT`=US..(|
-00000140  7a 3e 7b e0 d1 8a 60 45  87 81 bf fc 98 13 1e de  |z>{...`E........|
-00000150  7a 90 73 81 13 91 3a c4  da 71 74 e0 1d d5 30 55  |z.s...:..qt...0U|
-00000160  46 6a 48 c2 0c 18 91 a3  79 8e c2 b9 5b 24 88 76  |FjH.....y...[$.v|
-00000170  5f e6 8f 24 91 95 5b 0d  38 39 5b a4 f6 0e 1a b8  |_..$..[.89[.....|
-00000180  e8 2b 0d ac a8 56 10 23  54 a5 78 c9 2a cb ed 24  |.+...V.#T.x.*..$|
-00000190  58 16 1a 2f 1c b7 72 fc  da ab 56 f6 27 d1 98 39  |X../..r...V.'..9|
-000001a0  1f f9 dd e0 1f 1f 23 1a  ff 6b af e1 17 9d ec 35  |......#..k.....5|
-000001b0  de 0b 4d a4 46 5a fd 07  56 ce 72 19 76 dc 0c 06  |..M.FZ..V.r.v...|
-000001c0  99 38 ce 58 3b 9f 13 9a  d5 b7 d6 08 a6 05 4d e1  |.8.X;.........M.|
-000001d0  75 da 59 4d ab d9 28 e8  af c4 50 f0 b1 49 f8 fd  |u.YM..(...P..I..|
-000001e0  c9 11 b8 01 70 bb 49 e2  0f 26 1b cb ee c2 7b bd  |....p.I..&....{.|
-000001f0  2f 72 78 be a1 67 1d 0c  d0 bb 4e e7 40 b3 bd 8c  |/rx..g....N.@...|
-00000200  e2 f4 4f b2 c5 4c 82 49  51 00 44 17 c6 82 72 f5  |..O..L.IQ.D...r.|
-00000210  cd 55 c1 43 28 52 85 2b  5d 91 33 9c 15 34 6e ae  |.U.C(R.+].3..4n.|
-00000220  77 4e 08 0c 9c d2 ae 7f  e8 83 af 60 96 10 ae dc  |wN.........`....|
-00000230  58 6a 3b ae 15 e5 9c a8  25 f3 69 71 f7 94 9c 75  |Xj;.....%.iq...u|
-00000240  e0 b5 05 16 ae ce f4 23  20 30 aa 74 a3 63 68 76  |.......# 0.t.chv|
-00000250  f6 ec 64 e1 3d f6 0e b6  c4 7d a8 08 44 a9 96 1d  |..d.=....}..D...|
-00000260  7d c8 22 a8 df 04 2c ad  65 f1 4c 99 7d a1 cb bd  |}."...,.e.L.}...|
-00000270  b7 d4 d7 b5 ee 88 bd 15  2e 75 76 e2 72 bb 7d e6  |.........uv.r.}.|
-00000280  5b eb fc f7 96 96 f0 3c  aa b6 a8 58 92 e9 29 f6  |[......<...X..).|
-00000290  40 bf 8e 14 23 7c 45 da  e9 17 4b 32 16 11 ec 74  |@...#|E...K2...t|
-000002a0  78 d5 8c 5a 06 46 e4 dc  90 b9 44 8e d6 8a 4e 43  |x..Z.F....D...NC|
-000002b0  7f f9 60 9e a1 46 fa 16  88 ab 3c f1 1e d0 2e 00  |..`..F....<.....|
-000002c0  5d 01 e6 a7 b1 27 f7 40  26 17 f3 da fb cd 06 d1  |]....'.@&.......|
-000002d0  4e 27 75 9a 6f 0b 63 82  9c 40 07 4c 6e 0d d8 4b  |N'u.o.c..@.Ln..K|
-000002e0  f1 e6 d5 1c 41 55 72 b5  43 24 53 1e 0e a4 08 d7  |....AUr.C$S.....|
-000002f0  44 93 00 c9 8b 49 ba 7a  32 0c d8 e6 46 87 5d 62  |D....I.z2...F.]b|
-00000300  9d 4a 11 04 67 21 19 42  50 ad ad ab dd 62 0f f7  |.J..g!.BP....b..|
-00000310  0f 57 78 82 71 f6 09 9f  41 bc 8e 34 24 7c b5 d2  |.Wx.q...A..4$|..|
-00000320  5d 0c 18 fb d8 f6 62 dc  57 6a 78 2c 21 35 d8 eb  |].....b.Wjx,!5..|
-00000330  bb f8 7e 01 63 50 c1 98  88 a4 b5 63 1e c0 68 3c  |..~.cP.....c..h<|
-00000340  41 3c b8 6e 48 17 03 03  00 99 b6 09 37 a6 c2 d9  |A<.nH.......7...|
-00000350  5f 39 69 e1 0b ca 40 d8  31 5b 4b 4f c1 33 bf 1f  |_9i...@.1[KO.3..|
-00000360  db c2 8c 9c d2 14 26 96  4e aa b2 63 30 40 fa 49  |......&.N..c0@.I|
-00000370  fb 2d 66 59 70 cb c7 f8  fe 59 19 8b eb d5 5c 6c  |.-fYp....Y....\l|
-00000380  5c a0 c9 ba e6 4d d9 c3  e0 fe 00 c4 fb ab 8a f1  |\....M..........|
-00000390  2b ab 53 86 a7 86 57 01  b8 ae c4 a6 12 6b 7d f8  |+.S...W......k}.|
-000003a0  ea 2d df 37 04 01 eb 14  f4 9a d0 e7 67 46 ec 9f  |.-.7........gF..|
-000003b0  35 f8 d4 2e c6 95 91 10  0e dc 01 60 9a d6 f8 d8  |5..........`....|
-000003c0  9e c1 fd f8 2e e2 51 8a  e9 2f c3 4a 4f 01 31 52  |......Q../.JO.1R|
-000003d0  af cb 4b 52 96 4c 90 57  83 1f 11 97 d6 d6 16 74  |..KR.L.W.......t|
-000003e0  77 f8 c4 17 03 03 00 35  b0 61 57 8f 52 7e 93 b1  |w......5.aW.R~..|
-000003f0  f0 90 a1 23 09 6e 11 ff  a5 6c 38 f3 31 11 be 03  |...#.n...l8.1...|
-00000400  ad 59 65 57 1b 60 2b fc  41 98 e0 79 6d 14 26 c8  |.YeW.`+.A..ym.&.|
-00000410  fb d6 5f 00 e0 cc 70 46  a3 81 e4 3c ff           |.._...pF...<.|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 ff  |..+.....3.$... .|
+00000060  53 ac b3 b0 48 47 d0 1e  b1 70 eb dd 02 e5 e8 07  |S...HG...p......|
+00000070  ce c7 e0 af d7 e0 46 c7  ff f5 97 30 e5 80 5b 14  |......F....0..[.|
+00000080  03 03 00 01 01 17 03 03  00 17 0b 12 ef 6d ea 5e  |.............m.^|
+00000090  71 41 83 d6 35 9f 39 2c  f0 ab 01 e9 03 54 c6 9e  |qA..5.9,.....T..|
+000000a0  37 17 03 03 00 20 15 7a  35 f4 a6 6e 65 89 10 ae  |7.... .z5..ne...|
+000000b0  18 31 c0 0c 15 1c b8 c5  5d f3 54 0c 98 32 a4 5e  |.1......].T..2.^|
+000000c0  91 f7 03 8a 80 b9 17 03  03 02 7a fa 93 7f c6 d1  |..........z.....|
+000000d0  2f 7e 2d d6 1b b7 ff fd  96 6e a1 f7 0e 98 dc 77  |/~-......n.....w|
+000000e0  cc 6a 4e 91 3d c1 ad 4b  5c 28 ee ea a7 0a ce 8f  |.jN.=..K\(......|
+000000f0  51 dd 89 fd 5a 81 6d 21  d6 0d 35 70 84 73 8c fa  |Q...Z.m!..5p.s..|
+00000100  2e 7a e0 af ab 79 79 aa  67 2b 80 a8 b3 a8 fb 0d  |.z...yy.g+......|
+00000110  eb 87 66 d5 be 33 0b f0  80 b8 5e 21 84 be 25 fe  |..f..3....^!..%.|
+00000120  47 98 5a 26 5d c3 96 2e  c5 b8 da 9f a6 d4 ca bb  |G.Z&]...........|
+00000130  de 7f 2c 0a 28 a8 f3 41  bc a2 2e 70 f2 b3 6f a3  |..,.(..A...p..o.|
+00000140  10 0e 1f 11 af 11 50 2b  22 84 97 d7 80 f5 62 77  |......P+".....bw|
+00000150  a6 94 47 22 ef 24 c6 0e  dc 5c f5 40 08 f7 21 78  |..G".$...\.@..!x|
+00000160  ae 11 f3 d8 a5 d8 20 ac  90 73 d7 a2 e3 f0 08 57  |...... ..s.....W|
+00000170  fc 74 70 66 fd 3d 49 c7  99 37 98 5e b1 1c c4 38  |.tpf.=I..7.^...8|
+00000180  64 09 e6 70 b6 8b 00 72  2d 5b b4 70 39 d6 e9 d5  |d..p...r-[.p9...|
+00000190  dc cd 8e 01 eb 5f 34 61  d0 97 62 0b 4f 81 ed 30  |....._4a..b.O..0|
+000001a0  64 56 f2 6e 31 5e 24 e8  56 2b d6 31 54 c4 48 47  |dV.n1^$.V+.1T.HG|
+000001b0  16 00 a7 65 c1 fa ea 12  30 78 41 e7 30 2d 71 cf  |...e....0xA.0-q.|
+000001c0  b0 e9 be e4 a2 33 38 87  2d 37 14 2d 03 cf ae 87  |.....38.-7.-....|
+000001d0  9a 09 f2 ed f3 44 66 c3  8a 56 8e e4 c4 aa e9 f7  |.....Df..V......|
+000001e0  cd 75 52 1b d9 ed 66 04  13 dd dd cf 0f 44 cd 18  |.uR...f......D..|
+000001f0  68 c5 2c 4c f9 e3 d3 02  12 78 38 5c f6 96 d7 80  |h.,L.....x8\....|
+00000200  f0 83 03 fe 7a e0 35 7e  a3 ad 99 52 ec fc ee 74  |....z.5~...R...t|
+00000210  f5 09 0f ca 69 f0 fb d0  40 90 1b 46 9e 2d 62 c9  |....i...@..F.-b.|
+00000220  0f 59 b2 cc a0 4a 9b 84  14 3a 1b 51 fc e7 e8 a1  |.Y...J...:.Q....|
+00000230  26 fd 20 8c 88 6f 87 11  ae 97 76 f8 4b cc 67 1a  |&. ..o....v.K.g.|
+00000240  3e 58 65 77 77 82 06 c0  d4 41 4e 66 d2 5a 83 b1  |>Xeww....ANf.Z..|
+00000250  ee 19 5d 7b 99 34 d3 2f  6c bd 30 a3 8c 75 89 ec  |..]{.4./l.0..u..|
+00000260  cb 90 8b 89 05 b8 e4 6e  3b 60 5d 0e 19 8f d6 c7  |.......n;`].....|
+00000270  86 f0 a9 2b c7 12 4a 4c  d8 a5 e8 64 49 1d 49 99  |...+..JL...dI.I.|
+00000280  a7 80 01 f0 77 57 4a 78  3c ac 38 40 bb d2 10 24  |....wWJx<.8@...$|
+00000290  9d e2 29 b2 1e 4b 50 66  64 07 79 80 c7 81 9d e2  |..)..KPfd.y.....|
+000002a0  f5 a9 10 9a 8d 3b de 0e  21 85 13 ac 26 30 f9 e4  |.....;..!...&0..|
+000002b0  a6 f9 8f e0 3c c1 69 7e  11 4c d1 a8 4e 88 30 fc  |....<.i~.L..N.0.|
+000002c0  52 6e b0 4f b6 7e 15 9e  a5 8a 46 ca 1f ac 8e 2a  |Rn.O.~....F....*|
+000002d0  07 34 d7 c2 14 c6 c1 ed  a1 f9 1e 59 b4 b4 86 3e  |.4.........Y...>|
+000002e0  d3 d0 78 a6 07 62 d3 88  80 54 a8 2a e9 38 2e 58  |..x..b...T.*.8.X|
+000002f0  43 94 cc ed f0 46 f6 cc  4b 7a b8 f5 a2 d6 a8 36  |C....F..Kz.....6|
+00000300  e2 8e 11 fb e7 21 19 c5  fa c9 90 98 72 43 88 ac  |.....!......rC..|
+00000310  c0 56 84 9e cd b7 e5 26  d6 49 19 88 a5 12 ac 49  |.V.....&.I.....I|
+00000320  5d 77 37 2a ff 38 5a 7a  5b c8 74 5d 74 fc 22 7f  |]w7*.8Zz[.t]t.".|
+00000330  46 97 2b 34 32 fb 83 65  75 b6 8b 5c 8a b1 d4 a2  |F.+42..eu..\....|
+00000340  14 7f 46 0d 63 17 03 03  00 99 c7 79 bb 4f 88 a0  |..F.c......y.O..|
+00000350  78 be 04 ca 39 1f 1f a8  82 59 b5 dd 96 93 0d c4  |x...9....Y......|
+00000360  30 f4 22 4c e2 52 51 d4  33 b8 35 7b ed 01 19 25  |0."L.RQ.3.5{...%|
+00000370  b5 31 36 25 23 a2 51 d9  7a a9 00 72 05 34 81 62  |.16%#.Q.z..r.4.b|
+00000380  d0 df 8b 3a 65 98 4e 87  e2 29 9b 44 77 8c dd c9  |...:e.N..).Dw...|
+00000390  4c a5 de 14 97 e0 f1 2c  e8 5d 0e 8f d0 fd f6 77  |L......,.].....w|
+000003a0  c1 1f ac 79 4d 32 19 09  98 a8 f0 2f 3e d5 7e f7  |...yM2...../>.~.|
+000003b0  aa c1 f0 36 b1 8e c7 0b  ce 09 00 ac 28 64 c0 33  |...6........(d.3|
+000003c0  58 cc 48 3a 15 a4 77 24  50 67 f2 39 53 4d 63 23  |X.H:..w$Pg.9SMc#|
+000003d0  48 74 bd 0a c8 02 17 be  e4 64 af 6e 02 a9 22 92  |Ht.......d.n..".|
+000003e0  65 04 c6 17 03 03 00 35  e0 4e 15 4b 9d 53 57 c6  |e......5.N.K.SW.|
+000003f0  97 b4 9d 1a 03 39 26 b9  ca 5b 04 50 af db 52 99  |.....9&..[.P..R.|
+00000400  d9 13 40 6a 89 23 99 42  9a 91 1d d1 6c 07 a0 aa  |..@j.#.B....l...|
+00000410  05 6e 60 0b fd e7 de 32  c3 97 18 0d 9b           |.n`....2.....|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 02 7a 22 a3 3d 18 f8  |..........z".=..|
-00000010  a2 c7 8e 62 c3 07 99 b4  e6 bd 94 79 12 82 e9 e0  |...b.......y....|
-00000020  96 ff 5f c3 ec 34 02 2f  8d 95 2f 40 80 99 19 a3  |.._..4./../@....|
-00000030  bd 64 fd e4 0e b3 81 ad  4c 2e d9 72 d2 a3 bd 00  |.d......L..r....|
-00000040  81 42 78 5d f3 70 c3 78  0b fa cd b8 96 17 5e e7  |.Bx].p.x......^.|
-00000050  6e 03 b8 c6 ab 2b 2e 63  45 c7 b1 c9 98 71 c9 1d  |n....+.cE....q..|
-00000060  bb 7b 6e 6d c7 d5 90 b8  b2 4e 62 1a 8f cf 7d 99  |.{nm.....Nb...}.|
-00000070  52 3d 70 40 0f 0f 96 1c  ee a7 ff 29 2a 53 de d4  |R=p@.......)*S..|
-00000080  34 f9 d9 b2 33 2c 69 5e  2d f2 a7 62 dd ec 77 b1  |4...3,i^-..b..w.|
-00000090  6c 0f 61 86 8a bc 11 1f  91 ad f4 94 de 96 dd ef  |l.a.............|
-000000a0  d8 be 5e 45 50 fe af 1a  03 54 20 f6 05 8e a3 b0  |..^EP....T .....|
-000000b0  f7 31 93 f3 78 59 4d 54  50 99 a5 a1 53 81 1b 5d  |.1..xYMTP...S..]|
-000000c0  6d ea 32 e9 52 ab 83 d6  18 3f 2f 43 cd 64 ac 3f  |m.2.R....?/C.d.?|
-000000d0  11 6c 91 0d fa 86 f8 a5  12 eb 41 ac 24 2d 79 5b  |.l........A.$-y[|
-000000e0  ee 8e 02 46 f0 37 0a b1  19 c7 97 ed 97 d1 11 18  |...F.7..........|
-000000f0  df 80 8f f3 d7 61 a4 fe  6c ec b0 80 4e bc e4 52  |.....a..l...N..R|
-00000100  10 2f b1 6f 3f d4 39 08  81 f6 01 4b b4 d4 d5 20  |./.o?.9....K... |
-00000110  6b a1 be e6 cf c7 0e 95  e9 d7 00 07 63 25 1b 64  |k...........c%.d|
-00000120  4b b7 c4 79 29 84 45 45  5d 0d fe 72 2a 7e c6 bf  |K..y).EE]..r*~..|
-00000130  5a 98 ec e2 16 26 82 57  eb a6 dc ff 73 b6 e8 4c  |Z....&.W....s..L|
-00000140  87 52 e5 0a c1 6a 6f 02  69 17 17 ea e0 1c c1 07  |.R...jo.i.......|
-00000150  b4 f4 78 a7 99 39 8b 63  61 c2 7e 99 f4 64 16 d6  |..x..9.ca.~..d..|
-00000160  0a 84 9a 0f d4 f4 bd 4d  d4 4f 16 ec 19 30 a7 34  |.......M.O...0.4|
-00000170  f9 b9 60 10 39 25 ee 9d  bd 99 37 52 e6 32 a1 c9  |..`.9%....7R.2..|
-00000180  68 9b a2 4e 16 91 0e 54  54 d5 c5 77 bb 01 ba af  |h..N...TT..w....|
-00000190  97 be ea 09 85 91 69 84  4f 2c 04 f0 38 50 93 49  |......i.O,..8P.I|
-000001a0  e7 41 cb c1 d6 b6 77 59  09 7c 1e 0a 58 93 1e b4  |.A....wY.|..X...|
-000001b0  cf ed 32 85 b0 cd 6f 86  c7 94 8c 30 9d 83 a2 a0  |..2...o....0....|
-000001c0  4a de ad 8c b9 d8 58 d3  8c 34 6b 12 54 f1 28 66  |J.....X..4k.T.(f|
-000001d0  ea 55 d9 95 d0 b6 b3 aa  68 c3 31 e1 8f 1b f8 43  |.U......h.1....C|
-000001e0  51 b9 06 fc 53 69 9b 1c  e6 2c f8 b7 f0 47 4a 5a  |Q...Si...,...GJZ|
-000001f0  82 ca 27 df 0f 3d f8 79  90 8d c2 bd 27 85 74 6b  |..'..=.y....'.tk|
-00000200  9e 8b eb 74 a8 28 ba 6a  25 16 01 2c 56 3b c0 fa  |...t.(.j%..,V;..|
-00000210  91 ac af a7 c5 39 8d 2c  b1 f3 a2 c9 a5 72 c6 ff  |.....9.,.....r..|
-00000220  49 a0 78 14 5c 8c d2 71  de b9 4f 55 3a ca b6 a5  |I.x.\..q..OU:...|
-00000230  df ce bb f7 c2 d5 af 2c  c0 97 08 82 cc b4 02 26  |.......,.......&|
-00000240  c3 0c 99 39 4a df 6c d6  59 14 c4 d6 04 9d a4 92  |...9J.l.Y.......|
-00000250  d2 53 42 16 56 99 5f c2  82 a0 a8 5a 92 53 e6 b1  |.SB.V._....Z.S..|
-00000260  cd fc bc 9a b9 55 0b ae  2c 50 ce a3 bf d2 7d d2  |.....U..,P....}.|
-00000270  2b 58 ba 87 65 33 09 cf  74 51 0f 4b 4f a9 53 0d  |+X..e3..tQ.KO.S.|
-00000280  fa 60 1e ba e6 17 03 03  00 99 aa 43 d9 e2 e4 91  |.`.........C....|
-00000290  cf 65 fa 35 0e b0 21 51  9d c4 33 f5 7c 09 ff e5  |.e.5..!Q..3.|...|
-000002a0  db fd 6e 96 6d 13 7c 4c  ec 90 72 bd 54 6a 3f d8  |..n.m.|L..r.Tj?.|
-000002b0  1a a3 e2 a2 01 6b d6 50  a0 b1 d5 67 34 44 42 30  |.....k.P...g4DB0|
-000002c0  97 2e 82 07 46 04 56 0a  43 4b 9d 8c 81 64 bb 0b  |....F.V.CK...d..|
-000002d0  21 62 ea 23 0b 1c a0 c4  b2 cc 2f 51 b5 a2 9a a3  |!b.#....../Q....|
-000002e0  37 d3 0c 57 80 85 77 3b  8d 17 f1 a9 d5 ae 72 f9  |7..W..w;......r.|
-000002f0  cd 8c c4 2c fb c7 e0 f0  3a 5c d5 6a f7 8f 7e 53  |...,....:\.j..~S|
-00000300  c1 d0 7a b0 8d c9 b3 17  7c 99 df 54 d6 43 13 d5  |..z.....|..T.C..|
-00000310  78 9c 34 7e c9 11 4e e7  1c 8c f4 0f 82 89 94 61  |x.4~..N........a|
-00000320  80 d2 49 17 03 03 00 35  aa cd 97 5a a2 d3 27 78  |..I....5...Z..'x|
-00000330  d4 79 28 a7 57 dc 4f b1  2d b8 bd 3c ae ec e6 be  |.y(.W.O.-..<....|
-00000340  33 be b9 20 3b 69 22 03  31 34 7a 8d 68 39 c7 d5  |3.. ;i".14z.h9..|
-00000350  a1 a0 aa 46 15 94 93 d7  54 41 5b 6b 20 17 03 03  |...F....TA[k ...|
-00000360  00 17 f2 60 ff 91 c2 85  55 ed ab 39 6f 5d 0f 22  |...`....U..9o]."|
-00000370  45 3e 61 07 14 a3 05 f4  94 17 03 03 00 13 01 ea  |E>a.............|
-00000380  95 52 29 1c 63 71 3a 2d  73 a7 29 31 2c d0 ce 9f  |.R).cq:-s.)1,...|
-00000390  2b                                                |+|
+00000000  14 03 03 00 01 01 17 03  03 02 7a 94 78 2d 5d 5a  |..........z.x-]Z|
+00000010  3e 96 7f 19 29 51 99 f3  6e d3 a4 d5 3c 9a 3d d5  |>...)Q..n...<.=.|
+00000020  37 bc 3b 71 b3 54 83 d9  5e 9d 64 76 f9 74 7a 24  |7.;q.T..^.dv.tz$|
+00000030  e3 cb ea aa 17 f4 44 41  73 71 39 d6 9b d5 a6 a2  |......DAsq9.....|
+00000040  6a 1e 1c 02 a1 d5 e3 e8  f5 f7 07 9d 3b ea f8 6d  |j...........;..m|
+00000050  80 cf 6b 14 71 b8 bd c4  8a 07 49 31 e7 bd d5 91  |..k.q.....I1....|
+00000060  ac 80 70 25 5e f4 db 07  ed 36 c2 3a 1d ad 86 6e  |..p%^....6.:...n|
+00000070  68 1a ca 4f a1 ba c3 2f  de 49 01 fa a9 39 a6 51  |h..O.../.I...9.Q|
+00000080  3a e6 9f cf 6b 02 4e 1e  70 dd f2 10 c2 62 9b 1f  |:...k.N.p....b..|
+00000090  83 10 fa 85 52 a8 a7 08  37 9c 92 b0 9c fe 00 78  |....R...7......x|
+000000a0  0b a4 7b b5 f9 9f 87 d2  d3 07 72 b2 ab 96 9e 73  |..{.......r....s|
+000000b0  55 3c 1e 65 99 89 36 78  7e 42 8f 05 de b6 fb fc  |U<.e..6x~B......|
+000000c0  1b 34 18 e6 4d 15 6c d1  2f 2c b0 ef 00 e9 07 89  |.4..M.l./,......|
+000000d0  ca 91 d9 c1 73 bf 8f a5  a4 7d 7e cc f5 85 fb af  |....s....}~.....|
+000000e0  57 70 35 63 71 d6 78 57  13 48 27 ba a4 42 22 c2  |Wp5cq.xW.H'..B".|
+000000f0  56 f4 ae 38 39 a0 1f 57  44 57 c4 8a 70 90 30 70  |V..89..WDW..p.0p|
+00000100  ba 4a 98 29 0f aa e2 33  27 24 ee d9 e9 02 80 68  |.J.)...3'$.....h|
+00000110  4c 55 08 fb 3d 25 d6 d4  9d 83 ea 14 99 c2 77 94  |LU..=%........w.|
+00000120  f9 70 34 a8 ed 35 e6 4f  c2 75 50 63 d5 9d 9a 89  |.p4..5.O.uPc....|
+00000130  8f 2e 5b ca 6b b3 ad e7  a2 c6 f7 0c 45 08 b7 f4  |..[.k.......E...|
+00000140  58 d3 d5 54 c2 67 f3 76  fb fc 9d fe 42 43 ea 90  |X..T.g.v....BC..|
+00000150  2b 29 e7 10 2f d7 9c 04  c4 cc 89 8f a9 36 14 f6  |+)../........6..|
+00000160  fc f1 25 6c 90 12 bf c6  cd ad 46 ce 17 3b 26 fb  |..%l......F..;&.|
+00000170  c6 98 cb 6c f2 2c fd b9  2f 52 3e 56 42 78 0b 92  |...l.,../R>VBx..|
+00000180  a5 27 56 18 3d d6 26 3f  e4 a1 6f ce c8 f1 f1 7a  |.'V.=.&?..o....z|
+00000190  1f 84 66 c9 d9 8a 5c 0e  34 80 ba 58 b3 8b 7f f3  |..f...\.4..X....|
+000001a0  8a c9 6b c4 99 94 2c b7  e8 e8 9a a5 43 75 f8 e0  |..k...,.....Cu..|
+000001b0  29 1f 70 77 c7 4a 9f de  ca 92 88 7c 37 12 d9 ef  |).pw.J.....|7...|
+000001c0  2f 94 de ea d1 d9 69 6a  93 06 36 e0 68 02 53 ae  |/.....ij..6.h.S.|
+000001d0  0e 00 cd ad d3 10 a7 89  2c 53 a7 03 d9 07 3c e9  |........,S....<.|
+000001e0  0b b0 18 2e 03 88 03 5c  f4 b2 7e 59 f4 22 8c f7  |.......\..~Y."..|
+000001f0  5e d7 c7 ea ac 0f bc f7  3e 3f 75 fd 6d 9c 4c 3c  |^.......>?u.m.L<|
+00000200  41 8d f5 30 17 20 83 c3  27 83 ce 84 6a e3 75 2b  |A..0. ..'...j.u+|
+00000210  9d 7d de 2a bf 5a fb e1  2f 80 74 74 f6 09 bc 1f  |.}.*.Z../.tt....|
+00000220  be f0 59 9e ce a1 62 46  54 a4 9a 25 97 b7 cd 1a  |..Y...bFT..%....|
+00000230  0a d0 44 f6 ea a4 ed 63  e7 49 9a 4b f4 1a 39 91  |..D....c.I.K..9.|
+00000240  e6 34 e1 7b dd e7 53 ab  83 56 57 b2 89 3f 90 1f  |.4.{..S..VW..?..|
+00000250  98 c4 64 27 b5 f5 f6 57  16 ca d9 0a 33 de 24 c3  |..d'...W....3.$.|
+00000260  f3 7c 23 37 94 93 c5 1a  42 da 18 6b 24 dd 37 54  |.|#7....B..k$.7T|
+00000270  ae f3 8a 3e 10 42 20 6e  49 23 1a 0f bd 65 7e 45  |...>.B nI#...e~E|
+00000280  12 7a 64 9a 30 17 03 03  00 99 af 41 cf 95 21 1f  |.zd.0......A..!.|
+00000290  34 df 1c c7 a8 b6 ee 31  8d b3 9e 5a 59 8e c4 37  |4......1...ZY..7|
+000002a0  79 a4 d8 75 22 da 12 21  e5 de d4 ad 98 17 e2 ae  |y..u"..!........|
+000002b0  ae 9f f6 e8 29 66 d0 ac  b4 08 16 24 40 67 9d d5  |....)f.....$@g..|
+000002c0  bf a4 64 91 a1 17 82 c0  e7 77 b6 20 26 4a 70 1d  |..d......w. &Jp.|
+000002d0  c8 f8 ec 18 b7 c6 3c 81  b9 c6 04 9c 0d 37 a6 39  |......<......7.9|
+000002e0  fd 2d 99 d7 ba 41 a4 91  60 f1 1f d2 76 76 aa 47  |.-...A..`...vv.G|
+000002f0  89 0a d1 97 0b 91 20 a9  43 c9 ce 2c 84 ba 81 7a  |...... .C..,...z|
+00000300  39 91 7d 12 75 05 8e 87  b1 3f 80 8d 12 ca 8f 91  |9.}.u....?......|
+00000310  23 84 28 11 c3 81 ed 09  05 16 6e 50 57 76 ad 5c  |#.(.......nPWv.\|
+00000320  c5 92 77 17 03 03 00 35  5a d9 15 29 1f a3 f0 cf  |..w....5Z..)....|
+00000330  74 c4 1d 0c c3 fa 54 59  1e 54 06 0d 1b ce 07 00  |t.....TY.T......|
+00000340  f9 66 3d e1 75 10 cf de  cb 7d 0d d6 d1 4d 87 81  |.f=.u....}...M..|
+00000350  13 ec 2c 28 13 a5 b3 01  c7 86 3a 84 65 17 03 03  |..,(......:.e...|
+00000360  00 17 b4 e4 18 61 62 04  b3 ca 98 36 93 42 a2 be  |.....ab....6.B..|
+00000370  2c f5 18 11 bd 7d 64 70  bc 17 03 03 00 13 32 65  |,....}dp......2e|
+00000380  fa 07 3e 3c ed 9d 85 31  ba 8e 92 ea de 17 59 cd  |..><...1......Y.|
+00000390  db                                                |.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ECDSA b/src/crypto/tls/testdata/Client-TLSv13-ECDSA
index 098f3ab..dac9ef7 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-ECDSA
+++ b/src/crypto/tls/testdata/Client-TLSv13-ECDSA
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,71 +16,71 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 e8 ec ee 61 3e  |....z...v.....a>|
-00000010  c1 43 87 6d f1 61 ed d2  41 1f 7d d7 b7 c0 92 fd  |.C.m.a..A.}.....|
-00000020  34 17 85 7b c7 ff c4 56  dd 90 bd 20 00 00 00 00  |4..{...V... ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 e3 21 e8 24 fb  |....z...v...!.$.|
+00000010  e8 fe 46 e2 54 a7 db 98  ae a4 b2 fc f8 17 99 b4  |..F.T...........|
+00000020  ed 6a aa 9c f9 ce e2 0f  f8 88 05 20 00 00 00 00  |.j......... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 3f  |..+.....3.$... ?|
-00000060  be 50 e7 f1 b0 30 60 dc  92 50 b8 01 4a d1 3e ff  |.P...0`..P..J.>.|
-00000070  6e f0 bd e1 17 44 d8 19  1b c6 63 43 e5 c1 58 14  |n....D....cC..X.|
-00000080  03 03 00 01 01 17 03 03  00 17 c0 b7 da 01 3e 64  |..............>d|
-00000090  6b 57 ba 21 12 79 42 8c  63 1f 45 d1 f2 10 fe 98  |kW.!.yB.c.E.....|
-000000a0  b6 17 03 03 02 22 90 87  e6 c3 ba 92 41 a2 96 00  |....."......A...|
-000000b0  c7 92 97 ab 4b 80 02 bb  02 83 19 f3 f6 36 d5 23  |....K........6.#|
-000000c0  3c c7 bd fb 97 67 86 cb  70 4c 60 9e 6c d4 7a f3  |<....g..pL`.l.z.|
-000000d0  03 a5 f1 09 d5 7e 07 74  f3 c8 e4 b8 da 44 a3 94  |.....~.t.....D..|
-000000e0  ee 4e 4a 7b ab 4e 92 03  49 04 4e cf 1b b3 0d 91  |.NJ{.N..I.N.....|
-000000f0  0f 98 51 5c 56 4d d3 a8  75 4b e0 96 d9 9e dd c8  |..Q\VM..uK......|
-00000100  81 c4 37 a0 c6 c9 ec 0f  e0 f1 ed 29 ff 5a a2 d4  |..7........).Z..|
-00000110  af 61 f7 b1 d5 ee e7 1d  7a e1 7f 33 8d 75 e6 9d  |.a......z..3.u..|
-00000120  bc 78 56 eb c5 89 d3 19  86 81 09 e1 ee 10 03 7c  |.xV............||
-00000130  a4 1b 78 17 51 a3 53 b4  67 5d 29 49 21 b2 51 7b  |..x.Q.S.g])I!.Q{|
-00000140  f5 dc fd 60 11 ee 8f 50  ea 28 b5 db 57 04 7e 3b  |...`...P.(..W.~;|
-00000150  ad 6f 29 d4 22 f3 a1 4b  52 ac b8 2b 30 0c 67 16  |.o)."..KR..+0.g.|
-00000160  e3 e0 7d a3 03 66 c4 39  70 8e c7 06 cf d2 6f 98  |..}..f.9p.....o.|
-00000170  c1 c9 f6 a9 6a 89 b4 3e  38 97 ae e4 f2 97 a4 6f  |....j..>8......o|
-00000180  e2 05 f8 e9 53 c9 ae f7  87 c3 0f 68 75 9e 07 e9  |....S......hu...|
-00000190  45 e9 0d 03 7e c8 79 56  30 77 e3 ea db 92 a2 f8  |E...~.yV0w......|
-000001a0  5e 5b ab 77 0d 9b bc 5f  51 40 6c 1b 0d ef b4 cf  |^[.w..._Q@l.....|
-000001b0  4a 3d a6 8c b6 ab ce 4f  6c 08 0e 23 f0 2a 56 07  |J=.....Ol..#.*V.|
-000001c0  f5 88 68 c3 0c fd 63 9b  e4 56 12 a6 f5 0a ed 54  |..h...c..V.....T|
-000001d0  40 30 ee 36 72 5d ca bb  5a 52 d3 84 14 c1 7e e4  |@0.6r]..ZR....~.|
-000001e0  f8 fb e9 c8 10 16 54 16  1f 72 99 8c 7a 69 87 ca  |......T..r..zi..|
-000001f0  62 53 dc cb a4 26 73 90  fb 11 3c 3c 9f 94 65 cb  |bS...&s...<<..e.|
-00000200  28 94 65 ca 56 45 a8 c1  ec 08 31 dd eb bc 17 71  |(.e.VE....1....q|
-00000210  cd 65 04 95 2e e7 e0 fb  73 fe 70 db 70 31 93 90  |.e......s.p.p1..|
-00000220  cf 47 07 ec 92 98 c1 da  fc 13 f8 8a 28 4e e8 80  |.G..........(N..|
-00000230  a8 96 c2 e2 a6 cd df d4  7f 46 4a 3b e9 dd cf a5  |.........FJ;....|
-00000240  75 d5 cc 67 35 81 d5 2e  e4 68 c4 56 1a 46 33 5a  |u..g5....h.V.F3Z|
-00000250  f2 79 32 6b 4e a0 6b 76  53 53 04 73 86 fd bd e2  |.y2kN.kvSS.s....|
-00000260  f7 f8 14 0f 0a a8 10 6d  a1 bf f8 d0 27 8d cb e8  |.......m....'...|
-00000270  a5 51 16 4b 11 a2 8a 6f  22 c5 7c bc c5 7a 0b df  |.Q.K...o".|..z..|
-00000280  70 1d c4 93 ec 87 78 12  77 e3 85 5a 3c 29 d8 f7  |p.....x.w..Z<)..|
-00000290  ab a4 c6 10 50 ed d5 2a  3f b1 84 73 1e 7f 99 eb  |....P..*?..s....|
-000002a0  31 9c 2c d2 6a 80 4a 5e  7c aa 64 e7 83 df a9 17  |1.,.j.J^|.d.....|
-000002b0  c3 4c 13 c8 c1 d7 1b f5  be c9 00 cf ec 7e a5 ab  |.L...........~..|
-000002c0  89 9c b0 72 fd f0 cb 54  17 03 03 00 a4 28 34 92  |...r...T.....(4.|
-000002d0  a7 52 92 5d a0 99 6b e6  22 c5 f6 76 86 1b 0b d6  |.R.]..k."..v....|
-000002e0  b7 a8 67 c1 04 b8 1c ac  7b 02 f5 0a 20 41 dd 43  |..g.....{... A.C|
-000002f0  25 cc 01 f9 dc 6e c7 f7  4f 67 dd b3 54 81 80 d5  |%....n..Og..T...|
-00000300  6d 45 00 42 d0 49 23 d5  12 33 e4 5f fd 58 79 81  |mE.B.I#..3._.Xy.|
-00000310  e3 df 67 6d 03 44 58 0f  76 38 c3 de ed 26 90 29  |..gm.DX.v8...&.)|
-00000320  45 92 ce 3b fa ea 98 da  ea a2 d2 cc c6 0e a8 38  |E..;...........8|
-00000330  c1 2d 92 8c 48 79 58 25  75 fd 2d 6d ef 06 32 1a  |.-..HyX%u.-m..2.|
-00000340  bb 09 fa 66 bc 06 9d c5  fb 46 94 5e b1 73 8d 05  |...f.....F.^.s..|
-00000350  e1 90 24 c3 eb 72 7f a8  b7 12 a3 3c 11 29 ea 80  |..$..r.....<.)..|
-00000360  10 4e 19 40 25 0b c9 34  70 99 e9 1a 60 17 bb 5b  |.N.@%..4p...`..[|
-00000370  1a 17 03 03 00 35 91 4b  45 15 d5 2e 33 a7 ba 9b  |.....5.KE...3...|
-00000380  64 20 bb 72 28 06 27 37  2f ac c9 c0 9e b9 d8 f3  |d .r(.'7/.......|
-00000390  86 36 d2 7d df c2 4d 95  a5 a4 4b 64 5f 1a 83 67  |.6.}..M...Kd_..g|
-000003a0  f6 6a 21 ff d0 b4 1c 65  23 62 ac                 |.j!....e#b.|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 a9  |..+.....3.$... .|
+00000060  5a 5c e9 b1 71 e8 a8 64  97 65 02 6b 3d 25 6f 6f  |Z\..q..d.e.k=%oo|
+00000070  9a 47 cb 4a 81 ac 89 23  22 c1 f4 3d db 77 1e 14  |.G.J...#"..=.w..|
+00000080  03 03 00 01 01 17 03 03  00 17 12 15 75 15 9f 10  |............u...|
+00000090  90 07 34 9c eb 05 d0 a1  4b 36 5b 4c 7b 26 2a 00  |..4.....K6[L{&*.|
+000000a0  29 17 03 03 02 22 85 a0  67 d7 72 57 83 19 79 12  |)...."..g.rW..y.|
+000000b0  b7 bd 37 ed ab 49 5d 15  49 2b 4f a1 b2 25 08 22  |..7..I].I+O..%."|
+000000c0  88 83 70 07 bc 8f 69 45  1b 21 36 99 f4 99 40 f8  |..p...iE.!6...@.|
+000000d0  0d 30 13 87 70 68 f6 9d  ce c7 9e 25 2c 1e 7a b5  |.0..ph.....%,.z.|
+000000e0  52 ed f8 0f f7 d9 e5 15  fc a3 47 83 0d 18 c4 de  |R.........G.....|
+000000f0  a1 a6 24 35 aa 56 d1 8b  95 07 5f 0f ba 1f 96 c3  |..$5.V...._.....|
+00000100  5b 36 cc d2 15 e6 b4 88  8f e3 7f 79 c2 24 d5 f3  |[6.........y.$..|
+00000110  a7 35 69 4e d2 2a f7 5c  08 8a c0 26 dd b9 77 5b  |.5iN.*.\...&..w[|
+00000120  96 1b 5f 03 89 07 a0 6a  b1 14 1d 02 46 08 eb 80  |.._....j....F...|
+00000130  d5 4c dc 69 63 8f 14 a1  e5 02 95 05 8a 8b c8 68  |.L.ic..........h|
+00000140  c3 d8 75 56 47 94 32 ba  67 71 ed 4b b4 62 ba 6a  |..uVG.2.gq.K.b.j|
+00000150  31 20 a7 d6 f8 8c a0 e9  e8 d2 1a 6b 85 6b b7 ee  |1 .........k.k..|
+00000160  78 e1 2e 4c 14 f0 b3 3e  b8 dc 7d af f0 9d 29 f3  |x..L...>..}...).|
+00000170  54 1d 9d dc 9e a3 9f 29  5b 33 1d f7 00 98 85 bd  |T......)[3......|
+00000180  42 39 85 75 cf fa dc f3  7e 80 14 4e a5 90 80 b6  |B9.u....~..N....|
+00000190  e3 37 d3 27 c6 7b b9 ee  32 61 a5 72 e5 2f a6 ab  |.7.'.{..2a.r./..|
+000001a0  cb 8e ac 53 4b 86 24 92  4b 77 d6 8d aa b4 37 d5  |...SK.$.Kw....7.|
+000001b0  2b b2 2f 07 23 37 4a d9  1f cc 6c 72 c6 21 5b 38  |+./.#7J...lr.![8|
+000001c0  a3 33 5c 86 50 69 34 8f  5a b8 cc 5e 82 7d 5b b2  |.3\.Pi4.Z..^.}[.|
+000001d0  5b f5 58 7f 2c 61 08 4b  3d 8b 67 09 19 01 d2 4f  |[.X.,a.K=.g....O|
+000001e0  06 62 17 4e d4 bf 88 89  bb c4 6e 14 2b 3a 50 c9  |.b.N......n.+:P.|
+000001f0  56 8a c1 0a 45 e6 67 32  f3 96 37 4b ba c2 2a 2b  |V...E.g2..7K..*+|
+00000200  84 e1 ff bb e0 ea 68 9b  98 fc 78 26 25 f6 50 25  |......h...x&%.P%|
+00000210  52 57 83 94 39 b9 a7 8d  38 43 70 a8 b7 61 a6 cf  |RW..9...8Cp..a..|
+00000220  09 77 db 3d 64 94 63 73  5b a1 6d f4 06 c1 b3 fb  |.w.=d.cs[.m.....|
+00000230  c6 9a 0b ea 9f 8e 6d 58  53 0e 13 e0 a6 21 69 7a  |......mXS....!iz|
+00000240  d3 57 32 d4 c6 32 ef 02  8e 54 1d 72 2d d6 a7 dc  |.W2..2...T.r-...|
+00000250  59 54 be 69 3f 5c 53 23  a9 f7 3e a9 e6 e7 e0 98  |YT.i?\S#..>.....|
+00000260  65 f6 74 f4 49 1c 77 0f  92 34 87 81 29 85 d1 e0  |e.t.I.w..4..)...|
+00000270  1e 4d b4 eb c2 44 43 a7  10 51 7c 5e 8e a4 b6 37  |.M...DC..Q|^...7|
+00000280  78 e8 35 02 07 3d 60 a5  01 75 01 25 f3 ff 32 ff  |x.5..=`..u.%..2.|
+00000290  34 ab a4 c3 4c ad 21 b8  91 0a d6 54 4b 7d cf c5  |4...L.!....TK}..|
+000002a0  ec 0f e5 4a 4d 75 4c ec  fc 37 2b 26 5a 73 93 70  |...JMuL..7+&Zs.p|
+000002b0  88 c7 9c cf 32 f9 ee a7  27 6e 1d 9e 36 a2 31 9e  |....2...'n..6.1.|
+000002c0  cd 0e c2 89 ef 2b 40 1a  17 03 03 00 a4 ad 19 05  |.....+@.........|
+000002d0  e6 40 5e b1 ec 69 6b 47  ef 5d d3 ee a6 94 51 85  |.@^..ikG.]....Q.|
+000002e0  d8 28 d9 df 8b d0 df 23  7e bd 98 6c 33 26 45 fa  |.(.....#~..l3&E.|
+000002f0  60 71 8b f5 71 5c 22 4e  b3 a7 01 fe 17 39 89 67  |`q..q\"N.....9.g|
+00000300  0b 70 ff 52 b9 10 9c e9  02 c0 1c 56 9d c8 45 51  |.p.R.......V..EQ|
+00000310  5a dd 86 79 6d a7 7d eb  16 c2 1a 5f 6a 3b 93 42  |Z..ym.}...._j;.B|
+00000320  13 f3 3d 8a 39 21 5f a9  7f cf 4b 1e 22 f1 a3 f8  |..=.9!_...K."...|
+00000330  5c 35 41 2a e2 91 72 4f  59 61 1c 15 be 27 6a bd  |\5A*..rOYa...'j.|
+00000340  b7 16 1f 63 97 51 d6 96  dd 81 f9 e7 fd 97 33 6e  |...c.Q........3n|
+00000350  da 5a 61 77 57 6e 3b 65  24 db b3 3a 18 7b dc f4  |.ZawWn;e$..:.{..|
+00000360  7c ff ab 43 7f 1b ae ae  b8 73 71 9e be 91 d6 56  ||..C.....sq....V|
+00000370  13 17 03 03 00 35 39 61  a3 b7 e5 1d 3d 87 92 84  |.....59a....=...|
+00000380  11 39 7d f4 ce 29 b9 4b  fd 3c 0c 5a b6 3a fa e2  |.9}..).K.<.Z.:..|
+00000390  a8 5b e6 d2 e5 7e e3 a6  33 59 e4 a8 59 95 5d b9  |.[...~..3Y..Y.].|
+000003a0  31 6d 51 90 22 be c0 3f  6e 43 f2                 |1mQ."..?nC.|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 00 35 10 bd 5d 23 36  |..........5..]#6|
-00000010  58 43 f4 bb 5e 4e ee 43  fd 0e a1 d9 de 81 99 54  |XC..^N.C.......T|
-00000020  de 6e 82 33 71 8a 45 a7  35 f1 cd fb 5f bf 46 20  |.n.3q.E.5..._.F |
-00000030  a5 79 d6 87 aa f4 29 51  02 f5 4e 69 ef a5 d7 d6  |.y....)Q..Ni....|
-00000040  17 03 03 00 17 21 1f 90  0b 01 63 89 6a af 53 72  |.....!....c.j.Sr|
-00000050  51 c0 11 01 7b 09 dd 40  82 dd e1 32 17 03 03 00  |Q...{..@...2....|
-00000060  13 93 5d c1 19 16 5c 17  1a 7b 92 a0 9b f5 14 57  |..]...\..{.....W|
-00000070  85 39 4a ac                                       |.9J.|
+00000000  14 03 03 00 01 01 17 03  03 00 35 50 4f ce ae a5  |..........5PO...|
+00000010  f7 b0 7e 2b 91 86 72 da  90 65 fd 1b a5 46 c6 98  |..~+..r..e...F..|
+00000020  47 90 5a f2 b8 5a 1f 18  44 19 bd ca dd 2a 15 e7  |G.Z..Z..D....*..|
+00000030  53 f5 17 e8 7d 9b f1 9a  63 ac b0 b0 df c3 0e 4c  |S...}...c......L|
+00000040  17 03 03 00 17 8b bd fb  bc fd f7 af 53 9b 8b 1a  |............S...|
+00000050  a3 e5 f6 e9 87 bd 4a 8a  1b 0e c9 d9 17 03 03 00  |......J.........|
+00000060  13 8e c6 d3 6e 04 8f 3b  d4 76 a4 c7 c8 63 a8 a8  |....n..;.v...c..|
+00000070  9e ba e7 fd                                       |....|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-Ed25519 b/src/crypto/tls/testdata/Client-TLSv13-Ed25519
index 0b4a17a..d284740 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-Ed25519
+++ b/src/crypto/tls/testdata/Client-TLSv13-Ed25519
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,53 +16,53 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 a8 21 4e 51 6a  |....z...v...!NQj|
-00000010  ce ba 17 cc 2d 25 b3 31  59 6a 3f 81 eb e6 ac a0  |....-%.1Yj?.....|
-00000020  91 d9 ef 76 a1 5f bb 63  ab 2c 6b 20 00 00 00 00  |...v._.c.,k ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 6f b6 d3 79 9b  |....z...v..o..y.|
+00000010  00 17 a8 46 3f e4 bc fc  08 1e 56 6c d8 63 86 f3  |...F?.....Vl.c..|
+00000020  83 1b d8 26 6d 86 d6 4c  f3 4f e1 20 00 00 00 00  |...&m..L.O. ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 81  |..+.....3.$... .|
-00000060  4c a8 07 aa 6b 4a f9 44  77 78 a9 57 d0 07 55 07  |L...kJ.Dwx.W..U.|
-00000070  9a c2 8e 33 bf c4 09 ee  49 51 5c fe f1 7b 30 14  |...3....IQ\..{0.|
-00000080  03 03 00 01 01 17 03 03  00 17 5a 22 a1 07 01 ea  |..........Z"....|
-00000090  97 bd 5a 59 3a 21 de 9c  45 0c 41 ff 34 45 35 ab  |..ZY:!..E.A.4E5.|
-000000a0  25 17 03 03 01 50 a1 8c  19 e7 0c 69 d3 e0 f6 53  |%....P.....i...S|
-000000b0  95 15 13 4c e3 c3 3f 35  d9 73 c9 fe 24 b0 14 5f  |...L..?5.s..$.._|
-000000c0  b6 9e 94 20 cf 80 f7 88  7c 0f be 4c 70 16 00 2a  |... ....|..Lp..*|
-000000d0  55 02 aa a9 4b 7f a7 a5  b8 46 09 9e 18 78 78 66  |U...K....F...xxf|
-000000e0  22 c2 31 19 12 f7 e4 7e  f3 26 39 7d cd 5e 74 24  |".1....~.&9}.^t$|
-000000f0  fb 75 7d b7 2c b5 fb e0  49 bd da 96 e1 c3 63 8f  |.u}.,...I.....c.|
-00000100  e3 28 43 bb 32 a7 fd 9c  ab 54 ba ce 07 4a 23 35  |.(C.2....T...J#5|
-00000110  a4 3a ff 43 40 19 ef 38  07 02 ba d6 c4 f0 bf 63  |.:.C@..8.......c|
-00000120  aa b3 ea 55 d0 e1 a9 f3  cb 04 6b 1b 8d 35 3a f8  |...U......k..5:.|
-00000130  0b 1c 40 99 fe b0 04 5f  d1 5b 3f 4b be fe b5 96  |..@...._.[?K....|
-00000140  f0 49 3d bf a5 92 f3 bd  a6 4c 47 24 f8 b5 7c 45  |.I=......LG$..|E|
-00000150  47 85 9b 08 a1 da 51 7a  ce 3f 32 66 de 89 c0 c3  |G.....Qz.?2f....|
-00000160  ac da 73 0d 15 14 18 e6  a0 7d 07 26 44 df 55 b7  |..s......}.&D.U.|
-00000170  6e 4e fa c0 f5 5e 42 3a  d9 29 d3 1d e6 cf 3c 8c  |nN...^B:.)....<.|
-00000180  6d c1 d9 f9 04 f0 57 dc  47 4e d1 e2 a1 f1 a1 c9  |m.....W.GN......|
-00000190  2e da 97 4d 65 65 04 54  e7 80 f1 88 b2 34 26 61  |...Mee.T.....4&a|
-000001a0  77 8a 1f bb 82 7f 4b ce  b3 5a 55 60 e1 3a ef 95  |w.....K..ZU`.:..|
-000001b0  bd 34 fc ef 2b 18 4b bb  8a cf ba 3a 69 43 f4 59  |.4..+.K....:iC.Y|
-000001c0  98 a1 95 a3 22 f6 b5 1a  84 83 cf cb 90 eb 28 29  |....".........()|
-000001d0  b3 84 e1 0d 37 9e 98 96  91 73 f1 7f d7 9b 71 38  |....7....s....q8|
-000001e0  6e bc 2e 60 2d 27 0c 18  fd 2a b8 76 01 33 2f 95  |n..`-'...*.v.3/.|
-000001f0  6e 0b bf 2b 26 5e 17 03  03 00 59 ed 43 2f e8 df  |n..+&^....Y.C/..|
-00000200  f3 2f 91 f3 dc 1b aa ff  d3 3b 28 1f 78 21 fb e2  |./.......;(.x!..|
-00000210  7d 6e 03 09 98 c1 23 09  d7 45 da b8 e0 5a e5 27  |}n....#..E...Z.'|
-00000220  38 9a 2f da 9b d3 04 35  f5 b9 31 b0 c0 1f 8a 1e  |8./....5..1.....|
-00000230  d8 8a 19 f1 38 af a6 74  ac e5 b4 0d 45 83 b4 59  |....8..t....E..Y|
-00000240  83 42 97 14 23 55 71 ef  66 8c 35 69 3f 2c 88 63  |.B..#Uq.f.5i?,.c|
-00000250  8d 3b 05 fe 17 03 03 00  35 47 82 ec 22 f4 86 6a  |.;......5G.."..j|
-00000260  b7 c1 d8 64 3b 42 f4 ca  5c 3d ba a3 6a ea 77 6a  |...d;B..\=..j.wj|
-00000270  d6 52 e3 b0 42 fb c2 f1  2c b1 ef 44 ed 11 29 6d  |.R..B...,..D..)m|
-00000280  2b 6f 13 0f 42 48 a0 2e  5b ba a1 93 6b de        |+o..BH..[...k.|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 5b  |..+.....3.$... [|
+00000060  8f 4f 5a a9 95 6b 04 07  31 d3 ed 91 8b 25 b4 7b  |.OZ..k..1....%.{|
+00000070  5c a1 0a a6 26 09 92 9b  b0 72 26 f9 0d 09 60 14  |\...&....r&...`.|
+00000080  03 03 00 01 01 17 03 03  00 17 a8 99 d3 76 1f 12  |.............v..|
+00000090  19 18 15 8e 4c 59 43 92  11 4a aa 50 98 7e 4c d9  |....LYC..J.P.~L.|
+000000a0  63 17 03 03 01 50 66 f5  d6 ce 35 0f 10 e5 ab 34  |c....Pf...5....4|
+000000b0  78 17 c6 b6 60 40 eb 53  34 9f ce 02 c4 36 51 18  |x...`@.S4....6Q.|
+000000c0  c2 b3 fb f3 98 92 d0 f2  b7 be 28 f5 c7 2d fa 1f  |..........(..-..|
+000000d0  9b 8b aa e5 45 54 6b 0e  ed 6b 44 cb d4 4d 62 b2  |....ETk..kD..Mb.|
+000000e0  30 c9 df ac cf a3 7e 43  58 1e bf 6e 5b 69 4e 48  |0.....~CX..n[iNH|
+000000f0  1c 39 49 eb 8a 0c 22 f3  70 4a 80 50 39 d6 68 29  |.9I...".pJ.P9.h)|
+00000100  d0 6d 08 20 26 39 6d 37  5a 9f 79 e9 16 e3 7e 94  |.m. &9m7Z.y...~.|
+00000110  8f 5f 9b 97 2d e1 b1 48  e4 a3 36 63 40 5a 80 93  |._..-..H..6c@Z..|
+00000120  06 27 3b 93 d9 ed 2d b1  3e 74 ed bc 38 a1 cb 17  |.';...-.>t..8...|
+00000130  06 4a 9b c1 c1 d7 7a 1c  ca ff 4d ee 91 6d d0 3c  |.J....z...M..m.<|
+00000140  c2 4b cc 33 c6 7c 76 8e  db a2 e0 fe 15 e2 ec db  |.K.3.|v.........|
+00000150  1f 5d 05 c8 5e 0e 7f 2c  7a 95 08 34 68 a2 2c 7c  |.]..^..,z..4h.,||
+00000160  04 16 92 7a c8 ec 52 2d  1a c4 7a ea 12 cd 0f b9  |...z..R-..z.....|
+00000170  7c 00 51 55 02 5b 02 7d  ec 89 af f5 6d 76 89 0e  ||.QU.[.}....mv..|
+00000180  67 42 f0 e4 67 4d 3f 70  ff 2c 64 81 1c 4a 92 1f  |gB..gM?p.,d..J..|
+00000190  26 8b a4 4f 15 18 b5 11  4a 61 df 45 53 74 fd 8d  |&..O....Ja.ESt..|
+000001a0  ff 22 32 91 af c7 7f a4  7b 62 c3 3b 30 51 b6 34  |."2.....{b.;0Q.4|
+000001b0  b6 01 21 f9 86 74 be 62  27 1a 41 1f f0 0d 8b 5c  |..!..t.b'.A....\|
+000001c0  4b 82 ea 76 23 9c 36 af  25 1f f6 2d 5f 9c 28 bd  |K..v#.6.%..-_.(.|
+000001d0  b6 d5 1e 26 8b c1 dc ac  ed 6d 10 ff 13 ed fc 08  |...&.....m......|
+000001e0  08 0a 74 1c b1 5b f8 45  e4 83 44 f2 be ce 8d ac  |..t..[.E..D.....|
+000001f0  ee ae e6 21 da c7 17 03  03 00 59 d9 b3 95 0a f7  |...!......Y.....|
+00000200  1a 1a 54 fa ab 09 38 6d  6d 53 0a ef 11 73 bc a2  |..T...8mmS...s..|
+00000210  20 03 31 48 e2 0a d1 af  56 6c ca dd 88 ba 72 3a  | .1H....Vl....r:|
+00000220  c1 e0 c5 60 44 74 d6 c9  18 23 96 2c e7 88 c8 3e  |...`Dt...#.,...>|
+00000230  02 73 c0 38 d4 bd 85 a4  bb 78 a0 ba d3 fd f1 c4  |.s.8.....x......|
+00000240  27 08 05 fb 2c 26 20 b7  1a 41 87 a6 b7 97 19 26  |'...,& ..A.....&|
+00000250  50 ed 9a e4 17 03 03 00  35 68 36 c7 78 c3 5e ff  |P.......5h6.x.^.|
+00000260  b3 92 a7 25 31 2a a2 fa  24 d9 da 69 16 03 8b db  |...%1*..$..i....|
+00000270  fe b2 3f 63 88 49 f1 14  63 7a 58 a9 6f c5 64 92  |..?c.I..czX.o.d.|
+00000280  21 84 82 d8 49 98 fb f3  f1 fd 52 83 32 97        |!...I.....R.2.|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 00 35 11 45 8f b2 e0  |..........5.E...|
-00000010  87 3d 09 94 93 16 19 04  3d 84 6c e5 14 5e c6 8b  |.=......=.l..^..|
-00000020  73 1a 53 4c d0 f4 11 27  0c 0d 05 c7 9d ba d0 04  |s.SL...'........|
-00000030  37 ed 8b 8a 65 34 54 b1  07 36 92 8c 8c a8 30 b7  |7...e4T..6....0.|
-00000040  17 03 03 00 17 ea fc b8  84 8d f0 9d 8e 1c 2c 65  |..............,e|
-00000050  10 a8 69 7f dd 3c a4 80  45 5d c3 38 17 03 03 00  |..i..<..E].8....|
-00000060  13 15 4b b7 23 2f 55 b0  ae d3 3f f6 68 c9 b2 ef  |..K.#/U...?.h...|
-00000070  d7 e2 18 49                                       |...I|
+00000000  14 03 03 00 01 01 17 03  03 00 35 07 7b a2 7a 4f  |..........5.{.zO|
+00000010  40 e9 a2 94 9f b7 2d 91  87 1e 37 b0 ca b7 ea 91  |@.....-...7.....|
+00000020  53 f1 bf 7d 56 6a 0c 6a  9d 07 ac 93 9c db ca ac  |S..}Vj.j........|
+00000030  43 7b eb 56 9d 6c 79 f2  72 f8 0b 8d 15 08 84 d5  |C{.V.ly.r.......|
+00000040  17 03 03 00 17 07 b3 7d  a9 56 c4 76 e5 12 97 29  |.......}.V.v...)|
+00000050  b7 99 e6 3e 08 79 2d fb  1a 5b eb 7a 17 03 03 00  |...>.y-..[.z....|
+00000060  13 66 b7 65 57 0d 54 7b  6a 34 98 a1 4e 29 d5 92  |.f.eW.T{j4..N)..|
+00000070  1e b6 52 bc                                       |..R.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ExportKeyingMaterial b/src/crypto/tls/testdata/Client-TLSv13-ExportKeyingMaterial
index b306411..a0ede61 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-ExportKeyingMaterial
+++ b/src/crypto/tls/testdata/Client-TLSv13-ExportKeyingMaterial
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,75 +16,75 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 6d fb 70 07 b4  |....z...v..m.p..|
-00000010  2d 14 d1 d1 88 17 6a a3  b1 c1 e7 23 4b 06 c4 fa  |-.....j....#K...|
-00000020  4a 0e e1 2c ce 5a d5 c7  8c ab f2 20 00 00 00 00  |J..,.Z..... ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 d6 7f ef 2d f6  |....z...v.....-.|
+00000010  82 d9 be 6d 33 80 73 c0  d4 d8 63 e9 95 a6 5b 1f  |...m3.s...c...[.|
+00000020  ce c0 ec 13 07 f4 68 7d  cc 79 18 20 00 00 00 00  |......h}.y. ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 4e  |..+.....3.$... N|
-00000060  fe 87 d7 81 71 25 ba 33  de 10 df 19 38 d8 af 43  |....q%.3....8..C|
-00000070  58 3f 41 2e b9 b8 cb 1c  65 a7 cd 8d 00 b1 0e 14  |X?A.....e.......|
-00000080  03 03 00 01 01 17 03 03  00 17 b3 63 09 54 ad 41  |...........c.T.A|
-00000090  24 fe 2c 81 49 c8 86 88  c2 ad ba cd 45 77 51 c0  |$.,.I.......EwQ.|
-000000a0  d5 17 03 03 02 6d 74 7d  de 53 70 5c 11 d0 a7 68  |.....mt}.Sp\...h|
-000000b0  8e 10 c9 cb cd 0c 25 ac  88 e7 17 54 8b 32 2c ee  |......%....T.2,.|
-000000c0  97 9c 3d f6 ce d1 83 70  ee c0 85 0c fc 61 ba db  |..=....p.....a..|
-000000d0  6d e0 04 26 6f b7 4e 44  4d 1c 5c 16 9a 57 4f e6  |m..&o.NDM.\..WO.|
-000000e0  52 89 27 53 88 f8 93 91  ed b2 42 b4 4c f0 58 a3  |R.'S......B.L.X.|
-000000f0  50 a7 af 2c 47 ac ad 8b  14 a0 9f d4 28 2e 7b 28  |P..,G.......(.{(|
-00000100  8e ec d1 bb 7d d9 78 fb  24 82 9f 2a ac 4e 85 83  |....}.x.$..*.N..|
-00000110  35 25 75 8f 9e 6d 4c 8a  dd 6f 9f 9a 34 93 a2 9d  |5%u..mL..o..4...|
-00000120  d0 26 4c 7b a8 72 a3 12  b9 ef 6b c8 d0 4f 44 5b  |.&L{.r....k..OD[|
-00000130  dd f1 72 3a b4 5c 7e a8  8d d4 68 bc 6d 54 2c ee  |..r:.\~...h.mT,.|
-00000140  c1 f7 78 f1 15 cd 57 b5  54 89 08 f0 d8 56 ef 8d  |..x...W.T....V..|
-00000150  14 d1 e8 fd 83 bd ab 64  c1 99 36 4e af 81 27 52  |.......d..6N..'R|
-00000160  0f 5e 31 5e c0 70 21 fb  05 40 d4 d2 71 df 0c 09  |.^1^.p!..@..q...|
-00000170  31 83 b0 71 82 84 d9 90  6b 25 5a 67 03 30 c4 80  |1..q....k%Zg.0..|
-00000180  2c 99 41 3f fa 51 ce a8  b4 b8 98 2a bc e9 cc ce  |,.A?.Q.....*....|
-00000190  f7 0c 69 a3 c3 02 dc b9  4f 00 ac 4f 29 d5 e5 df  |..i.....O..O)...|
-000001a0  df 67 3b ed 94 8e 80 3f  aa 6e a8 b7 e0 7f 4d fd  |.g;....?.n....M.|
-000001b0  95 80 54 89 57 ff d7 73  86 bd e8 98 11 d5 09 c6  |..T.W..s........|
-000001c0  ab af 1a a4 a0 cc 30 40  bc 63 dc d0 db 92 41 f5  |......0@.c....A.|
-000001d0  5c 1e f1 92 03 5b 3f 27  23 1f 9c 8e f8 8b 4f 69  |\....[?'#.....Oi|
-000001e0  0c 3d 09 e5 95 d8 ba 8c  90 cd ac 53 ed 77 8d 75  |.=.........S.w.u|
-000001f0  3a 56 b4 f3 21 a5 4e c2  6e 1f 87 74 56 69 32 95  |:V..!.N.n..tVi2.|
-00000200  29 56 07 2c 0d b3 74 47  28 6d 8f ef 56 f6 68 7f  |)V.,..tG(m..V.h.|
-00000210  25 e4 76 06 7c 82 40 11  f8 eb 3c ec 62 fa be 60  |%.v.|.@...<.b..`|
-00000220  d3 11 98 e2 d4 b1 d0 72  3d e6 4a da f0 d6 c0 42  |.......r=.J....B|
-00000230  8e a6 63 cc a1 41 e3 18  21 00 ac cc 98 f8 8d 78  |..c..A..!......x|
-00000240  ab 9b 39 16 ad 4c fd 11  15 79 0c fd 0e 87 45 d6  |..9..L...y....E.|
-00000250  81 30 bb 3a 72 89 92 c1  fa e8 ad 59 3b 8b b0 38  |.0.:r......Y;..8|
-00000260  2d c3 6e 87 a8 b8 1f 7d  a0 b3 e6 91 83 97 78 94  |-.n....}......x.|
-00000270  f0 01 66 a2 c8 89 45 8e  2e a0 7e 89 4d 7f 49 ee  |..f...E...~.M.I.|
-00000280  2a 69 c0 ec 77 db 85 df  01 d9 02 36 df 94 81 01  |*i..w......6....|
-00000290  aa 43 a2 3d 76 8c c3 21  bf 05 c3 b2 c4 28 85 65  |.C.=v..!.....(.e|
-000002a0  7b 4a ac e3 45 40 77 1d  a9 ee 1e e9 97 7c 2f 45  |{J..E@w......|/E|
-000002b0  45 18 58 47 ab 51 0f 26  eb d5 bb ac c2 8b a9 ae  |E.XG.Q.&........|
-000002c0  65 6a 91 9b 13 93 69 c6  9d bc 61 23 20 d2 ad a0  |ej....i...a# ...|
-000002d0  d3 f9 2d 32 79 e3 4b 07  90 32 9e e1 f3 13 18 b0  |..-2y.K..2......|
-000002e0  65 6e 89 a5 45 c6 a1 9b  f0 f6 d1 66 d3 e7 49 1a  |en..E......f..I.|
-000002f0  b8 e2 17 cd d0 13 9c e6  e1 77 87 a4 8b 6a d3 74  |.........w...j.t|
-00000300  0e 85 b1 2c f3 c8 a8 f3  65 b3 71 c2 bb f5 95 d7  |...,....e.q.....|
-00000310  81 78 45 17 03 03 00 99  1e 53 96 f9 b9 97 ec 53  |.xE......S.....S|
-00000320  4e 97 a9 8c 01 06 ee 6b  31 47 93 4b ac f7 b6 4a  |N......k1G.K...J|
-00000330  15 bb 28 d7 87 73 7c 1d  3b d3 6b 9d 48 77 df 09  |..(..s|.;.k.Hw..|
-00000340  c9 97 98 b6 d6 20 94 8a  ed 71 08 2d 56 af b2 b8  |..... ...q.-V...|
-00000350  20 fc d7 81 e4 53 eb 57  6a bd 9b 1c 11 4f 2e fb  | ....S.Wj....O..|
-00000360  9a 0e 65 08 69 df 28 70  a7 50 21 62 9f 63 39 db  |..e.i.(p.P!b.c9.|
-00000370  9e 73 40 5d 73 77 a7 1d  2e 79 61 fa b9 50 f0 70  |.s@]sw...ya..P.p|
-00000380  1e 71 d1 9e c6 2f 8c 4c  5f e0 b1 37 d7 c9 ab fc  |.q.../.L_..7....|
-00000390  5f 6a ca a9 9e 27 38 42  78 ba fb e6 8e c2 3f a6  |_j...'8Bx.....?.|
-000003a0  a0 c6 04 b6 d8 b7 3a 68  83 15 3b 70 f9 0a 27 4a  |......:h..;p..'J|
-000003b0  0a 17 03 03 00 35 d0 88  b7 b8 cf 81 4e 97 76 96  |.....5......N.v.|
-000003c0  c2 ed e8 15 e4 01 54 2b  1f 0e 34 08 52 6c a8 6a  |......T+..4.Rl.j|
-000003d0  cf 04 29 7b 27 fb e9 1e  d1 6c d2 28 15 03 2a 58  |..){'....l.(..*X|
-000003e0  d4 eb 67 18 83 3f d4 2a  ab 9f aa                 |..g..?.*...|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 00  |..+.....3.$... .|
+00000060  e9 40 7a 65 78 98 47 43  aa e1 63 fd 6b c4 21 1d  |.@zex.GC..c.k.!.|
+00000070  58 45 5f 64 a0 18 55 a0  c3 14 7d 4e 12 93 7c 14  |XE_d..U...}N..|.|
+00000080  03 03 00 01 01 17 03 03  00 17 4c 01 0b f7 e7 1b  |..........L.....|
+00000090  a9 47 84 10 3b 50 85 6e  3d 8e 52 bc 99 bf d4 35  |.G..;P.n=.R....5|
+000000a0  45 17 03 03 02 6d 8c b3  22 04 de 8b 09 e5 e7 9f  |E....m..".......|
+000000b0  d5 1f fb 8a 57 ad a7 93  4c 5f 29 46 df c3 e5 86  |....W...L_)F....|
+000000c0  66 f1 c7 6b 14 79 cf 9d  cc e1 f5 3f 31 2c dc ff  |f..k.y.....?1,..|
+000000d0  77 99 14 9e 56 12 4e a4  cb 56 5c d6 c0 5b 57 dc  |w...V.N..V\..[W.|
+000000e0  22 72 12 2d d6 a0 8a c7  90 e6 41 66 78 1a d7 a6  |"r.-......Afx...|
+000000f0  87 db f1 e3 9b 86 8c cf  94 22 cf 81 99 20 bc 19  |........."... ..|
+00000100  50 f9 fe 6c ab ea d4 a2  ee f8 17 1d ae 37 86 2a  |P..l.........7.*|
+00000110  f9 83 3c 59 d0 aa 63 22  18 d5 12 40 be f7 02 f1  |..<Y..c"...@....|
+00000120  9a bf 07 39 23 73 23 a1  66 70 b7 be 9a 24 de 30  |...9#s#.fp...$.0|
+00000130  2f 62 6e f8 d5 ee 69 a7  87 3c 73 10 4c 7c 97 42  |/bn...i..<s.L|.B|
+00000140  62 b9 d5 74 40 f0 d7 b3  74 42 73 d7 41 bc 35 43  |b..t@...tBs.A.5C|
+00000150  87 2e c5 1b e9 15 e8 5e  18 b9 6b 57 2a ee 59 7a  |.......^..kW*.Yz|
+00000160  1c a6 2b cb b4 db e8 bb  99 87 74 4a ee 57 3a 87  |..+.......tJ.W:.|
+00000170  3c 2d b9 76 41 4a 7a a5  6a fa 92 e9 80 24 08 dc  |<-.vAJz.j....$..|
+00000180  18 44 4b 59 7c 81 99 29  f2 c4 55 b6 58 71 0d 68  |.DKY|..)..U.Xq.h|
+00000190  6b 06 bd 13 2c a0 04 15  2e 49 cc 99 7f a6 b4 5d  |k...,....I.....]|
+000001a0  d3 49 a5 21 15 d7 66 2d  a2 e8 cd a7 7e 46 c4 ac  |.I.!..f-....~F..|
+000001b0  89 ae cb 58 73 42 9f dc  c3 c9 5a 13 2f 6f f7 ab  |...XsB....Z./o..|
+000001c0  04 4b 9f f1 6c c4 ac 0f  f5 eb 8d 7a ef cf 01 00  |.K..l......z....|
+000001d0  8a 02 ec 16 09 c1 e9 27  81 32 70 b1 24 d4 db 4e  |.......'.2p.$..N|
+000001e0  9e 22 65 21 a7 8f 19 d5  c6 57 78 8a fa a6 41 87  |."e!.....Wx...A.|
+000001f0  52 eb 5d ef f8 7e 3b 34  a5 31 ff 33 33 fd 85 03  |R.]..~;4.1.33...|
+00000200  e4 94 56 ef 11 c0 fe 84  f6 87 94 26 de 7c bd d1  |..V........&.|..|
+00000210  1b ea 15 34 62 e5 da bd  e6 c4 b0 74 b5 27 ad 21  |...4b......t.'.!|
+00000220  39 16 c8 be e8 41 50 7b  de fb 71 10 4c b1 f4 5a  |9....AP{..q.L..Z|
+00000230  bf ea fd 9b 86 a5 c6 e7  2f c2 13 e4 d2 cd 32 7a  |......../.....2z|
+00000240  6b ad ab 43 12 3b 45 b9  5c e4 cf 2c f9 f3 44 2c  |k..C.;E.\..,..D,|
+00000250  11 31 ce c5 65 dd ea e6  52 bd 8a 35 d0 31 d4 4f  |.1..e...R..5.1.O|
+00000260  01 24 54 e4 d2 bf 6e 79  b2 bf a8 f0 5d 9d 72 44  |.$T...ny....].rD|
+00000270  6e df 29 8a d2 cc a8 d2  ee 0c 51 50 cd 71 a6 2a  |n.).......QP.q.*|
+00000280  fe 53 2e f7 ae fa 4c 34  d0 68 31 d5 69 be 64 a5  |.S....L4.h1.i.d.|
+00000290  03 54 31 1a dc f0 9e c7  82 1f 15 d1 64 ff 79 07  |.T1.........d.y.|
+000002a0  5e 71 3a 98 3c 21 a7 8e  1e bf 2d f3 86 4b 3f 30  |^q:.<!....-..K?0|
+000002b0  73 0d 7c 5d 57 1b a9 89  2b 52 70 84 8e e6 bb fe  |s.|]W...+Rp.....|
+000002c0  b7 1f 65 6a 08 63 58 16  81 51 09 b2 79 7d 84 c0  |..ej.cX..Q..y}..|
+000002d0  6f e1 ab 92 35 16 2e 8f  5c 17 2d 5e 68 7f d4 94  |o...5...\.-^h...|
+000002e0  5a 1b 1d 6c 5f e0 36 a0  ae 54 5b e9 39 1f bc 73  |Z..l_.6..T[.9..s|
+000002f0  f9 04 80 e9 36 d2 2c de  64 ca 08 95 d0 98 4b da  |....6.,.d.....K.|
+00000300  7b 0d 7f 79 1b a0 56 6c  dd 3c 40 52 3e 7a 8f 52  |{..y..Vl.<@R>z.R|
+00000310  3c c9 2f 17 03 03 00 99  07 91 f0 6b e0 bb 6f 0b  |<./........k..o.|
+00000320  ff 08 69 bc d2 1d f1 40  d2 d7 c7 f6 c2 b3 57 d7  |..i....@......W.|
+00000330  90 00 c9 9e ef 40 b6 96  86 0d 27 8b 6f ac 54 2f  |.....@....'.o.T/|
+00000340  73 b3 b4 82 1b d3 f5 e9  41 a7 fd d5 b1 67 f7 6e  |s.......A....g.n|
+00000350  2e c1 06 34 ef a3 b9 97  4d a8 64 4f f8 48 24 5c  |...4....M.dO.H$\|
+00000360  66 f4 d7 d4 e3 ad 45 fb  4a 42 0d 19 bb a1 cc b3  |f.....E.JB......|
+00000370  88 d2 2a d7 c3 53 c4 7b  08 a5 68 dc c4 1a f6 f3  |..*..S.{..h.....|
+00000380  a1 42 48 1c c9 2b 1f fb  5d fc 49 ed ce 16 14 34  |.BH..+..].I....4|
+00000390  34 01 c9 ef e6 29 9c 81  1a 7d 7b bd 95 eb ad 5f  |4....)...}{...._|
+000003a0  ce 19 30 9c e6 ae 09 15  3c 2b 38 8b e6 97 76 4e  |..0.....<+8...vN|
+000003b0  dd 17 03 03 00 35 d2 a1  3f 22 e9 2b b6 7a d1 d8  |.....5..?".+.z..|
+000003c0  7b 87 bf d1 bf 56 0b 55  52 d0 a9 cf ae 57 6e 6f  |{....V.UR....Wno|
+000003d0  29 0c c3 f7 f3 d4 bf ff  a4 6b 49 1a 57 57 27 89  |)........kI.WW'.|
+000003e0  e0 f5 bb d2 16 85 39 40  fd 77 a3                 |......9@.w.|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 00 35 02 ed 34 8f 83  |..........5..4..|
-00000010  44 27 8b 71 af c1 06 33  0b 25 aa 22 85 96 41 75  |D'.q...3.%."..Au|
-00000020  4f fe 46 82 ba 95 91 4c  cc a9 99 60 5c f7 72 7f  |O.F....L...`\.r.|
-00000030  e4 1f e4 99 6a c2 25 db  d0 11 5d fc d6 28 8f 56  |....j.%...]..(.V|
-00000040  17 03 03 00 17 fe e8 cf  ed a0 7a ce 77 57 e6 aa  |..........z.wW..|
-00000050  f0 ce 6d 2f 5c e5 1f 7d  37 c8 91 cf 17 03 03 00  |..m/\..}7.......|
-00000060  13 a4 a9 4c b5 33 38 4a  1e b7 65 9d 72 85 1b 79  |...L.38J..e.r..y|
-00000070  79 87 e3 bf                                       |y...|
+00000000  14 03 03 00 01 01 17 03  03 00 35 b3 39 ad 6b 24  |..........5.9.k$|
+00000010  47 e3 9f 11 f9 7e 9a cf  41 db c8 43 ce 86 ae ce  |G....~..A..C....|
+00000020  0c af 17 42 d7 24 57 13  e6 ba a7 44 7c 72 38 aa  |...B.$W....D|r8.|
+00000030  8f fa a2 a2 9f b0 ba 43  47 20 e8 03 3c 00 ee ad  |.......CG ..<...|
+00000040  17 03 03 00 17 ff 5b 79  f8 c8 0c 7a 52 6d b0 b2  |......[y...zRm..|
+00000050  22 17 3b 5d f9 75 23 bb  27 38 35 a6 17 03 03 00  |".;].u#.'85.....|
+00000060  13 d3 94 d9 b5 8b fa dc  b6 fe 26 ca b0 52 5c ef  |..........&..R\.|
+00000070  84 e3 3c f9                                       |..<.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-HelloRetryRequest b/src/crypto/tls/testdata/Client-TLSv13-HelloRetryRequest
index 10e13ec..4840339 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-HelloRetryRequest
+++ b/src/crypto/tls/testdata/Client-TLSv13-HelloRetryRequest
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 77 00 05 00 05  01 00 00 00 00 00 0a 00  |...w............|
 00000090  06 00 04 00 1d 00 17 00  0b 00 02 01 00 00 0d 00  |................|
 000000a0  1a 00 18 08 04 04 03 08  07 08 05 08 06 04 01 05  |................|
@@ -20,7 +20,7 @@
 00000010  9a 61 11 be 1d 8c 02 1e  65 b8 91 c2 a2 11 16 7a  |.a......e......z|
 00000020  bb 8c 5e 07 9e 09 e2 c8  a8 33 9c 20 00 00 00 00  |..^......3. ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
 00000050  0c 00 2b 00 02 03 04 00  33 00 02 00 17 14 03 03  |..+.....3.......|
 00000060  00 01 01                                          |...|
 >>> Flow 3 (client to server)
@@ -29,10 +29,10 @@
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000030  00 20 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |. ..............|
 00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000050  00 00 00 32 cc a8 cc a9  c0 2f c0 2b c0 30 c0 2c  |...2...../.+.0.,|
-00000060  c0 27 c0 13 c0 23 c0 09  c0 14 c0 0a 00 9c 00 9d  |.'...#..........|
-00000070  00 3c 00 2f 00 35 c0 12  00 0a 00 05 c0 11 c0 07  |.<./.5..........|
-00000080  13 01 13 03 13 02 01 00  00 98 00 05 00 05 01 00  |................|
+00000050  00 00 00 32 cc a9 cc a8  c0 2b c0 2f c0 2c c0 30  |...2.....+./.,.0|
+00000060  c0 09 c0 13 c0 0a c0 14  00 9c 00 9d 00 2f 00 35  |............./.5|
+00000070  c0 12 00 0a c0 23 c0 27  00 3c c0 07 c0 11 00 05  |.....#.'.<......|
+00000080  13 03 13 01 13 02 01 00  00 98 00 05 00 05 01 00  |................|
 00000090  00 00 00 00 0a 00 06 00  04 00 1d 00 17 00 0b 00  |................|
 000000a0  02 01 00 00 0d 00 1a 00  18 08 04 04 03 08 07 08  |................|
 000000b0  05 08 06 04 01 05 01 06  01 05 03 06 03 02 01 02  |................|
@@ -44,76 +44,76 @@
 00000110  32 42 e9 58 b6 d7 49 a6  b5 68 1a 41 03 56 6b dc  |2B.X..I..h.A.Vk.|
 00000120  5a 89                                             |Z.|
 >>> Flow 4 (server to client)
-00000000  16 03 03 00 9b 02 00 00  97 03 03 b5 7c 4a c4 82  |............|J..|
-00000010  67 2c 0d e4 cf 12 5a 8c  fc 44 10 da 7e ef ec ae  |g,....Z..D..~...|
-00000020  bc 59 6c 7d 62 b1 d8 95  5d 9d 3b 20 00 00 00 00  |.Yl}b...].; ....|
+00000000  16 03 03 00 9b 02 00 00  97 03 03 1d 65 62 8f 58  |............eb.X|
+00000010  2b 99 04 1d fd cc e3 0b  46 5c 55 a9 3a 80 76 60  |+.......F\U.:.v`|
+00000020  8f 52 09 6e 48 5d 5a e3  92 da a3 20 00 00 00 00  |.R.nH]Z.... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
 00000050  4f 00 2b 00 02 03 04 00  33 00 45 00 17 00 41 04  |O.+.....3.E...A.|
-00000060  51 c8 a4 d2 63 ec a1 b7  72 7e 42 30 8e d2 eb b0  |Q...c...r~B0....|
-00000070  3c e0 06 d0 69 39 b7 55  ee 47 c3 b3 b6 56 2d df  |<...i9.U.G...V-.|
-00000080  3e 0c 1c 92 cf f6 c4 52  13 90 fa e6 52 13 e6 6d  |>......R....R..m|
-00000090  35 46 de 60 05 a1 85 a9  ec 86 dc da 19 4d 21 67  |5F.`.........M!g|
-000000a0  17 03 03 00 17 d7 59 69  75 49 13 ac 27 ad 1c a9  |......YiuI..'...|
-000000b0  17 68 46 77 a2 22 0a f5  6f ce 70 67 17 03 03 02  |.hFw."..o.pg....|
-000000c0  6d ee 92 51 b3 07 0f 46  be 24 a1 12 02 7e d1 d4  |m..Q...F.$...~..|
-000000d0  b1 2e f5 87 f5 96 ed 00  77 f1 ad 1b 8e cd 1d 01  |........w.......|
-000000e0  41 78 6a ff 68 9f 6d ac  fe 92 8a c5 43 d2 c9 1d  |Axj.h.m.....C...|
-000000f0  a8 d8 0f 00 7e c1 06 a9  16 ba 13 94 e7 d9 cd e1  |....~...........|
-00000100  01 fd 52 12 be b0 04 14  85 d3 06 a2 63 d7 16 7a  |..R.........c..z|
-00000110  06 5f 1f c2 31 ea 27 1a  a5 1d f6 39 d2 b1 99 8c  |._..1.'....9....|
-00000120  e0 71 32 3b ef 4e d3 1c  21 3f 30 59 5b 3e 1f 64  |.q2;.N..!?0Y[>.d|
-00000130  3c 27 35 0f ee f4 75 5c  53 38 f8 43 87 55 88 28  |<'5...u\S8.C.U.(|
-00000140  17 8f 4c 2d 73 d0 bd db  43 25 2f da fb f3 f7 b4  |..L-s...C%/.....|
-00000150  63 90 08 24 c6 b3 ae 91  00 2d 4f bd af bc 22 82  |c..$.....-O...".|
-00000160  08 ef 29 c9 49 d2 73 97  ce 6c 8d 1e a2 cb 53 ff  |..).I.s..l....S.|
-00000170  fe 9c b1 14 58 6f 45 bf  ee 93 c0 9b 96 86 54 1a  |....XoE.......T.|
-00000180  fc fe 84 c3 88 13 92 d4  d7 de 00 07 d4 f7 ef 8e  |................|
-00000190  5e 5f b0 12 c9 6a 81 df  05 e6 c3 a1 f6 8a bc 06  |^_...j..........|
-000001a0  bc 45 47 06 d4 45 70 78  f9 16 0f d2 f4 ae b5 94  |.EG..Epx........|
-000001b0  e6 ac b5 bf e3 40 d1 fe  20 07 23 f8 65 fe 57 b2  |.....@.. .#.e.W.|
-000001c0  63 a0 db 7b fa 12 25 2b  1f 1c df 66 ee c4 84 80  |c..{..%+...f....|
-000001d0  4a 95 64 3d 9f c2 e9 eb  7c 59 72 1c 52 68 fa 5a  |J.d=....|Yr.Rh.Z|
-000001e0  b3 d6 9e dc 51 d6 ac 0b  34 f1 66 42 4b 99 1d cb  |....Q...4.fBK...|
-000001f0  94 f4 08 c6 57 f9 97 87  54 9c 3b ba 4e 21 c7 b3  |....W...T.;.N!..|
-00000200  a0 d9 41 33 22 c4 3f a4  29 e4 7a 3c a1 86 e0 65  |..A3".?.).z<...e|
-00000210  f4 ff 67 c5 32 ae 16 01  67 8e 16 d7 28 5e b3 19  |..g.2...g...(^..|
-00000220  c6 18 c7 27 0d 01 8e 04  87 fb 6b f9 72 ee 00 ff  |...'......k.r...|
-00000230  25 f9 c5 dd bc 30 45 63  2d 4d 2d 9d ea 7f 54 aa  |%....0Ec-M-...T.|
-00000240  ac 9e d8 a2 ae c2 e3 64  b7 3d 54 56 67 39 e8 96  |.......d.=TVg9..|
-00000250  a5 5d fd 1e 01 2a 0c 7d  ee f1 4e fc 1b 19 f9 ef  |.]...*.}..N.....|
-00000260  60 dd e1 b2 94 f3 5f 54  d4 05 f7 86 83 6f 97 43  |`....._T.....o.C|
-00000270  4e 30 c1 49 cc 5e 98 10  5c 4e 32 84 97 70 c8 b9  |N0.I.^..\N2..p..|
-00000280  6d 0b c2 23 ab f9 e8 85  6f 0a 2a 99 e7 12 33 e8  |m..#....o.*...3.|
-00000290  f2 62 6f 65 0c 3d ff 9f  e6 15 eb 1d 24 0e e9 8a  |.boe.=......$...|
-000002a0  28 e0 09 31 23 a4 5c 2c  25 49 b4 0c 5f 18 e1 12  |(..1#.\,%I.._...|
-000002b0  82 16 6e 79 68 21 fb 5a  68 73 dd f7 2f aa e2 f9  |..nyh!.Zhs../...|
-000002c0  85 8d af c6 84 50 af 84  95 12 c8 32 a6 eb f0 93  |.....P.....2....|
-000002d0  a2 bd 97 d3 ba 76 a8 2e  a2 44 2f 98 23 ca 78 cd  |.....v...D/.#.x.|
-000002e0  7a 5f bf ab 19 00 72 b5  b3 e0 a7 b5 da 47 05 c8  |z_....r......G..|
-000002f0  44 0b 6c 7f 0b 4c 99 79  3c 47 7e e9 25 bd a8 4d  |D.l..L.y<G~.%..M|
-00000300  7a 1c 17 aa 00 dc f8 d8  98 5b 8e e4 30 9f 52 9e  |z........[..0.R.|
-00000310  d3 13 ea 82 65 8b 43 1f  05 f9 3a 86 09 e0 ed b9  |....e.C...:.....|
-00000320  8d 42 75 c7 dd 70 5d 04  c5 a4 68 04 e1 36 17 03  |.Bu..p]...h..6..|
-00000330  03 00 99 52 81 9b 5c ed  c2 08 48 13 d9 4f 0a 52  |...R..\...H..O.R|
-00000340  db 15 fc 73 66 03 85 10  b3 32 f3 e9 60 f1 c5 30  |...sf....2..`..0|
-00000350  e4 85 d8 ab 85 c7 52 f0  1e 99 88 cf b0 e1 f9 c7  |......R.........|
-00000360  c1 8a d0 ed 0f 0d 34 05  35 63 a6 52 bf 91 db f0  |......4.5c.R....|
-00000370  b2 46 fb d9 68 95 ec a7  e4 fc ff f7 f0 7f 54 db  |.F..h.........T.|
-00000380  a8 96 fe 9d 12 f0 38 3e  4f 68 ff 27 1c 25 a6 1d  |......8>Oh.'.%..|
-00000390  1f 89 9e 21 34 97 b9 7e  6e 2a c2 df 47 22 7d a6  |...!4..~n*..G"}.|
-000003a0  aa 7a 4a fd 11 b0 73 10  f5 16 8b 2c 3a af a6 7a  |.zJ...s....,:..z|
-000003b0  cc 3d 4b f0 36 43 60 db  53 2a 4e 2c 1b 2c 0a 54  |.=K.6C`.S*N,.,.T|
-000003c0  01 ff ad 7e 93 a8 d0 76  da 5a 88 88 17 03 03 00  |...~...v.Z......|
-000003d0  35 d0 36 70 7c 4c 6a 10  bd 43 50 2c 47 74 f9 ed  |5.6p|Lj..CP,Gt..|
-000003e0  9f 0b d7 33 82 74 2f fd  81 4d 08 d6 cf f4 13 4e  |...3.t/..M.....N|
-000003f0  de ec 84 bf 79 35 ee 72  8a a3 d0 61 29 94 ad 79  |....y5.r...a)..y|
-00000400  04 42 0f 2b 65 a1                                 |.B.+e.|
+00000060  1c 01 c6 9e c8 49 43 49  6f 0f 17 f3 ce 87 1a 0f  |.....ICIo.......|
+00000070  1f 2c 70 18 e4 29 f2 16  a2 e0 02 b7 9d 52 bc b9  |.,p..).......R..|
+00000080  d4 b0 1d 19 da 3a 38 f6  93 04 0b ae 5f 60 45 87  |.....:8....._`E.|
+00000090  57 80 20 27 c6 9c d4 eb  ec c0 85 df f5 aa be de  |W. '............|
+000000a0  17 03 03 00 17 d4 a9 5f  09 d3 e6 47 ad a7 7b 38  |......._...G..{8|
+000000b0  a3 b8 02 37 16 ec 03 56  df d5 8d ec 17 03 03 02  |...7...V........|
+000000c0  6d be 1b 2a 60 52 3c 01  2e 6e 7f e3 68 fa de 09  |m..*`R<..n..h...|
+000000d0  ed 5e 8f 0f a0 34 d5 0a  8b 2f 30 8f 6c 56 9e fe  |.^...4.../0.lV..|
+000000e0  e6 9a a9 f1 6e 7c 63 a7  d8 88 e2 95 fa 17 ad 0c  |....n|c.........|
+000000f0  49 20 93 18 3c ba db fc  a1 14 60 2c 77 d4 44 5f  |I ..<.....`,w.D_|
+00000100  69 9c c7 a3 b9 d0 ee e8  c5 ec 45 d3 79 d0 ee 04  |i.........E.y...|
+00000110  fd c3 6d 12 1a f2 6e 62  9f eb ff 32 88 17 4c df  |..m...nb...2..L.|
+00000120  20 4f cc f9 fd d5 7c 8b  8c c2 da 7d 8a c9 f9 27  | O....|....}...'|
+00000130  32 06 75 fe 75 e2 bb bd  6c 31 5d 32 af 36 95 39  |2.u.u...l1]2.6.9|
+00000140  92 6c 32 e5 4f b5 f7 07  9f b3 1b b8 10 a8 d9 db  |.l2.O...........|
+00000150  d3 b0 40 2f 1e e6 54 f5  35 73 7d 22 b3 6b b8 3c  |..@/..T.5s}".k.<|
+00000160  83 82 8a 75 f4 ec 18 94  57 0c de 98 41 73 61 63  |...u....W...Asac|
+00000170  5b 95 3e 4e d4 02 c3 b7  f9 4c 6f 01 c9 52 3c b9  |[.>N.....Lo..R<.|
+00000180  ad 61 83 2c 89 6d 63 40  fd d4 67 83 36 8b 9a 1c  |.a.,.mc@..g.6...|
+00000190  ca 93 16 d8 e3 91 08 d1  3f ba af cb d9 69 09 10  |........?....i..|
+000001a0  07 a7 54 9c ee a2 7d 97  ce b6 1f 31 9b 85 b0 82  |..T...}....1....|
+000001b0  fc 22 87 70 93 59 9c c9  e3 07 9b d0 c0 a4 1d d4  |.".p.Y..........|
+000001c0  2e 36 c0 72 b6 d5 2a f5  b3 fa ab fb 1a 90 05 51  |.6.r..*........Q|
+000001d0  b7 19 15 af d9 b2 5f 32  ef e6 5a 2d 4a 2c 7f a9  |......_2..Z-J,..|
+000001e0  43 cf b8 ac e4 8a f0 bf  68 90 b9 7c 1c 7e fa f0  |C.......h..|.~..|
+000001f0  bc e3 a9 4f a7 2d 3a f3  12 eb b1 93 b4 b9 1b d7  |...O.-:.........|
+00000200  81 31 db 58 c4 8e 9f 46  44 39 74 a1 a8 b0 78 0c  |.1.X...FD9t...x.|
+00000210  b9 23 6d 90 bb a8 b0 7c  e2 a3 a3 c4 e6 83 32 5d  |.#m....|......2]|
+00000220  ea 5a a4 3d 94 ca 51 3c  71 28 cf 43 27 9f 66 9b  |.Z.=..Q<q(.C'.f.|
+00000230  ec 49 0f a4 12 f5 a3 96  cd 3e 05 5b 9c d0 07 6f  |.I.......>.[...o|
+00000240  8a 11 df 2f be a7 1d 0d  9f a8 04 41 3d 5e 1b f6  |.../.......A=^..|
+00000250  b0 10 9b 6a 49 da 6c f9  6c 6e 2e 6c 9b cf f1 fe  |...jI.l.ln.l....|
+00000260  49 92 2b 16 3f 63 ef 87  71 9c da 0d 49 63 2a 4c  |I.+.?c..q...Ic*L|
+00000270  b5 82 c8 b0 75 5b 7b 89  39 cd 9a da dc 42 d1 1f  |....u[{.9....B..|
+00000280  92 61 e1 71 b9 b5 d2 40  3c 7a 4a 8d 91 1f e6 9d  |.a.q...@<zJ.....|
+00000290  79 37 71 3c dc a3 98 0b  b3 64 39 74 f1 8f 84 35  |y7q<.....d9t...5|
+000002a0  1d 6b b7 0a f9 aa 26 55  a8 39 7f 11 26 18 98 fe  |.k....&U.9..&...|
+000002b0  94 fb 5d e4 a1 2f 0f 3b  f0 b6 78 d5 87 32 73 6e  |..]../.;..x..2sn|
+000002c0  3e b1 3e 3c 19 31 7a ae  d8 73 67 96 56 9c 38 a6  |>.><.1z..sg.V.8.|
+000002d0  bc 39 1f 11 74 ad 69 c6  d2 40 0f 65 d8 ee aa 87  |.9..t.i..@.e....|
+000002e0  b3 4c 6c 1a 1d 62 4a 7a  d9 15 05 54 0d 8a 22 68  |.Ll..bJz...T.."h|
+000002f0  8e 41 22 b0 ee 41 b3 94  5d 1a 62 d8 bb ac f2 87  |.A"..A..].b.....|
+00000300  ad 91 19 e7 e1 bc 29 3b  96 8c d1 76 99 e5 82 48  |......);...v...H|
+00000310  0b 87 6a 93 3b 2c b7 c1  73 07 53 7c 1f 9f 48 dd  |..j.;,..s.S|..H.|
+00000320  71 da 55 e1 4a a3 86 d2  ff 23 b2 1d ea b0 17 03  |q.U.J....#......|
+00000330  03 00 99 75 af 84 36 54  8e 17 09 c7 2e 72 de 7d  |...u..6T.....r.}|
+00000340  29 5c 94 a9 e3 d3 d0 9b  3e a0 84 e6 cf b4 48 d8  |)\......>.....H.|
+00000350  dd 7c 8a 82 96 15 aa cb  95 38 88 9e 48 c4 bf 75  |.|.......8..H..u|
+00000360  9c f4 07 ed 5d 4d 36 8b  58 7f 9c 32 0b f9 d2 44  |....]M6.X..2...D|
+00000370  3d d6 ab 3b 3d 38 1f 8d  7e e8 b6 26 57 c9 c6 98  |=..;=8..~..&W...|
+00000380  49 4f 1e ad 5d fa 8b ca  bc ce 99 f2 d9 5b 14 54  |IO..]........[.T|
+00000390  56 0c 59 c8 22 9f 77 f1  db 92 43 c3 dd a5 29 ec  |V.Y.".w...C...).|
+000003a0  0d 79 0d b3 04 3f 4b 6b  d6 a8 da 99 64 94 78 a5  |.y...?Kk....d.x.|
+000003b0  e9 cd 7e f8 0c fb 72 d6  03 89 dd 00 13 f3 14 18  |..~...r.........|
+000003c0  ba 59 3c 04 7f 6a b5 62  37 56 2e 2d 17 03 03 00  |.Y<..j.b7V.-....|
+000003d0  35 af eb 05 4e ec ee 4b  d6 6b 03 35 d8 ba a3 cf  |5...N..K.k.5....|
+000003e0  50 c6 80 07 90 92 1c ed  1f d2 d5 12 e3 7f 74 1a  |P.............t.|
+000003f0  2c 3b 4b 6c f4 58 af 9a  1a cd 90 f4 d8 78 97 09  |,;Kl.X.......x..|
+00000400  2f f6 35 c1 29 b8                                 |/.5.).|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 35 4b f7 dd  b6 64 32 61 42 e7 b2 93  |....5K...d2aB...|
-00000010  b8 4b dd 7c 25 c6 57 5b  68 d5 f2 d9 27 85 ee cf  |.K.|%.W[h...'...|
-00000020  09 44 79 8d 8e 14 0f 84  44 e5 16 a9 bf d9 14 bb  |.Dy.....D.......|
-00000030  22 73 c7 a9 24 c1 dd 38  1e 63 17 03 03 00 17 63  |"s..$..8.c.....c|
-00000040  56 45 91 62 9c 00 4b d6  ae f4 dc 17 a2 89 55 0d  |VE.b..K.......U.|
-00000050  c3 d4 f3 12 8b bf 17 03  03 00 13 1f ac ed f8 80  |................|
-00000060  31 7f 75 9f 6c a1 48 6e  20 89 b8 45 08 33        |1.u.l.Hn ..E.3|
+00000000  17 03 03 00 35 8d 07 5a  33 f5 d1 e7 6d 71 48 45  |....5..Z3...mqHE|
+00000010  3e 2a c0 7e 66 03 77 b5  69 b1 e5 13 04 0e 0d ea  |>*.~f.w.i.......|
+00000020  6f 80 46 a1 9a 54 09 6f  a7 be b7 a3 a1 0c d4 ba  |o.F..T.o........|
+00000030  0e 7d 00 8f 1b 01 0b d4  6b 4c 17 03 03 00 17 b9  |.}......kL......|
+00000040  fd 5a 5c a1 c2 33 71 63  99 25 bd 03 a3 24 a7 b6  |.Z\..3qc.%...$..|
+00000050  e7 42 04 6a 81 c5 17 03  03 00 13 b6 4a f1 0a 26  |.B.j........J..&|
+00000060  95 e8 fb 4b d1 db 24 95  8f 65 1f 3c 5d b9        |...K..$..e.<].|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-KeyUpdate b/src/crypto/tls/testdata/Client-TLSv13-KeyUpdate
index d1efba9..ea10f66 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-KeyUpdate
+++ b/src/crypto/tls/testdata/Client-TLSv13-KeyUpdate
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 7b 00 05 00 05  01 00 00 00 00 00 0a 00  |...{............|
 00000090  0a 00 08 00 1d 00 17 00  18 00 19 00 0b 00 02 01  |................|
 000000a0  00 00 0d 00 1a 00 18 08  04 04 03 08 07 08 05 08  |................|
@@ -16,87 +16,87 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 a2 49 b5 61 fe  |....z...v...I.a.|
-00000010  e3 52 ca 87 58 57 0f ec  bc 71 51 a9 50 7c ac 5e  |.R..XW...qQ.P|.^|
-00000020  af 4e 47 56 81 6c 92 d9  10 3d d0 20 00 00 00 00  |.NGV.l...=. ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 86 ed 46 3d 38  |....z...v....F=8|
+00000010  c5 47 10 b5 4e ac e5 b7  d7 ba cc 23 db f5 0a f4  |.G..N......#....|
+00000020  5e d3 62 af 47 8a 23 34  59 5c db 20 00 00 00 00  |^.b.G.#4Y\. ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 75  |..+.....3.$... u|
-00000060  c4 ba b0 c4 9b a0 57 6a  ca e4 9c c6 eb f8 66 5a  |......Wj......fZ|
-00000070  d4 64 36 34 71 9d 6d 0f  2f 34 b8 ad b7 4a 55 14  |.d64q.m./4...JU.|
-00000080  03 03 00 01 01 17 03 03  00 17 ec 4c 36 aa 81 cf  |...........L6...|
-00000090  61 2c 2f 6c 35 e8 25 62  54 17 ae 9b 46 b0 96 f5  |a,/l5.%bT...F...|
-000000a0  0f 17 03 03 02 6d 6f 6c  27 e5 53 42 db 32 b4 2c  |.....mol'.SB.2.,|
-000000b0  6a 70 56 a7 0d 3a 7f a3  d7 fe 04 4f 0a 3e 52 8c  |jpV..:.....O.>R.|
-000000c0  52 1e 3a 26 5d 47 b1 6b  da 90 e2 74 50 0d 6e fa  |R.:&]G.k...tP.n.|
-000000d0  1b 3f 17 3b 21 f7 fa f7  c7 c3 e3 14 05 09 76 b2  |.?.;!.........v.|
-000000e0  27 66 bc 42 7e 49 4b ff  3a f1 3f a3 1a d4 9e 03  |'f.B~IK.:.?.....|
-000000f0  3f b6 a8 87 98 50 f3 d8  cb 8b a2 e9 2a ea ff bc  |?....P......*...|
-00000100  50 18 d0 57 58 c5 e9 c8  96 67 01 8b e2 a3 f4 77  |P..WX....g.....w|
-00000110  5e 1d 93 89 b6 f6 57 7d  93 b6 62 86 0a 21 18 56  |^.....W}..b..!.V|
-00000120  8c 14 25 df 47 1a b3 23  e6 99 d1 fc dc 07 0a 38  |..%.G..#.......8|
-00000130  9a 05 c8 3f 23 5c c5 d3  c4 48 fb b2 fd 9f 83 37  |...?#\...H.....7|
-00000140  1d 0c 85 9c 2b e6 ae 42  aa ad d4 5a 9e 49 89 b7  |....+..B...Z.I..|
-00000150  b0 c2 c5 ec 42 89 88 87  6e 54 3d 73 b2 f1 5f 0f  |....B...nT=s.._.|
-00000160  4b 49 3f 6b a3 8f 5f 99  bf fe af e9 25 ac 27 b7  |KI?k.._.....%.'.|
-00000170  e7 96 bb 4a c8 e8 9e f1  2c 23 c2 e7 96 ba b4 fe  |...J....,#......|
-00000180  d5 94 b5 72 82 bd 7f c2  e1 af b4 bd db c7 15 20  |...r........... |
-00000190  85 60 bb 02 f6 4b ef 09  3e a1 4e b9 77 64 0a 4a  |.`...K..>.N.wd.J|
-000001a0  2c 05 82 96 91 be 23 44  50 c1 c5 6c 05 55 51 42  |,.....#DP..l.UQB|
-000001b0  84 87 20 71 65 8d 09 86  66 fa 88 8b 54 21 44 34  |.. qe...f...T!D4|
-000001c0  df 6f ce a3 e9 12 4a e0  90 76 bb 1a f5 00 79 cb  |.o....J..v....y.|
-000001d0  d8 82 3b 88 c8 6a 5b a1  49 49 a0 c0 f7 d9 8f 89  |..;..j[.II......|
-000001e0  f2 04 59 2b 0c 6f e2 3f  b8 a8 c9 aa bf 2e 18 74  |..Y+.o.?.......t|
-000001f0  45 b5 35 34 9a bb fa 77  e8 46 b2 f8 6d 41 65 36  |E.54...w.F..mAe6|
-00000200  d9 f8 64 81 a6 50 63 b4  73 3e fb f9 b3 3e 03 3d  |..d..Pc.s>...>.=|
-00000210  d1 f4 b5 c1 ac f8 3f 4d  73 b7 da 16 8a 37 c9 a7  |......?Ms....7..|
-00000220  51 33 b1 68 69 19 0b 26  de a6 42 4d 22 a3 e8 c0  |Q3.hi..&..BM"...|
-00000230  7b 1d 66 e7 70 26 44 f7  62 3f 3d 0d e2 02 50 61  |{.f.p&D.b?=...Pa|
-00000240  db 9b 5e e4 49 e8 32 32  7a c0 03 37 a8 c6 85 80  |..^.I.22z..7....|
-00000250  4a 7e 39 b5 ba 6c cb 6f  53 e5 90 d0 0d 9c 2e e5  |J~9..l.oS.......|
-00000260  90 df 9b b1 c5 3f 16 98  a9 dd a1 b5 7a 48 04 0e  |.....?......zH..|
-00000270  15 f9 60 a7 35 0b 33 a1  93 4b 73 5f b3 46 a6 43  |..`.5.3..Ks_.F.C|
-00000280  ea a3 6e 4c fa bb 24 44  cd 48 85 c1 9f ea c2 14  |..nL..$D.H......|
-00000290  92 48 2e 35 43 30 dc e6  76 23 0b e4 2f 28 13 c1  |.H.5C0..v#../(..|
-000002a0  e1 bb 2d 9f de cf 10 8f  c3 8f 48 eb 64 eb 6d ef  |..-.......H.d.m.|
-000002b0  2a b3 c5 d6 85 db a2 05  b2 46 f8 77 aa 2c fb 14  |*........F.w.,..|
-000002c0  be 09 e7 11 33 88 cb 71  1b ca 46 cb 79 c6 99 eb  |....3..q..F.y...|
-000002d0  43 bb 59 c6 91 3b 0f 1a  76 cb c7 3b ef 07 c9 cb  |C.Y..;..v..;....|
-000002e0  3a 75 ac 14 d9 53 08 ca  4d 45 48 24 4a af 4e 94  |:u...S..MEH$J.N.|
-000002f0  0e 81 31 63 d1 f6 67 25  7d c0 dd 02 05 1b ce 38  |..1c..g%}......8|
-00000300  69 cf e7 6a bb b5 02 85  00 82 71 a6 e3 c0 33 b8  |i..j......q...3.|
-00000310  78 51 55 17 03 03 00 99  b3 5c cb a4 a3 6c e9 fa  |xQU......\...l..|
-00000320  33 25 04 21 28 66 e7 d4  22 02 8f d4 3e cc e1 20  |3%.!(f.."...>.. |
-00000330  15 5b 5a 55 14 d3 2b a5  de 7b 95 48 3c 26 68 22  |.[ZU..+..{.H<&h"|
-00000340  a3 0d c6 ac 7f ec d3 7b  fa 4d 51 20 6f 32 97 bc  |.......{.MQ o2..|
-00000350  fa 0c d6 8e bf ee 13 ca  b3 cf 00 c5 f5 87 f1 cb  |................|
-00000360  9b 63 22 e6 61 99 83 78  69 1d 03 f1 0b 66 c5 c4  |.c".a..xi....f..|
-00000370  2e 6f d8 b5 59 93 f7 40  3c 40 4e 1a 58 af b5 37  |.o..Y..@<@N.X..7|
-00000380  ce dd 83 dd b1 78 a8 ba  a3 35 f8 9f 0c 47 1e fb  |.....x...5...G..|
-00000390  aa 9b b5 5f 11 4c b9 0c  c1 a0 01 47 87 f9 e6 1f  |..._.L.....G....|
-000003a0  d5 e5 3f a7 15 4d c8 a5  79 9c e5 bc 62 6f cb cd  |..?..M..y...bo..|
-000003b0  86 17 03 03 00 35 e7 4d  67 3a 39 5b ac 13 89 cc  |.....5.Mg:9[....|
-000003c0  c4 dc 20 2b a4 b2 3c 5d  96 f1 45 17 52 12 ed 85  |.. +..<]..E.R...|
-000003d0  00 f0 7e 73 3a 6d a2 46  b8 59 7f e8 6f 46 06 e1  |..~s:m.F.Y..oF..|
-000003e0  43 c9 ca af a9 3e ca d6  42 4b 41                 |C....>..BKA|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 e3  |..+.....3.$... .|
+00000060  ff 35 33 31 c9 d8 5c 68  2a e5 73 98 4d 11 5b d7  |.531..\h*.s.M.[.|
+00000070  06 18 a9 dd 0e 4a 21 92  5b 15 8f bb 91 a9 6c 14  |.....J!.[.....l.|
+00000080  03 03 00 01 01 17 03 03  00 17 ea ac f8 a0 41 47  |..............AG|
+00000090  af 01 fb 51 2e ec 3b 79  f1 8a 54 2b 93 45 33 c3  |...Q..;y..T+.E3.|
+000000a0  79 17 03 03 02 6d 0e c9  a4 55 8e 8c 09 55 cd a6  |y....m...U...U..|
+000000b0  d4 dc 1e 5a de ee 56 c8  c2 ac 12 77 77 76 82 fc  |...Z..V....wwv..|
+000000c0  a6 44 cb c8 c3 16 c4 5e  bc 3f f3 3b 6c 33 f3 35  |.D.....^.?.;l3.5|
+000000d0  ed bd 8e 37 1a 25 de 7e  b3 88 71 ce f9 e5 9b a6  |...7.%.~..q.....|
+000000e0  99 11 0f 71 6b 36 11 04  66 a2 5f 74 1c c6 6a 99  |...qk6..f._t..j.|
+000000f0  49 84 d1 36 96 df 6d 2c  c5 a3 cf 5a c9 37 22 8a  |I..6..m,...Z.7".|
+00000100  72 e4 d4 25 ed 4a b1 c4  85 5a 9a f7 de 0b dd 41  |r..%.J...Z.....A|
+00000110  7d 14 63 35 2e 1c 77 6c  9e 6f 41 d1 cb 29 ca 6d  |}.c5..wl.oA..).m|
+00000120  88 1c 35 53 1b 14 24 79  84 ec 85 0d de e3 0f 2c  |..5S..$y.......,|
+00000130  23 ae 41 72 85 fb 43 36  82 ba 8f 78 79 a2 c3 95  |#.Ar..C6...xy...|
+00000140  72 19 ea 1d 2f 29 0e d5  11 85 e4 cc 8c a5 f4 8e  |r.../)..........|
+00000150  39 ba 88 8f e1 5a 54 7c  53 8b a3 1a 44 9c ae 5b  |9....ZT|S...D..[|
+00000160  1f 0e ea 06 f1 8e 5f 22  d1 ef ee e1 4c b6 1a 26  |......_"....L..&|
+00000170  db 53 96 e6 bc 0b 2f ee  b7 fa 47 af 1e 9c f6 7b  |.S..../...G....{|
+00000180  81 97 0f c3 08 9b 2c a3  de bd f7 8a 1e 13 ad de  |......,.........|
+00000190  a5 fc 5f c7 7a 53 72 e5  17 dc 0a eb 90 91 29 2e  |.._.zSr.......).|
+000001a0  7a a5 09 fd be 31 ff 81  ec a3 fc 91 41 4f cb c7  |z....1......AO..|
+000001b0  27 c3 39 8f cd 77 62 72  9a e9 e9 16 da 90 b6 6b  |'.9..wbr.......k|
+000001c0  05 70 c8 aa f5 cd 88 13  4d ff a5 a9 0f e7 d2 d3  |.p......M.......|
+000001d0  97 2b eb e1 d7 fe 74 da  fb 1e af 94 e6 52 18 48  |.+....t......R.H|
+000001e0  5b e8 c3 10 9d 76 de 17  86 67 83 4a e9 fa 30 e8  |[....v...g.J..0.|
+000001f0  46 95 f5 81 b1 a5 76 38  57 37 3a 8d df ad e7 30  |F.....v8W7:....0|
+00000200  41 b2 94 31 da 0d d6 5c  df 76 01 cd 4d c2 1b fe  |A..1...\.v..M...|
+00000210  bc 69 41 ac dd d7 dd 0a  7c 5b 31 5c c8 1e b3 14  |.iA.....|[1\....|
+00000220  39 20 51 26 6d e5 55 27  a4 9a bb fc 3d 4b 6a b0  |9 Q&m.U'....=Kj.|
+00000230  54 92 ee 33 1b 9b d5 41  fd ef 21 c6 f0 f8 90 a0  |T..3...A..!.....|
+00000240  c4 f5 86 d4 d9 c7 89 6f  67 23 37 31 44 2f 8f 55  |.......og#71D/.U|
+00000250  0a aa e1 9a ec 32 26 e2  ce 96 90 c6 f5 cc 95 79  |.....2&........y|
+00000260  da 0c b4 c1 62 d3 0a 8d  7b 83 33 8e af ff 57 c0  |....b...{.3...W.|
+00000270  5b ca 0f b5 64 10 81 43  12 86 67 cf b2 0a 53 f2  |[...d..C..g...S.|
+00000280  04 46 4f 99 ee e2 cd ce  3e 82 1f 34 43 26 f9 4c  |.FO.....>..4C&.L|
+00000290  57 b0 10 c0 37 40 9c 4f  fb 14 fa 4e 1e 4b 40 da  |W...7@.O...N.K@.|
+000002a0  cc c3 d0 d7 ee 63 18 2e  97 06 a6 49 69 07 7a 3e  |.....c.....Ii.z>|
+000002b0  da 47 68 70 b0 10 bf 8d  18 d2 14 c0 18 18 b2 61  |.Ghp...........a|
+000002c0  45 54 e8 20 34 f8 a3 74  5a 8d aa c2 63 af e8 ff  |ET. 4..tZ...c...|
+000002d0  f9 1b 33 d6 34 c2 f2 c2  3d d8 0e 32 7a 10 cc 21  |..3.4...=..2z..!|
+000002e0  02 22 a6 aa 7d 15 c3 7b  3f a2 50 5a 4e 53 ec f5  |."..}..{?.PZNS..|
+000002f0  11 dd 48 6e 7e e9 c5 94  2c c4 9a 6e 10 a6 c6 a5  |..Hn~...,..n....|
+00000300  9d e1 c5 43 e6 69 a1 91  65 50 eb e6 76 db f0 09  |...C.i..eP..v...|
+00000310  14 45 ef 17 03 03 00 99  e4 82 99 6b d8 57 ca 1b  |.E.........k.W..|
+00000320  78 98 88 ad c7 04 b7 d2  b2 d5 00 3b a9 bf 86 66  |x..........;...f|
+00000330  a7 30 72 95 29 2a 27 9f  9a 3d bd 0b e6 a0 04 22  |.0r.)*'..=....."|
+00000340  56 3d d8 08 84 a7 e7 c5  67 74 34 7d 57 1f c9 df  |V=......gt4}W...|
+00000350  71 0c 97 55 5a d9 8d 99  df 49 b5 a9 57 6d b0 c7  |q..UZ....I..Wm..|
+00000360  2d 4b 70 9d e7 e3 70 31  f0 2f 32 15 7b 67 b4 4c  |-Kp...p1./2.{g.L|
+00000370  f0 f0 4a 16 a5 37 b2 ae  9b 2a 72 7c 2e d8 22 a1  |..J..7...*r|..".|
+00000380  2b 91 f2 14 fc f9 27 fd  ca ad 27 dd 15 11 df b1  |+.....'...'.....|
+00000390  cc 4c 3a 45 3f b6 7c 53  c5 d0 82 49 1a f2 28 63  |.L:E?.|S...I..(c|
+000003a0  a2 be 6f 2f db d8 d3 76  0a 12 fa 87 14 00 11 e7  |..o/...v........|
+000003b0  1f 17 03 03 00 35 0c af  49 a1 ba 14 d4 e5 5c cf  |.....5..I.....\.|
+000003c0  c8 f7 fb 93 e3 d5 45 ac  59 ed 56 3c 1c e6 53 6a  |......E.Y.V<..Sj|
+000003d0  77 62 a3 1a 8c 55 14 b0  d8 6f dd 1c fb a4 6f 25  |wb...U...o....o%|
+000003e0  18 28 ab 9e a5 ad 6d 97  63 f4 9c                 |.(....m.c..|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 00 35 4d ad c5 c7 cc  |..........5M....|
-00000010  5a 34 8a f8 5f 71 83 af  fa 94 df 2a 94 a0 c4 8e  |Z4.._q.....*....|
-00000020  5e 00 f7 02 e1 30 62 a5  49 27 58 0b 1f fa 46 98  |^....0b.I'X...F.|
-00000030  f0 b8 6f 42 e3 3a 7f 26  77 b6 46 8f ab c6 5d d6  |..oB.:.&w.F...].|
-00000040  17 03 03 00 17 90 81 68  7a 48 8d 3b 59 9e 11 6f  |.......hzH.;Y..o|
-00000050  86 b5 24 e4 d9 e0 60 9f  c2 4f 3d 33              |..$...`..O=3|
+00000000  14 03 03 00 01 01 17 03  03 00 35 12 2a a7 31 42  |..........5.*.1B|
+00000010  e9 65 d6 88 9c 49 85 53  16 6c 85 bc d1 70 65 3a  |.e...I.S.l...pe:|
+00000020  aa cd d3 12 ce 69 e3 3a  63 7a 8d ed 54 df 9c 97  |.....i.:cz..T...|
+00000030  4e ef 7c 20 ce 41 ac 33  a9 3b fc 5e 35 34 65 00  |N.| .A.3.;.^54e.|
+00000040  17 03 03 00 17 11 5f 88  3b 45 0e 4e 8a 26 43 a3  |......_.;E.N.&C.|
+00000050  9e 77 10 76 8c e1 ed d3  19 f4 27 5f              |.w.v......'_|
 >>> Flow 4 (server to client)
-00000000  17 03 03 00 16 94 83 fa  cc 66 b4 60 c0 c7 6d b3  |.........f.`..m.|
-00000010  6e 8c 84 9d 89 76 61 3d  69 fd 29                 |n....va=i.)|
+00000000  17 03 03 00 16 7d 92 67  60 95 ba fa a0 5f 03 e9  |.....}.g`...._..|
+00000010  2b e6 53 ed fb 6b 4f b9  e9 09 10                 |+.S..kO....|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 16 60 cb 39  3d 7d 79 01 88 93 bd bf  |.....`.9=}y.....|
-00000010  23 3b d1 f3 a4 5e 78 ea  cd 0f 5e                 |#;...^x...^|
+00000000  17 03 03 00 16 06 17 fb  4b 33 c7 06 d5 a9 40 e8  |........K3....@.|
+00000010  c7 09 65 b2 5c 2d 45 2f  bf 45 a8                 |..e.\-E/.E.|
 >>> Flow 6 (server to client)
-00000000  17 03 03 00 1a 88 13 b4  f1 5f cc 63 1e 99 9f 85  |........._.c....|
-00000010  60 ff 0e 97 13 59 64 2a  c3 0d 2b ac ca a2 25     |`....Yd*..+...%|
+00000000  17 03 03 00 1a 04 5e c0  bb ad 6c 2f 65 61 5c 39  |......^...l/ea\9|
+00000010  a9 e2 c4 9e 0e 4c 68 d2  a9 97 8a bf 95 39 3f     |.....Lh......9?|
 >>> Flow 7 (client to server)
-00000000  17 03 03 00 1d 4f f2 48  ea b8 d6 75 8e 97 ab 54  |.....O.H...u...T|
-00000010  29 57 50 5b 59 40 59 d3  7a 3c 01 43 6a 33 30 bb  |)WP[Y@Y.z<.Cj30.|
-00000020  d4 40 17 03 03 00 13 18  fc b7 ac eb e7 52 6d f0  |.@...........Rm.|
-00000030  d4 d3 03 c6 5f 4e ea e3  7b 4e                    |...._N..{N|
+00000000  17 03 03 00 1d 1f 74 d0  fb ed fa 59 81 21 7e f0  |......t....Y.!~.|
+00000010  41 c8 6e 6b 9f b6 1a 86  ad 2e ac 9e 3d 3b 66 c9  |A.nk........=;f.|
+00000020  4a 87 17 03 03 00 13 7b  76 c4 85 c1 41 47 6d 35  |J......{v...AGm5|
+00000030  98 86 02 d5 3b e4 6b 4c  3e 7a                    |....;.kL>z|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-P256-ECDHE b/src/crypto/tls/testdata/Client-TLSv13-P256-ECDHE
index e6d8118..db87bef 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-P256-ECDHE
+++ b/src/crypto/tls/testdata/Client-TLSv13-P256-ECDHE
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 96 00 05 00 05  01 00 00 00 00 00 0a 00  |................|
 00000090  04 00 02 00 17 00 0b 00  02 01 00 00 0d 00 1a 00  |................|
 000000a0  18 08 04 04 03 08 07 08  05 08 06 04 01 05 01 06  |................|
@@ -18,77 +18,77 @@
 00000100  07 9f 6c 4b 5b 83 56 e2  32 42 e9 58 b6 d7 49 a6  |..lK[.V.2B.X..I.|
 00000110  b5 68 1a 41 03 56 6b dc  5a 89                    |.h.A.Vk.Z.|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 9b 02 00 00  97 03 03 b5 3c c8 fe 64  |............<..d|
-00000010  f6 04 7d 28 a4 25 7c 1b  f5 0b e6 6d 0b f5 2f ec  |..}(.%|....m../.|
-00000020  78 c1 bd 5a cf c8 19 d9  5c 54 72 20 00 00 00 00  |x..Z....\Tr ....|
+00000000  16 03 03 00 9b 02 00 00  97 03 03 bb 03 f1 4e 88  |..............N.|
+00000010  23 9e 85 ee 32 13 db 0d  69 11 48 47 c6 c9 e5 b2  |#...2...i.HG....|
+00000020  25 9d 0c 27 87 05 3f 58  42 60 2d 20 00 00 00 00  |%..'..?XB`- ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
 00000050  4f 00 2b 00 02 03 04 00  33 00 45 00 17 00 41 04  |O.+.....3.E...A.|
-00000060  d7 63 55 0e 0d 7b fb 09  a9 61 92 70 2b 52 9c 38  |.cU..{...a.p+R.8|
-00000070  2d e8 2a 68 27 b7 15 3e  4a 1e 92 c8 08 7b 5c c9  |-.*h'..>J....{\.|
-00000080  8d d4 aa 97 63 42 a5 3e  4b e8 7d 37 98 d9 8c a6  |....cB.>K.}7....|
-00000090  e7 c7 45 9f 73 48 bd c3  14 82 67 5b bb 19 bd a5  |..E.sH....g[....|
-000000a0  14 03 03 00 01 01 17 03  03 00 17 67 d9 cb 2b d1  |...........g..+.|
-000000b0  d2 30 7d b3 3f c1 77 5a  6c 87 41 2c 29 83 36 19  |.0}.?.wZl.A,).6.|
-000000c0  74 38 17 03 03 02 6d ac  0c 4f fe b5 93 6a fa 9f  |t8....m..O...j..|
-000000d0  e9 76 a7 c3 8a bb 4a 64  7a 04 35 58 e6 a2 d8 7a  |.v....Jdz.5X...z|
-000000e0  cf 99 1c 60 13 1a ca c6  e6 10 11 7a f1 f4 be ec  |...`.......z....|
-000000f0  1d 2d db b1 a5 3a dd 7e  10 2b 65 ca 40 b2 5f fc  |.-...:.~.+e.@._.|
-00000100  3f c9 df 7d 26 c1 fc b7  2d 67 a1 2d a2 22 b3 40  |?..}&...-g.-.".@|
-00000110  79 d4 c8 b6 73 f7 93 8a  97 4f b7 ab b6 0c ca 14  |y...s....O......|
-00000120  3c 1e 6c 27 c0 be 01 d7  98 ef 93 78 f5 14 15 21  |<.l'.......x...!|
-00000130  4c f8 8e a6 f7 72 b2 b7  bc c2 3e 9b b7 e4 0d 15  |L....r....>.....|
-00000140  b5 69 75 e9 61 10 e4 d5  8e 60 44 88 bf 5f df f9  |.iu.a....`D.._..|
-00000150  8d 70 54 4e f6 0f 37 70  ff b8 6b c0 4f fb 61 c1  |.pTN..7p..k.O.a.|
-00000160  48 00 96 9b da 05 0f 78  7a 87 f5 b1 69 f6 4f 8e  |H......xz...i.O.|
-00000170  80 74 7b e0 e5 b7 0f ba  7d 9d 4c ff c9 d7 7c b9  |.t{.....}.L...|.|
-00000180  f0 bd dd 34 8e 77 5f 3b  48 10 10 6f ed c7 84 15  |...4.w_;H..o....|
-00000190  7a 0c 26 3e 5d 9d 58 07  02 8c e3 fa f0 6b 86 df  |z.&>].X......k..|
-000001a0  76 af 3c 13 c4 93 28 7a  17 04 98 91 26 72 5f aa  |v.<...(z....&r_.|
-000001b0  cf b2 9e 37 a9 93 12 bd  1d 92 64 b8 82 60 b0 b5  |...7......d..`..|
-000001c0  1d 2c 4e 18 24 11 3b 52  33 05 f0 3b f2 27 ed a6  |.,N.$.;R3..;.'..|
-000001d0  f6 4a 82 b6 df 05 a0 07  a3 9d 73 0a 3c 7f 02 47  |.J........s.<..G|
-000001e0  60 c8 aa 20 b4 9c cd 48  12 a3 82 fe 99 4e 0c bb  |`.. ...H.....N..|
-000001f0  ec 4f 10 75 26 99 a4 ed  5e 4a 34 51 38 88 2c 3c  |.O.u&...^J4Q8.,<|
-00000200  0b 8d f8 65 84 38 47 c8  31 30 82 71 3f 54 e3 3f  |...e.8G.10.q?T.?|
-00000210  f1 e6 2c ef a3 fe 02 34  16 58 21 55 6e 0f 95 d3  |..,....4.X!Un...|
-00000220  3e 18 e5 c4 fa 95 65 07  d8 4b 31 4b fa a7 85 74  |>.....e..K1K...t|
-00000230  6c 1c a3 7c 7b c6 20 e0  1f 28 33 6d 61 93 d0 7d  |l..|{. ..(3ma..}|
-00000240  e7 c4 5c 27 c9 d9 ca f9  fe 21 6f 7f 05 34 37 54  |..\'.....!o..47T|
-00000250  30 59 68 e1 04 36 60 52  d7 fc 4f 8c 67 f6 42 88  |0Yh..6`R..O.g.B.|
-00000260  bc 41 5f 8e 2c 05 dd 6a  b0 49 6c d8 8e 9c 9e 06  |.A_.,..j.Il.....|
-00000270  35 f9 f1 33 f2 54 b0 3f  9e bd 4f c7 48 aa a3 9e  |5..3.T.?..O.H...|
-00000280  fe 69 79 16 e0 5a ca 48  72 fe 52 4a f1 6f f1 e0  |.iy..Z.Hr.RJ.o..|
-00000290  8c fe 16 15 ce c9 87 dc  9b 66 4d 3a bb 05 21 82  |.........fM:..!.|
-000002a0  21 65 cb 7b da 06 1a 0b  53 ee 60 e4 79 0f bc 5d  |!e.{....S.`.y..]|
-000002b0  b6 52 fd 3b 33 28 97 6c  67 d7 ab 3d b0 da bb ac  |.R.;3(.lg..=....|
-000002c0  0d d9 06 81 a3 6c 1f ad  b8 05 20 63 2b c7 cb 4b  |.....l.... c+..K|
-000002d0  e2 96 6e 3d f1 9c 0a 6a  c6 01 3e 3a d0 54 c8 09  |..n=...j..>:.T..|
-000002e0  9b 17 a0 cc d6 d0 82 d1  02 a8 eb 9d 91 7e 30 b9  |.............~0.|
-000002f0  3d 5e 6d 43 fc 50 f8 9f  80 67 7a e3 33 30 cd b7  |=^mC.P...gz.30..|
-00000300  00 b3 bc 17 50 82 6c 80  67 bd c4 12 11 b1 53 22  |....P.l.g.....S"|
-00000310  96 67 07 90 d4 54 5c f1  5d ca cd f8 b5 35 94 e0  |.g...T\.]....5..|
-00000320  21 e6 58 d7 b0 32 ca 24  90 11 30 f5 2b 1d ca 3d  |!.X..2.$..0.+..=|
-00000330  6a 6d 35 fa 17 03 03 00  99 ad ab 79 79 28 a0 a9  |jm5........yy(..|
-00000340  9a cd 6d 8d 8c 92 2e 83  3d d4 be c7 50 61 f5 49  |..m.....=...Pa.I|
-00000350  97 6c ab 92 d4 a7 1a 6f  fc 5b dd 6e 73 0d bd d2  |.l.....o.[.ns...|
-00000360  09 52 9f c9 de bb 8d 09  0a 4f e0 c5 9a 08 79 4c  |.R.......O....yL|
-00000370  fc 01 b3 94 45 f6 1d bd  8d 23 62 14 14 65 4c 2a  |....E....#b..eL*|
-00000380  d9 ad 8f 76 5a 5e 9d da  68 37 c7 b1 54 1e b4 bd  |...vZ^..h7..T...|
-00000390  d3 15 b8 89 94 87 8b 17  17 0f 4c dc db a8 3b 2f  |..........L...;/|
-000003a0  e5 e2 25 d6 ec f6 f4 bb  ab d0 c5 7f 2a cb c6 57  |..%.........*..W|
-000003b0  84 50 3a e7 62 8b 76 ae  6a 06 6b 85 1c 23 f1 d1  |.P:.b.v.j.k..#..|
-000003c0  10 e2 6f 57 8c 20 7d da  2d f8 bc c5 df 4e 7c 22  |..oW. }.-....N|"|
-000003d0  d8 36 17 03 03 00 35 62  fa d4 65 7f 9a 97 5b ec  |.6....5b..e...[.|
-000003e0  25 4a 3a 43 18 08 08 fb  7f 9d 3b 73 64 9e f3 7a  |%J:C......;sd..z|
-000003f0  28 f1 a0 0e 00 7a 51 74  0e 6b 90 c6 39 7a 09 98  |(....zQt.k..9z..|
-00000400  6e d8 63 cc 1f f0 8f bc  37 66 27 a0              |n.c.....7f'.|
+00000060  85 3c 83 1b e5 02 e9 0d  89 cc c0 f7 af 1e ba af  |.<..............|
+00000070  de ad cb 8f 4d 58 04 40  c2 60 e9 41 8b 94 26 76  |....MX.@.`.A..&v|
+00000080  73 64 c3 27 e3 51 9d 5f  21 97 59 a3 02 cc 20 61  |sd.'.Q._!.Y... a|
+00000090  b7 ef cb bb d9 31 b6 b7  b1 77 ea 8d 69 13 13 48  |.....1...w..i..H|
+000000a0  14 03 03 00 01 01 17 03  03 00 17 ab ac 2e 62 de  |..............b.|
+000000b0  b6 f4 c7 35 cf b4 75 fc  a4 a5 2c 40 68 f5 48 80  |...5..u...,@h.H.|
+000000c0  d2 8b 17 03 03 02 6d a9  36 b5 10 78 1f af 79 65  |......m.6..x..ye|
+000000d0  dd ee 36 08 b9 96 e2 bf  09 53 c7 ee 12 19 1b de  |..6......S......|
+000000e0  96 25 cb a7 55 71 28 22  16 3f 4b 3e 15 a2 2e 57  |.%..Uq(".?K>...W|
+000000f0  99 85 28 b2 01 16 3a 75  ff 5e 21 39 6c be fc bd  |..(...:u.^!9l...|
+00000100  24 33 ec c7 50 83 49 91  8a ed 43 38 b5 48 cd 92  |$3..P.I...C8.H..|
+00000110  dd 9a f1 b7 90 61 3b 8f  ff b9 cf 97 3d 8e 23 8e  |.....a;.....=.#.|
+00000120  d1 78 52 b4 ba a1 75 97  32 52 e3 1f c8 43 ca b7  |.xR...u.2R...C..|
+00000130  89 46 e6 30 c2 c5 32 b3  5f a8 ea ea e2 31 d2 41  |.F.0..2._....1.A|
+00000140  23 5e 64 a2 b9 23 27 73  b2 df 77 cd 04 8b dd 37  |#^d..#'s..w....7|
+00000150  a5 77 df 0e 4f 9d 01 22  7b be 7a 0c 18 5c 8b 62  |.w..O.."{.z..\.b|
+00000160  7c 6b 7e a7 54 8c 69 97  50 d7 cf a0 a4 cb 3a 3b  ||k~.T.i.P.....:;|
+00000170  76 7b 0a de 80 d1 40 c3  05 5e b3 4e 71 cd 03 82  |v{....@..^.Nq...|
+00000180  d5 95 d0 38 ab 65 83 24  66 d2 31 2d 9e 58 16 87  |...8.e.$f.1-.X..|
+00000190  b8 ab 4c 4e 75 40 7e 3d  33 2f f4 ed 0b a8 11 1c  |..LNu@~=3/......|
+000001a0  7a a4 b0 e3 6a 73 d0 6e  e6 82 39 c1 cf 57 a4 9a  |z...js.n..9..W..|
+000001b0  8b fc bc 8e e8 6a c3 e1  b0 64 18 55 6d 19 30 25  |.....j...d.Um.0%|
+000001c0  34 f8 b1 ef cf 3c 04 08  69 10 ad 08 67 5b 8d 64  |4....<..i...g[.d|
+000001d0  eb 83 72 39 2e 56 e4 d2  e9 f2 da 40 3e 85 29 ab  |..r9.V.....@>.).|
+000001e0  5b 83 e5 b0 d2 9b eb c3  99 6e 2a f3 78 95 d4 7a  |[........n*.x..z|
+000001f0  7f bf 9c 16 55 77 43 4d  67 f7 4a 6f 40 27 a2 82  |....UwCMg.Jo@'..|
+00000200  b9 86 05 5d 90 e2 52 a2  d4 7c 7b 3e da 30 c1 aa  |...]..R..|{>.0..|
+00000210  30 2e 9a 34 c5 59 dd db  e9 25 67 da 22 47 f2 be  |0..4.Y...%g."G..|
+00000220  cc c8 5a 4e da cf ad 86  8d bd b0 68 26 69 ea 3a  |..ZN.......h&i.:|
+00000230  1c 1e 29 ae e1 09 63 88  f0 81 31 f9 70 a7 92 27  |..)...c...1.p..'|
+00000240  32 9e 3b 6f 09 5e 42 20  53 88 bf 09 8b a8 17 5c  |2.;o.^B S......\|
+00000250  24 7c 18 1f 9c 99 9b db  6d 11 26 8e 92 2c a1 b4  |$|......m.&..,..|
+00000260  5c 9f d9 0a a8 af 25 f7  84 f5 65 d1 b1 6c d8 aa  |\.....%...e..l..|
+00000270  49 c7 a6 13 47 2e 55 f4  2e de 3d 43 c1 15 8d 60  |I...G.U...=C...`|
+00000280  c1 27 59 7e 7b 14 ee 54  09 fc 99 79 c9 bf fb 45  |.'Y~{..T...y...E|
+00000290  2d 32 ed 1a 2c 84 bc f4  a2 b5 5f 4e cf 60 29 91  |-2..,....._N.`).|
+000002a0  90 b6 ab 06 8f 2d 43 a5  a5 54 0d 67 52 c2 1c fb  |.....-C..T.gR...|
+000002b0  f3 41 b7 67 b4 50 05 86  19 75 93 8b 6c c3 bf 08  |.A.g.P...u..l...|
+000002c0  64 f2 df ff 37 6d 2f 1e  3a 28 f4 ba 27 8d 61 d5  |d...7m/.:(..'.a.|
+000002d0  79 70 19 82 99 7a e5 68  f3 c1 23 da 5d e1 98 b2  |yp...z.h..#.]...|
+000002e0  69 ca 42 83 61 29 3f d9  20 51 f2 a9 ea 1c 0b 5a  |i.B.a)?. Q.....Z|
+000002f0  20 b0 af 70 cc c5 ad 72  6b 09 85 56 8a 26 86 cf  | ..p...rk..V.&..|
+00000300  4e 9a 56 97 5d 63 8d 1d  46 04 48 16 c9 1e 91 47  |N.V.]c..F.H....G|
+00000310  74 53 28 51 7e 3c 84 a1  50 d6 f3 ac 31 ce 04 18  |tS(Q~<..P...1...|
+00000320  81 38 0d c5 3d f5 d5 04  2f f0 96 9b 73 49 4c d6  |.8..=.../...sIL.|
+00000330  89 d9 b9 be 17 03 03 00  99 3a 37 ed 2d 98 80 f9  |.........:7.-...|
+00000340  d0 04 14 12 8c 63 45 cc  8d cb 29 5f 0e f0 86 ef  |.....cE...)_....|
+00000350  8d 6c d6 0f ef 66 99 91  e8 8c d7 7b 21 07 7e 96  |.l...f.....{!.~.|
+00000360  84 f8 f9 5b 1b 39 8b 4f  16 ec 5c 69 7b 18 09 5d  |...[.9.O..\i{..]|
+00000370  95 f1 f3 73 4b 8f 84 66  ee 61 85 dd fe ea 36 df  |...sK..f.a....6.|
+00000380  e5 2a 71 ec 2d 7e 47 1c  b7 79 2d 87 f8 dc 44 27  |.*q.-~G..y-...D'|
+00000390  8a f1 13 6e df ca 59 79  9b 18 01 7e 31 bd 44 f7  |...n..Yy...~1.D.|
+000003a0  8d ad 1c 97 e7 e1 b9 a6  17 d1 25 d1 b8 0d 04 bb  |..........%.....|
+000003b0  21 a4 08 db a2 08 87 5c  04 9a 11 fa c6 24 db 20  |!......\.....$. |
+000003c0  42 79 9c 97 dd 6c d2 e7  24 b4 79 47 be f3 43 87  |By...l..$.yG..C.|
+000003d0  0f 95 17 03 03 00 35 9e  7d 12 0e d6 0a e6 af a3  |......5.}.......|
+000003e0  83 dd eb 08 73 2d 43 7e  81 85 51 4c d1 ad d0 77  |....s-C~..QL...w|
+000003f0  8d 28 62 44 41 9c b0 e9  93 d7 3d 07 e4 e1 6e 4c  |.(bDA.....=...nL|
+00000400  a8 5b 4a 3f 58 3f 97 07  73 d7 5a 62              |.[J?X?..s.Zb|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 00 35 ba 59 57 3e a3  |..........5.YW>.|
-00000010  cd 02 7f 7c c2 16 f5 6b  ec 42 66 aa a2 7a 3d 47  |...|...k.Bf..z=G|
-00000020  43 c9 02 4b a3 72 d0 4d  fa f8 32 28 1a 19 16 6a  |C..K.r.M..2(...j|
-00000030  7c 0e 4a 75 80 94 34 fe  30 7b d0 52 15 48 10 30  ||.Ju..4.0{.R.H.0|
-00000040  17 03 03 00 17 5d de 53  df 00 21 ca 6d 69 ff 45  |.....].S..!.mi.E|
-00000050  2e 53 57 db 3f 8d d8 6c  5a e1 f8 cc 17 03 03 00  |.SW.?..lZ.......|
-00000060  13 43 d9 94 95 41 af 1d  80 a7 f2 28 2a 44 50 8d  |.C...A.....(*DP.|
-00000070  41 8f 82 09                                       |A...|
+00000000  14 03 03 00 01 01 17 03  03 00 35 df 31 1a 84 e2  |..........5.1...|
+00000010  93 54 01 f2 d1 e8 32 6c  32 91 e5 64 86 68 ad 5f  |.T....2l2..d.h._|
+00000020  aa 24 54 86 b2 39 92 24  06 65 5c 06 67 43 7d 09  |.$T..9.$.e\.gC}.|
+00000030  79 78 c6 f3 cf 6c a9 ec  38 e3 ec 81 c4 9b c5 33  |yx...l..8......3|
+00000040  17 03 03 00 17 25 ed 98  67 8f ad e8 60 ce 5b ad  |.....%..g...`.[.|
+00000050  ab 3e 67 64 e3 8d bf 98  96 a2 3d 99 17 03 03 00  |.>gd......=.....|
+00000060  13 9d 28 f2 24 fe d6 11  b0 64 d6 8a 8d c1 81 e0  |..(.$....d......|
+00000070  17 d5 a0 f3                                       |....|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-X25519-ECDHE b/src/crypto/tls/testdata/Client-TLSv13-X25519-ECDHE
index 4e3eb76..4a43382 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-X25519-ECDHE
+++ b/src/crypto/tls/testdata/Client-TLSv13-X25519-ECDHE
@@ -3,10 +3,10 @@
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 20 00 00 00 00  |........... ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a8  |.............2..|
-00000050  cc a9 c0 2f c0 2b c0 30  c0 2c c0 27 c0 13 c0 23  |.../.+.0.,.'...#|
-00000060  c0 09 c0 14 c0 0a 00 9c  00 9d 00 3c 00 2f 00 35  |...........<./.5|
-00000070  c0 12 00 0a 00 05 c0 11  c0 07 13 01 13 03 13 02  |................|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 32 cc a9  |.............2..|
+00000050  cc a8 c0 2b c0 2f c0 2c  c0 30 c0 09 c0 13 c0 0a  |...+./.,.0......|
+00000060  c0 14 00 9c 00 9d 00 2f  00 35 c0 12 00 0a c0 23  |......./.5.....#|
+00000070  c0 27 00 3c c0 07 c0 11  00 05 13 03 13 01 13 02  |.'.<............|
 00000080  01 00 00 75 00 05 00 05  01 00 00 00 00 00 0a 00  |...u............|
 00000090  04 00 02 00 1d 00 0b 00  02 01 00 00 0d 00 1a 00  |................|
 000000a0  18 08 04 04 03 08 07 08  05 08 06 04 01 05 01 06  |................|
@@ -16,75 +16,75 @@
 000000e0  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
 000000f0  c2 ed 90 99 5f 58 cb 3b  74                       |...._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 5d 2e e6 ba 34  |....z...v..]...4|
-00000010  6c 42 bb 48 58 fe c5 f0  95 f9 34 11 04 b5 2a f4  |lB.HX.....4...*.|
-00000020  f1 16 41 db 14 a0 19 d8  43 7c 09 20 00 00 00 00  |..A.....C|. ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 eb 1b 4e e5 65  |....z...v....N.e|
+00000010  54 ab 07 68 1c d9 32 0f  0e c2 ae a3 2a 89 37 50  |T..h..2.....*.7P|
+00000020  23 51 61 7d 68 60 34 0d  40 2f b8 20 00 00 00 00  |#Qa}h`4.@/. ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 01 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 82  |..+.....3.$... .|
-00000060  de 1b d1 83 7a e1 46 cc  c7 36 15 62 48 07 6b f6  |....z.F..6.bH.k.|
-00000070  eb 0a 53 a3 34 cd 34 ee  cc 0c d0 c9 02 d5 38 14  |..S.4.4.......8.|
-00000080  03 03 00 01 01 17 03 03  00 17 3d 0c 61 12 1b 55  |..........=.a..U|
-00000090  6e f4 13 59 c8 4a e7 12  63 5d bf be 34 9f d7 2a  |n..Y.J..c]..4..*|
-000000a0  c2 17 03 03 02 6d 82 e8  43 93 e4 80 4d a7 d2 cf  |.....m..C...M...|
-000000b0  43 9d 71 8d cc 78 e8 e9  58 7e 28 53 57 6d 95 1e  |C.q..x..X~(SWm..|
-000000c0  fb 98 05 ec 66 47 d9 a1  6a b5 f4 28 09 4a 6c 4c  |....fG..j..(.JlL|
-000000d0  ee a0 1a 86 e7 29 c0 0e  d8 e0 ca 2d bb 50 e4 34  |.....).....-.P.4|
-000000e0  8d 66 be 54 b5 df 94 fc  69 0e a6 9a 76 8b 8f f5  |.f.T....i...v...|
-000000f0  a9 01 1a 1d 8d b0 ae a9  0c 10 58 13 f9 91 80 43  |..........X....C|
-00000100  69 f8 3f 03 14 8e 73 1a  ce 52 72 86 3d 60 8b 0f  |i.?...s..Rr.=`..|
-00000110  38 e7 4b 43 f0 b3 4b 12  3a a7 cd 4b ac ef 7d fb  |8.KC..K.:..K..}.|
-00000120  27 3a 38 36 ad a5 90 eb  57 80 47 99 bc c6 58 55  |':86....W.G...XU|
-00000130  15 6f 53 f7 83 ca 2b 89  ae be 23 9a 83 3c 6b b1  |.oS...+...#..<k.|
-00000140  10 67 a2 c4 65 e0 3a 25  05 4a 5b dc 10 96 93 b8  |.g..e.:%.J[.....|
-00000150  72 7b 1f 07 6d c7 48 c4  86 b5 a5 cd bf 6f d4 98  |r{..m.H......o..|
-00000160  bc 71 5b 39 36 67 9b 1a  88 a1 74 c4 7d 34 7c 1b  |.q[96g....t.}4|.|
-00000170  a7 31 c1 04 77 b7 cd 30  8e 69 6c 99 c4 9f 0b b8  |.1..w..0.il.....|
-00000180  e4 53 03 b9 86 12 61 b0  fe 0e 37 df 99 77 00 3f  |.S....a...7..w.?|
-00000190  d4 10 c9 73 eb a2 9a 00  d6 cd 6a 5e 67 ec 55 ca  |...s......j^g.U.|
-000001a0  26 89 2f 11 9d 30 8f bd  5a 68 55 20 f5 93 44 5e  |&./..0..ZhU ..D^|
-000001b0  1f f2 24 20 fa 80 94 c7  01 62 c2 95 d3 18 c6 2c  |..$ .....b.....,|
-000001c0  00 42 fa ee 32 75 27 5f  df 81 f2 14 83 30 cd 25  |.B..2u'_.....0.%|
-000001d0  1d 6c 3a c5 f5 3f 6e b7  6a f0 cf 02 f9 a3 8d da  |.l:..?n.j.......|
-000001e0  96 55 31 2c 3c ef 62 c0  19 ac 36 f3 89 44 a4 a4  |.U1,<.b...6..D..|
-000001f0  60 c3 99 b5 db 9f c7 4c  9d fb f1 77 98 dc 90 0e  |`......L...w....|
-00000200  8a e2 0e e2 6a 25 6e 84  2b d6 dc 73 57 7a 6e 1d  |....j%n.+..sWzn.|
-00000210  41 2e d0 de 45 ab 49 f0  e3 64 e4 6a 02 fa 64 6f  |A...E.I..d.j..do|
-00000220  09 22 05 b5 0c 12 b0 57  e2 61 5a 63 b1 4c a4 e5  |.".....W.aZc.L..|
-00000230  79 c4 42 17 36 f0 0c 43  04 a5 d7 7c 3f 59 17 38  |y.B.6..C...|?Y.8|
-00000240  f0 f1 2c 2d be 6c 4e 58  e5 45 c9 c2 d6 df 7b b3  |..,-.lNX.E....{.|
-00000250  08 50 db e6 a8 ae 73 f2  82 09 6e 58 07 d3 87 e4  |.P....s...nX....|
-00000260  c2 70 c6 8f 8f 13 74 09  b1 7d 1a 42 e1 d1 72 41  |.p....t..}.B..rA|
-00000270  bd 71 cc f4 6c 7f 70 a2  99 95 34 b7 2c 08 af 43  |.q..l.p...4.,..C|
-00000280  43 ec 61 66 51 73 e2 87  b3 f3 ef ee 20 f2 55 58  |C.afQs...... .UX|
-00000290  c7 1a 0c ad dd 7b 44 9f  f1 ff 5e 2b 18 63 e1 45  |.....{D...^+.c.E|
-000002a0  88 5d c1 ce cb dc 42 ec  10 03 d4 d7 ae 2f ed ce  |.]....B....../..|
-000002b0  49 01 e3 1e de b0 68 ce  25 e0 69 b1 33 37 3d 0f  |I.....h.%.i.37=.|
-000002c0  b6 96 7e cd 7e 91 fb 82  a2 b8 66 6b 9a 44 83 c7  |..~.~.....fk.D..|
-000002d0  56 86 87 a5 f2 b1 06 16  a3 43 e1 29 fe f7 26 c9  |V........C.)..&.|
-000002e0  39 ea a4 b0 62 7b d5 9e  8a 0f 89 07 f9 a0 fc 45  |9...b{.........E|
-000002f0  bf ce 70 1d 75 7f fa db  2a 5b 32 02 bb 69 cc 72  |..p.u...*[2..i.r|
-00000300  cf 24 3d 92 20 d9 2f ee  a5 9d 72 33 23 f5 99 f5  |.$=. ./...r3#...|
-00000310  b1 82 eb 17 03 03 00 99  01 f0 87 1b 28 83 73 0f  |............(.s.|
-00000320  67 c8 76 69 e7 e6 ae d4  5c fc e0 e7 1c 6b 85 de  |g.vi....\....k..|
-00000330  de a0 9e 6c 1a 7d 90 31  d8 63 92 a1 bc f3 47 54  |...l.}.1.c....GT|
-00000340  c4 00 b9 62 30 db 1d 5b  c9 d5 e5 58 67 5e ab 68  |...b0..[...Xg^.h|
-00000350  3a 41 65 11 8d 9b a2 8c  4f e7 b7 76 ca c6 ca 2e  |:Ae.....O..v....|
-00000360  2d 6b 7b d1 90 41 9f 0c  c6 a5 18 4d d2 99 49 0b  |-k{..A.....M..I.|
-00000370  24 ab c5 84 cd a1 79 0a  0f 48 f3 f6 a4 f3 44 f3  |$.....y..H....D.|
-00000380  42 cb eb 6d 7d 16 b8 42  43 37 78 d9 e3 47 ce ee  |B..m}..BC7x..G..|
-00000390  c9 4b 3d 4f 47 ab 77 15  45 59 dd 31 02 f9 f8 60  |.K=OG.w.EY.1...`|
-000003a0  41 c6 dc e2 e3 25 8f 43  dd 77 c4 ce ba b9 63 c7  |A....%.C.w....c.|
-000003b0  5e 17 03 03 00 35 2a d8  c8 91 25 bb 27 c2 fc cd  |^....5*...%.'...|
-000003c0  b3 d0 c2 57 70 39 fc 81  d7 11 01 6c 72 ca 58 19  |...Wp9.....lr.X.|
-000003d0  c1 5d 72 9e 72 dc 70 2a  3d 1f 35 1c 05 4f 51 26  |.]r.r.p*=.5..OQ&|
-000003e0  30 72 97 a5 7a 7a 0a 7b  9e 91 03                 |0r..zz.{...|
+00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 17  |..+.....3.$... .|
+00000060  7d df 14 8a ad 43 51 c3  c2 08 3a ea f7 e3 96 6a  |}....CQ...:....j|
+00000070  b7 8b 61 66 d9 82 c5 7b  b9 77 bc 62 6a 19 04 14  |..af...{.w.bj...|
+00000080  03 03 00 01 01 17 03 03  00 17 4e 7b b6 d1 b1 19  |..........N{....|
+00000090  0d 0c d0 d3 5a 66 44 5c  81 49 74 f3 71 3b 97 5e  |....ZfD\.It.q;.^|
+000000a0  ee 17 03 03 02 6d 00 17  b1 4d b9 f5 fc ea 48 72  |.....m...M....Hr|
+000000b0  aa a5 1c 8b fe 97 08 54  ab 2d 0a 0e f7 51 41 bf  |.......T.-...QA.|
+000000c0  7b 14 ba b7 d9 0a 30 44  db b9 06 e7 6b a9 0a 94  |{.....0D....k...|
+000000d0  49 a2 29 50 f2 7f 7e 68  91 41 ad a9 cb ee e2 bd  |I.)P..~h.A......|
+000000e0  03 fd 95 79 ea c3 77 ee  88 3b 7a 81 15 9f 17 96  |...y..w..;z.....|
+000000f0  b2 db b9 f3 26 dd 75 69  ef 12 c0 63 b0 04 63 ae  |....&.ui...c..c.|
+00000100  aa b3 67 f8 7f a5 17 cf  56 5f ee 34 2d d7 83 23  |..g.....V_.4-..#|
+00000110  84 00 4b 94 1a 76 2a 01  ce 49 0a 57 7d c8 65 7a  |..K..v*..I.W}.ez|
+00000120  d7 16 34 1c a8 37 fd 71  d4 79 08 b1 44 9f 9e a7  |..4..7.q.y..D...|
+00000130  78 ab 9d 0d c4 80 0e 81  35 75 23 59 89 1b 2c d3  |x.......5u#Y..,.|
+00000140  bc c9 86 b9 7b 22 19 30  dd cc 68 93 ab d2 98 dd  |....{".0..h.....|
+00000150  c2 9f 20 af c9 1a 87 b3  28 73 84 83 ca 98 1d 60  |.. .....(s.....`|
+00000160  df 12 19 70 80 f2 ff 20  64 b5 8c ef e2 e8 6a 5a  |...p... d.....jZ|
+00000170  df 8e ba 95 d8 2c c4 b6  4f a1 33 8c 8d a3 fc d3  |.....,..O.3.....|
+00000180  c4 4b ba b2 6d 3a f7 da  38 23 5f 03 a7 92 13 76  |.K..m:..8#_....v|
+00000190  12 73 26 17 30 e0 21 f1  16 8f a1 e5 6d f0 21 a8  |.s&.0.!.....m.!.|
+000001a0  c6 25 64 86 95 5e 6f 4d  21 f0 f3 a3 27 23 2b 4b  |.%d..^oM!...'#+K|
+000001b0  90 03 ba 6c ce 9c 20 ed  69 15 76 cb 39 bc fd 44  |...l.. .i.v.9..D|
+000001c0  10 b4 72 d5 44 9d f7 eb  a4 b0 d5 07 20 a1 6b 71  |..r.D....... .kq|
+000001d0  16 e4 f7 8f a0 d8 fa 86  db e6 ef eb 63 41 a0 17  |............cA..|
+000001e0  83 71 0d 1c 4b ec 58 c3  90 9c ea 34 79 a7 91 43  |.q..K.X....4y..C|
+000001f0  ad 3d ff 28 c8 b4 3e 7a  b6 83 53 f4 99 0b 86 bc  |.=.(..>z..S.....|
+00000200  f2 cf ae 1d a7 5c 7f 57  d9 85 95 25 33 bb 4d 79  |.....\.W...%3.My|
+00000210  25 2e 54 6d 5d 14 32 68  7d 6e 45 bd b1 e1 24 30  |%.Tm].2h}nE...$0|
+00000220  c2 1c 45 b9 a2 42 ae b5  c6 6a 56 f9 8a 12 51 f9  |..E..B...jV...Q.|
+00000230  61 a2 9d 56 98 09 8d ea  70 17 48 d8 23 48 ca 18  |a..V....p.H.#H..|
+00000240  43 1e a2 bc 88 69 3d 45  95 89 cc f0 74 8d 88 36  |C....i=E....t..6|
+00000250  5e a8 1b be 88 41 35 8d  de a9 20 23 f3 5e ab c9  |^....A5... #.^..|
+00000260  61 22 2e 86 54 2f c4 4a  60 04 c2 e3 b8 cf 1a 41  |a"..T/.J`......A|
+00000270  a6 31 ab 7a b5 07 dc 54  82 89 b1 1f 9f 62 98 bc  |.1.z...T.....b..|
+00000280  bd 39 be 23 ed d5 bc 0d  8e a6 69 14 26 39 fe ed  |.9.#......i.&9..|
+00000290  98 c8 48 36 6c 8e 9f 93  57 7a ba 33 03 35 c6 de  |..H6l...Wz.3.5..|
+000002a0  55 03 63 e8 a4 53 08 0a  b0 a7 3e a3 cb f2 df 3d  |U.c..S....>....=|
+000002b0  cd 59 df ee f6 45 2d 77  39 32 4a 1f 08 21 e7 db  |.Y...E-w92J..!..|
+000002c0  52 2a 06 86 e6 00 98 ca  9f a3 ad 0f 7f d3 25 6d  |R*............%m|
+000002d0  56 58 21 e2 39 59 56 15  74 4d 18 37 f5 40 29 db  |VX!.9YV.tM.7.@).|
+000002e0  de be 49 77 e0 2c 5c 6b  ee b1 bd 4a ea 2a 07 94  |..Iw.,\k...J.*..|
+000002f0  0f 21 7c bb 1f bd 3e ad  9e b6 95 7d 16 e8 f0 4e  |.!|...>....}...N|
+00000300  de e2 ca 9c 34 9f b8 e5  57 d5 b7 b5 8d 60 dd c2  |....4...W....`..|
+00000310  ce 47 2c 17 03 03 00 99  37 37 20 49 98 44 f6 b4  |.G,.....77 I.D..|
+00000320  58 54 ff 5e b0 05 22 8e  c6 68 9a ae 49 51 e9 f1  |XT.^.."..h..IQ..|
+00000330  71 75 cf 1a 79 da 33 f1  5f 7e a1 02 81 05 12 8b  |qu..y.3._~......|
+00000340  a3 a8 ad 87 ee f0 87 da  f1 16 80 9d 2e fa 5a 22  |..............Z"|
+00000350  a5 f5 b9 14 f5 8f 9b 35  87 ba 1a f7 c4 17 c8 f6  |.......5........|
+00000360  a1 1e 28 cd fe 03 90 9f  f0 81 d3 80 bb 4c 1a b1  |..(..........L..|
+00000370  c6 11 de 19 a1 5a 3c 73  77 f0 70 b8 d1 38 16 f3  |.....Z<sw.p..8..|
+00000380  64 d0 8e 9c fe 4d 83 48  dc 20 78 db 6a 65 3f f4  |d....M.H. x.je?.|
+00000390  0f a0 70 cc 30 bb cd 86  51 0c 20 ea 59 a5 ed e8  |..p.0...Q. .Y...|
+000003a0  72 d9 5e f3 c3 41 0b 19  f3 97 0f fc 77 42 6d 15  |r.^..A......wBm.|
+000003b0  92 17 03 03 00 35 ac 97  30 a0 8a d8 d2 e6 4a 5b  |.....5..0.....J[|
+000003c0  f5 58 32 22 63 8e 36 2e  21 a2 30 33 ae 49 55 76  |.X2"c.6.!.03.IUv|
+000003d0  cf c8 b3 3f 82 8d c3 0e  ea 22 ec 8f 65 c8 c4 0d  |...?....."..e...|
+000003e0  bf cc 6a 86 e9 32 50 db  02 93 ec                 |..j..2P....|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 00 35 7d 5e 95 38 a2  |..........5}^.8.|
-00000010  d3 f4 04 59 57 2a 1a 86  ac 12 8e 17 88 fb 52 25  |...YW*........R%|
-00000020  1d 19 2c c5 ac 57 c9 bf  af 07 e7 c1 4d f3 dd f0  |..,..W......M...|
-00000030  13 ad a1 73 07 32 a4 c5  7c 9e ad 5a 88 59 57 4b  |...s.2..|..Z.YWK|
-00000040  17 03 03 00 17 e2 65 4f  bd 1f bb 00 a1 6b ae a4  |......eO.....k..|
-00000050  9d d3 d2 6e 7b 62 b5 09  19 d6 8f 1b 17 03 03 00  |...n{b..........|
-00000060  13 96 de 94 2b a7 bb c5  4b 7e 02 b2 27 07 4d 49  |....+...K~..'.MI|
-00000070  32 2b 83 48                                       |2+.H|
+00000000  14 03 03 00 01 01 17 03  03 00 35 e5 27 80 72 fd  |..........5.'.r.|
+00000010  6c 0d b5 a7 14 23 08 0b  f5 54 70 8c 29 61 d0 2a  |l....#...Tp.)a.*|
+00000020  81 2d 05 83 2a 21 1e 16  94 5b 65 0d 6a ca b6 81  |.-..*!...[e.j...|
+00000030  d9 9d 3c 5c 9c fe 2b 01  a8 3b 23 fb 9e eb 2c 56  |..<\..+..;#...,V|
+00000040  17 03 03 00 17 79 fd 43  29 72 96 e0 ad fd 7e 60  |.....y.C)r....~`|
+00000050  94 51 8d 8a 6e 6a 5d 6c  f3 0d 4b 74 17 03 03 00  |.Q..nj]l..Kt....|
+00000060  13 a4 7c e1 31 71 61 82  e7 7d 28 0f 63 d7 ae 76  |..|.1qa..}(.c..v|
+00000070  9c 71 37 cd                                       |.q7.|
diff --git a/src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial b/src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial
index a5d9ee4..cb3b8da 100644
--- a/src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial
+++ b/src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial
@@ -1,11 +1,11 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 63 01 00 00  5f 03 01 7a df fa af 20  |....c..._..z... |
-00000010  74 5a 83 3b 91 95 b4 9b  57 d8 6b f2 88 2a 68 e8  |tZ.;....W.k..*h.|
-00000020  b8 9e e7 88 a6 c5 e7 59  08 ff 9b 00 00 12 c0 0a  |.......Y........|
-00000030  c0 14 00 39 c0 09 c0 13  00 33 00 35 00 2f 00 ff  |...9.....3.5./..|
-00000040  01 00 00 24 00 0b 00 04  03 00 01 02 00 0a 00 0c  |...$............|
-00000050  00 0a 00 1d 00 17 00 1e  00 19 00 18 00 23 00 00  |.............#..|
-00000060  00 16 00 00 00 17 00 00                           |........|
+00000000  16 03 01 00 67 01 00 00  63 03 01 41 69 16 b5 d5  |....g...c..Ai...|
+00000010  c2 9d 36 2b 95 8e e5 41  9b 92 82 27 2a cc 4e 6e  |..6+...A...'*.Nn|
+00000020  5d f1 1b 58 49 3c 95 1d  8b 61 35 00 00 04 c0 14  |]..XI<...a5.....|
+00000030  00 ff 01 00 00 36 00 00  00 0e 00 0c 00 00 09 31  |.....6.........1|
+00000040  32 37 2e 30 2e 30 2e 31  00 0b 00 04 03 00 01 02  |27.0.0.1........|
+00000050  00 0a 00 0c 00 0a 00 1d  00 17 00 1e 00 19 00 18  |................|
+00000060  00 23 00 00 00 16 00 00  00 17 00 00              |.#..........|
 >>> Flow 2 (server to client)
 00000000  16 03 01 00 3b 02 00 00  37 03 01 00 00 00 00 00  |....;...7.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
@@ -51,43 +51,43 @@
 00000290  d4 db fe 3d 13 60 84 5c  21 d3 3b e9 fa e7 16 03  |...=.`.\!.;.....|
 000002a0  01 00 aa 0c 00 00 a6 03  00 1d 20 2f e5 7d a3 47  |.......... /.}.G|
 000002b0  cd 62 43 15 28 da ac 5f  bb 29 07 30 ff f6 84 af  |.bC.(.._.).0....|
-000002c0  c4 cf c2 ed 90 99 5f 58  cb 3b 74 00 80 bb 96 fe  |......_X.;t.....|
-000002d0  bf a0 81 24 bc 40 b4 e2  37 b1 c9 66 2d c3 c1 bb  |...$.@..7..f-...|
-000002e0  89 fb 28 23 60 76 b1 e6  2c c1 e9 06 d0 95 c5 10  |..(#`v..,.......|
-000002f0  17 ce 79 36 c2 14 e0 1d  1d 0d 0e 49 3e b9 7f 00  |..y6.......I>...|
-00000300  ad e3 1d 37 ab ce 2c 37  dc eb be aa 6c 28 33 05  |...7..,7....l(3.|
-00000310  53 fd 06 17 b4 85 b9 b8  35 1c a7 3c bb 07 3f 4b  |S.......5..<..?K|
-00000320  53 98 00 4d 8e 49 bd 35  55 64 92 d0 a0 db 05 80  |S..M.I.5Ud......|
-00000330  57 24 78 cd 10 ed ae f0  6a 83 bc b4 4d 77 79 ba  |W$x.....j...Mwy.|
-00000340  6e e7 2e 8f ac 9e 98 34  36 9d a9 27 f0 16 03 01  |n......46..'....|
+000002c0  c4 cf c2 ed 90 99 5f 58  cb 3b 74 00 80 c6 ad e2  |......_X.;t.....|
+000002d0  21 0d d7 30 42 da 08 52  d5 46 70 a3 e5 d6 40 ab  |!..0B..R.Fp...@.|
+000002e0  bf 52 f8 da a5 41 86 1d  48 e6 51 91 52 8d 3c 5d  |.R...A..H.Q.R.<]|
+000002f0  ca 36 4c 62 d1 6b c8 48  8c 99 50 89 a9 27 4b 21  |.6Lb.k.H..P..'K!|
+00000300  c9 9d a6 43 34 d2 47 a7  b3 1a 6d 98 b3 7f 37 94  |...C4.G...m...7.|
+00000310  60 ba 88 f1 b7 ed 34 2b  47 f4 80 27 d3 a0 74 6a  |`.....4+G..'..tj|
+00000320  c6 d6 49 e3 8a e5 5d f1  a7 54 8a b4 84 8d a8 6b  |..I...]..T.....k|
+00000330  3b 7a 3f eb 81 77 4b bf  be 1e ac cd aa f9 4b 79  |;z?..wK.......Ky|
+00000340  24 78 6c 67 14 13 ab f8  ad 33 7c 94 38 16 03 01  |$xlg.....3|.8...|
 00000350  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
-00000000  16 03 01 00 25 10 00 00  21 20 00 ad c5 2b 21 7f  |....%...! ...+!.|
-00000010  8e 44 f2 f5 32 22 c8 c2  c6 de 2c 0b 7a a9 24 b6  |.D..2"....,.z.$.|
-00000020  03 20 c0 cc 79 2e 11 2f  d3 43 14 03 01 00 01 01  |. ..y../.C......|
-00000030  16 03 01 00 30 78 5c 32  72 a1 c8 3b 9c 7b 77 0b  |....0x\2r..;.{w.|
-00000040  a0 28 52 55 17 16 d5 39  89 d0 43 bf 67 29 85 6f  |.(RU...9..C.g).o|
-00000050  b5 1e 83 fa 22 96 78 e3  5c 45 5a 3d fe 2b d5 b7  |....".x.\EZ=.+..|
-00000060  3d 64 44 8c a8                                    |=dD..|
+00000000  16 03 01 00 25 10 00 00  21 20 f5 be 48 cb fb 0d  |....%...! ..H...|
+00000010  69 27 a8 ab 59 c4 9a ac  92 71 46 d1 17 7e 35 67  |i'..Y....qF..~5g|
+00000020  15 b1 ea 9f 53 48 a3 b5  f9 55 14 03 01 00 01 01  |....SH...U......|
+00000030  16 03 01 00 30 e1 79 95  7c ab 01 74 35 39 9b ce  |....0.y.|..t59..|
+00000040  79 5f 15 21 88 fc be fc  46 a9 31 ca 82 07 0c 1f  |y_.!....F.1.....|
+00000050  d8 2f 93 b5 5d 23 bf f9  10 40 bc b5 22 53 df d6  |./..]#...@.."S..|
+00000060  b1 10 b9 16 96                                    |.....|
 >>> Flow 4 (server to client)
 00000000  16 03 01 00 8b 04 00 00  87 00 00 00 00 00 81 50  |...............P|
 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  6d ec a4 83 51 ed 14 ef  68 ca 42 c5 4c 5f bb 3b  |m...Q...h.B.L_.;|
-00000040  9c c8 3c 7e 1c cf dc da  e4 35 83 03 13 95 82 5f  |..<~.....5....._|
-00000050  32 77 8a cf dc e9 10 65  9b 97 d4 5d ff 43 57 14  |2w.....e...].CW.|
-00000060  a3 25 e0 fa c8 26 0c ff  71 67 9b 32 2f 49 38 16  |.%...&..qg.2/I8.|
-00000070  aa ea b9 fa 99 86 4c b9  db 7a ef bc 87 43 e8 db  |......L..z...C..|
-00000080  26 27 73 76 80 77 59 c4  fb 7d 56 e9 7e 23 03 75  |&'sv.wY..}V.~#.u|
-00000090  14 03 01 00 01 01 16 03  01 00 30 80 8f 8e 11 b5  |..........0.....|
-000000a0  f4 a0 8c 4a ae 3f 25 17  66 93 1c c5 a5 10 57 e3  |...J.?%.f.....W.|
-000000b0  24 7a c1 a9 72 74 4f fd  20 5e 5b 58 4d bd 5d f0  |$z..rtO. ^[XM.].|
-000000c0  05 8e 06 61 0a 98 19 a0  a8 73 02 17 03 01 00 20  |...a.....s..... |
-000000d0  d9 dd 86 e6 55 55 df 2c  0d 1e 5f 0e 9e 1e 76 51  |....UU.,.._...vQ|
-000000e0  98 e0 2b 09 f9 44 4d 4d  22 97 0d 1e 95 7b b9 41  |..+..DMM"....{.A|
-000000f0  17 03 01 00 30 74 82 1c  35 9b 87 cd 5e 29 95 e1  |....0t..5...^)..|
-00000100  18 e3 76 32 94 b5 1b d0  06 d2 ec 49 40 24 73 d3  |..v2.......I@$s.|
-00000110  fc 5d 1a 26 59 5b 33 d8  5a 30 d5 92 30 bc 80 e0  |.].&Y[3.Z0..0...|
-00000120  ed 85 e8 14 01 15 03 01  00 20 ec 69 2f 9d 29 4f  |......... .i/.)O|
-00000130  1f 8e e6 34 f0 87 66 40  e8 13 14 02 74 c4 1d aa  |...4..f@....t...|
-00000140  65 72 43 50 6e 71 9c 2e  b6 3a                    |erCPnq...:|
+00000030  6d ec a4 83 51 ed 14 ef  68 ca 42 c5 4c d2 34 08  |m...Q...h.B.L.4.|
+00000040  0b cc b9 32 8f 21 f7 50  c4 e1 28 9b 7d 5e ed de  |...2.!.P..(.}^..|
+00000050  0a df 30 0d 16 34 6b 6d  22 3c d3 c8 b2 99 84 8e  |..0..4km"<......|
+00000060  09 6d 3c 62 d4 0f f6 37  dc 53 ae 72 40 49 38 16  |.m<b...7.S.r@I8.|
+00000070  9c 30 34 bf 6e 34 bb 54  73 33 c0 c9 8c 12 ae bc  |.04.n4.Ts3......|
+00000080  e9 a8 80 23 de d0 e5 d3  46 d8 6a 86 c7 a5 6c 61  |...#....F.j...la|
+00000090  14 03 01 00 01 01 16 03  01 00 30 27 a7 5d e7 93  |..........0'.]..|
+000000a0  54 9a 77 d5 43 aa e3 ec  21 00 fa d4 36 04 c3 82  |T.w.C...!...6...|
+000000b0  b0 b7 f5 b4 19 ce f9 58  0a b4 7f d6 bf 95 43 9d  |.......X......C.|
+000000c0  26 44 46 77 48 cd 77 82  e2 48 51 17 03 01 00 20  |&DFwH.w..HQ.... |
+000000d0  c0 9b b1 d3 9f e6 4f 55  59 17 5a dc e4 2f bc 04  |......OUY.Z../..|
+000000e0  6f eb 4d d9 22 6e 97 20  33 94 d4 91 aa 70 4d ab  |o.M."n. 3....pM.|
+000000f0  17 03 01 00 30 9b 0f 50  a8 95 f5 db 67 96 c2 3e  |....0..P....g..>|
+00000100  46 a7 41 99 d5 e2 ab 60  b1 eb 8d 68 2f 71 30 70  |F.A....`...h/q0p|
+00000110  75 cc b8 50 1a 58 3b 96  d3 5c 99 43 27 4f b1 4a  |u..P.X;..\.C'O.J|
+00000120  c8 8d 5b ab 49 15 03 01  00 20 34 a6 41 25 fd 23  |..[.I.... 4.A%.#|
+00000130  44 6d 60 7f 79 5d 27 23  f7 cb 77 d0 cd 81 c4 67  |Dm`.y]'#..w....g|
+00000140  0e 56 92 60 ac a1 32 a5  0d 94                    |.V.`..2...|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback b/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback
new file mode 100644
index 0000000..4fadf39
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 a6 01 00 00  a2 03 03 b5 c9 ab 32 7f  |..............2.|
+00000010  e1 af 3f f2 ac 2a 11 dd  33 f9 b5 21 88 0d e4 29  |..?..*..3..!...)|
+00000020  e2 47 49 dc c7 31 a8 a5  25 81 0c 00 00 04 cc a8  |.GI..1..%.......|
+00000030  00 ff 01 00 00 75 00 0b  00 04 03 00 01 02 00 0a  |.....u..........|
+00000040  00 0c 00 0a 00 1d 00 17  00 1e 00 19 00 18 00 23  |...............#|
+00000050  00 00 00 10 00 19 00 17  06 70 72 6f 74 6f 33 08  |.........proto3.|
+00000060  68 74 74 70 2f 31 2e 31  06 70 72 6f 74 6f 34 00  |http/1.1.proto4.|
+00000070  16 00 00 00 17 00 00 00  0d 00 30 00 2e 04 03 05  |..........0.....|
+00000080  03 06 03 08 07 08 08 08  09 08 0a 08 0b 08 04 08  |................|
+00000090  05 08 06 04 01 05 01 06  01 03 03 02 03 03 01 02  |................|
+000000a0  01 03 02 02 02 04 02 05  02 06 02                 |...........|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 3b 02 00 00  37 03 03 00 00 00 00 00  |....;...7.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 44 4f 57 4e 47  52 44 01 00 cc a8 00 00  |...DOWNGRD......|
+00000030  0f 00 23 00 00 ff 01 00  01 00 00 0b 00 02 01 00  |..#.............|
+00000040  16 03 03 02 59 0b 00 02  55 00 02 52 00 02 4f 30  |....Y...U..R..O0|
+00000050  82 02 4b 30 82 01 b4 a0  03 02 01 02 02 09 00 e8  |..K0............|
+00000060  f0 9d 3f e2 5b ea a6 30  0d 06 09 2a 86 48 86 f7  |..?.[..0...*.H..|
+00000070  0d 01 01 0b 05 00 30 1f  31 0b 30 09 06 03 55 04  |......0.1.0...U.|
+00000080  0a 13 02 47 6f 31 10 30  0e 06 03 55 04 03 13 07  |...Go1.0...U....|
+00000090  47 6f 20 52 6f 6f 74 30  1e 17 0d 31 36 30 31 30  |Go Root0...16010|
+000000a0  31 30 30 30 30 30 30 5a  17 0d 32 35 30 31 30 31  |1000000Z..250101|
+000000b0  30 30 30 30 30 30 5a 30  1a 31 0b 30 09 06 03 55  |000000Z0.1.0...U|
+000000c0  04 0a 13 02 47 6f 31 0b  30 09 06 03 55 04 03 13  |....Go1.0...U...|
+000000d0  02 47 6f 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |.Go0..0...*.H...|
+000000e0  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
+000000f0  db 46 7d 93 2e 12 27 06  48 bc 06 28 21 ab 7e c4  |.F}...'.H..(!.~.|
+00000100  b6 a2 5d fe 1e 52 45 88  7a 36 47 a5 08 0d 92 42  |..]..RE.z6G....B|
+00000110  5b c2 81 c0 be 97 79 98  40 fb 4f 6d 14 fd 2b 13  |[.....y.@.Om..+.|
+00000120  8b c2 a5 2e 67 d8 d4 09  9e d6 22 38 b7 4a 0b 74  |....g....."8.J.t|
+00000130  73 2b c2 34 f1 d1 93 e5  96 d9 74 7b f3 58 9f 6c  |s+.4......t{.X.l|
+00000140  61 3c c0 b0 41 d4 d9 2b  2b 24 23 77 5b 1c 3b bd  |a<..A..++$#w[.;.|
+00000150  75 5d ce 20 54 cf a1 63  87 1d 1e 24 c4 f3 1d 1a  |u]. T..c...$....|
+00000160  50 8b aa b6 14 43 ed 97  a7 75 62 f4 14 c8 52 d7  |P....C...ub...R.|
+00000170  02 03 01 00 01 a3 81 93  30 81 90 30 0e 06 03 55  |........0..0...U|
+00000180  1d 0f 01 01 ff 04 04 03  02 05 a0 30 1d 06 03 55  |...........0...U|
+00000190  1d 25 04 16 30 14 06 08  2b 06 01 05 05 07 03 01  |.%..0...+.......|
+000001a0  06 08 2b 06 01 05 05 07  03 02 30 0c 06 03 55 1d  |..+.......0...U.|
+000001b0  13 01 01 ff 04 02 30 00  30 19 06 03 55 1d 0e 04  |......0.0...U...|
+000001c0  12 04 10 9f 91 16 1f 43  43 3e 49 a6 de 6d b6 80  |.......CC>I..m..|
+000001d0  d7 9f 60 30 1b 06 03 55  1d 23 04 14 30 12 80 10  |..`0...U.#..0...|
+000001e0  48 13 49 4d 13 7e 16 31  bb a3 01 d5 ac ab 6e 7b  |H.IM.~.1......n{|
+000001f0  30 19 06 03 55 1d 11 04  12 30 10 82 0e 65 78 61  |0...U....0...exa|
+00000200  6d 70 6c 65 2e 67 6f 6c  61 6e 67 30 0d 06 09 2a  |mple.golang0...*|
+00000210  86 48 86 f7 0d 01 01 0b  05 00 03 81 81 00 9d 30  |.H.............0|
+00000220  cc 40 2b 5b 50 a0 61 cb  ba e5 53 58 e1 ed 83 28  |.@+[P.a...SX...(|
+00000230  a9 58 1a a9 38 a4 95 a1  ac 31 5a 1a 84 66 3d 43  |.X..8....1Z..f=C|
+00000240  d3 2d d9 0b f2 97 df d3  20 64 38 92 24 3a 00 bc  |.-...... d8.$:..|
+00000250  cf 9c 7d b7 40 20 01 5f  aa d3 16 61 09 a2 76 fd  |..}.@ ._...a..v.|
+00000260  13 c3 cc e1 0c 5c ee b1  87 82 f1 6c 04 ed 73 bb  |.....\.....l..s.|
+00000270  b3 43 77 8d 0c 1c f1 0f  a1 d8 40 83 61 c9 4c 72  |.Cw.......@.a.Lr|
+00000280  2b 9d ae db 46 06 06 4d  f4 c1 b3 3e c0 d1 bd 42  |+...F..M...>...B|
+00000290  d4 db fe 3d 13 60 84 5c  21 d3 3b e9 fa e7 16 03  |...=.`.\!.;.....|
+000002a0  03 00 ac 0c 00 00 a8 03  00 1d 20 2f e5 7d a3 47  |.......... /.}.G|
+000002b0  cd 62 43 15 28 da ac 5f  bb 29 07 30 ff f6 84 af  |.bC.(.._.).0....|
+000002c0  c4 cf c2 ed 90 99 5f 58  cb 3b 74 08 04 00 80 5f  |......_X.;t...._|
+000002d0  37 27 84 58 1e ea 1e 40  1b de a9 8f 04 d4 94 64  |7'.X...@.......d|
+000002e0  4e 27 c7 f1 b3 30 d0 53  f5 3d 57 50 d2 17 97 c8  |N'...0.S.=WP....|
+000002f0  3d 61 af a6 21 ab 1c 34  47 70 f8 b1 3b 9c 06 86  |=a..!..4Gp..;...|
+00000300  87 00 e2 13 50 83 91 ad  bc 84 bd b4 7b f3 4b ed  |....P.......{.K.|
+00000310  ca 81 0c 94 37 a8 ec 67  ca 9c f3 00 f6 af c2 92  |....7..g........|
+00000320  c4 8c 78 07 18 0e 43 24  1b 98 16 50 5c 2b 75 0e  |..x...C$...P\+u.|
+00000330  40 66 dc 40 cd 10 1a 51  25 f3 96 25 1a 3e 70 af  |@f.@...Q%..%.>p.|
+00000340  16 24 d0 1c 0e 33 f9 c1  74 cf b7 e2 28 ac 60 16  |.$...3..t...(.`.|
+00000350  03 03 00 04 0e 00 00 00                           |........|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 25 10 00 00  21 20 30 f2 bb f7 a7 ac  |....%...! 0.....|
+00000010  23 20 22 ee 73 0d 49 9c  b3 7b c1 9a db 2c 85 f3  |# ".s.I..{...,..|
+00000020  c0 82 31 60 bd 8b 14 4e  73 43 14 03 03 00 01 01  |..1`...NsC......|
+00000030  16 03 03 00 20 09 8d c7  86 ee cc f4 c7 36 a3 49  |.... ........6.I|
+00000040  d3 f7 a1 4a 68 a2 1e b4  fc cc a2 15 cb 01 92 d8  |...Jh...........|
+00000050  72 b0 d1 6f eb                                    |r..o.|
+>>> Flow 4 (server to client)
+00000000  16 03 03 00 8b 04 00 00  87 00 00 00 00 00 81 50  |...............P|
+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 e0 18 83 51 ed 14 ef  68 ca 42 c5 4c a2 ac 05  |o...Q...h.B.L...|
+00000040  9c 69 69 99 08 9f de a4  d4 e7 37 ab 14 38 4c 47  |.ii.......7..8LG|
+00000050  70 f0 97 1d db 2d 0a 14  c2 1e f0 16 9f 6d 37 02  |p....-.......m7.|
+00000060  4b f1 16 be 98 3f df 74  83 7c 19 85 61 49 38 16  |K....?.t.|..aI8.|
+00000070  ee 35 7a e2 3f 74 fe 8d  e3 07 93 a1 5e fa f2 02  |.5z.?t......^...|
+00000080  e5 c8 60 3f 11 83 8b 0e  32 52 f1 aa 52 b7 0a 89  |..`?....2R..R...|
+00000090  14 03 03 00 01 01 16 03  03 00 20 9e 65 15 cf 45  |.......... .e..E|
+000000a0  a5 03 69 c9 b1 d8 9e 92  a3 a2 b0 df 2e 62 b1 3a  |..i..........b.:|
+000000b0  17 78 cd e5 1d f3 51 42  7e 4e 25 17 03 03 00 1d  |.x....QB~N%.....|
+000000c0  d9 ae d0 fa b7 90 a9 2f  28 8d 1d 6f 54 1f c0 1e  |......./(..oT...|
+000000d0  4d ae b6 91 f0 e8 84 cf  86 11 22 25 ea 15 03 03  |M........."%....|
+000000e0  00 12 0e 71 f2 11 9e 9f  58 ad c0 d8 fc fa 34 bc  |...q....X.....4.|
+000000f0  02 5a 60 00                                       |.Z`.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch b/src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
index fdfb175..2d8a2eb 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 9d 01 00 00  99 03 03 7f fc 15 86 d1  |................|
-00000010  83 09 78 47 8d cd 7b 88  b3 86 52 27 bc da bc 8d  |..xG..{...R'....|
-00000020  0e 5d 35 44 21 17 7b d9  67 b9 fb 00 00 04 cc a8  |.]5D!.{.g.......|
+00000000  16 03 01 00 9d 01 00 00  99 03 03 24 15 a8 f2 f5  |...........$....|
+00000010  53 02 78 f0 4c f7 82 3c  68 7d a0 b1 9a 0f 29 32  |S.x.L..<h}....)2|
+00000020  9c 38 cc e7 92 95 63 f2  30 53 46 00 00 04 cc a8  |.8....c.0SF.....|
 00000030  00 ff 01 00 00 6c 00 0b  00 04 03 00 01 02 00 0a  |.....l..........|
 00000040  00 0c 00 0a 00 1d 00 17  00 1e 00 19 00 18 00 23  |...............#|
 00000050  00 00 00 10 00 10 00 0e  06 70 72 6f 74 6f 32 06  |.........proto2.|
@@ -11,81 +11,4 @@
 00000090  03 03 02 03 03 01 02 01  03 02 02 02 04 02 05 02  |................|
 000000a0  06 02                                             |..|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 3b 02 00 00  37 03 03 00 00 00 00 00  |....;...7.......|
-00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 44 4f 57 4e 47  52 44 01 00 cc a8 00 00  |...DOWNGRD......|
-00000030  0f 00 23 00 00 ff 01 00  01 00 00 0b 00 02 01 00  |..#.............|
-00000040  16 03 03 02 59 0b 00 02  55 00 02 52 00 02 4f 30  |....Y...U..R..O0|
-00000050  82 02 4b 30 82 01 b4 a0  03 02 01 02 02 09 00 e8  |..K0............|
-00000060  f0 9d 3f e2 5b ea a6 30  0d 06 09 2a 86 48 86 f7  |..?.[..0...*.H..|
-00000070  0d 01 01 0b 05 00 30 1f  31 0b 30 09 06 03 55 04  |......0.1.0...U.|
-00000080  0a 13 02 47 6f 31 10 30  0e 06 03 55 04 03 13 07  |...Go1.0...U....|
-00000090  47 6f 20 52 6f 6f 74 30  1e 17 0d 31 36 30 31 30  |Go Root0...16010|
-000000a0  31 30 30 30 30 30 30 5a  17 0d 32 35 30 31 30 31  |1000000Z..250101|
-000000b0  30 30 30 30 30 30 5a 30  1a 31 0b 30 09 06 03 55  |000000Z0.1.0...U|
-000000c0  04 0a 13 02 47 6f 31 0b  30 09 06 03 55 04 03 13  |....Go1.0...U...|
-000000d0  02 47 6f 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |.Go0..0...*.H...|
-000000e0  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-000000f0  db 46 7d 93 2e 12 27 06  48 bc 06 28 21 ab 7e c4  |.F}...'.H..(!.~.|
-00000100  b6 a2 5d fe 1e 52 45 88  7a 36 47 a5 08 0d 92 42  |..]..RE.z6G....B|
-00000110  5b c2 81 c0 be 97 79 98  40 fb 4f 6d 14 fd 2b 13  |[.....y.@.Om..+.|
-00000120  8b c2 a5 2e 67 d8 d4 09  9e d6 22 38 b7 4a 0b 74  |....g....."8.J.t|
-00000130  73 2b c2 34 f1 d1 93 e5  96 d9 74 7b f3 58 9f 6c  |s+.4......t{.X.l|
-00000140  61 3c c0 b0 41 d4 d9 2b  2b 24 23 77 5b 1c 3b bd  |a<..A..++$#w[.;.|
-00000150  75 5d ce 20 54 cf a1 63  87 1d 1e 24 c4 f3 1d 1a  |u]. T..c...$....|
-00000160  50 8b aa b6 14 43 ed 97  a7 75 62 f4 14 c8 52 d7  |P....C...ub...R.|
-00000170  02 03 01 00 01 a3 81 93  30 81 90 30 0e 06 03 55  |........0..0...U|
-00000180  1d 0f 01 01 ff 04 04 03  02 05 a0 30 1d 06 03 55  |...........0...U|
-00000190  1d 25 04 16 30 14 06 08  2b 06 01 05 05 07 03 01  |.%..0...+.......|
-000001a0  06 08 2b 06 01 05 05 07  03 02 30 0c 06 03 55 1d  |..+.......0...U.|
-000001b0  13 01 01 ff 04 02 30 00  30 19 06 03 55 1d 0e 04  |......0.0...U...|
-000001c0  12 04 10 9f 91 16 1f 43  43 3e 49 a6 de 6d b6 80  |.......CC>I..m..|
-000001d0  d7 9f 60 30 1b 06 03 55  1d 23 04 14 30 12 80 10  |..`0...U.#..0...|
-000001e0  48 13 49 4d 13 7e 16 31  bb a3 01 d5 ac ab 6e 7b  |H.IM.~.1......n{|
-000001f0  30 19 06 03 55 1d 11 04  12 30 10 82 0e 65 78 61  |0...U....0...exa|
-00000200  6d 70 6c 65 2e 67 6f 6c  61 6e 67 30 0d 06 09 2a  |mple.golang0...*|
-00000210  86 48 86 f7 0d 01 01 0b  05 00 03 81 81 00 9d 30  |.H.............0|
-00000220  cc 40 2b 5b 50 a0 61 cb  ba e5 53 58 e1 ed 83 28  |.@+[P.a...SX...(|
-00000230  a9 58 1a a9 38 a4 95 a1  ac 31 5a 1a 84 66 3d 43  |.X..8....1Z..f=C|
-00000240  d3 2d d9 0b f2 97 df d3  20 64 38 92 24 3a 00 bc  |.-...... d8.$:..|
-00000250  cf 9c 7d b7 40 20 01 5f  aa d3 16 61 09 a2 76 fd  |..}.@ ._...a..v.|
-00000260  13 c3 cc e1 0c 5c ee b1  87 82 f1 6c 04 ed 73 bb  |.....\.....l..s.|
-00000270  b3 43 77 8d 0c 1c f1 0f  a1 d8 40 83 61 c9 4c 72  |.Cw.......@.a.Lr|
-00000280  2b 9d ae db 46 06 06 4d  f4 c1 b3 3e c0 d1 bd 42  |+...F..M...>...B|
-00000290  d4 db fe 3d 13 60 84 5c  21 d3 3b e9 fa e7 16 03  |...=.`.\!.;.....|
-000002a0  03 00 ac 0c 00 00 a8 03  00 1d 20 2f e5 7d a3 47  |.......... /.}.G|
-000002b0  cd 62 43 15 28 da ac 5f  bb 29 07 30 ff f6 84 af  |.bC.(.._.).0....|
-000002c0  c4 cf c2 ed 90 99 5f 58  cb 3b 74 08 04 00 80 b8  |......_X.;t.....|
-000002d0  a8 88 ac 85 ea 59 ac f1  41 e8 2d a2 76 3c 3b 4f  |.....Y..A.-.v<;O|
-000002e0  58 90 b7 03 74 4b 7a a7  5a 65 ea 08 9c cf e9 4d  |X...tKz.Ze.....M|
-000002f0  b4 8a ef f3 e1 d8 0a 83  0f 50 29 0b 59 77 90 e9  |.........P).Yw..|
-00000300  f3 e8 ca 6c b5 da e5 2b  95 47 e7 ed ff d6 3b 30  |...l...+.G....;0|
-00000310  45 61 2c af 5c 8c 4c df  bd c4 dc 28 dd d2 31 fa  |Ea,.\.L....(..1.|
-00000320  be 65 2b a4 cd 7c 41 29  4c 99 07 97 5c 2a 3c a7  |.e+..|A)L...\*<.|
-00000330  4d 9c ed 72 eb a1 a4 9e  db eb a0 cf c7 c2 b1 3b  |M..r...........;|
-00000340  5a d9 f8 f8 8e d5 07 81  f6 65 aa 0d 4f 4d 11 16  |Z........e..OM..|
-00000350  03 03 00 04 0e 00 00 00                           |........|
->>> Flow 3 (client to server)
-00000000  16 03 03 00 25 10 00 00  21 20 5f d2 13 b1 79 f6  |....%...! _...y.|
-00000010  f3 2a 21 f5 89 a3 22 29  73 30 14 60 1d 1e 77 8a  |.*!...")s0.`..w.|
-00000020  f4 1a 92 3f b0 04 06 98  1a 1e 14 03 03 00 01 01  |...?............|
-00000030  16 03 03 00 20 63 10 89  c0 c0 56 37 40 8c e8 5e  |.... c....V7@..^|
-00000040  7f f0 f0 e3 a0 8e d5 20  33 5f dd c3 16 e8 eb 6c  |....... 3_.....l|
-00000050  c3 a8 75 6d dc                                    |..um.|
->>> Flow 4 (server to client)
-00000000  16 03 03 00 8b 04 00 00  87 00 00 00 00 00 81 50  |...............P|
-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 e0 18 83 51 ed 14 ef  68 ca 42 c5 4c e3 f1 12  |o...Q...h.B.L...|
-00000040  a1 17 a6 ee 99 af e8 06  65 d0 6d c1 4f ce 92 7c  |........e.m.O..||
-00000050  40 df 41 c1 90 e3 e0 d8  a1 95 da 38 25 26 ea b5  |@.A........8%&..|
-00000060  ca a9 42 5f 8c 55 d4 d2  73 a6 a2 b6 22 49 38 16  |..B_.U..s..."I8.|
-00000070  ec 70 52 f9 c0 12 18 9e  9b 4d e3 6d 49 b7 3b c0  |.pR......M.mI.;.|
-00000080  e9 53 9d 06 96 fc a9 06  8c 2a 7a c5 7d 48 47 ef  |.S.......*z.}HG.|
-00000090  14 03 03 00 01 01 16 03  03 00 20 19 27 38 37 bf  |.......... .'87.|
-000000a0  07 4e 2f 77 b9 73 4b dd  c8 f8 4c c5 f1 35 86 2b  |.N/w.sK...L..5.+|
-000000b0  97 7e 0f 89 4b bf db 81  76 8a 41 17 03 03 00 1d  |.~..K...v.A.....|
-000000c0  6d b8 c3 eb b1 5a f3 06  97 04 61 fc 82 74 5d a0  |m....Z....a..t].|
-000000d0  73 57 75 6e 66 53 3e 12  5e 0d 60 31 52 15 03 03  |sWunfS>.^.`1R...|
-000000e0  00 12 e4 93 fb 7b cb ee  d6 70 ac af 5f 8b 82 9b  |.....{...p.._...|
-000000f0  e5 0b 68 9c                                       |..h.|
+00000000  15 03 03 00 02 02 78                              |......x|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN-NotConfigured b/src/crypto/tls/testdata/Server-TLSv12-ALPN-NotConfigured
new file mode 100644
index 0000000..e1c991b
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN-NotConfigured
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 9d 01 00 00  99 03 03 92 d8 d4 4f 2e  |..............O.|
+00000010  82 ad e9 4f a2 c3 f7 23  da 2e dc 23 c0 87 fc 33  |...O...#...#...3|
+00000020  14 63 f1 da 98 a8 af 70  3a 7e f3 00 00 04 cc a8  |.c.....p:~......|
+00000030  00 ff 01 00 00 6c 00 0b  00 04 03 00 01 02 00 0a  |.....l..........|
+00000040  00 0c 00 0a 00 1d 00 17  00 1e 00 19 00 18 00 23  |...............#|
+00000050  00 00 00 10 00 10 00 0e  06 70 72 6f 74 6f 32 06  |.........proto2.|
+00000060  70 72 6f 74 6f 31 00 16  00 00 00 17 00 00 00 0d  |proto1..........|
+00000070  00 30 00 2e 04 03 05 03  06 03 08 07 08 08 08 09  |.0..............|
+00000080  08 0a 08 0b 08 04 08 05  08 06 04 01 05 01 06 01  |................|
+00000090  03 03 02 03 03 01 02 01  03 02 02 02 04 02 05 02  |................|
+000000a0  06 02                                             |..|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 3b 02 00 00  37 03 03 00 00 00 00 00  |....;...7.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 44 4f 57 4e 47  52 44 01 00 cc a8 00 00  |...DOWNGRD......|
+00000030  0f 00 23 00 00 ff 01 00  01 00 00 0b 00 02 01 00  |..#.............|
+00000040  16 03 03 02 59 0b 00 02  55 00 02 52 00 02 4f 30  |....Y...U..R..O0|
+00000050  82 02 4b 30 82 01 b4 a0  03 02 01 02 02 09 00 e8  |..K0............|
+00000060  f0 9d 3f e2 5b ea a6 30  0d 06 09 2a 86 48 86 f7  |..?.[..0...*.H..|
+00000070  0d 01 01 0b 05 00 30 1f  31 0b 30 09 06 03 55 04  |......0.1.0...U.|
+00000080  0a 13 02 47 6f 31 10 30  0e 06 03 55 04 03 13 07  |...Go1.0...U....|
+00000090  47 6f 20 52 6f 6f 74 30  1e 17 0d 31 36 30 31 30  |Go Root0...16010|
+000000a0  31 30 30 30 30 30 30 5a  17 0d 32 35 30 31 30 31  |1000000Z..250101|
+000000b0  30 30 30 30 30 30 5a 30  1a 31 0b 30 09 06 03 55  |000000Z0.1.0...U|
+000000c0  04 0a 13 02 47 6f 31 0b  30 09 06 03 55 04 03 13  |....Go1.0...U...|
+000000d0  02 47 6f 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |.Go0..0...*.H...|
+000000e0  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
+000000f0  db 46 7d 93 2e 12 27 06  48 bc 06 28 21 ab 7e c4  |.F}...'.H..(!.~.|
+00000100  b6 a2 5d fe 1e 52 45 88  7a 36 47 a5 08 0d 92 42  |..]..RE.z6G....B|
+00000110  5b c2 81 c0 be 97 79 98  40 fb 4f 6d 14 fd 2b 13  |[.....y.@.Om..+.|
+00000120  8b c2 a5 2e 67 d8 d4 09  9e d6 22 38 b7 4a 0b 74  |....g....."8.J.t|
+00000130  73 2b c2 34 f1 d1 93 e5  96 d9 74 7b f3 58 9f 6c  |s+.4......t{.X.l|
+00000140  61 3c c0 b0 41 d4 d9 2b  2b 24 23 77 5b 1c 3b bd  |a<..A..++$#w[.;.|
+00000150  75 5d ce 20 54 cf a1 63  87 1d 1e 24 c4 f3 1d 1a  |u]. T..c...$....|
+00000160  50 8b aa b6 14 43 ed 97  a7 75 62 f4 14 c8 52 d7  |P....C...ub...R.|
+00000170  02 03 01 00 01 a3 81 93  30 81 90 30 0e 06 03 55  |........0..0...U|
+00000180  1d 0f 01 01 ff 04 04 03  02 05 a0 30 1d 06 03 55  |...........0...U|
+00000190  1d 25 04 16 30 14 06 08  2b 06 01 05 05 07 03 01  |.%..0...+.......|
+000001a0  06 08 2b 06 01 05 05 07  03 02 30 0c 06 03 55 1d  |..+.......0...U.|
+000001b0  13 01 01 ff 04 02 30 00  30 19 06 03 55 1d 0e 04  |......0.0...U...|
+000001c0  12 04 10 9f 91 16 1f 43  43 3e 49 a6 de 6d b6 80  |.......CC>I..m..|
+000001d0  d7 9f 60 30 1b 06 03 55  1d 23 04 14 30 12 80 10  |..`0...U.#..0...|
+000001e0  48 13 49 4d 13 7e 16 31  bb a3 01 d5 ac ab 6e 7b  |H.IM.~.1......n{|
+000001f0  30 19 06 03 55 1d 11 04  12 30 10 82 0e 65 78 61  |0...U....0...exa|
+00000200  6d 70 6c 65 2e 67 6f 6c  61 6e 67 30 0d 06 09 2a  |mple.golang0...*|
+00000210  86 48 86 f7 0d 01 01 0b  05 00 03 81 81 00 9d 30  |.H.............0|
+00000220  cc 40 2b 5b 50 a0 61 cb  ba e5 53 58 e1 ed 83 28  |.@+[P.a...SX...(|
+00000230  a9 58 1a a9 38 a4 95 a1  ac 31 5a 1a 84 66 3d 43  |.X..8....1Z..f=C|
+00000240  d3 2d d9 0b f2 97 df d3  20 64 38 92 24 3a 00 bc  |.-...... d8.$:..|
+00000250  cf 9c 7d b7 40 20 01 5f  aa d3 16 61 09 a2 76 fd  |..}.@ ._...a..v.|
+00000260  13 c3 cc e1 0c 5c ee b1  87 82 f1 6c 04 ed 73 bb  |.....\.....l..s.|
+00000270  b3 43 77 8d 0c 1c f1 0f  a1 d8 40 83 61 c9 4c 72  |.Cw.......@.a.Lr|
+00000280  2b 9d ae db 46 06 06 4d  f4 c1 b3 3e c0 d1 bd 42  |+...F..M...>...B|
+00000290  d4 db fe 3d 13 60 84 5c  21 d3 3b e9 fa e7 16 03  |...=.`.\!.;.....|
+000002a0  03 00 ac 0c 00 00 a8 03  00 1d 20 2f e5 7d a3 47  |.......... /.}.G|
+000002b0  cd 62 43 15 28 da ac 5f  bb 29 07 30 ff f6 84 af  |.bC.(.._.).0....|
+000002c0  c4 cf c2 ed 90 99 5f 58  cb 3b 74 08 04 00 80 8c  |......_X.;t.....|
+000002d0  cb 8c f6 6c dd 02 5f c9  13 7e c2 26 26 41 7a 1a  |...l.._..~.&&Az.|
+000002e0  25 c7 3e 22 11 30 32 c0  67 a5 53 32 1e 32 21 cb  |%.>".02.g.S2.2!.|
+000002f0  ff 0a b7 e1 7a 98 26 e9  bf 05 30 f6 13 38 ee 1d  |....z.&...0..8..|
+00000300  90 56 a6 0d e0 65 a8 02  0e 08 3e c0 31 ff dd fa  |.V...e....>.1...|
+00000310  05 3a 22 7c f8 ce 65 43  0c b6 c4 9a e4 ed 22 eb  |.:"|..eC......".|
+00000320  c4 46 b2 3d 1d 9c c1 e7  d4 6a 79 4f cf 8f 1c 45  |.F.=.....jyO...E|
+00000330  52 51 b3 d1 a4 0d 0d df  4e 19 15 e6 af 2e 5a d5  |RQ......N.....Z.|
+00000340  8a 2e 3c 48 8a f7 86 e5  53 0e 35 9a 8a c6 dd 16  |..<H....S.5.....|
+00000350  03 03 00 04 0e 00 00 00                           |........|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 25 10 00 00  21 20 b7 d6 2f 99 8f c7  |....%...! ../...|
+00000010  bc 48 b8 4f 01 f8 2c ff  75 e5 fe 10 c6 2d 2d d5  |.H.O..,.u....--.|
+00000020  43 2b c3 14 cb d0 b2 7a  e9 71 14 03 03 00 01 01  |C+.....z.q......|
+00000030  16 03 03 00 20 c9 88 f1  a0 1a 9b 8a 14 00 33 f0  |.... .........3.|
+00000040  e8 01 f3 c2 66 06 98 44  4d 35 89 8f 1b 65 d0 cf  |....f..DM5...e..|
+00000050  eb 7d 9f b1 df                                    |.}...|
+>>> Flow 4 (server to client)
+00000000  16 03 03 00 8b 04 00 00  87 00 00 00 00 00 81 50  |...............P|
+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 e0 18 83 51 ed 14 ef  68 ca 42 c5 4c 76 fb ec  |o...Q...h.B.Lv..|
+00000040  0d 89 48 e7 19 98 64 df  59 8f df 50 ce 28 e8 3c  |..H...d.Y..P.(.<|
+00000050  b6 f8 5a ae bc 6b 2e a2  d6 23 05 f6 7f 36 ea 55  |..Z..k...#...6.U|
+00000060  13 54 9e 9c 31 df d0 56  00 1f a7 6a b2 49 38 16  |.T..1..V...j.I8.|
+00000070  7f d0 78 12 95 86 11 ca  98 63 07 4a 81 a5 d3 bd  |..x......c.J....|
+00000080  dc 9e 54 9c 25 f2 55 d5  fd cf 36 94 99 e0 c5 82  |..T.%.U...6.....|
+00000090  14 03 03 00 01 01 16 03  03 00 20 e6 d9 c2 bb ca  |.......... .....|
+000000a0  02 d3 79 a4 fb b0 00 7d  e2 47 46 d3 e7 b4 fe be  |..y....}.GF.....|
+000000b0  b3 8f c4 98 b7 f7 25 bc  cc 3f a8 17 03 03 00 1d  |......%..?......|
+000000c0  ad f3 27 a0 c4 a4 5b 7b  40 11 a4 35 e6 10 03 63  |..'...[{@..5...c|
+000000d0  13 d3 1c ce 75 8f 09 8b  85 6c 93 b1 9f 15 03 03  |....u....l......|
+000000e0  00 12 79 0c dd 21 72 68  b8 30 45 5d 45 39 a9 c4  |..y..!rh.0E]E9..|
+000000f0  a6 d7 12 99                                       |....|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA b/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA
deleted file mode 100644
index 63e0edb..0000000
--- a/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA
+++ /dev/null
@@ -1,88 +0,0 @@
->>> Flow 1 (client to server)
-00000000  16 03 01 00 cb 01 00 00  c7 03 03 3f 5d 09 25 4e  |...........?].%N|
-00000010  82 83 13 89 ba 89 43 d5  43 4f f1 c3 2f 08 77 39  |......C.CO../.w9|
-00000020  bf eb c7 1d 4b d6 85 c8  17 2f 83 00 00 38 c0 2c  |....K..../...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.....=.<|
-00000060  00 35 00 2f 00 ff 01 00  00 66 00 00 00 0e 00 0c  |.5./.....f......|
-00000070  00 00 09 31 32 37 2e 30  2e 30 2e 31 00 0b 00 04  |...127.0.0.1....|
-00000080  03 00 01 02 00 0a 00 0c  00 0a 00 1d 00 17 00 1e  |................|
-00000090  00 19 00 18 00 16 00 00  00 17 00 00 00 0d 00 30  |...............0|
-000000a0  00 2e 04 03 05 03 06 03  08 07 08 08 08 09 08 0a  |................|
-000000b0  08 0b 08 04 08 05 08 06  04 01 05 01 06 01 03 03  |................|
-000000c0  02 03 03 01 02 01 03 02  02 02 04 02 05 02 06 02  |................|
->>> Flow 2 (server to client)
-00000000  16 03 03 00 37 02 00 00  33 03 03 00 00 00 00 00  |....7...3.......|
-00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 44 4f 57 4e 47  52 44 01 00 c0 0a 00 00  |...DOWNGRD......|
-00000030  0b ff 01 00 01 00 00 0b  00 02 01 00 16 03 03 02  |................|
-00000040  0e 0b 00 02 0a 00 02 07  00 02 04 30 82 02 00 30  |...........0...0|
-00000050  82 01 62 02 09 00 b8 bf  2d 47 a0 d2 eb f4 30 09  |..b.....-G....0.|
-00000060  06 07 2a 86 48 ce 3d 04  01 30 45 31 0b 30 09 06  |..*.H.=..0E1.0..|
-00000070  03 55 04 06 13 02 41 55  31 13 30 11 06 03 55 04  |.U....AU1.0...U.|
-00000080  08 13 0a 53 6f 6d 65 2d  53 74 61 74 65 31 21 30  |...Some-State1!0|
-00000090  1f 06 03 55 04 0a 13 18  49 6e 74 65 72 6e 65 74  |...U....Internet|
-000000a0  20 57 69 64 67 69 74 73  20 50 74 79 20 4c 74 64  | Widgits Pty Ltd|
-000000b0  30 1e 17 0d 31 32 31 31  32 32 31 35 30 36 33 32  |0...121122150632|
-000000c0  5a 17 0d 32 32 31 31 32  30 31 35 30 36 33 32 5a  |Z..221120150632Z|
-000000d0  30 45 31 0b 30 09 06 03  55 04 06 13 02 41 55 31  |0E1.0...U....AU1|
-000000e0  13 30 11 06 03 55 04 08  13 0a 53 6f 6d 65 2d 53  |.0...U....Some-S|
-000000f0  74 61 74 65 31 21 30 1f  06 03 55 04 0a 13 18 49  |tate1!0...U....I|
-00000100  6e 74 65 72 6e 65 74 20  57 69 64 67 69 74 73 20  |nternet Widgits |
-00000110  50 74 79 20 4c 74 64 30  81 9b 30 10 06 07 2a 86  |Pty Ltd0..0...*.|
-00000120  48 ce 3d 02 01 06 05 2b  81 04 00 23 03 81 86 00  |H.=....+...#....|
-00000130  04 00 c4 a1 ed be 98 f9  0b 48 73 36 7e c3 16 56  |.........Hs6~..V|
-00000140  11 22 f2 3d 53 c3 3b 4d  21 3d cd 6b 75 e6 f6 b0  |.".=S.;M!=.ku...|
-00000150  dc 9a df 26 c1 bc b2 87  f0 72 32 7c b3 64 2f 1c  |...&.....r2|.d/.|
-00000160  90 bc ea 68 23 10 7e fe  e3 25 c0 48 3a 69 e0 28  |...h#.~..%.H:i.(|
-00000170  6d d3 37 00 ef 04 62 dd  0d a0 9c 70 62 83 d8 81  |m.7...b....pb...|
-00000180  d3 64 31 aa 9e 97 31 bd  96 b0 68 c0 9b 23 de 76  |.d1...1...h..#.v|
-00000190  64 3f 1a 5c 7f e9 12 0e  58 58 b6 5f 70 dd 9b d8  |d?.\....XX._p...|
-000001a0  ea d5 d7 f5 d5 cc b9 b6  9f 30 66 5b 66 9a 20 e2  |.........0f[f. .|
-000001b0  27 e5 bf fe 3b 30 09 06  07 2a 86 48 ce 3d 04 01  |'...;0...*.H.=..|
-000001c0  03 81 8c 00 30 81 88 02  42 01 88 a2 4f eb e2 45  |....0...B...O..E|
-000001d0  c5 48 7d 1b ac f5 ed 98  9d ae 47 70 c0 5e 1b b6  |.H}.......Gp.^..|
-000001e0  2f bd f1 b6 4d b7 61 40  d3 11 a2 ce ee 0b 7e 92  |/...M.a@......~.|
-000001f0  7e ff 76 9d c3 3b 7e a5  3f ce fa 10 e2 59 ec 47  |~.v..;~.?....Y.G|
-00000200  2d 7c ac da 4e 97 0e 15  a0 6f d0 02 42 01 4d fc  |-|..N....o..B.M.|
-00000210  be 67 13 9c 2d 05 0e bd  3f a3 8c 25 c1 33 13 83  |.g..-...?..%.3..|
-00000220  0d 94 06 bb d4 37 7a f6  ec 7a c9 86 2e dd d7 11  |.....7z..z......|
-00000230  69 7f 85 7c 56 de fb 31  78 2b e4 c7 78 0d ae cb  |i..|V..1x+..x...|
-00000240  be 9e 4e 36 24 31 7b 6a  0f 39 95 12 07 8f 2a 16  |..N6$1{j.9....*.|
-00000250  03 03 00 b7 0c 00 00 b3  03 00 1d 20 2f e5 7d a3  |........... /.}.|
-00000260  47 cd 62 43 15 28 da ac  5f bb 29 07 30 ff f6 84  |G.bC.(.._.).0...|
-00000270  af c4 cf c2 ed 90 99 5f  58 cb 3b 74 04 03 00 8b  |......._X.;t....|
-00000280  30 81 88 02 42 01 5c 2a  30 4f 9f dc df a8 33 06  |0...B.\*0O....3.|
-00000290  3b bc 35 46 6a 9c a3 a1  26 ec 42 29 bf 63 b3 9b  |;.5Fj...&.B).c..|
-000002a0  8c bf 7b 07 8d 28 eb 41  68 7a 8a 1b f3 de a9 dc  |..{..(.Ahz......|
-000002b0  1e d1 21 3c 4d 24 df 89  90 b6 f2 fb ad 60 d2 27  |..!<M$.......`.'|
-000002c0  96 6d a2 b6 9b 48 e6 02  42 00 f1 c8 c2 f4 ee 4a  |.m...H..B......J|
-000002d0  8f 08 c5 09 05 e9 bf 7f  aa b6 3e 56 e9 98 46 b4  |..........>V..F.|
-000002e0  b4 e5 90 72 ed af 71 0d  fb e6 39 2f d5 4b 73 ba  |...r..q...9/.Ks.|
-000002f0  85 d2 a4 bf 99 74 d7 81  eb 3e 69 4d f0 12 1e 3c  |.....t...>iM...<|
-00000300  53 ca f0 35 85 ef ff ed  cc 0f f7 16 03 03 00 04  |S..5............|
-00000310  0e 00 00 00                                       |....|
->>> Flow 3 (client to server)
-00000000  16 03 03 00 25 10 00 00  21 20 b8 a6 ed 33 20 59  |....%...! ...3 Y|
-00000010  76 0b 7c 87 53 f1 12 c1  46 d9 db 68 c0 6f d6 30  |v.|.S...F..h.o.0|
-00000020  ea e0 64 04 54 7a 4c 95  03 41 14 03 03 00 01 01  |..d.TzL..A......|
-00000030  16 03 03 00 40 c0 70 29  39 a0 8a bd 59 58 88 44  |....@.p)9...YX.D|
-00000040  ea 10 b4 79 3e 0e 72 b7  2a 03 6d 4d 5a 24 f5 c0  |...y>.r.*.mMZ$..|
-00000050  4e e5 19 f0 fb 66 ca 97  89 4b 67 dc bb 19 cd 0b  |N....f...Kg.....|
-00000060  6e 74 01 d3 a4 9a ab af  8e 44 10 99 ac ff 9e 9e  |nt.......D......|
-00000070  17 04 56 78 55                                    |..VxU|
->>> 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 01 a0 6b 2c c5  |.............k,.|
-00000020  7e 83 70 b5 2c 8c 43 b6  8b 2e 18 2a 1d be 11 6d  |~.p.,.C....*...m|
-00000030  13 f9 ba b5 de db 01 2a  64 d9 5b 24 c9 61 a1 4d  |.......*d.[$.a.M|
-00000040  11 bb fc b1 86 61 b0 04  a9 cd 1e 17 03 03 00 40  |.....a.........@|
-00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  d8 98 85 b4 cb 61 39 69  2f b1 1f 24 c1 5a 4f e3  |.....a9i/..$.ZO.|
-00000070  0b 20 5d 6c 3f 3f 82 3a  a3 8a b3 cf e9 41 bb 60  |. ]l??.:.....A.`|
-00000080  ed b6 67 a0 76 39 ab 93  a5 35 d0 42 b3 a7 4c 92  |..g.v9...5.B..L.|
-00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 c7 0d 06  b2 2b 73 ab ed 16 88 6f  |.........+s....o|
-000000b0  62 77 fb 48 e4 5e 6d 7e  24 02 b6 08 fa 46 c8 76  |bw.H.^m~$....F.v|
-000000c0  18 fc f4 c4 08                                    |.....|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA b/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA
deleted file mode 100644
index 802aa1a..0000000
--- a/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA
+++ /dev/null
@@ -1,92 +0,0 @@
->>> Flow 1 (client to server)
-00000000  16 03 01 00 cb 01 00 00  c7 03 03 27 8a e9 f3 58  |...........'...X|
-00000010  5a 08 90 d6 d4 97 23 b6  a7 92 73 3a a3 3c c1 a1  |Z.....#...s:.<..|
-00000020  ca 06 23 c8 ed 4a 19 26  73 c9 62 00 00 38 c0 2c  |..#..J.&s.b..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.....=.<|
-00000060  00 35 00 2f 00 ff 01 00  00 66 00 00 00 0e 00 0c  |.5./.....f......|
-00000070  00 00 09 31 32 37 2e 30  2e 30 2e 31 00 0b 00 04  |...127.0.0.1....|
-00000080  03 00 01 02 00 0a 00 0c  00 0a 00 1d 00 17 00 1e  |................|
-00000090  00 19 00 18 00 16 00 00  00 17 00 00 00 0d 00 30  |...............0|
-000000a0  00 2e 04 03 05 03 06 03  08 07 08 08 08 09 08 0a  |................|
-000000b0  08 0b 08 04 08 05 08 06  04 01 05 01 06 01 03 03  |................|
-000000c0  02 03 03 01 02 01 03 02  02 02 04 02 05 02 06 02  |................|
->>> Flow 2 (server to client)
-00000000  16 03 03 00 37 02 00 00  33 03 03 00 00 00 00 00  |....7...3.......|
-00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 44 4f 57 4e 47  52 44 01 00 c0 14 00 00  |...DOWNGRD......|
-00000030  0b ff 01 00 01 00 00 0b  00 02 01 00 16 03 03 02  |................|
-00000040  59 0b 00 02 55 00 02 52  00 02 4f 30 82 02 4b 30  |Y...U..R..O0..K0|
-00000050  82 01 b4 a0 03 02 01 02  02 09 00 e8 f0 9d 3f e2  |..............?.|
-00000060  5b ea a6 30 0d 06 09 2a  86 48 86 f7 0d 01 01 0b  |[..0...*.H......|
-00000070  05 00 30 1f 31 0b 30 09  06 03 55 04 0a 13 02 47  |..0.1.0...U....G|
-00000080  6f 31 10 30 0e 06 03 55  04 03 13 07 47 6f 20 52  |o1.0...U....Go R|
-00000090  6f 6f 74 30 1e 17 0d 31  36 30 31 30 31 30 30 30  |oot0...160101000|
-000000a0  30 30 30 5a 17 0d 32 35  30 31 30 31 30 30 30 30  |000Z..2501010000|
-000000b0  30 30 5a 30 1a 31 0b 30  09 06 03 55 04 0a 13 02  |00Z0.1.0...U....|
-000000c0  47 6f 31 0b 30 09 06 03  55 04 03 13 02 47 6f 30  |Go1.0...U....Go0|
-000000d0  81 9f 30 0d 06 09 2a 86  48 86 f7 0d 01 01 01 05  |..0...*.H.......|
-000000e0  00 03 81 8d 00 30 81 89  02 81 81 00 db 46 7d 93  |.....0.......F}.|
-000000f0  2e 12 27 06 48 bc 06 28  21 ab 7e c4 b6 a2 5d fe  |..'.H..(!.~...].|
-00000100  1e 52 45 88 7a 36 47 a5  08 0d 92 42 5b c2 81 c0  |.RE.z6G....B[...|
-00000110  be 97 79 98 40 fb 4f 6d  14 fd 2b 13 8b c2 a5 2e  |..y.@.Om..+.....|
-00000120  67 d8 d4 09 9e d6 22 38  b7 4a 0b 74 73 2b c2 34  |g....."8.J.ts+.4|
-00000130  f1 d1 93 e5 96 d9 74 7b  f3 58 9f 6c 61 3c c0 b0  |......t{.X.la<..|
-00000140  41 d4 d9 2b 2b 24 23 77  5b 1c 3b bd 75 5d ce 20  |A..++$#w[.;.u]. |
-00000150  54 cf a1 63 87 1d 1e 24  c4 f3 1d 1a 50 8b aa b6  |T..c...$....P...|
-00000160  14 43 ed 97 a7 75 62 f4  14 c8 52 d7 02 03 01 00  |.C...ub...R.....|
-00000170  01 a3 81 93 30 81 90 30  0e 06 03 55 1d 0f 01 01  |....0..0...U....|
-00000180  ff 04 04 03 02 05 a0 30  1d 06 03 55 1d 25 04 16  |.......0...U.%..|
-00000190  30 14 06 08 2b 06 01 05  05 07 03 01 06 08 2b 06  |0...+.........+.|
-000001a0  01 05 05 07 03 02 30 0c  06 03 55 1d 13 01 01 ff  |......0...U.....|
-000001b0  04 02 30 00 30 19 06 03  55 1d 0e 04 12 04 10 9f  |..0.0...U.......|
-000001c0  91 16 1f 43 43 3e 49 a6  de 6d b6 80 d7 9f 60 30  |...CC>I..m....`0|
-000001d0  1b 06 03 55 1d 23 04 14  30 12 80 10 48 13 49 4d  |...U.#..0...H.IM|
-000001e0  13 7e 16 31 bb a3 01 d5  ac ab 6e 7b 30 19 06 03  |.~.1......n{0...|
-000001f0  55 1d 11 04 12 30 10 82  0e 65 78 61 6d 70 6c 65  |U....0...example|
-00000200  2e 67 6f 6c 61 6e 67 30  0d 06 09 2a 86 48 86 f7  |.golang0...*.H..|
-00000210  0d 01 01 0b 05 00 03 81  81 00 9d 30 cc 40 2b 5b  |...........0.@+[|
-00000220  50 a0 61 cb ba e5 53 58  e1 ed 83 28 a9 58 1a a9  |P.a...SX...(.X..|
-00000230  38 a4 95 a1 ac 31 5a 1a  84 66 3d 43 d3 2d d9 0b  |8....1Z..f=C.-..|
-00000240  f2 97 df d3 20 64 38 92  24 3a 00 bc cf 9c 7d b7  |.... d8.$:....}.|
-00000250  40 20 01 5f aa d3 16 61  09 a2 76 fd 13 c3 cc e1  |@ ._...a..v.....|
-00000260  0c 5c ee b1 87 82 f1 6c  04 ed 73 bb b3 43 77 8d  |.\.....l..s..Cw.|
-00000270  0c 1c f1 0f a1 d8 40 83  61 c9 4c 72 2b 9d ae db  |......@.a.Lr+...|
-00000280  46 06 06 4d f4 c1 b3 3e  c0 d1 bd 42 d4 db fe 3d  |F..M...>...B...=|
-00000290  13 60 84 5c 21 d3 3b e9  fa e7 16 03 03 00 ac 0c  |.`.\!.;.........|
-000002a0  00 00 a8 03 00 1d 20 2f  e5 7d a3 47 cd 62 43 15  |...... /.}.G.bC.|
-000002b0  28 da ac 5f bb 29 07 30  ff f6 84 af c4 cf c2 ed  |(.._.).0........|
-000002c0  90 99 5f 58 cb 3b 74 08  04 00 80 42 86 d0 0a 5b  |.._X.;t....B...[|
-000002d0  d7 97 20 4d be 16 b8 eb  51 66 28 3b f9 45 35 f5  |.. M....Qf(;.E5.|
-000002e0  de 1d 28 c9 36 63 5b 7b  f6 a7 64 79 fb 39 20 c3  |..(.6c[{..dy.9 .|
-000002f0  dd db 38 3e af 89 ce 91  f7 bd 51 b4 5e 01 d8 9b  |..8>......Q.^...|
-00000300  54 62 58 24 3b c2 43 59  a4 11 1a 2b 67 c5 5f 79  |TbX$;.CY...+g._y|
-00000310  fe 68 9d c7 e6 8b 36 8b  f9 cb 00 b0 b3 0f 52 fb  |.h....6.......R.|
-00000320  fe a5 e6 c6 26 9b d1 a2  17 4e e2 58 7f b2 80 78  |....&....N.X...x|
-00000330  10 b4 0a 47 e1 18 92 d4  a5 5a 86 06 36 ca f7 b6  |...G.....Z..6...|
-00000340  1c 83 81 0e eb 32 7d fe  06 c5 03 16 03 03 00 04  |.....2}.........|
-00000350  0e 00 00 00                                       |....|
->>> Flow 3 (client to server)
-00000000  16 03 03 00 25 10 00 00  21 20 14 7f fb 7d 0c ef  |....%...! ...}..|
-00000010  48 c4 8f 75 24 19 5f ee  5f 51 08 35 74 cf c3 ea  |H..u$._._Q.5t...|
-00000020  67 20 c4 f9 49 b2 cf 69  5a 77 14 03 03 00 01 01  |g ..I..iZw......|
-00000030  16 03 03 00 40 2b d2 f4  dc 36 98 ef 1d 43 f9 3e  |....@+...6...C.>|
-00000040  83 33 c0 71 a6 e3 ac f1  3c cc 94 e4 d0 fe 81 bc  |.3.q....<.......|
-00000050  94 56 15 eb 6a 7b 17 33  e1 a0 ef d5 7a 86 af ea  |.V..j{.3....z...|
-00000060  1f bb d5 8c 80 56 d5 e4  08 cd 68 bf c0 53 c2 56  |.....V....h..S.V|
-00000070  aa b3 38 1e 4e                                    |..8.N|
->>> 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 45 07 c3 ba 8c  |...........E....|
-00000020  d8 9f b6 f1 6a 14 bb b1  4e 84 3f 25 6a 3d ef f6  |....j...N.?%j=..|
-00000030  88 89 1a 91 22 ef e3 ed  ba 2a a3 7c 5b db e0 1d  |...."....*.|[...|
-00000040  b5 8d 7a ed e7 ad e1 31  b2 12 f5 17 03 03 00 40  |..z....1.......@|
-00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  a6 f3 0b 33 f7 7a 7c fb  fb b5 e6 eb 6e 0a 26 aa  |...3.z|.....n.&.|
-00000070  06 3b a6 bc 08 e5 3a b6  c9 a3 f3 77 28 93 45 08  |.;....:....w(.E.|
-00000080  1d 54 5e a3 92 cd 89 a3  e6 34 ec 52 70 c0 97 3c  |.T^......4.Rp..<|
-00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 2d 0d 96  57 b8 6f 90 1e 84 4d 35  |.....-..W.o...M5|
-000000b0  91 52 42 6b 8d a3 6b 21  22 60 1a c9 38 7f 5a ef  |.RBk..k!"`..8.Z.|
-000000c0  6e dd 84 06 79                                    |n...y|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback b/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback
new file mode 100644
index 0000000..6203e68
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback
@@ -0,0 +1,100 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 eb 01 00 00  e7 03 03 1c d3 8e 3b d9  |..............;.|
+00000010  fe 7d e7 f9 9f fa c6 51  c3 8c 1b dd dc 87 95 f4  |.}.....Q........|
+00000020  39 23 67 e4 d6 bd 94 93  fc 88 4e 20 c3 c0 e2 c1  |9#g.......N ....|
+00000030  3d 12 ec 4c 0a 3f 40 51  13 24 61 11 c0 5d 09 f9  |=..L.?@Q.$a..]..|
+00000040  08 d6 3e cd e7 b3 51 c3  06 8f b4 42 00 04 13 03  |..>...Q....B....|
+00000050  00 ff 01 00 00 9a 00 0b  00 04 03 00 01 02 00 0a  |................|
+00000060  00 0c 00 0a 00 1d 00 17  00 1e 00 19 00 18 00 23  |...............#|
+00000070  00 00 00 10 00 19 00 17  06 70 72 6f 74 6f 33 08  |.........proto3.|
+00000080  68 74 74 70 2f 31 2e 31  06 70 72 6f 74 6f 34 00  |http/1.1.proto4.|
+00000090  16 00 00 00 17 00 00 00  0d 00 1e 00 1c 04 03 05  |................|
+000000a0  03 06 03 08 07 08 08 08  09 08 0a 08 0b 08 04 08  |................|
+000000b0  05 08 06 04 01 05 01 06  01 00 2b 00 03 02 03 04  |..........+.....|
+000000c0  00 2d 00 02 01 01 00 33  00 26 00 24 00 1d 00 20  |.-.....3.&.$... |
+000000d0  f4 05 eb 4a 7a 73 20 18  74 aa 14 2a 0c 35 63 29  |...Jzs .t..*.5c)|
+000000e0  cb f2 ad d1 a2 3d bd 9d  02 b4 62 00 bc eb 10 58  |.....=....b....X|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 7a 02 00 00  76 03 03 00 00 00 00 00  |....z...v.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 20 c3 c0 e2 c1  |........... ....|
+00000030  3d 12 ec 4c 0a 3f 40 51  13 24 61 11 c0 5d 09 f9  |=..L.?@Q.$a..]..|
+00000040  08 d6 3e cd e7 b3 51 c3  06 8f b4 42 13 03 00 00  |..>...Q....B....|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 2f  |..+.....3.$... /|
+00000060  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
+00000070  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74 14  |.........._X.;t.|
+00000080  03 03 00 01 01 17 03 03  00 17 fb 75 d8 5c 50 35  |...........u.\P5|
+00000090  55 82 ba 65 1e 63 73 b8  c1 e9 d7 f5 28 68 3c c1  |U..e.cs.....(h<.|
+000000a0  5d 17 03 03 02 6d 56 c9  a9 09 73 6a bc fd 1a 3c  |]....mV...sj...<|
+000000b0  6a f8 3e 32 99 83 e8 f6  01 9e 5e 30 e8 53 7f 72  |j.>2......^0.S.r|
+000000c0  fd 86 72 a8 9e 47 25 67  c1 f1 9a 03 c0 9d 6f 9d  |..r..G%g......o.|
+000000d0  bd ed 29 30 8f 3c 01 ce  49 bb 5f dd 58 9a ae 80  |..)0.<..I._.X...|
+000000e0  5c 2d 81 fc ea 7b 03 03  3d 5d bb 92 23 73 67 89  |\-...{..=]..#sg.|
+000000f0  2e f0 ec 08 20 8a 36 eb  43 a6 a1 68 d0 39 95 37  |.... .6.C..h.9.7|
+00000100  6b 15 a9 0e 46 20 92 51  9c 04 bf 3b 07 97 84 cb  |k...F .Q...;....|
+00000110  1f 30 38 37 2e ff e7 0f  f5 14 93 5a 84 f1 f7 10  |.087.......Z....|
+00000120  c2 a5 0d bb 97 96 ef 4a  e0 13 c0 63 72 2b 60 f3  |.......J...cr+`.|
+00000130  59 b5 57 aa 5f d1 da a9  0e dd 9c dd c2 cb 61 fe  |Y.W._.........a.|
+00000140  e2 69 8e db 5d 70 6c 3a  33 e0 9e db 9a 31 26 6a  |.i..]pl:3....1&j|
+00000150  2b 9e 19 8e bb 5d 06 48  ea c0 a1 c6 11 24 fb c4  |+....].H.....$..|
+00000160  ce ae 48 54 64 81 d1 84  38 a6 e0 7a 7b 74 2b bc  |..HTd...8..z{t+.|
+00000170  ce 07 8b b6 04 1f 5b 4c  36 29 68 0c 8c c7 32 15  |......[L6)h...2.|
+00000180  93 e0 10 52 c2 27 23 96  c5 0c 9c e9 e2 a9 08 7d  |...R.'#........}|
+00000190  25 68 65 f5 4e 44 eb a9  85 78 13 e1 0d 86 5e dc  |%he.ND...x....^.|
+000001a0  fd e5 c6 dd 65 46 8e 2f  32 82 83 0b dd 67 f8 42  |....eF./2....g.B|
+000001b0  65 87 3b 08 fe b1 f5 12  e9 74 21 04 12 6d 75 35  |e.;......t!..mu5|
+000001c0  b2 eb 93 95 72 10 fa 56  96 77 c3 0c 17 8c 9e f6  |....r..V.w......|
+000001d0  77 19 28 37 96 3e 73 98  f4 d2 91 4f 40 db 76 56  |w.(7.>s....O@.vV|
+000001e0  ce b5 a8 7a b8 86 d0 9a  ba b5 8b 40 c2 63 e1 cf  |...z.......@.c..|
+000001f0  49 29 2c 5d 1a 9b 8b 56  cb 93 ca 2c c0 d0 15 b7  |I),]...V...,....|
+00000200  8a f1 6a d5 0a a8 81 57  b1 6e 10 cd a5 ff b1 4d  |..j....W.n.....M|
+00000210  47 c6 9b 35 f1 5f 83 91  22 f6 88 68 65 b3 b9 c9  |G..5._.."..he...|
+00000220  02 dc 4b f7 13 39 06 e6  3a ec 94 ef 51 15 05 72  |..K..9..:...Q..r|
+00000230  1d f4 9d 3b da ca 8d 2c  64 be 9b 45 99 2c 63 cc  |...;...,d..E.,c.|
+00000240  22 b3 8b 93 ad f6 2c f0  d2 d9 11 3f 5b c0 40 fa  |".....,....?[.@.|
+00000250  90 6e a0 76 b2 43 b9 4c  72 c4 24 28 a2 bf 56 d6  |.n.v.C.Lr.$(..V.|
+00000260  d2 a7 2a d1 8c 5e 1d eb  f8 be d0 43 da 7a c7 88  |..*..^.....C.z..|
+00000270  61 67 a2 69 85 23 43 3e  d4 88 f2 33 c3 5b 38 0a  |ag.i.#C>...3.[8.|
+00000280  1e de 28 3b 3b 19 de 95  2f 84 c0 37 88 80 59 2f  |..(;;.../..7..Y/|
+00000290  a6 ee 93 1a 69 08 c3 df  7c cf da c3 9b 96 70 d9  |....i...|.....p.|
+000002a0  60 c5 e9 0f 42 f6 1a f2  58 5e f2 32 61 6a b2 a3  |`...B...X^.2aj..|
+000002b0  1f 97 fa 08 6c 3f 4b 83  1f 04 66 80 8a 26 3a 7f  |....l?K...f..&:.|
+000002c0  24 30 ec 10 ae 7d 19 ff  39 91 ca 97 4e ed 0a d7  |$0...}..9...N...|
+000002d0  64 3b 6b 50 29 33 0d b2  10 bc 83 63 3c fb 9a 82  |d;kP)3.....c<...|
+000002e0  3b 7f bc 04 40 f1 33 64  4a 80 cd 01 f9 f4 c6 89  |;...@.3dJ.......|
+000002f0  65 27 25 f9 cf 4f 7e c8  6e d9 0e ec 47 4a 51 29  |e'%..O~.n...GJQ)|
+00000300  2f be 34 50 bd 9b d2 d8  b7 ea bb 0b a1 e0 20 1b  |/.4P.......... .|
+00000310  02 9c f2 17 03 03 00 99  61 dc 0b 3a 30 de 39 f6  |........a..:0.9.|
+00000320  f3 db f8 6c 3b fa 4e 1e  7e 62 a5 ae 73 ba e1 41  |...l;.N.~b..s..A|
+00000330  58 77 2a c1 7a 0c 50 bb  0c 57 b4 c4 25 bf 2f 9f  |Xw*.z.P..W..%./.|
+00000340  38 91 e2 65 22 9d ca ac  18 58 7e 81 2d fd 74 24  |8..e"....X~.-.t$|
+00000350  28 69 76 11 df 9d 23 b8  be ae 8b e0 93 8e 5d df  |(iv...#.......].|
+00000360  0a 64 d0 b7 02 68 aa 86  01 0d 55 11 3b 76 70 c6  |.d...h....U.;vp.|
+00000370  83 0c 5e 0a e3 37 a5 8b  ad 25 50 b9 e8 5c 6b 04  |..^..7...%P..\k.|
+00000380  b4 51 ec 9c d3 fa c6 b7  9c f0 46 aa 73 da 3c 0d  |.Q........F.s.<.|
+00000390  d3 bd 32 81 d4 d2 f1 1a  b0 92 f3 73 3e 54 2b 05  |..2........s>T+.|
+000003a0  92 24 34 75 df d6 18 a0  6a 82 95 4c 9b fc 7e b6  |.$4u....j..L..~.|
+000003b0  8e 17 03 03 00 35 8f 34  0e 3b 91 d8 e7 74 24 71  |.....5.4.;...t$q|
+000003c0  0e 7b f3 12 bb 76 2f 31  12 17 b8 9e 24 ce f9 2f  |.{...v/1....$../|
+000003d0  3f 5d f2 13 4b 2e 9b 1e  c4 78 03 a6 c8 07 11 a3  |?]..K....x......|
+000003e0  98 79 61 6e 4f 44 6e 18  ee c4 9b 17 03 03 00 93  |.yanODn.........|
+000003f0  64 dd 52 a9 d9 51 63 6a  a0 a3 c2 75 6b 5d 1d 54  |d.R..Qcj...uk].T|
+00000400  ce d4 53 7e 14 8e d9 26  93 28 78 65 16 1b 95 77  |..S~...&.(xe...w|
+00000410  68 0a 46 f1 82 36 bb 8a  fa 0d df 54 8c 3d 83 e0  |h.F..6.....T.=..|
+00000420  d7 de 2d 96 e9 c4 d7 22  d3 97 8e ae 90 f8 fc e6  |..-...."........|
+00000430  a6 4b 78 98 4c c5 28 87  91 46 fa f4 1c 8d 0e ec  |.Kx.L.(..F......|
+00000440  0d 71 40 9a 04 49 b4 e8  5b 62 6f cd 16 c1 d5 fb  |.q@..I..[bo.....|
+00000450  73 2a 96 8f e5 a2 f4 11  1e df 2d 40 45 6b d5 a9  |s*........-@Ek..|
+00000460  e4 e3 f7 93 fc fa d7 20  af d5 f7 b4 0e 09 ad d5  |....... ........|
+00000470  26 87 b8 6c e2 20 95 fb  c0 70 3e 38 be b7 b1 9f  |&..l. ...p>8....|
+00000480  70 da c1                                          |p..|
+>>> Flow 3 (client to server)
+00000000  14 03 03 00 01 01 17 03  03 00 35 29 d2 b9 bb 9b  |..........5)....|
+00000010  de 6c 5d 22 23 c1 fe 99  4c c5 33 bf fd 70 36 6b  |.l]"#...L.3..p6k|
+00000020  f1 a5 92 e8 bf 7c 3d 6e  ef 6a 44 73 bc cb 27 1c  |.....|=n.jDs..'.|
+00000030  09 5d bf 99 4c 19 24 c3  3b 30 91 b5 e3 b6 63 45  |.]..L.$.;0....cE|
+>>> Flow 4 (server to client)
+00000000  17 03 03 00 1e 52 55 85  7c b8 87 dd c7 b2 d9 5b  |.....RU.|......[|
+00000010  18 1d bb ac bf b6 ab 76  82 be 64 0e b2 7b 2c 0f  |.......v..d..{,.|
+00000020  aa 17 92 17 03 03 00 13  79 0a 60 b1 46 20 33 74  |........y.`.F 3t|
+00000030  ed 12 a0 23 de 68 88 fc  6f dd 8e                 |...#.h..o..|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch b/src/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch
index 0b5dc9b..b51ff25 100644
--- a/src/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch
+++ b/src/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch
@@ -1,9 +1,9 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 e2 01 00 00  de 03 03 ea ab 77 e1 48  |.............w.H|
-00000010  64 70 23 5c af b3 a7 3d  60 93 a0 30 0a 8c 98 61  |dp#\...=`..0...a|
-00000020  3a ab bc a9 11 c1 2f f5  ed d7 63 20 d4 29 26 9d  |:...../...c .)&.|
-00000030  64 37 72 d1 2c 7d 09 3b  94 67 f9 1c 19 c3 7e 17  |d7r.,}.;.g....~.|
-00000040  ec 80 5f 09 38 c1 15 4d  59 45 5c c3 00 04 13 03  |.._.8..MYE\.....|
+00000000  16 03 01 00 e2 01 00 00  de 03 03 9f 73 81 5f 56  |............s._V|
+00000010  a9 02 5f 8c 33 db dc 2a  92 d0 5e 7c e9 e6 01 d7  |.._.3..*..^|....|
+00000020  67 b6 bb 74 da bb d0 c1  11 08 20 20 9f bd d6 f8  |g..t......  ....|
+00000030  d7 8c e5 32 15 1d 4a 4c  36 ce 72 90 cb 68 ca dc  |...2..JL6.r..h..|
+00000040  ea b3 57 93 9a 12 e6 0e  9a bd 91 1a 00 04 13 03  |..W.............|
 00000050  00 ff 01 00 00 91 00 0b  00 04 03 00 01 02 00 0a  |................|
 00000060  00 0c 00 0a 00 1d 00 17  00 1e 00 19 00 18 00 23  |...............#|
 00000070  00 00 00 10 00 10 00 0e  06 70 72 6f 74 6f 32 06  |.........proto2.|
@@ -11,90 +11,17 @@
 00000090  00 1e 00 1c 04 03 05 03  06 03 08 07 08 08 08 09  |................|
 000000a0  08 0a 08 0b 08 04 08 05  08 06 04 01 05 01 06 01  |................|
 000000b0  00 2b 00 03 02 03 04 00  2d 00 02 01 01 00 33 00  |.+......-.....3.|
-000000c0  26 00 24 00 1d 00 20 68  64 e8 c1 4a c5 d5 b8 91  |&.$... hd..J....|
-000000d0  a0 20 c7 aa 8a 41 90 d6  d0 5e ed 6c ed e4 77 aa  |. ...A...^.l..w.|
-000000e0  ec 33 93 e3 d5 b7 55                              |.3....U|
+000000c0  26 00 24 00 1d 00 20 79  79 04 d3 03 58 93 22 5d  |&.$... yy...X."]|
+000000d0  06 69 1a 03 11 4e 65 e5  30 85 29 02 22 c8 11 6d  |.i...Ne.0.)."..m|
+000000e0  21 86 d4 4d 58 93 74                              |!..MX.t|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 7a 02 00 00  76 03 03 00 00 00 00 00  |....z...v.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 20 d4 29 26 9d  |........... .)&.|
-00000030  64 37 72 d1 2c 7d 09 3b  94 67 f9 1c 19 c3 7e 17  |d7r.,}.;.g....~.|
-00000040  ec 80 5f 09 38 c1 15 4d  59 45 5c c3 13 03 00 00  |.._.8..MYE\.....|
+00000020  00 00 00 00 00 00 00 00  00 00 00 20 9f bd d6 f8  |........... ....|
+00000030  d7 8c e5 32 15 1d 4a 4c  36 ce 72 90 cb 68 ca dc  |...2..JL6.r..h..|
+00000040  ea b3 57 93 9a 12 e6 0e  9a bd 91 1a 13 03 00 00  |..W.............|
 00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 2f  |..+.....3.$... /|
 00000060  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 00000070  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74 14  |.........._X.;t.|
-00000080  03 03 00 01 01 17 03 03  00 17 c0 d3 a2 c3 42 b4  |..............B.|
-00000090  39 f1 b6 f1 0a ac f3 76  dd 36 15 eb d7 3b 3f 63  |9......v.6...;?c|
-000000a0  0b 17 03 03 02 6d f2 02  6d 15 de 46 b3 30 ef 57  |.....m..m..F.0.W|
-000000b0  e5 a3 35 11 5c c3 b4 2e  ad 74 ca db d2 90 eb b4  |..5.\....t......|
-000000c0  ba 14 7e b0 65 68 e8 31  76 2a 28 e4 be bb d1 c3  |..~.eh.1v*(.....|
-000000d0  45 cb ba 07 eb 27 d9 5e  4a 45 52 10 62 f0 8f b2  |E....'.^JER.b...|
-000000e0  7c ad 0f 63 5c 39 f7 6e  f2 68 3e bc fd ec fe fa  ||..c\9.n.h>.....|
-000000f0  9b ba 45 96 2b 94 27 34  2c 78 c8 5f 40 e3 f9 20  |..E.+.'4,x._@.. |
-00000100  51 15 3d dc 70 d1 50 7c  26 6b 51 3f 47 61 0b e6  |Q.=.p.P|&kQ?Ga..|
-00000110  04 ee 49 19 27 f0 91 c5  0f 15 0a 90 a6 0c 14 f2  |..I.'...........|
-00000120  2f f1 42 28 be a0 7a ce  16 14 bf ff 34 34 a8 d8  |/.B(..z.....44..|
-00000130  61 e6 26 6a 00 62 a0 82  53 c6 27 30 89 81 8d fb  |a.&j.b..S.'0....|
-00000140  9e 97 bc a0 ce 2f a1 e2  bf 9e fe d2 cc 11 4e 00  |...../........N.|
-00000150  89 d1 e8 3b ab 58 e4 66  0a 87 00 b1 c1 a0 2d b0  |...;.X.f......-.|
-00000160  96 b3 13 9b d3 c0 16 6b  87 e8 e3 9e 6c 30 1b 67  |.......k....l0.g|
-00000170  c1 53 a5 4b 55 44 4e 27  6e ea 7c 7d 9f 44 b4 ca  |.S.KUDN'n.|}.D..|
-00000180  15 6f e5 d1 7f 18 e4 12  66 2d d5 a2 47 0c 73 26  |.o......f-..G.s&|
-00000190  b0 bf 93 5b 46 9c 3f 78  69 05 a1 38 0f 61 ea d6  |...[F.?xi..8.a..|
-000001a0  61 97 80 c5 72 be 6d be  2d e5 a2 9e d8 b3 bf 8d  |a...r.m.-.......|
-000001b0  a4 53 ba 6d fe c8 8d ac  c1 4a 6e 76 bf 72 1e 5a  |.S.m.....Jnv.r.Z|
-000001c0  0a 51 f3 c8 1f 11 91 36  f0 f5 ba 68 e8 69 c3 77  |.Q.....6...h.i.w|
-000001d0  52 63 dc b3 93 80 0d fd  9a 7d 7f f8 47 f8 62 2a  |Rc.......}..G.b*|
-000001e0  3d 4f 1b 46 9f cb 07 b6  96 00 b1 08 e7 32 50 41  |=O.F.........2PA|
-000001f0  83 da 20 c2 b0 c0 33 33  3f f2 f9 84 f0 64 9f 37  |.. ...33?....d.7|
-00000200  4b b6 7b ab 2e e9 50 8b  6a 61 da 12 51 54 13 25  |K.{...P.ja..QT.%|
-00000210  46 5d 90 06 ef 88 4e be  64 67 80 02 1f 25 9c 28  |F]....N.dg...%.(|
-00000220  07 b3 24 2b 10 81 c1 72  7c 94 97 b3 5a 16 bc cf  |..$+...r|...Z...|
-00000230  52 44 41 2c d7 ba e9 9f  4c d7 28 e6 b7 bb b0 fd  |RDA,....L.(.....|
-00000240  17 b2 0b 83 33 ed 2f c7  2d 42 37 fd 0a d0 4b c7  |....3./.-B7...K.|
-00000250  97 61 17 d6 cd cd 0f e0  0d dd ab 40 fb 00 4d 81  |.a.........@..M.|
-00000260  da 7d 1d 0e 48 d9 a7 6c  ba 2a 21 49 18 0f a4 7c  |.}..H..l.*!I...||
-00000270  af 0d 1b ca 94 f1 6c 78  59 ad 50 e4 1c 7b 37 45  |......lxY.P..{7E|
-00000280  e8 1b 73 ad 96 8d 98 d6  07 26 07 fd a8 e6 8c 39  |..s......&.....9|
-00000290  f1 5a 10 ef 04 97 fe d3  be cb f2 c1 5b 27 e8 d0  |.Z..........['..|
-000002a0  f9 b3 16 b9 82 6d e8 be  54 c7 cf 44 a4 8a fd 75  |.....m..T..D...u|
-000002b0  96 2a f1 65 2b d3 8f f5  86 a3 bf 12 74 c1 e4 d8  |.*.e+.......t...|
-000002c0  a9 db c9 43 05 07 b1 51  dc 20 29 d0 c0 9a 6d 10  |...C...Q. )...m.|
-000002d0  83 5f 87 a6 ab 03 58 43  1f 35 1c af dd 37 10 1b  |._....XC.5...7..|
-000002e0  16 50 52 e5 3c f5 3c ae  4f 92 7e dc 47 2e b3 9c  |.PR.<.<.O.~.G...|
-000002f0  1f d2 a0 31 8b 32 21 35  52 af bd f1 0b 2c 4e 6f  |...1.2!5R....,No|
-00000300  59 32 d8 db d6 9f b8 bd  bc a0 3b 77 41 43 46 fb  |Y2........;wACF.|
-00000310  2b 0e 82 17 03 03 00 99  0a 63 cd 1f fa 90 4d 95  |+........c....M.|
-00000320  17 d8 81 36 5c 62 17 33  6c 8d 9d 9f 26 3e 3a 2f  |...6\b.3l...&>:/|
-00000330  65 84 23 56 46 25 f6 1c  dd ea 6f 21 b4 05 d8 19  |e.#VF%....o!....|
-00000340  a3 c9 4b b1 03 78 39 32  00 97 6c d5 6e e3 ff 45  |..K..x92..l.n..E|
-00000350  ac 2a 10 71 21 ad d3 b9  73 b7 77 0e a8 79 fd 50  |.*.q!...s.w..y.P|
-00000360  a9 f1 41 39 2d 05 3d 92  3c 69 0a d7 7d 11 da f0  |..A9-.=.<i..}...|
-00000370  fe 83 a6 c8 79 96 33 9c  df 12 1c 39 90 da d3 94  |....y.3....9....|
-00000380  7e 4a 5d 1c 31 b2 5c ea  33 2c 40 56 3a 80 86 0c  |~J].1.\.3,@V:...|
-00000390  93 bf 0f 56 b6 67 2e 4c  7f 9f 0c d5 58 9f 9d d6  |...V.g.L....X...|
-000003a0  db e1 74 13 eb 7c a6 a5  1a 65 64 37 66 74 68 3a  |..t..|...ed7fth:|
-000003b0  73 17 03 03 00 35 53 63  0b ce 12 f7 f5 39 1d 20  |s....5Sc.....9. |
-000003c0  41 89 5f a0 d2 fa 84 a3  2b e2 95 f4 9b e8 14 66  |A._.....+......f|
-000003d0  2c c7 01 ad e9 ba 6c 11  86 c9 00 93 49 c1 af 30  |,.....l.....I..0|
-000003e0  13 a7 59 16 a2 32 43 63  eb c2 64 17 03 03 00 93  |..Y..2Cc..d.....|
-000003f0  20 da 02 66 ca 8d fa b5  4d 6a 0d e7 c6 a9 7b e2  | ..f....Mj....{.|
-00000400  1c e8 61 c4 59 a2 30 f4  1b 27 c9 05 2e a1 33 93  |..a.Y.0..'....3.|
-00000410  43 8a 70 15 9b 26 19 e3  0a a6 31 d9 ce 46 f7 78  |C.p..&....1..F.x|
-00000420  bd 88 c4 ff 73 eb a0 3c  42 01 b0 6d 55 2c 61 7b  |....s..<B..mU,a{|
-00000430  d6 87 2f 50 6e 64 ae 73  69 a2 04 dc ec 3a e7 a5  |../Pnd.si....:..|
-00000440  5c 24 df eb e8 bc 7b b9  df 3e a4 d8 26 1a ff 4b  |\$....{..>..&..K|
-00000450  a6 ce 93 36 ea a1 fd d9  78 61 a3 0e 08 72 da 03  |...6....xa...r..|
-00000460  5d 0c 27 48 75 61 25 ef  77 39 39 e5 8e 87 2e 86  |].'Hua%.w99.....|
-00000470  d5 70 d3 3b f4 b4 75 b1  44 d1 5f fe 9c d8 18 7d  |.p.;..u.D._....}|
-00000480  f9 89 20                                          |.. |
->>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 00 35 a8 ab 13 71 ec  |..........5...q.|
-00000010  af a7 4a 48 65 6d 02 ea  8a 0f d1 4d 2a 97 b6 11  |..JHem.....M*...|
-00000020  6d 53 5f be a4 b3 a7 20  d4 d3 aa 90 62 30 26 3f  |mS_.... ....b0&?|
-00000030  be c8 ed fc 6f 44 cc a5  3a 7f 4d 95 51 ed dc 80  |....oD..:.M.Q...|
->>> Flow 4 (server to client)
-00000000  17 03 03 00 1e 6a f5 e4  df 1b 2a 5a 87 68 b1 a7  |.....j....*Z.h..|
-00000010  1d b8 ef 04 b4 ac b9 50  b3 95 1c 12 d7 44 ca 46  |.......P.....D.F|
-00000020  ea 26 2a 17 03 03 00 13  a4 6b 4d 27 81 62 b0 3c  |.&*......kM'.b.<|
-00000030  d0 be d1 34 46 4c 7b 6c  71 24 d8                 |...4FL{lq$.|
+00000080  03 03 00 01 01 17 03 03  00 13 7c ab 7f dd 94 cf  |..........|.....|
+00000090  d7 98 34 16 75 02 63 37  fa 4f 19 4e 18           |..4.u.c7.O.N.|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ALPN-NotConfigured b/src/crypto/tls/testdata/Server-TLSv13-ALPN-NotConfigured
new file mode 100644
index 0000000..e0830d3
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ALPN-NotConfigured
@@ -0,0 +1,100 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 e2 01 00 00  de 03 03 9f 49 a7 46 f8  |............I.F.|
+00000010  72 04 47 a1 8e 4f 89 c3  cd 89 92 2f 7a 8a 07 37  |r.G..O...../z..7|
+00000020  8c 25 10 42 26 07 8b a2  71 3e 92 20 4c 83 1b 70  |.%.B&...q>. L..p|
+00000030  45 c3 79 68 c3 83 a7 05  c2 22 06 c6 91 da 8b 96  |E.yh....."......|
+00000040  4c 9d 89 c2 ec b8 49 87  17 3f 6c ae 00 04 13 03  |L.....I..?l.....|
+00000050  00 ff 01 00 00 91 00 0b  00 04 03 00 01 02 00 0a  |................|
+00000060  00 0c 00 0a 00 1d 00 17  00 1e 00 19 00 18 00 23  |...............#|
+00000070  00 00 00 10 00 10 00 0e  06 70 72 6f 74 6f 32 06  |.........proto2.|
+00000080  70 72 6f 74 6f 31 00 16  00 00 00 17 00 00 00 0d  |proto1..........|
+00000090  00 1e 00 1c 04 03 05 03  06 03 08 07 08 08 08 09  |................|
+000000a0  08 0a 08 0b 08 04 08 05  08 06 04 01 05 01 06 01  |................|
+000000b0  00 2b 00 03 02 03 04 00  2d 00 02 01 01 00 33 00  |.+......-.....3.|
+000000c0  26 00 24 00 1d 00 20 f4  91 87 6a ac cd 25 5e f1  |&.$... ...j..%^.|
+000000d0  0d 25 fb af a4 d4 fb 16  32 63 af 04 2d 21 d7 2f  |.%......2c..-!./|
+000000e0  61 f2 c2 d4 c4 6c 2b                              |a....l+|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 7a 02 00 00  76 03 03 00 00 00 00 00  |....z...v.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 20 4c 83 1b 70  |........... L..p|
+00000030  45 c3 79 68 c3 83 a7 05  c2 22 06 c6 91 da 8b 96  |E.yh....."......|
+00000040  4c 9d 89 c2 ec b8 49 87  17 3f 6c ae 13 03 00 00  |L.....I..?l.....|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 2f  |..+.....3.$... /|
+00000060  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
+00000070  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74 14  |.........._X.;t.|
+00000080  03 03 00 01 01 17 03 03  00 17 60 79 16 61 4f 6c  |..........`y.aOl|
+00000090  9e 2e ce fd cc f5 29 67  38 e7 53 67 92 b1 5f 9d  |......)g8.Sg.._.|
+000000a0  db 17 03 03 02 6d 54 d9  d6 a1 8e c2 1b 70 3f 3d  |.....mT......p?=|
+000000b0  a2 2e 0f a5 37 96 e1 68  66 69 cc f8 e9 06 4d bc  |....7..hfi....M.|
+000000c0  c2 9a 6e 0f ea d4 73 59  6a 59 28 79 7f 44 0c 32  |..n...sYjY(y.D.2|
+000000d0  29 22 51 d1 fb 00 c7 33  44 8b 19 71 98 8a 03 44  |)"Q....3D..q...D|
+000000e0  e0 95 ad 8f 91 66 e6 15  b8 99 b3 f8 2f 02 e9 a0  |.....f....../...|
+000000f0  4a 25 ec 3f 36 56 0c eb  0a a3 e0 d3 79 a1 b3 9e  |J%.?6V......y...|
+00000100  dc 42 08 76 a4 c3 55 91  06 11 e7 0c 94 dd 71 fc  |.B.v..U.......q.|
+00000110  bf 8a 87 d2 97 07 a3 b9  36 7e 58 ff ef b3 a3 f4  |........6~X.....|
+00000120  6e f1 23 d6 50 e3 23 d3  dc e7 20 ce 9d 84 17 cf  |n.#.P.#... .....|
+00000130  2d 5f b1 f9 8d 36 41 7d  ba 3b 93 63 2f bc be f0  |-_...6A}.;.c/...|
+00000140  a1 3a bb 5f b3 99 03 13  fb d2 2c 1a 8c cc 32 02  |.:._......,...2.|
+00000150  ef 93 b4 58 a8 f8 b1 42  52 24 c2 73 01 cb 5a fb  |...X...BR$.s..Z.|
+00000160  9f fc 38 08 d7 f9 0d d7  20 fa dc 8b 1a 8c 73 0f  |..8..... .....s.|
+00000170  f8 79 b2 84 e1 49 2d 8e  6d 46 16 38 0e 02 2a 2c  |.y...I-.mF.8..*,|
+00000180  f4 44 89 da f1 7a 01 55  9e 93 a8 d6 d5 f5 72 28  |.D...z.U......r(|
+00000190  47 2b 4f 17 7e a5 01 fd  ad 85 e0 6d f9 82 e8 cd  |G+O.~......m....|
+000001a0  09 18 84 8c 9d 4f 4e a1  43 ff d6 3d 55 05 fc 56  |.....ON.C..=U..V|
+000001b0  e6 d6 b6 61 4a c7 c7 9c  62 64 26 1d 33 1e 4f d5  |...aJ...bd&.3.O.|
+000001c0  5e ee 1f a9 ad 24 e4 7f  05 cc 02 7a f7 e0 c2 ce  |^....$.....z....|
+000001d0  b8 11 c9 a1 fd c5 d8 0e  ef f8 c9 6a 2d 49 30 63  |...........j-I0c|
+000001e0  e3 9b 43 bf 87 e1 5f 55  39 fa 80 ec 84 55 59 5d  |..C..._U9....UY]|
+000001f0  52 76 4c f4 70 eb 43 6a  b2 07 d5 29 4c 58 39 04  |RvL.p.Cj...)LX9.|
+00000200  46 42 70 8d 28 61 7c d5  7a 3a 2e a0 9f 74 49 2d  |FBp.(a|.z:...tI-|
+00000210  33 8d 39 18 70 8d 3c 50  4f 62 07 77 2d 15 1f 4b  |3.9.p.<POb.w-..K|
+00000220  22 01 c6 cb ac 2f 2d 9a  cf a6 9b 0e 24 99 41 64  |"..../-.....$.Ad|
+00000230  3e f2 9f 5f 17 7b d7 b8  3c b6 6d 24 5b 91 8c 13  |>.._.{..<.m$[...|
+00000240  1a 40 4e 80 7f 44 12 57  c9 03 57 c6 9b 54 0d 39  |.@N..D.W..W..T.9|
+00000250  91 88 72 3e c8 f9 18 eb  34 7c 0a eb 2d c8 56 1c  |..r>....4|..-.V.|
+00000260  84 8a 62 a2 3a 0a 52 b8  5a b6 5d 54 78 ae 05 b2  |..b.:.R.Z.]Tx...|
+00000270  f4 6c 2d 5e 92 94 6b f3  1e 93 13 1a 65 74 60 e3  |.l-^..k.....et`.|
+00000280  dd 15 36 62 2b 71 b1 bb  59 19 08 af 8e 9b d0 47  |..6b+q..Y......G|
+00000290  05 7b a3 89 ac 68 cf a0  32 ba 4a 2b 9e 5f a5 dc  |.{...h..2.J+._..|
+000002a0  b3 00 79 a8 1c f6 11 b8  6d 9c 51 b7 f1 f6 b2 13  |..y.....m.Q.....|
+000002b0  56 57 4e ac 97 ff 5a b8  52 33 0c c1 3d 52 81 6e  |VWN...Z.R3..=R.n|
+000002c0  85 ba b2 04 4b eb 41 aa  03 ff ae 63 93 72 3a 5f  |....K.A....c.r:_|
+000002d0  65 81 f9 6a 2a e4 70 f8  b3 59 31 51 62 ad 25 24  |e..j*.p..Y1Qb.%$|
+000002e0  82 0c b5 ad 7c 87 21 97  07 c0 c1 6d f0 22 97 0d  |....|.!....m."..|
+000002f0  28 cf a7 4d 74 d2 9c ac  d7 15 83 26 f7 2f 76 d4  |(..Mt......&./v.|
+00000300  ad cf e7 ef 1c f4 3e 1f  b4 f4 4f 76 6a 98 15 01  |......>...Ovj...|
+00000310  cd 17 8b 17 03 03 00 99  0b 15 9d 16 c6 2a 52 53  |.............*RS|
+00000320  33 d7 01 db 8a 49 1d d6  83 b7 28 a4 07 f0 73 5e  |3....I....(...s^|
+00000330  60 03 2c 6f 3f e0 88 a1  76 22 d6 23 0a df ca 86  |`.,o?...v".#....|
+00000340  b0 44 b9 1d 9a d7 53 f2  2b 57 a1 65 01 d4 e7 b4  |.D....S.+W.e....|
+00000350  9e 22 00 d2 20 da cd 55  7d 61 86 86 19 81 f9 ed  |.".. ..U}a......|
+00000360  f8 af c4 69 54 1d 35 0a  6f 9e 69 40 13 08 82 dd  |...iT.5.o.i@....|
+00000370  59 11 31 f2 81 a7 4b f1  bd d9 f2 5c 29 22 16 49  |Y.1...K....\)".I|
+00000380  86 62 8c a8 b8 89 58 96  cc d1 e4 e8 5e ef 6c b7  |.b....X.....^.l.|
+00000390  00 71 3d ab 92 b8 78 56  a7 25 5e a0 c4 d8 8c 02  |.q=...xV.%^.....|
+000003a0  c4 c8 eb d3 be 68 21 05  5c 5f 9c b0 ec 20 99 ff  |.....h!.\_... ..|
+000003b0  00 17 03 03 00 35 c9 c1  5e 25 1c b9 64 8e c2 fd  |.....5..^%..d...|
+000003c0  50 87 48 e6 02 36 75 31  67 f6 82 3c 94 79 7d 0b  |P.H..6u1g..<.y}.|
+000003d0  cb 83 b1 f4 e1 00 5f a6  b6 2c 2d 63 40 ab 98 f9  |......_..,-c@...|
+000003e0  e3 8e 4a 7e d4 77 3d 55  90 10 75 17 03 03 00 93  |..J~.w=U..u.....|
+000003f0  47 c4 6e 19 29 c2 5e d5  93 b7 c2 cc 46 a9 49 9d  |G.n.).^.....F.I.|
+00000400  8a 3b 9a 35 bb 45 22 13  b6 eb c9 ec ba 44 3c 24  |.;.5.E"......D<$|
+00000410  f2 ed bd 76 11 cc af 00  b3 89 63 5d 79 32 cc d7  |...v......c]y2..|
+00000420  5c 34 f3 5e 64 36 92 5d  ac ac 33 74 f4 3d c4 b8  |\4.^d6.]..3t.=..|
+00000430  4d ac d0 49 4e 59 1c 16  74 8c 43 94 4b 13 b9 22  |M..INY..t.C.K.."|
+00000440  de d7 ee 30 09 63 f3 32  5f a2 9d a1 20 ea ee 91  |...0.c.2_... ...|
+00000450  ca d8 01 33 df 43 19 69  63 ee 6a 2c 80 99 ad f0  |...3.C.ic.j,....|
+00000460  5e 20 b6 b6 81 28 b6 9d  4a 9a 91 30 30 04 c1 70  |^ ...(..J..00..p|
+00000470  68 54 1e e0 72 00 4c fd  23 a8 41 a2 6a ab a3 01  |hT..r.L.#.A.j...|
+00000480  7a 40 1a                                          |z@.|
+>>> Flow 3 (client to server)
+00000000  14 03 03 00 01 01 17 03  03 00 35 20 1f 0d 20 a8  |..........5 .. .|
+00000010  34 c4 dc fa f9 d6 2b fe  01 eb f1 54 f0 14 c2 2d  |4.....+....T...-|
+00000020  bb 59 db 04 96 f2 18 8b  bd 7e b0 38 b7 15 b5 d8  |.Y.......~.8....|
+00000030  6b f2 80 25 40 f6 97 67  fb 9e 5a 5c ad 33 c6 5f  |k..%@..g..Z\.3._|
+>>> Flow 4 (server to client)
+00000000  17 03 03 00 1e 3a 8a fc  60 3a 99 ee b6 01 b7 fe  |.....:..`:......|
+00000010  54 a9 2d 34 28 ae af 3b  6a bd e0 32 6b df 87 fe  |T.-4(..;j..2k...|
+00000020  d0 97 8d 17 03 03 00 13  c6 89 d5 ae 4c fa d5 71  |............L..q|
+00000030  66 6e 07 b5 9b 00 e8 50  7e b9 5f                 |fn.....P~._|
diff --git a/src/crypto/tls/tls.go b/src/crypto/tls/tls.go
index a389873..b529c70 100644
--- a/src/crypto/tls/tls.go
+++ b/src/crypto/tls/tls.go
@@ -25,7 +25,6 @@
 	"net"
 	"os"
 	"strings"
-	"time"
 )
 
 // Server returns a new TLS server side connection
@@ -111,33 +110,24 @@
 //
 // DialWithDialer interprets a nil configuration as equivalent to the zero
 // configuration; see the documentation of Config for the defaults.
+//
+// DialWithDialer uses context.Background internally; to specify the context,
+// use Dialer.DialContext with NetDialer set to the desired dialer.
 func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
 	return dial(context.Background(), dialer, network, addr, config)
 }
 
 func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
-	// We want the Timeout and Deadline values from dialer to cover the
-	// whole process: TCP connection and TLS handshake. This means that we
-	// also need to start our own timers now.
-	timeout := netDialer.Timeout
+	if netDialer.Timeout != 0 {
+		var cancel context.CancelFunc
+		ctx, cancel = context.WithTimeout(ctx, netDialer.Timeout)
+		defer cancel()
+	}
 
 	if !netDialer.Deadline.IsZero() {
-		deadlineTimeout := time.Until(netDialer.Deadline)
-		if timeout == 0 || deadlineTimeout < timeout {
-			timeout = deadlineTimeout
-		}
-	}
-
-	// hsErrCh is non-nil if we might not wait for Handshake to complete.
-	var hsErrCh chan error
-	if timeout != 0 || ctx.Done() != nil {
-		hsErrCh = make(chan error, 2)
-	}
-	if timeout != 0 {
-		timer := time.AfterFunc(timeout, func() {
-			hsErrCh <- timeoutError{}
-		})
-		defer timer.Stop()
+		var cancel context.CancelFunc
+		ctx, cancel = context.WithDeadline(ctx, netDialer.Deadline)
+		defer cancel()
 	}
 
 	rawConn, err := netDialer.DialContext(ctx, network, addr)
@@ -164,34 +154,10 @@
 	}
 
 	conn := Client(rawConn, config)
-
-	if hsErrCh == nil {
-		err = conn.Handshake()
-	} else {
-		go func() {
-			hsErrCh <- conn.Handshake()
-		}()
-
-		select {
-		case <-ctx.Done():
-			err = ctx.Err()
-		case err = <-hsErrCh:
-			if err != nil {
-				// If the error was due to the context
-				// closing, prefer the context's error, rather
-				// than some random network teardown error.
-				if e := ctx.Err(); e != nil {
-					err = e
-				}
-			}
-		}
-	}
-
-	if err != nil {
+	if err := conn.HandshakeContext(ctx); err != nil {
 		rawConn.Close()
 		return nil, err
 	}
-
 	return conn, nil
 }
 
@@ -224,6 +190,9 @@
 // handshake, returning the resulting TLS connection.
 //
 // The returned Conn, if any, will always be of type *Conn.
+//
+// Dial uses context.Background internally; to specify the context,
+// use DialContext.
 func (d *Dialer) Dial(network, addr string) (net.Conn, error) {
 	return d.DialContext(context.Background(), network, addr)
 }
diff --git a/src/crypto/tls/tls_test.go b/src/crypto/tls/tls_test.go
index 9995538..d8a43ad 100644
--- a/src/crypto/tls/tls_test.go
+++ b/src/crypto/tls/tls_test.go
@@ -18,6 +18,7 @@
 	"net"
 	"os"
 	"reflect"
+	"sort"
 	"strings"
 	"testing"
 	"time"
@@ -1383,7 +1384,7 @@
 		}
 	}
 
-	cipherSuiteByID := func(id uint16) *CipherSuite {
+	CipherSuiteByID := func(id uint16) *CipherSuite {
 		for _, c := range CipherSuites() {
 			if c.ID == id {
 				return c
@@ -1398,15 +1399,12 @@
 	}
 
 	for _, c := range cipherSuites {
-		cc := cipherSuiteByID(c.id)
+		cc := CipherSuiteByID(c.id)
 		if cc == nil {
 			t.Errorf("%#04x: no CipherSuite entry", c.id)
 			continue
 		}
 
-		if defaultOff := c.flags&suiteDefaultOff != 0; defaultOff != cc.Insecure {
-			t.Errorf("%#04x: Insecure %v, expected %v", c.id, cc.Insecure, defaultOff)
-		}
 		if tls12Only := c.flags&suiteTLS12 != 0; tls12Only && len(cc.SupportedVersions) != 1 {
 			t.Errorf("%#04x: suite is TLS 1.2 only, but SupportedVersions is %v", c.id, cc.SupportedVersions)
 		} else if !tls12Only && len(cc.SupportedVersions) != 3 {
@@ -1418,7 +1416,7 @@
 		}
 	}
 	for _, c := range cipherSuitesTLS13 {
-		cc := cipherSuiteByID(c.id)
+		cc := CipherSuiteByID(c.id)
 		if cc == nil {
 			t.Errorf("%#04x: no CipherSuite entry", c.id)
 			continue
@@ -1439,6 +1437,143 @@
 	if got := CipherSuiteName(0xabc); got != "0x0ABC" {
 		t.Errorf("unexpected fallback CipherSuiteName: got %q, expected 0x0ABC", got)
 	}
+
+	if len(cipherSuitesPreferenceOrder) != len(cipherSuites) {
+		t.Errorf("cipherSuitesPreferenceOrder is not the same size as cipherSuites")
+	}
+	if len(cipherSuitesPreferenceOrderNoAES) != len(cipherSuitesPreferenceOrder) {
+		t.Errorf("cipherSuitesPreferenceOrderNoAES is not the same size as cipherSuitesPreferenceOrder")
+	}
+
+	// Check that disabled suites are at the end of the preference lists, and
+	// that they are marked insecure.
+	for i, id := range disabledCipherSuites {
+		offset := len(cipherSuitesPreferenceOrder) - len(disabledCipherSuites)
+		if cipherSuitesPreferenceOrder[offset+i] != id {
+			t.Errorf("disabledCipherSuites[%d]: not at the end of cipherSuitesPreferenceOrder", i)
+		}
+		if cipherSuitesPreferenceOrderNoAES[offset+i] != id {
+			t.Errorf("disabledCipherSuites[%d]: not at the end of cipherSuitesPreferenceOrderNoAES", i)
+		}
+		c := CipherSuiteByID(id)
+		if c == nil {
+			t.Errorf("%#04x: no CipherSuite entry", id)
+			continue
+		}
+		if !c.Insecure {
+			t.Errorf("%#04x: disabled by default but not marked insecure", id)
+		}
+	}
+
+	for i, prefOrder := range [][]uint16{cipherSuitesPreferenceOrder, cipherSuitesPreferenceOrderNoAES} {
+		// Check that insecure and HTTP/2 bad cipher suites are at the end of
+		// the preference lists.
+		var sawInsecure, sawBad bool
+		for _, id := range prefOrder {
+			c := CipherSuiteByID(id)
+			if c == nil {
+				t.Errorf("%#04x: no CipherSuite entry", id)
+				continue
+			}
+
+			if c.Insecure {
+				sawInsecure = true
+			} else if sawInsecure {
+				t.Errorf("%#04x: secure suite after insecure one(s)", id)
+			}
+
+			if http2isBadCipher(id) {
+				sawBad = true
+			} else if sawBad {
+				t.Errorf("%#04x: non-bad suite after bad HTTP/2 one(s)", id)
+			}
+		}
+
+		// Check that the list is sorted according to the documented criteria.
+		isBetter := func(a, b int) bool {
+			aSuite, bSuite := cipherSuiteByID(prefOrder[a]), cipherSuiteByID(prefOrder[b])
+			aName, bName := CipherSuiteName(prefOrder[a]), CipherSuiteName(prefOrder[b])
+			// * < RC4
+			if !strings.Contains(aName, "RC4") && strings.Contains(bName, "RC4") {
+				return true
+			} else if strings.Contains(aName, "RC4") && !strings.Contains(bName, "RC4") {
+				return false
+			}
+			// * < CBC_SHA256
+			if !strings.Contains(aName, "CBC_SHA256") && strings.Contains(bName, "CBC_SHA256") {
+				return true
+			} else if strings.Contains(aName, "CBC_SHA256") && !strings.Contains(bName, "CBC_SHA256") {
+				return false
+			}
+			// * < 3DES
+			if !strings.Contains(aName, "3DES") && strings.Contains(bName, "3DES") {
+				return true
+			} else if strings.Contains(aName, "3DES") && !strings.Contains(bName, "3DES") {
+				return false
+			}
+			// ECDHE < *
+			if aSuite.flags&suiteECDHE != 0 && bSuite.flags&suiteECDHE == 0 {
+				return true
+			} else if aSuite.flags&suiteECDHE == 0 && bSuite.flags&suiteECDHE != 0 {
+				return false
+			}
+			// AEAD < CBC
+			if aSuite.aead != nil && bSuite.aead == nil {
+				return true
+			} else if aSuite.aead == nil && bSuite.aead != nil {
+				return false
+			}
+			// AES < ChaCha20
+			if strings.Contains(aName, "AES") && strings.Contains(bName, "CHACHA20") {
+				return i == 0 // true for cipherSuitesPreferenceOrder
+			} else if strings.Contains(aName, "CHACHA20") && strings.Contains(bName, "AES") {
+				return i != 0 // true for cipherSuitesPreferenceOrderNoAES
+			}
+			// AES-128 < AES-256
+			if strings.Contains(aName, "AES_128") && strings.Contains(bName, "AES_256") {
+				return true
+			} else if strings.Contains(aName, "AES_256") && strings.Contains(bName, "AES_128") {
+				return false
+			}
+			// ECDSA < RSA
+			if aSuite.flags&suiteECSign != 0 && bSuite.flags&suiteECSign == 0 {
+				return true
+			} else if aSuite.flags&suiteECSign == 0 && bSuite.flags&suiteECSign != 0 {
+				return false
+			}
+			t.Fatalf("two ciphersuites are equal by all criteria: %v and %v", aName, bName)
+			panic("unreachable")
+		}
+		if !sort.SliceIsSorted(prefOrder, isBetter) {
+			t.Error("preference order is not sorted according to the rules")
+		}
+	}
+}
+
+// http2isBadCipher is copied from net/http.
+// TODO: if it ends up exposed somewhere, use that instead.
+func http2isBadCipher(cipher uint16) bool {
+	switch cipher {
+	case TLS_RSA_WITH_RC4_128_SHA,
+		TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+		TLS_RSA_WITH_AES_128_CBC_SHA,
+		TLS_RSA_WITH_AES_256_CBC_SHA,
+		TLS_RSA_WITH_AES_128_CBC_SHA256,
+		TLS_RSA_WITH_AES_128_GCM_SHA256,
+		TLS_RSA_WITH_AES_256_GCM_SHA384,
+		TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+		TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+		TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+		TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+		TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+		TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+		TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+		TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+		TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+		return true
+	default:
+		return false
+	}
 }
 
 type brokenSigner struct{ crypto.Signer }
diff --git a/src/crypto/x509/internal/macos/corefoundation.go b/src/crypto/x509/internal/macos/corefoundation.go
index 9b776d4..fcfbc1e 100644
--- a/src/crypto/x509/internal/macos/corefoundation.go
+++ b/src/crypto/x509/internal/macos/corefoundation.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin && !ios
 // +build darwin,!ios
 
 // Package macOS provides cgo-less wrappers for Core Foundation and
@@ -11,6 +12,7 @@
 
 import (
 	"errors"
+	"internal/abi"
 	"reflect"
 	"runtime"
 	"unsafe"
@@ -39,24 +41,22 @@
 const kCFAllocatorDefault = 0
 const kCFStringEncodingUTF8 = 0x08000100
 
-//go:linkname x509_CFStringCreateWithBytes x509_CFStringCreateWithBytes
 //go:cgo_import_dynamic x509_CFStringCreateWithBytes CFStringCreateWithBytes "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
 
 // StringToCFString returns a copy of the UTF-8 contents of s as a new CFString.
 func StringToCFString(s string) CFString {
 	p := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&s)).Data)
-	ret := syscall(funcPC(x509_CFStringCreateWithBytes_trampoline), kCFAllocatorDefault, uintptr(p),
+	ret := syscall(abi.FuncPCABI0(x509_CFStringCreateWithBytes_trampoline), kCFAllocatorDefault, uintptr(p),
 		uintptr(len(s)), uintptr(kCFStringEncodingUTF8), 0 /* isExternalRepresentation */, 0)
 	runtime.KeepAlive(p)
 	return CFString(ret)
 }
 func x509_CFStringCreateWithBytes_trampoline()
 
-//go:linkname x509_CFDictionaryGetValueIfPresent x509_CFDictionaryGetValueIfPresent
 //go:cgo_import_dynamic x509_CFDictionaryGetValueIfPresent CFDictionaryGetValueIfPresent "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
 
 func CFDictionaryGetValueIfPresent(dict CFRef, key CFString) (value CFRef, ok bool) {
-	ret := syscall(funcPC(x509_CFDictionaryGetValueIfPresent_trampoline), uintptr(dict), uintptr(key),
+	ret := syscall(abi.FuncPCABI0(x509_CFDictionaryGetValueIfPresent_trampoline), uintptr(dict), uintptr(key),
 		uintptr(unsafe.Pointer(&value)), 0, 0, 0)
 	if ret == 0 {
 		return 0, false
@@ -67,12 +67,11 @@
 
 const kCFNumberSInt32Type = 3
 
-//go:linkname x509_CFNumberGetValue x509_CFNumberGetValue
 //go:cgo_import_dynamic x509_CFNumberGetValue CFNumberGetValue "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
 
 func CFNumberGetValue(num CFRef) (int32, error) {
 	var value int32
-	ret := syscall(funcPC(x509_CFNumberGetValue_trampoline), uintptr(num), uintptr(kCFNumberSInt32Type),
+	ret := syscall(abi.FuncPCABI0(x509_CFNumberGetValue_trampoline), uintptr(num), uintptr(kCFNumberSInt32Type),
 		uintptr(unsafe.Pointer(&value)), 0, 0, 0)
 	if ret == 0 {
 		return 0, errors.New("CFNumberGetValue call failed")
@@ -81,65 +80,52 @@
 }
 func x509_CFNumberGetValue_trampoline()
 
-//go:linkname x509_CFDataGetLength x509_CFDataGetLength
 //go:cgo_import_dynamic x509_CFDataGetLength CFDataGetLength "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
 
 func CFDataGetLength(data CFRef) int {
-	ret := syscall(funcPC(x509_CFDataGetLength_trampoline), uintptr(data), 0, 0, 0, 0, 0)
+	ret := syscall(abi.FuncPCABI0(x509_CFDataGetLength_trampoline), uintptr(data), 0, 0, 0, 0, 0)
 	return int(ret)
 }
 func x509_CFDataGetLength_trampoline()
 
-//go:linkname x509_CFDataGetBytePtr x509_CFDataGetBytePtr
 //go:cgo_import_dynamic x509_CFDataGetBytePtr CFDataGetBytePtr "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
 
 func CFDataGetBytePtr(data CFRef) uintptr {
-	ret := syscall(funcPC(x509_CFDataGetBytePtr_trampoline), uintptr(data), 0, 0, 0, 0, 0)
+	ret := syscall(abi.FuncPCABI0(x509_CFDataGetBytePtr_trampoline), uintptr(data), 0, 0, 0, 0, 0)
 	return ret
 }
 func x509_CFDataGetBytePtr_trampoline()
 
-//go:linkname x509_CFArrayGetCount x509_CFArrayGetCount
 //go:cgo_import_dynamic x509_CFArrayGetCount CFArrayGetCount "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
 
 func CFArrayGetCount(array CFRef) int {
-	ret := syscall(funcPC(x509_CFArrayGetCount_trampoline), uintptr(array), 0, 0, 0, 0, 0)
+	ret := syscall(abi.FuncPCABI0(x509_CFArrayGetCount_trampoline), uintptr(array), 0, 0, 0, 0, 0)
 	return int(ret)
 }
 func x509_CFArrayGetCount_trampoline()
 
-//go:linkname x509_CFArrayGetValueAtIndex x509_CFArrayGetValueAtIndex
 //go:cgo_import_dynamic x509_CFArrayGetValueAtIndex CFArrayGetValueAtIndex "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
 
 func CFArrayGetValueAtIndex(array CFRef, index int) CFRef {
-	ret := syscall(funcPC(x509_CFArrayGetValueAtIndex_trampoline), uintptr(array), uintptr(index), 0, 0, 0, 0)
+	ret := syscall(abi.FuncPCABI0(x509_CFArrayGetValueAtIndex_trampoline), uintptr(array), uintptr(index), 0, 0, 0, 0)
 	return CFRef(ret)
 }
 func x509_CFArrayGetValueAtIndex_trampoline()
 
-//go:linkname x509_CFEqual x509_CFEqual
 //go:cgo_import_dynamic x509_CFEqual CFEqual "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
 
 func CFEqual(a, b CFRef) bool {
-	ret := syscall(funcPC(x509_CFEqual_trampoline), uintptr(a), uintptr(b), 0, 0, 0, 0)
+	ret := syscall(abi.FuncPCABI0(x509_CFEqual_trampoline), uintptr(a), uintptr(b), 0, 0, 0, 0)
 	return ret == 1
 }
 func x509_CFEqual_trampoline()
 
-//go:linkname x509_CFRelease x509_CFRelease
 //go:cgo_import_dynamic x509_CFRelease CFRelease "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
 
 func CFRelease(ref CFRef) {
-	syscall(funcPC(x509_CFRelease_trampoline), uintptr(ref), 0, 0, 0, 0, 0)
+	syscall(abi.FuncPCABI0(x509_CFRelease_trampoline), uintptr(ref), 0, 0, 0, 0, 0)
 }
 func x509_CFRelease_trampoline()
 
 // syscall is implemented in the runtime package (runtime/sys_darwin.go)
 func syscall(fn, a1, a2, a3, a4, a5, a6 uintptr) uintptr
-
-// funcPC returns the entry point for f. See comments in runtime/proc.go
-// for the function of the same name.
-//go:nosplit
-func funcPC(f func()) uintptr {
-	return **(**uintptr)(unsafe.Pointer(&f))
-}
diff --git a/src/crypto/x509/internal/macos/corefoundation.s b/src/crypto/x509/internal/macos/corefoundation.s
index a4495d6..cda2336 100644
--- a/src/crypto/x509/internal/macos/corefoundation.s
+++ b/src/crypto/x509/internal/macos/corefoundation.s
@@ -2,10 +2,14 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin && !ios
 // +build darwin,!ios
 
 #include "textflag.h"
 
+// The trampolines are ABIInternal as they are address-taken in
+// Go code.
+
 TEXT ·x509_CFArrayGetCount_trampoline(SB),NOSPLIT,$0-0
 	JMP	x509_CFArrayGetCount(SB)
 TEXT ·x509_CFArrayGetValueAtIndex_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/crypto/x509/internal/macos/security.go b/src/crypto/x509/internal/macos/security.go
index 5e39e93..0f6fa42 100644
--- a/src/crypto/x509/internal/macos/security.go
+++ b/src/crypto/x509/internal/macos/security.go
@@ -2,12 +2,14 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin && !ios
 // +build darwin,!ios
 
 package macOS
 
 import (
 	"errors"
+	"internal/abi"
 	"strconv"
 	"unsafe"
 )
@@ -63,11 +65,10 @@
 
 const errSecNoTrustSettings = -25263
 
-//go:linkname x509_SecTrustSettingsCopyCertificates x509_SecTrustSettingsCopyCertificates
 //go:cgo_import_dynamic x509_SecTrustSettingsCopyCertificates SecTrustSettingsCopyCertificates "/System/Library/Frameworks/Security.framework/Versions/A/Security"
 
 func SecTrustSettingsCopyCertificates(domain SecTrustSettingsDomain) (certArray CFRef, err error) {
-	ret := syscall(funcPC(x509_SecTrustSettingsCopyCertificates_trampoline), uintptr(domain),
+	ret := syscall(abi.FuncPCABI0(x509_SecTrustSettingsCopyCertificates_trampoline), uintptr(domain),
 		uintptr(unsafe.Pointer(&certArray)), 0, 0, 0, 0)
 	if int32(ret) == errSecNoTrustSettings {
 		return 0, ErrNoTrustSettings
@@ -80,11 +81,10 @@
 
 const kSecFormatX509Cert int32 = 9
 
-//go:linkname x509_SecItemExport x509_SecItemExport
 //go:cgo_import_dynamic x509_SecItemExport SecItemExport "/System/Library/Frameworks/Security.framework/Versions/A/Security"
 
 func SecItemExport(cert CFRef) (data CFRef, err error) {
-	ret := syscall(funcPC(x509_SecItemExport_trampoline), uintptr(cert), uintptr(kSecFormatX509Cert),
+	ret := syscall(abi.FuncPCABI0(x509_SecItemExport_trampoline), uintptr(cert), uintptr(kSecFormatX509Cert),
 		0 /* flags */, 0 /* keyParams */, uintptr(unsafe.Pointer(&data)), 0)
 	if ret != 0 {
 		return 0, OSStatus{"SecItemExport", int32(ret)}
@@ -95,11 +95,10 @@
 
 const errSecItemNotFound = -25300
 
-//go:linkname x509_SecTrustSettingsCopyTrustSettings x509_SecTrustSettingsCopyTrustSettings
 //go:cgo_import_dynamic x509_SecTrustSettingsCopyTrustSettings SecTrustSettingsCopyTrustSettings "/System/Library/Frameworks/Security.framework/Versions/A/Security"
 
 func SecTrustSettingsCopyTrustSettings(cert CFRef, domain SecTrustSettingsDomain) (trustSettings CFRef, err error) {
-	ret := syscall(funcPC(x509_SecTrustSettingsCopyTrustSettings_trampoline), uintptr(cert), uintptr(domain),
+	ret := syscall(abi.FuncPCABI0(x509_SecTrustSettingsCopyTrustSettings_trampoline), uintptr(cert), uintptr(domain),
 		uintptr(unsafe.Pointer(&trustSettings)), 0, 0, 0)
 	if int32(ret) == errSecItemNotFound {
 		return 0, ErrNoTrustSettings
@@ -110,11 +109,10 @@
 }
 func x509_SecTrustSettingsCopyTrustSettings_trampoline()
 
-//go:linkname x509_SecPolicyCopyProperties x509_SecPolicyCopyProperties
 //go:cgo_import_dynamic x509_SecPolicyCopyProperties SecPolicyCopyProperties "/System/Library/Frameworks/Security.framework/Versions/A/Security"
 
 func SecPolicyCopyProperties(policy CFRef) CFRef {
-	ret := syscall(funcPC(x509_SecPolicyCopyProperties_trampoline), uintptr(policy), 0, 0, 0, 0, 0)
+	ret := syscall(abi.FuncPCABI0(x509_SecPolicyCopyProperties_trampoline), uintptr(policy), 0, 0, 0, 0, 0)
 	return CFRef(ret)
 }
 func x509_SecPolicyCopyProperties_trampoline()
diff --git a/src/crypto/x509/internal/macos/security.s b/src/crypto/x509/internal/macos/security.s
index bd446db..0038f25 100644
--- a/src/crypto/x509/internal/macos/security.s
+++ b/src/crypto/x509/internal/macos/security.s
@@ -2,10 +2,14 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin && !ios
 // +build darwin,!ios
 
 #include "textflag.h"
 
+// The trampolines are ABIInternal as they are address-taken in
+// Go code.
+
 TEXT ·x509_SecTrustSettingsCopyCertificates_trampoline(SB),NOSPLIT,$0-0
 	JMP	x509_SecTrustSettingsCopyCertificates(SB)
 TEXT ·x509_SecItemExport_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/crypto/x509/name_constraints_test.go b/src/crypto/x509/name_constraints_test.go
index 3826c82..c59a7dc 100644
--- a/src/crypto/x509/name_constraints_test.go
+++ b/src/crypto/x509/name_constraints_test.go
@@ -614,7 +614,8 @@
 		},
 	},
 
-	// #30: without SANs, a certificate with a CN is rejected in a constrained chain.
+	// #30: without SANs, a certificate with a CN is still accepted in a
+	// constrained chain, since we ignore the CN in VerifyHostname.
 	{
 		roots: []constraintsSpec{
 			{
@@ -630,7 +631,6 @@
 			sans: []string{},
 			cn:   "foo.com",
 		},
-		expectedError: "leaf doesn't have a SAN extension",
 	},
 
 	// #31: IPv6 addresses work in constraints: roots can permit them as
@@ -1595,26 +1595,6 @@
 			cn:   "foo.bar",
 		},
 	},
-
-	// #85: without SANs, a certificate with a valid CN is accepted in a
-	// constrained chain if x509ignoreCN is set.
-	{
-		roots: []constraintsSpec{
-			{
-				ok: []string{"dns:foo.com", "dns:.foo.com"},
-			},
-		},
-		intermediates: [][]constraintsSpec{
-			{
-				{},
-			},
-		},
-		leaf: leafSpec{
-			sans: []string{},
-			cn:   "foo.com",
-		},
-		ignoreCN: true,
-	},
 }
 
 func makeConstraintsCACert(constraints constraintsSpec, name string, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) {
@@ -1865,10 +1845,6 @@
 }
 
 func TestConstraintCases(t *testing.T) {
-	defer func(savedIgnoreCN bool) {
-		ignoreCN = savedIgnoreCN
-	}(ignoreCN)
-
 	privateKeys := sync.Pool{
 		New: func() interface{} {
 			priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
@@ -1960,7 +1936,6 @@
 			}
 		}
 
-		ignoreCN = test.ignoreCN
 		verifyOpts := VerifyOptions{
 			Roots:         rootPool,
 			Intermediates: intermediatePool,
@@ -1999,7 +1974,6 @@
 		for _, key := range keys {
 			privateKeys.Put(key)
 		}
-		keys = keys[:0]
 	}
 }
 
diff --git a/src/crypto/x509/parser.go b/src/crypto/x509/parser.go
new file mode 100644
index 0000000..f085162
--- /dev/null
+++ b/src/crypto/x509/parser.go
@@ -0,0 +1,1006 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+package x509
+
+import (
+	"bytes"
+	"crypto/dsa"
+	"crypto/ecdsa"
+	"crypto/ed25519"
+	"crypto/elliptic"
+	"crypto/rsa"
+	"crypto/x509/pkix"
+	"encoding/asn1"
+	"errors"
+	"fmt"
+	"math/big"
+	"net"
+	"net/url"
+	"strconv"
+	"strings"
+	"time"
+	"unicode/utf16"
+	"unicode/utf8"
+
+	"golang.org/x/crypto/cryptobyte"
+	cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
+)
+
+// isPrintable reports whether the given b is in the ASN.1 PrintableString set.
+// This is a simplified version of encoding/asn1.isPrintable.
+func isPrintable(b byte) bool {
+	return 'a' <= b && b <= 'z' ||
+		'A' <= b && b <= 'Z' ||
+		'0' <= b && b <= '9' ||
+		'\'' <= b && b <= ')' ||
+		'+' <= b && b <= '/' ||
+		b == ' ' ||
+		b == ':' ||
+		b == '=' ||
+		b == '?' ||
+		// This is technically not allowed in a PrintableString.
+		// However, x509 certificates with wildcard strings don't
+		// always use the correct string type so we permit it.
+		b == '*' ||
+		// 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.
+		b == '&'
+}
+
+// parseASN1String parses the ASN.1 string types T61String, PrintableString,
+// UTF8String, BMPString, and IA5String. This is mostly copied from the
+// respective encoding/asn1.parse... methods, rather than just increasing
+// the API surface of that package.
+func parseASN1String(tag cryptobyte_asn1.Tag, value []byte) (string, error) {
+	switch tag {
+	case cryptobyte_asn1.T61String:
+		return string(value), nil
+	case cryptobyte_asn1.PrintableString:
+		for _, b := range value {
+			if !isPrintable(b) {
+				return "", errors.New("invalid PrintableString")
+			}
+		}
+		return string(value), nil
+	case cryptobyte_asn1.UTF8String:
+		if !utf8.Valid(value) {
+			return "", errors.New("invalid UTF-8 string")
+		}
+		return string(value), nil
+	case cryptobyte_asn1.Tag(asn1.TagBMPString):
+		if len(value)%2 != 0 {
+			return "", errors.New("invalid BMPString")
+		}
+
+		// Strip terminator if present.
+		if l := len(value); l >= 2 && value[l-1] == 0 && value[l-2] == 0 {
+			value = value[:l-2]
+		}
+
+		s := make([]uint16, 0, len(value)/2)
+		for len(value) > 0 {
+			s = append(s, uint16(value[0])<<8+uint16(value[1]))
+			value = value[2:]
+		}
+
+		return string(utf16.Decode(s)), nil
+	case cryptobyte_asn1.IA5String:
+		s := string(value)
+		if isIA5String(s) != nil {
+			return "", errors.New("invalid IA5String")
+		}
+		return s, nil
+	}
+	return "", fmt.Errorf("unsupported string type: %v", tag)
+}
+
+// parseName parses a DER encoded Name as defined in RFC 5280. We may
+// want to export this function in the future for use in crypto/tls.
+func parseName(raw cryptobyte.String) (*pkix.RDNSequence, error) {
+	if !raw.ReadASN1(&raw, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: invalid RDNSequence")
+	}
+
+	var rdnSeq pkix.RDNSequence
+	for !raw.Empty() {
+		var rdnSet pkix.RelativeDistinguishedNameSET
+		var set cryptobyte.String
+		if !raw.ReadASN1(&set, cryptobyte_asn1.SET) {
+			return nil, errors.New("x509: invalid RDNSequence")
+		}
+		for !set.Empty() {
+			var atav cryptobyte.String
+			if !set.ReadASN1(&atav, cryptobyte_asn1.SEQUENCE) {
+				return nil, errors.New("x509: invalid RDNSequence: invalid attribute")
+			}
+			var attr pkix.AttributeTypeAndValue
+			if !atav.ReadASN1ObjectIdentifier(&attr.Type) {
+				return nil, errors.New("x509: invalid RDNSequence: invalid attribute type")
+			}
+			var rawValue cryptobyte.String
+			var valueTag cryptobyte_asn1.Tag
+			if !atav.ReadAnyASN1(&rawValue, &valueTag) {
+				return nil, errors.New("x509: invalid RDNSequence: invalid attribute value")
+			}
+			var err error
+			attr.Value, err = parseASN1String(valueTag, rawValue)
+			if err != nil {
+				return nil, fmt.Errorf("x509: invalid RDNSequence: invalid attribute value: %s", err)
+			}
+			rdnSet = append(rdnSet, attr)
+		}
+
+		rdnSeq = append(rdnSeq, rdnSet)
+	}
+
+	return &rdnSeq, nil
+}
+
+func parseAI(der cryptobyte.String) (pkix.AlgorithmIdentifier, error) {
+	ai := pkix.AlgorithmIdentifier{}
+	if !der.ReadASN1ObjectIdentifier(&ai.Algorithm) {
+		return ai, errors.New("x509: malformed OID")
+	}
+	if der.Empty() {
+		return ai, nil
+	}
+	var params cryptobyte.String
+	var tag cryptobyte_asn1.Tag
+	if !der.ReadAnyASN1Element(&params, &tag) {
+		return ai, errors.New("x509: malformed parameters")
+	}
+	ai.Parameters.Tag = int(tag)
+	ai.Parameters.FullBytes = params
+	return ai, nil
+}
+
+func parseValidity(der cryptobyte.String) (time.Time, time.Time, error) {
+	extract := func() (time.Time, error) {
+		var t time.Time
+		switch {
+		case der.PeekASN1Tag(cryptobyte_asn1.UTCTime):
+			// TODO(rolandshoemaker): once #45411 is fixed, the following code
+			// should be replaced with a call to der.ReadASN1UTCTime.
+			var utc cryptobyte.String
+			if !der.ReadASN1(&utc, cryptobyte_asn1.UTCTime) {
+				return t, errors.New("x509: malformed UTCTime")
+			}
+			s := string(utc)
+
+			formatStr := "0601021504Z0700"
+			var err error
+			t, err = time.Parse(formatStr, s)
+			if err != nil {
+				formatStr = "060102150405Z0700"
+				t, err = time.Parse(formatStr, s)
+			}
+			if err != nil {
+				return t, err
+			}
+
+			if serialized := t.Format(formatStr); serialized != s {
+				return t, errors.New("x509: malformed UTCTime")
+			}
+
+			if t.Year() >= 2050 {
+				// UTCTime only encodes times prior to 2050. See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+				t = t.AddDate(-100, 0, 0)
+			}
+		case der.PeekASN1Tag(cryptobyte_asn1.GeneralizedTime):
+			if !der.ReadASN1GeneralizedTime(&t) {
+				return t, errors.New("x509: malformed GeneralizedTime")
+			}
+		default:
+			return t, errors.New("x509: unsupported time format")
+		}
+		return t, nil
+	}
+
+	notBefore, err := extract()
+	if err != nil {
+		return time.Time{}, time.Time{}, err
+	}
+	notAfter, err := extract()
+	if err != nil {
+		return time.Time{}, time.Time{}, err
+	}
+
+	return notBefore, notAfter, nil
+}
+
+func parseExtension(der cryptobyte.String) (pkix.Extension, error) {
+	var ext pkix.Extension
+	if !der.ReadASN1ObjectIdentifier(&ext.Id) {
+		return ext, errors.New("x509: malformed extention OID field")
+	}
+	if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
+		if !der.ReadASN1Boolean(&ext.Critical) {
+			return ext, errors.New("x509: malformed extention critical field")
+		}
+	}
+	var val cryptobyte.String
+	if !der.ReadASN1(&val, cryptobyte_asn1.OCTET_STRING) {
+		return ext, errors.New("x509: malformed extention value field")
+	}
+	ext.Value = val
+	return ext, nil
+}
+
+func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) {
+	der := cryptobyte.String(keyData.PublicKey.RightAlign())
+	switch algo {
+	case RSA:
+		// RSA public keys must have a NULL in the parameters.
+		// See RFC 3279, Section 2.3.1.
+		if !bytes.Equal(keyData.Algorithm.Parameters.FullBytes, asn1.NullBytes) {
+			return nil, errors.New("x509: RSA key missing NULL parameters")
+		}
+
+		p := &pkcs1PublicKey{N: new(big.Int)}
+		if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+			return nil, errors.New("x509: invalid RSA public key")
+		}
+		if !der.ReadASN1Integer(p.N) {
+			return nil, errors.New("x509: invalid RSA modulus")
+		}
+		if !der.ReadASN1Integer(&p.E) {
+			return nil, errors.New("x509: invalid RSA public exponent")
+		}
+
+		if p.N.Sign() <= 0 {
+			return nil, errors.New("x509: RSA modulus is not a positive number")
+		}
+		if p.E <= 0 {
+			return nil, errors.New("x509: RSA public exponent is not a positive number")
+		}
+
+		pub := &rsa.PublicKey{
+			E: p.E,
+			N: p.N,
+		}
+		return pub, nil
+	case ECDSA:
+		paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes)
+		namedCurveOID := new(asn1.ObjectIdentifier)
+		if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {
+			return nil, errors.New("x509: invalid ECDSA parameters")
+		}
+		namedCurve := namedCurveFromOID(*namedCurveOID)
+		if namedCurve == nil {
+			return nil, errors.New("x509: unsupported elliptic curve")
+		}
+		x, y := elliptic.Unmarshal(namedCurve, der)
+		if x == nil {
+			return nil, errors.New("x509: failed to unmarshal elliptic curve point")
+		}
+		pub := &ecdsa.PublicKey{
+			Curve: namedCurve,
+			X:     x,
+			Y:     y,
+		}
+		return pub, nil
+	case Ed25519:
+		// RFC 8410, Section 3
+		// > For all of the OIDs, the parameters MUST be absent.
+		if len(keyData.Algorithm.Parameters.FullBytes) != 0 {
+			return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")
+		}
+		if len(der) != ed25519.PublicKeySize {
+			return nil, errors.New("x509: wrong Ed25519 public key size")
+		}
+		return ed25519.PublicKey(der), nil
+	case DSA:
+		y := new(big.Int)
+		if !der.ReadASN1Integer(y) {
+			return nil, errors.New("x509: invalid DSA public key")
+		}
+		pub := &dsa.PublicKey{
+			Y: y,
+			Parameters: dsa.Parameters{
+				P: new(big.Int),
+				Q: new(big.Int),
+				G: new(big.Int),
+			},
+		}
+		paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes)
+		if !paramsDer.ReadASN1(&paramsDer, cryptobyte_asn1.SEQUENCE) ||
+			!paramsDer.ReadASN1Integer(pub.Parameters.P) ||
+			!paramsDer.ReadASN1Integer(pub.Parameters.Q) ||
+			!paramsDer.ReadASN1Integer(pub.Parameters.G) {
+			return nil, errors.New("x509: invalid DSA parameters")
+		}
+		if pub.Y.Sign() <= 0 || pub.Parameters.P.Sign() <= 0 ||
+			pub.Parameters.Q.Sign() <= 0 || pub.Parameters.G.Sign() <= 0 {
+			return nil, errors.New("x509: zero or negative DSA parameter")
+		}
+		return pub, nil
+	default:
+		return nil, nil
+	}
+}
+
+func parseKeyUsageExtension(der cryptobyte.String) (KeyUsage, error) {
+	var usageBits asn1.BitString
+	if !der.ReadASN1BitString(&usageBits) {
+		return 0, errors.New("x509: invalid key usage")
+	}
+
+	var usage int
+	for i := 0; i < 9; i++ {
+		if usageBits.At(i) != 0 {
+			usage |= 1 << uint(i)
+		}
+	}
+	return KeyUsage(usage), nil
+}
+
+func parseBasicConstraintsExtension(der cryptobyte.String) (bool, int, error) {
+	var isCA bool
+	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+		return false, 0, errors.New("x509: invalid basic constraints a")
+	}
+	if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
+		if !der.ReadASN1Boolean(&isCA) {
+			return false, 0, errors.New("x509: invalid basic constraints b")
+		}
+	}
+	maxPathLen := -1
+	if !der.Empty() && der.PeekASN1Tag(cryptobyte_asn1.INTEGER) {
+		if !der.ReadASN1Integer(&maxPathLen) {
+			return false, 0, errors.New("x509: invalid basic constraints c")
+		}
+	}
+
+	// TODO: map out.MaxPathLen to 0 if it has the -1 default value? (Issue 19285)
+	return isCA, maxPathLen, nil
+}
+
+func forEachSAN(der cryptobyte.String, callback func(tag int, data []byte) error) error {
+	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+		return errors.New("x509: invalid subject alternative names")
+	}
+	for !der.Empty() {
+		var san cryptobyte.String
+		var tag cryptobyte_asn1.Tag
+		if !der.ReadAnyASN1(&san, &tag) {
+			return errors.New("x509: invalid subject alternative name")
+		}
+		if err := callback(int(tag^0x80), san); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func parseSANExtension(der cryptobyte.String) (dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL, err error) {
+	err = forEachSAN(der, func(tag int, data []byte) error {
+		switch tag {
+		case nameTypeEmail:
+			email := string(data)
+			if err := isIA5String(email); err != nil {
+				return errors.New("x509: SAN rfc822Name is malformed")
+			}
+			emailAddresses = append(emailAddresses, email)
+		case nameTypeDNS:
+			name := string(data)
+			if err := isIA5String(name); err != nil {
+				return errors.New("x509: SAN dNSName is malformed")
+			}
+			dnsNames = append(dnsNames, string(name))
+		case nameTypeURI:
+			uriStr := string(data)
+			if err := isIA5String(uriStr); err != nil {
+				return errors.New("x509: SAN uniformResourceIdentifier is malformed")
+			}
+			uri, err := url.Parse(uriStr)
+			if err != nil {
+				return fmt.Errorf("x509: cannot parse URI %q: %s", uriStr, err)
+			}
+			if len(uri.Host) > 0 {
+				if _, ok := domainToReverseLabels(uri.Host); !ok {
+					return fmt.Errorf("x509: cannot parse URI %q: invalid domain", uriStr)
+				}
+			}
+			uris = append(uris, uri)
+		case nameTypeIP:
+			switch len(data) {
+			case net.IPv4len, net.IPv6len:
+				ipAddresses = append(ipAddresses, data)
+			default:
+				return errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len(data)))
+			}
+		}
+
+		return nil
+	})
+
+	return
+}
+
+func parseExtKeyUsageExtension(der cryptobyte.String) ([]ExtKeyUsage, []asn1.ObjectIdentifier, error) {
+	var extKeyUsages []ExtKeyUsage
+	var unknownUsages []asn1.ObjectIdentifier
+	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+		return nil, nil, errors.New("x509: invalid extended key usages")
+	}
+	for !der.Empty() {
+		var eku asn1.ObjectIdentifier
+		if !der.ReadASN1ObjectIdentifier(&eku) {
+			return nil, nil, errors.New("x509: invalid extended key usages")
+		}
+		if extKeyUsage, ok := extKeyUsageFromOID(eku); ok {
+			extKeyUsages = append(extKeyUsages, extKeyUsage)
+		} else {
+			unknownUsages = append(unknownUsages, eku)
+		}
+	}
+	return extKeyUsages, unknownUsages, nil
+}
+
+func parseCertificatePoliciesExtension(der cryptobyte.String) ([]asn1.ObjectIdentifier, error) {
+	var oids []asn1.ObjectIdentifier
+	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: invalid certificate policies")
+	}
+	for !der.Empty() {
+		var cp cryptobyte.String
+		if !der.ReadASN1(&cp, cryptobyte_asn1.SEQUENCE) {
+			return nil, errors.New("x509: invalid certificate policies")
+		}
+		var oid asn1.ObjectIdentifier
+		if !cp.ReadASN1ObjectIdentifier(&oid) {
+			return nil, errors.New("x509: invalid certificate policies")
+		}
+		oids = append(oids, oid)
+	}
+
+	return oids, nil
+}
+
+// isValidIPMask reports whether 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 {
+		// From RFC 5280, 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 processExtensions(out *Certificate) error {
+	var err error
+	for _, e := range out.Extensions {
+		unhandled := false
+
+		if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 {
+			switch e.Id[3] {
+			case 15:
+				out.KeyUsage, err = parseKeyUsageExtension(e.Value)
+				if err != nil {
+					return err
+				}
+			case 19:
+				out.IsCA, out.MaxPathLen, err = parseBasicConstraintsExtension(e.Value)
+				if err != nil {
+					return err
+				}
+				out.BasicConstraintsValid = true
+				out.MaxPathLenZero = out.MaxPathLen == 0
+			case 17:
+				out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(e.Value)
+				if err != nil {
+					return err
+				}
+
+				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:
+				unhandled, err = parseNameConstraintsExtension(out, e)
+				if err != nil {
+					return err
+				}
+
+			case 31:
+				// RFC 5280, 4.2.1.13
+
+				// CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+				//
+				// DistributionPoint ::= SEQUENCE {
+				//     distributionPoint       [0]     DistributionPointName OPTIONAL,
+				//     reasons                 [1]     ReasonFlags OPTIONAL,
+				//     cRLIssuer               [2]     GeneralNames OPTIONAL }
+				//
+				// DistributionPointName ::= CHOICE {
+				//     fullName                [0]     GeneralNames,
+				//     nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
+				val := cryptobyte.String(e.Value)
+				if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {
+					return errors.New("x509: invalid CRL distribution points")
+				}
+				for !val.Empty() {
+					var dpDER cryptobyte.String
+					if !val.ReadASN1(&dpDER, cryptobyte_asn1.SEQUENCE) {
+						return errors.New("x509: invalid CRL distribution point")
+					}
+					var dpNameDER cryptobyte.String
+					var dpNamePresent bool
+					if !dpDER.ReadOptionalASN1(&dpNameDER, &dpNamePresent, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
+						return errors.New("x509: invalid CRL distribution point")
+					}
+					if !dpNamePresent {
+						continue
+					}
+					if !dpNameDER.ReadASN1(&dpNameDER, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
+						return errors.New("x509: invalid CRL distribution point")
+					}
+					for !dpNameDER.Empty() {
+						if !dpNameDER.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {
+							break
+						}
+						var uri cryptobyte.String
+						if !dpNameDER.ReadASN1(&uri, cryptobyte_asn1.Tag(6).ContextSpecific()) {
+							return errors.New("x509: invalid CRL distribution point")
+						}
+						out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(uri))
+					}
+				}
+
+			case 35:
+				// RFC 5280, 4.2.1.1
+				val := cryptobyte.String(e.Value)
+				var akid cryptobyte.String
+				if !val.ReadASN1(&akid, cryptobyte_asn1.SEQUENCE) {
+					return errors.New("x509: invalid authority key identifier")
+				}
+				if akid.PeekASN1Tag(cryptobyte_asn1.Tag(0).ContextSpecific()) {
+					if !akid.ReadASN1(&akid, cryptobyte_asn1.Tag(0).ContextSpecific()) {
+						return errors.New("x509: invalid authority key identifier")
+					}
+					out.AuthorityKeyId = akid
+				}
+			case 37:
+				out.ExtKeyUsage, out.UnknownExtKeyUsage, err = parseExtKeyUsageExtension(e.Value)
+				if err != nil {
+					return err
+				}
+			case 14:
+				// RFC 5280, 4.2.1.2
+				val := cryptobyte.String(e.Value)
+				var skid cryptobyte.String
+				if !val.ReadASN1(&skid, cryptobyte_asn1.OCTET_STRING) {
+					return errors.New("x509: invalid subject key identifier")
+				}
+				out.SubjectKeyId = skid
+			case 32:
+				out.PolicyIdentifiers, err = parseCertificatePoliciesExtension(e.Value)
+				if err != nil {
+					return err
+				}
+			default:
+				// Unknown extensions are recorded if critical.
+				unhandled = true
+			}
+		} else if e.Id.Equal(oidExtensionAuthorityInfoAccess) {
+			// RFC 5280 4.2.2.1: Authority Information Access
+			val := cryptobyte.String(e.Value)
+			if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {
+				return errors.New("x509: invalid authority info access")
+			}
+			for !val.Empty() {
+				var aiaDER cryptobyte.String
+				if !val.ReadASN1(&aiaDER, cryptobyte_asn1.SEQUENCE) {
+					return errors.New("x509: invalid authority info access")
+				}
+				var method asn1.ObjectIdentifier
+				if !aiaDER.ReadASN1ObjectIdentifier(&method) {
+					return errors.New("x509: invalid authority info access")
+				}
+				if !aiaDER.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {
+					continue
+				}
+				if !aiaDER.ReadASN1(&aiaDER, cryptobyte_asn1.Tag(6).ContextSpecific()) {
+					return errors.New("x509: invalid authority info access")
+				}
+				switch {
+				case method.Equal(oidAuthorityInfoAccessOcsp):
+					out.OCSPServer = append(out.OCSPServer, string(aiaDER))
+				case method.Equal(oidAuthorityInfoAccessIssuers):
+					out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(aiaDER))
+				}
+			}
+		} else {
+			// Unknown extensions are recorded if critical.
+			unhandled = true
+		}
+
+		if e.Critical && unhandled {
+			out.UnhandledCriticalExtensions = append(out.UnhandledCriticalExtensions, e.Id)
+		}
+	}
+
+	return nil
+}
+
+func parseCertificate(der []byte) (*Certificate, error) {
+	cert := &Certificate{}
+
+	input := cryptobyte.String(der)
+	// we read the SEQUENCE including length and tag bytes so that
+	// we can populate Certificate.Raw, before unwrapping the
+	// SEQUENCE so it can be operated on
+	if !input.ReadASN1Element(&input, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed certificate")
+	}
+	cert.Raw = input
+	if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed certificate")
+	}
+
+	var tbs cryptobyte.String
+	// do the same trick again as above to extract the raw
+	// bytes for Certificate.RawTBSCertificate
+	if !input.ReadASN1Element(&tbs, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed tbs certificate")
+	}
+	cert.RawTBSCertificate = tbs
+	if !tbs.ReadASN1(&tbs, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed tbs certificate")
+	}
+
+	if !tbs.ReadOptionalASN1Integer(&cert.Version, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific(), 0) {
+		return nil, errors.New("x509: malformed version")
+	}
+	if cert.Version < 0 {
+		return nil, errors.New("x509: malformed version")
+	}
+	// for backwards compat reasons Version is one-indexed,
+	// rather than zero-indexed as defined in 5280
+	cert.Version++
+	if cert.Version > 3 {
+		return nil, errors.New("x509: invalid version")
+	}
+
+	serial := new(big.Int)
+	if !tbs.ReadASN1Integer(serial) {
+		return nil, errors.New("x509: malformed serial number")
+	}
+	// we ignore the presence of negative serial numbers because
+	// of their prevalence, despite them being invalid
+	// TODO(rolandshoemaker): revist this decision, there are currently
+	// only 10 trusted certificates with negative serial numbers
+	// according to censys.io.
+	cert.SerialNumber = serial
+
+	var sigAISeq cryptobyte.String
+	if !tbs.ReadASN1(&sigAISeq, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed signature algorithm identifier")
+	}
+	// Before parsing the inner algorithm identifier, extract
+	// the outer algorithm identifier and make sure that they
+	// match.
+	var outerSigAISeq cryptobyte.String
+	if !input.ReadASN1(&outerSigAISeq, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed algorithm identifier")
+	}
+	if !bytes.Equal(outerSigAISeq, sigAISeq) {
+		return nil, errors.New("x509: inner and outer signature algorithm identifiers don't match")
+	}
+	sigAI, err := parseAI(sigAISeq)
+	if err != nil {
+		return nil, err
+	}
+	cert.SignatureAlgorithm = getSignatureAlgorithmFromAI(sigAI)
+
+	var issuerSeq cryptobyte.String
+	if !tbs.ReadASN1Element(&issuerSeq, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed issuer")
+	}
+	cert.RawIssuer = issuerSeq
+	issuerRDNs, err := parseName(issuerSeq)
+	if err != nil {
+		return nil, err
+	}
+	cert.Issuer.FillFromRDNSequence(issuerRDNs)
+
+	var validity cryptobyte.String
+	if !tbs.ReadASN1(&validity, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed validity")
+	}
+	cert.NotBefore, cert.NotAfter, err = parseValidity(validity)
+	if err != nil {
+		return nil, err
+	}
+
+	var subjectSeq cryptobyte.String
+	if !tbs.ReadASN1Element(&subjectSeq, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed issuer")
+	}
+	cert.RawSubject = subjectSeq
+	subjectRDNs, err := parseName(subjectSeq)
+	if err != nil {
+		return nil, err
+	}
+	cert.Subject.FillFromRDNSequence(subjectRDNs)
+
+	var spki cryptobyte.String
+	if !tbs.ReadASN1Element(&spki, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed spki")
+	}
+	cert.RawSubjectPublicKeyInfo = spki
+	if !spki.ReadASN1(&spki, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed spki")
+	}
+	var pkAISeq cryptobyte.String
+	if !spki.ReadASN1(&pkAISeq, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed public key algorithm identifier")
+	}
+	pkAI, err := parseAI(pkAISeq)
+	if err != nil {
+		return nil, err
+	}
+	cert.PublicKeyAlgorithm = getPublicKeyAlgorithmFromOID(pkAI.Algorithm)
+	var spk asn1.BitString
+	if !spki.ReadASN1BitString(&spk) {
+		return nil, errors.New("x509: malformed subjectPublicKey")
+	}
+	cert.PublicKey, err = parsePublicKey(cert.PublicKeyAlgorithm, &publicKeyInfo{
+		Algorithm: pkAI,
+		PublicKey: spk,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	if cert.Version > 1 {
+		if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(1).Constructed().ContextSpecific()) {
+			return nil, errors.New("x509: malformed issuerUniqueID")
+		}
+		if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(2).Constructed().ContextSpecific()) {
+			return nil, errors.New("x509: malformed subjectUniqueID")
+		}
+		if cert.Version == 3 {
+			var extensions cryptobyte.String
+			var present bool
+			if !tbs.ReadOptionalASN1(&extensions, &present, cryptobyte_asn1.Tag(3).Constructed().ContextSpecific()) {
+				return nil, errors.New("x509: malformed extensions")
+			}
+			if present {
+				if !extensions.ReadASN1(&extensions, cryptobyte_asn1.SEQUENCE) {
+					return nil, errors.New("x509: malformed extensions")
+				}
+				for !extensions.Empty() {
+					var extension cryptobyte.String
+					if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) {
+						return nil, errors.New("x509: malformed extension")
+					}
+					ext, err := parseExtension(extension)
+					if err != nil {
+						return nil, err
+					}
+					cert.Extensions = append(cert.Extensions, ext)
+				}
+				err = processExtensions(cert)
+				if err != nil {
+					return nil, err
+				}
+			}
+		}
+	}
+
+	var signature asn1.BitString
+	if !input.ReadASN1BitString(&signature) {
+		return nil, errors.New("x509: malformed signature")
+	}
+	cert.Signature = signature.RightAlign()
+
+	return cert, nil
+}
+
+// ParseCertificate parses a single certificate from the given ASN.1 DER data.
+func ParseCertificate(der []byte) (*Certificate, error) {
+	cert, err := parseCertificate(der)
+	if err != nil {
+		return nil, err
+	}
+	if len(der) != len(cert.Raw) {
+		return nil, errors.New("x509: trailing data")
+	}
+	return cert, err
+}
+
+// ParseCertificates parses one or more certificates from the given ASN.1 DER
+// data. The certificates must be concatenated with no intermediate padding.
+func ParseCertificates(der []byte) ([]*Certificate, error) {
+	var certs []*Certificate
+	for len(der) > 0 {
+		cert, err := parseCertificate(der)
+		if err != nil {
+			return nil, err
+		}
+		certs = append(certs, cert)
+		der = der[len(cert.Raw):]
+	}
+	return certs, nil
+}
diff --git a/src/crypto/x509/root.go b/src/crypto/x509/root.go
index cc53f7a..eef9c04 100644
--- a/src/crypto/x509/root.go
+++ b/src/crypto/x509/root.go
@@ -8,7 +8,7 @@
 // argument to the latest security_certificates version from
 // https://opensource.apple.com/source/security_certificates/
 // and run "go generate". See https://golang.org/issue/38843.
-//go:generate go run root_ios_gen.go -version 55188.40.9
+//go:generate go run root_ios_gen.go -version 55188.120.1.0.1
 
 import "sync"
 
diff --git a/src/crypto/x509/root_bsd.go b/src/crypto/x509/root_bsd.go
index f04b6bd..6712ea3 100644
--- a/src/crypto/x509/root_bsd.go
+++ b/src/crypto/x509/root_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || netbsd || openbsd
 // +build dragonfly freebsd netbsd openbsd
 
 package x509
@@ -17,6 +18,7 @@
 // Possible directories with certificate files; stop after successfully
 // reading at least one file from a directory.
 var certDirectories = []string{
+	"/etc/ssl/certs",         // FreeBSD 12.2+
 	"/usr/local/share/certs", // FreeBSD
 	"/etc/openssl/certs",     // NetBSD
 }
diff --git a/src/crypto/x509/root_darwin.go b/src/crypto/x509/root_darwin.go
index c9ea7e8..05593bb 100644
--- a/src/crypto/x509/root_darwin.go
+++ b/src/crypto/x509/root_darwin.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !ios
 // +build !ios
 
 package x509
diff --git a/src/crypto/x509/root_ios.go b/src/crypto/x509/root_ios.go
index d2dfb62..9bc62f8 100644
--- a/src/crypto/x509/root_ios.go
+++ b/src/crypto/x509/root_ios.go
@@ -1,8 +1,8 @@
-// Code generated by root_ios_gen.go -version 55188.40.9; DO NOT EDIT.
+// Code generated by root_ios_gen.go -version 55188.120.1.0.1; DO NOT EDIT.
 // Update the version in root.go and regenerate with "go generate".
 
-// +build ios
-// +build !x509omitbundledroots
+//go:build ios && !x509omitbundledroots
+// +build ios,!x509omitbundledroots
 
 package x509
 
@@ -2223,6 +2223,41 @@
 kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
 ewv4n4Q=
 -----END CERTIFICATE-----
+# "GlobalSign"
+# 2C AB EA FE 37 D0 6C A2 2A BA 73 91 C0 03 3D 25
+# 98 29 52 C4 53 64 73 49 76 3A 3A B5 AD 6C CF 69
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg
+MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh
+bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx
+MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET
+MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI
+xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k
+ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD
+aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw
+LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw
+1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX
+k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2
+SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h
+bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n
+WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY
+rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce
+MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu
+bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN
+nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt
+Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61
+55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj
+vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf
+cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz
+oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp
+nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs
+pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v
+JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R
+8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4
+5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=
+-----END CERTIFICATE-----
 # "GlobalSign Root CA"
 # EB D4 10 40 E4 BB 3E C7 42 C9 E3 81 D3 1E F2 A4
 # 1A 48 B6 68 5C 96 E7 CE F3 C1 DF 6C D4 33 1C 99
diff --git a/src/crypto/x509/root_ios_gen.go b/src/crypto/x509/root_ios_gen.go
index 8bc6e7d..05bd672 100644
--- a/src/crypto/x509/root_ios_gen.go
+++ b/src/crypto/x509/root_ios_gen.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // Generates root_ios.go.
diff --git a/src/crypto/x509/root_js.go b/src/crypto/x509/root_js.go
index 4e537a4..f2c2c0a 100644
--- a/src/crypto/x509/root_js.go
+++ b/src/crypto/x509/root_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package x509
diff --git a/src/crypto/x509/root_omit.go b/src/crypto/x509/root_omit.go
index 0055b3b..81f2f11 100644
--- a/src/crypto/x509/root_omit.go
+++ b/src/crypto/x509/root_omit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ((darwin && arm64) || (darwin && amd64 && ios)) && x509omitbundledroots
 // +build darwin,arm64 darwin,amd64,ios
 // +build x509omitbundledroots
 
diff --git a/src/crypto/x509/root_omit_test.go b/src/crypto/x509/root_omit_test.go
index 5ab6c93..158bd7f 100644
--- a/src/crypto/x509/root_omit_test.go
+++ b/src/crypto/x509/root_omit_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ((darwin && arm64) || (darwin && amd64 && ios)) && x509omitbundledroots
 // +build darwin,arm64 darwin,amd64,ios
 // +build x509omitbundledroots
 
diff --git a/src/crypto/x509/root_plan9.go b/src/crypto/x509/root_plan9.go
index 2dc4aaf..2bdb2fe 100644
--- a/src/crypto/x509/root_plan9.go
+++ b/src/crypto/x509/root_plan9.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build plan9
 // +build plan9
 
 package x509
diff --git a/src/crypto/x509/root_unix.go b/src/crypto/x509/root_unix.go
index 262fc07..dede825 100644
--- a/src/crypto/x509/root_unix.go
+++ b/src/crypto/x509/root_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package x509
diff --git a/src/crypto/x509/root_unix_test.go b/src/crypto/x509/root_unix_test.go
index 878ed7c..7118f12 100644
--- a/src/crypto/x509/root_unix_test.go
+++ b/src/crypto/x509/root_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build dragonfly freebsd linux netbsd openbsd solaris
 
 package x509
@@ -146,11 +147,7 @@
 		os.Setenv(certFileEnv, origFile)
 	}()
 
-	tmpDir, err := os.MkdirTemp(os.TempDir(), "x509-issue35325")
-	if err != nil {
-		t.Fatalf("Failed to create temporary directory: %v", err)
-	}
-	defer os.RemoveAll(tmpDir)
+	tmpDir := t.TempDir()
 
 	rootPEMs := []string{
 		geoTrustRoot,
diff --git a/src/crypto/x509/verify.go b/src/crypto/x509/verify.go
index 46afb26..9ef1146 100644
--- a/src/crypto/x509/verify.go
+++ b/src/crypto/x509/verify.go
@@ -10,7 +10,6 @@
 	"fmt"
 	"net"
 	"net/url"
-	"os"
 	"reflect"
 	"runtime"
 	"strings"
@@ -18,9 +17,6 @@
 	"unicode/utf8"
 )
 
-// ignoreCN disables interpreting Common Name as a hostname. See issue 24151.
-var ignoreCN = !strings.Contains(os.Getenv("GODEBUG"), "x509ignoreCN=0")
-
 type InvalidReason int
 
 const (
@@ -43,14 +39,7 @@
 	// 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, and the Common Name can be interpreted as
-	// a hostname.
-	//
-	// This error is only returned when legacy Common Name matching is enabled
-	// by setting the GODEBUG environment variable to "x509ignoreCN=1". This
-	// setting might be removed in the future.
+	// NameConstraintsWithoutSANs is a legacy error and is no longer returned.
 	NameConstraintsWithoutSANs
 	// UnconstrainedName results when a CA certificate contains permitted
 	// name constraints, but leaf certificate contains a name of an
@@ -110,15 +99,7 @@
 	c := h.Certificate
 
 	if !c.hasSANExtension() && matchHostnames(c.Subject.CommonName, h.Host) {
-		if !ignoreCN && !validHostnamePattern(c.Subject.CommonName) {
-			// This would have validated, if it weren't for the validHostname check on Common Name.
-			return "x509: Common Name is not a valid hostname: " + c.Subject.CommonName
-		}
-		if ignoreCN && validHostnamePattern(c.Subject.CommonName) {
-			// This would have validated if x509ignoreCN=0 were set.
-			return "x509: certificate relies on legacy Common Name field, " +
-				"use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0"
-		}
+		return "x509: certificate relies on legacy Common Name field, use SANs instead"
 	}
 
 	var valid string
@@ -134,11 +115,7 @@
 			valid += san.String()
 		}
 	} else {
-		if c.commonNameAsHostname() {
-			valid = c.Subject.CommonName
-		} else {
-			valid = strings.Join(c.DNSNames, ", ")
-		}
+		valid = strings.Join(c.DNSNames, ", ")
 	}
 
 	if len(valid) == 0 {
@@ -620,15 +597,8 @@
 		leaf = currentChain[0]
 	}
 
-	checkNameConstraints := (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints()
-	if checkNameConstraints && leaf.commonNameAsHostname() {
-		// This is the deprecated, legacy case of depending on the commonName as
-		// a hostname. We don't enforce name constraints against the CN, but
-		// VerifyHostname will look for hostnames in there if there are no SANs.
-		// In order to ensure VerifyHostname will not accept an unchecked name,
-		// return an error here.
-		return CertificateInvalidError{c, NameConstraintsWithoutSANs, ""}
-	} else if checkNameConstraints && leaf.hasSANExtension() {
+	if (certType == intermediateCertificate || certType == rootCertificate) &&
+		c.hasNameConstraints() && leaf.hasSANExtension() {
 		err := forEachSAN(leaf.getSANExtension(), func(tag int, data []byte) error {
 			switch tag {
 			case nameTypeEmail:
@@ -837,7 +807,7 @@
 }
 
 // maxChainSignatureChecks is the maximum number of CheckSignatureFrom calls
-// that an invocation of buildChains will (tranistively) make. Most chains are
+// that an invocation of buildChains will (transitively) make. Most chains are
 // less than 15 certificates long, so this leaves space for multiple chains and
 // for failed checks due to different intermediates having the same Subject.
 const maxChainSignatureChecks = 100
@@ -960,18 +930,6 @@
 	return true
 }
 
-// commonNameAsHostname reports whether the Common Name field should be
-// considered the hostname that the certificate is valid for. This is a legacy
-// behavior, disabled by default or if the Subject Alt Name extension is present.
-//
-// It applies the strict validHostname check to the Common Name field, so that
-// certificates without SANs can still be validated against CAs with name
-// constraints if there is no risk the CN would be matched as a hostname.
-// See NameConstraintsWithoutSANs and issue 24151.
-func (c *Certificate) commonNameAsHostname() bool {
-	return !ignoreCN && !c.hasSANExtension() && validHostnamePattern(c.Subject.CommonName)
-}
-
 func matchExactly(hostA, hostB string) bool {
 	if hostA == "" || hostA == "." || hostB == "" || hostB == "." {
 		return false
@@ -1046,10 +1004,7 @@
 // against the DNSNames field. If the names are valid hostnames, the certificate
 // fields can have a wildcard as the left-most label.
 //
-// The legacy Common Name field is ignored unless it's a valid hostname, the
-// certificate doesn't have any Subject Alternative Names, and the GODEBUG
-// environment variable is set to "x509ignoreCN=0". Support for Common Name is
-// deprecated will be entirely removed in the future.
+// Note that the legacy Common Name field is ignored.
 func (c *Certificate) VerifyHostname(h string) error {
 	// IP addresses may be written in [ ].
 	candidateIP := h
@@ -1067,15 +1022,10 @@
 		return HostnameError{c, candidateIP}
 	}
 
-	names := c.DNSNames
-	if c.commonNameAsHostname() {
-		names = []string{c.Subject.CommonName}
-	}
-
 	candidateName := toLowerCaseASCII(h) // Save allocations inside the loop.
 	validCandidateName := validHostnameInput(candidateName)
 
-	for _, match := range names {
+	for _, match := range c.DNSNames {
 		// Ideally, we'd only match valid hostnames according to RFC 6125 like
 		// browsers (more or less) do, but in practice Go is used in a wider
 		// array of contexts and can't even assume DNS resolution. Instead,
diff --git a/src/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go
index 8e0a7be..9954a67 100644
--- a/src/crypto/x509/verify_test.go
+++ b/src/crypto/x509/verify_test.go
@@ -30,7 +30,6 @@
 	systemSkip    bool
 	systemLax     bool
 	keyUsages     []ExtKeyUsage
-	ignoreCN      bool
 
 	errorCallback  func(*testing.T, error)
 	expectedChains [][]string
@@ -297,8 +296,6 @@
 		errorCallback: expectNotAuthorizedError,
 	},
 	{
-		// If any SAN extension is present (even one without any DNS
-		// names), the CN should be ignored.
 		name:        "IgnoreCNWithSANs",
 		leaf:        ignoreCNWithSANLeaf,
 		dnsName:     "foo.example.com",
@@ -325,7 +322,6 @@
 		// verify error.
 		name:          "CriticalExtLeaf",
 		leaf:          criticalExtLeafWithExt,
-		dnsName:       "example.com",
 		intermediates: []string{criticalExtIntermediate},
 		roots:         []string{criticalExtRoot},
 		currentTime:   1486684488,
@@ -338,7 +334,6 @@
 		// cause a verify error.
 		name:          "CriticalExtIntermediate",
 		leaf:          criticalExtLeaf,
-		dnsName:       "example.com",
 		intermediates: []string{criticalExtIntermediateWithExt},
 		roots:         []string{criticalExtRoot},
 		currentTime:   1486684488,
@@ -347,18 +342,6 @@
 		errorCallback: expectUnhandledCriticalExtension,
 	},
 	{
-		// Test that invalid CN are ignored.
-		name:        "InvalidCN",
-		leaf:        invalidCNWithoutSAN,
-		dnsName:     "foo,invalid",
-		roots:       []string{invalidCNRoot},
-		currentTime: 1540000000,
-		systemSkip:  true, // does not chain to a system root
-
-		errorCallback: expectHostnameError("Common Name is not a valid hostname"),
-	},
-	{
-		// Test that valid CN are respected.
 		name:        "ValidCN",
 		leaf:        validCNWithoutSAN,
 		dnsName:     "foo.example.com",
@@ -366,42 +349,6 @@
 		currentTime: 1540000000,
 		systemSkip:  true, // does not chain to a system root
 
-		expectedChains: [][]string{
-			{"foo.example.com", "Test root"},
-		},
-	},
-	// Replicate CN tests with ignoreCN = true
-	{
-		name:        "IgnoreCNWithSANs/ignoreCN",
-		leaf:        ignoreCNWithSANLeaf,
-		dnsName:     "foo.example.com",
-		roots:       []string{ignoreCNWithSANRoot},
-		currentTime: 1486684488,
-		systemSkip:  true, // does not chain to a system root
-		ignoreCN:    true,
-
-		errorCallback: expectHostnameError("certificate is not valid for any names"),
-	},
-	{
-		name:        "InvalidCN/ignoreCN",
-		leaf:        invalidCNWithoutSAN,
-		dnsName:     "foo,invalid",
-		roots:       []string{invalidCNRoot},
-		currentTime: 1540000000,
-		systemSkip:  true, // does not chain to a system root
-		ignoreCN:    true,
-
-		errorCallback: expectHostnameError("certificate is not valid for any names"),
-	},
-	{
-		name:        "ValidCN/ignoreCN",
-		leaf:        validCNWithoutSAN,
-		dnsName:     "foo.example.com",
-		roots:       []string{invalidCNRoot},
-		currentTime: 1540000000,
-		systemSkip:  true, // does not chain to a system root
-		ignoreCN:    true,
-
 		errorCallback: expectHostnameError("certificate relies on legacy Common Name field"),
 	},
 	{
@@ -503,9 +450,6 @@
 }
 
 func testVerify(t *testing.T, test verifyTest, useSystemRoots bool) {
-	defer func(savedIgnoreCN bool) { ignoreCN = savedIgnoreCN }(ignoreCN)
-
-	ignoreCN = test.ignoreCN
 	opts := VerifyOptions{
 		Intermediates: NewCertPool(),
 		DNSName:       test.dnsName,
@@ -1589,16 +1533,6 @@
 XzZZl0eW/ugCICgOfXeZ2GGy3wIC0352BaC3a8r5AAb2XSGNe+e9wNN6
 -----END CERTIFICATE-----`
 
-const invalidCNWithoutSAN = `-----BEGIN CERTIFICATE-----
-MIIBJDCBywIUB7q8t9mrDAL+UB1OFaMN5BEWFKIwCgYIKoZIzj0EAwIwFDESMBAG
-A1UECwwJVGVzdCByb290MB4XDTE4MDcxMTE4MzUyMVoXDTI4MDcwODE4MzUyMVow
-FjEUMBIGA1UEAwwLZm9vLGludmFsaWQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
-AASnpnwiM6dHfwiTLV9hNS7aRWd28pdzGLABEkoa1bdvQTy7BWn0Bl3/6yunhQtM
-90VOgUB6qcYdu7rZuSazylCQMAoGCCqGSM49BAMCA0gAMEUCIQCFlnW2cjxnEqB/
-hgSB0t3IZ1DXX4XAVFT85mtFCJPTKgIgYIY+1iimTtrdbpWJzAB2eBwDgIWmWgvr
-xfOcLt/vbvo=
------END CERTIFICATE-----`
-
 const validCNWithoutSAN = `-----BEGIN CERTIFICATE-----
 MIIBJzCBzwIUB7q8t9mrDAL+UB1OFaMN5BEWFKQwCgYIKoZIzj0EAwIwFDESMBAG
 A1UECwwJVGVzdCByb290MB4XDTE4MDcxMTE4NDcyNFoXDTI4MDcwODE4NDcyNFow
diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go
index 8c0299b..4304ab5 100644
--- a/src/crypto/x509/x509.go
+++ b/src/crypto/x509/x509.go
@@ -8,7 +8,6 @@
 import (
 	"bytes"
 	"crypto"
-	"crypto/dsa"
 	"crypto/ecdsa"
 	"crypto/ed25519"
 	"crypto/elliptic"
@@ -24,7 +23,6 @@
 	"net"
 	"net/url"
 	"strconv"
-	"strings"
 	"time"
 	"unicode"
 
@@ -914,676 +912,6 @@
 	RelativeName pkix.RDNSequence `asn1:"optional,tag:1"`
 }
 
-func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) {
-	asn1Data := keyData.PublicKey.RightAlign()
-	switch algo {
-	case RSA:
-		// RSA public keys must have a NULL in the parameters.
-		// See RFC 3279, Section 2.3.1.
-		if !bytes.Equal(keyData.Algorithm.Parameters.FullBytes, asn1.NullBytes) {
-			return nil, errors.New("x509: RSA key missing NULL parameters")
-		}
-
-		p := new(pkcs1PublicKey)
-		rest, err := asn1.Unmarshal(asn1Data, p)
-		if err != nil {
-			return nil, err
-		}
-		if len(rest) != 0 {
-			return nil, errors.New("x509: trailing data after RSA public key")
-		}
-
-		if p.N.Sign() <= 0 {
-			return nil, errors.New("x509: RSA modulus is not a positive number")
-		}
-		if p.E <= 0 {
-			return nil, errors.New("x509: RSA public exponent is not a positive number")
-		}
-
-		pub := &rsa.PublicKey{
-			E: p.E,
-			N: p.N,
-		}
-		return pub, nil
-	case DSA:
-		var p *big.Int
-		rest, err := asn1.Unmarshal(asn1Data, &p)
-		if err != nil {
-			return nil, err
-		}
-		if len(rest) != 0 {
-			return nil, errors.New("x509: trailing data after DSA public key")
-		}
-		paramsData := keyData.Algorithm.Parameters.FullBytes
-		params := new(dsaAlgorithmParameters)
-		rest, err = asn1.Unmarshal(paramsData, params)
-		if err != nil {
-			return nil, err
-		}
-		if len(rest) != 0 {
-			return nil, errors.New("x509: trailing data after DSA parameters")
-		}
-		if p.Sign() <= 0 || params.P.Sign() <= 0 || params.Q.Sign() <= 0 || params.G.Sign() <= 0 {
-			return nil, errors.New("x509: zero or negative DSA parameter")
-		}
-		pub := &dsa.PublicKey{
-			Parameters: dsa.Parameters{
-				P: params.P,
-				Q: params.Q,
-				G: params.G,
-			},
-			Y: p,
-		}
-		return pub, nil
-	case ECDSA:
-		paramsData := keyData.Algorithm.Parameters.FullBytes
-		namedCurveOID := new(asn1.ObjectIdentifier)
-		rest, err := asn1.Unmarshal(paramsData, namedCurveOID)
-		if err != nil {
-			return nil, errors.New("x509: failed to parse ECDSA parameters as named curve")
-		}
-		if len(rest) != 0 {
-			return nil, errors.New("x509: trailing data after ECDSA parameters")
-		}
-		namedCurve := namedCurveFromOID(*namedCurveOID)
-		if namedCurve == nil {
-			return nil, errors.New("x509: unsupported elliptic curve")
-		}
-		x, y := elliptic.Unmarshal(namedCurve, asn1Data)
-		if x == nil {
-			return nil, errors.New("x509: failed to unmarshal elliptic curve point")
-		}
-		pub := &ecdsa.PublicKey{
-			Curve: namedCurve,
-			X:     x,
-			Y:     y,
-		}
-		return pub, nil
-	case Ed25519:
-		// RFC 8410, Section 3
-		// > For all of the OIDs, the parameters MUST be absent.
-		if len(keyData.Algorithm.Parameters.FullBytes) != 0 {
-			return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")
-		}
-		if len(asn1Data) != ed25519.PublicKeySize {
-			return nil, errors.New("x509: wrong Ed25519 public key size")
-		}
-		pub := make([]byte, ed25519.PublicKeySize)
-		copy(pub, asn1Data)
-		return ed25519.PublicKey(pub), nil
-	default:
-		return nil, nil
-	}
-}
-
-func forEachSAN(extension []byte, callback func(tag int, data []byte) error) error {
-	// RFC 5280, 4.2.1.6
-
-	// SubjectAltName ::= GeneralNames
-	//
-	// GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
-	//
-	// GeneralName ::= CHOICE {
-	//      otherName                       [0]     OtherName,
-	//      rfc822Name                      [1]     IA5String,
-	//      dNSName                         [2]     IA5String,
-	//      x400Address                     [3]     ORAddress,
-	//      directoryName                   [4]     Name,
-	//      ediPartyName                    [5]     EDIPartyName,
-	//      uniformResourceIdentifier       [6]     IA5String,
-	//      iPAddress                       [7]     OCTET STRING,
-	//      registeredID                    [8]     OBJECT IDENTIFIER }
-	var seq asn1.RawValue
-	rest, err := asn1.Unmarshal(extension, &seq)
-	if err != nil {
-		return err
-	} else if len(rest) != 0 {
-		return errors.New("x509: trailing data after X.509 extension")
-	}
-	if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 {
-		return asn1.StructuralError{Msg: "bad SAN sequence"}
-	}
-
-	rest = seq.Bytes
-	for len(rest) > 0 {
-		var v asn1.RawValue
-		rest, err = asn1.Unmarshal(rest, &v)
-		if err != nil {
-			return err
-		}
-
-		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:
-			email := string(data)
-			if err := isIA5String(email); err != nil {
-				return errors.New("x509: SAN rfc822Name is malformed")
-			}
-			emailAddresses = append(emailAddresses, email)
-		case nameTypeDNS:
-			name := string(data)
-			if err := isIA5String(name); err != nil {
-				return errors.New("x509: SAN dNSName is malformed")
-			}
-			dnsNames = append(dnsNames, string(name))
-		case nameTypeURI:
-			uriStr := string(data)
-			if err := isIA5String(uriStr); err != nil {
-				return errors.New("x509: SAN uniformResourceIdentifier is malformed")
-			}
-			uri, err := url.Parse(uriStr)
-			if err != nil {
-				return fmt.Errorf("x509: cannot parse URI %q: %s", uriStr, err)
-			}
-			if len(uri.Host) > 0 {
-				if _, ok := domainToReverseLabels(uri.Host); !ok {
-					return fmt.Errorf("x509: cannot parse URI %q: invalid domain", uriStr)
-				}
-			}
-			uris = append(uris, uri)
-		case nameTypeIP:
-			switch len(data) {
-			case net.IPv4len, net.IPv6len:
-				ipAddresses = append(ipAddresses, data)
-			default:
-				return errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len(data)))
-			}
-		}
-
-		return nil
-	})
-
-	return
-}
-
-// isValidIPMask reports whether 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 {
-		// From RFC 5280, 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
-	out.RawTBSCertificate = in.TBSCertificate.Raw
-	out.RawSubjectPublicKeyInfo = in.TBSCertificate.PublicKey.Raw
-	out.RawSubject = in.TBSCertificate.Subject.FullBytes
-	out.RawIssuer = in.TBSCertificate.Issuer.FullBytes
-
-	out.Signature = in.SignatureValue.RightAlign()
-	out.SignatureAlgorithm =
-		getSignatureAlgorithmFromAI(in.TBSCertificate.SignatureAlgorithm)
-
-	out.PublicKeyAlgorithm =
-		getPublicKeyAlgorithmFromOID(in.TBSCertificate.PublicKey.Algorithm.Algorithm)
-	var err error
-	out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCertificate.PublicKey)
-	if err != nil {
-		return nil, err
-	}
-
-	out.Version = in.TBSCertificate.Version + 1
-	out.SerialNumber = in.TBSCertificate.SerialNumber
-
-	var issuer, subject pkix.RDNSequence
-	if rest, err := asn1.Unmarshal(in.TBSCertificate.Subject.FullBytes, &subject); err != nil {
-		return nil, err
-	} else if len(rest) != 0 {
-		return nil, errors.New("x509: trailing data after X.509 subject")
-	}
-	if rest, err := asn1.Unmarshal(in.TBSCertificate.Issuer.FullBytes, &issuer); err != nil {
-		return nil, err
-	} else if len(rest) != 0 {
-		return nil, errors.New("x509: trailing data after X.509 issuer")
-	}
-
-	out.Issuer.FillFromRDNSequence(&issuer)
-	out.Subject.FillFromRDNSequence(&subject)
-
-	out.NotBefore = in.TBSCertificate.Validity.NotBefore
-	out.NotAfter = in.TBSCertificate.Validity.NotAfter
-
-	for _, e := range in.TBSCertificate.Extensions {
-		out.Extensions = append(out.Extensions, e)
-		unhandled := false
-
-		if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 {
-			switch e.Id[3] {
-			case 15:
-				out.KeyUsage, err = parseKeyUsageExtension(e.Value)
-				if err != nil {
-					return nil, err
-				}
-			case 19:
-				out.IsCA, out.MaxPathLen, err = parseBasicConstraintsExtension(e.Value)
-				if err != nil {
-					return nil, err
-				}
-				out.BasicConstraintsValid = true
-				out.MaxPathLenZero = out.MaxPathLen == 0
-			case 17:
-				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 && len(out.URIs) == 0 {
-					// If we didn't parse anything then we do the critical check, below.
-					unhandled = true
-				}
-
-			case 30:
-				unhandled, err = parseNameConstraintsExtension(out, e)
-				if err != nil {
-					return nil, err
-				}
-
-			case 31:
-				// RFC 5280, 4.2.1.13
-
-				// CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
-				//
-				// DistributionPoint ::= SEQUENCE {
-				//     distributionPoint       [0]     DistributionPointName OPTIONAL,
-				//     reasons                 [1]     ReasonFlags OPTIONAL,
-				//     cRLIssuer               [2]     GeneralNames OPTIONAL }
-				//
-				// DistributionPointName ::= CHOICE {
-				//     fullName                [0]     GeneralNames,
-				//     nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
-
-				var cdp []distributionPoint
-				if rest, err := asn1.Unmarshal(e.Value, &cdp); err != nil {
-					return nil, err
-				} else if len(rest) != 0 {
-					return nil, errors.New("x509: trailing data after X.509 CRL distribution point")
-				}
-
-				for _, dp := range cdp {
-					// Per RFC 5280, 4.2.1.13, one of distributionPoint or cRLIssuer may be empty.
-					if len(dp.DistributionPoint.FullName) == 0 {
-						continue
-					}
-
-					for _, fullName := range dp.DistributionPoint.FullName {
-						if fullName.Tag == 6 {
-							out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(fullName.Bytes))
-						}
-					}
-				}
-
-			case 35:
-				// RFC 5280, 4.2.1.1
-				var a authKeyId
-				if rest, err := asn1.Unmarshal(e.Value, &a); err != nil {
-					return nil, err
-				} else if len(rest) != 0 {
-					return nil, errors.New("x509: trailing data after X.509 authority key-id")
-				}
-				out.AuthorityKeyId = a.Id
-
-			case 37:
-				out.ExtKeyUsage, out.UnknownExtKeyUsage, err = parseExtKeyUsageExtension(e.Value)
-				if err != nil {
-					return nil, err
-				}
-			case 14:
-				out.SubjectKeyId, err = parseSubjectKeyIdExtension(e.Value)
-				if err != nil {
-					return nil, err
-				}
-			case 32:
-				out.PolicyIdentifiers, err = parseCertificatePoliciesExtension(e.Value)
-				if err != nil {
-					return nil, err
-				}
-			default:
-				// Unknown extensions are recorded if critical.
-				unhandled = true
-			}
-		} else if e.Id.Equal(oidExtensionAuthorityInfoAccess) {
-			// RFC 5280 4.2.2.1: Authority Information Access
-			var aia []authorityInfoAccess
-			if rest, err := asn1.Unmarshal(e.Value, &aia); err != nil {
-				return nil, err
-			} else if len(rest) != 0 {
-				return nil, errors.New("x509: trailing data after X.509 authority information")
-			}
-
-			for _, v := range aia {
-				// GeneralName: uniformResourceIdentifier [6] IA5String
-				if v.Location.Tag != 6 {
-					continue
-				}
-				if v.Method.Equal(oidAuthorityInfoAccessOcsp) {
-					out.OCSPServer = append(out.OCSPServer, string(v.Location.Bytes))
-				} else if v.Method.Equal(oidAuthorityInfoAccessIssuers) {
-					out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(v.Location.Bytes))
-				}
-			}
-		} else {
-			// Unknown extensions are recorded if critical.
-			unhandled = true
-		}
-
-		if e.Critical && unhandled {
-			out.UnhandledCriticalExtensions = append(out.UnhandledCriticalExtensions, e.Id)
-		}
-	}
-
-	return out, nil
-}
-
-// parseKeyUsageExtension parses id-ce-keyUsage (2.5.29.15) from RFC 5280
-// Section 4.2.1.3
-func parseKeyUsageExtension(ext []byte) (KeyUsage, error) {
-	var usageBits asn1.BitString
-	if rest, err := asn1.Unmarshal(ext, &usageBits); err != nil {
-		return 0, err
-	} else if len(rest) != 0 {
-		return 0, errors.New("x509: trailing data after X.509 KeyUsage")
-	}
-
-	var usage int
-	for i := 0; i < 9; i++ {
-		if usageBits.At(i) != 0 {
-			usage |= 1 << uint(i)
-		}
-	}
-	return KeyUsage(usage), nil
-}
-
-// parseBasicConstraintsExtension parses id-ce-basicConstraints (2.5.29.19)
-// from RFC 5280 Section 4.2.1.9
-func parseBasicConstraintsExtension(ext []byte) (isCA bool, maxPathLen int, err error) {
-	var constraints basicConstraints
-	if rest, err := asn1.Unmarshal(ext, &constraints); err != nil {
-		return false, 0, err
-	} else if len(rest) != 0 {
-		return false, 0, errors.New("x509: trailing data after X.509 BasicConstraints")
-	}
-
-	// TODO: map out.MaxPathLen to 0 if it has the -1 default value? (Issue 19285)
-	return constraints.IsCA, constraints.MaxPathLen, nil
-}
-
-// parseExtKeyUsageExtension parses id-ce-extKeyUsage (2.5.29.37) from
-// RFC 5280 Section 4.2.1.12
-func parseExtKeyUsageExtension(ext []byte) ([]ExtKeyUsage, []asn1.ObjectIdentifier, error) {
-	var keyUsage []asn1.ObjectIdentifier
-	if rest, err := asn1.Unmarshal(ext, &keyUsage); err != nil {
-		return nil, nil, err
-	} else if len(rest) != 0 {
-		return nil, nil, errors.New("x509: trailing data after X.509 ExtendedKeyUsage")
-	}
-
-	var extKeyUsages []ExtKeyUsage
-	var unknownUsages []asn1.ObjectIdentifier
-	for _, u := range keyUsage {
-		if extKeyUsage, ok := extKeyUsageFromOID(u); ok {
-			extKeyUsages = append(extKeyUsages, extKeyUsage)
-		} else {
-			unknownUsages = append(unknownUsages, u)
-		}
-	}
-	return extKeyUsages, unknownUsages, nil
-}
-
-// parseSubjectKeyIdExtension parses id-ce-subjectKeyIdentifier (2.5.29.14)
-// from RFC 5280 Section 4.2.1.2
-func parseSubjectKeyIdExtension(ext []byte) ([]byte, error) {
-	var keyid []byte
-	if rest, err := asn1.Unmarshal(ext, &keyid); err != nil {
-		return nil, err
-	} else if len(rest) != 0 {
-		return nil, errors.New("x509: trailing data after X.509 key-id")
-	}
-	return keyid, nil
-}
-
-func parseCertificatePoliciesExtension(ext []byte) ([]asn1.ObjectIdentifier, error) {
-	var policies []policyInformation
-	if rest, err := asn1.Unmarshal(ext, &policies); err != nil {
-		return nil, err
-	} else if len(rest) != 0 {
-		return nil, errors.New("x509: trailing data after X.509 certificate policies")
-	}
-	oids := make([]asn1.ObjectIdentifier, len(policies))
-	for i, policy := range policies {
-		oids[i] = policy.Policy
-	}
-	return oids, nil
-}
-
-// ParseCertificate parses a single certificate from the given ASN.1 DER data.
-func ParseCertificate(asn1Data []byte) (*Certificate, error) {
-	var cert certificate
-	rest, err := asn1.Unmarshal(asn1Data, &cert)
-	if err != nil {
-		return nil, err
-	}
-	if len(rest) > 0 {
-		return nil, asn1.SyntaxError{Msg: "trailing data"}
-	}
-
-	return parseCertificate(&cert)
-}
-
-// ParseCertificates parses one or more certificates from the given ASN.1 DER
-// data. The certificates must be concatenated with no intermediate padding.
-func ParseCertificates(asn1Data []byte) ([]*Certificate, error) {
-	var v []*certificate
-
-	for len(asn1Data) > 0 {
-		cert := new(certificate)
-		var err error
-		asn1Data, err = asn1.Unmarshal(asn1Data, cert)
-		if err != nil {
-			return nil, err
-		}
-		v = append(v, cert)
-	}
-
-	ret := make([]*Certificate, len(v))
-	for i, ci := range v {
-		cert, err := parseCertificate(ci)
-		if err != nil {
-			return nil, err
-		}
-		ret[i] = cert
-	}
-
-	return ret, nil
-}
-
 func reverseBitsInAByte(in byte) byte {
 	b1 := in>>4 | in<<4
 	b2 := b1>>2&0x33 | b1<<2&0xcc
@@ -2085,8 +1413,8 @@
 // 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:
+// CreateCertificate creates a new X.509 v3 certificate based on a template.
+// The following members of template are currently used:
 //
 //  - AuthorityKeyId
 //  - BasicConstraintsValid
@@ -2123,7 +1451,7 @@
 //
 // The certificate is signed by parent. If parent is equal to template then the
 // certificate is self-signed. The parameter pub is the public key of the
-// signee and priv is the private key of the signer.
+// certificate to be generated and priv is the private key of the signer.
 //
 // The returned slice is the certificate in DER encoding.
 //
@@ -2137,7 +1465,7 @@
 //
 // If SubjectKeyId from template is empty and the template is a CA, SubjectKeyId
 // will be generated from the hash of the public key.
-func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv interface{}) (cert []byte, err error) {
+func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv interface{}) ([]byte, error) {
 	key, ok := priv.(crypto.Signer)
 	if !ok {
 		return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
@@ -2163,12 +1491,12 @@
 
 	asn1Issuer, err := subjectBytes(parent)
 	if err != nil {
-		return
+		return nil, err
 	}
 
 	asn1Subject, err := subjectBytes(template)
 	if err != nil {
-		return
+		return nil, err
 	}
 
 	authorityKeyId := template.AuthorityKeyId
@@ -2186,9 +1514,19 @@
 		subjectKeyId = h[:]
 	}
 
+	// Check that the signer's public key matches the private key, if available.
+	type privateKey interface {
+		Equal(crypto.PublicKey) bool
+	}
+	if privPub, ok := key.Public().(privateKey); !ok {
+		return nil, errors.New("x509: internal error: supported public key does not implement Equal")
+	} else if parent.PublicKey != nil && !privPub.Equal(parent.PublicKey) {
+		return nil, errors.New("x509: provided PrivateKey doesn't match parent's PublicKey")
+	}
+
 	extensions, err := buildCertExtensions(template, bytes.Equal(asn1Subject, emptyASN1Subject), authorityKeyId, subjectKeyId)
 	if err != nil {
-		return
+		return nil, err
 	}
 
 	encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}
@@ -2205,7 +1543,7 @@
 
 	tbsCertContents, err := asn1.Marshal(c)
 	if err != nil {
-		return
+		return nil, err
 	}
 	c.Raw = tbsCertContents
 
@@ -2227,7 +1565,7 @@
 	var signature []byte
 	signature, err = key.Sign(rand, signed, signerOpts)
 	if err != nil {
-		return
+		return nil, err
 	}
 
 	signedCert, err := asn1.Marshal(certificate{
diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go
index 51dda16..a4053ab 100644
--- a/src/crypto/x509/x509_test.go
+++ b/src/crypto/x509/x509_test.go
@@ -2995,3 +2995,224 @@
 		t.Fatalf("Unexpected URIs: got %v, want %v", out.URIs, in.URIs)
 	}
 }
+
+func BenchmarkParseCertificate(b *testing.B) {
+	cases := []struct {
+		name string
+		pem  string
+	}{
+		{
+			name: "ecdsa leaf",
+			pem: `-----BEGIN CERTIFICATE-----
+MIIINjCCBx6gAwIBAgIQHdQ6oBMoe/MJAAAAAEHzmTANBgkqhkiG9w0BAQsFADBG
+MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
+QzETMBEGA1UEAxMKR1RTIENBIDFDMzAeFw0yMDEyMDgwOTExMzZaFw0yMTAzMDIw
+OTExMzVaMBcxFTATBgNVBAMMDCouZ29vZ2xlLmNvbTBZMBMGByqGSM49AgEGCCqG
+SM49AwEHA0IABEFYegyHh1AHRS1nar5+zYJgMACcsIQMtg0YMyK/59ml8ERIt/JF
+kXM3XIvQuCJhghUawZrrAcAs8djZF1U9M4mjggYYMIIGFDAOBgNVHQ8BAf8EBAMC
+B4AwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU
+6SWWF36XBsmXJ6iV0EHPXUFoMbwwHwYDVR0jBBgwFoAUinR/r4XN7pXNPZzQ4kYU
+83E1HScwagYIKwYBBQUHAQEEXjBcMCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5w
+a2kuZ29vZy9ndHMxYzMwMQYIKwYBBQUHMAKGJWh0dHA6Ly9wa2kuZ29vZy9yZXBv
+L2NlcnRzL2d0czFjMy5kZXIwggTCBgNVHREEggS5MIIEtYIMKi5nb29nbGUuY29t
+gg0qLmFuZHJvaWQuY29tghYqLmFwcGVuZ2luZS5nb29nbGUuY29tggkqLmJkbi5k
+ZXaCEiouY2xvdWQuZ29vZ2xlLmNvbYIYKi5jcm93ZHNvdXJjZS5nb29nbGUuY29t
+ghgqLmRhdGFjb21wdXRlLmdvb2dsZS5jb22CBiouZy5jb4IOKi5nY3AuZ3Z0Mi5j
+b22CESouZ2NwY2RuLmd2dDEuY29tggoqLmdncGh0LmNugg4qLmdrZWNuYXBwcy5j
+boIWKi5nb29nbGUtYW5hbHl0aWNzLmNvbYILKi5nb29nbGUuY2GCCyouZ29vZ2xl
+LmNsgg4qLmdvb2dsZS5jby5pboIOKi5nb29nbGUuY28uanCCDiouZ29vZ2xlLmNv
+LnVrgg8qLmdvb2dsZS5jb20uYXKCDyouZ29vZ2xlLmNvbS5hdYIPKi5nb29nbGUu
+Y29tLmJygg8qLmdvb2dsZS5jb20uY2+CDyouZ29vZ2xlLmNvbS5teIIPKi5nb29n
+bGUuY29tLnRygg8qLmdvb2dsZS5jb20udm6CCyouZ29vZ2xlLmRlggsqLmdvb2ds
+ZS5lc4ILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmh1ggsqLmdvb2dsZS5pdIILKi5n
+b29nbGUubmyCCyouZ29vZ2xlLnBsggsqLmdvb2dsZS5wdIISKi5nb29nbGVhZGFw
+aXMuY29tgg8qLmdvb2dsZWFwaXMuY26CESouZ29vZ2xlY25hcHBzLmNughQqLmdv
+b2dsZWNvbW1lcmNlLmNvbYIRKi5nb29nbGV2aWRlby5jb22CDCouZ3N0YXRpYy5j
+boINKi5nc3RhdGljLmNvbYISKi5nc3RhdGljY25hcHBzLmNuggoqLmd2dDEuY29t
+ggoqLmd2dDIuY29tghQqLm1ldHJpYy5nc3RhdGljLmNvbYIMKi51cmNoaW4uY29t
+ghAqLnVybC5nb29nbGUuY29tghMqLndlYXIuZ2tlY25hcHBzLmNughYqLnlvdXR1
+YmUtbm9jb29raWUuY29tgg0qLnlvdXR1YmUuY29tghYqLnlvdXR1YmVlZHVjYXRp
+b24uY29tghEqLnlvdXR1YmVraWRzLmNvbYIHKi55dC5iZYILKi55dGltZy5jb22C
+GmFuZHJvaWQuY2xpZW50cy5nb29nbGUuY29tggthbmRyb2lkLmNvbYIbZGV2ZWxv
+cGVyLmFuZHJvaWQuZ29vZ2xlLmNughxkZXZlbG9wZXJzLmFuZHJvaWQuZ29vZ2xl
+LmNuggRnLmNvgghnZ3BodC5jboIMZ2tlY25hcHBzLmNuggZnb28uZ2yCFGdvb2ds
+ZS1hbmFseXRpY3MuY29tggpnb29nbGUuY29tgg9nb29nbGVjbmFwcHMuY26CEmdv
+b2dsZWNvbW1lcmNlLmNvbYIYc291cmNlLmFuZHJvaWQuZ29vZ2xlLmNuggp1cmNo
+aW4uY29tggp3d3cuZ29vLmdsggh5b3V0dS5iZYILeW91dHViZS5jb22CFHlvdXR1
+YmVlZHVjYXRpb24uY29tgg95b3V0dWJla2lkcy5jb22CBXl0LmJlMCEGA1UdIAQa
+MBgwCAYGZ4EMAQIBMAwGCisGAQQB1nkCBQMwNQYDVR0fBC4wLDAqoCigJoYkaHR0
+cDovL2NybC5wa2kuZ29vZy9ndHNyMS9ndHMxYzMuY3JsMBMGCisGAQQB1nkCBAMB
+Af8EAgUAMA0GCSqGSIb3DQEBCwUAA4IBAQAlDQm5zY7JcPxcJ9ulfTGsWV/m6Pro
+gLYmAlBUPGKy313aetT4Zjz44ZseVtUOKsXVHh4avPA9O+ta1FgkASlbkgJ05ivb
+j/+MMqkrLemdMv9Svvx3CNaAq2jJ2E+8GdrA1RzMkiNthJCiRafaPnXnN6hOHGNr
+GtqYfMHsvrRHW8J2IPHW0/MUHmJ/NDu/vNchxke2OEfCPLtseo3hJt8l8HbH+yE8
+DFrt8YVRi1CLomEyuPJDF4og3O3ZsoXuxcPd9UPxULOCxycdolRw8Iv/Xgr082j3
+svXC3HUd3apM2Yy3xJAlk/mUkzVXfdJZ+Zy1huNsUoJ+gM8rmpyGhYyx
+-----END CERTIFICATE-----`,
+		},
+		{
+			name: "rsa leaf",
+			pem: `-----BEGIN CERTIFICATE-----
+MIIJXjCCCEagAwIBAgIRAPYaTUsjP4iRBQAAAACHSSgwDQYJKoZIhvcNAQELBQAw
+QjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczET
+MBEGA1UEAxMKR1RTIENBIDFPMTAeFw0yMTAxMjYwODQ2MzRaFw0yMTA0MjAwODQ2
+MzNaMGYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH
+Ew1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgTExDMRUwEwYDVQQDDAwq
+Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC76xx0
+UdZ36/41rZNPfQ/yQ05vsBLUO0d+3uMOhvDlpst+XvIsG6L+vLDgf3RiQRFlei0h
+KqqLOtWLDc/y0+OmaaC+8ft1zljBYdvQlAYoZrT79Cc5pAIDq7G1OZ7cC4ahDno/
+n46FHjT/UTUAMYa8cKWBaMPneMIsKvn8nMdZzHkfO2nUd6OEecn90XweMvNmx8De
+6h5AlIgG3m66hkD/UCSdxn7yJHBQVdHgkfTqzv3sz2YyBQGNi288F1bn541f6khE
+fYti1MvXRtkky7yLCQNUG6PtvuSU4cKaNvRklHigf5i1nVdGEuH61gAElZIklSia
+OVK46UyU4DGtbdWNAgMBAAGjggYpMIIGJTAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0l
+BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU8zCvllLd3jhB
+k//+Wdjo40Q+T3gwHwYDVR0jBBgwFoAUmNH4bhDrz5vsYJ8YkBug630J/SswaAYI
+KwYBBQUHAQEEXDBaMCsGCCsGAQUFBzABhh9odHRwOi8vb2NzcC5wa2kuZ29vZy9n
+dHMxbzFjb3JlMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2cvZ3NyMi9HVFMx
+TzEuY3J0MIIE1wYDVR0RBIIEzjCCBMqCDCouZ29vZ2xlLmNvbYINKi5hbmRyb2lk
+LmNvbYIWKi5hcHBlbmdpbmUuZ29vZ2xlLmNvbYIJKi5iZG4uZGV2ghIqLmNsb3Vk
+Lmdvb2dsZS5jb22CGCouY3Jvd2Rzb3VyY2UuZ29vZ2xlLmNvbYIYKi5kYXRhY29t
+cHV0ZS5nb29nbGUuY29tghMqLmZsYXNoLmFuZHJvaWQuY29tggYqLmcuY2+CDiou
+Z2NwLmd2dDIuY29tghEqLmdjcGNkbi5ndnQxLmNvbYIKKi5nZ3BodC5jboIOKi5n
+a2VjbmFwcHMuY26CFiouZ29vZ2xlLWFuYWx5dGljcy5jb22CCyouZ29vZ2xlLmNh
+ggsqLmdvb2dsZS5jbIIOKi5nb29nbGUuY28uaW6CDiouZ29vZ2xlLmNvLmpwgg4q
+Lmdvb2dsZS5jby51a4IPKi5nb29nbGUuY29tLmFygg8qLmdvb2dsZS5jb20uYXWC
+DyouZ29vZ2xlLmNvbS5icoIPKi5nb29nbGUuY29tLmNvgg8qLmdvb2dsZS5jb20u
+bXiCDyouZ29vZ2xlLmNvbS50coIPKi5nb29nbGUuY29tLnZuggsqLmdvb2dsZS5k
+ZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZyggsqLmdvb2dsZS5odYILKi5nb29n
+bGUuaXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5wbIILKi5nb29nbGUucHSCEiou
+Z29vZ2xlYWRhcGlzLmNvbYIPKi5nb29nbGVhcGlzLmNughEqLmdvb2dsZWNuYXBw
+cy5jboIUKi5nb29nbGVjb21tZXJjZS5jb22CESouZ29vZ2xldmlkZW8uY29tggwq
+LmdzdGF0aWMuY26CDSouZ3N0YXRpYy5jb22CEiouZ3N0YXRpY2NuYXBwcy5jboIK
+Ki5ndnQxLmNvbYIKKi5ndnQyLmNvbYIUKi5tZXRyaWMuZ3N0YXRpYy5jb22CDCou
+dXJjaGluLmNvbYIQKi51cmwuZ29vZ2xlLmNvbYITKi53ZWFyLmdrZWNuYXBwcy5j
+boIWKi55b3V0dWJlLW5vY29va2llLmNvbYINKi55b3V0dWJlLmNvbYIWKi55b3V0
+dWJlZWR1Y2F0aW9uLmNvbYIRKi55b3V0dWJla2lkcy5jb22CByoueXQuYmWCCyou
+eXRpbWcuY29tghphbmRyb2lkLmNsaWVudHMuZ29vZ2xlLmNvbYILYW5kcm9pZC5j
+b22CG2RldmVsb3Blci5hbmRyb2lkLmdvb2dsZS5jboIcZGV2ZWxvcGVycy5hbmRy
+b2lkLmdvb2dsZS5jboIEZy5jb4IIZ2dwaHQuY26CDGdrZWNuYXBwcy5jboIGZ29v
+LmdsghRnb29nbGUtYW5hbHl0aWNzLmNvbYIKZ29vZ2xlLmNvbYIPZ29vZ2xlY25h
+cHBzLmNughJnb29nbGVjb21tZXJjZS5jb22CGHNvdXJjZS5hbmRyb2lkLmdvb2ds
+ZS5jboIKdXJjaGluLmNvbYIKd3d3Lmdvby5nbIIIeW91dHUuYmWCC3lvdXR1YmUu
+Y29tghR5b3V0dWJlZWR1Y2F0aW9uLmNvbYIPeW91dHViZWtpZHMuY29tggV5dC5i
+ZTAhBgNVHSAEGjAYMAgGBmeBDAECAjAMBgorBgEEAdZ5AgUDMDMGA1UdHwQsMCow
+KKAmoCSGImh0dHA6Ly9jcmwucGtpLmdvb2cvR1RTMU8xY29yZS5jcmwwEwYKKwYB
+BAHWeQIEAwEB/wQCBQAwDQYJKoZIhvcNAQELBQADggEBAHh9/ozYUGRd+W5akWlM
+4WvX808TK2oUISnagbxCCFZ2trpg2oi03CJf4o4o3Je5Qzzz10s22oQY6gPHAR0B
+QHzrpqAveQw9D5vd8xjgtQ/SAujPzPKNQee5511rS7/EKW9I83ccd5XhhoEyx8A1
+/65RTS+2hKpJKTMkr0yHBPJV7kUW+n/KIef5YaSOA9VYK7hyH0niDpvm9EmoqvWS
+U5xAFAe/Xrrq3sxTuDJPQA8alk6h/ql5Klkw6dL53csiPka/MevDqdifWkzuT/6n
+YK/ePeJzPD17FA9V+N1rcuF3Wk29AZvCOSasdIkIuE82vGr3dfNrsrn9E9lWIbCr
+Qc4=
+-----END CERTIFICATE-----`,
+		},
+	}
+	for _, c := range cases {
+		b.Run(c.name, func(b *testing.B) {
+			pemBlock, _ := pem.Decode([]byte(c.pem))
+			b.ReportAllocs()
+			b.ResetTimer()
+			for i := 0; i < b.N; i++ {
+				_, err := ParseCertificate(pemBlock.Bytes)
+				if err != nil {
+					b.Fatal(err)
+				}
+			}
+		})
+	}
+}
+
+func TestParseCertificateRawEquals(t *testing.T) {
+	p, _ := pem.Decode([]byte(pemCertificate))
+	cert, err := ParseCertificate(p.Bytes)
+	if err != nil {
+		t.Fatalf("failed to parse certificate: %s", err)
+	}
+	if !bytes.Equal(p.Bytes, cert.Raw) {
+		t.Fatalf("unexpected Certificate.Raw\ngot: %x\nwant: %x\n", cert.Raw, p.Bytes)
+	}
+	fmt.Printf("in:  %x\nout: %x\n", p.Bytes, cert.Raw)
+}
+
+// mismatchingSigAlgIDPEM contains a certificate where the Certificate
+// signatureAlgorithm and the TBSCertificate signature contain
+// mismatching OIDs
+const mismatchingSigAlgIDPEM = `-----BEGIN CERTIFICATE-----
+MIIBBzCBrqADAgECAgEAMAoGCCqGSM49BAMCMAAwIhgPMDAwMTAxMDEwMDAwMDBa
+GA8wMDAxMDEwMTAwMDAwMFowADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOqV
+EDuVXxwZgIU3+dOwv1SsMu0xuV48hf7xmK8n7sAMYgllB+96DnPqBeboJj4snYnx
+0AcE0PDVQ1l4Z3YXsQWjFTATMBEGA1UdEQEB/wQHMAWCA2FzZDAKBggqhkjOPQQD
+AwNIADBFAiBi1jz/T2HT5nAfrD7zsgR+68qh7Erc6Q4qlxYBOgKG4QIhAOtjIn+Q
+tA+bq+55P3ntxTOVRq0nv1mwnkjwt9cQR9Fn
+-----END CERTIFICATE-----`
+
+// mismatchingSigAlgParamPEM contains a certificate where the Certificate
+// signatureAlgorithm and the TBSCertificate signature contain
+// mismatching parameters
+const mismatchingSigAlgParamPEM = `-----BEGIN CERTIFICATE-----
+MIIBCTCBrqADAgECAgEAMAoGCCqGSM49BAMCMAAwIhgPMDAwMTAxMDEwMDAwMDBa
+GA8wMDAxMDEwMTAwMDAwMFowADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOqV
+EDuVXxwZgIU3+dOwv1SsMu0xuV48hf7xmK8n7sAMYgllB+96DnPqBeboJj4snYnx
+0AcE0PDVQ1l4Z3YXsQWjFTATMBEGA1UdEQEB/wQHMAWCA2FzZDAMBggqhkjOPQQD
+AgUAA0gAMEUCIGLWPP9PYdPmcB+sPvOyBH7ryqHsStzpDiqXFgE6AobhAiEA62Mi
+f5C0D5ur7nk/ee3FM5VGrSe/WbCeSPC31xBH0Wc=
+-----END CERTIFICATE-----`
+
+func TestSigAlgMismatch(t *testing.T) {
+	for _, certPEM := range []string{mismatchingSigAlgIDPEM, mismatchingSigAlgParamPEM} {
+		b, _ := pem.Decode([]byte(certPEM))
+		if b == nil {
+			t.Fatalf("couldn't decode test certificate")
+		}
+		_, err := ParseCertificate(b.Bytes)
+		if err == nil {
+			t.Fatalf("expected ParseCertificate to fail")
+		}
+		expected := "x509: inner and outer signature algorithm identifiers don't match"
+		if err.Error() != expected {
+			t.Errorf("unexpected error from ParseCertificate: got %q, want %q", err.Error(), expected)
+		}
+	}
+}
+
+const optionalAuthKeyIDPEM = `-----BEGIN CERTIFICATE-----
+MIIFEjCCBHugAwIBAgICAQwwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh
+bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
+Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g
+QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe
+BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MzkxNloX
+DTI0MDYyOTE3MzkxNlowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVs
+ZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAy
+IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0A
+MIIBCAKCAQEAtzLI/ulxpgSFrQwRZN/OTe/IAxiHP6Gr+zymn/DDodrU2G4rU5D7
+JKQ+hPCe6F/s5SdE9SimP3ve4CrwyK9TL57KBQGTHo9mHDmnTfpatnMEJWbrd3/n
+WcZKmSUUVOsmx/N/GdUwcI+vsEYq/63rKe3Xn6oEh6PU+YmlNF/bQ5GCNtlmPLG4
+uYL9nDo+EMg77wZlZnqbGRg9/3FRPDAuX749d3OyXQZswyNWmiuFJpIcpwKz5D8N
+rwh5grg2Peqc0zWzvGnK9cyd6P1kjReAM25eSl2ZyR6HtJ0awNVuEzUjXt+bXz3v
+1vd2wuo+u3gNHEJnawTY+Nbab4vyRKABqwIBA6OCAfMwggHvMB0GA1UdDgQWBBS/
+X7fRzt0fhvRbVazc1xDCDqmI5zCB0gYDVR0jBIHKMIHHoYHBpIG+MIG7MSQwIgYD
+VQQHExtWYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmsxFzAVBgNVBAoTDlZhbGlD
+ZXJ0LCBJbmMuMTUwMwYDVQQLEyxWYWxpQ2VydCBDbGFzcyAyIFBvbGljeSBWYWxp
+ZGF0aW9uIEF1dGhvcml0eTEhMB8GA1UEAxMYaHR0cDovL3d3dy52YWxpY2VydC5j
+b20vMSAwHgYJKoZIhvcNAQkBFhFpbmZvQHZhbGljZXJ0LmNvbYIBATAPBgNVHRMB
+Af8EBTADAQH/MDkGCCsGAQUFBwEBBC0wKzApBggrBgEFBQcwAYYdaHR0cDovL29j
+c3Auc3RhcmZpZWxkdGVjaC5jb20wSgYDVR0fBEMwQTA/oD2gO4Y5aHR0cDovL2Nl
+cnRpZmljYXRlcy5zdGFyZmllbGR0ZWNoLmNvbS9yZXBvc2l0b3J5L3Jvb3QuY3Js
+MFEGA1UdIARKMEgwRgYEVR0gADA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY2VydGlm
+aWNhdGVzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkwDgYDVR0PAQH/BAQD
+AgEGMA0GCSqGSIb3DQEBBQUAA4GBAKVi8afCXSWlcD284ipxs33kDTcdVWptobCr
+mADkhWBKIMuh8D1195TaQ39oXCUIuNJ9MxB73HZn8bjhU3zhxoNbKXuNSm8uf0So
+GkVrMgfHeMpkksK0hAzc3S1fTbvdiuo43NlmouxBulVtWmQ9twPMHOKRUJ7jCUSV
+FxdzPcwl
+-----END CERTIFICATE-----`
+
+func TestAuthKeyIdOptional(t *testing.T) {
+	b, _ := pem.Decode([]byte(optionalAuthKeyIDPEM))
+	if b == nil {
+		t.Fatalf("couldn't decode test certificate")
+	}
+	_, err := ParseCertificate(b.Bytes)
+	if err != nil {
+		t.Fatalf("ParseCertificate to failed to parse certificate with optional authority key identifier fields: %s", err)
+	}
+}
diff --git a/src/crypto/x509/x509_test_import.go b/src/crypto/x509/x509_test_import.go
index b778df2..ef3ee80 100644
--- a/src/crypto/x509/x509_test_import.go
+++ b/src/crypto/x509/x509_test_import.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // This file is run by the x509 tests to ensure that a program with minimal
diff --git a/src/database/sql/driver/driver.go b/src/database/sql/driver/driver.go
index 5bbcf20..f093961 100644
--- a/src/database/sql/driver/driver.go
+++ b/src/database/sql/driver/driver.go
@@ -115,6 +115,9 @@
 // DriverContext's OpenConnector method, to allow drivers
 // access to context and to avoid repeated parsing of driver
 // configuration.
+//
+// If a Connector implements io.Closer, the sql package's DB.Close
+// method will call Close and return error (if any).
 type Connector interface {
 	// Connect returns a connection to the database.
 	// Connect may return a cached connection (one previously
diff --git a/src/database/sql/fakedb_test.go b/src/database/sql/fakedb_test.go
index 7605a2a..4b68f1c 100644
--- a/src/database/sql/fakedb_test.go
+++ b/src/database/sql/fakedb_test.go
@@ -56,6 +56,7 @@
 	name string
 
 	waiter func(context.Context)
+	closed bool
 }
 
 func (c *fakeConnector) Connect(context.Context) (driver.Conn, error) {
@@ -68,6 +69,14 @@
 	return fdriver
 }
 
+func (c *fakeConnector) Close() error {
+	if c.closed {
+		return errors.New("fakedb: connector is closed")
+	}
+	c.closed = true
+	return nil
+}
+
 type fakeDriverCtx struct {
 	fakeDriver
 }
@@ -906,7 +915,7 @@
 				parentMem: s.c,
 				posRow:    -1,
 				rows: [][]*row{
-					[]*row{
+					{
 						{
 							cols: []interface{}{
 								txStatus,
@@ -915,12 +924,12 @@
 					},
 				},
 				cols: [][]string{
-					[]string{
+					{
 						"tx_status",
 					},
 				},
 				colType: [][]string{
-					[]string{
+					{
 						"string",
 					},
 				},
@@ -1177,9 +1186,11 @@
 		return driver.Bool
 	case "nullbool":
 		return driver.Null{Converter: driver.Bool}
+	case "byte", "int16":
+		return driver.NotNull{Converter: driver.DefaultParameterConverter}
 	case "int32":
 		return driver.Int32
-	case "nullint32":
+	case "nullbyte", "nullint32", "nullint16":
 		return driver.Null{Converter: driver.DefaultParameterConverter}
 	case "string":
 		return driver.NotNull{Converter: fakeDriverString{}}
@@ -1213,6 +1224,10 @@
 		return reflect.TypeOf(false)
 	case "nullbool":
 		return reflect.TypeOf(NullBool{})
+	case "int16":
+		return reflect.TypeOf(int16(0))
+	case "nullint16":
+		return reflect.TypeOf(NullInt16{})
 	case "int32":
 		return reflect.TypeOf(int32(0))
 	case "nullint32":
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
index 726aadb..68fb392 100644
--- a/src/database/sql/sql.go
+++ b/src/database/sql/sql.go
@@ -260,6 +260,60 @@
 	return int64(n.Int32), nil
 }
 
+// NullInt16 represents an int16 that may be null.
+// NullInt16 implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullInt16 struct {
+	Int16 int16
+	Valid bool // Valid is true if Int16 is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullInt16) Scan(value interface{}) error {
+	if value == nil {
+		n.Int16, n.Valid = 0, false
+		return nil
+	}
+	err := convertAssign(&n.Int16, value)
+	n.Valid = err == nil
+	return err
+}
+
+// Value implements the driver Valuer interface.
+func (n NullInt16) Value() (driver.Value, error) {
+	if !n.Valid {
+		return nil, nil
+	}
+	return int64(n.Int16), nil
+}
+
+// NullByte represents a byte that may be null.
+// NullByte implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullByte struct {
+	Byte  byte
+	Valid bool // Valid is true if Byte is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullByte) Scan(value interface{}) error {
+	if value == nil {
+		n.Byte, n.Valid = 0, false
+		return nil
+	}
+	err := convertAssign(&n.Byte, value)
+	n.Valid = err == nil
+	return err
+}
+
+// Value implements the driver Valuer interface.
+func (n NullByte) Value() (driver.Value, error) {
+	if !n.Valid {
+		return nil, nil
+	}
+	return int64(n.Byte), nil
+}
+
 // NullFloat64 represents a float64 that may be null.
 // NullFloat64 implements the Scanner interface so
 // it can be used as a scan destination, similar to NullString.
@@ -813,6 +867,9 @@
 
 // Ping verifies a connection to the database is still alive,
 // establishing a connection if necessary.
+//
+// Ping uses context.Background internally; to specify the context, use
+// PingContext.
 func (db *DB) Ping() error {
 	return db.PingContext(context.Background())
 }
@@ -850,6 +907,12 @@
 		}
 	}
 	db.stop()
+	if c, ok := db.connector.(io.Closer); ok {
+		err1 := c.Close()
+		if err1 != nil {
+			err = err1
+		}
+	}
 	return err
 }
 
@@ -1475,6 +1538,9 @@
 // returned statement.
 // The caller must call the statement's Close method
 // when the statement is no longer needed.
+//
+// Prepare uses context.Background internally; to specify the context, use
+// PrepareContext.
 func (db *DB) Prepare(query string) (*Stmt, error) {
 	return db.PrepareContext(context.Background(), query)
 }
@@ -1545,6 +1611,9 @@
 
 // Exec executes a query without returning any rows.
 // The args are for any placeholder parameters in the query.
+//
+// Exec uses context.Background internally; to specify the context, use
+// ExecContext.
 func (db *DB) Exec(query string, args ...interface{}) (Result, error) {
 	return db.ExecContext(context.Background(), query, args...)
 }
@@ -1615,6 +1684,9 @@
 
 // Query executes a query that returns rows, typically a SELECT.
 // The args are for any placeholder parameters in the query.
+//
+// Query uses context.Background internally; to specify the context, use
+// QueryContext.
 func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
 	return db.QueryContext(context.Background(), query, args...)
 }
@@ -1713,6 +1785,9 @@
 // If the query selects no rows, the *Row's Scan will return ErrNoRows.
 // Otherwise, the *Row's Scan scans the first selected row and discards
 // the rest.
+//
+// QueryRow uses context.Background internally; to specify the context, use
+// QueryRowContext.
 func (db *DB) QueryRow(query string, args ...interface{}) *Row {
 	return db.QueryRowContext(context.Background(), query, args...)
 }
@@ -1744,6 +1819,9 @@
 
 // Begin starts a transaction. The default isolation level is dependent on
 // the driver.
+//
+// Begin uses context.Background internally; to specify the context, use
+// BeginTx.
 func (db *DB) Begin() (*Tx, error) {
 	return db.BeginTx(context.Background(), nil)
 }
@@ -1771,7 +1849,7 @@
 		return nil, err
 	}
 
-	// Schedule the transaction to rollback when the context is cancelled.
+	// Schedule the transaction to rollback when the context is canceled.
 	// The cancel function in Tx will be called after done is set to true.
 	ctx, cancel := context.WithCancel(ctx)
 	tx = &Tx{
@@ -2249,6 +2327,9 @@
 // be used once the transaction has been committed or rolled back.
 //
 // To use an existing prepared statement on this transaction, see Tx.Stmt.
+//
+// Prepare uses context.Background internally; to specify the context, use
+// PrepareContext.
 func (tx *Tx) Prepare(query string) (*Stmt, error) {
 	return tx.PrepareContext(context.Background(), query)
 }
@@ -2352,6 +2433,9 @@
 //
 // The returned statement operates within the transaction and will be closed
 // when the transaction has been committed or rolled back.
+//
+// Stmt uses context.Background internally; to specify the context, use
+// StmtContext.
 func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
 	return tx.StmtContext(context.Background(), stmt)
 }
@@ -2368,6 +2452,9 @@
 
 // Exec executes a query that doesn't return rows.
 // For example: an INSERT and UPDATE.
+//
+// Exec uses context.Background internally; to specify the context, use
+// ExecContext.
 func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) {
 	return tx.ExecContext(context.Background(), query, args...)
 }
@@ -2383,6 +2470,9 @@
 }
 
 // Query executes a query that returns rows, typically a SELECT.
+//
+// Query uses context.Background internally; to specify the context, use
+// QueryContext.
 func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
 	return tx.QueryContext(context.Background(), query, args...)
 }
@@ -2404,6 +2494,9 @@
 // If the query selects no rows, the *Row's Scan will return ErrNoRows.
 // Otherwise, the *Row's Scan scans the first selected row and discards
 // the rest.
+//
+// QueryRow uses context.Background internally; to specify the context, use
+// QueryRowContext.
 func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
 	return tx.QueryRowContext(context.Background(), query, args...)
 }
@@ -2510,6 +2603,9 @@
 
 // Exec executes a prepared statement with the given arguments and
 // returns a Result summarizing the effect of the statement.
+//
+// Exec uses context.Background internally; to specify the context, use
+// ExecContext.
 func (s *Stmt) Exec(args ...interface{}) (Result, error) {
 	return s.ExecContext(context.Background(), args...)
 }
@@ -2681,6 +2777,9 @@
 
 // Query executes a prepared query statement with the given arguments
 // and returns the query results as a *Rows.
+//
+// Query uses context.Background internally; to specify the context, use
+// QueryContext.
 func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
 	return s.QueryContext(context.Background(), args...)
 }
@@ -2720,6 +2819,9 @@
 //
 //  var name string
 //  err := nameByUseridStmt.QueryRow(id).Scan(&name)
+//
+// QueryRow uses context.Background internally; to specify the context, use
+// QueryRowContext.
 func (s *Stmt) QueryRow(args ...interface{}) *Row {
 	return s.QueryRowContext(context.Background(), args...)
 }
diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go
index c968852..f771dee 100644
--- a/src/database/sql/sql_test.go
+++ b/src/database/sql/sql_test.go
@@ -431,25 +431,24 @@
 	db := newTestDB(t, "people")
 	defer closeDB(t, db)
 
-	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Millisecond)
-	defer cancel()
+	ctx, cancel := context.WithCancel(context.Background())
 
 	tx, err := db.BeginTx(ctx, nil)
 	if err != nil {
-		// Guard against the context being canceled before BeginTx completes.
-		if err == context.DeadlineExceeded {
-			t.Skip("tx context canceled prior to first use")
-		}
 		t.Fatal(err)
 	}
 	tx.keepConnOnRollback = false
 
+	go func() {
+		time.Sleep(15 * time.Millisecond)
+		cancel()
+	}()
 	// This will trigger the *fakeConn.Prepare method which will take time
 	// performing the query. The ctxDriverPrepare func will check the context
 	// after this and close the rows and return an error.
 	_, err = tx.QueryContext(ctx, "WAIT|1s|SELECT|people|age,name|")
-	if err != context.DeadlineExceeded {
-		t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err)
+	if err != context.Canceled {
+		t.Fatalf("expected QueryContext to error with context canceled but returned %v", err)
 	}
 
 	waitForFree(t, db, 5*time.Second, 0)
@@ -657,7 +656,7 @@
 	db.SetMaxOpenConns(max)
 
 	// First saturate the connection pool.
-	// Then start new requests for a connection that is cancelled after it is requested.
+	// Then start new requests for a connection that is canceled after it is requested.
 
 	state = 1
 	for i := 0; i < max; i++ {
@@ -1820,6 +1819,30 @@
 	nullTestRun(t, spec)
 }
 
+func TestNullInt16Param(t *testing.T) {
+	spec := nullTestSpec{"nullint16", "int16", [6]nullTestRow{
+		{NullInt16{31, true}, 1, NullInt16{31, true}},
+		{NullInt16{-22, false}, 1, NullInt16{0, false}},
+		{22, 1, NullInt16{22, true}},
+		{NullInt16{33, true}, 1, NullInt16{33, true}},
+		{NullInt16{222, false}, 1, NullInt16{0, false}},
+		{0, NullInt16{31, false}, nil},
+	}}
+	nullTestRun(t, spec)
+}
+
+func TestNullByteParam(t *testing.T) {
+	spec := nullTestSpec{"nullbyte", "byte", [6]nullTestRow{
+		{NullByte{31, true}, 1, NullByte{31, true}},
+		{NullByte{0, false}, 1, NullByte{0, false}},
+		{22, 1, NullByte{22, true}},
+		{NullByte{33, true}, 1, NullByte{33, true}},
+		{NullByte{222, false}, 1, NullByte{0, false}},
+		{0, NullByte{31, false}, nil},
+	}}
+	nullTestRun(t, spec)
+}
+
 func TestNullFloat64Param(t *testing.T) {
 	spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{
 		{NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}},
@@ -2785,7 +2808,7 @@
 	// 3. Check if 2.A has committed in Tx (pass) or outside of Tx (fail).
 	sendQuery := make(chan struct{})
 	// The Tx status is returned through the row results, ensure
-	// that the rows results are not cancelled.
+	// that the rows results are not canceled.
 	bypassRowsAwaitDone = true
 	hookTxGrabConn = func() {
 		cancel()
@@ -2815,7 +2838,7 @@
 	db := newTestDB(t, "people")
 	defer closeDB(t, db)
 
-	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond)
+	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
 	tx, err := db.BeginTx(ctx, nil)
 	if err != nil {
@@ -2826,6 +2849,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+	cancel()
 	// Run number of stmt queries to reproduce deadlock from context cancel
 	for i := 0; i < 1e3; i++ {
 		// Encounter any close related errors (e.g. ErrTxDone, stmt is closed)
@@ -4060,9 +4084,18 @@
 	}
 	defer db.Close()
 
-	if _, is := db.connector.(*fakeConnector); !is {
+	c, ok := db.connector.(*fakeConnector)
+	if !ok {
 		t.Fatal("not using *fakeConnector")
 	}
+
+	if err := db.Close(); err != nil {
+		t.Fatal(err)
+	}
+
+	if !c.closed {
+		t.Fatal("connector is not closed")
+	}
 }
 
 type ctxOnlyDriver struct {
diff --git a/src/debug/dwarf/const.go b/src/debug/dwarf/const.go
index c607091..c0a74b0 100644
--- a/src/debug/dwarf/const.go
+++ b/src/debug/dwarf/const.go
@@ -427,7 +427,7 @@
 	lneSetDiscriminator = 4
 )
 
-// Line table directory directory and file name entry formats.
+// Line table directory and file name entry formats.
 // These are new in DWARF 5.
 const (
 	lnctPath           = 0x01
diff --git a/src/debug/dwarf/entry.go b/src/debug/dwarf/entry.go
index 3fc73b8..9f5ac57 100644
--- a/src/debug/dwarf/entry.go
+++ b/src/debug/dwarf/entry.go
@@ -317,7 +317,7 @@
 	// the "mac" section.
 	ClassMacPtr
 
-	// ClassMacPtr represents values that are an int64 offset into
+	// ClassRangeListPtr represents values that are an int64 offset into
 	// the "rangelist" section.
 	ClassRangeListPtr
 
@@ -355,7 +355,7 @@
 	// into the "loclists" section.
 	ClassLocList
 
-	// ClassRngList represents values that are an int64 offset
+	// ClassRngList represents values that are a uint64 offset
 	// from the base of the "rnglists" section.
 	ClassRngList
 
@@ -464,6 +464,35 @@
 		return val
 	}
 
+	resolveRnglistx := func(rnglistsBase, off uint64) uint64 {
+		is64, _ := b.format.dwarf64()
+		if is64 {
+			off *= 8
+		} else {
+			off *= 4
+		}
+		off += rnglistsBase
+		if uint64(int(off)) != off {
+			b.error("DW_FORM_rnglistx offset out of range")
+		}
+
+		b1 := makeBuf(b.dwarf, b.format, "rnglists", 0, b.dwarf.rngLists)
+		b1.skip(int(off))
+		if is64 {
+			off = b1.uint64()
+		} else {
+			off = uint64(b1.uint32())
+		}
+		if b1.err != nil {
+			b.err = b1.err
+			return 0
+		}
+		if uint64(int(off)) != off {
+			b.error("DW_FORM_rnglistx indirect offset out of range")
+		}
+		return rnglistsBase + off
+	}
+
 	for i := range e.Field {
 		e.Field[i].Attr = a.field[i].attr
 		e.Field[i].Class = a.field[i].class
@@ -709,7 +738,21 @@
 
 		// rnglist
 		case formRnglistx:
-			val = b.uint()
+			off := b.uint()
+
+			// We have to adjust by the rnglists_base of
+			// the compilation unit. This won't work if
+			// the program uses Reader.Seek to skip over
+			// the unit. Not much we can do about that.
+			var rnglistsBase int64
+			if cu != nil {
+				rnglistsBase, _ = cu.Val(AttrRnglistsBase).(int64)
+			} else if a.tag == TagCompileUnit {
+				delay = append(delay, delayed{i, off, formRnglistx})
+				break
+			}
+
+			val = resolveRnglistx(uint64(rnglistsBase), off)
 		}
 
 		e.Field[i].Val = val
@@ -734,6 +777,12 @@
 			if b.err != nil {
 				return nil
 			}
+		case formRnglistx:
+			rnglistsBase, _ := e.Val(AttrRnglistsBase).(int64)
+			e.Field[del.idx].Val = resolveRnglistx(uint64(rnglistsBase), del.off)
+			if b.err != nil {
+				return nil
+			}
 		}
 	}
 
@@ -993,8 +1042,15 @@
 			return d.dwarf5Ranges(u, cu, base, ranges, ret)
 
 		case ClassRngList:
-			// TODO: support DW_FORM_rnglistx
-			return ret, nil
+			rnglist, ok := field.Val.(uint64)
+			if !ok {
+				return ret, nil
+			}
+			cu, base, err := d.baseAddressForEntry(e)
+			if err != nil {
+				return nil, err
+			}
+			return d.dwarf5Ranges(u, cu, base, int64(rnglist), ret)
 
 		default:
 			return ret, nil
diff --git a/src/debug/dwarf/entry_test.go b/src/debug/dwarf/entry_test.go
index b54f8b4..1f41d74 100644
--- a/src/debug/dwarf/entry_test.go
+++ b/src/debug/dwarf/entry_test.go
@@ -84,6 +84,19 @@
 	testRanges(t, "testdata/ranges.elf", want)
 }
 
+func TestRangesRnglistx(t *testing.T) {
+	want := []wantRange{
+		{0x401000, [][2]uint64{{0x401020, 0x40102c}, {0x401000, 0x40101d}}},
+		{0x40101c, [][2]uint64{{0x401020, 0x40102c}, {0x401000, 0x40101d}}},
+		{0x40101d, nil},
+		{0x40101f, nil},
+		{0x401020, [][2]uint64{{0x401020, 0x40102c}, {0x401000, 0x40101d}}},
+		{0x40102b, [][2]uint64{{0x401020, 0x40102c}, {0x401000, 0x40101d}}},
+		{0x40102c, nil},
+	}
+	testRanges(t, "testdata/rnglistx.elf", want)
+}
+
 func testRanges(t *testing.T, name string, want []wantRange) {
 	d := elfData(t, name)
 	r := d.Reader()
diff --git a/src/debug/dwarf/line_test.go b/src/debug/dwarf/line_test.go
index b13818e..9c6b6ff 100644
--- a/src/debug/dwarf/line_test.go
+++ b/src/debug/dwarf/line_test.go
@@ -117,6 +117,29 @@
 	testLineTable(t, want, files, elfData(t, "testdata/line-clang.elf"))
 }
 
+func TestLineRnglists(t *testing.T) {
+	// Test a newer file, generated by clang.
+	file := &LineFile{Name: "/usr/local/google/home/iant/foo.c"}
+	want := []LineEntry{
+		{Address: 0x401020, File: file, Line: 12, IsStmt: true},
+		{Address: 0x401020, File: file, Line: 13, Column: 12, IsStmt: true, PrologueEnd: true},
+		{Address: 0x401022, File: file, Line: 13, Column: 7},
+		{Address: 0x401024, File: file, Line: 17, Column: 1, IsStmt: true},
+		{Address: 0x401027, File: file, Line: 16, Column: 10, IsStmt: true},
+		{Address: 0x40102c, EndSequence: true},
+		{Address: 0x401000, File: file, Line: 2, IsStmt: true},
+		{Address: 0x401000, File: file, Line: 6, Column: 17, IsStmt: true, PrologueEnd: true},
+		{Address: 0x401002, File: file, Line: 6, Column: 3},
+		{Address: 0x401019, File: file, Line: 9, Column: 3, IsStmt: true},
+		{Address: 0x40101a, File: file, Line: 0, Column: 3},
+		{Address: 0x40101c, File: file, Line: 9, Column: 3},
+		{Address: 0x40101d, EndSequence: true},
+	}
+	files := [][]*LineFile{{file}}
+
+	testLineTable(t, want, files, elfData(t, "testdata/rnglistx.elf"))
+}
+
 func TestLineSeek(t *testing.T) {
 	d := elfData(t, "testdata/line-gcc.elf")
 
diff --git a/src/debug/dwarf/testdata/rnglistx.c b/src/debug/dwarf/testdata/rnglistx.c
new file mode 100644
index 0000000..8770435
--- /dev/null
+++ b/src/debug/dwarf/testdata/rnglistx.c
@@ -0,0 +1,19 @@
+// clang -gdwarf-5 -O2 -nostdlib
+
+__attribute__((noinline, cold))
+static int sum(int i) {
+  int j, s;
+
+  s = 0;
+  for (j = 0; j < i; j++) {
+    s += j * i;
+  }
+  return s;
+}
+
+int main(int argc, char** argv) {
+  if (argc == 0) {
+    return 0;
+  }
+  return sum(argc);
+}
diff --git a/src/debug/dwarf/testdata/rnglistx.elf b/src/debug/dwarf/testdata/rnglistx.elf
new file mode 100755
index 0000000..c2d7f55
--- /dev/null
+++ b/src/debug/dwarf/testdata/rnglistx.elf
Binary files differ
diff --git a/src/debug/dwarf/type.go b/src/debug/dwarf/type.go
index 316db25..eb5a666 100644
--- a/src/debug/dwarf/type.go
+++ b/src/debug/dwarf/type.go
@@ -292,11 +292,35 @@
 	return d.readType("info", d.Reader(), off, d.typeCache, nil)
 }
 
+type typeFixer struct {
+	typedefs   []*TypedefType
+	arraytypes []*Type
+}
+
+func (tf *typeFixer) recordArrayType(t *Type) {
+	if t == nil {
+		return
+	}
+	_, ok := (*t).(*ArrayType)
+	if ok {
+		tf.arraytypes = append(tf.arraytypes, t)
+	}
+}
+
+func (tf *typeFixer) apply() {
+	for _, t := range tf.typedefs {
+		t.Common().ByteSize = t.Type.Size()
+	}
+	for _, t := range tf.arraytypes {
+		zeroArray(t)
+	}
+}
+
 // readType reads a type from r at off of name. It adds types to the
 // type cache, appends new typedef types to typedefs, and computes the
 // sizes of types. Callers should pass nil for typedefs; this is used
 // for internal recursion.
-func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type, typedefs *[]*TypedefType) (Type, error) {
+func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type, fixups *typeFixer) (Type, error) {
 	if t, ok := typeCache[off]; ok {
 		return t, nil
 	}
@@ -311,18 +335,16 @@
 	}
 
 	// If this is the root of the recursion, prepare to resolve
-	// typedef sizes once the recursion is done. This must be done
-	// after the type graph is constructed because it may need to
-	// resolve cycles in a different order than readType
-	// encounters them.
-	if typedefs == nil {
-		var typedefList []*TypedefType
+	// typedef sizes and perform other fixups once the recursion is
+	// done. This must be done after the type graph is constructed
+	// because it may need to resolve cycles in a different order than
+	// readType encounters them.
+	if fixups == nil {
+		var fixer typeFixer
 		defer func() {
-			for _, t := range typedefList {
-				t.Common().ByteSize = t.Type.Size()
-			}
+			fixer.apply()
 		}()
-		typedefs = &typedefList
+		fixups = &fixer
 	}
 
 	// Parse type from Entry.
@@ -376,7 +398,7 @@
 		var t Type
 		switch toff := tval.(type) {
 		case Offset:
-			if t, err = d.readType(name, r.clone(), toff, typeCache, typedefs); err != nil {
+			if t, err = d.readType(name, r.clone(), toff, typeCache, fixups); err != nil {
 				return nil
 			}
 		case uint64:
@@ -567,7 +589,7 @@
 			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)
+				fixups.recordArrayType(lastFieldType)
 			}
 			lastFieldType = &f.Type
 			lastFieldBitOffset = bito
@@ -576,7 +598,7 @@
 			b, ok := e.Val(AttrByteSize).(int64)
 			if ok && b*8 == lastFieldBitOffset {
 				// Final field must be zero width. Fix array length.
-				zeroArray(lastFieldType)
+				fixups.recordArrayType(lastFieldType)
 			}
 		}
 
@@ -719,7 +741,7 @@
 				// Record that we need to resolve this
 				// type's size once the type graph is
 				// constructed.
-				*typedefs = append(*typedefs, t)
+				fixups.typedefs = append(fixups.typedefs, t)
 			case *PtrType:
 				b = int64(addressSize)
 			}
@@ -737,11 +759,8 @@
 }
 
 func zeroArray(t *Type) {
-	if t == nil {
-		return
-	}
-	at, ok := (*t).(*ArrayType)
-	if !ok || at.Type.Size() == 0 {
+	at := (*t).(*ArrayType)
+	if at.Type.Size() == 0 {
 		return
 	}
 	// Make a copy to avoid invalidating typeCache.
diff --git a/src/debug/dwarf/unit.go b/src/debug/dwarf/unit.go
index 29a744f..9b3d6e9 100644
--- a/src/debug/dwarf/unit.go
+++ b/src/debug/dwarf/unit.go
@@ -48,7 +48,9 @@
 			break
 		}
 		b.skip(int(len))
-		nunit++
+		if len > 0 {
+			nunit++
+		}
 	}
 	if b.err != nil {
 		return nil, b.err
@@ -61,7 +63,9 @@
 		u := &units[i]
 		u.base = b.off
 		var n Offset
-		n, u.is64 = b.unitLength()
+		for n == 0 {
+			n, u.is64 = b.unitLength()
+		}
 		dataOff := b.off
 		vers := b.uint16()
 		if vers < 2 || vers > 5 {
diff --git a/src/debug/elf/elf.go b/src/debug/elf/elf.go
index 2b777ea..9f8399d 100644
--- a/src/debug/elf/elf.go
+++ b/src/debug/elf/elf.go
@@ -123,8 +123,8 @@
 	ELFOSABI_NONE       OSABI = 0   /* UNIX System V ABI */
 	ELFOSABI_HPUX       OSABI = 1   /* HP-UX operating system */
 	ELFOSABI_NETBSD     OSABI = 2   /* NetBSD */
-	ELFOSABI_LINUX      OSABI = 3   /* GNU/Linux */
-	ELFOSABI_HURD       OSABI = 4   /* GNU/Hurd */
+	ELFOSABI_LINUX      OSABI = 3   /* Linux */
+	ELFOSABI_HURD       OSABI = 4   /* Hurd */
 	ELFOSABI_86OPEN     OSABI = 5   /* 86Open common IA32 ABI */
 	ELFOSABI_SOLARIS    OSABI = 6   /* Solaris */
 	ELFOSABI_AIX        OSABI = 7   /* AIX */
@@ -644,6 +644,7 @@
 	SHT_GNU_VERSYM     SectionType = 0x6fffffff /* GNU version symbol table */
 	SHT_HIOS           SectionType = 0x6fffffff /* Last of OS specific semantics */
 	SHT_LOPROC         SectionType = 0x70000000 /* reserved range for processor */
+	SHT_MIPS_ABIFLAGS  SectionType = 0x7000002a /* .MIPS.abiflags */
 	SHT_HIPROC         SectionType = 0x7fffffff /* specific section header types */
 	SHT_LOUSER         SectionType = 0x80000000 /* reserved range for application */
 	SHT_HIUSER         SectionType = 0xffffffff /* specific indexes */
@@ -675,6 +676,7 @@
 	{0x6ffffffe, "SHT_GNU_VERNEED"},
 	{0x6fffffff, "SHT_GNU_VERSYM"},
 	{0x70000000, "SHT_LOPROC"},
+	{0x7000002a, "SHT_MIPS_ABIFLAGS"},
 	{0x7fffffff, "SHT_HIPROC"},
 	{0x80000000, "SHT_LOUSER"},
 	{0xffffffff, "SHT_HIUSER"},
diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go
index cd5bf8f..b25d820 100644
--- a/src/debug/elf/file.go
+++ b/src/debug/elf/file.go
@@ -1164,6 +1164,13 @@
 			b = dbuf
 		}
 
+		if f.Type == ET_EXEC {
+			// Do not apply relocations to DWARF sections for ET_EXEC binaries.
+			// Relocations should already be applied, and .rela sections may
+			// contain incorrect data.
+			return b, nil
+		}
+
 		for _, r := range f.Sections {
 			if r.Type != SHT_RELA && r.Type != SHT_REL {
 				continue
diff --git a/src/debug/macho/macho.go b/src/debug/macho/macho.go
index 49e107e..9fa9f95 100644
--- a/src/debug/macho/macho.go
+++ b/src/debug/macho/macho.go
@@ -4,7 +4,7 @@
 
 // Mach-O header data structures
 // Originally at:
-// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html (since deleted by Apply)
+// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html (since deleted by Apple)
 // Archived copy at:
 // https://web.archive.org/web/20090819232456/http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/index.html
 // For cloned PDF see:
diff --git a/src/debug/pe/file.go b/src/debug/pe/file.go
index 7d763ff..e50229e 100644
--- a/src/debug/pe/file.go
+++ b/src/debug/pe/file.go
@@ -75,7 +75,7 @@
 		var sign [4]byte
 		r.ReadAt(sign[:], signoff)
 		if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) {
-			return nil, fmt.Errorf("Invalid PE COFF file signature of %v.", sign)
+			return nil, fmt.Errorf("invalid PE file signature: % x", sign)
 		}
 		base = signoff + 4
 	} else {
@@ -86,9 +86,14 @@
 		return nil, err
 	}
 	switch f.FileHeader.Machine {
-	case IMAGE_FILE_MACHINE_UNKNOWN, IMAGE_FILE_MACHINE_ARMNT, IMAGE_FILE_MACHINE_AMD64, IMAGE_FILE_MACHINE_I386:
+	case IMAGE_FILE_MACHINE_AMD64,
+		IMAGE_FILE_MACHINE_ARM64,
+		IMAGE_FILE_MACHINE_ARMNT,
+		IMAGE_FILE_MACHINE_I386,
+		IMAGE_FILE_MACHINE_UNKNOWN:
+		// ok
 	default:
-		return nil, fmt.Errorf("Unrecognised COFF file header machine value of 0x%x.", f.FileHeader.Machine)
+		return nil, fmt.Errorf("unrecognized PE machine: %#x", f.FileHeader.Machine)
 	}
 
 	var err error
@@ -112,7 +117,7 @@
 	// Seek past file header.
 	_, err = sr.Seek(base+int64(binary.Size(f.FileHeader)), seekStart)
 	if err != nil {
-		return nil, fmt.Errorf("failure to seek past the file header: %v", err)
+		return nil, err
 	}
 
 	// Read optional header.
@@ -309,7 +314,7 @@
 		return nil, nil
 	}
 
-	pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64
+	pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64 || f.Machine == IMAGE_FILE_MACHINE_ARM64
 
 	// grab the number of data directory entries
 	var dd_length uint32
diff --git a/src/debug/pe/file_cgo_test.go b/src/debug/pe/file_cgo_test.go
index 739671d..13eb4e6 100644
--- a/src/debug/pe/file_cgo_test.go
+++ b/src/debug/pe/file_cgo_test.go
@@ -2,12 +2,14 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo
 // +build cgo
 
 package pe
 
 import (
 	"os/exec"
+	"runtime"
 	"testing"
 )
 
@@ -23,6 +25,9 @@
 }
 
 func TestInternalLinkerDWARF(t *testing.T) {
+	if runtime.GOARCH == "arm64" {
+		t.Skip("internal linker disabled on windows/arm64")
+	}
 	testCgoDWARF(t, linkCgoInternal)
 }
 
diff --git a/src/debug/pe/file_test.go b/src/debug/pe/file_test.go
index 58deff1..8964b4f 100644
--- a/src/debug/pe/file_test.go
+++ b/src/debug/pe/file_test.go
@@ -353,11 +353,7 @@
 	}
 	testenv.MustHaveGoRun(t)
 
-	tmpdir, err := os.MkdirTemp("", "TestDWARF")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "a.go")
 	file, err := os.Create(src)
@@ -472,11 +468,7 @@
 		t.Skip("skipping test: gcc is missing")
 	}
 
-	tmpdir, err := os.MkdirTemp("", "TestBSSHasZeros")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	srcpath := filepath.Join(tmpdir, "a.c")
 	src := `
@@ -596,15 +588,10 @@
 	if runtime.GOOS != "windows" {
 		t.Skip("skipping windows only test")
 	}
-	tmpdir, err := os.MkdirTemp("", "TestBuildingWindowsGUI")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "a.go")
-	err = os.WriteFile(src, []byte(`package main; func main() {}`), 0644)
-	if err != nil {
+	if err := os.WriteFile(src, []byte(`package main; func main() {}`), 0644); err != nil {
 		t.Fatal(err)
 	}
 	exe := filepath.Join(tmpdir, "a.exe")
diff --git a/src/embed/embed.go b/src/embed/embed.go
index 98da870..851cc21 100644
--- a/src/embed/embed.go
+++ b/src/embed/embed.go
@@ -143,7 +143,7 @@
 // See the package documentation for more details about initializing an FS.
 type FS struct {
 	// The compiler knows the layout of this struct.
-	// See cmd/compile/internal/gc's initEmbed.
+	// See cmd/compile/internal/staticdata's WriteEmbed.
 	//
 	// The files list is sorted by name but not by simple string comparison.
 	// Instead, each file's name takes the form "dir/elem" or "dir/elem/".
@@ -213,7 +213,7 @@
 // It implements fs.FileInfo and fs.DirEntry.
 type file struct {
 	// The compiler knows the layout of this struct.
-	// See cmd/compile/internal/gc's initEmbed.
+	// See cmd/compile/internal/staticdata's WriteEmbed.
 	name string
 	data string
 	hash [16]byte // truncated SHA256 hash
@@ -386,15 +386,15 @@
 
 func (d *openDir) ReadDir(count int) ([]fs.DirEntry, error) {
 	n := len(d.files) - d.offset
-	if count > 0 && n > count {
-		n = count
-	}
 	if n == 0 {
 		if count <= 0 {
 			return nil, nil
 		}
 		return nil, io.EOF
 	}
+	if count > 0 && n > count {
+		n = count
+	}
 	list := make([]fs.DirEntry, n)
 	for i := range list {
 		list[i] = &d.files[d.offset+i]
diff --git a/src/embed/internal/embedtest/embed_test.go b/src/embed/internal/embedtest/embed_test.go
index 43ae5c7..2d50f5e 100644
--- a/src/embed/internal/embedtest/embed_test.go
+++ b/src/embed/internal/embedtest/embed_test.go
@@ -102,12 +102,12 @@
 	t.Logf("//go:embed testdata")
 
 	testDir(t, dir, "testdata",
-		"ascii.txt", "glass.txt", "hello.txt", "i/", "ken.txt")
+		"-not-hidden/", "ascii.txt", "glass.txt", "hello.txt", "i/", "ken.txt")
 
 	t.Logf("//go:embed testdata/*")
 
 	testDir(t, star, "testdata",
-		".hidden/", "_hidden/", "ascii.txt", "glass.txt", "hello.txt", "i/", "ken.txt")
+		"-not-hidden/", ".hidden/", "_hidden/", "ascii.txt", "glass.txt", "hello.txt", "i/", "ken.txt")
 
 	testDir(t, star, "testdata/.hidden",
 		"fortune.txt", "more/") // but not .more or _more
diff --git a/src/embed/internal/embedtest/testdata/-not-hidden/fortune.txt b/src/embed/internal/embedtest/testdata/-not-hidden/fortune.txt
new file mode 100644
index 0000000..31f2013
--- /dev/null
+++ b/src/embed/internal/embedtest/testdata/-not-hidden/fortune.txt
@@ -0,0 +1,2 @@
+WARNING: terminal is not fully functional
+ -  (press RETURN)
diff --git a/src/encoding/asn1/asn1.go b/src/encoding/asn1/asn1.go
index f9b9cb4..cffc06d 100644
--- a/src/encoding/asn1/asn1.go
+++ b/src/encoding/asn1/asn1.go
@@ -914,7 +914,7 @@
 		structType := fieldType
 
 		for i := 0; i < structType.NumField(); i++ {
-			if structType.Field(i).PkgPath != "" {
+			if !structType.Field(i).IsExported() {
 				err = StructuralError{"struct contains unexported fields"}
 				return
 			}
diff --git a/src/encoding/asn1/marshal.go b/src/encoding/asn1/marshal.go
index 0d34d5a..5b4d786 100644
--- a/src/encoding/asn1/marshal.go
+++ b/src/encoding/asn1/marshal.go
@@ -488,7 +488,7 @@
 		t := v.Type()
 
 		for i := 0; i < t.NumField(); i++ {
-			if t.Field(i).PkgPath != "" {
+			if !t.Field(i).IsExported() {
 				return nil, StructuralError{"struct contains unexported fields"}
 			}
 		}
diff --git a/src/encoding/asn1/marshal_test.go b/src/encoding/asn1/marshal_test.go
index e3a7d8f..f0217ba 100644
--- a/src/encoding/asn1/marshal_test.go
+++ b/src/encoding/asn1/marshal_test.go
@@ -306,7 +306,7 @@
 		return
 	}
 	if !reflect.DeepEqual(v, v1) {
-		t.Errorf("got: %#v data=%q , want : %#v data=%q\n ", v1, data1, v, data)
+		t.Errorf("got: %#v data=%q, want : %#v data=%q\n ", v1, data1, v, data)
 	}
 }
 
diff --git a/src/encoding/binary/varint.go b/src/encoding/binary/varint.go
index 1fa325d..8fe20b5 100644
--- a/src/encoding/binary/varint.go
+++ b/src/encoding/binary/varint.go
@@ -61,8 +61,13 @@
 	var x uint64
 	var s uint
 	for i, b := range buf {
+		if i == MaxVarintLen64 {
+			// Catch byte reads past MaxVarintLen64.
+			// See issue https://golang.org/issues/41185
+			return 0, -(i + 1) // overflow
+		}
 		if b < 0x80 {
-			if i >= MaxVarintLen64 || i == MaxVarintLen64-1 && b > 1 {
+			if i == MaxVarintLen64-1 && b > 1 {
 				return 0, -(i + 1) // overflow
 			}
 			return x | uint64(b)<<s, i + 1
diff --git a/src/encoding/binary/varint_test.go b/src/encoding/binary/varint_test.go
index 6ef4c99..d025a67 100644
--- a/src/encoding/binary/varint_test.go
+++ b/src/encoding/binary/varint_test.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"io"
+	"math"
 	"testing"
 )
 
@@ -121,10 +122,66 @@
 	}
 }
 
+// Ensure that we catch overflows of bytes going past MaxVarintLen64.
+// See issue https://golang.org/issues/41185
+func TestBufferTooBigWithOverflow(t *testing.T) {
+	tests := []struct {
+		in        []byte
+		name      string
+		wantN     int
+		wantValue uint64
+	}{
+		{
+			name: "invalid: 1000 bytes",
+			in: func() []byte {
+				b := make([]byte, 1000)
+				for i := range b {
+					b[i] = 0xff
+				}
+				b[999] = 0
+				return b
+			}(),
+			wantN:     -11,
+			wantValue: 0,
+		},
+		{
+			name:      "valid: math.MaxUint64-40",
+			in:        []byte{0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
+			wantValue: math.MaxUint64 - 40,
+			wantN:     10,
+		},
+		{
+			name:      "invalid: with more than MaxVarintLen64 bytes",
+			in:        []byte{0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
+			wantN:     -11,
+			wantValue: 0,
+		},
+		{
+			name:      "invalid: 10th byte",
+			in:        []byte{0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f},
+			wantN:     -10,
+			wantValue: 0,
+		},
+	}
+
+	for _, tt := range tests {
+		tt := tt
+		t.Run(tt.name, func(t *testing.T) {
+			value, n := Uvarint(tt.in)
+			if g, w := n, tt.wantN; g != w {
+				t.Errorf("bytes returned=%d, want=%d", g, w)
+			}
+			if g, w := value, tt.wantValue; g != w {
+				t.Errorf("value=%d, want=%d", g, w)
+			}
+		})
+	}
+}
+
 func testOverflow(t *testing.T, buf []byte, x0 uint64, n0 int, err0 error) {
 	x, n := Uvarint(buf)
 	if x != 0 || n != n0 {
-		t.Errorf("Uvarint(%v): got x = %d, n = %d; want 0, %d", buf, x, n, n0)
+		t.Errorf("Uvarint(% X): got x = %d, n = %d; want 0, %d", buf, x, n, n0)
 	}
 
 	r := bytes.NewReader(buf)
@@ -140,8 +197,8 @@
 
 func TestOverflow(t *testing.T) {
 	testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x2}, 0, -10, overflow)
-	testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1, 0, 0}, 0, -13, overflow)
-	testOverflow(t, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 1<<64-1, 0, overflow) // 11 bytes, should overflow
+	testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1, 0, 0}, 0, -11, overflow)
+	testOverflow(t, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 1<<64-1, -11, overflow) // 11 bytes, should overflow
 }
 
 func TestNonCanonicalZero(t *testing.T) {
diff --git a/src/encoding/csv/fuzz.go b/src/encoding/csv/fuzz.go
index 8be21d5..a03fa83 100644
--- a/src/encoding/csv/fuzz.go
+++ b/src/encoding/csv/fuzz.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gofuzz
 // +build gofuzz
 
 package csv
diff --git a/src/encoding/csv/reader.go b/src/encoding/csv/reader.go
index c40aa50..f860f4f 100644
--- a/src/encoding/csv/reader.go
+++ b/src/encoding/csv/reader.go
@@ -66,7 +66,7 @@
 type ParseError struct {
 	StartLine int   // Line where the record starts
 	Line      int   // Line where the error occurred
-	Column    int   // Column (rune index) where the error occurred
+	Column    int   // Column (1-based byte index) where the error occurred
 	Err       error // The actual error
 }
 
@@ -162,6 +162,10 @@
 	// The i'th field ends at offset fieldIndexes[i] in recordBuffer.
 	fieldIndexes []int
 
+	// fieldPositions is an index of field positions for the
+	// last record returned by Read.
+	fieldPositions []position
+
 	// lastRecord is a record cache and only used when ReuseRecord == true.
 	lastRecord []string
 }
@@ -192,6 +196,25 @@
 	return record, err
 }
 
+// FieldPos returns the line and column corresponding to
+// the start of the field with the given index in the slice most recently
+// returned by Read. Numbering of lines and columns starts at 1;
+// columns are counted in bytes, not runes.
+//
+// If this is called with an out-of-bounds index, it panics.
+func (r *Reader) FieldPos(field int) (line, column int) {
+	if field < 0 || field >= len(r.fieldPositions) {
+		panic("out of range index passed to FieldPos")
+	}
+	p := &r.fieldPositions[field]
+	return p.line, p.col
+}
+
+// pos holds the position of a field in the current line.
+type position struct {
+	line, col int
+}
+
 // ReadAll reads all the remaining records from r.
 // Each record is a slice of fields.
 // A successful call returns err == nil, not err == io.EOF. Because ReadAll is
@@ -260,7 +283,7 @@
 	}
 
 	// Read line (automatically skipping past empty lines and any comments).
-	var line, fullLine []byte
+	var line []byte
 	var errRead error
 	for errRead == nil {
 		line, errRead = r.readLine()
@@ -272,7 +295,6 @@
 			line = nil
 			continue // Skip empty lines
 		}
-		fullLine = line
 		break
 	}
 	if errRead == io.EOF {
@@ -286,10 +308,20 @@
 	recLine := r.numLine // Starting line for record
 	r.recordBuffer = r.recordBuffer[:0]
 	r.fieldIndexes = r.fieldIndexes[:0]
+	r.fieldPositions = r.fieldPositions[:0]
+	pos := position{line: r.numLine, col: 1}
 parseField:
 	for {
 		if r.TrimLeadingSpace {
-			line = bytes.TrimLeftFunc(line, unicode.IsSpace)
+			i := bytes.IndexFunc(line, func(r rune) bool {
+				return !unicode.IsSpace(r)
+			})
+			if i < 0 {
+				i = len(line)
+				pos.col -= lengthNL(line)
+			}
+			line = line[i:]
+			pos.col += i
 		}
 		if len(line) == 0 || line[0] != '"' {
 			// Non-quoted string field
@@ -303,48 +335,56 @@
 			// 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:])])
+					col := pos.col + 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))
+			r.fieldPositions = append(r.fieldPositions, pos)
 			if i >= 0 {
 				line = line[i+commaLen:]
+				pos.col += i + commaLen
 				continue parseField
 			}
 			break parseField
 		} else {
 			// Quoted string field
+			fieldPos := pos
 			line = line[quoteLen:]
+			pos.col += quoteLen
 			for {
 				i := bytes.IndexByte(line, '"')
 				if i >= 0 {
 					// Hit next quote.
 					r.recordBuffer = append(r.recordBuffer, line[:i]...)
 					line = line[i+quoteLen:]
+					pos.col += i + quoteLen
 					switch rn := nextRune(line); {
 					case rn == '"':
 						// `""` sequence (append quote).
 						r.recordBuffer = append(r.recordBuffer, '"')
 						line = line[quoteLen:]
+						pos.col += quoteLen
 					case rn == r.Comma:
 						// `",` sequence (end of field).
 						line = line[commaLen:]
+						pos.col += commaLen
 						r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
+						r.fieldPositions = append(r.fieldPositions, fieldPos)
 						continue parseField
 					case lengthNL(line) == len(line):
 						// `"\n` sequence (end of line).
 						r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
+						r.fieldPositions = append(r.fieldPositions, fieldPos)
 						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}
+						err = &ParseError{StartLine: recLine, Line: r.numLine, Column: pos.col - quoteLen, Err: ErrQuote}
 						break parseField
 					}
 				} else if len(line) > 0 {
@@ -353,19 +393,23 @@
 					if errRead != nil {
 						break parseField
 					}
+					pos.col += len(line)
 					line, errRead = r.readLine()
+					if len(line) > 0 {
+						pos.line++
+						pos.col = 1
+					}
 					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}
+						err = &ParseError{StartLine: recLine, Line: pos.line, Column: pos.col, Err: ErrQuote}
 						break parseField
 					}
 					r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
+					r.fieldPositions = append(r.fieldPositions, fieldPos)
 					break parseField
 				}
 			}
@@ -392,7 +436,12 @@
 	// Check or update the expected fields per record.
 	if r.FieldsPerRecord > 0 {
 		if len(dst) != r.FieldsPerRecord && err == nil {
-			err = &ParseError{StartLine: recLine, Line: recLine, Err: ErrFieldCount}
+			err = &ParseError{
+				StartLine: recLine,
+				Line:      recLine,
+				Column:    1,
+				Err:       ErrFieldCount,
+			}
 		}
 	} else if r.FieldsPerRecord == 0 {
 		r.FieldsPerRecord = len(dst)
diff --git a/src/encoding/csv/reader_test.go b/src/encoding/csv/reader_test.go
index 5121791..abe3fdf 100644
--- a/src/encoding/csv/reader_test.go
+++ b/src/encoding/csv/reader_test.go
@@ -5,6 +5,8 @@
 package csv
 
 import (
+	"errors"
+	"fmt"
 	"io"
 	"reflect"
 	"strings"
@@ -12,405 +14,544 @@
 	"unicode/utf8"
 )
 
-func TestRead(t *testing.T) {
-	tests := []struct {
-		Name   string
-		Input  string
-		Output [][]string
-		Error  error
+type readTest struct {
+	Name      string
+	Input     string
+	Output    [][]string
+	Positions [][][2]int
+	Errors    []error
 
-		// 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",
-		Input: `#field1,field2,field3
-"aaa","bb
-b","ccc"
-"a,a","b""bb","ccc"
-zzz,yyy,xxx
+	// 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
+}
+
+// In these tests, the §, ¶ and ∑ characters in readTest.Input are used to denote
+// the start of a field, a record boundary and the position of an error respectively.
+// They are removed before parsing and are used to verify the position
+// information reported by FieldPos.
+
+var readTests = []readTest{{
+	Name:   "Simple",
+	Input:  "§a,§b,§c\n",
+	Output: [][]string{{"a", "b", "c"}},
+}, {
+	Name:   "CRLF",
+	Input:  "§a,§b\r\n¶§c,§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",
+	Input: `§#field1,§field2,§field3
+¶§"aaa",§"bb
+b",§"ccc"
+¶§"a,a",§"b""bb",§"ccc"
+¶§zzz,§yyy,§xxx
 `,
-		Output: [][]string{
-			{"#field1", "field2", "field3"},
-			{"aaa", "bb\nb", "ccc"},
-			{"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",
-		Input:  "a;b;c\n",
-		Output: [][]string{{"a", "b", "c"}},
-		Comma:  ';',
-	}, {
-		Name: "MultiLine",
-		Input: `"two
-line","one line","three
+	Output: [][]string{
+		{"#field1", "field2", "field3"},
+		{"aaa", "bb\nb", "ccc"},
+		{"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",
+	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",
-		Output: [][]string{
-			{"a", "b", "c"},
-			{"d", "e", "f"},
-		},
-		UseFieldsPerRecord: true,
-		FieldsPerRecord:    0,
-	}, {
-		Name:             "TrimSpace",
-		Input:            " a,  b,   c\n",
-		Output:           [][]string{{"a", "b", "c"}},
-		TrimLeadingSpace: true,
-	}, {
-		Name:   "LeadingSpace",
-		Input:  " a,  b,   c\n",
-		Output: [][]string{{" a", "  b", "   c"}},
-	}, {
-		Name:    "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",
-		Input:      `a "word","1"2",a","b`,
-		Output:     [][]string{{`a "word"`, `1"2`, `a"`, `b`}},
-		LazyQuotes: true,
-	}, {
-		Name:       "BareQuotes",
-		Input:      `a "word","1"2",a"`,
-		Output:     [][]string{{`a "word"`, `1"2`, `a"`}},
-		LazyQuotes: true,
-	}, {
-		Name:       "BareDoubleQuotes",
-		Input:      `a""b,c`,
-		Output:     [][]string{{`a""b`, `c`}},
-		LazyQuotes: true,
-	}, {
-		Name:  "BadDoubleQuotes",
-		Input: `a""b,c`,
-		Error: &ParseError{StartLine: 1, Line: 1, Column: 1, Err: ErrBareQuote},
-	}, {
-		Name:             "TrimQuote",
-		Input:            ` "a"," b",c`,
-		Output:           [][]string{{"a", " b", "c"}},
-		TrimLeadingSpace: true,
-	}, {
-		Name:  "BadBareQuote",
-		Input: `a "word","b"`,
-		Error: &ParseError{StartLine: 1, Line: 1, Column: 2, Err: ErrBareQuote},
-	}, {
-		Name:  "BadTrailingQuote",
-		Input: `"a word",b"`,
-		Error: &ParseError{StartLine: 1, Line: 1, Column: 10, Err: ErrBareQuote},
-	}, {
-		Name:  "ExtraneousQuote",
-		Input: `"a "word","b"`,
-		Error: &ParseError{StartLine: 1, Line: 1, Column: 3, Err: ErrQuote},
-	}, {
-		Name:               "BadFieldCount",
-		Input:              "a,b,c\nd,e",
-		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,
-	}, {
-		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",
-		Input:            "a,b,c, ",
-		Output:           [][]string{{"a", "b", "c", ""}},
-		TrimLeadingSpace: true,
-	}, {
-		Name:             "TrailingCommaSpaceEOL",
-		Input:            "a,b,c, \n",
-		Output:           [][]string{{"a", "b", "c", ""}},
-		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",
-		Input: `x,y,z,w
-x,y,z,
-x,y,,
-x,,,
-,,,
-"x","y","z","w"
-"x","y","z",""
-"x","y","",""
-"x","","",""
-"","","",""
+	Output: [][]string{{"two\nline", "one line", "three\nline\nfield"}},
+}, {
+	Name:  "BlankLine",
+	Input: "§a,§b,§c\n\n¶§d,§e,§f\n\n",
+	Output: [][]string{
+		{"a", "b", "c"},
+		{"d", "e", "f"},
+	},
+}, {
+	Name:  "BlankLineFieldCount",
+	Input: "§a,§b,§c\n\n¶§d,§e,§f\n\n",
+	Output: [][]string{
+		{"a", "b", "c"},
+		{"d", "e", "f"},
+	},
+	UseFieldsPerRecord: true,
+	FieldsPerRecord:    0,
+}, {
+	Name:             "TrimSpace",
+	Input:            " §a,  §b,   §c\n",
+	Output:           [][]string{{"a", "b", "c"}},
+	TrimLeadingSpace: true,
+}, {
+	Name:   "LeadingSpace",
+	Input:  "§ a,§  b,§   c\n",
+	Output: [][]string{{" a", "  b", "   c"}},
+}, {
+	Name:    "Comment",
+	Input:   "#1,2,3\n§a,§b,§c\n#comment",
+	Output:  [][]string{{"a", "b", "c"}},
+	Comment: '#',
+}, {
+	Name:   "NoComment",
+	Input:  "§#1,§2,§3\n¶§a,§b,§c",
+	Output: [][]string{{"#1", "2", "3"}, {"a", "b", "c"}},
+}, {
+	Name:       "LazyQuotes",
+	Input:      `§a "word",§"1"2",§a",§"b`,
+	Output:     [][]string{{`a "word"`, `1"2`, `a"`, `b`}},
+	LazyQuotes: true,
+}, {
+	Name:       "BareQuotes",
+	Input:      `§a "word",§"1"2",§a"`,
+	Output:     [][]string{{`a "word"`, `1"2`, `a"`}},
+	LazyQuotes: true,
+}, {
+	Name:       "BareDoubleQuotes",
+	Input:      `§a""b,§c`,
+	Output:     [][]string{{`a""b`, `c`}},
+	LazyQuotes: true,
+}, {
+	Name:   "BadDoubleQuotes",
+	Input:  `§a∑""b,c`,
+	Errors: []error{&ParseError{Err: ErrBareQuote}},
+}, {
+	Name:             "TrimQuote",
+	Input:            ` §"a",§" b",§c`,
+	Output:           [][]string{{"a", " b", "c"}},
+	TrimLeadingSpace: true,
+}, {
+	Name:   "BadBareQuote",
+	Input:  `§a ∑"word","b"`,
+	Errors: []error{&ParseError{Err: ErrBareQuote}},
+}, {
+	Name:   "BadTrailingQuote",
+	Input:  `§"a word",b∑"`,
+	Errors: []error{&ParseError{Err: ErrBareQuote}},
+}, {
+	Name:   "ExtraneousQuote",
+	Input:  `§"a ∑"word","b"`,
+	Errors: []error{&ParseError{Err: ErrQuote}},
+}, {
+	Name:               "BadFieldCount",
+	Input:              "§a,§b,§c\n¶∑§d,§e",
+	Errors:             []error{nil, &ParseError{Err: ErrFieldCount}},
+	Output:             [][]string{{"a", "b", "c"}, {"d", "e"}},
+	UseFieldsPerRecord: true,
+	FieldsPerRecord:    0,
+}, {
+	Name:               "BadFieldCountMultiple",
+	Input:              "§a,§b,§c\n¶∑§d,§e\n¶∑§f",
+	Errors:             []error{nil, &ParseError{Err: ErrFieldCount}, &ParseError{Err: ErrFieldCount}},
+	Output:             [][]string{{"a", "b", "c"}, {"d", "e"}, {"f"}},
+	UseFieldsPerRecord: true,
+	FieldsPerRecord:    0,
+}, {
+	Name:               "BadFieldCount1",
+	Input:              `§∑a,§b,§c`,
+	Errors:             []error{&ParseError{Err: ErrFieldCount}},
+	Output:             [][]string{{"a", "b", "c"}},
+	UseFieldsPerRecord: true,
+	FieldsPerRecord:    2,
+}, {
+	Name:   "FieldCount",
+	Input:  "§a,§b,§c\n¶§d,§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",
+	Input:            "§a,§b,§c, §",
+	Output:           [][]string{{"a", "b", "c", ""}},
+	TrimLeadingSpace: true,
+}, {
+	Name:             "TrailingCommaSpaceEOL",
+	Input:            "§a,§b,§c, §\n",
+	Output:           [][]string{{"a", "b", "c", ""}},
+	TrimLeadingSpace: true,
+}, {
+	Name:             "TrailingCommaLine3",
+	Input:            "§a,§b,§c\n¶§d,§e,§f\n¶§g,§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",
+	Input: `§x,§y,§z,§w
+¶§x,§y,§z,§
+¶§x,§y,§,§
+¶§x,§,§,§
+¶§,§,§,§
+¶§"x",§"y",§"z",§"w"
+¶§"x",§"y",§"z",§""
+¶§"x",§"y",§"",§""
+¶§"x",§"",§"",§""
+¶§"",§"",§"",§""
 `,
-		Output: [][]string{
-			{"x", "y", "z", "w"},
-			{"x", "y", "z", ""},
-			{"x", "y", "", ""},
-			{"x", "", "", ""},
-			{"", "", "", ""},
-			{"x", "y", "z", "w"},
-			{"x", "y", "z", ""},
-			{"x", "y", "", ""},
-			{"x", "", "", ""},
-			{"", "", "", ""},
-		},
-	}, {
-		Name:  "TrailingCommaIneffective1",
-		Input: "a,b,\nc,d,e",
-		Output: [][]string{
-			{"a", "b", ""},
-			{"c", "d", "e"},
-		},
-		TrimLeadingSpace: true,
-	}, {
-		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: '"',
-		Error: errInvalidDelim,
-	}, {
-		Name:  "BadComma4",
-		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,
-	}}
+	Output: [][]string{
+		{"x", "y", "z", "w"},
+		{"x", "y", "z", ""},
+		{"x", "y", "", ""},
+		{"x", "", "", ""},
+		{"", "", "", ""},
+		{"x", "y", "z", "w"},
+		{"x", "y", "z", ""},
+		{"x", "y", "", ""},
+		{"x", "", "", ""},
+		{"", "", "", ""},
+	},
+}, {
+	Name:  "TrailingCommaIneffective1",
+	Input: "§a,§b,§\n¶§c,§d,§e",
+	Output: [][]string{
+		{"a", "b", ""},
+		{"c", "d", "e"},
+	},
+	TrimLeadingSpace: true,
+}, {
+	Name:  "ReadAllReuseRecord",
+	Input: "§a,§b\n¶§c,§d",
+	Output: [][]string{
+		{"a", "b"},
+		{"c", "d"},
+	},
+	ReuseRecord: true,
+}, {
+	Name:   "StartLine1", // Issue 19019
+	Input:  "§a,\"b\nc∑\"d,e",
+	Errors: []error{&ParseError{Err: ErrQuote}},
+}, {
+	Name:   "StartLine2",
+	Input:  "§a,§b\n¶§\"d\n\n,e∑",
+	Errors: []error{nil, &ParseError{Err: ErrQuote}},
+	Output: [][]string{{"a", "b"}},
+}, {
+	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",
+	Errors: []error{&ParseError{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\n¶§field\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£ \t§d,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",
+	Errors: []error{&ParseError{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:  `§"""""""∑`,
+	Errors: []error{&ParseError{Err: ErrQuote}},
+}, {
+	Name:       "LazyOddQuotes",
+	Input:      `§"""""""`,
+	Output:     [][]string{{`"""`}},
+	LazyQuotes: true,
+}, {
+	Name:   "BadComma1",
+	Comma:  '\n',
+	Errors: []error{errInvalidDelim},
+}, {
+	Name:   "BadComma2",
+	Comma:  '\r',
+	Errors: []error{errInvalidDelim},
+}, {
+	Name:   "BadComma3",
+	Comma:  '"',
+	Errors: []error{errInvalidDelim},
+}, {
+	Name:   "BadComma4",
+	Comma:  utf8.RuneError,
+	Errors: []error{errInvalidDelim},
+}, {
+	Name:    "BadComment1",
+	Comment: '\n',
+	Errors:  []error{errInvalidDelim},
+}, {
+	Name:    "BadComment2",
+	Comment: '\r',
+	Errors:  []error{errInvalidDelim},
+}, {
+	Name:    "BadComment3",
+	Comment: utf8.RuneError,
+	Errors:  []error{errInvalidDelim},
+}, {
+	Name:    "BadCommaComment",
+	Comma:   'X',
+	Comment: 'X',
+	Errors:  []error{errInvalidDelim},
+}}
 
-	for _, tt := range tests {
+func TestRead(t *testing.T) {
+	newReader := func(tt readTest) (*Reader, [][][2]int, map[int][2]int) {
+		positions, errPositions, input := makePositions(tt.Input)
+		r := NewReader(strings.NewReader(input))
+
+		if tt.Comma != 0 {
+			r.Comma = tt.Comma
+		}
+		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
+		return r, positions, errPositions
+	}
+
+	for _, tt := range readTests {
 		t.Run(tt.Name, func(t *testing.T) {
-			r := NewReader(strings.NewReader(tt.Input))
-
-			if tt.Comma != 0 {
-				r.Comma = tt.Comma
-			}
-			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
-
+			r, positions, errPositions := newReader(tt)
 			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)
+			if wantErr := firstError(tt.Errors, positions, errPositions); wantErr != nil {
+				if !reflect.DeepEqual(err, wantErr) {
+					t.Fatalf("ReadAll() error mismatch:\ngot  %v (%#v)\nwant %v (%#v)", err, err, wantErr, wantErr)
+				}
+				if out != nil {
+					t.Fatalf("ReadAll() output:\ngot  %q\nwant nil", out)
+				}
+			} else {
+				if err != nil {
+					t.Fatalf("unexpected Readall() error: %v", err)
+				}
+				if !reflect.DeepEqual(out, tt.Output) {
+					t.Fatalf("ReadAll() output:\ngot  %q\nwant %q", out, tt.Output)
+				}
+			}
+
+			// Check field and error positions.
+			r, _, _ = newReader(tt)
+			for recNum := 0; ; recNum++ {
+				rec, err := r.Read()
+				var wantErr error
+				if recNum < len(tt.Errors) && tt.Errors[recNum] != nil {
+					wantErr = errorWithPosition(tt.Errors[recNum], recNum, positions, errPositions)
+				} else if recNum >= len(tt.Output) {
+					wantErr = io.EOF
+				}
+				if !reflect.DeepEqual(err, wantErr) {
+					t.Fatalf("Read() error at record %d:\ngot %v (%#v)\nwant %v (%#v)", recNum, err, err, wantErr, wantErr)
+				}
+				// ErrFieldCount is explicitly non-fatal.
+				if err != nil && !errors.Is(err, ErrFieldCount) {
+					if recNum < len(tt.Output) {
+						t.Fatalf("need more records; got %d want %d", recNum, len(tt.Output))
+					}
+					break
+				}
+				if got, want := rec, tt.Output[recNum]; !reflect.DeepEqual(got, want) {
+					t.Errorf("Read vs ReadAll mismatch;\ngot %q\nwant %q", got, want)
+				}
+				pos := positions[recNum]
+				if len(pos) != len(rec) {
+					t.Fatalf("mismatched position length at record %d", recNum)
+				}
+				for i := range rec {
+					line, col := r.FieldPos(i)
+					if got, want := [2]int{line, col}, pos[i]; got != want {
+						t.Errorf("position mismatch at record %d, field %d;\ngot %v\nwant %v", recNum, i, got, want)
+					}
+				}
 			}
 		})
 	}
 }
 
+// firstError returns the first non-nil error in errs,
+// with the position adjusted according to the error's
+// index inside positions.
+func firstError(errs []error, positions [][][2]int, errPositions map[int][2]int) error {
+	for i, err := range errs {
+		if err != nil {
+			return errorWithPosition(err, i, positions, errPositions)
+		}
+	}
+	return nil
+}
+
+func errorWithPosition(err error, recNum int, positions [][][2]int, errPositions map[int][2]int) error {
+	parseErr, ok := err.(*ParseError)
+	if !ok {
+		return err
+	}
+	if recNum >= len(positions) {
+		panic(fmt.Errorf("no positions found for error at record %d", recNum))
+	}
+	errPos, ok := errPositions[recNum]
+	if !ok {
+		panic(fmt.Errorf("no error position found for error at record %d", recNum))
+	}
+	parseErr1 := *parseErr
+	parseErr1.StartLine = positions[recNum][0][0]
+	parseErr1.Line = errPos[0]
+	parseErr1.Column = errPos[1]
+	return &parseErr1
+}
+
+// makePositions returns the expected field positions of all
+// the fields in text, the positions of any errors, and the text with the position markers
+// removed.
+//
+// The start of each field is marked with a § symbol;
+// CSV lines are separated by ¶ symbols;
+// Error positions are marked with ∑ symbols.
+func makePositions(text string) ([][][2]int, map[int][2]int, string) {
+	buf := make([]byte, 0, len(text))
+	var positions [][][2]int
+	errPositions := make(map[int][2]int)
+	line, col := 1, 1
+	recNum := 0
+
+	for len(text) > 0 {
+		r, size := utf8.DecodeRuneInString(text)
+		switch r {
+		case '\n':
+			line++
+			col = 1
+			buf = append(buf, '\n')
+		case '§':
+			if len(positions) == 0 {
+				positions = append(positions, [][2]int{})
+			}
+			positions[len(positions)-1] = append(positions[len(positions)-1], [2]int{line, col})
+		case '¶':
+			positions = append(positions, [][2]int{})
+			recNum++
+		case '∑':
+			errPositions[recNum] = [2]int{line, col}
+		default:
+			buf = append(buf, text[:size]...)
+			col += size
+		}
+		text = text[size:]
+	}
+	return positions, errPositions, string(buf)
+}
+
 // nTimes is an io.Reader which yields the string s n times.
 type nTimes struct {
 	s   string
diff --git a/src/encoding/gob/debug.go b/src/encoding/gob/debug.go
index 8f93742..5965fea 100644
--- a/src/encoding/gob/debug.go
+++ b/src/encoding/gob/debug.go
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // Delete the next line to include in the gob package.
+//go:build ignore
 // +build ignore
 
 package gob
diff --git a/src/encoding/gob/decgen.go b/src/encoding/gob/decgen.go
index 1c31e66..994be87 100644
--- a/src/encoding/gob/decgen.go
+++ b/src/encoding/gob/decgen.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // encgen writes the helper functions for encoding. Intended to be
diff --git a/src/encoding/gob/decoder.go b/src/encoding/gob/decoder.go
index b52aabe..b476aaa 100644
--- a/src/encoding/gob/decoder.go
+++ b/src/encoding/gob/decoder.go
@@ -152,6 +152,9 @@
 		}
 		// Type definition for (-id) follows.
 		dec.recvType(-id)
+		if dec.err != nil {
+			break
+		}
 		// When decoding an interface, after a type there may be a
 		// DelimitedValue still in the buffer. Skip its count.
 		// (Alternatively, the buffer is empty and the byte count
@@ -215,7 +218,7 @@
 	return dec.err
 }
 
-// If debug.go is compiled into the program , debugFunc prints a human-readable
+// If debug.go is compiled into the program, debugFunc prints a human-readable
 // representation of the gob data read from r by calling that file's Debug function.
 // Otherwise it is nil.
 var debugFunc func(io.Reader)
diff --git a/src/encoding/gob/dump.go b/src/encoding/gob/dump.go
index 17238c9..8c0bbc4 100644
--- a/src/encoding/gob/dump.go
+++ b/src/encoding/gob/dump.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 package main
diff --git a/src/encoding/gob/encgen.go b/src/encoding/gob/encgen.go
index 409b8c9..b562da1 100644
--- a/src/encoding/gob/encgen.go
+++ b/src/encoding/gob/encgen.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // encgen writes the helper functions for encoding. Intended to be
diff --git a/src/encoding/gob/encoder_test.go b/src/encoding/gob/encoder_test.go
index fe27749..6183646 100644
--- a/src/encoding/gob/encoder_test.go
+++ b/src/encoding/gob/encoder_test.go
@@ -1127,3 +1127,28 @@
 		}
 	}
 }
+
+func TestDecodeErrorMultipleTypes(t *testing.T) {
+	type Test struct {
+		A string
+		B int
+	}
+	var b bytes.Buffer
+	NewEncoder(&b).Encode(Test{"one", 1})
+
+	var result, result2 Test
+	dec := NewDecoder(&b)
+	err := dec.Decode(&result)
+	if err != nil {
+		t.Errorf("decode: unexpected error %v", err)
+	}
+
+	b.Reset()
+	NewEncoder(&b).Encode(Test{"two", 2})
+	err = dec.Decode(&result2)
+	if err == nil {
+		t.Errorf("decode: expected duplicate type error, got nil")
+	} else if !strings.Contains(err.Error(), "duplicate type") {
+		t.Errorf("decode: expected duplicate type error, got %s", err.Error())
+	}
+}
diff --git a/src/encoding/json/decode.go b/src/encoding/json/decode.go
index 86d8a69..a9917e7 100644
--- a/src/encoding/json/decode.go
+++ b/src/encoding/json/decode.go
@@ -200,16 +200,19 @@
 	return strconv.ParseInt(string(n), 10, 64)
 }
 
+// An errorContext provides context for type errors during decoding.
+type errorContext struct {
+	Struct     reflect.Type
+	FieldStack []string
+}
+
 // decodeState represents the state while decoding a JSON value.
 type decodeState struct {
-	data         []byte
-	off          int // next read offset in data
-	opcode       int // last read result
-	scan         scanner
-	errorContext struct { // provides context for type errors
-		Struct     reflect.Type
-		FieldStack []string
-	}
+	data                  []byte
+	off                   int // next read offset in data
+	opcode                int // last read result
+	scan                  scanner
+	errorContext          *errorContext
 	savedError            error
 	useNumber             bool
 	disallowUnknownFields bool
@@ -229,10 +232,11 @@
 	d.data = data
 	d.off = 0
 	d.savedError = nil
-	d.errorContext.Struct = nil
-
-	// Reuse the allocated space for the FieldStack slice.
-	d.errorContext.FieldStack = d.errorContext.FieldStack[:0]
+	if d.errorContext != nil {
+		d.errorContext.Struct = nil
+		// Reuse the allocated space for the FieldStack slice.
+		d.errorContext.FieldStack = d.errorContext.FieldStack[:0]
+	}
 	return d
 }
 
@@ -246,12 +250,11 @@
 
 // addErrorContext returns a new error enhanced with information from d.errorContext
 func (d *decodeState) addErrorContext(err error) error {
-	if d.errorContext.Struct != nil || len(d.errorContext.FieldStack) > 0 {
+	if d.errorContext != nil && (d.errorContext.Struct != nil || len(d.errorContext.FieldStack) > 0) {
 		switch err := err.(type) {
 		case *UnmarshalTypeError:
 			err.Struct = d.errorContext.Struct.Name()
 			err.Field = strings.Join(d.errorContext.FieldStack, ".")
-			return err
 		}
 	}
 	return err
@@ -657,7 +660,10 @@
 	}
 
 	var mapElem reflect.Value
-	origErrorContext := d.errorContext
+	var origErrorContext errorContext
+	if d.errorContext != nil {
+		origErrorContext = *d.errorContext
+	}
 
 	for {
 		// Read opening " of string key or closing }.
@@ -732,6 +738,9 @@
 					}
 					subv = subv.Field(i)
 				}
+				if d.errorContext == nil {
+					d.errorContext = new(errorContext)
+				}
 				d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name)
 				d.errorContext.Struct = t
 			} else if d.disallowUnknownFields {
@@ -812,11 +821,13 @@
 		if d.opcode == scanSkipSpace {
 			d.scanWhile(scanSkipSpace)
 		}
-		// Reset errorContext to its original state.
-		// Keep the same underlying array for FieldStack, to reuse the
-		// space and avoid unnecessary allocs.
-		d.errorContext.FieldStack = d.errorContext.FieldStack[:len(origErrorContext.FieldStack)]
-		d.errorContext.Struct = origErrorContext.Struct
+		if d.errorContext != nil {
+			// Reset errorContext to its original state.
+			// Keep the same underlying array for FieldStack, to reuse the
+			// space and avoid unnecessary allocs.
+			d.errorContext.FieldStack = d.errorContext.FieldStack[:len(origErrorContext.FieldStack)]
+			d.errorContext.Struct = origErrorContext.Struct
+		}
 		if d.opcode == scanEndObject {
 			break
 		}
diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go
index 483b9d8..e473e61 100644
--- a/src/encoding/json/encode.go
+++ b/src/encoding/json/encode.go
@@ -794,23 +794,24 @@
 	e.WriteByte('{')
 
 	// Extract and sort the keys.
-	keys := v.MapKeys()
-	sv := make([]reflectWithString, len(keys))
-	for i, v := range keys {
-		sv[i].v = v
+	sv := make([]reflectWithString, v.Len())
+	mi := v.MapRange()
+	for i := 0; mi.Next(); i++ {
+		sv[i].k = mi.Key()
+		sv[i].v = mi.Value()
 		if err := sv[i].resolve(); err != nil {
 			e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error()))
 		}
 	}
-	sort.Slice(sv, func(i, j int) bool { return sv[i].s < sv[j].s })
+	sort.Slice(sv, func(i, j int) bool { return sv[i].ks < sv[j].ks })
 
 	for i, kv := range sv {
 		if i > 0 {
 			e.WriteByte(',')
 		}
-		e.string(kv.s, opts.escapeHTML)
+		e.string(kv.ks, opts.escapeHTML)
 		e.WriteByte(':')
-		me.elemEnc(e, v.MapIndex(kv.v), opts)
+		me.elemEnc(e, kv.v, opts)
 	}
 	e.WriteByte('}')
 	e.ptrLevel--
@@ -997,29 +998,30 @@
 }
 
 type reflectWithString struct {
-	v reflect.Value
-	s string
+	k  reflect.Value
+	v  reflect.Value
+	ks string
 }
 
 func (w *reflectWithString) resolve() error {
-	if w.v.Kind() == reflect.String {
-		w.s = w.v.String()
+	if w.k.Kind() == reflect.String {
+		w.ks = w.k.String()
 		return nil
 	}
-	if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok {
-		if w.v.Kind() == reflect.Ptr && w.v.IsNil() {
+	if tm, ok := w.k.Interface().(encoding.TextMarshaler); ok {
+		if w.k.Kind() == reflect.Ptr && w.k.IsNil() {
 			return nil
 		}
 		buf, err := tm.MarshalText()
-		w.s = string(buf)
+		w.ks = string(buf)
 		return err
 	}
-	switch w.v.Kind() {
+	switch w.k.Kind() {
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		w.s = strconv.FormatInt(w.v.Int(), 10)
+		w.ks = strconv.FormatInt(w.k.Int(), 10)
 		return nil
 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		w.s = strconv.FormatUint(w.v.Uint(), 10)
+		w.ks = strconv.FormatUint(w.k.Uint(), 10)
 		return nil
 	}
 	panic("unexpected map key type")
@@ -1239,19 +1241,18 @@
 			// 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 isUnexported && t.Kind() != reflect.Struct {
+					if !sf.IsExported() && t.Kind() != reflect.Struct {
 						// Ignore embedded fields of unexported non-struct types.
 						continue
 					}
 					// Do not ignore embedded fields of unexported struct types
 					// since they may have exported fields.
-				} else if isUnexported {
+				} else if !sf.IsExported() {
 					// Ignore unexported non-embedded fields.
 					continue
 				}
diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go
index 42bb09d..0dad951 100644
--- a/src/encoding/json/encode_test.go
+++ b/src/encoding/json/encode_test.go
@@ -245,6 +245,22 @@
 	}
 }
 
+// Issue 43207
+func TestMarshalTextFloatMap(t *testing.T) {
+	m := map[textfloat]string{
+		textfloat(math.NaN()): "1",
+		textfloat(math.NaN()): "1",
+	}
+	got, err := Marshal(m)
+	if err != nil {
+		t.Errorf("Marshal() error: %v", err)
+	}
+	want := `{"TF:NaN":"1","TF:NaN":"1"}`
+	if string(got) != want {
+		t.Errorf("Marshal() = %s, want %s", got, want)
+	}
+}
+
 // Ref has Marshaler and Unmarshaler methods with pointer receiver.
 type Ref int
 
@@ -854,6 +870,10 @@
 	return buf.Bytes(), nil
 }
 
+type textfloat float64
+
+func (f textfloat) MarshalText() ([]byte, error) { return tenc(`TF:%0.2f`, f) }
+
 // Issue 13783
 func TestEncodeBytekind(t *testing.T) {
 	testdata := []struct {
@@ -872,6 +892,7 @@
 		{[]jsonint{5, 4}, `[{"JI":5},{"JI":4}]`},
 		{[]textint{9, 3}, `["TI:9","TI:3"]`},
 		{[]int{9, 3}, `[9,3]`},
+		{[]textfloat{12, 3}, `["TF:12.00","TF:3.00"]`},
 	}
 	for _, d := range testdata {
 		js, err := Marshal(d.data)
diff --git a/src/encoding/json/example_test.go b/src/encoding/json/example_test.go
index 2088c34..fbecf1b 100644
--- a/src/encoding/json/example_test.go
+++ b/src/encoding/json/example_test.go
@@ -279,12 +279,12 @@
 		"b": 2,
 	}
 
-	json, err := json.MarshalIndent(data, "<prefix>", "<indent>")
+	b, err := json.MarshalIndent(data, "<prefix>", "<indent>")
 	if err != nil {
 		log.Fatal(err)
 	}
 
-	fmt.Println(string(json))
+	fmt.Println(string(b))
 	// Output:
 	// {
 	// <prefix><indent>"a": 1,
diff --git a/src/encoding/json/fuzz.go b/src/encoding/json/fuzz.go
index be03f0d..d3fa2d1 100644
--- a/src/encoding/json/fuzz.go
+++ b/src/encoding/json/fuzz.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gofuzz
 // +build gofuzz
 
 package json
diff --git a/src/encoding/xml/typeinfo.go b/src/encoding/xml/typeinfo.go
index f30fe58..162724e 100644
--- a/src/encoding/xml/typeinfo.go
+++ b/src/encoding/xml/typeinfo.go
@@ -60,7 +60,7 @@
 		n := typ.NumField()
 		for i := 0; i < n; i++ {
 			f := typ.Field(i)
-			if (f.PkgPath != "" && !f.Anonymous) || f.Tag.Get("xml") == "-" {
+			if (!f.IsExported() && !f.Anonymous) || f.Tag.Get("xml") == "-" {
 				continue // Private field
 			}
 
diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go
index 6f9594d..c14954d 100644
--- a/src/encoding/xml/xml.go
+++ b/src/encoding/xml/xml.go
@@ -261,7 +261,7 @@
 // call to Token. To acquire a copy of the bytes, call CopyToken
 // or the token's Copy method.
 //
-// Token expands self-closing elements such as <br/>
+// Token expands self-closing elements such as <br>
 // into separate start and end elements returned by successive calls.
 //
 // Token guarantees that the StartElement and EndElement
@@ -768,6 +768,12 @@
 					}
 					b0, b1 = b1, b
 				}
+
+				// Replace the comment with a space in the returned Directive
+				// body, so that markup parts that were separated by the comment
+				// (like a "<" and a "!") don't get joined when re-encoding the
+				// Directive, taking new semantic meaning.
+				d.buf.WriteByte(' ')
 			}
 		}
 		return Directive(d.buf.Bytes()), nil
@@ -1156,8 +1162,9 @@
 	if !ok {
 		return
 	}
-	i := strings.Index(s, ":")
-	if i < 0 {
+	if strings.Count(s, ":") > 1 {
+		name.Local = s
+	} else if i := strings.Index(s, ":"); i < 1 || i > len(s)-2 {
 		name.Local = s
 	} else {
 		name.Space = s[0:i]
diff --git a/src/encoding/xml/xml_test.go b/src/encoding/xml/xml_test.go
index 5672ebb..19152db 100644
--- a/src/encoding/xml/xml_test.go
+++ b/src/encoding/xml/xml_test.go
@@ -802,11 +802,11 @@
 
 var directivesWithCommentsTokens = []Token{
 	CharData("\n"),
-	Directive(`DOCTYPE [<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]`),
+	Directive(`DOCTYPE [ <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]`),
 	CharData("\n"),
-	Directive(`DOCTYPE [<!ENTITY go "Golang">]`),
+	Directive(`DOCTYPE [<!ENTITY go "Golang"> ]`),
 	CharData("\n"),
-	Directive(`DOCTYPE <!-> <!>    [<!ENTITY go "Golang">]`),
+	Directive(`DOCTYPE <!-> <!>       [<!ENTITY go "Golang"> ]`),
 	CharData("\n"),
 }
 
@@ -940,7 +940,7 @@
 }
 
 func TestNewTokenDecoderIdempotent(t *testing.T) {
-	d := NewDecoder(strings.NewReader(`<br/>`))
+	d := NewDecoder(strings.NewReader(`<br>`))
 	d2 := NewTokenDecoder(d)
 	if d != d2 {
 		t.Error("NewTokenDecoder did not detect underlying Decoder")
@@ -1003,3 +1003,60 @@
 	d := NewTokenDecoder(tokReader{})
 	d.Decode(&Failure{})
 }
+
+func testRoundTrip(t *testing.T, input string) {
+	d := NewDecoder(strings.NewReader(input))
+	var tokens []Token
+	var buf bytes.Buffer
+	e := NewEncoder(&buf)
+	for {
+		tok, err := d.Token()
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			t.Fatalf("invalid input: %v", err)
+		}
+		if err := e.EncodeToken(tok); err != nil {
+			t.Fatalf("failed to re-encode input: %v", err)
+		}
+		tokens = append(tokens, CopyToken(tok))
+	}
+	if err := e.Flush(); err != nil {
+		t.Fatal(err)
+	}
+
+	d = NewDecoder(&buf)
+	for {
+		tok, err := d.Token()
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			t.Fatalf("failed to decode output: %v", err)
+		}
+		if len(tokens) == 0 {
+			t.Fatalf("unexpected token: %#v", tok)
+		}
+		a, b := tokens[0], tok
+		if !reflect.DeepEqual(a, b) {
+			t.Fatalf("token mismatch: %#v vs %#v", a, b)
+		}
+		tokens = tokens[1:]
+	}
+	if len(tokens) > 0 {
+		t.Fatalf("lost tokens: %#v", tokens)
+	}
+}
+
+func TestRoundTrip(t *testing.T) {
+	tests := map[string]string{
+		"leading colon":          `<::Test ::foo="bar"><:::Hello></:::Hello><Hello></Hello></::Test>`,
+		"trailing colon":         `<foo abc:="x"></foo>`,
+		"double colon":           `<x:y:foo></x:y:foo>`,
+		"comments in directives": `<!ENTITY x<!<!-- c1 [ " -->--x --> > <e></e> <!DOCTYPE xxx [ x<!-- c2 " -->--x ]>`,
+	}
+	for name, input := range tests {
+		t.Run(name, func(t *testing.T) { testRoundTrip(t, input) })
+	}
+}
diff --git a/src/errors/wrap.go b/src/errors/wrap.go
index 7928fe6..4eb4f9a 100644
--- a/src/errors/wrap.go
+++ b/src/errors/wrap.go
@@ -83,10 +83,10 @@
 	if typ.Kind() != reflectlite.Ptr || val.IsNil() {
 		panic("errors: target must be a non-nil pointer")
 	}
-	if e := typ.Elem(); e.Kind() != reflectlite.Interface && !e.Implements(errorType) {
+	targetType := typ.Elem()
+	if targetType.Kind() != reflectlite.Interface && !targetType.Implements(errorType) {
 		panic("errors: *target must be interface or implement error")
 	}
-	targetType := typ.Elem()
 	for err != nil {
 		if reflectlite.TypeOf(err).AssignableTo(targetType) {
 			val.Elem().Set(reflectlite.ValueOf(err))
diff --git a/src/flag/flag.go b/src/flag/flag.go
index a8485f0..885a4c8 100644
--- a/src/flag/flag.go
+++ b/src/flag/flag.go
@@ -508,31 +508,33 @@
 // 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.
+		var b strings.Builder
+		fmt.Fprintf(&b, "  -%s", flag.Name) // Two spaces before -; see next two comments.
 		name, usage := UnquoteUsage(flag)
 		if len(name) > 0 {
-			s += " " + name
+			b.WriteString(" ")
+			b.WriteString(name)
 		}
 		// Boolean flags of one ASCII letter are so common we
 		// treat them specially, putting their usage on the same line.
-		if len(s) <= 4 { // space, space, '-', 'x'.
-			s += "\t"
+		if b.Len() <= 4 { // space, space, '-', 'x'.
+			b.WriteString("\t")
 		} else {
 			// Four spaces before the tab triggers good alignment
 			// for both 4- and 8-space tab stops.
-			s += "\n    \t"
+			b.WriteString("\n    \t")
 		}
-		s += strings.ReplaceAll(usage, "\n", "\n    \t")
+		b.WriteString(strings.ReplaceAll(usage, "\n", "\n    \t"))
 
 		if !isZeroValue(flag, flag.DefValue) {
 			if _, ok := flag.Value.(*stringValue); ok {
 				// put quotes on the value
-				s += fmt.Sprintf(" (default %q)", flag.DefValue)
+				fmt.Fprintf(&b, " (default %q)", flag.DefValue)
 			} else {
-				s += fmt.Sprintf(" (default %v)", flag.DefValue)
+				fmt.Fprintf(&b, " (default %v)", flag.DefValue)
 			}
 		}
-		fmt.Fprint(f.Output(), s, "\n")
+		fmt.Fprint(f.Output(), b.String(), "\n")
 	})
 }
 
@@ -857,17 +859,23 @@
 // of strings by giving the slice the methods of Value; in particular, Set would
 // decompose the comma-separated string into the slice.
 func (f *FlagSet) Var(value Value, name string, usage string) {
+	// Flag must not begin "-" or contain "=".
+	if strings.HasPrefix(name, "-") {
+		panic(f.sprintf("flag %q begins with -", name))
+	} else if strings.Contains(name, "=") {
+		panic(f.sprintf("flag %q contains =", name))
+	}
+
 	// Remember the default value as a string; it won't change.
 	flag := &Flag{name, usage, value, value.String()}
 	_, alreadythere := f.formal[name]
 	if alreadythere {
 		var msg string
 		if f.name == "" {
-			msg = fmt.Sprintf("flag redefined: %s", name)
+			msg = f.sprintf("flag redefined: %s", name)
 		} else {
-			msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
+			msg = f.sprintf("%s flag redefined: %s", f.name, name)
 		}
-		fmt.Fprintln(f.Output(), msg)
 		panic(msg) // Happens only if flags are declared with identical names
 	}
 	if f.formal == nil {
@@ -886,13 +894,19 @@
 	CommandLine.Var(value, name, usage)
 }
 
+// sprintf formats the message, prints it to output, and returns it.
+func (f *FlagSet) sprintf(format string, a ...interface{}) string {
+	msg := fmt.Sprintf(format, a...)
+	fmt.Fprintln(f.Output(), msg)
+	return msg
+}
+
 // failf prints to standard error a formatted error and usage message and
 // returns the error.
 func (f *FlagSet) failf(format string, a ...interface{}) error {
-	err := fmt.Errorf(format, a...)
-	fmt.Fprintln(f.Output(), err)
+	msg := f.sprintf(format, a...)
 	f.usage()
-	return err
+	return errors.New(msg)
 }
 
 // usage calls the Usage method for the flag set if one is specified,
diff --git a/src/flag/flag_test.go b/src/flag/flag_test.go
index 06cab79..5835fcf 100644
--- a/src/flag/flag_test.go
+++ b/src/flag/flag_test.go
@@ -655,3 +655,86 @@
 		}
 	}
 }
+
+func mustPanic(t *testing.T, testName string, expected string, f func()) {
+	t.Helper()
+	defer func() {
+		switch msg := recover().(type) {
+		case nil:
+			t.Errorf("%s\n: expected panic(%q), but did not panic", testName, expected)
+		case string:
+			if msg != expected {
+				t.Errorf("%s\n: expected panic(%q), but got panic(%q)", testName, expected, msg)
+			}
+		default:
+			t.Errorf("%s\n: expected panic(%q), but got panic(%T%v)", testName, expected, msg, msg)
+		}
+	}()
+	f()
+}
+
+func TestInvalidFlags(t *testing.T) {
+	tests := []struct {
+		flag     string
+		errorMsg string
+	}{
+		{
+			flag:     "-foo",
+			errorMsg: "flag \"-foo\" begins with -",
+		},
+		{
+			flag:     "foo=bar",
+			errorMsg: "flag \"foo=bar\" contains =",
+		},
+	}
+
+	for _, test := range tests {
+		testName := fmt.Sprintf("FlagSet.Var(&v, %q, \"\")", test.flag)
+
+		fs := NewFlagSet("", ContinueOnError)
+		buf := bytes.NewBuffer(nil)
+		fs.SetOutput(buf)
+
+		mustPanic(t, testName, test.errorMsg, func() {
+			var v flagVar
+			fs.Var(&v, test.flag, "")
+		})
+		if msg := test.errorMsg + "\n"; msg != buf.String() {
+			t.Errorf("%s\n: unexpected output: expected %q, bug got %q", testName, msg, buf)
+		}
+	}
+}
+
+func TestRedefinedFlags(t *testing.T) {
+	tests := []struct {
+		flagSetName string
+		errorMsg    string
+	}{
+		{
+			flagSetName: "",
+			errorMsg:    "flag redefined: foo",
+		},
+		{
+			flagSetName: "fs",
+			errorMsg:    "fs flag redefined: foo",
+		},
+	}
+
+	for _, test := range tests {
+		testName := fmt.Sprintf("flag redefined in FlagSet(%q)", test.flagSetName)
+
+		fs := NewFlagSet(test.flagSetName, ContinueOnError)
+		buf := bytes.NewBuffer(nil)
+		fs.SetOutput(buf)
+
+		var v flagVar
+		fs.Var(&v, "foo", "")
+
+		mustPanic(t, testName, test.errorMsg, func() {
+			fs.Var(&v, "foo", "")
+		})
+		if msg := test.errorMsg + "\n"; msg != buf.String() {
+			t.Errorf("%s\n: unexpected output: expected %q, bug got %q", testName, msg, buf)
+		}
+	}
+}
diff --git a/src/fmt/doc.go b/src/fmt/doc.go
index d05ee51..c584cc9 100644
--- a/src/fmt/doc.go
+++ b/src/fmt/doc.go
@@ -189,7 +189,7 @@
 	When printing a struct, fmt cannot and therefore does not invoke
 	formatting methods such as Error or String on unexported fields.
 
-	Explicit argument indexes:
+	Explicit argument indexes
 
 	In Printf, Sprintf, and Fprintf, the default behavior is for each
 	formatting verb to format successive arguments passed in the call.
@@ -211,7 +211,7 @@
 		fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
 	will yield "16 17 0x10 0x11".
 
-	Format errors:
+	Format errors
 
 	If an invalid argument is given for a verb, such as providing
 	a string to %d, the generated string will contain a
diff --git a/src/fmt/format.go b/src/fmt/format.go
index 4d12f82..bd00e5a 100644
--- a/src/fmt/format.go
+++ b/src/fmt/format.go
@@ -320,7 +320,7 @@
 	f.zero = oldZero
 }
 
-// truncate truncates the string s to the specified precision, if present.
+// truncateString truncates the string s to the specified precision, if present.
 func (f *fmt) truncateString(s string) string {
 	if f.precPresent {
 		n := f.prec
diff --git a/src/go.mod b/src/go.mod
index 4ae14ee..379dcf5 100644
--- a/src/go.mod
+++ b/src/go.mod
@@ -1,10 +1,10 @@
 module std
 
-go 1.16
+go 1.17
 
 require (
-	golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
-	golang.org/x/net v0.0.0-20201209123823-ac852fbbde11
-	golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
-	golang.org/x/text v0.3.4 // indirect
+	golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e
+	golang.org/x/net v0.0.0-20210510120150-4163338589ed
+	golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 // indirect
+	golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f // indirect
 )
diff --git a/src/go.sum b/src/go.sum
index 5586aa9..6e869b9 100644
--- a/src/go.sum
+++ b/src/go.sum
@@ -1,17 +1,15 @@
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
-golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20201209123823-ac852fbbde11 h1:lwlPPsmjDKK0J6eG6xDWd5XPehI0R024zxjDnw3esPA=
-golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e h1:8foAy0aoO5GkqCvAEJ4VC4P3zksTg4X4aJCDpZzmgQI=
+golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
+golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso=
-golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 h1:yhBbb4IRs2HS9PPlAg6DMC6mUOKexJBNsLf4Z+6En1Q=
+golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
-golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f h1:yQJrRE0hDxDFmZLlRaw+3vusO4fwNHgHIjUOMO7bHYI=
+golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/src/go/ast/ast.go b/src/go/ast/ast.go
index 300966a..337c87f 100644
--- a/src/go/ast/ast.go
+++ b/src/go/ast/ast.go
@@ -193,11 +193,14 @@
 // in a signature.
 // Field.Names is nil for unnamed parameters (parameter lists which only contain types)
 // and embedded struct fields. In the latter case, the field name is the type name.
+// Field.Names contains a single name "type" for elements of interface type lists.
+// Types belonging to the same type list share the same "type" identifier which also
+// records the position of that keyword.
 //
 type Field struct {
 	Doc     *CommentGroup // associated documentation; or nil
-	Names   []*Ident      // field/method/parameter names; or nil
-	Type    Expr          // field/method/parameter type
+	Names   []*Ident      // field/method/(type) parameter names, or type "type"; or nil
+	Type    Expr          // field/method/parameter type, type list type; or nil
 	Tag     *BasicLit     // field tag; or nil
 	Comment *CommentGroup // line comments; or nil
 }
@@ -206,14 +209,23 @@
 	if len(f.Names) > 0 {
 		return f.Names[0].Pos()
 	}
-	return f.Type.Pos()
+	if f.Type != nil {
+		return f.Type.Pos()
+	}
+	return token.NoPos
 }
 
 func (f *Field) End() token.Pos {
 	if f.Tag != nil {
 		return f.Tag.End()
 	}
-	return f.Type.End()
+	if f.Type != nil {
+		return f.Type.End()
+	}
+	if len(f.Names) > 0 {
+		return f.Names[len(f.Names)-1].End()
+	}
+	return token.NoPos
 }
 
 // A FieldList represents a list of Fields, enclosed by parentheses or braces.
@@ -290,12 +302,6 @@
 	}
 
 	// A BasicLit node represents a literal of basic type.
-	//
-	// Note that for the CHAR and STRING kinds, the literal is stored
-	// with its quotes. For example, for a double-quoted STRING, the
-	// first and the last rune in the Value field will be ". The
-	// Unquote and UnquoteChar functions in the strconv package can be
-	// used to unquote STRING and CHAR values, respectively.
 	BasicLit struct {
 		ValuePos token.Pos   // literal position
 		Kind     token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING
@@ -434,18 +440,11 @@
 
 	// Pointer types are represented via StarExpr nodes.
 
-	// A FuncType node represents a function type.
-	FuncType struct {
-		Func    token.Pos  // position of "func" keyword (token.NoPos if there is no "func")
-		Params  *FieldList // (incoming) parameters; non-nil
-		Results *FieldList // (outgoing) results; or nil
-	}
-
 	// An InterfaceType node represents an interface type.
 	InterfaceType struct {
 		Interface  token.Pos  // position of "interface" keyword
-		Methods    *FieldList // list of methods
-		Incomplete bool       // true if (source) methods are missing in the Methods list
+		Methods    *FieldList // list of embedded interfaces, methods, or types
+		Incomplete bool       // true if (source) methods or types are missing in the Methods list
 	}
 
 	// A MapType node represents a map type.
@@ -893,15 +892,6 @@
 		Values  []Expr        // initial values; or nil
 		Comment *CommentGroup // line comments; or nil
 	}
-
-	// A TypeSpec node represents a type declaration (TypeSpec production).
-	TypeSpec struct {
-		Doc     *CommentGroup // associated documentation; or nil
-		Name    *Ident        // type name
-		Assign  token.Pos     // position of '=', if any
-		Type    Expr          // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes
-		Comment *CommentGroup // line comments; or nil
-	}
 )
 
 // Pos and End implementations for spec nodes.
@@ -965,7 +955,7 @@
 	GenDecl struct {
 		Doc    *CommentGroup // associated documentation; or nil
 		TokPos token.Pos     // position of Tok
-		Tok    token.Token   // IMPORT, CONST, TYPE, VAR
+		Tok    token.Token   // IMPORT, CONST, TYPE, or VAR
 		Lparen token.Pos     // position of '(', if any
 		Specs  []Spec
 		Rparen token.Pos // position of ')', if any
@@ -976,8 +966,10 @@
 		Doc  *CommentGroup // associated documentation; or nil
 		Recv *FieldList    // receiver (methods); or nil (functions)
 		Name *Ident        // function/method name
-		Type *FuncType     // function signature: parameters, results, and position of "func" keyword
+		Type *FuncType     // function signature: type and value parameters, results, and position of "func" keyword
 		Body *BlockStmt    // function body; or nil for external (non-Go) function
+		// TODO(rFindley) consider storing TParams here, rather than FuncType, as
+		//                they are only valid for declared functions
 	}
 )
 
diff --git a/src/go/ast/ast_notypeparams.go b/src/go/ast/ast_notypeparams.go
new file mode 100644
index 0000000..fa132fb
--- /dev/null
+++ b/src/go/ast/ast_notypeparams.go
@@ -0,0 +1,28 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !typeparams
+// +build !typeparams
+
+package ast
+
+import "go/token"
+
+type (
+	// A FuncType node represents a function type.
+	FuncType struct {
+		Func    token.Pos  // position of "func" keyword (token.NoPos if there is no "func")
+		Params  *FieldList // (incoming) parameters; non-nil
+		Results *FieldList // (outgoing) results; or nil
+	}
+
+	// A TypeSpec node represents a type declaration (TypeSpec production).
+	TypeSpec struct {
+		Doc     *CommentGroup // associated documentation; or nil
+		Name    *Ident        // type name
+		Assign  token.Pos     // position of '=', if any
+		Type    Expr          // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes
+		Comment *CommentGroup // line comments; or nil
+	}
+)
diff --git a/src/go/ast/ast_typeparams.go b/src/go/ast/ast_typeparams.go
new file mode 100644
index 0000000..24fdc5f
--- /dev/null
+++ b/src/go/ast/ast_typeparams.go
@@ -0,0 +1,51 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build typeparams
+// +build typeparams
+
+package ast
+
+import "go/token"
+
+type (
+	// A FuncType node represents a function type.
+	FuncType struct {
+		Func    token.Pos  // position of "func" keyword (token.NoPos if there is no "func")
+		TParams *FieldList // type parameters; or nil
+		Params  *FieldList // (incoming) parameters; non-nil
+		Results *FieldList // (outgoing) results; or nil
+	}
+
+	// A TypeSpec node represents a type declaration (TypeSpec production).
+	TypeSpec struct {
+		Doc     *CommentGroup // associated documentation; or nil
+		Name    *Ident        // type name
+		TParams *FieldList    // type parameters; or nil
+		Assign  token.Pos     // position of '=', if any
+		Type    Expr          // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes
+		Comment *CommentGroup // line comments; or nil
+	}
+
+	// A ListExpr node represents a list of expressions separated by commas.
+	// ListExpr nodes are used as index in IndexExpr nodes representing type
+	// or function instantiations with more than one type argument.
+	ListExpr struct {
+		ElemList []Expr
+	}
+)
+
+func (*ListExpr) exprNode() {}
+func (x *ListExpr) Pos() token.Pos {
+	if len(x.ElemList) > 0 {
+		return x.ElemList[0].Pos()
+	}
+	return token.NoPos
+}
+func (x *ListExpr) End() token.Pos {
+	if len(x.ElemList) > 0 {
+		return x.ElemList[len(x.ElemList)-1].End()
+	}
+	return token.NoPos
+}
diff --git a/src/go/ast/commentmap.go b/src/go/ast/commentmap.go
index 2a653a6..5161ea7 100644
--- a/src/go/ast/commentmap.go
+++ b/src/go/ast/commentmap.go
@@ -315,9 +315,17 @@
 }
 
 func (cmap CommentMap) String() string {
+	// print map entries in sorted order
+	var nodes []Node
+	for node := range cmap {
+		nodes = append(nodes, node)
+	}
+	sort.Sort(byInterval(nodes))
+
 	var buf bytes.Buffer
 	fmt.Fprintln(&buf, "CommentMap {")
-	for node, comment := range cmap {
+	for _, node := range nodes {
+		comment := cmap[node]
 		// print name of identifiers; print node type for other nodes
 		var s string
 		if ident, ok := node.(*Ident); ok {
diff --git a/src/go/ast/walk.go b/src/go/ast/walk.go
index 8ca2195..9224264 100644
--- a/src/go/ast/walk.go
+++ b/src/go/ast/walk.go
@@ -4,8 +4,6 @@
 
 package ast
 
-import "fmt"
-
 // A Visitor's Visit method is invoked for each node encountered by Walk.
 // If the result visitor w is not nil, Walk visits each of the children
 // of node with the visitor w, followed by a call of w.Visit(nil).
@@ -71,7 +69,9 @@
 			Walk(v, n.Doc)
 		}
 		walkIdentList(v, n.Names)
-		Walk(v, n.Type)
+		if n.Type != nil {
+			Walk(v, n.Type)
+		}
 		if n.Tag != nil {
 			Walk(v, n.Tag)
 		}
@@ -161,6 +161,7 @@
 		Walk(v, n.Fields)
 
 	case *FuncType:
+		walkFuncTypeParams(v, n)
 		if n.Params != nil {
 			Walk(v, n.Params)
 		}
@@ -315,6 +316,7 @@
 			Walk(v, n.Doc)
 		}
 		Walk(v, n.Name)
+		walkTypeSpecParams(v, n)
 		Walk(v, n.Type)
 		if n.Comment != nil {
 			Walk(v, n.Comment)
@@ -361,7 +363,7 @@
 		}
 
 	default:
-		panic(fmt.Sprintf("ast.Walk: unexpected node type %T", n))
+		walkOtherNodes(v, n)
 	}
 
 	v.Visit(nil)
diff --git a/src/go/ast/walk_notypeparams.go b/src/go/ast/walk_notypeparams.go
new file mode 100644
index 0000000..d43e13d
--- /dev/null
+++ b/src/go/ast/walk_notypeparams.go
@@ -0,0 +1,17 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !typeparams
+// +build !typeparams
+
+package ast
+
+import "fmt"
+
+func walkFuncTypeParams(v Visitor, n *FuncType) {}
+func walkTypeSpecParams(v Visitor, n *TypeSpec) {}
+
+func walkOtherNodes(v Visitor, n Node) {
+	panic(fmt.Sprintf("ast.Walk: unexpected node type %T", n))
+}
diff --git a/src/go/ast/walk_typeparams.go b/src/go/ast/walk_typeparams.go
new file mode 100644
index 0000000..b662133
--- /dev/null
+++ b/src/go/ast/walk_typeparams.go
@@ -0,0 +1,36 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build typeparams
+// +build typeparams
+
+package ast
+
+import (
+	"fmt"
+)
+
+func walkFuncTypeParams(v Visitor, n *FuncType) {
+	if n.TParams != nil {
+		Walk(v, n.TParams)
+	}
+}
+
+func walkTypeSpecParams(v Visitor, n *TypeSpec) {
+	if n.TParams != nil {
+		Walk(v, n.TParams)
+	}
+}
+
+func walkOtherNodes(v Visitor, n Node) {
+	if e, ok := n.(*ListExpr); ok {
+		if e != nil {
+			for _, elem := range e.ElemList {
+				Walk(v, elem)
+			}
+		}
+	} else {
+		panic(fmt.Sprintf("ast.Walk: unexpected node type %T", n))
+	}
+}
diff --git a/src/go/build/build.go b/src/go/build/build.go
index 217fadf..8afa9d5 100644
--- a/src/go/build/build.go
+++ b/src/go/build/build.go
@@ -9,8 +9,10 @@
 	"errors"
 	"fmt"
 	"go/ast"
+	"go/build/constraint"
 	"go/doc"
 	"go/token"
+	"internal/buildcfg"
 	exec "internal/execabs"
 	"internal/goroot"
 	"internal/goversion"
@@ -47,16 +49,18 @@
 	UseAllFiles bool   // use files regardless of +build lines, file names
 	Compiler    string // compiler to assume when computing target paths
 
-	// The build and release tags specify build constraints
+	// The build, tool, and release tags specify build constraints
 	// that should be considered satisfied when processing +build lines.
 	// Clients creating a new context may customize BuildTags, which
-	// defaults to empty, but it is usually an error to customize ReleaseTags,
-	// which defaults to the list of Go releases the current release is compatible with.
+	// defaults to empty, but it is usually an error to customize ToolTags or ReleaseTags.
+	// ToolTags defaults to build tags appropriate to the current Go toolchain configuration.
+	// ReleaseTags defaults to the list of Go releases the current release is compatible with.
 	// BuildTags is not set for the Default build Context.
-	// In addition to the BuildTags and ReleaseTags, build constraints
+	// In addition to the BuildTags, ToolTags, and ReleaseTags, build constraints
 	// consider the values of GOARCH and GOOS as satisfied tags.
 	// The last element in ReleaseTags is assumed to be the current release.
 	BuildTags   []string
+	ToolTags    []string
 	ReleaseTags []string
 
 	// The install suffix specifies a suffix to use in the name of the installation
@@ -187,6 +191,7 @@
 	if f := ctxt.ReadDir; f != nil {
 		return f(path)
 	}
+	// TODO: use os.ReadDir
 	return ioutil.ReadDir(path)
 }
 
@@ -290,17 +295,27 @@
 	return ""
 }
 
-var defaultReleaseTags []string
+var defaultToolTags, defaultReleaseTags []string
 
 func defaultContext() Context {
 	var c Context
 
-	c.GOARCH = envOr("GOARCH", runtime.GOARCH)
-	c.GOOS = envOr("GOOS", runtime.GOOS)
+	c.GOARCH = buildcfg.GOARCH
+	c.GOOS = buildcfg.GOOS
 	c.GOROOT = pathpkg.Clean(runtime.GOROOT())
 	c.GOPATH = envOr("GOPATH", defaultGOPATH())
 	c.Compiler = runtime.Compiler
 
+	// For each experiment that has been enabled in the toolchain, define a
+	// build tag with the same name but prefixed by "goexperiment." which can be
+	// used for compiling alternative files for the experiment. This allows
+	// changes for the experiment, like extra struct fields in the runtime,
+	// without affecting the base non-experiment code at all.
+	for _, exp := range buildcfg.EnabledExperiments() {
+		c.ToolTags = append(c.ToolTags, "goexperiment."+exp)
+	}
+	defaultToolTags = append([]string{}, c.ToolTags...) // our own private copy
+
 	// Each major Go release in the Go 1.x series adds a new
 	// "go1.x" release tag. That is, the go1.x tag is present in
 	// all releases >= Go 1.x. Code that requires Go 1.x or later
@@ -795,6 +810,17 @@
 	}
 
 	var badGoError error
+	badFiles := make(map[string]bool)
+	badFile := func(name string, err error) {
+		if badGoError == nil {
+			badGoError = err
+		}
+		if !badFiles[name] {
+			p.InvalidGoFiles = append(p.InvalidGoFiles, name)
+			badFiles[name] = true
+		}
+	}
+
 	var Sfiles []string // files with ".S"(capital S)/.sx(capital s equivalent for case insensitive filesystems)
 	var firstFile, firstCommentFile string
 	embedPos := make(map[string][]token.Position)
@@ -819,16 +845,9 @@
 		name := d.Name()
 		ext := nameExt(name)
 
-		badFile := func(err error) {
-			if badGoError == nil {
-				badGoError = err
-			}
-			p.InvalidGoFiles = append(p.InvalidGoFiles, name)
-		}
-
 		info, err := ctxt.matchFile(p.Dir, name, allTags, &p.BinaryOnly, fset)
 		if err != nil {
-			badFile(err)
+			badFile(name, err)
 			continue
 		}
 		if info == nil {
@@ -859,15 +878,18 @@
 		}
 
 		if info.parseErr != nil {
-			badFile(info.parseErr)
-			continue
+			badFile(name, info.parseErr)
+			// Fall through: we might still have a partial AST in info.parsed,
+			// and we want to list files with parse errors anyway.
 		}
-		pf := info.parsed
 
-		pkg := pf.Name.Name
-		if pkg == "documentation" {
-			p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
-			continue
+		var pkg string
+		if info.parsed != nil {
+			pkg = info.parsed.Name.Name
+			if pkg == "documentation" {
+				p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
+				continue
+			}
 		}
 
 		isTest := strings.HasSuffix(name, "_test.go")
@@ -881,16 +903,18 @@
 			p.Name = pkg
 			firstFile = name
 		} else if pkg != p.Name {
-			badFile(&MultiplePackageError{
+			// TODO(#45999): The choice of p.Name is arbitrary based on file iteration
+			// order. Instead of resolving p.Name arbitrarily, we should clear out the
+			// existing name and mark the existing files as also invalid.
+			badFile(name, &MultiplePackageError{
 				Dir:      p.Dir,
 				Packages: []string{p.Name, pkg},
 				Files:    []string{firstFile, name},
 			})
-			p.InvalidGoFiles = append(p.InvalidGoFiles, name)
 		}
 		// Grab the first package comment as docs, provided it is not from a test file.
-		if pf.Doc != nil && p.Doc == "" && !isTest && !isXTest {
-			p.Doc = doc.Synopsis(pf.Doc.Text())
+		if info.parsed != nil && info.parsed.Doc != nil && p.Doc == "" && !isTest && !isXTest {
+			p.Doc = doc.Synopsis(info.parsed.Doc.Text())
 		}
 
 		if mode&ImportComment != 0 {
@@ -898,12 +922,12 @@
 			if line != 0 {
 				com, err := strconv.Unquote(qcom)
 				if err != nil {
-					badFile(fmt.Errorf("%s:%d: cannot parse import comment", filename, line))
+					badFile(name, fmt.Errorf("%s:%d: cannot parse import comment", filename, line))
 				} else if p.ImportComment == "" {
 					p.ImportComment = com
 					firstCommentFile = name
 				} else if p.ImportComment != com {
-					badFile(fmt.Errorf("found import comments %q (%s) and %q (%s) in %s", p.ImportComment, firstCommentFile, com, name, p.Dir))
+					badFile(name, fmt.Errorf("found import comments %q (%s) and %q (%s) in %s", p.ImportComment, firstCommentFile, com, name, p.Dir))
 				}
 			}
 		}
@@ -913,13 +937,13 @@
 		for _, imp := range info.imports {
 			if imp.path == "C" {
 				if isTest {
-					badFile(fmt.Errorf("use of cgo in test %s not supported", filename))
+					badFile(name, fmt.Errorf("use of cgo in test %s not supported", filename))
 					continue
 				}
 				isCgo = true
 				if imp.doc != nil {
 					if err := ctxt.saveCgo(filename, p, imp.doc); err != nil {
-						badFile(err)
+						badFile(name, err)
 					}
 				}
 			}
@@ -1054,7 +1078,7 @@
 	// we must not being doing special things like AllowBinary or IgnoreVendor,
 	// and all the file system callbacks must be nil (we're meant to use the local file system).
 	if mode&AllowBinary != 0 || mode&IgnoreVendor != 0 ||
-		ctxt.JoinPath != nil || ctxt.SplitPathList != nil || ctxt.IsAbsPath != nil || ctxt.IsDir != nil || ctxt.HasSubdir != nil || ctxt.ReadDir != nil || ctxt.OpenFile != nil || !equal(ctxt.ReleaseTags, defaultReleaseTags) {
+		ctxt.JoinPath != nil || ctxt.SplitPathList != nil || ctxt.IsAbsPath != nil || ctxt.IsDir != nil || ctxt.HasSubdir != nil || ctxt.ReadDir != nil || ctxt.OpenFile != nil || !equal(ctxt.ToolTags, defaultToolTags) || !equal(ctxt.ReleaseTags, defaultReleaseTags) {
 		return errNoModules
 	}
 
@@ -1423,7 +1447,7 @@
 	// Look for +build comments to accept or reject the file.
 	ok, sawBinaryOnly, err := ctxt.shouldBuild(info.header, allTags)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("%s: %v", name, err)
 	}
 	if !ok && !ctxt.UseAllFiles {
 		return nil, nil
@@ -1459,11 +1483,12 @@
 	bSlashSlash = []byte(slashSlash)
 	bStarSlash  = []byte(starSlash)
 	bSlashStar  = []byte(slashStar)
+	bPlusBuild  = []byte("+build")
 
 	goBuildComment = []byte("//go:build")
 
 	errGoBuildWithoutBuild = errors.New("//go:build comment without // +build comment")
-	errMultipleGoBuild     = errors.New("multiple //go:build comments") // unused in Go 1.(N-1)
+	errMultipleGoBuild     = errors.New("multiple //go:build comments")
 )
 
 func isGoBuildComment(line []byte) bool {
@@ -1498,8 +1523,7 @@
 // shouldBuild reports whether the file should be built
 // and whether a //go:binary-only-package comment was found.
 func (ctxt *Context) shouldBuild(content []byte, allTags map[string]bool) (shouldBuild, binaryOnly bool, err error) {
-
-	// Pass 1. Identify leading run of // comments and blank lines,
+	// Identify leading run of // comments and blank lines,
 	// which must be followed by a blank line.
 	// Also identify any //go:build comments.
 	content, goBuild, sawBinaryOnly, err := parseFileHeader(content)
@@ -1507,44 +1531,42 @@
 		return false, false, err
 	}
 
-	// Pass 2.  Process each +build line in the run.
-	p := content
-	shouldBuild = true
-	sawBuild := false
-	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):]
+	// If //go:build line is present, it controls.
+	// Otherwise fall back to +build processing.
+	switch {
+	case goBuild != nil:
+		x, err := constraint.Parse(string(goBuild))
+		if err != nil {
+			return false, false, fmt.Errorf("parsing //go:build line: %v", err)
 		}
-		line = bytes.TrimSpace(line)
-		if !bytes.HasPrefix(line, bSlashSlash) {
-			continue
-		}
-		line = bytes.TrimSpace(line[len(bSlashSlash):])
-		if len(line) > 0 && line[0] == '+' {
-			// Looks like a comment +line.
-			f := strings.Fields(string(line))
-			if f[0] == "+build" {
-				sawBuild = true
-				ok := false
-				for _, tok := range f[1:] {
-					if ctxt.match(tok, allTags) {
-						ok = true
-					}
-				}
-				if !ok {
+		shouldBuild = ctxt.eval(x, allTags)
+
+	default:
+		shouldBuild = true
+		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 !bytes.HasPrefix(line, bSlashSlash) || !bytes.Contains(line, bPlusBuild) {
+				continue
+			}
+			text := string(line)
+			if !constraint.IsPlusBuild(text) {
+				continue
+			}
+			if x, err := constraint.Parse(text); err == nil {
+				if !ctxt.eval(x, allTags) {
 					shouldBuild = false
 				}
 			}
 		}
 	}
 
-	if goBuild != nil && !sawBuild {
-		return false, false, errGoBuildWithoutBuild
-	}
-
 	return shouldBuild, sawBinaryOnly, nil
 }
 
@@ -1580,7 +1602,7 @@
 		}
 
 		if !inSlashStar && isGoBuildComment(line) {
-			if false && goBuild != nil { // enabled in Go 1.N
+			if goBuild != nil {
 				return nil, nil, false, errMultipleGoBuild
 			}
 			goBuild = line
@@ -1649,7 +1671,7 @@
 		if len(cond) > 0 {
 			ok := false
 			for _, c := range cond {
-				if ctxt.match(c, nil) {
+				if ctxt.matchAuto(c, nil) {
 					ok = true
 					break
 				}
@@ -1831,50 +1853,44 @@
 	return args, err
 }
 
-// match reports whether the name is one of:
+// matchAuto interprets text as either a +build or //go:build expression (whichever works),
+// reporting whether the expression matches the build context.
 //
+// matchAuto is only used for testing of tag evaluation
+// and in #cgo lines, which accept either syntax.
+func (ctxt *Context) matchAuto(text string, allTags map[string]bool) bool {
+	if strings.ContainsAny(text, "&|()") {
+		text = "//go:build " + text
+	} else {
+		text = "// +build " + text
+	}
+	x, err := constraint.Parse(text)
+	if err != nil {
+		return false
+	}
+	return ctxt.eval(x, allTags)
+}
+
+func (ctxt *Context) eval(x constraint.Expr, allTags map[string]bool) bool {
+	return x.Eval(func(tag string) bool { return ctxt.matchTag(tag, allTags) })
+}
+
+// matchTag reports whether the name is one of:
+//
+//	cgo (if cgo is enabled)
 //	$GOOS
 //	$GOARCH
-//	cgo (if cgo is enabled)
-//	!cgo (if cgo is disabled)
 //	ctxt.Compiler
-//	!ctxt.Compiler
+//	linux (if GOOS = android)
+//	solaris (if GOOS = illumos)
 //	tag (if tag is listed in ctxt.BuildTags or ctxt.ReleaseTags)
-//	!tag (if tag is not listed in ctxt.BuildTags or ctxt.ReleaseTags)
-//	a comma-separated list of any of these
 //
-func (ctxt *Context) match(name string, allTags map[string]bool) bool {
-	if name == "" {
-		if allTags != nil {
-			allTags[name] = true
-		}
-		return false
-	}
-	if i := strings.Index(name, ","); i >= 0 {
-		// comma-separated list
-		ok1 := ctxt.match(name[:i], allTags)
-		ok2 := ctxt.match(name[i+1:], allTags)
-		return ok1 && ok2
-	}
-	if strings.HasPrefix(name, "!!") { // bad syntax, reject always
-		return false
-	}
-	if strings.HasPrefix(name, "!") { // negation
-		return len(name) > 1 && !ctxt.match(name[1:], allTags)
-	}
-
+// It records all consulted tags in allTags.
+func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool {
 	if allTags != nil {
 		allTags[name] = true
 	}
 
-	// Tags must be letters, digits, underscores or dots.
-	// Unlike in Go identifiers, all digits are fine (e.g., "386").
-	for _, c := range name {
-		if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
-			return false
-		}
-	}
-
 	// special tags
 	if ctxt.CgoEnabled && name == "cgo" {
 		return true
@@ -1898,6 +1914,11 @@
 			return true
 		}
 	}
+	for _, tag := range ctxt.ToolTags {
+		if tag == name {
+			return true
+		}
+	}
 	for _, tag := range ctxt.ReleaseTags {
 		if tag == name {
 			return true
@@ -1946,10 +1967,10 @@
 	}
 	n := len(l)
 	if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] {
-		return ctxt.match(l[n-1], allTags) && ctxt.match(l[n-2], allTags)
+		return ctxt.matchTag(l[n-1], allTags) && ctxt.matchTag(l[n-2], allTags)
 	}
 	if n >= 1 && (knownOS[l[n-1]] || knownArch[l[n-1]]) {
-		return ctxt.match(l[n-1], allTags)
+		return ctxt.matchTag(l[n-1], allTags)
 	}
 	return true
 }
diff --git a/src/go/build/build_test.go b/src/go/build/build_test.go
index d13ea81..80f930f 100644
--- a/src/go/build/build_test.go
+++ b/src/go/build/build_test.go
@@ -30,7 +30,7 @@
 	match := func(tag string, want map[string]bool) {
 		t.Helper()
 		m := make(map[string]bool)
-		if !ctxt.match(tag, m) {
+		if !ctxt.matchAuto(tag, m) {
 			t.Errorf("%s context should match %s, does not", what, tag)
 		}
 		if !reflect.DeepEqual(m, want) {
@@ -40,7 +40,7 @@
 	nomatch := func(tag string, want map[string]bool) {
 		t.Helper()
 		m := make(map[string]bool)
-		if ctxt.match(tag, m) {
+		if ctxt.matchAuto(tag, m) {
 			t.Errorf("%s context should NOT match %s, does", what, tag)
 		}
 		if !reflect.DeepEqual(m, want) {
@@ -104,7 +104,8 @@
 }
 
 func TestMultiplePackageImport(t *testing.T) {
-	_, err := Import(".", "testdata/multi", 0)
+	pkg, err := Import(".", "testdata/multi", 0)
+
 	mpe, ok := err.(*MultiplePackageError)
 	if !ok {
 		t.Fatal(`Import("testdata/multi") did not return MultiplePackageError.`)
@@ -115,7 +116,20 @@
 		Files:    []string{"file.go", "file_appengine.go"},
 	}
 	if !reflect.DeepEqual(mpe, want) {
-		t.Errorf("got %#v; want %#v", mpe, want)
+		t.Errorf("err = %#v; want %#v", mpe, want)
+	}
+
+	// TODO(#45999): Since the name is ambiguous, pkg.Name should be left empty.
+	if wantName := "main"; pkg.Name != wantName {
+		t.Errorf("pkg.Name = %q; want %q", pkg.Name, wantName)
+	}
+
+	if wantGoFiles := []string{"file.go", "file_appengine.go"}; !reflect.DeepEqual(pkg.GoFiles, wantGoFiles) {
+		t.Errorf("pkg.GoFiles = %q; want %q", pkg.GoFiles, wantGoFiles)
+	}
+
+	if wantInvalidFiles := []string{"file_appengine.go"}; !reflect.DeepEqual(pkg.InvalidGoFiles, wantInvalidFiles) {
+		t.Errorf("pkg.InvalidGoFiles = %q; want %q", pkg.InvalidGoFiles, wantInvalidFiles)
 	}
 }
 
@@ -154,6 +168,13 @@
 		shouldBuild: true,
 	},
 	{
+		name: "Yes2",
+		content: "//go:build yes\n" +
+			"package main\n",
+		tags:        map[string]bool{"yes": true},
+		shouldBuild: true,
+	},
+	{
 		name: "Or",
 		content: "// +build no yes\n\n" +
 			"package main\n",
@@ -161,6 +182,13 @@
 		shouldBuild: true,
 	},
 	{
+		name: "Or2",
+		content: "//go:build no || yes\n" +
+			"package main\n",
+		tags:        map[string]bool{"yes": true, "no": true},
+		shouldBuild: true,
+	},
+	{
 		name: "And",
 		content: "// +build no,yes\n\n" +
 			"package main\n",
@@ -168,6 +196,13 @@
 		shouldBuild: false,
 	},
 	{
+		name: "And2",
+		content: "//go:build no && yes\n" +
+			"package main\n",
+		tags:        map[string]bool{"yes": true, "no": true},
+		shouldBuild: false,
+	},
+	{
 		name: "Cgo",
 		content: "// +build cgo\n\n" +
 			"// Copyright The Go Authors.\n\n" +
@@ -178,11 +213,22 @@
 		shouldBuild: false,
 	},
 	{
+		name: "Cgo2",
+		content: "//go:build cgo\n" +
+			"// Copyright The Go Authors.\n\n" +
+			"// This package implements parsing of tags like\n" +
+			"// +build tag1\n" +
+			"package build",
+		tags:        map[string]bool{"cgo": true},
+		shouldBuild: false,
+	},
+	{
 		name: "AfterPackage",
 		content: "// Copyright The Go Authors.\n\n" +
 			"package build\n\n" +
 			"// shouldBuild checks tags given by lines of the form\n" +
 			"// +build tag\n" +
+			"//go:build tag\n" +
 			"func shouldBuild(content []byte)\n",
 		tags:        map[string]bool{},
 		shouldBuild: true,
@@ -195,6 +241,13 @@
 		shouldBuild: true,
 	},
 	{
+		name: "TooClose2",
+		content: "//go:build yes\n" +
+			"package main\n",
+		tags:        map[string]bool{"yes": true},
+		shouldBuild: true,
+	},
+	{
 		name: "TooCloseNo",
 		content: "// +build no\n" +
 			"package main\n",
@@ -202,6 +255,13 @@
 		shouldBuild: true,
 	},
 	{
+		name: "TooCloseNo2",
+		content: "//go:build no\n" +
+			"package main\n",
+		tags:        map[string]bool{"no": true},
+		shouldBuild: false,
+	},
+	{
 		name: "BinaryOnly",
 		content: "//go:binary-only-package\n" +
 			"// +build yes\n" +
@@ -211,20 +271,21 @@
 		shouldBuild: true,
 	},
 	{
+		name: "BinaryOnly2",
+		content: "//go:binary-only-package\n" +
+			"//go:build no\n" +
+			"package main\n",
+		tags:        map[string]bool{"no": true},
+		binaryOnly:  true,
+		shouldBuild: false,
+	},
+	{
 		name: "ValidGoBuild",
 		content: "// +build yes\n\n" +
 			"//go:build no\n" +
 			"package main\n",
-		tags:        map[string]bool{"yes": true},
-		shouldBuild: true,
-	},
-	{
-		name: "MissingBuild",
-		content: "//go:build no\n" +
-			"package main\n",
-		tags:        map[string]bool{},
+		tags:        map[string]bool{"no": true},
 		shouldBuild: false,
-		err:         errGoBuildWithoutBuild,
 	},
 	{
 		name: "MissingBuild2",
@@ -232,20 +293,8 @@
 			"// +build yes\n\n" +
 			"//go:build no\n" +
 			"package main\n",
-		tags:        map[string]bool{},
+		tags:        map[string]bool{"no": true},
 		shouldBuild: false,
-		err:         errGoBuildWithoutBuild,
-	},
-	{
-		name: "MissingBuild2",
-		content: "/*\n" +
-			"// +build yes\n\n" +
-			"*/\n" +
-			"//go:build no\n" +
-			"package main\n",
-		tags:        map[string]bool{},
-		shouldBuild: false,
-		err:         errGoBuildWithoutBuild,
 	},
 	{
 		name: "Comment1",
@@ -263,9 +312,8 @@
 			"*/\n\n" +
 			"//go:build no\n" +
 			"package main\n",
-		tags:        map[string]bool{},
+		tags:        map[string]bool{"no": true},
 		shouldBuild: false,
-		err:         errGoBuildWithoutBuild,
 	},
 	{
 		name: "Comment3",
@@ -274,9 +322,8 @@
 			"*/\n\n" +
 			"//go:build no\n" +
 			"package main\n",
-		tags:        map[string]bool{},
+		tags:        map[string]bool{"no": true},
 		shouldBuild: false,
-		err:         errGoBuildWithoutBuild,
 	},
 	{
 		name: "Comment4",
@@ -290,9 +337,8 @@
 		content: "/**/\n" +
 			"//go:build no\n" +
 			"package main\n",
-		tags:        map[string]bool{},
+		tags:        map[string]bool{"no": true},
 		shouldBuild: false,
-		err:         errGoBuildWithoutBuild,
 	},
 }
 
@@ -454,11 +500,7 @@
 	testenv.MustHaveGoBuild(t) // really must just have source
 	ctxt := Default
 
-	emptyDir, err := os.MkdirTemp("", t.Name())
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(emptyDir)
+	emptyDir := t.TempDir()
 
 	ctxt.GOPATH = emptyDir
 	ctxt.Dir = emptyDir
@@ -511,8 +553,7 @@
 func TestImportVendor(t *testing.T) {
 	testenv.MustHaveGoBuild(t) // really must just have source
 
-	defer os.Setenv("GO111MODULE", os.Getenv("GO111MODULE"))
-	os.Setenv("GO111MODULE", "off")
+	t.Setenv("GO111MODULE", "off")
 
 	ctxt := Default
 	wd, err := os.Getwd()
@@ -533,8 +574,7 @@
 func TestImportVendorFailure(t *testing.T) {
 	testenv.MustHaveGoBuild(t) // really must just have source
 
-	defer os.Setenv("GO111MODULE", os.Getenv("GO111MODULE"))
-	os.Setenv("GO111MODULE", "off")
+	t.Setenv("GO111MODULE", "off")
 
 	ctxt := Default
 	wd, err := os.Getwd()
@@ -556,8 +596,7 @@
 func TestImportVendorParentFailure(t *testing.T) {
 	testenv.MustHaveGoBuild(t) // really must just have source
 
-	defer os.Setenv("GO111MODULE", os.Getenv("GO111MODULE"))
-	os.Setenv("GO111MODULE", "off")
+	t.Setenv("GO111MODULE", "off")
 
 	ctxt := Default
 	wd, err := os.Getwd()
@@ -587,16 +626,11 @@
 
 	// Disable module fetching for this test so that 'go list' fails quickly
 	// without trying to find the latest version of a module.
-	defer os.Setenv("GOPROXY", os.Getenv("GOPROXY"))
-	os.Setenv("GOPROXY", "off")
+	t.Setenv("GOPROXY", "off")
 
 	// Create a GOPATH in a temporary directory. We don't use testdata
 	// because it's in GOROOT, which interferes with the module heuristic.
-	gopath, err := os.MkdirTemp("", "gobuild-notmodule")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(gopath)
+	gopath := t.TempDir()
 	if err := os.MkdirAll(filepath.Join(gopath, "src/example.com/p"), 0777); err != nil {
 		t.Fatal(err)
 	}
@@ -604,10 +638,8 @@
 		t.Fatal(err)
 	}
 
-	defer os.Setenv("GO111MODULE", os.Getenv("GO111MODULE"))
-	os.Setenv("GO111MODULE", "on")
-	defer os.Setenv("GOPATH", os.Getenv("GOPATH"))
-	os.Setenv("GOPATH", gopath)
+	t.Setenv("GO111MODULE", "on")
+	t.Setenv("GOPATH", gopath)
 	ctxt := Default
 	ctxt.GOPATH = gopath
 	ctxt.Dir = filepath.Join(gopath, "src/example.com/p")
@@ -656,26 +688,19 @@
 // Verifies golang.org/issue/34752.
 func TestMissingImportErrorRepetition(t *testing.T) {
 	testenv.MustHaveGoBuild(t) // need 'go list' internally
-	tmp, err := os.MkdirTemp("", "")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmp)
+	tmp := t.TempDir()
 	if err := os.WriteFile(filepath.Join(tmp, "go.mod"), []byte("module m"), 0666); err != nil {
 		t.Fatal(err)
 	}
-	defer os.Setenv("GO111MODULE", os.Getenv("GO111MODULE"))
-	os.Setenv("GO111MODULE", "on")
-	defer os.Setenv("GOPROXY", os.Getenv("GOPROXY"))
-	os.Setenv("GOPROXY", "off")
-	defer os.Setenv("GONOPROXY", os.Getenv("GONOPROXY"))
-	os.Setenv("GONOPROXY", "none")
+	t.Setenv("GO111MODULE", "on")
+	t.Setenv("GOPROXY", "off")
+	t.Setenv("GONOPROXY", "none")
 
 	ctxt := Default
 	ctxt.Dir = tmp
 
 	pkgPath := "example.com/hello"
-	_, err = ctxt.Import(pkgPath, tmp, FindOnly)
+	_, err := ctxt.Import(pkgPath, tmp, FindOnly)
 	if err == nil {
 		t.Fatal("unexpected success")
 	}
diff --git a/src/go/build/constraint/expr.go b/src/go/build/constraint/expr.go
index 3b27870..957eb9b 100644
--- a/src/go/build/constraint/expr.go
+++ b/src/go/build/constraint/expr.go
@@ -355,8 +355,8 @@
 	return ok
 }
 
-// splitGoBuild splits apart the leading //go:build prefix in line from the build expression itself.
-// It returns "", false if the input is not a //go:build line or if the input contains multiple lines.
+// splitPlusBuild splits apart the leading // +build prefix in line from the build expression itself.
+// It returns "", false if the input is not a // +build line or if the input contains multiple lines.
 func splitPlusBuild(line string) (expr string, ok bool) {
 	// A single trailing newline is OK; otherwise multiple lines are not.
 	if len(line) > 0 && line[len(line)-1] == '\n' {
@@ -426,6 +426,9 @@
 			x = or(x, y)
 		}
 	}
+	if x == nil {
+		x = tag("ignore")
+	}
 	return x
 }
 
diff --git a/src/go/build/constraint/expr_test.go b/src/go/build/constraint/expr_test.go
index 4979f8b5..15d1890 100644
--- a/src/go/build/constraint/expr_test.go
+++ b/src/go/build/constraint/expr_test.go
@@ -216,6 +216,7 @@
 	{"!!x", tag("ignore")},
 	{"!x", not(tag("x"))},
 	{"!", tag("ignore")},
+	{"", tag("ignore")},
 }
 
 func TestParsePlusBuildExpr(t *testing.T) {
@@ -232,19 +233,22 @@
 var constraintTests = []struct {
 	in  string
 	x   Expr
-	err error
+	err string
 }{
-	{"//+build x y", or(tag("x"), tag("y")), nil},
-	{"// +build x y \n", or(tag("x"), tag("y")), nil},
-	{"// +build x y \n ", nil, errNotConstraint},
-	{"// +build x y \nmore", nil, errNotConstraint},
-	{" //+build x y", nil, errNotConstraint},
+	{"//+build !", tag("ignore"), ""},
+	{"//+build", tag("ignore"), ""},
+	{"//+build x y", or(tag("x"), tag("y")), ""},
+	{"// +build x y \n", or(tag("x"), tag("y")), ""},
+	{"// +build x y \n ", nil, "not a build constraint"},
+	{"// +build x y \nmore", nil, "not a build constraint"},
+	{" //+build x y", nil, "not a build constraint"},
 
-	{"//go:build x && y", and(tag("x"), tag("y")), nil},
-	{"//go:build x && y\n", and(tag("x"), tag("y")), nil},
-	{"//go:build x && y\n ", nil, errNotConstraint},
-	{"//go:build x && y\nmore", nil, errNotConstraint},
-	{" //go:build x && y", nil, errNotConstraint},
+	{"//go:build x && y", and(tag("x"), tag("y")), ""},
+	{"//go:build x && y\n", and(tag("x"), tag("y")), ""},
+	{"//go:build x && y\n ", nil, "not a build constraint"},
+	{"//go:build x && y\nmore", nil, "not a build constraint"},
+	{" //go:build x && y", nil, "not a build constraint"},
+	{"//go:build\n", nil, "unexpected end of expression"},
 }
 
 func TestParse(t *testing.T) {
@@ -252,14 +256,14 @@
 		t.Run(fmt.Sprint(i), func(t *testing.T) {
 			x, err := Parse(tt.in)
 			if err != nil {
-				if tt.err == nil {
+				if tt.err == "" {
 					t.Errorf("Constraint(%q): unexpected error: %v", tt.in, err)
-				} else if tt.err != err {
+				} else if !strings.Contains(err.Error(), tt.err) {
 					t.Errorf("Constraint(%q): error %v, want %v", tt.in, err, tt.err)
 				}
 				return
 			}
-			if tt.err != nil {
+			if tt.err != "" {
 				t.Errorf("Constraint(%q) = %v, want error %v", tt.in, x, tt.err)
 				return
 			}
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
index c97c668..45e2f25 100644
--- a/src/go/build/deps_test.go
+++ b/src/go/build/deps_test.go
@@ -71,14 +71,19 @@
 	# No dependencies allowed for any of these packages.
 	NONE
 	< container/list, container/ring,
-	  internal/cfg, internal/cpu,
+	  internal/cfg, internal/cpu, internal/goexperiment,
 	  internal/goversion, internal/nettrace,
 	  unicode/utf8, unicode/utf16, unicode,
 	  unsafe;
 
+	# These packages depend only on unsafe.
+	unsafe
+	< internal/abi;
+
 	# RUNTIME is the core runtime group of packages, all of them very light-weight.
-	internal/cpu, unsafe
+	internal/abi, internal/cpu, internal/goexperiment, unsafe
 	< internal/bytealg
+	< internal/itoa
 	< internal/unsafeheader
 	< runtime/internal/sys
 	< runtime/internal/atomic
@@ -273,9 +278,13 @@
 	< go/token
 	< go/scanner
 	< go/ast
+	< go/internal/typeparams
 	< go/parser;
 
-	go/parser, text/tabwriter
+	FMT
+	< go/build/constraint;
+
+	go/build/constraint, go/parser, text/tabwriter
 	< go/printer
 	< go/format;
 
@@ -285,13 +294,13 @@
 	math/big, go/token
 	< go/constant;
 
-	container/heap, go/constant, go/parser
+	container/heap, go/constant, go/parser, regexp
 	< go/types;
 
-	FMT
-	< go/build/constraint;
+	FMT, internal/goexperiment
+	< internal/buildcfg;
 
-	go/doc, go/parser, internal/goroot, internal/goversion
+	go/build/constraint, go/doc, go/parser, internal/buildcfg, internal/goroot, internal/goversion
 	< go/build;
 
 	DEBUG, go/build, go/types, text/scanner
@@ -383,6 +392,9 @@
 	< crypto
 	< crypto/subtle
 	< crypto/internal/subtle
+	< crypto/elliptic/internal/fiat
+	< crypto/ed25519/internal/edwards25519/field
+	< crypto/ed25519/internal/edwards25519
 	< crypto/cipher
 	< crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4,
 	  crypto/sha1, crypto/sha256, crypto/sha512
@@ -394,7 +406,6 @@
 	CRYPTO, FMT, math/big
 	< crypto/rand
 	< crypto/internal/randutil
-	< crypto/ed25519/internal/edwards25519
 	< crypto/ed25519
 	< encoding/asn1
 	< golang.org/x/crypto/cryptobyte/asn1
@@ -429,7 +440,8 @@
 	# HTTP, King of Dependencies.
 
 	FMT
-	< golang.org/x/net/http2/hpack, net/http/internal;
+	< golang.org/x/net/http2/hpack
+	< net/http/internal, net/http/internal/ascii, net/http/internal/testcert;
 
 	FMT, NET, container/list, encoding/binary, log
 	< golang.org/x/text/transform
@@ -447,6 +459,8 @@
 	golang.org/x/net/http/httpproxy,
 	golang.org/x/net/http2/hpack,
 	net/http/internal,
+	net/http/internal/ascii,
+	net/http/internal/testcert,
 	net/http/httptrace,
 	mime/multipart,
 	log
@@ -457,7 +471,7 @@
 	encoding/json, net/http
 	< expvar;
 
-	net/http
+	net/http, net/http/internal/ascii
 	< net/http/cookiejar, net/http/httputil;
 
 	net/http, flag
@@ -494,7 +508,7 @@
 	FMT, flag, math/rand
 	< testing/quick;
 
-	FMT, flag, runtime/debug, runtime/trace, internal/sysinfo
+	FMT, flag, runtime/debug, runtime/trace, internal/sysinfo, math/rand
 	< testing;
 
 	internal/testlog, runtime/pprof, regexp
diff --git a/src/go/build/doc.go b/src/go/build/doc.go
index 2c6f0a8..778b4f4 100644
--- a/src/go/build/doc.go
+++ b/src/go/build/doc.go
@@ -59,7 +59,7 @@
 //
 // A build constraint, also known as a build tag, is a line comment that begins
 //
-// 	// +build
+// 	//go:build
 //
 // that lists the conditions under which a file should be included in the
 // package. Build constraints may also be part of a file's name
diff --git a/src/go/build/gc.go b/src/go/build/gc.go
index 3025cd5..e16e186 100644
--- a/src/go/build/gc.go
+++ b/src/go/build/gc.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 package build
diff --git a/src/go/build/gccgo.go b/src/go/build/gccgo.go
index c6aac9a..c8ec704 100644
--- a/src/go/build/gccgo.go
+++ b/src/go/build/gccgo.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gccgo
 // +build gccgo
 
 package build
diff --git a/src/go/build/read.go b/src/go/build/read.go
index aa7c6ee..b98c793 100644
--- a/src/go/build/read.go
+++ b/src/go/build/read.go
@@ -6,6 +6,7 @@
 
 import (
 	"bufio"
+	"bytes"
 	"errors"
 	"fmt"
 	"go/ast"
@@ -28,9 +29,19 @@
 	pos  token.Position
 }
 
+var bom = []byte{0xef, 0xbb, 0xbf}
+
 func newImportReader(name string, r io.Reader) *importReader {
+	b := bufio.NewReader(r)
+	// Remove leading UTF-8 BOM.
+	// Per https://golang.org/ref/spec#Source_code_representation:
+	// a compiler may ignore a UTF-8-encoded byte order mark (U+FEFF)
+	// if it is the first Unicode code point in the source text.
+	if leadingBytes, err := b.Peek(3); err == nil && bytes.Equal(leadingBytes, bom) {
+		b.Discard(3)
+	}
 	return &importReader{
-		b: bufio.NewReader(r),
+		b: b,
 		pos: token.Position{
 			Filename: name,
 			Line:     1,
diff --git a/src/go/build/read_test.go b/src/go/build/read_test.go
index 32e6bae..1e5e1c2 100644
--- a/src/go/build/read_test.go
+++ b/src/go/build/read_test.go
@@ -66,6 +66,10 @@
 		`,
 		"",
 	},
+	{
+		"\ufeff𝔻" + `package p; import "x";ℙvar x = 1`,
+		"",
+	},
 }
 
 var readCommentsTests = []readTest{
@@ -82,6 +86,10 @@
 		"",
 	},
 	{
+		"\ufeff𝔻" + `ℙpackage p; import . "x"`,
+		"",
+	},
+	{
 		`// foo
 
 		/* bar */
@@ -94,6 +102,19 @@
 		ℙHello, world`,
 		"",
 	},
+	{
+		"\ufeff𝔻" + `// foo
+
+		/* bar */
+
+		/* quux */ // baz
+
+		/*/ zot */
+
+		// asdf
+		ℙHello, world`,
+		"",
+	},
 }
 
 func testRead(t *testing.T, tests []readTest, read func(io.Reader) ([]byte, error)) {
@@ -107,6 +128,11 @@
 			in = tt.in[:j] + tt.in[j+len("ℙ"):]
 			testOut = tt.in[:j]
 		}
+		d := strings.Index(tt.in, "𝔻")
+		if d >= 0 {
+			in = in[:d] + in[d+len("𝔻"):]
+			testOut = testOut[d+len("𝔻"):]
+		}
 		r := strings.NewReader(in)
 		buf, err := read(r)
 		if err != nil {
@@ -265,6 +291,12 @@
 		 test:3:16:z`,
 	},
 	{
+		"\ufeffpackage p\nimport \"embed\"\n//go:embed x y z\nvar files embed.FS",
+		`test:3:12:x
+		 test:3:14:y
+		 test:3:16:z`,
+	},
+	{
 		"package p\nimport \"embed\"\nvar s = \"/*\"\n//go:embed x\nvar files embed.FS",
 		`test:4:12:x`,
 	},
@@ -292,6 +324,10 @@
 		"package p\n//go:embed x y z\nvar files embed.FS", // no import, no scan
 		"",
 	},
+	{
+		"\ufeffpackage p\n//go:embed x y z\nvar files embed.FS", // no import, no scan
+		"",
+	},
 }
 
 func TestReadEmbed(t *testing.T) {
diff --git a/src/go/build/syslist.go b/src/go/build/syslist.go
index 1275f7c..60ac5511b 100644
--- a/src/go/build/syslist.go
+++ b/src/go/build/syslist.go
@@ -8,4 +8,4 @@
 // Do not remove from this list, as these are used for go/build filename matching.
 
 const goosList = "aix android darwin dragonfly freebsd hurd illumos ios js linux nacl netbsd openbsd plan9 solaris windows zos "
-const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc riscv riscv64 s390 s390x sparc sparc64 wasm "
+const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 ppc64le loong64 mips mipsle mips64 mips64le mips64p32 mips64p32le ppc riscv riscv64 s390 s390x sparc sparc64 wasm "
diff --git a/src/go/build/zcgo.go b/src/go/build/zcgo.go
index 7233d16..c22f4fb 100644
--- a/src/go/build/zcgo.go
+++ b/src/go/build/zcgo.go
@@ -40,7 +40,9 @@
 	"openbsd/amd64": true,
 	"openbsd/arm": true,
 	"openbsd/arm64": true,
+	"openbsd/mips64": true,
 	"solaris/amd64": true,
 	"windows/386": true,
 	"windows/amd64": true,
+	"windows/arm64": true,
 }
diff --git a/src/go/constant/value.go b/src/go/constant/value.go
index 4641442..78cb3f8 100644
--- a/src/go/constant/value.go
+++ b/src/go/constant/value.go
@@ -17,6 +17,7 @@
 	"go/token"
 	"math"
 	"math/big"
+	"math/bits"
 	"strconv"
 	"strings"
 	"sync"
@@ -71,6 +72,17 @@
 //           too large (incl. infinity), that could be recorded in unknownVal.
 //           See also #20583 and #42695 for use cases.
 
+// Representation of values:
+//
+// Values of Int and Float Kind have two different representations each: int64Val
+// and intVal, and ratVal and floatVal. When possible, the "smaller", respectively
+// more precise (for Floats) representation is chosen. However, once a Float value
+// is represented as a floatVal, any subsequent results remain floatVals (unless
+// explicitly converted); i.e., no attempt is made to convert a floatVal back into
+// a ratVal. The reasoning is that all representations but floatVal are mathematically
+// exact, but once that precision is lost (by moving to floatVal), moving back to
+// a different representation implies a precision that's not actually there.
+
 type (
 	unknownVal struct{}
 	boolVal    bool
@@ -262,14 +274,8 @@
 func i64tof(x int64Val) floatVal { return floatVal{newFloat().SetInt64(int64(x))} }
 func itor(x intVal) ratVal       { return ratVal{newRat().SetInt(x.val)} }
 func itof(x intVal) floatVal     { return floatVal{newFloat().SetInt(x.val)} }
-
-func rtof(x ratVal) floatVal {
-	a := newFloat().SetInt(x.val.Num())
-	b := newFloat().SetInt(x.val.Denom())
-	return floatVal{a.Quo(a, b)}
-}
-
-func vtoc(x Value) complexVal { return complexVal{x, int64Val(0)} }
+func rtof(x ratVal) floatVal     { return floatVal{newFloat().SetRat(x.val)} }
+func vtoc(x Value) complexVal    { return complexVal{x, int64Val(0)} }
 
 func makeInt(x *big.Int) Value {
 	if x.IsInt64() {
@@ -278,21 +284,15 @@
 	return intVal{x}
 }
 
-// Permit fractions with component sizes up to maxExp
-// before switching to using floating-point numbers.
-const maxExp = 4 << 10
-
 func makeRat(x *big.Rat) Value {
 	a := x.Num()
 	b := x.Denom()
-	if a.BitLen() < maxExp && b.BitLen() < maxExp {
+	if smallInt(a) && smallInt(b) {
 		// ok to remain fraction
 		return ratVal{x}
 	}
 	// components too large => switch to float
-	fa := newFloat().SetInt(a)
-	fb := newFloat().SetInt(b)
-	return floatVal{fa.Quo(fa, fb)}
+	return floatVal{newFloat().SetRat(x)}
 }
 
 var floatVal0 = floatVal{newFloat()}
@@ -305,6 +305,9 @@
 	if x.IsInf() {
 		return unknownVal{}
 	}
+	// No attempt is made to "go back" to ratVal, even if possible,
+	// to avoid providing the illusion of a mathematically exact
+	// representation.
 	return floatVal{x}
 }
 
@@ -317,7 +320,7 @@
 
 func makeFloatFromLiteral(lit string) Value {
 	if f, ok := newFloat().SetString(lit); ok {
-		if smallRat(f) {
+		if smallFloat(f) {
 			// ok to use rationals
 			if f.Sign() == 0 {
 				// Issue 20228: If the float underflowed to zero, parse just "0".
@@ -336,14 +339,34 @@
 	return nil
 }
 
-// smallRat reports whether x would lead to "reasonably"-sized fraction
+// Permit fractions with component sizes up to maxExp
+// before switching to using floating-point numbers.
+const maxExp = 4 << 10
+
+// smallInt reports whether x would lead to "reasonably"-sized fraction
 // if converted to a *big.Rat.
-func smallRat(x *big.Float) bool {
-	if !x.IsInf() {
-		e := x.MantExp(nil)
-		return -maxExp < e && e < maxExp
+func smallInt(x *big.Int) bool {
+	return x.BitLen() < maxExp
+}
+
+// smallFloat64 reports whether x would lead to "reasonably"-sized fraction
+// if converted to a *big.Rat.
+func smallFloat64(x float64) bool {
+	if math.IsInf(x, 0) {
+		return false
 	}
-	return false
+	_, e := math.Frexp(x)
+	return -maxExp < e && e < maxExp
+}
+
+// smallFloat reports whether x would lead to "reasonably"-sized fraction
+// if converted to a *big.Rat.
+func smallFloat(x *big.Float) bool {
+	if x.IsInf() {
+		return false
+	}
+	e := x.MantExp(nil)
+	return -maxExp < e && e < maxExp
 }
 
 // ----------------------------------------------------------------------------
@@ -376,7 +399,10 @@
 	if math.IsInf(x, 0) || math.IsNaN(x) {
 		return unknownVal{}
 	}
-	return ratVal{newRat().SetFloat64(x + 0)} // convert -0 to 0
+	if smallFloat64(x) {
+		return ratVal{newRat().SetFloat64(x + 0)} // convert -0 to 0
+	}
+	return floatVal{newFloat().SetFloat64(x + 0)}
 }
 
 // MakeFromLiteral returns the corresponding integer, floating-point,
@@ -607,7 +633,11 @@
 func BitLen(x Value) int {
 	switch x := x.(type) {
 	case int64Val:
-		return i64toi(x).val.BitLen()
+		u := uint64(x)
+		if x < 0 {
+			u = uint64(-x)
+		}
+		return 64 - bits.LeadingZeros64(u)
 	case intVal:
 		return x.val.BitLen()
 	case unknownVal:
@@ -728,7 +758,7 @@
 	case ratVal:
 		return makeInt(x.val.Num())
 	case floatVal:
-		if smallRat(x.val) {
+		if smallFloat(x.val) {
 			r, _ := x.val.Rat(nil)
 			return makeInt(r.Num())
 		}
@@ -750,7 +780,7 @@
 	case ratVal:
 		return makeInt(x.val.Denom())
 	case floatVal:
-		if smallRat(x.val) {
+		if smallFloat(x.val) {
 			r, _ := x.val.Rat(nil)
 			return makeInt(r.Denom())
 		}
@@ -823,7 +853,7 @@
 		// avoid creation of huge integers
 		// (Existing tests require permitting exponents of at least 1024;
 		// allow any value that would also be permissible as a fraction.)
-		if smallRat(x.val) {
+		if smallFloat(x.val) {
 			i := newInt()
 			if _, acc := x.val.Int(i); acc == big.Exact {
 				return makeInt(i)
@@ -866,14 +896,16 @@
 func ToFloat(x Value) Value {
 	switch x := x.(type) {
 	case int64Val:
-		return i64tof(x)
+		return i64tor(x) // x is always a small int
 	case intVal:
+		if smallInt(x.val) {
+			return itor(x)
+		}
 		return itof(x)
 	case ratVal, floatVal:
 		return x
 	case complexVal:
-		if im := ToInt(x.im); im.Kind() == Int && Sign(im) == 0 {
-			// imaginary component is 0
+		if Sign(x.im) == 0 {
 			return ToFloat(x.re)
 		}
 	}
@@ -884,13 +916,7 @@
 // Otherwise it returns an Unknown.
 func ToComplex(x Value) Value {
 	switch x := x.(type) {
-	case int64Val:
-		return vtoc(i64tof(x))
-	case intVal:
-		return vtoc(itof(x))
-	case ratVal:
-		return vtoc(x)
-	case floatVal:
+	case int64Val, intVal, ratVal, floatVal:
 		return vtoc(x)
 	case complexVal:
 		return x
@@ -1009,59 +1035,45 @@
 // or invalid (say, nil) both results are that value.
 //
 func match(x, y Value) (_, _ Value) {
-	if ord(x) > ord(y) {
-		y, x = match(y, x)
-		return x, y
+	switch ox, oy := ord(x), ord(y); {
+	case ox < oy:
+		x, y = match0(x, y)
+	case ox > oy:
+		y, x = match0(y, x)
 	}
-	// ord(x) <= ord(y)
+	return x, y
+}
 
-	switch x := x.(type) {
-	case boolVal, *stringVal, complexVal:
-		return x, y
+// match0 must only be called by match.
+// Invariant: ord(x) < ord(y)
+func match0(x, y Value) (_, _ Value) {
+	// Prefer to return the original x and y arguments when possible,
+	// to avoid unnecessary heap allocations.
 
-	case int64Val:
-		switch y := y.(type) {
-		case int64Val:
-			return x, y
-		case intVal:
-			return i64toi(x), y
-		case ratVal:
-			return i64tor(x), y
-		case floatVal:
-			return i64tof(x), y
-		case complexVal:
-			return vtoc(x), y
-		}
-
+	switch y.(type) {
 	case intVal:
-		switch y := y.(type) {
-		case intVal:
-			return x, y
-		case ratVal:
-			return itor(x), y
-		case floatVal:
-			return itof(x), y
-		case complexVal:
-			return vtoc(x), y
+		switch x1 := x.(type) {
+		case int64Val:
+			return i64toi(x1), y
 		}
-
 	case ratVal:
-		switch y := y.(type) {
-		case ratVal:
-			return x, y
-		case floatVal:
-			return rtof(x), y
-		case complexVal:
-			return vtoc(x), y
+		switch x1 := x.(type) {
+		case int64Val:
+			return i64tor(x1), y
+		case intVal:
+			return itor(x1), y
 		}
-
 	case floatVal:
-		switch y := y.(type) {
-		case floatVal:
-			return x, y
-		case complexVal:
-			return vtoc(x), y
+		switch x1 := x.(type) {
+		case int64Val:
+			return i64tof(x1), y
+		case intVal:
+			return itof(x1), y
+		case ratVal:
+			return rtof(x1), y
 		}
+	case complexVal:
+		return vtoc(x), y
 	}
 
 	// force unknown and invalid values into "x position" in callers of match
diff --git a/src/go/constant/value_test.go b/src/go/constant/value_test.go
index 2866774..91ad0b0 100644
--- a/src/go/constant/value_test.go
+++ b/src/go/constant/value_test.go
@@ -706,3 +706,24 @@
 		})
 	}
 }
+
+var bitLenTests = []struct {
+	val  int64
+	want int
+}{
+	{0, 0},
+	{1, 1},
+	{-16, 5},
+	{1 << 61, 62},
+	{1 << 62, 63},
+	{-1 << 62, 63},
+	{-1 << 63, 64},
+}
+
+func TestBitLen(t *testing.T) {
+	for _, test := range bitLenTests {
+		if got := BitLen(MakeInt64(test.val)); got != test.want {
+			t.Errorf("%v: got %v, want %v", test.val, got, test.want)
+		}
+	}
+}
diff --git a/src/go/doc/example.go b/src/go/doc/example.go
index 125fd53..274000c 100644
--- a/src/go/doc/example.go
+++ b/src/go/doc/example.go
@@ -237,7 +237,10 @@
 				}
 			}
 
-			ast.Inspect(d.Body, inspectFunc)
+			// Functions might not have a body. See #42706.
+			if d.Body != nil {
+				ast.Inspect(d.Body, inspectFunc)
+			}
 		case *ast.GenDecl:
 			for _, spec := range d.Specs {
 				switch s := spec.(type) {
diff --git a/src/go/doc/example_test.go b/src/go/doc/example_test.go
index 7c96f03..cf1b702 100644
--- a/src/go/doc/example_test.go
+++ b/src/go/doc/example_test.go
@@ -352,6 +352,25 @@
 }
 `
 
+const exampleWholeFileExternalFunction = `package foo_test
+
+func foo(int)
+
+func Example() {
+	foo(42)
+	// Output:
+}
+`
+
+const exampleWholeFileExternalFunctionOutput = `package main
+
+func foo(int)
+
+func main() {
+	foo(42)
+}
+`
+
 var exampleWholeFileTestCases = []struct {
 	Title, Source, Play, Output string
 }{
@@ -367,6 +386,12 @@
 		exampleWholeFileFunctionOutput,
 		"Hello, world!\n",
 	},
+	{
+		"ExternalFunction",
+		exampleWholeFileExternalFunction,
+		exampleWholeFileExternalFunctionOutput,
+		"",
+	},
 }
 
 func TestExamplesWholeFile(t *testing.T) {
diff --git a/src/go/doc/headscan.go b/src/go/doc/headscan.go
index fe26a0e..28cb84f 100644
--- a/src/go/doc/headscan.go
+++ b/src/go/doc/headscan.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/go/format/format_test.go b/src/go/format/format_test.go
index 27f4c74..6cc0278 100644
--- a/src/go/format/format_test.go
+++ b/src/go/format/format_test.go
@@ -151,6 +151,10 @@
 	// erroneous programs
 	"ERROR1 + 2 +",
 	"ERRORx :=  0",
+
+	// build comments
+	"// copyright\n\n//go:build x\n\npackage p\n",
+	"// copyright\n\n//go:build x\n// +build x\n\npackage p\n",
 }
 
 func String(s string) (string, error) {
diff --git a/src/go/internal/gccgoimporter/gccgoinstallation_test.go b/src/go/internal/gccgoimporter/gccgoinstallation_test.go
index b332bab..df0188a 100644
--- a/src/go/internal/gccgoimporter/gccgoinstallation_test.go
+++ b/src/go/internal/gccgoimporter/gccgoinstallation_test.go
@@ -184,7 +184,7 @@
 		{pkgpath: "io", name: "ReadWriter", want: "type ReadWriter interface{Reader; Writer}"},
 		{pkgpath: "math", name: "Pi", want: "const Pi untyped float"},
 		{pkgpath: "math", name: "Sin", want: "func Sin(x float64) float64"},
-		{pkgpath: "sort", name: "Ints", want: "func Ints(a []int)"},
+		{pkgpath: "sort", name: "Search", want: "func Search(n int, f func(int) bool) int"},
 		{pkgpath: "unsafe", name: "Pointer", want: "type Pointer"},
 	} {
 		runImporterTest(t, imp, nil, &test)
diff --git a/src/go/internal/gccgoimporter/importer_test.go b/src/go/internal/gccgoimporter/importer_test.go
index 35240c8..8a7ee1a 100644
--- a/src/go/internal/gccgoimporter/importer_test.go
+++ b/src/go/internal/gccgoimporter/importer_test.go
@@ -94,7 +94,7 @@
 	{pkgpath: "nointerface", name: "I", want: "type I int"},
 	{pkgpath: "issue29198", name: "FooServer", gccgoVersion: 7, want: "type FooServer struct{FooServer *FooServer; user string; ctx context.Context}"},
 	{pkgpath: "issue30628", name: "Apple", want: "type Apple struct{hey sync.RWMutex; x int; RQ [517]struct{Count uintptr; NumBytes uintptr; Last uintptr}}"},
-	{pkgpath: "issue31540", name: "S", gccgoVersion: 7, want: "type S struct{b int; map[Y]Z}"},
+	{pkgpath: "issue31540", name: "S", gccgoVersion: 7, want: "type S struct{b int; map[Y]Z}"}, // should want "type S struct{b int; A2}" (issue  #44410)
 	{pkgpath: "issue34182", name: "T1", want: "type T1 struct{f *T2}"},
 	{pkgpath: "notinheap", name: "S", want: "type S struct{}"},
 }
@@ -149,21 +149,11 @@
 	}
 	t.Logf("gccgo version %d.%d", major, minor)
 
-	tmpdir, err := os.MkdirTemp("", "TestObjImporter")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
-
+	tmpdir := t.TempDir()
 	initmap := make(map[*types.Package]InitData)
 	imp := GetImporter([]string{tmpdir}, initmap)
 
-	artmpdir, err := os.MkdirTemp("", "TestObjImporter")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(artmpdir)
-
+	artmpdir := t.TempDir()
 	arinitmap := make(map[*types.Package]InitData)
 	arimp := GetImporter([]string{artmpdir}, arinitmap)
 
diff --git a/src/go/internal/gcimporter/gcimporter.go b/src/go/internal/gcimporter/gcimporter.go
index b74daca..73cf633 100644
--- a/src/go/internal/gcimporter/gcimporter.go
+++ b/src/go/internal/gcimporter/gcimporter.go
@@ -145,17 +145,14 @@
 		err = fmt.Errorf("import %q: old textual export format no longer supported (recompile library)", path)
 
 	case "$$B\n":
-		var data []byte
-		data, err = io.ReadAll(buf)
-		if err != nil {
-			break
-		}
+		var exportFormat byte
+		exportFormat, err = buf.ReadByte()
 
 		// The indexed export format starts with an 'i'; the older
 		// binary export format starts with a 'c', 'd', or 'v'
 		// (from "version"). Select appropriate importer.
-		if len(data) > 0 && data[0] == 'i' {
-			_, pkg, err = iImportData(fset, packages, data[1:], id)
+		if err == nil && exportFormat == 'i' {
+			pkg, err = iImportData(fset, packages, buf, id)
 		} else {
 			err = fmt.Errorf("import %q: old binary export format no longer supported (recompile library)", path)
 		}
diff --git a/src/go/internal/gcimporter/iimport.go b/src/go/internal/gcimporter/iimport.go
index c59dd16..76d47d0 100644
--- a/src/go/internal/gcimporter/iimport.go
+++ b/src/go/internal/gcimporter/iimport.go
@@ -8,6 +8,7 @@
 package gcimporter
 
 import (
+	"bufio"
 	"bytes"
 	"encoding/binary"
 	"fmt"
@@ -15,11 +16,12 @@
 	"go/token"
 	"go/types"
 	"io"
+	"math/big"
 	"sort"
 )
 
 type intReader struct {
-	*bytes.Reader
+	*bufio.Reader
 	path string
 }
 
@@ -60,7 +62,7 @@
 // and returns the number of bytes consumed and a reference to the package.
 // If the export data version is not recognized or the format is otherwise
 // compromised, an error is returned.
-func iImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
+func iImportData(fset *token.FileSet, imports map[string]*types.Package, dataReader *bufio.Reader, path string) (pkg *types.Package, err error) {
 	const currentVersion = 1
 	version := int64(-1)
 	defer func() {
@@ -73,7 +75,7 @@
 		}
 	}()
 
-	r := &intReader{bytes.NewReader(data), path}
+	r := &intReader{dataReader, path}
 
 	version = int64(r.uint64())
 	switch version {
@@ -85,10 +87,12 @@
 	sLen := int64(r.uint64())
 	dLen := int64(r.uint64())
 
-	whence, _ := r.Seek(0, io.SeekCurrent)
-	stringData := data[whence : whence+sLen]
-	declData := data[whence+sLen : whence+sLen+dLen]
-	r.Seek(sLen+dLen, io.SeekCurrent)
+	data := make([]byte, sLen+dLen)
+	if _, err := io.ReadFull(r, data); err != nil {
+		errorf("cannot read %d bytes of stringData and declData: %s", len(data), err)
+	}
+	stringData := data[:sLen]
+	declData := data[sLen:]
 
 	p := iimporter{
 		ipath:   path,
@@ -164,9 +168,7 @@
 
 	// package was imported completely and without errors
 	localpkg.MarkComplete()
-
-	consumed, _ := r.Seek(0, io.SeekCurrent)
-	return int(consumed), localpkg, nil
+	return localpkg, nil
 }
 
 type iimporter struct {
@@ -320,7 +322,9 @@
 		val = constant.MakeString(r.string())
 
 	case types.IsInteger:
-		val = r.mpint(b)
+		var x big.Int
+		r.mpint(&x, b)
+		val = constant.Make(&x)
 
 	case types.IsFloat:
 		val = r.mpfloat(b)
@@ -365,8 +369,8 @@
 	return
 }
 
-func (r *importReader) mpint(b *types.Basic) constant.Value {
-	signed, maxBytes := intSize(b)
+func (r *importReader) mpint(x *big.Int, typ *types.Basic) {
+	signed, maxBytes := intSize(typ)
 
 	maxSmall := 256 - maxBytes
 	if signed {
@@ -385,7 +389,8 @@
 				v = ^v
 			}
 		}
-		return constant.MakeInt64(v)
+		x.SetInt64(v)
+		return
 	}
 
 	v := -n
@@ -395,39 +400,23 @@
 	if v < 1 || uint(v) > maxBytes {
 		errorf("weird decoding: %v, %v => %v", n, signed, v)
 	}
-
-	buf := make([]byte, v)
-	io.ReadFull(&r.declReader, buf)
-
-	// convert to little endian
-	// TODO(gri) go/constant should have a more direct conversion function
-	//           (e.g., once it supports a big.Float based implementation)
-	for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {
-		buf[i], buf[j] = buf[j], buf[i]
-	}
-
-	x := constant.MakeFromBytes(buf)
+	b := make([]byte, v)
+	io.ReadFull(&r.declReader, b)
+	x.SetBytes(b)
 	if signed && n&1 != 0 {
-		x = constant.UnaryOp(token.SUB, x, 0)
+		x.Neg(x)
 	}
-	return x
 }
 
-func (r *importReader) mpfloat(b *types.Basic) constant.Value {
-	x := r.mpint(b)
-	if constant.Sign(x) == 0 {
-		return x
+func (r *importReader) mpfloat(typ *types.Basic) constant.Value {
+	var mant big.Int
+	r.mpint(&mant, typ)
+	var f big.Float
+	f.SetInt(&mant)
+	if f.Sign() != 0 {
+		f.SetMantExp(&f, int(r.int64()))
 	}
-
-	exp := r.int64()
-	switch {
-	case exp > 0:
-		x = constant.Shift(x, token.SHL, uint(exp))
-	case exp < 0:
-		d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
-		x = constant.BinaryOp(x, token.QUO, d)
-	}
-	return x
+	return constant.Make(&f)
 }
 
 func (r *importReader) ident() string {
diff --git a/src/go/internal/srcimporter/srcimporter.go b/src/go/internal/srcimporter/srcimporter.go
index 438ae0f..e4225eb 100644
--- a/src/go/internal/srcimporter/srcimporter.go
+++ b/src/go/internal/srcimporter/srcimporter.go
@@ -30,7 +30,7 @@
 	packages map[string]*types.Package
 }
 
-// NewImporter returns a new Importer for the given context, file set, and map
+// New returns a new Importer for the given context, file set, and map
 // of packages. The context is used to resolve import paths to package paths,
 // and identifying the files belonging to the package. If the context provides
 // non-nil file system functions, they are used instead of the regular package
diff --git a/src/go/internal/typeparams/common.go b/src/go/internal/typeparams/common.go
new file mode 100644
index 0000000..47b8f7c
--- /dev/null
+++ b/src/go/internal/typeparams/common.go
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package typeparams provides functions to work with type parameter data
+// stored in the AST, while these AST changes are guarded by a build
+// constraint.
+package typeparams
+
+// DisallowParsing is the numeric value of a parsing mode that disallows type
+// parameters. This only matters if the typeparams experiment is active, and
+// may be used for running tests that disallow generics.
+const DisallowParsing = 1 << 30
diff --git a/src/go/internal/typeparams/notypeparams.go b/src/go/internal/typeparams/notypeparams.go
new file mode 100644
index 0000000..2ceafaa
--- /dev/null
+++ b/src/go/internal/typeparams/notypeparams.go
@@ -0,0 +1,40 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !typeparams
+// +build !typeparams
+
+package typeparams
+
+import (
+	"go/ast"
+)
+
+const Enabled = false
+
+func PackExpr(list []ast.Expr) ast.Expr {
+	switch len(list) {
+	case 1:
+		return list[0]
+	default:
+		// The parser should not attempt to pack multiple expressions into an
+		// IndexExpr if type params are disabled.
+		panic("multiple index expressions are unsupported without type params")
+	}
+}
+
+func UnpackExpr(expr ast.Expr) []ast.Expr {
+	return []ast.Expr{expr}
+}
+
+func IsListExpr(n ast.Node) bool {
+	return false
+}
+
+func Get(ast.Node) *ast.FieldList {
+	return nil
+}
+
+func Set(node ast.Node, params *ast.FieldList) {
+}
diff --git a/src/go/internal/typeparams/typeparams.go b/src/go/internal/typeparams/typeparams.go
new file mode 100644
index 0000000..871e95d
--- /dev/null
+++ b/src/go/internal/typeparams/typeparams.go
@@ -0,0 +1,69 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build typeparams
+// +build typeparams
+
+package typeparams
+
+import (
+	"fmt"
+	"go/ast"
+)
+
+const Enabled = true
+
+func PackExpr(list []ast.Expr) ast.Expr {
+	switch len(list) {
+	case 0:
+		// Return an empty ListExpr here, rather than nil, as IndexExpr.Index must
+		// never be nil.
+		// TODO(rFindley) would a BadExpr be more appropriate here?
+		return &ast.ListExpr{}
+	case 1:
+		return list[0]
+	default:
+		return &ast.ListExpr{ElemList: list}
+	}
+}
+
+// TODO(gri) Should find a more efficient solution that doesn't
+//           require introduction of a new slice for simple
+//           expressions.
+func UnpackExpr(x ast.Expr) []ast.Expr {
+	if x, _ := x.(*ast.ListExpr); x != nil {
+		return x.ElemList
+	}
+	if x != nil {
+		return []ast.Expr{x}
+	}
+	return nil
+}
+
+func IsListExpr(n ast.Node) bool {
+	_, ok := n.(*ast.ListExpr)
+	return ok
+}
+
+func Get(n ast.Node) *ast.FieldList {
+	switch n := n.(type) {
+	case *ast.TypeSpec:
+		return n.TParams
+	case *ast.FuncType:
+		return n.TParams
+	default:
+		panic(fmt.Sprintf("node type %T has no type parameters", n))
+	}
+}
+
+func Set(n ast.Node, params *ast.FieldList) {
+	switch n := n.(type) {
+	case *ast.TypeSpec:
+		n.TParams = params
+	case *ast.FuncType:
+		n.TParams = params
+	default:
+		panic(fmt.Sprintf("node type %T has no type parameters", n))
+	}
+}
diff --git a/src/go/parser/error_test.go b/src/go/parser/error_test.go
index 358a844..f4f0a52 100644
--- a/src/go/parser/error_test.go
+++ b/src/go/parser/error_test.go
@@ -23,6 +23,7 @@
 package parser
 
 import (
+	"go/internal/typeparams"
 	"go/scanner"
 	"go/token"
 	"os"
@@ -89,7 +90,7 @@
 				if s[1] == "HERE" {
 					pos = here
 				}
-				errors[pos] = string(s[2])
+				errors[pos] = s[2]
 			}
 		case token.SEMICOLON:
 			// don't use the position of auto-inserted (invisible) semicolons
@@ -114,6 +115,7 @@
 // of found errors and reports discrepancies.
 //
 func compareErrors(t *testing.T, fset *token.FileSet, expected map[token.Pos]string, found scanner.ErrorList) {
+	t.Helper()
 	for _, error := range found {
 		// error.Pos is a token.Position, but we want
 		// a token.Pos so we can do a map lookup
@@ -149,7 +151,8 @@
 	}
 }
 
-func checkErrors(t *testing.T, filename string, input interface{}) {
+func checkErrors(t *testing.T, filename string, input interface{}, mode Mode, expectErrors bool) {
+	t.Helper()
 	src, err := readSource(filename, input)
 	if err != nil {
 		t.Error(err)
@@ -157,7 +160,7 @@
 	}
 
 	fset := token.NewFileSet()
-	_, err = ParseFile(fset, filename, src, DeclarationErrors|AllErrors)
+	_, err = ParseFile(fset, filename, src, mode)
 	found, ok := err.(scanner.ErrorList)
 	if err != nil && !ok {
 		t.Error(err)
@@ -165,9 +168,12 @@
 	}
 	found.RemoveMultiples()
 
-	// we are expecting the following errors
-	// (collect these after parsing a file so that it is found in the file set)
-	expected := expectedErrors(fset, filename, src)
+	expected := map[token.Pos]string{}
+	if expectErrors {
+		// we are expecting the following errors
+		// (collect these after parsing a file so that it is found in the file set)
+		expected = expectedErrors(fset, filename, src)
+	}
 
 	// verify errors returned by the parser
 	compareErrors(t, fset, expected, found)
@@ -180,8 +186,16 @@
 	}
 	for _, d := range list {
 		name := d.Name()
-		if !d.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".src") {
-			checkErrors(t, filepath.Join(testdata, name), nil)
+		if !d.IsDir() && !strings.HasPrefix(name, ".") && (strings.HasSuffix(name, ".src") || strings.HasSuffix(name, ".go2")) {
+			mode := DeclarationErrors | AllErrors
+			if strings.HasSuffix(name, ".go2") {
+				if !typeparams.Enabled {
+					continue
+				}
+			} else {
+				mode |= typeparams.DisallowParsing
+			}
+			checkErrors(t, filepath.Join(testdata, name), nil, mode, true)
 		}
 	}
 }
diff --git a/src/go/parser/interface.go b/src/go/parser/interface.go
index 56ff5fe..85486d2 100644
--- a/src/go/parser/interface.go
+++ b/src/go/parser/interface.go
@@ -49,13 +49,14 @@
 type Mode uint
 
 const (
-	PackageClauseOnly Mode             = 1 << iota // stop parsing after package clause
-	ImportsOnly                                    // stop parsing after import declarations
-	ParseComments                                  // parse comments and add them to AST
-	Trace                                          // print a trace of parsed productions
-	DeclarationErrors                              // report declaration errors
-	SpuriousErrors                                 // same as AllErrors, for backward-compatibility
-	AllErrors         = SpuriousErrors             // report all errors (not just the first 10 on different lines)
+	PackageClauseOnly    Mode             = 1 << iota // stop parsing after package clause
+	ImportsOnly                                       // stop parsing after import declarations
+	ParseComments                                     // parse comments and add them to AST
+	Trace                                             // print a trace of parsed productions
+	DeclarationErrors                                 // report declaration errors
+	SpuriousErrors                                    // same as AllErrors, for backward-compatibility
+	SkipObjectResolution                              // don't resolve identifiers to objects - see ParseFile
+	AllErrors            = SpuriousErrors             // report all errors (not just the first 10 on different lines)
 )
 
 // ParseFile parses the source code of a single Go source file and returns
@@ -68,8 +69,12 @@
 // If src == nil, ParseFile parses the file specified by filename.
 //
 // The mode parameter controls the amount of source text parsed and other
-// optional parser functionality. Position information is recorded in the
-// file set fset, which must not be nil.
+// optional parser functionality. If the SkipObjectResolution mode bit is set,
+// the object resolution phase of parsing will be skipped, causing File.Scope,
+// File.Unresolved, and all Ident.Obj fields to be nil.
+//
+// Position information is recorded in the file set fset, which must not be
+// nil.
 //
 // If the source couldn't be read, the returned AST is nil and the error
 // indicates the specific failure. If the source was read but syntax
@@ -208,15 +213,7 @@
 
 	// parse expr
 	p.init(fset, filename, text, mode)
-	// Set up pkg-level scopes to avoid nil-pointer errors.
-	// This is not needed for a correct expression x as the
-	// parser will be ok with a nil topScope, but be cautious
-	// in case of an erroneous x.
-	p.openScope()
-	p.pkgScope = p.topScope
 	expr = p.parseRhsOrType()
-	p.closeScope()
-	assert(p.topScope == nil, "unbalanced scopes")
 
 	// If a semicolon was inserted, consume it;
 	// report an error if there's more tokens.
diff --git a/src/go/parser/parser.go b/src/go/parser/parser.go
index 31a7398..f10c865 100644
--- a/src/go/parser/parser.go
+++ b/src/go/parser/parser.go
@@ -19,6 +19,7 @@
 import (
 	"fmt"
 	"go/ast"
+	"go/internal/typeparams"
 	"go/scanner"
 	"go/token"
 	"strconv"
@@ -34,7 +35,7 @@
 
 	// Tracing/debugging
 	mode   Mode // parsing mode
-	trace  bool // == (mode & Trace != 0)
+	trace  bool // == (mode&Trace != 0)
 	indent int  // indentation used for tracing output
 
 	// Comments
@@ -58,16 +59,7 @@
 	exprLev int  // < 0: in control clause, >= 0: in expression
 	inRhs   bool // if set, the parser is parsing a rhs expression
 
-	// Ordinary identifier scopes
-	pkgScope   *ast.Scope        // pkgScope.Outer == nil
-	topScope   *ast.Scope        // top-most scope; may be pkgScope
-	unresolved []*ast.Ident      // unresolved identifiers
-	imports    []*ast.ImportSpec // list of imports
-
-	// Label scopes
-	// (maintained by open/close LabelScope)
-	labelScope  *ast.Scope     // label scope for current function
-	targetStack [][]*ast.Ident // stack of unresolved labels
+	imports []*ast.ImportSpec // list of imports
 }
 
 func (p *parser) init(fset *token.FileSet, filename string, src []byte, mode Mode) {
@@ -81,129 +73,11 @@
 
 	p.mode = mode
 	p.trace = mode&Trace != 0 // for convenience (p.trace is used frequently)
-
 	p.next()
 }
 
-// ----------------------------------------------------------------------------
-// Scoping support
-
-func (p *parser) openScope() {
-	p.topScope = ast.NewScope(p.topScope)
-}
-
-func (p *parser) closeScope() {
-	p.topScope = p.topScope.Outer
-}
-
-func (p *parser) openLabelScope() {
-	p.labelScope = ast.NewScope(p.labelScope)
-	p.targetStack = append(p.targetStack, nil)
-}
-
-func (p *parser) closeLabelScope() {
-	// resolve labels
-	n := len(p.targetStack) - 1
-	scope := p.labelScope
-	for _, ident := range p.targetStack[n] {
-		ident.Obj = scope.Lookup(ident.Name)
-		if ident.Obj == nil && p.mode&DeclarationErrors != 0 {
-			p.error(ident.Pos(), fmt.Sprintf("label %s undefined", ident.Name))
-		}
-	}
-	// pop label scope
-	p.targetStack = p.targetStack[0:n]
-	p.labelScope = p.labelScope.Outer
-}
-
-func (p *parser) declare(decl, data interface{}, scope *ast.Scope, kind ast.ObjKind, idents ...*ast.Ident) {
-	for _, ident := range idents {
-		assert(ident.Obj == nil, "identifier already declared or resolved")
-		obj := ast.NewObj(kind, ident.Name)
-		// remember the corresponding declaration for redeclaration
-		// errors and global variable resolution/typechecking phase
-		obj.Decl = decl
-		obj.Data = data
-		ident.Obj = obj
-		if ident.Name != "_" {
-			if alt := scope.Insert(obj); alt != nil && p.mode&DeclarationErrors != 0 {
-				prevDecl := ""
-				if pos := alt.Pos(); pos.IsValid() {
-					prevDecl = fmt.Sprintf("\n\tprevious declaration at %s", p.file.Position(pos))
-				}
-				p.error(ident.Pos(), fmt.Sprintf("%s redeclared in this block%s", ident.Name, prevDecl))
-			}
-		}
-	}
-}
-
-func (p *parser) shortVarDecl(decl *ast.AssignStmt, list []ast.Expr) {
-	// Go spec: A short variable declaration may redeclare variables
-	// provided they were originally declared in the same block with
-	// the same type, and at least one of the non-blank variables is new.
-	n := 0 // number of new variables
-	for _, x := range list {
-		if ident, isIdent := x.(*ast.Ident); isIdent {
-			assert(ident.Obj == nil, "identifier already declared or resolved")
-			obj := ast.NewObj(ast.Var, ident.Name)
-			// remember corresponding assignment for other tools
-			obj.Decl = decl
-			ident.Obj = obj
-			if ident.Name != "_" {
-				if alt := p.topScope.Insert(obj); alt != nil {
-					ident.Obj = alt // redeclaration
-				} else {
-					n++ // new declaration
-				}
-			}
-		} else {
-			p.errorExpected(x.Pos(), "identifier on left side of :=")
-		}
-	}
-	if n == 0 && p.mode&DeclarationErrors != 0 {
-		p.error(list[0].Pos(), "no new variables on left side of :=")
-	}
-}
-
-// The unresolved object is a sentinel to mark identifiers that have been added
-// to the list of unresolved identifiers. The sentinel is only used for verifying
-// internal consistency.
-var unresolved = new(ast.Object)
-
-// If x is an identifier, tryResolve attempts to resolve x by looking up
-// the object it denotes. If no object is found and collectUnresolved is
-// set, x is marked as unresolved and collected in the list of unresolved
-// identifiers.
-//
-func (p *parser) tryResolve(x ast.Expr, collectUnresolved bool) {
-	// nothing to do if x is not an identifier or the blank identifier
-	ident, _ := x.(*ast.Ident)
-	if ident == nil {
-		return
-	}
-	assert(ident.Obj == nil, "identifier already declared or resolved")
-	if ident.Name == "_" {
-		return
-	}
-	// try to resolve the identifier
-	for s := p.topScope; s != nil; s = s.Outer {
-		if obj := s.Lookup(ident.Name); obj != nil {
-			ident.Obj = obj
-			return
-		}
-	}
-	// all local scopes are known, so any unresolved identifier
-	// must be found either in the file scope, package scope
-	// (perhaps in another file), or universe scope --- collect
-	// them so that they can be resolved later
-	if collectUnresolved {
-		ident.Obj = unresolved
-		p.unresolved = append(p.unresolved, ident)
-	}
-}
-
-func (p *parser) resolve(x ast.Expr) {
-	p.tryResolve(x, true)
+func (p *parser) parseTypeParams() bool {
+	return typeparams.Enabled && p.mode&typeparams.DisallowParsing == 0
 }
 
 // ----------------------------------------------------------------------------
@@ -241,7 +115,7 @@
 	// Because of one-token look-ahead, print the previous token
 	// when tracing as it provides a more readable output. The
 	// very first token (!p.pos.IsValid()) is not initialized
-	// (it is token.ILLEGAL), so don't print it .
+	// (it is token.ILLEGAL), so don't print it.
 	if p.trace && p.pos.IsValid() {
 		s := p.tok.String()
 		switch {
@@ -352,6 +226,10 @@
 type bailout struct{}
 
 func (p *parser) error(pos token.Pos, msg string) {
+	if p.trace {
+		defer un(trace(p, "error: "+msg))
+	}
+
 	epos := p.file.Position(pos)
 
 	// If AllErrors is not set, discard errors reported on the same line
@@ -573,52 +451,24 @@
 // Common productions
 
 // If lhs is set, result list elements which are identifiers are not resolved.
-func (p *parser) parseExprList(lhs bool) (list []ast.Expr) {
+func (p *parser) parseExprList() (list []ast.Expr) {
 	if p.trace {
 		defer un(trace(p, "ExpressionList"))
 	}
 
-	list = append(list, p.checkExpr(p.parseExpr(lhs)))
+	list = append(list, p.checkExpr(p.parseExpr()))
 	for p.tok == token.COMMA {
 		p.next()
-		list = append(list, p.checkExpr(p.parseExpr(lhs)))
+		list = append(list, p.checkExpr(p.parseExpr()))
 	}
 
 	return
 }
 
-func (p *parser) parseLhsList() []ast.Expr {
+func (p *parser) parseList(inRhs bool) []ast.Expr {
 	old := p.inRhs
-	p.inRhs = false
-	list := p.parseExprList(true)
-	switch p.tok {
-	case token.DEFINE:
-		// lhs of a short variable declaration
-		// but doesn't enter scope until later:
-		// caller must call p.shortVarDecl(p.makeIdentList(list))
-		// at appropriate time.
-	case token.COLON:
-		// lhs of a label declaration or a communication clause of a select
-		// statement (parseLhsList is not called when parsing the case clause
-		// of a switch statement):
-		// - labels are declared by the caller of parseLhsList
-		// - for communication clauses, if there is a stand-alone identifier
-		//   followed by a colon, we have a syntax error; there is no need
-		//   to resolve the identifier in that case
-	default:
-		// identifiers must be declared elsewhere
-		for _, x := range list {
-			p.resolve(x)
-		}
-	}
-	p.inRhs = old
-	return list
-}
-
-func (p *parser) parseRhsList() []ast.Expr {
-	old := p.inRhs
-	p.inRhs = true
-	list := p.parseExprList(false)
+	p.inRhs = inRhs
+	list := p.parseExprList()
 	p.inRhs = old
 	return list
 }
@@ -631,7 +481,7 @@
 		defer un(trace(p, "Type"))
 	}
 
-	typ := p.tryType()
+	typ := p.tryIdentOrType()
 
 	if typ == nil {
 		pos := p.pos
@@ -643,19 +493,32 @@
 	return typ
 }
 
+func (p *parser) parseQualifiedIdent(ident *ast.Ident) ast.Expr {
+	if p.trace {
+		defer un(trace(p, "QualifiedIdent"))
+	}
+
+	typ := p.parseTypeName(ident)
+	if p.tok == token.LBRACK && p.parseTypeParams() {
+		typ = p.parseTypeInstance(typ)
+	}
+
+	return typ
+}
+
 // If the result is an identifier, it is not resolved.
-func (p *parser) parseTypeName() ast.Expr {
+func (p *parser) parseTypeName(ident *ast.Ident) ast.Expr {
 	if p.trace {
 		defer un(trace(p, "TypeName"))
 	}
 
-	ident := p.parseIdent()
-	// don't resolve ident yet - it may be a parameter or field name
+	if ident == nil {
+		ident = p.parseIdent()
+	}
 
 	if p.tok == token.PERIOD {
 		// ident is a package name
 		p.next()
-		p.resolve(ident)
 		sel := p.parseIdent()
 		return &ast.SelectorExpr{X: ident, Sel: sel}
 	}
@@ -663,12 +526,11 @@
 	return ident
 }
 
-func (p *parser) parseArrayType() ast.Expr {
+func (p *parser) parseArrayLen() ast.Expr {
 	if p.trace {
-		defer un(trace(p, "ArrayType"))
+		defer un(trace(p, "ArrayLen"))
 	}
 
-	lbrack := p.expect(token.LBRACK)
 	p.exprLev++
 	var len ast.Expr
 	// always permit ellipsis for more fault-tolerant parsing
@@ -679,66 +541,111 @@
 		len = p.parseRhs()
 	}
 	p.exprLev--
-	p.expect(token.RBRACK)
-	elt := p.parseType()
 
-	return &ast.ArrayType{Lbrack: lbrack, Len: len, Elt: elt}
+	return len
 }
 
-func (p *parser) makeIdentList(list []ast.Expr) []*ast.Ident {
-	idents := make([]*ast.Ident, len(list))
-	for i, x := range list {
-		ident, isIdent := x.(*ast.Ident)
-		if !isIdent {
-			if _, isBad := x.(*ast.BadExpr); !isBad {
-				// only report error if it's a new one
-				p.errorExpected(x.Pos(), "identifier")
-			}
-			ident = &ast.Ident{NamePos: x.Pos(), Name: "_"}
-		}
-		idents[i] = ident
+func (p *parser) parseArrayFieldOrTypeInstance(x *ast.Ident) (*ast.Ident, ast.Expr) {
+	if p.trace {
+		defer un(trace(p, "ArrayFieldOrTypeInstance"))
 	}
-	return idents
+
+	// TODO(gri) Should we allow a trailing comma in a type argument
+	//           list such as T[P,]? (We do in parseTypeInstance).
+	lbrack := p.expect(token.LBRACK)
+	var args []ast.Expr
+	var firstComma token.Pos
+	// TODO(rfindley): consider changing parseRhsOrType so that this function variable
+	// is not needed.
+	argparser := p.parseRhsOrType
+	if !p.parseTypeParams() {
+		argparser = p.parseRhs
+	}
+	if p.tok != token.RBRACK {
+		p.exprLev++
+		args = append(args, argparser())
+		for p.tok == token.COMMA {
+			if !firstComma.IsValid() {
+				firstComma = p.pos
+			}
+			p.next()
+			args = append(args, argparser())
+		}
+		p.exprLev--
+	}
+	rbrack := p.expect(token.RBRACK)
+
+	if len(args) == 0 {
+		// x []E
+		elt := p.parseType()
+		return x, &ast.ArrayType{Lbrack: lbrack, Elt: elt}
+	}
+
+	// x [P]E or x[P]
+	if len(args) == 1 {
+		elt := p.tryIdentOrType()
+		if elt != nil {
+			// x [P]E
+			return x, &ast.ArrayType{Lbrack: lbrack, Len: args[0], Elt: elt}
+		}
+		if !p.parseTypeParams() {
+			p.error(rbrack, "missing element type in array type expression")
+			return nil, &ast.BadExpr{From: args[0].Pos(), To: args[0].End()}
+		}
+	}
+
+	if !p.parseTypeParams() {
+		p.error(firstComma, "expected ']', found ','")
+		return x, &ast.BadExpr{From: args[0].Pos(), To: args[len(args)-1].End()}
+	}
+
+	// x[P], x[P1, P2], ...
+	return nil, &ast.IndexExpr{X: x, Lbrack: lbrack, Index: typeparams.PackExpr(args), Rbrack: rbrack}
 }
 
-func (p *parser) parseFieldDecl(scope *ast.Scope) *ast.Field {
+func (p *parser) parseFieldDecl() *ast.Field {
 	if p.trace {
 		defer un(trace(p, "FieldDecl"))
 	}
 
 	doc := p.leadComment
 
-	// 1st FieldDecl
-	// A type name used as an anonymous field looks like a field identifier.
-	var list []ast.Expr
-	for {
-		list = append(list, p.parseVarType(false))
-		if p.tok != token.COMMA {
-			break
+	var names []*ast.Ident
+	var typ ast.Expr
+	if p.tok == token.IDENT {
+		name := p.parseIdent()
+		if p.tok == token.PERIOD || p.tok == token.STRING || p.tok == token.SEMICOLON || p.tok == token.RBRACE {
+			// embedded type
+			typ = name
+			if p.tok == token.PERIOD {
+				typ = p.parseQualifiedIdent(name)
+			}
+		} else {
+			// name1, name2, ... T
+			names = []*ast.Ident{name}
+			for p.tok == token.COMMA {
+				p.next()
+				names = append(names, p.parseIdent())
+			}
+			// Careful dance: We don't know if we have an embedded instantiated
+			// type T[P1, P2, ...] or a field T of array type []E or [P]E.
+			if len(names) == 1 && p.tok == token.LBRACK {
+				name, typ = p.parseArrayFieldOrTypeInstance(name)
+				if name == nil {
+					names = nil
+				}
+			} else {
+				// T P
+				typ = p.parseType()
+			}
 		}
-		p.next()
-	}
-
-	typ := p.tryVarType(false)
-
-	// analyze case
-	var idents []*ast.Ident
-	if typ != nil {
-		// IdentifierList Type
-		idents = p.makeIdentList(list)
 	} else {
-		// ["*"] TypeName (AnonymousField)
-		typ = list[0] // we always have at least one element
-		if n := len(list); n > 1 {
-			p.errorExpected(p.pos, "type")
-			typ = &ast.BadExpr{From: p.pos, To: p.pos}
-		} else if !isTypeName(deref(typ)) {
-			p.errorExpected(typ.Pos(), "anonymous field")
-			typ = &ast.BadExpr{From: typ.Pos(), To: p.safePos(typ.End())}
-		}
+		// embedded, possibly generic type
+		// (using the enclosing parentheses to distinguish it from a named field declaration)
+		// TODO(rFindley) confirm that this doesn't allow parenthesized embedded type
+		typ = p.parseType()
 	}
 
-	// Tag
 	var tag *ast.BasicLit
 	if p.tok == token.STRING {
 		tag = &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit}
@@ -747,10 +654,7 @@
 
 	p.expectSemi() // call before accessing p.linecomment
 
-	field := &ast.Field{Doc: doc, Names: idents, Type: typ, Tag: tag, Comment: p.lineComment}
-	p.declare(field, nil, scope, ast.Var, idents...)
-	p.resolve(typ)
-
+	field := &ast.Field{Doc: doc, Names: names, Type: typ, Tag: tag, Comment: p.lineComment}
 	return field
 }
 
@@ -761,13 +665,12 @@
 
 	pos := p.expect(token.STRUCT)
 	lbrace := p.expect(token.LBRACE)
-	scope := ast.NewScope(nil) // struct scope
 	var list []*ast.Field
 	for p.tok == token.IDENT || p.tok == token.MUL || p.tok == token.LPAREN {
 		// a field declaration cannot start with a '(' but we accept
 		// it here for more robust parsing and better error messages
 		// (parseFieldDecl will check and complain if necessary)
-		list = append(list, p.parseFieldDecl(scope))
+		list = append(list, p.parseFieldDecl())
 	}
 	rbrace := p.expect(token.RBRACE)
 
@@ -792,119 +695,232 @@
 	return &ast.StarExpr{Star: star, X: base}
 }
 
-// If the result is an identifier, it is not resolved.
-func (p *parser) tryVarType(isParam bool) ast.Expr {
-	if isParam && p.tok == token.ELLIPSIS {
-		pos := p.pos
-		p.next()
-		typ := p.tryIdentOrType() // don't use parseType so we can provide better error message
-		if typ != nil {
-			p.resolve(typ)
+func (p *parser) parseDotsType() *ast.Ellipsis {
+	if p.trace {
+		defer un(trace(p, "DotsType"))
+	}
+
+	pos := p.expect(token.ELLIPSIS)
+	elt := p.parseType()
+
+	return &ast.Ellipsis{Ellipsis: pos, Elt: elt}
+}
+
+type field struct {
+	name *ast.Ident
+	typ  ast.Expr
+}
+
+func (p *parser) parseParamDecl(name *ast.Ident) (f field) {
+	// TODO(rFindley) compare with parser.paramDeclOrNil in the syntax package
+	if p.trace {
+		defer un(trace(p, "ParamDeclOrNil"))
+	}
+
+	ptok := p.tok
+	if name != nil {
+		p.tok = token.IDENT // force token.IDENT case in switch below
+	}
+
+	switch p.tok {
+	case token.IDENT:
+		if name != nil {
+			f.name = name
+			p.tok = ptok
 		} else {
-			p.error(pos, "'...' parameter is missing type")
-			typ = &ast.BadExpr{From: pos, To: p.pos}
+			f.name = p.parseIdent()
 		}
-		return &ast.Ellipsis{Ellipsis: pos, Elt: typ}
+		switch p.tok {
+		case token.IDENT, token.MUL, token.ARROW, token.FUNC, token.CHAN, token.MAP, token.STRUCT, token.INTERFACE, token.LPAREN:
+			// name type
+			f.typ = p.parseType()
+
+		case token.LBRACK:
+			// name[type1, type2, ...] or name []type or name [len]type
+			f.name, f.typ = p.parseArrayFieldOrTypeInstance(f.name)
+
+		case token.ELLIPSIS:
+			// name ...type
+			f.typ = p.parseDotsType()
+
+		case token.PERIOD:
+			// qualified.typename
+			f.typ = p.parseQualifiedIdent(f.name)
+			f.name = nil
+		}
+
+	case token.MUL, token.ARROW, token.FUNC, token.LBRACK, token.CHAN, token.MAP, token.STRUCT, token.INTERFACE, token.LPAREN:
+		// type
+		f.typ = p.parseType()
+
+	case token.ELLIPSIS:
+		// ...type
+		// (always accepted)
+		f.typ = p.parseDotsType()
+
+	default:
+		p.errorExpected(p.pos, ")")
+		p.advance(exprEnd)
 	}
-	return p.tryIdentOrType()
+
+	return
 }
 
-// If the result is an identifier, it is not resolved.
-func (p *parser) parseVarType(isParam bool) ast.Expr {
-	typ := p.tryVarType(isParam)
-	if typ == nil {
-		pos := p.pos
-		p.errorExpected(pos, "type")
-		p.next() // make progress
-		typ = &ast.BadExpr{From: pos, To: p.pos}
-	}
-	return typ
-}
-
-func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params []*ast.Field) {
+func (p *parser) parseParameterList(name0 *ast.Ident, closing token.Token, parseParamDecl func(*ast.Ident) field, tparams bool) (params []*ast.Field) {
 	if p.trace {
 		defer un(trace(p, "ParameterList"))
 	}
 
-	// 1st ParameterDecl
-	// A list of identifiers looks like a list of type names.
-	var list []ast.Expr
-	for {
-		list = append(list, p.parseVarType(ellipsisOk))
-		if p.tok != token.COMMA {
+	pos := p.pos
+	if name0 != nil {
+		pos = name0.Pos()
+	}
+
+	var list []field
+	var named int // number of parameters that have an explicit name and type
+
+	for name0 != nil || p.tok != closing && p.tok != token.EOF {
+		par := parseParamDecl(name0)
+		name0 = nil // 1st name was consumed if present
+		if par.name != nil || par.typ != nil {
+			list = append(list, par)
+			if par.name != nil && par.typ != nil {
+				named++
+			}
+		}
+		if !p.atComma("parameter list", closing) {
 			break
 		}
 		p.next()
-		if p.tok == token.RPAREN {
-			break
+	}
+
+	if len(list) == 0 {
+		return // not uncommon
+	}
+
+	// TODO(gri) parameter distribution and conversion to []*ast.Field
+	//           can be combined and made more efficient
+
+	// distribute parameter types
+	if named == 0 {
+		// all unnamed => found names are type names
+		for i := 0; i < len(list); i++ {
+			par := &list[i]
+			if typ := par.name; typ != nil {
+				par.typ = typ
+				par.name = nil
+			}
+		}
+		if tparams {
+			p.error(pos, "all type parameters must be named")
+		}
+	} else if named != len(list) {
+		// some named => all must be named
+		ok := true
+		var typ ast.Expr
+		for i := len(list) - 1; i >= 0; i-- {
+			if par := &list[i]; par.typ != nil {
+				typ = par.typ
+				if par.name == nil {
+					ok = false
+					n := ast.NewIdent("_")
+					n.NamePos = typ.Pos() // correct position
+					par.name = n
+				}
+			} else if typ != nil {
+				par.typ = typ
+			} else {
+				// par.typ == nil && typ == nil => we only have a par.name
+				ok = false
+				par.typ = &ast.BadExpr{From: par.name.Pos(), To: p.pos}
+			}
+		}
+		if !ok {
+			if tparams {
+				p.error(pos, "all type parameters must be named")
+			} else {
+				p.error(pos, "mixed named and unnamed parameters")
+			}
 		}
 	}
 
-	// analyze case
-	if typ := p.tryVarType(ellipsisOk); typ != nil {
-		// IdentifierList Type
-		idents := p.makeIdentList(list)
-		field := &ast.Field{Names: idents, Type: typ}
-		params = append(params, field)
-		// Go spec: The scope of an identifier denoting a function
-		// parameter or result variable is the function body.
-		p.declare(field, nil, scope, ast.Var, idents...)
-		p.resolve(typ)
-		if !p.atComma("parameter list", token.RPAREN) {
-			return
-		}
-		p.next()
-		for p.tok != token.RPAREN && p.tok != token.EOF {
-			idents := p.parseIdentList()
-			typ := p.parseVarType(ellipsisOk)
-			field := &ast.Field{Names: idents, Type: typ}
-			params = append(params, field)
-			// Go spec: The scope of an identifier denoting a function
-			// parameter or result variable is the function body.
-			p.declare(field, nil, scope, ast.Var, idents...)
-			p.resolve(typ)
-			if !p.atComma("parameter list", token.RPAREN) {
-				break
-			}
-			p.next()
+	// convert list []*ast.Field
+	if named == 0 {
+		// parameter list consists of types only
+		for _, par := range list {
+			assert(par.typ != nil, "nil type in unnamed parameter list")
+			params = append(params, &ast.Field{Type: par.typ})
 		}
 		return
 	}
 
-	// Type { "," Type } (anonymous parameters)
-	params = make([]*ast.Field, len(list))
-	for i, typ := range list {
-		p.resolve(typ)
-		params[i] = &ast.Field{Type: typ}
+	// parameter list consists of named parameters with types
+	var names []*ast.Ident
+	var typ ast.Expr
+	addParams := func() {
+		assert(typ != nil, "nil type in named parameter list")
+		field := &ast.Field{Names: names, Type: typ}
+		params = append(params, field)
+		names = nil
+	}
+	for _, par := range list {
+		if par.typ != typ {
+			if len(names) > 0 {
+				addParams()
+			}
+			typ = par.typ
+		}
+		names = append(names, par.name)
+	}
+	if len(names) > 0 {
+		addParams()
 	}
 	return
 }
 
-func (p *parser) parseParameters(scope *ast.Scope, ellipsisOk bool) *ast.FieldList {
+func (p *parser) parseParameters(acceptTParams bool) (tparams, params *ast.FieldList) {
 	if p.trace {
 		defer un(trace(p, "Parameters"))
 	}
 
-	var params []*ast.Field
-	lparen := p.expect(token.LPAREN)
-	if p.tok != token.RPAREN {
-		params = p.parseParameterList(scope, ellipsisOk)
+	if p.parseTypeParams() && acceptTParams && p.tok == token.LBRACK {
+		opening := p.pos
+		p.next()
+		// [T any](params) syntax
+		list := p.parseParameterList(nil, token.RBRACK, p.parseParamDecl, true)
+		rbrack := p.expect(token.RBRACK)
+		tparams = &ast.FieldList{Opening: opening, List: list, Closing: rbrack}
+		// Type parameter lists must not be empty.
+		if tparams.NumFields() == 0 {
+			p.error(tparams.Closing, "empty type parameter list")
+			tparams = nil // avoid follow-on errors
+		}
 	}
-	rparen := p.expect(token.RPAREN)
 
-	return &ast.FieldList{Opening: lparen, List: params, Closing: rparen}
+	opening := p.expect(token.LPAREN)
+
+	var fields []*ast.Field
+	if p.tok != token.RPAREN {
+		fields = p.parseParameterList(nil, token.RPAREN, p.parseParamDecl, false)
+	}
+
+	rparen := p.expect(token.RPAREN)
+	params = &ast.FieldList{Opening: opening, List: fields, Closing: rparen}
+
+	return
 }
 
-func (p *parser) parseResult(scope *ast.Scope) *ast.FieldList {
+func (p *parser) parseResult() *ast.FieldList {
 	if p.trace {
 		defer un(trace(p, "Result"))
 	}
 
 	if p.tok == token.LPAREN {
-		return p.parseParameters(scope, false)
+		_, results := p.parseParameters(false)
+		return results
 	}
 
-	typ := p.tryType()
+	typ := p.tryIdentOrType()
 	if typ != nil {
 		list := make([]*ast.Field, 1)
 		list[0] = &ast.Field{Type: typ}
@@ -914,30 +930,22 @@
 	return nil
 }
 
-func (p *parser) parseSignature(scope *ast.Scope) (params, results *ast.FieldList) {
-	if p.trace {
-		defer un(trace(p, "Signature"))
-	}
-
-	params = p.parseParameters(scope, true)
-	results = p.parseResult(scope)
-
-	return
-}
-
-func (p *parser) parseFuncType() (*ast.FuncType, *ast.Scope) {
+func (p *parser) parseFuncType() *ast.FuncType {
 	if p.trace {
 		defer un(trace(p, "FuncType"))
 	}
 
 	pos := p.expect(token.FUNC)
-	scope := ast.NewScope(p.topScope) // function scope
-	params, results := p.parseSignature(scope)
+	tparams, params := p.parseParameters(true)
+	if tparams != nil {
+		p.error(tparams.Pos(), "function type cannot have type parameters")
+	}
+	results := p.parseResult()
 
-	return &ast.FuncType{Func: pos, Params: params, Results: results}, scope
+	return &ast.FuncType{Func: pos, Params: params, Results: results}
 }
 
-func (p *parser) parseMethodSpec(scope *ast.Scope) *ast.Field {
+func (p *parser) parseMethodSpec() *ast.Field {
 	if p.trace {
 		defer un(trace(p, "MethodSpec"))
 	}
@@ -945,22 +953,67 @@
 	doc := p.leadComment
 	var idents []*ast.Ident
 	var typ ast.Expr
-	x := p.parseTypeName()
-	if ident, isIdent := x.(*ast.Ident); isIdent && p.tok == token.LPAREN {
-		// method
-		idents = []*ast.Ident{ident}
-		scope := ast.NewScope(nil) // method scope
-		params, results := p.parseSignature(scope)
-		typ = &ast.FuncType{Func: token.NoPos, Params: params, Results: results}
+	x := p.parseTypeName(nil)
+	if ident, _ := x.(*ast.Ident); ident != nil {
+		switch {
+		case p.tok == token.LBRACK && p.parseTypeParams():
+			// generic method or embedded instantiated type
+			lbrack := p.pos
+			p.next()
+			p.exprLev++
+			x := p.parseExpr()
+			p.exprLev--
+			if name0, _ := x.(*ast.Ident); name0 != nil && p.tok != token.COMMA && p.tok != token.RBRACK {
+				// generic method m[T any]
+				list := p.parseParameterList(name0, token.RBRACK, p.parseParamDecl, true)
+				rbrack := p.expect(token.RBRACK)
+				tparams := &ast.FieldList{Opening: lbrack, List: list, Closing: rbrack}
+				// TODO(rfindley) refactor to share code with parseFuncType.
+				_, params := p.parseParameters(false)
+				results := p.parseResult()
+				idents = []*ast.Ident{ident}
+				typ = &ast.FuncType{Func: token.NoPos, Params: params, Results: results}
+				typeparams.Set(typ, tparams)
+			} else {
+				// embedded instantiated type
+				// TODO(rfindley) should resolve all identifiers in x.
+				list := []ast.Expr{x}
+				if p.atComma("type argument list", token.RBRACK) {
+					p.exprLev++
+					for p.tok != token.RBRACK && p.tok != token.EOF {
+						list = append(list, p.parseType())
+						if !p.atComma("type argument list", token.RBRACK) {
+							break
+						}
+						p.next()
+					}
+					p.exprLev--
+				}
+				rbrack := p.expectClosing(token.RBRACK, "type argument list")
+				typ = &ast.IndexExpr{X: ident, Lbrack: lbrack, Index: typeparams.PackExpr(list), Rbrack: rbrack}
+			}
+		case p.tok == token.LPAREN:
+			// ordinary method
+			// TODO(rfindley) refactor to share code with parseFuncType.
+			_, params := p.parseParameters(false)
+			results := p.parseResult()
+			idents = []*ast.Ident{ident}
+			typ = &ast.FuncType{Func: token.NoPos, Params: params, Results: results}
+		default:
+			// embedded type
+			typ = x
+		}
 	} else {
-		// embedded interface
+		// embedded, possibly instantiated type
 		typ = x
-		p.resolve(typ)
+		if p.tok == token.LBRACK && p.parseTypeParams() {
+			// embedded instantiated interface
+			typ = p.parseTypeInstance(typ)
+		}
 	}
 	p.expectSemi() // call before accessing p.linecomment
 
 	spec := &ast.Field{Doc: doc, Names: idents, Type: typ, Comment: p.lineComment}
-	p.declare(spec, nil, scope, ast.Fun, idents...)
 
 	return spec
 }
@@ -972,11 +1025,24 @@
 
 	pos := p.expect(token.INTERFACE)
 	lbrace := p.expect(token.LBRACE)
-	scope := ast.NewScope(nil) // interface scope
 	var list []*ast.Field
-	for p.tok == token.IDENT {
-		list = append(list, p.parseMethodSpec(scope))
+	for p.tok == token.IDENT || p.parseTypeParams() && p.tok == token.TYPE {
+		if p.tok == token.IDENT {
+			list = append(list, p.parseMethodSpec())
+		} else {
+			// all types in a type list share the same field name "type"
+			// (since type is a keyword, a Go program cannot have that field name)
+			name := []*ast.Ident{{NamePos: p.pos, Name: "type"}}
+			p.next()
+			// add each type as a field named "type"
+			for _, typ := range p.parseTypeList() {
+				list = append(list, &ast.Field{Names: name, Type: typ})
+			}
+			p.expectSemi()
+		}
 	}
+	// TODO(rfindley): the error produced here could be improved, since we could
+	// accept a identifier, 'type', or a '}' at this point.
 	rbrace := p.expect(token.RBRACE)
 
 	return &ast.InterfaceType{
@@ -1028,19 +1094,50 @@
 	return &ast.ChanType{Begin: pos, Arrow: arrow, Dir: dir, Value: value}
 }
 
-// If the result is an identifier, it is not resolved.
+func (p *parser) parseTypeInstance(typ ast.Expr) ast.Expr {
+	assert(p.parseTypeParams(), "parseTypeInstance while not parsing type params")
+	if p.trace {
+		defer un(trace(p, "TypeInstance"))
+	}
+
+	opening := p.expect(token.LBRACK)
+
+	p.exprLev++
+	var list []ast.Expr
+	for p.tok != token.RBRACK && p.tok != token.EOF {
+		list = append(list, p.parseType())
+		if !p.atComma("type argument list", token.RBRACK) {
+			break
+		}
+		p.next()
+	}
+	p.exprLev--
+
+	closing := p.expectClosing(token.RBRACK, "type argument list")
+
+	return &ast.IndexExpr{X: typ, Lbrack: opening, Index: typeparams.PackExpr(list), Rbrack: closing}
+}
+
 func (p *parser) tryIdentOrType() ast.Expr {
 	switch p.tok {
 	case token.IDENT:
-		return p.parseTypeName()
+		typ := p.parseTypeName(nil)
+		if p.tok == token.LBRACK && p.parseTypeParams() {
+			typ = p.parseTypeInstance(typ)
+		}
+		return typ
 	case token.LBRACK:
-		return p.parseArrayType()
+		lbrack := p.expect(token.LBRACK)
+		alen := p.parseArrayLen()
+		p.expect(token.RBRACK)
+		elt := p.parseType()
+		return &ast.ArrayType{Lbrack: lbrack, Len: alen, Elt: elt}
 	case token.STRUCT:
 		return p.parseStructType()
 	case token.MUL:
 		return p.parsePointerType()
 	case token.FUNC:
-		typ, _ := p.parseFuncType()
+		typ := p.parseFuncType()
 		return typ
 	case token.INTERFACE:
 		return p.parseInterfaceType()
@@ -1060,14 +1157,6 @@
 	return nil
 }
 
-func (p *parser) tryType() ast.Expr {
-	typ := p.tryIdentOrType()
-	if typ != nil {
-		p.resolve(typ)
-	}
-	return typ
-}
-
 // ----------------------------------------------------------------------------
 // Blocks
 
@@ -1083,17 +1172,13 @@
 	return
 }
 
-func (p *parser) parseBody(scope *ast.Scope) *ast.BlockStmt {
+func (p *parser) parseBody() *ast.BlockStmt {
 	if p.trace {
 		defer un(trace(p, "Body"))
 	}
 
 	lbrace := p.expect(token.LBRACE)
-	p.topScope = scope // open function scope
-	p.openLabelScope()
 	list := p.parseStmtList()
-	p.closeLabelScope()
-	p.closeScope()
 	rbrace := p.expect2(token.RBRACE)
 
 	return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
@@ -1105,9 +1190,7 @@
 	}
 
 	lbrace := p.expect(token.LBRACE)
-	p.openScope()
 	list := p.parseStmtList()
-	p.closeScope()
 	rbrace := p.expect2(token.RBRACE)
 
 	return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
@@ -1121,14 +1204,14 @@
 		defer un(trace(p, "FuncTypeOrLit"))
 	}
 
-	typ, scope := p.parseFuncType()
+	typ := p.parseFuncType()
 	if p.tok != token.LBRACE {
 		// function type only
 		return typ
 	}
 
 	p.exprLev++
-	body := p.parseBody(scope)
+	body := p.parseBody()
 	p.exprLev--
 
 	return &ast.FuncLit{Type: typ, Body: body}
@@ -1136,9 +1219,8 @@
 
 // parseOperand may return an expression or a raw type (incl. array
 // types of the form [...]T. Callers must verify the result.
-// If lhs is set and the result is an identifier, it is not resolved.
 //
-func (p *parser) parseOperand(lhs bool) ast.Expr {
+func (p *parser) parseOperand() ast.Expr {
 	if p.trace {
 		defer un(trace(p, "Operand"))
 	}
@@ -1146,9 +1228,6 @@
 	switch p.tok {
 	case token.IDENT:
 		x := p.parseIdent()
-		if !lhs {
-			p.resolve(x)
-		}
 		return x
 
 	case token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING:
@@ -1169,7 +1248,7 @@
 		return p.parseFuncTypeOrLit()
 	}
 
-	if typ := p.tryIdentOrType(); typ != nil {
+	if typ := p.tryIdentOrType(); typ != nil { // do not consume trailing type parameters
 		// could be type for composite literal or conversion
 		_, isIdent := typ.(*ast.Ident)
 		assert(!isIdent, "type cannot be identifier")
@@ -1211,28 +1290,61 @@
 	return &ast.TypeAssertExpr{X: x, Type: typ, Lparen: lparen, Rparen: rparen}
 }
 
-func (p *parser) parseIndexOrSlice(x ast.Expr) ast.Expr {
+func (p *parser) parseIndexOrSliceOrInstance(x ast.Expr) ast.Expr {
 	if p.trace {
-		defer un(trace(p, "IndexOrSlice"))
+		defer un(trace(p, "parseIndexOrSliceOrInstance"))
 	}
 
-	const N = 3 // change the 3 to 2 to disable 3-index slices
 	lbrack := p.expect(token.LBRACK)
-	p.exprLev++
-	var index [N]ast.Expr
-	var colons [N - 1]token.Pos
-	if p.tok != token.COLON {
-		index[0] = p.parseRhs()
-	}
-	ncolons := 0
-	for p.tok == token.COLON && ncolons < len(colons) {
-		colons[ncolons] = p.pos
-		ncolons++
+	if p.tok == token.RBRACK {
+		// empty index, slice or index expressions are not permitted;
+		// accept them for parsing tolerance, but complain
+		p.errorExpected(p.pos, "operand")
+		rbrack := p.pos
 		p.next()
-		if p.tok != token.COLON && p.tok != token.RBRACK && p.tok != token.EOF {
-			index[ncolons] = p.parseRhs()
+		return &ast.IndexExpr{
+			X:      x,
+			Lbrack: lbrack,
+			Index:  &ast.BadExpr{From: rbrack, To: rbrack},
+			Rbrack: rbrack,
 		}
 	}
+	p.exprLev++
+
+	const N = 3 // change the 3 to 2 to disable 3-index slices
+	var args []ast.Expr
+	var index [N]ast.Expr
+	var colons [N - 1]token.Pos
+	var firstComma token.Pos
+	if p.tok != token.COLON {
+		// We can't know if we have an index expression or a type instantiation;
+		// so even if we see a (named) type we are not going to be in type context.
+		index[0] = p.parseRhsOrType()
+	}
+	ncolons := 0
+	switch p.tok {
+	case token.COLON:
+		// slice expression
+		for p.tok == token.COLON && ncolons < len(colons) {
+			colons[ncolons] = p.pos
+			ncolons++
+			p.next()
+			if p.tok != token.COLON && p.tok != token.RBRACK && p.tok != token.EOF {
+				index[ncolons] = p.parseRhs()
+			}
+		}
+	case token.COMMA:
+		firstComma = p.pos
+		// instance expression
+		args = append(args, index[0])
+		for p.tok == token.COMMA {
+			p.next()
+			if p.tok != token.RBRACK && p.tok != token.EOF {
+				args = append(args, p.parseType())
+			}
+		}
+	}
+
 	p.exprLev--
 	rbrack := p.expect(token.RBRACK)
 
@@ -1255,7 +1367,18 @@
 		return &ast.SliceExpr{X: x, Lbrack: lbrack, Low: index[0], High: index[1], Max: index[2], Slice3: slice3, Rbrack: rbrack}
 	}
 
-	return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: index[0], Rbrack: rbrack}
+	if len(args) == 0 {
+		// index expression
+		return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: index[0], Rbrack: rbrack}
+	}
+
+	if !p.parseTypeParams() {
+		p.error(firstComma, "expected ']' or ':', found ','")
+		return &ast.BadExpr{From: args[0].Pos(), To: args[len(args)-1].End()}
+	}
+
+	// instance expression
+	return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: typeparams.PackExpr(args), Rbrack: rbrack}
 }
 
 func (p *parser) parseCallOrConversion(fun ast.Expr) *ast.CallExpr {
@@ -1284,7 +1407,7 @@
 	return &ast.CallExpr{Fun: fun, Lparen: lparen, Args: list, Ellipsis: ellipsis, Rparen: rparen}
 }
 
-func (p *parser) parseValue(keyOk bool) ast.Expr {
+func (p *parser) parseValue() ast.Expr {
 	if p.trace {
 		defer un(trace(p, "Element"))
 	}
@@ -1293,35 +1416,7 @@
 		return p.parseLiteralValue(nil)
 	}
 
-	// Because the parser doesn't know the composite literal type, it cannot
-	// know if a key that's an identifier is a struct field name or a name
-	// denoting a value. The former is not resolved by the parser or the
-	// resolver.
-	//
-	// Instead, _try_ to resolve such a key if possible. If it resolves,
-	// it a) has correctly resolved, or b) incorrectly resolved because
-	// the key is a struct field with a name matching another identifier.
-	// In the former case we are done, and in the latter case we don't
-	// care because the type checker will do a separate field lookup.
-	//
-	// If the key does not resolve, it a) must be defined at the top
-	// level in another file of the same package, the universe scope, or be
-	// undeclared; or b) it is a struct field. In the former case, the type
-	// checker can do a top-level lookup, and in the latter case it will do
-	// a separate field lookup.
-	x := p.checkExpr(p.parseExpr(keyOk))
-	if keyOk {
-		if p.tok == token.COLON {
-			// Try to resolve the key but don't collect it
-			// as unresolved identifier if it fails so that
-			// we don't get (possibly false) errors about
-			// undeclared names.
-			p.tryResolve(x, false)
-		} else {
-			// not a key
-			p.resolve(x)
-		}
-	}
+	x := p.checkExpr(p.parseExpr())
 
 	return x
 }
@@ -1331,11 +1426,11 @@
 		defer un(trace(p, "Element"))
 	}
 
-	x := p.parseValue(true)
+	x := p.parseValue()
 	if p.tok == token.COLON {
 		colon := p.pos
 		p.next()
-		x = &ast.KeyValueExpr{Key: x, Colon: colon, Value: p.parseValue(false)}
+		x = &ast.KeyValueExpr{Key: x, Colon: colon, Value: p.parseValue()}
 	}
 
 	return x
@@ -1404,45 +1499,6 @@
 	return x
 }
 
-// isTypeName reports whether x is a (qualified) TypeName.
-func isTypeName(x ast.Expr) bool {
-	switch t := x.(type) {
-	case *ast.BadExpr:
-	case *ast.Ident:
-	case *ast.SelectorExpr:
-		_, isIdent := t.X.(*ast.Ident)
-		return isIdent
-	default:
-		return false // all other nodes are not type names
-	}
-	return true
-}
-
-// isLiteralType reports whether x is a legal composite literal type.
-func isLiteralType(x ast.Expr) bool {
-	switch t := x.(type) {
-	case *ast.BadExpr:
-	case *ast.Ident:
-	case *ast.SelectorExpr:
-		_, isIdent := t.X.(*ast.Ident)
-		return isIdent
-	case *ast.ArrayType:
-	case *ast.StructType:
-	case *ast.MapType:
-	default:
-		return false // all other nodes are not legal composite literal types
-	}
-	return true
-}
-
-// If x is of the form *T, deref returns T, otherwise it returns x.
-func deref(x ast.Expr) ast.Expr {
-	if p, isPtr := x.(*ast.StarExpr); isPtr {
-		x = p.X
-	}
-	return x
-}
-
 // If x is of the form (T), unparen returns unparen(T), otherwise it returns x.
 func unparen(x ast.Expr) ast.Expr {
 	if p, isParen := x.(*ast.ParenExpr); isParen {
@@ -1469,21 +1525,16 @@
 	return x
 }
 
-// If lhs is set and the result is an identifier, it is not resolved.
-func (p *parser) parsePrimaryExpr(lhs bool) ast.Expr {
+func (p *parser) parsePrimaryExpr() (x ast.Expr) {
 	if p.trace {
 		defer un(trace(p, "PrimaryExpr"))
 	}
 
-	x := p.parseOperand(lhs)
-L:
+	x = p.parseOperand()
 	for {
 		switch p.tok {
 		case token.PERIOD:
 			p.next()
-			if lhs {
-				p.resolve(x)
-			}
 			switch p.tok {
 			case token.IDENT:
 				x = p.parseSelector(p.checkExprOrType(x))
@@ -1492,40 +1543,54 @@
 			default:
 				pos := p.pos
 				p.errorExpected(pos, "selector or type assertion")
-				p.next() // make progress
+				// TODO(rFindley) The check for token.RBRACE below is a targeted fix
+				//                to error recovery sufficient to make the x/tools tests to
+				//                pass with the new parsing logic introduced for type
+				//                parameters. Remove this once error recovery has been
+				//                more generally reconsidered.
+				if p.tok != token.RBRACE {
+					p.next() // make progress
+				}
 				sel := &ast.Ident{NamePos: pos, Name: "_"}
 				x = &ast.SelectorExpr{X: x, Sel: sel}
 			}
 		case token.LBRACK:
-			if lhs {
-				p.resolve(x)
-			}
-			x = p.parseIndexOrSlice(p.checkExpr(x))
+			x = p.parseIndexOrSliceOrInstance(p.checkExpr(x))
 		case token.LPAREN:
-			if lhs {
-				p.resolve(x)
-			}
 			x = p.parseCallOrConversion(p.checkExprOrType(x))
 		case token.LBRACE:
-			if isLiteralType(x) && (p.exprLev >= 0 || !isTypeName(x)) {
-				if lhs {
-					p.resolve(x)
+			// operand may have returned a parenthesized complit
+			// type; accept it but complain if we have a complit
+			t := unparen(x)
+			// determine if '{' belongs to a composite literal or a block statement
+			switch t.(type) {
+			case *ast.BadExpr, *ast.Ident, *ast.SelectorExpr:
+				if p.exprLev < 0 {
+					return
 				}
-				x = p.parseLiteralValue(x)
-			} else {
-				break L
+				// x is possibly a composite literal type
+			case *ast.IndexExpr:
+				if p.exprLev < 0 {
+					return
+				}
+				// x is possibly a composite literal type
+			case *ast.ArrayType, *ast.StructType, *ast.MapType:
+				// x is a composite literal type
+			default:
+				return
 			}
+			if t != x {
+				p.error(t.Pos(), "cannot parenthesize type in composite literal")
+				// already progressed, no need to advance
+			}
+			x = p.parseLiteralValue(x)
 		default:
-			break L
+			return
 		}
-		lhs = false // no need to try to resolve again
 	}
-
-	return x
 }
 
-// If lhs is set and the result is an identifier, it is not resolved.
-func (p *parser) parseUnaryExpr(lhs bool) ast.Expr {
+func (p *parser) parseUnaryExpr() ast.Expr {
 	if p.trace {
 		defer un(trace(p, "UnaryExpr"))
 	}
@@ -1534,7 +1599,7 @@
 	case token.ADD, token.SUB, token.NOT, token.XOR, token.AND:
 		pos, op := p.pos, p.tok
 		p.next()
-		x := p.parseUnaryExpr(false)
+		x := p.parseUnaryExpr()
 		return &ast.UnaryExpr{OpPos: pos, Op: op, X: p.checkExpr(x)}
 
 	case token.ARROW:
@@ -1556,7 +1621,7 @@
 		//   <- (chan type)    =>  (<-chan type)
 		//   <- (chan<- type)  =>  (<-chan (<-type))
 
-		x := p.parseUnaryExpr(false)
+		x := p.parseUnaryExpr()
 
 		// determine which case we have
 		if typ, ok := x.(*ast.ChanType); ok {
@@ -1587,11 +1652,11 @@
 		// pointer type or unary "*" expression
 		pos := p.pos
 		p.next()
-		x := p.parseUnaryExpr(false)
+		x := p.parseUnaryExpr()
 		return &ast.StarExpr{Star: pos, X: p.checkExprOrType(x)}
 	}
 
-	return p.parsePrimaryExpr(lhs)
+	return p.parsePrimaryExpr()
 }
 
 func (p *parser) tokPrec() (token.Token, int) {
@@ -1602,44 +1667,38 @@
 	return tok, tok.Precedence()
 }
 
-// If lhs is set and the result is an identifier, it is not resolved.
-func (p *parser) parseBinaryExpr(lhs bool, prec1 int) ast.Expr {
+func (p *parser) parseBinaryExpr(prec1 int) ast.Expr {
 	if p.trace {
 		defer un(trace(p, "BinaryExpr"))
 	}
 
-	x := p.parseUnaryExpr(lhs)
+	x := p.parseUnaryExpr()
 	for {
 		op, oprec := p.tokPrec()
 		if oprec < prec1 {
 			return x
 		}
 		pos := p.expect(op)
-		if lhs {
-			p.resolve(x)
-			lhs = false
-		}
-		y := p.parseBinaryExpr(false, oprec+1)
+		y := p.parseBinaryExpr(oprec + 1)
 		x = &ast.BinaryExpr{X: p.checkExpr(x), OpPos: pos, Op: op, Y: p.checkExpr(y)}
 	}
 }
 
-// If lhs is set and the result is an identifier, it is not resolved.
 // The result may be a type or even a raw type ([...]int). Callers must
 // check the result (using checkExpr or checkExprOrType), depending on
 // context.
-func (p *parser) parseExpr(lhs bool) ast.Expr {
+func (p *parser) parseExpr() ast.Expr {
 	if p.trace {
 		defer un(trace(p, "Expression"))
 	}
 
-	return p.parseBinaryExpr(lhs, token.LowestPrec+1)
+	return p.parseBinaryExpr(token.LowestPrec + 1)
 }
 
 func (p *parser) parseRhs() ast.Expr {
 	old := p.inRhs
 	p.inRhs = true
-	x := p.checkExpr(p.parseExpr(false))
+	x := p.checkExpr(p.parseExpr())
 	p.inRhs = old
 	return x
 }
@@ -1647,7 +1706,7 @@
 func (p *parser) parseRhsOrType() ast.Expr {
 	old := p.inRhs
 	p.inRhs = true
-	x := p.checkExprOrType(p.parseExpr(false))
+	x := p.checkExprOrType(p.parseExpr())
 	p.inRhs = old
 	return x
 }
@@ -1671,7 +1730,7 @@
 		defer un(trace(p, "SimpleStmt"))
 	}
 
-	x := p.parseLhsList()
+	x := p.parseList(false)
 
 	switch p.tok {
 	case
@@ -1690,11 +1749,11 @@
 			y = []ast.Expr{&ast.UnaryExpr{OpPos: pos, Op: token.RANGE, X: p.parseRhs()}}
 			isRange = true
 		} else {
-			y = p.parseRhsList()
+			y = p.parseList(true)
 		}
 		as := &ast.AssignStmt{Lhs: x, TokPos: pos, Tok: tok, Rhs: y}
 		if tok == token.DEFINE {
-			p.shortVarDecl(as, x)
+			p.checkAssignStmt(as)
 		}
 		return as, isRange
 	}
@@ -1714,7 +1773,6 @@
 			// in which it is declared and excludes the body of any nested
 			// function.
 			stmt := &ast.LabeledStmt{Label: label, Colon: colon, Stmt: p.parseStmt()}
-			p.declare(stmt, nil, p.labelScope, ast.Lbl, label)
 			return stmt, false
 		}
 		// The label declaration typically starts at x[0].Pos(), but the label
@@ -1744,6 +1802,14 @@
 	return &ast.ExprStmt{X: x[0]}, false
 }
 
+func (p *parser) checkAssignStmt(as *ast.AssignStmt) {
+	for _, x := range as.Lhs {
+		if _, isIdent := x.(*ast.Ident); !isIdent {
+			p.errorExpected(x.Pos(), "identifier on left side of :=")
+		}
+	}
+}
+
 func (p *parser) parseCallExpr(callType string) *ast.CallExpr {
 	x := p.parseRhsOrType() // could be a conversion: (some type)(x)
 	if call, isCall := x.(*ast.CallExpr); isCall {
@@ -1795,7 +1861,7 @@
 	p.expect(token.RETURN)
 	var x []ast.Expr
 	if p.tok != token.SEMICOLON && p.tok != token.RBRACE {
-		x = p.parseRhsList()
+		x = p.parseList(true)
 	}
 	p.expectSemi()
 
@@ -1811,9 +1877,6 @@
 	var label *ast.Ident
 	if tok != token.FALLTHROUGH && p.tok == token.IDENT {
 		label = p.parseIdent()
-		// add to list of unresolved targets
-		n := len(p.targetStack) - 1
-		p.targetStack[n] = append(p.targetStack[n], label)
 	}
 	p.expectSemi()
 
@@ -1846,14 +1909,14 @@
 	}
 	// p.tok != token.LBRACE
 
-	outer := p.exprLev
+	prevLev := p.exprLev
 	p.exprLev = -1
 
 	if p.tok != token.SEMICOLON {
 		// accept potential variable declaration but complain
 		if p.tok == token.VAR {
 			p.next()
-			p.error(p.pos, fmt.Sprintf("var declaration not allowed in 'IF' initializer"))
+			p.error(p.pos, "var declaration not allowed in 'IF' initializer")
 		}
 		init, _ = p.parseSimpleStmt(basic)
 	}
@@ -1894,7 +1957,7 @@
 		cond = &ast.BadExpr{From: p.pos, To: p.pos}
 	}
 
-	p.exprLev = outer
+	p.exprLev = prevLev
 	return
 }
 
@@ -1904,8 +1967,6 @@
 	}
 
 	pos := p.expect(token.IF)
-	p.openScope()
-	defer p.closeScope()
 
 	init, cond := p.parseIfHeader()
 	body := p.parseBlockStmt()
@@ -1956,16 +2017,14 @@
 		if typeSwitch {
 			list = p.parseTypeList()
 		} else {
-			list = p.parseRhsList()
+			list = p.parseList(true)
 		}
 	} else {
 		p.expect(token.DEFAULT)
 	}
 
 	colon := p.expect(token.COLON)
-	p.openScope()
 	body := p.parseStmtList()
-	p.closeScope()
 
 	return &ast.CaseClause{Case: pos, List: list, Colon: colon, Body: body}
 }
@@ -2002,8 +2061,6 @@
 	}
 
 	pos := p.expect(token.SWITCH)
-	p.openScope()
-	defer p.closeScope()
 
 	var s1, s2 ast.Stmt
 	if p.tok != token.LBRACE {
@@ -2029,8 +2086,6 @@
 				//
 				// If we don't have a type switch, s2 must be an expression.
 				// Having the extra nested but empty scope won't affect it.
-				p.openScope()
-				defer p.closeScope()
 				s2, _ = p.parseSimpleStmt(basic)
 			}
 		}
@@ -2059,12 +2114,11 @@
 		defer un(trace(p, "CommClause"))
 	}
 
-	p.openScope()
 	pos := p.pos
 	var comm ast.Stmt
 	if p.tok == token.CASE {
 		p.next()
-		lhs := p.parseLhsList()
+		lhs := p.parseList(false)
 		if p.tok == token.ARROW {
 			// SendStmt
 			if len(lhs) > 1 {
@@ -2089,7 +2143,7 @@
 				rhs := p.parseRhs()
 				as := &ast.AssignStmt{Lhs: lhs, TokPos: pos, Tok: tok, Rhs: []ast.Expr{rhs}}
 				if tok == token.DEFINE {
-					p.shortVarDecl(as, lhs)
+					p.checkAssignStmt(as)
 				}
 				comm = as
 			} else {
@@ -2107,7 +2161,6 @@
 
 	colon := p.expect(token.COLON)
 	body := p.parseStmtList()
-	p.closeScope()
 
 	return &ast.CommClause{Case: pos, Comm: comm, Colon: colon, Body: body}
 }
@@ -2136,8 +2189,6 @@
 	}
 
 	pos := p.expect(token.FOR)
-	p.openScope()
-	defer p.closeScope()
 
 	var s1, s2, s3 ast.Stmt
 	var isRange bool
@@ -2275,7 +2326,7 @@
 // ----------------------------------------------------------------------------
 // Declarations
 
-type parseSpecFunction func(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec
+type parseSpecFunction func(doc *ast.CommentGroup, pos token.Pos, keyword token.Token, iota int) ast.Spec
 
 func isValidImport(lit string) bool {
 	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
@@ -2288,7 +2339,7 @@
 	return s != ""
 }
 
-func (p *parser) parseImportSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.Spec {
+func (p *parser) parseImportSpec(doc *ast.CommentGroup, _ token.Pos, _ token.Token, _ int) ast.Spec {
 	if p.trace {
 		defer un(trace(p, "ImportSpec"))
 	}
@@ -2327,19 +2378,19 @@
 	return spec
 }
 
-func (p *parser) parseValueSpec(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec {
+func (p *parser) parseValueSpec(doc *ast.CommentGroup, _ token.Pos, keyword token.Token, iota int) ast.Spec {
 	if p.trace {
 		defer un(trace(p, keyword.String()+"Spec"))
 	}
 
 	pos := p.pos
 	idents := p.parseIdentList()
-	typ := p.tryType()
+	typ := p.tryIdentOrType()
 	var values []ast.Expr
 	// always permit optional initialization for more tolerant parsing
 	if p.tok == token.ASSIGN {
 		p.next()
-		values = p.parseRhsList()
+		values = p.parseList(true)
 	}
 	p.expectSemi() // call before accessing p.linecomment
 
@@ -2354,10 +2405,6 @@
 		}
 	}
 
-	// Go spec: The scope of a constant or variable identifier declared inside
-	// a function begins at the end of the ConstSpec or VarSpec and ends at
-	// the end of the innermost containing block.
-	// (Global identifiers are resolved in a separate phase after parsing.)
 	spec := &ast.ValueSpec{
 		Doc:     doc,
 		Names:   idents,
@@ -2365,33 +2412,66 @@
 		Values:  values,
 		Comment: p.lineComment,
 	}
-	kind := ast.Con
-	if keyword == token.VAR {
-		kind = ast.Var
-	}
-	p.declare(spec, iota, p.topScope, kind, idents...)
-
 	return spec
 }
 
-func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.Spec {
+func (p *parser) parseGenericType(spec *ast.TypeSpec, openPos token.Pos, name0 *ast.Ident, closeTok token.Token) {
+	list := p.parseParameterList(name0, closeTok, p.parseParamDecl, true)
+	closePos := p.expect(closeTok)
+	typeparams.Set(spec, &ast.FieldList{Opening: openPos, List: list, Closing: closePos})
+	// Type alias cannot have type parameters. Accept them for robustness but complain.
+	if p.tok == token.ASSIGN {
+		p.error(p.pos, "generic type cannot be alias")
+		p.next()
+	}
+	spec.Type = p.parseType()
+}
+
+func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Pos, _ token.Token, _ int) ast.Spec {
 	if p.trace {
 		defer un(trace(p, "TypeSpec"))
 	}
 
 	ident := p.parseIdent()
-
-	// Go spec: The scope of a type identifier declared inside a function begins
-	// at the identifier in the TypeSpec and ends at the end of the innermost
-	// containing block.
-	// (Global identifiers are resolved in a separate phase after parsing.)
 	spec := &ast.TypeSpec{Doc: doc, Name: ident}
-	p.declare(spec, nil, p.topScope, ast.Typ, ident)
-	if p.tok == token.ASSIGN {
-		spec.Assign = p.pos
+
+	switch p.tok {
+	case token.LBRACK:
+		lbrack := p.pos
 		p.next()
+		if p.tok == token.IDENT {
+			// array type or generic type [T any]
+			p.exprLev++
+			x := p.parseExpr()
+			p.exprLev--
+			if name0, _ := x.(*ast.Ident); p.parseTypeParams() && name0 != nil && p.tok != token.RBRACK {
+				// generic type [T any];
+				p.parseGenericType(spec, lbrack, name0, token.RBRACK)
+			} else {
+				// array type
+				// TODO(rfindley) should resolve all identifiers in x.
+				p.expect(token.RBRACK)
+				elt := p.parseType()
+				spec.Type = &ast.ArrayType{Lbrack: lbrack, Len: x, Elt: elt}
+			}
+		} else {
+			// array type
+			alen := p.parseArrayLen()
+			p.expect(token.RBRACK)
+			elt := p.parseType()
+			spec.Type = &ast.ArrayType{Lbrack: lbrack, Len: alen, Elt: elt}
+		}
+
+	default:
+		// no type parameters
+		if p.tok == token.ASSIGN {
+			// type alias
+			spec.Assign = p.pos
+			p.next()
+		}
+		spec.Type = p.parseType()
 	}
-	spec.Type = p.parseType()
+
 	p.expectSemi() // call before accessing p.linecomment
 	spec.Comment = p.lineComment
 
@@ -2411,12 +2491,12 @@
 		lparen = p.pos
 		p.next()
 		for iota := 0; p.tok != token.RPAREN && p.tok != token.EOF; iota++ {
-			list = append(list, f(p.leadComment, keyword, iota))
+			list = append(list, f(p.leadComment, pos, keyword, iota))
 		}
 		rparen = p.expect(token.RPAREN)
 		p.expectSemi()
 	} else {
-		list = append(list, f(nil, keyword, 0))
+		list = append(list, f(nil, pos, keyword, 0))
 	}
 
 	return &ast.GenDecl{
@@ -2436,27 +2516,27 @@
 
 	doc := p.leadComment
 	pos := p.expect(token.FUNC)
-	scope := ast.NewScope(p.topScope) // function scope
 
 	var recv *ast.FieldList
 	if p.tok == token.LPAREN {
-		recv = p.parseParameters(scope, false)
+		_, recv = p.parseParameters(false)
 	}
 
 	ident := p.parseIdent()
 
-	params, results := p.parseSignature(scope)
+	tparams, params := p.parseParameters(true)
+	results := p.parseResult()
 
 	var body *ast.BlockStmt
 	if p.tok == token.LBRACE {
-		body = p.parseBody(scope)
+		body = p.parseBody()
 		p.expectSemi()
 	} else if p.tok == token.SEMICOLON {
 		p.next()
 		if p.tok == token.LBRACE {
 			// opening { of function declaration on next line
 			p.error(p.pos, "unexpected semicolon or newline before {")
-			body = p.parseBody(scope)
+			body = p.parseBody()
 			p.expectSemi()
 		}
 	} else {
@@ -2474,18 +2554,7 @@
 		},
 		Body: body,
 	}
-	if recv == nil {
-		// Go spec: The scope of an identifier denoting a constant, type,
-		// variable, or function (but not method) declared at top level
-		// (outside any function) is the package block.
-		//
-		// init() functions cannot be referred to and there may
-		// be more than one - don't put them in the pkgScope
-		if ident.Name != "init" {
-			p.declare(decl, nil, p.pkgScope, ast.Fun, ident)
-		}
-	}
-
+	typeparams.Set(decl.Type, tparams)
 	return decl
 }
 
@@ -2546,8 +2615,6 @@
 		return nil
 	}
 
-	p.openScope()
-	p.pkgScope = p.topScope
 	var decls []ast.Decl
 	if p.mode&PackageClauseOnly == 0 {
 		// import decls
@@ -2562,30 +2629,22 @@
 			}
 		}
 	}
-	p.closeScope()
-	assert(p.topScope == nil, "unbalanced scopes")
-	assert(p.labelScope == nil, "unbalanced label scopes")
 
-	// resolve global identifiers within the same file
-	i := 0
-	for _, ident := range p.unresolved {
-		// i <= index for current ident
-		assert(ident.Obj == unresolved, "object already resolved")
-		ident.Obj = p.pkgScope.Lookup(ident.Name) // also removes unresolved sentinel
-		if ident.Obj == nil {
-			p.unresolved[i] = ident
-			i++
-		}
+	f := &ast.File{
+		Doc:      doc,
+		Package:  pos,
+		Name:     ident,
+		Decls:    decls,
+		Imports:  p.imports,
+		Comments: p.comments,
+	}
+	var declErr func(token.Pos, string)
+	if p.mode&DeclarationErrors != 0 {
+		declErr = p.error
+	}
+	if p.mode&SkipObjectResolution == 0 {
+		resolveFile(f, p.file, declErr)
 	}
 
-	return &ast.File{
-		Doc:        doc,
-		Package:    pos,
-		Name:       ident,
-		Decls:      decls,
-		Scope:      p.pkgScope,
-		Imports:    p.imports,
-		Unresolved: p.unresolved[0:i],
-		Comments:   p.comments,
-	}
+	return f
 }
diff --git a/src/go/parser/performance_test.go b/src/go/parser/performance_test.go
index f81bcee..6f8a977 100644
--- a/src/go/parser/performance_test.go
+++ b/src/go/parser/performance_test.go
@@ -10,6 +10,8 @@
 	"testing"
 )
 
+// TODO(rFindley): use a testdata file or file from another package here, to
+//                 avoid a moving target.
 var src = readFile("parser.go")
 
 func readFile(filename string) []byte {
@@ -28,3 +30,27 @@
 		}
 	}
 }
+
+func BenchmarkParseOnly(b *testing.B) {
+	b.SetBytes(int64(len(src)))
+	for i := 0; i < b.N; i++ {
+		if _, err := ParseFile(token.NewFileSet(), "", src, ParseComments|SkipObjectResolution); err != nil {
+			b.Fatalf("benchmark failed due to parse error: %s", err)
+		}
+	}
+}
+
+func BenchmarkResolve(b *testing.B) {
+	b.SetBytes(int64(len(src)))
+	for i := 0; i < b.N; i++ {
+		b.StopTimer()
+		fset := token.NewFileSet()
+		file, err := ParseFile(fset, "", src, SkipObjectResolution)
+		if err != nil {
+			b.Fatalf("benchmark failed due to parse error: %s", err)
+		}
+		b.StartTimer()
+		handle := fset.File(file.Package)
+		resolveFile(file, handle, nil)
+	}
+}
diff --git a/src/go/parser/resolver.go b/src/go/parser/resolver.go
new file mode 100644
index 0000000..cf92c7e
--- /dev/null
+++ b/src/go/parser/resolver.go
@@ -0,0 +1,556 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package parser
+
+import (
+	"fmt"
+	"go/ast"
+	"go/internal/typeparams"
+	"go/token"
+)
+
+const debugResolve = false
+
+// resolveFile walks the given file to resolve identifiers within the file
+// scope, updating ast.Ident.Obj fields with declaration information.
+//
+// If declErr is non-nil, it is used to report declaration errors during
+// resolution. tok is used to format position in error messages.
+func resolveFile(file *ast.File, handle *token.File, declErr func(token.Pos, string)) {
+	pkgScope := ast.NewScope(nil)
+	r := &resolver{
+		handle:   handle,
+		declErr:  declErr,
+		topScope: pkgScope,
+		pkgScope: pkgScope,
+	}
+
+	for _, decl := range file.Decls {
+		ast.Walk(r, decl)
+	}
+
+	r.closeScope()
+	assert(r.topScope == nil, "unbalanced scopes")
+	assert(r.labelScope == nil, "unbalanced label scopes")
+
+	// resolve global identifiers within the same file
+	i := 0
+	for _, ident := range r.unresolved {
+		// i <= index for current ident
+		assert(ident.Obj == unresolved, "object already resolved")
+		ident.Obj = r.pkgScope.Lookup(ident.Name) // also removes unresolved sentinel
+		if ident.Obj == nil {
+			r.unresolved[i] = ident
+			i++
+		} else if debugResolve {
+			pos := ident.Obj.Decl.(interface{ Pos() token.Pos }).Pos()
+			r.dump("resolved %s@%v to package object %v", ident.Name, ident.Pos(), pos)
+		}
+	}
+	file.Scope = r.pkgScope
+	file.Unresolved = r.unresolved[0:i]
+}
+
+type resolver struct {
+	handle  *token.File
+	declErr func(token.Pos, string)
+
+	// Ordinary identifier scopes
+	pkgScope   *ast.Scope   // pkgScope.Outer == nil
+	topScope   *ast.Scope   // top-most scope; may be pkgScope
+	unresolved []*ast.Ident // unresolved identifiers
+
+	// Label scopes
+	// (maintained by open/close LabelScope)
+	labelScope  *ast.Scope     // label scope for current function
+	targetStack [][]*ast.Ident // stack of unresolved labels
+}
+
+func (r *resolver) dump(format string, args ...interface{}) {
+	fmt.Println(">>> " + r.sprintf(format, args...))
+}
+
+func (r *resolver) sprintf(format string, args ...interface{}) string {
+	for i, arg := range args {
+		switch arg := arg.(type) {
+		case token.Pos:
+			args[i] = r.handle.Position(arg)
+		}
+	}
+	return fmt.Sprintf(format, args...)
+}
+
+func (r *resolver) openScope(pos token.Pos) {
+	if debugResolve {
+		r.dump("opening scope @%v", pos)
+	}
+	r.topScope = ast.NewScope(r.topScope)
+}
+
+func (r *resolver) closeScope() {
+	if debugResolve {
+		r.dump("closing scope")
+	}
+	r.topScope = r.topScope.Outer
+}
+
+func (r *resolver) openLabelScope() {
+	r.labelScope = ast.NewScope(r.labelScope)
+	r.targetStack = append(r.targetStack, nil)
+}
+
+func (r *resolver) closeLabelScope() {
+	// resolve labels
+	n := len(r.targetStack) - 1
+	scope := r.labelScope
+	for _, ident := range r.targetStack[n] {
+		ident.Obj = scope.Lookup(ident.Name)
+		if ident.Obj == nil && r.declErr != nil {
+			r.declErr(ident.Pos(), fmt.Sprintf("label %s undefined", ident.Name))
+		}
+	}
+	// pop label scope
+	r.targetStack = r.targetStack[0:n]
+	r.labelScope = r.labelScope.Outer
+}
+
+func (r *resolver) declare(decl, data interface{}, scope *ast.Scope, kind ast.ObjKind, idents ...*ast.Ident) {
+	for _, ident := range idents {
+		// "type" is used for type lists in interfaces, and is otherwise an invalid
+		// identifier. The 'type' identifier is also artificially duplicated in the
+		// type list, so could cause panics below if we were to proceed.
+		if ident.Name == "type" {
+			continue
+		}
+		assert(ident.Obj == nil, "identifier already declared or resolved")
+		obj := ast.NewObj(kind, ident.Name)
+		// remember the corresponding declaration for redeclaration
+		// errors and global variable resolution/typechecking phase
+		obj.Decl = decl
+		obj.Data = data
+		ident.Obj = obj
+		if ident.Name != "_" {
+			if debugResolve {
+				r.dump("declaring %s@%v", ident.Name, ident.Pos())
+			}
+			if alt := scope.Insert(obj); alt != nil && r.declErr != nil {
+				prevDecl := ""
+				if pos := alt.Pos(); pos.IsValid() {
+					prevDecl = fmt.Sprintf("\n\tprevious declaration at %s", r.handle.Position(pos))
+				}
+				r.declErr(ident.Pos(), fmt.Sprintf("%s redeclared in this block%s", ident.Name, prevDecl))
+			}
+		}
+	}
+}
+
+func (r *resolver) shortVarDecl(decl *ast.AssignStmt) {
+	// Go spec: A short variable declaration may redeclare variables
+	// provided they were originally declared in the same block with
+	// the same type, and at least one of the non-blank variables is new.
+	n := 0 // number of new variables
+	for _, x := range decl.Lhs {
+		if ident, isIdent := x.(*ast.Ident); isIdent {
+			assert(ident.Obj == nil, "identifier already declared or resolved")
+			obj := ast.NewObj(ast.Var, ident.Name)
+			// remember corresponding assignment for other tools
+			obj.Decl = decl
+			ident.Obj = obj
+			if ident.Name != "_" {
+				if debugResolve {
+					r.dump("declaring %s@%v", ident.Name, ident.Pos())
+				}
+				if alt := r.topScope.Insert(obj); alt != nil {
+					ident.Obj = alt // redeclaration
+				} else {
+					n++ // new declaration
+				}
+			}
+		}
+	}
+	if n == 0 && r.declErr != nil {
+		r.declErr(decl.Lhs[0].Pos(), "no new variables on left side of :=")
+	}
+}
+
+// The unresolved object is a sentinel to mark identifiers that have been added
+// to the list of unresolved identifiers. The sentinel is only used for verifying
+// internal consistency.
+var unresolved = new(ast.Object)
+
+// If x is an identifier, resolve attempts to resolve x by looking up
+// the object it denotes. If no object is found and collectUnresolved is
+// set, x is marked as unresolved and collected in the list of unresolved
+// identifiers.
+//
+func (r *resolver) resolve(ident *ast.Ident, collectUnresolved bool) {
+	if ident.Obj != nil {
+		panic(fmt.Sprintf("%s: identifier %s already declared or resolved", r.handle.Position(ident.Pos()), ident.Name))
+	}
+	// '_' and 'type' should never refer to existing declarations: '_' because it
+	// has special handling in the spec, and 'type' because it is a keyword, and
+	// only valid in an interface type list.
+	if ident.Name == "_" || ident.Name == "type" {
+		return
+	}
+	for s := r.topScope; s != nil; s = s.Outer {
+		if obj := s.Lookup(ident.Name); obj != nil {
+			assert(obj.Name != "", "obj with no name")
+			ident.Obj = obj
+			return
+		}
+	}
+	// all local scopes are known, so any unresolved identifier
+	// must be found either in the file scope, package scope
+	// (perhaps in another file), or universe scope --- collect
+	// them so that they can be resolved later
+	if collectUnresolved {
+		ident.Obj = unresolved
+		r.unresolved = append(r.unresolved, ident)
+	}
+}
+
+func (r *resolver) walkExprs(list []ast.Expr) {
+	for _, node := range list {
+		ast.Walk(r, node)
+	}
+}
+
+func (r *resolver) walkLHS(list []ast.Expr) {
+	for _, expr := range list {
+		expr := unparen(expr)
+		if _, ok := expr.(*ast.Ident); !ok && expr != nil {
+			ast.Walk(r, expr)
+		}
+	}
+}
+
+func (r *resolver) walkStmts(list []ast.Stmt) {
+	for _, stmt := range list {
+		ast.Walk(r, stmt)
+	}
+}
+
+func (r *resolver) Visit(node ast.Node) ast.Visitor {
+	if debugResolve && node != nil {
+		r.dump("node %T@%v", node, node.Pos())
+	}
+
+	switch n := node.(type) {
+
+	// Expressions.
+	case *ast.Ident:
+		r.resolve(n, true)
+
+	case *ast.FuncLit:
+		r.openScope(n.Pos())
+		defer r.closeScope()
+		r.walkFuncType(n.Type)
+		r.walkBody(n.Body)
+
+	case *ast.SelectorExpr:
+		ast.Walk(r, n.X)
+		// Note: don't try to resolve n.Sel, as we don't support qualified
+		// resolution.
+
+	case *ast.StructType:
+		r.openScope(n.Pos())
+		defer r.closeScope()
+		r.walkFieldList(n.Fields, ast.Var)
+
+	case *ast.FuncType:
+		r.openScope(n.Pos())
+		defer r.closeScope()
+		r.walkFuncType(n)
+
+	case *ast.CompositeLit:
+		if n.Type != nil {
+			ast.Walk(r, n.Type)
+		}
+		for _, e := range n.Elts {
+			if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
+				// See issue #45160: try to resolve composite lit keys, but don't
+				// collect them as unresolved if resolution failed. This replicates
+				// existing behavior when resolving during parsing.
+				if ident, _ := kv.Key.(*ast.Ident); ident != nil {
+					r.resolve(ident, false)
+				} else {
+					ast.Walk(r, kv.Key)
+				}
+				ast.Walk(r, kv.Value)
+			} else {
+				ast.Walk(r, e)
+			}
+		}
+
+	case *ast.InterfaceType:
+		r.openScope(n.Pos())
+		defer r.closeScope()
+		r.walkFieldList(n.Methods, ast.Fun)
+
+	// Statements
+	case *ast.LabeledStmt:
+		r.declare(n, nil, r.labelScope, ast.Lbl, n.Label)
+		ast.Walk(r, n.Stmt)
+
+	case *ast.AssignStmt:
+		r.walkExprs(n.Rhs)
+		if n.Tok == token.DEFINE {
+			r.shortVarDecl(n)
+		} else {
+			r.walkExprs(n.Lhs)
+		}
+
+	case *ast.BranchStmt:
+		// add to list of unresolved targets
+		if n.Tok != token.FALLTHROUGH && n.Label != nil {
+			depth := len(r.targetStack) - 1
+			r.targetStack[depth] = append(r.targetStack[depth], n.Label)
+		}
+
+	case *ast.BlockStmt:
+		r.openScope(n.Pos())
+		defer r.closeScope()
+		r.walkStmts(n.List)
+
+	case *ast.IfStmt:
+		r.openScope(n.Pos())
+		defer r.closeScope()
+		if n.Init != nil {
+			ast.Walk(r, n.Init)
+		}
+		ast.Walk(r, n.Cond)
+		ast.Walk(r, n.Body)
+		if n.Else != nil {
+			ast.Walk(r, n.Else)
+		}
+
+	case *ast.CaseClause:
+		r.walkExprs(n.List)
+		r.openScope(n.Pos())
+		defer r.closeScope()
+		r.walkStmts(n.Body)
+
+	case *ast.SwitchStmt:
+		r.openScope(n.Pos())
+		defer r.closeScope()
+		if n.Init != nil {
+			ast.Walk(r, n.Init)
+		}
+		if n.Tag != nil {
+			// The scope below reproduces some unnecessary behavior of the parser,
+			// opening an extra scope in case this is a type switch. It's not needed
+			// for expression switches.
+			// TODO: remove this once we've matched the parser resolution exactly.
+			if n.Init != nil {
+				r.openScope(n.Tag.Pos())
+				defer r.closeScope()
+			}
+			ast.Walk(r, n.Tag)
+		}
+		if n.Body != nil {
+			r.walkStmts(n.Body.List)
+		}
+
+	case *ast.TypeSwitchStmt:
+		if n.Init != nil {
+			r.openScope(n.Pos())
+			defer r.closeScope()
+			ast.Walk(r, n.Init)
+		}
+		r.openScope(n.Assign.Pos())
+		defer r.closeScope()
+		ast.Walk(r, n.Assign)
+		// s.Body consists only of case clauses, so does not get its own
+		// scope.
+		if n.Body != nil {
+			r.walkStmts(n.Body.List)
+		}
+
+	case *ast.CommClause:
+		r.openScope(n.Pos())
+		defer r.closeScope()
+		if n.Comm != nil {
+			ast.Walk(r, n.Comm)
+		}
+		r.walkStmts(n.Body)
+
+	case *ast.SelectStmt:
+		// as for switch statements, select statement bodies don't get their own
+		// scope.
+		if n.Body != nil {
+			r.walkStmts(n.Body.List)
+		}
+
+	case *ast.ForStmt:
+		r.openScope(n.Pos())
+		defer r.closeScope()
+		if n.Init != nil {
+			ast.Walk(r, n.Init)
+		}
+		if n.Cond != nil {
+			ast.Walk(r, n.Cond)
+		}
+		if n.Post != nil {
+			ast.Walk(r, n.Post)
+		}
+		ast.Walk(r, n.Body)
+
+	case *ast.RangeStmt:
+		r.openScope(n.Pos())
+		defer r.closeScope()
+		ast.Walk(r, n.X)
+		var lhs []ast.Expr
+		if n.Key != nil {
+			lhs = append(lhs, n.Key)
+		}
+		if n.Value != nil {
+			lhs = append(lhs, n.Value)
+		}
+		if len(lhs) > 0 {
+			if n.Tok == token.DEFINE {
+				// Note: we can't exactly match the behavior of object resolution
+				// during the parsing pass here, as it uses the position of the RANGE
+				// token for the RHS OpPos. That information is not contained within
+				// the AST.
+				as := &ast.AssignStmt{
+					Lhs:    lhs,
+					Tok:    token.DEFINE,
+					TokPos: n.TokPos,
+					Rhs:    []ast.Expr{&ast.UnaryExpr{Op: token.RANGE, X: n.X}},
+				}
+				// TODO(rFindley): this walkLHS reproduced the parser resolution, but
+				// is it necessary? By comparison, for a normal AssignStmt we don't
+				// walk the LHS in case there is an invalid identifier list.
+				r.walkLHS(lhs)
+				r.shortVarDecl(as)
+			} else {
+				r.walkExprs(lhs)
+			}
+		}
+		ast.Walk(r, n.Body)
+
+	// Declarations
+	case *ast.GenDecl:
+		switch n.Tok {
+		case token.CONST, token.VAR:
+			for i, spec := range n.Specs {
+				spec := spec.(*ast.ValueSpec)
+				kind := ast.Con
+				if n.Tok == token.VAR {
+					kind = ast.Var
+				}
+				r.walkExprs(spec.Values)
+				if spec.Type != nil {
+					ast.Walk(r, spec.Type)
+				}
+				r.declare(spec, i, r.topScope, kind, spec.Names...)
+			}
+		case token.TYPE:
+			for _, spec := range n.Specs {
+				spec := spec.(*ast.TypeSpec)
+				// Go spec: The scope of a type identifier declared inside a function begins
+				// at the identifier in the TypeSpec and ends at the end of the innermost
+				// containing block.
+				r.declare(spec, nil, r.topScope, ast.Typ, spec.Name)
+				if tparams := typeparams.Get(spec); tparams != nil {
+					r.openScope(spec.Pos())
+					defer r.closeScope()
+					r.walkTParams(tparams)
+				}
+				ast.Walk(r, spec.Type)
+			}
+		}
+
+	case *ast.FuncDecl:
+		// Open the function scope.
+		r.openScope(n.Pos())
+		defer r.closeScope()
+
+		// Resolve the receiver first, without declaring.
+		r.resolveList(n.Recv)
+
+		// Type parameters are walked normally: they can reference each other, and
+		// can be referenced by normal parameters.
+		if tparams := typeparams.Get(n.Type); tparams != nil {
+			r.walkTParams(tparams)
+			// TODO(rFindley): need to address receiver type parameters.
+		}
+
+		// Resolve and declare parameters in a specific order to get duplicate
+		// declaration errors in the correct location.
+		r.resolveList(n.Type.Params)
+		r.resolveList(n.Type.Results)
+		r.declareList(n.Recv, ast.Var)
+		r.declareList(n.Type.Params, ast.Var)
+		r.declareList(n.Type.Results, ast.Var)
+
+		r.walkBody(n.Body)
+		if n.Recv == nil && n.Name.Name != "init" {
+			r.declare(n, nil, r.pkgScope, ast.Fun, n.Name)
+		}
+
+	default:
+		return r
+	}
+
+	return nil
+}
+
+func (r *resolver) walkFuncType(typ *ast.FuncType) {
+	// typ.TParams must be walked separately for FuncDecls.
+	r.resolveList(typ.Params)
+	r.resolveList(typ.Results)
+	r.declareList(typ.Params, ast.Var)
+	r.declareList(typ.Results, ast.Var)
+}
+
+func (r *resolver) resolveList(list *ast.FieldList) {
+	if list == nil {
+		return
+	}
+	for _, f := range list.List {
+		if f.Type != nil {
+			ast.Walk(r, f.Type)
+		}
+	}
+}
+
+func (r *resolver) declareList(list *ast.FieldList, kind ast.ObjKind) {
+	if list == nil {
+		return
+	}
+	for _, f := range list.List {
+		r.declare(f, nil, r.topScope, kind, f.Names...)
+	}
+}
+
+func (r *resolver) walkFieldList(list *ast.FieldList, kind ast.ObjKind) {
+	if list == nil {
+		return
+	}
+	r.resolveList(list)
+	r.declareList(list, kind)
+}
+
+// walkTParams is like walkFieldList, but declares type parameters eagerly so
+// that they may be resolved in the constraint expressions held in the field
+// Type.
+func (r *resolver) walkTParams(list *ast.FieldList) {
+	if list == nil {
+		return
+	}
+	r.declareList(list, ast.Typ)
+	r.resolveList(list)
+}
+
+func (r *resolver) walkBody(body *ast.BlockStmt) {
+	if body == nil {
+		return
+	}
+	r.openLabelScope()
+	defer r.closeLabelScope()
+	r.walkStmts(body.List)
+}
diff --git a/src/go/parser/resolver_test.go b/src/go/parser/resolver_test.go
new file mode 100644
index 0000000..625c009
--- /dev/null
+++ b/src/go/parser/resolver_test.go
@@ -0,0 +1,180 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package parser
+
+import (
+	"fmt"
+	"go/ast"
+	"go/internal/typeparams"
+	"go/scanner"
+	"go/token"
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+// TestResolution checks that identifiers are resolved to the declarations
+// annotated in the source, by comparing the positions of the resulting
+// Ident.Obj.Decl to positions marked in the source via special comments.
+//
+// In the test source, any comment prefixed with '=' or '@' (or both) marks the
+// previous token position as the declaration ('=') or a use ('@') of an
+// identifier. The text following '=' and '@' in the comment string is the
+// label to use for the location.  Declaration labels must be unique within the
+// file, and use labels must refer to an existing declaration label. It's OK
+// for a comment to denote both the declaration and use of a label (e.g.
+// '=@foo'). Leading and trailing whitespace is ignored. Any comment not
+// beginning with '=' or '@' is ignored.
+func TestResolution(t *testing.T) {
+	dir := filepath.Join("testdata", "resolution")
+	fis, err := os.ReadDir(dir)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	for _, fi := range fis {
+		t.Run(fi.Name(), func(t *testing.T) {
+			fset := token.NewFileSet()
+			path := filepath.Join(dir, fi.Name())
+			src := readFile(path) // panics on failure
+			var mode Mode
+			if strings.HasSuffix(path, ".go2") {
+				if !typeparams.Enabled {
+					t.Skip("type params are not enabled")
+				}
+			} else {
+				mode |= typeparams.DisallowParsing
+			}
+			file, err := ParseFile(fset, path, src, mode)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			// Compare the positions of objects resolved during parsing (fromParser)
+			// to those annotated in source comments (fromComments).
+
+			handle := fset.File(file.Package)
+			fromParser := declsFromParser(file)
+			fromComments := declsFromComments(handle, src)
+
+			pos := func(pos token.Pos) token.Position {
+				p := handle.Position(pos)
+				// The file name is implied by the subtest, so remove it to avoid
+				// clutter in error messages.
+				p.Filename = ""
+				return p
+			}
+			for k, want := range fromComments {
+				if got := fromParser[k]; got != want {
+					t.Errorf("%s resolved to %s, want %s", pos(k), pos(got), pos(want))
+				}
+				delete(fromParser, k)
+			}
+			// What remains in fromParser are unexpected resolutions.
+			for k, got := range fromParser {
+				t.Errorf("%s resolved to %s, want no object", pos(k), pos(got))
+			}
+		})
+	}
+}
+
+// declsFromParser walks the file and collects the map associating an
+// identifier position with its declaration position.
+func declsFromParser(file *ast.File) map[token.Pos]token.Pos {
+	objmap := map[token.Pos]token.Pos{}
+	ast.Inspect(file, func(node ast.Node) bool {
+		// Ignore blank identifiers to reduce noise.
+		if ident, _ := node.(*ast.Ident); ident != nil && ident.Obj != nil && ident.Name != "_" {
+			objmap[ident.Pos()] = ident.Obj.Pos()
+		}
+		return true
+	})
+	return objmap
+}
+
+// declsFromComments looks at comments annotating uses and declarations, and
+// maps each identifier use to its corresponding declaration. See the
+// description of these annotations in the documentation for TestResolution.
+func declsFromComments(handle *token.File, src []byte) map[token.Pos]token.Pos {
+	decls, uses := positionMarkers(handle, src)
+
+	objmap := make(map[token.Pos]token.Pos)
+	// Join decls and uses on name, to build the map of use->decl.
+	for name, posns := range uses {
+		declpos, ok := decls[name]
+		if !ok {
+			panic(fmt.Sprintf("missing declaration for %s", name))
+		}
+		for _, pos := range posns {
+			objmap[pos] = declpos
+		}
+	}
+	return objmap
+}
+
+// positionMarkers extracts named positions from the source denoted by comments
+// prefixed with '=' (declarations) and '@' (uses): for example '@foo' or
+// '=@bar'. It returns a map of name->position for declarations, and
+// name->position(s) for uses.
+func positionMarkers(handle *token.File, src []byte) (decls map[string]token.Pos, uses map[string][]token.Pos) {
+	var s scanner.Scanner
+	s.Init(handle, src, nil, scanner.ScanComments)
+	decls = make(map[string]token.Pos)
+	uses = make(map[string][]token.Pos)
+	var prev token.Pos // position of last non-comment, non-semicolon token
+
+scanFile:
+	for {
+		pos, tok, lit := s.Scan()
+		switch tok {
+		case token.EOF:
+			break scanFile
+		case token.COMMENT:
+			name, decl, use := annotatedObj(lit)
+			if len(name) > 0 {
+				if decl {
+					if _, ok := decls[name]; ok {
+						panic(fmt.Sprintf("duplicate declaration markers for %s", name))
+					}
+					decls[name] = prev
+				}
+				if use {
+					uses[name] = append(uses[name], prev)
+				}
+			}
+		case token.SEMICOLON:
+			// ignore automatically inserted semicolon
+			if lit == "\n" {
+				continue scanFile
+			}
+			fallthrough
+		default:
+			prev = pos
+		}
+	}
+	return decls, uses
+}
+
+func annotatedObj(lit string) (name string, decl, use bool) {
+	if lit[1] == '*' {
+		lit = lit[:len(lit)-2] // strip trailing */
+	}
+	lit = strings.TrimSpace(lit[2:])
+
+scanLit:
+	for idx, r := range lit {
+		switch r {
+		case '=':
+			decl = true
+		case '@':
+			use = true
+		default:
+			name = lit[idx:]
+			break scanLit
+		}
+	}
+	return
+}
diff --git a/src/go/parser/short_test.go b/src/go/parser/short_test.go
index 49bb681..67fef15 100644
--- a/src/go/parser/short_test.go
+++ b/src/go/parser/short_test.go
@@ -6,7 +6,10 @@
 
 package parser
 
-import "testing"
+import (
+	"go/internal/typeparams"
+	"testing"
+)
 
 var valids = []string{
 	"package p\n",
@@ -48,12 +51,104 @@
 	`package p; var _ = map[*P]int{&P{}:0, {}:1}`,
 	`package p; type T = int`,
 	`package p; type (T = p.T; _ = struct{}; x = *T)`,
+	`package p; type T (*int)`,
+	`package p; type _ struct{ ((int)) }`,
+	`package p; type _ struct{ (*(int)) }`,
+	`package p; type _ struct{ ([]byte) }`, // disallowed by type-checker
+	`package p; var _ = func()T(nil)`,
+	`package p; func _(T (P))`,
+	`package p; func _(T []E)`,
+	`package p; func _(T [P]E)`,
+	`package p; type _ [A+B]struct{}`,
+	`package p; func (R) _()`,
+	`package p; type _ struct{ f [n]E }`,
+	`package p; type _ struct{ f [a+b+c+d]E }`,
+	`package p; type I1 interface{}; type I2 interface{ I1 }`,
+}
+
+// validWithTParamsOnly holds source code examples that are valid if
+// parseTypeParams is set, but invalid if not. When checking with the
+// parseTypeParams set, errors are ignored.
+var validWithTParamsOnly = []string{
+	`package p; type _ []T[ /* ERROR "expected ';', found '\['" */ int]`,
+	`package p; type T[P any /* ERROR "expected ']', found any" */ ] struct { P }`,
+	`package p; type T[P comparable /* ERROR "expected ']', found comparable" */ ] struct { P }`,
+	`package p; type T[P comparable /* ERROR "expected ']', found comparable" */ [P]] struct { P }`,
+	`package p; type T[P1, /* ERROR "expected ']', found ','" */ P2 any] struct { P1; f []P2 }`,
+	`package p; func _[ /* ERROR "expected '\(', found '\['" */ T any]()()`,
+	`package p; func _(T (P))`,
+	`package p; func f[ /* ERROR "expected '\(', found '\['" */ A, B any](); func _() { _ = f[int, int] }`,
+	`package p; func _(x /* ERROR "mixed named and unnamed parameters" */ T[P1, P2, P3])`,
+	`package p; func _(x /* ERROR "mixed named and unnamed parameters" */ p.T[Q])`,
+	`package p; func _(p.T[ /* ERROR "missing ',' in parameter list" */ Q])`,
+	`package p; type _[A interface /* ERROR "expected ']', found 'interface'" */ {},] struct{}`,
+	`package p; type _[A interface /* ERROR "expected ']', found 'interface'" */ {}] struct{}`,
+	`package p; type _[A, /* ERROR "expected ']', found ','" */  B any,] struct{}`,
+	`package p; type _[A, /* ERROR "expected ']', found ','" */ B any] struct{}`,
+	`package p; type _[A any /* ERROR "expected ']', found any" */,] struct{}`,
+	`package p; type _[A any /* ERROR "expected ']', found any" */ ]struct{}`,
+	`package p; type _[A any /* ERROR "expected ']', found any" */ ] struct{ A }`,
+	`package p; func _[ /* ERROR "expected '\(', found '\['" */ T any]()`,
+	`package p; func _[ /* ERROR "expected '\(', found '\['" */ T any](x T)`,
+	`package p; func _[ /* ERROR "expected '\(', found '\['" */ T1, T2 any](x T)`,
+	`package p; func _[ /* ERROR "expected '\(', found '\['" */ A, B any](a A) B`,
+	`package p; func _[ /* ERROR "expected '\(', found '\['" */ A, B C](a A) B`,
+	`package p; func _[ /* ERROR "expected '\(', found '\['" */ A, B C[A, B]](a A) B`,
+	`package p; func (T) _[ /* ERROR "expected '\(', found '\['" */ A, B any](a A) B`,
+	`package p; func (T) _[ /* ERROR "expected '\(', found '\['" */ A, B C](a A) B`,
+	`package p; func (T) _[ /* ERROR "expected '\(', found '\['" */ A, B C[A, B]](a A) B`,
+	`package p; type _[A, /* ERROR "expected ']', found ','" */ B any] interface { _(a A) B }`,
+	`package p; type _[A, /* ERROR "expected ']', found ','" */ B C[A, B]] interface { _(a A) B }`,
+	`package p; func _[ /* ERROR "expected '\(', found '\['" */ T1, T2 interface{}](x T1) T2`,
+	`package p; func _[ /* ERROR "expected '\(', found '\['" */ T1 interface{ m() }, T2, T3 interface{}](x T1, y T3) T2`,
+	`package p; var _ = [ /* ERROR "expected expression" */ ]T[int]{}`,
+	`package p; var _ = [ /* ERROR "expected expression" */ 10]T[int]{}`,
+	`package p; var _ = func /* ERROR "expected expression" */ ()T[int]{}`,
+	`package p; var _ = map /* ERROR "expected expression" */ [T[int]]T[int]{}`,
+	`package p; var _ = chan /* ERROR "expected expression" */ T[int](x)`,
+	`package p; func _(_ T[ /* ERROR "missing ',' in parameter list" */ P], T P) T[P]`,
+	`package p; var _ T[ /* ERROR "expected ';', found '\['" */ chan int]`,
+
+	// TODO(rfindley) this error message could be improved.
+	`package p; func (_ /* ERROR "mixed named and unnamed parameters" */ R[P]) _[T any](x T)`,
+	`package p; func (_ /* ERROR "mixed named and unnamed parameters" */ R[ P, Q]) _[T1, T2 any](x T)`,
+
+	`package p; func (R[P] /* ERROR "missing element type" */ ) _[T any]()`,
+	`package p; func _(T[P] /* ERROR "missing element type" */ )`,
+	`package p; func _(T[P1, /* ERROR "expected ']', found ','" */ P2, P3 ])`,
+	`package p; func _(T[P] /* ERROR "missing element type" */ ) T[P]`,
+	`package p; type _ struct{ T[P] /* ERROR "missing element type" */ }`,
+	`package p; type _ struct{ T[struct /* ERROR "expected expression" */ {a, b, c int}] }`,
+	`package p; type _ interface{type /* ERROR "expected '}', found 'type'" */ int}`,
+	`package p; type _ interface{type /* ERROR "expected '}', found 'type'" */ int, float32; type bool; m(); type string;}`,
+	`package p; type I1[T any /* ERROR "expected ']', found any" */ ] interface{}; type I2 interface{ I1[int] }`,
+	`package p; type I1[T any /* ERROR "expected ']', found any" */ ] interface{}; type I2[T any] interface{ I1[T] }`,
+	`package p; type _ interface { f[ /* ERROR "expected ';', found '\['" */ T any]() }`,
 }
 
 func TestValid(t *testing.T) {
-	for _, src := range valids {
-		checkErrors(t, src, src)
-	}
+	t.Run("no tparams", func(t *testing.T) {
+		for _, src := range valids {
+			checkErrors(t, src, src, DeclarationErrors|AllErrors, false)
+		}
+	})
+	t.Run("tparams", func(t *testing.T) {
+		if !typeparams.Enabled {
+			t.Skip("type params are not enabled")
+		}
+		for _, src := range valids {
+			checkErrors(t, src, src, DeclarationErrors|AllErrors, false)
+		}
+		for _, src := range validWithTParamsOnly {
+			checkErrors(t, src, src, DeclarationErrors|AllErrors, false)
+		}
+	})
+}
+
+// TestSingle is useful to track down a problem with a single short test program.
+func TestSingle(t *testing.T) {
+	const src = `package p; var _ = T{}`
+	checkErrors(t, src, src, DeclarationErrors|AllErrors, true)
 }
 
 var invalids = []string{
@@ -79,7 +174,6 @@
 	`package p; var a = chan /* ERROR "expected expression" */ int;`,
 	`package p; var a = []int{[ /* ERROR "expected expression" */ ]int};`,
 	`package p; var a = ( /* ERROR "expected expression" */ []int);`,
-	`package p; var a = a[[ /* ERROR "expected expression" */ ]int:[]int];`,
 	`package p; var a = <- /* ERROR "expected expression" */ chan int;`,
 	`package p; func f() { select { case _ <- chan /* ERROR "expected expression" */ int: } };`,
 	`package p; func f() { _ = (<-<- /* ERROR "expected 'chan'" */ chan int)(nil) };`,
@@ -102,7 +196,14 @@
 	`package p; func f() { go f /* ERROR HERE "function must be invoked" */ }`,
 	`package p; func f() { defer func() {} /* ERROR HERE "function must be invoked" */ }`,
 	`package p; func f() { go func() { func() { f(x func /* ERROR "missing ','" */ (){}) } } }`,
-	`package p; func f(x func(), u v func /* ERROR "missing ','" */ ()){}`,
+	`package p; func _() (type /* ERROR "found 'type'" */ T)(T)`,
+	`package p; func (type /* ERROR "found 'type'" */ T)(T) _()`,
+	`package p; type _[A+B, /* ERROR "expected ']'" */ ] int`,
+
+	// TODO: this error should be positioned on the ':'
+	`package p; var a = a[[]int:[ /* ERROR "expected expression" */ ]int];`,
+	// TODO: the compiler error is better here: "cannot parenthesize embedded type"
+	`package p; type I1 interface{}; type I2 interface{ (/* ERROR "expected '}', found '\('" */ I1) }`,
 
 	// issue 8656
 	`package p; func f() (a b string /* ERROR "missing ','" */ , ok bool)`,
@@ -118,19 +219,61 @@
 	`package p; var _ = struct { x int, /* ERROR "expected ';', found ','" */ y float }{};`,
 
 	// issue 11611
-	`package p; type _ struct { int, } /* ERROR "expected type, found '}'" */ ;`,
+	`package p; type _ struct { int, } /* ERROR "expected 'IDENT', found '}'" */ ;`,
 	`package p; type _ struct { int, float } /* ERROR "expected type, found '}'" */ ;`,
-	`package p; type _ struct { ( /* ERROR "expected anonymous field" */ int) };`,
-	`package p; func _()(x, y, z ... /* ERROR "expected '\)', found '...'" */ int){}`,
-	`package p; func _()(... /* ERROR "expected type, found '...'" */ int){}`,
 
 	// issue 13475
 	`package p; func f() { if true {} else ; /* ERROR "expected if statement or block" */ }`,
 	`package p; func f() { if true {} else defer /* ERROR "expected if statement or block" */ f() }`,
 }
 
+// invalidNoTParamErrs holds invalid source code examples annotated with the
+// error messages produced when ParseTypeParams is not set.
+var invalidNoTParamErrs = []string{
+	`package p; type _[_ any /* ERROR "expected ']', found any" */ ] int; var _ = T[]{}`,
+	`package p; type T[P any /* ERROR "expected ']', found any" */ ] = T0`,
+	`package p; var _ func[ /* ERROR "expected '\(', found '\['" */ T any](T)`,
+	`package p; func _[ /* ERROR "expected '\(', found '\['" */ ]()`,
+	`package p; type _[A, /* ERROR "expected ']', found ','" */] struct{ A }`,
+	`package p; func _[ /* ERROR "expected '\(', found '\['" */ type P, *Q interface{}]()`,
+}
+
+// invalidTParamErrs holds invalid source code examples annotated with the
+// error messages produced when ParseTypeParams is set.
+var invalidTParamErrs = []string{
+	`package p; type _[_ any] int; var _ = T[] /* ERROR "expected operand" */ {}`,
+	`package p; type T[P any] = /* ERROR "cannot be alias" */ T0`,
+	`package p; var _ func[ /* ERROR "cannot have type parameters" */ T any](T)`,
+	`package p; func _[]/* ERROR "empty type parameter list" */()`,
+
+	// TODO(rfindley) a better location would be after the ']'
+	`package p; type _[A/* ERROR "all type parameters must be named" */,] struct{ A }`,
+
+	// TODO(rfindley) this error is confusing.
+	`package p; func _[type /* ERROR "all type parameters must be named" */P, *Q interface{}]()`,
+}
+
 func TestInvalid(t *testing.T) {
-	for _, src := range invalids {
-		checkErrors(t, src, src)
-	}
+	t.Run("no tparams", func(t *testing.T) {
+		for _, src := range invalids {
+			checkErrors(t, src, src, DeclarationErrors|AllErrors|typeparams.DisallowParsing, true)
+		}
+		for _, src := range validWithTParamsOnly {
+			checkErrors(t, src, src, DeclarationErrors|AllErrors|typeparams.DisallowParsing, true)
+		}
+		for _, src := range invalidNoTParamErrs {
+			checkErrors(t, src, src, DeclarationErrors|AllErrors|typeparams.DisallowParsing, true)
+		}
+	})
+	t.Run("tparams", func(t *testing.T) {
+		if !typeparams.Enabled {
+			t.Skip("type params are not enabled")
+		}
+		for _, src := range invalids {
+			checkErrors(t, src, src, DeclarationErrors|AllErrors, true)
+		}
+		for _, src := range invalidTParamErrs {
+			checkErrors(t, src, src, DeclarationErrors|AllErrors, true)
+		}
+	})
 }
diff --git a/src/go/parser/testdata/chans.go2 b/src/go/parser/testdata/chans.go2
new file mode 100644
index 0000000..fad2bce
--- /dev/null
+++ b/src/go/parser/testdata/chans.go2
@@ -0,0 +1,62 @@
+package chans
+
+import "runtime"
+
+// Ranger returns a Sender and a Receiver. The Receiver provides a
+// Next method to retrieve values. The Sender provides a Send method
+// to send values and a Close method to stop sending values. The Next
+// method indicates when the Sender has been closed, and the Send
+// method indicates when the Receiver has been freed.
+//
+// This is a convenient way to exit a goroutine sending values when
+// the receiver stops reading them.
+func Ranger[T any]() (*Sender[T], *Receiver[T]) {
+	c := make(chan T)
+	d := make(chan bool)
+	s := &Sender[T]{values: c, done: d}
+	r := &Receiver[T]{values: c, done: d}
+	runtime.SetFinalizer(r, r.finalize)
+	return s, r
+}
+
+// A sender is used to send values to a Receiver.
+type Sender[T any] struct {
+	values chan<- T
+	done <-chan bool
+}
+
+// Send sends a value to the receiver. It returns whether any more
+// values may be sent; if it returns false the value was not sent.
+func (s *Sender[T]) Send(v T) bool {
+	select {
+	case s.values <- v:
+		return true
+	case <-s.done:
+		return false
+	}
+}
+
+// Close tells the receiver that no more values will arrive.
+// After Close is called, the Sender may no longer be used.
+func (s *Sender[T]) Close() {
+	close(s.values)
+}
+
+// A Receiver receives values from a Sender.
+type Receiver[T any] struct {
+	values <-chan T
+	done chan<- bool
+}
+
+// Next returns the next value from the channel. The bool result
+// indicates whether the value is valid, or whether the Sender has
+// been closed and no more values will be received.
+func (r *Receiver[T]) Next() (T, bool) {
+	v, ok := <-r.values
+	return v, ok
+}
+
+// finalize is a finalizer for the receiver.
+func (r *Receiver[T]) finalize() {
+	close(r.done)
+}
diff --git a/src/go/parser/testdata/issue44504.src b/src/go/parser/testdata/issue44504.src
new file mode 100644
index 0000000..7791f4a
--- /dev/null
+++ b/src/go/parser/testdata/issue44504.src
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test case for issue 44504: panic due to duplicate resolution of slice/index
+// operands. We should not try to resolve a LHS expression with invalid syntax.
+
+package p
+
+func _() {
+  var items []bool
+  items[] /* ERROR "operand" */ = false
+}
diff --git a/src/go/parser/testdata/linalg.go2 b/src/go/parser/testdata/linalg.go2
new file mode 100644
index 0000000..fba0d02
--- /dev/null
+++ b/src/go/parser/testdata/linalg.go2
@@ -0,0 +1,83 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package linalg
+
+import "math"
+
+// Numeric is type bound that matches any numeric type.
+// It would likely be in a constraints package in the standard library.
+type Numeric interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64,
+		complex64, complex128
+}
+
+func DotProduct[T Numeric](s1, s2 []T) T {
+	if len(s1) != len(s2) {
+		panic("DotProduct: slices of unequal length")
+	}
+	var r T
+	for i := range s1 {
+		r += s1[i] * s2[i]
+	}
+	return r
+}
+
+// NumericAbs matches numeric types with an Abs method.
+type NumericAbs[T any] interface {
+	Numeric
+
+	Abs() T
+}
+
+// AbsDifference computes the absolute value of the difference of
+// a and b, where the absolute value is determined by the Abs method.
+func AbsDifference[T NumericAbs](a, b T) T {
+	d := a - b
+	return d.Abs()
+}
+
+// OrderedNumeric is a type bound that matches numeric types that support the < operator.
+type OrderedNumeric interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64
+}
+
+// Complex is a type bound that matches the two complex types, which do not have a < operator.
+type Complex interface {
+	type complex64, complex128
+}
+
+// OrderedAbs is a helper type that defines an Abs method for
+// ordered numeric types.
+type OrderedAbs[T OrderedNumeric] T
+
+func (a OrderedAbs[T]) Abs() OrderedAbs[T] {
+	if a < 0 {
+		return -a
+	}
+	return a
+}
+
+// ComplexAbs is a helper type that defines an Abs method for
+// complex types.
+type ComplexAbs[T Complex] T
+
+func (a ComplexAbs[T]) Abs() ComplexAbs[T] {
+	r := float64(real(a))
+	i := float64(imag(a))
+	d := math.Sqrt(r * r + i * i)
+	return ComplexAbs[T](complex(d, 0))
+}
+
+func OrderedAbsDifference[T OrderedNumeric](a, b T) T {
+	return T(AbsDifference(OrderedAbs[T](a), OrderedAbs[T](b)))
+}
+
+func ComplexAbsDifference[T Complex](a, b T) T {
+	return T(AbsDifference(ComplexAbs[T](a), ComplexAbs[T](b)))
+}
diff --git a/src/go/parser/testdata/map.go2 b/src/go/parser/testdata/map.go2
new file mode 100644
index 0000000..74c79ae
--- /dev/null
+++ b/src/go/parser/testdata/map.go2
@@ -0,0 +1,109 @@
+// Package orderedmap provides an ordered map, implemented as a binary tree.
+package orderedmap
+
+import "chans"
+
+// Map is an ordered map.
+type Map[K, V any] struct {
+	root    *node[K, V]
+	compare func(K, K) int
+}
+
+// node is the type of a node in the binary tree.
+type node[K, V any] struct {
+	key         K
+	val         V
+	left, right *node[K, V]
+}
+
+// New returns a new map.
+func New[K, V any](compare func(K, K) int) *Map[K, V] {
+        return &Map[K, V]{compare: compare}
+}
+
+// find looks up key in the map, and returns either a pointer
+// to the node holding key, or a pointer to the location where
+// such a node would go.
+func (m *Map[K, V]) find(key K) **node[K, V] {
+	pn := &m.root
+	for *pn != nil {
+		switch cmp := m.compare(key, (*pn).key); {
+		case cmp < 0:
+			pn = &(*pn).left
+		case cmp > 0:
+			pn = &(*pn).right
+		default:
+			return pn
+		}
+	}
+	return pn
+}
+
+// Insert inserts a new key/value into the map.
+// If the key is already present, the value is replaced.
+// Returns true if this is a new key, false if already present.
+func (m *Map[K, V]) Insert(key K, val V) bool {
+	pn := m.find(key)
+	if *pn != nil {
+		(*pn).val = val
+		return false
+	}
+        *pn = &node[K, V]{key: key, val: val}
+	return true
+}
+
+// Find returns the value associated with a key, or zero if not present.
+// The found result reports whether the key was found.
+func (m *Map[K, V]) Find(key K) (V, bool) {
+	pn := m.find(key)
+	if *pn == nil {
+		var zero V // see the discussion of zero values, above
+		return zero, false
+	}
+	return (*pn).val, true
+}
+
+// keyValue is a pair of key and value used when iterating.
+type keyValue[K, V any] struct {
+	key K
+	val V
+}
+
+// InOrder returns an iterator that does an in-order traversal of the map.
+func (m *Map[K, V]) InOrder() *Iterator[K, V] {
+	sender, receiver := chans.Ranger[keyValue[K, V]]()
+	var f func(*node[K, V]) bool
+	f = func(n *node[K, V]) bool {
+		if n == nil {
+			return true
+		}
+		// Stop sending values if sender.Send returns false,
+		// meaning that nothing is listening at the receiver end.
+		return f(n.left) &&
+                        // TODO
+			// sender.Send(keyValue[K, V]{n.key, n.val}) &&
+			f(n.right)
+	}
+	go func() {
+		f(m.root)
+		sender.Close()
+	}()
+	return &Iterator{receiver}
+}
+
+// Iterator is used to iterate over the map.
+type Iterator[K, V any] struct {
+	r *chans.Receiver[keyValue[K, V]]
+}
+
+// Next returns the next key and value pair, and a boolean indicating
+// whether they are valid or whether we have reached the end.
+func (it *Iterator[K, V]) Next() (K, V, bool) {
+	keyval, ok := it.r.Next()
+	if !ok {
+		var zerok K
+		var zerov V
+		return zerok, zerov, false
+	}
+	return keyval.key, keyval.val, true
+}
diff --git a/src/go/parser/testdata/metrics.go2 b/src/go/parser/testdata/metrics.go2
new file mode 100644
index 0000000..ef1c66b
--- /dev/null
+++ b/src/go/parser/testdata/metrics.go2
@@ -0,0 +1,58 @@
+package metrics
+
+import "sync"
+
+type Metric1[T comparable] struct {
+	mu sync.Mutex
+	m  map[T]int
+}
+
+func (m *Metric1[T]) Add(v T) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	if m.m == nil {
+		m.m = make(map[T]int)
+	}
+	m[v]++
+}
+
+type key2[T1, T2 comparable] struct {
+	f1 T1
+	f2 T2
+}
+
+type Metric2[T1, T2 cmp2] struct {
+	mu sync.Mutex
+	m  map[key2[T1, T2]]int
+}
+
+func (m *Metric2[T1, T2]) Add(v1 T1, v2 T2) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	if m.m == nil {
+		m.m = make(map[key2[T1, T2]]int)
+	}
+	m[key[T1, T2]{v1, v2}]++
+}
+
+type key3[T1, T2, T3 comparable] struct {
+	f1 T1
+	f2 T2
+	f3 T3
+}
+
+type Metric3[T1, T2, T3 comparable] struct {
+	mu sync.Mutex
+	m  map[key3[T1, T2, T3]]int
+}
+
+func (m *Metric3[T1, T2, T3]) Add(v1 T1, v2 T2, v3 T3) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	if m.m == nil {
+		m.m = make(map[key3]int)
+	}
+	m[key[T1, T2, T3]{v1, v2, v3}]++
+}
+
+// Repeat for the maximum number of permitted arguments.
diff --git a/src/go/parser/testdata/resolution/issue45136.src b/src/go/parser/testdata/resolution/issue45136.src
new file mode 100644
index 0000000..e1d63d8
--- /dev/null
+++ b/src/go/parser/testdata/resolution/issue45136.src
@@ -0,0 +1,27 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue45136
+
+type obj /* =@obj */ struct {
+	name /*=@name */ string
+}
+
+func _() {
+	var foo /* =@foo */ = "foo"
+	obj /* @obj */ ["foo"]
+	obj /* @obj */ .run()
+	obj /* @obj */ {
+		name: foo /* @foo */,
+	}
+	obj /* @obj */ {
+		name: "bar",
+	}.run()
+
+	var _ = File{key: obj /* @obj */ {}}
+	var _ = File{obj /* @obj */ {}}
+
+	[]obj /* @obj */ {foo /* @foo */}
+	x /* =@x1 */ := obj /* @obj */{}
+}
diff --git a/src/go/parser/testdata/resolution/issue45160.src b/src/go/parser/testdata/resolution/issue45160.src
new file mode 100644
index 0000000..6be933b
--- /dev/null
+++ b/src/go/parser/testdata/resolution/issue45160.src
@@ -0,0 +1,25 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue45160
+
+func mklink1 /* =@mklink1func */() {}
+
+func _() {
+	var tests /* =@tests */ = []dirLinkTest /* @dirLinkTest */ {
+		{
+			mklink1 /* @mklink1func */: func() {},
+			mklink2: func(link /* =@link */, target /* =@target */ string) error {
+				return nil
+			},
+		},
+	}
+}
+
+type dirLinkTest /* =@dirLinkTest */ struct {
+	mklink1 /* =@mklink1field */ func(string, string) error
+	mklink2 /* =@mklink2field */ func(string, string) error
+}
+
+func mklink2 /* =@mklink2func */() {}
diff --git a/src/go/parser/testdata/resolution/resolution.src b/src/go/parser/testdata/resolution/resolution.src
new file mode 100644
index 0000000..a880dd1
--- /dev/null
+++ b/src/go/parser/testdata/resolution/resolution.src
@@ -0,0 +1,63 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package resolution
+
+func f /* =@fdecl */(n /* =@narg */ ast.Node) bool {
+		if n /* =@ninit */, ok /* =@ok */ := n /* @narg */ .(*ast.SelectorExpr); ok /* @ok */ {
+			sel = n /* @ninit */
+	}
+}
+
+type c /* =@cdecl */ map[token.Pos]resolvedObj
+
+func (v /* =@vdecl */ c /* @cdecl */) Visit(node /* =@nodearg */ ast.Node) (w /* =@w */ ast.Visitor) {}
+
+const (
+	basic /* =@basic */ = iota
+	labelOk // =@labelOk
+)
+
+type T /* =@T */ int
+
+func _(count /* =@count */ T /* @T */) {
+	x /* =@x1 */ := c /* @cdecl */{}
+	switch x /* =@x2 */ := x /* @x1 */; x /* =@x3 */ := x /* @x2 */.(type) {
+	case c /* @cdecl */:
+	default:
+	}
+loop /* =@loop */:
+	for {
+		if true {
+			break loop /* @loop */
+		}
+	}
+	select {
+	case err /* =@err1 */ := <-_:
+		return err /* @err1 */
+	case err /* =@err2 */ := <-_:
+		return err /* @err2 */
+	}
+
+	_ = func(p1 /* =@p1 */ int, p2 /* =@p2 */ p1) {
+		closed /* =@closed */ := p1 // @p1
+		shadowed /* =@shadowed1 */ := p2 // @p2
+		_ = func(shadowed /* =@shadowed2 */ p2 /* @p2 */) {
+			closed /* @closed */ = 1
+			shadowed /* @shadowed2 */ = 2
+		}
+	}
+}
+
+func (r /* =@r */ c /* @cdecl */) m(_ r) c /* @cdecl */ { return r /* @r */ }
+
+var cycle /* =@cycle */ = cycle /* @cycle */ + 1
+
+type chain /* =@chain */ struct {
+	next /* =@next */ *chain /* @chain */
+}
+
+func recursive /* =@recursive */() {
+	recursive /* @recursive */ ()
+}
diff --git a/src/go/parser/testdata/resolution/typeparams.go2 b/src/go/parser/testdata/resolution/typeparams.go2
new file mode 100644
index 0000000..0ffecd6
--- /dev/null
+++ b/src/go/parser/testdata/resolution/typeparams.go2
@@ -0,0 +1,43 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package resolution
+
+type List /* =@List */ [E /* =@E */ any] []E // @E
+
+type Pair /* =@Pair */ [L /* =@L */, R /* =@R */ any] struct {
+	Left /* =@Left */ L // @L
+	Right /* =@Right */ R // @R
+	L /* =@Lfield */ int
+}
+
+var _ = Pair /* @Pair */ [int, string]{}
+
+type Addable /* =@Addable */ interface {
+	type int64, float64
+}
+
+func Add /* =@AddDecl */[T /* =@T */ Addable /* @Addable */](l /* =@l */, r /* =@r */ T /* @T */) T /* @T */ {
+	var t /* =@t */ T /* @T */
+	return l /* @l */ + r /* @r */ + t /* @t */
+}
+
+type Receiver /* =@Receiver */[P /* =@P */ any] struct {}
+
+// TODO(rFindley): make a decision on how/whether to resolve identifiers that
+// refer to receiver type parameters, as is the case for the 'P' result
+// parameter below.
+func (r /* =@recv */ Receiver /* @Receiver */ [P]) m() P {}
+
+func f /* =@f */[T1 /* =@T1 */ interface{type []T2 /* @T2 */}, T2 /* =@T2 */ any](
+  x /* =@x */ T1 /* @T1 */, T1 /* =@T1_duplicate */ y,  // Note that this is a bug:
+                                                        // the duplicate T1 should
+							// not be allowed.
+  ){
+  // Note that duplicate short var declarations resolve to their alt declaration.
+  x /* @x */ := 0
+  y /* =@y */ := 0
+  T1 /* @T1 */ := 0
+  var t1var /* =@t1var */ T1 /* @T1 */
+}
diff --git a/src/go/parser/testdata/set.go2 b/src/go/parser/testdata/set.go2
new file mode 100644
index 0000000..0da6377
--- /dev/null
+++ b/src/go/parser/testdata/set.go2
@@ -0,0 +1,31 @@
+// Package set implements sets of any type.
+package set
+
+type Set[Elem comparable] map[Elem]struct{}
+
+func Make[Elem comparable]() Set[Elem] {
+	return make(Set(Elem))
+}
+
+func (s Set[Elem]) Add(v Elem) {
+	s[v] = struct{}{}
+}
+
+func (s Set[Elem]) Delete(v Elem) {
+	delete(s, v)
+}
+
+func (s Set[Elem]) Contains(v Elem) bool {
+	_, ok := s[v]
+	return ok
+}
+
+func (s Set[Elem]) Len() int {
+	return len(s)
+}
+
+func (s Set[Elem]) Iterate(f func(Elem)) {
+	for v := range s {
+		f(v)
+	}
+}
diff --git a/src/go/parser/testdata/slices.go2 b/src/go/parser/testdata/slices.go2
new file mode 100644
index 0000000..e060212
--- /dev/null
+++ b/src/go/parser/testdata/slices.go2
@@ -0,0 +1,31 @@
+// Package slices implements various slice algorithms.
+package slices
+
+// Map turns a []T1 to a []T2 using a mapping function.
+func Map[T1, T2 any](s []T1, f func(T1) T2) []T2 {
+	r := make([]T2, len(s))
+	for i, v := range s {
+		r[i] = f(v)
+	}
+	return r
+}
+
+// Reduce reduces a []T1 to a single value using a reduction function.
+func Reduce[T1, T2 any](s []T1, initializer T2, f func(T2, T1) T2) T2 {
+	r := initializer
+	for _, v := range s {
+		r = f(r, v)
+	}
+	return r
+}
+
+// Filter filters values from a slice using a filter function.
+func Filter[T any](s []T, f func(T) bool) []T {
+	var r []T
+	for _, v := range s {
+		if f(v) {
+			r = append(r, v)
+		}
+	}
+	return r
+}
diff --git a/src/go/parser/testdata/sort.go2 b/src/go/parser/testdata/sort.go2
new file mode 100644
index 0000000..88be79f
--- /dev/null
+++ b/src/go/parser/testdata/sort.go2
@@ -0,0 +1,27 @@
+package sort
+
+type orderedSlice[Elem comparable] []Elem
+
+func (s orderedSlice[Elem]) Len() int           { return len(s) }
+func (s orderedSlice[Elem]) Less(i, j int) bool { return s[i] < s[j] }
+func (s orderedSlice[Elem]) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+
+// OrderedSlice sorts the slice s in ascending order.
+// The elements of s must be ordered using the < operator.
+func OrderedSlice[Elem comparable](s []Elem) {
+	sort.Sort(orderedSlice[Elem](s))
+}
+
+type sliceFn[Elem any] struct {
+	s []Elem
+	f func(Elem, Elem) bool
+}
+
+func (s sliceFn[Elem]) Len() int           { return len(s.s) }
+func (s sliceFn[Elem]) Less(i, j int) bool { return s.f(s.s[i], s.s[j]) }
+func (s sliceFn[Elem]) Swap(i, j int)      { s.s[i], s.s[j] = s.s[j], s.s[i] }
+
+// SliceFn sorts the slice s according to the function f.
+func SliceFn[Elem any](s []Elem, f func(Elem, Elem) bool) {
+	Sort(sliceFn[Elem]{s, f})
+}
diff --git a/src/go/parser/testdata/typeparams.src b/src/go/parser/testdata/typeparams.src
new file mode 100644
index 0000000..1fea23f
--- /dev/null
+++ b/src/go/parser/testdata/typeparams.src
@@ -0,0 +1,17 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test cases for error messages produced while parsing code that uses type
+// parameters, without ParseTypeParams being enabled.
+
+package p
+
+type List[E any /* ERROR "expected ']', found any" */ ] []E
+
+type Pair[L, /* ERROR "expected ']', found ','" */ R any] struct {
+	Left L
+	Right R
+}
+
+var _ = Pair[int, /* ERROR "expected ']' or ':', found ','" */ string]{}
diff --git a/src/go/printer/gobuild.go b/src/go/printer/gobuild.go
new file mode 100644
index 0000000..f00492d
--- /dev/null
+++ b/src/go/printer/gobuild.go
@@ -0,0 +1,170 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package printer
+
+import (
+	"go/build/constraint"
+	"sort"
+	"text/tabwriter"
+)
+
+func (p *printer) fixGoBuildLines() {
+	if len(p.goBuild)+len(p.plusBuild) == 0 {
+		return
+	}
+
+	// Find latest possible placement of //go:build and // +build comments.
+	// That's just after the last blank line before we find a non-comment.
+	// (We'll add another blank line after our comment block.)
+	// When we start dropping // +build comments, we can skip over /* */ comments too.
+	// Note that we are processing tabwriter input, so every comment
+	// begins and ends with a tabwriter.Escape byte.
+	// And some newlines have turned into \f bytes.
+	insert := 0
+	for pos := 0; ; {
+		// Skip leading space at beginning of line.
+		blank := true
+		for pos < len(p.output) && (p.output[pos] == ' ' || p.output[pos] == '\t') {
+			pos++
+		}
+		// Skip over // comment if any.
+		if pos+3 < len(p.output) && p.output[pos] == tabwriter.Escape && p.output[pos+1] == '/' && p.output[pos+2] == '/' {
+			blank = false
+			for pos < len(p.output) && !isNL(p.output[pos]) {
+				pos++
+			}
+		}
+		// Skip over \n at end of line.
+		if pos >= len(p.output) || !isNL(p.output[pos]) {
+			break
+		}
+		pos++
+
+		if blank {
+			insert = pos
+		}
+	}
+
+	// If there is a //go:build comment before the place we identified,
+	// use that point instead. (Earlier in the file is always fine.)
+	if len(p.goBuild) > 0 && p.goBuild[0] < insert {
+		insert = p.goBuild[0]
+	} else if len(p.plusBuild) > 0 && p.plusBuild[0] < insert {
+		insert = p.plusBuild[0]
+	}
+
+	var x constraint.Expr
+	switch len(p.goBuild) {
+	case 0:
+		// Synthesize //go:build expression from // +build lines.
+		for _, pos := range p.plusBuild {
+			y, err := constraint.Parse(p.commentTextAt(pos))
+			if err != nil {
+				x = nil
+				break
+			}
+			if x == nil {
+				x = y
+			} else {
+				x = &constraint.AndExpr{X: x, Y: y}
+			}
+		}
+	case 1:
+		// Parse //go:build expression.
+		x, _ = constraint.Parse(p.commentTextAt(p.goBuild[0]))
+	}
+
+	var block []byte
+	if x == nil {
+		// Don't have a valid //go:build expression to treat as truth.
+		// Bring all the lines together but leave them alone.
+		// Note that these are already tabwriter-escaped.
+		for _, pos := range p.goBuild {
+			block = append(block, p.lineAt(pos)...)
+		}
+		for _, pos := range p.plusBuild {
+			block = append(block, p.lineAt(pos)...)
+		}
+	} else {
+		block = append(block, tabwriter.Escape)
+		block = append(block, "//go:build "...)
+		block = append(block, x.String()...)
+		block = append(block, tabwriter.Escape, '\n')
+		if len(p.plusBuild) > 0 {
+			lines, err := constraint.PlusBuildLines(x)
+			if err != nil {
+				lines = []string{"// +build error: " + err.Error()}
+			}
+			for _, line := range lines {
+				block = append(block, tabwriter.Escape)
+				block = append(block, line...)
+				block = append(block, tabwriter.Escape, '\n')
+			}
+		}
+	}
+	block = append(block, '\n')
+
+	// Build sorted list of lines to delete from remainder of output.
+	toDelete := append(p.goBuild, p.plusBuild...)
+	sort.Ints(toDelete)
+
+	// Collect output after insertion point, with lines deleted, into after.
+	var after []byte
+	start := insert
+	for _, end := range toDelete {
+		if end < start {
+			continue
+		}
+		after = appendLines(after, p.output[start:end])
+		start = end + len(p.lineAt(end))
+	}
+	after = appendLines(after, p.output[start:])
+	if n := len(after); n >= 2 && isNL(after[n-1]) && isNL(after[n-2]) {
+		after = after[:n-1]
+	}
+
+	p.output = p.output[:insert]
+	p.output = append(p.output, block...)
+	p.output = append(p.output, after...)
+}
+
+// appendLines is like append(x, y...)
+// but it avoids creating doubled blank lines,
+// which would not be gofmt-standard output.
+// It assumes that only whole blocks of lines are being appended,
+// not line fragments.
+func appendLines(x, y []byte) []byte {
+	if len(y) > 0 && isNL(y[0]) && // y starts in blank line
+		(len(x) == 0 || len(x) >= 2 && isNL(x[len(x)-1]) && isNL(x[len(x)-2])) { // x is empty or ends in blank line
+		y = y[1:] // delete y's leading blank line
+	}
+	return append(x, y...)
+}
+
+func (p *printer) lineAt(start int) []byte {
+	pos := start
+	for pos < len(p.output) && !isNL(p.output[pos]) {
+		pos++
+	}
+	if pos < len(p.output) {
+		pos++
+	}
+	return p.output[start:pos]
+}
+
+func (p *printer) commentTextAt(start int) string {
+	if start < len(p.output) && p.output[start] == tabwriter.Escape {
+		start++
+	}
+	pos := start
+	for pos < len(p.output) && p.output[pos] != tabwriter.Escape && !isNL(p.output[pos]) {
+		pos++
+	}
+	return string(p.output[start:pos])
+}
+
+func isNL(b byte) bool {
+	return b == '\n' || b == '\f'
+}
diff --git a/src/go/printer/nodes.go b/src/go/printer/nodes.go
index 95b9e91..913281e 100644
--- a/src/go/printer/nodes.go
+++ b/src/go/printer/nodes.go
@@ -11,6 +11,7 @@
 import (
 	"bytes"
 	"go/ast"
+	"go/internal/typeparams"
 	"go/token"
 	"math"
 	"strconv"
@@ -319,8 +320,12 @@
 	}
 }
 
-func (p *printer) parameters(fields *ast.FieldList) {
-	p.print(fields.Opening, token.LPAREN)
+func (p *printer) parameters(fields *ast.FieldList, isTypeParam bool) {
+	openTok, closeTok := token.LPAREN, token.RPAREN
+	if isTypeParam {
+		openTok, closeTok = token.LBRACK, token.RBRACK
+	}
+	p.print(fields.Opening, openTok)
 	if len(fields.List) > 0 {
 		prevLine := p.lineFor(fields.Opening)
 		ws := indent
@@ -328,13 +333,8 @@
 			// determine par begin and end line (may be different
 			// if there are multiple parameter names for this par
 			// or the type is on a separate line)
-			var parLineBeg int
-			if len(par.Names) > 0 {
-				parLineBeg = p.lineFor(par.Names[0].Pos())
-			} else {
-				parLineBeg = p.lineFor(par.Type.Pos())
-			}
-			var parLineEnd = p.lineFor(par.Type.End())
+			parLineBeg := p.lineFor(par.Pos())
+			parLineEnd := p.lineFor(par.End())
 			// separating "," if needed
 			needsLinebreak := 0 < prevLine && prevLine < parLineBeg
 			if i > 0 {
@@ -379,25 +379,29 @@
 			p.print(unindent)
 		}
 	}
-	p.print(fields.Closing, token.RPAREN)
+	p.print(fields.Closing, closeTok)
 }
 
-func (p *printer) signature(params, result *ast.FieldList) {
-	if params != nil {
-		p.parameters(params)
+func (p *printer) signature(sig *ast.FuncType) {
+	if tparams := typeparams.Get(sig); tparams != nil {
+		p.parameters(tparams, true)
+	}
+	if sig.Params != nil {
+		p.parameters(sig.Params, false)
 	} else {
 		p.print(token.LPAREN, token.RPAREN)
 	}
-	n := result.NumFields()
+	res := sig.Results
+	n := res.NumFields()
 	if n > 0 {
-		// result != nil
+		// res != nil
 		p.print(blank)
-		if n == 1 && result.List[0].Names == nil {
-			// single anonymous result; no ()'s
-			p.expr(stripParensAlways(result.List[0].Type))
+		if n == 1 && res.List[0].Names == nil {
+			// single anonymous res; no ()'s
+			p.expr(stripParensAlways(res.List[0].Type))
 			return
 		}
-		p.parameters(result)
+		p.parameters(res, false)
 	}
 }
 
@@ -467,10 +471,18 @@
 				}
 				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)
+				if len(f.Names) > 0 {
+					// type list type or method
+					name := f.Names[0] // "type" or method name
+					p.expr(name)
+					if name.Name == "type" {
+						// type list type
+						p.print(blank)
+						p.expr(f.Type)
+					} else {
+						// method
+						p.signature(f.Type.(*ast.FuncType)) // don't print "func"
+					}
 				} else {
 					// embedded interface
 					p.expr(f.Type)
@@ -538,19 +550,47 @@
 	} else { // interface
 
 		var line int
+		var prev *ast.Ident // previous "type" identifier
 		for i, f := range list {
+			var name *ast.Ident // first name, or nil
+			if len(f.Names) > 0 {
+				name = f.Names[0]
+			}
 			if i > 0 {
-				p.linebreak(p.lineFor(f.Pos()), 1, ignore, p.linesFrom(line) > 0)
+				// don't do a line break (min == 0) if we are printing a list of types
+				// TODO(gri) this doesn't work quite right if the list of types is
+				//           spread across multiple lines
+				min := 1
+				if prev != nil && name == prev {
+					min = 0
+				}
+				p.linebreak(p.lineFor(f.Pos()), min, ignore, p.linesFrom(line) > 0)
 			}
 			p.setComment(f.Doc)
 			p.recordLine(&line)
-			if ftyp, isFtyp := f.Type.(*ast.FuncType); isFtyp {
-				// method
-				p.expr(f.Names[0])
-				p.signature(ftyp.Params, ftyp.Results)
+			if name != nil {
+				// type list type or method
+				if name.Name == "type" {
+					// type list type
+					if name == prev {
+						// type is part of a list of types
+						p.print(token.COMMA, blank)
+					} else {
+						// type starts a new list of types
+						p.print(name, blank)
+					}
+					p.expr(f.Type)
+					prev = name
+				} else {
+					// method
+					p.expr(name)
+					p.signature(f.Type.(*ast.FuncType)) // don't print "func"
+					prev = nil
+				}
 			} else {
 				// embedded interface
 				p.expr(f.Type)
+				prev = nil
 			}
 			p.setComment(f.Comment)
 		}
@@ -800,7 +840,7 @@
 		p.print(x.Type.Pos(), token.FUNC)
 		// See the comment in funcDecl about how the header size is computed.
 		startCol := p.out.Column - len("func")
-		p.signature(x.Type.Params, x.Type.Results)
+		p.signature(x.Type)
 		p.funcBody(p.distanceFrom(x.Type.Pos(), startCol), blank, x.Body)
 
 	case *ast.ParenExpr:
@@ -831,7 +871,17 @@
 		// TODO(gri): should treat[] like parentheses and undo one level of depth
 		p.expr1(x.X, token.HighestPrec, 1)
 		p.print(x.Lbrack, token.LBRACK)
-		p.expr0(x.Index, depth+1)
+		// Note: we're a bit defensive here to handle the case of a ListExpr of
+		// length 1.
+		if list := typeparams.UnpackExpr(x.Index); len(list) > 0 {
+			if len(list) > 1 {
+				p.exprList(x.Lbrack, list, depth+1, commaTerm, x.Rbrack, false)
+			} else {
+				p.expr0(list[0], depth+1)
+			}
+		} else {
+			p.expr0(x.Index, depth+1)
+		}
 		p.print(x.Rbrack, token.RBRACK)
 
 	case *ast.SliceExpr:
@@ -945,7 +995,7 @@
 
 	case *ast.FuncType:
 		p.print(token.FUNC)
-		p.signature(x.Params, x.Results)
+		p.signature(x)
 
 	case *ast.InterfaceType:
 		p.print(token.INTERFACE)
@@ -1585,6 +1635,9 @@
 	case *ast.TypeSpec:
 		p.setComment(s.Doc)
 		p.expr(s.Name)
+		if tparams := typeparams.Get(s); tparams != nil {
+			p.parameters(tparams, true)
+		}
 		if n == 1 {
 			p.print(blank)
 		} else {
@@ -1773,11 +1826,11 @@
 	// FUNC is emitted).
 	startCol := p.out.Column - len("func ")
 	if d.Recv != nil {
-		p.parameters(d.Recv) // method: print receiver
+		p.parameters(d.Recv, false) // method: print receiver
 		p.print(blank)
 	}
 	p.expr(d.Name)
-	p.signature(d.Type.Params, d.Type.Results)
+	p.signature(d.Type)
 	p.funcBody(p.distanceFrom(d.Pos(), startCol), vtab, d.Body)
 }
 
diff --git a/src/go/printer/printer.go b/src/go/printer/printer.go
index 0077afe..ba61f78 100644
--- a/src/go/printer/printer.go
+++ b/src/go/printer/printer.go
@@ -8,6 +8,7 @@
 import (
 	"fmt"
 	"go/ast"
+	"go/build/constraint"
 	"go/token"
 	"io"
 	"os"
@@ -64,6 +65,8 @@
 	lastTok      token.Token  // last token printed (token.ILLEGAL if it's whitespace)
 	prevOpen     token.Token  // previous non-brace "open" token (, [, or token.ILLEGAL
 	wsbuf        []whiteSpace // delayed white space
+	goBuild      []int        // start index of all //go:build comments in output
+	plusBuild    []int        // start index of all // +build comments in output
 
 	// Positions
 	// The out position differs from the pos position when the result
@@ -649,6 +652,11 @@
 
 	// shortcut common case of //-style comments
 	if text[1] == '/' {
+		if constraint.IsGoBuild(text) {
+			p.goBuild = append(p.goBuild, len(p.output))
+		} else if constraint.IsPlusBuild(text) {
+			p.plusBuild = append(p.plusBuild, len(p.output))
+		}
 		p.writeString(pos, trimRight(text), true)
 		return
 	}
@@ -836,7 +844,7 @@
 // ----------------------------------------------------------------------------
 // Printing interface
 
-// nlines limits n to maxNewlines.
+// nlimit limits n to maxNewlines.
 func nlimit(n int) int {
 	if n > maxNewlines {
 		n = maxNewlines
@@ -1122,6 +1130,8 @@
 	// get comments ready for use
 	p.nextComment()
 
+	p.print(pmode(0))
+
 	// format node
 	switch n := node.(type) {
 	case ast.Expr:
@@ -1313,6 +1323,10 @@
 	p.impliedSemi = false // EOF acts like a newline
 	p.flush(token.Position{Offset: infinity, Line: infinity}, token.EOF)
 
+	// output is buffered in p.output now.
+	// fix //go:build and // +build comments if needed.
+	p.fixGoBuildLines()
+
 	// redirect output through a trimmer to eliminate trailing whitespace
 	// (Input to a tabwriter must be untrimmed since trailing tabs provide
 	// formatting information. The tabwriter could provide trimming
diff --git a/src/go/printer/printer_test.go b/src/go/printer/printer_test.go
index 45e5011..20c97b8 100644
--- a/src/go/printer/printer_test.go
+++ b/src/go/printer/printer_test.go
@@ -10,6 +10,7 @@
 	"flag"
 	"fmt"
 	"go/ast"
+	"go/internal/typeparams"
 	"go/parser"
 	"go/token"
 	"io"
@@ -35,6 +36,7 @@
 	rawFormat
 	normNumber
 	idempotent
+	allowTypeParams
 )
 
 // format parses src, prints the corresponding AST, verifies the resulting
@@ -70,7 +72,7 @@
 
 	// make sure formatted output is syntactically correct
 	res := buf.Bytes()
-	if _, err := parser.ParseFile(fset, "", res, 0); err != nil {
+	if _, err := parser.ParseFile(fset, "", res, parser.ParseComments); err != nil {
 		return nil, fmt.Errorf("re-parse: %s\n%s", err, buf.Bytes())
 	}
 
@@ -88,8 +90,11 @@
 
 // diff compares a and b.
 func diff(aname, bname string, a, b []byte) error {
-	var buf bytes.Buffer // holding long error message
+	if bytes.Equal(a, b) {
+		return nil
+	}
 
+	var buf bytes.Buffer // holding long error message
 	// compare lengths
 	if len(a) != len(b) {
 		fmt.Fprintf(&buf, "\nlength changed: len(%s) = %d, len(%s) = %d", aname, len(a), bname, len(b))
@@ -97,7 +102,7 @@
 
 	// compare contents
 	line := 1
-	offs := 1
+	offs := 0
 	for i := 0; i < len(a) && i < len(b); i++ {
 		ch := a[i]
 		if ch != b[i] {
@@ -112,10 +117,8 @@
 		}
 	}
 
-	if buf.Len() > 0 {
-		return errors.New(buf.String())
-	}
-	return nil
+	fmt.Fprintf(&buf, "\n%s:\n%s\n%s:\n%s", aname, a, bname, b)
+	return errors.New(buf.String())
 }
 
 func runcheck(t *testing.T, source, golden string, mode checkMode) {
@@ -206,11 +209,22 @@
 	{"complit.input", "complit.x", export},
 	{"go2numbers.input", "go2numbers.golden", idempotent},
 	{"go2numbers.input", "go2numbers.norm", normNumber | idempotent},
+	{"generics.input", "generics.golden", idempotent | allowTypeParams},
+	{"gobuild1.input", "gobuild1.golden", idempotent},
+	{"gobuild2.input", "gobuild2.golden", idempotent},
+	{"gobuild3.input", "gobuild3.golden", idempotent},
+	{"gobuild4.input", "gobuild4.golden", idempotent},
+	{"gobuild5.input", "gobuild5.golden", idempotent},
+	{"gobuild6.input", "gobuild6.golden", idempotent},
+	{"gobuild7.input", "gobuild7.golden", idempotent},
 }
 
 func TestFiles(t *testing.T) {
 	t.Parallel()
 	for _, e := range data {
+		if !typeparams.Enabled && e.mode&allowTypeParams != 0 {
+			continue
+		}
 		source := filepath.Join(dataDir, e.source)
 		golden := filepath.Join(dataDir, e.golden)
 		mode := e.mode
diff --git a/src/go/printer/testdata/declarations.input b/src/go/printer/testdata/declarations.input
index a858051..f34395b 100644
--- a/src/go/printer/testdata/declarations.input
+++ b/src/go/printer/testdata/declarations.input
@@ -1018,4 +1018,4 @@
 	c = foo
 	d = interface{}
 	ddd = p.Foo
-)
\ No newline at end of file
+)
diff --git a/src/go/printer/testdata/generics.golden b/src/go/printer/testdata/generics.golden
new file mode 100644
index 0000000..cc7fbbe
--- /dev/null
+++ b/src/go/printer/testdata/generics.golden
@@ -0,0 +1,43 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package generics
+
+func _[A, B any](a A, b B) int	{}
+func _[T any](x, y T) T
+
+type T[P any] struct{}
+type T[P1, P2, P3 any] struct{}
+
+type T[P C] struct{}
+type T[P1, P2, P3 C] struct{}
+
+type T[P C[P]] struct{}
+type T[P1, P2, P3 C[P1, P2, P3]] struct{}
+
+func f[P any](x P)
+func f[P1, P2, P3 any](x1 P1, x2 P2, x3 P3) struct{}
+
+func f[P interface{}](x P)
+func f[P1, P2, P3 interface {
+	m1(P1)
+	type P2, P3
+}](x1 P1, x2 P2, x3 P3) struct{}
+func f[P any](T1[P], T2[P]) T3[P]
+
+func (x T[P]) m()
+func (T[P]) m(x T[P]) P
+
+func _() {
+	type _ []T[P]
+	var _ []T[P]
+	_ = []T[P]{}
+}
+
+// properly format one-line type lists
+type _ interface{ type a }
+
+type _ interface {
+	type a, b, c
+}
diff --git a/src/go/printer/testdata/generics.input b/src/go/printer/testdata/generics.input
new file mode 100644
index 0000000..f4571ad
--- /dev/null
+++ b/src/go/printer/testdata/generics.input
@@ -0,0 +1,38 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package generics
+
+func _[A, B any](a A, b B) int {}
+func _[T any](x, y T) T
+
+type T[P any] struct{}
+type T[P1, P2, P3 any] struct{}
+
+type T[P C] struct{}
+type T[P1, P2, P3 C] struct{}
+
+type T[P C[P]] struct{}
+type T[P1, P2, P3 C[P1, P2, P3]] struct{}
+
+func f[P any](x P)
+func f[P1, P2, P3 any](x1 P1, x2 P2, x3 P3) struct{}
+
+func f[P interface{}](x P)
+func f[P1, P2, P3 interface{ m1(P1); type P2, P3 }](x1 P1, x2 P2, x3 P3) struct{}
+func f[P any](T1[P], T2[P]) T3[P]
+
+func (x T[P]) m()
+func ((T[P])) m(x T[P]) P
+
+func _() {
+	type _ []T[P]
+	var _ []T[P]
+	_ = []T[P]{}
+}
+
+// properly format one-line type lists
+type _ interface { type a }
+
+type _ interface { type a,b,c }
diff --git a/src/go/printer/testdata/gobuild1.golden b/src/go/printer/testdata/gobuild1.golden
new file mode 100644
index 0000000..649da40
--- /dev/null
+++ b/src/go/printer/testdata/gobuild1.golden
@@ -0,0 +1,6 @@
+//go:build x
+// +build x
+
+package p
+
+func f()
diff --git a/src/go/printer/testdata/gobuild1.input b/src/go/printer/testdata/gobuild1.input
new file mode 100644
index 0000000..6538ee6
--- /dev/null
+++ b/src/go/printer/testdata/gobuild1.input
@@ -0,0 +1,7 @@
+package p
+
+//go:build x
+
+func f()
+
+// +build y
diff --git a/src/go/printer/testdata/gobuild2.golden b/src/go/printer/testdata/gobuild2.golden
new file mode 100644
index 0000000..c46fd34
--- /dev/null
+++ b/src/go/printer/testdata/gobuild2.golden
@@ -0,0 +1,8 @@
+//go:build x
+// +build x
+
+// other comment
+
+package p
+
+func f()
diff --git a/src/go/printer/testdata/gobuild2.input b/src/go/printer/testdata/gobuild2.input
new file mode 100644
index 0000000..f0f772a
--- /dev/null
+++ b/src/go/printer/testdata/gobuild2.input
@@ -0,0 +1,9 @@
+// +build y
+
+// other comment
+
+package p
+
+func f()
+
+//go:build x
diff --git a/src/go/printer/testdata/gobuild3.golden b/src/go/printer/testdata/gobuild3.golden
new file mode 100644
index 0000000..db92c57
--- /dev/null
+++ b/src/go/printer/testdata/gobuild3.golden
@@ -0,0 +1,10 @@
+// other comment
+
+//go:build x
+// +build x
+
+// yet another comment
+
+package p
+
+func f()
diff --git a/src/go/printer/testdata/gobuild3.input b/src/go/printer/testdata/gobuild3.input
new file mode 100644
index 0000000..d0c97b2
--- /dev/null
+++ b/src/go/printer/testdata/gobuild3.input
@@ -0,0 +1,11 @@
+// other comment
+
+// +build y
+
+// yet another comment
+
+package p
+
+//go:build x
+
+func f()
diff --git a/src/go/printer/testdata/gobuild4.golden b/src/go/printer/testdata/gobuild4.golden
new file mode 100644
index 0000000..b16477f
--- /dev/null
+++ b/src/go/printer/testdata/gobuild4.golden
@@ -0,0 +1,6 @@
+//go:build (x || y) && z
+// +build x y
+// +build z
+
+// doc comment
+package p
diff --git a/src/go/printer/testdata/gobuild4.input b/src/go/printer/testdata/gobuild4.input
new file mode 100644
index 0000000..29d5a0a
--- /dev/null
+++ b/src/go/printer/testdata/gobuild4.input
@@ -0,0 +1,5 @@
+// doc comment
+package p
+
+// +build x y
+// +build z
diff --git a/src/go/printer/testdata/gobuild5.golden b/src/go/printer/testdata/gobuild5.golden
new file mode 100644
index 0000000..2808a53
--- /dev/null
+++ b/src/go/printer/testdata/gobuild5.golden
@@ -0,0 +1,4 @@
+//go:build !(x || y) && z
+// +build !x,!y,z
+
+package p
diff --git a/src/go/printer/testdata/gobuild5.input b/src/go/printer/testdata/gobuild5.input
new file mode 100644
index 0000000..ec5815c
--- /dev/null
+++ b/src/go/printer/testdata/gobuild5.input
@@ -0,0 +1,4 @@
+//go:build !(x || y) && z
+// +build something else
+
+package p
diff --git a/src/go/printer/testdata/gobuild6.golden b/src/go/printer/testdata/gobuild6.golden
new file mode 100644
index 0000000..abb1e2a
--- /dev/null
+++ b/src/go/printer/testdata/gobuild6.golden
@@ -0,0 +1,5 @@
+//go:build !(x || y) && z
+
+// no +build line
+
+package p
diff --git a/src/go/printer/testdata/gobuild6.input b/src/go/printer/testdata/gobuild6.input
new file mode 100644
index 0000000..1621897
--- /dev/null
+++ b/src/go/printer/testdata/gobuild6.input
@@ -0,0 +1,4 @@
+//go:build !(x || y) && z
+// no +build line
+
+package p
diff --git a/src/go/printer/testdata/gobuild7.golden b/src/go/printer/testdata/gobuild7.golden
new file mode 100644
index 0000000..bf41dd4
--- /dev/null
+++ b/src/go/printer/testdata/gobuild7.golden
@@ -0,0 +1,11 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Delete this file once Go 1.17 comes out and we can retire Go 1.15 support.
+
+//go:build !go1.16
+// +build !go1.16
+
+// Package buildtag defines an Analyzer that checks build tags.
+package buildtag
diff --git a/src/go/printer/testdata/gobuild7.input b/src/go/printer/testdata/gobuild7.input
new file mode 100644
index 0000000..bf41dd4
--- /dev/null
+++ b/src/go/printer/testdata/gobuild7.input
@@ -0,0 +1,11 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Delete this file once Go 1.17 comes out and we can retire Go 1.15 support.
+
+//go:build !go1.16
+// +build !go1.16
+
+// Package buildtag defines an Analyzer that checks build tags.
+package buildtag
diff --git a/src/go/printer/testdata/parser.go b/src/go/printer/testdata/parser.go
index 80b476c..fc2812a 100644
--- a/src/go/printer/testdata/parser.go
+++ b/src/go/printer/testdata/parser.go
@@ -231,7 +231,7 @@
 	// Because of one-token look-ahead, print the previous token
 	// when tracing as it provides a more readable output. The
 	// very first token (!p.pos.IsValid()) is not initialized
-	// (it is token.ILLEGAL), so don't print it .
+	// (it is token.ILLEGAL), so don't print it.
 	if p.trace && p.pos.IsValid() {
 		s := p.tok.String()
 		switch {
diff --git a/src/go/scanner/errors.go b/src/go/scanner/errors.go
index bf7bfa3..3114f4b 100644
--- a/src/go/scanner/errors.go
+++ b/src/go/scanner/errors.go
@@ -86,7 +86,7 @@
 			i++
 		}
 	}
-	(*p) = (*p)[0:i]
+	*p = (*p)[0:i]
 }
 
 // An ErrorList implements the error interface.
diff --git a/src/go/scanner/scanner.go b/src/go/scanner/scanner.go
index 00fe2dc..f08e28c 100644
--- a/src/go/scanner/scanner.go
+++ b/src/go/scanner/scanner.go
@@ -48,11 +48,16 @@
 	ErrorCount int // number of errors encountered
 }
 
-const bom = 0xFEFF // byte order mark, only permitted as very first character
+const (
+	bom = 0xFEFF // byte order mark, only permitted as very first character
+	eof = -1     // end of file
+)
 
 // Read the next Unicode char into s.ch.
 // s.ch < 0 means end-of-file.
 //
+// For optimization, there is some overlap between this method and
+// s.scanIdentifier.
 func (s *Scanner) next() {
 	if s.rdOffset < len(s.src) {
 		s.offset = s.rdOffset
@@ -81,7 +86,7 @@
 			s.lineOffset = s.offset
 			s.file.AddLine(s.offset)
 		}
-		s.ch = -1 // eof
+		s.ch = eof
 	}
 }
 
@@ -347,11 +352,53 @@
 	return isDecimal(ch) || ch >= utf8.RuneSelf && unicode.IsDigit(ch)
 }
 
+// scanIdentifier reads the string of valid identifier characters at s.offset.
+// It must only be called when s.ch is known to be a valid letter.
+//
+// Be careful when making changes to this function: it is optimized and affects
+// scanning performance significantly.
 func (s *Scanner) scanIdentifier() string {
 	offs := s.offset
-	for isLetter(s.ch) || isDigit(s.ch) {
+
+	// Optimize for the common case of an ASCII identifier.
+	//
+	// Ranging over s.src[s.rdOffset:] lets us avoid some bounds checks, and
+	// avoids conversions to runes.
+	//
+	// In case we encounter a non-ASCII character, fall back on the slower path
+	// of calling into s.next().
+	for rdOffset, b := range s.src[s.rdOffset:] {
+		if 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z' || b == '_' || '0' <= b && b <= '9' {
+			// Avoid assigning a rune for the common case of an ascii character.
+			continue
+		}
+		s.rdOffset += rdOffset
+		if 0 < b && b < utf8.RuneSelf {
+			// Optimization: we've encountered an ASCII character that's not a letter
+			// or number. Avoid the call into s.next() and corresponding set up.
+			//
+			// Note that s.next() does some line accounting if s.ch is '\n', so this
+			// shortcut is only possible because we know that the preceding character
+			// is not '\n'.
+			s.ch = rune(b)
+			s.offset = s.rdOffset
+			s.rdOffset++
+			goto exit
+		}
+		// We know that the preceding character is valid for an identifier because
+		// scanIdentifier is only called when s.ch is a letter, so calling s.next()
+		// at s.rdOffset resets the scanner state.
 		s.next()
+		for isLetter(s.ch) || isDigit(s.ch) {
+			s.next()
+		}
+		goto exit
 	}
+	s.offset = len(s.src)
+	s.rdOffset = len(s.src)
+	s.ch = eof
+
+exit:
 	return string(s.src[offs:s.offset])
 }
 
@@ -383,7 +430,7 @@
 			if s.ch == '_' {
 				ds = 2
 			} else if s.ch >= max && *invalid < 0 {
-				*invalid = int(s.offset) // record invalid rune offset
+				*invalid = s.offset // record invalid rune offset
 			}
 			digsep |= ds
 			s.next()
diff --git a/src/go/scanner/scanner_test.go b/src/go/scanner/scanner_test.go
index ab4c2dd..db123c3 100644
--- a/src/go/scanner/scanner_test.go
+++ b/src/go/scanner/scanner_test.go
@@ -628,7 +628,7 @@
 	}
 
 	if S.ErrorCount != len(invalidSegments) {
-		t.Errorf("go %d errors; want %d", S.ErrorCount, len(invalidSegments))
+		t.Errorf("got %d errors; want %d", S.ErrorCount, len(invalidSegments))
 	}
 }
 
@@ -812,6 +812,8 @@
 	{"//\ufeff", token.COMMENT, 2, "//\ufeff", "illegal byte order mark"},                                // only first BOM is ignored
 	{"'\ufeff" + `'`, token.CHAR, 1, "'\ufeff" + `'`, "illegal byte order mark"},                         // only first BOM is ignored
 	{`"` + "abc\ufeffdef" + `"`, token.STRING, 4, `"` + "abc\ufeffdef" + `"`, "illegal byte order mark"}, // only first BOM is ignored
+	{"abc\x00def", token.IDENT, 3, "abc", "illegal character NUL"},
+	{"abc\x00", token.IDENT, 3, "abc", "illegal character NUL"},
 }
 
 func TestScanErrors(t *testing.T) {
@@ -889,26 +891,37 @@
 	}
 }
 
-func BenchmarkScanFile(b *testing.B) {
-	b.StopTimer()
-	const filename = "scanner.go"
-	src, err := os.ReadFile(filename)
-	if err != nil {
-		panic(err)
-	}
-	fset := token.NewFileSet()
-	file := fset.AddFile(filename, fset.Base(), len(src))
-	b.SetBytes(int64(len(src)))
-	var s Scanner
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		s.Init(file, src, nil, ScanComments)
-		for {
-			_, tok, _ := s.Scan()
-			if tok == token.EOF {
-				break
+func BenchmarkScanFiles(b *testing.B) {
+	// Scan a few arbitrary large files, and one small one, to provide some
+	// variety in benchmarks.
+	for _, p := range []string{
+		"go/types/expr.go",
+		"go/parser/parser.go",
+		"net/http/server.go",
+		"go/scanner/errors.go",
+	} {
+		b.Run(p, func(b *testing.B) {
+			b.StopTimer()
+			filename := filepath.Join("..", "..", filepath.FromSlash(p))
+			src, err := os.ReadFile(filename)
+			if err != nil {
+				b.Fatal(err)
 			}
-		}
+			fset := token.NewFileSet()
+			file := fset.AddFile(filename, fset.Base(), len(src))
+			b.SetBytes(int64(len(src)))
+			var s Scanner
+			b.StartTimer()
+			for i := 0; i < b.N; i++ {
+				s.Init(file, src, nil, ScanComments)
+				for {
+					_, tok, _ := s.Scan()
+					if tok == token.EOF {
+						break
+					}
+				}
+			}
+		})
 	}
 }
 
diff --git a/src/go/token/position.go b/src/go/token/position.go
index a21f5fd..0d7982c 100644
--- a/src/go/token/position.go
+++ b/src/go/token/position.go
@@ -278,7 +278,7 @@
 //
 func (f *File) Offset(p Pos) int {
 	if int(p) < f.base || int(p) > f.base+f.size {
-		panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d[)", p, f.base, f.base+f.size))
+		panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d])", p, f.base, f.base+f.size))
 	}
 	return int(p) - f.base
 }
@@ -346,7 +346,7 @@
 func (f *File) PositionFor(p Pos, adjusted bool) (pos Position) {
 	if p != NoPos {
 		if int(p) < f.base || int(p) > f.base+f.size {
-			panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d[)", p, f.base, f.base+f.size))
+			panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d])", p, f.base, f.base+f.size))
 		}
 		pos = f.position(p, adjusted)
 	}
@@ -540,7 +540,7 @@
 	// TODO(gri): Remove this when compilers have caught up.
 	i, j := 0, len(a)
 	for i < j {
-		h := i + (j-i)/2 // avoid overflow when computing h
+		h := i + (j-i)>>1 // avoid overflow when computing h
 		// i ≤ h < j
 		if a[h] <= x {
 			i = h + 1
diff --git a/src/go/token/position_bench_test.go b/src/go/token/position_bench_test.go
new file mode 100644
index 0000000..41be728
--- /dev/null
+++ b/src/go/token/position_bench_test.go
@@ -0,0 +1,24 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package token
+
+import (
+	"testing"
+)
+
+func BenchmarkSearchInts(b *testing.B) {
+	data := make([]int, 10000)
+	for i := 0; i < 10000; i++ {
+		data[i] = i
+	}
+	const x = 8
+	if r := searchInts(data, x); r != x {
+		b.Errorf("got index = %d; want %d", r, x)
+	}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		searchInts(data, x)
+	}
+}
diff --git a/src/go/types/api.go b/src/go/types/api.go
index d625959..8c0d9d2 100644
--- a/src/go/types/api.go
+++ b/src/go/types/api.go
@@ -101,6 +101,13 @@
 // A Config specifies the configuration for type checking.
 // The zero value for Config is a ready-to-use default configuration.
 type Config struct {
+	// goVersion describes the accepted Go language version. The string
+	// must follow the format "go%d.%d" (e.g. "go1.12") or it must be
+	// empty; an empty string indicates the latest language version.
+	// If the format is invalid, invoking the type checker will cause a
+	// panic.
+	goVersion string
+
 	// If IgnoreFuncBodies is set, function bodies are not
 	// type-checked.
 	IgnoreFuncBodies bool
@@ -153,95 +160,7 @@
 	conf.go115UsesCgo = true
 }
 
-// Info holds result type information for a type-checked package.
-// Only the information for which a map is provided is collected.
-// If the package has type errors, the collected information may
-// be incomplete.
-type Info struct {
-	// Types maps expressions to their types, and for constant
-	// expressions, also their values. Invalid expressions are
-	// omitted.
-	//
-	// For (possibly parenthesized) identifiers denoting built-in
-	// functions, the recorded signatures are call-site specific:
-	// if the call result is not a constant, the recorded type is
-	// an argument-specific signature. Otherwise, the recorded type
-	// is invalid.
-	//
-	// The Types map does not record the type of every identifier,
-	// only those that appear where an arbitrary expression is
-	// permitted. For instance, the identifier f in a selector
-	// expression x.f is found only in the Selections map, the
-	// identifier z in a variable declaration 'var z int' is found
-	// only in the Defs map, and identifiers denoting packages in
-	// qualified identifiers are collected in the Uses map.
-	Types map[ast.Expr]TypeAndValue
-
-	// Defs maps identifiers to the objects they define (including
-	// package names, dots "." of dot-imports, and blank "_" identifiers).
-	// For identifiers that do not denote objects (e.g., the package name
-	// in package clauses, or symbolic variables t in t := x.(type) of
-	// type switch headers), the corresponding objects are nil.
-	//
-	// For an embedded field, Defs returns the field *Var it defines.
-	//
-	// Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos()
-	Defs map[*ast.Ident]Object
-
-	// Uses maps identifiers to the objects they denote.
-	//
-	// For an embedded field, Uses returns the *TypeName it denotes.
-	//
-	// Invariant: Uses[id].Pos() != id.Pos()
-	Uses map[*ast.Ident]Object
-
-	// Implicits maps nodes to their implicitly declared objects, if any.
-	// The following node and object types may appear:
-	//
-	//     node               declared object
-	//
-	//     *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 (incl. unnamed results)
-	//
-	Implicits map[ast.Node]Object
-
-	// Selections maps selector expressions (excluding qualified identifiers)
-	// to their corresponding selections.
-	Selections map[*ast.SelectorExpr]*Selection
-
-	// Scopes maps ast.Nodes to the scopes they define. Package scopes are not
-	// associated with a specific node but with all files belonging to a package.
-	// Thus, the package scope can be found in the type-checked Package object.
-	// Scopes nest, with the Universe scope being the outermost scope, enclosing
-	// the package scope, which contains (one or more) files scopes, which enclose
-	// function scopes which in turn enclose statement and function literal scopes.
-	// Note that even though package-level functions are declared in the package
-	// scope, the function scopes are embedded in the file scope of the file
-	// containing the function declaration.
-	//
-	// 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
-	//
-	Scopes map[ast.Node]*Scope
-
-	// InitOrder is the list of package-level initializers in the order in which
-	// they must be executed. Initializers referring to variables related by an
-	// initialization dependency appear in topological order, the others appear
-	// in source order. Variables without an initialization expression do not
-	// appear in this list.
-	InitOrder []*Initializer
-}
+// The Info struct is found in api_notypeparams.go and api_typeparams.go.
 
 // TypeOf returns the type of expression e, or nil if not found.
 // Precondition: the Types, Uses and Defs maps are populated.
@@ -333,6 +252,13 @@
 	return tv.mode == commaok || tv.mode == mapindex
 }
 
+// _Inferred reports the _Inferred type arguments and signature
+// for a parameterized function call that uses type inference.
+type _Inferred struct {
+	Targs []Type
+	Sig   *Signature
+}
+
 // An Initializer describes a package-level variable, or a list of variables in case
 // of a multi-valued initialization expression, and the corresponding initialization
 // expression.
@@ -386,7 +312,7 @@
 // ConvertibleTo reports whether a value of type V is convertible to a value of type T.
 func ConvertibleTo(V, T Type) bool {
 	x := operand{mode: value, typ: V}
-	return x.convertibleTo(nil, T) // check not needed for non-constant x
+	return x.convertibleTo(nil, T, nil) // check not needed for non-constant x
 }
 
 // Implements reports whether type V implements interface T.
diff --git a/src/go/types/api_notypeparams.go b/src/go/types/api_notypeparams.go
new file mode 100644
index 0000000..9f7cb7e
--- /dev/null
+++ b/src/go/types/api_notypeparams.go
@@ -0,0 +1,104 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !typeparams
+// +build !typeparams
+
+package types
+
+import "go/ast"
+
+// Info holds result type information for a type-checked package.
+// Only the information for which a map is provided is collected.
+// If the package has type errors, the collected information may
+// be incomplete.
+type Info struct {
+	// Types maps expressions to their types, and for constant
+	// expressions, also their values. Invalid expressions are
+	// omitted.
+	//
+	// For (possibly parenthesized) identifiers denoting built-in
+	// functions, the recorded signatures are call-site specific:
+	// if the call result is not a constant, the recorded type is
+	// an argument-specific signature. Otherwise, the recorded type
+	// is invalid.
+	//
+	// The Types map does not record the type of every identifier,
+	// only those that appear where an arbitrary expression is
+	// permitted. For instance, the identifier f in a selector
+	// expression x.f is found only in the Selections map, the
+	// identifier z in a variable declaration 'var z int' is found
+	// only in the Defs map, and identifiers denoting packages in
+	// qualified identifiers are collected in the Uses map.
+	Types map[ast.Expr]TypeAndValue
+
+	// Defs maps identifiers to the objects they define (including
+	// package names, dots "." of dot-imports, and blank "_" identifiers).
+	// For identifiers that do not denote objects (e.g., the package name
+	// in package clauses, or symbolic variables t in t := x.(type) of
+	// type switch headers), the corresponding objects are nil.
+	//
+	// For an embedded field, Defs returns the field *Var it defines.
+	//
+	// Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos()
+	Defs map[*ast.Ident]Object
+
+	// Uses maps identifiers to the objects they denote.
+	//
+	// For an embedded field, Uses returns the *TypeName it denotes.
+	//
+	// Invariant: Uses[id].Pos() != id.Pos()
+	Uses map[*ast.Ident]Object
+
+	// Implicits maps nodes to their implicitly declared objects, if any.
+	// The following node and object types may appear:
+	//
+	//     node               declared object
+	//
+	//     *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 (incl. unnamed results)
+	//
+	Implicits map[ast.Node]Object
+
+	// Selections maps selector expressions (excluding qualified identifiers)
+	// to their corresponding selections.
+	Selections map[*ast.SelectorExpr]*Selection
+
+	// Scopes maps ast.Nodes to the scopes they define. Package scopes are not
+	// associated with a specific node but with all files belonging to a package.
+	// Thus, the package scope can be found in the type-checked Package object.
+	// Scopes nest, with the Universe scope being the outermost scope, enclosing
+	// the package scope, which contains (one or more) files scopes, which enclose
+	// function scopes which in turn enclose statement and function literal scopes.
+	// Note that even though package-level functions are declared in the package
+	// scope, the function scopes are embedded in the file scope of the file
+	// containing the function declaration.
+	//
+	// 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
+	//
+	Scopes map[ast.Node]*Scope
+
+	// InitOrder is the list of package-level initializers in the order in which
+	// they must be executed. Initializers referring to variables related by an
+	// initialization dependency appear in topological order, the others appear
+	// in source order. Variables without an initialization expression do not
+	// appear in this list.
+	InitOrder []*Initializer
+}
+
+func getInferred(info *Info) map[ast.Expr]_Inferred {
+	return nil
+}
diff --git a/src/go/types/api_test.go b/src/go/types/api_test.go
index 75cebc9..f964c65 100644
--- a/src/go/types/api_test.go
+++ b/src/go/types/api_test.go
@@ -9,6 +9,7 @@
 	"fmt"
 	"go/ast"
 	"go/importer"
+	"go/internal/typeparams"
 	"go/parser"
 	"go/token"
 	"internal/testenv"
@@ -20,9 +21,15 @@
 	. "go/types"
 )
 
+// pkgFor parses and type checks the package specified by path and source,
+// populating info if provided.
+//
+// If source begins with "package generic_" and type parameters are enabled,
+// generic code is permitted.
 func pkgFor(path, source string, info *Info) (*Package, error) {
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, path, source, 0)
+	mode := modeForSource(source)
+	f, err := parser.ParseFile(fset, path, source, mode)
 	if err != nil {
 		return nil, err
 	}
@@ -42,9 +49,21 @@
 	return pkg.Name()
 }
 
-func mayTypecheck(t *testing.T, path, source string, info *Info) string {
+// genericPkg is a prefix for packages that should be type checked with
+// generics.
+const genericPkg = "package generic_"
+
+func modeForSource(src string) parser.Mode {
+	if !strings.HasPrefix(src, genericPkg) {
+		return typeparams.DisallowParsing
+	}
+	return 0
+}
+
+func mayTypecheck(t *testing.T, path, source string, info *Info) (string, error) {
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, path, source, 0)
+	mode := modeForSource(source)
+	f, err := parser.ParseFile(fset, path, source, mode)
 	if f == nil { // ignore errors unless f is nil
 		t.Fatalf("%s: unable to parse: %s", path, err)
 	}
@@ -52,8 +71,8 @@
 		Error:    func(err error) {},
 		Importer: importer.Default(),
 	}
-	pkg, _ := conf.Check(f.Name.Name, fset, []*ast.File{f}, info)
-	return pkg.Name()
+	pkg, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, info)
+	return pkg.Name(), err
 }
 
 func TestValuesInfo(t *testing.T) {
@@ -175,6 +194,9 @@
 }
 
 func TestTypesInfo(t *testing.T) {
+	// Test sources that are not expected to typecheck must start with the broken prefix.
+	const broken = "package broken_"
+
 	var tests = []struct {
 		src  string
 		expr string // expression
@@ -187,6 +209,39 @@
 		{`package b3; var x interface{} = 0i`, `0i`, `complex128`},
 		{`package b4; var x interface{} = "foo"`, `"foo"`, `string`},
 
+		// uses of nil
+		{`package n0; var _ *int = nil`, `nil`, `untyped nil`},
+		{`package n1; var _ func() = nil`, `nil`, `untyped nil`},
+		{`package n2; var _ []byte = nil`, `nil`, `untyped nil`},
+		{`package n3; var _ map[int]int = nil`, `nil`, `untyped nil`},
+		{`package n4; var _ chan int = nil`, `nil`, `untyped nil`},
+		{`package n5; var _ interface{} = nil`, `nil`, `untyped nil`},
+		{`package n6; import "unsafe"; var _ unsafe.Pointer = nil`, `nil`, `untyped nil`},
+
+		{`package n10; var (x *int; _ = x == nil)`, `nil`, `untyped nil`},
+		{`package n11; var (x func(); _ = x == nil)`, `nil`, `untyped nil`},
+		{`package n12; var (x []byte; _ = x == nil)`, `nil`, `untyped nil`},
+		{`package n13; var (x map[int]int; _ = x == nil)`, `nil`, `untyped nil`},
+		{`package n14; var (x chan int; _ = x == nil)`, `nil`, `untyped nil`},
+		{`package n15; var (x interface{}; _ = x == nil)`, `nil`, `untyped nil`},
+		{`package n15; import "unsafe"; var (x unsafe.Pointer; _ = x == nil)`, `nil`, `untyped nil`},
+
+		{`package n20; var _ = (*int)(nil)`, `nil`, `untyped nil`},
+		{`package n21; var _ = (func())(nil)`, `nil`, `untyped nil`},
+		{`package n22; var _ = ([]byte)(nil)`, `nil`, `untyped nil`},
+		{`package n23; var _ = (map[int]int)(nil)`, `nil`, `untyped nil`},
+		{`package n24; var _ = (chan int)(nil)`, `nil`, `untyped nil`},
+		{`package n25; var _ = (interface{})(nil)`, `nil`, `untyped nil`},
+		{`package n26; import "unsafe"; var _ = unsafe.Pointer(nil)`, `nil`, `untyped nil`},
+
+		{`package n30; func f(*int) { f(nil) }`, `nil`, `untyped nil`},
+		{`package n31; func f(func()) { f(nil) }`, `nil`, `untyped nil`},
+		{`package n32; func f([]byte) { f(nil) }`, `nil`, `untyped nil`},
+		{`package n33; func f(map[int]int) { f(nil) }`, `nil`, `untyped nil`},
+		{`package n34; func f(chan int) { f(nil) }`, `nil`, `untyped nil`},
+		{`package n35; func f(interface{}) { f(nil) }`, `nil`, `untyped nil`},
+		{`package n35; import "unsafe"; func f(unsafe.Pointer) { f(nil) }`, `nil`, `untyped nil`},
+
 		// comma-ok expressions
 		{`package p0; var x interface{}; var _, _ = x.(int)`,
 			`x.(int)`,
@@ -267,18 +322,65 @@
 			`[][]struct{}`,
 		},
 
+		// issue 47243
+		{`package issue47243_a; var x int32; var _ = x << 3`, `3`, `untyped int`},
+		{`package issue47243_b; var x int32; var _ = x << 3.`, `3.`, `uint`}, // issue 47410: should be untyped float
+		{`package issue47243_c; var x int32; var _ = 1 << x`, `1 << x`, `int`},
+		{`package issue47243_d; var x int32; var _ = 1 << x`, `1`, `int`},
+		{`package issue47243_e; var x int32; var _ = 1 << 2`, `1`, `untyped int`},
+		{`package issue47243_f; var x int32; var _ = 1 << 2`, `2`, `untyped int`},
+		{`package issue47243_g; var x int32; var _ = int(1) << 2`, `2`, `untyped int`},
+		{`package issue47243_h; var x int32; var _ = 1 << (2 << x)`, `1`, `int`},
+		{`package issue47243_i; var x int32; var _ = 1 << (2 << x)`, `(2 << x)`, `untyped int`},
+		{`package issue47243_j; var x int32; var _ = 1 << (2 << x)`, `2`, `untyped int`},
+
 		// tests for broken code that doesn't parse or type-check
-		{`package x0; func _() { var x struct {f string}; x.f := 0 }`, `x.f`, `string`},
-		{`package x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}`, `z`, `string`},
-		{`package x2; func _() { var a, b string; type x struct {f string}; z := &x{f: a; f: b;}}`, `b`, `string`},
-		{`package x3; var x = panic("");`, `panic`, `func(interface{})`},
+		{broken + `x0; func _() { var x struct {f string}; x.f := 0 }`, `x.f`, `string`},
+		{broken + `x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}`, `z`, `string`},
+		{broken + `x2; func _() { var a, b string; type x struct {f string}; z := &x{f: a; f: b;}}`, `b`, `string`},
+		{broken + `x3; var x = panic("");`, `panic`, `func(interface{})`},
 		{`package x4; func _() { panic("") }`, `panic`, `func(interface{})`},
-		{`package x5; func _() { var x map[string][...]int; x = map[string][...]int{"": {1,2,3}} }`, `x`, `map[string][-1]int`},
+		{broken + `x5; func _() { var x map[string][...]int; x = map[string][...]int{"": {1,2,3}} }`, `x`, `map[string][-1]int`},
+
+		// parameterized functions
+		{genericPkg + `p0; func f[T any](T); var _ = f[int]`, `f`, `func[T₁ interface{}](T₁)`},
+		{genericPkg + `p1; func f[T any](T); var _ = f[int]`, `f[int]`, `func(int)`},
+		{genericPkg + `p2; func f[T any](T); func _() { f(42) }`, `f`, `func[T₁ interface{}](T₁)`},
+		{genericPkg + `p3; func f[T any](T); func _() { f(42) }`, `f(42)`, `()`},
+
+		// type parameters
+		{genericPkg + `t0; type t[] int; var _ t`, `t`, `generic_t0.t`}, // t[] is a syntax error that is ignored in this test in favor of t
+		{genericPkg + `t1; type t[P any] int; var _ t[int]`, `t`, `generic_t1.t[P₁ interface{}]`},
+		{genericPkg + `t2; type t[P interface{}] int; var _ t[int]`, `t`, `generic_t2.t[P₁ interface{}]`},
+		{genericPkg + `t3; type t[P, Q interface{}] int; var _ t[int, int]`, `t`, `generic_t3.t[P₁, Q₂ interface{}]`},
+
+		// TODO (rFindley): compare with types2, which resolves the type broken_t4.t[P₁, Q₂ interface{m()}] here
+		{broken + `t4; type t[P, Q interface{ m() }] int; var _ t[int, int]`, `t`, `broken_t4.t`},
+
+		// instantiated types must be sanitized
+		{genericPkg + `g0; type t[P any] int; var x struct{ f t[int] }; var _ = x.f`, `x.f`, `generic_g0.t[int]`},
+
+		// issue 45096
+		{genericPkg + `issue45096; func _[T interface{ type int8, int16, int32  }](x T) { _ = x < 0 }`, `0`, `T₁`},
 	}
 
 	for _, test := range tests {
+		ResetId() // avoid renumbering of type parameter ids when adding tests
+		if strings.HasPrefix(test.src, genericPkg) && !typeparams.Enabled {
+			continue
+		}
 		info := Info{Types: make(map[ast.Expr]TypeAndValue)}
-		name := mayTypecheck(t, "TypesInfo", test.src, &info)
+		var name string
+		if strings.HasPrefix(test.src, broken) {
+			var err error
+			name, err = mayTypecheck(t, "TypesInfo", test.src, &info)
+			if err == nil {
+				t.Errorf("package %s: expected to fail but passed", name)
+				continue
+			}
+		} else {
+			name = mustTypecheck(t, "TypesInfo", test.src, &info)
+		}
 
 		// look for expression type
 		var typ Type
@@ -300,6 +402,103 @@
 	}
 }
 
+func TestDefsInfo(t *testing.T) {
+	var tests = []struct {
+		src  string
+		obj  string
+		want string
+	}{
+		{`package p0; const x = 42`, `x`, `const p0.x untyped int`},
+		{`package p1; const x int = 42`, `x`, `const p1.x int`},
+		{`package p2; var x int`, `x`, `var p2.x int`},
+		{`package p3; type x int`, `x`, `type p3.x int`},
+		{`package p4; func f()`, `f`, `func p4.f()`},
+		{`package p5; func f() int { x, _ := 1, 2; return x }`, `_`, `var _ int`},
+
+		// generic types must be sanitized
+		// (need to use sufficiently nested types to provoke unexpanded types)
+		{genericPkg + `g0; type t[P any] P; const x = t[int](42)`, `x`, `const generic_g0.x generic_g0.t[int]`},
+		{genericPkg + `g1; type t[P any] P; var x = t[int](42)`, `x`, `var generic_g1.x generic_g1.t[int]`},
+		{genericPkg + `g2; type t[P any] P; type x struct{ f t[int] }`, `x`, `type generic_g2.x struct{f generic_g2.t[int]}`},
+		{genericPkg + `g3; type t[P any] P; func f(x struct{ f t[string] }); var g = f`, `g`, `var generic_g3.g func(x struct{f generic_g3.t[string]})`},
+	}
+
+	for _, test := range tests {
+		if strings.HasPrefix(test.src, genericPkg) && !typeparams.Enabled {
+			continue
+		}
+		info := Info{
+			Defs: make(map[*ast.Ident]Object),
+		}
+		name := mustTypecheck(t, "DefsInfo", test.src, &info)
+
+		// find object
+		var def Object
+		for id, obj := range info.Defs {
+			if id.Name == test.obj {
+				def = obj
+				break
+			}
+		}
+		if def == nil {
+			t.Errorf("package %s: %s not found", name, test.obj)
+			continue
+		}
+
+		if got := def.String(); got != test.want {
+			t.Errorf("package %s: got %s; want %s", name, got, test.want)
+		}
+	}
+}
+
+func TestUsesInfo(t *testing.T) {
+	var tests = []struct {
+		src  string
+		obj  string
+		want string
+	}{
+		{`package p0; func _() { _ = x }; const x = 42`, `x`, `const p0.x untyped int`},
+		{`package p1; func _() { _ = x }; const x int = 42`, `x`, `const p1.x int`},
+		{`package p2; func _() { _ = x }; var x int`, `x`, `var p2.x int`},
+		{`package p3; func _() { type _ x }; type x int`, `x`, `type p3.x int`},
+		{`package p4; func _() { _ = f }; func f()`, `f`, `func p4.f()`},
+
+		// generic types must be sanitized
+		// (need to use sufficiently nested types to provoke unexpanded types)
+		{genericPkg + `g0; func _() { _ = x }; type t[P any] P; const x = t[int](42)`, `x`, `const generic_g0.x generic_g0.t[int]`},
+		{genericPkg + `g1; func _() { _ = x }; type t[P any] P; var x = t[int](42)`, `x`, `var generic_g1.x generic_g1.t[int]`},
+		{genericPkg + `g2; func _() { type _ x }; type t[P any] P; type x struct{ f t[int] }`, `x`, `type generic_g2.x struct{f generic_g2.t[int]}`},
+		{genericPkg + `g3; func _() { _ = f }; type t[P any] P; func f(x struct{ f t[string] })`, `f`, `func generic_g3.f(x struct{f generic_g3.t[string]})`},
+	}
+
+	for _, test := range tests {
+		if strings.HasPrefix(test.src, genericPkg) && !typeparams.Enabled {
+			continue
+		}
+		info := Info{
+			Uses: make(map[*ast.Ident]Object),
+		}
+		name := mustTypecheck(t, "UsesInfo", test.src, &info)
+
+		// find object
+		var use Object
+		for id, obj := range info.Uses {
+			if id.Name == test.obj {
+				use = obj
+				break
+			}
+		}
+		if use == nil {
+			t.Errorf("package %s: %s not found", name, test.obj)
+			continue
+		}
+
+		if got := use.String(); got != test.want {
+			t.Errorf("package %s: got %s; want %s", name, got, test.want)
+		}
+	}
+}
+
 func TestImplicitsInfo(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
 
@@ -1033,6 +1232,8 @@
 	// Test cases assume a lookup of the form a.f or x.f, where a stands for an
 	// addressable value, and x for a non-addressable value (even though a variable
 	// for ease of test case writing).
+	//
+	// Should be kept in sync with TestMethodSet.
 	var tests = []struct {
 		src      string
 		found    bool
@@ -1243,6 +1444,9 @@
 		{newDefined(new(Struct)), new(Struct), true},
 		{newDefined(Typ[Int]), new(Struct), false},
 		{Typ[UntypedInt], Typ[Int], true},
+		{NewSlice(Typ[Int]), NewPointer(NewArray(Typ[Int], 10)), true},
+		{NewSlice(Typ[Int]), NewArray(Typ[Int], 10), false},
+		{NewSlice(Typ[Int]), NewPointer(NewArray(Typ[Uint], 10)), false},
 		// Untyped string values are not permitted by the spec, so the below
 		// behavior is undefined.
 		{Typ[UntypedString], Typ[String], true},
diff --git a/src/go/types/api_typeparams.go b/src/go/types/api_typeparams.go
new file mode 100644
index 0000000..ed744c4
--- /dev/null
+++ b/src/go/types/api_typeparams.go
@@ -0,0 +1,53 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build typeparams
+// +build typeparams
+
+package types
+
+import (
+	"go/ast"
+)
+
+type (
+	Inferred  = _Inferred
+	Sum       = _Sum
+	TypeParam = _TypeParam
+)
+
+func NewSum(types []Type) Type { return _NewSum(types) }
+
+func (s *Signature) TParams() []*TypeName           { return s._TParams() }
+func (s *Signature) SetTParams(tparams []*TypeName) { s._SetTParams(tparams) }
+
+func (t *Interface) HasTypeList() bool  { return t._HasTypeList() }
+func (t *Interface) IsComparable() bool { return t._IsComparable() }
+func (t *Interface) IsConstraint() bool { return t._IsConstraint() }
+
+func (t *Named) TParams() []*TypeName { return t._TParams() }
+func (t *Named) TArgs() []Type        { return t._TArgs() }
+func (t *Named) SetTArgs(args []Type) { t._SetTArgs(args) }
+
+// Info is documented in api_notypeparams.go.
+type Info struct {
+	Types map[ast.Expr]TypeAndValue
+
+	// Inferred maps calls of parameterized functions that use type inference to
+	// the Inferred type arguments and signature of the function called. The
+	// recorded "call" expression may be an *ast.CallExpr (as in f(x)), or an
+	// *ast.IndexExpr (s in f[T]).
+	Inferred map[ast.Expr]_Inferred
+
+	Defs       map[*ast.Ident]Object
+	Uses       map[*ast.Ident]Object
+	Implicits  map[ast.Node]Object
+	Selections map[*ast.SelectorExpr]*Selection
+	Scopes     map[ast.Node]*Scope
+	InitOrder  []*Initializer
+}
+
+func getInferred(info *Info) map[ast.Expr]_Inferred {
+	return info.Inferred
+}
diff --git a/src/go/types/api_typeparams_test.go b/src/go/types/api_typeparams_test.go
new file mode 100644
index 0000000..15c9bf0
--- /dev/null
+++ b/src/go/types/api_typeparams_test.go
@@ -0,0 +1,139 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build typeparams
+// +build typeparams
+
+package types_test
+
+import (
+	"fmt"
+	"go/ast"
+	"testing"
+
+	. "go/types"
+)
+
+func TestInferredInfo(t *testing.T) {
+	var tests = []struct {
+		src   string
+		fun   string
+		targs []string
+		sig   string
+	}{
+		{genericPkg + `p0; func f[T any](T); func _() { f(42) }`,
+			`f`,
+			[]string{`int`},
+			`func(int)`,
+		},
+		{genericPkg + `p1; func f[T any](T) T; func _() { f('@') }`,
+			`f`,
+			[]string{`rune`},
+			`func(rune) rune`,
+		},
+		{genericPkg + `p2; func f[T any](...T) T; func _() { f(0i) }`,
+			`f`,
+			[]string{`complex128`},
+			`func(...complex128) complex128`,
+		},
+		{genericPkg + `p3; func f[A, B, C any](A, *B, []C); func _() { f(1.2, new(string), []byte{}) }`,
+			`f`,
+			[]string{`float64`, `string`, `byte`},
+			`func(float64, *string, []byte)`,
+		},
+		{genericPkg + `p4; func f[A, B any](A, *B, ...[]B); func _() { f(1.2, new(byte)) }`,
+			`f`,
+			[]string{`float64`, `byte`},
+			`func(float64, *byte, ...[]byte)`,
+		},
+
+		{genericPkg + `s1; func f[T any, P interface{type *T}](x T); func _(x string) { f(x) }`,
+			`f`,
+			[]string{`string`, `*string`},
+			`func(x string)`,
+		},
+		{genericPkg + `s2; func f[T any, P interface{type *T}](x []T); func _(x []int) { f(x) }`,
+			`f`,
+			[]string{`int`, `*int`},
+			`func(x []int)`,
+		},
+		{genericPkg + `s3; type C[T any] interface{type chan<- T}; func f[T any, P C[T]](x []T); func _(x []int) { f(x) }`,
+			`f`,
+			[]string{`int`, `chan<- int`},
+			`func(x []int)`,
+		},
+		{genericPkg + `s4; type C[T any] interface{type chan<- T}; func f[T any, P C[T], Q C[[]*P]](x []T); func _(x []int) { f(x) }`,
+			`f`,
+			[]string{`int`, `chan<- int`, `chan<- []*chan<- int`},
+			`func(x []int)`,
+		},
+
+		{genericPkg + `t1; func f[T any, P interface{type *T}]() T; func _() { _ = f[string] }`,
+			`f`,
+			[]string{`string`, `*string`},
+			`func() string`,
+		},
+		{genericPkg + `t2; type C[T any] interface{type chan<- T}; func f[T any, P C[T]]() []T; func _() { _ = f[int] }`,
+			`f`,
+			[]string{`int`, `chan<- int`},
+			`func() []int`,
+		},
+		{genericPkg + `t3; type C[T any] interface{type chan<- T}; func f[T any, P C[T], Q C[[]*P]]() []T; func _() { _ = f[int] }`,
+			`f`,
+			[]string{`int`, `chan<- int`, `chan<- []*chan<- int`},
+			`func() []int`,
+		},
+	}
+
+	for _, test := range tests {
+		info := Info{}
+		info.Inferred = make(map[ast.Expr]Inferred)
+		name, err := mayTypecheck(t, "InferredInfo", test.src, &info)
+		if err != nil {
+			t.Errorf("package %s: %v", name, err)
+			continue
+		}
+
+		// look for inferred type arguments and signature
+		var targs []Type
+		var sig *Signature
+		for call, inf := range info.Inferred {
+			var fun ast.Expr
+			switch x := call.(type) {
+			case *ast.CallExpr:
+				fun = x.Fun
+			case *ast.IndexExpr:
+				fun = x.X
+			default:
+				panic(fmt.Sprintf("unexpected call expression type %T", call))
+			}
+			if ExprString(fun) == test.fun {
+				targs = inf.Targs
+				sig = inf.Sig
+				break
+			}
+		}
+		if targs == nil {
+			t.Errorf("package %s: no inferred information found for %s", name, test.fun)
+			continue
+		}
+
+		// check that type arguments are correct
+		if len(targs) != len(test.targs) {
+			t.Errorf("package %s: got %d type arguments; want %d", name, len(targs), len(test.targs))
+			continue
+		}
+		for i, targ := range targs {
+			if got := targ.String(); got != test.targs[i] {
+				t.Errorf("package %s, %d. type argument: got %s; want %s", name, i, got, test.targs[i])
+				continue
+			}
+		}
+
+		// check that signature is correct
+		if got := sig.String(); got != test.sig {
+			t.Errorf("package %s: got %s; want %s", name, got, test.sig)
+		}
+	}
+}
diff --git a/src/go/types/assignments.go b/src/go/types/assignments.go
index 616564b..18eae62 100644
--- a/src/go/types/assignments.go
+++ b/src/go/types/assignments.go
@@ -7,7 +7,6 @@
 package types
 
 import (
-	"errors"
 	"go/ast"
 	"go/token"
 )
@@ -26,7 +25,9 @@
 	case constant_, variable, mapindex, value, commaok, commaerr:
 		// ok
 	default:
-		unreachable()
+		// we may get here because of other problems (issue #39634, crash 12)
+		check.errorf(x, 0, "cannot assign %s to %s in %s", x, T, context)
+		return
 	}
 
 	if isUntyped(x.typ) {
@@ -44,27 +45,35 @@
 			}
 			target = Default(x.typ)
 		}
-		if err := check.canConvertUntyped(x, target); err != nil {
+		newType, val, code := check.implicitTypeAndValue(x, target)
+		if code != 0 {
 			msg := check.sprintf("cannot use %s as %s value in %s", x, target, context)
-			code := _IncompatibleAssign
-			var ierr Error
-			if errors.As(err, &ierr) {
-				// Preserve these inner errors, as they are informative.
-				switch ierr.go116code {
-				case _TruncatedFloat:
-					msg += " (truncated)"
-					code = ierr.go116code
-				case _NumericOverflow:
-					msg += " (overflows)"
-					code = ierr.go116code
-				}
+			switch code {
+			case _TruncatedFloat:
+				msg += " (truncated)"
+			case _NumericOverflow:
+				msg += " (overflows)"
+			default:
+				code = _IncompatibleAssign
 			}
 			check.error(x, code, msg)
 			x.mode = invalid
 			return
 		}
+		if val != nil {
+			x.val = val
+			check.updateExprVal(x.expr, val)
+		}
+		if newType != x.typ {
+			x.typ = newType
+			check.updateExprType(x.expr, newType, false)
+		}
 	}
-	// x.typ is typed
+
+	// A generic (non-instantiated) function value cannot be assigned to a variable.
+	if sig := asSignature(x.typ); sig != nil && len(sig.tparams) > 0 {
+		check.errorf(x, _Todo, "cannot use generic function %s without instantiation in %s", x, context)
+	}
 
 	// spec: "If a left-hand side is the blank identifier, any typed or
 	// non-constant value except for the predeclared identifier nil may
@@ -148,6 +157,7 @@
 
 func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type {
 	if x.mode == invalid || x.typ == Typ[Invalid] {
+		check.useLHS(lhs)
 		return nil
 	}
 
@@ -221,25 +231,27 @@
 
 // If returnPos is valid, initVars is called to type-check the assignment of
 // return expressions, and returnPos is the position of the return statement.
-func (check *Checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos) {
-	l := len(lhs)
-	get, r, commaOk := unpack(func(x *operand, i int) { check.multiExpr(x, rhs[i]) }, len(rhs), l == 2 && !returnPos.IsValid())
-	if get == nil || l != r {
-		// invalidate lhs and use rhs
+func (check *Checker) initVars(lhs []*Var, origRHS []ast.Expr, returnPos token.Pos) {
+	rhs, commaOk := check.exprList(origRHS, len(lhs) == 2 && !returnPos.IsValid())
+
+	if len(lhs) != len(rhs) {
+		// invalidate lhs
 		for _, obj := range lhs {
 			if obj.typ == nil {
 				obj.typ = Typ[Invalid]
 			}
 		}
-		if get == nil {
-			return // error reported by unpack
+		// don't report an error if we already reported one
+		for _, x := range rhs {
+			if x.mode == invalid {
+				return
+			}
 		}
-		check.useGetter(get, r)
 		if returnPos.IsValid() {
-			check.errorf(atPos(returnPos), _WrongResultCount, "wrong number of return values (want %d, got %d)", l, r)
+			check.errorf(atPos(returnPos), _WrongResultCount, "wrong number of return values (want %d, got %d)", len(lhs), len(rhs))
 			return
 		}
-		check.errorf(rhs[0], _WrongAssignCount, "cannot initialize %d variables with %d values", l, r)
+		check.errorf(rhs[0], _WrongAssignCount, "cannot initialize %d variables with %d values", len(lhs), len(rhs))
 		return
 	}
 
@@ -248,50 +260,46 @@
 		context = "return statement"
 	}
 
-	var x operand
 	if commaOk {
 		var a [2]Type
 		for i := range a {
-			get(&x, i)
-			a[i] = check.initVar(lhs[i], &x, context)
+			a[i] = check.initVar(lhs[i], rhs[i], context)
 		}
-		check.recordCommaOkTypes(rhs[0], a)
+		check.recordCommaOkTypes(origRHS[0], a)
 		return
 	}
 
 	for i, lhs := range lhs {
-		get(&x, i)
-		check.initVar(lhs, &x, context)
+		check.initVar(lhs, rhs[i], context)
 	}
 }
 
-func (check *Checker) assignVars(lhs, rhs []ast.Expr) {
-	l := len(lhs)
-	get, r, commaOk := unpack(func(x *operand, i int) { check.multiExpr(x, rhs[i]) }, len(rhs), l == 2)
-	if get == nil {
+func (check *Checker) assignVars(lhs, origRHS []ast.Expr) {
+	rhs, commaOk := check.exprList(origRHS, len(lhs) == 2)
+
+	if len(lhs) != len(rhs) {
 		check.useLHS(lhs...)
-		return // error reported by unpack
-	}
-	if l != r {
-		check.useGetter(get, r)
-		check.errorf(rhs[0], _WrongAssignCount, "cannot assign %d values to %d variables", r, l)
+		// don't report an error if we already reported one
+		for _, x := range rhs {
+			if x.mode == invalid {
+				return
+			}
+		}
+		check.errorf(rhs[0], _WrongAssignCount, "cannot assign %d values to %d variables", len(rhs), len(lhs))
 		return
 	}
 
-	var x operand
 	if commaOk {
 		var a [2]Type
 		for i := range a {
-			get(&x, i)
-			a[i] = check.assignVar(lhs[i], &x)
+			a[i] = check.assignVar(lhs[i], rhs[i])
 		}
-		check.recordCommaOkTypes(rhs[0], a)
+		check.recordCommaOkTypes(origRHS[0], a)
 		return
 	}
 
 	for i, lhs := range lhs {
-		get(&x, i)
-		check.assignVar(lhs, &x)
+		check.assignVar(lhs, rhs[i])
 	}
 }
 
@@ -300,40 +308,60 @@
 	scope := check.scope
 
 	// collect lhs variables
-	var newVars []*Var
-	var lhsVars = make([]*Var, len(lhs))
+	seen := make(map[string]bool, len(lhs))
+	lhsVars := make([]*Var, len(lhs))
+	newVars := make([]*Var, 0, len(lhs))
+	hasErr := false
 	for i, lhs := range lhs {
-		var obj *Var
-		if ident, _ := lhs.(*ast.Ident); ident != nil {
-			// Use the correct obj if the ident is redeclared. The
-			// variable's scope starts after the declaration; so we
-			// must use Scope.Lookup here and call Scope.Insert
-			// (via check.declare) later.
-			name := ident.Name
-			if alt := scope.Lookup(name); alt != nil {
-				// redeclared object must be a variable
-				if alt, _ := alt.(*Var); alt != nil {
-					obj = alt
-				} else {
-					check.errorf(lhs, _UnassignableOperand, "cannot assign to %s", lhs)
-				}
-				check.recordUse(ident, alt)
-			} else {
-				// declare new variable, possibly a blank (_) variable
-				obj = NewVar(ident.Pos(), check.pkg, name, nil)
-				if name != "_" {
-					newVars = append(newVars, obj)
-				}
-				check.recordDef(ident, obj)
-			}
-		} else {
+		ident, _ := lhs.(*ast.Ident)
+		if ident == nil {
 			check.useLHS(lhs)
-			check.invalidAST(lhs, "cannot declare %s", lhs)
+			// TODO(rFindley) this is redundant with a parser error. Consider omitting?
+			check.errorf(lhs, _BadDecl, "non-name %s on left side of :=", lhs)
+			hasErr = true
+			continue
 		}
-		if obj == nil {
-			obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
+
+		name := ident.Name
+		if name != "_" {
+			if seen[name] {
+				check.errorf(lhs, _RepeatedDecl, "%s repeated on left side of :=", lhs)
+				hasErr = true
+				continue
+			}
+			seen[name] = true
 		}
+
+		// Use the correct obj if the ident is redeclared. The
+		// variable's scope starts after the declaration; so we
+		// must use Scope.Lookup here and call Scope.Insert
+		// (via check.declare) later.
+		if alt := scope.Lookup(name); alt != nil {
+			check.recordUse(ident, alt)
+			// redeclared object must be a variable
+			if obj, _ := alt.(*Var); obj != nil {
+				lhsVars[i] = obj
+			} else {
+				check.errorf(lhs, _UnassignableOperand, "cannot assign to %s", lhs)
+				hasErr = true
+			}
+			continue
+		}
+
+		// declare new variable
+		obj := NewVar(ident.Pos(), check.pkg, name, nil)
 		lhsVars[i] = obj
+		if name != "_" {
+			newVars = append(newVars, obj)
+		}
+		check.recordDef(ident, obj)
+	}
+
+	// create dummy variables where the lhs is invalid
+	for i, obj := range lhsVars {
+		if obj == nil {
+			lhsVars[i] = NewVar(lhs[i].Pos(), check.pkg, "_", nil)
+		}
 	}
 
 	check.initVars(lhsVars, rhs, token.NoPos)
@@ -341,17 +369,18 @@
 	// process function literals in rhs expressions before scope changes
 	check.processDelayed(top)
 
-	// declare new variables
-	if len(newVars) > 0 {
-		// spec: "The scope of a constant or variable identifier declared inside
-		// a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
-		// for short variable declarations) and ends at the end of the innermost
-		// containing block."
-		scopePos := rhs[len(rhs)-1].End()
-		for _, obj := range newVars {
-			check.declare(scope, nil, obj, scopePos) // recordObject already called
-		}
-	} else {
+	if len(newVars) == 0 && !hasErr {
 		check.softErrorf(pos, _NoNewVar, "no new variables on left side of :=")
+		return
+	}
+
+	// declare new variables
+	// spec: "The scope of a constant or variable identifier declared inside
+	// a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
+	// for short variable declarations) and ends at the end of the innermost
+	// containing block."
+	scopePos := rhs[len(rhs)-1].End()
+	for _, obj := range newVars {
+		check.declare(scope, nil, obj, scopePos) // id = nil: recordDef already called
 	}
 }
diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go
index fd35f78..2a2d54d 100644
--- a/src/go/types/builtins.go
+++ b/src/go/types/builtins.go
@@ -31,8 +31,8 @@
 	// For len(x) and cap(x) we need to know if x contains any function calls or
 	// receive operations. Save/restore current setting and set hasCallOrRecv to
 	// false for the evaluation of x so that we can check it afterwards.
-	// Note: We must do this _before_ calling unpack because unpack evaluates the
-	//       first argument before we even call arg(x, 0)!
+	// Note: We must do this _before_ calling exprList because exprList evaluates
+	//       all arguments.
 	if id == _Len || id == _Cap {
 		defer func(b bool) {
 			check.hasCallOrRecv = b
@@ -41,15 +41,14 @@
 	}
 
 	// determine actual arguments
-	var arg getter
+	var arg func(*operand, int) // TODO(gri) remove use of arg getter in favor of using xlist directly
 	nargs := len(call.Args)
 	switch id {
 	default:
 		// make argument getter
-		arg, nargs, _ = unpack(func(x *operand, i int) { check.multiExpr(x, call.Args[i]) }, nargs, false)
-		if arg == nil {
-			return
-		}
+		xlist, _ := check.exprList(call.Args, false)
+		arg = func(x *operand, i int) { *x = *xlist[i]; x.typ = expand(x.typ) }
+		nargs = len(xlist)
 		// evaluate first argument, if present
 		if nargs > 0 {
 			arg(x, 0)
@@ -84,7 +83,7 @@
 		// of S and the respective parameter passing rules apply."
 		S := x.typ
 		var T Type
-		if s, _ := S.Underlying().(*Slice); s != nil {
+		if s := asSlice(S); s != nil {
 			T = s.elem
 		} else {
 			check.invalidArg(x, _InvalidAppend, "%s is not a slice", x)
@@ -121,14 +120,17 @@
 		// check general case by creating custom signature
 		sig := makeSig(S, S, NewSlice(T)) // []T required for variadic signature
 		sig.variadic = true
-		check.arguments(x, call, sig, func(x *operand, i int) {
-			// only evaluate arguments that have not been evaluated before
-			if i < len(alist) {
-				*x = alist[i]
-				return
-			}
-			arg(x, i)
-		}, nargs)
+		var xlist []*operand
+		// convert []operand to []*operand
+		for i := range alist {
+			xlist = append(xlist, &alist[i])
+		}
+		for i := len(alist); i < nargs; i++ {
+			var x operand
+			arg(&x, i)
+			xlist = append(xlist, &x)
+		}
+		check.arguments(call, sig, nil, xlist) // discard result (we know the result type)
 		// ok to continue even if check.arguments reported errors
 
 		x.mode = value
@@ -143,7 +145,7 @@
 		mode := invalid
 		var typ Type
 		var val constant.Value
-		switch typ = implicitArrayDeref(x.typ.Underlying()); t := typ.(type) {
+		switch typ = implicitArrayDeref(optype(x.typ)); t := typ.(type) {
 		case *Basic:
 			if isString(t) && id == _Len {
 				if x.mode == constant_ {
@@ -176,6 +178,25 @@
 			if id == _Len {
 				mode = value
 			}
+
+		case *_Sum:
+			if t.is(func(t Type) bool {
+				switch t := under(t).(type) {
+				case *Basic:
+					if isString(t) && id == _Len {
+						return true
+					}
+				case *Array, *Slice, *Chan:
+					return true
+				case *Map:
+					if id == _Len {
+						return true
+					}
+				}
+				return false
+			}) {
+				mode = value
+			}
 		}
 
 		if mode == invalid && typ != Typ[Invalid] {
@@ -196,7 +217,7 @@
 
 	case _Close:
 		// close(c)
-		c, _ := x.typ.Underlying().(*Chan)
+		c := asChan(x.typ)
 		if c == nil {
 			check.invalidArg(x, _InvalidClose, "%s is not a channel", x)
 			return
@@ -271,7 +292,21 @@
 		}
 
 		// the argument types must be of floating-point type
-		if !isFloat(x.typ) {
+		f := func(x Type) Type {
+			if t := asBasic(x); t != nil {
+				switch t.kind {
+				case Float32:
+					return Typ[Complex64]
+				case Float64:
+					return Typ[Complex128]
+				case UntypedFloat:
+					return Typ[UntypedComplex]
+				}
+			}
+			return nil
+		}
+		resTyp := check.applyTypeFunc(f, x.typ)
+		if resTyp == nil {
 			check.invalidArg(x, _InvalidComplex, "arguments have type %s, expected floating-point", x.typ)
 			return
 		}
@@ -283,20 +318,6 @@
 			x.mode = value
 		}
 
-		// determine result type
-		var res BasicKind
-		switch x.typ.Underlying().(*Basic).kind {
-		case Float32:
-			res = Complex64
-		case Float64:
-			res = Complex128
-		case UntypedFloat:
-			res = UntypedComplex
-		default:
-			unreachable()
-		}
-		resTyp := Typ[res]
-
 		if check.Types != nil && x.mode != constant_ {
 			check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
 		}
@@ -306,7 +327,7 @@
 	case _Copy:
 		// copy(x, y []T) int
 		var dst Type
-		if t, _ := x.typ.Underlying().(*Slice); t != nil {
+		if t := asSlice(x.typ); t != nil {
 			dst = t.elem
 		}
 
@@ -316,7 +337,7 @@
 			return
 		}
 		var src Type
-		switch t := y.typ.Underlying().(type) {
+		switch t := optype(y.typ).(type) {
 		case *Basic:
 			if isString(y.typ) {
 				src = universeByte
@@ -343,7 +364,7 @@
 
 	case _Delete:
 		// delete(m, k)
-		m, _ := x.typ.Underlying().(*Map)
+		m := asMap(x.typ)
 		if m == nil {
 			check.invalidArg(x, _InvalidDelete, "%s is not a map", x)
 			return
@@ -353,8 +374,8 @@
 			return
 		}
 
-		if ok, code := x.assignableTo(check, m.key, nil); !ok {
-			check.invalidArg(x, code, "%s is not assignable to %s", x, m.key)
+		check.assignment(x, m.key, "argument to delete")
+		if x.mode == invalid {
 			return
 		}
 
@@ -389,7 +410,21 @@
 		}
 
 		// the argument must be of complex type
-		if !isComplex(x.typ) {
+		f := func(x Type) Type {
+			if t := asBasic(x); t != nil {
+				switch t.kind {
+				case Complex64:
+					return Typ[Float32]
+				case Complex128:
+					return Typ[Float64]
+				case UntypedComplex:
+					return Typ[UntypedFloat]
+				}
+			}
+			return nil
+		}
+		resTyp := check.applyTypeFunc(f, x.typ)
+		if resTyp == nil {
 			code := _InvalidImag
 			if id == _Real {
 				code = _InvalidReal
@@ -409,20 +444,6 @@
 			x.mode = value
 		}
 
-		// determine result type
-		var res BasicKind
-		switch x.typ.Underlying().(*Basic).kind {
-		case Complex64:
-			res = Float32
-		case Complex128:
-			res = Float64
-		case UntypedComplex:
-			res = UntypedFloat
-		default:
-			unreachable()
-		}
-		resTyp := Typ[res]
-
 		if check.Types != nil && x.mode != constant_ {
 			check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
 		}
@@ -434,25 +455,47 @@
 		// make(T, n, m)
 		// (no argument evaluated yet)
 		arg0 := call.Args[0]
-		T := check.typ(arg0)
+		T := check.varType(arg0)
 		if T == Typ[Invalid] {
 			return
 		}
 
-		var min int // minimum number of arguments
-		switch T.Underlying().(type) {
-		case *Slice:
-			min = 2
-		case *Map, *Chan:
-			min = 1
-		default:
+		min, max := -1, 10
+		var valid func(t Type) bool
+		valid = func(t Type) bool {
+			var m int
+			switch t := optype(t).(type) {
+			case *Slice:
+				m = 2
+			case *Map, *Chan:
+				m = 1
+			case *_Sum:
+				return t.is(valid)
+			default:
+				return false
+			}
+			if m > min {
+				min = m
+			}
+			if m+1 < max {
+				max = m + 1
+			}
+			return true
+		}
+
+		if !valid(T) {
 			check.invalidArg(arg0, _InvalidMake, "cannot make %s; type must be slice, map, or channel", arg0)
 			return
 		}
-		if nargs < min || min+1 < nargs {
-			check.errorf(call, _WrongArgCount, "%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
+		if nargs < min || max < nargs {
+			if min == max {
+				check.errorf(call, _WrongArgCount, "%v expects %d arguments; found %d", call, min, nargs)
+			} else {
+				check.errorf(call, _WrongArgCount, "%v expects %d or %d arguments; found %d", call, min, max, nargs)
+			}
 			return
 		}
+
 		types := []Type{T}
 		var sizes []int64 // constant integer arguments, if any
 		for _, arg := range call.Args[1:] {
@@ -475,7 +518,7 @@
 	case _New:
 		// new(T)
 		// (no argument evaluated yet)
-		T := check.typ(call.Args[0])
+		T := check.varType(call.Args[0])
 		if T == Typ[Invalid] {
 			return
 		}
@@ -543,8 +586,36 @@
 			check.recordBuiltinType(call.Fun, makeSig(x.typ))
 		}
 
+	case _Add:
+		// unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer
+		if !check.allowVersion(check.pkg, 1, 17) {
+			check.errorf(call.Fun, _InvalidUnsafeAdd, "unsafe.Add requires go1.17 or later")
+			return
+		}
+
+		check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
+		if x.mode == invalid {
+			return
+		}
+
+		var y operand
+		arg(&y, 1)
+		if !check.isValidIndex(&y, _InvalidUnsafeAdd, "length", true) {
+			return
+		}
+
+		x.mode = value
+		x.typ = Typ[UnsafePointer]
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, x.typ, y.typ))
+		}
+
 	case _Alignof:
 		// unsafe.Alignof(x T) uintptr
+		if asTypeParam(x.typ) != nil {
+			check.invalidOp(call, _Todo, "unsafe.Alignof undefined for %s", x)
+			return
+		}
 		check.assignment(x, nil, "argument to unsafe.Alignof")
 		if x.mode == invalid {
 			return
@@ -602,6 +673,10 @@
 
 	case _Sizeof:
 		// unsafe.Sizeof(x T) uintptr
+		if asTypeParam(x.typ) != nil {
+			check.invalidOp(call, _Todo, "unsafe.Sizeof undefined for %s", x)
+			return
+		}
 		check.assignment(x, nil, "argument to unsafe.Sizeof")
 		if x.mode == invalid {
 			return
@@ -612,6 +687,31 @@
 		x.typ = Typ[Uintptr]
 		// result is constant - no need to record signature
 
+	case _Slice:
+		// unsafe.Slice(ptr *T, len IntegerType) []T
+		if !check.allowVersion(check.pkg, 1, 17) {
+			check.errorf(call.Fun, _InvalidUnsafeSlice, "unsafe.Slice requires go1.17 or later")
+			return
+		}
+
+		typ := asPointer(x.typ)
+		if typ == nil {
+			check.invalidArg(x, _InvalidUnsafeSlice, "%s is not a pointer", x)
+			return
+		}
+
+		var y operand
+		arg(&y, 1)
+		if !check.isValidIndex(&y, _InvalidUnsafeSlice, "length", false) {
+			return
+		}
+
+		x.mode = value
+		x.typ = NewSlice(typ.base)
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, typ, y.typ))
+		}
+
 	case _Assert:
 		// assert(pred) causes a typechecker error if pred is false.
 		// The result of assert is the value of pred if there is no error.
@@ -657,6 +757,40 @@
 	return true
 }
 
+// applyTypeFunc applies f to x. If x is a type parameter,
+// the result is a type parameter constrained by an new
+// interface bound. The type bounds for that interface
+// are computed by applying f to each of the type bounds
+// of x. If any of these applications of f return nil,
+// applyTypeFunc returns nil.
+// If x is not a type parameter, the result is f(x).
+func (check *Checker) applyTypeFunc(f func(Type) Type, x Type) Type {
+	if tp := asTypeParam(x); tp != nil {
+		// Test if t satisfies the requirements for the argument
+		// type and collect possible result types at the same time.
+		var rtypes []Type
+		if !tp.Bound().is(func(x Type) bool {
+			if r := f(x); r != nil {
+				rtypes = append(rtypes, r)
+				return true
+			}
+			return false
+		}) {
+			return nil
+		}
+
+		// construct a suitable new type parameter
+		tpar := NewTypeName(token.NoPos, nil /* = Universe pkg */, "<type parameter>", nil)
+		ptyp := check.newTypeParam(tpar, 0, &emptyInterface) // assigns type to tpar as a side-effect
+		tsum := _NewSum(rtypes)
+		ptyp.bound = &Interface{types: tsum, allMethods: markComplete, allTypes: tsum}
+
+		return ptyp
+	}
+
+	return f(x)
+}
+
 // makeSig makes a signature for the given argument and result types.
 // Default types are used for untyped arguments, and res may be nil.
 func makeSig(res Type, args ...Type) *Signature {
@@ -678,7 +812,7 @@
 //
 func implicitArrayDeref(typ Type) Type {
 	if p, ok := typ.(*Pointer); ok {
-		if a, ok := p.base.Underlying().(*Array); ok {
+		if a := asArray(p.base); a != nil {
 			return a
 		}
 	}
diff --git a/src/go/types/builtins_test.go b/src/go/types/builtins_test.go
index cfd19d5..11de9a1 100644
--- a/src/go/types/builtins_test.go
+++ b/src/go/types/builtins_test.go
@@ -87,6 +87,9 @@
 	{"make", `var    c int32; _ = make([]float64   , 0, c)`, `func([]float64, int, int32) []float64`},
 	{"make", `var l, c uint ; _ = make([]complex128, l, c)`, `func([]complex128, uint, uint) []complex128`},
 
+	// issue #45667
+	{"make", `const l uint = 1; _ = make([]int, l)`, `func([]int, uint) []int`},
+
 	{"new", `_ = new(int)`, `func(int) *int`},
 	{"new", `type T struct{}; _ = new(T)`, `func(p.T) *p.T`},
 
@@ -104,6 +107,10 @@
 	{"recover", `recover()`, `func() interface{}`},
 	{"recover", `_ = recover()`, `func() interface{}`},
 
+	{"Add", `var p unsafe.Pointer; _ = unsafe.Add(p, -1.0)`, `func(unsafe.Pointer, int) unsafe.Pointer`},
+	{"Add", `var p unsafe.Pointer; var n uintptr; _ = unsafe.Add(p, n)`, `func(unsafe.Pointer, uintptr) unsafe.Pointer`},
+	{"Add", `_ = unsafe.Add(nil, 0)`, `func(unsafe.Pointer, int) unsafe.Pointer`},
+
 	{"Alignof", `_ = unsafe.Alignof(0)`, `invalid type`},                 // constant
 	{"Alignof", `var x struct{}; _ = unsafe.Alignof(x)`, `invalid type`}, // constant
 
@@ -113,6 +120,9 @@
 	{"Sizeof", `_ = unsafe.Sizeof(0)`, `invalid type`},                 // constant
 	{"Sizeof", `var x struct{}; _ = unsafe.Sizeof(x)`, `invalid type`}, // constant
 
+	{"Slice", `var p *int; _ = unsafe.Slice(p, 1)`, `func(*int, int) []int`},
+	{"Slice", `var p *byte; var n uintptr; _ = unsafe.Slice(p, n)`, `func(*byte, uintptr) []byte`},
+
 	{"assert", `assert(true)`, `invalid type`},                                    // constant
 	{"assert", `type B bool; const pred B = 1 < 2; assert(pred)`, `invalid type`}, // constant
 
diff --git a/src/go/types/call.go b/src/go/types/call.go
index 6765b17..631ea42 100644
--- a/src/go/types/call.go
+++ b/src/go/types/call.go
@@ -8,313 +8,352 @@
 
 import (
 	"go/ast"
+	"go/internal/typeparams"
 	"go/token"
 	"strings"
 	"unicode"
 )
 
-func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind {
-	check.exprOrType(x, e.Fun)
+// funcInst type-checks a function instantiation inst and returns the result in x.
+// The operand x must be the evaluation of inst.X and its type must be a signature.
+func (check *Checker) funcInst(x *operand, inst *ast.IndexExpr) {
+	xlist := typeparams.UnpackExpr(inst.Index)
+	targs := check.typeList(xlist)
+	if targs == nil {
+		x.mode = invalid
+		x.expr = inst
+		return
+	}
+	assert(len(targs) == len(xlist))
+
+	// check number of type arguments (got) vs number of type parameters (want)
+	sig := x.typ.(*Signature)
+	got, want := len(targs), len(sig.tparams)
+	if got > want {
+		check.errorf(xlist[got-1], _Todo, "got %d type arguments but want %d", got, want)
+		x.mode = invalid
+		x.expr = inst
+		return
+	}
+
+	// if we don't have enough type arguments, try type inference
+	inferred := false
+
+	if got < want {
+		targs = check.infer(inst, sig.tparams, targs, nil, nil, true)
+		if targs == nil {
+			// error was already reported
+			x.mode = invalid
+			x.expr = inst
+			return
+		}
+		got = len(targs)
+		inferred = true
+	}
+	assert(got == want)
+
+	// determine argument positions (for error reporting)
+	// TODO(rFindley) use a positioner here? instantiate would need to be
+	//                updated accordingly.
+	poslist := make([]token.Pos, len(xlist))
+	for i, x := range xlist {
+		poslist[i] = x.Pos()
+	}
+
+	// instantiate function signature
+	res := check.instantiate(x.Pos(), sig, targs, poslist).(*Signature)
+	assert(res.tparams == nil) // signature is not generic anymore
+	if inferred {
+		check.recordInferred(inst, targs, res)
+	}
+	x.typ = res
+	x.mode = value
+	x.expr = inst
+}
+
+func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
+	var inst *ast.IndexExpr
+	if iexpr, _ := call.Fun.(*ast.IndexExpr); iexpr != nil {
+		if check.indexExpr(x, iexpr) {
+			// Delay function instantiation to argument checking,
+			// where we combine type and value arguments for type
+			// inference.
+			assert(x.mode == value)
+			inst = iexpr
+		}
+		x.expr = iexpr
+		check.record(x)
+	} else {
+		check.exprOrType(x, call.Fun)
+	}
 
 	switch x.mode {
 	case invalid:
-		check.use(e.Args...)
-		x.mode = invalid
-		x.expr = e
+		check.use(call.Args...)
+		x.expr = call
 		return statement
 
 	case typexpr:
 		// conversion
 		T := x.typ
 		x.mode = invalid
-		switch n := len(e.Args); n {
+		switch n := len(call.Args); n {
 		case 0:
-			check.errorf(inNode(e, e.Rparen), _WrongArgCount, "missing argument in conversion to %s", T)
+			check.errorf(inNode(call, call.Rparen), _WrongArgCount, "missing argument in conversion to %s", T)
 		case 1:
-			check.expr(x, e.Args[0])
+			check.expr(x, call.Args[0])
 			if x.mode != invalid {
-				if e.Ellipsis.IsValid() {
-					check.errorf(e.Args[0], _BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
+				if call.Ellipsis.IsValid() {
+					check.errorf(call.Args[0], _BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
 					break
 				}
+				if t := asInterface(T); t != nil {
+					check.completeInterface(token.NoPos, t)
+					if t._IsConstraint() {
+						check.errorf(call, _Todo, "cannot use interface %s in conversion (contains type list or is comparable)", T)
+						break
+					}
+				}
 				check.conversion(x, T)
 			}
 		default:
-			check.use(e.Args...)
-			check.errorf(e.Args[n-1], _WrongArgCount, "too many arguments in conversion to %s", T)
+			check.use(call.Args...)
+			check.errorf(call.Args[n-1], _WrongArgCount, "too many arguments in conversion to %s", T)
 		}
-		x.expr = e
+		x.expr = call
 		return conversion
 
 	case builtin:
 		id := x.id
-		if !check.builtin(x, e, id) {
+		if !check.builtin(x, call, id) {
 			x.mode = invalid
 		}
-		x.expr = e
+		x.expr = call
 		// a non-constant result implies a function call
 		if x.mode != invalid && x.mode != constant_ {
 			check.hasCallOrRecv = true
 		}
 		return predeclaredFuncs[id].kind
+	}
 
-	default:
-		// function/method call
-		cgocall := x.mode == cgofunc
+	// ordinary function/method call
+	cgocall := x.mode == cgofunc
 
-		sig, _ := x.typ.Underlying().(*Signature)
-		if sig == nil {
-			check.invalidOp(x, _InvalidCall, "cannot call non-function %s", x)
-			x.mode = invalid
-			x.expr = e
-			return statement
-		}
-
-		arg, n, _ := unpack(func(x *operand, i int) { check.multiExpr(x, e.Args[i]) }, len(e.Args), false)
-		if arg != nil {
-			check.arguments(x, e, sig, arg, n)
-		} else {
-			x.mode = invalid
-		}
-
-		// determine result
-		switch sig.results.Len() {
-		case 0:
-			x.mode = novalue
-		case 1:
-			if cgocall {
-				x.mode = commaerr
-			} else {
-				x.mode = value
-			}
-			x.typ = sig.results.vars[0].typ // unpack tuple
-		default:
-			x.mode = value
-			x.typ = sig.results
-		}
-
-		x.expr = e
-		check.hasCallOrRecv = true
-
+	sig := asSignature(x.typ)
+	if sig == nil {
+		check.invalidOp(x, _InvalidCall, "cannot call non-function %s", x)
+		x.mode = invalid
+		x.expr = call
 		return statement
 	}
-}
 
-// 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 {
-		// 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)
+	// evaluate type arguments, if any
+	var targs []Type
+	if inst != nil {
+		xlist := typeparams.UnpackExpr(inst.Index)
+		targs = check.typeList(xlist)
+		if targs == nil {
+			check.use(call.Args...)
+			x.mode = invalid
+			x.expr = call
+			return statement
 		}
-	}
-}
+		assert(len(targs) == len(xlist))
 
-// 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
-// unpack, which may have evaluated the first argument already).
-func (check *Checker) useGetter(get getter, n int) {
-	var x operand
-	for i := 0; i < n; i++ {
-		get(&x, i)
-	}
-}
-
-// A getter sets x as the i'th operand, where 0 <= i < n and n is the total
-// number of operands (context-specific, and maintained elsewhere). A getter
-// type-checks the i'th operand; the details of the actual check are getter-
-// specific.
-type getter func(x *operand, i int)
-
-// unpack takes a getter get and a number of operands n. If n == 1, unpack
-// calls the incoming getter for the first operand. If that operand is
-// invalid, unpack returns (nil, 0, false). Otherwise, if that operand is a
-// function call, or a comma-ok expression and allowCommaOk is set, the result
-// is a new getter and operand count providing access to the function results,
-// or comma-ok values, respectively. The third result value reports if it
-// is indeed the comma-ok case. In all other cases, the incoming getter and
-// operand count are returned unchanged, and the third result value is false.
-//
-// In other words, if there's exactly one operand that - after type-checking
-// by calling get - stands for multiple operands, the resulting getter provides
-// access to those operands instead.
-//
-// If the returned getter is called at most once for a given operand index i
-// (including i == 0), that operand is guaranteed to cause only one call of
-// the incoming getter with that i.
-//
-func unpack(get getter, n int, allowCommaOk bool) (getter, int, bool) {
-	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
-		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 || x0.mode == commaerr {
-		// comma-ok value
-		if allowCommaOk {
-			a := [2]Type{x0.typ, Typ[UntypedBool]}
-			if x0.mode == commaerr {
-				a[1] = universeError
-			}
-			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
-}
-
-// arguments checks argument passing for the call with the given signature.
-// The arg function provides the operand for the i'th argument.
-func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, arg getter, n int) {
-	if call.Ellipsis.IsValid() {
-		// last argument is of the form x...
-		if !sig.variadic {
-			check.errorf(atPos(call.Ellipsis), _NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
-			check.useGetter(arg, n)
-			return
-		}
-		if len(call.Args) == 1 && n > 1 {
-			// f()... is not permitted if f() is multi-valued
-			check.errorf(atPos(call.Ellipsis), _InvalidDotDotDotOperand, "cannot use ... with %d-valued %s", n, call.Args[0])
-			check.useGetter(arg, n)
-			return
+		// check number of type arguments (got) vs number of type parameters (want)
+		got, want := len(targs), len(sig.tparams)
+		if got > want {
+			check.errorf(xlist[want], _Todo, "got %d type arguments but want %d", got, want)
+			check.use(call.Args...)
+			x.mode = invalid
+			x.expr = call
+			return statement
 		}
 	}
 
 	// evaluate arguments
-	context := check.sprintf("argument to %s", call.Fun)
-	for i := 0; i < n; i++ {
-		arg(x, i)
-		if x.mode != invalid {
-			var ellipsis token.Pos
-			if i == n-1 && call.Ellipsis.IsValid() {
-				ellipsis = call.Ellipsis
-			}
-			check.argument(sig, i, x, ellipsis, context)
+	args, _ := check.exprList(call.Args, false)
+	sig = check.arguments(call, sig, targs, args)
+
+	// determine result
+	switch sig.results.Len() {
+	case 0:
+		x.mode = novalue
+	case 1:
+		if cgocall {
+			x.mode = commaerr
+		} else {
+			x.mode = value
 		}
+		x.typ = sig.results.vars[0].typ // unpack tuple
+	default:
+		x.mode = value
+		x.typ = sig.results
+	}
+	x.expr = call
+	check.hasCallOrRecv = true
+
+	// if type inference failed, a parametrized result must be invalidated
+	// (operands cannot have a parametrized type)
+	if x.mode == value && len(sig.tparams) > 0 && isParameterized(sig.tparams, x.typ) {
+		x.mode = invalid
+	}
+
+	return statement
+}
+
+func (check *Checker) exprList(elist []ast.Expr, allowCommaOk bool) (xlist []*operand, commaOk bool) {
+	switch len(elist) {
+	case 0:
+		// nothing to do
+
+	case 1:
+		// single (possibly comma-ok) value, or function returning multiple values
+		e := elist[0]
+		var x operand
+		check.multiExpr(&x, e)
+		if t, ok := x.typ.(*Tuple); ok && x.mode != invalid {
+			// multiple values
+			xlist = make([]*operand, t.Len())
+			for i, v := range t.vars {
+				xlist[i] = &operand{mode: value, expr: e, typ: v.typ}
+			}
+			break
+		}
+
+		// exactly one (possibly invalid or comma-ok) value
+		xlist = []*operand{&x}
+		if allowCommaOk && (x.mode == mapindex || x.mode == commaok || x.mode == commaerr) {
+			x.mode = value
+			x2 := &operand{mode: value, expr: e, typ: Typ[UntypedBool]}
+			if x.mode == commaerr {
+				x2.typ = universeError
+			}
+			xlist = append(xlist, x2)
+			commaOk = true
+		}
+
+	default:
+		// multiple (possibly invalid) values
+		xlist = make([]*operand, len(elist))
+		for i, e := range elist {
+			var x operand
+			check.expr(&x, e)
+			xlist[i] = &x
+		}
+	}
+
+	return
+}
+
+func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type, args []*operand) (rsig *Signature) {
+	rsig = sig
+
+	// TODO(gri) try to eliminate this extra verification loop
+	for _, a := range args {
+		switch a.mode {
+		case typexpr:
+			check.errorf(a, 0, "%s used as value", a)
+			return
+		case invalid:
+			return
+		}
+	}
+
+	// Function call argument/parameter count requirements
+	//
+	//               | standard call    | dotdotdot call |
+	// --------------+------------------+----------------+
+	// standard func | nargs == npars   | invalid        |
+	// --------------+------------------+----------------+
+	// variadic func | nargs >= npars-1 | nargs == npars |
+	// --------------+------------------+----------------+
+
+	nargs := len(args)
+	npars := sig.params.Len()
+	ddd := call.Ellipsis.IsValid()
+
+	// set up parameters
+	sigParams := sig.params // adjusted for variadic functions (may be nil for empty parameter lists!)
+	adjusted := false       // indicates if sigParams is different from t.params
+	if sig.variadic {
+		if ddd {
+			// variadic_func(a, b, c...)
+			if len(call.Args) == 1 && nargs > 1 {
+				// f()... is not permitted if f() is multi-valued
+				check.errorf(inNode(call, call.Ellipsis), _InvalidDotDotDot, "cannot use ... with %d-valued %s", nargs, call.Args[0])
+				return
+			}
+		} else {
+			// variadic_func(a, b, c)
+			if nargs >= npars-1 {
+				// Create custom parameters for arguments: keep
+				// the first npars-1 parameters and add one for
+				// each argument mapping to the ... parameter.
+				vars := make([]*Var, npars-1) // npars > 0 for variadic functions
+				copy(vars, sig.params.vars)
+				last := sig.params.vars[npars-1]
+				typ := last.typ.(*Slice).elem
+				for len(vars) < nargs {
+					vars = append(vars, NewParam(last.pos, last.pkg, last.name, typ))
+				}
+				sigParams = NewTuple(vars...) // possibly nil!
+				adjusted = true
+				npars = nargs
+			} else {
+				// nargs < npars-1
+				npars-- // for correct error message below
+			}
+		}
+	} else {
+		if ddd {
+			// standard_func(a, b, c...)
+			check.errorf(inNode(call, call.Ellipsis), _NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
+			return
+		}
+		// standard_func(a, b, c)
 	}
 
 	// check argument count
-	if sig.variadic {
-		// a variadic function accepts an "empty"
-		// last argument: count one extra
-		n++
-	}
-	if n < sig.params.Len() {
-		check.errorf(inNode(call, call.Rparen), _WrongArgCount, "too few arguments in call to %s", call.Fun)
-		// ok to continue
-	}
-}
-
-// argument checks passing of argument x to the i'th parameter of the given signature.
-// If ellipsis is valid, the argument is followed by ... at that position in the call.
-func (check *Checker) argument(sig *Signature, i int, x *operand, ellipsis token.Pos, context string) {
-	check.singleValue(x)
-	if x.mode == invalid {
-		return
-	}
-
-	n := sig.params.Len()
-
-	// determine parameter type
-	var typ Type
 	switch {
-	case i < n:
-		typ = sig.params.vars[i].typ
-	case sig.variadic:
-		typ = sig.params.vars[n-1].typ
-		if debug {
-			if _, ok := typ.(*Slice); !ok {
-				check.dump("%v: expected unnamed slice type, got %s", sig.params.vars[n-1].Pos(), typ)
-			}
-		}
-	default:
-		check.errorf(x, _WrongArgCount, "too many arguments")
+	case nargs < npars:
+		check.errorf(inNode(call, call.Rparen), _WrongArgCount, "not enough arguments in call to %s", call.Fun)
+		return
+	case nargs > npars:
+		check.errorf(args[npars], _WrongArgCount, "too many arguments in call to %s", call.Fun) // report at first extra argument
 		return
 	}
 
-	if ellipsis.IsValid() {
-		if i != n-1 {
-			check.errorf(atPos(ellipsis), _MisplacedDotDotDot, "can only use ... with matching parameter")
-			return
+	// infer type arguments and instantiate signature if necessary
+	if len(sig.tparams) > 0 {
+		// TODO(gri) provide position information for targs so we can feed
+		//           it to the instantiate call for better error reporting
+		targs := check.infer(call, sig.tparams, targs, sigParams, args, true)
+		if targs == nil {
+			return // error already reported
 		}
-		// argument is of the form x... and x is single-valued
-		if _, ok := x.typ.Underlying().(*Slice); !ok && x.typ != Typ[UntypedNil] { // see issue #18268
-			check.errorf(x, _InvalidDotDotDotOperand, "cannot use %s as parameter of type %s", x, typ)
-			return
+
+		// compute result signature
+		rsig = check.instantiate(call.Pos(), sig, targs, nil).(*Signature)
+		assert(rsig.tparams == nil) // signature is not generic anymore
+		check.recordInferred(call, targs, rsig)
+
+		// Optimization: Only if the parameter list was adjusted do we
+		// need to compute it from the adjusted list; otherwise we can
+		// simply use the result signature's parameter list.
+		if adjusted {
+			sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(sig.tparams, targs)).(*Tuple)
+		} else {
+			sigParams = rsig.params
 		}
-	} else if sig.variadic && i >= n-1 {
-		// use the variadic parameter slice's element type
-		typ = typ.(*Slice).elem
 	}
 
-	check.assignment(x, typ, context)
+	// check arguments
+	for i, a := range args {
+		check.assignment(a, sigParams.vars[i].typ, check.sprintf("argument to %s", call.Fun))
+	}
+
+	return
 }
 
 var cgoPrefixes = [...]string{
@@ -417,7 +456,7 @@
 				x.typ = exp.typ
 				x.id = exp.id
 			default:
-				check.dump("unexpected object %v", exp)
+				check.dump("%v: unexpected object %v", e.Sel.Pos(), exp)
 				unreachable()
 			}
 			x.expr = e
@@ -430,6 +469,8 @@
 		goto Error
 	}
 
+	check.instantiatedOperand(x)
+
 	obj, index, indirect = check.lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
 	if obj == nil {
 		switch {
@@ -439,8 +480,20 @@
 		case indirect:
 			check.errorf(e.Sel, _InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
 		default:
-			// Check if capitalization of sel matters and provide better error
-			// message in that case.
+			var why string
+			if tpar := asTypeParam(x.typ); tpar != nil {
+				// Type parameter bounds don't specify fields, so don't mention "field".
+				switch obj := tpar.Bound().obj.(type) {
+				case nil:
+					why = check.sprintf("type bound for %s has no method %s", x.typ, sel)
+				case *TypeName:
+					why = check.sprintf("interface %s has no method %s", obj.name, sel)
+				}
+			} else {
+				why = check.sprintf("type %s has no field or method %s", x.typ, sel)
+			}
+
+			// Check if capitalization of sel matters and provide better error message in that case.
 			if len(sel) > 0 {
 				var changeCase string
 				if r := rune(sel[0]); unicode.IsUpper(r) {
@@ -449,11 +502,11 @@
 					changeCase = string(unicode.ToUpper(r)) + sel[1:]
 				}
 				if obj, _, _ = check.lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, changeCase); obj != nil {
-					check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (type %s has no field or method %s, but does have %s)", x.expr, sel, x.typ, sel, changeCase)
-					break
+					why += ", but does have " + changeCase
 				}
 			}
-			check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (type %s has no field or method %s)", x.expr, sel, x.typ, sel)
+
+			check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
 		}
 		goto Error
 	}
@@ -461,6 +514,54 @@
 	// methods may not have a fully set up signature yet
 	if m, _ := obj.(*Func); m != nil {
 		check.objDecl(m, nil)
+		// If m has a parameterized receiver type, infer the type arguments from
+		// the actual receiver provided and then substitute the type parameters in
+		// the signature accordingly.
+		// TODO(gri) factor this code out
+		sig := m.typ.(*Signature)
+		if len(sig.rparams) > 0 {
+			// For inference to work, we must use the receiver type
+			// matching the receiver in the actual method declaration.
+			// If the method is embedded, the matching receiver is the
+			// embedded struct or interface that declared the method.
+			// Traverse the embedding to find that type (issue #44688).
+			recv := x.typ
+			for i := 0; i < len(index)-1; i++ {
+				// The embedded type is either a struct or a pointer to
+				// a struct except for the last one (which we don't need).
+				recv = asStruct(derefStructPtr(recv)).Field(index[i]).typ
+			}
+
+			// The method may have a pointer receiver, but the actually provided receiver
+			// may be a (hopefully addressable) non-pointer value, or vice versa. Here we
+			// only care about inferring receiver type parameters; to make the inference
+			// work, match up pointer-ness of receiver and argument.
+			if ptrRecv := isPointer(sig.recv.typ); ptrRecv != isPointer(recv) {
+				if ptrRecv {
+					recv = NewPointer(recv)
+				} else {
+					recv = recv.(*Pointer).base
+				}
+			}
+			// Disable reporting of errors during inference below. If we're unable to infer
+			// the receiver type arguments here, the receiver must be be otherwise invalid
+			// and an error has been reported elsewhere.
+			arg := operand{mode: variable, expr: x.expr, typ: recv}
+			targs := check.infer(m, sig.rparams, nil, NewTuple(sig.recv), []*operand{&arg}, false /* no error reporting */)
+			if targs == nil {
+				// We may reach here if there were other errors (see issue #40056).
+				goto Error
+			}
+			// Don't modify m. Instead - for now - make a copy of m and use that instead.
+			// (If we modify m, some tests will fail; possibly because the m is in use.)
+			// TODO(gri) investigate and provide a correct explanation here
+			copy := *m
+			copy.typ = check.subst(e.Pos(), m.typ, makeSubstMap(sig.rparams, targs))
+			obj = &copy
+		}
+		// TODO(gri) we also need to do substitution for parameterized interface methods
+		//           (this breaks code in testdata/linalg.go2 at the moment)
+		//           12/20/2019: Is this TODO still correct?
 	}
 
 	if x.mode == typexpr {
@@ -483,7 +584,8 @@
 		}
 		x.mode = value
 		x.typ = &Signature{
-			params:   NewTuple(append([]*Var{NewVar(token.NoPos, check.pkg, "", x.typ)}, params...)...),
+			tparams:  sig.tparams,
+			params:   NewTuple(append([]*Var{NewVar(token.NoPos, check.pkg, "_", x.typ)}, params...)...),
 			results:  sig.results,
 			variadic: sig.variadic,
 		}
@@ -507,7 +609,14 @@
 			// addressability, should we report the type &(x.typ) instead?
 			check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
 
-			if debug {
+			// TODO(gri) The verification pass below is disabled for now because
+			//           method sets don't match method lookup in some cases.
+			//           For instance, if we made a copy above when creating a
+			//           custom method for a parameterized received type, the
+			//           method set method doesn't match (no copy there). There
+			///          may be other situations.
+			disabled := true
+			if !disabled && debug {
 				// Verify that LookupFieldOrMethod and MethodSet.Lookup agree.
 				// TODO(gri) This only works because we call LookupFieldOrMethod
 				// _before_ calling NewMethodSet: LookupFieldOrMethod completes
@@ -567,3 +676,60 @@
 	x.mode = invalid
 	x.expr = e
 }
+
+// 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 {
+		// 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
+		}
+	}
+}
+
+// instantiatedOperand reports an error of x is an uninstantiated (generic) type and sets x.typ to Typ[Invalid].
+func (check *Checker) instantiatedOperand(x *operand) {
+	if x.mode == typexpr && isGeneric(x.typ) {
+		check.errorf(x, _Todo, "cannot use generic type %s without instantiation", x.typ)
+		x.typ = Typ[Invalid]
+	}
+}
diff --git a/src/go/types/check.go b/src/go/types/check.go
index 280792e..a923c3c 100644
--- a/src/go/types/check.go
+++ b/src/go/types/check.go
@@ -8,6 +8,7 @@
 
 import (
 	"errors"
+	"fmt"
 	"go/ast"
 	"go/constant"
 	"go/token"
@@ -19,18 +20,18 @@
 	trace = false // turn on for detailed type resolution traces
 )
 
-// If Strict is set, the type-checker enforces additional
+// If forceStrict is set, the type-checker enforces additional
 // rules not specified by the Go 1 spec, but which will
 // catch guaranteed run-time errors if the respective
 // code is executed. In other words, programs passing in
-// Strict mode are Go 1 compliant, but not all Go 1 programs
-// will pass in Strict mode. The additional rules are:
+// strict mode are Go 1 compliant, but not all Go 1 programs
+// will pass in strict mode. The additional rules are:
 //
 // - A type assertion x.(T) where T is an interface type
 //   is invalid if any (statically known) method that exists
 //   for both x and T have different signatures.
 //
-const strict = false
+const forceStrict = false
 
 // exprInfo stores information about an untyped expression.
 type exprInfo struct {
@@ -69,6 +70,12 @@
 	path, dir string
 }
 
+// A dotImportKey describes a dot-imported object in the given scope.
+type dotImportKey struct {
+	scope *Scope
+	obj   Object
+}
+
 // A Checker maintains the state of the type checker.
 // It must be created with NewChecker.
 type Checker struct {
@@ -78,22 +85,33 @@
 	fset *token.FileSet
 	pkg  *Package
 	*Info
-	objMap map[Object]*declInfo       // maps package-level objects and (non-interface) methods to declaration info
-	impMap map[importKey]*Package     // maps (import path, source directory) to (complete or fake) package
-	posMap map[*Interface][]token.Pos // maps interface types to lists of embedded interface positions
-	pkgCnt map[string]int             // counts number of imported packages with a given name (for better error messages)
+	version version                    // accepted language version
+	objMap  map[Object]*declInfo       // maps package-level objects and (non-interface) methods to declaration info
+	impMap  map[importKey]*Package     // maps (import path, source directory) to (complete or fake) package
+	posMap  map[*Interface][]token.Pos // maps interface types to lists of embedded interface positions
+	typMap  map[string]*Named          // maps an instantiated named type hash to a *Named type
+
+	// pkgPathMap maps package names to the set of distinct import paths we've
+	// seen for that name, anywhere in the import graph. It is used for
+	// disambiguating package names in error messages.
+	//
+	// pkgPathMap is allocated lazily, so that we don't pay the price of building
+	// it on the happy path. seenPkgMap tracks the packages that we've already
+	// walked.
+	pkgPathMap map[string]map[string]bool
+	seenPkgMap map[*Package]bool
 
 	// information collected during type-checking of a set of package files
 	// (initialized by Files, valid only for the duration of check.Files;
 	// maps and lists are allocated on demand)
-	files            []*ast.File                             // package files
-	unusedDotImports map[*Scope]map[*Package]*ast.ImportSpec // unused dot-imported packages
+	files        []*ast.File               // package files
+	imports      []*PkgName                // list of imported packages
+	dotImportMap map[dotImportKey]*PkgName // maps dot-imported objects to the package they were dot-imported through
 
 	firstErr error                 // first error encountered
 	methods  map[*TypeName][]*Func // maps package scope type names to associated non-blank (non-interface) methods
 	untyped  map[ast.Expr]exprInfo // map of expressions without final type
 	delayed  []func()              // stack of delayed action segments; segments are processed in FIFO order
-	finals   []func()              // list of final actions; processed at the end of type-checking the current set of files
 	objPath  []Object              // path of object dependencies during type inference (for cycle reporting)
 
 	// context within which the current object is type-checked
@@ -104,22 +122,6 @@
 	indent int // indentation for tracing
 }
 
-// addUnusedImport adds the position of a dot-imported package
-// pkg to the map of dot imports for the given file scope.
-func (check *Checker) addUnusedDotImport(scope *Scope, pkg *Package, spec *ast.ImportSpec) {
-	mm := check.unusedDotImports
-	if mm == nil {
-		mm = make(map[*Scope]map[*Package]*ast.ImportSpec)
-		check.unusedDotImports = mm
-	}
-	m := mm[scope]
-	if m == nil {
-		m = make(map[*Package]*ast.ImportSpec)
-		mm[scope] = m
-	}
-	m[pkg] = spec
-}
-
 // addDeclDep adds the dependency edge (check.decl -> to) if check.decl exists
 func (check *Checker) addDeclDep(to Object) {
 	from := check.decl
@@ -149,14 +151,6 @@
 	check.delayed = append(check.delayed, f)
 }
 
-// atEnd adds f to the list of actions processed at the end
-// of type-checking, before initialization order computation.
-// Actions added by atEnd are processed after any actions
-// added by later.
-func (check *Checker) atEnd(f func()) {
-	check.finals = append(check.finals, f)
-}
-
 // push pushes obj onto the object path and returns its index in the path.
 func (check *Checker) push(obj Object) int {
 	check.objPath = append(check.objPath, obj)
@@ -185,15 +179,21 @@
 		info = new(Info)
 	}
 
+	version, err := parseGoVersion(conf.goVersion)
+	if err != nil {
+		panic(fmt.Sprintf("invalid Go version %q (%v)", conf.goVersion, err))
+	}
+
 	return &Checker{
-		conf:   conf,
-		fset:   fset,
-		pkg:    pkg,
-		Info:   info,
-		objMap: make(map[Object]*declInfo),
-		impMap: make(map[importKey]*Package),
-		posMap: make(map[*Interface][]token.Pos),
-		pkgCnt: make(map[string]int),
+		conf:    conf,
+		fset:    fset,
+		pkg:     pkg,
+		Info:    info,
+		version: version,
+		objMap:  make(map[Object]*declInfo),
+		impMap:  make(map[importKey]*Package),
+		posMap:  make(map[*Interface][]token.Pos),
+		typMap:  make(map[string]*Named),
 	}
 }
 
@@ -202,13 +202,13 @@
 func (check *Checker) initFiles(files []*ast.File) {
 	// start with a clean slate (check.Files may be called multiple times)
 	check.files = nil
-	check.unusedDotImports = nil
+	check.imports = nil
+	check.dotImportMap = nil
 
 	check.firstErr = nil
 	check.methods = nil
 	check.untyped = nil
 	check.delayed = nil
-	check.finals = nil
 
 	// determine package name and collect valid files
 	pkg := check.pkg
@@ -265,7 +265,6 @@
 	check.packageObjects()
 
 	check.processDelayed(0) // incl. all functions
-	check.processFinals()
 
 	check.initOrder()
 
@@ -275,7 +274,20 @@
 
 	check.recordUntyped()
 
+	if check.Info != nil {
+		sanitizeInfo(check.Info)
+	}
+
 	check.pkg.complete = true
+
+	// no longer needed - release memory
+	check.imports = nil
+	check.dotImportMap = nil
+	check.pkgPathMap = nil
+	check.seenPkgMap = nil
+
+	// TODO(rFindley) There's more memory we should release at this point.
+
 	return
 }
 
@@ -294,13 +306,30 @@
 	check.delayed = check.delayed[:top]
 }
 
-func (check *Checker) processFinals() {
-	n := len(check.finals)
-	for _, f := range check.finals {
-		f() // must not append to check.finals
+func (check *Checker) record(x *operand) {
+	// convert x into a user-friendly set of values
+	// TODO(gri) this code can be simplified
+	var typ Type
+	var val constant.Value
+	switch x.mode {
+	case invalid:
+		typ = Typ[Invalid]
+	case novalue:
+		typ = (*Tuple)(nil)
+	case constant_:
+		typ = x.typ
+		val = x.val
+	default:
+		typ = x.typ
 	}
-	if len(check.finals) != n {
-		panic("internal error: final action list grew")
+	assert(x.expr != nil && typ != nil)
+
+	if isUntyped(typ) {
+		// delay type and value recording until we know the type
+		// or until the end of type checking
+		check.rememberUntyped(x.expr, false, x.mode, typ.(*Basic), val)
+	} else {
+		check.recordTypeAndValue(x.expr, x.mode, typ, val)
 	}
 }
 
@@ -326,7 +355,9 @@
 	}
 	if mode == constant_ {
 		assert(val != nil)
-		assert(typ == Typ[Invalid] || isConstType(typ))
+		// We check is(typ, IsConstType) here as constant expressions may be
+		// recorded as type parameters.
+		assert(typ == Typ[Invalid] || is(typ, IsConstType))
 	}
 	if m := check.Types; m != nil {
 		m[x] = TypeAndValue{mode, typ, val}
@@ -334,14 +365,14 @@
 }
 
 func (check *Checker) recordBuiltinType(f ast.Expr, sig *Signature) {
-	// f must be a (possibly parenthesized) identifier denoting a built-in
-	// (built-ins in package unsafe always produce a constant result and
-	// we don't record their signatures, so we don't see qualified idents
-	// here): record the signature for f and possible children.
+	// f must be a (possibly parenthesized, possibly qualified)
+	// identifier denoting a built-in (including unsafe's non-constant
+	// functions Add and Slice): record the signature for f and possible
+	// children.
 	for {
 		check.recordTypeAndValue(f, builtin, sig, nil)
 		switch p := f.(type) {
-		case *ast.Ident:
+		case *ast.Ident, *ast.SelectorExpr:
 			return // we're done
 		case *ast.ParenExpr:
 			f = p.X
@@ -377,6 +408,14 @@
 	}
 }
 
+func (check *Checker) recordInferred(call ast.Expr, targs []Type, sig *Signature) {
+	assert(call != nil)
+	assert(sig != nil)
+	if m := getInferred(check.Info); m != nil {
+		m[call] = _Inferred{targs, sig}
+	}
+}
+
 func (check *Checker) recordDef(id *ast.Ident, obj Object) {
 	assert(id != nil)
 	if m := check.Defs; m != nil {
diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go
index ce31dab..f83abf1 100644
--- a/src/go/types/check_test.go
+++ b/src/go/types/check_test.go
@@ -27,8 +27,10 @@
 
 import (
 	"flag"
+	"fmt"
 	"go/ast"
 	"go/importer"
+	"go/internal/typeparams"
 	"go/parser"
 	"go/scanner"
 	"go/token"
@@ -43,59 +45,11 @@
 )
 
 var (
-	haltOnError = flag.Bool("halt", false, "halt on error")
-	listErrors  = flag.Bool("errlist", false, "list errors")
-	testFiles   = flag.String("files", "", "space-separated list of test files")
+	haltOnError  = flag.Bool("halt", false, "halt on error")
+	verifyErrors = flag.Bool("verify", false, "verify errors (rather than list them) in TestManual")
+	goVersion    = flag.String("lang", "", "Go language version (e.g. \"go1.12\") for TestManual")
 )
 
-// The test filenames do not end in .go so that they are invisible
-// to gofmt since they contain comments that must not change their
-// positions relative to surrounding tokens.
-
-// Each tests entry is list of files belonging to the same package.
-var tests = [][]string{
-	{"testdata/errors.src"},
-	{"testdata/importdecl0a.src", "testdata/importdecl0b.src"},
-	{"testdata/importdecl1a.src", "testdata/importdecl1b.src"},
-	{"testdata/importC.src"}, // special handling in checkFiles
-	{"testdata/cycles.src"},
-	{"testdata/cycles1.src"},
-	{"testdata/cycles2.src"},
-	{"testdata/cycles3.src"},
-	{"testdata/cycles4.src"},
-	{"testdata/cycles5.src"},
-	{"testdata/init0.src"},
-	{"testdata/init1.src"},
-	{"testdata/init2.src"},
-	{"testdata/decls0.src"},
-	{"testdata/decls1.src"},
-	{"testdata/decls2a.src", "testdata/decls2b.src"},
-	{"testdata/decls3.src"},
-	{"testdata/decls4.src"},
-	{"testdata/decls5.src"},
-	{"testdata/const0.src"},
-	{"testdata/const1.src"},
-	{"testdata/constdecl.src"},
-	{"testdata/vardecl.src"},
-	{"testdata/expr0.src"},
-	{"testdata/expr1.src"},
-	{"testdata/expr2.src"},
-	{"testdata/expr3.src"},
-	{"testdata/methodsets.src"},
-	{"testdata/shifts.src"},
-	{"testdata/builtins.src"},
-	{"testdata/conversions.src"},
-	{"testdata/conversions2.src"},
-	{"testdata/stmt0.src"},
-	{"testdata/stmt1.src"},
-	{"testdata/gotos.src"},
-	{"testdata/labels.src"},
-	{"testdata/literals.src"},
-	{"testdata/issues.src"},
-	{"testdata/blank.src"},
-	{"testdata/issue25008b.src", "testdata/issue25008a.src"}, // order (b before a) is crucial!
-}
-
 var fset = token.NewFileSet()
 
 // Positioned errors are of the form filename:line:column: message .
@@ -114,11 +68,11 @@
 	return
 }
 
-func parseFiles(t *testing.T, filenames []string) ([]*ast.File, []error) {
+func parseFiles(t *testing.T, filenames []string, srcs [][]byte, mode parser.Mode) ([]*ast.File, []error) {
 	var files []*ast.File
 	var errlist []error
-	for _, filename := range filenames {
-		file, err := parser.ParseFile(fset, filename, nil, parser.AllErrors)
+	for i, filename := range filenames {
+		file, err := parser.ParseFile(fset, filename, srcs[i], mode)
 		if file == nil {
 			t.Fatalf("%s: %s", filename, err)
 		}
@@ -147,19 +101,17 @@
 // errMap collects the regular expressions of ERROR comments found
 // in files and returns them as a map of error positions to error messages.
 //
-func errMap(t *testing.T, testname string, files []*ast.File) map[string][]string {
+// srcs must be a slice of the same length as files, containing the original
+// source for the parsed AST.
+func errMap(t *testing.T, files []*ast.File, srcs [][]byte) map[string][]string {
 	// map of position strings to lists of error message patterns
 	errmap := make(map[string][]string)
 
-	for _, file := range files {
-		filename := fset.Position(file.Package).Filename
-		src, err := os.ReadFile(filename)
-		if err != nil {
-			t.Fatalf("%s: could not read %s", testname, filename)
-		}
-
+	for i, file := range files {
+		tok := fset.File(file.Package)
+		src := srcs[i]
 		var s scanner.Scanner
-		s.Init(fset.AddFile(filename, -1, len(src)), src, nil, scanner.ScanComments)
+		s.Init(tok, src, nil, scanner.ScanComments)
 		var prev token.Pos // position of last non-comment, non-semicolon token
 		var here token.Pos // position immediately after the token at position prev
 
@@ -236,16 +188,52 @@
 	}
 }
 
-func checkFiles(t *testing.T, testfiles []string) {
+// goVersionRx matches a Go version string using '_', e.g. "go1_12".
+var goVersionRx = regexp.MustCompile(`^go[1-9][0-9]*_(0|[1-9][0-9]*)$`)
+
+// asGoVersion returns a regular Go language version string
+// if s is a Go version string using '_' rather than '.' to
+// separate the major and minor version numbers (e.g. "go1_12").
+// Otherwise it returns the empty string.
+func asGoVersion(s string) string {
+	if goVersionRx.MatchString(s) {
+		return strings.Replace(s, "_", ".", 1)
+	}
+	return ""
+}
+
+func checkFiles(t *testing.T, sizes Sizes, goVersion string, filenames []string, srcs [][]byte, manual bool, imp Importer) {
+	if len(filenames) == 0 {
+		t.Fatal("no source files")
+	}
+
+	if strings.HasSuffix(filenames[0], ".go2") && !typeparams.Enabled {
+		t.Skip("type params are not enabled")
+	}
+	if strings.HasSuffix(filenames[0], ".go1") && typeparams.Enabled {
+		t.Skip("type params are enabled")
+	}
+
+	mode := parser.AllErrors
+	if !strings.HasSuffix(filenames[0], ".go2") {
+		mode |= typeparams.DisallowParsing
+	}
+
 	// parse files and collect parser errors
-	files, errlist := parseFiles(t, testfiles)
+	files, errlist := parseFiles(t, filenames, srcs, mode)
 
 	pkgName := "<no package>"
 	if len(files) > 0 {
 		pkgName = files[0].Name.Name
 	}
 
-	if *listErrors && len(errlist) > 0 {
+	// if no Go version is given, consider the package name
+	if goVersion == "" {
+		goVersion = asGoVersion(pkgName)
+	}
+
+	listErrors := manual && !*verifyErrors
+	if listErrors && len(errlist) > 0 {
 		t.Errorf("--- %s:", pkgName)
 		for _, err := range errlist {
 			t.Error(err)
@@ -254,16 +242,25 @@
 
 	// typecheck and collect typechecker errors
 	var conf Config
+	conf.Sizes = sizes
+	SetGoVersion(&conf, goVersion)
+
 	// special case for importC.src
-	if len(testfiles) == 1 && strings.HasSuffix(testfiles[0], "importC.src") {
-		conf.FakeImportC = true
+	if len(filenames) == 1 {
+		if strings.HasSuffix(filenames[0], "importC.src") {
+			conf.FakeImportC = true
+		}
 	}
-	conf.Importer = importer.Default()
+
+	conf.Importer = imp
+	if imp == nil {
+		conf.Importer = importer.Default()
+	}
 	conf.Error = func(err error) {
 		if *haltOnError {
 			defer panic(err)
 		}
-		if *listErrors {
+		if listErrors {
 			t.Error(err)
 			return
 		}
@@ -275,7 +272,7 @@
 	}
 	conf.Check(pkgName, fset, files, nil)
 
-	if *listErrors {
+	if listErrors {
 		return
 	}
 
@@ -292,7 +289,7 @@
 
 	// match and eliminate errors;
 	// we are expecting the following errors
-	errmap := errMap(t, pkgName, files)
+	errmap := errMap(t, files, srcs)
 	eliminate(t, errmap, errlist)
 
 	// there should be no expected errors left
@@ -306,44 +303,100 @@
 	}
 }
 
-func TestCheck(t *testing.T) {
-	testenv.MustHaveGoBuild(t)
-
-	// Declare builtins for testing.
-	DefPredeclaredTestFuncs()
-
-	// If explicit test files are specified, only check those.
-	if files := *testFiles; files != "" {
-		checkFiles(t, strings.Split(files, " "))
+// TestManual is for manual testing of input files, provided as a list
+// of arguments after the test arguments (and a separating "--"). For
+// instance, to check the files foo.go and bar.go, use:
+//
+// 	go test -run Manual -- foo.go bar.go
+//
+// Provide the -verify flag to verify errors against ERROR comments in
+// the input files rather than having a list of errors reported.
+// The accepted Go language version can be controlled with the -lang flag.
+func TestManual(t *testing.T) {
+	filenames := flag.Args()
+	if len(filenames) == 0 {
 		return
 	}
-
-	// Otherwise, run all the tests.
-	for _, files := range tests {
-		checkFiles(t, files)
-	}
+	testenv.MustHaveGoBuild(t)
+	DefPredeclaredTestFuncs()
+	testPkg(t, filenames, *goVersion, true)
 }
 
-func TestFixedBugs(t *testing.T) { testDir(t, "fixedbugs") }
+func TestLongConstants(t *testing.T) {
+	format := "package longconst\n\nconst _ = %s\nconst _ = %s // ERROR excessively long constant"
+	src := fmt.Sprintf(format, strings.Repeat("1", 9999), strings.Repeat("1", 10001))
+	checkFiles(t, nil, "", []string{"longconst.go"}, [][]byte{[]byte(src)}, false, nil)
+}
+
+// TestIndexRepresentability tests that constant index operands must
+// be representable as int even if they already have a type that can
+// represent larger values.
+func TestIndexRepresentability(t *testing.T) {
+	const src = "package index\n\nvar s []byte\nvar _ = s[int64 /* ERROR \"int64\\(1\\) << 40 \\(.*\\) overflows int\" */ (1) << 40]"
+	checkFiles(t, &StdSizes{4, 4}, "", []string{"index.go"}, [][]byte{[]byte(src)}, false, nil)
+}
+
+func TestIssue46453(t *testing.T) {
+	if typeparams.Enabled {
+		t.Skip("type params are enabled")
+	}
+	const src = "package p\ntype _ comparable // ERROR \"undeclared name: comparable\""
+	checkFiles(t, nil, "", []string{"issue46453.go"}, [][]byte{[]byte(src)}, false, nil)
+}
+
+func TestIssue47243_TypedRHS(t *testing.T) {
+	// The RHS of the shift expression below overflows uint on 32bit platforms,
+	// but this is OK as it is explicitly typed.
+	const src = "package issue47243\n\nvar a uint64; var _ = a << uint64(4294967296)" // uint64(1<<32)
+	checkFiles(t, &StdSizes{4, 4}, "", []string{"p.go"}, [][]byte{[]byte(src)}, false, nil)
+}
+
+func TestCheck(t *testing.T)     { DefPredeclaredTestFuncs(); testDir(t, "check") }
+func TestExamples(t *testing.T)  { testDir(t, "examples") }
+func TestFixedbugs(t *testing.T) { testDir(t, "fixedbugs") }
 
 func testDir(t *testing.T, dir string) {
 	testenv.MustHaveGoBuild(t)
 
-	dirs, err := os.ReadDir(dir)
+	dir = filepath.Join("testdata", dir)
+	fis, err := os.ReadDir(dir)
 	if err != nil {
-		t.Fatal(err)
+		t.Error(err)
+		return
 	}
 
-	for _, d := range dirs {
-		testname := filepath.Base(d.Name())
-		testname = strings.TrimSuffix(testname, filepath.Ext(testname))
-		t.Run(testname, func(t *testing.T) {
-			filename := filepath.Join(dir, d.Name())
-			if d.IsDir() {
-				t.Errorf("skipped directory %q", filename)
-				return
+	for _, fi := range fis {
+		path := filepath.Join(dir, fi.Name())
+
+		// if fi is a directory, its files make up a single package
+		var filenames []string
+		if fi.IsDir() {
+			fis, err := os.ReadDir(path)
+			if err != nil {
+				t.Error(err)
+				continue
 			}
-			checkFiles(t, []string{filename})
+			for _, fi := range fis {
+				filenames = append(filenames, filepath.Join(path, fi.Name()))
+			}
+		} else {
+			filenames = []string{path}
+		}
+		t.Run(filepath.Base(path), func(t *testing.T) {
+			testPkg(t, filenames, "", false)
 		})
 	}
 }
+
+// TODO(rFindley) reconcile the different test setup in go/types with types2.
+func testPkg(t *testing.T, filenames []string, goVersion string, manual bool) {
+	srcs := make([][]byte, len(filenames))
+	for i, filename := range filenames {
+		src, err := os.ReadFile(filename)
+		if err != nil {
+			t.Fatalf("could not read %s: %v", filename, err)
+		}
+		srcs[i] = src
+	}
+	checkFiles(t, nil, goVersion, filenames, srcs, manual, nil)
+}
diff --git a/src/go/types/conversions.go b/src/go/types/conversions.go
index 1cab1cc..ad6d3ee 100644
--- a/src/go/types/conversions.go
+++ b/src/go/types/conversions.go
@@ -17,10 +17,11 @@
 	constArg := x.mode == constant_
 
 	var ok bool
+	var reason string
 	switch {
 	case constArg && isConstType(T):
 		// constant conversion
-		switch t := T.Underlying().(*Basic); {
+		switch t := asBasic(T); {
 		case representableConst(x.val, check, t, &x.val):
 			ok = true
 		case isInteger(x.typ) && isString(t):
@@ -31,14 +32,18 @@
 			x.val = constant.MakeString(string(codepoint))
 			ok = true
 		}
-	case x.convertibleTo(check, T):
+	case x.convertibleTo(check, T, &reason):
 		// non-constant conversion
 		x.mode = value
 		ok = true
 	}
 
 	if !ok {
-		check.errorf(x, _InvalidConversion, "cannot convert %s to %s", x, T)
+		if reason != "" {
+			check.errorf(x, _InvalidConversion, "cannot convert %s to %s (%s)", x, T, reason)
+		} else {
+			check.errorf(x, _InvalidConversion, "cannot convert %s to %s", x, T)
+		}
 		x.mode = invalid
 		return
 	}
@@ -55,8 +60,8 @@
 		// - 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)
+		if IsInterface(T) || constArg && !isConstType(T) || x.isNil() {
+			final = Default(x.typ) // default type of untyped nil is untyped nil
 		} else if isInteger(x.typ) && isString(T) {
 			final = x.typ
 		}
@@ -79,7 +84,7 @@
 // convertibleTo reports whether T(x) is valid.
 // The check parameter may be nil if convertibleTo is invoked through an
 // exported API call, i.e., when all methods have been type-checked.
-func (x *operand) convertibleTo(check *Checker, T Type) bool {
+func (x *operand) convertibleTo(check *Checker, T Type, reason *string) bool {
 	// "x is assignable to T"
 	if ok, _ := x.assignableTo(check, T, nil); ok {
 		return true
@@ -87,8 +92,8 @@
 
 	// "x's type and T have identical underlying types if tags are ignored"
 	V := x.typ
-	Vu := V.Underlying()
-	Tu := T.Underlying()
+	Vu := under(V)
+	Tu := under(T)
 	if check.identicalIgnoreTags(Vu, Tu) {
 		return true
 	}
@@ -97,14 +102,14 @@
 	// have identical underlying types if tags are ignored"
 	if V, ok := V.(*Pointer); ok {
 		if T, ok := T.(*Pointer); ok {
-			if check.identicalIgnoreTags(V.base.Underlying(), T.base.Underlying()) {
+			if check.identicalIgnoreTags(under(V.base), under(T.base)) {
 				return true
 			}
 		}
 	}
 
 	// "x's type and T are both integer or floating point types"
-	if (isInteger(V) || isFloat(V)) && (isInteger(T) || isFloat(T)) {
+	if isIntegerOrFloat(V) && isIntegerOrFloat(T) {
 		return true
 	}
 
@@ -133,31 +138,48 @@
 		return true
 	}
 
+	// "x is a slice, T is a pointer-to-array type,
+	// and the slice and array types have identical element types."
+	if s := asSlice(V); s != nil {
+		if p := asPointer(T); p != nil {
+			if a := asArray(p.Elem()); a != nil {
+				if check.identical(s.Elem(), a.Elem()) {
+					if check == nil || check.allowVersion(check.pkg, 1, 17) {
+						return true
+					}
+					if reason != nil {
+						*reason = "conversion of slices to array pointers requires go1.17 or later"
+					}
+				}
+			}
+		}
+	}
+
 	return false
 }
 
 func isUintptr(typ Type) bool {
-	t, ok := typ.Underlying().(*Basic)
-	return ok && t.kind == Uintptr
+	t := asBasic(typ)
+	return t != nil && t.kind == Uintptr
 }
 
 func isUnsafePointer(typ Type) bool {
-	// TODO(gri): Is this (typ.Underlying() instead of just typ) correct?
+	// TODO(gri): Is this asBasic(typ) instead of typ.(*Basic) correct?
+	//            (The former calls under(), while the latter doesn't.)
 	//            The spec does not say so, but gc claims it is. See also
 	//            issue 6326.
-	t, ok := typ.Underlying().(*Basic)
-	return ok && t.kind == UnsafePointer
+	t := asBasic(typ)
+	return t != nil && t.kind == UnsafePointer
 }
 
 func isPointer(typ Type) bool {
-	_, ok := typ.Underlying().(*Pointer)
-	return ok
+	return asPointer(typ) != nil
 }
 
 func isBytesOrRunes(typ Type) bool {
-	if s, ok := typ.(*Slice); ok {
-		t, ok := s.elem.Underlying().(*Basic)
-		return ok && (t.kind == Byte || t.kind == Rune)
+	if s := asSlice(typ); s != nil {
+		t := asBasic(s.elem)
+		return t != nil && (t.kind == Byte || t.kind == Rune)
 	}
 	return false
 }
diff --git a/src/go/types/decl.go b/src/go/types/decl.go
index 1f0bc35..9211feb 100644
--- a/src/go/types/decl.go
+++ b/src/go/types/decl.go
@@ -5,8 +5,10 @@
 package types
 
 import (
+	"fmt"
 	"go/ast"
 	"go/constant"
+	"go/internal/typeparams"
 	"go/token"
 )
 
@@ -52,7 +54,10 @@
 // objDecl type-checks the declaration of obj in its respective (file) context.
 // For the meaning of def, see Checker.definedType, in typexpr.go.
 func (check *Checker) objDecl(obj Object, def *Named) {
-	if trace {
+	if trace && obj.Type() == nil {
+		if check.indent == 0 {
+			fmt.Println() // empty line between top-level objects for readability
+		}
 		check.trace(obj.Pos(), "-- checking %s (%s, objPath = %s)", obj, obj.color(), pathString(check.objPath))
 		check.indent++
 		defer func() {
@@ -183,13 +188,14 @@
 	switch obj := obj.(type) {
 	case *Const:
 		check.decl = d // new package-level const decl
-		check.constDecl(obj, d.typ, d.init, d.inherited)
+		check.constDecl(obj, d.vtyp, d.init, d.inherited)
 	case *Var:
 		check.decl = d // new package-level var decl
-		check.varDecl(obj, d.lhs, d.typ, d.init)
+		check.varDecl(obj, d.lhs, d.vtyp, d.init)
 	case *TypeName:
 		// invalid recursive types are detected via path
-		check.typeDecl(obj, d.typ, def, d.alias)
+		check.typeDecl(obj, d.tdecl, def)
+		check.collectMethods(obj) // methods can only be added to top-level types
 	case *Func:
 		// functions may be recursive - no need to track dependencies
 		check.funcDecl(obj, d)
@@ -234,7 +240,7 @@
 			// this information explicitly in the object.
 			var alias bool
 			if d := check.objMap[obj]; d != nil {
-				alias = d.alias // package-level object
+				alias = d.tdecl.Assign.IsValid() // package-level object
 			} else {
 				alias = obj.IsAlias() // function local object
 			}
@@ -318,7 +324,7 @@
 		}
 
 		// don't report a 2nd error if we already know the type is invalid
-		// (e.g., if a cycle was detected earlier, via Checker.underlying).
+		// (e.g., if a cycle was detected earlier, via under).
 		if t.underlying == Typ[Invalid] {
 			t.info = invalid
 			return invalid
@@ -337,13 +343,15 @@
 				if tn == t.obj {
 					check.cycleError(path[i:])
 					t.info = invalid
-					t.underlying = Typ[Invalid]
 					return t.info
 				}
 			}
 			panic("internal error: cycle start not found")
 		}
 		return t.info
+
+	case *instance:
+		return check.validType(t.expand(), path)
 	}
 
 	return valid
@@ -475,7 +483,7 @@
 		if !isConstType(t) {
 			// don't report an error if the type is an invalid C (defined) type
 			// (issue #22090)
-			if t.Underlying() != Typ[Invalid] {
+			if under(t) != Typ[Invalid] {
 				check.errorf(typ, _InvalidConstType, "invalid constant type %s", t)
 			}
 			obj.typ = Typ[Invalid]
@@ -506,7 +514,7 @@
 
 	// determine type, if any
 	if typ != nil {
-		obj.typ = check.typ(typ)
+		obj.typ = check.varType(typ)
 		// We cannot spread the type to all lhs variables if there
 		// are more than one since that would mark them as checked
 		// (see Checker.objDecl) and the assignment of init exprs,
@@ -561,36 +569,66 @@
 	check.initVars(lhs, []ast.Expr{init}, token.NoPos)
 }
 
-// underlying returns the underlying type of typ; possibly by following
-// forward chains of named types. Such chains only exist while named types
-// are incomplete. If an underlying type is found, resolve the chain by
-// setting the underlying type for each defined type in the chain before
-// returning it.
-//
-// If no underlying type is found, a cycle error is reported and Typ[Invalid]
-// is used as underlying type for each defined type in the chain and returned
-// as result.
-func (check *Checker) underlying(typ Type) Type {
-	// If typ is not a defined type, its underlying type is itself.
-	n0, _ := typ.(*Named)
-	if n0 == nil {
-		return typ // nothing to do
+// under returns the expanded underlying type of n0; possibly by following
+// forward chains of named types. If an underlying type is found, resolve
+// the chain by setting the underlying type for each defined type in the
+// chain before returning it. If no underlying type is found or a cycle
+// is detected, the result is Typ[Invalid]. If a cycle is detected and
+// n0.check != nil, the cycle is reported.
+func (n0 *Named) under() Type {
+	u := n0.underlying
+
+	if u == Typ[Invalid] {
+		return u
 	}
 
 	// If the underlying type of a defined type is not a defined
-	// type, then that is the desired underlying type.
-	typ = n0.underlying
-	n, _ := typ.(*Named)
+	// (incl. instance) type, then that is the desired underlying
+	// type.
+	switch u.(type) {
+	case nil:
+		return Typ[Invalid]
+	default:
+		// common case
+		return u
+	case *Named, *instance:
+		// handled below
+	}
+
+	if n0.check == nil {
+		panic("internal error: Named.check == nil but type is incomplete")
+	}
+
+	// Invariant: after this point n0 as well as any named types in its
+	// underlying chain should be set up when this function exits.
+	check := n0.check
+
+	// If we can't expand u at this point, it is invalid.
+	n := asNamed(u)
 	if n == nil {
-		return typ // common case
+		n0.underlying = Typ[Invalid]
+		return n0.underlying
 	}
 
 	// Otherwise, follow the forward chain.
 	seen := map[*Named]int{n0: 0}
 	path := []Object{n0.obj}
 	for {
-		typ = n.underlying
-		n1, _ := typ.(*Named)
+		u = n.underlying
+		if u == nil {
+			u = Typ[Invalid]
+			break
+		}
+		var n1 *Named
+		switch u1 := u.(type) {
+		case *Named:
+			n1 = u1
+		case *instance:
+			n1, _ = u1.expand().(*Named)
+			if n1 == nil {
+				u = Typ[Invalid]
+			}
+		}
 		if n1 == nil {
 			break // end of chain
 		}
@@ -602,7 +640,7 @@
 		if i, ok := seen[n]; ok {
 			// cycle
 			check.cycleError(path[i:])
-			typ = Typ[Invalid]
+			u = Typ[Invalid]
 			break
 		}
 	}
@@ -611,13 +649,14 @@
 		// We should never have to update the underlying type of an imported type;
 		// those underlying types should have been resolved during the import.
 		// Also, doing so would lead to a race condition (was issue #31749).
+		// Do this check always, not just in debug mode (it's cheap).
 		if n.obj.pkg != check.pkg {
 			panic("internal error: imported type with unresolved underlying type")
 		}
-		n.underlying = typ
+		n.underlying = u
 	}
 
-	return typ
+	return u
 }
 
 func (n *Named) setUnderlying(typ Type) {
@@ -626,26 +665,45 @@
 	}
 }
 
-func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, alias bool) {
+func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
 	assert(obj.typ == nil)
 
 	check.later(func() {
 		check.validType(obj.typ, nil)
 	})
 
+	alias := tdecl.Assign.IsValid()
+	if alias && typeparams.Get(tdecl) != nil {
+		// The parser will ensure this but we may still get an invalid AST.
+		// Complain and continue as regular type definition.
+		check.error(atPos(tdecl.Assign), 0, "generic type cannot be alias")
+		alias = false
+	}
+
 	if alias {
+		// type alias declaration
+		if !check.allowVersion(check.pkg, 1, 9) {
+			check.errorf(atPos(tdecl.Assign), _BadDecl, "type aliases requires go1.9 or later")
+		}
 
 		obj.typ = Typ[Invalid]
-		obj.typ = check.typ(typ)
+		obj.typ = check.anyType(tdecl.Type)
 
 	} else {
+		// defined type declaration
 
-		named := &Named{obj: obj}
+		named := check.newNamed(obj, nil, nil)
 		def.setUnderlying(named)
 		obj.typ = named // make sure recursive type declarations terminate
 
+		if tparams := typeparams.Get(tdecl); tparams != nil {
+			check.openScope(tdecl, "type parameters")
+			defer check.closeScope()
+			named.tparams = check.collectTypeParams(tparams)
+		}
+
 		// determine underlying type of named
-		named.orig = check.definedType(typ, named)
+		named.orig = check.definedType(tdecl.Type, named)
 
 		// The underlying type of named may be itself a named type that is
 		// incomplete:
@@ -660,14 +718,85 @@
 		// and which has as its underlying type the named type B.
 		// Determine the (final, unnamed) underlying type by resolving
 		// any forward chain.
-		named.underlying = check.underlying(named)
-
+		// TODO(gri) Investigate if we can just use named.origin here
+		//           and rely on lazy computation of the underlying type.
+		named.underlying = under(named)
 	}
 
-	check.addMethodDecls(obj)
 }
 
-func (check *Checker) addMethodDecls(obj *TypeName) {
+func (check *Checker) collectTypeParams(list *ast.FieldList) (tparams []*TypeName) {
+	// Type parameter lists should not be empty. The parser will
+	// complain but we still may get an incorrect AST: ignore it.
+	if list.NumFields() == 0 {
+		return
+	}
+
+	// Declare type parameters up-front, with empty interface as type bound.
+	// The scope of type parameters starts at the beginning of the type parameter
+	// list (so we can have mutually recursive parameterized interfaces).
+	for _, f := range list.List {
+		tparams = check.declareTypeParams(tparams, f.Names)
+	}
+
+	setBoundAt := func(at int, bound Type) {
+		assert(IsInterface(bound))
+		tparams[at].typ.(*_TypeParam).bound = bound
+	}
+
+	index := 0
+	var bound Type
+	for _, f := range list.List {
+		if f.Type == nil {
+			goto next
+		}
+
+		// The predeclared identifier "any" is visible only as a constraint
+		// in a type parameter list. Look for it before general constraint
+		// resolution.
+		if tident, _ := unparen(f.Type).(*ast.Ident); tident != nil && tident.Name == "any" && check.lookup("any") == nil {
+			bound = universeAny
+		} else {
+			bound = check.typ(f.Type)
+		}
+
+		// type bound must be an interface
+		// TODO(gri) We should delay the interface check because
+		//           we may not have a complete interface yet:
+		//           type C(type T C) interface {}
+		//           (issue #39724).
+		if _, ok := under(bound).(*Interface); ok {
+			// Otherwise, set the bound for each type parameter.
+			for i := range f.Names {
+				setBoundAt(index+i, bound)
+			}
+		} else if bound != Typ[Invalid] {
+			check.errorf(f.Type, _Todo, "%s is not an interface", bound)
+		}
+
+	next:
+		index += len(f.Names)
+	}
+
+	return
+}
+
+func (check *Checker) declareTypeParams(tparams []*TypeName, names []*ast.Ident) []*TypeName {
+	for _, name := range names {
+		tpar := NewTypeName(name.Pos(), check.pkg, name.Name, nil)
+		check.newTypeParam(tpar, len(tparams), &emptyInterface) // assigns type to tpar as a side-effect
+		check.declare(check.scope, name, tpar, check.scope.pos) // TODO(gri) check scope position
+		tparams = append(tparams, tpar)
+	}
+
+	if trace && len(names) > 0 {
+		check.trace(names[0].Pos(), "type params = %v", tparams[len(tparams)-len(names):])
+	}
+
+	return tparams
+}
+
+func (check *Checker) collectMethods(obj *TypeName) {
 	// get associated methods
 	// (Checker.collectObjects only collects methods with non-blank names;
 	// Checker.resolveBaseTypeName ensures that obj is not an alias name
@@ -677,14 +806,14 @@
 		return
 	}
 	delete(check.methods, obj)
-	assert(!check.objMap[obj].alias) // don't use TypeName.IsAlias (requires fully set up object)
+	assert(!check.objMap[obj].tdecl.Assign.IsValid()) // don't use TypeName.IsAlias (requires fully set up object)
 
 	// use an objset to check for name conflicts
 	var mset objset
 
 	// spec: "If the base type is a struct type, the non-blank method
 	// and field names must be distinct."
-	base, _ := obj.typ.(*Named) // shouldn't fail but be conservative
+	base := asNamed(obj.typ) // shouldn't fail but be conservative
 	if base != nil {
 		if t, _ := base.underlying.(*Struct); t != nil {
 			for _, fld := range t.fields {
@@ -735,12 +864,18 @@
 
 	sig := new(Signature)
 	obj.typ = sig // guard against cycles
+
+	// Avoid cycle error when referring to method while type-checking the signature.
+	// This avoids a nuisance in the best case (non-parameterized receiver type) and
+	// since the method is not a type, we get an error. If we have a parameterized
+	// receiver type, instantiating the receiver type leads to the instantiation of
+	// its methods, and we don't want a cycle error in that case.
+	// TODO(gri) review if this is correct and/or whether we still need this?
+	saved := obj.color_
+	obj.color_ = black
 	fdecl := decl.fdecl
 	check.funcType(sig, fdecl.Recv, fdecl.Type)
-	if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) {
-		check.errorf(fdecl, _InvalidInitSig, "func init must have no arguments and no return values")
-		// ok to continue
-	}
+	obj.color_ = saved
 
 	// function body must be type-checked after global declarations
 	// (functions implemented elsewhere have no body)
@@ -846,7 +981,7 @@
 			check.declare(check.scope, d.spec.Name, obj, scopePos)
 			// mark and unmark type before calling typeDecl; its type is still nil (see Checker.objDecl)
 			obj.setColor(grey + color(check.push(obj)))
-			check.typeDecl(obj, d.spec.Type, nil, d.spec.Assign.IsValid())
+			check.typeDecl(obj, d.spec, nil)
 			check.pop().setColor(black)
 		default:
 			check.invalidAST(d.node(), "unknown ast.Decl node %T", d.node())
diff --git a/src/go/types/errorcodes.go b/src/go/types/errorcodes.go
index c01a12c..3d24da7 100644
--- a/src/go/types/errorcodes.go
+++ b/src/go/types/errorcodes.go
@@ -10,6 +10,8 @@
 // Collectively, these codes provide an identifier that may be used to
 // implement special handling for certain types of errors.
 //
+// Error code values should not be changed: add new codes at the end.
+//
 // Error codes should be fine-grained enough that the exact nature of the error
 // can be easily determined, but coarse enough that they are not an
 // implementation detail of the type checking algorithm. As a rule-of-thumb,
@@ -34,8 +36,6 @@
 	// _Test is reserved for errors that only apply while in self-test mode.
 	_Test
 
-	/* package names */
-
 	// _BlankPkgName occurs when a package name is the blank identifier "_".
 	//
 	// Per the spec:
@@ -55,8 +55,6 @@
 	//  var _ = fmt
 	_InvalidPkgUse
 
-	/* imports */
-
 	// _BadImportPath occurs when an import path is not valid.
 	_BadImportPath
 
@@ -81,8 +79,6 @@
 	//  func main() {}
 	_UnusedImport
 
-	/* initialization */
-
 	// _InvalidInitCycle occurs when an invalid cycle is detected within the
 	// initialization graph.
 	//
@@ -92,8 +88,6 @@
 	//  func f() int { return x }
 	_InvalidInitCycle
 
-	/* decls */
-
 	// _DuplicateDecl occurs when an identifier is declared multiple times.
 	//
 	// Example:
@@ -122,8 +116,6 @@
 	//  type T [unsafe.Sizeof(T{})]int
 	_InvalidTypeCycle
 
-	/* decls > const */
-
 	// _InvalidConstInit occurs when a const declaration has a non-constant
 	// initializer.
 	//
@@ -149,8 +141,6 @@
 	//  const c *int = 4
 	_InvalidConstType
 
-	/* decls > var (+ other variable assignment codes) */
-
 	// _UntypedNil occurs when the predeclared (untyped) value nil is used to
 	// initialize a variable declared without an explicit type.
 	//
@@ -159,7 +149,7 @@
 	_UntypedNil
 
 	// _WrongAssignCount occurs when the number of values on the right-hand side
-	// of an assignment or or initialization expression does not match the number
+	// of an assignment or initialization expression does not match the number
 	// of variables on the left-hand side.
 	//
 	// Example:
@@ -249,8 +239,6 @@
 	//  }
 	_UnaddressableFieldAssign
 
-	/* decls > type (+ other type expression codes) */
-
 	// _NotAType occurs when the identifier used as the underlying type in a type
 	// declaration or the right-hand side of a type alias does not denote a type.
 	//
@@ -320,8 +308,6 @@
 	//  }
 	_InvalidPtrEmbed
 
-	/* decls > func and method */
-
 	// _BadRecv occurs when a method declaration does not have exactly one
 	// receiver parameter.
 	//
@@ -358,8 +344,6 @@
 	//  func (T) m(i int) int { return i }
 	_DuplicateMethod
 
-	/* decls > special */
-
 	// _InvalidBlank occurs when a blank identifier is used as a value or type.
 	//
 	// Per the spec:
@@ -386,8 +370,8 @@
 	// _InvalidInitSig occurs when an init function declares parameters or
 	// results.
 	//
-	// Example:
-	//  func init() int { return 1 }
+	// Deprecated: no longer emitted by the type checker. _InvalidInitDecl is
+	// used instead.
 	_InvalidInitSig
 
 	// _InvalidInitDecl occurs when init is declared as anything other than a
@@ -395,14 +379,15 @@
 	//
 	// Example:
 	//  var init = 1
+	//
+	// Example:
+	//  func init() int { return 1 }
 	_InvalidInitDecl
 
 	// _InvalidMainDecl occurs when main is declared as anything other than a
 	// function, in a main package.
 	_InvalidMainDecl
 
-	/* exprs */
-
 	// _TooManyValues occurs when a function returns too many values for the
 	// expression context in which it is used.
 	//
@@ -425,8 +410,6 @@
 	//  }
 	_NotAnExpr
 
-	/* exprs > const */
-
 	// _TruncatedFloat occurs when a float constant is truncated to an integer
 	// value.
 	//
@@ -440,8 +423,6 @@
 	//  var x int8 = 1000
 	_NumericOverflow
 
-	/* exprs > operation */
-
 	// _UndefinedOp occurs when an operator is not defined for the type(s) used
 	// in an operation.
 	//
@@ -476,8 +457,6 @@
 	//  }
 	_NonNumericIncDec
 
-	/* exprs > ptr */
-
 	// _UnaddressableOperand occurs when the & operator is applied to an
 	// unaddressable expression.
 	//
@@ -493,8 +472,6 @@
 	//  var y = *x
 	_InvalidIndirection
 
-	/* exprs > [] */
-
 	// _NonIndexableOperand occurs when an index operation is applied to a value
 	// that cannot be indexed.
 	//
@@ -527,8 +504,6 @@
 	//  var _ = []int{1,2,3}[2:1]
 	_SwappedSliceIndices
 
-	/* operators > slice */
-
 	// _NonSliceableOperand occurs when a slice operation is applied to a value
 	// whose type is not sliceable, or is unaddressable.
 	//
@@ -548,8 +523,6 @@
 	//  var x = s[1:2:3]
 	_InvalidSliceExpr
 
-	/* exprs > shift */
-
 	// _InvalidShiftCount occurs when the right-hand side of a shift operation is
 	// either non-integer, negative, or too large.
 	//
@@ -567,8 +540,6 @@
 	//  var x = s << 2
 	_InvalidShiftOperand
 
-	/* exprs > chan */
-
 	// _InvalidReceive occurs when there is a channel receive from a value that
 	// is either not a channel, or is a send-only channel.
 	//
@@ -589,8 +560,6 @@
 	//  }
 	_InvalidSend
 
-	/* exprs > literal */
-
 	// _DuplicateLitKey occurs when an index is duplicated in a slice, array, or
 	// map literal.
 	//
@@ -680,8 +649,6 @@
 	//  var _ = P {}
 	_InvalidLit
 
-	/* exprs > selector */
-
 	// _AmbiguousSelector occurs when a selector is ambiguous.
 	//
 	// Example:
@@ -727,8 +694,6 @@
 	//  var x = T{}.f
 	_MissingFieldOrMethod
 
-	/* exprs > ... */
-
 	// _BadDotDotDotSyntax occurs when a "..." occurs in a context where it is
 	// not valid.
 	//
@@ -753,51 +718,13 @@
 	_NonVariadicDotDotDot
 
 	// _MisplacedDotDotDot occurs when a "..." is used somewhere other than the
-	// final argument to a function call.
+	// final argument in a function declaration.
 	//
 	// Example:
-	//  func printArgs(args ...int) {
-	//  	for _, a := range args {
-	//  		println(a)
-	//  	}
-	//  }
-	//
-	//  func f() {
-	//  	a := []int{1,2,3}
-	//  	printArgs(0, a...)
-	//  }
+	// 	func f(...int, int)
 	_MisplacedDotDotDot
 
-	// _InvalidDotDotDotOperand occurs when a "..." operator is applied to a
-	// single-valued operand.
-	//
-	// Example:
-	//  func printArgs(args ...int) {
-	//  	for _, a := range args {
-	//  		println(a)
-	//  	}
-	//  }
-	//
-	//  func f() {
-	//  	a := 1
-	//  	printArgs(a...)
-	//  }
-	//
-	// Example:
-	//  func args() (int, int) {
-	//  	return 1, 2
-	//  }
-	//
-	//  func printArgs(args ...int) {
-	//  	for _, a := range args {
-	//  		println(a)
-	//  	}
-	//  }
-	//
-	//  func g() {
-	//  	printArgs(args()...)
-	//  }
-	_InvalidDotDotDotOperand
+	_ // _InvalidDotDotDotOperand was removed.
 
 	// _InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in
 	// function.
@@ -807,8 +734,6 @@
 	//  var l = len(s...)
 	_InvalidDotDotDot
 
-	/* exprs > built-in */
-
 	// _UncalledBuiltin occurs when a built-in function is used as a
 	// function-valued expression, instead of being called.
 	//
@@ -920,8 +845,6 @@
 	//  var _ = real(int(1))
 	_InvalidReal
 
-	/* exprs > assertion */
-
 	// _InvalidAssert occurs when a type assertion is applied to a
 	// value that is not of interface type.
 	//
@@ -945,8 +868,6 @@
 	//  var _ = x.(T)
 	_ImpossibleAssert
 
-	/* exprs > conversion */
-
 	// _InvalidConversion occurs when the argument type cannot be converted to the
 	// target.
 	//
@@ -966,8 +887,6 @@
 	//  var _ = 1 + ""
 	_InvalidUntypedConversion
 
-	/* offsetof */
-
 	// _BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument
 	// that is not a selector expression.
 	//
@@ -1006,8 +925,6 @@
 	//  var _ = unsafe.Offsetof(s.m)
 	_InvalidOffsetof
 
-	/* control flow > scope */
-
 	// _UnusedExpr occurs when a side-effect free expression is used as a
 	// statement. Such a statement has no effect.
 	//
@@ -1055,8 +972,6 @@
 	//  }
 	_OutOfScopeResult
 
-	/* control flow > if */
-
 	// _InvalidCond occurs when an if condition is not a boolean expression.
 	//
 	// Example:
@@ -1067,8 +982,6 @@
 	//  }
 	_InvalidCond
 
-	/* control flow > for */
-
 	// _InvalidPostDecl occurs when there is a declaration in a for-loop post
 	// statement.
 	//
@@ -1078,17 +991,7 @@
 	//  }
 	_InvalidPostDecl
 
-	// _InvalidChanRange occurs when a send-only channel used in a range
-	// expression.
-	//
-	// Example:
-	//  func sum(c chan<- int) {
-	//  	s := 0
-	//  	for i := range c {
-	//  		s += i
-	//  	}
-	//  }
-	_InvalidChanRange
+	_ // _InvalidChanRange was removed.
 
 	// _InvalidIterVar occurs when two iteration variables are used while ranging
 	// over a channel.
@@ -1112,8 +1015,6 @@
 	//  }
 	_InvalidRangeExpr
 
-	/* control flow > switch */
-
 	// _MisplacedBreak occurs when a break statement is not within a for, switch,
 	// or select statement of the innermost function definition.
 	//
@@ -1217,8 +1118,6 @@
 	//  }
 	_InvalidExprSwitch
 
-	/* control flow > select */
-
 	// _InvalidSelectCase occurs when a select case is not a channel send or
 	// receive.
 	//
@@ -1233,8 +1132,6 @@
 	//  }
 	_InvalidSelectCase
 
-	/* control flow > labels and jumps */
-
 	// _UndeclaredLabel occurs when an undeclared label is jumped to.
 	//
 	// Example:
@@ -1302,8 +1199,6 @@
 	// }
 	_JumpIntoBlock
 
-	/* control flow > calls */
-
 	// _InvalidMethodExpr occurs when a pointer method is called but the argument
 	// is not addressable.
 	//
@@ -1331,8 +1226,6 @@
 	//  var y = x()
 	_InvalidCall
 
-	/* control flow > suspended */
-
 	// _UnusedResults occurs when a restricted expression-only built-in function
 	// is suspended via go or defer. Such a suspension discards the results of
 	// these side-effect free built-in functions, and therefore is ineffectual.
@@ -1363,4 +1256,61 @@
 	//  	return i
 	//  }
 	_InvalidGo
+
+	// All codes below were added in Go 1.17.
+
+	// _BadDecl occurs when a declaration has invalid syntax.
+	_BadDecl
+
+	// _RepeatedDecl occurs when an identifier occurs more than once on the left
+	// hand side of a short variable declaration.
+	//
+	// Example:
+	//  func _() {
+	//  	x, y, y := 1, 2, 3
+	//  }
+	_RepeatedDecl
+
+	// _InvalidUnsafeAdd occurs when unsafe.Add is called with a
+	// length argument that is not of integer type.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var p unsafe.Pointer
+	//  var _ = unsafe.Add(p, float64(1))
+	_InvalidUnsafeAdd
+
+	// _InvalidUnsafeSlice occurs when unsafe.Slice is called with a
+	// pointer argument that is not of pointer type or a length argument
+	// that is not of integer type, negative, or out of bounds.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(x, 1)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, float64(1))
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, -1)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, uint64(1) << 63)
+	_InvalidUnsafeSlice
+
+	// _Todo is a placeholder for error codes that have not been decided.
+	// TODO(rFindley) remove this error code after deciding on errors for generics code.
+	_Todo
 )
diff --git a/src/go/types/errors.go b/src/go/types/errors.go
index a219501..2263106 100644
--- a/src/go/types/errors.go
+++ b/src/go/types/errors.go
@@ -28,8 +28,13 @@
 func (check *Checker) qualifier(pkg *Package) string {
 	// Qualify the package unless it's the package being type-checked.
 	if pkg != check.pkg {
+		if check.pkgPathMap == nil {
+			check.pkgPathMap = make(map[string]map[string]bool)
+			check.seenPkgMap = make(map[*Package]bool)
+			check.markImports(check.pkg)
+		}
 		// If the same package name was used by multiple packages, display the full path.
-		if check.pkgCnt[pkg.name] > 1 {
+		if len(check.pkgPathMap[pkg.name]) > 1 {
 			return strconv.Quote(pkg.path)
 		}
 		return pkg.name
@@ -37,6 +42,26 @@
 	return ""
 }
 
+// markImports recursively walks pkg and its imports, to record unique import
+// paths in pkgPathMap.
+func (check *Checker) markImports(pkg *Package) {
+	if check.seenPkgMap[pkg] {
+		return
+	}
+	check.seenPkgMap[pkg] = true
+
+	forName, ok := check.pkgPathMap[pkg.name]
+	if !ok {
+		forName = make(map[string]bool)
+		check.pkgPathMap[pkg.name] = forName
+	}
+	forName[pkg.path] = true
+
+	for _, imp := range pkg.imports {
+		check.markImports(imp)
+	}
+}
+
 func (check *Checker) sprintf(format string, args ...interface{}) string {
 	for i, arg := range args {
 		switch a := arg.(type) {
@@ -89,15 +114,18 @@
 		return
 	}
 
-	if check.errpos != nil && isInternal {
-		// If we have an internal error and the errpos override is set, use it to
-		// augment our error positioning.
-		// TODO(rFindley) we may also want to augment the error message and refer
-		// to the position (pos) in the original expression.
-		span := spanOf(check.errpos)
-		e.Pos = span.pos
-		e.go116start = span.start
-		e.go116end = span.end
+	if isInternal {
+		e.Msg = stripAnnotations(e.Msg)
+		if check.errpos != nil {
+			// If we have an internal error and the errpos override is set, use it to
+			// augment our error positioning.
+			// TODO(rFindley) we may also want to augment the error message and refer
+			// to the position (pos) in the original expression.
+			span := spanOf(check.errpos)
+			e.Pos = span.pos
+			e.go116start = span.start
+			e.go116end = span.end
+		}
 		err = e
 	}
 
@@ -225,3 +253,18 @@
 		return posSpan{pos, pos, pos}
 	}
 }
+
+// stripAnnotations removes internal (type) annotations from s.
+func stripAnnotations(s string) string {
+	var b strings.Builder
+	for _, r := range s {
+		// strip #'s and subscript digits
+		if r != instanceMarker && !('₀' <= r && r < '₀'+10) { // '₀' == U+2080
+			b.WriteRune(r)
+		}
+	}
+	if b.Len() < len(s) {
+		return b.String()
+	}
+	return s
+}
diff --git a/src/go/types/errors_test.go b/src/go/types/errors_test.go
new file mode 100644
index 0000000..fdbe07c
--- /dev/null
+++ b/src/go/types/errors_test.go
@@ -0,0 +1,25 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import "testing"
+
+func TestStripAnnotations(t *testing.T) {
+	for _, test := range []struct {
+		in, want string
+	}{
+		{"", ""},
+		{"   ", "   "},
+		{"foo", "foo"},
+		{"foo₀", "foo"},
+		{"foo(T₀)", "foo(T)"},
+		{"#foo(T₀)", "foo(T)"},
+	} {
+		got := stripAnnotations(test.in)
+		if got != test.want {
+			t.Errorf("%q: got %q; want %q", test.in, got, test.want)
+		}
+	}
+}
diff --git a/src/go/types/eval_test.go b/src/go/types/eval_test.go
index d940bf0..41d3a61 100644
--- a/src/go/types/eval_test.go
+++ b/src/go/types/eval_test.go
@@ -76,7 +76,7 @@
 		`false == false`,
 		`12345678 + 87654321 == 99999999`,
 		`10 * 20 == 200`,
-		`(1<<1000)*2 >> 100 == 2<<900`,
+		`(1<<500)*2 >> 100 == 2<<400`,
 		`"foo" + "bar" == "foobar"`,
 		`"abc" <= "bcd"`,
 		`len([10]struct{}{}) == 2*5`,
@@ -155,9 +155,9 @@
 		import "io"
 		type R = io.Reader
 		func _() {
-			/* interface{R}.Read => , func(interface{io.Reader}, p []byte) (n int, err error) */
+			/* interface{R}.Read => , func(_ interface{io.Reader}, p []byte) (n int, err error) */
 			_ = func() {
-				/* interface{io.Writer}.Write => , func(interface{io.Writer}, p []byte) (n int, err error) */
+				/* interface{io.Writer}.Write => , func(_ interface{io.Writer}, p []byte) (n int, err error) */
 				type io interface {} // must not shadow io in line above
 			}
 			type R interface {} // must not shadow R in first line of this function body
diff --git a/src/go/types/example_test.go b/src/go/types/example_test.go
index 3747f3b..32a25a4 100644
--- a/src/go/types/example_test.go
+++ b/src/go/types/example_test.go
@@ -5,6 +5,7 @@
 // Only run where builders (build.golang.org) have
 // access to compiled packages for import.
 //
+//go:build !arm && !arm64
 // +build !arm,!arm64
 
 package types_test
diff --git a/src/go/types/expr.go b/src/go/types/expr.go
index eb20561..58962e7 100644
--- a/src/go/types/expr.go
+++ b/src/go/types/expr.go
@@ -10,6 +10,7 @@
 	"fmt"
 	"go/ast"
 	"go/constant"
+	"go/internal/typeparams"
 	"go/token"
 	"math"
 )
@@ -58,11 +59,16 @@
 
 type opPredicates map[token.Token]func(Type) bool
 
-var unaryOpPredicates = opPredicates{
-	token.ADD: isNumeric,
-	token.SUB: isNumeric,
-	token.XOR: isInteger,
-	token.NOT: isBoolean,
+var unaryOpPredicates opPredicates
+
+func init() {
+	// Setting unaryOpPredicates in init avoids declaration cycles.
+	unaryOpPredicates = opPredicates{
+		token.ADD: isNumeric,
+		token.SUB: isNumeric,
+		token.XOR: isInteger,
+		token.NOT: isBoolean,
+	}
 }
 
 func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool {
@@ -78,13 +84,77 @@
 	return true
 }
 
+// overflow checks that the constant x is representable by its type.
+// For untyped constants, it checks that the value doesn't become
+// arbitrarily large.
+func (check *Checker) overflow(x *operand, op token.Token, opPos token.Pos) {
+	assert(x.mode == constant_)
+
+	if x.val.Kind() == constant.Unknown {
+		// TODO(gri) We should report exactly what went wrong. At the
+		//           moment we don't have the (go/constant) API for that.
+		//           See also TODO in go/constant/value.go.
+		check.errorf(atPos(opPos), _InvalidConstVal, "constant result is not representable")
+		return
+	}
+
+	// Typed constants must be representable in
+	// their type after each constant operation.
+	if isTyped(x.typ) {
+		check.representable(x, asBasic(x.typ))
+		return
+	}
+
+	// Untyped integer values must not grow arbitrarily.
+	const prec = 512 // 512 is the constant precision
+	if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
+		check.errorf(atPos(opPos), _InvalidConstVal, "constant %s overflow", opName(x.expr))
+		x.val = constant.MakeUnknown()
+	}
+}
+
+// opName returns the name of an operation, or the empty string.
+// For now, only operations that might overflow are handled.
+// TODO(gri) Expand this to a general mechanism giving names to
+//           nodes?
+func opName(e ast.Expr) string {
+	switch e := e.(type) {
+	case *ast.BinaryExpr:
+		if int(e.Op) < len(op2str2) {
+			return op2str2[e.Op]
+		}
+	case *ast.UnaryExpr:
+		if int(e.Op) < len(op2str1) {
+			return op2str1[e.Op]
+		}
+	}
+	return ""
+}
+
+var op2str1 = [...]string{
+	token.XOR: "bitwise complement",
+}
+
+// This is only used for operations that may cause overflow.
+var op2str2 = [...]string{
+	token.ADD: "addition",
+	token.SUB: "subtraction",
+	token.XOR: "bitwise XOR",
+	token.MUL: "multiplication",
+	token.SHL: "shift",
+}
+
 // The unary expression e may be nil. It's passed in for better error messages only.
-func (check *Checker) unary(x *operand, e *ast.UnaryExpr, op token.Token) {
-	switch op {
+func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
+	check.expr(x, e.X)
+	if x.mode == invalid {
+		return
+	}
+	switch e.Op {
 	case token.AND:
 		// spec: "As an exception to the addressability
 		// requirement x may also be a composite literal."
-		if _, ok := unparen(x.expr).(*ast.CompositeLit); !ok && x.mode != variable {
+		if _, ok := unparen(e.X).(*ast.CompositeLit); !ok && x.mode != variable {
 			check.invalidOp(x, _UnaddressableOperand, "cannot take address of %s", x)
 			x.mode = invalid
 			return
@@ -94,8 +164,8 @@
 		return
 
 	case token.ARROW:
-		typ, ok := x.typ.Underlying().(*Chan)
-		if !ok {
+		typ := asChan(x.typ)
+		if typ == nil {
 			check.invalidOp(x, _InvalidReceive, "cannot receive from non-channel %s", x)
 			x.mode = invalid
 			return
@@ -111,26 +181,23 @@
 		return
 	}
 
-	if !check.op(unaryOpPredicates, x, op) {
+	if !check.op(unaryOpPredicates, x, e.Op) {
 		x.mode = invalid
 		return
 	}
 
 	if x.mode == constant_ {
-		typ := x.typ.Underlying().(*Basic)
+		if x.val.Kind() == constant.Unknown {
+			// nothing to do (and don't cause an error below in the overflow check)
+			return
+		}
 		var prec uint
-		if isUnsigned(typ) {
-			prec = uint(check.conf.sizeof(typ) * 8)
+		if isUnsigned(x.typ) {
+			prec = uint(check.conf.sizeof(x.typ) * 8)
 		}
-		x.val = constant.UnaryOp(op, x.val, prec)
-		// Typed constants must be representable in
-		// their type after each constant operation.
-		if isTyped(typ) {
-			if e != nil {
-				x.expr = e // for better error message
-			}
-			check.representable(x, typ)
-		}
+		x.val = constant.UnaryOp(e.Op, x.val, prec)
+		x.expr = e
+		check.overflow(x, e.Op, x.Pos())
 		return
 	}
 
@@ -332,17 +399,24 @@
 // representable checks that a constant operand is representable in the given
 // basic type.
 func (check *Checker) representable(x *operand, typ *Basic) {
-	if err := check.isRepresentable(x, typ); err != nil {
+	v, code := check.representation(x, typ)
+	if code != 0 {
+		check.invalidConversion(code, x, typ)
 		x.mode = invalid
-		check.err(err)
+		return
 	}
+	assert(v != nil)
+	x.val = v
 }
 
-func (check *Checker) isRepresentable(x *operand, typ *Basic) error {
+// representation returns the representation of the constant operand x as the
+// basic type typ.
+//
+// If no such representation is possible, it returns a non-zero error code.
+func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, errorCode) {
 	assert(x.mode == constant_)
-	if !representableConst(x.val, check, typ, &x.val) {
-		var msg string
-		var code errorCode
+	v := x.val
+	if !representableConst(x.val, check, typ, &v) {
 		if isNumeric(x.typ) && isNumeric(typ) {
 			// numeric conversion : error msg
 			//
@@ -352,19 +426,25 @@
 			// float   -> float   : overflows
 			//
 			if !isInteger(x.typ) && isInteger(typ) {
-				msg = "%s truncated to %s"
-				code = _TruncatedFloat
+				return nil, _TruncatedFloat
 			} else {
-				msg = "%s overflows %s"
-				code = _NumericOverflow
+				return nil, _NumericOverflow
 			}
-		} else {
-			msg = "cannot convert %s to %s"
-			code = _InvalidConstVal
 		}
-		return check.newErrorf(x, code, false, msg, x, typ)
+		return nil, _InvalidConstVal
 	}
-	return nil
+	return v, 0
+}
+
+func (check *Checker) invalidConversion(code errorCode, x *operand, target Type) {
+	msg := "cannot convert %s to %s"
+	switch code {
+	case _TruncatedFloat:
+		msg = "%s truncated to %s"
+	case _NumericOverflow:
+		msg = "%s overflows %s"
+	}
+	check.errorf(x, code, msg, x, target)
 }
 
 // updateExprType updates the type of x to typ and invokes itself
@@ -456,7 +536,7 @@
 	// If the new type is not final and still untyped, just
 	// update the recorded type.
 	if !final && isUntyped(typ) {
-		old.typ = typ.Underlying().(*Basic)
+		old.typ = asBasic(typ)
 		check.untyped[x] = old
 		return
 	}
@@ -500,15 +580,32 @@
 
 // convertUntyped attempts to set the type of an untyped value to the target type.
 func (check *Checker) convertUntyped(x *operand, target Type) {
-	if err := check.canConvertUntyped(x, target); err != nil {
+	newType, val, code := check.implicitTypeAndValue(x, target)
+	if code != 0 {
+		check.invalidConversion(code, x, target.Underlying())
 		x.mode = invalid
-		check.err(err)
+		return
+	}
+	if val != nil {
+		x.val = val
+		check.updateExprVal(x.expr, val)
+	}
+	if newType != x.typ {
+		x.typ = newType
+		check.updateExprType(x.expr, newType, false)
 	}
 }
 
-func (check *Checker) canConvertUntyped(x *operand, target Type) error {
+// implicitTypeAndValue returns the implicit type of x when used in a context
+// where the target type is expected. If no such implicit conversion is
+// possible, it returns a nil Type and non-zero error code.
+//
+// If x is a constant operand, the returned constant.Value will be the
+// representation of x in this context.
+func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, errorCode) {
+	target = expand(target)
 	if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
-		return nil
+		return x.typ, nil, 0
 	}
 
 	if isUntyped(target) {
@@ -517,43 +614,23 @@
 		tkind := target.(*Basic).kind
 		if isNumeric(x.typ) && isNumeric(target) {
 			if xkind < tkind {
-				x.typ = target
-				check.updateExprType(x.expr, target, false)
+				return target, nil, 0
 			}
 		} else if xkind != tkind {
-			return check.newErrorf(x, _InvalidUntypedConversion, false, "cannot convert %s to %s", x, target)
+			return nil, nil, _InvalidUntypedConversion
 		}
-		return nil
+		return x.typ, nil, 0
 	}
 
-	if t, ok := target.Underlying().(*Basic); ok && x.mode == constant_ {
-		if err := check.isRepresentable(x, t); err != nil {
-			return err
-		}
-		// Expression value may have been rounded - update if needed.
-		check.updateExprVal(x.expr, x.val)
-	} else {
-		newTarget := check.implicitType(x, target)
-		if newTarget == nil {
-			return check.newErrorf(x, _InvalidUntypedConversion, false, "cannot convert %s to %s", x, target)
-		}
-		target = newTarget
-	}
-	x.typ = target
-	// Even though implicitType can return UntypedNil, this value is final: the
-	// predeclared identifier nil has no type.
-	check.updateExprType(x.expr, target, true)
-	return nil
-}
-
-// implicitType returns the implicit type of x when used in a context where the
-// target type is expected. If no such implicit conversion is possible, it
-// returns nil.
-func (check *Checker) implicitType(x *operand, target Type) Type {
-	assert(isUntyped(x.typ))
-	switch t := target.Underlying().(type) {
+	switch t := optype(target).(type) {
 	case *Basic:
-		assert(x.mode != constant_)
+		if x.mode == constant_ {
+			v, code := check.representation(x, t)
+			if code != 0 {
+				return nil, nil, code
+			}
+			return target, v, code
+		}
 		// Non-constant untyped values may appear as the
 		// result of comparisons (untyped bool), intermediate
 		// (delayed-checked) rhs operands of shifts, and as
@@ -561,26 +638,40 @@
 		switch x.typ.(*Basic).kind {
 		case UntypedBool:
 			if !isBoolean(target) {
-				return nil
+				return nil, nil, _InvalidUntypedConversion
 			}
 		case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
 			if !isNumeric(target) {
-				return nil
+				return nil, nil, _InvalidUntypedConversion
 			}
 		case UntypedString:
 			// Non-constant untyped string values are not permitted by the spec and
 			// should not occur during normal typechecking passes, but this path is
 			// reachable via the AssignableTo API.
 			if !isString(target) {
-				return nil
+				return nil, nil, _InvalidUntypedConversion
 			}
 		case UntypedNil:
 			// Unsafe.Pointer is a basic type that includes nil.
 			if !hasNil(target) {
-				return nil
+				return nil, nil, _InvalidUntypedConversion
 			}
+			// Preserve the type of nil as UntypedNil: see #13061.
+			return Typ[UntypedNil], nil, 0
 		default:
-			return nil
+			return nil, nil, _InvalidUntypedConversion
+		}
+	case *_Sum:
+		ok := t.is(func(t Type) bool {
+			target, _, _ := check.implicitTypeAndValue(x, t)
+			return target != nil
+		})
+		if !ok {
+			return nil, nil, _InvalidUntypedConversion
+		}
+		// keep nil untyped (was bug #39755)
+		if x.isNil() {
+			return Typ[UntypedNil], nil, 0
 		}
 	case *Interface:
 		// Values must have concrete dynamic types. If the value is nil,
@@ -588,24 +679,24 @@
 		// need the dynamic type for argument checking of say, print
 		// functions)
 		if x.isNil() {
-			return Typ[UntypedNil]
+			return Typ[UntypedNil], nil, 0
 		}
 		// cannot assign untyped values to non-empty interfaces
-		check.completeInterface(t)
+		check.completeInterface(token.NoPos, t)
 		if !t.Empty() {
-			return nil
+			return nil, nil, _InvalidUntypedConversion
 		}
-		return Default(x.typ)
+		return Default(x.typ), nil, 0
 	case *Pointer, *Signature, *Slice, *Map, *Chan:
 		if !x.isNil() {
-			return nil
+			return nil, nil, _InvalidUntypedConversion
 		}
 		// Keep nil untyped - see comment for interfaces, above.
-		return Typ[UntypedNil]
+		return Typ[UntypedNil], nil, 0
 	default:
-		return nil
+		return nil, nil, _InvalidUntypedConversion
 	}
-	return target
+	return target, nil, 0
 }
 
 func (check *Checker) comparison(x, y *operand, op token.Token) {
@@ -665,15 +756,16 @@
 	x.typ = Typ[UntypedBool]
 }
 
-func (check *Checker) shift(x, y *operand, e *ast.BinaryExpr, op token.Token) {
-	untypedx := isUntyped(x.typ)
+// If e != nil, it must be the shift expression; it may be nil for non-constant shifts.
+func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
+	// TODO(gri) This function seems overly complex. Revisit.
 
 	var xval constant.Value
 	if x.mode == constant_ {
 		xval = constant.ToInt(x.val)
 	}
 
-	if isInteger(x.typ) || untypedx && xval != nil && xval.Kind() == constant.Int {
+	if isInteger(x.typ) || isUntyped(x.typ) && xval != nil && xval.Kind() == constant.Int {
 		// The lhs is of integer type or an untyped constant representable
 		// as an integer. Nothing to do.
 	} else {
@@ -685,10 +777,40 @@
 
 	// spec: "The right operand in a shift expression must have integer type
 	// or be an untyped constant representable by a value of type uint."
+
+	// Check that constants are representable by uint, but do not convert them
+	// (see also issue #47243).
+	if y.mode == constant_ {
+		// Provide a good error message for negative shift counts.
+		yval := constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
+		if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
+			check.invalidOp(y, _InvalidShiftCount, "negative shift count %s", y)
+			x.mode = invalid
+			return
+		}
+
+		if isUntyped(y.typ) {
+			// Caution: Check for representability here, rather than in the switch
+			// below, because isInteger includes untyped integers (was bug #43697).
+			check.representable(y, Typ[Uint])
+			if y.mode == invalid {
+				x.mode = invalid
+				return
+			}
+		}
+	}
+
+	// Check that RHS is otherwise at least of integer type.
 	switch {
 	case isInteger(y.typ):
-		// nothing to do
+		if !isUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
+			check.invalidOp(y, _InvalidShiftCount, "signed shift count %s requires go1.13 or later", y)
+			x.mode = invalid
+			return
+		}
 	case isUntyped(y.typ):
+		// This is incorrect, but preserves pre-existing behavior.
+		// See also bug #47410.
 		check.convertUntyped(y, Typ[Uint])
 		if y.mode == invalid {
 			x.mode = invalid
@@ -700,25 +822,20 @@
 		return
 	}
 
-	var yval constant.Value
-	if y.mode == constant_ {
-		// rhs must be an integer value
-		// (Either it was of an integer type already, or it was
-		// untyped and successfully converted to a uint above.)
-		yval = constant.ToInt(y.val)
-		assert(yval.Kind() == constant.Int)
-		if constant.Sign(yval) < 0 {
-			check.invalidOp(y, _InvalidShiftCount, "negative shift count %s", y)
-			x.mode = invalid
-			return
-		}
-	}
-
 	if x.mode == constant_ {
 		if y.mode == constant_ {
+			// if either x or y has an unknown value, the result is unknown
+			if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
+				x.val = constant.MakeUnknown()
+				// ensure the correct type - see comment below
+				if !isInteger(x.typ) {
+					x.typ = Typ[UntypedInt]
+				}
+				return
+			}
 			// rhs must be within reasonable bounds in constant shifts
-			const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64
-			s, ok := constant.Uint64Val(yval)
+			const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 (see issue #44057)
+			s, ok := constant.Uint64Val(y.val)
 			if !ok || s > shiftBound {
 				check.invalidOp(y, _InvalidShiftCount, "invalid shift count %s", y)
 				x.mode = invalid
@@ -733,19 +850,17 @@
 			}
 			// x is a constant so xval != nil and it must be of Int kind.
 			x.val = constant.Shift(xval, op, uint(s))
-			// Typed constants must be representable in
-			// their type after each constant operation.
-			if isTyped(x.typ) {
-				if e != nil {
-					x.expr = e // for better error message
-				}
-				check.representable(x, x.typ.Underlying().(*Basic))
+			x.expr = e
+			opPos := x.Pos()
+			if b, _ := e.(*ast.BinaryExpr); b != nil {
+				opPos = b.OpPos
 			}
+			check.overflow(x, op, opPos)
 			return
 		}
 
 		// non-constant shift with constant lhs
-		if untypedx {
+		if isUntyped(x.typ) {
 			// spec: "If the left operand of a non-constant shift
 			// expression is an untyped constant, the type of the
 			// constant is what it would be if the shift expression
@@ -785,24 +900,30 @@
 	x.mode = value
 }
 
-var binaryOpPredicates = opPredicates{
-	token.ADD: func(typ Type) bool { return isNumeric(typ) || isString(typ) },
-	token.SUB: isNumeric,
-	token.MUL: isNumeric,
-	token.QUO: isNumeric,
-	token.REM: isInteger,
+var binaryOpPredicates opPredicates
 
-	token.AND:     isInteger,
-	token.OR:      isInteger,
-	token.XOR:     isInteger,
-	token.AND_NOT: isInteger,
+func init() {
+	// Setting binaryOpPredicates in init avoids declaration cycles.
+	binaryOpPredicates = opPredicates{
+		token.ADD: isNumericOrString,
+		token.SUB: isNumeric,
+		token.MUL: isNumeric,
+		token.QUO: isNumeric,
+		token.REM: isInteger,
 
-	token.LAND: isBoolean,
-	token.LOR:  isBoolean,
+		token.AND:     isInteger,
+		token.OR:      isInteger,
+		token.XOR:     isInteger,
+		token.AND_NOT: isInteger,
+
+		token.LAND: isBoolean,
+		token.LOR:  isBoolean,
+	}
 }
 
-// The binary expression e may be nil. It's passed in for better error messages only.
-func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, op token.Token, opPos token.Pos) {
+// If e != nil, it must be the binary expression; it may be nil for non-constant expressions
+// (when invoked for an assignment operation where the binary expression is implicit).
+func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token.Token, opPos token.Pos) {
 	var y operand
 
 	check.expr(x, lhs)
@@ -877,30 +998,19 @@
 	}
 
 	if x.mode == constant_ && y.mode == constant_ {
-		xval := x.val
-		yval := y.val
-		typ := x.typ.Underlying().(*Basic)
+		// if either x or y has an unknown value, the result is unknown
+		if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
+			x.val = constant.MakeUnknown()
+			// x.typ is unchanged
+			return
+		}
 		// force integer division of integer operands
-		if op == token.QUO && isInteger(typ) {
+		if op == token.QUO && isInteger(x.typ) {
 			op = token.QUO_ASSIGN
 		}
-		x.val = constant.BinaryOp(xval, op, yval)
-		// report error if valid operands lead to an invalid result
-		if xval.Kind() != constant.Unknown && yval.Kind() != constant.Unknown && x.val.Kind() == constant.Unknown {
-			// TODO(gri) We should report exactly what went wrong. At the
-			//           moment we don't have the (go/constant) API for that.
-			//           See also TODO in go/constant/value.go.
-			check.errorf(atPos(opPos), _InvalidConstVal, "constant result is not representable")
-			// TODO(gri) Should we mark operands with unknown values as invalid?
-		}
-		// Typed constants must be representable in
-		// their type after each constant operation.
-		if isTyped(typ) {
-			if e != nil {
-				x.expr = e // for better error message
-			}
-			check.representable(x, typ)
-		}
+		x.val = constant.BinaryOp(x.val, op, y.val)
+		x.expr = e
+		check.overflow(x, op, opPos)
 		return
 	}
 
@@ -908,100 +1018,6 @@
 	// x.typ is unchanged
 }
 
-// index checks an index expression for validity.
-// If max >= 0, it is the upper bound for index.
-// If the result typ is != Typ[Invalid], index is valid and typ is its (possibly named) integer type.
-// If the result val >= 0, index is valid and val is its constant int value.
-func (check *Checker) index(index ast.Expr, max int64) (typ Type, val int64) {
-	typ = Typ[Invalid]
-	val = -1
-
-	var x operand
-	check.expr(&x, index)
-	if x.mode == invalid {
-		return
-	}
-
-	// an untyped constant must be representable as Int
-	check.convertUntyped(&x, Typ[Int])
-	if x.mode == invalid {
-		return
-	}
-
-	// the index must be of integer type
-	if !isInteger(x.typ) {
-		check.invalidArg(&x, _InvalidIndex, "index %s must be integer", &x)
-		return
-	}
-
-	if x.mode != constant_ {
-		return x.typ, -1
-	}
-
-	// a constant index i must be in bounds
-	if constant.Sign(x.val) < 0 {
-		check.invalidArg(&x, _InvalidIndex, "index %s must not be negative", &x)
-		return
-	}
-
-	v, valid := constant.Int64Val(constant.ToInt(x.val))
-	if !valid || max >= 0 && v >= max {
-		check.errorf(&x, _InvalidIndex, "index %s is out of bounds", &x)
-		return
-	}
-
-	// 0 <= v [ && v < max ]
-	return Typ[Int], v
-}
-
-// indexElts checks the elements (elts) of an array or slice composite literal
-// against the literal's element type (typ), and the element indices against
-// the literal length if known (length >= 0). It returns the length of the
-// literal (maximum index value + 1).
-//
-func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 {
-	visited := make(map[int64]bool, len(elts))
-	var index, max int64
-	for _, e := range elts {
-		// determine and check index
-		validIndex := false
-		eval := e
-		if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
-			if typ, i := check.index(kv.Key, length); typ != Typ[Invalid] {
-				if i >= 0 {
-					index = i
-					validIndex = true
-				} else {
-					check.errorf(e, _InvalidLitIndex, "index %s must be integer constant", kv.Key)
-				}
-			}
-			eval = kv.Value
-		} else if length >= 0 && index >= length {
-			check.errorf(e, _OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
-		} else {
-			validIndex = true
-		}
-
-		// if we have a valid index, check for duplicate entries
-		if validIndex {
-			if visited[index] {
-				check.errorf(e, _DuplicateLitKey, "duplicate index %d in array or slice literal", index)
-			}
-			visited[index] = true
-		}
-		index++
-		if index > max {
-			max = index
-		}
-
-		// check element against composite literal element type
-		var x operand
-		check.exprWithHint(&x, eval, typ)
-		check.assignment(&x, typ, "array or slice literal")
-	}
-	return max
-}
-
 // exprKind describes the kind of an expression; the kind
 // determines if an expression is valid in 'statement context'.
 type exprKind int
@@ -1018,7 +1034,7 @@
 //
 func (check *Checker) rawExpr(x *operand, e ast.Expr, hint Type) exprKind {
 	if trace {
-		check.trace(e.Pos(), "%s", e)
+		check.trace(e.Pos(), "expr %s", e)
 		check.indent++
 		defer func() {
 			check.indent--
@@ -1027,31 +1043,7 @@
 	}
 
 	kind := check.exprInternal(x, e, hint)
-
-	// convert x into a user-friendly set of values
-	// TODO(gri) this code can be simplified
-	var typ Type
-	var val constant.Value
-	switch x.mode {
-	case invalid:
-		typ = Typ[Invalid]
-	case novalue:
-		typ = (*Tuple)(nil)
-	case constant_:
-		typ = x.typ
-		val = x.val
-	default:
-		typ = x.typ
-	}
-	assert(x.expr != nil && typ != nil)
-
-	if isUntyped(typ) {
-		// delay type and value recording until we know the type
-		// or until the end of type checking
-		check.rememberUntyped(x.expr, false, x.mode, typ.(*Basic), val)
-	} else {
-		check.recordTypeAndValue(e, x.mode, typ, val)
-	}
+	check.record(x)
 
 	return kind
 }
@@ -1079,6 +1071,24 @@
 		goto Error
 
 	case *ast.BasicLit:
+		switch e.Kind {
+		case token.INT, token.FLOAT, token.IMAG:
+			check.langCompat(e)
+			// The max. mantissa precision for untyped numeric values
+			// is 512 bits, or 4048 bits for each of the two integer
+			// parts of a fraction for floating-point numbers that are
+			// represented accurately in the go/constant package.
+			// Constant literals that are longer than this many bits
+			// are not meaningful; and excessively long constants may
+			// consume a lot of space and time for a useless conversion.
+			// Cap constant length with a generous upper limit that also
+			// allows for separators between all digits.
+			const limit = 10000
+			if len(e.Value) > limit {
+				check.errorf(e, _InvalidConstVal, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
+				goto Error
+			}
+		}
 		x.setConst(e.Kind, e.Value)
 		if x.mode == invalid {
 			// The parser already establishes syntactic correctness.
@@ -1091,18 +1101,20 @@
 
 	case *ast.FuncLit:
 		if sig, ok := check.typ(e.Type).(*Signature); ok {
-			// Anonymous functions are considered part of the
-			// init expression/func declaration which contains
-			// them: use existing package-level declaration info.
-			decl := check.decl // capture for use in closure below
-			iota := check.iota // capture for use in closure below (#22345)
-			// Don't type-check right away because the function may
-			// be part of a type definition to which the function
-			// body refers. Instead, type-check as soon as possible,
-			// but before the enclosing scope contents changes (#22992).
-			check.later(func() {
-				check.funcBody(decl, "<function literal>", sig, e.Body, iota)
-			})
+			if !check.conf.IgnoreFuncBodies && e.Body != nil {
+				// Anonymous functions are considered part of the
+				// init expression/func declaration which contains
+				// them: use existing package-level declaration info.
+				decl := check.decl // capture for use in closure below
+				iota := check.iota // capture for use in closure below (#22345)
+				// Don't type-check right away because the function may
+				// be part of a type definition to which the function
+				// body refers. Instead, type-check as soon as possible,
+				// but before the enclosing scope contents changes (#22992).
+				check.later(func() {
+					check.funcBody(decl, "<function literal>", sig, e.Body, iota)
+				})
+			}
 			x.mode = value
 			x.typ = sig
 		} else {
@@ -1123,7 +1135,7 @@
 					// We have an "open" [...]T array type.
 					// Create a new ArrayType with unknown length (-1)
 					// and finish setting it up after analyzing the literal.
-					typ = &Array{len: -1, elem: check.typ(atyp.Elt)}
+					typ = &Array{len: -1, elem: check.varType(atyp.Elt)}
 					base = typ
 					break
 				}
@@ -1134,7 +1146,7 @@
 		case hint != nil:
 			// no composite literal type present - use hint (element type of enclosing type)
 			typ = hint
-			base, _ = deref(typ.Underlying()) // *T implies &T{}
+			base, _ = deref(under(typ)) // *T implies &T{}
 
 		default:
 			// TODO(gri) provide better error messages depending on context
@@ -1142,7 +1154,7 @@
 			goto Error
 		}
 
-		switch utyp := base.Underlying().(type) {
+		switch utyp := optype(base).(type) {
 		case *Struct:
 			if len(e.Elts) == 0 {
 				break
@@ -1270,7 +1282,7 @@
 					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 {
+					if asInterface(utyp.key) != nil {
 						for _, vtyp := range visited[xkey] {
 							if check.identical(vtyp, x.typ) {
 								duplicate = true
@@ -1322,184 +1334,30 @@
 		check.selector(x, e)
 
 	case *ast.IndexExpr:
-		check.expr(x, e.X)
+		if check.indexExpr(x, e) {
+			check.funcInst(x, e)
+		}
 		if x.mode == invalid {
-			check.use(e.Index)
 			goto Error
 		}
 
-		valid := false
-		length := int64(-1) // valid if >= 0
-		switch typ := x.typ.Underlying().(type) {
-		case *Basic:
-			if isString(typ) {
-				valid = true
-				if x.mode == constant_ {
-					length = int64(len(constant.StringVal(x.val)))
-				}
-				// an indexed string always yields a byte value
-				// (not a constant) even if the string and the
-				// index are constant
-				x.mode = value
-				x.typ = universeByte // use 'byte' name
-			}
-
-		case *Array:
-			valid = true
-			length = typ.len
-			if x.mode != variable {
-				x.mode = value
-			}
-			x.typ = typ.elem
-
-		case *Pointer:
-			if typ, _ := typ.base.Underlying().(*Array); typ != nil {
-				valid = true
-				length = typ.len
-				x.mode = variable
-				x.typ = typ.elem
-			}
-
-		case *Slice:
-			valid = true
-			x.mode = variable
-			x.typ = typ.elem
-
-		case *Map:
-			var key operand
-			check.expr(&key, e.Index)
-			check.assignment(&key, typ.key, "map index")
-			// ok to continue even if indexing failed - map element type is known
-			x.mode = mapindex
-			x.typ = typ.elem
-			x.expr = e
-			return expression
-		}
-
-		if !valid {
-			check.invalidOp(x, _NonIndexableOperand, "cannot index %s", x)
-			goto Error
-		}
-
-		if e.Index == nil {
-			check.invalidAST(e, "missing index for %s", x)
-			goto Error
-		}
-
-		check.index(e.Index, length)
-		// ok to continue
-
 	case *ast.SliceExpr:
-		check.expr(x, e.X)
+		check.sliceExpr(x, e)
 		if x.mode == invalid {
-			check.use(e.Low, e.High, e.Max)
 			goto Error
 		}
 
-		valid := false
-		length := int64(-1) // valid if >= 0
-		switch typ := x.typ.Underlying().(type) {
-		case *Basic:
-			if isString(typ) {
-				if e.Slice3 {
-					check.invalidOp(x, _InvalidSliceExpr, "3-index slice of string")
-					goto Error
-				}
-				valid = true
-				if x.mode == constant_ {
-					length = int64(len(constant.StringVal(x.val)))
-				}
-				// spec: "For untyped string operands the result
-				// is a non-constant value of type string."
-				if typ.kind == UntypedString {
-					x.typ = Typ[String]
-				}
-			}
-
-		case *Array:
-			valid = true
-			length = typ.len
-			if x.mode != variable {
-				check.invalidOp(x, _NonSliceableOperand, "cannot slice %s (value not addressable)", x)
-				goto Error
-			}
-			x.typ = &Slice{elem: typ.elem}
-
-		case *Pointer:
-			if typ, _ := typ.base.Underlying().(*Array); typ != nil {
-				valid = true
-				length = typ.len
-				x.typ = &Slice{elem: typ.elem}
-			}
-
-		case *Slice:
-			valid = true
-			// x.typ doesn't change
-		}
-
-		if !valid {
-			check.invalidOp(x, _NonSliceableOperand, "cannot slice %s", x)
-			goto Error
-		}
-
-		x.mode = value
-
-		// spec: "Only the first index may be omitted; it defaults to 0."
-		if e.Slice3 && (e.High == nil || e.Max == nil) {
-			check.invalidAST(inNode(e, e.Rbrack), "2nd and 3rd index required in 3-index slice")
-			goto Error
-		}
-
-		// check indices
-		var ind [3]int64
-		for i, expr := range []ast.Expr{e.Low, e.High, e.Max} {
-			x := int64(-1)
-			switch {
-			case expr != nil:
-				// The "capacity" is only known statically for strings, arrays,
-				// and pointers to arrays, and it is the same as the length for
-				// those types.
-				max := int64(-1)
-				if length >= 0 {
-					max = length + 1
-				}
-				if _, v := check.index(expr, max); v >= 0 {
-					x = v
-				}
-			case i == 0:
-				// default is 0 for the first index
-				x = 0
-			case length >= 0:
-				// default is length (== capacity) otherwise
-				x = length
-			}
-			ind[i] = x
-		}
-
-		// constant indices must be in range
-		// (check.index already checks that existing indices >= 0)
-	L:
-		for i, x := range ind[:len(ind)-1] {
-			if x > 0 {
-				for _, y := range ind[i+1:] {
-					if y >= 0 && x > y {
-						check.errorf(inNode(e, e.Rbrack), _SwappedSliceIndices, "swapped slice indices: %d > %d", x, y)
-						break L // only report one error, ok to continue
-					}
-				}
-			}
-		}
-
 	case *ast.TypeAssertExpr:
 		check.expr(x, e.X)
 		if x.mode == invalid {
 			goto Error
 		}
-		xtyp, _ := x.typ.Underlying().(*Interface)
+		xtyp, _ := under(x.typ).(*Interface)
 		if xtyp == nil {
 			check.invalidOp(x, _InvalidAssert, "%s is not an interface", x)
 			goto Error
 		}
+		check.ordinaryType(x, xtyp)
 		// x.(type) expressions are handled explicitly in type switches
 		if e.Type == nil {
 			// Don't use invalidAST because this can occur in the AST produced by
@@ -1507,7 +1365,7 @@
 			check.error(e, _BadTypeKeyword, "use of .(type) outside type switch")
 			goto Error
 		}
-		T := check.typ(e.Type)
+		T := check.varType(e.Type)
 		if T == Typ[Invalid] {
 			goto Error
 		}
@@ -1516,7 +1374,7 @@
 		x.typ = T
 
 	case *ast.CallExpr:
-		return check.call(x, e)
+		return check.callExpr(x, e)
 
 	case *ast.StarExpr:
 		check.exprOrType(x, e.X)
@@ -1526,7 +1384,7 @@
 		case typexpr:
 			x.typ = &Pointer{base: x.typ}
 		default:
-			if typ, ok := x.typ.Underlying().(*Pointer); ok {
+			if typ := asPointer(x.typ); typ != nil {
 				x.mode = variable
 				x.typ = typ.base
 			} else {
@@ -1536,11 +1394,7 @@
 		}
 
 	case *ast.UnaryExpr:
-		check.expr(x, e.X)
-		if x.mode == invalid {
-			goto Error
-		}
-		check.unary(x, e, e.Op)
+		check.unary(x, e)
 		if x.mode == invalid {
 			goto Error
 		}
@@ -1571,7 +1425,12 @@
 		// types, which are comparatively rare.
 
 	default:
-		panic(fmt.Sprintf("%s: unknown expression type %T", check.fset.Position(e.Pos()), e))
+		if typeparams.IsListExpr(e) {
+			// catch-all for unexpected expression lists
+			check.errorf(e, _Todo, "unexpected list of expressions")
+		} else {
+			panic(fmt.Sprintf("%s: unknown expression type %T", check.fset.Position(e.Pos()), e))
+		}
 	}
 
 	// everything went well
@@ -1627,46 +1486,20 @@
 	check.errorf(at, _ImpossibleAssert, "%s cannot have dynamic type %s (%s)", x, T, msg)
 }
 
-func (check *Checker) singleValue(x *operand) {
-	if x.mode == value {
-		// tuple types are never named - no need for underlying type below
-		if t, ok := x.typ.(*Tuple); ok {
-			assert(t.Len() != 1)
-			check.errorf(x, _TooManyValues, "%d-valued %s where single value is expected", t.Len(), x)
-			x.mode = invalid
-		}
-	}
-}
-
 // expr typechecks expression e and initializes x with the expression value.
 // The result must be a single value.
 // If an error occurred, x.mode is set to invalid.
 //
 func (check *Checker) expr(x *operand, e ast.Expr) {
-	check.multiExpr(x, e)
+	check.rawExpr(x, e, nil)
+	check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
 	check.singleValue(x)
 }
 
-// multiExpr is like expr but the result may be a multi-value.
+// multiExpr is like expr but the result may also be a multi-value.
 func (check *Checker) multiExpr(x *operand, e ast.Expr) {
 	check.rawExpr(x, e, nil)
-	var msg string
-	var code errorCode
-	switch x.mode {
-	default:
-		return
-	case novalue:
-		msg = "%s used as value"
-		code = _TooManyValues
-	case builtin:
-		msg = "%s must be called"
-		code = _UncalledBuiltin
-	case typexpr:
-		msg = "%s is not an expression"
-		code = _NotAnExpr
-	}
-	check.errorf(x, code, msg, x)
-	x.mode = invalid
+	check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
 }
 
 // exprWithHint typechecks expression e and initializes x with the expression value;
@@ -1676,24 +1509,8 @@
 func (check *Checker) exprWithHint(x *operand, e ast.Expr, hint Type) {
 	assert(hint != nil)
 	check.rawExpr(x, e, hint)
+	check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
 	check.singleValue(x)
-	var msg string
-	var code errorCode
-	switch x.mode {
-	default:
-		return
-	case novalue:
-		msg = "%s used as value"
-		code = _TooManyValues
-	case builtin:
-		msg = "%s must be called"
-		code = _UncalledBuiltin
-	case typexpr:
-		msg = "%s is not an expression"
-		code = _NotAnExpr
-	}
-	check.errorf(x, code, msg, x)
-	x.mode = invalid
 }
 
 // exprOrType typechecks expression or type e and initializes x with the expression value or type.
@@ -1701,9 +1518,46 @@
 //
 func (check *Checker) exprOrType(x *operand, e ast.Expr) {
 	check.rawExpr(x, e, nil)
+	check.exclude(x, 1<<novalue)
 	check.singleValue(x)
-	if x.mode == novalue {
-		check.errorf(x, _NotAnExpr, "%s used as value or type", x)
+}
+
+// exclude reports an error if x.mode is in modeset and sets x.mode to invalid.
+// The modeset may contain any of 1<<novalue, 1<<builtin, 1<<typexpr.
+func (check *Checker) exclude(x *operand, modeset uint) {
+	if modeset&(1<<x.mode) != 0 {
+		var msg string
+		var code errorCode
+		switch x.mode {
+		case novalue:
+			if modeset&(1<<typexpr) != 0 {
+				msg = "%s used as value"
+			} else {
+				msg = "%s used as value or type"
+			}
+			code = _TooManyValues
+		case builtin:
+			msg = "%s must be called"
+			code = _UncalledBuiltin
+		case typexpr:
+			msg = "%s is not an expression"
+			code = _NotAnExpr
+		default:
+			unreachable()
+		}
+		check.errorf(x, code, msg, x)
 		x.mode = invalid
 	}
 }
+
+// singleValue reports an error if x describes a tuple and sets x.mode to invalid.
+func (check *Checker) singleValue(x *operand) {
+	if x.mode == value {
+		// tuple types are never named - no need for underlying type below
+		if t, ok := x.typ.(*Tuple); ok {
+			assert(t.Len() != 1)
+			check.errorf(x, _TooManyValues, "%d-valued %s where single value is expected", t.Len(), x)
+			x.mode = invalid
+		}
+	}
+}
diff --git a/src/go/types/exprstring.go b/src/go/types/exprstring.go
index 28d605f..f05e642 100644
--- a/src/go/types/exprstring.go
+++ b/src/go/types/exprstring.go
@@ -8,7 +8,9 @@
 
 import (
 	"bytes"
+	"fmt"
 	"go/ast"
+	"go/internal/typeparams"
 )
 
 // ExprString returns the (possibly shortened) string representation for x.
@@ -31,7 +33,7 @@
 
 	switch x := x.(type) {
 	default:
-		buf.WriteString("(bad expr)") // nil, ast.BadExpr, ast.KeyValueExpr
+		buf.WriteString(fmt.Sprintf("(ast: %T)", x)) // nil, ast.BadExpr, ast.KeyValueExpr
 
 	case *ast.Ident:
 		buf.WriteString(x.Name)
@@ -68,7 +70,13 @@
 	case *ast.IndexExpr:
 		WriteExpr(buf, x.X)
 		buf.WriteByte('[')
-		WriteExpr(buf, x.Index)
+		exprs := typeparams.UnpackExpr(x.Index)
+		for i, e := range exprs {
+			if i > 0 {
+				buf.WriteString(", ")
+			}
+			WriteExpr(buf, e)
+		}
 		buf.WriteByte(']')
 
 	case *ast.SliceExpr:
@@ -98,12 +106,7 @@
 	case *ast.CallExpr:
 		WriteExpr(buf, x.Fun)
 		buf.WriteByte('(')
-		for i, arg := range x.Args {
-			if i > 0 {
-				buf.WriteString(", ")
-			}
-			WriteExpr(buf, arg)
-		}
+		writeExprList(buf, x.Args)
 		if x.Ellipsis.IsValid() {
 			buf.WriteString("...")
 		}
@@ -134,7 +137,7 @@
 
 	case *ast.StructType:
 		buf.WriteString("struct{")
-		writeFieldList(buf, x.Fields, "; ", false)
+		writeFieldList(buf, x.Fields.List, "; ", false)
 		buf.WriteByte('}')
 
 	case *ast.FuncType:
@@ -142,8 +145,29 @@
 		writeSigExpr(buf, x)
 
 	case *ast.InterfaceType:
+		// separate type list types from method list
+		// TODO(gri) we can get rid of this extra code if writeExprList does the separation
+		var types []ast.Expr
+		var methods []*ast.Field
+		for _, f := range x.Methods.List {
+			if len(f.Names) > 1 && f.Names[0].Name == "type" {
+				// type list type
+				types = append(types, f.Type)
+			} else {
+				// method or embedded interface
+				methods = append(methods, f)
+			}
+		}
+
 		buf.WriteString("interface{")
-		writeFieldList(buf, x.Methods, "; ", true)
+		writeFieldList(buf, methods, "; ", true)
+		if len(types) > 0 {
+			if len(methods) > 0 {
+				buf.WriteString("; ")
+			}
+			buf.WriteString("type ")
+			writeExprList(buf, types)
+		}
 		buf.WriteByte('}')
 
 	case *ast.MapType:
@@ -169,7 +193,7 @@
 
 func writeSigExpr(buf *bytes.Buffer, sig *ast.FuncType) {
 	buf.WriteByte('(')
-	writeFieldList(buf, sig.Params, ", ", false)
+	writeFieldList(buf, sig.Params.List, ", ", false)
 	buf.WriteByte(')')
 
 	res := sig.Results
@@ -188,23 +212,18 @@
 
 	// multiple or named result(s)
 	buf.WriteByte('(')
-	writeFieldList(buf, res, ", ", false)
+	writeFieldList(buf, res.List, ", ", false)
 	buf.WriteByte(')')
 }
 
-func writeFieldList(buf *bytes.Buffer, fields *ast.FieldList, sep string, iface bool) {
-	for i, f := range fields.List {
+func writeFieldList(buf *bytes.Buffer, list []*ast.Field, sep string, iface bool) {
+	for i, f := range list {
 		if i > 0 {
 			buf.WriteString(sep)
 		}
 
 		// field list names
-		for i, name := range f.Names {
-			if i > 0 {
-				buf.WriteString(", ")
-			}
-			buf.WriteString(name.Name)
-		}
+		writeIdentList(buf, f.Names)
 
 		// types of interface methods consist of signatures only
 		if sig, _ := f.Type.(*ast.FuncType); sig != nil && iface {
@@ -222,3 +241,21 @@
 		// ignore tag
 	}
 }
+
+func writeIdentList(buf *bytes.Buffer, list []*ast.Ident) {
+	for i, x := range list {
+		if i > 0 {
+			buf.WriteString(", ")
+		}
+		buf.WriteString(x.Name)
+	}
+}
+
+func writeExprList(buf *bytes.Buffer, list []ast.Expr) {
+	for i, x := range list {
+		if i > 0 {
+			buf.WriteString(", ")
+		}
+		WriteExpr(buf, x)
+	}
+}
diff --git a/src/go/types/gotype.go b/src/go/types/gotype.go
index 52709df..ca1d42c 100644
--- a/src/go/types/gotype.go
+++ b/src/go/types/gotype.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // Build this command explicitly: go build gotype.go
diff --git a/src/go/types/index.go b/src/go/types/index.go
new file mode 100644
index 0000000..2ba3475
--- /dev/null
+++ b/src/go/types/index.go
@@ -0,0 +1,446 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements typechecking of index/slice expressions.
+
+package types
+
+import (
+	"go/ast"
+	"go/constant"
+	"go/internal/typeparams"
+)
+
+// If e is a valid function instantiation, indexExpr returns true.
+// In that case x represents the uninstantiated function value and
+// it is the caller's responsibility to instantiate the function.
+func (check *Checker) indexExpr(x *operand, e *ast.IndexExpr) (isFuncInst bool) {
+	check.exprOrType(x, e.X)
+
+	switch x.mode {
+	case invalid:
+		check.use(typeparams.UnpackExpr(e.Index)...)
+		return false
+
+	case typexpr:
+		// type instantiation
+		x.mode = invalid
+		x.typ = check.varType(e)
+		if x.typ != Typ[Invalid] {
+			x.mode = typexpr
+		}
+		return false
+
+	case value:
+		if sig := asSignature(x.typ); sig != nil && len(sig.tparams) > 0 {
+			// function instantiation
+			return true
+		}
+	}
+
+	valid := false
+	length := int64(-1) // valid if >= 0
+	switch typ := optype(x.typ).(type) {
+	case *Basic:
+		if isString(typ) {
+			valid = true
+			if x.mode == constant_ {
+				length = int64(len(constant.StringVal(x.val)))
+			}
+			// an indexed string always yields a byte value
+			// (not a constant) even if the string and the
+			// index are constant
+			x.mode = value
+			x.typ = universeByte // use 'byte' name
+		}
+
+	case *Array:
+		valid = true
+		length = typ.len
+		if x.mode != variable {
+			x.mode = value
+		}
+		x.typ = typ.elem
+
+	case *Pointer:
+		if typ := asArray(typ.base); typ != nil {
+			valid = true
+			length = typ.len
+			x.mode = variable
+			x.typ = typ.elem
+		}
+
+	case *Slice:
+		valid = true
+		x.mode = variable
+		x.typ = typ.elem
+
+	case *Map:
+		index := check.singleIndex(e)
+		if index == nil {
+			x.mode = invalid
+			return
+		}
+		var key operand
+		check.expr(&key, index)
+		check.assignment(&key, typ.key, "map index")
+		// ok to continue even if indexing failed - map element type is known
+		x.mode = mapindex
+		x.typ = typ.elem
+		x.expr = e
+		return
+
+	case *_Sum:
+		// A sum type can be indexed if all of the sum's types
+		// support indexing and have the same index and element
+		// type. Special rules apply for maps in the sum type.
+		var tkey, telem Type // key is for map types only
+		nmaps := 0           // number of map types in sum type
+		if typ.is(func(t Type) bool {
+			var e Type
+			switch t := under(t).(type) {
+			case *Basic:
+				if isString(t) {
+					e = universeByte
+				}
+			case *Array:
+				e = t.elem
+			case *Pointer:
+				if t := asArray(t.base); t != nil {
+					e = t.elem
+				}
+			case *Slice:
+				e = t.elem
+			case *Map:
+				// If there are multiple maps in the sum type,
+				// they must have identical key types.
+				// TODO(gri) We may be able to relax this rule
+				// but it becomes complicated very quickly.
+				if tkey != nil && !Identical(t.key, tkey) {
+					return false
+				}
+				tkey = t.key
+				e = t.elem
+				nmaps++
+			case *_TypeParam:
+				check.errorf(x, 0, "type of %s contains a type parameter - cannot index (implementation restriction)", x)
+			case *instance:
+				panic("unimplemented")
+			}
+			if e == nil || telem != nil && !Identical(e, telem) {
+				return false
+			}
+			telem = e
+			return true
+		}) {
+			// If there are maps, the index expression must be assignable
+			// to the map key type (as for simple map index expressions).
+			if nmaps > 0 {
+				index := check.singleIndex(e)
+				if index == nil {
+					x.mode = invalid
+					return
+				}
+				var key operand
+				check.expr(&key, index)
+				check.assignment(&key, tkey, "map index")
+				// ok to continue even if indexing failed - map element type is known
+
+				// If there are only maps, we are done.
+				if nmaps == len(typ.types) {
+					x.mode = mapindex
+					x.typ = telem
+					x.expr = e
+					return
+				}
+
+				// Otherwise we have mix of maps and other types. For
+				// now we require that the map key be an integer type.
+				// TODO(gri) This is probably not good enough.
+				valid = isInteger(tkey)
+				// avoid 2nd indexing error if indexing failed above
+				if !valid && key.mode == invalid {
+					x.mode = invalid
+					return
+				}
+				x.mode = value // map index expressions are not addressable
+			} else {
+				// no maps
+				valid = true
+				x.mode = variable
+			}
+			x.typ = telem
+		}
+	}
+
+	if !valid {
+		check.invalidOp(x, _NonIndexableOperand, "cannot index %s", x)
+		x.mode = invalid
+		return
+	}
+
+	index := check.singleIndex(e)
+	if index == nil {
+		x.mode = invalid
+		return
+	}
+
+	// In pathological (invalid) cases (e.g.: type T1 [][[]T1{}[0][0]]T0)
+	// the element type may be accessed before it's set. Make sure we have
+	// a valid type.
+	if x.typ == nil {
+		x.typ = Typ[Invalid]
+	}
+
+	check.index(index, length)
+	return false
+}
+
+func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
+	check.expr(x, e.X)
+	if x.mode == invalid {
+		check.use(e.Low, e.High, e.Max)
+		return
+	}
+
+	valid := false
+	length := int64(-1) // valid if >= 0
+	switch typ := optype(x.typ).(type) {
+	case *Basic:
+		if isString(typ) {
+			if e.Slice3 {
+				check.invalidOp(x, _InvalidSliceExpr, "3-index slice of string")
+				x.mode = invalid
+				return
+			}
+			valid = true
+			if x.mode == constant_ {
+				length = int64(len(constant.StringVal(x.val)))
+			}
+			// spec: "For untyped string operands the result
+			// is a non-constant value of type string."
+			if typ.kind == UntypedString {
+				x.typ = Typ[String]
+			}
+		}
+
+	case *Array:
+		valid = true
+		length = typ.len
+		if x.mode != variable {
+			check.invalidOp(x, _NonSliceableOperand, "cannot slice %s (value not addressable)", x)
+			x.mode = invalid
+			return
+		}
+		x.typ = &Slice{elem: typ.elem}
+
+	case *Pointer:
+		if typ := asArray(typ.base); typ != nil {
+			valid = true
+			length = typ.len
+			x.typ = &Slice{elem: typ.elem}
+		}
+
+	case *Slice:
+		valid = true
+		// x.typ doesn't change
+
+	case *_Sum, *_TypeParam:
+		check.errorf(x, 0, "generic slice expressions not yet implemented")
+		x.mode = invalid
+		return
+	}
+
+	if !valid {
+		check.invalidOp(x, _NonSliceableOperand, "cannot slice %s", x)
+		x.mode = invalid
+		return
+	}
+
+	x.mode = value
+
+	// spec: "Only the first index may be omitted; it defaults to 0."
+	if e.Slice3 && (e.High == nil || e.Max == nil) {
+		check.invalidAST(inNode(e, e.Rbrack), "2nd and 3rd index required in 3-index slice")
+		x.mode = invalid
+		return
+	}
+
+	// check indices
+	var ind [3]int64
+	for i, expr := range []ast.Expr{e.Low, e.High, e.Max} {
+		x := int64(-1)
+		switch {
+		case expr != nil:
+			// The "capacity" is only known statically for strings, arrays,
+			// and pointers to arrays, and it is the same as the length for
+			// those types.
+			max := int64(-1)
+			if length >= 0 {
+				max = length + 1
+			}
+			if _, v := check.index(expr, max); v >= 0 {
+				x = v
+			}
+		case i == 0:
+			// default is 0 for the first index
+			x = 0
+		case length >= 0:
+			// default is length (== capacity) otherwise
+			x = length
+		}
+		ind[i] = x
+	}
+
+	// constant indices must be in range
+	// (check.index already checks that existing indices >= 0)
+L:
+	for i, x := range ind[:len(ind)-1] {
+		if x > 0 {
+			for _, y := range ind[i+1:] {
+				if y >= 0 && x > y {
+					check.errorf(inNode(e, e.Rbrack), _SwappedSliceIndices, "swapped slice indices: %d > %d", x, y)
+					break L // only report one error, ok to continue
+				}
+			}
+		}
+	}
+}
+
+// singleIndex returns the (single) index from the index expression e.
+// If the index is missing, or if there are multiple indices, an error
+// is reported and the result is nil.
+func (check *Checker) singleIndex(e *ast.IndexExpr) ast.Expr {
+	index := e.Index
+	if index == nil {
+		check.invalidAST(e, "missing index for %s", e)
+		return nil
+	}
+
+	indexes := typeparams.UnpackExpr(index)
+	if len(indexes) == 0 {
+		check.invalidAST(index, "index expression %v with 0 indices", index)
+		return nil
+	}
+	if len(indexes) > 1 {
+		// TODO(rFindley) should this get a distinct error code?
+		check.invalidOp(indexes[1], _InvalidIndex, "more than one index")
+	}
+	return indexes[0]
+}
+
+// index checks an index expression for validity.
+// If max >= 0, it is the upper bound for index.
+// If the result typ is != Typ[Invalid], index is valid and typ is its (possibly named) integer type.
+// If the result val >= 0, index is valid and val is its constant int value.
+func (check *Checker) index(index ast.Expr, max int64) (typ Type, val int64) {
+	typ = Typ[Invalid]
+	val = -1
+
+	var x operand
+	check.expr(&x, index)
+	if !check.isValidIndex(&x, _InvalidIndex, "index", false) {
+		return
+	}
+
+	if x.mode != constant_ {
+		return x.typ, -1
+	}
+
+	if x.val.Kind() == constant.Unknown {
+		return
+	}
+
+	v, ok := constant.Int64Val(x.val)
+	assert(ok)
+	if max >= 0 && v >= max {
+		check.invalidArg(&x, _InvalidIndex, "index %s is out of bounds", &x)
+		return
+	}
+
+	// 0 <= v [ && v < max ]
+	return x.typ, v
+}
+
+func (check *Checker) isValidIndex(x *operand, code errorCode, what string, allowNegative bool) bool {
+	if x.mode == invalid {
+		return false
+	}
+
+	// spec: "a constant index that is untyped is given type int"
+	check.convertUntyped(x, Typ[Int])
+	if x.mode == invalid {
+		return false
+	}
+
+	// spec: "the index x must be of integer type or an untyped constant"
+	if !isInteger(x.typ) {
+		check.invalidArg(x, code, "%s %s must be integer", what, x)
+		return false
+	}
+
+	if x.mode == constant_ {
+		// spec: "a constant index must be non-negative ..."
+		if !allowNegative && constant.Sign(x.val) < 0 {
+			check.invalidArg(x, code, "%s %s must not be negative", what, x)
+			return false
+		}
+
+		// spec: "... and representable by a value of type int"
+		if !representableConst(x.val, check, Typ[Int], &x.val) {
+			check.invalidArg(x, code, "%s %s overflows int", what, x)
+			return false
+		}
+	}
+
+	return true
+}
+
+// indexElts checks the elements (elts) of an array or slice composite literal
+// against the literal's element type (typ), and the element indices against
+// the literal length if known (length >= 0). It returns the length of the
+// literal (maximum index value + 1).
+//
+func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 {
+	visited := make(map[int64]bool, len(elts))
+	var index, max int64
+	for _, e := range elts {
+		// determine and check index
+		validIndex := false
+		eval := e
+		if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
+			if typ, i := check.index(kv.Key, length); typ != Typ[Invalid] {
+				if i >= 0 {
+					index = i
+					validIndex = true
+				} else {
+					check.errorf(e, _InvalidLitIndex, "index %s must be integer constant", kv.Key)
+				}
+			}
+			eval = kv.Value
+		} else if length >= 0 && index >= length {
+			check.errorf(e, _OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
+		} else {
+			validIndex = true
+		}
+
+		// if we have a valid index, check for duplicate entries
+		if validIndex {
+			if visited[index] {
+				check.errorf(e, _DuplicateLitKey, "duplicate index %d in array or slice literal", index)
+			}
+			visited[index] = true
+		}
+		index++
+		if index > max {
+			max = index
+		}
+
+		// check element against composite literal element type
+		var x operand
+		check.exprWithHint(&x, eval, typ)
+		check.assignment(&x, typ, "array or slice literal")
+	}
+	return max
+}
diff --git a/src/go/types/infer.go b/src/go/types/infer.go
new file mode 100644
index 0000000..5d49351
--- /dev/null
+++ b/src/go/types/infer.go
@@ -0,0 +1,482 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements type parameter inference given
+// a list of concrete arguments and a parameter list.
+
+package types
+
+import (
+	"go/token"
+	"strings"
+)
+
+// infer attempts to infer the complete set of type arguments for generic function instantiation/call
+// based on the given type parameters tparams, type arguments targs, function parameters params, and
+// function arguments args, if any. There must be at least one type parameter, no more type arguments
+// than type parameters, and params and args must match in number (incl. zero).
+// If successful, infer returns the complete list of type arguments, one for each type parameter.
+// Otherwise the result is nil and appropriate errors will be reported unless report is set to false.
+//
+// Inference proceeds in 3 steps:
+//
+//   1) Start with given type arguments.
+//   2) Infer type arguments from typed function arguments.
+//   3) Infer type arguments from untyped function arguments.
+//
+// Constraint type inference is used after each step to expand the set of type arguments.
+//
+func (check *Checker) infer(posn positioner, tparams []*TypeName, targs []Type, params *Tuple, args []*operand, report bool) (result []Type) {
+	if debug {
+		defer func() {
+			assert(result == nil || len(result) == len(tparams))
+			for _, targ := range result {
+				assert(targ != nil)
+			}
+			//check.dump("### inferred targs = %s", result)
+		}()
+	}
+
+	// There must be at least one type parameter, and no more type arguments than type parameters.
+	n := len(tparams)
+	assert(n > 0 && len(targs) <= n)
+
+	// Function parameters and arguments must match in number.
+	assert(params.Len() == len(args))
+
+	// --- 0 ---
+	// If we already have all type arguments, we're done.
+	if len(targs) == n {
+		return targs
+	}
+	// len(targs) < n
+
+	// --- 1 ---
+	// Explicitly provided type arguments take precedence over any inferred types;
+	// and types inferred via constraint type inference take precedence over types
+	// inferred from function arguments.
+	// If we have type arguments, see how far we get with constraint type inference.
+	if len(targs) > 0 {
+		var index int
+		targs, index = check.inferB(tparams, targs, report)
+		if targs == nil || index < 0 {
+			return targs
+		}
+	}
+
+	// Continue with the type arguments we have now. Avoid matching generic
+	// parameters that already have type arguments against function arguments:
+	// It may fail because matching uses type identity while parameter passing
+	// uses assignment rules. Instantiate the parameter list with the type
+	// arguments we have, and continue with that parameter list.
+
+	// First, make sure we have a "full" list of type arguments, so of which
+	// may be nil (unknown).
+	if len(targs) < n {
+		targs2 := make([]Type, n)
+		copy(targs2, targs)
+		targs = targs2
+	}
+	// len(targs) == n
+
+	// Substitute type arguments for their respective type parameters in params,
+	// if any. Note that nil targs entries are ignored by check.subst.
+	// TODO(gri) Can we avoid this (we're setting known type argumemts below,
+	//           but that doesn't impact the isParameterized check for now).
+	if params.Len() > 0 {
+		smap := makeSubstMap(tparams, targs)
+		params = check.subst(token.NoPos, params, smap).(*Tuple)
+	}
+
+	// --- 2 ---
+	// Unify parameter and argument types for generic parameters with typed arguments
+	// and collect the indices of generic parameters with untyped arguments.
+	// Terminology: generic parameter = function parameter with a type-parameterized type
+	u := newUnifier(check, false)
+	u.x.init(tparams)
+
+	// Set the type arguments which we know already.
+	for i, targ := range targs {
+		if targ != nil {
+			u.x.set(i, targ)
+		}
+	}
+
+	errorf := func(kind string, tpar, targ Type, arg *operand) {
+		if !report {
+			return
+		}
+		// provide a better error message if we can
+		targs, index := u.x.types()
+		if index == 0 {
+			// The first type parameter couldn't be inferred.
+			// If none of them could be inferred, don't try
+			// to provide the inferred type in the error msg.
+			allFailed := true
+			for _, targ := range targs {
+				if targ != nil {
+					allFailed = false
+					break
+				}
+			}
+			if allFailed {
+				check.errorf(arg, _Todo, "%s %s of %s does not match %s (cannot infer %s)", kind, targ, arg.expr, tpar, typeNamesString(tparams))
+				return
+			}
+		}
+		smap := makeSubstMap(tparams, targs)
+		// TODO(rFindley): pass a positioner here, rather than arg.Pos().
+		inferred := check.subst(arg.Pos(), tpar, smap)
+		if inferred != tpar {
+			check.errorf(arg, _Todo, "%s %s of %s does not match inferred type %s for %s", kind, targ, arg.expr, inferred, tpar)
+		} else {
+			check.errorf(arg, 0, "%s %s of %s does not match %s", kind, targ, arg.expr, tpar)
+		}
+	}
+
+	// indices of the generic parameters with untyped arguments - save for later
+	var indices []int
+	for i, arg := range args {
+		par := params.At(i)
+		// If we permit bidirectional unification, this conditional code needs to be
+		// executed even if par.typ is not parameterized since the argument may be a
+		// generic function (for which we want to infer its type arguments).
+		if isParameterized(tparams, par.typ) {
+			if arg.mode == invalid {
+				// An error was reported earlier. Ignore this targ
+				// and continue, we may still be able to infer all
+				// targs resulting in fewer follon-on errors.
+				continue
+			}
+			if targ := arg.typ; isTyped(targ) {
+				// If we permit bidirectional unification, and targ is
+				// a generic function, we need to initialize u.y with
+				// the respective type parameters of targ.
+				if !u.unify(par.typ, targ) {
+					errorf("type", par.typ, targ, arg)
+					return nil
+				}
+			} else {
+				indices = append(indices, i)
+			}
+		}
+	}
+
+	// If we've got all type arguments, we're done.
+	var index int
+	targs, index = u.x.types()
+	if index < 0 {
+		return targs
+	}
+
+	// See how far we get with constraint type inference.
+	// Note that even if we don't have any type arguments, constraint type inference
+	// may produce results for constraints that explicitly specify a type.
+	targs, index = check.inferB(tparams, targs, report)
+	if targs == nil || index < 0 {
+		return targs
+	}
+
+	// --- 3 ---
+	// Use any untyped arguments to infer additional type arguments.
+	// Some generic parameters with untyped arguments may have been given
+	// a type by now, we can ignore them.
+	for _, i := range indices {
+		par := params.At(i)
+		// Since untyped types are all basic (i.e., non-composite) types, an
+		// untyped argument will never match a composite parameter type; the
+		// only parameter type it can possibly match against is a *TypeParam.
+		// Thus, only consider untyped arguments for generic parameters that
+		// are not of composite types and which don't have a type inferred yet.
+		if tpar, _ := par.typ.(*_TypeParam); tpar != nil && targs[tpar.index] == nil {
+			arg := args[i]
+			targ := Default(arg.typ)
+			// The default type for an untyped nil is untyped nil. We must not
+			// infer an untyped nil type as type parameter type. Ignore untyped
+			// nil by making sure all default argument types are typed.
+			if isTyped(targ) && !u.unify(par.typ, targ) {
+				errorf("default type", par.typ, targ, arg)
+				return nil
+			}
+		}
+	}
+
+	// If we've got all type arguments, we're done.
+	targs, index = u.x.types()
+	if index < 0 {
+		return targs
+	}
+
+	// Again, follow up with constraint type inference.
+	targs, index = check.inferB(tparams, targs, report)
+	if targs == nil || index < 0 {
+		return targs
+	}
+
+	// At least one type argument couldn't be inferred.
+	assert(index >= 0 && targs[index] == nil)
+	tpar := tparams[index]
+	if report {
+		check.errorf(posn, _Todo, "cannot infer %s (%v) (%v)", tpar.name, tpar.pos, targs)
+	}
+	return nil
+}
+
+// typeNamesString produces a string containing all the
+// type names in list suitable for human consumption.
+func typeNamesString(list []*TypeName) string {
+	// common cases
+	n := len(list)
+	switch n {
+	case 0:
+		return ""
+	case 1:
+		return list[0].name
+	case 2:
+		return list[0].name + " and " + list[1].name
+	}
+
+	// general case (n > 2)
+	var b strings.Builder
+	for i, tname := range list[:n-1] {
+		if i > 0 {
+			b.WriteString(", ")
+		}
+		b.WriteString(tname.name)
+	}
+	b.WriteString(", and ")
+	b.WriteString(list[n-1].name)
+	return b.String()
+}
+
+// IsParameterized reports whether typ contains any of the type parameters of tparams.
+func isParameterized(tparams []*TypeName, typ Type) bool {
+	w := tpWalker{
+		seen:    make(map[Type]bool),
+		tparams: tparams,
+	}
+	return w.isParameterized(typ)
+}
+
+type tpWalker struct {
+	seen    map[Type]bool
+	tparams []*TypeName
+}
+
+func (w *tpWalker) isParameterized(typ Type) (res bool) {
+	// detect cycles
+	if x, ok := w.seen[typ]; ok {
+		return x
+	}
+	w.seen[typ] = false
+	defer func() {
+		w.seen[typ] = res
+	}()
+
+	switch t := typ.(type) {
+	case nil, *Basic: // TODO(gri) should nil be handled here?
+		break
+
+	case *Array:
+		return w.isParameterized(t.elem)
+
+	case *Slice:
+		return w.isParameterized(t.elem)
+
+	case *Struct:
+		for _, fld := range t.fields {
+			if w.isParameterized(fld.typ) {
+				return true
+			}
+		}
+
+	case *Pointer:
+		return w.isParameterized(t.base)
+
+	case *Tuple:
+		n := t.Len()
+		for i := 0; i < n; i++ {
+			if w.isParameterized(t.At(i).typ) {
+				return true
+			}
+		}
+
+	case *_Sum:
+		return w.isParameterizedList(t.types)
+
+	case *Signature:
+		// t.tparams may not be nil if we are looking at a signature
+		// of a generic function type (or an interface method) that is
+		// part of the type we're testing. We don't care about these type
+		// parameters.
+		// Similarly, the receiver of a method may declare (rather then
+		// use) type parameters, we don't care about those either.
+		// Thus, we only need to look at the input and result parameters.
+		return w.isParameterized(t.params) || w.isParameterized(t.results)
+
+	case *Interface:
+		if t.allMethods != nil {
+			// TODO(rFindley) at some point we should enforce completeness here
+			for _, m := range t.allMethods {
+				if w.isParameterized(m.typ) {
+					return true
+				}
+			}
+			return w.isParameterizedList(unpackType(t.allTypes))
+		}
+
+		return t.iterate(func(t *Interface) bool {
+			for _, m := range t.methods {
+				if w.isParameterized(m.typ) {
+					return true
+				}
+			}
+			return w.isParameterizedList(unpackType(t.types))
+		}, nil)
+
+	case *Map:
+		return w.isParameterized(t.key) || w.isParameterized(t.elem)
+
+	case *Chan:
+		return w.isParameterized(t.elem)
+
+	case *Named:
+		return w.isParameterizedList(t.targs)
+
+	case *_TypeParam:
+		// t must be one of w.tparams
+		return t.index < len(w.tparams) && w.tparams[t.index].typ == t
+
+	case *instance:
+		return w.isParameterizedList(t.targs)
+
+	default:
+		unreachable()
+	}
+
+	return false
+}
+
+func (w *tpWalker) isParameterizedList(list []Type) bool {
+	for _, t := range list {
+		if w.isParameterized(t) {
+			return true
+		}
+	}
+	return false
+}
+
+// inferB returns the list of actual type arguments inferred from the type parameters'
+// bounds and an initial set of type arguments. If type inference is impossible because
+// unification fails, an error is reported if report is set to true, the resulting types
+// list is nil, and index is 0.
+// Otherwise, types is the list of inferred type arguments, and index is the index of the
+// first type argument in that list that couldn't be inferred (and thus is nil). If all
+// type arguments were inferred successfully, index is < 0. The number of type arguments
+// provided may be less than the number of type parameters, but there must be at least one.
+func (check *Checker) inferB(tparams []*TypeName, targs []Type, report bool) (types []Type, index int) {
+	assert(len(tparams) >= len(targs) && len(targs) > 0)
+
+	// Setup bidirectional unification between those structural bounds
+	// and the corresponding type arguments (which may be nil!).
+	u := newUnifier(check, false)
+	u.x.init(tparams)
+	u.y = u.x // type parameters between LHS and RHS of unification are identical
+
+	// Set the type arguments which we know already.
+	for i, targ := range targs {
+		if targ != nil {
+			u.x.set(i, targ)
+		}
+	}
+
+	// Unify type parameters with their structural constraints, if any.
+	for _, tpar := range tparams {
+		typ := tpar.typ.(*_TypeParam)
+		sbound := check.structuralType(typ.bound)
+		if sbound != nil {
+			if !u.unify(typ, sbound) {
+				if report {
+					check.errorf(tpar, _Todo, "%s does not match %s", tpar, sbound)
+				}
+				return nil, 0
+			}
+		}
+	}
+
+	// u.x.types() now contains the incoming type arguments plus any additional type
+	// arguments for which there were structural constraints. The newly inferred non-
+	// nil entries may still contain references to other type parameters. For instance,
+	// for [A any, B interface{type []C}, C interface{type *A}], if A == int
+	// was given, unification produced the type list [int, []C, *A]. We eliminate the
+	// remaining type parameters by substituting the type parameters in this type list
+	// until nothing changes anymore.
+	types, _ = u.x.types()
+	if debug {
+		for i, targ := range targs {
+			assert(targ == nil || types[i] == targ)
+		}
+	}
+
+	// dirty tracks the indices of all types that may still contain type parameters.
+	// We know that nil type entries and entries corresponding to provided (non-nil)
+	// type arguments are clean, so exclude them from the start.
+	var dirty []int
+	for i, typ := range types {
+		if typ != nil && (i >= len(targs) || targs[i] == nil) {
+			dirty = append(dirty, i)
+		}
+	}
+
+	for len(dirty) > 0 {
+		// TODO(gri) Instead of creating a new substMap for each iteration,
+		// provide an update operation for substMaps and only change when
+		// needed. Optimization.
+		smap := makeSubstMap(tparams, types)
+		n := 0
+		for _, index := range dirty {
+			t0 := types[index]
+			if t1 := check.subst(token.NoPos, t0, smap); t1 != t0 {
+				types[index] = t1
+				dirty[n] = index
+				n++
+			}
+		}
+		dirty = dirty[:n]
+	}
+
+	// Once nothing changes anymore, we may still have type parameters left;
+	// e.g., a structural constraint *P may match a type parameter Q but we
+	// don't have any type arguments to fill in for *P or Q (issue #45548).
+	// Don't let such inferences escape, instead nil them out.
+	for i, typ := range types {
+		if typ != nil && isParameterized(tparams, typ) {
+			types[i] = nil
+		}
+	}
+
+	// update index
+	index = -1
+	for i, typ := range types {
+		if typ == nil {
+			index = i
+			break
+		}
+	}
+
+	return
+}
+
+// structuralType returns the structural type of a constraint, if any.
+func (check *Checker) structuralType(constraint Type) Type {
+	if iface, _ := under(constraint).(*Interface); iface != nil {
+		check.completeInterface(token.NoPos, iface)
+		types := unpackType(iface.allTypes)
+		if len(types) == 1 {
+			return types[0]
+		}
+		return nil
+	}
+	return constraint
+}
diff --git a/src/go/types/issues_test.go b/src/go/types/issues_test.go
index 34850eb..519e199 100644
--- a/src/go/types/issues_test.go
+++ b/src/go/types/issues_test.go
@@ -385,9 +385,9 @@
 			}
 		}
 		if obj == nil {
-			t.Fatal("interface not found")
+			t.Fatal("object X not found")
 		}
-		iface := obj.Type().Underlying().(*Interface) // I must be an interface
+		iface := obj.Type().Underlying().(*Interface) // object X must be an interface
 
 		// Each iface method m is embedded; and m's receiver base type name
 		// must match the method's name per the choice in the source file.
@@ -477,7 +477,7 @@
 	}
 
 	bast := mustParse(t, bsrc)
-	conf := Config{Importer: importHelper{a}}
+	conf := Config{Importer: importHelper{pkg: a}}
 	b, err := conf.Check(bast.Name.Name, fset, []*ast.File{bast}, nil)
 	if err != nil {
 		t.Errorf("package %s failed to typecheck: %v", b.Name(), err)
@@ -485,14 +485,18 @@
 }
 
 type importHelper struct {
-	pkg *Package
+	pkg      *Package
+	fallback Importer
 }
 
 func (h importHelper) Import(path string) (*Package, error) {
-	if path != h.pkg.Path() {
+	if path == h.pkg.Path() {
+		return h.pkg, nil
+	}
+	if h.fallback == nil {
 		return nil, fmt.Errorf("got package path %q; want %q", path, h.pkg.Path())
 	}
-	return h.pkg, nil
+	return h.fallback.Import(path)
 }
 
 // TestIssue34921 verifies that we don't update an imported type's underlying
@@ -516,7 +520,7 @@
 	var pkg *Package
 	for _, src := range sources {
 		f := mustParse(t, src)
-		conf := Config{Importer: importHelper{pkg}}
+		conf := Config{Importer: importHelper{pkg: pkg}}
 		res, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, nil)
 		if err != nil {
 			t.Errorf("%q failed to typecheck: %v", src, err)
@@ -549,3 +553,88 @@
 	Comparable(T1)
 	Comparable(T2)
 }
+
+func TestIssue44515(t *testing.T) {
+	typ := Unsafe.Scope().Lookup("Pointer").Type()
+
+	got := TypeString(typ, nil)
+	want := "unsafe.Pointer"
+	if got != want {
+		t.Errorf("got %q; want %q", got, want)
+	}
+
+	qf := func(pkg *Package) string {
+		if pkg == Unsafe {
+			return "foo"
+		}
+		return ""
+	}
+	got = TypeString(typ, qf)
+	want = "foo.Pointer"
+	if got != want {
+		t.Errorf("got %q; want %q", got, want)
+	}
+}
+
+func TestIssue43124(t *testing.T) {
+	// TODO(rFindley) move this to testdata by enhancing support for importing.
+
+	// All involved packages have the same name (template). Error messages should
+	// disambiguate between text/template and html/template by printing the full
+	// path.
+	const (
+		asrc = `package a; import "text/template"; func F(template.Template) {}; func G(int) {}`
+		bsrc = `
+package b
+
+import (
+	"a"
+	"html/template"
+)
+
+func _() {
+	// Packages should be fully qualified when there is ambiguity within the
+	// error string itself.
+	a.F(template /* ERROR cannot use.*html/template.* as .*text/template */ .Template{})
+}
+`
+		csrc = `
+package c
+
+import (
+	"a"
+	"fmt"
+	"html/template"
+)
+
+// Issue #46905: make sure template is not the first package qualified.
+var _ fmt.Stringer = 1 // ERROR cannot use 1.*as fmt\.Stringer
+
+// Packages should be fully qualified when there is ambiguity in reachable
+// packages. In this case both a (and for that matter html/template) import
+// text/template.
+func _() { a.G(template /* ERROR cannot use .*html/template.*Template */ .Template{}) }
+`
+
+		tsrc = `
+package template
+
+import "text/template"
+
+type T int
+
+// Verify that the current package name also causes disambiguation.
+var _ T = template /* ERROR cannot use.*text/template.* as T value */.Template{}
+`
+	)
+
+	a, err := pkgFor("a", asrc, nil)
+	if err != nil {
+		t.Fatalf("package a failed to typecheck: %v", err)
+	}
+	imp := importHelper{pkg: a, fallback: importer.Default()}
+
+	checkFiles(t, nil, "", []string{"b.go"}, [][]byte{[]byte(bsrc)}, false, imp)
+	checkFiles(t, nil, "", []string{"c.go"}, [][]byte{[]byte(csrc)}, false, imp)
+	checkFiles(t, nil, "", []string{"t.go"}, [][]byte{[]byte(tsrc)}, false, imp)
+}
diff --git a/src/go/types/lookup.go b/src/go/types/lookup.go
index 3c9ff18..9c7bfd4 100644
--- a/src/go/types/lookup.go
+++ b/src/go/types/lookup.go
@@ -6,6 +6,8 @@
 
 package types
 
+import "go/token"
+
 // LookupFieldOrMethod looks up a field or method with given package and name
 // in T and returns the corresponding *Var or *Func, an index sequence, and a
 // bool indicating if there were any pointer indirections on the path to the
@@ -53,7 +55,7 @@
 	// Thus, if we have a named pointer type, proceed with the underlying
 	// pointer type but discard the result if it is a method since we would
 	// not have found it for T (see also issue 8590).
-	if t, _ := T.(*Named); t != nil {
+	if t := asNamed(T); t != nil {
 		if p, _ := t.underlying.(*Pointer); p != nil {
 			obj, index, indirect = check.rawLookupFieldOrMethod(p, false, pkg, name)
 			if _, ok := obj.(*Func); ok {
@@ -83,7 +85,8 @@
 	typ, isPtr := deref(T)
 
 	// *typ where typ is an interface has no methods.
-	if isPtr && IsInterface(typ) {
+	// Be cautious: typ may be nil (issue 39634, crash #3).
+	if typ == nil || isPtr && IsInterface(typ) {
 		return
 	}
 
@@ -104,12 +107,13 @@
 		var next []embeddedType // embedded types found at current depth
 
 		// look for (pkg, name) in all types at current depth
+		var tpar *_TypeParam // set if obj receiver is a type parameter
 		for _, e := range current {
 			typ := e.typ
 
 			// If we have a named type, we may have associated methods.
 			// Look for those first.
-			if named, _ := typ.(*Named); named != nil {
+			if named := asNamed(typ); named != nil {
 				if seen[named] {
 					// We have seen this type before, at a more shallow depth
 					// (note that multiples of this type at the current depth
@@ -136,10 +140,17 @@
 					continue // we can't have a matching field or interface method
 				}
 
-				// continue with underlying type
-				typ = named.underlying
+				// continue with underlying type, but only if it's not a type parameter
+				// TODO(gri) is this what we want to do for type parameters? (spec question)
+				// TODO(#45639) the error message produced as a result of skipping an
+				//              underlying type parameter should be improved.
+				typ = named.under()
+				if asTypeParam(typ) != nil {
+					continue
+				}
 			}
 
+			tpar = nil
 			switch t := typ.(type) {
 			case *Struct:
 				// look for a matching field and collect embedded types
@@ -175,7 +186,7 @@
 			case *Interface:
 				// look for a matching method
 				// TODO(gri) t.allMethods is sorted - use binary search
-				check.completeInterface(t)
+				check.completeInterface(token.NoPos, t)
 				if i, m := lookupMethod(t.allMethods, pkg, name); m != nil {
 					assert(m.typ != nil)
 					index = concat(e.index, i)
@@ -185,6 +196,20 @@
 					obj = m
 					indirect = e.indirect
 				}
+
+			case *_TypeParam:
+				// only consider explicit methods in the type parameter bound, not
+				// methods that may be common to all types in the type list.
+				if i, m := lookupMethod(t.Bound().allMethods, pkg, name); m != nil {
+					assert(m.typ != nil)
+					index = concat(e.index, i)
+					if obj != nil || e.multiples {
+						return nil, index, false // collision
+					}
+					tpar = t
+					obj = m
+					indirect = e.indirect
+				}
 			}
 		}
 
@@ -194,8 +219,12 @@
 			//        contains m and the argument list can be assigned to the parameter
 			//        list of m. If x is addressable and &x's method set contains m, x.m()
 			//        is shorthand for (&x).m()".
-			if f, _ := obj.(*Func); f != nil && ptrRecv(f) && !indirect && !addressable {
-				return nil, nil, true // pointer/addressable receiver required
+			if f, _ := obj.(*Func); f != nil {
+				// determine if method has a pointer receiver
+				hasPtrRecv := tpar == nil && ptrRecv(f)
+				if hasPtrRecv && !indirect && !addressable {
+					return nil, nil, true // pointer/addressable receiver required
+				}
 			}
 			return
 		}
@@ -267,7 +296,8 @@
 	return m, typ != nil
 }
 
-// missingMethod is like MissingMethod but accepts a receiver.
+// missingMethod is like MissingMethod but accepts a *Checker as
+// receiver and an addressable flag.
 // The receiver may be nil if missingMethod is invoked through
 // an exported API call (such as MissingMethod), i.e., when all
 // methods have been type-checked.
@@ -276,32 +306,53 @@
 // To improve error messages, also report the wrong signature
 // when the method exists on *V instead of V.
 func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, wrongType *Func) {
-	check.completeInterface(T)
+	check.completeInterface(token.NoPos, T)
 
 	// fast path for common case
 	if T.Empty() {
 		return
 	}
 
-	if ityp, _ := V.Underlying().(*Interface); ityp != nil {
-		check.completeInterface(ityp)
+	if ityp := asInterface(V); ityp != nil {
+		check.completeInterface(token.NoPos, ityp)
 		// TODO(gri) allMethods is sorted - can do this more efficiently
 		for _, m := range T.allMethods {
-			_, obj := lookupMethod(ityp.allMethods, m.pkg, m.name)
-			switch {
-			case obj == nil:
-				if static {
-					return m, nil
+			_, f := lookupMethod(ityp.allMethods, m.pkg, m.name)
+
+			if f == nil {
+				// if m is the magic method == we're ok (interfaces are comparable)
+				if m.name == "==" || !static {
+					continue
 				}
-			case !check.identical(obj.Type(), m.typ):
-				return m, obj
+				return m, f
+			}
+
+			ftyp := f.typ.(*Signature)
+			mtyp := m.typ.(*Signature)
+			if len(ftyp.tparams) != len(mtyp.tparams) {
+				return m, f
+			}
+
+			// If the methods have type parameters we don't care whether they
+			// are the same or not, as long as they match up. Use unification
+			// to see if they can be made to match.
+			// TODO(gri) is this always correct? what about type bounds?
+			// (Alternative is to rename/subst type parameters and compare.)
+			u := newUnifier(check, true)
+			u.x.init(ftyp.tparams)
+			if !u.unify(ftyp, mtyp) {
+				return m, f
 			}
 		}
+
 		return
 	}
 
 	// A concrete type implements T if it implements all methods of T.
+	Vd, _ := deref(V)
+	Vn := asNamed(Vd)
 	for _, m := range T.allMethods {
+		// TODO(gri) should this be calling lookupFieldOrMethod instead (and why not)?
 		obj, _, _ := check.rawLookupFieldOrMethod(V, false, m.pkg, m.name)
 
 		// Check if *V implements this method of T.
@@ -316,6 +367,10 @@
 		// we must have a method (not a field of matching function type)
 		f, _ := obj.(*Func)
 		if f == nil {
+			// if m is the magic method == and V is comparable, we're ok
+			if m.name == "==" && Comparable(V) {
+				continue
+			}
 			return m, nil
 		}
 
@@ -324,7 +379,41 @@
 			check.objDecl(f, nil)
 		}
 
-		if !check.identical(f.typ, m.typ) {
+		// both methods must have the same number of type parameters
+		ftyp := f.typ.(*Signature)
+		mtyp := m.typ.(*Signature)
+		if len(ftyp.tparams) != len(mtyp.tparams) {
+			return m, f
+		}
+
+		// If V is a (instantiated) generic type, its methods are still
+		// parameterized using the original (declaration) receiver type
+		// parameters (subst simply copies the existing method list, it
+		// does not instantiate the methods).
+		// In order to compare the signatures, substitute the receiver
+		// type parameters of ftyp with V's instantiation type arguments.
+		// This lazily instantiates the signature of method f.
+		if Vn != nil && len(Vn.tparams) > 0 {
+			// Be careful: The number of type arguments may not match
+			// the number of receiver parameters. If so, an error was
+			// reported earlier but the length discrepancy is still
+			// here. Exit early in this case to prevent an assertion
+			// failure in makeSubstMap.
+			// TODO(gri) Can we avoid this check by fixing the lengths?
+			if len(ftyp.rparams) != len(Vn.targs) {
+				return
+			}
+			ftyp = check.subst(token.NoPos, ftyp, makeSubstMap(ftyp.rparams, Vn.targs)).(*Signature)
+		}
+
+		// If the methods have type parameters we don't care whether they
+		// are the same or not, as long as they match up. Use unification
+		// to see if they can be made to match.
+		// TODO(gri) is this always correct? what about type bounds?
+		// (Alternative is to rename/subst type parameters and compare.)
+		u := newUnifier(check, true)
+		u.x.init(ftyp.tparams)
+		if !u.unify(ftyp, mtyp) {
 			return m, f
 		}
 	}
@@ -337,11 +426,13 @@
 // method required by V and whether it is missing or just has the wrong type.
 // The receiver may be nil if assertableTo is invoked through an exported API call
 // (such as AssertableTo), i.e., when all methods have been type-checked.
+// If the global constant forceStrict is set, assertions that are known to fail
+// are not permitted.
 func (check *Checker) assertableTo(V *Interface, T Type) (method, wrongType *Func) {
 	// no static check is required if T is an interface
 	// spec: "If T is an interface type, x.(T) asserts that the
 	//        dynamic type of x implements the interface T."
-	if _, ok := T.Underlying().(*Interface); ok && !strict {
+	if asInterface(T) != nil && !forceStrict {
 		return
 	}
 	return check.missingMethod(T, V, false)
@@ -359,8 +450,8 @@
 // derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a
 // (named or unnamed) struct and returns its base. Otherwise it returns typ.
 func derefStructPtr(typ Type) Type {
-	if p, _ := typ.Underlying().(*Pointer); p != nil {
-		if _, ok := p.base.Underlying().(*Struct); ok {
+	if p := asPointer(typ); p != nil {
+		if asStruct(p.base) != nil {
 			return p.base
 		}
 	}
diff --git a/src/go/types/methodset.go b/src/go/types/methodset.go
index c34d732..ae8011a 100644
--- a/src/go/types/methodset.go
+++ b/src/go/types/methodset.go
@@ -63,7 +63,7 @@
 var emptyMethodSet MethodSet
 
 // Note: NewMethodSet is intended for external use only as it
-//       requires interfaces to be complete. If may be used
+//       requires interfaces to be complete. It may be used
 //       internally if LookupFieldOrMethod completed the same
 //       interfaces beforehand.
 
@@ -73,6 +73,9 @@
 	// WARNING: The code in this function is extremely subtle - do not modify casually!
 	//          This function and lookupFieldOrMethod should be kept in sync.
 
+	// TODO(rfindley) confirm that this code is in sync with lookupFieldOrMethod
+	//                with respect to type params.
+
 	// method set up to the current depth, allocated lazily
 	var base methodSet
 
@@ -108,7 +111,7 @@
 
 			// If we have a named type, we may have associated methods.
 			// Look for those first.
-			if named, _ := typ.(*Named); named != nil {
+			if named := asNamed(typ); named != nil {
 				if seen[named] {
 					// We have seen this type before, at a more shallow depth
 					// (note that multiples of this type at the current depth
@@ -124,8 +127,12 @@
 
 				mset = mset.add(named.methods, e.index, e.indirect, e.multiples)
 
-				// continue with underlying type
+				// continue with underlying type, but only if it's not a type parameter
+				// TODO(rFindley): should this use named.under()? Can there be a difference?
 				typ = named.underlying
+				if _, ok := typ.(*_TypeParam); ok {
+					continue
+				}
 			}
 
 			switch t := typ.(type) {
@@ -151,6 +158,9 @@
 
 			case *Interface:
 				mset = mset.add(t.allMethods, e.index, true, e.multiples)
+
+			case *_TypeParam:
+				mset = mset.add(t.Bound().allMethods, e.index, true, e.multiples)
 			}
 		}
 
diff --git a/src/go/types/methodset_test.go b/src/go/types/methodset_test.go
new file mode 100644
index 0000000..4a373fa
--- /dev/null
+++ b/src/go/types/methodset_test.go
@@ -0,0 +1,109 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types_test
+
+import (
+	"testing"
+
+	"go/internal/typeparams"
+	. "go/types"
+)
+
+func TestNewMethodSet(t *testing.T) {
+	type method struct {
+		name     string
+		index    []int
+		indirect bool
+	}
+
+	// Tests are expressed src -> methods, for simplifying the composite literal.
+	// Should be kept in sync with TestLookupFieldOrMethod.
+	tests := map[string][]method{
+		// Named types
+		"var a T; type T struct{}; func (T) f() {}":   {{"f", []int{0}, false}},
+		"var a *T; type T struct{}; func (T) f() {}":  {{"f", []int{0}, true}},
+		"var a T; type T struct{}; func (*T) f() {}":  {},
+		"var a *T; type T struct{}; func (*T) f() {}": {{"f", []int{0}, true}},
+
+		// Interfaces
+		"var a T; type T interface{ f() }":                           {{"f", []int{0}, true}},
+		"var a T1; type ( T1 T2; T2 interface{ f() } )":              {{"f", []int{0}, true}},
+		"var a T1; type ( T1 interface{ T2 }; T2 interface{ f() } )": {{"f", []int{0}, true}},
+
+		// Embedding
+		"var a struct{ E }; type E interface{ f() }":            {{"f", []int{0, 0}, true}},
+		"var a *struct{ E }; type E interface{ f() }":           {{"f", []int{0, 0}, true}},
+		"var a struct{ E }; type E struct{}; func (E) f() {}":   {{"f", []int{0, 0}, false}},
+		"var a struct{ *E }; type E struct{}; func (E) f() {}":  {{"f", []int{0, 0}, true}},
+		"var a struct{ E }; type E struct{}; func (*E) f() {}":  {},
+		"var a struct{ *E }; type E struct{}; func (*E) f() {}": {{"f", []int{0, 0}, true}},
+
+		// collisions
+		"var a struct{ E1; *E2 }; type ( E1 interface{ f() }; E2 struct{ f int })":            {},
+		"var a struct{ E1; *E2 }; type ( E1 struct{ f int }; E2 struct{} ); func (E2) f() {}": {},
+	}
+
+	genericTests := map[string][]method{
+		// By convention, look up a in the scope of "g"
+		"type C interface{ f() }; func g[T C](a T){}":                       {{"f", []int{0}, true}},
+		"type C interface{ f() }; func g[T C]() { var a T; _ = a }":         {{"f", []int{0}, true}},
+		"type C interface{ f() }; func g[T C]() { var a struct{T}; _ = a }": {{"f", []int{0, 0}, true}},
+
+		// Issue #45639.
+		"type C interface{ f() }; func g[T C]() { type Y T; var a Y; _ = a }": {},
+	}
+
+	check := func(src string, methods []method, generic bool) {
+		pkgName := "p"
+		if generic {
+			// The generic_ prefix causes pkgFor to allow generic code.
+			pkgName = "generic_p"
+		}
+		pkg, err := pkgFor("test", "package "+pkgName+";"+src, nil)
+		if err != nil {
+			t.Errorf("%s: incorrect test case: %s", src, err)
+			return
+		}
+
+		scope := pkg.Scope()
+		if generic {
+			fn := pkg.Scope().Lookup("g").(*Func)
+			scope = fn.Scope()
+		}
+		obj := scope.Lookup("a")
+		if obj == nil {
+			t.Errorf("%s: incorrect test case - no object a", src)
+			return
+		}
+
+		ms := NewMethodSet(obj.Type())
+		if got, want := ms.Len(), len(methods); got != want {
+			t.Errorf("%s: got %d methods, want %d", src, got, want)
+			return
+		}
+		for i, m := range methods {
+			sel := ms.At(i)
+			if got, want := sel.Obj().Name(), m.name; got != want {
+				t.Errorf("%s [method %d]: got name = %q at, want %q", src, i, got, want)
+			}
+			if got, want := sel.Index(), m.index; !sameSlice(got, want) {
+				t.Errorf("%s [method %d]: got index = %v, want %v", src, i, got, want)
+			}
+			if got, want := sel.Indirect(), m.indirect; got != want {
+				t.Errorf("%s [method %d]: got indirect = %v, want %v", src, i, got, want)
+			}
+		}
+	}
+
+	for src, methods := range tests {
+		check(src, methods, false)
+	}
+
+	if typeparams.Enabled {
+		for src, methods := range genericTests {
+			check(src, methods, true)
+		}
+	}
+}
diff --git a/src/go/types/object.go b/src/go/types/object.go
index 374b24d..50346ec 100644
--- a/src/go/types/object.go
+++ b/src/go/types/object.go
@@ -36,6 +36,9 @@
 	// color returns the object's color.
 	color() color
 
+	// setType sets the type of the object.
+	setType(Type)
+
 	// setOrder sets the order number of the object. It must be > 0.
 	setOrder(uint32)
 
@@ -149,6 +152,7 @@
 func (obj *object) scopePos() token.Pos { return obj.scopePos_ }
 
 func (obj *object) setParent(parent *Scope)   { obj.parent = parent }
+func (obj *object) setType(typ Type)          { obj.typ = typ }
 func (obj *object) setOrder(order uint32)     { assert(order > 0); obj.order_ = order }
 func (obj *object) setColor(color color)      { assert(color != white); obj.color_ = color }
 func (obj *object) setScopePos(pos token.Pos) { obj.scopePos_ = pos }
@@ -299,7 +303,7 @@
 // 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
+	// don't store a (typed) nil signature
 	var typ Type
 	if sig != nil {
 		typ = sig
@@ -420,7 +424,7 @@
 		if tname.IsAlias() {
 			buf.WriteString(" =")
 		} else {
-			typ = typ.Underlying()
+			typ = under(typ)
 		}
 	}
 
diff --git a/src/go/types/operand.go b/src/go/types/operand.go
index 3e1ac31..6463728 100644
--- a/src/go/types/operand.go
+++ b/src/go/types/operand.go
@@ -158,7 +158,16 @@
 	// <typ>
 	if hasType {
 		if x.typ != Typ[Invalid] {
-			buf.WriteString(" of type ")
+			var intro string
+			switch {
+			case isGeneric(x.typ):
+				intro = " of generic type "
+			case asTypeParam(x.typ) != nil:
+				intro = " of type parameter type "
+			default:
+				intro = " of type "
+			}
+			buf.WriteString(intro)
 			WriteType(&buf, x.typ, qf)
 		} else {
 			buf.WriteString(" with invalid type")
@@ -213,9 +222,10 @@
 
 // assignableTo reports whether x is assignable to a variable of type T. If the
 // result is false and a non-nil reason is provided, it may be set to a more
-// detailed explanation of the failure (result != ""). The check parameter may
-// be nil if assignableTo is invoked through an exported API call, i.e., when
-// all methods have been type-checked.
+// detailed explanation of the failure (result != ""). The returned error code
+// is only valid if the (first) result is false. The check parameter may be nil
+// if assignableTo is invoked through an exported API call, i.e., when all
+// methods have been type-checked.
 func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, errorCode) {
 	if x.mode == invalid || T == Typ[Invalid] {
 		return true, 0 // avoid spurious errors
@@ -228,20 +238,25 @@
 		return true, 0
 	}
 
-	Vu := V.Underlying()
-	Tu := T.Underlying()
+	Vu := optype(V)
+	Tu := optype(T)
 
 	// x is an untyped value representable by a value of type T.
 	if isUntyped(Vu) {
-		if t, ok := Tu.(*Basic); ok && x.mode == constant_ {
-			return representableConst(x.val, check, t, nil), _IncompatibleAssign
+		if t, ok := Tu.(*_Sum); ok {
+			return t.is(func(t Type) bool {
+				// TODO(gri) this could probably be more efficient
+				ok, _ := x.assignableTo(check, t, reason)
+				return ok
+			}), _IncompatibleAssign
 		}
-		return check.implicitType(x, Tu) != nil, _IncompatibleAssign
+		newType, _, _ := check.implicitTypeAndValue(x, Tu)
+		return newType != nil, _IncompatibleAssign
 	}
 	// Vu is typed
 
-	// x's type V and T have identical underlying types and at least one of V or
-	// T is not a named type.
+	// x's type V and T have identical underlying types
+	// and at least one of V or T is not a named type
 	if check.identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) {
 		return true, 0
 	}
@@ -271,11 +286,7 @@
 	// and at least one of V or T is not a named type
 	if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv {
 		if Tc, ok := Tu.(*Chan); ok && check.identical(Vc.elem, Tc.elem) {
-			if !isNamed(V) || !isNamed(T) {
-				return true, 0
-			} else {
-				return false, _InvalidChanAssign
-			}
+			return !isNamed(V) || !isNamed(T), _InvalidChanAssign
 		}
 	}
 
diff --git a/src/go/types/predicates.go b/src/go/types/predicates.go
index 148edbf..7bb0264 100644
--- a/src/go/types/predicates.go
+++ b/src/go/types/predicates.go
@@ -6,75 +6,84 @@
 
 package types
 
-import "sort"
+import (
+	"go/token"
+)
 
+// isNamed reports whether typ has a name.
+// isNamed may be called with types that are not fully set up.
 func isNamed(typ Type) bool {
-	if _, ok := typ.(*Basic); ok {
-		return ok
+	switch typ.(type) {
+	case *Basic, *Named, *_TypeParam, *instance:
+		return true
 	}
-	_, ok := typ.(*Named)
-	return ok
+	return false
 }
 
-func isBoolean(typ Type) bool {
-	t, ok := typ.Underlying().(*Basic)
-	return ok && t.info&IsBoolean != 0
+// isGeneric reports whether a type is a generic, uninstantiated type (generic
+// signatures are not included).
+func isGeneric(typ Type) bool {
+	// A parameterized type is only instantiated if it doesn't have an instantiation already.
+	named, _ := typ.(*Named)
+	return named != nil && named.obj != nil && named.tparams != nil && named.targs == nil
 }
 
-func isInteger(typ Type) bool {
-	t, ok := typ.Underlying().(*Basic)
-	return ok && t.info&IsInteger != 0
+func is(typ Type, what BasicInfo) bool {
+	switch t := optype(typ).(type) {
+	case *Basic:
+		return t.info&what != 0
+	case *_Sum:
+		return t.is(func(typ Type) bool { return is(typ, what) })
+	}
+	return false
 }
 
-func isUnsigned(typ Type) bool {
-	t, ok := typ.Underlying().(*Basic)
-	return ok && t.info&IsUnsigned != 0
-}
+func isBoolean(typ Type) bool  { return is(typ, IsBoolean) }
+func isInteger(typ Type) bool  { return is(typ, IsInteger) }
+func isUnsigned(typ Type) bool { return is(typ, IsUnsigned) }
+func isFloat(typ Type) bool    { return is(typ, IsFloat) }
+func isComplex(typ Type) bool  { return is(typ, IsComplex) }
+func isNumeric(typ Type) bool  { return is(typ, IsNumeric) }
+func isString(typ Type) bool   { return is(typ, IsString) }
 
-func isFloat(typ Type) bool {
-	t, ok := typ.Underlying().(*Basic)
-	return ok && t.info&IsFloat != 0
-}
+// Note that if typ is a type parameter, isInteger(typ) || isFloat(typ) does not
+// produce the expected result because a type list that contains both an integer
+// and a floating-point type is neither (all) integers, nor (all) floats.
+// Use isIntegerOrFloat instead.
+func isIntegerOrFloat(typ Type) bool { return is(typ, IsInteger|IsFloat) }
 
-func isComplex(typ Type) bool {
-	t, ok := typ.Underlying().(*Basic)
-	return ok && t.info&IsComplex != 0
-}
+// isNumericOrString is the equivalent of isIntegerOrFloat for isNumeric(typ) || isString(typ).
+func isNumericOrString(typ Type) bool { return is(typ, IsNumeric|IsString) }
 
-func isNumeric(typ Type) bool {
-	t, ok := typ.Underlying().(*Basic)
-	return ok && t.info&IsNumeric != 0
-}
-
-func isString(typ Type) bool {
-	t, ok := typ.Underlying().(*Basic)
-	return ok && t.info&IsString != 0
-}
-
+// isTyped reports whether typ is typed; i.e., not an untyped
+// constant or boolean. isTyped may be called with types that
+// are not fully set up.
 func isTyped(typ Type) bool {
-	t, ok := typ.Underlying().(*Basic)
-	return !ok || t.info&IsUntyped == 0
+	// isTyped is called with types that are not fully
+	// set up. Must not call asBasic()!
+	// A *Named or *instance type is always typed, so
+	// we only need to check if we have a true *Basic
+	// type.
+	t, _ := typ.(*Basic)
+	return t == nil || t.info&IsUntyped == 0
 }
 
+// isUntyped(typ) is the same as !isTyped(typ).
 func isUntyped(typ Type) bool {
-	t, ok := typ.Underlying().(*Basic)
-	return ok && t.info&IsUntyped != 0
+	return !isTyped(typ)
 }
 
-func isOrdered(typ Type) bool {
-	t, ok := typ.Underlying().(*Basic)
-	return ok && t.info&IsOrdered != 0
-}
+func isOrdered(typ Type) bool { return is(typ, IsOrdered) }
 
 func isConstType(typ Type) bool {
-	t, ok := typ.Underlying().(*Basic)
-	return ok && t.info&IsConstType != 0
+	// Type parameters are never const types.
+	t, _ := under(typ).(*Basic)
+	return t != nil && t.info&IsConstType != 0
 }
 
 // IsInterface reports whether typ is an interface type.
 func IsInterface(typ Type) bool {
-	_, ok := typ.Underlying().(*Interface)
-	return ok
+	return asInterface(typ) != nil
 }
 
 // Comparable reports whether values of type T are comparable.
@@ -91,7 +100,19 @@
 	}
 	seen[T] = true
 
-	switch t := T.Underlying().(type) {
+	// If T is a type parameter not constrained by any type
+	// list (i.e., it's underlying type is the top type),
+	// T is comparable if it has the == method. Otherwise,
+	// the underlying type "wins". For instance
+	//
+	//     interface{ comparable; type []byte }
+	//
+	// is not comparable because []byte is not comparable.
+	if t := asTypeParam(T); t != nil && optype(t) == theTop {
+		return t.Bound()._IsComparable()
+	}
+
+	switch t := optype(T).(type) {
 	case *Basic:
 		// assume invalid types to be comparable
 		// to avoid follow-up errors
@@ -107,17 +128,26 @@
 		return true
 	case *Array:
 		return comparable(t.elem, seen)
+	case *_Sum:
+		pred := func(t Type) bool {
+			return comparable(t, seen)
+		}
+		return t.is(pred)
+	case *_TypeParam:
+		return t.Bound()._IsComparable()
 	}
 	return false
 }
 
 // hasNil reports whether a type includes the nil value.
 func hasNil(typ Type) bool {
-	switch t := typ.Underlying().(type) {
+	switch t := optype(typ).(type) {
 	case *Basic:
 		return t.kind == UnsafePointer
 	case *Slice, *Pointer, *Signature, *Interface, *Map, *Chan:
 		return true
+	case *_Sum:
+		return t.is(hasNil)
 	}
 	return false
 }
@@ -144,7 +174,12 @@
 	return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
 }
 
+// For changes to this code the corresponding changes should be made to unifier.nify.
 func (check *Checker) identical0(x, y Type, cmpTags bool, p *ifacePair) bool {
+	// types must be expanded for comparison
+	x = expandf(x)
+	y = expandf(y)
+
 	if x == y {
 		return true
 	}
@@ -221,12 +256,38 @@
 		// and result values, corresponding parameter and result types are identical,
 		// and either both functions are variadic or neither is. Parameter and result
 		// names are not required to match.
+		// Generic functions must also have matching type parameter lists, but for the
+		// parameter names.
 		if y, ok := y.(*Signature); ok {
 			return x.variadic == y.variadic &&
+				check.identicalTParams(x.tparams, y.tparams, cmpTags, p) &&
 				check.identical0(x.params, y.params, cmpTags, p) &&
 				check.identical0(x.results, y.results, cmpTags, p)
 		}
 
+	case *_Sum:
+		// Two sum types are identical if they contain the same types.
+		// (Sum types always consist of at least two types. Also, the
+		// the set (list) of types in a sum type consists of unique
+		// types - each type appears exactly once. Thus, two sum types
+		// must contain the same number of types to have chance of
+		// being equal.
+		if y, ok := y.(*_Sum); ok && len(x.types) == len(y.types) {
+			// Every type in x.types must be in y.types.
+			// Quadratic algorithm, but probably good enough for now.
+			// TODO(gri) we need a fast quick type ID/hash for all types.
+		L:
+			for _, x := range x.types {
+				for _, y := range y.types {
+					if Identical(x, y) {
+						continue L // x is in y.types
+					}
+				}
+				return false // x is not in y.types
+			}
+			return true
+		}
+
 	case *Interface:
 		// Two interface types are identical if they have the same set of methods with
 		// the same names and identical function types. Lower-case method names from
@@ -237,8 +298,8 @@
 			// that case, interfaces are expected to be complete and lazy completion
 			// here is not needed.
 			if check != nil {
-				check.completeInterface(x)
-				check.completeInterface(y)
+				check.completeInterface(token.NoPos, x)
+				check.completeInterface(token.NoPos, y)
 			}
 			a := x.allMethods
 			b := y.allMethods
@@ -273,8 +334,8 @@
 					p = p.prev
 				}
 				if debug {
-					assert(sort.IsSorted(byUniqueMethodName(a)))
-					assert(sort.IsSorted(byUniqueMethodName(b)))
+					assertSortedMethods(a)
+					assertSortedMethods(b)
 				}
 				for i, f := range a {
 					g := b[i]
@@ -303,10 +364,25 @@
 		// Two named types are identical if their type names originate
 		// in the same type declaration.
 		if y, ok := y.(*Named); ok {
+			// TODO(gri) Why is x == y not sufficient? And if it is,
+			//           we can just return false here because x == y
+			//           is caught in the very beginning of this function.
 			return x.obj == y.obj
 		}
 
+	case *_TypeParam:
+		// nothing to do (x and y being equal is caught in the very beginning of this function)
+
+	// case *instance:
+	//	unreachable since types are expanded
+
+	case *bottom, *top:
+		// Either both types are theBottom, or both are theTop in which
+		// case the initial x == y check will have caught them. Otherwise
+		// they are not identical.
+
 	case nil:
+		// avoid a crash in case of nil type
 
 	default:
 		unreachable()
@@ -315,6 +391,19 @@
 	return false
 }
 
+func (check *Checker) identicalTParams(x, y []*TypeName, cmpTags bool, p *ifacePair) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, x := range x {
+		y := y[i]
+		if !check.identical0(x.typ.(*_TypeParam).bound, y.typ.(*_TypeParam).bound, cmpTags, p) {
+			return false
+		}
+	}
+	return true
+}
+
 // Default returns the default "typed" type for an "untyped" type;
 // it returns the incoming type for all other types. The default type
 // for untyped nil is untyped nil.
diff --git a/src/go/types/resolver.go b/src/go/types/resolver.go
index b637f8b..114647a 100644
--- a/src/go/types/resolver.go
+++ b/src/go/types/resolver.go
@@ -8,6 +8,7 @@
 	"fmt"
 	"go/ast"
 	"go/constant"
+	"go/internal/typeparams"
 	"go/token"
 	"sort"
 	"strconv"
@@ -19,11 +20,11 @@
 type declInfo struct {
 	file      *Scope        // scope of file containing this declaration
 	lhs       []*Var        // lhs of n:1 variable declarations, or nil
-	typ       ast.Expr      // type, or nil
-	init      ast.Expr      // init/orig expression, or nil
+	vtyp      ast.Expr      // type, or nil (for const and var declarations only)
+	init      ast.Expr      // init/orig expression, or nil (for const and var declarations only)
 	inherited bool          // if set, the init expression is inherited from a previous constant declaration
+	tdecl     *ast.TypeSpec // type declaration, or nil
 	fdecl     *ast.FuncDecl // func declaration, or nil
-	alias     bool          // type alias declaration
 
 	// The deps field tracks initialization expression dependencies.
 	deps map[Object]bool // lazily initialized
@@ -130,7 +131,7 @@
 	return fmt.Sprintf("file[%d]", fileNo)
 }
 
-func (check *Checker) importPackage(pos token.Pos, path, dir string) *Package {
+func (check *Checker) importPackage(at positioner, path, dir string) *Package {
 	// If we already have a package for the given (path, dir)
 	// pair, use it instead of doing a full import.
 	// Checker.impMap only caches packages that are marked Complete
@@ -170,7 +171,7 @@
 			imp = nil // create fake package below
 		}
 		if err != nil {
-			check.errorf(atPos(pos), _BrokenImport, "could not import %s (%s)", path, err)
+			check.errorf(at, _BrokenImport, "could not import %s (%s)", path, err)
 			if imp == nil {
 				// create a new fake package
 				// come up with a sensible package name (heuristic)
@@ -191,7 +192,11 @@
 	// package should be complete or marked fake, but be cautious
 	if imp.complete || imp.fake {
 		check.impMap[key] = imp
-		check.pkgCnt[imp.name]++
+		// Once we've formatted an error message once, keep the pkgPathMap
+		// up-to-date on subsequent imports.
+		if check.pkgPathMap != nil {
+			check.markImports(imp)
+		}
 		return imp
 	}
 
@@ -216,7 +221,13 @@
 		pkgImports[imp] = true
 	}
 
-	var methods []*Func // list of methods with non-blank _ names
+	type methodInfo struct {
+		obj  *Func      // method
+		ptr  bool       // true if pointer receiver
+		recv *ast.Ident // receiver type name
+	}
+	var methods []methodInfo // collected methods with valid receivers and non-blank _ names
+	var fileScopes []*Scope
 	for fileNo, file := range check.files {
 		// The package identifier denotes the current package,
 		// but there is no corresponding package object.
@@ -230,6 +241,7 @@
 			pos, end = token.Pos(f.Base()), token.Pos(f.Base()+f.Size())
 		}
 		fileScope := NewScope(check.pkg.scope, pos, end, check.filename(fileNo))
+		fileScopes = append(fileScopes, fileScope)
 		check.recordScope(file, fileScope)
 
 		// determine file directory, necessary to resolve imports
@@ -247,19 +259,11 @@
 					return
 				}
 
-				imp := check.importPackage(d.spec.Path.Pos(), path, fileDir)
+				imp := check.importPackage(d.spec.Path, path, fileDir)
 				if imp == nil {
 					return
 				}
 
-				// add package to list of explicit imports
-				// (this functionality is provided as a convenience
-				// for clients; it is not needed for type-checking)
-				if !pkgImports[imp] {
-					pkgImports[imp] = true
-					pkg.imports = append(pkg.imports, imp)
-				}
-
 				// local name overrides imported package name
 				name := imp.name
 				if d.spec.Name != nil {
@@ -269,27 +273,41 @@
 						check.errorf(d.spec.Name, _ImportCRenamed, `cannot rename import "C"`)
 						return
 					}
-					if name == "init" {
-						check.errorf(d.spec.Name, _InvalidInitDecl, "cannot declare init - must be func")
-						return
-					}
 				}
 
-				obj := NewPkgName(d.spec.Pos(), pkg, name, imp)
+				if name == "init" {
+					check.errorf(d.spec.Name, _InvalidInitDecl, "cannot import package as init - init must be a func")
+					return
+				}
+
+				// add package to list of explicit imports
+				// (this functionality is provided as a convenience
+				// for clients; it is not needed for type-checking)
+				if !pkgImports[imp] {
+					pkgImports[imp] = true
+					pkg.imports = append(pkg.imports, imp)
+				}
+
+				pkgName := NewPkgName(d.spec.Pos(), pkg, name, imp)
 				if d.spec.Name != nil {
 					// in a dot-import, the dot represents the package
-					check.recordDef(d.spec.Name, obj)
+					check.recordDef(d.spec.Name, pkgName)
 				} else {
-					check.recordImplicit(d.spec, obj)
+					check.recordImplicit(d.spec, pkgName)
 				}
 
 				if path == "C" {
 					// match cmd/compile (not prescribed by spec)
-					obj.used = true
+					pkgName.used = true
 				}
 
 				// add import to file scope
+				check.imports = append(check.imports, pkgName)
 				if name == "." {
+					// dot-import
+					if check.dotImportMap == nil {
+						check.dotImportMap = make(map[dotImportKey]*PkgName)
+					}
 					// merge imported scope with file scope
 					for _, obj := range imp.scope.elems {
 						// A package scope may contain non-exported objects,
@@ -303,16 +321,15 @@
 							if alt := fileScope.Insert(obj); alt != nil {
 								check.errorf(d.spec.Name, _DuplicateDecl, "%s redeclared in this block", obj.Name())
 								check.reportAltDecl(alt)
+							} else {
+								check.dotImportMap[dotImportKey{fileScope, obj}] = pkgName
 							}
 						}
 					}
-					// add position to set of dot-import positions for this file
-					// (this is only needed for "imported but not used" errors)
-					check.addUnusedDotImport(fileScope, imp, d.spec)
 				} else {
 					// declare imported package object in file scope
 					// (no need to provide s.Name since we called check.recordDef earlier)
-					check.declare(fileScope, nil, obj, token.NoPos)
+					check.declare(fileScope, nil, pkgName, token.NoPos)
 				}
 			case constDecl:
 				// declare all constants
@@ -324,7 +341,7 @@
 						init = d.init[i]
 					}
 
-					d := &declInfo{file: fileScope, typ: d.typ, init: init, inherited: d.inherited}
+					d := &declInfo{file: fileScope, vtyp: d.typ, init: init, inherited: d.inherited}
 					check.declarePkgObj(name, obj, d)
 				}
 
@@ -339,7 +356,7 @@
 					// The lhs elements are only set up after the for loop below,
 					// but that's ok because declareVar only collects the declInfo
 					// for a later phase.
-					d1 = &declInfo{file: fileScope, lhs: lhs, typ: d.spec.Type, init: d.spec.Values[0]}
+					d1 = &declInfo{file: fileScope, lhs: lhs, vtyp: d.spec.Type, init: d.spec.Values[0]}
 				}
 
 				// declare all variables
@@ -354,26 +371,44 @@
 						if i < len(d.spec.Values) {
 							init = d.spec.Values[i]
 						}
-						di = &declInfo{file: fileScope, typ: d.spec.Type, init: init}
+						di = &declInfo{file: fileScope, vtyp: d.spec.Type, init: init}
 					}
 
 					check.declarePkgObj(name, obj, di)
 				}
 			case typeDecl:
 				obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil)
-				check.declarePkgObj(d.spec.Name, obj, &declInfo{file: fileScope, typ: d.spec.Type, alias: d.spec.Assign.IsValid()})
+				check.declarePkgObj(d.spec.Name, obj, &declInfo{file: fileScope, tdecl: d.spec})
 			case funcDecl:
 				info := &declInfo{file: fileScope, fdecl: d.decl}
 				name := d.decl.Name.Name
 				obj := NewFunc(d.decl.Name.Pos(), pkg, name, nil)
-				if d.decl.Recv == nil {
+				if d.decl.Recv.NumFields() == 0 {
 					// regular function
+					if d.decl.Recv != nil {
+						check.error(d.decl.Recv, _BadRecv, "method is missing receiver")
+						// treat as function
+					}
+					if name == "init" || (name == "main" && check.pkg.name == "main") {
+						code := _InvalidInitDecl
+						if name == "main" {
+							code = _InvalidMainDecl
+						}
+						if tparams := typeparams.Get(d.decl.Type); tparams != nil {
+							check.softErrorf(tparams, code, "func %s must have no type parameters", name)
+						}
+						if t := d.decl.Type; t.Params.NumFields() != 0 || t.Results != nil {
+							// TODO(rFindley) Should this be a hard error?
+							check.softErrorf(d.decl, code, "func %s must have no arguments and no return values", name)
+						}
+					}
 					if name == "init" {
 						// don't declare init functions in the package scope - they are invisible
 						obj.parent = pkg.scope
 						check.recordDef(d.decl.Name, obj)
 						// init functions must have a body
 						if d.decl.Body == nil {
+							// TODO(gri) make this error message consistent with the others above
 							check.softErrorf(obj, _MissingInitBody, "missing function body")
 						}
 					} else {
@@ -381,11 +416,18 @@
 					}
 				} else {
 					// method
-					// (Methods with blank _ names are never found; no need to collect
-					// them for later type association. They will still be type-checked
-					// with all the other functions.)
-					if name != "_" {
-						methods = append(methods, obj)
+
+					// TODO(rFindley) earlier versions of this code checked that methods
+					//                have no type parameters, but this is checked later
+					//                when type checking the function type. Confirm that
+					//                we don't need to check tparams here.
+
+					ptr, recv, _ := check.unpackRecv(d.decl.Recv.List[0].Type, false)
+					// (Methods with invalid receiver cannot be associated to a type, and
+					// methods with blank _ names are never found; no need to collect any
+					// of them. They will still be type-checked with all the other functions.)
+					if recv != nil && name != "_" {
+						methods = append(methods, methodInfo{obj, ptr, recv})
 					}
 					check.recordDef(d.decl.Name, obj)
 				}
@@ -400,7 +442,7 @@
 	}
 
 	// verify that objects in package and file scopes have different names
-	for _, scope := range check.pkg.scope.children /* file scopes */ {
+	for _, scope := range fileScopes {
 		for _, obj := range scope.elems {
 			if alt := pkg.scope.Lookup(obj.Name()); alt != nil {
 				if pkg, ok := obj.(*PkgName); ok {
@@ -423,31 +465,84 @@
 		return // nothing to do
 	}
 	check.methods = make(map[*TypeName][]*Func)
-	for _, f := range methods {
-		fdecl := check.objMap[f].fdecl
-		if list := fdecl.Recv.List; len(list) > 0 {
-			// f is a method.
-			// Determine the receiver base type and associate f with it.
-			ptr, base := check.resolveBaseTypeName(list[0].Type)
-			if base != nil {
-				f.hasPtrRecv = ptr
-				check.methods[base] = append(check.methods[base], f)
+	for i := range methods {
+		m := &methods[i]
+		// Determine the receiver base type and associate m with it.
+		ptr, base := check.resolveBaseTypeName(m.ptr, m.recv)
+		if base != nil {
+			m.obj.hasPtrRecv = ptr
+			check.methods[base] = append(check.methods[base], m.obj)
+		}
+	}
+}
+
+// unpackRecv unpacks a receiver type and returns its components: ptr indicates whether
+// rtyp is a pointer receiver, rname is the receiver type name, and tparams are its
+// type parameters, if any. The type parameters are only unpacked if unpackParams is
+// set. If rname is nil, the receiver is unusable (i.e., the source has a bug which we
+// cannot easily work around).
+func (check *Checker) unpackRecv(rtyp ast.Expr, unpackParams bool) (ptr bool, rname *ast.Ident, tparams []*ast.Ident) {
+L: // unpack receiver type
+	// This accepts invalid receivers such as ***T and does not
+	// work for other invalid receivers, but we don't care. The
+	// validity of receiver expressions is checked elsewhere.
+	for {
+		switch t := rtyp.(type) {
+		case *ast.ParenExpr:
+			rtyp = t.X
+		case *ast.StarExpr:
+			ptr = true
+			rtyp = t.X
+		default:
+			break L
+		}
+	}
+
+	// unpack type parameters, if any
+	if ptyp, _ := rtyp.(*ast.IndexExpr); ptyp != nil {
+		rtyp = ptyp.X
+		if unpackParams {
+			for _, arg := range typeparams.UnpackExpr(ptyp.Index) {
+				var par *ast.Ident
+				switch arg := arg.(type) {
+				case *ast.Ident:
+					par = arg
+				case *ast.BadExpr:
+					// ignore - error already reported by parser
+				case nil:
+					check.invalidAST(ptyp, "parameterized receiver contains nil parameters")
+				default:
+					check.errorf(arg, _Todo, "receiver type parameter %s must be an identifier", arg)
+				}
+				if par == nil {
+					par = &ast.Ident{NamePos: arg.Pos(), Name: "_"}
+				}
+				tparams = append(tparams, par)
 			}
 		}
 	}
+
+	// unpack receiver name
+	if name, _ := rtyp.(*ast.Ident); name != nil {
+		rname = name
+	}
+
+	return
 }
 
 // resolveBaseTypeName returns the non-alias base type name for typ, and whether
 // there was a pointer indirection to get to it. The base type name must be declared
 // in package scope, and there can be at most one pointer indirection. If no such type
 // name exists, the returned base is nil.
-func (check *Checker) resolveBaseTypeName(typ ast.Expr) (ptr bool, base *TypeName) {
+func (check *Checker) resolveBaseTypeName(seenPtr bool, name *ast.Ident) (ptr bool, base *TypeName) {
 	// Algorithm: Starting from a type expression, which may be a name,
 	// we follow that type through alias declarations until we reach a
 	// non-alias type name. If we encounter anything but pointer types or
 	// parentheses we're done. If we encounter more than one pointer type
 	// we're done.
+	ptr = seenPtr
 	var seen map[*TypeName]bool
+	var typ ast.Expr = name
 	for {
 		typ = unparen(typ)
 
@@ -487,13 +582,13 @@
 
 		// we're done if tdecl defined tname as a new type
 		// (rather than an alias)
-		tdecl := check.objMap[tname] // must exist for objects in package scope
-		if !tdecl.alias {
+		tdecl := check.objMap[tname].tdecl // must exist for objects in package scope
+		if !tdecl.Assign.IsValid() {
 			return ptr, tname
 		}
 
 		// otherwise, continue resolving
-		typ = tdecl.typ
+		typ = tdecl.Type
 		if seen == nil {
 			seen = make(map[*TypeName]bool)
 		}
@@ -515,7 +610,7 @@
 	// add new methods to already type-checked types (from a prior Checker.Files call)
 	for _, obj := range objList {
 		if obj, _ := obj.(*TypeName); obj != nil && obj.typ != nil {
-			check.addMethodDecls(obj)
+			check.collectMethods(obj)
 		}
 	}
 
@@ -529,7 +624,7 @@
 	// phase 1
 	for _, obj := range objList {
 		// If we have a type alias, collect it for the 2nd phase.
-		if tname, _ := obj.(*TypeName); tname != nil && check.objMap[tname].alias {
+		if tname, _ := obj.(*TypeName); tname != nil && check.objMap[tname].tdecl.Assign.IsValid() {
 			aliasList = append(aliasList, tname)
 			continue
 		}
@@ -566,39 +661,30 @@
 	// any of its exported identifiers. To import a package solely for its side-effects
 	// (initialization), use the blank identifier as explicit package name."
 
-	// check use of regular imported packages
-	for _, scope := range check.pkg.scope.children /* file scopes */ {
-		for _, obj := range scope.elems {
-			if obj, ok := obj.(*PkgName); ok {
-				// Unused "blank imports" are automatically ignored
-				// since _ identifiers are not entered into scopes.
-				if !obj.used {
-					path := obj.imported.path
-					base := pkgName(path)
-					if obj.name == base {
-						check.softErrorf(obj, _UnusedImport, "%q imported but not used", path)
-					} else {
-						check.softErrorf(obj, _UnusedImport, "%q imported but not used as %s", path, obj.name)
-					}
-				}
-			}
-		}
-	}
-
-	// check use of dot-imported packages
-	for _, unusedDotImports := range check.unusedDotImports {
-		for pkg, pos := range unusedDotImports {
-			check.softErrorf(pos, _UnusedImport, "%q imported but not used", pkg.path)
+	for _, obj := range check.imports {
+		if !obj.used && obj.name != "_" {
+			check.errorUnusedPkg(obj)
 		}
 	}
 }
 
-// pkgName returns the package name (last element) of an import path.
-func pkgName(path string) string {
-	if i := strings.LastIndex(path, "/"); i >= 0 {
-		path = path[i+1:]
+func (check *Checker) errorUnusedPkg(obj *PkgName) {
+	// If the package was imported with a name other than the final
+	// import path element, show it explicitly in the error message.
+	// Note that this handles both renamed imports and imports of
+	// packages containing unconventional package declarations.
+	// Note that this uses / always, even on Windows, because Go import
+	// paths always use forward slashes.
+	path := obj.imported.path
+	elem := path
+	if i := strings.LastIndex(elem, "/"); i >= 0 {
+		elem = elem[i+1:]
 	}
-	return path
+	if obj.name == "" || obj.name == "." || obj.name == elem {
+		check.softErrorf(obj, _UnusedImport, "%q imported but not used", path)
+	} else {
+		check.softErrorf(obj, _UnusedImport, "%q imported but not used as %s", path, obj.name)
+	}
 }
 
 // dir makes a good-faith attempt to return the directory
diff --git a/src/go/types/sanitize.go b/src/go/types/sanitize.go
new file mode 100644
index 0000000..727ec17
--- /dev/null
+++ b/src/go/types/sanitize.go
@@ -0,0 +1,206 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+// sanitizeInfo walks the types contained in info to ensure that all instances
+// are expanded.
+//
+// This includes some objects that may be shared across concurrent
+// type-checking passes (such as those in the universe scope), so we are
+// careful here not to write types that are already sanitized. This avoids a
+// data race as any shared types should already be sanitized.
+func sanitizeInfo(info *Info) {
+	var s sanitizer = make(map[Type]Type)
+
+	// Note: Some map entries are not references.
+	// If modified, they must be assigned back.
+
+	for e, tv := range info.Types {
+		if typ := s.typ(tv.Type); typ != tv.Type {
+			tv.Type = typ
+			info.Types[e] = tv
+		}
+	}
+
+	inferred := getInferred(info)
+	for e, inf := range inferred {
+		changed := false
+		for i, targ := range inf.Targs {
+			if typ := s.typ(targ); typ != targ {
+				inf.Targs[i] = typ
+				changed = true
+			}
+		}
+		if typ := s.typ(inf.Sig); typ != inf.Sig {
+			inf.Sig = typ.(*Signature)
+			changed = true
+		}
+		if changed {
+			inferred[e] = inf
+		}
+	}
+
+	for _, obj := range info.Defs {
+		if obj != nil {
+			if typ := s.typ(obj.Type()); typ != obj.Type() {
+				obj.setType(typ)
+			}
+		}
+	}
+
+	for _, obj := range info.Uses {
+		if obj != nil {
+			if typ := s.typ(obj.Type()); typ != obj.Type() {
+				obj.setType(typ)
+			}
+		}
+	}
+
+	// TODO(gri) sanitize as needed
+	// - info.Implicits
+	// - info.Selections
+	// - info.Scopes
+	// - info.InitOrder
+}
+
+type sanitizer map[Type]Type
+
+func (s sanitizer) typ(typ Type) Type {
+	if typ == nil {
+		return nil
+	}
+
+	if t, found := s[typ]; found {
+		return t
+	}
+	s[typ] = typ
+
+	switch t := typ.(type) {
+	case *Basic, *bottom, *top:
+		// nothing to do
+
+	case *Array:
+		if elem := s.typ(t.elem); elem != t.elem {
+			t.elem = elem
+		}
+
+	case *Slice:
+		if elem := s.typ(t.elem); elem != t.elem {
+			t.elem = elem
+		}
+
+	case *Struct:
+		s.varList(t.fields)
+
+	case *Pointer:
+		if base := s.typ(t.base); base != t.base {
+			t.base = base
+		}
+
+	case *Tuple:
+		s.tuple(t)
+
+	case *Signature:
+		s.var_(t.recv)
+		s.tuple(t.params)
+		s.tuple(t.results)
+
+	case *_Sum:
+		s.typeList(t.types)
+
+	case *Interface:
+		s.funcList(t.methods)
+		if types := s.typ(t.types); types != t.types {
+			t.types = types
+		}
+		s.typeList(t.embeddeds)
+		s.funcList(t.allMethods)
+		if allTypes := s.typ(t.allTypes); allTypes != t.allTypes {
+			t.allTypes = allTypes
+		}
+
+	case *Map:
+		if key := s.typ(t.key); key != t.key {
+			t.key = key
+		}
+		if elem := s.typ(t.elem); elem != t.elem {
+			t.elem = elem
+		}
+
+	case *Chan:
+		if elem := s.typ(t.elem); elem != t.elem {
+			t.elem = elem
+		}
+
+	case *Named:
+		if debug && t.check != nil {
+			panic("internal error: Named.check != nil")
+		}
+		if orig := s.typ(t.orig); orig != t.orig {
+			t.orig = orig
+		}
+		if under := s.typ(t.underlying); under != t.underlying {
+			t.underlying = under
+		}
+		s.typeList(t.targs)
+		s.funcList(t.methods)
+
+	case *_TypeParam:
+		if bound := s.typ(t.bound); bound != t.bound {
+			t.bound = bound
+		}
+
+	case *instance:
+		typ = t.expand()
+		s[t] = typ
+
+	default:
+		panic("unimplemented")
+	}
+
+	return typ
+}
+
+func (s sanitizer) var_(v *Var) {
+	if v != nil {
+		if typ := s.typ(v.typ); typ != v.typ {
+			v.typ = typ
+		}
+	}
+}
+
+func (s sanitizer) varList(list []*Var) {
+	for _, v := range list {
+		s.var_(v)
+	}
+}
+
+func (s sanitizer) tuple(t *Tuple) {
+	if t != nil {
+		s.varList(t.vars)
+	}
+}
+
+func (s sanitizer) func_(f *Func) {
+	if f != nil {
+		if typ := s.typ(f.typ); typ != f.typ {
+			f.typ = typ
+		}
+	}
+}
+
+func (s sanitizer) funcList(list []*Func) {
+	for _, f := range list {
+		s.func_(f)
+	}
+}
+
+func (s sanitizer) typeList(list []Type) {
+	for i, t := range list {
+		if typ := s.typ(t); typ != t {
+			list[i] = typ
+		}
+	}
+}
diff --git a/src/go/types/scope.go b/src/go/types/scope.go
index 8c9d9ab..26c28d1 100644
--- a/src/go/types/scope.go
+++ b/src/go/types/scope.go
@@ -108,6 +108,40 @@
 	return nil
 }
 
+// squash merges s with its parent scope p by adding all
+// objects of s to p, adding all children of s to the
+// children of p, and removing s from p's children.
+// The function f is called for each object obj in s which
+// has an object alt in p. s should be discarded after
+// having been squashed.
+func (s *Scope) squash(err func(obj, alt Object)) {
+	p := s.parent
+	assert(p != nil)
+	for _, obj := range s.elems {
+		obj.setParent(nil)
+		if alt := p.Insert(obj); alt != nil {
+			err(obj, alt)
+		}
+	}
+
+	j := -1 // index of s in p.children
+	for i, ch := range p.children {
+		if ch == s {
+			j = i
+			break
+		}
+	}
+	assert(j >= 0)
+	k := len(p.children) - 1
+	p.children[j] = p.children[k]
+	p.children = p.children[:k]
+
+	p.children = append(p.children, s.children...)
+
+	s.children = nil
+	s.elems = nil
+}
+
 // Pos and End describe the scope's source code extent [pos, end).
 // The results are guaranteed to be valid only if the type-checked
 // AST has complete position information. The extent is undefined
diff --git a/src/go/types/sizeof_test.go b/src/go/types/sizeof_test.go
new file mode 100644
index 0000000..5a9d07c
--- /dev/null
+++ b/src/go/types/sizeof_test.go
@@ -0,0 +1,63 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+	"reflect"
+	"testing"
+)
+
+// Signal size changes of important structures.
+func TestSizeof(t *testing.T) {
+	const _64bit = ^uint(0)>>32 != 0
+
+	var tests = []struct {
+		val    interface{} // type as a value
+		_32bit uintptr     // size on 32bit platforms
+		_64bit uintptr     // size on 64bit platforms
+	}{
+		// Types
+		{Basic{}, 16, 32},
+		{Array{}, 16, 24},
+		{Slice{}, 8, 16},
+		{Struct{}, 24, 48},
+		{Pointer{}, 8, 16},
+		{Tuple{}, 12, 24},
+		{Signature{}, 44, 88},
+		{_Sum{}, 12, 24},
+		{Interface{}, 60, 120},
+		{Map{}, 16, 32},
+		{Chan{}, 12, 24},
+		{Named{}, 64, 128},
+		{_TypeParam{}, 28, 48},
+		{instance{}, 44, 88},
+		{bottom{}, 0, 0},
+		{top{}, 0, 0},
+
+		// Objects
+		{PkgName{}, 48, 88},
+		{Const{}, 48, 88},
+		{TypeName{}, 40, 72},
+		{Var{}, 44, 80},
+		{Func{}, 44, 80},
+		{Label{}, 44, 80},
+		{Builtin{}, 44, 80},
+		{Nil{}, 40, 72},
+
+		// Misc
+		{Scope{}, 40, 80},
+		{Package{}, 40, 80},
+	}
+	for _, test := range tests {
+		got := reflect.TypeOf(test.val).Size()
+		want := test._32bit
+		if _64bit {
+			want = test._64bit
+		}
+		if got != want {
+			t.Errorf("unsafe.Sizeof(%T) = %d, want %d", test.val, got, want)
+		}
+	}
+}
diff --git a/src/go/types/sizes.go b/src/go/types/sizes.go
index 6ab6157..67052bb 100644
--- a/src/go/types/sizes.go
+++ b/src/go/types/sizes.go
@@ -48,7 +48,7 @@
 func (s *StdSizes) Alignof(T Type) int64 {
 	// For arrays and structs, alignment is defined in terms
 	// of alignment of the elements and fields, respectively.
-	switch t := T.Underlying().(type) {
+	switch t := optype(T).(type) {
 	case *Array:
 		// spec: "For a variable x of array type: unsafe.Alignof(x)
 		// is the same as unsafe.Alignof(x[0]), but at least 1."
@@ -118,7 +118,7 @@
 }
 
 func (s *StdSizes) Sizeof(T Type) int64 {
-	switch t := T.Underlying().(type) {
+	switch t := optype(T).(type) {
 	case *Basic:
 		assert(isTyped(T))
 		k := t.kind
@@ -148,6 +148,8 @@
 		}
 		offsets := s.Offsetsof(t.fields)
 		return offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
+	case *_Sum:
+		panic("Sizeof unimplemented for type sum")
 	case *Interface:
 		return s.WordSize * 2
 	}
@@ -239,7 +241,7 @@
 func (conf *Config) offsetof(typ Type, index []int) int64 {
 	var o int64
 	for _, i := range index {
-		s := typ.Underlying().(*Struct)
+		s := asStruct(typ)
 		o += conf.offsetsof(s)[i]
 		typ = s.fields[i].typ
 	}
diff --git a/src/go/types/stdlib_test.go b/src/go/types/stdlib_test.go
index 5ca4493..d86a77a 100644
--- a/src/go/types/stdlib_test.go
+++ b/src/go/types/stdlib_test.go
@@ -26,9 +26,15 @@
 	. "go/types"
 )
 
+// The cmd/*/internal packages may have been deleted as part of a binary
+// release. Import from source instead.
+//
+// (See https://golang.org/issue/43232 and
+// https://github.com/golang/build/blob/df58bbac082bc87c4a3cdfe336d1ffe60bbaa916/cmd/release/release.go#L533-L545.)
+//
 // Use the same importer for all std lib tests to
 // avoid repeated importing of the same packages.
-var stdLibImporter = importer.Default()
+var stdLibImporter = importer.ForCompiler(token.NewFileSet(), "source", nil)
 
 func TestStdlib(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
@@ -106,6 +112,7 @@
 		// get per-file instructions
 		expectErrors := false
 		filename := filepath.Join(path, f.Name())
+		goVersion := ""
 		if comment := firstComment(filename); comment != "" {
 			fields := strings.Fields(comment)
 			switch fields[0] {
@@ -115,13 +122,17 @@
 				expectErrors = true
 				for _, arg := range fields[1:] {
 					if arg == "-0" || arg == "-+" || arg == "-std" {
-						// Marked explicitly as not expected errors (-0),
+						// Marked explicitly as not expecting errors (-0),
 						// or marked as compiling runtime/stdlib, which is only done
 						// to trigger runtime/stdlib-only error output.
 						// In both cases, the code should typecheck.
 						expectErrors = false
 						break
 					}
+					const prefix = "-lang="
+					if strings.HasPrefix(arg, prefix) {
+						goVersion = arg[len(prefix):]
+					}
 				}
 			}
 		}
@@ -130,6 +141,7 @@
 		file, err := parser.ParseFile(fset, filename, nil, 0)
 		if err == nil {
 			conf := Config{Importer: stdLibImporter}
+			SetGoVersion(&conf, goVersion)
 			_, err = conf.Check(filename, fset, []*ast.File{file}, nil)
 		}
 
@@ -157,6 +169,7 @@
 		"directive.go",   // tests compiler rejection of bad directive placement - ignore
 		"embedfunc.go",   // tests //go:embed
 		"embedvers.go",   // tests //go:embed
+		"linkname2.go",   // go/types doesn't check validity of //go:xxx directives
 	)
 }
 
@@ -170,19 +183,15 @@
 	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
 		"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
 		"issue25507.go",  // go/types does not have constraints on stack size
 		"issue20780.go",  // go/types does not have constraints on stack size
-		"issue31747.go",  // go/types does not have constraints on language level (-lang=go1.12) (see #31793)
-		"issue34329.go",  // go/types does not have constraints on language level (-lang=go1.13) (see #31793)
 		"bug251.go",      // issue #34333 which was exposed with fix for #34151
 		"issue42058a.go", // go/types does not have constraints on channel element size
 		"issue42058b.go", // go/types does not have constraints on channel element size
@@ -198,6 +207,9 @@
 // Package paths of excluded packages.
 var excluded = map[string]bool{
 	"builtin": true,
+
+	// See #46027: some imports are missing for this submodule.
+	"crypto/ed25519/internal/edwards25519/field/_asm": true,
 }
 
 // typecheck typechecks the given package files.
diff --git a/src/go/types/stmt.go b/src/go/types/stmt.go
index d88e471..47f6dcf 100644
--- a/src/go/types/stmt.go
+++ b/src/go/types/stmt.go
@@ -14,6 +14,10 @@
 )
 
 func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body *ast.BlockStmt, iota constant.Value) {
+	if check.conf.IgnoreFuncBodies {
+		panic("internal error: function body not ignored")
+	}
+
 	if trace {
 		check.trace(body.Pos(), "--- %s: %s", name, sig)
 		defer func() {
@@ -49,6 +53,11 @@
 		check.error(atPos(body.Rbrace), _MissingReturn, "missing return")
 	}
 
+	// TODO(gri) Should we make it an error to declare generic functions
+	//           where the type parameters are not used?
+	// 12/19/2018: Probably not - it can make sense to have an API with
+	//           all functions uniformly sharing the same type parameters.
+
 	// spec: "Implementation restriction: A compiler may make it illegal to
 	// declare a variable inside a function body if the variable is never used."
 	check.usage(sig.scope)
@@ -147,9 +156,9 @@
 	}
 }
 
-func (check *Checker) openScope(s ast.Stmt, comment string) {
-	scope := NewScope(check.scope, s.Pos(), s.End(), comment)
-	check.recordScope(s, scope)
+func (check *Checker) openScope(node ast.Node, comment string) {
+	scope := NewScope(check.scope, node.Pos(), node.End(), comment)
+	check.recordScope(node, scope)
 	check.scope = scope
 }
 
@@ -269,10 +278,13 @@
 func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []ast.Expr, seen map[Type]ast.Expr) (T Type) {
 L:
 	for _, e := range types {
-		T = check.typOrNil(e)
+		T = check.typeOrNil(e)
 		if T == Typ[Invalid] {
 			continue L
 		}
+		if T != nil {
+			check.ordinaryType(e, T)
+		}
 		// look for duplicate types
 		// (quadratic algorithm, but type switches tend to be reasonably small)
 		for t, other := range seen {
@@ -355,8 +367,8 @@
 			return
 		}
 
-		tch, ok := ch.typ.Underlying().(*Chan)
-		if !ok {
+		tch := asChan(ch.typ)
+		if tch == nil {
 			check.invalidOp(inNode(s, s.Arrow), _InvalidSend, "cannot send to non-chan type %s", ch.typ)
 			return
 		}
@@ -609,7 +621,7 @@
 			return
 		}
 
-		// rhs must be of the form: expr.(type) and expr must be an interface
+		// rhs must be of the form: expr.(type) and expr must be an ordinary interface
 		expr, _ := rhs.(*ast.TypeAssertExpr)
 		if expr == nil || expr.Type != nil {
 			check.invalidAST(s, "incorrect form of type switch guard")
@@ -620,11 +632,12 @@
 		if x.mode == invalid {
 			return
 		}
-		xtyp, _ := x.typ.Underlying().(*Interface)
+		xtyp, _ := under(x.typ).(*Interface)
 		if xtyp == nil {
 			check.errorf(&x, _InvalidTypeSwitch, "%s is not an interface", &x)
 			return
 		}
+		check.ordinaryType(&x, xtyp)
 
 		check.multipleDefaults(s.Body.List)
 
@@ -761,43 +774,22 @@
 		// determine key/value types
 		var key, val Type
 		if x.mode != invalid {
-			switch typ := x.typ.Underlying().(type) {
-			case *Basic:
-				if isString(typ) {
-					key = Typ[Int]
-					val = universeRune // use 'rune' name
-				}
-			case *Array:
-				key = Typ[Int]
-				val = typ.elem
-			case *Slice:
-				key = Typ[Int]
-				val = typ.elem
-			case *Pointer:
-				if typ, _ := typ.base.Underlying().(*Array); typ != nil {
-					key = Typ[Int]
-					val = typ.elem
-				}
-			case *Map:
-				key = typ.key
-				val = typ.elem
-			case *Chan:
-				key = typ.elem
-				val = Typ[Invalid]
-				if typ.dir == SendOnly {
-					check.errorf(&x, _InvalidChanRange, "cannot range over send-only channel %s", &x)
-					// ok to continue
-				}
-				if s.Value != nil {
-					check.errorf(atPos(s.Value.Pos()), _InvalidIterVar, "iteration over %s permits only one iteration variable", &x)
-					// ok to continue
-				}
+			typ := optype(x.typ)
+			if _, ok := typ.(*Chan); ok && s.Value != nil {
+				// TODO(gri) this also needs to happen for channels in generic variables
+				check.softErrorf(atPos(s.Value.Pos()), _InvalidIterVar, "range over %s permits only one iteration variable", &x)
+				// ok to continue
 			}
-		}
-
-		if key == nil {
-			check.errorf(&x, _InvalidRangeExpr, "cannot range over %s", &x)
-			// ok to continue
+			var msg string
+			key, val, msg = rangeKeyVal(typ, isVarName(s.Key), isVarName(s.Value))
+			if key == nil || msg != "" {
+				if msg != "" {
+					// TODO(rFindley) should this be parenthesized, to be consistent with other qualifiers?
+					msg = ": " + msg
+				}
+				check.softErrorf(&x, _InvalidRangeExpr, "cannot range over %s%s", &x, msg)
+				// ok to continue
+			}
 		}
 
 		// check assignment to/declaration of iteration variables
@@ -879,3 +871,72 @@
 		check.invalidAST(s, "invalid statement")
 	}
 }
+
+// isVarName reports whether x is a non-nil, non-blank (_) expression.
+func isVarName(x ast.Expr) bool {
+	if x == nil {
+		return false
+	}
+	ident, _ := unparen(x).(*ast.Ident)
+	return ident == nil || ident.Name != "_"
+}
+
+// rangeKeyVal returns the key and value type produced by a range clause
+// over an expression of type typ, and possibly an error message. If the
+// range clause is not permitted the returned key is nil or msg is not
+// empty (in that case we still may have a non-nil key type which can be
+// used to reduce the chance for follow-on errors).
+// The wantKey, wantVal, and hasVal flags indicate which of the iteration
+// variables are used or present; this matters if we range over a generic
+// type where not all keys or values are of the same type.
+func rangeKeyVal(typ Type, wantKey, wantVal bool) (Type, Type, string) {
+	switch typ := typ.(type) {
+	case *Basic:
+		if isString(typ) {
+			return Typ[Int], universeRune, "" // use 'rune' name
+		}
+	case *Array:
+		return Typ[Int], typ.elem, ""
+	case *Slice:
+		return Typ[Int], typ.elem, ""
+	case *Pointer:
+		if typ := asArray(typ.base); typ != nil {
+			return Typ[Int], typ.elem, ""
+		}
+	case *Map:
+		return typ.key, typ.elem, ""
+	case *Chan:
+		var msg string
+		if typ.dir == SendOnly {
+			msg = "send-only channel"
+		}
+		return typ.elem, Typ[Invalid], msg
+	case *_Sum:
+		first := true
+		var key, val Type
+		var msg string
+		typ.is(func(t Type) bool {
+			k, v, m := rangeKeyVal(under(t), wantKey, wantVal)
+			if k == nil || m != "" {
+				key, val, msg = k, v, m
+				return false
+			}
+			if first {
+				key, val, msg = k, v, m
+				first = false
+				return true
+			}
+			if wantKey && !Identical(key, k) {
+				key, val, msg = nil, nil, "all possible values must have the same key type"
+				return false
+			}
+			if wantVal && !Identical(val, v) {
+				key, val, msg = nil, nil, "all possible values must have the same element type"
+				return false
+			}
+			return true
+		})
+		return key, val, msg
+	}
+	return nil, nil, ""
+}
diff --git a/src/go/types/subst.go b/src/go/types/subst.go
new file mode 100644
index 0000000..931375f
--- /dev/null
+++ b/src/go/types/subst.go
@@ -0,0 +1,543 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements instantiation of generic types
+// through substitution of type parameters by actual
+// types.
+
+package types
+
+import (
+	"bytes"
+	"fmt"
+	"go/token"
+)
+
+// TODO(rFindley) decide error codes for the errors in this file, and check
+//                if error spans can be improved
+
+type substMap struct {
+	// The targs field is currently needed for *Named type substitution.
+	// TODO(gri) rewrite that code, get rid of this field, and make this
+	//           struct just the map (proj)
+	targs []Type
+	proj  map[*_TypeParam]Type
+}
+
+// makeSubstMap creates a new substitution map mapping tpars[i] to targs[i].
+// If targs[i] is nil, tpars[i] is not substituted.
+func makeSubstMap(tpars []*TypeName, targs []Type) *substMap {
+	assert(len(tpars) == len(targs))
+	proj := make(map[*_TypeParam]Type, len(tpars))
+	for i, tpar := range tpars {
+		// We must expand type arguments otherwise *instance
+		// types end up as components in composite types.
+		// TODO(gri) explain why this causes problems, if it does
+		targ := expand(targs[i]) // possibly nil
+		targs[i] = targ
+		proj[tpar.typ.(*_TypeParam)] = targ
+	}
+	return &substMap{targs, proj}
+}
+
+func (m *substMap) String() string {
+	return fmt.Sprintf("%s", m.proj)
+}
+
+func (m *substMap) empty() bool {
+	return len(m.proj) == 0
+}
+
+func (m *substMap) lookup(tpar *_TypeParam) Type {
+	if t := m.proj[tpar]; t != nil {
+		return t
+	}
+	return tpar
+}
+
+func (check *Checker) instantiate(pos token.Pos, typ Type, targs []Type, poslist []token.Pos) (res Type) {
+	if trace {
+		check.trace(pos, "-- instantiating %s with %s", typ, typeListString(targs))
+		check.indent++
+		defer func() {
+			check.indent--
+			var under Type
+			if res != nil {
+				// Calling under() here may lead to endless instantiations.
+				// Test case: type T[P any] T[P]
+				// TODO(gri) investigate if that's a bug or to be expected.
+				under = res.Underlying()
+			}
+			check.trace(pos, "=> %s (under = %s)", res, under)
+		}()
+	}
+
+	assert(len(poslist) <= len(targs))
+
+	// TODO(gri) What is better here: work with TypeParams, or work with TypeNames?
+	var tparams []*TypeName
+	switch t := typ.(type) {
+	case *Named:
+		tparams = t.tparams
+	case *Signature:
+		tparams = t.tparams
+		defer func() {
+			// If we had an unexpected failure somewhere don't panic below when
+			// asserting res.(*Signature). Check for *Signature in case Typ[Invalid]
+			// is returned.
+			if _, ok := res.(*Signature); !ok {
+				return
+			}
+			// If the signature doesn't use its type parameters, subst
+			// will not make a copy. In that case, make a copy now (so
+			// we can set tparams to nil w/o causing side-effects).
+			if t == res {
+				copy := *t
+				res = &copy
+			}
+			// After instantiating a generic signature, it is not generic
+			// anymore; we need to set tparams to nil.
+			res.(*Signature).tparams = nil
+		}()
+
+	default:
+		check.dump("%v: cannot instantiate %v", pos, typ)
+		unreachable() // only defined types and (defined) functions can be generic
+	}
+
+	// the number of supplied types must match the number of type parameters
+	if len(targs) != len(tparams) {
+		// TODO(gri) provide better error message
+		check.errorf(atPos(pos), _Todo, "got %d arguments but %d type parameters", len(targs), len(tparams))
+		return Typ[Invalid]
+	}
+
+	if len(tparams) == 0 {
+		return typ // nothing to do (minor optimization)
+	}
+
+	smap := makeSubstMap(tparams, targs)
+
+	// check bounds
+	for i, tname := range tparams {
+		tpar := tname.typ.(*_TypeParam)
+		iface := tpar.Bound()
+		if iface.Empty() {
+			continue // no type bound
+		}
+
+		targ := targs[i]
+
+		// best position for error reporting
+		pos := pos
+		if i < len(poslist) {
+			pos = poslist[i]
+		}
+
+		// The type parameter bound is parameterized with the same type parameters
+		// as the instantiated type; before we can use it for bounds checking we
+		// need to instantiate it with the type arguments with which we instantiate
+		// the parameterized type.
+		iface = check.subst(pos, iface, smap).(*Interface)
+
+		// targ must implement iface (methods)
+		// - check only if we have methods
+		check.completeInterface(token.NoPos, iface)
+		if len(iface.allMethods) > 0 {
+			// If the type argument is a pointer to a type parameter, the type argument's
+			// method set is empty.
+			// TODO(gri) is this what we want? (spec question)
+			if base, isPtr := deref(targ); isPtr && asTypeParam(base) != nil {
+				check.errorf(atPos(pos), 0, "%s has no methods", targ)
+				break
+			}
+			if m, wrong := check.missingMethod(targ, iface, true); m != nil {
+				// TODO(gri) needs to print updated name to avoid major confusion in error message!
+				//           (print warning for now)
+				// Old warning:
+				// check.softErrorf(pos, "%s does not satisfy %s (warning: name not updated) = %s (missing method %s)", targ, tpar.bound, iface, m)
+				if m.name == "==" {
+					// We don't want to report "missing method ==".
+					check.softErrorf(atPos(pos), 0, "%s does not satisfy comparable", targ)
+				} else if wrong != nil {
+					// TODO(gri) This can still report uninstantiated types which makes the error message
+					//           more difficult to read then necessary.
+					// TODO(rFindley) should this use parentheses rather than ':' for qualification?
+					check.softErrorf(atPos(pos), _Todo,
+						"%s does not satisfy %s: wrong method signature\n\tgot  %s\n\twant %s",
+						targ, tpar.bound, wrong, m,
+					)
+				} else {
+					check.softErrorf(atPos(pos), 0, "%s does not satisfy %s (missing method %s)", targ, tpar.bound, m.name)
+				}
+				break
+			}
+		}
+
+		// targ's underlying type must also be one of the interface types listed, if any
+		if iface.allTypes == nil {
+			continue // nothing to do
+		}
+
+		// If targ is itself a type parameter, each of its possible types, but at least one, must be in the
+		// list of iface types (i.e., the targ type list must be a non-empty subset of the iface types).
+		if targ := asTypeParam(targ); targ != nil {
+			targBound := targ.Bound()
+			if targBound.allTypes == nil {
+				check.softErrorf(atPos(pos), _Todo, "%s does not satisfy %s (%s has no type constraints)", targ, tpar.bound, targ)
+				break
+			}
+			for _, t := range unpackType(targBound.allTypes) {
+				if !iface.isSatisfiedBy(t) {
+					// TODO(gri) match this error message with the one below (or vice versa)
+					check.softErrorf(atPos(pos), 0, "%s does not satisfy %s (%s type constraint %s not found in %s)", targ, tpar.bound, targ, t, iface.allTypes)
+					break
+				}
+			}
+			break
+		}
+
+		// Otherwise, targ's type or underlying type must also be one of the interface types listed, if any.
+		if !iface.isSatisfiedBy(targ) {
+			check.softErrorf(atPos(pos), _Todo, "%s does not satisfy %s (%s or %s not found in %s)", targ, tpar.bound, targ, under(targ), iface.allTypes)
+			break
+		}
+	}
+
+	return check.subst(pos, typ, smap)
+}
+
+// subst returns the type typ with its type parameters tpars replaced by
+// the corresponding type arguments targs, recursively.
+// subst is functional in the sense that it doesn't modify the incoming
+// type. If a substitution took place, the result type is different from
+// from the incoming type.
+func (check *Checker) subst(pos token.Pos, typ Type, smap *substMap) Type {
+	if smap.empty() {
+		return typ
+	}
+
+	// common cases
+	switch t := typ.(type) {
+	case *Basic:
+		return typ // nothing to do
+	case *_TypeParam:
+		return smap.lookup(t)
+	}
+
+	// general case
+	subst := subster{check, pos, make(map[Type]Type), smap}
+	return subst.typ(typ)
+}
+
+type subster struct {
+	check *Checker
+	pos   token.Pos
+	cache map[Type]Type
+	smap  *substMap
+}
+
+func (subst *subster) typ(typ Type) Type {
+	switch t := typ.(type) {
+	case nil:
+		// Call typOrNil if it's possible that typ is nil.
+		panic("nil typ")
+
+	case *Basic, *bottom, *top:
+		// nothing to do
+
+	case *Array:
+		elem := subst.typOrNil(t.elem)
+		if elem != t.elem {
+			return &Array{len: t.len, elem: elem}
+		}
+
+	case *Slice:
+		elem := subst.typOrNil(t.elem)
+		if elem != t.elem {
+			return &Slice{elem: elem}
+		}
+
+	case *Struct:
+		if fields, copied := subst.varList(t.fields); copied {
+			return &Struct{fields: fields, tags: t.tags}
+		}
+
+	case *Pointer:
+		base := subst.typ(t.base)
+		if base != t.base {
+			return &Pointer{base: base}
+		}
+
+	case *Tuple:
+		return subst.tuple(t)
+
+	case *Signature:
+		// TODO(gri) rethink the recv situation with respect to methods on parameterized types
+		// recv := subst.var_(t.recv) // TODO(gri) this causes a stack overflow - explain
+		recv := t.recv
+		params := subst.tuple(t.params)
+		results := subst.tuple(t.results)
+		if recv != t.recv || params != t.params || results != t.results {
+			return &Signature{
+				rparams: t.rparams,
+				// TODO(rFindley) why can't we nil out tparams here, rather than in
+				//                instantiate above?
+				tparams:  t.tparams,
+				scope:    t.scope,
+				recv:     recv,
+				params:   params,
+				results:  results,
+				variadic: t.variadic,
+			}
+		}
+
+	case *_Sum:
+		types, copied := subst.typeList(t.types)
+		if copied {
+			// Don't do it manually, with a Sum literal: the new
+			// types list may not be unique and NewSum may remove
+			// duplicates.
+			return _NewSum(types)
+		}
+
+	case *Interface:
+		methods, mcopied := subst.funcList(t.methods)
+		types := t.types
+		if t.types != nil {
+			types = subst.typ(t.types)
+		}
+		embeddeds, ecopied := subst.typeList(t.embeddeds)
+		if mcopied || types != t.types || ecopied {
+			iface := &Interface{methods: methods, types: types, embeddeds: embeddeds}
+			subst.check.posMap[iface] = subst.check.posMap[t] // satisfy completeInterface requirement
+			subst.check.completeInterface(token.NoPos, iface)
+			return iface
+		}
+
+	case *Map:
+		key := subst.typ(t.key)
+		elem := subst.typ(t.elem)
+		if key != t.key || elem != t.elem {
+			return &Map{key: key, elem: elem}
+		}
+
+	case *Chan:
+		elem := subst.typ(t.elem)
+		if elem != t.elem {
+			return &Chan{dir: t.dir, elem: elem}
+		}
+
+	case *Named:
+		subst.check.indent++
+		defer func() {
+			subst.check.indent--
+		}()
+		dump := func(format string, args ...interface{}) {
+			if trace {
+				subst.check.trace(subst.pos, format, args...)
+			}
+		}
+
+		if t.tparams == nil {
+			dump(">>> %s is not parameterized", t)
+			return t // type is not parameterized
+		}
+
+		var newTargs []Type
+
+		if len(t.targs) > 0 {
+			// already instantiated
+			dump(">>> %s already instantiated", t)
+			assert(len(t.targs) == len(t.tparams))
+			// For each (existing) type argument targ, determine if it needs
+			// to be substituted; i.e., if it is or contains a type parameter
+			// that has a type argument for it.
+			for i, targ := range t.targs {
+				dump(">>> %d targ = %s", i, targ)
+				newTarg := subst.typ(targ)
+				if newTarg != targ {
+					dump(">>> substituted %d targ %s => %s", i, targ, newTarg)
+					if newTargs == nil {
+						newTargs = make([]Type, len(t.tparams))
+						copy(newTargs, t.targs)
+					}
+					newTargs[i] = newTarg
+				}
+			}
+
+			if newTargs == nil {
+				dump(">>> nothing to substitute in %s", t)
+				return t // nothing to substitute
+			}
+		} else {
+			// not yet instantiated
+			dump(">>> first instantiation of %s", t)
+			// TODO(rFindley) can we instead subst the tparam types here?
+			newTargs = subst.smap.targs
+		}
+
+		// before creating a new named type, check if we have this one already
+		h := instantiatedHash(t, newTargs)
+		dump(">>> new type hash: %s", h)
+		if named, found := subst.check.typMap[h]; found {
+			dump(">>> found %s", named)
+			subst.cache[t] = named
+			return named
+		}
+
+		// create a new named type and populate caches to avoid endless recursion
+		tname := NewTypeName(subst.pos, t.obj.pkg, t.obj.name, nil)
+		named := subst.check.newNamed(tname, t.underlying, t.methods) // method signatures are updated lazily
+		named.tparams = t.tparams                                     // new type is still parameterized
+		named.targs = newTargs
+		subst.check.typMap[h] = named
+		subst.cache[t] = named
+
+		// do the substitution
+		dump(">>> subst %s with %s (new: %s)", t.underlying, subst.smap, newTargs)
+		named.underlying = subst.typOrNil(t.underlying)
+		named.orig = named.underlying // for cycle detection (Checker.validType)
+
+		return named
+
+	case *_TypeParam:
+		return subst.smap.lookup(t)
+
+	case *instance:
+		// TODO(gri) can we avoid the expansion here and just substitute the type parameters?
+		return subst.typ(t.expand())
+
+	default:
+		panic("unimplemented")
+	}
+
+	return typ
+}
+
+// TODO(gri) Eventually, this should be more sophisticated.
+//           It won't work correctly for locally declared types.
+func instantiatedHash(typ *Named, targs []Type) string {
+	var buf bytes.Buffer
+	writeTypeName(&buf, typ.obj, nil)
+	buf.WriteByte('[')
+	writeTypeList(&buf, targs, nil, nil)
+	buf.WriteByte(']')
+
+	// With respect to the represented type, whether a
+	// type is fully expanded or stored as instance
+	// does not matter - they are the same types.
+	// Remove the instanceMarkers printed for instances.
+	res := buf.Bytes()
+	i := 0
+	for _, b := range res {
+		if b != instanceMarker {
+			res[i] = b
+			i++
+		}
+	}
+
+	return string(res[:i])
+}
+
+func typeListString(list []Type) string {
+	var buf bytes.Buffer
+	writeTypeList(&buf, list, nil, nil)
+	return buf.String()
+}
+
+// typOrNil is like typ but if the argument is nil it is replaced with Typ[Invalid].
+// A nil type may appear in pathological cases such as type T[P any] []func(_ T([]_))
+// where an array/slice element is accessed before it is set up.
+func (subst *subster) typOrNil(typ Type) Type {
+	if typ == nil {
+		return Typ[Invalid]
+	}
+	return subst.typ(typ)
+}
+
+func (subst *subster) var_(v *Var) *Var {
+	if v != nil {
+		if typ := subst.typ(v.typ); typ != v.typ {
+			copy := *v
+			copy.typ = typ
+			return &copy
+		}
+	}
+	return v
+}
+
+func (subst *subster) tuple(t *Tuple) *Tuple {
+	if t != nil {
+		if vars, copied := subst.varList(t.vars); copied {
+			return &Tuple{vars: vars}
+		}
+	}
+	return t
+}
+
+func (subst *subster) varList(in []*Var) (out []*Var, copied bool) {
+	out = in
+	for i, v := range in {
+		if w := subst.var_(v); w != v {
+			if !copied {
+				// first variable that got substituted => allocate new out slice
+				// and copy all variables
+				new := make([]*Var, len(in))
+				copy(new, out)
+				out = new
+				copied = true
+			}
+			out[i] = w
+		}
+	}
+	return
+}
+
+func (subst *subster) func_(f *Func) *Func {
+	if f != nil {
+		if typ := subst.typ(f.typ); typ != f.typ {
+			copy := *f
+			copy.typ = typ
+			return &copy
+		}
+	}
+	return f
+}
+
+func (subst *subster) funcList(in []*Func) (out []*Func, copied bool) {
+	out = in
+	for i, f := range in {
+		if g := subst.func_(f); g != f {
+			if !copied {
+				// first function that got substituted => allocate new out slice
+				// and copy all functions
+				new := make([]*Func, len(in))
+				copy(new, out)
+				out = new
+				copied = true
+			}
+			out[i] = g
+		}
+	}
+	return
+}
+
+func (subst *subster) typeList(in []Type) (out []Type, copied bool) {
+	out = in
+	for i, t := range in {
+		if u := subst.typ(t); u != t {
+			if !copied {
+				// first function that got substituted => allocate new out slice
+				// and copy all functions
+				new := make([]Type, len(in))
+				copy(new, out)
+				out = new
+				copied = true
+			}
+			out[i] = u
+		}
+	}
+	return
+}
diff --git a/src/go/types/testdata/builtins.src b/src/go/types/testdata/builtins.src
deleted file mode 100644
index 98830eb..0000000
--- a/src/go/types/testdata/builtins.src
+++ /dev/null
@@ -1,902 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// builtin calls
-
-package builtins
-
-import "unsafe"
-
-func f0() {}
-
-func append1() {
-	var b byte
-	var x int
-	var s []byte
-	_ = append() // ERROR not enough arguments
-	_ = append("foo" /* ERROR not a slice */ )
-	_ = append(nil /* ERROR not a slice */ , s)
-	_ = append(x /* ERROR not a slice */ , s)
-	_ = append(s)
-	_ = append(s, nil...)
-	append /* ERROR not used */ (s)
-
-	_ = append(s, b)
-	_ = append(s, x /* ERROR cannot use x */ )
-	_ = append(s, s /* ERROR cannot use s */ )
-	_ = append(s... /* ERROR can only use ... with matching parameter */ )
-	_ = append(s, b, s... /* ERROR can only use ... with matching parameter */ )
-	_ = append(s, 1, 2, 3)
-	_ = append(s, 1, 2, 3, x /* ERROR cannot use x */ , 5, 6, 6)
-	_ = append(s, 1, 2, s... /* ERROR can only use ... with matching parameter */ )
-	_ = append([]interface{}(nil), 1, 2, "foo", x, 3.1425, false)
-
-	type S []byte
-	type T string
-	var t T
-	_ = append(s, "foo" /* ERROR cannot use .* in argument to append */ )
-	_ = append(s, "foo"...)
-	_ = append(S(s), "foo" /* ERROR cannot use .* in argument to append */ )
-	_ = append(S(s), "foo"...)
-	_ = append(s, t /* ERROR cannot use t */ )
-	_ = append(s, t...)
-	_ = append(s, T("foo")...)
-	_ = append(S(s), t /* ERROR cannot use t */ )
-	_ = append(S(s), t...)
-	_ = append(S(s), T("foo")...)
-	_ = append([]string{}, t /* ERROR cannot use t */ , "foo")
-	_ = append([]T{}, t, "foo")
-}
-
-// from the spec
-func append2() {
-	s0 := []int{0, 0}
-	s1 := append(s0, 2)                // append a single element     s1 == []int{0, 0, 2}
-	s2 := append(s1, 3, 5, 7)          // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
-	s3 := append(s2, s0...)            // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
-	s4 := append(s3[3:6], s3[2:]...)   // append overlapping slice    s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
-
-	var t []interface{}
-	t = append(t, 42, 3.1415, "foo")   //                             t == []interface{}{42, 3.1415, "foo"}
-
-	var b []byte
-	b = append(b, "bar"...)            // append string contents      b == []byte{'b', 'a', 'r' }
-
-	_ = s4
-}
-
-func append3() {
-	f1 := func() (s []int) { return }
-	f2 := func() (s []int, x int) { return }
-	f3 := func() (s []int, x, y int) { return }
-	f5 := func() (s []interface{}, x int, y float32, z string, b bool) { return }
-	ff := func() (int, float32) { return 0, 0 }
-	_ = append(f0 /* ERROR used as value */ ())
-	_ = append(f1())
-	_ = append(f2())
-	_ = append(f3())
-	_ = append(f5())
-	_ = append(ff /* ERROR not a slice */ ()) // TODO(gri) better error message
-}
-
-func cap1() {
-	var a [10]bool
-	var p *[20]int
-	var c chan string
-	_ = cap() // ERROR not enough arguments
-	_ = cap(1, 2) // ERROR too many arguments
-	_ = cap(42 /* ERROR invalid */)
-	const _3 = cap(a)
-	assert(_3 == 10)
-	const _4 = cap(p)
-	assert(_4 == 20)
-	_ = cap(c)
-	cap /* ERROR not used */ (c)
-
-	// issue 4744
-	type T struct{ a [10]int }
-	const _ = cap(((*T)(nil)).a)
-
-	var s [][]byte
-	_ = cap(s)
-	_ = cap(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func cap2() {
-	f1a := func() (a [10]int) { return }
-	f1s := func() (s []int) { return }
-	f2 := func() (s []int, x int) { return }
-	_ = cap(f0 /* ERROR used as value */ ())
-	_ = cap(f1a())
-	_ = cap(f1s())
-	_ = cap(f2()) // ERROR too many arguments
-}
-
-// test cases for issue 7387
-func cap3() {
-	var f = func() int { return 0 }
-	var x = f()
-	const (
-		_ = cap([4]int{})
-		_ = cap([4]int{x})
-		_ = cap /* ERROR not constant */ ([4]int{f()})
-		_ = cap /* ERROR not constant */ ([4]int{cap([]int{})})
-		_ = cap([4]int{cap([4]int{})})
-	)
-	var y float64
-	var z complex128
-	const (
-		_ = cap([4]float64{})
-		_ = cap([4]float64{y})
-		_ = cap([4]float64{real(2i)})
-		_ = cap /* ERROR not constant */ ([4]float64{real(z)})
-	)
-	var ch chan [10]int
-	const (
-		_ = cap /* ERROR not constant */ (<-ch)
-		_ = cap /* ERROR not constant */ ([4]int{(<-ch)[0]})
-	)
-}
-
-func close1() {
-	var c chan int
-	var r <-chan int
-	close() // ERROR not enough arguments
-	close(1, 2) // ERROR too many arguments
-	close(42 /* ERROR not a channel */)
-	close(r /* ERROR receive-only channel */)
-	close(c)
-	_ = close /* ERROR used as value */ (c)
-
-	var s []chan int
-	close(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func close2() {
-	f1 := func() (ch chan int) { return }
-	f2 := func() (ch chan int, x int) { return }
-	close(f0 /* ERROR used as value */ ())
-	close(f1())
-	close(f2()) // ERROR too many arguments
-}
-
-func complex1() {
-	var i32 int32
-	var f32 float32
-	var f64 float64
-	var c64 complex64
-	var c128 complex128
-	_ = complex() // ERROR not enough arguments
-	_ = complex(1) // ERROR not enough arguments
-	_ = complex(true /* ERROR mismatched types */ , 0)
-	_ = complex(i32 /* ERROR expected floating-point */ , 0)
-	_ = complex("foo" /* ERROR mismatched types */ , 0)
-	_ = complex(c64 /* ERROR expected floating-point */ , 0)
-	_ = complex(0 /* ERROR mismatched types */ , true)
-	_ = complex(0 /* ERROR expected floating-point */ , i32)
-	_ = complex(0 /* ERROR mismatched types */ , "foo")
-	_ = complex(0 /* ERROR expected floating-point */ , c64)
-	_ = complex(f32, f32)
-	_ = complex(f32, 1)
-	_ = complex(f32, 1.0)
-	_ = complex(f32, 'a')
-	_ = complex(f64, f64)
-	_ = complex(f64, 1)
-	_ = complex(f64, 1.0)
-	_ = complex(f64, 'a')
-	_ = complex(f32 /* ERROR mismatched types */ , f64)
-	_ = complex(f64 /* ERROR mismatched types */ , f32)
-	_ = complex(1, 1)
-	_ = complex(1, 1.1)
-	_ = complex(1, 'a')
-	complex /* ERROR not used */ (1, 2)
-
-	var _ complex64 = complex(f32, f32)
-	var _ complex64 = complex /* ERROR cannot use .* in variable declaration */ (f64, f64)
-
-	var _ complex128 = complex /* ERROR cannot use .* in variable declaration */ (f32, f32)
-	var _ complex128 = complex(f64, f64)
-
-	// untyped constants
-	const _ int = complex(1, 0)
-	const _ float32 = complex(1, 0)
-	const _ complex64 = complex(1, 0)
-	const _ complex128 = complex(1, 0)
-	const _ = complex(0i, 0i)
-	const _ = complex(0i, 0)
-	const _ int = 1.0 + complex(1, 0i)
-
-	const _ int = complex /* ERROR int */ (1.1, 0)
-	const _ float32 = complex /* ERROR float32 */ (1, 2)
-
-	// untyped values
-	var s uint
-	_ = complex(1 /* ERROR integer */ <<s, 0)
-	const _ = complex /* ERROR not constant */ (1 /* ERROR integer */ <<s, 0)
-	var _ int = complex /* ERROR cannot use .* in variable declaration */ (1 /* ERROR integer */ <<s, 0)
-
-	// floating-point argument types must be identical
-	type F32 float32
-	type F64 float64
-	var x32 F32
-	var x64 F64
-	c64 = complex(x32, x32)
-	_ = complex(x32 /* ERROR mismatched types */ , f32)
-	_ = complex(f32 /* ERROR mismatched types */ , x32)
-	c128 = complex(x64, x64)
-	_ = c128
-	_ = complex(x64 /* ERROR mismatched types */ , f64)
-	_ = complex(f64 /* ERROR mismatched types */ , x64)
-
-	var t []float32
-	_ = complex(t... /* ERROR invalid use of \.\.\. */ )
-}
-
-func complex2() {
-	f1 := func() (x float32) { return }
-	f2 := func() (x, y float32) { return }
-	f3 := func() (x, y, z float32) { return }
-	_ = complex(f0 /* ERROR used as value */ ())
-	_ = complex(f1()) // ERROR not enough arguments
-	_ = complex(f2())
-	_ = complex(f3()) // ERROR too many arguments
-}
-
-func copy1() {
-	copy() // ERROR not enough arguments
-	copy("foo") // ERROR not enough arguments
-	copy([ /* ERROR copy expects slice arguments */ ...]int{}, []int{})
-	copy([ /* ERROR copy expects slice arguments */ ]int{}, [...]int{})
-	copy([ /* ERROR different element types */ ]int8{}, "foo")
-
-	// spec examples
-	var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
-	var s = make([]int, 6)
-	var b = make([]byte, 5)
-	n1 := copy(s, a[0:])            // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
-	n2 := copy(s, s[2:])            // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
-	n3 := copy(b, "Hello, World!")  // n3 == 5, b == []byte("Hello")
-	_, _, _ = n1, n2, n3
-
-	var t [][]int
-	copy(t, t)
-	copy(t /* ERROR copy expects slice arguments */ , nil)
-	copy(nil /* ERROR copy expects slice arguments */ , t)
-	copy(nil /* ERROR copy expects slice arguments */ , nil)
-	copy(t... /* ERROR invalid use of \.\.\. */ )
-}
-
-func copy2() {
-	f1 := func() (a []int) { return }
-	f2 := func() (a, b []int) { return }
-	f3 := func() (a, b, c []int) { return }
-	copy(f0 /* ERROR used as value */ ())
-	copy(f1()) // ERROR not enough arguments
-	copy(f2())
-	copy(f3()) // ERROR too many arguments
-}
-
-func delete1() {
-	var m map[string]int
-	var s string
-	delete() // ERROR not enough arguments
-	delete(1) // ERROR not enough arguments
-	delete(1, 2, 3) // ERROR too many arguments
-	delete(m, 0 /* ERROR not assignable */)
-	delete(m, s)
-	_ = delete /* ERROR used as value */ (m, s)
-
-	var t []map[string]string
-	delete(t... /* ERROR invalid use of \.\.\. */ )
-}
-
-func delete2() {
-	f1 := func() (m map[string]int) { return }
-	f2 := func() (m map[string]int, k string) { return }
-	f3 := func() (m map[string]int, k string, x float32) { return }
-	delete(f0 /* ERROR used as value */ ())
-	delete(f1()) // ERROR not enough arguments
-	delete(f2())
-	delete(f3()) // ERROR too many arguments
-}
-
-func imag1() {
-	var f32 float32
-	var f64 float64
-	var c64 complex64
-	var c128 complex128
-	_ = imag() // ERROR not enough arguments
-	_ = imag(1, 2) // ERROR too many arguments
-	_ = imag(10)
-	_ = imag(2.7182818)
-	_ = imag("foo" /* ERROR expected complex */)
-	_ = imag('a')
-	const _5 = imag(1 + 2i)
-	assert(_5 == 2)
-	f32 = _5
-	f64 = _5
-	const _6 = imag(0i)
-	assert(_6 == 0)
-	f32 = imag(c64)
-	f64 = imag(c128)
-	f32 = imag /* ERROR cannot use .* in assignment */ (c128)
-	f64 = imag /* ERROR cannot use .* in assignment */ (c64)
-	imag /* ERROR not used */ (c64)
-	_, _ = f32, f64
-
-	// complex type may not be predeclared
-	type C64 complex64
-	type C128 complex128
-	var x64 C64
-	var x128 C128
-	f32 = imag(x64)
-	f64 = imag(x128)
-
-	var a []complex64
-	_ = imag(a... /* ERROR invalid use of \.\.\. */ )
-
-	// if argument is untyped, result is untyped
-	const _ byte = imag(1.2 + 3i)
-	const _ complex128 = imag(1.2 + 3i)
-
-	// lhs constant shift operands are typed as complex128
-	var s uint
-	_ = imag(1 /* ERROR must be integer */ << s)
-}
-
-func imag2() {
-	f1 := func() (x complex128) { return }
-	f2 := func() (x, y complex128) { return }
-	_ = imag(f0 /* ERROR used as value */ ())
-	_ = imag(f1())
-	_ = imag(f2()) // ERROR too many arguments
-}
-
-func len1() {
-	const c = "foobar"
-	var a [10]bool
-	var p *[20]int
-	var m map[string]complex128
-	_ = len() // ERROR not enough arguments
-	_ = len(1, 2) // ERROR too many arguments
-	_ = len(42 /* ERROR invalid */)
-	const _3 = len(c)
-	assert(_3 == 6)
-	const _4 = len(a)
-	assert(_4 == 10)
-	const _5 = len(p)
-	assert(_5 == 20)
-	_ = len(m)
-	len /* ERROR not used */ (c)
-
-	// esoteric case
-	var t string
-	var hash map[interface{}][]*[10]int
-	const n = len /* ERROR not constant */ (hash[recover()][len(t)])
-	assert(n == 10) // ok because n has unknown value and no error is reported
-	var ch <-chan int
-	const nn = len /* ERROR not constant */ (hash[<-ch][len(t)])
-
-	// issue 4744
-	type T struct{ a [10]int }
-	const _ = len(((*T)(nil)).a)
-
-	var s [][]byte
-	_ = len(s)
-	_ = len(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func len2() {
-	f1 := func() (x []int) { return }
-	f2 := func() (x, y []int) { return }
-	_ = len(f0 /* ERROR used as value */ ())
-	_ = len(f1())
-	_ = len(f2()) // ERROR too many arguments
-}
-
-// test cases for issue 7387
-func len3() {
-	var f = func() int { return 0 }
-	var x = f()
-	const (
-		_ = len([4]int{})
-		_ = len([4]int{x})
-		_ = len /* ERROR not constant */ ([4]int{f()})
-		_ = len /* ERROR not constant */ ([4]int{len([]int{})})
-		_ = len([4]int{len([4]int{})})
-	)
-	var y float64
-	var z complex128
-	const (
-		_ = len([4]float64{})
-		_ = len([4]float64{y})
-		_ = len([4]float64{real(2i)})
-		_ = len /* ERROR not constant */ ([4]float64{real(z)})
-	)
-	var ch chan [10]int
-	const (
-		_ = len /* ERROR not constant */ (<-ch)
-		_ = len /* ERROR not constant */ ([4]int{(<-ch)[0]})
-	)
-}
-
-func make1() {
-	var n int
-	var m float32
-	var s uint
-
-	_ = make() // ERROR not enough arguments
-	_ = make(1 /* ERROR not a type */)
-	_ = make(int /* ERROR cannot make */)
-
-	// slices
-	_ = make/* ERROR arguments */ ([]int)
-	_ = make/* ERROR arguments */ ([]int, 2, 3, 4)
-	_ = make([]int, int /* ERROR not an expression */)
-	_ = make([]int, 10, float32 /* ERROR not an expression */)
-	_ = make([]int, "foo" /* ERROR cannot convert */)
-	_ = make([]int, 10, 2.3 /* ERROR truncated */)
-	_ = make([]int, 5, 10.0)
-	_ = make([]int, 0i)
-	_ = make([]int, 1.0)
-	_ = make([]int, 1.0<<s)
-	_ = make([]int, 1.1 /* ERROR int */ <<s)
-	_ = make([]int, - /* ERROR must not be negative */ 1, 10)
-	_ = make([]int, 0, - /* ERROR must not be negative */ 1)
-	_ = make([]int, - /* ERROR must not be negative */ 1, - /* ERROR must not be negative */ 1)
-	_ = make([]int, 1 /* ERROR overflows */ <<100, 1 /* ERROR overflows */ <<100)
-	_ = make([]int, 10 /* ERROR length and capacity swapped */ , 9)
-	_ = make([]int, 1 /* ERROR overflows */ <<100, 12345)
-	_ = make([]int, m /* ERROR must be integer */ )
-        _ = &make /* ERROR cannot take address */ ([]int, 0)
-
-	// maps
-	_ = make /* ERROR arguments */ (map[int]string, 10, 20)
-	_ = make(map[int]float32, int /* ERROR not an expression */)
-	_ = make(map[int]float32, "foo" /* ERROR cannot convert */)
-	_ = make(map[int]float32, 10)
-	_ = make(map[int]float32, n)
-	_ = make(map[int]float32, int64(n))
-	_ = make(map[string]bool, 10.0)
-	_ = make(map[string]bool, 10.0<<s)
-        _ = &make /* ERROR cannot take address */ (map[string]bool)
-
-	// channels
-	_ = make /* ERROR arguments */ (chan int, 10, 20)
-	_ = make(chan int, int /* ERROR not an expression */)
-	_ = make(chan<- int, "foo" /* ERROR cannot convert */)
-	_ = make(chan int, - /* ERROR must not be negative */ 10)
-	_ = make(<-chan float64, 10)
-	_ = make(chan chan int, n)
-	_ = make(chan string, int64(n))
-	_ = make(chan bool, 10.0)
-	_ = make(chan bool, 10.0<<s)
-        _ = &make /* ERROR cannot take address */ (chan bool)
-
-	make /* ERROR not used */ ([]int, 10)
-
-	var t []int
-	_ = make([]int, t[0], t[1])
-	_ = make([]int, t... /* ERROR invalid use of \.\.\. */ )
-}
-
-func make2() {
-	f1 /* ERROR not used */ := func() (x []int) { return }
-	_ = make(f0 /* ERROR not a type */ ())
-	_ = make(f1 /* ERROR not a type */ ())
-}
-
-func new1() {
-	_ = new() // ERROR not enough arguments
-	_ = new(1, 2) // ERROR too many arguments
-	_ = new("foo" /* ERROR not a type */)
-	p := new(float64)
-	_ = new(struct{ x, y int })
-	q := new(*float64)
-	_ = *p == **q
-	new /* ERROR not used */ (int)
-        _ = &new /* ERROR cannot take address */ (int)
-
-	_ = new(int... /* ERROR invalid use of \.\.\. */ )
-}
-
-func new2() {
-	f1 /* ERROR not used */ := func() (x []int) { return }
-	_ = new(f0 /* ERROR not a type */ ())
-	_ = new(f1 /* ERROR not a type */ ())
-}
-
-func panic1() {
-	panic() // ERROR not enough arguments
-	panic(1, 2) // ERROR too many arguments
-	panic(0)
-	panic("foo")
-	panic(false)
-	panic(1<<10)
-	panic(1 /* ERROR overflows */ <<1000)
-	_ = panic /* ERROR used as value */ (0)
-
-	var s []byte
-	panic(s)
-	panic(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func panic2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x, y int) { return }
-	panic(f0 /* ERROR used as value */ ())
-	panic(f1())
-	panic(f2()) // ERROR too many arguments
-}
-
-func print1() {
-	print()
-	print(1)
-	print(1, 2)
-	print("foo")
-	print(2.718281828)
-	print(false)
-	print(1<<10)
-	print(1 /* ERROR overflows */ <<1000)
-	println(nil /* ERROR untyped nil */ )
-
-	var s []int
-	print(s... /* ERROR invalid use of \.\.\. */ )
-	_ = print /* ERROR used as value */ ()
-}
-
-func print2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x, y int) { return }
-	f3 := func() (x int, y float32, z string) { return }
-	print(f0 /* ERROR used as value */ ())
-	print(f1())
-	print(f2())
-	print(f3())
-}
-
-func println1() {
-	println()
-	println(1)
-	println(1, 2)
-	println("foo")
-	println(2.718281828)
-	println(false)
-	println(1<<10)
-	println(1 /* ERROR overflows */ <<1000)
-	println(nil /* ERROR untyped nil */ )
-
-	var s []int
-	println(s... /* ERROR invalid use of \.\.\. */ )
-	_ = println /* ERROR used as value */ ()
-}
-
-func println2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x, y int) { return }
-	f3 := func() (x int, y float32, z string) { return }
-	println(f0 /* ERROR used as value */ ())
-	println(f1())
-	println(f2())
-	println(f3())
-}
-
-func real1() {
-	var f32 float32
-	var f64 float64
-	var c64 complex64
-	var c128 complex128
-	_ = real() // ERROR not enough arguments
-	_ = real(1, 2) // ERROR too many arguments
-	_ = real(10)
-	_ = real(2.7182818)
-	_ = real("foo" /* ERROR expected complex */)
-	const _5 = real(1 + 2i)
-	assert(_5 == 1)
-	f32 = _5
-	f64 = _5
-	const _6 = real(0i)
-	assert(_6 == 0)
-	f32 = real(c64)
-	f64 = real(c128)
-	f32 = real /* ERROR cannot use .* in assignment */ (c128)
-	f64 = real /* ERROR cannot use .* in assignment */ (c64)
-	real /* ERROR not used */ (c64)
-
-	// complex type may not be predeclared
-	type C64 complex64
-	type C128 complex128
-	var x64 C64
-	var x128 C128
-	f32 = imag(x64)
-	f64 = imag(x128)
-	_, _ = f32, f64
-
-	var a []complex64
-	_ = real(a... /* ERROR invalid use of \.\.\. */ )
-
-	// if argument is untyped, result is untyped
-	const _ byte = real(1 + 2.3i)
-	const _ complex128 = real(1 + 2.3i)
-
-	// lhs constant shift operands are typed as complex128
-	var s uint
-	_ = real(1 /* ERROR must be integer */ << s)
-}
-
-func real2() {
-	f1 := func() (x complex128) { return }
-	f2 := func() (x, y complex128) { return }
-	_ = real(f0 /* ERROR used as value */ ())
-	_ = real(f1())
-	_ = real(f2()) // ERROR too many arguments
-}
-
-func recover1() {
-	_ = recover()
-	_ = recover(10) // ERROR too many arguments
-	recover()
-
-	var s []int
-	recover(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func recover2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x, y int) { return }
-	_ = recover(f0 /* ERROR used as value */ ())
-	_ = recover(f1()) // ERROR too many arguments
-	_ = recover(f2()) // ERROR too many arguments
-}
-
-// assuming types.DefaultPtrSize == 8
-type S0 struct{      // offset
-	a bool       //  0
-	b rune       //  4
-	c *int       //  8
-	d bool       // 16
-	e complex128 // 24
-}                    // 40
-
-type S1 struct{   // offset
-	x float32 //  0
-	y string  //  8
-	z *S1     // 24
-	S0        // 32
-}                 // 72
-
-type S2 struct{ // offset
-	*S1     //  0
-}               //  8
-
-type S3 struct { // offset
-	a int64  //  0
-	b int32  //  8
-}                // 12
-
-type S4 struct { // offset
-	S3       //  0
-	int32    // 12
-}                // 16
-
-type S5 struct {   // offset
-	a [3]int32 //  0
-	b int32    // 12
-}                  // 16
-
-func (S2) m() {}
-
-func Alignof1() {
-	var x int
-	_ = unsafe.Alignof() // ERROR not enough arguments
-	_ = unsafe.Alignof(1, 2) // ERROR too many arguments
-	_ = unsafe.Alignof(int /* ERROR not an expression */)
-	_ = unsafe.Alignof(42)
-	_ = unsafe.Alignof(new(struct{}))
-	_ = unsafe.Alignof(1<<10)
-	_ = unsafe.Alignof(1 /* ERROR overflows */ <<1000)
-	_ = unsafe.Alignof(nil /* ERROR "untyped nil */ )
-	unsafe /* ERROR not used */ .Alignof(x)
-
-	var y S0
-	assert(unsafe.Alignof(y.a) == 1)
-	assert(unsafe.Alignof(y.b) == 4)
-	assert(unsafe.Alignof(y.c) == 8)
-	assert(unsafe.Alignof(y.d) == 1)
-	assert(unsafe.Alignof(y.e) == 8)
-
-	var s []byte
-	_ = unsafe.Alignof(s)
-	_ = unsafe.Alignof(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func Alignof2() {
-	f1 := func() (x int32) { return }
-	f2 := func() (x, y int32) { return }
-	_ = unsafe.Alignof(f0 /* ERROR used as value */ ())
-	assert(unsafe.Alignof(f1()) == 4)
-	_ = unsafe.Alignof(f2()) // ERROR too many arguments
-}
-
-func Offsetof1() {
-	var x struct{ f int }
-	_ = unsafe.Offsetof() // ERROR not enough arguments
-	_ = unsafe.Offsetof(1, 2) // ERROR too many arguments
-	_ = unsafe.Offsetof(int /* ERROR not a selector expression */ )
-	_ = unsafe.Offsetof(x /* ERROR not a selector expression */ )
-	_ = unsafe.Offsetof(nil /* ERROR not a selector expression */ )
-	_ = unsafe.Offsetof(x.f)
-	_ = unsafe.Offsetof((x.f))
-	_ = unsafe.Offsetof((((((((x))).f)))))
-	unsafe /* ERROR not used */ .Offsetof(x.f)
-
-	var y0 S0
-	assert(unsafe.Offsetof(y0.a) == 0)
-	assert(unsafe.Offsetof(y0.b) == 4)
-	assert(unsafe.Offsetof(y0.c) == 8)
-	assert(unsafe.Offsetof(y0.d) == 16)
-	assert(unsafe.Offsetof(y0.e) == 24)
-
-	var y1 S1
-	assert(unsafe.Offsetof(y1.x) == 0)
-	assert(unsafe.Offsetof(y1.y) == 8)
-	assert(unsafe.Offsetof(y1.z) == 24)
-	assert(unsafe.Offsetof(y1.S0) == 32)
-
-	assert(unsafe.Offsetof(y1.S0.a) == 0) // relative to S0
-	assert(unsafe.Offsetof(y1.a) == 32)   // relative to S1
-	assert(unsafe.Offsetof(y1.b) == 36)   // relative to S1
-	assert(unsafe.Offsetof(y1.c) == 40)   // relative to S1
-	assert(unsafe.Offsetof(y1.d) == 48)   // relative to S1
-	assert(unsafe.Offsetof(y1.e) == 56)   // relative to S1
-
-	var y1p *S1
-	assert(unsafe.Offsetof(y1p.S0) == 32)
-
-	type P *S1
-	var p P = y1p
-	assert(unsafe.Offsetof(p.S0) == 32)
-
-	var y2 S2
-	assert(unsafe.Offsetof(y2.S1) == 0)
-	_ = unsafe.Offsetof(y2 /* ERROR embedded via a pointer */ .x)
-	_ = unsafe.Offsetof(y2 /* ERROR method value */ .m)
-
-	var s []byte
-	_ = unsafe.Offsetof(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func Offsetof2() {
-	f1 := func() (x int32) { return }
-	f2 := func() (x, y int32) { return }
-	_ = unsafe.Offsetof(f0 /* ERROR not a selector expression */ ())
-	_ = unsafe.Offsetof(f1 /* ERROR not a selector expression */ ())
-	_ = unsafe.Offsetof(f2 /* ERROR not a selector expression */ ())
-}
-
-func Sizeof1() {
-	var x int
-	_ = unsafe.Sizeof() // ERROR not enough arguments
-	_ = unsafe.Sizeof(1, 2) // ERROR too many arguments
-	_ = unsafe.Sizeof(int /* ERROR not an expression */)
-	_ = unsafe.Sizeof(42)
-	_ = unsafe.Sizeof(new(complex128))
-	_ = unsafe.Sizeof(1<<10)
-	_ = unsafe.Sizeof(1 /* ERROR overflows */ <<1000)
-	_ = unsafe.Sizeof(nil /* ERROR untyped nil */ )
-	unsafe /* ERROR not used */ .Sizeof(x)
-
-	// basic types have size guarantees
-	assert(unsafe.Sizeof(byte(0)) == 1)
-	assert(unsafe.Sizeof(uint8(0)) == 1)
-	assert(unsafe.Sizeof(int8(0)) == 1)
-	assert(unsafe.Sizeof(uint16(0)) == 2)
-	assert(unsafe.Sizeof(int16(0)) == 2)
-	assert(unsafe.Sizeof(uint32(0)) == 4)
-	assert(unsafe.Sizeof(int32(0)) == 4)
-	assert(unsafe.Sizeof(float32(0)) == 4)
-	assert(unsafe.Sizeof(uint64(0)) == 8)
-	assert(unsafe.Sizeof(int64(0)) == 8)
-	assert(unsafe.Sizeof(float64(0)) == 8)
-	assert(unsafe.Sizeof(complex64(0)) == 8)
-	assert(unsafe.Sizeof(complex128(0)) == 16)
-
-	var y0 S0
-	assert(unsafe.Sizeof(y0.a) == 1)
-	assert(unsafe.Sizeof(y0.b) == 4)
-	assert(unsafe.Sizeof(y0.c) == 8)
-	assert(unsafe.Sizeof(y0.d) == 1)
-	assert(unsafe.Sizeof(y0.e) == 16)
-	assert(unsafe.Sizeof(y0) == 40)
-
-	var y1 S1
-	assert(unsafe.Sizeof(y1) == 72)
-
-	var y2 S2
-	assert(unsafe.Sizeof(y2) == 8)
-
-	var y3 S3
-	assert(unsafe.Sizeof(y3) == 12)
-
-	var y4 S4
-	assert(unsafe.Sizeof(y4) == 16)
-
-	var y5 S5
-	assert(unsafe.Sizeof(y5) == 16)
-
-	var a3 [10]S3
-	assert(unsafe.Sizeof(a3) == 156)
-
-	// test case for issue 5670
-	type T struct {
-		a int32
-		_ int32
-		c int32
-	}
-	assert(unsafe.Sizeof(T{}) == 12)
-
-	var s []byte
-	_ = unsafe.Sizeof(s)
-	_ = unsafe.Sizeof(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func Sizeof2() {
-	f1 := func() (x int64) { return }
-	f2 := func() (x, y int64) { return }
-	_ = unsafe.Sizeof(f0 /* ERROR used as value */ ())
-	assert(unsafe.Sizeof(f1()) == 8)
-	_ = unsafe.Sizeof(f2()) // ERROR too many arguments
-}
-
-// self-testing only
-func assert1() {
-	var x int
-	assert() /* ERROR not enough arguments */
-	assert(1, 2) /* ERROR too many arguments */
-	assert("foo" /* ERROR boolean constant */ )
-	assert(x /* ERROR boolean constant */)
-	assert(true)
-	assert /* ERROR failed */ (false)
-	_ = assert(true)
-
-	var s []byte
-	assert(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func assert2() {
-	f1 := func() (x bool) { return }
-	f2 := func() (x bool) { return }
-	assert(f0 /* ERROR used as value */ ())
-	assert(f1 /* ERROR boolean constant */ ())
-	assert(f2 /* ERROR boolean constant */ ())
-}
-
-// self-testing only
-func trace1() {
-	// Uncomment the code below to test trace - will produce console output
-	// _ = trace /* ERROR no value */ ()
-	// _ = trace(1)
-	// _ = trace(true, 1.2, '\'', "foo", 42i, "foo" <= "bar")
-
-	var s []byte
-	trace(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func trace2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x int, y string) { return }
-	f3 := func() (x int, y string, z []int) { return }
-	_ = f1
-	_ = f2
-	_ = f3
-	// Uncomment the code below to test trace - will produce console output
-	// trace(f0())
-	// trace(f1())
-	// trace(f2())
-	// trace(f3())
-	// trace(f0(), 1)
-	// trace(f1(), 1, 2)
-	// trace(f2(), 1, 2, 3)
-	// trace(f3(), 1, 2, 3, 4)
-}
diff --git a/src/go/types/testdata/blank.src b/src/go/types/testdata/check/blank.src
similarity index 100%
rename from src/go/types/testdata/blank.src
rename to src/go/types/testdata/check/blank.src
diff --git a/src/go/types/testdata/check/builtins.go2 b/src/go/types/testdata/check/builtins.go2
new file mode 100644
index 0000000..3918d83
--- /dev/null
+++ b/src/go/types/testdata/check/builtins.go2
@@ -0,0 +1,53 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file tests built-in calls on generic types.
+
+package builtins
+
+type Bmc interface {
+	type map[rune]string, chan int
+}
+
+type Bms interface {
+	type map[string]int, []int
+}
+
+type Bcs interface {
+	type chan bool, []float64
+}
+
+type Bss interface {
+	type []int, []string
+}
+
+func _[T any] () {
+	_ = make(T /* ERROR invalid argument */ )
+	_ = make(T /* ERROR invalid argument */ , 10)
+	_ = make(T /* ERROR invalid argument */ , 10, 20)
+}
+
+func _[T Bmc] () {
+	_ = make(T)
+	_ = make(T, 10)
+	_ = make /* ERROR expects 1 or 2 arguments */ (T, 10, 20)
+}
+
+func _[T Bms] () {
+	_ = make /* ERROR expects 2 arguments */ (T)
+	_ = make(T, 10)
+	_ = make /* ERROR expects 2 arguments */ (T, 10, 20)
+}
+
+func _[T Bcs] () {
+	_ = make /* ERROR expects 2 arguments */ (T)
+	_ = make(T, 10)
+	_ = make /* ERROR expects 2 arguments */ (T, 10, 20)
+}
+
+func _[T Bss] () {
+	_ = make /* ERROR expects 2 or 3 arguments */ (T)
+	_ = make(T, 10)
+	_ = make(T, 10, 20)
+}
diff --git a/src/go/types/testdata/check/builtins.src b/src/go/types/testdata/check/builtins.src
new file mode 100644
index 0000000..3707528
--- /dev/null
+++ b/src/go/types/testdata/check/builtins.src
@@ -0,0 +1,902 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// builtin calls
+
+package builtins
+
+import "unsafe"
+
+func f0() {}
+
+func append1() {
+	var b byte
+	var x int
+	var s []byte
+	_ = append() // ERROR not enough arguments
+	_ = append("foo" /* ERROR not a slice */ )
+	_ = append(nil /* ERROR not a slice */ , s)
+	_ = append(x /* ERROR not a slice */ , s)
+	_ = append(s)
+	_ = append(s, nil...)
+	append /* ERROR not used */ (s)
+
+	_ = append(s, b)
+	_ = append(s, x /* ERROR cannot use x */ )
+	_ = append(s, s /* ERROR cannot use s */ )
+	_ = append(s...) /* ERROR not enough arguments */
+	_ = append(s, b, s /* ERROR too many arguments */ ...)
+	_ = append(s, 1, 2, 3)
+	_ = append(s, 1, 2, 3, x /* ERROR cannot use x */ , 5, 6, 6)
+	_ = append(s, 1, 2 /* ERROR too many arguments */, s...)
+	_ = append([]interface{}(nil), 1, 2, "foo", x, 3.1425, false)
+
+	type S []byte
+	type T string
+	var t T
+	_ = append(s, "foo" /* ERROR cannot use .* in argument to append */ )
+	_ = append(s, "foo"...)
+	_ = append(S(s), "foo" /* ERROR cannot use .* in argument to append */ )
+	_ = append(S(s), "foo"...)
+	_ = append(s, t /* ERROR cannot use t */ )
+	_ = append(s, t...)
+	_ = append(s, T("foo")...)
+	_ = append(S(s), t /* ERROR cannot use t */ )
+	_ = append(S(s), t...)
+	_ = append(S(s), T("foo")...)
+	_ = append([]string{}, t /* ERROR cannot use t */ , "foo")
+	_ = append([]T{}, t, "foo")
+}
+
+// from the spec
+func append2() {
+	s0 := []int{0, 0}
+	s1 := append(s0, 2)                // append a single element     s1 == []int{0, 0, 2}
+	s2 := append(s1, 3, 5, 7)          // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
+	s3 := append(s2, s0...)            // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
+	s4 := append(s3[3:6], s3[2:]...)   // append overlapping slice    s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
+
+	var t []interface{}
+	t = append(t, 42, 3.1415, "foo")   //                             t == []interface{}{42, 3.1415, "foo"}
+
+	var b []byte
+	b = append(b, "bar"...)            // append string contents      b == []byte{'b', 'a', 'r' }
+
+	_ = s4
+}
+
+func append3() {
+	f1 := func() (s []int) { return }
+	f2 := func() (s []int, x int) { return }
+	f3 := func() (s []int, x, y int) { return }
+	f5 := func() (s []interface{}, x int, y float32, z string, b bool) { return }
+	ff := func() (int, float32) { return 0, 0 }
+	_ = append(f0 /* ERROR used as value */ ())
+	_ = append(f1())
+	_ = append(f2())
+	_ = append(f3())
+	_ = append(f5())
+	_ = append(ff /* ERROR not a slice */ ()) // TODO(gri) better error message
+}
+
+func cap1() {
+	var a [10]bool
+	var p *[20]int
+	var c chan string
+	_ = cap() // ERROR not enough arguments
+	_ = cap(1, 2) // ERROR too many arguments
+	_ = cap(42 /* ERROR invalid */)
+	const _3 = cap(a)
+	assert(_3 == 10)
+	const _4 = cap(p)
+	assert(_4 == 20)
+	_ = cap(c)
+	cap /* ERROR not used */ (c)
+
+	// issue 4744
+	type T struct{ a [10]int }
+	const _ = cap(((*T)(nil)).a)
+
+	var s [][]byte
+	_ = cap(s)
+	_ = cap(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func cap2() {
+	f1a := func() (a [10]int) { return }
+	f1s := func() (s []int) { return }
+	f2 := func() (s []int, x int) { return }
+	_ = cap(f0 /* ERROR used as value */ ())
+	_ = cap(f1a())
+	_ = cap(f1s())
+	_ = cap(f2()) // ERROR too many arguments
+}
+
+// test cases for issue 7387
+func cap3() {
+	var f = func() int { return 0 }
+	var x = f()
+	const (
+		_ = cap([4]int{})
+		_ = cap([4]int{x})
+		_ = cap /* ERROR not constant */ ([4]int{f()})
+		_ = cap /* ERROR not constant */ ([4]int{cap([]int{})})
+		_ = cap([4]int{cap([4]int{})})
+	)
+	var y float64
+	var z complex128
+	const (
+		_ = cap([4]float64{})
+		_ = cap([4]float64{y})
+		_ = cap([4]float64{real(2i)})
+		_ = cap /* ERROR not constant */ ([4]float64{real(z)})
+	)
+	var ch chan [10]int
+	const (
+		_ = cap /* ERROR not constant */ (<-ch)
+		_ = cap /* ERROR not constant */ ([4]int{(<-ch)[0]})
+	)
+}
+
+func close1() {
+	var c chan int
+	var r <-chan int
+	close() // ERROR not enough arguments
+	close(1, 2) // ERROR too many arguments
+	close(42 /* ERROR not a channel */)
+	close(r /* ERROR receive-only channel */)
+	close(c)
+	_ = close /* ERROR used as value */ (c)
+
+	var s []chan int
+	close(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func close2() {
+	f1 := func() (ch chan int) { return }
+	f2 := func() (ch chan int, x int) { return }
+	close(f0 /* ERROR used as value */ ())
+	close(f1())
+	close(f2()) // ERROR too many arguments
+}
+
+func complex1() {
+	var i32 int32
+	var f32 float32
+	var f64 float64
+	var c64 complex64
+	var c128 complex128
+	_ = complex() // ERROR not enough arguments
+	_ = complex(1) // ERROR not enough arguments
+	_ = complex(true /* ERROR mismatched types */ , 0)
+	_ = complex(i32 /* ERROR expected floating-point */ , 0)
+	_ = complex("foo" /* ERROR mismatched types */ , 0)
+	_ = complex(c64 /* ERROR expected floating-point */ , 0)
+	_ = complex(0 /* ERROR mismatched types */ , true)
+	_ = complex(0 /* ERROR expected floating-point */ , i32)
+	_ = complex(0 /* ERROR mismatched types */ , "foo")
+	_ = complex(0 /* ERROR expected floating-point */ , c64)
+	_ = complex(f32, f32)
+	_ = complex(f32, 1)
+	_ = complex(f32, 1.0)
+	_ = complex(f32, 'a')
+	_ = complex(f64, f64)
+	_ = complex(f64, 1)
+	_ = complex(f64, 1.0)
+	_ = complex(f64, 'a')
+	_ = complex(f32 /* ERROR mismatched types */ , f64)
+	_ = complex(f64 /* ERROR mismatched types */ , f32)
+	_ = complex(1, 1)
+	_ = complex(1, 1.1)
+	_ = complex(1, 'a')
+	complex /* ERROR not used */ (1, 2)
+
+	var _ complex64 = complex(f32, f32)
+	var _ complex64 = complex /* ERROR cannot use .* in variable declaration */ (f64, f64)
+
+	var _ complex128 = complex /* ERROR cannot use .* in variable declaration */ (f32, f32)
+	var _ complex128 = complex(f64, f64)
+
+	// untyped constants
+	const _ int = complex(1, 0)
+	const _ float32 = complex(1, 0)
+	const _ complex64 = complex(1, 0)
+	const _ complex128 = complex(1, 0)
+	const _ = complex(0i, 0i)
+	const _ = complex(0i, 0)
+	const _ int = 1.0 + complex(1, 0i)
+
+	const _ int = complex /* ERROR int */ (1.1, 0)
+	const _ float32 = complex /* ERROR float32 */ (1, 2)
+
+	// untyped values
+	var s uint
+	_ = complex(1 /* ERROR integer */ <<s, 0)
+	const _ = complex /* ERROR not constant */ (1 /* ERROR integer */ <<s, 0)
+	var _ int = complex /* ERROR cannot use .* in variable declaration */ (1 /* ERROR integer */ <<s, 0)
+
+	// floating-point argument types must be identical
+	type F32 float32
+	type F64 float64
+	var x32 F32
+	var x64 F64
+	c64 = complex(x32, x32)
+	_ = complex(x32 /* ERROR mismatched types */ , f32)
+	_ = complex(f32 /* ERROR mismatched types */ , x32)
+	c128 = complex(x64, x64)
+	_ = c128
+	_ = complex(x64 /* ERROR mismatched types */ , f64)
+	_ = complex(f64 /* ERROR mismatched types */ , x64)
+
+	var t []float32
+	_ = complex(t... /* ERROR invalid use of \.\.\. */ )
+}
+
+func complex2() {
+	f1 := func() (x float32) { return }
+	f2 := func() (x, y float32) { return }
+	f3 := func() (x, y, z float32) { return }
+	_ = complex(f0 /* ERROR used as value */ ())
+	_ = complex(f1()) // ERROR not enough arguments
+	_ = complex(f2())
+	_ = complex(f3()) // ERROR too many arguments
+}
+
+func copy1() {
+	copy() // ERROR not enough arguments
+	copy("foo") // ERROR not enough arguments
+	copy([ /* ERROR copy expects slice arguments */ ...]int{}, []int{})
+	copy([ /* ERROR copy expects slice arguments */ ]int{}, [...]int{})
+	copy([ /* ERROR different element types */ ]int8{}, "foo")
+
+	// spec examples
+	var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
+	var s = make([]int, 6)
+	var b = make([]byte, 5)
+	n1 := copy(s, a[0:])            // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
+	n2 := copy(s, s[2:])            // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
+	n3 := copy(b, "Hello, World!")  // n3 == 5, b == []byte("Hello")
+	_, _, _ = n1, n2, n3
+
+	var t [][]int
+	copy(t, t)
+	copy(t /* ERROR copy expects slice arguments */ , nil)
+	copy(nil /* ERROR copy expects slice arguments */ , t)
+	copy(nil /* ERROR copy expects slice arguments */ , nil)
+	copy(t... /* ERROR invalid use of \.\.\. */ )
+}
+
+func copy2() {
+	f1 := func() (a []int) { return }
+	f2 := func() (a, b []int) { return }
+	f3 := func() (a, b, c []int) { return }
+	copy(f0 /* ERROR used as value */ ())
+	copy(f1()) // ERROR not enough arguments
+	copy(f2())
+	copy(f3()) // ERROR too many arguments
+}
+
+func delete1() {
+	var m map[string]int
+	var s string
+	delete() // ERROR not enough arguments
+	delete(1) // ERROR not enough arguments
+	delete(1, 2, 3) // ERROR too many arguments
+	delete(m, 0 /* ERROR cannot use */)
+	delete(m, s)
+	_ = delete /* ERROR used as value */ (m, s)
+
+	var t []map[string]string
+	delete(t... /* ERROR invalid use of \.\.\. */ )
+}
+
+func delete2() {
+	f1 := func() (m map[string]int) { return }
+	f2 := func() (m map[string]int, k string) { return }
+	f3 := func() (m map[string]int, k string, x float32) { return }
+	delete(f0 /* ERROR used as value */ ())
+	delete(f1()) // ERROR not enough arguments
+	delete(f2())
+	delete(f3()) // ERROR too many arguments
+}
+
+func imag1() {
+	var f32 float32
+	var f64 float64
+	var c64 complex64
+	var c128 complex128
+	_ = imag() // ERROR not enough arguments
+	_ = imag(1, 2) // ERROR too many arguments
+	_ = imag(10)
+	_ = imag(2.7182818)
+	_ = imag("foo" /* ERROR expected complex */)
+	_ = imag('a')
+	const _5 = imag(1 + 2i)
+	assert(_5 == 2)
+	f32 = _5
+	f64 = _5
+	const _6 = imag(0i)
+	assert(_6 == 0)
+	f32 = imag(c64)
+	f64 = imag(c128)
+	f32 = imag /* ERROR cannot use .* in assignment */ (c128)
+	f64 = imag /* ERROR cannot use .* in assignment */ (c64)
+	imag /* ERROR not used */ (c64)
+	_, _ = f32, f64
+
+	// complex type may not be predeclared
+	type C64 complex64
+	type C128 complex128
+	var x64 C64
+	var x128 C128
+	f32 = imag(x64)
+	f64 = imag(x128)
+
+	var a []complex64
+	_ = imag(a... /* ERROR invalid use of \.\.\. */ )
+
+	// if argument is untyped, result is untyped
+	const _ byte = imag(1.2 + 3i)
+	const _ complex128 = imag(1.2 + 3i)
+
+	// lhs constant shift operands are typed as complex128
+	var s uint
+	_ = imag(1 /* ERROR must be integer */ << s)
+}
+
+func imag2() {
+	f1 := func() (x complex128) { return }
+	f2 := func() (x, y complex128) { return }
+	_ = imag(f0 /* ERROR used as value */ ())
+	_ = imag(f1())
+	_ = imag(f2()) // ERROR too many arguments
+}
+
+func len1() {
+	const c = "foobar"
+	var a [10]bool
+	var p *[20]int
+	var m map[string]complex128
+	_ = len() // ERROR not enough arguments
+	_ = len(1, 2) // ERROR too many arguments
+	_ = len(42 /* ERROR invalid */)
+	const _3 = len(c)
+	assert(_3 == 6)
+	const _4 = len(a)
+	assert(_4 == 10)
+	const _5 = len(p)
+	assert(_5 == 20)
+	_ = len(m)
+	len /* ERROR not used */ (c)
+
+	// esoteric case
+	var t string
+	var hash map[interface{}][]*[10]int
+	const n = len /* ERROR not constant */ (hash[recover()][len(t)])
+	assert(n == 10) // ok because n has unknown value and no error is reported
+	var ch <-chan int
+	const nn = len /* ERROR not constant */ (hash[<-ch][len(t)])
+
+	// issue 4744
+	type T struct{ a [10]int }
+	const _ = len(((*T)(nil)).a)
+
+	var s [][]byte
+	_ = len(s)
+	_ = len(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func len2() {
+	f1 := func() (x []int) { return }
+	f2 := func() (x, y []int) { return }
+	_ = len(f0 /* ERROR used as value */ ())
+	_ = len(f1())
+	_ = len(f2()) // ERROR too many arguments
+}
+
+// test cases for issue 7387
+func len3() {
+	var f = func() int { return 0 }
+	var x = f()
+	const (
+		_ = len([4]int{})
+		_ = len([4]int{x})
+		_ = len /* ERROR not constant */ ([4]int{f()})
+		_ = len /* ERROR not constant */ ([4]int{len([]int{})})
+		_ = len([4]int{len([4]int{})})
+	)
+	var y float64
+	var z complex128
+	const (
+		_ = len([4]float64{})
+		_ = len([4]float64{y})
+		_ = len([4]float64{real(2i)})
+		_ = len /* ERROR not constant */ ([4]float64{real(z)})
+	)
+	var ch chan [10]int
+	const (
+		_ = len /* ERROR not constant */ (<-ch)
+		_ = len /* ERROR not constant */ ([4]int{(<-ch)[0]})
+	)
+}
+
+func make1() {
+	var n int
+	var m float32
+	var s uint
+
+	_ = make() // ERROR not enough arguments
+	_ = make(1 /* ERROR not a type */)
+	_ = make(int /* ERROR cannot make */)
+
+	// slices
+	_ = make/* ERROR arguments */ ([]int)
+	_ = make/* ERROR arguments */ ([]int, 2, 3, 4)
+	_ = make([]int, int /* ERROR not an expression */)
+	_ = make([]int, 10, float32 /* ERROR not an expression */)
+	_ = make([]int, "foo" /* ERROR cannot convert */)
+	_ = make([]int, 10, 2.3 /* ERROR truncated */)
+	_ = make([]int, 5, 10.0)
+	_ = make([]int, 0i)
+	_ = make([]int, 1.0)
+	_ = make([]int, 1.0<<s)
+	_ = make([]int, 1.1 /* ERROR int */ <<s)
+	_ = make([]int, - /* ERROR must not be negative */ 1, 10)
+	_ = make([]int, 0, - /* ERROR must not be negative */ 1)
+	_ = make([]int, - /* ERROR must not be negative */ 1, - /* ERROR must not be negative */ 1)
+	_ = make([]int, 1 /* ERROR overflows */ <<100, 1 /* ERROR overflows */ <<100)
+	_ = make([]int, 10 /* ERROR length and capacity swapped */ , 9)
+	_ = make([]int, 1 /* ERROR overflows */ <<100, 12345)
+	_ = make([]int, m /* ERROR must be integer */ )
+        _ = &make /* ERROR cannot take address */ ([]int, 0)
+
+	// maps
+	_ = make /* ERROR arguments */ (map[int]string, 10, 20)
+	_ = make(map[int]float32, int /* ERROR not an expression */)
+	_ = make(map[int]float32, "foo" /* ERROR cannot convert */)
+	_ = make(map[int]float32, 10)
+	_ = make(map[int]float32, n)
+	_ = make(map[int]float32, int64(n))
+	_ = make(map[string]bool, 10.0)
+	_ = make(map[string]bool, 10.0<<s)
+        _ = &make /* ERROR cannot take address */ (map[string]bool)
+
+	// channels
+	_ = make /* ERROR arguments */ (chan int, 10, 20)
+	_ = make(chan int, int /* ERROR not an expression */)
+	_ = make(chan<- int, "foo" /* ERROR cannot convert */)
+	_ = make(chan int, - /* ERROR must not be negative */ 10)
+	_ = make(<-chan float64, 10)
+	_ = make(chan chan int, n)
+	_ = make(chan string, int64(n))
+	_ = make(chan bool, 10.0)
+	_ = make(chan bool, 10.0<<s)
+        _ = &make /* ERROR cannot take address */ (chan bool)
+
+	make /* ERROR not used */ ([]int, 10)
+
+	var t []int
+	_ = make([]int, t[0], t[1])
+	_ = make([]int, t... /* ERROR invalid use of \.\.\. */ )
+}
+
+func make2() {
+	f1 /* ERROR not used */ := func() (x []int) { return }
+	_ = make(f0 /* ERROR not a type */ ())
+	_ = make(f1 /* ERROR not a type */ ())
+}
+
+func new1() {
+	_ = new() // ERROR not enough arguments
+	_ = new(1, 2) // ERROR too many arguments
+	_ = new("foo" /* ERROR not a type */)
+	p := new(float64)
+	_ = new(struct{ x, y int })
+	q := new(*float64)
+	_ = *p == **q
+	new /* ERROR not used */ (int)
+        _ = &new /* ERROR cannot take address */ (int)
+
+	_ = new(int... /* ERROR invalid use of \.\.\. */ )
+}
+
+func new2() {
+	f1 /* ERROR not used */ := func() (x []int) { return }
+	_ = new(f0 /* ERROR not a type */ ())
+	_ = new(f1 /* ERROR not a type */ ())
+}
+
+func panic1() {
+	panic() // ERROR not enough arguments
+	panic(1, 2) // ERROR too many arguments
+	panic(0)
+	panic("foo")
+	panic(false)
+	panic(1<<10)
+	panic(1 << /* ERROR constant shift overflow */ 1000)
+	_ = panic /* ERROR used as value */ (0)
+
+	var s []byte
+	panic(s)
+	panic(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func panic2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x, y int) { return }
+	panic(f0 /* ERROR used as value */ ())
+	panic(f1())
+	panic(f2()) // ERROR too many arguments
+}
+
+func print1() {
+	print()
+	print(1)
+	print(1, 2)
+	print("foo")
+	print(2.718281828)
+	print(false)
+	print(1<<10)
+	print(1 << /* ERROR constant shift overflow */ 1000)
+	println(nil /* ERROR untyped nil */ )
+
+	var s []int
+	print(s... /* ERROR invalid use of \.\.\. */ )
+	_ = print /* ERROR used as value */ ()
+}
+
+func print2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x, y int) { return }
+	f3 := func() (x int, y float32, z string) { return }
+	print(f0 /* ERROR used as value */ ())
+	print(f1())
+	print(f2())
+	print(f3())
+}
+
+func println1() {
+	println()
+	println(1)
+	println(1, 2)
+	println("foo")
+	println(2.718281828)
+	println(false)
+	println(1<<10)
+	println(1 << /* ERROR constant shift overflow */ 1000)
+	println(nil /* ERROR untyped nil */ )
+
+	var s []int
+	println(s... /* ERROR invalid use of \.\.\. */ )
+	_ = println /* ERROR used as value */ ()
+}
+
+func println2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x, y int) { return }
+	f3 := func() (x int, y float32, z string) { return }
+	println(f0 /* ERROR used as value */ ())
+	println(f1())
+	println(f2())
+	println(f3())
+}
+
+func real1() {
+	var f32 float32
+	var f64 float64
+	var c64 complex64
+	var c128 complex128
+	_ = real() // ERROR not enough arguments
+	_ = real(1, 2) // ERROR too many arguments
+	_ = real(10)
+	_ = real(2.7182818)
+	_ = real("foo" /* ERROR expected complex */)
+	const _5 = real(1 + 2i)
+	assert(_5 == 1)
+	f32 = _5
+	f64 = _5
+	const _6 = real(0i)
+	assert(_6 == 0)
+	f32 = real(c64)
+	f64 = real(c128)
+	f32 = real /* ERROR cannot use .* in assignment */ (c128)
+	f64 = real /* ERROR cannot use .* in assignment */ (c64)
+	real /* ERROR not used */ (c64)
+
+	// complex type may not be predeclared
+	type C64 complex64
+	type C128 complex128
+	var x64 C64
+	var x128 C128
+	f32 = imag(x64)
+	f64 = imag(x128)
+	_, _ = f32, f64
+
+	var a []complex64
+	_ = real(a... /* ERROR invalid use of \.\.\. */ )
+
+	// if argument is untyped, result is untyped
+	const _ byte = real(1 + 2.3i)
+	const _ complex128 = real(1 + 2.3i)
+
+	// lhs constant shift operands are typed as complex128
+	var s uint
+	_ = real(1 /* ERROR must be integer */ << s)
+}
+
+func real2() {
+	f1 := func() (x complex128) { return }
+	f2 := func() (x, y complex128) { return }
+	_ = real(f0 /* ERROR used as value */ ())
+	_ = real(f1())
+	_ = real(f2()) // ERROR too many arguments
+}
+
+func recover1() {
+	_ = recover()
+	_ = recover(10) // ERROR too many arguments
+	recover()
+
+	var s []int
+	recover(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func recover2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x, y int) { return }
+	_ = recover(f0 /* ERROR used as value */ ())
+	_ = recover(f1()) // ERROR too many arguments
+	_ = recover(f2()) // ERROR too many arguments
+}
+
+// assuming types.DefaultPtrSize == 8
+type S0 struct{      // offset
+	a bool       //  0
+	b rune       //  4
+	c *int       //  8
+	d bool       // 16
+	e complex128 // 24
+}                    // 40
+
+type S1 struct{   // offset
+	x float32 //  0
+	y string  //  8
+	z *S1     // 24
+	S0        // 32
+}                 // 72
+
+type S2 struct{ // offset
+	*S1     //  0
+}               //  8
+
+type S3 struct { // offset
+	a int64  //  0
+	b int32  //  8
+}                // 12
+
+type S4 struct { // offset
+	S3       //  0
+	int32    // 12
+}                // 16
+
+type S5 struct {   // offset
+	a [3]int32 //  0
+	b int32    // 12
+}                  // 16
+
+func (S2) m() {}
+
+func Alignof1() {
+	var x int
+	_ = unsafe.Alignof() // ERROR not enough arguments
+	_ = unsafe.Alignof(1, 2) // ERROR too many arguments
+	_ = unsafe.Alignof(int /* ERROR not an expression */)
+	_ = unsafe.Alignof(42)
+	_ = unsafe.Alignof(new(struct{}))
+	_ = unsafe.Alignof(1<<10)
+	_ = unsafe.Alignof(1 << /* ERROR constant shift overflow */ 1000)
+	_ = unsafe.Alignof(nil /* ERROR "untyped nil */ )
+	unsafe /* ERROR not used */ .Alignof(x)
+
+	var y S0
+	assert(unsafe.Alignof(y.a) == 1)
+	assert(unsafe.Alignof(y.b) == 4)
+	assert(unsafe.Alignof(y.c) == 8)
+	assert(unsafe.Alignof(y.d) == 1)
+	assert(unsafe.Alignof(y.e) == 8)
+
+	var s []byte
+	_ = unsafe.Alignof(s)
+	_ = unsafe.Alignof(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func Alignof2() {
+	f1 := func() (x int32) { return }
+	f2 := func() (x, y int32) { return }
+	_ = unsafe.Alignof(f0 /* ERROR used as value */ ())
+	assert(unsafe.Alignof(f1()) == 4)
+	_ = unsafe.Alignof(f2()) // ERROR too many arguments
+}
+
+func Offsetof1() {
+	var x struct{ f int }
+	_ = unsafe.Offsetof() // ERROR not enough arguments
+	_ = unsafe.Offsetof(1, 2) // ERROR too many arguments
+	_ = unsafe.Offsetof(int /* ERROR not a selector expression */ )
+	_ = unsafe.Offsetof(x /* ERROR not a selector expression */ )
+	_ = unsafe.Offsetof(nil /* ERROR not a selector expression */ )
+	_ = unsafe.Offsetof(x.f)
+	_ = unsafe.Offsetof((x.f))
+	_ = unsafe.Offsetof((((((((x))).f)))))
+	unsafe /* ERROR not used */ .Offsetof(x.f)
+
+	var y0 S0
+	assert(unsafe.Offsetof(y0.a) == 0)
+	assert(unsafe.Offsetof(y0.b) == 4)
+	assert(unsafe.Offsetof(y0.c) == 8)
+	assert(unsafe.Offsetof(y0.d) == 16)
+	assert(unsafe.Offsetof(y0.e) == 24)
+
+	var y1 S1
+	assert(unsafe.Offsetof(y1.x) == 0)
+	assert(unsafe.Offsetof(y1.y) == 8)
+	assert(unsafe.Offsetof(y1.z) == 24)
+	assert(unsafe.Offsetof(y1.S0) == 32)
+
+	assert(unsafe.Offsetof(y1.S0.a) == 0) // relative to S0
+	assert(unsafe.Offsetof(y1.a) == 32)   // relative to S1
+	assert(unsafe.Offsetof(y1.b) == 36)   // relative to S1
+	assert(unsafe.Offsetof(y1.c) == 40)   // relative to S1
+	assert(unsafe.Offsetof(y1.d) == 48)   // relative to S1
+	assert(unsafe.Offsetof(y1.e) == 56)   // relative to S1
+
+	var y1p *S1
+	assert(unsafe.Offsetof(y1p.S0) == 32)
+
+	type P *S1
+	var p P = y1p
+	assert(unsafe.Offsetof(p.S0) == 32)
+
+	var y2 S2
+	assert(unsafe.Offsetof(y2.S1) == 0)
+	_ = unsafe.Offsetof(y2 /* ERROR embedded via a pointer */ .x)
+	_ = unsafe.Offsetof(y2 /* ERROR method value */ .m)
+
+	var s []byte
+	_ = unsafe.Offsetof(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func Offsetof2() {
+	f1 := func() (x int32) { return }
+	f2 := func() (x, y int32) { return }
+	_ = unsafe.Offsetof(f0 /* ERROR not a selector expression */ ())
+	_ = unsafe.Offsetof(f1 /* ERROR not a selector expression */ ())
+	_ = unsafe.Offsetof(f2 /* ERROR not a selector expression */ ())
+}
+
+func Sizeof1() {
+	var x int
+	_ = unsafe.Sizeof() // ERROR not enough arguments
+	_ = unsafe.Sizeof(1, 2) // ERROR too many arguments
+	_ = unsafe.Sizeof(int /* ERROR not an expression */)
+	_ = unsafe.Sizeof(42)
+	_ = unsafe.Sizeof(new(complex128))
+	_ = unsafe.Sizeof(1<<10)
+	_ = unsafe.Sizeof(1 << /* ERROR constant shift overflow */ 1000)
+	_ = unsafe.Sizeof(nil /* ERROR untyped nil */ )
+	unsafe /* ERROR not used */ .Sizeof(x)
+
+	// basic types have size guarantees
+	assert(unsafe.Sizeof(byte(0)) == 1)
+	assert(unsafe.Sizeof(uint8(0)) == 1)
+	assert(unsafe.Sizeof(int8(0)) == 1)
+	assert(unsafe.Sizeof(uint16(0)) == 2)
+	assert(unsafe.Sizeof(int16(0)) == 2)
+	assert(unsafe.Sizeof(uint32(0)) == 4)
+	assert(unsafe.Sizeof(int32(0)) == 4)
+	assert(unsafe.Sizeof(float32(0)) == 4)
+	assert(unsafe.Sizeof(uint64(0)) == 8)
+	assert(unsafe.Sizeof(int64(0)) == 8)
+	assert(unsafe.Sizeof(float64(0)) == 8)
+	assert(unsafe.Sizeof(complex64(0)) == 8)
+	assert(unsafe.Sizeof(complex128(0)) == 16)
+
+	var y0 S0
+	assert(unsafe.Sizeof(y0.a) == 1)
+	assert(unsafe.Sizeof(y0.b) == 4)
+	assert(unsafe.Sizeof(y0.c) == 8)
+	assert(unsafe.Sizeof(y0.d) == 1)
+	assert(unsafe.Sizeof(y0.e) == 16)
+	assert(unsafe.Sizeof(y0) == 40)
+
+	var y1 S1
+	assert(unsafe.Sizeof(y1) == 72)
+
+	var y2 S2
+	assert(unsafe.Sizeof(y2) == 8)
+
+	var y3 S3
+	assert(unsafe.Sizeof(y3) == 12)
+
+	var y4 S4
+	assert(unsafe.Sizeof(y4) == 16)
+
+	var y5 S5
+	assert(unsafe.Sizeof(y5) == 16)
+
+	var a3 [10]S3
+	assert(unsafe.Sizeof(a3) == 156)
+
+	// test case for issue 5670
+	type T struct {
+		a int32
+		_ int32
+		c int32
+	}
+	assert(unsafe.Sizeof(T{}) == 12)
+
+	var s []byte
+	_ = unsafe.Sizeof(s)
+	_ = unsafe.Sizeof(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func Sizeof2() {
+	f1 := func() (x int64) { return }
+	f2 := func() (x, y int64) { return }
+	_ = unsafe.Sizeof(f0 /* ERROR used as value */ ())
+	assert(unsafe.Sizeof(f1()) == 8)
+	_ = unsafe.Sizeof(f2()) // ERROR too many arguments
+}
+
+// self-testing only
+func assert1() {
+	var x int
+	assert() /* ERROR not enough arguments */
+	assert(1, 2) /* ERROR too many arguments */
+	assert("foo" /* ERROR boolean constant */ )
+	assert(x /* ERROR boolean constant */)
+	assert(true)
+	assert /* ERROR failed */ (false)
+	_ = assert(true)
+
+	var s []byte
+	assert(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func assert2() {
+	f1 := func() (x bool) { return }
+	f2 := func() (x bool) { return }
+	assert(f0 /* ERROR used as value */ ())
+	assert(f1 /* ERROR boolean constant */ ())
+	assert(f2 /* ERROR boolean constant */ ())
+}
+
+// self-testing only
+func trace1() {
+	// Uncomment the code below to test trace - will produce console output
+	// _ = trace /* ERROR no value */ ()
+	// _ = trace(1)
+	// _ = trace(true, 1.2, '\'', "foo", 42i, "foo" <= "bar")
+
+	var s []byte
+	trace(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func trace2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x int, y string) { return }
+	f3 := func() (x int, y string, z []int) { return }
+	_ = f1
+	_ = f2
+	_ = f3
+	// Uncomment the code below to test trace - will produce console output
+	// trace(f0())
+	// trace(f1())
+	// trace(f2())
+	// trace(f3())
+	// trace(f0(), 1)
+	// trace(f1(), 1, 2)
+	// trace(f2(), 1, 2, 3)
+	// trace(f3(), 1, 2, 3, 4)
+}
diff --git a/src/go/types/testdata/check/chans.go2 b/src/go/types/testdata/check/chans.go2
new file mode 100644
index 0000000..fad2bce
--- /dev/null
+++ b/src/go/types/testdata/check/chans.go2
@@ -0,0 +1,62 @@
+package chans
+
+import "runtime"
+
+// Ranger returns a Sender and a Receiver. The Receiver provides a
+// Next method to retrieve values. The Sender provides a Send method
+// to send values and a Close method to stop sending values. The Next
+// method indicates when the Sender has been closed, and the Send
+// method indicates when the Receiver has been freed.
+//
+// This is a convenient way to exit a goroutine sending values when
+// the receiver stops reading them.
+func Ranger[T any]() (*Sender[T], *Receiver[T]) {
+	c := make(chan T)
+	d := make(chan bool)
+	s := &Sender[T]{values: c, done: d}
+	r := &Receiver[T]{values: c, done: d}
+	runtime.SetFinalizer(r, r.finalize)
+	return s, r
+}
+
+// A sender is used to send values to a Receiver.
+type Sender[T any] struct {
+	values chan<- T
+	done <-chan bool
+}
+
+// Send sends a value to the receiver. It returns whether any more
+// values may be sent; if it returns false the value was not sent.
+func (s *Sender[T]) Send(v T) bool {
+	select {
+	case s.values <- v:
+		return true
+	case <-s.done:
+		return false
+	}
+}
+
+// Close tells the receiver that no more values will arrive.
+// After Close is called, the Sender may no longer be used.
+func (s *Sender[T]) Close() {
+	close(s.values)
+}
+
+// A Receiver receives values from a Sender.
+type Receiver[T any] struct {
+	values <-chan T
+	done chan<- bool
+}
+
+// Next returns the next value from the channel. The bool result
+// indicates whether the value is valid, or whether the Sender has
+// been closed and no more values will be received.
+func (r *Receiver[T]) Next() (T, bool) {
+	v, ok := <-r.values
+	return v, ok
+}
+
+// finalize is a finalizer for the receiver.
+func (r *Receiver[T]) finalize() {
+	close(r.done)
+}
diff --git a/src/go/types/testdata/check/const0.src b/src/go/types/testdata/check/const0.src
new file mode 100644
index 0000000..5608b15
--- /dev/null
+++ b/src/go/types/testdata/check/const0.src
@@ -0,0 +1,363 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// constant declarations
+
+package const0
+
+import "unsafe"
+
+// constants declarations must be initialized by constants
+var x = 0
+const c0 = x /* ERROR "not constant" */
+
+// typed constants must have constant types
+const _ interface /* ERROR invalid constant type */ {} = 0
+
+func _ () {
+	const _ interface /* ERROR invalid constant type */ {} = 0
+	for i := 0; i < 10; i++ {} // don't crash with non-nil iota here
+}
+
+// untyped constants
+const (
+	// boolean values
+	ub0 = false
+	ub1 = true
+	ub2 = 2 < 1
+	ub3 = ui1 == uf1
+	ub4 = true /* ERROR "cannot convert" */ == 0
+
+	// integer values
+	ui0 = 0
+	ui1 = 1
+	ui2 = 42
+	ui3 = 3141592653589793238462643383279502884197169399375105820974944592307816406286
+	ui4 = -10
+
+	ui5 = ui0 + ui1
+	ui6 = ui1 - ui1
+	ui7 = ui2 * ui1
+	ui8 = ui3 / ui3
+	ui9 = ui3 % ui3
+
+	ui10 = 1 / 0 /* ERROR "division by zero" */
+	ui11 = ui1 / 0 /* ERROR "division by zero" */
+	ui12 = ui3 / ui0 /* ERROR "division by zero" */
+	ui13 = 1 % 0 /* ERROR "division by zero" */
+	ui14 = ui1 % 0 /* ERROR "division by zero" */
+	ui15 = ui3 % ui0 /* ERROR "division by zero" */
+
+	ui16 = ui2 & ui3
+	ui17 = ui2 | ui3
+	ui18 = ui2 ^ ui3
+	ui19 = 1 /* ERROR "invalid operation" */ % 1.0
+
+	// floating point values
+	uf0 = 0.
+	uf1 = 1.
+	uf2 = 4.2e1
+	uf3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286
+	uf4 = 1e-1
+
+	uf5 = uf0 + uf1
+	uf6 = uf1 - uf1
+	uf7 = uf2 * uf1
+	uf8 = uf3 / uf3
+	uf9 = uf3 /* ERROR "not defined" */ % uf3
+
+	uf10 = 1 / 0 /* ERROR "division by zero" */
+	uf11 = uf1 / 0 /* ERROR "division by zero" */
+	uf12 = uf3 / uf0 /* ERROR "division by zero" */
+
+	uf16 = uf2 /* ERROR "not defined" */ & uf3
+	uf17 = uf2 /* ERROR "not defined" */ | uf3
+	uf18 = uf2 /* ERROR "not defined" */ ^ uf3
+
+	// complex values
+	uc0 = 0.i
+	uc1 = 1.i
+	uc2 = 4.2e1i
+	uc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i
+	uc4 = 1e-1i
+
+	uc5 = uc0 + uc1
+	uc6 = uc1 - uc1
+	uc7 = uc2 * uc1
+	uc8 = uc3 / uc3
+	uc9 = uc3 /* ERROR "not defined" */ % uc3
+
+	uc10 = 1 / 0 /* ERROR "division by zero" */
+	uc11 = uc1 / 0 /* ERROR "division by zero" */
+	uc12 = uc3 / uc0 /* ERROR "division by zero" */
+
+	uc16 = uc2 /* ERROR "not defined" */ & uc3
+	uc17 = uc2 /* ERROR "not defined" */ | uc3
+	uc18 = uc2 /* ERROR "not defined" */ ^ uc3
+)
+
+type (
+	mybool bool
+	myint int
+	myfloat float64
+	mycomplex complex128
+)
+
+// typed constants
+const (
+	// boolean values
+	tb0 bool = false
+	tb1 bool = true
+	tb2 mybool = 2 < 1
+	tb3 mybool = ti1 /* ERROR "mismatched types" */ == tf1
+
+	// integer values
+	ti0 int8 = ui0
+	ti1 int32 = ui1
+	ti2 int64 = ui2
+	ti3 myint = ui3 /* ERROR "overflows" */
+	ti4 myint = ui4
+
+	ti5 = ti0 /* ERROR "mismatched types" */ + ti1
+	ti6 = ti1 - ti1
+	ti7 = ti2 /* ERROR "mismatched types" */ * ti1
+	ti8 = ti3 / ti3
+	ti9 = ti3 % ti3
+
+	ti10 = 1 / 0 /* ERROR "division by zero" */
+	ti11 = ti1 / 0 /* ERROR "division by zero" */
+	ti12 = ti3 /* ERROR "mismatched types" */ / ti0
+	ti13 = 1 % 0 /* ERROR "division by zero" */
+	ti14 = ti1 % 0 /* ERROR "division by zero" */
+	ti15 = ti3 /* ERROR "mismatched types" */ % ti0
+
+	ti16 = ti2 /* ERROR "mismatched types" */ & ti3
+	ti17 = ti2 /* ERROR "mismatched types" */ | ti4
+	ti18 = ti2 ^ ti5 // no mismatched types error because the type of ti5 is unknown
+
+	// floating point values
+	tf0 float32 = 0.
+	tf1 float32 = 1.
+	tf2 float64 = 4.2e1
+	tf3 myfloat = 3.141592653589793238462643383279502884197169399375105820974944592307816406286
+	tf4 myfloat = 1e-1
+
+	tf5 = tf0 + tf1
+	tf6 = tf1 - tf1
+	tf7 = tf2 /* ERROR "mismatched types" */ * tf1
+	tf8 = tf3 / tf3
+	tf9 = tf3 /* ERROR "not defined" */ % tf3
+
+	tf10 = 1 / 0 /* ERROR "division by zero" */
+	tf11 = tf1 / 0 /* ERROR "division by zero" */
+	tf12 = tf3 /* ERROR "mismatched types" */ / tf0
+
+	tf16 = tf2 /* ERROR "mismatched types" */ & tf3
+	tf17 = tf2 /* ERROR "mismatched types" */ | tf3
+	tf18 = tf2 /* ERROR "mismatched types" */ ^ tf3
+
+	// complex values
+	tc0 = 0.i
+	tc1 = 1.i
+	tc2 = 4.2e1i
+	tc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i
+	tc4 = 1e-1i
+
+	tc5 = tc0 + tc1
+	tc6 = tc1 - tc1
+	tc7 = tc2 * tc1
+	tc8 = tc3 / tc3
+	tc9 = tc3 /* ERROR "not defined" */ % tc3
+
+	tc10 = 1 / 0 /* ERROR "division by zero" */
+	tc11 = tc1 / 0 /* ERROR "division by zero" */
+	tc12 = tc3 / tc0 /* ERROR "division by zero" */
+
+	tc16 = tc2 /* ERROR "not defined" */ & tc3
+	tc17 = tc2 /* ERROR "not defined" */ | tc3
+	tc18 = tc2 /* ERROR "not defined" */ ^ tc3
+)
+
+// initialization cycles
+const (
+	a /* ERROR "initialization cycle" */ = a
+	b /* ERROR "initialization cycle" */ , c /* ERROR "initialization cycle" */, d, e = e, d, c, b // TODO(gri) should only have one cycle error
+	f float64 = d
+)
+
+// multiple initialization
+const (
+	a1, a2, a3 = 7, 3.1415926, "foo"
+	b1, b2, b3 = b3, b1, 42
+	c1, c2, c3  /* ERROR "missing init expr for c3" */ = 1, 2
+	d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */
+	_p0 = assert(a1 == 7)
+	_p1 = assert(a2 == 3.1415926)
+	_p2 = assert(a3 == "foo")
+	_p3 = assert(b1 == 42)
+	_p4 = assert(b2 == 42)
+	_p5 = assert(b3 == 42)
+)
+
+func _() {
+	const (
+		a1, a2, a3 = 7, 3.1415926, "foo"
+		b1, b2, b3 = b3, b1, 42
+		c1, c2, c3  /* ERROR "missing init expr for c3" */ = 1, 2
+		d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */
+		_p0 = assert(a1 == 7)
+		_p1 = assert(a2 == 3.1415926)
+		_p2 = assert(a3 == "foo")
+		_p3 = assert(b1 == 42)
+		_p4 = assert(b2 == 42)
+		_p5 = assert(b3 == 42)
+	)
+}
+
+// iota
+const (
+	iota0 = iota
+	iota1 = iota
+	iota2 = iota*2
+	_a0 = assert(iota0 == 0)
+	_a1 = assert(iota1 == 1)
+	_a2 = assert(iota2 == 4)
+	iota6 = iota*3
+
+	iota7
+	iota8
+	_a3 = assert(iota7 == 21)
+	_a4 = assert(iota8 == 24)
+)
+
+const (
+	_b0 = iota
+	_b1 = assert(iota + iota2 == 5)
+	_b2 = len([iota]int{}) // iota may appear in a type!
+	_b3 = assert(_b2 == 2)
+	_b4 = len(A{})
+)
+
+type A [iota /* ERROR "cannot use iota" */ ]int
+
+// constant expressions with operands across different
+// constant declarations must use the right iota values
+const (
+	_c0 = iota
+	_c1
+	_c2
+	_x = _c2 + _d1 + _e0 // 3
+)
+
+const (
+	_d0 = iota
+	_d1
+)
+
+const (
+	_e0 = iota
+)
+
+var _ = assert(_x == 3)
+
+// special cases
+const (
+	_n0 = nil /* ERROR "not constant" */
+	_n1 = [ /* ERROR "not constant" */ ]int{}
+)
+
+// iotas must not be usable in expressions outside constant declarations
+type _ [iota /* ERROR "iota outside constant decl" */ ]byte
+var _ = iota /* ERROR "iota outside constant decl" */
+func _() {
+	_ = iota /* ERROR "iota outside constant decl" */
+	const _ = iota
+	_ = iota /* ERROR "iota outside constant decl" */
+}
+
+func _() {
+	iota := 123
+	const x = iota /* ERROR "is not constant" */
+	var y = iota
+	_ = y
+}
+
+// iotas are usable inside closures in constant declarations (#22345)
+const (
+	_ = iota
+	_ = len([iota]byte{})
+	_ = unsafe.Sizeof(iota)
+	_ = unsafe.Sizeof(func() { _ = iota })
+	_ = unsafe.Sizeof(func() { var _ = iota })
+	_ = unsafe.Sizeof(func() { const _ = iota })
+	_ = unsafe.Sizeof(func() { type _ [iota]byte })
+	_ = unsafe.Sizeof(func() { func() int { return iota }() })
+)
+
+// verify inner and outer const declarations have distinct iotas
+const (
+	zero = iota
+	one  = iota
+	_    = unsafe.Sizeof(func() {
+		var x [iota]int // [2]int
+		const (
+			Zero = iota
+			One
+			Two
+			_ = unsafe.Sizeof([iota-1]int{} == x) // assert types are equal
+			_ = unsafe.Sizeof([Two]int{} == x)    // assert types are equal
+		)
+		var z [iota]int                           // [2]int
+		_ = unsafe.Sizeof([2]int{} == z)          // assert types are equal
+	})
+	three = iota // the sequence continues
+)
+var _ [three]int = [3]int{} // assert 'three' has correct value
+
+var (
+	_ = iota /* ERROR "iota outside constant decl" */
+	_ = unsafe.Sizeof(iota  /* ERROR "iota outside constant decl" */ )
+	_ = unsafe.Sizeof(func() { _ = iota /* ERROR "iota outside constant decl" */ })
+	_ = unsafe.Sizeof(func() { var _ = iota /* ERROR "iota outside constant decl" */ })
+	_ = unsafe.Sizeof(func() { type _ [iota /* ERROR "iota outside constant decl" */ ]byte })
+	_ = unsafe.Sizeof(func() { func() int { return iota /* ERROR "iota outside constant decl" */ }() })
+)
+
+// constant arithmetic precision and rounding must lead to expected (integer) results
+var _ = []int64{
+	0.0005 * 1e9,
+	0.001 * 1e9,
+	0.005 * 1e9,
+	0.01 * 1e9,
+	0.05 * 1e9,
+	0.1 * 1e9,
+	0.5 * 1e9,
+	1 * 1e9,
+	5 * 1e9,
+}
+
+const _ = unsafe.Sizeof(func() {
+	const _ = 0
+	_ = iota
+
+	const (
+	   zero = iota
+	   one
+	)
+	assert(one == 1)
+	assert(iota == 0)
+})
+
+// untyped constants must not get arbitrarily large
+const prec = 512 // internal maximum precision for integers
+const maxInt = (1<<(prec/2) - 1) * (1<<(prec/2) + 1) // == 1<<prec - 1
+
+const _ = maxInt + /* ERROR constant addition overflow */ 1
+const _ = -maxInt - /* ERROR constant subtraction overflow */ 1
+const _ = maxInt ^ /* ERROR constant bitwise XOR overflow */ -1
+const _ = maxInt * /* ERROR constant multiplication overflow */ 2
+const _ = maxInt << /* ERROR constant shift overflow */ 2
+const _ = 1 << /* ERROR constant shift overflow */ prec
+
+const _ = ^ /* ERROR constant bitwise complement overflow */ maxInt
diff --git a/src/go/types/testdata/check/const1.src b/src/go/types/testdata/check/const1.src
new file mode 100644
index 0000000..c912801
--- /dev/null
+++ b/src/go/types/testdata/check/const1.src
@@ -0,0 +1,334 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// constant conversions
+
+package const1
+
+import "math"
+
+const(
+	mi = ^int(0)
+	mu = ^uint(0)
+	mp = ^uintptr(0)
+
+	logSizeofInt     = uint(mi>>8&1 + mi>>16&1 + mi>>32&1)
+	logSizeofUint    = uint(mu>>8&1 + mu>>16&1 + mu>>32&1)
+	logSizeofUintptr = uint(mp>>8&1 + mp>>16&1 + mp>>32&1)
+)
+
+const (
+	minInt8 = -1<<(8<<iota - 1)
+	minInt16
+	minInt32
+	minInt64
+	minInt = -1<<(8<<logSizeofInt - 1)
+)
+
+const (
+	maxInt8 = 1<<(8<<iota - 1) - 1
+	maxInt16
+	maxInt32
+	maxInt64
+	maxInt = 1<<(8<<logSizeofInt - 1) - 1
+)
+
+const (
+	maxUint8 = 1<<(8<<iota) - 1
+	maxUint16
+	maxUint32
+	maxUint64
+	maxUint    = 1<<(8<<logSizeofUint) - 1
+	maxUintptr = 1<<(8<<logSizeofUintptr) - 1
+)
+
+const (
+	smallestFloat32 = 1.0 / (1<<(127 - 1 + 23))
+	// TODO(gri) The compiler limits integers to 512 bit and thus
+	//           we cannot compute the value (1<<(1023 - 1 + 52))
+	//           without overflow. For now we match the compiler.
+	//           See also issue #44057.
+	// smallestFloat64 = 1.0 / (1<<(1023 - 1 + 52))
+	smallestFloat64 = math.SmallestNonzeroFloat64
+)
+
+const (
+	_ = assert(smallestFloat32 > 0)
+	_ = assert(smallestFloat64 > 0)
+)
+
+const (
+	maxFloat32 = 1<<127 * (1<<24 - 1) / (1.0<<23)
+	// TODO(gri) The compiler limits integers to 512 bit and thus
+	//           we cannot compute the value 1<<1023
+	//           without overflow. For now we match the compiler.
+	//           See also issue #44057.
+	// maxFloat64 = 1<<1023 * (1<<53 - 1) / (1.0<<52)
+	maxFloat64 = math.MaxFloat64
+)
+
+const (
+	_ int8 = minInt8 /* ERROR "overflows" */ - 1
+	_ int8 = minInt8
+	_ int8 = maxInt8
+	_ int8 = maxInt8 /* ERROR "overflows" */ + 1
+	_ int8 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = int8(minInt8 /* ERROR "cannot convert" */ - 1)
+	_ = int8(minInt8)
+	_ = int8(maxInt8)
+	_ = int8(maxInt8 /* ERROR "cannot convert" */ + 1)
+	_ = int8(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ int16 = minInt16 /* ERROR "overflows" */ - 1
+	_ int16 = minInt16
+	_ int16 = maxInt16
+	_ int16 = maxInt16 /* ERROR "overflows" */ + 1
+	_ int16 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = int16(minInt16 /* ERROR "cannot convert" */ - 1)
+	_ = int16(minInt16)
+	_ = int16(maxInt16)
+	_ = int16(maxInt16 /* ERROR "cannot convert" */ + 1)
+	_ = int16(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ int32 = minInt32 /* ERROR "overflows" */ - 1
+	_ int32 = minInt32
+	_ int32 = maxInt32
+	_ int32 = maxInt32 /* ERROR "overflows" */ + 1
+	_ int32 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = int32(minInt32 /* ERROR "cannot convert" */ - 1)
+	_ = int32(minInt32)
+	_ = int32(maxInt32)
+	_ = int32(maxInt32 /* ERROR "cannot convert" */ + 1)
+	_ = int32(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ int64 = minInt64 /* ERROR "overflows" */ - 1
+	_ int64 = minInt64
+	_ int64 = maxInt64
+	_ int64 = maxInt64 /* ERROR "overflows" */ + 1
+	_ int64 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = int64(minInt64 /* ERROR "cannot convert" */ - 1)
+	_ = int64(minInt64)
+	_ = int64(maxInt64)
+	_ = int64(maxInt64 /* ERROR "cannot convert" */ + 1)
+	_ = int64(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ int = minInt /* ERROR "overflows" */ - 1
+	_ int = minInt
+	_ int = maxInt
+	_ int = maxInt /* ERROR "overflows" */ + 1
+	_ int = smallestFloat64 /* ERROR "truncated" */
+
+	_ = int(minInt /* ERROR "cannot convert" */ - 1)
+	_ = int(minInt)
+	_ = int(maxInt)
+	_ = int(maxInt /* ERROR "cannot convert" */ + 1)
+	_ = int(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ uint8 = 0 /* ERROR "overflows" */ - 1
+	_ uint8 = 0
+	_ uint8 = maxUint8
+	_ uint8 = maxUint8 /* ERROR "overflows" */ + 1
+	_ uint8 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = uint8(0 /* ERROR "cannot convert" */ - 1)
+	_ = uint8(0)
+	_ = uint8(maxUint8)
+	_ = uint8(maxUint8 /* ERROR "cannot convert" */ + 1)
+	_ = uint8(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ uint16 = 0 /* ERROR "overflows" */ - 1
+	_ uint16 = 0
+	_ uint16 = maxUint16
+	_ uint16 = maxUint16 /* ERROR "overflows" */ + 1
+	_ uint16 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = uint16(0 /* ERROR "cannot convert" */ - 1)
+	_ = uint16(0)
+	_ = uint16(maxUint16)
+	_ = uint16(maxUint16 /* ERROR "cannot convert" */ + 1)
+	_ = uint16(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ uint32 = 0 /* ERROR "overflows" */ - 1
+	_ uint32 = 0
+	_ uint32 = maxUint32
+	_ uint32 = maxUint32 /* ERROR "overflows" */ + 1
+	_ uint32 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = uint32(0 /* ERROR "cannot convert" */ - 1)
+	_ = uint32(0)
+	_ = uint32(maxUint32)
+	_ = uint32(maxUint32 /* ERROR "cannot convert" */ + 1)
+	_ = uint32(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ uint64 = 0 /* ERROR "overflows" */ - 1
+	_ uint64 = 0
+	_ uint64 = maxUint64
+	_ uint64 = maxUint64 /* ERROR "overflows" */ + 1
+	_ uint64 = smallestFloat64 /* ERROR "truncated" */
+
+	_ = uint64(0 /* ERROR "cannot convert" */ - 1)
+	_ = uint64(0)
+	_ = uint64(maxUint64)
+	_ = uint64(maxUint64 /* ERROR "cannot convert" */ + 1)
+	_ = uint64(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ uint = 0 /* ERROR "overflows" */ - 1
+	_ uint = 0
+	_ uint = maxUint
+	_ uint = maxUint /* ERROR "overflows" */ + 1
+	_ uint = smallestFloat64 /* ERROR "truncated" */
+
+	_ = uint(0 /* ERROR "cannot convert" */ - 1)
+	_ = uint(0)
+	_ = uint(maxUint)
+	_ = uint(maxUint /* ERROR "cannot convert" */ + 1)
+	_ = uint(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ uintptr = 0 /* ERROR "overflows" */ - 1
+	_ uintptr = 0
+	_ uintptr = maxUintptr
+	_ uintptr = maxUintptr /* ERROR "overflows" */ + 1
+	_ uintptr = smallestFloat64 /* ERROR "truncated" */
+
+	_ = uintptr(0 /* ERROR "cannot convert" */ - 1)
+	_ = uintptr(0)
+	_ = uintptr(maxUintptr)
+	_ = uintptr(maxUintptr /* ERROR "cannot convert" */ + 1)
+	_ = uintptr(smallestFloat64 /* ERROR "cannot convert" */)
+)
+
+const (
+	_ float32 = minInt64
+	_ float64 = minInt64
+	_ complex64 = minInt64
+	_ complex128 = minInt64
+
+	_ = float32(minInt64)
+	_ = float64(minInt64)
+	_ = complex64(minInt64)
+	_ = complex128(minInt64)
+)
+
+const (
+	_ float32 = maxUint64
+	_ float64 = maxUint64
+	_ complex64 = maxUint64
+	_ complex128 = maxUint64
+
+	_ = float32(maxUint64)
+	_ = float64(maxUint64)
+	_ = complex64(maxUint64)
+	_ = complex128(maxUint64)
+)
+
+// TODO(gri) find smaller deltas below
+
+const delta32 = maxFloat32/(1 << 23)
+
+const (
+	_ float32 = - /* ERROR "overflow" */ (maxFloat32 + delta32)
+	_ float32 = -maxFloat32
+	_ float32 = maxFloat32
+	_ float32 = maxFloat32 /* ERROR "overflow" */ + delta32
+
+	_ = float32(- /* ERROR "cannot convert" */ (maxFloat32 + delta32))
+	_ = float32(-maxFloat32)
+	_ = float32(maxFloat32)
+	_ = float32(maxFloat32 /* ERROR "cannot convert" */ + delta32)
+
+	_ = assert(float32(smallestFloat32) == smallestFloat32)
+	_ = assert(float32(smallestFloat32/2) == 0)
+	_ = assert(float32(smallestFloat64) == 0)
+	_ = assert(float32(smallestFloat64/2) == 0)
+)
+
+const delta64 = maxFloat64/(1 << 52)
+
+const (
+	_ float64 = - /* ERROR "overflow" */ (maxFloat64 + delta64)
+	_ float64 = -maxFloat64
+	_ float64 = maxFloat64
+	_ float64 = maxFloat64 /* ERROR "overflow" */ + delta64
+
+	_ = float64(- /* ERROR "cannot convert" */ (maxFloat64 + delta64))
+	_ = float64(-maxFloat64)
+	_ = float64(maxFloat64)
+	_ = float64(maxFloat64 /* ERROR "cannot convert" */ + delta64)
+
+	_ = assert(float64(smallestFloat32) == smallestFloat32)
+	_ = assert(float64(smallestFloat32/2) == smallestFloat32/2)
+	_ = assert(float64(smallestFloat64) == smallestFloat64)
+	_ = assert(float64(smallestFloat64/2) == 0)
+)
+
+const (
+	_ complex64 = - /* ERROR "overflow" */ (maxFloat32 + delta32)
+	_ complex64 = -maxFloat32
+	_ complex64 = maxFloat32
+	_ complex64 = maxFloat32 /* ERROR "overflow" */ + delta32
+
+	_ = complex64(- /* ERROR "cannot convert" */ (maxFloat32 + delta32))
+	_ = complex64(-maxFloat32)
+	_ = complex64(maxFloat32)
+	_ = complex64(maxFloat32 /* ERROR "cannot convert" */ + delta32)
+)
+
+const (
+	_ complex128 = - /* ERROR "overflow" */ (maxFloat64 + delta64)
+	_ complex128 = -maxFloat64
+	_ complex128 = maxFloat64
+	_ complex128 = maxFloat64 /* ERROR "overflow" */ + delta64
+
+	_ = complex128(- /* ERROR "cannot convert" */ (maxFloat64 + delta64))
+	_ = complex128(-maxFloat64)
+	_ = complex128(maxFloat64)
+	_ = complex128(maxFloat64 /* ERROR "cannot convert" */ + delta64)
+)
+
+// Initialization of typed constant and conversion are the same:
+const (
+	f32 = 1 + smallestFloat32
+	x32 float32 = f32
+	y32 = float32(f32)
+	_ = assert(x32 - y32 == 0)
+)
+
+const (
+	f64 = 1 + smallestFloat64
+	x64 float64 = f64
+	y64 = float64(f64)
+	_ = assert(x64 - y64 == 0)
+)
+
+const (
+	_ = int8(-1) << 7
+	_ = int8 /* ERROR "overflows" */ (-1) << 8
+
+	_ = uint32(1) << 31
+	_ = uint32 /* ERROR "overflows" */ (1) << 32
+)
diff --git a/src/go/types/testdata/constdecl.src b/src/go/types/testdata/check/constdecl.src
similarity index 100%
rename from src/go/types/testdata/constdecl.src
rename to src/go/types/testdata/check/constdecl.src
diff --git a/src/go/types/testdata/conversions.src b/src/go/types/testdata/check/conversions.src
similarity index 100%
rename from src/go/types/testdata/conversions.src
rename to src/go/types/testdata/check/conversions.src
diff --git a/src/go/types/testdata/conversions2.src b/src/go/types/testdata/check/conversions2.src
similarity index 100%
rename from src/go/types/testdata/conversions2.src
rename to src/go/types/testdata/check/conversions2.src
diff --git a/src/go/types/testdata/cycles.src b/src/go/types/testdata/check/cycles.src
similarity index 100%
rename from src/go/types/testdata/cycles.src
rename to src/go/types/testdata/check/cycles.src
diff --git a/src/go/types/testdata/cycles1.src b/src/go/types/testdata/check/cycles1.src
similarity index 100%
rename from src/go/types/testdata/cycles1.src
rename to src/go/types/testdata/check/cycles1.src
diff --git a/src/go/types/testdata/cycles2.src b/src/go/types/testdata/check/cycles2.src
similarity index 100%
rename from src/go/types/testdata/cycles2.src
rename to src/go/types/testdata/check/cycles2.src
diff --git a/src/go/types/testdata/cycles3.src b/src/go/types/testdata/check/cycles3.src
similarity index 100%
rename from src/go/types/testdata/cycles3.src
rename to src/go/types/testdata/check/cycles3.src
diff --git a/src/go/types/testdata/cycles4.src b/src/go/types/testdata/check/cycles4.src
similarity index 100%
rename from src/go/types/testdata/cycles4.src
rename to src/go/types/testdata/check/cycles4.src
diff --git a/src/go/types/testdata/cycles5.src b/src/go/types/testdata/check/cycles5.src
similarity index 100%
rename from src/go/types/testdata/cycles5.src
rename to src/go/types/testdata/check/cycles5.src
diff --git a/src/go/types/testdata/check/decls0.src b/src/go/types/testdata/check/decls0.src
new file mode 100644
index 0000000..5ad8f53
--- /dev/null
+++ b/src/go/types/testdata/check/decls0.src
@@ -0,0 +1,208 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// type declarations
+
+package decls0
+
+import "unsafe"
+
+const pi = 3.1415
+
+type (
+	N undeclared /* ERROR "undeclared" */
+	B bool
+	I int32
+	A [10]P
+	T struct {
+		x, y P
+	}
+	P *T
+	R (*R)
+	F func(A) I
+	Y interface {
+		f(A) I
+	}
+	S [](((P)))
+	M map[I]F
+	C chan<- I
+
+	// blank types must be typechecked
+	_ pi /* ERROR "not a type" */
+	_ struct{}
+	_ struct{ pi /* ERROR "not a type" */ }
+)
+
+
+// declarations of init
+const _, init /* ERROR "cannot declare init" */ , _ = 0, 1, 2
+type init /* ERROR "cannot declare init" */ struct{}
+var _, init /* ERROR "cannot declare init" */ int
+
+func init() {}
+func init /* ERROR "missing function body" */ ()
+
+func _() { const init = 0 }
+func _() { type init int }
+func _() { var init int; _ = init }
+
+// invalid array types
+type (
+	iA0 [... /* ERROR "invalid use of '...'" */ ]byte
+	// The error message below could be better. At the moment
+	// we believe an integer that is too large is not an integer.
+	// But at least we get an error.
+	iA1 [1 /* ERROR "must be integer" */ <<100]int
+	iA2 [- /* ERROR "invalid array length" */ 1]complex128
+	iA3 ["foo" /* ERROR "must be integer" */ ]string
+	iA4 [float64 /* ERROR "must be integer" */ (0)]int
+)
+
+
+type (
+	p1 pi.foo /* ERROR "no field or method foo" */
+	p2 unsafe.Pointer
+)
+
+
+type (
+	Pi pi /* ERROR "not a type" */
+
+	a /* ERROR "illegal cycle" */ a
+	a /* ERROR "redeclared" */ int
+
+	b /* ERROR "illegal cycle" */ c
+	c d
+	d e
+	e b
+
+	t *t
+
+	U V
+	V *W
+	W U
+
+	P1 *S2
+	P2 P1
+
+	S0 struct {
+	}
+	S1 struct {
+		a, b, c int
+		u, v, a /* ERROR "redeclared" */ float32
+	}
+	S2 struct {
+		S0 // embedded field
+		S0 /* ERROR "redeclared" */ int
+	}
+	S3 struct {
+		x S2
+	}
+	S4/* ERROR "illegal cycle" */ struct {
+		S4
+	}
+	S5 /* ERROR "illegal cycle" */ struct {
+		S6
+	}
+	S6 struct {
+		field S7
+	}
+	S7 struct {
+		S5
+	}
+
+	L1 []L1
+	L2 []int
+
+	A1 [10.0]int
+	A2 /* ERROR "illegal cycle" */ [10]A2
+	A3 /* ERROR "illegal cycle" */ [10]struct {
+		x A4
+	}
+	A4 [10]A3
+
+	F1 func()
+	F2 func(x, y, z float32)
+	F3 func(x, y, x /* ERROR "redeclared" */ float32)
+	F4 func() (x, y, x /* ERROR "redeclared" */ float32)
+	F5 func(x int) (x /* ERROR "redeclared" */ float32)
+	F6 func(x ...int)
+
+	I1 interface{}
+	I2 interface {
+		m1()
+	}
+	I3 interface {
+		m1()
+		m1 /* ERROR "duplicate method" */ ()
+	}
+	I4 interface {
+		m1(x, y, x /* ERROR "redeclared" */ float32)
+		m2() (x, y, x /* ERROR "redeclared" */ float32)
+		m3(x int) (x /* ERROR "redeclared" */ float32)
+	}
+	I5 interface {
+		m1(I5)
+	}
+	I6 interface {
+		S0 /* ERROR "not an interface" */
+	}
+	I7 interface {
+		I1
+		I1
+	}
+	I8 /* ERROR "illegal cycle" */ interface {
+		I8
+	}
+	I9 /* ERROR "illegal cycle" */ interface {
+		I10
+	}
+	I10 interface {
+		I11
+	}
+	I11 interface {
+		I9
+	}
+
+	C1 chan int
+	C2 <-chan int
+	C3 chan<- C3
+	C4 chan C5
+	C5 chan C6
+	C6 chan C4
+
+	M1 map[Last]string
+	M2 map[string]M2
+
+	Last int
+)
+
+// cycles in function/method declarations
+// (test cases for issues #5217, #25790 and variants)
+func f1(x f1 /* ERROR "not a type" */ ) {}
+func f2(x *f2 /* ERROR "not a type" */ ) {}
+func f3() (x f3 /* ERROR "not a type" */ ) { return }
+func f4() (x *f4 /* ERROR "not a type" */ ) { return }
+// TODO(#43215) this should be detected as a cycle error
+func f5([unsafe.Sizeof(f5)]int) {}
+
+func (S0) m1 (x S0 /* ERROR value .* is not a type */ .m1) {}
+func (S0) m2 (x *S0 /* ERROR value .* is not a type */ .m2) {}
+func (S0) m3 () (x S0 /* ERROR value .* is not a type */ .m3) { return }
+func (S0) m4 () (x *S0 /* ERROR value .* is not a type */ .m4) { return }
+
+// interfaces may not have any blank methods
+type BlankI interface {
+	_ /* ERROR "invalid method name" */ ()
+	_ /* ERROR "invalid method name" */ (float32) int
+	m()
+}
+
+// non-interface types may have multiple blank methods
+type BlankT struct{}
+
+func (BlankT) _() {}
+func (BlankT) _(int) {}
+func (BlankT) _() int { return 0 }
+func (BlankT) _(int) int { return 0}
diff --git a/src/go/types/testdata/decls1.src b/src/go/types/testdata/check/decls1.src
similarity index 100%
rename from src/go/types/testdata/decls1.src
rename to src/go/types/testdata/check/decls1.src
diff --git a/src/go/types/testdata/decls2a.src b/src/go/types/testdata/check/decls2/decls2a.src
similarity index 100%
rename from src/go/types/testdata/decls2a.src
rename to src/go/types/testdata/check/decls2/decls2a.src
diff --git a/src/go/types/testdata/decls2b.src b/src/go/types/testdata/check/decls2/decls2b.src
similarity index 100%
rename from src/go/types/testdata/decls2b.src
rename to src/go/types/testdata/check/decls2/decls2b.src
diff --git a/src/go/types/testdata/decls3.src b/src/go/types/testdata/check/decls3.src
similarity index 100%
rename from src/go/types/testdata/decls3.src
rename to src/go/types/testdata/check/decls3.src
diff --git a/src/go/types/testdata/decls4.src b/src/go/types/testdata/check/decls4.src
similarity index 100%
rename from src/go/types/testdata/decls4.src
rename to src/go/types/testdata/check/decls4.src
diff --git a/src/go/types/testdata/decls5.src b/src/go/types/testdata/check/decls5.src
similarity index 100%
rename from src/go/types/testdata/decls5.src
rename to src/go/types/testdata/check/decls5.src
diff --git a/src/go/types/testdata/errors.src b/src/go/types/testdata/check/errors.src
similarity index 100%
rename from src/go/types/testdata/errors.src
rename to src/go/types/testdata/check/errors.src
diff --git a/src/go/types/testdata/expr0.src b/src/go/types/testdata/check/expr0.src
similarity index 100%
rename from src/go/types/testdata/expr0.src
rename to src/go/types/testdata/check/expr0.src
diff --git a/src/go/types/testdata/expr1.src b/src/go/types/testdata/check/expr1.src
similarity index 100%
rename from src/go/types/testdata/expr1.src
rename to src/go/types/testdata/check/expr1.src
diff --git a/src/go/types/testdata/expr2.src b/src/go/types/testdata/check/expr2.src
similarity index 100%
rename from src/go/types/testdata/expr2.src
rename to src/go/types/testdata/check/expr2.src
diff --git a/src/go/types/testdata/check/expr3.src b/src/go/types/testdata/check/expr3.src
new file mode 100644
index 0000000..0525a5a
--- /dev/null
+++ b/src/go/types/testdata/check/expr3.src
@@ -0,0 +1,564 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package expr3
+
+import "time"
+
+func indexes() {
+	_ = 1 /* ERROR "cannot index" */ [0]
+	_ = indexes /* ERROR "cannot index" */ [0]
+	_ = ( /* ERROR "cannot slice" */ 12 + 3)[1:2]
+
+	var a [10]int
+	_ = a[true /* ERROR "cannot convert" */ ]
+	_ = a["foo" /* ERROR "cannot convert" */ ]
+	_ = a[1.1 /* ERROR "truncated" */ ]
+	_ = a[1.0]
+	_ = a[- /* ERROR "negative" */ 1]
+	_ = a[- /* ERROR "negative" */ 1 :]
+	_ = a[: - /* ERROR "negative" */ 1]
+	_ = a[: /* ERROR "2nd index required" */ : /* ERROR "3rd index required" */ ]
+	_ = a[0: /* ERROR "2nd index required" */ : /* ERROR "3rd index required" */ ]
+	_ = a[0: /* ERROR "2nd index required" */ :10]
+	_ = a[:10:10]
+
+	var a0 int
+	a0 = a[0]
+	_ = a0
+	var a1 int32
+	a1 = a /* ERROR "cannot use .* in assignment" */ [1]
+	_ = a1
+
+	_ = a[9]
+	_ = a[10 /* ERROR "index .* out of bounds" */ ]
+	_ = a[1 /* ERROR "overflows" */ <<100]
+	_ = a[1<< /* ERROR "constant shift overflow" */ 1000] // no out-of-bounds follow-on error
+	_ = a[10:]
+	_ = a[:10]
+	_ = a[10:10]
+	_ = a[11 /* ERROR "index .* out of bounds" */ :]
+	_ = a[: 11 /* ERROR "index .* out of bounds" */ ]
+	_ = a[: 1 /* ERROR "overflows" */ <<100]
+	_ = a[:10:10]
+	_ = a[:11 /* ERROR "index .* out of bounds" */ :10]
+	_ = a[:10:11 /* ERROR "index .* out of bounds" */ ]
+	_ = a[10:0:10] /* ERROR swapped slice indices" */
+	_ = a[0:10:0] /* ERROR "swapped slice indices" */
+	_ = a[10:0:0] /* ERROR "swapped slice indices" */
+	_ = &a /* ERROR "cannot take address" */ [:10]
+
+	pa := &a
+	_ = pa[9]
+	_ = pa[10 /* ERROR "index .* out of bounds" */ ]
+	_ = pa[1 /* ERROR "overflows" */ <<100]
+	_ = pa[10:]
+	_ = pa[:10]
+	_ = pa[10:10]
+	_ = pa[11 /* ERROR "index .* out of bounds" */ :]
+	_ = pa[: 11 /* ERROR "index .* out of bounds" */ ]
+	_ = pa[: 1 /* ERROR "overflows" */ <<100]
+	_ = pa[:10:10]
+	_ = pa[:11 /* ERROR "index .* out of bounds" */ :10]
+	_ = pa[:10:11 /* ERROR "index .* out of bounds" */ ]
+	_ = pa[10:0:10] /* ERROR "swapped slice indices" */
+	_ = pa[0:10:0] /* ERROR "swapped slice indices" */
+	_ = pa[10:0:0] /* ERROR "swapped slice indices" */
+	_ = &pa /* ERROR "cannot take address" */ [:10]
+
+	var b [0]int
+	_ = b[0 /* ERROR "index .* out of bounds" */ ]
+	_ = b[:]
+	_ = b[0:]
+	_ = b[:0]
+	_ = b[0:0]
+	_ = b[0:0:0]
+	_ = b[1 /* ERROR "index .* out of bounds" */ :0:0]
+
+	var s []int
+	_ = s[- /* ERROR "negative" */ 1]
+	_ = s[- /* ERROR "negative" */ 1 :]
+	_ = s[: - /* ERROR "negative" */ 1]
+	_ = s[0]
+	_ = s[1:2]
+	_ = s[2:1] /* ERROR "swapped slice indices" */
+	_ = s[2:]
+	_ = s[: 1 /* ERROR "overflows" */ <<100]
+	_ = s[1 /* ERROR "overflows" */ <<100 :]
+	_ = s[1 /* ERROR "overflows" */ <<100 : 1 /* ERROR "overflows" */ <<100]
+	_ = s[: /* ERROR "2nd index required" */ :  /* ERROR "3rd index required" */ ]
+	_ = s[:10:10]
+	_ = s[10:0:10] /* ERROR "swapped slice indices" */
+	_ = s[0:10:0] /* ERROR "swapped slice indices" */
+	_ = s[10:0:0] /* ERROR "swapped slice indices" */
+	_ = &s /* ERROR "cannot take address" */ [:10]
+
+	var m map[string]int
+	_ = m[0 /* ERROR "cannot use .* in map index" */ ]
+	_ = m /* ERROR "cannot slice" */ ["foo" : "bar"]
+	_ = m["foo"]
+	// ok is of type bool
+	type mybool bool
+	var ok mybool
+	_, ok = m["bar"]
+	_ = ok
+	_ = m[0 /* ERROR "cannot use 0" */ ] + "foo" // ERROR "cannot convert"
+
+	var t string
+	_ = t[- /* ERROR "negative" */ 1]
+	_ = t[- /* ERROR "negative" */ 1 :]
+	_ = t[: - /* ERROR "negative" */ 1]
+	_ = t /* ERROR "3-index slice of string" */ [1:2:3]
+	_ = "foo" /* ERROR "3-index slice of string" */ [1:2:3]
+	var t0 byte
+	t0 = t[0]
+	_ = t0
+	var t1 rune
+	t1 = t /* ERROR "cannot use .* in assignment" */ [2]
+	_ = t1
+	_ = ("foo" + "bar")[5]
+	_ = ("foo" + "bar")[6 /* ERROR "index .* out of bounds" */ ]
+
+	const c = "foo"
+	_ = c[- /* ERROR "negative" */ 1]
+	_ = c[- /* ERROR "negative" */ 1 :]
+	_ = c[: - /* ERROR "negative" */ 1]
+	var c0 byte
+	c0 = c[0]
+	_ = c0
+	var c2 float32
+	c2 = c /* ERROR "cannot use .* in assignment" */ [2]
+	_ = c[3 /* ERROR "index .* out of bounds" */ ]
+	_ = ""[0 /* ERROR "index .* out of bounds" */ ]
+	_ = c2
+
+	_ = s[1<<30] // no compile-time error here
+
+	// issue 4913
+	type mystring string
+	var ss string
+	var ms mystring
+	var i, j int
+	ss = "foo"[1:2]
+	ss = "foo"[i:j]
+	ms = "foo" /* ERROR "cannot use .* in assignment" */ [1:2]
+	ms = "foo" /* ERROR "cannot use .* in assignment" */ [i:j]
+	_, _ = ss, ms
+}
+
+type T struct {
+	x int
+	y func()
+}
+
+func (*T) m() {}
+
+func method_expressions() {
+	_ = T.a /* ERROR "no field or method" */
+	_ = T.x /* ERROR "has no method" */
+	_ = T.m /* ERROR "cannot call pointer method m on T" */
+	_ = (*T).m
+
+	var f func(*T) = T.m /* ERROR "cannot call pointer method m on T" */
+	var g func(*T) = (*T).m
+	_, _ = f, g
+
+	_ = T.y /* ERROR "has no method" */
+	_ = (*T).y /* ERROR "has no method" */
+}
+
+func struct_literals() {
+	type T0 struct {
+		a, b, c int
+	}
+
+	type T1 struct {
+		T0
+		a, b int
+		u float64
+		s string
+	}
+
+	// keyed elements
+	_ = T1{}
+	_ = T1{a: 0, 1 /* ERROR "mixture of .* elements" */ }
+	_ = T1{aa /* ERROR "unknown field" */ : 0}
+	_ = T1{1 /* ERROR "invalid field name" */ : 0}
+	_ = T1{a: 0, s: "foo", u: 0, a /* ERROR "duplicate field" */: 10}
+	_ = T1{a: "foo" /* ERROR "cannot use .* in struct literal" */ }
+	_ = T1{c /* ERROR "unknown field" */ : 0}
+	_ = T1{T0: { /* ERROR "missing type" */ }} // struct literal element type may not be elided
+	_ = T1{T0: T0{}}
+	_ = T1{T0 /* ERROR "invalid field name" */ .a: 0}
+
+	// unkeyed elements
+	_ = T0{1, 2, 3}
+	_ = T0{1, b /* ERROR "mixture" */ : 2, 3}
+	_ = T0{1, 2} /* ERROR "too few values" */
+	_ = T0{1, 2, 3, 4  /* ERROR "too many values" */ }
+	_ = T0{1, "foo" /* ERROR "cannot use .* in struct literal" */, 3.4  /* ERROR "cannot use .*\(truncated\)" */}
+
+	// invalid type
+	type P *struct{
+		x int
+	}
+	_ = P /* ERROR "invalid composite literal type" */ {}
+
+	// unexported fields
+	_ = time.Time{}
+	_ = time.Time{sec /* ERROR "unknown field" */ : 0}
+	_ = time.Time{
+		0 /* ERROR implicit assignment to unexported field wall in time.Time literal */,
+		0 /* ERROR implicit assignment */ ,
+		nil /* ERROR implicit assignment */ ,
+	}
+}
+
+func array_literals() {
+	type A0 [0]int
+	_ = A0{}
+	_ = A0{0 /* ERROR "index .* out of bounds" */}
+	_ = A0{0 /* ERROR "index .* out of bounds" */ : 0}
+
+	type A1 [10]int
+	_ = A1{}
+	_ = A1{0, 1, 2}
+	_ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+	_ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /* ERROR "index .* out of bounds" */ }
+	_ = A1{- /* ERROR "negative" */ 1: 0}
+	_ = A1{8: 8, 9}
+	_ = A1{8: 8, 9, 10 /* ERROR "index .* out of bounds" */ }
+	_ = A1{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
+	_ = A1{5: 5, 6, 7, 3: 3, 4}
+	_ = A1{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ }
+	_ = A1{10 /* ERROR "index .* out of bounds" */ : 10, 10 /* ERROR "index .* out of bounds" */ : 10}
+	_ = A1{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ }
+	_ = A1{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4}
+	_ = A1{2.0}
+	_ = A1{2.1 /* ERROR "truncated" */ }
+	_ = A1{"foo" /* ERROR "cannot use .* in array or slice literal" */ }
+
+	// indices must be integer constants
+	i := 1
+	const f = 2.1
+	const s = "foo"
+	_ = A1{i /* ERROR "index i must be integer constant" */ : 0}
+	_ = A1{f /* ERROR "truncated" */ : 0}
+	_ = A1{s /* ERROR "cannot convert" */ : 0}
+
+	a0 := [...]int{}
+	assert(len(a0) == 0)
+
+	a1 := [...]int{0, 1, 2}
+	assert(len(a1) == 3)
+	var a13 [3]int
+	var a14 [4]int
+	a13 = a1
+	a14 = a1 /* ERROR "cannot use .* in assignment" */
+	_, _ = a13, a14
+
+	a2 := [...]int{- /* ERROR "negative" */ 1: 0}
+	_ = a2
+
+	a3 := [...]int{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
+	assert(len(a3) == 5) // somewhat arbitrary
+
+	a4 := [...]complex128{0, 1, 2, 1<<10-2: -1i, 1i, 400: 10, 12, 14}
+	assert(len(a4) == 1024)
+
+	// composite literal element types may be elided
+	type T []int
+	_ = [10]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
+	a6 := [...]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
+	assert(len(a6) == 8)
+
+	// recursively so
+	_ = [10][10]T{{}, [10]T{{}}, {{1, 2, 3}}}
+
+	// from the spec
+	type Point struct { x, y float32 }
+	_ = [...]Point{Point{1.5, -3.5}, Point{0, 0}}
+	_ = [...]Point{{1.5, -3.5}, {0, 0}}
+	_ = [][]int{[]int{1, 2, 3}, []int{4, 5}}
+	_ = [][]int{{1, 2, 3}, {4, 5}}
+	_ = [...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}
+	_ = [...]*Point{{1.5, -3.5}, {0, 0}}
+}
+
+func slice_literals() {
+	type S0 []int
+	_ = S0{}
+	_ = S0{0, 1, 2}
+	_ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+	_ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
+	_ = S0{- /* ERROR "negative" */ 1: 0}
+	_ = S0{8: 8, 9}
+	_ = S0{8: 8, 9, 10}
+	_ = S0{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
+	_ = S0{5: 5, 6, 7, 3: 3, 4}
+	_ = S0{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ }
+	_ = S0{10: 10, 10 /* ERROR "duplicate index" */ : 10}
+	_ = S0{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ }
+	_ = S0{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4}
+	_ = S0{2.0}
+	_ = S0{2.1 /* ERROR "truncated" */ }
+	_ = S0{"foo" /* ERROR "cannot use .* in array or slice literal" */ }
+
+	// indices must be resolved correctly
+	const index1 = 1
+	_ = S0{index1: 1}
+	_ = S0{index2: 2}
+	_ = S0{index3 /* ERROR "undeclared name" */ : 3}
+
+	// indices must be integer constants
+	i := 1
+	const f = 2.1
+	const s = "foo"
+	_ = S0{i /* ERROR "index i must be integer constant" */ : 0}
+	_ = S0{f /* ERROR "truncated" */ : 0}
+	_ = S0{s /* ERROR "cannot convert" */ : 0}
+
+	// composite literal element types may be elided
+	type T []int
+	_ = []T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
+	_ = [][]int{{1, 2, 3}, {4, 5}}
+
+	// recursively so
+	_ = [][]T{{}, []T{{}}, {{1, 2, 3}}}
+
+	// issue 17954
+	type T0 *struct { s string }
+	_ = []T0{{}}
+	_ = []T0{{"foo"}}
+
+	type T1 *struct{ int }
+	_ = []T1{}
+	_ = []T1{{0}, {1}, {2}}
+
+	type T2 T1
+	_ = []T2{}
+	_ = []T2{{0}, {1}, {2}}
+
+	_ = map[T0]T2{}
+	_ = map[T0]T2{{}: {}}
+}
+
+const index2 int = 2
+
+type N int
+func (N) f() {}
+
+func map_literals() {
+	type M0 map[string]int
+	type M1 map[bool]int
+	type M2 map[*int]int
+
+	_ = M0{}
+	_ = M0{1 /* ERROR "missing key" */ }
+	_ = M0{1 /* ERROR "cannot use .* in map literal" */ : 2}
+	_ = M0{"foo": "bar" /* ERROR "cannot use .* in map literal" */ }
+	_ = M0{"foo": 1, "bar": 2, "foo" /* ERROR "duplicate key" */ : 3 }
+
+	_ = map[interface{}]int{2: 1, 2 /* ERROR "duplicate key" */ : 1}
+	_ = map[interface{}]int{int(2): 1, int16(2): 1}
+	_ = map[interface{}]int{int16(2): 1, int16 /* ERROR "duplicate key" */ (2): 1}
+
+	type S string
+
+	_ = map[interface{}]int{"a": 1, "a" /* ERROR "duplicate key" */ : 1}
+	_ = map[interface{}]int{"a": 1, S("a"): 1}
+	_ = map[interface{}]int{S("a"): 1, S /* ERROR "duplicate key" */ ("a"): 1}
+	_ = map[interface{}]int{1.0: 1, 1.0 /* ERROR "duplicate key" */: 1}
+	_ = map[interface{}]int{int64(-1): 1, int64 /* ERROR "duplicate key" */ (-1) : 1}
+	_ = map[interface{}]int{^uint64(0): 1, ^ /* ERROR "duplicate key" */ uint64(0): 1}
+	_ = map[interface{}]int{complex(1,2): 1, complex /* ERROR "duplicate key" */ (1,2) : 1}
+
+	type I interface {
+		f()
+	}
+
+	_ = map[I]int{N(0): 1, N(2): 1}
+	_ = map[I]int{N(2): 1, N /* ERROR "duplicate key" */ (2): 1}
+
+	// map keys must be resolved correctly
+	key1 := "foo"
+	_ = M0{key1: 1}
+	_ = M0{key2: 2}
+	_ = M0{key3 /* ERROR "undeclared name" */ : 2}
+
+	var value int
+	_ = M1{true: 1, false: 0}
+	_ = M2{nil: 0, &value: 1}
+
+	// composite literal element types may be elided
+	type T [2]int
+	_ = map[int]T{0: T{3, 4}, 1: {5, 6}}
+
+	// recursively so
+	_ = map[int][]T{0: {}, 1: {{}, T{1, 2}}}
+
+	// composite literal key types may be elided
+	_ = map[T]int{T{3, 4}: 0, {5, 6}: 1}
+
+	// recursively so
+	_ = map[[2]T]int{{}: 0, {{}}: 1, [2]T{{}}: 2, {T{1, 2}}: 3}
+
+	// composite literal element and key types may be elided
+	_ = map[T]T{{}: {}, {1, 2}: T{3, 4}, T{4, 5}: {}}
+	_ = map[T]M0{{} : {}, T{1, 2}: M0{"foo": 0}, {1, 3}: {"foo": 1}}
+
+	// recursively so
+	_ = map[[2]T][]T{{}: {}, {{}}: {{}, T{1, 2}}, [2]T{{}}: nil, {T{1, 2}}: {{}, {}}}
+
+	// from the spec
+	type Point struct { x, y float32 }
+	_ = map[string]Point{"orig": {0, 0}}
+	_ = map[*Point]string{{0, 0}: "orig"}
+
+	// issue 17954
+	type T0 *struct{ s string }
+	type T1 *struct{ int }
+	type T2 T1
+
+	_ = map[T0]T2{}
+	_ = map[T0]T2{{}: {}}
+}
+
+var key2 string = "bar"
+
+type I interface {
+	m()
+}
+
+type I2 interface {
+	m(int)
+}
+
+type T1 struct{}
+type T2 struct{}
+
+func (T2) m(int) {}
+
+type mybool bool
+
+func type_asserts() {
+	var x int
+	_ = x /* ERROR "not an interface" */ .(int)
+
+	var e interface{}
+	var ok bool
+	x, ok = e.(int)
+	_ = ok
+
+	// ok value is of type bool
+	var myok mybool
+	_, myok = e.(int)
+	_ = myok
+
+	var t I
+	_ = t /* ERROR "use of .* outside type switch" */ .(type)
+	_ = t /* ERROR "missing method m" */ .(T)
+	_ = t.(*T)
+	_ = t /* ERROR "missing method m" */ .(T1)
+	_ = t /* ERROR "wrong type for method m" */ .(T2)
+	_ = t /* STRICT "wrong type for method m" */ .(I2) // only an error in strict mode (issue 8561)
+
+	// e doesn't statically have an m, but may have one dynamically.
+	_ = e.(I2)
+}
+
+func f0() {}
+func f1(x int) {}
+func f2(u float32, s string) {}
+func fs(s []byte) {}
+func fv(x ...int) {}
+func fi(x ... interface{}) {}
+func (T) fm(x ...int)
+
+func g0() {}
+func g1() int { return 0}
+func g2() (u float32, s string) { return }
+func gs() []byte { return nil }
+
+func _calls() {
+	var x int
+	var y float32
+	var s []int
+
+	f0()
+	_ = f0 /* ERROR "used as value" */ ()
+	f0(g0 /* ERROR "too many arguments" */ )
+
+	f1(0)
+	f1(x)
+	f1(10.0)
+	f1() /* ERROR "not enough arguments" */
+	f1(x, y /* ERROR "too many arguments" */ )
+	f1(s /* ERROR "cannot use .* in argument" */ )
+	f1(x ... /* ERROR "cannot use ..." */ )
+	f1(g0 /* ERROR "used as value" */ ())
+	f1(g1())
+	f1(g2 /* ERROR "too many arguments" */ ())
+
+	f2() /* ERROR "not enough arguments" */
+	f2(3.14) /* ERROR "not enough arguments" */
+	f2(3.14, "foo")
+	f2(x /* ERROR "cannot use .* in argument" */ , "foo")
+	f2(g0 /* ERROR "used as value" */ ())
+	f2(g1()) /* ERROR "not enough arguments" */
+	f2(g2())
+
+	fs() /* ERROR "not enough arguments" */
+	fs(g0 /* ERROR "used as value" */ ())
+	fs(g1 /* ERROR "cannot use .* in argument" */ ())
+	fs(g2 /* ERROR "too many arguments" */ ())
+	fs(gs())
+
+	fv()
+	fv(1, 2.0, x)
+	fv(s /* ERROR "cannot use .* in argument" */ )
+	fv(s...)
+	fv(x /* ERROR "cannot use" */ ...)
+	fv(1, s /* ERROR "too many arguments" */ ...)
+	fv(gs /* ERROR "cannot use .* in argument" */ ())
+	fv(gs /* ERROR "cannot use .* in argument" */ ()...)
+
+	var t T
+	t.fm()
+	t.fm(1, 2.0, x)
+	t.fm(s /* ERROR "cannot use .* in argument" */ )
+	t.fm(g1())
+	t.fm(1, s /* ERROR "too many arguments" */ ...)
+	t.fm(gs /* ERROR "cannot use .* in argument" */ ())
+	t.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
+
+	T.fm(t, )
+	T.fm(t, 1, 2.0, x)
+	T.fm(t, s /* ERROR "cannot use .* in argument" */ )
+	T.fm(t, g1())
+	T.fm(t, 1, s /* ERROR "too many arguments" */ ...)
+	T.fm(t, gs /* ERROR "cannot use .* in argument" */ ())
+	T.fm(t, gs /* ERROR "cannot use .* in argument" */ ()...)
+
+	var i interface{ fm(x ...int) } = t
+	i.fm()
+	i.fm(1, 2.0, x)
+	i.fm(s /* ERROR "cannot use .* in argument" */ )
+	i.fm(g1())
+	i.fm(1, s /* ERROR "too many arguments" */ ...)
+	i.fm(gs /* ERROR "cannot use .* in argument" */ ())
+	i.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
+
+	fi()
+	fi(1, 2.0, x, 3.14, "foo")
+	fi(g2())
+	fi(0, g2)
+	fi(0, g2 /* ERROR "2-valued g2" */ ())
+}
+
+func issue6344() {
+	type T []interface{}
+	var x T
+	fi(x...) // ... applies also to named slices
+}
diff --git a/src/go/types/testdata/check/go1_12.src b/src/go/types/testdata/check/go1_12.src
new file mode 100644
index 0000000..1e529f1
--- /dev/null
+++ b/src/go/types/testdata/check/go1_12.src
@@ -0,0 +1,35 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check Go language version-specific errors.
+
+package go1_12 // go1.12
+
+// numeric literals
+const (
+	_ = 1_000 // ERROR "underscores in numeric literals requires go1.13 or later"
+	_ = 0b111 // ERROR "binary literals requires go1.13 or later"
+	_ = 0o567 // ERROR "0o/0O-style octal literals requires go1.13 or later"
+	_ = 0xabc // ok
+	_ = 0x0p1 // ERROR "hexadecimal floating-point literals requires go1.13 or later"
+
+	_ = 0B111 // ERROR "binary"
+	_ = 0O567 // ERROR "octal"
+	_ = 0Xabc // ok
+	_ = 0X0P1 // ERROR "hexadecimal floating-point"
+
+	_ = 1_000i // ERROR "underscores"
+	_ = 0b111i // ERROR "binary"
+	_ = 0o567i // ERROR "octal"
+	_ = 0xabci // ERROR "hexadecimal floating-point"
+	_ = 0x0p1i // ERROR "hexadecimal floating-point"
+)
+
+// signed shift counts
+var (
+	s int
+	_ = 1 << s // ERROR "invalid operation: signed shift count s \(variable of type int\) requires go1.13 or later"
+	_ = 1 >> s // ERROR "signed shift count"
+)
+
diff --git a/src/go/types/testdata/check/go1_13.src b/src/go/types/testdata/check/go1_13.src
new file mode 100644
index 0000000..6aa1364
--- /dev/null
+++ b/src/go/types/testdata/check/go1_13.src
@@ -0,0 +1,22 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check Go language version-specific errors.
+
+package go1_13 // go1.13
+
+// interface embedding
+
+type I interface { m() }
+
+type _ interface {
+	m()
+	I // ERROR "duplicate method m"
+}
+
+type _ interface {
+	I
+	I // ERROR "duplicate method m"
+}
+
diff --git a/src/go/types/testdata/check/go1_16.src b/src/go/types/testdata/check/go1_16.src
new file mode 100644
index 0000000..fdf5c99
--- /dev/null
+++ b/src/go/types/testdata/check/go1_16.src
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check Go language version-specific errors.
+
+package go1_16 // go1.16
+
+type Slice []byte
+type Array [8]byte
+
+var s Slice
+var p = (*Array)(s /* ERROR requires go1.17 or later */ )
diff --git a/src/go/types/testdata/check/go1_8.src b/src/go/types/testdata/check/go1_8.src
new file mode 100644
index 0000000..3ead1e9
--- /dev/null
+++ b/src/go/types/testdata/check/go1_8.src
@@ -0,0 +1,11 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check Go language version-specific errors.
+
+package go1_8 // go1.8
+
+// type alias declarations
+type any = /* ERROR type aliases requires go1.9 or later */ interface{}
+
diff --git a/src/go/types/testdata/gotos.src b/src/go/types/testdata/check/gotos.src
similarity index 100%
rename from src/go/types/testdata/gotos.src
rename to src/go/types/testdata/check/gotos.src
diff --git a/src/go/types/testdata/importC.src b/src/go/types/testdata/check/importC.src
similarity index 100%
rename from src/go/types/testdata/importC.src
rename to src/go/types/testdata/check/importC.src
diff --git a/src/go/types/testdata/check/importdecl0/importdecl0a.src b/src/go/types/testdata/check/importdecl0/importdecl0a.src
new file mode 100644
index 0000000..5ceb96e
--- /dev/null
+++ b/src/go/types/testdata/check/importdecl0/importdecl0a.src
@@ -0,0 +1,53 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package importdecl0
+
+import ()
+
+import (
+	// we can have multiple blank imports (was bug)
+	_ "math"
+	_ "net/rpc"
+	init /* ERROR "cannot import package as init" */ "fmt"
+	// reflect defines a type "flag" which shows up in the gc export data
+	"reflect"
+	. /* ERROR "imported but not used" */ "reflect"
+)
+
+import "math" /* ERROR "imported but not used" */
+import m /* ERROR "imported but not used as m" */ "math"
+import _ "math"
+
+import (
+	"math/big" /* ERROR "imported but not used" */
+	b /* ERROR "imported but not used" */ "math/big"
+	_ "math/big"
+)
+
+import "fmt"
+import f1 "fmt"
+import f2 "fmt"
+
+// reflect.flag must not be visible in this package
+type flag int
+type _ reflect.flag /* ERROR "not exported" */
+
+// imported package name may conflict with local objects
+type reflect /* ERROR "reflect already declared" */ int
+
+// dot-imported exported objects may conflict with local objects
+type Value /* ERROR "Value already declared through dot-import of package reflect" */ struct{}
+
+var _ = fmt.Println // use "fmt"
+
+func _() {
+	f1.Println() // use "fmt"
+}
+
+func _() {
+	_ = func() {
+		f2.Println() // use "fmt"
+	}
+}
diff --git a/src/go/types/testdata/check/importdecl0/importdecl0b.src b/src/go/types/testdata/check/importdecl0/importdecl0b.src
new file mode 100644
index 0000000..5569042
--- /dev/null
+++ b/src/go/types/testdata/check/importdecl0/importdecl0b.src
@@ -0,0 +1,33 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package importdecl0
+
+import "math"
+import m "math"
+
+import . "testing" // declares T in file scope
+import . /* ERROR .unsafe. imported but not used */ "unsafe"
+import . "fmt"     // declares Println in file scope
+
+import (
+	// TODO(gri) At the moment, 2 errors are reported because both go/parser
+	// and the type checker report it. Eventually, this test should not be
+	// done by the parser anymore.
+	"" /* ERROR invalid import path */ /* ERROR invalid import path */
+	"a!b" /* ERROR invalid import path */ /* ERROR invalid import path */
+	"abc\xffdef" /* ERROR invalid import path */ /* ERROR invalid import path */
+)
+
+// using "math" in this file doesn't affect its use in other files
+const Pi0 = math.Pi
+const Pi1 = m.Pi
+
+type _ T // use "testing"
+
+func _() func() interface{} {
+	return func() interface{} {
+		return Println // use "fmt"
+	}
+}
diff --git a/src/go/types/testdata/importdecl1a.src b/src/go/types/testdata/check/importdecl1/importdecl1a.src
similarity index 100%
rename from src/go/types/testdata/importdecl1a.src
rename to src/go/types/testdata/check/importdecl1/importdecl1a.src
diff --git a/src/go/types/testdata/check/importdecl1/importdecl1b.src b/src/go/types/testdata/check/importdecl1/importdecl1b.src
new file mode 100644
index 0000000..43a7bcd
--- /dev/null
+++ b/src/go/types/testdata/check/importdecl1/importdecl1b.src
@@ -0,0 +1,11 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package importdecl1
+
+import . /* ERROR .unsafe. imported but not used */ "unsafe"
+
+type B interface {
+	A
+}
diff --git a/src/go/types/testdata/init0.src b/src/go/types/testdata/check/init0.src
similarity index 100%
rename from src/go/types/testdata/init0.src
rename to src/go/types/testdata/check/init0.src
diff --git a/src/go/types/testdata/init1.src b/src/go/types/testdata/check/init1.src
similarity index 100%
rename from src/go/types/testdata/init1.src
rename to src/go/types/testdata/check/init1.src
diff --git a/src/go/types/testdata/init2.src b/src/go/types/testdata/check/init2.src
similarity index 100%
rename from src/go/types/testdata/init2.src
rename to src/go/types/testdata/check/init2.src
diff --git a/src/go/types/testdata/issue25008a.src b/src/go/types/testdata/check/issue25008/issue25008a.src
similarity index 100%
rename from src/go/types/testdata/issue25008a.src
rename to src/go/types/testdata/check/issue25008/issue25008a.src
diff --git a/src/go/types/testdata/issue25008b.src b/src/go/types/testdata/check/issue25008/issue25008b.src
similarity index 100%
rename from src/go/types/testdata/issue25008b.src
rename to src/go/types/testdata/check/issue25008/issue25008b.src
diff --git a/src/go/types/testdata/check/issues.go2 b/src/go/types/testdata/check/issues.go2
new file mode 100644
index 0000000..8994164
--- /dev/null
+++ b/src/go/types/testdata/check/issues.go2
@@ -0,0 +1,256 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains regression tests for bugs found.
+
+package p
+
+import "io"
+import "context"
+
+// Interfaces are always comparable (though the comparison may panic at runtime).
+func eql[T comparable](x, y T) bool {
+	return x == y
+}
+
+func _() {
+	var x interface{}
+	var y interface{ m() }
+	eql(x, y /* ERROR does not match */ ) // interfaces of different types
+	eql(x, x)
+	eql(y, y)
+	eql(y, nil)
+	eql[io.Reader](nil, nil)
+}
+
+// If we have a receiver of pointer type (below: *T) we must ignore
+// the pointer in the implementation of the method lookup because
+// the type bound of T is an interface and pointer to interface types
+// have no methods and then the lookup would fail.
+type C[T any] interface {
+    m()
+}
+
+// using type bound C
+func _[T C[T]](x *T) {
+	x.m()
+}
+
+// using an interface literal as bound
+func _[T interface{ m() }](x *T) {
+	x.m()
+}
+
+// In a generic function body all method calls will be pointer method calls.
+// If necessary, the function body will insert temporary variables, not seen
+// by the user, in order to get an addressable variable to use to call the method.
+// Thus, assume an argument type for a generic function to be the type of addressable
+// values in the generic function when checking if the argument type satisfies the
+// generic function's type bound.
+func f2[_ interface{ m1(); m2() }]()
+
+type T struct{}
+func (T) m1()
+func (*T) m2()
+
+func _() {
+	// TODO(rFindley) this error should be positioned on the 'T'.
+	f2 /* ERROR wrong method signature */ [T]()
+	f2[*T]()
+}
+
+// When a type parameter is used as an argument to instantiate a parameterized
+// type with a type list constraint, all of the type argument's types in its
+// bound, but at least one (!), must be in the type list of the bound of the
+// corresponding parameterized type's type parameter.
+type T1[P interface{type uint}] struct{}
+
+func _[P any]() {
+    _ = T1[P /* ERROR P has no type constraints */ ]{}
+}
+
+// This is the original (simplified) program causing the same issue.
+type Unsigned interface {
+	type uint
+}
+
+type T2[U Unsigned] struct {
+    s U
+}
+
+func (u T2[U]) Add1() U {
+    return u.s + 1
+}
+
+func NewT2[U any]() T2[U /* ERROR U has no type constraints */ ] {
+    return T2[U /* ERROR U has no type constraints */ ]{}
+}
+
+func _() {
+    u := NewT2[string]()
+    _ = u.Add1()
+}
+
+// When we encounter an instantiated type such as Elem[T] we must
+// not "expand" the instantiation when the type to be instantiated
+// (Elem in this case) is not yet fully set up.
+type Elem[T any] struct {
+	next *Elem[T]
+	list *List[T]
+}
+
+type List[T any] struct {
+	root Elem[T]
+}
+
+func (l *List[T]) Init() {
+	l.root.next = &l.root
+}
+
+// This is the original program causing the same issue.
+type Element2[TElem any] struct {
+	next, prev *Element2[TElem]
+	list *List2[TElem]
+	Value TElem
+}
+
+type List2[TElem any] struct {
+	root Element2[TElem]
+	len  int
+}
+
+func (l *List2[TElem]) Init() *List2[TElem] {
+	l.root.next = &l.root
+	l.root.prev = &l.root
+	l.len = 0
+	return l
+}
+
+// Self-recursive instantiations must work correctly.
+type A[P any] struct { _ *A[P] }
+
+type AB[P any] struct { _ *BA[P] }
+type BA[P any] struct { _ *AB[P] }
+
+// And a variation that also caused a problem with an
+// unresolved underlying type.
+type Element3[TElem any] struct {
+	next, prev *Element3[TElem]
+	list *List3[TElem]
+	Value TElem
+}
+
+func (e *Element3[TElem]) Next() *Element3[TElem] {
+	if p := e.next; e.list != nil && p != &e.list.root {
+		return p
+	}
+	return nil
+}
+
+type List3[TElem any] struct {
+	root Element3[TElem]
+	len  int
+}
+
+// Infinite generic type declarations must lead to an error.
+type inf1[T any] struct{ _ inf1 /* ERROR illegal cycle */ [T] }
+type inf2[T any] struct{ inf2 /* ERROR illegal cycle */ [T] }
+
+// The implementation of conversions T(x) between integers and floating-point
+// numbers checks that both T and x have either integer or floating-point
+// type. When the type of T or x is a type parameter, the respective simple
+// predicate disjunction in the implementation was wrong because if a type list
+// contains both an integer and a floating-point type, the type parameter is
+// neither an integer or a floating-point number.
+func convert[T1, T2 interface{type int, uint, float32}](v T1) T2 {
+	return T2(v)
+}
+
+func _() {
+	convert[int, uint](5)
+}
+
+// When testing binary operators, for +, the operand types must either be
+// both numeric, or both strings. The implementation had the same problem
+// with this check as the conversion issue above (issue #39623).
+
+func issue39623[T interface{type int, string}](x, y T) T {
+	return x + y
+}
+
+// Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI:
+func Sum[T interface{type int, string}](s []T) (sum T) {
+	for _, v := range s {
+		sum += v
+	}
+	return
+}
+
+// Assignability of an unnamed pointer type to a type parameter that
+// has a matching underlying type.
+func _[T interface{}, PT interface{type *T}] (x T) PT {
+    return &x
+}
+
+// Indexing of generic types containing type parameters in their type list:
+func at[T interface{ type []E }, E interface{}](x T, i int) E {
+        return x[i]
+}
+
+// A generic type inside a function acts like a named type. Its underlying
+// type is itself, its "operational type" is defined by the type list in
+// the tybe bound, if any.
+func _[T interface{type int}](x T) {
+	type myint int
+	var _ int = int(x)
+	var _ T = 42
+	var _ T = T(myint(42))
+}
+
+// Indexing a generic type with an array type bound checks length.
+// (Example by mdempsky@.)
+func _[T interface { type [10]int }](x T) {
+	_ = x[9] // ok
+	_ = x[20 /* ERROR out of bounds */ ]
+}
+
+// Pointer indirection of a generic type.
+func _[T interface{ type *int }](p T) int {
+	return *p
+}
+
+// Channel sends and receives on generic types.
+func _[T interface{ type chan int }](ch T) int {
+	ch <- 0
+	return <- ch
+}
+
+// Calling of a generic variable.
+func _[T interface{ type func() }](f T) {
+	f()
+	go f()
+}
+
+// We must compare against the underlying type of type list entries
+// when checking if a constraint is satisfied by a type. The under-
+// lying type of each type list entry must be computed after the
+// interface has been instantiated as its typelist may contain a
+// type parameter that was substituted with a defined type.
+// Test case from an (originally) failing example.
+
+type sliceOf[E any] interface{ type []E }
+
+func append[T interface{}, S sliceOf[T], T2 interface{ type T }](s S, t ...T2) S
+
+var f           func()
+var cancelSlice []context.CancelFunc
+var _ = append[context.CancelFunc, []context.CancelFunc, context.CancelFunc](cancelSlice, f)
+
+// A generic function must be instantiated with a type, not a value.
+
+func g[T any](T) T
+
+var _ = g[int]
+var _ = g[nil /* ERROR is not a type */ ]
+var _ = g(0)
diff --git a/src/go/types/testdata/check/issues.src b/src/go/types/testdata/check/issues.src
new file mode 100644
index 0000000..55fe220
--- /dev/null
+++ b/src/go/types/testdata/check/issues.src
@@ -0,0 +1,371 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issues
+
+import (
+	"fmt"
+	syn "regexp/syntax"
+	t1 "text/template"
+	t2 "html/template"
+)
+
+func issue7035() {
+	type T struct{ X int }
+	_ = func() {
+		fmt.Println() // must refer to imported fmt rather than the fmt below
+	}
+	fmt := new(T)
+	_ = fmt.X
+}
+
+func issue8066() {
+	const (
+		_ = float32(340282356779733661637539395458142568447)
+		_ = float32(340282356779733661637539395458142568448 /* ERROR cannot convert */ )
+	)
+}
+
+// Check that a missing identifier doesn't lead to a spurious error cascade.
+func issue8799a() {
+	x, ok := missing /* ERROR undeclared */ ()
+	_ = !ok
+	_ = x
+}
+
+func issue8799b(x int, ok bool) {
+	x, ok = missing /* ERROR undeclared */ ()
+	_ = !ok
+	_ = x
+}
+
+func issue9182() {
+	type Point C /* ERROR undeclared */ .Point
+	// no error for composite literal based on unknown type
+	_ = Point{x: 1, y: 2}
+}
+
+func f0() (a []int)         { return }
+func f1() (a []int, b int)  { return }
+func f2() (a, b []int)      { return }
+
+func append_([]int, ...int) {}
+
+func issue9473(a []int, b ...int) {
+	// variadic builtin function
+	_ = append(f0())
+	_ = append(f0(), f0()...)
+	_ = append(f1())
+	_ = append(f2 /* ERROR cannot use .* in argument */ ())
+	_ = append(f2()... /* ERROR cannot use ... */ )
+	_ = append(f0(), f1 /* ERROR 2-valued f1 */ ())
+	_ = append(f0(), f2 /* ERROR 2-valued f2 */ ())
+	_ = append(f0(), f1 /* ERROR 2-valued f1 */ ()...)
+	_ = append(f0(), f2 /* ERROR 2-valued f2 */ ()...)
+
+	// variadic user-defined function
+	append_(f0())
+	append_(f0(), f0()...)
+	append_(f1())
+	append_(f2 /* ERROR cannot use .* in argument */ ())
+	append_(f2()... /* ERROR cannot use ... */ )
+	append_(f0(), f1 /* ERROR 2-valued f1 */ ())
+	append_(f0(), f2 /* ERROR 2-valued f2 */ ())
+	append_(f0(), f1 /* ERROR 2-valued f1 */ ()...)
+	append_(f0(), f2 /* ERROR 2-valued f2 */ ()...)
+}
+
+// Check that embedding a non-interface type in an interface results in a good error message.
+func issue10979() {
+	type _ interface {
+		int /* ERROR int is not an interface */
+	}
+	type T struct{}
+	type _ interface {
+		T /* ERROR T is not an interface */
+	}
+	type _ interface {
+		nosuchtype /* ERROR undeclared name: nosuchtype */
+	}
+	type _ interface {
+		fmt.Nosuchtype /* ERROR Nosuchtype not declared by package fmt */
+	}
+	type _ interface {
+		nosuchpkg /* ERROR undeclared name: nosuchpkg */ .Nosuchtype
+	}
+	type I interface {
+		I.m /* ERROR no field or method m */
+		m()
+	}
+}
+
+// issue11347
+// These should not crash.
+var a1, b1 /* ERROR cycle */ , c1 /* ERROR cycle */ b1 = 0 > 0<<""[""[c1]]>c1
+var a2, b2 /* ERROR cycle */ = 0 /* ERROR cannot initialize */ /* ERROR cannot initialize */ > 0<<""[b2]
+var a3, b3 /* ERROR cycle */ = int /* ERROR cannot initialize */ /* ERROR cannot initialize */ (1<<""[b3])
+
+// issue10260
+// Check that error messages explain reason for interface assignment failures.
+type (
+	I0 interface{}
+	I1 interface{ foo() }
+	I2 interface{ foo(x int) }
+	T0 struct{}
+	T1 struct{}
+	T2 struct{}
+)
+
+func (*T1) foo() {}
+func (*T2) foo(x int) {}
+
+func issue10260() {
+	var (
+		i0 I0
+		i1 I1
+		i2 I2
+		t0 *T0
+		t1 *T1
+		t2 *T2
+	)
+
+	var x I1
+	x = T1 /* ERROR cannot use .*: missing method foo \(foo has pointer receiver\) */ {}
+	_ = x /* ERROR .* cannot have dynamic type T1 \(missing method foo \(foo has pointer receiver\)\) */ .(T1)
+
+	T1{}.foo /* ERROR cannot call pointer method foo on T1 */ ()
+	x.Foo /* ERROR "x.Foo undefined \(type I1 has no field or method Foo, but does have foo\)" */ ()
+
+	_ = i2 /* ERROR i2 .* cannot have dynamic type \*T1 \(wrong type for method foo \(have func\(\), want func\(x int\)\)\) */ .(*T1)
+
+	i1 = i0 /* ERROR cannot use .* missing method foo */
+	i1 = t0 /* ERROR cannot use .* missing method foo */
+	i1 = i2 /* ERROR cannot use .* wrong type for method foo */
+	i1 = t2 /* ERROR cannot use .* wrong type for method foo */
+	i2 = i1 /* ERROR cannot use .* wrong type for method foo */
+	i2 = t1 /* ERROR cannot use .* wrong type for method foo */
+
+	_ = func() I1 { return i0 /* ERROR cannot use .* missing method foo */ }
+	_ = func() I1 { return t0 /* ERROR cannot use .* missing method foo */ }
+	_ = func() I1 { return i2 /* ERROR cannot use .* wrong type for method foo */ }
+	_ = func() I1 { return t2 /* ERROR cannot use .* wrong type for method foo */ }
+	_ = func() I2 { return i1 /* ERROR cannot use .* wrong type for method foo */ }
+	_ = func() I2 { return t1 /* ERROR cannot use .* wrong type for method foo */ }
+
+	// a few more - less exhaustive now
+
+	f := func(I1, I2){}
+	f(i0 /* ERROR cannot use .* missing method foo */ , i1 /* ERROR cannot use .* wrong type for method foo \(have func\(\), want func\(x int\)\) */ )
+
+	_ = [...]I1{i0 /* ERROR cannot use .* missing method foo */ }
+	_ = [...]I1{i2 /* ERROR cannot use .* wrong type for method foo */ }
+	_ = []I1{i0 /* ERROR cannot use .* missing method foo */ }
+	_ = []I1{i2 /* ERROR cannot use .* wrong type for method foo */ }
+	_ = map[int]I1{0: i0 /* ERROR cannot use .* missing method foo */ }
+	_ = map[int]I1{0: i2 /* ERROR cannot use .* wrong type for method foo */ }
+
+	make(chan I1) <- i0 /* ERROR cannot use .* in send: missing method foo */
+	make(chan I1) <- i2 /* ERROR cannot use .* in send: wrong type for method foo */
+}
+
+// Check that constants representable as integers are in integer form
+// before being used in operations that are only defined on integers.
+func issue14229() {
+	// from the issue
+	const _ = int64(-1<<63) % 1e6
+
+	// related
+	const (
+		a int = 3
+		b = 4.0
+		_ = a / b
+		_ = a % b
+		_ = b / a
+		_ = b % a
+	)
+}
+
+// Check that in a n:1 variable declaration with type and initialization
+// expression the type is distributed to all variables of the lhs before
+// the initialization expression assignment is checked.
+func issue15755() {
+	// from issue
+	var i interface{}
+	type b bool
+	var x, y b = i.(b)
+	_ = x == y
+
+	// related: we should see an error since the result of f1 is ([]int, int)
+	var u, v []int = f1 /* ERROR cannot use f1 */ ()
+	_ = u
+	_ = v
+}
+
+// Test that we don't get "declared but not used"
+// errors in the context of invalid/C objects.
+func issue20358() {
+	var F C /* ERROR "undeclared" */ .F
+	var A C /* ERROR "undeclared" */ .A
+	var S C /* ERROR "undeclared" */ .S
+	type T C /* ERROR "undeclared" */ .T
+	type P C /* ERROR "undeclared" */ .P
+
+	// these variables must be "used" even though
+	// the LHS expressions/types below in which
+	// context they are used are unknown/invalid
+	var f, a, s1, s2, s3, t, p int
+
+	_ = F(f)
+	_ = A[a]
+	_ = S[s1:s2:s3]
+	_ = T{t}
+	_ = P{f: p}
+}
+
+// Test that we don't declare lhs variables in short variable
+// declarations before we type-check function literals on the
+// rhs.
+func issue24026() {
+	f := func() int { f(0) /* must refer to outer f */; return 0 }
+	_ = f
+
+	_ = func() {
+		f := func() { _ = f() /* must refer to outer f */ }
+		_ = f
+	}
+
+	// b and c must not be visible inside function literal
+	a := 0
+	a, b, c := func() (int, int, int) {
+		return a, b /* ERROR undeclared */ , c /* ERROR undeclared */
+	}()
+	_, _ = b, c
+}
+
+func f(int) {} // for issue24026
+
+// Test that we don't report a "missing return statement" error
+// (due to incorrect context when type-checking interfaces).
+func issue24140(x interface{}) int {
+        switch x.(type) {
+        case interface{}:
+                return 0
+        default:
+                panic(0)
+        }
+}
+
+// Test that we don't crash when the 'if' condition is missing.
+func issue25438() {
+	if { /* ERROR missing condition */ }
+	if x := 0; /* ERROR missing condition */ { _ = x }
+	if
+	{ /* ERROR missing condition */ }
+}
+
+// Test that we can embed alias type names in interfaces.
+type issue25301 interface {
+	E
+}
+
+type E = interface {
+	m()
+}
+
+// Test case from issue.
+// cmd/compile reports a cycle as well.
+type issue25301b /* ERROR cycle */ = interface {
+	m() interface{ issue25301b }
+}
+
+type issue25301c interface {
+	notE // ERROR struct\{\} is not an interface
+}
+
+type notE = struct{}
+
+// Test that method declarations don't introduce artificial cycles
+// (issue #26124).
+const CC TT = 1
+type TT int
+func (TT) MM() [CC]TT
+
+// Reduced test case from issue #26124.
+const preloadLimit LNumber = 128
+type LNumber float64
+func (LNumber) assertFunction() *LFunction
+type LFunction struct {
+	GFunction LGFunction
+}
+type LGFunction func(*LState)
+type LState struct {
+	reg *registry
+}
+type registry struct {
+	alloc *allocator
+}
+type allocator struct {
+	_ [int(preloadLimit)]int
+}
+
+// Test that we don't crash when type-checking composite literals
+// containing errors in the type.
+var issue27346 = [][n /* ERROR undeclared */ ]int{
+	0: {},
+}
+
+var issue22467 = map[int][... /* ERROR invalid use of ... */ ]int{0: {}}
+
+// Test that invalid use of ... in parameter lists is recognized
+// (issue #28281).
+func issue28281a(int, int, ...int)
+func issue28281b(a, b int, c ...int)
+func issue28281c(a, b, c ... /* ERROR can only use ... with final parameter */ int)
+func issue28281d(... /* ERROR can only use ... with final parameter */ int, int)
+func issue28281e(a, b, c  ... /* ERROR can only use ... with final parameter */ int, d int)
+func issue28281f(... /* ERROR can only use ... with final parameter */ int, ... /* ERROR can only use ... with final parameter */ int, int)
+func (... /* ERROR can only use ... with final parameter */ TT) f()
+func issue28281g() (... /* ERROR can only use ... with final parameter */ TT)
+
+// Issue #26234: Make various field/method lookup errors easier to read by matching cmd/compile's output
+func issue26234a(f *syn.Prog) {
+	// The error message below should refer to the actual package name (syntax)
+	// not the local package name (syn).
+	f.foo /* ERROR f\.foo undefined \(type \*syntax\.Prog has no field or method foo\) */
+}
+
+type T struct {
+	x int
+	E1
+	E2
+}
+
+type E1 struct{ f int }
+type E2 struct{ f int }
+
+func issue26234b(x T) {
+	_ = x.f /* ERROR ambiguous selector x.f */
+}
+
+func issue26234c() {
+	T.x /* ERROR T.x undefined \(type T has no method x\) */ ()
+}
+
+func issue35895() {
+	// T is defined in this package, don't qualify its name with the package name.
+	var _ T = 0 // ERROR cannot use 0 \(untyped int constant\) as T
+
+	// There is only one package with name syntax imported, only use the (global) package name in error messages.
+	var _ *syn.Prog = 0 // ERROR cannot use 0 \(untyped int constant\) as \*syntax.Prog
+
+	// Because both t1 and t2 have the same global package name (template),
+	// qualify packages with full path name in this case.
+	var _ t1.Template = t2 /* ERROR cannot use .* \(value of type .html/template.\.Template\) as .text/template.\.Template */ .Template{}
+}
+
+func issue42989(s uint) {
+	var m map[int]string
+	delete(m, 1<<s)
+	delete(m, 1.<<s)
+}
diff --git a/src/go/types/testdata/labels.src b/src/go/types/testdata/check/labels.src
similarity index 100%
rename from src/go/types/testdata/labels.src
rename to src/go/types/testdata/check/labels.src
diff --git a/src/go/types/testdata/check/linalg.go2 b/src/go/types/testdata/check/linalg.go2
new file mode 100644
index 0000000..0d27603
--- /dev/null
+++ b/src/go/types/testdata/check/linalg.go2
@@ -0,0 +1,83 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package linalg
+
+import "math"
+
+// Numeric is type bound that matches any numeric type.
+// It would likely be in a constraints package in the standard library.
+type Numeric interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64,
+		complex64, complex128
+}
+
+func DotProduct[T Numeric](s1, s2 []T) T {
+	if len(s1) != len(s2) {
+		panic("DotProduct: slices of unequal length")
+	}
+	var r T
+	for i := range s1 {
+		r += s1[i] * s2[i]
+	}
+	return r
+}
+
+// NumericAbs matches numeric types with an Abs method.
+type NumericAbs[T any] interface {
+	Numeric
+
+	Abs() T
+}
+
+// AbsDifference computes the absolute value of the difference of
+// a and b, where the absolute value is determined by the Abs method.
+func AbsDifference[T NumericAbs[T]](a, b T) T {
+	d := a - b
+	return d.Abs()
+}
+
+// OrderedNumeric is a type bound that matches numeric types that support the < operator.
+type OrderedNumeric interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64
+}
+
+// Complex is a type bound that matches the two complex types, which do not have a < operator.
+type Complex interface {
+	type complex64, complex128
+}
+
+// OrderedAbs is a helper type that defines an Abs method for
+// ordered numeric types.
+type OrderedAbs[T OrderedNumeric] T
+
+func (a OrderedAbs[T]) Abs() OrderedAbs[T] {
+	if a < 0 {
+		return -a
+	}
+	return a
+}
+
+// ComplexAbs is a helper type that defines an Abs method for
+// complex types.
+type ComplexAbs[T Complex] T
+
+func (a ComplexAbs[T]) Abs() ComplexAbs[T] {
+	r := float64(real(a))
+	i := float64(imag(a))
+	d := math.Sqrt(r * r + i * i)
+	return ComplexAbs[T](complex(d, 0))
+}
+
+func OrderedAbsDifference[T OrderedNumeric](a, b T) T {
+	return T(AbsDifference(OrderedAbs[T](a), OrderedAbs[T](b)))
+}
+
+func ComplexAbsDifference[T Complex](a, b T) T {
+	return T(AbsDifference(ComplexAbs[T](a), ComplexAbs[T](b)))
+}
diff --git a/src/go/types/testdata/literals.src b/src/go/types/testdata/check/literals.src
similarity index 100%
rename from src/go/types/testdata/literals.src
rename to src/go/types/testdata/check/literals.src
diff --git a/src/go/types/testdata/check/main.go2 b/src/go/types/testdata/check/main.go2
new file mode 100644
index 0000000..65e9aa2
--- /dev/null
+++ b/src/go/types/testdata/check/main.go2
@@ -0,0 +1,7 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main[ /* ERROR "func main must have no type parameters" */ T any]() {}
diff --git a/src/go/types/testdata/check/main.src b/src/go/types/testdata/check/main.src
new file mode 100644
index 0000000..f892938
--- /dev/null
+++ b/src/go/types/testdata/check/main.src
@@ -0,0 +1,9 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main()
+func /* ERROR "no arguments and no return values" */ main /* ERROR redeclared */ (int)
+func /* ERROR "no arguments and no return values" */ main /* ERROR redeclared */ () int
diff --git a/src/go/types/testdata/check/map.go2 b/src/go/types/testdata/check/map.go2
new file mode 100644
index 0000000..814d953
--- /dev/null
+++ b/src/go/types/testdata/check/map.go2
@@ -0,0 +1,113 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package orderedmap provides an ordered map, implemented as a binary tree.
+package orderedmap
+
+// TODO(gri) fix imports for tests
+import "chans" // ERROR could not import
+
+// Map is an ordered map.
+type Map[K, V any] struct {
+	root    *node[K, V]
+	compare func(K, K) int
+}
+
+// node is the type of a node in the binary tree.
+type node[K, V any] struct {
+	key         K
+	val         V
+	left, right *node[K, V]
+}
+
+// New returns a new map.
+func New[K, V any](compare func(K, K) int) *Map[K, V] {
+        return &Map[K, V]{compare: compare}
+}
+
+// find looks up key in the map, and returns either a pointer
+// to the node holding key, or a pointer to the location where
+// such a node would go.
+func (m *Map[K, V]) find(key K) **node[K, V] {
+	pn := &m.root
+	for *pn != nil {
+		switch cmp := m.compare(key, (*pn).key); {
+		case cmp < 0:
+			pn = &(*pn).left
+		case cmp > 0:
+			pn = &(*pn).right
+		default:
+			return pn
+		}
+	}
+	return pn
+}
+
+// Insert inserts a new key/value into the map.
+// If the key is already present, the value is replaced.
+// Returns true if this is a new key, false if already present.
+func (m *Map[K, V]) Insert(key K, val V) bool {
+	pn := m.find(key)
+	if *pn != nil {
+		(*pn).val = val
+		return false
+	}
+        *pn = &node[K, V]{key: key, val: val}
+	return true
+}
+
+// Find returns the value associated with a key, or zero if not present.
+// The found result reports whether the key was found.
+func (m *Map[K, V]) Find(key K) (V, bool) {
+	pn := m.find(key)
+	if *pn == nil {
+		var zero V // see the discussion of zero values, above
+		return zero, false
+	}
+	return (*pn).val, true
+}
+
+// keyValue is a pair of key and value used when iterating.
+type keyValue[K, V any] struct {
+	key K
+	val V
+}
+
+// InOrder returns an iterator that does an in-order traversal of the map.
+func (m *Map[K, V]) InOrder() *Iterator[K, V] {
+	sender, receiver := chans.Ranger[keyValue[K, V]]()
+	var f func(*node[K, V]) bool
+	f = func(n *node[K, V]) bool {
+		if n == nil {
+			return true
+		}
+		// Stop sending values if sender.Send returns false,
+		// meaning that nothing is listening at the receiver end.
+		return f(n.left) &&
+                        sender.Send(keyValue[K, V]{n.key, n.val}) &&
+			f(n.right)
+	}
+	go func() {
+		f(m.root)
+		sender.Close()
+	}()
+	return &Iterator[K, V]{receiver}
+}
+
+// Iterator is used to iterate over the map.
+type Iterator[K, V any] struct {
+	r *chans.Receiver[keyValue[K, V]]
+}
+
+// Next returns the next key and value pair, and a boolean indicating
+// whether they are valid or whether we have reached the end.
+func (it *Iterator[K, V]) Next() (K, V, bool) {
+	keyval, ok := it.r.Next()
+	if !ok {
+		var zerok K
+		var zerov V
+		return zerok, zerov, false
+	}
+	return keyval.key, keyval.val, true
+}
diff --git a/src/go/types/testdata/check/map2.go2 b/src/go/types/testdata/check/map2.go2
new file mode 100644
index 0000000..2833445
--- /dev/null
+++ b/src/go/types/testdata/check/map2.go2
@@ -0,0 +1,146 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is like map.go2, but instead if importing chans, it contains
+// the necessary functionality at the end of the file.
+
+// Package orderedmap provides an ordered map, implemented as a binary tree.
+package orderedmap
+
+// Map is an ordered map.
+type Map[K, V any] struct {
+	root    *node[K, V]
+	compare func(K, K) int
+}
+
+// node is the type of a node in the binary tree.
+type node[K, V any] struct {
+	key         K
+	val         V
+	left, right *node[K, V]
+}
+
+// New returns a new map.
+func New[K, V any](compare func(K, K) int) *Map[K, V] {
+        return &Map[K, V]{compare: compare}
+}
+
+// find looks up key in the map, and returns either a pointer
+// to the node holding key, or a pointer to the location where
+// such a node would go.
+func (m *Map[K, V]) find(key K) **node[K, V] {
+	pn := &m.root
+	for *pn != nil {
+		switch cmp := m.compare(key, (*pn).key); {
+		case cmp < 0:
+			pn = &(*pn).left
+		case cmp > 0:
+			pn = &(*pn).right
+		default:
+			return pn
+		}
+	}
+	return pn
+}
+
+// Insert inserts a new key/value into the map.
+// If the key is already present, the value is replaced.
+// Returns true if this is a new key, false if already present.
+func (m *Map[K, V]) Insert(key K, val V) bool {
+	pn := m.find(key)
+	if *pn != nil {
+		(*pn).val = val
+		return false
+	}
+	*pn = &node[K, V]{key: key, val: val}
+	return true
+}
+
+// Find returns the value associated with a key, or zero if not present.
+// The found result reports whether the key was found.
+func (m *Map[K, V]) Find(key K) (V, bool) {
+	pn := m.find(key)
+	if *pn == nil {
+		var zero V // see the discussion of zero values, above
+		return zero, false
+	}
+	return (*pn).val, true
+}
+
+// keyValue is a pair of key and value used when iterating.
+type keyValue[K, V any] struct {
+	key K
+	val V
+}
+
+// InOrder returns an iterator that does an in-order traversal of the map.
+func (m *Map[K, V]) InOrder() *Iterator[K, V] {
+	sender, receiver := chans_Ranger[keyValue[K, V]]()
+	var f func(*node[K, V]) bool
+	f = func(n *node[K, V]) bool {
+		if n == nil {
+			return true
+		}
+		// Stop sending values if sender.Send returns false,
+		// meaning that nothing is listening at the receiver end.
+		return f(n.left) &&
+                        sender.Send(keyValue[K, V]{n.key, n.val}) &&
+			f(n.right)
+	}
+	go func() {
+		f(m.root)
+		sender.Close()
+	}()
+	return &Iterator[K, V]{receiver}
+}
+
+// Iterator is used to iterate over the map.
+type Iterator[K, V any] struct {
+	r *chans_Receiver[keyValue[K, V]]
+}
+
+// Next returns the next key and value pair, and a boolean indicating
+// whether they are valid or whether we have reached the end.
+func (it *Iterator[K, V]) Next() (K, V, bool) {
+	keyval, ok := it.r.Next()
+	if !ok {
+		var zerok K
+		var zerov V
+		return zerok, zerov, false
+	}
+	return keyval.key, keyval.val, true
+}
+
+// chans
+
+func chans_Ranger[T any]() (*chans_Sender[T], *chans_Receiver[T])
+
+// A sender is used to send values to a Receiver.
+type chans_Sender[T any] struct {
+	values chan<- T
+	done <-chan bool
+}
+
+func (s *chans_Sender[T]) Send(v T) bool {
+	select {
+	case s.values <- v:
+		return true
+	case <-s.done:
+		return false
+	}
+}
+
+func (s *chans_Sender[T]) Close() {
+	close(s.values)
+}
+
+type chans_Receiver[T any] struct {
+	values <-chan T
+	done chan<- bool
+}
+
+func (r *chans_Receiver[T]) Next() (T, bool) {
+	v, ok := <-r.values
+	return v, ok
+}
\ No newline at end of file
diff --git a/src/go/types/testdata/methodsets.src b/src/go/types/testdata/check/methodsets.src
similarity index 100%
rename from src/go/types/testdata/methodsets.src
rename to src/go/types/testdata/check/methodsets.src
diff --git a/src/go/types/testdata/check/shifts.src b/src/go/types/testdata/check/shifts.src
new file mode 100644
index 0000000..4d3c59a
--- /dev/null
+++ b/src/go/types/testdata/check/shifts.src
@@ -0,0 +1,397 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package shifts
+
+func shifts0() {
+	// basic constant shifts
+	const (
+		s = 10
+		_ = 0<<0
+		_ = 1<<s
+		_ = 1<<- /* ERROR "negative shift count" */ 1
+		// For the test below we may decide to convert to int
+		// rather than uint and then report a negative shift
+		// count instead, which might be a better error. The
+		// (minor) difference is that this would restrict the
+		// shift count range by half (from all uint values to
+		// the positive int values).
+		// This depends on the exact spec wording which is not
+		// done yet.
+		// TODO(gri) revisit and adjust when spec change is done
+		_ = 1<<- /* ERROR "negative shift count" */ 1.0
+		_ = 1<<1075 /* ERROR "invalid shift" */
+		_ = 2.0<<1
+		_ = 1<<1.0
+		_ = 1<<(1+0i)
+
+		_ int = 2<<s
+		_ float32 = 2<<s
+		_ complex64 = 2<<s
+
+		_ int = 2.0<<s
+		_ float32 = 2.0<<s
+		_ complex64 = 2.0<<s
+
+		_ int = 'a'<<s
+		_ float32 = 'a'<<s
+		_ complex64 = 'a'<<s
+	)
+}
+
+func shifts1() {
+	// basic non-constant shifts
+	var (
+		i int
+		u uint
+
+		_ = 1<<0
+		_ = 1<<i
+		_ = 1<<u
+		_ = 1<<"foo" /* ERROR "cannot convert" */
+		_ = i<<0
+		_ = i<<- /* ERROR "negative shift count" */ 1
+		_ = i<<1.0
+		_ = 1<<(1+0i)
+		_ = 1 /* ERROR "overflows" */ <<100
+
+		_ uint = 1 << 0
+		_ uint = 1 << u
+		_ float32 = 1 /* ERROR "must be integer" */ << u
+
+		// issue #14822
+		_ = 1<<( /* ERROR "overflows uint" */ 1<<64)
+		_ = 1<<( /* ERROR "invalid shift count" */ 1<<64-1)
+
+		// issue #43697
+		_ = u<<( /* ERROR "overflows uint" */ 1<<64)
+		_ = u<<(1<<64-1)
+	)
+}
+
+func shifts2() {
+	// from the spec
+	var (
+		s uint = 33
+		i = 1<<s           // 1 has type int
+		j int32 = 1<<s     // 1 has type int32; j == 0
+		k = uint64(1<<s)   // 1 has type uint64; k == 1<<33
+		m int = 1.0<<s     // 1.0 has type int
+		n = 1.0<<s != i    // 1.0 has type int; n == false if ints are 32bits in size
+		o = 1<<s == 2<<s   // 1 and 2 have type int; o == true if ints are 32bits in size
+		p = 1<<s == 1<<33  // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int
+		u = 1.0 /* ERROR "must be integer" */ <<s         // illegal: 1.0 has type float64, cannot shift
+		u1 = 1.0 /* ERROR "must be integer" */ <<s != 0   // illegal: 1.0 has type float64, cannot shift
+		u2 = 1 /* ERROR "must be integer" */ <<s != 1.0   // illegal: 1 has type float64, cannot shift
+		v float32 = 1 /* ERROR "must be integer" */ <<s   // illegal: 1 has type float32, cannot shift
+		w int64 = 1.0<<33  // 1.0<<33 is a constant shift expression
+	)
+	_, _, _, _, _, _, _, _, _, _, _, _ = i, j, k, m, n, o, p, u, u1, u2, v, w
+}
+
+func shifts3(a int16, b float32) {
+	// random tests
+	var (
+		s uint = 11
+		u = 1 /* ERROR "must be integer" */ <<s + 1.0
+		v complex128 = 1 /* ERROR "must be integer" */ << s + 1.0 /* ERROR "must be integer" */ << s + 1
+	)
+	x := 1.0 /* ERROR "must be integer" */ <<s + 1
+	shifts3(1.0 << s, 1 /* ERROR "must be integer" */ >> s)
+	_, _, _ = u, v, x
+}
+
+func shifts4() {
+	// shifts in comparisons w/ untyped operands
+	var s uint
+
+	_ = 1<<s == 1
+	_ = 1 /* ERROR "integer" */ <<s == 1.
+	_ = 1. /* ERROR "integer" */ <<s == 1
+	_ = 1. /* ERROR "integer" */ <<s == 1.
+
+	_ = 1<<s + 1 == 1
+	_ = 1 /* ERROR "integer" */ <<s + 1 == 1.
+	_ = 1 /* ERROR "integer" */ <<s + 1. == 1
+	_ = 1 /* ERROR "integer" */ <<s + 1. == 1.
+	_ = 1. /* ERROR "integer" */ <<s + 1 == 1
+	_ = 1. /* ERROR "integer" */ <<s + 1 == 1.
+	_ = 1. /* ERROR "integer" */ <<s + 1. == 1
+	_ = 1. /* ERROR "integer" */ <<s + 1. == 1.
+
+	_ = 1<<s == 1<<s
+	_ = 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s
+
+	_ = 1<<s + 1<<s == 1
+	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1.
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1.
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1.
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1.
+
+	_ = 1<<s + 1<<s == 1<<s + 1<<s
+	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+}
+
+func shifts5() {
+	// shifts in comparisons w/ typed operands
+	var s uint
+	var x int
+
+	_ = 1<<s == x
+	_ = 1.<<s == x
+	_ = 1.1 /* ERROR "int" */ <<s == x
+
+	_ = 1<<s + x == 1
+	_ = 1<<s + x == 1.
+	_ = 1<<s + x == 1.1 /* ERROR "int" */
+	_ = 1.<<s + x == 1
+	_ = 1.<<s + x == 1.
+	_ = 1.<<s + x == 1.1 /* ERROR "int" */
+	_ = 1.1 /* ERROR "int" */ <<s + x == 1
+	_ = 1.1 /* ERROR "int" */ <<s + x == 1.
+	_ = 1.1 /* ERROR "int" */ <<s + x == 1.1
+
+	_ = 1<<s == x<<s
+	_ = 1.<<s == x<<s
+	_ = 1.1  /* ERROR "int" */ <<s == x<<s
+}
+
+func shifts6() {
+	// shifts as operands in non-arithmetic operations and as arguments
+	var a [10]int
+	var s uint
+
+	_ = a[1<<s]
+	_ = a[1.0]
+	_ = a[1.0<<s]
+
+	_ = make([]int, 1.0)
+	_ = make([]int, 1.0<<s)
+	_ = make([]int, 1.1 /* ERROR "must be integer" */ <<s)
+
+	_ = float32(1)
+	_ = float32(1 /* ERROR "must be integer" */ <<s)
+	_ = float32(1.0)
+	_ = float32(1.0 /* ERROR "must be integer" */ <<s)
+	_ = float32(1.1 /* ERROR "must be integer" */ <<s)
+
+	_ = int32(0x80000000 /* ERROR "overflows int32" */ << s)
+	// TODO(rfindley) Eliminate the redundant error here.
+	_ = int32(( /* ERROR "truncated to int32" */ 0x80000000 /* ERROR "truncated to int32" */ + 0i) << s)
+
+	_ = int(1+0i<<0)
+	_ = int((1+0i)<<s)
+	_ = int(1.0<<s)
+	_ = int(complex(1, 0)<<s)
+	_ = int(float32/* ERROR "must be integer" */(1.0) <<s)
+	_ = int(1.1 /* ERROR must be integer */ <<s)
+	_ = int(( /* ERROR "must be integer" */ 1+1i)  <<s)
+
+	_ = complex(1 /* ERROR "must be integer" */ <<s, 0)
+
+	var b []int
+	_ = append(b, 1<<s)
+	_ = append(b, 1.0<<s)
+	_ = append(b, (1+0i)<<s)
+	_ = append(b, 1.1 /* ERROR "must be integer" */ <<s)
+	_ = append(b, (1 + 0i) <<s)
+	_ = append(b, ( /* ERROR "must be integer" */ 1 + 1i)  <<s)
+
+	_ = complex(1.0 /* ERROR "must be integer" */ <<s, 0)
+	_ = complex(1.1 /* ERROR "must be integer" */ <<s, 0)
+	_ = complex(0, 1.0 /* ERROR "must be integer" */ <<s)
+	_ = complex(0, 1.1 /* ERROR "must be integer" */ <<s)
+
+	// TODO(gri) The delete below is not type-checked correctly yet.
+	// var m1 map[int]string
+	// delete(m1, 1<<s)
+}
+
+func shifts7() {
+	// shifts of shifts
+	var s uint
+	var x int
+	_ = x
+
+	_ = 1<<(1<<s)
+	_ = 1<<(1.<<s)
+	_ = 1. /* ERROR "integer" */ <<(1<<s)
+	_ = 1. /* ERROR "integer" */ <<(1.<<s)
+
+	x = 1<<(1<<s)
+	x = 1<<(1.<<s)
+	x = 1.<<(1<<s)
+	x = 1.<<(1.<<s)
+
+	_ = (1<<s)<<(1<<s)
+	_ = (1<<s)<<(1.<<s)
+	_ = ( /* ERROR "integer" */ 1.<<s)<<(1<<s)
+	_ = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s)
+
+	x = (1<<s)<<(1<<s)
+	x = (1<<s)<<(1.<<s)
+	x = ( /* ERROR "integer" */ 1.<<s)<<(1<<s)
+	x = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s)
+}
+
+func shifts8() {
+	// shift examples from shift discussion: better error messages
+	var s uint
+	_ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1
+	_ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1.0
+	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s == 1.0
+	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.0 == 1
+	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.1 == 1
+	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1 == 1.0
+
+	// additional cases
+	_ = complex(1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s, 1)
+	_ = complex(1.0, 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s)
+
+	_ = int(1.<<s)
+	_ = int(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
+	_ = float32(1 /* ERROR "shifted operand .* must be integer" */ <<s)
+	_ = float32(1. /* ERROR "shifted operand .* must be integer" */ <<s)
+	_ = float32(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
+	// TODO(gri) the error messages for these two are incorrect - disabled for now
+	// _ = complex64(1<<s)
+	// _ = complex64(1.<<s)
+	_ = complex64(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
+}
+
+func shifts9() {
+	// various originally failing snippets of code from the std library
+	// from src/compress/lzw/reader.go:90
+	{
+		var d struct {
+			bits     uint32
+			width    uint
+		}
+		_ = uint16(d.bits & (1<<d.width - 1))
+	}
+
+	// from src/debug/dwarf/buf.go:116
+	{
+		var ux uint64
+		var bits uint
+		x := int64(ux)
+		if x&(1<<(bits-1)) != 0 {}
+	}
+
+	// from src/encoding/asn1/asn1.go:160
+	{
+		var bytes []byte
+		if bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {}
+	}
+
+	// from src/math/big/rat.go:140
+	{
+		var exp int
+		var mantissa uint64
+		shift := uint64(-1022 - (exp - 1)) // [1..53)
+		_ = mantissa & (1<<shift - 1)
+	}
+
+	// from src/net/interface.go:51
+	{
+		type Flags uint
+		var f Flags
+		var i int
+		if f&(1<<uint(i)) != 0 {}
+	}
+
+	// from src/runtime/softfloat64.go:234
+	{
+		var gm uint64
+		var shift uint
+		_ = gm & (1<<shift - 1)
+	}
+
+	// from src/strconv/atof.go:326
+	{
+		var mant uint64
+		var mantbits uint
+		if mant == 2<<mantbits {}
+	}
+
+	// from src/route_bsd.go:82
+	{
+		var Addrs int32
+		const rtaRtMask = 1
+		var i uint
+		if Addrs&rtaRtMask&(1<<i) == 0 {}
+	}
+
+	// from src/text/scanner/scanner.go:540
+	{
+		var s struct { Whitespace uint64 }
+		var ch rune
+		for s.Whitespace&(1<<uint(ch)) != 0 {}
+	}
+}
+
+func issue5895() {
+	var x = 'a' << 1 // type of x must be rune
+	var _ rune = x
+}
+
+func issue11325() {
+	var _ = 0 >> 1.1 /* ERROR "truncated to uint" */ // example from issue 11325
+	_ = 0 >> 1.1 /* ERROR "truncated to uint" */
+	_ = 0 << 1.1 /* ERROR "truncated to uint" */
+	_ = 0 >> 1.
+	_ = 1 >> 1.1 /* ERROR "truncated to uint" */
+	_ = 1 >> 1.
+	_ = 1. >> 1
+	_ = 1. >> 1.
+	_ = 1.1 /* ERROR "must be integer" */ >> 1
+}
+
+func issue11594() {
+	var _ = complex64 /* ERROR "must be integer" */ (1) << 2 // example from issue 11594
+	_ = float32 /* ERROR "must be integer" */ (0) << 1
+	_ = float64 /* ERROR "must be integer" */ (0) >> 2
+	_ = complex64 /* ERROR "must be integer" */ (0) << 3
+	_ = complex64 /* ERROR "must be integer" */ (0) >> 4
+}
+
+func issue21727() {
+	var s uint
+	var a = make([]int, 1<<s + 1.2 /* ERROR "truncated to int" */ )
+	var _ = a[1<<s - 2.3 /* ERROR "truncated to int" */ ]
+	var _ int = 1<<s + 3.4 /* ERROR "truncated to int" */
+	var _ = string(1 << s)
+	var _ = string(1.0 /* ERROR "cannot convert" */ << s)
+}
+
+func issue22969() {
+	var s uint
+	var a []byte
+	_ = a[0xffffffffffffffff /* ERROR "overflows int" */ <<s] // example from issue 22969
+	_ = make([]int, 0xffffffffffffffff /* ERROR "overflows int" */ << s)
+	_ = make([]int, 0, 0xffffffffffffffff /* ERROR "overflows int" */ << s)
+	var _ byte = 0x100 /* ERROR "overflows byte" */ << s
+	var _ int8 = 0xff /* ERROR "overflows int8" */ << s
+	var _ int16 = 0xffff /* ERROR "overflows int16" */ << s
+	var _ int32 = 0x80000000 /* ERROR "overflows int32" */ << s
+}
diff --git a/src/go/types/testdata/check/slices.go2 b/src/go/types/testdata/check/slices.go2
new file mode 100644
index 0000000..2bacd1c
--- /dev/null
+++ b/src/go/types/testdata/check/slices.go2
@@ -0,0 +1,68 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package slices implements various slice algorithms.
+package slices
+
+// Map turns a []T1 to a []T2 using a mapping function.
+func Map[T1, T2 any](s []T1, f func(T1) T2) []T2 {
+	r := make([]T2, len(s))
+	for i, v := range s {
+		r[i] = f(v)
+	}
+	return r
+}
+
+// Reduce reduces a []T1 to a single value using a reduction function.
+func Reduce[T1, T2 any](s []T1, initializer T2, f func(T2, T1) T2) T2 {
+	r := initializer
+	for _, v := range s {
+		r = f(r, v)
+	}
+	return r
+}
+
+// Filter filters values from a slice using a filter function.
+func Filter[T any](s []T, f func(T) bool) []T {
+	var r []T
+	for _, v := range s {
+		if f(v) {
+			r = append(r, v)
+		}
+	}
+	return r
+}
+
+// Example uses
+
+func limiter(x int) byte {
+	switch {
+	case x < 0:
+		return 0
+	default:
+		return byte(x)
+	case x > 255:
+		return 255
+	}
+}
+
+var input = []int{-4, 68954, 7, 44, 0, -555, 6945}
+var limited1 = Map[int, byte](input, limiter)
+var limited2 = Map(input, limiter) // using type inference
+
+func reducer(x float64, y int) float64 {
+	return x + float64(y)
+}
+
+var reduced1 = Reduce[int, float64](input, 0, reducer)
+var reduced2 = Reduce(input, 1i /* ERROR overflows */, reducer) // using type inference
+var reduced3 = Reduce(input, 1, reducer) // using type inference
+
+func filter(x int) bool {
+	return x&1 != 0
+}
+
+var filtered1 = Filter[int](input, filter)
+var filtered2 = Filter(input, filter) // using type inference
+
diff --git a/src/go/types/testdata/check/stmt0.src b/src/go/types/testdata/check/stmt0.src
new file mode 100644
index 0000000..76b6e70
--- /dev/null
+++ b/src/go/types/testdata/check/stmt0.src
@@ -0,0 +1,980 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// statements
+
+package stmt0
+
+func assignments0() (int, int) {
+	var a, b, c int
+	var ch chan int
+	f0 := func() {}
+	f1 := func() int { return 1 }
+	f2 := func() (int, int) { return 1, 2 }
+	f3 := func() (int, int, int) { return 1, 2, 3 }
+
+	a, b, c = 1, 2, 3
+	a, b, c = 1 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ , 2
+	a, b, c = 1 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ , 2, 3, 4
+	_, _, _ = a, b, c
+
+	a = f0 /* ERROR "used as value" */ ()
+	a = f1()
+	a = f2 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
+	a, b = f2()
+	a, b, c = f2 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
+	a, b, c = f3()
+	a, b = f3 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
+
+	a, b, c = <- /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ch
+
+	return /* ERROR "wrong number of return values" */
+	return /* ERROR "wrong number of return values" */ 1
+	return 1, 2
+	return /* ERROR "wrong number of return values" */ 1, 2, 3
+}
+
+func assignments1() {
+	b, i, f, c, s := false, 1, 1.0, 1i, "foo"
+	b = i /* ERROR "cannot use .* in assignment" */
+	i = f /* ERROR "cannot use .* in assignment" */
+	f = c /* ERROR "cannot use .* in assignment" */
+	c = s /* ERROR "cannot use .* in assignment" */
+	s = b /* ERROR "cannot use .* in assignment" */
+
+	v0, v1, v2 := 1 /* ERROR "cannot initialize" */ , 2, 3, 4
+	_, _, _ = v0, v1, v2
+
+	b = true
+
+	i += 1
+	i += "foo" /* ERROR "cannot convert.*int" */
+
+	f -= 1
+	f /= 0
+	f = float32(0)/0 /* ERROR "division by zero" */
+	f -= "foo" /* ERROR "cannot convert.*float64" */
+
+	c *= 1
+	c /= 0
+
+	s += "bar"
+	s += 1 /* ERROR "cannot convert.*string" */
+
+	var u64 uint64
+	u64 += 1<<u64
+
+	undeclared /* ERROR "undeclared" */ = 991
+
+	// test cases for issue 5800
+	var (
+		_ int = nil /* ERROR "untyped nil value" */
+		_ [10]int = nil /* ERROR "untyped nil value" */
+		_ []byte = nil
+		_ struct{} = nil /* ERROR "untyped nil value" */
+		_ func() = nil
+		_ map[int]string = nil
+		_ chan int = nil
+	)
+
+	// test cases for issue 5500
+	_ = func() (int, bool) {
+		var m map[int]int
+		return /* ERROR "wrong number of return values" */ m[0]
+	}
+
+	g := func(int, bool){}
+	var m map[int]int
+	g(m[0]) /* ERROR "not enough arguments" */
+
+	// assignments to _
+	_ = nil /* ERROR "use of untyped nil" */
+	_ = 1  << /* ERROR constant shift overflow */ 1000
+	(_) = 0
+}
+
+func assignments2() {
+	type mybool bool
+	var m map[string][]bool
+	var s []bool
+	var b bool
+	var d mybool
+	_ = s
+	_ = b
+	_ = d
+
+	// assignments to map index expressions are ok
+	s, b = m["foo"]
+	_, d = m["bar"]
+	m["foo"] = nil
+	m["foo"] = nil /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
+	_ = append(m["foo"])
+	_ = append(m["foo"], true)
+
+	var c chan int
+	_, b = <-c
+	_, d = <-c
+	<- /* ERROR cannot assign */ c = 0
+	<-c = 0 /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
+
+	var x interface{}
+	_, b = x.(int)
+	x /* ERROR cannot assign */ .(int) = 0
+	x.(int) = 0 /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
+
+	assignments2 /* ERROR used as value */ () = nil
+	int /* ERROR not an expression */ = 0
+}
+
+func issue6487() {
+	type S struct{x int}
+	_ = &S /* ERROR "cannot take address" */ {}.x
+	_ = &( /* ERROR "cannot take address" */ S{}.x)
+	_ = (&S{}).x
+	S /* ERROR "cannot assign" */ {}.x = 0
+	(&S{}).x = 0
+
+	type M map[string]S
+	var m M
+	m /* ERROR "cannot assign to struct field" */ ["foo"].x = 0
+	_ = &( /* ERROR "cannot take address" */ m["foo"].x)
+	_ = &m /* ERROR "cannot take address" */ ["foo"].x
+}
+
+func issue6766a() {
+	a, a /* ERROR a repeated on left side of := */ := 1, 2
+	_ = a
+	a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3
+	_ = b
+	c, c /* ERROR c repeated on left side of := */, b := 1, 2, 3
+	_ = c
+	a, b := /* ERROR no new variables */ 1, 2
+}
+
+func shortVarDecls1() {
+	const c = 0
+	type d int
+	a, b, c /* ERROR "cannot assign" */ , d /* ERROR "cannot assign" */  := 1, "zwei", 3.0, 4
+	var _ int = a // a is of type int
+	var _ string = b // b is of type string
+}
+
+func incdecs() {
+	const c = 3.14
+	c /* ERROR "cannot assign" */ ++
+	s := "foo"
+	s /* ERROR "invalid operation" */ --
+	3.14 /* ERROR "cannot assign" */ ++
+	var (
+		x int
+		y float32
+		z complex128
+	)
+	x++
+	y--
+	z++
+}
+
+func sends() {
+	var ch chan int
+	var rch <-chan int
+	var x int
+	x <- /* ERROR "cannot send" */ x
+	rch <- /* ERROR "cannot send" */ x
+	ch <- "foo" /* ERROR "cannot use .* in send" */
+	ch <- x
+}
+
+func selects() {
+	select {}
+	var (
+		ch chan int
+		sc chan <- bool
+	)
+	select {
+	case <-ch:
+	case (<-ch):
+	case t := <-ch:
+		_ = t
+	case t := (<-ch):
+		_ = t
+	case t, ok := <-ch:
+		_, _ = t, ok
+	case t, ok := (<-ch):
+		_, _ = t, ok
+	case <-sc /* ERROR "cannot receive from send-only channel" */ :
+	}
+	select {
+	default:
+	default /* ERROR "multiple defaults" */ :
+	}
+	select {
+	case a, b := <-ch:
+		_, b = a, b
+	case x /* ERROR send or receive */ :
+	case a /* ERROR send or receive */ := ch:
+	}
+
+	// test for issue 9570: ch2 in second case falsely resolved to
+	// ch2 declared in body of first case
+	ch1 := make(chan int)
+	ch2 := make(chan int)
+	select {
+	case <-ch1:
+		var ch2 /* ERROR ch2 declared but not used */ chan bool
+	case i := <-ch2:
+		print(i + 1)
+	}
+}
+
+func gos() {
+	go 1 /* ERROR HERE "function must be invoked" */
+	go int /* ERROR "go requires function call, not conversion" */ (0)
+	go gos()
+	var c chan int
+	go close(c)
+	go len /* ERROR "go discards result" */ (c)
+}
+
+func defers() {
+	defer 1 /* ERROR HERE "function must be invoked" */
+	defer int /* ERROR "defer requires function call, not conversion" */ (0)
+	defer defers()
+	var c chan int
+	defer close(c)
+	defer len /* ERROR "defer discards result" */ (c)
+}
+
+func breaks() {
+	var x, y int
+
+	break /* ERROR "break" */
+	{
+		break /* ERROR "break" */
+	}
+	if x < y {
+		break /* ERROR "break" */
+	}
+
+	switch x {
+	case 0:
+		break
+	case 1:
+		if x == y {
+			break
+		}
+	default:
+		break
+		break
+	}
+
+	var z interface{}
+	switch z.(type) {
+	case int:
+		break
+	}
+
+	for {
+		break
+	}
+
+	var a []int
+	for _ = range a {
+		break
+	}
+
+	for {
+		if x == y {
+			break
+		}
+	}
+
+	var ch chan int
+	select {
+	case <-ch:
+		break
+	}
+
+	select {
+	case <-ch:
+		if x == y {
+			break
+		}
+	default:
+		break
+	}
+}
+
+func continues() {
+	var x, y int
+
+	continue /* ERROR "continue" */
+	{
+		continue /* ERROR "continue" */
+	}
+
+	if x < y {
+		continue /* ERROR "continue" */
+	}
+
+	switch x {
+	case 0:
+		continue /* ERROR "continue" */
+	}
+
+	var z interface{}
+	switch z.(type) {
+	case int:
+		continue /* ERROR "continue" */
+	}
+
+	var ch chan int
+	select {
+	case <-ch:
+		continue /* ERROR "continue" */
+	}
+
+	for i := 0; i < 10; i++ {
+		continue
+		if x < y {
+			continue
+			break
+		}
+		switch x {
+		case y:
+			continue
+		default:
+			break
+		}
+		select {
+		case <-ch:
+			continue
+		}
+	}
+
+	var a []int
+	for _ = range a {
+		continue
+		if x < y {
+			continue
+			break
+		}
+		switch x {
+		case y:
+			continue
+		default:
+			break
+		}
+		select {
+		case <-ch:
+			continue
+		}
+	}
+}
+
+func returns0() {
+	return
+	return 0 /* ERROR no result values expected */
+}
+
+func returns1(x float64) (int, *float64) {
+	return 0, &x
+	return /* ERROR wrong number of return values */
+	return "foo" /* ERROR "cannot .* in return statement" */, x /* ERROR "cannot use .* in return statement" */
+	return /* ERROR wrong number of return values */ 0, &x, 1
+}
+
+func returns2() (a, b int) {
+	return
+	return 1, "foo" /* ERROR cannot use .* in return statement */
+	return /* ERROR wrong number of return values */ 1, 2, 3
+	{
+		type a int
+		return 1, 2
+		return /* ERROR a not in scope at return */
+	}
+}
+
+func returns3() (_ int) {
+	return
+	{
+		var _ int // blank (_) identifiers never shadow since they are in no scope
+		return
+	}
+}
+
+func switches0() {
+	var x int
+
+	switch x {
+	}
+
+	switch x {
+	default:
+	default /* ERROR "multiple defaults" */ :
+	}
+
+	switch {
+	case 1  /* ERROR "cannot convert" */ :
+	}
+
+	true := "false"
+	_ = true
+	// A tagless switch is equivalent to the bool
+        // constant true, not the identifier 'true'.
+	switch {
+	case "false" /* ERROR "cannot convert" */:
+	}
+
+	switch int32(x) {
+	case 1, 2:
+	case x /* ERROR "cannot compare" */ :
+	}
+
+	switch x {
+	case 1 /* ERROR "overflows" */ << 100:
+	}
+
+	switch x {
+	case 1:
+	case 1 /* ERROR "duplicate case" */ :
+	case ( /* ERROR "duplicate case" */ 1):
+	case 2, 3, 4:
+	case 5, 1 /* ERROR "duplicate case" */ :
+	}
+
+	switch uint64(x) {
+	case 1<<64 - 1:
+	case 1 /* ERROR duplicate case */ <<64 - 1:
+	case 2, 3, 4:
+	case 5, 1 /* ERROR duplicate case */ <<64 - 1:
+	}
+
+	var y32 float32
+	switch y32 {
+	case 1.1:
+	case 11/10: // integer division!
+	case 11. /* ERROR duplicate case */ /10:
+	case 2, 3.0, 4.1:
+	case 5.2, 1.10 /* ERROR duplicate case */ :
+	}
+
+	var y64 float64
+	switch y64 {
+	case 1.1:
+	case 11/10: // integer division!
+	case 11. /* ERROR duplicate case */ /10:
+	case 2, 3.0, 4.1:
+	case 5.2, 1.10 /* ERROR duplicate case */ :
+	}
+
+	var s string
+	switch s {
+	case "foo":
+	case "foo" /* ERROR duplicate case */ :
+	case "f" /* ERROR duplicate case */ + "oo":
+	case "abc", "def", "ghi":
+	case "jkl", "foo" /* ERROR duplicate case */ :
+	}
+
+	type T int
+	type F float64
+	type S string
+	type B bool
+	var i interface{}
+	switch i {
+	case nil:
+	case nil: // no duplicate detection
+	case (*int)(nil):
+	case (*int)(nil): // do duplicate detection
+	case 1:
+	case byte(1):
+	case int /* ERROR duplicate case */ (1):
+	case T(1):
+	case 1.0:
+	case F(1.0):
+	case F /* ERROR duplicate case */ (1.0):
+	case "hello":
+	case S("hello"):
+	case S /* ERROR duplicate case */ ("hello"):
+	case 1==1, B(false):
+	case false, B(2==2):
+	}
+
+	// switch on array
+	var a [3]int
+	switch a {
+	case [3]int{1, 2, 3}:
+	case [3]int{1, 2, 3}: // no duplicate detection
+	case [ /* ERROR "mismatched types */ 4]int{4, 5, 6}:
+	}
+
+	// switch on channel
+	var c1, c2 chan int
+	switch c1 {
+	case nil:
+	case c1:
+	case c2:
+	case c1, c2: // no duplicate detection
+	}
+}
+
+func switches1() {
+	fallthrough /* ERROR "fallthrough statement out of place" */
+
+	var x int
+	switch x {
+	case 0:
+		fallthrough /* ERROR "fallthrough statement out of place" */
+		break
+	case 1:
+		fallthrough
+	case 2:
+		fallthrough; ; ; // trailing empty statements are ok
+	case 3:
+	default:
+		fallthrough; ;
+	case 4:
+		fallthrough /* ERROR "cannot fallthrough final case in switch" */
+	}
+
+	var y interface{}
+	switch y.(type) {
+	case int:
+		fallthrough /* ERROR "fallthrough statement out of place" */ ; ; ;
+	default:
+	}
+
+	switch x {
+	case 0:
+		if x == 0 {
+			fallthrough /* ERROR "fallthrough statement out of place" */
+		}
+	}
+
+	switch x {
+	case 0:
+		goto L1
+		L1: fallthrough; ;
+	case 1:
+		goto L2
+		goto L3
+		goto L4
+		L2: L3: L4: fallthrough
+	default:
+	}
+
+	switch x {
+	case 0:
+		goto L5
+		L5: fallthrough
+	default:
+		goto L6
+		goto L7
+		goto L8
+		L6: L7: L8: fallthrough /* ERROR "cannot fallthrough final case in switch" */
+	}
+
+	switch x {
+	case 0:
+		fallthrough; ;
+	case 1:
+		{
+			fallthrough /* ERROR "fallthrough statement out of place" */
+		}
+	case 2:
+		fallthrough
+	case 3:
+		fallthrough /* ERROR "fallthrough statement out of place" */
+		{ /* empty block is not an empty statement */ }; ;
+	default:
+		fallthrough /* ERROR "cannot fallthrough final case in switch" */
+	}
+
+	switch x {
+	case 0:
+		{
+			fallthrough /* ERROR "fallthrough statement out of place" */
+		}
+	}
+}
+
+func switches2() {
+	// untyped nil is not permitted as switch expression
+	switch nil /* ERROR "use of untyped nil" */ {
+	case 1, 2, "foo": // don't report additional errors here
+	}
+
+	// untyped constants are converted to default types
+	switch 1<<63-1 {
+	}
+	switch 1 /* ERROR "cannot use .* as int value.*\(overflows\)" */ << 63 {
+	}
+	var x int
+	switch 1.0 {
+	case 1.0, 2.0, x /* ERROR "mismatched types int and float64" */ :
+	}
+	switch x {
+	case 1.0:
+	}
+
+	// untyped bools become of type bool
+	type B bool
+	var b B = true
+	switch x == x {
+	case b /* ERROR "mismatched types B and bool" */ :
+	}
+	switch {
+	case b /* ERROR "mismatched types B and bool" */ :
+	}
+}
+
+func issue11667() {
+	switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ {
+	}
+	switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ {
+	case 9223372036854775808:
+	}
+	var x int
+	switch x {
+	case 9223372036854775808 /* ERROR "overflows int" */ :
+	}
+	var y float64
+	switch y {
+	case 9223372036854775808:
+	}
+}
+
+func issue11687() {
+	f := func() (_, _ int) { return }
+	switch f /* ERROR "2-valued f" */ () {
+	}
+	var x int
+	switch f /* ERROR "2-valued f" */ () {
+	case x:
+	}
+	switch x {
+	case f /* ERROR "2-valued f" */ ():
+	}
+}
+
+type I interface {
+	m()
+}
+
+type I2 interface {
+	m(int)
+}
+
+type T struct{}
+type T1 struct{}
+type T2 struct{}
+
+func (T) m() {}
+func (T2) m(int) {}
+
+func typeswitches() {
+	var i int
+	var x interface{}
+
+	switch x.(type) {}
+	switch (x /* ERROR "outside type switch" */ .(type)) {}
+
+	switch x.(type) {
+	default:
+	default /* ERROR "multiple defaults" */ :
+	}
+
+	switch x /* ERROR "declared but not used" */ := x.(type) {}
+	switch _ /* ERROR "no new variable on left side of :=" */ := x.(type) {}
+
+	switch x := x.(type) {
+	case int:
+		var y int = x
+		_ = y
+	}
+
+	switch x := i /* ERROR "not an interface" */ .(type) {}
+
+	switch t := x.(type) {
+	case nil:
+		var v bool = t /* ERROR "cannot use .* in variable declaration" */
+		_ = v
+	case int:
+		var v int = t
+		_ = v
+	case float32, complex64:
+		var v float32 = t /* ERROR "cannot use .* in variable declaration" */
+		_ = v
+	default:
+		var v float32 = t /* ERROR "cannot use .* in variable declaration" */
+		_ = v
+	}
+
+	var t I
+	switch t.(type) {
+	case T:
+	case T1 /* ERROR "missing method m" */ :
+	case T2 /* ERROR "wrong type for method m" */ :
+	case I2 /* STRICT "wrong type for method m" */ : // only an error in strict mode (issue 8561)
+	}
+}
+
+// Test that each case clause uses the correct type of the variable
+// declared by the type switch (issue 5504).
+func typeswitch0() {
+	switch y := interface{}(nil).(type) {
+	case int:
+		func() int { return y + 0 }()
+	case float32:
+		func() float32 { return y }()
+	}
+}
+
+// Test correct scope setup.
+// (no redeclaration errors expected in the type switch)
+func typeswitch1() {
+	var t I
+	switch t := t; t := t.(type) {
+	case nil:
+		var _ I = t
+	case T:
+		var _ T = t
+	default:
+		var _ I = t
+	}
+}
+
+// Test correct typeswitch against interface types.
+type A interface { a() }
+type B interface { b() }
+type C interface { a(int) }
+
+func typeswitch2() {
+	switch A(nil).(type) {
+	case A:
+	case B:
+	case C /* STRICT "cannot have dynamic type" */: // only an error in strict mode (issue 8561)
+	}
+}
+
+func typeswitch3(x interface{}) {
+	switch x.(type) {
+	case int:
+	case float64:
+	case int /* ERROR duplicate case */ :
+	}
+
+	switch x.(type) {
+	case nil:
+	case int:
+	case nil /* ERROR duplicate case */ , nil /* ERROR duplicate case */ :
+	}
+
+	type F func(int)
+	switch x.(type) {
+	case nil:
+	case int, func(int):
+	case float32, func /* ERROR duplicate case */ (x int):
+	case F:
+	}
+}
+
+func fors1() {
+	for {}
+	var i string
+	_ = i
+	for i := 0; i < 10; i++ {}
+	for i := 0; i < 10; j /* ERROR cannot declare */ := 0 {}
+}
+
+func rangeloops1() {
+	var (
+		x int
+		a [10]float32
+		b []string
+		p *[10]complex128
+		pp **[10]complex128
+		s string
+		m map[int]bool
+		c chan int
+		sc chan<- int
+		rc <-chan int
+	)
+
+	for range x /* ERROR "cannot range over" */ {}
+	for _ = range x /* ERROR "cannot range over" */ {}
+	for i := range x /* ERROR "cannot range over" */ {}
+
+	for range a {}
+	for i := range a {
+		var ii int
+		ii = i
+		_ = ii
+	}
+	for i, x := range a {
+		var ii int
+		ii = i
+		_ = ii
+		var xx float64
+		xx = x /* ERROR "cannot use .* in assignment" */
+		_ = xx
+	}
+	var ii int
+	var xx float32
+	for ii, xx = range a {}
+	_, _ = ii, xx
+
+	for range b {}
+	for i := range b {
+		var ii int
+		ii = i
+		_ = ii
+	}
+	for i, x := range b {
+		var ii int
+		ii = i
+		_ = ii
+		var xx string
+		xx = x
+		_ = xx
+	}
+
+	for range s {}
+	for i := range s {
+		var ii int
+		ii = i
+		_ = ii
+	}
+	for i, x := range s {
+		var ii int
+		ii = i
+		_ = ii
+		var xx rune
+		xx = x
+		_ = xx
+	}
+
+	for range p {}
+	for _, x := range p {
+		var xx complex128
+		xx = x
+		_ = xx
+	}
+
+	for range pp /* ERROR "cannot range over" */ {}
+	for _, x := range pp /* ERROR "cannot range over" */ {}
+
+	for range m {}
+	for k := range m {
+		var kk int32
+		kk = k /* ERROR "cannot use .* in assignment" */
+		_ = kk
+	}
+	for k, v := range m {
+		var kk int
+		kk = k
+		_ = kk
+		if v {}
+	}
+
+	for range c {}
+	for _, _ /* ERROR "only one iteration variable" */ = range c {}
+	for e := range c {
+		var ee int
+		ee = e
+		_ = ee
+	}
+	for _ = range sc /* ERROR "cannot range over" */ {}
+	for _ = range rc {}
+
+	// constant strings
+	const cs = "foo"
+	for range cs {}
+	for range "" {}
+	for i, x := range cs { _, _ = i, x }
+	for i, x := range "" {
+		var ii int
+		ii = i
+		_ = ii
+		var xx rune
+		xx = x
+		_ = xx
+	}
+}
+
+func rangeloops2() {
+	type I int
+	type R rune
+
+	var a [10]int
+	var i I
+	_ = i
+	for i /* ERROR cannot use .* in assignment */ = range a {}
+	for i /* ERROR cannot use .* in assignment */ = range &a {}
+	for i /* ERROR cannot use .* in assignment */ = range a[:] {}
+
+	var s string
+	var r R
+	_ = r
+	for i /* ERROR cannot use .* in assignment */ = range s {}
+	for i /* ERROR cannot use .* in assignment */ = range "foo" {}
+	for _, r /* ERROR cannot use .* in assignment */ = range s {}
+	for _, r /* ERROR cannot use .* in assignment */ = range "foo" {}
+}
+
+func issue6766b() {
+	for _ := /* ERROR no new variables */ range "" {}
+	for a, a /* ERROR redeclared */ := range "" { _ = a }
+	var a int
+	_ = a
+	for a, a /* ERROR redeclared */ := range []int{1, 2, 3} { _ = a }
+}
+
+// Test that despite errors in the range clause,
+// the loop body is still type-checked (and thus
+// errors reported).
+func issue10148() {
+	for y /* ERROR declared but not used */ := range "" {
+		_ = "" /* ERROR cannot convert */ + 1
+	}
+	for range 1 /* ERROR cannot range over 1 */ {
+		_ = "" /* ERROR cannot convert */ + 1
+	}
+	for y := range 1 /* ERROR cannot range over 1 */ {
+		_ = "" /* ERROR cannot convert */ + 1
+	}
+}
+
+func labels0() {
+	goto L0
+	goto L1
+	L0:
+	L1:
+	L1 /* ERROR "already declared" */ :
+	if true {
+		goto L2
+		L2:
+		L0 /* ERROR "already declared" */ :
+	}
+	_ = func() {
+		goto L0
+		goto L1
+		goto L2
+		L0:
+		L1:
+		L2:
+	}
+}
+
+func expression_statements(ch chan int) {
+	expression_statements(ch)
+	<-ch
+	println()
+
+	0 /* ERROR "not used" */
+	1 /* ERROR "not used" */ +2
+	cap /* ERROR "not used" */ (ch)
+	println /* ERROR "must be called" */
+}
diff --git a/src/go/types/testdata/stmt1.src b/src/go/types/testdata/check/stmt1.src
similarity index 100%
rename from src/go/types/testdata/stmt1.src
rename to src/go/types/testdata/check/stmt1.src
diff --git a/src/go/types/testdata/check/tinference.go2 b/src/go/types/testdata/check/tinference.go2
new file mode 100644
index 0000000..31338b3
--- /dev/null
+++ b/src/go/types/testdata/check/tinference.go2
@@ -0,0 +1,108 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tinferenceB
+
+import "strconv"
+
+type any interface{}
+
+// TODO(rFindley) the below partially applied function types should probably
+//                not be permitted (spec question).
+
+func f0[A any, B interface{type C}, C interface{type D}, D interface{type A}](A, B, C, D)
+func _() {
+	f := f0[string]
+	f("a", "b", "c", "d")
+	f0("a", "b", "c", "d")
+}
+
+func f1[A any, B interface{type A}](A, B)
+func _() {
+	f := f1[int]
+	f(int(0), int(0))
+	f1(int(0), int(0))
+}
+
+func f2[A any, B interface{type []A}](A, B)
+func _() {
+	f := f2[byte]
+	f(byte(0), []byte{})
+	f2(byte(0), []byte{})
+}
+
+func f3[A any, B interface{type C}, C interface{type *A}](A, B, C)
+func _() {
+	f := f3[int]
+	var x int
+	f(x, &x, &x)
+	f3(x, &x, &x)
+}
+
+func f4[A any, B interface{type []C}, C interface{type *A}](A, B, C)
+func _() {
+	f := f4[int]
+	var x int
+	f(x, []*int{}, &x)
+	f4(x, []*int{}, &x)
+}
+
+func f5[A interface{type struct{b B; c C}}, B any, C interface{type *B}](x B) A
+func _() {
+	x := f5(1.2)
+	var _ float64 = x.b
+	var _ float64 = *x.c
+}
+
+func f6[A any, B interface{type struct{f []A}}](B) A
+func _() {
+	x := f6(struct{f []string}{})
+	var _ string = x
+}
+
+// TODO(gri) Need to flag invalid recursive constraints. At the
+// moment these cause infinite recursions and stack overflow.
+// func f7[A interface{type B}, B interface{type A}]()
+
+// More realistic examples
+
+func Double[S interface{ type []E }, E interface{ type int, int8, int16, int32, int64 }](s S) S {
+	r := make(S, len(s))
+	for i, v := range s {
+		r[i] = v + v
+	}
+	return r
+}
+
+type MySlice []int
+
+var _ = Double(MySlice{1})
+
+// From the draft design.
+
+type Setter[B any] interface {
+	Set(string)
+	type *B
+}
+
+func FromStrings[T interface{}, PT Setter[T]](s []string) []T {
+	result := make([]T, len(s))
+	for i, v := range s {
+		// The type of &result[i] is *T which is in the type list
+		// of Setter2, so we can convert it to PT.
+		p := PT(&result[i])
+		// PT has a Set method.
+		p.Set(v)
+	}
+	return result
+}
+
+type Settable int
+
+func (p *Settable) Set(s string) {
+	i, _ := strconv.Atoi(s) // real code should not ignore the error
+	*p = Settable(i)
+}
+
+var _ = FromStrings[Settable]([]string{"1", "2"})
diff --git a/src/go/types/testdata/check/tmp.go2 b/src/go/types/testdata/check/tmp.go2
new file mode 100644
index 0000000..dae78ca
--- /dev/null
+++ b/src/go/types/testdata/check/tmp.go2
@@ -0,0 +1,17 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is meant as "dumping ground" for debugging code.
+
+package p
+
+// fun test case
+type C[P interface{m()}] P
+
+func (r C[P]) m() { r.m() }
+
+func f[T interface{m(); n()}](x T) {
+	y := C[T](x)
+	y.m()
+}
diff --git a/src/go/types/testdata/check/todos.go2 b/src/go/types/testdata/check/todos.go2
new file mode 100644
index 0000000..09e9b4c
--- /dev/null
+++ b/src/go/types/testdata/check/todos.go2
@@ -0,0 +1,22 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is meant as "dumping ground" for tests
+// of not yet implemented features. It will grow and
+// shrink over time.
+
+package p
+
+// When using []'s instead of ()'s for type parameters
+// we don't need extra parentheses for some composite
+// literal types.
+type T1[P any] struct{}
+type T2[P, Q any] struct{}
+
+func _() {
+   _ = []T1[int]{}            // ok if we use []'s
+   _ = [](T1[int]){}
+   _ = []T2[int, string]{}    // ok if we use []'s
+   _ = [](T2[int, string]){}
+}
diff --git a/src/go/types/testdata/check/typeinst.go2 b/src/go/types/testdata/check/typeinst.go2
new file mode 100644
index 0000000..3184a4b
--- /dev/null
+++ b/src/go/types/testdata/check/typeinst.go2
@@ -0,0 +1,59 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type myInt int
+
+// Parameterized type declarations
+
+type T1[P any] P
+
+type T2[P any] struct {
+        f P
+        g int // int should still be in scope chain
+}
+
+type List[P any] []P
+
+// Alias type declarations cannot have type parameters. Syntax error.
+type A1[P any] = /* ERROR cannot be alias */ P
+
+// But an alias may refer to a generic, uninstantiated type.
+type A2 = List
+var _ A2[int]
+var _ A2 /* ERROR without instantiation */
+
+type A3 = List[int]
+var _ A3
+
+// Parameterized type instantiations
+
+var x int
+type _ x /* ERROR not a type */ [int]
+
+type _ int /* ERROR not a generic type */ []
+type _ myInt /* ERROR not a generic type */ []
+
+// TODO(gri) better error messages
+type _ T1 /* ERROR got 0 arguments but 1 type parameters */ []
+type _ T1[x /* ERROR not a type */ ]
+type _ T1 /* ERROR got 2 arguments but 1 type parameters */ [int, float32]
+
+var _ T2[int] = T2[int]{}
+
+var _ List[int] = []int{1, 2, 3}
+var _ List[[]int] = [][]int{{1, 2, 3}}
+var _ List[List[List[int]]]
+
+// Parameterized types containing parameterized types
+
+type T3[P any] List[P]
+
+var _ T3[int] = T3[int](List[int]{1, 2, 3})
+
+// Self-recursive generic types are not permitted
+
+type self1[P any] self1 /* ERROR illegal cycle */ [P]
+type self2[P any] *self2[P] // this is ok
diff --git a/src/go/types/testdata/check/typeinst2.go2 b/src/go/types/testdata/check/typeinst2.go2
new file mode 100644
index 0000000..6e2104a
--- /dev/null
+++ b/src/go/types/testdata/check/typeinst2.go2
@@ -0,0 +1,256 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type List[E any] []E
+var _ List[List[List[int]]]
+var _ List[List[List[int]]] = []List[List[int]]{}
+
+type (
+	T1[P1 any] struct {
+		f1 T2[P1, float32]
+	}
+
+	T2[P2, P3 any] struct {
+		f2 P2
+		f3 P3
+	}
+)
+
+func _() {
+	var x1 T1[int]
+	var x2 T2[int, float32]
+
+	x1.f1.f2 = 0
+	x1.f1 = x2
+}
+
+type T3[P any] T1[T2[P, P]]
+
+func _() {
+	var x1 T3[int]
+	var x2 T2[int, int]
+	x1.f1.f2 = x2
+}
+
+func f[P any] (x P) List[P] {
+	return List[P]{x}
+}
+
+var (
+	_ []int = f(0)
+	_ []float32 = f[float32](10)
+	_ List[complex128] = f(1i)
+	_ []List[int] = f(List[int]{})
+        _ List[List[int]] = []List[int]{}
+        _ = []List[int]{}
+)
+
+// Parameterized types with methods
+
+func (l List[E]) Head() (_ E, _ bool) {
+	if len(l) > 0 {
+		return l[0], true
+	}
+	return
+}
+
+// A test case for instantiating types with other types (extracted from map.go2)
+
+type Pair[K any] struct {
+	key K
+}
+
+type Receiver[T any] struct {
+	values T
+}
+
+type Iterator[K any] struct {
+	r Receiver[Pair[K]]
+}
+
+func Values [T any] (r Receiver[T]) T {
+        return r.values
+}
+
+func (it Iterator[K]) Next() K {
+        return Values[Pair[K]](it.r).key
+}
+
+// A more complex test case testing type bounds (extracted from linalg.go2 and reduced to essence)
+
+type NumericAbs[T any] interface {
+	Abs() T
+}
+
+func AbsDifference[T NumericAbs[T]](x T)
+
+type OrderedAbs[T any] T
+
+func (a OrderedAbs[T]) Abs() OrderedAbs[T]
+
+func OrderedAbsDifference[T any](x T) {
+	AbsDifference(OrderedAbs[T](x))
+}
+
+// same code, reduced to essence
+
+func g[P interface{ m() P }](x P)
+
+type T4[P any] P
+
+func (_ T4[P]) m() T4[P]
+
+func _[Q any](x Q) {
+	g(T4[Q](x))
+}
+
+// Another test case that caused  problems in the past
+
+type T5[_ interface { a() }, _ interface{}] struct{}
+
+type A[P any] struct{ x P }
+
+func (_ A[P]) a() {}
+
+var _ T5[A[int], int]
+
+// Invoking methods with parameterized receiver types uses
+// type inference to determine the actual type arguments matching
+// the receiver type parameters from the actual receiver argument.
+// Go does implicit address-taking and dereferenciation depending
+// on the actual receiver and the method's receiver type. To make
+// type inference work, the type-checker matches "pointer-ness"
+// of the actual receiver and the method's receiver type.
+// The following code tests this mechanism.
+
+type R1[A any] struct{}
+func (_ R1[A]) vm()
+func (_ *R1[A]) pm()
+
+func _[T any](r R1[T], p *R1[T]) {
+	r.vm()
+	r.pm()
+	p.vm()
+	p.pm()
+}
+
+type R2[A, B any] struct{}
+func (_ R2[A, B]) vm()
+func (_ *R2[A, B]) pm()
+
+func _[T any](r R2[T, int], p *R2[string, T]) {
+	r.vm()
+	r.pm()
+	p.vm()
+	p.pm()
+}
+
+// An interface can (explicitly) declare at most one type list.
+type _ interface {
+	m0()
+	type int, string, bool
+	type /* ERROR multiple type lists */ float32, float64
+	m1()
+	m2()
+	type /* ERROR multiple type lists */ complex64, complex128
+	type /* ERROR multiple type lists */ rune
+}
+
+// Interface type lists may contain each type at most once.
+// (If there are multiple lists, we assume the author intended
+// for them to be all in a single list, and we report the error
+// as well.)
+type _ interface {
+	type int, int /* ERROR duplicate type int */
+	type /* ERROR multiple type lists */ int /* ERROR duplicate type int */
+}
+
+type _ interface {
+	type struct{f int}, struct{g int}, struct /* ERROR duplicate type */ {f int}
+}
+
+// Interface type lists can contain any type, incl. *Named types.
+// Verify that we use the underlying type to compute the operational type.
+type MyInt int
+func add1[T interface{type MyInt}](x T) T {
+	return x + 1
+}
+
+type MyString string
+func double[T interface{type MyInt, MyString}](x T) T {
+	return x + x
+}
+
+// Embedding of interfaces with type lists leads to interfaces
+// with type lists that are the intersection of the embedded
+// type lists.
+
+type E0 interface {
+	type int, bool, string
+}
+
+type E1 interface {
+	type int, float64, string
+}
+
+type E2 interface {
+	type float64
+}
+
+type I0 interface {
+	E0
+}
+
+func f0[T I0]()
+var _ = f0[int]
+var _ = f0[bool]
+var _ = f0[string]
+var _ = f0[float64 /* ERROR does not satisfy I0 */ ]
+
+type I01 interface {
+	E0
+	E1
+}
+
+func f01[T I01]()
+var _ = f01[int]
+var _ = f01[bool /* ERROR does not satisfy I0 */ ]
+var _ = f01[string]
+var _ = f01[float64 /* ERROR does not satisfy I0 */ ]
+
+type I012 interface {
+	E0
+	E1
+	E2
+}
+
+func f012[T I012]()
+var _ = f012[int /* ERROR does not satisfy I012 */ ]
+var _ = f012[bool /* ERROR does not satisfy I012 */ ]
+var _ = f012[string /* ERROR does not satisfy I012 */ ]
+var _ = f012[float64 /* ERROR does not satisfy I012 */ ]
+
+type I12 interface {
+	E1
+	E2
+}
+
+func f12[T I12]()
+var _ = f12[int /* ERROR does not satisfy I12 */ ]
+var _ = f12[bool /* ERROR does not satisfy I12 */ ]
+var _ = f12[string /* ERROR does not satisfy I12 */ ]
+var _ = f12[float64]
+
+type I0_ interface {
+	E0
+	type int
+}
+
+func f0_[T I0_]()
+var _ = f0_[int]
+var _ = f0_[bool /* ERROR does not satisfy I0_ */ ]
+var _ = f0_[string /* ERROR does not satisfy I0_ */ ]
+var _ = f0_[float64 /* ERROR does not satisfy I0_ */ ]
diff --git a/src/go/types/testdata/check/typeparams.go2 b/src/go/types/testdata/check/typeparams.go2
new file mode 100644
index 0000000..d95e02e
--- /dev/null
+++ b/src/go/types/testdata/check/typeparams.go2
@@ -0,0 +1,433 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// import "io" // for type assertion tests
+
+// The predeclared identifier "any" is only visible as a constraint
+// in a type parameter list.
+var _ any // ERROR undeclared
+func _[_ any /* ok here */ , _ interface{any /* ERROR undeclared */ }](any /* ERROR undeclared */ ) {
+        var _ any /* ERROR undeclared */
+}
+
+func identity[T any](x T) T { return x }
+
+func _[_ any](x int) int
+func _[T any](T /* ERROR redeclared */ T)()
+func _[T, T /* ERROR redeclared */ any]()
+
+// Constraints (incl. any) may be parenthesized.
+func _[_ (any)]() {}
+func _[_ (interface{})]() {}
+
+func reverse[T any](list []T) []T {
+        rlist := make([]T, len(list))
+        i := len(list)
+        for _, x := range list {
+                i--
+                rlist[i] = x
+        }
+        return rlist
+}
+
+var _ = reverse /* ERROR cannot use generic function reverse */
+var _ = reverse[int, float32 /* ERROR got 2 type arguments */ ] ([]int{1, 2, 3})
+var _ = reverse[int]([ /* ERROR cannot use */ ]float32{1, 2, 3})
+var f = reverse[chan int]
+var _ = f(0 /* ERROR cannot use 0 .* as \[\]chan int */ )
+
+func swap[A, B any](a A, b B) (B, A) { return b, a }
+
+var _ = swap /* ERROR single value is expected */ [int, float32](1, 2)
+var f32, i = swap[int, float32](swap[float32, int](1, 2))
+var _ float32 = f32
+var _ int = i
+
+func swapswap[A, B any](a A, b B) (A, B) {
+        return swap[B, A](b, a)
+}
+
+type F[A, B any] func(A, B) (B, A)
+
+func min[T interface{ type int }](x, y T) T {
+        if x < y {
+                return x
+        }
+        return y
+}
+
+func _[T interface{type int, float32}](x, y T) bool { return x < y }
+func _[T any](x, y T) bool { return x /* ERROR cannot compare */ < y }
+func _[T interface{type int, float32, bool}](x, y T) bool { return x /* ERROR cannot compare */ < y }
+
+func _[T C1[T]](x, y T) bool { return x /* ERROR cannot compare */ < y }
+func _[T C2[T]](x, y T) bool { return x < y }
+
+type C1[T any] interface{}
+type C2[T any] interface{ type int, float32 }
+
+func new[T any]() *T {
+        var x T
+        return &x
+}
+
+var _ = new /* ERROR cannot use generic function new */
+var _ *int = new[int]()
+
+func _[T any](map[T /* ERROR incomparable map key type T \(missing comparable constraint\) */]int) // w/o constraint we don't know if T is comparable
+
+func f1[T1 any](struct{T1}) int
+var _ = f1[int](struct{T1}{})
+type T1 = int
+
+func f2[t1 any](struct{t1; x float32}) int
+var _ = f2[t1](struct{t1; x float32}{})
+type t1 = int
+
+
+func f3[A, B, C any](A, struct{x B}, func(A, struct{x B}, *C)) int
+
+var _ = f3[int, rune, bool](1, struct{x rune}{}, nil)
+
+// indexing
+
+func _[T any] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+func _[T interface{ type int }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+func _[T interface{ type string }] (x T, i int) { _ = x[i] }
+func _[T interface{ type []int }] (x T, i int) { _ = x[i] }
+func _[T interface{ type [10]int, *[20]int, map[int]int }] (x T, i int) { _ = x[i] }
+func _[T interface{ type string, []byte }] (x T, i int) { _ = x[i] }
+func _[T interface{ type []int, [1]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+func _[T interface{ type string, []rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+
+// indexing with various combinations of map types in type lists (see issue #42616)
+func _[T interface{ type []E, map[int]E }, E any](x T, i int) { _ = x[i] }
+func _[T interface{ type []E }, E any](x T, i int) { _ = &x[i] }
+func _[T interface{ type map[int]E }, E any](x T, i int) { _, _ = x[i] } // comma-ok permitted
+func _[T interface{ type []E, map[int]E }, E any](x T, i int) { _ = &x /* ERROR cannot take address */ [i] }
+func _[T interface{ type []E, map[int]E, map[uint]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // different map element types
+func _[T interface{ type []E, map[string]E }, E any](x T, i int) { _ = x[i /* ERROR cannot use i */ ] }
+
+// slicing
+// TODO(gri) implement this
+
+func _[T interface{ type string }] (x T, i, j, k int) { _ = x /* ERROR invalid operation */ [i:j:k] }
+
+// len/cap built-ins
+
+func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) }
+func _[T interface{ type int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
+func _[T interface{ type string, []byte, int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
+func _[T interface{ type string }](x T) { _ = len(x) }
+func _[T interface{ type [10]int }](x T) { _ = len(x) }
+func _[T interface{ type []byte }](x T) { _ = len(x) }
+func _[T interface{ type map[int]int }](x T) { _ = len(x) }
+func _[T interface{ type chan int }](x T) { _ = len(x) }
+func _[T interface{ type string, []byte, chan int }](x T) { _ = len(x) }
+
+func _[T any](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type string, []byte, int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type string }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type [10]int }](x T) { _ = cap(x) }
+func _[T interface{ type []byte }](x T) { _ = cap(x) }
+func _[T interface{ type map[int]int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ type chan int }](x T) { _ = cap(x) }
+func _[T interface{ type []byte, chan int }](x T) { _ = cap(x) }
+
+// range iteration
+
+func _[T interface{}](x T) {
+        for range x /* ERROR cannot range */ {}
+}
+
+func _[T interface{ type string, []string }](x T) {
+        for range x {}
+        for i := range x { _ = i }
+        for i, _ := range x { _ = i }
+        for i, e := range x /* ERROR must have the same element type */ { _ = i }
+        for _, e := range x /* ERROR must have the same element type */ {}
+        var e rune
+        _ = e
+        for _, (e) = range x /* ERROR must have the same element type */ {}
+}
+
+
+func _[T interface{ type string, []rune, map[int]rune }](x T) {
+        for _, e := range x { _ = e }
+        for i, e := range x { _ = i; _ = e }
+}
+
+func _[T interface{ type string, []rune, map[string]rune }](x T) {
+        for _, e := range x { _ = e }
+        for i, e := range x /* ERROR must have the same key type */ { _ = e }
+}
+
+func _[T interface{ type string, chan int }](x T) {
+        for range x {}
+        for i := range x { _ = i }
+        for i, _ := range x { _ = i } // TODO(gri) should get an error here: channels only return one value
+}
+
+func _[T interface{ type string, chan<-int }](x T) {
+        for i := range x /* ERROR send-only channel */ { _ = i }
+}
+
+// type inference checks
+
+var _ = new /* ERROR cannot infer T */ ()
+
+func f4[A, B, C any](A, B) C
+
+var _ = f4 /* ERROR cannot infer C */ (1, 2)
+var _ = f4[int, float32, complex128](1, 2)
+
+func f5[A, B, C any](A, []*B, struct{f []C}) int
+
+var _ = f5[int, float32, complex128](0, nil, struct{f []complex128}{})
+var _ = f5 /* ERROR cannot infer */ (0, nil, struct{f []complex128}{})
+var _ = f5(0, []*float32{new[float32]()}, struct{f []complex128}{})
+
+func f6[A any](A, []A) int
+
+var _ = f6(0, nil)
+
+func f6nil[A any](A) int
+
+var _ = f6nil /* ERROR cannot infer */ (nil)
+
+// type inference with variadic functions
+
+func f7[T any](...T) T
+
+var _ int = f7 /* ERROR cannot infer T */ ()
+var _ int = f7(1)
+var _ int = f7(1, 2)
+var _ int = f7([]int{}...)
+var _ int = f7 /* ERROR cannot use */ ([]float64{}...)
+var _ float64 = f7([]float64{}...)
+var _ = f7[float64](1, 2.3)
+var _ = f7(float64(1), 2.3)
+var _ = f7(1, 2.3 /* ERROR does not match */ )
+var _ = f7(1.2, 3 /* ERROR does not match */ )
+
+func f8[A, B any](A, B, ...B) int
+
+var _ = f8(1) /* ERROR not enough arguments */
+var _ = f8(1, 2.3)
+var _ = f8(1, 2.3, 3.4, 4.5)
+var _ = f8(1, 2.3, 3.4, 4 /* ERROR does not match */ )
+var _ = f8[int, float64](1, 2.3, 3.4, 4)
+
+var _ = f8[int, float64](0, 0, nil...) // test case for #18268
+
+// init functions cannot have type parameters
+
+func init() {}
+func init[/* ERROR func init must have no type parameters */ _ any]() {}
+func init[/* ERROR func init must have no type parameters */ P any]() {}
+
+type T struct {}
+
+func (T) m1() {}
+func (T) m2[ /* ERROR methods cannot have type parameters */ _ any]() {}
+func (T) m3[ /* ERROR methods cannot have type parameters */ P any]() {}
+
+// type inference across parameterized types
+
+type S1[P any] struct { f P }
+
+func f9[P any](x S1[P])
+
+func _() {
+        f9[int](S1[int]{42})
+	f9(S1[int]{42})
+}
+
+type S2[A, B, C any] struct{}
+
+func f10[X, Y, Z any](a S2[X, int, Z], b S2[X, Y, bool])
+
+func _[P any]() {
+        f10[int, float32, string](S2[int, int, string]{}, S2[int, float32, bool]{})
+        f10(S2[int, int, string]{}, S2[int, float32, bool]{})
+        f10(S2[P, int, P]{}, S2[P, float32, bool]{})
+}
+
+// corner case for type inference
+// (was bug: after instanting f11, the type-checker didn't mark f11 as non-generic)
+
+func f11[T any]()
+
+func _() {
+	f11[int]()
+}
+
+// the previous example was extracted from
+
+func f12[T interface{m() T}]()
+
+type A[T any] T
+
+func (a A[T]) m() A[T]
+
+func _[T any]() {
+	f12[A[T]]()
+}
+
+// method expressions
+
+func (_ S1[P]) m()
+
+func _() {
+	m := S1[int].m
+	m(struct { f int }{42})
+}
+
+func _[T any] (x T) {
+        m := S1[T].m
+        m(S1[T]{x})
+}
+
+// type parameters in methods (generalization)
+
+type R0 struct{}
+
+func (R0) _[ /* ERROR methods cannot have type parameters */ T any](x T)
+func (R0 /* ERROR invalid receiver */ ) _[ /* ERROR methods cannot have type parameters */ R0 any]() // scope of type parameters starts at "func"
+
+type R1[A, B any] struct{}
+
+func (_ R1[A, B]) m0(A, B)
+func (_ R1[A, B]) m1[ /* ERROR methods cannot have type parameters */ T any](A, B, T) T
+func (_ R1 /* ERROR not a generic type */ [R1, _]) _()
+func (_ R1[A, B]) _[ /* ERROR methods cannot have type parameters */ A /* ERROR redeclared */ any](B)
+
+func _() {
+        var r R1[int, string]
+        r.m1[rune](42, "foo", 'a')
+        r.m1[rune](42, "foo", 1.2 /* ERROR cannot use .* as rune .* \(truncated\) */)
+        r.m1(42, "foo", 1.2) // using type inference
+        var _ float64 = r.m1(42, "foo", 1.2)
+}
+
+type I1[A any] interface {
+        m1(A)
+}
+
+var _ I1[int] = r1[int]{}
+
+type r1[T any] struct{}
+
+func (_ r1[T]) m1(T)
+
+type I2[A, B any] interface {
+        m1(A)
+        m2(A) B
+}
+
+var _ I2[int, float32] = R2[int, float32]{}
+
+type R2[P, Q any] struct{}
+
+func (_ R2[X, Y]) m1(X)
+func (_ R2[X, Y]) m2(X) Y
+
+// type assertions and type switches over generic types
+// NOTE: These are currently disabled because it's unclear what the correct
+// approach is, and one can always work around by assigning the variable to
+// an interface first.
+
+// // ReadByte1 corresponds to the ReadByte example in the draft design.
+// func ReadByte1[T io.Reader](r T) (byte, error) {
+// 	if br, ok := r.(io.ByteReader); ok {
+// 		return br.ReadByte()
+// 	}
+// 	var b [1]byte
+// 	_, err := r.Read(b[:])
+// 	return b[0], err
+// }
+//
+// // ReadBytes2 is like ReadByte1 but uses a type switch instead.
+// func ReadByte2[T io.Reader](r T) (byte, error) {
+//         switch br := r.(type) {
+//         case io.ByteReader:
+//                 return br.ReadByte()
+//         }
+// 	var b [1]byte
+// 	_, err := r.Read(b[:])
+// 	return b[0], err
+// }
+//
+// // type assertions and type switches over generic types are strict
+// type I3 interface {
+//         m(int)
+// }
+//
+// type I4 interface {
+//         m() int // different signature from I3.m
+// }
+//
+// func _[T I3](x I3, p T) {
+//         // type assertions and type switches over interfaces are not strict
+//         _ = x.(I4)
+//         switch x.(type) {
+//         case I4:
+//         }
+// 
+//         // type assertions and type switches over generic types are strict
+//         _ = p /* ERROR cannot have dynamic type I4 */.(I4)
+//         switch p.(type) {
+//         case I4 /* ERROR cannot have dynamic type I4 */ :
+//         }
+// }
+
+// type assertions and type switches over generic types lead to errors for now
+
+func _[T any](x T) {
+	_ = x /* ERROR not an interface */ .(int)
+	switch x /* ERROR not an interface */ .(type) {
+	}
+
+	// work-around
+	var t interface{} = x
+	_ = t.(int)
+	switch t.(type) {
+	}
+}
+
+func _[T interface{type int}](x T) {
+	_ = x /* ERROR not an interface */ .(int)
+	switch x /* ERROR not an interface */ .(type) {
+	}
+
+	// work-around
+	var t interface{} = x
+	_ = t.(int)
+	switch t.(type) {
+	}
+}
+
+// error messages related to type bounds mention those bounds
+type C[P any] interface{}
+
+func _[P C[P]] (x P) {
+	x.m /* ERROR x.m undefined */ ()
+}
+
+type I interface {}
+
+func _[P I] (x P) {
+	x.m /* ERROR interface I has no method m */ ()
+}
+
+func _[P interface{}] (x P) {
+	x.m /* ERROR type bound for P has no method m */ ()
+}
+
+func _[P any] (x P) {
+	x.m /* ERROR type bound for P has no method m */ ()
+}
diff --git a/src/go/types/testdata/vardecl.src b/src/go/types/testdata/check/vardecl.src
similarity index 100%
rename from src/go/types/testdata/vardecl.src
rename to src/go/types/testdata/check/vardecl.src
diff --git a/src/go/types/testdata/const0.src b/src/go/types/testdata/const0.src
deleted file mode 100644
index adbbf28..0000000
--- a/src/go/types/testdata/const0.src
+++ /dev/null
@@ -1,350 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// constant declarations
-
-package const0
-
-import "unsafe"
-
-// constants declarations must be initialized by constants
-var x = 0
-const c0 = x /* ERROR "not constant" */
-
-// typed constants must have constant types
-const _ interface /* ERROR invalid constant type */ {} = 0
-
-func _ () {
-	const _ interface /* ERROR invalid constant type */ {} = 0
-	for i := 0; i < 10; i++ {} // don't crash with non-nil iota here
-}
-
-// untyped constants
-const (
-	// boolean values
-	ub0 = false
-	ub1 = true
-	ub2 = 2 < 1
-	ub3 = ui1 == uf1
-	ub4 = true /* ERROR "cannot convert" */ == 0
-
-	// integer values
-	ui0 = 0
-	ui1 = 1
-	ui2 = 42
-	ui3 = 3141592653589793238462643383279502884197169399375105820974944592307816406286
-	ui4 = -10
-
-	ui5 = ui0 + ui1
-	ui6 = ui1 - ui1
-	ui7 = ui2 * ui1
-	ui8 = ui3 / ui3
-	ui9 = ui3 % ui3
-
-	ui10 = 1 / 0 /* ERROR "division by zero" */
-	ui11 = ui1 / 0 /* ERROR "division by zero" */
-	ui12 = ui3 / ui0 /* ERROR "division by zero" */
-	ui13 = 1 % 0 /* ERROR "division by zero" */
-	ui14 = ui1 % 0 /* ERROR "division by zero" */
-	ui15 = ui3 % ui0 /* ERROR "division by zero" */
-
-	ui16 = ui2 & ui3
-	ui17 = ui2 | ui3
-	ui18 = ui2 ^ ui3
-	ui19 = 1 /* ERROR "invalid operation" */ % 1.0
-
-	// floating point values
-	uf0 = 0.
-	uf1 = 1.
-	uf2 = 4.2e1
-	uf3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286
-	uf4 = 1e-1
-
-	uf5 = uf0 + uf1
-	uf6 = uf1 - uf1
-	uf7 = uf2 * uf1
-	uf8 = uf3 / uf3
-	uf9 = uf3 /* ERROR "not defined" */ % uf3
-
-	uf10 = 1 / 0 /* ERROR "division by zero" */
-	uf11 = uf1 / 0 /* ERROR "division by zero" */
-	uf12 = uf3 / uf0 /* ERROR "division by zero" */
-
-	uf16 = uf2 /* ERROR "not defined" */ & uf3
-	uf17 = uf2 /* ERROR "not defined" */ | uf3
-	uf18 = uf2 /* ERROR "not defined" */ ^ uf3
-
-	// complex values
-	uc0 = 0.i
-	uc1 = 1.i
-	uc2 = 4.2e1i
-	uc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i
-	uc4 = 1e-1i
-
-	uc5 = uc0 + uc1
-	uc6 = uc1 - uc1
-	uc7 = uc2 * uc1
-	uc8 = uc3 / uc3
-	uc9 = uc3 /* ERROR "not defined" */ % uc3
-
-	uc10 = 1 / 0 /* ERROR "division by zero" */
-	uc11 = uc1 / 0 /* ERROR "division by zero" */
-	uc12 = uc3 / uc0 /* ERROR "division by zero" */
-
-	uc16 = uc2 /* ERROR "not defined" */ & uc3
-	uc17 = uc2 /* ERROR "not defined" */ | uc3
-	uc18 = uc2 /* ERROR "not defined" */ ^ uc3
-)
-
-type (
-	mybool bool
-	myint int
-	myfloat float64
-	mycomplex complex128
-)
-
-// typed constants
-const (
-	// boolean values
-	tb0 bool = false
-	tb1 bool = true
-	tb2 mybool = 2 < 1
-	tb3 mybool = ti1 /* ERROR "mismatched types" */ == tf1
-
-	// integer values
-	ti0 int8 = ui0
-	ti1 int32 = ui1
-	ti2 int64 = ui2
-	ti3 myint = ui3 /* ERROR "overflows" */
-	ti4 myint = ui4
-
-	ti5 = ti0 /* ERROR "mismatched types" */ + ti1
-	ti6 = ti1 - ti1
-	ti7 = ti2 /* ERROR "mismatched types" */ * ti1
-	ti8 = ti3 / ti3
-	ti9 = ti3 % ti3
-
-	ti10 = 1 / 0 /* ERROR "division by zero" */
-	ti11 = ti1 / 0 /* ERROR "division by zero" */
-	ti12 = ti3 /* ERROR "mismatched types" */ / ti0
-	ti13 = 1 % 0 /* ERROR "division by zero" */
-	ti14 = ti1 % 0 /* ERROR "division by zero" */
-	ti15 = ti3 /* ERROR "mismatched types" */ % ti0
-
-	ti16 = ti2 /* ERROR "mismatched types" */ & ti3
-	ti17 = ti2 /* ERROR "mismatched types" */ | ti4
-	ti18 = ti2 ^ ti5 // no mismatched types error because the type of ti5 is unknown
-
-	// floating point values
-	tf0 float32 = 0.
-	tf1 float32 = 1.
-	tf2 float64 = 4.2e1
-	tf3 myfloat = 3.141592653589793238462643383279502884197169399375105820974944592307816406286
-	tf4 myfloat = 1e-1
-
-	tf5 = tf0 + tf1
-	tf6 = tf1 - tf1
-	tf7 = tf2 /* ERROR "mismatched types" */ * tf1
-	tf8 = tf3 / tf3
-	tf9 = tf3 /* ERROR "not defined" */ % tf3
-
-	tf10 = 1 / 0 /* ERROR "division by zero" */
-	tf11 = tf1 / 0 /* ERROR "division by zero" */
-	tf12 = tf3 /* ERROR "mismatched types" */ / tf0
-
-	tf16 = tf2 /* ERROR "mismatched types" */ & tf3
-	tf17 = tf2 /* ERROR "mismatched types" */ | tf3
-	tf18 = tf2 /* ERROR "mismatched types" */ ^ tf3
-
-	// complex values
-	tc0 = 0.i
-	tc1 = 1.i
-	tc2 = 4.2e1i
-	tc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i
-	tc4 = 1e-1i
-
-	tc5 = tc0 + tc1
-	tc6 = tc1 - tc1
-	tc7 = tc2 * tc1
-	tc8 = tc3 / tc3
-	tc9 = tc3 /* ERROR "not defined" */ % tc3
-
-	tc10 = 1 / 0 /* ERROR "division by zero" */
-	tc11 = tc1 / 0 /* ERROR "division by zero" */
-	tc12 = tc3 / tc0 /* ERROR "division by zero" */
-
-	tc16 = tc2 /* ERROR "not defined" */ & tc3
-	tc17 = tc2 /* ERROR "not defined" */ | tc3
-	tc18 = tc2 /* ERROR "not defined" */ ^ tc3
-)
-
-// initialization cycles
-const (
-	a /* ERROR "initialization cycle" */ = a
-	b /* ERROR "initialization cycle" */ , c /* ERROR "initialization cycle" */, d, e = e, d, c, b // TODO(gri) should only have one cycle error
-	f float64 = d
-)
-
-// multiple initialization
-const (
-	a1, a2, a3 = 7, 3.1415926, "foo"
-	b1, b2, b3 = b3, b1, 42
-	c1, c2, c3  /* ERROR "missing init expr for c3" */ = 1, 2
-	d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */
-	_p0 = assert(a1 == 7)
-	_p1 = assert(a2 == 3.1415926)
-	_p2 = assert(a3 == "foo")
-	_p3 = assert(b1 == 42)
-	_p4 = assert(b2 == 42)
-	_p5 = assert(b3 == 42)
-)
-
-func _() {
-	const (
-		a1, a2, a3 = 7, 3.1415926, "foo"
-		b1, b2, b3 = b3, b1, 42
-		c1, c2, c3  /* ERROR "missing init expr for c3" */ = 1, 2
-		d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */
-		_p0 = assert(a1 == 7)
-		_p1 = assert(a2 == 3.1415926)
-		_p2 = assert(a3 == "foo")
-		_p3 = assert(b1 == 42)
-		_p4 = assert(b2 == 42)
-		_p5 = assert(b3 == 42)
-	)
-}
-
-// iota
-const (
-	iota0 = iota
-	iota1 = iota
-	iota2 = iota*2
-	_a0 = assert(iota0 == 0)
-	_a1 = assert(iota1 == 1)
-	_a2 = assert(iota2 == 4)
-	iota6 = iota*3
-
-	iota7
-	iota8
-	_a3 = assert(iota7 == 21)
-	_a4 = assert(iota8 == 24)
-)
-
-const (
-	_b0 = iota
-	_b1 = assert(iota + iota2 == 5)
-	_b2 = len([iota]int{}) // iota may appear in a type!
-	_b3 = assert(_b2 == 2)
-	_b4 = len(A{})
-)
-
-type A [iota /* ERROR "cannot use iota" */ ]int
-
-// constant expressions with operands across different
-// constant declarations must use the right iota values
-const (
-	_c0 = iota
-	_c1
-	_c2
-	_x = _c2 + _d1 + _e0 // 3
-)
-
-const (
-	_d0 = iota
-	_d1
-)
-
-const (
-	_e0 = iota
-)
-
-var _ = assert(_x == 3)
-
-// special cases
-const (
-	_n0 = nil /* ERROR "not constant" */
-	_n1 = [ /* ERROR "not constant" */ ]int{}
-)
-
-// iotas must not be usable in expressions outside constant declarations
-type _ [iota /* ERROR "iota outside constant decl" */ ]byte
-var _ = iota /* ERROR "iota outside constant decl" */
-func _() {
-	_ = iota /* ERROR "iota outside constant decl" */
-	const _ = iota
-	_ = iota /* ERROR "iota outside constant decl" */
-}
-
-func _() {
-	iota := 123
-	const x = iota /* ERROR "is not constant" */
-	var y = iota
-	_ = y
-}
-
-// iotas are usable inside closures in constant declarations (#22345)
-const (
-	_ = iota
-	_ = len([iota]byte{})
-	_ = unsafe.Sizeof(iota)
-	_ = unsafe.Sizeof(func() { _ = iota })
-	_ = unsafe.Sizeof(func() { var _ = iota })
-	_ = unsafe.Sizeof(func() { const _ = iota })
-	_ = unsafe.Sizeof(func() { type _ [iota]byte })
-	_ = unsafe.Sizeof(func() { func() int { return iota }() })
-)
-
-// verify inner and outer const declarations have distinct iotas
-const (
-	zero = iota
-	one  = iota
-	_    = unsafe.Sizeof(func() {
-		var x [iota]int // [2]int
-		const (
-			Zero = iota
-			One
-			Two
-			_ = unsafe.Sizeof([iota-1]int{} == x) // assert types are equal
-			_ = unsafe.Sizeof([Two]int{} == x)    // assert types are equal
-		)
-		var z [iota]int                           // [2]int
-		_ = unsafe.Sizeof([2]int{} == z)          // assert types are equal
-	})
-	three = iota // the sequence continues
-)
-var _ [three]int = [3]int{} // assert 'three' has correct value
-
-var (
-	_ = iota /* ERROR "iota outside constant decl" */
-	_ = unsafe.Sizeof(iota  /* ERROR "iota outside constant decl" */ )
-	_ = unsafe.Sizeof(func() { _ = iota /* ERROR "iota outside constant decl" */ })
-	_ = unsafe.Sizeof(func() { var _ = iota /* ERROR "iota outside constant decl" */ })
-	_ = unsafe.Sizeof(func() { type _ [iota /* ERROR "iota outside constant decl" */ ]byte })
-	_ = unsafe.Sizeof(func() { func() int { return iota /* ERROR "iota outside constant decl" */ }() })
-)
-
-// constant arithmetic precision and rounding must lead to expected (integer) results
-var _ = []int64{
-	0.0005 * 1e9,
-	0.001 * 1e9,
-	0.005 * 1e9,
-	0.01 * 1e9,
-	0.05 * 1e9,
-	0.1 * 1e9,
-	0.5 * 1e9,
-	1 * 1e9,
-	5 * 1e9,
-}
-
-const _ = unsafe.Sizeof(func() {
-	const _ = 0
-	_ = iota
-
-	const (
-	   zero = iota
-	   one
-	)
-	assert(one == 1)
-	assert(iota == 0)
-})
diff --git a/src/go/types/testdata/const1.src b/src/go/types/testdata/const1.src
deleted file mode 100644
index d827704..0000000
--- a/src/go/types/testdata/const1.src
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// constant conversions
-
-package const1
-
-const(
-	mi = ^int(0)
-	mu = ^uint(0)
-	mp = ^uintptr(0)
-
-	logSizeofInt     = uint(mi>>8&1 + mi>>16&1 + mi>>32&1)
-	logSizeofUint    = uint(mu>>8&1 + mu>>16&1 + mu>>32&1)
-	logSizeofUintptr = uint(mp>>8&1 + mp>>16&1 + mp>>32&1)
-)
-
-const (
-	minInt8 = -1<<(8<<iota - 1)
-	minInt16
-	minInt32
-	minInt64
-	minInt = -1<<(8<<logSizeofInt - 1)
-)
-
-const (
-	maxInt8 = 1<<(8<<iota - 1) - 1
-	maxInt16
-	maxInt32
-	maxInt64
-	maxInt = 1<<(8<<logSizeofInt - 1) - 1
-)
-
-const (
-	maxUint8 = 1<<(8<<iota) - 1
-	maxUint16
-	maxUint32
-	maxUint64
-	maxUint    = 1<<(8<<logSizeofUint) - 1
-	maxUintptr = 1<<(8<<logSizeofUintptr) - 1
-)
-
-const (
-	smallestFloat32 = 1.0 / (1<<(127 - 1 + 23))
-	smallestFloat64 = 1.0 / (1<<(1023 - 1 + 52))
-)
-
-const (
-	_ = assert(smallestFloat32 > 0)
-	_ = assert(smallestFloat64 > 0)
-)
-
-const (
-	maxFloat32 = 1<<127 * (1<<24 - 1) / (1.0<<23)
-	maxFloat64 = 1<<1023 * (1<<53 - 1) / (1.0<<52)
-)
-
-const (
-	_ int8 = minInt8 /* ERROR "overflows" */ - 1
-	_ int8 = minInt8
-	_ int8 = maxInt8
-	_ int8 = maxInt8 /* ERROR "overflows" */ + 1
-	_ int8 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = int8(minInt8 /* ERROR "cannot convert" */ - 1)
-	_ = int8(minInt8)
-	_ = int8(maxInt8)
-	_ = int8(maxInt8 /* ERROR "cannot convert" */ + 1)
-	_ = int8(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ int16 = minInt16 /* ERROR "overflows" */ - 1
-	_ int16 = minInt16
-	_ int16 = maxInt16
-	_ int16 = maxInt16 /* ERROR "overflows" */ + 1
-	_ int16 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = int16(minInt16 /* ERROR "cannot convert" */ - 1)
-	_ = int16(minInt16)
-	_ = int16(maxInt16)
-	_ = int16(maxInt16 /* ERROR "cannot convert" */ + 1)
-	_ = int16(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ int32 = minInt32 /* ERROR "overflows" */ - 1
-	_ int32 = minInt32
-	_ int32 = maxInt32
-	_ int32 = maxInt32 /* ERROR "overflows" */ + 1
-	_ int32 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = int32(minInt32 /* ERROR "cannot convert" */ - 1)
-	_ = int32(minInt32)
-	_ = int32(maxInt32)
-	_ = int32(maxInt32 /* ERROR "cannot convert" */ + 1)
-	_ = int32(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ int64 = minInt64 /* ERROR "overflows" */ - 1
-	_ int64 = minInt64
-	_ int64 = maxInt64
-	_ int64 = maxInt64 /* ERROR "overflows" */ + 1
-	_ int64 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = int64(minInt64 /* ERROR "cannot convert" */ - 1)
-	_ = int64(minInt64)
-	_ = int64(maxInt64)
-	_ = int64(maxInt64 /* ERROR "cannot convert" */ + 1)
-	_ = int64(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ int = minInt /* ERROR "overflows" */ - 1
-	_ int = minInt
-	_ int = maxInt
-	_ int = maxInt /* ERROR "overflows" */ + 1
-	_ int = smallestFloat64 /* ERROR "truncated" */
-
-	_ = int(minInt /* ERROR "cannot convert" */ - 1)
-	_ = int(minInt)
-	_ = int(maxInt)
-	_ = int(maxInt /* ERROR "cannot convert" */ + 1)
-	_ = int(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ uint8 = 0 /* ERROR "overflows" */ - 1
-	_ uint8 = 0
-	_ uint8 = maxUint8
-	_ uint8 = maxUint8 /* ERROR "overflows" */ + 1
-	_ uint8 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = uint8(0 /* ERROR "cannot convert" */ - 1)
-	_ = uint8(0)
-	_ = uint8(maxUint8)
-	_ = uint8(maxUint8 /* ERROR "cannot convert" */ + 1)
-	_ = uint8(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ uint16 = 0 /* ERROR "overflows" */ - 1
-	_ uint16 = 0
-	_ uint16 = maxUint16
-	_ uint16 = maxUint16 /* ERROR "overflows" */ + 1
-	_ uint16 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = uint16(0 /* ERROR "cannot convert" */ - 1)
-	_ = uint16(0)
-	_ = uint16(maxUint16)
-	_ = uint16(maxUint16 /* ERROR "cannot convert" */ + 1)
-	_ = uint16(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ uint32 = 0 /* ERROR "overflows" */ - 1
-	_ uint32 = 0
-	_ uint32 = maxUint32
-	_ uint32 = maxUint32 /* ERROR "overflows" */ + 1
-	_ uint32 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = uint32(0 /* ERROR "cannot convert" */ - 1)
-	_ = uint32(0)
-	_ = uint32(maxUint32)
-	_ = uint32(maxUint32 /* ERROR "cannot convert" */ + 1)
-	_ = uint32(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ uint64 = 0 /* ERROR "overflows" */ - 1
-	_ uint64 = 0
-	_ uint64 = maxUint64
-	_ uint64 = maxUint64 /* ERROR "overflows" */ + 1
-	_ uint64 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = uint64(0 /* ERROR "cannot convert" */ - 1)
-	_ = uint64(0)
-	_ = uint64(maxUint64)
-	_ = uint64(maxUint64 /* ERROR "cannot convert" */ + 1)
-	_ = uint64(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ uint = 0 /* ERROR "overflows" */ - 1
-	_ uint = 0
-	_ uint = maxUint
-	_ uint = maxUint /* ERROR "overflows" */ + 1
-	_ uint = smallestFloat64 /* ERROR "truncated" */
-
-	_ = uint(0 /* ERROR "cannot convert" */ - 1)
-	_ = uint(0)
-	_ = uint(maxUint)
-	_ = uint(maxUint /* ERROR "cannot convert" */ + 1)
-	_ = uint(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ uintptr = 0 /* ERROR "overflows" */ - 1
-	_ uintptr = 0
-	_ uintptr = maxUintptr
-	_ uintptr = maxUintptr /* ERROR "overflows" */ + 1
-	_ uintptr = smallestFloat64 /* ERROR "truncated" */
-
-	_ = uintptr(0 /* ERROR "cannot convert" */ - 1)
-	_ = uintptr(0)
-	_ = uintptr(maxUintptr)
-	_ = uintptr(maxUintptr /* ERROR "cannot convert" */ + 1)
-	_ = uintptr(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ float32 = minInt64
-	_ float64 = minInt64
-	_ complex64 = minInt64
-	_ complex128 = minInt64
-
-	_ = float32(minInt64)
-	_ = float64(minInt64)
-	_ = complex64(minInt64)
-	_ = complex128(minInt64)
-)
-
-const (
-	_ float32 = maxUint64
-	_ float64 = maxUint64
-	_ complex64 = maxUint64
-	_ complex128 = maxUint64
-
-	_ = float32(maxUint64)
-	_ = float64(maxUint64)
-	_ = complex64(maxUint64)
-	_ = complex128(maxUint64)
-)
-
-// TODO(gri) find smaller deltas below
-
-const delta32 = maxFloat32/(1 << 23)
-
-const (
-	_ float32 = - /* ERROR "overflow" */ (maxFloat32 + delta32)
-	_ float32 = -maxFloat32
-	_ float32 = maxFloat32
-	_ float32 = maxFloat32 /* ERROR "overflow" */ + delta32
-
-	_ = float32(- /* ERROR "cannot convert" */ (maxFloat32 + delta32))
-	_ = float32(-maxFloat32)
-	_ = float32(maxFloat32)
-	_ = float32(maxFloat32 /* ERROR "cannot convert" */ + delta32)
-
-	_ = assert(float32(smallestFloat32) == smallestFloat32)
-	_ = assert(float32(smallestFloat32/2) == 0)
-	_ = assert(float32(smallestFloat64) == 0)
-	_ = assert(float32(smallestFloat64/2) == 0)
-)
-
-const delta64 = maxFloat64/(1 << 52)
-
-const (
-	_ float64 = - /* ERROR "overflow" */ (maxFloat64 + delta64)
-	_ float64 = -maxFloat64
-	_ float64 = maxFloat64
-	_ float64 = maxFloat64 /* ERROR "overflow" */ + delta64
-
-	_ = float64(- /* ERROR "cannot convert" */ (maxFloat64 + delta64))
-	_ = float64(-maxFloat64)
-	_ = float64(maxFloat64)
-	_ = float64(maxFloat64 /* ERROR "cannot convert" */ + delta64)
-
-	_ = assert(float64(smallestFloat32) == smallestFloat32)
-	_ = assert(float64(smallestFloat32/2) == smallestFloat32/2)
-	_ = assert(float64(smallestFloat64) == smallestFloat64)
-	_ = assert(float64(smallestFloat64/2) == 0)
-)
-
-const (
-	_ complex64 = - /* ERROR "overflow" */ (maxFloat32 + delta32)
-	_ complex64 = -maxFloat32
-	_ complex64 = maxFloat32
-	_ complex64 = maxFloat32 /* ERROR "overflow" */ + delta32
-
-	_ = complex64(- /* ERROR "cannot convert" */ (maxFloat32 + delta32))
-	_ = complex64(-maxFloat32)
-	_ = complex64(maxFloat32)
-	_ = complex64(maxFloat32 /* ERROR "cannot convert" */ + delta32)
-)
-
-const (
-	_ complex128 = - /* ERROR "overflow" */ (maxFloat64 + delta64)
-	_ complex128 = -maxFloat64
-	_ complex128 = maxFloat64
-	_ complex128 = maxFloat64 /* ERROR "overflow" */ + delta64
-
-	_ = complex128(- /* ERROR "cannot convert" */ (maxFloat64 + delta64))
-	_ = complex128(-maxFloat64)
-	_ = complex128(maxFloat64)
-	_ = complex128(maxFloat64 /* ERROR "cannot convert" */ + delta64)
-)
-
-// Initialization of typed constant and conversion are the same:
-const (
-	f32 = 1 + smallestFloat32
-	x32 float32 = f32
-	y32 = float32(f32)
-	_ = assert(x32 - y32 == 0)
-)
-
-const (
-	f64 = 1 + smallestFloat64
-	x64 float64 = f64
-	y64 = float64(f64)
-	_ = assert(x64 - y64 == 0)
-)
-
-const (
-	_ = int8(-1) << 7
-	_ = int8 /* ERROR "overflows" */ (-1) << 8
-
-	_ = uint32(1) << 31
-	_ = uint32 /* ERROR "overflows" */ (1) << 32
-)
diff --git a/src/go/types/testdata/decls0.src b/src/go/types/testdata/decls0.src
deleted file mode 100644
index 5501b65..0000000
--- a/src/go/types/testdata/decls0.src
+++ /dev/null
@@ -1,206 +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.
-
-// type declarations
-
-package decls0
-
-import "unsafe"
-
-const pi = 3.1415
-
-type (
-	N undeclared /* ERROR "undeclared" */
-	B bool
-	I int32
-	A [10]P
-	T struct {
-		x, y P
-	}
-	P *T
-	R (*R)
-	F func(A) I
-	Y interface {
-		f(A) I
-	}
-	S [](((P)))
-	M map[I]F
-	C chan<- I
-
-	// blank types must be typechecked
-	_ pi /* ERROR "not a type" */
-	_ struct{}
-	_ struct{ pi /* ERROR "not a type" */ }
-)
-
-
-// declarations of init
-const _, init /* ERROR "cannot declare init" */ , _ = 0, 1, 2
-type init /* ERROR "cannot declare init" */ struct{}
-var _, init /* ERROR "cannot declare init" */ int
-
-func init() {}
-func init /* ERROR "missing function body" */ ()
-
-func _() { const init = 0 }
-func _() { type init int }
-func _() { var init int; _ = init }
-
-// invalid array types
-type (
-	iA0 [... /* ERROR "invalid use of '...'" */ ]byte
-	// The error message below could be better. At the moment
-	// we believe an integer that is too large is not an integer.
-	// But at least we get an error.
-	iA1 [1 /* ERROR "must be integer" */ <<100]int
-	iA2 [- /* ERROR "invalid array length" */ 1]complex128
-	iA3 ["foo" /* ERROR "must be integer" */ ]string
-	iA4 [float64 /* ERROR "must be integer" */ (0)]int
-)
-
-
-type (
-	p1 pi.foo /* ERROR "no field or method foo" */
-	p2 unsafe.Pointer
-)
-
-
-type (
-	Pi pi /* ERROR "not a type" */
-
-	a /* ERROR "illegal cycle" */ a
-	a /* ERROR "redeclared" */ int
-
-	b /* ERROR "illegal cycle" */ c
-	c d
-	d e
-	e b
-
-	t *t
-
-	U V
-	V *W
-	W U
-
-	P1 *S2
-	P2 P1
-
-	S0 struct {
-	}
-	S1 struct {
-		a, b, c int
-		u, v, a /* ERROR "redeclared" */ float32
-	}
-	S2 struct {
-		S0 // embedded field
-		S0 /* ERROR "redeclared" */ int
-	}
-	S3 struct {
-		x S2
-	}
-	S4/* ERROR "illegal cycle" */ struct {
-		S4
-	}
-	S5 /* ERROR "illegal cycle" */ struct {
-		S6
-	}
-	S6 struct {
-		field S7
-	}
-	S7 struct {
-		S5
-	}
-
-	L1 []L1
-	L2 []int
-
-	A1 [10.0]int
-	A2 /* ERROR "illegal cycle" */ [10]A2
-	A3 /* ERROR "illegal cycle" */ [10]struct {
-		x A4
-	}
-	A4 [10]A3
-
-	F1 func()
-	F2 func(x, y, z float32)
-	F3 func(x, y, x /* ERROR "redeclared" */ float32)
-	F4 func() (x, y, x /* ERROR "redeclared" */ float32)
-	F5 func(x int) (x /* ERROR "redeclared" */ float32)
-	F6 func(x ...int)
-
-	I1 interface{}
-	I2 interface {
-		m1()
-	}
-	I3 interface {
-		m1()
-		m1 /* ERROR "duplicate method" */ ()
-	}
-	I4 interface {
-		m1(x, y, x /* ERROR "redeclared" */ float32)
-		m2() (x, y, x /* ERROR "redeclared" */ float32)
-		m3(x int) (x /* ERROR "redeclared" */ float32)
-	}
-	I5 interface {
-		m1(I5)
-	}
-	I6 interface {
-		S0 /* ERROR "not an interface" */
-	}
-	I7 interface {
-		I1
-		I1
-	}
-	I8 /* ERROR "illegal cycle" */ interface {
-		I8
-	}
-	I9 /* ERROR "illegal cycle" */ interface {
-		I10
-	}
-	I10 interface {
-		I11
-	}
-	I11 interface {
-		I9
-	}
-
-	C1 chan int
-	C2 <-chan int
-	C3 chan<- C3
-	C4 chan C5
-	C5 chan C6
-	C6 chan C4
-
-	M1 map[Last]string
-	M2 map[string]M2
-
-	Last int
-)
-
-// cycles in function/method declarations
-// (test cases for issues #5217, #25790 and variants)
-func f1(x f1 /* ERROR "not a type" */ ) {}
-func f2(x *f2 /* ERROR "not a type" */ ) {}
-func f3() (x f3 /* ERROR "not a type" */ ) { return }
-func f4() (x *f4 /* ERROR "not a type" */ ) { return }
-
-func (S0) m1 /* ERROR illegal cycle */ (x S0 /* ERROR value .* is not a type */ .m1) {}
-func (S0) m2 /* ERROR illegal cycle */ (x *S0 /* ERROR value .* is not a type */ .m2) {}
-func (S0) m3 /* ERROR illegal cycle */ () (x S0 /* ERROR value .* is not a type */ .m3) { return }
-func (S0) m4 /* ERROR illegal cycle */ () (x *S0 /* ERROR value .* is not a type */ .m4) { return }
-
-// interfaces may not have any blank methods
-type BlankI interface {
-	_ /* ERROR "invalid method name" */ ()
-	_ /* ERROR "invalid method name" */ (float32) int
-	m()
-}
-
-// non-interface types may have multiple blank methods
-type BlankT struct{}
-
-func (BlankT) _() {}
-func (BlankT) _(int) {}
-func (BlankT) _() int { return 0 }
-func (BlankT) _(int) int { return 0}
diff --git a/src/go/types/testdata/examples/functions.go2 b/src/go/types/testdata/examples/functions.go2
new file mode 100644
index 0000000..a053471
--- /dev/null
+++ b/src/go/types/testdata/examples/functions.go2
@@ -0,0 +1,214 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file shows some examples of type-parameterized functions.
+
+package p
+
+// Reverse is a generic function that takes a []T argument and
+// reverses that slice in place.
+func Reverse[T any](list []T) {
+	i := 0
+	j := len(list)-1
+	for i < j {
+		list[i], list[j] = list[j], list[i]
+		i++
+		j--
+	}
+}
+
+func _() {
+	// Reverse can be called with an explicit type argument.
+	Reverse[int](nil)
+	Reverse[string]([]string{"foo", "bar"})
+	Reverse[struct{x, y int}]([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})
+
+	// Since the type parameter is used for an incoming argument,
+	// it can be inferred from the provided argument's type.
+	Reverse([]string{"foo", "bar"})
+	Reverse([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})
+
+	// But the incoming argument must have a type, even if it's a
+	// default type. An untyped nil won't work.
+	// Reverse(nil) // this won't type-check
+
+	// A typed nil will work, though.
+	Reverse([]int(nil))
+}
+
+// Certain functions, such as the built-in `new` could be written using
+// type parameters.
+func new[T any]() *T {
+	var x T
+	return &x
+}
+
+// When calling our own `new`, we need to pass the type parameter
+// explicitly since there is no (value) argument from which the
+// result type could be inferred. We don't try to infer the
+// result type from the assignment to keep things simple and
+// easy to understand.
+var _ = new[int]()
+var _ *float64 = new[float64]() // the result type is indeed *float64
+
+// A function may have multiple type parameters, of course.
+func foo[A, B, C any](a A, b []B, c *C) B {
+	// do something here
+	return b[0]
+}
+
+// As before, we can pass type parameters explicitly.
+var s = foo[int, string, float64](1, []string{"first"}, new[float64]())
+
+// Or we can use type inference.
+var _ float64 = foo(42, []float64{1.0}, &s)
+
+// Type inference works in a straight-forward manner even
+// for variadic functions.
+func variadic[A, B any](A, B, ...B) int
+
+// var _ = variadic(1) // ERROR not enough arguments
+var _ = variadic(1, 2.3)
+var _ = variadic(1, 2.3, 3.4, 4.5)
+var _ = variadic[int, float64](1, 2.3, 3.4, 4)
+
+// Type inference also works in recursive function calls where
+// the inferred type is the type parameter of the caller.
+func f1[T any](x T) {
+	f1(x)
+}
+
+func f2a[T any](x, y T) {
+	f2a(x, y)
+}
+
+func f2b[T any](x, y T) {
+	f2b(y, x)
+}
+
+func g2a[P, Q any](x P, y Q) {
+	g2a(x, y)
+}
+
+func g2b[P, Q any](x P, y Q) {
+	g2b(y, x)
+}
+
+// Here's an example of a recursive function call with variadic
+// arguments and type inference inferring the type parameter of
+// the caller (i.e., itself).
+func max[T interface{ type int }](x ...T) T {
+	var x0 T
+	if len(x) > 0 {
+		x0 = x[0]
+	}
+	if len(x) > 1 {
+		x1 := max(x[1:]...)
+		if x1 > x0 {
+			return x1
+		}
+	}
+	return x0
+}
+
+// When inferring channel types, the channel direction is ignored
+// for the purpose of type inference. Once the type has been in-
+// fered, the usual parameter passing rules are applied.
+// Thus even if a type can be inferred successfully, the function
+// call may not be valid.
+
+func fboth[T any](chan T)
+func frecv[T any](<-chan T)
+func fsend[T any](chan<- T)
+
+func _() {
+	var both chan int
+	var recv <-chan int
+	var send chan<-int
+
+	fboth(both)
+	fboth(recv /* ERROR cannot use */ )
+	fboth(send /* ERROR cannot use */ )
+
+	frecv(both)
+	frecv(recv)
+	frecv(send /* ERROR cannot use */ )
+
+	fsend(both)
+	fsend(recv /* ERROR cannot use */)
+	fsend(send)
+}
+
+func ffboth[T any](func(chan T))
+func ffrecv[T any](func(<-chan T))
+func ffsend[T any](func(chan<- T))
+
+func _() {
+	var both func(chan int)
+	var recv func(<-chan int)
+	var send func(chan<- int)
+
+	ffboth(both)
+	ffboth(recv /* ERROR cannot use */ )
+	ffboth(send /* ERROR cannot use */ )
+
+	ffrecv(both /* ERROR cannot use */ )
+	ffrecv(recv)
+	ffrecv(send /* ERROR cannot use */ )
+
+	ffsend(both /* ERROR cannot use */ )
+	ffsend(recv /* ERROR cannot use */ )
+	ffsend(send)
+}
+
+// When inferring elements of unnamed composite parameter types,
+// if the arguments are defined types, use their underlying types.
+// Even though the matching types are not exactly structurally the
+// same (one is a type literal, the other a named type), because
+// assignment is permitted, parameter passing is permitted as well,
+// so type inference should be able to handle these cases well.
+
+func g1[T any]([]T)
+func g2[T any]([]T, T)
+func g3[T any](*T, ...T)
+
+func _() {
+	type intSlize []int
+	g1([]int{})
+	g1(intSlize{})
+	g2(nil, 0)
+
+	type myString string
+	var s1 string
+	g3(nil, "1", myString("2"), "3")
+	g3(&s1, "1", myString /* ERROR does not match */ ("2"), "3")
+
+	type myStruct struct{x int}
+	var s2 myStruct
+	g3(nil, struct{x int}{}, myStruct{})
+	g3(&s2, struct{x int}{}, myStruct{})
+	g3(nil, myStruct{}, struct{x int}{})
+	g3(&s2, myStruct{}, struct{x int}{})
+}
+
+// Here's a realistic example.
+
+func append[T any](s []T, t ...T) []T
+
+func _() {
+	var f func()
+	type Funcs []func()
+	var funcs Funcs
+	_ = append(funcs, f)
+}
+
+// Generic type declarations cannot have empty type parameter lists
+// (that would indicate a slice type). Thus, generic functions cannot
+// have empty type parameter lists, either. This is a syntax error.
+
+func h[] /* ERROR empty type parameter list */ ()
+
+func _() {
+	h /* ERROR cannot index */ [] /* ERROR operand */ ()
+}
diff --git a/src/go/types/testdata/examples/inference.go2 b/src/go/types/testdata/examples/inference.go2
new file mode 100644
index 0000000..b4f3369
--- /dev/null
+++ b/src/go/types/testdata/examples/inference.go2
@@ -0,0 +1,101 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file shows some examples of type inference.
+
+package p
+
+type Ordered interface {
+	type int, float64, string
+}
+
+func min[T Ordered](x, y T) T
+
+func _() {
+	// min can be called with explicit instantiation.
+	_ = min[int](1, 2)
+
+	// Alternatively, the type argument can be inferred from
+	// one of the arguments. Untyped arguments will be considered
+	// last.
+	var x int
+	_ = min(x, x)
+	_ = min(x, 1)
+	_ = min(x, 1.0)
+	_ = min(1, 2)
+	_ = min(1, 2.3 /* ERROR default type float64 .* does not match */ )
+
+	var y float64
+	_ = min(1, y)
+	_ = min(1.2, y)
+	_ = min(1.2, 3.4)
+	_ = min(1.2, 3 /* ERROR default type int .* does not match */ )
+
+	var s string
+	_ = min(s, "foo")
+	_ = min("foo", "bar")
+}
+
+func mixed[T1, T2, T3 any](T1, T2, T3)
+
+func _() {
+	// mixed can be called with explicit instantiation.
+	mixed[int, string, bool](0, "", false)
+
+	// Alternatively, partial type arguments may be provided
+	// (from left to right), and the other may be inferred.
+	mixed[int, string](0, "", false)
+	mixed[int](0, "", false)
+	mixed(0, "", false)
+
+	// Provided type arguments always take precedence over
+	// inferred types.
+	mixed[int, string](1.1 /* ERROR cannot use 1.1 */ , "", false)
+}
+
+func related1[Slice interface{type []Elem}, Elem any](s Slice, e Elem)
+
+func _() {
+	// related1 can be called with explicit instantiation.
+	var si []int
+	related1[[]int, int](si, 0)
+
+	// Alternatively, the 2nd type argument can be inferred
+	// from the first one through constraint type inference.
+	var ss []string
+	_ = related1[[]string]
+	related1[[]string](ss, "foo")
+
+	// A type argument inferred from another explicitly provided
+	// type argument overrides whatever value argument type is given.
+	related1[[]string](ss, 0 /* ERROR cannot use 0 */ )
+
+	// A type argument may be inferred from a value argument
+	// and then help infer another type argument via constraint
+	// type inference.
+	related1(si, 0)
+	related1(si, "foo" /* ERROR cannot use "foo" */ )
+}
+
+func related2[Elem any, Slice interface{type []Elem}](e Elem, s Slice)
+
+func _() {
+	// related2 can be called with explicit instantiation.
+	var si []int
+	related2[int, []int](0, si)
+
+	// Alternatively, the 2nd type argument can be inferred
+	// from the first one through constraint type inference.
+	var ss []string
+	_ = related2[string]
+	related2[string]("foo", ss)
+
+	// A type argument may be inferred from a value argument
+	// and then help infer another type argument via constraint
+	// type inference. Untyped arguments are always considered
+	// last.
+	related2(1.2, []float64{})
+	related2(1.0, []int{})
+	related2 /* ERROR does not satisfy */ (float64(1.0), []int{})
+}
diff --git a/src/go/types/testdata/examples/methods.go2 b/src/go/types/testdata/examples/methods.go2
new file mode 100644
index 0000000..76c6539
--- /dev/null
+++ b/src/go/types/testdata/examples/methods.go2
@@ -0,0 +1,96 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file shows some examples of methods on type-parameterized types.
+
+package p
+
+// Parameterized types may have methods.
+type T1[A any] struct{ a A }
+
+// When declaring a method for a parameterized type, the "instantiated"
+// receiver type acts as an implicit declaration of the type parameters
+// for the receiver type. In the example below, method m1 on type T1 has
+// the receiver type T1[A] which declares the type parameter A for use
+// with this method. That is, within the method m1, A stands for the
+// actual type argument provided to an instantiated T1.
+func (t T1[A]) m1() A { return t.a }
+
+// For instance, if T1 is instantiated with the type int, the type
+// parameter A in m1 assumes that type (int) as well and we can write
+// code like this:
+var x T1[int]
+var _ int = x.m1()
+
+// Because the type parameter provided to a parameterized receiver type
+// is declared through that receiver declaration, it must be an identifier.
+// It cannot possibly be some other type because the receiver type is not
+// instantiated with concrete types, it is standing for the parameterized
+// receiver type.
+func (t T1[[ /* ERROR must be an identifier */ ]int]) m2() {}
+
+// Note that using what looks like a predeclared identifier, say int,
+// as type parameter in this situation is deceptive and considered bad
+// style. In m3 below, int is the name of the local receiver type parameter
+// and it shadows the predeclared identifier int which then cannot be used
+// anymore as expected.
+// This is no different from locally redelaring a predeclared identifier
+// and usually should be avoided. There are some notable exceptions; e.g.,
+// sometimes it makes sense to use the identifier "copy" which happens to
+// also be the name of a predeclared built-in function.
+func (t T1[int]) m3() { var _ int = 42 /* ERROR cannot use 42 .* as int */ }
+
+// The names of the type parameters used in a parameterized receiver
+// type don't have to match the type parameter names in the declaration
+// of the type used for the receiver. In our example, even though T1 is
+// declared with type parameter named A, methods using that receiver type
+// are free to use their own name for that type parameter. That is, the
+// name of type parameters is always local to the declaration where they
+// are introduced. In our example we can write a method m2 and use the
+// name X instead of A for the type parameter w/o any difference.
+func (t T1[X]) m4() X { return t.a }
+
+// If the receiver type is parameterized, type parameters must always be
+// provided: this simply follows from the general rule that a parameterized
+// type must be instantiated before it can be used. A method receiver
+// declaration using a parameterized receiver type is no exception. It is
+// simply that such receiver type expressions perform two tasks simultaneously:
+// they declare the (local) type parameters and then use them to instantiate
+// the receiver type. Forgetting to provide a type parameter leads to an error.
+func (t T1 /* ERROR generic type .* without instantiation */ ) m5() {}
+
+// However, sometimes we don't need the type parameter, and thus it is
+// inconvenient to have to choose a name. Since the receiver type expression
+// serves as a declaration for its type parameters, we are free to choose the
+// blank identifier:
+func (t T1[_]) m6() {}
+
+// Naturally, these rules apply to any number of type parameters on the receiver
+// type. Here are some more complex examples.
+type T2[A, B, C any] struct {
+        a A
+        b B
+        c C
+}
+
+// Naming of the type parameters is local and has no semantic impact:
+func (t T2[A, B, C]) m1() (A, B, C) { return t.a, t.b, t.c }
+func (t T2[C, B, A]) m2() (C, B, A) { return t.a, t.b, t.c }
+func (t T2[X, Y, Z]) m3() (X, Y, Z) { return t.a, t.b, t.c }
+
+// Type parameters may be left blank if they are not needed:
+func (t T2[A, _, C]) m4() (A, C) { return t.a, t.c }
+func (t T2[_, _, X]) m5() X { return t.c }
+func (t T2[_, _, _]) m6() {}
+
+// As usual, blank names may be used for any object which we don't care about
+// using later. For instance, we may write an unnamed method with a receiver
+// that cannot be accessed:
+func (_ T2[_, _, _]) _() int { return 42 }
+
+// Because a receiver parameter list is simply a parameter list, we can
+// leave the receiver argument away for receiver types.
+type T0 struct{}
+func (T0) _() {}
+func (T1[A]) _() {}
diff --git a/src/go/types/testdata/examples/types.go2 b/src/go/types/testdata/examples/types.go2
new file mode 100644
index 0000000..59c8804
--- /dev/null
+++ b/src/go/types/testdata/examples/types.go2
@@ -0,0 +1,286 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file shows some examples of generic types.
+
+package p
+
+// List is just what it says - a slice of E elements.
+type List[E any] []E
+
+// A generic (parameterized) type must always be instantiated
+// before it can be used to designate the type of a variable
+// (including a struct field, or function parameter); though
+// for the latter cases, the provided type may be another type
+// parameter. So:
+var _ List[byte] = []byte{}
+
+// A generic binary tree might be declared as follows.
+type Tree[E any] struct {
+	left, right *Tree[E]
+	payload E
+}
+
+// A simple instantiation of Tree:
+var root1 Tree[int]
+
+// The actual type parameter provided may be a generic type itself:
+var root2 Tree[List[int]]
+
+// A couple of more complex examples.
+// We don't need extra parentheses around the element type of the slices on
+// the right (unlike when we use ()'s rather than []'s for type parameters).
+var _ List[List[int]] = []List[int]{}
+var _ List[List[List[Tree[int]]]] = []List[List[Tree[int]]]{}
+
+// Type parameters act like type aliases when used in generic types
+// in the sense that we can "emulate" a specific type instantiation
+// with type aliases.
+type T1[P any] struct {
+	f P
+}
+
+type T2[P any] struct {
+	f struct {
+		g P
+	}
+}
+
+var x1 T1[struct{ g int }]
+var x2 T2[int]
+
+func _() {
+	// This assignment is invalid because the types of x1, x2 are T1(...)
+	// and T2(...) respectively, which are two different defined types.
+	x1 = x2 // ERROR assignment
+
+	// This assignment is valid because the types of x1.f and x2.f are
+	// both struct { g int }; the type parameters act like type aliases
+	// and their actual names don't come into play here.
+	x1.f = x2.f
+}
+
+// We can verify this behavior using type aliases instead:
+type T1a struct {
+	f A1
+}
+type A1 = struct { g int }
+
+type T2a struct {
+	f struct {
+		g A2
+	}
+}
+type A2 = int
+
+var x1a T1a
+var x2a T2a
+
+func _() {
+	x1a = x2a // ERROR assignment
+	x1a.f = x2a.f
+}
+
+// Another interesting corner case are generic types that don't use
+// their type arguments. For instance:
+type T[P any] struct{}
+
+var xint T[int]
+var xbool T[bool]
+
+// Are these two variables of the same type? After all, their underlying
+// types are identical. We consider them to be different because each type
+// instantiation creates a new named type, in this case T<int> and T<bool>
+// even if their underlying types are identical. This is sensible because
+// we might still have methods that have different signatures or behave
+// differently depending on the type arguments, and thus we can't possibly
+// consider such types identical. Consequently:
+func _() {
+	xint = xbool // ERROR assignment
+}
+
+// Generic types cannot be used without instantiation.
+var _ T // ERROR cannot use generic type T
+
+// In type context, generic (parameterized) types cannot be parenthesized before
+// being instantiated. See also NOTES entry from 12/4/2019.
+var _ (T /* ERROR cannot use generic type T */ )[ /* ERROR expected ';' */ int]
+
+// All types may be parameterized, including interfaces.
+type I1[T any] interface{
+	m1(T)
+}
+
+// There is no such thing as a variadic generic type.
+type _[T ... /* ERROR invalid use of ... */ interface{}] struct{}
+
+// Generic interfaces may be embedded as one would expect.
+type I2 interface {
+	I1(int)     // method!
+	I1[string]  // embedded I1
+}
+
+func _() {
+	var x I2
+	x.I1(0)
+	x.m1("foo")
+}
+
+type I0 interface {
+	m0()
+}
+
+type I3 interface {
+	I0
+	I1[bool]
+	m(string)
+}
+
+func _() {
+	var x I3
+	x.m0()
+	x.m1(true)
+	x.m("foo")
+}
+
+// We accept parenthesized embedded struct fields so we can distinguish between
+// a named field with a parenthesized type foo (T) and an embedded parameterized
+// type (foo(T)), similarly to interface embedding.
+// They still need to be valid embedded types after the parentheses are stripped
+// (i.e., in contrast to interfaces, we cannot embed a struct literal). The name
+// of the embedded field is derived as before, after stripping parentheses.
+// (7/14/2020: See comment above. We probably will revert this generalized ability
+// if we go with [] for type parameters.)
+type _ struct {
+	int8
+	*int16
+	*List[int]
+
+	int8 /* ERROR int8 redeclared */
+	* /* ERROR List redeclared */ List[int]
+}
+
+// It's possible to declare local types whose underlying types
+// are type parameters. As with ordinary type definitions, the
+// types underlying properties are "inherited" but the methods
+// are not.
+func _[T interface{ m(); type int }]() {
+	type L T
+	var x L
+
+	// m is not defined on L (it is not "inherited" from
+	// its underlying type).
+	x.m /* ERROR x.m undefined */ ()
+
+	// But the properties of T, such that as that it supports
+	// the operations of the types given by its type bound,
+	// are also the properties of L.
+	x++
+	_ = x - x
+
+	// On the other hand, if we define a local alias for T,
+	// that alias stands for T as expected.
+	type A = T
+	var y A
+	y.m()
+	_ = y < 0
+}
+
+// As a special case, an explicit type argument may be omitted
+// from a type parameter bound if the type bound expects exactly
+// one type argument. In that case, the type argument is the
+// respective type parameter to which the type bound applies.
+// Note: We may not permit this syntactic sugar at first.
+// Note: This is now disabled. All examples below are adjusted.
+type Adder[T any] interface {
+	Add(T) T
+}
+
+// We don't need to explicitly instantiate the Adder bound
+// if we have exactly one type parameter.
+func Sum[T Adder[T]](list []T) T {
+	var sum T
+	for _, x := range list {
+		sum = sum.Add(x)
+	}
+	return sum
+}
+
+// Valid and invalid variations.
+type B0 interface {}
+type B1[_ any] interface{}
+type B2[_, _ any] interface{}
+
+func _[T1 B0]()
+func _[T1 B1[T1]]()
+func _[T1 B2 /* ERROR cannot use generic type .* without instantiation */ ]()
+
+func _[T1, T2 B0]()
+func _[T1 B1[T1], T2 B1[T2]]()
+func _[T1, T2 B2 /* ERROR cannot use generic type .* without instantiation */ ]()
+
+func _[T1 B0, T2 B1[T2]]() // here B1 applies to T2
+
+// When the type argument is left away, the type bound is
+// instantiated for each type parameter with that type
+// parameter.
+// Note: We may not permit this syntactic sugar at first.
+func _[A Adder[A], B Adder[B], C Adder[A]]() {
+	var a A // A's type bound is Adder[A]
+	a = a.Add(a)
+	var b B // B's type bound is Adder[B]
+	b = b.Add(b)
+	var c C // C's type bound is Adder[A]
+	a = c.Add(a)
+}
+
+// The type of variables (incl. parameters and return values) cannot
+// be an interface with type constraints or be/embed comparable.
+type I interface {
+	type int
+}
+
+var (
+	_ interface /* ERROR contains type constraints */ {type int}
+	_ I /* ERROR contains type constraints */
+)
+
+func _(I /* ERROR contains type constraints */ )
+func _(x, y, z I /* ERROR contains type constraints */ )
+func _() I /* ERROR contains type constraints */
+
+func _() {
+	var _ I /* ERROR contains type constraints */
+}
+
+type C interface {
+	comparable
+}
+
+var _ comparable /* ERROR comparable */
+var _ C /* ERROR comparable */
+
+func _(_ comparable /* ERROR comparable */ , _ C /* ERROR comparable */ )
+
+func _() {
+	var _ comparable /* ERROR comparable */
+	var _ C /* ERROR comparable */
+}
+
+// Type parameters are never const types, i.e., it's
+// not possible to declare a constant of type parameter type.
+// (If a type list contains just a single const type, we could
+// allow it, but such type lists don't make much sense in the
+// first place.)
+func _[T interface { type int, float64 }]() {
+	// not valid
+	const _ = T /* ERROR not constant */ (0)
+	const _ T /* ERROR invalid constant type T */ = 1
+
+	// valid
+	var _ = T(0)
+	var _ T = 1
+	_ = T(0)
+}
+
diff --git a/src/go/types/testdata/expr3.src b/src/go/types/testdata/expr3.src
deleted file mode 100644
index e6777aa..0000000
--- a/src/go/types/testdata/expr3.src
+++ /dev/null
@@ -1,563 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package expr3
-
-import "time"
-
-func indexes() {
-	_ = 1 /* ERROR "cannot index" */ [0]
-	_ = indexes /* ERROR "cannot index" */ [0]
-	_ = ( /* ERROR "cannot slice" */ 12 + 3)[1:2]
-
-	var a [10]int
-	_ = a[true /* ERROR "cannot convert" */ ]
-	_ = a["foo" /* ERROR "cannot convert" */ ]
-	_ = a[1.1 /* ERROR "truncated" */ ]
-	_ = a[1.0]
-	_ = a[- /* ERROR "negative" */ 1]
-	_ = a[- /* ERROR "negative" */ 1 :]
-	_ = a[: - /* ERROR "negative" */ 1]
-	_ = a[: /* ERROR "2nd index required" */ : /* ERROR "3rd index required" */ ]
-	_ = a[0: /* ERROR "2nd index required" */ : /* ERROR "3rd index required" */ ]
-	_ = a[0: /* ERROR "2nd index required" */ :10]
-	_ = a[:10:10]
-
-	var a0 int
-	a0 = a[0]
-	_ = a0
-	var a1 int32
-	a1 = a /* ERROR "cannot use .* in assignment" */ [1]
-	_ = a1
-
-	_ = a[9]
-	_ = a[10 /* ERROR "index .* out of bounds" */ ]
-	_ = a[1 /* ERROR "overflows" */ <<100]
-	_ = a[10:]
-	_ = a[:10]
-	_ = a[10:10]
-	_ = a[11 /* ERROR "index .* out of bounds" */ :]
-	_ = a[: 11 /* ERROR "index .* out of bounds" */ ]
-	_ = a[: 1 /* ERROR "overflows" */ <<100]
-	_ = a[:10:10]
-	_ = a[:11 /* ERROR "index .* out of bounds" */ :10]
-	_ = a[:10:11 /* ERROR "index .* out of bounds" */ ]
-	_ = a[10:0:10] /* ERROR swapped slice indices" */
-	_ = a[0:10:0] /* ERROR "swapped slice indices" */
-	_ = a[10:0:0] /* ERROR "swapped slice indices" */
-	_ = &a /* ERROR "cannot take address" */ [:10]
-
-	pa := &a
-	_ = pa[9]
-	_ = pa[10 /* ERROR "index .* out of bounds" */ ]
-	_ = pa[1 /* ERROR "overflows" */ <<100]
-	_ = pa[10:]
-	_ = pa[:10]
-	_ = pa[10:10]
-	_ = pa[11 /* ERROR "index .* out of bounds" */ :]
-	_ = pa[: 11 /* ERROR "index .* out of bounds" */ ]
-	_ = pa[: 1 /* ERROR "overflows" */ <<100]
-	_ = pa[:10:10]
-	_ = pa[:11 /* ERROR "index .* out of bounds" */ :10]
-	_ = pa[:10:11 /* ERROR "index .* out of bounds" */ ]
-	_ = pa[10:0:10] /* ERROR "swapped slice indices" */
-	_ = pa[0:10:0] /* ERROR "swapped slice indices" */
-	_ = pa[10:0:0] /* ERROR "swapped slice indices" */
-	_ = &pa /* ERROR "cannot take address" */ [:10]
-
-	var b [0]int
-	_ = b[0 /* ERROR "index .* out of bounds" */ ]
-	_ = b[:]
-	_ = b[0:]
-	_ = b[:0]
-	_ = b[0:0]
-	_ = b[0:0:0]
-	_ = b[1 /* ERROR "index .* out of bounds" */ :0:0]
-
-	var s []int
-	_ = s[- /* ERROR "negative" */ 1]
-	_ = s[- /* ERROR "negative" */ 1 :]
-	_ = s[: - /* ERROR "negative" */ 1]
-	_ = s[0]
-	_ = s[1:2]
-	_ = s[2:1] /* ERROR "swapped slice indices" */
-	_ = s[2:]
-	_ = s[: 1 /* ERROR "overflows" */ <<100]
-	_ = s[1 /* ERROR "overflows" */ <<100 :]
-	_ = s[1 /* ERROR "overflows" */ <<100 : 1 /* ERROR "overflows" */ <<100]
-	_ = s[: /* ERROR "2nd index required" */ :  /* ERROR "3rd index required" */ ]
-	_ = s[:10:10]
-	_ = s[10:0:10] /* ERROR "swapped slice indices" */
-	_ = s[0:10:0] /* ERROR "swapped slice indices" */
-	_ = s[10:0:0] /* ERROR "swapped slice indices" */
-	_ = &s /* ERROR "cannot take address" */ [:10]
-
-	var m map[string]int
-	_ = m[0 /* ERROR "cannot use .* in map index" */ ]
-	_ = m /* ERROR "cannot slice" */ ["foo" : "bar"]
-	_ = m["foo"]
-	// ok is of type bool
-	type mybool bool
-	var ok mybool
-	_, ok = m["bar"]
-	_ = ok
-	_ = m[0 /* ERROR "cannot use 0" */ ] + "foo" // ERROR "cannot convert"
-
-	var t string
-	_ = t[- /* ERROR "negative" */ 1]
-	_ = t[- /* ERROR "negative" */ 1 :]
-	_ = t[: - /* ERROR "negative" */ 1]
-	_ = t /* ERROR "3-index slice of string" */ [1:2:3]
-	_ = "foo" /* ERROR "3-index slice of string" */ [1:2:3]
-	var t0 byte
-	t0 = t[0]
-	_ = t0
-	var t1 rune
-	t1 = t /* ERROR "cannot use .* in assignment" */ [2]
-	_ = t1
-	_ = ("foo" + "bar")[5]
-	_ = ("foo" + "bar")[6 /* ERROR "index .* out of bounds" */ ]
-
-	const c = "foo"
-	_ = c[- /* ERROR "negative" */ 1]
-	_ = c[- /* ERROR "negative" */ 1 :]
-	_ = c[: - /* ERROR "negative" */ 1]
-	var c0 byte
-	c0 = c[0]
-	_ = c0
-	var c2 float32
-	c2 = c /* ERROR "cannot use .* in assignment" */ [2]
-	_ = c[3 /* ERROR "index .* out of bounds" */ ]
-	_ = ""[0 /* ERROR "index .* out of bounds" */ ]
-	_ = c2
-
-	_ = s[1<<30] // no compile-time error here
-
-	// issue 4913
-	type mystring string
-	var ss string
-	var ms mystring
-	var i, j int
-	ss = "foo"[1:2]
-	ss = "foo"[i:j]
-	ms = "foo" /* ERROR "cannot use .* in assignment" */ [1:2]
-	ms = "foo" /* ERROR "cannot use .* in assignment" */ [i:j]
-	_, _ = ss, ms
-}
-
-type T struct {
-	x int
-	y func()
-}
-
-func (*T) m() {}
-
-func method_expressions() {
-	_ = T.a /* ERROR "no field or method" */
-	_ = T.x /* ERROR "has no method" */
-	_ = T.m /* ERROR "cannot call pointer method m on T" */
-	_ = (*T).m
-
-	var f func(*T) = T.m /* ERROR "cannot call pointer method m on T" */
-	var g func(*T) = (*T).m
-	_, _ = f, g
-
-	_ = T.y /* ERROR "has no method" */
-	_ = (*T).y /* ERROR "has no method" */
-}
-
-func struct_literals() {
-	type T0 struct {
-		a, b, c int
-	}
-
-	type T1 struct {
-		T0
-		a, b int
-		u float64
-		s string
-	}
-
-	// keyed elements
-	_ = T1{}
-	_ = T1{a: 0, 1 /* ERROR "mixture of .* elements" */ }
-	_ = T1{aa /* ERROR "unknown field" */ : 0}
-	_ = T1{1 /* ERROR "invalid field name" */ : 0}
-	_ = T1{a: 0, s: "foo", u: 0, a /* ERROR "duplicate field" */: 10}
-	_ = T1{a: "foo" /* ERROR "cannot use .* in struct literal" */ }
-	_ = T1{c /* ERROR "unknown field" */ : 0}
-	_ = T1{T0: { /* ERROR "missing type" */ }} // struct literal element type may not be elided
-	_ = T1{T0: T0{}}
-	_ = T1{T0 /* ERROR "invalid field name" */ .a: 0}
-
-	// unkeyed elements
-	_ = T0{1, 2, 3}
-	_ = T0{1, b /* ERROR "mixture" */ : 2, 3}
-	_ = T0{1, 2} /* ERROR "too few values" */
-	_ = T0{1, 2, 3, 4  /* ERROR "too many values" */ }
-	_ = T0{1, "foo" /* ERROR "cannot use .* in struct literal" */, 3.4  /* ERROR "cannot use .*\(truncated\)" */}
-
-	// invalid type
-	type P *struct{
-		x int
-	}
-	_ = P /* ERROR "invalid composite literal type" */ {}
-
-	// unexported fields
-	_ = time.Time{}
-	_ = time.Time{sec /* ERROR "unknown field" */ : 0}
-	_ = time.Time{
-		0 /* ERROR implicit assignment to unexported field wall in time.Time literal */,
-		0 /* ERROR implicit assignment */ ,
-		nil /* ERROR implicit assignment */ ,
-	}
-}
-
-func array_literals() {
-	type A0 [0]int
-	_ = A0{}
-	_ = A0{0 /* ERROR "index .* out of bounds" */}
-	_ = A0{0 /* ERROR "index .* out of bounds" */ : 0}
-
-	type A1 [10]int
-	_ = A1{}
-	_ = A1{0, 1, 2}
-	_ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
-	_ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /* ERROR "index .* out of bounds" */ }
-	_ = A1{- /* ERROR "negative" */ 1: 0}
-	_ = A1{8: 8, 9}
-	_ = A1{8: 8, 9, 10 /* ERROR "index .* out of bounds" */ }
-	_ = A1{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
-	_ = A1{5: 5, 6, 7, 3: 3, 4}
-	_ = A1{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ }
-	_ = A1{10 /* ERROR "index .* out of bounds" */ : 10, 10 /* ERROR "index .* out of bounds" */ : 10}
-	_ = A1{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ }
-	_ = A1{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4}
-	_ = A1{2.0}
-	_ = A1{2.1 /* ERROR "truncated" */ }
-	_ = A1{"foo" /* ERROR "cannot use .* in array or slice literal" */ }
-
-	// indices must be integer constants
-	i := 1
-	const f = 2.1
-	const s = "foo"
-	_ = A1{i /* ERROR "index i must be integer constant" */ : 0}
-	_ = A1{f /* ERROR "truncated" */ : 0}
-	_ = A1{s /* ERROR "cannot convert" */ : 0}
-
-	a0 := [...]int{}
-	assert(len(a0) == 0)
-
-	a1 := [...]int{0, 1, 2}
-	assert(len(a1) == 3)
-	var a13 [3]int
-	var a14 [4]int
-	a13 = a1
-	a14 = a1 /* ERROR "cannot use .* in assignment" */
-	_, _ = a13, a14
-
-	a2 := [...]int{- /* ERROR "negative" */ 1: 0}
-	_ = a2
-
-	a3 := [...]int{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
-	assert(len(a3) == 5) // somewhat arbitrary
-
-	a4 := [...]complex128{0, 1, 2, 1<<10-2: -1i, 1i, 400: 10, 12, 14}
-	assert(len(a4) == 1024)
-
-	// composite literal element types may be elided
-	type T []int
-	_ = [10]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
-	a6 := [...]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
-	assert(len(a6) == 8)
-
-	// recursively so
-	_ = [10][10]T{{}, [10]T{{}}, {{1, 2, 3}}}
-
-	// from the spec
-	type Point struct { x, y float32 }
-	_ = [...]Point{Point{1.5, -3.5}, Point{0, 0}}
-	_ = [...]Point{{1.5, -3.5}, {0, 0}}
-	_ = [][]int{[]int{1, 2, 3}, []int{4, 5}}
-	_ = [][]int{{1, 2, 3}, {4, 5}}
-	_ = [...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}
-	_ = [...]*Point{{1.5, -3.5}, {0, 0}}
-}
-
-func slice_literals() {
-	type S0 []int
-	_ = S0{}
-	_ = S0{0, 1, 2}
-	_ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
-	_ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
-	_ = S0{- /* ERROR "negative" */ 1: 0}
-	_ = S0{8: 8, 9}
-	_ = S0{8: 8, 9, 10}
-	_ = S0{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
-	_ = S0{5: 5, 6, 7, 3: 3, 4}
-	_ = S0{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ }
-	_ = S0{10: 10, 10 /* ERROR "duplicate index" */ : 10}
-	_ = S0{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ }
-	_ = S0{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4}
-	_ = S0{2.0}
-	_ = S0{2.1 /* ERROR "truncated" */ }
-	_ = S0{"foo" /* ERROR "cannot use .* in array or slice literal" */ }
-
-	// indices must be resolved correctly
-	const index1 = 1
-	_ = S0{index1: 1}
-	_ = S0{index2: 2}
-	_ = S0{index3 /* ERROR "undeclared name" */ : 3}
-
-	// indices must be integer constants
-	i := 1
-	const f = 2.1
-	const s = "foo"
-	_ = S0{i /* ERROR "index i must be integer constant" */ : 0}
-	_ = S0{f /* ERROR "truncated" */ : 0}
-	_ = S0{s /* ERROR "cannot convert" */ : 0}
-
-	// composite literal element types may be elided
-	type T []int
-	_ = []T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
-	_ = [][]int{{1, 2, 3}, {4, 5}}
-
-	// recursively so
-	_ = [][]T{{}, []T{{}}, {{1, 2, 3}}}
-
-	// issue 17954
-	type T0 *struct { s string }
-	_ = []T0{{}}
-	_ = []T0{{"foo"}}
-
-	type T1 *struct{ int }
-	_ = []T1{}
-	_ = []T1{{0}, {1}, {2}}
-
-	type T2 T1
-	_ = []T2{}
-	_ = []T2{{0}, {1}, {2}}
-
-	_ = map[T0]T2{}
-	_ = map[T0]T2{{}: {}}
-}
-
-const index2 int = 2
-
-type N int
-func (N) f() {}
-
-func map_literals() {
-	type M0 map[string]int
-	type M1 map[bool]int
-	type M2 map[*int]int
-
-	_ = M0{}
-	_ = M0{1 /* ERROR "missing key" */ }
-	_ = M0{1 /* ERROR "cannot use .* in map literal" */ : 2}
-	_ = M0{"foo": "bar" /* ERROR "cannot use .* in map literal" */ }
-	_ = M0{"foo": 1, "bar": 2, "foo" /* ERROR "duplicate key" */ : 3 }
-
-	_ = map[interface{}]int{2: 1, 2 /* ERROR "duplicate key" */ : 1}
-	_ = map[interface{}]int{int(2): 1, int16(2): 1}
-	_ = map[interface{}]int{int16(2): 1, int16 /* ERROR "duplicate key" */ (2): 1}
-
-	type S string
-
-	_ = map[interface{}]int{"a": 1, "a" /* ERROR "duplicate key" */ : 1}
-	_ = map[interface{}]int{"a": 1, S("a"): 1}
-	_ = map[interface{}]int{S("a"): 1, S /* ERROR "duplicate key" */ ("a"): 1}
-	_ = map[interface{}]int{1.0: 1, 1.0 /* ERROR "duplicate key" */: 1}
-	_ = map[interface{}]int{int64(-1): 1, int64 /* ERROR "duplicate key" */ (-1) : 1}
-	_ = map[interface{}]int{^uint64(0): 1, ^ /* ERROR "duplicate key" */ uint64(0): 1}
-	_ = map[interface{}]int{complex(1,2): 1, complex /* ERROR "duplicate key" */ (1,2) : 1}
-
-	type I interface {
-		f()
-	}
-
-	_ = map[I]int{N(0): 1, N(2): 1}
-	_ = map[I]int{N(2): 1, N /* ERROR "duplicate key" */ (2): 1}
-
-	// map keys must be resolved correctly
-	key1 := "foo"
-	_ = M0{key1: 1}
-	_ = M0{key2: 2}
-	_ = M0{key3 /* ERROR "undeclared name" */ : 2}
-
-	var value int
-	_ = M1{true: 1, false: 0}
-	_ = M2{nil: 0, &value: 1}
-
-	// composite literal element types may be elided
-	type T [2]int
-	_ = map[int]T{0: T{3, 4}, 1: {5, 6}}
-
-	// recursively so
-	_ = map[int][]T{0: {}, 1: {{}, T{1, 2}}}
-
-	// composite literal key types may be elided
-	_ = map[T]int{T{3, 4}: 0, {5, 6}: 1}
-
-	// recursively so
-	_ = map[[2]T]int{{}: 0, {{}}: 1, [2]T{{}}: 2, {T{1, 2}}: 3}
-
-	// composite literal element and key types may be elided
-	_ = map[T]T{{}: {}, {1, 2}: T{3, 4}, T{4, 5}: {}}
-	_ = map[T]M0{{} : {}, T{1, 2}: M0{"foo": 0}, {1, 3}: {"foo": 1}}
-
-	// recursively so
-	_ = map[[2]T][]T{{}: {}, {{}}: {{}, T{1, 2}}, [2]T{{}}: nil, {T{1, 2}}: {{}, {}}}
-
-	// from the spec
-	type Point struct { x, y float32 }
-	_ = map[string]Point{"orig": {0, 0}}
-	_ = map[*Point]string{{0, 0}: "orig"}
-
-	// issue 17954
-	type T0 *struct{ s string }
-	type T1 *struct{ int }
-	type T2 T1
-
-	_ = map[T0]T2{}
-	_ = map[T0]T2{{}: {}}
-}
-
-var key2 string = "bar"
-
-type I interface {
-	m()
-}
-
-type I2 interface {
-	m(int)
-}
-
-type T1 struct{}
-type T2 struct{}
-
-func (T2) m(int) {}
-
-type mybool bool
-
-func type_asserts() {
-	var x int
-	_ = x /* ERROR "not an interface" */ .(int)
-
-	var e interface{}
-	var ok bool
-	x, ok = e.(int)
-	_ = ok
-
-	// ok value is of type bool
-	var myok mybool
-	_, myok = e.(int)
-	_ = myok
-
-	var t I
-	_ = t /* ERROR "use of .* outside type switch" */ .(type)
-	_ = t /* ERROR "missing method m" */ .(T)
-	_ = t.(*T)
-	_ = t /* ERROR "missing method m" */ .(T1)
-	_ = t /* ERROR "wrong type for method m" */ .(T2)
-	_ = t /* STRICT "wrong type for method m" */ .(I2) // only an error in strict mode (issue 8561)
-
-	// e doesn't statically have an m, but may have one dynamically.
-	_ = e.(I2)
-}
-
-func f0() {}
-func f1(x int) {}
-func f2(u float32, s string) {}
-func fs(s []byte) {}
-func fv(x ...int) {}
-func fi(x ... interface{}) {}
-func (T) fm(x ...int)
-
-func g0() {}
-func g1() int { return 0}
-func g2() (u float32, s string) { return }
-func gs() []byte { return nil }
-
-func _calls() {
-	var x int
-	var y float32
-	var s []int
-
-	f0()
-	_ = f0 /* ERROR "used as value" */ ()
-	f0(g0 /* ERROR "too many arguments" */ )
-
-	f1(0)
-	f1(x)
-	f1(10.0)
-	f1() /* ERROR "too few arguments" */
-	f1(x, y /* ERROR "too many arguments" */ )
-	f1(s /* ERROR "cannot use .* in argument" */ )
-	f1(x ... /* ERROR "cannot use ..." */ )
-	f1(g0 /* ERROR "used as value" */ ())
-	f1(g1())
-	f1(g2 /* ERROR "cannot use g2" */ /* ERROR "too many arguments" */ ())
-
-	f2() /* ERROR "too few arguments" */
-	f2(3.14) /* ERROR "too few arguments" */
-	f2(3.14, "foo")
-	f2(x /* ERROR "cannot use .* in argument" */ , "foo")
-	f2(g0 /* ERROR "used as value" */ ())
-	f2(g1 /* ERROR "cannot use .* in argument" */ ()) /* ERROR "too few arguments" */
-	f2(g2())
-
-	fs() /* ERROR "too few arguments" */
-	fs(g0 /* ERROR "used as value" */ ())
-	fs(g1 /* ERROR "cannot use .* in argument" */ ())
-	fs(g2 /* ERROR "cannot use .* in argument" */ /* ERROR "too many arguments" */ ())
-	fs(gs())
-
-	fv()
-	fv(1, 2.0, x)
-	fv(s /* ERROR "cannot use .* in argument" */ )
-	fv(s...)
-	fv(x /* ERROR "cannot use" */ ...)
-	fv(1, s... /* ERROR "can only use ... with matching parameter" */ )
-	fv(gs /* ERROR "cannot use .* in argument" */ ())
-	fv(gs /* ERROR "cannot use .* in argument" */ ()...)
-
-	var t T
-	t.fm()
-	t.fm(1, 2.0, x)
-	t.fm(s /* ERROR "cannot use .* in argument" */ )
-	t.fm(g1())
-	t.fm(1, s... /* ERROR "can only use ... with matching parameter" */ )
-	t.fm(gs /* ERROR "cannot use .* in argument" */ ())
-	t.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
-
-	T.fm(t, )
-	T.fm(t, 1, 2.0, x)
-	T.fm(t, s /* ERROR "cannot use .* in argument" */ )
-	T.fm(t, g1())
-	T.fm(t, 1, s... /* ERROR "can only use ... with matching parameter" */ )
-	T.fm(t, gs /* ERROR "cannot use .* in argument" */ ())
-	T.fm(t, gs /* ERROR "cannot use .* in argument" */ ()...)
-
-	var i interface{ fm(x ...int) } = t
-	i.fm()
-	i.fm(1, 2.0, x)
-	i.fm(s /* ERROR "cannot use .* in argument" */ )
-	i.fm(g1())
-	i.fm(1, s... /* ERROR "can only use ... with matching parameter" */ )
-	i.fm(gs /* ERROR "cannot use .* in argument" */ ())
-	i.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
-
-	fi()
-	fi(1, 2.0, x, 3.14, "foo")
-	fi(g2())
-	fi(0, g2)
-	fi(0, g2 /* ERROR "2-valued g2" */ ())
-}
-
-func issue6344() {
-	type T []interface{}
-	var x T
-	fi(x...) // ... applies also to named slices
-}
diff --git a/src/go/types/fixedbugs/issue20583.src b/src/go/types/testdata/fixedbugs/issue20583.src
similarity index 100%
rename from src/go/types/fixedbugs/issue20583.src
rename to src/go/types/testdata/fixedbugs/issue20583.src
diff --git a/src/go/types/fixedbugs/issue23203a.src b/src/go/types/testdata/fixedbugs/issue23203a.src
similarity index 100%
rename from src/go/types/fixedbugs/issue23203a.src
rename to src/go/types/testdata/fixedbugs/issue23203a.src
diff --git a/src/go/types/fixedbugs/issue23203b.src b/src/go/types/testdata/fixedbugs/issue23203b.src
similarity index 100%
rename from src/go/types/fixedbugs/issue23203b.src
rename to src/go/types/testdata/fixedbugs/issue23203b.src
diff --git a/src/go/types/fixedbugs/issue26390.src b/src/go/types/testdata/fixedbugs/issue26390.src
similarity index 100%
rename from src/go/types/fixedbugs/issue26390.src
rename to src/go/types/testdata/fixedbugs/issue26390.src
diff --git a/src/go/types/fixedbugs/issue28251.src b/src/go/types/testdata/fixedbugs/issue28251.src
similarity index 100%
rename from src/go/types/fixedbugs/issue28251.src
rename to src/go/types/testdata/fixedbugs/issue28251.src
diff --git a/src/go/types/testdata/fixedbugs/issue39634.go2 b/src/go/types/testdata/fixedbugs/issue39634.go2
new file mode 100644
index 0000000..a13ed13
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39634.go2
@@ -0,0 +1,91 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Examples adjusted to match new [T any] syntax for type parameters.
+// Also, previously permitted empty type parameter lists and instantiations
+// are now syntax errors.
+
+package p
+
+// crash 1
+type nt1[_ any]interface{g /* ERROR undeclared name */ }
+type ph1[e nt1[e],g(d /* ERROR undeclared name */ )]s /* ERROR undeclared name */
+func(*ph1[e,e /* ERROR redeclared */ ])h(d /* ERROR undeclared name */ )
+
+// crash 2
+// Disabled: empty []'s are now syntax errors. This example leads to too many follow-on errors.
+// type Numeric2 interface{t2 /* ERROR not a type */ }
+// func t2[T Numeric2](s[]T){0 /* ERROR not a type */ []{s /* ERROR cannot index */ [0][0]}}
+
+// crash 3
+type t3 *interface{ t3.p /* ERROR no field or method p */ }
+
+// crash 4
+type Numeric4 interface{t4 /* ERROR not a type */ }
+func t4[T Numeric4](s[]T){if( /* ERROR non-boolean */ 0){*s /* ERROR cannot indirect */ [0]}}
+
+// crash 7
+type foo7 interface { bar() }
+type x7[A any] struct{ foo7 }
+func main7() { var _ foo7 = x7[int]{} }
+
+// crash 8
+type foo8[A any] interface { type A }
+func bar8[A foo8[A]](a A) {}
+func main8() {}
+
+// crash 9
+type foo9[A any] interface { type foo9 /* ERROR interface contains type constraints */ [A] }
+func _() { var _ = new(foo9 /* ERROR interface contains type constraints */ [int]) }
+
+// crash 12
+var u /* ERROR cycle */ , i [func /* ERROR used as value */ /* ERROR used as value */ (u, c /* ERROR undeclared */ /* ERROR undeclared */ ) {}(0, len /* ERROR must be called */ /* ERROR must be called */ )]c /* ERROR undeclared */ /* ERROR undeclared */
+
+// crash 15
+func y15() { var a /* ERROR declared but not used */ interface{ p() } = G15[string]{} }
+type G15[X any] s /* ERROR undeclared name */
+func (G15 /* ERROR generic type .* without instantiation */ ) p()
+
+// crash 16
+type Foo16[T any] r16 /* ERROR not a type */
+func r16[T any]() Foo16[Foo16[T]]
+
+// crash 17
+type Y17 interface{ c() }
+type Z17 interface {
+	c() Y17
+	Y17 /* ERROR duplicate method */
+}
+func F17[T Z17](T)
+
+// crash 18
+type o18[T any] []func(_ o18[[]_ /* ERROR cannot use _ */ ])
+
+// crash 19
+type Z19 [][[]Z19{}[0][0]]c19 /* ERROR undeclared */
+
+// crash 20
+type Z20 /* ERROR illegal cycle */ interface{ Z20 }
+func F20[t Z20]() { F20(t /* ERROR invalid composite literal type */ {}) }
+
+// crash 21
+type Z21 /* ERROR illegal cycle */ interface{ Z21 }
+func F21[T Z21]() { ( /* ERROR not used */ F21[Z21]) }
+
+// crash 24
+type T24[P any] P
+func (r T24[P]) m() { T24 /* ERROR without instantiation */ .m() }
+
+// crash 25
+type T25[A any] int
+func (t T25[A]) m1() {}
+var x T25 /* ERROR without instantiation */ .m1
+
+// crash 26
+type T26 = interface{ F26[ /* ERROR methods cannot have type parameters */ Z any]() }
+func F26[Z any]() T26 { return F26[] /* ERROR operand */ }
+
+// crash 27
+func e27[T any]() interface{ x27 /* ERROR not a type */ }
+func x27() { e27 /* ERROR cannot infer T */ () }
diff --git a/src/go/types/testdata/fixedbugs/issue39664.go2 b/src/go/types/testdata/fixedbugs/issue39664.go2
new file mode 100644
index 0000000..3b3ec56
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39664.go2
@@ -0,0 +1,15 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T[_ any] struct {}
+
+func (T /* ERROR instantiation */ ) m()
+
+func _() {
+	var x interface { m() }
+	x = T[int]{}
+	_ = x
+}
diff --git a/src/go/types/testdata/fixedbugs/issue39680.go2 b/src/go/types/testdata/fixedbugs/issue39680.go2
new file mode 100644
index 0000000..9bc26f3
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39680.go2
@@ -0,0 +1,27 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "fmt"
+
+// Minimal test case.
+func _[T interface{type T}](x T) T{
+	return x
+}
+
+// Test case from issue.
+type constr[T any] interface {
+	type T
+}
+
+func Print[T constr[T]](s []T) {
+	for _, v := range s {
+		fmt.Print(v)
+	}
+}
+
+func f() {
+	Print([]string{"Hello, ", "playground\n"})
+}
diff --git a/src/go/types/testdata/fixedbugs/issue39693.go2 b/src/go/types/testdata/fixedbugs/issue39693.go2
new file mode 100644
index 0000000..316ab19
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39693.go2
@@ -0,0 +1,14 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type Number interface {
+	int     /* ERROR int is not an interface */
+	float64 /* ERROR float64 is not an interface */
+}
+
+func Add[T Number](a, b T) T {
+	return a /* ERROR not defined */ + b
+}
diff --git a/src/go/types/testdata/fixedbugs/issue39699.go2 b/src/go/types/testdata/fixedbugs/issue39699.go2
new file mode 100644
index 0000000..75491e7
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39699.go2
@@ -0,0 +1,29 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T0 interface{
+}
+
+type T1 interface{
+	type int
+}
+
+type T2 interface{
+	comparable
+}
+
+type T3 interface {
+	T0
+	T1
+	T2
+}
+
+func _() {
+	_ = T0(0)
+	_ = T1 /* ERROR cannot use interface T1 in conversion */ (1)
+	_ = T2 /* ERROR cannot use interface T2 in conversion */ (2)
+	_ = T3 /* ERROR cannot use interface T3 in conversion */ (3)
+}
diff --git a/src/go/types/testdata/fixedbugs/issue39711.go2 b/src/go/types/testdata/fixedbugs/issue39711.go2
new file mode 100644
index 0000000..df621a4
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39711.go2
@@ -0,0 +1,11 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// Do not report a duplicate type error for this type list.
+// (Check types after interfaces have been completed.)
+type _ interface {
+	type interface{ Error() string }, interface{ String() string }
+}
diff --git a/src/go/types/testdata/fixedbugs/issue39723.go2 b/src/go/types/testdata/fixedbugs/issue39723.go2
new file mode 100644
index 0000000..55464e6
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39723.go2
@@ -0,0 +1,9 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// A constraint must be an interface; it cannot
+// be a type parameter, for instance.
+func _[A interface{ type interface{} }, B A /* ERROR not an interface */ ]()
diff --git a/src/go/types/testdata/fixedbugs/issue39725.go2 b/src/go/types/testdata/fixedbugs/issue39725.go2
new file mode 100644
index 0000000..e19b677
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39725.go2
@@ -0,0 +1,16 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f1[T1, T2 any](T1, T2, struct{a T1; b T2})
+func _() {
+	f1(42, string("foo"), struct /* ERROR does not match inferred type struct\{a int; b string\} */ {a, b int}{})
+}
+
+// simplified test case from issue
+func f2[T any](_ []T, _ func(T))
+func _() {
+	f2([]string{}, func /* ERROR does not match inferred type func\(string\) */ (f []byte) {})
+}
diff --git a/src/go/types/testdata/fixedbugs/issue39754.go2 b/src/go/types/testdata/fixedbugs/issue39754.go2
new file mode 100644
index 0000000..4b4420d
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39754.go2
@@ -0,0 +1,24 @@
+// Copyright 2020 The Go Authors. All rights reserved.

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

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

+

+package p

+

+type Optional[T any] struct {}

+

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

+

+type Box[T any] interface {

+	Val() (T, bool)

+}

+

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

+

+func _() {

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

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

+	// TODO(gri) Provide better position information here.

+	//           See TODO in call.go, Checker.arguments.

+	// TODO(rFindley) Reconcile this error position with types2.

+	f /* ERROR does not satisfy Box */ [int, Optional[int], Optional[string]]()

+}

diff --git a/src/go/types/testdata/fixedbugs/issue39755.go2 b/src/go/types/testdata/fixedbugs/issue39755.go2
new file mode 100644
index 0000000..b7ab688
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39755.go2
@@ -0,0 +1,23 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _[T interface{type map[string]int}](x T) {
+	_ = x == nil
+}
+
+// simplified test case from issue
+
+type PathParamsConstraint interface {
+        type map[string]string, []struct{key, value string}
+}
+
+type PathParams[T PathParamsConstraint] struct {
+	t T
+}
+
+func (pp *PathParams[T]) IsNil() bool {
+	return pp.t == nil // this must succeed
+}
diff --git a/src/go/types/testdata/fixedbugs/issue39768.go2 b/src/go/types/testdata/fixedbugs/issue39768.go2
new file mode 100644
index 0000000..abac141
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39768.go2
@@ -0,0 +1,20 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T[P any] P
+type A = T
+var x A[int]
+var _ A /* ERROR cannot use generic type */
+
+type B = T[int]
+var y B = x
+var _ B /* ERROR not a generic type */ [int]
+
+// test case from issue
+
+type Vector[T any] []T
+type VectorAlias = Vector
+var v Vector[int]
diff --git a/src/go/types/testdata/fixedbugs/issue39938.go2 b/src/go/types/testdata/fixedbugs/issue39938.go2
new file mode 100644
index 0000000..76e7e36
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39938.go2
@@ -0,0 +1,50 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check "infinite expansion" cycle errors across instantiated types.
+
+package p
+
+type E0[P any] P
+type E1[P any] *P
+type E2[P any] struct{ P }
+type E3[P any] struct{ *P }
+
+type T0 /* ERROR illegal cycle */ struct {
+        _ E0[T0]
+}
+
+type T0_ /* ERROR illegal cycle */ struct {
+        E0[T0_]
+}
+
+type T1 struct {
+        _ E1[T1]
+}
+
+type T2 /* ERROR illegal cycle */ struct {
+        _ E2[T2]
+}
+
+type T3 struct {
+        _ E3[T3]
+}
+
+// some more complex cases
+
+type T4 /* ERROR illegal cycle */ struct {
+	_ E0[E2[T4]]
+}
+
+type T5 struct {
+	_ E0[E2[E0[E1[E2[[10]T5]]]]]
+}
+
+type T6 /* ERROR illegal cycle */ struct {
+	_ E0[[10]E2[E0[E2[E2[T6]]]]]
+}
+
+type T7 struct {
+	_ E0[[]E2[E0[E2[E2[T6]]]]]
+}
diff --git a/src/go/types/testdata/fixedbugs/issue39948.go2 b/src/go/types/testdata/fixedbugs/issue39948.go2
new file mode 100644
index 0000000..c2b4609
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39948.go2
@@ -0,0 +1,9 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T[P any] interface{
+	P // ERROR P is a type parameter, not an interface
+}
diff --git a/src/go/types/testdata/fixedbugs/issue39976.go2 b/src/go/types/testdata/fixedbugs/issue39976.go2
new file mode 100644
index 0000000..3db4eae
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39976.go2
@@ -0,0 +1,16 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type policy[K, V any] interface{}
+type LRU[K, V any] struct{}
+
+func NewCache[K, V any](p policy[K, V])
+
+func _() {
+	var lru LRU[int, string]
+	NewCache[int, string](&lru)
+	NewCache(& /* ERROR does not match policy\[K, V\] \(cannot infer K and V\) */ lru)
+}
diff --git a/src/go/types/testdata/fixedbugs/issue39982.go2 b/src/go/types/testdata/fixedbugs/issue39982.go2
new file mode 100644
index 0000000..9810b63
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue39982.go2
@@ -0,0 +1,36 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type (
+	T[_ any] struct{}
+	S[_ any] struct {
+		data T[*T[int]]
+	}
+)
+
+func _() {
+	_ = S[int]{
+		data: T[*T[int]]{},
+	}
+}
+
+// full test case from issue
+
+type (
+	Element[TElem any] struct{}
+
+	entry[K comparable] struct{}
+
+	Cache[K comparable] struct {
+		data map[K]*Element[*entry[K]]
+	}
+)
+
+func _() {
+	_ = Cache[int]{
+		data: make(map[int](*Element[*entry[int]])),
+	}
+}
diff --git a/src/go/types/testdata/fixedbugs/issue40038.go2 b/src/go/types/testdata/fixedbugs/issue40038.go2
new file mode 100644
index 0000000..8948d61
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue40038.go2
@@ -0,0 +1,15 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type A[T any] int
+
+func (A[T]) m(A[T])
+
+func f[P interface{m(P)}]()
+
+func _() {
+	_ = f[A[int]]
+}
\ No newline at end of file
diff --git a/src/go/types/testdata/fixedbugs/issue40056.go2 b/src/go/types/testdata/fixedbugs/issue40056.go2
new file mode 100644
index 0000000..f587691
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue40056.go2
@@ -0,0 +1,15 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _() {
+	NewS /* ERROR cannot infer T */ ().M()
+}
+
+type S struct {}
+
+func NewS[T any]() *S
+
+func (_ *S /* ERROR S is not a generic type */ [T]) M()
diff --git a/src/go/types/testdata/fixedbugs/issue40057.go2 b/src/go/types/testdata/fixedbugs/issue40057.go2
new file mode 100644
index 0000000..fdc8fb1
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue40057.go2
@@ -0,0 +1,17 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _() {
+	var x interface{}
+	switch t := x.(type) {
+	case S /* ERROR cannot use generic type */ :
+		t.m()
+	}
+}
+
+type S[T any] struct {}
+
+func (_ S[T]) m()
diff --git a/src/go/types/testdata/fixedbugs/issue40301.go2 b/src/go/types/testdata/fixedbugs/issue40301.go2
new file mode 100644
index 0000000..5d97855
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue40301.go2
@@ -0,0 +1,12 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "unsafe"
+
+func _[T any](x T) {
+	_ = unsafe /* ERROR undefined */ .Alignof(x)
+	_ = unsafe /* ERROR undefined */ .Sizeof(x)
+}
diff --git a/src/go/types/testdata/fixedbugs/issue40684.go2 b/src/go/types/testdata/fixedbugs/issue40684.go2
new file mode 100644
index 0000000..0269c3a
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue40684.go2
@@ -0,0 +1,15 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T[_ any] int
+
+func f[_ any]()
+func g[_, _ any]()
+
+func _() {
+	_ = f[T /* ERROR without instantiation */ ]
+	_ = g[T /* ERROR without instantiation */ , T /* ERROR without instantiation */ ]
+}
\ No newline at end of file
diff --git a/src/go/types/testdata/fixedbugs/issue41124.go2 b/src/go/types/testdata/fixedbugs/issue41124.go2
new file mode 100644
index 0000000..61f766b
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue41124.go2
@@ -0,0 +1,91 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// Test case from issue.
+
+type Nat interface {
+	type Zero, Succ
+}
+
+type Zero struct{}
+type Succ struct{
+	Nat // ERROR interface contains type constraints
+}
+
+// Struct tests.
+
+type I1 interface {
+	comparable
+}
+
+type I2 interface {
+	type int
+}
+
+type I3 interface {
+	I1
+	I2
+}
+
+type _ struct {
+	f I1 // ERROR interface is .* comparable
+}
+
+type _ struct {
+	comparable // ERROR interface is .* comparable
+}
+
+type _ struct{
+	I1 // ERROR interface is .* comparable
+}
+
+type _ struct{
+	I2 // ERROR interface contains type constraints
+}
+
+type _ struct{
+	I3 // ERROR interface contains type constraints
+}
+
+// General composite types.
+
+type (
+	_ [10]I1 // ERROR interface is .* comparable
+	_ [10]I2 // ERROR interface contains type constraints
+
+	_ []I1 // ERROR interface is .* comparable
+	_ []I2 // ERROR interface contains type constraints
+
+	_ *I3 // ERROR interface contains type constraints
+	_ map[I1 /* ERROR interface is .* comparable */ ]I2 // ERROR interface contains type constraints
+	_ chan I3 // ERROR interface contains type constraints
+	_ func(I1 /* ERROR interface is .* comparable */ )
+	_ func() I2 // ERROR interface contains type constraints
+)
+
+// Other cases.
+
+var _ = [...]I3 /* ERROR interface contains type constraints */ {}
+
+func _(x interface{}) {
+	_ = x.(I3 /* ERROR interface contains type constraints */ )
+}
+
+type T1[_ any] struct{}
+type T3[_, _, _ any] struct{}
+var _ T1[I2 /* ERROR interface contains type constraints */ ]
+var _ T3[int, I2 /* ERROR interface contains type constraints */ , float32]
+
+func f1[_ any]() int
+var _ = f1[I2 /* ERROR interface contains type constraints */ ]()
+func f3[_, _, _ any]() int
+var _ = f3[int, I2 /* ERROR interface contains type constraints */ , float32]()
+
+func _(x interface{}) {
+	switch x.(type) {
+	case I2 /* ERROR interface contains type constraints */ :
+	}
+}
diff --git a/src/go/types/fixedbugs/issue42695.src b/src/go/types/testdata/fixedbugs/issue42695.src
similarity index 100%
rename from src/go/types/fixedbugs/issue42695.src
rename to src/go/types/testdata/fixedbugs/issue42695.src
diff --git a/src/go/types/testdata/fixedbugs/issue42758.go2 b/src/go/types/testdata/fixedbugs/issue42758.go2
new file mode 100644
index 0000000..698cb8a
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue42758.go2
@@ -0,0 +1,33 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _[T any](x interface{}){
+	switch x.(type) {
+	case T: // ok to use a type parameter
+	case int:
+	}
+
+	switch x.(type) {
+	case T:
+	case T /* ERROR duplicate case */ :
+	}
+}
+
+type constraint interface {
+	type int
+}
+
+func _[T constraint](x interface{}){
+	switch x.(type) {
+	case T: // ok to use a type parameter even if type list contains int
+	case int:
+	}
+}
+
+func _(x constraint /* ERROR contains type constraints */ ) {
+	switch x /* ERROR contains type constraints */ .(type) {
+	}
+}
diff --git a/src/go/types/testdata/fixedbugs/issue42987.src b/src/go/types/testdata/fixedbugs/issue42987.src
new file mode 100644
index 0000000..6060ec8
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue42987.src
@@ -0,0 +1,10 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check that there is only one error (no follow-on errors).
+
+package p
+// TODO(rFindley) This is a parser error, but in types2 it is a type checking
+//                error. We could probably do without this check in the parser.
+var _ = [... /* ERROR expected array length, found '...' */ ]byte("foo")
diff --git a/src/go/types/testdata/fixedbugs/issue43087.src b/src/go/types/testdata/fixedbugs/issue43087.src
new file mode 100644
index 0000000..ef37b4a
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue43087.src
@@ -0,0 +1,43 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _() {
+	a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3
+	_ = a
+	_ = b
+}
+
+func _() {
+	a, _, _ := 1, 2, 3 // multiple _'s ok
+	_ = a
+}
+
+func _() {
+	var b int
+	a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3
+	_ = a
+	_ = b
+}
+
+func _() {
+	var a []int
+	a /* ERROR expected identifier */ /* ERROR non-name .* on left side of := */ [0], b := 1, 2
+	_ = a
+	_ = b
+}
+
+func _() {
+	var a int
+	a, a /* ERROR a repeated on left side of := */ := 1, 2
+	_ = a
+}
+
+func _() {
+	var a, b int
+	a, b := /* ERROR no new variables on left side of := */ 1, 2
+	_ = a
+	_ = b
+}
diff --git a/src/go/types/fixedbugs/issue43110.src b/src/go/types/testdata/fixedbugs/issue43110.src
similarity index 100%
rename from src/go/types/fixedbugs/issue43110.src
rename to src/go/types/testdata/fixedbugs/issue43110.src
diff --git a/src/go/types/fixedbugs/issue43124.src b/src/go/types/testdata/fixedbugs/issue43124.src
similarity index 100%
rename from src/go/types/fixedbugs/issue43124.src
rename to src/go/types/testdata/fixedbugs/issue43124.src
diff --git a/src/go/types/testdata/fixedbugs/issue43125.src b/src/go/types/testdata/fixedbugs/issue43125.src
new file mode 100644
index 0000000..456888d
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue43125.src
@@ -0,0 +1,8 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+var _ = new(- /* ERROR not a type */ 1)
+var _ = new(1 /* ERROR not a type */ + 1)
diff --git a/src/go/types/testdata/fixedbugs/issue43190.src b/src/go/types/testdata/fixedbugs/issue43190.src
new file mode 100644
index 0000000..96acb3a
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue43190.src
@@ -0,0 +1,22 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Most of the errors below are actually produced by the parser, but we check
+// them here for consistency with the types2 tests.
+
+package p
+
+import ; /* ERROR invalid import path */ /* ERROR expected 'STRING' */
+import // ERROR expected ';'
+var _ int
+import /* ERROR expected declaration */ .;
+
+import ()
+import (.)
+import (
+	"fmt"
+	.
+)
+
+var _ = fmt /* ERROR "undeclared name" */ .Println
diff --git a/src/go/types/testdata/fixedbugs/issue44688.go2 b/src/go/types/testdata/fixedbugs/issue44688.go2
new file mode 100644
index 0000000..512bfcc
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue44688.go2
@@ -0,0 +1,83 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package P
+
+type A1[T any] struct{}
+
+func (*A1[T]) m1(T) {}
+
+type A2[T any] interface {
+	m2(T)
+}
+
+type B1[T any] struct {
+	filler int
+	*A1[T]
+	A2[T]
+}
+
+type B2[T any] interface {
+	A2[T]
+}
+
+type C[T any] struct {
+	filler1 int
+	filler2 int
+	B1[T]
+}
+
+type D[T any] struct {
+	filler1 int
+	filler2 int
+	filler3 int
+	C[T]
+}
+
+func _() {
+	// calling embedded methods
+	var b1 B1[string]
+
+	b1.A1.m1("")
+	b1.m1("")
+
+	b1.A2.m2("")
+	b1.m2("")
+
+	var b2 B2[string]
+	b2.m2("")
+
+	// a deeper nesting
+	var d D[string]
+	d.m1("")
+	d.m2("")
+
+	// calling method expressions
+	m1x := B1[string].m1
+	m1x(b1, "")
+	m2x := B2[string].m2
+	m2x(b2, "")
+
+	// calling method values
+	m1v := b1.m1
+	m1v("")
+	m2v := b1.m2
+	m2v("")
+	b2v := b2.m2
+	b2v("")
+}
+
+// actual test case from issue
+
+type A[T any] struct{}
+
+func (*A[T]) f(T) {}
+
+type B[T any] struct{ A[T] }
+
+func _() {
+	var b B[string]
+	b.A.f("")
+	b.f("")
+}
diff --git a/src/go/types/testdata/fixedbugs/issue44799.go2 b/src/go/types/testdata/fixedbugs/issue44799.go2
new file mode 100644
index 0000000..9e528a7
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue44799.go2
@@ -0,0 +1,19 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func Map[F, T any](s []F, f func(F) T) []T { return nil }
+
+func Reduce[Elem1, Elem2 any](s []Elem1, initializer Elem2, f func(Elem2, Elem1) Elem2) Elem2 { var x Elem2; return x }
+
+func main() {
+	var s []int
+	var f1 func(int) float64
+	var f2 func(float64, int) float64
+	_ = Map[int](s, f1)
+	_ = Map(s, f1)
+	_ = Reduce[int](s, 0, f2)
+	_ = Reduce(s, 0, f2)
+}
diff --git a/src/go/types/testdata/fixedbugs/issue45548.go2 b/src/go/types/testdata/fixedbugs/issue45548.go2
new file mode 100644
index 0000000..b1e4249
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue45548.go2
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f[F interface{type *Q}, G interface{type *R}, Q, R any](q Q, r R) {}
+
+func _() {
+	f[*float64, *int](1, 2)
+	f[*float64](1, 2)
+	f(1, 2)
+}
diff --git a/src/go/types/testdata/fixedbugs/issue45635.go2 b/src/go/types/testdata/fixedbugs/issue45635.go2
new file mode 100644
index 0000000..3e2ccec
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue45635.go2
@@ -0,0 +1,32 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main() {
+	some /* ERROR "undeclared name" */ [int, int]()
+}
+
+type N[T any] struct{}
+
+var _ N /* ERROR "0 arguments but 1 type parameters" */ []
+
+type I interface {
+	type map[int]int, []int
+}
+
+func _[T I](i, j int) {
+	var m map[int]int
+	_ = m[i, j /* ERROR "more than one index" */ ]
+
+	var a [3]int
+	_ = a[i, j /* ERROR "more than one index" */ ]
+
+	var s []int
+	_ = s[i, j /* ERROR "more than one index" */ ]
+
+	var t T
+	// TODO(rFindley) Fix the duplicate error below.
+	_ = t[i, j /* ERROR "more than one index" */ /* ERROR "more than one index" */ ]
+}
diff --git a/src/go/types/testdata/fixedbugs/issue45985.go2 b/src/go/types/testdata/fixedbugs/issue45985.go2
new file mode 100644
index 0000000..550b9c6
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue45985.go2
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue45985
+
+// TODO(rFindley): this error should be on app[int] below.
+func app[S /* ERROR "type S = S does not match" */ interface{ type []T }, T any](s S, e T) S {
+    return append(s, e)
+}
+
+func _() {
+	_ = app[int]
+}
diff --git a/src/go/types/testdata/fixedbugs/issue46403.src b/src/go/types/testdata/fixedbugs/issue46403.src
new file mode 100644
index 0000000..9d47522
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue46403.src
@@ -0,0 +1,11 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue46403
+
+func _() {
+	// a should be used, despite the parser error below.
+	var a []int
+	var _ = a[] // ERROR expected operand
+}
diff --git a/src/go/types/testdata/fixedbugs/issue46404.go1 b/src/go/types/testdata/fixedbugs/issue46404.go1
new file mode 100644
index 0000000..db604bc
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue46404.go1
@@ -0,0 +1,8 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue46404
+
+// Check that we don't type check t[_] as an instantiation.
+type t [t /* ERROR not a type */ [_]]_ // ERROR cannot use
diff --git a/src/go/types/fixedbugs/issue6977.src b/src/go/types/testdata/fixedbugs/issue6977.src
similarity index 100%
rename from src/go/types/fixedbugs/issue6977.src
rename to src/go/types/testdata/fixedbugs/issue6977.src
diff --git a/src/go/types/testdata/importdecl0a.src b/src/go/types/testdata/importdecl0a.src
deleted file mode 100644
index e96fca3..0000000
--- a/src/go/types/testdata/importdecl0a.src
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package importdecl0
-
-import ()
-
-import (
-	// we can have multiple blank imports (was bug)
-	_ "math"
-	_ "net/rpc"
-	init /* ERROR "cannot declare init" */ "fmt"
-	// reflect defines a type "flag" which shows up in the gc export data
-	"reflect"
-	. /* ERROR "imported but not used" */ "reflect"
-)
-
-import "math" /* ERROR "imported but not used" */
-import m /* ERROR "imported but not used as m" */ "math"
-import _ "math"
-
-import (
-	"math/big" /* ERROR "imported but not used" */
-	b /* ERROR "imported but not used" */ "math/big"
-	_ "math/big"
-)
-
-import "fmt"
-import f1 "fmt"
-import f2 "fmt"
-
-// reflect.flag must not be visible in this package
-type flag int
-type _ reflect.flag /* ERROR "not exported" */
-
-// imported package name may conflict with local objects
-type reflect /* ERROR "reflect already declared" */ int
-
-// dot-imported exported objects may conflict with local objects
-type Value /* ERROR "Value already declared through dot-import of package reflect" */ struct{}
-
-var _ = fmt.Println // use "fmt"
-
-func _() {
-	f1.Println() // use "fmt"
-}
-
-func _() {
-	_ = func() {
-		f2.Println() // use "fmt"
-	}
-}
diff --git a/src/go/types/testdata/importdecl0b.src b/src/go/types/testdata/importdecl0b.src
deleted file mode 100644
index 6844e70..0000000
--- a/src/go/types/testdata/importdecl0b.src
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package importdecl0
-
-import "math"
-import m "math"
-
-import . "testing" // declares T in file scope
-import . /* ERROR "imported but not used" */ "unsafe"
-import . "fmt"     // declares Println in file scope
-
-import (
-	// TODO(gri) At the moment, 2 errors are reported because both go/parser
-	// and the type checker report it. Eventually, this test should not be
-	// done by the parser anymore.
-	"" /* ERROR invalid import path */ /* ERROR invalid import path */
-	"a!b" /* ERROR invalid import path */ /* ERROR invalid import path */
-	"abc\xffdef" /* ERROR invalid import path */ /* ERROR invalid import path */
-)
-
-// using "math" in this file doesn't affect its use in other files
-const Pi0 = math.Pi
-const Pi1 = m.Pi
-
-type _ T // use "testing"
-
-func _() func() interface{} {
-	return func() interface{} {
-		return Println // use "fmt"
-	}
-}
diff --git a/src/go/types/testdata/importdecl1b.src b/src/go/types/testdata/importdecl1b.src
deleted file mode 100644
index ee70bbd..0000000
--- a/src/go/types/testdata/importdecl1b.src
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package importdecl1
-
-import . /* ERROR "imported but not used" */ "unsafe"
-
-type B interface {
-	A
-}
diff --git a/src/go/types/testdata/issues.src b/src/go/types/testdata/issues.src
deleted file mode 100644
index e0c5d7a..0000000
--- a/src/go/types/testdata/issues.src
+++ /dev/null
@@ -1,365 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package issues
-
-import (
-	"fmt"
-	syn "cmd/compile/internal/syntax"
-	t1 "text/template"
-	t2 "html/template"
-)
-
-func issue7035() {
-	type T struct{ X int }
-	_ = func() {
-		fmt.Println() // must refer to imported fmt rather than the fmt below
-	}
-	fmt := new(T)
-	_ = fmt.X
-}
-
-func issue8066() {
-	const (
-		_ = float32(340282356779733661637539395458142568447)
-		_ = float32(340282356779733661637539395458142568448 /* ERROR cannot convert */ )
-	)
-}
-
-// Check that a missing identifier doesn't lead to a spurious error cascade.
-func issue8799a() {
-	x, ok := missing /* ERROR undeclared */ ()
-	_ = !ok
-	_ = x
-}
-
-func issue8799b(x int, ok bool) {
-	x, ok = missing /* ERROR undeclared */ ()
-	_ = !ok
-	_ = x
-}
-
-func issue9182() {
-	type Point C /* ERROR undeclared */ .Point
-	// no error for composite literal based on unknown type
-	_ = Point{x: 1, y: 2}
-}
-
-func f0() (a []int)         { return }
-func f1() (a []int, b int)  { return }
-func f2() (a, b []int)      { return }
-
-func append_([]int, ...int) {}
-
-func issue9473(a []int, b ...int) {
-	// variadic builtin function
-	_ = append(f0())
-	_ = append(f0(), f0()...)
-	_ = append(f1())
-	_ = append(f2 /* ERROR cannot use .* in argument */ ())
-	_ = append(f2()... /* ERROR cannot use ... */ )
-	_ = append(f0(), f1 /* ERROR 2-valued f1 */ ())
-	_ = append(f0(), f2 /* ERROR 2-valued f2 */ ())
-	_ = append(f0(), f1 /* ERROR 2-valued f1 */ ()...)
-	_ = append(f0(), f2 /* ERROR 2-valued f2 */ ()...)
-
-	// variadic user-defined function
-	append_(f0())
-	append_(f0(), f0()...)
-	append_(f1())
-	append_(f2 /* ERROR cannot use .* in argument */ ())
-	append_(f2()... /* ERROR cannot use ... */ )
-	append_(f0(), f1 /* ERROR 2-valued f1 */ ())
-	append_(f0(), f2 /* ERROR 2-valued f2 */ ())
-	append_(f0(), f1 /* ERROR 2-valued f1 */ ()...)
-	append_(f0(), f2 /* ERROR 2-valued f2 */ ()...)
-}
-
-// Check that embedding a non-interface type in an interface results in a good error message.
-func issue10979() {
-	type _ interface {
-		int /* ERROR int is not an interface */
-	}
-	type T struct{}
-	type _ interface {
-		T /* ERROR T is not an interface */
-	}
-	type _ interface {
-		nosuchtype /* ERROR undeclared name: nosuchtype */
-	}
-	type _ interface {
-		fmt.Nosuchtype /* ERROR Nosuchtype not declared by package fmt */
-	}
-	type _ interface {
-		nosuchpkg /* ERROR undeclared name: nosuchpkg */ .Nosuchtype
-	}
-	type I interface {
-		I.m /* ERROR no field or method m */
-		m()
-	}
-}
-
-// issue11347
-// These should not crash.
-var a1, b1 /* ERROR cycle */ , c1 /* ERROR cycle */ b1 = 0 > 0<<""[""[c1]]>c1
-var a2, b2 /* ERROR cycle */ = 0 /* ERROR cannot initialize */ /* ERROR cannot initialize */ > 0<<""[b2]
-var a3, b3 /* ERROR cycle */ = int /* ERROR cannot initialize */ /* ERROR cannot initialize */ (1<<""[b3])
-
-// issue10260
-// Check that error messages explain reason for interface assignment failures.
-type (
-	I0 interface{}
-	I1 interface{ foo() }
-	I2 interface{ foo(x int) }
-	T0 struct{}
-	T1 struct{}
-	T2 struct{}
-)
-
-func (*T1) foo() {}
-func (*T2) foo(x int) {}
-
-func issue10260() {
-	var (
-		i0 I0
-		i1 I1
-		i2 I2
-		t0 *T0
-		t1 *T1
-		t2 *T2
-	)
-
-	var x I1
-	x = T1 /* ERROR cannot use .*: missing method foo \(foo has pointer receiver\) */ {}
-	_ = x /* ERROR .* cannot have dynamic type T1 \(missing method foo \(foo has pointer receiver\)\) */ .(T1)
-
-	T1{}.foo /* ERROR cannot call pointer method foo on T1 */ ()
-	x.Foo /* ERROR "x.Foo undefined \(type I1 has no field or method Foo, but does have foo\)" */ ()
-
-	_ = i2 /* ERROR i2 .* cannot have dynamic type \*T1 \(wrong type for method foo \(have func\(\), want func\(x int\)\)\) */ .(*T1)
-
-	i1 = i0 /* ERROR cannot use .* missing method foo */
-	i1 = t0 /* ERROR cannot use .* missing method foo */
-	i1 = i2 /* ERROR cannot use .* wrong type for method foo */
-	i1 = t2 /* ERROR cannot use .* wrong type for method foo */
-	i2 = i1 /* ERROR cannot use .* wrong type for method foo */
-	i2 = t1 /* ERROR cannot use .* wrong type for method foo */
-
-	_ = func() I1 { return i0 /* ERROR cannot use .* missing method foo */ }
-	_ = func() I1 { return t0 /* ERROR cannot use .* missing method foo */ }
-	_ = func() I1 { return i2 /* ERROR cannot use .* wrong type for method foo */ }
-	_ = func() I1 { return t2 /* ERROR cannot use .* wrong type for method foo */ }
-	_ = func() I2 { return i1 /* ERROR cannot use .* wrong type for method foo */ }
-	_ = func() I2 { return t1 /* ERROR cannot use .* wrong type for method foo */ }
-
-	// a few more - less exhaustive now
-
-	f := func(I1, I2){}
-	f(i0 /* ERROR cannot use .* missing method foo */ , i1 /* ERROR cannot use .* wrong type for method foo \(have func\(\), want func\(x int\)\) */ )
-
-	_ = [...]I1{i0 /* ERROR cannot use .* missing method foo */ }
-	_ = [...]I1{i2 /* ERROR cannot use .* wrong type for method foo */ }
-	_ = []I1{i0 /* ERROR cannot use .* missing method foo */ }
-	_ = []I1{i2 /* ERROR cannot use .* wrong type for method foo */ }
-	_ = map[int]I1{0: i0 /* ERROR cannot use .* missing method foo */ }
-	_ = map[int]I1{0: i2 /* ERROR cannot use .* wrong type for method foo */ }
-
-	make(chan I1) <- i0 /* ERROR cannot use .* in send: missing method foo */
-	make(chan I1) <- i2 /* ERROR cannot use .* in send: wrong type for method foo */
-}
-
-// Check that constants representable as integers are in integer form
-// before being used in operations that are only defined on integers.
-func issue14229() {
-	// from the issue
-	const _ = int64(-1<<63) % 1e6
-
-	// related
-	const (
-		a int = 3
-		b = 4.0
-		_ = a / b
-		_ = a % b
-		_ = b / a
-		_ = b % a
-	)
-}
-
-// Check that in a n:1 variable declaration with type and initialization
-// expression the type is distributed to all variables of the lhs before
-// the initialization expression assignment is checked.
-func issue15755() {
-	// from issue
-	var i interface{}
-	type b bool
-	var x, y b = i.(b)
-	_ = x == y
-
-	// related: we should see an error since the result of f1 is ([]int, int)
-	var u, v []int = f1 /* ERROR cannot use f1 */ ()
-	_ = u
-	_ = v
-}
-
-// Test that we don't get "declared but not used"
-// errors in the context of invalid/C objects.
-func issue20358() {
-	var F C /* ERROR "undeclared" */ .F
-	var A C /* ERROR "undeclared" */ .A
-	var S C /* ERROR "undeclared" */ .S
-	type T C /* ERROR "undeclared" */ .T
-	type P C /* ERROR "undeclared" */ .P
-
-	// these variables must be "used" even though
-	// the LHS expressions/types below in which
-	// context they are used are unknown/invalid
-	var f, a, s1, s2, s3, t, p int
-
-	_ = F(f)
-	_ = A[a]
-	_ = S[s1:s2:s3]
-	_ = T{t}
-	_ = P{f: p}
-}
-
-// Test that we don't declare lhs variables in short variable
-// declarations before we type-check function literals on the
-// rhs.
-func issue24026() {
-	f := func() int { f(0) /* must refer to outer f */; return 0 }
-	_ = f
-
-	_ = func() {
-		f := func() { _ = f() /* must refer to outer f */ }
-		_ = f
-	}
-
-	// b and c must not be visible inside function literal
-	a := 0
-	a, b, c := func() (int, int, int) {
-		return a, b /* ERROR undeclared */ , c /* ERROR undeclared */
-	}()
-	_, _ = b, c
-}
-
-func f(int) {} // for issue24026
-
-// Test that we don't report a "missing return statement" error
-// (due to incorrect context when type-checking interfaces).
-func issue24140(x interface{}) int {
-        switch x.(type) {
-        case interface{}:
-                return 0
-        default:
-                panic(0)
-        }
-}
-
-// Test that we don't crash when the 'if' condition is missing.
-func issue25438() {
-	if { /* ERROR missing condition */ }
-	if x := 0; /* ERROR missing condition */ { _ = x }
-	if
-	{ /* ERROR missing condition */ }
-}
-
-// Test that we can embed alias type names in interfaces.
-type issue25301 interface {
-	E
-}
-
-type E = interface {
-	m()
-}
-
-// Test case from issue.
-// cmd/compile reports a cycle as well.
-type issue25301b /* ERROR cycle */ = interface {
-	m() interface{ issue25301b }
-}
-
-type issue25301c interface {
-	notE // ERROR struct\{\} is not an interface
-}
-
-type notE = struct{}
-
-// Test that method declarations don't introduce artificial cycles
-// (issue #26124).
-const CC TT = 1
-type TT int
-func (TT) MM() [CC]TT
-
-// Reduced test case from issue #26124.
-const preloadLimit LNumber = 128
-type LNumber float64
-func (LNumber) assertFunction() *LFunction
-type LFunction struct {
-	GFunction LGFunction
-}
-type LGFunction func(*LState)
-type LState struct {
-	reg *registry
-}
-type registry struct {
-	alloc *allocator
-}
-type allocator struct {
-	_ [int(preloadLimit)]int
-}
-
-// Test that we don't crash when type-checking composite literals
-// containing errors in the type.
-var issue27346 = [][n /* ERROR undeclared */ ]int{
-	0: {},
-}
-
-var issue22467 = map[int][... /* ERROR invalid use of ... */ ]int{0: {}}
-
-// Test that invalid use of ... in parameter lists is recognized
-// (issue #28281).
-func issue28281a(int, int, ...int)
-func issue28281b(a, b int, c ...int)
-func issue28281c(a, b, c ... /* ERROR can only use ... with final parameter */ int)
-func issue28281d(... /* ERROR can only use ... with final parameter */ int, int)
-func issue28281e(a, b, c  ... /* ERROR can only use ... with final parameter */ int, d int)
-func issue28281f(... /* ERROR can only use ... with final parameter */ int, ... /* ERROR can only use ... with final parameter */ int, int)
-func (... /* ERROR expected type */ TT) f()
-func issue28281g() (... /* ERROR expected type */ TT)
-
-// Issue #26234: Make various field/method lookup errors easier to read by matching cmd/compile's output
-func issue26234a(f *syn.File) {
-	// The error message below should refer to the actual package name (syntax)
-	// not the local package name (syn).
-	f.foo /* ERROR f.foo undefined \(type \*syntax.File has no field or method foo\) */
-}
-
-type T struct {
-	x int
-	E1
-	E2
-}
-
-type E1 struct{ f int }
-type E2 struct{ f int }
-
-func issue26234b(x T) {
-	_ = x.f /* ERROR ambiguous selector x.f */
-}
-
-func issue26234c() {
-	T.x /* ERROR T.x undefined \(type T has no method x\) */ ()
-}
-
-func issue35895() {
-	// T is defined in this package, don't qualify its name with the package name.
-	var _ T = 0 // ERROR cannot use 0 \(untyped int constant\) as T
-
-	// There is only one package with name syntax imported, only use the (global) package name in error messages.
-	var _ *syn.File = 0 // ERROR cannot use 0 \(untyped int constant\) as \*syntax.File
-
-	// Because both t1 and t2 have the same global package name (template),
-	// qualify packages with full path name in this case.
-	var _ t1.Template = t2 /* ERROR cannot use .* \(value of type "html/template".Template\) as "text/template".Template */ .Template{}
-}
diff --git a/src/go/types/testdata/shifts.src b/src/go/types/testdata/shifts.src
deleted file mode 100644
index c9a38ae..0000000
--- a/src/go/types/testdata/shifts.src
+++ /dev/null
@@ -1,395 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package shifts
-
-func shifts0() {
-	// basic constant shifts
-	const (
-		s = 10
-		_ = 0<<0
-		_ = 1<<s
-		_ = 1<<- /* ERROR "negative shift count" */ 1
-		// For the test below we may decide to convert to int
-		// rather than uint and then report a negative shift
-		// count instead, which might be a better error. The
-		// (minor) difference is that this would restrict the
-		// shift count range by half (from all uint values to
-		// the positive int values).
-		// This depends on the exact spec wording which is not
-		// done yet.
-		// TODO(gri) revisit and adjust when spec change is done
-		_ = 1<<- /* ERROR "truncated to uint" */ 1.0
-		_ = 1<<1075 /* ERROR "invalid shift" */
-		_ = 2.0<<1
-		_ = 1<<1.0
-		_ = 1<<(1+0i)
-
-		_ int = 2<<s
-		_ float32 = 2<<s
-		_ complex64 = 2<<s
-
-		_ int = 2.0<<s
-		_ float32 = 2.0<<s
-		_ complex64 = 2.0<<s
-
-		_ int = 'a'<<s
-		_ float32 = 'a'<<s
-		_ complex64 = 'a'<<s
-	)
-}
-
-func shifts1() {
-	// basic non-constant shifts
-	var (
-		i int
-		u uint
-
-		_ = 1<<0
-		_ = 1<<i
-		_ = 1<<u
-		_ = 1<<"foo" /* ERROR "cannot convert" */
-		_ = i<<0
-		_ = i<<- /* ERROR "negative shift count" */ 1
-		_ = i<<1.0
-		_ = 1<<(1+0i)
-		_ = 1 /* ERROR "overflows" */ <<100
-
-		_ uint = 1 << 0
-		_ uint = 1 << u
-		_ float32 = 1 /* ERROR "must be integer" */ << u
-
-		// for issue 14822
-		_ = 1<<( /* ERROR "invalid shift count" */ 1<<64-1)
-		_ = 1<<( /* ERROR "invalid shift count" */ 1<<64)
-		_ = u<<(1<<63) // valid
-		_ = u<<(1<<64) // valid
-	)
-}
-
-func shifts2() {
-	// from the spec
-	var (
-		s uint = 33
-		i = 1<<s           // 1 has type int
-		j int32 = 1<<s     // 1 has type int32; j == 0
-		k = uint64(1<<s)   // 1 has type uint64; k == 1<<33
-		m int = 1.0<<s     // 1.0 has type int
-		n = 1.0<<s != i    // 1.0 has type int; n == false if ints are 32bits in size
-		o = 1<<s == 2<<s   // 1 and 2 have type int; o == true if ints are 32bits in size
-		p = 1<<s == 1<<33  // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int
-		u = 1.0 /* ERROR "must be integer" */ <<s         // illegal: 1.0 has type float64, cannot shift
-		u1 = 1.0 /* ERROR "must be integer" */ <<s != 0   // illegal: 1.0 has type float64, cannot shift
-		u2 = 1 /* ERROR "must be integer" */ <<s != 1.0   // illegal: 1 has type float64, cannot shift
-		v float32 = 1 /* ERROR "must be integer" */ <<s   // illegal: 1 has type float32, cannot shift
-		w int64 = 1.0<<33  // 1.0<<33 is a constant shift expression
-	)
-	_, _, _, _, _, _, _, _, _, _, _, _ = i, j, k, m, n, o, p, u, u1, u2, v, w
-}
-
-func shifts3(a int16, b float32) {
-	// random tests
-	var (
-		s uint = 11
-		u = 1 /* ERROR "must be integer" */ <<s + 1.0
-		v complex128 = 1 /* ERROR "must be integer" */ << s + 1.0 /* ERROR "must be integer" */ << s + 1
-	)
-	x := 1.0 /* ERROR "must be integer" */ <<s + 1
-	shifts3(1.0 << s, 1 /* ERROR "must be integer" */ >> s)
-	_, _, _ = u, v, x
-}
-
-func shifts4() {
-	// shifts in comparisons w/ untyped operands
-	var s uint
-
-	_ = 1<<s == 1
-	_ = 1 /* ERROR "integer" */ <<s == 1.
-	_ = 1. /* ERROR "integer" */ <<s == 1
-	_ = 1. /* ERROR "integer" */ <<s == 1.
-
-	_ = 1<<s + 1 == 1
-	_ = 1 /* ERROR "integer" */ <<s + 1 == 1.
-	_ = 1 /* ERROR "integer" */ <<s + 1. == 1
-	_ = 1 /* ERROR "integer" */ <<s + 1. == 1.
-	_ = 1. /* ERROR "integer" */ <<s + 1 == 1
-	_ = 1. /* ERROR "integer" */ <<s + 1 == 1.
-	_ = 1. /* ERROR "integer" */ <<s + 1. == 1
-	_ = 1. /* ERROR "integer" */ <<s + 1. == 1.
-
-	_ = 1<<s == 1<<s
-	_ = 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s
-
-	_ = 1<<s + 1<<s == 1
-	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1.
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1.
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1.
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1.
-
-	_ = 1<<s + 1<<s == 1<<s + 1<<s
-	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-}
-
-func shifts5() {
-	// shifts in comparisons w/ typed operands
-	var s uint
-	var x int
-
-	_ = 1<<s == x
-	_ = 1.<<s == x
-	_ = 1.1 /* ERROR "int" */ <<s == x
-
-	_ = 1<<s + x == 1
-	_ = 1<<s + x == 1.
-	_ = 1<<s + x == 1.1 /* ERROR "int" */
-	_ = 1.<<s + x == 1
-	_ = 1.<<s + x == 1.
-	_ = 1.<<s + x == 1.1 /* ERROR "int" */
-	_ = 1.1 /* ERROR "int" */ <<s + x == 1
-	_ = 1.1 /* ERROR "int" */ <<s + x == 1.
-	_ = 1.1 /* ERROR "int" */ <<s + x == 1.1
-
-	_ = 1<<s == x<<s
-	_ = 1.<<s == x<<s
-	_ = 1.1  /* ERROR "int" */ <<s == x<<s
-}
-
-func shifts6() {
-	// shifts as operands in non-arithmetic operations and as arguments
-	var a [10]int
-	var s uint
-
-	_ = a[1<<s]
-	_ = a[1.0]
-	_ = a[1.0<<s]
-
-	_ = make([]int, 1.0)
-	_ = make([]int, 1.0<<s)
-	_ = make([]int, 1.1 /* ERROR "must be integer" */ <<s)
-
-	_ = float32(1)
-	_ = float32(1 /* ERROR "must be integer" */ <<s)
-	_ = float32(1.0)
-	_ = float32(1.0 /* ERROR "must be integer" */ <<s)
-	_ = float32(1.1 /* ERROR "must be integer" */ <<s)
-
-	_ = int32(0x80000000 /* ERROR "overflows int32" */ << s)
-	// TODO(rfindley) Eliminate the redundant error here.
-	_ = int32(( /* ERROR "truncated to int32" */ 0x80000000 /* ERROR "truncated to int32" */ + 0i) << s)
-
-	_ = int(1+0i<<0)
-	_ = int((1+0i)<<s)
-	_ = int(1.0<<s)
-	_ = int(complex(1, 0)<<s)
-	_ = int(float32/* ERROR "must be integer" */(1.0) <<s)
-	_ = int(1.1 /* ERROR must be integer */ <<s)
-	_ = int(( /* ERROR "must be integer" */ 1+1i)  <<s)
-
-	_ = complex(1 /* ERROR "must be integer" */ <<s, 0)
-
-	var b []int
-	_ = append(b, 1<<s)
-	_ = append(b, 1.0<<s)
-	_ = append(b, (1+0i)<<s)
-	_ = append(b, 1.1 /* ERROR "must be integer" */ <<s)
-	_ = append(b, (1 + 0i) <<s)
-	_ = append(b, ( /* ERROR "must be integer" */ 1 + 1i)  <<s)
-
-	_ = complex(1.0 /* ERROR "must be integer" */ <<s, 0)
-	_ = complex(1.1 /* ERROR "must be integer" */ <<s, 0)
-	_ = complex(0, 1.0 /* ERROR "must be integer" */ <<s)
-	_ = complex(0, 1.1 /* ERROR "must be integer" */ <<s)
-
-	// TODO(gri) The delete below is not type-checked correctly yet.
-	// var m1 map[int]string
-	// delete(m1, 1<<s)
-}
-
-func shifts7() {
-	// shifts of shifts
-	var s uint
-	var x int
-	_ = x
-
-	_ = 1<<(1<<s)
-	_ = 1<<(1.<<s)
-	_ = 1. /* ERROR "integer" */ <<(1<<s)
-	_ = 1. /* ERROR "integer" */ <<(1.<<s)
-
-	x = 1<<(1<<s)
-	x = 1<<(1.<<s)
-	x = 1.<<(1<<s)
-	x = 1.<<(1.<<s)
-
-	_ = (1<<s)<<(1<<s)
-	_ = (1<<s)<<(1.<<s)
-	_ = ( /* ERROR "integer" */ 1.<<s)<<(1<<s)
-	_ = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s)
-
-	x = (1<<s)<<(1<<s)
-	x = (1<<s)<<(1.<<s)
-	x = ( /* ERROR "integer" */ 1.<<s)<<(1<<s)
-	x = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s)
-}
-
-func shifts8() {
-	// shift examples from shift discussion: better error messages
-	var s uint
-	_ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1
-	_ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1.0
-	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s == 1.0
-	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.0 == 1
-	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.1 == 1
-	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1 == 1.0
-
-	// additional cases
-	_ = complex(1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s, 1)
-	_ = complex(1.0, 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s)
-
-	_ = int(1.<<s)
-	_ = int(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
-	_ = float32(1 /* ERROR "shifted operand .* must be integer" */ <<s)
-	_ = float32(1. /* ERROR "shifted operand .* must be integer" */ <<s)
-	_ = float32(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
-	// TODO(gri) the error messages for these two are incorrect - disabled for now
-	// _ = complex64(1<<s)
-	// _ = complex64(1.<<s)
-	_ = complex64(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
-}
-
-func shifts9() {
-	// various originally failing snippets of code from the std library
-	// from src/compress/lzw/reader.go:90
-	{
-		var d struct {
-			bits     uint32
-			width    uint
-		}
-		_ = uint16(d.bits & (1<<d.width - 1))
-	}
-
-	// from src/debug/dwarf/buf.go:116
-	{
-		var ux uint64
-		var bits uint
-		x := int64(ux)
-		if x&(1<<(bits-1)) != 0 {}
-	}
-
-	// from src/encoding/asn1/asn1.go:160
-	{
-		var bytes []byte
-		if bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {}
-	}
-
-	// from src/math/big/rat.go:140
-	{
-		var exp int
-		var mantissa uint64
-		shift := uint64(-1022 - (exp - 1)) // [1..53)
-		_ = mantissa & (1<<shift - 1)
-	}
-
-	// from src/net/interface.go:51
-	{
-		type Flags uint
-		var f Flags
-		var i int
-		if f&(1<<uint(i)) != 0 {}
-	}
-
-	// from src/runtime/softfloat64.go:234
-	{
-		var gm uint64
-		var shift uint
-		_ = gm & (1<<shift - 1)
-	}
-
-	// from src/strconv/atof.go:326
-	{
-		var mant uint64
-		var mantbits uint
-		if mant == 2<<mantbits {}
-	}
-
-	// from src/route_bsd.go:82
-	{
-		var Addrs int32
-		const rtaRtMask = 1
-		var i uint
-		if Addrs&rtaRtMask&(1<<i) == 0 {}
-	}
-
-	// from src/text/scanner/scanner.go:540
-	{
-		var s struct { Whitespace uint64 }
-		var ch rune
-		for s.Whitespace&(1<<uint(ch)) != 0 {}
-	}
-}
-
-func issue5895() {
-	var x = 'a' << 1 // type of x must be rune
-	var _ rune = x
-}
-
-func issue11325() {
-	var _ = 0 >> 1.1 /* ERROR "truncated to uint" */ // example from issue 11325
-	_ = 0 >> 1.1 /* ERROR "truncated to uint" */
-	_ = 0 << 1.1 /* ERROR "truncated to uint" */
-	_ = 0 >> 1.
-	_ = 1 >> 1.1 /* ERROR "truncated to uint" */
-	_ = 1 >> 1.
-	_ = 1. >> 1
-	_ = 1. >> 1.
-	_ = 1.1 /* ERROR "must be integer" */ >> 1
-}
-
-func issue11594() {
-	var _ = complex64 /* ERROR "must be integer" */ (1) << 2 // example from issue 11594
-	_ = float32 /* ERROR "must be integer" */ (0) << 1
-	_ = float64 /* ERROR "must be integer" */ (0) >> 2
-	_ = complex64 /* ERROR "must be integer" */ (0) << 3
-	_ = complex64 /* ERROR "must be integer" */ (0) >> 4
-}
-
-func issue21727() {
-	var s uint
-	var a = make([]int, 1<<s + 1.2 /* ERROR "truncated to int" */ )
-	var _ = a[1<<s - 2.3 /* ERROR "truncated to int" */ ]
-	var _ int = 1<<s + 3.4 /* ERROR "truncated to int" */
-	var _ = string(1 << s)
-	var _ = string(1.0 /* ERROR "cannot convert" */ << s)
-}
-
-func issue22969() {
-	var s uint
-	var a []byte
-	_ = a[0xffffffffffffffff /* ERROR "overflows int" */ <<s] // example from issue 22969
-	_ = make([]int, 0xffffffffffffffff /* ERROR "overflows int" */ << s)
-	_ = make([]int, 0, 0xffffffffffffffff /* ERROR "overflows int" */ << s)
-	var _ byte = 0x100 /* ERROR "overflows byte" */ << s
-	var _ int8 = 0xff /* ERROR "overflows int8" */ << s
-	var _ int16 = 0xffff /* ERROR "overflows int16" */ << s
-	var _ int32 = 0x80000000 /* ERROR "overflows int32" */ << s
-}
diff --git a/src/go/types/testdata/stmt0.src b/src/go/types/testdata/stmt0.src
deleted file mode 100644
index 1377729..0000000
--- a/src/go/types/testdata/stmt0.src
+++ /dev/null
@@ -1,980 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// statements
-
-package stmt0
-
-func assignments0() (int, int) {
-	var a, b, c int
-	var ch chan int
-	f0 := func() {}
-	f1 := func() int { return 1 }
-	f2 := func() (int, int) { return 1, 2 }
-	f3 := func() (int, int, int) { return 1, 2, 3 }
-
-	a, b, c = 1, 2, 3
-	a, b, c = 1 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ , 2
-	a, b, c = 1 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ , 2, 3, 4
-	_, _, _ = a, b, c
-
-	a = f0 /* ERROR "used as value" */ ()
-	a = f1()
-	a = f2 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
-	a, b = f2()
-	a, b, c = f2 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
-	a, b, c = f3()
-	a, b = f3 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
-
-	a, b, c = <- /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ch
-
-	return /* ERROR "wrong number of return values" */
-	return /* ERROR "wrong number of return values" */ 1
-	return 1, 2
-	return /* ERROR "wrong number of return values" */ 1, 2, 3
-}
-
-func assignments1() {
-	b, i, f, c, s := false, 1, 1.0, 1i, "foo"
-	b = i /* ERROR "cannot use .* in assignment" */
-	i = f /* ERROR "cannot use .* in assignment" */
-	f = c /* ERROR "cannot use .* in assignment" */
-	c = s /* ERROR "cannot use .* in assignment" */
-	s = b /* ERROR "cannot use .* in assignment" */
-
-	v0, v1, v2 := 1 /* ERROR "cannot initialize" */ , 2, 3, 4
-	_, _, _ = v0, v1, v2
-
-	b = true
-
-	i += 1
-	i += "foo" /* ERROR "cannot convert.*int" */
-
-	f -= 1
-	f /= 0
-	f = float32(0)/0 /* ERROR "division by zero" */
-	f -= "foo" /* ERROR "cannot convert.*float64" */
-
-	c *= 1
-	c /= 0
-
-	s += "bar"
-	s += 1 /* ERROR "cannot convert.*string" */
-
-	var u64 uint64
-	u64 += 1<<u64
-
-	undeclared /* ERROR "undeclared" */ = 991
-
-	// test cases for issue 5800
-	var (
-		_ int = nil /* ERROR "untyped nil value" */
-		_ [10]int = nil /* ERROR "untyped nil value" */
-		_ []byte = nil
-		_ struct{} = nil /* ERROR "untyped nil value" */
-		_ func() = nil
-		_ map[int]string = nil
-		_ chan int = nil
-	)
-
-	// test cases for issue 5500
-	_ = func() (int, bool) {
-		var m map[int]int
-		return /* ERROR "wrong number of return values" */ m[0]
-	}
-
-	g := func(int, bool){}
-	var m map[int]int
-	g(m[0]) /* ERROR "too few arguments" */
-
-	// assignments to _
-	_ = nil /* ERROR "use of untyped nil" */
-	_ = 1 /* ERROR overflow */ <<1000
-	(_) = 0
-}
-
-func assignments2() {
-	type mybool bool
-	var m map[string][]bool
-	var s []bool
-	var b bool
-	var d mybool
-	_ = s
-	_ = b
-	_ = d
-
-	// assignments to map index expressions are ok
-	s, b = m["foo"]
-	_, d = m["bar"]
-	m["foo"] = nil
-	m["foo"] = nil /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
-	_ = append(m["foo"])
-	_ = append(m["foo"], true)
-
-	var c chan int
-	_, b = <-c
-	_, d = <-c
-	<- /* ERROR cannot assign */ c = 0
-	<-c = 0 /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
-
-	var x interface{}
-	_, b = x.(int)
-	x /* ERROR cannot assign */ .(int) = 0
-	x.(int) = 0 /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
-
-	assignments2 /* ERROR used as value */ () = nil
-	int /* ERROR not an expression */ = 0
-}
-
-func issue6487() {
-	type S struct{x int}
-	_ = &S /* ERROR "cannot take address" */ {}.x
-	_ = &( /* ERROR "cannot take address" */ S{}.x)
-	_ = (&S{}).x
-	S /* ERROR "cannot assign" */ {}.x = 0
-	(&S{}).x = 0
-
-	type M map[string]S
-	var m M
-	m /* ERROR "cannot assign to struct field" */ ["foo"].x = 0
-	_ = &( /* ERROR "cannot take address" */ m["foo"].x)
-	_ = &m /* ERROR "cannot take address" */ ["foo"].x
-}
-
-func issue6766a() {
-	a, a /* ERROR redeclared */ := 1, 2
-	_ = a
-	a, b, b /* ERROR redeclared */ := 1, 2, 3
-	_ = b
-	c, c /* ERROR redeclared */, b := 1, 2, 3
-	_ = c
-	a, b := /* ERROR no new variables */ 1, 2
-}
-
-func shortVarDecls1() {
-	const c = 0
-	type d int
-	a, b, c /* ERROR "cannot assign" */ , d /* ERROR "cannot assign" */  := 1, "zwei", 3.0, 4
-	var _ int = a // a is of type int
-	var _ string = b // b is of type string
-}
-
-func incdecs() {
-	const c = 3.14
-	c /* ERROR "cannot assign" */ ++
-	s := "foo"
-	s /* ERROR "invalid operation" */ --
-	3.14 /* ERROR "cannot assign" */ ++
-	var (
-		x int
-		y float32
-		z complex128
-	)
-	x++
-	y--
-	z++
-}
-
-func sends() {
-	var ch chan int
-	var rch <-chan int
-	var x int
-	x <- /* ERROR "cannot send" */ x
-	rch <- /* ERROR "cannot send" */ x
-	ch <- "foo" /* ERROR "cannot use .* in send" */
-	ch <- x
-}
-
-func selects() {
-	select {}
-	var (
-		ch chan int
-		sc chan <- bool
-	)
-	select {
-	case <-ch:
-	case (<-ch):
-	case t := <-ch:
-		_ = t
-	case t := (<-ch):
-		_ = t
-	case t, ok := <-ch:
-		_, _ = t, ok
-	case t, ok := (<-ch):
-		_, _ = t, ok
-	case <-sc /* ERROR "cannot receive from send-only channel" */ :
-	}
-	select {
-	default:
-	default /* ERROR "multiple defaults" */ :
-	}
-	select {
-	case a, b := <-ch:
-		_, b = a, b
-	case x /* ERROR send or receive */ :
-	case a /* ERROR send or receive */ := ch:
-	}
-
-	// test for issue 9570: ch2 in second case falsely resolved to
-	// ch2 declared in body of first case
-	ch1 := make(chan int)
-	ch2 := make(chan int)
-	select {
-	case <-ch1:
-		var ch2 /* ERROR ch2 declared but not used */ chan bool
-	case i := <-ch2:
-		print(i + 1)
-	}
-}
-
-func gos() {
-	go 1 /* ERROR HERE "function must be invoked" */
-	go int /* ERROR "go requires function call, not conversion" */ (0)
-	go gos()
-	var c chan int
-	go close(c)
-	go len /* ERROR "go discards result" */ (c)
-}
-
-func defers() {
-	defer 1 /* ERROR HERE "function must be invoked" */
-	defer int /* ERROR "defer requires function call, not conversion" */ (0)
-	defer defers()
-	var c chan int
-	defer close(c)
-	defer len /* ERROR "defer discards result" */ (c)
-}
-
-func breaks() {
-	var x, y int
-
-	break /* ERROR "break" */
-	{
-		break /* ERROR "break" */
-	}
-	if x < y {
-		break /* ERROR "break" */
-	}
-
-	switch x {
-	case 0:
-		break
-	case 1:
-		if x == y {
-			break
-		}
-	default:
-		break
-		break
-	}
-
-	var z interface{}
-	switch z.(type) {
-	case int:
-		break
-	}
-
-	for {
-		break
-	}
-
-	var a []int
-	for _ = range a {
-		break
-	}
-
-	for {
-		if x == y {
-			break
-		}
-	}
-
-	var ch chan int
-	select {
-	case <-ch:
-		break
-	}
-
-	select {
-	case <-ch:
-		if x == y {
-			break
-		}
-	default:
-		break
-	}
-}
-
-func continues() {
-	var x, y int
-
-	continue /* ERROR "continue" */
-	{
-		continue /* ERROR "continue" */
-	}
-
-	if x < y {
-		continue /* ERROR "continue" */
-	}
-
-	switch x {
-	case 0:
-		continue /* ERROR "continue" */
-	}
-
-	var z interface{}
-	switch z.(type) {
-	case int:
-		continue /* ERROR "continue" */
-	}
-
-	var ch chan int
-	select {
-	case <-ch:
-		continue /* ERROR "continue" */
-	}
-
-	for i := 0; i < 10; i++ {
-		continue
-		if x < y {
-			continue
-			break
-		}
-		switch x {
-		case y:
-			continue
-		default:
-			break
-		}
-		select {
-		case <-ch:
-			continue
-		}
-	}
-
-	var a []int
-	for _ = range a {
-		continue
-		if x < y {
-			continue
-			break
-		}
-		switch x {
-		case y:
-			continue
-		default:
-			break
-		}
-		select {
-		case <-ch:
-			continue
-		}
-	}
-}
-
-func returns0() {
-	return
-	return 0 /* ERROR no result values expected */
-}
-
-func returns1(x float64) (int, *float64) {
-	return 0, &x
-	return /* ERROR wrong number of return values */
-	return "foo" /* ERROR "cannot .* in return statement" */, x /* ERROR "cannot use .* in return statement" */
-	return /* ERROR wrong number of return values */ 0, &x, 1
-}
-
-func returns2() (a, b int) {
-	return
-	return 1, "foo" /* ERROR cannot use .* in return statement */
-	return /* ERROR wrong number of return values */ 1, 2, 3
-	{
-		type a int
-		return 1, 2
-		return /* ERROR a not in scope at return */
-	}
-}
-
-func returns3() (_ int) {
-	return
-	{
-		var _ int // blank (_) identifiers never shadow since they are in no scope
-		return
-	}
-}
-
-func switches0() {
-	var x int
-
-	switch x {
-	}
-
-	switch x {
-	default:
-	default /* ERROR "multiple defaults" */ :
-	}
-
-	switch {
-	case 1  /* ERROR "cannot convert" */ :
-	}
-
-	true := "false"
-	_ = true
-	// A tagless switch is equivalent to the bool
-        // constant true, not the identifier 'true'.
-	switch {
-	case "false" /* ERROR "cannot convert" */:
-	}
-
-	switch int32(x) {
-	case 1, 2:
-	case x /* ERROR "cannot compare" */ :
-	}
-
-	switch x {
-	case 1 /* ERROR "overflows" */ << 100:
-	}
-
-	switch x {
-	case 1:
-	case 1 /* ERROR "duplicate case" */ :
-	case ( /* ERROR "duplicate case" */ 1):
-	case 2, 3, 4:
-	case 5, 1 /* ERROR "duplicate case" */ :
-	}
-
-	switch uint64(x) {
-	case 1<<64 - 1:
-	case 1 /* ERROR duplicate case */ <<64 - 1:
-	case 2, 3, 4:
-	case 5, 1 /* ERROR duplicate case */ <<64 - 1:
-	}
-
-	var y32 float32
-	switch y32 {
-	case 1.1:
-	case 11/10: // integer division!
-	case 11. /* ERROR duplicate case */ /10:
-	case 2, 3.0, 4.1:
-	case 5.2, 1.10 /* ERROR duplicate case */ :
-	}
-
-	var y64 float64
-	switch y64 {
-	case 1.1:
-	case 11/10: // integer division!
-	case 11. /* ERROR duplicate case */ /10:
-	case 2, 3.0, 4.1:
-	case 5.2, 1.10 /* ERROR duplicate case */ :
-	}
-
-	var s string
-	switch s {
-	case "foo":
-	case "foo" /* ERROR duplicate case */ :
-	case "f" /* ERROR duplicate case */ + "oo":
-	case "abc", "def", "ghi":
-	case "jkl", "foo" /* ERROR duplicate case */ :
-	}
-
-	type T int
-	type F float64
-	type S string
-	type B bool
-	var i interface{}
-	switch i {
-	case nil:
-	case nil: // no duplicate detection
-	case (*int)(nil):
-	case (*int)(nil): // do duplicate detection
-	case 1:
-	case byte(1):
-	case int /* ERROR duplicate case */ (1):
-	case T(1):
-	case 1.0:
-	case F(1.0):
-	case F /* ERROR duplicate case */ (1.0):
-	case "hello":
-	case S("hello"):
-	case S /* ERROR duplicate case */ ("hello"):
-	case 1==1, B(false):
-	case false, B(2==2):
-	}
-
-	// switch on array
-	var a [3]int
-	switch a {
-	case [3]int{1, 2, 3}:
-	case [3]int{1, 2, 3}: // no duplicate detection
-	case [ /* ERROR "mismatched types */ 4]int{4, 5, 6}:
-	}
-
-	// switch on channel
-	var c1, c2 chan int
-	switch c1 {
-	case nil:
-	case c1:
-	case c2:
-	case c1, c2: // no duplicate detection
-	}
-}
-
-func switches1() {
-	fallthrough /* ERROR "fallthrough statement out of place" */
-
-	var x int
-	switch x {
-	case 0:
-		fallthrough /* ERROR "fallthrough statement out of place" */
-		break
-	case 1:
-		fallthrough
-	case 2:
-		fallthrough; ; ; // trailing empty statements are ok
-	case 3:
-	default:
-		fallthrough; ;
-	case 4:
-		fallthrough /* ERROR "cannot fallthrough final case in switch" */
-	}
-
-	var y interface{}
-	switch y.(type) {
-	case int:
-		fallthrough /* ERROR "fallthrough statement out of place" */ ; ; ;
-	default:
-	}
-
-	switch x {
-	case 0:
-		if x == 0 {
-			fallthrough /* ERROR "fallthrough statement out of place" */
-		}
-	}
-
-	switch x {
-	case 0:
-		goto L1
-		L1: fallthrough; ;
-	case 1:
-		goto L2
-		goto L3
-		goto L4
-		L2: L3: L4: fallthrough
-	default:
-	}
-
-	switch x {
-	case 0:
-		goto L5
-		L5: fallthrough
-	default:
-		goto L6
-		goto L7
-		goto L8
-		L6: L7: L8: fallthrough /* ERROR "cannot fallthrough final case in switch" */
-	}
-
-	switch x {
-	case 0:
-		fallthrough; ;
-	case 1:
-		{
-			fallthrough /* ERROR "fallthrough statement out of place" */
-		}
-	case 2:
-		fallthrough
-	case 3:
-		fallthrough /* ERROR "fallthrough statement out of place" */
-		{ /* empty block is not an empty statement */ }; ;
-	default:
-		fallthrough /* ERROR "cannot fallthrough final case in switch" */
-	}
-
-	switch x {
-	case 0:
-		{
-			fallthrough /* ERROR "fallthrough statement out of place" */
-		}
-	}
-}
-
-func switches2() {
-	// untyped nil is not permitted as switch expression
-	switch nil /* ERROR "use of untyped nil" */ {
-	case 1, 2, "foo": // don't report additional errors here
-	}
-
-	// untyped constants are converted to default types
-	switch 1<<63-1 {
-	}
-	switch 1 /* ERROR "cannot use .* as int value.*\(overflows\)" */ << 63 {
-	}
-	var x int
-	switch 1.0 {
-	case 1.0, 2.0, x /* ERROR "mismatched types int and float64" */ :
-	}
-	switch x {
-	case 1.0:
-	}
-
-	// untyped bools become of type bool
-	type B bool
-	var b B = true
-	switch x == x {
-	case b /* ERROR "mismatched types B and bool" */ :
-	}
-	switch {
-	case b /* ERROR "mismatched types B and bool" */ :
-	}
-}
-
-func issue11667() {
-	switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ {
-	}
-	switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ {
-	case 9223372036854775808:
-	}
-	var x int
-	switch x {
-	case 9223372036854775808 /* ERROR "overflows int" */ :
-	}
-	var y float64
-	switch y {
-	case 9223372036854775808:
-	}
-}
-
-func issue11687() {
-	f := func() (_, _ int) { return }
-	switch f /* ERROR "2-valued f" */ () {
-	}
-	var x int
-	switch f /* ERROR "2-valued f" */ () {
-	case x:
-	}
-	switch x {
-	case f /* ERROR "2-valued f" */ ():
-	}
-}
-
-type I interface {
-	m()
-}
-
-type I2 interface {
-	m(int)
-}
-
-type T struct{}
-type T1 struct{}
-type T2 struct{}
-
-func (T) m() {}
-func (T2) m(int) {}
-
-func typeswitches() {
-	var i int
-	var x interface{}
-
-	switch x.(type) {}
-	switch (x /* ERROR "outside type switch" */ .(type)) {}
-
-	switch x.(type) {
-	default:
-	default /* ERROR "multiple defaults" */ :
-	}
-
-	switch x /* ERROR "declared but not used" */ := x.(type) {}
-	switch _ /* ERROR "no new variable on left side of :=" */ := x.(type) {}
-
-	switch x := x.(type) {
-	case int:
-		var y int = x
-		_ = y
-	}
-
-	switch x := i /* ERROR "not an interface" */ .(type) {}
-
-	switch t := x.(type) {
-	case nil:
-		var v bool = t /* ERROR "cannot use .* in variable declaration" */
-		_ = v
-	case int:
-		var v int = t
-		_ = v
-	case float32, complex64:
-		var v float32 = t /* ERROR "cannot use .* in variable declaration" */
-		_ = v
-	default:
-		var v float32 = t /* ERROR "cannot use .* in variable declaration" */
-		_ = v
-	}
-
-	var t I
-	switch t.(type) {
-	case T:
-	case T1 /* ERROR "missing method m" */ :
-	case T2 /* ERROR "wrong type for method m" */ :
-	case I2 /* STRICT "wrong type for method m" */ : // only an error in strict mode (issue 8561)
-	}
-}
-
-// Test that each case clause uses the correct type of the variable
-// declared by the type switch (issue 5504).
-func typeswitch0() {
-	switch y := interface{}(nil).(type) {
-	case int:
-		func() int { return y + 0 }()
-	case float32:
-		func() float32 { return y }()
-	}
-}
-
-// Test correct scope setup.
-// (no redeclaration errors expected in the type switch)
-func typeswitch1() {
-	var t I
-	switch t := t; t := t.(type) {
-	case nil:
-		var _ I = t
-	case T:
-		var _ T = t
-	default:
-		var _ I = t
-	}
-}
-
-// Test correct typeswitch against interface types.
-type A interface { a() }
-type B interface { b() }
-type C interface { a(int) }
-
-func typeswitch2() {
-	switch A(nil).(type) {
-	case A:
-	case B:
-	case C /* STRICT "cannot have dynamic type" */: // only an error in strict mode (issue 8561)
-	}
-}
-
-func typeswitch3(x interface{}) {
-	switch x.(type) {
-	case int:
-	case float64:
-	case int /* ERROR duplicate case */ :
-	}
-
-	switch x.(type) {
-	case nil:
-	case int:
-	case nil /* ERROR duplicate case */ , nil /* ERROR duplicate case */ :
-	}
-
-	type F func(int)
-	switch x.(type) {
-	case nil:
-	case int, func(int):
-	case float32, func /* ERROR duplicate case */ (x int):
-	case F:
-	}
-}
-
-func fors1() {
-	for {}
-	var i string
-	_ = i
-	for i := 0; i < 10; i++ {}
-	for i := 0; i < 10; j /* ERROR cannot declare */ := 0 {}
-}
-
-func rangeloops1() {
-	var (
-		x int
-		a [10]float32
-		b []string
-		p *[10]complex128
-		pp **[10]complex128
-		s string
-		m map[int]bool
-		c chan int
-		sc chan<- int
-		rc <-chan int
-	)
-
-	for range x /* ERROR "cannot range over" */ {}
-	for _ = range x /* ERROR "cannot range over" */ {}
-	for i := range x /* ERROR "cannot range over" */ {}
-
-	for range a {}
-	for i := range a {
-		var ii int
-		ii = i
-		_ = ii
-	}
-	for i, x := range a {
-		var ii int
-		ii = i
-		_ = ii
-		var xx float64
-		xx = x /* ERROR "cannot use .* in assignment" */
-		_ = xx
-	}
-	var ii int
-	var xx float32
-	for ii, xx = range a {}
-	_, _ = ii, xx
-
-	for range b {}
-	for i := range b {
-		var ii int
-		ii = i
-		_ = ii
-	}
-	for i, x := range b {
-		var ii int
-		ii = i
-		_ = ii
-		var xx string
-		xx = x
-		_ = xx
-	}
-
-	for range s {}
-	for i := range s {
-		var ii int
-		ii = i
-		_ = ii
-	}
-	for i, x := range s {
-		var ii int
-		ii = i
-		_ = ii
-		var xx rune
-		xx = x
-		_ = xx
-	}
-
-	for range p {}
-	for _, x := range p {
-		var xx complex128
-		xx = x
-		_ = xx
-	}
-
-	for range pp /* ERROR "cannot range over" */ {}
-	for _, x := range pp /* ERROR "cannot range over" */ {}
-
-	for range m {}
-	for k := range m {
-		var kk int32
-		kk = k /* ERROR "cannot use .* in assignment" */
-		_ = kk
-	}
-	for k, v := range m {
-		var kk int
-		kk = k
-		_ = kk
-		if v {}
-	}
-
-	for range c {}
-	for _, _ /* ERROR "only one iteration variable" */ = range c {}
-	for e := range c {
-		var ee int
-		ee = e
-		_ = ee
-	}
-	for _ = range sc /* ERROR "cannot range over send-only channel" */ {}
-	for _ = range rc {}
-
-	// constant strings
-	const cs = "foo"
-	for range cs {}
-	for range "" {}
-	for i, x := range cs { _, _ = i, x }
-	for i, x := range "" {
-		var ii int
-		ii = i
-		_ = ii
-		var xx rune
-		xx = x
-		_ = xx
-	}
-}
-
-func rangeloops2() {
-	type I int
-	type R rune
-
-	var a [10]int
-	var i I
-	_ = i
-	for i /* ERROR cannot use .* in assignment */ = range a {}
-	for i /* ERROR cannot use .* in assignment */ = range &a {}
-	for i /* ERROR cannot use .* in assignment */ = range a[:] {}
-
-	var s string
-	var r R
-	_ = r
-	for i /* ERROR cannot use .* in assignment */ = range s {}
-	for i /* ERROR cannot use .* in assignment */ = range "foo" {}
-	for _, r /* ERROR cannot use .* in assignment */ = range s {}
-	for _, r /* ERROR cannot use .* in assignment */ = range "foo" {}
-}
-
-func issue6766b() {
-	for _ := /* ERROR no new variables */ range "" {}
-	for a, a /* ERROR redeclared */ := range "" { _ = a }
-	var a int
-	_ = a
-	for a, a /* ERROR redeclared */ := range []int{1, 2, 3} { _ = a }
-}
-
-// Test that despite errors in the range clause,
-// the loop body is still type-checked (and thus
-// errors reported).
-func issue10148() {
-	for y /* ERROR declared but not used */ := range "" {
-		_ = "" /* ERROR cannot convert */ + 1
-	}
-	for range 1 /* ERROR cannot range over 1 */ {
-		_ = "" /* ERROR cannot convert */ + 1
-	}
-	for y := range 1 /* ERROR cannot range over 1 */ {
-		_ = "" /* ERROR cannot convert */ + 1
-	}
-}
-
-func labels0() {
-	goto L0
-	goto L1
-	L0:
-	L1:
-	L1 /* ERROR "already declared" */ :
-	if true {
-		goto L2
-		L2:
-		L0 /* ERROR "already declared" */ :
-	}
-	_ = func() {
-		goto L0
-		goto L1
-		goto L2
-		L0:
-		L1:
-		L2:
-	}
-}
-
-func expression_statements(ch chan int) {
-	expression_statements(ch)
-	<-ch
-	println()
-
-	0 /* ERROR "not used" */
-	1 /* ERROR "not used" */ +2
-	cap /* ERROR "not used" */ (ch)
-	println /* ERROR "must be called" */
-}
diff --git a/src/go/types/type.go b/src/go/types/type.go
index 087cda4..2660ce4 100644
--- a/src/go/types/type.go
+++ b/src/go/types/type.go
@@ -4,12 +4,18 @@
 
 package types
 
-import "sort"
+import (
+	"fmt"
+	"go/token"
+	"sync/atomic"
+)
 
 // A Type represents a type of Go.
 // All types implement the Type interface.
 type Type interface {
-	// Underlying returns the underlying type of a type.
+	// Underlying returns the underlying type of a type
+	// w/o following forwarding chains. Only used by
+	// client packages (here for backward-compatibility).
 	Underlying() Type
 
 	// String returns a string representation of a type.
@@ -98,7 +104,7 @@
 
 // NewArray returns a new array type for the given element type and length.
 // A negative length indicates an unknown length.
-func NewArray(elem Type, len int64) *Array { return &Array{len, elem} }
+func NewArray(elem Type, len int64) *Array { return &Array{len: len, elem: elem} }
 
 // Len returns the length of array a.
 // A negative result indicates an unknown length.
@@ -113,7 +119,7 @@
 }
 
 // NewSlice returns a new slice type for the given element type.
-func NewSlice(elem Type) *Slice { return &Slice{elem} }
+func NewSlice(elem Type) *Slice { return &Slice{elem: elem} }
 
 // Elem returns the element type of slice s.
 func (s *Slice) Elem() Type { return s.elem }
@@ -176,8 +182,10 @@
 // NewTuple returns a new tuple for the given variables.
 func NewTuple(x ...*Var) *Tuple {
 	if len(x) > 0 {
-		return &Tuple{x}
+		return &Tuple{vars: x}
 	}
+	// TODO(gri) Don't represent empty tuples with a (*Tuple)(nil) pointer;
+	//           it's too subtle and causes problems.
 	return nil
 }
 
@@ -199,11 +207,13 @@
 	// and store it in the Func Object) because when type-checking a function
 	// literal we call the general type checker which returns a general Type.
 	// We then unpack the *Signature and use the scope for the literal body.
-	scope    *Scope // function scope, present for package-local signatures
-	recv     *Var   // nil if not a method
-	params   *Tuple // (incoming) parameters from left to right; or nil
-	results  *Tuple // (outgoing) results from left to right; or nil
-	variadic bool   // true if the last parameter's type is of the form ...T (or string, for append built-in only)
+	rparams  []*TypeName // receiver type parameters from left to right, or nil
+	tparams  []*TypeName // type parameters from left to right, or nil
+	scope    *Scope      // function scope, present for package-local signatures
+	recv     *Var        // nil if not a method
+	params   *Tuple      // (incoming) parameters from left to right; or nil
+	results  *Tuple      // (outgoing) results from left to right; or nil
+	variadic bool        // true if the last parameter's type is of the form ...T (or string, for append built-in only)
 }
 
 // NewSignature returns a new function type for the given receiver, parameters,
@@ -220,7 +230,7 @@
 			panic("types.NewSignature: variadic parameter must be of unnamed slice type")
 		}
 	}
-	return &Signature{nil, recv, params, results, variadic}
+	return &Signature{recv: recv, params: params, results: results, variadic: variadic}
 }
 
 // Recv returns the receiver of signature s (if a method), or nil if a
@@ -231,6 +241,12 @@
 // contain methods whose receiver type is a different interface.
 func (s *Signature) Recv() *Var { return s.recv }
 
+// _TParams returns the type parameters of signature s, or nil.
+func (s *Signature) _TParams() []*TypeName { return s.tparams }
+
+// _SetTParams sets the type parameters of signature s.
+func (s *Signature) _SetTParams(tparams []*TypeName) { s.tparams = tparams }
+
 // Params returns the parameters of signature s, or nil.
 func (s *Signature) Params() *Tuple { return s.params }
 
@@ -240,12 +256,88 @@
 // Variadic reports whether the signature s is variadic.
 func (s *Signature) Variadic() bool { return s.variadic }
 
+// A _Sum represents a set of possible types.
+// Sums are currently used to represent type lists of interfaces
+// and thus the underlying types of type parameters; they are not
+// first class types of Go.
+type _Sum struct {
+	types []Type // types are unique
+}
+
+// _NewSum returns a new Sum type consisting of the provided
+// types if there are more than one. If there is exactly one
+// type, it returns that type. If the list of types is empty
+// the result is nil.
+func _NewSum(types []Type) Type {
+	if len(types) == 0 {
+		return nil
+	}
+
+	// What should happen if types contains a sum type?
+	// Do we flatten the types list? For now we check
+	// and panic. This should not be possible for the
+	// current use case of type lists.
+	// TODO(gri) Come up with the rules for sum types.
+	for _, t := range types {
+		if _, ok := t.(*_Sum); ok {
+			panic("sum type contains sum type - unimplemented")
+		}
+	}
+
+	if len(types) == 1 {
+		return types[0]
+	}
+	return &_Sum{types: types}
+}
+
+// is reports whether all types in t satisfy pred.
+func (s *_Sum) is(pred func(Type) bool) bool {
+	if s == nil {
+		return false
+	}
+	for _, t := range s.types {
+		if !pred(t) {
+			return false
+		}
+	}
+	return true
+}
+
 // An Interface represents an interface type.
 type Interface struct {
 	methods   []*Func // ordered list of explicitly declared methods
+	types     Type    // (possibly a Sum) type declared with a type list (TODO(gri) need better field name)
 	embeddeds []Type  // ordered list of explicitly embedded types
 
 	allMethods []*Func // ordered list of methods declared with or embedded in this interface (TODO(gri): replace with mset)
+	allTypes   Type    // intersection of all embedded and locally declared types  (TODO(gri) need better field name)
+
+	obj Object // type declaration defining this interface; or nil (for better error messages)
+}
+
+// unpack unpacks a type into a list of types.
+// TODO(gri) Try to eliminate the need for this function.
+func unpackType(typ Type) []Type {
+	if typ == nil {
+		return nil
+	}
+	if sum := asSum(typ); sum != nil {
+		return sum.types
+	}
+	return []Type{typ}
+}
+
+// is reports whether interface t represents types that all satisfy pred.
+func (t *Interface) is(pred func(Type) bool) bool {
+	if t.allTypes == nil {
+		return false // we must have at least one type! (was bug)
+	}
+	for _, t := range unpackType(t.allTypes) {
+		if !pred(t) {
+			return false
+		}
+	}
+	return true
 }
 
 // emptyInterface represents the empty (completed) interface
@@ -301,8 +393,8 @@
 	}
 
 	// sort for API stability
-	sort.Sort(byUniqueMethodName(methods))
-	sort.Stable(byUniqueTypeName(embeddeds))
+	sortMethods(methods)
+	sortTypes(embeddeds)
 
 	typ.methods = methods
 	typ.embeddeds = embeddeds
@@ -344,8 +436,101 @@
 func (t *Interface) Method(i int) *Func { t.assertCompleteness(); return t.allMethods[i] }
 
 // Empty reports whether t is the empty interface.
-// The interface must have been completed.
-func (t *Interface) Empty() bool { t.assertCompleteness(); return len(t.allMethods) == 0 }
+func (t *Interface) Empty() bool {
+	if t.allMethods != nil {
+		// interface is complete - quick test
+		// A non-nil allTypes may still be empty and represents the bottom type.
+		return len(t.allMethods) == 0 && t.allTypes == nil
+	}
+	return !t.iterate(func(t *Interface) bool {
+		return len(t.methods) > 0 || t.types != nil
+	}, nil)
+}
+
+// _HasTypeList reports whether interface t has a type list, possibly from an embedded type.
+func (t *Interface) _HasTypeList() bool {
+	if t.allMethods != nil {
+		// interface is complete - quick test
+		return t.allTypes != nil
+	}
+
+	return t.iterate(func(t *Interface) bool {
+		return t.types != nil
+	}, nil)
+}
+
+// _IsComparable reports whether interface t is or embeds the predeclared interface "comparable".
+func (t *Interface) _IsComparable() bool {
+	if t.allMethods != nil {
+		// interface is complete - quick test
+		_, m := lookupMethod(t.allMethods, nil, "==")
+		return m != nil
+	}
+
+	return t.iterate(func(t *Interface) bool {
+		_, m := lookupMethod(t.methods, nil, "==")
+		return m != nil
+	}, nil)
+}
+
+// _IsConstraint reports t.HasTypeList() || t.IsComparable().
+func (t *Interface) _IsConstraint() bool {
+	if t.allMethods != nil {
+		// interface is complete - quick test
+		if t.allTypes != nil {
+			return true
+		}
+		_, m := lookupMethod(t.allMethods, nil, "==")
+		return m != nil
+	}
+
+	return t.iterate(func(t *Interface) bool {
+		if t.types != nil {
+			return true
+		}
+		_, m := lookupMethod(t.methods, nil, "==")
+		return m != nil
+	}, nil)
+}
+
+// iterate calls f with t and then with any embedded interface of t, recursively, until f returns true.
+// iterate reports whether any call to f returned true.
+func (t *Interface) iterate(f func(*Interface) bool, seen map[*Interface]bool) bool {
+	if f(t) {
+		return true
+	}
+	for _, e := range t.embeddeds {
+		// e should be an interface but be careful (it may be invalid)
+		if e := asInterface(e); e != nil {
+			// Cyclic interfaces such as "type E interface { E }" are not permitted
+			// but they are still constructed and we need to detect such cycles.
+			if seen[e] {
+				continue
+			}
+			if seen == nil {
+				seen = make(map[*Interface]bool)
+			}
+			seen[e] = true
+			if e.iterate(f, seen) {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// isSatisfiedBy reports whether interface t's type list is satisfied by the type typ.
+// If the type list is empty (absent), typ trivially satisfies the interface.
+// TODO(gri) This is not a great name. Eventually, we should have a more comprehensive
+//           "implements" predicate.
+func (t *Interface) isSatisfiedBy(typ Type) bool {
+	t.Complete()
+	if t.allTypes == nil {
+		return true
+	}
+	types := unpackType(t.allTypes)
+	return includes(types, typ) || includes(types, under(typ))
+}
 
 // Complete computes the interface's method set. It must be called by users of
 // NewInterfaceType and NewInterface after the interface's embedded types are
@@ -379,12 +564,22 @@
 		addMethod(m, true)
 	}
 
+	allTypes := t.types
+
 	for _, typ := range t.embeddeds {
-		typ := typ.Underlying().(*Interface)
-		typ.Complete()
-		for _, m := range typ.allMethods {
+		utyp := under(typ)
+		etyp := asInterface(utyp)
+		if etyp == nil {
+			if utyp != Typ[Invalid] {
+				panic(fmt.Sprintf("%s is not an interface", typ))
+			}
+			continue
+		}
+		etyp.Complete()
+		for _, m := range etyp.allMethods {
 			addMethod(m, false)
 		}
+		allTypes = intersect(allTypes, etyp.allTypes)
 	}
 
 	for i := 0; i < len(todo); i += 2 {
@@ -396,9 +591,10 @@
 	}
 
 	if methods != nil {
-		sort.Sort(byUniqueMethodName(methods))
+		sortMethods(methods)
 		t.allMethods = methods
 	}
+	t.allTypes = allTypes
 
 	return t
 }
@@ -410,7 +606,7 @@
 
 // NewMap returns a new map for the given key and element types.
 func NewMap(key, elem Type) *Map {
-	return &Map{key, elem}
+	return &Map{key: key, elem: elem}
 }
 
 // Key returns the key type of map m.
@@ -437,7 +633,7 @@
 
 // NewChan returns a new channel type for the given direction and element type.
 func NewChan(dir ChanDir, elem Type) *Chan {
-	return &Chan{dir, elem}
+	return &Chan{dir: dir, elem: elem}
 }
 
 // Dir returns the direction of channel c.
@@ -446,13 +642,16 @@
 // Elem returns the element type of channel c.
 func (c *Chan) Elem() Type { return c.elem }
 
-// A Named represents a named type.
+// A Named represents a named (defined) type.
 type Named struct {
-	info       typeInfo  // for cycle detection
-	obj        *TypeName // corresponding declared object
-	orig       Type      // type (on RHS of declaration) this *Named type is derived of (for cycle reporting)
-	underlying Type      // possibly a *Named during setup; never a *Named once set up completely
-	methods    []*Func   // methods declared for this type (not the method set of this type); signatures are type-checked lazily
+	check      *Checker    // for Named.under implementation; nilled once under has been called
+	info       typeInfo    // for cycle detection
+	obj        *TypeName   // corresponding declared object
+	orig       Type        // type (on RHS of declaration) this *Named type is derived of (for cycle reporting)
+	underlying Type        // possibly a *Named during setup; never a *Named once set up completely
+	tparams    []*TypeName // type parameters, or nil
+	targs      []Type      // type arguments (after instantiation), or nil
+	methods    []*Func     // methods declared for this type (not the method set of this type); signatures are type-checked lazily
 }
 
 // NewNamed returns a new named type for the given type name, underlying type, and associated methods.
@@ -462,16 +661,50 @@
 	if _, ok := underlying.(*Named); ok {
 		panic("types.NewNamed: underlying type must not be *Named")
 	}
-	typ := &Named{obj: obj, orig: underlying, underlying: underlying, methods: methods}
+	return (*Checker)(nil).newNamed(obj, underlying, methods)
+}
+
+func (check *Checker) newNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
+	typ := &Named{check: check, obj: obj, orig: underlying, underlying: underlying, methods: methods}
 	if obj.typ == nil {
 		obj.typ = typ
 	}
+	// Ensure that typ is always expanded, at which point the check field can be
+	// nilled out.
+	//
+	// Note that currently we cannot nil out check inside typ.under(), because
+	// it's possible that typ is expanded multiple times.
+	//
+	// TODO(rFindley): clean this up so that under is the only function mutating
+	//                 named types.
+	if check != nil {
+		check.later(func() {
+			switch typ.under().(type) {
+			case *Named, *instance:
+				panic("internal error: unexpanded underlying type")
+			}
+			typ.check = nil
+		})
+	}
 	return typ
 }
 
 // Obj returns the type name for the named type t.
 func (t *Named) Obj() *TypeName { return t.obj }
 
+// TODO(gri) Come up with a better representation and API to distinguish
+//           between parameterized instantiated and non-instantiated types.
+
+// _TParams returns the type parameters of the named type t, or nil.
+// The result is non-nil for an (originally) parameterized type even if it is instantiated.
+func (t *Named) _TParams() []*TypeName { return t.tparams }
+
+// _TArgs returns the type arguments after instantiation of the named type t, or nil if not instantiated.
+func (t *Named) _TArgs() []Type { return t.targs }
+
+// _SetTArgs sets the type arguments of Named.
+func (t *Named) _SetTArgs(args []Type) { t.targs = args }
+
 // NumMethods returns the number of explicit methods whose receiver is named type t.
 func (t *Named) NumMethods() int { return len(t.methods) }
 
@@ -496,28 +729,258 @@
 	}
 }
 
-// Implementations for Type methods.
+// Note: This is a uint32 rather than a uint64 because the
+// respective 64 bit atomic instructions are not available
+// on all platforms.
+var lastId uint32
 
-func (b *Basic) Underlying() Type     { return b }
-func (a *Array) Underlying() Type     { return a }
-func (s *Slice) Underlying() Type     { return s }
-func (s *Struct) Underlying() Type    { return s }
-func (p *Pointer) Underlying() Type   { return p }
-func (t *Tuple) Underlying() Type     { return t }
-func (s *Signature) Underlying() Type { return s }
-func (t *Interface) Underlying() Type { return t }
-func (m *Map) Underlying() Type       { return m }
-func (c *Chan) Underlying() Type      { return c }
-func (t *Named) Underlying() Type     { return t.underlying }
+// nextId returns a value increasing monotonically by 1 with
+// each call, starting with 1. It may be called concurrently.
+func nextId() uint64 { return uint64(atomic.AddUint32(&lastId, 1)) }
 
-func (b *Basic) String() string     { return TypeString(b, nil) }
-func (a *Array) String() string     { return TypeString(a, nil) }
-func (s *Slice) String() string     { return TypeString(s, nil) }
-func (s *Struct) String() string    { return TypeString(s, nil) }
-func (p *Pointer) String() string   { return TypeString(p, nil) }
-func (t *Tuple) String() string     { return TypeString(t, nil) }
-func (s *Signature) String() string { return TypeString(s, nil) }
-func (t *Interface) String() string { return TypeString(t, nil) }
-func (m *Map) String() string       { return TypeString(m, nil) }
-func (c *Chan) String() string      { return TypeString(c, nil) }
-func (t *Named) String() string     { return TypeString(t, nil) }
+// A _TypeParam represents a type parameter type.
+type _TypeParam struct {
+	check *Checker  // for lazy type bound completion
+	id    uint64    // unique id
+	obj   *TypeName // corresponding type name
+	index int       // parameter index
+	bound Type      // *Named or *Interface; underlying type is always *Interface
+}
+
+// newTypeParam returns a new TypeParam.
+func (check *Checker) newTypeParam(obj *TypeName, index int, bound Type) *_TypeParam {
+	assert(bound != nil)
+	typ := &_TypeParam{check: check, id: nextId(), obj: obj, index: index, bound: bound}
+	if obj.typ == nil {
+		obj.typ = typ
+	}
+	return typ
+}
+
+func (t *_TypeParam) Bound() *Interface {
+	iface := asInterface(t.bound)
+	// use the type bound position if we have one
+	pos := token.NoPos
+	if n, _ := t.bound.(*Named); n != nil {
+		pos = n.obj.pos
+	}
+	// TODO(rFindley) switch this to an unexported method on Checker.
+	t.check.completeInterface(pos, iface)
+	return iface
+}
+
+// optype returns a type's operational type. Except for
+// type parameters, the operational type is the same
+// as the underlying type (as returned by under). For
+// Type parameters, the operational type is determined
+// by the corresponding type bound's type list. The
+// result may be the bottom or top type, but it is never
+// the incoming type parameter.
+func optype(typ Type) Type {
+	if t := asTypeParam(typ); t != nil {
+		// If the optype is typ, return the top type as we have
+		// no information. It also prevents infinite recursion
+		// via the asTypeParam converter function. This can happen
+		// for a type parameter list of the form:
+		// (type T interface { type T }).
+		// See also issue #39680.
+		if u := t.Bound().allTypes; u != nil && u != typ {
+			// u != typ and u is a type parameter => under(u) != typ, so this is ok
+			return under(u)
+		}
+		return theTop
+	}
+	return under(typ)
+}
+
+// An instance represents an instantiated generic type syntactically
+// (without expanding the instantiation). Type instances appear only
+// during type-checking and are replaced by their fully instantiated
+// (expanded) types before the end of type-checking.
+type instance struct {
+	check   *Checker    // for lazy instantiation
+	pos     token.Pos   // position of type instantiation; for error reporting only
+	base    *Named      // parameterized type to be instantiated
+	targs   []Type      // type arguments
+	poslist []token.Pos // position of each targ; for error reporting only
+	value   Type        // base(targs...) after instantiation or Typ[Invalid]; nil if not yet set
+}
+
+// expand returns the instantiated (= expanded) type of t.
+// The result is either an instantiated *Named type, or
+// Typ[Invalid] if there was an error.
+func (t *instance) expand() Type {
+	v := t.value
+	if v == nil {
+		v = t.check.instantiate(t.pos, t.base, t.targs, t.poslist)
+		if v == nil {
+			v = Typ[Invalid]
+		}
+		t.value = v
+	}
+	// After instantiation we must have an invalid or a *Named type.
+	if debug && v != Typ[Invalid] {
+		_ = v.(*Named)
+	}
+	return v
+}
+
+// expand expands a type instance into its instantiated
+// type and leaves all other types alone. expand does
+// not recurse.
+func expand(typ Type) Type {
+	if t, _ := typ.(*instance); t != nil {
+		return t.expand()
+	}
+	return typ
+}
+
+// expandf is set to expand.
+// Call expandf when calling expand causes compile-time cycle error.
+var expandf func(Type) Type
+
+func init() { expandf = expand }
+
+// bottom represents the bottom of the type lattice.
+// It is the underlying type of a type parameter that
+// cannot be satisfied by any type, usually because
+// the intersection of type constraints left nothing).
+type bottom struct{}
+
+// theBottom is the singleton bottom type.
+var theBottom = &bottom{}
+
+// top represents the top of the type lattice.
+// It is the underlying type of a type parameter that
+// can be satisfied by any type (ignoring methods),
+// usually because the type constraint has no type
+// list.
+type top struct{}
+
+// theTop is the singleton top type.
+var theTop = &top{}
+
+// Type-specific implementations of Underlying.
+func (t *Basic) Underlying() Type      { return t }
+func (t *Array) Underlying() Type      { return t }
+func (t *Slice) Underlying() Type      { return t }
+func (t *Struct) Underlying() Type     { return t }
+func (t *Pointer) Underlying() Type    { return t }
+func (t *Tuple) Underlying() Type      { return t }
+func (t *Signature) Underlying() Type  { return t }
+func (t *_Sum) Underlying() Type       { return t }
+func (t *Interface) Underlying() Type  { return t }
+func (t *Map) Underlying() Type        { return t }
+func (t *Chan) Underlying() Type       { return t }
+func (t *Named) Underlying() Type      { return t.underlying }
+func (t *_TypeParam) Underlying() Type { return t }
+func (t *instance) Underlying() Type   { return t }
+func (t *bottom) Underlying() Type     { return t }
+func (t *top) Underlying() Type        { return t }
+
+// Type-specific implementations of String.
+func (t *Basic) String() string      { return TypeString(t, nil) }
+func (t *Array) String() string      { return TypeString(t, nil) }
+func (t *Slice) String() string      { return TypeString(t, nil) }
+func (t *Struct) String() string     { return TypeString(t, nil) }
+func (t *Pointer) String() string    { return TypeString(t, nil) }
+func (t *Tuple) String() string      { return TypeString(t, nil) }
+func (t *Signature) String() string  { return TypeString(t, nil) }
+func (t *_Sum) String() string       { return TypeString(t, nil) }
+func (t *Interface) String() string  { return TypeString(t, nil) }
+func (t *Map) String() string        { return TypeString(t, nil) }
+func (t *Chan) String() string       { return TypeString(t, nil) }
+func (t *Named) String() string      { return TypeString(t, nil) }
+func (t *_TypeParam) String() string { return TypeString(t, nil) }
+func (t *instance) String() string   { return TypeString(t, nil) }
+func (t *bottom) String() string     { return TypeString(t, nil) }
+func (t *top) String() string        { return TypeString(t, nil) }
+
+// under returns the true expanded underlying type.
+// If it doesn't exist, the result is Typ[Invalid].
+// under must only be called when a type is known
+// to be fully set up.
+func under(t Type) Type {
+	// TODO(gri) is this correct for *Sum?
+	if n := asNamed(t); n != nil {
+		return n.under()
+	}
+	return t
+}
+
+// Converters
+//
+// A converter must only be called when a type is
+// known to be fully set up. A converter returns
+// a type's operational type (see comment for optype)
+// or nil if the type argument is not of the
+// respective type.
+
+func asBasic(t Type) *Basic {
+	op, _ := optype(t).(*Basic)
+	return op
+}
+
+func asArray(t Type) *Array {
+	op, _ := optype(t).(*Array)
+	return op
+}
+
+func asSlice(t Type) *Slice {
+	op, _ := optype(t).(*Slice)
+	return op
+}
+
+func asStruct(t Type) *Struct {
+	op, _ := optype(t).(*Struct)
+	return op
+}
+
+func asPointer(t Type) *Pointer {
+	op, _ := optype(t).(*Pointer)
+	return op
+}
+
+func asTuple(t Type) *Tuple {
+	op, _ := optype(t).(*Tuple)
+	return op
+}
+
+func asSignature(t Type) *Signature {
+	op, _ := optype(t).(*Signature)
+	return op
+}
+
+func asSum(t Type) *_Sum {
+	op, _ := optype(t).(*_Sum)
+	return op
+}
+
+func asInterface(t Type) *Interface {
+	op, _ := optype(t).(*Interface)
+	return op
+}
+
+func asMap(t Type) *Map {
+	op, _ := optype(t).(*Map)
+	return op
+}
+
+func asChan(t Type) *Chan {
+	op, _ := optype(t).(*Chan)
+	return op
+}
+
+// If the argument to asNamed and asTypeParam is of the respective types
+// (possibly after expanding an instance type), these methods return that type.
+// Otherwise the result is nil.
+
+func asNamed(t Type) *Named {
+	e, _ := expand(t).(*Named)
+	return e
+}
+
+func asTypeParam(t Type) *_TypeParam {
+	u, _ := under(t).(*_TypeParam)
+	return u
+}
diff --git a/src/go/types/types_test.go b/src/go/types/types_test.go
new file mode 100644
index 0000000..25cd996
--- /dev/null
+++ b/src/go/types/types_test.go
@@ -0,0 +1,19 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import "sync/atomic"
+
+// Upon calling ResetId, nextId starts with 1 again.
+// It may be called concurrently. This is only needed
+// for tests where we may want to have a consistent
+// numbering for each individual test case.
+func ResetId() { atomic.StoreUint32(&lastId, 0) }
+
+// SetGoVersion sets the unexported goVersion field on config, so that tests
+// which assert on behavior for older Go versions can set it.
+func SetGoVersion(config *Config, goVersion string) {
+	config.goVersion = goVersion
+}
diff --git a/src/go/types/typestring.go b/src/go/types/typestring.go
index 31c572f..fe27f0f 100644
--- a/src/go/types/typestring.go
+++ b/src/go/types/typestring.go
@@ -9,6 +9,8 @@
 import (
 	"bytes"
 	"fmt"
+	"go/token"
+	"unicode/utf8"
 )
 
 // A Qualifier controls how named package-level objects are printed in
@@ -75,6 +77,10 @@
 	writeType(buf, typ, qf, make([]Type, 0, 8))
 }
 
+// instanceMarker is the prefix for an instantiated type
+// in "non-evaluated" instance form.
+const instanceMarker = '#'
+
 func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
 	// Theoretically, this is a quadratic lookup algorithm, but in
 	// practice deeply nested composite types with unnamed component
@@ -82,7 +88,7 @@
 	// using a map.
 	for _, t := range visited {
 		if t == typ {
-			fmt.Fprintf(buf, "○%T", typ) // cycle to typ
+			fmt.Fprintf(buf, "○%T", goTypeName(typ)) // cycle to typ
 			return
 		}
 	}
@@ -93,9 +99,15 @@
 		buf.WriteString("<nil>")
 
 	case *Basic:
-		if t.kind == UnsafePointer {
-			buf.WriteString("unsafe.")
+		// exported basic types go into package unsafe
+		// (currently this is just unsafe.Pointer)
+		if token.IsExported(t.name) {
+			if obj, _ := Unsafe.scope.Lookup(t.name).(*TypeName); obj != nil {
+				writeTypeName(buf, obj, qf)
+				break
+			}
 		}
+
 		if gcCompatibilityMode {
 			// forget the alias names
 			switch t.kind {
@@ -121,6 +133,9 @@
 			if i > 0 {
 				buf.WriteString("; ")
 			}
+			// This doesn't do the right thing for embedded type
+			// aliases where we should print the alias name, not
+			// the aliased type (see issue #44410).
 			if !f.embedded {
 				buf.WriteString(f.name)
 				buf.WriteByte(' ')
@@ -143,6 +158,14 @@
 		buf.WriteString("func")
 		writeSignature(buf, t, qf, visited)
 
+	case *_Sum:
+		for i, t := range t.types {
+			if i > 0 {
+				buf.WriteString(", ")
+			}
+			writeType(buf, t, qf, visited)
+		}
+
 	case *Interface:
 		// We write the source-level methods and embedded types rather
 		// than the actual method set since resolved method signatures
@@ -168,6 +191,13 @@
 				writeSignature(buf, m.typ.(*Signature), qf, visited)
 				empty = false
 			}
+			if !empty && t.allTypes != nil {
+				buf.WriteString("; ")
+			}
+			if t.allTypes != nil {
+				buf.WriteString("type ")
+				writeType(buf, t.allTypes, qf, visited)
+			}
 		} else {
 			// print explicit interface methods and embedded types
 			for i, m := range t.methods {
@@ -178,8 +208,19 @@
 				writeSignature(buf, m.typ.(*Signature), qf, visited)
 				empty = false
 			}
+			if !empty && t.types != nil {
+				buf.WriteString("; ")
+			}
+			if t.types != nil {
+				buf.WriteString("type ")
+				writeType(buf, t.types, qf, visited)
+				empty = false
+			}
+			if !empty && len(t.embeddeds) > 0 {
+				buf.WriteString("; ")
+			}
 			for i, typ := range t.embeddeds {
-				if i > 0 || len(t.methods) > 0 {
+				if i > 0 {
 					buf.WriteString("; ")
 				}
 				writeType(buf, typ, qf, visited)
@@ -227,17 +268,36 @@
 		}
 
 	case *Named:
-		s := "<Named w/o object>"
-		if obj := t.obj; obj != nil {
-			if obj.pkg != nil {
-				writePackage(buf, obj.pkg, qf)
-			}
-			// TODO(gri): function-local named types should be displayed
-			// differently from named types at package level to avoid
-			// ambiguity.
-			s = obj.name
+		writeTypeName(buf, t.obj, qf)
+		if t.targs != nil {
+			// instantiated type
+			buf.WriteByte('[')
+			writeTypeList(buf, t.targs, qf, visited)
+			buf.WriteByte(']')
+		} else if t.tparams != nil {
+			// parameterized type
+			writeTParamList(buf, t.tparams, qf, visited)
 		}
-		buf.WriteString(s)
+
+	case *_TypeParam:
+		s := "?"
+		if t.obj != nil {
+			s = t.obj.name
+		}
+		buf.WriteString(s + subscript(t.id))
+
+	case *instance:
+		buf.WriteByte(instanceMarker) // indicate "non-evaluated" syntactic instance
+		writeTypeName(buf, t.base.obj, qf)
+		buf.WriteByte('[')
+		writeTypeList(buf, t.targs, qf, visited)
+		buf.WriteByte(']')
+
+	case *bottom:
+		buf.WriteString("⊥")
+
+	case *top:
+		buf.WriteString("⊤")
 
 	default:
 		// For externally defined implementations of Type.
@@ -245,6 +305,62 @@
 	}
 }
 
+func writeTypeList(buf *bytes.Buffer, list []Type, qf Qualifier, visited []Type) {
+	for i, typ := range list {
+		if i > 0 {
+			buf.WriteString(", ")
+		}
+		writeType(buf, typ, qf, visited)
+	}
+}
+
+func writeTParamList(buf *bytes.Buffer, list []*TypeName, qf Qualifier, visited []Type) {
+	// TODO(rFindley) compare this with the corresponding implementation in types2
+	buf.WriteString("[")
+	var prev Type
+	for i, p := range list {
+		// TODO(rFindley) support 'any' sugar here.
+		var b Type = &emptyInterface
+		if t, _ := p.typ.(*_TypeParam); t != nil && t.bound != nil {
+			b = t.bound
+		}
+		if i > 0 {
+			if b != prev {
+				// type bound changed - write previous one before advancing
+				buf.WriteByte(' ')
+				writeType(buf, prev, qf, visited)
+			}
+			buf.WriteString(", ")
+		}
+		prev = b
+
+		if t, _ := p.typ.(*_TypeParam); t != nil {
+			writeType(buf, t, qf, visited)
+		} else {
+			buf.WriteString(p.name)
+		}
+	}
+	if prev != nil {
+		buf.WriteByte(' ')
+		writeType(buf, prev, qf, visited)
+	}
+	buf.WriteByte(']')
+}
+
+func writeTypeName(buf *bytes.Buffer, obj *TypeName, qf Qualifier) {
+	s := "<Named w/o object>"
+	if obj != nil {
+		if obj.pkg != nil {
+			writePackage(buf, obj.pkg, qf)
+		}
+		// TODO(gri): function-local named types should be displayed
+		// differently from named types at package level to avoid
+		// ambiguity.
+		s = obj.name
+	}
+	buf.WriteString(s)
+}
+
 func writeTuple(buf *bytes.Buffer, tup *Tuple, variadic bool, qf Qualifier, visited []Type) {
 	buf.WriteByte('(')
 	if tup != nil {
@@ -264,7 +380,7 @@
 				} else {
 					// special case:
 					// append(s, "foo"...) leads to signature func([]byte, string...)
-					if t, ok := typ.Underlying().(*Basic); !ok || t.kind != String {
+					if t := asBasic(typ); t == nil || t.kind != String {
 						panic("internal error: string type expected")
 					}
 					writeType(buf, typ, qf, visited)
@@ -287,6 +403,10 @@
 }
 
 func writeSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier, visited []Type) {
+	if sig.tparams != nil {
+		writeTParamList(buf, sig.tparams, qf, visited)
+	}
+
 	writeTuple(buf, sig.params, sig.variadic, qf, visited)
 
 	n := sig.results.Len()
@@ -305,3 +425,19 @@
 	// multiple or named result(s)
 	writeTuple(buf, sig.results, false, qf, visited)
 }
+
+// subscript returns the decimal (utf8) representation of x using subscript digits.
+func subscript(x uint64) string {
+	const w = len("₀") // all digits 0...9 have the same utf8 width
+	var buf [32 * w]byte
+	i := len(buf)
+	for {
+		i -= w
+		utf8.EncodeRune(buf[i:], '₀'+rune(x%10)) // '₀' == U+2080
+		x /= 10
+		if x == 0 {
+			break
+		}
+	}
+	return string(buf[i:])
+}
diff --git a/src/go/types/typestring_test.go b/src/go/types/typestring_test.go
index 5d9db39..b16529d 100644
--- a/src/go/types/typestring_test.go
+++ b/src/go/types/typestring_test.go
@@ -96,6 +96,10 @@
 	dup("interface{m()}"),
 	dup(`interface{String() string; m(int) float32}`),
 
+	// TODO(rFindley) uncomment this once this AST is accepted, and add more test
+	// cases.
+	// dup(`interface{type int, float32, complex128}`),
+
 	// maps
 	dup("map[string]int"),
 	{"map[struct{x, y int}][]byte", "map[struct{x int; y int}][]byte"},
diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go
index 2b39801..1738d86 100644
--- a/src/go/types/typexpr.go
+++ b/src/go/types/typexpr.go
@@ -7,11 +7,14 @@
 package types
 
 import (
+	"fmt"
 	"go/ast"
 	"go/constant"
+	"go/internal/typeparams"
 	"go/token"
 	"sort"
 	"strconv"
+	"strings"
 )
 
 // ident type-checks identifier e and initializes x with the value or type of e.
@@ -51,12 +54,12 @@
 	}
 	assert(typ != nil)
 
-	// The object may be dot-imported: If so, remove its package from
-	// the map of unused dot imports for the respective file scope.
+	// The object may have been dot-imported.
+	// If so, mark the respective package as used.
 	// (This code is only needed for dot-imports. Without them,
 	// we only have to mark variables, see *Var case below).
-	if pkg := obj.Pkg(); pkg != check.pkg && pkg != nil {
-		delete(check.unusedDotImports[scope], pkg)
+	if pkgName := check.dotImportMap[dotImportKey{scope, obj}]; pkgName != nil {
+		pkgName.used = true
 	}
 
 	switch obj := obj.(type) {
@@ -116,41 +119,220 @@
 }
 
 // typ type-checks the type expression e and returns its type, or Typ[Invalid].
+// The type must not be an (uninstantiated) generic type.
 func (check *Checker) typ(e ast.Expr) Type {
 	return check.definedType(e, nil)
 }
 
+// varType type-checks the type expression e and returns its type, or Typ[Invalid].
+// The type must not be an (uninstantiated) generic type and it must be ordinary
+// (see ordinaryType).
+func (check *Checker) varType(e ast.Expr) Type {
+	typ := check.definedType(e, nil)
+	check.ordinaryType(e, typ)
+	return typ
+}
+
+// ordinaryType reports an error if typ is an interface type containing
+// type lists or is (or embeds) the predeclared type comparable.
+func (check *Checker) ordinaryType(pos positioner, typ Type) {
+	// We don't want to call under() (via asInterface) or complete interfaces
+	// while we are in the middle of type-checking parameter declarations that
+	// might belong to interface methods. Delay this check to the end of
+	// type-checking.
+	check.later(func() {
+		if t := asInterface(typ); t != nil {
+			check.completeInterface(pos.Pos(), t) // TODO(gri) is this the correct position?
+			if t.allTypes != nil {
+				check.softErrorf(pos, _Todo, "interface contains type constraints (%s)", t.allTypes)
+				return
+			}
+			if t._IsComparable() {
+				check.softErrorf(pos, _Todo, "interface is (or embeds) comparable")
+			}
+		}
+	})
+}
+
+// anyType type-checks the type expression e and returns its type, or Typ[Invalid].
+// The type may be generic or instantiated.
+func (check *Checker) anyType(e ast.Expr) Type {
+	typ := check.typInternal(e, nil)
+	assert(isTyped(typ))
+	check.recordTypeAndValue(e, typexpr, typ, nil)
+	return typ
+}
+
 // definedType is like typ but also accepts a type name def.
 // If def != nil, e is the type specification for the defined type def, declared
 // in a type declaration, and def.underlying will be set to the type of e before
 // any components of e are type-checked.
 //
-func (check *Checker) definedType(e ast.Expr, def *Named) (T Type) {
-	if trace {
-		check.trace(e.Pos(), "%s", e)
-		check.indent++
-		defer func() {
-			check.indent--
-			check.trace(e.Pos(), "=> %s", T)
-		}()
+func (check *Checker) definedType(e ast.Expr, def *Named) Type {
+	typ := check.typInternal(e, def)
+	assert(isTyped(typ))
+	if isGeneric(typ) {
+		check.errorf(e, _Todo, "cannot use generic type %s without instantiation", typ)
+		typ = Typ[Invalid]
 	}
+	check.recordTypeAndValue(e, typexpr, typ, nil)
+	return typ
+}
 
-	T = check.typInternal(e, def)
-	assert(isTyped(T))
-	check.recordTypeAndValue(e, typexpr, T, nil)
+// genericType is like typ but the type must be an (uninstantiated) generic type.
+func (check *Checker) genericType(e ast.Expr, reportErr bool) Type {
+	typ := check.typInternal(e, nil)
+	assert(isTyped(typ))
+	if typ != Typ[Invalid] && !isGeneric(typ) {
+		if reportErr {
+			check.errorf(e, _Todo, "%s is not a generic type", typ)
+		}
+		typ = Typ[Invalid]
+	}
+	// TODO(gri) what is the correct call below?
+	check.recordTypeAndValue(e, typexpr, typ, nil)
+	return typ
+}
 
-	return
+// isubst returns an x with identifiers substituted per the substitution map smap.
+// isubst only handles the case of (valid) method receiver type expressions correctly.
+func isubst(x ast.Expr, smap map[*ast.Ident]*ast.Ident) ast.Expr {
+	switch n := x.(type) {
+	case *ast.Ident:
+		if alt := smap[n]; alt != nil {
+			return alt
+		}
+	case *ast.StarExpr:
+		X := isubst(n.X, smap)
+		if X != n.X {
+			new := *n
+			new.X = X
+			return &new
+		}
+	case *ast.IndexExpr:
+		elems := typeparams.UnpackExpr(n.Index)
+		var newElems []ast.Expr
+		for i, elem := range elems {
+			new := isubst(elem, smap)
+			if new != elem {
+				if newElems == nil {
+					newElems = make([]ast.Expr, len(elems))
+					copy(newElems, elems)
+				}
+				newElems[i] = new
+			}
+		}
+		if newElems != nil {
+			index := typeparams.PackExpr(newElems)
+			new := *n
+			new.Index = index
+			return &new
+		}
+	case *ast.ParenExpr:
+		return isubst(n.X, smap) // no need to keep parentheses
+	default:
+		// Other receiver type expressions are invalid.
+		// It's fine to ignore those here as they will
+		// be checked elsewhere.
+	}
+	return x
 }
 
 // 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)
+	check.openScope(ftyp, "function")
+	check.scope.isFunc = true
+	check.recordScope(ftyp, check.scope)
+	sig.scope = check.scope
+	defer check.closeScope()
 
-	recvList, _ := check.collectParams(scope, recvPar, false)
-	params, variadic := check.collectParams(scope, ftyp.Params, true)
-	results, _ := check.collectParams(scope, ftyp.Results, false)
+	var recvTyp ast.Expr // rewritten receiver type; valid if != nil
+	if recvPar != nil && len(recvPar.List) > 0 {
+		// collect generic receiver type parameters, if any
+		// - a receiver type parameter is like any other type parameter, except that it is declared implicitly
+		// - the receiver specification acts as local declaration for its type parameters, which may be blank
+		_, rname, rparams := check.unpackRecv(recvPar.List[0].Type, true)
+		if len(rparams) > 0 {
+			// Blank identifiers don't get declared and regular type-checking of the instantiated
+			// parameterized receiver type expression fails in Checker.collectParams of receiver.
+			// Identify blank type parameters and substitute each with a unique new identifier named
+			// "n_" (where n is the parameter index) and which cannot conflict with any user-defined
+			// name.
+			var smap map[*ast.Ident]*ast.Ident // substitution map from "_" to "n_" identifiers
+			for i, p := range rparams {
+				if p.Name == "_" {
+					new := *p
+					new.Name = fmt.Sprintf("%d_", i)
+					rparams[i] = &new // use n_ identifier instead of _ so it can be looked up
+					if smap == nil {
+						smap = make(map[*ast.Ident]*ast.Ident)
+					}
+					smap[p] = &new
+				}
+			}
+			if smap != nil {
+				// blank identifiers were found => use rewritten receiver type
+				recvTyp = isubst(recvPar.List[0].Type, smap)
+			}
+			sig.rparams = check.declareTypeParams(nil, rparams)
+			// determine receiver type to get its type parameters
+			// and the respective type parameter bounds
+			var recvTParams []*TypeName
+			if rname != nil {
+				// recv should be a Named type (otherwise an error is reported elsewhere)
+				// Also: Don't report an error via genericType since it will be reported
+				//       again when we type-check the signature.
+				// TODO(gri) maybe the receiver should be marked as invalid instead?
+				if recv := asNamed(check.genericType(rname, false)); recv != nil {
+					recvTParams = recv.tparams
+				}
+			}
+			// provide type parameter bounds
+			// - only do this if we have the right number (otherwise an error is reported elsewhere)
+			if len(sig.rparams) == len(recvTParams) {
+				// We have a list of *TypeNames but we need a list of Types.
+				list := make([]Type, len(sig.rparams))
+				for i, t := range sig.rparams {
+					list[i] = t.typ
+				}
+				smap := makeSubstMap(recvTParams, list)
+				for i, tname := range sig.rparams {
+					bound := recvTParams[i].typ.(*_TypeParam).bound
+					// bound is (possibly) parameterized in the context of the
+					// receiver type declaration. Substitute parameters for the
+					// current context.
+					// TODO(gri) should we assume now that bounds always exist?
+					//           (no bound == empty interface)
+					if bound != nil {
+						bound = check.subst(tname.pos, bound, smap)
+						tname.typ.(*_TypeParam).bound = bound
+					}
+				}
+			}
+		}
+	}
+
+	if tparams := typeparams.Get(ftyp); tparams != nil {
+		sig.tparams = check.collectTypeParams(tparams)
+		// Always type-check method type parameters but complain that they are not allowed.
+		// (A separate check is needed when type-checking interface method signatures because
+		// they don't have a receiver specification.)
+		if recvPar != nil {
+			check.errorf(tparams, _Todo, "methods cannot have type parameters")
+		}
+	}
+
+	// Value (non-type) parameters' scope starts in the function body. Use a temporary scope for their
+	// declarations and then squash that scope into the parent scope (and report any redeclarations at
+	// that time).
+	scope := NewScope(check.scope, token.NoPos, token.NoPos, "function body (temp. scope)")
+	recvList, _ := check.collectParams(scope, recvPar, recvTyp, false) // use rewritten receiver type, if any
+	params, variadic := check.collectParams(scope, ftyp.Params, nil, true)
+	results, _ := check.collectParams(scope, ftyp.Results, nil, false)
+	scope.squash(func(obj, alt Object) {
+		check.errorf(obj, _DuplicateDecl, "%s redeclared in this block", obj.Name())
+		check.reportAltDecl(alt)
+	})
 
 	if recvPar != nil {
 		// recv parameter list present (may be empty)
@@ -159,7 +341,7 @@
 		var recv *Var
 		switch len(recvList) {
 		case 0:
-			check.error(recvPar, _BadRecv, "method is missing receiver")
+			// error reported by resolver
 			recv = NewParam(0, nil, "", Typ[Invalid]) // ignore recv below
 		default:
 			// more than one receiver
@@ -168,19 +350,24 @@
 		case 1:
 			recv = recvList[0]
 		}
+
+		// TODO(gri) We should delay rtyp expansion to when we actually need the
+		//           receiver; thus all checks here should be delayed to later.
+		rtyp, _ := deref(recv.typ)
+		rtyp = expand(rtyp)
+
 		// spec: "The receiver type must be of the form T or *T where T is a type name."
 		// (ignore invalid types - error was reported before)
-		if t, _ := deref(recv.typ); t != Typ[Invalid] {
+		if t := rtyp; t != Typ[Invalid] {
 			var err string
-			if T, _ := t.(*Named); T != nil {
+			if T := asNamed(t); T != nil {
 				// spec: "The type denoted by T is called the receiver base type; it must not
 				// be a pointer or interface type and it must be declared in the same package
 				// as the method."
 				if T.obj.pkg != check.pkg {
 					err = "type not defined in this package"
 				} else {
-					// TODO(gri) This is not correct if the underlying type is unknown yet.
-					switch u := T.underlying.(type) {
+					switch u := optype(T).(type) {
 					case *Basic:
 						// unsafe.Pointer is treated like a regular pointer
 						if u.kind == UnsafePointer {
@@ -201,17 +388,43 @@
 		sig.recv = recv
 	}
 
-	sig.scope = scope
 	sig.params = NewTuple(params...)
 	sig.results = NewTuple(results...)
 	sig.variadic = variadic
 }
 
+// goTypeName returns the Go type name for typ and
+// removes any occurrences of "types." from that name.
+func goTypeName(typ Type) string {
+	return strings.ReplaceAll(fmt.Sprintf("%T", typ), "types.", "")
+}
+
 // typInternal drives type checking of types.
-// Must only be called by definedType.
+// Must only be called by definedType or genericType.
 //
-func (check *Checker) typInternal(e ast.Expr, def *Named) Type {
-	switch e := e.(type) {
+func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
+	if trace {
+		check.trace(e0.Pos(), "type %s", e0)
+		check.indent++
+		defer func() {
+			check.indent--
+			var under Type
+			if T != nil {
+				// Calling under() here may lead to endless instantiations.
+				// Test case: type T[P any] *T[P]
+				// TODO(gri) investigate if that's a bug or to be expected
+				// (see also analogous comment in Checker.instantiate).
+				under = T.Underlying()
+			}
+			if T == under {
+				check.trace(e0.Pos(), "=> %s // %s", T, goTypeName(T))
+			} else {
+				check.trace(e0.Pos(), "=> %s (under = %s) // %s", T, under, goTypeName(T))
+			}
+		}()
+	}
+
+	switch e := e0.(type) {
 	case *ast.BadExpr:
 		// ignore - error reported before
 
@@ -249,7 +462,17 @@
 			check.errorf(&x, _NotAType, "%s is not a type", &x)
 		}
 
+	case *ast.IndexExpr:
+		if typeparams.Enabled {
+			exprs := typeparams.UnpackExpr(e.Index)
+			return check.instantiatedType(e.X, exprs, def)
+		}
+		check.errorf(e0, _NotAType, "%s is not a type", e0)
+		check.use(e.X)
+
 	case *ast.ParenExpr:
+		// Generic types must be instantiated before they can be used in any form.
+		// Consequently, generic types cannot be parenthesized.
 		return check.definedType(e.X, def)
 
 	case *ast.ArrayType:
@@ -257,16 +480,21 @@
 			typ := new(Array)
 			def.setUnderlying(typ)
 			typ.len = check.arrayLength(e.Len)
-			typ.elem = check.typ(e.Elt)
-			return typ
-
-		} else {
-			typ := new(Slice)
-			def.setUnderlying(typ)
-			typ.elem = check.typ(e.Elt)
+			typ.elem = check.varType(e.Elt)
 			return typ
 		}
 
+		typ := new(Slice)
+		def.setUnderlying(typ)
+		typ.elem = check.varType(e.Elt)
+		return typ
+
+	case *ast.Ellipsis:
+		// dots are handled explicitly where they are legal
+		// (array composite literals and parameter lists)
+		check.error(e, _InvalidDotDotDot, "invalid use of '...'")
+		check.use(e.Elt)
+
 	case *ast.StructType:
 		typ := new(Struct)
 		def.setUnderlying(typ)
@@ -276,7 +504,7 @@
 	case *ast.StarExpr:
 		typ := new(Pointer)
 		def.setUnderlying(typ)
-		typ.base = check.typ(e.X)
+		typ.base = check.varType(e.X)
 		return typ
 
 	case *ast.FuncType:
@@ -288,6 +516,9 @@
 	case *ast.InterfaceType:
 		typ := new(Interface)
 		def.setUnderlying(typ)
+		if def != nil {
+			typ.obj = def.obj
+		}
 		check.interfaceType(typ, e, def)
 		return typ
 
@@ -295,8 +526,8 @@
 		typ := new(Map)
 		def.setUnderlying(typ)
 
-		typ.key = check.typ(e.Key)
-		typ.elem = check.typ(e.Value)
+		typ.key = check.varType(e.Key)
+		typ.elem = check.varType(e.Value)
 
 		// spec: "The comparison operators == and != must be fully defined
 		// for operands of the key type; thus the key type must not be a
@@ -304,9 +535,13 @@
 		//
 		// Delay this check because it requires fully setup types;
 		// it is safe to continue in any case (was issue 6667).
-		check.atEnd(func() {
+		check.later(func() {
 			if !Comparable(typ.key) {
-				check.errorf(e.Key, _IncomparableMapKey, "incomparable map key type %s", typ.key)
+				var why string
+				if asTypeParam(typ.key) != nil {
+					why = " (missing comparable constraint)"
+				}
+				check.errorf(e.Key, _IncomparableMapKey, "incomparable map key type %s%s", typ.key, why)
 			}
 		})
 
@@ -330,11 +565,11 @@
 		}
 
 		typ.dir = dir
-		typ.elem = check.typ(e.Value)
+		typ.elem = check.varType(e.Value)
 		return typ
 
 	default:
-		check.errorf(e, _NotAType, "%s is not a type", e)
+		check.errorf(e0, _NotAType, "%s is not a type", e0)
 	}
 
 	typ := Typ[Invalid]
@@ -343,10 +578,11 @@
 }
 
 // typeOrNil type-checks the type expression (or nil value) e
-// and returns the typ of e, or nil.
-// If e is neither a type nor nil, typOrNil returns Typ[Invalid].
-//
-func (check *Checker) typOrNil(e ast.Expr) Type {
+// and returns the type of e, or nil. If e is a type, it must
+// not be an (uninstantiated) generic type.
+// If e is neither a type nor nil, typeOrNil returns Typ[Invalid].
+// TODO(gri) should we also disallow non-var types?
+func (check *Checker) typeOrNil(e ast.Expr) Type {
 	var x operand
 	check.rawExpr(&x, e, nil)
 	switch x.mode {
@@ -355,6 +591,7 @@
 	case novalue:
 		check.errorf(&x, _NotAType, "%s used as type", &x)
 	case typexpr:
+		check.instantiatedOperand(&x)
 		return x.typ
 	case value:
 		if x.isNil() {
@@ -367,6 +604,49 @@
 	return Typ[Invalid]
 }
 
+func (check *Checker) instantiatedType(x ast.Expr, targs []ast.Expr, def *Named) Type {
+	b := check.genericType(x, true) // TODO(gri) what about cycles?
+	if b == Typ[Invalid] {
+		return b // error already reported
+	}
+	base := asNamed(b)
+	if base == nil {
+		unreachable() // should have been caught by genericType
+	}
+
+	// create a new type instance rather than instantiate the type
+	// TODO(gri) should do argument number check here rather than
+	//           when instantiating the type?
+	typ := new(instance)
+	def.setUnderlying(typ)
+
+	typ.check = check
+	typ.pos = x.Pos()
+	typ.base = base
+
+	// evaluate arguments (always)
+	typ.targs = check.typeList(targs)
+	if typ.targs == nil {
+		def.setUnderlying(Typ[Invalid]) // avoid later errors due to lazy instantiation
+		return Typ[Invalid]
+	}
+
+	// determine argument positions (for error reporting)
+	typ.poslist = make([]token.Pos, len(targs))
+	for i, arg := range targs {
+		typ.poslist[i] = arg.Pos()
+	}
+
+	// make sure we check instantiation works at least once
+	// and that the resulting type is valid
+	check.later(func() {
+		t := typ.expand()
+		check.validType(t, nil)
+	})
+
+	return typ
+}
+
 // arrayLength type-checks the array length expression e
 // and returns the constant length >= 0, or a value < 0
 // to indicate an error (and thus an unknown length).
@@ -394,7 +674,25 @@
 	return -1
 }
 
-func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, variadic bool) {
+// typeList provides the list of types corresponding to the incoming expression list.
+// If an error occurred, the result is nil, but all list elements were type-checked.
+func (check *Checker) typeList(list []ast.Expr) []Type {
+	res := make([]Type, len(list)) // res != nil even if len(list) == 0
+	for i, x := range list {
+		t := check.varType(x)
+		if t == Typ[Invalid] {
+			res = nil
+		}
+		if res != nil {
+			res[i] = t
+		}
+	}
+	return res
+}
+
+// collectParams declares the parameters of list in scope and returns the corresponding
+// variable list. If type0 != nil, it is used instead of the first type in list.
+func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, type0 ast.Expr, variadicOk bool) (params []*Var, variadic bool) {
 	if list == nil {
 		return
 	}
@@ -402,6 +700,9 @@
 	var named, anonymous bool
 	for i, field := range list.List {
 		ftype := field.Type
+		if i == 0 && type0 != nil {
+			ftype = type0
+		}
 		if t, _ := ftype.(*ast.Ellipsis); t != nil {
 			ftype = t.Elt
 			if variadicOk && i == len(list.List)-1 && len(field.Names) <= 1 {
@@ -411,7 +712,7 @@
 				// ignore ... and continue
 			}
 		}
-		typ := check.typ(ftype)
+		typ := check.varType(ftype)
 		// The parser ensures that f.Tag is nil and we don't
 		// care if a constructed AST contains a non-nil tag.
 		if len(field.Names) > 0 {
@@ -462,9 +763,12 @@
 }
 
 func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named) {
+	var tlist *ast.Ident // "type" name of first entry in a type list declaration
+	var types []ast.Expr
 	for _, f := range iface.Methods.List {
 		if len(f.Names) > 0 {
-			// We have a method with name f.Names[0].
+			// We have a method with name f.Names[0], or a type
+			// of a type list (name.Name == "type").
 			// (The parser ensures that there's only one method
 			// and we don't care if a constructed AST has more.)
 			name := f.Names[0]
@@ -473,6 +777,18 @@
 				continue // ignore
 			}
 
+			if name.Name == "type" {
+				// Always collect all type list entries, even from
+				// different type lists, under the assumption that
+				// the author intended to include all types.
+				types = append(types, f.Type)
+				if tlist != nil && tlist != name {
+					check.errorf(name, _Todo, "cannot have multiple type lists in an interface")
+				}
+				tlist = name
+				continue
+			}
+
 			typ := check.typ(f.Type)
 			sig, _ := typ.(*Signature)
 			if sig == nil {
@@ -482,6 +798,17 @@
 				continue // ignore
 			}
 
+			// Always type-check method type parameters but complain if they are not enabled.
+			// (This extra check is needed here because interface method signatures don't have
+			// a receiver specification.)
+			if sig.tparams != nil {
+				var at positioner = f.Type
+				if tparams := typeparams.Get(f.Type); tparams != nil {
+					at = tparams
+				}
+				check.errorf(at, _Todo, "methods cannot have type parameters")
+			}
+
 			// use named receiver type if available (for better error messages)
 			var recvTyp Type = ityp
 			if def != nil {
@@ -493,38 +820,30 @@
 			check.recordDef(name, m)
 			ityp.methods = append(ityp.methods, m)
 		} else {
-			// We have an embedded interface and f.Type is its
-			// (possibly qualified) embedded type name. Collect
-			// it if it's a valid interface.
-			typ := check.typ(f.Type)
-
-			utyp := check.underlying(typ)
-			if _, ok := utyp.(*Interface); !ok {
-				if utyp != Typ[Invalid] {
-					check.errorf(f.Type, _InvalidIfaceEmbed, "%s is not an interface", typ)
-				}
-				continue
-			}
-
-			ityp.embeddeds = append(ityp.embeddeds, typ)
+			// We have an embedded type. completeInterface will
+			// eventually verify that we have an interface.
+			ityp.embeddeds = append(ityp.embeddeds, check.typ(f.Type))
 			check.posMap[ityp] = append(check.posMap[ityp], f.Type.Pos())
 		}
 	}
 
-	if len(ityp.methods) == 0 && len(ityp.embeddeds) == 0 {
+	// type constraints
+	ityp.types = _NewSum(check.collectTypeConstraints(iface.Pos(), types))
+
+	if len(ityp.methods) == 0 && ityp.types == nil && len(ityp.embeddeds) == 0 {
 		// empty interface
 		ityp.allMethods = markComplete
 		return
 	}
 
 	// sort for API stability
-	sort.Sort(byUniqueMethodName(ityp.methods))
-	sort.Stable(byUniqueTypeName(ityp.embeddeds))
+	sortMethods(ityp.methods)
+	sortTypes(ityp.embeddeds)
 
-	check.later(func() { check.completeInterface(ityp) })
+	check.later(func() { check.completeInterface(iface.Pos(), ityp) })
 }
 
-func (check *Checker) completeInterface(ityp *Interface) {
+func (check *Checker) completeInterface(pos token.Pos, ityp *Interface) {
 	if ityp.allMethods != nil {
 		return
 	}
@@ -538,11 +857,18 @@
 	}
 
 	if trace {
-		check.trace(token.NoPos, "complete %s", ityp)
+		// Types don't generally have position information.
+		// If we don't have a valid pos provided, try to use
+		// one close enough.
+		if !pos.IsValid() && len(ityp.methods) > 0 {
+			pos = ityp.methods[0].pos
+		}
+
+		check.trace(pos, "complete %s", ityp)
 		check.indent++
 		defer func() {
 			check.indent--
-			check.trace(token.NoPos, "=> %s", ityp)
+			check.trace(pos, "=> %s (methods = %v, types = %v)", ityp, ityp.allMethods, ityp.allTypes)
 		}()
 	}
 
@@ -578,9 +904,13 @@
 			check.errorf(atPos(pos), _DuplicateDecl, "duplicate method %s", m.name)
 			check.errorf(atPos(mpos[other.(*Func)]), _DuplicateDecl, "\tother declaration of %s", m.name) // secondary error, \t indented
 		default:
-			// check method signatures after all types are computed (issue #33656)
-			check.atEnd(func() {
-				if !check.identical(m.typ, other.Type()) {
+			// We have a duplicate method name in an embedded (not explicitly declared) method.
+			// Check method signatures after all types are computed (issue #33656).
+			// If we're pre-go1.14 (overlapping embeddings are not permitted), report that
+			// error here as well (even though we could do it eagerly) because it's the same
+			// error message.
+			check.later(func() {
+				if !check.allowVersion(m.pkg, 1, 14) || !check.identical(m.typ, other.Type()) {
 					check.errorf(atPos(pos), _DuplicateDecl, "duplicate method %s", m.name)
 					check.errorf(atPos(mpos[other.(*Func)]), _DuplicateDecl, "\tother declaration of %s", m.name) // secondary error, \t indented
 				}
@@ -592,25 +922,81 @@
 		addMethod(m.pos, m, true)
 	}
 
+	// collect types
+	allTypes := ityp.types
+
 	posList := check.posMap[ityp]
 	for i, typ := range ityp.embeddeds {
 		pos := posList[i] // embedding position
-		typ, ok := check.underlying(typ).(*Interface)
-		if !ok {
-			// An error was reported when collecting the embedded types.
-			// Ignore it.
+		utyp := under(typ)
+		etyp := asInterface(utyp)
+		if etyp == nil {
+			if utyp != Typ[Invalid] {
+				var format string
+				if _, ok := utyp.(*_TypeParam); ok {
+					format = "%s is a type parameter, not an interface"
+				} else {
+					format = "%s is not an interface"
+				}
+				// TODO: correct error code.
+				check.errorf(atPos(pos), _InvalidIfaceEmbed, format, typ)
+			}
 			continue
 		}
-		check.completeInterface(typ)
-		for _, m := range typ.allMethods {
+		check.completeInterface(pos, etyp)
+		for _, m := range etyp.allMethods {
 			addMethod(pos, m, false) // use embedding position pos rather than m.pos
 		}
+		allTypes = intersect(allTypes, etyp.allTypes)
 	}
 
 	if methods != nil {
 		sort.Sort(byUniqueMethodName(methods))
 		ityp.allMethods = methods
 	}
+	ityp.allTypes = allTypes
+}
+
+// intersect computes the intersection of the types x and y.
+// Note: A incomming nil type stands for the top type. A top
+// type result is returned as nil.
+func intersect(x, y Type) (r Type) {
+	defer func() {
+		if r == theTop {
+			r = nil
+		}
+	}()
+
+	switch {
+	case x == theBottom || y == theBottom:
+		return theBottom
+	case x == nil || x == theTop:
+		return y
+	case y == nil || x == theTop:
+		return x
+	}
+
+	xtypes := unpackType(x)
+	ytypes := unpackType(y)
+	// Compute the list rtypes which includes only
+	// types that are in both xtypes and ytypes.
+	// Quadratic algorithm, but good enough for now.
+	// TODO(gri) fix this
+	var rtypes []Type
+	for _, x := range xtypes {
+		if includes(ytypes, x) {
+			rtypes = append(rtypes, x)
+		}
+	}
+
+	if rtypes == nil {
+		return theBottom
+	}
+	return _NewSum(rtypes)
+}
+
+func sortTypes(list []Type) {
+	sort.Stable(byUniqueTypeName(list))
 }
 
 // byUniqueTypeName named type lists can be sorted by their unique type names.
@@ -621,12 +1007,25 @@
 func (a byUniqueTypeName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
 
 func sortName(t Type) string {
-	if named, _ := t.(*Named); named != nil {
+	if named := asNamed(t); named != nil {
 		return named.obj.Id()
 	}
 	return ""
 }
 
+func sortMethods(list []*Func) {
+	sort.Sort(byUniqueMethodName(list))
+}
+
+func assertSortedMethods(list []*Func) {
+	if !debug {
+		panic("internal error: assertSortedMethods called outside debug mode")
+	}
+	if !sort.IsSorted(byUniqueMethodName(list)) {
+		panic("internal error: methods not sorted")
+	}
+}
+
 // byUniqueMethodName method lists can be sorted by their unique method names.
 type byUniqueMethodName []*Func
 
@@ -690,7 +1089,7 @@
 	}
 
 	for _, f := range list.List {
-		typ = check.typ(f.Type)
+		typ = check.varType(f.Type)
 		tag = check.tag(f.Tag)
 		if len(f.Names) > 0 {
 			// named fields
@@ -699,48 +1098,51 @@
 			}
 		} else {
 			// embedded field
-			// spec: "An embedded type must be specified as a type name T or as a pointer
-			// to a non-interface type name *T, and T itself may not be a pointer type."
+			// spec: "An embedded type must be specified as a type name T or as a
+			// pointer to a non-interface type name *T, and T itself may not be a
+			// pointer type."
 			pos := f.Type.Pos()
 			name := embeddedFieldIdent(f.Type)
 			if name == nil {
-				check.invalidAST(f.Type, "embedded field type %s has no name", f.Type)
+				// TODO(rFindley): using invalidAST here causes test failures (all
+				//                 errors should have codes). Clean this up.
+				check.errorf(f.Type, _Todo, "invalid AST: embedded field type %s has no name", f.Type)
 				name = ast.NewIdent("_")
 				name.NamePos = pos
 				addInvalid(name, pos)
 				continue
 			}
-			t, isPtr := deref(typ)
+			add(name, true, pos)
+
 			// Because we have a name, typ must be of the form T or *T, where T is the name
 			// of a (named or alias) type, and t (= deref(typ)) must be the type of T.
-			switch t := t.Underlying().(type) {
-			case *Basic:
-				if t == Typ[Invalid] {
-					// error was reported before
-					addInvalid(name, pos)
-					continue
-				}
+			// We must delay this check to the end because we don't want to instantiate
+			// (via under(t)) a possibly incomplete type.
 
-				// unsafe.Pointer is treated like a regular pointer
-				if t.kind == UnsafePointer {
-					check.errorf(f.Type, _InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer")
-					addInvalid(name, pos)
-					continue
-				}
+			// for use in the closure below
+			embeddedTyp := typ
+			embeddedPos := f.Type
 
-			case *Pointer:
-				check.errorf(f.Type, _InvalidPtrEmbed, "embedded field type cannot be a pointer")
-				addInvalid(name, pos)
-				continue
-
-			case *Interface:
-				if isPtr {
-					check.errorf(f.Type, _InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface")
-					addInvalid(name, pos)
-					continue
+			check.later(func() {
+				t, isPtr := deref(embeddedTyp)
+				switch t := optype(t).(type) {
+				case *Basic:
+					if t == Typ[Invalid] {
+						// error was reported before
+						return
+					}
+					// unsafe.Pointer is treated like a regular pointer
+					if t.kind == UnsafePointer {
+						check.errorf(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer")
+					}
+				case *Pointer:
+					check.errorf(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer")
+				case *Interface:
+					if isPtr {
+						check.errorf(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface")
+					}
 				}
-			}
-			add(name, true, pos)
+			})
 		}
 	}
 
@@ -759,6 +1161,46 @@
 		}
 	case *ast.SelectorExpr:
 		return e.Sel
+	case *ast.IndexExpr:
+		return embeddedFieldIdent(e.X)
 	}
 	return nil // invalid embedded field
 }
+
+func (check *Checker) collectTypeConstraints(pos token.Pos, types []ast.Expr) []Type {
+	list := make([]Type, 0, len(types)) // assume all types are correct
+	for _, texpr := range types {
+		if texpr == nil {
+			check.invalidAST(atPos(pos), "missing type constraint")
+			continue
+		}
+		list = append(list, check.varType(texpr))
+	}
+
+	// Ensure that each type is only present once in the type list.  Types may be
+	// interfaces, which may not be complete yet. It's ok to do this check at the
+	// end because it's not a requirement for correctness of the code.
+	// Note: This is a quadratic algorithm, but type lists tend to be short.
+	check.later(func() {
+		for i, t := range list {
+			if t := asInterface(t); t != nil {
+				check.completeInterface(types[i].Pos(), t)
+			}
+			if includes(list[:i], t) {
+				check.softErrorf(types[i], _Todo, "duplicate type %s in type list", t)
+			}
+		}
+	})
+
+	return list
+}
+
+// includes reports whether typ is in list.
+func includes(list []Type, typ Type) bool {
+	for _, e := range list {
+		if Identical(typ, e) {
+			return true
+		}
+	}
+	return false
+}
diff --git a/src/go/types/unify.go b/src/go/types/unify.go
new file mode 100644
index 0000000..db06e21
--- /dev/null
+++ b/src/go/types/unify.go
@@ -0,0 +1,469 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements type unification.
+
+package types
+
+import (
+	"bytes"
+	"go/token"
+	"sort"
+)
+
+// The unifier maintains two separate sets of type parameters x and y
+// which are used to resolve type parameters in the x and y arguments
+// provided to the unify call. For unidirectional unification, only
+// one of these sets (say x) is provided, and then type parameters are
+// only resolved for the x argument passed to unify, not the y argument
+// (even if that also contains possibly the same type parameters). This
+// is crucial to infer the type parameters of self-recursive calls:
+//
+//	func f[P any](a P) { f(a) }
+//
+// For the call f(a) we want to infer that the type argument for P is P.
+// During unification, the parameter type P must be resolved to the type
+// parameter P ("x" side), but the argument type P must be left alone so
+// that unification resolves the type parameter P to P.
+//
+// For bidirection unification, both sets are provided. This enables
+// unification to go from argument to parameter type and vice versa.
+// For constraint type inference, we use bidirectional unification
+// where both the x and y type parameters are identical. This is done
+// by setting up one of them (using init) and then assigning its value
+// to the other.
+
+// A unifier maintains the current type parameters for x and y
+// and the respective types inferred for each type parameter.
+// A unifier is created by calling newUnifier.
+type unifier struct {
+	check *Checker
+	exact bool
+	x, y  tparamsList // x and y must initialized via tparamsList.init
+	types []Type      // inferred types, shared by x and y
+}
+
+// newUnifier returns a new unifier.
+// If exact is set, unification requires unified types to match
+// exactly. If exact is not set, a named type's underlying type
+// is considered if unification would fail otherwise, and the
+// direction of channels is ignored.
+func newUnifier(check *Checker, exact bool) *unifier {
+	u := &unifier{check: check, exact: exact}
+	u.x.unifier = u
+	u.y.unifier = u
+	return u
+}
+
+// unify attempts to unify x and y and reports whether it succeeded.
+func (u *unifier) unify(x, y Type) bool {
+	return u.nify(x, y, nil)
+}
+
+// A tparamsList describes a list of type parameters and the types inferred for them.
+type tparamsList struct {
+	unifier *unifier
+	tparams []*TypeName
+	// For each tparams element, there is a corresponding type slot index in indices.
+	// index  < 0: unifier.types[-index-1] == nil
+	// index == 0: no type slot allocated yet
+	// index  > 0: unifier.types[index-1] == typ
+	// Joined tparams elements share the same type slot and thus have the same index.
+	// By using a negative index for nil types we don't need to check unifier.types
+	// to see if we have a type or not.
+	indices []int // len(d.indices) == len(d.tparams)
+}
+
+// String returns a string representation for a tparamsList. For debugging.
+func (d *tparamsList) String() string {
+	var buf bytes.Buffer
+	buf.WriteByte('[')
+	for i, tname := range d.tparams {
+		if i > 0 {
+			buf.WriteString(", ")
+		}
+		writeType(&buf, tname.typ, nil, nil)
+		buf.WriteString(": ")
+		writeType(&buf, d.at(i), nil, nil)
+	}
+	buf.WriteByte(']')
+	return buf.String()
+}
+
+// init initializes d with the given type parameters.
+// The type parameters must be in the order in which they appear in their declaration
+// (this ensures that the tparams indices match the respective type parameter index).
+func (d *tparamsList) init(tparams []*TypeName) {
+	if len(tparams) == 0 {
+		return
+	}
+	if debug {
+		for i, tpar := range tparams {
+			assert(i == tpar.typ.(*_TypeParam).index)
+		}
+	}
+	d.tparams = tparams
+	d.indices = make([]int, len(tparams))
+}
+
+// join unifies the i'th type parameter of x with the j'th type parameter of y.
+// If both type parameters already have a type associated with them and they are
+// not joined, join fails and return false.
+func (u *unifier) join(i, j int) bool {
+	ti := u.x.indices[i]
+	tj := u.y.indices[j]
+	switch {
+	case ti == 0 && tj == 0:
+		// Neither type parameter has a type slot associated with them.
+		// Allocate a new joined nil type slot (negative index).
+		u.types = append(u.types, nil)
+		u.x.indices[i] = -len(u.types)
+		u.y.indices[j] = -len(u.types)
+	case ti == 0:
+		// The type parameter for x has no type slot yet. Use slot of y.
+		u.x.indices[i] = tj
+	case tj == 0:
+		// The type parameter for y has no type slot yet. Use slot of x.
+		u.y.indices[j] = ti
+
+	// Both type parameters have a slot: ti != 0 && tj != 0.
+	case ti == tj:
+		// Both type parameters already share the same slot. Nothing to do.
+		break
+	case ti > 0 && tj > 0:
+		// Both type parameters have (possibly different) inferred types. Cannot join.
+		return false
+	case ti > 0:
+		// Only the type parameter for x has an inferred type. Use x slot for y.
+		u.y.setIndex(j, ti)
+	default:
+		// Either the type parameter for y has an inferred type, or neither type
+		// parameter has an inferred type. In either case, use y slot for x.
+		u.x.setIndex(i, tj)
+	}
+	return true
+}
+
+// If typ is a type parameter of d, index returns the type parameter index.
+// Otherwise, the result is < 0.
+func (d *tparamsList) index(typ Type) int {
+	if t, ok := typ.(*_TypeParam); ok {
+		if i := t.index; i < len(d.tparams) && d.tparams[i].typ == t {
+			return i
+		}
+	}
+	return -1
+}
+
+// setIndex sets the type slot index for the i'th type parameter
+// (and all its joined parameters) to tj. The type parameter
+// must have a (possibly nil) type slot associated with it.
+func (d *tparamsList) setIndex(i, tj int) {
+	ti := d.indices[i]
+	assert(ti != 0 && tj != 0)
+	for k, tk := range d.indices {
+		if tk == ti {
+			d.indices[k] = tj
+		}
+	}
+}
+
+// at returns the type set for the i'th type parameter; or nil.
+func (d *tparamsList) at(i int) Type {
+	if ti := d.indices[i]; ti > 0 {
+		return d.unifier.types[ti-1]
+	}
+	return nil
+}
+
+// set sets the type typ for the i'th type parameter;
+// typ must not be nil and it must not have been set before.
+func (d *tparamsList) set(i int, typ Type) {
+	assert(typ != nil)
+	u := d.unifier
+	switch ti := d.indices[i]; {
+	case ti < 0:
+		u.types[-ti-1] = typ
+		d.setIndex(i, -ti)
+	case ti == 0:
+		u.types = append(u.types, typ)
+		d.indices[i] = len(u.types)
+	default:
+		panic("type already set")
+	}
+}
+
+// types returns the list of inferred types (via unification) for the type parameters
+// described by d, and an index. If all types were inferred, the returned index is < 0.
+// Otherwise, it is the index of the first type parameter which couldn't be inferred;
+// i.e., for which list[index] is nil.
+func (d *tparamsList) types() (list []Type, index int) {
+	list = make([]Type, len(d.tparams))
+	index = -1
+	for i := range d.tparams {
+		t := d.at(i)
+		list[i] = t
+		if index < 0 && t == nil {
+			index = i
+		}
+	}
+	return
+}
+
+func (u *unifier) nifyEq(x, y Type, p *ifacePair) bool {
+	return x == y || u.nify(x, y, p)
+}
+
+// nify implements the core unification algorithm which is an
+// adapted version of Checker.identical0. For changes to that
+// code the corresponding changes should be made here.
+// Must not be called directly from outside the unifier.
+func (u *unifier) nify(x, y Type, p *ifacePair) bool {
+	// types must be expanded for comparison
+	x = expand(x)
+	y = expand(y)
+
+	if !u.exact {
+		// If exact unification is known to fail because we attempt to
+		// match a type name against an unnamed type literal, consider
+		// the underlying type of the named type.
+		// (Subtle: We use isNamed to include any type with a name (incl.
+		// basic types and type parameters. We use asNamed() because we only
+		// want *Named types.)
+		switch {
+		case !isNamed(x) && y != nil && asNamed(y) != nil:
+			return u.nify(x, under(y), p)
+		case x != nil && asNamed(x) != nil && !isNamed(y):
+			return u.nify(under(x), y, p)
+		}
+	}
+
+	// Cases where at least one of x or y is a type parameter.
+	switch i, j := u.x.index(x), u.y.index(y); {
+	case i >= 0 && j >= 0:
+		// both x and y are type parameters
+		if u.join(i, j) {
+			return true
+		}
+		// both x and y have an inferred type - they must match
+		return u.nifyEq(u.x.at(i), u.y.at(j), p)
+
+	case i >= 0:
+		// x is a type parameter, y is not
+		if tx := u.x.at(i); tx != nil {
+			return u.nifyEq(tx, y, p)
+		}
+		// otherwise, infer type from y
+		u.x.set(i, y)
+		return true
+
+	case j >= 0:
+		// y is a type parameter, x is not
+		if ty := u.y.at(j); ty != nil {
+			return u.nifyEq(x, ty, p)
+		}
+		// otherwise, infer type from x
+		u.y.set(j, x)
+		return true
+	}
+
+	// For type unification, do not shortcut (x == y) for identical
+	// types. Instead keep comparing them element-wise to unify the
+	// matching (and equal type parameter types). A simple test case
+	// where this matters is: func f[P any](a P) { f(a) } .
+
+	switch x := x.(type) {
+	case *Basic:
+		// Basic types are singletons except for the rune and byte
+		// aliases, thus we cannot solely rely on the x == y check
+		// above. See also comment in TypeName.IsAlias.
+		if y, ok := y.(*Basic); ok {
+			return x.kind == y.kind
+		}
+
+	case *Array:
+		// Two array types are identical if they have identical element types
+		// and the same array length.
+		if y, ok := y.(*Array); ok {
+			// If one or both array lengths are unknown (< 0) due to some error,
+			// assume they are the same to avoid spurious follow-on errors.
+			return (x.len < 0 || y.len < 0 || x.len == y.len) && u.nify(x.elem, y.elem, p)
+		}
+
+	case *Slice:
+		// Two slice types are identical if they have identical element types.
+		if y, ok := y.(*Slice); ok {
+			return u.nify(x.elem, y.elem, p)
+		}
+
+	case *Struct:
+		// Two struct types are identical if they have the same sequence of fields,
+		// and if corresponding fields have the same names, and identical types,
+		// and identical tags. Two embedded fields are considered to have the same
+		// name. Lower-case field names from different packages are always different.
+		if y, ok := y.(*Struct); ok {
+			if x.NumFields() == y.NumFields() {
+				for i, f := range x.fields {
+					g := y.fields[i]
+					if f.embedded != g.embedded ||
+						x.Tag(i) != y.Tag(i) ||
+						!f.sameId(g.pkg, g.name) ||
+						!u.nify(f.typ, g.typ, p) {
+						return false
+					}
+				}
+				return true
+			}
+		}
+
+	case *Pointer:
+		// Two pointer types are identical if they have identical base types.
+		if y, ok := y.(*Pointer); ok {
+			return u.nify(x.base, y.base, p)
+		}
+
+	case *Tuple:
+		// Two tuples types are identical if they have the same number of elements
+		// and corresponding elements have identical types.
+		if y, ok := y.(*Tuple); ok {
+			if x.Len() == y.Len() {
+				if x != nil {
+					for i, v := range x.vars {
+						w := y.vars[i]
+						if !u.nify(v.typ, w.typ, p) {
+							return false
+						}
+					}
+				}
+				return true
+			}
+		}
+
+	case *Signature:
+		// Two function types are identical if they have the same number of parameters
+		// and result values, corresponding parameter and result types are identical,
+		// and either both functions are variadic or neither is. Parameter and result
+		// names are not required to match.
+		// TODO(gri) handle type parameters or document why we can ignore them.
+		if y, ok := y.(*Signature); ok {
+			return x.variadic == y.variadic &&
+				u.nify(x.params, y.params, p) &&
+				u.nify(x.results, y.results, p)
+		}
+
+	case *_Sum:
+		// This should not happen with the current internal use of sum types.
+		panic("type inference across sum types not implemented")
+
+	case *Interface:
+		// Two interface types are identical if they have the same set of methods with
+		// the same names and identical function types. Lower-case method names from
+		// different packages are always different. The order of the methods is irrelevant.
+		if y, ok := y.(*Interface); ok {
+			// If identical0 is called (indirectly) via an external API entry point
+			// (such as Identical, IdenticalIgnoreTags, etc.), check is nil. But in
+			// that case, interfaces are expected to be complete and lazy completion
+			// here is not needed.
+			if u.check != nil {
+				u.check.completeInterface(token.NoPos, x)
+				u.check.completeInterface(token.NoPos, y)
+			}
+			a := x.allMethods
+			b := y.allMethods
+			if len(a) == len(b) {
+				// Interface types are the only types where cycles can occur
+				// that are not "terminated" via named types; and such cycles
+				// can only be created via method parameter types that are
+				// anonymous interfaces (directly or indirectly) embedding
+				// the current interface. Example:
+				//
+				//    type T interface {
+				//        m() interface{T}
+				//    }
+				//
+				// If two such (differently named) interfaces are compared,
+				// endless recursion occurs if the cycle is not detected.
+				//
+				// If x and y were compared before, they must be equal
+				// (if they were not, the recursion would have stopped);
+				// search the ifacePair stack for the same pair.
+				//
+				// This is a quadratic algorithm, but in practice these stacks
+				// are extremely short (bounded by the nesting depth of interface
+				// type declarations that recur via parameter types, an extremely
+				// rare occurrence). An alternative implementation might use a
+				// "visited" map, but that is probably less efficient overall.
+				q := &ifacePair{x, y, p}
+				for p != nil {
+					if p.identical(q) {
+						return true // same pair was compared before
+					}
+					p = p.prev
+				}
+				if debug {
+					assert(sort.IsSorted(byUniqueMethodName(a)))
+					assert(sort.IsSorted(byUniqueMethodName(b)))
+				}
+				for i, f := range a {
+					g := b[i]
+					if f.Id() != g.Id() || !u.nify(f.typ, g.typ, q) {
+						return false
+					}
+				}
+				return true
+			}
+		}
+
+	case *Map:
+		// Two map types are identical if they have identical key and value types.
+		if y, ok := y.(*Map); ok {
+			return u.nify(x.key, y.key, p) && u.nify(x.elem, y.elem, p)
+		}
+
+	case *Chan:
+		// Two channel types are identical if they have identical value types.
+		if y, ok := y.(*Chan); ok {
+			return (!u.exact || x.dir == y.dir) && u.nify(x.elem, y.elem, p)
+		}
+
+	case *Named:
+		// Two named types are identical if their type names originate
+		// in the same type declaration.
+		// if y, ok := y.(*Named); ok {
+		// 	return x.obj == y.obj
+		// }
+		if y, ok := y.(*Named); ok {
+			// TODO(gri) This is not always correct: two types may have the same names
+			//           in the same package if one of them is nested in a function.
+			//           Extremely unlikely but we need an always correct solution.
+			if x.obj.pkg == y.obj.pkg && x.obj.name == y.obj.name {
+				assert(len(x.targs) == len(y.targs))
+				for i, x := range x.targs {
+					if !u.nify(x, y.targs[i], p) {
+						return false
+					}
+				}
+				return true
+			}
+		}
+
+	case *_TypeParam:
+		// Two type parameters (which are not part of the type parameters of the
+		// enclosing type as those are handled in the beginning of this function)
+		// are identical if they originate in the same declaration.
+		return x == y
+
+	// case *instance:
+	//	unreachable since types are expanded
+
+	case nil:
+		// avoid a crash in case of nil type
+
+	default:
+		u.check.dump("### u.nify(%s, %s), u.x.tparams = %s", x, y, u.x.tparams)
+		unreachable()
+	}
+
+	return false
+}
diff --git a/src/go/types/universe.go b/src/go/types/universe.go
index ff5b891..d7feb2c 100644
--- a/src/go/types/universe.go
+++ b/src/go/types/universe.go
@@ -8,6 +8,7 @@
 
 import (
 	"go/constant"
+	"go/internal/typeparams"
 	"go/token"
 	"strings"
 )
@@ -24,6 +25,7 @@
 	universeIota  *Const
 	universeByte  *Basic // uint8 alias, but has name "byte"
 	universeRune  *Basic // int32 alias, but has name "rune"
+	universeAny   *Interface
 	universeError *Named
 )
 
@@ -77,13 +79,21 @@
 		def(NewTypeName(token.NoPos, nil, t.name, t))
 	}
 
+	// any
+	// (Predeclared and entered into universe scope so we do all the
+	// usual checks; but removed again from scope later since it's
+	// only visible as constraint in a type parameter list.)
+	def(NewTypeName(token.NoPos, nil, "any", &emptyInterface))
+
 	// Error has a nil package in its qualified name since it is in no package
-	res := NewVar(token.NoPos, nil, "", Typ[String])
-	sig := &Signature{results: NewTuple(res)}
-	err := NewFunc(token.NoPos, nil, "Error", sig)
-	typ := &Named{underlying: NewInterfaceType([]*Func{err}, nil).Complete()}
-	sig.recv = NewVar(token.NoPos, nil, "", typ)
-	def(NewTypeName(token.NoPos, nil, "error", typ))
+	{
+		res := NewVar(token.NoPos, nil, "", Typ[String])
+		sig := &Signature{results: NewTuple(res)}
+		err := NewFunc(token.NoPos, nil, "Error", sig)
+		typ := &Named{underlying: NewInterfaceType([]*Func{err}, nil).Complete()}
+		sig.recv = NewVar(token.NoPos, nil, "", typ)
+		def(NewTypeName(token.NoPos, nil, "error", typ))
+	}
 }
 
 var predeclaredConsts = [...]struct {
@@ -128,9 +138,11 @@
 	_Recover
 
 	// package unsafe
+	_Add
 	_Alignof
 	_Offsetof
 	_Sizeof
+	_Slice
 
 	// testing support
 	_Assert
@@ -159,9 +171,11 @@
 	_Real:    {"real", 1, false, expression},
 	_Recover: {"recover", 0, false, statement},
 
+	_Add:      {"Add", 2, false, expression},
 	_Alignof:  {"Alignof", 1, false, expression},
 	_Offsetof: {"Offsetof", 1, false, expression},
 	_Sizeof:   {"Sizeof", 1, false, expression},
+	_Slice:    {"Slice", 2, false, expression},
 
 	_Assert: {"assert", 1, false, statement},
 	_Trace:  {"trace", 0, true, statement},
@@ -188,6 +202,33 @@
 	def(newBuiltin(_Trace))
 }
 
+func defPredeclaredComparable() {
+	// The "comparable" interface can be imagined as defined like
+	//
+	// type comparable interface {
+	//         == () untyped bool
+	//         != () untyped bool
+	// }
+	//
+	// == and != cannot be user-declared but we can declare
+	// a magic method == and check for its presence when needed.
+
+	// Define interface { == () }. We don't care about the signature
+	// for == so leave it empty except for the receiver, which is
+	// set up later to match the usual interface method assumptions.
+	sig := new(Signature)
+	eql := NewFunc(token.NoPos, nil, "==", sig)
+	iface := NewInterfaceType([]*Func{eql}, nil).Complete()
+
+	// set up the defined type for the interface
+	obj := NewTypeName(token.NoPos, nil, "comparable", nil)
+	named := NewNamed(obj, iface, nil)
+	obj.color_ = black
+	sig.recv = NewVar(token.NoPos, nil, "", named) // complete == signature
+
+	def(obj)
+}
+
 func init() {
 	Universe = NewScope(nil, token.NoPos, token.NoPos, "universe")
 	Unsafe = NewPackage("unsafe", "unsafe")
@@ -197,11 +238,18 @@
 	defPredeclaredConsts()
 	defPredeclaredNil()
 	defPredeclaredFuncs()
+	if typeparams.Enabled {
+		defPredeclaredComparable()
+	}
 
 	universeIota = Universe.Lookup("iota").(*Const)
 	universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic)
 	universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic)
+	universeAny = Universe.Lookup("any").(*TypeName).typ.(*Interface)
 	universeError = Universe.Lookup("error").(*TypeName).typ.(*Named)
+
+	// "any" is only visible as constraint in a type parameter list
+	delete(Universe.elems, "any")
 }
 
 // Objects with names containing blanks are internal and not entered into
@@ -215,7 +263,7 @@
 		return // nothing to do
 	}
 	// fix Obj link for named types
-	if typ, ok := obj.Type().(*Named); ok {
+	if typ := asNamed(obj.Type()); typ != nil {
 		typ.obj = obj.(*TypeName)
 	}
 	// exported identifiers go into package unsafe
diff --git a/src/go/types/version.go b/src/go/types/version.go
new file mode 100644
index 0000000..1546941
--- /dev/null
+++ b/src/go/types/version.go
@@ -0,0 +1,82 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+// langCompat reports an error if the representation of a numeric
+// literal is not compatible with the current language version.
+func (check *Checker) langCompat(lit *ast.BasicLit) {
+	s := lit.Value
+	if len(s) <= 2 || check.allowVersion(check.pkg, 1, 13) {
+		return
+	}
+	// len(s) > 2
+	if strings.Contains(s, "_") {
+		check.errorf(lit, _InvalidLit, "underscores in numeric literals requires go1.13 or later")
+		return
+	}
+	if s[0] != '0' {
+		return
+	}
+	radix := s[1]
+	if radix == 'b' || radix == 'B' {
+		check.errorf(lit, _InvalidLit, "binary literals requires go1.13 or later")
+		return
+	}
+	if radix == 'o' || radix == 'O' {
+		check.errorf(lit, _InvalidLit, "0o/0O-style octal literals requires go1.13 or later")
+		return
+	}
+	if lit.Kind != token.INT && (radix == 'x' || radix == 'X') {
+		check.errorf(lit, _InvalidLit, "hexadecimal floating-point literals requires go1.13 or later")
+	}
+}
+
+// allowVersion reports whether the given package
+// is allowed to use version major.minor.
+func (check *Checker) allowVersion(pkg *Package, major, minor int) bool {
+	// We assume that imported packages have all been checked,
+	// so we only have to check for the local package.
+	if pkg != check.pkg {
+		return true
+	}
+	ma, mi := check.version.major, check.version.minor
+	return ma == 0 && mi == 0 || ma > major || ma == major && mi >= minor
+}
+
+type version struct {
+	major, minor int
+}
+
+// parseGoVersion parses a Go version string (such as "go1.12")
+// and returns the version, or an error. If s is the empty
+// string, the version is 0.0.
+func parseGoVersion(s string) (v version, err error) {
+	if s == "" {
+		return
+	}
+	matches := goVersionRx.FindStringSubmatch(s)
+	if matches == nil {
+		err = fmt.Errorf(`should be something like "go1.12"`)
+		return
+	}
+	v.major, err = strconv.Atoi(matches[1])
+	if err != nil {
+		return
+	}
+	v.minor, err = strconv.Atoi(matches[2])
+	return
+}
+
+// goVersionRx matches a Go version string, e.g. "go1.12".
+var goVersionRx = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
diff --git a/src/hash/crc32/crc32_otherarch.go b/src/hash/crc32/crc32_otherarch.go
index 1a5e542..936e5bf 100644
--- a/src/hash/crc32/crc32_otherarch.go
+++ b/src/hash/crc32/crc32_otherarch.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !amd64 && !s390x && !ppc64le && !arm64
 // +build !amd64,!s390x,!ppc64le,!arm64
 
 package crc32
diff --git a/src/hash/crc32/crc32_s390x.s b/src/hash/crc32/crc32_s390x.s
index a168fad..8aabc60 100644
--- a/src/hash/crc32/crc32_s390x.s
+++ b/src/hash/crc32/crc32_s390x.s
@@ -217,7 +217,7 @@
 	// V2 and XOR the intermediate result, T2(x),  with the value in V1.
 	// The final result is in the rightmost word of V2.
 
-	VUPLLF  V2 , V2
+	VUPLLF  V2, V2
 	VGFMAG  CONST_CRC_POLY, V2, V1, V2
 
 done:
diff --git a/src/hash/crc32/gen_const_ppc64le.go b/src/hash/crc32/gen_const_ppc64le.go
index d7af018..c98454c 100644
--- a/src/hash/crc32/gen_const_ppc64le.go
+++ b/src/hash/crc32/gen_const_ppc64le.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // Generate the constant table associated with the poly used by the
diff --git a/src/hash/maphash/maphash.go b/src/hash/maphash/maphash.go
index ecc147d..d022d74 100644
--- a/src/hash/maphash/maphash.go
+++ b/src/hash/maphash/maphash.go
@@ -13,7 +13,10 @@
 //
 package maphash
 
-import "unsafe"
+import (
+	"internal/unsafeheader"
+	"unsafe"
+)
 
 // A Seed is a random value that selects the specific hash function
 // computed by a Hash. If two Hashes use the same Seeds, they
@@ -34,7 +37,7 @@
 //
 // The zero Hash is a valid Hash ready to use.
 // A zero Hash chooses a random seed for itself during
-// the first call to a Reset, Write, Seed, Sum64, or Seed method.
+// the first call to a Reset, Write, Seed, or Sum64 method.
 // For control over the seed, use SetSeed.
 //
 // The computed hash values depend only on the initial seed and
@@ -54,13 +57,19 @@
 // If multiple goroutines must compute the same seeded hash,
 // each can declare its own Hash and call SetSeed with a common Seed.
 type Hash struct {
-	_     [0]func() // not comparable
-	seed  Seed      // initial seed used for this hash
-	state Seed      // current hash of all flushed bytes
-	buf   [64]byte  // unflushed byte buffer
-	n     int       // number of unflushed bytes
+	_     [0]func()     // not comparable
+	seed  Seed          // initial seed used for this hash
+	state Seed          // current hash of all flushed bytes
+	buf   [bufSize]byte // unflushed byte buffer
+	n     int           // number of unflushed bytes
 }
 
+// bufSize is the size of the Hash write buffer.
+// The buffer ensures that writes depend only on the sequence of bytes,
+// not the sequence of WriteByte/Write/WriteString calls,
+// by always calling rthash with a full buffer (except for the tail).
+const bufSize = 128
+
 // initSeed seeds the hash if necessary.
 // initSeed is called lazily before any operation that actually uses h.seed/h.state.
 // Note that this does not include Write/WriteByte/WriteString in the case
@@ -68,7 +77,9 @@
 // which does call h.initSeed.)
 func (h *Hash) initSeed() {
 	if h.seed.s == 0 {
-		h.setSeed(MakeSeed())
+		seed := MakeSeed()
+		h.seed = seed
+		h.state = seed
 	}
 }
 
@@ -87,27 +98,58 @@
 // It always writes all of b and never fails; the count and error result are for implementing io.Writer.
 func (h *Hash) Write(b []byte) (int, error) {
 	size := len(b)
-	for h.n+len(b) > len(h.buf) {
+	// Deal with bytes left over in h.buf.
+	// h.n <= bufSize is always true.
+	// Checking it is ~free and it lets the compiler eliminate a bounds check.
+	if h.n > 0 && h.n <= bufSize {
 		k := copy(h.buf[h.n:], b)
-		h.n = len(h.buf)
+		h.n += k
+		if h.n < bufSize {
+			// Copied the entirety of b to h.buf.
+			return size, nil
+		}
 		b = b[k:]
 		h.flush()
+		// No need to set h.n = 0 here; it happens just before exit.
 	}
-	h.n += copy(h.buf[h.n:], b)
+	// Process as many full buffers as possible, without copying, and calling initSeed only once.
+	if len(b) > bufSize {
+		h.initSeed()
+		for len(b) > bufSize {
+			h.state.s = rthash(&b[0], bufSize, h.state.s)
+			b = b[bufSize:]
+		}
+	}
+	// Copy the tail.
+	copy(h.buf[:], b)
+	h.n = len(b)
 	return size, nil
 }
 
 // WriteString adds the bytes of s to the sequence of bytes hashed by h.
 // It always writes all of s and never fails; the count and error result are for implementing io.StringWriter.
 func (h *Hash) WriteString(s string) (int, error) {
+	// WriteString mirrors Write. See Write for comments.
 	size := len(s)
-	for h.n+len(s) > len(h.buf) {
+	if h.n > 0 && h.n <= bufSize {
 		k := copy(h.buf[h.n:], s)
-		h.n = len(h.buf)
+		h.n += k
+		if h.n < bufSize {
+			return size, nil
+		}
 		s = s[k:]
 		h.flush()
 	}
-	h.n += copy(h.buf[h.n:], s)
+	if len(s) > bufSize {
+		h.initSeed()
+		for len(s) > bufSize {
+			ptr := (*byte)((*unsafeheader.String)(unsafe.Pointer(&s)).Data)
+			h.state.s = rthash(ptr, bufSize, h.state.s)
+			s = s[bufSize:]
+		}
+	}
+	copy(h.buf[:], s)
+	h.n = len(s)
 	return size, nil
 }
 
@@ -123,17 +165,12 @@
 // Two Hash objects with different seeds will very likely behave differently.
 // Any bytes added to h before this call will be discarded.
 func (h *Hash) SetSeed(seed Seed) {
-	h.setSeed(seed)
-	h.n = 0
-}
-
-// setSeed sets seed without discarding accumulated data.
-func (h *Hash) setSeed(seed Seed) {
 	if seed.s == 0 {
 		panic("maphash: use of uninitialized Seed")
 	}
 	h.seed = seed
 	h.state = seed
+	h.n = 0
 }
 
 // Reset discards all bytes added to h.
@@ -150,7 +187,7 @@
 		panic("maphash: flush of partially full buffer")
 	}
 	h.initSeed()
-	h.state.s = rthash(h.buf[:], h.state.s)
+	h.state.s = rthash(&h.buf[0], h.n, h.state.s)
 	h.n = 0
 }
 
@@ -163,7 +200,7 @@
 // by using bit masking, shifting, or modular arithmetic.
 func (h *Hash) Sum64() uint64 {
 	h.initSeed()
-	return rthash(h.buf[:h.n], h.state.s)
+	return rthash(&h.buf[0], h.n, h.state.s)
 }
 
 // MakeSeed returns a new random seed.
@@ -184,18 +221,18 @@
 //go:linkname runtime_fastrand runtime.fastrand
 func runtime_fastrand() uint32
 
-func rthash(b []byte, seed uint64) uint64 {
-	if len(b) == 0 {
+func rthash(ptr *byte, len int, seed uint64) uint64 {
+	if len == 0 {
 		return seed
 	}
 	// The runtime hasher only works on uintptr. For 64-bit
 	// architectures, we use the hasher directly. Otherwise,
 	// we use two parallel hashers on the lower and upper 32 bits.
 	if unsafe.Sizeof(uintptr(0)) == 8 {
-		return uint64(runtime_memhash(unsafe.Pointer(&b[0]), uintptr(seed), uintptr(len(b))))
+		return uint64(runtime_memhash(unsafe.Pointer(ptr), uintptr(seed), uintptr(len)))
 	}
-	lo := runtime_memhash(unsafe.Pointer(&b[0]), uintptr(seed), uintptr(len(b)))
-	hi := runtime_memhash(unsafe.Pointer(&b[0]), uintptr(seed>>32), uintptr(len(b)))
+	lo := runtime_memhash(unsafe.Pointer(ptr), uintptr(seed), uintptr(len))
+	hi := runtime_memhash(unsafe.Pointer(ptr), uintptr(seed>>32), uintptr(len))
 	return uint64(hi)<<32 | uint64(lo)
 }
 
diff --git a/src/hash/maphash/maphash_test.go b/src/hash/maphash/maphash_test.go
index daf6eb4..78cdfc0 100644
--- a/src/hash/maphash/maphash_test.go
+++ b/src/hash/maphash/maphash_test.go
@@ -5,6 +5,7 @@
 package maphash
 
 import (
+	"bytes"
 	"hash"
 	"testing"
 )
@@ -34,19 +35,57 @@
 }
 
 func TestHashGrouping(t *testing.T) {
-	b := []byte("foo")
-	h1 := new(Hash)
-	h2 := new(Hash)
-	h2.SetSeed(h1.Seed())
-	h1.Write(b)
-	for _, x := range b {
-		err := h2.WriteByte(x)
+	b := bytes.Repeat([]byte("foo"), 100)
+	hh := make([]*Hash, 7)
+	for i := range hh {
+		hh[i] = new(Hash)
+	}
+	for _, h := range hh[1:] {
+		h.SetSeed(hh[0].Seed())
+	}
+	hh[0].Write(b)
+	hh[1].WriteString(string(b))
+
+	writeByte := func(h *Hash, b byte) {
+		err := h.WriteByte(b)
 		if err != nil {
 			t.Fatalf("WriteByte: %v", err)
 		}
 	}
-	if h1.Sum64() != h2.Sum64() {
-		t.Errorf("hash of \"foo\" and \"f\",\"o\",\"o\" not identical")
+	writeSingleByte := func(h *Hash, b byte) {
+		_, err := h.Write([]byte{b})
+		if err != nil {
+			t.Fatalf("Write single byte: %v", err)
+		}
+	}
+	writeStringSingleByte := func(h *Hash, b byte) {
+		_, err := h.WriteString(string([]byte{b}))
+		if err != nil {
+			t.Fatalf("WriteString single byte: %v", err)
+		}
+	}
+
+	for i, x := range b {
+		writeByte(hh[2], x)
+		writeSingleByte(hh[3], x)
+		if i == 0 {
+			writeByte(hh[4], x)
+		} else {
+			writeSingleByte(hh[4], x)
+		}
+		writeStringSingleByte(hh[5], x)
+		if i == 0 {
+			writeByte(hh[6], x)
+		} else {
+			writeStringSingleByte(hh[6], x)
+		}
+	}
+
+	sum := hh[0].Sum64()
+	for i, h := range hh {
+		if sum != h.Sum64() {
+			t.Errorf("hash %d not identical to a single Write", i)
+		}
 	}
 }
 
diff --git a/src/html/fuzz.go b/src/html/fuzz.go
index ffa3e25..ecaf4f9 100644
--- a/src/html/fuzz.go
+++ b/src/html/fuzz.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gofuzz
 // +build gofuzz
 
 package html
diff --git a/src/html/template/exec_test.go b/src/html/template/exec_test.go
index 7d1bef1..8885873 100644
--- a/src/html/template/exec_test.go
+++ b/src/html/template/exec_test.go
@@ -1720,8 +1720,6 @@
 `
 
 func TestEscapeRace(t *testing.T) {
-	t.Skip("this test currently fails with -race; see issue #39807")
-
 	tmpl := New("")
 	_, err := tmpl.New("templ.html").Parse(raceText)
 	if err != nil {
diff --git a/src/image/color/palette/gen.go b/src/image/color/palette/gen.go
index 3243e53..7bb257d 100644
--- a/src/image/color/palette/gen.go
+++ b/src/image/color/palette/gen.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 package main
diff --git a/src/image/draw/draw.go b/src/image/draw/draw.go
index 8f96aa2..13f6668 100644
--- a/src/image/draw/draw.go
+++ b/src/image/draw/draw.go
@@ -23,6 +23,16 @@
 	Set(x, y int, c color.Color)
 }
 
+// RGBA64Image extends both the Image and image.RGBA64Image interfaces with a
+// SetRGBA64 method to change a single pixel. SetRGBA64 is equivalent to
+// calling Set, but it can avoid allocations from converting concrete color
+// types to the color.Color interface type.
+type RGBA64Image interface {
+	image.RGBA64Image
+	Set(x, y int, c color.Color)
+	SetRGBA64(x, y int, c color.RGBA64)
+}
+
 // Quantizer produces a palette for an image.
 type Quantizer interface {
 	// Quantize appends up to cap(p) - len(p) colors to p and returns the
diff --git a/src/image/geom.go b/src/image/geom.go
index 78e9e49..e71aa61 100644
--- a/src/image/geom.go
+++ b/src/image/geom.go
@@ -246,6 +246,14 @@
 	return color.Transparent
 }
 
+// RGBA64At implements the RGBA64Image interface.
+func (r Rectangle) RGBA64At(x, y int) color.RGBA64 {
+	if (Point{x, y}).In(r) {
+		return color.RGBA64{0xffff, 0xffff, 0xffff, 0xffff}
+	}
+	return color.RGBA64{}
+}
+
 // Bounds implements the Image interface.
 func (r Rectangle) Bounds() Rectangle {
 	return r
diff --git a/src/image/gif/reader.go b/src/image/gif/reader.go
index e580ab0..9e8268c 100644
--- a/src/image/gif/reader.go
+++ b/src/image/gif/reader.go
@@ -116,7 +116,7 @@
 // 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.
+// implements io.ByteReader and buffers blocks into the decoder's "tmp" buffer.
 type blockReader struct {
 	d    *decoder
 	i, j uint8 // d.tmp[i:j] contains the buffered bytes
diff --git a/src/image/image.go b/src/image/image.go
index 8adba96..930d9ac 100644
--- a/src/image/image.go
+++ b/src/image/image.go
@@ -45,6 +45,17 @@
 	At(x, y int) color.Color
 }
 
+// RGBA64Image is an Image whose pixels can be converted directly to a
+// color.RGBA64.
+type RGBA64Image interface {
+	// RGBA64At returns the RGBA64 color of the pixel at (x, y). It is
+	// equivalent to calling At(x, y).RGBA() and converting the resulting
+	// 32-bit return values to a color.RGBA64, but it can avoid allocations
+	// from converting concrete color types to the color.Color interface type.
+	RGBA64At(x, y int) color.RGBA64
+	Image
+}
+
 // PalettedImage is an image whose colors may come from a limited palette.
 // If m is a PalettedImage and m.ColorModel() returns a color.Palette p,
 // then m.At(x, y) should be equivalent to p[m.ColorIndexAt(x, y)]. If m's
@@ -90,6 +101,24 @@
 	return p.RGBAAt(x, y)
 }
 
+func (p *RGBA) RGBA64At(x, y int) color.RGBA64 {
+	if !(Point{x, y}.In(p.Rect)) {
+		return color.RGBA64{}
+	}
+	i := p.PixOffset(x, y)
+	s := p.Pix[i : i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
+	r := uint16(s[0])
+	g := uint16(s[1])
+	b := uint16(s[2])
+	a := uint16(s[3])
+	return color.RGBA64{
+		(r << 8) | r,
+		(g << 8) | g,
+		(b << 8) | b,
+		(a << 8) | a,
+	}
+}
+
 func (p *RGBA) RGBAAt(x, y int) color.RGBA {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.RGBA{}
@@ -118,6 +147,18 @@
 	s[3] = c1.A
 }
 
+func (p *RGBA) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	s := p.Pix[i : i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
+	s[0] = uint8(c.R >> 8)
+	s[1] = uint8(c.G >> 8)
+	s[2] = uint8(c.B >> 8)
+	s[3] = uint8(c.A >> 8)
+}
+
 func (p *RGBA) SetRGBA(x, y int, c color.RGBA) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -311,6 +352,11 @@
 	return p.NRGBAAt(x, y)
 }
 
+func (p *NRGBA) RGBA64At(x, y int) color.RGBA64 {
+	r, g, b, a := p.NRGBAAt(x, y).RGBA()
+	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
 func (p *NRGBA) NRGBAAt(x, y int) color.NRGBA {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.NRGBA{}
@@ -339,6 +385,24 @@
 	s[3] = c1.A
 }
 
+func (p *NRGBA) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	r, g, b, a := uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
+	if (a != 0) && (a != 0xffff) {
+		r = (r * 0xffff) / a
+		g = (g * 0xffff) / a
+		b = (b * 0xffff) / a
+	}
+	i := p.PixOffset(x, y)
+	s := p.Pix[i : i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
+	s[0] = uint8(r >> 8)
+	s[1] = uint8(g >> 8)
+	s[2] = uint8(b >> 8)
+	s[3] = uint8(a >> 8)
+}
+
 func (p *NRGBA) SetNRGBA(x, y int, c color.NRGBA) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -415,6 +479,11 @@
 	return p.NRGBA64At(x, y)
 }
 
+func (p *NRGBA64) RGBA64At(x, y int) color.RGBA64 {
+	r, g, b, a := p.NRGBA64At(x, y).RGBA()
+	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
 func (p *NRGBA64) NRGBA64At(x, y int) color.NRGBA64 {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.NRGBA64{}
@@ -452,6 +521,28 @@
 	s[7] = uint8(c1.A)
 }
 
+func (p *NRGBA64) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	r, g, b, a := uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
+	if (a != 0) && (a != 0xffff) {
+		r = (r * 0xffff) / a
+		g = (g * 0xffff) / a
+		b = (b * 0xffff) / a
+	}
+	i := p.PixOffset(x, y)
+	s := p.Pix[i : i+8 : i+8] // Small cap improves performance, see https://golang.org/issue/27857
+	s[0] = uint8(r >> 8)
+	s[1] = uint8(r)
+	s[2] = uint8(g >> 8)
+	s[3] = uint8(g)
+	s[4] = uint8(b >> 8)
+	s[5] = uint8(b)
+	s[6] = uint8(a >> 8)
+	s[7] = uint8(a)
+}
+
 func (p *NRGBA64) SetNRGBA64(x, y int, c color.NRGBA64) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -532,6 +623,12 @@
 	return p.AlphaAt(x, y)
 }
 
+func (p *Alpha) RGBA64At(x, y int) color.RGBA64 {
+	a := uint16(p.AlphaAt(x, y).A)
+	a |= a << 8
+	return color.RGBA64{a, a, a, a}
+}
+
 func (p *Alpha) AlphaAt(x, y int) color.Alpha {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.Alpha{}
@@ -554,6 +651,14 @@
 	p.Pix[i] = color.AlphaModel.Convert(c).(color.Alpha).A
 }
 
+func (p *Alpha) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i] = uint8(c.A >> 8)
+}
+
 func (p *Alpha) SetAlpha(x, y int, c color.Alpha) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -626,6 +731,11 @@
 	return p.Alpha16At(x, y)
 }
 
+func (p *Alpha16) RGBA64At(x, y int) color.RGBA64 {
+	a := p.Alpha16At(x, y).A
+	return color.RGBA64{a, a, a, a}
+}
+
 func (p *Alpha16) Alpha16At(x, y int) color.Alpha16 {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.Alpha16{}
@@ -650,6 +760,15 @@
 	p.Pix[i+1] = uint8(c1.A)
 }
 
+func (p *Alpha16) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i+0] = uint8(c.A >> 8)
+	p.Pix[i+1] = uint8(c.A)
+}
+
 func (p *Alpha16) SetAlpha16(x, y int, c color.Alpha16) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -723,6 +842,12 @@
 	return p.GrayAt(x, y)
 }
 
+func (p *Gray) RGBA64At(x, y int) color.RGBA64 {
+	gray := uint16(p.GrayAt(x, y).Y)
+	gray |= gray << 8
+	return color.RGBA64{gray, gray, gray, 0xffff}
+}
+
 func (p *Gray) GrayAt(x, y int) color.Gray {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.Gray{}
@@ -745,6 +870,16 @@
 	p.Pix[i] = color.GrayModel.Convert(c).(color.Gray).Y
 }
 
+func (p *Gray) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	// This formula is the same as in color.grayModel.
+	gray := (19595*uint32(c.R) + 38470*uint32(c.G) + 7471*uint32(c.B) + 1<<15) >> 24
+	i := p.PixOffset(x, y)
+	p.Pix[i] = uint8(gray)
+}
+
 func (p *Gray) SetGray(x, y int, c color.Gray) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -804,6 +939,11 @@
 	return p.Gray16At(x, y)
 }
 
+func (p *Gray16) RGBA64At(x, y int) color.RGBA64 {
+	gray := p.Gray16At(x, y).Y
+	return color.RGBA64{gray, gray, gray, 0xffff}
+}
+
 func (p *Gray16) Gray16At(x, y int) color.Gray16 {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.Gray16{}
@@ -828,6 +968,17 @@
 	p.Pix[i+1] = uint8(c1.Y)
 }
 
+func (p *Gray16) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	// This formula is the same as in color.gray16Model.
+	gray := (19595*uint32(c.R) + 38470*uint32(c.G) + 7471*uint32(c.B) + 1<<15) >> 16
+	i := p.PixOffset(x, y)
+	p.Pix[i+0] = uint8(gray >> 8)
+	p.Pix[i+1] = uint8(gray)
+}
+
 func (p *Gray16) SetGray16(x, y int, c color.Gray16) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -888,6 +1039,11 @@
 	return p.CMYKAt(x, y)
 }
 
+func (p *CMYK) RGBA64At(x, y int) color.RGBA64 {
+	r, g, b, a := p.CMYKAt(x, y).RGBA()
+	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
 func (p *CMYK) CMYKAt(x, y int) color.CMYK {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.CMYK{}
@@ -916,6 +1072,19 @@
 	s[3] = c1.K
 }
 
+func (p *CMYK) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	cc, mm, yy, kk := color.RGBToCMYK(uint8(c.R>>8), uint8(c.G>>8), uint8(c.B>>8))
+	i := p.PixOffset(x, y)
+	s := p.Pix[i : i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
+	s[0] = cc
+	s[1] = mm
+	s[2] = yy
+	s[3] = kk
+}
+
 func (p *CMYK) SetCMYK(x, y int, c color.CMYK) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -988,6 +1157,26 @@
 	return p.Palette[p.Pix[i]]
 }
 
+func (p *Paletted) RGBA64At(x, y int) color.RGBA64 {
+	if len(p.Palette) == 0 {
+		return color.RGBA64{}
+	}
+	c := color.Color(nil)
+	if !(Point{x, y}.In(p.Rect)) {
+		c = p.Palette[0]
+	} else {
+		i := p.PixOffset(x, y)
+		c = p.Palette[p.Pix[i]]
+	}
+	r, g, b, a := c.RGBA()
+	return color.RGBA64{
+		uint16(r),
+		uint16(g),
+		uint16(b),
+		uint16(a),
+	}
+}
+
 // PixOffset returns the index of the first element of Pix that corresponds to
 // the pixel at (x, y).
 func (p *Paletted) PixOffset(x, y int) int {
@@ -1002,6 +1191,14 @@
 	p.Pix[i] = uint8(p.Palette.Index(c))
 }
 
+func (p *Paletted) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i] = uint8(p.Palette.Index(c))
+}
+
 func (p *Paletted) ColorIndexAt(x, y int) uint8 {
 	if !(Point{x, y}.In(p.Rect)) {
 		return 0
diff --git a/src/image/image_test.go b/src/image/image_test.go
index b9b9bfa..7f41bcb 100644
--- a/src/image/image_test.go
+++ b/src/image/image_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"image/color"
+	"image/color/palette"
 	"testing"
 )
 
@@ -191,6 +192,92 @@
 	}
 }
 
+func TestRGBA64Image(t *testing.T) {
+	// memset sets every element of s to v.
+	memset := func(s []byte, v byte) {
+		for i := range s {
+			s[i] = v
+		}
+	}
+
+	r := Rect(0, 0, 3, 2)
+	testCases := []Image{
+		NewAlpha(r),
+		NewAlpha16(r),
+		NewCMYK(r),
+		NewGray(r),
+		NewGray16(r),
+		NewNRGBA(r),
+		NewNRGBA64(r),
+		NewNYCbCrA(r, YCbCrSubsampleRatio444),
+		NewPaletted(r, palette.Plan9),
+		NewRGBA(r),
+		NewRGBA64(r),
+		NewUniform(color.RGBA64{}),
+		NewYCbCr(r, YCbCrSubsampleRatio444),
+		r,
+	}
+	for _, tc := range testCases {
+		switch tc := tc.(type) {
+		// Most of the concrete image types in the testCases implement the
+		// draw.RGBA64Image interface: they have a SetRGBA64 method. We use an
+		// interface literal here, instead of importing "image/draw", to avoid
+		// an import cycle.
+		//
+		// The YCbCr and NYCbCrA types are special-cased. Chroma subsampling
+		// means that setting one pixel can modify neighboring pixels. They
+		// don't have Set or SetRGBA64 methods because that side effect could
+		// be surprising. Here, we just memset the channel buffers instead.
+		//
+		// The Uniform and Rectangle types are also special-cased, as they
+		// don't have a Set or SetRGBA64 method.
+		case interface {
+			SetRGBA64(x, y int, c color.RGBA64)
+		}:
+			tc.SetRGBA64(1, 1, color.RGBA64{0x7FFF, 0x3FFF, 0x0000, 0x7FFF})
+
+		case *NYCbCrA:
+			memset(tc.YCbCr.Y, 0x77)
+			memset(tc.YCbCr.Cb, 0x88)
+			memset(tc.YCbCr.Cr, 0x99)
+			memset(tc.A, 0xAA)
+
+		case *Uniform:
+			tc.C = color.RGBA64{0x7FFF, 0x3FFF, 0x0000, 0x7FFF}
+
+		case *YCbCr:
+			memset(tc.Y, 0x77)
+			memset(tc.Cb, 0x88)
+			memset(tc.Cr, 0x99)
+
+		case Rectangle:
+			// No-op. Rectangle pixels' colors are immutable. They're always
+			// color.Opaque.
+
+		default:
+			t.Errorf("could not initialize pixels for %T", tc)
+			continue
+		}
+
+		// Check that RGBA64At(x, y) is equivalent to At(x, y).RGBA().
+		rgba64Image, ok := tc.(RGBA64Image)
+		if !ok {
+			t.Errorf("%T is not an RGBA64Image", tc)
+			continue
+		}
+		got := rgba64Image.RGBA64At(1, 1)
+		wantR, wantG, wantB, wantA := tc.At(1, 1).RGBA()
+		if (uint32(got.R) != wantR) || (uint32(got.G) != wantG) ||
+			(uint32(got.B) != wantB) || (uint32(got.A) != wantA) {
+			t.Errorf("%T:\ngot  (0x%04X, 0x%04X, 0x%04X, 0x%04X)\n"+
+				"want (0x%04X, 0x%04X, 0x%04X, 0x%04X)", tc,
+				got.R, got.G, got.B, got.A,
+				wantR, wantG, wantB, wantA)
+			continue
+		}
+	}
+}
+
 func BenchmarkAt(b *testing.B) {
 	for _, tc := range testImages {
 		b.Run(tc.name, func(b *testing.B) {
diff --git a/src/image/internal/imageutil/gen.go b/src/image/internal/imageutil/gen.go
index 36de5dc..38f4130 100644
--- a/src/image/internal/imageutil/gen.go
+++ b/src/image/internal/imageutil/gen.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 package main
diff --git a/src/image/jpeg/reader.go b/src/image/jpeg/reader.go
index 4a4706f..b340723 100644
--- a/src/image/jpeg/reader.go
+++ b/src/image/jpeg/reader.go
@@ -14,9 +14,6 @@
 	"io"
 )
 
-// TODO(nigeltao): fix up the doc comment style so that sentences start with
-// the name of the type or function that they annotate.
-
 // A FormatError reports that the input is not a valid JPEG.
 type FormatError string
 
diff --git a/src/image/names.go b/src/image/names.go
index 8595a35..17b0658 100644
--- a/src/image/names.go
+++ b/src/image/names.go
@@ -41,6 +41,11 @@
 
 func (c *Uniform) At(x, y int) color.Color { return c.C }
 
+func (c *Uniform) RGBA64At(x, y int) color.RGBA64 {
+	r, g, b, a := c.C.RGBA()
+	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
 // Opaque scans the entire image and reports whether it is fully opaque.
 func (c *Uniform) Opaque() bool {
 	_, _, _, a := c.C.RGBA()
diff --git a/src/image/png/fuzz.go b/src/image/png/fuzz.go
index d9cb392..6508533 100644
--- a/src/image/png/fuzz.go
+++ b/src/image/png/fuzz.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gofuzz
 // +build gofuzz
 
 package png
diff --git a/src/image/png/writer.go b/src/image/png/writer.go
index 53adc16..cbcdb9e 100644
--- a/src/image/png/writer.go
+++ b/src/image/png/writer.go
@@ -51,6 +51,7 @@
 	bw      *bufio.Writer
 }
 
+// CompressionLevel indicates the compression level.
 type CompressionLevel int
 
 const (
diff --git a/src/image/ycbcr.go b/src/image/ycbcr.go
index fbdffe1..328b90d 100644
--- a/src/image/ycbcr.go
+++ b/src/image/ycbcr.go
@@ -71,6 +71,11 @@
 	return p.YCbCrAt(x, y)
 }
 
+func (p *YCbCr) RGBA64At(x, y int) color.RGBA64 {
+	r, g, b, a := p.YCbCrAt(x, y).RGBA()
+	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
 func (p *YCbCr) YCbCrAt(x, y int) color.YCbCr {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.YCbCr{}
@@ -210,6 +215,11 @@
 	return p.NYCbCrAAt(x, y)
 }
 
+func (p *NYCbCrA) RGBA64At(x, y int) color.RGBA64 {
+	r, g, b, a := p.NYCbCrAAt(x, y).RGBA()
+	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
 func (p *NYCbCrA) NYCbCrAAt(x, y int) color.NYCbCrA {
 	if !(Point{X: x, Y: y}.In(p.Rect)) {
 		return color.NYCbCrA{}
diff --git a/src/index/suffixarray/gen.go b/src/index/suffixarray/gen.go
index 94184d7..3bc9b1e 100644
--- a/src/index/suffixarray/gen.go
+++ b/src/index/suffixarray/gen.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // Gen generates sais2.go by duplicating functions in sais.go
diff --git a/src/internal/abi/abi.go b/src/internal/abi/abi.go
new file mode 100644
index 0000000..aaff9ce
--- /dev/null
+++ b/src/internal/abi/abi.go
@@ -0,0 +1,77 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package abi
+
+import "unsafe"
+
+// RegArgs is a struct that has space for each argument
+// and return value register on the current architecture.
+//
+// Assembly code knows the layout of the first two fields
+// of RegArgs.
+//
+// RegArgs also contains additional space to hold pointers
+// when it may not be safe to keep them only in the integer
+// register space otherwise.
+type RegArgs struct {
+	Ints   [IntArgRegs]uintptr  // untyped integer registers
+	Floats [FloatArgRegs]uint64 // untyped float registers
+
+	// Fields above this point are known to assembly.
+
+	// Ptrs is a space that duplicates Ints but with pointer type,
+	// used to make pointers passed or returned  in registers
+	// visible to the GC by making the type unsafe.Pointer.
+	Ptrs [IntArgRegs]unsafe.Pointer
+
+	// ReturnIsPtr is a bitmap that indicates which registers
+	// contain or will contain pointers on the return path from
+	// a reflectcall. The i'th bit indicates whether the i'th
+	// register contains or will contain a valid Go pointer.
+	ReturnIsPtr IntArgRegBitmap
+}
+
+// IntArgRegBitmap is a bitmap large enough to hold one bit per
+// integer argument/return register.
+type IntArgRegBitmap [(IntArgRegs + 7) / 8]uint8
+
+// Set sets the i'th bit of the bitmap to 1.
+func (b *IntArgRegBitmap) Set(i int) {
+	b[i/8] |= uint8(1) << (i % 8)
+}
+
+// Get returns whether the i'th bit of the bitmap is set.
+//
+// nosplit because it's called in extremely sensitive contexts, like
+// on the reflectcall return path.
+//
+//go:nosplit
+func (b *IntArgRegBitmap) Get(i int) bool {
+	return b[i/8]&(uint8(1)<<(i%8)) != 0
+}
+
+// FuncPC* intrinsics.
+//
+// CAREFUL: In programs with plugins, FuncPC* can return different values
+// for the same function (because there are actually multiple copies of
+// the same function in the address space). To be safe, don't use the
+// results of this function in any == expression. It is only safe to
+// use the result as an address at which to start executing code.
+
+// FuncPCABI0 returns the entry PC of the function f, which must be a
+// direct reference of a function defined as ABI0. Otherwise it is a
+// compile-time error.
+//
+// Implemented as a compile intrinsic.
+func FuncPCABI0(f interface{}) uintptr
+
+// FuncPCABIInternal returns the entry PC of the function f. If f is a
+// direct reference of a function, it must be defined as ABIInternal.
+// Otherwise it is a compile-time error. If f is not a direct reference
+// of a defined function, it assumes that f is a func value. Otherwise
+// the behavior is undefined.
+//
+// Implemented as a compile intrinsic.
+func FuncPCABIInternal(f interface{}) uintptr
diff --git a/src/internal/abi/abi_amd64.go b/src/internal/abi/abi_amd64.go
new file mode 100644
index 0000000..aff71f6
--- /dev/null
+++ b/src/internal/abi/abi_amd64.go
@@ -0,0 +1,21 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.regabireflect
+// +build goexperiment.regabireflect
+
+package abi
+
+const (
+	// See abi_generic.go.
+
+	// RAX, RBX, RCX, RDI, RSI, R8, R9, R10, R11.
+	IntArgRegs = 9
+
+	// X0 -> X14.
+	FloatArgRegs = 15
+
+	// We use SSE2 registers which support 64-bit float operations.
+	EffectiveFloatRegSize = 8
+)
diff --git a/src/internal/abi/abi_generic.go b/src/internal/abi/abi_generic.go
new file mode 100644
index 0000000..69400f9
--- /dev/null
+++ b/src/internal/abi/abi_generic.go
@@ -0,0 +1,39 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !goexperiment.regabireflect
+// +build !goexperiment.regabireflect
+
+package abi
+
+const (
+	// ABI-related constants.
+	//
+	// In the generic case, these are all zero
+	// which lets them gracefully degrade to ABI0.
+
+	// IntArgRegs is the number of registers dedicated
+	// to passing integer argument values. Result registers are identical
+	// to argument registers, so this number is used for those too.
+	IntArgRegs = 0
+
+	// FloatArgRegs is the number of registers dedicated
+	// to passing floating-point argument values. Result registers are
+	// identical to argument registers, so this number is used for
+	// those too.
+	FloatArgRegs = 0
+
+	// EffectiveFloatRegSize describes the width of floating point
+	// registers on the current platform from the ABI's perspective.
+	//
+	// Since Go only supports 32-bit and 64-bit floating point primitives,
+	// this number should be either 0, 4, or 8. 0 indicates no floating
+	// point registers for the ABI or that floating point values will be
+	// passed via the softfloat ABI.
+	//
+	// For platforms that support larger floating point register widths,
+	// such as x87's 80-bit "registers" (not that we support x87 currently),
+	// use 8.
+	EffectiveFloatRegSize = 0
+)
diff --git a/src/internal/abi/abi_test.go b/src/internal/abi/abi_test.go
new file mode 100644
index 0000000..5a3b6b6
--- /dev/null
+++ b/src/internal/abi/abi_test.go
@@ -0,0 +1,76 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package abi_test
+
+import (
+	"internal/abi"
+	"internal/testenv"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+func TestFuncPC(t *testing.T) {
+	// Test that FuncPC* can get correct function PC.
+	pcFromAsm := abi.FuncPCTestFnAddr
+
+	// Test FuncPC for locally defined function
+	pcFromGo := abi.FuncPCTest()
+	if pcFromGo != pcFromAsm {
+		t.Errorf("FuncPC returns wrong PC, want %x, got %x", pcFromAsm, pcFromGo)
+	}
+
+	// Test FuncPC for imported function
+	pcFromGo = abi.FuncPCABI0(abi.FuncPCTestFn)
+	if pcFromGo != pcFromAsm {
+		t.Errorf("FuncPC returns wrong PC, want %x, got %x", pcFromAsm, pcFromGo)
+	}
+}
+
+func TestFuncPCCompileError(t *testing.T) {
+	// Test that FuncPC* on a function of a mismatched ABI is rejected.
+	testenv.MustHaveGoBuild(t)
+
+	// We want to test internal package, which we cannot normally import.
+	// Run the assembler and compiler manually.
+	tmpdir := t.TempDir()
+	asmSrc := filepath.Join("testdata", "x.s")
+	goSrc := filepath.Join("testdata", "x.go")
+	symabi := filepath.Join(tmpdir, "symabi")
+	obj := filepath.Join(tmpdir, "x.o")
+
+	// parse assembly code for symabi.
+	cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-gensymabis", "-o", symabi, asmSrc)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("go tool asm -gensymabis failed: %v\n%s", err, out)
+	}
+
+	// compile go code.
+	cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-symabis", symabi, "-o", obj, goSrc)
+	out, err = cmd.CombinedOutput()
+	if err == nil {
+		t.Fatalf("go tool compile did not fail")
+	}
+
+	// Expect errors in line 17, 18, 20, no errors on other lines.
+	want := []string{"x.go:17", "x.go:18", "x.go:20"}
+	got := strings.Split(string(out), "\n")
+	if got[len(got)-1] == "" {
+		got = got[:len(got)-1] // remove last empty line
+	}
+	for i, s := range got {
+		if !strings.Contains(s, want[i]) {
+			t.Errorf("did not error on line %s", want[i])
+		}
+	}
+	if len(got) != len(want) {
+		t.Errorf("unexpected number of errors, want %d, got %d", len(want), len(got))
+	}
+	if t.Failed() {
+		t.Logf("output:\n%s", string(out))
+	}
+}
diff --git a/src/internal/abi/abi_test.s b/src/internal/abi/abi_test.s
new file mode 100644
index 0000000..93ace3e
--- /dev/null
+++ b/src/internal/abi/abi_test.s
@@ -0,0 +1,27 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+#ifdef GOARCH_386
+#define PTRSIZE 4
+#endif
+#ifdef GOARCH_arm
+#define PTRSIZE 4
+#endif
+#ifdef GOARCH_mips
+#define PTRSIZE 4
+#endif
+#ifdef GOARCH_mipsle
+#define PTRSIZE 4
+#endif
+#ifndef PTRSIZE
+#define PTRSIZE 8
+#endif
+
+TEXT	internal∕abi·FuncPCTestFn(SB),NOSPLIT,$0-0
+	RET
+
+GLOBL	internal∕abi·FuncPCTestFnAddr(SB), NOPTR, $PTRSIZE
+DATA	internal∕abi·FuncPCTestFnAddr(SB)/PTRSIZE, $internal∕abi·FuncPCTestFn(SB)
diff --git a/src/internal/abi/export_test.go b/src/internal/abi/export_test.go
new file mode 100644
index 0000000..2a87e9d
--- /dev/null
+++ b/src/internal/abi/export_test.go
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package abi
+
+func FuncPCTestFn()
+
+var FuncPCTestFnAddr uintptr // address of FuncPCTestFn, directly retrieved from assembly
+
+//go:noinline
+func FuncPCTest() uintptr {
+	return FuncPCABI0(FuncPCTestFn)
+}
diff --git a/src/internal/abi/testdata/x.go b/src/internal/abi/testdata/x.go
new file mode 100644
index 0000000..cae103d
--- /dev/null
+++ b/src/internal/abi/testdata/x.go
@@ -0,0 +1,22 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package x
+
+import "internal/abi"
+
+func Fn0() // defined in assembly
+
+func Fn1() {}
+
+var FnExpr func()
+
+func test() {
+	_ = abi.FuncPCABI0(Fn0)           // line 16, no error
+	_ = abi.FuncPCABIInternal(Fn0)    // line 17, error
+	_ = abi.FuncPCABI0(Fn1)           // line 18, error
+	_ = abi.FuncPCABIInternal(Fn1)    // line 19, no error
+	_ = abi.FuncPCABI0(FnExpr)        // line 20, error
+	_ = abi.FuncPCABIInternal(FnExpr) // line 21, no error
+}
diff --git a/src/internal/abi/testdata/x.s b/src/internal/abi/testdata/x.s
new file mode 100644
index 0000000..63c1385
--- /dev/null
+++ b/src/internal/abi/testdata/x.s
@@ -0,0 +1,6 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+TEXT	·Fn0(SB), 0, $0-0
+	RET
diff --git a/src/internal/buildcfg/cfg.go b/src/internal/buildcfg/cfg.go
new file mode 100644
index 0000000..9fe7f21
--- /dev/null
+++ b/src/internal/buildcfg/cfg.go
@@ -0,0 +1,136 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package buildcfg provides access to the build configuration
+// described by the current environment. It is for use by build tools
+// such as cmd/go or cmd/compile and for setting up go/build's Default context.
+//
+// Note that it does NOT provide access to the build configuration used to
+// build the currently-running binary. For that, use runtime.GOOS etc
+// as well as internal/goexperiment.
+package buildcfg
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+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()
+	GOMIPS64 = gomips64()
+	GOPPC64  = goppc64()
+	GOWASM   = gowasm()
+	GO_LDSO  = defaultGO_LDSO
+	Version  = version
+)
+
+// Error is one of the errors found (if any) in the build configuration.
+var Error error
+
+// Check exits the program with a fatal error if Error is non-nil.
+func Check() {
+	if Error != nil {
+		fmt.Fprintf(os.Stderr, "%s: %v\n", filepath.Base(os.Args[0]), Error)
+		os.Exit(2)
+	}
+}
+
+func envOr(key, value string) string {
+	if x := os.Getenv(key); x != "" {
+		return x
+	}
+	return value
+}
+
+func goarm() int {
+	def := defaultGOARM
+	if GOOS == "android" && GOARCH == "arm" {
+		// Android arm devices always support GOARM=7.
+		def = "7"
+	}
+	switch v := envOr("GOARM", def); v {
+	case "5":
+		return 5
+	case "6":
+		return 6
+	case "7":
+		return 7
+	}
+	Error = fmt.Errorf("invalid GOARM: must be 5, 6, 7")
+	return int(def[0] - '0')
+}
+
+func gomips() string {
+	switch v := envOr("GOMIPS", defaultGOMIPS); v {
+	case "hardfloat", "softfloat":
+		return v
+	}
+	Error = fmt.Errorf("invalid GOMIPS: must be hardfloat, softfloat")
+	return defaultGOMIPS
+}
+
+func gomips64() string {
+	switch v := envOr("GOMIPS64", defaultGOMIPS64); v {
+	case "hardfloat", "softfloat":
+		return v
+	}
+	Error = fmt.Errorf("invalid GOMIPS64: must be hardfloat, softfloat")
+	return defaultGOMIPS64
+}
+
+func goppc64() int {
+	switch v := envOr("GOPPC64", defaultGOPPC64); v {
+	case "power8":
+		return 8
+	case "power9":
+		return 9
+	}
+	Error = fmt.Errorf("invalid GOPPC64: must be power8, power9")
+	return int(defaultGOPPC64[len("power")] - '0')
+}
+
+type gowasmFeatures struct {
+	SignExt bool
+	SatConv bool
+}
+
+func (f gowasmFeatures) String() string {
+	var flags []string
+	if f.SatConv {
+		flags = append(flags, "satconv")
+	}
+	if f.SignExt {
+		flags = append(flags, "signext")
+	}
+	return strings.Join(flags, ",")
+}
+
+func gowasm() (f gowasmFeatures) {
+	for _, opt := range strings.Split(envOr("GOWASM", ""), ",") {
+		switch opt {
+		case "satconv":
+			f.SatConv = true
+		case "signext":
+			f.SignExt = true
+		case "":
+			// ignore
+		default:
+			Error = fmt.Errorf("invalid GOWASM: no such feature %q", opt)
+		}
+	}
+	return
+}
+
+func Getgoextlinkenabled() string {
+	return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
+}
diff --git a/src/internal/buildcfg/exp.go b/src/internal/buildcfg/exp.go
new file mode 100644
index 0000000..9a60253
--- /dev/null
+++ b/src/internal/buildcfg/exp.go
@@ -0,0 +1,189 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package buildcfg
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+
+	"internal/goexperiment"
+)
+
+// Experiment contains the toolchain experiments enabled for the
+// current build.
+//
+// (This is not necessarily the set of experiments the compiler itself
+// was built with.)
+//
+// experimentBaseline specifies the experiment flags that are enabled by
+// default in the current toolchain. This is, in effect, the "control"
+// configuration and any variation from this is an experiment.
+var Experiment, experimentBaseline = func() (goexperiment.Flags, goexperiment.Flags) {
+	flags, baseline, err := ParseGOEXPERIMENT(GOOS, GOARCH, envOr("GOEXPERIMENT", defaultGOEXPERIMENT))
+	if err != nil {
+		Error = err
+	}
+	return flags, baseline
+}()
+
+const DefaultGOEXPERIMENT = defaultGOEXPERIMENT
+
+// FramePointerEnabled enables the use of platform conventions for
+// saving frame pointers.
+//
+// This used to be an experiment, but now it's always enabled on
+// platforms that support it.
+//
+// Note: must agree with runtime.framepointer_enabled.
+var FramePointerEnabled = GOARCH == "amd64" || GOARCH == "arm64"
+
+// ParseGOEXPERIMENT parses a (GOOS, GOARCH, GOEXPERIMENT)
+// configuration tuple and returns the enabled and baseline experiment
+// flag sets.
+//
+// TODO(mdempsky): Move to internal/goexperiment.
+func ParseGOEXPERIMENT(goos, goarch, goexp string) (flags, baseline goexperiment.Flags, err error) {
+	regabiSupported := goarch == "amd64" && (goos == "android" || goos == "linux" || goos == "darwin" || goos == "windows")
+
+	baseline = goexperiment.Flags{
+		RegabiWrappers: regabiSupported,
+		RegabiG:        regabiSupported,
+		RegabiReflect:  regabiSupported,
+		RegabiDefer:    regabiSupported,
+		RegabiArgs:     regabiSupported,
+	}
+
+	// Start with the statically enabled set of experiments.
+	flags = baseline
+
+	// Pick up any changes to the baseline configuration from the
+	// GOEXPERIMENT environment. This can be set at make.bash time
+	// and overridden at build time.
+	if goexp != "" {
+		// Create a map of known experiment names.
+		names := make(map[string]func(bool))
+		rv := reflect.ValueOf(&flags).Elem()
+		rt := rv.Type()
+		for i := 0; i < rt.NumField(); i++ {
+			field := rv.Field(i)
+			names[strings.ToLower(rt.Field(i).Name)] = field.SetBool
+		}
+
+		// "regabi" is an alias for all working regabi
+		// subexperiments, and not an experiment itself. Doing
+		// this as an alias make both "regabi" and "noregabi"
+		// do the right thing.
+		names["regabi"] = func(v bool) {
+			flags.RegabiWrappers = v
+			flags.RegabiG = v
+			flags.RegabiReflect = v
+			flags.RegabiDefer = v
+			flags.RegabiArgs = v
+		}
+
+		// Parse names.
+		for _, f := range strings.Split(goexp, ",") {
+			if f == "" {
+				continue
+			}
+			if f == "none" {
+				// GOEXPERIMENT=none disables all experiment flags.
+				// This is used by cmd/dist, which doesn't know how
+				// to build with any experiment flags.
+				flags = goexperiment.Flags{}
+				continue
+			}
+			val := true
+			if strings.HasPrefix(f, "no") {
+				f, val = f[2:], false
+			}
+			set, ok := names[f]
+			if !ok {
+				err = fmt.Errorf("unknown GOEXPERIMENT %s", f)
+				return
+			}
+			set(val)
+		}
+	}
+
+	// regabi is only supported on amd64.
+	if goarch != "amd64" {
+		flags.RegabiWrappers = false
+		flags.RegabiG = false
+		flags.RegabiReflect = false
+		flags.RegabiDefer = false
+		flags.RegabiArgs = false
+	}
+	// Check regabi dependencies.
+	if flags.RegabiG && !flags.RegabiWrappers {
+		err = fmt.Errorf("GOEXPERIMENT regabig requires regabiwrappers")
+	}
+	if flags.RegabiArgs && !(flags.RegabiWrappers && flags.RegabiG && flags.RegabiReflect && flags.RegabiDefer) {
+		err = fmt.Errorf("GOEXPERIMENT regabiargs requires regabiwrappers,regabig,regabireflect,regabidefer")
+	}
+	return
+}
+
+// expList returns the list of lower-cased experiment names for
+// experiments that differ from base. base may be nil to indicate no
+// experiments. If all is true, then include all experiment flags,
+// regardless of base.
+func expList(exp, base *goexperiment.Flags, all bool) []string {
+	var list []string
+	rv := reflect.ValueOf(exp).Elem()
+	var rBase reflect.Value
+	if base != nil {
+		rBase = reflect.ValueOf(base).Elem()
+	}
+	rt := rv.Type()
+	for i := 0; i < rt.NumField(); i++ {
+		name := strings.ToLower(rt.Field(i).Name)
+		val := rv.Field(i).Bool()
+		baseVal := false
+		if base != nil {
+			baseVal = rBase.Field(i).Bool()
+		}
+		if all || val != baseVal {
+			if val {
+				list = append(list, name)
+			} else {
+				list = append(list, "no"+name)
+			}
+		}
+	}
+	return list
+}
+
+// GOEXPERIMENT is a comma-separated list of enabled or disabled
+// experiments that differ from the baseline experiment configuration.
+// GOEXPERIMENT is exactly what a user would set on the command line
+// to get the set of enabled experiments.
+func GOEXPERIMENT() string {
+	return strings.Join(expList(&Experiment, &experimentBaseline, false), ",")
+}
+
+// EnabledExperiments returns a list of enabled experiments, as
+// lower-cased experiment names.
+func EnabledExperiments() []string {
+	return expList(&Experiment, nil, false)
+}
+
+// AllExperiments returns a list of all experiment settings.
+// Disabled experiments appear in the list prefixed by "no".
+func AllExperiments() []string {
+	return expList(&Experiment, nil, true)
+}
+
+// UpdateExperiments updates the Experiment global based on a new GOARCH value.
+// This is only required for cmd/go, which can change GOARCH after
+// program startup due to use of "go env -w".
+func UpdateExperiments(goos, goarch, goexperiment string) {
+	var err error
+	Experiment, experimentBaseline, err = ParseGOEXPERIMENT(goos, goarch, goexperiment)
+	if err != nil {
+		Error = err
+	}
+}
diff --git a/src/internal/buildcfg/zbootstrap.go b/src/internal/buildcfg/zbootstrap.go
new file mode 100644
index 0000000..be957f8
--- /dev/null
+++ b/src/internal/buildcfg/zbootstrap.go
@@ -0,0 +1,17 @@
+// Code generated by go tool dist; DO NOT EDIT.
+
+package buildcfg
+
+import "runtime"
+
+const defaultGO386 = `sse2`
+const defaultGOARM = `5`
+const defaultGOMIPS = `hardfloat`
+const defaultGOMIPS64 = `hardfloat`
+const defaultGOPPC64 = `power8`
+const defaultGOEXPERIMENT = ``
+const defaultGO_EXTLINK_ENABLED = ``
+const defaultGO_LDSO = ``
+const version = `go1.17`
+const defaultGOOS = runtime.GOOS
+const defaultGOARCH = runtime.GOARCH
diff --git a/src/internal/bytealg/bytealg.go b/src/internal/bytealg/bytealg.go
index b30c234..6b2b540 100644
--- a/src/internal/bytealg/bytealg.go
+++ b/src/internal/bytealg/bytealg.go
@@ -17,6 +17,8 @@
 	offsetX86HasPOPCNT = unsafe.Offsetof(cpu.X86.HasPOPCNT)
 
 	offsetS390xHasVX = unsafe.Offsetof(cpu.S390X.HasVX)
+
+	offsetPPC64HasPOWER9 = unsafe.Offsetof(cpu.PPC64.IsPOWER9)
 )
 
 // MaxLen is the maximum length of the string to be searched for (argument b) in Index.
diff --git a/src/internal/bytealg/compare_amd64.s b/src/internal/bytealg/compare_amd64.s
index 900b92a..8295acb 100644
--- a/src/internal/bytealg/compare_amd64.s
+++ b/src/internal/bytealg/compare_amd64.s
@@ -5,20 +5,41 @@
 #include "go_asm.h"
 #include "textflag.h"
 
-TEXT ·Compare(SB),NOSPLIT,$0-56
+TEXT ·Compare<ABIInternal>(SB),NOSPLIT,$0-56
+#ifdef GOEXPERIMENT_regabiargs
+	// AX = a_base (want in SI)
+	// BX = a_len  (want in BX)
+	// CX = a_cap  (unused)
+	// DI = b_base (want in DI)
+	// SI = b_len  (want in DX)
+	// R8 = b_cap  (unused)
+	MOVQ	SI, DX
+	MOVQ	AX, SI
+#else
 	MOVQ	a_base+0(FP), SI
 	MOVQ	a_len+8(FP), BX
 	MOVQ	b_base+24(FP), DI
 	MOVQ	b_len+32(FP), DX
 	LEAQ	ret+48(FP), R9
+#endif
 	JMP	cmpbody<>(SB)
 
-TEXT runtime·cmpstring(SB),NOSPLIT,$0-40
+TEXT runtime·cmpstring<ABIInternal>(SB),NOSPLIT,$0-40
+#ifdef GOEXPERIMENT_regabiargs
+	// AX = a_base (want in SI)
+	// BX = a_len  (want in BX)
+	// CX = b_base (want in DI)
+	// DI = b_len  (want in DX)
+	MOVQ	AX, SI
+	MOVQ	DI, DX
+	MOVQ	CX, DI
+#else
 	MOVQ	a_base+0(FP), SI
 	MOVQ	a_len+8(FP), BX
 	MOVQ	b_base+16(FP), DI
 	MOVQ	b_len+24(FP), DX
 	LEAQ	ret+32(FP), R9
+#endif
 	JMP	cmpbody<>(SB)
 
 // input:
@@ -26,7 +47,12 @@
 //   DI = b
 //   BX = alen
 //   DX = blen
+#ifndef GOEXPERIMENT_regabiargs
 //   R9 = address of output word (stores -1/0/1 here)
+#else
+// output:
+//   AX = output (-1/0/1)
+#endif
 TEXT cmpbody<>(SB),NOSPLIT,$0-0
 	CMPQ	SI, DI
 	JEQ	allsame
@@ -74,7 +100,9 @@
 	CMPB	CX, (DI)(BX*1)
 	SETHI	AX
 	LEAQ	-1(AX*2), AX	// convert 1/0 to +1/-1
+#ifndef GOEXPERIMENT_regabiargs
 	MOVQ	AX, (R9)
+#endif
 	RET
 
 	// 0 through 16 bytes left, alen>=8, blen>=8
@@ -100,7 +128,9 @@
 	SHRQ	CX, AX	// move a's bit to bottom
 	ANDQ	$1, AX	// mask bit
 	LEAQ	-1(AX*2), AX // 1/0 => +1/-1
+#ifndef GOEXPERIMENT_regabiargs
 	MOVQ	AX, (R9)
+#endif
 	RET
 
 	// 0-7 bytes in common
@@ -139,7 +169,9 @@
 	SHRQ	CX, SI	// move a's bit to bottom
 	ANDQ	$1, SI	// mask bit
 	LEAQ	-1(SI*2), AX // 1/0 => +1/-1
+#ifndef GOEXPERIMENT_regabiargs
 	MOVQ	AX, (R9)
+#endif
 	RET
 
 allsame:
@@ -149,7 +181,9 @@
 	SETGT	AX	// 1 if alen > blen
 	SETEQ	CX	// 1 if alen == blen
 	LEAQ	-1(CX)(AX*2), AX	// 1,0,-1 result
+#ifndef GOEXPERIMENT_regabiargs
 	MOVQ	AX, (R9)
+#endif
 	RET
 
 	// this works for >= 64 bytes of data.
diff --git a/src/internal/bytealg/compare_generic.go b/src/internal/bytealg/compare_generic.go
index bd4489a..0690d0c 100644
--- a/src/internal/bytealg/compare_generic.go
+++ b/src/internal/bytealg/compare_generic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !386 && !amd64 && !s390x && !arm && !arm64 && !ppc64 && !ppc64le && !mips && !mipsle && !wasm && !mips64 && !mips64le
 // +build !386,!amd64,!s390x,!arm,!arm64,!ppc64,!ppc64le,!mips,!mipsle,!wasm,!mips64,!mips64le
 
 package bytealg
diff --git a/src/internal/bytealg/compare_mips64x.s b/src/internal/bytealg/compare_mips64x.s
index 4f05fce..b472e51 100644
--- a/src/internal/bytealg/compare_mips64x.s
+++ b/src/internal/bytealg/compare_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "go_asm.h"
diff --git a/src/internal/bytealg/compare_mipsx.s b/src/internal/bytealg/compare_mipsx.s
index 9ac5ba5..dcc4916 100644
--- a/src/internal/bytealg/compare_mipsx.s
+++ b/src/internal/bytealg/compare_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "go_asm.h"
diff --git a/src/internal/bytealg/compare_native.go b/src/internal/bytealg/compare_native.go
index b53ba97..baa188f 100644
--- a/src/internal/bytealg/compare_native.go
+++ b/src/internal/bytealg/compare_native.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 || amd64 || s390x || arm || arm64 || ppc64 || ppc64le || mips || mipsle || wasm || mips64 || mips64le
 // +build 386 amd64 s390x arm arm64 ppc64 ppc64le mips mipsle wasm mips64 mips64le
 
 package bytealg
diff --git a/src/internal/bytealg/compare_ppc64x.s b/src/internal/bytealg/compare_ppc64x.s
index 7819da3..83444fa 100644
--- a/src/internal/bytealg/compare_ppc64x.s
+++ b/src/internal/bytealg/compare_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "go_asm.h"
diff --git a/src/internal/bytealg/count_generic.go b/src/internal/bytealg/count_generic.go
index 5575e81..1891d29 100644
--- a/src/internal/bytealg/count_generic.go
+++ b/src/internal/bytealg/count_generic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !amd64 && !arm && !arm64 && !ppc64le && !ppc64 && !riscv64 && !s390x
 // +build !amd64,!arm,!arm64,!ppc64le,!ppc64,!riscv64,!s390x
 
 package bytealg
diff --git a/src/internal/bytealg/count_native.go b/src/internal/bytealg/count_native.go
index b1ff1d2..a19a6f8 100644
--- a/src/internal/bytealg/count_native.go
+++ b/src/internal/bytealg/count_native.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 || arm || arm64 || ppc64le || ppc64 || riscv64 || s390x
 // +build amd64 arm arm64 ppc64le ppc64 riscv64 s390x
 
 package bytealg
diff --git a/src/internal/bytealg/count_ppc64x.s b/src/internal/bytealg/count_ppc64x.s
index a64d7d7..94163cb 100644
--- a/src/internal/bytealg/count_ppc64x.s
+++ b/src/internal/bytealg/count_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64le || ppc64
 // +build ppc64le ppc64
 
 #include "go_asm.h"
diff --git a/src/internal/bytealg/equal_amd64.s b/src/internal/bytealg/equal_amd64.s
index c816409..6f12d2a 100644
--- a/src/internal/bytealg/equal_amd64.s
+++ b/src/internal/bytealg/equal_amd64.s
@@ -6,7 +6,21 @@
 #include "textflag.h"
 
 // memequal(a, b unsafe.Pointer, size uintptr) bool
-TEXT runtime·memequal(SB),NOSPLIT,$0-25
+TEXT runtime·memequal<ABIInternal>(SB),NOSPLIT,$0-25
+#ifdef GOEXPERIMENT_regabiargs
+	// AX = a    (want in SI)
+	// BX = b    (want in DI)
+	// CX = size (want in BX)
+	CMPQ	AX, BX
+	JNE	neq
+	MOVQ	$1, AX	// return 1
+	RET
+neq:
+	MOVQ	AX, SI
+	MOVQ	BX, DI
+	MOVQ	CX, BX
+	JMP	memeqbody<>(SB)
+#else
 	MOVQ	a+0(FP), SI
 	MOVQ	b+8(FP), DI
 	CMPQ	SI, DI
@@ -17,9 +31,24 @@
 eq:
 	MOVB	$1, ret+24(FP)
 	RET
+#endif
 
 // memequal_varlen(a, b unsafe.Pointer) bool
-TEXT runtime·memequal_varlen(SB),NOSPLIT,$0-17
+TEXT runtime·memequal_varlen<ABIInternal>(SB),NOSPLIT,$0-17
+#ifdef GOEXPERIMENT_regabiargs
+	// AX = a       (want in SI)
+	// BX = b       (want in DI)
+	// 8(DX) = size (want in BX)
+	CMPQ	AX, BX
+	JNE	neq
+	MOVQ	$1, AX	// return 1
+	RET
+neq:
+	MOVQ	AX, SI
+	MOVQ	BX, DI
+	MOVQ	8(DX), BX    // compiler stores size at offset 8 in the closure
+	JMP	memeqbody<>(SB)
+#else
 	MOVQ	a+0(FP), SI
 	MOVQ	b+8(FP), DI
 	CMPQ	SI, DI
@@ -30,11 +59,18 @@
 eq:
 	MOVB	$1, ret+16(FP)
 	RET
+#endif
 
-// a in SI
-// b in DI
-// count in BX
-// address of result byte in AX
+// Input:
+//   a in SI
+//   b in DI
+//   count in BX
+#ifndef GOEXPERIMENT_regabiargs
+//   address of result byte in AX
+#else
+// Output:
+//   result in AX
+#endif
 TEXT memeqbody<>(SB),NOSPLIT,$0-0
 	CMPQ	BX, $8
 	JB	small
@@ -68,7 +104,11 @@
 	SUBQ	$64, BX
 	CMPL	DX, $0xffff
 	JEQ	hugeloop
+#ifdef GOEXPERIMENT_regabiargs
+	XORQ	AX, AX	// return 0
+#else
 	MOVB	$0, (AX)
+#endif
 	RET
 
 	// 64 bytes at a time using ymm registers
@@ -89,7 +129,11 @@
 	CMPL	DX, $0xffffffff
 	JEQ	hugeloop_avx2
 	VZEROUPPER
+#ifdef GOEXPERIMENT_regabiargs
+	XORQ	AX, AX	// return 0
+#else
 	MOVB	$0, (AX)
+#endif
 	RET
 
 bigloop_avx2:
@@ -106,7 +150,11 @@
 	SUBQ	$8, BX
 	CMPQ	CX, DX
 	JEQ	bigloop
+#ifdef GOEXPERIMENT_regabiargs
+	XORQ	AX, AX	// return 0
+#else
 	MOVB	$0, (AX)
+#endif
 	RET
 
 	// remaining 0-8 bytes
@@ -114,7 +162,11 @@
 	MOVQ	-8(SI)(BX*1), CX
 	MOVQ	-8(DI)(BX*1), DX
 	CMPQ	CX, DX
+#ifdef GOEXPERIMENT_regabiargs
+	SETEQ	AX
+#else
 	SETEQ	(AX)
+#endif
 	RET
 
 small:
@@ -149,6 +201,10 @@
 	SUBQ	SI, DI
 	SHLQ	CX, DI
 equal:
+#ifdef GOEXPERIMENT_regabiargs
+	SETEQ	AX
+#else
 	SETEQ	(AX)
+#endif
 	RET
 
diff --git a/src/internal/bytealg/equal_mips64x.s b/src/internal/bytealg/equal_mips64x.s
index 641e3ff..c2f7d39 100644
--- a/src/internal/bytealg/equal_mips64x.s
+++ b/src/internal/bytealg/equal_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "go_asm.h"
diff --git a/src/internal/bytealg/equal_mipsx.s b/src/internal/bytealg/equal_mipsx.s
index 1cabc70..11e5549 100644
--- a/src/internal/bytealg/equal_mipsx.s
+++ b/src/internal/bytealg/equal_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "go_asm.h"
diff --git a/src/internal/bytealg/equal_ppc64x.s b/src/internal/bytealg/equal_ppc64x.s
index 18171ea..5f0fea5 100644
--- a/src/internal/bytealg/equal_ppc64x.s
+++ b/src/internal/bytealg/equal_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "go_asm.h"
diff --git a/src/internal/bytealg/index_generic.go b/src/internal/bytealg/index_generic.go
index 98e859f..0a6eb90 100644
--- a/src/internal/bytealg/index_generic.go
+++ b/src/internal/bytealg/index_generic.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64,!arm64,!s390x
+//go:build !amd64 && !arm64 && !s390x && !ppc64le && !ppc64
+// +build !amd64,!arm64,!s390x,!ppc64le,!ppc64
 
 package bytealg
 
diff --git a/src/internal/bytealg/index_native.go b/src/internal/bytealg/index_native.go
index fde4214..9547a5d 100644
--- a/src/internal/bytealg/index_native.go
+++ b/src/internal/bytealg/index_native.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build amd64 arm64 s390x
+//go:build amd64 || arm64 || s390x || ppc64le || ppc64
+// +build amd64 arm64 s390x ppc64le ppc64
 
 package bytealg
 
diff --git a/src/internal/bytealg/index_ppc64x.go b/src/internal/bytealg/index_ppc64x.go
new file mode 100644
index 0000000..c9b2b5a
--- /dev/null
+++ b/src/internal/bytealg/index_ppc64x.go
@@ -0,0 +1,28 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (aix || linux) && (ppc64 || ppc64le)
+// +build aix linux
+// +build ppc64 ppc64le
+
+package bytealg
+
+import "internal/cpu"
+
+const MaxBruteForce = 16
+
+var SupportsPower9 = cpu.PPC64.IsPOWER9
+
+func init() {
+	MaxLen = 32
+}
+
+// Cutover reports the number of failures of IndexByte we should tolerate
+// before switching over to Index.
+// n is the number of bytes processed so far.
+// See the bytes.Index implementation for details.
+func Cutover(n int) int {
+	// 1 error per 8 characters, plus a few slop to start.
+	return (n + 16) / 8
+}
diff --git a/src/internal/bytealg/index_ppc64x.s b/src/internal/bytealg/index_ppc64x.s
new file mode 100644
index 0000000..3ed9442
--- /dev/null
+++ b/src/internal/bytealg/index_ppc64x.s
@@ -0,0 +1,768 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This is an implementation based on the s390x
+// implementation.
+
+// Find a separator with 2 <= len <= 32 within a string.
+// Separators with lengths of 2, 3 or 4 are handled
+// specially.
+
+// This works on power8 and above. The loads and
+// compares are done in big endian order
+// since that allows the used of VCLZD, and allows
+// the same implementation to work on big and little
+// endian platforms with minimal conditional changes.
+
+// NOTE: There is a power9 implementation that
+// improves performance by 10-15% on little
+// endian for some of the benchmarks, but
+// work is still needed for a big endian
+// implementation on power9.
+
+//go:build ppc64 || ppc64le
+// +build ppc64 ppc64le
+
+#include "go_asm.h"
+#include "textflag.h"
+
+// Needed to swap LXVD2X loads to the correct
+// byte order to work on POWER8.
+
+#ifdef GOARCH_ppc64
+DATA byteswap<>+0(SB)/8, $0x0001020304050607
+DATA byteswap<>+8(SB)/8, $0x08090a0b0c0d0e0f
+#else
+DATA byteswap<>+0(SB)/8, $0x0706050403020100
+DATA byteswap<>+8(SB)/8, $0x0f0e0d0c0b0a0908
+#endif
+
+// Load bytes in big endian order. Address
+// alignment does not need checking.
+#define VLOADSWAP(base, index, vreg, vsreg) \
+	LXVD2X (base)(index), vsreg;  \
+	VPERM  vreg, vreg, SWAP, vreg
+
+GLOBL byteswap<>+0(SB), RODATA, $16
+
+TEXT ·Index(SB), NOSPLIT|NOFRAME, $0-56
+	MOVD a_base+0(FP), R3  // R3 = byte array pointer
+	MOVD a_len+8(FP), R4   // R4 = length
+	MOVD b_base+24(FP), R5 // R5 = separator pointer
+	MOVD b_len+32(FP), R6  // R6 = separator length
+	MOVD $ret+48(FP), R14  // R14 = &ret
+
+#ifdef GOARCH_ppc64le
+	MOVBZ internal∕cpu·PPC64+const_offsetPPC64HasPOWER9(SB), R7
+	CMP   R7, $1
+	BNE   power8
+	BR    indexbodyp9<>(SB)
+
+#endif
+power8:
+	BR indexbody<>(SB)
+
+TEXT ·IndexString(SB), NOSPLIT|NOFRAME, $0-40
+	MOVD a_base+0(FP), R3  // R3 = string
+	MOVD a_len+8(FP), R4   // R4 = length
+	MOVD b_base+16(FP), R5 // R5 = separator pointer
+	MOVD b_len+24(FP), R6  // R6 = separator length
+	MOVD $ret+32(FP), R14  // R14 = &ret
+
+#ifdef GOARCH_ppc64le
+	MOVBZ internal∕cpu·PPC64+const_offsetPPC64HasPOWER9(SB), R7
+	CMP   R7, $1
+	BNE   power8
+	BR    indexbody<>(SB)
+
+#endif
+power8:
+	BR indexbody<>(SB)
+
+	// s: string we are searching
+	// sep: string to search for
+	// R3=&s[0], R4=len(s)
+	// R5=&sep[0], R6=len(sep)
+	// R14=&ret (index where sep found)
+	// R7=working addr of string
+	// R16=index value 16
+	// R17=index value 17
+	// R18=index value 18
+	// R19=index value 1
+	// R26=LASTBYTE of string
+	// R27=LASTSTR last start byte to compare with sep
+	// R8, R9 scratch
+	// V0=sep left justified zero fill
+	// CR4=sep length >= 16
+
+#define SEPMASK V17
+#define LASTBYTE R26
+#define LASTSTR R27
+#define ONES V20
+#define SWAP V21
+#define V0_ VS32
+#define V1_ VS33
+#define V2_ VS34
+#define V3_ VS35
+#define V4_ VS36
+#define V5_ VS37
+#define V6_ VS38
+#define V7_ VS39
+#define V8_ VS40
+#define V9_ VS41
+#define SWAP_ VS53
+TEXT indexbody<>(SB), NOSPLIT|NOFRAME, $0
+	CMP      R6, R4                 // Compare lengths
+	BGT      notfound               // If sep len is > string, notfound
+	ADD      R4, R3, LASTBYTE       // find last byte addr
+	SUB      R6, LASTBYTE, LASTSTR  // LAST=&s[len(s)-len(sep)] (last valid start index)
+	CMP      R6, $0                 // Check sep len
+	BEQ      notfound               // sep len 0 -- not found
+	MOVD     R3, R7                 // Copy of string addr
+	MOVD     $16, R16               // Index value 16
+	MOVD     $17, R17               // Index value 17
+	MOVD     $18, R18               // Index value 18
+	MOVD     $1, R19                // Index value 1
+	MOVD     $byteswap<>+00(SB), R8
+	VSPLTISB $0xFF, ONES            // splat all 1s
+	LXVD2X   (R8)(R0), SWAP_        // Set up swap string
+
+	CMP    R6, $16, CR4        // CR4 for len(sep) >= 16
+	VOR    ONES, ONES, SEPMASK // Set up full SEPMASK
+	BGE    CR4, loadge16       // Load for len(sep) >= 16
+	SUB    R6, R16, R9         // 16-len of sep
+	SLD    $3, R9              // Set up for VSLO
+	MTVSRD R9, V9_             // Set up for VSLO
+	VSLDOI $8, V9, V9, V9      // Set up for VSLO
+	VSLO   ONES, V9, SEPMASK   // Mask for separator len(sep) < 16
+
+loadge16:
+	ANDCC $15, R5, R9 // Find byte offset of sep
+	ADD   R9, R6, R10 // Add sep len
+	CMP   R10, $16    // Check if sep len+offset > 16
+	BGE   sepcross16  // Sep crosses 16 byte boundary
+
+	RLDICR $0, R5, $59, R8 // Adjust addr to 16 byte container
+	VLOADSWAP(R8, R0, V0, V0_)// Load 16 bytes @R8 into V0
+	SLD    $3, R9          // Set up shift count for VSLO
+	MTVSRD R9, V8_         // Set up shift count for VSLO
+	VSLDOI $8, V8, V8, V8
+	VSLO   V0, V8, V0      // Shift by start byte
+
+	VAND V0, SEPMASK, V0 // Mask separator (< 16)
+	BR   index2plus
+
+sepcross16:
+	VLOADSWAP(R5, R0, V0, V0_) // Load 16 bytes @R5 into V0
+
+	VAND V0, SEPMASK, V0 // mask out separator
+	BLE  CR4, index2to16
+	BR   index17plus     // Handle sep > 16
+
+index2plus:
+	CMP      R6, $2       // Check length of sep
+	BNE      index3plus   // If not 2, check for 3
+	ADD      $16, R7, R9  // Check if next 16 bytes past last
+	CMP      R9, LASTBYTE // compare with last
+	BGE      index2to16   // 2 <= len(string) <= 16
+	MOVD     $0xff00, R21 // Mask for later
+	MTVSRD   R21, V25     // Move to Vreg
+	VSPLTH   $3, V25, V31 // Splat mask
+	VSPLTH   $0, V0, V1   // Splat 1st 2 bytes of sep
+	VSPLTISB $0, V10      // Clear V10
+
+	// First case: 2 byte separator
+	// V1: 2 byte separator splatted
+	// V2: 16 bytes at addr
+	// V4: 16 bytes at addr+1
+	// Compare 2 byte separator at start
+	// and at start+1. Use VSEL to combine
+	// those results to find the first
+	// matching start byte, returning
+	// that value when found. Loop as
+	// long as len(string) > 16
+index2loop2:
+	VLOADSWAP(R7, R19, V3, V3_) // Load 16 bytes @R7+1 into V3
+
+index2loop:
+	VLOADSWAP(R7, R0, V2, V2_) // Load 16 bytes @R7 into V2
+	VCMPEQUH V1, V2, V5        // Search for sep
+	VCMPEQUH V1, V3, V6        // Search for sep offset by 1
+	VSEL     V6, V5, V31, V7   // merge even and odd indices
+	VCLZD    V7, V18           // find index of first match
+	MFVSRD   V18, R25          // get first value
+	CMP      R25, $64          // Found if < 64
+	BLT      foundR25          // Return byte index where found
+	VSLDOI   $8, V18, V18, V18 // Adjust 2nd value
+	MFVSRD   V18, R25          // get second value
+	CMP      R25, $64          // Found if < 64
+	ADD      $64, R25          // Update byte offset
+	BLT      foundR25          // Return value
+	ADD      $16, R7           // R7+=16 Update string pointer
+	ADD      $17, R7, R9       // R9=F7+17 since loop unrolled
+	CMP      R9, LASTBYTE      // Compare addr+17 against last byte
+	BLT      index2loop2       // If < last, continue loop
+	CMP      R7, LASTBYTE      // Compare addr+16 against last byte
+	BLT      index2to16        // If < 16 handle specially
+	VLOADSWAP(R7, R0, V3, V3_) // Load 16 bytes @R7 into V3
+	VSLDOI   $1, V3, V10, V3   // Shift left by 1 byte
+	BR       index2loop
+
+index3plus:
+	CMP    R6, $3       // Check if sep == 3
+	BNE    index4plus   // If not check larger
+	ADD    $19, R7, R9  // Find bytes for use in this loop
+	CMP    R9, LASTBYTE // Compare against last byte
+	BGE    index2to16   // Remaining string 2<=len<=16
+	MOVD   $0xff00, R21 // Set up mask for upcoming loop
+	MTVSRD R21, V25     // Move mask to Vreg
+	VSPLTH $3, V25, V31 // Splat mask
+	VSPLTH $0, V0, V1   // Splat 1st two bytes of sep
+	VSPLTB $2, V0, V8   // Splat 3rd byte of sep
+
+	// Loop to process 3 byte separator.
+	// string[0:16] is in V2
+	// string[2:18] is in V3
+	// sep[0:2] splatted in V1
+	// sec[3] splatted in v8
+	// Load vectors at string, string+1
+	// and string+2. Compare string, string+1
+	// against first 2 bytes of separator
+	// splatted, and string+2 against 3rd
+	// byte splatted. Merge the results with
+	// VSEL to find the first byte of a match.
+
+	// Special handling for last 16 bytes if the
+	// string fits in 16 byte multiple.
+index3loop2:
+	MOVD     $2, R21          // Set up index for 2
+	VSPLTISB $0, V10          // Clear V10
+	VLOADSWAP(R7, R21, V3, V3_)// Load 16 bytes @R7+2 into V3
+	VSLDOI   $14, V3, V10, V3 // Left justify next 2 bytes
+
+index3loop:
+	VLOADSWAP(R7, R0, V2, V2_) // Load with correct order
+	VSLDOI   $1, V2, V3, V4    // string[1:17]
+	VSLDOI   $2, V2, V3, V9    // string[2:18]
+	VCMPEQUH V1, V2, V5        // compare hw even indices
+	VCMPEQUH V1, V4, V6        // compare hw odd indices
+	VCMPEQUB V8, V9, V10       // compare 3rd to last byte
+	VSEL     V6, V5, V31, V7   // Find 1st matching byte using mask
+	VAND     V7, V10, V7       // AND matched bytes with matched 3rd byte
+	VCLZD    V7, V18           // Find first nonzero indexes
+	MFVSRD   V18, R25          // Move 1st doubleword
+	CMP      R25, $64          // If < 64 found
+	BLT      foundR25          // Return matching index
+	VSLDOI   $8, V18, V18, V18 // Move value
+	MFVSRD   V18, R25          // Move 2nd doubleword
+	CMP      R25, $64          // If < 64 found
+	ADD      $64, R25          // Update byte index
+	BLT      foundR25          // Return matching index
+	ADD      $16, R7           // R7+=16 string ptr
+	ADD      $19, R7, R9       // Number of string bytes for loop
+	CMP      R9, LASTBYTE      // Compare against last byte of string
+	BLT      index3loop2       // If within, continue this loop
+	CMP      R7, LASTSTR       // Compare against last start byte
+	BLT      index2to16        // Process remainder
+	VSPLTISB $0, V3            // Special case for last 16 bytes
+	BR       index3loop        // Continue this loop
+
+	// Loop to process 4 byte separator
+	// string[0:16] in V2
+	// string[3:16] in V3
+	// sep[0:4] splatted in V1
+	// Set up vectors with strings at offsets
+	// 0, 1, 2, 3 and compare against the 4 byte
+	// separator also splatted. Use VSEL with the
+	// compare results to find the first byte where
+	// a separator match is found.
+index4plus:
+	CMP  R6, $4       // Check if 4 byte separator
+	BNE  index5plus   // If not next higher
+	ADD  $20, R7, R9  // Check string size to load
+	CMP  R9, LASTBYTE // Verify string length
+	BGE  index2to16   // If not large enough, process remaining
+	MOVD $2, R15      // Set up index
+
+	// Set up masks for use with VSEL
+	MOVD   $0xff, R21        // Set up mask 0xff000000ff000000...
+	SLD    $24, R21
+	MTVSRD R21, V10
+	VSPLTW $1, V10, V29
+	VSLDOI $2, V29, V29, V30 // Mask 0x0000ff000000ff00...
+	MOVD   $0xffff, R21
+	SLD    $16, R21
+	MTVSRD R21, V10
+	VSPLTW $1, V10, V31      // Mask 0xffff0000ffff0000...
+	VSPLTW $0, V0, V1        // Splat 1st word of separator
+
+index4loop:
+	VLOADSWAP(R7, R0, V2, V2_) // Load 16 bytes @R7 into V2
+
+next4:
+	VSPLTISB $0, V10            // Clear
+	MOVD     $3, R9             // Number of bytes beyond 16
+	VLOADSWAP(R7, R9, V3, V3_)  // Load 16 bytes @R7+3 into V3
+	VSLDOI   $13, V3, V10, V3   // Shift left last 3 bytes
+	VSLDOI   $1, V2, V3, V4     // V4=(V2:V3)<<1
+	VSLDOI   $2, V2, V3, V9     // V9=(V2:V3)<<2
+	VSLDOI   $3, V2, V3, V10    // V10=(V2:v3)<<3
+	VCMPEQUW V1, V2, V5         // compare index 0, 4, ... with sep
+	VCMPEQUW V1, V4, V6         // compare index 1, 5, ... with sep
+	VCMPEQUW V1, V9, V11        // compare index 2, 6, ... with sep
+	VCMPEQUW V1, V10, V12       // compare index 3, 7, ... with sep
+	VSEL     V6, V5, V29, V13   // merge index 0, 1, 4, 5, using mask
+	VSEL     V12, V11, V30, V14 // merge index 2, 3, 6, 7, using mask
+	VSEL     V14, V13, V31, V7  // final merge
+	VCLZD    V7, V18            // Find first index for each half
+	MFVSRD   V18, R25           // Isolate value
+	CMP      R25, $64           // If < 64, found
+	BLT      foundR25           // Return found index
+	VSLDOI   $8, V18, V18, V18  // Move for MFVSRD
+	MFVSRD   V18, R25           // Isolate other value
+	CMP      R25, $64           // If < 64, found
+	ADD      $64, R25           // Update index for high doubleword
+	BLT      foundR25           // Return found index
+	ADD      $16, R7            // R7+=16 for next string
+	ADD      $20, R7, R9        // R+20 for all bytes to load
+	CMP      R9, LASTBYTE       // Past end? Maybe check for extra?
+	BLT      index4loop         // If not, continue loop
+	CMP      R7, LASTSTR        // Check remainder
+	BLE      index2to16         // Process remainder
+	BR       notfound           // Not found
+
+index5plus:
+	CMP R6, $16     // Check for sep > 16
+	BGT index17plus // Handle large sep
+
+	// Assumption is that the separator is smaller than the string at this point
+index2to16:
+	CMP R7, LASTSTR // Compare last start byte
+	BGT notfound    // last takes len(sep) into account
+
+	ADD $16, R7, R9    // Check for last byte of string
+	CMP R9, LASTBYTE
+	BGT index2to16tail
+
+	// At least 16 bytes of string left
+	// Mask the number of bytes in sep
+index2to16loop:
+	VLOADSWAP(R7, R0, V1, V1_) // Load 16 bytes @R7 into V1
+
+compare:
+	VAND       V1, SEPMASK, V2 // Mask out sep size
+	VCMPEQUBCC V0, V2, V3      // Compare masked string
+	BLT        CR6, found      // All equal
+	ADD        $1, R7          // Update ptr to next byte
+	CMP        R7, LASTSTR     // Still less than last start byte
+	BGT        notfound        // Not found
+	ADD        $16, R7, R9     // Verify remaining bytes
+	CMP        R9, LASTBYTE    // At least 16
+	BLT        index2to16loop  // Try again
+
+	// Less than 16 bytes remaining in string
+	// Separator >= 2
+index2to16tail:
+	ADD   R3, R4, R9     // End of string
+	SUB   R7, R9, R9     // Number of bytes left
+	ANDCC $15, R7, R10   // 16 byte offset
+	ADD   R10, R9, R11   // offset + len
+	CMP   R11, $16       // >= 16?
+	BLE   short          // Does not cross 16 bytes
+	VLOADSWAP(R7, R0, V1, V1_)// Load 16 bytes @R7 into V1
+	BR    index2to16next // Continue on
+
+short:
+	RLDICR   $0, R7, $59, R9 // Adjust addr to 16 byte container
+	VLOADSWAP(R9, R0, V1, V1_)// Load 16 bytes @R9 into V1
+	SLD      $3, R10         // Set up shift
+	MTVSRD   R10, V8_        // Set up shift
+	VSLDOI   $8, V8, V8, V8
+	VSLO     V1, V8, V1      // Shift by start byte
+	VSPLTISB $0, V25         // Clear for later use
+
+index2to16next:
+	VAND       V1, SEPMASK, V2 // Just compare size of sep
+	VCMPEQUBCC V0, V2, V3      // Compare sep and partial string
+	BLT        CR6, found      // Found
+	ADD        $1, R7          // Not found, try next partial string
+	CMP        R7, LASTSTR     // Check for end of string
+	BGT        notfound        // If at end, then not found
+	VSLDOI     $1, V1, V25, V1 // Shift string left by 1 byte
+	BR         index2to16next  // Check the next partial string
+
+index17plus:
+	CMP      R6, $32      // Check if 17 < len(sep) <= 32
+	BGT      index33plus
+	SUB      $16, R6, R9  // Extra > 16
+	SLD      $56, R9, R10 // Shift to use in VSLO
+	MTVSRD   R10, V9_     // Set up for VSLO
+	VLOADSWAP(R5, R9, V1, V1_)// Load 16 bytes @R5+R9 into V1
+	VSLO     V1, V9, V1   // Shift left
+	VSPLTISB $0xff, V7    // Splat 1s
+	VSPLTISB $0, V27      // Splat 0
+
+index17to32loop:
+	VLOADSWAP(R7, R0, V2, V2_) // Load 16 bytes @R7 into V2
+
+next17:
+	VLOADSWAP(R7, R9, V3, V3_) // Load 16 bytes @R7+R9 into V3
+	VSLO       V3, V9, V3      // Shift left
+	VCMPEQUB   V0, V2, V4      // Compare first 16 bytes
+	VCMPEQUB   V1, V3, V5      // Compare extra over 16 bytes
+	VAND       V4, V5, V6      // Check if both equal
+	VCMPEQUBCC V6, V7, V8      // All equal?
+	BLT        CR6, found      // Yes
+	ADD        $1, R7          // On to next byte
+	CMP        R7, LASTSTR     // Check if last start byte
+	BGT        notfound        // If too high, not found
+	BR         index17to32loop // Continue
+
+notfound:
+	MOVD $-1, R8   // Return -1 if not found
+	MOVD R8, (R14)
+	RET
+
+index33plus:
+	MOVD $0, (R0) // Case not implemented
+	RET           // Crash before return
+
+foundR25:
+	SRD  $3, R25   // Convert from bits to bytes
+	ADD  R25, R7   // Add to current string address
+	SUB  R3, R7    // Subtract from start of string
+	MOVD R7, (R14) // Return byte where found
+	RET
+
+found:
+	SUB  R3, R7    // Return byte where found
+	MOVD R7, (R14)
+	RET
+
+TEXT indexbodyp9<>(SB), NOSPLIT|NOFRAME, $0
+	CMP      R6, R4                // Compare lengths
+	BGT      notfound              // If sep len is > string, notfound
+	ADD      R4, R3, LASTBYTE      // find last byte addr
+	SUB      R6, LASTBYTE, LASTSTR // LAST=&s[len(s)-len(sep)] (last valid start index)
+	CMP      R6, $0                // Check sep len
+	BEQ      notfound              // sep len 0 -- not found
+	MOVD     R3, R7                // Copy of string addr
+	MOVD     $16, R16              // Index value 16
+	MOVD     $17, R17              // Index value 17
+	MOVD     $18, R18              // Index value 18
+	MOVD     $1, R19               // Index value 1
+	VSPLTISB $0xFF, ONES           // splat all 1s
+
+	CMP    R6, $16, CR4        // CR4 for len(sep) >= 16
+	VOR    ONES, ONES, SEPMASK // Set up full SEPMASK
+	BGE    CR4, loadge16       // Load for len(sep) >= 16
+	SUB    R6, R16, R9         // 16-len of sep
+	SLD    $3, R9              // Set up for VSLO
+	MTVSRD R9, V9_             // Set up for VSLO
+	VSLDOI $8, V9, V9, V9      // Set up for VSLO
+	VSLO   ONES, V9, SEPMASK   // Mask for separator len(sep) < 16
+
+loadge16:
+	ANDCC $15, R5, R9 // Find byte offset of sep
+	ADD   R9, R6, R10 // Add sep len
+	CMP   R10, $16    // Check if sep len+offset > 16
+	BGE   sepcross16  // Sep crosses 16 byte boundary
+
+	RLDICR  $0, R5, $59, R8 // Adjust addr to 16 byte container
+	LXVB16X (R8)(R0), V0_   // Load 16 bytes @R8 into V0
+	SLD     $3, R9          // Set up shift count for VSLO
+	MTVSRD  R9, V8_         // Set up shift count for VSLO
+	VSLDOI  $8, V8, V8, V8
+	VSLO    V0, V8, V0      // Shift by start byte
+
+	VAND V0, SEPMASK, V0 // Mask separator (< 16)
+	BR   index2plus
+
+sepcross16:
+	LXVB16X (R5)(R0), V0_ // Load 16 bytes @R5 into V0
+
+	VAND V0, SEPMASK, V0 // mask out separator
+	BLE  CR4, index2to16
+	BR   index17plus     // Handle sep > 16
+
+index2plus:
+	CMP      R6, $2       // Check length of sep
+	BNE      index3plus   // If not 2, check for 3
+	ADD      $16, R7, R9  // Check if next 16 bytes past last
+	CMP      R9, LASTBYTE // compare with last
+	BGE      index2to16   // 2 <= len(string) <= 16
+	MOVD     $0xff00, R21 // Mask for later
+	MTVSRD   R21, V25     // Move to Vreg
+	VSPLTH   $3, V25, V31 // Splat mask
+	VSPLTH   $0, V0, V1   // Splat 1st 2 bytes of sep
+	VSPLTISB $0, V10      // Clear V10
+
+	// First case: 2 byte separator
+	// V1: 2 byte separator splatted
+	// V2: 16 bytes at addr
+	// V4: 16 bytes at addr+1
+	// Compare 2 byte separator at start
+	// and at start+1. Use VSEL to combine
+	// those results to find the first
+	// matching start byte, returning
+	// that value when found. Loop as
+	// long as len(string) > 16
+index2loop2:
+	LXVB16X (R7)(R19), V3_ // Load 16 bytes @R7+1 into V3
+
+index2loop:
+	LXVB16X  (R7)(R0), V2_   // Load 16 bytes @R7 into V2
+	VCMPEQUH V1, V2, V5      // Search for sep
+	VCMPEQUH V1, V3, V6      // Search for sep offset by 1
+	VSEL     V6, V5, V31, V7 // merge even and odd indices
+	VCLZD    V7, V18         // find index of first match
+	MFVSRD   V18, R25        // get first value
+	CMP      R25, $64        // Found if < 64
+	BLT      foundR25        // Return byte index where found
+
+	MFVSRLD V18, R25        // get second value
+	CMP     R25, $64        // Found if < 64
+	ADD     $64, R25        // Update byte offset
+	BLT     foundR25        // Return value
+	ADD     $16, R7         // R7+=16 Update string pointer
+	ADD     $17, R7, R9     // R9=F7+17 since loop unrolled
+	CMP     R9, LASTBYTE    // Compare addr+17 against last byte
+	BLT     index2loop2     // If < last, continue loop
+	CMP     R7, LASTBYTE    // Compare addr+16 against last byte
+	BLT     index2to16      // If < 16 handle specially
+	LXVB16X (R7)(R0), V3_   // Load 16 bytes @R7 into V3
+	VSLDOI  $1, V3, V10, V3 // Shift left by 1 byte
+	BR      index2loop
+
+index3plus:
+	CMP    R6, $3       // Check if sep == 3
+	BNE    index4plus   // If not check larger
+	ADD    $19, R7, R9  // Find bytes for use in this loop
+	CMP    R9, LASTBYTE // Compare against last byte
+	BGE    index2to16   // Remaining string 2<=len<=16
+	MOVD   $0xff00, R21 // Set up mask for upcoming loop
+	MTVSRD R21, V25     // Move mask to Vreg
+	VSPLTH $3, V25, V31 // Splat mask
+	VSPLTH $0, V0, V1   // Splat 1st two bytes of sep
+	VSPLTB $2, V0, V8   // Splat 3rd byte of sep
+
+	// Loop to process 3 byte separator.
+	// string[0:16] is in V2
+	// string[2:18] is in V3
+	// sep[0:2] splatted in V1
+	// sec[3] splatted in v8
+	// Load vectors at string, string+1
+	// and string+2. Compare string, string+1
+	// against first 2 bytes of separator
+	// splatted, and string+2 against 3rd
+	// byte splatted. Merge the results with
+	// VSEL to find the first byte of a match.
+
+	// Special handling for last 16 bytes if the
+	// string fits in 16 byte multiple.
+index3loop2:
+	MOVD     $2, R21          // Set up index for 2
+	VSPLTISB $0, V10          // Clear V10
+	LXVB16X  (R7)(R21), V3_   // Load 16 bytes @R7+2 into V3
+	VSLDOI   $14, V3, V10, V3 // Left justify next 2 bytes
+
+index3loop:
+	LXVB16X  (R7)(R0), V2_   // Load 16 bytes @R7
+	VSLDOI   $1, V2, V3, V4  // string[1:17]
+	VSLDOI   $2, V2, V3, V9  // string[2:18]
+	VCMPEQUH V1, V2, V5      // compare hw even indices
+	VCMPEQUH V1, V4, V6      // compare hw odd indices
+	VCMPEQUB V8, V9, V10     // compare 3rd to last byte
+	VSEL     V6, V5, V31, V7 // Find 1st matching byte using mask
+	VAND     V7, V10, V7     // AND matched bytes with matched 3rd byte
+	VCLZD    V7, V18         // Find first nonzero indexes
+	MFVSRD   V18, R25        // Move 1st doubleword
+	CMP      R25, $64        // If < 64 found
+	BLT      foundR25        // Return matching index
+
+	MFVSRLD  V18, R25     // Move 2nd doubleword
+	CMP      R25, $64     // If < 64 found
+	ADD      $64, R25     // Update byte index
+	BLT      foundR25     // Return matching index
+	ADD      $16, R7      // R7+=16 string ptr
+	ADD      $19, R7, R9  // Number of string bytes for loop
+	CMP      R9, LASTBYTE // Compare against last byte of string
+	BLT      index3loop2  // If within, continue this loop
+	CMP      R7, LASTSTR  // Compare against last start byte
+	BLT      index2to16   // Process remainder
+	VSPLTISB $0, V3       // Special case for last 16 bytes
+	BR       index3loop   // Continue this loop
+
+	// Loop to process 4 byte separator
+	// string[0:16] in V2
+	// string[3:16] in V3
+	// sep[0:4] splatted in V1
+	// Set up vectors with strings at offsets
+	// 0, 1, 2, 3 and compare against the 4 byte
+	// separator also splatted. Use VSEL with the
+	// compare results to find the first byte where
+	// a separator match is found.
+index4plus:
+	CMP  R6, $4       // Check if 4 byte separator
+	BNE  index5plus   // If not next higher
+	ADD  $20, R7, R9  // Check string size to load
+	CMP  R9, LASTBYTE // Verify string length
+	BGE  index2to16   // If not large enough, process remaining
+	MOVD $2, R15      // Set up index
+
+	// Set up masks for use with VSEL
+	MOVD    $0xff, R21 // Set up mask 0xff000000ff000000...
+	SLD     $24, R21
+	MTVSRWS R21, V29
+
+	VSLDOI  $2, V29, V29, V30 // Mask 0x0000ff000000ff00...
+	MOVD    $0xffff, R21
+	SLD     $16, R21
+	MTVSRWS R21, V31
+
+	VSPLTW $0, V0, V1 // Splat 1st word of separator
+
+index4loop:
+	LXVB16X (R7)(R0), V2_ // Load 16 bytes @R7 into V2
+
+next4:
+	VSPLTISB $0, V10            // Clear
+	MOVD     $3, R9             // Number of bytes beyond 16
+	LXVB16X  (R7)(R9), V3_      // Load 16 bytes @R7 into V2
+	VSLDOI   $13, V3, V10, V3   // Shift left last 3 bytes
+	VSLDOI   $1, V2, V3, V4     // V4=(V2:V3)<<1
+	VSLDOI   $2, V2, V3, V9     // V9=(V2:V3)<<2
+	VSLDOI   $3, V2, V3, V10    // V10=(V2:v3)<<3
+	VCMPEQUW V1, V2, V5         // compare index 0, 4, ... with sep
+	VCMPEQUW V1, V4, V6         // compare index 1, 5, ... with sep
+	VCMPEQUW V1, V9, V11        // compare index 2, 6, ... with sep
+	VCMPEQUW V1, V10, V12       // compare index 3, 7, ... with sep
+	VSEL     V6, V5, V29, V13   // merge index 0, 1, 4, 5, using mask
+	VSEL     V12, V11, V30, V14 // merge index 2, 3, 6, 7, using mask
+	VSEL     V14, V13, V31, V7  // final merge
+	VCLZD    V7, V18            // Find first index for each half
+	MFVSRD   V18, R25           // Isolate value
+	CMP      R25, $64           // If < 64, found
+	BLT      foundR25           // Return found index
+
+	MFVSRLD V18, R25     // Isolate other value
+	CMP     R25, $64     // If < 64, found
+	ADD     $64, R25     // Update index for high doubleword
+	BLT     foundR25     // Return found index
+	ADD     $16, R7      // R7+=16 for next string
+	ADD     $20, R7, R9  // R+20 for all bytes to load
+	CMP     R9, LASTBYTE // Past end? Maybe check for extra?
+	BLT     index4loop   // If not, continue loop
+	CMP     R7, LASTSTR  // Check remainder
+	BLE     index2to16   // Process remainder
+	BR      notfound     // Not found
+
+index5plus:
+	CMP R6, $16     // Check for sep > 16
+	BGT index17plus // Handle large sep
+
+	// Assumption is that the separator is smaller than the string at this point
+index2to16:
+	CMP R7, LASTSTR // Compare last start byte
+	BGT notfound    // last takes len(sep) into account
+
+	ADD $16, R7, R9    // Check for last byte of string
+	CMP R9, LASTBYTE
+	BGT index2to16tail
+
+	// At least 16 bytes of string left
+	// Mask the number of bytes in sep
+index2to16loop:
+	LXVB16X (R7)(R0), V1_ // Load 16 bytes @R7 into V1
+
+compare:
+	VAND       V1, SEPMASK, V2 // Mask out sep size
+	VCMPEQUBCC V0, V2, V3      // Compare masked string
+	BLT        CR6, found      // All equal
+	ADD        $1, R7          // Update ptr to next byte
+	CMP        R7, LASTSTR     // Still less than last start byte
+	BGT        notfound        // Not found
+	ADD        $16, R7, R9     // Verify remaining bytes
+	CMP        R9, LASTBYTE    // At least 16
+	BLT        index2to16loop  // Try again
+
+	// Less than 16 bytes remaining in string
+	// Separator >= 2
+index2to16tail:
+	ADD     R3, R4, R9     // End of string
+	SUB     R7, R9, R9     // Number of bytes left
+	ANDCC   $15, R7, R10   // 16 byte offset
+	ADD     R10, R9, R11   // offset + len
+	CMP     R11, $16       // >= 16?
+	BLE     short          // Does not cross 16 bytes
+	LXVB16X (R7)(R0), V1_  // Load 16 bytes @R7 into V1
+	BR      index2to16next // Continue on
+
+short:
+	RLDICR   $0, R7, $59, R9 // Adjust addr to 16 byte container
+	LXVB16X  (R9)(R0), V1_   // Load 16 bytes @R9 into V1
+	SLD      $3, R10         // Set up shift
+	MTVSRD   R10, V8_        // Set up shift
+	VSLDOI   $8, V8, V8, V8
+	VSLO     V1, V8, V1      // Shift by start byte
+	VSPLTISB $0, V25         // Clear for later use
+
+index2to16next:
+	VAND       V1, SEPMASK, V2 // Just compare size of sep
+	VCMPEQUBCC V0, V2, V3      // Compare sep and partial string
+	BLT        CR6, found      // Found
+	ADD        $1, R7          // Not found, try next partial string
+	CMP        R7, LASTSTR     // Check for end of string
+	BGT        notfound        // If at end, then not found
+	VSLDOI     $1, V1, V25, V1 // Shift string left by 1 byte
+	BR         index2to16next  // Check the next partial string
+
+index17plus:
+	CMP      R6, $32       // Check if 17 < len(sep) <= 32
+	BGT      index33plus
+	SUB      $16, R6, R9   // Extra > 16
+	SLD      $56, R9, R10  // Shift to use in VSLO
+	MTVSRD   R10, V9_      // Set up for VSLO
+	LXVB16X  (R5)(R9), V1_ // Load 16 bytes @R5+R9 into V1
+	VSLO     V1, V9, V1    // Shift left
+	VSPLTISB $0xff, V7     // Splat 1s
+	VSPLTISB $0, V27       // Splat 0
+
+index17to32loop:
+	LXVB16X (R7)(R0), V2_ // Load 16 bytes @R7 into V2
+
+next17:
+	LXVB16X    (R7)(R9), V3_   // Load 16 bytes @R7+R9 into V3
+	VSLO       V3, V9, V3      // Shift left
+	VCMPEQUB   V0, V2, V4      // Compare first 16 bytes
+	VCMPEQUB   V1, V3, V5      // Compare extra over 16 bytes
+	VAND       V4, V5, V6      // Check if both equal
+	VCMPEQUBCC V6, V7, V8      // All equal?
+	BLT        CR6, found      // Yes
+	ADD        $1, R7          // On to next byte
+	CMP        R7, LASTSTR     // Check if last start byte
+	BGT        notfound        // If too high, not found
+	BR         index17to32loop // Continue
+
+notfound:
+	MOVD $-1, R8   // Return -1 if not found
+	MOVD R8, (R14)
+	RET
+
+index33plus:
+	MOVD $0, (R0) // Case not implemented
+	RET           // Crash before return
+
+foundR25:
+	SRD  $3, R25   // Convert from bits to bytes
+	ADD  R25, R7   // Add to current string address
+	SUB  R3, R7    // Subtract from start of string
+	MOVD R7, (R14) // Return byte where found
+	RET
+
+found:
+	SUB  R3, R7    // Return byte where found
+	MOVD R7, (R14)
+	RET
+
diff --git a/src/internal/bytealg/indexbyte_generic.go b/src/internal/bytealg/indexbyte_generic.go
index 0b012a8..6ef639f 100644
--- a/src/internal/bytealg/indexbyte_generic.go
+++ b/src/internal/bytealg/indexbyte_generic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !386 && !amd64 && !s390x && !arm && !arm64 && !ppc64 && !ppc64le && !mips && !mipsle && !mips64 && !mips64le && !riscv64 && !wasm
 // +build !386,!amd64,!s390x,!arm,!arm64,!ppc64,!ppc64le,!mips,!mipsle,!mips64,!mips64le,!riscv64,!wasm
 
 package bytealg
diff --git a/src/internal/bytealg/indexbyte_mips64x.s b/src/internal/bytealg/indexbyte_mips64x.s
index 6ebf0de..0f377f5 100644
--- a/src/internal/bytealg/indexbyte_mips64x.s
+++ b/src/internal/bytealg/indexbyte_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "go_asm.h"
diff --git a/src/internal/bytealg/indexbyte_mipsx.s b/src/internal/bytealg/indexbyte_mipsx.s
index e44440b..bed015b 100644
--- a/src/internal/bytealg/indexbyte_mipsx.s
+++ b/src/internal/bytealg/indexbyte_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "go_asm.h"
diff --git a/src/internal/bytealg/indexbyte_native.go b/src/internal/bytealg/indexbyte_native.go
index f96c5be..965f38f 100644
--- a/src/internal/bytealg/indexbyte_native.go
+++ b/src/internal/bytealg/indexbyte_native.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 || amd64 || s390x || arm || arm64 || ppc64 || ppc64le || mips || mipsle || mips64 || mips64le || riscv64 || wasm
 // +build 386 amd64 s390x arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le riscv64 wasm
 
 package bytealg
diff --git a/src/internal/bytealg/indexbyte_ppc64x.s b/src/internal/bytealg/indexbyte_ppc64x.s
index 6e14e80..8e13c5a 100644
--- a/src/internal/bytealg/indexbyte_ppc64x.s
+++ b/src/internal/bytealg/indexbyte_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "go_asm.h"
diff --git a/src/internal/cfg/cfg.go b/src/internal/cfg/cfg.go
index 5530213..815994b 100644
--- a/src/internal/cfg/cfg.go
+++ b/src/internal/cfg/cfg.go
@@ -39,6 +39,7 @@
 	GOCACHE
 	GOENV
 	GOEXE
+	GOEXPERIMENT
 	GOFLAGS
 	GOGCCFLAGS
 	GOHOSTARCH
diff --git a/src/internal/cpu/cpu_arm64_android.go b/src/internal/cpu/cpu_arm64_android.go
index 3c9e57c..ac6eee5 100644
--- a/src/internal/cpu/cpu_arm64_android.go
+++ b/src/internal/cpu/cpu_arm64_android.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm64
 // +build arm64
 
 package cpu
diff --git a/src/internal/cpu/cpu_arm64_darwin.go b/src/internal/cpu/cpu_arm64_darwin.go
index e094b97..ce1b250 100644
--- a/src/internal/cpu/cpu_arm64_darwin.go
+++ b/src/internal/cpu/cpu_arm64_darwin.go
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build arm64
-// +build darwin
-// +build !ios
+//go:build arm64 && darwin && !ios
+// +build arm64,darwin,!ios
 
 package cpu
 
diff --git a/src/internal/cpu/cpu_arm64_freebsd.go b/src/internal/cpu/cpu_arm64_freebsd.go
index 9de2005..8c48137 100644
--- a/src/internal/cpu/cpu_arm64_freebsd.go
+++ b/src/internal/cpu/cpu_arm64_freebsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm64
 // +build arm64
 
 package cpu
diff --git a/src/internal/cpu/cpu_arm64_hwcap.go b/src/internal/cpu/cpu_arm64_hwcap.go
index fdaf43e..8ac04fd 100644
--- a/src/internal/cpu/cpu_arm64_hwcap.go
+++ b/src/internal/cpu/cpu_arm64_hwcap.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build arm64
-// +build linux
+//go:build arm64 && linux
+// +build arm64,linux
 
 package cpu
 
diff --git a/src/internal/cpu/cpu_arm64_linux.go b/src/internal/cpu/cpu_arm64_linux.go
index 2f7411f..c3a3f9a 100644
--- a/src/internal/cpu/cpu_arm64_linux.go
+++ b/src/internal/cpu/cpu_arm64_linux.go
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build arm64
-// +build linux
-// +build !android
+//go:build arm64 && linux && !android
+// +build arm64,linux,!android
 
 package cpu
 
diff --git a/src/internal/cpu/cpu_arm64_other.go b/src/internal/cpu/cpu_arm64_other.go
index f191db2..e8b5d52 100644
--- a/src/internal/cpu/cpu_arm64_other.go
+++ b/src/internal/cpu/cpu_arm64_other.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm64 && !linux && !freebsd && !android && (!darwin || ios)
 // +build arm64
 // +build !linux
 // +build !freebsd
diff --git a/src/internal/cpu/cpu_mips64x.go b/src/internal/cpu/cpu_mips64x.go
index 0c4794a..d2f9d44 100644
--- a/src/internal/cpu/cpu_mips64x.go
+++ b/src/internal/cpu/cpu_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 package cpu
diff --git a/src/internal/cpu/cpu_no_name.go b/src/internal/cpu/cpu_no_name.go
index ce1c37a..8d563b5 100644
--- a/src/internal/cpu/cpu_no_name.go
+++ b/src/internal/cpu/cpu_no_name.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !386
-// +build !amd64
+//go:build !386 && !amd64
+// +build !386,!amd64
 
 package cpu
 
diff --git a/src/internal/cpu/cpu_ppc64x.go b/src/internal/cpu/cpu_ppc64x.go
index beb1765..2e7fd3e 100644
--- a/src/internal/cpu/cpu_ppc64x.go
+++ b/src/internal/cpu/cpu_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 package cpu
diff --git a/src/internal/cpu/cpu_ppc64x_aix.go b/src/internal/cpu/cpu_ppc64x_aix.go
index b840b82..3d17a9c 100644
--- a/src/internal/cpu/cpu_ppc64x_aix.go
+++ b/src/internal/cpu/cpu_ppc64x_aix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 package cpu
diff --git a/src/internal/cpu/cpu_ppc64x_linux.go b/src/internal/cpu/cpu_ppc64x_linux.go
index 73b1914..b7c7345 100644
--- a/src/internal/cpu/cpu_ppc64x_linux.go
+++ b/src/internal/cpu/cpu_ppc64x_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 package cpu
diff --git a/src/internal/cpu/cpu_x86.go b/src/internal/cpu/cpu_x86.go
index ba6bf69..fd1217a 100644
--- a/src/internal/cpu/cpu_x86.go
+++ b/src/internal/cpu/cpu_x86.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 || amd64
 // +build 386 amd64
 
 package cpu
diff --git a/src/internal/cpu/cpu_x86.s b/src/internal/cpu/cpu_x86.s
index 93c712d..0df5da1 100644
--- a/src/internal/cpu/cpu_x86.s
+++ b/src/internal/cpu/cpu_x86.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 || amd64
 // +build 386 amd64
 
 #include "textflag.h"
diff --git a/src/internal/cpu/cpu_x86_test.go b/src/internal/cpu/cpu_x86_test.go
index 61db93b..e3e16cc 100644
--- a/src/internal/cpu/cpu_x86_test.go
+++ b/src/internal/cpu/cpu_x86_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 || amd64
 // +build 386 amd64
 
 package cpu_test
diff --git a/src/internal/execabs/execabs_test.go b/src/internal/execabs/execabs_test.go
index b714585..97a3f39 100644
--- a/src/internal/execabs/execabs_test.go
+++ b/src/internal/execabs/execabs_test.go
@@ -8,7 +8,6 @@
 	"context"
 	"fmt"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -42,8 +41,8 @@
 		if runtime.GOOS == "windows" {
 			executable += ".exe"
 		}
-		if err := ioutil.WriteFile(filepath.Join(tmpDir, executable), []byte{1, 2, 3}, 0111); err != nil {
-			t.Fatalf("ioutil.WriteFile failed: %s", err)
+		if err := os.WriteFile(filepath.Join(tmpDir, executable), []byte{1, 2, 3}, 0111); err != nil {
+			t.Fatalf("os.WriteFile failed: %s", err)
 		}
 		cwd, err := os.Getwd()
 		if err != nil {
@@ -77,8 +76,8 @@
 	if runtime.GOOS == "windows" {
 		executable += ".exe"
 	}
-	if err := ioutil.WriteFile(filepath.Join(tmpDir, executable), []byte{1, 2, 3}, 0111); err != nil {
-		t.Fatalf("ioutil.WriteFile failed: %s", err)
+	if err := os.WriteFile(filepath.Join(tmpDir, executable), []byte{1, 2, 3}, 0111); err != nil {
+		t.Fatalf("os.WriteFile failed: %s", err)
 	}
 	cwd, err := os.Getwd()
 	if err != nil {
diff --git a/src/internal/goexperiment/exp_fieldtrack_off.go b/src/internal/goexperiment/exp_fieldtrack_off.go
new file mode 100644
index 0000000..e5e1326
--- /dev/null
+++ b/src/internal/goexperiment/exp_fieldtrack_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.fieldtrack
+// +build !goexperiment.fieldtrack
+
+package goexperiment
+
+const FieldTrack = false
+const FieldTrackInt = 0
diff --git a/src/internal/goexperiment/exp_fieldtrack_on.go b/src/internal/goexperiment/exp_fieldtrack_on.go
new file mode 100644
index 0000000..0d8c447
--- /dev/null
+++ b/src/internal/goexperiment/exp_fieldtrack_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.fieldtrack
+// +build goexperiment.fieldtrack
+
+package goexperiment
+
+const FieldTrack = true
+const FieldTrackInt = 1
diff --git a/src/internal/goexperiment/exp_preemptibleloops_off.go b/src/internal/goexperiment/exp_preemptibleloops_off.go
new file mode 100644
index 0000000..7a26088
--- /dev/null
+++ b/src/internal/goexperiment/exp_preemptibleloops_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.preemptibleloops
+// +build !goexperiment.preemptibleloops
+
+package goexperiment
+
+const PreemptibleLoops = false
+const PreemptibleLoopsInt = 0
diff --git a/src/internal/goexperiment/exp_preemptibleloops_on.go b/src/internal/goexperiment/exp_preemptibleloops_on.go
new file mode 100644
index 0000000..a9ca28c
--- /dev/null
+++ b/src/internal/goexperiment/exp_preemptibleloops_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.preemptibleloops
+// +build goexperiment.preemptibleloops
+
+package goexperiment
+
+const PreemptibleLoops = true
+const PreemptibleLoopsInt = 1
diff --git a/src/internal/goexperiment/exp_regabi_off.go b/src/internal/goexperiment/exp_regabi_off.go
new file mode 100644
index 0000000..5d88238
--- /dev/null
+++ b/src/internal/goexperiment/exp_regabi_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.regabi
+// +build !goexperiment.regabi
+
+package goexperiment
+
+const Regabi = false
+const RegabiInt = 0
diff --git a/src/internal/goexperiment/exp_regabi_on.go b/src/internal/goexperiment/exp_regabi_on.go
new file mode 100644
index 0000000..c08d58e
--- /dev/null
+++ b/src/internal/goexperiment/exp_regabi_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.regabi
+// +build goexperiment.regabi
+
+package goexperiment
+
+const Regabi = true
+const RegabiInt = 1
diff --git a/src/internal/goexperiment/exp_regabiargs_off.go b/src/internal/goexperiment/exp_regabiargs_off.go
new file mode 100644
index 0000000..31a139b
--- /dev/null
+++ b/src/internal/goexperiment/exp_regabiargs_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.regabiargs
+// +build !goexperiment.regabiargs
+
+package goexperiment
+
+const RegabiArgs = false
+const RegabiArgsInt = 0
diff --git a/src/internal/goexperiment/exp_regabiargs_on.go b/src/internal/goexperiment/exp_regabiargs_on.go
new file mode 100644
index 0000000..9b26f3c
--- /dev/null
+++ b/src/internal/goexperiment/exp_regabiargs_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.regabiargs
+// +build goexperiment.regabiargs
+
+package goexperiment
+
+const RegabiArgs = true
+const RegabiArgsInt = 1
diff --git a/src/internal/goexperiment/exp_regabidefer_off.go b/src/internal/goexperiment/exp_regabidefer_off.go
new file mode 100644
index 0000000..b47c0c2
--- /dev/null
+++ b/src/internal/goexperiment/exp_regabidefer_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.regabidefer
+// +build !goexperiment.regabidefer
+
+package goexperiment
+
+const RegabiDefer = false
+const RegabiDeferInt = 0
diff --git a/src/internal/goexperiment/exp_regabidefer_on.go b/src/internal/goexperiment/exp_regabidefer_on.go
new file mode 100644
index 0000000..bbf2f6c
--- /dev/null
+++ b/src/internal/goexperiment/exp_regabidefer_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.regabidefer
+// +build goexperiment.regabidefer
+
+package goexperiment
+
+const RegabiDefer = true
+const RegabiDeferInt = 1
diff --git a/src/internal/goexperiment/exp_regabig_off.go b/src/internal/goexperiment/exp_regabig_off.go
new file mode 100644
index 0000000..1b37d45
--- /dev/null
+++ b/src/internal/goexperiment/exp_regabig_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.regabig
+// +build !goexperiment.regabig
+
+package goexperiment
+
+const RegabiG = false
+const RegabiGInt = 0
diff --git a/src/internal/goexperiment/exp_regabig_on.go b/src/internal/goexperiment/exp_regabig_on.go
new file mode 100644
index 0000000..7e5b162
--- /dev/null
+++ b/src/internal/goexperiment/exp_regabig_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.regabig
+// +build goexperiment.regabig
+
+package goexperiment
+
+const RegabiG = true
+const RegabiGInt = 1
diff --git a/src/internal/goexperiment/exp_regabireflect_off.go b/src/internal/goexperiment/exp_regabireflect_off.go
new file mode 100644
index 0000000..515f4a5
--- /dev/null
+++ b/src/internal/goexperiment/exp_regabireflect_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.regabireflect
+// +build !goexperiment.regabireflect
+
+package goexperiment
+
+const RegabiReflect = false
+const RegabiReflectInt = 0
diff --git a/src/internal/goexperiment/exp_regabireflect_on.go b/src/internal/goexperiment/exp_regabireflect_on.go
new file mode 100644
index 0000000..e8a3e9c
--- /dev/null
+++ b/src/internal/goexperiment/exp_regabireflect_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.regabireflect
+// +build goexperiment.regabireflect
+
+package goexperiment
+
+const RegabiReflect = true
+const RegabiReflectInt = 1
diff --git a/src/internal/goexperiment/exp_regabiwrappers_off.go b/src/internal/goexperiment/exp_regabiwrappers_off.go
new file mode 100644
index 0000000..bfa0fa3
--- /dev/null
+++ b/src/internal/goexperiment/exp_regabiwrappers_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.regabiwrappers
+// +build !goexperiment.regabiwrappers
+
+package goexperiment
+
+const RegabiWrappers = false
+const RegabiWrappersInt = 0
diff --git a/src/internal/goexperiment/exp_regabiwrappers_on.go b/src/internal/goexperiment/exp_regabiwrappers_on.go
new file mode 100644
index 0000000..11ffffb
--- /dev/null
+++ b/src/internal/goexperiment/exp_regabiwrappers_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.regabiwrappers
+// +build goexperiment.regabiwrappers
+
+package goexperiment
+
+const RegabiWrappers = true
+const RegabiWrappersInt = 1
diff --git a/src/internal/goexperiment/exp_staticlockranking_off.go b/src/internal/goexperiment/exp_staticlockranking_off.go
new file mode 100644
index 0000000..3d546c0
--- /dev/null
+++ b/src/internal/goexperiment/exp_staticlockranking_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.staticlockranking
+// +build !goexperiment.staticlockranking
+
+package goexperiment
+
+const StaticLockRanking = false
+const StaticLockRankingInt = 0
diff --git a/src/internal/goexperiment/exp_staticlockranking_on.go b/src/internal/goexperiment/exp_staticlockranking_on.go
new file mode 100644
index 0000000..78188fb
--- /dev/null
+++ b/src/internal/goexperiment/exp_staticlockranking_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.staticlockranking
+// +build goexperiment.staticlockranking
+
+package goexperiment
+
+const StaticLockRanking = true
+const StaticLockRankingInt = 1
diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go
new file mode 100644
index 0000000..cd4c178
--- /dev/null
+++ b/src/internal/goexperiment/flags.go
@@ -0,0 +1,93 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package goexperiment implements support for toolchain experiments.
+//
+// Toolchain experiments are controlled by the GOEXPERIMENT
+// environment variable. GOEXPERIMENT is a comma-separated list of
+// experiment names. GOEXPERIMENT can be set at make.bash time, which
+// sets the default experiments for binaries built with the tool
+// chain; or it can be set at build time. GOEXPERIMENT can also be set
+// to "none", which disables any experiments that were enabled at
+// make.bash time.
+//
+// Experiments are exposed to the build in the following ways:
+//
+// - Build tag goexperiment.x is set if experiment x (lower case) is
+// enabled.
+//
+// - For each experiment x (in camel case), this package contains a
+// boolean constant x and an integer constant xInt.
+//
+// - In runtime assembly, the macro GOEXPERIMENT_x is defined if
+// experiment x (lower case) is enabled.
+//
+// In the toolchain, the set of experiments enabled for the current
+// build should be accessed via objabi.Experiment.
+//
+// The set of experiments is included in the output of runtime.Version()
+// and "go version <binary>" if it differs from the default experiments.
+//
+// For the set of experiments supported by the current toolchain, see
+// "go doc goexperiment.Flags".
+//
+// Note that this package defines the set of experiments (in Flags)
+// and records the experiments that were enabled when the package
+// was compiled (as boolean and integer constants).
+//
+// Note especially that this package does not itself change behavior
+// at run time based on the GOEXPERIMENT variable.
+// The code used in builds to interpret the GOEXPERIMENT variable
+// is in the separate package internal/buildcfg.
+package goexperiment
+
+//go:generate go run mkconsts.go
+
+// Flags is the set of experiments that can be enabled or disabled in
+// the current toolchain.
+//
+// When specified in the GOEXPERIMENT environment variable or as build
+// tags, experiments use the strings.ToLower of their field name.
+//
+// For the baseline experimental configuration, see
+// objabi.experimentBaseline.
+//
+// If you change this struct definition, run "go generate".
+type Flags struct {
+	FieldTrack        bool
+	PreemptibleLoops  bool
+	StaticLockRanking bool
+
+	// Regabi is split into several sub-experiments that can be
+	// enabled individually. Not all combinations work.
+	// The "regabi" GOEXPERIMENT is an alias for all "working"
+	// subexperiments.
+
+	// RegabiWrappers enables ABI wrappers for calling between
+	// ABI0 and ABIInternal functions. Without this, the ABIs are
+	// assumed to be identical so cross-ABI calls are direct.
+	RegabiWrappers bool
+	// RegabiG enables dedicated G and zero registers in
+	// ABIInternal.
+	//
+	// Requires wrappers because it makes the ABIs incompatible.
+	RegabiG bool
+	// RegabiReflect enables the register-passing paths in
+	// reflection calls. This is also gated by intArgRegs in
+	// reflect and runtime (which are disabled by default) so it
+	// can be used in targeted tests.
+	RegabiReflect bool
+	// RegabiDefer enables desugaring defer and go calls
+	// into argument-less closures.
+	RegabiDefer bool
+	// RegabiArgs enables register arguments/results in all
+	// compiled Go functions.
+	//
+	// Requires wrappers (to do ABI translation), g (because
+	// runtime assembly that's been ported to ABIInternal uses the
+	// G register), reflect (so reflection calls use registers),
+	// and defer (because the runtime doesn't support passing
+	// register arguments to defer/go).
+	RegabiArgs bool
+}
diff --git a/src/internal/goexperiment/mkconsts.go b/src/internal/goexperiment/mkconsts.go
new file mode 100644
index 0000000..204ca9d
--- /dev/null
+++ b/src/internal/goexperiment/mkconsts.go
@@ -0,0 +1,74 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build ignore
+// +build ignore
+
+// mkconsts generates const definition files for each GOEXPERIMENT.
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"internal/goexperiment"
+	"log"
+	"os"
+	"reflect"
+	"strings"
+)
+
+func main() {
+	// Delete existing experiment constant files.
+	ents, err := os.ReadDir(".")
+	if err != nil {
+		log.Fatal(err)
+	}
+	for _, ent := range ents {
+		name := ent.Name()
+		if !strings.HasPrefix(name, "exp_") {
+			continue
+		}
+		// Check that this is definitely a generated file.
+		data, err := os.ReadFile(name)
+		if err != nil {
+			log.Fatalf("reading %s: %v", name, err)
+		}
+		if !bytes.Contains(data, []byte("Code generated by mkconsts")) {
+			log.Fatalf("%s: expected generated file", name)
+		}
+		if err := os.Remove(name); err != nil {
+			log.Fatal(err)
+		}
+	}
+
+	// Generate new experiment constant files.
+	rt := reflect.TypeOf(&goexperiment.Flags{}).Elem()
+	for i := 0; i < rt.NumField(); i++ {
+		f := rt.Field(i).Name
+		buildTag := "goexperiment." + strings.ToLower(f)
+		for _, val := range []bool{false, true} {
+			name := fmt.Sprintf("exp_%s_%s.go", strings.ToLower(f), pick(val, "off", "on"))
+			data := fmt.Sprintf(`// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build %s%s
+// +build %s%s
+
+package goexperiment
+
+const %s = %v
+const %sInt = %s
+`, pick(val, "!", ""), buildTag, pick(val, "!", ""), buildTag, f, val, f, pick(val, "0", "1"))
+			if err := os.WriteFile(name, []byte(data), 0666); err != nil {
+				log.Fatalf("writing %s: %v", name, err)
+			}
+		}
+	}
+}
+
+func pick(v bool, f, t string) string {
+	if v {
+		return t
+	}
+	return f
+}
diff --git a/src/internal/goroot/gc.go b/src/internal/goroot/gc.go
index ce72bc3..2338b78 100644
--- a/src/internal/goroot/gc.go
+++ b/src/internal/goroot/gc.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 package goroot
diff --git a/src/internal/goroot/gccgo.go b/src/internal/goroot/gccgo.go
index 3530e59..b1041da 100644
--- a/src/internal/goroot/gccgo.go
+++ b/src/internal/goroot/gccgo.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gccgo
 // +build gccgo
 
 package goroot
diff --git a/src/internal/goversion/goversion.go b/src/internal/goversion/goversion.go
index 513be45..4cc1568 100644
--- a/src/internal/goversion/goversion.go
+++ b/src/internal/goversion/goversion.go
@@ -9,4 +9,4 @@
 //
 // It should be updated at the start of each development cycle to be
 // the version of the next Go 1.x release. See golang.org/issue/40705.
-const Version = 16
+const Version = 17
diff --git a/src/internal/itoa/itoa.go b/src/internal/itoa/itoa.go
new file mode 100644
index 0000000..c6062d9
--- /dev/null
+++ b/src/internal/itoa/itoa.go
@@ -0,0 +1,33 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Simple conversions to avoid depending on strconv.
+
+package itoa
+
+// Itoa converts val to a decimal string.
+func Itoa(val int) string {
+	if val < 0 {
+		return "-" + Uitoa(uint(-val))
+	}
+	return Uitoa(uint(val))
+}
+
+// Uitoa converts val to a decimal string.
+func Uitoa(val uint) string {
+	if val == 0 { // avoid string allocation
+		return "0"
+	}
+	var buf [20]byte // big enough for 64bit value base 10
+	i := len(buf) - 1
+	for val >= 10 {
+		q := val / 10
+		buf[i] = byte('0' + val - q*10)
+		i--
+		val = q
+	}
+	// val < 10
+	buf[i] = byte('0' + val)
+	return string(buf[i:])
+}
diff --git a/src/internal/itoa/itoa_test.go b/src/internal/itoa/itoa_test.go
new file mode 100644
index 0000000..71931c1
--- /dev/null
+++ b/src/internal/itoa/itoa_test.go
@@ -0,0 +1,40 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package itoa_test
+
+import (
+	"fmt"
+	"internal/itoa"
+	"math"
+	"testing"
+)
+
+var (
+	minInt64  int64  = math.MinInt64
+	maxInt64  int64  = math.MaxInt64
+	maxUint64 uint64 = math.MaxUint64
+)
+
+func TestItoa(t *testing.T) {
+	tests := []int{int(minInt64), math.MinInt32, -999, -100, -1, 0, 1, 100, 999, math.MaxInt32, int(maxInt64)}
+	for _, tt := range tests {
+		got := itoa.Itoa(tt)
+		want := fmt.Sprint(tt)
+		if want != got {
+			t.Fatalf("Itoa(%d) = %s, want %s", tt, got, want)
+		}
+	}
+}
+
+func TestUitoa(t *testing.T) {
+	tests := []uint{0, 1, 100, 999, math.MaxUint32, uint(maxUint64)}
+	for _, tt := range tests {
+		got := itoa.Uitoa(tt)
+		want := fmt.Sprint(tt)
+		if want != got {
+			t.Fatalf("Uitoa(%d) = %s, want %s", tt, got, want)
+		}
+	}
+}
diff --git a/src/internal/poll/copy_file_range_linux.go b/src/internal/poll/copy_file_range_linux.go
index 01b242a..5b9e5d4 100644
--- a/src/internal/poll/copy_file_range_linux.go
+++ b/src/internal/poll/copy_file_range_linux.go
@@ -78,7 +78,7 @@
 			// Go supports Linux >= 2.6.33, so the system call
 			// may not be present.
 			//
-			// If we see ENOSYS, we have certainly not transfered
+			// If we see ENOSYS, we have certainly not transferred
 			// any data, so we can tell the caller that we
 			// couldn't handle the transfer and let them fall
 			// back to more generic code.
@@ -91,13 +91,13 @@
 			// Prior to Linux 5.3, it was not possible to
 			// copy_file_range across file systems. Similarly to
 			// the ENOSYS case above, if we see EXDEV, we have
-			// not transfered any data, and we can let the caller
+			// not transferred any data, and we can let the caller
 			// fall back to generic code.
 			//
 			// As for EINVAL, that is what we see if, for example,
 			// dst or src refer to a pipe rather than a regular
 			// file. This is another case where no data has been
-			// transfered, so we consider it unhandled.
+			// transferred, so we consider it unhandled.
 			//
 			// If src and dst are on CIFS, we can see EIO.
 			// See issue #42334.
diff --git a/src/internal/poll/errno_unix.go b/src/internal/poll/errno_unix.go
index 0b23fc3..55c5488 100644
--- a/src/internal/poll/errno_unix.go
+++ b/src/internal/poll/errno_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package poll
diff --git a/src/internal/poll/errno_windows.go b/src/internal/poll/errno_windows.go
index e3bddb4..c55f5f0 100644
--- a/src/internal/poll/errno_windows.go
+++ b/src/internal/poll/errno_windows.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build windows
 // +build windows
 
 package poll
diff --git a/src/internal/poll/error_stub_test.go b/src/internal/poll/error_stub_test.go
index c40ffcd..bcc25dd 100644
--- a/src/internal/poll/error_stub_test.go
+++ b/src/internal/poll/error_stub_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !linux
 // +build !linux
 
 package poll_test
diff --git a/src/internal/poll/export_linux_test.go b/src/internal/poll/export_linux_test.go
new file mode 100644
index 0000000..7fba793
--- /dev/null
+++ b/src/internal/poll/export_linux_test.go
@@ -0,0 +1,22 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Export guts for testing on linux.
+// Since testing imports os and os imports internal/poll,
+// the internal/poll tests can not be in package poll.
+
+package poll
+
+var (
+	GetPipe     = getPipe
+	PutPipe     = putPipe
+	NewPipe     = newPipe
+	DestroyPipe = destroyPipe
+)
+
+func GetPipeFds(p *SplicePipe) (int, int) {
+	return p.rfd, p.wfd
+}
+
+type SplicePipe = splicePipe
diff --git a/src/internal/poll/export_posix_test.go b/src/internal/poll/export_posix_test.go
index abadf50..f59c1f6 100644
--- a/src/internal/poll/export_posix_test.go
+++ b/src/internal/poll/export_posix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 // Export guts for testing on posix.
diff --git a/src/internal/poll/fcntl_js.go b/src/internal/poll/fcntl_js.go
index 120fc11..7bf0ddc 100644
--- a/src/internal/poll/fcntl_js.go
+++ b/src/internal/poll/fcntl_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package poll
diff --git a/src/internal/poll/fcntl_libc.go b/src/internal/poll/fcntl_libc.go
index 642472b..cc609e4 100644
--- a/src/internal/poll/fcntl_libc.go
+++ b/src/internal/poll/fcntl_libc.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || solaris
 // +build aix darwin solaris
 
 package poll
diff --git a/src/internal/poll/fcntl_syscall.go b/src/internal/poll/fcntl_syscall.go
index 5ac8143..8db5b66 100644
--- a/src/internal/poll/fcntl_syscall.go
+++ b/src/internal/poll/fcntl_syscall.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || linux || netbsd || openbsd
 // +build dragonfly freebsd linux netbsd openbsd
 
 package poll
diff --git a/src/internal/poll/fd.go b/src/internal/poll/fd.go
index b72ea3d..69a9005 100644
--- a/src/internal/poll/fd.go
+++ b/src/internal/poll/fd.go
@@ -13,11 +13,22 @@
 	"errors"
 )
 
-// ErrNetClosing is returned when a network descriptor is used after
-// it has been closed. Keep this string consistent because of issue
-// #4373: since historically programs have not been able to detect
+// errNetClosing is the type of the variable ErrNetClosing.
+// This is used to implement the net.Error interface.
+type errNetClosing struct{}
+
+// Error returns the error message for ErrNetClosing.
+// Keep this string consistent because of issue #4373:
+// since historically programs have not been able to detect
 // this error, they look for the string.
-var ErrNetClosing = errors.New("use of closed network connection")
+func (e errNetClosing) Error() string { return "use of closed network connection" }
+
+func (e errNetClosing) Timeout() bool   { return false }
+func (e errNetClosing) Temporary() bool { return false }
+
+// ErrNetClosing is returned when a network descriptor is used after
+// it has been closed.
+var ErrNetClosing = errNetClosing{}
 
 // ErrFileClosing is returned when a file descriptor is used after it
 // has been closed.
diff --git a/src/internal/poll/fd_fsync_posix.go b/src/internal/poll/fd_fsync_posix.go
index dd7956f..651a5ec 100644
--- a/src/internal/poll/fd_fsync_posix.go
+++ b/src/internal/poll/fd_fsync_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package poll
diff --git a/src/internal/poll/fd_io_plan9.go b/src/internal/poll/fd_io_plan9.go
index 287d11b..3205ac8 100644
--- a/src/internal/poll/fd_io_plan9.go
+++ b/src/internal/poll/fd_io_plan9.go
@@ -5,6 +5,7 @@
 package poll
 
 import (
+	"internal/itoa"
 	"runtime"
 	"sync"
 	"syscall"
@@ -71,7 +72,7 @@
 	if aio.pid == -1 {
 		return
 	}
-	f, e := syscall.Open("/proc/"+itoa(aio.pid)+"/note", syscall.O_WRONLY)
+	f, e := syscall.Open("/proc/"+itoa.Itoa(aio.pid)+"/note", syscall.O_WRONLY)
 	if e != nil {
 		return
 	}
diff --git a/src/internal/poll/fd_poll_js.go b/src/internal/poll/fd_poll_js.go
index d6b28e5..760e248 100644
--- a/src/internal/poll/fd_poll_js.go
+++ b/src/internal/poll/fd_poll_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package poll
diff --git a/src/internal/poll/fd_poll_runtime.go b/src/internal/poll/fd_poll_runtime.go
index 222e5c6..b072af0 100644
--- a/src/internal/poll/fd_poll_runtime.go
+++ b/src/internal/poll/fd_poll_runtime.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || windows || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd windows solaris
 
 package poll
@@ -38,10 +39,6 @@
 	serverInit.Do(runtime_pollServerInit)
 	ctx, errno := runtime_pollOpen(uintptr(fd.Sysfd))
 	if errno != 0 {
-		if ctx != 0 {
-			runtime_pollUnblock(ctx)
-			runtime_pollClose(ctx)
-		}
 		return errnoErr(syscall.Errno(errno))
 	}
 	pd.runtimeCtx = ctx
diff --git a/src/internal/poll/fd_posix.go b/src/internal/poll/fd_posix.go
index 4edfa95..487f328 100644
--- a/src/internal/poll/fd_posix.go
+++ b/src/internal/poll/fd_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package poll
diff --git a/src/internal/poll/fd_posix_test.go b/src/internal/poll/fd_posix_test.go
index 4449eb3..1dcf51d 100644
--- a/src/internal/poll/fd_posix_test.go
+++ b/src/internal/poll/fd_posix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package poll_test
diff --git a/src/internal/poll/fd_unix.go b/src/internal/poll/fd_unix.go
index 2e77e76..3b17cd2 100644
--- a/src/internal/poll/fd_unix.go
+++ b/src/internal/poll/fd_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package poll
@@ -230,7 +231,7 @@
 }
 
 // ReadMsg wraps the recvmsg network call.
-func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) {
+func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) {
 	if err := fd.readLock(); err != nil {
 		return 0, 0, 0, nil, err
 	}
@@ -239,7 +240,7 @@
 		return 0, 0, 0, nil, err
 	}
 	for {
-		n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0)
+		n, oobn, sysflags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, flags)
 		if err != nil {
 			if err == syscall.EINTR {
 				continue
@@ -252,7 +253,7 @@
 			}
 		}
 		err = fd.eofError(n, err)
-		return n, oobn, flags, sa, err
+		return n, oobn, sysflags, sa, err
 	}
 }
 
diff --git a/src/internal/poll/fd_windows.go b/src/internal/poll/fd_windows.go
index d8c834f..4a51695 100644
--- a/src/internal/poll/fd_windows.go
+++ b/src/internal/poll/fd_windows.go
@@ -1013,7 +1013,7 @@
 }
 
 // ReadMsg wraps the WSARecvMsg network call.
-func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) {
+func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) {
 	if err := fd.readLock(); err != nil {
 		return 0, 0, 0, nil, err
 	}
@@ -1028,6 +1028,7 @@
 	o.rsa = new(syscall.RawSockaddrAny)
 	o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
 	o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
+	o.msg.Flags = uint32(flags)
 	n, err := execIO(o, func(o *operation) error {
 		return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
 	})
diff --git a/src/internal/poll/fd_writev_darwin.go b/src/internal/poll/fd_writev_darwin.go
index e202447..805fa2c 100644
--- a/src/internal/poll/fd_writev_darwin.go
+++ b/src/internal/poll/fd_writev_darwin.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin
 // +build darwin
 
 package poll
diff --git a/src/internal/poll/fd_writev_illumos.go b/src/internal/poll/fd_writev_illumos.go
index 1fa47ab..a0b11ed 100644
--- a/src/internal/poll/fd_writev_illumos.go
+++ b/src/internal/poll/fd_writev_illumos.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build illumos
 // +build illumos
 
 package poll
diff --git a/src/internal/poll/fd_writev_unix.go b/src/internal/poll/fd_writev_unix.go
index daeec96..87f284a 100644
--- a/src/internal/poll/fd_writev_unix.go
+++ b/src/internal/poll/fd_writev_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || linux || netbsd || openbsd
 // +build dragonfly freebsd linux netbsd openbsd
 
 package poll
diff --git a/src/internal/poll/hook_cloexec.go b/src/internal/poll/hook_cloexec.go
index 5fd5449..d519f60 100644
--- a/src/internal/poll/hook_cloexec.go
+++ b/src/internal/poll/hook_cloexec.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || illumos || linux || netbsd || openbsd
 // +build dragonfly freebsd illumos linux netbsd openbsd
 
 package poll
diff --git a/src/internal/poll/hook_unix.go b/src/internal/poll/hook_unix.go
index 11f90e9..c88d65c 100644
--- a/src/internal/poll/hook_unix.go
+++ b/src/internal/poll/hook_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package poll
diff --git a/src/internal/poll/iovec_illumos.go b/src/internal/poll/iovec_illumos.go
index 0570674..f4058b2 100644
--- a/src/internal/poll/iovec_illumos.go
+++ b/src/internal/poll/iovec_illumos.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build illumos
 // +build illumos
 
 package poll
diff --git a/src/internal/poll/iovec_unix.go b/src/internal/poll/iovec_unix.go
index 6f98947..6fd5d86 100644
--- a/src/internal/poll/iovec_unix.go
+++ b/src/internal/poll/iovec_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
 // +build darwin dragonfly freebsd linux netbsd openbsd
 
 package poll
diff --git a/src/internal/poll/sendfile_bsd.go b/src/internal/poll/sendfile_bsd.go
index 66005a9..3ba30a2 100644
--- a/src/internal/poll/sendfile_bsd.go
+++ b/src/internal/poll/sendfile_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd
 // +build dragonfly freebsd
 
 package poll
@@ -22,7 +23,7 @@
 		return 0, err
 	}
 
-	dst := int(dstFD.Sysfd)
+	dst := dstFD.Sysfd
 	var written int64
 	var err error
 	for remain > 0 {
diff --git a/src/internal/poll/sendfile_linux.go b/src/internal/poll/sendfile_linux.go
index d6442e8..6e78523 100644
--- a/src/internal/poll/sendfile_linux.go
+++ b/src/internal/poll/sendfile_linux.go
@@ -20,7 +20,7 @@
 		return 0, err
 	}
 
-	dst := int(dstFD.Sysfd)
+	dst := dstFD.Sysfd
 	var written int64
 	var err error
 	for remain > 0 {
diff --git a/src/internal/poll/sendfile_solaris.go b/src/internal/poll/sendfile_solaris.go
index 748c851..0a88430 100644
--- a/src/internal/poll/sendfile_solaris.go
+++ b/src/internal/poll/sendfile_solaris.go
@@ -24,7 +24,7 @@
 		return 0, err
 	}
 
-	dst := int(dstFD.Sysfd)
+	dst := dstFD.Sysfd
 	var written int64
 	var err error
 	for remain > 0 {
diff --git a/src/internal/poll/sock_cloexec.go b/src/internal/poll/sock_cloexec.go
index ff7982c..b303829 100644
--- a/src/internal/poll/sock_cloexec.go
+++ b/src/internal/poll/sock_cloexec.go
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This file implements sysSocket and accept for platforms that
-// provide a fast path for setting SetNonblock and CloseOnExec.
+// This file implements accept for platforms that provide a fast path for
+// setting SetNonblock and CloseOnExec.
 
+//go:build dragonfly || freebsd || illumos || linux || netbsd || openbsd
 // +build dragonfly freebsd illumos linux netbsd openbsd
 
 package poll
diff --git a/src/internal/poll/sockopt.go b/src/internal/poll/sockopt.go
index bb5ea02..4f2e2fb 100644
--- a/src/internal/poll/sockopt.go
+++ b/src/internal/poll/sockopt.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package poll
diff --git a/src/internal/poll/sockopt_unix.go b/src/internal/poll/sockopt_unix.go
index bd942c2..4fb9600 100644
--- a/src/internal/poll/sockopt_unix.go
+++ b/src/internal/poll/sockopt_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package poll
diff --git a/src/internal/poll/sockoptip.go b/src/internal/poll/sockoptip.go
index c55a1e3..d86c4c1 100644
--- a/src/internal/poll/sockoptip.go
+++ b/src/internal/poll/sockoptip.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package poll
diff --git a/src/internal/poll/splice_linux.go b/src/internal/poll/splice_linux.go
index 01baf14..8062d98 100644
--- a/src/internal/poll/splice_linux.go
+++ b/src/internal/poll/splice_linux.go
@@ -6,6 +6,8 @@
 
 import (
 	"internal/syscall/unix"
+	"runtime"
+	"sync"
 	"sync/atomic"
 	"syscall"
 	"unsafe"
@@ -23,23 +25,23 @@
 // Splice transfers at most remain bytes of data from src to dst, using the
 // splice system call to minimize copies of data from and to userspace.
 //
-// Splice creates a temporary pipe, to serve as a buffer for the data transfer.
+// Splice gets a pipe buffer from the pool or creates a new one if needed, to serve as a buffer for the data transfer.
 // src and dst must both be stream-oriented sockets.
 //
 // If err != nil, sc is the system call which caused the error.
 func Splice(dst, src *FD, remain int64) (written int64, handled bool, sc string, err error) {
-	prfd, pwfd, sc, err := newTempPipe()
+	p, sc, err := getPipe()
 	if err != nil {
 		return 0, false, sc, err
 	}
-	defer destroyTempPipe(prfd, pwfd)
+	defer putPipe(p)
 	var inPipe, n int
 	for err == nil && remain > 0 {
 		max := maxSpliceSize
 		if int64(max) > remain {
 			max = int(remain)
 		}
-		inPipe, err = spliceDrain(pwfd, src, max)
+		inPipe, err = spliceDrain(p.wfd, src, max)
 		// The operation is considered handled if splice returns no
 		// error, or an error other than EINVAL. An EINVAL means the
 		// kernel does not support splice for the socket type of src.
@@ -52,13 +54,16 @@
 		// If inPipe == 0 && err == nil, src is at EOF, and the
 		// transfer is complete.
 		handled = handled || (err != syscall.EINVAL)
-		if err != nil || (inPipe == 0 && err == nil) {
+		if err != nil || inPipe == 0 {
 			break
 		}
-		n, err = splicePump(dst, prfd, inPipe)
+		p.data += inPipe
+
+		n, err = splicePump(dst, p.rfd, inPipe)
 		if n > 0 {
 			written += int64(n)
 			remain -= int64(n)
+			p.data -= n
 		}
 	}
 	if err != nil {
@@ -149,13 +154,58 @@
 	return int(n), err
 }
 
+type splicePipe struct {
+	rfd  int
+	wfd  int
+	data int
+}
+
+// splicePipePool caches pipes to avoid high-frequency construction and destruction of pipe buffers.
+// The garbage collector will free all pipes in the sync.Pool periodically, thus we need to set up
+// a finalizer for each pipe to close its file descriptors before the actual GC.
+var splicePipePool = sync.Pool{New: newPoolPipe}
+
+func newPoolPipe() interface{} {
+	// Discard the error which occurred during the creation of pipe buffer,
+	// redirecting the data transmission to the conventional way utilizing read() + write() as a fallback.
+	p := newPipe()
+	if p == nil {
+		return nil
+	}
+	runtime.SetFinalizer(p, destroyPipe)
+	return p
+}
+
+// getPipe tries to acquire a pipe buffer from the pool or create a new one with newPipe() if it gets nil from the cache.
+//
+// Note that it may fail to create a new pipe buffer by newPipe(), in which case getPipe() will return a generic error
+// and system call name splice in a string as the indication.
+func getPipe() (*splicePipe, string, error) {
+	v := splicePipePool.Get()
+	if v == nil {
+		return nil, "splice", syscall.EINVAL
+	}
+	return v.(*splicePipe), "", nil
+}
+
+func putPipe(p *splicePipe) {
+	// If there is still data left in the pipe,
+	// then close and discard it instead of putting it back into the pool.
+	if p.data != 0 {
+		runtime.SetFinalizer(p, nil)
+		destroyPipe(p)
+		return
+	}
+	splicePipePool.Put(p)
+}
+
 var disableSplice unsafe.Pointer
 
-// newTempPipe sets up a temporary pipe for a splice operation.
-func newTempPipe() (prfd, pwfd int, sc string, err error) {
+// newPipe sets up a pipe for a splice operation.
+func newPipe() (sp *splicePipe) {
 	p := (*bool)(atomic.LoadPointer(&disableSplice))
 	if p != nil && *p {
-		return -1, -1, "splice", syscall.EINVAL
+		return nil
 	}
 
 	var fds [2]int
@@ -165,9 +215,11 @@
 	// closed.
 	const flags = syscall.O_CLOEXEC | syscall.O_NONBLOCK
 	if err := syscall.Pipe2(fds[:], flags); err != nil {
-		return -1, -1, "pipe2", err
+		return nil
 	}
 
+	sp = &splicePipe{rfd: fds[0], wfd: fds[1]}
+
 	if p == nil {
 		p = new(bool)
 		defer atomic.StorePointer(&disableSplice, unsafe.Pointer(p))
@@ -175,20 +227,16 @@
 		// F_GETPIPE_SZ was added in 2.6.35, which does not have the -EAGAIN bug.
 		if _, _, errno := syscall.Syscall(unix.FcntlSyscall, uintptr(fds[0]), syscall.F_GETPIPE_SZ, 0); errno != 0 {
 			*p = true
-			destroyTempPipe(fds[0], fds[1])
-			return -1, -1, "fcntl", errno
+			destroyPipe(sp)
+			return nil
 		}
 	}
 
-	return fds[0], fds[1], "", nil
+	return
 }
 
-// destroyTempPipe destroys a temporary pipe.
-func destroyTempPipe(prfd, pwfd int) error {
-	err := CloseFunc(prfd)
-	err1 := CloseFunc(pwfd)
-	if err == nil {
-		return err1
-	}
-	return err
+// destroyPipe destroys a pipe.
+func destroyPipe(p *splicePipe) {
+	CloseFunc(p.rfd)
+	CloseFunc(p.wfd)
 }
diff --git a/src/internal/poll/splice_linux_test.go b/src/internal/poll/splice_linux_test.go
new file mode 100644
index 0000000..280468c
--- /dev/null
+++ b/src/internal/poll/splice_linux_test.go
@@ -0,0 +1,119 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package poll_test
+
+import (
+	"internal/poll"
+	"internal/syscall/unix"
+	"runtime"
+	"syscall"
+	"testing"
+	"time"
+)
+
+// checkPipes returns true if all pipes are closed properly, false otherwise.
+func checkPipes(fds []int) bool {
+	for _, fd := range fds {
+		// Check if each pipe fd has been closed.
+		_, _, errno := syscall.Syscall(unix.FcntlSyscall, uintptr(fd), syscall.F_GETPIPE_SZ, 0)
+		if errno == 0 {
+			return false
+		}
+	}
+	return true
+}
+
+func TestSplicePipePool(t *testing.T) {
+	const N = 64
+	var (
+		p   *poll.SplicePipe
+		ps  []*poll.SplicePipe
+		fds []int
+		err error
+	)
+	for i := 0; i < N; i++ {
+		p, _, err = poll.GetPipe()
+		if err != nil {
+			t.Skip("failed to create pipe, skip this test")
+		}
+		_, pwfd := poll.GetPipeFds(p)
+		fds = append(fds, pwfd)
+		ps = append(ps, p)
+	}
+	for _, p = range ps {
+		poll.PutPipe(p)
+	}
+	ps = nil
+	p = nil
+
+	// Exploit the timeout of "go test" as a timer for the subsequent verification.
+	timeout := 5 * time.Minute
+	if deadline, ok := t.Deadline(); ok {
+		timeout = deadline.Sub(time.Now())
+		timeout -= timeout / 10 // Leave 10% headroom for cleanup.
+	}
+	expiredTime := time.NewTimer(timeout)
+	defer expiredTime.Stop()
+
+	// Trigger garbage collection repeatedly, waiting for all pipes in sync.Pool
+	// to either be deallocated and closed, or to time out.
+	for {
+		runtime.GC()
+		time.Sleep(10 * time.Millisecond)
+		if checkPipes(fds) {
+			break
+		}
+		select {
+		case <-expiredTime.C:
+			t.Fatal("at least one pipe is still open")
+		default:
+		}
+	}
+}
+
+func BenchmarkSplicePipe(b *testing.B) {
+	b.Run("SplicePipeWithPool", func(b *testing.B) {
+		for i := 0; i < b.N; i++ {
+			p, _, err := poll.GetPipe()
+			if err != nil {
+				continue
+			}
+			poll.PutPipe(p)
+		}
+	})
+	b.Run("SplicePipeWithoutPool", func(b *testing.B) {
+		for i := 0; i < b.N; i++ {
+			p := poll.NewPipe()
+			if p == nil {
+				b.Skip("newPipe returned nil")
+			}
+			poll.DestroyPipe(p)
+		}
+	})
+}
+
+func BenchmarkSplicePipePoolParallel(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			p, _, err := poll.GetPipe()
+			if err != nil {
+				continue
+			}
+			poll.PutPipe(p)
+		}
+	})
+}
+
+func BenchmarkSplicePipeNativeParallel(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			p := poll.NewPipe()
+			if p == nil {
+				b.Skip("newPipe returned nil")
+			}
+			poll.DestroyPipe(p)
+		}
+	})
+}
diff --git a/src/internal/poll/strconv.go b/src/internal/poll/strconv.go
index 21cb40d..c98332d 100644
--- a/src/internal/poll/strconv.go
+++ b/src/internal/poll/strconv.go
@@ -2,38 +2,11 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build plan9
 // +build plan9
 
-// Simple conversions to avoid depending on strconv.
-
 package poll
 
-// Convert integer to decimal string
-func itoa(val int) string {
-	if val < 0 {
-		return "-" + uitoa(uint(-val))
-	}
-	return uitoa(uint(val))
-}
-
-// Convert unsigned integer to decimal string
-func uitoa(val uint) string {
-	if val == 0 { // avoid string allocation
-		return "0"
-	}
-	var buf [20]byte // big enough for 64bit value base 10
-	i := len(buf) - 1
-	for val >= 10 {
-		q := val / 10
-		buf[i] = byte('0' + val - q*10)
-		i--
-		val = q
-	}
-	// val < 10
-	buf[i] = byte('0' + val)
-	return string(buf[i:])
-}
-
 // stringsHasSuffix is strings.HasSuffix. It reports whether s ends in
 // suffix.
 func stringsHasSuffix(s, suffix string) bool {
diff --git a/src/internal/poll/sys_cloexec.go b/src/internal/poll/sys_cloexec.go
index 4b3c642..7e6d422 100644
--- a/src/internal/poll/sys_cloexec.go
+++ b/src/internal/poll/sys_cloexec.go
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This file implements sysSocket and accept for platforms that do not
-// provide a fast path for setting SetNonblock and CloseOnExec.
+// This file implements accept for platforms that do not provide a fast path for
+// setting SetNonblock and CloseOnExec.
 
+//go:build aix || darwin || (js && wasm) || (solaris && !illumos)
 // +build aix darwin js,wasm solaris,!illumos
 
 package poll
diff --git a/src/internal/poll/writev.go b/src/internal/poll/writev.go
index 0123fc3..824de75 100644
--- a/src/internal/poll/writev.go
+++ b/src/internal/poll/writev.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || illumos || linux || netbsd || openbsd
 // +build darwin dragonfly freebsd illumos linux netbsd openbsd
 
 package poll
diff --git a/src/internal/race/norace.go b/src/internal/race/norace.go
index d83c016..67b1305 100644
--- a/src/internal/race/norace.go
+++ b/src/internal/race/norace.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !race
 // +build !race
 
 package race
diff --git a/src/internal/race/race.go b/src/internal/race/race.go
index 2e7d97b..40f2c99 100644
--- a/src/internal/race/race.go
+++ b/src/internal/race/race.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build race
 // +build race
 
 package race
diff --git a/src/internal/reflectlite/all_test.go b/src/internal/reflectlite/all_test.go
index e2c4f30..e15f364 100644
--- a/src/internal/reflectlite/all_test.go
+++ b/src/internal/reflectlite/all_test.go
@@ -982,19 +982,6 @@
 	}
 }
 
-type embed struct {
-	EmbedWithUnexpMeth
-}
-
-func TestNameBytesAreAligned(t *testing.T) {
-	typ := TypeOf(embed{})
-	b := FirstMethodNameBytes(typ)
-	v := uintptr(unsafe.Pointer(b))
-	if v%unsafe.Alignof((*byte)(nil)) != 0 {
-		t.Errorf("reflect.name.bytes pointer is not aligned: %x", v)
-	}
-}
-
 // TestUnaddressableField tests that the reflect package will not allow
 // a type from another package to be used as a named type with an
 // unexported field.
diff --git a/src/internal/reflectlite/type.go b/src/internal/reflectlite/type.go
index 15ba30d..b1899b0 100644
--- a/src/internal/reflectlite/type.go
+++ b/src/internal/reflectlite/type.go
@@ -68,7 +68,7 @@
 }
 
 /*
- * These data structures are known to the compiler (../../cmd/internal/gc/reflect.go).
+ * These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go).
  * A few are known to ../runtime/type.go to convey to debuggers.
  * They are also known to ../runtime/type.go.
  */
@@ -111,7 +111,7 @@
 // available in the memory directly following the rtype value.
 //
 // tflag values must be kept in sync with copies in:
-//	cmd/compile/internal/gc/reflect.go
+//	cmd/compile/internal/reflectdata/reflect.go
 //	cmd/link/internal/ld/decodesym.go
 //	runtime/type.go
 type tflag uint8
@@ -321,49 +321,55 @@
 	return (*n.bytes)&(1<<0) != 0
 }
 
-func (n name) nameLen() int {
-	return int(uint16(*n.data(1, "name len field"))<<8 | uint16(*n.data(2, "name len field")))
+func (n name) hasTag() bool {
+	return (*n.bytes)&(1<<1) != 0
 }
 
-func (n name) tagLen() int {
-	if *n.data(0, "name flag field")&(1<<1) == 0 {
-		return 0
+// readVarint parses a varint as encoded by encoding/binary.
+// It returns the number of encoded bytes and the encoded value.
+func (n name) readVarint(off int) (int, int) {
+	v := 0
+	for i := 0; ; i++ {
+		x := *n.data(off+i, "read varint")
+		v += int(x&0x7f) << (7 * i)
+		if x&0x80 == 0 {
+			return i + 1, v
+		}
 	}
-	off := 3 + n.nameLen()
-	return int(uint16(*n.data(off, "name taglen field"))<<8 | uint16(*n.data(off+1, "name taglen field")))
 }
 
 func (n name) name() (s string) {
 	if n.bytes == nil {
 		return
 	}
-	b := (*[4]byte)(unsafe.Pointer(n.bytes))
-
+	i, l := n.readVarint(1)
 	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
-	hdr.Data = unsafe.Pointer(&b[3])
-	hdr.Len = int(b[1])<<8 | int(b[2])
-	return s
+	hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string"))
+	hdr.Len = l
+	return
 }
 
 func (n name) tag() (s string) {
-	tl := n.tagLen()
-	if tl == 0 {
+	if !n.hasTag() {
 		return ""
 	}
-	nl := n.nameLen()
+	i, l := n.readVarint(1)
+	i2, l2 := n.readVarint(1 + i + l)
 	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
-	hdr.Data = unsafe.Pointer(n.data(3+nl+2, "non-empty string"))
-	hdr.Len = tl
-	return s
+	hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string"))
+	hdr.Len = l2
+	return
 }
 
 func (n name) pkgPath() string {
 	if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 {
 		return ""
 	}
-	off := 3 + n.nameLen()
-	if tl := n.tagLen(); tl > 0 {
-		off += 2 + tl
+	i, l := n.readVarint(1)
+	off := 1 + i + l
+	if n.hasTag() {
+		i2, l2 := n.readVarint(off)
+		off += i2 + l2
 	}
 	var nameOff int32
 	// Note that this field may not be aligned in memory,
diff --git a/src/internal/syscall/execenv/execenv_default.go b/src/internal/syscall/execenv/execenv_default.go
index 4bdbb55..73289f1 100644
--- a/src/internal/syscall/execenv/execenv_default.go
+++ b/src/internal/syscall/execenv/execenv_default.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows
 // +build !windows
 
 package execenv
diff --git a/src/internal/syscall/execenv/execenv_windows.go b/src/internal/syscall/execenv/execenv_windows.go
index b50029c..6c06549 100644
--- a/src/internal/syscall/execenv/execenv_windows.go
+++ b/src/internal/syscall/execenv/execenv_windows.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build windows
 // +build windows
 
 package execenv
diff --git a/src/internal/syscall/unix/asm_darwin.s b/src/internal/syscall/unix/asm_darwin.s
new file mode 100644
index 0000000..8fbdc1d
--- /dev/null
+++ b/src/internal/syscall/unix/asm_darwin.s
@@ -0,0 +1,8 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·libc_getentropy_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getentropy(SB)
diff --git a/src/internal/syscall/unix/at.go b/src/internal/syscall/unix/at.go
index f857d68..9b08864 100644
--- a/src/internal/syscall/unix/at.go
+++ b/src/internal/syscall/unix/at.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux || openbsd || netbsd || dragonfly
 // +build linux openbsd netbsd dragonfly
 
 package unix
diff --git a/src/internal/syscall/unix/at_libc.go b/src/internal/syscall/unix/at_libc.go
index 6c3a8c9..4cc351e 100644
--- a/src/internal/syscall/unix/at_libc.go
+++ b/src/internal/syscall/unix/at_libc.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || solaris
 // +build aix solaris
 
 package unix
diff --git a/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go b/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go
index c6ea206..050d401 100644
--- a/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go
+++ b/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm || mips || mipsle || 386
 // +build arm mips mipsle 386
 
 package unix
diff --git a/src/internal/syscall/unix/at_sysnum_fstatat_linux.go b/src/internal/syscall/unix/at_sysnum_fstatat_linux.go
index 31fe6a5..e53a2d1 100644
--- a/src/internal/syscall/unix/at_sysnum_fstatat_linux.go
+++ b/src/internal/syscall/unix/at_sysnum_fstatat_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm64 || riscv64
 // +build arm64 riscv64
 
 package unix
diff --git a/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go b/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go
index e76c1cb..4cb4a59 100644
--- a/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go
+++ b/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 || mips64 || mips64le || ppc64 || ppc64le || s390x
 // +build amd64 mips64 mips64le ppc64 ppc64le s390x
 
 package unix
diff --git a/src/internal/syscall/unix/fcntl_linux_32bit.go b/src/internal/syscall/unix/fcntl_linux_32bit.go
index 6c75afc..46a4f6b 100644
--- a/src/internal/syscall/unix/fcntl_linux_32bit.go
+++ b/src/internal/syscall/unix/fcntl_linux_32bit.go
@@ -5,6 +5,7 @@
 // On 32-bit Linux systems, use SYS_FCNTL64.
 // If you change the build tags here, see syscall/flock_linux_32bit.go.
 
+//go:build (linux && 386) || (linux && arm) || (linux && mips) || (linux && mipsle)
 // +build linux,386 linux,arm linux,mips linux,mipsle
 
 package unix
diff --git a/src/internal/syscall/unix/getentropy_darwin.go b/src/internal/syscall/unix/getentropy_darwin.go
new file mode 100644
index 0000000..e1a410a
--- /dev/null
+++ b/src/internal/syscall/unix/getentropy_darwin.go
@@ -0,0 +1,30 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import (
+	"internal/abi"
+	"syscall"
+	"unsafe"
+)
+
+//go:cgo_import_dynamic libc_getentropy getentropy "/usr/lib/libSystem.B.dylib"
+
+func libc_getentropy_trampoline()
+
+// GetEntropy calls the macOS getentropy system call.
+func GetEntropy(p []byte) error {
+	_, _, errno := syscall_syscall(abi.FuncPCABI0(libc_getentropy_trampoline),
+		uintptr(unsafe.Pointer(&p[0])),
+		uintptr(len(p)),
+		0)
+	if errno != 0 {
+		return errno
+	}
+	return nil
+}
+
+//go:linkname syscall_syscall syscall.syscall
+func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
diff --git a/src/internal/syscall/unix/getrandom.go b/src/internal/syscall/unix/getrandom.go
new file mode 100644
index 0000000..d2c58c0
--- /dev/null
+++ b/src/internal/syscall/unix/getrandom.go
@@ -0,0 +1,40 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build dragonfly || freebsd || linux
+// +build dragonfly freebsd linux
+
+package unix
+
+import (
+	"sync/atomic"
+	"syscall"
+	"unsafe"
+)
+
+var getrandomUnsupported int32 // atomic
+
+// GetRandomFlag is a flag supported by the getrandom system call.
+type GetRandomFlag uintptr
+
+// GetRandom calls the getrandom system call.
+func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) {
+	if len(p) == 0 {
+		return 0, nil
+	}
+	if atomic.LoadInt32(&getrandomUnsupported) != 0 {
+		return 0, syscall.ENOSYS
+	}
+	r1, _, errno := syscall.Syscall(getrandomTrap,
+		uintptr(unsafe.Pointer(&p[0])),
+		uintptr(len(p)),
+		uintptr(flags))
+	if errno != 0 {
+		if errno == syscall.ENOSYS {
+			atomic.StoreInt32(&getrandomUnsupported, 1)
+		}
+		return 0, errno
+	}
+	return int(r1), nil
+}
diff --git a/src/internal/syscall/unix/getrandom_dragonfly.go b/src/internal/syscall/unix/getrandom_dragonfly.go
new file mode 100644
index 0000000..fbf78f9
--- /dev/null
+++ b/src/internal/syscall/unix/getrandom_dragonfly.go
@@ -0,0 +1,16 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+// DragonFlyBSD getrandom system call number.
+const getrandomTrap uintptr = 550
+
+const (
+	// GRND_RANDOM is only set for portability purpose, no-op on DragonFlyBSD.
+	GRND_RANDOM GetRandomFlag = 0x0001
+
+	// GRND_NONBLOCK means return EAGAIN rather than blocking.
+	GRND_NONBLOCK GetRandomFlag = 0x0002
+)
diff --git a/src/internal/syscall/unix/getrandom_freebsd.go b/src/internal/syscall/unix/getrandom_freebsd.go
index f1ba573..8c4f3df 100644
--- a/src/internal/syscall/unix/getrandom_freebsd.go
+++ b/src/internal/syscall/unix/getrandom_freebsd.go
@@ -4,19 +4,8 @@
 
 package unix
 
-import (
-	"sync/atomic"
-	"syscall"
-	"unsafe"
-)
-
-var randomUnsupported int32 // atomic
-
 // FreeBSD getrandom system call number.
-const randomTrap uintptr = 563
-
-// GetRandomFlag is a flag supported by the getrandom system call.
-type GetRandomFlag uintptr
+const getrandomTrap uintptr = 563
 
 const (
 	// GRND_NONBLOCK means return EAGAIN rather than blocking.
@@ -25,24 +14,3 @@
 	// GRND_RANDOM is only set for portability purpose, no-op on FreeBSD.
 	GRND_RANDOM GetRandomFlag = 0x0002
 )
-
-// GetRandom calls the FreeBSD getrandom system call.
-func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) {
-	if len(p) == 0 {
-		return 0, nil
-	}
-	if atomic.LoadInt32(&randomUnsupported) != 0 {
-		return 0, syscall.ENOSYS
-	}
-	r1, _, errno := syscall.Syscall(randomTrap,
-		uintptr(unsafe.Pointer(&p[0])),
-		uintptr(len(p)),
-		uintptr(flags))
-	if errno != 0 {
-		if errno == syscall.ENOSYS {
-			atomic.StoreInt32(&randomUnsupported, 1)
-		}
-		return 0, errno
-	}
-	return int(r1), nil
-}
diff --git a/src/internal/syscall/unix/getrandom_linux.go b/src/internal/syscall/unix/getrandom_linux.go
index 490d516..8ccd8d3 100644
--- a/src/internal/syscall/unix/getrandom_linux.go
+++ b/src/internal/syscall/unix/getrandom_linux.go
@@ -4,17 +4,6 @@
 
 package unix
 
-import (
-	"sync/atomic"
-	"syscall"
-	"unsafe"
-)
-
-var randomUnsupported int32 // atomic
-
-// GetRandomFlag is a flag supported by the getrandom system call.
-type GetRandomFlag uintptr
-
 const (
 	// GRND_NONBLOCK means return EAGAIN rather than blocking.
 	GRND_NONBLOCK GetRandomFlag = 0x0001
@@ -22,25 +11,3 @@
 	// GRND_RANDOM means use the /dev/random pool instead of /dev/urandom.
 	GRND_RANDOM GetRandomFlag = 0x0002
 )
-
-// GetRandom calls the Linux getrandom system call.
-// See https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c6e9d6f38894798696f23c8084ca7edbf16ee895
-func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) {
-	if len(p) == 0 {
-		return 0, nil
-	}
-	if atomic.LoadInt32(&randomUnsupported) != 0 {
-		return 0, syscall.ENOSYS
-	}
-	r1, _, errno := syscall.Syscall(getrandomTrap,
-		uintptr(unsafe.Pointer(&p[0])),
-		uintptr(len(p)),
-		uintptr(flags))
-	if errno != 0 {
-		if errno == syscall.ENOSYS {
-			atomic.StoreInt32(&randomUnsupported, 1)
-		}
-		return 0, errno
-	}
-	return int(r1), nil
-}
diff --git a/src/internal/syscall/unix/getrandom_solaris.go b/src/internal/syscall/unix/getrandom_solaris.go
new file mode 100644
index 0000000..d86775c
--- /dev/null
+++ b/src/internal/syscall/unix/getrandom_solaris.go
@@ -0,0 +1,53 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import (
+	"sync/atomic"
+	"syscall"
+	"unsafe"
+)
+
+//go:cgo_import_dynamic libc_getrandom getrandom "libc.so"
+
+//go:linkname procGetrandom libc_getrandom
+
+var procGetrandom uintptr
+
+var getrandomUnsupported int32 // atomic
+
+// GetRandomFlag is a flag supported by the getrandom system call.
+type GetRandomFlag uintptr
+
+const (
+	// GRND_NONBLOCK means return EAGAIN rather than blocking.
+	GRND_NONBLOCK GetRandomFlag = 0x0001
+
+	// GRND_RANDOM means use the /dev/random pool instead of /dev/urandom.
+	GRND_RANDOM GetRandomFlag = 0x0002
+)
+
+// GetRandom calls the getrandom system call.
+func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) {
+	if len(p) == 0 {
+		return 0, nil
+	}
+	if atomic.LoadInt32(&getrandomUnsupported) != 0 {
+		return 0, syscall.ENOSYS
+	}
+	r1, _, errno := syscall6(uintptr(unsafe.Pointer(&procGetrandom)),
+		3,
+		uintptr(unsafe.Pointer(&p[0])),
+		uintptr(len(p)),
+		uintptr(flags),
+		0, 0, 0)
+	if errno != 0 {
+		if errno == syscall.ENOSYS {
+			atomic.StoreInt32(&getrandomUnsupported, 1)
+		}
+		return 0, errno
+	}
+	return int(r1), nil
+}
diff --git a/src/internal/syscall/unix/nonblocking.go b/src/internal/syscall/unix/nonblocking.go
index db25fcc..a22986c 100644
--- a/src/internal/syscall/unix/nonblocking.go
+++ b/src/internal/syscall/unix/nonblocking.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || linux || netbsd || openbsd
 // +build dragonfly freebsd linux netbsd openbsd
 
 package unix
diff --git a/src/internal/syscall/unix/nonblocking_js.go b/src/internal/syscall/unix/nonblocking_js.go
index a360b53..a5a5080 100644
--- a/src/internal/syscall/unix/nonblocking_js.go
+++ b/src/internal/syscall/unix/nonblocking_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package unix
diff --git a/src/internal/syscall/unix/nonblocking_libc.go b/src/internal/syscall/unix/nonblocking_libc.go
index 37cc794..d9565ef 100644
--- a/src/internal/syscall/unix/nonblocking_libc.go
+++ b/src/internal/syscall/unix/nonblocking_libc.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || solaris
 // +build aix darwin solaris
 
 package unix
diff --git a/src/internal/syscall/unix/pipe2_illumos.go b/src/internal/syscall/unix/pipe2_illumos.go
index f3ac8d2..b0aac89 100644
--- a/src/internal/syscall/unix/pipe2_illumos.go
+++ b/src/internal/syscall/unix/pipe2_illumos.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build illumos
 // +build illumos
 
 package unix
diff --git a/src/internal/syscall/unix/sysnum_linux_generic.go b/src/internal/syscall/unix/sysnum_linux_generic.go
index f48da40..a760254 100644
--- a/src/internal/syscall/unix/sysnum_linux_generic.go
+++ b/src/internal/syscall/unix/sysnum_linux_generic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (arm64 || riscv64)
 // +build linux
 // +build arm64 riscv64
 
diff --git a/src/internal/syscall/unix/sysnum_linux_mips64x.go b/src/internal/syscall/unix/sysnum_linux_mips64x.go
index 6680942..f353d4d 100644
--- a/src/internal/syscall/unix/sysnum_linux_mips64x.go
+++ b/src/internal/syscall/unix/sysnum_linux_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 package unix
diff --git a/src/internal/syscall/unix/sysnum_linux_mipsx.go b/src/internal/syscall/unix/sysnum_linux_mipsx.go
index 185d832..4ed4715 100644
--- a/src/internal/syscall/unix/sysnum_linux_mipsx.go
+++ b/src/internal/syscall/unix/sysnum_linux_mipsx.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 package unix
diff --git a/src/internal/syscall/unix/sysnum_linux_ppc64x.go b/src/internal/syscall/unix/sysnum_linux_ppc64x.go
index 576937e..b484ffe 100644
--- a/src/internal/syscall/unix/sysnum_linux_ppc64x.go
+++ b/src/internal/syscall/unix/sysnum_linux_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 package unix
diff --git a/src/internal/syscall/unix/writev_illumos.go b/src/internal/syscall/unix/writev_illumos.go
index eb7973d..f60949f 100644
--- a/src/internal/syscall/unix/writev_illumos.go
+++ b/src/internal/syscall/unix/writev_illumos.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build illumos
 // +build illumos
 
 package unix
diff --git a/src/internal/testenv/testenv_cgo.go b/src/internal/testenv/testenv_cgo.go
index e3d4d16..02f08f5 100644
--- a/src/internal/testenv/testenv_cgo.go
+++ b/src/internal/testenv/testenv_cgo.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo
 // +build cgo
 
 package testenv
diff --git a/src/internal/testenv/testenv_notwin.go b/src/internal/testenv/testenv_notwin.go
index ccb5d55..846ec93 100644
--- a/src/internal/testenv/testenv_notwin.go
+++ b/src/internal/testenv/testenv_notwin.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows
 // +build !windows
 
 package testenv
diff --git a/src/internal/trace/parser.go b/src/internal/trace/parser.go
index c371ff3..254f201 100644
--- a/src/internal/trace/parser.go
+++ b/src/internal/trace/parser.go
@@ -1042,8 +1042,8 @@
 	EvGoSysBlock        = 30 // syscall blocks [timestamp]
 	EvGoWaiting         = 31 // denotes that goroutine is blocked when tracing starts [timestamp, goroutine id]
 	EvGoInSyscall       = 32 // denotes that goroutine is in syscall when tracing starts [timestamp, goroutine id]
-	EvHeapAlloc         = 33 // memstats.heap_live change [timestamp, heap_alloc]
-	EvNextGC            = 34 // memstats.next_gc change [timestamp, next_gc]
+	EvHeapAlloc         = 33 // gcController.heapLive change [timestamp, heap live bytes]
+	EvHeapGoal          = 34 // gcController.heapGoal change [timestamp, heap goal bytes]
 	EvTimerGoroutine    = 35 // denotes timer goroutine [timer goroutine id]
 	EvFutileWakeup      = 36 // denotes that the previous wakeup of this goroutine was futile [timestamp]
 	EvString            = 37 // string dictionary entry [ID, length, string]
@@ -1102,7 +1102,7 @@
 	EvGoWaiting:         {"GoWaiting", 1005, false, []string{"g"}, nil},
 	EvGoInSyscall:       {"GoInSyscall", 1005, false, []string{"g"}, nil},
 	EvHeapAlloc:         {"HeapAlloc", 1005, false, []string{"mem"}, nil},
-	EvNextGC:            {"NextGC", 1005, false, []string{"mem"}, nil},
+	EvHeapGoal:          {"HeapGoal", 1005, false, []string{"mem"}, nil},
 	EvTimerGoroutine:    {"TimerGoroutine", 1005, false, []string{"g"}, nil}, // in 1.5 format it was {"g", "unused"}
 	EvFutileWakeup:      {"FutileWakeup", 1005, false, []string{}, nil},
 	EvString:            {"String", 1007, false, []string{}, nil},
diff --git a/src/io/example_test.go b/src/io/example_test.go
index 6d338ac..a18df9f 100644
--- a/src/io/example_test.go
+++ b/src/io/example_test.go
@@ -103,7 +103,9 @@
 }
 
 func ExampleWriteString() {
-	io.WriteString(os.Stdout, "Hello World")
+	if _, err := io.WriteString(os.Stdout, "Hello World"); err != nil {
+		log.Fatal(err)
+	}
 
 	// Output: Hello World
 }
diff --git a/src/io/fs/example_test.go b/src/io/fs/example_test.go
new file mode 100644
index 0000000..c902703
--- /dev/null
+++ b/src/io/fs/example_test.go
@@ -0,0 +1,25 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fs_test
+
+import (
+	"fmt"
+	"io/fs"
+	"log"
+	"os"
+)
+
+func ExampleWalkDir() {
+	root := "/usr/local/go/bin"
+	fileSystem := os.DirFS(root)
+
+	fs.WalkDir(fileSystem, ".", func(path string, d fs.DirEntry, err error) error {
+		if err != nil {
+			log.Fatal(err)
+		}
+		fmt.Println(path)
+		return nil
+	})
+}
diff --git a/src/io/fs/fs.go b/src/io/fs/fs.go
index 3d2e2ee..e603afa 100644
--- a/src/io/fs/fs.go
+++ b/src/io/fs/fs.go
@@ -73,8 +73,8 @@
 
 // A File provides access to a single file.
 // The File interface is the minimum implementation required of the file.
-// A file may implement additional interfaces, such as
-// ReadDirFile, ReaderAt, or Seeker, to provide additional or optimized functionality.
+// Directory files should also implement ReadDirFile.
+// A file may implement io.ReaderAt or io.Seeker as optimizations.
 type File interface {
 	Stat() (FileInfo, error)
 	Read([]byte) (int, error)
@@ -86,7 +86,7 @@
 type DirEntry interface {
 	// Name returns the name of the file (or subdirectory) described by the entry.
 	// This name is only the final element of the path (the base name), not the entire path.
-	// For example, Name would return "hello.go" not "/home/gopher/hello.go".
+	// For example, Name would return "hello.go" not "home/gopher/hello.go".
 	Name() string
 
 	// IsDir reports whether the entry describes a directory.
diff --git a/src/io/fs/readdir.go b/src/io/fs/readdir.go
index 3a5aa6d..2b10ddb 100644
--- a/src/io/fs/readdir.go
+++ b/src/io/fs/readdir.go
@@ -45,3 +45,33 @@
 	sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
 	return list, err
 }
+
+// dirInfo is a DirEntry based on a FileInfo.
+type dirInfo struct {
+	fileInfo FileInfo
+}
+
+func (di dirInfo) IsDir() bool {
+	return di.fileInfo.IsDir()
+}
+
+func (di dirInfo) Type() FileMode {
+	return di.fileInfo.Mode().Type()
+}
+
+func (di dirInfo) Info() (FileInfo, error) {
+	return di.fileInfo, nil
+}
+
+func (di dirInfo) Name() string {
+	return di.fileInfo.Name()
+}
+
+// FileInfoToDirEntry returns a DirEntry that returns information from info.
+// If info is nil, FileInfoToDirEntry returns nil.
+func FileInfoToDirEntry(info FileInfo) DirEntry {
+	if info == nil {
+		return nil
+	}
+	return dirInfo{fileInfo: info}
+}
diff --git a/src/io/fs/readdir_test.go b/src/io/fs/readdir_test.go
index 405bfa6..a2b2c12 100644
--- a/src/io/fs/readdir_test.go
+++ b/src/io/fs/readdir_test.go
@@ -6,7 +6,10 @@
 
 import (
 	. "io/fs"
+	"os"
 	"testing"
+	"testing/fstest"
+	"time"
 )
 
 type readDirOnly struct{ ReadDirFS }
@@ -41,3 +44,50 @@
 	dirs, err = ReadDir(sub, ".")
 	check("sub(.)", dirs, err)
 }
+
+func TestFileInfoToDirEntry(t *testing.T) {
+	testFs := fstest.MapFS{
+		"notadir.txt": {
+			Data:    []byte("hello, world"),
+			Mode:    0,
+			ModTime: time.Now(),
+			Sys:     &sysValue,
+		},
+		"adir": {
+			Data:    nil,
+			Mode:    os.ModeDir,
+			ModTime: time.Now(),
+			Sys:     &sysValue,
+		},
+	}
+
+	tests := []struct {
+		path     string
+		wantMode FileMode
+		wantDir  bool
+	}{
+		{path: "notadir.txt", wantMode: 0, wantDir: false},
+		{path: "adir", wantMode: os.ModeDir, wantDir: true},
+	}
+
+	for _, test := range tests {
+		test := test
+		t.Run(test.path, func(t *testing.T) {
+			fi, err := Stat(testFs, test.path)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			dirEntry := FileInfoToDirEntry(fi)
+			if g, w := dirEntry.Type(), test.wantMode; g != w {
+				t.Errorf("FileMode mismatch: got=%v, want=%v", g, w)
+			}
+			if g, w := dirEntry.Name(), test.path; g != w {
+				t.Errorf("Name mismatch: got=%v, want=%v", g, w)
+			}
+			if g, w := dirEntry.IsDir(), test.wantDir; g != w {
+				t.Errorf("IsDir mismatch: got=%v, want=%v", g, w)
+			}
+		})
+	}
+}
diff --git a/src/io/fs/readfile.go b/src/io/fs/readfile.go
index 7ee9ead..d3c181c 100644
--- a/src/io/fs/readfile.go
+++ b/src/io/fs/readfile.go
@@ -15,6 +15,9 @@
 	// A successful call returns a nil error, not io.EOF.
 	// (Because ReadFile reads the whole file, the expected EOF
 	// from the final Read is not treated as an error to be reported.)
+	//
+	// The caller is permitted to modify the returned byte slice.
+	// This method should return a copy of the underlying data.
 	ReadFile(name string) ([]byte, error)
 }
 
diff --git a/src/io/fs/sub.go b/src/io/fs/sub.go
index 64cdffe..ae20e03 100644
--- a/src/io/fs/sub.go
+++ b/src/io/fs/sub.go
@@ -19,10 +19,10 @@
 
 // Sub returns an FS corresponding to the subtree rooted at fsys's dir.
 //
-// If fs implements SubFS, Sub calls returns fsys.Sub(dir).
-// Otherwise, if dir is ".", Sub returns fsys unchanged.
+// If dir is ".", Sub returns fsys unchanged.
+// Otherwise, if fs implements SubFS, Sub returns fsys.Sub(dir).
 // Otherwise, Sub returns a new FS implementation sub that,
-// in effect, implements sub.Open(dir) as fsys.Open(path.Join(dir, name)).
+// in effect, implements sub.Open(name) as fsys.Open(path.Join(dir, name)).
 // The implementation also translates calls to ReadDir, ReadFile, and Glob appropriately.
 //
 // Note that Sub(os.DirFS("/"), "prefix") is equivalent to os.DirFS("/prefix")
@@ -68,7 +68,7 @@
 	return "", false
 }
 
-// fixErr shortens any reported names in PathErrors by stripping dir.
+// fixErr shortens any reported names in PathErrors by stripping f.dir.
 func (f *subFS) fixErr(err error) error {
 	if e, ok := err.(*PathError); ok {
 		if short, ok := f.shorten(e.Path); ok {
@@ -125,3 +125,14 @@
 	}
 	return list, f.fixErr(err)
 }
+
+func (f *subFS) Sub(dir string) (FS, error) {
+	if dir == "." {
+		return f, nil
+	}
+	full, err := f.fullName("sub", dir)
+	if err != nil {
+		return nil, err
+	}
+	return &subFS{f.fsys, full}, nil
+}
diff --git a/src/io/fs/walk_test.go b/src/io/fs/walk_test.go
index ebc4e50..5e127e7 100644
--- a/src/io/fs/walk_test.go
+++ b/src/io/fs/walk_test.go
@@ -6,7 +6,6 @@
 
 import (
 	. "io/fs"
-	"io/ioutil"
 	"os"
 	pathpkg "path"
 	"testing"
@@ -96,11 +95,7 @@
 }
 
 func TestWalkDir(t *testing.T) {
-	tmpDir, err := ioutil.TempDir("", "TestWalk")
-	if err != nil {
-		t.Fatal("creating temp dir:", err)
-	}
-	defer os.RemoveAll(tmpDir)
+	tmpDir := t.TempDir()
 
 	origDir, err := os.Getwd()
 	if err != nil {
diff --git a/src/io/io.go b/src/io/io.go
index ffd3ced..2724321 100644
--- a/src/io/io.go
+++ b/src/io/io.go
@@ -566,7 +566,7 @@
 	return
 }
 
-// Discard is an Writer on which all Write calls succeed
+// Discard is a Writer on which all Write calls succeed
 // without doing anything.
 var Discard Writer = discard{}
 
diff --git a/src/io/ioutil/export_test.go b/src/io/ioutil/export_test.go
deleted file mode 100644
index dff55f0..0000000
--- a/src/io/ioutil/export_test.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ioutil
-
-var ErrPatternHasSeparator = errPatternHasSeparator
diff --git a/src/io/ioutil/tempfile.go b/src/io/ioutil/tempfile.go
index af7c6fd..c43db2c 100644
--- a/src/io/ioutil/tempfile.go
+++ b/src/io/ioutil/tempfile.go
@@ -5,38 +5,9 @@
 package ioutil
 
 import (
-	"errors"
 	"os"
-	"path/filepath"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
 )
 
-// Random number state.
-// We generate random temporary file names so that there's a good
-// chance the file doesn't exist yet - keeps the number of tries in
-// TempFile to a minimum.
-var rand uint32
-var randmu sync.Mutex
-
-func reseed() uint32 {
-	return uint32(time.Now().UnixNano() + int64(os.Getpid()))
-}
-
-func nextRandom() string {
-	randmu.Lock()
-	r := rand
-	if r == 0 {
-		r = reseed()
-	}
-	r = r*1664525 + 1013904223 // constants from Numerical Recipes
-	rand = r
-	randmu.Unlock()
-	return strconv.Itoa(int(1e9 + r%1e9))[1:]
-}
-
 // TempFile creates a new temporary file in the directory dir,
 // opens the file for reading and writing, and returns the resulting *os.File.
 // The filename is generated by taking pattern and adding a random
@@ -48,48 +19,10 @@
 // will not choose the same file. The caller can use f.Name()
 // to find the pathname of the file. It is the caller's responsibility
 // to remove the file when no longer needed.
+//
+// As of Go 1.17, this function simply calls os.CreateTemp.
 func TempFile(dir, pattern string) (f *os.File, err error) {
-	if dir == "" {
-		dir = os.TempDir()
-	}
-
-	prefix, suffix, err := prefixAndSuffix(pattern)
-	if err != nil {
-		return
-	}
-
-	nconflict := 0
-	for i := 0; i < 10000; i++ {
-		name := filepath.Join(dir, prefix+nextRandom()+suffix)
-		f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
-		if os.IsExist(err) {
-			if nconflict++; nconflict > 10 {
-				randmu.Lock()
-				rand = reseed()
-				randmu.Unlock()
-			}
-			continue
-		}
-		break
-	}
-	return
-}
-
-var errPatternHasSeparator = errors.New("pattern contains path separator")
-
-// prefixAndSuffix splits pattern by the last wildcard "*", if applicable,
-// returning prefix as the part before "*" and suffix as the part after "*".
-func prefixAndSuffix(pattern string) (prefix, suffix string, err error) {
-	if strings.ContainsRune(pattern, os.PathSeparator) {
-		err = errPatternHasSeparator
-		return
-	}
-	if pos := strings.LastIndex(pattern, "*"); pos != -1 {
-		prefix, suffix = pattern[:pos], pattern[pos+1:]
-	} else {
-		prefix = pattern
-	}
-	return
+	return os.CreateTemp(dir, pattern)
 }
 
 // TempDir creates a new temporary directory in the directory dir.
@@ -101,37 +34,8 @@
 // Multiple programs calling TempDir simultaneously
 // will not choose the same directory. It is the caller's responsibility
 // to remove the directory when no longer needed.
+//
+// As of Go 1.17, this function simply calls os.MkdirTemp.
 func TempDir(dir, pattern string) (name string, err error) {
-	if dir == "" {
-		dir = os.TempDir()
-	}
-
-	prefix, suffix, err := prefixAndSuffix(pattern)
-	if err != nil {
-		return
-	}
-
-	nconflict := 0
-	for i := 0; i < 10000; i++ {
-		try := filepath.Join(dir, prefix+nextRandom()+suffix)
-		err = os.Mkdir(try, 0700)
-		if os.IsExist(err) {
-			if nconflict++; nconflict > 10 {
-				randmu.Lock()
-				rand = reseed()
-				randmu.Unlock()
-			}
-			continue
-		}
-		if os.IsNotExist(err) {
-			if _, err := os.Stat(dir); os.IsNotExist(err) {
-				return "", err
-			}
-		}
-		if err == nil {
-			name = try
-		}
-		break
-	}
-	return
+	return os.MkdirTemp(dir, pattern)
 }
diff --git a/src/io/ioutil/tempfile_test.go b/src/io/ioutil/tempfile_test.go
index 440c7cf..5cef18c 100644
--- a/src/io/ioutil/tempfile_test.go
+++ b/src/io/ioutil/tempfile_test.go
@@ -50,6 +50,9 @@
 	}
 }
 
+// This string is from os.errPatternHasSeparator.
+const patternHasSeparator = "pattern contains path separator"
+
 func TestTempFile_BadPattern(t *testing.T) {
 	tmpDir, err := TempDir("", t.Name())
 	if err != nil {
@@ -81,9 +84,8 @@
 			if tt.wantErr {
 				if err == nil {
 					t.Errorf("Expected an error for pattern %q", tt.pattern)
-				}
-				if g, w := err, ErrPatternHasSeparator; g != w {
-					t.Errorf("Error mismatch: got %#v, want %#v for pattern %q", g, w, tt.pattern)
+				} else if !strings.Contains(err.Error(), patternHasSeparator) {
+					t.Errorf("Error mismatch: got %#v, want %q for pattern %q", err, patternHasSeparator, tt.pattern)
 				}
 			} else if err != nil {
 				t.Errorf("Unexpected error %v for pattern %q", err, tt.pattern)
@@ -183,9 +185,8 @@
 			if tt.wantErr {
 				if err == nil {
 					t.Errorf("Expected an error for pattern %q", tt.pattern)
-				}
-				if g, w := err, ErrPatternHasSeparator; g != w {
-					t.Errorf("Error mismatch: got %#v, want %#v for pattern %q", g, w, tt.pattern)
+				} else if !strings.Contains(err.Error(), patternHasSeparator) {
+					t.Errorf("Error mismatch: got %#v, want %q for pattern %q", err, patternHasSeparator, tt.pattern)
 				}
 			} else if err != nil {
 				t.Errorf("Unexpected error %v for pattern %q", err, tt.pattern)
diff --git a/src/log/syslog/example_test.go b/src/log/syslog/example_test.go
index 4288d37..9939765 100644
--- a/src/log/syslog/example_test.go
+++ b/src/log/syslog/example_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows && !plan9
 // +build !windows,!plan9
 
 package syslog_test
diff --git a/src/log/syslog/syslog.go b/src/log/syslog/syslog.go
index 97c10f3..6abd4ad 100644
--- a/src/log/syslog/syslog.go
+++ b/src/log/syslog/syslog.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows && !plan9
 // +build !windows,!plan9
 
 package syslog
diff --git a/src/log/syslog/syslog_test.go b/src/log/syslog/syslog_test.go
index 207bcf5..62c6250 100644
--- a/src/log/syslog/syslog_test.go
+++ b/src/log/syslog/syslog_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows && !plan9 && !js
 // +build !windows,!plan9,!js
 
 package syslog
diff --git a/src/log/syslog/syslog_unix.go b/src/log/syslog/syslog_unix.go
index a64eed2..2e45f07 100644
--- a/src/log/syslog/syslog_unix.go
+++ b/src/log/syslog/syslog_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows && !plan9
 // +build !windows,!plan9
 
 package syslog
diff --git a/src/make.bash b/src/make.bash
index b58f27b..7986125 100755
--- a/src/make.bash
+++ b/src/make.bash
@@ -130,12 +130,12 @@
 	export CGO_ENABLED=0
 fi
 
-# On Alpine Linux, use the musl dynamic linker/loader
-if [ -f "/etc/alpine-release" ]; then
-	if type readelf >/dev/null 2>&1; then
-		echo "int main() { return 0; }" | ${CC:-gcc} -o ./test-alpine-ldso -x c -
-		export GO_LDSO=$(readelf -l ./test-alpine-ldso | grep 'interpreter:' | sed -e 's/^.*interpreter: \(.*\)[]]/\1/')
-		rm -f ./test-alpine-ldso
+# Test which linker/loader our system is using, if GO_LDSO is not set.
+if [ -z "$GO_LDSO" ] && type readelf >/dev/null 2>&1; then
+	if echo "int main() { return 0; }" | ${CC:-cc} -o ./test-musl-ldso -x c - >/dev/null 2>&1; then
+		LDSO=$(readelf -l ./test-musl-ldso | grep 'interpreter:' | sed -e 's/^.*interpreter: \(.*\)[]]/\1/') >/dev/null 2>&1
+		[ -z "$LDSO" ] || export GO_LDSO="$LDSO"
+		rm -f ./test-musl-ldso
 	fi
 fi
 
@@ -203,16 +203,10 @@
 	exit 0
 fi
 
-buildall="-a"
-if [ "$1" = "--no-clean" ]; then
-	buildall=""
-	shift
-fi
-
 # 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 "$@"
+./cmd/dist/dist bootstrap -a $vflag $GO_DISTFLAGS "$@"
 rm -f ./cmd/dist/dist
 
 # DO NOT ADD ANY NEW CODE HERE.
diff --git a/src/make.bat b/src/make.bat
index b4a8e70..8f2825b 100644
--- a/src/make.bat
+++ b/src/make.bat
@@ -112,20 +112,20 @@
 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=

-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

+set bootstrapflags=

+if x%1==x--no-clean set bootstrapflags=--no-clean

+if x%2==x--no-clean set bootstrapflags=--no-clean

+if x%3==x--no-clean set bootstrapflags=--no-clean

+if x%4==x--no-clean set bootstrapflags=--no-clean

+if x%1==x--no-banner set bootstrapflags=%bootstrapflags% --no-banner

+if x%2==x--no-banner set bootstrapflags=%bootstrapflags% --no-banner

+if x%3==x--no-banner set bootstrapflags=%bootstrapflags% --no-banner

+if x%4==x--no-banner set bootstrapflags=%bootstrapflags% --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.exe bootstrap %vflag% %buildall%

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

 if errorlevel 1 goto fail

 del .\cmd\dist\dist.exe

 goto end

diff --git a/src/make.rc b/src/make.rc
index f5e57e9..7bdc7de 100755
--- a/src/make.rc
+++ b/src/make.rc
@@ -92,15 +92,10 @@
 	exit
 }
 
-buildall = -a
-if(~ $1 --no-clean) {
-	buildall = ()
-	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 $*
+./cmd/dist/dist bootstrap -a $vflag $*
 rm -f ./cmd/dist/dist
 
 # DO NOT ADD ANY NEW CODE HERE.
diff --git a/src/math/acosh.go b/src/math/acosh.go
index 41ca871..f74e0b6 100644
--- a/src/math/acosh.go
+++ b/src/math/acosh.go
@@ -39,7 +39,12 @@
 //	Acosh(+Inf) = +Inf
 //	Acosh(x) = NaN if x < 1
 //	Acosh(NaN) = NaN
-func Acosh(x float64) float64
+func Acosh(x float64) float64 {
+	if haveArchAcosh {
+		return archAcosh(x)
+	}
+	return acosh(x)
+}
 
 func acosh(x float64) float64 {
 	const Large = 1 << 28 // 2**28
diff --git a/src/math/all_test.go b/src/math/all_test.go
index 3aae037..55c805e 100644
--- a/src/math/all_test.go
+++ b/src/math/all_test.go
@@ -2067,6 +2067,21 @@
 	{-7.751454006381804e-05, 5.588653777189071e-308, -2.2207280111272877e-308, -2.2211612130544025e-308},
 }
 
+var sqrt32 = []float32{
+	0,
+	float32(Copysign(0, -1)),
+	float32(NaN()),
+	float32(Inf(1)),
+	float32(Inf(-1)),
+	1,
+	2,
+	-2,
+	4.9790119248836735e+00,
+	7.7388724745781045e+00,
+	-2.7688005719200159e-01,
+	-5.0106036182710749e+00,
+}
+
 func tolerance(a, b, e float64) bool {
 	// Multiplying by e here can underflow denormal values to zero.
 	// Check a==b so that at least if a and b are small and identical
@@ -3181,6 +3196,34 @@
 	}
 }
 
+func TestFloatMinima(t *testing.T) {
+	if q := float32(SmallestNonzeroFloat32 / 2); q != 0 {
+		t.Errorf("float32(SmallestNonzeroFloat32 / 2) = %g, want 0", q)
+	}
+	if q := float64(SmallestNonzeroFloat64 / 2); q != 0 {
+		t.Errorf("float64(SmallestNonzeroFloat64 / 2) = %g, want 0", q)
+	}
+}
+
+var indirectSqrt = Sqrt
+
+// TestFloat32Sqrt checks the correctness of the float32 square root optimization result.
+func TestFloat32Sqrt(t *testing.T) {
+	for _, v := range sqrt32 {
+		want := float32(indirectSqrt(float64(v)))
+		got := float32(Sqrt(float64(v)))
+		if IsNaN(float64(want)) {
+			if !IsNaN(float64(got)) {
+				t.Errorf("got=%#v want=NaN, v=%#v", got, v)
+			}
+			continue
+		}
+		if got != want {
+			t.Errorf("got=%#v want=%#v, v=%#v", got, want, v)
+		}
+	}
+}
+
 // Benchmarks
 
 // Global exported variables are used to store the
diff --git a/src/math/arith_s390x.go b/src/math/arith_s390x.go
index 90a7d4f..129156a 100644
--- a/src/math/arith_s390x.go
+++ b/src/math/arith_s390x.go
@@ -6,72 +6,165 @@
 
 import "internal/cpu"
 
-func log10TrampolineSetup(x float64) float64
-func log10Asm(x float64) float64
-
-func cosTrampolineSetup(x float64) float64
-func cosAsm(x float64) float64
-
-func coshTrampolineSetup(x float64) float64
-func coshAsm(x float64) float64
-
-func sinTrampolineSetup(x float64) float64
-func sinAsm(x float64) float64
-
-func sinhTrampolineSetup(x float64) float64
-func sinhAsm(x float64) float64
-
-func tanhTrampolineSetup(x float64) float64
-func tanhAsm(x float64) float64
-
-func log1pTrampolineSetup(x float64) float64
-func log1pAsm(x float64) float64
-
-func atanhTrampolineSetup(x float64) float64
-func atanhAsm(x float64) float64
-
-func acosTrampolineSetup(x float64) float64
-func acosAsm(x float64) float64
-
-func acoshTrampolineSetup(x float64) float64
-func acoshAsm(x float64) float64
-
-func asinTrampolineSetup(x float64) float64
-func asinAsm(x float64) float64
-
-func asinhTrampolineSetup(x float64) float64
-func asinhAsm(x float64) float64
-
-func erfTrampolineSetup(x float64) float64
-func erfAsm(x float64) float64
-
-func erfcTrampolineSetup(x float64) float64
-func erfcAsm(x float64) float64
-
-func atanTrampolineSetup(x float64) float64
-func atanAsm(x float64) float64
-
-func atan2TrampolineSetup(x, y float64) float64
-func atan2Asm(x, y float64) float64
-
-func cbrtTrampolineSetup(x float64) float64
-func cbrtAsm(x float64) float64
+func expTrampolineSetup(x float64) float64
+func expAsm(x float64) float64
 
 func logTrampolineSetup(x float64) float64
 func logAsm(x float64) float64
 
+// Below here all functions are grouped in stubs.go for other
+// architectures.
+
+const haveArchLog10 = true
+
+func archLog10(x float64) float64
+func log10TrampolineSetup(x float64) float64
+func log10Asm(x float64) float64
+
+const haveArchCos = true
+
+func archCos(x float64) float64
+func cosTrampolineSetup(x float64) float64
+func cosAsm(x float64) float64
+
+const haveArchCosh = true
+
+func archCosh(x float64) float64
+func coshTrampolineSetup(x float64) float64
+func coshAsm(x float64) float64
+
+const haveArchSin = true
+
+func archSin(x float64) float64
+func sinTrampolineSetup(x float64) float64
+func sinAsm(x float64) float64
+
+const haveArchSinh = true
+
+func archSinh(x float64) float64
+func sinhTrampolineSetup(x float64) float64
+func sinhAsm(x float64) float64
+
+const haveArchTanh = true
+
+func archTanh(x float64) float64
+func tanhTrampolineSetup(x float64) float64
+func tanhAsm(x float64) float64
+
+const haveArchLog1p = true
+
+func archLog1p(x float64) float64
+func log1pTrampolineSetup(x float64) float64
+func log1pAsm(x float64) float64
+
+const haveArchAtanh = true
+
+func archAtanh(x float64) float64
+func atanhTrampolineSetup(x float64) float64
+func atanhAsm(x float64) float64
+
+const haveArchAcos = true
+
+func archAcos(x float64) float64
+func acosTrampolineSetup(x float64) float64
+func acosAsm(x float64) float64
+
+const haveArchAcosh = true
+
+func archAcosh(x float64) float64
+func acoshTrampolineSetup(x float64) float64
+func acoshAsm(x float64) float64
+
+const haveArchAsin = true
+
+func archAsin(x float64) float64
+func asinTrampolineSetup(x float64) float64
+func asinAsm(x float64) float64
+
+const haveArchAsinh = true
+
+func archAsinh(x float64) float64
+func asinhTrampolineSetup(x float64) float64
+func asinhAsm(x float64) float64
+
+const haveArchErf = true
+
+func archErf(x float64) float64
+func erfTrampolineSetup(x float64) float64
+func erfAsm(x float64) float64
+
+const haveArchErfc = true
+
+func archErfc(x float64) float64
+func erfcTrampolineSetup(x float64) float64
+func erfcAsm(x float64) float64
+
+const haveArchAtan = true
+
+func archAtan(x float64) float64
+func atanTrampolineSetup(x float64) float64
+func atanAsm(x float64) float64
+
+const haveArchAtan2 = true
+
+func archAtan2(y, x float64) float64
+func atan2TrampolineSetup(x, y float64) float64
+func atan2Asm(x, y float64) float64
+
+const haveArchCbrt = true
+
+func archCbrt(x float64) float64
+func cbrtTrampolineSetup(x float64) float64
+func cbrtAsm(x float64) float64
+
+const haveArchTan = true
+
+func archTan(x float64) float64
 func tanTrampolineSetup(x float64) float64
 func tanAsm(x float64) float64
 
-func expTrampolineSetup(x float64) float64
-func expAsm(x float64) float64
+const haveArchExpm1 = true
 
+func archExpm1(x float64) float64
 func expm1TrampolineSetup(x float64) float64
 func expm1Asm(x float64) float64
 
+const haveArchPow = true
+
+func archPow(x, y float64) float64
 func powTrampolineSetup(x, y float64) float64
 func powAsm(x, y float64) float64
 
+const haveArchFrexp = false
+
+func archFrexp(x float64) (float64, int) {
+	panic("not implemented")
+}
+
+const haveArchLdexp = false
+
+func archLdexp(frac float64, exp int) float64 {
+	panic("not implemented")
+}
+
+const haveArchLog2 = false
+
+func archLog2(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchMod = false
+
+func archMod(x, y float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchRemainder = false
+
+func archRemainder(x, y float64) float64 {
+	panic("not implemented")
+}
+
 // hasVX reports whether the machine has the z/Architecture
 // vector facility installed and enabled.
 var hasVX = cpu.S390X.HasVX
diff --git a/src/math/asin.go b/src/math/asin.go
index 88b851e..989a741 100644
--- a/src/math/asin.go
+++ b/src/math/asin.go
@@ -16,7 +16,12 @@
 // Special cases are:
 //	Asin(±0) = ±0
 //	Asin(x) = NaN if x < -1 or x > 1
-func Asin(x float64) float64
+func Asin(x float64) float64 {
+	if haveArchAsin {
+		return archAsin(x)
+	}
+	return asin(x)
+}
 
 func asin(x float64) float64 {
 	if x == 0 {
@@ -48,7 +53,12 @@
 //
 // Special case is:
 //	Acos(x) = NaN if x < -1 or x > 1
-func Acos(x float64) float64
+func Acos(x float64) float64 {
+	if haveArchAcos {
+		return archAcos(x)
+	}
+	return acos(x)
+}
 
 func acos(x float64) float64 {
 	return Pi/2 - Asin(x)
diff --git a/src/math/asin_386.s b/src/math/asin_386.s
deleted file mode 100644
index 7dab390..0000000
--- a/src/math/asin_386.s
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Asin(x float64) float64
-TEXT ·Asin(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=sin(x)
-	FMOVD   F0, F1       // F0=sin(x), F1=sin(x)
-	FMULD   F0, F0       // F0=sin(x)*sin(x), F1=sin(x)
-	FLD1                 // F0=1, F1=sin(x)*sin(x), F2=sin(x)
-	FSUBRDP F0, F1       // F0=1-sin(x)*sin(x) (=cos(x)*cos(x)), F1=sin(x)
-	FSQRT                // F0=cos(x), F1=sin(x)
-	FPATAN               // F0=arcsin(sin(x))=x
-	FMOVDP  F0, ret+8(FP)
-	RET
-
-// func Acos(x float64) float64
-TEXT ·Acos(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=cos(x)
-	FMOVD   F0, F1       // F0=cos(x), F1=cos(x)
-	FMULD   F0, F0       // F0=cos(x)*cos(x), F1=cos(x)
-	FLD1                 // F0=1, F1=cos(x)*cos(x), F2=cos(x)
-	FSUBRDP F0, F1       // F0=1-cos(x)*cos(x) (=sin(x)*sin(x)), F1=cos(x)
-	FSQRT                // F0=sin(x), F1=cos(x)
-	FXCHD   F0, F1       // F0=cos(x), F1=sin(x)
-	FPATAN               // F0=arccos(cos(x))=x
-	FMOVDP	F0, ret+8(FP)
-	RET
diff --git a/src/math/asinh.go b/src/math/asinh.go
index 65ae4c6..6dcb241 100644
--- a/src/math/asinh.go
+++ b/src/math/asinh.go
@@ -36,7 +36,12 @@
 //	Asinh(±0) = ±0
 //	Asinh(±Inf) = ±Inf
 //	Asinh(NaN) = NaN
-func Asinh(x float64) float64
+func Asinh(x float64) float64 {
+	if haveArchAsinh {
+		return archAsinh(x)
+	}
+	return asinh(x)
+}
 
 func asinh(x float64) float64 {
 	const (
diff --git a/src/math/atan.go b/src/math/atan.go
index 7fcc90b..69af860 100644
--- a/src/math/atan.go
+++ b/src/math/atan.go
@@ -92,7 +92,12 @@
 // Special cases are:
 //      Atan(±0) = ±0
 //      Atan(±Inf) = ±Pi/2
-func Atan(x float64) float64
+func Atan(x float64) float64 {
+	if haveArchAtan {
+		return archAtan(x)
+	}
+	return atan(x)
+}
 
 func atan(x float64) float64 {
 	if x == 0 {
diff --git a/src/math/atan2.go b/src/math/atan2.go
index d84b332..11d7e81 100644
--- a/src/math/atan2.go
+++ b/src/math/atan2.go
@@ -26,7 +26,12 @@
 //	Atan2(y<0, -Inf) = -Pi
 //	Atan2(+Inf, x) = +Pi/2
 //	Atan2(-Inf, x) = -Pi/2
-func Atan2(y, x float64) float64
+func Atan2(y, x float64) float64 {
+	if haveArchAtan2 {
+		return archAtan2(y, x)
+	}
+	return atan2(y, x)
+}
 
 func atan2(y, x float64) float64 {
 	// special cases
diff --git a/src/math/atan2_386.s b/src/math/atan2_386.s
deleted file mode 100644
index 90d211b..0000000
--- a/src/math/atan2_386.s
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Atan2(y, x float64) float64	// =atan(y/x)
-TEXT ·Atan2(SB),NOSPLIT,$0
-	FMOVD   y+0(FP), F0  // F0=y
-	FMOVD   x+8(FP), F0  // F0=x, F1=y
-	FPATAN               // F0=atan(F1/F0)
-	FMOVDP  F0, ret+16(FP)
-	RET
diff --git a/src/math/atan_386.s b/src/math/atan_386.s
deleted file mode 100644
index 43e79b9..0000000
--- a/src/math/atan_386.s
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Atan(x float64) float64
-TEXT ·Atan(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=x
-	FLD1                 // F0=1, F1=x
-	FPATAN               // F0=atan(F1/F0)
-	FMOVDP  F0, ret+8(FP)
-	RET
diff --git a/src/math/atanh.go b/src/math/atanh.go
index 8904bd6..fe8bd6d 100644
--- a/src/math/atanh.go
+++ b/src/math/atanh.go
@@ -44,7 +44,12 @@
 //	Atanh(-1) = -Inf
 //	Atanh(x) = NaN if x < -1 or x > 1
 //	Atanh(NaN) = NaN
-func Atanh(x float64) float64
+func Atanh(x float64) float64 {
+	if haveArchAtanh {
+		return archAtanh(x)
+	}
+	return atanh(x)
+}
 
 func atanh(x float64) float64 {
 	const NearZero = 1.0 / (1 << 28) // 2**-28
diff --git a/src/math/big/arith.go b/src/math/big/arith.go
index 750ce8a..8f55c19 100644
--- a/src/math/big/arith.go
+++ b/src/math/big/arith.go
@@ -170,12 +170,16 @@
 	if len(z) == 0 {
 		return
 	}
+	if len(x) != len(z) {
+		// This is an invariant guaranteed by the caller.
+		panic("len(x) != len(z)")
+	}
 	s &= _W - 1 // hint to the compiler that shifts by s don't need guard code
 	ŝ := _W - s
 	ŝ &= _W - 1 // ditto
 	c = x[0] << ŝ
-	for i := 0; i < len(z)-1; i++ {
-		z[i] = x[i]>>s | x[i+1]<<ŝ
+	for i := 1; i < len(z); i++ {
+		z[i-1] = x[i-1]>>s | x[i]<<ŝ
 	}
 	z[len(z)-1] = x[len(z)-1] >> s
 	return
@@ -263,20 +267,6 @@
 	return Word(qq), Word(r0 >> s)
 }
 
-func divWVW(z []Word, xn Word, x []Word, y Word) (r Word) {
-	r = xn
-	if len(x) == 1 {
-		qq, rr := bits.Div(uint(r), uint(x[0]), uint(y))
-		z[0] = Word(qq)
-		return Word(rr)
-	}
-	rec := reciprocalWord(y)
-	for i := len(z) - 1; i >= 0; i-- {
-		z[i], r = divWW(r, x[i], y, rec)
-	}
-	return r
-}
-
 // reciprocalWord return the reciprocal of the divisor. rec = floor(( _B^2 - 1 ) / u - _B). u = d1 << nlz(d1).
 func reciprocalWord(d1 Word) Word {
 	u := uint(d1 << nlz(d1))
diff --git a/src/math/big/arith_386.s b/src/math/big/arith_386.s
index d0ea949..acf2b06 100644
--- a/src/math/big/arith_386.s
+++ b/src/math/big/arith_386.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !math_big_pure_go
 // +build !math_big_pure_go
 
 #include "textflag.h"
diff --git a/src/math/big/arith_amd64.go b/src/math/big/arith_amd64.go
index 1d2d37c..89108fe 100644
--- a/src/math/big/arith_amd64.go
+++ b/src/math/big/arith_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !math_big_pure_go
 // +build !math_big_pure_go
 
 package big
diff --git a/src/math/big/arith_amd64.s b/src/math/big/arith_amd64.s
index 61043ca..59be952 100644
--- a/src/math/big/arith_amd64.s
+++ b/src/math/big/arith_amd64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !math_big_pure_go
 // +build !math_big_pure_go
 
 #include "textflag.h"
diff --git a/src/math/big/arith_arm.s b/src/math/big/arith_arm.s
index cbf7445..f2872d8 100644
--- a/src/math/big/arith_arm.s
+++ b/src/math/big/arith_arm.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !math_big_pure_go
 // +build !math_big_pure_go
 
 #include "textflag.h"
diff --git a/src/math/big/arith_arm64.s b/src/math/big/arith_arm64.s
index 22357d0..7bfe08e 100644
--- a/src/math/big/arith_arm64.s
+++ b/src/math/big/arith_arm64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !math_big_pure_go
 // +build !math_big_pure_go
 
 #include "textflag.h"
diff --git a/src/math/big/arith_decl.go b/src/math/big/arith_decl.go
index d519bdc..eea3d6b 100644
--- a/src/math/big/arith_decl.go
+++ b/src/math/big/arith_decl.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !math_big_pure_go
 // +build !math_big_pure_go
 
 package big
diff --git a/src/math/big/arith_decl_pure.go b/src/math/big/arith_decl_pure.go
index 5faa3bd..059f6f1 100644
--- a/src/math/big/arith_decl_pure.go
+++ b/src/math/big/arith_decl_pure.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build math_big_pure_go
 // +build math_big_pure_go
 
 package big
diff --git a/src/math/big/arith_decl_s390x.go b/src/math/big/arith_decl_s390x.go
index f1a69e1..4193f32 100644
--- a/src/math/big/arith_decl_s390x.go
+++ b/src/math/big/arith_decl_s390x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !math_big_pure_go
 // +build !math_big_pure_go
 
 package big
diff --git a/src/math/big/arith_mips64x.s b/src/math/big/arith_mips64x.s
index 804b9fe..4b5c502 100644
--- a/src/math/big/arith_mips64x.s
+++ b/src/math/big/arith_mips64x.s
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !math_big_pure_go,mips64 !math_big_pure_go,mips64le
+//go:build !math_big_pure_go && (mips64 || mips64le)
+// +build !math_big_pure_go
+// +build mips64 mips64le
 
 #include "textflag.h"
 
diff --git a/src/math/big/arith_mipsx.s b/src/math/big/arith_mipsx.s
index efdecb8..e72e6d6 100644
--- a/src/math/big/arith_mipsx.s
+++ b/src/math/big/arith_mipsx.s
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !math_big_pure_go,mips !math_big_pure_go,mipsle
+//go:build !math_big_pure_go && (mips || mipsle)
+// +build !math_big_pure_go
+// +build mips mipsle
 
 #include "textflag.h"
 
diff --git a/src/math/big/arith_ppc64x.s b/src/math/big/arith_ppc64x.s
index b299ccc..68c6286 100644
--- a/src/math/big/arith_ppc64x.s
+++ b/src/math/big/arith_ppc64x.s
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !math_big_pure_go,ppc64 !math_big_pure_go,ppc64le
+//go:build !math_big_pure_go && (ppc64 || ppc64le)
+// +build !math_big_pure_go
+// +build ppc64 ppc64le
 
 #include "textflag.h"
 
diff --git a/src/math/big/arith_riscv64.s b/src/math/big/arith_riscv64.s
index a2f7666..2e950dd 100644
--- a/src/math/big/arith_riscv64.s
+++ b/src/math/big/arith_riscv64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !math_big_pure_go && riscv64
 // +build !math_big_pure_go,riscv64
 
 #include "textflag.h"
diff --git a/src/math/big/arith_s390x.s b/src/math/big/arith_s390x.s
index caa4db0..ad822f7 100644
--- a/src/math/big/arith_s390x.s
+++ b/src/math/big/arith_s390x.s
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !math_big_pure_go,s390x
+//go:build !math_big_pure_go
+// +build !math_big_pure_go
 
 #include "textflag.h"
 
@@ -18,7 +19,7 @@
 	RET
 
 
-// DI = R3, CX = R4, SI = r10, r8 = r8, r9=r9, r10 = r2 , r11 = r5, r12 = r6, r13 = r7, r14 = r1 (R0 set to 0) + use R11
+// DI = R3, CX = R4, SI = r10, r8 = r8, r9=r9, r10 = r2, r11 = r5, r12 = r6, r13 = r7, r14 = r1 (R0 set to 0) + use R11
 // func addVV(z, x, y []Word) (c Word)
 
 TEXT ·addVV(SB), NOSPLIT, $0
@@ -288,7 +289,7 @@
 GLOBL subvectorfacility+0x00(SB), NOPTR, $8
 DATA subvectorfacility+0x00(SB)/8, $·subVV_check(SB)
 
-// DI = R3, CX = R4, SI = r10, r8 = r8, r9=r9, r10 = r2 , r11 = r5, r12 = r6, r13 = r7, r14 = r1 (R0 set to 0) + use R11
+// DI = R3, CX = R4, SI = r10, r8 = r8, r9=r9, r10 = r2, r11 = r5, r12 = r6, r13 = r7, r14 = r1 (R0 set to 0) + use R11
 // func subVV(z, x, y []Word) (c Word)
 // (same as addVV except for SUBC/SUBE instead of ADDC/ADDE and label names)
 TEXT ·subVV_vec(SB), NOSPLIT, $0
@@ -442,7 +443,7 @@
 	MOVD R4, c+72(FP) // return c
 	RET
 
-// DI = R3, CX = R4, SI = r10, r8 = r8, r9=r9, r10 = r2 , r11 = r5, r12 = r6, r13 = r7, r14 = r1 (R0 set to 0) + use R11
+// DI = R3, CX = R4, SI = r10, r8 = r8, r9=r9, r10 = r2, r11 = r5, r12 = r6, r13 = r7, r14 = r1 (R0 set to 0) + use R11
 // func subVV(z, x, y []Word) (c Word)
 // (same as addVV except for SUBC/SUBE instead of ADDC/ADDE and label names)
 TEXT ·subVV_novec(SB), NOSPLIT, $0
@@ -699,7 +700,7 @@
 TEXT ·shrVU(SB), NOSPLIT, $0
 	BR ·shrVU_g(SB)
 
-// CX = R4, r8 = r8, r9=r9, r10 = r2 , r11 = r5, DX = r3, AX = r6 , BX = R1 , (R0 set to 0) + use R11 + use R7 for i
+// CX = R4, r8 = r8, r9=r9, r10 = r2, r11 = r5, DX = r3, AX = r6, BX = R1, (R0 set to 0) + use R11 + use R7 for i
 // func mulAddVWW(z, x []Word, y, r Word) (c Word)
 TEXT ·mulAddVWW(SB), NOSPLIT, $0
 	MOVD z+0(FP), R2
@@ -729,7 +730,7 @@
 	RET
 
 // func addMulVVW(z, x []Word, y Word) (c Word)
-// CX = R4, r8 = r8, r9=r9, r10 = r2 , r11 = r5, AX = r11, DX = R6, r12=r12, BX = R1 , (R0 set to 0) + use R11 + use R7 for i
+// CX = R4, r8 = r8, r9=r9, r10 = r2, r11 = r5, AX = r11, DX = R6, r12=r12, BX = R1, (R0 set to 0) + use R11 + use R7 for i
 TEXT ·addMulVVW(SB), NOSPLIT, $0
 	MOVD z+0(FP), R2
 	MOVD x+24(FP), R8
diff --git a/src/math/big/arith_s390x_test.go b/src/math/big/arith_s390x_test.go
index ce6bca8..8375ddb 100644
--- a/src/math/big/arith_s390x_test.go
+++ b/src/math/big/arith_s390x_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build s390x && !math_big_pure_go
 // +build s390x,!math_big_pure_go
 
 package big
diff --git a/src/math/big/arith_test.go b/src/math/big/arith_test.go
index 2aca0ef..7b3427f 100644
--- a/src/math/big/arith_test.go
+++ b/src/math/big/arith_test.go
@@ -671,3 +671,27 @@
 		})
 	}
 }
+
+func BenchmarkNonZeroShifts(b *testing.B) {
+	for _, n := range benchSizes {
+		if isRaceBuilder && n > 1e3 {
+			continue
+		}
+		x := rndV(n)
+		s := uint(rand.Int63n(_W-2)) + 1 // avoid 0 and over-large shifts
+		z := make([]Word, n)
+		b.Run(fmt.Sprint(n), func(b *testing.B) {
+			b.SetBytes(int64(n * _W))
+			b.Run("shrVU", func(b *testing.B) {
+				for i := 0; i < b.N; i++ {
+					_ = shrVU(z, x, s)
+				}
+			})
+			b.Run("shlVU", func(b *testing.B) {
+				for i := 0; i < b.N; i++ {
+					_ = shlVU(z, x, s)
+				}
+			})
+		})
+	}
+}
diff --git a/src/math/big/arith_wasm.s b/src/math/big/arith_wasm.s
index add1064..e8605f1 100644
--- a/src/math/big/arith_wasm.s
+++ b/src/math/big/arith_wasm.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !math_big_pure_go
 // +build !math_big_pure_go
 
 #include "textflag.h"
diff --git a/src/math/big/int.go b/src/math/big/int.go
index 65f3248..7647346 100644
--- a/src/math/big/int.go
+++ b/src/math/big/int.go
@@ -425,7 +425,7 @@
 	return z.setFromScanner(strings.NewReader(s), base)
 }
 
-// setFromScanner implements SetString given an io.BytesScanner.
+// setFromScanner implements SetString given an io.ByteScanner.
 // 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 {
diff --git a/src/math/big/link_test.go b/src/math/big/link_test.go
index 42f9cef..6e33aa5 100644
--- a/src/math/big/link_test.go
+++ b/src/math/big/link_test.go
@@ -42,7 +42,7 @@
 	if err != nil {
 		t.Fatalf("nm: %v, %s", err, nm)
 	}
-	const want = "runtime.(*Frames).Next"
+	const want = "runtime.main"
 	if !bytes.Contains(nm, []byte(want)) {
 		// Test the test.
 		t.Errorf("expected symbol %q not found", want)
diff --git a/src/math/big/nat.go b/src/math/big/nat.go
index bbd6c88..140c619 100644
--- a/src/math/big/nat.go
+++ b/src/math/big/nat.go
@@ -631,48 +631,6 @@
 	return z.mul(nat(nil).mulRange(a, m), nat(nil).mulRange(m+1, b))
 }
 
-// q = (x-r)/y, with 0 <= r < y
-func (z nat) divW(x nat, y Word) (q nat, r Word) {
-	m := len(x)
-	switch {
-	case y == 0:
-		panic("division by zero")
-	case y == 1:
-		q = z.set(x) // result is x
-		return
-	case m == 0:
-		q = z[:0] // result is 0
-		return
-	}
-	// m > 0
-	z = z.make(m)
-	r = divWVW(z, 0, x, y)
-	q = z.norm()
-	return
-}
-
-func (z nat) div(z2, u, v nat) (q, r nat) {
-	if len(v) == 0 {
-		panic("division by zero")
-	}
-
-	if u.cmp(v) < 0 {
-		q = z[:0]
-		r = z2.set(u)
-		return
-	}
-
-	if len(v) == 1 {
-		var r2 Word
-		q, r2 = z.divW(u, v[0])
-		r = z2.setWord(r2)
-		return
-	}
-
-	q, r = z.divLarge(z2, u, v)
-	return
-}
-
 // getNat returns a *nat of len n. The contents may not be zero.
 // The pool holds *nat to avoid allocation when converting to interface{}.
 func getNat(n int) *nat {
@@ -693,276 +651,6 @@
 
 var natPool sync.Pool
 
-// q = (uIn-r)/vIn, with 0 <= r < vIn
-// Uses z as storage for q, and u as storage for r if possible.
-// See Knuth, Volume 2, section 4.3.1, Algorithm D.
-// Preconditions:
-//    len(vIn) >= 2
-//    len(uIn) >= len(vIn)
-//    u must not alias z
-func (z nat) divLarge(u, uIn, vIn nat) (q, r nat) {
-	n := len(vIn)
-	m := len(uIn) - n
-
-	// D1.
-	shift := nlz(vIn[n-1])
-	// do not modify vIn, it may be used by another goroutine simultaneously
-	vp := getNat(n)
-	v := *vp
-	shlVU(v, vIn, shift)
-
-	// u may safely alias uIn or vIn, the value of uIn is used to set u and vIn was already used
-	u = u.make(len(uIn) + 1)
-	u[len(uIn)] = shlVU(u[0:len(uIn)], uIn, shift)
-
-	// z may safely alias uIn or vIn, both values were used already
-	if alias(z, u) {
-		z = nil // z is an alias for u - cannot reuse
-	}
-	q = z.make(m + 1)
-
-	if n < divRecursiveThreshold {
-		q.divBasic(u, v)
-	} else {
-		q.divRecursive(u, v)
-	}
-	putNat(vp)
-
-	q = q.norm()
-	shrVU(u, u, shift)
-	r = u.norm()
-
-	return q, r
-}
-
-// divBasic performs word-by-word division of u by v.
-// The quotient is written in pre-allocated q.
-// The remainder overwrites input u.
-//
-// Precondition:
-// - q is large enough to hold the quotient u / v
-//   which has a maximum length of len(u)-len(v)+1.
-func (q nat) divBasic(u, v nat) {
-	n := len(v)
-	m := len(u) - n
-
-	qhatvp := getNat(n + 1)
-	qhatv := *qhatvp
-
-	// D2.
-	vn1 := v[n-1]
-	rec := reciprocalWord(vn1)
-	for j := m; j >= 0; j-- {
-		// D3.
-		qhat := Word(_M)
-		var ujn Word
-		if j+n < len(u) {
-			ujn = u[j+n]
-		}
-		if ujn != vn1 {
-			var rhat Word
-			qhat, rhat = divWW(ujn, u[j+n-1], vn1, rec)
-
-			// x1 | x2 = q̂v_{n-2}
-			vn2 := v[n-2]
-			x1, x2 := mulWW(qhat, vn2)
-			// test if q̂v_{n-2} > br̂ + u_{j+n-2}
-			ujn2 := u[j+n-2]
-			for greaterThan(x1, x2, rhat, ujn2) {
-				qhat--
-				prevRhat := rhat
-				rhat += vn1
-				// v[n-1] >= 0, so this tests for overflow.
-				if rhat < prevRhat {
-					break
-				}
-				x1, x2 = mulWW(qhat, vn2)
-			}
-		}
-
-		// D4.
-		// Compute the remainder u - (q̂*v) << (_W*j).
-		// The subtraction may overflow if q̂ estimate was off by one.
-		qhatv[n] = mulAddVWW(qhatv[0:n], v, qhat, 0)
-		qhl := len(qhatv)
-		if j+qhl > len(u) && qhatv[n] == 0 {
-			qhl--
-		}
-		c := subVV(u[j:j+qhl], u[j:], qhatv)
-		if c != 0 {
-			c := addVV(u[j:j+n], u[j:], v)
-			// If n == qhl, the carry from subVV and the carry from addVV
-			// cancel out and don't affect u[j+n].
-			if n < qhl {
-				u[j+n] += c
-			}
-			qhat--
-		}
-
-		if j == m && m == len(q) && qhat == 0 {
-			continue
-		}
-		q[j] = qhat
-	}
-
-	putNat(qhatvp)
-}
-
-const divRecursiveThreshold = 100
-
-// divRecursive performs word-by-word division of u by v.
-// The quotient is written in pre-allocated z.
-// The remainder overwrites input u.
-//
-// Precondition:
-// - len(z) >= len(u)-len(v)
-//
-// See Burnikel, Ziegler, "Fast Recursive Division", Algorithm 1 and 2.
-func (z nat) divRecursive(u, v nat) {
-	// Recursion depth is less than 2 log2(len(v))
-	// Allocate a slice of temporaries to be reused across recursion.
-	recDepth := 2 * bits.Len(uint(len(v)))
-	// large enough to perform Karatsuba on operands as large as v
-	tmp := getNat(3 * len(v))
-	temps := make([]*nat, recDepth)
-	z.clear()
-	z.divRecursiveStep(u, v, 0, tmp, temps)
-	for _, n := range temps {
-		if n != nil {
-			putNat(n)
-		}
-	}
-	putNat(tmp)
-}
-
-// divRecursiveStep computes the division of u by v.
-// - z must be large enough to hold the quotient
-// - the quotient will overwrite z
-// - the remainder will overwrite u
-func (z nat) divRecursiveStep(u, v nat, depth int, tmp *nat, temps []*nat) {
-	u = u.norm()
-	v = v.norm()
-
-	if len(u) == 0 {
-		z.clear()
-		return
-	}
-	n := len(v)
-	if n < divRecursiveThreshold {
-		z.divBasic(u, v)
-		return
-	}
-	m := len(u) - n
-	if m < 0 {
-		return
-	}
-
-	// Produce the quotient by blocks of B words.
-	// Division by v (length n) is done using a length n/2 division
-	// and a length n/2 multiplication for each block. The final
-	// complexity is driven by multiplication complexity.
-	B := n / 2
-
-	// Allocate a nat for qhat below.
-	if temps[depth] == nil {
-		temps[depth] = getNat(n)
-	} else {
-		*temps[depth] = temps[depth].make(B + 1)
-	}
-
-	j := m
-	for j > B {
-		// Divide u[j-B:j+n] by vIn. Keep remainder in u
-		// for next block.
-		//
-		// The following property will be used (Lemma 2):
-		// if u = u1 << s + u0
-		//    v = v1 << s + v0
-		// then floor(u1/v1) >= floor(u/v)
-		//
-		// Moreover, the difference is at most 2 if len(v1) >= len(u/v)
-		// We choose s = B-1 since len(v)-s >= B+1 >= len(u/v)
-		s := (B - 1)
-		// Except for the first step, the top bits are always
-		// a division remainder, so the quotient length is <= n.
-		uu := u[j-B:]
-
-		qhat := *temps[depth]
-		qhat.clear()
-		qhat.divRecursiveStep(uu[s:B+n], v[s:], depth+1, tmp, temps)
-		qhat = qhat.norm()
-		// Adjust the quotient:
-		//    u = u_h << s + u_l
-		//    v = v_h << s + v_l
-		//  u_h = q̂ v_h + rh
-		//    u = q̂ (v - v_l) + rh << s + u_l
-		// After the above step, u contains a remainder:
-		//    u = rh << s + u_l
-		// and we need to subtract q̂ v_l
-		//
-		// But it may be a bit too large, in which case q̂ needs to be smaller.
-		qhatv := tmp.make(3 * n)
-		qhatv.clear()
-		qhatv = qhatv.mul(qhat, v[:s])
-		for i := 0; i < 2; i++ {
-			e := qhatv.cmp(uu.norm())
-			if e <= 0 {
-				break
-			}
-			subVW(qhat, qhat, 1)
-			c := subVV(qhatv[:s], qhatv[:s], v[:s])
-			if len(qhatv) > s {
-				subVW(qhatv[s:], qhatv[s:], c)
-			}
-			addAt(uu[s:], v[s:], 0)
-		}
-		if qhatv.cmp(uu.norm()) > 0 {
-			panic("impossible")
-		}
-		c := subVV(uu[:len(qhatv)], uu[:len(qhatv)], qhatv)
-		if c > 0 {
-			subVW(uu[len(qhatv):], uu[len(qhatv):], c)
-		}
-		addAt(z, qhat, j-B)
-		j -= B
-	}
-
-	// Now u < (v<<B), compute lower bits in the same way.
-	// Choose shift = B-1 again.
-	s := B - 1
-	qhat := *temps[depth]
-	qhat.clear()
-	qhat.divRecursiveStep(u[s:].norm(), v[s:], depth+1, tmp, temps)
-	qhat = qhat.norm()
-	qhatv := tmp.make(3 * n)
-	qhatv.clear()
-	qhatv = qhatv.mul(qhat, v[:s])
-	// Set the correct remainder as before.
-	for i := 0; i < 2; i++ {
-		if e := qhatv.cmp(u.norm()); e > 0 {
-			subVW(qhat, qhat, 1)
-			c := subVV(qhatv[:s], qhatv[:s], v[:s])
-			if len(qhatv) > s {
-				subVW(qhatv[s:], qhatv[s:], c)
-			}
-			addAt(u[s:], v[s:], 0)
-		}
-	}
-	if qhatv.cmp(u.norm()) > 0 {
-		panic("impossible")
-	}
-	c := subVV(u[0:len(qhatv)], u[0:len(qhatv)], qhatv)
-	if c > 0 {
-		c = subVW(u[len(qhatv):], u[len(qhatv):], c)
-	}
-	if c > 0 {
-		panic("impossible")
-	}
-
-	// Done!
-	addAt(z, qhat.norm(), 0)
-}
-
 // Length of x in bits. x must be normalized.
 func (x nat) bitLen() int {
 	if i := len(x) - 1; i >= 0 {
@@ -1170,19 +858,6 @@
 	return z.norm()
 }
 
-// greaterThan reports whether (x1<<_W + x2) > (y1<<_W + y2)
-func greaterThan(x1, x2, y1, y2 Word) bool {
-	return x1 > y1 || x1 == y1 && x2 > y2
-}
-
-// modW returns x % d.
-func (x nat) modW(d Word) (r Word) {
-	// TODO(agl): we don't actually need to store the q value.
-	var q nat
-	q = q.make(len(x))
-	return divWVW(q, 0, x, d)
-}
-
 // random creates a random integer in [0..limit), using the space in z if
 // possible. n is the bit length of limit.
 func (z nat) random(rand *rand.Rand, limit nat, n int) nat {
diff --git a/src/math/big/natdiv.go b/src/math/big/natdiv.go
new file mode 100644
index 0000000..882bb6d
--- /dev/null
+++ b/src/math/big/natdiv.go
@@ -0,0 +1,884 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+
+Multi-precision division. Here be dragons.
+
+Given u and v, where u is n+m digits, and v is n digits (with no leading zeros),
+the goal is to return quo, rem such that u = quo*v + rem, where 0 ≤ rem < v.
+That is, quo = ⌊u/v⌋ where ⌊x⌋ denotes the floor (truncation to integer) of x,
+and rem = u - quo·v.
+
+
+Long Division
+
+Division in a computer proceeds the same as long division in elementary school,
+but computers are not as good as schoolchildren at following vague directions,
+so we have to be much more precise about the actual steps and what can happen.
+
+We work from most to least significant digit of the quotient, doing:
+
+ • Guess a digit q, the number of v to subtract from the current
+   section of u to zero out the topmost digit.
+ • Check the guess by multiplying q·v and comparing it against
+   the current section of u, adjusting the guess as needed.
+ • Subtract q·v from the current section of u.
+ • Add q to the corresponding section of the result quo.
+
+When all digits have been processed, the final remainder is left in u
+and returned as rem.
+
+For example, here is a sketch of dividing 5 digits by 3 digits (n=3, m=2).
+
+	                 q₂ q₁ q₀
+	         _________________
+	v₂ v₁ v₀ ) u₄ u₃ u₂ u₁ u₀
+	           ↓  ↓  ↓  |  |
+	          [u₄ u₃ u₂]|  |
+	        - [  q₂·v  ]|  |
+	        ----------- ↓  |
+	          [  rem  | u₁]|
+	        - [    q₁·v   ]|
+	           ----------- ↓
+	             [  rem  | u₀]
+	           - [    q₀·v   ]
+	              ------------
+	                [  rem   ]
+
+Instead of creating new storage for the remainders and copying digits from u
+as indicated by the arrows, we use u's storage directly as both the source
+and destination of the subtractions, so that the remainders overwrite
+successive overlapping sections of u as the division proceeds, using a slice
+of u to identify the current section. This avoids all the copying as well as
+shifting of remainders.
+
+Division of u with n+m digits by v with n digits (in base B) can in general
+produce at most m+1 digits, because:
+
+  • u < B^(n+m)               [B^(n+m) has n+m+1 digits]
+  • v ≥ B^(n-1)               [B^(n-1) is the smallest n-digit number]
+  • u/v < B^(n+m) / B^(n-1)   [divide bounds for u, v]
+  • u/v < B^(m+1)             [simplify]
+
+The first step is special: it takes the top n digits of u and divides them by
+the n digits of v, producing the first quotient digit and an n-digit remainder.
+In the example, q₂ = ⌊u₄u₃u₂ / v⌋.
+
+The first step divides n digits by n digits to ensure that it produces only a
+single digit.
+
+Each subsequent step appends the next digit from u to the remainder and divides
+those n+1 digits by the n digits of v, producing another quotient digit and a
+new n-digit remainder.
+
+Subsequent steps divide n+1 digits by n digits, an operation that in general
+might produce two digits. However, as used in the algorithm, that division is
+guaranteed to produce only a single digit. The dividend is of the form
+rem·B + d, where rem is a remainder from the previous step and d is a single
+digit, so:
+
+ • rem ≤ v - 1                 [rem is a remainder from dividing by v]
+ • rem·B ≤ v·B - B             [multiply by B]
+ • d ≤ B - 1                   [d is a single digit]
+ • rem·B + d ≤ v·B - 1         [add]
+ • rem·B + d < v·B             [change ≤ to <]
+ • (rem·B + d)/v < B           [divide by v]
+
+
+Guess and Check
+
+At each step we need to divide n+1 digits by n digits, but this is for the
+implementation of division by n digits, so we can't just invoke a division
+routine: we _are_ the division routine. Instead, we guess at the answer and
+then check it using multiplication. If the guess is wrong, we correct it.
+
+How can this guessing possibly be efficient? It turns out that the following
+statement (let's call it the Good Guess Guarantee) is true.
+
+If
+
+ • q = ⌊u/v⌋ where u is n+1 digits and v is n digits,
+ • q < B, and
+ • the topmost digit of v = vₙ₋₁ ≥ B/2,
+
+then q̂ = ⌊uₙuₙ₋₁ / vₙ₋₁⌋ satisfies q ≤ q̂ ≤ q+2. (Proof below.)
+
+That is, if we know the answer has only a single digit and we guess an answer
+by ignoring the bottom n-1 digits of u and v, using a 2-by-1-digit division,
+then that guess is at least as large as the correct answer. It is also not
+too much larger: it is off by at most two from the correct answer.
+
+Note that in the first step of the overall division, which is an n-by-n-digit
+division, the 2-by-1 guess uses an implicit uₙ = 0.
+
+Note that using a 2-by-1-digit division here does not mean calling ourselves
+recursively. Instead, we use an efficient direct hardware implementation of
+that operation.
+
+Note that because q is u/v rounded down, q·v must not exceed u: u ≥ q·v.
+If a guess q̂ is too big, it will not satisfy this test. Viewed a different way,
+the remainder r̂ for a given q̂ is u - q̂·v, which must be positive. If it is
+negative, then the guess q̂ is too big.
+
+This gives us a way to compute q. First compute q̂ with 2-by-1-digit division.
+Then, while u < q̂·v, decrement q̂; this loop executes at most twice, because
+q̂ ≤ q+2.
+
+
+Scaling Inputs
+
+The Good Guess Guarantee requires that the top digit of v (vₙ₋₁) be at least B/2.
+For example in base 10, ⌊172/19⌋ = 9, but ⌊18/1⌋ = 18: the guess is wildly off
+because the first digit 1 is smaller than B/2 = 5.
+
+We can ensure that v has a large top digit by multiplying both u and v by the
+right amount. Continuing the example, if we multiply both 172 and 19 by 3, we
+now have ⌊516/57⌋, the leading digit of v is now ≥ 5, and sure enough
+⌊51/5⌋ = 10 is much closer to the correct answer 9. It would be easier here
+to multiply by 4, because that can be done with a shift. Specifically, we can
+always count the number of leading zeros i in the first digit of v and then
+shift both u and v left by i bits.
+
+Having scaled u and v, the value ⌊u/v⌋ is unchanged, but the remainder will
+be scaled: 172 mod 19 is 1, but 516 mod 57 is 3. We have to divide the remainder
+by the scaling factor (shifting right i bits) when we finish.
+
+Note that these shifts happen before and after the entire division algorithm,
+not at each step in the per-digit iteration.
+
+Note the effect of scaling inputs on the size of the possible quotient.
+In the scaled u/v, u can gain a digit from scaling; v never does, because we
+pick the scaling factor to make v's top digit larger but without overflowing.
+If u and v have n+m and n digits after scaling, then:
+
+  • u < B^(n+m)               [B^(n+m) has n+m+1 digits]
+  • v ≥ B^n / 2               [vₙ₋₁ ≥ B/2, so vₙ₋₁·B^(n-1) ≥ B^n/2]
+  • u/v < B^(n+m) / (B^n / 2) [divide bounds for u, v]
+  • u/v < 2 B^m               [simplify]
+
+The quotient can still have m+1 significant digits, but if so the top digit
+must be a 1. This provides a different way to handle the first digit of the
+result: compare the top n digits of u against v and fill in either a 0 or a 1.
+
+
+Refining Guesses
+
+Before we check whether u < q̂·v, we can adjust our guess to change it from
+q̂ = ⌊uₙuₙ₋₁ / vₙ₋₁⌋ into the refined guess ⌊uₙuₙ₋₁uₙ₋₂ / vₙ₋₁vₙ₋₂⌋.
+Although not mentioned above, the Good Guess Guarantee also promises that this
+3-by-2-digit division guess is more precise and at most one away from the real
+answer q. The improvement from the 2-by-1 to the 3-by-2 guess can also be done
+without n-digit math.
+
+If we have a guess q̂ = ⌊uₙuₙ₋₁ / vₙ₋₁⌋ and we want to see if it also equal to
+⌊uₙuₙ₋₁uₙ₋₂ / vₙ₋₁vₙ₋₂⌋, we can use the same check we would for the full division:
+if uₙuₙ₋₁uₙ₋₂ < q̂·vₙ₋₁vₙ₋₂, then the guess is too large and should be reduced.
+
+Checking uₙuₙ₋₁uₙ₋₂ < q̂·vₙ₋₁vₙ₋₂ is the same as uₙuₙ₋₁uₙ₋₂ - q̂·vₙ₋₁vₙ₋₂ < 0,
+and
+
+	uₙuₙ₋₁uₙ₋₂ - q̂·vₙ₋₁vₙ₋₂ = (uₙuₙ₋₁·B + uₙ₋₂) - q̂·(vₙ₋₁·B + vₙ₋₂)
+	                          [splitting off the bottom digit]
+	                      = (uₙuₙ₋₁ - q̂·vₙ₋₁)·B + uₙ₋₂ - q̂·vₙ₋₂
+	                          [regrouping]
+
+The expression (uₙuₙ₋₁ - q̂·vₙ₋₁) is the remainder of uₙuₙ₋₁ / vₙ₋₁.
+If the initial guess returns both q̂ and its remainder r̂, then checking
+whether uₙuₙ₋₁uₙ₋₂ < q̂·vₙ₋₁vₙ₋₂ is the same as checking r̂·B + uₙ₋₂ < q̂·vₙ₋₂.
+
+If we find that r̂·B + uₙ₋₂ < q̂·vₙ₋₂, then we can adjust the guess by
+decrementing q̂ and adding vₙ₋₁ to r̂. We repeat until r̂·B + uₙ₋₂ ≥ q̂·vₙ₋₂.
+(As before, this fixup is only needed at most twice.)
+
+Now that q̂ = ⌊uₙuₙ₋₁uₙ₋₂ / vₙ₋₁vₙ₋₂⌋, as mentioned above it is at most one
+away from the correct q, and we've avoided doing any n-digit math.
+(If we need the new remainder, it can be computed as r̂·B + uₙ₋₂ - q̂·vₙ₋₂.)
+
+The final check u < q̂·v and the possible fixup must be done at full precision.
+For random inputs, a fixup at this step is exceedingly rare: the 3-by-2 guess
+is not often wrong at all. But still we must do the check. Note that since the
+3-by-2 guess is off by at most 1, it can be convenient to perform the final
+u < q̂·v as part of the computation of the remainder r = u - q̂·v. If the
+subtraction underflows, decremeting q̂ and adding one v back to r is enough to
+arrive at the final q, r.
+
+That's the entirety of long division: scale the inputs, and then loop over
+each output position, guessing, checking, and correcting the next output digit.
+
+For a 2n-digit number divided by an n-digit number (the worst size-n case for
+division complexity), this algorithm uses n+1 iterations, each of which must do
+at least the 1-by-n-digit multiplication q̂·v. That's O(n) iterations of
+O(n) time each, so O(n²) time overall.
+
+
+Recursive Division
+
+For very large inputs, it is possible to improve on the O(n²) algorithm.
+Let's call a group of n/2 real digits a (very) “wide digit”. We can run the
+standard long division algorithm explained above over the wide digits instead of
+the actual digits. This will result in many fewer steps, but the math involved in
+each step is more work.
+
+Where basic long division uses a 2-by-1-digit division to guess the initial q̂,
+the new algorithm must use a 2-by-1-wide-digit division, which is of course
+really an n-by-n/2-digit division. That's OK: if we implement n-digit division
+in terms of n/2-digit division, the recursion will terminate when the divisor
+becomes small enough to handle with standard long division or even with the
+2-by-1 hardware instruction.
+
+For example, here is a sketch of dividing 10 digits by 4, proceeding with
+wide digits corresponding to two regular digits. The first step, still special,
+must leave off a (regular) digit, dividing 5 by 4 and producing a 4-digit
+remainder less than v. The middle steps divide 6 digits by 4, guaranteed to
+produce two output digits each (one wide digit) with 4-digit remainders.
+The final step must use what it has: the 4-digit remainder plus one more,
+5 digits to divide by 4.
+
+	                       q₆ q₅ q₄ q₃ q₂ q₁ q₀
+	            _______________________________
+	v₃ v₂ v₁ v₀ ) u₉ u₈ u₇ u₆ u₅ u₄ u₃ u₂ u₁ u₀
+	              ↓  ↓  ↓  ↓  ↓  |  |  |  |  |
+	             [u₉ u₈ u₇ u₆ u₅]|  |  |  |  |
+	           - [    q₆q₅·v    ]|  |  |  |  |
+	           ----------------- ↓  ↓  |  |  |
+	                [    rem    |u₄ u₃]|  |  |
+	              - [     q₄q₃·v      ]|  |  |
+	              -------------------- ↓  ↓  |
+	                      [    rem    |u₂ u₁]|
+	                    - [     q₂q₁·v      ]|
+	                    -------------------- ↓
+	                            [    rem    |u₀]
+	                          - [     q₀·v     ]
+	                          ------------------
+	                               [    rem    ]
+
+An alternative would be to look ahead to how well n/2 divides into n+m and
+adjust the first step to use fewer digits as needed, making the first step
+more special to make the last step not special at all. For example, using the
+same input, we could choose to use only 4 digits in the first step, leaving
+a full wide digit for the last step:
+
+	                       q₆ q₅ q₄ q₃ q₂ q₁ q₀
+	            _______________________________
+	v₃ v₂ v₁ v₀ ) u₉ u₈ u₇ u₆ u₅ u₄ u₃ u₂ u₁ u₀
+	              ↓  ↓  ↓  ↓  |  |  |  |  |  |
+	             [u₉ u₈ u₇ u₆]|  |  |  |  |  |
+	           - [    q₆·v   ]|  |  |  |  |  |
+	           -------------- ↓  ↓  |  |  |  |
+	             [    rem    |u₅ u₄]|  |  |  |
+	           - [     q₅q₄·v      ]|  |  |  |
+	           -------------------- ↓  ↓  |  |
+	                   [    rem    |u₃ u₂]|  |
+	                 - [     q₃q₂·v      ]|  |
+	                 -------------------- ↓  ↓
+	                         [    rem    |u₁ u₀]
+	                       - [     q₁q₀·v      ]
+	                       ---------------------
+	                               [    rem    ]
+
+Today, the code in divRecursiveStep works like the first example. Perhaps in
+the future we will make it work like the alternative, to avoid a special case
+in the final iteration.
+
+Either way, each step is a 3-by-2-wide-digit division approximated first by
+a 2-by-1-wide-digit division, just as we did for regular digits in long division.
+Because the actual answer we want is a 3-by-2-wide-digit division, instead of
+multiplying q̂·v directly during the fixup, we can use the quick refinement
+from long division (an n/2-by-n/2 multiply) to correct q to its actual value
+and also compute the remainder (as mentioned above), and then stop after that,
+never doing a full n-by-n multiply.
+
+Instead of using an n-by-n/2-digit division to produce n/2 digits, we can add
+(not discard) one more real digit, doing an (n+1)-by-(n/2+1)-digit division that
+produces n/2+1 digits. That single extra digit tightens the Good Guess Guarantee
+to q ≤ q̂ ≤ q+1 and lets us drop long division's special treatment of the first
+digit. These benefits are discussed more after the Good Guess Guarantee proof
+below.
+
+
+How Fast is Recursive Division?
+
+For a 2n-by-n-digit division, this algorithm runs a 4-by-2 long division over
+wide digits, producing two wide digits plus a possible leading regular digit 1,
+which can be handled without a recursive call. That is, the algorithm uses two
+full iterations, each using an n-by-n/2-digit division and an n/2-by-n/2-digit
+multiplication, along with a few n-digit additions and subtractions. The standard
+n-by-n-digit multiplication algorithm requires O(n²) time, making the overall
+algorithm require time T(n) where
+
+	T(n) = 2T(n/2) + O(n) + O(n²)
+
+which, by the Bentley-Haken-Saxe theorem, ends up reducing to T(n) = O(n²).
+This is not an improvement over regular long division.
+
+When the number of digits n becomes large enough, Karatsuba's algorithm for
+multiplication can be used instead, which takes O(n^log₂3) = O(n^1.6) time.
+(Karatsuba multiplication is implemented in func karatsuba in nat.go.)
+That makes the overall recursive division algorithm take O(n^1.6) time as well,
+which is an improvement, but again only for large enough numbers.
+
+It is not critical to make sure that every recursion does only two recursive
+calls. While in general the number of recursive calls can change the time
+analysis, in this case doing three calls does not change the analysis:
+
+	T(n) = 3T(n/2) + O(n) + O(n^log₂3)
+
+ends up being T(n) = O(n^log₂3). Because the Karatsuba multiplication taking
+time O(n^log₂3) is itself doing 3 half-sized recursions, doing three for the
+division does not hurt the asymptotic performance. Of course, it is likely
+still faster in practice to do two.
+
+
+Proof of the Good Guess Guarantee
+
+Given numbers x, y, let us break them into the quotients and remainders when
+divided by some scaling factor S, with the added constraints that the quotient
+x/y and the high part of y are both less than some limit T, and that the high
+part of y is at least half as big as T.
+
+	x₁ = ⌊x/S⌋        y₁ = ⌊y/S⌋
+	x₀ = x mod S      y₀ = y mod S
+
+	x  = x₁·S + x₀    0 ≤ x₀ < S    x/y < T
+	y  = y₁·S + y₀    0 ≤ y₀ < S    T/2 ≤ y₁ < T
+
+And consider the two truncated quotients:
+
+	q = ⌊x/y⌋
+	q̂ = ⌊x₁/y₁⌋
+
+We will prove that q ≤ q̂ ≤ q+2.
+
+The guarantee makes no real demands on the scaling factor S: it is simply the
+magnitude of the digits cut from both x and y to produce x₁ and y₁.
+The guarantee makes only limited demands on T: it must be large enough to hold
+the quotient x/y, and y₁ must have roughly the same size.
+
+To apply to the earlier discussion of 2-by-1 guesses in long division,
+we would choose:
+
+	S  = Bⁿ⁻¹
+	T  = B
+	x  = u
+	x₁ = uₙuₙ₋₁
+	x₀ = uₙ₋₂...u₀
+	y  = v
+	y₁ = vₙ₋₁
+	y₀ = vₙ₋₂...u₀
+
+These simpler variables avoid repeating those longer expressions in the proof.
+
+Note also that, by definition, truncating division ⌊x/y⌋ satisfies
+
+	x/y - 1 < ⌊x/y⌋ ≤ x/y.
+
+This fact will be used a few times in the proofs.
+
+Proof that q ≤ q̂:
+
+	q̂·y₁ = ⌊x₁/y₁⌋·y₁                      [by definition, q̂ = ⌊x₁/y₁⌋]
+	     > (x₁/y₁ - 1)·y₁                  [x₁/y₁ - 1 < ⌊x₁/y₁⌋]
+	     = x₁ - y₁                         [distribute y₁]
+
+	So q̂·y₁ > x₁ - y₁.
+	Since q̂·y₁ is an integer, q̂·y₁ ≥ x₁ - y₁ + 1.
+
+	q̂ - q = q̂ - ⌊x/y⌋                      [by definition, q = ⌊x/y⌋]
+	      ≥ q̂ - x/y                        [⌊x/y⌋ < x/y]
+	      = (1/y)·(q̂·y - x)                [factor out 1/y]
+	      ≥ (1/y)·(q̂·y₁·S - x)             [y = y₁·S + y₀ ≥ y₁·S]
+	      ≥ (1/y)·((x₁ - y₁ + 1)·S - x)    [above: q̂·y₁ ≥ x₁ - y₁ + 1]
+	      = (1/y)·(x₁·S - y₁·S + S - x)    [distribute S]
+	      = (1/y)·(S - x₀ - y₁·S)          [-x = -x₁·S - x₀]
+	      > -y₁·S / y                      [x₀ < S, so S - x₀ < 0; drop it]
+	      ≥ -1                             [y₁·S ≤ y]
+
+	So q̂ - q > -1.
+	Since q̂ - q is an integer, q̂ - q ≥ 0, or equivalently q ≤ q̂.
+
+Proof that q̂ ≤ q+2:
+
+	x₁/y₁ - x/y = x₁·S/y₁·S - x/y          [multiply left term by S/S]
+	            ≤ x/y₁·S - x/y             [x₁S ≤ x]
+	            = (x/y)·(y/y₁·S - 1)       [factor out x/y]
+	            = (x/y)·((y - y₁·S)/y₁·S)  [move -1 into y/y₁·S fraction]
+	            = (x/y)·(y₀/y₁·S)          [y - y₁·S = y₀]
+	            = (x/y)·(1/y₁)·(y₀/S)      [factor out 1/y₁]
+	            < (x/y)·(1/y₁)             [y₀ < S, so y₀/S < 1]
+	            ≤ (x/y)·(2/T)              [y₁ ≥ T/2, so 1/y₁ ≤ 2/T]
+	            < T·(2/T)                  [x/y < T]
+	            = 2                        [T·(2/T) = 2]
+
+	So x₁/y₁ - x/y < 2.
+
+	q̂ - q = ⌊x₁/y₁⌋ - q                    [by definition, q̂ = ⌊x₁/y₁⌋]
+	      = ⌊x₁/y₁⌋ - ⌊x/y⌋                [by definition, q = ⌊x/y⌋]
+	      ≤ x₁/y₁ - ⌊x/y⌋                  [⌊x₁/y₁⌋ ≤ x₁/y₁]
+	      < x₁/y₁ - (x/y - 1)              [⌊x/y⌋ > x/y - 1]
+	      = (x₁/y₁ - x/y) + 1              [regrouping]
+	      < 2 + 1                          [above: x₁/y₁ - x/y < 2]
+	      = 3
+
+	So q̂ - q < 3.
+	Since q̂ - q is an integer, q̂ - q ≤ 2.
+
+Note that when x/y < T/2, the bounds tighten to x₁/y₁ - x/y < 1 and therefore
+q̂ - q ≤ 1.
+
+Note also that in the general case 2n-by-n division where we don't know that
+x/y < T, we do know that x/y < 2T, yielding the bound q̂ - q ≤ 4. So we could
+remove the special case first step of long division as long as we allow the
+first fixup loop to run up to four times. (Using a simple comparison to decide
+whether the first digit is 0 or 1 is still more efficient, though.)
+
+Finally, note that when dividing three leading base-B digits by two (scaled),
+we have T = B² and x/y < B = T/B, a much tighter bound than x/y < T.
+This in turn yields the much tighter bound x₁/y₁ - x/y < 2/B. This means that
+⌊x₁/y₁⌋ and ⌊x/y⌋ can only differ when x/y is less than 2/B greater than an
+integer. For random x and y, the chance of this is 2/B, or, for large B,
+approximately zero. This means that after we produce the 3-by-2 guess in the
+long division algorithm, the fixup loop essentially never runs.
+
+In the recursive algorithm, the extra digit in (2·⌊n/2⌋+1)-by-(⌊n/2⌋+1)-digit
+division has exactly the same effect: the probability of needing a fixup is the
+same 2/B. Even better, we can allow the general case x/y < 2T and the fixup
+probability only grows to 4/B, still essentially zero.
+
+
+References
+
+There are no great references for implementing long division; thus this comment.
+Here are some notes about what to expect from the obvious references.
+
+Knuth Volume 2 (Seminumerical Algorithms) section 4.3.1 is the usual canonical
+reference for long division, but that entire series is highly compressed, never
+repeating a necessary fact and leaving important insights to the exercises.
+For example, no rationale whatsoever is given for the calculation that extends
+q̂ from a 2-by-1 to a 3-by-2 guess, nor why it reduces the error bound.
+The proof that the calculation even has the desired effect is left to exercises.
+The solutions to those exercises provided at the back of the book are entirely
+calculations, still with no explanation as to what is going on or how you would
+arrive at the idea of doing those exact calculations. Nowhere is it mentioned
+that this test extends the 2-by-1 guess into a 3-by-2 guess. The proof of the
+Good Guess Guarantee is only for the 2-by-1 guess and argues by contradiction,
+making it difficult to understand how modifications like adding another digit
+or adjusting the quotient range affects the overall bound.
+
+All that said, Knuth remains the canonical reference. It is dense but packed
+full of information and references, and the proofs are simpler than many other
+presentations. The proofs above are reworkings of Knuth's to remove the
+arguments by contradiction and add explanations or steps that Knuth omitted.
+But beware of errors in older printings. Take the published errata with you.
+
+Brinch Hansen's “Multiple-length Division Revisited: a Tour of the Minefield”
+starts with a blunt critique of Knuth's presentation (among others) and then
+presents a more detailed and easier to follow treatment of long division,
+including an implementation in Pascal. But the algorithm and implementation
+work entirely in terms of 3-by-2 division, which is much less useful on modern
+hardware than an algorithm using 2-by-1 division. The proofs are a bit too
+focused on digit counting and seem needlessly complex, especially compared to
+the ones given above.
+
+Burnikel and Ziegler's “Fast Recursive Division” introduced the key insight of
+implementing division by an n-digit divisor using recursive calls to division
+by an n/2-digit divisor, relying on Karatsuba multiplication to yield a
+sub-quadratic run time. However, the presentation decisions are made almost
+entirely for the purpose of simplifying the run-time analysis, rather than
+simplifying the presentation. Instead of a single algorithm that loops over
+quotient digits, the paper presents two mutually-recursive algorithms, for
+2n-by-n and 3n-by-2n. The paper also does not present any general (n+m)-by-n
+algorithm.
+
+The proofs in the paper are remarkably complex, especially considering that
+the algorithm is at its core just long division on wide digits, so that the
+usual long division proofs apply essentially unaltered.
+*/
+
+package big
+
+import "math/bits"
+
+// div returns q, r such that q = ⌊u/v⌋ and r = u%v = u - q·v.
+// It uses z and z2 as the storage for q and r.
+func (z nat) div(z2, u, v nat) (q, r nat) {
+	if len(v) == 0 {
+		panic("division by zero")
+	}
+
+	if u.cmp(v) < 0 {
+		q = z[:0]
+		r = z2.set(u)
+		return
+	}
+
+	if len(v) == 1 {
+		// Short division: long optimized for a single-word divisor.
+		// In that case, the 2-by-1 guess is all we need at each step.
+		var r2 Word
+		q, r2 = z.divW(u, v[0])
+		r = z2.setWord(r2)
+		return
+	}
+
+	q, r = z.divLarge(z2, u, v)
+	return
+}
+
+// divW returns q, r such that q = ⌊x/y⌋ and r = x%y = x - q·y.
+// It uses z as the storage for q.
+// Note that y is a single digit (Word), not a big number.
+func (z nat) divW(x nat, y Word) (q nat, r Word) {
+	m := len(x)
+	switch {
+	case y == 0:
+		panic("division by zero")
+	case y == 1:
+		q = z.set(x) // result is x
+		return
+	case m == 0:
+		q = z[:0] // result is 0
+		return
+	}
+	// m > 0
+	z = z.make(m)
+	r = divWVW(z, 0, x, y)
+	q = z.norm()
+	return
+}
+
+// modW returns x % d.
+func (x nat) modW(d Word) (r Word) {
+	// TODO(agl): we don't actually need to store the q value.
+	var q nat
+	q = q.make(len(x))
+	return divWVW(q, 0, x, d)
+}
+
+// divWVW overwrites z with ⌊x/y⌋, returning the remainder r.
+// The caller must ensure that len(z) = len(x).
+func divWVW(z []Word, xn Word, x []Word, y Word) (r Word) {
+	r = xn
+	if len(x) == 1 {
+		qq, rr := bits.Div(uint(r), uint(x[0]), uint(y))
+		z[0] = Word(qq)
+		return Word(rr)
+	}
+	rec := reciprocalWord(y)
+	for i := len(z) - 1; i >= 0; i-- {
+		z[i], r = divWW(r, x[i], y, rec)
+	}
+	return r
+}
+
+// div returns q, r such that q = ⌊uIn/vIn⌋ and r = uIn%vIn = uIn - q·vIn.
+// It uses z and u as the storage for q and r.
+// The caller must ensure that len(vIn) ≥ 2 (use divW otherwise)
+// and that len(uIn) ≥ len(vIn) (the answer is 0, uIn otherwise).
+func (z nat) divLarge(u, uIn, vIn nat) (q, r nat) {
+	n := len(vIn)
+	m := len(uIn) - n
+
+	// Scale the inputs so vIn's top bit is 1 (see “Scaling Inputs” above).
+	// vIn is treated as a read-only input (it may be in use by another
+	// goroutine), so we must make a copy.
+	// uIn is copied to u.
+	shift := nlz(vIn[n-1])
+	vp := getNat(n)
+	v := *vp
+	shlVU(v, vIn, shift)
+	u = u.make(len(uIn) + 1)
+	u[len(uIn)] = shlVU(u[0:len(uIn)], uIn, shift)
+
+	// The caller should not pass aliased z and u, since those are
+	// the two different outputs, but correct just in case.
+	if alias(z, u) {
+		z = nil
+	}
+	q = z.make(m + 1)
+
+	// Use basic or recursive long division depending on size.
+	if n < divRecursiveThreshold {
+		q.divBasic(u, v)
+	} else {
+		q.divRecursive(u, v)
+	}
+	putNat(vp)
+
+	q = q.norm()
+
+	// Undo scaling of remainder.
+	shrVU(u, u, shift)
+	r = u.norm()
+
+	return q, r
+}
+
+// divBasic implements long division as described above.
+// It overwrites q with ⌊u/v⌋ and overwrites u with the remainder r.
+// q must be large enough to hold ⌊u/v⌋.
+func (q nat) divBasic(u, v nat) {
+	n := len(v)
+	m := len(u) - n
+
+	qhatvp := getNat(n + 1)
+	qhatv := *qhatvp
+
+	// Set up for divWW below, precomputing reciprocal argument.
+	vn1 := v[n-1]
+	rec := reciprocalWord(vn1)
+
+	// Compute each digit of quotient.
+	for j := m; j >= 0; j-- {
+		// Compute the 2-by-1 guess q̂.
+		// The first iteration must invent a leading 0 for u.
+		qhat := Word(_M)
+		var ujn Word
+		if j+n < len(u) {
+			ujn = u[j+n]
+		}
+
+		// ujn ≤ vn1, or else q̂ would be more than one digit.
+		// For ujn == vn1, we set q̂ to the max digit M above.
+		// Otherwise, we compute the 2-by-1 guess.
+		if ujn != vn1 {
+			var rhat Word
+			qhat, rhat = divWW(ujn, u[j+n-1], vn1, rec)
+
+			// Refine q̂ to a 3-by-2 guess. See “Refining Guesses” above.
+			vn2 := v[n-2]
+			x1, x2 := mulWW(qhat, vn2)
+			ujn2 := u[j+n-2]
+			for greaterThan(x1, x2, rhat, ujn2) { // x1x2 > r̂ u[j+n-2]
+				qhat--
+				prevRhat := rhat
+				rhat += vn1
+				// If r̂  overflows, then
+				// r̂ u[j+n-2]v[n-1] is now definitely > x1 x2.
+				if rhat < prevRhat {
+					break
+				}
+				// TODO(rsc): No need for a full mulWW.
+				// x2 += vn2; if x2 overflows, x1++
+				x1, x2 = mulWW(qhat, vn2)
+			}
+		}
+
+		// Compute q̂·v.
+		qhatv[n] = mulAddVWW(qhatv[0:n], v, qhat, 0)
+		qhl := len(qhatv)
+		if j+qhl > len(u) && qhatv[n] == 0 {
+			qhl--
+		}
+
+		// Subtract q̂·v from the current section of u.
+		// If it underflows, q̂·v > u, which we fix up
+		// by decrementing q̂ and adding v back.
+		c := subVV(u[j:j+qhl], u[j:], qhatv)
+		if c != 0 {
+			c := addVV(u[j:j+n], u[j:], v)
+			// If n == qhl, the carry from subVV and the carry from addVV
+			// cancel out and don't affect u[j+n].
+			if n < qhl {
+				u[j+n] += c
+			}
+			qhat--
+		}
+
+		// Save quotient digit.
+		// Caller may know the top digit is zero and not leave room for it.
+		if j == m && m == len(q) && qhat == 0 {
+			continue
+		}
+		q[j] = qhat
+	}
+
+	putNat(qhatvp)
+}
+
+// greaterThan reports whether the two digit numbers x1 x2 > y1 y2.
+// TODO(rsc): In contradiction to most of this file, x1 is the high
+// digit and x2 is the low digit. This should be fixed.
+func greaterThan(x1, x2, y1, y2 Word) bool {
+	return x1 > y1 || x1 == y1 && x2 > y2
+}
+
+// divRecursiveThreshold is the number of divisor digits
+// at which point divRecursive is faster than divBasic.
+const divRecursiveThreshold = 100
+
+// divRecursive implements recursive division as described above.
+// It overwrites z with ⌊u/v⌋ and overwrites u with the remainder r.
+// z must be large enough to hold ⌊u/v⌋.
+// This function is just for allocating and freeing temporaries
+// around divRecursiveStep, the real implementation.
+func (z nat) divRecursive(u, v nat) {
+	// Recursion depth is (much) less than 2 log₂(len(v)).
+	// Allocate a slice of temporaries to be reused across recursion,
+	// plus one extra temporary not live across the recursion.
+	recDepth := 2 * bits.Len(uint(len(v)))
+	tmp := getNat(3 * len(v))
+	temps := make([]*nat, recDepth)
+
+	z.clear()
+	z.divRecursiveStep(u, v, 0, tmp, temps)
+
+	// Free temporaries.
+	for _, n := range temps {
+		if n != nil {
+			putNat(n)
+		}
+	}
+	putNat(tmp)
+}
+
+// divRecursiveStep is the actual implementation of recursive division.
+// It adds ⌊u/v⌋ to z and overwrites u with the remainder r.
+// z must be large enough to hold ⌊u/v⌋.
+// It uses temps[depth] (allocating if needed) as a temporary live across
+// the recursive call. It also uses tmp, but not live across the recursion.
+func (z nat) divRecursiveStep(u, v nat, depth int, tmp *nat, temps []*nat) {
+	// u is a subsection of the original and may have leading zeros.
+	// TODO(rsc): The v = v.norm() is useless and should be removed.
+	// We know (and require) that v's top digit is ≥ B/2.
+	u = u.norm()
+	v = v.norm()
+	if len(u) == 0 {
+		z.clear()
+		return
+	}
+
+	// Fall back to basic division if the problem is now small enough.
+	n := len(v)
+	if n < divRecursiveThreshold {
+		z.divBasic(u, v)
+		return
+	}
+
+	// Nothing to do if u is shorter than v (implies u < v).
+	m := len(u) - n
+	if m < 0 {
+		return
+	}
+
+	// We consider B digits in a row as a single wide digit.
+	// (See “Recursive Division” above.)
+	//
+	// TODO(rsc): rename B to Wide, to avoid confusion with _B,
+	// which is something entirely different.
+	// TODO(rsc): Look into whether using ⌈n/2⌉ is better than ⌊n/2⌋.
+	B := n / 2
+
+	// Allocate a nat for qhat below.
+	if temps[depth] == nil {
+		temps[depth] = getNat(n) // TODO(rsc): Can be just B+1.
+	} else {
+		*temps[depth] = temps[depth].make(B + 1)
+	}
+
+	// Compute each wide digit of the quotient.
+	//
+	// TODO(rsc): Change the loop to be
+	//	for j := (m+B-1)/B*B; j > 0; j -= B {
+	// which will make the final step a regular step, letting us
+	// delete what amounts to an extra copy of the loop body below.
+	j := m
+	for j > B {
+		// Divide u[j-B:j+n] (3 wide digits) by v (2 wide digits).
+		// First make the 2-by-1-wide-digit guess using a recursive call.
+		// Then extend the guess to the full 3-by-2 (see “Refining Guesses”).
+		//
+		// For the 2-by-1-wide-digit guess, instead of doing 2B-by-B-digit,
+		// we use a (2B+1)-by-(B+1) digit, which handles the possibility that
+		// the result has an extra leading 1 digit as well as guaranteeing
+		// that the computed q̂ will be off by at most 1 instead of 2.
+
+		// s is the number of digits to drop from the 3B- and 2B-digit chunks.
+		// We drop B-1 to be left with 2B+1 and B+1.
+		s := (B - 1)
+
+		// uu is the up-to-3B-digit section of u we are working on.
+		uu := u[j-B:]
+
+		// Compute the 2-by-1 guess q̂, leaving r̂ in uu[s:B+n].
+		qhat := *temps[depth]
+		qhat.clear()
+		qhat.divRecursiveStep(uu[s:B+n], v[s:], depth+1, tmp, temps)
+		qhat = qhat.norm()
+
+		// Extend to a 3-by-2 quotient and remainder.
+		// Because divRecursiveStep overwrote the top part of uu with
+		// the remainder r̂, the full uu already contains the equivalent
+		// of r̂·B + uₙ₋₂ from the “Refining Guesses” discussion.
+		// Subtracting q̂·vₙ₋₂ from it will compute the full-length remainder.
+		// If that subtraction underflows, q̂·v > u, which we fix up
+		// by decrementing q̂ and adding v back, same as in long division.
+
+		// TODO(rsc): Instead of subtract and fix-up, this code is computing
+		// q̂·vₙ₋₂ and decrementing q̂ until that product is ≤ u.
+		// But we can do the subtraction directly, as in the comment above
+		// and in long division, because we know that q̂ is wrong by at most one.
+		qhatv := tmp.make(3 * n)
+		qhatv.clear()
+		qhatv = qhatv.mul(qhat, v[:s])
+		for i := 0; i < 2; i++ {
+			e := qhatv.cmp(uu.norm())
+			if e <= 0 {
+				break
+			}
+			subVW(qhat, qhat, 1)
+			c := subVV(qhatv[:s], qhatv[:s], v[:s])
+			if len(qhatv) > s {
+				subVW(qhatv[s:], qhatv[s:], c)
+			}
+			addAt(uu[s:], v[s:], 0)
+		}
+		if qhatv.cmp(uu.norm()) > 0 {
+			panic("impossible")
+		}
+		c := subVV(uu[:len(qhatv)], uu[:len(qhatv)], qhatv)
+		if c > 0 {
+			subVW(uu[len(qhatv):], uu[len(qhatv):], c)
+		}
+		addAt(z, qhat, j-B)
+		j -= B
+	}
+
+	// TODO(rsc): Rewrite loop as described above and delete all this code.
+
+	// Now u < (v<<B), compute lower bits in the same way.
+	// Choose shift = B-1 again.
+	s := B - 1
+	qhat := *temps[depth]
+	qhat.clear()
+	qhat.divRecursiveStep(u[s:].norm(), v[s:], depth+1, tmp, temps)
+	qhat = qhat.norm()
+	qhatv := tmp.make(3 * n)
+	qhatv.clear()
+	qhatv = qhatv.mul(qhat, v[:s])
+	// Set the correct remainder as before.
+	for i := 0; i < 2; i++ {
+		if e := qhatv.cmp(u.norm()); e > 0 {
+			subVW(qhat, qhat, 1)
+			c := subVV(qhatv[:s], qhatv[:s], v[:s])
+			if len(qhatv) > s {
+				subVW(qhatv[s:], qhatv[s:], c)
+			}
+			addAt(u[s:], v[s:], 0)
+		}
+	}
+	if qhatv.cmp(u.norm()) > 0 {
+		panic("impossible")
+	}
+	c := subVV(u[0:len(qhatv)], u[0:len(qhatv)], qhatv)
+	if c > 0 {
+		c = subVW(u[len(qhatv):], u[len(qhatv):], c)
+	}
+	if c > 0 {
+		panic("impossible")
+	}
+
+	// Done!
+	addAt(z, qhat.norm(), 0)
+}
diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go
index 941139e..ac3c8bd 100644
--- a/src/math/big/ratconv.go
+++ b/src/math/big/ratconv.go
@@ -51,7 +51,8 @@
 // An optional base-10 ``e'' or base-2 ``p'' (or their upper-case variants)
 // exponent may be provided as well, except for hexadecimal floats which
 // only accept an (optional) ``p'' exponent (because an ``e'' or ``E'' cannot
-// be distinguished from a mantissa digit).
+// be distinguished from a mantissa digit). If the exponent's absolute value
+// is too large, the operation may fail.
 // The entire string, not just a prefix, must be valid for success. If the
 // operation failed, the value of z is undefined but the returned value is nil.
 func (z *Rat) SetString(s string) (*Rat, bool) {
@@ -169,6 +170,9 @@
 		if n < 0 {
 			n = -n
 		}
+		if n > 1e6 {
+			return nil, false // avoid excessively large exponents
+		}
 		pow5 := z.b.abs.expNN(natFive, nat(nil).setWord(Word(n)), nil) // use underlying array of z.b.abs
 		if exp5 > 0 {
 			z.a.abs = z.a.abs.mul(z.a.abs, pow5)
@@ -181,15 +185,12 @@
 	}
 
 	// apply exp2 contributions
+	if exp2 < -1e7 || exp2 > 1e7 {
+		return nil, false // avoid excessively large exponents
+	}
 	if exp2 > 0 {
-		if int64(uint(exp2)) != exp2 {
-			panic("exponent too large")
-		}
 		z.a.abs = z.a.abs.shl(z.a.abs, uint(exp2))
 	} else if exp2 < 0 {
-		if int64(uint(-exp2)) != -exp2 {
-			panic("exponent too large")
-		}
 		z.b.abs = z.b.abs.shl(z.b.abs, uint(-exp2))
 	}
 
diff --git a/src/math/big/ratconv_test.go b/src/math/big/ratconv_test.go
index ba0d1ba..15d206c 100644
--- a/src/math/big/ratconv_test.go
+++ b/src/math/big/ratconv_test.go
@@ -589,3 +589,28 @@
 		}
 	}
 }
+
+func TestIssue45910(t *testing.T) {
+	var x Rat
+	for _, test := range []struct {
+		input string
+		want  bool
+	}{
+		{"1e-1000001", false},
+		{"1e-1000000", true},
+		{"1e+1000000", true},
+		{"1e+1000001", false},
+
+		{"0p1000000000000", true},
+		{"1p-10000001", false},
+		{"1p-10000000", true},
+		{"1p+10000000", true},
+		{"1p+10000001", false},
+		{"1.770p02041010010011001001", false}, // test case from issue
+	} {
+		_, got := x.SetString(test.input)
+		if got != test.want {
+			t.Errorf("SetString(%s) got ok = %v; want %v", test.input, got, test.want)
+		}
+	}
+}
diff --git a/src/math/bits/bits.go b/src/math/bits/bits.go
index 879ef2d..65452fe 100644
--- a/src/math/bits/bits.go
+++ b/src/math/bits/bits.go
@@ -8,7 +8,7 @@
 // functions for the predeclared unsigned integer types.
 package bits
 
-const uintSize = 32 << (^uint(0) >> 32 & 1) // 32 or 64
+const uintSize = 32 << (^uint(0) >> 63) // 32 or 64
 
 // UintSize is the size of a uint in bits.
 const UintSize = uintSize
diff --git a/src/math/bits/bits_errors.go b/src/math/bits/bits_errors.go
index 192b4be..61cb5c9 100644
--- a/src/math/bits/bits_errors.go
+++ b/src/math/bits/bits_errors.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !compiler_bootstrap
 // +build !compiler_bootstrap
 
 package bits
diff --git a/src/math/bits/bits_errors_bootstrap.go b/src/math/bits/bits_errors_bootstrap.go
index 5df5738..4d610d3 100644
--- a/src/math/bits/bits_errors_bootstrap.go
+++ b/src/math/bits/bits_errors_bootstrap.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build compiler_bootstrap
 // +build compiler_bootstrap
 
 // This version used only for bootstrap (on this path we want
diff --git a/src/math/bits/bits_tables.go b/src/math/bits/bits_tables.go
index f1e15a0..f869b8d 100644
--- a/src/math/bits/bits_tables.go
+++ b/src/math/bits/bits_tables.go
@@ -6,78 +6,74 @@
 
 package bits
 
-var ntz8tab = [256]uint8{
-	0x08, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x07, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-}
+const ntz8tab = "" +
+	"\x08\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x06\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x07\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x06\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00"
 
-var pop8tab = [256]uint8{
-	0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
-	0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
-	0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
-	0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
-	0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
-	0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
-	0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
-	0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
-	0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
-	0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
-	0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
-	0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
-	0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
-	0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
-	0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
-	0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x05, 0x06, 0x06, 0x07, 0x06, 0x07, 0x07, 0x08,
-}
+const pop8tab = "" +
+	"\x00\x01\x01\x02\x01\x02\x02\x03\x01\x02\x02\x03\x02\x03\x03\x04" +
+	"\x01\x02\x02\x03\x02\x03\x03\x04\x02\x03\x03\x04\x03\x04\x04\x05" +
+	"\x01\x02\x02\x03\x02\x03\x03\x04\x02\x03\x03\x04\x03\x04\x04\x05" +
+	"\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06" +
+	"\x01\x02\x02\x03\x02\x03\x03\x04\x02\x03\x03\x04\x03\x04\x04\x05" +
+	"\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06" +
+	"\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06" +
+	"\x03\x04\x04\x05\x04\x05\x05\x06\x04\x05\x05\x06\x05\x06\x06\x07" +
+	"\x01\x02\x02\x03\x02\x03\x03\x04\x02\x03\x03\x04\x03\x04\x04\x05" +
+	"\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06" +
+	"\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06" +
+	"\x03\x04\x04\x05\x04\x05\x05\x06\x04\x05\x05\x06\x05\x06\x06\x07" +
+	"\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06" +
+	"\x03\x04\x04\x05\x04\x05\x05\x06\x04\x05\x05\x06\x05\x06\x06\x07" +
+	"\x03\x04\x04\x05\x04\x05\x05\x06\x04\x05\x05\x06\x05\x06\x06\x07" +
+	"\x04\x05\x05\x06\x05\x06\x06\x07\x05\x06\x06\x07\x06\x07\x07\x08"
 
-var rev8tab = [256]uint8{
-	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
-	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
-	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
-	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
-	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
-	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
-	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
-	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
-	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
-	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
-	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
-	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
-	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
-	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
-	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
-}
+const rev8tab = "" +
+	"\x00\x80\x40\xc0\x20\xa0\x60\xe0\x10\x90\x50\xd0\x30\xb0\x70\xf0" +
+	"\x08\x88\x48\xc8\x28\xa8\x68\xe8\x18\x98\x58\xd8\x38\xb8\x78\xf8" +
+	"\x04\x84\x44\xc4\x24\xa4\x64\xe4\x14\x94\x54\xd4\x34\xb4\x74\xf4" +
+	"\x0c\x8c\x4c\xcc\x2c\xac\x6c\xec\x1c\x9c\x5c\xdc\x3c\xbc\x7c\xfc" +
+	"\x02\x82\x42\xc2\x22\xa2\x62\xe2\x12\x92\x52\xd2\x32\xb2\x72\xf2" +
+	"\x0a\x8a\x4a\xca\x2a\xaa\x6a\xea\x1a\x9a\x5a\xda\x3a\xba\x7a\xfa" +
+	"\x06\x86\x46\xc6\x26\xa6\x66\xe6\x16\x96\x56\xd6\x36\xb6\x76\xf6" +
+	"\x0e\x8e\x4e\xce\x2e\xae\x6e\xee\x1e\x9e\x5e\xde\x3e\xbe\x7e\xfe" +
+	"\x01\x81\x41\xc1\x21\xa1\x61\xe1\x11\x91\x51\xd1\x31\xb1\x71\xf1" +
+	"\x09\x89\x49\xc9\x29\xa9\x69\xe9\x19\x99\x59\xd9\x39\xb9\x79\xf9" +
+	"\x05\x85\x45\xc5\x25\xa5\x65\xe5\x15\x95\x55\xd5\x35\xb5\x75\xf5" +
+	"\x0d\x8d\x4d\xcd\x2d\xad\x6d\xed\x1d\x9d\x5d\xdd\x3d\xbd\x7d\xfd" +
+	"\x03\x83\x43\xc3\x23\xa3\x63\xe3\x13\x93\x53\xd3\x33\xb3\x73\xf3" +
+	"\x0b\x8b\x4b\xcb\x2b\xab\x6b\xeb\x1b\x9b\x5b\xdb\x3b\xbb\x7b\xfb" +
+	"\x07\x87\x47\xc7\x27\xa7\x67\xe7\x17\x97\x57\xd7\x37\xb7\x77\xf7" +
+	"\x0f\x8f\x4f\xcf\x2f\xaf\x6f\xef\x1f\x9f\x5f\xdf\x3f\xbf\x7f\xff"
 
-var len8tab = [256]uint8{
-	0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-	0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-	0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-	0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-}
+const len8tab = "" +
+	"\x00\x01\x02\x02\x03\x03\x03\x03\x04\x04\x04\x04\x04\x04\x04\x04" +
+	"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05" +
+	"\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06" +
+	"\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06" +
+	"\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
+	"\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
+	"\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
+	"\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"
diff --git a/src/math/bits/make_examples.go b/src/math/bits/make_examples.go
index 1d3ad53..ac4004d 100644
--- a/src/math/bits/make_examples.go
+++ b/src/math/bits/make_examples.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // This program generates example_test.go.
diff --git a/src/math/bits/make_tables.go b/src/math/bits/make_tables.go
index b068d5e..867025e 100644
--- a/src/math/bits/make_tables.go
+++ b/src/math/bits/make_tables.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // This program generates bits_tables.go.
@@ -47,16 +48,15 @@
 }
 
 func gen(w io.Writer, name string, f func(uint8) uint8) {
-	fmt.Fprintf(w, "var %s = [256]uint8{", name)
+	// Use a const string to allow the compiler to constant-evaluate lookups at constant index.
+	fmt.Fprintf(w, "const %s = \"\"+\n\"", name)
 	for i := 0; i < 256; i++ {
-		if i%16 == 0 {
-			fmt.Fprint(w, "\n\t")
-		} else {
-			fmt.Fprint(w, " ")
+		fmt.Fprintf(w, "\\x%02x", f(uint8(i)))
+		if i%16 == 15 && i != 255 {
+			fmt.Fprint(w, "\"+\n\"")
 		}
-		fmt.Fprintf(w, "%#02x,", f(uint8(i)))
 	}
-	fmt.Fprint(w, "\n}\n\n")
+	fmt.Fprint(w, "\"\n\n")
 }
 
 func ntz8(x uint8) (n uint8) {
diff --git a/src/math/cbrt.go b/src/math/cbrt.go
index 4afd4a8..45c8ecb 100644
--- a/src/math/cbrt.go
+++ b/src/math/cbrt.go
@@ -22,7 +22,12 @@
 //	Cbrt(±0) = ±0
 //	Cbrt(±Inf) = ±Inf
 //	Cbrt(NaN) = NaN
-func Cbrt(x float64) float64
+func Cbrt(x float64) float64 {
+	if haveArchCbrt {
+		return archCbrt(x)
+	}
+	return cbrt(x)
+}
 
 func cbrt(x float64) float64 {
 	const (
diff --git a/src/math/cmplx/huge_test.go b/src/math/cmplx/huge_test.go
index f8e60c2..78b4231 100644
--- a/src/math/cmplx/huge_test.go
+++ b/src/math/cmplx/huge_test.go
@@ -5,6 +5,7 @@
 // Disabled for s390x because it uses assembly routines that are not
 // accurate for huge arguments.
 
+//go:build !s390x
 // +build !s390x
 
 package cmplx
diff --git a/src/math/const.go b/src/math/const.go
index 0fc8715..5ea935f 100644
--- a/src/math/const.go
+++ b/src/math/const.go
@@ -28,15 +28,19 @@
 // Max is the largest finite value representable by the type.
 // SmallestNonzero is the smallest positive, non-zero value representable by the type.
 const (
-	MaxFloat32             = 3.40282346638528859811704183484516925440e+38  // 2**127 * (2**24 - 1) / 2**23
-	SmallestNonzeroFloat32 = 1.401298464324817070923729583289916131280e-45 // 1 / 2**(127 - 1 + 23)
+	MaxFloat32             = 0x1p127 * (1 + (1 - 0x1p-23)) // 3.40282346638528859811704183484516925440e+38
+	SmallestNonzeroFloat32 = 0x1p-126 * 0x1p-23            // 1.401298464324817070923729583289916131280e-45
 
-	MaxFloat64             = 1.797693134862315708145274237317043567981e+308 // 2**1023 * (2**53 - 1) / 2**52
-	SmallestNonzeroFloat64 = 4.940656458412465441765687928682213723651e-324 // 1 / 2**(1023 - 1 + 52)
+	MaxFloat64             = 0x1p1023 * (1 + (1 - 0x1p-52)) // 1.79769313486231570814527423731704356798070e+308
+	SmallestNonzeroFloat64 = 0x1p-1022 * 0x1p-52            // 4.9406564584124654417656879286822137236505980e-324
 )
 
 // Integer limit values.
 const (
+	intSize = 32 << (^uint(0) >> 63) // 32 or 64
+
+	MaxInt    = 1<<(intSize-1) - 1
+	MinInt    = -1 << (intSize - 1)
 	MaxInt8   = 1<<7 - 1
 	MinInt8   = -1 << 7
 	MaxInt16  = 1<<15 - 1
@@ -45,6 +49,7 @@
 	MinInt32  = -1 << 31
 	MaxInt64  = 1<<63 - 1
 	MinInt64  = -1 << 63
+	MaxUint   = 1<<intSize - 1
 	MaxUint8  = 1<<8 - 1
 	MaxUint16 = 1<<16 - 1
 	MaxUint32 = 1<<32 - 1
diff --git a/src/math/const_test.go b/src/math/const_test.go
new file mode 100644
index 0000000..170ba6a
--- /dev/null
+++ b/src/math/const_test.go
@@ -0,0 +1,47 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package math_test
+
+import (
+	"testing"
+
+	. "math"
+)
+
+func TestMaxUint(t *testing.T) {
+	if v := uint(MaxUint); v+1 != 0 {
+		t.Errorf("MaxUint should wrap around to zero: %d", v+1)
+	}
+	if v := uint8(MaxUint8); v+1 != 0 {
+		t.Errorf("MaxUint8 should wrap around to zero: %d", v+1)
+	}
+	if v := uint16(MaxUint16); v+1 != 0 {
+		t.Errorf("MaxUint16 should wrap around to zero: %d", v+1)
+	}
+	if v := uint32(MaxUint32); v+1 != 0 {
+		t.Errorf("MaxUint32 should wrap around to zero: %d", v+1)
+	}
+	if v := uint64(MaxUint64); v+1 != 0 {
+		t.Errorf("MaxUint64 should wrap around to zero: %d", v+1)
+	}
+}
+
+func TestMaxInt(t *testing.T) {
+	if v := int(MaxInt); v+1 != MinInt {
+		t.Errorf("MaxInt should wrap around to MinInt: %d", v+1)
+	}
+	if v := int8(MaxInt8); v+1 != MinInt8 {
+		t.Errorf("MaxInt8 should wrap around to MinInt8: %d", v+1)
+	}
+	if v := int16(MaxInt16); v+1 != MinInt16 {
+		t.Errorf("MaxInt16 should wrap around to MinInt16: %d", v+1)
+	}
+	if v := int32(MaxInt32); v+1 != MinInt32 {
+		t.Errorf("MaxInt32 should wrap around to MinInt32: %d", v+1)
+	}
+	if v := int64(MaxInt64); v+1 != MinInt64 {
+		t.Errorf("MaxInt64 should wrap around to MinInt64: %d", v+1)
+	}
+}
diff --git a/src/math/dim.go b/src/math/dim.go
index d2e5d47..6a857bb 100644
--- a/src/math/dim.go
+++ b/src/math/dim.go
@@ -32,7 +32,12 @@
 //	Max(x, NaN) = Max(NaN, x) = NaN
 //	Max(+0, ±0) = Max(±0, +0) = +0
 //	Max(-0, -0) = -0
-func Max(x, y float64) float64
+func Max(x, y float64) float64 {
+	if haveArchMax {
+		return archMax(x, y)
+	}
+	return max(x, y)
+}
 
 func max(x, y float64) float64 {
 	// special cases
@@ -59,7 +64,12 @@
 //	Min(x, -Inf) = Min(-Inf, x) = -Inf
 //	Min(x, NaN) = Min(NaN, x) = NaN
 //	Min(-0, ±0) = Min(±0, -0) = -0
-func Min(x, y float64) float64
+func Min(x, y float64) float64 {
+	if haveArchMin {
+		return archMin(x, y)
+	}
+	return min(x, y)
+}
 
 func min(x, y float64) float64 {
 	// special cases
diff --git a/src/math/dim_amd64.s b/src/math/dim_amd64.s
index 85c02e6..253f03b 100644
--- a/src/math/dim_amd64.s
+++ b/src/math/dim_amd64.s
@@ -8,8 +8,8 @@
 #define NaN    0x7FF8000000000001
 #define NegInf 0xFFF0000000000000
 
-// func ·Max(x, y float64) float64
-TEXT ·Max(SB),NOSPLIT,$0
+// func ·archMax(x, y float64) float64
+TEXT ·archMax(SB),NOSPLIT,$0
 	// +Inf special cases
 	MOVQ    $PosInf, AX
 	MOVQ    x+0(FP), R8
@@ -52,8 +52,8 @@
 	MOVQ    R9, ret+16(FP) // return other 0
 	RET
 
-// func Min(x, y float64) float64
-TEXT ·Min(SB),NOSPLIT,$0
+// func archMin(x, y float64) float64
+TEXT ·archMin(SB),NOSPLIT,$0
 	// -Inf special cases
 	MOVQ    $NegInf, AX
 	MOVQ    x+0(FP), R8
diff --git a/src/math/dim_arm64.s b/src/math/dim_arm64.s
index 2cb866f..f112003 100644
--- a/src/math/dim_arm64.s
+++ b/src/math/dim_arm64.s
@@ -8,8 +8,8 @@
 #define NaN    0x7FF8000000000001
 #define NegInf 0xFFF0000000000000
 
-// func ·Max(x, y float64) float64
-TEXT ·Max(SB),NOSPLIT,$0
+// func ·archMax(x, y float64) float64
+TEXT ·archMax(SB),NOSPLIT,$0
 	// +Inf special cases
 	MOVD	$PosInf, R0
 	MOVD	x+0(FP), R1
@@ -28,8 +28,8 @@
 	MOVD	R0, ret+16(FP)
 	RET
 
-// func Min(x, y float64) float64
-TEXT ·Min(SB),NOSPLIT,$0
+// func archMin(x, y float64) float64
+TEXT ·archMin(SB),NOSPLIT,$0
 	// -Inf special cases
 	MOVD	$NegInf, R0
 	MOVD	x+0(FP), R1
diff --git a/src/math/dim_asm.go b/src/math/dim_asm.go
new file mode 100644
index 0000000..9ba742a
--- /dev/null
+++ b/src/math/dim_asm.go
@@ -0,0 +1,16 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 || arm64 || riscv64 || s390x
+// +build amd64 arm64 riscv64 s390x
+
+package math
+
+const haveArchMax = true
+
+func archMax(x, y float64) float64
+
+const haveArchMin = true
+
+func archMin(x, y float64) float64
diff --git a/src/math/dim_noasm.go b/src/math/dim_noasm.go
new file mode 100644
index 0000000..ea46577
--- /dev/null
+++ b/src/math/dim_noasm.go
@@ -0,0 +1,20 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 && !arm64 && !riscv64 && !s390x
+// +build !amd64,!arm64,!riscv64,!s390x
+
+package math
+
+const haveArchMax = false
+
+func archMax(x, y float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchMin = false
+
+func archMin(x, y float64) float64 {
+	panic("not implemented")
+}
diff --git a/src/math/dim_riscv64.s b/src/math/dim_riscv64.s
index 38f5fe7..5b2fd3d 100644
--- a/src/math/dim_riscv64.s
+++ b/src/math/dim_riscv64.s
@@ -9,8 +9,8 @@
 #define	PosInf	0x080
 #define	NaN	0x200
 
-// func Max(x, y float64) float64
-TEXT ·Max(SB),NOSPLIT,$0
+// func archMax(x, y float64) float64
+TEXT ·archMax(SB),NOSPLIT,$0
 	MOVD	x+0(FP), F0
 	MOVD	y+8(FP), F1
 	FCLASSD	F0, X5
@@ -39,8 +39,8 @@
 	MOVD	F1, ret+16(FP)
 	RET
 
-// func Min(x, y float64) float64
-TEXT ·Min(SB),NOSPLIT,$0
+// func archMin(x, y float64) float64
+TEXT ·archMin(SB),NOSPLIT,$0
 	MOVD	x+0(FP), F0
 	MOVD	y+8(FP), F1
 	FCLASSD	F0, X5
diff --git a/src/math/dim_s390x.s b/src/math/dim_s390x.s
index 74fdd75..1277026 100644
--- a/src/math/dim_s390x.s
+++ b/src/math/dim_s390x.s
@@ -11,7 +11,7 @@
 #define NegInf 0xFFF0000000000000
 
 // func ·Max(x, y float64) float64
-TEXT ·Max(SB),NOSPLIT,$0
+TEXT ·archMax(SB),NOSPLIT,$0
 	// +Inf special cases
 	MOVD    $PosInf, R4
 	MOVD    x+0(FP), R8
@@ -52,8 +52,8 @@
 	MOVD    R9, ret+16(FP) // return other 0
 	RET
 
-// func Min(x, y float64) float64
-TEXT ·Min(SB),NOSPLIT,$0
+// func archMin(x, y float64) float64
+TEXT ·archMin(SB),NOSPLIT,$0
 	// -Inf special cases
 	MOVD    $NegInf, R4
 	MOVD    x+0(FP), R8
diff --git a/src/math/erf.go b/src/math/erf.go
index 9b4048f..4d6fe47 100644
--- a/src/math/erf.go
+++ b/src/math/erf.go
@@ -185,7 +185,12 @@
 //	Erf(+Inf) = 1
 //	Erf(-Inf) = -1
 //	Erf(NaN) = NaN
-func Erf(x float64) float64
+func Erf(x float64) float64 {
+	if haveArchErf {
+		return archErf(x)
+	}
+	return erf(x)
+}
 
 func erf(x float64) float64 {
 	const (
@@ -264,7 +269,12 @@
 //	Erfc(+Inf) = 0
 //	Erfc(-Inf) = 2
 //	Erfc(NaN) = NaN
-func Erfc(x float64) float64
+func Erfc(x float64) float64 {
+	if haveArchErfc {
+		return archErfc(x)
+	}
+	return erfc(x)
+}
 
 func erfc(x float64) float64 {
 	const Tiny = 1.0 / (1 << 56) // 2**-56
diff --git a/src/math/exp.go b/src/math/exp.go
index bd4c5c9..d05eb91 100644
--- a/src/math/exp.go
+++ b/src/math/exp.go
@@ -11,7 +11,12 @@
 //	Exp(NaN) = NaN
 // Very large values overflow to 0 or +Inf.
 // Very small values underflow to 1.
-func Exp(x float64) float64
+func Exp(x float64) float64 {
+	if haveArchExp {
+		return archExp(x)
+	}
+	return exp(x)
+}
 
 // The original C code, the long comment, and the constants
 // below are from FreeBSD's /usr/src/lib/msun/src/e_exp.c
@@ -132,7 +137,12 @@
 // Exp2 returns 2**x, the base-2 exponential of x.
 //
 // Special cases are the same as Exp.
-func Exp2(x float64) float64
+func Exp2(x float64) float64 {
+	if haveArchExp2 {
+		return archExp2(x)
+	}
+	return exp2(x)
+}
 
 func exp2(x float64) float64 {
 	const (
diff --git a/src/math/exp2_386.s b/src/math/exp2_386.s
deleted file mode 100644
index d04cad6..0000000
--- a/src/math/exp2_386.s
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Exp2(x float64) float64
-TEXT ·Exp2(SB),NOSPLIT,$0
-// test bits for not-finite
-	MOVL    x_hi+4(FP), AX
-	ANDL    $0x7ff00000, AX
-	CMPL    AX, $0x7ff00000
-	JEQ     not_finite
-	FMOVD   x+0(FP), F0   // F0=x
-	FMOVD   F0, F1        // F0=x, F1=x
-	FRNDINT               // F0=int(x), F1=x
-	FSUBD   F0, F1        // F0=int(x), F1=x-int(x)
-	FXCHD   F0, F1        // F0=x-int(x), F1=int(x)
-	F2XM1                 // F0=2**(x-int(x))-1, F1=int(x)
-	FLD1                  // F0=1, F1=2**(x-int(x))-1, F2=int(x)
-	FADDDP  F0, F1        // F0=2**(x-int(x)), F1=int(x)
-	FSCALE                // F0=2**x, F1=int(x)
-	FMOVDP  F0, F1        // F0=2**x
-	FMOVDP  F0, ret+8(FP)
-	RET
-not_finite:
-// test bits for -Inf
-	MOVL    x_hi+4(FP), BX
-	MOVL    x_lo+0(FP), CX
-	CMPL    BX, $0xfff00000
-	JNE     not_neginf
-	CMPL    CX, $0
-	JNE     not_neginf
-	MOVL    $0, ret_lo+8(FP)
-	MOVL    $0, ret_hi+12(FP)
-	RET
-not_neginf:
-	MOVL    CX, ret_lo+8(FP)
-	MOVL    BX, ret_hi+12(FP)
-	RET
diff --git a/src/math/exp2_asm.go b/src/math/exp2_asm.go
new file mode 100644
index 0000000..76d258f
--- /dev/null
+++ b/src/math/exp2_asm.go
@@ -0,0 +1,12 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build arm64
+// +build arm64
+
+package math
+
+const haveArchExp2 = true
+
+func archExp2(x float64) float64
diff --git a/src/math/exp2_noasm.go b/src/math/exp2_noasm.go
new file mode 100644
index 0000000..1b0ac87
--- /dev/null
+++ b/src/math/exp2_noasm.go
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !arm64
+// +build !arm64
+
+package math
+
+const haveArchExp2 = false
+
+func archExp2(x float64) float64 {
+	panic("not implemented")
+}
diff --git a/src/math/exp_amd64.go b/src/math/exp_amd64.go
new file mode 100644
index 0000000..654ccce
--- /dev/null
+++ b/src/math/exp_amd64.go
@@ -0,0 +1,12 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64
+// +build amd64
+
+package math
+
+import "internal/cpu"
+
+var useFMA = cpu.X86.HasAVX && cpu.X86.HasFMA
diff --git a/src/math/exp_amd64.s b/src/math/exp_amd64.s
index b3e1c22..02b71c8 100644
--- a/src/math/exp_amd64.s
+++ b/src/math/exp_amd64.s
@@ -37,7 +37,7 @@
 GLOBL exprodata<>+0(SB), RODATA, $72
 
 // func Exp(x float64) float64
-TEXT ·Exp(SB),NOSPLIT,$0
+TEXT ·archExp(SB),NOSPLIT,$0
 	// test bits for not-finite
 	MOVQ    x+0(FP), BX
 	MOVQ    $~(1<<63), AX // sign bit mask
diff --git a/src/math/exp_arm64.s b/src/math/exp_arm64.s
index 19736cb..44673ab 100644
--- a/src/math/exp_arm64.s
+++ b/src/math/exp_arm64.s
@@ -23,7 +23,7 @@
 // This is an assembly implementation of the method used for function Exp in file exp.go.
 //
 // func Exp(x float64) float64
-TEXT ·Exp(SB),$0-16
+TEXT ·archExp(SB),$0-16
 	FMOVD	x+0(FP), F0	// F0 = x
 	FCMPD	F0, F0
 	BNE	isNaN		// x = NaN, return NaN
@@ -109,7 +109,7 @@
 // This is an assembly implementation of the method used for function Exp2 in file exp.go.
 //
 // func Exp2(x float64) float64
-TEXT ·Exp2(SB),$0-16
+TEXT ·archExp2(SB),$0-16
 	FMOVD	x+0(FP), F0	// F0 = x
 	FCMPD	F0, F0
 	BNE	isNaN		// x = NaN, return NaN
diff --git a/src/math/exp_asm.go b/src/math/exp_asm.go
index 8dad3c8..a1673ea 100644
--- a/src/math/exp_asm.go
+++ b/src/math/exp_asm.go
@@ -1,11 +1,12 @@
-// Copyright 2017 The Go Authors. All rights reserved.
+// Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build amd64
+//go:build amd64 || arm64 || s390x
+// +build amd64 arm64 s390x
 
 package math
 
-import "internal/cpu"
+const haveArchExp = true
 
-var useFMA = cpu.X86.HasAVX && cpu.X86.HasFMA
+func archExp(x float64) float64
diff --git a/src/math/exp_noasm.go b/src/math/exp_noasm.go
new file mode 100644
index 0000000..b757e6e
--- /dev/null
+++ b/src/math/exp_noasm.go
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 && !arm64 && !s390x
+// +build !amd64,!arm64,!s390x
+
+package math
+
+const haveArchExp = false
+
+func archExp(x float64) float64 {
+	panic("not implemented")
+}
diff --git a/src/math/expm1.go b/src/math/expm1.go
index 8e77398..66d3421 100644
--- a/src/math/expm1.go
+++ b/src/math/expm1.go
@@ -121,7 +121,12 @@
 //	Expm1(-Inf) = -1
 //	Expm1(NaN) = NaN
 // Very large values overflow to -1 or +Inf.
-func Expm1(x float64) float64
+func Expm1(x float64) float64 {
+	if haveArchExpm1 {
+		return archExpm1(x)
+	}
+	return expm1(x)
+}
 
 func expm1(x float64) float64 {
 	const (
diff --git a/src/math/expm1_386.s b/src/math/expm1_386.s
deleted file mode 100644
index d020296..0000000
--- a/src/math/expm1_386.s
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Expm1(x float64) float64
-TEXT ·Expm1(SB),NOSPLIT,$0
-	FLDLN2               // F0=log(2) = 1/log2(e) ~ 0.693147
-	FMOVD   x+0(FP), F0  // F0=x, F1=1/log2(e)
-	FABS                 // F0=|x|, F1=1/log2(e)
-	FUCOMPP F0, F1       // compare F0 to F1
-	FSTSW   AX
-	SAHF
-	JCC     use_exp      // jump if F0 >= F1
-	FLDL2E                // F0=log2(e)
-	FMULD   x+0(FP), F0   // F0=x*log2(e) (-1<F0<1)
-	F2XM1                 // F0=e**x-1 = 2**(x*log2(e))-1
-	FMOVDP  F0, ret+8(FP)
-	RET
-use_exp:
-// test bits for not-finite
-	MOVL    x_hi+4(FP), AX
-	ANDL    $0x7ff00000, AX
-	CMPL    AX, $0x7ff00000
-	JEQ     not_finite
-	FLDL2E                // F0=log2(e)
-	FMULD   x+0(FP), F0   // F0=x*log2(e)
-	FMOVD   F0, F1        // F0=x*log2(e), F1=x*log2(e)
-	FRNDINT               // F0=int(x*log2(e)), F1=x*log2(e)
-	FSUBD   F0, F1        // F0=int(x*log2(e)), F1=x*log2(e)-int(x*log2(e))
-	FXCHD   F0, F1        // F0=x*log2(e)-int(x*log2(e)), F1=int(x*log2(e))
-	F2XM1                 // F0=2**(x*log2(e)-int(x*log2(e)))-1, F1=int(x*log2(e))
-	FLD1                  // F0=1, F1=2**(x*log2(e)-int(x*log2(e)))-1, F2=int(x*log2(e))
-	FADDDP  F0, F1        // F0=2**(x*log2(e)-int(x*log2(e))), F1=int(x*log2(e))
-	FSCALE                // F0=e**x, F1=int(x*log2(e))
-	FMOVDP  F0, F1        // F0=e**x
-	FLD1                  // F0=1, F1=e**x
-	FSUBDP  F0, F1        // F0=e**x-1
-	FMOVDP  F0, ret+8(FP)
-	RET
-not_finite:
-// test bits for -Inf
-	MOVL    x_hi+4(FP), BX
-	MOVL    x_lo+0(FP), CX
-	CMPL    BX, $0xfff00000
-	JNE     not_neginf
-	CMPL    CX, $0
-	JNE     not_neginf
-	FLD1                 // F0=1
-	FCHS                 // F0=-1
-	FMOVDP  F0, ret+8(FP)
-	RET
-not_neginf:
-	MOVL    CX, ret_lo+8(FP)
-	MOVL    BX, ret_hi+12(FP)
-	RET
diff --git a/src/math/floor.go b/src/math/floor.go
index 18e89ef..7913a90 100644
--- a/src/math/floor.go
+++ b/src/math/floor.go
@@ -10,7 +10,12 @@
 //	Floor(±0) = ±0
 //	Floor(±Inf) = ±Inf
 //	Floor(NaN) = NaN
-func Floor(x float64) float64
+func Floor(x float64) float64 {
+	if haveArchFloor {
+		return archFloor(x)
+	}
+	return floor(x)
+}
 
 func floor(x float64) float64 {
 	if x == 0 || IsNaN(x) || IsInf(x, 0) {
@@ -33,7 +38,12 @@
 //	Ceil(±0) = ±0
 //	Ceil(±Inf) = ±Inf
 //	Ceil(NaN) = NaN
-func Ceil(x float64) float64
+func Ceil(x float64) float64 {
+	if haveArchCeil {
+		return archCeil(x)
+	}
+	return ceil(x)
+}
 
 func ceil(x float64) float64 {
 	return -Floor(-x)
@@ -45,7 +55,12 @@
 //	Trunc(±0) = ±0
 //	Trunc(±Inf) = ±Inf
 //	Trunc(NaN) = NaN
-func Trunc(x float64) float64
+func Trunc(x float64) float64 {
+	if haveArchTrunc {
+		return archTrunc(x)
+	}
+	return trunc(x)
+}
 
 func trunc(x float64) float64 {
 	if x == 0 || IsNaN(x) || IsInf(x, 0) {
diff --git a/src/math/floor_386.s b/src/math/floor_386.s
index 0960eec..1990cb0 100644
--- a/src/math/floor_386.s
+++ b/src/math/floor_386.s
@@ -4,8 +4,8 @@
 
 #include "textflag.h"
 
-// func Ceil(x float64) float64
-TEXT ·Ceil(SB),NOSPLIT,$0
+// func archCeil(x float64) float64
+TEXT ·archCeil(SB),NOSPLIT,$0
 	FMOVD   x+0(FP), F0  // F0=x
 	FSTCW   -2(SP)       // save old Control Word
 	MOVW    -2(SP), AX
@@ -18,8 +18,8 @@
 	FMOVDP  F0, ret+8(FP)
 	RET
 
-// func Floor(x float64) float64
-TEXT ·Floor(SB),NOSPLIT,$0
+// func archFloor(x float64) float64
+TEXT ·archFloor(SB),NOSPLIT,$0
 	FMOVD   x+0(FP), F0  // F0=x
 	FSTCW   -2(SP)       // save old Control Word
 	MOVW    -2(SP), AX
@@ -32,8 +32,8 @@
 	FMOVDP  F0, ret+8(FP)
 	RET
 
-// func Trunc(x float64) float64
-TEXT ·Trunc(SB),NOSPLIT,$0
+// func archTrunc(x float64) float64
+TEXT ·archTrunc(SB),NOSPLIT,$0
 	FMOVD   x+0(FP), F0  // F0=x
 	FSTCW   -2(SP)       // save old Control Word
 	MOVW    -2(SP), AX
diff --git a/src/math/floor_amd64.s b/src/math/floor_amd64.s
index 4ef02eb..0880499 100644
--- a/src/math/floor_amd64.s
+++ b/src/math/floor_amd64.s
@@ -6,8 +6,8 @@
 
 #define Big		0x4330000000000000 // 2**52
 
-// func Floor(x float64) float64
-TEXT ·Floor(SB),NOSPLIT,$0
+// func archFloor(x float64) float64
+TEXT ·archFloor(SB),NOSPLIT,$0
 	MOVQ	x+0(FP), AX
 	MOVQ	$~(1<<63), DX // sign bit mask
 	ANDQ	AX,DX // DX = |x|
@@ -28,8 +28,8 @@
 	MOVQ    AX, ret+8(FP) // return x
 	RET
 
-// func Ceil(x float64) float64
-TEXT ·Ceil(SB),NOSPLIT,$0
+// func archCeil(x float64) float64
+TEXT ·archCeil(SB),NOSPLIT,$0
 	MOVQ	x+0(FP), AX
 	MOVQ	$~(1<<63), DX // sign bit mask
 	MOVQ	AX, BX // BX = copy of x
@@ -54,8 +54,8 @@
 	MOVQ	AX, ret+8(FP)
 	RET
 
-// func Trunc(x float64) float64
-TEXT ·Trunc(SB),NOSPLIT,$0
+// func archTrunc(x float64) float64
+TEXT ·archTrunc(SB),NOSPLIT,$0
 	MOVQ	x+0(FP), AX
 	MOVQ	$~(1<<63), DX // sign bit mask
 	MOVQ	AX, BX // BX = copy of x
diff --git a/src/math/floor_arm64.s b/src/math/floor_arm64.s
index 6d240d4..d9c5df7 100644
--- a/src/math/floor_arm64.s
+++ b/src/math/floor_arm64.s
@@ -4,22 +4,22 @@
 
 #include "textflag.h"
 
-// func Floor(x float64) float64
-TEXT ·Floor(SB),NOSPLIT,$0
+// func archFloor(x float64) float64
+TEXT ·archFloor(SB),NOSPLIT,$0
 	FMOVD	x+0(FP), F0
 	FRINTMD	F0, F0
 	FMOVD	F0, ret+8(FP)
 	RET
 
-// func Ceil(x float64) float64
-TEXT ·Ceil(SB),NOSPLIT,$0
+// func archCeil(x float64) float64
+TEXT ·archCeil(SB),NOSPLIT,$0
 	FMOVD	x+0(FP), F0
 	FRINTPD	F0, F0
 	FMOVD	F0, ret+8(FP)
 	RET
 
-// func Trunc(x float64) float64
-TEXT ·Trunc(SB),NOSPLIT,$0
+// func archTrunc(x float64) float64
+TEXT ·archTrunc(SB),NOSPLIT,$0
 	FMOVD	x+0(FP), F0
 	FRINTZD	F0, F0
 	FMOVD	F0, ret+8(FP)
diff --git a/src/math/floor_asm.go b/src/math/floor_asm.go
new file mode 100644
index 0000000..1265e51
--- /dev/null
+++ b/src/math/floor_asm.go
@@ -0,0 +1,20 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build 386 || amd64 || arm64 || ppc64 || ppc64le || s390x || wasm
+// +build 386 amd64 arm64 ppc64 ppc64le s390x wasm
+
+package math
+
+const haveArchFloor = true
+
+func archFloor(x float64) float64
+
+const haveArchCeil = true
+
+func archCeil(x float64) float64
+
+const haveArchTrunc = true
+
+func archTrunc(x float64) float64
diff --git a/src/math/floor_noasm.go b/src/math/floor_noasm.go
new file mode 100644
index 0000000..821af21
--- /dev/null
+++ b/src/math/floor_noasm.go
@@ -0,0 +1,26 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !386 && !amd64 && !arm64 && !ppc64 && !ppc64le && !s390x && !wasm
+// +build !386,!amd64,!arm64,!ppc64,!ppc64le,!s390x,!wasm
+
+package math
+
+const haveArchFloor = false
+
+func archFloor(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchCeil = false
+
+func archCeil(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchTrunc = false
+
+func archTrunc(x float64) float64 {
+	panic("not implemented")
+}
diff --git a/src/math/floor_ppc64x.s b/src/math/floor_ppc64x.s
index 2ab011d..584c27e 100644
--- a/src/math/floor_ppc64x.s
+++ b/src/math/floor_ppc64x.s
@@ -2,23 +2,24 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "textflag.h"
 
-TEXT ·Floor(SB),NOSPLIT,$0
+TEXT ·archFloor(SB),NOSPLIT,$0
 	FMOVD   x+0(FP), F0
 	FRIM	F0, F0
 	FMOVD   F0, ret+8(FP)
 	RET
 
-TEXT ·Ceil(SB),NOSPLIT,$0
+TEXT ·archCeil(SB),NOSPLIT,$0
 	FMOVD   x+0(FP), F0
 	FRIP    F0, F0
 	FMOVD	F0, ret+8(FP)
 	RET
 
-TEXT ·Trunc(SB),NOSPLIT,$0
+TEXT ·archTrunc(SB),NOSPLIT,$0
 	FMOVD   x+0(FP), F0
 	FRIZ    F0, F0
 	FMOVD   F0, ret+8(FP)
diff --git a/src/math/floor_s390x.s b/src/math/floor_s390x.s
index 896e79b..b5dd462 100644
--- a/src/math/floor_s390x.s
+++ b/src/math/floor_s390x.s
@@ -4,22 +4,22 @@
 
 #include "textflag.h"
 
-// func Floor(x float64) float64
-TEXT ·Floor(SB),NOSPLIT,$0
+// func archFloor(x float64) float64
+TEXT ·archFloor(SB),NOSPLIT,$0
 	FMOVD	x+0(FP), F0
 	FIDBR	$7, F0, F0
 	FMOVD	F0, ret+8(FP)
 	RET
 
-// func Ceil(x float64) float64
-TEXT ·Ceil(SB),NOSPLIT,$0
+// func archCeil(x float64) float64
+TEXT ·archCeil(SB),NOSPLIT,$0
 	FMOVD	x+0(FP), F0
 	FIDBR	$6, F0, F0
 	FMOVD	F0, ret+8(FP)
 	RET
 
-// func Trunc(x float64) float64
-TEXT ·Trunc(SB),NOSPLIT,$0
+// func archTrunc(x float64) float64
+TEXT ·archTrunc(SB),NOSPLIT,$0
 	FMOVD	x+0(FP), F0
 	FIDBR	$5, F0, F0
 	FMOVD	F0, ret+8(FP)
diff --git a/src/math/floor_wasm.s b/src/math/floor_wasm.s
index 4d8a0eb..3751471 100644
--- a/src/math/floor_wasm.s
+++ b/src/math/floor_wasm.s
@@ -4,21 +4,21 @@
 
 #include "textflag.h"
 
-TEXT ·Floor(SB),NOSPLIT,$0
+TEXT ·archFloor(SB),NOSPLIT,$0
 	Get SP
 	F64Load x+0(FP)
 	F64Floor
 	F64Store ret+8(FP)
 	RET
 
-TEXT ·Ceil(SB),NOSPLIT,$0
+TEXT ·archCeil(SB),NOSPLIT,$0
 	Get SP
 	F64Load x+0(FP)
 	F64Ceil
 	F64Store ret+8(FP)
 	RET
 
-TEXT ·Trunc(SB),NOSPLIT,$0
+TEXT ·archTrunc(SB),NOSPLIT,$0
 	Get SP
 	F64Load x+0(FP)
 	F64Trunc
diff --git a/src/math/fma.go b/src/math/fma.go
index db78dfa..ca0bf99 100644
--- a/src/math/fma.go
+++ b/src/math/fma.go
@@ -128,7 +128,7 @@
 	pe -= int32(is62zero)
 
 	// Swap addition operands so |p| >= |z|
-	if pe < ze || (pe == ze && (pm1 < zm1 || (pm1 == zm1 && pm2 < zm2))) {
+	if pe < ze || pe == ze && pm1 < zm1 {
 		ps, pe, pm1, pm2, zs, ze, zm1, zm2 = zs, ze, zm1, zm2, ps, pe, pm1, pm2
 	}
 
diff --git a/src/math/frexp.go b/src/math/frexp.go
index 0e26feb..3c8a909 100644
--- a/src/math/frexp.go
+++ b/src/math/frexp.go
@@ -13,7 +13,12 @@
 //	Frexp(±0) = ±0, 0
 //	Frexp(±Inf) = ±Inf, 0
 //	Frexp(NaN) = NaN, 0
-func Frexp(f float64) (frac float64, exp int)
+func Frexp(f float64) (frac float64, exp int) {
+	if haveArchFrexp {
+		return archFrexp(f)
+	}
+	return frexp(f)
+}
 
 func frexp(f float64) (frac float64, exp int) {
 	// special cases
diff --git a/src/math/frexp_386.s b/src/math/frexp_386.s
deleted file mode 100644
index 832b435..0000000
--- a/src/math/frexp_386.s
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Frexp(f float64) (frac float64, exp int)
-TEXT ·Frexp(SB),NOSPLIT,$0
-	FMOVD   f+0(FP), F0   // F0=f
-	FXAM
-	FSTSW   AX
-	SAHF
-	JNP     nan_zero_inf
-	JCS     nan_zero_inf
-	FXTRACT               // F0=f (0<=f<1), F1=e
-	FMULD  $(0.5), F0     // F0=f (0.5<=f<1), F1=e
-	FMOVDP  F0, frac+8(FP)   // F0=e
-	FLD1                  // F0=1, F1=e
-	FADDDP  F0, F1        // F0=e+1
-	FMOVLP  F0, exp+16(FP)  // (int=int32)
-	RET
-nan_zero_inf:
-	FMOVDP  F0, frac+8(FP)   // F0=e
-	MOVL    $0, exp+16(FP)  // exp=0
-	RET
diff --git a/src/math/huge_test.go b/src/math/huge_test.go
index 9448edc..ec81a4a 100644
--- a/src/math/huge_test.go
+++ b/src/math/huge_test.go
@@ -5,6 +5,7 @@
 // Disabled for s390x because it uses assembly routines that are not
 // accurate for huge arguments.
 
+//go:build !s390x
 // +build !s390x
 
 package math_test
diff --git a/src/math/hypot.go b/src/math/hypot.go
index c7f19d4..12af177 100644
--- a/src/math/hypot.go
+++ b/src/math/hypot.go
@@ -16,7 +16,12 @@
 //	Hypot(p, ±Inf) = +Inf
 //	Hypot(NaN, q) = NaN
 //	Hypot(p, NaN) = NaN
-func Hypot(p, q float64) float64
+func Hypot(p, q float64) float64 {
+	if haveArchHypot {
+		return archHypot(p, q)
+	}
+	return hypot(p, q)
+}
 
 func hypot(p, q float64) float64 {
 	// special cases
diff --git a/src/math/hypot_386.s b/src/math/hypot_386.s
index a89cdf7..80a8fd3 100644
--- a/src/math/hypot_386.s
+++ b/src/math/hypot_386.s
@@ -4,8 +4,8 @@
 
 #include "textflag.h"
 
-// func Hypot(p, q float64) float64
-TEXT ·Hypot(SB),NOSPLIT,$0
+// func archHypot(p, q float64) float64
+TEXT ·archHypot(SB),NOSPLIT,$0
 // test bits for not-finite
 	MOVL    p_hi+4(FP), AX   // high word p
 	ANDL    $0x7ff00000, AX
diff --git a/src/math/hypot_amd64.s b/src/math/hypot_amd64.s
index d7983a7..fe326c9 100644
--- a/src/math/hypot_amd64.s
+++ b/src/math/hypot_amd64.s
@@ -7,8 +7,8 @@
 #define PosInf 0x7FF0000000000000
 #define NaN 0x7FF8000000000001
 
-// func Hypot(p, q float64) float64
-TEXT ·Hypot(SB),NOSPLIT,$0
+// func archHypot(p, q float64) float64
+TEXT ·archHypot(SB),NOSPLIT,$0
 	// test bits for special cases
 	MOVQ    p+0(FP), BX
 	MOVQ    $~(1<<63), AX
diff --git a/src/math/hypot_asm.go b/src/math/hypot_asm.go
new file mode 100644
index 0000000..9435af4
--- /dev/null
+++ b/src/math/hypot_asm.go
@@ -0,0 +1,12 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build 386 || amd64
+// +build 386 amd64
+
+package math
+
+const haveArchHypot = true
+
+func archHypot(p, q float64) float64
diff --git a/src/math/hypot_noasm.go b/src/math/hypot_noasm.go
new file mode 100644
index 0000000..bc41b13
--- /dev/null
+++ b/src/math/hypot_noasm.go
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !386 && !amd64
+// +build !386,!amd64
+
+package math
+
+const haveArchHypot = false
+
+func archHypot(p, q float64) float64 {
+	panic("not implemented")
+}
diff --git a/src/math/ldexp.go b/src/math/ldexp.go
index aa50a49..55c82f1 100644
--- a/src/math/ldexp.go
+++ b/src/math/ldexp.go
@@ -11,7 +11,12 @@
 //	Ldexp(±0, exp) = ±0
 //	Ldexp(±Inf, exp) = ±Inf
 //	Ldexp(NaN, exp) = NaN
-func Ldexp(frac float64, exp int) float64
+func Ldexp(frac float64, exp int) float64 {
+	if haveArchLdexp {
+		return archLdexp(frac, exp)
+	}
+	return ldexp(frac, exp)
+}
 
 func ldexp(frac float64, exp int) float64 {
 	// special cases
diff --git a/src/math/ldexp_386.s b/src/math/ldexp_386.s
deleted file mode 100644
index 6f67ae1..0000000
--- a/src/math/ldexp_386.s
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Ldexp(frac float64, exp int) float64
-TEXT ·Ldexp(SB),NOSPLIT,$0
-	FMOVL   exp+8(FP), F0   // F0=exp
-	FMOVD   frac+0(FP), F0   // F0=frac, F1=e
-	FSCALE                // F0=x*2**e, F1=e
-	FMOVDP  F0, F1        // F0=x*2**e
-	FMOVDP  F0, ret+12(FP)
-	RET
diff --git a/src/math/log.go b/src/math/log.go
index e328348..1b3e306 100644
--- a/src/math/log.go
+++ b/src/math/log.go
@@ -77,7 +77,12 @@
 //	Log(0) = -Inf
 //	Log(x < 0) = NaN
 //	Log(NaN) = NaN
-func Log(x float64) float64
+func Log(x float64) float64 {
+	if haveArchLog {
+		return archLog(x)
+	}
+	return log(x)
+}
 
 func log(x float64) float64 {
 	const (
diff --git a/src/math/log10.go b/src/math/log10.go
index ccd079d..e6916a5 100644
--- a/src/math/log10.go
+++ b/src/math/log10.go
@@ -6,7 +6,12 @@
 
 // Log10 returns the decimal logarithm of x.
 // The special cases are the same as for Log.
-func Log10(x float64) float64
+func Log10(x float64) float64 {
+	if haveArchLog10 {
+		return archLog10(x)
+	}
+	return log10(x)
+}
 
 func log10(x float64) float64 {
 	return Log(x) * (1 / Ln10)
@@ -14,7 +19,12 @@
 
 // Log2 returns the binary logarithm of x.
 // The special cases are the same as for Log.
-func Log2(x float64) float64
+func Log2(x float64) float64 {
+	if haveArchLog2 {
+		return archLog2(x)
+	}
+	return log2(x)
+}
 
 func log2(x float64) float64 {
 	frac, exp := Frexp(x)
diff --git a/src/math/log10_386.s b/src/math/log10_386.s
deleted file mode 100644
index 10eecd9..0000000
--- a/src/math/log10_386.s
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Log10(x float64) float64
-TEXT ·Log10(SB),NOSPLIT,$0
-	FLDLG2               // F0=log10(2)
-	FMOVD   x+0(FP), F0  // F0=x, F1=log10(2)
-	FYL2X                // F0=log10(x)=log2(x)*log10(2)
-	FMOVDP  F0, ret+8(FP)
-	RET
-
-// func Log2(x float64) float64
-TEXT ·Log2(SB),NOSPLIT,$0
-	FLD1                 // F0=1
-	FMOVD   x+0(FP), F0  // F0=x, F1=1
-	FYL2X                // F0=log2(x)
-	FMOVDP  F0, ret+8(FP)
-	RET
diff --git a/src/math/log1p.go b/src/math/log1p.go
index e34e1ff..c117f72 100644
--- a/src/math/log1p.go
+++ b/src/math/log1p.go
@@ -92,7 +92,12 @@
 //	Log1p(-1) = -Inf
 //	Log1p(x < -1) = NaN
 //	Log1p(NaN) = NaN
-func Log1p(x float64) float64
+func Log1p(x float64) float64 {
+	if haveArchLog1p {
+		return archLog1p(x)
+	}
+	return log1p(x)
+}
 
 func log1p(x float64) float64 {
 	const (
diff --git a/src/math/log1p_386.s b/src/math/log1p_386.s
deleted file mode 100644
index 63b7e62..0000000
--- a/src/math/log1p_386.s
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Log1p(x float64) float64
-TEXT ·Log1p(SB),NOSPLIT,$0
-	FMOVD   $(2.928932188134524e-01), F0
-	FMOVD   x+0(FP), F0  // F0=x, F1=1-sqrt(2)/2 = 0.29289321881345247559915564
-	FABS                 // F0=|x|, F1=1-sqrt(2)/2
-	FUCOMPP F0, F1       // compare F0 to F1
-	FSTSW   AX
-	FLDLN2               // F0=log(2)
-	ANDW    $0x0100, AX
-	JEQ     use_fyl2x    // jump if F0 >= F1
-	FMOVD   x+0(FP), F0  // F0=x, F1=log(2)
-	FYL2XP1              // F0=log(1+x)=log2(1+x)*log(2)
-	FMOVDP  F0, ret+8(FP)
-	RET
-use_fyl2x:
-	FLD1                 // F0=1, F2=log(2)
-	FADDD   x+0(FP), F0  // F0=1+x, F1=log(2)
-	FYL2X                // F0=log(1+x)=log2(1+x)*log(2)
-	FMOVDP  F0, ret+8(FP)
-	RET
-
diff --git a/src/math/log_386.s b/src/math/log_386.s
deleted file mode 100644
index 0b64b50..0000000
--- a/src/math/log_386.s
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Log(x float64) float64
-TEXT ·Log(SB),NOSPLIT,$0
-	FLDLN2               // F0=log(2)
-	FMOVD   x+0(FP), F0  // F0=x, F1=log(2)
-	FYL2X                // F0=log(x)=log2(x)*log(2)
-	FMOVDP  F0, ret+8(FP)
-	RET
diff --git a/src/math/log_amd64.s b/src/math/log_amd64.s
index 3d76389..d84091f 100644
--- a/src/math/log_amd64.s
+++ b/src/math/log_amd64.s
@@ -19,7 +19,7 @@
 #define PosInf 0x7FF0000000000000
 
 // func Log(x float64) float64
-TEXT ·Log(SB),NOSPLIT,$0
+TEXT ·archLog(SB),NOSPLIT,$0
 	// test bits for special cases
 	MOVQ    x+0(FP), BX
 	MOVQ    $~(1<<63), AX // sign bit mask
diff --git a/src/math/log_asm.go b/src/math/log_asm.go
new file mode 100644
index 0000000..4d3b7ee
--- /dev/null
+++ b/src/math/log_asm.go
@@ -0,0 +1,12 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 || s390x
+// +build amd64 s390x
+
+package math
+
+const haveArchLog = true
+
+func archLog(x float64) float64
diff --git a/src/math/log_stub.go b/src/math/log_stub.go
new file mode 100644
index 0000000..e169716
--- /dev/null
+++ b/src/math/log_stub.go
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 && !s390x
+// +build !amd64,!s390x
+
+package math
+
+const haveArchLog = false
+
+func archLog(x float64) float64 {
+	panic("not implemented")
+}
diff --git a/src/math/mod.go b/src/math/mod.go
index 7efc018..6bc5f28 100644
--- a/src/math/mod.go
+++ b/src/math/mod.go
@@ -18,7 +18,12 @@
 //	Mod(x, 0) = NaN
 //	Mod(x, ±Inf) = x
 //	Mod(x, NaN) = NaN
-func Mod(x, y float64) float64
+func Mod(x, y float64) float64 {
+	if haveArchMod {
+		return archMod(x, y)
+	}
+	return mod(x, y)
+}
 
 func mod(x, y float64) float64 {
 	if y == 0 || IsInf(x, 0) || IsNaN(x) || IsNaN(y) {
diff --git a/src/math/mod_386.s b/src/math/mod_386.s
deleted file mode 100644
index 10ad98b..0000000
--- a/src/math/mod_386.s
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Mod(x, y float64) float64
-TEXT ·Mod(SB),NOSPLIT,$0
-	FMOVD   y+8(FP), F0  // F0=y
-	FMOVD   x+0(FP), F0  // F0=x, F1=y
-	FPREM                // F0=reduced_x, F1=y
-	FSTSW   AX           // AX=status word
-	ANDW    $0x0400, AX
-	JNE     -3(PC)       // jump if reduction incomplete
-	FMOVDP  F0, F1       // F0=x-q*y
-	FMOVDP  F0, ret+16(FP)
-	RET
diff --git a/src/math/modf.go b/src/math/modf.go
index c5bb894..bf08dc6 100644
--- a/src/math/modf.go
+++ b/src/math/modf.go
@@ -10,7 +10,12 @@
 // Special cases are:
 //	Modf(±Inf) = ±Inf, NaN
 //	Modf(NaN) = NaN, NaN
-func Modf(f float64) (int float64, frac float64)
+func Modf(f float64) (int float64, frac float64) {
+	if haveArchModf {
+		return archModf(f)
+	}
+	return modf(f)
+}
 
 func modf(f float64) (int float64, frac float64) {
 	if f < 1 {
diff --git a/src/math/modf_386.s b/src/math/modf_386.s
deleted file mode 100644
index e916073..0000000
--- a/src/math/modf_386.s
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Modf(f float64) (int float64, frac float64)
-TEXT ·Modf(SB),NOSPLIT,$0
-	// special case for f == -0.0
-	MOVL f_hi+4(FP), DX	// high word
-	MOVL f_lo+0(FP), AX	// low word
-	CMPL DX, $(1<<31)	// beginning of -0.0
-	JNE notNegativeZero
-	CMPL AX, $0			// could be denormalized
-	JNE notNegativeZero
-	MOVL AX, int_lo+8(FP)
-	MOVL DX, int_hi+12(FP)
-	MOVL AX, frac_lo+16(FP)
-	MOVL DX, frac_hi+20(FP)
-	RET
-notNegativeZero:
-	FMOVD   f+0(FP), F0  // F0=f
-	FMOVD   F0, F1       // F0=f, F1=f
-	FSTCW   -2(SP)       // save old Control Word
-	MOVW    -2(SP), AX
-	ORW     $0x0c00, AX  // Rounding Control set to truncate
-	MOVW    AX, -4(SP)   // store new Control Word
-	FLDCW   -4(SP)       // load new Control Word
-	FRNDINT              // F0=trunc(f), F1=f
-	FLDCW   -2(SP)       // load old Control Word
-	FSUBD   F0, F1       // F0=trunc(f), F1=f-trunc(f)
-	FMOVDP  F0, int+8(FP)  // F0=f-trunc(f)
-	FMOVDP  F0, frac+16(FP)
-	RET
diff --git a/src/math/modf_arm64.s b/src/math/modf_arm64.s
index 7c70ef3..1e4a329 100644
--- a/src/math/modf_arm64.s
+++ b/src/math/modf_arm64.s
@@ -4,8 +4,8 @@
 
 #include "textflag.h"
 
-// func Modf(f float64) (int float64, frac float64)
-TEXT ·Modf(SB),NOSPLIT,$0
+// func archModf(f float64) (int float64, frac float64)
+TEXT ·archModf(SB),NOSPLIT,$0
 	MOVD	f+0(FP), R0
 	FMOVD	R0, F0
 	FRINTZD	F0, F1
diff --git a/src/math/modf_asm.go b/src/math/modf_asm.go
new file mode 100644
index 0000000..ce431a9
--- /dev/null
+++ b/src/math/modf_asm.go
@@ -0,0 +1,12 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build arm64 || ppc64 || ppc64le
+// +build arm64 ppc64 ppc64le
+
+package math
+
+const haveArchModf = true
+
+func archModf(f float64) (int float64, frac float64)
diff --git a/src/math/modf_noasm.go b/src/math/modf_noasm.go
new file mode 100644
index 0000000..9607a08
--- /dev/null
+++ b/src/math/modf_noasm.go
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !arm64 && !ppc64 && !ppc64le
+// +build !arm64,!ppc64,!ppc64le
+
+package math
+
+const haveArchModf = false
+
+func archModf(f float64) (int float64, frac float64) {
+	panic("not implemented")
+}
diff --git a/src/math/modf_ppc64x.s b/src/math/modf_ppc64x.s
index da58653..1303067 100644
--- a/src/math/modf_ppc64x.s
+++ b/src/math/modf_ppc64x.s
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "textflag.h"
 
-// func Modf(f float64) (int float64, frac float64)
-TEXT ·Modf(SB),NOSPLIT,$0
+// func archModf(f float64) (int float64, frac float64)
+TEXT ·archModf(SB),NOSPLIT,$0
 	FMOVD	f+0(FP), F0
 	FRIZ	F0, F1
 	FMOVD	F1, int+8(FP)
diff --git a/src/math/pow.go b/src/math/pow.go
index 2219a90..e45a044 100644
--- a/src/math/pow.go
+++ b/src/math/pow.go
@@ -35,7 +35,12 @@
 //	Pow(+Inf, y) = +0 for y < 0
 //	Pow(-Inf, y) = Pow(-0, -y)
 //	Pow(x, y) = NaN for finite x < 0 and finite non-integer y
-func Pow(x, y float64) float64
+func Pow(x, y float64) float64 {
+	if haveArchPow {
+		return archPow(x, y)
+	}
+	return pow(x, y)
+}
 
 func pow(x, y float64) float64 {
 	switch {
diff --git a/src/math/rand/export_test.go b/src/math/rand/export_test.go
new file mode 100644
index 0000000..560010b
--- /dev/null
+++ b/src/math/rand/export_test.go
@@ -0,0 +1,17 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package rand
+
+func Int31nForTest(r *Rand, n int32) int32 {
+	return r.int31n(n)
+}
+
+func GetNormalDistributionParameters() (float64, [128]uint32, [128]float32, [128]float32) {
+	return rn, kn, wn, fn
+}
+
+func GetExponentialDistributionParameters() (float64, [256]uint32, [256]float32, [256]float32) {
+	return re, ke, we, fe
+}
diff --git a/src/math/rand/gen_cooked.go b/src/math/rand/gen_cooked.go
index 0afc10d..7950e09 100644
--- a/src/math/rand/gen_cooked.go
+++ b/src/math/rand/gen_cooked.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // This program computes the value of rngCooked in rng.go,
diff --git a/src/math/rand/race_test.go b/src/math/rand/race_test.go
index 186c716..e7d1036 100644
--- a/src/math/rand/race_test.go
+++ b/src/math/rand/race_test.go
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package rand
+package rand_test
 
 import (
+	. "math/rand"
 	"sync"
 	"testing"
 )
diff --git a/src/math/rand/rand.go b/src/math/rand/rand.go
index d6422c9..13f20ca 100644
--- a/src/math/rand/rand.go
+++ b/src/math/rand/rand.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package rand implements pseudo-random number generators.
+// Package rand implements pseudo-random number generators unsuitable for
+// security-sensitive work.
 //
 // Random numbers are generated by a Source. Top-level functions, such as
 // Float64 and Int, use a default shared Source that produces a deterministic
@@ -11,11 +12,9 @@
 // The default Source is safe for concurrent use by multiple goroutines, but
 // Sources created by NewSource are not.
 //
-// Mathematical interval notation such as [0, n) is used throughout the
-// documentation for this package.
-//
-// For random numbers suitable for security-sensitive work, see the crypto/rand
-// package.
+// This package's outputs might be easily predictable regardless of how it's
+// seeded. For random numbers suitable for security-sensitive work, see the
+// crypto/rand package.
 package rand
 
 import "sync"
@@ -104,7 +103,7 @@
 	return int(u << 1 >> 1) // clear sign bit if int == int32
 }
 
-// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n).
+// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n).
 // It panics if n <= 0.
 func (r *Rand) Int63n(n int64) int64 {
 	if n <= 0 {
@@ -121,7 +120,7 @@
 	return v % n
 }
 
-// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
+// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n).
 // It panics if n <= 0.
 func (r *Rand) Int31n(n int32) int32 {
 	if n <= 0 {
@@ -138,7 +137,7 @@
 	return v % n
 }
 
-// int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
+// int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [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.
@@ -162,7 +161,7 @@
 	return int32(prod >> 32)
 }
 
-// Intn returns, as an int, a non-negative pseudo-random number in [0,n).
+// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n).
 // It panics if n <= 0.
 func (r *Rand) Intn(n int) int {
 	if n <= 0 {
@@ -174,7 +173,7 @@
 	return int(r.Int63n(int64(n)))
 }
 
-// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0).
+// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0).
 func (r *Rand) Float64() float64 {
 	// A clearer, simpler implementation would be:
 	//	return float64(r.Int63n(1<<53)) / (1<<53)
@@ -200,7 +199,7 @@
 	return f
 }
 
-// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
+// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0).
 func (r *Rand) Float32() float32 {
 	// Same rationale as in Float64: we want to preserve the Go 1 value
 	// stream except we want to fix it not to return 1.0
@@ -213,7 +212,8 @@
 	return f
 }
 
-// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
+// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers
+// in the half-open interval [0,n).
 func (r *Rand) Perm(n int) []int {
 	m := make([]int, n)
 	// In the following loop, the iteration when i=0 always swaps m[0] with m[0].
@@ -321,31 +321,31 @@
 // Int returns a non-negative pseudo-random int from the default Source.
 func Int() int { return globalRand.Int() }
 
-// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n)
+// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n)
 // from the default Source.
 // It panics if n <= 0.
 func Int63n(n int64) int64 { return globalRand.Int63n(n) }
 
-// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n)
+// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n)
 // from the default Source.
 // It panics if n <= 0.
 func Int31n(n int32) int32 { return globalRand.Int31n(n) }
 
-// Intn returns, as an int, a non-negative pseudo-random number in [0,n)
+// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n)
 // from the default Source.
 // It panics if n <= 0.
 func Intn(n int) int { return globalRand.Intn(n) }
 
-// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0)
+// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0)
 // from the default Source.
 func Float64() float64 { return globalRand.Float64() }
 
-// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0)
+// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0)
 // from the default Source.
 func Float32() float32 { return globalRand.Float32() }
 
-// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n)
-// from the default Source.
+// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers
+// in the half-open interval [0,n) from the default Source.
 func Perm(n int) []int { return globalRand.Perm(n) }
 
 // Shuffle pseudo-randomizes the order of elements using the default Source.
diff --git a/src/math/rand/rand_test.go b/src/math/rand/rand_test.go
index e037aae..462de8b 100644
--- a/src/math/rand/rand_test.go
+++ b/src/math/rand/rand_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package rand
+package rand_test
 
 import (
 	"bytes"
@@ -11,6 +11,7 @@
 	"internal/testenv"
 	"io"
 	"math"
+	. "math/rand"
 	"os"
 	"runtime"
 	"testing"
@@ -21,6 +22,9 @@
 	numTestSamples = 10000
 )
 
+var rn, kn, wn, fn = GetNormalDistributionParameters()
+var re, ke, we, fe = GetExponentialDistributionParameters()
+
 type statsResults struct {
 	mean        float64
 	stddev      float64
@@ -503,7 +507,7 @@
 				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: "int31n", fn: func() int { return int(Int31nForTest(r, int32(nfact))) }},
 				{name: "Perm", fn: func() int { return encodePerm(r.Perm(n)) }},
 				{name: "Shuffle", fn: func() int {
 					// Generate permutation using Shuffle.
diff --git a/src/math/remainder.go b/src/math/remainder.go
index 7c77d6e..bf8bfd5 100644
--- a/src/math/remainder.go
+++ b/src/math/remainder.go
@@ -34,7 +34,12 @@
 //	Remainder(x, 0) = NaN
 //	Remainder(x, ±Inf) = x
 //	Remainder(x, NaN) = NaN
-func Remainder(x, y float64) float64
+func Remainder(x, y float64) float64 {
+	if haveArchRemainder {
+		return archRemainder(x, y)
+	}
+	return remainder(x, y)
+}
 
 func remainder(x, y float64) float64 {
 	const (
diff --git a/src/math/remainder_386.s b/src/math/remainder_386.s
deleted file mode 100644
index 318fa2c..0000000
--- a/src/math/remainder_386.s
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Remainder(x, y float64) float64
-TEXT ·Remainder(SB),NOSPLIT,$0
-	FMOVD   y+8(FP), F0  // F0=y
-	FMOVD   x+0(FP), F0  // F0=x, F1=y
-	FPREM1               // F0=reduced_x, F1=y
-	FSTSW   AX           // AX=status word
-	ANDW    $0x0400, AX
-	JNE     -3(PC)       // jump if reduction incomplete
-	FMOVDP  F0, F1       // F0=x-q*y
-	FMOVDP  F0, ret+16(FP)
-	RET
diff --git a/src/math/sin.go b/src/math/sin.go
index 3b6dbe3..d95bb54 100644
--- a/src/math/sin.go
+++ b/src/math/sin.go
@@ -114,7 +114,12 @@
 // Special cases are:
 //	Cos(±Inf) = NaN
 //	Cos(NaN) = NaN
-func Cos(x float64) float64
+func Cos(x float64) float64 {
+	if haveArchCos {
+		return archCos(x)
+	}
+	return cos(x)
+}
 
 func cos(x float64) float64 {
 	const (
@@ -175,7 +180,12 @@
 //	Sin(±0) = ±0
 //	Sin(±Inf) = NaN
 //	Sin(NaN) = NaN
-func Sin(x float64) float64
+func Sin(x float64) float64 {
+	if haveArchSin {
+		return archSin(x)
+	}
+	return sin(x)
+}
 
 func sin(x float64) float64 {
 	const (
diff --git a/src/math/sinh.go b/src/math/sinh.go
index 573a37e..9fe9b4e 100644
--- a/src/math/sinh.go
+++ b/src/math/sinh.go
@@ -22,7 +22,12 @@
 //	Sinh(±0) = ±0
 //	Sinh(±Inf) = ±Inf
 //	Sinh(NaN) = NaN
-func Sinh(x float64) float64
+func Sinh(x float64) float64 {
+	if haveArchSinh {
+		return archSinh(x)
+	}
+	return sinh(x)
+}
 
 func sinh(x float64) float64 {
 	// The coefficients are #2029 from Hart & Cheney. (20.36D)
@@ -69,7 +74,12 @@
 //	Cosh(±0) = 1
 //	Cosh(±Inf) = +Inf
 //	Cosh(NaN) = NaN
-func Cosh(x float64) float64
+func Cosh(x float64) float64 {
+	if haveArchCosh {
+		return archCosh(x)
+	}
+	return cosh(x)
+}
 
 func cosh(x float64) float64 {
 	x = Abs(x)
diff --git a/src/math/sqrt.go b/src/math/sqrt.go
index 1077a62..903d57d 100644
--- a/src/math/sqrt.go
+++ b/src/math/sqrt.go
@@ -89,7 +89,12 @@
 //	Sqrt(±0) = ±0
 //	Sqrt(x < 0) = NaN
 //	Sqrt(NaN) = NaN
-func Sqrt(x float64) float64
+func Sqrt(x float64) float64 {
+	if haveArchSqrt {
+		return archSqrt(x)
+	}
+	return sqrt(x)
+}
 
 // Note: Sqrt is implemented in assembly on some systems.
 // Others have assembly stubs that jump to func sqrt below.
diff --git a/src/math/sqrt_386.s b/src/math/sqrt_386.s
index 5a5c33a..90aec13 100644
--- a/src/math/sqrt_386.s
+++ b/src/math/sqrt_386.s
@@ -4,8 +4,8 @@
 
 #include "textflag.h"
 
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB),NOSPLIT,$0
+// func archSqrt(x float64) float64
+TEXT ·archSqrt(SB),NOSPLIT,$0
 	FMOVD   x+0(FP),F0
 	FSQRT
 	FMOVDP  F0,ret+8(FP)
diff --git a/src/math/sqrt_amd64.s b/src/math/sqrt_amd64.s
index 1102903..c3b110e 100644
--- a/src/math/sqrt_amd64.s
+++ b/src/math/sqrt_amd64.s
@@ -4,8 +4,8 @@
 
 #include "textflag.h"
 
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB), NOSPLIT, $0
+// func archSqrt(x float64) float64
+TEXT ·archSqrt(SB), NOSPLIT, $0
 	XORPS  X0, X0 // break dependency
 	SQRTSD x+0(FP), X0
 	MOVSD  X0, ret+8(FP)
diff --git a/src/math/sqrt_arm.s b/src/math/sqrt_arm.s
index ffc7d10..64792ec 100644
--- a/src/math/sqrt_arm.s
+++ b/src/math/sqrt_arm.s
@@ -4,8 +4,8 @@
 
 #include "textflag.h"
 
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB),NOSPLIT,$0
+// func archSqrt(x float64) float64
+TEXT ·archSqrt(SB),NOSPLIT,$0
 	MOVB	runtime·goarm(SB), R11
 	CMP	$5, R11
 	BEQ	arm5
diff --git a/src/math/sqrt_arm64.s b/src/math/sqrt_arm64.s
index 3041d25..36ba41a 100644
--- a/src/math/sqrt_arm64.s
+++ b/src/math/sqrt_arm64.s
@@ -4,8 +4,8 @@
 
 #include "textflag.h"
 
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB),NOSPLIT,$0
+// func archSqrt(x float64) float64
+TEXT ·archSqrt(SB),NOSPLIT,$0
 	FMOVD	x+0(FP), F0
 	FSQRTD	F0, F0
 	FMOVD	F0, ret+8(FP)
diff --git a/src/math/sqrt_asm.go b/src/math/sqrt_asm.go
new file mode 100644
index 0000000..b910256
--- /dev/null
+++ b/src/math/sqrt_asm.go
@@ -0,0 +1,12 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build 386 || amd64 || arm64 || arm || mips || mipsle || ppc64 || ppc64le || s390x || riscv64 || wasm
+// +build 386 amd64 arm64 arm mips mipsle ppc64 ppc64le s390x riscv64 wasm
+
+package math
+
+const haveArchSqrt = true
+
+func archSqrt(x float64) float64
diff --git a/src/math/sqrt_mipsx.s b/src/math/sqrt_mipsx.s
index a63ea9e..291d4af 100644
--- a/src/math/sqrt_mipsx.s
+++ b/src/math/sqrt_mipsx.s
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "textflag.h"
 
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB),NOSPLIT,$0
+// func archSqrt(x float64) float64
+TEXT ·archSqrt(SB),NOSPLIT,$0
 #ifdef GOMIPS_softfloat
 	JMP ·sqrt(SB)
 #else
diff --git a/src/math/sqrt_noasm.go b/src/math/sqrt_noasm.go
new file mode 100644
index 0000000..7b546b7
--- /dev/null
+++ b/src/math/sqrt_noasm.go
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !386 && !amd64 && !arm64 && !arm && !mips && !mipsle && !ppc64 && !ppc64le && !s390x && !riscv64 && !wasm
+// +build !386,!amd64,!arm64,!arm,!mips,!mipsle,!ppc64,!ppc64le,!s390x,!riscv64,!wasm
+
+package math
+
+const haveArchSqrt = false
+
+func archSqrt(x float64) float64 {
+	panic("not implemented")
+}
diff --git a/src/math/sqrt_ppc64x.s b/src/math/sqrt_ppc64x.s
index 0469f4d..c929da2 100644
--- a/src/math/sqrt_ppc64x.s
+++ b/src/math/sqrt_ppc64x.s
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "textflag.h"
 
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB),NOSPLIT,$0
+// func archSqrt(x float64) float64
+TEXT ·archSqrt(SB),NOSPLIT,$0
 	FMOVD	x+0(FP), F0
 	FSQRT	F0, F0
 	FMOVD	F0, ret+8(FP)
diff --git a/src/math/sqrt_riscv64.s b/src/math/sqrt_riscv64.s
index 048171b..0dbdbc9 100644
--- a/src/math/sqrt_riscv64.s
+++ b/src/math/sqrt_riscv64.s
@@ -2,12 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build riscv64
-
 #include "textflag.h"
 
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB),NOSPLIT,$0
+// func archSqrt(x float64) float64
+TEXT ·archSqrt(SB),NOSPLIT,$0
 	MOVD	x+0(FP), F0
 	FSQRTD	F0, F0
 	MOVD	F0, ret+8(FP)
diff --git a/src/math/sqrt_s390x.s b/src/math/sqrt_s390x.s
index 37ca0be..fa31f75 100644
--- a/src/math/sqrt_s390x.s
+++ b/src/math/sqrt_s390x.s
@@ -4,8 +4,8 @@
 
 #include "textflag.h"
 
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB),NOSPLIT,$0
+// func archSqrt(x float64) float64
+TEXT ·archSqrt(SB),NOSPLIT,$0
 	FMOVD x+0(FP), F1
 	FSQRT F1, F1
 	FMOVD F1, ret+8(FP)
diff --git a/src/math/sqrt_wasm.s b/src/math/sqrt_wasm.s
index cbfe598..fa6799d 100644
--- a/src/math/sqrt_wasm.s
+++ b/src/math/sqrt_wasm.s
@@ -4,7 +4,7 @@
 
 #include "textflag.h"
 
-TEXT ·Sqrt(SB),NOSPLIT,$0
+TEXT ·archSqrt(SB),NOSPLIT,$0
 	Get SP
 	F64Load x+0(FP)
 	F64Sqrt
diff --git a/src/math/stubs.go b/src/math/stubs.go
new file mode 100644
index 0000000..e1345eb
--- /dev/null
+++ b/src/math/stubs.go
@@ -0,0 +1,161 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !s390x
+// +build !s390x
+
+// This is a large group of functions that most architectures don't
+// implement in assembly.
+
+package math
+
+const haveArchAcos = false
+
+func archAcos(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchAcosh = false
+
+func archAcosh(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchAsin = false
+
+func archAsin(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchAsinh = false
+
+func archAsinh(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchAtan = false
+
+func archAtan(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchAtan2 = false
+
+func archAtan2(y, x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchAtanh = false
+
+func archAtanh(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchCbrt = false
+
+func archCbrt(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchCos = false
+
+func archCos(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchCosh = false
+
+func archCosh(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchErf = false
+
+func archErf(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchErfc = false
+
+func archErfc(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchExpm1 = false
+
+func archExpm1(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchFrexp = false
+
+func archFrexp(x float64) (float64, int) {
+	panic("not implemented")
+}
+
+const haveArchLdexp = false
+
+func archLdexp(frac float64, exp int) float64 {
+	panic("not implemented")
+}
+
+const haveArchLog10 = false
+
+func archLog10(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchLog2 = false
+
+func archLog2(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchLog1p = false
+
+func archLog1p(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchMod = false
+
+func archMod(x, y float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchPow = false
+
+func archPow(x, y float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchRemainder = false
+
+func archRemainder(x, y float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchSin = false
+
+func archSin(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchSinh = false
+
+func archSinh(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchTan = false
+
+func archTan(x float64) float64 {
+	panic("not implemented")
+}
+
+const haveArchTanh = false
+
+func archTanh(x float64) float64 {
+	panic("not implemented")
+}
diff --git a/src/math/stubs_386.s b/src/math/stubs_386.s
deleted file mode 100644
index 92c8621..0000000
--- a/src/math/stubs_386.s
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-TEXT ·Acosh(SB), NOSPLIT, $0
-	JMP ·acosh(SB)
-
-TEXT ·Asinh(SB), NOSPLIT, $0
-	JMP ·asinh(SB)
-
-TEXT ·Atanh(SB), NOSPLIT, $0
-	JMP ·atanh(SB)
-
-TEXT ·Cbrt(SB), NOSPLIT, $0
-	JMP ·cbrt(SB)
-
-TEXT ·Cos(SB), NOSPLIT, $0
-	JMP ·cos(SB)
-
-TEXT ·Cosh(SB), NOSPLIT, $0
-	JMP ·cosh(SB)
-
-TEXT ·Erf(SB), NOSPLIT, $0
-	JMP ·erf(SB)
-
-TEXT ·Erfc(SB), NOSPLIT, $0
-	JMP ·erfc(SB)
-
-TEXT ·Exp(SB), NOSPLIT, $0
-	JMP ·exp(SB)
-
-TEXT ·Max(SB), NOSPLIT, $0
-	JMP ·max(SB)
-
-TEXT ·Min(SB), NOSPLIT, $0
-	JMP ·min(SB)
-
-TEXT ·Pow(SB), NOSPLIT, $0
-	JMP ·pow(SB)
-
-TEXT ·Sin(SB), NOSPLIT, $0
-	JMP ·sin(SB)
-
-TEXT ·Sinh(SB), NOSPLIT, $0
-	JMP ·sinh(SB)
-
-TEXT ·Tan(SB), NOSPLIT, $0
-	JMP ·tan(SB)
-
-TEXT ·Tanh(SB), NOSPLIT, $0
-	JMP ·tanh(SB)
diff --git a/src/math/stubs_amd64.s b/src/math/stubs_amd64.s
deleted file mode 100644
index 31e01fd..0000000
--- a/src/math/stubs_amd64.s
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-TEXT ·Acos(SB), NOSPLIT, $0
-	JMP ·acos(SB)
-
-TEXT ·Acosh(SB), NOSPLIT, $0
-	JMP ·acosh(SB)
-
-TEXT ·Asin(SB), NOSPLIT, $0
-	JMP ·asin(SB)
-
-TEXT ·Asinh(SB), NOSPLIT, $0
-	JMP ·asinh(SB)
-
-TEXT ·Atan(SB), NOSPLIT, $0
-	JMP ·atan(SB)
-
-TEXT ·Atan2(SB), NOSPLIT, $0
-	JMP ·atan2(SB)
-
-TEXT ·Atanh(SB), NOSPLIT, $0
-	JMP ·atanh(SB)
-
-TEXT ·Cbrt(SB), NOSPLIT, $0
-	JMP ·cbrt(SB)
-
-TEXT ·Cos(SB), NOSPLIT, $0
-	JMP ·cos(SB)
-
-TEXT ·Cosh(SB), NOSPLIT, $0
-	JMP ·cosh(SB)
-
-TEXT ·Erf(SB), NOSPLIT, $0
-	JMP ·erf(SB)
-
-TEXT ·Erfc(SB), NOSPLIT, $0
-	JMP ·erfc(SB)
-
-TEXT ·Exp2(SB), NOSPLIT, $0
-	JMP ·exp2(SB)
-
-TEXT ·Expm1(SB), NOSPLIT, $0
-	JMP ·expm1(SB)
-
-TEXT ·Frexp(SB), NOSPLIT, $0
-	JMP ·frexp(SB)
-
-TEXT ·Ldexp(SB), NOSPLIT, $0
-	JMP ·ldexp(SB)
-
-TEXT ·Log10(SB), NOSPLIT, $0
-	JMP ·log10(SB)
-
-TEXT ·Log2(SB), NOSPLIT, $0
-	JMP ·log2(SB)
-
-TEXT ·Log1p(SB), NOSPLIT, $0
-	JMP ·log1p(SB)
-
-TEXT ·Mod(SB), NOSPLIT, $0
-	JMP ·mod(SB)
-
-TEXT ·Modf(SB), NOSPLIT, $0
-	JMP ·modf(SB)
-
-TEXT ·Pow(SB), NOSPLIT, $0
-	JMP ·pow(SB)
-
-TEXT ·Remainder(SB), NOSPLIT, $0
-	JMP ·remainder(SB)
-
-TEXT ·Sin(SB), NOSPLIT, $0
-	JMP ·sin(SB)
-
-TEXT ·Sinh(SB), NOSPLIT, $0
-	JMP ·sinh(SB)
-
-TEXT ·Tan(SB), NOSPLIT, $0
-	JMP ·tan(SB)
-
-TEXT ·Tanh(SB), NOSPLIT, $0
-	JMP ·tanh(SB)
diff --git a/src/math/stubs_arm.s b/src/math/stubs_arm.s
deleted file mode 100644
index 31bf872..0000000
--- a/src/math/stubs_arm.s
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-TEXT ·Acos(SB), NOSPLIT, $0
-	B ·acos(SB)
-
-TEXT ·Acosh(SB), NOSPLIT, $0
-	B ·acosh(SB)
-
-TEXT ·Asin(SB), NOSPLIT, $0
-	B ·asin(SB)
-
-TEXT ·Asinh(SB), NOSPLIT, $0
-	B ·asinh(SB)
-
-TEXT ·Atan(SB), NOSPLIT, $0
-	B ·atan(SB)
-
-TEXT ·Atan2(SB), NOSPLIT, $0
-	B ·atan2(SB)
-
-TEXT ·Atanh(SB), NOSPLIT, $0
-	B ·atanh(SB)
-
-TEXT ·Cbrt(SB), NOSPLIT, $0
-	B ·cbrt(SB)
-
-TEXT ·Cos(SB), NOSPLIT, $0
-	B ·cos(SB)
-
-TEXT ·Cosh(SB), NOSPLIT, $0
-	B ·cosh(SB)
-
-TEXT ·Erf(SB), NOSPLIT, $0
-	B ·erf(SB)
-
-TEXT ·Erfc(SB), NOSPLIT, $0
-	B ·erfc(SB)
-
-TEXT ·Exp2(SB), NOSPLIT, $0
-	B ·exp2(SB)
-
-TEXT ·Exp(SB), NOSPLIT, $0
-	B ·exp(SB)
-
-TEXT ·Expm1(SB), NOSPLIT, $0
-	B ·expm1(SB)
-
-TEXT ·Floor(SB), NOSPLIT, $0
-	B ·floor(SB)
-
-TEXT ·Ceil(SB), NOSPLIT, $0
-	B ·ceil(SB)
-
-TEXT ·Trunc(SB), NOSPLIT, $0
-	B ·trunc(SB)
-
-TEXT ·Frexp(SB), NOSPLIT, $0
-	B ·frexp(SB)
-
-TEXT ·Hypot(SB), NOSPLIT, $0
-	B ·hypot(SB)
-
-TEXT ·Ldexp(SB), NOSPLIT, $0
-	B ·ldexp(SB)
-
-TEXT ·Log10(SB), NOSPLIT, $0
-	B ·log10(SB)
-
-TEXT ·Log2(SB), NOSPLIT, $0
-	B ·log2(SB)
-
-TEXT ·Log1p(SB), NOSPLIT, $0
-	B ·log1p(SB)
-
-TEXT ·Log(SB), NOSPLIT, $0
-	B ·log(SB)
-
-TEXT ·Max(SB), NOSPLIT, $0
-	B ·max(SB)
-
-TEXT ·Min(SB), NOSPLIT, $0
-	B ·min(SB)
-
-TEXT ·Mod(SB), NOSPLIT, $0
-	B ·mod(SB)
-
-TEXT ·Modf(SB), NOSPLIT, $0
-	B ·modf(SB)
-
-TEXT ·Pow(SB), NOSPLIT, $0
-	JMP ·pow(SB)
-
-TEXT ·Remainder(SB), NOSPLIT, $0
-	B ·remainder(SB)
-
-TEXT ·Sin(SB), NOSPLIT, $0
-	B ·sin(SB)
-
-TEXT ·Sinh(SB), NOSPLIT, $0
-	B ·sinh(SB)
-
-TEXT ·Tan(SB), NOSPLIT, $0
-	B ·tan(SB)
-
-TEXT ·Tanh(SB), NOSPLIT, $0
-	B ·tanh(SB)
diff --git a/src/math/stubs_arm64.s b/src/math/stubs_arm64.s
deleted file mode 100644
index 24564d0..0000000
--- a/src/math/stubs_arm64.s
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build arm64
-
-#include "textflag.h"
-
-TEXT ·Asin(SB), NOSPLIT, $0
-	B ·asin(SB)
-
-TEXT ·Acos(SB), NOSPLIT, $0
-	B ·acos(SB)
-
-TEXT ·Asinh(SB), NOSPLIT, $0
-	B ·asinh(SB)
-
-TEXT ·Acosh(SB), NOSPLIT, $0
-	B ·acosh(SB)
-
-TEXT ·Atan2(SB), NOSPLIT, $0
-	B ·atan2(SB)
-
-TEXT ·Atan(SB), NOSPLIT, $0
-	B ·atan(SB)
-
-TEXT ·Atanh(SB), NOSPLIT, $0
-	B ·atanh(SB)
-
-TEXT ·Erf(SB), NOSPLIT, $0
-	B ·erf(SB)
-
-TEXT ·Erfc(SB), NOSPLIT, $0
-	B ·erfc(SB)
-
-TEXT ·Cbrt(SB), NOSPLIT, $0
-	B ·cbrt(SB)
-
-TEXT ·Cosh(SB), NOSPLIT, $0
-	B ·cosh(SB)
-
-TEXT ·Expm1(SB), NOSPLIT, $0
-	B ·expm1(SB)
-
-TEXT ·Frexp(SB), NOSPLIT, $0
-	B ·frexp(SB)
-
-TEXT ·Hypot(SB), NOSPLIT, $0
-	B ·hypot(SB)
-
-TEXT ·Ldexp(SB), NOSPLIT, $0
-	B ·ldexp(SB)
-
-TEXT ·Log10(SB), NOSPLIT, $0
-	B ·log10(SB)
-
-TEXT ·Log2(SB), NOSPLIT, $0
-	B ·log2(SB)
-
-TEXT ·Log1p(SB), NOSPLIT, $0
-	B ·log1p(SB)
-
-TEXT ·Log(SB), NOSPLIT, $0
-	B ·log(SB)
-
-TEXT ·Mod(SB), NOSPLIT, $0
-	B ·mod(SB)
-
-TEXT ·Remainder(SB), NOSPLIT, $0
-	B ·remainder(SB)
-
-TEXT ·Sin(SB), NOSPLIT, $0
-	B ·sin(SB)
-
-TEXT ·Sinh(SB), NOSPLIT, $0
-	B ·sinh(SB)
-
-TEXT ·Cos(SB), NOSPLIT, $0
-	B ·cos(SB)
-
-TEXT ·Tan(SB), NOSPLIT, $0
-	B ·tan(SB)
-
-TEXT ·Tanh(SB), NOSPLIT, $0
-	B ·tanh(SB)
-
-TEXT ·Pow(SB), NOSPLIT, $0
-	B ·pow(SB)
diff --git a/src/math/stubs_mips64x.s b/src/math/stubs_mips64x.s
deleted file mode 100644
index 187b069..0000000
--- a/src/math/stubs_mips64x.s
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build mips64 mips64le
-
-#include "textflag.h"
-
-TEXT ·Asin(SB), NOSPLIT, $0
-	JMP ·asin(SB)
-
-TEXT ·Acos(SB), NOSPLIT, $0
-	JMP ·acos(SB)
-
-TEXT ·Asinh(SB), NOSPLIT, $0
-	JMP ·asinh(SB)
-
-TEXT ·Acosh(SB), NOSPLIT, $0
-	JMP ·acosh(SB)
-
-TEXT ·Atan2(SB), NOSPLIT, $0
-	JMP ·atan2(SB)
-
-TEXT ·Atan(SB), NOSPLIT, $0
-	JMP ·atan(SB)
-
-TEXT ·Atanh(SB), NOSPLIT, $0
-	JMP ·atanh(SB)
-
-TEXT ·Min(SB), NOSPLIT, $0
-	JMP ·min(SB)
-
-TEXT ·Max(SB), NOSPLIT, $0
-	JMP ·max(SB)
-
-TEXT ·Erf(SB), NOSPLIT, $0
-	JMP ·erf(SB)
-
-TEXT ·Erfc(SB), NOSPLIT, $0
-	JMP ·erfc(SB)
-
-TEXT ·Exp2(SB), NOSPLIT, $0
-	JMP ·exp2(SB)
-
-TEXT ·Expm1(SB), NOSPLIT, $0
-	JMP ·expm1(SB)
-
-TEXT ·Exp(SB), NOSPLIT, $0
-	JMP ·exp(SB)
-
-TEXT ·Floor(SB), NOSPLIT, $0
-	JMP ·floor(SB)
-
-TEXT ·Ceil(SB), NOSPLIT, $0
-	JMP ·ceil(SB)
-
-TEXT ·Trunc(SB), NOSPLIT, $0
-	JMP ·trunc(SB)
-
-TEXT ·Frexp(SB), NOSPLIT, $0
-	JMP ·frexp(SB)
-
-TEXT ·Hypot(SB), NOSPLIT, $0
-	JMP ·hypot(SB)
-
-TEXT ·Ldexp(SB), NOSPLIT, $0
-	JMP ·ldexp(SB)
-
-TEXT ·Log10(SB), NOSPLIT, $0
-	JMP ·log10(SB)
-
-TEXT ·Log2(SB), NOSPLIT, $0
-	JMP ·log2(SB)
-
-TEXT ·Log1p(SB), NOSPLIT, $0
-	JMP ·log1p(SB)
-
-TEXT ·Log(SB), NOSPLIT, $0
-	JMP ·log(SB)
-
-TEXT ·Modf(SB), NOSPLIT, $0
-	JMP ·modf(SB)
-
-TEXT ·Mod(SB), NOSPLIT, $0
-	JMP ·mod(SB)
-
-TEXT ·Remainder(SB), NOSPLIT, $0
-	JMP ·remainder(SB)
-
-TEXT ·Sin(SB), NOSPLIT, $0
-	JMP ·sin(SB)
-
-TEXT ·Sinh(SB), NOSPLIT, $0
-	JMP ·sinh(SB)
-
-TEXT ·Cos(SB), NOSPLIT, $0
-	JMP ·cos(SB)
-
-TEXT ·Cosh(SB), NOSPLIT, $0
-	JMP ·cosh(SB)
-
-TEXT ·Sqrt(SB), NOSPLIT, $0
-	JMP ·sqrt(SB)
-
-TEXT ·Tan(SB), NOSPLIT, $0
-	JMP ·tan(SB)
-
-TEXT ·Tanh(SB), NOSPLIT, $0
-	JMP ·tanh(SB)
-
-TEXT ·Cbrt(SB), NOSPLIT, $0
-	JMP ·cbrt(SB)
-
-TEXT ·Pow(SB), NOSPLIT, $0
-	JMP ·pow(SB)
diff --git a/src/math/stubs_mipsx.s b/src/math/stubs_mipsx.s
deleted file mode 100644
index 4b82449..0000000
--- a/src/math/stubs_mipsx.s
+++ /dev/null
@@ -1,113 +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.
-
-// +build mips mipsle
-
-#include "textflag.h"
-
-TEXT ·Asin(SB), NOSPLIT, $0
-	JMP ·asin(SB)
-
-TEXT ·Acos(SB), NOSPLIT, $0
-	JMP ·acos(SB)
-
-TEXT ·Asinh(SB), NOSPLIT, $0
-	JMP ·asinh(SB)
-
-TEXT ·Acosh(SB), NOSPLIT, $0
-	JMP ·acosh(SB)
-
-TEXT ·Atan2(SB), NOSPLIT, $0
-	JMP ·atan2(SB)
-
-TEXT ·Atan(SB), NOSPLIT, $0
-	JMP ·atan(SB)
-
-TEXT ·Atanh(SB), NOSPLIT, $0
-	JMP ·atanh(SB)
-
-TEXT ·Min(SB), NOSPLIT, $0
-	JMP ·min(SB)
-
-TEXT ·Max(SB), NOSPLIT, $0
-	JMP ·max(SB)
-
-TEXT ·Erf(SB), NOSPLIT, $0
-	JMP ·erf(SB)
-
-TEXT ·Erfc(SB), NOSPLIT, $0
-	JMP ·erfc(SB)
-
-TEXT ·Exp2(SB), NOSPLIT, $0
-	JMP ·exp2(SB)
-
-TEXT ·Expm1(SB), NOSPLIT, $0
-	JMP ·expm1(SB)
-
-TEXT ·Exp(SB), NOSPLIT, $0
-	JMP ·exp(SB)
-
-TEXT ·Floor(SB), NOSPLIT, $0
-	JMP ·floor(SB)
-
-TEXT ·Ceil(SB), NOSPLIT, $0
-	JMP ·ceil(SB)
-
-TEXT ·Trunc(SB), NOSPLIT, $0
-	JMP ·trunc(SB)
-
-TEXT ·Frexp(SB), NOSPLIT, $0
-	JMP ·frexp(SB)
-
-TEXT ·Hypot(SB), NOSPLIT, $0
-	JMP ·hypot(SB)
-
-TEXT ·Ldexp(SB), NOSPLIT, $0
-	JMP ·ldexp(SB)
-
-TEXT ·Log10(SB), NOSPLIT, $0
-	JMP ·log10(SB)
-
-TEXT ·Log2(SB), NOSPLIT, $0
-	JMP ·log2(SB)
-
-TEXT ·Log1p(SB), NOSPLIT, $0
-	JMP ·log1p(SB)
-
-TEXT ·Log(SB), NOSPLIT, $0
-	JMP ·log(SB)
-
-TEXT ·Modf(SB), NOSPLIT, $0
-	JMP ·modf(SB)
-
-TEXT ·Mod(SB), NOSPLIT, $0
-	JMP ·mod(SB)
-
-TEXT ·Remainder(SB), NOSPLIT, $0
-	JMP ·remainder(SB)
-
-TEXT ·Sin(SB), NOSPLIT, $0
-	JMP ·sin(SB)
-
-TEXT ·Sinh(SB), NOSPLIT, $0
-	JMP ·sinh(SB)
-
-TEXT ·Cos(SB), NOSPLIT, $0
-	JMP ·cos(SB)
-
-TEXT ·Cosh(SB), NOSPLIT, $0
-	JMP ·cosh(SB)
-
-TEXT ·Tan(SB), NOSPLIT, $0
-	JMP ·tan(SB)
-
-TEXT ·Tanh(SB), NOSPLIT, $0
-	JMP ·tanh(SB)
-
-TEXT ·Cbrt(SB), NOSPLIT, $0
-	JMP ·cbrt(SB)
-
-TEXT ·Pow(SB), NOSPLIT, $0
-	JMP ·pow(SB)
-
diff --git a/src/math/stubs_ppc64x.s b/src/math/stubs_ppc64x.s
deleted file mode 100644
index e7be07e..0000000
--- a/src/math/stubs_ppc64x.s
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ppc64 ppc64le
-
-#include "textflag.h"
-
-TEXT ·Asin(SB), NOSPLIT, $0
-	BR ·asin(SB)
-
-TEXT ·Acos(SB), NOSPLIT, $0
-	BR ·acos(SB)
-
-TEXT ·Asinh(SB), NOSPLIT, $0
-	BR ·asinh(SB)
-
-TEXT ·Acosh(SB), NOSPLIT, $0
-	BR ·acosh(SB)
-
-TEXT ·Atan2(SB), NOSPLIT, $0
-	BR ·atan2(SB)
-
-TEXT ·Atan(SB), NOSPLIT, $0
-	BR ·atan(SB)
-
-TEXT ·Atanh(SB), NOSPLIT, $0
-	BR ·atanh(SB)
-
-TEXT ·Min(SB), NOSPLIT, $0
-	BR ·min(SB)
-
-TEXT ·Max(SB), NOSPLIT, $0
-	BR ·max(SB)
-
-TEXT ·Erf(SB), NOSPLIT, $0
-	BR ·erf(SB)
-
-TEXT ·Erfc(SB), NOSPLIT, $0
-	BR ·erfc(SB)
-
-TEXT ·Exp2(SB), NOSPLIT, $0
-	BR ·exp2(SB)
-
-TEXT ·Expm1(SB), NOSPLIT, $0
-	BR ·expm1(SB)
-
-TEXT ·Exp(SB), NOSPLIT, $0
-	BR ·exp(SB)
-
-TEXT ·Frexp(SB), NOSPLIT, $0
-	BR ·frexp(SB)
-
-TEXT ·Hypot(SB), NOSPLIT, $0
-	BR ·hypot(SB)
-
-TEXT ·Ldexp(SB), NOSPLIT, $0
-	BR ·ldexp(SB)
-
-TEXT ·Log10(SB), NOSPLIT, $0
-	BR ·log10(SB)
-
-TEXT ·Log2(SB), NOSPLIT, $0
-	BR ·log2(SB)
-
-TEXT ·Log1p(SB), NOSPLIT, $0
-	BR ·log1p(SB)
-
-TEXT ·Log(SB), NOSPLIT, $0
-	BR ·log(SB)
-
-TEXT ·Mod(SB), NOSPLIT, $0
-	BR ·mod(SB)
-
-TEXT ·Remainder(SB), NOSPLIT, $0
-	BR ·remainder(SB)
-
-TEXT ·Sin(SB), NOSPLIT, $0
-	BR ·sin(SB)
-
-TEXT ·Sinh(SB), NOSPLIT, $0
-	BR ·sinh(SB)
-
-TEXT ·Cos(SB), NOSPLIT, $0
-	BR ·cos(SB)
-
-TEXT ·Cosh(SB), NOSPLIT, $0
-	BR ·cosh(SB)
-
-TEXT ·Tan(SB), NOSPLIT, $0
-	BR ·tan(SB)
-
-TEXT ·Tanh(SB), NOSPLIT, $0
-	BR ·tanh(SB)
-
-TEXT ·Cbrt(SB), NOSPLIT, $0
-	BR ·cbrt(SB)
-
-TEXT ·Pow(SB), NOSPLIT, $0
-	BR ·pow(SB)
-
diff --git a/src/math/stubs_riscv64.s b/src/math/stubs_riscv64.s
deleted file mode 100644
index b36efb8..0000000
--- a/src/math/stubs_riscv64.s
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-TEXT ·Asin(SB),NOSPLIT,$0
-	JMP ·asin(SB)
-
-TEXT ·Acos(SB),NOSPLIT,$0
-	JMP ·acos(SB)
-
-TEXT ·Asinh(SB),NOSPLIT,$0
-        JMP ·asinh(SB)
-
-TEXT ·Acosh(SB),NOSPLIT,$0
-        JMP ·acosh(SB)
-
-TEXT ·Atan2(SB),NOSPLIT,$0
-	JMP ·atan2(SB)
-
-TEXT ·Atan(SB),NOSPLIT,$0
-	JMP ·atan(SB)
-
-TEXT ·Atanh(SB),NOSPLIT,$0
-	JMP ·atanh(SB)
-
-TEXT ·Erf(SB),NOSPLIT,$0
-	JMP ·erf(SB)
-
-TEXT ·Erfc(SB),NOSPLIT,$0
-	JMP ·erfc(SB)
-
-TEXT ·Exp2(SB),NOSPLIT,$0
-	JMP ·exp2(SB)
-
-TEXT ·Expm1(SB),NOSPLIT,$0
-	JMP ·expm1(SB)
-
-TEXT ·Exp(SB),NOSPLIT,$0
-	JMP ·exp(SB)
-
-TEXT ·Floor(SB),NOSPLIT,$0
-	JMP ·floor(SB)
-
-TEXT ·Ceil(SB),NOSPLIT,$0
-	JMP ·ceil(SB)
-
-TEXT ·Trunc(SB),NOSPLIT,$0
-	JMP ·trunc(SB)
-
-TEXT ·Frexp(SB),NOSPLIT,$0
-	JMP ·frexp(SB)
-
-TEXT ·Hypot(SB),NOSPLIT,$0
-	JMP ·hypot(SB)
-
-TEXT ·Ldexp(SB),NOSPLIT,$0
-	JMP ·ldexp(SB)
-
-TEXT ·Log10(SB),NOSPLIT,$0
-	JMP ·log10(SB)
-
-TEXT ·Log2(SB),NOSPLIT,$0
-	JMP ·log2(SB)
-
-TEXT ·Log1p(SB),NOSPLIT,$0
-	JMP ·log1p(SB)
-
-TEXT ·Log(SB),NOSPLIT,$0
-	JMP ·log(SB)
-
-TEXT ·Modf(SB),NOSPLIT,$0
-	JMP ·modf(SB)
-
-TEXT ·Mod(SB),NOSPLIT,$0
-	JMP ·mod(SB)
-
-TEXT ·Remainder(SB),NOSPLIT,$0
-	JMP ·remainder(SB)
-
-TEXT ·Sin(SB),NOSPLIT,$0
-	JMP ·sin(SB)
-
-TEXT ·Sinh(SB),NOSPLIT,$0
-	JMP ·sinh(SB)
-
-TEXT ·Cos(SB),NOSPLIT,$0
-	JMP ·cos(SB)
-
-TEXT ·Cosh(SB),NOSPLIT,$0
-	JMP ·cosh(SB)
-
-TEXT ·Tan(SB),NOSPLIT,$0
-	JMP ·tan(SB)
-
-TEXT ·Tanh(SB),NOSPLIT,$0
-	JMP ·tanh(SB)
-
-TEXT ·Cbrt(SB),NOSPLIT,$0
-	JMP ·cbrt(SB)
-
-TEXT ·Pow(SB),NOSPLIT,$0
-	JMP ·pow(SB)
diff --git a/src/math/stubs_s390x.s b/src/math/stubs_s390x.s
index d0087ab..7400179 100644
--- a/src/math/stubs_s390x.s
+++ b/src/math/stubs_s390x.s
@@ -4,31 +4,7 @@
 
 #include "textflag.h"
 
-TEXT ·Exp2(SB), NOSPLIT, $0
-	BR ·exp2(SB)
-
-TEXT ·Frexp(SB), NOSPLIT, $0
-	BR ·frexp(SB)
-
-TEXT ·Hypot(SB), NOSPLIT, $0
-	BR ·hypot(SB)
-
-TEXT ·Ldexp(SB), NOSPLIT, $0
-	BR ·ldexp(SB)
-
-TEXT ·Log2(SB), NOSPLIT, $0
-	BR ·log2(SB)
-
-TEXT ·Modf(SB), NOSPLIT, $0
-	BR ·modf(SB)
-
-TEXT ·Mod(SB), NOSPLIT, $0
-	BR ·mod(SB)
-
-TEXT ·Remainder(SB), NOSPLIT, $0
-	BR ·remainder(SB)
-
-TEXT ·Log10(SB), NOSPLIT, $0
+TEXT ·archLog10(SB), NOSPLIT, $0
 	MOVD ·log10vectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -49,7 +25,7 @@
 GLOBL ·log10vectorfacility+0x00(SB), NOPTR, $8
 DATA ·log10vectorfacility+0x00(SB)/8, $·log10TrampolineSetup(SB)
 
-TEXT ·Cos(SB), NOSPLIT, $0
+TEXT ·archCos(SB), NOSPLIT, $0
 	MOVD ·cosvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -70,7 +46,7 @@
 GLOBL ·cosvectorfacility+0x00(SB), NOPTR, $8
 DATA ·cosvectorfacility+0x00(SB)/8, $·cosTrampolineSetup(SB)
 
-TEXT ·Cosh(SB), NOSPLIT, $0
+TEXT ·archCosh(SB), NOSPLIT, $0
 	MOVD ·coshvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -91,7 +67,7 @@
 GLOBL ·coshvectorfacility+0x00(SB), NOPTR, $8
 DATA ·coshvectorfacility+0x00(SB)/8, $·coshTrampolineSetup(SB)
 
-TEXT ·Sin(SB), NOSPLIT, $0
+TEXT ·archSin(SB), NOSPLIT, $0
 	MOVD ·sinvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -112,7 +88,7 @@
 GLOBL ·sinvectorfacility+0x00(SB), NOPTR, $8
 DATA ·sinvectorfacility+0x00(SB)/8, $·sinTrampolineSetup(SB)
 
-TEXT ·Sinh(SB), NOSPLIT, $0
+TEXT ·archSinh(SB), NOSPLIT, $0
 	MOVD ·sinhvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -133,7 +109,7 @@
 GLOBL ·sinhvectorfacility+0x00(SB), NOPTR, $8
 DATA ·sinhvectorfacility+0x00(SB)/8, $·sinhTrampolineSetup(SB)
 
-TEXT ·Tanh(SB), NOSPLIT, $0
+TEXT ·archTanh(SB), NOSPLIT, $0
 	MOVD ·tanhvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -154,7 +130,7 @@
 GLOBL ·tanhvectorfacility+0x00(SB), NOPTR, $8
 DATA ·tanhvectorfacility+0x00(SB)/8, $·tanhTrampolineSetup(SB)
 
-TEXT ·Log1p(SB), NOSPLIT, $0
+TEXT ·archLog1p(SB), NOSPLIT, $0
 	MOVD ·log1pvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -175,7 +151,7 @@
 GLOBL ·log1pvectorfacility+0x00(SB), NOPTR, $8
 DATA ·log1pvectorfacility+0x00(SB)/8, $·log1pTrampolineSetup(SB)
 
-TEXT ·Atanh(SB), NOSPLIT, $0
+TEXT ·archAtanh(SB), NOSPLIT, $0
 	MOVD ·atanhvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -196,7 +172,7 @@
 GLOBL ·atanhvectorfacility+0x00(SB), NOPTR, $8
 DATA ·atanhvectorfacility+0x00(SB)/8, $·atanhTrampolineSetup(SB)
 
-TEXT ·Acos(SB), NOSPLIT, $0
+TEXT ·archAcos(SB), NOSPLIT, $0
 	MOVD ·acosvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -217,7 +193,7 @@
 GLOBL ·acosvectorfacility+0x00(SB), NOPTR, $8
 DATA ·acosvectorfacility+0x00(SB)/8, $·acosTrampolineSetup(SB)
 
-TEXT ·Asin(SB), NOSPLIT, $0
+TEXT ·archAsin(SB), NOSPLIT, $0
 	MOVD ·asinvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -238,7 +214,7 @@
 GLOBL ·asinvectorfacility+0x00(SB), NOPTR, $8
 DATA ·asinvectorfacility+0x00(SB)/8, $·asinTrampolineSetup(SB)
 
-TEXT ·Asinh(SB), NOSPLIT, $0
+TEXT ·archAsinh(SB), NOSPLIT, $0
 	MOVD ·asinhvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -259,7 +235,7 @@
 GLOBL ·asinhvectorfacility+0x00(SB), NOPTR, $8
 DATA ·asinhvectorfacility+0x00(SB)/8, $·asinhTrampolineSetup(SB)
 
-TEXT ·Acosh(SB), NOSPLIT, $0
+TEXT ·archAcosh(SB), NOSPLIT, $0
 	MOVD ·acoshvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -280,7 +256,7 @@
 GLOBL ·acoshvectorfacility+0x00(SB), NOPTR, $8
 DATA ·acoshvectorfacility+0x00(SB)/8, $·acoshTrampolineSetup(SB)
 
-TEXT ·Erf(SB), NOSPLIT, $0
+TEXT ·archErf(SB), NOSPLIT, $0
 	MOVD ·erfvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -301,7 +277,7 @@
 GLOBL ·erfvectorfacility+0x00(SB), NOPTR, $8
 DATA ·erfvectorfacility+0x00(SB)/8, $·erfTrampolineSetup(SB)
 
-TEXT ·Erfc(SB), NOSPLIT, $0
+TEXT ·archErfc(SB), NOSPLIT, $0
 	MOVD ·erfcvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -322,7 +298,7 @@
 GLOBL ·erfcvectorfacility+0x00(SB), NOPTR, $8
 DATA ·erfcvectorfacility+0x00(SB)/8, $·erfcTrampolineSetup(SB)
 
-TEXT ·Atan(SB), NOSPLIT, $0
+TEXT ·archAtan(SB), NOSPLIT, $0
 	MOVD ·atanvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -343,7 +319,7 @@
 GLOBL ·atanvectorfacility+0x00(SB), NOPTR, $8
 DATA ·atanvectorfacility+0x00(SB)/8, $·atanTrampolineSetup(SB)
 
-TEXT ·Atan2(SB), NOSPLIT, $0
+TEXT ·archAtan2(SB), NOSPLIT, $0
 	MOVD ·atan2vectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -364,7 +340,7 @@
 GLOBL ·atan2vectorfacility+0x00(SB), NOPTR, $8
 DATA ·atan2vectorfacility+0x00(SB)/8, $·atan2TrampolineSetup(SB)
 
-TEXT ·Cbrt(SB), NOSPLIT, $0
+TEXT ·archCbrt(SB), NOSPLIT, $0
 	MOVD ·cbrtvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -385,7 +361,7 @@
 GLOBL ·cbrtvectorfacility+0x00(SB), NOPTR, $8
 DATA ·cbrtvectorfacility+0x00(SB)/8, $·cbrtTrampolineSetup(SB)
 
-TEXT ·Log(SB), NOSPLIT, $0
+TEXT ·archLog(SB), NOSPLIT, $0
 	MOVD ·logvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -406,7 +382,7 @@
 GLOBL ·logvectorfacility+0x00(SB), NOPTR, $8
 DATA ·logvectorfacility+0x00(SB)/8, $·logTrampolineSetup(SB)
 
-TEXT ·Tan(SB), NOSPLIT, $0
+TEXT ·archTan(SB), NOSPLIT, $0
 	MOVD ·tanvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -427,7 +403,7 @@
 GLOBL ·tanvectorfacility+0x00(SB), NOPTR, $8
 DATA ·tanvectorfacility+0x00(SB)/8, $·tanTrampolineSetup(SB)
 
-TEXT ·Exp(SB), NOSPLIT, $0
+TEXT ·archExp(SB), NOSPLIT, $0
 	MOVD ·expvectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -448,7 +424,7 @@
 GLOBL ·expvectorfacility+0x00(SB), NOPTR, $8
 DATA ·expvectorfacility+0x00(SB)/8, $·expTrampolineSetup(SB)
 
-TEXT ·Expm1(SB), NOSPLIT, $0
+TEXT ·archExpm1(SB), NOSPLIT, $0
 	MOVD ·expm1vectorfacility+0x00(SB), R1
 	BR   (R1)
 
@@ -469,7 +445,7 @@
 GLOBL ·expm1vectorfacility+0x00(SB), NOPTR, $8
 DATA ·expm1vectorfacility+0x00(SB)/8, $·expm1TrampolineSetup(SB)
 
-TEXT ·Pow(SB), NOSPLIT, $0
+TEXT ·archPow(SB), NOSPLIT, $0
 	MOVD ·powvectorfacility+0x00(SB), R1
 	BR   (R1)
 
diff --git a/src/math/stubs_wasm.s b/src/math/stubs_wasm.s
deleted file mode 100644
index c97a2d7..0000000
--- a/src/math/stubs_wasm.s
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-TEXT ·Asin(SB), NOSPLIT, $0
-	JMP ·asin(SB)
-
-TEXT ·Asinh(SB), NOSPLIT, $0
-	JMP ·asinh(SB)
-
-TEXT ·Acos(SB), NOSPLIT, $0
-	JMP ·acos(SB)
-
-TEXT ·Acosh(SB), NOSPLIT, $0
-	JMP ·acosh(SB)
-
-TEXT ·Atan(SB), NOSPLIT, $0
-	JMP ·atan(SB)
-
-TEXT ·Atanh(SB), NOSPLIT, $0
-	JMP ·atanh(SB)
-
-TEXT ·Atan2(SB), NOSPLIT, $0
-	JMP ·atan2(SB)
-
-TEXT ·Cbrt(SB), NOSPLIT, $0
-	JMP ·cbrt(SB)
-
-TEXT ·Cos(SB), NOSPLIT, $0
-	JMP ·cos(SB)
-
-TEXT ·Cosh(SB), NOSPLIT, $0
-	JMP ·cosh(SB)
-
-TEXT ·Erf(SB), NOSPLIT, $0
-	JMP ·erf(SB)
-
-TEXT ·Erfc(SB), NOSPLIT, $0
-	JMP ·erfc(SB)
-
-TEXT ·Exp(SB), NOSPLIT, $0
-	JMP ·exp(SB)
-
-TEXT ·Expm1(SB), NOSPLIT, $0
-	JMP ·expm1(SB)
-
-TEXT ·Exp2(SB), NOSPLIT, $0
-	JMP ·exp2(SB)
-
-TEXT ·Frexp(SB), NOSPLIT, $0
-	JMP ·frexp(SB)
-
-TEXT ·Hypot(SB), NOSPLIT, $0
-	JMP ·hypot(SB)
-
-TEXT ·Ldexp(SB), NOSPLIT, $0
-	JMP ·ldexp(SB)
-
-TEXT ·Log(SB), NOSPLIT, $0
-	JMP ·log(SB)
-
-TEXT ·Log1p(SB), NOSPLIT, $0
-	JMP ·log1p(SB)
-
-TEXT ·Log10(SB), NOSPLIT, $0
-	JMP ·log10(SB)
-
-TEXT ·Log2(SB), NOSPLIT, $0
-	JMP ·log2(SB)
-
-TEXT ·Max(SB), NOSPLIT, $0
-	JMP ·max(SB)
-
-TEXT ·Min(SB), NOSPLIT, $0
-	JMP ·min(SB)
-
-TEXT ·Mod(SB), NOSPLIT, $0
-	JMP ·mod(SB)
-
-TEXT ·Modf(SB), NOSPLIT, $0
-	JMP ·modf(SB)
-
-TEXT ·Pow(SB), NOSPLIT, $0
-	JMP ·pow(SB)
-
-TEXT ·Remainder(SB), NOSPLIT, $0
-	JMP ·remainder(SB)
-
-TEXT ·Sin(SB), NOSPLIT, $0
-	JMP ·sin(SB)
-
-TEXT ·Sinh(SB), NOSPLIT, $0
-	JMP ·sinh(SB)
-
-TEXT ·Tan(SB), NOSPLIT, $0
-	JMP ·tan(SB)
-
-TEXT ·Tanh(SB), NOSPLIT, $0
-	JMP ·tanh(SB)
diff --git a/src/math/tan.go b/src/math/tan.go
index 49b1239..a25417f 100644
--- a/src/math/tan.go
+++ b/src/math/tan.go
@@ -79,7 +79,12 @@
 //	Tan(±0) = ±0
 //	Tan(±Inf) = NaN
 //	Tan(NaN) = NaN
-func Tan(x float64) float64
+func Tan(x float64) float64 {
+	if haveArchTan {
+		return archTan(x)
+	}
+	return tan(x)
+}
 
 func tan(x float64) float64 {
 	const (
diff --git a/src/math/tanh.go b/src/math/tanh.go
index 0b7fb7f..a825678 100644
--- a/src/math/tanh.go
+++ b/src/math/tanh.go
@@ -71,7 +71,12 @@
 //	Tanh(±0) = ±0
 //	Tanh(±Inf) = ±1
 //	Tanh(NaN) = NaN
-func Tanh(x float64) float64
+func Tanh(x float64) float64 {
+	if haveArchTanh {
+		return archTanh(x)
+	}
+	return tanh(x)
+}
 
 func tanh(x float64) float64 {
 	const MAXLOG = 8.8029691931113054295988e+01 // log(2**127)
diff --git a/src/mime/multipart/multipart.go b/src/mime/multipart/multipart.go
index cb8bf39..81bf722 100644
--- a/src/mime/multipart/multipart.go
+++ b/src/mime/multipart/multipart.go
@@ -20,6 +20,7 @@
 	"mime"
 	"mime/quotedprintable"
 	"net/textproto"
+	"path/filepath"
 	"strings"
 )
 
@@ -67,13 +68,20 @@
 	return p.dispositionParams["name"]
 }
 
-// FileName returns the filename parameter of the Part's
-// Content-Disposition header.
+// FileName returns the filename parameter of the Part's Content-Disposition
+// header. If not empty, the filename is passed through filepath.Base (which is
+// platform dependent) before being returned.
 func (p *Part) FileName() string {
 	if p.dispositionParams == nil {
 		p.parseContentDisposition()
 	}
-	return p.dispositionParams["filename"]
+	filename := p.dispositionParams["filename"]
+	if filename == "" {
+		return ""
+	}
+	// RFC 7578, Section 4.2 requires that if a filename is provided, the
+	// directory path information must not be used.
+	return filepath.Base(filename)
 }
 
 func (p *Part) parseContentDisposition() {
diff --git a/src/mime/testdata/test.types.globs2 b/src/mime/testdata/test.types.globs2
new file mode 100644
index 0000000..cb5b789
--- /dev/null
+++ b/src/mime/testdata/test.types.globs2
@@ -0,0 +1,9 @@
+# Copyright 2021 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+
+# mime package test for globs2
+50:document/test:*.t3
+50:example/test:*.t4
+30:example/do-not-use:*.t4
diff --git a/src/mime/type.go b/src/mime/type.go
index 6d2b89e..2642433 100644
--- a/src/mime/type.go
+++ b/src/mime/type.go
@@ -58,6 +58,7 @@
 }
 
 var builtinTypesLower = map[string]string{
+	".avif": "image/avif",
 	".css":  "text/css; charset=utf-8",
 	".gif":  "image/gif",
 	".htm":  "text/html; charset=utf-8",
@@ -95,9 +96,11 @@
 // Extensions are looked up first case-sensitively, then case-insensitively.
 //
 // The built-in table is small but on unix it is augmented by the local
-// system's mime.types file(s) if available under one or more of these
-// names:
+// system's MIME-info database or mime.types file(s) if available under one or
+// more of these names:
 //
+//   /usr/local/share/mime/globs2
+//   /usr/share/mime/globs2
 //   /etc/mime.types
 //   /etc/apache2/mime.types
 //   /etc/apache/mime.types
diff --git a/src/mime/type_unix.go b/src/mime/type_unix.go
index 3a25002..f954bc8 100644
--- a/src/mime/type_unix.go
+++ b/src/mime/type_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package mime
@@ -16,6 +17,14 @@
 	osInitMime = initMimeUnix
 }
 
+// See https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-0.21.html
+// for the FreeDesktop Shared MIME-info Database specification.
+var mimeGlobs = []string{
+	"/usr/local/share/mime/globs2",
+	"/usr/share/mime/globs2",
+}
+
+// Common locations for mime.types files on unix.
 var typeFiles = []string{
 	"/etc/mime.types",
 	"/etc/apache2/mime.types",
@@ -23,6 +32,39 @@
 	"/etc/httpd/conf/mime.types",
 }
 
+func loadMimeGlobsFile(filename string) error {
+	f, err := os.Open(filename)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	scanner := bufio.NewScanner(f)
+	for scanner.Scan() {
+		// Each line should be of format: weight:mimetype:*.ext
+		fields := strings.Split(scanner.Text(), ":")
+		if len(fields) < 3 || len(fields[0]) < 1 || len(fields[2]) < 2 {
+			continue
+		} else if fields[0][0] == '#' || fields[2][0] != '*' {
+			continue
+		}
+
+		extension := fields[2][1:]
+		if _, ok := mimeTypes.Load(extension); ok {
+			// We've already seen this extension.
+			// The file is in weight order, so we keep
+			// the first entry that we see.
+			continue
+		}
+
+		setExtensionType(extension, fields[1])
+	}
+	if err := scanner.Err(); err != nil {
+		panic(err)
+	}
+	return nil
+}
+
 func loadMimeFile(filename string) {
 	f, err := os.Open(filename)
 	if err != nil {
@@ -50,12 +92,20 @@
 }
 
 func initMimeUnix() {
+	for _, filename := range mimeGlobs {
+		if err := loadMimeGlobsFile(filename); err == nil {
+			return // Stop checking more files if mimetype database is found.
+		}
+	}
+
+	// Fallback if no system-generated mimetype database exists.
 	for _, filename := range typeFiles {
 		loadMimeFile(filename)
 	}
 }
 
 func initMimeForTests() map[string]string {
+	mimeGlobs = []string{""}
 	typeFiles = []string{"testdata/test.types"}
 	return map[string]string{
 		".T1":  "application/test",
diff --git a/src/mime/type_unix_test.go b/src/mime/type_unix_test.go
new file mode 100644
index 0000000..6e29882
--- /dev/null
+++ b/src/mime/type_unix_test.go
@@ -0,0 +1,39 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
+// +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
+
+package mime
+
+import (
+	"testing"
+)
+
+func initMimeUnixTest(t *testing.T) {
+	err := loadMimeGlobsFile("testdata/test.types.globs2")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	loadMimeFile("testdata/test.types")
+}
+
+func TestTypeByExtensionUNIX(t *testing.T) {
+	initMimeUnixTest(t)
+	typeTests := map[string]string{
+		".T1":  "application/test",
+		".t2":  "text/test; charset=utf-8",
+		".t3":  "document/test",
+		".t4":  "example/test",
+		".png": "image/png",
+	}
+
+	for ext, want := range typeTests {
+		val := TypeByExtension(ext)
+		if val != want {
+			t.Errorf("TypeByExtension(%q) = %q, want %q", ext, val, want)
+		}
+	}
+}
diff --git a/src/net/addrselect.go b/src/net/addrselect.go
index 7c0dfe2..ae93c59 100644
--- a/src/net/addrselect.go
+++ b/src/net/addrselect.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 // Minimal RFC 6724 address selection.
diff --git a/src/net/addrselect_test.go b/src/net/addrselect_test.go
index d6e0e63..dc13917 100644
--- a/src/net/addrselect_test.go
+++ b/src/net/addrselect_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/cgo_aix.go b/src/net/cgo_aix.go
index d0ad414..a94405e 100644
--- a/src/net/cgo_aix.go
+++ b/src/net/cgo_aix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo && !netgo
 // +build cgo,!netgo
 
 package net
diff --git a/src/net/cgo_android.go b/src/net/cgo_android.go
index ab0368d..4b1a2e3 100644
--- a/src/net/cgo_android.go
+++ b/src/net/cgo_android.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo && !netgo
 // +build cgo,!netgo
 
 package net
diff --git a/src/net/cgo_bsd.go b/src/net/cgo_bsd.go
index a923c55..23be721 100644
--- a/src/net/cgo_bsd.go
+++ b/src/net/cgo_bsd.go
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build cgo,!netgo
+//go:build cgo && !netgo && (darwin || dragonfly || freebsd)
+// +build cgo
+// +build !netgo
 // +build darwin dragonfly freebsd
 
 package net
diff --git a/src/net/cgo_linux.go b/src/net/cgo_linux.go
index 86d8f4d..1bd6be9 100644
--- a/src/net/cgo_linux.go
+++ b/src/net/cgo_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !android && cgo && !netgo
 // +build !android,cgo,!netgo
 
 package net
diff --git a/src/net/cgo_netbsd.go b/src/net/cgo_netbsd.go
index 4610246..3714793 100644
--- a/src/net/cgo_netbsd.go
+++ b/src/net/cgo_netbsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo && !netgo
 // +build cgo,!netgo
 
 package net
diff --git a/src/net/cgo_openbsd.go b/src/net/cgo_openbsd.go
index 4610246..3714793 100644
--- a/src/net/cgo_openbsd.go
+++ b/src/net/cgo_openbsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo && !netgo
 // +build cgo,!netgo
 
 package net
diff --git a/src/net/cgo_resnew.go b/src/net/cgo_resnew.go
index 3e3e77e..1544052 100644
--- a/src/net/cgo_resnew.go
+++ b/src/net/cgo_resnew.go
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build cgo,!netgo
+//go:build cgo && !netgo && (darwin || (linux && !android) || netbsd || solaris)
+// +build cgo
+// +build !netgo
 // +build darwin linux,!android netbsd solaris
 
 package net
diff --git a/src/net/cgo_resold.go b/src/net/cgo_resold.go
index abd04a8..c4aab33 100644
--- a/src/net/cgo_resold.go
+++ b/src/net/cgo_resold.go
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build cgo,!netgo
+//go:build cgo && !netgo && (android || freebsd || dragonfly || openbsd)
+// +build cgo
+// +build !netgo
 // +build android freebsd dragonfly openbsd
 
 package net
diff --git a/src/net/cgo_socknew.go b/src/net/cgo_socknew.go
index 3b13926..f9cfad9 100644
--- a/src/net/cgo_socknew.go
+++ b/src/net/cgo_socknew.go
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build cgo,!netgo
+//go:build cgo && !netgo && (android || linux || solaris)
+// +build cgo
+// +build !netgo
 // +build android linux solaris
 
 package net
diff --git a/src/net/cgo_sockold.go b/src/net/cgo_sockold.go
index e1e642b..22c6725 100644
--- a/src/net/cgo_sockold.go
+++ b/src/net/cgo_sockold.go
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build cgo,!netgo
+//go:build cgo && !netgo && (aix || darwin || dragonfly || freebsd || netbsd || openbsd)
+// +build cgo
+// +build !netgo
 // +build aix darwin dragonfly freebsd netbsd openbsd
 
 package net
diff --git a/src/net/cgo_solaris.go b/src/net/cgo_solaris.go
index 25c0721..a84f5b0 100644
--- a/src/net/cgo_solaris.go
+++ b/src/net/cgo_solaris.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo && !netgo
 // +build cgo,!netgo
 
 package net
diff --git a/src/net/cgo_stub.go b/src/net/cgo_stub.go
index 041f8af..039e4be 100644
--- a/src/net/cgo_stub.go
+++ b/src/net/cgo_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !cgo || netgo
 // +build !cgo netgo
 
 package net
diff --git a/src/net/cgo_unix.go b/src/net/cgo_unix.go
index 69c99fe..2ea86e0 100644
--- a/src/net/cgo_unix.go
+++ b/src/net/cgo_unix.go
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build cgo,!netgo
+//go:build cgo && !netgo && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris)
+// +build cgo
+// +build !netgo
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/cgo_unix_test.go b/src/net/cgo_unix_test.go
index 99d79a6..1f3d9ea 100644
--- a/src/net/cgo_unix_test.go
+++ b/src/net/cgo_unix_test.go
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build cgo,!netgo
+//go:build cgo && !netgo && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris)
+// +build cgo
+// +build !netgo
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/cgo_windows.go b/src/net/cgo_windows.go
index 8968b75..1fd1f29 100644
--- a/src/net/cgo_windows.go
+++ b/src/net/cgo_windows.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo && !netgo
 // +build cgo,!netgo
 
 package net
diff --git a/src/net/conf.go b/src/net/conf.go
index f1bbfed..6b9569c 100644
--- a/src/net/conf.go
+++ b/src/net/conf.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/conf_netcgo.go b/src/net/conf_netcgo.go
index db4c703..8f387eb 100644
--- a/src/net/conf_netcgo.go
+++ b/src/net/conf_netcgo.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build netcgo
 // +build netcgo
 
 package net
diff --git a/src/net/conf_test.go b/src/net/conf_test.go
index 1fe3cf4..b1f2c55 100644
--- a/src/net/conf_test.go
+++ b/src/net/conf_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/conn_test.go b/src/net/conn_test.go
index 771cabc..45e271c 100644
--- a/src/net/conn_test.go
+++ b/src/net/conn_test.go
@@ -5,6 +5,7 @@
 // This file implements API tests across platforms and will never have a build
 // tag.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/dial.go b/src/net/dial.go
index 13a312a..486ced0 100644
--- a/src/net/dial.go
+++ b/src/net/dial.go
@@ -344,6 +344,9 @@
 //
 // See func Dial for a description of the network and address
 // parameters.
+//
+// Dial uses context.Background internally; to specify the context, use
+// DialContext.
 func (d *Dialer) Dial(network, address string) (Conn, error) {
 	return d.DialContext(context.Background(), network, address)
 }
@@ -701,6 +704,9 @@
 //
 // See func Dial for a description of the network and address
 // parameters.
+//
+// Listen uses context.Background internally; to specify the context, use
+// ListenConfig.Listen.
 func Listen(network, address string) (Listener, error) {
 	var lc ListenConfig
 	return lc.Listen(context.Background(), network, address)
@@ -728,6 +734,9 @@
 //
 // See func Dial for a description of the network and address
 // parameters.
+//
+// ListenPacket uses context.Background internally; to specify the context, use
+// ListenConfig.ListenPacket.
 func ListenPacket(network, address string) (PacketConn, error) {
 	var lc ListenConfig
 	return lc.ListenPacket(context.Background(), network, address)
diff --git a/src/net/dial_test.go b/src/net/dial_test.go
index 57cf555..723038c 100644
--- a/src/net/dial_test.go
+++ b/src/net/dial_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
@@ -154,40 +155,27 @@
 	return c, err
 }
 
-func dialClosedPort(t *testing.T) (actual, expected time.Duration) {
-	// Estimate the expected time for this platform.
-	// On Windows, dialing a closed port takes roughly 1 second,
-	// but other platforms should be instantaneous.
-	if runtime.GOOS == "windows" {
-		expected = 1500 * time.Millisecond
-	} else if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
-		expected = 150 * time.Millisecond
-	} else {
-		expected = 95 * time.Millisecond
-	}
+func dialClosedPort(t *testing.T) (dialLatency time.Duration) {
+	// On most platforms, dialing a closed port should be nearly instantaneous —
+	// less than a few hundred milliseconds. However, on some platforms it may be
+	// much slower: on Windows and OpenBSD, it has been observed to take up to a
+	// few seconds.
 
 	l, err := Listen("tcp", "127.0.0.1:0")
 	if err != nil {
-		t.Logf("dialClosedPort: Listen failed: %v", err)
-		return 999 * time.Hour, expected
+		t.Fatalf("dialClosedPort: Listen failed: %v", err)
 	}
 	addr := l.Addr().String()
 	l.Close()
-	// On OpenBSD, interference from TestTCPSelfConnect is mysteriously
-	// causing the first attempt to hang for a few seconds, so we throw
-	// away the first result and keep the second.
-	for i := 1; ; i++ {
-		startTime := time.Now()
-		c, err := Dial("tcp", addr)
-		if err == nil {
-			c.Close()
-		}
-		elapsed := time.Now().Sub(startTime)
-		if i == 2 {
-			t.Logf("dialClosedPort: measured delay %v", elapsed)
-			return elapsed, expected
-		}
+
+	startTime := time.Now()
+	c, err := Dial("tcp", addr)
+	if err == nil {
+		c.Close()
 	}
+	elapsed := time.Now().Sub(startTime)
+	t.Logf("dialClosedPort: measured delay %v", elapsed)
+	return elapsed
 }
 
 func TestDialParallel(t *testing.T) {
@@ -197,10 +185,7 @@
 		t.Skip("both IPv4 and IPv6 are required")
 	}
 
-	closedPortDelay, expectClosedPortDelay := dialClosedPort(t)
-	if closedPortDelay > expectClosedPortDelay {
-		t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
-	}
+	closedPortDelay := dialClosedPort(t)
 
 	const instant time.Duration = 0
 	const fallbackDelay = 200 * time.Millisecond
@@ -655,15 +640,7 @@
 		}
 		c, err := d.Dial(tt.network, addr)
 		if err == nil && tt.error != nil || err != nil && tt.error == nil {
-			// A suspected kernel bug in macOS 10.12 occasionally results in
-			// timeout errors when dialing address ::1. The errors have not
-			// been observed on newer versions of the OS, so we don't plan to work
-			// around them. See https://golang.org/issue/22019.
-			if tt.raddr == "::1" && os.Getenv("GO_BUILDER_NAME") == "darwin-amd64-10_12" && 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)
-			}
+			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 {
@@ -682,10 +659,7 @@
 		t.Skip("both IPv4 and IPv6 are required")
 	}
 
-	closedPortDelay, expectClosedPortDelay := dialClosedPort(t)
-	if closedPortDelay > expectClosedPortDelay {
-		t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
-	}
+	closedPortDelay := dialClosedPort(t)
 
 	origTestHookLookupIP := testHookLookupIP
 	defer func() { testHookLookupIP = origTestHookLookupIP }()
diff --git a/src/net/dial_unix_test.go b/src/net/dial_unix_test.go
index 3cfc9d8..108b973 100644
--- a/src/net/dial_unix_test.go
+++ b/src/net/dial_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/dnsclient.go b/src/net/dnsclient.go
index e9c7384..1bbe396 100644
--- a/src/net/dnsclient.go
+++ b/src/net/dnsclient.go
@@ -5,6 +5,7 @@
 package net
 
 import (
+	"internal/itoa"
 	"sort"
 
 	"golang.org/x/net/dns/dnsmessage"
@@ -33,7 +34,7 @@
 		return "", &DNSError{Err: "unrecognized address", Name: addr}
 	}
 	if ip.To4() != nil {
-		return uitoa(uint(ip[15])) + "." + uitoa(uint(ip[14])) + "." + uitoa(uint(ip[13])) + "." + uitoa(uint(ip[12])) + ".in-addr.arpa.", nil
+		return itoa.Uitoa(uint(ip[15])) + "." + itoa.Uitoa(uint(ip[14])) + "." + itoa.Uitoa(uint(ip[13])) + "." + itoa.Uitoa(uint(ip[12])) + ".in-addr.arpa.", nil
 	}
 	// Must be IPv6
 	buf := make([]byte, 0, len(ip)*4+len("ip6.arpa."))
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go
index d7db0c8..50e9bb0 100644
--- a/src/net/dnsclient_unix.go
+++ b/src/net/dnsclient_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 // DNS client: see RFC 1035.
@@ -17,6 +18,7 @@
 import (
 	"context"
 	"errors"
+	"internal/itoa"
 	"io"
 	"os"
 	"sync"
@@ -509,7 +511,7 @@
 	if s, ok := lookupOrderName[o]; ok {
 		return s
 	}
-	return "hostLookupOrder=" + itoa(int(o)) + "??"
+	return "hostLookupOrder=" + itoa.Itoa(int(o)) + "??"
 }
 
 // goLookupHost is the native Go implementation of LookupHost.
@@ -530,7 +532,7 @@
 			return
 		}
 	}
-	ips, _, err := r.goLookupIPCNAMEOrder(ctx, name, order)
+	ips, _, err := r.goLookupIPCNAMEOrder(ctx, "ip", name, order)
 	if err != nil {
 		return
 	}
@@ -556,13 +558,13 @@
 
 // goLookupIP is the native Go implementation of LookupIP.
 // The libc versions are in cgo_*.go.
-func (r *Resolver) goLookupIP(ctx context.Context, host string) (addrs []IPAddr, err error) {
+func (r *Resolver) goLookupIP(ctx context.Context, network, host string) (addrs []IPAddr, err error) {
 	order := systemConf().hostLookupOrder(r, host)
-	addrs, _, err = r.goLookupIPCNAMEOrder(ctx, host, order)
+	addrs, _, err = r.goLookupIPCNAMEOrder(ctx, network, host, order)
 	return
 }
 
-func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, name string, order hostLookupOrder) (addrs []IPAddr, cname dnsmessage.Name, err error) {
+func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name string, order hostLookupOrder) (addrs []IPAddr, cname dnsmessage.Name, err error) {
 	if order == hostLookupFilesDNS || order == hostLookupFiles {
 		addrs = goLookupIPFiles(name)
 		if len(addrs) > 0 || order == hostLookupFiles {
@@ -583,7 +585,13 @@
 		error
 	}
 	lane := make(chan result, 1)
-	qtypes := [...]dnsmessage.Type{dnsmessage.TypeA, dnsmessage.TypeAAAA}
+	qtypes := []dnsmessage.Type{dnsmessage.TypeA, dnsmessage.TypeAAAA}
+	switch ipVersion(network) {
+	case '4':
+		qtypes = []dnsmessage.Type{dnsmessage.TypeA}
+	case '6':
+		qtypes = []dnsmessage.Type{dnsmessage.TypeAAAA}
+	}
 	var queryFn func(fqdn string, qtype dnsmessage.Type)
 	var responseFn func(fqdn string, qtype dnsmessage.Type) result
 	if conf.singleRequest {
@@ -728,7 +736,7 @@
 // goLookupCNAME is the native Go (non-cgo) implementation of LookupCNAME.
 func (r *Resolver) goLookupCNAME(ctx context.Context, host string) (string, error) {
 	order := systemConf().hostLookupOrder(r, host)
-	_, cname, err := r.goLookupIPCNAMEOrder(ctx, host, order)
+	_, cname, err := r.goLookupIPCNAMEOrder(ctx, "ip", host, order)
 	return cname.String(), err
 }
 
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
index 0530c92..350ad5d 100644
--- a/src/net/dnsclient_unix_test.go
+++ b/src/net/dnsclient_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
@@ -600,14 +601,14 @@
 		name := fmt.Sprintf("order %v", order)
 
 		// First ensure that we get an error when contacting a non-existent host.
-		_, _, err := r.goLookupIPCNAMEOrder(context.Background(), "notarealhost", order)
+		_, _, err := r.goLookupIPCNAMEOrder(context.Background(), "ip", "notarealhost", order)
 		if err == nil {
 			t.Errorf("%s: expected error while looking up name not in hosts file", name)
 			continue
 		}
 
 		// Now check that we get an address when the name appears in the hosts file.
-		addrs, _, err := r.goLookupIPCNAMEOrder(context.Background(), "thor", order) // entry is in "testdata/hosts"
+		addrs, _, err := r.goLookupIPCNAMEOrder(context.Background(), "ip", "thor", order) // entry is in "testdata/hosts"
 		if err != nil {
 			t.Errorf("%s: expected to successfully lookup host entry", name)
 			continue
@@ -1798,3 +1799,325 @@
 		t.Errorf("names = %q; want %q", names, want)
 	}
 }
+
+func TestCVE202133195(t *testing.T) {
+	fake := fakeDNSServer{
+		rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
+			r := dnsmessage.Message{
+				Header: dnsmessage.Header{
+					ID:                 q.Header.ID,
+					Response:           true,
+					RCode:              dnsmessage.RCodeSuccess,
+					RecursionAvailable: true,
+				},
+				Questions: q.Questions,
+			}
+			switch q.Questions[0].Type {
+			case dnsmessage.TypeCNAME:
+				r.Answers = []dnsmessage.Resource{}
+			case dnsmessage.TypeA: // CNAME lookup uses a A/AAAA as a proxy
+				r.Answers = append(r.Answers,
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("<html>.golang.org."),
+							Type:   dnsmessage.TypeA,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.AResource{
+							A: TestAddr,
+						},
+					},
+				)
+			case dnsmessage.TypeSRV:
+				n := q.Questions[0].Name
+				if n.String() == "_hdr._tcp.golang.org." {
+					n = dnsmessage.MustNewName("<html>.golang.org.")
+				}
+				r.Answers = append(r.Answers,
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   n,
+							Type:   dnsmessage.TypeSRV,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.SRVResource{
+							Target: dnsmessage.MustNewName("<html>.golang.org."),
+						},
+					},
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   n,
+							Type:   dnsmessage.TypeSRV,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.SRVResource{
+							Target: dnsmessage.MustNewName("good.golang.org."),
+						},
+					},
+				)
+			case dnsmessage.TypeMX:
+				r.Answers = append(r.Answers,
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("<html>.golang.org."),
+							Type:   dnsmessage.TypeMX,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.MXResource{
+							MX: dnsmessage.MustNewName("<html>.golang.org."),
+						},
+					},
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("good.golang.org."),
+							Type:   dnsmessage.TypeMX,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.MXResource{
+							MX: dnsmessage.MustNewName("good.golang.org."),
+						},
+					},
+				)
+			case dnsmessage.TypeNS:
+				r.Answers = append(r.Answers,
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("<html>.golang.org."),
+							Type:   dnsmessage.TypeNS,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.NSResource{
+							NS: dnsmessage.MustNewName("<html>.golang.org."),
+						},
+					},
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("good.golang.org."),
+							Type:   dnsmessage.TypeNS,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.NSResource{
+							NS: dnsmessage.MustNewName("good.golang.org."),
+						},
+					},
+				)
+			case dnsmessage.TypePTR:
+				r.Answers = append(r.Answers,
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("<html>.golang.org."),
+							Type:   dnsmessage.TypePTR,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.PTRResource{
+							PTR: dnsmessage.MustNewName("<html>.golang.org."),
+						},
+					},
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("good.golang.org."),
+							Type:   dnsmessage.TypePTR,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.PTRResource{
+							PTR: dnsmessage.MustNewName("good.golang.org."),
+						},
+					},
+				)
+			}
+			return r, nil
+		},
+	}
+
+	r := Resolver{PreferGo: true, Dial: fake.DialContext}
+	// Change the default resolver to match our manipulated resolver
+	originalDefault := DefaultResolver
+	DefaultResolver = &r
+	defer func() { DefaultResolver = originalDefault }()
+	// Redirect host file lookups.
+	defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+	testHookHostsPath = "testdata/hosts"
+
+	tests := []struct {
+		name string
+		f    func(*testing.T)
+	}{
+		{
+			name: "CNAME",
+			f: func(t *testing.T) {
+				expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
+				_, err := r.LookupCNAME(context.Background(), "golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				_, err = LookupCNAME("golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+			},
+		},
+		{
+			name: "SRV (bad record)",
+			f: func(t *testing.T) {
+				expected := []*SRV{
+					{
+						Target: "good.golang.org.",
+					},
+				}
+				expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
+				_, records, err := r.LookupSRV(context.Background(), "target", "tcp", "golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+				_, records, err = LookupSRV("target", "tcp", "golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Errorf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+			},
+		},
+		{
+			name: "SRV (bad header)",
+			f: func(t *testing.T) {
+				_, _, err := r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org.")
+				if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected {
+					t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected)
+				}
+				_, _, err = LookupSRV("hdr", "tcp", "golang.org.")
+				if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected {
+					t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected)
+				}
+			},
+		},
+		{
+			name: "MX",
+			f: func(t *testing.T) {
+				expected := []*MX{
+					{
+						Host: "good.golang.org.",
+					},
+				}
+				expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
+				records, err := r.LookupMX(context.Background(), "golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+				records, err = LookupMX("golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+			},
+		},
+		{
+			name: "NS",
+			f: func(t *testing.T) {
+				expected := []*NS{
+					{
+						Host: "good.golang.org.",
+					},
+				}
+				expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
+				records, err := r.LookupNS(context.Background(), "golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+				records, err = LookupNS("golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+			},
+		},
+		{
+			name: "Addr",
+			f: func(t *testing.T) {
+				expected := []string{"good.golang.org."}
+				expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "192.0.2.42"}
+				records, err := r.LookupAddr(context.Background(), "192.0.2.42")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+				records, err = LookupAddr("192.0.2.42")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+			},
+		},
+	}
+
+	for _, tc := range tests {
+		t.Run(tc.name, tc.f)
+	}
+
+}
+
+func TestNullMX(t *testing.T) {
+	fake := fakeDNSServer{
+		rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
+			r := dnsmessage.Message{
+				Header: dnsmessage.Header{
+					ID:       q.Header.ID,
+					Response: true,
+					RCode:    dnsmessage.RCodeSuccess,
+				},
+				Questions: q.Questions,
+				Answers: []dnsmessage.Resource{
+					{
+						Header: dnsmessage.ResourceHeader{
+							Name:  q.Questions[0].Name,
+							Type:  dnsmessage.TypeMX,
+							Class: dnsmessage.ClassINET,
+						},
+						Body: &dnsmessage.MXResource{
+							MX: dnsmessage.MustNewName("."),
+						},
+					},
+				},
+			}
+			return r, nil
+		},
+	}
+	r := Resolver{PreferGo: true, Dial: fake.DialContext}
+	rrset, err := r.LookupMX(context.Background(), "golang.org")
+	if err != nil {
+		t.Fatalf("LookupMX: %v", err)
+	}
+	if want := []*MX{&MX{Host: "."}}; !reflect.DeepEqual(rrset, want) {
+		records := []string{}
+		for _, rr := range rrset {
+			records = append(records, fmt.Sprintf("%v", rr))
+		}
+		t.Errorf("records = [%v]; want [%v]", strings.Join(records, " "), want[0])
+	}
+}
diff --git a/src/net/dnsconfig_unix.go b/src/net/dnsconfig_unix.go
index 877e77c..db9213a 100644
--- a/src/net/dnsconfig_unix.go
+++ b/src/net/dnsconfig_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 // Read system DNS config from /etc/resolv.conf
diff --git a/src/net/dnsconfig_unix_test.go b/src/net/dnsconfig_unix_test.go
index 0d7897a..0e2317c 100644
--- a/src/net/dnsconfig_unix_test.go
+++ b/src/net/dnsconfig_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/dnsname_test.go b/src/net/dnsname_test.go
index 2964982..d851bf7 100644
--- a/src/net/dnsname_test.go
+++ b/src/net/dnsname_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/error_posix.go b/src/net/error_posix.go
index d709a27..50eb66f 100644
--- a/src/net/error_posix.go
+++ b/src/net/error_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package net
diff --git a/src/net/error_posix_test.go b/src/net/error_posix_test.go
index b411a37..ea52a45 100644
--- a/src/net/error_posix_test.go
+++ b/src/net/error_posix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !plan9
 // +build !plan9
 
 package net
diff --git a/src/net/error_test.go b/src/net/error_test.go
index 556eb8c..c304390 100644
--- a/src/net/error_test.go
+++ b/src/net/error_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/error_unix.go b/src/net/error_unix.go
index e615330..d0b5e2c 100644
--- a/src/net/error_unix.go
+++ b/src/net/error_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || js || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/error_unix_test.go b/src/net/error_unix_test.go
index 9ce9e12..533a45e 100644
--- a/src/net/error_unix_test.go
+++ b/src/net/error_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !plan9 && !windows
 // +build !plan9,!windows
 
 package net
diff --git a/src/net/external_test.go b/src/net/external_test.go
index f3c69c4..b8753cc 100644
--- a/src/net/external_test.go
+++ b/src/net/external_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/fcntl_libc_test.go b/src/net/fcntl_libc_test.go
new file mode 100644
index 0000000..0320d63
--- /dev/null
+++ b/src/net/fcntl_libc_test.go
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || solaris
+// +build aix darwin solaris
+
+package net
+
+import _ "unsafe" // for go:linkname
+
+// Implemented in the syscall package.
+//go:linkname fcntl syscall.fcntl
+func fcntl(fd int, cmd int, arg int) (int, error)
diff --git a/src/net/fcntl_syscall_test.go b/src/net/fcntl_syscall_test.go
new file mode 100644
index 0000000..0f04bb4
--- /dev/null
+++ b/src/net/fcntl_syscall_test.go
@@ -0,0 +1,21 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build dragonfly || freebsd || linux || netbsd || openbsd
+// +build dragonfly freebsd linux netbsd openbsd
+
+package net
+
+import (
+	"internal/syscall/unix"
+	"syscall"
+)
+
+func fcntl(fd int, cmd int, arg int) (int, error) {
+	r, _, e := syscall.Syscall(unix.FcntlSyscall, uintptr(fd), uintptr(cmd), uintptr(arg))
+	if e != 0 {
+		return int(r), syscall.Errno(e)
+	}
+	return int(r), nil
+}
diff --git a/src/net/fd_posix.go b/src/net/fd_posix.go
index 53abd15..4703ff3 100644
--- a/src/net/fd_posix.go
+++ b/src/net/fd_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package net
@@ -63,10 +64,10 @@
 	return n, sa, wrapSyscallError(readFromSyscallName, err)
 }
 
-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)
+func (fd *netFD) readMsg(p []byte, oob []byte, flags int) (n, oobn, retflags int, sa syscall.Sockaddr, err error) {
+	n, oobn, retflags, sa, err = fd.pfd.ReadMsg(p, oob, flags)
 	runtime.KeepAlive(fd)
-	return n, oobn, flags, sa, wrapSyscallError(readMsgSyscallName, err)
+	return n, oobn, retflags, sa, wrapSyscallError(readMsgSyscallName, err)
 }
 
 func (fd *netFD) Write(p []byte) (nn int, err error) {
diff --git a/src/net/fd_unix.go b/src/net/fd_unix.go
index 1c9bba3..a7bbdd2 100644
--- a/src/net/fd_unix.go
+++ b/src/net/fd_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/file_stub.go b/src/net/file_stub.go
index bfb8100..9f988fe 100644
--- a/src/net/file_stub.go
+++ b/src/net/file_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package net
diff --git a/src/net/file_test.go b/src/net/file_test.go
index 8c09c0d..a70ef1b 100644
--- a/src/net/file_test.go
+++ b/src/net/file_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/file_unix.go b/src/net/file_unix.go
index dba6955..4520d4b 100644
--- a/src/net/file_unix.go
+++ b/src/net/file_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/hook_unix.go b/src/net/hook_unix.go
index a28f1e0..b9153d1 100644
--- a/src/net/hook_unix.go
+++ b/src/net/hook_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/hosts_test.go b/src/net/hosts_test.go
index f850e2f..19c4399 100644
--- a/src/net/hosts_test.go
+++ b/src/net/hosts_test.go
@@ -36,7 +36,7 @@
 		},
 	},
 	{
-		"testdata/ipv4-hosts", // see golang.org/issue/8996
+		"testdata/ipv4-hosts",
 		[]staticHostEntry{
 			{"localhost", []string{"127.0.0.1", "127.0.0.2", "127.0.0.3"}},
 			{"localhost.localdomain", []string{"127.0.0.3"}},
@@ -102,7 +102,7 @@
 		},
 	},
 	{
-		"testdata/ipv4-hosts", // see golang.org/issue/8996
+		"testdata/ipv4-hosts",
 		[]staticHostEntry{
 			{"127.0.0.1", []string{"localhost"}},
 			{"127.0.0.2", []string{"localhost"}},
diff --git a/src/net/http/cgi/integration_test.go b/src/net/http/cgi/integration_test.go
index 76cbca8..ef2eaf7 100644
--- a/src/net/http/cgi/integration_test.go
+++ b/src/net/http/cgi/integration_test.go
@@ -95,12 +95,6 @@
 func TestKillChildAfterCopyError(t *testing.T) {
 	testenv.MustHaveExec(t)
 
-	defer func() { testHookStartProcess = nil }()
-	proc := make(chan *os.Process, 1)
-	testHookStartProcess = func(p *os.Process) {
-		proc <- p
-	}
-
 	h := &Handler{
 		Path: os.Args[0],
 		Root: "/test.go",
@@ -112,26 +106,9 @@
 	const writeLen = 50 << 10
 	rw := &customWriterRecorder{&limitWriter{&out, writeLen}, rec}
 
-	donec := make(chan bool, 1)
-	go func() {
-		h.ServeHTTP(rw, req)
-		donec <- true
-	}()
-
-	select {
-	case <-donec:
-		if out.Len() != writeLen || out.Bytes()[0] != 'a' {
-			t.Errorf("unexpected output: %q", out.Bytes())
-		}
-	case <-time.After(5 * time.Second):
-		t.Errorf("timeout. ServeHTTP hung and didn't kill the child process?")
-		select {
-		case p := <-proc:
-			p.Kill()
-			t.Logf("killed process")
-		default:
-			t.Logf("didn't kill process")
-		}
+	h.ServeHTTP(rw, req)
+	if out.Len() != writeLen || out.Bytes()[0] != 'a' {
+		t.Errorf("unexpected output: %q", out.Bytes())
 	}
 }
 
diff --git a/src/net/http/cgi/plan9_test.go b/src/net/http/cgi/plan9_test.go
index cc20fe0..f998bac 100644
--- a/src/net/http/cgi/plan9_test.go
+++ b/src/net/http/cgi/plan9_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build plan9
 // +build plan9
 
 package cgi
diff --git a/src/net/http/cgi/posix_test.go b/src/net/http/cgi/posix_test.go
index 9396ce0..bc58ea9 100644
--- a/src/net/http/cgi/posix_test.go
+++ b/src/net/http/cgi/posix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !plan9
 // +build !plan9
 
 package cgi
diff --git a/src/net/http/client.go b/src/net/http/client.go
index 88e2028..4d380c6 100644
--- a/src/net/http/client.go
+++ b/src/net/http/client.go
@@ -17,6 +17,7 @@
 	"fmt"
 	"io"
 	"log"
+	"net/http/internal/ascii"
 	"net/url"
 	"reflect"
 	"sort"
@@ -432,8 +433,7 @@
 // An error is returned if there were too many redirects or if there
 // was an HTTP protocol error. A non-2xx response doesn't cause an
 // error. Any returned error will be of type *url.Error. The url.Error
-// value's Timeout method will report true if request timed out or was
-// canceled.
+// value's Timeout method will report true if the request timed out.
 //
 // When err is nil, resp always contains a non-nil resp.Body.
 // Caller should close resp.Body when done reading from it.
@@ -442,6 +442,9 @@
 //
 // To make a request with custom headers, use NewRequest and
 // DefaultClient.Do.
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and DefaultClient.Do.
 func Get(url string) (resp *Response, err error) {
 	return DefaultClient.Get(url)
 }
@@ -466,6 +469,9 @@
 // Caller should close resp.Body when done reading from it.
 //
 // To make a request with custom headers, use NewRequest and Client.Do.
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and Client.Do.
 func (c *Client) Get(url string) (resp *Response, err error) {
 	req, err := NewRequest("GET", url, nil)
 	if err != nil {
@@ -541,7 +547,10 @@
 	if method == "" {
 		return "Get"
 	}
-	return method[:1] + strings.ToLower(method[1:])
+	if lowerMethod, ok := ascii.ToLower(method); ok {
+		return method[:1] + lowerMethod[1:]
+	}
+	return method
 }
 
 // Do sends an HTTP request and returns an HTTP response, following
@@ -579,8 +588,7 @@
 // standard library body types.
 //
 // Any returned error will be of type *url.Error. The url.Error
-// value's Timeout method will report true if request timed out or was
-// canceled.
+// value's Timeout method will report true if the request timed out.
 func (c *Client) Do(req *Request) (*Response, error) {
 	return c.do(req)
 }
@@ -719,7 +727,6 @@
 			reqBodyClosed = true
 			if !deadline.IsZero() && didTimeout() {
 				err = &httpError{
-					// TODO: early in cycle: s/Client.Timeout exceeded/timeout or context cancellation/
 					err:     err.Error() + " (Client.Timeout exceeded while awaiting headers)",
 					timeout: true,
 				}
@@ -821,6 +828,9 @@
 //
 // See the Client.Do method documentation for details on how redirects
 // are handled.
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and DefaultClient.Do.
 func Post(url, contentType string, body io.Reader) (resp *Response, err error) {
 	return DefaultClient.Post(url, contentType, body)
 }
@@ -834,6 +844,9 @@
 //
 // To set custom headers, use NewRequest and Client.Do.
 //
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and Client.Do.
+//
 // See the Client.Do method documentation for details on how redirects
 // are handled.
 func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, err error) {
@@ -858,6 +871,9 @@
 //
 // See the Client.Do method documentation for details on how redirects
 // are handled.
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and DefaultClient.Do.
 func PostForm(url string, data url.Values) (resp *Response, err error) {
 	return DefaultClient.PostForm(url, data)
 }
@@ -873,6 +889,9 @@
 //
 // See the Client.Do method documentation for details on how redirects
 // are handled.
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and Client.Do.
 func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) {
 	return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
 }
@@ -888,6 +907,9 @@
 //    308 (Permanent Redirect)
 //
 // Head is a wrapper around DefaultClient.Head
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and DefaultClient.Do.
 func Head(url string) (resp *Response, err error) {
 	return DefaultClient.Head(url)
 }
@@ -901,6 +923,9 @@
 //    303 (See Other)
 //    307 (Temporary Redirect)
 //    308 (Permanent Redirect)
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and Client.Do.
 func (c *Client) Head(url string) (resp *Response, err error) {
 	req, err := NewRequest("HEAD", url, nil)
 	if err != nil {
@@ -926,7 +951,7 @@
 }
 
 // cancelTimerBody is an io.ReadCloser that wraps rc with two features:
-// 1) on Read error or close, the stop func is called.
+// 1) On Read error or close, the stop func is called.
 // 2) On Read failure, if reqDidTimeout is true, the error is wrapped and
 //    marked as net.Error that hit its timeout.
 type cancelTimerBody struct {
diff --git a/src/net/http/client_test.go b/src/net/http/client_test.go
index d90b484..01d605c 100644
--- a/src/net/http/client_test.go
+++ b/src/net/http/client_test.go
@@ -257,12 +257,12 @@
 		t.Fatalf("Get error: %v", err)
 	}
 	res.Body.Close()
-	finalUrl := res.Request.URL.String()
+	finalURL := res.Request.URL.String()
 	if e, g := "<nil>", fmt.Sprintf("%v", err); e != g {
 		t.Errorf("with custom client, expected error %q, got %q", e, g)
 	}
-	if !strings.HasSuffix(finalUrl, "/?n=15") {
-		t.Errorf("expected final url to end in /?n=15; got url %q", finalUrl)
+	if !strings.HasSuffix(finalURL, "/?n=15") {
+		t.Errorf("expected final url to end in /?n=15; got url %q", finalURL)
 	}
 	if e, g := 15, len(lastVia); e != g {
 		t.Errorf("expected lastVia to have contained %d elements; got %d", e, g)
@@ -1945,7 +1945,7 @@
 }
 
 // Issue 33545: lock-in the behavior promised by Client.Do's
-// docs about request cancelation vs timing out.
+// docs about request cancellation vs timing out.
 func testClientDoCanceledVsTimeout(t *testing.T, h2 bool) {
 	defer afterTest(t)
 	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
diff --git a/src/net/http/cookie.go b/src/net/http/cookie.go
index 141bc94..ca2c1c2 100644
--- a/src/net/http/cookie.go
+++ b/src/net/http/cookie.go
@@ -7,6 +7,7 @@
 import (
 	"log"
 	"net"
+	"net/http/internal/ascii"
 	"net/textproto"
 	"strconv"
 	"strings"
@@ -93,15 +94,23 @@
 			if j := strings.Index(attr, "="); j >= 0 {
 				attr, val = attr[:j], attr[j+1:]
 			}
-			lowerAttr := strings.ToLower(attr)
+			lowerAttr, isASCII := ascii.ToLower(attr)
+			if !isASCII {
+				continue
+			}
 			val, ok = parseCookieValue(val, false)
 			if !ok {
 				c.Unparsed = append(c.Unparsed, parts[i])
 				continue
 			}
+
 			switch lowerAttr {
 			case "samesite":
-				lowerVal := strings.ToLower(val)
+				lowerVal, ascii := ascii.ToLower(val)
+				if !ascii {
+					c.SameSite = SameSiteDefaultMode
+					continue
+				}
 				switch lowerVal {
 				case "lax":
 					c.SameSite = SameSiteLaxMode
diff --git a/src/net/http/cookiejar/jar.go b/src/net/http/cookiejar/jar.go
index 9f19917..e6583da 100644
--- a/src/net/http/cookiejar/jar.go
+++ b/src/net/http/cookiejar/jar.go
@@ -10,6 +10,7 @@
 	"fmt"
 	"net"
 	"net/http"
+	"net/http/internal/ascii"
 	"net/url"
 	"sort"
 	"strings"
@@ -296,7 +297,6 @@
 // host name.
 func canonicalHost(host string) (string, error) {
 	var err error
-	host = strings.ToLower(host)
 	if hasPort(host) {
 		host, _, err = net.SplitHostPort(host)
 		if err != nil {
@@ -307,7 +307,13 @@
 		// Strip trailing dot from fully qualified domain names.
 		host = host[:len(host)-1]
 	}
-	return toASCII(host)
+	encoded, err := toASCII(host)
+	if err != nil {
+		return "", err
+	}
+	// We know this is ascii, no need to check.
+	lower, _ := ascii.ToLower(encoded)
+	return lower, nil
 }
 
 // hasPort reports whether host contains a port number. host may be a host
@@ -469,7 +475,12 @@
 		// both are illegal.
 		return "", false, errMalformedDomain
 	}
-	domain = strings.ToLower(domain)
+
+	domain, isASCII := ascii.ToLower(domain)
+	if !isASCII {
+		// Received non-ASCII domain, e.g. "perché.com" instead of "xn--perch-fsa.com"
+		return "", false, errMalformedDomain
+	}
 
 	if domain[len(domain)-1] == '.' {
 		// We received stuff like "Domain=www.example.com.".
diff --git a/src/net/http/cookiejar/punycode.go b/src/net/http/cookiejar/punycode.go
index a9cc666..c7f438d 100644
--- a/src/net/http/cookiejar/punycode.go
+++ b/src/net/http/cookiejar/punycode.go
@@ -8,6 +8,7 @@
 
 import (
 	"fmt"
+	"net/http/internal/ascii"
 	"strings"
 	"unicode/utf8"
 )
@@ -133,12 +134,12 @@
 // toASCII("bücher.example.com") is "xn--bcher-kva.example.com", and
 // toASCII("golang") is "golang".
 func toASCII(s string) (string, error) {
-	if ascii(s) {
+	if ascii.Is(s) {
 		return s, nil
 	}
 	labels := strings.Split(s, ".")
 	for i, label := range labels {
-		if !ascii(label) {
+		if !ascii.Is(label) {
 			a, err := encode(acePrefix, label)
 			if err != nil {
 				return "", err
@@ -148,12 +149,3 @@
 	}
 	return strings.Join(labels, "."), nil
 }
-
-func ascii(s string) bool {
-	for i := 0; i < len(s); i++ {
-		if s[i] >= utf8.RuneSelf {
-			return false
-		}
-	}
-	return true
-}
diff --git a/src/net/http/example_test.go b/src/net/http/example_test.go
index c677d52..2f411d1 100644
--- a/src/net/http/example_test.go
+++ b/src/net/http/example_test.go
@@ -45,12 +45,15 @@
 	if err != nil {
 		log.Fatal(err)
 	}
-	robots, err := io.ReadAll(res.Body)
+	body, err := io.ReadAll(res.Body)
 	res.Body.Close()
+	if res.StatusCode > 299 {
+		log.Fatalf("Response failed with status code: %d and\nbody: %s\n", res.StatusCode, body)
+	}
 	if err != nil {
 		log.Fatal(err)
 	}
-	fmt.Printf("%s", robots)
+	fmt.Printf("%s", body)
 }
 
 func ExampleFileServer() {
diff --git a/src/net/http/fcgi/child.go b/src/net/http/fcgi/child.go
index 756722b..dc82bf7 100644
--- a/src/net/http/fcgi/child.go
+++ b/src/net/http/fcgi/child.go
@@ -16,7 +16,6 @@
 	"net/http/cgi"
 	"os"
 	"strings"
-	"sync"
 	"time"
 )
 
@@ -154,7 +153,6 @@
 	conn    *conn
 	handler http.Handler
 
-	mu       sync.Mutex          // protects requests:
 	requests map[uint16]*request // keyed by request ID
 }
 
@@ -193,9 +191,7 @@
 var ErrConnClosed = errors.New("fcgi: connection to web server closed")
 
 func (c *child) handleRecord(rec *record) error {
-	c.mu.Lock()
 	req, ok := c.requests[rec.h.Id]
-	c.mu.Unlock()
 	if !ok && rec.h.Type != typeBeginRequest && rec.h.Type != typeGetValues {
 		// The spec says to ignore unknown request IDs.
 		return nil
@@ -218,9 +214,7 @@
 			return nil
 		}
 		req = newRequest(rec.h.Id, br.flags)
-		c.mu.Lock()
 		c.requests[rec.h.Id] = req
-		c.mu.Unlock()
 		return nil
 	case typeParams:
 		// NOTE(eds): Technically a key-value pair can straddle the boundary
@@ -248,8 +242,11 @@
 			// TODO(eds): This blocks until the handler reads from the pipe.
 			// If the handler takes a long time, it might be a problem.
 			req.pw.Write(content)
-		} else if req.pw != nil {
-			req.pw.Close()
+		} else {
+			delete(c.requests, req.reqId)
+			if req.pw != nil {
+				req.pw.Close()
+			}
 		}
 		return nil
 	case typeGetValues:
@@ -260,9 +257,7 @@
 		// If the filter role is implemented, read the data stream here.
 		return nil
 	case typeAbortRequest:
-		c.mu.Lock()
 		delete(c.requests, rec.h.Id)
-		c.mu.Unlock()
 		c.conn.writeEndRequest(rec.h.Id, 0, statusRequestComplete)
 		if req.pw != nil {
 			req.pw.CloseWithError(ErrRequestAborted)
@@ -309,9 +304,6 @@
 	// Make sure we serve something even if nothing was written to r
 	r.Write(nil)
 	r.Close()
-	c.mu.Lock()
-	delete(c.requests, req.reqId)
-	c.mu.Unlock()
 	c.conn.writeEndRequest(req.reqId, 0, statusRequestComplete)
 
 	// Consume the entire body, so the host isn't still writing to
@@ -330,8 +322,6 @@
 }
 
 func (c *child) cleanUp() {
-	c.mu.Lock()
-	defer c.mu.Unlock()
 	for _, req := range c.requests {
 		if req.pw != nil {
 			// race with call to Close in c.serveRequest doesn't matter because
diff --git a/src/net/http/fcgi/fcgi_test.go b/src/net/http/fcgi/fcgi_test.go
index b58111d..5888783 100644
--- a/src/net/http/fcgi/fcgi_test.go
+++ b/src/net/http/fcgi/fcgi_test.go
@@ -11,6 +11,7 @@
 	"net/http"
 	"strings"
 	"testing"
+	"time"
 )
 
 var sizeTests = []struct {
@@ -399,3 +400,55 @@
 		})
 	}
 }
+
+type signallingNopCloser struct {
+	io.Reader
+	closed chan bool
+}
+
+func (*signallingNopCloser) Write(buf []byte) (int, error) {
+	return len(buf), nil
+}
+
+func (rc *signallingNopCloser) Close() error {
+	close(rc.closed)
+	return nil
+}
+
+// Test whether server properly closes connection when processing slow
+// requests
+func TestSlowRequest(t *testing.T) {
+	pr, pw := io.Pipe()
+	go func(w io.Writer) {
+		for _, buf := range [][]byte{
+			streamBeginTypeStdin,
+			makeRecord(typeStdin, 1, nil),
+		} {
+			pw.Write(buf)
+			time.Sleep(100 * time.Millisecond)
+		}
+	}(pw)
+
+	rc := &signallingNopCloser{pr, make(chan bool)}
+	handlerDone := make(chan bool)
+
+	c := newChild(rc, http.HandlerFunc(func(
+		w http.ResponseWriter,
+		r *http.Request,
+	) {
+		w.WriteHeader(200)
+		close(handlerDone)
+	}))
+	go c.serve()
+	defer c.cleanUp()
+
+	timeout := time.After(2 * time.Second)
+
+	<-handlerDone
+	select {
+	case <-rc.closed:
+		t.Log("FastCGI child closed connection")
+	case <-timeout:
+		t.Error("FastCGI child did not close socket after handling request")
+	}
+}
diff --git a/src/net/http/filetransport_test.go b/src/net/http/filetransport_test.go
index b58888d..77fc8ee 100644
--- a/src/net/http/filetransport_test.go
+++ b/src/net/http/filetransport_test.go
@@ -23,12 +23,10 @@
 func TestFileTransport(t *testing.T) {
 	check := checker(t)
 
-	dname, err := os.MkdirTemp("", "")
-	check("TempDir", err)
+	dname := t.TempDir()
 	fname := filepath.Join(dname, "foo.txt")
-	err = os.WriteFile(fname, []byte("Bar"), 0644)
+	err := os.WriteFile(fname, []byte("Bar"), 0644)
 	check("WriteFile", err)
-	defer os.Remove(dname)
 	defer os.Remove(fname)
 
 	tr := &Transport{}
diff --git a/src/net/http/fs.go b/src/net/http/fs.go
index a28ae85..57e731e 100644
--- a/src/net/http/fs.go
+++ b/src/net/http/fs.go
@@ -46,7 +46,7 @@
 // to a possibly better non-nil error. In particular, it turns OS-specific errors
 // about opening files in non-directories into fs.ErrNotExist. See Issue 18984.
 func mapDirOpenError(originalErr error, name string) error {
-	if os.IsNotExist(originalErr) || os.IsPermission(originalErr) {
+	if errors.Is(originalErr, fs.ErrNotExist) || errors.Is(originalErr, fs.ErrPermission) {
 		return originalErr
 	}
 
@@ -670,10 +670,10 @@
 // and historically Go's ServeContent always returned just "404 Not Found" for
 // all errors. We don't want to start leaking information in error messages.
 func toHTTPError(err error) (msg string, httpStatus int) {
-	if os.IsNotExist(err) {
+	if errors.Is(err, fs.ErrNotExist) {
 		return "404 page not found", StatusNotFound
 	}
-	if os.IsPermission(err) {
+	if errors.Is(err, fs.ErrPermission) {
 		return "403 Forbidden", StatusForbidden
 	}
 	// Default:
diff --git a/src/net/http/fs_test.go b/src/net/http/fs_test.go
index 2499051..b42ade1 100644
--- a/src/net/http/fs_test.go
+++ b/src/net/http/fs_test.go
@@ -11,7 +11,6 @@
 	"fmt"
 	"io"
 	"io/fs"
-	"io/ioutil"
 	"mime"
 	"mime/multipart"
 	"net"
@@ -379,11 +378,7 @@
 
 func TestFileServerImplicitLeadingSlash(t *testing.T) {
 	defer afterTest(t)
-	tempDir, err := os.MkdirTemp("", "")
-	if err != nil {
-		t.Fatalf("TempDir: %v", err)
-	}
-	defer mustRemoveAll(tempDir)
+	tempDir := t.TempDir()
 	if err := os.WriteFile(filepath.Join(tempDir, "foo.txt"), []byte("Hello world"), 0644); err != nil {
 		t.Fatalf("WriteFile: %v", err)
 	}
@@ -593,7 +588,7 @@
 				if err != nil {
 					t.Fatal(err)
 				}
-				b, err := ioutil.ReadAll(res.Body)
+				b, err := io.ReadAll(res.Body)
 				if err != nil {
 					t.Fatal("reading Body:", err)
 				}
@@ -1270,16 +1265,18 @@
 			if err == nil {
 				t.Fatal("err == nil; want != nil")
 			}
-			if !os.IsNotExist(err) {
-				t.Errorf("err = %v; os.IsNotExist(err) = %v; want true", err, os.IsNotExist(err))
+			if !errors.Is(err, fs.ErrNotExist) {
+				t.Errorf("err = %v; errors.Is(err, fs.ErrNotExist) = %v; want true", err,
+					errors.Is(err, fs.ErrNotExist))
 			}
 
 			_, err = dir.Open("/index.html/not-a-dir/not-a-file")
 			if err == nil {
 				t.Fatal("err == nil; want != nil")
 			}
-			if !os.IsNotExist(err) {
-				t.Errorf("err = %v; os.IsNotExist(err) = %v; want true", err, os.IsNotExist(err))
+			if !errors.Is(err, fs.ErrNotExist) {
+				t.Errorf("err = %v; errors.Is(err, fs.ErrNotExist) = %v; want true", err,
+					errors.Is(err, fs.ErrNotExist))
 			}
 		})
 	}
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index 6bef310..a948ff3 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -1,3 +1,4 @@
+//go:build !nethttpomithttp2
 // +build !nethttpomithttp2
 
 // Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
@@ -52,6 +53,48 @@
 	"golang.org/x/net/idna"
 )
 
+// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t
+// are equal, ASCII-case-insensitively.
+func http2asciiEqualFold(s, t string) bool {
+	if len(s) != len(t) {
+		return false
+	}
+	for i := 0; i < len(s); i++ {
+		if http2lower(s[i]) != http2lower(t[i]) {
+			return false
+		}
+	}
+	return true
+}
+
+// lower returns the ASCII lowercase version of b.
+func http2lower(b byte) byte {
+	if 'A' <= b && b <= 'Z' {
+		return b + ('a' - 'A')
+	}
+	return b
+}
+
+// isASCIIPrint returns whether s is ASCII and printable according to
+// https://tools.ietf.org/html/rfc20#section-4.2.
+func http2isASCIIPrint(s string) bool {
+	for i := 0; i < len(s); i++ {
+		if s[i] < ' ' || s[i] > '~' {
+			return false
+		}
+	}
+	return true
+}
+
+// asciiToLower returns the lowercase version of s if s is ASCII and printable,
+// and whether or not it was.
+func http2asciiToLower(s string) (lower string, ok bool) {
+	if !http2isASCIIPrint(s) {
+		return "", false
+	}
+	return strings.ToLower(s), true
+}
+
 // A list of the possible cipher suite ids. Taken from
 // https://www.iana.org/assignments/tls-parameters/tls-parameters.txt
 
@@ -754,61 +797,69 @@
 		// It gets its own connection.
 		http2traceGetConn(req, addr)
 		const singleUse = true
-		cc, err := p.t.dialClientConn(addr, singleUse)
+		cc, err := p.t.dialClientConn(req.Context(), addr, singleUse)
 		if err != nil {
 			return nil, err
 		}
 		return cc, nil
 	}
-	p.mu.Lock()
-	for _, cc := range p.conns[addr] {
-		if st := cc.idleState(); st.canTakeNewRequest {
-			if p.shouldTraceGetConn(st) {
-				http2traceGetConn(req, addr)
+	for {
+		p.mu.Lock()
+		for _, cc := range p.conns[addr] {
+			if st := cc.idleState(); st.canTakeNewRequest {
+				if p.shouldTraceGetConn(st) {
+					http2traceGetConn(req, addr)
+				}
+				p.mu.Unlock()
+				return cc, nil
 			}
-			p.mu.Unlock()
-			return cc, nil
 		}
-	}
-	if !dialOnMiss {
+		if !dialOnMiss {
+			p.mu.Unlock()
+			return nil, http2ErrNoCachedConn
+		}
+		http2traceGetConn(req, addr)
+		call := p.getStartDialLocked(req.Context(), addr)
 		p.mu.Unlock()
-		return nil, http2ErrNoCachedConn
+		<-call.done
+		if http2shouldRetryDial(call, req) {
+			continue
+		}
+		return call.res, call.err
 	}
-	http2traceGetConn(req, addr)
-	call := p.getStartDialLocked(addr)
-	p.mu.Unlock()
-	<-call.done
-	return call.res, call.err
 }
 
 // dialCall is an in-flight Transport dial call to a host.
 type http2dialCall struct {
-	_    http2incomparable
-	p    *http2clientConnPool
+	_ http2incomparable
+	p *http2clientConnPool
+	// the context associated with the request
+	// that created this dialCall
+	ctx  context.Context
 	done chan struct{}    // closed when done
 	res  *http2ClientConn // valid after done is closed
 	err  error            // valid after done is closed
 }
 
 // requires p.mu is held.
-func (p *http2clientConnPool) getStartDialLocked(addr string) *http2dialCall {
+func (p *http2clientConnPool) getStartDialLocked(ctx context.Context, addr string) *http2dialCall {
 	if call, ok := p.dialing[addr]; ok {
 		// A dial is already in-flight. Don't start another.
 		return call
 	}
-	call := &http2dialCall{p: p, done: make(chan struct{})}
+	call := &http2dialCall{p: p, done: make(chan struct{}), ctx: ctx}
 	if p.dialing == nil {
 		p.dialing = make(map[string]*http2dialCall)
 	}
 	p.dialing[addr] = call
-	go call.dial(addr)
+	go call.dial(call.ctx, addr)
 	return call
 }
 
 // run in its own goroutine.
-func (c *http2dialCall) dial(addr string) {
+func (c *http2dialCall) dial(ctx context.Context, addr string) {
 	const singleUse = false // shared conn
-	c.res, c.err = c.p.t.dialClientConn(addr, singleUse)
+	c.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse)
 	close(c.done)
 
 	c.p.mu.Lock()
@@ -953,6 +1004,31 @@
 	return p.getClientConn(req, addr, http2noDialOnMiss)
 }
 
+// shouldRetryDial reports whether the current request should
+// retry dialing after the call finished unsuccessfully, for example
+// if the dial was canceled because of a context cancellation or
+// deadline expiry.
+func http2shouldRetryDial(call *http2dialCall, req *Request) bool {
+	if call.err == nil {
+		// No error, no need to retry
+		return false
+	}
+	if call.ctx == req.Context() {
+		// If the call has the same context as the request, the dial
+		// should not be retried, since any cancellation will have come
+		// from this request.
+		return false
+	}
+	if !errors.Is(call.err, context.Canceled) && !errors.Is(call.err, context.DeadlineExceeded) {
+		// If the call error is not because of a context cancellation or a deadline expiry,
+		// the dial should not be retried.
+		return false
+	}
+	// Only retry if the error is a context cancellation error or deadline expiry
+	// and the context associated with the call was canceled or expired.
+	return call.ctx.Err() != nil
+}
+
 // Buffer chunks are allocated from a pool to reduce pressure on GC.
 // The maximum wasted space per dataBuffer is 2x the largest size class,
 // which happens when the dataBuffer has multiple chunks and there is
@@ -2873,6 +2949,20 @@
 	return nil
 }
 
+// dialTLSWithContext uses tls.Dialer, added in Go 1.15, to open a TLS
+// connection.
+func (t *http2Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) {
+	dialer := &tls.Dialer{
+		Config: cfg,
+	}
+	cn, err := dialer.DialContext(ctx, network, addr)
+	if err != nil {
+		return nil, err
+	}
+	tlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed
+	return tlsCn, nil
+}
+
 var http2DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
 
 type http2goroutineLock uint64
@@ -3094,12 +3184,12 @@
 	}
 }
 
-func http2lowerHeader(v string) string {
+func http2lowerHeader(v string) (lower string, ascii bool) {
 	http2buildCommonHeaderMapsOnce()
 	if s, ok := http2commonLowerHeader[v]; ok {
-		return s
+		return s, true
 	}
-	return strings.ToLower(v)
+	return http2asciiToLower(v)
 }
 
 var (
@@ -3797,13 +3887,12 @@
 
 	if s.TLSConfig == nil {
 		s.TLSConfig = new(tls.Config)
-	} 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 or ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
+	} else if s.TLSConfig.CipherSuites != nil && s.TLSConfig.MinVersion < tls.VersionTLS13 {
+		// If they already provided a TLS 1.0–1.2 CipherSuite list, return an
+		// error if it is missing 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 {
+		for _, cs := range s.TLSConfig.CipherSuites {
 			switch cs {
 			case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
 				// Alternative MTI cipher to not discourage ECDSA-only servers.
@@ -3811,14 +3900,9 @@
 				tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
 				haveRequired = true
 			}
-			if http2isBadCipher(cs) {
-				sawBad = true
-			} else if sawBad {
-				return fmt.Errorf("http2: TLSConfig.CipherSuites index %d contains an HTTP/2-approved cipher suite (%#04x), but it comes after unapproved cipher suites. With this configuration, clients that don't support previous, approved cipher suites may be given an unapproved one and reject the connection.", i, cs)
-			}
 		}
 		if !haveRequired {
-			return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).")
+			return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)")
 		}
 	}
 
@@ -4864,7 +4948,9 @@
 	sc.shutdownOnce.Do(func() { sc.sendServeMsg(http2gracefulShutdownMsg) })
 }
 
-// After sending GOAWAY, the connection will close after goAwayTimeout.
+// After sending GOAWAY with an error code (non-graceful shutdown), 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
@@ -5200,23 +5286,37 @@
 
 func (sc *http2serverConn) processData(f *http2DataFrame) error {
 	sc.serveG.check()
-	if sc.inGoAway && sc.goAwayCode != http2ErrCodeNo {
+	id := f.Header().StreamID
+	if sc.inGoAway && (sc.goAwayCode != http2ErrCodeNo || id > sc.maxClientStreamID) {
+		// Discard all DATA frames if the GOAWAY is due to an
+		// error, or:
+		//
+		// Section 6.8: After sending a GOAWAY frame, the sender
+		// can discard frames for streams initiated by the
+		// receiver with identifiers higher than the identified
+		// last stream.
 		return nil
 	}
-	data := f.Data()
 
-	// "If a DATA frame is received whose stream is not in "open"
-	// or "half closed (local)" state, the recipient MUST respond
-	// with a stream error (Section 5.4.2) of type STREAM_CLOSED."
-	id := f.Header().StreamID
+	data := f.Data()
 	state, st := sc.state(id)
 	if id == 0 || state == http2stateIdle {
+		// Section 6.1: "DATA frames MUST be associated with a
+		// stream. If a DATA frame is received whose stream
+		// identifier field is 0x0, the recipient MUST respond
+		// with a connection error (Section 5.4.1) of type
+		// PROTOCOL_ERROR."
+		//
 		// Section 5.1: "Receiving any frame other than HEADERS
 		// or PRIORITY on a stream in this state MUST be
 		// treated as a connection error (Section 5.4.1) of
 		// type PROTOCOL_ERROR."
 		return http2ConnectionError(http2ErrCodeProtocol)
 	}
+
+	// "If a DATA frame is received whose stream is not in "open"
+	// or "half closed (local)" state, the recipient MUST respond
+	// with a stream error (Section 5.4.2) of type STREAM_CLOSED."
 	if st == nil || state != http2stateOpen || st.gotTrailerHeader || st.resetQueued {
 		// This includes sending a RST_STREAM if the stream is
 		// in stateHalfClosedLocal (which currently means that
@@ -6344,8 +6444,12 @@
 		// but PUSH_PROMISE requests cannot have a body.
 		// http://tools.ietf.org/html/rfc7540#section-8.2
 		// Also disallow Host, since the promised URL must be absolute.
-		switch strings.ToLower(k) {
-		case "content-length", "content-encoding", "trailer", "te", "expect", "host":
+		if http2asciiEqualFold(k, "content-length") ||
+			http2asciiEqualFold(k, "content-encoding") ||
+			http2asciiEqualFold(k, "trailer") ||
+			http2asciiEqualFold(k, "te") ||
+			http2asciiEqualFold(k, "expect") ||
+			http2asciiEqualFold(k, "host") {
 			return fmt.Errorf("promised request headers cannot include %q", k)
 		}
 	}
@@ -7067,12 +7171,12 @@
 	return false
 }
 
-func (t *http2Transport) dialClientConn(addr string, singleUse bool) (*http2ClientConn, error) {
+func (t *http2Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*http2ClientConn, error) {
 	host, _, err := net.SplitHostPort(addr)
 	if err != nil {
 		return nil, err
 	}
-	tconn, err := t.dialTLS()("tcp", addr, t.newTLSConfig(host))
+	tconn, err := t.dialTLS(ctx)("tcp", addr, t.newTLSConfig(host))
 	if err != nil {
 		return nil, err
 	}
@@ -7093,34 +7197,24 @@
 	return cfg
 }
 
-func (t *http2Transport) dialTLS() func(string, string, *tls.Config) (net.Conn, error) {
+func (t *http2Transport) dialTLS(ctx context.Context) func(string, string, *tls.Config) (net.Conn, error) {
 	if t.DialTLS != nil {
 		return t.DialTLS
 	}
-	return t.dialTLSDefault
-}
-
-func (t *http2Transport) dialTLSDefault(network, addr string, cfg *tls.Config) (net.Conn, error) {
-	cn, err := tls.Dial(network, addr, cfg)
-	if err != nil {
-		return nil, err
-	}
-	if err := cn.Handshake(); err != nil {
-		return nil, err
-	}
-	if !cfg.InsecureSkipVerify {
-		if err := cn.VerifyHostname(cfg.ServerName); err != nil {
+	return func(network, addr string, cfg *tls.Config) (net.Conn, error) {
+		tlsCn, err := t.dialTLSWithContext(ctx, network, addr, cfg)
+		if err != nil {
 			return nil, err
 		}
+		state := tlsCn.ConnectionState()
+		if p := state.NegotiatedProtocol; p != http2NextProtoTLS {
+			return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, http2NextProtoTLS)
+		}
+		if !state.NegotiatedProtocolIsMutual {
+			return nil, errors.New("http2: could not negotiate protocol mutually")
+		}
+		return tlsCn, nil
 	}
-	state := cn.ConnectionState()
-	if p := state.NegotiatedProtocol; p != http2NextProtoTLS {
-		return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, http2NextProtoTLS)
-	}
-	if !state.NegotiatedProtocolIsMutual {
-		return nil, errors.New("http2: could not negotiate protocol mutually")
-	}
-	return cn, nil
 }
 
 // disableKeepAlives reports whether connections should be closed as
@@ -7508,7 +7602,7 @@
 	if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") {
 		return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv)
 	}
-	if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !strings.EqualFold(vv[0], "close") && !strings.EqualFold(vv[0], "keep-alive")) {
+	if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !http2asciiEqualFold(vv[0], "close") && !http2asciiEqualFold(vv[0], "keep-alive")) {
 		return fmt.Errorf("http2: invalid Connection request header: %q", vv)
 	}
 	return nil
@@ -8034,19 +8128,21 @@
 
 		var didUA bool
 		for k, vv := range req.Header {
-			if strings.EqualFold(k, "host") || strings.EqualFold(k, "content-length") {
+			if http2asciiEqualFold(k, "host") || http2asciiEqualFold(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") {
+			} else if http2asciiEqualFold(k, "connection") ||
+				http2asciiEqualFold(k, "proxy-connection") ||
+				http2asciiEqualFold(k, "transfer-encoding") ||
+				http2asciiEqualFold(k, "upgrade") ||
+				http2asciiEqualFold(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") {
+			} else if http2asciiEqualFold(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,
@@ -8059,7 +8155,7 @@
 				if vv[0] == "" {
 					continue
 				}
-			} else if strings.EqualFold(k, "cookie") {
+			} else if http2asciiEqualFold(k, "cookie") {
 				// Per 8.1.2.5 To allow for better compression efficiency, the
 				// Cookie header field MAY be split into separate header fields,
 				// each with one or more cookie-pairs.
@@ -8118,7 +8214,12 @@
 
 	// Header list size is ok. Write the headers.
 	enumerateHeaders(func(name, value string) {
-		name = strings.ToLower(name)
+		name, ascii := http2asciiToLower(name)
+		if !ascii {
+			// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
+			// field names have to be ASCII characters (just as in HTTP/1.x).
+			return
+		}
 		cc.writeHeader(name, value)
 		if traceHeaders {
 			http2traceWroteHeaderField(trace, name, value)
@@ -8166,9 +8267,14 @@
 	}
 
 	for k, vv := range req.Trailer {
+		lowKey, ascii := http2asciiToLower(k)
+		if !ascii {
+			// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
+			// field names have to be ASCII characters (just as in HTTP/1.x).
+			continue
+		}
 		// Transfer-Encoding, etc.. have already been filtered at the
 		// start of RoundTrip
-		lowKey := strings.ToLower(k)
 		for _, v := range vv {
 			cc.writeHeader(lowKey, v)
 		}
@@ -9591,7 +9697,12 @@
 	}
 	for _, k := range keys {
 		vv := h[k]
-		k = http2lowerHeader(k)
+		k, ascii := http2lowerHeader(k)
+		if !ascii {
+			// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
+			// field names have to be ASCII characters (just as in HTTP/1.x).
+			continue
+		}
 		if !http2validWireHeaderFieldName(k) {
 			// Skip it as backup paranoia. Per
 			// golang.org/issue/14048, these should
diff --git a/src/net/http/header.go b/src/net/http/header.go
index b9b5391..4c72dcb 100644
--- a/src/net/http/header.go
+++ b/src/net/http/header.go
@@ -7,6 +7,7 @@
 import (
 	"io"
 	"net/http/httptrace"
+	"net/http/internal/ascii"
 	"net/textproto"
 	"sort"
 	"strings"
@@ -251,7 +252,7 @@
 		if endPos := sp + len(token); endPos != len(v) && !isTokenBoundary(v[endPos]) {
 			continue
 		}
-		if strings.EqualFold(v[sp:sp+len(token)], token) {
+		if ascii.EqualFold(v[sp:sp+len(token)], token) {
 			return true
 		}
 	}
diff --git a/src/net/http/http.go b/src/net/http/http.go
index 4c5054b..101799f 100644
--- a/src/net/http/http.go
+++ b/src/net/http/http.go
@@ -62,15 +62,6 @@
 	return !httpguts.IsTokenRune(r)
 }
 
-func isASCII(s string) bool {
-	for i := 0; i < len(s); i++ {
-		if s[i] >= utf8.RuneSelf {
-			return false
-		}
-	}
-	return true
-}
-
 // stringContainsCTLByte reports whether s contains any ASCII control character.
 func stringContainsCTLByte(s string) bool {
 	for i := 0; i < len(s); i++ {
diff --git a/src/net/http/http_test.go b/src/net/http/http_test.go
index 3f1d7ce..0d92fe5 100644
--- a/src/net/http/http_test.go
+++ b/src/net/http/http_test.go
@@ -9,9 +9,13 @@
 import (
 	"bytes"
 	"internal/testenv"
+	"io/fs"
 	"net/url"
+	"os"
 	"os/exec"
 	"reflect"
+	"regexp"
+	"strings"
 	"testing"
 )
 
@@ -156,3 +160,61 @@
 		b.Fatal("Benchmark wasn't run")
 	}
 }
+
+var forbiddenStringsFunctions = map[string]bool{
+	// Functions that use Unicode-aware case folding.
+	"EqualFold":      true,
+	"Title":          true,
+	"ToLower":        true,
+	"ToLowerSpecial": true,
+	"ToTitle":        true,
+	"ToTitleSpecial": true,
+	"ToUpper":        true,
+	"ToUpperSpecial": true,
+
+	// Functions that use Unicode-aware spaces.
+	"Fields":    true,
+	"TrimSpace": true,
+}
+
+// TestNoUnicodeStrings checks that nothing in net/http uses the Unicode-aware
+// strings and bytes package functions. HTTP is mostly ASCII based, and doing
+// Unicode-aware case folding or space stripping can introduce vulnerabilities.
+func TestNoUnicodeStrings(t *testing.T) {
+	if !testenv.HasSrc() {
+		t.Skip("source code not available")
+	}
+
+	re := regexp.MustCompile(`(strings|bytes).([A-Za-z]+)`)
+	if err := fs.WalkDir(os.DirFS("."), ".", func(path string, d fs.DirEntry, err error) error {
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		if path == "internal/ascii" {
+			return fs.SkipDir
+		}
+		if !strings.HasSuffix(path, ".go") ||
+			strings.HasSuffix(path, "_test.go") ||
+			path == "h2_bundle.go" || d.IsDir() {
+			return nil
+		}
+
+		contents, err := os.ReadFile(path)
+		if err != nil {
+			t.Fatal(err)
+		}
+		for lineNum, line := range strings.Split(string(contents), "\n") {
+			for _, match := range re.FindAllStringSubmatch(line, -1) {
+				if !forbiddenStringsFunctions[match[2]] {
+					continue
+				}
+				t.Errorf("disallowed call to %s at %s:%d", match[0], path, lineNum+1)
+			}
+		}
+
+		return nil
+	}); err != nil {
+		t.Fatal(err)
+	}
+}
diff --git a/src/net/http/httptest/recorder.go b/src/net/http/httptest/recorder.go
index 2428482..1b712ef 100644
--- a/src/net/http/httptest/recorder.go
+++ b/src/net/http/httptest/recorder.go
@@ -122,11 +122,30 @@
 	return len(str), nil
 }
 
+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 https://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))
+	}
+}
+
 // WriteHeader implements http.ResponseWriter.
 func (rw *ResponseRecorder) WriteHeader(code int) {
 	if rw.wroteHeader {
 		return
 	}
+
+	checkWriteHeaderCode(code)
 	rw.Code = code
 	rw.wroteHeader = true
 	if rw.HeaderMap == nil {
diff --git a/src/net/http/httptest/recorder_test.go b/src/net/http/httptest/recorder_test.go
index a865e87..8cb32dd 100644
--- a/src/net/http/httptest/recorder_test.go
+++ b/src/net/http/httptest/recorder_test.go
@@ -345,3 +345,28 @@
 		}
 	}
 }
+
+// Ensure that httptest.Recorder panics when given a non-3 digit (XXX)
+// status HTTP code. See https://golang.org/issues/45353
+func TestRecorderPanicsOnNonXXXStatusCode(t *testing.T) {
+	badCodes := []int{
+		-100, 0, 99, 1000, 20000,
+	}
+	for _, badCode := range badCodes {
+		badCode := badCode
+		t.Run(fmt.Sprintf("Code=%d", badCode), func(t *testing.T) {
+			defer func() {
+				if r := recover(); r == nil {
+					t.Fatal("Expected a panic")
+				}
+			}()
+
+			handler := func(rw http.ResponseWriter, _ *http.Request) {
+				rw.WriteHeader(badCode)
+			}
+			r, _ := http.NewRequest("GET", "http://example.org/", nil)
+			rw := NewRecorder()
+			handler(rw, r)
+		})
+	}
+}
diff --git a/src/net/http/httptest/server.go b/src/net/http/httptest/server.go
index 65165d9..4f85ff5 100644
--- a/src/net/http/httptest/server.go
+++ b/src/net/http/httptest/server.go
@@ -14,7 +14,7 @@
 	"log"
 	"net"
 	"net/http"
-	"net/http/internal"
+	"net/http/internal/testcert"
 	"os"
 	"strings"
 	"sync"
@@ -144,7 +144,7 @@
 	if s.client == nil {
 		s.client = &http.Client{Transport: &http.Transport{}}
 	}
-	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
 	if err != nil {
 		panic(fmt.Sprintf("httptest: NewTLSServer: %v", err))
 	}
@@ -316,6 +316,13 @@
 	s.Config.ConnState = func(c net.Conn, cs http.ConnState) {
 		s.mu.Lock()
 		defer s.mu.Unlock()
+
+		// Keep Close from returning until the user's ConnState hook
+		// (if any) finishes. Without this, the call to forgetConn
+		// below might send the count to 0 before we run the hook.
+		s.wg.Add(1)
+		defer s.wg.Done()
+
 		switch cs {
 		case http.StateNew:
 			s.wg.Add(1)
diff --git a/src/net/http/httptrace/trace.go b/src/net/http/httptrace/trace.go
index 6a5cbac..5777c91 100644
--- a/src/net/http/httptrace/trace.go
+++ b/src/net/http/httptrace/trace.go
@@ -127,7 +127,7 @@
 
 	// ConnectDone is called when a new connection's Dial
 	// completes. The provided err indicates whether the
-	// connection completedly successfully.
+	// connection completed successfully.
 	// If net.Dialer.DualStack ("Happy Eyeballs") support is
 	// enabled, this may be called multiple times.
 	ConnectDone func(network, addr string, err error)
diff --git a/src/net/http/httputil/dump_test.go b/src/net/http/httputil/dump_test.go
index 8168b2e..366cc82 100644
--- a/src/net/http/httputil/dump_test.go
+++ b/src/net/http/httputil/dump_test.go
@@ -478,7 +478,7 @@
 	}
 }
 
-// Issue 38352: Check for deadlock on cancelled requests.
+// Issue 38352: Check for deadlock on canceled requests.
 func TestDumpRequestOutIssue38352(t *testing.T) {
 	if testing.Short() {
 		return
diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
index 4e36958..8b63368 100644
--- a/src/net/http/httputil/reverseproxy.go
+++ b/src/net/http/httputil/reverseproxy.go
@@ -13,6 +13,7 @@
 	"log"
 	"net"
 	"net/http"
+	"net/http/internal/ascii"
 	"net/textproto"
 	"net/url"
 	"strings"
@@ -234,6 +235,15 @@
 	if req.ContentLength == 0 {
 		outreq.Body = nil // Issue 16036: nil Body for http.Transport retries
 	}
+	if outreq.Body != nil {
+		// Reading from the request body after returning from a handler is not
+		// allowed, and the RoundTrip goroutine that reads the Body can outlive
+		// this handler. This can lead to a crash if the handler panics (see
+		// Issue 46866). Although calling Close doesn't guarantee there isn't
+		// any Read in flight after the handle returns, in practice it's safe to
+		// read after closing it.
+		defer outreq.Body.Close()
+	}
 	if outreq.Header == nil {
 		outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate
 	}
@@ -242,28 +252,28 @@
 	outreq.Close = false
 
 	reqUpType := upgradeType(outreq.Header)
+	if !ascii.IsPrint(reqUpType) {
+		p.getErrorHandler()(rw, req, fmt.Errorf("client tried to switch to invalid protocol %q", reqUpType))
+		return
+	}
 	removeConnectionHeaders(outreq.Header)
 
 	// Remove hop-by-hop headers to the backend. Especially
 	// important is "Connection" because we want a persistent
 	// connection, regardless of what the client sent to us.
 	for _, h := range hopHeaders {
-		hv := outreq.Header.Get(h)
-		if hv == "" {
-			continue
-		}
-		if h == "Te" && hv == "trailers" {
-			// Issue 21096: tell backend applications that
-			// care about trailer support that we support
-			// trailers. (We do, but we don't go out of
-			// our way to advertise that unless the
-			// incoming client request thought it was
-			// worth mentioning)
-			continue
-		}
 		outreq.Header.Del(h)
 	}
 
+	// Issue 21096: tell backend applications that care about trailer support
+	// that we support trailers. (We do, but we don't go out of our way to
+	// advertise that unless the incoming client request thought it was worth
+	// mentioning.) Note that we look at req.Header, not outreq.Header, since
+	// the latter has passed through removeConnectionHeaders.
+	if httpguts.HeaderValuesContainsToken(req.Header["Te"], "trailers") {
+		outreq.Header.Set("Te", "trailers")
+	}
+
 	// After stripping all the hop-by-hop connection headers above, add back any
 	// necessary for protocol upgrades, such as for websockets.
 	if reqUpType != "" {
@@ -538,13 +548,16 @@
 	if !httpguts.HeaderValuesContainsToken(h["Connection"], "Upgrade") {
 		return ""
 	}
-	return strings.ToLower(h.Get("Upgrade"))
+	return h.Get("Upgrade")
 }
 
 func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.Request, res *http.Response) {
 	reqUpType := upgradeType(req.Header)
 	resUpType := upgradeType(res.Header)
-	if reqUpType != resUpType {
+	if !ascii.IsPrint(resUpType) { // We know reqUpType is ASCII, it's checked by the caller.
+		p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch to invalid protocol %q", resUpType))
+	}
+	if !ascii.EqualFold(reqUpType, resUpType) {
 		p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch protocol %q when %q was requested", resUpType, reqUpType))
 		return
 	}
@@ -562,7 +575,7 @@
 
 	backConnCloseCh := make(chan bool)
 	go func() {
-		// Ensure that the cancelation of a request closes the backend.
+		// Ensure that the cancellation of a request closes the backend.
 		// See issue https://golang.org/issue/35559.
 		select {
 		case <-req.Context().Done():
diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
index 3acbd94..4b6ad77 100644
--- a/src/net/http/httputil/reverseproxy_test.go
+++ b/src/net/http/httputil/reverseproxy_test.go
@@ -16,6 +16,7 @@
 	"log"
 	"net/http"
 	"net/http/httptest"
+	"net/http/internal/ascii"
 	"net/url"
 	"os"
 	"reflect"
@@ -90,8 +91,9 @@
 
 	getReq, _ := http.NewRequest("GET", frontend.URL, nil)
 	getReq.Host = "some-name"
-	getReq.Header.Set("Connection", "close")
-	getReq.Header.Set("Te", "trailers")
+	getReq.Header.Set("Connection", "close, TE")
+	getReq.Header.Add("Te", "foo")
+	getReq.Header.Add("Te", "bar, trailers")
 	getReq.Header.Set("Proxy-Connection", "should be deleted")
 	getReq.Header.Set("Upgrade", "foo")
 	getReq.Close = true
@@ -235,6 +237,64 @@
 	}
 }
 
+func TestReverseProxyStripEmptyConnection(t *testing.T) {
+	// See Issue 46313.
+	const backendResponse = "I am the backend"
+
+	// someConnHeader is some arbitrary header to be declared as a hop-by-hop header
+	// in the Request's Connection header.
+	const someConnHeader = "X-Some-Conn-Header"
+
+	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		if c := r.Header.Values("Connection"); len(c) != 0 {
+			t.Errorf("handler got header %q = %v; want empty", "Connection", c)
+		}
+		if c := r.Header.Get(someConnHeader); c != "" {
+			t.Errorf("handler got header %q = %q; want empty", someConnHeader, c)
+		}
+		w.Header().Add("Connection", "")
+		w.Header().Add("Connection", someConnHeader)
+		w.Header().Set(someConnHeader, "should be deleted")
+		io.WriteString(w, backendResponse)
+	}))
+	defer backend.Close()
+	backendURL, err := url.Parse(backend.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	proxyHandler := NewSingleHostReverseProxy(backendURL)
+	frontend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		proxyHandler.ServeHTTP(w, r)
+		if c := r.Header.Get(someConnHeader); c != "should be deleted" {
+			t.Errorf("handler modified header %q = %q; want %q", someConnHeader, c, "should be deleted")
+		}
+	}))
+	defer frontend.Close()
+
+	getReq, _ := http.NewRequest("GET", frontend.URL, nil)
+	getReq.Header.Add("Connection", "")
+	getReq.Header.Add("Connection", someConnHeader)
+	getReq.Header.Set(someConnHeader, "should be deleted")
+	res, err := frontend.Client().Do(getReq)
+	if err != nil {
+		t.Fatalf("Get: %v", err)
+	}
+	defer res.Body.Close()
+	bodyBytes, err := io.ReadAll(res.Body)
+	if err != nil {
+		t.Fatalf("reading body: %v", err)
+	}
+	if got, want := string(bodyBytes), backendResponse; got != want {
+		t.Errorf("got body %q; want %q", got, want)
+	}
+	if c := res.Header.Get("Connection"); c != "" {
+		t.Errorf("handler got header %q = %q; want empty", "Connection", c)
+	}
+	if c := res.Header.Get(someConnHeader); c != "" {
+		t.Errorf("handler got header %q = %q; want empty", someConnHeader, c)
+	}
+}
+
 func TestXForwardedFor(t *testing.T) {
 	const prevForwardedFor = "client ip"
 	const backendResponse = "I am the backend"
@@ -1062,6 +1122,45 @@
 	rproxy.ServeHTTP(httptest.NewRecorder(), req)
 }
 
+// Issue #46866: panic without closing incoming request body causes a panic
+func TestReverseProxy_PanicClosesIncomingBody(t *testing.T) {
+	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		out := "this call was relayed by the reverse proxy"
+		// Coerce a wrong content length to induce io.ErrUnexpectedEOF
+		w.Header().Set("Content-Length", fmt.Sprintf("%d", len(out)*2))
+		fmt.Fprintln(w, out)
+	}))
+	defer backend.Close()
+	backendURL, err := url.Parse(backend.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	proxyHandler := NewSingleHostReverseProxy(backendURL)
+	proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
+	frontend := httptest.NewServer(proxyHandler)
+	defer frontend.Close()
+	frontendClient := frontend.Client()
+
+	var wg sync.WaitGroup
+	for i := 0; i < 2; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			for j := 0; j < 10; j++ {
+				const reqLen = 6 * 1024 * 1024
+				req, _ := http.NewRequest("POST", frontend.URL, &io.LimitedReader{R: neverEnding('x'), N: reqLen})
+				req.ContentLength = reqLen
+				resp, _ := frontendClient.Transport.RoundTrip(req)
+				if resp != nil {
+					io.Copy(io.Discard, resp.Body)
+					resp.Body.Close()
+				}
+			}
+		}()
+	}
+	wg.Wait()
+}
+
 func TestSelectFlushInterval(t *testing.T) {
 	tests := []struct {
 		name string
@@ -1183,7 +1282,7 @@
 		t.Errorf("Header(XHeader) = %q; want %q", got, want)
 	}
 
-	if upgradeType(res.Header) != "websocket" {
+	if !ascii.EqualFold(upgradeType(res.Header), "websocket") {
 		t.Fatalf("not websocket upgrade; got %#v", res.Header)
 	}
 	rwc, ok := res.Body.(io.ReadWriteCloser)
@@ -1208,7 +1307,7 @@
 	}
 }
 
-func TestReverseProxyWebSocketCancelation(t *testing.T) {
+func TestReverseProxyWebSocketCancellation(t *testing.T) {
 	n := 5
 	triggerCancelCh := make(chan bool, n)
 	nthResponse := func(i int) string {
@@ -1300,7 +1399,7 @@
 		t.Errorf("X-Header mismatch\n\tgot:  %q\n\twant: %q", g, w)
 	}
 
-	if g, w := upgradeType(res.Header), "websocket"; g != w {
+	if g, w := upgradeType(res.Header), "websocket"; !ascii.EqualFold(g, w) {
 		t.Fatalf("Upgrade header mismatch\n\tgot:  %q\n\twant: %q", g, w)
 	}
 
diff --git a/src/net/http/internal/ascii/print.go b/src/net/http/internal/ascii/print.go
new file mode 100644
index 0000000..585e5ba
--- /dev/null
+++ b/src/net/http/internal/ascii/print.go
@@ -0,0 +1,61 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ascii
+
+import (
+	"strings"
+	"unicode"
+)
+
+// EqualFold is strings.EqualFold, ASCII only. It reports whether s and t
+// are equal, ASCII-case-insensitively.
+func EqualFold(s, t string) bool {
+	if len(s) != len(t) {
+		return false
+	}
+	for i := 0; i < len(s); i++ {
+		if lower(s[i]) != lower(t[i]) {
+			return false
+		}
+	}
+	return true
+}
+
+// lower returns the ASCII lowercase version of b.
+func lower(b byte) byte {
+	if 'A' <= b && b <= 'Z' {
+		return b + ('a' - 'A')
+	}
+	return b
+}
+
+// IsPrint returns whether s is ASCII and printable according to
+// https://tools.ietf.org/html/rfc20#section-4.2.
+func IsPrint(s string) bool {
+	for i := 0; i < len(s); i++ {
+		if s[i] < ' ' || s[i] > '~' {
+			return false
+		}
+	}
+	return true
+}
+
+// Is returns whether s is ASCII.
+func Is(s string) bool {
+	for i := 0; i < len(s); i++ {
+		if s[i] > unicode.MaxASCII {
+			return false
+		}
+	}
+	return true
+}
+
+// ToLower returns the lowercase version of s if s is ASCII and printable.
+func ToLower(s string) (lower string, ok bool) {
+	if !IsPrint(s) {
+		return "", false
+	}
+	return strings.ToLower(s), true
+}
diff --git a/src/net/http/internal/ascii/print_test.go b/src/net/http/internal/ascii/print_test.go
new file mode 100644
index 0000000..0b7767c
--- /dev/null
+++ b/src/net/http/internal/ascii/print_test.go
@@ -0,0 +1,95 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ascii
+
+import "testing"
+
+func TestEqualFold(t *testing.T) {
+	var tests = []struct {
+		name string
+		a, b string
+		want bool
+	}{
+		{
+			name: "empty",
+			want: true,
+		},
+		{
+			name: "simple match",
+			a:    "CHUNKED",
+			b:    "chunked",
+			want: true,
+		},
+		{
+			name: "same string",
+			a:    "chunked",
+			b:    "chunked",
+			want: true,
+		},
+		{
+			name: "Unicode Kelvin symbol",
+			a:    "chunKed", // This "K" is 'KELVIN SIGN' (\u212A)
+			b:    "chunked",
+			want: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := EqualFold(tt.a, tt.b); got != tt.want {
+				t.Errorf("AsciiEqualFold(%q,%q): got %v want %v", tt.a, tt.b, got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsPrint(t *testing.T) {
+	var tests = []struct {
+		name string
+		in   string
+		want bool
+	}{
+		{
+			name: "empty",
+			want: true,
+		},
+		{
+			name: "ASCII low",
+			in:   "This is a space: ' '",
+			want: true,
+		},
+		{
+			name: "ASCII high",
+			in:   "This is a tilde: '~'",
+			want: true,
+		},
+		{
+			name: "ASCII low non-print",
+			in:   "This is a unit separator: \x1F",
+			want: false,
+		},
+		{
+			name: "Ascii high non-print",
+			in:   "This is a Delete: \x7F",
+			want: false,
+		},
+		{
+			name: "Unicode letter",
+			in:   "Today it's 280K outside: it's freezing!", // This "K" is 'KELVIN SIGN' (\u212A)
+			want: false,
+		},
+		{
+			name: "Unicode emoji",
+			in:   "Gophers like 🧀",
+			want: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsPrint(tt.in); got != tt.want {
+				t.Errorf("IsASCIIPrint(%q): got %v want %v", tt.in, got, tt.want)
+			}
+		})
+	}
+}
diff --git a/src/net/http/internal/testcert.go b/src/net/http/internal/testcert.go
deleted file mode 100644
index 2284a83..0000000
--- a/src/net/http/internal/testcert.go
+++ /dev/null
@@ -1,45 +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 internal
-
-import "strings"
-
-// LocalhostCert is a PEM-encoded TLS cert with SAN IPs
-// "127.0.0.1" and "[::1]", expiring at Jan 29 16:00:00 2084 GMT.
-// generated from src/crypto/tls:
-// go run generate_cert.go  --rsa-bits 1024 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
-var LocalhostCert = []byte(`-----BEGIN CERTIFICATE-----
-MIICEzCCAXygAwIBAgIQMIMChMLGrR+QvmQvpwAU6zANBgkqhkiG9w0BAQsFADAS
-MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw
-MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
-iQKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9SjY1bIw4
-iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZBl2+XsDul
-rKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQABo2gwZjAO
-BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw
-AwEB/zAuBgNVHREEJzAlggtleGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAA
-AAAAATANBgkqhkiG9w0BAQsFAAOBgQCEcetwO59EWk7WiJsG4x8SY+UIAA+flUI9
-tyC4lNhbcF2Idq9greZwbYCqTTTr2XiRNSMLCOjKyI7ukPoPjo16ocHj+P3vZGfs
-h1fIw3cSS2OolhloGw/XM6RWPWtPAlGykKLciQrBru5NAPvCMsb/I1DAceTiotQM
-fblo6RBxUQ==
------END CERTIFICATE-----`)
-
-// LocalhostKey is the private key for localhostCert.
-var LocalhostKey = []byte(testingKey(`-----BEGIN RSA TESTING KEY-----
-MIICXgIBAAKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9
-SjY1bIw4iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZB
-l2+XsDulrKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQAB
-AoGAGRzwwir7XvBOAy5tM/uV6e+Zf6anZzus1s1Y1ClbjbE6HXbnWWF/wbZGOpet
-3Zm4vD6MXc7jpTLryzTQIvVdfQbRc6+MUVeLKwZatTXtdZrhu+Jk7hx0nTPy8Jcb
-uJqFk541aEw+mMogY/xEcfbWd6IOkp+4xqjlFLBEDytgbIECQQDvH/E6nk+hgN4H
-qzzVtxxr397vWrjrIgPbJpQvBsafG7b0dA4AFjwVbFLmQcj2PprIMmPcQrooz8vp
-jy4SHEg1AkEA/v13/5M47K9vCxmb8QeD/asydfsgS5TeuNi8DoUBEmiSJwma7FXY
-fFUtxuvL7XvjwjN5B30pNEbc6Iuyt7y4MQJBAIt21su4b3sjXNueLKH85Q+phy2U
-fQtuUE9txblTu14q3N7gHRZB4ZMhFYyDy8CKrN2cPg/Fvyt0Xlp/DoCzjA0CQQDU
-y2ptGsuSmgUtWj3NM9xuwYPm+Z/F84K6+ARYiZ6PYj013sovGKUFfYAqVXVlxtIX
-qyUBnu3X9ps8ZfjLZO7BAkEAlT4R5Yl6cGhaJQYZHOde3JEMhNRcVFMO8dJDaFeo
-f9Oeos0UUothgiDktdQHxdNEwLjQf7lJJBzV+5OtwswCWA==
------END RSA TESTING KEY-----`))
-
-func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }
diff --git a/src/net/http/internal/testcert/testcert.go b/src/net/http/internal/testcert/testcert.go
new file mode 100644
index 0000000..5f94704
--- /dev/null
+++ b/src/net/http/internal/testcert/testcert.go
@@ -0,0 +1,46 @@
+// 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 testcert contains a test-only localhost certificate.
+package testcert
+
+import "strings"
+
+// LocalhostCert is a PEM-encoded TLS cert with SAN IPs
+// "127.0.0.1" and "[::1]", expiring at Jan 29 16:00:00 2084 GMT.
+// generated from src/crypto/tls:
+// go run generate_cert.go  --rsa-bits 1024 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
+var LocalhostCert = []byte(`-----BEGIN CERTIFICATE-----
+MIICEzCCAXygAwIBAgIQMIMChMLGrR+QvmQvpwAU6zANBgkqhkiG9w0BAQsFADAS
+MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw
+MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9SjY1bIw4
+iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZBl2+XsDul
+rKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQABo2gwZjAO
+BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw
+AwEB/zAuBgNVHREEJzAlggtleGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAA
+AAAAATANBgkqhkiG9w0BAQsFAAOBgQCEcetwO59EWk7WiJsG4x8SY+UIAA+flUI9
+tyC4lNhbcF2Idq9greZwbYCqTTTr2XiRNSMLCOjKyI7ukPoPjo16ocHj+P3vZGfs
+h1fIw3cSS2OolhloGw/XM6RWPWtPAlGykKLciQrBru5NAPvCMsb/I1DAceTiotQM
+fblo6RBxUQ==
+-----END CERTIFICATE-----`)
+
+// LocalhostKey is the private key for LocalhostCert.
+var LocalhostKey = []byte(testingKey(`-----BEGIN RSA TESTING KEY-----
+MIICXgIBAAKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9
+SjY1bIw4iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZB
+l2+XsDulrKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQAB
+AoGAGRzwwir7XvBOAy5tM/uV6e+Zf6anZzus1s1Y1ClbjbE6HXbnWWF/wbZGOpet
+3Zm4vD6MXc7jpTLryzTQIvVdfQbRc6+MUVeLKwZatTXtdZrhu+Jk7hx0nTPy8Jcb
+uJqFk541aEw+mMogY/xEcfbWd6IOkp+4xqjlFLBEDytgbIECQQDvH/E6nk+hgN4H
+qzzVtxxr397vWrjrIgPbJpQvBsafG7b0dA4AFjwVbFLmQcj2PprIMmPcQrooz8vp
+jy4SHEg1AkEA/v13/5M47K9vCxmb8QeD/asydfsgS5TeuNi8DoUBEmiSJwma7FXY
+fFUtxuvL7XvjwjN5B30pNEbc6Iuyt7y4MQJBAIt21su4b3sjXNueLKH85Q+phy2U
+fQtuUE9txblTu14q3N7gHRZB4ZMhFYyDy8CKrN2cPg/Fvyt0Xlp/DoCzjA0CQQDU
+y2ptGsuSmgUtWj3NM9xuwYPm+Z/F84K6+ARYiZ6PYj013sovGKUFfYAqVXVlxtIX
+qyUBnu3X9ps8ZfjLZO7BAkEAlT4R5Yl6cGhaJQYZHOde3JEMhNRcVFMO8dJDaFeo
+f9Oeos0UUothgiDktdQHxdNEwLjQf7lJJBzV+5OtwswCWA==
+-----END RSA TESTING KEY-----`))
+
+func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }
diff --git a/src/net/http/omithttp2.go b/src/net/http/omithttp2.go
index 30c6e48..79599d0 100644
--- a/src/net/http/omithttp2.go
+++ b/src/net/http/omithttp2.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build nethttpomithttp2
 // +build nethttpomithttp2
 
 package http
diff --git a/src/net/http/pprof/pprof.go b/src/net/http/pprof/pprof.go
index 5389a38..888ea35 100644
--- a/src/net/http/pprof/pprof.go
+++ b/src/net/http/pprof/pprof.go
@@ -287,7 +287,7 @@
 		err := r.Context().Err()
 		if err == context.DeadlineExceeded {
 			serveError(w, http.StatusRequestTimeout, err.Error())
-		} else { // TODO: what's a good status code for cancelled requests? 400?
+		} else { // TODO: what's a good status code for canceled requests? 400?
 			serveError(w, http.StatusInternalServerError, err.Error())
 		}
 		return
@@ -431,7 +431,7 @@
 
 	b.WriteString(`</table>
 <a href="goroutine?debug=2">full goroutine stack dump</a>
-<br/>
+<br>
 <p>
 Profile Descriptions:
 <ul>
diff --git a/src/net/http/request.go b/src/net/http/request.go
index adba540..09cb0c7 100644
--- a/src/net/http/request.go
+++ b/src/net/http/request.go
@@ -19,6 +19,7 @@
 	"mime/multipart"
 	"net"
 	"net/http/httptrace"
+	"net/http/internal/ascii"
 	"net/textproto"
 	"net/url"
 	urlpkg "net/url"
@@ -723,7 +724,7 @@
 	// version does not.
 	// Note that for correct ASCII IDNs ToASCII will only do considerably more
 	// work, but it will not cause an allocation.
-	if isASCII(v) {
+	if ascii.Is(v) {
 		return v, nil
 	}
 	return idna.Lookup.ToASCII(v)
@@ -779,7 +780,8 @@
 }
 
 // ParseHTTPVersion parses an HTTP version string.
-// "HTTP/1.0" returns (1, 0, true).
+// "HTTP/1.0" returns (1, 0, true). Note that strings without
+// a minor version, such as "HTTP/2", are not valid.
 func ParseHTTPVersion(vers string) (major, minor int, ok bool) {
 	const Big = 1000000 // arbitrary upper bound
 	switch vers {
@@ -823,7 +825,7 @@
 	return len(method) > 0 && strings.IndexFunc(method, isNotToken) == -1
 }
 
-// NewRequest wraps NewRequestWithContext using the background context.
+// NewRequest wraps NewRequestWithContext using context.Background.
 func NewRequest(method, url string, body io.Reader) (*Request, error) {
 	return NewRequestWithContext(context.Background(), method, url, body)
 }
@@ -947,7 +949,7 @@
 func parseBasicAuth(auth string) (username, password string, ok bool) {
 	const prefix = "Basic "
 	// Case insensitive prefix match. See Issue 22736.
-	if len(auth) < len(prefix) || !strings.EqualFold(auth[:len(prefix)], prefix) {
+	if len(auth) < len(prefix) || !ascii.EqualFold(auth[:len(prefix)], prefix) {
 		return
 	}
 	c, err := base64.StdEncoding.DecodeString(auth[len(prefix):])
@@ -1009,16 +1011,16 @@
 // requests and handle them via the Handler interface. ReadRequest
 // only supports HTTP/1.x requests. For HTTP/2, use golang.org/x/net/http2.
 func ReadRequest(b *bufio.Reader) (*Request, error) {
-	return readRequest(b, deleteHostHeader)
+	req, err := readRequest(b)
+	if err != nil {
+		return nil, err
+	}
+
+	delete(req.Header, "Host")
+	return req, err
 }
 
-// Constants for readRequest's deleteHostHeader parameter.
-const (
-	deleteHostHeader = true
-	keepHostHeader   = false
-)
-
-func readRequest(b *bufio.Reader, deleteHostHeader bool) (req *Request, err error) {
+func readRequest(b *bufio.Reader) (req *Request, err error) {
 	tp := newTextprotoReader(b)
 	req = new(Request)
 
@@ -1076,6 +1078,9 @@
 		return nil, err
 	}
 	req.Header = Header(mimeHeader)
+	if len(req.Header["Host"]) > 1 {
+		return nil, fmt.Errorf("too many Host headers")
+	}
 
 	// RFC 7230, section 5.3: Must treat
 	//	GET /index.html HTTP/1.1
@@ -1088,9 +1093,6 @@
 	if req.Host == "" {
 		req.Host = req.Header.get("Host")
 	}
-	if deleteHostHeader {
-		delete(req.Header, "Host")
-	}
 
 	fixPragmaCacheControl(req.Header)
 
@@ -1123,6 +1125,9 @@
 // MaxBytesReader prevents clients from accidentally or maliciously
 // sending a large request and wasting server resources.
 func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser {
+	if n < 0 { // Treat negative limits as equivalent to 0.
+		n = 0
+	}
 	return &maxBytesReader{w: w, r: r, n: n}
 }
 
@@ -1288,16 +1293,18 @@
 // its file parts are stored in memory, with the remainder stored on
 // disk in temporary files.
 // ParseMultipartForm calls ParseForm if necessary.
+// If ParseForm returns an error, ParseMultipartForm returns it but also
+// continues parsing the request body.
 // After one call to ParseMultipartForm, subsequent calls have no effect.
 func (r *Request) ParseMultipartForm(maxMemory int64) error {
 	if r.MultipartForm == multipartByReader {
 		return errors.New("http: multipart handled by MultipartReader")
 	}
+	var parseFormErr error
 	if r.Form == nil {
-		err := r.ParseForm()
-		if err != nil {
-			return err
-		}
+		// Let errors in ParseForm fall through, and just
+		// return it at the end.
+		parseFormErr = r.ParseForm()
 	}
 	if r.MultipartForm != nil {
 		return nil
@@ -1324,7 +1331,7 @@
 
 	r.MultipartForm = f
 
-	return nil
+	return parseFormErr
 }
 
 // FormValue returns the first value for the named component of the query.
@@ -1452,5 +1459,5 @@
 // an HTTP/1 connection.
 func (r *Request) requiresHTTP1() bool {
 	return hasToken(r.Header.Get("Connection"), "upgrade") &&
-		strings.EqualFold(r.Header.Get("Upgrade"), "websocket")
+		ascii.EqualFold(r.Header.Get("Upgrade"), "websocket")
 }
diff --git a/src/net/http/request_test.go b/src/net/http/request_test.go
index 29297b0..4e0c4ba 100644
--- a/src/net/http/request_test.go
+++ b/src/net/http/request_test.go
@@ -32,9 +32,26 @@
 	}
 }
 
+// Issue #25192: Test that ParseForm fails but still parses the form when an URL
+// containing a semicolon is provided.
+func TestParseFormSemicolonSeparator(t *testing.T) {
+	for _, method := range []string{"POST", "PATCH", "PUT", "GET"} {
+		req, _ := NewRequest(method, "http://www.google.com/search?q=foo;q=bar&a=1",
+			strings.NewReader("q"))
+		err := req.ParseForm()
+		if err == nil {
+			t.Fatalf(`for method %s, ParseForm expected an error, got success`, method)
+		}
+		wantForm := url.Values{"a": []string{"1"}}
+		if !reflect.DeepEqual(req.Form, wantForm) {
+			t.Fatalf("for method %s, ParseForm expected req.Form = %v, want %v", method, req.Form, wantForm)
+		}
+	}
+}
+
 func TestParseFormQuery(t *testing.T) {
 	req, _ := NewRequest("POST", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&orphan=nope&empty=not",
-		strings.NewReader("z=post&both=y&prio=2&=nokey&orphan;empty=&"))
+		strings.NewReader("z=post&both=y&prio=2&=nokey&orphan&empty=&"))
 	req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
 
 	if q := req.FormValue("q"); q != "foo" {
@@ -245,6 +262,29 @@
 	}
 }
 
+// Issue 45789: multipart form should not include directory path in filename
+func TestParseMultipartFormFilename(t *testing.T) {
+	postData :=
+		`--xxx
+Content-Disposition: form-data; name="file"; filename="../usr/foobar.txt/"
+Content-Type: text/plain
+
+--xxx--
+`
+	req := &Request{
+		Method: "POST",
+		Header: Header{"Content-Type": {`multipart/form-data; boundary=xxx`}},
+		Body:   io.NopCloser(strings.NewReader(postData)),
+	}
+	_, hdr, err := req.FormFile("file")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if hdr.Filename != "foobar.txt" {
+		t.Errorf("expected only the last element of the path, got %q", hdr.Filename)
+	}
+}
+
 // Issue #40430: Test that if maxMemory for ParseMultipartForm when combined with
 // the payload size and the internal leeway buffer size of 10MiB overflows, that we
 // correctly return an error.
@@ -342,6 +382,18 @@
 	validateTestMultipartContents(t, req, false)
 }
 
+// Issue #25192: Test that ParseMultipartForm fails but still parses the
+// multi-part form when an URL containing a semicolon is provided.
+func TestParseMultipartFormSemicolonSeparator(t *testing.T) {
+	req := newTestMultipartRequest(t)
+	req.URL = &url.URL{RawQuery: "q=foo;q=bar"}
+	if err := req.ParseMultipartForm(25); err == nil {
+		t.Fatal("ParseMultipartForm expected error due to invalid semicolon, got nil")
+	}
+	defer req.MultipartForm.RemoveAll()
+	validateTestMultipartContents(t, req, false)
+}
+
 func TestMultipartRequestAuto(t *testing.T) {
 	// Test that FormValue and FormFile automatically invoke
 	// ParseMultipartForm and return the right values.
@@ -469,6 +521,10 @@
 		in:     "HEAD / HTTP/1.1\r\nContent-Length:0\r\nContent-Length: 0\r\n\r\n",
 		header: Header{"Content-Length": {"0"}},
 	},
+	11: {
+		in:  "HEAD / HTTP/1.1\r\nHost: foo\r\nHost: bar\r\n\r\n\r\n\r\n",
+		err: "too many Host headers",
+	},
 }
 
 func TestReadRequestErrors(t *testing.T) {
@@ -850,6 +906,92 @@
 	}
 }
 
+// Issue 45101: maxBytesReader's Read panicked when n < -1. This test
+// also ensures that Read treats negative limits as equivalent to 0.
+func TestMaxBytesReaderDifferentLimits(t *testing.T) {
+	const testStr = "1234"
+	tests := [...]struct {
+		limit   int64
+		lenP    int
+		wantN   int
+		wantErr bool
+	}{
+		0: {
+			limit:   -123,
+			lenP:    0,
+			wantN:   0,
+			wantErr: false, // Ensure we won't return an error when the limit is negative, but we don't need to read.
+		},
+		1: {
+			limit:   -100,
+			lenP:    32 * 1024,
+			wantN:   0,
+			wantErr: true,
+		},
+		2: {
+			limit:   -2,
+			lenP:    1,
+			wantN:   0,
+			wantErr: true,
+		},
+		3: {
+			limit:   -1,
+			lenP:    2,
+			wantN:   0,
+			wantErr: true,
+		},
+		4: {
+			limit:   0,
+			lenP:    3,
+			wantN:   0,
+			wantErr: true,
+		},
+		5: {
+			limit:   1,
+			lenP:    4,
+			wantN:   1,
+			wantErr: true,
+		},
+		6: {
+			limit:   2,
+			lenP:    5,
+			wantN:   2,
+			wantErr: true,
+		},
+		7: {
+			limit:   3,
+			lenP:    2,
+			wantN:   2,
+			wantErr: false,
+		},
+		8: {
+			limit:   int64(len(testStr)),
+			lenP:    len(testStr),
+			wantN:   len(testStr),
+			wantErr: false,
+		},
+		9: {
+			limit:   100,
+			lenP:    6,
+			wantN:   len(testStr),
+			wantErr: false,
+		},
+	}
+	for i, tt := range tests {
+		rc := MaxBytesReader(nil, io.NopCloser(strings.NewReader(testStr)), tt.limit)
+
+		n, err := rc.Read(make([]byte, tt.lenP))
+
+		if n != tt.wantN {
+			t.Errorf("%d. n: %d, want n: %d", i, n, tt.wantN)
+		}
+
+		if (err != nil) != tt.wantErr {
+			t.Errorf("%d. error: %v", i, err)
+		}
+	}
+}
+
 func TestWithContextDeepCopiesURL(t *testing.T) {
 	req, err := NewRequest("POST", "https://golang.org/", nil)
 	if err != nil {
diff --git a/src/net/http/roundtrip.go b/src/net/http/roundtrip.go
index 2ec736b..eef7c79 100644
--- a/src/net/http/roundtrip.go
+++ b/src/net/http/roundtrip.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js || !wasm
 // +build !js !wasm
 
 package http
diff --git a/src/net/http/roundtrip_js.go b/src/net/http/roundtrip_js.go
index c6a221a..74c83a9 100644
--- a/src/net/http/roundtrip_js.go
+++ b/src/net/http/roundtrip_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package http
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index f868741..6394da3 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -25,6 +25,7 @@
 	"net/http/httptest"
 	"net/http/httputil"
 	"net/http/internal"
+	"net/http/internal/testcert"
 	"net/url"
 	"os"
 	"os/exec"
@@ -1475,7 +1476,7 @@
 	defer afterTest(t)
 	defer SetTestHookServerServe(nil)
 
-	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1599,7 +1600,7 @@
 }
 
 func TestAutomaticHTTP2_ListenAndServe(t *testing.T) {
-	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1609,7 +1610,7 @@
 }
 
 func TestAutomaticHTTP2_ListenAndServe_GetCertificate(t *testing.T) {
-	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -6507,3 +6508,104 @@
 		t.Fatalf("unexpected value read from body:\ngot: %q\nwant: %q", b, "hello")
 	}
 }
+
+func TestMuxRedirectRelative(t *testing.T) {
+	setParallel(t)
+	req, err := ReadRequest(bufio.NewReader(strings.NewReader("GET http://example.com HTTP/1.1\r\nHost: test\r\n\r\n")))
+	if err != nil {
+		t.Errorf("%s", err)
+	}
+	mux := NewServeMux()
+	resp := httptest.NewRecorder()
+	mux.ServeHTTP(resp, req)
+	if got, want := resp.Header().Get("Location"), "/"; got != want {
+		t.Errorf("Location header expected %q; got %q", want, got)
+	}
+	if got, want := resp.Code, StatusMovedPermanently; got != want {
+		t.Errorf("Expected response code %d; got %d", want, got)
+	}
+}
+
+// TestQuerySemicolon tests the behavior of semicolons in queries. See Issue 25192.
+func TestQuerySemicolon(t *testing.T) {
+	t.Cleanup(func() { afterTest(t) })
+
+	tests := []struct {
+		query           string
+		xNoSemicolons   string
+		xWithSemicolons string
+		warning         bool
+	}{
+		{"?a=1;x=bad&x=good", "good", "bad", true},
+		{"?a=1;b=bad&x=good", "good", "good", true},
+		{"?a=1%3Bx=bad&x=good%3B", "good;", "good;", false},
+		{"?a=1;x=good;x=bad", "", "good", true},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.query+"/allow=false", func(t *testing.T) {
+			allowSemicolons := false
+			testQuerySemicolon(t, tt.query, tt.xNoSemicolons, allowSemicolons, tt.warning)
+		})
+		t.Run(tt.query+"/allow=true", func(t *testing.T) {
+			allowSemicolons, expectWarning := true, false
+			testQuerySemicolon(t, tt.query, tt.xWithSemicolons, allowSemicolons, expectWarning)
+		})
+	}
+}
+
+func testQuerySemicolon(t *testing.T, query string, wantX string, allowSemicolons, expectWarning bool) {
+	setParallel(t)
+
+	writeBackX := func(w ResponseWriter, r *Request) {
+		x := r.URL.Query().Get("x")
+		if expectWarning {
+			if err := r.ParseForm(); err == nil || !strings.Contains(err.Error(), "semicolon") {
+				t.Errorf("expected error mentioning semicolons from ParseForm, got %v", err)
+			}
+		} else {
+			if err := r.ParseForm(); err != nil {
+				t.Errorf("expected no error from ParseForm, got %v", err)
+			}
+		}
+		if got := r.FormValue("x"); x != got {
+			t.Errorf("got %q from FormValue, want %q", got, x)
+		}
+		fmt.Fprintf(w, "%s", x)
+	}
+
+	h := Handler(HandlerFunc(writeBackX))
+	if allowSemicolons {
+		h = AllowQuerySemicolons(h)
+	}
+
+	ts := httptest.NewUnstartedServer(h)
+	logBuf := &bytes.Buffer{}
+	ts.Config.ErrorLog = log.New(logBuf, "", 0)
+	ts.Start()
+	defer ts.Close()
+
+	req, _ := NewRequest("GET", ts.URL+query, nil)
+	res, err := ts.Client().Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	slurp, _ := io.ReadAll(res.Body)
+	res.Body.Close()
+	if got, want := res.StatusCode, 200; got != want {
+		t.Errorf("Status = %d; want = %d", got, want)
+	}
+	if got, want := string(slurp), wantX; got != want {
+		t.Errorf("Body = %q; want = %q", got, want)
+	}
+
+	if expectWarning {
+		if !strings.Contains(logBuf.String(), "semicolon") {
+			t.Errorf("got %q from ErrorLog, expected a mention of semicolons", logBuf.String())
+		}
+	} else {
+		if strings.Contains(logBuf.String(), "semicolon") {
+			t.Errorf("got %q from ErrorLog, expected no mention of semicolons", logBuf.String())
+		}
+	}
+}
diff --git a/src/net/http/server.go b/src/net/http/server.go
index ad99741..5b113cf 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -333,7 +333,7 @@
 const bufferBeforeChunkingSize = 2048
 
 // chunkWriter writes to a response's conn buffer, and is the writer
-// wrapped by the response.bufw buffered writer.
+// wrapped by the response.w buffered writer.
 //
 // chunkWriter also is responsible for finalizing the Header, including
 // conditionally setting the Content-Type and setting a Content-Length
@@ -577,37 +577,17 @@
 		return io.CopyBuffer(writerOnly{w}, src, buf)
 	}
 
-	// sendfile path:
-
-	// Do not start actually writing response until src is readable.
-	// If body length is <= sniffLen, sendfile/splice path will do
-	// little anyway. This small read also satisfies sniffing the
-	// body in case Content-Type is missing.
-	nr, er := src.Read(buf[:sniffLen])
-	atEOF := errors.Is(er, io.EOF)
-	n += int64(nr)
-
-	if nr > 0 {
-		// Write the small amount read normally.
-		nw, ew := w.Write(buf[:nr])
-		if ew != nil {
-			err = ew
-		} else if nr != nw {
-			err = io.ErrShortWrite
+	// Copy the first sniffLen bytes before switching to ReadFrom.
+	// This ensures we don't start writing the response before the
+	// source is available (see golang.org/issue/5660) and provides
+	// enough bytes to perform Content-Type sniffing when required.
+	if !w.cw.wroteHeader {
+		n0, err := io.CopyBuffer(writerOnly{w}, io.LimitReader(src, sniffLen), buf)
+		n += n0
+		if err != nil || n0 < sniffLen {
+			return n, err
 		}
 	}
-	if err == nil && er != nil && !atEOF {
-		err = er
-	}
-
-	// Do not send StatusOK in the error case where nothing has been written.
-	if err == nil && !w.wroteHeader {
-		w.WriteHeader(StatusOK) // nr == 0, no error (or EOF)
-	}
-
-	if err != nil || atEOF {
-		return n, err
-	}
 
 	w.w.Flush()  // get rid of any previous writes
 	w.cw.flush() // make sure Header is written; flush data to rwc
@@ -620,7 +600,7 @@
 		return n, err
 	}
 
-	n0, err := io.Copy(writerOnly{w}, src)
+	n0, err := io.CopyBuffer(writerOnly{w}, src, buf)
 	n += n0
 	return n, err
 }
@@ -964,14 +944,14 @@
 		hdrDeadline      time.Time // or zero if none
 	)
 	t0 := time.Now()
-	if d := c.server.readHeaderTimeout(); d != 0 {
+	if d := c.server.readHeaderTimeout(); d > 0 {
 		hdrDeadline = t0.Add(d)
 	}
-	if d := c.server.ReadTimeout; d != 0 {
+	if d := c.server.ReadTimeout; d > 0 {
 		wholeReqDeadline = t0.Add(d)
 	}
 	c.rwc.SetReadDeadline(hdrDeadline)
-	if d := c.server.WriteTimeout; d != 0 {
+	if d := c.server.WriteTimeout; d > 0 {
 		defer func() {
 			c.rwc.SetWriteDeadline(time.Now().Add(d))
 		}()
@@ -983,7 +963,7 @@
 		peek, _ := c.bufr.Peek(4) // ReadRequest will get err below
 		c.bufr.Discard(numLeadingCRorLF(peek))
 	}
-	req, err := readRequest(c.bufr, keepHostHeader)
+	req, err := readRequest(c.bufr)
 	if err != nil {
 		if c.r.hitReadLimit() {
 			return nil, errTooLarge
@@ -1003,9 +983,6 @@
 	if req.ProtoAtLeast(1, 1) && (!haveHost || len(hosts) == 0) && !isH2Upgrade && req.Method != "CONNECT" {
 		return nil, badRequestError("missing required Host header")
 	}
-	if len(hosts) > 1 {
-		return nil, badRequestError("too many Host headers")
-	}
 	if len(hosts) == 1 && !httpguts.ValidHostHeader(hosts[0]) {
 		return nil, badRequestError("malformed Host header")
 	}
@@ -1552,12 +1529,12 @@
 // The Writers are wired together like:
 //
 // 1. *response (the ResponseWriter) ->
-// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes
+// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes ->
 // 3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type)
-//    and which writes the chunk headers, if needed.
-// 4. conn.buf, a bufio.Writer of default (4kB) bytes, writing to ->
+//    and which writes the chunk headers, if needed ->
+// 4. conn.bufw, a *bufio.Writer of default (4kB) bytes, writing to ->
 // 5. checkConnErrorWriter{c}, which notes any non-nil error on Write
-//    and populates c.werr with it if so. but otherwise writes to:
+//    and populates c.werr with it if so, but otherwise writes to ->
 // 6. the rwc, the net.Conn.
 //
 // TODO(bradfitz): short-circuit some of the buffering when the
@@ -1831,13 +1808,13 @@
 	}()
 
 	if tlsConn, ok := c.rwc.(*tls.Conn); ok {
-		if d := c.server.ReadTimeout; d != 0 {
+		if d := c.server.ReadTimeout; d > 0 {
 			c.rwc.SetReadDeadline(time.Now().Add(d))
 		}
-		if d := c.server.WriteTimeout; d != 0 {
+		if d := c.server.WriteTimeout; d > 0 {
 			c.rwc.SetWriteDeadline(time.Now().Add(d))
 		}
-		if err := tlsConn.Handshake(); err != nil {
+		if err := tlsConn.HandshakeContext(ctx); err != nil {
 			// If the handshake failed due to the client not speaking
 			// TLS, assume they're speaking plaintext HTTP and write a
 			// 400 response on the TLS conn's underlying net.Conn.
@@ -2407,9 +2384,8 @@
 
 	if path != r.URL.Path {
 		_, pattern = mux.handler(host, path)
-		url := *r.URL
-		url.Path = path
-		return RedirectHandler(url.String(), StatusMovedPermanently), pattern
+		u := &url.URL{Path: path, RawQuery: r.URL.RawQuery}
+		return RedirectHandler(u.String(), StatusMovedPermanently), pattern
 	}
 
 	return mux.handler(host, r.URL.Path)
@@ -2567,7 +2543,8 @@
 	TLSConfig *tls.Config
 
 	// ReadTimeout is the maximum duration for reading the entire
-	// request, including the body.
+	// request, including the body. A zero or negative value means
+	// there will be no timeout.
 	//
 	// Because ReadTimeout does not let Handlers make per-request
 	// decisions on each request body's acceptable deadline or
@@ -2587,6 +2564,7 @@
 	// writes of the response. It is reset whenever a new
 	// request's header is read. Like ReadTimeout, it does not
 	// let Handlers make decisions on a per-request basis.
+	// A zero or negative value means there will be no timeout.
 	WriteTimeout time.Duration
 
 	// IdleTimeout is the maximum amount of time to wait for the
@@ -2638,7 +2616,7 @@
 	// value.
 	ConnContext func(ctx context.Context, c net.Conn) context.Context
 
-	inShutdown atomicBool // true when when server is in shutdown
+	inShutdown atomicBool // true when server is in shutdown
 
 	disableKeepAlives int32     // accessed atomically.
 	nextProtoOnce     sync.Once // guards setupHTTP2_* init
@@ -2884,9 +2862,51 @@
 	if req.RequestURI == "*" && req.Method == "OPTIONS" {
 		handler = globalOptionsHandler{}
 	}
+
+	if req.URL != nil && strings.Contains(req.URL.RawQuery, ";") {
+		var allowQuerySemicolonsInUse int32
+		req = req.WithContext(context.WithValue(req.Context(), silenceSemWarnContextKey, func() {
+			atomic.StoreInt32(&allowQuerySemicolonsInUse, 1)
+		}))
+		defer func() {
+			if atomic.LoadInt32(&allowQuerySemicolonsInUse) == 0 {
+				sh.srv.logf("http: URL query contains semicolon, which is no longer a supported separator; parts of the query may be stripped when parsed; see golang.org/issue/25192")
+			}
+		}()
+	}
+
 	handler.ServeHTTP(rw, req)
 }
 
+var silenceSemWarnContextKey = &contextKey{"silence-semicolons"}
+
+// AllowQuerySemicolons returns a handler that serves requests by converting any
+// unescaped semicolons in the URL query to ampersands, and invoking the handler h.
+//
+// This restores the pre-Go 1.17 behavior of splitting query parameters on both
+// semicolons and ampersands. (See golang.org/issue/25192). Note that this
+// behavior doesn't match that of many proxies, and the mismatch can lead to
+// security issues.
+//
+// AllowQuerySemicolons should be invoked before Request.ParseForm is called.
+func AllowQuerySemicolons(h Handler) Handler {
+	return HandlerFunc(func(w ResponseWriter, r *Request) {
+		if silenceSemicolonsWarning, ok := r.Context().Value(silenceSemWarnContextKey).(func()); ok {
+			silenceSemicolonsWarning()
+		}
+		if strings.Contains(r.URL.RawQuery, ";") {
+			r2 := new(Request)
+			*r2 = *r
+			r2.URL = new(url.URL)
+			*r2.URL = *r.URL
+			r2.URL.RawQuery = strings.ReplaceAll(r.URL.RawQuery, ";", "&")
+			h.ServeHTTP(w, r2)
+		} else {
+			h.ServeHTTP(w, r)
+		}
+	})
+}
+
 // ListenAndServe listens on the TCP network address srv.Addr and then
 // calls Serve to handle requests on incoming connections.
 // Accepted connections are configured to enable TCP keep-alives.
diff --git a/src/net/http/sniff_test.go b/src/net/http/sniff_test.go
index 8d53503..e913357 100644
--- a/src/net/http/sniff_test.go
+++ b/src/net/http/sniff_test.go
@@ -157,9 +157,25 @@
 	resp.Body.Close()
 }
 
-func TestContentTypeWithCopy_h1(t *testing.T) { testContentTypeWithCopy(t, h1Mode) }
-func TestContentTypeWithCopy_h2(t *testing.T) { testContentTypeWithCopy(t, h2Mode) }
-func testContentTypeWithCopy(t *testing.T, h2 bool) {
+type byteAtATimeReader struct {
+	buf []byte
+}
+
+func (b *byteAtATimeReader) Read(p []byte) (n int, err error) {
+	if len(p) < 1 {
+		return 0, nil
+	}
+	if len(b.buf) == 0 {
+		return 0, io.EOF
+	}
+	p[0] = b.buf[0]
+	b.buf = b.buf[1:]
+	return 1, nil
+}
+
+func TestContentTypeWithVariousSources_h1(t *testing.T) { testContentTypeWithVariousSources(t, h1Mode) }
+func TestContentTypeWithVariousSources_h2(t *testing.T) { testContentTypeWithVariousSources(t, h2Mode) }
+func testContentTypeWithVariousSources(t *testing.T, h2 bool) {
 	defer afterTest(t)
 
 	const (
@@ -167,30 +183,86 @@
 		expected = "text/html; charset=utf-8"
 	)
 
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
-		// Use io.Copy from a bytes.Buffer to trigger ReadFrom.
-		buf := bytes.NewBuffer([]byte(input))
-		n, err := io.Copy(w, buf)
-		if int(n) != len(input) || err != nil {
-			t.Errorf("io.Copy(w, %q) = %v, %v want %d, nil", input, n, err, len(input))
-		}
-	}))
-	defer cst.close()
+	for _, test := range []struct {
+		name    string
+		handler func(ResponseWriter, *Request)
+	}{{
+		name: "write",
+		handler: func(w ResponseWriter, r *Request) {
+			// Write the whole input at once.
+			n, err := w.Write([]byte(input))
+			if int(n) != len(input) || err != nil {
+				t.Errorf("w.Write(%q) = %v, %v want %d, nil", input, n, err, len(input))
+			}
+		},
+	}, {
+		name: "write one byte at a time",
+		handler: func(w ResponseWriter, r *Request) {
+			// Write the input one byte at a time.
+			buf := []byte(input)
+			for i := range buf {
+				n, err := w.Write(buf[i : i+1])
+				if n != 1 || err != nil {
+					t.Errorf("w.Write(%q) = %v, %v want 1, nil", input, n, err)
+				}
+			}
+		},
+	}, {
+		name: "copy from Reader",
+		handler: func(w ResponseWriter, r *Request) {
+			// Use io.Copy from a plain Reader.
+			type readerOnly struct{ io.Reader }
+			buf := bytes.NewBuffer([]byte(input))
+			n, err := io.Copy(w, readerOnly{buf})
+			if int(n) != len(input) || err != nil {
+				t.Errorf("io.Copy(w, %q) = %v, %v want %d, nil", input, n, err, len(input))
+			}
+		},
+	}, {
+		name: "copy from bytes.Buffer",
+		handler: func(w ResponseWriter, r *Request) {
+			// Use io.Copy from a bytes.Buffer to trigger ReadFrom.
+			buf := bytes.NewBuffer([]byte(input))
+			n, err := io.Copy(w, buf)
+			if int(n) != len(input) || err != nil {
+				t.Errorf("io.Copy(w, %q) = %v, %v want %d, nil", input, n, err, len(input))
+			}
+		},
+	}, {
+		name: "copy one byte at a time",
+		handler: func(w ResponseWriter, r *Request) {
+			// Use io.Copy from a Reader that returns one byte at a time.
+			n, err := io.Copy(w, &byteAtATimeReader{[]byte(input)})
+			if int(n) != len(input) || err != nil {
+				t.Errorf("io.Copy(w, %q) = %v, %v want %d, nil", input, n, err, len(input))
+			}
+		},
+	}} {
+		t.Run(test.name, func(t *testing.T) {
+			cst := newClientServerTest(t, h2, HandlerFunc(test.handler))
+			defer cst.close()
 
-	resp, err := cst.c.Get(cst.ts.URL)
-	if err != nil {
-		t.Fatalf("Get: %v", err)
+			resp, err := cst.c.Get(cst.ts.URL)
+			if err != nil {
+				t.Fatalf("Get: %v", err)
+			}
+			if ct := resp.Header.Get("Content-Type"); ct != expected {
+				t.Errorf("Content-Type = %q, want %q", ct, expected)
+			}
+			if want, got := resp.Header.Get("Content-Length"), fmt.Sprint(len(input)); want != got {
+				t.Errorf("Content-Length = %q, want %q", want, got)
+			}
+			data, err := io.ReadAll(resp.Body)
+			if err != nil {
+				t.Errorf("reading body: %v", err)
+			} else if !bytes.Equal(data, []byte(input)) {
+				t.Errorf("data is %q, want %q", data, input)
+			}
+			resp.Body.Close()
+
+		})
+
 	}
-	if ct := resp.Header.Get("Content-Type"); ct != expected {
-		t.Errorf("Content-Type = %q, want %q", ct, expected)
-	}
-	data, err := io.ReadAll(resp.Body)
-	if err != nil {
-		t.Errorf("reading body: %v", err)
-	} else if !bytes.Equal(data, []byte(input)) {
-		t.Errorf("data is %q, want %q", data, input)
-	}
-	resp.Body.Close()
 }
 
 func TestSniffWriteSize_h1(t *testing.T) { testSniffWriteSize(t, h1Mode) }
diff --git a/src/net/http/transfer.go b/src/net/http/transfer.go
index fbb0c39..85c2e5a 100644
--- a/src/net/http/transfer.go
+++ b/src/net/http/transfer.go
@@ -12,6 +12,7 @@
 	"io"
 	"net/http/httptrace"
 	"net/http/internal"
+	"net/http/internal/ascii"
 	"net/textproto"
 	"reflect"
 	"sort"
@@ -638,7 +639,7 @@
 	if len(raw) != 1 {
 		return &unsupportedTEError{fmt.Sprintf("too many transfer encodings: %q", raw)}
 	}
-	if strings.ToLower(textproto.TrimString(raw[0])) != "chunked" {
+	if !ascii.EqualFold(textproto.TrimString(raw[0]), "chunked") {
 		return &unsupportedTEError{fmt.Sprintf("unsupported transfer encoding: %q", raw[0])}
 	}
 
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index 0aa4827..309194e 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -21,6 +21,7 @@
 	"log"
 	"net"
 	"net/http/httptrace"
+	"net/http/internal/ascii"
 	"net/textproto"
 	"net/url"
 	"os"
@@ -426,6 +427,7 @@
 //
 // The environment values may be either a complete URL or a
 // "host[:port]", in which case the "http" scheme is assumed.
+// The schemes "http", "https", and "socks5" are supported.
 // An error is returned if the value is a different form.
 //
 // A nil URL and nil error are returned if no proxy is defined in the
@@ -786,10 +788,12 @@
 // Cancel an in-flight request, recording the error value.
 // Returns whether the request was canceled.
 func (t *Transport) cancelRequest(key cancelKey, err error) bool {
+	// This function must not return until the cancel func has completed.
+	// See: https://golang.org/issue/34658
 	t.reqMu.Lock()
+	defer t.reqMu.Unlock()
 	cancel := t.reqCanceler[key]
 	delete(t.reqCanceler, key)
-	t.reqMu.Unlock()
 	if cancel != nil {
 		cancel(err)
 	}
@@ -1185,7 +1189,7 @@
 
 	// hooks for testing to know when dials are done
 	// beforeDial is called in the getConn goroutine when the dial is queued.
-	// afterDial is called when the dial is completed or cancelled.
+	// afterDial is called when the dial is completed or canceled.
 	beforeDial func()
 	afterDial  func()
 
@@ -1373,7 +1377,7 @@
 			trace.GotConn(httptrace.GotConnInfo{Conn: w.pc.conn, Reused: w.pc.isReused()})
 		}
 		if w.err != nil {
-			// If the request has been cancelled, that's probably
+			// If the request has been canceled, that's probably
 			// what caused w.err; if so, prefer to return the
 			// cancellation error (see golang.org/issue/16049).
 			select {
@@ -1435,7 +1439,7 @@
 
 // dialConnFor dials on behalf of w and delivers the result to w.
 // dialConnFor has received permission to dial w.cm and is counted in t.connCount[w.cm.key()].
-// If the dial is cancelled or unsuccessful, dialConnFor decrements t.connCount[w.cm.key()].
+// If the dial is canceled or unsuccessful, dialConnFor decrements t.connCount[w.cm.key()].
 func (t *Transport) dialConnFor(w *wantConn) {
 	defer w.afterDial()
 
@@ -1505,7 +1509,7 @@
 // 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 {
+func (pconn *persistConn) addTLS(ctx context.Context, name string, trace *httptrace.ClientTrace) error {
 	// Initiate TLS and check remote host name against certificate.
 	cfg := cloneTLSConfig(pconn.t.TLSClientConfig)
 	if cfg.ServerName == "" {
@@ -1527,7 +1531,7 @@
 		if trace != nil && trace.TLSHandshakeStart != nil {
 			trace.TLSHandshakeStart()
 		}
-		err := tlsConn.Handshake()
+		err := tlsConn.HandshakeContext(ctx)
 		if timer != nil {
 			timer.Stop()
 		}
@@ -1583,7 +1587,7 @@
 			if trace != nil && trace.TLSHandshakeStart != nil {
 				trace.TLSHandshakeStart()
 			}
-			if err := tc.Handshake(); err != nil {
+			if err := tc.HandshakeContext(ctx); err != nil {
 				go pconn.conn.Close()
 				if trace != nil && trace.TLSHandshakeDone != nil {
 					trace.TLSHandshakeDone(tls.ConnectionState{}, err)
@@ -1607,7 +1611,7 @@
 			if firstTLSHost, _, err = net.SplitHostPort(cm.addr()); err != nil {
 				return nil, wrapErr(err)
 			}
-			if err = pconn.addTLS(firstTLSHost, trace); err != nil {
+			if err = pconn.addTLS(ctx, firstTLSHost, trace); err != nil {
 				return nil, wrapErr(err)
 			}
 		}
@@ -1721,7 +1725,7 @@
 	}
 
 	if cm.proxyURL != nil && cm.targetScheme == "https" {
-		if err := pconn.addTLS(cm.tlsHost(), trace); err != nil {
+		if err := pconn.addTLS(ctx, cm.tlsHost(), trace); err != nil {
 			return nil, err
 		}
 	}
@@ -2183,7 +2187,7 @@
 		}
 
 		resp.Body = body
-		if rc.addedGzip && strings.EqualFold(resp.Header.Get("Content-Encoding"), "gzip") {
+		if rc.addedGzip && ascii.EqualFold(resp.Header.Get("Content-Encoding"), "gzip") {
 			resp.Body = &gzipReader{body: body}
 			resp.Header.Del("Content-Encoding")
 			resp.Header.Del("Content-Length")
diff --git a/src/net/http/transport_internal_test.go b/src/net/http/transport_internal_test.go
index 1097ffd..1cce272 100644
--- a/src/net/http/transport_internal_test.go
+++ b/src/net/http/transport_internal_test.go
@@ -12,7 +12,7 @@
 	"errors"
 	"io"
 	"net"
-	"net/http/internal"
+	"net/http/internal/testcert"
 	"strings"
 	"testing"
 )
@@ -191,7 +191,7 @@
 
 // Issue 25009
 func TestTransportBodyAltRewind(t *testing.T) {
-	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index ba85a61..eeaa492 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -30,7 +30,7 @@
 	"net/http/httptest"
 	"net/http/httptrace"
 	"net/http/httputil"
-	"net/http/internal"
+	"net/http/internal/testcert"
 	"net/textproto"
 	"net/url"
 	"os"
@@ -626,12 +626,15 @@
 			t.Fatalf("ExportHttp2ConfigureTransport: %v", err)
 		}
 
-		connCh := make(chan net.Conn, 1)
+		mu := sync.Mutex{}
+		var conns []net.Conn
 		var dialCnt, gotConnCnt, tlsHandshakeCnt int32
 		tr.Dial = func(network, addr string) (net.Conn, error) {
 			atomic.AddInt32(&dialCnt, 1)
 			c, err := net.Dial(network, addr)
-			connCh <- c
+			mu.Lock()
+			defer mu.Unlock()
+			conns = append(conns, c)
 			return c, err
 		}
 
@@ -685,7 +688,12 @@
 			t.FailNow()
 		}
 
-		(<-connCh).Close()
+		mu.Lock()
+		for _, c := range conns {
+			c.Close()
+		}
+		conns = nil
+		mu.Unlock()
 		tr.CloseIdleConnections()
 
 		doReq()
@@ -3734,7 +3742,7 @@
 		if err != nil {
 			return nil, err
 		}
-		return c, c.Handshake()
+		return c, c.HandshakeContext(ctx)
 	}
 
 	req, err := NewRequest("GET", ts.URL, nil)
@@ -4291,7 +4299,7 @@
 
 // Issue 13839
 func TestNoCrashReturningTransportAltConn(t *testing.T) {
-	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -5314,7 +5322,6 @@
 
 	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" +
@@ -5326,10 +5333,7 @@
 		"Aloha Olaa"
 
 	go func() {
-		defer func() {
-			ln.Close()
-			close(done)
-		}()
+		defer close(done)
 
 		conn, _ := ln.Accept()
 		if conn != nil {
@@ -5360,7 +5364,7 @@
 		t.Errorf("got=%v want=%q", err, want)
 	}
 
-	close(shutdown)
+	ln.Close()
 	<-done
 }
 
@@ -6437,10 +6441,11 @@
 // Test that a new request which uses the connection of an active request
 // cannot cause it to be canceled as well.
 func TestCancelRequestWhenSharingConnection(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in short mode")
-	}
+	reqc := make(chan chan struct{}, 2)
 	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, req *Request) {
+		ch := make(chan struct{}, 1)
+		reqc <- ch
+		<-ch
 		w.Header().Add("Content-Length", "0")
 	}))
 	defer ts.Close()
@@ -6452,34 +6457,58 @@
 
 	var wg sync.WaitGroup
 
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	for i := 0; i < 10; i++ {
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
-			for ctx.Err() == nil {
-				reqctx, reqcancel := context.WithCancel(ctx)
-				go reqcancel()
-				req, _ := NewRequestWithContext(reqctx, "GET", ts.URL, nil)
-				res, err := client.Do(req)
-				if err == nil {
-					res.Body.Close()
-				}
-			}
-		}()
-	}
-
-	for ctx.Err() == nil {
-		req, _ := NewRequest("GET", ts.URL, nil)
-		if res, err := client.Do(req); err != nil {
-			t.Errorf("unexpected: %p %v", req, err)
-			break
-		} else {
+	wg.Add(1)
+	putidlec := make(chan chan struct{})
+	go func() {
+		defer wg.Done()
+		ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
+			PutIdleConn: func(error) {
+				// Signal that the idle conn has been returned to the pool,
+				// and wait for the order to proceed.
+				ch := make(chan struct{})
+				putidlec <- ch
+				<-ch
+			},
+		})
+		req, _ := NewRequestWithContext(ctx, "GET", ts.URL, nil)
+		res, err := client.Do(req)
+		if err == nil {
 			res.Body.Close()
 		}
-	}
+		if err != nil {
+			t.Errorf("request 1: got err %v, want nil", err)
+		}
+	}()
 
+	// Wait for the first request to receive a response and return the
+	// connection to the idle pool.
+	r1c := <-reqc
+	close(r1c)
+	idlec := <-putidlec
+
+	wg.Add(1)
+	cancelctx, cancel := context.WithCancel(context.Background())
+	go func() {
+		defer wg.Done()
+		req, _ := NewRequestWithContext(cancelctx, "GET", ts.URL, nil)
+		res, err := client.Do(req)
+		if err == nil {
+			res.Body.Close()
+		}
+		if !errors.Is(err, context.Canceled) {
+			t.Errorf("request 2: got err %v, want Canceled", err)
+		}
+	}()
+
+	// Wait for the second request to arrive at the server, and then cancel
+	// the request context.
+	r2c := <-reqc
 	cancel()
+
+	// Give the cancelation a moment to take effect, and then unblock the first request.
+	time.Sleep(1 * time.Millisecond)
+	close(idlec)
+
+	close(r2c)
 	wg.Wait()
 }
diff --git a/src/net/http/triv.go b/src/net/http/triv.go
index 23e65d5..4dc6240 100644
--- a/src/net/http/triv.go
+++ b/src/net/http/triv.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 package main
diff --git a/src/net/interface.go b/src/net/interface.go
index 914aaa0..0e5d320 100644
--- a/src/net/interface.go
+++ b/src/net/interface.go
@@ -6,6 +6,7 @@
 
 import (
 	"errors"
+	"internal/itoa"
 	"sync"
 	"time"
 )
@@ -230,7 +231,7 @@
 		zoneCache.RUnlock()
 	}
 	if !ok { // last resort
-		name = uitoa(uint(index))
+		name = itoa.Uitoa(uint(index))
 	}
 	return name
 }
diff --git a/src/net/interface_bsd.go b/src/net/interface_bsd.go
index d791cb3..7578b1a 100644
--- a/src/net/interface_bsd.go
+++ b/src/net/interface_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 package net
diff --git a/src/net/interface_bsd_test.go b/src/net/interface_bsd_test.go
index 947dde7..8d0d9c3 100644
--- a/src/net/interface_bsd_test.go
+++ b/src/net/interface_bsd_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 package net
diff --git a/src/net/interface_bsdvar.go b/src/net/interface_bsdvar.go
index a809b5f..6230e0b 100644
--- a/src/net/interface_bsdvar.go
+++ b/src/net/interface_bsdvar.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || netbsd || openbsd
 // +build dragonfly netbsd openbsd
 
 package net
diff --git a/src/net/interface_freebsd.go b/src/net/interface_freebsd.go
index 45badd6..2b51fcb 100644
--- a/src/net/interface_freebsd.go
+++ b/src/net/interface_freebsd.go
@@ -16,9 +16,9 @@
 	if err != nil {
 		typ = route.RIBType(syscall.NET_RT_IFLIST)
 		rib, err = route.FetchRIB(syscall.AF_UNSPEC, typ, ifindex)
-	}
-	if err != nil {
-		return nil, err
+		if err != nil {
+			return nil, err
+		}
 	}
 	return route.ParseRIB(typ, rib)
 }
diff --git a/src/net/interface_plan9.go b/src/net/interface_plan9.go
index 31bbaca..957975c 100644
--- a/src/net/interface_plan9.go
+++ b/src/net/interface_plan9.go
@@ -6,6 +6,7 @@
 
 import (
 	"errors"
+	"internal/itoa"
 	"os"
 )
 
@@ -38,8 +39,8 @@
 
 func readInterface(i int) (*Interface, error) {
 	ifc := &Interface{
-		Index: i + 1,                        // Offset the index by one to suit the contract
-		Name:  netdir + "/ipifc/" + itoa(i), // Name is the full path to the interface path in plan9
+		Index: i + 1,                             // Offset the index by one to suit the contract
+		Name:  netdir + "/ipifc/" + itoa.Itoa(i), // Name is the full path to the interface path in plan9
 	}
 
 	ifcstat := ifc.Name + "/status"
diff --git a/src/net/interface_stub.go b/src/net/interface_stub.go
index ec58665..efe67c2 100644
--- a/src/net/interface_stub.go
+++ b/src/net/interface_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package net
diff --git a/src/net/interface_test.go b/src/net/interface_test.go
index b2ef21e..754db36 100644
--- a/src/net/interface_test.go
+++ b/src/net/interface_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/interface_unix_test.go b/src/net/interface_unix_test.go
index bf41a0f..0d69fa5 100644
--- a/src/net/interface_unix_test.go
+++ b/src/net/interface_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
 // +build darwin dragonfly freebsd linux netbsd openbsd
 
 package net
diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go
index 3b0a48a..8af85d3 100644
--- a/src/net/internal/socktest/main_test.go
+++ b/src/net/internal/socktest/main_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js && !plan9
 // +build !js,!plan9
 
 package socktest_test
diff --git a/src/net/internal/socktest/main_unix_test.go b/src/net/internal/socktest/main_unix_test.go
index 4d9d414..6aa8875 100644
--- a/src/net/internal/socktest/main_unix_test.go
+++ b/src/net/internal/socktest/main_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js && !plan9 && !windows
 // +build !js,!plan9,!windows
 
 package socktest_test
diff --git a/src/net/internal/socktest/switch_posix.go b/src/net/internal/socktest/switch_posix.go
index 863edef..cda74e8 100644
--- a/src/net/internal/socktest/switch_posix.go
+++ b/src/net/internal/socktest/switch_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !plan9
 // +build !plan9
 
 package socktest
diff --git a/src/net/internal/socktest/switch_stub.go b/src/net/internal/socktest/switch_stub.go
index 28ce72c..5aa2ece 100644
--- a/src/net/internal/socktest/switch_stub.go
+++ b/src/net/internal/socktest/switch_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build plan9
 // +build plan9
 
 package socktest
diff --git a/src/net/internal/socktest/switch_unix.go b/src/net/internal/socktest/switch_unix.go
index 7dc3518..bfe9d4d 100644
--- a/src/net/internal/socktest/switch_unix.go
+++ b/src/net/internal/socktest/switch_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package socktest
diff --git a/src/net/internal/socktest/sys_cloexec.go b/src/net/internal/socktest/sys_cloexec.go
index 421352c..c7f8331 100644
--- a/src/net/internal/socktest/sys_cloexec.go
+++ b/src/net/internal/socktest/sys_cloexec.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || illumos || linux || netbsd || openbsd
 // +build dragonfly freebsd illumos linux netbsd openbsd
 
 package socktest
diff --git a/src/net/internal/socktest/sys_unix.go b/src/net/internal/socktest/sys_unix.go
index 0525512..e7cc459 100644
--- a/src/net/internal/socktest/sys_unix.go
+++ b/src/net/internal/socktest/sys_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package socktest
diff --git a/src/net/ip.go b/src/net/ip.go
index c00fe8e..38e1aa2 100644
--- a/src/net/ip.go
+++ b/src/net/ip.go
@@ -12,7 +12,10 @@
 
 package net
 
-import "internal/bytealg"
+import (
+	"internal/bytealg"
+	"internal/itoa"
+)
 
 // IP address lengths (bytes).
 const (
@@ -125,6 +128,25 @@
 	return ip.Equal(IPv6loopback)
 }
 
+// IsPrivate reports whether ip is a private address, according to
+// RFC 1918 (IPv4 addresses) and RFC 4193 (IPv6 addresses).
+func (ip IP) IsPrivate() bool {
+	if ip4 := ip.To4(); ip4 != nil {
+		// Following RFC 1918, Section 3. Private Address Space which says:
+		//   The Internet Assigned Numbers Authority (IANA) has reserved the
+		//   following three blocks of the IP address space for private internets:
+		//     10.0.0.0        -   10.255.255.255  (10/8 prefix)
+		//     172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
+		//     192.168.0.0     -   192.168.255.255 (192.168/16 prefix)
+		return ip4[0] == 10 ||
+			(ip4[0] == 172 && ip4[1]&0xf0 == 16) ||
+			(ip4[0] == 192 && ip4[1] == 168)
+	}
+	// Following RFC 4193, Section 8. IANA Considerations which says:
+	//   The IANA has assigned the FC00::/7 prefix to "Unique Local Unicast".
+	return len(ip) == IPv6len && ip[0]&0xfe == 0xfc
+}
+
 // IsMulticast reports whether ip is a multicast address.
 func (ip IP) IsMulticast() bool {
 	if ip4 := ip.To4(); ip4 != nil {
@@ -531,7 +553,7 @@
 	if l == -1 {
 		return nn.String() + "/" + m.String()
 	}
-	return nn.String() + "/" + uitoa(uint(l))
+	return nn.String() + "/" + itoa.Uitoa(uint(l))
 }
 
 // Parse IPv4 address (d.d.d.d).
@@ -552,6 +574,10 @@
 		if !ok || n > 0xFF {
 			return nil
 		}
+		if c > 1 && s[0] == '0' {
+			// Reject non-zero components with leading zeroes.
+			return nil
+		}
 		s = s[c:]
 		p[i] = byte(n)
 	}
diff --git a/src/net/ip_test.go b/src/net/ip_test.go
index a5fc5e6..5bbda60 100644
--- a/src/net/ip_test.go
+++ b/src/net/ip_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
@@ -20,9 +21,7 @@
 }{
 	{"127.0.1.2", IPv4(127, 0, 1, 2)},
 	{"127.0.0.1", IPv4(127, 0, 0, 1)},
-	{"127.001.002.003", IPv4(127, 1, 2, 3)},
 	{"::ffff:127.1.2.3", IPv4(127, 1, 2, 3)},
-	{"::ffff:127.001.002.003", IPv4(127, 1, 2, 3)},
 	{"::ffff:7f01:0203", IPv4(127, 1, 2, 3)},
 	{"0:0:0:0:0000:ffff:127.1.2.3", IPv4(127, 1, 2, 3)},
 	{"0:0:0:0:000000:ffff:127.1.2.3", IPv4(127, 1, 2, 3)},
@@ -42,6 +41,11 @@
 	{"fe80::1%911", nil},
 	{"", nil},
 	{"a1:a2:a3:a4::b1:b2:b3:b4", nil}, // Issue 6628
+	{"127.001.002.003", nil},
+	{"::ffff:127.001.002.003", nil},
+	{"123.000.000.000", nil},
+	{"1.2..4", nil},
+	{"0123.0.0.1", nil},
 }
 
 func TestParseIP(t *testing.T) {
@@ -357,6 +361,7 @@
 	{"0.0.-2.0/32", nil, nil, &ParseError{Type: "CIDR address", Text: "0.0.-2.0/32"}},
 	{"0.0.0.-3/32", nil, nil, &ParseError{Type: "CIDR address", Text: "0.0.0.-3/32"}},
 	{"0.0.0.0/-0", nil, nil, &ParseError{Type: "CIDR address", Text: "0.0.0.0/-0"}},
+	{"127.000.000.001/32", nil, nil, &ParseError{Type: "CIDR address", Text: "127.000.000.001/32"}},
 	{"", nil, nil, &ParseError{Type: "CIDR address", Text: ""}},
 }
 
@@ -690,6 +695,28 @@
 	{IP.IsGlobalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
 	{IP.IsGlobalUnicast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
 	{IP.IsGlobalUnicast, nil, false},
+	{IP.IsPrivate, nil, false},
+	{IP.IsPrivate, IPv4(1, 1, 1, 1), false},
+	{IP.IsPrivate, IPv4(9, 255, 255, 255), false},
+	{IP.IsPrivate, IPv4(10, 0, 0, 0), true},
+	{IP.IsPrivate, IPv4(10, 255, 255, 255), true},
+	{IP.IsPrivate, IPv4(11, 0, 0, 0), false},
+	{IP.IsPrivate, IPv4(172, 15, 255, 255), false},
+	{IP.IsPrivate, IPv4(172, 16, 0, 0), true},
+	{IP.IsPrivate, IPv4(172, 16, 255, 255), true},
+	{IP.IsPrivate, IPv4(172, 23, 18, 255), true},
+	{IP.IsPrivate, IPv4(172, 31, 255, 255), true},
+	{IP.IsPrivate, IPv4(172, 31, 0, 0), true},
+	{IP.IsPrivate, IPv4(172, 32, 0, 0), false},
+	{IP.IsPrivate, IPv4(192, 167, 255, 255), false},
+	{IP.IsPrivate, IPv4(192, 168, 0, 0), true},
+	{IP.IsPrivate, IPv4(192, 168, 255, 255), true},
+	{IP.IsPrivate, IPv4(192, 169, 0, 0), false},
+	{IP.IsPrivate, IP{0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, false},
+	{IP.IsPrivate, IP{0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
+	{IP.IsPrivate, IP{0xfc, 0xff, 0x12, 0, 0, 0, 0, 0x44, 0, 0, 0, 0, 0, 0, 0, 0}, true},
+	{IP.IsPrivate, IP{0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, true},
+	{IP.IsPrivate, IP{0xfe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
 }
 
 func name(f interface{}) string {
diff --git a/src/net/iprawsock_posix.go b/src/net/iprawsock_posix.go
index e653f6a..b94eec0 100644
--- a/src/net/iprawsock_posix.go
+++ b/src/net/iprawsock_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package net
@@ -74,7 +75,7 @@
 
 func (c *IPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error) {
 	var sa syscall.Sockaddr
-	n, oobn, flags, sa, err = c.fd.readMsg(b, oob)
+	n, oobn, flags, sa, err = c.fd.readMsg(b, oob, 0)
 	switch sa := sa.(type) {
 	case *syscall.SockaddrInet4:
 		addr = &IPAddr{IP: sa.Addr[0:]}
diff --git a/src/net/iprawsock_test.go b/src/net/iprawsock_test.go
index 8e3543d..a96448e 100644
--- a/src/net/iprawsock_test.go
+++ b/src/net/iprawsock_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/ipsock.go b/src/net/ipsock.go
index 7d0684d..0f5da25 100644
--- a/src/net/ipsock.go
+++ b/src/net/ipsock.go
@@ -7,6 +7,7 @@
 import (
 	"context"
 	"internal/bytealg"
+	"runtime"
 	"sync"
 )
 
@@ -44,6 +45,13 @@
 // IPv4 address inside an IPv6 address at transport layer
 // protocols. See RFC 4291, RFC 4038 and RFC 3493.
 func supportsIPv4map() bool {
+	// Some operating systems provide no support for mapping IPv4
+	// addresses to IPv6, and a runtime check is unnecessary.
+	switch runtime.GOOS {
+	case "dragonfly", "openbsd":
+		return false
+	}
+
 	ipStackCaps.Once.Do(ipStackCaps.probe)
 	return ipStackCaps.ipv4MappedIPv6Enabled
 }
diff --git a/src/net/ipsock_plan9.go b/src/net/ipsock_plan9.go
index 7a4b7a6..4328743 100644
--- a/src/net/ipsock_plan9.go
+++ b/src/net/ipsock_plan9.go
@@ -7,12 +7,13 @@
 import (
 	"context"
 	"internal/bytealg"
+	"internal/itoa"
 	"io/fs"
 	"os"
 	"syscall"
 )
 
-// Probe probes IPv4, IPv6 and IPv4-mapped IPv6 communication
+// probe probes IPv4, IPv6 and IPv4-mapped IPv6 communication
 // capabilities.
 //
 // Plan 9 uses IPv6 natively, see ip(3).
@@ -336,9 +337,9 @@
 		if port == 0 {
 			return ""
 		}
-		return itoa(port)
+		return itoa.Itoa(port)
 	}
-	return ip.String() + "!" + itoa(port)
+	return ip.String() + "!" + itoa.Itoa(port)
 }
 
 func hangupCtlWrite(ctx context.Context, proto string, ctl *os.File, msg string) error {
diff --git a/src/net/ipsock_posix.go b/src/net/ipsock_posix.go
index 8763d57..c51c227 100644
--- a/src/net/ipsock_posix.go
+++ b/src/net/ipsock_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package net
@@ -13,13 +14,13 @@
 	"syscall"
 )
 
-// Probe probes IPv4, IPv6 and IPv4-mapped IPv6 communication
+// probe probes IPv4, IPv6 and IPv4-mapped IPv6 communication
 // capabilities which are controlled by the IPV6_V6ONLY socket option
 // and kernel configuration.
 //
 // Should we try to use the IPv4 socket interface if we're only
 // dealing with IPv4 sockets? As long as the host system understands
-// IPv4-mapped IPv6, it's okay to pass IPv4-mapeed IPv6 addresses to
+// IPv4-mapped IPv6, it's okay to pass IPv4-mapped IPv6 addresses to
 // the IPv6 interface. That simplifies our code and is most
 // general. Unfortunately, we need to run on kernels built without
 // IPv6 support too. So probe the kernel to figure it out.
diff --git a/src/net/listen_test.go b/src/net/listen_test.go
index d8c7209..b1dce29 100644
--- a/src/net/listen_test.go
+++ b/src/net/listen_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js && !plan9
 // +build !js,!plan9
 
 package net
diff --git a/src/net/lookup.go b/src/net/lookup.go
index 5f71198..d350ef7 100644
--- a/src/net/lookup.go
+++ b/src/net/lookup.go
@@ -166,6 +166,9 @@
 
 // LookupHost looks up the given host using the local resolver.
 // It returns a slice of that host's addresses.
+//
+// LookupHost uses context.Background internally; to specify the context, use
+// Resolver.LookupHost.
 func LookupHost(host string) (addrs []string, err error) {
 	return DefaultResolver.LookupHost(context.Background(), host)
 }
@@ -353,6 +356,9 @@
 }
 
 // LookupPort looks up the port for the given network and service.
+//
+// LookupPort uses context.Background internally; to specify the context, use
+// Resolver.LookupPort.
 func LookupPort(network, service string) (port int, err error) {
 	return DefaultResolver.LookupPort(context.Background(), network, service)
 }
@@ -389,8 +395,14 @@
 // LookupCNAME does not return an error if host does not
 // contain DNS "CNAME" records, as long as host resolves to
 // address records.
+//
+// The returned canonical name is validated to be a properly
+// formatted presentation-format domain name.
+//
+// LookupCNAME uses context.Background internally; to specify the context, use
+// Resolver.LookupCNAME.
 func LookupCNAME(host string) (cname string, err error) {
-	return DefaultResolver.lookupCNAME(context.Background(), host)
+	return DefaultResolver.LookupCNAME(context.Background(), host)
 }
 
 // LookupCNAME returns the canonical name for the given host.
@@ -403,8 +415,18 @@
 // LookupCNAME does not return an error if host does not
 // contain DNS "CNAME" records, as long as host resolves to
 // address records.
-func (r *Resolver) LookupCNAME(ctx context.Context, host string) (cname string, err error) {
-	return r.lookupCNAME(ctx, host)
+//
+// The returned canonical name is validated to be a properly
+// formatted presentation-format domain name.
+func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error) {
+	cname, err := r.lookupCNAME(ctx, host)
+	if err != nil {
+		return "", err
+	}
+	if !isDomainName(cname) {
+		return "", &DNSError{Err: errMalformedDNSRecordsDetail, Name: host}
+	}
+	return cname, nil
 }
 
 // LookupSRV tries to resolve an SRV query of the given service,
@@ -416,8 +438,13 @@
 // That is, it looks up _service._proto.name. To accommodate services
 // publishing SRV records under non-standard names, if both service
 // and proto are empty strings, LookupSRV looks up name directly.
+//
+// The returned service names are validated to be properly
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the the remaining results, if any.
 func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
-	return DefaultResolver.lookupSRV(context.Background(), service, proto, name)
+	return DefaultResolver.LookupSRV(context.Background(), service, proto, name)
 }
 
 // LookupSRV tries to resolve an SRV query of the given service,
@@ -429,31 +456,121 @@
 // That is, it looks up _service._proto.name. To accommodate services
 // publishing SRV records under non-standard names, if both service
 // and proto are empty strings, LookupSRV looks up name directly.
-func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*SRV, err error) {
-	return r.lookupSRV(ctx, service, proto, name)
+//
+// The returned service names are validated to be properly
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the the remaining results, if any.
+func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
+	cname, addrs, err := r.lookupSRV(ctx, service, proto, name)
+	if err != nil {
+		return "", nil, err
+	}
+	if cname != "" && !isDomainName(cname) {
+		return "", nil, &DNSError{Err: "SRV header name is invalid", Name: name}
+	}
+	filteredAddrs := make([]*SRV, 0, len(addrs))
+	for _, addr := range addrs {
+		if addr == nil {
+			continue
+		}
+		if !isDomainName(addr.Target) {
+			continue
+		}
+		filteredAddrs = append(filteredAddrs, addr)
+	}
+	if len(addrs) != len(filteredAddrs) {
+		return cname, filteredAddrs, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
+	}
+	return cname, filteredAddrs, nil
 }
 
 // LookupMX returns the DNS MX records for the given domain name sorted by preference.
+//
+// The returned mail server names are validated to be properly
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the the remaining results, if any.
+//
+// LookupMX uses context.Background internally; to specify the context, use
+// Resolver.LookupMX.
 func LookupMX(name string) ([]*MX, error) {
-	return DefaultResolver.lookupMX(context.Background(), name)
+	return DefaultResolver.LookupMX(context.Background(), name)
 }
 
 // LookupMX returns the DNS MX records for the given domain name sorted by preference.
+//
+// The returned mail server names are validated to be properly
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the the remaining results, if any.
 func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) {
-	return r.lookupMX(ctx, name)
+	records, err := r.lookupMX(ctx, name)
+	if err != nil {
+		return nil, err
+	}
+	filteredMX := make([]*MX, 0, len(records))
+	for _, mx := range records {
+		if mx == nil {
+			continue
+		}
+		// Bypass the hostname validity check for targets which contain only a dot,
+		// as this is used to represent a 'Null' MX record.
+		if mx.Host != "." && !isDomainName(mx.Host) {
+			continue
+		}
+		filteredMX = append(filteredMX, mx)
+	}
+	if len(records) != len(filteredMX) {
+		return filteredMX, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
+	}
+	return filteredMX, nil
 }
 
 // LookupNS returns the DNS NS records for the given domain name.
+//
+// The returned name server names are validated to be properly
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the the remaining results, if any.
+//
+// LookupNS uses context.Background internally; to specify the context, use
+// Resolver.LookupNS.
 func LookupNS(name string) ([]*NS, error) {
-	return DefaultResolver.lookupNS(context.Background(), name)
+	return DefaultResolver.LookupNS(context.Background(), name)
 }
 
 // LookupNS returns the DNS NS records for the given domain name.
+//
+// The returned name server names are validated to be properly
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the the remaining results, if any.
 func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*NS, error) {
-	return r.lookupNS(ctx, name)
+	records, err := r.lookupNS(ctx, name)
+	if err != nil {
+		return nil, err
+	}
+	filteredNS := make([]*NS, 0, len(records))
+	for _, ns := range records {
+		if ns == nil {
+			continue
+		}
+		if !isDomainName(ns.Host) {
+			continue
+		}
+		filteredNS = append(filteredNS, ns)
+	}
+	if len(records) != len(filteredNS) {
+		return filteredNS, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
+	}
+	return filteredNS, nil
 }
 
 // LookupTXT returns the DNS TXT records for the given domain name.
+//
+// LookupTXT uses context.Background internally; to specify the context, use
+// Resolver.LookupTXT.
 func LookupTXT(name string) ([]string, error) {
 	return DefaultResolver.lookupTXT(context.Background(), name)
 }
@@ -466,14 +583,43 @@
 // LookupAddr performs a reverse lookup for the given address, returning a list
 // of names mapping to that address.
 //
+// The returned names are validated to be properly formatted presentation-format
+// domain names. If the response contains invalid names, those records are filtered
+// out and an error will be returned alongside the the remaining results, if any.
+//
 // When using the host C library resolver, at most one result will be
 // returned. To bypass the host resolver, use a custom Resolver.
+//
+// LookupAddr uses context.Background internally; to specify the context, use
+// Resolver.LookupAddr.
 func LookupAddr(addr string) (names []string, err error) {
-	return DefaultResolver.lookupAddr(context.Background(), addr)
+	return DefaultResolver.LookupAddr(context.Background(), addr)
 }
 
 // LookupAddr performs a reverse lookup for the given address, returning a list
 // of names mapping to that address.
-func (r *Resolver) LookupAddr(ctx context.Context, addr string) (names []string, err error) {
-	return r.lookupAddr(ctx, addr)
+//
+// The returned names are validated to be properly formatted presentation-format
+// domain names. If the response contains invalid names, those records are filtered
+// out and an error will be returned alongside the the remaining results, if any.
+func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error) {
+	names, err := r.lookupAddr(ctx, addr)
+	if err != nil {
+		return nil, err
+	}
+	filteredNames := make([]string, 0, len(names))
+	for _, name := range names {
+		if isDomainName(name) {
+			filteredNames = append(filteredNames, name)
+		}
+	}
+	if len(names) != len(filteredNames) {
+		return filteredNames, &DNSError{Err: errMalformedDNSRecordsDetail, Name: addr}
+	}
+	return filteredNames, nil
 }
+
+// errMalformedDNSRecordsDetail is the DNSError detail which is returned when a Resolver.Lookup...
+// method recieves DNS records which contain invalid DNS names. This may be returned alongside
+// results which have had the malformed records filtered out.
+var errMalformedDNSRecordsDetail = "DNS response contained records which contain invalid names"
diff --git a/src/net/lookup_fake.go b/src/net/lookup_fake.go
index 3b3c39b..f4fcaed 100644
--- a/src/net/lookup_fake.go
+++ b/src/net/lookup_fake.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package net
diff --git a/src/net/lookup_plan9.go b/src/net/lookup_plan9.go
index 6a2d48e..75c18b3 100644
--- a/src/net/lookup_plan9.go
+++ b/src/net/lookup_plan9.go
@@ -8,6 +8,7 @@
 	"context"
 	"errors"
 	"internal/bytealg"
+	"internal/itoa"
 	"io"
 	"os"
 )
@@ -84,7 +85,7 @@
 	if len(ip) != 0 && !ip.IsUnspecified() {
 		ips = ip.String()
 	}
-	lines, err := queryCS(ctx, net, ips, itoa(port))
+	lines, err := queryCS(ctx, net, ips, itoa.Itoa(port))
 	if err != nil {
 		return
 	}
@@ -308,7 +309,7 @@
 	}
 	for _, line := range lines {
 		if i := bytealg.IndexByteString(line, '\t'); i >= 0 {
-			txt = append(txt, absDomainName([]byte(line[i+1:])))
+			txt = append(txt, line[i+1:])
 		}
 	}
 	return
diff --git a/src/net/lookup_test.go b/src/net/lookup_test.go
index 32a0d37..3faaf00 100644
--- a/src/net/lookup_test.go
+++ b/src/net/lookup_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/lookup_unix.go b/src/net/lookup_unix.go
index 9055826..8030e3d 100644
--- a/src/net/lookup_unix.go
+++ b/src/net/lookup_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
@@ -89,7 +90,7 @@
 
 func (r *Resolver) lookupIP(ctx context.Context, network, host string) (addrs []IPAddr, err error) {
 	if r.preferGo() {
-		return r.goLookupIP(ctx, host)
+		return r.goLookupIP(ctx, network, host)
 	}
 	order := systemConf().hostLookupOrder(r, host)
 	if order == hostLookupCgo {
@@ -99,7 +100,7 @@
 		// cgo not available (or netgo); fall back to Go's DNS resolver
 		order = hostLookupFilesDNS
 	}
-	ips, _, err := r.goLookupIPCNAMEOrder(ctx, host, order)
+	ips, _, err := r.goLookupIPCNAMEOrder(ctx, network, host, order)
 	return ips, err
 }
 
diff --git a/src/net/lookup_windows_test.go b/src/net/lookup_windows_test.go
index 62b61ed..aa95501 100644
--- a/src/net/lookup_windows_test.go
+++ b/src/net/lookup_windows_test.go
@@ -299,7 +299,7 @@
 	ptr = make([]string, 0, 10)
 	rx := regexp.MustCompile(`(?m)^Pinging\s+([a-zA-Z0-9.\-]+)\s+\[.*$`)
 	for _, ans := range rx.FindAllStringSubmatch(r, -1) {
-		ptr = append(ptr, ans[1]+".")
+		ptr = append(ptr, absDomainName([]byte(ans[1])))
 	}
 	return
 }
diff --git a/src/net/main_cloexec_test.go b/src/net/main_cloexec_test.go
index 46b9ba5..742be2f 100644
--- a/src/net/main_cloexec_test.go
+++ b/src/net/main_cloexec_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || illumos || linux || netbsd || openbsd
 // +build dragonfly freebsd illumos linux netbsd openbsd
 
 package net
diff --git a/src/net/main_conf_test.go b/src/net/main_conf_test.go
index a92dff5..645b267 100644
--- a/src/net/main_conf_test.go
+++ b/src/net/main_conf_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js && !plan9 && !windows
 // +build !js,!plan9,!windows
 
 package net
diff --git a/src/net/main_noconf_test.go b/src/net/main_noconf_test.go
index bac84aa..bcea630 100644
--- a/src/net/main_noconf_test.go
+++ b/src/net/main_noconf_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (js && wasm) || plan9 || windows
 // +build js,wasm plan9 windows
 
 package net
diff --git a/src/net/main_posix_test.go b/src/net/main_posix_test.go
index f2484f3..c9ab25a 100644
--- a/src/net/main_posix_test.go
+++ b/src/net/main_posix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js && !plan9
 // +build !js,!plan9
 
 package net
diff --git a/src/net/main_test.go b/src/net/main_test.go
index 2d5be2e..dc17d3f 100644
--- a/src/net/main_test.go
+++ b/src/net/main_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/main_unix_test.go b/src/net/main_unix_test.go
index 8b98976..c8cff2d 100644
--- a/src/net/main_unix_test.go
+++ b/src/net/main_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/mockserver_test.go b/src/net/mockserver_test.go
index 867e31e..b50a1e5 100644
--- a/src/net/mockserver_test.go
+++ b/src/net/mockserver_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/net.go b/src/net/net.go
index 4b4ed12..a7c65ff 100644
--- a/src/net/net.go
+++ b/src/net/net.go
@@ -539,6 +539,9 @@
 
 func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
 
+func (e *ParseError) Timeout() bool   { return false }
+func (e *ParseError) Temporary() bool { return false }
+
 type AddrError struct {
 	Err  string
 	Addr string
@@ -642,7 +645,7 @@
 // another goroutine before the I/O is completed. This may be wrapped
 // in another error, and should normally be tested using
 // errors.Is(err, net.ErrClosed).
-var ErrClosed = errClosed
+var ErrClosed error = errClosed
 
 type writerOnly struct {
 	io.Writer
@@ -733,6 +736,7 @@
 			return
 		}
 		n -= ln0
+		(*v)[0] = nil
 		*v = (*v)[1:]
 	}
 }
diff --git a/src/net/net_fake.go b/src/net/net_fake.go
index 0c48dd5..74fc1da 100644
--- a/src/net/net_fake.go
+++ b/src/net/net_fake.go
@@ -4,6 +4,7 @@
 
 // Fake networking for js/wasm. It is intended to allow tests of other package to pass.
 
+//go:build js && wasm
 // +build js,wasm
 
 package net
@@ -267,7 +268,7 @@
 	return 0, nil, syscall.ENOSYS
 }
 
-func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
+func (fd *netFD) readMsg(p []byte, oob []byte, flags int) (n, oobn, retflags int, sa syscall.Sockaddr, err error) {
 	return 0, 0, 0, nil, syscall.ENOSYS
 }
 
diff --git a/src/net/net_test.go b/src/net/net_test.go
index 409e140..6e7be4d 100644
--- a/src/net/net_test.go
+++ b/src/net/net_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
@@ -587,3 +588,23 @@
 	}
 	withTCPConnPair(t, client, server)
 }
+
+// The various errors should implement the Error interface.
+func TestErrors(t *testing.T) {
+	var (
+		_ Error = &OpError{}
+		_ Error = &ParseError{}
+		_ Error = &AddrError{}
+		_ Error = UnknownNetworkError("")
+		_ Error = InvalidAddrError("")
+		_ Error = &timeoutError{}
+		_ Error = &DNSConfigError{}
+		_ Error = &DNSError{}
+	)
+
+	// ErrClosed was introduced as type error, so we can't check
+	// it using a declaration.
+	if _, ok := ErrClosed.(Error); !ok {
+		t.Fatal("ErrClosed does not implement Error")
+	}
+}
diff --git a/src/net/net_windows_test.go b/src/net/net_windows_test.go
index a000095..2a563a0 100644
--- a/src/net/net_windows_test.go
+++ b/src/net/net_windows_test.go
@@ -204,12 +204,17 @@
 	return removeUTF8BOM(out), nil
 }
 
-func netshSpeaksEnglish(t *testing.T) bool {
+func checkNetsh(t *testing.T) {
 	out, err := runCmd("netsh", "help")
 	if err != nil {
 		t.Fatal(err)
 	}
-	return bytes.Contains(out, []byte("The following commands are available:"))
+	if bytes.Contains(out, []byte("The following helper DLL cannot be loaded")) {
+		t.Skipf("powershell failure:\n%s", err)
+	}
+	if !bytes.Contains(out, []byte("The following commands are available:")) {
+		t.Skipf("powershell does not speak English:\n%s", out)
+	}
 }
 
 func netshInterfaceIPShowInterface(ipver string, ifaces map[string]bool) error {
@@ -256,9 +261,7 @@
 }
 
 func TestInterfacesWithNetsh(t *testing.T) {
-	if !netshSpeaksEnglish(t) {
-		t.Skip("English version of netsh required for this test")
-	}
+	checkNetsh(t)
 
 	toString := func(name string, isup bool) string {
 		if isup {
@@ -427,9 +430,7 @@
 }
 
 func TestInterfaceAddrsWithNetsh(t *testing.T) {
-	if !netshSpeaksEnglish(t) {
-		t.Skip("English version of netsh required for this test")
-	}
+	checkNetsh(t)
 
 	outIPV4, err := runCmd("netsh", "interface", "ipv4", "show", "address")
 	if err != nil {
diff --git a/src/net/netgo_unix_test.go b/src/net/netgo_unix_test.go
index c672d3e..5551e47 100644
--- a/src/net/netgo_unix_test.go
+++ b/src/net/netgo_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (!cgo || netgo) && (darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris)
 // +build !cgo netgo
 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
@@ -23,7 +24,7 @@
 	if err != nil {
 		t.Error(err)
 	}
-	if _, err := DefaultResolver.goLookupIP(ctx, host); err != nil {
+	if _, err := DefaultResolver.goLookupIP(ctx, "ip", host); err != nil {
 		t.Error(err)
 	}
 }
diff --git a/src/net/nss.go b/src/net/nss.go
index 96b9cdd..85177ca 100644
--- a/src/net/nss.go
+++ b/src/net/nss.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/nss_test.go b/src/net/nss_test.go
index 371deb5..4b73886 100644
--- a/src/net/nss_test.go
+++ b/src/net/nss_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/packetconn_test.go b/src/net/packetconn_test.go
index a377d33..aeb9845 100644
--- a/src/net/packetconn_test.go
+++ b/src/net/packetconn_test.go
@@ -5,6 +5,7 @@
 // This file implements API tests across platforms and will never have a build
 // tag.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/parse.go b/src/net/parse.go
index cdb35bb..6c230ab 100644
--- a/src/net/parse.go
+++ b/src/net/parse.go
@@ -172,32 +172,6 @@
 	return byte(n), ok && ei == 2
 }
 
-// Convert integer to decimal string.
-func itoa(val int) string {
-	if val < 0 {
-		return "-" + uitoa(uint(-val))
-	}
-	return uitoa(uint(val))
-}
-
-// Convert unsigned integer to decimal string.
-func uitoa(val uint) string {
-	if val == 0 { // avoid string allocation
-		return "0"
-	}
-	var buf [20]byte // big enough for 64bit value base 10
-	i := len(buf) - 1
-	for val >= 10 {
-		q := val / 10
-		buf[i] = byte('0' + val - q*10)
-		i--
-		val = q
-	}
-	// val < 10
-	buf[i] = byte('0' + val)
-	return string(buf[i:])
-}
-
 // Convert i to a hexadecimal string. Leading zeros are not printed.
 func appendHex(dst []byte, i uint32) []byte {
 	if i == 0 {
diff --git a/src/net/port_unix.go b/src/net/port_unix.go
index 4fdd9a3..a9a96a2 100644
--- a/src/net/port_unix.go
+++ b/src/net/port_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 // Read system port mappings from /etc/services
diff --git a/src/net/protoconn_test.go b/src/net/protoconn_test.go
index 6f83f52..fc9b386 100644
--- a/src/net/protoconn_test.go
+++ b/src/net/protoconn_test.go
@@ -5,6 +5,7 @@
 // This file implements API tests across platforms and will never have a build
 // tag.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/rawconn_stub_test.go b/src/net/rawconn_stub_test.go
index cec977f..975aa8d 100644
--- a/src/net/rawconn_stub_test.go
+++ b/src/net/rawconn_stub_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (js && wasm) || plan9
 // +build js,wasm plan9
 
 package net
diff --git a/src/net/rawconn_test.go b/src/net/rawconn_test.go
index a08ff89..3ef7af3 100644
--- a/src/net/rawconn_test.go
+++ b/src/net/rawconn_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/rawconn_unix_test.go b/src/net/rawconn_unix_test.go
index 0194ba6..75bbab8 100644
--- a/src/net/rawconn_unix_test.go
+++ b/src/net/rawconn_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/rpc/server.go b/src/net/rpc/server.go
index 9cb9282..074c5b9 100644
--- a/src/net/rpc/server.go
+++ b/src/net/rpc/server.go
@@ -283,7 +283,7 @@
 		mtype := method.Type
 		mname := method.Name
 		// Method must be exported.
-		if method.PkgPath != "" {
+		if !method.IsExported() {
 			continue
 		}
 		// Method needs three ins: receiver, *args, *reply.
diff --git a/src/net/sendfile_stub.go b/src/net/sendfile_stub.go
index 53bc53a..5753bc0 100644
--- a/src/net/sendfile_stub.go
+++ b/src/net/sendfile_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || (js && wasm) || netbsd || openbsd
 // +build aix darwin js,wasm netbsd openbsd
 
 package net
diff --git a/src/net/sendfile_test.go b/src/net/sendfile_test.go
index d6057fd..54e51fa 100644
--- a/src/net/sendfile_test.go
+++ b/src/net/sendfile_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
@@ -13,7 +14,6 @@
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"runtime"
 	"sync"
@@ -366,7 +366,7 @@
 	}
 	defer conn.Close()
 
-	n, err := io.Copy(ioutil.Discard, conn)
+	n, err := io.Copy(io.Discard, conn)
 	if err != nil {
 		t.Fatalf("expected nil error, but got %v", err)
 	}
diff --git a/src/net/sendfile_unix_alt.go b/src/net/sendfile_unix_alt.go
index 8cededc..54667d6 100644
--- a/src/net/sendfile_unix_alt.go
+++ b/src/net/sendfile_unix_alt.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || solaris
 // +build dragonfly freebsd solaris
 
 package net
diff --git a/src/net/server_test.go b/src/net/server_test.go
index 4ac5443..7cbf152 100644
--- a/src/net/server_test.go
+++ b/src/net/server_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
@@ -104,13 +105,6 @@
 					if perr := parseDialError(err); perr != nil {
 						t.Error(perr)
 					}
-					if tt.taddr == "::1" && os.Getenv("GO_BUILDER_NAME") == "darwin-amd64-10_12" && os.IsTimeout(err) {
-						// A suspected kernel bug in macOS 10.12 occasionally results in
-						// "i/o timeout" errors when dialing address ::1. The errors have not
-						// been observed on newer versions of the OS, so we don't plan to work
-						// around them. See https://golang.org/issue/32919.
-						t.Skipf("skipping due to error on known-flaky macOS 10.12 builder: %v", err)
-					}
 					t.Fatal(err)
 				}
 				defer c.Close()
diff --git a/src/net/sock_bsd.go b/src/net/sock_bsd.go
index 73fb6be..4c883ad 100644
--- a/src/net/sock_bsd.go
+++ b/src/net/sock_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 package net
diff --git a/src/net/sock_cloexec.go b/src/net/sock_cloexec.go
index 5f345f0..6861c4b 100644
--- a/src/net/sock_cloexec.go
+++ b/src/net/sock_cloexec.go
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This file implements sysSocket and accept for platforms that
-// provide a fast path for setting SetNonblock and CloseOnExec.
+// This file implements sysSocket for platforms that provide a fast path for
+// setting SetNonblock and CloseOnExec.
 
+//go:build dragonfly || freebsd || illumos || linux || netbsd || openbsd
 // +build dragonfly freebsd illumos linux netbsd openbsd
 
 package net
diff --git a/src/net/sock_posix.go b/src/net/sock_posix.go
index 80b4169..9b1e788 100644
--- a/src/net/sock_posix.go
+++ b/src/net/sock_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package net
diff --git a/src/net/sock_stub.go b/src/net/sock_stub.go
index c9f86af..d804bfa 100644
--- a/src/net/sock_stub.go
+++ b/src/net/sock_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || (js && wasm) || solaris
 // +build aix js,wasm solaris
 
 package net
diff --git a/src/net/sockaddr_posix.go b/src/net/sockaddr_posix.go
index a3710dd..9d77cb5 100644
--- a/src/net/sockaddr_posix.go
+++ b/src/net/sockaddr_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package net
diff --git a/src/net/sockopt_bsd.go b/src/net/sockopt_bsd.go
index 8fd1e88..ee1f98b 100644
--- a/src/net/sockopt_bsd.go
+++ b/src/net/sockopt_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 package net
@@ -25,7 +26,7 @@
 			syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_PORTRANGE, syscall.IPV6_PORTRANGE_HIGH)
 		}
 	}
-	if supportsIPv4map() && family == syscall.AF_INET6 && sotype != syscall.SOCK_RAW {
+	if family == syscall.AF_INET6 && sotype != syscall.SOCK_RAW && supportsIPv4map() {
 		// Allow both IP versions even if the OS default
 		// is otherwise. Note that some operating systems
 		// never admit this option.
diff --git a/src/net/sockopt_posix.go b/src/net/sockopt_posix.go
index de72556..50b9bfa 100644
--- a/src/net/sockopt_posix.go
+++ b/src/net/sockopt_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package net
diff --git a/src/net/sockopt_stub.go b/src/net/sockopt_stub.go
index 52624a3..99b5277 100644
--- a/src/net/sockopt_stub.go
+++ b/src/net/sockopt_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package net
diff --git a/src/net/sockoptip_bsdvar.go b/src/net/sockoptip_bsdvar.go
index 20a6dc9..56022fd 100644
--- a/src/net/sockoptip_bsdvar.go
+++ b/src/net/sockoptip_bsdvar.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd netbsd openbsd solaris
 
 package net
diff --git a/src/net/sockoptip_posix.go b/src/net/sockoptip_posix.go
index b14963f..a2143ae 100644
--- a/src/net/sockoptip_posix.go
+++ b/src/net/sockoptip_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
 // +build aix 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 57cd289..4175922 100644
--- a/src/net/sockoptip_stub.go
+++ b/src/net/sockoptip_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package net
diff --git a/src/net/splice_stub.go b/src/net/splice_stub.go
index 9106cb2..ce2e904 100644
--- a/src/net/splice_stub.go
+++ b/src/net/splice_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !linux
 // +build !linux
 
 package net
diff --git a/src/net/splice_test.go b/src/net/splice_test.go
index 8a0cda6..be13cc9 100644
--- a/src/net/splice_test.go
+++ b/src/net/splice_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux
 // +build linux
 
 package net
diff --git a/src/net/sys_cloexec.go b/src/net/sys_cloexec.go
index 967b8be..a32483e 100644
--- a/src/net/sys_cloexec.go
+++ b/src/net/sys_cloexec.go
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This file implements sysSocket and accept for platforms that do not
-// provide a fast path for setting SetNonblock and CloseOnExec.
+// This file implements sysSocket for platforms that do not provide a fast path
+// for setting SetNonblock and CloseOnExec.
 
+//go:build aix || darwin || (solaris && !illumos)
 // +build aix darwin solaris,!illumos
 
 package net
diff --git a/src/net/tcpsock.go b/src/net/tcpsock.go
index 9a9b03a..19a9014 100644
--- a/src/net/tcpsock.go
+++ b/src/net/tcpsock.go
@@ -6,6 +6,7 @@
 
 import (
 	"context"
+	"internal/itoa"
 	"io"
 	"os"
 	"syscall"
@@ -31,9 +32,9 @@
 	}
 	ip := ipEmptyString(a.IP)
 	if a.Zone != "" {
-		return JoinHostPort(ip+"%"+a.Zone, itoa(a.Port))
+		return JoinHostPort(ip+"%"+a.Zone, itoa.Itoa(a.Port))
 	}
-	return JoinHostPort(ip, itoa(a.Port))
+	return JoinHostPort(ip, itoa.Itoa(a.Port))
 }
 
 func (a *TCPAddr) isWildcard() bool {
diff --git a/src/net/tcpsock_posix.go b/src/net/tcpsock_posix.go
index 257c119..7c4523c 100644
--- a/src/net/tcpsock_posix.go
+++ b/src/net/tcpsock_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package net
diff --git a/src/net/tcpsock_test.go b/src/net/tcpsock_test.go
index d6172bc..9c9f1ea 100644
--- a/src/net/tcpsock_test.go
+++ b/src/net/tcpsock_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/tcpsock_unix_test.go b/src/net/tcpsock_unix_test.go
index 2bd591b..41bd229 100644
--- a/src/net/tcpsock_unix_test.go
+++ b/src/net/tcpsock_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js && !plan9 && !windows
 // +build !js,!plan9,!windows
 
 package net
diff --git a/src/net/tcpsockopt_plan9.go b/src/net/tcpsockopt_plan9.go
index fb56871..264359d 100644
--- a/src/net/tcpsockopt_plan9.go
+++ b/src/net/tcpsockopt_plan9.go
@@ -7,6 +7,7 @@
 package net
 
 import (
+	"internal/itoa"
 	"syscall"
 	"time"
 )
@@ -17,7 +18,7 @@
 
 // Set keep alive period.
 func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
-	cmd := "keepalive " + itoa(int(d/time.Millisecond))
+	cmd := "keepalive " + itoa.Itoa(int(d/time.Millisecond))
 	_, e := fd.ctl.WriteAt([]byte(cmd), 0)
 	return e
 }
diff --git a/src/net/tcpsockopt_posix.go b/src/net/tcpsockopt_posix.go
index 5e00ba1..d08832a 100644
--- a/src/net/tcpsockopt_posix.go
+++ b/src/net/tcpsockopt_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package net
diff --git a/src/net/tcpsockopt_stub.go b/src/net/tcpsockopt_stub.go
index d043da1..028d5fd 100644
--- a/src/net/tcpsockopt_stub.go
+++ b/src/net/tcpsockopt_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package net
diff --git a/src/net/tcpsockopt_unix.go b/src/net/tcpsockopt_unix.go
index fb0ecb8..a945889 100644
--- a/src/net/tcpsockopt_unix.go
+++ b/src/net/tcpsockopt_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || freebsd || linux || netbsd
 // +build aix freebsd linux netbsd
 
 package net
diff --git a/src/net/testdata/ipv4-hosts b/src/net/testdata/ipv4-hosts
index 5208bb4..6b99675 100644
--- a/src/net/testdata/ipv4-hosts
+++ b/src/net/testdata/ipv4-hosts
@@ -1,12 +1,8 @@
 # See https://tools.ietf.org/html/rfc1123.
-#
-# The literal IPv4 address parser in the net package is a relaxed
-# one. It may accept a literal IPv4 address in dotted-decimal notation
-# with leading zeros such as "001.2.003.4".
 
 # internet address and host name
 127.0.0.1	localhost	# inline comment separated by tab
-127.000.000.002	localhost       # inline comment separated by space
+127.0.0.2	localhost   # inline comment separated by space
 
 # internet address, host name and aliases
-127.000.000.003	localhost	localhost.localdomain
+127.0.0.3	localhost	localhost.localdomain
diff --git a/src/net/timeout_test.go b/src/net/timeout_test.go
index 205aaa4..e1cf146 100644
--- a/src/net/timeout_test.go
+++ b/src/net/timeout_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/udpsock.go b/src/net/udpsock.go
index 571e099..70f2ce2 100644
--- a/src/net/udpsock.go
+++ b/src/net/udpsock.go
@@ -6,6 +6,7 @@
 
 import (
 	"context"
+	"internal/itoa"
 	"syscall"
 )
 
@@ -34,9 +35,9 @@
 	}
 	ip := ipEmptyString(a.IP)
 	if a.Zone != "" {
-		return JoinHostPort(ip+"%"+a.Zone, itoa(a.Port))
+		return JoinHostPort(ip+"%"+a.Zone, itoa.Itoa(a.Port))
 	}
-	return JoinHostPort(ip, itoa(a.Port))
+	return JoinHostPort(ip, itoa.Itoa(a.Port))
 }
 
 func (a *UDPAddr) isWildcard() bool {
@@ -99,11 +100,20 @@
 }
 
 // ReadFromUDP acts like ReadFrom but returns a UDPAddr.
-func (c *UDPConn) ReadFromUDP(b []byte) (int, *UDPAddr, error) {
+func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) {
+	// This function is designed to allow the caller to control the lifetime
+	// of the returned *UDPAddr and thereby prevent an allocation.
+	// See https://blog.filippo.io/efficient-go-apis-with-the-inliner/.
+	// The real work is done by readFromUDP, below.
+	return c.readFromUDP(b, &UDPAddr{})
+}
+
+// readFromUDP implements ReadFromUDP.
+func (c *UDPConn) readFromUDP(b []byte, addr *UDPAddr) (int, *UDPAddr, error) {
 	if !c.ok() {
 		return 0, nil, syscall.EINVAL
 	}
-	n, addr, err := c.readFrom(b)
+	n, addr, err := c.readFrom(b, addr)
 	if err != nil {
 		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
 	}
@@ -112,14 +122,9 @@
 
 // ReadFrom implements the PacketConn ReadFrom method.
 func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) {
-	if !c.ok() {
-		return 0, nil, syscall.EINVAL
-	}
-	n, addr, err := c.readFrom(b)
-	if err != nil {
-		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
-	}
+	n, addr, err := c.readFromUDP(b, &UDPAddr{})
 	if addr == nil {
+		// Return Addr(nil), not Addr(*UDPConn(nil)).
 		return n, nil, err
 	}
 	return n, addr, err
diff --git a/src/net/udpsock_plan9.go b/src/net/udpsock_plan9.go
index 79986ce..1df293d 100644
--- a/src/net/udpsock_plan9.go
+++ b/src/net/udpsock_plan9.go
@@ -11,7 +11,7 @@
 	"syscall"
 )
 
-func (c *UDPConn) readFrom(b []byte) (n int, addr *UDPAddr, err error) {
+func (c *UDPConn) readFrom(b []byte, addr *UDPAddr) (int, *UDPAddr, error) {
 	buf := make([]byte, udpHeaderSize+len(b))
 	m, err := c.fd.Read(buf)
 	if err != nil {
@@ -23,8 +23,9 @@
 	buf = buf[:m]
 
 	h, buf := unmarshalUDPHeader(buf)
-	n = copy(b, buf)
-	return n, &UDPAddr{IP: h.raddr, Port: int(h.rport)}, nil
+	n := copy(b, buf)
+	*addr = UDPAddr{IP: h.raddr, Port: int(h.rport)}
+	return n, addr, nil
 }
 
 func (c *UDPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
diff --git a/src/net/udpsock_posix.go b/src/net/udpsock_posix.go
index bbfa4ed..96fb373 100644
--- a/src/net/udpsock_posix.go
+++ b/src/net/udpsock_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package net
@@ -42,21 +43,23 @@
 	return &UDPAddr{loopbackIP(net), a.Port, a.Zone}
 }
 
-func (c *UDPConn) readFrom(b []byte) (int, *UDPAddr, error) {
-	var addr *UDPAddr
+func (c *UDPConn) readFrom(b []byte, addr *UDPAddr) (int, *UDPAddr, error) {
 	n, sa, err := c.fd.readFrom(b)
 	switch sa := sa.(type) {
 	case *syscall.SockaddrInet4:
-		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
+		*addr = UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
 	case *syscall.SockaddrInet6:
-		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneCache.name(int(sa.ZoneId))}
+		*addr = UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneCache.name(int(sa.ZoneId))}
+	default:
+		// No sockaddr, so don't return UDPAddr.
+		addr = nil
 	}
 	return n, addr, err
 }
 
 func (c *UDPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
 	var sa syscall.Sockaddr
-	n, oobn, flags, sa, err = c.fd.readMsg(b, oob)
+	n, oobn, flags, sa, err = c.fd.readMsg(b, oob, 0)
 	switch sa := sa.(type) {
 	case *syscall.SockaddrInet4:
 		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
diff --git a/src/net/udpsock_test.go b/src/net/udpsock_test.go
index 327eba6..0e8c351 100644
--- a/src/net/udpsock_test.go
+++ b/src/net/udpsock_test.go
@@ -2,12 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
 
 import (
+	"errors"
 	"internal/testenv"
+	"os"
 	"reflect"
 	"runtime"
 	"testing"
@@ -444,3 +447,51 @@
 		}
 	}
 }
+
+// TestUDPReadTimeout verifies that ReadFromUDP with timeout returns an error
+// without data or an address.
+func TestUDPReadTimeout(t *testing.T) {
+	la, err := ResolveUDPAddr("udp4", "127.0.0.1:0")
+	if err != nil {
+		t.Fatal(err)
+	}
+	c, err := ListenUDP("udp4", la)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	c.SetDeadline(time.Now())
+	b := make([]byte, 1)
+	n, addr, err := c.ReadFromUDP(b)
+	if !errors.Is(err, os.ErrDeadlineExceeded) {
+		t.Errorf("ReadFromUDP got err %v want os.ErrDeadlineExceeded", err)
+	}
+	if n != 0 {
+		t.Errorf("ReadFromUDP got n %d want 0", n)
+	}
+	if addr != nil {
+		t.Errorf("ReadFromUDP got addr %+#v want nil", addr)
+	}
+}
+
+func BenchmarkWriteToReadFromUDP(b *testing.B) {
+	conn, err := ListenUDP("udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)})
+	if err != nil {
+		b.Fatal(err)
+	}
+	addr := conn.LocalAddr()
+	buf := make([]byte, 8)
+	b.ResetTimer()
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		_, err := conn.WriteTo(buf, addr)
+		if err != nil {
+			b.Fatal(err)
+		}
+		_, _, err = conn.ReadFromUDP(buf)
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}
diff --git a/src/net/unixsock_posix.go b/src/net/unixsock_posix.go
index 275c7c9..99a89c8 100644
--- a/src/net/unixsock_posix.go
+++ b/src/net/unixsock_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package net
@@ -112,7 +113,11 @@
 
 func (c *UnixConn) readMsg(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
 	var sa syscall.Sockaddr
-	n, oobn, flags, sa, err = c.fd.readMsg(b, oob)
+	n, oobn, flags, sa, err = c.fd.readMsg(b, oob, readMsgFlags)
+	if readMsgFlags == 0 && err == nil && oobn > 0 {
+		setReadMsgCloseOnExec(oob[:oobn])
+	}
+
 	switch sa := sa.(type) {
 	case *syscall.SockaddrUnix:
 		if sa.Name != "" {
diff --git a/src/net/unixsock_readmsg_cloexec.go b/src/net/unixsock_readmsg_cloexec.go
new file mode 100644
index 0000000..716484c
--- /dev/null
+++ b/src/net/unixsock_readmsg_cloexec.go
@@ -0,0 +1,31 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || freebsd || solaris
+// +build aix darwin freebsd solaris
+
+package net
+
+import "syscall"
+
+const readMsgFlags = 0
+
+func setReadMsgCloseOnExec(oob []byte) {
+	scms, err := syscall.ParseSocketControlMessage(oob)
+	if err != nil {
+		return
+	}
+
+	for _, scm := range scms {
+		if scm.Header.Level == syscall.SOL_SOCKET && scm.Header.Type == syscall.SCM_RIGHTS {
+			fds, err := syscall.ParseUnixRights(&scm)
+			if err != nil {
+				continue
+			}
+			for _, fd := range fds {
+				syscall.CloseOnExec(fd)
+			}
+		}
+	}
+}
diff --git a/src/net/unixsock_readmsg_cmsg_cloexec.go b/src/net/unixsock_readmsg_cmsg_cloexec.go
new file mode 100644
index 0000000..bb851b8
--- /dev/null
+++ b/src/net/unixsock_readmsg_cmsg_cloexec.go
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build dragonfly || linux || netbsd || openbsd
+// +build dragonfly linux netbsd openbsd
+
+package net
+
+import "syscall"
+
+const readMsgFlags = syscall.MSG_CMSG_CLOEXEC
+
+func setReadMsgCloseOnExec(oob []byte) {}
diff --git a/src/net/unixsock_readmsg_other.go b/src/net/unixsock_readmsg_other.go
new file mode 100644
index 0000000..3290761
--- /dev/null
+++ b/src/net/unixsock_readmsg_other.go
@@ -0,0 +1,12 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (js && wasm) || windows
+// +build js,wasm windows
+
+package net
+
+const readMsgFlags = 0
+
+func setReadMsgCloseOnExec(oob []byte) {}
diff --git a/src/net/unixsock_readmsg_test.go b/src/net/unixsock_readmsg_test.go
new file mode 100644
index 0000000..a4d2fca
--- /dev/null
+++ b/src/net/unixsock_readmsg_test.go
@@ -0,0 +1,105 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package net
+
+import (
+	"os"
+	"syscall"
+	"testing"
+	"time"
+)
+
+func TestUnixConnReadMsgUnixSCMRightsCloseOnExec(t *testing.T) {
+	if !testableNetwork("unix") {
+		t.Skip("not unix system")
+	}
+
+	scmFile, err := os.Open(os.DevNull)
+	if err != nil {
+		t.Fatalf("file open: %v", err)
+	}
+	defer scmFile.Close()
+
+	rights := syscall.UnixRights(int(scmFile.Fd()))
+	fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
+	if err != nil {
+		t.Fatalf("Socketpair: %v", err)
+	}
+
+	writeFile := os.NewFile(uintptr(fds[0]), "write-socket")
+	defer writeFile.Close()
+	readFile := os.NewFile(uintptr(fds[1]), "read-socket")
+	defer readFile.Close()
+
+	cw, err := FileConn(writeFile)
+	if err != nil {
+		t.Fatalf("FileConn: %v", err)
+	}
+	defer cw.Close()
+	cr, err := FileConn(readFile)
+	if err != nil {
+		t.Fatalf("FileConn: %v", err)
+	}
+	defer cr.Close()
+
+	ucw, ok := cw.(*UnixConn)
+	if !ok {
+		t.Fatalf("got %T; want UnixConn", cw)
+	}
+	ucr, ok := cr.(*UnixConn)
+	if !ok {
+		t.Fatalf("got %T; want UnixConn", cr)
+	}
+
+	oob := make([]byte, syscall.CmsgSpace(4))
+	err = ucw.SetWriteDeadline(time.Now().Add(5 * time.Second))
+	if err != nil {
+		t.Fatalf("Can't set unix connection timeout: %v", err)
+	}
+	_, _, err = ucw.WriteMsgUnix(nil, rights, nil)
+	if err != nil {
+		t.Fatalf("UnixConn readMsg: %v", err)
+	}
+	err = ucr.SetReadDeadline(time.Now().Add(5 * time.Second))
+	if err != nil {
+		t.Fatalf("Can't set unix connection timeout: %v", err)
+	}
+	_, oobn, _, _, err := ucr.ReadMsgUnix(nil, oob)
+	if err != nil {
+		t.Fatalf("UnixConn readMsg: %v", err)
+	}
+
+	scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
+	if err != nil {
+		t.Fatalf("ParseSocketControlMessage: %v", err)
+	}
+	if len(scms) != 1 {
+		t.Fatalf("got scms = %#v; expected 1 SocketControlMessage", scms)
+	}
+	scm := scms[0]
+	gotFDs, err := syscall.ParseUnixRights(&scm)
+	if err != nil {
+		t.Fatalf("syscall.ParseUnixRights: %v", err)
+	}
+	if len(gotFDs) != 1 {
+		t.Fatalf("got FDs %#v: wanted only 1 fd", gotFDs)
+	}
+	defer func() {
+		if err := syscall.Close(gotFDs[0]); err != nil {
+			t.Fatalf("fail to close gotFDs: %v", err)
+		}
+	}()
+
+	flags, err := fcntl(gotFDs[0], syscall.F_GETFD, 0)
+	if err != nil {
+		t.Fatalf("Can't get flags of fd:%#v, with err:%v", gotFDs[0], err)
+	}
+	if flags&syscall.FD_CLOEXEC == 0 {
+		t.Fatalf("got flags %#x, want %#x (FD_CLOEXEC) set", flags, syscall.FD_CLOEXEC)
+	}
+}
diff --git a/src/net/unixsock_test.go b/src/net/unixsock_test.go
index 0b13bf6..71092e8 100644
--- a/src/net/unixsock_test.go
+++ b/src/net/unixsock_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js && !plan9 && !windows
 // +build !js,!plan9,!windows
 
 package net
diff --git a/src/net/unixsock_windows_test.go b/src/net/unixsock_windows_test.go
index 5dccc14..29244f6 100644
--- a/src/net/unixsock_windows_test.go
+++ b/src/net/unixsock_windows_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build windows
 // +build windows
 
 package net
diff --git a/src/net/url/example_test.go b/src/net/url/example_test.go
index cb9e892..476132a 100644
--- a/src/net/url/example_test.go
+++ b/src/net/url/example_test.go
@@ -72,13 +72,13 @@
 }
 
 func ExampleParseQuery() {
-	m, err := url.ParseQuery(`x=1&y=2&y=3;z`)
+	m, err := url.ParseQuery(`x=1&y=2&y=3`)
 	if err != nil {
 		log.Fatal(err)
 	}
 	fmt.Println(toJSON(m))
 	// Output:
-	// {"x":["1"], "y":["2", "3"], "z":[""]}
+	// {"x":["1"], "y":["2", "3"]}
 }
 
 func ExampleURL_EscapedPath() {
diff --git a/src/net/url/url.go b/src/net/url/url.go
index d90f5f0..20de0f6 100644
--- a/src/net/url/url.go
+++ b/src/net/url/url.go
@@ -425,31 +425,31 @@
 	return s
 }
 
-// Maybe rawurl is of the form scheme:path.
+// Maybe rawURL is of the form scheme:path.
 // (Scheme must be [a-zA-Z][a-zA-Z0-9+-.]*)
-// If so, return scheme, path; else return "", rawurl.
-func getscheme(rawurl string) (scheme, path string, err error) {
-	for i := 0; i < len(rawurl); i++ {
-		c := rawurl[i]
+// If so, return scheme, path; else return "", rawURL.
+func getScheme(rawURL string) (scheme, path string, err error) {
+	for i := 0; i < len(rawURL); i++ {
+		c := rawURL[i]
 		switch {
 		case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
 		// do nothing
 		case '0' <= c && c <= '9' || c == '+' || c == '-' || c == '.':
 			if i == 0 {
-				return "", rawurl, nil
+				return "", rawURL, nil
 			}
 		case c == ':':
 			if i == 0 {
 				return "", "", errors.New("missing protocol scheme")
 			}
-			return rawurl[:i], rawurl[i+1:], nil
+			return rawURL[:i], rawURL[i+1:], nil
 		default:
 			// we have encountered an invalid character,
 			// so there is no valid scheme
-			return "", rawurl, nil
+			return "", rawURL, nil
 		}
 	}
-	return "", rawurl, nil
+	return "", rawURL, nil
 }
 
 // split slices s into two substrings separated by the first occurrence of
@@ -466,15 +466,15 @@
 	return s[:i], s[i:]
 }
 
-// Parse parses rawurl into a URL structure.
+// Parse parses a raw url into a URL structure.
 //
-// The rawurl may be relative (a path, without a host) or absolute
+// The url 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) {
+func Parse(rawURL string) (*URL, error) {
 	// Cut off #frag
-	u, frag := split(rawurl, '#', true)
+	u, frag := split(rawURL, '#', true)
 	url, err := parse(u, false)
 	if err != nil {
 		return nil, &Error{"parse", u, err}
@@ -483,20 +483,20 @@
 		return url, nil
 	}
 	if err = url.setFragment(frag); err != nil {
-		return nil, &Error{"parse", rawurl, err}
+		return nil, &Error{"parse", rawURL, err}
 	}
 	return url, nil
 }
 
-// ParseRequestURI parses rawurl into a URL structure. It assumes that
-// rawurl was received in an HTTP request, so the rawurl is interpreted
+// ParseRequestURI parses a raw url into a URL structure. It assumes that
+// url was received in an HTTP request, so the url is interpreted
 // only as an absolute URI or an absolute path.
-// The string rawurl is assumed not to have a #fragment suffix.
+// The string url is assumed not to have a #fragment suffix.
 // (Web browsers strip #fragment before sending the URL to a web server.)
-func ParseRequestURI(rawurl string) (*URL, error) {
-	url, err := parse(rawurl, true)
+func ParseRequestURI(rawURL string) (*URL, error) {
+	url, err := parse(rawURL, true)
 	if err != nil {
-		return nil, &Error{"parse", rawurl, err}
+		return nil, &Error{"parse", rawURL, err}
 	}
 	return url, nil
 }
@@ -505,27 +505,27 @@
 // viaRequest is true, the URL is assumed to have arrived via an HTTP request,
 // in which case only absolute URLs or path-absolute relative URLs are allowed.
 // If viaRequest is false, all forms of relative URLs are allowed.
-func parse(rawurl string, viaRequest bool) (*URL, error) {
+func parse(rawURL string, viaRequest bool) (*URL, error) {
 	var rest string
 	var err error
 
-	if stringContainsCTLByte(rawurl) {
+	if stringContainsCTLByte(rawURL) {
 		return nil, errors.New("net/url: invalid control character in URL")
 	}
 
-	if rawurl == "" && viaRequest {
+	if rawURL == "" && viaRequest {
 		return nil, errors.New("empty url")
 	}
 	url := new(URL)
 
-	if rawurl == "*" {
+	if rawURL == "*" {
 		url.Path = "*"
 		return url, nil
 	}
 
 	// Split off possible leading "http:", "mailto:", etc.
 	// Cannot contain escaped characters.
-	if url.Scheme, rest, err = getscheme(rawurl); err != nil {
+	if url.Scheme, rest, err = getScheme(rawURL); err != nil {
 		return nil, err
 	}
 	url.Scheme = strings.ToLower(url.Scheme)
@@ -909,15 +909,22 @@
 	delete(v, key)
 }
 
+// Has checks whether a given key is set.
+func (v Values) Has(key string) bool {
+	_, ok := v[key]
+	return ok
+}
+
 // ParseQuery parses the URL-encoded query string and returns
 // a map listing the values specified for each key.
 // ParseQuery always returns a non-nil map containing all the
 // valid query parameters found; err describes the first decoding error
 // encountered, if any.
 //
-// Query is expected to be a list of key=value settings separated by
-// ampersands or semicolons. A setting without an equals sign is
-// interpreted as a key set to an empty value.
+// Query is expected to be a list of key=value settings separated by ampersands.
+// A setting without an equals sign is interpreted as a key set to an empty
+// value.
+// Settings containing a non-URL-encoded semicolon are considered invalid.
 func ParseQuery(query string) (Values, error) {
 	m := make(Values)
 	err := parseQuery(m, query)
@@ -927,11 +934,15 @@
 func parseQuery(m Values, query string) (err error) {
 	for query != "" {
 		key := query
-		if i := strings.IndexAny(key, "&;"); i >= 0 {
+		if i := strings.IndexAny(key, "&"); i >= 0 {
 			key, query = key[:i], key[i+1:]
 		} else {
 			query = ""
 		}
+		if strings.Contains(key, ";") {
+			err = fmt.Errorf("invalid semicolon separator in query")
+			continue
+		}
 		if key == "" {
 			continue
 		}
@@ -1009,6 +1020,8 @@
 	)
 	first := true
 	remaining := full
+	// We want to return a leading '/', so write it now.
+	dst.WriteByte('/')
 	for i >= 0 {
 		i = strings.IndexByte(remaining, '/')
 		if i < 0 {
@@ -1023,10 +1036,12 @@
 		}
 
 		if elem == ".." {
-			str := dst.String()
+			// Ignore the leading '/' we already wrote.
+			str := dst.String()[1:]
 			index := strings.LastIndexByte(str, '/')
 
 			dst.Reset()
+			dst.WriteByte('/')
 			if index == -1 {
 				first = true
 			} else {
@@ -1045,7 +1060,12 @@
 		dst.WriteByte('/')
 	}
 
-	return "/" + strings.TrimPrefix(dst.String(), "/")
+	// We wrote an initial '/', but we don't want two.
+	r := dst.String()
+	if len(r) > 1 && r[1] == '/' {
+		r = r[1:]
+	}
+	return r
 }
 
 // IsAbs reports whether the URL is absolute.
@@ -1058,11 +1078,11 @@
 // may be relative or absolute. Parse returns nil, err on parse
 // failure, otherwise its return value is the same as ResolveReference.
 func (u *URL) Parse(ref string) (*URL, error) {
-	refurl, err := Parse(ref)
+	refURL, err := Parse(ref)
 	if err != nil {
 		return nil, err
 	}
-	return u.ResolveReference(refurl), nil
+	return u.ResolveReference(refURL), nil
 }
 
 // ResolveReference resolves a URI reference to an absolute URI from
@@ -1151,8 +1171,8 @@
 // splitHostPort separates host and port. If the port is not valid, it returns
 // the entire input as host, and it doesn't check the validity of the host.
 // Unlike net.SplitHostPort, but per RFC 3986, it requires ports to be numeric.
-func splitHostPort(hostport string) (host, port string) {
-	host = hostport
+func splitHostPort(hostPort string) (host, port string) {
+	host = hostPort
 
 	colon := strings.LastIndexByte(host, ':')
 	if colon != -1 && validOptionalPort(host[colon:]) {
diff --git a/src/net/url/url_test.go b/src/net/url/url_test.go
index f02e465..63c8e69 100644
--- a/src/net/url/url_test.go
+++ b/src/net/url/url_test.go
@@ -1295,10 +1295,10 @@
 }
 
 func TestQueryValues(t *testing.T) {
-	u, _ := Parse("http://x.com?foo=bar&bar=1&bar=2")
+	u, _ := Parse("http://x.com?foo=bar&bar=1&bar=2&baz")
 	v := u.Query()
-	if len(v) != 2 {
-		t.Errorf("got %d keys in Query values, want 2", len(v))
+	if len(v) != 3 {
+		t.Errorf("got %d keys in Query values, want 3", len(v))
 	}
 	if g, e := v.Get("foo"), "bar"; g != e {
 		t.Errorf("Get(foo) = %q, want %q", g, e)
@@ -1313,6 +1313,18 @@
 	if g, e := v.Get("baz"), ""; g != e {
 		t.Errorf("Get(baz) = %q, want %q", g, e)
 	}
+	if h, e := v.Has("foo"), true; h != e {
+		t.Errorf("Has(foo) = %t, want %t", h, e)
+	}
+	if h, e := v.Has("bar"), true; h != e {
+		t.Errorf("Has(bar) = %t, want %t", h, e)
+	}
+	if h, e := v.Has("baz"), true; h != e {
+		t.Errorf("Has(baz) = %t, want %t", h, e)
+	}
+	if h, e := v.Has("noexist"), false; h != e {
+		t.Errorf("Has(noexist) = %t, want %t", h, e)
+	}
 	v.Del("bar")
 	if g, e := v.Get("bar"), ""; g != e {
 		t.Errorf("second Get(bar) = %q, want %q", g, e)
@@ -1322,57 +1334,125 @@
 type parseTest struct {
 	query string
 	out   Values
+	ok    bool
 }
 
 var parseTests = []parseTest{
 	{
+		query: "a=1",
+		out:   Values{"a": []string{"1"}},
+		ok:    true,
+	},
+	{
 		query: "a=1&b=2",
 		out:   Values{"a": []string{"1"}, "b": []string{"2"}},
+		ok:    true,
 	},
 	{
 		query: "a=1&a=2&a=banana",
 		out:   Values{"a": []string{"1", "2", "banana"}},
+		ok:    true,
 	},
 	{
 		query: "ascii=%3Ckey%3A+0x90%3E",
 		out:   Values{"ascii": []string{"<key: 0x90>"}},
+		ok:    true,
+	}, {
+		query: "a=1;b=2",
+		out:   Values{},
+		ok:    false,
+	}, {
+		query: "a;b=1",
+		out:   Values{},
+		ok:    false,
+	}, {
+		query: "a=%3B", // hex encoding for semicolon
+		out:   Values{"a": []string{";"}},
+		ok:    true,
 	},
 	{
-		query: "a=1;b=2",
-		out:   Values{"a": []string{"1"}, "b": []string{"2"}},
+		query: "a%3Bb=1",
+		out:   Values{"a;b": []string{"1"}},
+		ok:    true,
 	},
 	{
 		query: "a=1&a=2;a=banana",
-		out:   Values{"a": []string{"1", "2", "banana"}},
+		out:   Values{"a": []string{"1"}},
+		ok:    false,
+	},
+	{
+		query: "a;b&c=1",
+		out:   Values{"c": []string{"1"}},
+		ok:    false,
+	},
+	{
+		query: "a=1&b=2;a=3&c=4",
+		out:   Values{"a": []string{"1"}, "c": []string{"4"}},
+		ok:    false,
+	},
+	{
+		query: "a=1&b=2;c=3",
+		out:   Values{"a": []string{"1"}},
+		ok:    false,
+	},
+	{
+		query: ";",
+		out:   Values{},
+		ok:    false,
+	},
+	{
+		query: "a=1;",
+		out:   Values{},
+		ok:    false,
+	},
+	{
+		query: "a=1&;",
+		out:   Values{"a": []string{"1"}},
+		ok:    false,
+	},
+	{
+		query: ";a=1&b=2",
+		out:   Values{"b": []string{"2"}},
+		ok:    false,
+	},
+	{
+		query: "a=1&b=2;",
+		out:   Values{"a": []string{"1"}},
+		ok:    false,
 	},
 }
 
 func TestParseQuery(t *testing.T) {
-	for i, test := range parseTests {
-		form, err := ParseQuery(test.query)
-		if err != nil {
-			t.Errorf("test %d: Unexpected error: %v", i, err)
-			continue
-		}
-		if len(form) != len(test.out) {
-			t.Errorf("test %d: len(form) = %d, want %d", i, len(form), len(test.out))
-		}
-		for k, evs := range test.out {
-			vs, ok := form[k]
-			if !ok {
-				t.Errorf("test %d: Missing key %q", i, k)
-				continue
+	for _, test := range parseTests {
+		t.Run(test.query, func(t *testing.T) {
+			form, err := ParseQuery(test.query)
+			if test.ok != (err == nil) {
+				want := "<error>"
+				if test.ok {
+					want = "<nil>"
+				}
+				t.Errorf("Unexpected error: %v, want %v", err, want)
 			}
-			if len(vs) != len(evs) {
-				t.Errorf("test %d: len(form[%q]) = %d, want %d", i, k, len(vs), len(evs))
-				continue
+			if len(form) != len(test.out) {
+				t.Errorf("len(form) = %d, want %d", len(form), len(test.out))
 			}
-			for j, ev := range evs {
-				if v := vs[j]; v != ev {
-					t.Errorf("test %d: form[%q][%d] = %q, want %q", i, k, j, v, ev)
+			for k, evs := range test.out {
+				vs, ok := form[k]
+				if !ok {
+					t.Errorf("Missing key %q", k)
+					continue
+				}
+				if len(vs) != len(evs) {
+					t.Errorf("len(form[%q]) = %d, want %d", k, len(vs), len(evs))
+					continue
+				}
+				for j, ev := range evs {
+					if v := vs[j]; v != ev {
+						t.Errorf("form[%q][%d] = %q, want %q", k, j, v, ev)
+					}
 				}
 			}
-		}
+		})
 	}
 }
 
diff --git a/src/net/write_unix_test.go b/src/net/write_unix_test.go
index 6d8cb6a..f79f2d0 100644
--- a/src/net/write_unix_test.go
+++ b/src/net/write_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package net
diff --git a/src/net/writev_test.go b/src/net/writev_test.go
index d603b7f..bf40ca2 100644
--- a/src/net/writev_test.go
+++ b/src/net/writev_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package net
diff --git a/src/net/writev_unix.go b/src/net/writev_unix.go
index 8b20f42..a0fedc2 100644
--- a/src/net/writev_unix.go
+++ b/src/net/writev_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || illumos || linux || netbsd || openbsd
 // +build darwin dragonfly freebsd illumos linux netbsd openbsd
 
 package net
diff --git a/src/os/dir_unix.go b/src/os/dir_unix.go
index 0e1eab1..5589c9c 100644
--- a/src/os/dir_unix.go
+++ b/src/os/dir_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package os
@@ -9,15 +10,16 @@
 import (
 	"io"
 	"runtime"
+	"sync"
 	"syscall"
 	"unsafe"
 )
 
 // Auxiliary information if the File describes a directory
 type dirInfo struct {
-	buf  []byte // buffer for directory I/O
-	nbuf int    // length of buf; return value from Getdirentries
-	bufp int    // location of next record in buf.
+	buf  *[]byte // buffer for directory I/O
+	nbuf int     // length of buf; return value from Getdirentries
+	bufp int     // location of next record in buf.
 }
 
 const (
@@ -25,14 +27,26 @@
 	blockSize = 8192
 )
 
-func (d *dirInfo) close() {}
+var dirBufPool = sync.Pool{
+	New: func() interface{} {
+		// The buffer must be at least a block long.
+		buf := make([]byte, blockSize)
+		return &buf
+	},
+}
+
+func (d *dirInfo) close() {
+	if d.buf != nil {
+		dirBufPool.Put(d.buf)
+		d.buf = nil
+	}
+}
 
 func (f *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEntry, infos []FileInfo, err error) {
 	// If this file has no dirinfo, create one.
 	if f.dirinfo == nil {
 		f.dirinfo = new(dirInfo)
-		// The buffer must be at least a block long.
-		f.dirinfo.buf = make([]byte, blockSize)
+		f.dirinfo.buf = dirBufPool.Get().(*[]byte)
 	}
 	d := f.dirinfo
 
@@ -54,7 +68,7 @@
 		if d.bufp >= d.nbuf {
 			d.bufp = 0
 			var errno error
-			d.nbuf, errno = f.pfd.ReadDirent(d.buf)
+			d.nbuf, errno = f.pfd.ReadDirent(*d.buf)
 			runtime.KeepAlive(f)
 			if errno != nil {
 				return names, dirents, infos, &PathError{Op: "readdirent", Path: f.name, Err: errno}
@@ -65,7 +79,7 @@
 		}
 
 		// Drain the buffer
-		buf := d.buf[d.bufp:d.nbuf]
+		buf := (*d.buf)[d.bufp:d.nbuf]
 		reclen, ok := direntReclen(buf)
 		if !ok || reclen > uint64(len(buf)) {
 			break
diff --git a/src/os/endian_big.go b/src/os/endian_big.go
index c98f124..0529dcc 100644
--- a/src/os/endian_big.go
+++ b/src/os/endian_big.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 //
+//go:build ppc64 || s390x || mips || mips64
 // +build ppc64 s390x mips mips64
 
 package os
diff --git a/src/os/endian_little.go b/src/os/endian_little.go
index 3efc5e0..6be6020 100644
--- a/src/os/endian_little.go
+++ b/src/os/endian_little.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 //
+//go:build 386 || amd64 || arm || arm64 || ppc64le || mips64le || mipsle || riscv64 || wasm
 // +build 386 amd64 arm arm64 ppc64le mips64le mipsle riscv64 wasm
 
 package os
diff --git a/src/os/env_unix_test.go b/src/os/env_unix_test.go
index 89430b3..d45e1de 100644
--- a/src/os/env_unix_test.go
+++ b/src/os/env_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package os_test
diff --git a/src/os/error.go b/src/os/error.go
index 704a6fb..fe8f2a8 100644
--- a/src/os/error.go
+++ b/src/os/error.go
@@ -78,7 +78,7 @@
 // well as some syscall errors.
 //
 // This function predates errors.Is. It only supports errors returned by
-// the os package. New code should use errors.Is(err, os.ErrExist).
+// the os package. New code should use errors.Is(err, fs.ErrExist).
 func IsExist(err error) bool {
 	return underlyingErrorIs(err, ErrExist)
 }
@@ -88,7 +88,7 @@
 // ErrNotExist as well as some syscall errors.
 //
 // This function predates errors.Is. It only supports errors returned by
-// the os package. New code should use errors.Is(err, os.ErrNotExist).
+// the os package. New code should use errors.Is(err, fs.ErrNotExist).
 func IsNotExist(err error) bool {
 	return underlyingErrorIs(err, ErrNotExist)
 }
@@ -98,7 +98,7 @@
 // as some syscall errors.
 //
 // This function predates errors.Is. It only supports errors returned by
-// the os package. New code should use errors.Is(err, os.ErrPermission).
+// the os package. New code should use errors.Is(err, fs.ErrPermission).
 func IsPermission(err error) bool {
 	return underlyingErrorIs(err, ErrPermission)
 }
diff --git a/src/os/error_errno.go b/src/os/error_errno.go
index 31ae05a..580e915 100644
--- a/src/os/error_errno.go
+++ b/src/os/error_errno.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !plan9
 // +build !plan9
 
 package os
diff --git a/src/os/error_posix.go b/src/os/error_posix.go
index 2aeca82..268b3a9 100644
--- a/src/os/error_posix.go
+++ b/src/os/error_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package os
diff --git a/src/os/error_test.go b/src/os/error_test.go
index 6264ccc..4ab6246 100644
--- a/src/os/error_test.go
+++ b/src/os/error_test.go
@@ -33,7 +33,12 @@
 	}
 }
 
-func testErrNotExist(name string) string {
+func testErrNotExist(t *testing.T, name string) string {
+	originalWD, err := os.Getwd()
+	if err != nil {
+		t.Fatal(err)
+	}
+
 	f, err := os.Open(name)
 	if err == nil {
 		f.Close()
@@ -45,7 +50,10 @@
 
 	err = os.Chdir(name)
 	if err == nil {
-		return "Chdir should have failed"
+		if err := os.Chdir(originalWD); err != nil {
+			t.Fatalf("Chdir should have failed, failed to restore original working directory: %v", err)
+		}
+		return "Chdir should have failed, restored original working directory"
 	}
 	if s := checkErrorPredicate("os.IsNotExist", os.IsNotExist, err, fs.ErrNotExist); s != "" {
 		return s
@@ -54,21 +62,15 @@
 }
 
 func TestErrIsNotExist(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "_Go_ErrIsNotExist")
-	if err != nil {
-		t.Fatalf("create ErrIsNotExist tempdir: %s", err)
-		return
-	}
-	defer os.RemoveAll(tmpDir)
-
+	tmpDir := t.TempDir()
 	name := filepath.Join(tmpDir, "NotExists")
-	if s := testErrNotExist(name); s != "" {
+	if s := testErrNotExist(t, name); s != "" {
 		t.Fatal(s)
 		return
 	}
 
 	name = filepath.Join(name, "NotExists2")
-	if s := testErrNotExist(name); s != "" {
+	if s := testErrNotExist(t, name); s != "" {
 		t.Fatal(s)
 		return
 	}
diff --git a/src/os/error_unix_test.go b/src/os/error_unix_test.go
index 18bcf3f..e45282a 100644
--- a/src/os/error_unix_test.go
+++ b/src/os/error_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package os_test
diff --git a/src/os/error_windows_test.go b/src/os/error_windows_test.go
index b8191c5..aa0c14b 100644
--- a/src/os/error_windows_test.go
+++ b/src/os/error_windows_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build windows
 // +build windows
 
 package os_test
diff --git a/src/os/example_test.go b/src/os/example_test.go
index 3adce51..e8554b0 100644
--- a/src/os/example_test.go
+++ b/src/os/example_test.go
@@ -5,6 +5,7 @@
 package os_test
 
 import (
+	"errors"
 	"fmt"
 	"io/fs"
 	"log"
@@ -71,9 +72,9 @@
 	}
 }
 
-func ExampleIsNotExist() {
+func ExampleErrNotExist() {
 	filename := "a-nonexistent-file"
-	if _, err := os.Stat(filename); os.IsNotExist(err) {
+	if _, err := os.Stat(filename); errors.Is(err, fs.ErrNotExist) {
 		fmt.Println("file does not exist")
 	}
 	// Output:
diff --git a/src/os/exec.go b/src/os/exec.go
index edb773a..bc75d4d 100644
--- a/src/os/exec.go
+++ b/src/os/exec.go
@@ -54,6 +54,9 @@
 	// standard error. An implementation may support additional entries,
 	// depending on the underlying operating system. A nil entry corresponds
 	// to that file being closed when the process starts.
+	// On Unix systems, StartProcess will change these File values
+	// to blocking mode, which means that SetDeadline will stop working
+	// and calling Close will not interrupt a Read or Write.
 	Files []*File
 
 	// Operating system-specific process creation attributes.
diff --git a/src/os/exec/exec_linux_test.go b/src/os/exec/exec_linux_test.go
index 6f85020..3cfa30e 100644
--- a/src/os/exec/exec_linux_test.go
+++ b/src/os/exec/exec_linux_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && cgo
 // +build linux,cgo
 
 // On systems that use glibc, calling malloc can create a new arena,
diff --git a/src/os/exec/exec_posix_test.go b/src/os/exec/exec_posix_test.go
index d4d67ac..7b2c0c0 100644
--- a/src/os/exec/exec_posix_test.go
+++ b/src/os/exec/exec_posix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package exec_test
diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go
index 8b0c93f..d854e0d 100644
--- a/src/os/exec/exec_test.go
+++ b/src/os/exec/exec_test.go
@@ -488,7 +488,7 @@
 }
 
 func TestExtraFilesFDShuffle(t *testing.T) {
-	t.Skip("flaky test; see https://golang.org/issue/5780")
+	testenv.SkipFlaky(t, 5780)
 	switch runtime.GOOS {
 	case "windows":
 		t.Skip("no operating system support; skipping")
@@ -915,6 +915,16 @@
 	case "sleep":
 		time.Sleep(3 * time.Second)
 		os.Exit(0)
+	case "pipehandle":
+		handle, _ := strconv.ParseUint(args[0], 16, 64)
+		pipe := os.NewFile(uintptr(handle), "")
+		_, err := fmt.Fprint(pipe, args[1])
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "writing to pipe failed: %v\n", err)
+			os.Exit(1)
+		}
+		pipe.Close()
+		os.Exit(0)
 	default:
 		fmt.Fprintf(os.Stderr, "Unknown command %q\n", cmd)
 		os.Exit(2)
@@ -1042,41 +1052,18 @@
 	defer cancel()
 	c := helperCommandContext(t, ctx, "cat")
 
-	r, w, err := os.Pipe()
+	stdin, err := c.StdinPipe()
 	if err != nil {
 		t.Fatal(err)
 	}
-	c.Stdin = r
-
-	stdout, err := c.StdoutPipe()
-	if err != nil {
-		t.Fatal(err)
-	}
-	readDone := make(chan struct{})
-	go func() {
-		defer close(readDone)
-		var a [1024]byte
-		for {
-			n, err := stdout.Read(a[:])
-			if err != nil {
-				if err != io.EOF {
-					t.Errorf("unexpected read error: %v", err)
-				}
-				return
-			}
-			t.Logf("%s", a[:n])
-		}
-	}()
+	defer stdin.Close()
 
 	if err := c.Start(); err != nil {
 		t.Fatal(err)
 	}
 
-	if err := r.Close(); err != nil {
-		t.Fatal(err)
-	}
-
-	if _, err := io.WriteString(w, "echo"); err != nil {
+	// At this point the process is alive. Ensure it by sending data to stdin.
+	if _, err := io.WriteString(stdin, "echo"); err != nil {
 		t.Fatal(err)
 	}
 
@@ -1086,20 +1073,15 @@
 	// should now fail.  Give the process a little while to die.
 	start := time.Now()
 	for {
-		if _, err := io.WriteString(w, "echo"); err != nil {
+		if _, err := io.WriteString(stdin, "echo"); err != nil {
 			break
 		}
-		if time.Since(start) > time.Second {
+		if time.Since(start) > time.Minute {
 			t.Fatal("canceling context did not stop program")
 		}
 		time.Sleep(time.Millisecond)
 	}
 
-	if err := w.Close(); err != nil {
-		t.Errorf("error closing write end of pipe: %v", err)
-	}
-	<-readDone
-
 	if err := c.Wait(); err == nil {
 		t.Error("program unexpectedly exited successfully")
 	} else {
diff --git a/src/os/exec/exec_unix.go b/src/os/exec/exec_unix.go
index 51c5242..467c069 100644
--- a/src/os/exec/exec_unix.go
+++ b/src/os/exec/exec_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !plan9 && !windows
 // +build !plan9,!windows
 
 package exec
diff --git a/src/os/exec/exec_windows_test.go b/src/os/exec/exec_windows_test.go
new file mode 100644
index 0000000..fbccffe
--- /dev/null
+++ b/src/os/exec/exec_windows_test.go
@@ -0,0 +1,43 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build windows
+// +build windows
+
+package exec_test
+
+import (
+	"io"
+	"os"
+	"strconv"
+	"syscall"
+	"testing"
+)
+
+func TestPipePassing(t *testing.T) {
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Error(err)
+	}
+	const marker = "arrakis, dune, desert planet"
+	childProc := helperCommand(t, "pipehandle", strconv.FormatUint(uint64(w.Fd()), 16), marker)
+	childProc.SysProcAttr = &syscall.SysProcAttr{AdditionalInheritedHandles: []syscall.Handle{syscall.Handle(w.Fd())}}
+	err = childProc.Start()
+	if err != nil {
+		t.Error(err)
+	}
+	w.Close()
+	response, err := io.ReadAll(r)
+	if err != nil {
+		t.Error(err)
+	}
+	r.Close()
+	if string(response) != marker {
+		t.Errorf("got %q; want %q", string(response), marker)
+	}
+	err = childProc.Wait()
+	if err != nil {
+		t.Error(err)
+	}
+}
diff --git a/src/os/exec/lp_js.go b/src/os/exec/lp_js.go
index 6750fb9..4eac25f 100644
--- a/src/os/exec/lp_js.go
+++ b/src/os/exec/lp_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package exec
diff --git a/src/os/exec/lp_unix.go b/src/os/exec/lp_unix.go
index 66c1df7..d1d246a 100644
--- a/src/os/exec/lp_unix.go
+++ b/src/os/exec/lp_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package exec
diff --git a/src/os/exec/lp_unix_test.go b/src/os/exec/lp_unix_test.go
index 296480f..9fded0e 100644
--- a/src/os/exec/lp_unix_test.go
+++ b/src/os/exec/lp_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package exec
@@ -36,13 +37,7 @@
 		t.Fatal("Close failed: ", err)
 	}
 
-	pathenv := os.Getenv("PATH")
-	defer os.Setenv("PATH", pathenv)
-
-	err = os.Setenv("PATH", "")
-	if err != nil {
-		t.Fatal("Setenv failed: ", err)
-	}
+	t.Setenv("PATH", "")
 
 	path, err := LookPath("exec_me")
 	if err == nil {
diff --git a/src/os/exec/lp_windows_test.go b/src/os/exec/lp_windows_test.go
index c6f3d5d..bbf6a9b 100644
--- a/src/os/exec/lp_windows_test.go
+++ b/src/os/exec/lp_windows_test.go
@@ -143,7 +143,7 @@
 	if errCmd == nil && errLP == nil {
 		// both succeeded
 		if should != have {
-			t.Fatalf("test=%+v failed: expected to find %q, but found %q", test, should, have)
+			t.Fatalf("test=%+v:\ncmd /c ran: %s\nlookpath found: %s", test, should, have)
 		}
 		return
 	}
@@ -306,22 +306,19 @@
 }
 
 func TestLookPath(t *testing.T) {
-	tmp, err := os.MkdirTemp("", "TestLookPath")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer os.RemoveAll(tmp)
-
+	tmp := t.TempDir()
 	printpathExe := buildPrintPathExe(t, tmp)
 
 	// Run all tests.
 	for i, test := range lookPathTests {
-		dir := filepath.Join(tmp, "d"+strconv.Itoa(i))
-		err := os.Mkdir(dir, 0700)
-		if err != nil {
-			t.Fatal("Mkdir failed: ", err)
-		}
-		test.run(t, dir, printpathExe)
+		t.Run(fmt.Sprint(i), func(t *testing.T) {
+			dir := filepath.Join(tmp, "d"+strconv.Itoa(i))
+			err := os.Mkdir(dir, 0700)
+			if err != nil {
+				t.Fatal("Mkdir failed: ", err)
+			}
+			test.run(t, dir, printpathExe)
+		})
 	}
 }
 
@@ -503,12 +500,7 @@
 }
 
 func TestCommand(t *testing.T) {
-	tmp, err := os.MkdirTemp("", "TestCommand")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer os.RemoveAll(tmp)
-
+	tmp := t.TempDir()
 	printpathExe := buildPrintPathExe(t, tmp)
 
 	// Run all tests.
diff --git a/src/os/exec/read3.go b/src/os/exec/read3.go
index 8cc24da..a8c7183 100644
--- a/src/os/exec/read3.go
+++ b/src/os/exec/read3.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // This is a test program that verifies that it can read from
diff --git a/src/os/exec_plan9.go b/src/os/exec_plan9.go
index 8580153..cc84f97 100644
--- a/src/os/exec_plan9.go
+++ b/src/os/exec_plan9.go
@@ -5,6 +5,7 @@
 package os
 
 import (
+	"internal/itoa"
 	"runtime"
 	"syscall"
 	"time"
@@ -40,7 +41,7 @@
 }
 
 func (p *Process) writeProcFile(file string, data string) error {
-	f, e := OpenFile("/proc/"+itoa(p.Pid)+"/"+file, O_WRONLY, 0)
+	f, e := OpenFile("/proc/"+itoa.Itoa(p.Pid)+"/"+file, O_WRONLY, 0)
 	if e != nil {
 		return e
 	}
diff --git a/src/os/exec_posix.go b/src/os/exec_posix.go
index 7ecddae..e8736f7 100644
--- a/src/os/exec_posix.go
+++ b/src/os/exec_posix.go
@@ -2,11 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package os
 
 import (
+	"internal/itoa"
 	"internal/syscall/execenv"
 	"runtime"
 	"syscall"
@@ -102,13 +104,18 @@
 	res := ""
 	switch {
 	case status.Exited():
-		res = "exit status " + itoa(status.ExitStatus())
+		code := status.ExitStatus()
+		if runtime.GOOS == "windows" && uint(code) >= 1<<16 { // windows uses large hex numbers
+			res = "exit status " + uitox(uint(code))
+		} else { // unix systems use small decimal integers
+			res = "exit status " + itoa.Itoa(code) // unix
+		}
 	case status.Signaled():
 		res = "signal: " + status.Signal().String()
 	case status.Stopped():
 		res = "stop signal: " + status.StopSignal().String()
 		if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != 0 {
-			res += " (trap " + itoa(status.TrapCause()) + ")"
+			res += " (trap " + itoa.Itoa(status.TrapCause()) + ")"
 		}
 	case status.Continued():
 		res = "continued"
diff --git a/src/os/exec_unix.go b/src/os/exec_unix.go
index a1703a1..d1bbeb7 100644
--- a/src/os/exec_unix.go
+++ b/src/os/exec_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package os
diff --git a/src/os/exec_unix_test.go b/src/os/exec_unix_test.go
index d942cdb..f14b351 100644
--- a/src/os/exec_unix_test.go
+++ b/src/os/exec_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package os_test
diff --git a/src/os/exec_windows.go b/src/os/exec_windows.go
index 5710401..239bed1 100644
--- a/src/os/exec_windows.go
+++ b/src/os/exec_windows.go
@@ -45,16 +45,6 @@
 	return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil
 }
 
-func terminateProcess(pid, exitcode int) error {
-	h, e := syscall.OpenProcess(syscall.PROCESS_TERMINATE, false, uint32(pid))
-	if e != nil {
-		return NewSyscallError("OpenProcess", e)
-	}
-	defer syscall.CloseHandle(h)
-	e = syscall.TerminateProcess(h, uint32(exitcode))
-	return NewSyscallError("TerminateProcess", e)
-}
-
 func (p *Process) signal(sig Signal) error {
 	handle := atomic.LoadUintptr(&p.handle)
 	if handle == uintptr(syscall.InvalidHandle) {
@@ -64,16 +54,22 @@
 		return ErrProcessDone
 	}
 	if sig == Kill {
-		err := terminateProcess(p.Pid, 1)
+		var terminationHandle syscall.Handle
+		e := syscall.DuplicateHandle(^syscall.Handle(0), syscall.Handle(handle), ^syscall.Handle(0), &terminationHandle, syscall.PROCESS_TERMINATE, false, 0)
+		if e != nil {
+			return NewSyscallError("DuplicateHandle", e)
+		}
 		runtime.KeepAlive(p)
-		return err
+		defer syscall.CloseHandle(terminationHandle)
+		e = syscall.TerminateProcess(syscall.Handle(terminationHandle), 1)
+		return NewSyscallError("TerminateProcess", e)
 	}
 	// TODO(rsc): Handle Interrupt too?
 	return syscall.Errno(syscall.EWINDOWS)
 }
 
 func (p *Process) release() error {
-	handle := atomic.LoadUintptr(&p.handle)
+	handle := atomic.SwapUintptr(&p.handle, uintptr(syscall.InvalidHandle))
 	if handle == uintptr(syscall.InvalidHandle) {
 		return syscall.EINVAL
 	}
@@ -81,7 +77,6 @@
 	if e != nil {
 		return NewSyscallError("CloseHandle", e)
 	}
-	atomic.StoreUintptr(&p.handle, uintptr(syscall.InvalidHandle))
 	// no need for a finalizer anymore
 	runtime.SetFinalizer(p, nil)
 	return nil
diff --git a/src/os/executable_path.go b/src/os/executable_path.go
index 7b8b836..625430e 100644
--- a/src/os/executable_path.go
+++ b/src/os/executable_path.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || openbsd
 // +build aix openbsd
 
 package os
diff --git a/src/os/executable_plan9.go b/src/os/executable_plan9.go
index a5947ea..ad7a441 100644
--- a/src/os/executable_plan9.go
+++ b/src/os/executable_plan9.go
@@ -2,14 +2,18 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build plan9
 // +build plan9
 
 package os
 
-import "syscall"
+import (
+	"internal/itoa"
+	"syscall"
+)
 
 func executable() (string, error) {
-	fn := "/proc/" + itoa(Getpid()) + "/text"
+	fn := "/proc/" + itoa.Itoa(Getpid()) + "/text"
 	f, err := Open(fn)
 	if err != nil {
 		return "", err
diff --git a/src/os/executable_procfs.go b/src/os/executable_procfs.go
index 5ee41a4..76ba0e6 100644
--- a/src/os/executable_procfs.go
+++ b/src/os/executable_procfs.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux || netbsd || (js && wasm)
 // +build linux netbsd js,wasm
 
 package os
@@ -11,10 +12,7 @@
 	"runtime"
 )
 
-// We query the executable path at init time to avoid the problem of
-// readlink returns a path appended with " (deleted)" when the original
-// binary gets deleted.
-var executablePath, executablePathErr = func() (string, error) {
+func executable() (string, error) {
 	var procfn string
 	switch runtime.GOOS {
 	default:
@@ -24,9 +22,17 @@
 	case "netbsd":
 		procfn = "/proc/curproc/exe"
 	}
-	return Readlink(procfn)
-}()
+	path, err := Readlink(procfn)
 
-func executable() (string, error) {
-	return executablePath, executablePathErr
+	// When the executable has been deleted then Readlink returns a
+	// path appended with " (deleted)".
+	return stringsTrimSuffix(path, " (deleted)"), err
+}
+
+// stringsTrimSuffix is the same as strings.TrimSuffix.
+func stringsTrimSuffix(s, suffix string) string {
+	if len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix {
+		return s[:len(s)-len(suffix)]
+	}
+	return s
 }
diff --git a/src/os/executable_sysctl.go b/src/os/executable_sysctl.go
index f9a4b18..039448b 100644
--- a/src/os/executable_sysctl.go
+++ b/src/os/executable_sysctl.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build freebsd || dragonfly
 // +build freebsd dragonfly
 
 package os
diff --git a/src/os/executable_test.go b/src/os/executable_test.go
index f25ee0c..719d6a6 100644
--- a/src/os/executable_test.go
+++ b/src/os/executable_test.go
@@ -86,3 +86,68 @@
 		os.Exit(0)
 	}
 }
+
+func TestExecutableDeleted(t *testing.T) {
+	testenv.MustHaveExec(t)
+	switch runtime.GOOS {
+	case "windows", "plan9":
+		t.Skipf("%v does not support deleting running binary", runtime.GOOS)
+	case "openbsd", "freebsd", "aix":
+		t.Skipf("%v does not support reading deleted binary name", runtime.GOOS)
+	}
+
+	dir := t.TempDir()
+
+	src := filepath.Join(dir, "testdel.go")
+	exe := filepath.Join(dir, "testdel.exe")
+
+	err := os.WriteFile(src, []byte(testExecutableDeletion), 0666)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	out, err := osexec.Command(testenv.GoToolPath(t), "build", "-o", exe, src).CombinedOutput()
+	t.Logf("build output:\n%s", out)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	out, err = osexec.Command(exe).CombinedOutput()
+	t.Logf("exec output:\n%s", out)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+const testExecutableDeletion = `package main
+
+import (
+	"fmt"
+	"os"
+)
+
+func main() {
+	before, err := os.Executable()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "failed to read executable name before deletion: %v\n", err)
+		os.Exit(1)
+	}
+
+	err = os.Remove(before)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "failed to remove executable: %v\n", err)
+		os.Exit(1)
+	}
+
+	after, err := os.Executable()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "failed to read executable name after deletion: %v\n", err)
+		os.Exit(1)
+	}
+
+	if before != after {
+		fmt.Fprintf(os.Stderr, "before and after do not match: %v != %v\n", before, after)
+		os.Exit(1)
+	}
+}
+`
diff --git a/src/os/export_unix_test.go b/src/os/export_unix_test.go
index 39866a6..10f8312 100644
--- a/src/os/export_unix_test.go
+++ b/src/os/export_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package os
diff --git a/src/os/export_windows_test.go b/src/os/export_windows_test.go
index f36fadb..ff4f899 100644
--- a/src/os/export_windows_test.go
+++ b/src/os/export_windows_test.go
@@ -8,6 +8,7 @@
 
 var (
 	FixLongPath       = fixLongPath
+	CanUseLongPaths   = canUseLongPaths
 	NewConsoleFile    = newConsoleFile
 	CommandLineToArgv = commandLineToArgv
 )
diff --git a/src/os/fifo_test.go b/src/os/fifo_test.go
index 2439192..007ed29 100644
--- a/src/os/fifo_test.go
+++ b/src/os/fifo_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
 // +build darwin dragonfly freebsd linux netbsd openbsd
 
 package os_test
@@ -25,17 +26,9 @@
 	switch runtime.GOOS {
 	case "android":
 		t.Skip("skipping on Android; mkfifo syscall not available")
-	case "openbsd":
-		// On OpenBSD 6.2 this test just hangs for some reason.
-		t.Skip("skipping on OpenBSD; issue 25877")
 	}
 
-	dir, err := os.MkdirTemp("", "TestFifoEOF")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
-
+	dir := t.TempDir()
 	fifoName := filepath.Join(dir, "fifo")
 	if err := syscall.Mkfifo(fifoName, 0600); err != nil {
 		t.Fatal(err)
diff --git a/src/os/file.go b/src/os/file.go
index 52dd943..e717f17 100644
--- a/src/os/file.go
+++ b/src/os/file.go
@@ -44,11 +44,13 @@
 	"errors"
 	"internal/poll"
 	"internal/testlog"
+	"internal/unsafeheader"
 	"io"
 	"io/fs"
 	"runtime"
 	"syscall"
 	"time"
+	"unsafe"
 )
 
 // Name returns the name of the file as presented to Open.
@@ -246,7 +248,12 @@
 // WriteString is like Write, but writes the contents of string s rather than
 // a slice of bytes.
 func (f *File) WriteString(s string) (n int, err error) {
-	return f.Write([]byte(s))
+	var b []byte
+	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
+	hdr.Data = (*unsafeheader.String)(unsafe.Pointer(&s)).Data
+	hdr.Cap = len(s)
+	hdr.Len = len(s)
+	return f.Write(b)
 }
 
 // Mkdir creates a new directory with the specified name and permission
@@ -644,6 +651,17 @@
 	return f, nil
 }
 
+func (dir dirFS) Stat(name string) (fs.FileInfo, error) {
+	if !fs.ValidPath(name) || runtime.GOOS == "windows" && containsAny(name, `\:`) {
+		return nil, &PathError{Op: "stat", Path: name, Err: ErrInvalid}
+	}
+	f, err := Stat(string(dir) + "/" + name)
+	if err != nil {
+		return nil, err
+	}
+	return f, nil
+}
+
 // ReadFile reads the named file and returns the contents.
 // A successful call returns err == nil, not err == EOF.
 // Because ReadFile reads the whole file, it does not treat an EOF from Read
diff --git a/src/os/file_plan9.go b/src/os/file_plan9.go
index 4f384e9..604aea6 100644
--- a/src/os/file_plan9.go
+++ b/src/os/file_plan9.go
@@ -440,6 +440,8 @@
 }
 
 // Symlink creates newname as a symbolic link to oldname.
+// On Windows, a symlink to a non-existent oldname creates a file symlink;
+// if oldname is later created as a directory the symlink will not work.
 // If there is an error, it will be of type *LinkError.
 func Symlink(oldname, newname string) error {
 	return &LinkError{"symlink", oldname, newname, syscall.EPLAN9}
diff --git a/src/os/file_posix.go b/src/os/file_posix.go
index 795c547..211f2a1 100644
--- a/src/os/file_posix.go
+++ b/src/os/file_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package os
diff --git a/src/os/file_unix.go b/src/os/file_unix.go
index f884500..a2531b9 100644
--- a/src/os/file_unix.go
+++ b/src/os/file_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package os
@@ -173,7 +174,7 @@
 		// with the netpoll system. That can happen for
 		// a file descriptor that is not supported by
 		// epoll/kqueue; for example, disk files on
-		// GNU/Linux systems. We assume that any real error
+		// Linux systems. We assume that any real error
 		// will show up in later I/O.
 	} else if pollable {
 		// We successfully registered with netpoll, so put
@@ -246,6 +247,7 @@
 	}
 	if file.dirinfo != nil {
 		file.dirinfo.close()
+		file.dirinfo = nil
 	}
 	var err error
 	if e := file.pfd.Close(); e != nil {
@@ -349,6 +351,8 @@
 }
 
 // Symlink creates newname as a symbolic link to oldname.
+// On Windows, a symlink to a non-existent oldname creates a file symlink;
+// if oldname is later created as a directory the symlink will not work.
 // If there is an error, it will be of type *LinkError.
 func Symlink(oldname, newname string) error {
 	e := ignoringEINTR(func() error {
diff --git a/src/os/file_windows.go b/src/os/file_windows.go
index dfc5fc6..378e2b1 100644
--- a/src/os/file_windows.go
+++ b/src/os/file_windows.go
@@ -279,10 +279,11 @@
 }
 
 // Pipe returns a connected pair of Files; reads from r return bytes written to w.
-// It returns the files and an error, if any.
+// It returns the files and an error, if any. The Windows handles underlying
+// the returned files are marked as inheritable by child processes.
 func Pipe() (r *File, w *File, err error) {
 	var p [2]syscall.Handle
-	e := syscall.CreatePipe(&p[0], &p[1], nil, 0)
+	e := syscall.Pipe(p[:])
 	if e != nil {
 		return nil, nil, NewSyscallError("pipe", e)
 	}
@@ -326,6 +327,8 @@
 }
 
 // Symlink creates newname as a symbolic link to oldname.
+// On Windows, a symlink to a non-existent oldname creates a file symlink;
+// if oldname is later created as a directory the symlink will not work.
 // If there is an error, it will be of type *LinkError.
 func Symlink(oldname, newname string) error {
 	// '/' does not work in link's content
@@ -364,17 +367,14 @@
 		flags |= syscall.SYMBOLIC_LINK_FLAG_DIRECTORY
 	}
 	err = syscall.CreateSymbolicLink(n, o, flags)
-
 	if err != nil {
 		// the unprivileged create flag is unsupported
 		// below Windows 10 (1703, v10.0.14972). retry without it.
 		flags &^= windows.SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
-
 		err = syscall.CreateSymbolicLink(n, o, flags)
-	}
-
-	if err != nil {
-		return &LinkError{"symlink", oldname, newname, err}
+		if err != nil {
+			return &LinkError{"symlink", oldname, newname, err}
+		}
 	}
 	return nil
 }
diff --git a/src/os/os_test.go b/src/os/os_test.go
index a32e5fc..506f1fb 100644
--- a/src/os/os_test.go
+++ b/src/os/os_test.go
@@ -617,11 +617,7 @@
 	if testing.Short() {
 		t.Skip("test.short; skipping")
 	}
-	dir, err := os.MkdirTemp("", "")
-	if err != nil {
-		t.Fatalf("TempDir: %v", err)
-	}
-	defer RemoveAll(dir)
+	dir := t.TempDir()
 	for i := 1; i <= 105; i++ {
 		f, err := Create(filepath.Join(dir, fmt.Sprintf("%d", i)))
 		if err != nil {
@@ -716,11 +712,7 @@
 		// testing it wouldn't work.
 		t.Skipf("skipping test on %v", runtime.GOOS)
 	}
-	dir, err := os.MkdirTemp("", "")
-	if err != nil {
-		t.Fatalf("TempDir: %v", err)
-	}
-	defer RemoveAll(dir)
+	dir := t.TempDir()
 	touch(t, filepath.Join(dir, "good1"))
 	touch(t, filepath.Join(dir, "x")) // will disappear or have an error
 	touch(t, filepath.Join(dir, "good2"))
@@ -1949,22 +1941,16 @@
 
 func TestStatDirWithTrailingSlash(t *testing.T) {
 	// Create new temporary directory and arrange to clean it up.
-	path, err := os.MkdirTemp("", "_TestStatDirWithSlash_")
-	if err != nil {
-		t.Fatalf("TempDir: %s", err)
-	}
-	defer RemoveAll(path)
+	path := t.TempDir()
 
 	// Stat of path should succeed.
-	_, err = Stat(path)
-	if err != nil {
+	if _, err := Stat(path); err != nil {
 		t.Fatalf("stat %s failed: %s", path, err)
 	}
 
 	// Stat of path+"/" should succeed too.
 	path += "/"
-	_, err = Stat(path)
-	if err != nil {
+	if _, err := Stat(path); err != nil {
 		t.Fatalf("stat %s failed: %s", path, err)
 	}
 }
@@ -2091,12 +2077,7 @@
 func TestStatDirModeExec(t *testing.T) {
 	const mode = 0111
 
-	path, err := os.MkdirTemp("", "go-build")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer RemoveAll(path)
-
+	path := t.TempDir()
 	if err := Chmod(path, 0777); err != nil {
 		t.Fatalf("Chmod %q 0777: %v", path, err)
 	}
@@ -2160,12 +2141,7 @@
 func TestStatRelativeSymlink(t *testing.T) {
 	testenv.MustHaveSymlink(t)
 
-	tmpdir, err := os.MkdirTemp("", "TestStatRelativeSymlink")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer RemoveAll(tmpdir)
-
+	tmpdir := t.TempDir()
 	target := filepath.Join(tmpdir, "target")
 	f, err := Create(target)
 	if err != nil {
@@ -2773,3 +2749,21 @@
 		t.Fatalf("read %s: not newline-terminated: %q", name, data)
 	}
 }
+
+func TestWriteStringAlloc(t *testing.T) {
+	if runtime.GOOS == "js" {
+		t.Skip("js allocates a lot during File.WriteString")
+	}
+	d := t.TempDir()
+	f, err := Create(filepath.Join(d, "whiteboard.txt"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer f.Close()
+	allocs := testing.AllocsPerRun(100, func() {
+		f.WriteString("I will not allocate when passed a string longer than 32 bytes.\n")
+	})
+	if allocs != 0 {
+		t.Errorf("expected 0 allocs for File.WriteString, got %v", allocs)
+	}
+}
diff --git a/src/os/os_unix_test.go b/src/os/os_unix_test.go
index 51693fd..9b4c0ab 100644
--- a/src/os/os_unix_test.go
+++ b/src/os/os_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package os_test
diff --git a/src/os/os_windows_test.go b/src/os/os_windows_test.go
index b0929b4..195c30f 100644
--- a/src/os/os_windows_test.go
+++ b/src/os/os_windows_test.go
@@ -29,22 +29,32 @@
 // For TestRawConnReadWrite.
 type syscallDescriptor = syscall.Handle
 
+// chdir changes the current working directory to the named directory,
+// and then restore the original working directory at the end of the test.
+func chdir(t *testing.T, dir string) {
+	olddir, err := os.Getwd()
+	if err != nil {
+		t.Fatalf("chdir: %v", err)
+	}
+	if err := os.Chdir(dir); err != nil {
+		t.Fatalf("chdir %s: %v", dir, err)
+	}
+
+	t.Cleanup(func() {
+		if err := os.Chdir(olddir); err != nil {
+			t.Errorf("chdir to original working directory %s: %v", olddir, err)
+			os.Exit(1)
+		}
+	})
+}
+
 func TestSameWindowsFile(t *testing.T) {
 	temp, err := os.MkdirTemp("", "TestSameWindowsFile")
 	if err != nil {
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(temp)
-
-	wd, err := os.Getwd()
-	if err != nil {
-		t.Fatal(err)
-	}
-	err = os.Chdir(temp)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.Chdir(wd)
+	chdir(t, temp)
 
 	f, err := os.Create("a")
 	if err != nil {
@@ -94,16 +104,7 @@
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(tmpdir)
-
-	oldwd, err := os.Getwd()
-	if err != nil {
-		t.Fatal(err)
-	}
-	err = os.Chdir(tmpdir)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.Chdir(oldwd)
+	chdir(t, tmpdir)
 
 	dir := filepath.Join(tmpdir, "dir")
 	err = os.Mkdir(dir, 0777)
@@ -444,15 +445,7 @@
 	}
 	defer os.RemoveAll(dir)
 
-	oldwd, err := os.Getwd()
-	if err != nil {
-		t.Fatal(err)
-	}
-	err = os.Chdir(dir)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.Chdir(oldwd)
+	chdir(t, dir)
 
 	shareName := "GoSymbolicLinkTestShare" // hope no conflictions
 	sharePath := filepath.Join(dir, shareName)
@@ -604,16 +597,7 @@
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(tmpdir)
-
-	wd, err := os.Getwd()
-	if err != nil {
-		t.Fatal(err)
-	}
-	err = os.Chdir(tmpdir)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.Chdir(wd)
+	chdir(t, tmpdir)
 
 	want := []string{"file1", "file2", "file3", "gopher.txt"}
 	sort.Strings(want)
@@ -642,11 +626,7 @@
 }
 
 func TestDeleteReadOnly(t *testing.T) {
-	tmpdir, err := os.MkdirTemp("", "TestDeleteReadOnly")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 	p := filepath.Join(tmpdir, "a")
 	// This sets FILE_ATTRIBUTE_READONLY.
 	f, err := os.OpenFile(p, os.O_CREATE, 0400)
@@ -812,11 +792,7 @@
 }
 
 func TestCmdArgs(t *testing.T) {
-	tmpdir, err := os.MkdirTemp("", "TestCmdArgs")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	const prog = `
 package main
@@ -831,8 +807,7 @@
 }
 `
 	src := filepath.Join(tmpdir, "main.go")
-	err = os.WriteFile(src, []byte(prog), 0666)
-	if err != nil {
+	if err := os.WriteFile(src, []byte(prog), 0666); err != nil {
 		t.Fatal(err)
 	}
 
@@ -979,21 +954,14 @@
 	}
 	t.Parallel()
 
-	temp, err := os.MkdirTemp("", "TestSymlinkCreation")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(temp)
-
+	temp := t.TempDir()
 	dummyFile := filepath.Join(temp, "file")
-	err = os.WriteFile(dummyFile, []byte(""), 0644)
-	if err != nil {
+	if err := os.WriteFile(dummyFile, []byte(""), 0644); err != nil {
 		t.Fatal(err)
 	}
 
 	linkFile := filepath.Join(temp, "link")
-	err = os.Symlink(dummyFile, linkFile)
-	if err != nil {
+	if err := os.Symlink(dummyFile, linkFile); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -1226,16 +1194,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-
-	wd, err := os.Getwd()
-	if err != nil {
-		t.Fatal(err)
-	}
-	err = os.Chdir(tmpdir)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.Chdir(wd)
+	chdir(t, tmpdir)
 
 	vol := filepath.VolumeName(tmpdir)
 	output, err := osexec.Command("cmd", "/c", "mountvol", vol, "/L").CombinedOutput()
diff --git a/src/os/path_test.go b/src/os/path_test.go
index b79d958..4535abb 100644
--- a/src/os/path_test.go
+++ b/src/os/path_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"internal/testenv"
-	"os"
 	. "os"
 	"path/filepath"
 	"runtime"
@@ -78,27 +77,19 @@
 func TestMkdirAllWithSymlink(t *testing.T) {
 	testenv.MustHaveSymlink(t)
 
-	tmpDir, err := os.MkdirTemp("", "TestMkdirAllWithSymlink-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer RemoveAll(tmpDir)
-
+	tmpDir := t.TempDir()
 	dir := tmpDir + "/dir"
-	err = Mkdir(dir, 0755)
-	if err != nil {
+	if err := Mkdir(dir, 0755); err != nil {
 		t.Fatalf("Mkdir %s: %s", dir, err)
 	}
 
 	link := tmpDir + "/link"
-	err = Symlink("dir", link)
-	if err != nil {
+	if err := Symlink("dir", link); err != nil {
 		t.Fatalf("Symlink %s: %s", link, err)
 	}
 
 	path := link + "/foo"
-	err = MkdirAll(path, 0755)
-	if err != nil {
+	if err := MkdirAll(path, 0755); err != nil {
 		t.Errorf("MkdirAll %q: %s", path, err)
 	}
 }
diff --git a/src/os/path_unix.go b/src/os/path_unix.go
index c99a824..db38359 100644
--- a/src/os/path_unix.go
+++ b/src/os/path_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package os
diff --git a/src/os/path_windows.go b/src/os/path_windows.go
index 87b1cac..a96245f 100644
--- a/src/os/path_windows.go
+++ b/src/os/path_windows.go
@@ -128,6 +128,10 @@
 	return vol + dir
 }
 
+// This is set via go:linkname on runtime.canUseLongPaths, and is true when the OS
+// supports opting into proper long path handling without the need for fixups.
+var canUseLongPaths bool
+
 // fixLongPath returns the extended-length (\\?\-prefixed) form of
 // path when needed, in order to avoid the default 260 character file
 // path limit imposed by Windows. If path is not easily converted to
@@ -137,6 +141,9 @@
 //
 // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
 func fixLongPath(path string) string {
+	if canUseLongPaths {
+		return path
+	}
 	// Do nothing (and don't allocate) if the path is "short".
 	// Empirically (at least on the Windows Server 2013 builder),
 	// the kernel is arbitrarily okay with < 248 bytes. That
diff --git a/src/os/path_windows_test.go b/src/os/path_windows_test.go
index 869db8f..e960bcb 100644
--- a/src/os/path_windows_test.go
+++ b/src/os/path_windows_test.go
@@ -12,6 +12,9 @@
 )
 
 func TestFixLongPath(t *testing.T) {
+	if os.CanUseLongPaths {
+		return
+	}
 	// 248 is long enough to trigger the longer-than-248 checks in
 	// fixLongPath, but short enough not to make a path component
 	// longer than 255, which is illegal on Windows. (which
@@ -46,12 +49,22 @@
 	}
 }
 
-func TestMkdirAllExtendedLength(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "TestMkdirAllExtendedLength")
-	if err != nil {
-		t.Fatal(err)
+func TestMkdirAllLongPath(t *testing.T) {
+	tmpDir := t.TempDir()
+	path := tmpDir
+	for i := 0; i < 100; i++ {
+		path += `\another-path-component`
 	}
-	defer os.RemoveAll(tmpDir)
+	if err := os.MkdirAll(path, 0777); err != nil {
+		t.Fatalf("MkdirAll(%q) failed; %v", path, err)
+	}
+	if err := os.RemoveAll(tmpDir); err != nil {
+		t.Fatalf("RemoveAll(%q) failed; %v", tmpDir, err)
+	}
+}
+
+func TestMkdirAllExtendedLength(t *testing.T) {
+	tmpDir := t.TempDir()
 
 	const prefix = `\\?\`
 	if len(tmpDir) < 4 || tmpDir[:4] != prefix {
@@ -62,14 +75,12 @@
 		tmpDir = prefix + fullPath
 	}
 	path := tmpDir + `\dir\`
-	err = os.MkdirAll(path, 0777)
-	if err != nil {
+	if err := os.MkdirAll(path, 0777); err != nil {
 		t.Fatalf("MkdirAll(%q) failed: %v", path, err)
 	}
 
 	path = path + `.\dir2`
-	err = os.MkdirAll(path, 0777)
-	if err == nil {
+	if err := os.MkdirAll(path, 0777); err == nil {
 		t.Fatalf("MkdirAll(%q) should have failed, but did not", path)
 	}
 }
diff --git a/src/os/pipe2_bsd.go b/src/os/pipe2_bsd.go
index 0ef894b..bf6d081 100644
--- a/src/os/pipe2_bsd.go
+++ b/src/os/pipe2_bsd.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build freebsd netbsd openbsd
+//go:build dragonfly || freebsd || netbsd || openbsd
+// +build dragonfly freebsd netbsd openbsd
 
 package os
 
diff --git a/src/os/pipe2_illumos.go b/src/os/pipe2_illumos.go
index 026ce62..71b8cb8 100644
--- a/src/os/pipe2_illumos.go
+++ b/src/os/pipe2_illumos.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build illumos
 // +build illumos
 
 package os
diff --git a/src/os/pipe_bsd.go b/src/os/pipe_bsd.go
index 115d6ba..097b32e 100644
--- a/src/os/pipe_bsd.go
+++ b/src/os/pipe_bsd.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin dragonfly js,wasm solaris,!illumos
+//go:build aix || darwin || (js && wasm) || (solaris && !illumos)
+// +build aix darwin js,wasm solaris,!illumos
 
 package os
 
diff --git a/src/os/pipe_test.go b/src/os/pipe_test.go
index b98e538..41a1e9c 100644
--- a/src/os/pipe_test.go
+++ b/src/os/pipe_test.go
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // Test broken pipes on Unix systems.
+//go:build !plan9 && !js
 // +build !plan9,!js
 
 package os_test
@@ -441,12 +442,14 @@
 	defer r.Close()
 	defer w.Close()
 
-	c := make(chan bool)
+	const count = 10
+
+	c := make(chan bool, 1)
 	var wg sync.WaitGroup
 	wg.Add(1)
 	go func() {
 		defer wg.Done()
-		var buf [10]byte
+		var buf [count]byte
 		r.SetReadDeadline(time.Now().Add(time.Minute))
 		c <- true
 		if _, err := r.Read(buf[:]); os.IsTimeout(err) {
@@ -465,8 +468,9 @@
 		r.Fd()
 
 		// The bug was that Fd would hang until Read timed out.
-		// If the bug is fixed, then closing r here will cause
-		// the Read to exit before the timeout expires.
+		// If the bug is fixed, then writing to w and closing r here
+		// will cause the Read to exit before the timeout expires.
+		w.Write(make([]byte, count))
 		r.Close()
 	}()
 
diff --git a/src/os/rawconn.go b/src/os/rawconn.go
index 9e11cda..ffc598b 100644
--- a/src/os/rawconn.go
+++ b/src/os/rawconn.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !plan9
 // +build !plan9
 
 package os
diff --git a/src/os/rawconn_test.go b/src/os/rawconn_test.go
index 2554f5b..8aebaf8 100644
--- a/src/os/rawconn_test.go
+++ b/src/os/rawconn_test.go
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // Test use of raw connections.
+//go:build !plan9 && !js
 // +build !plan9,!js
 
 package os_test
diff --git a/src/os/readfrom_linux_test.go b/src/os/readfrom_linux_test.go
index 1d145da..cb6a59a 100644
--- a/src/os/readfrom_linux_test.go
+++ b/src/os/readfrom_linux_test.go
@@ -106,7 +106,7 @@
 				t.Fatal(err)
 			}
 			if n != int64(len(data)) {
-				t.Fatalf("transfered %d, want %d", n, len(data))
+				t.Fatalf("transferred %d, want %d", n, len(data))
 			}
 			if !hook.called {
 				t.Fatalf("should have called poll.CopyFileRange")
@@ -130,7 +130,7 @@
 				t.Fatal(err)
 			}
 			if n != int64(len(data)) {
-				t.Fatalf("transfered %d, want %d", n, len(data))
+				t.Fatalf("transferred %d, want %d", n, len(data))
 			}
 			if !hook.called {
 				t.Fatalf("should have called poll.CopyFileRange")
@@ -162,7 +162,7 @@
 				t.Fatal(err)
 			}
 			if n != int64(len(data)) {
-				t.Fatalf("transfered %d, want %d", n, len(data))
+				t.Fatalf("transferred %d, want %d", n, len(data))
 			}
 			if !hook.called {
 				t.Fatalf("should have called poll.CopyFileRange")
diff --git a/src/os/readfrom_stub.go b/src/os/readfrom_stub.go
index 65429d0..826760f 100644
--- a/src/os/readfrom_stub.go
+++ b/src/os/readfrom_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !linux
 // +build !linux
 
 package os
diff --git a/src/os/removeall_at.go b/src/os/removeall_at.go
index c1a1b72..d04540b 100644
--- a/src/os/removeall_at.go
+++ b/src/os/removeall_at.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package os
diff --git a/src/os/removeall_noat.go b/src/os/removeall_noat.go
index 7c888ba..853e0ed 100644
--- a/src/os/removeall_noat.go
+++ b/src/os/removeall_noat.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris
 // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
 
 package os
diff --git a/src/os/removeall_test.go b/src/os/removeall_test.go
index 3a2f6e3..08dfdd8 100644
--- a/src/os/removeall_test.go
+++ b/src/os/removeall_test.go
@@ -15,12 +15,7 @@
 )
 
 func TestRemoveAll(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "TestRemoveAll-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer RemoveAll(tmpDir)
-
+	tmpDir := t.TempDir()
 	if err := RemoveAll(""); err != nil {
 		t.Errorf("RemoveAll(\"\"): %v; want nil", err)
 	}
@@ -128,12 +123,7 @@
 		t.Skip("skipping in short mode")
 	}
 
-	tmpDir, err := os.MkdirTemp("", "TestRemoveAll-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer RemoveAll(tmpDir)
-
+	tmpDir := t.TempDir()
 	path := filepath.Join(tmpDir, "_TestRemoveAllLarge_")
 
 	// Make directory with 1000 files and remove.
@@ -236,12 +226,7 @@
 func TestRemoveAllDotDot(t *testing.T) {
 	t.Parallel()
 
-	tempDir, err := os.MkdirTemp("", "TestRemoveAllDotDot-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer RemoveAll(tempDir)
-
+	tempDir := t.TempDir()
 	subdir := filepath.Join(tempDir, "x")
 	subsubdir := filepath.Join(subdir, "y")
 	if err := MkdirAll(subsubdir, 0777); err != nil {
@@ -261,12 +246,7 @@
 func TestRemoveReadOnlyDir(t *testing.T) {
 	t.Parallel()
 
-	tempDir, err := os.MkdirTemp("", "TestRemoveReadOnlyDir-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer RemoveAll(tempDir)
-
+	tempDir := t.TempDir()
 	subdir := filepath.Join(tempDir, "x")
 	if err := Mkdir(subdir, 0); err != nil {
 		t.Fatal(err)
@@ -298,12 +278,7 @@
 
 	t.Parallel()
 
-	tempDir, err := os.MkdirTemp("", "TestRemoveAllButReadOnly-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer RemoveAll(tempDir)
-
+	tempDir := t.TempDir()
 	dirs := []string{
 		"a",
 		"a/x",
@@ -347,7 +322,7 @@
 		defer Chmod(d, 0777)
 	}
 
-	err = RemoveAll(tempDir)
+	err := RemoveAll(tempDir)
 	if err == nil {
 		t.Fatal("RemoveAll succeeded unexpectedly")
 	}
@@ -389,12 +364,7 @@
 
 	t.Parallel()
 
-	tempDir, err := os.MkdirTemp("", "TestRemoveAllButReadOnly-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer RemoveAll(tempDir)
-
+	tempDir := t.TempDir()
 	target := filepath.Join(tempDir, "d0", "d1", "d2")
 	if err := MkdirAll(target, 0755); err != nil {
 		t.Fatal(err)
@@ -413,12 +383,7 @@
 		t.Skip("skipping in short mode")
 	}
 
-	tmpDir, err := os.MkdirTemp("", "TestRemoveAll-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer RemoveAll(tmpDir)
-
+	tmpDir := t.TempDir()
 	path := filepath.Join(tmpDir, "_TestRemoveAllWithMoreErrorThanReqSize_")
 
 	// Make directory with 1025 read-only files.
@@ -443,7 +408,7 @@
 
 	// This call should not hang, even on a platform that disallows file deletion
 	// from read-only directories.
-	err = RemoveAll(path)
+	err := RemoveAll(path)
 
 	if Getuid() == 0 {
 		// On many platforms, root can remove files from read-only directories.
diff --git a/src/os/signal/doc.go b/src/os/signal/doc.go
index 2229d36..7af61d2 100644
--- a/src/os/signal/doc.go
+++ b/src/os/signal/doc.go
@@ -50,7 +50,7 @@
 If the Go program is started with a non-empty signal mask, that will
 generally be honored. However, some signals are explicitly unblocked:
 the synchronous signals, SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF,
-and, on GNU/Linux, signals 32 (SIGCANCEL) and 33 (SIGSETXID)
+and, on Linux, signals 32 (SIGCANCEL) and 33 (SIGSETXID)
 (SIGCANCEL and SIGSETXID are used internally by glibc). Subprocesses
 started by os.Exec, or by the os/exec package, will inherit the
 modified signal mask.
@@ -129,9 +129,7 @@
 SA_ONSTACK flag with sigaction. Failing to do so is likely to cause
 the program to crash if the signal is received. Go programs routinely
 run with a limited stack, and therefore set up an alternate signal
-stack. Also, the Go standard library expects that any signal handlers
-will use the SA_RESTART flag. Failing to do so may cause some library
-calls to return "interrupted system call" errors.
+stack.
 
 If the non-Go code installs a signal handler for any of the
 synchronous signals (SIGBUS, SIGFPE, SIGSEGV), then it should record
@@ -178,7 +176,7 @@
 shared library is loaded.
 
 If the Go runtime sees an existing signal handler for the SIGCANCEL or
-SIGSETXID signals (which are used only on GNU/Linux), it will turn on
+SIGSETXID signals (which are used only on Linux), it will turn on
 the SA_ONSTACK flag and otherwise keep the signal handler.
 
 For the synchronous signals and SIGPIPE, the Go runtime will install a
diff --git a/src/os/signal/example_unix_test.go b/src/os/signal/example_unix_test.go
index a0af37a..3f7795b 100644
--- a/src/os/signal/example_unix_test.go
+++ b/src/os/signal/example_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package signal_test
diff --git a/src/os/signal/internal/pty/pty.go b/src/os/signal/internal/pty/pty.go
index f8813ce..8d2eac7 100644
--- a/src/os/signal/internal/pty/pty.go
+++ b/src/os/signal/internal/pty/pty.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (aix || darwin || dragonfly || freebsd || (linux && !android) || netbsd || openbsd) && cgo
 // +build aix darwin dragonfly freebsd linux,!android netbsd openbsd
 // +build cgo
 
diff --git a/src/os/signal/signal_cgo_test.go b/src/os/signal/signal_cgo_test.go
index a8a4856..e1e4509 100644
--- a/src/os/signal/signal_cgo_test.go
+++ b/src/os/signal/signal_cgo_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (darwin || dragonfly || freebsd || (linux && !android) || netbsd || openbsd) && cgo
 // +build darwin dragonfly freebsd linux,!android netbsd openbsd
 // +build cgo
 
diff --git a/src/os/signal/signal_linux_test.go b/src/os/signal/signal_linux_test.go
index 2e553d0..7abe1ec 100644
--- a/src/os/signal/signal_linux_test.go
+++ b/src/os/signal/signal_linux_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux
 // +build linux
 
 package signal
diff --git a/src/os/signal/signal_plan9_test.go b/src/os/signal/signal_plan9_test.go
index 10bfdc3..8357199 100644
--- a/src/os/signal/signal_plan9_test.go
+++ b/src/os/signal/signal_plan9_test.go
@@ -5,6 +5,7 @@
 package signal
 
 import (
+	"internal/itoa"
 	"os"
 	"runtime"
 	"syscall"
@@ -155,23 +156,8 @@
 	}
 }
 
-func itoa(val int) string {
-	if val < 0 {
-		return "-" + itoa(-val)
-	}
-	var buf [32]byte // big enough for int64
-	i := len(buf) - 1
-	for val >= 10 {
-		buf[i] = byte(val%10 + '0')
-		i--
-		val /= 10
-	}
-	buf[i] = byte(val + '0')
-	return string(buf[i:])
-}
-
 func postNote(pid int, note string) error {
-	f, err := os.OpenFile("/proc/"+itoa(pid)+"/note", os.O_WRONLY, 0)
+	f, err := os.OpenFile("/proc/"+itoa.Itoa(pid)+"/note", os.O_WRONLY, 0)
 	if err != nil {
 		return err
 	}
diff --git a/src/os/signal/signal_test.go b/src/os/signal/signal_test.go
index bbc68af..649854b 100644
--- a/src/os/signal/signal_test.go
+++ b/src/os/signal/signal_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package signal
@@ -15,7 +16,9 @@
 	"os"
 	"os/exec"
 	"runtime"
+	"runtime/trace"
 	"strconv"
+	"strings"
 	"sync"
 	"syscall"
 	"testing"
@@ -29,6 +32,11 @@
 // The current value is set based on flakes observed in the Go builders.
 var settleTime = 100 * time.Millisecond
 
+// fatalWaitingTime is an absurdly long time to wait for signals to be
+// delivered but, using it, we (hopefully) eliminate test flakes on the
+// build servers. See #46736 for discussion.
+var fatalWaitingTime = 30 * time.Second
+
 func init() {
 	if testenv.Builder() == "solaris-amd64-oraclerel" {
 		// The solaris-amd64-oraclerel builder has been observed to time out in
@@ -45,6 +53,13 @@
 		//
 		// See https://golang.org/issue/33174.
 		settleTime = 11 * time.Second
+	} else if runtime.GOOS == "linux" && strings.HasPrefix(runtime.GOARCH, "ppc64") {
+		// Older linux kernels seem to have some hiccups delivering the signal
+		// in a timely manner on ppc64 and ppc64le. When running on a
+		// ppc64le/ubuntu 16.04/linux 4.4 host the time can vary quite
+		// substantially even on a idle system. 5 seconds is twice any value
+		// observed when running 10000 tests on such a system.
+		settleTime = 5 * time.Second
 	} else if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" {
 		if scale, err := strconv.Atoi(s); err == nil {
 			settleTime *= time.Duration(scale)
@@ -74,7 +89,7 @@
 	// General user code should filter out all unexpected signals instead of just
 	// SIGURG, but since os/signal is tightly coupled to the runtime it seems
 	// appropriate to be stricter here.
-	for time.Since(start) < settleTime {
+	for time.Since(start) < fatalWaitingTime {
 		select {
 		case s := <-c:
 			if s == sig {
@@ -87,7 +102,7 @@
 			timer.Reset(settleTime / 10)
 		}
 	}
-	t.Fatalf("timeout after %v waiting for %v", settleTime, sig)
+	t.Fatalf("timeout after %v waiting for %v", fatalWaitingTime, sig)
 }
 
 // quiesce waits until we can be reasonably confident that all pending signals
@@ -853,3 +868,44 @@
 		t.Errorf("c.String() = %q, want %q", got, want)
 	}
 }
+
+// #44193 test signal handling while stopping and starting the world.
+func TestSignalTrace(t *testing.T) {
+	done := make(chan struct{})
+	quit := make(chan struct{})
+	c := make(chan os.Signal, 1)
+	Notify(c, syscall.SIGHUP)
+
+	// Source and sink for signals busy loop unsynchronized with
+	// trace starts and stops. We are ultimately validating that
+	// signals and runtime.(stop|start)TheWorldGC are compatible.
+	go func() {
+		defer close(done)
+		defer Stop(c)
+		pid := syscall.Getpid()
+		for {
+			select {
+			case <-quit:
+				return
+			default:
+				syscall.Kill(pid, syscall.SIGHUP)
+			}
+			waitSig(t, c, syscall.SIGHUP)
+		}
+	}()
+
+	for i := 0; i < 100; i++ {
+		buf := new(bytes.Buffer)
+		if err := trace.Start(buf); err != nil {
+			t.Fatalf("[%d] failed to start tracing: %v", i, err)
+		}
+		time.After(1 * time.Microsecond)
+		trace.Stop()
+		size := buf.Len()
+		if size == 0 {
+			t.Fatalf("[%d] trace is empty", i)
+		}
+	}
+	close(quit)
+	<-done
+}
diff --git a/src/os/signal/signal_unix.go b/src/os/signal/signal_unix.go
index 90a1eca..9e241c4 100644
--- a/src/os/signal/signal_unix.go
+++ b/src/os/signal/signal_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package signal
diff --git a/src/os/signal/signal_windows_test.go b/src/os/signal/signal_windows_test.go
index 4640428..9b14551 100644
--- a/src/os/signal/signal_windows_test.go
+++ b/src/os/signal/signal_windows_test.go
@@ -56,11 +56,7 @@
 	}
 }
 `
-	tmp, err := os.MkdirTemp("", "TestCtrlBreak")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer os.RemoveAll(tmp)
+	tmp := t.TempDir()
 
 	// write ctrlbreak.go
 	name := filepath.Join(tmp, "ctlbreak")
diff --git a/src/os/stat_js.go b/src/os/stat_js.go
index 8d20ccd..3badf5b 100644
--- a/src/os/stat_js.go
+++ b/src/os/stat_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package os
diff --git a/src/os/stat_test.go b/src/os/stat_test.go
index c409f0f..8d99f64 100644
--- a/src/os/stat_test.go
+++ b/src/os/stat_test.go
@@ -185,30 +185,22 @@
 func TestDirAndSymlinkStats(t *testing.T) {
 	testenv.MustHaveSymlink(t)
 
-	tmpdir, err := os.MkdirTemp("", "TestDirAndSymlinkStats")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
-
+	tmpdir := t.TempDir()
 	dir := filepath.Join(tmpdir, "dir")
-	err = os.Mkdir(dir, 0777)
-	if err != nil {
+	if err := os.Mkdir(dir, 0777); err != nil {
 		t.Fatal(err)
 	}
 	testDirStats(t, dir)
 
 	dirlink := filepath.Join(tmpdir, "link")
-	err = os.Symlink(dir, dirlink)
-	if err != nil {
+	if err := os.Symlink(dir, dirlink); err != nil {
 		t.Fatal(err)
 	}
 	testSymlinkStats(t, dirlink, true)
 	testSymlinkSameFile(t, dir, dirlink)
 
 	linklink := filepath.Join(tmpdir, "linklink")
-	err = os.Symlink(dirlink, linklink)
-	if err != nil {
+	if err := os.Symlink(dirlink, linklink); err != nil {
 		t.Fatal(err)
 	}
 	testSymlinkStats(t, linklink, true)
@@ -218,30 +210,22 @@
 func TestFileAndSymlinkStats(t *testing.T) {
 	testenv.MustHaveSymlink(t)
 
-	tmpdir, err := os.MkdirTemp("", "TestFileAndSymlinkStats")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
-
+	tmpdir := t.TempDir()
 	file := filepath.Join(tmpdir, "file")
-	err = os.WriteFile(file, []byte(""), 0644)
-	if err != nil {
+	if err := os.WriteFile(file, []byte(""), 0644); err != nil {
 		t.Fatal(err)
 	}
 	testFileStats(t, file)
 
 	filelink := filepath.Join(tmpdir, "link")
-	err = os.Symlink(file, filelink)
-	if err != nil {
+	if err := os.Symlink(file, filelink); err != nil {
 		t.Fatal(err)
 	}
 	testSymlinkStats(t, filelink, false)
 	testSymlinkSameFile(t, file, filelink)
 
 	linklink := filepath.Join(tmpdir, "linklink")
-	err = os.Symlink(filelink, linklink)
-	if err != nil {
+	if err := os.Symlink(filelink, linklink); err != nil {
 		t.Fatal(err)
 	}
 	testSymlinkStats(t, linklink, false)
@@ -252,20 +236,13 @@
 func TestSymlinkWithTrailingSlash(t *testing.T) {
 	testenv.MustHaveSymlink(t)
 
-	tmpdir, err := os.MkdirTemp("", "TestSymlinkWithTrailingSlash")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
-
+	tmpdir := t.TempDir()
 	dir := filepath.Join(tmpdir, "dir")
-	err = os.Mkdir(dir, 0777)
-	if err != nil {
+	if err := os.Mkdir(dir, 0777); err != nil {
 		t.Fatal(err)
 	}
 	dirlink := filepath.Join(tmpdir, "link")
-	err = os.Symlink(dir, dirlink)
-	if err != nil {
+	if err := os.Symlink(dir, dirlink); err != nil {
 		t.Fatal(err)
 	}
 	dirlinkWithSlash := dirlink + string(os.PathSeparator)
diff --git a/src/os/stat_unix.go b/src/os/stat_unix.go
index 66c356f..8c17805 100644
--- a/src/os/stat_unix.go
+++ b/src/os/stat_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package os
diff --git a/src/os/sticky_bsd.go b/src/os/sticky_bsd.go
index c09b1ac..ab23d81 100644
--- a/src/os/sticky_bsd.go
+++ b/src/os/sticky_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm netbsd openbsd solaris
 
 package os
diff --git a/src/os/sticky_notbsd.go b/src/os/sticky_notbsd.go
index c158506..9979b43 100644
--- a/src/os/sticky_notbsd.go
+++ b/src/os/sticky_notbsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !aix && !darwin && !dragonfly && !freebsd && (!js || !wasm) && !netbsd && !openbsd && !solaris
 // +build !aix
 // +build !darwin
 // +build !dragonfly
diff --git a/src/os/str.go b/src/os/str.go
index cba9fa3..35643e0 100644
--- a/src/os/str.go
+++ b/src/os/str.go
@@ -6,28 +6,34 @@
 
 package os
 
-// Convert integer to decimal string
-func itoa(val int) string {
+// itox converts val (an int) to a hexdecimal string.
+func itox(val int) string {
 	if val < 0 {
-		return "-" + uitoa(uint(-val))
+		return "-" + uitox(uint(-val))
 	}
-	return uitoa(uint(val))
+	return uitox(uint(val))
 }
 
-// Convert unsigned integer to decimal string
-func uitoa(val uint) string {
+const hex = "0123456789abcdef"
+
+// uitox converts val (a uint) to a hexdecimal string.
+func uitox(val uint) string {
 	if val == 0 { // avoid string allocation
-		return "0"
+		return "0x0"
 	}
-	var buf [20]byte // big enough for 64bit value base 10
+	var buf [20]byte // big enough for 64bit value base 16 + 0x
 	i := len(buf) - 1
-	for val >= 10 {
-		q := val / 10
-		buf[i] = byte('0' + val - q*10)
+	for val >= 16 {
+		q := val / 16
+		buf[i] = hex[val%16]
 		i--
 		val = q
 	}
-	// val < 10
-	buf[i] = byte('0' + val)
+	// val < 16
+	buf[i] = hex[val%16]
+	i--
+	buf[i] = 'x'
+	i--
+	buf[i] = '0'
 	return string(buf[i:])
 }
diff --git a/src/os/sys_bsd.go b/src/os/sys_bsd.go
index b1698f5..1e245eb 100644
--- a/src/os/sys_bsd.go
+++ b/src/os/sys_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || (js && wasm) || netbsd || openbsd
 // +build darwin dragonfly freebsd js,wasm netbsd openbsd
 
 package os
diff --git a/src/os/sys_js.go b/src/os/sys_js.go
index e860654..4d6a64e 100644
--- a/src/os/sys_js.go
+++ b/src/os/sys_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package os
diff --git a/src/os/sys_unix.go b/src/os/sys_unix.go
index 8491bad..e316eaf 100644
--- a/src/os/sys_unix.go
+++ b/src/os/sys_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package os
diff --git a/src/os/tempfile.go b/src/os/tempfile.go
index 1ad44f1..5b681fc 100644
--- a/src/os/tempfile.go
+++ b/src/os/tempfile.go
@@ -4,7 +4,10 @@
 
 package os
 
-import "errors"
+import (
+	"errors"
+	"internal/itoa"
+)
 
 // fastrand provided by runtime.
 // We generate random temporary file names so that there's a good
@@ -13,7 +16,7 @@
 func fastrand() uint32
 
 func nextRandom() string {
-	return uitoa(uint(fastrand()))
+	return itoa.Uitoa(uint(fastrand()))
 }
 
 // CreateTemp creates a new temporary file in the directory dir,
diff --git a/src/os/timeout_test.go b/src/os/timeout_test.go
index 0a39f46..6d65e42 100644
--- a/src/os/timeout_test.go
+++ b/src/os/timeout_test.go
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !js
-// +build !plan9
-// +build !windows
+//go:build !js && !plan9 && !windows
+// +build !js,!plan9,!windows
 
 package os_test
 
diff --git a/src/os/types_unix.go b/src/os/types_unix.go
index c0259ae..e9b8b8b 100644
--- a/src/os/types_unix.go
+++ b/src/os/types_unix.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !windows
-// +build !plan9
+//go:build !windows && !plan9
+// +build !windows,!plan9
 
 package os
 
diff --git a/src/os/user/cgo_lookup_unix.go b/src/os/user/cgo_lookup_unix.go
index 3307f79..abc9e9c 100644
--- a/src/os/user/cgo_lookup_unix.go
+++ b/src/os/user/cgo_lookup_unix.go
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (aix || darwin || dragonfly || freebsd || (!android && linux) || netbsd || openbsd || solaris) && cgo && !osusergo
 // +build aix darwin dragonfly freebsd !android,linux netbsd openbsd solaris
-// +build cgo,!osusergo
+// +build cgo
+// +build !osusergo
 
 package user
 
diff --git a/src/os/user/cgo_unix_test.go b/src/os/user/cgo_unix_test.go
index 1d341aa..9ec32b3 100644
--- a/src/os/user/cgo_unix_test.go
+++ b/src/os/user/cgo_unix_test.go
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (darwin || dragonfly || freebsd || (!android && linux) || netbsd || openbsd || solaris) && cgo && !osusergo
 // +build darwin dragonfly freebsd !android,linux netbsd openbsd solaris
-// +build cgo,!osusergo
+// +build cgo
+// +build !osusergo
 
 package user
 
diff --git a/src/os/user/getgrouplist_darwin.go b/src/os/user/getgrouplist_darwin.go
index e8fe26c..23d12e3 100644
--- a/src/os/user/getgrouplist_darwin.go
+++ b/src/os/user/getgrouplist_darwin.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo && !osusergo
 // +build cgo,!osusergo
 
 package user
diff --git a/src/os/user/getgrouplist_unix.go b/src/os/user/getgrouplist_unix.go
index 9685414..fd66961 100644
--- a/src/os/user/getgrouplist_unix.go
+++ b/src/os/user/getgrouplist_unix.go
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build dragonfly freebsd !android,linux netbsd openbsd
-// +build cgo,!osusergo
+//go:build (dragonfly || freebsd || (!android && linux) || netbsd || openbsd || (solaris && !illumos)) && cgo && !osusergo
+// +build dragonfly freebsd !android,linux netbsd openbsd solaris,!illumos
+// +build cgo
+// +build !osusergo
 
 package user
 
diff --git a/src/os/user/listgroups_aix.go b/src/os/user/listgroups_aix.go
index 17de3e9..d2fdfdc 100644
--- a/src/os/user/listgroups_aix.go
+++ b/src/os/user/listgroups_aix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo && !osusergo
 // +build cgo,!osusergo
 
 package user
diff --git a/src/os/user/listgroups_illumos.go b/src/os/user/listgroups_illumos.go
new file mode 100644
index 0000000..d25e033
--- /dev/null
+++ b/src/os/user/listgroups_illumos.go
@@ -0,0 +1,18 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build cgo && !osusergo
+// +build cgo,!osusergo
+
+// Even though this file requires no C, it is used to provide a
+// listGroup stub because all the other illumos calls work.  Otherwise,
+// this stub will conflict with the lookup_stubs.go fallback.
+
+package user
+
+import "fmt"
+
+func listGroups(u *User) ([]string, error) {
+	return nil, fmt.Errorf("user: list groups for %s: not supported on illumos", u.Username)
+}
diff --git a/src/os/user/listgroups_solaris.go b/src/os/user/listgroups_solaris.go
deleted file mode 100644
index f3cbf6c..0000000
--- a/src/os/user/listgroups_solaris.go
+++ /dev/null
@@ -1,17 +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.
-
-// +build cgo,!osusergo
-
-// Even though this file requires no C, it is used to provide a
-// listGroup stub because all the other Solaris calls work.  Otherwise,
-// this stub will conflict with the lookup_stubs.go fallback.
-
-package user
-
-import "fmt"
-
-func listGroups(u *User) ([]string, error) {
-	return nil, fmt.Errorf("user: list groups for %s: not supported on Solaris", u.Username)
-}
diff --git a/src/os/user/listgroups_unix.go b/src/os/user/listgroups_unix.go
index 70f7af7..38aa765 100644
--- a/src/os/user/listgroups_unix.go
+++ b/src/os/user/listgroups_unix.go
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build dragonfly darwin freebsd !android,linux netbsd openbsd
-// +build cgo,!osusergo
+//go:build (dragonfly || darwin || freebsd || (!android && linux) || netbsd || openbsd || (solaris && !illumos)) && cgo && !osusergo
+// +build dragonfly darwin freebsd !android,linux netbsd openbsd solaris,!illumos
+// +build cgo
+// +build !osusergo
 
 package user
 
diff --git a/src/os/user/lookup_android.go b/src/os/user/lookup_android.go
index 8ca30b8..151aab4 100644
--- a/src/os/user/lookup_android.go
+++ b/src/os/user/lookup_android.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build android
 // +build android
 
 package user
diff --git a/src/os/user/lookup_stubs.go b/src/os/user/lookup_stubs.go
index 178d814..c975a11 100644
--- a/src/os/user/lookup_stubs.go
+++ b/src/os/user/lookup_stubs.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (!cgo && !windows && !plan9) || android || (osusergo && !windows && !plan9)
 // +build !cgo,!windows,!plan9 android osusergo,!windows,!plan9
 
 package user
diff --git a/src/os/user/lookup_unix.go b/src/os/user/lookup_unix.go
index 0890cd8..97c611f 100644
--- a/src/os/user/lookup_unix.go
+++ b/src/os/user/lookup_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (aix || darwin || dragonfly || freebsd || (js && wasm) || (!android && linux) || netbsd || openbsd || solaris) && (!cgo || osusergo)
 // +build aix darwin dragonfly freebsd js,wasm !android,linux netbsd openbsd solaris
 // +build !cgo osusergo
 
@@ -32,23 +33,72 @@
 // readColonFile parses r as an /etc/group or /etc/passwd style file, running
 // fn for each row. readColonFile returns a value, an error, or (nil, nil) if
 // the end of the file is reached without a match.
-func readColonFile(r io.Reader, fn lineFunc) (v interface{}, err error) {
-	bs := bufio.NewScanner(r)
-	for bs.Scan() {
-		line := bs.Bytes()
+//
+// readCols is the minimum number of colon-separated fields that will be passed
+// to fn; in a long line additional fields may be silently discarded.
+func readColonFile(r io.Reader, fn lineFunc, readCols int) (v interface{}, err error) {
+	rd := bufio.NewReader(r)
+
+	// Read the file line-by-line.
+	for {
+		var isPrefix bool
+		var wholeLine []byte
+
+		// Read the next line. We do so in chunks (as much as reader's
+		// buffer is able to keep), check if we read enough columns
+		// already on each step and store final result in wholeLine.
+		for {
+			var line []byte
+			line, isPrefix, err = rd.ReadLine()
+
+			if err != nil {
+				// We should return (nil, nil) if EOF is reached
+				// without a match.
+				if err == io.EOF {
+					err = nil
+				}
+				return nil, err
+			}
+
+			// Simple common case: line is short enough to fit in a
+			// single reader's buffer.
+			if !isPrefix && len(wholeLine) == 0 {
+				wholeLine = line
+				break
+			}
+
+			wholeLine = append(wholeLine, line...)
+
+			// Check if we read the whole line (or enough columns)
+			// already.
+			if !isPrefix || bytes.Count(wholeLine, []byte{':'}) >= readCols {
+				break
+			}
+		}
+
 		// There's no spec for /etc/passwd or /etc/group, but we try to follow
 		// the same rules as the glibc parser, which allows comments and blank
 		// space at the beginning of a line.
-		line = bytes.TrimSpace(line)
-		if len(line) == 0 || line[0] == '#' {
+		wholeLine = bytes.TrimSpace(wholeLine)
+		if len(wholeLine) == 0 || wholeLine[0] == '#' {
 			continue
 		}
-		v, err = fn(line)
+		v, err = fn(wholeLine)
 		if v != nil || err != nil {
 			return
 		}
+
+		// If necessary, skip the rest of the line
+		for ; isPrefix; _, isPrefix, err = rd.ReadLine() {
+			if err != nil {
+				// We should return (nil, nil) if EOF is reached without a match.
+				if err == io.EOF {
+					err = nil
+				}
+				return nil, err
+			}
+		}
 	}
-	return nil, bs.Err()
 }
 
 func matchGroupIndexValue(value string, idx int) lineFunc {
@@ -79,7 +129,7 @@
 }
 
 func findGroupId(id string, r io.Reader) (*Group, error) {
-	if v, err := readColonFile(r, matchGroupIndexValue(id, 2)); err != nil {
+	if v, err := readColonFile(r, matchGroupIndexValue(id, 2), 3); err != nil {
 		return nil, err
 	} else if v != nil {
 		return v.(*Group), nil
@@ -88,7 +138,7 @@
 }
 
 func findGroupName(name string, r io.Reader) (*Group, error) {
-	if v, err := readColonFile(r, matchGroupIndexValue(name, 0)); err != nil {
+	if v, err := readColonFile(r, matchGroupIndexValue(name, 0), 3); err != nil {
 		return nil, err
 	} else if v != nil {
 		return v.(*Group), nil
@@ -143,7 +193,7 @@
 	if e != nil {
 		return nil, errors.New("user: invalid userid " + uid)
 	}
-	if v, err := readColonFile(r, matchUserIndexValue(uid, 2)); err != nil {
+	if v, err := readColonFile(r, matchUserIndexValue(uid, 2), 6); err != nil {
 		return nil, err
 	} else if v != nil {
 		return v.(*User), nil
@@ -152,7 +202,7 @@
 }
 
 func findUsername(name string, r io.Reader) (*User, error) {
-	if v, err := readColonFile(r, matchUserIndexValue(name, 0)); err != nil {
+	if v, err := readColonFile(r, matchUserIndexValue(name, 0), 6); err != nil {
 		return nil, err
 	} else if v != nil {
 		return v.(*User), nil
diff --git a/src/os/user/lookup_unix_test.go b/src/os/user/lookup_unix_test.go
index 72d3b47..060cfe1 100644
--- a/src/os/user/lookup_unix_test.go
+++ b/src/os/user/lookup_unix_test.go
@@ -2,18 +2,20 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (aix || darwin || dragonfly || freebsd || (!android && linux) || netbsd || openbsd || solaris) && !cgo
 // +build aix darwin dragonfly freebsd !android,linux netbsd openbsd solaris
 // +build !cgo
 
 package user
 
 import (
+	"fmt"
 	"reflect"
 	"strings"
 	"testing"
 )
 
-const testGroupFile = `# See the opendirectoryd(8) man page for additional 
+var testGroupFile = `# See the opendirectoryd(8) man page for additional 
 # information about Open Directory.
 ##
 nobody:*:-2:
@@ -29,7 +31,7 @@
 # comment:*:4:found
      # comment:*:4:found
 kmem:*:2:root
-`
+` + largeGroup()
 
 var groupTests = []struct {
 	in   string
@@ -48,9 +50,20 @@
 	{testGroupFile, "invalidgid", ""},
 	{testGroupFile, "indented", "7"},
 	{testGroupFile, "# comment", ""},
+	{testGroupFile, "largegroup", "1000"},
 	{"", "emptyfile", ""},
 }
 
+// Generate a proper "largegroup" entry for testGroupFile string
+func largeGroup() (res string) {
+	var b strings.Builder
+	b.WriteString("largegroup:x:1000:user1")
+	for i := 2; i <= 7500; i++ {
+		fmt.Fprintf(&b, ",user%d", i)
+	}
+	return b.String()
+}
+
 func TestFindGroupName(t *testing.T) {
 	for _, tt := range groupTests {
 		got, err := findGroupName(tt.name, strings.NewReader(tt.in))
diff --git a/src/os/user/user_test.go b/src/os/user/user_test.go
index 8c4c817..4992031 100644
--- a/src/os/user/user_test.go
+++ b/src/os/user/user_test.go
@@ -132,7 +132,7 @@
 	if runtime.GOOS == "aix" {
 		t.Skip("skipping GroupIds, see golang.org/issue/30563")
 	}
-	if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" {
+	if runtime.GOOS == "illumos" {
 		t.Skip("skipping GroupIds, see golang.org/issue/14709")
 	}
 	user, err := Current()
diff --git a/src/os/wait_unimp.go b/src/os/wait_unimp.go
index 0f4cdc4..9bb85da 100644
--- a/src/os/wait_unimp.go
+++ b/src/os/wait_unimp.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin dragonfly js,wasm netbsd openbsd solaris
+//go:build aix || darwin || (js && wasm) || openbsd || solaris
+// +build aix darwin js,wasm openbsd solaris
 
 package os
 
diff --git a/src/os/wait_wait6.go b/src/os/wait_wait6.go
index 5420b2d..45b370a 100644
--- a/src/os/wait_wait6.go
+++ b/src/os/wait_wait6.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build freebsd
+//go:build dragonfly || freebsd || netbsd
+// +build dragonfly freebsd netbsd
 
 package os
 
@@ -22,9 +23,9 @@
 		// The arguments on 32-bit FreeBSD look like the following:
 		// - freebsd32_wait6_args{ idtype, id1, id2, status, options, wrusage, info } or
 		// - freebsd32_wait6_args{ idtype, pad, id1, id2, status, options, wrusage, info } when PAD64_REQUIRED=1 on ARM, MIPS or PowerPC
-		if runtime.GOARCH == "386" {
+		if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" {
 			_, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0, 0)
-		} else if runtime.GOARCH == "arm" {
+		} else if runtime.GOOS == "freebsd" && runtime.GOARCH == "arm" {
 			_, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, 0, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0)
 		} else {
 			_, _, errno = syscall.Syscall6(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0)
@@ -34,7 +35,9 @@
 		}
 	}
 	runtime.KeepAlive(p)
-	if errno != 0 {
+	if errno == syscall.ENOSYS {
+		return false, nil
+	} else if errno != 0 {
 		return false, NewSyscallError("wait6", errno)
 	}
 	return true, nil
diff --git a/src/os/wait_waitid.go b/src/os/wait_waitid.go
index 9c56eb2..44962c8 100644
--- a/src/os/wait_waitid.go
+++ b/src/os/wait_waitid.go
@@ -5,6 +5,7 @@
 // We used to used this code for Darwin, but according to issue #19314
 // waitid returns if the process is stopped, even when using WEXITED.
 
+//go:build linux
 // +build linux
 
 package os
@@ -22,7 +23,7 @@
 // It does not actually call p.Wait.
 func (p *Process) blockUntilWaitable() (bool, error) {
 	// The waitid system call expects a pointer to a siginfo_t,
-	// which is 128 bytes on all GNU/Linux systems.
+	// which is 128 bytes on all Linux systems.
 	// On darwin/amd64, it requires 104 bytes.
 	// We don't care about the values it returns.
 	var siginfo [16]uint64
diff --git a/src/path/filepath/example_unix_test.go b/src/path/filepath/example_unix_test.go
index c9d6944..4ce1009 100644
--- a/src/path/filepath/example_unix_test.go
+++ b/src/path/filepath/example_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows && !plan9
 // +build !windows,!plan9
 
 package filepath_test
diff --git a/src/path/filepath/example_unix_walk_test.go b/src/path/filepath/example_unix_walk_test.go
index c8a818f..d72efce 100644
--- a/src/path/filepath/example_unix_walk_test.go
+++ b/src/path/filepath/example_unix_walk_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows && !plan9
 // +build !windows,!plan9
 
 package filepath_test
diff --git a/src/path/filepath/match_test.go b/src/path/filepath/match_test.go
index 48880ea..375c41a 100644
--- a/src/path/filepath/match_test.go
+++ b/src/path/filepath/match_test.go
@@ -181,12 +181,7 @@
 func TestGlobSymlink(t *testing.T) {
 	testenv.MustHaveSymlink(t)
 
-	tmpDir, err := os.MkdirTemp("", "globsymlink")
-	if err != nil {
-		t.Fatal("creating temp dir:", err)
-	}
-	defer os.RemoveAll(tmpDir)
-
+	tmpDir := t.TempDir()
 	for _, tt := range globSymlinkTests {
 		path := Join(tmpDir, tt.path)
 		dest := Join(tmpDir, tt.dest)
@@ -267,18 +262,7 @@
 		t.Skipf("skipping windows specific test")
 	}
 
-	tmpDir, err := os.MkdirTemp("", "TestWindowsGlob")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpDir)
-
-	// /tmp may itself be a symlink
-	tmpDir, err = EvalSymlinks(tmpDir)
-	if err != nil {
-		t.Fatal("eval symlink for tmp dir:", err)
-	}
-
+	tmpDir := tempDirCanonical(t)
 	if len(tmpDir) < 3 {
 		t.Fatalf("tmpDir path %q is too short", tmpDir)
 	}
@@ -323,15 +307,13 @@
 	// test absolute paths
 	for _, test := range tests {
 		var p string
-		err = test.globAbs(tmpDir, tmpDir)
-		if err != nil {
+		if err := test.globAbs(tmpDir, tmpDir); err != nil {
 			t.Error(err)
 		}
 		// test C:\*Documents and Settings\...
 		p = tmpDir
 		p = strings.Replace(p, `:\`, `:\*`, 1)
-		err = test.globAbs(tmpDir, p)
-		if err != nil {
+		if err := test.globAbs(tmpDir, p); err != nil {
 			t.Error(err)
 		}
 		// test C:\Documents and Settings*\...
@@ -339,8 +321,7 @@
 		p = strings.Replace(p, `:\`, `:`, 1)
 		p = strings.Replace(p, `\`, `*\`, 1)
 		p = strings.Replace(p, `:`, `:\`, 1)
-		err = test.globAbs(tmpDir, p)
-		if err != nil {
+		if err := test.globAbs(tmpDir, p); err != nil {
 			t.Error(err)
 		}
 	}
diff --git a/src/path/filepath/path.go b/src/path/filepath/path.go
index 2e7b439..b56534d 100644
--- a/src/path/filepath/path.go
+++ b/src/path/filepath/path.go
@@ -275,7 +275,11 @@
 	targ = targ[len(targVol):]
 	if base == "." {
 		base = ""
+	} else if base == "" && volumeNameLen(baseVol) > 2 /* isUNC */ {
+		// Treat any targetpath matching `\\host\share` basepath as absolute path.
+		base = string(Separator)
 	}
+
 	// Can't use IsAbs - `\a` and `a` are both relative in Windows.
 	baseSlashed := len(base) > 0 && base[0] == Separator
 	targSlashed := len(targ) > 0 && targ[0] == Separator
@@ -336,7 +340,7 @@
 // as an error by any function.
 var SkipDir error = fs.SkipDir
 
-// WalkFunc is the type of the function called by Walk to visit each each
+// WalkFunc is the type of the function called by Walk to visit each
 // file or directory.
 //
 // The path argument contains the argument to Walk as a prefix.
diff --git a/src/path/filepath/path_test.go b/src/path/filepath/path_test.go
index 8616256..bc5509b 100644
--- a/src/path/filepath/path_test.go
+++ b/src/path/filepath/path_test.go
@@ -410,6 +410,25 @@
 	return nil
 }
 
+// chdir changes the current working directory to the named directory,
+// and then restore the original working directory at the end of the test.
+func chdir(t *testing.T, dir string) {
+	olddir, err := os.Getwd()
+	if err != nil {
+		t.Fatalf("getwd %s: %v", dir, err)
+	}
+	if err := os.Chdir(dir); err != nil {
+		t.Fatalf("chdir %s: %v", dir, err)
+	}
+
+	t.Cleanup(func() {
+		if err := os.Chdir(olddir); err != nil {
+			t.Errorf("restore original working directory %s: %v", olddir, err)
+			os.Exit(1)
+		}
+	})
+}
+
 func chtmpdir(t *testing.T) (restore func()) {
 	oldwd, err := os.Getwd()
 	if err != nil {
@@ -430,6 +449,19 @@
 	}
 }
 
+// tempDirCanonical returns a temporary directory for the test to use, ensuring
+// that the returned path does not contain symlinks.
+func tempDirCanonical(t *testing.T) string {
+	dir := t.TempDir()
+
+	cdir, err := filepath.EvalSymlinks(dir)
+	if err != nil {
+		t.Errorf("tempDirCanonical: %v", err)
+	}
+
+	return cdir
+}
+
 func TestWalk(t *testing.T) {
 	walk := func(root string, fn fs.WalkDirFunc) error {
 		return filepath.Walk(root, func(path string, info fs.FileInfo, err error) error {
@@ -458,11 +490,7 @@
 		defer restore()
 	}
 
-	tmpDir, err := os.MkdirTemp("", "TestWalk")
-	if err != nil {
-		t.Fatal("creating temp dir:", err)
-	}
-	defer os.RemoveAll(tmpDir)
+	tmpDir := t.TempDir()
 
 	origDir, err := os.Getwd()
 	if err != nil {
@@ -562,11 +590,7 @@
 }
 
 func TestWalkSkipDirOnFile(t *testing.T) {
-	td, err := os.MkdirTemp("", "walktest")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(td)
+	td := t.TempDir()
 
 	if err := os.MkdirAll(filepath.Join(td, "dir"), 0755); err != nil {
 		t.Fatal(err)
@@ -590,7 +614,7 @@
 	check := func(t *testing.T, walk func(root string) error, root string) {
 		t.Helper()
 		sawFoo2 = false
-		err = walk(root)
+		err := walk(root)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -612,11 +636,7 @@
 }
 
 func TestWalkFileError(t *testing.T) {
-	td, err := os.MkdirTemp("", "walktest")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(td)
+	td := t.TempDir()
 
 	touch(t, filepath.Join(td, "foo"))
 	touch(t, filepath.Join(td, "bar"))
@@ -637,7 +657,7 @@
 		return os.Lstat(path)
 	}
 	got := map[string]error{}
-	err = filepath.Walk(td, func(path string, fi fs.FileInfo, err error) error {
+	err := filepath.Walk(td, func(path string, fi fs.FileInfo, err error) error {
 		rel, _ := filepath.Rel(td, path)
 		got[filepath.ToSlash(rel)] = err
 		return nil
@@ -891,14 +911,11 @@
 func TestEvalSymlinks(t *testing.T) {
 	testenv.MustHaveSymlink(t)
 
-	tmpDir, err := os.MkdirTemp("", "evalsymlink")
-	if err != nil {
-		t.Fatal("creating temp dir:", err)
-	}
-	defer os.RemoveAll(tmpDir)
+	tmpDir := t.TempDir()
 
 	// /tmp may itself be a symlink! Avoid the confusion, although
 	// it means trusting the thing we're testing.
+	var err error
 	tmpDir, err = filepath.EvalSymlinks(tmpDir)
 	if err != nil {
 		t.Fatal("eval symlink for tmp dir:", err)
@@ -977,14 +994,10 @@
 func TestIssue13582(t *testing.T) {
 	testenv.MustHaveSymlink(t)
 
-	tmpDir, err := os.MkdirTemp("", "issue13582")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpDir)
+	tmpDir := t.TempDir()
 
 	dir := filepath.Join(tmpDir, "dir")
-	err = os.Mkdir(dir, 0755)
+	err := os.Mkdir(dir, 0755)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1064,12 +1077,7 @@
 }
 
 func TestAbs(t *testing.T) {
-	root, err := os.MkdirTemp("", "TestAbs")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer os.RemoveAll(root)
-
+	root := t.TempDir()
 	wd, err := os.Getwd()
 	if err != nil {
 		t.Fatal("getwd failed: ", err)
@@ -1135,11 +1143,7 @@
 // We test it separately from all other absTests because the empty string is not
 // a valid path, so it can't be used with os.Stat.
 func TestAbsEmptyString(t *testing.T) {
-	root, err := os.MkdirTemp("", "TestAbsEmptyString")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer os.RemoveAll(root)
+	root := t.TempDir()
 
 	wd, err := os.Getwd()
 	if err != nil {
@@ -1227,6 +1231,7 @@
 	{`C:\Projects`, `c:\projects\src`, `src`},
 	{`C:\Projects`, `c:\projects`, `.`},
 	{`C:\Projects\a\..`, `c:\projects`, `.`},
+	{`\\host\share`, `\\host\share\file.txt`, `file.txt`},
 }
 
 func TestRel(t *testing.T) {
@@ -1356,11 +1361,7 @@
 }
 
 func testWalkSymlink(t *testing.T, mklink func(target, link string) error) {
-	tmpdir, err := os.MkdirTemp("", "testWalkSymlink")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	wd, err := os.Getwd()
 	if err != nil {
@@ -1406,14 +1407,10 @@
 }
 
 func TestIssue29372(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "TestIssue29372")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpDir)
+	tmpDir := t.TempDir()
 
 	path := filepath.Join(tmpDir, "file.txt")
-	err = os.WriteFile(path, nil, 0644)
+	err := os.WriteFile(path, nil, 0644)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1442,11 +1439,7 @@
 
 	t.Parallel()
 
-	tmpDir, err := os.MkdirTemp("", "TestEvalSymlinksAboveRoot")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpDir)
+	tmpDir := t.TempDir()
 
 	evalTmpDir, err := filepath.EvalSymlinks(tmpDir)
 	if err != nil {
@@ -1476,11 +1469,16 @@
 	// Try different numbers of "..".
 	for _, i := range []int{c, c + 1, c + 2} {
 		check := strings.Join([]string{evalTmpDir, strings.Join(dd[:i], string(os.PathSeparator)), evalTmpDir[len(vol)+1:], "b", "file"}, string(os.PathSeparator))
-		if resolved, err := filepath.EvalSymlinks(check); err != nil {
+		resolved, err := filepath.EvalSymlinks(check)
+		switch {
+		case runtime.GOOS == "darwin" && errors.Is(err, fs.ErrNotExist):
+			// On darwin, the temp dir is sometimes cleaned up mid-test (issue 37910).
+			testenv.SkipFlaky(t, 37910)
+		case err != nil:
 			t.Errorf("EvalSymlinks(%q) failed: %v", check, err)
-		} else if !strings.HasSuffix(resolved, wantSuffix) {
+		case !strings.HasSuffix(resolved, wantSuffix):
 			t.Errorf("EvalSymlinks(%q) = %q does not end with %q", check, resolved, wantSuffix)
-		} else {
+		default:
 			t.Logf("EvalSymlinks(%q) = %q", check, resolved)
 		}
 	}
@@ -1495,16 +1493,7 @@
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(tmpDir)
-
-	wd, err := os.Getwd()
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.Chdir(wd)
-
-	if err := os.Chdir(tmpDir); err != nil {
-		t.Fatal(err)
-	}
+	chdir(t, tmpDir)
 
 	subdir := filepath.Join("a", "b")
 	if err := os.MkdirAll(subdir, 0777); err != nil {
diff --git a/src/path/filepath/path_unix.go b/src/path/filepath/path_unix.go
index ec497d9..d4b6f96 100644
--- a/src/path/filepath/path_unix.go
+++ b/src/path/filepath/path_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package filepath
diff --git a/src/path/filepath/path_windows_test.go b/src/path/filepath/path_windows_test.go
index 1c3d84c..76a459a 100644
--- a/src/path/filepath/path_windows_test.go
+++ b/src/path/filepath/path_windows_test.go
@@ -37,12 +37,7 @@
 		perm    fs.FileMode = 0700
 	)
 
-	tmp, err := os.MkdirTemp("", "testWinSplitListTestIsValid")
-	if err != nil {
-		t.Fatalf("TempDir failed: %v", err)
-	}
-	defer os.RemoveAll(tmp)
-
+	tmp := t.TempDir()
 	for i, d := range tt.result {
 		if d == "" {
 			continue
@@ -57,12 +52,12 @@
 			t.Errorf("%d,%d: %#q already exists", ti, i, d)
 			return
 		}
-		if err = os.MkdirAll(dd, perm); err != nil {
+		if err := os.MkdirAll(dd, perm); err != nil {
 			t.Errorf("%d,%d: MkdirAll(%#q) failed: %v", ti, i, dd, err)
 			return
 		}
 		fn, data := filepath.Join(dd, cmdfile), []byte("@echo "+d+"\r\n")
-		if err = os.WriteFile(fn, data, perm); err != nil {
+		if err := os.WriteFile(fn, data, perm); err != nil {
 			t.Errorf("%d,%d: WriteFile(%#q) failed: %v", ti, i, fn, err)
 			return
 		}
@@ -103,18 +98,7 @@
 func TestWindowsEvalSymlinks(t *testing.T) {
 	testenv.MustHaveSymlink(t)
 
-	tmpDir, err := os.MkdirTemp("", "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)
-	}
+	tmpDir := tempDirCanonical(t)
 
 	if len(tmpDir) < 3 {
 		t.Fatalf("tmpDir path %q is too short", tmpDir)
@@ -161,18 +145,7 @@
 // TestEvalSymlinksCanonicalNames verify that EvalSymlinks
 // returns "canonical" path names on windows.
 func TestEvalSymlinksCanonicalNames(t *testing.T) {
-	tmp, err := os.MkdirTemp("", "evalsymlinkcanonical")
-	if err != nil {
-		t.Fatal("creating temp dir:", err)
-	}
-	defer os.RemoveAll(tmp)
-
-	// os.MkdirTemp might return "non-canonical" name.
-	cTmpName, err := filepath.EvalSymlinks(tmp)
-	if err != nil {
-		t.Errorf("EvalSymlinks(%q) error: %v", tmp, err)
-	}
-
+	ctmp := tempDirCanonical(t)
 	dirs := []string{
 		"test",
 		"test/dir",
@@ -181,7 +154,7 @@
 	}
 
 	for _, d := range dirs {
-		dir := filepath.Join(cTmpName, d)
+		dir := filepath.Join(ctmp, d)
 		err := os.Mkdir(dir, 0755)
 		if err != nil {
 			t.Fatal(err)
@@ -417,25 +390,8 @@
 		{".", `\\localhost\c$`, `\\localhost\c$`},
 	}
 
-	tmp, err := os.MkdirTemp("", "testToNorm")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer func() {
-		err := os.RemoveAll(tmp)
-		if err != nil {
-			t.Fatal(err)
-		}
-	}()
-
-	// os.MkdirTemp might return "non-canonical" name.
-	ctmp, err := filepath.EvalSymlinks(tmp)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	err = os.MkdirAll(strings.ReplaceAll(testPath, "{{tmp}}", ctmp), 0777)
-	if err != nil {
+	ctmp := tempDirCanonical(t)
+	if err := os.MkdirAll(strings.ReplaceAll(testPath, "{{tmp}}", ctmp), 0777); err != nil {
 		t.Fatal(err)
 	}
 
@@ -526,20 +482,10 @@
 		t.Skip("skipping test because mklink command does not support junctions")
 	}
 
-	tmpdir, err := os.MkdirTemp("", "TestNTNamespaceSymlink")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
-
-	// Make sure tmpdir is not a symlink, otherwise tests will fail.
-	tmpdir, err = filepath.EvalSymlinks(tmpdir)
-	if err != nil {
-		t.Fatal(err)
-	}
+	tmpdir := tempDirCanonical(t)
 
 	vol := filepath.VolumeName(tmpdir)
-	output, err = exec.Command("cmd", "/c", "mountvol", vol, "/L").CombinedOutput()
+	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)
 	}
diff --git a/src/path/filepath/symlink_unix.go b/src/path/filepath/symlink_unix.go
index d20e63a..657945a 100644
--- a/src/path/filepath/symlink_unix.go
+++ b/src/path/filepath/symlink_unix.go
@@ -1,3 +1,4 @@
+//go:build !windows
 // +build !windows
 
 package filepath
diff --git a/src/plugin/plugin_dlopen.go b/src/plugin/plugin_dlopen.go
index 9200fdc..aa85d48 100644
--- a/src/plugin/plugin_dlopen.go
+++ b/src/plugin/plugin_dlopen.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (linux && cgo) || (darwin && cgo) || (freebsd && cgo)
 // +build linux,cgo darwin,cgo freebsd,cgo
 
 package plugin
diff --git a/src/plugin/plugin_stubs.go b/src/plugin/plugin_stubs.go
index 1893203..67855be 100644
--- a/src/plugin/plugin_stubs.go
+++ b/src/plugin/plugin_stubs.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (!linux && !freebsd && !darwin) || !cgo
 // +build !linux,!freebsd,!darwin !cgo
 
 package plugin
diff --git a/src/plugin/plugin_test.go b/src/plugin/plugin_test.go
index 30b79ed..4ce9121 100644
--- a/src/plugin/plugin_test.go
+++ b/src/plugin/plugin_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !linux || (linux && !arm64)
 // +build !linux linux,!arm64
 
 package plugin_test
diff --git a/src/race.bash b/src/race.bash
index e2b96bc..81fb4be 100755
--- a/src/race.bash
+++ b/src/race.bash
@@ -9,7 +9,7 @@
 set -e
 
 function usage {
-	echo 'race detector is only supported on linux/amd64, linux/ppc64le, linux/arm64, freebsd/amd64, netbsd/amd64, darwin/amd64, and darwin/arm64' 1>&2
+	echo 'race detector is only supported on linux/amd64, linux/ppc64le, linux/arm64, freebsd/amd64, netbsd/amd64, openbsd/amd64, darwin/amd64, and darwin/arm64' 1>&2
 	exit 1
 }
 
@@ -34,6 +34,11 @@
 		usage
 	fi
 	;;
+"OpenBSD")
+	if [ $(uname -m) != "amd64" ]; then
+		usage
+	fi
+	;;
 *)
 	usage
 	;;
diff --git a/src/reflect/abi.go b/src/reflect/abi.go
new file mode 100644
index 0000000..17b79a8
--- /dev/null
+++ b/src/reflect/abi.go
@@ -0,0 +1,468 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package reflect
+
+import (
+	"internal/abi"
+	"internal/goexperiment"
+	"unsafe"
+)
+
+// These variables are used by the register assignment
+// algorithm in this file.
+//
+// They should be modified with care (no other reflect code
+// may be executing) and are generally only modified
+// when testing this package.
+//
+// They should never be set higher than their internal/abi
+// constant counterparts, because the system relies on a
+// structure that is at least large enough to hold the
+// registers the system supports.
+//
+// Currently they're set to zero because using the actual
+// constants will break every part of the toolchain that
+// uses reflect to call functions (e.g. go test, or anything
+// that uses text/template). The values that are currently
+// commented out there should be the actual values once
+// we're ready to use the register ABI everywhere.
+var (
+	intArgRegs   = abi.IntArgRegs * goexperiment.RegabiArgsInt
+	floatArgRegs = abi.FloatArgRegs * goexperiment.RegabiArgsInt
+	floatRegSize = uintptr(abi.EffectiveFloatRegSize * goexperiment.RegabiArgsInt)
+)
+
+// abiStep represents an ABI "instruction." Each instruction
+// describes one part of how to translate between a Go value
+// in memory and a call frame.
+type abiStep struct {
+	kind abiStepKind
+
+	// offset and size together describe a part of a Go value
+	// in memory.
+	offset uintptr
+	size   uintptr // size in bytes of the part
+
+	// These fields describe the ABI side of the translation.
+	stkOff uintptr // stack offset, used if kind == abiStepStack
+	ireg   int     // integer register index, used if kind == abiStepIntReg or kind == abiStepPointer
+	freg   int     // FP register index, used if kind == abiStepFloatReg
+}
+
+// abiStepKind is the "op-code" for an abiStep instruction.
+type abiStepKind int
+
+const (
+	abiStepBad      abiStepKind = iota
+	abiStepStack                // copy to/from stack
+	abiStepIntReg               // copy to/from integer register
+	abiStepPointer              // copy pointer to/from integer register
+	abiStepFloatReg             // copy to/from FP register
+)
+
+// abiSeq represents a sequence of ABI instructions for copying
+// from a series of reflect.Values to a call frame (for call arguments)
+// or vice-versa (for call results).
+//
+// An abiSeq should be populated by calling its addArg method.
+type abiSeq struct {
+	// steps is the set of instructions.
+	//
+	// The instructions are grouped together by whole arguments,
+	// with the starting index for the instructions
+	// of the i'th Go value available in valueStart.
+	//
+	// For instance, if this abiSeq represents 3 arguments
+	// passed to a function, then the 2nd argument's steps
+	// begin at steps[valueStart[1]].
+	//
+	// Because reflect accepts Go arguments in distinct
+	// Values and each Value is stored separately, each abiStep
+	// that begins a new argument will have its offset
+	// field == 0.
+	steps      []abiStep
+	valueStart []int
+
+	stackBytes   uintptr // stack space used
+	iregs, fregs int     // registers used
+}
+
+func (a *abiSeq) dump() {
+	for i, p := range a.steps {
+		println("part", i, p.kind, p.offset, p.size, p.stkOff, p.ireg, p.freg)
+	}
+	print("values ")
+	for _, i := range a.valueStart {
+		print(i, " ")
+	}
+	println()
+	println("stack", a.stackBytes)
+	println("iregs", a.iregs)
+	println("fregs", a.fregs)
+}
+
+// stepsForValue returns the ABI instructions for translating
+// the i'th Go argument or return value represented by this
+// abiSeq to the Go ABI.
+func (a *abiSeq) stepsForValue(i int) []abiStep {
+	s := a.valueStart[i]
+	var e int
+	if i == len(a.valueStart)-1 {
+		e = len(a.steps)
+	} else {
+		e = a.valueStart[i+1]
+	}
+	return a.steps[s:e]
+}
+
+// addArg extends the abiSeq with a new Go value of type t.
+//
+// If the value was stack-assigned, returns the single
+// abiStep describing that translation, and nil otherwise.
+func (a *abiSeq) addArg(t *rtype) *abiStep {
+	// We'll always be adding a new value, so do that first.
+	pStart := len(a.steps)
+	a.valueStart = append(a.valueStart, pStart)
+	if t.size == 0 {
+		// If the size of the argument type is zero, then
+		// in order to degrade gracefully into ABI0, we need
+		// to stack-assign this type. The reason is that
+		// although zero-sized types take up no space on the
+		// stack, they do cause the next argument to be aligned.
+		// So just do that here, but don't bother actually
+		// generating a new ABI step for it (there's nothing to
+		// actually copy).
+		//
+		// We cannot handle this in the recursive case of
+		// regAssign because zero-sized *fields* of a
+		// non-zero-sized struct do not cause it to be
+		// stack-assigned. So we need a special case here
+		// at the top.
+		a.stackBytes = align(a.stackBytes, uintptr(t.align))
+		return nil
+	}
+	// Hold a copy of "a" so that we can roll back if
+	// register assignment fails.
+	aOld := *a
+	if !a.regAssign(t, 0) {
+		// Register assignment failed. Roll back any changes
+		// and stack-assign.
+		*a = aOld
+		a.stackAssign(t.size, uintptr(t.align))
+		return &a.steps[len(a.steps)-1]
+	}
+	return nil
+}
+
+// addRcvr extends the abiSeq with a new method call
+// receiver according to the interface calling convention.
+//
+// If the receiver was stack-assigned, returns the single
+// abiStep describing that translation, and nil otherwise.
+// Returns true if the receiver is a pointer.
+func (a *abiSeq) addRcvr(rcvr *rtype) (*abiStep, bool) {
+	// The receiver is always one word.
+	a.valueStart = append(a.valueStart, len(a.steps))
+	var ok, ptr bool
+	if ifaceIndir(rcvr) || rcvr.pointers() {
+		ok = a.assignIntN(0, ptrSize, 1, 0b1)
+		ptr = true
+	} else {
+		// TODO(mknyszek): Is this case even possible?
+		// The interface data work never contains a non-pointer
+		// value. This case was copied over from older code
+		// in the reflect package which only conditionally added
+		// a pointer bit to the reflect.(Value).Call stack frame's
+		// GC bitmap.
+		ok = a.assignIntN(0, ptrSize, 1, 0b0)
+		ptr = false
+	}
+	if !ok {
+		a.stackAssign(ptrSize, ptrSize)
+		return &a.steps[len(a.steps)-1], ptr
+	}
+	return nil, ptr
+}
+
+// regAssign attempts to reserve argument registers for a value of
+// type t, stored at some offset.
+//
+// It returns whether or not the assignment succeeded, but
+// leaves any changes it made to a.steps behind, so the caller
+// must undo that work by adjusting a.steps if it fails.
+//
+// This method along with the assign* methods represent the
+// complete register-assignment algorithm for the Go ABI.
+func (a *abiSeq) regAssign(t *rtype, offset uintptr) bool {
+	switch t.Kind() {
+	case UnsafePointer, Ptr, Chan, Map, Func:
+		return a.assignIntN(offset, t.size, 1, 0b1)
+	case Bool, Int, Uint, Int8, Uint8, Int16, Uint16, Int32, Uint32, Uintptr:
+		return a.assignIntN(offset, t.size, 1, 0b0)
+	case Int64, Uint64:
+		switch ptrSize {
+		case 4:
+			return a.assignIntN(offset, 4, 2, 0b0)
+		case 8:
+			return a.assignIntN(offset, 8, 1, 0b0)
+		}
+	case Float32, Float64:
+		return a.assignFloatN(offset, t.size, 1)
+	case Complex64:
+		return a.assignFloatN(offset, 4, 2)
+	case Complex128:
+		return a.assignFloatN(offset, 8, 2)
+	case String:
+		return a.assignIntN(offset, ptrSize, 2, 0b01)
+	case Interface:
+		return a.assignIntN(offset, ptrSize, 2, 0b10)
+	case Slice:
+		return a.assignIntN(offset, ptrSize, 3, 0b001)
+	case Array:
+		tt := (*arrayType)(unsafe.Pointer(t))
+		switch tt.len {
+		case 0:
+			// There's nothing to assign, so don't modify
+			// a.steps but succeed so the caller doesn't
+			// try to stack-assign this value.
+			return true
+		case 1:
+			return a.regAssign(tt.elem, offset)
+		default:
+			return false
+		}
+	case Struct:
+		st := (*structType)(unsafe.Pointer(t))
+		for i := range st.fields {
+			f := &st.fields[i]
+			if !a.regAssign(f.typ, offset+f.offset()) {
+				return false
+			}
+		}
+		return true
+	default:
+		print("t.Kind == ", t.Kind(), "\n")
+		panic("unknown type kind")
+	}
+	panic("unhandled register assignment path")
+}
+
+// assignIntN assigns n values to registers, each "size" bytes large,
+// from the data at [offset, offset+n*size) in memory. Each value at
+// [offset+i*size, offset+(i+1)*size) for i < n is assigned to the
+// next n integer registers.
+//
+// Bit i in ptrMap indicates whether the i'th value is a pointer.
+// n must be <= 8.
+//
+// Returns whether assignment succeeded.
+func (a *abiSeq) assignIntN(offset, size uintptr, n int, ptrMap uint8) bool {
+	if n > 8 || n < 0 {
+		panic("invalid n")
+	}
+	if ptrMap != 0 && size != ptrSize {
+		panic("non-empty pointer map passed for non-pointer-size values")
+	}
+	if a.iregs+n > intArgRegs {
+		return false
+	}
+	for i := 0; i < n; i++ {
+		kind := abiStepIntReg
+		if ptrMap&(uint8(1)<<i) != 0 {
+			kind = abiStepPointer
+		}
+		a.steps = append(a.steps, abiStep{
+			kind:   kind,
+			offset: offset + uintptr(i)*size,
+			size:   size,
+			ireg:   a.iregs,
+		})
+		a.iregs++
+	}
+	return true
+}
+
+// assignFloatN assigns n values to registers, each "size" bytes large,
+// from the data at [offset, offset+n*size) in memory. Each value at
+// [offset+i*size, offset+(i+1)*size) for i < n is assigned to the
+// next n floating-point registers.
+//
+// Returns whether assignment succeeded.
+func (a *abiSeq) assignFloatN(offset, size uintptr, n int) bool {
+	if n < 0 {
+		panic("invalid n")
+	}
+	if a.fregs+n > floatArgRegs || floatRegSize < size {
+		return false
+	}
+	for i := 0; i < n; i++ {
+		a.steps = append(a.steps, abiStep{
+			kind:   abiStepFloatReg,
+			offset: offset + uintptr(i)*size,
+			size:   size,
+			freg:   a.fregs,
+		})
+		a.fregs++
+	}
+	return true
+}
+
+// stackAssign reserves space for one value that is "size" bytes
+// large with alignment "alignment" to the stack.
+//
+// Should not be called directly; use addArg instead.
+func (a *abiSeq) stackAssign(size, alignment uintptr) {
+	a.stackBytes = align(a.stackBytes, alignment)
+	a.steps = append(a.steps, abiStep{
+		kind:   abiStepStack,
+		offset: 0, // Only used for whole arguments, so the memory offset is 0.
+		size:   size,
+		stkOff: a.stackBytes,
+	})
+	a.stackBytes += size
+}
+
+// abiDesc describes the ABI for a function or method.
+type abiDesc struct {
+	// call and ret represent the translation steps for
+	// the call and return paths of a Go function.
+	call, ret abiSeq
+
+	// These fields describe the stack space allocated
+	// for the call. stackCallArgsSize is the amount of space
+	// reserved for arguments but not return values. retOffset
+	// is the offset at which return values begin, and
+	// spill is the size in bytes of additional space reserved
+	// to spill argument registers into in case of preemption in
+	// reflectcall's stack frame.
+	stackCallArgsSize, retOffset, spill uintptr
+
+	// stackPtrs is a bitmap that indicates whether
+	// each word in the ABI stack space (stack-assigned
+	// args + return values) is a pointer. Used
+	// as the heap pointer bitmap for stack space
+	// passed to reflectcall.
+	stackPtrs *bitVector
+
+	// inRegPtrs is a bitmap whose i'th bit indicates
+	// whether the i'th integer argument register contains
+	// a pointer. Used by makeFuncStub and methodValueCall
+	// to make result pointers visible to the GC.
+	//
+	// outRegPtrs is the same, but for result values.
+	// Used by reflectcall to make result pointers visible
+	// to the GC.
+	inRegPtrs, outRegPtrs abi.IntArgRegBitmap
+}
+
+func (a *abiDesc) dump() {
+	println("ABI")
+	println("call")
+	a.call.dump()
+	println("ret")
+	a.ret.dump()
+	println("stackCallArgsSize", a.stackCallArgsSize)
+	println("retOffset", a.retOffset)
+	println("spill", a.spill)
+	print("inRegPtrs:")
+	dumpPtrBitMap(a.inRegPtrs)
+	println()
+	print("outRegPtrs:")
+	dumpPtrBitMap(a.outRegPtrs)
+	println()
+}
+
+func dumpPtrBitMap(b abi.IntArgRegBitmap) {
+	for i := 0; i < intArgRegs; i++ {
+		x := 0
+		if b.Get(i) {
+			x = 1
+		}
+		print(" ", x)
+	}
+}
+
+func newAbiDesc(t *funcType, rcvr *rtype) abiDesc {
+	// We need to add space for this argument to
+	// the frame so that it can spill args into it.
+	//
+	// The size of this space is just the sum of the sizes
+	// of each register-allocated type.
+	//
+	// TODO(mknyszek): Remove this when we no longer have
+	// caller reserved spill space.
+	spill := uintptr(0)
+
+	// Compute gc program & stack bitmap for stack arguments
+	stackPtrs := new(bitVector)
+
+	// Compute the stack frame pointer bitmap and register
+	// pointer bitmap for arguments.
+	inRegPtrs := abi.IntArgRegBitmap{}
+
+	// Compute abiSeq for input parameters.
+	var in abiSeq
+	if rcvr != nil {
+		stkStep, isPtr := in.addRcvr(rcvr)
+		if stkStep != nil {
+			if isPtr {
+				stackPtrs.append(1)
+			} else {
+				stackPtrs.append(0)
+			}
+		} else {
+			spill += ptrSize
+		}
+	}
+	for i, arg := range t.in() {
+		stkStep := in.addArg(arg)
+		if stkStep != nil {
+			addTypeBits(stackPtrs, stkStep.stkOff, arg)
+		} else {
+			spill = align(spill, uintptr(arg.align))
+			spill += arg.size
+			for _, st := range in.stepsForValue(i) {
+				if st.kind == abiStepPointer {
+					inRegPtrs.Set(st.ireg)
+				}
+			}
+		}
+	}
+	spill = align(spill, ptrSize)
+
+	// From the input parameters alone, we now know
+	// the stackCallArgsSize and retOffset.
+	stackCallArgsSize := in.stackBytes
+	retOffset := align(in.stackBytes, ptrSize)
+
+	// Compute the stack frame pointer bitmap and register
+	// pointer bitmap for return values.
+	outRegPtrs := abi.IntArgRegBitmap{}
+
+	// Compute abiSeq for output parameters.
+	var out abiSeq
+	// Stack-assigned return values do not share
+	// space with arguments like they do with registers,
+	// so we need to inject a stack offset here.
+	// Fake it by artificially extending stackBytes by
+	// the return offset.
+	out.stackBytes = retOffset
+	for i, res := range t.out() {
+		stkStep := out.addArg(res)
+		if stkStep != nil {
+			addTypeBits(stackPtrs, stkStep.stkOff, res)
+		} else {
+			for _, st := range out.stepsForValue(i) {
+				if st.kind == abiStepPointer {
+					outRegPtrs.Set(st.ireg)
+				}
+			}
+		}
+	}
+	// Undo the faking from earlier so that stackBytes
+	// is accurate.
+	out.stackBytes -= retOffset
+	return abiDesc{in, out, stackCallArgsSize, retOffset, spill, stackPtrs, inRegPtrs, outRegPtrs}
+}
diff --git a/src/reflect/abi_test.go b/src/reflect/abi_test.go
new file mode 100644
index 0000000..5a0130f
--- /dev/null
+++ b/src/reflect/abi_test.go
@@ -0,0 +1,964 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.regabireflect
+// +build goexperiment.regabireflect
+
+package reflect_test
+
+import (
+	"internal/abi"
+	"math/rand"
+	"reflect"
+	"runtime"
+	"testing"
+	"testing/quick"
+)
+
+// As of early May 2021 this is no longer necessary for amd64,
+// but it remains in case this is needed for the next register abi port.
+// TODO (1.18) If enabling register ABI on additional architectures turns out not to need this, remove it.
+type MagicLastTypeNameForTestingRegisterABI struct{}
+
+func TestMethodValueCallABI(t *testing.T) {
+	// Enable register-based reflect.Call and ensure we don't
+	// use potentially incorrect cached versions by clearing
+	// the cache before we start and after we're done.
+	defer reflect.SetArgRegs(reflect.SetArgRegs(abi.IntArgRegs, abi.FloatArgRegs, abi.EffectiveFloatRegSize))
+
+	// This test is simple. Calling a method value involves
+	// pretty much just plumbing whatever arguments in whichever
+	// location through to reflectcall. They're already set up
+	// for us, so there isn't a whole lot to do. Let's just
+	// make sure that we can pass register and stack arguments
+	// through. The exact combination is not super important.
+	makeMethodValue := func(method string) (*StructWithMethods, interface{}) {
+		s := new(StructWithMethods)
+		v := reflect.ValueOf(s).MethodByName(method)
+		return s, v.Interface()
+	}
+
+	a0 := StructFewRegs{
+		10, 11, 12, 13,
+		20.0, 21.0, 22.0, 23.0,
+	}
+	a1 := [4]uint64{100, 101, 102, 103}
+	a2 := StructFillRegs{
+		1, 2, 3, 4, 5, 6, 7, 8, 9,
+		1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
+	}
+
+	s, i := makeMethodValue("AllRegsCall")
+	f0 := i.(func(StructFewRegs, MagicLastTypeNameForTestingRegisterABI) StructFewRegs)
+	r0 := f0(a0, MagicLastTypeNameForTestingRegisterABI{})
+	if r0 != a0 {
+		t.Errorf("bad method value call: got %#v, want %#v", r0, a0)
+	}
+	if s.Value != 1 {
+		t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 1)
+	}
+
+	s, i = makeMethodValue("RegsAndStackCall")
+	f1 := i.(func(StructFewRegs, [4]uint64, MagicLastTypeNameForTestingRegisterABI) (StructFewRegs, [4]uint64))
+	r0, r1 := f1(a0, a1, MagicLastTypeNameForTestingRegisterABI{})
+	if r0 != a0 {
+		t.Errorf("bad method value call: got %#v, want %#v", r0, a0)
+	}
+	if r1 != a1 {
+		t.Errorf("bad method value call: got %#v, want %#v", r1, a1)
+	}
+	if s.Value != 2 {
+		t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 2)
+	}
+
+	s, i = makeMethodValue("SpillStructCall")
+	f2 := i.(func(StructFillRegs, MagicLastTypeNameForTestingRegisterABI) StructFillRegs)
+	r2 := f2(a2, MagicLastTypeNameForTestingRegisterABI{})
+	if r2 != a2 {
+		t.Errorf("bad method value call: got %#v, want %#v", r2, a2)
+	}
+	if s.Value != 3 {
+		t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 3)
+	}
+
+	s, i = makeMethodValue("ValueRegMethodSpillInt")
+	f3 := i.(func(StructFillRegs, int, MagicLastTypeNameForTestingRegisterABI) (StructFillRegs, int))
+	r3a, r3b := f3(a2, 42, MagicLastTypeNameForTestingRegisterABI{})
+	if r3a != a2 {
+		t.Errorf("bad method value call: got %#v, want %#v", r3a, a2)
+	}
+	if r3b != 42 {
+		t.Errorf("bad method value call: got %#v, want %#v", r3b, 42)
+	}
+	if s.Value != 4 {
+		t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 4)
+	}
+
+	s, i = makeMethodValue("ValueRegMethodSpillPtr")
+	f4 := i.(func(StructFillRegs, *byte, MagicLastTypeNameForTestingRegisterABI) (StructFillRegs, *byte))
+	vb := byte(10)
+	r4a, r4b := f4(a2, &vb, MagicLastTypeNameForTestingRegisterABI{})
+	if r4a != a2 {
+		t.Errorf("bad method value call: got %#v, want %#v", r4a, a2)
+	}
+	if r4b != &vb {
+		t.Errorf("bad method value call: got %#v, want %#v", r4b, &vb)
+	}
+	if s.Value != 5 {
+		t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 5)
+	}
+}
+
+type StructWithMethods struct {
+	Value int
+}
+
+type StructFewRegs struct {
+	a0, a1, a2, a3 int
+	f0, f1, f2, f3 float64
+}
+
+type StructFillRegs struct {
+	a0, a1, a2, a3, a4, a5, a6, a7, a8                              int
+	f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14 float64
+}
+
+func (m *StructWithMethods) AllRegsCall(s StructFewRegs, _ MagicLastTypeNameForTestingRegisterABI) StructFewRegs {
+	m.Value = 1
+	return s
+}
+
+func (m *StructWithMethods) RegsAndStackCall(s StructFewRegs, a [4]uint64, _ MagicLastTypeNameForTestingRegisterABI) (StructFewRegs, [4]uint64) {
+	m.Value = 2
+	return s, a
+}
+
+func (m *StructWithMethods) SpillStructCall(s StructFillRegs, _ MagicLastTypeNameForTestingRegisterABI) StructFillRegs {
+	m.Value = 3
+	return s
+}
+
+// When called as a method value, i is passed on the stack.
+// When called as a method, i is passed in a register.
+func (m *StructWithMethods) ValueRegMethodSpillInt(s StructFillRegs, i int, _ MagicLastTypeNameForTestingRegisterABI) (StructFillRegs, int) {
+	m.Value = 4
+	return s, i
+}
+
+// When called as a method value, i is passed on the stack.
+// When called as a method, i is passed in a register.
+func (m *StructWithMethods) ValueRegMethodSpillPtr(s StructFillRegs, i *byte, _ MagicLastTypeNameForTestingRegisterABI) (StructFillRegs, *byte) {
+	m.Value = 5
+	return s, i
+}
+
+func TestReflectCallABI(t *testing.T) {
+	// Enable register-based reflect.Call and ensure we don't
+	// use potentially incorrect cached versions by clearing
+	// the cache before we start and after we're done.
+	defer reflect.SetArgRegs(reflect.SetArgRegs(abi.IntArgRegs, abi.FloatArgRegs, abi.EffectiveFloatRegSize))
+
+	// Execute the functions defined below which all have the
+	// same form and perform the same function: pass all arguments
+	// to return values. The purpose is to test the call boundary
+	// and make sure it works.
+	r := rand.New(rand.NewSource(genValueRandSeed))
+	for _, fn := range abiCallTestCases {
+		fn := reflect.ValueOf(fn)
+		t.Run(runtime.FuncForPC(fn.Pointer()).Name(), func(t *testing.T) {
+			typ := fn.Type()
+			if typ.Kind() != reflect.Func {
+				t.Fatalf("test case is not a function, has type: %s", typ.String())
+			}
+			if typ.NumIn() != typ.NumOut() {
+				t.Fatalf("test case has different number of inputs and outputs: %d in, %d out", typ.NumIn(), typ.NumOut())
+			}
+			var args []reflect.Value
+			for i := 0; i < typ.NumIn(); i++ {
+				args = append(args, genValue(t, typ.In(i), r))
+			}
+			results := fn.Call(args)
+			for i := range results {
+				x, y := args[i].Interface(), results[i].Interface()
+				if reflect.DeepEqual(x, y) {
+					continue
+				}
+				t.Errorf("arg and result %d differ: got %+v, want %+v", i, y, x)
+			}
+		})
+	}
+}
+
+func TestReflectMakeFuncCallABI(t *testing.T) {
+	// Enable register-based reflect.MakeFunc and ensure we don't
+	// use potentially incorrect cached versions by clearing
+	// the cache before we start and after we're done.
+	defer reflect.SetArgRegs(reflect.SetArgRegs(abi.IntArgRegs, abi.FloatArgRegs, abi.EffectiveFloatRegSize))
+
+	// Execute the functions defined below which all have the
+	// same form and perform the same function: pass all arguments
+	// to return values. The purpose is to test the call boundary
+	// and make sure it works.
+	r := rand.New(rand.NewSource(genValueRandSeed))
+	makeFuncHandler := func(args []reflect.Value) []reflect.Value {
+		if len(args) == 0 {
+			return []reflect.Value{}
+		}
+		return args[:len(args)-1] // The last Value is an empty magic value.
+	}
+	for _, callFn := range abiMakeFuncTestCases {
+		fnTyp := reflect.TypeOf(callFn).In(0)
+		fn := reflect.MakeFunc(fnTyp, makeFuncHandler)
+		callFn := reflect.ValueOf(callFn)
+		t.Run(runtime.FuncForPC(callFn.Pointer()).Name(), func(t *testing.T) {
+			args := []reflect.Value{fn}
+			for i := 0; i < fnTyp.NumIn()-1; /* last one is magic type */ i++ {
+				args = append(args, genValue(t, fnTyp.In(i), r))
+			}
+			results := callFn.Call(args)
+			for i := range results {
+				x, y := args[i+1].Interface(), results[i].Interface()
+				if reflect.DeepEqual(x, y) {
+					continue
+				}
+				t.Errorf("arg and result %d differ: got %+v, want %+v", i, y, x)
+			}
+		})
+	}
+	t.Run("OnlyPointerInRegisterGC", func(t *testing.T) {
+		// This test attempts to induce a failure wherein
+		// the last pointer to an object is passed via registers.
+		// If makeFuncStub doesn't successfully store the pointer
+		// to a location visible to the GC, the object should be
+		// freed and then the next GC should notice that an object
+		// was inexplicably revived.
+		var f func(b *uint64, _ MagicLastTypeNameForTestingRegisterABI) *uint64
+		mkfn := reflect.MakeFunc(reflect.TypeOf(f), func(args []reflect.Value) []reflect.Value {
+			*(args[0].Interface().(*uint64)) = 5
+			return args[:1]
+		})
+		fn := mkfn.Interface().(func(*uint64, MagicLastTypeNameForTestingRegisterABI) *uint64)
+
+		// Call the MakeFunc'd function while trying pass the only pointer
+		// to a new heap-allocated uint64.
+		*reflect.CallGC = true
+		x := fn(new(uint64), MagicLastTypeNameForTestingRegisterABI{})
+		*reflect.CallGC = false
+
+		// Check for bad pointers (which should be x if things went wrong).
+		runtime.GC()
+
+		// Sanity check x.
+		if *x != 5 {
+			t.Fatalf("failed to set value in object")
+		}
+	})
+}
+
+var abiCallTestCases = []interface{}{
+	passNone,
+	passInt,
+	passInt8,
+	passInt16,
+	passInt32,
+	passInt64,
+	passUint,
+	passUint8,
+	passUint16,
+	passUint32,
+	passUint64,
+	passFloat32,
+	passFloat64,
+	passComplex64,
+	passComplex128,
+	passManyInt,
+	passManyFloat64,
+	passArray1,
+	passArray,
+	passArray1Mix,
+	passString,
+	// TODO(mknyszek): Test passing interface values.
+	passSlice,
+	passPointer,
+	passStruct1,
+	passStruct2,
+	passStruct3,
+	passStruct4,
+	passStruct5,
+	passStruct6,
+	passStruct7,
+	passStruct8,
+	passStruct9,
+	passStruct10,
+	// TODO(mknyszek): Test passing unsafe.Pointer values.
+	// TODO(mknyszek): Test passing chan values.
+	passStruct11,
+	passStruct12,
+	passStruct13,
+	passStruct14,
+	passStruct15,
+	pass2Struct1,
+	passEmptyStruct,
+	passStruct10AndSmall,
+}
+
+// Functions for testing reflect function call functionality.
+
+//go:registerparams
+//go:noinline
+func passNone() {}
+
+//go:registerparams
+//go:noinline
+func passInt(a int) int {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passInt8(a int8) int8 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passInt16(a int16) int16 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passInt32(a int32) int32 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passInt64(a int64) int64 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passUint(a uint) uint {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passUint8(a uint8) uint8 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passUint16(a uint16) uint16 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passUint32(a uint32) uint32 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passUint64(a uint64) uint64 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passFloat32(a float32) float32 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passFloat64(a float64) float64 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passComplex64(a complex64) complex64 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passComplex128(a complex128) complex128 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passArray1(a [1]uint32) [1]uint32 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passArray(a [2]uintptr) [2]uintptr {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passArray1Mix(a int, b [1]uint32, c float64) (int, [1]uint32, float64) {
+	return a, b, c
+}
+
+//go:registerparams
+//go:noinline
+func passString(a string) string {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passSlice(a []byte) []byte {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passPointer(a *byte) *byte {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passManyInt(a, b, c, d, e, f, g, h, i, j int) (int, int, int, int, int, int, int, int, int, int) {
+	return a, b, c, d, e, f, g, h, i, j
+}
+
+//go:registerparams
+//go:noinline
+func passManyFloat64(a, b, c, d, e, f, g, h, i, j, l, m, n, o, p, q, r, s, t float64) (float64, float64, float64, float64, float64, float64, float64, float64, float64, float64, float64, float64, float64, float64, float64, float64, float64, float64, float64) {
+	return a, b, c, d, e, f, g, h, i, j, l, m, n, o, p, q, r, s, t
+}
+
+//go:registerparams
+//go:noinline
+func passStruct1(a Struct1) Struct1 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct2(a Struct2) Struct2 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct3(a Struct3) Struct3 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct4(a Struct4) Struct4 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct5(a Struct5) Struct5 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct6(a Struct6) Struct6 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct7(a Struct7) Struct7 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct8(a Struct8) Struct8 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct9(a Struct9) Struct9 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct10(a Struct10) Struct10 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct11(a Struct11) Struct11 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct12(a Struct12) Struct12 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct13(a Struct13) Struct13 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct14(a Struct14) Struct14 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func passStruct15(a Struct15) Struct15 {
+	return a
+}
+
+//go:registerparams
+//go:noinline
+func pass2Struct1(a, b Struct1) (x, y Struct1) {
+	return a, b
+}
+
+//go:registerparams
+//go:noinline
+func passEmptyStruct(a int, b struct{}, c float64) (int, struct{}, float64) {
+	return a, b, c
+}
+
+// This test case forces a large argument to the stack followed by more
+// in-register arguments.
+//go:registerparams
+//go:noinline
+func passStruct10AndSmall(a Struct10, b byte, c uint) (Struct10, byte, uint) {
+	return a, b, c
+}
+
+var abiMakeFuncTestCases = []interface{}{
+	callArgsNone,
+	callArgsInt,
+	callArgsInt8,
+	callArgsInt16,
+	callArgsInt32,
+	callArgsInt64,
+	callArgsUint,
+	callArgsUint8,
+	callArgsUint16,
+	callArgsUint32,
+	callArgsUint64,
+	callArgsFloat32,
+	callArgsFloat64,
+	callArgsComplex64,
+	callArgsComplex128,
+	callArgsManyInt,
+	callArgsManyFloat64,
+	callArgsArray1,
+	callArgsArray,
+	callArgsArray1Mix,
+	callArgsString,
+	// TODO(mknyszek): Test callArgsing interface values.
+	callArgsSlice,
+	callArgsPointer,
+	callArgsStruct1,
+	callArgsStruct2,
+	callArgsStruct3,
+	callArgsStruct4,
+	callArgsStruct5,
+	callArgsStruct6,
+	callArgsStruct7,
+	callArgsStruct8,
+	callArgsStruct9,
+	callArgsStruct10,
+	// TODO(mknyszek): Test callArgsing unsafe.Pointer values.
+	// TODO(mknyszek): Test callArgsing chan values.
+	callArgsStruct11,
+	callArgsStruct12,
+	callArgsStruct13,
+	callArgsStruct14,
+	callArgsStruct15,
+	callArgs2Struct1,
+	callArgsEmptyStruct,
+}
+
+//go:registerparams
+//go:noinline
+func callArgsNone(f func(MagicLastTypeNameForTestingRegisterABI)) {
+	f(MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsInt(f func(int, MagicLastTypeNameForTestingRegisterABI) int, a0 int) int {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsInt8(f func(int8, MagicLastTypeNameForTestingRegisterABI) int8, a0 int8) int8 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsInt16(f func(int16, MagicLastTypeNameForTestingRegisterABI) int16, a0 int16) int16 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsInt32(f func(int32, MagicLastTypeNameForTestingRegisterABI) int32, a0 int32) int32 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsInt64(f func(int64, MagicLastTypeNameForTestingRegisterABI) int64, a0 int64) int64 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsUint(f func(uint, MagicLastTypeNameForTestingRegisterABI) uint, a0 uint) uint {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsUint8(f func(uint8, MagicLastTypeNameForTestingRegisterABI) uint8, a0 uint8) uint8 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsUint16(f func(uint16, MagicLastTypeNameForTestingRegisterABI) uint16, a0 uint16) uint16 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsUint32(f func(uint32, MagicLastTypeNameForTestingRegisterABI) uint32, a0 uint32) uint32 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsUint64(f func(uint64, MagicLastTypeNameForTestingRegisterABI) uint64, a0 uint64) uint64 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsFloat32(f func(float32, MagicLastTypeNameForTestingRegisterABI) float32, a0 float32) float32 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsFloat64(f func(float64, MagicLastTypeNameForTestingRegisterABI) float64, a0 float64) float64 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsComplex64(f func(complex64, MagicLastTypeNameForTestingRegisterABI) complex64, a0 complex64) complex64 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsComplex128(f func(complex128, MagicLastTypeNameForTestingRegisterABI) complex128, a0 complex128) complex128 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsArray1(f func([1]uint32, MagicLastTypeNameForTestingRegisterABI) [1]uint32, a0 [1]uint32) [1]uint32 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsArray(f func([2]uintptr, MagicLastTypeNameForTestingRegisterABI) [2]uintptr, a0 [2]uintptr) [2]uintptr {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsArray1Mix(f func(int, [1]uint32, float64, MagicLastTypeNameForTestingRegisterABI) (int, [1]uint32, float64), a0 int, a1 [1]uint32, a2 float64) (int, [1]uint32, float64) {
+	return f(a0, a1, a2, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsString(f func(string, MagicLastTypeNameForTestingRegisterABI) string, a0 string) string {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsSlice(f func([]byte, MagicLastTypeNameForTestingRegisterABI) []byte, a0 []byte) []byte {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsPointer(f func(*byte, MagicLastTypeNameForTestingRegisterABI) *byte, a0 *byte) *byte {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsManyInt(f func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 int, x MagicLastTypeNameForTestingRegisterABI) (r0, r1, r2, r3, r4, r5, r6, r7, r8, r9 int), a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 int) (int, int, int, int, int, int, int, int, int, int) {
+	return f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsManyFloat64(f func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 float64, x MagicLastTypeNameForTestingRegisterABI) (r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18 float64), a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 float64) (r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18 float64) {
+	return f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct1(f func(Struct1, MagicLastTypeNameForTestingRegisterABI) Struct1, a0 Struct1) Struct1 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct2(f func(Struct2, MagicLastTypeNameForTestingRegisterABI) Struct2, a0 Struct2) Struct2 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct3(f func(Struct3, MagicLastTypeNameForTestingRegisterABI) Struct3, a0 Struct3) Struct3 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct4(f func(Struct4, MagicLastTypeNameForTestingRegisterABI) Struct4, a0 Struct4) Struct4 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct5(f func(Struct5, MagicLastTypeNameForTestingRegisterABI) Struct5, a0 Struct5) Struct5 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct6(f func(Struct6, MagicLastTypeNameForTestingRegisterABI) Struct6, a0 Struct6) Struct6 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct7(f func(Struct7, MagicLastTypeNameForTestingRegisterABI) Struct7, a0 Struct7) Struct7 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct8(f func(Struct8, MagicLastTypeNameForTestingRegisterABI) Struct8, a0 Struct8) Struct8 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct9(f func(Struct9, MagicLastTypeNameForTestingRegisterABI) Struct9, a0 Struct9) Struct9 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct10(f func(Struct10, MagicLastTypeNameForTestingRegisterABI) Struct10, a0 Struct10) Struct10 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct11(f func(Struct11, MagicLastTypeNameForTestingRegisterABI) Struct11, a0 Struct11) Struct11 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct12(f func(Struct12, MagicLastTypeNameForTestingRegisterABI) Struct12, a0 Struct12) Struct12 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct13(f func(Struct13, MagicLastTypeNameForTestingRegisterABI) Struct13, a0 Struct13) Struct13 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct14(f func(Struct14, MagicLastTypeNameForTestingRegisterABI) Struct14, a0 Struct14) Struct14 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsStruct15(f func(Struct15, MagicLastTypeNameForTestingRegisterABI) Struct15, a0 Struct15) Struct15 {
+	return f(a0, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgs2Struct1(f func(Struct1, Struct1, MagicLastTypeNameForTestingRegisterABI) (Struct1, Struct1), a0, a1 Struct1) (r0, r1 Struct1) {
+	return f(a0, a1, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+//go:registerparams
+//go:noinline
+func callArgsEmptyStruct(f func(int, struct{}, float64, MagicLastTypeNameForTestingRegisterABI) (int, struct{}, float64), a0 int, a1 struct{}, a2 float64) (int, struct{}, float64) {
+	return f(a0, a1, a2, MagicLastTypeNameForTestingRegisterABI{})
+}
+
+// Struct1 is a simple integer-only aggregate struct.
+type Struct1 struct {
+	A, B, C uint
+}
+
+// Struct2 is Struct1 but with an array-typed field that will
+// force it to get passed on the stack.
+type Struct2 struct {
+	A, B, C uint
+	D       [2]uint32
+}
+
+// Struct3 is Struct2 but with an anonymous array-typed field.
+// This should act identically to Struct2.
+type Struct3 struct {
+	A, B, C uint
+	D       [2]uint32
+}
+
+// Struct4 has byte-length fields that should
+// each use up a whole registers.
+type Struct4 struct {
+	A, B int8
+	C, D uint8
+	E    bool
+}
+
+// Struct5 is a relatively large struct
+// with both integer and floating point values.
+type Struct5 struct {
+	A             uint16
+	B             int16
+	C, D          uint32
+	E             int32
+	F, G, H, I, J float32
+}
+
+// Struct6 has a nested struct.
+type Struct6 struct {
+	Struct1
+}
+
+// Struct7 is a struct with a nested array-typed field
+// that cannot be passed in registers as a result.
+type Struct7 struct {
+	Struct1
+	Struct2
+}
+
+// Struct8 is large aggregate struct type that may be
+// passed in registers.
+type Struct8 struct {
+	Struct5
+	Struct1
+}
+
+// Struct9 is a type that has an array type nested
+// 2 layers deep, and as a result needs to be passed
+// on the stack.
+type Struct9 struct {
+	Struct1
+	Struct7
+}
+
+// Struct10 is a struct type that is too large to be
+// passed in registers.
+type Struct10 struct {
+	Struct5
+	Struct8
+}
+
+// Struct11 is a struct type that has several reference
+// types in it.
+type Struct11 struct {
+	X map[string]int
+}
+
+// Struct12 has Struct11 embedded into it to test more
+// paths.
+type Struct12 struct {
+	A int
+	Struct11
+}
+
+// Struct13 tests an empty field.
+type Struct13 struct {
+	A int
+	X struct{}
+	B int
+}
+
+// Struct14 tests a non-zero-sized (and otherwise register-assignable)
+// struct with a field that is a non-zero length array with zero-sized members.
+type Struct14 struct {
+	A uintptr
+	X [3]struct{}
+	B float64
+}
+
+// Struct15 tests a non-zero-sized (and otherwise register-assignable)
+// struct with a struct field that is zero-sized but contains a
+// non-zero length array with zero-sized members.
+type Struct15 struct {
+	A uintptr
+	X struct {
+		Y [3]struct{}
+	}
+	B float64
+}
+
+const genValueRandSeed = 0
+
+// genValue generates a pseudorandom reflect.Value with type t.
+// The reflect.Value produced by this function is always the same
+// for the same type.
+func genValue(t *testing.T, typ reflect.Type, r *rand.Rand) reflect.Value {
+	// Re-seed and reset the PRNG because we want each value with the
+	// same type to be the same random value.
+	r.Seed(genValueRandSeed)
+	v, ok := quick.Value(typ, r)
+	if !ok {
+		t.Fatal("failed to generate value")
+	}
+	return v
+}
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index 1225d61..eac27e8 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -15,6 +15,8 @@
 	"math/rand"
 	"os"
 	. "reflect"
+	"reflect/internal/example1"
+	"reflect/internal/example2"
 	"runtime"
 	"sort"
 	"strconv"
@@ -1942,6 +1944,22 @@
 	})
 }
 
+type myint int64
+
+func (i *myint) inc() {
+	*i = *i + 1
+}
+
+func BenchmarkCallMethod(b *testing.B) {
+	b.ReportAllocs()
+	z := new(myint)
+
+	v := ValueOf(z.inc)
+	for i := 0; i < b.N; i++ {
+		v.Call(nil)
+	}
+}
+
 func BenchmarkCallArgCopy(b *testing.B) {
 	byteArray := func(n int) Value {
 		return Zero(ArrayOf(n, TypeOf(byte(0))))
@@ -2900,6 +2918,7 @@
 		index    []int
 		pkgPath  string
 		embedded bool
+		exported bool
 	}
 
 	checkPkgPath := func(name string, s []pkgpathTest) {
@@ -2911,27 +2930,63 @@
 			if got, want := f.Anonymous, test.embedded; got != want {
 				t.Errorf("%s: Field(%d).Anonymous = %v, want %v", name, test.index, got, want)
 			}
+			if got, want := f.IsExported(), test.exported; got != want {
+				t.Errorf("%s: Field(%d).IsExported = %v, want %v", name, test.index, got, want)
+			}
 		}
 	}
 
 	checkPkgPath("testStruct", []pkgpathTest{
-		{[]int{0}, "", false},             // Exported
-		{[]int{1}, "reflect_test", false}, // unexported
-		{[]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
+		{[]int{0}, "", false, true},              // Exported
+		{[]int{1}, "reflect_test", false, false}, // unexported
+		{[]int{2}, "", true, true},               // OtherPkgFields
+		{[]int{2, 0}, "", false, true},           // OtherExported
+		{[]int{2, 1}, "reflect", false, false},   // otherUnexported
+		{[]int{3}, "reflect_test", true, false},  // int
+		{[]int{4}, "reflect_test", true, false},  // *x
 	})
 
 	type localOtherPkgFields OtherPkgFields
 	typ = TypeOf(localOtherPkgFields{})
 	checkPkgPath("localOtherPkgFields", []pkgpathTest{
-		{[]int{0}, "", false},        // OtherExported
-		{[]int{1}, "reflect", false}, // otherUnexported
+		{[]int{0}, "", false, true},         // OtherExported
+		{[]int{1}, "reflect", false, false}, // otherUnexported
 	})
 }
 
+func TestMethodPkgPath(t *testing.T) {
+	type I interface {
+		x()
+		X()
+	}
+	typ := TypeOf((*interface {
+		I
+		y()
+		Y()
+	})(nil)).Elem()
+
+	tests := []struct {
+		name     string
+		pkgPath  string
+		exported bool
+	}{
+		{"X", "", true},
+		{"Y", "", true},
+		{"x", "reflect_test", false},
+		{"y", "reflect_test", false},
+	}
+
+	for _, test := range tests {
+		m, _ := typ.MethodByName(test.name)
+		if got, want := m.PkgPath, test.pkgPath; got != want {
+			t.Errorf("MethodByName(%q).PkgPath = %q, want %q", test.name, got, want)
+		}
+		if got, want := m.IsExported(), test.exported; got != want {
+			t.Errorf("MethodByName(%q).IsExported = %v, want %v", test.name, got, want)
+		}
+	}
+}
+
 func TestVariadicType(t *testing.T) {
 	// Test example from Type documentation.
 	var f func(x int, y ...float64)
@@ -3755,8 +3810,22 @@
 type MyStruct struct {
 	x int `some:"tag"`
 }
+type MyStruct1 struct {
+	x struct {
+		int `some:"bar"`
+	}
+}
+type MyStruct2 struct {
+	x struct {
+		int `some:"foo"`
+	}
+}
 type MyString string
 type MyBytes []byte
+type MyBytesArrayPtr0 *[0]byte
+type MyBytesArrayPtr *[4]byte
+type MyBytesArray0 [0]byte
+type MyBytesArray [4]byte
 type MyRunes []int32
 type MyFunc func()
 type MyByte byte
@@ -4063,6 +4132,30 @@
 	{V(MyString("runes♝")), V(MyRunes("runes♝"))},
 	{V(MyRunes("runes♕")), V(MyString("runes♕"))},
 
+	// slice to array pointer
+	{V([]byte(nil)), V((*[0]byte)(nil))},
+	{V([]byte{}), V(new([0]byte))},
+	{V([]byte{7}), V(&[1]byte{7})},
+	{V(MyBytes([]byte(nil))), V((*[0]byte)(nil))},
+	{V(MyBytes([]byte{})), V(new([0]byte))},
+	{V(MyBytes([]byte{9})), V(&[1]byte{9})},
+	{V([]byte(nil)), V(MyBytesArrayPtr0(nil))},
+	{V([]byte{}), V(MyBytesArrayPtr0(new([0]byte)))},
+	{V([]byte{1, 2, 3, 4}), V(MyBytesArrayPtr(&[4]byte{1, 2, 3, 4}))},
+	{V(MyBytes([]byte{})), V(MyBytesArrayPtr0(new([0]byte)))},
+	{V(MyBytes([]byte{5, 6, 7, 8})), V(MyBytesArrayPtr(&[4]byte{5, 6, 7, 8}))},
+
+	{V([]byte(nil)), V((*MyBytesArray0)(nil))},
+	{V([]byte{}), V((*MyBytesArray0)(new([0]byte)))},
+	{V([]byte{1, 2, 3, 4}), V(&MyBytesArray{1, 2, 3, 4})},
+	{V(MyBytes([]byte(nil))), V((*MyBytesArray0)(nil))},
+	{V(MyBytes([]byte{})), V((*MyBytesArray0)(new([0]byte)))},
+	{V(MyBytes([]byte{5, 6, 7, 8})), V(&MyBytesArray{5, 6, 7, 8})},
+	{V(new([0]byte)), V(new(MyBytesArray0))},
+	{V(new(MyBytesArray0)), V(new([0]byte))},
+	{V(MyBytesArrayPtr0(nil)), V((*[0]byte)(nil))},
+	{V((*[0]byte)(nil)), V(MyBytesArrayPtr0(nil))},
+
 	// named types and equal underlying types
 	{V(new(int)), V(new(integer))},
 	{V(new(integer)), V(new(int))},
@@ -4105,6 +4198,9 @@
 		x int `some:"bar"`
 	}{}), V(MyStruct{})},
 
+	{V(MyStruct1{}), V(MyStruct2{})},
+	{V(MyStruct2{}), V(MyStruct1{})},
+
 	// can convert *byte and *MyByte
 	{V((*byte)(nil)), V((*MyByte)(nil))},
 	{V((*MyByte)(nil)), V((*byte)(nil))},
@@ -4208,6 +4304,9 @@
 
 		// vout1 represents the in value converted to the in type.
 		v1 := tt.in
+		if !v1.CanConvert(t1) {
+			t.Errorf("ValueOf(%T(%[1]v)).CanConvert(%s) = false, want true", tt.in.Interface(), t1)
+		}
 		vout1 := v1.Convert(t1)
 		out1 := vout1.Interface()
 		if vout1.Type() != tt.in.Type() || !DeepEqual(out1, tt.in.Interface()) {
@@ -4215,11 +4314,17 @@
 		}
 
 		// vout2 represents the in value converted to the out type.
+		if !v1.CanConvert(t2) {
+			t.Errorf("ValueOf(%T(%[1]v)).CanConvert(%s) = false, want true", tt.in.Interface(), t2)
+		}
 		vout2 := v1.Convert(t2)
 		out2 := vout2.Interface()
 		if vout2.Type() != tt.out.Type() || !DeepEqual(out2, tt.out.Interface()) {
 			t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t2, out2, tt.out.Interface())
 		}
+		if got, want := vout2.Kind(), vout2.Type().Kind(); got != want {
+			t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) has internal kind %v want %v", tt.in.Interface(), t1, got, want)
+		}
 
 		// vout3 represents a new value of the out type, set to vout2.  This makes
 		// sure the converted value vout2 is really usable as a regular value.
@@ -4264,6 +4369,22 @@
 	}
 }
 
+func TestConvertPanic(t *testing.T) {
+	s := make([]byte, 4)
+	p := new([8]byte)
+	v := ValueOf(s)
+	pt := TypeOf(p)
+	if !v.Type().ConvertibleTo(pt) {
+		t.Errorf("[]byte should be convertible to *[8]byte")
+	}
+	if v.CanConvert(pt) {
+		t.Errorf("slice with length 4 should not be convertible to *[8]byte")
+	}
+	shouldPanic("reflect: cannot convert slice with length 4 to pointer to array with length 8", func() {
+		_ = v.Convert(pt)
+	})
+}
+
 var gFloat32 float32
 
 func TestConvertNaNs(t *testing.T) {
@@ -4599,6 +4720,14 @@
 	}
 }
 
+// Ensure passing in negative lengths panics.
+// See https://golang.org/issue/43603
+func TestArrayOfPanicOnNegativeLength(t *testing.T) {
+	shouldPanic("reflect: negative length passed to ArrayOf", func() {
+		ArrayOf(-1, TypeOf(byte(0)))
+	})
+}
+
 func TestSliceOf(t *testing.T) {
 	// check construction and use of type not in binary
 	type T int
@@ -6335,144 +6464,135 @@
 	runtime.GC()
 }
 
-type funcLayoutTest struct {
-	rcvr, t                  Type
-	size, argsize, retOffset uintptr
-	stack                    []byte // pointer bitmap: 1 is pointer, 0 is scalar
-	gc                       []byte
-}
-
-var funcLayoutTests []funcLayoutTest
-
-func init() {
-	var argAlign uintptr = PtrSize
-	roundup := func(x uintptr, a uintptr) uintptr {
-		return (x + a - 1) / a * a
+func TestFuncLayout(t *testing.T) {
+	align := func(x uintptr) uintptr {
+		return (x + PtrSize - 1) &^ (PtrSize - 1)
 	}
-
-	funcLayoutTests = append(funcLayoutTests,
-		funcLayoutTest{
-			nil,
-			ValueOf(func(a, b string) string { return "" }).Type(),
-			6 * PtrSize,
-			4 * PtrSize,
-			4 * PtrSize,
-			[]byte{1, 0, 1, 0, 1},
-			[]byte{1, 0, 1, 0, 1},
-		})
-
 	var r []byte
 	if PtrSize == 4 {
 		r = []byte{0, 0, 0, 1}
 	} else {
 		r = []byte{0, 0, 1}
 	}
-	funcLayoutTests = append(funcLayoutTests,
-		funcLayoutTest{
-			nil,
-			ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(),
-			roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign),
-			roundup(3*4, PtrSize) + PtrSize + 2,
-			roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign),
-			r,
-			r,
-		})
-
-	funcLayoutTests = append(funcLayoutTests,
-		funcLayoutTest{
-			nil,
-			ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(),
-			4 * PtrSize,
-			4 * PtrSize,
-			4 * PtrSize,
-			[]byte{1, 0, 1, 1},
-			[]byte{1, 0, 1, 1},
-		})
 
 	type S struct {
 		a, b uintptr
 		c, d *byte
 	}
-	funcLayoutTests = append(funcLayoutTests,
-		funcLayoutTest{
-			nil,
-			ValueOf(func(a S) {}).Type(),
-			4 * PtrSize,
-			4 * PtrSize,
-			4 * PtrSize,
-			[]byte{0, 0, 1, 1},
-			[]byte{0, 0, 1, 1},
-		})
 
-	funcLayoutTests = append(funcLayoutTests,
-		funcLayoutTest{
-			ValueOf((*byte)(nil)).Type(),
-			ValueOf(func(a uintptr, b *int) {}).Type(),
-			roundup(3*PtrSize, argAlign),
-			3 * PtrSize,
-			roundup(3*PtrSize, argAlign),
-			[]byte{1, 0, 1},
-			[]byte{1, 0, 1},
-		})
-
-	funcLayoutTests = append(funcLayoutTests,
-		funcLayoutTest{
-			nil,
-			ValueOf(func(a uintptr) {}).Type(),
-			roundup(PtrSize, argAlign),
-			PtrSize,
-			roundup(PtrSize, argAlign),
-			[]byte{},
-			[]byte{},
-		})
-
-	funcLayoutTests = append(funcLayoutTests,
-		funcLayoutTest{
-			nil,
-			ValueOf(func() uintptr { return 0 }).Type(),
-			PtrSize,
-			0,
-			0,
-			[]byte{},
-			[]byte{},
-		})
-
-	funcLayoutTests = append(funcLayoutTests,
-		funcLayoutTest{
-			ValueOf(uintptr(0)).Type(),
-			ValueOf(func(a uintptr) {}).Type(),
-			2 * PtrSize,
-			2 * PtrSize,
-			2 * PtrSize,
-			[]byte{1},
-			[]byte{1},
+	type test struct {
+		rcvr, typ                  Type
+		size, argsize, retOffset   uintptr
+		stack, gc, inRegs, outRegs []byte // pointer bitmap: 1 is pointer, 0 is scalar
+		intRegs, floatRegs         int
+		floatRegSize               uintptr
+	}
+	tests := []test{
+		{
+			typ:       ValueOf(func(a, b string) string { return "" }).Type(),
+			size:      6 * PtrSize,
+			argsize:   4 * PtrSize,
+			retOffset: 4 * PtrSize,
+			stack:     []byte{1, 0, 1, 0, 1},
+			gc:        []byte{1, 0, 1, 0, 1},
+		},
+		{
+			typ:       ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(),
+			size:      align(align(3*4) + PtrSize + 2),
+			argsize:   align(3*4) + PtrSize + 2,
+			retOffset: align(align(3*4) + PtrSize + 2),
+			stack:     r,
+			gc:        r,
+		},
+		{
+			typ:       ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(),
+			size:      4 * PtrSize,
+			argsize:   4 * PtrSize,
+			retOffset: 4 * PtrSize,
+			stack:     []byte{1, 0, 1, 1},
+			gc:        []byte{1, 0, 1, 1},
+		},
+		{
+			typ:       ValueOf(func(a S) {}).Type(),
+			size:      4 * PtrSize,
+			argsize:   4 * PtrSize,
+			retOffset: 4 * PtrSize,
+			stack:     []byte{0, 0, 1, 1},
+			gc:        []byte{0, 0, 1, 1},
+		},
+		{
+			rcvr:      ValueOf((*byte)(nil)).Type(),
+			typ:       ValueOf(func(a uintptr, b *int) {}).Type(),
+			size:      3 * PtrSize,
+			argsize:   3 * PtrSize,
+			retOffset: 3 * PtrSize,
+			stack:     []byte{1, 0, 1},
+			gc:        []byte{1, 0, 1},
+		},
+		{
+			typ:       ValueOf(func(a uintptr) {}).Type(),
+			size:      PtrSize,
+			argsize:   PtrSize,
+			retOffset: PtrSize,
+			stack:     []byte{},
+			gc:        []byte{},
+		},
+		{
+			typ:       ValueOf(func() uintptr { return 0 }).Type(),
+			size:      PtrSize,
+			argsize:   0,
+			retOffset: 0,
+			stack:     []byte{},
+			gc:        []byte{},
+		},
+		{
+			rcvr:      ValueOf(uintptr(0)).Type(),
+			typ:       ValueOf(func(a uintptr) {}).Type(),
+			size:      2 * PtrSize,
+			argsize:   2 * PtrSize,
+			retOffset: 2 * PtrSize,
+			stack:     []byte{1},
+			gc:        []byte{1},
 			// Note: this one is tricky, as the receiver is not a pointer. But we
 			// pass the receiver by reference to the autogenerated pointer-receiver
 			// version of the function.
-		})
-}
+		},
+		// TODO(mknyszek): Add tests for non-zero register count.
+	}
+	for _, lt := range tests {
+		name := lt.typ.String()
+		if lt.rcvr != nil {
+			name = lt.rcvr.String() + "." + name
+		}
+		t.Run(name, func(t *testing.T) {
+			defer SetArgRegs(SetArgRegs(lt.intRegs, lt.floatRegs, lt.floatRegSize))
 
-func TestFuncLayout(t *testing.T) {
-	for _, lt := range funcLayoutTests {
-		typ, argsize, retOffset, stack, gc, ptrs := FuncLayout(lt.t, lt.rcvr)
-		if typ.Size() != lt.size {
-			t.Errorf("funcLayout(%v, %v).size=%d, want %d", lt.t, lt.rcvr, typ.Size(), lt.size)
-		}
-		if argsize != lt.argsize {
-			t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.t, lt.rcvr, argsize, lt.argsize)
-		}
-		if retOffset != lt.retOffset {
-			t.Errorf("funcLayout(%v, %v).retOffset=%d, want %d", lt.t, lt.rcvr, retOffset, lt.retOffset)
-		}
-		if !bytes.Equal(stack, lt.stack) {
-			t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.t, lt.rcvr, stack, lt.stack)
-		}
-		if !bytes.Equal(gc, lt.gc) {
-			t.Errorf("funcLayout(%v, %v).gc=%v, want %v", lt.t, lt.rcvr, gc, lt.gc)
-		}
-		if ptrs && len(stack) == 0 || !ptrs && len(stack) > 0 {
-			t.Errorf("funcLayout(%v, %v) pointers flag=%v, want %v", lt.t, lt.rcvr, ptrs, !ptrs)
-		}
+			typ, argsize, retOffset, stack, gc, inRegs, outRegs, ptrs := FuncLayout(lt.typ, lt.rcvr)
+			if typ.Size() != lt.size {
+				t.Errorf("funcLayout(%v, %v).size=%d, want %d", lt.typ, lt.rcvr, typ.Size(), lt.size)
+			}
+			if argsize != lt.argsize {
+				t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.typ, lt.rcvr, argsize, lt.argsize)
+			}
+			if retOffset != lt.retOffset {
+				t.Errorf("funcLayout(%v, %v).retOffset=%d, want %d", lt.typ, lt.rcvr, retOffset, lt.retOffset)
+			}
+			if !bytes.Equal(stack, lt.stack) {
+				t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.typ, lt.rcvr, stack, lt.stack)
+			}
+			if !bytes.Equal(gc, lt.gc) {
+				t.Errorf("funcLayout(%v, %v).gc=%v, want %v", lt.typ, lt.rcvr, gc, lt.gc)
+			}
+			if !bytes.Equal(inRegs, lt.inRegs) {
+				t.Errorf("funcLayout(%v, %v).inRegs=%v, want %v", lt.typ, lt.rcvr, inRegs, lt.inRegs)
+			}
+			if !bytes.Equal(outRegs, lt.outRegs) {
+				t.Errorf("funcLayout(%v, %v).outRegs=%v, want %v", lt.typ, lt.rcvr, outRegs, lt.outRegs)
+			}
+			if ptrs && len(stack) == 0 || !ptrs && len(stack) > 0 {
+				t.Errorf("funcLayout(%v, %v) pointers flag=%v, want %v", lt.typ, lt.rcvr, ptrs, !ptrs)
+			}
+		})
 	}
 }
 
@@ -6831,19 +6951,6 @@
 	}
 }
 
-type embed struct {
-	EmbedWithUnexpMeth
-}
-
-func TestNameBytesAreAligned(t *testing.T) {
-	typ := TypeOf(embed{})
-	b := FirstMethodNameBytes(typ)
-	v := uintptr(unsafe.Pointer(b))
-	if v%unsafe.Alignof((*byte)(nil)) != 0 {
-		t.Errorf("reflect.name.bytes pointer is not aligned: %x", v)
-	}
-}
-
 func TestTypeStrings(t *testing.T) {
 	type stringTest struct {
 		typ  Type
@@ -7179,3 +7286,13 @@
 	sort.Strings(got)
 	return "[" + strings.Join(got, ", ") + "]"
 }
+
+func TestConvertibleTo(t *testing.T) {
+	t1 := ValueOf(example1.MyStruct{}).Type()
+	t2 := ValueOf(example2.MyStruct{}).Type()
+
+	// Shouldn't raise stack overflow
+	if t1.ConvertibleTo(t2) {
+		t.Fatalf("(%s).ConvertibleTo(%s) = true, want false", t1, t2)
+	}
+}
diff --git a/src/reflect/asm_386.s b/src/reflect/asm_386.s
index e79beb6..5bedea5 100644
--- a/src/reflect/asm_386.s
+++ b/src/reflect/asm_386.s
@@ -9,14 +9,15 @@
 // See the comment on the declaration of makeFuncStub in makefunc.go
 // for more details.
 // No argsize here, gc generates argsize info at call site.
-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$16
+TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$20
 	NO_LOCAL_POINTERS
 	MOVL	DX, 0(SP)
 	LEAL	argframe+0(FP), CX
 	MOVL	CX, 4(SP)
-	MOVB	$0, 12(SP)
-	LEAL	12(SP), AX
+	MOVB	$0, 16(SP)
+	LEAL	16(SP), AX
 	MOVL	AX, 8(SP)
+	MOVL	$0, 12(SP)
 	CALL	·callReflect(SB)
 	RET
 
@@ -24,13 +25,14 @@
 // See the comment on the declaration of methodValueCall in makefunc.go
 // for more details.
 // No argsize here, gc generates argsize info at call site.
-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$16
+TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$20
 	NO_LOCAL_POINTERS
 	MOVL	DX, 0(SP)
 	LEAL	argframe+0(FP), CX
 	MOVL	CX, 4(SP)
-	MOVB	$0, 12(SP)
-	LEAL	12(SP), AX
+	MOVB	$0, 16(SP)
+	LEAL	16(SP), AX
 	MOVL	AX, 8(SP)
+	MOVL	$0, 12(SP)
 	CALL	·callMethod(SB)
 	RET
diff --git a/src/reflect/asm_amd64.s b/src/reflect/asm_amd64.s
index 5c8e565..facf075 100644
--- a/src/reflect/asm_amd64.s
+++ b/src/reflect/asm_amd64.s
@@ -4,6 +4,21 @@
 
 #include "textflag.h"
 #include "funcdata.h"
+#include "go_asm.h"
+
+// The frames of each of the two functions below contain two locals, at offsets
+// that are known to the runtime.
+//
+// The first local is a bool called retValid with a whole pointer-word reserved
+// for it on the stack. The purpose of this word is so that the runtime knows
+// whether the stack-allocated return space contains valid values for stack
+// scanning.
+//
+// The second local is an abi.RegArgs value whose offset is also known to the
+// runtime, so that a stack map for it can be constructed, since it contains
+// pointers visible to the GC.
+#define LOCAL_RETVALID 32
+#define LOCAL_REGARGS 40
 
 // makeFuncStub is the code half of the function returned by MakeFunc.
 // See the comment on the declaration of makeFuncStub in makefunc.go
@@ -11,15 +26,29 @@
 // No arg size here; runtime pulls arg map out of the func value.
 // makeFuncStub must be ABIInternal because it is placed directly
 // in function values.
-TEXT ·makeFuncStub<ABIInternal>(SB),(NOSPLIT|WRAPPER),$32
+// This frame contains two locals. See the comment above LOCAL_RETVALID.
+TEXT ·makeFuncStub<ABIInternal>(SB),(NOSPLIT|WRAPPER),$312
 	NO_LOCAL_POINTERS
+	// NO_LOCAL_POINTERS is a lie. The stack map for the two locals in this
+	// frame is specially handled in the runtime. See the comment above LOCAL_RETVALID.
+	LEAQ	LOCAL_REGARGS(SP), R12
+	CALL	runtime·spillArgs<ABIInternal>(SB)
+	MOVQ	DX, 24(SP) // outside of moveMakeFuncArgPtrs's arg area
+	MOVQ	DX, 0(SP)
+	MOVQ	R12, 8(SP)
+	CALL	·moveMakeFuncArgPtrs(SB)
+	MOVQ	24(SP), DX
 	MOVQ	DX, 0(SP)
 	LEAQ	argframe+0(FP), CX
 	MOVQ	CX, 8(SP)
-	MOVB	$0, 24(SP)
-	LEAQ	24(SP), AX
+	MOVB	$0, LOCAL_RETVALID(SP)
+	LEAQ	LOCAL_RETVALID(SP), AX
 	MOVQ	AX, 16(SP)
-	CALL	·callReflect<ABIInternal>(SB)
+	LEAQ	LOCAL_REGARGS(SP), AX
+	MOVQ	AX, 24(SP)
+	CALL	·callReflect(SB)
+	LEAQ	LOCAL_REGARGS(SP), R12
+	CALL	runtime·unspillArgs<ABIInternal>(SB)
 	RET
 
 // methodValueCall is the code half of the function returned by makeMethodValue.
@@ -28,13 +57,27 @@
 // No arg size here; runtime pulls arg map out of the func value.
 // methodValueCall must be ABIInternal because it is placed directly
 // in function values.
-TEXT ·methodValueCall<ABIInternal>(SB),(NOSPLIT|WRAPPER),$32
+// This frame contains two locals. See the comment above LOCAL_RETVALID.
+TEXT ·methodValueCall<ABIInternal>(SB),(NOSPLIT|WRAPPER),$312
 	NO_LOCAL_POINTERS
+	// NO_LOCAL_POINTERS is a lie. The stack map for the two locals in this
+	// frame is specially handled in the runtime. See the comment above LOCAL_RETVALID.
+	LEAQ	LOCAL_REGARGS(SP), R12
+	CALL	runtime·spillArgs<ABIInternal>(SB)
+	MOVQ	DX, 24(SP) // outside of moveMakeFuncArgPtrs's arg area
+	MOVQ	DX, 0(SP)
+	MOVQ	R12, 8(SP)
+	CALL	·moveMakeFuncArgPtrs(SB)
+	MOVQ	24(SP), DX
 	MOVQ	DX, 0(SP)
 	LEAQ	argframe+0(FP), CX
 	MOVQ	CX, 8(SP)
-	MOVB	$0, 24(SP)
-	LEAQ	24(SP), AX
+	MOVB	$0, LOCAL_RETVALID(SP)
+	LEAQ	LOCAL_RETVALID(SP), AX
 	MOVQ	AX, 16(SP)
-	CALL	·callMethod<ABIInternal>(SB)
+	LEAQ	LOCAL_REGARGS(SP), AX
+	MOVQ	AX, 24(SP)
+	CALL	·callMethod(SB)
+	LEAQ	LOCAL_REGARGS(SP), R12
+	CALL	runtime·unspillArgs<ABIInternal>(SB)
 	RET
diff --git a/src/reflect/asm_arm.s b/src/reflect/asm_arm.s
index cd50d33..057c941 100644
--- a/src/reflect/asm_arm.s
+++ b/src/reflect/asm_arm.s
@@ -9,15 +9,17 @@
 // See the comment on the declaration of makeFuncStub in makefunc.go
 // for more details.
 // No argsize here, gc generates argsize info at call site.
-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$16
+TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$20
 	NO_LOCAL_POINTERS
 	MOVW	R7, 4(R13)
 	MOVW	$argframe+0(FP), R1
 	MOVW	R1, 8(R13)
 	MOVW	$0, R1
-	MOVB	R1, 16(R13)
-	ADD	$16, R13, R1
+	MOVB	R1, 20(R13)
+	ADD	$20, R13, R1
 	MOVW	R1, 12(R13)
+	MOVW	$0, R1
+	MOVW	R1, 16(R13)
 	BL	·callReflect(SB)
 	RET
 
@@ -25,14 +27,16 @@
 // See the comment on the declaration of methodValueCall in makefunc.go
 // for more details.
 // No argsize here, gc generates argsize info at call site.
-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$16
+TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$20
 	NO_LOCAL_POINTERS
 	MOVW	R7, 4(R13)
 	MOVW	$argframe+0(FP), R1
 	MOVW	R1, 8(R13)
 	MOVW	$0, R1
-	MOVB	R1, 16(R13)
-	ADD	$16, R13, R1
+	MOVB	R1, 20(R13)
+	ADD	$20, R13, R1
 	MOVW	R1, 12(R13)
+	MOVW	$0, R1
+	MOVW	R1, 16(R13)
 	BL	·callMethod(SB)
 	RET
diff --git a/src/reflect/asm_arm64.s b/src/reflect/asm_arm64.s
index 28bb86c..5fe88e2 100644
--- a/src/reflect/asm_arm64.s
+++ b/src/reflect/asm_arm64.s
@@ -14,9 +14,10 @@
 	MOVD	R26, 8(RSP)
 	MOVD	$argframe+0(FP), R3
 	MOVD	R3, 16(RSP)
-	MOVB	$0, 32(RSP)
-	ADD	$32, RSP, R3
+	MOVB	$0, 40(RSP)
+	ADD	$40, RSP, R3
 	MOVD	R3, 24(RSP)
+	MOVD	$0, 32(RSP)
 	BL	·callReflect(SB)
 	RET
 
@@ -29,8 +30,9 @@
 	MOVD	R26, 8(RSP)
 	MOVD	$argframe+0(FP), R3
 	MOVD	R3, 16(RSP)
-	MOVB	$0, 32(RSP)
-	ADD	$32, RSP, R3
+	MOVB	$0, 40(RSP)
+	ADD	$40, RSP, R3
 	MOVD	R3, 24(RSP)
+	MOVD	$0, 32(RSP)
 	BL	·callMethod(SB)
 	RET
diff --git a/src/reflect/asm_mips64x.s b/src/reflect/asm_mips64x.s
index 6f76685..8d01c5f 100644
--- a/src/reflect/asm_mips64x.s
+++ b/src/reflect/asm_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "textflag.h"
@@ -13,14 +14,15 @@
 // See the comment on the declaration of makeFuncStub in makefunc.go
 // for more details.
 // No arg size here, runtime pulls arg map out of the func value.
-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$32
+TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$40
 	NO_LOCAL_POINTERS
 	MOVV	REGCTXT, 8(R29)
 	MOVV	$argframe+0(FP), R1
 	MOVV	R1, 16(R29)
-	MOVB	R0, 32(R29)
-	ADDV	$32, R29, R1
+	MOVB	R0, 40(R29)
+	ADDV	$40, R29, R1
 	MOVV	R1, 24(R29)
+	MOVV	R0, 32(R29)
 	JAL	·callReflect(SB)
 	RET
 
@@ -28,13 +30,14 @@
 // See the comment on the declaration of methodValueCall in makefunc.go
 // for more details.
 // No arg size here; runtime pulls arg map out of the func value.
-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$32
+TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$40
 	NO_LOCAL_POINTERS
 	MOVV	REGCTXT, 8(R29)
 	MOVV	$argframe+0(FP), R1
 	MOVV	R1, 16(R29)
-	MOVB	R0, 32(R29)
-	ADDV	$32, R29, R1
+	MOVB	R0, 40(R29)
+	ADDV	$40, R29, R1
 	MOVV	R1, 24(R29)
+	MOVV	R0, 32(R29)
 	JAL	·callMethod(SB)
 	RET
diff --git a/src/reflect/asm_mipsx.s b/src/reflect/asm_mipsx.s
index 5a5c53e..6ea8233 100644
--- a/src/reflect/asm_mipsx.s
+++ b/src/reflect/asm_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "textflag.h"
@@ -13,14 +14,15 @@
 // See the comment on the declaration of makeFuncStub in makefunc.go
 // for more details.
 // No arg size here, runtime pulls arg map out of the func value.
-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$16
+TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$20
 	NO_LOCAL_POINTERS
 	MOVW	REGCTXT, 4(R29)
 	MOVW	$argframe+0(FP), R1
 	MOVW	R1, 8(R29)
-	MOVB	R0, 16(R29)
-	ADD	$16, R29, R1
+	MOVB	R0, 20(R29)
+	ADD	$20, R29, R1
 	MOVW	R1, 12(R29)
+	MOVW	R0, 16(R29)
 	JAL	·callReflect(SB)
 	RET
 
@@ -28,13 +30,14 @@
 // See the comment on the declaration of methodValueCall in makefunc.go
 // for more details.
 // No arg size here; runtime pulls arg map out of the func value.
-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$16
+TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$20
 	NO_LOCAL_POINTERS
 	MOVW	REGCTXT, 4(R29)
 	MOVW	$argframe+0(FP), R1
 	MOVW	R1, 8(R29)
-	MOVB	R0, 16(R29)
-	ADD	$16, R29, R1
+	MOVB	R0, 20(R29)
+	ADD	$20, R29, R1
 	MOVW	R1, 12(R29)
+	MOVW	R0, 16(R29)
 	JAL	·callMethod(SB)
 	RET
diff --git a/src/reflect/asm_ppc64x.s b/src/reflect/asm_ppc64x.s
index 4609f6b..d955e41 100644
--- a/src/reflect/asm_ppc64x.s
+++ b/src/reflect/asm_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "textflag.h"
@@ -12,14 +13,15 @@
 // See the comment on the declaration of makeFuncStub in makefunc.go
 // for more details.
 // No arg size here, runtime pulls arg map out of the func value.
-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$32
+TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$40
 	NO_LOCAL_POINTERS
 	MOVD	R11, FIXED_FRAME+0(R1)
 	MOVD	$argframe+0(FP), R3
 	MOVD	R3, FIXED_FRAME+8(R1)
-	MOVB	R0, FIXED_FRAME+24(R1)
-	ADD	$FIXED_FRAME+24, R1, R3
+	MOVB	R0, FIXED_FRAME+32(R1)
+	ADD	$FIXED_FRAME+32, R1, R3
 	MOVD	R3, FIXED_FRAME+16(R1)
+	MOVD	R0, FIXED_FRAME+24(R1)
 	BL	·callReflect(SB)
 	RET
 
@@ -27,13 +29,14 @@
 // See the comment on the declaration of methodValueCall in makefunc.go
 // for more details.
 // No arg size here; runtime pulls arg map out of the func value.
-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$32
+TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$40
 	NO_LOCAL_POINTERS
 	MOVD	R11, FIXED_FRAME+0(R1)
 	MOVD	$argframe+0(FP), R3
 	MOVD	R3, FIXED_FRAME+8(R1)
-	MOVB	R0, FIXED_FRAME+24(R1)
-	ADD	$FIXED_FRAME+24, R1, R3
+	MOVB	R0, FIXED_FRAME+32(R1)
+	ADD	$FIXED_FRAME+32, R1, R3
 	MOVD	R3, FIXED_FRAME+16(R1)
+	MOVD	R0, FIXED_FRAME+24(R1)
 	BL	·callMethod(SB)
 	RET
diff --git a/src/reflect/asm_riscv64.s b/src/reflect/asm_riscv64.s
index e6fab39..e707112 100644
--- a/src/reflect/asm_riscv64.s
+++ b/src/reflect/asm_riscv64.s
@@ -9,14 +9,15 @@
 // See the comment on the declaration of makeFuncStub in makefunc.go
 // for more details.
 // No arg size here, runtime pulls arg map out of the func value.
-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$32
+TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$40
 	NO_LOCAL_POINTERS
 	MOV	CTXT, 8(SP)
 	MOV	$argframe+0(FP), T0
 	MOV	T0, 16(SP)
-	ADD	$32, SP, T1
+	ADD	$40, SP, T1
 	MOV	T1, 24(SP)
-	MOVB	ZERO, 32(SP)
+	MOV	ZERO, 32(SP)
+	MOVB	ZERO, 40(SP)
 	CALL	·callReflect(SB)
 	RET
 
@@ -24,13 +25,14 @@
 // See the comment on the declaration of methodValueCall in makefunc.go
 // for more details.
 // No arg size here; runtime pulls arg map out of the func value.
-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$32
+TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$40
 	NO_LOCAL_POINTERS
 	MOV	CTXT, 8(SP)
 	MOV	$argframe+0(FP), T0
 	MOV	T0, 16(SP)
-	ADD	$32, SP, T1
+	ADD	$40, SP, T1
 	MOV	T1, 24(SP)
-	MOVB	ZERO, 32(SP)
+	MOV	ZERO, 32(SP)
+	MOVB	ZERO, 40(SP)
 	CALL	·callMethod(SB)
 	RET
diff --git a/src/reflect/asm_s390x.s b/src/reflect/asm_s390x.s
index cb7954c..4bd6613 100644
--- a/src/reflect/asm_s390x.s
+++ b/src/reflect/asm_s390x.s
@@ -9,14 +9,15 @@
 // See the comment on the declaration of makeFuncStub in makefunc.go
 // for more details.
 // No arg size here, runtime pulls arg map out of the func value.
-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$32
+TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$40
 	NO_LOCAL_POINTERS
 	MOVD	R12, 8(R15)
 	MOVD	$argframe+0(FP), R3
 	MOVD	R3, 16(R15)
-	MOVB	$0, 32(R15)
-	ADD	$32, R15, R3
+	MOVB	$0, 40(R15)
+	ADD	$40, R15, R3
 	MOVD	R3, 24(R15)
+	MOVD	$0, 32(R15)
 	BL	·callReflect(SB)
 	RET
 
@@ -24,13 +25,14 @@
 // See the comment on the declaration of methodValueCall in makefunc.go
 // for more details.
 // No arg size here; runtime pulls arg map out of the func value.
-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$32
+TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$40
 	NO_LOCAL_POINTERS
 	MOVD	R12, 8(R15)
 	MOVD	$argframe+0(FP), R3
 	MOVD	R3, 16(R15)
-	MOVB	$0, 32(R15)
-	ADD	$32, R15, R3
+	MOVB	$0, 40(R15)
+	ADD	$40, R15, R3
 	MOVD	R3, 24(R15)
+	MOVD	$0, 32(R15)
 	BL	·callMethod(SB)
 	RET
diff --git a/src/reflect/asm_wasm.s b/src/reflect/asm_wasm.s
index 63b4d94..71abe67 100644
--- a/src/reflect/asm_wasm.s
+++ b/src/reflect/asm_wasm.s
@@ -9,7 +9,7 @@
 // See the comment on the declaration of makeFuncStub in makefunc.go
 // for more details.
 // No arg size here; runtime pulls arg map out of the func value.
-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$32
+TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$40
 	NO_LOCAL_POINTERS
 
 	MOVD CTXT, 0(SP)
@@ -21,8 +21,9 @@
 	I64Add
 	I64Store $8
 
-	MOVB $0, 24(SP)
-	MOVD $24(SP), 16(SP)
+	MOVB $0, 32(SP)
+	MOVD $32(SP), 16(SP)
+	MOVD $0, 24(SP)
 
 	CALL ·callReflect(SB)
 	RET
@@ -31,7 +32,7 @@
 // See the comment on the declaration of methodValueCall in makefunc.go
 // for more details.
 // No arg size here; runtime pulls arg map out of the func value.
-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$32
+TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$40
 	NO_LOCAL_POINTERS
 
 	MOVD CTXT, 0(SP)
@@ -43,8 +44,9 @@
 	I64Add
 	I64Store $8
 
-	MOVB $0, 24(SP)
-	MOVD $24(SP), 16(SP)
+	MOVB $0, 32(SP)
+	MOVD $32(SP), 16(SP)
+	MOVD $0, 24(SP)
 
 	CALL ·callMethod(SB)
 	RET
diff --git a/src/reflect/export_test.go b/src/reflect/export_test.go
index de426b5..b6830a9 100644
--- a/src/reflect/export_test.go
+++ b/src/reflect/export_test.go
@@ -4,7 +4,10 @@
 
 package reflect
 
-import "unsafe"
+import (
+	"sync"
+	"unsafe"
+)
 
 // MakeRO returns a copy of v with the read-only flag set.
 func MakeRO(v Value) Value {
@@ -21,21 +24,45 @@
 
 const PtrSize = ptrSize
 
-func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr, stack []byte, gc []byte, ptrs bool) {
+// FuncLayout calls funcLayout and returns a subset of the results for testing.
+//
+// Bitmaps like stack, gc, inReg, and outReg are expanded such that each bit
+// takes up one byte, so that writing out test cases is a little clearer.
+// If ptrs is false, gc will be nil.
+func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr, stack, gc, inReg, outReg []byte, ptrs bool) {
 	var ft *rtype
-	var s *bitVector
+	var abid abiDesc
 	if rcvr != nil {
-		ft, argSize, retOffset, s, _ = funcLayout((*funcType)(unsafe.Pointer(t.(*rtype))), rcvr.(*rtype))
+		ft, _, abid = funcLayout((*funcType)(unsafe.Pointer(t.(*rtype))), rcvr.(*rtype))
 	} else {
-		ft, argSize, retOffset, s, _ = funcLayout((*funcType)(unsafe.Pointer(t.(*rtype))), nil)
+		ft, _, abid = funcLayout((*funcType)(unsafe.Pointer(t.(*rtype))), nil)
 	}
+	// Extract size information.
+	argSize = abid.stackCallArgsSize
+	retOffset = abid.retOffset
 	frametype = ft
-	for i := uint32(0); i < s.n; i++ {
-		stack = append(stack, s.data[i/8]>>(i%8)&1)
+
+	// Expand stack pointer bitmap into byte-map.
+	for i := uint32(0); i < abid.stackPtrs.n; i++ {
+		stack = append(stack, abid.stackPtrs.data[i/8]>>(i%8)&1)
+	}
+
+	// Expand register pointer bitmaps into byte-maps.
+	bool2byte := func(b bool) byte {
+		if b {
+			return 1
+		}
+		return 0
+	}
+	for i := 0; i < intArgRegs; i++ {
+		inReg = append(inReg, bool2byte(abid.inRegPtrs.Get(i)))
+		outReg = append(outReg, bool2byte(abid.outRegPtrs.Get(i)))
 	}
 	if ft.kind&kindGCProg != 0 {
 		panic("can't handle gc programs")
 	}
+
+	// Expand frame type's GC bitmap into byte-map.
 	ptrs = ft.ptrdata != 0
 	if ptrs {
 		nptrs := ft.ptrdata / ptrSize
@@ -120,3 +147,18 @@
 type Buffer struct {
 	buf []byte
 }
+
+func clearLayoutCache() {
+	layoutCache = sync.Map{}
+}
+
+func SetArgRegs(ints, floats int, floatSize uintptr) (oldInts, oldFloats int, oldFloatSize uintptr) {
+	oldInts = intArgRegs
+	oldFloats = floatArgRegs
+	oldFloatSize = floatRegSize
+	intArgRegs = ints
+	floatArgRegs = floats
+	floatRegSize = floatSize
+	clearLayoutCache()
+	return
+}
diff --git a/src/reflect/internal/example1/example.go b/src/reflect/internal/example1/example.go
new file mode 100644
index 0000000..0f829a8
--- /dev/null
+++ b/src/reflect/internal/example1/example.go
@@ -0,0 +1,6 @@
+package example1
+
+type MyStruct struct {
+	MyStructs []MyStruct
+	MyStruct  *MyStruct
+}
diff --git a/src/reflect/internal/example2/example.go b/src/reflect/internal/example2/example.go
new file mode 100644
index 0000000..df64ba1
--- /dev/null
+++ b/src/reflect/internal/example2/example.go
@@ -0,0 +1,6 @@
+package example2
+
+type MyStruct struct {
+	MyStructs []MyStruct
+	MyStruct  *MyStruct
+}
diff --git a/src/reflect/makefunc.go b/src/reflect/makefunc.go
index 67dc485..d53e68a 100644
--- a/src/reflect/makefunc.go
+++ b/src/reflect/makefunc.go
@@ -7,6 +7,7 @@
 package reflect
 
 import (
+	"internal/abi"
 	"unsafe"
 )
 
@@ -16,11 +17,9 @@
 // methodValue and runtime.reflectMethodValue.
 // Any changes should be reflected in all three.
 type makeFuncImpl struct {
-	code   uintptr
-	stack  *bitVector // ptrmap for both args and results
-	argLen uintptr    // just args
-	ftyp   *funcType
-	fn     func([]Value) []Value
+	makeFuncCtxt
+	ftyp *funcType
+	fn   func([]Value) []Value
 }
 
 // MakeFunc returns a new function of the given Type
@@ -60,9 +59,18 @@
 	code := **(**uintptr)(unsafe.Pointer(&dummy))
 
 	// makeFuncImpl contains a stack map for use by the runtime
-	_, argLen, _, stack, _ := funcLayout(ftyp, nil)
+	_, _, abi := funcLayout(ftyp, nil)
 
-	impl := &makeFuncImpl{code: code, stack: stack, argLen: argLen, ftyp: ftyp, fn: fn}
+	impl := &makeFuncImpl{
+		makeFuncCtxt: makeFuncCtxt{
+			fn:      code,
+			stack:   abi.stackPtrs,
+			argLen:  abi.stackCallArgsSize,
+			regPtrs: abi.inRegPtrs,
+		},
+		ftyp: ftyp,
+		fn:   fn,
+	}
 
 	return Value{t, unsafe.Pointer(impl), flag(Func)}
 }
@@ -78,9 +86,7 @@
 // makeFuncImpl and runtime.reflectMethodValue.
 // Any changes should be reflected in all three.
 type methodValue struct {
-	fn     uintptr
-	stack  *bitVector // ptrmap for both args and results
-	argLen uintptr    // just args
+	makeFuncCtxt
 	method int
 	rcvr   Value
 }
@@ -112,12 +118,14 @@
 	code := **(**uintptr)(unsafe.Pointer(&dummy))
 
 	// methodValue contains a stack map for use by the runtime
-	_, argLen, _, stack, _ := funcLayout(ftyp, nil)
-
+	_, _, abi := funcLayout(ftyp, nil)
 	fv := &methodValue{
-		fn:     code,
-		stack:  stack,
-		argLen: argLen,
+		makeFuncCtxt: makeFuncCtxt{
+			fn:      code,
+			stack:   abi.stackPtrs,
+			argLen:  abi.stackCallArgsSize,
+			regPtrs: abi.inRegPtrs,
+		},
 		method: int(v.flag) >> flagMethodShift,
 		rcvr:   rcvr,
 	}
@@ -136,3 +144,37 @@
 // where ctxt is the context register and frame is a pointer to the first
 // word in the passed-in argument frame.
 func methodValueCall()
+
+// This structure must be kept in sync with runtime.reflectMethodValue.
+// Any changes should be reflected in all both.
+type makeFuncCtxt struct {
+	fn      uintptr
+	stack   *bitVector // ptrmap for both stack args and results
+	argLen  uintptr    // just args
+	regPtrs abi.IntArgRegBitmap
+}
+
+// moveMakeFuncArgPtrs uses ctxt.regPtrs to copy integer pointer arguments
+// in args.Ints to args.Ptrs where the GC can see them.
+//
+// This is similar to what reflectcallmove does in the runtime, except
+// that happens on the return path, whereas this happens on the call path.
+//
+// nosplit because pointers are being held in uintptr slots in args, so
+// having our stack scanned now could lead to accidentally freeing
+// memory.
+//go:nosplit
+func moveMakeFuncArgPtrs(ctxt *makeFuncCtxt, args *abi.RegArgs) {
+	for i, arg := range args.Ints {
+		// Avoid write barriers! Because our write barrier enqueues what
+		// was there before, we might enqueue garbage.
+		if ctxt.regPtrs.Get(i) {
+			*(*uintptr)(unsafe.Pointer(&args.Ptrs[i])) = arg
+		} else {
+			// We *must* zero this space ourselves because it's defined in
+			// assembly code and the GC will scan these pointers. Otherwise,
+			// there will be garbage here.
+			*(*uintptr)(unsafe.Pointer(&args.Ptrs[i])) = 0
+		}
+	}
+}
diff --git a/src/reflect/type.go b/src/reflect/type.go
index a1cdf45..f672a7a 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -106,9 +106,15 @@
 	AssignableTo(u Type) bool
 
 	// ConvertibleTo reports whether a value of the type is convertible to type u.
+	// Even if ConvertibleTo returns true, the conversion may still panic.
+	// For example, a slice of type []T is convertible to *[N]T,
+	// but the conversion will panic if its length is less than N.
 	ConvertibleTo(u Type) bool
 
 	// Comparable reports whether values of this type are comparable.
+	// Even if Comparable returns true, the comparison may still panic.
+	// For example, values of interface type are comparable,
+	// but the comparison will panic if their dynamic type is not comparable.
 	Comparable() bool
 
 	// Methods applicable only to some types, depending on Kind.
@@ -222,7 +228,7 @@
 // See https://golang.org/issue/4876 for more details.
 
 /*
- * These data structures are known to the compiler (../../cmd/internal/gc/reflect.go).
+ * These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go).
  * A few are known to ../runtime/type.go to convey to debuggers.
  * They are also known to ../runtime/type.go.
  */
@@ -265,7 +271,7 @@
 // available in the memory directly following the rtype value.
 //
 // tflag values must be kept in sync with copies in:
-//	cmd/compile/internal/gc/reflect.go
+//	cmd/compile/internal/reflectdata/reflect.go
 //	cmd/link/internal/ld/decodesym.go
 //	runtime/type.go
 type tflag uint8
@@ -448,14 +454,11 @@
 //	1<<1 tag data follows the name
 //	1<<2 pkgPath nameOff follows the name and tag
 //
-// The next two bytes are the data length:
+// Following that, there is a varint-encoded length of the name,
+// followed by the name itself.
 //
-//	 l := uint16(data[1])<<8 | uint16(data[2])
-//
-// Bytes [3:3+l] are the string data.
-//
-// If tag data follows then bytes 3+l and 3+l+1 are the tag length,
-// with the data following.
+// If tag data is present, it also has a varint-encoded length
+// followed by the tag itself.
 //
 // If the import path follows, then 4 bytes at the end of
 // the data form a nameOff. The import path is only set for concrete
@@ -463,6 +466,13 @@
 //
 // If a name starts with "*", then the exported bit represents
 // whether the pointed to type is exported.
+//
+// Note: this encoding must match here and in:
+//   cmd/compile/internal/reflectdata/reflect.go
+//   runtime/type.go
+//   internal/reflectlite/type.go
+//   cmd/link/internal/ld/decodesym.go
+
 type name struct {
 	bytes *byte
 }
@@ -475,49 +485,70 @@
 	return (*n.bytes)&(1<<0) != 0
 }
 
-func (n name) nameLen() int {
-	return int(uint16(*n.data(1, "name len field"))<<8 | uint16(*n.data(2, "name len field")))
+func (n name) hasTag() bool {
+	return (*n.bytes)&(1<<1) != 0
 }
 
-func (n name) tagLen() int {
-	if *n.data(0, "name flag field")&(1<<1) == 0 {
-		return 0
+// readVarint parses a varint as encoded by encoding/binary.
+// It returns the number of encoded bytes and the encoded value.
+func (n name) readVarint(off int) (int, int) {
+	v := 0
+	for i := 0; ; i++ {
+		x := *n.data(off+i, "read varint")
+		v += int(x&0x7f) << (7 * i)
+		if x&0x80 == 0 {
+			return i + 1, v
+		}
 	}
-	off := 3 + n.nameLen()
-	return int(uint16(*n.data(off, "name taglen field"))<<8 | uint16(*n.data(off+1, "name taglen field")))
+}
+
+// writeVarint writes n to buf in varint form. Returns the
+// number of bytes written. n must be nonnegative.
+// Writes at most 10 bytes.
+func writeVarint(buf []byte, n int) int {
+	for i := 0; ; i++ {
+		b := byte(n & 0x7f)
+		n >>= 7
+		if n == 0 {
+			buf[i] = b
+			return i + 1
+		}
+		buf[i] = b | 0x80
+	}
 }
 
 func (n name) name() (s string) {
 	if n.bytes == nil {
 		return
 	}
-	b := (*[4]byte)(unsafe.Pointer(n.bytes))
-
+	i, l := n.readVarint(1)
 	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
-	hdr.Data = unsafe.Pointer(&b[3])
-	hdr.Len = int(b[1])<<8 | int(b[2])
-	return s
+	hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string"))
+	hdr.Len = l
+	return
 }
 
 func (n name) tag() (s string) {
-	tl := n.tagLen()
-	if tl == 0 {
+	if !n.hasTag() {
 		return ""
 	}
-	nl := n.nameLen()
+	i, l := n.readVarint(1)
+	i2, l2 := n.readVarint(1 + i + l)
 	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
-	hdr.Data = unsafe.Pointer(n.data(3+nl+2, "non-empty string"))
-	hdr.Len = tl
-	return s
+	hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string"))
+	hdr.Len = l2
+	return
 }
 
 func (n name) pkgPath() string {
 	if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 {
 		return ""
 	}
-	off := 3 + n.nameLen()
-	if tl := n.tagLen(); tl > 0 {
-		off += 2 + tl
+	i, l := n.readVarint(1)
+	off := 1 + i + l
+	if n.hasTag() {
+		i2, l2 := n.readVarint(off)
+		off += i2 + l2
 	}
 	var nameOff int32
 	// Note that this field may not be aligned in memory,
@@ -528,33 +559,35 @@
 }
 
 func newName(n, tag string, exported bool) name {
-	if len(n) > 1<<16-1 {
-		panic("reflect.nameFrom: name too long: " + n)
+	if len(n) >= 1<<29 {
+		panic("reflect.nameFrom: name too long: " + n[:1024] + "...")
 	}
-	if len(tag) > 1<<16-1 {
-		panic("reflect.nameFrom: tag too long: " + tag)
+	if len(tag) >= 1<<29 {
+		panic("reflect.nameFrom: tag too long: " + tag[:1024] + "...")
 	}
+	var nameLen [10]byte
+	var tagLen [10]byte
+	nameLenLen := writeVarint(nameLen[:], len(n))
+	tagLenLen := writeVarint(tagLen[:], len(tag))
 
 	var bits byte
-	l := 1 + 2 + len(n)
+	l := 1 + nameLenLen + len(n)
 	if exported {
 		bits |= 1 << 0
 	}
 	if len(tag) > 0 {
-		l += 2 + len(tag)
+		l += tagLenLen + len(tag)
 		bits |= 1 << 1
 	}
 
 	b := make([]byte, l)
 	b[0] = bits
-	b[1] = uint8(len(n) >> 8)
-	b[2] = uint8(len(n))
-	copy(b[3:], n)
+	copy(b[1:], nameLen[:nameLenLen])
+	copy(b[1+nameLenLen:], n)
 	if len(tag) > 0 {
-		tb := b[3+len(n):]
-		tb[0] = uint8(len(tag) >> 8)
-		tb[1] = uint8(len(tag))
-		copy(tb[2:], tag)
+		tb := b[1+nameLenLen+len(n):]
+		copy(tb, tagLen[:tagLenLen])
+		copy(tb[tagLenLen:], tag)
 	}
 
 	return name{bytes: &b[0]}
@@ -568,12 +601,13 @@
 // Method represents a single method.
 type Method struct {
 	// Name is the method name.
+	Name string
+
 	// PkgPath is the package path that qualifies a lower case (unexported)
 	// method name. It is empty for upper case (exported) method names.
 	// The combination of PkgPath and Name uniquely identifies a method
 	// in a method set.
 	// See https://golang.org/ref/spec#Uniqueness_of_identifiers
-	Name    string
 	PkgPath string
 
 	Type  Type  // method type
@@ -581,6 +615,11 @@
 	Index int   // index for Type.Method
 }
 
+// IsExported reports whether the method is exported.
+func (m Method) IsExported() bool {
+	return m.PkgPath == ""
+}
+
 const (
 	kindDirectIface = 1 << 5
 	kindGCProg      = 1 << 6 // Type.gc points to GC program
@@ -1090,6 +1129,7 @@
 type StructField struct {
 	// Name is the field name.
 	Name string
+
 	// PkgPath is the package path that qualifies a lower case (unexported)
 	// field name. It is empty for upper case (exported) field names.
 	// See https://golang.org/ref/spec#Uniqueness_of_identifiers
@@ -1102,6 +1142,11 @@
 	Anonymous bool      // is an embedded field
 }
 
+// IsExported reports whether the field is exported.
+func (f StructField) IsExported() bool {
+	return f.PkgPath == ""
+}
+
 // A StructTag is the tag string in a struct field.
 //
 // By convention, tag strings are a concatenation of
@@ -1587,7 +1632,7 @@
 		return T == V
 	}
 
-	if T.Name() != V.Name() || T.Kind() != V.Kind() {
+	if T.Name() != V.Name() || T.Kind() != V.Kind() || T.PkgPath() != V.PkgPath() {
 		return false
 	}
 
@@ -1723,7 +1768,7 @@
 		// This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s).
 		i, j := 0, len(offs)
 		for i < j {
-			h := i + (j-i)/2 // avoid overflow when computing h
+			h := i + (j-i)>>1 // avoid overflow when computing h
 			// i ≤ h < j
 			if !(rtypeOff(section, offs[h]).String() >= s) {
 				i = h + 1 // preserves f(i-1) == false
@@ -1865,7 +1910,7 @@
 
 	// Make a map type.
 	// Note: flag values must match those used in the TMAP case
-	// in ../cmd/compile/internal/gc/reflect.go:dtypesym.
+	// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
 	var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
 	mt := **(**mapType)(unsafe.Pointer(&imap))
 	mt.str = resolveReflectName(newName(s, "", false))
@@ -2556,7 +2601,7 @@
 		hash = fnv1(hash, byte(ft.hash>>24), byte(ft.hash>>16), byte(ft.hash>>8), byte(ft.hash))
 
 		repr = append(repr, (" " + ft.String())...)
-		if f.name.tagLen() > 0 {
+		if f.name.hasTag() {
 			hash = fnv1(hash, []byte(f.name.tag())...)
 			repr = append(repr, (" " + strconv.Quote(f.name.tag()))...)
 		}
@@ -2771,8 +2816,7 @@
 		panic("reflect.StructOf: field \"" + field.Name + "\" is anonymous but has PkgPath set")
 	}
 
-	exported := field.PkgPath == ""
-	if exported {
+	if field.IsExported() {
 		// Best-effort check for misuse.
 		// Since this field will be treated as exported, not much harm done if Unicode lowercase slips through.
 		c := field.Name[0]
@@ -2788,7 +2832,7 @@
 
 	resolveReflectType(field.Type.common()) // install in runtime
 	f := structField{
-		name:        newName(field.Name, string(field.Tag), exported),
+		name:        newName(field.Name, string(field.Tag), field.IsExported()),
 		typ:         field.Type.common(),
 		offsetEmbed: offsetEmbed,
 	}
@@ -2797,7 +2841,7 @@
 
 // typeptrdata returns the length in bytes of the prefix of t
 // containing pointer data. Anything after this offset is scalar data.
-// keep in sync with ../cmd/compile/internal/gc/reflect.go
+// keep in sync with ../cmd/compile/internal/reflectdata/reflect.go
 func typeptrdata(t *rtype) uintptr {
 	switch t.Kind() {
 	case Struct:
@@ -2821,25 +2865,29 @@
 	}
 }
 
-// See cmd/compile/internal/gc/reflect.go for derivation of constant.
+// See cmd/compile/internal/reflectdata/reflect.go for derivation of constant.
 const maxPtrmaskBytes = 2048
 
-// ArrayOf returns the array type with the given count and element type.
+// ArrayOf returns the array type with the given length and element type.
 // For example, if t represents int, ArrayOf(5, t) represents [5]int.
 //
 // If the resulting type would be larger than the available address space,
 // ArrayOf panics.
-func ArrayOf(count int, elem Type) Type {
+func ArrayOf(length int, elem Type) Type {
+	if length < 0 {
+		panic("reflect: negative length passed to ArrayOf")
+	}
+
 	typ := elem.(*rtype)
 
 	// Look in cache.
-	ckey := cacheKey{Array, typ, nil, uintptr(count)}
+	ckey := cacheKey{Array, typ, nil, uintptr(length)}
 	if array, ok := lookupCache.Load(ckey); ok {
 		return array.(Type)
 	}
 
 	// Look in known types.
-	s := "[" + strconv.Itoa(count) + "]" + typ.String()
+	s := "[" + strconv.Itoa(length) + "]" + typ.String()
 	for _, tt := range typesByString(s) {
 		array := (*arrayType)(unsafe.Pointer(tt))
 		if array.elem == typ {
@@ -2855,7 +2903,7 @@
 	array.tflag = typ.tflag & tflagRegularMemory
 	array.str = resolveReflectName(newName(s, "", false))
 	array.hash = fnv1(typ.hash, '[')
-	for n := uint32(count); n > 0; n >>= 8 {
+	for n := uint32(length); n > 0; n >>= 8 {
 		array.hash = fnv1(array.hash, byte(n))
 	}
 	array.hash = fnv1(array.hash, ']')
@@ -2863,17 +2911,17 @@
 	array.ptrToThis = 0
 	if typ.size > 0 {
 		max := ^uintptr(0) / typ.size
-		if uintptr(count) > max {
+		if uintptr(length) > max {
 			panic("reflect.ArrayOf: array size would exceed virtual address space")
 		}
 	}
-	array.size = typ.size * uintptr(count)
-	if count > 0 && typ.ptrdata != 0 {
-		array.ptrdata = typ.size*uintptr(count-1) + typ.ptrdata
+	array.size = typ.size * uintptr(length)
+	if length > 0 && typ.ptrdata != 0 {
+		array.ptrdata = typ.size*uintptr(length-1) + typ.ptrdata
 	}
 	array.align = typ.align
 	array.fieldAlign = typ.fieldAlign
-	array.len = uintptr(count)
+	array.len = uintptr(length)
 	array.slice = SliceOf(elem).(*rtype)
 
 	switch {
@@ -2882,7 +2930,7 @@
 		array.gcdata = nil
 		array.ptrdata = 0
 
-	case count == 1:
+	case length == 1:
 		// In memory, 1-element array looks just like the element.
 		array.kind |= typ.kind & kindGCProg
 		array.gcdata = typ.gcdata
@@ -2891,7 +2939,7 @@
 	case typ.kind&kindGCProg == 0 && array.size <= maxPtrmaskBytes*8*ptrSize:
 		// Element is small with pointer mask; array is still small.
 		// Create direct pointer mask by turning each 1 bit in elem
-		// into count 1 bits in larger mask.
+		// into length 1 bits in larger mask.
 		mask := make([]byte, (array.ptrdata/ptrSize+7)/8)
 		emitGCMask(mask, 0, typ, array.len)
 		array.gcdata = &mask[0]
@@ -2912,14 +2960,14 @@
 				prog = appendVarint(prog, elemWords-elemPtrs-1)
 			}
 		}
-		// Repeat count-1 times.
+		// Repeat length-1 times.
 		if elemWords < 0x80 {
 			prog = append(prog, byte(elemWords|0x80))
 		} else {
 			prog = append(prog, 0x80)
 			prog = appendVarint(prog, elemWords)
 		}
-		prog = appendVarint(prog, uintptr(count)-1)
+		prog = appendVarint(prog, uintptr(length)-1)
 		prog = append(prog, 0)
 		*(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4)
 		array.kind |= kindGCProg
@@ -2933,9 +2981,9 @@
 	array.equal = nil
 	if eequal := etyp.equal; eequal != nil {
 		array.equal = func(p, q unsafe.Pointer) bool {
-			for i := 0; i < count; i++ {
-				pi := arrayAt(p, i, esize, "i < count")
-				qi := arrayAt(q, i, esize, "i < count")
+			for i := 0; i < length; i++ {
+				pi := arrayAt(p, i, esize, "i < length")
+				qi := arrayAt(q, i, esize, "i < length")
 				if !eequal(pi, qi) {
 					return false
 				}
@@ -2946,7 +2994,7 @@
 	}
 
 	switch {
-	case count == 1 && !ifaceIndir(typ):
+	case length == 1 && !ifaceIndir(typ):
 		// array of 1 direct iface type can be direct
 		array.kind |= kindDirectIface
 	default:
@@ -2984,21 +3032,20 @@
 
 type layoutType struct {
 	t         *rtype
-	argSize   uintptr // size of arguments
-	retOffset uintptr // offset of return values.
-	stack     *bitVector
 	framePool *sync.Pool
+	abi       abiDesc
 }
 
 var layoutCache sync.Map // map[layoutKey]layoutType
 
 // funcLayout computes a struct type representing the layout of the
-// function arguments and return values for the function type t.
+// stack-assigned function arguments and return values for the function
+// type t.
 // If rcvr != nil, rcvr specifies the type of the receiver.
 // The returned type exists only for GC, so we only fill out GC relevant info.
 // Currently, that's just size and the GC program. We also fill in
 // the name for possible debugging use.
-func funcLayout(t *funcType, rcvr *rtype) (frametype *rtype, argSize, retOffset uintptr, stk *bitVector, framePool *sync.Pool) {
+func funcLayout(t *funcType, rcvr *rtype) (frametype *rtype, framePool *sync.Pool, abi abiDesc) {
 	if t.Kind() != Func {
 		panic("reflect: funcLayout of non-func type " + t.String())
 	}
@@ -3008,46 +3055,24 @@
 	k := layoutKey{t, rcvr}
 	if lti, ok := layoutCache.Load(k); ok {
 		lt := lti.(layoutType)
-		return lt.t, lt.argSize, lt.retOffset, lt.stack, lt.framePool
+		return lt.t, lt.framePool, lt.abi
 	}
 
-	// compute gc program & stack bitmap for arguments
-	ptrmap := new(bitVector)
-	var offset uintptr
-	if rcvr != nil {
-		// Reflect uses the "interface" calling convention for
-		// methods, where receivers take one word of argument
-		// space no matter how big they actually are.
-		if ifaceIndir(rcvr) || rcvr.pointers() {
-			ptrmap.append(1)
-		} else {
-			ptrmap.append(0)
-		}
-		offset += ptrSize
-	}
-	for _, arg := range t.in() {
-		offset += -offset & uintptr(arg.align-1)
-		addTypeBits(ptrmap, offset, arg)
-		offset += arg.size
-	}
-	argSize = offset
-	offset += -offset & (ptrSize - 1)
-	retOffset = offset
-	for _, res := range t.out() {
-		offset += -offset & uintptr(res.align-1)
-		addTypeBits(ptrmap, offset, res)
-		offset += res.size
-	}
-	offset += -offset & (ptrSize - 1)
+	// Compute the ABI layout.
+	abi = newAbiDesc(t, rcvr)
 
 	// build dummy rtype holding gc program
 	x := &rtype{
-		align:   ptrSize,
-		size:    offset,
-		ptrdata: uintptr(ptrmap.n) * ptrSize,
+		align: ptrSize,
+		// Don't add spill space here; it's only necessary in
+		// reflectcall's frame, not in the allocated frame.
+		// TODO(mknyszek): Remove this comment when register
+		// spill space in the frame is no longer required.
+		size:    align(abi.retOffset+abi.ret.stackBytes, ptrSize),
+		ptrdata: uintptr(abi.stackPtrs.n) * ptrSize,
 	}
-	if ptrmap.n > 0 {
-		x.gcdata = &ptrmap.data[0]
+	if abi.stackPtrs.n > 0 {
+		x.gcdata = &abi.stackPtrs.data[0]
 	}
 
 	var s string
@@ -3064,13 +3089,11 @@
 	}}
 	lti, _ := layoutCache.LoadOrStore(k, layoutType{
 		t:         x,
-		argSize:   argSize,
-		retOffset: retOffset,
-		stack:     ptrmap,
 		framePool: framePool,
+		abi:       abi,
 	})
 	lt := lti.(layoutType)
-	return lt.t, lt.argSize, lt.retOffset, lt.stack, lt.framePool
+	return lt.t, lt.framePool, lt.abi
 }
 
 // ifaceIndir reports whether t is stored indirectly in an interface value.
diff --git a/src/reflect/value.go b/src/reflect/value.go
index 1f185b5..6f878eb 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -5,6 +5,8 @@
 package reflect
 
 import (
+	"internal/abi"
+	"internal/itoa"
 	"internal/unsafeheader"
 	"math"
 	"runtime"
@@ -352,6 +354,8 @@
 
 var callGC bool // for testing; see TestCallMethodJump
 
+const debugReflectCall = false
+
 func (v Value) call(op string, in []Value) []Value {
 	// Get function pointer, type.
 	t := (*funcType)(unsafe.Pointer(v.typ))
@@ -375,8 +379,9 @@
 
 	isSlice := op == "CallSlice"
 	n := t.NumIn()
+	isVariadic := t.IsVariadic()
 	if isSlice {
-		if !t.IsVariadic() {
+		if !isVariadic {
 			panic("reflect: CallSlice of non-variadic function")
 		}
 		if len(in) < n {
@@ -386,13 +391,13 @@
 			panic("reflect: CallSlice with too many input arguments")
 		}
 	} else {
-		if t.IsVariadic() {
+		if isVariadic {
 			n--
 		}
 		if len(in) < n {
 			panic("reflect: Call with too few input arguments")
 		}
-		if !t.IsVariadic() && len(in) > n {
+		if !isVariadic && len(in) > n {
 			panic("reflect: Call with too many input arguments")
 		}
 	}
@@ -406,7 +411,7 @@
 			panic("reflect: " + op + " using " + xt.String() + " as type " + targ.String())
 		}
 	}
-	if !isSlice && t.IsVariadic() {
+	if !isSlice && isVariadic {
 		// prepare slice for remaining values
 		m := len(in) - n
 		slice := MakeSlice(t.In(n), m, m)
@@ -430,50 +435,112 @@
 	}
 	nout := t.NumOut()
 
-	// Compute frame type.
-	frametype, _, retOffset, _, framePool := funcLayout(t, rcvrtype)
+	// Register argument space.
+	var regArgs abi.RegArgs
 
-	// Allocate a chunk of memory for frame.
-	var args unsafe.Pointer
-	if nout == 0 {
-		args = framePool.Get().(unsafe.Pointer)
-	} else {
-		// Can't use pool if the function has return values.
-		// We will leak pointer to args in ret, so its lifetime is not scoped.
-		args = unsafe_New(frametype)
+	// Compute frame type.
+	frametype, framePool, abi := funcLayout(t, rcvrtype)
+
+	// Allocate a chunk of memory for frame if needed.
+	var stackArgs unsafe.Pointer
+	if frametype.size != 0 {
+		if nout == 0 {
+			stackArgs = framePool.Get().(unsafe.Pointer)
+		} else {
+			// Can't use pool if the function has return values.
+			// We will leak pointer to args in ret, so its lifetime is not scoped.
+			stackArgs = unsafe_New(frametype)
+		}
 	}
-	off := uintptr(0)
+	frameSize := frametype.size
+
+	if debugReflectCall {
+		println("reflect.call", t.String())
+		abi.dump()
+	}
 
 	// Copy inputs into args.
+
+	// Handle receiver.
+	inStart := 0
 	if rcvrtype != nil {
-		storeRcvr(rcvr, args)
-		off = ptrSize
+		// Guaranteed to only be one word in size,
+		// so it will only take up exactly 1 abiStep (either
+		// in a register or on the stack).
+		switch st := abi.call.steps[0]; st.kind {
+		case abiStepStack:
+			storeRcvr(rcvr, stackArgs)
+		case abiStepIntReg, abiStepPointer:
+			// Even pointers can go into the uintptr slot because
+			// they'll be kept alive by the Values referenced by
+			// this frame. Reflection forces these to be heap-allocated,
+			// so we don't need to worry about stack copying.
+			storeRcvr(rcvr, unsafe.Pointer(&regArgs.Ints[st.ireg]))
+		case abiStepFloatReg:
+			storeRcvr(rcvr, unsafe.Pointer(&regArgs.Floats[st.freg]))
+		default:
+			panic("unknown ABI parameter kind")
+		}
+		inStart = 1
 	}
+
+	// Handle arguments.
 	for i, v := range in {
 		v.mustBeExported()
 		targ := t.In(i).(*rtype)
-		a := uintptr(targ.align)
-		off = (off + a - 1) &^ (a - 1)
-		n := targ.size
-		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
+		// TODO(mknyszek): Figure out if it's possible to get some
+		// scratch space for this assignment check. Previously, it
+		// was possible to use space in the argument frame.
+		v = v.assignTo("reflect.Value.Call", targ, nil)
+	stepsLoop:
+		for _, st := range abi.call.stepsForValue(i + inStart) {
+			switch st.kind {
+			case abiStepStack:
+				// Copy values to the "stack."
+				addr := add(stackArgs, st.stkOff, "precomputed stack arg offset")
+				if v.flag&flagIndir != 0 {
+					typedmemmove(targ, addr, v.ptr)
+				} else {
+					*(*unsafe.Pointer)(addr) = v.ptr
+				}
+				// There's only one step for a stack-allocated value.
+				break stepsLoop
+			case abiStepIntReg, abiStepPointer:
+				// Copy values to "integer registers."
+				if v.flag&flagIndir != 0 {
+					offset := add(v.ptr, st.offset, "precomputed value offset")
+					memmove(unsafe.Pointer(&regArgs.Ints[st.ireg]), offset, st.size)
+				} else {
+					if st.kind == abiStepPointer {
+						// Duplicate this pointer in the pointer area of the
+						// register space. Otherwise, there's the potential for
+						// this to be the last reference to v.ptr.
+						regArgs.Ptrs[st.ireg] = v.ptr
+					}
+					regArgs.Ints[st.ireg] = uintptr(v.ptr)
+				}
+			case abiStepFloatReg:
+				// Copy values to "float registers."
+				if v.flag&flagIndir == 0 {
+					panic("attempted to copy pointer to FP register")
+				}
+				offset := add(v.ptr, st.offset, "precomputed value offset")
+				memmove(unsafe.Pointer(&regArgs.Floats[st.freg]), offset, st.size)
+			default:
+				panic("unknown ABI part kind")
+			}
 		}
-		addr := add(args, off, "n > 0")
-		v = v.assignTo("reflect.Value.Call", targ, addr)
-		if v.flag&flagIndir != 0 {
-			typedmemmove(targ, addr, v.ptr)
-		} else {
-			*(*unsafe.Pointer)(addr) = v.ptr
-		}
-		off += n
 	}
+	// TODO(mknyszek): Remove this when we no longer have
+	// caller reserved spill space.
+	frameSize = align(frameSize, ptrSize)
+	frameSize += abi.spill
+
+	// Mark pointers in registers for the return path.
+	regArgs.ReturnIsPtr = abi.outRegPtrs
 
 	// Call.
-	call(frametype, fn, args, uint32(frametype.size), uint32(retOffset))
+	call(frametype, fn, stackArgs, uint32(frametype.size), uint32(abi.retOffset), uint32(frameSize), &regArgs)
 
 	// For testing; see TestCallMethodJump.
 	if callGC {
@@ -482,34 +549,82 @@
 
 	var ret []Value
 	if nout == 0 {
-		typedmemclr(frametype, args)
-		framePool.Put(args)
+		if stackArgs != nil {
+			typedmemclr(frametype, stackArgs)
+			framePool.Put(stackArgs)
+		}
 	} else {
-		// Zero the now unused input area of args,
-		// because the Values returned by this function contain pointers to the args object,
-		// and will thus keep the args object alive indefinitely.
-		typedmemclrpartial(frametype, args, 0, retOffset)
+		if stackArgs != nil {
+			// Zero the now unused input area of args,
+			// because the Values returned by this function contain pointers to the args object,
+			// and will thus keep the args object alive indefinitely.
+			typedmemclrpartial(frametype, stackArgs, 0, abi.retOffset)
+		}
 
 		// Wrap Values around return values in args.
 		ret = make([]Value, nout)
-		off = retOffset
 		for i := 0; i < nout; i++ {
 			tv := t.Out(i)
-			a := uintptr(tv.Align())
-			off = (off + a - 1) &^ (a - 1)
-			if tv.Size() != 0 {
+			if tv.Size() == 0 {
+				// 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)
+				continue
+			}
+			steps := abi.ret.stepsForValue(i)
+			if st := steps[0]; st.kind == abiStepStack {
+				// This value is on the stack. If part of a value is stack
+				// allocated, the entire value is according to the ABI. So
+				// just make an indirection into the allocated frame.
 				fl := flagIndir | flag(tv.Kind())
-				ret[i] = Value{tv.common(), add(args, off, "tv.Size() != 0"), fl}
+				ret[i] = Value{tv.common(), add(stackArgs, st.stkOff, "tv.Size() != 0"), fl}
 				// Note: this does introduce false sharing between results -
 				// if any result is live, they are all live.
 				// (And the space for the args is live as well, but as we've
 				// cleared that space it isn't as big a deal.)
-			} 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)
+				continue
 			}
-			off += tv.Size()
+
+			// Handle pointers passed in registers.
+			if !ifaceIndir(tv.common()) {
+				// Pointer-valued data gets put directly
+				// into v.ptr.
+				if steps[0].kind != abiStepPointer {
+					print("kind=", steps[0].kind, ", type=", tv.String(), "\n")
+					panic("mismatch between ABI description and types")
+				}
+				ret[i] = Value{tv.common(), regArgs.Ptrs[steps[0].ireg], flag(tv.Kind())}
+				continue
+			}
+
+			// All that's left is values passed in registers that we need to
+			// create space for and copy values back into.
+			//
+			// TODO(mknyszek): We make a new allocation for each register-allocated
+			// value, but previously we could always point into the heap-allocated
+			// stack frame. This is a regression that could be fixed by adding
+			// additional space to the allocated stack frame and storing the
+			// register-allocated return values into the allocated stack frame and
+			// referring there in the resulting Value.
+			s := unsafe_New(tv.common())
+			for _, st := range steps {
+				switch st.kind {
+				case abiStepIntReg:
+					offset := add(s, st.offset, "precomputed value offset")
+					memmove(offset, unsafe.Pointer(&regArgs.Ints[st.ireg]), st.size)
+				case abiStepPointer:
+					s := add(s, st.offset, "precomputed value offset")
+					*((*unsafe.Pointer)(s)) = regArgs.Ptrs[st.ireg]
+				case abiStepFloatReg:
+					offset := add(s, st.offset, "precomputed value offset")
+					memmove(offset, unsafe.Pointer(&regArgs.Floats[st.freg]), st.size)
+				case abiStepStack:
+					panic("register-based return value has stack component")
+				default:
+					panic("unknown ABI part kind")
+				}
+			}
+			ret[i] = Value{tv.common(), s, flagIndir | flag(tv.Kind())}
 		}
 	}
 
@@ -533,32 +648,81 @@
 // frame is a pointer to the arguments to that closure on the stack.
 // retValid points to a boolean which should be set when the results
 // section of frame is set.
-func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer, retValid *bool) {
+//
+// regs contains the argument values passed in registers and will contain
+// the values returned from ctxt.fn in registers.
+func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer, retValid *bool, regs *abi.RegArgs) {
+	if callGC {
+		// Call GC upon entry during testing.
+		// Getting our stack scanned here is the biggest hazard, because
+		// our caller (makeFuncStub) could have failed to place the last
+		// pointer to a value in regs' pointer space, in which case it
+		// won't be visible to the GC.
+		runtime.GC()
+	}
 	ftyp := ctxt.ftyp
 	f := ctxt.fn
 
-	// Copy argument frame into Values.
+	_, _, abi := funcLayout(ftyp, nil)
+
+	// Copy arguments into Values.
 	ptr := frame
-	off := uintptr(0)
 	in := make([]Value, 0, int(ftyp.inCount))
-	for _, typ := range ftyp.in() {
-		off += -off & uintptr(typ.align-1)
+	for i, typ := range ftyp.in() {
+		if typ.Size() == 0 {
+			in = append(in, Zero(typ))
+			continue
+		}
 		v := Value{typ, nil, flag(typ.Kind())}
-		if ifaceIndir(typ) {
-			// value cannot be inlined in interface data.
-			// Must make a copy, because f might keep a reference to it,
-			// and we cannot let f keep a reference to the stack frame
-			// after this function returns, not even a read-only reference.
-			v.ptr = unsafe_New(typ)
-			if typ.size > 0 {
-				typedmemmove(typ, v.ptr, add(ptr, off, "typ.size > 0"))
+		steps := abi.call.stepsForValue(i)
+		if st := steps[0]; st.kind == abiStepStack {
+			if ifaceIndir(typ) {
+				// value cannot be inlined in interface data.
+				// Must make a copy, because f might keep a reference to it,
+				// and we cannot let f keep a reference to the stack frame
+				// after this function returns, not even a read-only reference.
+				v.ptr = unsafe_New(typ)
+				if typ.size > 0 {
+					typedmemmove(typ, v.ptr, add(ptr, st.stkOff, "typ.size > 0"))
+				}
+				v.flag |= flagIndir
+			} else {
+				v.ptr = *(*unsafe.Pointer)(add(ptr, st.stkOff, "1-ptr"))
 			}
-			v.flag |= flagIndir
 		} else {
-			v.ptr = *(*unsafe.Pointer)(add(ptr, off, "1-ptr"))
+			if ifaceIndir(typ) {
+				// All that's left is values passed in registers that we need to
+				// create space for the values.
+				v.flag |= flagIndir
+				v.ptr = unsafe_New(typ)
+				for _, st := range steps {
+					switch st.kind {
+					case abiStepIntReg:
+						offset := add(v.ptr, st.offset, "precomputed value offset")
+						memmove(offset, unsafe.Pointer(&regs.Ints[st.ireg]), st.size)
+					case abiStepPointer:
+						s := add(v.ptr, st.offset, "precomputed value offset")
+						*((*unsafe.Pointer)(s)) = regs.Ptrs[st.ireg]
+					case abiStepFloatReg:
+						offset := add(v.ptr, st.offset, "precomputed value offset")
+						memmove(offset, unsafe.Pointer(&regs.Floats[st.freg]), st.size)
+					case abiStepStack:
+						panic("register-based return value has stack component")
+					default:
+						panic("unknown ABI part kind")
+					}
+				}
+			} else {
+				// Pointer-valued data gets put directly
+				// into v.ptr.
+				if steps[0].kind != abiStepPointer {
+					print("kind=", steps[0].kind, ", type=", typ.String(), "\n")
+					panic("mismatch between ABI description and types")
+				}
+				v.ptr = regs.Ptrs[steps[0].ireg]
+			}
 		}
 		in = append(in, v)
-		off += typ.size
 	}
 
 	// Call underlying function.
@@ -568,9 +732,8 @@
 		panic("reflect: wrong return count from function created by MakeFunc")
 	}
 
-	// Copy results back into argument frame.
+	// Copy results back into argument frame and register space.
 	if numOut > 0 {
-		off += -off & (ptrSize - 1)
 		for i, typ := range ftyp.out() {
 			v := out[i]
 			if v.typ == nil {
@@ -581,31 +744,67 @@
 				panic("reflect: function created by MakeFunc using " + funcName(f) +
 					" returned value obtained from unexported field")
 			}
-			off += -off & uintptr(typ.align-1)
 			if typ.size == 0 {
 				continue
 			}
-			addr := add(ptr, off, "typ.size > 0")
 
 			// Convert v to type typ if v is assignable to a variable
 			// of type t in the language spec.
 			// See issue 28761.
-			if typ.Kind() == Interface {
-				// We must clear the destination before calling assignTo,
-				// in case assignTo writes (with memory barriers) to the
-				// target location used as scratch space. See issue 39541.
-				*(*uintptr)(addr) = 0
-				*(*uintptr)(add(addr, ptrSize, "typ.size == 2*ptrSize")) = 0
+			//
+			//
+			// TODO(mknyszek): In the switch to the register ABI we lost
+			// the scratch space here for the register cases (and
+			// temporarily for all the cases).
+			//
+			// If/when this happens, take note of the following:
+			//
+			// We must clear the destination before calling assignTo,
+			// in case assignTo writes (with memory barriers) to the
+			// target location used as scratch space. See issue 39541.
+			v = v.assignTo("reflect.MakeFunc", typ, nil)
+		stepsLoop:
+			for _, st := range abi.ret.stepsForValue(i) {
+				switch st.kind {
+				case abiStepStack:
+					// Copy values to the "stack."
+					addr := add(ptr, st.stkOff, "precomputed stack arg offset")
+					// Do not use write barriers. The stack space used
+					// for this call is not adequately zeroed, and we
+					// are careful to keep the arguments alive until we
+					// return to makeFuncStub's caller.
+					if v.flag&flagIndir != 0 {
+						memmove(addr, v.ptr, st.size)
+					} else {
+						// This case must be a pointer type.
+						*(*uintptr)(addr) = uintptr(v.ptr)
+					}
+					// There's only one step for a stack-allocated value.
+					break stepsLoop
+				case abiStepIntReg, abiStepPointer:
+					// Copy values to "integer registers."
+					if v.flag&flagIndir != 0 {
+						offset := add(v.ptr, st.offset, "precomputed value offset")
+						memmove(unsafe.Pointer(&regs.Ints[st.ireg]), offset, st.size)
+					} else {
+						// Only populate the Ints space on the return path.
+						// This is safe because out is kept alive until the
+						// end of this function, and the return path through
+						// makeFuncStub has no preemption, so these pointers
+						// are always visible to the GC.
+						regs.Ints[st.ireg] = uintptr(v.ptr)
+					}
+				case abiStepFloatReg:
+					// Copy values to "float registers."
+					if v.flag&flagIndir == 0 {
+						panic("attempted to copy pointer to FP register")
+					}
+					offset := add(v.ptr, st.offset, "precomputed value offset")
+					memmove(unsafe.Pointer(&regs.Floats[st.freg]), offset, st.size)
+				default:
+					panic("unknown ABI part kind")
+				}
 			}
-			v = v.assignTo("reflect.MakeFunc", typ, addr)
-
-			// We are writing to stack. No write barrier.
-			if v.flag&flagIndir != 0 {
-				memmove(addr, v.ptr, typ.size)
-			} else {
-				*(*uintptr)(addr) = uintptr(v.ptr)
-			}
-			off += typ.size
 		}
 	}
 
@@ -706,41 +905,172 @@
 // frame is a pointer to the arguments to that closure on the stack.
 // retValid points to a boolean which should be set when the results
 // section of frame is set.
-func callMethod(ctxt *methodValue, frame unsafe.Pointer, retValid *bool) {
+//
+// regs contains the argument values passed in registers and will contain
+// the values returned from ctxt.fn in registers.
+func callMethod(ctxt *methodValue, frame unsafe.Pointer, retValid *bool, regs *abi.RegArgs) {
 	rcvr := ctxt.rcvr
-	rcvrtype, t, fn := methodReceiver("call", rcvr, ctxt.method)
-	frametype, argSize, retOffset, _, framePool := funcLayout(t, rcvrtype)
+	rcvrType, valueFuncType, methodFn := methodReceiver("call", rcvr, ctxt.method)
+
+	// There are two ABIs at play here.
+	//
+	// methodValueCall was invoked with the ABI assuming there was no
+	// receiver ("value ABI") and that's what frame and regs are holding.
+	//
+	// Meanwhile, we need to actually call the method with a receiver, which
+	// has its own ABI ("method ABI"). Everything that follows is a translation
+	// between the two.
+	_, _, valueABI := funcLayout(valueFuncType, nil)
+	valueFrame, valueRegs := frame, regs
+	methodFrameType, methodFramePool, methodABI := funcLayout(valueFuncType, rcvrType)
 
 	// Make a new frame that is one word bigger so we can store the receiver.
 	// This space is used for both arguments and return values.
-	scratch := framePool.Get().(unsafe.Pointer)
+	methodFrame := methodFramePool.Get().(unsafe.Pointer)
+	var methodRegs abi.RegArgs
 
-	// Copy in receiver and rest of args.
-	storeRcvr(rcvr, scratch)
-	// Align the first arg. The alignment can't be larger than ptrSize.
-	argOffset := uintptr(ptrSize)
-	if len(t.in()) > 0 {
-		argOffset = align(argOffset, uintptr(t.in()[0].align))
+	// Deal with the receiver. It's guaranteed to only be one word in size.
+	if st := methodABI.call.steps[0]; st.kind == abiStepStack {
+		// Only copy the reciever to the stack if the ABI says so.
+		// Otherwise, it'll be in a register already.
+		storeRcvr(rcvr, methodFrame)
+	} else {
+		// Put the receiver in a register.
+		storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ints))
 	}
-	// Avoid constructing out-of-bounds pointers if there are no args.
-	if argSize-argOffset > 0 {
-		typedmemmovepartial(frametype, add(scratch, argOffset, "argSize > argOffset"), frame, argOffset, argSize-argOffset)
+
+	// Translate the rest of the arguments.
+	for i, t := range valueFuncType.in() {
+		valueSteps := valueABI.call.stepsForValue(i)
+		methodSteps := methodABI.call.stepsForValue(i + 1)
+
+		// Zero-sized types are trivial: nothing to do.
+		if len(valueSteps) == 0 {
+			if len(methodSteps) != 0 {
+				panic("method ABI and value ABI do not align")
+			}
+			continue
+		}
+
+		// There are four cases to handle in translating each
+		// argument:
+		// 1. Stack -> stack translation.
+		// 2. Stack -> registers translation.
+		// 3. Registers -> stack translation.
+		// 4. Registers -> registers translation.
+		// TODO(mknyszek): Cases 2 and 3 below only work on little endian
+		// architectures. This is OK for now, but this needs to be fixed
+		// before supporting the register ABI on big endian architectures.
+
+		// If the value ABI passes the value on the stack,
+		// then the method ABI does too, because it has strictly
+		// fewer arguments. Simply copy between the two.
+		if vStep := valueSteps[0]; vStep.kind == abiStepStack {
+			mStep := methodSteps[0]
+			// Handle stack -> stack translation.
+			if mStep.kind == abiStepStack {
+				if vStep.size != mStep.size {
+					panic("method ABI and value ABI do not align")
+				}
+				typedmemmove(t,
+					add(methodFrame, mStep.stkOff, "precomputed stack offset"),
+					add(valueFrame, vStep.stkOff, "precomputed stack offset"))
+				continue
+			}
+			// Handle stack -> register translation.
+			for _, mStep := range methodSteps {
+				from := add(valueFrame, vStep.stkOff+mStep.offset, "precomputed stack offset")
+				switch mStep.kind {
+				case abiStepPointer:
+					// Do the pointer copy directly so we get a write barrier.
+					methodRegs.Ptrs[mStep.ireg] = *(*unsafe.Pointer)(from)
+					fallthrough // We need to make sure this ends up in Ints, too.
+				case abiStepIntReg:
+					memmove(unsafe.Pointer(&methodRegs.Ints[mStep.ireg]), from, mStep.size)
+				case abiStepFloatReg:
+					memmove(unsafe.Pointer(&methodRegs.Floats[mStep.freg]), from, mStep.size)
+				default:
+					panic("unexpected method step")
+				}
+			}
+			continue
+		}
+		// Handle register -> stack translation.
+		if mStep := methodSteps[0]; mStep.kind == abiStepStack {
+			for _, vStep := range valueSteps {
+				to := add(methodFrame, mStep.stkOff+vStep.offset, "precomputed stack offset")
+				switch vStep.kind {
+				case abiStepPointer:
+					// Do the pointer copy directly so we get a write barrier.
+					*(*unsafe.Pointer)(to) = valueRegs.Ptrs[vStep.ireg]
+				case abiStepIntReg:
+					memmove(to, unsafe.Pointer(&valueRegs.Ints[vStep.ireg]), vStep.size)
+				case abiStepFloatReg:
+					memmove(to, unsafe.Pointer(&valueRegs.Floats[vStep.freg]), vStep.size)
+				default:
+					panic("unexpected value step")
+				}
+			}
+			continue
+		}
+		// Handle register -> register translation.
+		if len(valueSteps) != len(methodSteps) {
+			// Because it's the same type for the value, and it's assigned
+			// to registers both times, it should always take up the same
+			// number of registers for each ABI.
+			panic("method ABI and value ABI don't align")
+		}
+		for i, vStep := range valueSteps {
+			mStep := methodSteps[i]
+			if mStep.kind != vStep.kind {
+				panic("method ABI and value ABI don't align")
+			}
+			switch vStep.kind {
+			case abiStepPointer:
+				// Copy this too, so we get a write barrier.
+				methodRegs.Ptrs[mStep.ireg] = valueRegs.Ptrs[vStep.ireg]
+				fallthrough
+			case abiStepIntReg:
+				methodRegs.Ints[mStep.ireg] = valueRegs.Ints[vStep.ireg]
+			case abiStepFloatReg:
+				methodRegs.Floats[mStep.freg] = valueRegs.Floats[vStep.freg]
+			default:
+				panic("unexpected value step")
+			}
+		}
 	}
 
+	methodFrameSize := methodFrameType.size
+	// TODO(mknyszek): Remove this when we no longer have
+	// caller reserved spill space.
+	methodFrameSize = align(methodFrameSize, ptrSize)
+	methodFrameSize += methodABI.spill
+
+	// Mark pointers in registers for the return path.
+	methodRegs.ReturnIsPtr = methodABI.outRegPtrs
+
 	// Call.
 	// Call copies the arguments from scratch to the stack, calls fn,
 	// and then copies the results back into scratch.
-	call(frametype, fn, scratch, uint32(frametype.size), uint32(retOffset))
+	call(methodFrameType, methodFn, methodFrame, uint32(methodFrameType.size), uint32(methodABI.retOffset), uint32(methodFrameSize), &methodRegs)
 
 	// Copy return values.
-	// Ignore any changes to args and just copy return values.
+	//
+	// This is somewhat simpler because both ABIs have an identical
+	// return value ABI (the types are identical). As a result, register
+	// results can simply be copied over. Stack-allocated values are laid
+	// out the same, but are at different offsets from the start of the frame
+	// Ignore any changes to args.
 	// Avoid constructing out-of-bounds pointers if there are no return values.
-	if frametype.size-retOffset > 0 {
-		callerRetOffset := retOffset - argOffset
+	// because the arguments may be laid out differently.
+	if valueRegs != nil {
+		*valueRegs = methodRegs
+	}
+	if retSize := methodFrameType.size - methodABI.retOffset; retSize > 0 {
+		valueRet := add(valueFrame, valueABI.retOffset, "valueFrame's size > retOffset")
+		methodRet := add(methodFrame, methodABI.retOffset, "methodFrame's size > retOffset")
 		// This copies to the stack. Write barriers are not needed.
-		memmove(add(frame, callerRetOffset, "frametype.size > retOffset"),
-			add(scratch, retOffset, "frametype.size > retOffset"),
-			frametype.size-retOffset)
+		memmove(valueRet, methodRet, retSize)
 	}
 
 	// Tell the runtime it can now depend on the return values
@@ -750,11 +1080,16 @@
 	// Clear the scratch space and put it back in the pool.
 	// This must happen after the statement above, so that the return
 	// values will always be scanned by someone.
-	typedmemclr(frametype, scratch)
-	framePool.Put(scratch)
+	typedmemclr(methodFrameType, methodFrame)
+	methodFramePool.Put(methodFrame)
 
 	// See the comment in callReflect.
 	runtime.KeepAlive(ctxt)
+
+	// Keep valueRegs alive because it may hold live pointer results.
+	// The caller (methodValueCall) has it as a stack object, which is only
+	// scanned when there is a reference to it.
+	runtime.KeepAlive(valueRegs)
 }
 
 // funcName returns the name of f, for use in error messages.
@@ -1046,10 +1381,16 @@
 	return packEface(v)
 }
 
-// InterfaceData returns the interface v's value as a uintptr pair.
+// InterfaceData returns a pair of unspecified uintptr values.
 // It panics if v's Kind is not Interface.
+//
+// In earlier versions of Go, this function returned the interface's
+// value as a uintptr pair. As of Go 1.4, the implementation of
+// interface values precludes any defined use of InterfaceData.
+//
+// Deprecated: The memory representation of interface values is not
+// compatible with InterfaceData.
 func (v Value) InterfaceData() [2]uintptr {
-	// TODO: deprecate this
 	v.mustBe(Interface)
 	// We treat this as a read operation, so we allow
 	// it even for unexported data, because the caller
@@ -2398,9 +2739,14 @@
 		panic("reflect: New(nil)")
 	}
 	t := typ.(*rtype)
+	pt := t.ptrTo()
+	if ifaceIndir(pt) {
+		// This is a pointer to a go:notinheap type.
+		panic("reflect: New of type that may not be allocated in heap (possibly undefined cgo C type)")
+	}
 	ptr := unsafe_New(t)
 	fl := flag(Ptr)
-	return Value{t.ptrTo(), ptr, fl}
+	return Value{pt, ptr, fl}
 }
 
 // NewAt returns a Value representing a pointer to a value of the
@@ -2453,7 +2799,7 @@
 
 // Convert returns the value v converted to type t.
 // If the usual Go conversion rules do not allow conversion
-// of the value v to type t, Convert panics.
+// of the value v to type t, or if converting v to type t panics, Convert panics.
 func (v Value) Convert(t Type) Value {
 	if v.flag&flagMethod != 0 {
 		v = makeMethodValue("Convert", v)
@@ -2465,6 +2811,26 @@
 	return op(v, t)
 }
 
+// CanConvert reports whether the value v can be converted to type t.
+// If v.CanConvert(t) returns true then v.Convert(t) will not panic.
+func (v Value) CanConvert(t Type) bool {
+	vt := v.Type()
+	if !vt.ConvertibleTo(t) {
+		return false
+	}
+	// Currently the only conversion that is OK in terms of type
+	// but that can panic depending on the value is converting
+	// from slice to pointer-to-array.
+	if vt.Kind() == Slice && t.Kind() == Ptr && t.Elem().Kind() == Array {
+		n := t.Elem().Len()
+		h := (*unsafeheader.Slice)(v.ptr)
+		if n > h.Len {
+			return false
+		}
+	}
+	return true
+}
+
 // convertOp returns the function to convert a value of type src
 // to a value of type dst. If the conversion is illegal, convertOp returns nil.
 func convertOp(dst, src *rtype) func(Value, Type) Value {
@@ -2524,6 +2890,11 @@
 				return cvtRunesString
 			}
 		}
+		// "x is a slice, T is a pointer-to-array type,
+		// and the slice and array types have identical element types."
+		if dst.Kind() == Ptr && dst.Elem().Kind() == Array && src.Elem() == dst.Elem().Elem() {
+			return cvtSliceArrayPtr
+		}
 
 	case Chan:
 		if dst.Kind() == Chan && specialChannelAssignability(dst, src) {
@@ -2717,6 +3088,16 @@
 	return makeRunes(v.flag.ro(), []rune(v.String()), t)
 }
 
+// convertOp: []T -> *[N]T
+func cvtSliceArrayPtr(v Value, t Type) Value {
+	n := t.Elem().Len()
+	h := (*unsafeheader.Slice)(v.ptr)
+	if n > h.Len {
+		panic("reflect: cannot convert slice with length " + itoa.Itoa(h.Len) + " to pointer to array with length " + itoa.Itoa(n))
+	}
+	return Value{t.common(), h.Data, v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Ptr)}
+}
+
 // convertOp: direct copy
 func cvtDirect(v Value, typ Type) Value {
 	f := v.flag
@@ -2802,14 +3183,32 @@
 //go:noescape
 func maplen(m unsafe.Pointer) int
 
-// call calls fn with a copy of the n argument bytes pointed at by arg.
-// After fn returns, reflectcall copies n-retoffset result bytes
-// back into arg+retoffset before returning. If copying result bytes back,
-// the caller must pass the argument frame type as argtype, so that
-// call can execute appropriate write barriers during the copy.
+// call calls fn with "stackArgsSize" bytes of stack arguments laid out
+// at stackArgs and register arguments laid out in regArgs. frameSize is
+// the total amount of stack space that will be reserved by call, so this
+// should include enough space to spill register arguments to the stack in
+// case of preemption.
 //
+// After fn returns, call copies stackArgsSize-stackRetOffset result bytes
+// back into stackArgs+stackRetOffset before returning, for any return
+// values passed on the stack. Register-based return values will be found
+// in the same regArgs structure.
+//
+// regArgs must also be prepared with an appropriate ReturnIsPtr bitmap
+// indicating which registers will contain pointer-valued return values. The
+// purpose of this bitmap is to keep pointers visible to the GC between
+// returning from reflectcall and actually using them.
+//
+// If copying result bytes back from the stack, the caller must pass the
+// argument frame type as stackArgsType, so that call can execute appropriate
+// write barriers during the copy.
+//
+// Arguments passed through to call do not escape. The type is used only in a
+// very limited callee of call, the stackArgs are copied, and regArgs is only
+// used in the call frame.
+//go:noescape
 //go:linkname call runtime.reflectcall
-func call(argtype *rtype, fn, arg unsafe.Pointer, n uint32, retoffset uint32)
+func call(stackArgsType *rtype, f, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
 
 func ifaceE2I(t *rtype, src interface{}, dst unsafe.Pointer)
 
diff --git a/src/reflect/visiblefields.go b/src/reflect/visiblefields.go
new file mode 100644
index 0000000..1a2b535
--- /dev/null
+++ b/src/reflect/visiblefields.go
@@ -0,0 +1,105 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package reflect
+
+// VisibleFields returns all the visible fields in t, which must be a
+// struct type. A field is defined as visible if it's accessible
+// directly with a FieldByName call. The returned fields include fields
+// inside anonymous struct members and unexported fields. They follow
+// the same order found in the struct, with anonymous fields followed
+// immediately by their promoted fields.
+//
+// For each element e of the returned slice, the corresponding field
+// can be retrieved from a value v of type t by calling v.FieldByIndex(e.Index).
+func VisibleFields(t Type) []StructField {
+	if t == nil {
+		panic("reflect: VisibleFields(nil)")
+	}
+	if t.Kind() != Struct {
+		panic("reflect.VisibleFields of non-struct type")
+	}
+	w := &visibleFieldsWalker{
+		byName:   make(map[string]int),
+		visiting: make(map[Type]bool),
+		fields:   make([]StructField, 0, t.NumField()),
+		index:    make([]int, 0, 2),
+	}
+	w.walk(t)
+	// Remove all the fields that have been hidden.
+	// Use an in-place removal that avoids copying in
+	// the common case that there are no hidden fields.
+	j := 0
+	for i := range w.fields {
+		f := &w.fields[i]
+		if f.Name == "" {
+			continue
+		}
+		if i != j {
+			// A field has been removed. We need to shuffle
+			// all the subsequent elements up.
+			w.fields[j] = *f
+		}
+		j++
+	}
+	return w.fields[:j]
+}
+
+type visibleFieldsWalker struct {
+	byName   map[string]int
+	visiting map[Type]bool
+	fields   []StructField
+	index    []int
+}
+
+// walk walks all the fields in the struct type t, visiting
+// fields in index preorder and appending them to w.fields
+// (this maintains the required ordering).
+// Fields that have been overridden have their
+// Name field cleared.
+func (w *visibleFieldsWalker) walk(t Type) {
+	if w.visiting[t] {
+		return
+	}
+	w.visiting[t] = true
+	for i := 0; i < t.NumField(); i++ {
+		f := t.Field(i)
+		w.index = append(w.index, i)
+		add := true
+		if oldIndex, ok := w.byName[f.Name]; ok {
+			old := &w.fields[oldIndex]
+			if len(w.index) == len(old.Index) {
+				// Fields with the same name at the same depth
+				// cancel one another out. Set the field name
+				// to empty to signify that has happened, and
+				// there's no need to add this field.
+				old.Name = ""
+				add = false
+			} else if len(w.index) < len(old.Index) {
+				// The old field loses because it's deeper than the new one.
+				old.Name = ""
+			} else {
+				// The old field wins because it's shallower than the new one.
+				add = false
+			}
+		}
+		if add {
+			// Copy the index so that it's not overwritten
+			// by the other appends.
+			f.Index = append([]int(nil), w.index...)
+			w.byName[f.Name] = len(w.fields)
+			w.fields = append(w.fields, f)
+		}
+		if f.Anonymous {
+			if f.Type.Kind() == Ptr {
+				f.Type = f.Type.Elem()
+			}
+			if f.Type.Kind() == Struct {
+				w.walk(f.Type)
+			}
+		}
+		w.index = w.index[:len(w.index)-1]
+	}
+	delete(w.visiting, t)
+}
diff --git a/src/reflect/visiblefields_test.go b/src/reflect/visiblefields_test.go
new file mode 100644
index 0000000..915bbee
--- /dev/null
+++ b/src/reflect/visiblefields_test.go
@@ -0,0 +1,330 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package reflect_test
+
+import (
+	. "reflect"
+	"testing"
+)
+
+type structField struct {
+	name  string
+	index []int
+}
+
+var fieldsTests = []struct {
+	testName string
+	val      interface{}
+	expect   []structField
+}{{
+	testName: "SimpleStruct",
+	val: struct {
+		A int
+		B string
+		C bool
+	}{},
+	expect: []structField{{
+		name:  "A",
+		index: []int{0},
+	}, {
+		name:  "B",
+		index: []int{1},
+	}, {
+		name:  "C",
+		index: []int{2},
+	}},
+}, {
+	testName: "NonEmbeddedStructMember",
+	val: struct {
+		A struct {
+			X int
+		}
+	}{},
+	expect: []structField{{
+		name:  "A",
+		index: []int{0},
+	}},
+}, {
+	testName: "EmbeddedExportedStruct",
+	val: struct {
+		SFG
+	}{},
+	expect: []structField{{
+		name:  "SFG",
+		index: []int{0},
+	}, {
+		name:  "F",
+		index: []int{0, 0},
+	}, {
+		name:  "G",
+		index: []int{0, 1},
+	}},
+}, {
+	testName: "EmbeddedUnexportedStruct",
+	val: struct {
+		sFG
+	}{},
+	expect: []structField{{
+		name:  "sFG",
+		index: []int{0},
+	}, {
+		name:  "F",
+		index: []int{0, 0},
+	}, {
+		name:  "G",
+		index: []int{0, 1},
+	}},
+}, {
+	testName: "TwoEmbeddedStructsWithCancellingMembers",
+	val: struct {
+		SFG
+		SF
+	}{},
+	expect: []structField{{
+		name:  "SFG",
+		index: []int{0},
+	}, {
+		name:  "G",
+		index: []int{0, 1},
+	}, {
+		name:  "SF",
+		index: []int{1},
+	}},
+}, {
+	testName: "EmbeddedStructsWithSameFieldsAtDifferentDepths",
+	val: struct {
+		SFGH3
+		SG1
+		SFG2
+		SF2
+		L int
+	}{},
+	expect: []structField{{
+		name:  "SFGH3",
+		index: []int{0},
+	}, {
+		name:  "SFGH2",
+		index: []int{0, 0},
+	}, {
+		name:  "SFGH1",
+		index: []int{0, 0, 0},
+	}, {
+		name:  "SFGH",
+		index: []int{0, 0, 0, 0},
+	}, {
+		name:  "H",
+		index: []int{0, 0, 0, 0, 2},
+	}, {
+		name:  "SG1",
+		index: []int{1},
+	}, {
+		name:  "SG",
+		index: []int{1, 0},
+	}, {
+		name:  "G",
+		index: []int{1, 0, 0},
+	}, {
+		name:  "SFG2",
+		index: []int{2},
+	}, {
+		name:  "SFG1",
+		index: []int{2, 0},
+	}, {
+		name:  "SFG",
+		index: []int{2, 0, 0},
+	}, {
+		name:  "SF2",
+		index: []int{3},
+	}, {
+		name:  "SF1",
+		index: []int{3, 0},
+	}, {
+		name:  "SF",
+		index: []int{3, 0, 0},
+	}, {
+		name:  "L",
+		index: []int{4},
+	}},
+}, {
+	testName: "EmbeddedPointerStruct",
+	val: struct {
+		*SF
+	}{},
+	expect: []structField{{
+		name:  "SF",
+		index: []int{0},
+	}, {
+		name:  "F",
+		index: []int{0, 0},
+	}},
+}, {
+	testName: "EmbeddedNotAPointer",
+	val: struct {
+		M
+	}{},
+	expect: []structField{{
+		name:  "M",
+		index: []int{0},
+	}},
+}, {
+	testName: "RecursiveEmbedding",
+	val:      Rec1{},
+	expect: []structField{{
+		name:  "Rec2",
+		index: []int{0},
+	}, {
+		name:  "F",
+		index: []int{0, 0},
+	}, {
+		name:  "Rec1",
+		index: []int{0, 1},
+	}},
+}, {
+	testName: "RecursiveEmbedding2",
+	val:      Rec2{},
+	expect: []structField{{
+		name:  "F",
+		index: []int{0},
+	}, {
+		name:  "Rec1",
+		index: []int{1},
+	}, {
+		name:  "Rec2",
+		index: []int{1, 0},
+	}},
+}, {
+	testName: "RecursiveEmbedding3",
+	val:      RS3{},
+	expect: []structField{{
+		name:  "RS2",
+		index: []int{0},
+	}, {
+		name:  "RS1",
+		index: []int{1},
+	}, {
+		name:  "i",
+		index: []int{1, 0},
+	}},
+}}
+
+type SFG struct {
+	F int
+	G int
+}
+
+type SFG1 struct {
+	SFG
+}
+
+type SFG2 struct {
+	SFG1
+}
+
+type SFGH struct {
+	F int
+	G int
+	H int
+}
+
+type SFGH1 struct {
+	SFGH
+}
+
+type SFGH2 struct {
+	SFGH1
+}
+
+type SFGH3 struct {
+	SFGH2
+}
+
+type SF struct {
+	F int
+}
+
+type SF1 struct {
+	SF
+}
+
+type SF2 struct {
+	SF1
+}
+
+type SG struct {
+	G int
+}
+
+type SG1 struct {
+	SG
+}
+
+type sFG struct {
+	F int
+	G int
+}
+
+type RS1 struct {
+	i int
+}
+
+type RS2 struct {
+	RS1
+}
+
+type RS3 struct {
+	RS2
+	RS1
+}
+
+type M map[string]interface{}
+
+type Rec1 struct {
+	*Rec2
+}
+
+type Rec2 struct {
+	F string
+	*Rec1
+}
+
+func TestFields(t *testing.T) {
+	for _, test := range fieldsTests {
+		test := test
+		t.Run(test.testName, func(t *testing.T) {
+			typ := TypeOf(test.val)
+			fields := VisibleFields(typ)
+			if got, want := len(fields), len(test.expect); got != want {
+				t.Fatalf("unexpected field count; got %d want %d", got, want)
+			}
+
+			for j, field := range fields {
+				expect := test.expect[j]
+				t.Logf("field %d: %s", j, expect.name)
+				gotField := typ.FieldByIndex(field.Index)
+				// Unfortunately, FieldByIndex does not return
+				// a field with the same index that we passed in,
+				// so we set it to the expected value so that
+				// it can be compared later with the result of FieldByName.
+				gotField.Index = field.Index
+				expectField := typ.FieldByIndex(expect.index)
+				// ditto.
+				expectField.Index = expect.index
+				if !DeepEqual(gotField, expectField) {
+					t.Fatalf("unexpected field result\ngot %#v\nwant %#v", gotField, expectField)
+				}
+
+				// Sanity check that we can actually access the field by the
+				// expected name.
+				gotField1, ok := typ.FieldByName(expect.name)
+				if !ok {
+					t.Fatalf("field %q not accessible by name", expect.name)
+				}
+				if !DeepEqual(gotField1, expectField) {
+					t.Fatalf("unexpected FieldByName result; got %#v want %#v", gotField1, expectField)
+				}
+			}
+		})
+	}
+}
diff --git a/src/regexp/exec2_test.go b/src/regexp/exec2_test.go
index 7b86b41..6444bc1 100644
--- a/src/regexp/exec2_test.go
+++ b/src/regexp/exec2_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !race
 // +build !race
 
 package regexp
diff --git a/src/regexp/find_test.go b/src/regexp/find_test.go
index 87c49b0..64c2239 100644
--- a/src/regexp/find_test.go
+++ b/src/regexp/find_test.go
@@ -97,6 +97,7 @@
 	{`\B`, "xx", build(1, 1, 1)},
 	{`\B`, "x y", nil},
 	{`\B`, "xx yy", build(2, 1, 1, 4, 4)},
+	{`(|a)*`, "aa", build(3, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2)},
 
 	// RE2 tests
 	{`[^\S\s]`, "abcd", nil},
diff --git a/src/regexp/onepass_test.go b/src/regexp/onepass_test.go
index 32264d5..6a42eda 100644
--- a/src/regexp/onepass_test.go
+++ b/src/regexp/onepass_test.go
@@ -142,7 +142,7 @@
 	{`^(?:(a)|(?:a*))$`, false},
 	{`^(?:(?:(?:.(?:$))?))$`, true},
 	{`^abcd$`, true},
-	{`^(?:(?:a{0,})*?)$`, true},
+	{`^(?:(?:a{0,})*?)$`, false},
 	{`^(?:(?:a+)*)$`, true},
 	{`^(?:(?:a|(?:aa)))$`, true},
 	{`^(?:[^\s\S])$`, true},
diff --git a/src/regexp/syntax/compile.go b/src/regexp/syntax/compile.go
index 7524d62..c9f9fa0 100644
--- a/src/regexp/syntax/compile.go
+++ b/src/regexp/syntax/compile.go
@@ -57,8 +57,9 @@
 
 // A frag represents a compiled program fragment.
 type frag struct {
-	i   uint32    // index of first instruction
-	out patchList // where to record end instruction
+	i        uint32    // index of first instruction
+	out      patchList // where to record end instruction
+	nullable bool      // whether fragment can match empty string
 }
 
 type compiler struct {
@@ -159,7 +160,7 @@
 
 func (c *compiler) inst(op InstOp) frag {
 	// TODO: impose length limit
-	f := frag{i: uint32(len(c.p.Inst))}
+	f := frag{i: uint32(len(c.p.Inst)), nullable: true}
 	c.p.Inst = append(c.p.Inst, Inst{Op: op})
 	return f
 }
@@ -194,7 +195,7 @@
 	// TODO: elide nop
 
 	f1.out.patch(c.p, f2.i)
-	return frag{f1.i, f2.out}
+	return frag{f1.i, f2.out, f1.nullable && f2.nullable}
 }
 
 func (c *compiler) alt(f1, f2 frag) frag {
@@ -211,6 +212,7 @@
 	i.Out = f1.i
 	i.Arg = f2.i
 	f.out = f1.out.append(c.p, f2.out)
+	f.nullable = f1.nullable || f2.nullable
 	return f
 }
 
@@ -228,7 +230,12 @@
 	return f
 }
 
-func (c *compiler) star(f1 frag, nongreedy bool) frag {
+// loop returns the fragment for the main loop of a plus or star.
+// For plus, it can be used after changing the entry to f1.i.
+// For star, it can be used directly when f1 can't match an empty string.
+// (When f1 can match an empty string, f1* must be implemented as (f1+)?
+// to get the priority match order correct.)
+func (c *compiler) loop(f1 frag, nongreedy bool) frag {
 	f := c.inst(InstAlt)
 	i := &c.p.Inst[f.i]
 	if nongreedy {
@@ -242,8 +249,17 @@
 	return f
 }
 
+func (c *compiler) star(f1 frag, nongreedy bool) frag {
+	if f1.nullable {
+		// Use (f1+)? to get priority match order correct.
+		// See golang.org/issue/46123.
+		return c.quest(c.plus(f1, nongreedy), nongreedy)
+	}
+	return c.loop(f1, nongreedy)
+}
+
 func (c *compiler) plus(f1 frag, nongreedy bool) frag {
-	return frag{f1.i, c.star(f1, nongreedy).out}
+	return frag{f1.i, c.loop(f1, nongreedy).out, f1.nullable}
 }
 
 func (c *compiler) empty(op EmptyOp) frag {
@@ -255,6 +271,7 @@
 
 func (c *compiler) rune(r []rune, flags Flags) frag {
 	f := c.inst(InstRune)
+	f.nullable = false
 	i := &c.p.Inst[f.i]
 	i.Rune = r
 	flags &= FoldCase // only relevant flag is FoldCase
diff --git a/src/regexp/syntax/prog_test.go b/src/regexp/syntax/prog_test.go
index 50bfa3d..5603aea 100644
--- a/src/regexp/syntax/prog_test.go
+++ b/src/regexp/syntax/prog_test.go
@@ -89,6 +89,21 @@
   2	anynotnl -> 3
   3	match
 `},
+	{"(?:|a)+", `  0	fail
+  1	nop -> 4
+  2	rune1 "a" -> 4
+  3*	alt -> 1, 2
+  4	alt -> 3, 5
+  5	match
+`},
+	{"(?:|a)*", `  0	fail
+  1	nop -> 4
+  2	rune1 "a" -> 4
+  3	alt -> 1, 2
+  4	alt -> 3, 6
+  5*	alt -> 3, 6
+  6	match
+`},
 }
 
 func TestCompile(t *testing.T) {
diff --git a/src/regexp/testdata/basic.dat b/src/regexp/testdata/basic.dat
index 7859290..1776b1f 100644
--- a/src/regexp/testdata/basic.dat
+++ b/src/regexp/testdata/basic.dat
@@ -124,24 +124,20 @@
 E	(a)b(c)			abc		(0,3)(0,1)(2,3)
 E	a+b+c			aabbabc		(4,7)
 E	a*			aaa		(0,3)
-#E	(a*)*			-		(0,0)(0,0)
-E	(a*)*			-		(0,0)(?,?)	RE2/Go
+E	(a*)*			-		(0,0)(0,0)
 E	(a*)+			-		(0,0)(0,0)
-#E	(a*|b)*			-		(0,0)(0,0)
-E	(a*|b)*			-		(0,0)(?,?)	RE2/Go
+E	(a*|b)*			-		(0,0)(0,0)
 E	(a+|b)*			ab		(0,2)(1,2)
 E	(a+|b)+			ab		(0,2)(1,2)
 E	(a+|b)?			ab		(0,1)(0,1)
 BE	[^ab]*			cde		(0,3)
-#E	(^)*			-		(0,0)(0,0)
-E	(^)*			-		(0,0)(?,?)	RE2/Go
+E	(^)*			-		(0,0)(0,0)
 BE	a*			NULL		(0,0)
 E	([abc])*d		abbbcd		(0,6)(4,5)
 E	([abc])*bcd		abcd		(0,4)(0,1)
 E	a|b|c|d|e		e		(0,1)
 E	(a|b|c|d|e)f		ef		(0,2)(0,1)
-#E	((a*|b))*		-		(0,0)(0,0)(0,0)
-E	((a*|b))*		-		(0,0)(?,?)(?,?)	RE2/Go
+E	((a*|b))*		-		(0,0)(0,0)(0,0)
 BE	abcd*efg		abcdefg		(0,7)
 BE	ab*			xabyabbbz	(1,3)
 BE	ab*			xayabbbz	(1,2)
diff --git a/src/regexp/testdata/nullsubexpr.dat b/src/regexp/testdata/nullsubexpr.dat
index 2e18fbb..68d9c99 100644
--- a/src/regexp/testdata/nullsubexpr.dat
+++ b/src/regexp/testdata/nullsubexpr.dat
@@ -1,8 +1,7 @@
 NOTE	null subexpression matches : 2002-06-06
 
 E	(a*)*		a		(0,1)(0,1)
-#E	SAME		x		(0,0)(0,0)
-E	SAME		x		(0,0)(?,?)	RE2/Go
+E	SAME		x		(0,0)(0,0)
 E	SAME		aaaaaa		(0,6)(0,6)
 E	SAME		aaaaaax		(0,6)(0,6)
 E	(a*)+		a		(0,1)(0,1)
@@ -19,8 +18,7 @@
 E	SAME		aaaaaax		(0,6)(0,6)
 
 E	([a]*)*		a		(0,1)(0,1)
-#E	SAME		x		(0,0)(0,0)
-E	SAME		x		(0,0)(?,?)	RE2/Go
+E	SAME		x		(0,0)(0,0)
 E	SAME		aaaaaa		(0,6)(0,6)
 E	SAME		aaaaaax		(0,6)(0,6)
 E	([a]*)+		a		(0,1)(0,1)
@@ -28,8 +26,7 @@
 E	SAME		aaaaaa		(0,6)(0,6)
 E	SAME		aaaaaax		(0,6)(0,6)
 E	([^b]*)*	a		(0,1)(0,1)
-#E	SAME		b		(0,0)(0,0)
-E	SAME		b		(0,0)(?,?)	RE2/Go
+E	SAME		b		(0,0)(0,0)
 E	SAME		aaaaaa		(0,6)(0,6)
 E	SAME		aaaaaab		(0,6)(0,6)
 E	([ab]*)*	a		(0,1)(0,1)
@@ -41,11 +38,9 @@
 E	SAME		aaaabcde	(0,5)(0,5)
 E	([^a]*)*	b		(0,1)(0,1)
 E	SAME		bbbbbb		(0,6)(0,6)
-#E	SAME		aaaaaa		(0,0)(0,0)
-E	SAME		aaaaaa		(0,0)(?,?)	RE2/Go
+E	SAME		aaaaaa		(0,0)(0,0)
 E	([^ab]*)*	ccccxx		(0,6)(0,6)
-#E	SAME		ababab		(0,0)(0,0)
-E	SAME		ababab		(0,0)(?,?)	RE2/Go
+E	SAME		ababab		(0,0)(0,0)
 
 E	((z)+|a)*	zabcde		(0,2)(1,2)
 
@@ -65,8 +60,7 @@
 B	\(a*\)*\(x\)\(\1\)\(x\)	axax	(0,4)(0,1)(1,2)(2,3)(3,4)
 B	\(a*\)*\(x\)\(\1\)\(x\)	axxa	(0,3)(1,1)(1,2)(2,2)(2,3)
 
-#E	(a*)*(x)		x	(0,1)(0,0)(0,1)
-E	(a*)*(x)		x	(0,1)(?,?)(0,1)	RE2/Go
+E	(a*)*(x)		x	(0,1)(0,0)(0,1)
 E	(a*)*(x)		ax	(0,2)(0,1)(1,2)
 E	(a*)*(x)		axa	(0,2)(0,1)(1,2)
 
diff --git a/src/regexp/testdata/re2-exhaustive.txt.bz2 b/src/regexp/testdata/re2-exhaustive.txt.bz2
index a357f28..6638476 100644
--- a/src/regexp/testdata/re2-exhaustive.txt.bz2
+++ b/src/regexp/testdata/re2-exhaustive.txt.bz2
Binary files differ
diff --git a/src/regexp/testdata/re2-search.txt b/src/regexp/testdata/re2-search.txt
index 4d02e9c..8c4098a 100644
--- a/src/regexp/testdata/re2-search.txt
+++ b/src/regexp/testdata/re2-search.txt
@@ -1,5 +1,5 @@
 # RE2 basic search tests built by make log
-# Thu Sep 8 13:43:43 EDT 2011
+# Wed May 12 12:13:22 EDT 2021
 Regexp.SearchTests
 strings
 ""
@@ -227,22 +227,6 @@
 0-0;0-0;0-0;0-0
 strings
 ""
-""
-regexps
-"a*"
-0-0;0-0;0-0;0-0
-0-0;0-0;0-0;0-0
-"^(?:a*)$"
-0-0;0-0;0-0;0-0
-0-0;0-0;0-0;0-0
-"^(?:a*)"
-0-0;0-0;0-0;0-0
-0-0;0-0;0-0;0-0
-"(?:a*)$"
-0-0;0-0;0-0;0-0
-0-0;0-0;0-0;0-0
-strings
-""
 "xabcdx"
 regexps
 "ab|cd"
@@ -3651,6 +3635,86 @@
 0-1;0-1;0-1;0-1
 strings
 ""
+"a"
+regexps
+"a\\C+"
+-;-;-;-
+-;-;-;-
+"^(?:a\\C+)$"
+-;-;-;-
+-;-;-;-
+"^(?:a\\C+)"
+-;-;-;-
+-;-;-;-
+"(?:a\\C+)$"
+-;-;-;-
+-;-;-;-
+strings
+""
+"a"
+regexps
+"a\\C?"
+-;-;-;-
+0-1;0-1;0-1;0-1
+"^(?:a\\C?)$"
+-;-;-;-
+0-1;0-1;0-1;0-1
+"^(?:a\\C?)"
+-;-;-;-
+0-1;0-1;0-1;0-1
+"(?:a\\C?)$"
+-;-;-;-
+0-1;0-1;0-1;0-1
+strings
+""
+"a"
+regexps
+"a\\C*?"
+-;-;-;-
+0-1;0-1;0-1;0-1
+"^(?:a\\C*?)$"
+-;-;-;-
+0-1;0-1;0-1;0-1
+"^(?:a\\C*?)"
+-;-;-;-
+0-1;0-1;0-1;0-1
+"(?:a\\C*?)$"
+-;-;-;-
+0-1;0-1;0-1;0-1
+strings
+""
+"a"
+regexps
+"a\\C+?"
+-;-;-;-
+-;-;-;-
+"^(?:a\\C+?)$"
+-;-;-;-
+-;-;-;-
+"^(?:a\\C+?)"
+-;-;-;-
+-;-;-;-
+"(?:a\\C+?)$"
+-;-;-;-
+-;-;-;-
+strings
+""
+"a"
+regexps
+"a\\C??"
+-;-;-;-
+0-1;0-1;0-1;0-1
+"^(?:a\\C??)$"
+-;-;-;-
+0-1;0-1;0-1;0-1
+"^(?:a\\C??)"
+-;-;-;-
+0-1;0-1;0-1;0-1
+"(?:a\\C??)$"
+-;-;-;-
+0-1;0-1;0-1;0-1
+strings
+""
 "baba"
 regexps
 "a\\C*|ba\\C"
@@ -3666,7 +3730,50 @@
 -;-;-;-
 -;1-4;-;1-4
 strings
-"abc"
+""
+"Inc."
 regexps
-"a.*?c|a.*?b"
+"\\w*I\\w*"
+-;-;-;-
+-;0-3;-;0-3
+"^(?:\\w*I\\w*)$"
+-;-;-;-
+-;-;-;-
+"^(?:\\w*I\\w*)"
+-;-;-;-
+-;0-3;-;0-3
+"(?:\\w*I\\w*)$"
+-;-;-;-
+-;-;-;-
+strings
+""
+"aaa"
+regexps
+"(?:|a)*"
+0-0;0-0;0-0;0-0
+0-3;0-0;0-3;0-3
+"^(?:(?:|a)*)$"
+0-0;0-0;0-0;0-0
+0-3;0-3;0-3;0-3
+"^(?:(?:|a)*)"
+0-0;0-0;0-0;0-0
+0-3;0-0;0-3;0-3
+"(?:(?:|a)*)$"
+0-0;0-0;0-0;0-0
+0-3;0-3;0-3;0-3
+strings
+""
+"aaa"
+regexps
+"(?:|a)+"
+0-0;0-0;0-0;0-0
+0-3;0-0;0-3;0-3
+"^(?:(?:|a)+)$"
+0-0;0-0;0-0;0-0
+0-3;0-3;0-3;0-3
+"^(?:(?:|a)+)"
+0-0;0-0;0-0;0-0
+0-3;0-0;0-3;0-3
+"(?:(?:|a)+)$"
+0-0;0-0;0-0;0-0
 0-3;0-3;0-3;0-3
diff --git a/src/runtime/abi_test.go b/src/runtime/abi_test.go
new file mode 100644
index 0000000..f69d3a9
--- /dev/null
+++ b/src/runtime/abi_test.go
@@ -0,0 +1,113 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.regabireflect
+// +build goexperiment.regabireflect
+
+// This file contains tests specific to making sure the register ABI
+// works in a bunch of contexts in the runtime.
+
+package runtime_test
+
+import (
+	"internal/abi"
+	"internal/testenv"
+	"os"
+	"os/exec"
+	"runtime"
+	"strings"
+	"testing"
+	"time"
+)
+
+var regConfirmRun chan int
+
+//go:registerparams
+func regFinalizerPointer(v *Tint) (int, float32, [10]byte) {
+	regConfirmRun <- *(*int)(v)
+	return 5151, 4.0, [10]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
+}
+
+//go:registerparams
+func regFinalizerIface(v Tinter) (int, float32, [10]byte) {
+	regConfirmRun <- *(*int)(v.(*Tint))
+	return 5151, 4.0, [10]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
+}
+
+func TestFinalizerRegisterABI(t *testing.T) {
+	testenv.MustHaveExec(t)
+
+	// Actually run the test in a subprocess because we don't want
+	// finalizers from other tests interfering.
+	if os.Getenv("TEST_FINALIZER_REGABI") != "1" {
+		cmd := testenv.CleanCmdEnv(exec.Command(os.Args[0], "-test.run=TestFinalizerRegisterABI", "-test.v"))
+		cmd.Env = append(cmd.Env, "TEST_FINALIZER_REGABI=1")
+		out, err := cmd.CombinedOutput()
+		if !strings.Contains(string(out), "PASS\n") || err != nil {
+			t.Fatalf("%s\n(exit status %v)", string(out), err)
+		}
+		return
+	}
+
+	// Optimistically clear any latent finalizers from e.g. the testing
+	// package before continuing.
+	//
+	// It's possible that a finalizer only becomes available to run
+	// after this point, which would interfere with the test and could
+	// cause a crash, but because we're running in a separate process
+	// it's extremely unlikely.
+	runtime.GC()
+	runtime.GC()
+
+	// fing will only pick the new IntRegArgs up if it's currently
+	// sleeping and wakes up, so wait for it to go to sleep.
+	success := false
+	for i := 0; i < 100; i++ {
+		if runtime.FinalizerGAsleep() {
+			success = true
+			break
+		}
+		time.Sleep(20 * time.Millisecond)
+	}
+	if !success {
+		t.Fatal("finalizer not asleep?")
+	}
+
+	argRegsBefore := runtime.SetIntArgRegs(abi.IntArgRegs)
+	defer runtime.SetIntArgRegs(argRegsBefore)
+
+	tests := []struct {
+		name         string
+		fin          interface{}
+		confirmValue int
+	}{
+		{"Pointer", regFinalizerPointer, -1},
+		{"Interface", regFinalizerIface, -2},
+	}
+	for i := range tests {
+		test := &tests[i]
+		t.Run(test.name, func(t *testing.T) {
+			regConfirmRun = make(chan int)
+
+			x := new(Tint)
+			*x = (Tint)(test.confirmValue)
+			runtime.SetFinalizer(x, test.fin)
+
+			runtime.KeepAlive(x)
+
+			// Queue the finalizer.
+			runtime.GC()
+			runtime.GC()
+
+			select {
+			case <-time.After(time.Second):
+				t.Fatal("finalizer failed to execute")
+			case gotVal := <-regConfirmRun:
+				if gotVal != test.confirmValue {
+					t.Fatalf("wrong finalizer executed? got %d, want %d", gotVal, test.confirmValue)
+				}
+			}
+		})
+	}
+}
diff --git a/src/runtime/alg.go b/src/runtime/alg.go
index 1b3bf11..39c7426 100644
--- a/src/runtime/alg.go
+++ b/src/runtime/alg.go
@@ -178,28 +178,11 @@
 		return h
 	case kindStruct:
 		s := (*structtype)(unsafe.Pointer(t))
-		memStart := uintptr(0)
-		memEnd := uintptr(0)
 		for _, f := range s.fields {
-			if memEnd > memStart && (f.name.isBlank() || f.offset() != memEnd || f.typ.tflag&tflagRegularMemory == 0) {
-				// flush any pending regular memory hashing
-				h = memhash(add(p, memStart), h, memEnd-memStart)
-				memStart = memEnd
-			}
 			if f.name.isBlank() {
 				continue
 			}
-			if f.typ.tflag&tflagRegularMemory == 0 {
-				h = typehash(f.typ, add(p, f.offset()), h)
-				continue
-			}
-			if memStart == memEnd {
-				memStart = f.offset()
-			}
-			memEnd = f.offset() + f.typ.size
-		}
-		if memEnd > memStart {
-			h = memhash(add(p, memStart), h, memEnd-memStart)
+			h = typehash(f.typ, add(p, f.offset()), h)
 		}
 		return h
 	default:
diff --git a/src/runtime/asm.s b/src/runtime/asm.s
index 27d8df9..72c7449 100644
--- a/src/runtime/asm.s
+++ b/src/runtime/asm.s
@@ -11,3 +11,8 @@
 DATA runtime·no_pointers_stackmap+0x00(SB)/4, $2
 DATA runtime·no_pointers_stackmap+0x04(SB)/4, $0
 GLOBL runtime·no_pointers_stackmap(SB),RODATA, $8
+
+#ifndef GOARCH_amd64
+TEXT ·sigpanic0<ABIInternal>(SB),NOSPLIT,$0-0
+	JMP	·sigpanic<ABIInternal>(SB)
+#endif
diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s
index fa3b1be..ec5ea58 100644
--- a/src/runtime/asm_386.s
+++ b/src/runtime/asm_386.s
@@ -89,7 +89,7 @@
 DATA _rt0_386_lib_argv<>(SB)/4, $0
 GLOBL _rt0_386_lib_argv<>(SB),NOPTR, $4
 
-TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
 	// Copy arguments forward on an even stack.
 	// Users of this function jump to it, they don't call it.
 	MOVL	0(SP), AX
@@ -195,6 +195,10 @@
 	JMP ok
 #endif
 needtls:
+#ifdef GOOS_openbsd
+	// skip runtime·ldt0setup(SB) and tls test on OpenBSD in all cases
+	JMP	ok
+#endif
 #ifdef GOOS_plan9
 	// skip runtime·ldt0setup(SB) and tls test on Plan 9 in all cases
 	JMP	ok
@@ -269,35 +273,23 @@
 	FLDCW	runtime·controlWord64(SB)
 	RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+	CALL	runtime·mstart0(SB)
+	RET // not reached
+
 /*
  *  go-routine
  */
 
-// void gosave(Gobuf*)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB), NOSPLIT, $0-4
-	MOVL	buf+0(FP), AX		// gobuf
-	LEAL	buf+0(FP), BX		// caller's SP
-	MOVL	BX, gobuf_sp(AX)
-	MOVL	0(SP), BX		// caller's PC
-	MOVL	BX, gobuf_pc(AX)
-	MOVL	$0, gobuf_ret(AX)
-	// Assert ctxt is zero. See func save.
-	MOVL	gobuf_ctxt(AX), BX
-	TESTL	BX, BX
-	JZ	2(PC)
-	CALL	runtime·badctxt(SB)
-	get_tls(CX)
-	MOVL	g(CX), BX
-	MOVL	BX, gobuf_g(AX)
-	RET
-
 // void gogo(Gobuf*)
 // restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB), NOSPLIT, $8-4
+TEXT runtime·gogo(SB), NOSPLIT, $0-4
 	MOVL	buf+0(FP), BX		// gobuf
 	MOVL	gobuf_g(BX), DX
 	MOVL	0(DX), CX		// make sure g != nil
+	JMP	gogo<>(SB)
+
+TEXT gogo<>(SB), NOSPLIT, $0
 	get_tls(CX)
 	MOVL	DX, g(CX)
 	MOVL	gobuf_sp(BX), SP	// restore SP
@@ -322,7 +314,6 @@
 	MOVL	BX, (g_sched+gobuf_pc)(AX)
 	LEAL	fn+0(FP), BX	// caller's SP
 	MOVL	BX, (g_sched+gobuf_sp)(AX)
-	MOVL	AX, (g_sched+gobuf_g)(AX)
 
 	// switch to m->g0 & its stack, call fn
 	MOVL	g(DX), BX
@@ -371,18 +362,12 @@
 	// switch stacks
 	// save our state in g->sched. Pretend to
 	// be systemstack_switch if the G stack is scanned.
-	MOVL	$runtime·systemstack_switch(SB), (g_sched+gobuf_pc)(AX)
-	MOVL	SP, (g_sched+gobuf_sp)(AX)
-	MOVL	AX, (g_sched+gobuf_g)(AX)
+	CALL	gosave_systemstack_switch<>(SB)
 
 	// switch to g0
 	get_tls(CX)
 	MOVL	DX, g(CX)
 	MOVL	(g_sched+gobuf_sp)(DX), BX
-	// make it look like mstart called systemstack on g0, to stop traceback
-	SUBL	$4, BX
-	MOVL	$runtime·mstart(SB), DX
-	MOVL	DX, 0(BX)
 	MOVL	BX, SP
 
 	// call target function
@@ -457,7 +442,6 @@
 	// Set g->sched to context in f.
 	MOVL	0(SP), AX	// f's PC
 	MOVL	AX, (g_sched+gobuf_pc)(SI)
-	MOVL	SI, (g_sched+gobuf_g)(SI)
 	LEAL	4(SP), AX	// f's SP
 	MOVL	AX, (g_sched+gobuf_sp)(SI)
 	MOVL	DX, (g_sched+gobuf_ctxt)(SI)
@@ -477,7 +461,7 @@
 	JMP runtime·morestack(SB)
 
 // reflectcall: call a function with the given argument list
-// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
+// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
 // we don't have variable-sized frames, so we use a small number
 // of constant-sized-frame functions to encode a few bits of size in the pc.
 // Caution: ugly multiline assembly macros in your future!
@@ -489,8 +473,8 @@
 	JMP	AX
 // Note: can't just "JMP NAME(SB)" - bad inlining results.
 
-TEXT ·reflectcall(SB), NOSPLIT, $0-20
-	MOVL	argsize+12(FP), CX
+TEXT ·reflectcall(SB), NOSPLIT, $0-28
+	MOVL	frameSize+20(FP), CX
 	DISPATCH(runtime·call16, 16)
 	DISPATCH(runtime·call32, 32)
 	DISPATCH(runtime·call64, 64)
@@ -522,11 +506,11 @@
 	JMP	AX
 
 #define CALLFN(NAME,MAXSIZE)			\
-TEXT NAME(SB), WRAPPER, $MAXSIZE-20;		\
+TEXT NAME(SB), WRAPPER, $MAXSIZE-28;		\
 	NO_LOCAL_POINTERS;			\
 	/* copy arguments to stack */		\
-	MOVL	argptr+8(FP), SI;		\
-	MOVL	argsize+12(FP), CX;		\
+	MOVL	stackArgs+8(FP), SI;		\
+	MOVL	stackArgsSize+12(FP), CX;		\
 	MOVL	SP, DI;				\
 	REP;MOVSB;				\
 	/* call function */			\
@@ -535,10 +519,10 @@
 	PCDATA  $PCDATA_StackMapIndex, $0;	\
 	CALL	AX;				\
 	/* copy return values back */		\
-	MOVL	argtype+0(FP), DX;		\
-	MOVL	argptr+8(FP), DI;		\
-	MOVL	argsize+12(FP), CX;		\
-	MOVL	retoffset+16(FP), BX;		\
+	MOVL	stackArgsType+0(FP), DX;		\
+	MOVL	stackArgs+8(FP), DI;		\
+	MOVL	stackArgsSize+12(FP), CX;		\
+	MOVL	stackRetOffset+16(FP), BX;		\
 	MOVL	SP, SI;				\
 	ADDL	BX, DI;				\
 	ADDL	BX, SI;				\
@@ -550,11 +534,12 @@
 // separate function so it can allocate stack space for the arguments
 // to reflectcallmove. It does not follow the Go ABI; it expects its
 // arguments in registers.
-TEXT callRet<>(SB), NOSPLIT, $16-0
+TEXT callRet<>(SB), NOSPLIT, $20-0
 	MOVL	DX, 0(SP)
 	MOVL	DI, 4(SP)
 	MOVL	SI, 8(SP)
 	MOVL	CX, 12(SP)
+	MOVL	$0, 16(SP)
 	CALL	runtime·reflectcallmove(SB)
 	RET
 
@@ -619,26 +604,45 @@
 	MOVL	0(DX), BX
 	JMP	BX	// but first run the deferred function
 
-// Save state of caller into g->sched.
-TEXT gosave<>(SB),NOSPLIT,$0
+// Save state of caller into g->sched,
+// but using fake PC from systemstack_switch.
+// Must only be called from functions with no locals ($0)
+// or else unwinding from systemstack_switch is incorrect.
+TEXT gosave_systemstack_switch<>(SB),NOSPLIT,$0
 	PUSHL	AX
 	PUSHL	BX
 	get_tls(BX)
 	MOVL	g(BX), BX
 	LEAL	arg+0(FP), AX
 	MOVL	AX, (g_sched+gobuf_sp)(BX)
-	MOVL	-4(AX), AX
+	MOVL	$runtime·systemstack_switch(SB), AX
 	MOVL	AX, (g_sched+gobuf_pc)(BX)
 	MOVL	$0, (g_sched+gobuf_ret)(BX)
 	// Assert ctxt is zero. See func save.
 	MOVL	(g_sched+gobuf_ctxt)(BX), AX
 	TESTL	AX, AX
 	JZ	2(PC)
-	CALL	runtime·badctxt(SB)
+	CALL	runtime·abort(SB)
 	POPL	BX
 	POPL	AX
 	RET
 
+// func asmcgocall_no_g(fn, arg unsafe.Pointer)
+// Call fn(arg) aligned appropriately for the gcc ABI.
+// Called on a system stack, and there may be no g yet (during needm).
+TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-8
+	MOVL	fn+0(FP), AX
+	MOVL	arg+4(FP), BX
+	MOVL	SP, DX
+	SUBL	$32, SP
+	ANDL	$~15, SP	// alignment, perhaps unnecessary
+	MOVL	DX, 8(SP)	// save old SP
+	MOVL	BX, 0(SP)	// first argument in x86-32 ABI
+	CALL	AX
+	MOVL	8(SP), DX
+	MOVL	DX, SP
+	RET
+
 // func asmcgocall(fn, arg unsafe.Pointer) int32
 // Call fn(arg) on the scheduler stack,
 // aligned appropriately for the gcc ABI.
@@ -663,7 +667,7 @@
 	JEQ	noswitch
 	CMPL	DI, m_gsignal(BP)
 	JEQ	noswitch
-	CALL	gosave<>(SB)
+	CALL	gosave_systemstack_switch<>(SB)
 	get_tls(CX)
 	MOVL	SI, g(CX)
 	MOVL	(g_sched+gobuf_sp)(SI), SP
@@ -1311,7 +1315,7 @@
 
 // The top-most function running on a goroutine
 // returns to goexit+PCQuantum.
-TEXT runtime·goexit(SB),NOSPLIT,$0-0
+TEXT runtime·goexit(SB),NOSPLIT|TOPFRAME,$0-0
 	BYTE	$0x90	// NOP
 	CALL	runtime·goexit1(SB)	// does not return
 	// traceback from goexit1 must hit code range of goexit
@@ -1473,6 +1477,10 @@
 	MOVL	AX, x+0(FP)
 	MOVL	CX, y+4(FP)
 	JMP	runtime·goPanicSlice3CU(SB)
+TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-8
+	MOVL	DX, x+0(FP)
+	MOVL	BX, y+4(FP)
+	JMP	runtime·goPanicSliceConvert(SB)
 
 // Extended versions for 64-bit indexes.
 TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
index 4ac8708..14f29e1 100644
--- a/src/runtime/asm_amd64.s
+++ b/src/runtime/asm_amd64.s
@@ -6,6 +6,7 @@
 #include "go_tls.h"
 #include "funcdata.h"
 #include "textflag.h"
+#include "cgo/abi_amd64.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
@@ -28,18 +29,9 @@
 // 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)
+TEXT _rt0_amd64_lib(SB),NOSPLIT,$0
+	// Transition from C ABI to Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
 
 	MOVQ	DI, _rt0_amd64_lib_argc<>(SB)
 	MOVQ	SI, _rt0_amd64_lib_argv<>(SB)
@@ -51,25 +43,27 @@
 	MOVQ	_cgo_sys_thread_create(SB), AX
 	TESTQ	AX, AX
 	JZ	nocgo
+
+	// We're calling back to C.
+	// Align stack per ELF ABI requirements.
+	MOVQ	SP, BX  // Callee-save in C ABI
+	ANDQ	$~15, SP
 	MOVQ	$_rt0_amd64_lib_go(SB), DI
 	MOVQ	$0, SI
 	CALL	AX
+	MOVQ	BX, SP
 	JMP	restore
 
 nocgo:
+	ADJSP	$16
 	MOVQ	$0x800000, 0(SP)		// stacksize
 	MOVQ	$_rt0_amd64_lib_go(SB), AX
 	MOVQ	AX, 8(SP)			// fn
 	CALL	runtime·newosproc0(SB)
+	ADJSP	$-16
 
 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
+	POP_REGS_HOST_TO_ABI0()
 	RET
 
 // _rt0_amd64_lib_go initializes the Go runtime.
@@ -84,9 +78,7 @@
 DATA _rt0_amd64_lib_argv<>(SB)/8, $0
 GLOBL _rt0_amd64_lib_argv<>(SB),NOPTR, $8
 
-// Defined as ABIInternal since it does not use the stack-based Go ABI (and
-// in addition there are no calls to this entry point from Go code).
-TEXT runtime·rt0_go<ABIInternal>(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
 	// copy arguments forward on an even stack
 	MOVQ	DI, AX		// argc
 	MOVQ	SI, BX		// argv
@@ -233,9 +225,9 @@
 	CALL	runtime·abort(SB)	// mstart should never return
 	RET
 
-	// Prevent dead-code elimination of debugCallV1, which is
+	// Prevent dead-code elimination of debugCallV2, which is
 	// intended to be called by debuggers.
-	MOVQ	$runtime·debugCallV1<ABIInternal>(SB), AX
+	MOVQ	$runtime·debugCallV2<ABIInternal>(SB), AX
 	RET
 
 // mainPC is a function value for runtime.main, to be passed to newproc.
@@ -252,38 +244,26 @@
 	// No per-thread init.
 	RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+	CALL	runtime·mstart0(SB)
+	RET // not reached
+
 /*
  *  go-routine
  */
 
-// func gosave(buf *gobuf)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB), NOSPLIT, $0-8
-	MOVQ	buf+0(FP), AX		// gobuf
-	LEAQ	buf+0(FP), BX		// caller's SP
-	MOVQ	BX, gobuf_sp(AX)
-	MOVQ	0(SP), BX		// caller's PC
-	MOVQ	BX, gobuf_pc(AX)
-	MOVQ	$0, gobuf_ret(AX)
-	MOVQ	BP, gobuf_bp(AX)
-	// Assert ctxt is zero. See func save.
-	MOVQ	gobuf_ctxt(AX), BX
-	TESTQ	BX, BX
-	JZ	2(PC)
-	CALL	runtime·badctxt(SB)
-	get_tls(CX)
-	MOVQ	g(CX), BX
-	MOVQ	BX, gobuf_g(AX)
-	RET
-
 // func gogo(buf *gobuf)
 // restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB), NOSPLIT, $16-8
+TEXT runtime·gogo(SB), NOSPLIT, $0-8
 	MOVQ	buf+0(FP), BX		// gobuf
 	MOVQ	gobuf_g(BX), DX
 	MOVQ	0(DX), CX		// make sure g != nil
+	JMP	gogo<>(SB)
+
+TEXT gogo<>(SB), NOSPLIT, $0
 	get_tls(CX)
 	MOVQ	DX, g(CX)
+	MOVQ	DX, R14		// set the g register
 	MOVQ	gobuf_sp(BX), SP	// restore SP
 	MOVQ	gobuf_ret(BX), AX
 	MOVQ	gobuf_ctxt(BX), DX
@@ -299,6 +279,36 @@
 // Switch to m->g0's stack, call fn(g).
 // Fn must never return. It should gogo(&g->sched)
 // to keep running g.
+#ifdef GOEXPERIMENT_regabiargs
+TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT, $0-8
+	MOVQ	AX, DX	// DX = fn
+
+	// save state in g->sched
+	MOVQ	0(SP), BX	// caller's PC
+	MOVQ	BX, (g_sched+gobuf_pc)(R14)
+	LEAQ	fn+0(FP), BX	// caller's SP
+	MOVQ	BX, (g_sched+gobuf_sp)(R14)
+	MOVQ	BP, (g_sched+gobuf_bp)(R14)
+
+	// switch to m->g0 & its stack, call fn
+	MOVQ	g_m(R14), BX
+	MOVQ	m_g0(BX), SI	// SI = g.m.g0
+	CMPQ	SI, R14	// if g == m->g0 call badmcall
+	JNE	goodm
+	JMP	runtime·badmcall(SB)
+goodm:
+	MOVQ	R14, AX		// AX (and arg 0) = g
+	MOVQ	SI, R14		// g = g.m.g0
+	get_tls(CX)		// Set G in TLS
+	MOVQ	R14, g(CX)
+	MOVQ	(g_sched+gobuf_sp)(R14), SP	// sp = g0.sched.sp
+	PUSHQ	AX	// open up space for fn's arg spill slot
+	MOVQ	0(DX), R12
+	CALL	R12		// fn(g)
+	POPQ	AX
+	JMP	runtime·badmcall2(SB)
+	RET
+#else
 TEXT runtime·mcall(SB), NOSPLIT, $0-8
 	MOVQ	fn+0(FP), DI
 
@@ -308,7 +318,6 @@
 	MOVQ	BX, (g_sched+gobuf_pc)(AX)
 	LEAQ	fn+0(FP), BX	// caller's SP
 	MOVQ	BX, (g_sched+gobuf_sp)(AX)
-	MOVQ	AX, (g_sched+gobuf_g)(AX)
 	MOVQ	BP, (g_sched+gobuf_bp)(AX)
 
 	// switch to m->g0 & its stack, call fn
@@ -320,6 +329,7 @@
 	MOVQ	$runtime·badmcall(SB), AX
 	JMP	AX
 	MOVQ	SI, g(CX)	// g = m->g0
+	MOVQ	SI, R14	// set the g register
 	MOVQ	(g_sched+gobuf_sp)(SI), SP	// sp = m->g0->sched.sp
 	PUSHQ	AX
 	MOVQ	DI, DX
@@ -329,6 +339,7 @@
 	MOVQ	$runtime·badmcall2(SB), AX
 	JMP	AX
 	RET
+#endif
 
 // systemstack_switch is a dummy routine that systemstack leaves at the bottom
 // of the G stack. We need to distinguish the routine that
@@ -358,19 +369,12 @@
 	// switch stacks
 	// save our state in g->sched. Pretend to
 	// be systemstack_switch if the G stack is scanned.
-	MOVQ	$runtime·systemstack_switch(SB), SI
-	MOVQ	SI, (g_sched+gobuf_pc)(AX)
-	MOVQ	SP, (g_sched+gobuf_sp)(AX)
-	MOVQ	AX, (g_sched+gobuf_g)(AX)
-	MOVQ	BP, (g_sched+gobuf_bp)(AX)
+	CALL	gosave_systemstack_switch<>(SB)
 
 	// switch to g0
 	MOVQ	DX, g(CX)
+	MOVQ	DX, R14 // set the g register
 	MOVQ	(g_sched+gobuf_sp)(DX), BX
-	// make it look like mstart called systemstack on g0, to stop traceback
-	SUBQ	$8, BX
-	MOVQ	$runtime·mstart(SB), DX
-	MOVQ	DX, 0(BX)
 	MOVQ	BX, SP
 
 	// call target function
@@ -445,7 +449,6 @@
 	// Set g->sched to context in f.
 	MOVQ	0(SP), AX // f's PC
 	MOVQ	AX, (g_sched+gobuf_pc)(SI)
-	MOVQ	SI, (g_sched+gobuf_g)(SI)
 	LEAQ	8(SP), AX // f's SP
 	MOVQ	AX, (g_sched+gobuf_sp)(SI)
 	MOVQ	BP, (g_sched+gobuf_bp)(SI)
@@ -464,8 +467,74 @@
 	MOVL	$0, DX
 	JMP	runtime·morestack(SB)
 
+#ifdef GOEXPERIMENT_regabireflect
+// spillArgs stores return values from registers to a *internal/abi.RegArgs in R12.
+TEXT ·spillArgs<ABIInternal>(SB),NOSPLIT,$0-0
+	MOVQ AX, 0(R12)
+	MOVQ BX, 8(R12)
+	MOVQ CX, 16(R12)
+	MOVQ DI, 24(R12)
+	MOVQ SI, 32(R12)
+	MOVQ R8, 40(R12)
+	MOVQ R9, 48(R12)
+	MOVQ R10, 56(R12)
+	MOVQ R11, 64(R12)
+	MOVQ X0, 72(R12)
+	MOVQ X1, 80(R12)
+	MOVQ X2, 88(R12)
+	MOVQ X3, 96(R12)
+	MOVQ X4, 104(R12)
+	MOVQ X5, 112(R12)
+	MOVQ X6, 120(R12)
+	MOVQ X7, 128(R12)
+	MOVQ X8, 136(R12)
+	MOVQ X9, 144(R12)
+	MOVQ X10, 152(R12)
+	MOVQ X11, 160(R12)
+	MOVQ X12, 168(R12)
+	MOVQ X13, 176(R12)
+	MOVQ X14, 184(R12)
+	RET
+
+// unspillArgs loads args into registers from a *internal/abi.RegArgs in R12.
+TEXT ·unspillArgs<ABIInternal>(SB),NOSPLIT,$0-0
+	MOVQ 0(R12), AX
+	MOVQ 8(R12), BX
+	MOVQ 16(R12), CX
+	MOVQ 24(R12), DI
+	MOVQ 32(R12), SI
+	MOVQ 40(R12), R8
+	MOVQ 48(R12), R9
+	MOVQ 56(R12), R10
+	MOVQ 64(R12), R11
+	MOVQ 72(R12), X0
+	MOVQ 80(R12), X1
+	MOVQ 88(R12), X2
+	MOVQ 96(R12), X3
+	MOVQ 104(R12), X4
+	MOVQ 112(R12), X5
+	MOVQ 120(R12), X6
+	MOVQ 128(R12), X7
+	MOVQ 136(R12), X8
+	MOVQ 144(R12), X9
+	MOVQ 152(R12), X10
+	MOVQ 160(R12), X11
+	MOVQ 168(R12), X12
+	MOVQ 176(R12), X13
+	MOVQ 184(R12), X14
+	RET
+#else
+// spillArgs stores return values from registers to a pointer in R12.
+TEXT ·spillArgs<ABIInternal>(SB),NOSPLIT,$0-0
+	RET
+
+// unspillArgs loads args into registers from a pointer in R12.
+TEXT ·unspillArgs<ABIInternal>(SB),NOSPLIT,$0-0
+	RET
+#endif
+
 // reflectcall: call a function with the given argument list
-// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
+// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
 // we don't have variable-sized frames, so we use a small number
 // of constant-sized-frame functions to encode a few bits of size in the pc.
 // Caution: ugly multiline assembly macros in your future!
@@ -477,8 +546,8 @@
 	JMP	AX
 // Note: can't just "JMP NAME(SB)" - bad inlining results.
 
-TEXT ·reflectcall<ABIInternal>(SB), NOSPLIT, $0-32
-	MOVLQZX argsize+24(FP), CX
+TEXT ·reflectcall(SB), NOSPLIT, $0-48
+	MOVLQZX frameSize+32(FP), CX
 	DISPATCH(runtime·call16, 16)
 	DISPATCH(runtime·call32, 32)
 	DISPATCH(runtime·call64, 64)
@@ -510,23 +579,28 @@
 	JMP	AX
 
 #define CALLFN(NAME,MAXSIZE)			\
-TEXT NAME(SB), WRAPPER, $MAXSIZE-32;		\
+TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
 	NO_LOCAL_POINTERS;			\
 	/* copy arguments to stack */		\
-	MOVQ	argptr+16(FP), SI;		\
-	MOVLQZX argsize+24(FP), CX;		\
+	MOVQ	stackArgs+16(FP), SI;		\
+	MOVLQZX stackArgsSize+24(FP), CX;		\
 	MOVQ	SP, DI;				\
 	REP;MOVSB;				\
+	/* set up argument registers */		\
+	MOVQ    regArgs+40(FP), R12;		\
+	CALL    ·unspillArgs<ABIInternal>(SB);		\
 	/* call function */			\
 	MOVQ	f+8(FP), DX;			\
 	PCDATA  $PCDATA_StackMapIndex, $0;	\
-	MOVQ	(DX), AX;			\
-	CALL	AX;				\
-	/* copy return values back */		\
-	MOVQ	argtype+0(FP), DX;		\
-	MOVQ	argptr+16(FP), DI;		\
-	MOVLQZX	argsize+24(FP), CX;		\
-	MOVLQZX	retoffset+28(FP), BX;		\
+	MOVQ	(DX), R12;			\
+	CALL	R12;				\
+	/* copy register return values back */		\
+	MOVQ    regArgs+40(FP), R12;		\
+	CALL    ·spillArgs<ABIInternal>(SB);		\
+	MOVLQZX	stackArgsSize+24(FP), CX;		\
+	MOVLQZX	stackRetOffset+28(FP), BX;		\
+	MOVQ	stackArgs+16(FP), DI;		\
+	MOVQ	stackArgsType+0(FP), DX;		\
 	MOVQ	SP, SI;				\
 	ADDQ	BX, DI;				\
 	ADDQ	BX, SI;				\
@@ -538,12 +612,13 @@
 // separate function so it can allocate stack space for the arguments
 // to reflectcallmove. It does not follow the Go ABI; it expects its
 // arguments in registers.
-TEXT callRet<>(SB), NOSPLIT, $32-0
+TEXT callRet<>(SB), NOSPLIT, $40-0
 	NO_LOCAL_POINTERS
 	MOVQ	DX, 0(SP)
 	MOVQ	DI, 8(SP)
 	MOVQ	SI, 16(SP)
 	MOVQ	CX, 24(SP)
+	MOVQ	R12, 32(SP)
 	CALL	runtime·reflectcallmove(SB)
 	RET
 
@@ -604,21 +679,44 @@
 	MOVQ	0(DX), BX
 	JMP	BX	// but first run the deferred function
 
-// Save state of caller into g->sched. Smashes R8, R9.
-TEXT gosave<>(SB),NOSPLIT,$0
-	get_tls(R8)
-	MOVQ	g(R8), R8
-	MOVQ	0(SP), R9
-	MOVQ	R9, (g_sched+gobuf_pc)(R8)
+// Save state of caller into g->sched,
+// but using fake PC from systemstack_switch.
+// Must only be called from functions with no locals ($0)
+// or else unwinding from systemstack_switch is incorrect.
+// Smashes R9.
+TEXT gosave_systemstack_switch<>(SB),NOSPLIT,$0
+#ifndef GOEXPERIMENT_regabig
+	get_tls(R14)
+	MOVQ	g(R14), R14
+#endif
+	MOVQ	$runtime·systemstack_switch(SB), R9
+	MOVQ	R9, (g_sched+gobuf_pc)(R14)
 	LEAQ	8(SP), R9
-	MOVQ	R9, (g_sched+gobuf_sp)(R8)
-	MOVQ	$0, (g_sched+gobuf_ret)(R8)
-	MOVQ	BP, (g_sched+gobuf_bp)(R8)
+	MOVQ	R9, (g_sched+gobuf_sp)(R14)
+	MOVQ	$0, (g_sched+gobuf_ret)(R14)
+	MOVQ	BP, (g_sched+gobuf_bp)(R14)
 	// Assert ctxt is zero. See func save.
-	MOVQ	(g_sched+gobuf_ctxt)(R8), R9
+	MOVQ	(g_sched+gobuf_ctxt)(R14), R9
 	TESTQ	R9, R9
 	JZ	2(PC)
-	CALL	runtime·badctxt(SB)
+	CALL	runtime·abort(SB)
+	RET
+
+// func asmcgocall_no_g(fn, arg unsafe.Pointer)
+// Call fn(arg) aligned appropriately for the gcc ABI.
+// Called on a system stack, and there may be no g yet (during needm).
+TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
+	MOVQ	fn+0(FP), AX
+	MOVQ	arg+8(FP), BX
+	MOVQ	SP, DX
+	SUBQ	$32, SP
+	ANDQ	$~15, SP	// alignment
+	MOVQ	DX, 8(SP)
+	MOVQ	BX, DI		// DI = first argument in AMD64 ABI
+	MOVQ	BX, CX		// CX = first argument in Win64
+	CALL	AX
+	MOVQ	8(SP), DX
+	MOVQ	DX, SP
 	RET
 
 // func asmcgocall(fn, arg unsafe.Pointer) int32
@@ -649,7 +747,7 @@
 
 	// Switch to system stack.
 	MOVQ	m_g0(R8), SI
-	CALL	gosave<>(SB)
+	CALL	gosave_systemstack_switch<>(SB)
 	MOVQ	SI, g(CX)
 	MOVQ	(g_sched+gobuf_sp)(SI), SP
 
@@ -700,6 +798,14 @@
 	MOVL	AX, ret+16(FP)
 	RET
 
+#ifdef GOOS_windows
+// Dummy TLS that's used on Windows so that we don't crash trying
+// to restore the G register in needm. needm and its callees are
+// very careful never to actually use the G, the TLS just can't be
+// unset since we're in Go code.
+GLOBL zeroTLS<>(SB),RODATA,$const_tlsSize
+#endif
+
 // func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
 // See cgocall.go for more details.
 TEXT ·cgocallback(SB),NOSPLIT,$24-24
@@ -723,7 +829,27 @@
 	MOVQ	BX, savedm-8(SP)	// saved copy of oldm
 	JMP	havem
 needm:
-	MOVQ    $runtime·needm(SB), AX
+#ifdef GOOS_windows
+	// Set up a dummy TLS value. needm is careful not to use it,
+	// but it needs to be there to prevent autogenerated code from
+	// crashing when it loads from it.
+	// We don't need to clear it or anything later because needm
+	// will set up TLS properly.
+	MOVQ	$zeroTLS<>(SB), DI
+	CALL	runtime·settls(SB)
+#endif
+	// On some platforms (Windows) we cannot call needm through
+	// an ABI wrapper because there's no TLS set up, and the ABI
+	// wrapper will try to restore the G register (R14) from TLS.
+	// Clear X15 because Go expects it and we're not calling
+	// through a wrapper, but otherwise avoid setting the G
+	// register in the wrapper and call needm directly. It
+	// takes no arguments and doesn't return any values so
+	// there's no need to handle that. Clear R14 so that there's
+	// a bad value in there, in case needm tries to use it.
+	XORPS	X15, X15
+	XORQ    R14, R14
+	MOVQ	$runtime·needm<ABIInternal>(SB), AX
 	CALL	AX
 	MOVQ	$0, savedm-8(SP) // dropm on return
 	get_tls(CX)
@@ -785,7 +911,8 @@
 	MOVQ	BX, 0(SP)
 	MOVQ	CX, 8(SP)
 	MOVQ	DX, 16(SP)
-	CALL	runtime·cgocallbackg(SB)
+	MOVQ	$runtime·cgocallbackg(SB), AX
+	CALL	AX	// indirect call to bypass nosplit check. We're on a different stack now.
 
 	// Compute the size of the frame again. FP and SP have
 	// completely different values here than they did above,
@@ -817,9 +944,17 @@
 	// for the duration of the call. Since the call is over, return it with dropm.
 	MOVQ	savedm-8(SP), BX
 	CMPQ	BX, $0
-	JNE 3(PC)
+	JNE	done
 	MOVQ	$runtime·dropm(SB), AX
 	CALL	AX
+#ifdef GOOS_windows
+	// We need to clear the TLS pointer in case the next
+	// thread that comes into Go tries to reuse that space
+	// but uses the same M.
+	XORQ	DI, DI
+	CALL	runtime·settls(SB)
+#endif
+done:
 
 	// Done!
 	RET
@@ -828,16 +963,6 @@
 // set g. for use by needm.
 TEXT runtime·setg(SB), NOSPLIT, $0-8
 	MOVQ	gg+0(FP), BX
-#ifdef GOOS_windows
-	CMPQ	BX, $0
-	JNE	settls
-	MOVQ	$0, 0x28(GS)
-	RET
-settls:
-	MOVQ	g_m(BX), AX
-	LEAQ	m_tls(AX), AX
-	MOVQ	AX, 0x28(GS)
-#endif
 	get_tls(CX)
 	MOVQ	BX, g(CX)
 	RET
@@ -846,6 +971,7 @@
 TEXT setg_gcc<>(SB),NOSPLIT,$0
 	get_tls(AX)
 	MOVQ	DI, g(AX)
+	MOVQ	DI, R14 // set the g register
 	RET
 
 TEXT runtime·abort(SB),NOSPLIT,$0-0
@@ -882,34 +1008,62 @@
 
 // func memhash(p unsafe.Pointer, h, s uintptr) uintptr
 // hash function using AES hardware instructions
-TEXT runtime·memhash(SB),NOSPLIT,$0-32
+TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT,$0-32
+#ifdef GOEXPERIMENT_regabiargs
+	// AX = ptr to data
+	// BX = seed
+	// CX = size
+#endif
 	CMPB	runtime·useAeshash(SB), $0
 	JEQ	noaes
+#ifndef GOEXPERIMENT_regabiargs
 	MOVQ	p+0(FP), AX	// ptr to data
 	MOVQ	s+16(FP), CX	// size
 	LEAQ	ret+24(FP), DX
+#endif
 	JMP	aeshashbody<>(SB)
 noaes:
-	JMP	runtime·memhashFallback(SB)
+	JMP	runtime·memhashFallback<ABIInternal>(SB)
 
 // func strhash(p unsafe.Pointer, h uintptr) uintptr
-TEXT runtime·strhash(SB),NOSPLIT,$0-24
+TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT,$0-24
+#ifdef GOEXPERIMENT_regabiargs
+	// AX = ptr to string struct
+	// BX = seed
+#endif
 	CMPB	runtime·useAeshash(SB), $0
 	JEQ	noaes
+#ifndef GOEXPERIMENT_regabiargs
 	MOVQ	p+0(FP), AX	// ptr to string struct
+#endif
 	MOVQ	8(AX), CX	// length of string
 	MOVQ	(AX), AX	// string data
+#ifndef GOEXPERIMENT_regabiargs
 	LEAQ	ret+16(FP), DX
+#endif
 	JMP	aeshashbody<>(SB)
 noaes:
-	JMP	runtime·strhashFallback(SB)
+	JMP	runtime·strhashFallback<ABIInternal>(SB)
 
 // AX: data
+#ifdef GOEXPERIMENT_regabiargs
+// BX: hash seed
+#else
+// h+8(FP): hash seed
+#endif
 // CX: length
+#ifdef GOEXPERIMENT_regabiargs
+// At return: AX = return value
+#else
 // DX: address to put return value
+#endif
 TEXT aeshashbody<>(SB),NOSPLIT,$0-0
 	// Fill an SSE register with our seeds.
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	BX, X0				// 64 bits of per-table hash seed
+#else
 	MOVQ	h+8(FP), X0			// 64 bits of per-table hash seed
+#endif
 	PINSRW	$4, CX, X0			// 16 bits of length
 	PSHUFHW $0, X0, X0			// repeat length 4 times total
 	MOVO	X0, X1				// save unscrambled seed
@@ -946,7 +1100,11 @@
 	AESENC	X1, X1	// scramble combo 3 times
 	AESENC	X1, X1
 	AESENC	X1, X1
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	X1, AX	// return X1
+#else
 	MOVQ	X1, (DX)
+#endif
 	RET
 
 endofpage:
@@ -962,7 +1120,11 @@
 aes0:
 	// Return scrambled input seed
 	AESENC	X0, X0
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	X0, AX	// return X0
+#else
 	MOVQ	X0, (DX)
+#endif
 	RET
 
 aes16:
@@ -992,7 +1154,11 @@
 
 	// combine results
 	PXOR	X3, X2
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	X2, AX	// return X2
+#else
 	MOVQ	X2, (DX)
+#endif
 	RET
 
 aes33to64:
@@ -1034,7 +1200,11 @@
 	PXOR	X6, X4
 	PXOR	X7, X5
 	PXOR	X5, X4
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	X4, AX	// return X4
+#else
 	MOVQ	X4, (DX)
+#endif
 	RET
 
 aes65to128:
@@ -1116,7 +1286,15 @@
 	PXOR	X10, X8
 	PXOR	X11, X9
 	PXOR	X9, X8
+#ifdef GOEXPERIMENT_regabig
+	// X15 must be zero on return
+	PXOR	X15, X15
+#endif
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	X8, AX	// return X8
+#else
 	MOVQ	X8, (DX)
+#endif
 	RET
 
 aes129plus:
@@ -1232,38 +1410,73 @@
 	PXOR	X10, X8
 	PXOR	X11, X9
 	PXOR	X9, X8
+#ifdef GOEXPERIMENT_regabig
+	// X15 must be zero on return
+	PXOR	X15, X15
+#endif
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	X8, AX	// return X8
+#else
 	MOVQ	X8, (DX)
+#endif
 	RET
 
 // func memhash32(p unsafe.Pointer, h uintptr) uintptr
-TEXT runtime·memhash32(SB),NOSPLIT,$0-24
+// ABIInternal for performance.
+TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT,$0-24
+#ifdef GOEXPERIMENT_regabiargs
+	// AX = ptr to data
+	// BX = seed
+#endif
 	CMPB	runtime·useAeshash(SB), $0
 	JEQ	noaes
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	BX, X0	// X0 = seed
+#else
 	MOVQ	p+0(FP), AX	// ptr to data
 	MOVQ	h+8(FP), X0	// seed
+#endif
 	PINSRD	$2, (AX), X0	// data
 	AESENC	runtime·aeskeysched+0(SB), X0
 	AESENC	runtime·aeskeysched+16(SB), X0
 	AESENC	runtime·aeskeysched+32(SB), X0
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	X0, AX	// return X0
+#else
 	MOVQ	X0, ret+16(FP)
+#endif
 	RET
 noaes:
-	JMP	runtime·memhash32Fallback(SB)
+	JMP	runtime·memhash32Fallback<ABIInternal>(SB)
 
 // func memhash64(p unsafe.Pointer, h uintptr) uintptr
-TEXT runtime·memhash64(SB),NOSPLIT,$0-24
+// ABIInternal for performance.
+TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT,$0-24
+#ifdef GOEXPERIMENT_regabiargs
+	// AX = ptr to data
+	// BX = seed
+#else
+#endif
 	CMPB	runtime·useAeshash(SB), $0
 	JEQ	noaes
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	BX, X0	// X0 = seed
+#else
 	MOVQ	p+0(FP), AX	// ptr to data
 	MOVQ	h+8(FP), X0	// seed
+#endif
 	PINSRQ	$1, (AX), X0	// data
 	AESENC	runtime·aeskeysched+0(SB), X0
 	AESENC	runtime·aeskeysched+16(SB), X0
 	AESENC	runtime·aeskeysched+32(SB), X0
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	X0, AX	// return X0
+#else
 	MOVQ	X0, ret+16(FP)
+#endif
 	RET
 noaes:
-	JMP	runtime·memhash64Fallback(SB)
+	JMP	runtime·memhash64Fallback<ABIInternal>(SB)
 
 // simple mask to get rid of data in the high part of the register.
 DATA masks<>+0x00(SB)/8, $0x0000000000000000
@@ -1363,11 +1576,8 @@
 	RET
 
 // The top-most function running on a goroutine
-// returns to goexit+PCQuantum. Defined as ABIInternal
-// so as to make it identifiable to traceback (this
-// function it used as a sentinel; traceback wants to
-// see the func PC, not a wrapper PC).
-TEXT runtime·goexit<ABIInternal>(SB),NOSPLIT,$0-0
+// returns to goexit+PCQuantum.
+TEXT runtime·goexit(SB),NOSPLIT|TOPFRAME,$0-0
 	BYTE	$0x90	// NOP
 	CALL	runtime·goexit1(SB)	// does not return
 	// traceback from goexit1 must hit code range of goexit
@@ -1382,6 +1592,18 @@
 	POPQ	R15
 	RET
 
+// Initialize special registers then jump to sigpanic.
+// This function is injected from the signal handler for panicking
+// signals. It is quite painful to set X15 in the signal context,
+// so we do it here.
+TEXT ·sigpanic0<ABIInternal>(SB),NOSPLIT,$0-0
+#ifdef GOEXPERIMENT_regabig
+	get_tls(R14)
+	MOVQ	g(R14), R14
+	XORPS	X15, X15
+#endif
+	JMP	·sigpanic<ABIInternal>(SB)
+
 // gcWriteBarrier performs a heap pointer write and informs the GC.
 //
 // gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:
@@ -1390,24 +1612,28 @@
 // It clobbers FLAGS. It does not clobber any general-purpose registers,
 // but may clobber others (e.g., SSE registers).
 // Defined as ABIInternal since it does not use the stack-based Go ABI.
-TEXT runtime·gcWriteBarrier<ABIInternal>(SB),NOSPLIT,$120
+TEXT runtime·gcWriteBarrier<ABIInternal>(SB),NOSPLIT,$112
 	// 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)
+	MOVQ	R12, 96(SP)
+	MOVQ	R13, 104(SP)
 	// TODO: Consider passing g.m.p in as an argument so they can be shared
 	// across a sequence of write barriers.
+#ifdef GOEXPERIMENT_regabig
+	MOVQ	g_m(R14), R13
+#else
 	get_tls(R13)
 	MOVQ	g(R13), R13
 	MOVQ	g_m(R13), R13
+#endif
 	MOVQ	m_p(R13), R13
-	MOVQ	(p_wbBuf+wbBuf_next)(R13), R14
+	MOVQ	(p_wbBuf+wbBuf_next)(R13), R12
 	// Increment wbBuf.next position.
-	LEAQ	16(R14), R14
-	MOVQ	R14, (p_wbBuf+wbBuf_next)(R13)
-	CMPQ	R14, (p_wbBuf+wbBuf_end)(R13)
+	LEAQ	16(R12), R12
+	MOVQ	R12, (p_wbBuf+wbBuf_next)(R13)
+	CMPQ	R12, (p_wbBuf+wbBuf_end)(R13)
 	// Record the write.
-	MOVQ	AX, -16(R14)	// Record value
+	MOVQ	AX, -16(R12)	// Record value
 	// Note: This turns bad pointer writes into bad
 	// pointer reads, which could be confusing. We could avoid
 	// reading from obviously bad pointers, which would
@@ -1415,12 +1641,12 @@
 	// patch this up in the signal handler, or use XCHG to
 	// combine the read and the write.
 	MOVQ	(DI), R13
-	MOVQ	R13, -8(R14)	// Record *slot
+	MOVQ	R13, -8(R12)	// Record *slot
 	// Is the buffer full? (flags set in CMPQ above)
 	JEQ	flush
 ret:
-	MOVQ	104(SP), R14
-	MOVQ	112(SP), R13
+	MOVQ	96(SP), R12
+	MOVQ	104(SP), R13
 	// Do the write.
 	MOVQ	AX, (DI)
 	RET
@@ -1450,10 +1676,10 @@
 	MOVQ	R9, 64(SP)
 	MOVQ	R10, 72(SP)
 	MOVQ	R11, 80(SP)
-	MOVQ	R12, 88(SP)
+	// R12 already saved
 	// R13 already saved
-	// R14 already saved
-	MOVQ	R15, 96(SP)
+	// R14 is g
+	MOVQ	R15, 88(SP)
 
 	// This takes arguments DI and AX
 	CALL	runtime·wbBufFlush(SB)
@@ -1469,8 +1695,7 @@
 	MOVQ	64(SP), R9
 	MOVQ	72(SP), R10
 	MOVQ	80(SP), R11
-	MOVQ	88(SP), R12
-	MOVQ	96(SP), R15
+	MOVQ	88(SP), R15
 	JMP	ret
 
 // gcWriteBarrierCX is gcWriteBarrier, but with args in DI and CX.
@@ -1532,7 +1757,7 @@
 DATA	debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
 GLOBL	debugCallFrameTooLarge<>(SB), RODATA, $20	// Size duplicated below
 
-// debugCallV1 is the entry point for debugger-injected function
+// debugCallV2 is the entry point for debugger-injected function
 // calls on running goroutines. It informs the runtime that a
 // debug call has been injected and creates a call frame for the
 // debugger to fill in.
@@ -1545,7 +1770,7 @@
 //    after step 2).
 // 4. Save all machine registers (including flags and XMM reigsters)
 //    so they can be restored later by the debugger.
-// 5. Set the PC to debugCallV1 and resume execution.
+// 5. Set the PC to debugCallV2 and resume execution.
 //
 // If the goroutine is in state _Grunnable, then it's not generally
 // safe to inject a call because it may return out via other runtime
@@ -1555,19 +1780,19 @@
 //
 // If the goroutine is in any other state, it's not safe to inject a call.
 //
-// This function communicates back to the debugger by setting RAX and
+// This function communicates back to the debugger by setting R12 and
 // invoking INT3 to raise a breakpoint signal. See the comments in the
 // implementation for the protocol the debugger is expected to
 // follow. InjectDebugCall in the runtime tests demonstrates this protocol.
 //
 // The debugger must ensure that any pointers passed to the function
 // obey escape analysis requirements. Specifically, it must not pass
-// a stack pointer to an escaping argument. debugCallV1 cannot check
+// a stack pointer to an escaping argument. debugCallV2 cannot check
 // this invariant.
 //
 // This is ABIInternal because Go code injects its PC directly into new
 // goroutine stacks.
-TEXT runtime·debugCallV1<ABIInternal>(SB),NOSPLIT,$152-0
+TEXT runtime·debugCallV2<ABIInternal>(SB),NOSPLIT,$152-0
 	// Save all registers that may contain pointers so they can be
 	// conservatively scanned.
 	//
@@ -1607,10 +1832,10 @@
 	MOVQ	AX, 0(SP)
 	MOVQ	16(SP), AX
 	MOVQ	AX, 8(SP)
-	// Set AX to 8 and invoke INT3. The debugger should get the
+	// Set R12 to 8 and invoke INT3. The debugger should get the
 	// reason a call can't be injected from the top of the stack
 	// and resume execution.
-	MOVQ	$8, AX
+	MOVQ	$8, R12
 	BYTE	$0xcc
 	JMP	restore
 
@@ -1618,17 +1843,18 @@
 	// Registers are saved and it's safe to make a call.
 	// Open up a call frame, moving the stack if necessary.
 	//
-	// Once the frame is allocated, this will set AX to 0 and
+	// Once the frame is allocated, this will set R12 to 0 and
 	// invoke INT3. The debugger should write the argument
-	// frame for the call at SP, push the trapping PC on the
-	// stack, set the PC to the function to call, set RCX to point
-	// to the closure (if a closure call), and resume execution.
+	// frame for the call at SP, set up argument registers, push
+	// the trapping PC on the stack, set the PC to the function to
+	// call, set RDX to point to the closure (if a closure call),
+	// and resume execution.
 	//
-	// If the function returns, this will set AX to 1 and invoke
+	// If the function returns, this will set R12 to 1 and invoke
 	// INT3. The debugger can then inspect any return value saved
-	// on the stack at SP and resume execution again.
+	// on the stack at SP and in registers and resume execution again.
 	//
-	// If the function panics, this will set AX to 2 and invoke INT3.
+	// If the function panics, this will set R12 to 2 and invoke INT3.
 	// The interface{} value of the panic will be at SP. The debugger
 	// can inspect the panic value and resume execution again.
 #define DEBUG_CALL_DISPATCH(NAME,MAXSIZE)	\
@@ -1656,16 +1882,16 @@
 	MOVQ	$debugCallFrameTooLarge<>(SB), AX
 	MOVQ	AX, 0(SP)
 	MOVQ	$20, 8(SP) // length of debugCallFrameTooLarge string
-	MOVQ	$8, AX
+	MOVQ	$8, R12
 	BYTE	$0xcc
 	JMP	restore
 
 restore:
 	// Calls and failures resume here.
 	//
-	// Set AX to 16 and invoke INT3. The debugger should restore
+	// Set R12 to 16 and invoke INT3. The debugger should restore
 	// all registers except RIP and RSP and resume execution.
-	MOVQ	$16, AX
+	MOVQ	$16, R12
 	BYTE	$0xcc
 	// We must not modify flags after this point.
 
@@ -1694,9 +1920,9 @@
 #define DEBUG_CALL_FN(NAME,MAXSIZE)		\
 TEXT NAME(SB),WRAPPER,$MAXSIZE-0;		\
 	NO_LOCAL_POINTERS;			\
-	MOVQ	$0, AX;				\
+	MOVQ	$0, R12;				\
 	BYTE	$0xcc;				\
-	MOVQ	$1, AX;				\
+	MOVQ	$1, R12;				\
 	BYTE	$0xcc;				\
 	RET
 DEBUG_CALL_FN(debugCall32<>, 32)
@@ -1719,7 +1945,7 @@
 	MOVQ	AX, 0(SP)
 	MOVQ	val_data+8(FP), AX
 	MOVQ	AX, 8(SP)
-	MOVQ	$2, AX
+	MOVQ	$2, R12
 	BYTE	$0xcc
 	RET
 
@@ -1730,69 +1956,147 @@
 // The tail call makes these stubs disappear in backtraces.
 // Defined as ABIInternal since they do not use the stack-based Go ABI.
 TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	CX, BX
+#else
 	MOVQ	AX, x+0(FP)
 	MOVQ	CX, y+8(FP)
-	JMP	runtime·goPanicIndex(SB)
+#endif
+	JMP	runtime·goPanicIndex<ABIInternal>(SB)
 TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	CX, BX
+#else
 	MOVQ	AX, x+0(FP)
 	MOVQ	CX, y+8(FP)
-	JMP	runtime·goPanicIndexU(SB)
+#endif
+	JMP	runtime·goPanicIndexU<ABIInternal>(SB)
 TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	CX, AX
+	MOVQ	DX, BX
+#else
 	MOVQ	CX, x+0(FP)
 	MOVQ	DX, y+8(FP)
-	JMP	runtime·goPanicSliceAlen(SB)
+#endif
+	JMP	runtime·goPanicSliceAlen<ABIInternal>(SB)
 TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	CX, AX
+	MOVQ	DX, BX
+#else
 	MOVQ	CX, x+0(FP)
 	MOVQ	DX, y+8(FP)
-	JMP	runtime·goPanicSliceAlenU(SB)
+#endif
+	JMP	runtime·goPanicSliceAlenU<ABIInternal>(SB)
 TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	CX, AX
+	MOVQ	DX, BX
+#else
 	MOVQ	CX, x+0(FP)
 	MOVQ	DX, y+8(FP)
-	JMP	runtime·goPanicSliceAcap(SB)
+#endif
+	JMP	runtime·goPanicSliceAcap<ABIInternal>(SB)
 TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	CX, AX
+	MOVQ	DX, BX
+#else
 	MOVQ	CX, x+0(FP)
 	MOVQ	DX, y+8(FP)
-	JMP	runtime·goPanicSliceAcapU(SB)
+#endif
+	JMP	runtime·goPanicSliceAcapU<ABIInternal>(SB)
 TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	CX, BX
+#else
 	MOVQ	AX, x+0(FP)
 	MOVQ	CX, y+8(FP)
-	JMP	runtime·goPanicSliceB(SB)
+#endif
+	JMP	runtime·goPanicSliceB<ABIInternal>(SB)
 TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	CX, BX
+#else
 	MOVQ	AX, x+0(FP)
 	MOVQ	CX, y+8(FP)
-	JMP	runtime·goPanicSliceBU(SB)
+#endif
+	JMP	runtime·goPanicSliceBU<ABIInternal>(SB)
 TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	DX, AX
+#else
 	MOVQ	DX, x+0(FP)
 	MOVQ	BX, y+8(FP)
-	JMP	runtime·goPanicSlice3Alen(SB)
+#endif
+	JMP	runtime·goPanicSlice3Alen<ABIInternal>(SB)
 TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	DX, AX
+#else
 	MOVQ	DX, x+0(FP)
 	MOVQ	BX, y+8(FP)
-	JMP	runtime·goPanicSlice3AlenU(SB)
+#endif
+	JMP	runtime·goPanicSlice3AlenU<ABIInternal>(SB)
 TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	DX, AX
+#else
 	MOVQ	DX, x+0(FP)
 	MOVQ	BX, y+8(FP)
-	JMP	runtime·goPanicSlice3Acap(SB)
+#endif
+	JMP	runtime·goPanicSlice3Acap<ABIInternal>(SB)
 TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	DX, AX
+#else
 	MOVQ	DX, x+0(FP)
 	MOVQ	BX, y+8(FP)
-	JMP	runtime·goPanicSlice3AcapU(SB)
+#endif
+	JMP	runtime·goPanicSlice3AcapU<ABIInternal>(SB)
 TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	CX, AX
+	MOVQ	DX, BX
+#else
 	MOVQ	CX, x+0(FP)
 	MOVQ	DX, y+8(FP)
-	JMP	runtime·goPanicSlice3B(SB)
+#endif
+	JMP	runtime·goPanicSlice3B<ABIInternal>(SB)
 TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	CX, AX
+	MOVQ	DX, BX
+#else
 	MOVQ	CX, x+0(FP)
 	MOVQ	DX, y+8(FP)
-	JMP	runtime·goPanicSlice3BU(SB)
+#endif
+	JMP	runtime·goPanicSlice3BU<ABIInternal>(SB)
 TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	CX, BX
+#else
 	MOVQ	AX, x+0(FP)
 	MOVQ	CX, y+8(FP)
-	JMP	runtime·goPanicSlice3C(SB)
+#endif
+	JMP	runtime·goPanicSlice3C<ABIInternal>(SB)
 TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	CX, BX
+#else
 	MOVQ	AX, x+0(FP)
 	MOVQ	CX, y+8(FP)
-	JMP	runtime·goPanicSlice3CU(SB)
+#endif
+	JMP	runtime·goPanicSlice3CU<ABIInternal>(SB)
+TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	DX, AX
+#else
+	MOVQ	DX, x+0(FP)
+	MOVQ	BX, y+8(FP)
+#endif
+	JMP	runtime·goPanicSliceConvert<ABIInternal>(SB)
 
 #ifdef GOOS_android
 // Use the free TLS_SLOT_APP slot #2 on Android Q.
diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s
index c54b4eb..6d3573d 100644
--- a/src/runtime/asm_arm.s
+++ b/src/runtime/asm_arm.s
@@ -112,7 +112,7 @@
 
 // using NOFRAME means do not save LR on stack.
 // argc is in R0, argv is in R1.
-TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
 	MOVW	$0xcafebabe, R12
 
 	// copy arguments forward on an even stack
@@ -142,6 +142,11 @@
 
 	BL	runtime·emptyfunc(SB)	// fault if stack check is wrong
 
+#ifdef GOOS_openbsd
+	// Save g to TLS so that it is available from signal trampoline.
+	BL	runtime·save_g(SB)
+#endif
+
 	BL	runtime·_initcgo(SB)	// will clobber R0-R3
 
 	// update stackguard after _cgo_init
@@ -202,44 +207,24 @@
 	WORD	$0xeee1ba10	// vmsr fpscr, r11
 	RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+	BL	runtime·mstart0(SB)
+	RET // not reached
+
 /*
  *  go-routine
  */
 
-// void gosave(Gobuf*)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB),NOSPLIT|NOFRAME,$0-4
-	MOVW	buf+0(FP), R0
-	MOVW	R13, gobuf_sp(R0)
-	MOVW	LR, gobuf_pc(R0)
-	MOVW	g, gobuf_g(R0)
-	MOVW	$0, R11
-	MOVW	R11, gobuf_lr(R0)
-	MOVW	R11, gobuf_ret(R0)
-	// Assert ctxt is zero. See func save.
-	MOVW	gobuf_ctxt(R0), R0
-	CMP	R0, R11
-	B.EQ	2(PC)
-	CALL	runtime·badctxt(SB)
-	RET
-
 // void gogo(Gobuf*)
 // restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB),NOSPLIT,$8-4
+TEXT runtime·gogo(SB),NOSPLIT|NOFRAME,$0-4
 	MOVW	buf+0(FP), R1
 	MOVW	gobuf_g(R1), R0
-	BL	setg<>(SB)
+	MOVW	0(R0), R2	// make sure g != nil
+	B	gogo<>(SB)
 
-	// NOTE: We updated g above, and we are about to update SP.
-	// Until LR and PC are also updated, the g/SP/LR/PC quadruple
-	// are out of sync and must not be used as the basis of a traceback.
-	// Sigprof skips the traceback when SP is not within g's bounds,
-	// and when the PC is inside this function, runtime.gogo.
-	// Since we are about to update SP, until we complete runtime.gogo
-	// we must not leave this function. In particular, no calls
-	// after this point: it must be straight-line code until the
-	// final B instruction.
-	// See large comment in sigprof for more details.
+TEXT gogo<>(SB),NOSPLIT|NOFRAME,$0
+	BL	setg<>(SB)
 	MOVW	gobuf_sp(R1), R13	// restore SP==R13
 	MOVW	gobuf_lr(R1), LR
 	MOVW	gobuf_ret(R1), R0
@@ -263,7 +248,6 @@
 	MOVW	LR, (g_sched+gobuf_pc)(g)
 	MOVW	$0, R11
 	MOVW	R11, (g_sched+gobuf_lr)(g)
-	MOVW	g, (g_sched+gobuf_g)(g)
 
 	// Switch to m->g0 & its stack, call fn.
 	MOVW	g, R1
@@ -273,9 +257,6 @@
 	CMP	g, R1
 	B.NE	2(PC)
 	B	runtime·badmcall(SB)
-	MOVB	runtime·iscgo(SB), R11
-	CMP	$0, R11
-	BL.NE	runtime·save_g(SB)
 	MOVW	fn+0(FP), R0
 	MOVW	(g_sched+gobuf_sp)(g), R13
 	SUB	$8, R13
@@ -322,24 +303,14 @@
 switch:
 	// save our state in g->sched. Pretend to
 	// be systemstack_switch if the G stack is scanned.
-	MOVW	$runtime·systemstack_switch(SB), R3
-	ADD	$4, R3, R3 // get past push {lr}
-	MOVW	R3, (g_sched+gobuf_pc)(g)
-	MOVW	R13, (g_sched+gobuf_sp)(g)
-	MOVW	LR, (g_sched+gobuf_lr)(g)
-	MOVW	g, (g_sched+gobuf_g)(g)
+	BL	gosave_systemstack_switch<>(SB)
 
 	// switch to g0
 	MOVW	R0, R5
 	MOVW	R2, R0
 	BL	setg<>(SB)
 	MOVW	R5, R0
-	MOVW	(g_sched+gobuf_sp)(R2), R3
-	// make it look like mstart called systemstack on g0, to stop traceback
-	SUB	$4, R3, R3
-	MOVW	$runtime·mstart(SB), R4
-	MOVW	R4, 0(R3)
-	MOVW	R3, R13
+	MOVW	(g_sched+gobuf_sp)(R2), R13
 
 	// call target function
 	MOVW	R0, R7
@@ -421,7 +392,7 @@
 	B runtime·morestack(SB)
 
 // reflectcall: call a function with the given argument list
-// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
+// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
 // we don't have variable-sized frames, so we use a small number
 // of constant-sized-frame functions to encode a few bits of size in the pc.
 // Caution: ugly multiline assembly macros in your future!
@@ -432,8 +403,8 @@
 	MOVW	$NAME(SB), R1;		\
 	B	(R1)
 
-TEXT ·reflectcall(SB),NOSPLIT|NOFRAME,$0-20
-	MOVW	argsize+12(FP), R0
+TEXT ·reflectcall(SB),NOSPLIT|NOFRAME,$0-28
+	MOVW	frameSize+20(FP), R0
 	DISPATCH(runtime·call16, 16)
 	DISPATCH(runtime·call32, 32)
 	DISPATCH(runtime·call64, 64)
@@ -465,11 +436,11 @@
 	B	(R1)
 
 #define CALLFN(NAME,MAXSIZE)			\
-TEXT NAME(SB), WRAPPER, $MAXSIZE-20;		\
+TEXT NAME(SB), WRAPPER, $MAXSIZE-28;		\
 	NO_LOCAL_POINTERS;			\
 	/* copy arguments to stack */		\
-	MOVW	argptr+8(FP), R0;		\
-	MOVW	argsize+12(FP), R2;		\
+	MOVW	stackArgs+8(FP), R0;		\
+	MOVW	stackArgsSize+12(FP), R2;		\
 	ADD	$4, R13, R1;			\
 	CMP	$0, R2;				\
 	B.EQ	5(PC);				\
@@ -483,10 +454,10 @@
 	PCDATA  $PCDATA_StackMapIndex, $0;	\
 	BL	(R0);				\
 	/* copy return values back */		\
-	MOVW	argtype+0(FP), R4;		\
-	MOVW	argptr+8(FP), R0;		\
-	MOVW	argsize+12(FP), R2;		\
-	MOVW	retoffset+16(FP), R3;		\
+	MOVW	stackArgsType+0(FP), R4;		\
+	MOVW	stackArgs+8(FP), R0;		\
+	MOVW	stackArgsSize+12(FP), R2;		\
+	MOVW	stackArgsRetOffset+16(FP), R3;		\
 	ADD	$4, R13, R1;			\
 	ADD	R3, R1;				\
 	ADD	R3, R0;				\
@@ -498,11 +469,13 @@
 // separate function so it can allocate stack space for the arguments
 // to reflectcallmove. It does not follow the Go ABI; it expects its
 // arguments in registers.
-TEXT callRet<>(SB), NOSPLIT, $16-0
+TEXT callRet<>(SB), NOSPLIT, $20-0
 	MOVW	R4, 4(R13)
 	MOVW	R0, 8(R13)
 	MOVW	R1, 12(R13)
 	MOVW	R2, 16(R13)
+	MOVW	$0, R7
+	MOVW	R7, 20(R13)
 	BL	runtime·reflectcallmove(SB)
 	RET
 
@@ -539,10 +512,6 @@
 // 1. grab stored LR for caller
 // 2. sub 4 bytes to get back to BL deferreturn
 // 3. B to fn
-// TODO(rsc): Push things on stack and then use pop
-// to load all registers simultaneously, so that a profiling
-// interrupt can never see mismatched SP/LR/PC.
-// (And double-check that pop is atomic in that way.)
 TEXT runtime·jmpdefer(SB),NOSPLIT,$0-8
 	MOVW	0(R13), LR
 	MOVW	$-4(LR), LR	// BL deferreturn
@@ -552,19 +521,39 @@
 	MOVW	0(R7), R1
 	B	(R1)
 
-// Save state of caller into g->sched. Smashes R11.
-TEXT gosave<>(SB),NOSPLIT|NOFRAME,$0
-	MOVW	LR, (g_sched+gobuf_pc)(g)
+// Save state of caller into g->sched,
+// but using fake PC from systemstack_switch.
+// Must only be called from functions with no locals ($0)
+// or else unwinding from systemstack_switch is incorrect.
+// Smashes R11.
+TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
+	MOVW	$runtime·systemstack_switch(SB), R11
+	ADD	$4, R11 // get past push {lr}
+	MOVW	R11, (g_sched+gobuf_pc)(g)
 	MOVW	R13, (g_sched+gobuf_sp)(g)
 	MOVW	$0, R11
 	MOVW	R11, (g_sched+gobuf_lr)(g)
 	MOVW	R11, (g_sched+gobuf_ret)(g)
-	MOVW	R11, (g_sched+gobuf_ctxt)(g)
 	// Assert ctxt is zero. See func save.
 	MOVW	(g_sched+gobuf_ctxt)(g), R11
-	CMP	$0, R11
+	TST	R11, R11
 	B.EQ	2(PC)
-	CALL	runtime·badctxt(SB)
+	BL	runtime·abort(SB)
+	RET
+
+// func asmcgocall_no_g(fn, arg unsafe.Pointer)
+// Call fn(arg) aligned appropriately for the gcc ABI.
+// Called on a system stack, and there may be no g yet (during needm).
+TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-8
+	MOVW	fn+0(FP), R1
+	MOVW	arg+4(FP), R0
+	MOVW	R13, R2
+	SUB	$32, R13
+	BIC	$0x7, R13	// alignment for gcc ABI
+	MOVW	R2, 8(R13)
+	BL	(R1)
+	MOVW	8(R13), R2
+	MOVW	R2, R13
 	RET
 
 // func asmcgocall(fn, arg unsafe.Pointer) int32
@@ -590,7 +579,7 @@
 	MOVW	m_g0(R8), R3
 	CMP	R3, g
 	BEQ	nosave
-	BL	gosave<>(SB)
+	BL	gosave_systemstack_switch<>(SB)
 	MOVW	R0, R5
 	MOVW	R3, R0
 	BL	setg<>(SB)
@@ -649,9 +638,13 @@
 	NO_LOCAL_POINTERS
 
 	// Load m and g from thread-local storage.
+#ifdef GOOS_openbsd
+	BL	runtime·load_g(SB)
+#else
 	MOVB	runtime·iscgo(SB), R0
 	CMP	$0, R0
 	BL.NE	runtime·load_g(SB)
+#endif
 
 	// If g is nil, Go did not create the current thread.
 	// Call needm to obtain one for temporary use.
@@ -761,6 +754,9 @@
 #ifdef GOOS_windows
 	B	runtime·save_g(SB)
 #else
+#ifdef GOOS_openbsd
+	B	runtime·save_g(SB)
+#else
 	MOVB	runtime·iscgo(SB), R0
 	CMP	$0, R0
 	B.EQ	2(PC)
@@ -769,6 +765,7 @@
 	MOVW	g, R0
 	RET
 #endif
+#endif
 
 TEXT runtime·emptyfunc(SB),0,$0-0
 	RET
@@ -1005,6 +1002,10 @@
 	MOVW	R0, x+0(FP)
 	MOVW	R1, y+4(FP)
 	JMP	runtime·goPanicSlice3CU(SB)
+TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-8
+	MOVW	R2, x+0(FP)
+	MOVW	R3, y+4(FP)
+	JMP	runtime·goPanicSliceConvert(SB)
 
 // Extended versions for 64-bit indexes.
 TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s
index a09172f..2d49539 100644
--- a/src/runtime/asm_arm64.s
+++ b/src/runtime/asm_arm64.s
@@ -8,7 +8,7 @@
 #include "funcdata.h"
 #include "textflag.h"
 
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
 	// SP = stack; R0 = argc; R1 = argv
 
 	SUB	$32, RSP
@@ -73,6 +73,10 @@
 
 	BL	runtime·check(SB)
 
+#ifdef GOOS_windows
+	BL	runtime·wintls(SB)
+#endif
+
 	MOVW	8(RSP), R0	// copy argc
 	MOVW	R0, -8(RSP)
 	MOVD	16(RSP), R0		// copy argv
@@ -109,35 +113,26 @@
 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
 	RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+	BL	runtime·mstart0(SB)
+	RET // not reached
+
 /*
  *  go-routine
  */
 
-// void gosave(Gobuf*)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB), NOSPLIT|NOFRAME, $0-8
-	MOVD	buf+0(FP), R3
-	MOVD	RSP, R0
-	MOVD	R0, gobuf_sp(R3)
-	MOVD	R29, gobuf_bp(R3)
-	MOVD	LR, gobuf_pc(R3)
-	MOVD	g, gobuf_g(R3)
-	MOVD	ZR, gobuf_lr(R3)
-	MOVD	ZR, gobuf_ret(R3)
-	// Assert ctxt is zero. See func save.
-	MOVD	gobuf_ctxt(R3), R0
-	CBZ	R0, 2(PC)
-	CALL	runtime·badctxt(SB)
-	RET
-
 // void gogo(Gobuf*)
 // restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB), NOSPLIT, $24-8
+TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
 	MOVD	buf+0(FP), R5
-	MOVD	gobuf_g(R5), g
+	MOVD	gobuf_g(R5), R6
+	MOVD	0(R6), R4	// make sure g != nil
+	B	gogo<>(SB)
+
+TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
+	MOVD	R6, g
 	BL	runtime·save_g(SB)
 
-	MOVD	0(g), R4	// make sure g is not nil
 	MOVD	gobuf_sp(R5), R0
 	MOVD	R0, RSP
 	MOVD	gobuf_bp(R5), R29
@@ -164,7 +159,6 @@
 	MOVD	R29, (g_sched+gobuf_bp)(g)
 	MOVD	LR, (g_sched+gobuf_pc)(g)
 	MOVD	$0, (g_sched+gobuf_lr)(g)
-	MOVD	g, (g_sched+gobuf_g)(g)
 
 	// Switch to m->g0 & its stack, call fn.
 	MOVD	g, R3
@@ -222,24 +216,12 @@
 switch:
 	// save our state in g->sched. Pretend to
 	// be systemstack_switch if the G stack is scanned.
-	MOVD	$runtime·systemstack_switch(SB), R6
-	ADD	$8, R6	// get past prologue
-	MOVD	R6, (g_sched+gobuf_pc)(g)
-	MOVD	RSP, R0
-	MOVD	R0, (g_sched+gobuf_sp)(g)
-	MOVD	R29, (g_sched+gobuf_bp)(g)
-	MOVD	$0, (g_sched+gobuf_lr)(g)
-	MOVD	g, (g_sched+gobuf_g)(g)
+	BL	gosave_systemstack_switch<>(SB)
 
 	// switch to g0
 	MOVD	R5, g
 	BL	runtime·save_g(SB)
 	MOVD	(g_sched+gobuf_sp)(g), R3
-	// make it look like mstart called systemstack on g0, to stop traceback
-	SUB	$16, R3
-	AND	$~15, R3
-	MOVD	$runtime·mstart(SB), R4
-	MOVD	R4, 0(R3)
 	MOVD	R3, RSP
 	MOVD	(g_sched+gobuf_bp)(g), R29
 
@@ -329,7 +311,7 @@
 	B runtime·morestack(SB)
 
 // reflectcall: call a function with the given argument list
-// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
+// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
 // we don't have variable-sized frames, so we use a small number
 // of constant-sized-frame functions to encode a few bits of size in the pc.
 // Caution: ugly multiline assembly macros in your future!
@@ -342,8 +324,8 @@
 	B	(R27)
 // Note: can't just "B NAME(SB)" - bad inlining results.
 
-TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-32
-	MOVWU argsize+24(FP), R16
+TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
+	MOVWU	frameSize+32(FP), R16
 	DISPATCH(runtime·call16, 16)
 	DISPATCH(runtime·call32, 32)
 	DISPATCH(runtime·call64, 64)
@@ -375,11 +357,11 @@
 	B	(R0)
 
 #define CALLFN(NAME,MAXSIZE)			\
-TEXT NAME(SB), WRAPPER, $MAXSIZE-24;		\
+TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
 	NO_LOCAL_POINTERS;			\
 	/* copy arguments to stack */		\
-	MOVD	arg+16(FP), R3;			\
-	MOVWU	argsize+24(FP), R4;		\
+	MOVD	stackArgs+16(FP), R3;			\
+	MOVWU	stackArgsSize+24(FP), R4;		\
 	ADD	$8, RSP, R5;			\
 	BIC	$0xf, R4, R6;			\
 	CBZ	R6, 6(PC);			\
@@ -405,10 +387,10 @@
 	PCDATA  $PCDATA_StackMapIndex, $0;	\
 	BL	(R0);				\
 	/* copy return values back */		\
-	MOVD	argtype+0(FP), R7;		\
-	MOVD	arg+16(FP), R3;			\
-	MOVWU	n+24(FP), R4;			\
-	MOVWU	retoffset+28(FP), R6;		\
+	MOVD	stackArgsType+0(FP), R7;		\
+	MOVD	stackArgs+16(FP), R3;			\
+	MOVWU	stackArgsSize+24(FP), R4;			\
+	MOVWU	stackRetOffset+28(FP), R6;		\
 	ADD	$8, RSP, R5;			\
 	ADD	R6, R5; 			\
 	ADD	R6, R3;				\
@@ -420,11 +402,12 @@
 // separate function so it can allocate stack space for the arguments
 // to reflectcallmove. It does not follow the Go ABI; it expects its
 // arguments in registers.
-TEXT callRet<>(SB), NOSPLIT, $40-0
+TEXT callRet<>(SB), NOSPLIT, $48-0
 	MOVD	R7, 8(RSP)
 	MOVD	R3, 16(RSP)
 	MOVD	R5, 24(RSP)
 	MOVD	R4, 32(RSP)
+	MOVD	$0, 40(RSP)
 	BL	runtime·reflectcallmove(SB)
 	RET
 
@@ -875,9 +858,15 @@
 	MOVD	0(R26), R3
 	B	(R3)
 
-// Save state of caller into g->sched. Smashes R0.
-TEXT gosave<>(SB),NOSPLIT|NOFRAME,$0
-	MOVD	LR, (g_sched+gobuf_pc)(g)
+// Save state of caller into g->sched,
+// but using fake PC from systemstack_switch.
+// Must only be called from functions with no locals ($0)
+// or else unwinding from systemstack_switch is incorrect.
+// Smashes R0.
+TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
+	MOVD	$runtime·systemstack_switch(SB), R0
+	ADD	$8, R0	// get past prologue
+	MOVD	R0, (g_sched+gobuf_pc)(g)
 	MOVD	RSP, R0
 	MOVD	R0, (g_sched+gobuf_sp)(g)
 	MOVD	R29, (g_sched+gobuf_bp)(g)
@@ -886,7 +875,18 @@
 	// Assert ctxt is zero. See func save.
 	MOVD	(g_sched+gobuf_ctxt)(g), R0
 	CBZ	R0, 2(PC)
-	CALL	runtime·badctxt(SB)
+	CALL	runtime·abort(SB)
+	RET
+
+// func asmcgocall_no_g(fn, arg unsafe.Pointer)
+// Call fn(arg) aligned appropriately for the gcc ABI.
+// Called on a system stack, and there may be no g yet (during needm).
+TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
+	MOVD	fn+0(FP), R1
+	MOVD	arg+8(FP), R0
+	SUB	$16, RSP	// skip over saved frame pointer below RSP
+	BL	(R1)
+	ADD	$16, RSP	// skip over saved frame pointer below RSP
 	RET
 
 // func asmcgocall(fn, arg unsafe.Pointer) int32
@@ -913,8 +913,8 @@
 	BEQ	nosave
 
 	// Switch to system stack.
-	MOVD	R0, R9	// gosave<> and save_g might clobber R0
-	BL	gosave<>(SB)
+	MOVD	R0, R9	// gosave_systemstack_switch<> and save_g might clobber R0
+	BL	gosave_systemstack_switch<>(SB)
 	MOVD	R3, g
 	BL	runtime·save_g(SB)
 	MOVD	(g_sched+gobuf_sp)(g), R0
@@ -967,7 +967,7 @@
 	BL	(R1)
 	// Restore stack pointer.
 	MOVD	8(RSP), R2
-	MOVD	R2, RSP	
+	MOVD	R2, RSP
 	MOVD	R0, ret+16(FP)
 	RET
 
@@ -1115,6 +1115,9 @@
 	MOVD	savedR27-8(SP), R27
 	RET
 
+TEXT runtime·emptyfunc(SB),0,$0-0
+	RET
+
 TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
 	MOVD	ZR, R0
 	MOVD	(R0), R0
@@ -1155,10 +1158,10 @@
 // It does not clobber any general-purpose registers,
 // but may clobber others (e.g., floating point registers)
 // The act of CALLing gcWriteBarrier will clobber R30 (LR).
-TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$216
+TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$200
 	// Save the registers clobbered by the fast path.
-	MOVD	R0, 200(RSP)
-	MOVD	R1, 208(RSP)
+	MOVD	R0, 184(RSP)
+	MOVD	R1, 192(RSP)
 	MOVD	g_m(g), R0
 	MOVD	m_p(R0), R0
 	MOVD	(p_wbBuf+wbBuf_next)(R0), R1
@@ -1174,8 +1177,8 @@
 	// Is the buffer full? (flags set in CMP above)
 	BEQ	flush
 ret:
-	MOVD	200(RSP), R0
-	MOVD	208(RSP), R1
+	MOVD	184(RSP), R0
+	MOVD	192(RSP), R1
 	// Do the write.
 	MOVD	R3, (R2)
 	RET
@@ -1199,17 +1202,16 @@
 	MOVD	R13, 96(RSP)
 	MOVD	R14, 104(RSP)
 	MOVD	R15, 112(RSP)
-	MOVD	R16, 120(RSP)
-	MOVD	R17, 128(RSP)
+	// R16, R17 may be clobbered by linker trampoline
 	// R18 is unused.
-	MOVD	R19, 136(RSP)
-	MOVD	R20, 144(RSP)
-	MOVD	R21, 152(RSP)
-	MOVD	R22, 160(RSP)
-	MOVD	R23, 168(RSP)
-	MOVD	R24, 176(RSP)
-	MOVD	R25, 184(RSP)
-	MOVD	R26, 192(RSP)
+	MOVD	R19, 120(RSP)
+	MOVD	R20, 128(RSP)
+	MOVD	R21, 136(RSP)
+	MOVD	R22, 144(RSP)
+	MOVD	R23, 152(RSP)
+	MOVD	R24, 160(RSP)
+	MOVD	R25, 168(RSP)
+	MOVD	R26, 176(RSP)
 	// R27 is temp register.
 	// R28 is g.
 	// R29 is frame pointer (unused).
@@ -1233,16 +1235,14 @@
 	MOVD	96(RSP), R13
 	MOVD	104(RSP), R14
 	MOVD	112(RSP), R15
-	MOVD	120(RSP), R16
-	MOVD	128(RSP), R17
-	MOVD	136(RSP), R19
-	MOVD	144(RSP), R20
-	MOVD	152(RSP), R21
-	MOVD	160(RSP), R22
-	MOVD	168(RSP), R23
-	MOVD	176(RSP), R24
-	MOVD	184(RSP), R25
-	MOVD	192(RSP), R26
+	MOVD	120(RSP), R19
+	MOVD	128(RSP), R20
+	MOVD	136(RSP), R21
+	MOVD	144(RSP), R22
+	MOVD	152(RSP), R23
+	MOVD	160(RSP), R24
+	MOVD	168(RSP), R25
+	MOVD	176(RSP), R26
 	JMP	ret
 
 // Note: these functions use a special calling convention to save generated code space.
@@ -1314,3 +1314,7 @@
 	MOVD	R0, x+0(FP)
 	MOVD	R1, y+8(FP)
 	JMP	runtime·goPanicSlice3CU(SB)
+TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16
+	MOVD	R2, x+0(FP)
+	MOVD	R3, y+8(FP)
+	JMP	runtime·goPanicSliceConvert(SB)
diff --git a/src/runtime/asm_mips64x.s b/src/runtime/asm_mips64x.s
index 19781f7..d4d2280 100644
--- a/src/runtime/asm_mips64x.s
+++ b/src/runtime/asm_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "go_asm.h"
@@ -11,7 +12,7 @@
 
 #define	REGCTXT	R22
 
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
 	// R29 = stack; R4 = argc; R5 = argv
 
 	ADDV	$-24, R29
@@ -85,30 +86,24 @@
 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
 	RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+	JAL	runtime·mstart0(SB)
+	RET // not reached
+
 /*
  *  go-routine
  */
 
-// void gosave(Gobuf*)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB), NOSPLIT|NOFRAME, $0-8
-	MOVV	buf+0(FP), R1
-	MOVV	R29, gobuf_sp(R1)
-	MOVV	R31, gobuf_pc(R1)
-	MOVV	g, gobuf_g(R1)
-	MOVV	R0, gobuf_lr(R1)
-	MOVV	R0, gobuf_ret(R1)
-	// Assert ctxt is zero. See func save.
-	MOVV	gobuf_ctxt(R1), R1
-	BEQ	R1, 2(PC)
-	JAL	runtime·badctxt(SB)
-	RET
-
 // void gogo(Gobuf*)
 // restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB), NOSPLIT, $16-8
+TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
 	MOVV	buf+0(FP), R3
-	MOVV	gobuf_g(R3), g	// make sure g is not nil
+	MOVV	gobuf_g(R3), R4
+	MOVV	0(R4), R0	// make sure g != nil
+	JMP	gogo<>(SB)
+
+TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
+	MOVV	R4, g
 	JAL	runtime·save_g(SB)
 
 	MOVV	0(g), R2
@@ -132,7 +127,6 @@
 	MOVV	R29, (g_sched+gobuf_sp)(g)
 	MOVV	R31, (g_sched+gobuf_pc)(g)
 	MOVV	R0, (g_sched+gobuf_lr)(g)
-	MOVV	g, (g_sched+gobuf_g)(g)
 
 	// Switch to m->g0 & its stack, call fn.
 	MOVV	g, R1
@@ -184,21 +178,12 @@
 switch:
 	// save our state in g->sched. Pretend to
 	// be systemstack_switch if the G stack is scanned.
-	MOVV	$runtime·systemstack_switch(SB), R4
-	ADDV	$8, R4	// get past prologue
-	MOVV	R4, (g_sched+gobuf_pc)(g)
-	MOVV	R29, (g_sched+gobuf_sp)(g)
-	MOVV	R0, (g_sched+gobuf_lr)(g)
-	MOVV	g, (g_sched+gobuf_g)(g)
+	JAL	gosave_systemstack_switch<>(SB)
 
 	// switch to g0
 	MOVV	R3, g
 	JAL	runtime·save_g(SB)
 	MOVV	(g_sched+gobuf_sp)(g), R1
-	// make it look like mstart called systemstack on g0, to stop traceback
-	ADDV	$-8, R1
-	MOVV	$runtime·mstart(SB), R2
-	MOVV	R2, 0(R1)
 	MOVV	R1, R29
 
 	// call target function
@@ -279,7 +264,7 @@
 	JMP	runtime·morestack(SB)
 
 // reflectcall: call a function with the given argument list
-// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
+// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
 // we don't have variable-sized frames, so we use a small number
 // of constant-sized-frame functions to encode a few bits of size in the pc.
 // Caution: ugly multiline assembly macros in your future!
@@ -292,8 +277,8 @@
 	JMP	(R4)
 // Note: can't just "BR NAME(SB)" - bad inlining results.
 
-TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-32
-	MOVWU argsize+24(FP), R1
+TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
+	MOVWU	frameSize+32(FP), R1
 	DISPATCH(runtime·call16, 16)
 	DISPATCH(runtime·call32, 32)
 	DISPATCH(runtime·call64, 64)
@@ -325,11 +310,11 @@
 	JMP	(R4)
 
 #define CALLFN(NAME,MAXSIZE)			\
-TEXT NAME(SB), WRAPPER, $MAXSIZE-24;		\
+TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
 	NO_LOCAL_POINTERS;			\
 	/* copy arguments to stack */		\
-	MOVV	arg+16(FP), R1;			\
-	MOVWU	argsize+24(FP), R2;			\
+	MOVV	stackArgs+16(FP), R1;			\
+	MOVWU	stackArgsSize+24(FP), R2;			\
 	MOVV	R29, R3;				\
 	ADDV	$8, R3;			\
 	ADDV	R3, R2;				\
@@ -345,10 +330,10 @@
 	PCDATA  $PCDATA_StackMapIndex, $0;	\
 	JAL	(R4);				\
 	/* copy return values back */		\
-	MOVV	argtype+0(FP), R5;		\
-	MOVV	arg+16(FP), R1;			\
-	MOVWU	n+24(FP), R2;			\
-	MOVWU	retoffset+28(FP), R4;		\
+	MOVV	stackArgsType+0(FP), R5;		\
+	MOVV	stackArgs+16(FP), R1;			\
+	MOVWU	stackArgsSize+24(FP), R2;			\
+	MOVWU	stackRetOffset+28(FP), R4;		\
 	ADDV	$8, R29, R3;				\
 	ADDV	R4, R3; 			\
 	ADDV	R4, R1;				\
@@ -360,11 +345,12 @@
 // separate function so it can allocate stack space for the arguments
 // to reflectcallmove. It does not follow the Go ABI; it expects its
 // arguments in registers.
-TEXT callRet<>(SB), NOSPLIT, $32-0
+TEXT callRet<>(SB), NOSPLIT, $40-0
 	MOVV	R5, 8(R29)
 	MOVV	R1, 16(R29)
 	MOVV	R3, 24(R29)
 	MOVV	R2, 32(R29)
+	MOVV	$0, 40(R29)
 	JAL	runtime·reflectcallmove(SB)
 	RET
 
@@ -415,16 +401,31 @@
 	MOVV	0(REGCTXT), R4
 	JMP	(R4)
 
-// Save state of caller into g->sched. Smashes R1.
-TEXT gosave<>(SB),NOSPLIT|NOFRAME,$0
-	MOVV	R31, (g_sched+gobuf_pc)(g)
+// Save state of caller into g->sched,
+// but using fake PC from systemstack_switch.
+// Must only be called from functions with no locals ($0)
+// or else unwinding from systemstack_switch is incorrect.
+// Smashes R1.
+TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
+	MOVV	$runtime·systemstack_switch(SB), R1
+	ADDV	$8, R1	// get past prologue
+	MOVV	R1, (g_sched+gobuf_pc)(g)
 	MOVV	R29, (g_sched+gobuf_sp)(g)
 	MOVV	R0, (g_sched+gobuf_lr)(g)
 	MOVV	R0, (g_sched+gobuf_ret)(g)
 	// Assert ctxt is zero. See func save.
 	MOVV	(g_sched+gobuf_ctxt)(g), R1
 	BEQ	R1, 2(PC)
-	JAL	runtime·badctxt(SB)
+	JAL	runtime·abort(SB)
+	RET
+
+// func asmcgocall_no_g(fn, arg unsafe.Pointer)
+// Call fn(arg) aligned appropriately for the gcc ABI.
+// Called on a system stack, and there may be no g yet (during needm).
+TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
+	MOVV	fn+0(FP), R25
+	MOVV	arg+8(FP), R4
+	JAL	(R25)
 	RET
 
 // func asmcgocall(fn, arg unsafe.Pointer) int32
@@ -445,7 +446,7 @@
 	MOVV	m_g0(R5), R6
 	BEQ	R6, g, g0
 
-	JAL	gosave<>(SB)
+	JAL	gosave_systemstack_switch<>(SB)
 	MOVV	R6, g
 	JAL	runtime·save_g(SB)
 	MOVV	(g_sched+gobuf_sp)(g), R29
@@ -805,3 +806,7 @@
 	MOVV	R1, x+0(FP)
 	MOVV	R2, y+8(FP)
 	JMP	runtime·goPanicSlice3CU(SB)
+TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16
+	MOVV	R3, x+0(FP)
+	MOVV	R4, y+8(FP)
+	JMP	runtime·goPanicSliceConvert(SB)
diff --git a/src/runtime/asm_mipsx.s b/src/runtime/asm_mipsx.s
index ee87d81..ea7edf2 100644
--- a/src/runtime/asm_mipsx.s
+++ b/src/runtime/asm_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "go_asm.h"
@@ -11,7 +12,7 @@
 
 #define	REGCTXT	R22
 
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
 	// R29 = stack; R4 = argc; R5 = argv
 
 	ADDU	$-12, R29
@@ -86,33 +87,25 @@
 TEXT runtime·asminit(SB),NOSPLIT,$0-0
 	RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+	JAL	runtime·mstart0(SB)
+	RET // not reached
+
 /*
  *  go-routine
  */
 
-// void gosave(Gobuf*)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB),NOSPLIT|NOFRAME,$0-4
-	MOVW	buf+0(FP), R1
-	MOVW	R29, gobuf_sp(R1)
-	MOVW	R31, gobuf_pc(R1)
-	MOVW	g, gobuf_g(R1)
-	MOVW	R0, gobuf_lr(R1)
-	MOVW	R0, gobuf_ret(R1)
-	// Assert ctxt is zero. See func save.
-	MOVW	gobuf_ctxt(R1), R1
-	BEQ	R1, 2(PC)
-	JAL	runtime·badctxt(SB)
-	RET
-
 // void gogo(Gobuf*)
 // restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB),NOSPLIT,$8-4
+TEXT runtime·gogo(SB),NOSPLIT|NOFRAME,$0-4
 	MOVW	buf+0(FP), R3
-	MOVW	gobuf_g(R3), g	// make sure g is not nil
-	JAL	runtime·save_g(SB)
+	MOVW	gobuf_g(R3), R4
+	MOVW	0(R4), R5	// make sure g != nil
+	JMP	gogo<>(SB)
 
-	MOVW	0(g), R2
+TEXT gogo<>(SB),NOSPLIT|NOFRAME,$0
+	MOVW	R4, g
+	JAL	runtime·save_g(SB)
 	MOVW	gobuf_sp(R3), R29
 	MOVW	gobuf_lr(R3), R31
 	MOVW	gobuf_ret(R3), R1
@@ -133,7 +126,6 @@
 	MOVW	R29, (g_sched+gobuf_sp)(g)
 	MOVW	R31, (g_sched+gobuf_pc)(g)
 	MOVW	R0, (g_sched+gobuf_lr)(g)
-	MOVW	g, (g_sched+gobuf_g)(g)
 
 	// Switch to m->g0 & its stack, call fn.
 	MOVW	g, R1
@@ -185,21 +177,12 @@
 switch:
 	// save our state in g->sched.  Pretend to
 	// be systemstack_switch if the G stack is scanned.
-	MOVW	$runtime·systemstack_switch(SB), R4
-	ADDU	$8, R4	// get past prologue
-	MOVW	R4, (g_sched+gobuf_pc)(g)
-	MOVW	R29, (g_sched+gobuf_sp)(g)
-	MOVW	R0, (g_sched+gobuf_lr)(g)
-	MOVW	g, (g_sched+gobuf_g)(g)
+	JAL	gosave_systemstack_switch<>(SB)
 
 	// switch to g0
 	MOVW	R3, g
 	JAL	runtime·save_g(SB)
 	MOVW	(g_sched+gobuf_sp)(g), R1
-	// make it look like mstart called systemstack on g0, to stop traceback
-	ADDU	$-4, R1
-	MOVW	$runtime·mstart(SB), R2
-	MOVW	R2, 0(R1)
 	MOVW	R1, R29
 
 	// call target function
@@ -280,7 +263,7 @@
 	JMP	runtime·morestack(SB)
 
 // reflectcall: call a function with the given argument list
-// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
+// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
 // we don't have variable-sized frames, so we use a small number
 // of constant-sized-frame functions to encode a few bits of size in the pc.
 
@@ -291,8 +274,8 @@
 	MOVW	$NAME(SB), R4;	\
 	JMP	(R4)
 
-TEXT ·reflectcall(SB),NOSPLIT|NOFRAME,$0-20
-	MOVW	argsize+12(FP), R1
+TEXT ·reflectcall(SB),NOSPLIT|NOFRAME,$0-28
+	MOVW	frameSize+20(FP), R1
 
 	DISPATCH(runtime·call16, 16)
 	DISPATCH(runtime·call32, 32)
@@ -325,11 +308,11 @@
 	JMP	(R4)
 
 #define CALLFN(NAME,MAXSIZE)	\
-TEXT NAME(SB),WRAPPER,$MAXSIZE-20;	\
+TEXT NAME(SB),WRAPPER,$MAXSIZE-28;	\
 	NO_LOCAL_POINTERS;	\
 	/* copy arguments to stack */		\
-	MOVW	arg+8(FP), R1;	\
-	MOVW	argsize+12(FP), R2;	\
+	MOVW	stackArgs+8(FP), R1;	\
+	MOVW	stackArgsSize+12(FP), R2;	\
 	MOVW	R29, R3;	\
 	ADDU	$4, R3;	\
 	ADDU	R3, R2;	\
@@ -345,10 +328,10 @@
 	PCDATA	$PCDATA_StackMapIndex, $0;	\
 	JAL	(R4);	\
 	/* copy return values back */		\
-	MOVW	argtype+0(FP), R5;	\
-	MOVW	arg+8(FP), R1;	\
-	MOVW	n+12(FP), R2;	\
-	MOVW	retoffset+16(FP), R4;	\
+	MOVW	stackArgsType+0(FP), R5;	\
+	MOVW	stackArgs+8(FP), R1;	\
+	MOVW	stackArgsSize+12(FP), R2;	\
+	MOVW	stackRetOffset+16(FP), R4;	\
 	ADDU	$4, R29, R3;	\
 	ADDU	R4, R3;	\
 	ADDU	R4, R1;	\
@@ -360,11 +343,12 @@
 // separate function so it can allocate stack space for the arguments
 // to reflectcallmove. It does not follow the Go ABI; it expects its
 // arguments in registers.
-TEXT callRet<>(SB), NOSPLIT, $16-0
+TEXT callRet<>(SB), NOSPLIT, $20-0
 	MOVW	R5, 4(R29)
 	MOVW	R1, 8(R29)
 	MOVW	R3, 12(R29)
 	MOVW	R2, 16(R29)
+	MOVW    $0, 20(R29)
 	JAL	runtime·reflectcallmove(SB)
 	RET
 
@@ -415,16 +399,22 @@
 	MOVW	0(REGCTXT), R4
 	JMP	(R4)
 
-// Save state of caller into g->sched. Smashes R1.
-TEXT gosave<>(SB),NOSPLIT|NOFRAME,$0
-	MOVW	R31, (g_sched+gobuf_pc)(g)
+// Save state of caller into g->sched,
+// but using fake PC from systemstack_switch.
+// Must only be called from functions with no locals ($0)
+// or else unwinding from systemstack_switch is incorrect.
+// Smashes R1.
+TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
+	MOVW	$runtime·systemstack_switch(SB), R1
+	ADDU	$8, R1	// get past prologue
+	MOVW	R1, (g_sched+gobuf_pc)(g)
 	MOVW	R29, (g_sched+gobuf_sp)(g)
 	MOVW	R0, (g_sched+gobuf_lr)(g)
 	MOVW	R0, (g_sched+gobuf_ret)(g)
 	// Assert ctxt is zero. See func save.
 	MOVW	(g_sched+gobuf_ctxt)(g), R1
 	BEQ	R1, 2(PC)
-	JAL	runtime·badctxt(SB)
+	JAL	runtime·abort(SB)
 	RET
 
 // func asmcgocall(fn, arg unsafe.Pointer) int32
@@ -445,7 +435,7 @@
 	MOVW	m_g0(R5), R6
 	BEQ	R6, g, g0
 
-	JAL	gosave<>(SB)
+	JAL	gosave_systemstack_switch<>(SB)
 	MOVW	R6, g
 	JAL	runtime·save_g(SB)
 	MOVW	(g_sched+gobuf_sp)(g), R29
@@ -812,6 +802,10 @@
 	MOVW	R1, x+0(FP)
 	MOVW	R2, y+4(FP)
 	JMP	runtime·goPanicSlice3CU(SB)
+TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-8
+	MOVW	R3, x+0(FP)
+	MOVW	R4, y+4(FP)
+	JMP	runtime·goPanicSliceConvert(SB)
 
 // Extended versions for 64-bit indexes.
 TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s
index dc34c0e..942cc14 100644
--- a/src/runtime/asm_ppc64x.s
+++ b/src/runtime/asm_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "go_asm.h"
@@ -16,7 +17,7 @@
 #define cgoCalleeStackSize 32
 #endif
 
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
 	// R1 = stack; R3 = argc; R4 = argv; R13 = C TLS base pointer
 
 	// initialize essential registers
@@ -124,35 +125,26 @@
 	XOR R0, R0
 	RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+	BL	runtime·mstart0(SB)
+	RET // not reached
+
 /*
  *  go-routine
  */
 
-// void gosave(Gobuf*)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB), NOSPLIT|NOFRAME, $0-8
-	MOVD	buf+0(FP), R3
-	MOVD	R1, gobuf_sp(R3)
-	MOVD	LR, R31
-	MOVD	R31, gobuf_pc(R3)
-	MOVD	g, gobuf_g(R3)
-	MOVD	R0, gobuf_lr(R3)
-	MOVD	R0, gobuf_ret(R3)
-	// Assert ctxt is zero. See func save.
-	MOVD	gobuf_ctxt(R3), R3
-	CMP	R0, R3
-	BEQ	2(PC)
-	BL	runtime·badctxt(SB)
-	RET
-
 // void gogo(Gobuf*)
 // restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB), NOSPLIT, $16-8
+TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
 	MOVD	buf+0(FP), R5
-	MOVD	gobuf_g(R5), g	// make sure g is not nil
+	MOVD	gobuf_g(R5), R6
+	MOVD	0(R6), R4	// make sure g != nil
+	BR	gogo<>(SB)
+
+TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
+	MOVD	R6, g
 	BL	runtime·save_g(SB)
 
-	MOVD	0(g), R4
 	MOVD	gobuf_sp(R5), R1
 	MOVD	gobuf_lr(R5), R31
 #ifndef GOOS_aix
@@ -180,7 +172,6 @@
 	MOVD	LR, R31
 	MOVD	R31, (g_sched+gobuf_pc)(g)
 	MOVD	R0, (g_sched+gobuf_lr)(g)
-	MOVD	g, (g_sched+gobuf_g)(g)
 
 	// Switch to m->g0 & its stack, call fn.
 	MOVD	g, R3
@@ -246,22 +237,12 @@
 switch:
 	// save our state in g->sched. Pretend to
 	// be systemstack_switch if the G stack is scanned.
-	MOVD	$runtime·systemstack_switch(SB), R6
-	ADD     $16, R6 // get past prologue (including r2-setting instructions when they're there)
-	MOVD	R6, (g_sched+gobuf_pc)(g)
-	MOVD	R1, (g_sched+gobuf_sp)(g)
-	MOVD	R0, (g_sched+gobuf_lr)(g)
-	MOVD	g, (g_sched+gobuf_g)(g)
+	BL	gosave_systemstack_switch<>(SB)
 
 	// switch to g0
 	MOVD	R5, g
 	BL	runtime·save_g(SB)
-	MOVD	(g_sched+gobuf_sp)(g), R3
-	// make it look like mstart called systemstack on g0, to stop traceback
-	SUB	$FIXED_FRAME, R3
-	MOVD	$runtime·mstart(SB), R4
-	MOVD	R4, 0(R3)
-	MOVD	R3, R1
+	MOVD	(g_sched+gobuf_sp)(g), R1
 
 	// call target function
 	MOVD	0(R11), R12	// code pointer
@@ -356,7 +337,7 @@
 	BR	runtime·morestack(SB)
 
 // reflectcall: call a function with the given argument list
-// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
+// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
 // we don't have variable-sized frames, so we use a small number
 // of constant-sized-frame functions to encode a few bits of size in the pc.
 // Caution: ugly multiline assembly macros in your future!
@@ -370,8 +351,8 @@
 	BR	(CTR)
 // Note: can't just "BR NAME(SB)" - bad inlining results.
 
-TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-32
-	MOVWZ argsize+24(FP), R3
+TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
+	MOVWZ	frameSize+32(FP), R3
 	DISPATCH(runtime·call16, 16)
 	DISPATCH(runtime·call32, 32)
 	DISPATCH(runtime·call64, 64)
@@ -404,11 +385,11 @@
 	BR	(CTR)
 
 #define CALLFN(NAME,MAXSIZE)			\
-TEXT NAME(SB), WRAPPER, $MAXSIZE-24;		\
+TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
 	NO_LOCAL_POINTERS;			\
 	/* copy arguments to stack */		\
-	MOVD	arg+16(FP), R3;			\
-	MOVWZ	argsize+24(FP), R4;			\
+	MOVD	stackArgs+16(FP), R3;			\
+	MOVWZ	stackArgsSize+24(FP), R4;			\
 	MOVD    R1, R5;				\
 	CMP	R4, $8;				\
 	BLT	tailsetup;			\
@@ -456,10 +437,10 @@
 	MOVD	24(R1), R2;			\
 #endif						\
 	/* copy return values back */		\
-	MOVD	argtype+0(FP), R7;		\
-	MOVD	arg+16(FP), R3;			\
-	MOVWZ	n+24(FP), R4;			\
-	MOVWZ	retoffset+28(FP), R6;		\
+	MOVD	stackArgsType+0(FP), R7;		\
+	MOVD	stackArgs+16(FP), R3;			\
+	MOVWZ	stackArgsSize+24(FP), R4;			\
+	MOVWZ	stackRetOffset+28(FP), R6;		\
 	ADD	$FIXED_FRAME, R1, R5;		\
 	ADD	R6, R5; 			\
 	ADD	R6, R3;				\
@@ -471,11 +452,12 @@
 // separate function so it can allocate stack space for the arguments
 // to reflectcallmove. It does not follow the Go ABI; it expects its
 // arguments in registers.
-TEXT callRet<>(SB), NOSPLIT, $32-0
+TEXT callRet<>(SB), NOSPLIT, $40-0
 	MOVD	R7, FIXED_FRAME+0(R1)
 	MOVD	R3, FIXED_FRAME+8(R1)
 	MOVD	R5, FIXED_FRAME+16(R1)
 	MOVD	R4, FIXED_FRAME+24(R1)
+	MOVD	$0, FIXED_FRAME+32(R1)
 	BL	runtime·reflectcallmove(SB)
 	RET
 
@@ -550,9 +532,14 @@
 	MOVD	R12, CTR
 	BR	(CTR)
 
-// Save state of caller into g->sched. Smashes R31.
-TEXT gosave<>(SB),NOSPLIT|NOFRAME,$0
-	MOVD	LR, R31
+// Save state of caller into g->sched,
+// but using fake PC from systemstack_switch.
+// Must only be called from functions with no locals ($0)
+// or else unwinding from systemstack_switch is incorrect.
+// Smashes R31.
+TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
+	MOVD	$runtime·systemstack_switch(SB), R31
+	ADD     $16, R31 // get past prologue (including r2-setting instructions when they're there)
 	MOVD	R31, (g_sched+gobuf_pc)(g)
 	MOVD	R1, (g_sched+gobuf_sp)(g)
 	MOVD	R0, (g_sched+gobuf_lr)(g)
@@ -561,7 +548,7 @@
 	MOVD	(g_sched+gobuf_ctxt)(g), R31
 	CMP	R0, R31
 	BEQ	2(PC)
-	BL	runtime·badctxt(SB)
+	BL	runtime·abort(SB)
 	RET
 
 #ifdef GOOS_aix
@@ -593,7 +580,7 @@
 	MOVD	m_g0(R8), R6
 	CMP	R6, g
 	BEQ	g0
-	BL	gosave<>(SB)
+	BL	gosave_systemstack_switch<>(SB)
 	MOVD	R6, g
 	BL	runtime·save_g(SB)
 	MOVD	(g_sched+gobuf_sp)(g), R1
@@ -1036,3 +1023,7 @@
 	MOVD	R3, x+0(FP)
 	MOVD	R4, y+8(FP)
 	JMP	runtime·goPanicSlice3CU(SB)
+TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16
+	MOVD	R5, x+0(FP)
+	MOVD	R6, y+8(FP)
+	JMP	runtime·goPanicSliceConvert(SB)
diff --git a/src/runtime/asm_riscv64.s b/src/runtime/asm_riscv64.s
index 01b42dc..ef7af4e 100644
--- a/src/runtime/asm_riscv64.s
+++ b/src/runtime/asm_riscv64.s
@@ -7,7 +7,7 @@
 #include "textflag.h"
 
 // func rt0_go()
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
 	// X2 = stack; A0 = argc; A1 = argv
 	ADD	$-24, X2
 	MOV	A0, 8(X2)	// argc
@@ -70,6 +70,10 @@
 	WORD $0 // crash if reached
 	RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+	CALL	runtime·mstart0(SB)
+	RET // not reached
+
 // void setg_gcc(G*); set g called from gcc with g in A0
 TEXT setg_gcc<>(SB),NOSPLIT,$0-0
 	MOV	A0, g
@@ -114,21 +118,12 @@
 switch:
 	// save our state in g->sched. Pretend to
 	// be systemstack_switch if the G stack is scanned.
-	MOV	$runtime·systemstack_switch(SB), T2
-	ADD	$8, T2	// get past prologue
-	MOV	T2, (g_sched+gobuf_pc)(g)
-	MOV	X2, (g_sched+gobuf_sp)(g)
-	MOV	ZERO, (g_sched+gobuf_lr)(g)
-	MOV	g, (g_sched+gobuf_g)(g)
+	CALL	gosave_systemstack_switch<>(SB)
 
 	// switch to g0
 	MOV	T1, g
 	CALL	runtime·save_g(SB)
 	MOV	(g_sched+gobuf_sp)(g), T0
-	// make it look like mstart called systemstack on g0, to stop traceback
-	ADD	$-8, T0
-	MOV	$runtime·mstart(SB), T1
-	MOV	T1, 0(T0)
 	MOV	T0, X2
 
 	// call target function
@@ -233,12 +228,16 @@
 // restore state from Gobuf; longjmp
 
 // func gogo(buf *gobuf)
-TEXT runtime·gogo(SB), NOSPLIT, $16-8
+TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
 	MOV	buf+0(FP), T0
-	MOV	gobuf_g(T0), g	// make sure g is not nil
+	MOV	gobuf_g(T0), T1
+	MOV	0(T1), ZERO // make sure g != nil
+	JMP	gogo<>(SB)
+
+TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
+	MOV	T1, g
 	CALL	runtime·save_g(SB)
 
-	MOV	(g), ZERO // make sure g is not nil
 	MOV	gobuf_sp(T0), X2
 	MOV	gobuf_lr(T0), RA
 	MOV	gobuf_ret(T0), A0
@@ -279,7 +278,6 @@
 	MOV	X2, (g_sched+gobuf_sp)(g)
 	MOV	RA, (g_sched+gobuf_pc)(g)
 	MOV	ZERO, (g_sched+gobuf_lr)(g)
-	MOV	g, (g_sched+gobuf_g)(g)
 
 	// Switch to m->g0 & its stack, call fn.
 	MOV	g, T0
@@ -297,31 +295,22 @@
 	JALR	RA, T1
 	JMP	runtime·badmcall2(SB)
 
-// func gosave(buf *gobuf)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB), NOSPLIT|NOFRAME, $0-8
-	MOV	buf+0(FP), T1
-	MOV	X2, gobuf_sp(T1)
-	MOV	RA, gobuf_pc(T1)
-	MOV	g, gobuf_g(T1)
-	MOV	ZERO, gobuf_lr(T1)
-	MOV	ZERO, gobuf_ret(T1)
-	// Assert ctxt is zero. See func save.
-	MOV	gobuf_ctxt(T1), T1
-	BEQ	T1, ZERO, 2(PC)
-	CALL	runtime·badctxt(SB)
-	RET
-
-// Save state of caller into g->sched. Smashes X31.
-TEXT gosave<>(SB),NOSPLIT|NOFRAME,$0
-	MOV	X1, (g_sched+gobuf_pc)(g)
+// Save state of caller into g->sched,
+// but using fake PC from systemstack_switch.
+// Must only be called from functions with no locals ($0)
+// or else unwinding from systemstack_switch is incorrect.
+// Smashes X31.
+TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
+	MOV	$runtime·systemstack_switch(SB), X31
+	ADD	$8, X31	// get past prologue
+	MOV	X31, (g_sched+gobuf_pc)(g)
 	MOV	X2, (g_sched+gobuf_sp)(g)
 	MOV	ZERO, (g_sched+gobuf_lr)(g)
 	MOV	ZERO, (g_sched+gobuf_ret)(g)
 	// Assert ctxt is zero. See func save.
 	MOV	(g_sched+gobuf_ctxt)(g), X31
 	BEQ	ZERO, X31, 2(PC)
-	CALL	runtime·badctxt(SB)
+	CALL	runtime·abort(SB)
 	RET
 
 // func asmcgocall(fn, arg unsafe.Pointer) int32
@@ -342,7 +331,7 @@
 	MOV	m_g0(X6), X7
 	BEQ	X7, g, g0
 
-	CALL	gosave<>(SB)
+	CALL	gosave_systemstack_switch<>(SB)
 	MOV	X7, g
 	CALL	runtime·save_g(SB)
 	MOV	(g_sched+gobuf_sp)(g), X2
@@ -374,7 +363,7 @@
 	RET
 
 // reflectcall: call a function with the given argument list
-// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
+// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
 // we don't have variable-sized frames, so we use a small number
 // of constant-sized-frame functions to encode a few bits of size in the pc.
 // Caution: ugly multiline assembly macros in your future!
@@ -386,13 +375,13 @@
 	JALR	ZERO, T2
 // Note: can't just "BR NAME(SB)" - bad inlining results.
 
-// func call(argtype *rtype, fn, arg unsafe.Pointer, n uint32, retoffset uint32)
+// func call(stackArgsType *rtype, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
 TEXT reflect·call(SB), NOSPLIT, $0-0
 	JMP	·reflectcall(SB)
 
-// func reflectcall(argtype *_type, fn, arg unsafe.Pointer, argsize uint32, retoffset uint32)
-TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-32
-	MOVWU argsize+24(FP), T0
+// func call(stackArgsType *_type, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
+TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
+	MOVWU	frameSize+32(FP), T0
 	DISPATCH(runtime·call16, 16)
 	DISPATCH(runtime·call32, 32)
 	DISPATCH(runtime·call64, 64)
@@ -424,11 +413,11 @@
 	JALR	ZERO, T2
 
 #define CALLFN(NAME,MAXSIZE)			\
-TEXT NAME(SB), WRAPPER, $MAXSIZE-24;		\
+TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
 	NO_LOCAL_POINTERS;			\
 	/* copy arguments to stack */		\
-	MOV	arg+16(FP), A1;			\
-	MOVWU	argsize+24(FP), A2;		\
+	MOV	stackArgs+16(FP), A1;			\
+	MOVWU	stackArgsSize+24(FP), A2;		\
 	MOV	X2, A3;				\
 	ADD	$8, A3;				\
 	ADD	A3, A2;				\
@@ -444,10 +433,10 @@
 	PCDATA  $PCDATA_StackMapIndex, $0;	\
 	JALR	RA, A4;				\
 	/* copy return values back */		\
-	MOV	argtype+0(FP), A5;		\
-	MOV	arg+16(FP), A1;			\
-	MOVWU	n+24(FP), A2;			\
-	MOVWU	retoffset+28(FP), A4;		\
+	MOV	stackArgsType+0(FP), A5;		\
+	MOV	stackArgs+16(FP), A1;			\
+	MOVWU	stackArgsSize+24(FP), A2;			\
+	MOVWU	stackRetOffset+28(FP), A4;		\
 	ADD	$8, X2, A3;			\
 	ADD	A4, A3; 			\
 	ADD	A4, A1;				\
@@ -459,11 +448,12 @@
 // separate function so it can allocate stack space for the arguments
 // to reflectcallmove. It does not follow the Go ABI; it expects its
 // arguments in registers.
-TEXT callRet<>(SB), NOSPLIT, $32-0
+TEXT callRet<>(SB), NOSPLIT, $40-0
 	MOV	A5, 8(X2)
 	MOV	A1, 16(X2)
 	MOV	A3, 24(X2)
 	MOV	A2, 32(X2)
+	MOV	ZERO, 40(X2)
 	CALL	runtime·reflectcallmove(SB)
 	RET
 
@@ -816,6 +806,10 @@
 	MOV	T0, x+0(FP)
 	MOV	T1, y+8(FP)
 	JMP	runtime·goPanicSlice3CU(SB)
+TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16
+	MOV	T2, x+0(FP)
+	MOV	T3, y+8(FP)
+	JMP	runtime·goPanicSliceConvert(SB)
 
 DATA	runtime·mainPC+0(SB)/8,$runtime·main(SB)
 GLOBL	runtime·mainPC(SB),RODATA,$8
diff --git a/src/runtime/asm_s390x.s b/src/runtime/asm_s390x.s
index 7baef37..fb38271 100644
--- a/src/runtime/asm_s390x.s
+++ b/src/runtime/asm_s390x.s
@@ -84,7 +84,7 @@
 DATA _rt0_s90x_lib_argv<>(SB)/8, $0
 GLOBL _rt0_s390x_lib_argv<>(SB), NOPTR, $8
 
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
 	// R2 = argc; R3 = argv; R11 = temp; R13 = g; R15 = stack pointer
 	// C TLS base pointer in AR0:AR1
 
@@ -170,30 +170,24 @@
 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
 	RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+	CALL	runtime·mstart0(SB)
+	RET // not reached
+
 /*
  *  go-routine
  */
 
-// void gosave(Gobuf*)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB), NOSPLIT, $-8-8
-	MOVD	buf+0(FP), R3
-	MOVD	R15, gobuf_sp(R3)
-	MOVD	LR, gobuf_pc(R3)
-	MOVD	g, gobuf_g(R3)
-	MOVD	$0, gobuf_lr(R3)
-	MOVD	$0, gobuf_ret(R3)
-	// Assert ctxt is zero. See func save.
-	MOVD	gobuf_ctxt(R3), R3
-	CMPBEQ	R3, $0, 2(PC)
-	BL	runtime·badctxt(SB)
-	RET
-
 // void gogo(Gobuf*)
 // restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB), NOSPLIT, $16-8
+TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
 	MOVD	buf+0(FP), R5
-	MOVD	gobuf_g(R5), g	// make sure g is not nil
+	MOVD	gobuf_g(R5), R6
+	MOVD	0(R6), R7	// make sure g != nil
+	BR	gogo<>(SB)
+
+TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
+	MOVD	R6, g
 	BL	runtime·save_g(SB)
 
 	MOVD	0(g), R4
@@ -218,7 +212,6 @@
 	MOVD	R15, (g_sched+gobuf_sp)(g)
 	MOVD	LR, (g_sched+gobuf_pc)(g)
 	MOVD	$0, (g_sched+gobuf_lr)(g)
-	MOVD	g, (g_sched+gobuf_g)(g)
 
 	// Switch to m->g0 & its stack, call fn.
 	MOVD	g, R3
@@ -271,22 +264,12 @@
 switch:
 	// save our state in g->sched.  Pretend to
 	// be systemstack_switch if the G stack is scanned.
-	MOVD	$runtime·systemstack_switch(SB), R6
-	ADD	$16, R6	// get past prologue
-	MOVD	R6, (g_sched+gobuf_pc)(g)
-	MOVD	R15, (g_sched+gobuf_sp)(g)
-	MOVD	$0, (g_sched+gobuf_lr)(g)
-	MOVD	g, (g_sched+gobuf_g)(g)
+	BL	gosave_systemstack_switch<>(SB)
 
 	// switch to g0
 	MOVD	R5, g
 	BL	runtime·save_g(SB)
-	MOVD	(g_sched+gobuf_sp)(g), R3
-	// make it look like mstart called systemstack on g0, to stop traceback
-	SUB	$8, R3
-	MOVD	$runtime·mstart(SB), R4
-	MOVD	R4, 0(R3)
-	MOVD	R3, R15
+	MOVD	(g_sched+gobuf_sp)(g), R15
 
 	// call target function
 	MOVD	0(R12), R3	// code pointer
@@ -368,7 +351,7 @@
 	BR	runtime·morestack(SB)
 
 // reflectcall: call a function with the given argument list
-// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
+// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
 // we don't have variable-sized frames, so we use a small number
 // of constant-sized-frame functions to encode a few bits of size in the pc.
 // Caution: ugly multiline assembly macros in your future!
@@ -381,8 +364,8 @@
 	BR	(R5)
 // Note: can't just "BR NAME(SB)" - bad inlining results.
 
-TEXT ·reflectcall(SB), NOSPLIT, $-8-32
-	MOVWZ argsize+24(FP), R3
+TEXT ·reflectcall(SB), NOSPLIT, $-8-48
+	MOVWZ	frameSize+32(FP), R3
 	DISPATCH(runtime·call16, 16)
 	DISPATCH(runtime·call32, 32)
 	DISPATCH(runtime·call64, 64)
@@ -414,11 +397,11 @@
 	BR	(R5)
 
 #define CALLFN(NAME,MAXSIZE)			\
-TEXT NAME(SB), WRAPPER, $MAXSIZE-24;		\
+TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
 	NO_LOCAL_POINTERS;			\
 	/* copy arguments to stack */		\
-	MOVD	arg+16(FP), R4;			\
-	MOVWZ	argsize+24(FP), R5;		\
+	MOVD	stackArgs+16(FP), R4;			\
+	MOVWZ	stackArgsSize+24(FP), R5;		\
 	MOVD	$stack-MAXSIZE(SP), R6;		\
 loopArgs: /* copy 256 bytes at a time */	\
 	CMP	R5, $256;			\
@@ -439,11 +422,11 @@
 	PCDATA  $PCDATA_StackMapIndex, $0;	\
 	BL	(R8);				\
 	/* copy return values back */		\
-	MOVD	argtype+0(FP), R7;		\
-	MOVD	arg+16(FP), R6;			\
-	MOVWZ	n+24(FP), R5;			\
+	MOVD	stackArgsType+0(FP), R7;		\
+	MOVD	stackArgs+16(FP), R6;			\
+	MOVWZ	stackArgsSize+24(FP), R5;			\
 	MOVD	$stack-MAXSIZE(SP), R4;		\
-	MOVWZ	retoffset+28(FP), R1;		\
+	MOVWZ	stackRetOffset+28(FP), R1;		\
 	ADD	R1, R4;				\
 	ADD	R1, R6;				\
 	SUB	R1, R5;				\
@@ -454,11 +437,12 @@
 // separate function so it can allocate stack space for the arguments
 // to reflectcallmove. It does not follow the Go ABI; it expects its
 // arguments in registers.
-TEXT callRet<>(SB), NOSPLIT, $32-0
+TEXT callRet<>(SB), NOSPLIT, $40-0
 	MOVD	R7, 8(R15)
 	MOVD	R6, 16(R15)
 	MOVD	R4, 24(R15)
 	MOVD	R5, 32(R15)
+	MOVD	$0, 40(R15)
 	BL	runtime·reflectcallmove(SB)
 	RET
 
@@ -512,16 +496,22 @@
 	MOVD	0(R12), R3
 	BR	(R3)
 
-// Save state of caller into g->sched. Smashes R1.
-TEXT gosave<>(SB),NOSPLIT|NOFRAME,$0
-	MOVD	LR, (g_sched+gobuf_pc)(g)
+// Save state of caller into g->sched,
+// but using fake PC from systemstack_switch.
+// Must only be called from functions with no locals ($0)
+// or else unwinding from systemstack_switch is incorrect.
+// Smashes R1.
+TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
+	MOVD	$runtime·systemstack_switch(SB), R1
+	ADD	$16, R1	// get past prologue
+	MOVD	R1, (g_sched+gobuf_pc)(g)
 	MOVD	R15, (g_sched+gobuf_sp)(g)
 	MOVD	$0, (g_sched+gobuf_lr)(g)
 	MOVD	$0, (g_sched+gobuf_ret)(g)
 	// Assert ctxt is zero. See func save.
 	MOVD	(g_sched+gobuf_ctxt)(g), R1
 	CMPBEQ	R1, $0, 2(PC)
-	BL	runtime·badctxt(SB)
+	BL	runtime·abort(SB)
 	RET
 
 // func asmcgocall(fn, arg unsafe.Pointer) int32
@@ -543,7 +533,7 @@
 	MOVD	g_m(g), R6
 	MOVD	m_g0(R6), R6
 	CMPBEQ	R6, g, g0
-	BL	gosave<>(SB)
+	BL	gosave_systemstack_switch<>(SB)
 	MOVD	R6, g
 	BL	runtime·save_g(SB)
 	MOVD	(g_sched+gobuf_sp)(g), R15
@@ -916,3 +906,7 @@
 	MOVD	R0, x+0(FP)
 	MOVD	R1, y+8(FP)
 	JMP	runtime·goPanicSlice3CU(SB)
+TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16
+	MOVD	R2, x+0(FP)
+	MOVD	R3, y+8(FP)
+	JMP	runtime·goPanicSliceConvert(SB)
diff --git a/src/runtime/asm_wasm.s b/src/runtime/asm_wasm.s
index fcb780f..33c335b 100644
--- a/src/runtime/asm_wasm.s
+++ b/src/runtime/asm_wasm.s
@@ -7,7 +7,7 @@
 #include "funcdata.h"
 #include "textflag.h"
 
-TEXT runtime·rt0_go(SB), NOSPLIT|NOFRAME, $0
+TEXT runtime·rt0_go(SB), NOSPLIT|NOFRAME|TOPFRAME, $0
 	// save m->g0 = g0
 	MOVD $runtime·g0(SB), runtime·m0+m_g0(SB)
 	// save m0 to g0->m
@@ -24,6 +24,10 @@
 	CALL runtime·mstart(SB) // WebAssembly stack will unwind when switching to another goroutine
 	UNDEF
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+	CALL	runtime·mstart0(SB)
+	RET // not reached
+
 DATA  runtime·mainPC+0(SB)/8,$runtime·main(SB)
 GLOBL runtime·mainPC(SB),RODATA,$8
 
@@ -34,7 +38,9 @@
 
 TEXT runtime·gogo(SB), NOSPLIT, $0-8
 	MOVD buf+0(FP), R0
-	MOVD gobuf_g(R0), g
+	MOVD gobuf_g(R0), R1
+	MOVD 0(R1), R2	// make sure g != nil
+	MOVD R1, g
 	MOVD gobuf_sp(R0), SP
 
 	// Put target PC at -8(SP), wasm_pc_f_loop will pick it up
@@ -69,7 +75,6 @@
 	// save state in g->sched
 	MOVD 0(SP), g_sched+gobuf_pc(g)     // caller's PC
 	MOVD $fn+0(FP), g_sched+gobuf_sp(g) // caller's SP
-	MOVD g, g_sched+gobuf_g(g)
 
 	// if g == g0 call badmcall
 	Get g
@@ -143,7 +148,6 @@
 	MOVD $runtime·systemstack_switch(SB), g_sched+gobuf_pc(g)
 
 	MOVD SP, g_sched+gobuf_sp(g)
-	MOVD g, g_sched+gobuf_g(g)
 
 	// switch to g0
 	MOVD R2, g
@@ -270,7 +274,6 @@
 
 	// Set g->sched to context in f.
 	MOVD 0(SP), g_sched+gobuf_pc(g)
-	MOVD g, g_sched+gobuf_g(g)
 	MOVD $8(SP), g_sched+gobuf_sp(g) // f's SP
 	MOVD CTXT, g_sched+gobuf_ctxt(g)
 
@@ -296,14 +299,14 @@
 		JMP NAME(SB); \
 	End
 
-TEXT ·reflectcall(SB), NOSPLIT, $0-32
+TEXT ·reflectcall(SB), NOSPLIT, $0-48
 	I64Load fn+8(FP)
 	I64Eqz
 	If
 		CALLNORESUME runtime·sigpanic<ABIInternal>(SB)
 	End
 
-	MOVW argsize+24(FP), R0
+	MOVW frameSize+32(FP), R0
 
 	DISPATCH(runtime·call16, 16)
 	DISPATCH(runtime·call32, 32)
@@ -335,18 +338,18 @@
 	JMP runtime·badreflectcall(SB)
 
 #define CALLFN(NAME, MAXSIZE) \
-TEXT NAME(SB), WRAPPER, $MAXSIZE-32; \
+TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \
 	NO_LOCAL_POINTERS; \
-	MOVW argsize+24(FP), R0; \
+	MOVW stackArgsSize+24(FP), R0; \
 	\
 	Get R0; \
 	I64Eqz; \
 	Not; \
 	If; \
 		Get SP; \
-		I64Load argptr+16(FP); \
+		I64Load stackArgs+16(FP); \
 		I32WrapI64; \
-		I64Load argsize+24(FP); \
+		I64Load stackArgsSize+24(FP); \
 		I64Const $3; \
 		I64ShrU; \
 		I32WrapI64; \
@@ -359,12 +362,12 @@
 	I64Load $0; \
 	CALL; \
 	\
-	I64Load32U retoffset+28(FP); \
+	I64Load32U stackRetOffset+28(FP); \
 	Set R0; \
 	\
-	MOVD argtype+0(FP), RET0; \
+	MOVD stackArgsType+0(FP), RET0; \
 	\
-	I64Load argptr+16(FP); \
+	I64Load stackArgs+16(FP); \
 	Get R0; \
 	I64Add; \
 	Set RET1; \
@@ -375,7 +378,7 @@
 	I64Add; \
 	Set RET2; \
 	\
-	I64Load32U argsize+24(FP); \
+	I64Load32U stackArgsSize+24(FP); \
 	Get R0; \
 	I64Sub; \
 	Set RET3; \
@@ -387,12 +390,13 @@
 // separate function so it can allocate stack space for the arguments
 // to reflectcallmove. It does not follow the Go ABI; it expects its
 // arguments in registers.
-TEXT callRet<>(SB), NOSPLIT, $32-0
+TEXT callRet<>(SB), NOSPLIT, $40-0
 	NO_LOCAL_POINTERS
 	MOVD RET0, 0(SP)
 	MOVD RET1, 8(SP)
 	MOVD RET2, 16(SP)
 	MOVD RET3, 24(SP)
+	MOVD $0,   32(SP)
 	CALL runtime·reflectcallmove(SB)
 	RET
 
@@ -424,7 +428,7 @@
 CALLFN(·call536870912, 536870912)
 CALLFN(·call1073741824, 1073741824)
 
-TEXT runtime·goexit(SB), NOSPLIT, $0-0
+TEXT runtime·goexit(SB), NOSPLIT|TOPFRAME, $0-0
 	NOP // first PC of goexit is skipped
 	CALL runtime·goexit1(SB) // does not return
 	UNDEF
diff --git a/src/runtime/atomic_mips64x.s b/src/runtime/atomic_mips64x.s
index 6f42412..e2118e6 100644
--- a/src/runtime/atomic_mips64x.s
+++ b/src/runtime/atomic_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "textflag.h"
diff --git a/src/runtime/atomic_mipsx.s b/src/runtime/atomic_mipsx.s
index ed078a2..1eacd27 100644
--- a/src/runtime/atomic_mipsx.s
+++ b/src/runtime/atomic_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "textflag.h"
diff --git a/src/runtime/atomic_ppc64x.s b/src/runtime/atomic_ppc64x.s
index 57f672f..b63de2d 100644
--- a/src/runtime/atomic_ppc64x.s
+++ b/src/runtime/atomic_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "textflag.h"
diff --git a/src/runtime/auxv_none.go b/src/runtime/auxv_none.go
index 3ca617b..3178f1a 100644
--- a/src/runtime/auxv_none.go
+++ b/src/runtime/auxv_none.go
@@ -2,12 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !linux
-// +build !darwin
-// +build !dragonfly
-// +build !freebsd
-// +build !netbsd
-// +build !solaris
+//go:build !linux && !darwin && !dragonfly && !freebsd && !netbsd && !solaris
+// +build !linux,!darwin,!dragonfly,!freebsd,!netbsd,!solaris
 
 package runtime
 
diff --git a/src/runtime/cgo/abi_amd64.h b/src/runtime/cgo/abi_amd64.h
new file mode 100644
index 0000000..9949435
--- /dev/null
+++ b/src/runtime/cgo/abi_amd64.h
@@ -0,0 +1,99 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Macros for transitioning from the host ABI to Go ABI0.
+//
+// These save the frame pointer, so in general, functions that use
+// these should have zero frame size to suppress the automatic frame
+// pointer, though it's harmless to not do this.
+
+#ifdef GOOS_windows
+
+// REGS_HOST_TO_ABI0_STACK is the stack bytes used by
+// PUSH_REGS_HOST_TO_ABI0.
+#define REGS_HOST_TO_ABI0_STACK (28*8 + 8)
+
+// PUSH_REGS_HOST_TO_ABI0 prepares for transitioning from
+// the host ABI to Go ABI0 code. It saves all registers that are
+// callee-save in the host ABI and caller-save in Go ABI0 and prepares
+// for entry to Go.
+//
+// Save DI SI BP BX R12 R13 R14 R15 X6-X15 registers and the DF flag.
+// Clear the DF flag for the Go ABI.
+// MXCSR matches the Go ABI, so we don't have to set that,
+// and Go doesn't modify it, so we don't have to save it.
+#define PUSH_REGS_HOST_TO_ABI0()	\
+	PUSHFQ			\
+	CLD			\
+	ADJSP	$(REGS_HOST_TO_ABI0_STACK - 8)	\
+	MOVQ	DI, (0*0)(SP)	\
+	MOVQ	SI, (1*8)(SP)	\
+	MOVQ	BP, (2*8)(SP)	\
+	MOVQ	BX, (3*8)(SP)	\
+	MOVQ	R12, (4*8)(SP)	\
+	MOVQ	R13, (5*8)(SP)	\
+	MOVQ	R14, (6*8)(SP)	\
+	MOVQ	R15, (7*8)(SP)	\
+	MOVUPS	X6, (8*8)(SP)	\
+	MOVUPS	X7, (10*8)(SP)	\
+	MOVUPS	X8, (12*8)(SP)	\
+	MOVUPS	X9, (14*8)(SP)	\
+	MOVUPS	X10, (16*8)(SP)	\
+	MOVUPS	X11, (18*8)(SP)	\
+	MOVUPS	X12, (20*8)(SP)	\
+	MOVUPS	X13, (22*8)(SP)	\
+	MOVUPS	X14, (24*8)(SP)	\
+	MOVUPS	X15, (26*8)(SP)
+
+#define POP_REGS_HOST_TO_ABI0()	\
+	MOVQ	(0*0)(SP), DI	\
+	MOVQ	(1*8)(SP), SI	\
+	MOVQ	(2*8)(SP), BP	\
+	MOVQ	(3*8)(SP), BX	\
+	MOVQ	(4*8)(SP), R12	\
+	MOVQ	(5*8)(SP), R13	\
+	MOVQ	(6*8)(SP), R14	\
+	MOVQ	(7*8)(SP), R15	\
+	MOVUPS	(8*8)(SP), X6	\
+	MOVUPS	(10*8)(SP), X7	\
+	MOVUPS	(12*8)(SP), X8	\
+	MOVUPS	(14*8)(SP), X9	\
+	MOVUPS	(16*8)(SP), X10	\
+	MOVUPS	(18*8)(SP), X11	\
+	MOVUPS	(20*8)(SP), X12	\
+	MOVUPS	(22*8)(SP), X13	\
+	MOVUPS	(24*8)(SP), X14	\
+	MOVUPS	(26*8)(SP), X15	\
+	ADJSP	$-(REGS_HOST_TO_ABI0_STACK - 8)	\
+	POPFQ
+
+#else
+// SysV ABI
+
+#define REGS_HOST_TO_ABI0_STACK (6*8)
+
+// SysV MXCSR matches the Go ABI, so we don't have to set that,
+// and Go doesn't modify it, so we don't have to save it.
+// Both SysV and Go require DF to be cleared, so that's already clear.
+// The SysV and Go frame pointer conventions are compatible.
+#define PUSH_REGS_HOST_TO_ABI0()	\
+	ADJSP	$(REGS_HOST_TO_ABI0_STACK)	\
+	MOVQ	BP, (5*8)(SP)	\
+	LEAQ	(5*8)(SP), BP	\
+	MOVQ	BX, (0*8)(SP)	\
+	MOVQ	R12, (1*8)(SP)	\
+	MOVQ	R13, (2*8)(SP)	\
+	MOVQ	R14, (3*8)(SP)	\
+	MOVQ	R15, (4*8)(SP)
+
+#define POP_REGS_HOST_TO_ABI0()	\
+	MOVQ	(0*8)(SP), BX	\
+	MOVQ	(1*8)(SP), R12	\
+	MOVQ	(2*8)(SP), R13	\
+	MOVQ	(3*8)(SP), R14	\
+	MOVQ	(4*8)(SP), R15	\
+	MOVQ	(5*8)(SP), BP	\
+	ADJSP	$-(REGS_HOST_TO_ABI0_STACK)
+
+#endif
diff --git a/src/runtime/cgo/asm_amd64.s b/src/runtime/cgo/asm_amd64.s
index 5dc8e2d..386299c 100644
--- a/src/runtime/cgo/asm_amd64.s
+++ b/src/runtime/cgo/asm_amd64.s
@@ -3,70 +3,32 @@
 // license that can be found in the LICENSE file.
 
 #include "textflag.h"
+#include "abi_amd64.h"
 
 // Called by C code generated by cmd/cgo.
 // func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
 // Saves C callee-saved registers and calls cgocallback with three arguments.
 // fn is the PC of a func(a unsafe.Pointer) function.
 // This signature is known to SWIG, so we can't change it.
+TEXT crosscall2(SB),NOSPLIT,$0-0
+	PUSH_REGS_HOST_TO_ABI0()
+
+	// Make room for arguments to cgocallback.
+	ADJSP	$0x18
 #ifndef GOOS_windows
-TEXT crosscall2(SB),NOSPLIT,$0x50-0 /* keeps stack pointer 32-byte aligned */
-#else
-TEXT crosscall2(SB),NOSPLIT,$0x110-0 /* also need to save xmm6 - xmm15 */
-#endif
-	MOVQ	BX, 0x18(SP)
-	MOVQ	R12, 0x28(SP)
-	MOVQ	R13, 0x30(SP)
-	MOVQ	R14, 0x38(SP)
-	MOVQ	R15, 0x40(SP)
-
-#ifdef GOOS_windows
-	// Win64 save RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15 and XMM6 -- XMM15.
-	MOVQ	DI, 0x48(SP)
-	MOVQ	SI, 0x50(SP)
-	MOVUPS	X6, 0x60(SP)
-	MOVUPS	X7, 0x70(SP)
-	MOVUPS	X8, 0x80(SP)
-	MOVUPS	X9, 0x90(SP)
-	MOVUPS	X10, 0xa0(SP)
-	MOVUPS	X11, 0xb0(SP)
-	MOVUPS	X12, 0xc0(SP)
-	MOVUPS	X13, 0xd0(SP)
-	MOVUPS	X14, 0xe0(SP)
-	MOVUPS	X15, 0xf0(SP)
-
-	MOVQ	CX, 0x0(SP)	/* fn */
-	MOVQ	DX, 0x8(SP)	/* arg */
-	// Skip n in R8.
-	MOVQ	R9, 0x10(SP)	/* ctxt */
-
-	CALL	runtime·cgocallback(SB)
-
-	MOVQ	0x48(SP), DI
-	MOVQ	0x50(SP), SI
-	MOVUPS	0x60(SP), X6
-	MOVUPS	0x70(SP), X7
-	MOVUPS	0x80(SP), X8
-	MOVUPS	0x90(SP), X9
-	MOVUPS	0xa0(SP), X10
-	MOVUPS	0xb0(SP), X11
-	MOVUPS	0xc0(SP), X12
-	MOVUPS	0xd0(SP), X13
-	MOVUPS	0xe0(SP), X14
-	MOVUPS	0xf0(SP), X15
-#else
 	MOVQ	DI, 0x0(SP)	/* fn */
 	MOVQ	SI, 0x8(SP)	/* arg */
 	// Skip n in DX.
 	MOVQ	CX, 0x10(SP)	/* ctxt */
-
-	CALL	runtime·cgocallback(SB)
+#else
+	MOVQ	CX, 0x0(SP)	/* fn */
+	MOVQ	DX, 0x8(SP)	/* arg */
+	// Skip n in R8.
+	MOVQ	R9, 0x10(SP)	/* ctxt */
 #endif
 
-	MOVQ	0x18(SP), BX
-	MOVQ	0x28(SP), R12
-	MOVQ	0x30(SP), R13
-	MOVQ	0x38(SP), R14
-	MOVQ	0x40(SP), R15
+	CALL	runtime·cgocallback(SB)
 
+	ADJSP	$-0x18
+	POP_REGS_HOST_TO_ABI0()
 	RET
diff --git a/src/runtime/cgo/asm_mips64x.s b/src/runtime/cgo/asm_mips64x.s
index e51cdf3..ba94807 100644
--- a/src/runtime/cgo/asm_mips64x.s
+++ b/src/runtime/cgo/asm_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "textflag.h"
diff --git a/src/runtime/cgo/asm_mipsx.s b/src/runtime/cgo/asm_mipsx.s
index 1127c8b..fd5d78e 100644
--- a/src/runtime/cgo/asm_mipsx.s
+++ b/src/runtime/cgo/asm_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "textflag.h"
diff --git a/src/runtime/cgo/asm_ppc64x.s b/src/runtime/cgo/asm_ppc64x.s
index f4efc1e..187b2d4 100644
--- a/src/runtime/cgo/asm_ppc64x.s
+++ b/src/runtime/cgo/asm_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "textflag.h"
@@ -11,17 +12,20 @@
 // func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
 // Saves C callee-saved registers and calls cgocallback with three arguments.
 // fn is the PC of a func(a unsafe.Pointer) function.
+// The value of R2 is saved on the new stack frame, and not
+// the caller's frame due to issue #43228.
 TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
 	// Start with standard C stack frame layout and linkage
 	MOVD	LR, R0
 	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
+	MOVW	R0, 8(R1)
 
 	BL	saveregs2<>(SB)
 
 	MOVDU	R1, (-288-3*8-FIXED_FRAME)(R1)
+	// Save the caller's R2
+	MOVD	R2, 24(R1)
 
 	// Initialize Go ABI environment
 	BL	runtime·reginit(SB)
@@ -40,12 +44,13 @@
 	MOVD	R6, FIXED_FRAME+16(R1)	// ctxt uintptr
 	BL	runtime·cgocallback(SB)
 
+	// Restore the caller's R2
+	MOVD	24(R1), R2
 	ADD	$(288+3*8+FIXED_FRAME), R1
 
 	BL	restoreregs2<>(SB)
 
-	MOVD	24(R1), R2
-	MOVD	8(R1), R0
+	MOVW	8(R1), R0
 	MOVFL	R0, $0xff
 	MOVD	16(R1), R0
 	MOVD	R0, LR
diff --git a/src/runtime/cgo/asm_riscv64.s b/src/runtime/cgo/asm_riscv64.s
index b4ddbb0..fcd1d36 100644
--- a/src/runtime/cgo/asm_riscv64.s
+++ b/src/runtime/cgo/asm_riscv64.s
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build riscv64
-
 #include "textflag.h"
 
 // Called by C code generated by cmd/cgo.
diff --git a/src/runtime/cgo/callbacks_traceback.go b/src/runtime/cgo/callbacks_traceback.go
index cdadf9e..7302c1e 100644
--- a/src/runtime/cgo/callbacks_traceback.go
+++ b/src/runtime/cgo/callbacks_traceback.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || linux
 // +build darwin linux
 
 package cgo
diff --git a/src/runtime/cgo/dragonfly.go b/src/runtime/cgo/dragonfly.go
index d6d6918..cfa6fe8 100644
--- a/src/runtime/cgo/dragonfly.go
+++ b/src/runtime/cgo/dragonfly.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly
 // +build dragonfly
 
 package cgo
diff --git a/src/runtime/cgo/freebsd.go b/src/runtime/cgo/freebsd.go
index 5c9ddbd..d56702e 100644
--- a/src/runtime/cgo/freebsd.go
+++ b/src/runtime/cgo/freebsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build freebsd
 // +build freebsd
 
 package cgo
diff --git a/src/runtime/cgo/gcc_amd64.S b/src/runtime/cgo/gcc_amd64.S
index 17d9d47..d75f864 100644
--- a/src/runtime/cgo/gcc_amd64.S
+++ b/src/runtime/cgo/gcc_amd64.S
@@ -30,9 +30,14 @@
 	pushq %r15
 
 #if defined(_WIN64)
+	movq %r8, %rdi	/* arg of setg_gcc */
+	call *%rdx	/* setg_gcc */
 	call *%rcx	/* fn */
 #else
-	call *%rdi	/* fn */
+	movq %rdi, %rbx
+	movq %rdx, %rdi	/* arg of setg_gcc */
+	call *%rsi	/* setg_gcc */
+	call *%rbx	/* fn */
 #endif
 
 	popq %r15
diff --git a/src/runtime/cgo/gcc_darwin_amd64.c b/src/runtime/cgo/gcc_darwin_amd64.c
index 51410d5..d5b7fd8 100644
--- a/src/runtime/cgo/gcc_darwin_amd64.c
+++ b/src/runtime/cgo/gcc_darwin_amd64.c
@@ -9,13 +9,16 @@
 #include "libcgo_unix.h"
 
 static void* threadentry(void*);
+static void (*setg_gcc)(void*);
 
 void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
 	pthread_attr_t attr;
 	size_t size;
 
+	setg_gcc = setg;
+
 	pthread_attr_init(&attr);
 	pthread_attr_getstacksize(&attr, &size);
 	g->stacklo = (uintptr)&attr - size + 4096;
@@ -57,10 +60,6 @@
 	ts = *(ThreadStart*)v;
 	free(v);
 
-	// Move the g pointer into the slot reserved in thread local storage.
-	// Constant must match the one in cmd/link/internal/ld/sym.go.
-	asm volatile("movq %0, %%gs:0x30" :: "r"(ts.g));
-
-	crosscall_amd64(ts.fn);
+	crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
 	return nil;
 }
diff --git a/src/runtime/cgo/gcc_dragonfly_amd64.c b/src/runtime/cgo/gcc_dragonfly_amd64.c
index d25db91..0003414 100644
--- a/src/runtime/cgo/gcc_dragonfly_amd64.c
+++ b/src/runtime/cgo/gcc_dragonfly_amd64.c
@@ -61,11 +61,6 @@
 	ts = *(ThreadStart*)v;
 	free(v);
 
-	/*
-	 * Set specific keys.
-	 */
-	setg_gcc((void*)ts.g);
-
-	crosscall_amd64(ts.fn);
+	crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
 	return nil;
 }
diff --git a/src/runtime/cgo/gcc_freebsd_amd64.c b/src/runtime/cgo/gcc_freebsd_amd64.c
index 514a2f8..6071ec3 100644
--- a/src/runtime/cgo/gcc_freebsd_amd64.c
+++ b/src/runtime/cgo/gcc_freebsd_amd64.c
@@ -69,11 +69,6 @@
 	free(v);
 	_cgo_tsan_release();
 
-	/*
-	 * Set specific keys.
-	 */
-	setg_gcc((void*)ts.g);
-
-	crosscall_amd64(ts.fn);
+	crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
 	return nil;
 }
diff --git a/src/runtime/cgo/gcc_libinit_windows.c b/src/runtime/cgo/gcc_libinit_windows.c
index 2732248..ad50386 100644
--- a/src/runtime/cgo/gcc_libinit_windows.c
+++ b/src/runtime/cgo/gcc_libinit_windows.c
@@ -4,7 +4,7 @@
 
 // +build cgo
 
-#define WIN64_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <process.h>
 
diff --git a/src/runtime/cgo/gcc_linux_amd64.c b/src/runtime/cgo/gcc_linux_amd64.c
index f2bf648..c25e7e7 100644
--- a/src/runtime/cgo/gcc_linux_amd64.c
+++ b/src/runtime/cgo/gcc_linux_amd64.c
@@ -89,11 +89,6 @@
 	free(v);
 	_cgo_tsan_release();
 
-	/*
-	 * Set specific keys.
-	 */
-	setg_gcc((void*)ts.g);
-
-	crosscall_amd64(ts.fn);
+	crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
 	return nil;
 }
diff --git a/src/runtime/cgo/gcc_mmap.c b/src/runtime/cgo/gcc_mmap.c
index e6a621d..698a7e3 100644
--- a/src/runtime/cgo/gcc_mmap.c
+++ b/src/runtime/cgo/gcc_mmap.c
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux,amd64 linux,arm64
+// +build linux,amd64 linux,arm64 linux,ppc64le
 
 #include <errno.h>
 #include <stdint.h>
diff --git a/src/runtime/cgo/gcc_netbsd_amd64.c b/src/runtime/cgo/gcc_netbsd_amd64.c
index dc966fc..9f4b031 100644
--- a/src/runtime/cgo/gcc_netbsd_amd64.c
+++ b/src/runtime/cgo/gcc_netbsd_amd64.c
@@ -62,11 +62,6 @@
 	ts = *(ThreadStart*)v;
 	free(v);
 
-	/*
-	 * Set specific keys.
-	 */
-	setg_gcc((void*)ts.g);
-
 	// On NetBSD, a new thread inherits the signal stack of the
 	// creating thread. That confuses minit, so we remove that
 	// signal stack here before calling the regular mstart. It's
@@ -78,6 +73,6 @@
 	ss.ss_flags = SS_DISABLE;
 	sigaltstack(&ss, nil);
 
-	crosscall_amd64(ts.fn);
+	crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
 	return nil;
 }
diff --git a/src/runtime/cgo/gcc_openbsd_amd64.c b/src/runtime/cgo/gcc_openbsd_amd64.c
index 34319fb..09d2750 100644
--- a/src/runtime/cgo/gcc_openbsd_amd64.c
+++ b/src/runtime/cgo/gcc_openbsd_amd64.c
@@ -60,11 +60,6 @@
 	ts = *(ThreadStart*)v;
 	free(v);
 
-	/*
-	 * Set specific keys.
-	 */
-	setg_gcc((void*)ts.g);
-
-	crosscall_amd64(ts.fn);
+	crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
 	return nil;
 }
diff --git a/src/runtime/cgo/gcc_openbsd_mips64.c b/src/runtime/cgo/gcc_openbsd_mips64.c
new file mode 100644
index 0000000..79f039a
--- /dev/null
+++ b/src/runtime/cgo/gcc_openbsd_mips64.c
@@ -0,0 +1,67 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+#include "libcgo_unix.h"
+
+static void* threadentry(void*);
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+}
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	sigfillset(&ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+
+	// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
+	ts->g->stackhi = size;
+	err = _cgo_try_pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+extern void crosscall1(void (*fn)(void), void (*setg_gcc)(void*), void *g);
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	crosscall1(ts.fn, setg_gcc, (void*)ts.g);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_sigaction.c b/src/runtime/cgo/gcc_sigaction.c
index e510e35..dd28315 100644
--- a/src/runtime/cgo/gcc_sigaction.c
+++ b/src/runtime/cgo/gcc_sigaction.c
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux,amd64 linux,arm64
+// +build linux,amd64 linux,arm64 linux,ppc64le
 
 #include <errno.h>
 #include <stddef.h>
@@ -23,7 +23,7 @@
 } go_sigaction_t;
 
 // SA_RESTORER is part of the kernel interface.
-// This is GNU/Linux i386/amd64 specific.
+// This is Linux i386/amd64 specific.
 #ifndef SA_RESTORER
 #define SA_RESTORER 0x4000000
 #endif
diff --git a/src/runtime/cgo/gcc_solaris_amd64.c b/src/runtime/cgo/gcc_solaris_amd64.c
index 079bd12..e89e844 100644
--- a/src/runtime/cgo/gcc_solaris_amd64.c
+++ b/src/runtime/cgo/gcc_solaris_amd64.c
@@ -72,11 +72,6 @@
 	ts = *(ThreadStart*)v;
 	free(v);
 
-	/*
-	 * Set specific keys.
-	 */
-	setg_gcc((void*)ts.g);
-
-	crosscall_amd64(ts.fn);
+	crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
 	return nil;
 }
diff --git a/src/runtime/cgo/gcc_traceback.c b/src/runtime/cgo/gcc_traceback.c
index d86331c..6e9470c 100644
--- a/src/runtime/cgo/gcc_traceback.c
+++ b/src/runtime/cgo/gcc_traceback.c
@@ -7,6 +7,14 @@
 #include <stdint.h>
 #include "libcgo.h"
 
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+#if __has_feature(memory_sanitizer)
+#include <sanitizer/msan_interface.h>
+#endif
+
 // Call the user's traceback function and then call sigtramp.
 // The runtime signal handler will jump to this code.
 // We do it this way so that the user's traceback function will be called
@@ -19,6 +27,18 @@
 	arg.SigContext = (uintptr_t)(context);
 	arg.Buf = cgoCallers;
 	arg.Max = 32; // must match len(runtime.cgoCallers)
+
+#if __has_feature(memory_sanitizer)
+        // This function is called directly from the signal handler.
+        // The arguments are passed in registers, so whether msan
+        // considers cgoCallers to be initialized depends on whether
+        // it considers the appropriate register to be initialized.
+        // That can cause false reports in rare cases.
+        // Explicitly unpoison the memory to avoid that.
+        // See issue #47543 for more details.
+        __msan_unpoison(&arg, sizeof arg);
+#endif
+
 	(*cgoTraceback)(&arg);
 	sigtramp(sig, info, context);
 }
diff --git a/src/runtime/cgo/gcc_windows_amd64.c b/src/runtime/cgo/gcc_windows_amd64.c
index 0f8c817..9df9b9b 100644
--- a/src/runtime/cgo/gcc_windows_amd64.c
+++ b/src/runtime/cgo/gcc_windows_amd64.c
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-#define WIN64_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <process.h>
 #include <stdlib.h>
@@ -12,10 +12,12 @@
 #include "libcgo_windows.h"
 
 static void threadentry(void*);
+static void (*setg_gcc)(void*);
 
 void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
+	setg_gcc = setg;
 }
 
 
@@ -46,10 +48,8 @@
 	 */
 	asm volatile (
 	  "movq %0, %%gs:0x28\n"	// MOVL tls0, 0x28(GS)
-	  "movq %%gs:0x28, %%rax\n" // MOVQ 0x28(GS), tmp
-	  "movq %1, 0(%%rax)\n" // MOVQ g, 0(GS)
-	  :: "r"(ts.tls), "r"(ts.g) : "%rax"
+	  :: "r"(ts.tls)
 	);
 
-	crosscall_amd64(ts.fn);
+	crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
 }
diff --git a/src/runtime/cgo/gcc_windows_arm64.c b/src/runtime/cgo/gcc_windows_arm64.c
new file mode 100644
index 0000000..61ef094
--- /dev/null
+++ b/src/runtime/cgo/gcc_windows_arm64.c
@@ -0,0 +1,46 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <process.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include "libcgo.h"
+#include "libcgo_windows.h"
+
+static void threadentry(void*);
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	setg_gcc = setg;
+}
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	uintptr_t thandle;
+
+	thandle = _beginthread(threadentry, 0, ts);
+	if(thandle == -1) {
+		fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
+		abort();
+	}
+}
+
+extern void crosscall1(void (*fn)(void), void (*setg_gcc)(void*), void *g);
+
+static void
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	crosscall1(ts.fn, setg_gcc, (void *)ts.g);
+}
diff --git a/src/runtime/cgo/handle.go b/src/runtime/cgo/handle.go
new file mode 100644
index 0000000..720acca
--- /dev/null
+++ b/src/runtime/cgo/handle.go
@@ -0,0 +1,109 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cgo
+
+import (
+	"sync"
+	"sync/atomic"
+)
+
+// Handle provides a way to pass values that contain Go pointers
+// (pointers to memory allocated by Go) between Go and C without
+// breaking the cgo pointer passing rules. A Handle is an integer
+// value that can represent any Go value. A Handle can be passed
+// through C and back to Go, and Go code can use the Handle to
+// retrieve the original Go value.
+//
+// The underlying type of Handle is guaranteed to fit in an integer type
+// that is large enough to hold the bit pattern of any pointer. The zero
+// value of a Handle is not valid, and thus is safe to use as a sentinel
+// in C APIs.
+//
+// For instance, on the Go side:
+//
+//	package main
+//
+//	/*
+//	#include <stdint.h> // for uintptr_t
+//
+//	extern void MyGoPrint(uintptr_t handle);
+//	void myprint(uintptr_t handle);
+//	*/
+//	import "C"
+//	import "runtime/cgo"
+//
+//	//export MyGoPrint
+//	func MyGoPrint(handle C.uintptr_t) {
+//		h := cgo.Handle(handle)
+//		val := h.Value().(string)
+//		println(val)
+//		h.Delete()
+//	}
+//
+//	func main() {
+//		val := "hello Go"
+//		C.myprint(C.uintptr_t(cgo.NewHandle(val)))
+//		// Output: hello Go
+//	}
+//
+// and on the C side:
+//
+//	#include <stdint.h> // for uintptr_t
+//
+//	// A Go function
+//	extern void MyGoPrint(uintptr_t handle);
+//
+//	// A C function
+//	void myprint(uintptr_t handle) {
+//	    MyGoPrint(handle);
+//	}
+type Handle uintptr
+
+// NewHandle returns a handle for a given value.
+//
+// The handle is valid until the program calls Delete on it. The handle
+// uses resources, and this package assumes that C code may hold on to
+// the handle, so a program must explicitly call Delete when the handle
+// is no longer needed.
+//
+// The intended use is to pass the returned handle to C code, which
+// passes it back to Go, which calls Value.
+func NewHandle(v interface{}) Handle {
+	h := atomic.AddUintptr(&handleIdx, 1)
+	if h == 0 {
+		panic("runtime/cgo: ran out of handle space")
+	}
+
+	handles.Store(h, v)
+	return Handle(h)
+}
+
+// Value returns the associated Go value for a valid handle.
+//
+// The method panics if the handle is invalid.
+func (h Handle) Value() interface{} {
+	v, ok := handles.Load(uintptr(h))
+	if !ok {
+		panic("runtime/cgo: misuse of an invalid Handle")
+	}
+	return v
+}
+
+// Delete invalidates a handle. This method should only be called once
+// the program no longer needs to pass the handle to C and the C code
+// no longer has a copy of the handle value.
+//
+// The method panics if the handle is invalid.
+func (h Handle) Delete() {
+	_, ok := handles.LoadAndDelete(uintptr(h))
+	if !ok {
+		panic("runtime/cgo: misuse of an invalid Handle")
+	}
+}
+
+var (
+	handles   = sync.Map{} // map[Handle]interface{}
+	handleIdx uintptr      // atomic
+)
diff --git a/src/runtime/cgo/handle_test.go b/src/runtime/cgo/handle_test.go
new file mode 100644
index 0000000..738051a
--- /dev/null
+++ b/src/runtime/cgo/handle_test.go
@@ -0,0 +1,103 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cgo
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestHandle(t *testing.T) {
+	v := 42
+
+	tests := []struct {
+		v1 interface{}
+		v2 interface{}
+	}{
+		{v1: v, v2: v},
+		{v1: &v, v2: &v},
+		{v1: nil, v2: nil},
+	}
+
+	for _, tt := range tests {
+		h1 := NewHandle(tt.v1)
+		h2 := NewHandle(tt.v2)
+
+		if uintptr(h1) == 0 || uintptr(h2) == 0 {
+			t.Fatalf("NewHandle returns zero")
+		}
+
+		if uintptr(h1) == uintptr(h2) {
+			t.Fatalf("Duplicated Go values should have different handles, but got equal")
+		}
+
+		h1v := h1.Value()
+		h2v := h2.Value()
+		if !reflect.DeepEqual(h1v, h2v) || !reflect.DeepEqual(h1v, tt.v1) {
+			t.Fatalf("Value of a Handle got wrong, got %+v %+v, want %+v", h1v, h2v, tt.v1)
+		}
+
+		h1.Delete()
+		h2.Delete()
+	}
+
+	siz := 0
+	handles.Range(func(k, v interface{}) bool {
+		siz++
+		return true
+	})
+	if siz != 0 {
+		t.Fatalf("handles are not cleared, got %d, want %d", siz, 0)
+	}
+}
+
+func TestInvalidHandle(t *testing.T) {
+	t.Run("zero", func(t *testing.T) {
+		h := Handle(0)
+
+		defer func() {
+			if r := recover(); r != nil {
+				return
+			}
+			t.Fatalf("Delete of zero handle did not trigger a panic")
+		}()
+
+		h.Delete()
+	})
+
+	t.Run("invalid", func(t *testing.T) {
+		h := NewHandle(42)
+
+		defer func() {
+			if r := recover(); r != nil {
+				h.Delete()
+				return
+			}
+			t.Fatalf("Invalid handle did not trigger a panic")
+		}()
+
+		Handle(h + 1).Delete()
+	})
+}
+
+func BenchmarkHandle(b *testing.B) {
+	b.Run("non-concurrent", func(b *testing.B) {
+		for i := 0; i < b.N; i++ {
+			h := NewHandle(i)
+			_ = h.Value()
+			h.Delete()
+		}
+	})
+	b.Run("concurrent", func(b *testing.B) {
+		b.RunParallel(func(pb *testing.PB) {
+			var v int
+			for pb.Next() {
+				h := NewHandle(v)
+				_ = h.Value()
+				h.Delete()
+			}
+		})
+	})
+}
diff --git a/src/runtime/cgo/libcgo.h b/src/runtime/cgo/libcgo.h
index aba500a..af4960e 100644
--- a/src/runtime/cgo/libcgo.h
+++ b/src/runtime/cgo/libcgo.h
@@ -66,7 +66,7 @@
 /*
  * Call fn in the 6c world.
  */
-void crosscall_amd64(void (*fn)(void));
+void crosscall_amd64(void (*fn)(void), void (*setg_gcc)(void*), void *g);
 
 /*
  * Call fn in the 8c world.
diff --git a/src/runtime/cgo/linux.go b/src/runtime/cgo/linux.go
index 76c0192..070d531 100644
--- a/src/runtime/cgo/linux.go
+++ b/src/runtime/cgo/linux.go
@@ -5,6 +5,7 @@
 // Linux system call wrappers that provide POSIX semantics through the
 // corresponding cgo->libc (nptl) wrappers for various system calls.
 
+//go:build linux
 // +build linux
 
 package cgo
diff --git a/src/runtime/cgo/mmap.go b/src/runtime/cgo/mmap.go
index 00fb7fc..347ae6b 100644
--- a/src/runtime/cgo/mmap.go
+++ b/src/runtime/cgo/mmap.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (linux && amd64) || (linux && arm64)
 // +build linux,amd64 linux,arm64
 
 package cgo
diff --git a/src/runtime/cgo/netbsd.go b/src/runtime/cgo/netbsd.go
index 74d0aed..7e17d1f 100644
--- a/src/runtime/cgo/netbsd.go
+++ b/src/runtime/cgo/netbsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build netbsd
 // +build netbsd
 
 package cgo
diff --git a/src/runtime/cgo/openbsd.go b/src/runtime/cgo/openbsd.go
index 81c73bf..f621561 100644
--- a/src/runtime/cgo/openbsd.go
+++ b/src/runtime/cgo/openbsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build openbsd
 // +build openbsd
 
 package cgo
diff --git a/src/runtime/cgo/setenv.go b/src/runtime/cgo/setenv.go
index 6495fcb..e6e8040 100644
--- a/src/runtime/cgo/setenv.go
+++ b/src/runtime/cgo/setenv.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package cgo
diff --git a/src/runtime/cgo/sigaction.go b/src/runtime/cgo/sigaction.go
index 076fbc1..692fd26 100644
--- a/src/runtime/cgo/sigaction.go
+++ b/src/runtime/cgo/sigaction.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux,amd64 freebsd,amd64 linux,arm64
+//go:build (linux && amd64) || (freebsd && amd64) || (linux && arm64) || (linux && ppc64le)
+// +build linux,amd64 freebsd,amd64 linux,arm64 linux,ppc64le
 
 package cgo
 
@@ -10,8 +11,8 @@
 import _ "unsafe"
 
 // When using cgo, call the C library for sigaction, so that we call into
-// any sanitizer interceptors. This supports using the memory
-// sanitizer with Go programs. The memory sanitizer only applies to
+// any sanitizer interceptors. This supports using the sanitizers
+// with Go programs. The thread and memory sanitizers only apply to
 // C/C++ code; this permits that code to see the Go runtime's existing signal
 // handlers when registering new signal handlers for the process.
 
diff --git a/src/runtime/cgo_mmap.go b/src/runtime/cgo_mmap.go
index d5e0cc1..17d26b4 100644
--- a/src/runtime/cgo_mmap.go
+++ b/src/runtime/cgo_mmap.go
@@ -4,6 +4,7 @@
 
 // Support for memory sanitizer. See runtime/cgo/mmap.go.
 
+//go:build (linux && amd64) || (linux && arm64)
 // +build linux,amd64 linux,arm64
 
 package runtime
diff --git a/src/runtime/cgo_ppc64x.go b/src/runtime/cgo_ppc64x.go
index fb2da32..4dc92ea 100644
--- a/src/runtime/cgo_ppc64x.go
+++ b/src/runtime/cgo_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 package runtime
diff --git a/src/runtime/cgo_sigaction.go b/src/runtime/cgo_sigaction.go
index de634dc..6099d1b 100644
--- a/src/runtime/cgo_sigaction.go
+++ b/src/runtime/cgo_sigaction.go
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Support for memory sanitizer. See runtime/cgo/sigaction.go.
+// Support for sanitizers. See runtime/cgo/sigaction.go.
 
-// +build linux,amd64 freebsd,amd64 linux,arm64
+//go:build (linux && amd64) || (freebsd && amd64) || (linux && arm64) || (linux && ppc64le)
+// +build linux,amd64 freebsd,amd64 linux,arm64 linux,ppc64le
 
 package runtime
 
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index 20cacd6..2626216 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -110,6 +110,8 @@
 	return as.retval
 }
 
+var ncgocall uint64 // number of cgo calls in total for dead m
+
 // Call from Go to C.
 //
 // This must be nosplit because it's used for syscalls on some
@@ -195,7 +197,7 @@
 	return errno
 }
 
-// Call from C back to Go.
+// Call from C back to Go. fn must point to an ABIInternal Go entry-point.
 //go:nosplit
 func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
 	gp := getg()
@@ -210,6 +212,8 @@
 	// a different M. The call to unlockOSThread is in unwindm.
 	lockOSThread()
 
+	checkm := gp.m
+
 	// Save current syscall parameters, so m.syscall can be
 	// used again if callback decide to make syscall.
 	syscall := gp.m.syscall
@@ -225,15 +229,20 @@
 
 	osPreemptExtExit(gp.m)
 
-	cgocallbackg1(fn, frame, ctxt)
+	cgocallbackg1(fn, frame, ctxt) // will call unlockOSThread
 
 	// 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
+
+	if gp.m != checkm {
+		throw("m changed unexpectedly in cgocallbackg")
+	}
+
 	osPreemptExtEnter(gp.m)
 
-	gp.m.incgo = true
 	// going back to cgo call
 	reentersyscall(savedpc, uintptr(savedsp))
 
@@ -242,6 +251,11 @@
 
 func cgocallbackg1(fn, frame unsafe.Pointer, ctxt uintptr) {
 	gp := getg()
+
+	// When we return, undo the call to lockOSThread in cgocallbackg.
+	// We must still stay on the same m.
+	defer unlockOSThread()
+
 	if gp.m.needextram || atomic.Load(&extraMWaiters) > 0 {
 		gp.m.needextram = false
 		systemstack(newextram)
@@ -306,14 +320,7 @@
 		// 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", "riscv64":
-			sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + sys.MinFrameSize))
-		case "arm64":
-			sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + 16))
-		}
+		sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + alignUp(sys.MinFrameSize, sys.StackAlign)))
 
 		// Do the accounting that cgocall will not have a chance to do
 		// during an unwind.
@@ -328,10 +335,6 @@
 
 		releasem(mp)
 	}
-
-	// Undo the call to lockOSThread in cgocallbackg.
-	// We must still stay on the same m.
-	unlockOSThread()
 }
 
 // called from assembly
diff --git a/src/runtime/chan.go b/src/runtime/chan.go
index ba56e2c..f2a75b3 100644
--- a/src/runtime/chan.go
+++ b/src/runtime/chan.go
@@ -690,28 +690,6 @@
 // compiler implements
 //
 //	select {
-//	case v = <-c:
-//		... foo
-//	default:
-//		... bar
-//	}
-//
-// as
-//
-//	if selectnbrecv(&v, c) {
-//		... foo
-//	} else {
-//		... bar
-//	}
-//
-func selectnbrecv(elem unsafe.Pointer, c *hchan) (selected bool) {
-	selected, _ = chanrecv(c, elem, false)
-	return
-}
-
-// compiler implements
-//
-//	select {
 //	case v, ok = <-c:
 //		... foo
 //	default:
@@ -720,16 +698,14 @@
 //
 // as
 //
-//	if c != nil && selectnbrecv2(&v, &ok, c) {
+//	if selected, ok = selectnbrecv(&v, c); selected {
 //		... foo
 //	} else {
 //		... bar
 //	}
 //
-func selectnbrecv2(elem unsafe.Pointer, received *bool, c *hchan) (selected bool) {
-	// TODO(khr): just return 2 values from this function, now that it is in Go.
-	selected, *received = chanrecv(c, elem, false)
-	return
+func selectnbrecv(elem unsafe.Pointer, c *hchan) (selected, received bool) {
+	return chanrecv(c, elem, false)
 }
 
 //go:linkname reflect_chansend reflect.chansend
diff --git a/src/runtime/chan_test.go b/src/runtime/chan_test.go
index 756bbbe..c9ce3ac 100644
--- a/src/runtime/chan_test.go
+++ b/src/runtime/chan_test.go
@@ -631,7 +631,7 @@
 	// channel. See issue 40641 for more details on the problem.
 	//
 	// The way we try to induce this failure is to set up two
-	// goroutines: a sender and a reciever that communicate across
+	// goroutines: a sender and a receiver that communicate across
 	// a channel. We try to set up a situation where the sender
 	// grows its stack temporarily then *fully* blocks on a channel
 	// often. Meanwhile a GC is triggered so that we try to get a
@@ -671,7 +671,7 @@
 		go send(c, done)
 		// Wait a little bit before triggering
 		// the GC to make sure the sender and
-		// reciever have gotten into their groove.
+		// receiver have gotten into their groove.
 		time.Sleep(50 * time.Microsecond)
 		runtime.GC()
 		<-done
@@ -708,8 +708,6 @@
 	c <- 8 // wake up B.  This operation used to fail because c.recvq was corrupted (it tries to wake up an already running G instead of B)
 }
 
-var selectSink interface{}
-
 func TestSelectStackAdjust(t *testing.T) {
 	// Test that channel receive slots that contain local stack
 	// pointers are adjusted correctly by stack shrinking.
@@ -766,20 +764,8 @@
 	<-ready2
 	time.Sleep(10 * time.Millisecond)
 
-	// Force concurrent GC a few times.
-	var before, after runtime.MemStats
-	runtime.ReadMemStats(&before)
-	for i := 0; i < 100; i++ {
-		selectSink = new([1 << 20]byte)
-		runtime.ReadMemStats(&after)
-		if after.NumGC-before.NumGC >= 2 {
-			goto done
-		}
-		runtime.Gosched()
-	}
-	t.Fatal("failed to trigger concurrent GC")
-done:
-	selectSink = nil
+	// Force concurrent GC to shrink the stacks.
+	runtime.GC()
 
 	// Wake selects.
 	close(d)
diff --git a/src/runtime/checkptr.go b/src/runtime/checkptr.go
index 59891a0..2d4afd5 100644
--- a/src/runtime/checkptr.go
+++ b/src/runtime/checkptr.go
@@ -7,6 +7,11 @@
 import "unsafe"
 
 func checkptrAlignment(p unsafe.Pointer, elem *_type, n uintptr) {
+	// nil pointer is always suitably aligned (#47430).
+	if p == nil {
+		return
+	}
+
 	// Check that (*[n]elem)(p) is appropriately aligned.
 	// Note that we allow unaligned pointers if the types they point to contain
 	// no pointers themselves. See issue 37298.
@@ -16,11 +21,32 @@
 	}
 
 	// Check that (*[n]elem)(p) doesn't straddle multiple heap objects.
-	if size := n * elem.size; size > 1 && checkptrBase(p) != checkptrBase(add(p, size-1)) {
+	// TODO(mdempsky): Fix #46938 so we don't need to worry about overflow here.
+	if checkptrStraddles(p, n*elem.size) {
 		throw("checkptr: converted pointer straddles multiple allocations")
 	}
 }
 
+// checkptrStraddles reports whether the first size-bytes of memory
+// addressed by ptr is known to straddle more than one Go allocation.
+func checkptrStraddles(ptr unsafe.Pointer, size uintptr) bool {
+	if size <= 1 {
+		return false
+	}
+
+	// Check that add(ptr, size-1) won't overflow. This avoids the risk
+	// of producing an illegal pointer value (assuming ptr is legal).
+	if uintptr(ptr) >= -(size - 1) {
+		return true
+	}
+	end := add(ptr, size-1)
+
+	// TODO(mdempsky): Detect when [ptr, end] contains Go allocations,
+	// but neither ptr nor end point into one themselves.
+
+	return checkptrBase(ptr) != checkptrBase(end)
+}
+
 func checkptrArithmetic(p unsafe.Pointer, originals []unsafe.Pointer) {
 	if 0 < uintptr(p) && uintptr(p) < minLegalPointer {
 		throw("checkptr: pointer arithmetic computed bad pointer value")
diff --git a/src/runtime/checkptr_test.go b/src/runtime/checkptr_test.go
index 194cc12..d5dd101 100644
--- a/src/runtime/checkptr_test.go
+++ b/src/runtime/checkptr_test.go
@@ -26,10 +26,13 @@
 	}{
 		{"CheckPtrAlignmentPtr", "fatal error: checkptr: misaligned pointer conversion\n"},
 		{"CheckPtrAlignmentNoPtr", ""},
+		{"CheckPtrAlignmentNilPtr", ""},
 		{"CheckPtrArithmetic", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
 		{"CheckPtrArithmetic2", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
 		{"CheckPtrSize", "fatal error: checkptr: converted pointer straddles multiple allocations\n"},
 		{"CheckPtrSmall", "fatal error: checkptr: pointer arithmetic computed bad pointer value\n"},
+		{"CheckPtrSliceOK", ""},
+		{"CheckPtrSliceFail", "fatal error: checkptr: unsafe.Slice result straddles multiple allocations\n"},
 	}
 
 	for _, tc := range testCases {
diff --git a/src/runtime/cpuprof.go b/src/runtime/cpuprof.go
index 9bfdfe7..e5d0193 100644
--- a/src/runtime/cpuprof.go
+++ b/src/runtime/cpuprof.go
@@ -103,7 +103,16 @@
 		// because otherwise its write barrier behavior may not
 		// be correct. See the long comment there before
 		// changing the argument here.
-		cpuprof.log.write(&gp.labels, nanotime(), hdr[:], stk)
+		//
+		// Note: it can happen on Windows, where we are calling
+		// p.add with a gp that is not the current g, that gp is nil,
+		// meaning we interrupted a system thread with no g.
+		// Avoid faulting in that case.
+		var tagPtr *unsafe.Pointer
+		if gp != nil {
+			tagPtr = &gp.labels
+		}
+		cpuprof.log.write(tagPtr, nanotime(), hdr[:], stk)
 	}
 
 	atomic.Store(&prof.signalLock, 0)
diff --git a/src/runtime/cputicks.go b/src/runtime/cputicks.go
index 7beb57e..7c926f4 100644
--- a/src/runtime/cputicks.go
+++ b/src/runtime/cputicks.go
@@ -2,13 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !arm
-// +build !arm64
-// +build !mips64
-// +build !mips64le
-// +build !mips
-// +build !mipsle
-// +build !wasm
+//go:build !arm && !arm64 && !mips64 && !mips64le && !mips && !mipsle && !wasm
+// +build !arm,!arm64,!mips64,!mips64le,!mips,!mipsle,!wasm
 
 package runtime
 
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index 140c170..5729942 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo
 // +build cgo
 
 package runtime_test
@@ -281,6 +282,15 @@
 	}
 }
 
+func TestCgoTracebackContextPreemption(t *testing.T) {
+	t.Parallel()
+	got := runTestProg(t, "testprogcgo", "TracebackContextPreemption")
+	want := "OK\n"
+	if got != want {
+		t.Errorf("expected %q got %v", want, got)
+	}
+}
+
 func testCgoPprof(t *testing.T, buildArg, runArg, top, bottom string) {
 	t.Parallel()
 	if runtime.GOOS != "linux" || (runtime.GOARCH != "amd64" && runtime.GOARCH != "ppc64le") {
diff --git a/src/runtime/crash_nonunix_test.go b/src/runtime/crash_nonunix_test.go
index 06c197e..5f61476f 100644
--- a/src/runtime/crash_nonunix_test.go
+++ b/src/runtime/crash_nonunix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build windows || plan9 || (js && wasm)
 // +build windows plan9 js,wasm
 
 package runtime_test
diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go
index e5bd797..e0c0bac 100644
--- a/src/runtime/crash_test.go
+++ b/src/runtime/crash_test.go
@@ -470,14 +470,6 @@
 }
 
 func TestNetpollDeadlock(t *testing.T) {
-	if os.Getenv("GO_BUILDER_NAME") == "darwin-amd64-10_12" {
-		// A suspected kernel bug in macOS 10.12 occasionally results in
-		// an apparent deadlock when dialing localhost. The errors have not
-		// been observed on newer versions of the OS, so we don't plan to work
-		// around them. See https://golang.org/issue/22019.
-		testenv.SkipFlaky(t, 22019)
-	}
-
 	t.Parallel()
 	output := runTestProg(t, "testprognet", "NetpollDeadlock")
 	want := "done\n"
diff --git a/src/runtime/crash_unix_test.go b/src/runtime/crash_unix_test.go
index 803b031..694cc3d 100644
--- a/src/runtime/crash_unix_test.go
+++ b/src/runtime/crash_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package runtime_test
@@ -12,7 +13,6 @@
 	"io"
 	"os"
 	"os/exec"
-	"path/filepath"
 	"runtime"
 	"strings"
 	"sync"
@@ -69,7 +69,8 @@
 		t.Skipf("skipping; not supported on %v", runtime.GOOS)
 	}
 
-	if runtime.GOOS == "openbsd" && runtime.GOARCH == "mips64" {
+	if runtime.GOOS == "openbsd" && (runtime.GOARCH == "arm" || runtime.GOARCH == "mips64") {
+		// This may be ncpu < 2 related...
 		t.Skipf("skipping; test fails on %s/%s - see issue #42464", runtime.GOOS, runtime.GOARCH)
 	}
 
@@ -77,31 +78,14 @@
 		t.Skip("skipping; SIGQUIT is blocked, see golang.org/issue/19196")
 	}
 
-	// We don't use executeTest because we need to kill the
-	// program while it is running.
-
 	testenv.MustHaveGoBuild(t)
 
-	t.Parallel()
-
-	dir, err := os.MkdirTemp("", "go-build")
+	exe, err := buildTestProg(t, "testprog")
 	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
-
-	if err := os.WriteFile(filepath.Join(dir, "main.go"), []byte(crashDumpsAllThreadsSource), 0666); err != nil {
-		t.Fatalf("failed to create Go file: %v", err)
+		t.Fatal(err)
 	}
 
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "a.exe", "main.go")
-	cmd.Dir = dir
-	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 := exec.Command(exe, "CrashDumpsAllThreads")
 	cmd = testenv.CleanCmdEnv(cmd)
 	cmd.Env = append(cmd.Env,
 		"GOTRACEBACK=crash",
@@ -123,9 +107,12 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+	defer rp.Close()
+
 	cmd.ExtraFiles = []*os.File{wp}
 
 	if err := cmd.Start(); err != nil {
+		wp.Close()
 		t.Fatalf("starting program: %v", err)
 	}
 
@@ -147,56 +134,14 @@
 	// We want to see a stack trace for each thread.
 	// Before https://golang.org/cl/2811 running threads would say
 	// "goroutine running on other thread; stack unavailable".
-	out = outbuf.Bytes()
-	n := bytes.Count(out, []byte("main.loop("))
+	out := outbuf.Bytes()
+	n := bytes.Count(out, []byte("main.crashDumpsAllThreadsLoop("))
 	if n != 4 {
 		t.Errorf("found %d instances of main.loop; expected 4", n)
 		t.Logf("%s", out)
 	}
 }
 
-const crashDumpsAllThreadsSource = `
-package main
-
-import (
-	"fmt"
-	"os"
-	"runtime"
-)
-
-func main() {
-	const count = 4
-	runtime.GOMAXPROCS(count + 1)
-
-	chans := make([]chan bool, count)
-	for i := range chans {
-		chans[i] = make(chan bool)
-		go loop(i, chans[i])
-	}
-
-	// Wait for all the goroutines to start executing.
-	for _, c := range chans {
-		<-c
-	}
-
-	// Tell our parent that all the goroutines are executing.
-	if _, err := os.NewFile(3, "pipe").WriteString("x"); err != nil {
-		fmt.Fprintf(os.Stderr, "write to pipe failed: %v\n", err)
-		os.Exit(2)
-	}
-
-	select {}
-}
-
-func loop(i int, c chan bool) {
-	close(c)
-	for {
-		for j := 0; j < 0x7fffffff; j++ {
-		}
-	}
-}
-`
-
 func TestPanicSystemstack(t *testing.T) {
 	// Test that GOTRACEBACK=crash prints both the system and user
 	// stack of other threads.
diff --git a/src/runtime/debug.go b/src/runtime/debug.go
index f411b22..82deefa 100644
--- a/src/runtime/debug.go
+++ b/src/runtime/debug.go
@@ -45,7 +45,7 @@
 
 // NumCgoCall returns the number of cgo calls made by the current process.
 func NumCgoCall() int64 {
-	var n int64
+	var n = int64(atomic.Load64(&ncgocall))
 	for mp := (*m)(atomic.Loadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink {
 		n += int64(mp.ncgocall)
 	}
diff --git a/src/runtime/debug/panic_test.go b/src/runtime/debug/panic_test.go
index b67a3de..65f9555 100644
--- a/src/runtime/debug/panic_test.go
+++ b/src/runtime/debug/panic_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd
 // +build aix darwin dragonfly freebsd linux netbsd openbsd
 
 // TODO: test on Windows?
@@ -23,6 +24,9 @@
 	if runtime.GOOS == "ios" {
 		t.Skip("iOS doesn't provide fault addresses")
 	}
+	if runtime.GOOS == "netbsd" && runtime.GOARCH == "arm" {
+		t.Skip("netbsd-arm doesn't provide fault address (golang.org/issue/45026)")
+	}
 	m, err := syscall.Mmap(-1, 0, 0x1000, syscall.PROT_READ /* Note: no PROT_WRITE */, syscall.MAP_SHARED|syscall.MAP_ANON)
 	if err != nil {
 		t.Fatalf("can't map anonymous memory: %s", err)
diff --git a/src/runtime/debug_test.go b/src/runtime/debug_test.go
index a0b3f84..f743834 100644
--- a/src/runtime/debug_test.go
+++ b/src/runtime/debug_test.go
@@ -9,14 +9,16 @@
 // spends all of its time in the race runtime, which isn't a safe
 // point.
 
-// +build amd64
-// +build linux
-// +build !race
+//go:build amd64 && linux && !race
+// +build amd64,linux,!race
 
 package runtime_test
 
 import (
 	"fmt"
+	"internal/abi"
+	"internal/goexperiment"
+	"math"
 	"os"
 	"regexp"
 	"runtime"
@@ -116,21 +118,49 @@
 	g, after := startDebugCallWorker(t)
 	defer after()
 
+	type stackArgs struct {
+		x0    int
+		x1    float64
+		y0Ret int
+		y1Ret float64
+	}
+
 	// Inject a call into the debugCallWorker goroutine and test
 	// basic argument and result passing.
-	var args struct {
-		x    int
-		yRet int
+	fn := func(x int, y float64) (y0Ret int, y1Ret float64) {
+		return x + 1, y + 1.0
 	}
-	fn := func(x int) (yRet int) {
-		return x + 1
+	var args *stackArgs
+	var regs abi.RegArgs
+	intRegs := regs.Ints[:]
+	floatRegs := regs.Floats[:]
+	fval := float64(42.0)
+	if goexperiment.RegabiArgs {
+		intRegs[0] = 42
+		floatRegs[0] = math.Float64bits(fval)
+	} else {
+		args = &stackArgs{
+			x0: 42,
+			x1: 42.0,
+		}
 	}
-	args.x = 42
-	if _, err := runtime.InjectDebugCall(g, fn, &args, debugCallTKill, false); err != nil {
+	if _, err := runtime.InjectDebugCall(g, fn, &regs, args, debugCallTKill, false); err != nil {
 		t.Fatal(err)
 	}
-	if args.yRet != 43 {
-		t.Fatalf("want 43, got %d", args.yRet)
+	var result0 int
+	var result1 float64
+	if goexperiment.RegabiArgs {
+		result0 = int(intRegs[0])
+		result1 = math.Float64frombits(floatRegs[0])
+	} else {
+		result0 = args.y0Ret
+		result1 = args.y1Ret
+	}
+	if result0 != 43 {
+		t.Errorf("want 43, got %d", result0)
+	}
+	if result1 != fval+1 {
+		t.Errorf("want 43, got %f", result1)
 	}
 }
 
@@ -155,7 +185,7 @@
 		args.in[i] = i
 		want[i] = i + 1
 	}
-	if _, err := runtime.InjectDebugCall(g, fn, &args, debugCallTKill, false); err != nil {
+	if _, err := runtime.InjectDebugCall(g, fn, nil, &args, debugCallTKill, false); err != nil {
 		t.Fatal(err)
 	}
 	if want != args.out {
@@ -168,7 +198,7 @@
 	defer after()
 
 	// Inject a call that performs a GC.
-	if _, err := runtime.InjectDebugCall(g, runtime.GC, nil, debugCallTKill, false); err != nil {
+	if _, err := runtime.InjectDebugCall(g, runtime.GC, nil, nil, debugCallTKill, false); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -179,7 +209,7 @@
 
 	// Inject a call that grows the stack. debugCallWorker checks
 	// for stack pointer breakage.
-	if _, err := runtime.InjectDebugCall(g, func() { growStack(nil) }, nil, debugCallTKill, false); err != nil {
+	if _, err := runtime.InjectDebugCall(g, func() { growStack(nil) }, nil, nil, debugCallTKill, false); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -215,7 +245,7 @@
 		runtime.Gosched()
 	}
 
-	_, err := runtime.InjectDebugCall(g, func() {}, nil, debugCallTKill, true)
+	_, err := runtime.InjectDebugCall(g, func() {}, nil, nil, debugCallTKill, true)
 	if msg := "call not at safe point"; err == nil || err.Error() != msg {
 		t.Fatalf("want %q, got %s", msg, err)
 	}
@@ -239,7 +269,7 @@
 	}()
 	g := <-ready
 
-	p, err := runtime.InjectDebugCall(g, func() { panic("test") }, nil, debugCallTKill, false)
+	p, err := runtime.InjectDebugCall(g, func() { panic("test") }, nil, nil, debugCallTKill, false)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/src/runtime/debugcall.go b/src/runtime/debugcall.go
index efc68a7..faddf59 100644
--- a/src/runtime/debugcall.go
+++ b/src/runtime/debugcall.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64
 // +build amd64
 
 package runtime
@@ -15,7 +16,7 @@
 	debugCallUnsafePoint = "call not at safe point"
 )
 
-func debugCallV1()
+func debugCallV2()
 func debugCallPanicked(val interface{})
 
 // debugCallCheck checks whether it is safe to inject a debugger
@@ -95,7 +96,7 @@
 // function at PC dispatch.
 //
 // This must be deeply nosplit because there are untyped values on the
-// stack from debugCallV1.
+// stack from debugCallV2.
 //
 //go:nosplit
 func debugCallWrap(dispatch uintptr) {
@@ -107,14 +108,16 @@
 	// Create a new goroutine to execute the call on. Run this on
 	// the system stack to avoid growing our stack.
 	systemstack(func() {
-		var args struct {
-			dispatch uintptr
-			callingG *g
-		}
-		args.dispatch = dispatch
-		args.callingG = gp
+		// TODO(mknyszek): It would be nice to wrap these arguments in an allocated
+		// closure and start the goroutine with that closure, but the compiler disallows
+		// implicit closure allocation in the runtime.
 		fn := debugCallWrap1
-		newg := newproc1(*(**funcval)(unsafe.Pointer(&fn)), unsafe.Pointer(&args), int32(unsafe.Sizeof(args)), gp, callerpc)
+		newg := newproc1(*(**funcval)(unsafe.Pointer(&fn)), nil, 0, gp, callerpc)
+		args := &debugCallWrapArgs{
+			dispatch: dispatch,
+			callingG: gp,
+		}
+		newg.param = unsafe.Pointer(args)
 
 		// If the current G is locked, then transfer that
 		// locked-ness to the new goroutine.
@@ -184,9 +187,19 @@
 	gp.asyncSafePoint = false
 }
 
+type debugCallWrapArgs struct {
+	dispatch uintptr
+	callingG *g
+}
+
 // debugCallWrap1 is the continuation of debugCallWrap on the callee
 // goroutine.
-func debugCallWrap1(dispatch uintptr, callingG *g) {
+func debugCallWrap1() {
+	gp := getg()
+	args := (*debugCallWrapArgs)(gp.param)
+	dispatch, callingG := args.dispatch, args.callingG
+	gp.param = nil
+
 	// Dispatch call and trap panics.
 	debugCallWrap2(dispatch)
 
diff --git a/src/runtime/debuglog_off.go b/src/runtime/debuglog_off.go
index bb3e172..dd38156 100644
--- a/src/runtime/debuglog_off.go
+++ b/src/runtime/debuglog_off.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !debuglog
 // +build !debuglog
 
 package runtime
diff --git a/src/runtime/debuglog_on.go b/src/runtime/debuglog_on.go
index 3d477e8..2fcdbe7 100644
--- a/src/runtime/debuglog_on.go
+++ b/src/runtime/debuglog_on.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build debuglog
 // +build debuglog
 
 package runtime
diff --git a/src/runtime/defer_test.go b/src/runtime/defer_test.go
index 9a40ea1..fc96144 100644
--- a/src/runtime/defer_test.go
+++ b/src/runtime/defer_test.go
@@ -370,7 +370,7 @@
 	defer ap.method2()
 	defer ap.method1()
 	ff1(ap, 1, 2, 3, 4, 5, 6, 7, 8, 9)
-	// Try to get the stack to be be moved by growing it too large, so
+	// Try to get the stack to be moved by growing it too large, so
 	// existing stack-allocated defer becomes invalid.
 	rec1(2000)
 }
diff --git a/src/runtime/defs1_linux.go b/src/runtime/defs1_linux.go
index 4085d6f..df9c05d 100644
--- a/src/runtime/defs1_linux.go
+++ b/src/runtime/defs1_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs2_linux.go b/src/runtime/defs2_linux.go
index 87e19c1..d016db7 100644
--- a/src/runtime/defs2_linux.go
+++ b/src/runtime/defs2_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs3_linux.go b/src/runtime/defs3_linux.go
index 31f2191..0a06aa2 100644
--- a/src/runtime/defs3_linux.go
+++ b/src/runtime/defs3_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_aix.go b/src/runtime/defs_aix.go
index 23a6cac..1605002 100644
--- a/src/runtime/defs_aix.go
+++ b/src/runtime/defs_aix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_aix_ppc64.go b/src/runtime/defs_aix_ppc64.go
index a53fcc5..f84ff11 100644
--- a/src/runtime/defs_aix_ppc64.go
+++ b/src/runtime/defs_aix_ppc64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix
 // +build aix
 
 package runtime
diff --git a/src/runtime/defs_arm_linux.go b/src/runtime/defs_arm_linux.go
index e51dd32..f6b6dd2 100644
--- a/src/runtime/defs_arm_linux.go
+++ b/src/runtime/defs_arm_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_darwin.go b/src/runtime/defs_darwin.go
index cc8c475..2d41a97 100644
--- a/src/runtime/defs_darwin.go
+++ b/src/runtime/defs_darwin.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_dragonfly.go b/src/runtime/defs_dragonfly.go
index 95014fe..aca2bf9 100644
--- a/src/runtime/defs_dragonfly.go
+++ b/src/runtime/defs_dragonfly.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
@@ -31,6 +32,10 @@
 	EFAULT = C.EFAULT
 	EBUSY  = C.EBUSY
 	EAGAIN = C.EAGAIN
+	ENOSYS = C.ENOSYS
+
+	O_NONBLOCK = C.O_NONBLOCK
+	O_CLOEXEC  = C.O_CLOEXEC
 
 	PROT_NONE  = C.PROT_NONE
 	PROT_READ  = C.PROT_READ
diff --git a/src/runtime/defs_dragonfly_amd64.go b/src/runtime/defs_dragonfly_amd64.go
index 30f1b33..f3c6ecd 100644
--- a/src/runtime/defs_dragonfly_amd64.go
+++ b/src/runtime/defs_dragonfly_amd64.go
@@ -10,6 +10,10 @@
 	_EFAULT = 0xe
 	_EBUSY  = 0x10
 	_EAGAIN = 0x23
+	_ENOSYS = 0x4e
+
+	_O_NONBLOCK = 0x4
+	_O_CLOEXEC  = 0x20000
 
 	_PROT_NONE  = 0x0
 	_PROT_READ  = 0x1
diff --git a/src/runtime/defs_freebsd.go b/src/runtime/defs_freebsd.go
index e196dff..c258759 100644
--- a/src/runtime/defs_freebsd.go
+++ b/src/runtime/defs_freebsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_linux.go b/src/runtime/defs_linux.go
index 7b14063..022ef19 100644
--- a/src/runtime/defs_linux.go
+++ b/src/runtime/defs_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_linux_mips64x.go b/src/runtime/defs_linux_mips64x.go
index 1fb423b..2cafad2 100644
--- a/src/runtime/defs_linux_mips64x.go
+++ b/src/runtime/defs_linux_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (mips64 || mips64le) && linux
 // +build mips64 mips64le
 // +build linux
 
diff --git a/src/runtime/defs_linux_mipsx.go b/src/runtime/defs_linux_mipsx.go
index 9315ba9..3a8dfe2 100644
--- a/src/runtime/defs_linux_mipsx.go
+++ b/src/runtime/defs_linux_mipsx.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (mips || mipsle) && linux
 // +build mips mipsle
 // +build linux
 
diff --git a/src/runtime/defs_netbsd.go b/src/runtime/defs_netbsd.go
index 3f5ce5a..755992d 100644
--- a/src/runtime/defs_netbsd.go
+++ b/src/runtime/defs_netbsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_netbsd_386.go b/src/runtime/defs_netbsd_386.go
index c26f246..03c9c2d 100644
--- a/src/runtime/defs_netbsd_386.go
+++ b/src/runtime/defs_netbsd_386.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_netbsd_amd64.go b/src/runtime/defs_netbsd_amd64.go
index f18a7b1..9fda1d7 100644
--- a/src/runtime/defs_netbsd_amd64.go
+++ b/src/runtime/defs_netbsd_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_netbsd_arm.go b/src/runtime/defs_netbsd_arm.go
index cb0dce6..e7f4f6c 100644
--- a/src/runtime/defs_netbsd_arm.go
+++ b/src/runtime/defs_netbsd_arm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_openbsd.go b/src/runtime/defs_openbsd.go
index ff7e21c..8d32344 100644
--- a/src/runtime/defs_openbsd.go
+++ b/src/runtime/defs_openbsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_openbsd_386.go b/src/runtime/defs_openbsd_386.go
index 35f2e53..a866ec8 100644
--- a/src/runtime/defs_openbsd_386.go
+++ b/src/runtime/defs_openbsd_386.go
@@ -30,6 +30,13 @@
 	_SA_RESTART = 0x2
 	_SA_ONSTACK = 0x1
 
+	_PTHREAD_CREATE_DETACHED = 0x1
+
+	_F_SETFD    = 0x2
+	_F_GETFL    = 0x3
+	_F_SETFL    = 0x4
+	_FD_CLOEXEC = 0x1
+
 	_SIGHUP    = 0x1
 	_SIGINT    = 0x2
 	_SIGQUIT   = 0x3
@@ -166,3 +173,10 @@
 	data   int64
 	udata  *byte
 }
+
+type pthread uintptr
+type pthreadattr uintptr
+type pthreadcond uintptr
+type pthreadcondattr uintptr
+type pthreadmutex uintptr
+type pthreadmutexattr uintptr
diff --git a/src/runtime/defs_openbsd_arm.go b/src/runtime/defs_openbsd_arm.go
index 170bb38..6f128c4 100644
--- a/src/runtime/defs_openbsd_arm.go
+++ b/src/runtime/defs_openbsd_arm.go
@@ -30,6 +30,13 @@
 	_SA_RESTART = 0x2
 	_SA_ONSTACK = 0x1
 
+	_PTHREAD_CREATE_DETACHED = 0x1
+
+	_F_SETFD    = 0x2
+	_F_GETFL    = 0x3
+	_F_SETFL    = 0x4
+	_FD_CLOEXEC = 0x1
+
 	_SIGHUP    = 0x1
 	_SIGINT    = 0x2
 	_SIGQUIT   = 0x3
@@ -174,3 +181,10 @@
 	udata     *byte
 	pad_cgo_1 [4]byte
 }
+
+type pthread uintptr
+type pthreadattr uintptr
+type pthreadcond uintptr
+type pthreadcondattr uintptr
+type pthreadmutex uintptr
+type pthreadmutexattr uintptr
diff --git a/src/runtime/defs_solaris.go b/src/runtime/defs_solaris.go
index 22df590..e644f9c 100644
--- a/src/runtime/defs_solaris.go
+++ b/src/runtime/defs_solaris.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_solaris_amd64.go b/src/runtime/defs_solaris_amd64.go
index 0493178..a0b3831 100644
--- a/src/runtime/defs_solaris_amd64.go
+++ b/src/runtime/defs_solaris_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/runtime/defs_windows.go b/src/runtime/defs_windows.go
index 43f358d..8d4e381 100644
--- a/src/runtime/defs_windows.go
+++ b/src/runtime/defs_windows.go
@@ -2,77 +2,83 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build ignore
-
-/*
-Input to cgo.
-
-GOARCH=amd64 go tool cgo -cdefs defs_windows.go > defs_windows_amd64.h
-GOARCH=386 go tool cgo -cdefs defs_windows.go > defs_windows_386.h
-*/
+// Windows architecture-independent definitions.
 
 package runtime
 
-/*
-#include <signal.h>
-#include <stdarg.h>
-#include <windef.h>
-#include <winbase.h>
-#include <wincon.h>
-
-#ifndef _X86_
-typedef struct {} FLOATING_SAVE_AREA;
-#endif
-#ifndef _AMD64_
-typedef struct {} M128A;
-#endif
-*/
-import "C"
-
 const (
-	PROT_NONE  = 0
-	PROT_READ  = 1
-	PROT_WRITE = 2
-	PROT_EXEC  = 4
+	_PROT_NONE  = 0
+	_PROT_READ  = 1
+	_PROT_WRITE = 2
+	_PROT_EXEC  = 4
 
-	MAP_ANON    = 1
-	MAP_PRIVATE = 2
+	_MAP_ANON    = 1
+	_MAP_PRIVATE = 2
 
-	DUPLICATE_SAME_ACCESS   = C.DUPLICATE_SAME_ACCESS
-	THREAD_PRIORITY_HIGHEST = C.THREAD_PRIORITY_HIGHEST
+	_DUPLICATE_SAME_ACCESS   = 0x2
+	_THREAD_PRIORITY_HIGHEST = 0x2
 
-	SIGINT              = C.SIGINT
-	SIGTERM             = C.SIGTERM
-	CTRL_C_EVENT        = C.CTRL_C_EVENT
-	CTRL_BREAK_EVENT    = C.CTRL_BREAK_EVENT
-	CTRL_CLOSE_EVENT    = C.CTRL_CLOSE_EVENT
-	CTRL_LOGOFF_EVENT   = C.CTRL_LOGOFF_EVENT
-	CTRL_SHUTDOWN_EVENT = C.CTRL_SHUTDOWN_EVENT
+	_SIGINT              = 0x2
+	_SIGTERM             = 0xF
+	_CTRL_C_EVENT        = 0x0
+	_CTRL_BREAK_EVENT    = 0x1
+	_CTRL_CLOSE_EVENT    = 0x2
+	_CTRL_LOGOFF_EVENT   = 0x5
+	_CTRL_SHUTDOWN_EVENT = 0x6
 
-	CONTEXT_CONTROL = C.CONTEXT_CONTROL
-	CONTEXT_FULL    = C.CONTEXT_FULL
+	_EXCEPTION_ACCESS_VIOLATION     = 0xc0000005
+	_EXCEPTION_BREAKPOINT           = 0x80000003
+	_EXCEPTION_ILLEGAL_INSTRUCTION  = 0xc000001d
+	_EXCEPTION_FLT_DENORMAL_OPERAND = 0xc000008d
+	_EXCEPTION_FLT_DIVIDE_BY_ZERO   = 0xc000008e
+	_EXCEPTION_FLT_INEXACT_RESULT   = 0xc000008f
+	_EXCEPTION_FLT_OVERFLOW         = 0xc0000091
+	_EXCEPTION_FLT_UNDERFLOW        = 0xc0000093
+	_EXCEPTION_INT_DIVIDE_BY_ZERO   = 0xc0000094
+	_EXCEPTION_INT_OVERFLOW         = 0xc0000095
 
-	EXCEPTION_ACCESS_VIOLATION     = C.STATUS_ACCESS_VIOLATION
-	EXCEPTION_BREAKPOINT           = C.STATUS_BREAKPOINT
-	EXCEPTION_FLT_DENORMAL_OPERAND = C.STATUS_FLOAT_DENORMAL_OPERAND
-	EXCEPTION_FLT_DIVIDE_BY_ZERO   = C.STATUS_FLOAT_DIVIDE_BY_ZERO
-	EXCEPTION_FLT_INEXACT_RESULT   = C.STATUS_FLOAT_INEXACT_RESULT
-	EXCEPTION_FLT_OVERFLOW         = C.STATUS_FLOAT_OVERFLOW
-	EXCEPTION_FLT_UNDERFLOW        = C.STATUS_FLOAT_UNDERFLOW
-	EXCEPTION_INT_DIVIDE_BY_ZERO   = C.STATUS_INTEGER_DIVIDE_BY_ZERO
-	EXCEPTION_INT_OVERFLOW         = C.STATUS_INTEGER_OVERFLOW
+	_INFINITE     = 0xffffffff
+	_WAIT_TIMEOUT = 0x102
 
-	INFINITE     = C.INFINITE
-	WAIT_TIMEOUT = C.WAIT_TIMEOUT
-
-	EXCEPTION_CONTINUE_EXECUTION = C.EXCEPTION_CONTINUE_EXECUTION
-	EXCEPTION_CONTINUE_SEARCH    = C.EXCEPTION_CONTINUE_SEARCH
+	_EXCEPTION_CONTINUE_EXECUTION = -0x1
+	_EXCEPTION_CONTINUE_SEARCH    = 0x0
 )
 
-type SystemInfo C.SYSTEM_INFO
-type ExceptionRecord C.EXCEPTION_RECORD
-type FloatingSaveArea C.FLOATING_SAVE_AREA
-type M128a C.M128A
-type Context C.CONTEXT
-type Overlapped C.OVERLAPPED
-type MemoryBasicInformation C.MEMORY_BASIC_INFORMATION
+type systeminfo struct {
+	anon0                       [4]byte
+	dwpagesize                  uint32
+	lpminimumapplicationaddress *byte
+	lpmaximumapplicationaddress *byte
+	dwactiveprocessormask       uintptr
+	dwnumberofprocessors        uint32
+	dwprocessortype             uint32
+	dwallocationgranularity     uint32
+	wprocessorlevel             uint16
+	wprocessorrevision          uint16
+}
+
+type exceptionrecord struct {
+	exceptioncode        uint32
+	exceptionflags       uint32
+	exceptionrecord      *exceptionrecord
+	exceptionaddress     *byte
+	numberparameters     uint32
+	exceptioninformation [15]uintptr
+}
+
+type overlapped struct {
+	internal     uintptr
+	internalhigh uintptr
+	anon0        [8]byte
+	hevent       *byte
+}
+
+type memoryBasicInformation struct {
+	baseAddress       uintptr
+	allocationBase    uintptr
+	allocationProtect uint32
+	regionSize        uintptr
+	state             uint32
+	protect           uint32
+	type_             uint32
+}
diff --git a/src/runtime/defs_windows_386.go b/src/runtime/defs_windows_386.go
index 3c5057b..37fe74c 100644
--- a/src/runtime/defs_windows_386.go
+++ b/src/runtime/defs_windows_386.go
@@ -1,69 +1,10 @@
-// created by cgo -cdefs and then converted to Go
-// cgo -cdefs defs_windows.go
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
 package runtime
 
-const (
-	_PROT_NONE  = 0
-	_PROT_READ  = 1
-	_PROT_WRITE = 2
-	_PROT_EXEC  = 4
-
-	_MAP_ANON    = 1
-	_MAP_PRIVATE = 2
-
-	_DUPLICATE_SAME_ACCESS   = 0x2
-	_THREAD_PRIORITY_HIGHEST = 0x2
-
-	_SIGINT              = 0x2
-	_SIGTERM             = 0xF
-	_CTRL_C_EVENT        = 0x0
-	_CTRL_BREAK_EVENT    = 0x1
-	_CTRL_CLOSE_EVENT    = 0x2
-	_CTRL_LOGOFF_EVENT   = 0x5
-	_CTRL_SHUTDOWN_EVENT = 0x6
-
-	_CONTEXT_CONTROL = 0x10001
-	_CONTEXT_FULL    = 0x10007
-
-	_EXCEPTION_ACCESS_VIOLATION     = 0xc0000005
-	_EXCEPTION_BREAKPOINT           = 0x80000003
-	_EXCEPTION_FLT_DENORMAL_OPERAND = 0xc000008d
-	_EXCEPTION_FLT_DIVIDE_BY_ZERO   = 0xc000008e
-	_EXCEPTION_FLT_INEXACT_RESULT   = 0xc000008f
-	_EXCEPTION_FLT_OVERFLOW         = 0xc0000091
-	_EXCEPTION_FLT_UNDERFLOW        = 0xc0000093
-	_EXCEPTION_INT_DIVIDE_BY_ZERO   = 0xc0000094
-	_EXCEPTION_INT_OVERFLOW         = 0xc0000095
-
-	_INFINITE     = 0xffffffff
-	_WAIT_TIMEOUT = 0x102
-
-	_EXCEPTION_CONTINUE_EXECUTION = -0x1
-	_EXCEPTION_CONTINUE_SEARCH    = 0x0
-)
-
-type systeminfo struct {
-	anon0                       [4]byte
-	dwpagesize                  uint32
-	lpminimumapplicationaddress *byte
-	lpmaximumapplicationaddress *byte
-	dwactiveprocessormask       uint32
-	dwnumberofprocessors        uint32
-	dwprocessortype             uint32
-	dwallocationgranularity     uint32
-	wprocessorlevel             uint16
-	wprocessorrevision          uint16
-}
-
-type exceptionrecord struct {
-	exceptioncode        uint32
-	exceptionflags       uint32
-	exceptionrecord      *exceptionrecord
-	exceptionaddress     *byte
-	numberparameters     uint32
-	exceptioninformation [15]uint32
-}
+const _CONTEXT_CONTROL = 0x10001
 
 type floatingsavearea struct {
 	controlword   uint32
@@ -130,20 +71,3 @@
 	print("fs      ", hex(r.segfs), "\n")
 	print("gs      ", hex(r.seggs), "\n")
 }
-
-type overlapped struct {
-	internal     uint32
-	internalhigh uint32
-	anon0        [8]byte
-	hevent       *byte
-}
-
-type memoryBasicInformation struct {
-	baseAddress       uintptr
-	allocationBase    uintptr
-	allocationProtect uint32
-	regionSize        uintptr
-	state             uint32
-	protect           uint32
-	type_             uint32
-}
diff --git a/src/runtime/defs_windows_amd64.go b/src/runtime/defs_windows_amd64.go
index ebb1506..ac636a6 100644
--- a/src/runtime/defs_windows_amd64.go
+++ b/src/runtime/defs_windows_amd64.go
@@ -1,70 +1,10 @@
-// created by cgo -cdefs and then converted to Go
-// cgo -cdefs defs_windows.go
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
 package runtime
 
-const (
-	_PROT_NONE  = 0
-	_PROT_READ  = 1
-	_PROT_WRITE = 2
-	_PROT_EXEC  = 4
-
-	_MAP_ANON    = 1
-	_MAP_PRIVATE = 2
-
-	_DUPLICATE_SAME_ACCESS   = 0x2
-	_THREAD_PRIORITY_HIGHEST = 0x2
-
-	_SIGINT              = 0x2
-	_SIGTERM             = 0xF
-	_CTRL_C_EVENT        = 0x0
-	_CTRL_BREAK_EVENT    = 0x1
-	_CTRL_CLOSE_EVENT    = 0x2
-	_CTRL_LOGOFF_EVENT   = 0x5
-	_CTRL_SHUTDOWN_EVENT = 0x6
-
-	_CONTEXT_CONTROL = 0x100001
-	_CONTEXT_FULL    = 0x10000b
-
-	_EXCEPTION_ACCESS_VIOLATION     = 0xc0000005
-	_EXCEPTION_BREAKPOINT           = 0x80000003
-	_EXCEPTION_FLT_DENORMAL_OPERAND = 0xc000008d
-	_EXCEPTION_FLT_DIVIDE_BY_ZERO   = 0xc000008e
-	_EXCEPTION_FLT_INEXACT_RESULT   = 0xc000008f
-	_EXCEPTION_FLT_OVERFLOW         = 0xc0000091
-	_EXCEPTION_FLT_UNDERFLOW        = 0xc0000093
-	_EXCEPTION_INT_DIVIDE_BY_ZERO   = 0xc0000094
-	_EXCEPTION_INT_OVERFLOW         = 0xc0000095
-
-	_INFINITE     = 0xffffffff
-	_WAIT_TIMEOUT = 0x102
-
-	_EXCEPTION_CONTINUE_EXECUTION = -0x1
-	_EXCEPTION_CONTINUE_SEARCH    = 0x0
-)
-
-type systeminfo struct {
-	anon0                       [4]byte
-	dwpagesize                  uint32
-	lpminimumapplicationaddress *byte
-	lpmaximumapplicationaddress *byte
-	dwactiveprocessormask       uint64
-	dwnumberofprocessors        uint32
-	dwprocessortype             uint32
-	dwallocationgranularity     uint32
-	wprocessorlevel             uint16
-	wprocessorrevision          uint16
-}
-
-type exceptionrecord struct {
-	exceptioncode        uint32
-	exceptionflags       uint32
-	exceptionrecord      *exceptionrecord
-	exceptionaddress     *byte
-	numberparameters     uint32
-	pad_cgo_0            [4]byte
-	exceptioninformation [15]uint64
-}
+const _CONTEXT_CONTROL = 0x100001
 
 type m128a struct {
 	low  uint64
@@ -123,7 +63,7 @@
 func (c *context) ip() uintptr { return uintptr(c.rip) }
 func (c *context) sp() uintptr { return uintptr(c.rsp) }
 
-// Amd64 does not have link register, so this returns 0.
+// AMD64 does not have link register, so this returns 0.
 func (c *context) lr() uintptr      { return 0 }
 func (c *context) set_lr(x uintptr) {}
 
@@ -152,20 +92,3 @@
 	print("fs      ", hex(r.segfs), "\n")
 	print("gs      ", hex(r.seggs), "\n")
 }
-
-type overlapped struct {
-	internal     uint64
-	internalhigh uint64
-	anon0        [8]byte
-	hevent       *byte
-}
-
-type memoryBasicInformation struct {
-	baseAddress       uintptr
-	allocationBase    uintptr
-	allocationProtect uint32
-	regionSize        uintptr
-	state             uint32
-	protect           uint32
-	type_             uint32
-}
diff --git a/src/runtime/defs_windows_arm.go b/src/runtime/defs_windows_arm.go
index b275b05..370470e 100644
--- a/src/runtime/defs_windows_arm.go
+++ b/src/runtime/defs_windows_arm.go
@@ -4,67 +4,13 @@
 
 package runtime
 
-const (
-	_PROT_NONE  = 0
-	_PROT_READ  = 1
-	_PROT_WRITE = 2
-	_PROT_EXEC  = 4
-
-	_MAP_ANON    = 1
-	_MAP_PRIVATE = 2
-
-	_DUPLICATE_SAME_ACCESS   = 0x2
-	_THREAD_PRIORITY_HIGHEST = 0x2
-
-	_SIGINT              = 0x2
-	_SIGTERM             = 0xF
-	_CTRL_C_EVENT        = 0x0
-	_CTRL_BREAK_EVENT    = 0x1
-	_CTRL_CLOSE_EVENT    = 0x2
-	_CTRL_LOGOFF_EVENT   = 0x5
-	_CTRL_SHUTDOWN_EVENT = 0x6
-
-	_CONTEXT_CONTROL = 0x10001
-	_CONTEXT_FULL    = 0x10007
-
-	_EXCEPTION_ACCESS_VIOLATION     = 0xc0000005
-	_EXCEPTION_BREAKPOINT           = 0x80000003
-	_EXCEPTION_FLT_DENORMAL_OPERAND = 0xc000008d
-	_EXCEPTION_FLT_DIVIDE_BY_ZERO   = 0xc000008e
-	_EXCEPTION_FLT_INEXACT_RESULT   = 0xc000008f
-	_EXCEPTION_FLT_OVERFLOW         = 0xc0000091
-	_EXCEPTION_FLT_UNDERFLOW        = 0xc0000093
-	_EXCEPTION_INT_DIVIDE_BY_ZERO   = 0xc0000094
-	_EXCEPTION_INT_OVERFLOW         = 0xc0000095
-
-	_INFINITE     = 0xffffffff
-	_WAIT_TIMEOUT = 0x102
-
-	_EXCEPTION_CONTINUE_EXECUTION = -0x1
-	_EXCEPTION_CONTINUE_SEARCH    = 0x0
-)
-
-type systeminfo struct {
-	anon0                       [4]byte
-	dwpagesize                  uint32
-	lpminimumapplicationaddress *byte
-	lpmaximumapplicationaddress *byte
-	dwactiveprocessormask       uint32
-	dwnumberofprocessors        uint32
-	dwprocessortype             uint32
-	dwallocationgranularity     uint32
-	wprocessorlevel             uint16
-	wprocessorrevision          uint16
-}
-
-type exceptionrecord struct {
-	exceptioncode        uint32
-	exceptionflags       uint32
-	exceptionrecord      *exceptionrecord
-	exceptionaddress     *byte
-	numberparameters     uint32
-	exceptioninformation [15]uint32
-}
+// NOTE(rsc): _CONTEXT_CONTROL is actually 0x200001 and should include PC, SP, and LR.
+// However, empirically, LR doesn't come along on Windows 10
+// unless you also set _CONTEXT_INTEGER (0x200002).
+// Without LR, we skip over the next-to-bottom function in profiles
+// when the bottom function is frameless.
+// So we set both here, to make a working _CONTEXT_CONTROL.
+const _CONTEXT_CONTROL = 0x200003
 
 type neon128 struct {
 	low  uint64
@@ -132,23 +78,6 @@
 	print("cpsr ", hex(r.cpsr), "\n")
 }
 
-type overlapped struct {
-	internal     uint32
-	internalhigh uint32
-	anon0        [8]byte
-	hevent       *byte
-}
-
-type memoryBasicInformation struct {
-	baseAddress       uintptr
-	allocationBase    uintptr
-	allocationProtect uint32
-	regionSize        uintptr
-	state             uint32
-	protect           uint32
-	type_             uint32
-}
-
 func stackcheck() {
 	// TODO: not implemented on ARM
 }
diff --git a/src/runtime/defs_windows_arm64.go b/src/runtime/defs_windows_arm64.go
new file mode 100644
index 0000000..9ccce46
--- /dev/null
+++ b/src/runtime/defs_windows_arm64.go
@@ -0,0 +1,83 @@
+// 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 runtime
+
+// NOTE(rsc): _CONTEXT_CONTROL is actually 0x400001 and should include PC, SP, and LR.
+// However, empirically, LR doesn't come along on Windows 10
+// unless you also set _CONTEXT_INTEGER (0x400002).
+// Without LR, we skip over the next-to-bottom function in profiles
+// when the bottom function is frameless.
+// So we set both here, to make a working _CONTEXT_CONTROL.
+const _CONTEXT_CONTROL = 0x400003
+
+type neon128 struct {
+	low  uint64
+	high int64
+}
+
+// See https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-arm64_nt_context
+type context struct {
+	contextflags uint32
+	cpsr         uint32
+	x            [31]uint64 // fp is x[29], lr is x[30]
+	xsp          uint64
+	pc           uint64
+	v            [32]neon128
+	fpcr         uint32
+	fpsr         uint32
+	bcr          [8]uint32
+	bvr          [8]uint64
+	wcr          [2]uint32
+	wvr          [2]uint64
+}
+
+func (c *context) ip() uintptr { return uintptr(c.pc) }
+func (c *context) sp() uintptr { return uintptr(c.xsp) }
+func (c *context) lr() uintptr { return uintptr(c.x[30]) }
+
+func (c *context) set_ip(x uintptr) { c.pc = uint64(x) }
+func (c *context) set_sp(x uintptr) { c.xsp = uint64(x) }
+func (c *context) set_lr(x uintptr) { c.x[30] = uint64(x) }
+
+func dumpregs(r *context) {
+	print("r0   ", hex(r.x[0]), "\n")
+	print("r1   ", hex(r.x[1]), "\n")
+	print("r2   ", hex(r.x[2]), "\n")
+	print("r3   ", hex(r.x[3]), "\n")
+	print("r4   ", hex(r.x[4]), "\n")
+	print("r5   ", hex(r.x[5]), "\n")
+	print("r6   ", hex(r.x[6]), "\n")
+	print("r7   ", hex(r.x[7]), "\n")
+	print("r8   ", hex(r.x[8]), "\n")
+	print("r9   ", hex(r.x[9]), "\n")
+	print("r10  ", hex(r.x[10]), "\n")
+	print("r11  ", hex(r.x[11]), "\n")
+	print("r12  ", hex(r.x[12]), "\n")
+	print("r13  ", hex(r.x[13]), "\n")
+	print("r14  ", hex(r.x[14]), "\n")
+	print("r15  ", hex(r.x[15]), "\n")
+	print("r16  ", hex(r.x[16]), "\n")
+	print("r17  ", hex(r.x[17]), "\n")
+	print("r18  ", hex(r.x[18]), "\n")
+	print("r19  ", hex(r.x[19]), "\n")
+	print("r20  ", hex(r.x[20]), "\n")
+	print("r21  ", hex(r.x[21]), "\n")
+	print("r22  ", hex(r.x[22]), "\n")
+	print("r23  ", hex(r.x[23]), "\n")
+	print("r24  ", hex(r.x[24]), "\n")
+	print("r25  ", hex(r.x[25]), "\n")
+	print("r26  ", hex(r.x[26]), "\n")
+	print("r27  ", hex(r.x[27]), "\n")
+	print("r28  ", hex(r.x[28]), "\n")
+	print("r29  ", hex(r.x[29]), "\n")
+	print("lr   ", hex(r.x[30]), "\n")
+	print("sp   ", hex(r.xsp), "\n")
+	print("pc   ", hex(r.pc), "\n")
+	print("cpsr ", hex(r.cpsr), "\n")
+}
+
+func stackcheck() {
+	// TODO: not implemented on ARM
+}
diff --git a/src/runtime/duff_amd64.s b/src/runtime/duff_amd64.s
index 2ff5bf6..df010f5 100644
--- a/src/runtime/duff_amd64.s
+++ b/src/runtime/duff_amd64.s
@@ -5,100 +5,100 @@
 #include "textflag.h"
 
 TEXT runtime·duffzero<ABIInternal>(SB), NOSPLIT, $0-0
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
-	MOVUPS	X0,(DI)
-	MOVUPS	X0,16(DI)
-	MOVUPS	X0,32(DI)
-	MOVUPS	X0,48(DI)
+	MOVUPS	X15,(DI)
+	MOVUPS	X15,16(DI)
+	MOVUPS	X15,32(DI)
+	MOVUPS	X15,48(DI)
 	LEAQ	64(DI),DI
 
 	RET
diff --git a/src/runtime/duff_mips64x.s b/src/runtime/duff_mips64x.s
index c4e04cc..a897d7f 100644
--- a/src/runtime/duff_mips64x.s
+++ b/src/runtime/duff_mips64x.s
@@ -2,6 +2,7 @@
 // Run go generate from src/runtime to update.
 // See mkduff.go for comments.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "textflag.h"
diff --git a/src/runtime/duff_ppc64x.s b/src/runtime/duff_ppc64x.s
index d6b89ba..d4e3b40 100644
--- a/src/runtime/duff_ppc64x.s
+++ b/src/runtime/duff_ppc64x.s
@@ -2,6 +2,7 @@
 // Run go generate from src/runtime to update.
 // See mkduff.go for comments.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "textflag.h"
diff --git a/src/runtime/env_posix.go b/src/runtime/env_posix.go
index af353bb..95517b2 100644
--- a/src/runtime/env_posix.go
+++ b/src/runtime/env_posix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows || plan9
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows plan9
 
 package runtime
diff --git a/src/runtime/error.go b/src/runtime/error.go
index 9e6cdf3..91f83ae 100644
--- a/src/runtime/error.go
+++ b/src/runtime/error.go
@@ -134,6 +134,7 @@
 	boundsSlice3B    // s[?:x:y], 0 <= x <= y failed (but boundsSlice3A didn't happen)
 	boundsSlice3C    // s[x:y:?], 0 <= x <= y failed (but boundsSlice3A/B didn't happen)
 
+	boundsConvert // (*[x]T)(s), 0 <= x <= len(s) failed
 	// Note: in the above, len(s) and cap(s) are stored in y
 )
 
@@ -149,6 +150,7 @@
 	boundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",
 	boundsSlice3B:    "slice bounds out of range [:%x:%y]",
 	boundsSlice3C:    "slice bounds out of range [%x:%y:]",
+	boundsConvert:    "cannot convert slice with length %y to pointer to array with length %x",
 }
 
 // boundsNegErrorFmts are overriding formats if x is negative. In this case there's no need to report y.
diff --git a/src/runtime/example_test.go b/src/runtime/example_test.go
index e4912a5..dcb8f77 100644
--- a/src/runtime/example_test.go
+++ b/src/runtime/example_test.go
@@ -12,12 +12,15 @@
 
 func ExampleFrames() {
 	c := func() {
-		// Ask runtime.Callers for up to 10 pcs, including runtime.Callers itself.
+		// Ask runtime.Callers for up to 10 PCs, including runtime.Callers itself.
 		pc := make([]uintptr, 10)
 		n := runtime.Callers(0, pc)
 		if n == 0 {
-			// No pcs available. Stop now.
-			// This can happen if the first argument to runtime.Callers is large.
+			// No PCs available. This can happen if the first argument to
+			// runtime.Callers is large.
+			//
+			// Return now to avoid processing the zero Frame that would
+			// otherwise be returned by frames.Next below.
 			return
 		}
 
@@ -25,9 +28,12 @@
 		frames := runtime.CallersFrames(pc)
 
 		// Loop to get frames.
-		// A fixed number of pcs can expand to an indefinite number of Frames.
+		// A fixed number of PCs can expand to an indefinite number of Frames.
 		for {
 			frame, more := frames.Next()
+
+			// Process this frame.
+			//
 			// To keep this example's output stable
 			// even if there are changes in the testing package,
 			// stop unwinding when we leave package runtime.
@@ -35,6 +41,8 @@
 				break
 			}
 			fmt.Printf("- more:%v | %s\n", more, frame.Function)
+
+			// Check whether there are more frames to process after this one.
 			if !more {
 				break
 			}
diff --git a/src/runtime/export_debug_regabiargs_off_test.go b/src/runtime/export_debug_regabiargs_off_test.go
new file mode 100644
index 0000000..5009003
--- /dev/null
+++ b/src/runtime/export_debug_regabiargs_off_test.go
@@ -0,0 +1,16 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && linux && !goexperiment.regabiargs
+// +build amd64,linux,!goexperiment.regabiargs
+
+package runtime
+
+import "internal/abi"
+
+func storeRegArgs(dst *sigcontext, src *abi.RegArgs) {
+}
+
+func loadRegArgs(dst *abi.RegArgs, src *sigcontext) {
+}
diff --git a/src/runtime/export_debug_regabiargs_on_test.go b/src/runtime/export_debug_regabiargs_on_test.go
new file mode 100644
index 0000000..e1b72ef
--- /dev/null
+++ b/src/runtime/export_debug_regabiargs_on_test.go
@@ -0,0 +1,46 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && linux && goexperiment.regabiargs
+// +build amd64,linux,goexperiment.regabiargs
+
+package runtime
+
+import "internal/abi"
+
+// storeRegArgs sets up argument registers in the signal
+// context state from an abi.RegArgs.
+//
+// Both src and dst must be non-nil.
+func storeRegArgs(dst *sigcontext, src *abi.RegArgs) {
+	dst.rax = uint64(src.Ints[0])
+	dst.rbx = uint64(src.Ints[1])
+	dst.rcx = uint64(src.Ints[2])
+	dst.rdi = uint64(src.Ints[3])
+	dst.rsi = uint64(src.Ints[4])
+	dst.r8 = uint64(src.Ints[5])
+	dst.r9 = uint64(src.Ints[6])
+	dst.r10 = uint64(src.Ints[7])
+	dst.r11 = uint64(src.Ints[8])
+	for i := range src.Floats {
+		dst.fpstate._xmm[i].element[0] = uint32(src.Floats[i] >> 0)
+		dst.fpstate._xmm[i].element[1] = uint32(src.Floats[i] >> 32)
+	}
+}
+
+func loadRegArgs(dst *abi.RegArgs, src *sigcontext) {
+	dst.Ints[0] = uintptr(src.rax)
+	dst.Ints[1] = uintptr(src.rbx)
+	dst.Ints[2] = uintptr(src.rcx)
+	dst.Ints[3] = uintptr(src.rdi)
+	dst.Ints[4] = uintptr(src.rsi)
+	dst.Ints[5] = uintptr(src.r8)
+	dst.Ints[6] = uintptr(src.r9)
+	dst.Ints[7] = uintptr(src.r10)
+	dst.Ints[8] = uintptr(src.r11)
+	for i := range dst.Floats {
+		dst.Floats[i] = uint64(src.fpstate._xmm[i].element[0]) << 0
+		dst.Floats[i] |= uint64(src.fpstate._xmm[i].element[1]) << 32
+	}
+}
diff --git a/src/runtime/export_debug_test.go b/src/runtime/export_debug_test.go
index ed4242e..fe4c904 100644
--- a/src/runtime/export_debug_test.go
+++ b/src/runtime/export_debug_test.go
@@ -2,25 +2,28 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build amd64
-// +build linux
+//go:build amd64 && linux
+// +build amd64,linux
 
 package runtime
 
 import (
+	"internal/abi"
 	"runtime/internal/sys"
 	"unsafe"
 )
 
-// InjectDebugCall injects a debugger call to fn into g. args must be
-// a pointer to a valid call frame (including arguments and return
-// space) for fn, or nil. tkill must be a function that will send
-// SIGTRAP to thread ID tid. gp must be locked to its OS thread and
+// InjectDebugCall injects a debugger call to fn into g. regArgs must
+// contain any arguments to fn that are passed in registers, according
+// to the internal Go ABI. It may be nil if no arguments are passed in
+// registers to fn. args must be a pointer to a valid call frame (including
+// arguments and return space) for fn, or nil. tkill must be a function that
+// will send SIGTRAP to thread ID tid. gp must be locked to its OS thread and
 // running.
 //
 // On success, InjectDebugCall returns the panic value of fn or nil.
 // If fn did not panic, its results will be available in args.
-func InjectDebugCall(gp *g, fn, args interface{}, tkill func(tid int) error, returnOnUnsafePoint bool) (interface{}, error) {
+func InjectDebugCall(gp *g, fn interface{}, regArgs *abi.RegArgs, stackArgs interface{}, tkill func(tid int) error, returnOnUnsafePoint bool) (interface{}, error) {
 	if gp.lockedm == 0 {
 		return nil, plainError("goroutine not locked to thread")
 	}
@@ -36,7 +39,7 @@
 	}
 	fv := (*funcval)(f.data)
 
-	a := efaceOf(&args)
+	a := efaceOf(&stackArgs)
 	if a._type != nil && a._type.kind&kindMask != kindPtr {
 		return nil, plainError("args must be a pointer or nil")
 	}
@@ -51,7 +54,7 @@
 	// gp may not be running right now, but we can still get the M
 	// it will run on since it's locked.
 	h.mp = gp.lockedm.ptr()
-	h.fv, h.argp, h.argSize = fv, argp, argSize
+	h.fv, h.regArgs, h.argp, h.argSize = fv, regArgs, argp, argSize
 	h.handleF = h.handle // Avoid allocating closure during signal
 
 	defer func() { testSigtrap = nil }()
@@ -91,6 +94,7 @@
 	gp      *g
 	mp      *m
 	fv      *funcval
+	regArgs *abi.RegArgs
 	argp    unsafe.Pointer
 	argSize uintptr
 	panic   interface{}
@@ -120,8 +124,8 @@
 		h.savedRegs = *ctxt.regs()
 		h.savedFP = *h.savedRegs.fpstate
 		h.savedRegs.fpstate = nil
-		// Set PC to debugCallV1.
-		ctxt.set_rip(uint64(funcPC(debugCallV1)))
+		// Set PC to debugCallV2.
+		ctxt.set_rip(uint64(funcPC(debugCallV2)))
 		// Call injected. Switch to the debugCall protocol.
 		testSigtrap = h.handleF
 	case _Grunnable:
@@ -153,22 +157,28 @@
 		return false
 	}
 
-	switch status := ctxt.rax(); status {
+	switch status := ctxt.r12(); status {
 	case 0:
-		// Frame is ready. Copy the arguments to the frame.
+		// Frame is ready. Copy the arguments to the frame and to registers.
 		sp := ctxt.rsp()
 		memmove(unsafe.Pointer(uintptr(sp)), h.argp, h.argSize)
+		if h.regArgs != nil {
+			storeRegArgs(ctxt.regs(), h.regArgs)
+		}
 		// Push return PC.
 		sp -= sys.PtrSize
 		ctxt.set_rsp(sp)
 		*(*uint64)(unsafe.Pointer(uintptr(sp))) = ctxt.rip()
 		// Set PC to call and context register.
 		ctxt.set_rip(uint64(h.fv.fn))
-		ctxt.regs().rcx = uint64(uintptr(unsafe.Pointer(h.fv)))
+		ctxt.regs().rdx = uint64(uintptr(unsafe.Pointer(h.fv)))
 	case 1:
-		// Function returned. Copy frame back out.
+		// Function returned. Copy frame and result registers back out.
 		sp := ctxt.rsp()
 		memmove(h.argp, unsafe.Pointer(uintptr(sp)), h.argSize)
+		if h.regArgs != nil {
+			loadRegArgs(h.regArgs, ctxt.regs())
+		}
 	case 2:
 		// Function panicked. Copy panic out.
 		sp := ctxt.rsp()
@@ -191,7 +201,7 @@
 		// Done
 		notewakeup(&h.done)
 	default:
-		h.err = plainError("unexpected debugCallV1 status")
+		h.err = plainError("unexpected debugCallV2 status")
 		notewakeup(&h.done)
 	}
 	// Resume execution.
diff --git a/src/runtime/export_futex_test.go b/src/runtime/export_futex_test.go
index a727a93..34c970d 100644
--- a/src/runtime/export_futex_test.go
+++ b/src/runtime/export_futex_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || linux
 // +build dragonfly freebsd linux
 
 package runtime
diff --git a/src/runtime/export_mmap_test.go b/src/runtime/export_mmap_test.go
index aeaf37f..bf4a815 100644
--- a/src/runtime/export_mmap_test.go
+++ b/src/runtime/export_mmap_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 // Export guts for testing.
diff --git a/src/runtime/export_pipe2_test.go b/src/runtime/export_pipe2_test.go
index 9d580d3..26d8b7d 100644
--- a/src/runtime/export_pipe2_test.go
+++ b/src/runtime/export_pipe2_test.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build freebsd linux netbsd openbsd solaris
+//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris
+// +build dragonfly freebsd linux netbsd openbsd solaris
 
 package runtime
 
diff --git a/src/runtime/export_pipe_test.go b/src/runtime/export_pipe_test.go
index 8f66770..a0c6c04 100644
--- a/src/runtime/export_pipe_test.go
+++ b/src/runtime/export_pipe_test.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin dragonfly
+//go:build aix || darwin
+// +build aix darwin
 
 package runtime
 
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index 22fef31..c8d01fb 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -46,6 +46,14 @@
 var Memmove = memmove
 var MemclrNoHeapPointers = memclrNoHeapPointers
 
+var LockPartialOrder = lockPartialOrder
+
+type LockRank lockRank
+
+func (l LockRank) String() string {
+	return lockRank(l).String()
+}
+
 const PreemptMSupported = preemptMSupported
 
 type LFNode struct {
@@ -139,28 +147,40 @@
 	}
 }
 
+// Temporary to enable register ABI bringup.
+// TODO(register args): convert back to local variables in RunSchedLocalQueueEmptyTest that
+// get passed to the "go" stmts there.
+var RunSchedLocalQueueEmptyState struct {
+	done  chan bool
+	ready *uint32
+	p     *p
+}
+
 func RunSchedLocalQueueEmptyTest(iters int) {
 	// Test that runq is not spuriously reported as empty.
 	// Runq emptiness affects scheduling decisions and spurious emptiness
 	// can lead to underutilization (both runnable Gs and idle Ps coexist
 	// for arbitrary long time).
 	done := make(chan bool, 1)
+	RunSchedLocalQueueEmptyState.done = done
 	p := new(p)
+	RunSchedLocalQueueEmptyState.p = p
 	gs := make([]g, 2)
 	ready := new(uint32)
+	RunSchedLocalQueueEmptyState.ready = ready
 	for i := 0; i < iters; i++ {
 		*ready = 0
 		next0 := (i & 1) == 0
 		next1 := (i & 2) == 0
 		runqput(p, &gs[0], next0)
 		go func() {
-			for atomic.Xadd(ready, 1); atomic.Load(ready) != 2; {
+			for atomic.Xadd(RunSchedLocalQueueEmptyState.ready, 1); atomic.Load(RunSchedLocalQueueEmptyState.ready) != 2; {
 			}
-			if runqempty(p) {
-				println("next:", next0, next1)
+			if runqempty(RunSchedLocalQueueEmptyState.p) {
+				//println("next:", next0, next1)
 				throw("queue is empty")
 			}
-			done <- true
+			RunSchedLocalQueueEmptyState.done <- true
 		}()
 		for atomic.Xadd(ready, 1); atomic.Load(ready) != 2; {
 		}
@@ -200,8 +220,6 @@
 	return
 }
 
-type Uintreg sys.Uintreg
-
 var Open = open
 var Close = closefd
 var Read = read
@@ -375,7 +393,7 @@
 			bySize[i].Mallocs += uint64(m.smallFreeCount[i])
 			smallFree += uint64(m.smallFreeCount[i]) * uint64(class_to_size[i])
 		}
-		slow.Frees += memstats.tinyallocs + uint64(m.largeFreeCount)
+		slow.Frees += uint64(m.tinyAllocCount) + uint64(m.largeFreeCount)
 		slow.Mallocs += slow.Frees
 
 		slow.TotalAlloc = slow.Alloc + uint64(m.largeFree) + smallFree
@@ -398,9 +416,6 @@
 			slow.HeapReleased += uint64(pg) * pageSize
 		}
 
-		// Unused space in the current arena also counts as released space.
-		slow.HeapReleased += uint64(mheap_.curArena.end - mheap_.curArena.base)
-
 		getg().m.mallocing--
 	})
 
@@ -1133,31 +1148,6 @@
 	return atomic.Load(&root.nwait)
 }
 
-// MapHashCheck computes the hash of the key k for the map m, twice.
-// Method 1 uses the built-in hasher for the map.
-// Method 2 uses the typehash function (the one used by reflect).
-// Returns the two hash values, which should always be equal.
-func MapHashCheck(m interface{}, k interface{}) (uintptr, uintptr) {
-	// Unpack m.
-	mt := (*maptype)(unsafe.Pointer(efaceOf(&m)._type))
-	mh := (*hmap)(efaceOf(&m).data)
-
-	// Unpack k.
-	kt := efaceOf(&k)._type
-	var p unsafe.Pointer
-	if isDirectIface(kt) {
-		q := efaceOf(&k).data
-		p = unsafe.Pointer(&q)
-	} else {
-		p = efaceOf(&k).data
-	}
-
-	// Compute the hash functions.
-	x := mt.hasher(noescape(p), uintptr(mh.hash0))
-	y := typehash(kt, noescape(p), uintptr(mh.hash0))
-	return x, y
-}
-
 // mspan wrapper for testing.
 //go:notinheap
 type MSpan mspan
@@ -1214,3 +1204,43 @@
 func (th *TimeHistogram) Record(duration int64) {
 	(*timeHistogram)(th).record(duration)
 }
+
+func SetIntArgRegs(a int) int {
+	lock(&finlock)
+	old := intArgRegs
+	if a >= 0 {
+		intArgRegs = a
+	}
+	unlock(&finlock)
+	return old
+}
+
+func FinalizerGAsleep() bool {
+	lock(&finlock)
+	result := fingwait
+	unlock(&finlock)
+	return result
+}
+
+// For GCTestMoveStackOnNextCall, it's important not to introduce an
+// extra layer of call, since then there's a return before the "real"
+// next call.
+var GCTestMoveStackOnNextCall = gcTestMoveStackOnNextCall
+
+// For GCTestIsReachable, it's important that we do this as a call so
+// escape analysis can see through it.
+func GCTestIsReachable(ptrs ...unsafe.Pointer) (mask uint64) {
+	return gcTestIsReachable(ptrs...)
+}
+
+// For GCTestPointerClass, it's important that we do this as a call so
+// escape analysis can see through it.
+//
+// This is nosplit because gcTestPointerClass is.
+//
+//go:nosplit
+func GCTestPointerClass(p unsafe.Pointer) string {
+	return gcTestPointerClass(p)
+}
+
+const Raceenabled = raceenabled
diff --git a/src/runtime/export_unix_test.go b/src/runtime/export_unix_test.go
index 307c63f..215e234 100644
--- a/src/runtime/export_unix_test.go
+++ b/src/runtime/export_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package runtime
diff --git a/src/runtime/extern.go b/src/runtime/extern.go
index dacdf4f..48e1e66 100644
--- a/src/runtime/extern.go
+++ b/src/runtime/extern.go
@@ -110,8 +110,6 @@
 	with a trivial allocator that obtains memory from the operating system and
 	never reclaims any memory.
 
-	scavenge: scavenge=1 enables debugging mode of heap scavenger.
-
 	scavtrace: setting scavtrace=1 causes the runtime to emit a single line to standard
 	error, roughly once per GC cycle, summarizing the amount of work done by the
 	scavenger as well as the total amount of memory returned to the operating system
@@ -229,6 +227,8 @@
 	return callers(skip, pc)
 }
 
+var defaultGOROOT string // set by cmd/link
+
 // 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.
@@ -237,14 +237,24 @@
 	if s != "" {
 		return s
 	}
-	return sys.DefaultGoroot
+	return defaultGOROOT
 }
 
+// buildVersion is the Go tree's version string at build time.
+//
+// If any GOEXPERIMENTs are set to non-default values, it will include
+// "X:<GOEXPERIMENT>".
+//
+// This is set by the linker.
+//
+// This is accessed by "go version <binary>".
+var buildVersion string
+
 // Version returns the Go tree's version string.
 // It is either the commit hash and date at the time of the build or,
 // when possible, a release tag like "go1.3".
 func Version() string {
-	return sys.TheVersion
+	return buildVersion
 }
 
 // GOOS is the running program's operating system target:
diff --git a/src/runtime/funcdata.h b/src/runtime/funcdata.h
index 798dbac..1002b18 100644
--- a/src/runtime/funcdata.h
+++ b/src/runtime/funcdata.h
@@ -17,6 +17,7 @@
 #define FUNCDATA_StackObjects 2
 #define FUNCDATA_InlTree 3
 #define FUNCDATA_OpenCodedDeferInfo 4 /* info for func with open-coded defers */
+#define FUNCDATA_ArgInfo 5
 
 // Pseudo-assembly statements.
 
diff --git a/src/runtime/futex_test.go b/src/runtime/futex_test.go
index 3051bd5..10a7353 100644
--- a/src/runtime/futex_test.go
+++ b/src/runtime/futex_test.go
@@ -6,6 +6,7 @@
 // The race detector emits calls to split stack functions so it breaks
 // the test.
 
+//go:build (dragonfly || freebsd || linux) && !race
 // +build dragonfly freebsd linux
 // +build !race
 
diff --git a/src/runtime/gc_test.go b/src/runtime/gc_test.go
index 7870f31..5e7c6c5 100644
--- a/src/runtime/gc_test.go
+++ b/src/runtime/gc_test.go
@@ -202,6 +202,108 @@
 	}
 }
 
+func TestGCTestMoveStackOnNextCall(t *testing.T) {
+	t.Parallel()
+	var onStack int
+	// GCTestMoveStackOnNextCall can fail in rare cases if there's
+	// a preemption. This won't happen many times in quick
+	// succession, so just retry a few times.
+	for retry := 0; retry < 5; retry++ {
+		runtime.GCTestMoveStackOnNextCall()
+		if moveStackCheck(t, &onStack, uintptr(unsafe.Pointer(&onStack))) {
+			// Passed.
+			return
+		}
+	}
+	t.Fatal("stack did not move")
+}
+
+// This must not be inlined because the point is to force a stack
+// growth check and move the stack.
+//
+//go:noinline
+func moveStackCheck(t *testing.T, new *int, old uintptr) bool {
+	// new should have been updated by the stack move;
+	// old should not have.
+
+	// Capture new's value before doing anything that could
+	// further move the stack.
+	new2 := uintptr(unsafe.Pointer(new))
+
+	t.Logf("old stack pointer %x, new stack pointer %x", old, new2)
+	if new2 == old {
+		// Check that we didn't screw up the test's escape analysis.
+		if cls := runtime.GCTestPointerClass(unsafe.Pointer(new)); cls != "stack" {
+			t.Fatalf("test bug: new (%#x) should be a stack pointer, not %s", new2, cls)
+		}
+		// This was a real failure.
+		return false
+	}
+	return true
+}
+
+func TestGCTestMoveStackRepeatedly(t *testing.T) {
+	// Move the stack repeatedly to make sure we're not doubling
+	// it each time.
+	for i := 0; i < 100; i++ {
+		runtime.GCTestMoveStackOnNextCall()
+		moveStack1(false)
+	}
+}
+
+//go:noinline
+func moveStack1(x bool) {
+	// Make sure this function doesn't get auto-nosplit.
+	if x {
+		println("x")
+	}
+}
+
+func TestGCTestIsReachable(t *testing.T) {
+	var all, half []unsafe.Pointer
+	var want uint64
+	for i := 0; i < 16; i++ {
+		// The tiny allocator muddies things, so we use a
+		// scannable type.
+		p := unsafe.Pointer(new(*int))
+		all = append(all, p)
+		if i%2 == 0 {
+			half = append(half, p)
+			want |= 1 << i
+		}
+	}
+
+	got := runtime.GCTestIsReachable(all...)
+	if want != got {
+		t.Fatalf("did not get expected reachable set; want %b, got %b", want, got)
+	}
+	runtime.KeepAlive(half)
+}
+
+var pointerClassSink *int
+var pointerClassData = 42
+
+func TestGCTestPointerClass(t *testing.T) {
+	t.Parallel()
+	check := func(p unsafe.Pointer, want string) {
+		t.Helper()
+		got := runtime.GCTestPointerClass(p)
+		if got != want {
+			// Convert the pointer to a uintptr to avoid
+			// escaping it.
+			t.Errorf("for %#x, want class %s, got %s", uintptr(p), want, got)
+		}
+	}
+	var onStack int
+	var notOnStack int
+	pointerClassSink = &notOnStack
+	check(unsafe.Pointer(&onStack), "stack")
+	check(unsafe.Pointer(&notOnStack), "heap")
+	check(unsafe.Pointer(&pointerClassSink), "bss")
+	check(unsafe.Pointer(&pointerClassData), "data")
+	check(nil, "other")
+}
+
 func BenchmarkSetTypePtr(b *testing.B) {
 	benchSetType(b, new(*byte))
 }
diff --git a/src/runtime/hash32.go b/src/runtime/hash32.go
index 966f70e..7c22c76 100644
--- a/src/runtime/hash32.go
+++ b/src/runtime/hash32.go
@@ -3,110 +3,61 @@
 // license that can be found in the LICENSE file.
 
 // Hashing algorithm inspired by
-//   xxhash: https://code.google.com/p/xxhash/
-// cityhash: https://code.google.com/p/cityhash/
+// wyhash: https://github.com/wangyi-fudan/wyhash/blob/ceb019b530e2c1c14d70b79bfa2bc49de7d95bc1/Modern%20Non-Cryptographic%20Hash%20Function%20and%20Pseudorandom%20Number%20Generator.pdf
 
+//go:build 386 || arm || mips || mipsle
 // +build 386 arm mips mipsle
 
 package runtime
 
 import "unsafe"
 
-const (
-	// Constants for multiplication: four random odd 32-bit numbers.
-	m1 = 3168982561
-	m2 = 3339683297
-	m3 = 832293441
-	m4 = 2336365089
-)
-
-func memhashFallback(p unsafe.Pointer, seed, s uintptr) uintptr {
-	h := uint32(seed + s*hashkey[0])
-tail:
-	switch {
-	case s == 0:
-	case s < 4:
-		h ^= uint32(*(*byte)(p))
-		h ^= uint32(*(*byte)(add(p, s>>1))) << 8
-		h ^= uint32(*(*byte)(add(p, s-1))) << 16
-		h = rotl_15(h*m1) * m2
-	case s == 4:
-		h ^= readUnaligned32(p)
-		h = rotl_15(h*m1) * m2
-	case s <= 8:
-		h ^= readUnaligned32(p)
-		h = rotl_15(h*m1) * m2
-		h ^= readUnaligned32(add(p, s-4))
-		h = rotl_15(h*m1) * m2
-	case s <= 16:
-		h ^= readUnaligned32(p)
-		h = rotl_15(h*m1) * m2
-		h ^= readUnaligned32(add(p, 4))
-		h = rotl_15(h*m1) * m2
-		h ^= readUnaligned32(add(p, s-8))
-		h = rotl_15(h*m1) * m2
-		h ^= readUnaligned32(add(p, s-4))
-		h = rotl_15(h*m1) * m2
-	default:
-		v1 := h
-		v2 := uint32(seed * hashkey[1])
-		v3 := uint32(seed * hashkey[2])
-		v4 := uint32(seed * hashkey[3])
-		for s >= 16 {
-			v1 ^= readUnaligned32(p)
-			v1 = rotl_15(v1*m1) * m2
-			p = add(p, 4)
-			v2 ^= readUnaligned32(p)
-			v2 = rotl_15(v2*m2) * m3
-			p = add(p, 4)
-			v3 ^= readUnaligned32(p)
-			v3 = rotl_15(v3*m3) * m4
-			p = add(p, 4)
-			v4 ^= readUnaligned32(p)
-			v4 = rotl_15(v4*m4) * m1
-			p = add(p, 4)
-			s -= 16
-		}
-		h = v1 ^ v2 ^ v3 ^ v4
-		goto tail
-	}
-	h ^= h >> 17
-	h *= m3
-	h ^= h >> 13
-	h *= m4
-	h ^= h >> 16
-	return uintptr(h)
-}
-
 func memhash32Fallback(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)
+	a, b := mix32(uint32(seed), uint32(4^hashkey[0]))
+	t := readUnaligned32(p)
+	a ^= t
+	b ^= t
+	a, b = mix32(a, b)
+	a, b = mix32(a, b)
+	return uintptr(a ^ b)
 }
 
 func memhash64Fallback(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)
+	a, b := mix32(uint32(seed), uint32(8^hashkey[0]))
+	a ^= readUnaligned32(p)
+	b ^= readUnaligned32(add(p, 4))
+	a, b = mix32(a, b)
+	a, b = mix32(a, b)
+	return uintptr(a ^ b)
 }
 
-// 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.
-func rotl_15(x uint32) uint32 {
-	return (x << 15) | (x >> (32 - 15))
+func memhashFallback(p unsafe.Pointer, seed, s uintptr) uintptr {
+
+	a, b := mix32(uint32(seed), uint32(s^hashkey[0]))
+	if s == 0 {
+		return uintptr(a ^ b)
+	}
+	for ; s > 8; s -= 8 {
+		a ^= readUnaligned32(p)
+		b ^= readUnaligned32(add(p, 4))
+		a, b = mix32(a, b)
+		p = add(p, 8)
+	}
+	if s >= 4 {
+		a ^= readUnaligned32(p)
+		b ^= readUnaligned32(add(p, s-4))
+	} else {
+		t := uint32(*(*byte)(p))
+		t |= uint32(*(*byte)(add(p, s>>1))) << 8
+		t |= uint32(*(*byte)(add(p, s-1))) << 16
+		b ^= t
+	}
+	a, b = mix32(a, b)
+	a, b = mix32(a, b)
+	return uintptr(a ^ b)
+}
+
+func mix32(a, b uint32) (uint32, uint32) {
+	c := uint64(a^uint32(hashkey[1])) * uint64(b^uint32(hashkey[2]))
+	return uint32(c), uint32(c >> 32)
 }
diff --git a/src/runtime/hash64.go b/src/runtime/hash64.go
index d128382..5f7d00b 100644
--- a/src/runtime/hash64.go
+++ b/src/runtime/hash64.go
@@ -3,106 +3,91 @@
 // license that can be found in the LICENSE file.
 
 // Hashing algorithm inspired by
-//   xxhash: https://code.google.com/p/xxhash/
-// cityhash: https://code.google.com/p/cityhash/
+// wyhash: https://github.com/wangyi-fudan/wyhash
 
+//go:build amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm
 // +build amd64 arm64 mips64 mips64le ppc64 ppc64le riscv64 s390x wasm
 
 package runtime
 
-import "unsafe"
+import (
+	"runtime/internal/math"
+	"unsafe"
+)
 
 const (
-	// Constants for multiplication: four random odd 64-bit numbers.
-	m1 = 16877499708836156737
-	m2 = 2820277070424839065
-	m3 = 9497967016996688599
-	m4 = 15839092249703872147
+	m1 = 0xa0761d6478bd642f
+	m2 = 0xe7037ed1a0b428db
+	m3 = 0x8ebc6af09c88c6e3
+	m4 = 0x589965cc75374cc3
+	m5 = 0x1d8e4e27c47d124f
 )
 
 func memhashFallback(p unsafe.Pointer, seed, s uintptr) uintptr {
-	h := uint64(seed + s*hashkey[0])
-tail:
+	var a, b uintptr
+	seed ^= hashkey[0] ^ m1
 	switch {
 	case s == 0:
+		return seed
 	case s < 4:
-		h ^= uint64(*(*byte)(p))
-		h ^= uint64(*(*byte)(add(p, s>>1))) << 8
-		h ^= uint64(*(*byte)(add(p, s-1))) << 16
-		h = rotl_31(h*m1) * m2
-	case s <= 8:
-		h ^= uint64(readUnaligned32(p))
-		h ^= uint64(readUnaligned32(add(p, s-4))) << 32
-		h = rotl_31(h*m1) * m2
+		a = uintptr(*(*byte)(p))
+		a |= uintptr(*(*byte)(add(p, s>>1))) << 8
+		a |= uintptr(*(*byte)(add(p, s-1))) << 16
+	case s == 4:
+		a = r4(p)
+		b = a
+	case s < 8:
+		a = r4(p)
+		b = r4(add(p, s-4))
+	case s == 8:
+		a = r8(p)
+		b = a
 	case s <= 16:
-		h ^= readUnaligned64(p)
-		h = rotl_31(h*m1) * m2
-		h ^= readUnaligned64(add(p, s-8))
-		h = rotl_31(h*m1) * m2
-	case s <= 32:
-		h ^= readUnaligned64(p)
-		h = rotl_31(h*m1) * m2
-		h ^= readUnaligned64(add(p, 8))
-		h = rotl_31(h*m1) * m2
-		h ^= readUnaligned64(add(p, s-16))
-		h = rotl_31(h*m1) * m2
-		h ^= readUnaligned64(add(p, s-8))
-		h = rotl_31(h*m1) * m2
+		a = r8(p)
+		b = r8(add(p, s-8))
 	default:
-		v1 := h
-		v2 := uint64(seed * hashkey[1])
-		v3 := uint64(seed * hashkey[2])
-		v4 := uint64(seed * hashkey[3])
-		for s >= 32 {
-			v1 ^= readUnaligned64(p)
-			v1 = rotl_31(v1*m1) * m2
-			p = add(p, 8)
-			v2 ^= readUnaligned64(p)
-			v2 = rotl_31(v2*m2) * m3
-			p = add(p, 8)
-			v3 ^= readUnaligned64(p)
-			v3 = rotl_31(v3*m3) * m4
-			p = add(p, 8)
-			v4 ^= readUnaligned64(p)
-			v4 = rotl_31(v4*m4) * m1
-			p = add(p, 8)
-			s -= 32
+		l := s
+		if l > 48 {
+			seed1 := seed
+			seed2 := seed
+			for ; l > 48; l -= 48 {
+				seed = mix(r8(p)^m2, r8(add(p, 8))^seed)
+				seed1 = mix(r8(add(p, 16))^m3, r8(add(p, 24))^seed1)
+				seed2 = mix(r8(add(p, 32))^m4, r8(add(p, 40))^seed2)
+				p = add(p, 48)
+			}
+			seed ^= seed1 ^ seed2
 		}
-		h = v1 ^ v2 ^ v3 ^ v4
-		goto tail
+		for ; l > 16; l -= 16 {
+			seed = mix(r8(p)^m2, r8(add(p, 8))^seed)
+			p = add(p, 16)
+		}
+		a = r8(add(p, l-16))
+		b = r8(add(p, l-8))
 	}
 
-	h ^= h >> 29
-	h *= m3
-	h ^= h >> 32
-	return uintptr(h)
+	return mix(m5^s, mix(a^m2, b^seed))
 }
 
 func memhash32Fallback(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)
+	a := r4(p)
+	return mix(m5^4, mix(a^m2, a^seed^hashkey[0]^m1))
 }
 
 func memhash64Fallback(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)
+	a := r8(p)
+	return mix(m5^8, mix(a^m2, a^seed^hashkey[0]^m1))
 }
 
-// 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.
-func rotl_31(x uint64) uint64 {
-	return (x << 31) | (x >> (64 - 31))
+func mix(a, b uintptr) uintptr {
+	hi, lo := math.Mul64(uint64(a), uint64(b))
+	return uintptr(hi ^ lo)
+}
+
+func r4(p unsafe.Pointer) uintptr {
+	return uintptr(readUnaligned32(p))
+}
+
+func r8(p unsafe.Pointer) uintptr {
+	return uintptr(readUnaligned64(p))
 }
diff --git a/src/runtime/hash_test.go b/src/runtime/hash_test.go
index 5023835..7048874 100644
--- a/src/runtime/hash_test.go
+++ b/src/runtime/hash_test.go
@@ -8,7 +8,6 @@
 	"fmt"
 	"math"
 	"math/rand"
-	"reflect"
 	. "runtime"
 	"strings"
 	"testing"
@@ -49,54 +48,6 @@
 	}
 }
 
-func TestCompilerVsRuntimeHash(t *testing.T) {
-	// Test to make sure the compiler's hash function and the runtime's hash function agree.
-	// See issue 37716.
-	for _, m := range []interface{}{
-		map[bool]int{},
-		map[int8]int{},
-		map[uint8]int{},
-		map[int16]int{},
-		map[uint16]int{},
-		map[int32]int{},
-		map[uint32]int{},
-		map[int64]int{},
-		map[uint64]int{},
-		map[int]int{},
-		map[uint]int{},
-		map[uintptr]int{},
-		map[*byte]int{},
-		map[chan int]int{},
-		map[unsafe.Pointer]int{},
-		map[float32]int{},
-		map[float64]int{},
-		map[complex64]int{},
-		map[complex128]int{},
-		map[string]int{},
-		//map[interface{}]int{},
-		//map[interface{F()}]int{},
-		map[[8]uint64]int{},
-		map[[8]string]int{},
-		map[struct{ a, b, c, d int32 }]int{}, // Note: tests AMEM128
-		map[struct{ a, b, _, d int32 }]int{},
-		map[struct {
-			a, b int32
-			c    float32
-			d, e [8]byte
-		}]int{},
-		map[struct {
-			a int16
-			b int64
-		}]int{},
-	} {
-		k := reflect.New(reflect.TypeOf(m).Key()).Elem().Interface() // the zero key
-		x, y := MapHashCheck(m, k)
-		if x != y {
-			t.Errorf("hashes did not match (%x vs %x) for map %T", x, y, m)
-		}
-	}
-}
-
 // 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/heapdump.go b/src/runtime/heapdump.go
index 2d53157..934e55f 100644
--- a/src/runtime/heapdump.go
+++ b/src/runtime/heapdump.go
@@ -403,9 +403,10 @@
 }
 
 func dumpgs() {
+	assertWorldStopped()
+
 	// goroutines & stacks
-	for i := 0; uintptr(i) < allglen; i++ {
-		gp := allgs[i]
+	forEachG(func(gp *g) {
 		status := readgstatus(gp) // The world is stopped so gp will not be in a scan state.
 		switch status {
 		default:
@@ -418,7 +419,7 @@
 			_Gwaiting:
 			dumpgoroutine(gp)
 		}
-	}
+	})
 }
 
 func finq_callback(fn *funcval, obj unsafe.Pointer, nret uintptr, fint *_type, ot *ptrtype) {
@@ -531,7 +532,7 @@
 	dumpint(uint64(arenaStart))
 	dumpint(uint64(arenaEnd))
 	dumpstr(sys.GOARCH)
-	dumpstr(sys.Goexperiment)
+	dumpstr(buildVersion)
 	dumpint(uint64(ncpu))
 }
 
diff --git a/src/runtime/histogram.go b/src/runtime/histogram.go
index da4910d..0cccbcc 100644
--- a/src/runtime/histogram.go
+++ b/src/runtime/histogram.go
@@ -81,6 +81,10 @@
 }
 
 // record adds the given duration to the distribution.
+//
+// Disallow preemptions and stack growths because this function
+// may run in sensitive locations.
+//go:nosplit
 func (h *timeHistogram) record(duration int64) {
 	if duration < 0 {
 		atomic.Xadd64(&h.underflow, 1)
diff --git a/src/runtime/iface.go b/src/runtime/iface.go
index 0504b89..cd5fead 100644
--- a/src/runtime/iface.go
+++ b/src/runtime/iface.go
@@ -447,23 +447,18 @@
 	return
 }
 
-func assertI2I(inter *interfacetype, i iface) (r iface) {
-	tab := i.tab
+func assertI2I(inter *interfacetype, tab *itab) *itab {
 	if tab == nil {
 		// explicit conversions require non-nil interface value.
 		panic(&TypeAssertionError{nil, nil, &inter.typ, ""})
 	}
 	if tab.inter == inter {
-		r.tab = tab
-		r.data = i.data
-		return
+		return tab
 	}
-	r.tab = getitab(inter, tab._type, false)
-	r.data = i.data
-	return
+	return getitab(inter, tab._type, false)
 }
 
-func assertI2I2(inter *interfacetype, i iface) (r iface, b bool) {
+func assertI2I2(inter *interfacetype, i iface) (r iface) {
 	tab := i.tab
 	if tab == nil {
 		return
@@ -476,22 +471,18 @@
 	}
 	r.tab = tab
 	r.data = i.data
-	b = true
 	return
 }
 
-func assertE2I(inter *interfacetype, e eface) (r iface) {
-	t := e._type
+func assertE2I(inter *interfacetype, t *_type) *itab {
 	if t == nil {
 		// explicit conversions require non-nil interface value.
 		panic(&TypeAssertionError{nil, nil, &inter.typ, ""})
 	}
-	r.tab = getitab(inter, t, false)
-	r.data = e.data
-	return
+	return getitab(inter, t, false)
 }
 
-func assertE2I2(inter *interfacetype, e eface) (r iface, b bool) {
+func assertE2I2(inter *interfacetype, e eface) (r iface) {
 	t := e._type
 	if t == nil {
 		return
@@ -502,18 +493,17 @@
 	}
 	r.tab = tab
 	r.data = e.data
-	b = true
 	return
 }
 
 //go:linkname reflect_ifaceE2I reflect.ifaceE2I
 func reflect_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
-	*dst = assertE2I(inter, e)
+	*dst = iface{assertE2I(inter, e._type), e.data}
 }
 
 //go:linkname reflectlite_ifaceE2I internal/reflectlite.ifaceE2I
 func reflectlite_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
-	*dst = assertE2I(inter, e)
+	*dst = iface{assertE2I(inter, e._type), e.data}
 }
 
 func iterate_itabs(fn func(*itab)) {
@@ -563,3 +553,10 @@
 	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
 	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 }
+
+// The linker redirects a reference of a method that it determined
+// unreachable to a reference to this function, so it will throw if
+// ever called.
+func unreachableMethod() {
+	throw("unreachable method called. linker bug?")
+}
diff --git a/src/runtime/internal/atomic/asm_386.s b/src/runtime/internal/atomic/asm_386.s
deleted file mode 100644
index d82faef..0000000
--- a/src/runtime/internal/atomic/asm_386.s
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-#include "funcdata.h"
-
-// bool Cas(int32 *val, int32 old, int32 new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	}else
-//		return 0;
-TEXT ·Cas(SB), NOSPLIT, $0-13
-	MOVL	ptr+0(FP), BX
-	MOVL	old+4(FP), AX
-	MOVL	new+8(FP), CX
-	LOCK
-	CMPXCHGL	CX, 0(BX)
-	SETEQ	ret+12(FP)
-	RET
-
-TEXT ·Casuintptr(SB), NOSPLIT, $0-13
-	JMP	·Cas(SB)
-
-TEXT ·CasRel(SB), NOSPLIT, $0-13
-	JMP	·Cas(SB)
-
-TEXT ·Loaduintptr(SB), NOSPLIT, $0-8
-	JMP	·Load(SB)
-
-TEXT ·Loaduint(SB), NOSPLIT, $0-8
-	JMP	·Load(SB)
-
-TEXT ·Storeuintptr(SB), NOSPLIT, $0-8
-	JMP	·Store(SB)
-
-TEXT ·Xadduintptr(SB), NOSPLIT, $0-12
-	JMP	·Xadd(SB)
-
-TEXT ·Loadint64(SB), NOSPLIT, $0-12
-	JMP	·Load64(SB)
-
-TEXT ·Xaddint64(SB), NOSPLIT, $0-20
-	JMP	·Xadd64(SB)
-
-// bool ·Cas64(uint64 *val, uint64 old, uint64 new)
-// Atomically:
-//	if(*val == *old){
-//		*val = new;
-//		return 1;
-//	} else {
-//		return 0;
-//	}
-TEXT ·Cas64(SB), NOSPLIT, $0-21
-	NO_LOCAL_POINTERS
-	MOVL	ptr+0(FP), BP
-	TESTL	$7, BP
-	JZ	2(PC)
-	CALL	·panicUnaligned(SB)
-	MOVL	old_lo+4(FP), AX
-	MOVL	old_hi+8(FP), DX
-	MOVL	new_lo+12(FP), BX
-	MOVL	new_hi+16(FP), CX
-	LOCK
-	CMPXCHG8B	0(BP)
-	SETEQ	ret+20(FP)
-	RET
-
-// bool Casp1(void **p, void *old, void *new)
-// Atomically:
-//	if(*p == old){
-//		*p = new;
-//		return 1;
-//	}else
-//		return 0;
-TEXT ·Casp1(SB), NOSPLIT, $0-13
-	MOVL	ptr+0(FP), BX
-	MOVL	old+4(FP), AX
-	MOVL	new+8(FP), CX
-	LOCK
-	CMPXCHGL	CX, 0(BX)
-	SETEQ	ret+12(FP)
-	RET
-
-// uint32 Xadd(uint32 volatile *val, int32 delta)
-// Atomically:
-//	*val += delta;
-//	return *val;
-TEXT ·Xadd(SB), NOSPLIT, $0-12
-	MOVL	ptr+0(FP), BX
-	MOVL	delta+4(FP), AX
-	MOVL	AX, CX
-	LOCK
-	XADDL	AX, 0(BX)
-	ADDL	CX, AX
-	MOVL	AX, ret+8(FP)
-	RET
-
-TEXT ·Xadd64(SB), NOSPLIT, $0-20
-	NO_LOCAL_POINTERS
-	// no XADDQ so use CMPXCHG8B loop
-	MOVL	ptr+0(FP), BP
-	TESTL	$7, BP
-	JZ	2(PC)
-	CALL	·panicUnaligned(SB)
-	// DI:SI = delta
-	MOVL	delta_lo+4(FP), SI
-	MOVL	delta_hi+8(FP), DI
-	// DX:AX = *addr
-	MOVL	0(BP), AX
-	MOVL	4(BP), DX
-addloop:
-	// CX:BX = DX:AX (*addr) + DI:SI (delta)
-	MOVL	AX, BX
-	MOVL	DX, CX
-	ADDL	SI, BX
-	ADCL	DI, CX
-
-	// if *addr == DX:AX {
-	//	*addr = CX:BX
-	// } else {
-	//	DX:AX = *addr
-	// }
-	// all in one instruction
-	LOCK
-	CMPXCHG8B	0(BP)
-
-	JNZ	addloop
-
-	// success
-	// return CX:BX
-	MOVL	BX, ret_lo+12(FP)
-	MOVL	CX, ret_hi+16(FP)
-	RET
-
-TEXT ·Xchg(SB), NOSPLIT, $0-12
-	MOVL	ptr+0(FP), BX
-	MOVL	new+4(FP), AX
-	XCHGL	AX, 0(BX)
-	MOVL	AX, ret+8(FP)
-	RET
-
-TEXT ·Xchguintptr(SB), NOSPLIT, $0-12
-	JMP	·Xchg(SB)
-
-TEXT ·Xchg64(SB),NOSPLIT,$0-20
-	NO_LOCAL_POINTERS
-	// no XCHGQ so use CMPXCHG8B loop
-	MOVL	ptr+0(FP), BP
-	TESTL	$7, BP
-	JZ	2(PC)
-	CALL	·panicUnaligned(SB)
-	// CX:BX = new
-	MOVL	new_lo+4(FP), BX
-	MOVL	new_hi+8(FP), CX
-	// DX:AX = *addr
-	MOVL	0(BP), AX
-	MOVL	4(BP), DX
-swaploop:
-	// if *addr == DX:AX
-	//	*addr = CX:BX
-	// else
-	//	DX:AX = *addr
-	// all in one instruction
-	LOCK
-	CMPXCHG8B	0(BP)
-	JNZ	swaploop
-
-	// success
-	// return DX:AX
-	MOVL	AX, ret_lo+12(FP)
-	MOVL	DX, ret_hi+16(FP)
-	RET
-
-TEXT ·StorepNoWB(SB), NOSPLIT, $0-8
-	MOVL	ptr+0(FP), BX
-	MOVL	val+4(FP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-TEXT ·Store(SB), NOSPLIT, $0-8
-	MOVL	ptr+0(FP), BX
-	MOVL	val+4(FP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-TEXT ·StoreRel(SB), NOSPLIT, $0-8
-	JMP	·Store(SB)
-
-TEXT runtime∕internal∕atomic·StoreReluintptr(SB), NOSPLIT, $0-8
-	JMP	runtime∕internal∕atomic·Store(SB)
-
-// uint64 atomicload64(uint64 volatile* addr);
-TEXT ·Load64(SB), NOSPLIT, $0-12
-	NO_LOCAL_POINTERS
-	MOVL	ptr+0(FP), AX
-	TESTL	$7, AX
-	JZ	2(PC)
-	CALL	·panicUnaligned(SB)
-	MOVQ	(AX), M0
-	MOVQ	M0, ret+4(FP)
-	EMMS
-	RET
-
-// void ·Store64(uint64 volatile* addr, uint64 v);
-TEXT ·Store64(SB), NOSPLIT, $0-12
-	NO_LOCAL_POINTERS
-	MOVL	ptr+0(FP), AX
-	TESTL	$7, AX
-	JZ	2(PC)
-	CALL	·panicUnaligned(SB)
-	// MOVQ and EMMS were introduced on the Pentium MMX.
-	MOVQ	val+4(FP), M0
-	MOVQ	M0, (AX)
-	EMMS
-	// This is essentially a no-op, but it provides required memory fencing.
-	// It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
-	XORL	AX, AX
-	LOCK
-	XADDL	AX, (SP)
-	RET
-
-// void	·Or8(byte volatile*, byte);
-TEXT ·Or8(SB), NOSPLIT, $0-5
-	MOVL	ptr+0(FP), AX
-	MOVB	val+4(FP), BX
-	LOCK
-	ORB	BX, (AX)
-	RET
-
-// void	·And8(byte volatile*, byte);
-TEXT ·And8(SB), NOSPLIT, $0-5
-	MOVL	ptr+0(FP), AX
-	MOVB	val+4(FP), BX
-	LOCK
-	ANDB	BX, (AX)
-	RET
-
-TEXT ·Store8(SB), NOSPLIT, $0-5
-	MOVL	ptr+0(FP), BX
-	MOVB	val+4(FP), AX
-	XCHGB	AX, 0(BX)
-	RET
-
-// func Or(addr *uint32, v uint32)
-TEXT ·Or(SB), NOSPLIT, $0-8
-	MOVL	ptr+0(FP), AX
-	MOVL	val+4(FP), BX
-	LOCK
-	ORL	BX, (AX)
-	RET
-
-// func And(addr *uint32, v uint32)
-TEXT ·And(SB), NOSPLIT, $0-8
-	MOVL	ptr+0(FP), AX
-	MOVL	val+4(FP), BX
-	LOCK
-	ANDL	BX, (AX)
-	RET
diff --git a/src/runtime/internal/atomic/asm_amd64.s b/src/runtime/internal/atomic/asm_amd64.s
deleted file mode 100644
index 2cf7c55..0000000
--- a/src/runtime/internal/atomic/asm_amd64.s
+++ /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.
-
-// Note: some of these functions are semantically inlined
-// by the compiler (in src/cmd/compile/internal/gc/ssa.go).
-
-#include "textflag.h"
-
-// bool Cas(int32 *val, int32 old, int32 new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	} else
-//		return 0;
-TEXT runtime∕internal∕atomic·Cas(SB),NOSPLIT,$0-17
-	MOVQ	ptr+0(FP), BX
-	MOVL	old+8(FP), AX
-	MOVL	new+12(FP), CX
-	LOCK
-	CMPXCHGL	CX, 0(BX)
-	SETEQ	ret+16(FP)
-	RET
-
-// bool	runtime∕internal∕atomic·Cas64(uint64 *val, uint64 old, uint64 new)
-// Atomically:
-//	if(*val == *old){
-//		*val = new;
-//		return 1;
-//	} else {
-//		return 0;
-//	}
-TEXT runtime∕internal∕atomic·Cas64(SB), NOSPLIT, $0-25
-	MOVQ	ptr+0(FP), BX
-	MOVQ	old+8(FP), AX
-	MOVQ	new+16(FP), CX
-	LOCK
-	CMPXCHGQ	CX, 0(BX)
-	SETEQ	ret+24(FP)
-	RET
-
-TEXT runtime∕internal∕atomic·Casuintptr(SB), NOSPLIT, $0-25
-	JMP	runtime∕internal∕atomic·Cas64(SB)
-
-TEXT runtime∕internal∕atomic·CasRel(SB), NOSPLIT, $0-17
-	JMP	runtime∕internal∕atomic·Cas(SB)
-
-TEXT runtime∕internal∕atomic·Loaduintptr(SB), NOSPLIT, $0-16
-	JMP	runtime∕internal∕atomic·Load64(SB)
-
-TEXT runtime∕internal∕atomic·Loaduint(SB), NOSPLIT, $0-16
-	JMP	runtime∕internal∕atomic·Load64(SB)
-
-TEXT runtime∕internal∕atomic·Storeuintptr(SB), NOSPLIT, $0-16
-	JMP	runtime∕internal∕atomic·Store64(SB)
-
-TEXT runtime∕internal∕atomic·Loadint64(SB), NOSPLIT, $0-16
-	JMP	runtime∕internal∕atomic·Load64(SB)
-
-TEXT runtime∕internal∕atomic·Xaddint64(SB), NOSPLIT, $0-24
-	JMP	runtime∕internal∕atomic·Xadd64(SB)
-
-// bool Casp1(void **val, void *old, void *new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	} else
-//		return 0;
-TEXT runtime∕internal∕atomic·Casp1(SB), NOSPLIT, $0-25
-	MOVQ	ptr+0(FP), BX
-	MOVQ	old+8(FP), AX
-	MOVQ	new+16(FP), CX
-	LOCK
-	CMPXCHGQ	CX, 0(BX)
-	SETEQ	ret+24(FP)
-	RET
-
-// uint32 Xadd(uint32 volatile *val, int32 delta)
-// Atomically:
-//	*val += delta;
-//	return *val;
-TEXT runtime∕internal∕atomic·Xadd(SB), NOSPLIT, $0-20
-	MOVQ	ptr+0(FP), BX
-	MOVL	delta+8(FP), AX
-	MOVL	AX, CX
-	LOCK
-	XADDL	AX, 0(BX)
-	ADDL	CX, AX
-	MOVL	AX, ret+16(FP)
-	RET
-
-TEXT runtime∕internal∕atomic·Xadd64(SB), NOSPLIT, $0-24
-	MOVQ	ptr+0(FP), BX
-	MOVQ	delta+8(FP), AX
-	MOVQ	AX, CX
-	LOCK
-	XADDQ	AX, 0(BX)
-	ADDQ	CX, AX
-	MOVQ	AX, ret+16(FP)
-	RET
-
-TEXT runtime∕internal∕atomic·Xadduintptr(SB), NOSPLIT, $0-24
-	JMP	runtime∕internal∕atomic·Xadd64(SB)
-
-TEXT runtime∕internal∕atomic·Xchg(SB), NOSPLIT, $0-20
-	MOVQ	ptr+0(FP), BX
-	MOVL	new+8(FP), AX
-	XCHGL	AX, 0(BX)
-	MOVL	AX, ret+16(FP)
-	RET
-
-TEXT runtime∕internal∕atomic·Xchg64(SB), NOSPLIT, $0-24
-	MOVQ	ptr+0(FP), BX
-	MOVQ	new+8(FP), AX
-	XCHGQ	AX, 0(BX)
-	MOVQ	AX, ret+16(FP)
-	RET
-
-TEXT runtime∕internal∕atomic·Xchguintptr(SB), NOSPLIT, $0-24
-	JMP	runtime∕internal∕atomic·Xchg64(SB)
-
-TEXT runtime∕internal∕atomic·StorepNoWB(SB), NOSPLIT, $0-16
-	MOVQ	ptr+0(FP), BX
-	MOVQ	val+8(FP), AX
-	XCHGQ	AX, 0(BX)
-	RET
-
-TEXT runtime∕internal∕atomic·Store(SB), NOSPLIT, $0-12
-	MOVQ	ptr+0(FP), BX
-	MOVL	val+8(FP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-TEXT runtime∕internal∕atomic·StoreRel(SB), NOSPLIT, $0-12
-	JMP	runtime∕internal∕atomic·Store(SB)
-
-TEXT runtime∕internal∕atomic·StoreRel64(SB), NOSPLIT, $0-16
-	JMP	runtime∕internal∕atomic·Store64(SB)
-
-TEXT runtime∕internal∕atomic·StoreReluintptr(SB), NOSPLIT, $0-16
-	JMP	runtime∕internal∕atomic·Store64(SB)
-
-TEXT runtime∕internal∕atomic·Store8(SB), NOSPLIT, $0-9
-	MOVQ	ptr+0(FP), BX
-	MOVB	val+8(FP), AX
-	XCHGB	AX, 0(BX)
-	RET
-
-TEXT runtime∕internal∕atomic·Store64(SB), NOSPLIT, $0-16
-	MOVQ	ptr+0(FP), BX
-	MOVQ	val+8(FP), AX
-	XCHGQ	AX, 0(BX)
-	RET
-
-// void	runtime∕internal∕atomic·Or8(byte volatile*, byte);
-TEXT runtime∕internal∕atomic·Or8(SB), NOSPLIT, $0-9
-	MOVQ	ptr+0(FP), AX
-	MOVB	val+8(FP), BX
-	LOCK
-	ORB	BX, (AX)
-	RET
-
-// void	runtime∕internal∕atomic·And8(byte volatile*, byte);
-TEXT runtime∕internal∕atomic·And8(SB), NOSPLIT, $0-9
-	MOVQ	ptr+0(FP), AX
-	MOVB	val+8(FP), BX
-	LOCK
-	ANDB	BX, (AX)
-	RET
-
-// func Or(addr *uint32, v uint32)
-TEXT runtime∕internal∕atomic·Or(SB), NOSPLIT, $0-12
-	MOVQ	ptr+0(FP), AX
-	MOVL	val+8(FP), BX
-	LOCK
-	ORL	BX, (AX)
-	RET
-
-// func And(addr *uint32, v uint32)
-TEXT runtime∕internal∕atomic·And(SB), NOSPLIT, $0-12
-	MOVQ	ptr+0(FP), AX
-	MOVL	val+8(FP), BX
-	LOCK
-	ANDL	BX, (AX)
-	RET
diff --git a/src/runtime/internal/atomic/asm_arm.s b/src/runtime/internal/atomic/asm_arm.s
deleted file mode 100644
index 274925e..0000000
--- a/src/runtime/internal/atomic/asm_arm.s
+++ /dev/null
@@ -1,284 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-#include "funcdata.h"
-
-// bool armcas(int32 *val, int32 old, int32 new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	}else
-//		return 0;
-//
-// To implement ·cas in sys_$GOOS_arm.s
-// using the native instructions, use:
-//
-//	TEXT ·cas(SB),NOSPLIT,$0
-//		B	·armcas(SB)
-//
-TEXT ·armcas(SB),NOSPLIT,$0-13
-	MOVW	ptr+0(FP), R1
-	MOVW	old+4(FP), R2
-	MOVW	new+8(FP), R3
-casl:
-	LDREX	(R1), R0
-	CMP	R0, R2
-	BNE	casfail
-
-	MOVB	runtime·goarm(SB), R8
-	CMP	$7, R8
-	BLT	2(PC)
-	DMB	MB_ISHST
-
-	STREX	R3, (R1), R0
-	CMP	$0, R0
-	BNE	casl
-	MOVW	$1, R0
-
-	CMP	$7, R8
-	BLT	2(PC)
-	DMB	MB_ISH
-
-	MOVB	R0, ret+12(FP)
-	RET
-casfail:
-	MOVW	$0, R0
-	MOVB	R0, ret+12(FP)
-	RET
-
-// stubs
-
-TEXT ·Loadp(SB),NOSPLIT|NOFRAME,$0-8
-	B	·Load(SB)
-
-TEXT ·LoadAcq(SB),NOSPLIT|NOFRAME,$0-8
-	B	·Load(SB)
-
-TEXT ·LoadAcquintptr(SB),NOSPLIT|NOFRAME,$0-8
-	B 	·Load(SB)
-
-TEXT ·Casuintptr(SB),NOSPLIT,$0-13
-	B	·Cas(SB)
-
-TEXT ·Casp1(SB),NOSPLIT,$0-13
-	B	·Cas(SB)
-
-TEXT ·CasRel(SB),NOSPLIT,$0-13
-	B	·Cas(SB)
-
-TEXT ·Loaduintptr(SB),NOSPLIT,$0-8
-	B	·Load(SB)
-
-TEXT ·Loaduint(SB),NOSPLIT,$0-8
-	B	·Load(SB)
-
-TEXT ·Storeuintptr(SB),NOSPLIT,$0-8
-	B	·Store(SB)
-
-TEXT ·StorepNoWB(SB),NOSPLIT,$0-8
-	B	·Store(SB)
-
-TEXT ·StoreRel(SB),NOSPLIT,$0-8
-	B	·Store(SB)
-
-TEXT ·StoreReluintptr(SB),NOSPLIT,$0-8
-	B	·Store(SB)
-
-TEXT ·Xadduintptr(SB),NOSPLIT,$0-12
-	B	·Xadd(SB)
-
-TEXT ·Loadint64(SB),NOSPLIT,$0-12
-	B	·Load64(SB)
-
-TEXT ·Xaddint64(SB),NOSPLIT,$0-20
-	B	·Xadd64(SB)
-
-// 64-bit atomics
-// The native ARM implementations use LDREXD/STREXD, which are
-// available on ARMv6k or later. We use them only on ARMv7.
-// On older ARM, we use Go implementations which simulate 64-bit
-// atomics with locks.
-
-TEXT armCas64<>(SB),NOSPLIT,$0-21
-	// addr is already in R1
-	MOVW	old_lo+4(FP), R2
-	MOVW	old_hi+8(FP), R3
-	MOVW	new_lo+12(FP), R4
-	MOVW	new_hi+16(FP), R5
-cas64loop:
-	LDREXD	(R1), R6	// loads R6 and R7
-	CMP	R2, R6
-	BNE	cas64fail
-	CMP	R3, R7
-	BNE	cas64fail
-
-	DMB	MB_ISHST
-
-	STREXD	R4, (R1), R0	// stores R4 and R5
-	CMP	$0, R0
-	BNE	cas64loop
-	MOVW	$1, R0
-
-	DMB	MB_ISH
-
-	MOVBU	R0, swapped+20(FP)
-	RET
-cas64fail:
-	MOVW	$0, R0
-	MOVBU	R0, swapped+20(FP)
-	RET
-
-TEXT armXadd64<>(SB),NOSPLIT,$0-20
-	// addr is already in R1
-	MOVW	delta_lo+4(FP), R2
-	MOVW	delta_hi+8(FP), R3
-
-add64loop:
-	LDREXD	(R1), R4	// loads R4 and R5
-	ADD.S	R2, R4
-	ADC	R3, R5
-
-	DMB	MB_ISHST
-
-	STREXD	R4, (R1), R0	// stores R4 and R5
-	CMP	$0, R0
-	BNE	add64loop
-
-	DMB	MB_ISH
-
-	MOVW	R4, new_lo+12(FP)
-	MOVW	R5, new_hi+16(FP)
-	RET
-
-TEXT armXchg64<>(SB),NOSPLIT,$0-20
-	// addr is already in R1
-	MOVW	new_lo+4(FP), R2
-	MOVW	new_hi+8(FP), R3
-
-swap64loop:
-	LDREXD	(R1), R4	// loads R4 and R5
-
-	DMB	MB_ISHST
-
-	STREXD	R2, (R1), R0	// stores R2 and R3
-	CMP	$0, R0
-	BNE	swap64loop
-
-	DMB	MB_ISH
-
-	MOVW	R4, old_lo+12(FP)
-	MOVW	R5, old_hi+16(FP)
-	RET
-
-TEXT armLoad64<>(SB),NOSPLIT,$0-12
-	// addr is already in R1
-
-	LDREXD	(R1), R2	// loads R2 and R3
-	DMB	MB_ISH
-
-	MOVW	R2, val_lo+4(FP)
-	MOVW	R3, val_hi+8(FP)
-	RET
-
-TEXT armStore64<>(SB),NOSPLIT,$0-12
-	// addr is already in R1
-	MOVW	val_lo+4(FP), R2
-	MOVW	val_hi+8(FP), R3
-
-store64loop:
-	LDREXD	(R1), R4	// loads R4 and R5
-
-	DMB	MB_ISHST
-
-	STREXD	R2, (R1), R0	// stores R2 and R3
-	CMP	$0, R0
-	BNE	store64loop
-
-	DMB	MB_ISH
-	RET
-
-// The following functions all panic if their address argument isn't
-// 8-byte aligned. Since we're calling back into Go code to do this,
-// we have to cooperate with stack unwinding. In the normal case, the
-// functions tail-call into the appropriate implementation, which
-// means they must not open a frame. Hence, when they go down the
-// panic path, at that point they push the LR to create a real frame
-// (they don't need to pop it because panic won't return).
-
-TEXT ·Cas64(SB),NOSPLIT,$-4-21
-	NO_LOCAL_POINTERS
-	MOVW	addr+0(FP), R1
-	// make unaligned atomic access panic
-	AND.S	$7, R1, R2
-	BEQ 	3(PC)
-	MOVW.W	R14, -4(R13) // prepare a real frame
-	BL	·panicUnaligned(SB)
-
-	MOVB	runtime·goarm(SB), R11
-	CMP	$7, R11
-	BLT	2(PC)
-	JMP	armCas64<>(SB)
-	JMP	·goCas64(SB)
-
-TEXT ·Xadd64(SB),NOSPLIT,$-4-20
-	NO_LOCAL_POINTERS
-	MOVW	addr+0(FP), R1
-	// make unaligned atomic access panic
-	AND.S	$7, R1, R2
-	BEQ 	3(PC)
-	MOVW.W	R14, -4(R13) // prepare a real frame
-	BL	·panicUnaligned(SB)
-
-	MOVB	runtime·goarm(SB), R11
-	CMP	$7, R11
-	BLT	2(PC)
-	JMP	armXadd64<>(SB)
-	JMP	·goXadd64(SB)
-
-TEXT ·Xchg64(SB),NOSPLIT,$-4-20
-	NO_LOCAL_POINTERS
-	MOVW	addr+0(FP), R1
-	// make unaligned atomic access panic
-	AND.S	$7, R1, R2
-	BEQ 	3(PC)
-	MOVW.W	R14, -4(R13) // prepare a real frame
-	BL	·panicUnaligned(SB)
-
-	MOVB	runtime·goarm(SB), R11
-	CMP	$7, R11
-	BLT	2(PC)
-	JMP	armXchg64<>(SB)
-	JMP	·goXchg64(SB)
-
-TEXT ·Load64(SB),NOSPLIT,$-4-12
-	NO_LOCAL_POINTERS
-	MOVW	addr+0(FP), R1
-	// make unaligned atomic access panic
-	AND.S	$7, R1, R2
-	BEQ 	3(PC)
-	MOVW.W	R14, -4(R13) // prepare a real frame
-	BL	·panicUnaligned(SB)
-
-	MOVB	runtime·goarm(SB), R11
-	CMP	$7, R11
-	BLT	2(PC)
-	JMP	armLoad64<>(SB)
-	JMP	·goLoad64(SB)
-
-TEXT ·Store64(SB),NOSPLIT,$-4-12
-	NO_LOCAL_POINTERS
-	MOVW	addr+0(FP), R1
-	// make unaligned atomic access panic
-	AND.S	$7, R1, R2
-	BEQ 	3(PC)
-	MOVW.W	R14, -4(R13) // prepare a real frame
-	BL	·panicUnaligned(SB)
-
-	MOVB	runtime·goarm(SB), R11
-	CMP	$7, R11
-	BLT	2(PC)
-	JMP	armStore64<>(SB)
-	JMP	·goStore64(SB)
diff --git a/src/runtime/internal/atomic/asm_arm64.s b/src/runtime/internal/atomic/asm_arm64.s
deleted file mode 100644
index 8336a85..0000000
--- a/src/runtime/internal/atomic/asm_arm64.s
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// bool Cas(uint32 *ptr, uint32 old, uint32 new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	} else
-//		return 0;
-TEXT runtime∕internal∕atomic·Cas(SB), NOSPLIT, $0-17
-	MOVD	ptr+0(FP), R0
-	MOVW	old+8(FP), R1
-	MOVW	new+12(FP), R2
-again:
-	LDAXRW	(R0), R3
-	CMPW	R1, R3
-	BNE	ok
-	STLXRW	R2, (R0), R3
-	CBNZ	R3, again
-ok:
-	CSET	EQ, R0
-	MOVB	R0, ret+16(FP)
-	RET
-
-TEXT runtime∕internal∕atomic·Casuintptr(SB), NOSPLIT, $0-25
-	B	runtime∕internal∕atomic·Cas64(SB)
-
-TEXT runtime∕internal∕atomic·CasRel(SB), NOSPLIT, $0-17
-	B	runtime∕internal∕atomic·Cas(SB)
-
-TEXT runtime∕internal∕atomic·Loaduintptr(SB), NOSPLIT, $0-16
-	B	runtime∕internal∕atomic·Load64(SB)
-
-TEXT runtime∕internal∕atomic·Loaduint(SB), NOSPLIT, $0-16
-	B	runtime∕internal∕atomic·Load64(SB)
-
-TEXT runtime∕internal∕atomic·Storeuintptr(SB), NOSPLIT, $0-16
-	B	runtime∕internal∕atomic·Store64(SB)
-
-TEXT runtime∕internal∕atomic·Xadduintptr(SB), NOSPLIT, $0-24
-	B	runtime∕internal∕atomic·Xadd64(SB)
-
-TEXT runtime∕internal∕atomic·Loadint64(SB), NOSPLIT, $0-16
-	B	runtime∕internal∕atomic·Load64(SB)
-
-TEXT runtime∕internal∕atomic·Xaddint64(SB), NOSPLIT, $0-24
-	B	runtime∕internal∕atomic·Xadd64(SB)
-
-// bool Casp1(void **val, void *old, void *new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	} else
-//		return 0;
-TEXT runtime∕internal∕atomic·Casp1(SB), NOSPLIT, $0-25
-	B runtime∕internal∕atomic·Cas64(SB)
diff --git a/src/runtime/internal/atomic/asm_mips64x.s b/src/runtime/internal/atomic/asm_mips64x.s
deleted file mode 100644
index a515683..0000000
--- a/src/runtime/internal/atomic/asm_mips64x.s
+++ /dev/null
@@ -1,271 +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.
-
-// +build mips64 mips64le
-
-#include "textflag.h"
-
-// bool cas(uint32 *ptr, uint32 old, uint32 new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	} else
-//		return 0;
-TEXT ·Cas(SB), NOSPLIT, $0-17
-	MOVV	ptr+0(FP), R1
-	MOVW	old+8(FP), R2
-	MOVW	new+12(FP), R5
-	SYNC
-cas_again:
-	MOVV	R5, R3
-	LL	(R1), R4
-	BNE	R2, R4, cas_fail
-	SC	R3, (R1)
-	BEQ	R3, cas_again
-	MOVV	$1, R1
-	MOVB	R1, ret+16(FP)
-	SYNC
-	RET
-cas_fail:
-	MOVV	$0, R1
-	JMP	-4(PC)
-
-// bool	cas64(uint64 *ptr, uint64 old, uint64 new)
-// Atomically:
-//	if(*val == *old){
-//		*val = new;
-//		return 1;
-//	} else {
-//		return 0;
-//	}
-TEXT ·Cas64(SB), NOSPLIT, $0-25
-	MOVV	ptr+0(FP), R1
-	MOVV	old+8(FP), R2
-	MOVV	new+16(FP), R5
-	SYNC
-cas64_again:
-	MOVV	R5, R3
-	LLV	(R1), R4
-	BNE	R2, R4, cas64_fail
-	SCV	R3, (R1)
-	BEQ	R3, cas64_again
-	MOVV	$1, R1
-	MOVB	R1, ret+24(FP)
-	SYNC
-	RET
-cas64_fail:
-	MOVV	$0, R1
-	JMP	-4(PC)
-
-TEXT ·Casuintptr(SB), NOSPLIT, $0-25
-	JMP	·Cas64(SB)
-
-TEXT ·CasRel(SB), NOSPLIT, $0-17
-	JMP	·Cas(SB)
-
-TEXT ·Loaduintptr(SB),  NOSPLIT|NOFRAME, $0-16
-	JMP	·Load64(SB)
-
-TEXT ·Loaduint(SB), NOSPLIT|NOFRAME, $0-16
-	JMP	·Load64(SB)
-
-TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
-	JMP	·Store64(SB)
-
-TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
-	JMP	·Xadd64(SB)
-
-TEXT ·Loadint64(SB), NOSPLIT, $0-16
-	JMP	·Load64(SB)
-
-TEXT ·Xaddint64(SB), NOSPLIT, $0-24
-	JMP	·Xadd64(SB)
-
-// bool casp(void **val, void *old, void *new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	} else
-//		return 0;
-TEXT ·Casp1(SB), NOSPLIT, $0-25
-	JMP runtime∕internal∕atomic·Cas64(SB)
-
-// uint32 xadd(uint32 volatile *ptr, int32 delta)
-// Atomically:
-//	*val += delta;
-//	return *val;
-TEXT ·Xadd(SB), NOSPLIT, $0-20
-	MOVV	ptr+0(FP), R2
-	MOVW	delta+8(FP), R3
-	SYNC
-	LL	(R2), R1
-	ADDU	R1, R3, R4
-	MOVV	R4, R1
-	SC	R4, (R2)
-	BEQ	R4, -4(PC)
-	MOVW	R1, ret+16(FP)
-	SYNC
-	RET
-
-TEXT ·Xadd64(SB), NOSPLIT, $0-24
-	MOVV	ptr+0(FP), R2
-	MOVV	delta+8(FP), R3
-	SYNC
-	LLV	(R2), R1
-	ADDVU	R1, R3, R4
-	MOVV	R4, R1
-	SCV	R4, (R2)
-	BEQ	R4, -4(PC)
-	MOVV	R1, ret+16(FP)
-	SYNC
-	RET
-
-TEXT ·Xchg(SB), NOSPLIT, $0-20
-	MOVV	ptr+0(FP), R2
-	MOVW	new+8(FP), R5
-
-	SYNC
-	MOVV	R5, R3
-	LL	(R2), R1
-	SC	R3, (R2)
-	BEQ	R3, -3(PC)
-	MOVW	R1, ret+16(FP)
-	SYNC
-	RET
-
-TEXT ·Xchg64(SB), NOSPLIT, $0-24
-	MOVV	ptr+0(FP), R2
-	MOVV	new+8(FP), R5
-
-	SYNC
-	MOVV	R5, R3
-	LLV	(R2), R1
-	SCV	R3, (R2)
-	BEQ	R3, -3(PC)
-	MOVV	R1, ret+16(FP)
-	SYNC
-	RET
-
-TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
-	JMP	·Xchg64(SB)
-
-TEXT ·StorepNoWB(SB), NOSPLIT, $0-16
-	JMP	·Store64(SB)
-
-TEXT ·StoreRel(SB), NOSPLIT, $0-12
-	JMP	·Store(SB)
-
-TEXT ·StoreRel64(SB), NOSPLIT, $0-16
-	JMP	·Store64(SB)
-
-TEXT ·StoreReluintptr(SB), NOSPLIT, $0-16
-	JMP	·Store64(SB)
-
-TEXT ·Store(SB), NOSPLIT, $0-12
-	MOVV	ptr+0(FP), R1
-	MOVW	val+8(FP), R2
-	SYNC
-	MOVW	R2, 0(R1)
-	SYNC
-	RET
-
-TEXT ·Store8(SB), NOSPLIT, $0-9
-	MOVV	ptr+0(FP), R1
-	MOVB	val+8(FP), R2
-	SYNC
-	MOVB	R2, 0(R1)
-	SYNC
-	RET
-
-TEXT ·Store64(SB), NOSPLIT, $0-16
-	MOVV	ptr+0(FP), R1
-	MOVV	val+8(FP), R2
-	SYNC
-	MOVV	R2, 0(R1)
-	SYNC
-	RET
-
-// void	Or8(byte volatile*, byte);
-TEXT ·Or8(SB), NOSPLIT, $0-9
-	MOVV	ptr+0(FP), R1
-	MOVBU	val+8(FP), R2
-	// Align ptr down to 4 bytes so we can use 32-bit load/store.
-	MOVV	$~3, R3
-	AND	R1, R3
-	// Compute val shift.
-#ifdef GOARCH_mips64
-	// Big endian.  ptr = ptr ^ 3
-	XOR	$3, R1
-#endif
-	// R4 = ((ptr & 3) * 8)
-	AND	$3, R1, R4
-	SLLV	$3, R4
-	// Shift val for aligned ptr. R2 = val << R4
-	SLLV	R4, R2
-
-	SYNC
-	LL	(R3), R4
-	OR	R2, R4
-	SC	R4, (R3)
-	BEQ	R4, -4(PC)
-	SYNC
-	RET
-
-// void	And8(byte volatile*, byte);
-TEXT ·And8(SB), NOSPLIT, $0-9
-	MOVV	ptr+0(FP), R1
-	MOVBU	val+8(FP), R2
-	// Align ptr down to 4 bytes so we can use 32-bit load/store.
-	MOVV	$~3, R3
-	AND	R1, R3
-	// Compute val shift.
-#ifdef GOARCH_mips64
-	// Big endian.  ptr = ptr ^ 3
-	XOR	$3, R1
-#endif
-	// R4 = ((ptr & 3) * 8)
-	AND	$3, R1, R4
-	SLLV	$3, R4
-	// Shift val for aligned ptr. R2 = val << R4 | ^(0xFF << R4)
-	MOVV	$0xFF, R5
-	SLLV	R4, R2
-	SLLV	R4, R5
-	NOR	R0, R5
-	OR	R5, R2
-
-	SYNC
-	LL	(R3), R4
-	AND	R2, R4
-	SC	R4, (R3)
-	BEQ	R4, -4(PC)
-	SYNC
-	RET
-
-// func Or(addr *uint32, v uint32)
-TEXT ·Or(SB), NOSPLIT, $0-12
-	MOVV	ptr+0(FP), R1
-	MOVW	val+8(FP), R2
-
-	SYNC
-	LL	(R1), R3
-	OR	R2, R3
-	SC	R3, (R1)
-	BEQ	R3, -4(PC)
-	SYNC
-	RET
-
-// func And(addr *uint32, v uint32)
-TEXT ·And(SB), NOSPLIT, $0-12
-	MOVV	ptr+0(FP), R1
-	MOVW	val+8(FP), R2
-
-	SYNC
-	LL	(R1), R3
-	AND	R2, R3
-	SC	R3, (R1)
-	BEQ	R3, -4(PC)
-	SYNC
-	RET
diff --git a/src/runtime/internal/atomic/asm_mipsx.s b/src/runtime/internal/atomic/asm_mipsx.s
deleted file mode 100644
index 2b2cfab..0000000
--- a/src/runtime/internal/atomic/asm_mipsx.s
+++ /dev/null
@@ -1,200 +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.
-
-// +build mips mipsle
-
-#include "textflag.h"
-
-TEXT ·Cas(SB),NOSPLIT,$0-13
-	MOVW	ptr+0(FP), R1
-	MOVW	old+4(FP), R2
-	MOVW	new+8(FP), R5
-	SYNC
-try_cas:
-	MOVW	R5, R3
-	LL	(R1), R4	// R4 = *R1
-	BNE	R2, R4, cas_fail
-	SC	R3, (R1)	// *R1 = R3
-	BEQ	R3, try_cas
-	SYNC
-	MOVB	R3, ret+12(FP)
-	RET
-cas_fail:
-	MOVB	R0, ret+12(FP)
-	RET
-
-TEXT ·Store(SB),NOSPLIT,$0-8
-	MOVW	ptr+0(FP), R1
-	MOVW	val+4(FP), R2
-	SYNC
-	MOVW	R2, 0(R1)
-	SYNC
-	RET
-
-TEXT ·Store8(SB),NOSPLIT,$0-5
-	MOVW	ptr+0(FP), R1
-	MOVB	val+4(FP), R2
-	SYNC
-	MOVB	R2, 0(R1)
-	SYNC
-	RET
-
-TEXT ·Load(SB),NOSPLIT,$0-8
-	MOVW	ptr+0(FP), R1
-	SYNC
-	MOVW	0(R1), R1
-	SYNC
-	MOVW	R1, ret+4(FP)
-	RET
-
-TEXT ·Load8(SB),NOSPLIT,$0-5
-	MOVW	ptr+0(FP), R1
-	SYNC
-	MOVB	0(R1), R1
-	SYNC
-	MOVB	R1, ret+4(FP)
-	RET
-
-TEXT ·Xadd(SB),NOSPLIT,$0-12
-	MOVW	ptr+0(FP), R2
-	MOVW	delta+4(FP), R3
-	SYNC
-try_xadd:
-	LL	(R2), R1	// R1 = *R2
-	ADDU	R1, R3, R4
-	MOVW	R4, R1
-	SC	R4, (R2)	// *R2 = R4
-	BEQ	R4, try_xadd
-	SYNC
-	MOVW	R1, ret+8(FP)
-	RET
-
-TEXT ·Xchg(SB),NOSPLIT,$0-12
-	MOVW	ptr+0(FP), R2
-	MOVW	new+4(FP), R5
-	SYNC
-try_xchg:
-	MOVW	R5, R3
-	LL	(R2), R1	// R1 = *R2
-	SC	R3, (R2)	// *R2 = R3
-	BEQ	R3, try_xchg
-	SYNC
-	MOVW	R1, ret+8(FP)
-	RET
-
-TEXT ·Casuintptr(SB),NOSPLIT,$0-13
-	JMP	·Cas(SB)
-
-TEXT ·CasRel(SB),NOSPLIT,$0-13
-	JMP	·Cas(SB)
-
-TEXT ·Loaduintptr(SB),NOSPLIT,$0-8
-	JMP	·Load(SB)
-
-TEXT ·Loaduint(SB),NOSPLIT,$0-8
-	JMP	·Load(SB)
-
-TEXT ·Loadp(SB),NOSPLIT,$-0-8
-	JMP	·Load(SB)
-
-TEXT ·Storeuintptr(SB),NOSPLIT,$0-8
-	JMP	·Store(SB)
-
-TEXT ·Xadduintptr(SB),NOSPLIT,$0-12
-	JMP	·Xadd(SB)
-
-TEXT ·Loadint64(SB),NOSPLIT,$0-12
-	JMP	·Load64(SB)
-
-TEXT ·Xaddint64(SB),NOSPLIT,$0-20
-	JMP	·Xadd64(SB)
-
-TEXT ·Casp1(SB),NOSPLIT,$0-13
-	JMP	·Cas(SB)
-
-TEXT ·Xchguintptr(SB),NOSPLIT,$0-12
-	JMP	·Xchg(SB)
-
-TEXT ·StorepNoWB(SB),NOSPLIT,$0-8
-	JMP	·Store(SB)
-
-TEXT ·StoreRel(SB),NOSPLIT,$0-8
-	JMP	·Store(SB)
-
-TEXT ·StoreReluintptr(SB),NOSPLIT,$0-8
-	JMP	·Store(SB)
-
-// void	Or8(byte volatile*, byte);
-TEXT ·Or8(SB),NOSPLIT,$0-5
-	MOVW	ptr+0(FP), R1
-	MOVBU	val+4(FP), R2
-	MOVW	$~3, R3	// Align ptr down to 4 bytes so we can use 32-bit load/store.
-	AND	R1, R3
-#ifdef GOARCH_mips
-	// Big endian.  ptr = ptr ^ 3
-	XOR	$3, R1
-#endif
-	AND	$3, R1, R4	// R4 = ((ptr & 3) * 8)
-	SLL	$3, R4
-	SLL	R4, R2, R2	// Shift val for aligned ptr. R2 = val << R4
-	SYNC
-try_or8:
-	LL	(R3), R4	// R4 = *R3
-	OR	R2, R4
-	SC	R4, (R3)	// *R3 = R4
-	BEQ	R4, try_or8
-	SYNC
-	RET
-
-// void	And8(byte volatile*, byte);
-TEXT ·And8(SB),NOSPLIT,$0-5
-	MOVW	ptr+0(FP), R1
-	MOVBU	val+4(FP), R2
-	MOVW	$~3, R3
-	AND	R1, R3
-#ifdef GOARCH_mips
-	// Big endian.  ptr = ptr ^ 3
-	XOR	$3, R1
-#endif
-	AND	$3, R1, R4	// R4 = ((ptr & 3) * 8)
-	SLL	$3, R4
-	MOVW	$0xFF, R5
-	SLL	R4, R2
-	SLL	R4, R5
-	NOR	R0, R5
-	OR	R5, R2	// Shift val for aligned ptr. R2 = val << R4 | ^(0xFF << R4)
-	SYNC
-try_and8:
-	LL	(R3), R4	// R4 = *R3
-	AND	R2, R4
-	SC	R4, (R3)	// *R3 = R4
-	BEQ	R4, try_and8
-	SYNC
-	RET
-
-// func Or(addr *uint32, v uint32)
-TEXT ·Or(SB), NOSPLIT, $0-8
-	MOVW	ptr+0(FP), R1
-	MOVW	val+4(FP), R2
-
-	SYNC
-	LL	(R1), R3
-	OR	R2, R3
-	SC	R3, (R1)
-	BEQ	R3, -4(PC)
-	SYNC
-	RET
-
-// func And(addr *uint32, v uint32)
-TEXT ·And(SB), NOSPLIT, $0-8
-	MOVW	ptr+0(FP), R1
-	MOVW	val+4(FP), R2
-
-	SYNC
-	LL	(R1), R3
-	AND	R2, R3
-	SC	R3, (R1)
-	BEQ	R3, -4(PC)
-	SYNC
-	RET
diff --git a/src/runtime/internal/atomic/asm_ppc64x.s b/src/runtime/internal/atomic/asm_ppc64x.s
deleted file mode 100644
index bb009ab..0000000
--- a/src/runtime/internal/atomic/asm_ppc64x.s
+++ /dev/null
@@ -1,253 +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.
-
-// +build ppc64 ppc64le
-
-#include "textflag.h"
-
-// bool cas(uint32 *ptr, uint32 old, uint32 new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	} else
-//		return 0;
-TEXT runtime∕internal∕atomic·Cas(SB), NOSPLIT, $0-17
-	MOVD	ptr+0(FP), R3
-	MOVWZ	old+8(FP), R4
-	MOVWZ	new+12(FP), R5
-	LWSYNC
-cas_again:
-	LWAR	(R3), R6
-	CMPW	R6, R4
-	BNE	cas_fail
-	STWCCC	R5, (R3)
-	BNE	cas_again
-	MOVD	$1, R3
-	LWSYNC
-	MOVB	R3, ret+16(FP)
-	RET
-cas_fail:
-	MOVB	R0, ret+16(FP)
-	RET
-
-// bool	runtime∕internal∕atomic·Cas64(uint64 *ptr, uint64 old, uint64 new)
-// Atomically:
-//	if(*val == *old){
-//		*val = new;
-//		return 1;
-//	} else {
-//		return 0;
-//	}
-TEXT runtime∕internal∕atomic·Cas64(SB), NOSPLIT, $0-25
-	MOVD	ptr+0(FP), R3
-	MOVD	old+8(FP), R4
-	MOVD	new+16(FP), R5
-	LWSYNC
-cas64_again:
-	LDAR	(R3), R6
-	CMP	R6, R4
-	BNE	cas64_fail
-	STDCCC	R5, (R3)
-	BNE	cas64_again
-	MOVD	$1, R3
-	LWSYNC
-	MOVB	R3, ret+24(FP)
-	RET
-cas64_fail:
-	MOVB	R0, ret+24(FP)
-	RET
-
-TEXT runtime∕internal∕atomic·CasRel(SB), NOSPLIT, $0-17
-	MOVD    ptr+0(FP), R3
-	MOVWZ   old+8(FP), R4
-	MOVWZ   new+12(FP), R5
-	LWSYNC
-cas_again:
-	LWAR    (R3), $0, R6        // 0 = Mutex release hint
-	CMPW    R6, R4
-	BNE     cas_fail
-	STWCCC  R5, (R3)
-	BNE     cas_again
-	MOVD    $1, R3
-	MOVB    R3, ret+16(FP)
-	RET
-cas_fail:
-	MOVB    R0, ret+16(FP)
-	RET
-
-TEXT runtime∕internal∕atomic·Casuintptr(SB), NOSPLIT, $0-25
-	BR	runtime∕internal∕atomic·Cas64(SB)
-
-TEXT runtime∕internal∕atomic·Loaduintptr(SB),  NOSPLIT|NOFRAME, $0-16
-	BR	runtime∕internal∕atomic·Load64(SB)
-
-TEXT runtime∕internal∕atomic·LoadAcquintptr(SB),  NOSPLIT|NOFRAME, $0-16
-	BR	runtime∕internal∕atomic·LoadAcq64(SB)
-
-TEXT runtime∕internal∕atomic·Loaduint(SB), NOSPLIT|NOFRAME, $0-16
-	BR	runtime∕internal∕atomic·Load64(SB)
-
-TEXT runtime∕internal∕atomic·Storeuintptr(SB), NOSPLIT, $0-16
-	BR	runtime∕internal∕atomic·Store64(SB)
-
-TEXT runtime∕internal∕atomic·StoreReluintptr(SB), NOSPLIT, $0-16
-	BR	runtime∕internal∕atomic·StoreRel64(SB)
-
-TEXT runtime∕internal∕atomic·Xadduintptr(SB), NOSPLIT, $0-24
-	BR	runtime∕internal∕atomic·Xadd64(SB)
-
-TEXT runtime∕internal∕atomic·Loadint64(SB), NOSPLIT, $0-16
-	BR	runtime∕internal∕atomic·Load64(SB)
-
-TEXT runtime∕internal∕atomic·Xaddint64(SB), NOSPLIT, $0-24
-	BR	runtime∕internal∕atomic·Xadd64(SB)
-
-// bool casp(void **val, void *old, void *new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	} else
-//		return 0;
-TEXT runtime∕internal∕atomic·Casp1(SB), NOSPLIT, $0-25
-	BR runtime∕internal∕atomic·Cas64(SB)
-
-// uint32 xadd(uint32 volatile *ptr, int32 delta)
-// Atomically:
-//	*val += delta;
-//	return *val;
-TEXT runtime∕internal∕atomic·Xadd(SB), NOSPLIT, $0-20
-	MOVD	ptr+0(FP), R4
-	MOVW	delta+8(FP), R5
-	LWSYNC
-	LWAR	(R4), R3
-	ADD	R5, R3
-	STWCCC	R3, (R4)
-	BNE	-3(PC)
-	MOVW	R3, ret+16(FP)
-	RET
-
-TEXT runtime∕internal∕atomic·Xadd64(SB), NOSPLIT, $0-24
-	MOVD	ptr+0(FP), R4
-	MOVD	delta+8(FP), R5
-	LWSYNC
-	LDAR	(R4), R3
-	ADD	R5, R3
-	STDCCC	R3, (R4)
-	BNE	-3(PC)
-	MOVD	R3, ret+16(FP)
-	RET
-
-TEXT runtime∕internal∕atomic·Xchg(SB), NOSPLIT, $0-20
-	MOVD	ptr+0(FP), R4
-	MOVW	new+8(FP), R5
-	LWSYNC
-	LWAR	(R4), R3
-	STWCCC	R5, (R4)
-	BNE	-2(PC)
-	ISYNC
-	MOVW	R3, ret+16(FP)
-	RET
-
-TEXT runtime∕internal∕atomic·Xchg64(SB), NOSPLIT, $0-24
-	MOVD	ptr+0(FP), R4
-	MOVD	new+8(FP), R5
-	LWSYNC
-	LDAR	(R4), R3
-	STDCCC	R5, (R4)
-	BNE	-2(PC)
-	ISYNC
-	MOVD	R3, ret+16(FP)
-	RET
-
-TEXT runtime∕internal∕atomic·Xchguintptr(SB), NOSPLIT, $0-24
-	BR	runtime∕internal∕atomic·Xchg64(SB)
-
-
-TEXT runtime∕internal∕atomic·StorepNoWB(SB), NOSPLIT, $0-16
-	BR	runtime∕internal∕atomic·Store64(SB)
-
-TEXT runtime∕internal∕atomic·Store(SB), NOSPLIT, $0-12
-	MOVD	ptr+0(FP), R3
-	MOVW	val+8(FP), R4
-	SYNC
-	MOVW	R4, 0(R3)
-	RET
-
-TEXT runtime∕internal∕atomic·Store8(SB), NOSPLIT, $0-9
-	MOVD	ptr+0(FP), R3
-	MOVB	val+8(FP), R4
-	SYNC
-	MOVB	R4, 0(R3)
-	RET
-
-TEXT runtime∕internal∕atomic·Store64(SB), NOSPLIT, $0-16
-	MOVD	ptr+0(FP), R3
-	MOVD	val+8(FP), R4
-	SYNC
-	MOVD	R4, 0(R3)
-	RET
-
-TEXT runtime∕internal∕atomic·StoreRel(SB), NOSPLIT, $0-12
-	MOVD	ptr+0(FP), R3
-	MOVW	val+8(FP), R4
-	LWSYNC
-	MOVW	R4, 0(R3)
-	RET
-
-TEXT runtime∕internal∕atomic·StoreRel64(SB), NOSPLIT, $0-16
-	MOVD	ptr+0(FP), R3
-	MOVD	val+8(FP), R4
-	LWSYNC
-	MOVD	R4, 0(R3)
-	RET
-
-// void runtime∕internal∕atomic·Or8(byte volatile*, byte);
-TEXT runtime∕internal∕atomic·Or8(SB), NOSPLIT, $0-9
-	MOVD	ptr+0(FP), R3
-	MOVBZ	val+8(FP), R4
-	LWSYNC
-again:
-	LBAR	(R3), R6
-	OR	R4, R6
-	STBCCC	R6, (R3)
-	BNE	again
-	RET
-
-// void runtime∕internal∕atomic·And8(byte volatile*, byte);
-TEXT runtime∕internal∕atomic·And8(SB), NOSPLIT, $0-9
-	MOVD	ptr+0(FP), R3
-	MOVBZ	val+8(FP), R4
-	LWSYNC
-again:
-	LBAR	(R3), R6
-	AND	R4, R6
-	STBCCC	R6, (R3)
-	BNE	again
-	RET
-
-// func Or(addr *uint32, v uint32)
-TEXT runtime∕internal∕atomic·Or(SB), NOSPLIT, $0-12
-	MOVD	ptr+0(FP), R3
-	MOVW	val+8(FP), R4
-	LWSYNC
-again:
-	LWAR	(R3), R6
-	OR	R4, R6
-	STWCCC	R6, (R3)
-	BNE	again
-	RET
-
-// func And(addr *uint32, v uint32)
-TEXT runtime∕internal∕atomic·And(SB), NOSPLIT, $0-12
-	MOVD	ptr+0(FP), R3
-	MOVW	val+8(FP), R4
-	LWSYNC
-again:
-	LWAR	(R3),R6
-	AND	R4, R6
-	STWCCC	R6, (R3)
-	BNE	again
-	RET
diff --git a/src/runtime/internal/atomic/asm_s390x.s b/src/runtime/internal/atomic/asm_s390x.s
deleted file mode 100644
index daf1f3c..0000000
--- a/src/runtime/internal/atomic/asm_s390x.s
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func Store(ptr *uint32, val uint32)
-TEXT ·Store(SB), NOSPLIT, $0
-	MOVD	ptr+0(FP), R2
-	MOVWZ	val+8(FP), R3
-	MOVW	R3, 0(R2)
-	SYNC
-	RET
-
-// func Store8(ptr *uint8, val uint8)
-TEXT ·Store8(SB), NOSPLIT, $0
-	MOVD	ptr+0(FP), R2
-	MOVB	val+8(FP), R3
-	MOVB	R3, 0(R2)
-	SYNC
-	RET
-
-// func Store64(ptr *uint64, val uint64)
-TEXT ·Store64(SB), NOSPLIT, $0
-	MOVD	ptr+0(FP), R2
-	MOVD	val+8(FP), R3
-	MOVD	R3, 0(R2)
-	SYNC
-	RET
-
-// func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)
-TEXT ·StorepNoWB(SB), NOSPLIT, $0
-	MOVD	ptr+0(FP), R2
-	MOVD	val+8(FP), R3
-	MOVD	R3, 0(R2)
-	SYNC
-	RET
-
-// func Cas(ptr *uint32, old, new uint32) bool
-// Atomically:
-//	if *ptr == old {
-//		*val = new
-//		return 1
-//	} else {
-//		return 0
-//	}
-TEXT ·Cas(SB), NOSPLIT, $0-17
-	MOVD	ptr+0(FP), R3
-	MOVWZ	old+8(FP), R4
-	MOVWZ	new+12(FP), R5
-	CS	R4, R5, 0(R3)    //  if (R4 == 0(R3)) then 0(R3)= R5
-	BNE	cas_fail
-	MOVB	$1, ret+16(FP)
-	RET
-cas_fail:
-	MOVB	$0, ret+16(FP)
-	RET
-
-// func Cas64(ptr *uint64, old, new uint64) bool
-// Atomically:
-//	if *ptr == old {
-//		*ptr = new
-//		return 1
-//	} else {
-//		return 0
-//	}
-TEXT ·Cas64(SB), NOSPLIT, $0-25
-	MOVD	ptr+0(FP), R3
-	MOVD	old+8(FP), R4
-	MOVD	new+16(FP), R5
-	CSG	R4, R5, 0(R3)    //  if (R4 == 0(R3)) then 0(R3)= R5
-	BNE	cas64_fail
-	MOVB	$1, ret+24(FP)
-	RET
-cas64_fail:
-	MOVB	$0, ret+24(FP)
-	RET
-
-// func Casuintptr(ptr *uintptr, old, new uintptr) bool
-TEXT ·Casuintptr(SB), NOSPLIT, $0-25
-	BR	·Cas64(SB)
-
-// func CasRel(ptr *uint32, old, new uint32) bool
-TEXT ·CasRel(SB), NOSPLIT, $0-17
-	BR	·Cas(SB)
-
-// func Loaduintptr(ptr *uintptr) uintptr
-TEXT ·Loaduintptr(SB), NOSPLIT, $0-16
-	BR	·Load64(SB)
-
-// func Loaduint(ptr *uint) uint
-TEXT ·Loaduint(SB), NOSPLIT, $0-16
-	BR	·Load64(SB)
-
-// func Storeuintptr(ptr *uintptr, new uintptr)
-TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
-	BR	·Store64(SB)
-
-// func Loadint64(ptr *int64) int64
-TEXT ·Loadint64(SB), NOSPLIT, $0-16
-	BR	·Load64(SB)
-
-// func Xadduintptr(ptr *uintptr, delta uintptr) uintptr
-TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
-	BR	·Xadd64(SB)
-
-// func Xaddint64(ptr *int64, delta int64) int64
-TEXT ·Xaddint64(SB), NOSPLIT, $0-24
-	BR	·Xadd64(SB)
-
-// func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool
-// Atomically:
-//	if *ptr == old {
-//		*ptr = new
-//		return 1
-//	} else {
-//		return 0
-//	}
-TEXT ·Casp1(SB), NOSPLIT, $0-25
-	BR ·Cas64(SB)
-
-// func Xadd(ptr *uint32, delta int32) uint32
-// Atomically:
-//	*ptr += delta
-//	return *ptr
-TEXT ·Xadd(SB), NOSPLIT, $0-20
-	MOVD	ptr+0(FP), R4
-	MOVW	delta+8(FP), R5
-	MOVW	(R4), R3
-repeat:
-	ADD	R5, R3, R6
-	CS	R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
-	BNE	repeat
-	MOVW	R6, ret+16(FP)
-	RET
-
-// func Xadd64(ptr *uint64, delta int64) uint64
-TEXT ·Xadd64(SB), NOSPLIT, $0-24
-	MOVD	ptr+0(FP), R4
-	MOVD	delta+8(FP), R5
-	MOVD	(R4), R3
-repeat:
-	ADD	R5, R3, R6
-	CSG	R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
-	BNE	repeat
-	MOVD	R6, ret+16(FP)
-	RET
-
-// func Xchg(ptr *uint32, new uint32) uint32
-TEXT ·Xchg(SB), NOSPLIT, $0-20
-	MOVD	ptr+0(FP), R4
-	MOVW	new+8(FP), R3
-	MOVW	(R4), R6
-repeat:
-	CS	R6, R3, (R4) // if R6==(R4) then (R4)=R3 else R6=(R4)
-	BNE	repeat
-	MOVW	R6, ret+16(FP)
-	RET
-
-// func Xchg64(ptr *uint64, new uint64) uint64
-TEXT ·Xchg64(SB), NOSPLIT, $0-24
-	MOVD	ptr+0(FP), R4
-	MOVD	new+8(FP), R3
-	MOVD	(R4), R6
-repeat:
-	CSG	R6, R3, (R4) // if R6==(R4) then (R4)=R3 else R6=(R4)
-	BNE	repeat
-	MOVD	R6, ret+16(FP)
-	RET
-
-// func Xchguintptr(ptr *uintptr, new uintptr) uintptr
-TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
-	BR	·Xchg64(SB)
-
-// func Or8(addr *uint8, v uint8)
-TEXT ·Or8(SB), NOSPLIT, $0-9
-	MOVD	ptr+0(FP), R3
-	MOVBZ	val+8(FP), R4
-	// We don't have atomic operations that work on individual bytes so we
-	// need to align addr down to a word boundary and create a mask
-	// containing v to OR with the entire word atomically.
-	MOVD	$(3<<3), R5
-	RXSBG	$59, $60, $3, R3, R5 // R5 = 24 - ((addr % 4) * 8) = ((addr & 3) << 3) ^ (3 << 3)
-	ANDW	$~3, R3              // R3 = floor(addr, 4) = addr &^ 3
-	SLW	R5, R4               // R4 = uint32(v) << R5
-	LAO	R4, R6, 0(R3)        // R6 = *R3; *R3 |= R4; (atomic)
-	RET
-
-// func And8(addr *uint8, v uint8)
-TEXT ·And8(SB), NOSPLIT, $0-9
-	MOVD	ptr+0(FP), R3
-	MOVBZ	val+8(FP), R4
-	// We don't have atomic operations that work on individual bytes so we
-	// need to align addr down to a word boundary and create a mask
-	// containing v to AND with the entire word atomically.
-	ORW	$~0xff, R4           // R4 = uint32(v) | 0xffffff00
-	MOVD	$(3<<3), R5
-	RXSBG	$59, $60, $3, R3, R5 // R5 = 24 - ((addr % 4) * 8) = ((addr & 3) << 3) ^ (3 << 3)
-	ANDW	$~3, R3              // R3 = floor(addr, 4) = addr &^ 3
-	RLL	R5, R4, R4           // R4 = rotl(R4, R5)
-	LAN	R4, R6, 0(R3)        // R6 = *R3; *R3 &= R4; (atomic)
-	RET
-
-// func Or(addr *uint32, v uint32)
-TEXT ·Or(SB), NOSPLIT, $0-12
-	MOVD	ptr+0(FP), R3
-	MOVW	val+8(FP), R4
-	LAO	R4, R6, 0(R3)        // R6 = *R3; *R3 |= R4; (atomic)
-	RET
-
-// func And(addr *uint32, v uint32)
-TEXT ·And(SB), NOSPLIT, $0-12
-	MOVD	ptr+0(FP), R3
-	MOVW	val+8(FP), R4
-	LAN	R4, R6, 0(R3)        // R6 = *R3; *R3 &= R4; (atomic)
-	RET
diff --git a/src/runtime/internal/atomic/asm_wasm.s b/src/runtime/internal/atomic/asm_wasm.s
deleted file mode 100644
index 7c33cb1..0000000
--- a/src/runtime/internal/atomic/asm_wasm.s
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-TEXT runtime∕internal∕atomic·StorepNoWB(SB), NOSPLIT, $0-16
-	MOVD ptr+0(FP), R0
-	MOVD val+8(FP), 0(R0)
-	RET
diff --git a/src/runtime/internal/atomic/atomic_386.go b/src/runtime/internal/atomic/atomic_386.go
index 1bfcb11..d4aed6b 100644
--- a/src/runtime/internal/atomic/atomic_386.go
+++ b/src/runtime/internal/atomic/atomic_386.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386
 // +build 386
 
 package atomic
diff --git a/src/runtime/internal/atomic/atomic_386.s b/src/runtime/internal/atomic/atomic_386.s
new file mode 100644
index 0000000..724d515
--- /dev/null
+++ b/src/runtime/internal/atomic/atomic_386.s
@@ -0,0 +1,285 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+// bool Cas(int32 *val, int32 old, int32 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	}else
+//		return 0;
+TEXT ·Cas(SB), NOSPLIT, $0-13
+	MOVL	ptr+0(FP), BX
+	MOVL	old+4(FP), AX
+	MOVL	new+8(FP), CX
+	LOCK
+	CMPXCHGL	CX, 0(BX)
+	SETEQ	ret+12(FP)
+	RET
+
+TEXT ·Casint32(SB), NOSPLIT, $0-13
+	JMP	·Cas(SB)
+
+TEXT ·Casint64(SB), NOSPLIT, $0-21
+	JMP	·Cas64(SB)
+
+TEXT ·Casuintptr(SB), NOSPLIT, $0-13
+	JMP	·Cas(SB)
+
+TEXT ·CasRel(SB), NOSPLIT, $0-13
+	JMP	·Cas(SB)
+
+TEXT ·Loaduintptr(SB), NOSPLIT, $0-8
+	JMP	·Load(SB)
+
+TEXT ·Loaduint(SB), NOSPLIT, $0-8
+	JMP	·Load(SB)
+
+TEXT ·Storeint32(SB), NOSPLIT, $0-8
+	JMP	·Store(SB)
+
+TEXT ·Storeint64(SB), NOSPLIT, $0-12
+	JMP	·Store64(SB)
+
+TEXT ·Storeuintptr(SB), NOSPLIT, $0-8
+	JMP	·Store(SB)
+
+TEXT ·Xadduintptr(SB), NOSPLIT, $0-12
+	JMP	·Xadd(SB)
+
+TEXT ·Loadint32(SB), NOSPLIT, $0-8
+	JMP	·Load(SB)
+
+TEXT ·Loadint64(SB), NOSPLIT, $0-12
+	JMP	·Load64(SB)
+
+TEXT ·Xaddint32(SB), NOSPLIT, $0-12
+	JMP	·Xadd(SB)
+
+TEXT ·Xaddint64(SB), NOSPLIT, $0-20
+	JMP	·Xadd64(SB)
+
+// bool ·Cas64(uint64 *val, uint64 old, uint64 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else {
+//		return 0;
+//	}
+TEXT ·Cas64(SB), NOSPLIT, $0-21
+	NO_LOCAL_POINTERS
+	MOVL	ptr+0(FP), BP
+	TESTL	$7, BP
+	JZ	2(PC)
+	CALL	·panicUnaligned(SB)
+	MOVL	old_lo+4(FP), AX
+	MOVL	old_hi+8(FP), DX
+	MOVL	new_lo+12(FP), BX
+	MOVL	new_hi+16(FP), CX
+	LOCK
+	CMPXCHG8B	0(BP)
+	SETEQ	ret+20(FP)
+	RET
+
+// bool Casp1(void **p, void *old, void *new)
+// Atomically:
+//	if(*p == old){
+//		*p = new;
+//		return 1;
+//	}else
+//		return 0;
+TEXT ·Casp1(SB), NOSPLIT, $0-13
+	MOVL	ptr+0(FP), BX
+	MOVL	old+4(FP), AX
+	MOVL	new+8(FP), CX
+	LOCK
+	CMPXCHGL	CX, 0(BX)
+	SETEQ	ret+12(FP)
+	RET
+
+// uint32 Xadd(uint32 volatile *val, int32 delta)
+// Atomically:
+//	*val += delta;
+//	return *val;
+TEXT ·Xadd(SB), NOSPLIT, $0-12
+	MOVL	ptr+0(FP), BX
+	MOVL	delta+4(FP), AX
+	MOVL	AX, CX
+	LOCK
+	XADDL	AX, 0(BX)
+	ADDL	CX, AX
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT ·Xadd64(SB), NOSPLIT, $0-20
+	NO_LOCAL_POINTERS
+	// no XADDQ so use CMPXCHG8B loop
+	MOVL	ptr+0(FP), BP
+	TESTL	$7, BP
+	JZ	2(PC)
+	CALL	·panicUnaligned(SB)
+	// DI:SI = delta
+	MOVL	delta_lo+4(FP), SI
+	MOVL	delta_hi+8(FP), DI
+	// DX:AX = *addr
+	MOVL	0(BP), AX
+	MOVL	4(BP), DX
+addloop:
+	// CX:BX = DX:AX (*addr) + DI:SI (delta)
+	MOVL	AX, BX
+	MOVL	DX, CX
+	ADDL	SI, BX
+	ADCL	DI, CX
+
+	// if *addr == DX:AX {
+	//	*addr = CX:BX
+	// } else {
+	//	DX:AX = *addr
+	// }
+	// all in one instruction
+	LOCK
+	CMPXCHG8B	0(BP)
+
+	JNZ	addloop
+
+	// success
+	// return CX:BX
+	MOVL	BX, ret_lo+12(FP)
+	MOVL	CX, ret_hi+16(FP)
+	RET
+
+TEXT ·Xchg(SB), NOSPLIT, $0-12
+	MOVL	ptr+0(FP), BX
+	MOVL	new+4(FP), AX
+	XCHGL	AX, 0(BX)
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT ·Xchgint32(SB), NOSPLIT, $0-12
+	JMP	·Xchg(SB)
+
+TEXT ·Xchgint64(SB), NOSPLIT, $0-20
+	JMP	·Xchg64(SB)
+
+TEXT ·Xchguintptr(SB), NOSPLIT, $0-12
+	JMP	·Xchg(SB)
+
+TEXT ·Xchg64(SB),NOSPLIT,$0-20
+	NO_LOCAL_POINTERS
+	// no XCHGQ so use CMPXCHG8B loop
+	MOVL	ptr+0(FP), BP
+	TESTL	$7, BP
+	JZ	2(PC)
+	CALL	·panicUnaligned(SB)
+	// CX:BX = new
+	MOVL	new_lo+4(FP), BX
+	MOVL	new_hi+8(FP), CX
+	// DX:AX = *addr
+	MOVL	0(BP), AX
+	MOVL	4(BP), DX
+swaploop:
+	// if *addr == DX:AX
+	//	*addr = CX:BX
+	// else
+	//	DX:AX = *addr
+	// all in one instruction
+	LOCK
+	CMPXCHG8B	0(BP)
+	JNZ	swaploop
+
+	// success
+	// return DX:AX
+	MOVL	AX, ret_lo+12(FP)
+	MOVL	DX, ret_hi+16(FP)
+	RET
+
+TEXT ·StorepNoWB(SB), NOSPLIT, $0-8
+	MOVL	ptr+0(FP), BX
+	MOVL	val+4(FP), AX
+	XCHGL	AX, 0(BX)
+	RET
+
+TEXT ·Store(SB), NOSPLIT, $0-8
+	MOVL	ptr+0(FP), BX
+	MOVL	val+4(FP), AX
+	XCHGL	AX, 0(BX)
+	RET
+
+TEXT ·StoreRel(SB), NOSPLIT, $0-8
+	JMP	·Store(SB)
+
+TEXT ·StoreReluintptr(SB), NOSPLIT, $0-8
+	JMP	·Store(SB)
+
+// uint64 atomicload64(uint64 volatile* addr);
+TEXT ·Load64(SB), NOSPLIT, $0-12
+	NO_LOCAL_POINTERS
+	MOVL	ptr+0(FP), AX
+	TESTL	$7, AX
+	JZ	2(PC)
+	CALL	·panicUnaligned(SB)
+	MOVQ	(AX), M0
+	MOVQ	M0, ret+4(FP)
+	EMMS
+	RET
+
+// void ·Store64(uint64 volatile* addr, uint64 v);
+TEXT ·Store64(SB), NOSPLIT, $0-12
+	NO_LOCAL_POINTERS
+	MOVL	ptr+0(FP), AX
+	TESTL	$7, AX
+	JZ	2(PC)
+	CALL	·panicUnaligned(SB)
+	// MOVQ and EMMS were introduced on the Pentium MMX.
+	MOVQ	val+4(FP), M0
+	MOVQ	M0, (AX)
+	EMMS
+	// This is essentially a no-op, but it provides required memory fencing.
+	// It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
+	XORL	AX, AX
+	LOCK
+	XADDL	AX, (SP)
+	RET
+
+// void	·Or8(byte volatile*, byte);
+TEXT ·Or8(SB), NOSPLIT, $0-5
+	MOVL	ptr+0(FP), AX
+	MOVB	val+4(FP), BX
+	LOCK
+	ORB	BX, (AX)
+	RET
+
+// void	·And8(byte volatile*, byte);
+TEXT ·And8(SB), NOSPLIT, $0-5
+	MOVL	ptr+0(FP), AX
+	MOVB	val+4(FP), BX
+	LOCK
+	ANDB	BX, (AX)
+	RET
+
+TEXT ·Store8(SB), NOSPLIT, $0-5
+	MOVL	ptr+0(FP), BX
+	MOVB	val+4(FP), AX
+	XCHGB	AX, 0(BX)
+	RET
+
+// func Or(addr *uint32, v uint32)
+TEXT ·Or(SB), NOSPLIT, $0-8
+	MOVL	ptr+0(FP), AX
+	MOVL	val+4(FP), BX
+	LOCK
+	ORL	BX, (AX)
+	RET
+
+// func And(addr *uint32, v uint32)
+TEXT ·And(SB), NOSPLIT, $0-8
+	MOVL	ptr+0(FP), AX
+	MOVL	val+4(FP), BX
+	LOCK
+	ANDL	BX, (AX)
+	RET
diff --git a/src/runtime/internal/atomic/atomic_amd64.s b/src/runtime/internal/atomic/atomic_amd64.s
new file mode 100644
index 0000000..d21514b
--- /dev/null
+++ b/src/runtime/internal/atomic/atomic_amd64.s
@@ -0,0 +1,225 @@
+// 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.
+
+// Note: some of these functions are semantically inlined
+// by the compiler (in src/cmd/compile/internal/gc/ssa.go).
+
+#include "textflag.h"
+
+TEXT ·Loaduintptr(SB), NOSPLIT, $0-16
+	JMP	·Load64(SB)
+
+TEXT ·Loaduint(SB), NOSPLIT, $0-16
+	JMP	·Load64(SB)
+
+TEXT ·Loadint32(SB), NOSPLIT, $0-12
+	JMP	·Load(SB)
+
+TEXT ·Loadint64(SB), NOSPLIT, $0-16
+	JMP	·Load64(SB)
+
+// bool Cas(int32 *val, int32 old, int32 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else
+//		return 0;
+TEXT ·Cas(SB),NOSPLIT,$0-17
+	MOVQ	ptr+0(FP), BX
+	MOVL	old+8(FP), AX
+	MOVL	new+12(FP), CX
+	LOCK
+	CMPXCHGL	CX, 0(BX)
+	SETEQ	ret+16(FP)
+	RET
+
+// bool	·Cas64(uint64 *val, uint64 old, uint64 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else {
+//		return 0;
+//	}
+TEXT ·Cas64(SB), NOSPLIT, $0-25
+	MOVQ	ptr+0(FP), BX
+	MOVQ	old+8(FP), AX
+	MOVQ	new+16(FP), CX
+	LOCK
+	CMPXCHGQ	CX, 0(BX)
+	SETEQ	ret+24(FP)
+	RET
+
+// bool Casp1(void **val, void *old, void *new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else
+//		return 0;
+TEXT ·Casp1(SB), NOSPLIT, $0-25
+	MOVQ	ptr+0(FP), BX
+	MOVQ	old+8(FP), AX
+	MOVQ	new+16(FP), CX
+	LOCK
+	CMPXCHGQ	CX, 0(BX)
+	SETEQ	ret+24(FP)
+	RET
+
+TEXT ·Casint32(SB), NOSPLIT, $0-17
+	JMP	·Cas(SB)
+
+TEXT ·Casint64(SB), NOSPLIT, $0-25
+	JMP	·Cas64(SB)
+
+TEXT ·Casuintptr(SB), NOSPLIT, $0-25
+	JMP	·Cas64(SB)
+
+TEXT ·CasRel(SB), NOSPLIT, $0-17
+	JMP	·Cas(SB)
+
+// uint32 Xadd(uint32 volatile *val, int32 delta)
+// Atomically:
+//	*val += delta;
+//	return *val;
+TEXT ·Xadd(SB), NOSPLIT, $0-20
+	MOVQ	ptr+0(FP), BX
+	MOVL	delta+8(FP), AX
+	MOVL	AX, CX
+	LOCK
+	XADDL	AX, 0(BX)
+	ADDL	CX, AX
+	MOVL	AX, ret+16(FP)
+	RET
+
+// uint64 Xadd64(uint64 volatile *val, int64 delta)
+// Atomically:
+//	*val += delta;
+//	return *val;
+TEXT ·Xadd64(SB), NOSPLIT, $0-24
+	MOVQ	ptr+0(FP), BX
+	MOVQ	delta+8(FP), AX
+	MOVQ	AX, CX
+	LOCK
+	XADDQ	AX, 0(BX)
+	ADDQ	CX, AX
+	MOVQ	AX, ret+16(FP)
+	RET
+
+TEXT ·Xaddint32(SB), NOSPLIT, $0-20
+	JMP	·Xadd(SB)
+
+TEXT ·Xaddint64(SB), NOSPLIT, $0-24
+	JMP	·Xadd64(SB)
+
+TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
+	JMP	·Xadd64(SB)
+
+// uint32 Xchg(ptr *uint32, new uint32)
+// Atomically:
+//	old := *ptr;
+//	*ptr = new;
+//	return old;
+TEXT ·Xchg(SB), NOSPLIT, $0-20
+	MOVQ	ptr+0(FP), BX
+	MOVL	new+8(FP), AX
+	XCHGL	AX, 0(BX)
+	MOVL	AX, ret+16(FP)
+	RET
+
+// uint64 Xchg64(ptr *uint64, new uint64)
+// Atomically:
+//	old := *ptr;
+//	*ptr = new;
+//	return old;
+TEXT ·Xchg64(SB), NOSPLIT, $0-24
+	MOVQ	ptr+0(FP), BX
+	MOVQ	new+8(FP), AX
+	XCHGQ	AX, 0(BX)
+	MOVQ	AX, ret+16(FP)
+	RET
+
+TEXT ·Xchgint32(SB), NOSPLIT, $0-20
+	JMP	·Xchg(SB)
+
+TEXT ·Xchgint64(SB), NOSPLIT, $0-24
+	JMP	·Xchg64(SB)
+
+TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
+	JMP	·Xchg64(SB)
+
+TEXT ·StorepNoWB(SB), NOSPLIT, $0-16
+	MOVQ	ptr+0(FP), BX
+	MOVQ	val+8(FP), AX
+	XCHGQ	AX, 0(BX)
+	RET
+
+TEXT ·Store(SB), NOSPLIT, $0-12
+	MOVQ	ptr+0(FP), BX
+	MOVL	val+8(FP), AX
+	XCHGL	AX, 0(BX)
+	RET
+
+TEXT ·Store8(SB), NOSPLIT, $0-9
+	MOVQ	ptr+0(FP), BX
+	MOVB	val+8(FP), AX
+	XCHGB	AX, 0(BX)
+	RET
+
+TEXT ·Store64(SB), NOSPLIT, $0-16
+	MOVQ	ptr+0(FP), BX
+	MOVQ	val+8(FP), AX
+	XCHGQ	AX, 0(BX)
+	RET
+
+TEXT ·Storeint32(SB), NOSPLIT, $0-12
+	JMP	·Store(SB)
+
+TEXT ·Storeint64(SB), NOSPLIT, $0-16
+	JMP	·Store64(SB)
+
+TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
+	JMP	·Store64(SB)
+
+TEXT ·StoreRel(SB), NOSPLIT, $0-12
+	JMP	·Store(SB)
+
+TEXT ·StoreRel64(SB), NOSPLIT, $0-16
+	JMP	·Store64(SB)
+
+TEXT ·StoreReluintptr(SB), NOSPLIT, $0-16
+	JMP	·Store64(SB)
+
+// void	·Or8(byte volatile*, byte);
+TEXT ·Or8(SB), NOSPLIT, $0-9
+	MOVQ	ptr+0(FP), AX
+	MOVB	val+8(FP), BX
+	LOCK
+	ORB	BX, (AX)
+	RET
+
+// void	·And8(byte volatile*, byte);
+TEXT ·And8(SB), NOSPLIT, $0-9
+	MOVQ	ptr+0(FP), AX
+	MOVB	val+8(FP), BX
+	LOCK
+	ANDB	BX, (AX)
+	RET
+
+// func Or(addr *uint32, v uint32)
+TEXT ·Or(SB), NOSPLIT, $0-12
+	MOVQ	ptr+0(FP), AX
+	MOVL	val+8(FP), BX
+	LOCK
+	ORL	BX, (AX)
+	RET
+
+// func And(addr *uint32, v uint32)
+TEXT ·And(SB), NOSPLIT, $0-12
+	MOVQ	ptr+0(FP), AX
+	MOVL	val+8(FP), BX
+	LOCK
+	ANDL	BX, (AX)
+	RET
diff --git a/src/runtime/internal/atomic/atomic_arm.go b/src/runtime/internal/atomic/atomic_arm.go
index 546b3d6..2e9374c 100644
--- a/src/runtime/internal/atomic/atomic_arm.go
+++ b/src/runtime/internal/atomic/atomic_arm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm
 // +build arm
 
 package atomic
diff --git a/src/runtime/internal/atomic/atomic_arm.s b/src/runtime/internal/atomic/atomic_arm.s
new file mode 100644
index 0000000..be3fd3a
--- /dev/null
+++ b/src/runtime/internal/atomic/atomic_arm.s
@@ -0,0 +1,307 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+// bool armcas(int32 *val, int32 old, int32 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	}else
+//		return 0;
+//
+// To implement ·cas in sys_$GOOS_arm.s
+// using the native instructions, use:
+//
+//	TEXT ·cas(SB),NOSPLIT,$0
+//		B	·armcas(SB)
+//
+TEXT ·armcas(SB),NOSPLIT,$0-13
+	MOVW	ptr+0(FP), R1
+	MOVW	old+4(FP), R2
+	MOVW	new+8(FP), R3
+casl:
+	LDREX	(R1), R0
+	CMP	R0, R2
+	BNE	casfail
+
+	MOVB	runtime·goarm(SB), R8
+	CMP	$7, R8
+	BLT	2(PC)
+	DMB	MB_ISHST
+
+	STREX	R3, (R1), R0
+	CMP	$0, R0
+	BNE	casl
+	MOVW	$1, R0
+
+	CMP	$7, R8
+	BLT	2(PC)
+	DMB	MB_ISH
+
+	MOVB	R0, ret+12(FP)
+	RET
+casfail:
+	MOVW	$0, R0
+	MOVB	R0, ret+12(FP)
+	RET
+
+// stubs
+
+TEXT ·Loadp(SB),NOSPLIT|NOFRAME,$0-8
+	B	·Load(SB)
+
+TEXT ·LoadAcq(SB),NOSPLIT|NOFRAME,$0-8
+	B	·Load(SB)
+
+TEXT ·LoadAcquintptr(SB),NOSPLIT|NOFRAME,$0-8
+	B 	·Load(SB)
+
+TEXT ·Casint32(SB),NOSPLIT,$0-13
+	B	·Cas(SB)
+
+TEXT ·Casint64(SB),NOSPLIT,$-4-21
+	B	·Cas64(SB)
+
+TEXT ·Casuintptr(SB),NOSPLIT,$0-13
+	B	·Cas(SB)
+
+TEXT ·Casp1(SB),NOSPLIT,$0-13
+	B	·Cas(SB)
+
+TEXT ·CasRel(SB),NOSPLIT,$0-13
+	B	·Cas(SB)
+
+TEXT ·Loadint32(SB),NOSPLIT,$0-8
+	B	·Load(SB)
+
+TEXT ·Loadint64(SB),NOSPLIT,$-4-12
+	B	·Load64(SB)
+
+TEXT ·Loaduintptr(SB),NOSPLIT,$0-8
+	B	·Load(SB)
+
+TEXT ·Loaduint(SB),NOSPLIT,$0-8
+	B	·Load(SB)
+
+TEXT ·Storeint32(SB),NOSPLIT,$0-8
+	B	·Store(SB)
+
+TEXT ·Storeint64(SB),NOSPLIT,$0-12
+	B	·Store64(SB)
+
+TEXT ·Storeuintptr(SB),NOSPLIT,$0-8
+	B	·Store(SB)
+
+TEXT ·StorepNoWB(SB),NOSPLIT,$0-8
+	B	·Store(SB)
+
+TEXT ·StoreRel(SB),NOSPLIT,$0-8
+	B	·Store(SB)
+
+TEXT ·StoreReluintptr(SB),NOSPLIT,$0-8
+	B	·Store(SB)
+
+TEXT ·Xaddint32(SB),NOSPLIT,$0-12
+	B	·Xadd(SB)
+
+TEXT ·Xaddint64(SB),NOSPLIT,$-4-20
+	B	·Xadd64(SB)
+
+TEXT ·Xadduintptr(SB),NOSPLIT,$0-12
+	B	·Xadd(SB)
+
+TEXT ·Xchgint32(SB),NOSPLIT,$0-12
+	B	·Xchg(SB)
+
+TEXT ·Xchgint64(SB),NOSPLIT,$-4-20
+	B	·Xchg64(SB)
+
+// 64-bit atomics
+// The native ARM implementations use LDREXD/STREXD, which are
+// available on ARMv6k or later. We use them only on ARMv7.
+// On older ARM, we use Go implementations which simulate 64-bit
+// atomics with locks.
+TEXT armCas64<>(SB),NOSPLIT,$0-21
+	// addr is already in R1
+	MOVW	old_lo+4(FP), R2
+	MOVW	old_hi+8(FP), R3
+	MOVW	new_lo+12(FP), R4
+	MOVW	new_hi+16(FP), R5
+cas64loop:
+	LDREXD	(R1), R6	// loads R6 and R7
+	CMP	R2, R6
+	BNE	cas64fail
+	CMP	R3, R7
+	BNE	cas64fail
+
+	DMB	MB_ISHST
+
+	STREXD	R4, (R1), R0	// stores R4 and R5
+	CMP	$0, R0
+	BNE	cas64loop
+	MOVW	$1, R0
+
+	DMB	MB_ISH
+
+	MOVBU	R0, swapped+20(FP)
+	RET
+cas64fail:
+	MOVW	$0, R0
+	MOVBU	R0, swapped+20(FP)
+	RET
+
+TEXT armXadd64<>(SB),NOSPLIT,$0-20
+	// addr is already in R1
+	MOVW	delta_lo+4(FP), R2
+	MOVW	delta_hi+8(FP), R3
+
+add64loop:
+	LDREXD	(R1), R4	// loads R4 and R5
+	ADD.S	R2, R4
+	ADC	R3, R5
+
+	DMB	MB_ISHST
+
+	STREXD	R4, (R1), R0	// stores R4 and R5
+	CMP	$0, R0
+	BNE	add64loop
+
+	DMB	MB_ISH
+
+	MOVW	R4, new_lo+12(FP)
+	MOVW	R5, new_hi+16(FP)
+	RET
+
+TEXT armXchg64<>(SB),NOSPLIT,$0-20
+	// addr is already in R1
+	MOVW	new_lo+4(FP), R2
+	MOVW	new_hi+8(FP), R3
+
+swap64loop:
+	LDREXD	(R1), R4	// loads R4 and R5
+
+	DMB	MB_ISHST
+
+	STREXD	R2, (R1), R0	// stores R2 and R3
+	CMP	$0, R0
+	BNE	swap64loop
+
+	DMB	MB_ISH
+
+	MOVW	R4, old_lo+12(FP)
+	MOVW	R5, old_hi+16(FP)
+	RET
+
+TEXT armLoad64<>(SB),NOSPLIT,$0-12
+	// addr is already in R1
+
+	LDREXD	(R1), R2	// loads R2 and R3
+	DMB	MB_ISH
+
+	MOVW	R2, val_lo+4(FP)
+	MOVW	R3, val_hi+8(FP)
+	RET
+
+TEXT armStore64<>(SB),NOSPLIT,$0-12
+	// addr is already in R1
+	MOVW	val_lo+4(FP), R2
+	MOVW	val_hi+8(FP), R3
+
+store64loop:
+	LDREXD	(R1), R4	// loads R4 and R5
+
+	DMB	MB_ISHST
+
+	STREXD	R2, (R1), R0	// stores R2 and R3
+	CMP	$0, R0
+	BNE	store64loop
+
+	DMB	MB_ISH
+	RET
+
+// The following functions all panic if their address argument isn't
+// 8-byte aligned. Since we're calling back into Go code to do this,
+// we have to cooperate with stack unwinding. In the normal case, the
+// functions tail-call into the appropriate implementation, which
+// means they must not open a frame. Hence, when they go down the
+// panic path, at that point they push the LR to create a real frame
+// (they don't need to pop it because panic won't return).
+
+TEXT ·Cas64(SB),NOSPLIT,$-4-21
+	NO_LOCAL_POINTERS
+	MOVW	addr+0(FP), R1
+	// make unaligned atomic access panic
+	AND.S	$7, R1, R2
+	BEQ 	3(PC)
+	MOVW.W	R14, -4(R13) // prepare a real frame
+	BL	·panicUnaligned(SB)
+
+	MOVB	runtime·goarm(SB), R11
+	CMP	$7, R11
+	BLT	2(PC)
+	JMP	armCas64<>(SB)
+	JMP	·goCas64(SB)
+
+TEXT ·Xadd64(SB),NOSPLIT,$-4-20
+	NO_LOCAL_POINTERS
+	MOVW	addr+0(FP), R1
+	// make unaligned atomic access panic
+	AND.S	$7, R1, R2
+	BEQ 	3(PC)
+	MOVW.W	R14, -4(R13) // prepare a real frame
+	BL	·panicUnaligned(SB)
+
+	MOVB	runtime·goarm(SB), R11
+	CMP	$7, R11
+	BLT	2(PC)
+	JMP	armXadd64<>(SB)
+	JMP	·goXadd64(SB)
+
+TEXT ·Xchg64(SB),NOSPLIT,$-4-20
+	NO_LOCAL_POINTERS
+	MOVW	addr+0(FP), R1
+	// make unaligned atomic access panic
+	AND.S	$7, R1, R2
+	BEQ 	3(PC)
+	MOVW.W	R14, -4(R13) // prepare a real frame
+	BL	·panicUnaligned(SB)
+
+	MOVB	runtime·goarm(SB), R11
+	CMP	$7, R11
+	BLT	2(PC)
+	JMP	armXchg64<>(SB)
+	JMP	·goXchg64(SB)
+
+TEXT ·Load64(SB),NOSPLIT,$-4-12
+	NO_LOCAL_POINTERS
+	MOVW	addr+0(FP), R1
+	// make unaligned atomic access panic
+	AND.S	$7, R1, R2
+	BEQ 	3(PC)
+	MOVW.W	R14, -4(R13) // prepare a real frame
+	BL	·panicUnaligned(SB)
+
+	MOVB	runtime·goarm(SB), R11
+	CMP	$7, R11
+	BLT	2(PC)
+	JMP	armLoad64<>(SB)
+	JMP	·goLoad64(SB)
+
+TEXT ·Store64(SB),NOSPLIT,$-4-12
+	NO_LOCAL_POINTERS
+	MOVW	addr+0(FP), R1
+	// make unaligned atomic access panic
+	AND.S	$7, R1, R2
+	BEQ 	3(PC)
+	MOVW.W	R14, -4(R13) // prepare a real frame
+	BL	·panicUnaligned(SB)
+
+	MOVB	runtime·goarm(SB), R11
+	CMP	$7, R11
+	BLT	2(PC)
+	JMP	armStore64<>(SB)
+	JMP	·goStore64(SB)
diff --git a/src/runtime/internal/atomic/atomic_arm64.go b/src/runtime/internal/atomic/atomic_arm64.go
index d49bee8..dbb1796 100644
--- a/src/runtime/internal/atomic/atomic_arm64.go
+++ b/src/runtime/internal/atomic/atomic_arm64.go
@@ -2,11 +2,19 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm64
 // +build arm64
 
 package atomic
 
-import "unsafe"
+import (
+	"internal/cpu"
+	"unsafe"
+)
+
+const (
+	offsetARM64HasATOMICS = unsafe.Offsetof(cpu.ARM64.HasATOMICS)
+)
 
 //go:noescape
 func Xadd(ptr *uint32, delta int32) uint32
diff --git a/src/runtime/internal/atomic/atomic_arm64.s b/src/runtime/internal/atomic/atomic_arm64.s
index 0cf3c40..5f77d92 100644
--- a/src/runtime/internal/atomic/atomic_arm64.s
+++ b/src/runtime/internal/atomic/atomic_arm64.s
@@ -2,116 +2,220 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include "go_asm.h"
 #include "textflag.h"
 
-// uint32 runtime∕internal∕atomic·Load(uint32 volatile* addr)
+TEXT ·Casint32(SB), NOSPLIT, $0-17
+	B	·Cas(SB)
+
+TEXT ·Casint64(SB), NOSPLIT, $0-25
+	B	·Cas64(SB)
+
+TEXT ·Casuintptr(SB), NOSPLIT, $0-25
+	B	·Cas64(SB)
+
+TEXT ·CasRel(SB), NOSPLIT, $0-17
+	B	·Cas(SB)
+
+TEXT ·Loadint32(SB), NOSPLIT, $0-12
+	B	·Load(SB)
+
+TEXT ·Loadint64(SB), NOSPLIT, $0-16
+	B	·Load64(SB)
+
+TEXT ·Loaduintptr(SB), NOSPLIT, $0-16
+	B	·Load64(SB)
+
+TEXT ·Loaduint(SB), NOSPLIT, $0-16
+	B	·Load64(SB)
+
+TEXT ·Storeint32(SB), NOSPLIT, $0-12
+	B	·Store(SB)
+
+TEXT ·Storeint64(SB), NOSPLIT, $0-16
+	B	·Store64(SB)
+
+TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
+	B	·Store64(SB)
+
+TEXT ·Xaddint32(SB), NOSPLIT, $0-20
+	B	·Xadd(SB)
+
+TEXT ·Xaddint64(SB), NOSPLIT, $0-24
+	B	·Xadd64(SB)
+
+TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
+	B	·Xadd64(SB)
+
+TEXT ·Casp1(SB), NOSPLIT, $0-25
+	B ·Cas64(SB)
+
+// uint32 ·Load(uint32 volatile* addr)
 TEXT ·Load(SB),NOSPLIT,$0-12
 	MOVD	ptr+0(FP), R0
 	LDARW	(R0), R0
 	MOVW	R0, ret+8(FP)
 	RET
 
-// uint8 runtime∕internal∕atomic·Load8(uint8 volatile* addr)
+// uint8 ·Load8(uint8 volatile* addr)
 TEXT ·Load8(SB),NOSPLIT,$0-9
 	MOVD	ptr+0(FP), R0
 	LDARB	(R0), R0
 	MOVB	R0, ret+8(FP)
 	RET
 
-// uint64 runtime∕internal∕atomic·Load64(uint64 volatile* addr)
+// uint64 ·Load64(uint64 volatile* addr)
 TEXT ·Load64(SB),NOSPLIT,$0-16
 	MOVD	ptr+0(FP), R0
 	LDAR	(R0), R0
 	MOVD	R0, ret+8(FP)
 	RET
 
-// void *runtime∕internal∕atomic·Loadp(void *volatile *addr)
+// void *·Loadp(void *volatile *addr)
 TEXT ·Loadp(SB),NOSPLIT,$0-16
 	MOVD	ptr+0(FP), R0
 	LDAR	(R0), R0
 	MOVD	R0, ret+8(FP)
 	RET
 
-// uint32 runtime∕internal∕atomic·LoadAcq(uint32 volatile* addr)
+// uint32 ·LoadAcq(uint32 volatile* addr)
 TEXT ·LoadAcq(SB),NOSPLIT,$0-12
 	B	·Load(SB)
 
-// uint64 runtime∕internal∕atomic·LoadAcquintptr(uint64 volatile* addr)
+// uint64 ·LoadAcquintptr(uint64 volatile* addr)
 TEXT ·LoadAcq64(SB),NOSPLIT,$0-16
 	B	·Load64(SB)
 
-// uintptr runtime∕internal∕atomic·LoadAcq64(uintptr volatile* addr)
+// uintptr ·LoadAcq64(uintptr volatile* addr)
 TEXT ·LoadAcquintptr(SB),NOSPLIT,$0-16
 	B	·Load64(SB)
 
-TEXT runtime∕internal∕atomic·StorepNoWB(SB), NOSPLIT, $0-16
-	B	runtime∕internal∕atomic·Store64(SB)
+TEXT ·StorepNoWB(SB), NOSPLIT, $0-16
+	B	·Store64(SB)
 
-TEXT runtime∕internal∕atomic·StoreRel(SB), NOSPLIT, $0-12
-	B	runtime∕internal∕atomic·Store(SB)
+TEXT ·StoreRel(SB), NOSPLIT, $0-12
+	B	·Store(SB)
 
-TEXT runtime∕internal∕atomic·StoreRel64(SB), NOSPLIT, $0-16
-	B	runtime∕internal∕atomic·Store64(SB)
+TEXT ·StoreRel64(SB), NOSPLIT, $0-16
+	B	·Store64(SB)
 
-TEXT runtime∕internal∕atomic·StoreReluintptr(SB), NOSPLIT, $0-16
-	B	runtime∕internal∕atomic·Store64(SB)
+TEXT ·StoreReluintptr(SB), NOSPLIT, $0-16
+	B	·Store64(SB)
 
-TEXT runtime∕internal∕atomic·Store(SB), NOSPLIT, $0-12
+TEXT ·Store(SB), NOSPLIT, $0-12
 	MOVD	ptr+0(FP), R0
 	MOVW	val+8(FP), R1
 	STLRW	R1, (R0)
 	RET
 
-TEXT runtime∕internal∕atomic·Store8(SB), NOSPLIT, $0-9
+TEXT ·Store8(SB), NOSPLIT, $0-9
 	MOVD	ptr+0(FP), R0
 	MOVB	val+8(FP), R1
 	STLRB	R1, (R0)
 	RET
 
-TEXT runtime∕internal∕atomic·Store64(SB), NOSPLIT, $0-16
+TEXT ·Store64(SB), NOSPLIT, $0-16
 	MOVD	ptr+0(FP), R0
 	MOVD	val+8(FP), R1
 	STLR	R1, (R0)
 	RET
 
-TEXT runtime∕internal∕atomic·Xchg(SB), NOSPLIT, $0-20
+// uint32 Xchg(ptr *uint32, new uint32)
+// Atomically:
+//	old := *ptr;
+//	*ptr = new;
+//	return old;
+TEXT ·Xchg(SB), NOSPLIT, $0-20
 	MOVD	ptr+0(FP), R0
 	MOVW	new+8(FP), R1
-again:
+	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+	CBZ 	R4, load_store_loop
+	SWPALW	R1, (R0), R2
+	MOVW	R2, ret+16(FP)
+	RET
+load_store_loop:
 	LDAXRW	(R0), R2
 	STLXRW	R1, (R0), R3
-	CBNZ	R3, again
+	CBNZ	R3, load_store_loop
 	MOVW	R2, ret+16(FP)
 	RET
 
-TEXT runtime∕internal∕atomic·Xchg64(SB), NOSPLIT, $0-24
+// uint64 Xchg64(ptr *uint64, new uint64)
+// Atomically:
+//	old := *ptr;
+//	*ptr = new;
+//	return old;
+TEXT ·Xchg64(SB), NOSPLIT, $0-24
 	MOVD	ptr+0(FP), R0
 	MOVD	new+8(FP), R1
-again:
+	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+	CBZ 	R4, load_store_loop
+	SWPALD	R1, (R0), R2
+	MOVD	R2, ret+16(FP)
+	RET
+load_store_loop:
 	LDAXR	(R0), R2
 	STLXR	R1, (R0), R3
-	CBNZ	R3, again
+	CBNZ	R3, load_store_loop
 	MOVD	R2, ret+16(FP)
 	RET
 
-// bool runtime∕internal∕atomic·Cas64(uint64 *ptr, uint64 old, uint64 new)
+// bool Cas(uint32 *ptr, uint32 old, uint32 new)
 // Atomically:
-//      if(*val == *old){
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else
+//		return 0;
+TEXT ·Cas(SB), NOSPLIT, $0-17
+	MOVD	ptr+0(FP), R0
+	MOVW	old+8(FP), R1
+	MOVW	new+12(FP), R2
+	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+	CBZ 	R4, load_store_loop
+	MOVD	R1, R3
+	CASALW	R3, (R0), R2
+	CMP 	R1, R3
+	CSET	EQ, R0
+	MOVB	R0, ret+16(FP)
+	RET
+load_store_loop:
+	LDAXRW	(R0), R3
+	CMPW	R1, R3
+	BNE	ok
+	STLXRW	R2, (R0), R3
+	CBNZ	R3, load_store_loop
+ok:
+	CSET	EQ, R0
+	MOVB	R0, ret+16(FP)
+	RET
+
+// bool ·Cas64(uint64 *ptr, uint64 old, uint64 new)
+// Atomically:
+//      if(*val == old){
 //              *val = new;
 //              return 1;
 //      } else {
 //              return 0;
 //      }
-TEXT runtime∕internal∕atomic·Cas64(SB), NOSPLIT, $0-25
+TEXT ·Cas64(SB), NOSPLIT, $0-25
 	MOVD	ptr+0(FP), R0
 	MOVD	old+8(FP), R1
 	MOVD	new+16(FP), R2
-again:
+	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+	CBZ 	R4, load_store_loop
+	MOVD	R1, R3
+	CASALD	R3, (R0), R2
+	CMP 	R1, R3
+	CSET	EQ, R0
+	MOVB	R0, ret+24(FP)
+	RET
+load_store_loop:
 	LDAXR	(R0), R3
 	CMP	R1, R3
 	BNE	ok
 	STLXR	R2, (R0), R3
-	CBNZ	R3, again
+	CBNZ	R3, load_store_loop
 ok:
 	CSET	EQ, R0
 	MOVB	R0, ret+24(FP)
@@ -121,65 +225,109 @@
 // Atomically:
 //      *val += delta;
 //      return *val;
-TEXT runtime∕internal∕atomic·Xadd(SB), NOSPLIT, $0-20
+TEXT ·Xadd(SB), NOSPLIT, $0-20
 	MOVD	ptr+0(FP), R0
 	MOVW	delta+8(FP), R1
-again:
+	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+	CBZ 	R4, load_store_loop
+	LDADDALW	R1, (R0), R2
+	ADD 	R1, R2
+	MOVW	R2, ret+16(FP)
+	RET
+load_store_loop:
 	LDAXRW	(R0), R2
 	ADDW	R2, R1, R2
 	STLXRW	R2, (R0), R3
-	CBNZ	R3, again
+	CBNZ	R3, load_store_loop
 	MOVW	R2, ret+16(FP)
 	RET
 
-TEXT runtime∕internal∕atomic·Xadd64(SB), NOSPLIT, $0-24
+// uint64 Xadd64(uint64 volatile *ptr, int64 delta)
+// Atomically:
+//      *val += delta;
+//      return *val;
+TEXT ·Xadd64(SB), NOSPLIT, $0-24
 	MOVD	ptr+0(FP), R0
 	MOVD	delta+8(FP), R1
-again:
+	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+	CBZ 	R4, load_store_loop
+	LDADDALD	R1, (R0), R2
+	ADD 	R1, R2
+	MOVD	R2, ret+16(FP)
+	RET
+load_store_loop:
 	LDAXR	(R0), R2
 	ADD	R2, R1, R2
 	STLXR	R2, (R0), R3
-	CBNZ	R3, again
+	CBNZ	R3, load_store_loop
 	MOVD	R2, ret+16(FP)
 	RET
 
-TEXT runtime∕internal∕atomic·Xchguintptr(SB), NOSPLIT, $0-24
-	B	runtime∕internal∕atomic·Xchg64(SB)
+TEXT ·Xchgint32(SB), NOSPLIT, $0-20
+	B	·Xchg(SB)
+
+TEXT ·Xchgint64(SB), NOSPLIT, $0-24
+	B	·Xchg64(SB)
+
+TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
+	B	·Xchg64(SB)
 
 TEXT ·And8(SB), NOSPLIT, $0-9
 	MOVD	ptr+0(FP), R0
 	MOVB	val+8(FP), R1
+	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+	CBZ 	R4, load_store_loop
+	MVN 	R1, R2
+	LDCLRALB	R2, (R0), R3
+	RET
+load_store_loop:
 	LDAXRB	(R0), R2
 	AND	R1, R2
 	STLXRB	R2, (R0), R3
-	CBNZ	R3, -3(PC)
+	CBNZ	R3, load_store_loop
 	RET
 
 TEXT ·Or8(SB), NOSPLIT, $0-9
 	MOVD	ptr+0(FP), R0
 	MOVB	val+8(FP), R1
+	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+	CBZ 	R4, load_store_loop
+	LDORALB	R1, (R0), R2
+	RET
+load_store_loop:
 	LDAXRB	(R0), R2
 	ORR	R1, R2
 	STLXRB	R2, (R0), R3
-	CBNZ	R3, -3(PC)
+	CBNZ	R3, load_store_loop
 	RET
 
 // func And(addr *uint32, v uint32)
 TEXT ·And(SB), NOSPLIT, $0-12
 	MOVD	ptr+0(FP), R0
 	MOVW	val+8(FP), R1
+	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+	CBZ 	R4, load_store_loop
+	MVN 	R1, R2
+	LDCLRALW	R2, (R0), R3
+	RET
+load_store_loop:
 	LDAXRW	(R0), R2
 	AND	R1, R2
 	STLXRW	R2, (R0), R3
-	CBNZ	R3, -3(PC)
+	CBNZ	R3, load_store_loop
 	RET
 
 // func Or(addr *uint32, v uint32)
 TEXT ·Or(SB), NOSPLIT, $0-12
 	MOVD	ptr+0(FP), R0
 	MOVW	val+8(FP), R1
+	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+	CBZ 	R4, load_store_loop
+	LDORALW	R1, (R0), R2
+	RET
+load_store_loop:
 	LDAXRW	(R0), R2
 	ORR	R1, R2
 	STLXRW	R2, (R0), R3
-	CBNZ	R3, -3(PC)
+	CBNZ	R3, load_store_loop
 	RET
diff --git a/src/runtime/internal/atomic/atomic_mips64x.go b/src/runtime/internal/atomic/atomic_mips64x.go
index b0109d7..5b407eb 100644
--- a/src/runtime/internal/atomic/atomic_mips64x.go
+++ b/src/runtime/internal/atomic/atomic_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 package atomic
diff --git a/src/runtime/internal/atomic/atomic_mips64x.s b/src/runtime/internal/atomic/atomic_mips64x.s
index 125c0c2..fedfc4a 100644
--- a/src/runtime/internal/atomic/atomic_mips64x.s
+++ b/src/runtime/internal/atomic/atomic_mips64x.s
@@ -2,13 +2,316 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "textflag.h"
 
 #define SYNC	WORD $0xf
 
-// uint32 runtime∕internal∕atomic·Load(uint32 volatile* ptr)
+// bool cas(uint32 *ptr, uint32 old, uint32 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else
+//		return 0;
+TEXT ·Cas(SB), NOSPLIT, $0-17
+	MOVV	ptr+0(FP), R1
+	MOVW	old+8(FP), R2
+	MOVW	new+12(FP), R5
+	SYNC
+cas_again:
+	MOVV	R5, R3
+	LL	(R1), R4
+	BNE	R2, R4, cas_fail
+	SC	R3, (R1)
+	BEQ	R3, cas_again
+	MOVV	$1, R1
+	MOVB	R1, ret+16(FP)
+	SYNC
+	RET
+cas_fail:
+	MOVV	$0, R1
+	JMP	-4(PC)
+
+// bool	cas64(uint64 *ptr, uint64 old, uint64 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else {
+//		return 0;
+//	}
+TEXT ·Cas64(SB), NOSPLIT, $0-25
+	MOVV	ptr+0(FP), R1
+	MOVV	old+8(FP), R2
+	MOVV	new+16(FP), R5
+	SYNC
+cas64_again:
+	MOVV	R5, R3
+	LLV	(R1), R4
+	BNE	R2, R4, cas64_fail
+	SCV	R3, (R1)
+	BEQ	R3, cas64_again
+	MOVV	$1, R1
+	MOVB	R1, ret+24(FP)
+	SYNC
+	RET
+cas64_fail:
+	MOVV	$0, R1
+	JMP	-4(PC)
+
+TEXT ·Casint32(SB), NOSPLIT, $0-17
+	JMP	·Cas(SB)
+
+TEXT ·Casint64(SB), NOSPLIT, $0-25
+	JMP	·Cas64(SB)
+
+TEXT ·Casuintptr(SB), NOSPLIT, $0-25
+	JMP	·Cas64(SB)
+
+TEXT ·CasRel(SB), NOSPLIT, $0-17
+	JMP	·Cas(SB)
+
+TEXT ·Loaduintptr(SB),  NOSPLIT|NOFRAME, $0-16
+	JMP	·Load64(SB)
+
+TEXT ·Loaduint(SB), NOSPLIT|NOFRAME, $0-16
+	JMP	·Load64(SB)
+
+TEXT ·Storeint32(SB), NOSPLIT, $0-12
+	JMP	·Store(SB)
+
+TEXT ·Storeint64(SB), NOSPLIT, $0-16
+	JMP	·Store64(SB)
+
+TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
+	JMP	·Store64(SB)
+
+TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
+	JMP	·Xadd64(SB)
+
+TEXT ·Loadint32(SB), NOSPLIT, $0-12
+	JMP	·Load(SB)
+
+TEXT ·Loadint64(SB), NOSPLIT, $0-16
+	JMP	·Load64(SB)
+
+TEXT ·Xaddint32(SB), NOSPLIT, $0-20
+	JMP	·Xadd(SB)
+
+TEXT ·Xaddint64(SB), NOSPLIT, $0-24
+	JMP	·Xadd64(SB)
+
+// bool casp(void **val, void *old, void *new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else
+//		return 0;
+TEXT ·Casp1(SB), NOSPLIT, $0-25
+	JMP ·Cas64(SB)
+
+// uint32 xadd(uint32 volatile *ptr, int32 delta)
+// Atomically:
+//	*val += delta;
+//	return *val;
+TEXT ·Xadd(SB), NOSPLIT, $0-20
+	MOVV	ptr+0(FP), R2
+	MOVW	delta+8(FP), R3
+	SYNC
+	LL	(R2), R1
+	ADDU	R1, R3, R4
+	MOVV	R4, R1
+	SC	R4, (R2)
+	BEQ	R4, -4(PC)
+	MOVW	R1, ret+16(FP)
+	SYNC
+	RET
+
+// uint64 Xadd64(uint64 volatile *ptr, int64 delta)
+// Atomically:
+//	*val += delta;
+//	return *val;
+TEXT ·Xadd64(SB), NOSPLIT, $0-24
+	MOVV	ptr+0(FP), R2
+	MOVV	delta+8(FP), R3
+	SYNC
+	LLV	(R2), R1
+	ADDVU	R1, R3, R4
+	MOVV	R4, R1
+	SCV	R4, (R2)
+	BEQ	R4, -4(PC)
+	MOVV	R1, ret+16(FP)
+	SYNC
+	RET
+
+// uint32 Xchg(ptr *uint32, new uint32)
+// Atomically:
+//	old := *ptr;
+//	*ptr = new;
+//	return old;
+TEXT ·Xchg(SB), NOSPLIT, $0-20
+	MOVV	ptr+0(FP), R2
+	MOVW	new+8(FP), R5
+
+	SYNC
+	MOVV	R5, R3
+	LL	(R2), R1
+	SC	R3, (R2)
+	BEQ	R3, -3(PC)
+	MOVW	R1, ret+16(FP)
+	SYNC
+	RET
+
+// uint64 Xchg64(ptr *uint64, new uint64)
+// Atomically:
+//	old := *ptr;
+//	*ptr = new;
+//	return old;
+TEXT ·Xchg64(SB), NOSPLIT, $0-24
+	MOVV	ptr+0(FP), R2
+	MOVV	new+8(FP), R5
+
+	SYNC
+	MOVV	R5, R3
+	LLV	(R2), R1
+	SCV	R3, (R2)
+	BEQ	R3, -3(PC)
+	MOVV	R1, ret+16(FP)
+	SYNC
+	RET
+
+TEXT ·Xchgint32(SB), NOSPLIT, $0-20
+	JMP	·Xchg(SB)
+
+TEXT ·Xchgint64(SB), NOSPLIT, $0-24
+	JMP	·Xchg64(SB)
+
+TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
+	JMP	·Xchg64(SB)
+
+TEXT ·StorepNoWB(SB), NOSPLIT, $0-16
+	JMP	·Store64(SB)
+
+TEXT ·StoreRel(SB), NOSPLIT, $0-12
+	JMP	·Store(SB)
+
+TEXT ·StoreRel64(SB), NOSPLIT, $0-16
+	JMP	·Store64(SB)
+
+TEXT ·StoreReluintptr(SB), NOSPLIT, $0-16
+	JMP	·Store64(SB)
+
+TEXT ·Store(SB), NOSPLIT, $0-12
+	MOVV	ptr+0(FP), R1
+	MOVW	val+8(FP), R2
+	SYNC
+	MOVW	R2, 0(R1)
+	SYNC
+	RET
+
+TEXT ·Store8(SB), NOSPLIT, $0-9
+	MOVV	ptr+0(FP), R1
+	MOVB	val+8(FP), R2
+	SYNC
+	MOVB	R2, 0(R1)
+	SYNC
+	RET
+
+TEXT ·Store64(SB), NOSPLIT, $0-16
+	MOVV	ptr+0(FP), R1
+	MOVV	val+8(FP), R2
+	SYNC
+	MOVV	R2, 0(R1)
+	SYNC
+	RET
+
+// void	Or8(byte volatile*, byte);
+TEXT ·Or8(SB), NOSPLIT, $0-9
+	MOVV	ptr+0(FP), R1
+	MOVBU	val+8(FP), R2
+	// Align ptr down to 4 bytes so we can use 32-bit load/store.
+	MOVV	$~3, R3
+	AND	R1, R3
+	// Compute val shift.
+#ifdef GOARCH_mips64
+	// Big endian.  ptr = ptr ^ 3
+	XOR	$3, R1
+#endif
+	// R4 = ((ptr & 3) * 8)
+	AND	$3, R1, R4
+	SLLV	$3, R4
+	// Shift val for aligned ptr. R2 = val << R4
+	SLLV	R4, R2
+
+	SYNC
+	LL	(R3), R4
+	OR	R2, R4
+	SC	R4, (R3)
+	BEQ	R4, -4(PC)
+	SYNC
+	RET
+
+// void	And8(byte volatile*, byte);
+TEXT ·And8(SB), NOSPLIT, $0-9
+	MOVV	ptr+0(FP), R1
+	MOVBU	val+8(FP), R2
+	// Align ptr down to 4 bytes so we can use 32-bit load/store.
+	MOVV	$~3, R3
+	AND	R1, R3
+	// Compute val shift.
+#ifdef GOARCH_mips64
+	// Big endian.  ptr = ptr ^ 3
+	XOR	$3, R1
+#endif
+	// R4 = ((ptr & 3) * 8)
+	AND	$3, R1, R4
+	SLLV	$3, R4
+	// Shift val for aligned ptr. R2 = val << R4 | ^(0xFF << R4)
+	MOVV	$0xFF, R5
+	SLLV	R4, R2
+	SLLV	R4, R5
+	NOR	R0, R5
+	OR	R5, R2
+
+	SYNC
+	LL	(R3), R4
+	AND	R2, R4
+	SC	R4, (R3)
+	BEQ	R4, -4(PC)
+	SYNC
+	RET
+
+// func Or(addr *uint32, v uint32)
+TEXT ·Or(SB), NOSPLIT, $0-12
+	MOVV	ptr+0(FP), R1
+	MOVW	val+8(FP), R2
+
+	SYNC
+	LL	(R1), R3
+	OR	R2, R3
+	SC	R3, (R1)
+	BEQ	R3, -4(PC)
+	SYNC
+	RET
+
+// func And(addr *uint32, v uint32)
+TEXT ·And(SB), NOSPLIT, $0-12
+	MOVV	ptr+0(FP), R1
+	MOVW	val+8(FP), R2
+
+	SYNC
+	LL	(R1), R3
+	AND	R2, R3
+	SC	R3, (R1)
+	BEQ	R3, -4(PC)
+	SYNC
+	RET
+
+// uint32 ·Load(uint32 volatile* ptr)
 TEXT ·Load(SB),NOSPLIT|NOFRAME,$0-12
 	MOVV	ptr+0(FP), R1
 	SYNC
@@ -17,7 +320,7 @@
 	MOVW	R1, ret+8(FP)
 	RET
 
-// uint8 runtime∕internal∕atomic·Load8(uint8 volatile* ptr)
+// uint8 ·Load8(uint8 volatile* ptr)
 TEXT ·Load8(SB),NOSPLIT|NOFRAME,$0-9
 	MOVV	ptr+0(FP), R1
 	SYNC
@@ -26,7 +329,7 @@
 	MOVB	R1, ret+8(FP)
 	RET
 
-// uint64 runtime∕internal∕atomic·Load64(uint64 volatile* ptr)
+// uint64 ·Load64(uint64 volatile* ptr)
 TEXT ·Load64(SB),NOSPLIT|NOFRAME,$0-16
 	MOVV	ptr+0(FP), R1
 	SYNC
@@ -35,7 +338,7 @@
 	MOVV	R1, ret+8(FP)
 	RET
 
-// void *runtime∕internal∕atomic·Loadp(void *volatile *ptr)
+// void *·Loadp(void *volatile *ptr)
 TEXT ·Loadp(SB),NOSPLIT|NOFRAME,$0-16
 	MOVV	ptr+0(FP), R1
 	SYNC
@@ -44,14 +347,14 @@
 	MOVV	R1, ret+8(FP)
 	RET
 
-// uint32 runtime∕internal∕atomic·LoadAcq(uint32 volatile* ptr)
+// uint32 ·LoadAcq(uint32 volatile* ptr)
 TEXT ·LoadAcq(SB),NOSPLIT|NOFRAME,$0-12
 	JMP	atomic·Load(SB)
 
-// uint64 runtime∕internal∕atomic·LoadAcq64(uint64 volatile* ptr)
+// uint64 ·LoadAcq64(uint64 volatile* ptr)
 TEXT ·LoadAcq64(SB),NOSPLIT|NOFRAME,$0-16
 	JMP	atomic·Load64(SB)
 
-// uintptr runtime∕internal∕atomic·LoadAcquintptr(uintptr volatile* ptr)
+// uintptr ·LoadAcquintptr(uintptr volatile* ptr)
 TEXT ·LoadAcquintptr(SB),NOSPLIT|NOFRAME,$0-16
 	JMP	atomic·Load64(SB)
diff --git a/src/runtime/internal/atomic/atomic_mipsx.go b/src/runtime/internal/atomic/atomic_mipsx.go
index 1336b50..80cd65b 100644
--- a/src/runtime/internal/atomic/atomic_mipsx.go
+++ b/src/runtime/internal/atomic/atomic_mipsx.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 // Export some functions via linkname to assembly in sync/atomic.
diff --git a/src/runtime/internal/atomic/atomic_mipsx.s b/src/runtime/internal/atomic/atomic_mipsx.s
index aeebc8f..c0835d6 100644
--- a/src/runtime/internal/atomic/atomic_mipsx.s
+++ b/src/runtime/internal/atomic/atomic_mipsx.s
@@ -2,10 +2,244 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "textflag.h"
 
+// bool Cas(int32 *val, int32 old, int32 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else
+//		return 0;
+TEXT ·Cas(SB),NOSPLIT,$0-13
+	MOVW	ptr+0(FP), R1
+	MOVW	old+4(FP), R2
+	MOVW	new+8(FP), R5
+	SYNC
+try_cas:
+	MOVW	R5, R3
+	LL	(R1), R4	// R4 = *R1
+	BNE	R2, R4, cas_fail
+	SC	R3, (R1)	// *R1 = R3
+	BEQ	R3, try_cas
+	SYNC
+	MOVB	R3, ret+12(FP)
+	RET
+cas_fail:
+	MOVB	R0, ret+12(FP)
+	RET
+
+TEXT ·Store(SB),NOSPLIT,$0-8
+	MOVW	ptr+0(FP), R1
+	MOVW	val+4(FP), R2
+	SYNC
+	MOVW	R2, 0(R1)
+	SYNC
+	RET
+
+TEXT ·Store8(SB),NOSPLIT,$0-5
+	MOVW	ptr+0(FP), R1
+	MOVB	val+4(FP), R2
+	SYNC
+	MOVB	R2, 0(R1)
+	SYNC
+	RET
+
+TEXT ·Load(SB),NOSPLIT,$0-8
+	MOVW	ptr+0(FP), R1
+	SYNC
+	MOVW	0(R1), R1
+	SYNC
+	MOVW	R1, ret+4(FP)
+	RET
+
+TEXT ·Load8(SB),NOSPLIT,$0-5
+	MOVW	ptr+0(FP), R1
+	SYNC
+	MOVB	0(R1), R1
+	SYNC
+	MOVB	R1, ret+4(FP)
+	RET
+
+// uint32 Xadd(uint32 volatile *val, int32 delta)
+// Atomically:
+//	*val += delta;
+//	return *val;
+TEXT ·Xadd(SB),NOSPLIT,$0-12
+	MOVW	ptr+0(FP), R2
+	MOVW	delta+4(FP), R3
+	SYNC
+try_xadd:
+	LL	(R2), R1	// R1 = *R2
+	ADDU	R1, R3, R4
+	MOVW	R4, R1
+	SC	R4, (R2)	// *R2 = R4
+	BEQ	R4, try_xadd
+	SYNC
+	MOVW	R1, ret+8(FP)
+	RET
+
+// uint32 Xchg(ptr *uint32, new uint32)
+// Atomically:
+//	old := *ptr;
+//	*ptr = new;
+//	return old;
+TEXT ·Xchg(SB),NOSPLIT,$0-12
+	MOVW	ptr+0(FP), R2
+	MOVW	new+4(FP), R5
+	SYNC
+try_xchg:
+	MOVW	R5, R3
+	LL	(R2), R1	// R1 = *R2
+	SC	R3, (R2)	// *R2 = R3
+	BEQ	R3, try_xchg
+	SYNC
+	MOVW	R1, ret+8(FP)
+	RET
+
+TEXT ·Casint32(SB),NOSPLIT,$0-13
+	JMP	·Cas(SB)
+
+TEXT ·Casint64(SB),NOSPLIT,$0-21
+	JMP	·Cas64(SB)
+
+TEXT ·Casuintptr(SB),NOSPLIT,$0-13
+	JMP	·Cas(SB)
+
+TEXT ·CasRel(SB),NOSPLIT,$0-13
+	JMP	·Cas(SB)
+
+TEXT ·Loaduintptr(SB),NOSPLIT,$0-8
+	JMP	·Load(SB)
+
+TEXT ·Loaduint(SB),NOSPLIT,$0-8
+	JMP	·Load(SB)
+
+TEXT ·Loadp(SB),NOSPLIT,$-0-8
+	JMP	·Load(SB)
+
+TEXT ·Storeint32(SB),NOSPLIT,$0-8
+	JMP	·Store(SB)
+
+TEXT ·Storeint64(SB),NOSPLIT,$0-12
+	JMP	·Store64(SB)
+
+TEXT ·Storeuintptr(SB),NOSPLIT,$0-8
+	JMP	·Store(SB)
+
+TEXT ·Xadduintptr(SB),NOSPLIT,$0-12
+	JMP	·Xadd(SB)
+
+TEXT ·Loadint32(SB),NOSPLIT,$0-8
+	JMP	·Load(SB)
+
+TEXT ·Loadint64(SB),NOSPLIT,$0-12
+	JMP	·Load64(SB)
+
+TEXT ·Xaddint32(SB),NOSPLIT,$0-12
+	JMP	·Xadd(SB)
+
+TEXT ·Xaddint64(SB),NOSPLIT,$0-20
+	JMP	·Xadd64(SB)
+
+TEXT ·Casp1(SB),NOSPLIT,$0-13
+	JMP	·Cas(SB)
+
+TEXT ·Xchgint32(SB),NOSPLIT,$0-12
+	JMP	·Xchg(SB)
+
+TEXT ·Xchgint64(SB),NOSPLIT,$0-20
+	JMP	·Xchg64(SB)
+
+TEXT ·Xchguintptr(SB),NOSPLIT,$0-12
+	JMP	·Xchg(SB)
+
+TEXT ·StorepNoWB(SB),NOSPLIT,$0-8
+	JMP	·Store(SB)
+
+TEXT ·StoreRel(SB),NOSPLIT,$0-8
+	JMP	·Store(SB)
+
+TEXT ·StoreReluintptr(SB),NOSPLIT,$0-8
+	JMP	·Store(SB)
+
+// void	Or8(byte volatile*, byte);
+TEXT ·Or8(SB),NOSPLIT,$0-5
+	MOVW	ptr+0(FP), R1
+	MOVBU	val+4(FP), R2
+	MOVW	$~3, R3	// Align ptr down to 4 bytes so we can use 32-bit load/store.
+	AND	R1, R3
+#ifdef GOARCH_mips
+	// Big endian.  ptr = ptr ^ 3
+	XOR	$3, R1
+#endif
+	AND	$3, R1, R4	// R4 = ((ptr & 3) * 8)
+	SLL	$3, R4
+	SLL	R4, R2, R2	// Shift val for aligned ptr. R2 = val << R4
+	SYNC
+try_or8:
+	LL	(R3), R4	// R4 = *R3
+	OR	R2, R4
+	SC	R4, (R3)	// *R3 = R4
+	BEQ	R4, try_or8
+	SYNC
+	RET
+
+// void	And8(byte volatile*, byte);
+TEXT ·And8(SB),NOSPLIT,$0-5
+	MOVW	ptr+0(FP), R1
+	MOVBU	val+4(FP), R2
+	MOVW	$~3, R3
+	AND	R1, R3
+#ifdef GOARCH_mips
+	// Big endian.  ptr = ptr ^ 3
+	XOR	$3, R1
+#endif
+	AND	$3, R1, R4	// R4 = ((ptr & 3) * 8)
+	SLL	$3, R4
+	MOVW	$0xFF, R5
+	SLL	R4, R2
+	SLL	R4, R5
+	NOR	R0, R5
+	OR	R5, R2	// Shift val for aligned ptr. R2 = val << R4 | ^(0xFF << R4)
+	SYNC
+try_and8:
+	LL	(R3), R4	// R4 = *R3
+	AND	R2, R4
+	SC	R4, (R3)	// *R3 = R4
+	BEQ	R4, try_and8
+	SYNC
+	RET
+
+// func Or(addr *uint32, v uint32)
+TEXT ·Or(SB), NOSPLIT, $0-8
+	MOVW	ptr+0(FP), R1
+	MOVW	val+4(FP), R2
+
+	SYNC
+	LL	(R1), R3
+	OR	R2, R3
+	SC	R3, (R1)
+	BEQ	R3, -4(PC)
+	SYNC
+	RET
+
+// func And(addr *uint32, v uint32)
+TEXT ·And(SB), NOSPLIT, $0-8
+	MOVW	ptr+0(FP), R1
+	MOVW	val+4(FP), R2
+
+	SYNC
+	LL	(R1), R3
+	AND	R2, R3
+	SC	R3, (R1)
+	BEQ	R3, -4(PC)
+	SYNC
+	RET
+
 TEXT ·spinLock(SB),NOSPLIT,$0-4
 	MOVW	state+0(FP), R1
 	MOVW	$1, R2
diff --git a/src/runtime/internal/atomic/atomic_ppc64x.go b/src/runtime/internal/atomic/atomic_ppc64x.go
index e4b109f..98101e3 100644
--- a/src/runtime/internal/atomic/atomic_ppc64x.go
+++ b/src/runtime/internal/atomic/atomic_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 package atomic
diff --git a/src/runtime/internal/atomic/atomic_ppc64x.s b/src/runtime/internal/atomic/atomic_ppc64x.s
index b79cdbc..226b3b6 100644
--- a/src/runtime/internal/atomic/atomic_ppc64x.s
+++ b/src/runtime/internal/atomic/atomic_ppc64x.s
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "textflag.h"
 
-
 // For more details about how various memory models are
 // enforced on POWER, the following paper provides more
 // details about how they enforce C/C++ like models. This
@@ -15,7 +15,7 @@
 //
 // http://www.rdrop.com/users/paulmck/scalability/paper/N2745r.2011.03.04a.html
 
-// uint32 runtime∕internal∕atomic·Load(uint32 volatile* ptr)
+// uint32 ·Load(uint32 volatile* ptr)
 TEXT ·Load(SB),NOSPLIT|NOFRAME,$-8-12
 	MOVD	ptr+0(FP), R3
 	SYNC
@@ -26,7 +26,7 @@
 	MOVW	R3, ret+8(FP)
 	RET
 
-// uint8 runtime∕internal∕atomic·Load8(uint8 volatile* ptr)
+// uint8 ·Load8(uint8 volatile* ptr)
 TEXT ·Load8(SB),NOSPLIT|NOFRAME,$-8-9
 	MOVD	ptr+0(FP), R3
 	SYNC
@@ -37,7 +37,7 @@
 	MOVB	R3, ret+8(FP)
 	RET
 
-// uint64 runtime∕internal∕atomic·Load64(uint64 volatile* ptr)
+// uint64 ·Load64(uint64 volatile* ptr)
 TEXT ·Load64(SB),NOSPLIT|NOFRAME,$-8-16
 	MOVD	ptr+0(FP), R3
 	SYNC
@@ -48,7 +48,7 @@
 	MOVD	R3, ret+8(FP)
 	RET
 
-// void *runtime∕internal∕atomic·Loadp(void *volatile *ptr)
+// void *·Loadp(void *volatile *ptr)
 TEXT ·Loadp(SB),NOSPLIT|NOFRAME,$-8-16
 	MOVD	ptr+0(FP), R3
 	SYNC
@@ -59,7 +59,7 @@
 	MOVD	R3, ret+8(FP)
 	RET
 
-// uint32 runtime∕internal∕atomic·LoadAcq(uint32 volatile* ptr)
+// uint32 ·LoadAcq(uint32 volatile* ptr)
 TEXT ·LoadAcq(SB),NOSPLIT|NOFRAME,$-8-12
 	MOVD   ptr+0(FP), R3
 	MOVWZ  0(R3), R3
@@ -69,7 +69,7 @@
 	MOVW   R3, ret+8(FP)
 	RET
 
-// uint64 runtime∕internal∕atomic·LoadAcq64(uint64 volatile* ptr)
+// uint64 ·LoadAcq64(uint64 volatile* ptr)
 TEXT ·LoadAcq64(SB),NOSPLIT|NOFRAME,$-8-16
 	MOVD   ptr+0(FP), R3
 	MOVD   0(R3), R3
@@ -78,3 +78,286 @@
 	ISYNC
 	MOVD   R3, ret+8(FP)
 	RET
+
+// bool cas(uint32 *ptr, uint32 old, uint32 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else
+//		return 0;
+TEXT ·Cas(SB), NOSPLIT, $0-17
+	MOVD	ptr+0(FP), R3
+	MOVWZ	old+8(FP), R4
+	MOVWZ	new+12(FP), R5
+	LWSYNC
+cas_again:
+	LWAR	(R3), R6
+	CMPW	R6, R4
+	BNE	cas_fail
+	STWCCC	R5, (R3)
+	BNE	cas_again
+	MOVD	$1, R3
+	LWSYNC
+	MOVB	R3, ret+16(FP)
+	RET
+cas_fail:
+	MOVB	R0, ret+16(FP)
+	RET
+
+// bool	·Cas64(uint64 *ptr, uint64 old, uint64 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else {
+//		return 0;
+//	}
+TEXT ·Cas64(SB), NOSPLIT, $0-25
+	MOVD	ptr+0(FP), R3
+	MOVD	old+8(FP), R4
+	MOVD	new+16(FP), R5
+	LWSYNC
+cas64_again:
+	LDAR	(R3), R6
+	CMP	R6, R4
+	BNE	cas64_fail
+	STDCCC	R5, (R3)
+	BNE	cas64_again
+	MOVD	$1, R3
+	LWSYNC
+	MOVB	R3, ret+24(FP)
+	RET
+cas64_fail:
+	MOVB	R0, ret+24(FP)
+	RET
+
+TEXT ·CasRel(SB), NOSPLIT, $0-17
+	MOVD    ptr+0(FP), R3
+	MOVWZ   old+8(FP), R4
+	MOVWZ   new+12(FP), R5
+	LWSYNC
+cas_again:
+	LWAR    (R3), $0, R6        // 0 = Mutex release hint
+	CMPW    R6, R4
+	BNE     cas_fail
+	STWCCC  R5, (R3)
+	BNE     cas_again
+	MOVD    $1, R3
+	MOVB    R3, ret+16(FP)
+	RET
+cas_fail:
+	MOVB    R0, ret+16(FP)
+	RET
+
+TEXT ·Casint32(SB), NOSPLIT, $0-17
+	BR	·Cas(SB)
+
+TEXT ·Casint64(SB), NOSPLIT, $0-25
+	BR	·Cas64(SB)
+
+TEXT ·Casuintptr(SB), NOSPLIT, $0-25
+	BR	·Cas64(SB)
+
+TEXT ·Loaduintptr(SB),  NOSPLIT|NOFRAME, $0-16
+	BR	·Load64(SB)
+
+TEXT ·LoadAcquintptr(SB),  NOSPLIT|NOFRAME, $0-16
+	BR	·LoadAcq64(SB)
+
+TEXT ·Loaduint(SB), NOSPLIT|NOFRAME, $0-16
+	BR	·Load64(SB)
+
+TEXT ·Storeint32(SB), NOSPLIT, $0-12
+	BR	·Store(SB)
+
+TEXT ·Storeint64(SB), NOSPLIT, $0-16
+	BR	·Store64(SB)
+
+TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
+	BR	·Store64(SB)
+
+TEXT ·StoreReluintptr(SB), NOSPLIT, $0-16
+	BR	·StoreRel64(SB)
+
+TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
+	BR	·Xadd64(SB)
+
+TEXT ·Loadint32(SB), NOSPLIT, $0-12
+	BR	·Load(SB)
+
+TEXT ·Loadint64(SB), NOSPLIT, $0-16
+	BR	·Load64(SB)
+
+TEXT ·Xaddint32(SB), NOSPLIT, $0-20
+	BR	·Xadd(SB)
+
+TEXT ·Xaddint64(SB), NOSPLIT, $0-24
+	BR	·Xadd64(SB)
+
+// bool casp(void **val, void *old, void *new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else
+//		return 0;
+TEXT ·Casp1(SB), NOSPLIT, $0-25
+	BR ·Cas64(SB)
+
+// uint32 xadd(uint32 volatile *ptr, int32 delta)
+// Atomically:
+//	*val += delta;
+//	return *val;
+TEXT ·Xadd(SB), NOSPLIT, $0-20
+	MOVD	ptr+0(FP), R4
+	MOVW	delta+8(FP), R5
+	LWSYNC
+	LWAR	(R4), R3
+	ADD	R5, R3
+	STWCCC	R3, (R4)
+	BNE	-3(PC)
+	MOVW	R3, ret+16(FP)
+	RET
+
+// uint64 Xadd64(uint64 volatile *val, int64 delta)
+// Atomically:
+//	*val += delta;
+//	return *val;
+TEXT ·Xadd64(SB), NOSPLIT, $0-24
+	MOVD	ptr+0(FP), R4
+	MOVD	delta+8(FP), R5
+	LWSYNC
+	LDAR	(R4), R3
+	ADD	R5, R3
+	STDCCC	R3, (R4)
+	BNE	-3(PC)
+	MOVD	R3, ret+16(FP)
+	RET
+
+// uint32 Xchg(ptr *uint32, new uint32)
+// Atomically:
+//	old := *ptr;
+//	*ptr = new;
+//	return old;
+TEXT ·Xchg(SB), NOSPLIT, $0-20
+	MOVD	ptr+0(FP), R4
+	MOVW	new+8(FP), R5
+	LWSYNC
+	LWAR	(R4), R3
+	STWCCC	R5, (R4)
+	BNE	-2(PC)
+	ISYNC
+	MOVW	R3, ret+16(FP)
+	RET
+
+// uint64 Xchg64(ptr *uint64, new uint64)
+// Atomically:
+//	old := *ptr;
+//	*ptr = new;
+//	return old;
+TEXT ·Xchg64(SB), NOSPLIT, $0-24
+	MOVD	ptr+0(FP), R4
+	MOVD	new+8(FP), R5
+	LWSYNC
+	LDAR	(R4), R3
+	STDCCC	R5, (R4)
+	BNE	-2(PC)
+	ISYNC
+	MOVD	R3, ret+16(FP)
+	RET
+
+TEXT ·Xchgint32(SB), NOSPLIT, $0-20
+	BR	·Xchg(SB)
+
+TEXT ·Xchgint64(SB), NOSPLIT, $0-24
+	BR	·Xchg64(SB)
+
+TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
+	BR	·Xchg64(SB)
+
+TEXT ·StorepNoWB(SB), NOSPLIT, $0-16
+	BR	·Store64(SB)
+
+TEXT ·Store(SB), NOSPLIT, $0-12
+	MOVD	ptr+0(FP), R3
+	MOVW	val+8(FP), R4
+	SYNC
+	MOVW	R4, 0(R3)
+	RET
+
+TEXT ·Store8(SB), NOSPLIT, $0-9
+	MOVD	ptr+0(FP), R3
+	MOVB	val+8(FP), R4
+	SYNC
+	MOVB	R4, 0(R3)
+	RET
+
+TEXT ·Store64(SB), NOSPLIT, $0-16
+	MOVD	ptr+0(FP), R3
+	MOVD	val+8(FP), R4
+	SYNC
+	MOVD	R4, 0(R3)
+	RET
+
+TEXT ·StoreRel(SB), NOSPLIT, $0-12
+	MOVD	ptr+0(FP), R3
+	MOVW	val+8(FP), R4
+	LWSYNC
+	MOVW	R4, 0(R3)
+	RET
+
+TEXT ·StoreRel64(SB), NOSPLIT, $0-16
+	MOVD	ptr+0(FP), R3
+	MOVD	val+8(FP), R4
+	LWSYNC
+	MOVD	R4, 0(R3)
+	RET
+
+// void ·Or8(byte volatile*, byte);
+TEXT ·Or8(SB), NOSPLIT, $0-9
+	MOVD	ptr+0(FP), R3
+	MOVBZ	val+8(FP), R4
+	LWSYNC
+again:
+	LBAR	(R3), R6
+	OR	R4, R6
+	STBCCC	R6, (R3)
+	BNE	again
+	RET
+
+// void ·And8(byte volatile*, byte);
+TEXT ·And8(SB), NOSPLIT, $0-9
+	MOVD	ptr+0(FP), R3
+	MOVBZ	val+8(FP), R4
+	LWSYNC
+again:
+	LBAR	(R3), R6
+	AND	R4, R6
+	STBCCC	R6, (R3)
+	BNE	again
+	RET
+
+// func Or(addr *uint32, v uint32)
+TEXT ·Or(SB), NOSPLIT, $0-12
+	MOVD	ptr+0(FP), R3
+	MOVW	val+8(FP), R4
+	LWSYNC
+again:
+	LWAR	(R3), R6
+	OR	R4, R6
+	STWCCC	R6, (R3)
+	BNE	again
+	RET
+
+// func And(addr *uint32, v uint32)
+TEXT ·And(SB), NOSPLIT, $0-12
+	MOVD	ptr+0(FP), R3
+	MOVW	val+8(FP), R4
+	LWSYNC
+again:
+	LWAR	(R3),R6
+	AND	R4, R6
+	STWCCC	R6, (R3)
+	BNE	again
+	RET
diff --git a/src/runtime/internal/atomic/atomic_riscv64.s b/src/runtime/internal/atomic/atomic_riscv64.s
index 74c896c..21d5adc 100644
--- a/src/runtime/internal/atomic/atomic_riscv64.s
+++ b/src/runtime/internal/atomic/atomic_riscv64.s
@@ -30,14 +30,14 @@
 
 #include "textflag.h"
 
+// func Cas(ptr *uint64, old, new uint64) bool
 // Atomically:
-//      if(*val == *old){
+//      if(*val == old){
 //              *val = new;
 //              return 1;
 //      } else {
 //              return 0;
 //      }
-
 TEXT ·Cas(SB), NOSPLIT, $0-17
 	MOV	ptr+0(FP), A0
 	MOVW	old+8(FP), A1
@@ -121,6 +121,12 @@
 TEXT ·Casp1(SB), NOSPLIT, $0-25
 	JMP	·Cas64(SB)
 
+TEXT ·Casint32(SB),NOSPLIT,$0-17
+	JMP	·Cas(SB)
+
+TEXT ·Casint64(SB),NOSPLIT,$0-25
+	JMP	·Cas64(SB)
+
 TEXT ·Casuintptr(SB),NOSPLIT,$0-25
 	JMP	·Cas64(SB)
 
@@ -130,14 +136,26 @@
 TEXT ·Loaduintptr(SB),NOSPLIT,$0-16
 	JMP	·Load64(SB)
 
+TEXT ·Storeint32(SB),NOSPLIT,$0-12
+	JMP	·Store(SB)
+
+TEXT ·Storeint64(SB),NOSPLIT,$0-16
+	JMP	·Store64(SB)
+
 TEXT ·Storeuintptr(SB),NOSPLIT,$0-16
 	JMP	·Store64(SB)
 
 TEXT ·Loaduint(SB),NOSPLIT,$0-16
 	JMP ·Loaduintptr(SB)
 
+TEXT ·Loadint32(SB),NOSPLIT,$0-12
+	JMP ·Load(SB)
+
 TEXT ·Loadint64(SB),NOSPLIT,$0-16
-	JMP ·Loaduintptr(SB)
+	JMP ·Load64(SB)
+
+TEXT ·Xaddint32(SB),NOSPLIT,$0-20
+	JMP ·Xadd(SB)
 
 TEXT ·Xaddint64(SB),NOSPLIT,$0-24
 	MOV	ptr+0(FP), A0
@@ -215,6 +233,14 @@
 TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
 	JMP	·Xadd64(SB)
 
+// func Xchgint32(ptr *int32, new int32) int32
+TEXT ·Xchgint32(SB), NOSPLIT, $0-20
+	JMP	·Xchg(SB)
+
+// func Xchgint64(ptr *int64, new int64) int64
+TEXT ·Xchgint64(SB), NOSPLIT, $0-24
+	JMP	·Xchg64(SB)
+
 // func Xchguintptr(ptr *uintptr, new uintptr) uintptr
 TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
 	JMP	·Xchg64(SB)
diff --git a/src/runtime/internal/atomic/atomic_s390x.s b/src/runtime/internal/atomic/atomic_s390x.s
new file mode 100644
index 0000000..a0c204b
--- /dev/null
+++ b/src/runtime/internal/atomic/atomic_s390x.s
@@ -0,0 +1,248 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// func Store(ptr *uint32, val uint32)
+TEXT ·Store(SB), NOSPLIT, $0
+	MOVD	ptr+0(FP), R2
+	MOVWZ	val+8(FP), R3
+	MOVW	R3, 0(R2)
+	SYNC
+	RET
+
+// func Store8(ptr *uint8, val uint8)
+TEXT ·Store8(SB), NOSPLIT, $0
+	MOVD	ptr+0(FP), R2
+	MOVB	val+8(FP), R3
+	MOVB	R3, 0(R2)
+	SYNC
+	RET
+
+// func Store64(ptr *uint64, val uint64)
+TEXT ·Store64(SB), NOSPLIT, $0
+	MOVD	ptr+0(FP), R2
+	MOVD	val+8(FP), R3
+	MOVD	R3, 0(R2)
+	SYNC
+	RET
+
+// func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)
+TEXT ·StorepNoWB(SB), NOSPLIT, $0
+	MOVD	ptr+0(FP), R2
+	MOVD	val+8(FP), R3
+	MOVD	R3, 0(R2)
+	SYNC
+	RET
+
+// func Cas(ptr *uint32, old, new uint32) bool
+// Atomically:
+//	if *ptr == old {
+//		*val = new
+//		return 1
+//	} else {
+//		return 0
+//	}
+TEXT ·Cas(SB), NOSPLIT, $0-17
+	MOVD	ptr+0(FP), R3
+	MOVWZ	old+8(FP), R4
+	MOVWZ	new+12(FP), R5
+	CS	R4, R5, 0(R3)    //  if (R4 == 0(R3)) then 0(R3)= R5
+	BNE	cas_fail
+	MOVB	$1, ret+16(FP)
+	RET
+cas_fail:
+	MOVB	$0, ret+16(FP)
+	RET
+
+// func Cas64(ptr *uint64, old, new uint64) bool
+// Atomically:
+//	if *ptr == old {
+//		*ptr = new
+//		return 1
+//	} else {
+//		return 0
+//	}
+TEXT ·Cas64(SB), NOSPLIT, $0-25
+	MOVD	ptr+0(FP), R3
+	MOVD	old+8(FP), R4
+	MOVD	new+16(FP), R5
+	CSG	R4, R5, 0(R3)    //  if (R4 == 0(R3)) then 0(R3)= R5
+	BNE	cas64_fail
+	MOVB	$1, ret+24(FP)
+	RET
+cas64_fail:
+	MOVB	$0, ret+24(FP)
+	RET
+
+// func Casint32(ptr *int32, old, new int32) bool
+TEXT ·Casint32(SB), NOSPLIT, $0-17
+	BR	·Cas(SB)
+
+// func Casint64(ptr *int64, old, new int64) bool
+TEXT ·Casint64(SB), NOSPLIT, $0-25
+	BR	·Cas64(SB)
+
+// func Casuintptr(ptr *uintptr, old, new uintptr) bool
+TEXT ·Casuintptr(SB), NOSPLIT, $0-25
+	BR	·Cas64(SB)
+
+// func CasRel(ptr *uint32, old, new uint32) bool
+TEXT ·CasRel(SB), NOSPLIT, $0-17
+	BR	·Cas(SB)
+
+// func Loaduintptr(ptr *uintptr) uintptr
+TEXT ·Loaduintptr(SB), NOSPLIT, $0-16
+	BR	·Load64(SB)
+
+// func Loaduint(ptr *uint) uint
+TEXT ·Loaduint(SB), NOSPLIT, $0-16
+	BR	·Load64(SB)
+
+// func Storeint32(ptr *int32, new int32)
+TEXT ·Storeint32(SB), NOSPLIT, $0-12
+	BR	·Store(SB)
+
+// func Storeint64(ptr *int64, new int64)
+TEXT ·Storeint64(SB), NOSPLIT, $0-16
+	BR	·Store64(SB)
+
+// func Storeuintptr(ptr *uintptr, new uintptr)
+TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
+	BR	·Store64(SB)
+
+// func Loadint32(ptr *int32) int32
+TEXT ·Loadint32(SB), NOSPLIT, $0-12
+	BR	·Load(SB)
+
+// func Loadint64(ptr *int64) int64
+TEXT ·Loadint64(SB), NOSPLIT, $0-16
+	BR	·Load64(SB)
+
+// func Xadduintptr(ptr *uintptr, delta uintptr) uintptr
+TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
+	BR	·Xadd64(SB)
+
+// func Xaddint32(ptr *int32, delta int32) int32
+TEXT ·Xaddint32(SB), NOSPLIT, $0-20
+	BR	·Xadd(SB)
+
+// func Xaddint64(ptr *int64, delta int64) int64
+TEXT ·Xaddint64(SB), NOSPLIT, $0-24
+	BR	·Xadd64(SB)
+
+// func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool
+// Atomically:
+//	if *ptr == old {
+//		*ptr = new
+//		return 1
+//	} else {
+//		return 0
+//	}
+TEXT ·Casp1(SB), NOSPLIT, $0-25
+	BR ·Cas64(SB)
+
+// func Xadd(ptr *uint32, delta int32) uint32
+// Atomically:
+//	*ptr += delta
+//	return *ptr
+TEXT ·Xadd(SB), NOSPLIT, $0-20
+	MOVD	ptr+0(FP), R4
+	MOVW	delta+8(FP), R5
+	MOVW	(R4), R3
+repeat:
+	ADD	R5, R3, R6
+	CS	R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
+	BNE	repeat
+	MOVW	R6, ret+16(FP)
+	RET
+
+// func Xadd64(ptr *uint64, delta int64) uint64
+TEXT ·Xadd64(SB), NOSPLIT, $0-24
+	MOVD	ptr+0(FP), R4
+	MOVD	delta+8(FP), R5
+	MOVD	(R4), R3
+repeat:
+	ADD	R5, R3, R6
+	CSG	R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
+	BNE	repeat
+	MOVD	R6, ret+16(FP)
+	RET
+
+// func Xchg(ptr *uint32, new uint32) uint32
+TEXT ·Xchg(SB), NOSPLIT, $0-20
+	MOVD	ptr+0(FP), R4
+	MOVW	new+8(FP), R3
+	MOVW	(R4), R6
+repeat:
+	CS	R6, R3, (R4) // if R6==(R4) then (R4)=R3 else R6=(R4)
+	BNE	repeat
+	MOVW	R6, ret+16(FP)
+	RET
+
+// func Xchg64(ptr *uint64, new uint64) uint64
+TEXT ·Xchg64(SB), NOSPLIT, $0-24
+	MOVD	ptr+0(FP), R4
+	MOVD	new+8(FP), R3
+	MOVD	(R4), R6
+repeat:
+	CSG	R6, R3, (R4) // if R6==(R4) then (R4)=R3 else R6=(R4)
+	BNE	repeat
+	MOVD	R6, ret+16(FP)
+	RET
+
+// func Xchgint32(ptr *int32, new int32) int32
+TEXT ·Xchgint32(SB), NOSPLIT, $0-20
+	BR	·Xchg(SB)
+
+// func Xchgint64(ptr *int64, new int64) int64
+TEXT ·Xchgint64(SB), NOSPLIT, $0-24
+	BR	·Xchg64(SB)
+
+// func Xchguintptr(ptr *uintptr, new uintptr) uintptr
+TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
+	BR	·Xchg64(SB)
+
+// func Or8(addr *uint8, v uint8)
+TEXT ·Or8(SB), NOSPLIT, $0-9
+	MOVD	ptr+0(FP), R3
+	MOVBZ	val+8(FP), R4
+	// We don't have atomic operations that work on individual bytes so we
+	// need to align addr down to a word boundary and create a mask
+	// containing v to OR with the entire word atomically.
+	MOVD	$(3<<3), R5
+	RXSBG	$59, $60, $3, R3, R5 // R5 = 24 - ((addr % 4) * 8) = ((addr & 3) << 3) ^ (3 << 3)
+	ANDW	$~3, R3              // R3 = floor(addr, 4) = addr &^ 3
+	SLW	R5, R4               // R4 = uint32(v) << R5
+	LAO	R4, R6, 0(R3)        // R6 = *R3; *R3 |= R4; (atomic)
+	RET
+
+// func And8(addr *uint8, v uint8)
+TEXT ·And8(SB), NOSPLIT, $0-9
+	MOVD	ptr+0(FP), R3
+	MOVBZ	val+8(FP), R4
+	// We don't have atomic operations that work on individual bytes so we
+	// need to align addr down to a word boundary and create a mask
+	// containing v to AND with the entire word atomically.
+	ORW	$~0xff, R4           // R4 = uint32(v) | 0xffffff00
+	MOVD	$(3<<3), R5
+	RXSBG	$59, $60, $3, R3, R5 // R5 = 24 - ((addr % 4) * 8) = ((addr & 3) << 3) ^ (3 << 3)
+	ANDW	$~3, R3              // R3 = floor(addr, 4) = addr &^ 3
+	RLL	R5, R4, R4           // R4 = rotl(R4, R5)
+	LAN	R4, R6, 0(R3)        // R6 = *R3; *R3 &= R4; (atomic)
+	RET
+
+// func Or(addr *uint32, v uint32)
+TEXT ·Or(SB), NOSPLIT, $0-12
+	MOVD	ptr+0(FP), R3
+	MOVW	val+8(FP), R4
+	LAO	R4, R6, 0(R3)        // R6 = *R3; *R3 |= R4; (atomic)
+	RET
+
+// func And(addr *uint32, v uint32)
+TEXT ·And(SB), NOSPLIT, $0-12
+	MOVD	ptr+0(FP), R3
+	MOVW	val+8(FP), R4
+	LAN	R4, R6, 0(R3)        // R6 = *R3; *R3 &= R4; (atomic)
+	RET
diff --git a/src/runtime/internal/atomic/atomic_wasm.go b/src/runtime/internal/atomic/atomic_wasm.go
index b05d98e..3f77f16 100644
--- a/src/runtime/internal/atomic/atomic_wasm.go
+++ b/src/runtime/internal/atomic/atomic_wasm.go
@@ -9,18 +9,28 @@
 //go:linkname Load
 //go:linkname Loadp
 //go:linkname Load64
+//go:linkname Loadint32
+//go:linkname Loadint64
 //go:linkname Loaduintptr
 //go:linkname Xadd
+//go:linkname Xaddint32
+//go:linkname Xaddint64
 //go:linkname Xadd64
 //go:linkname Xadduintptr
 //go:linkname Xchg
 //go:linkname Xchg64
+//go:linkname Xchgint32
+//go:linkname Xchgint64
 //go:linkname Xchguintptr
 //go:linkname Cas
 //go:linkname Cas64
+//go:linkname Casint32
+//go:linkname Casint64
 //go:linkname Casuintptr
 //go:linkname Store
 //go:linkname Store64
+//go:linkname Storeint32
+//go:linkname Storeint64
 //go:linkname Storeuintptr
 
 package atomic
@@ -111,6 +121,22 @@
 
 //go:nosplit
 //go:noinline
+func Xchgint32(ptr *int32, new int32) int32 {
+	old := *ptr
+	*ptr = new
+	return old
+}
+
+//go:nosplit
+//go:noinline
+func Xchgint64(ptr *int64, new int64) int64 {
+	old := *ptr
+	*ptr = new
+	return old
+}
+
+//go:nosplit
+//go:noinline
 func Xchguintptr(ptr *uintptr, new uintptr) uintptr {
 	old := *ptr
 	*ptr = new
@@ -197,6 +223,26 @@
 
 //go:nosplit
 //go:noinline
+func Casint32(ptr *int32, old, new int32) bool {
+	if *ptr == old {
+		*ptr = new
+		return true
+	}
+	return false
+}
+
+//go:nosplit
+//go:noinline
+func Casint64(ptr *int64, old, new int64) bool {
+	if *ptr == old {
+		*ptr = new
+		return true
+	}
+	return false
+}
+
+//go:nosplit
+//go:noinline
 func Cas(ptr *uint32, old, new uint32) bool {
 	if *ptr == old {
 		*ptr = new
@@ -237,6 +283,18 @@
 
 //go:nosplit
 //go:noinline
+func Storeint32(ptr *int32, new int32) {
+	*ptr = new
+}
+
+//go:nosplit
+//go:noinline
+func Storeint64(ptr *int64, new int64) {
+	*ptr = new
+}
+
+//go:nosplit
+//go:noinline
 func Storeuintptr(ptr *uintptr, new uintptr) {
 	*ptr = new
 }
@@ -255,12 +313,26 @@
 
 //go:nosplit
 //go:noinline
+func Loadint32(ptr *int32) int32 {
+	return *ptr
+}
+
+//go:nosplit
+//go:noinline
 func Loadint64(ptr *int64) int64 {
 	return *ptr
 }
 
 //go:nosplit
 //go:noinline
+func Xaddint32(ptr *int32, delta int32) int32 {
+	new := *ptr + delta
+	*ptr = new
+	return new
+}
+
+//go:nosplit
+//go:noinline
 func Xaddint64(ptr *int64, delta int64) int64 {
 	new := *ptr + delta
 	*ptr = new
diff --git a/src/runtime/internal/atomic/atomic_wasm.s b/src/runtime/internal/atomic/atomic_wasm.s
new file mode 100644
index 0000000..1c2d1ce
--- /dev/null
+++ b/src/runtime/internal/atomic/atomic_wasm.s
@@ -0,0 +1,10 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·StorepNoWB(SB), NOSPLIT, $0-16
+	MOVD ptr+0(FP), R0
+	MOVD val+8(FP), 0(R0)
+	RET
diff --git a/src/runtime/internal/atomic/stubs.go b/src/runtime/internal/atomic/stubs.go
index 62e30d1..e7544ba 100644
--- a/src/runtime/internal/atomic/stubs.go
+++ b/src/runtime/internal/atomic/stubs.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !wasm
 // +build !wasm
 
 package atomic
@@ -15,9 +16,21 @@
 func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool
 
 //go:noescape
+func Casint32(ptr *int32, old, new int32) bool
+
+//go:noescape
+func Casint64(ptr *int64, old, new int64) bool
+
+//go:noescape
 func Casuintptr(ptr *uintptr, old, new uintptr) bool
 
 //go:noescape
+func Storeint32(ptr *int32, new int32)
+
+//go:noescape
+func Storeint64(ptr *int64, new int64)
+
+//go:noescape
 func Storeuintptr(ptr *uintptr, new uintptr)
 
 //go:noescape
@@ -29,7 +42,19 @@
 // TODO(matloob): Should these functions have the go:noescape annotation?
 
 //go:noescape
+func Loadint32(ptr *int32) int32
+
+//go:noescape
 func Loadint64(ptr *int64) int64
 
 //go:noescape
+func Xaddint32(ptr *int32, delta int32) int32
+
+//go:noescape
 func Xaddint64(ptr *int64, delta int64) int64
+
+//go:noescape
+func Xchgint32(ptr *int32, new int32) int32
+
+//go:noescape
+func Xchgint64(ptr *int64, new int64) int64
diff --git a/src/runtime/internal/atomic/sys_linux_arm.s b/src/runtime/internal/atomic/sys_linux_arm.s
index 192be4b..0cc7fa7 100644
--- a/src/runtime/internal/atomic/sys_linux_arm.s
+++ b/src/runtime/internal/atomic/sys_linux_arm.s
@@ -24,7 +24,7 @@
 TEXT cas<>(SB),NOSPLIT,$0
 	MOVW	$0xffff0fc0, R15 // R15 is hardware PC.
 
-TEXT runtime∕internal∕atomic·Cas(SB),NOSPLIT|NOFRAME,$0
+TEXT ·Cas(SB),NOSPLIT|NOFRAME,$0
 	MOVB	runtime·goarm(SB), R11
 	CMP	$7, R11
 	BLT	2(PC)
diff --git a/src/runtime/internal/atomic/sys_nonlinux_arm.s b/src/runtime/internal/atomic/sys_nonlinux_arm.s
index 57568b2..04036ca 100644
--- a/src/runtime/internal/atomic/sys_nonlinux_arm.s
+++ b/src/runtime/internal/atomic/sys_nonlinux_arm.s
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !linux,arm
+//go:build !linux
+// +build !linux
 
 #include "textflag.h"
 
diff --git a/src/runtime/internal/math/math.go b/src/runtime/internal/math/math.go
index 5385f5d..b6bd12d 100644
--- a/src/runtime/internal/math/math.go
+++ b/src/runtime/internal/math/math.go
@@ -17,3 +17,24 @@
 	overflow := b > MaxUintptr/a
 	return a * b, overflow
 }
+
+// Mul64 returns the 128-bit product of x and y: (hi, lo) = x * y
+// with the product bits' upper half returned in hi and the lower
+// half returned in lo.
+// This is a copy from math/bits.Mul64
+// On supported platforms this is an intrinsic lowered by the compiler.
+func Mul64(x, y uint64) (hi, lo uint64) {
+	const mask32 = 1<<32 - 1
+	x0 := x & mask32
+	x1 := x >> 32
+	y0 := y & mask32
+	y1 := y >> 32
+	w0 := x0 * y0
+	t := x1*y0 + w0>>32
+	w1 := t & mask32
+	w2 := t >> 32
+	w1 += x0 * y1
+	hi = x1*y1 + w2 + w1>>32
+	lo = x * y
+	return
+}
diff --git a/src/runtime/internal/sys/arch.go b/src/runtime/internal/sys/arch.go
index 13c00cf..3c99a2f 100644
--- a/src/runtime/internal/sys/arch.go
+++ b/src/runtime/internal/sys/arch.go
@@ -18,3 +18,37 @@
 	S390X
 	WASM
 )
+
+// PtrSize is the size of a pointer in bytes - unsafe.Sizeof(uintptr(0)) but as an ideal constant.
+// It is also the size of the machine's native word size (that is, 4 on 32-bit systems, 8 on 64-bit).
+const PtrSize = 4 << (^uintptr(0) >> 63)
+
+// AIX requires a larger stack for syscalls.
+const StackGuardMultiplier = StackGuardMultiplierDefault*(1-GoosAix) + 2*GoosAix
+
+// ArchFamily is the architecture family (AMD64, ARM, ...)
+const ArchFamily ArchFamilyType = _ArchFamily
+
+// BigEndian reports whether the architecture is big-endian.
+const BigEndian = GoarchArmbe|GoarchArm64be|GoarchMips|GoarchMips64|GoarchPpc|GoarchPpc64|GoarchS390|GoarchS390x|GoarchSparc|GoarchSparc64 == 1
+
+// DefaultPhysPageSize is the default physical page size.
+const DefaultPhysPageSize = _DefaultPhysPageSize
+
+// PCQuantum is the minimal unit for a program counter (1 on x86, 4 on most other systems).
+// The various PC tables record PC deltas pre-divided by PCQuantum.
+const PCQuantum = _PCQuantum
+
+// Int64Align is the required alignment for a 64-bit integer (4 on 32-bit systems, 8 on 64-bit).
+const Int64Align = PtrSize
+
+// MinFrameSize is the size of the system-reserved words at the bottom
+// of a frame (just above the architectural stack pointer).
+// It is zero on x86 and PtrSize on most non-x86 (LR-based) systems.
+// On PowerPC it is larger, to cover three more reserved words:
+// the compiler word, the link editor word, and the TOC save word.
+const MinFrameSize = _MinFrameSize
+
+// StackAlign is the required alignment of the SP register.
+// The stack must be at least word aligned, but some architectures require more.
+const StackAlign = _StackAlign
diff --git a/src/runtime/internal/sys/arch_386.go b/src/runtime/internal/sys/arch_386.go
index b51f70a..1ebce34 100644
--- a/src/runtime/internal/sys/arch_386.go
+++ b/src/runtime/internal/sys/arch_386.go
@@ -5,12 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = I386
-	BigEndian           = false
-	DefaultPhysPageSize = 4096
-	PCQuantum           = 1
-	Int64Align          = 4
-	MinFrameSize        = 0
+	_ArchFamily          = I386
+	_DefaultPhysPageSize = 4096
+	_PCQuantum           = 1
+	_MinFrameSize        = 0
+	_StackAlign          = PtrSize
 )
-
-type Uintreg uint32
diff --git a/src/runtime/internal/sys/arch_amd64.go b/src/runtime/internal/sys/arch_amd64.go
index 3d6776e..7f003d0 100644
--- a/src/runtime/internal/sys/arch_amd64.go
+++ b/src/runtime/internal/sys/arch_amd64.go
@@ -5,12 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = AMD64
-	BigEndian           = false
-	DefaultPhysPageSize = 4096
-	PCQuantum           = 1
-	Int64Align          = 8
-	MinFrameSize        = 0
+	_ArchFamily          = AMD64
+	_DefaultPhysPageSize = 4096
+	_PCQuantum           = 1
+	_MinFrameSize        = 0
+	_StackAlign          = PtrSize
 )
-
-type Uintreg uint64
diff --git a/src/runtime/internal/sys/arch_arm.go b/src/runtime/internal/sys/arch_arm.go
index 97960d6..ef2048b 100644
--- a/src/runtime/internal/sys/arch_arm.go
+++ b/src/runtime/internal/sys/arch_arm.go
@@ -5,12 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = ARM
-	BigEndian           = false
-	DefaultPhysPageSize = 65536
-	PCQuantum           = 4
-	Int64Align          = 4
-	MinFrameSize        = 4
+	_ArchFamily          = ARM
+	_DefaultPhysPageSize = 65536
+	_PCQuantum           = 4
+	_MinFrameSize        = 4
+	_StackAlign          = PtrSize
 )
-
-type Uintreg uint32
diff --git a/src/runtime/internal/sys/arch_arm64.go b/src/runtime/internal/sys/arch_arm64.go
index 911a948..b9f2f7b 100644
--- a/src/runtime/internal/sys/arch_arm64.go
+++ b/src/runtime/internal/sys/arch_arm64.go
@@ -5,12 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = ARM64
-	BigEndian           = false
-	DefaultPhysPageSize = 65536
-	PCQuantum           = 4
-	Int64Align          = 8
-	MinFrameSize        = 8
+	_ArchFamily          = ARM64
+	_DefaultPhysPageSize = 65536
+	_PCQuantum           = 4
+	_MinFrameSize        = 8
+	_StackAlign          = 16
 )
-
-type Uintreg uint64
diff --git a/src/runtime/internal/sys/arch_mips.go b/src/runtime/internal/sys/arch_mips.go
index 75cdb2e..4cb0eeb 100644
--- a/src/runtime/internal/sys/arch_mips.go
+++ b/src/runtime/internal/sys/arch_mips.go
@@ -5,12 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = MIPS
-	BigEndian           = true
-	DefaultPhysPageSize = 65536
-	PCQuantum           = 4
-	Int64Align          = 4
-	MinFrameSize        = 4
+	_ArchFamily          = MIPS
+	_DefaultPhysPageSize = 65536
+	_PCQuantum           = 4
+	_MinFrameSize        = 4
+	_StackAlign          = PtrSize
 )
-
-type Uintreg uint32
diff --git a/src/runtime/internal/sys/arch_mips64.go b/src/runtime/internal/sys/arch_mips64.go
index 494291a..57636ac 100644
--- a/src/runtime/internal/sys/arch_mips64.go
+++ b/src/runtime/internal/sys/arch_mips64.go
@@ -5,12 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = MIPS64
-	BigEndian           = true
-	DefaultPhysPageSize = 16384
-	PCQuantum           = 4
-	Int64Align          = 8
-	MinFrameSize        = 8
+	_ArchFamily          = MIPS64
+	_DefaultPhysPageSize = 16384
+	_PCQuantum           = 4
+	_MinFrameSize        = 8
+	_StackAlign          = PtrSize
 )
-
-type Uintreg uint64
diff --git a/src/runtime/internal/sys/arch_mips64le.go b/src/runtime/internal/sys/arch_mips64le.go
index d36d120..57636ac 100644
--- a/src/runtime/internal/sys/arch_mips64le.go
+++ b/src/runtime/internal/sys/arch_mips64le.go
@@ -5,12 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = MIPS64
-	BigEndian           = false
-	DefaultPhysPageSize = 16384
-	PCQuantum           = 4
-	Int64Align          = 8
-	MinFrameSize        = 8
+	_ArchFamily          = MIPS64
+	_DefaultPhysPageSize = 16384
+	_PCQuantum           = 4
+	_MinFrameSize        = 8
+	_StackAlign          = PtrSize
 )
-
-type Uintreg uint64
diff --git a/src/runtime/internal/sys/arch_mipsle.go b/src/runtime/internal/sys/arch_mipsle.go
index 323bf82..4240f5c 100644
--- a/src/runtime/internal/sys/arch_mipsle.go
+++ b/src/runtime/internal/sys/arch_mipsle.go
@@ -5,12 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = MIPS
-	BigEndian           = false
-	DefaultPhysPageSize = 65536
-	PCQuantum           = 4
-	Int64Align          = 4
-	MinFrameSize        = 4
+	_ArchFamily          = MIPS
+	_DefaultPhysPageSize = 65536
+	_PCQuantum           = 4
+	_MinFrameSize        = 4
+	_StackAlign          = PtrSize
 )
-
-type Uintreg uint32
diff --git a/src/runtime/internal/sys/arch_ppc64.go b/src/runtime/internal/sys/arch_ppc64.go
index da1fe3d..1869213 100644
--- a/src/runtime/internal/sys/arch_ppc64.go
+++ b/src/runtime/internal/sys/arch_ppc64.go
@@ -5,12 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = PPC64
-	BigEndian           = true
-	DefaultPhysPageSize = 65536
-	PCQuantum           = 4
-	Int64Align          = 8
-	MinFrameSize        = 32
+	_ArchFamily          = PPC64
+	_DefaultPhysPageSize = 65536
+	_PCQuantum           = 4
+	_MinFrameSize        = 32
+	_StackAlign          = 16
 )
-
-type Uintreg uint64
diff --git a/src/runtime/internal/sys/arch_ppc64le.go b/src/runtime/internal/sys/arch_ppc64le.go
index 6059799..1869213 100644
--- a/src/runtime/internal/sys/arch_ppc64le.go
+++ b/src/runtime/internal/sys/arch_ppc64le.go
@@ -5,12 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = PPC64
-	BigEndian           = false
-	DefaultPhysPageSize = 65536
-	PCQuantum           = 4
-	Int64Align          = 8
-	MinFrameSize        = 32
+	_ArchFamily          = PPC64
+	_DefaultPhysPageSize = 65536
+	_PCQuantum           = 4
+	_MinFrameSize        = 32
+	_StackAlign          = 16
 )
-
-type Uintreg uint64
diff --git a/src/runtime/internal/sys/arch_riscv64.go b/src/runtime/internal/sys/arch_riscv64.go
index 7cdcc8f..360d236 100644
--- a/src/runtime/internal/sys/arch_riscv64.go
+++ b/src/runtime/internal/sys/arch_riscv64.go
@@ -5,14 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = RISCV64
-	BigEndian           = false
-	CacheLineSize       = 64
-	DefaultPhysPageSize = 4096
-	PCQuantum           = 4
-	Int64Align          = 8
-	HugePageSize        = 1 << 21
-	MinFrameSize        = 8
+	_ArchFamily          = RISCV64
+	_DefaultPhysPageSize = 4096
+	_PCQuantum           = 4
+	_MinFrameSize        = 8
+	_StackAlign          = PtrSize
 )
-
-type Uintreg uint64
diff --git a/src/runtime/internal/sys/arch_s390x.go b/src/runtime/internal/sys/arch_s390x.go
index 12cb8a0..e33e0b7 100644
--- a/src/runtime/internal/sys/arch_s390x.go
+++ b/src/runtime/internal/sys/arch_s390x.go
@@ -5,12 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = S390X
-	BigEndian           = true
-	DefaultPhysPageSize = 4096
-	PCQuantum           = 2
-	Int64Align          = 8
-	MinFrameSize        = 8
+	_ArchFamily          = S390X
+	_DefaultPhysPageSize = 4096
+	_PCQuantum           = 2
+	_MinFrameSize        = 8
+	_StackAlign          = PtrSize
 )
-
-type Uintreg uint64
diff --git a/src/runtime/internal/sys/arch_wasm.go b/src/runtime/internal/sys/arch_wasm.go
index eb825df..ee919ff 100644
--- a/src/runtime/internal/sys/arch_wasm.go
+++ b/src/runtime/internal/sys/arch_wasm.go
@@ -5,12 +5,9 @@
 package sys
 
 const (
-	ArchFamily          = WASM
-	BigEndian           = false
-	DefaultPhysPageSize = 65536
-	PCQuantum           = 1
-	Int64Align          = 8
-	MinFrameSize        = 0
+	_ArchFamily          = WASM
+	_DefaultPhysPageSize = 65536
+	_PCQuantum           = 1
+	_MinFrameSize        = 0
+	_StackAlign          = PtrSize
 )
-
-type Uintreg uint64
diff --git a/src/runtime/internal/sys/gengoos.go b/src/runtime/internal/sys/gengoos.go
index 9bbc48d..ffe962f 100644
--- a/src/runtime/internal/sys/gengoos.go
+++ b/src/runtime/internal/sys/gengoos.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 package main
@@ -47,18 +48,21 @@
 		if target == "nacl" {
 			continue
 		}
-		var buf bytes.Buffer
-		fmt.Fprintf(&buf, "// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.\n\n")
+		var tags []string
 		if target == "linux" {
-			fmt.Fprintf(&buf, "// +build !android\n") // must explicitly exclude android for linux
+			tags = append(tags, "!android") // must explicitly exclude android for linux
 		}
 		if target == "solaris" {
-			fmt.Fprintf(&buf, "// +build !illumos\n") // must explicitly exclude illumos for solaris
+			tags = append(tags, "!illumos") // must explicitly exclude illumos for solaris
 		}
 		if target == "darwin" {
-			fmt.Fprintf(&buf, "// +build !ios\n") // must explicitly exclude ios for darwin
+			tags = append(tags, "!ios") // must explicitly exclude ios for darwin
 		}
-		fmt.Fprintf(&buf, "// +build %s\n\n", target) // must explicitly include target for bootstrapping purposes
+		tags = append(tags, target) // must explicitly include target for bootstrapping purposes
+		var buf bytes.Buffer
+		fmt.Fprintf(&buf, "// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.\n\n")
+		fmt.Fprintf(&buf, "//go:build %s\n", strings.Join(tags, " && "))
+		fmt.Fprintf(&buf, "// +build %s\n\n", strings.Join(tags, ","))
 		fmt.Fprintf(&buf, "package sys\n\n")
 		fmt.Fprintf(&buf, "const GOOS = `%s`\n\n", target)
 		for _, goos := range gooses {
@@ -80,6 +84,7 @@
 		}
 		var buf bytes.Buffer
 		fmt.Fprintf(&buf, "// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.\n\n")
+		fmt.Fprintf(&buf, "//go:build %s\n", target)
 		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)
diff --git a/src/runtime/internal/sys/intrinsics.go b/src/runtime/internal/sys/intrinsics.go
index 3c88982..e76d8dd 100644
--- a/src/runtime/internal/sys/intrinsics.go
+++ b/src/runtime/internal/sys/intrinsics.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !386
 // +build !386
 
 // TODO finish intrinsifying 386, deadcode the assembly, remove build tags, merge w/ intrinsics_common
diff --git a/src/runtime/internal/sys/intrinsics_stubs.go b/src/runtime/internal/sys/intrinsics_stubs.go
index 9cbf482..bf1494d 100644
--- a/src/runtime/internal/sys/intrinsics_stubs.go
+++ b/src/runtime/internal/sys/intrinsics_stubs.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386
 // +build 386
 
 package sys
diff --git a/src/runtime/internal/sys/stubs.go b/src/runtime/internal/sys/stubs.go
deleted file mode 100644
index 10b0173..0000000
--- a/src/runtime/internal/sys/stubs.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sys
-
-// Declarations for runtime services implemented in C or assembly.
-
-const PtrSize = 4 << (^uintptr(0) >> 63)           // unsafe.Sizeof(uintptr(0)) but an ideal const
-const RegSize = 4 << (^Uintreg(0) >> 63)           // unsafe.Sizeof(uintreg(0)) but an ideal const
-const SpAlign = 1*(1-GoarchArm64) + 16*GoarchArm64 // SP alignment: 1 normally, 16 for ARM64
-
-var DefaultGoroot string // set at link time
-
-// AIX requires a larger stack for syscalls.
-const StackGuardMultiplier = StackGuardMultiplierDefault*(1-GoosAix) + 2*GoosAix
diff --git a/src/runtime/internal/sys/zgoarch_386.go b/src/runtime/internal/sys/zgoarch_386.go
index c286d0d..5b189e7 100644
--- a/src/runtime/internal/sys/zgoarch_386.go
+++ b/src/runtime/internal/sys/zgoarch_386.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build 386
 // +build 386
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_amd64.go b/src/runtime/internal/sys/zgoarch_amd64.go
index d21c1d7..312977d 100644
--- a/src/runtime/internal/sys/zgoarch_amd64.go
+++ b/src/runtime/internal/sys/zgoarch_amd64.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build amd64
 // +build amd64
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_arm.go b/src/runtime/internal/sys/zgoarch_arm.go
index 9085fb0..5781870 100644
--- a/src/runtime/internal/sys/zgoarch_arm.go
+++ b/src/runtime/internal/sys/zgoarch_arm.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build arm
 // +build arm
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_arm64.go b/src/runtime/internal/sys/zgoarch_arm64.go
index ed7ef2e..f72a1f2 100644
--- a/src/runtime/internal/sys/zgoarch_arm64.go
+++ b/src/runtime/internal/sys/zgoarch_arm64.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build arm64
 // +build arm64
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_arm64be.go b/src/runtime/internal/sys/zgoarch_arm64be.go
index faf3111..e805646 100644
--- a/src/runtime/internal/sys/zgoarch_arm64be.go
+++ b/src/runtime/internal/sys/zgoarch_arm64be.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build arm64be
 // +build arm64be
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 1
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_armbe.go b/src/runtime/internal/sys/zgoarch_armbe.go
index cb28301..d8d4e56 100644
--- a/src/runtime/internal/sys/zgoarch_armbe.go
+++ b/src/runtime/internal/sys/zgoarch_armbe.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build armbe
 // +build armbe
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_loong64.go b/src/runtime/internal/sys/zgoarch_loong64.go
new file mode 100644
index 0000000..6f35eb4
--- /dev/null
+++ b/src/runtime/internal/sys/zgoarch_loong64.go
@@ -0,0 +1,33 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+//go:build loong64
+// +build loong64
+
+package sys
+
+const GOARCH = `loong64`
+
+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 GoarchLoong64 = 1
+const GoarchMips = 0
+const GoarchMipsle = 0
+const GoarchMips64 = 0
+const GoarchMips64le = 0
+const GoarchMips64p32 = 0
+const GoarchMips64p32le = 0
+const GoarchPpc = 0
+const GoarchRiscv = 0
+const GoarchRiscv64 = 0
+const GoarchS390 = 0
+const GoarchS390x = 0
+const GoarchSparc = 0
+const GoarchSparc64 = 0
+const GoarchWasm = 0
diff --git a/src/runtime/internal/sys/zgoarch_mips.go b/src/runtime/internal/sys/zgoarch_mips.go
index 315dea1..bd58a92 100644
--- a/src/runtime/internal/sys/zgoarch_mips.go
+++ b/src/runtime/internal/sys/zgoarch_mips.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build mips
 // +build mips
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 1
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_mips64.go b/src/runtime/internal/sys/zgoarch_mips64.go
index 5258cbf..8e4a3dc 100644
--- a/src/runtime/internal/sys/zgoarch_mips64.go
+++ b/src/runtime/internal/sys/zgoarch_mips64.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build mips64
 // +build mips64
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 1
diff --git a/src/runtime/internal/sys/zgoarch_mips64le.go b/src/runtime/internal/sys/zgoarch_mips64le.go
index 1721698..d8e0033 100644
--- a/src/runtime/internal/sys/zgoarch_mips64le.go
+++ b/src/runtime/internal/sys/zgoarch_mips64le.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build mips64le
 // +build mips64le
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_mips64p32.go b/src/runtime/internal/sys/zgoarch_mips64p32.go
index 44c4624..8549cc0 100644
--- a/src/runtime/internal/sys/zgoarch_mips64p32.go
+++ b/src/runtime/internal/sys/zgoarch_mips64p32.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build mips64p32
 // +build mips64p32
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_mips64p32le.go b/src/runtime/internal/sys/zgoarch_mips64p32le.go
index eb63225..667b6fe 100644
--- a/src/runtime/internal/sys/zgoarch_mips64p32le.go
+++ b/src/runtime/internal/sys/zgoarch_mips64p32le.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build mips64p32le
 // +build mips64p32le
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_mipsle.go b/src/runtime/internal/sys/zgoarch_mipsle.go
index e0ebfbf..8bedb2b 100644
--- a/src/runtime/internal/sys/zgoarch_mipsle.go
+++ b/src/runtime/internal/sys/zgoarch_mipsle.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build mipsle
 // +build mipsle
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 1
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_ppc.go b/src/runtime/internal/sys/zgoarch_ppc.go
index ef26aa3..fe2196a 100644
--- a/src/runtime/internal/sys/zgoarch_ppc.go
+++ b/src/runtime/internal/sys/zgoarch_ppc.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build ppc
 // +build ppc
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_ppc64.go b/src/runtime/internal/sys/zgoarch_ppc64.go
index 32c2d46..bd7cc43 100644
--- a/src/runtime/internal/sys/zgoarch_ppc64.go
+++ b/src/runtime/internal/sys/zgoarch_ppc64.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build ppc64
 // +build ppc64
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 1
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_ppc64le.go b/src/runtime/internal/sys/zgoarch_ppc64le.go
index 3a6e567..e101892 100644
--- a/src/runtime/internal/sys/zgoarch_ppc64le.go
+++ b/src/runtime/internal/sys/zgoarch_ppc64le.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build ppc64le
 // +build ppc64le
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 1
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_riscv.go b/src/runtime/internal/sys/zgoarch_riscv.go
index d8f6b49..559f860 100644
--- a/src/runtime/internal/sys/zgoarch_riscv.go
+++ b/src/runtime/internal/sys/zgoarch_riscv.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build riscv
 // +build riscv
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_riscv64.go b/src/runtime/internal/sys/zgoarch_riscv64.go
index 0ba843b..8485a94 100644
--- a/src/runtime/internal/sys/zgoarch_riscv64.go
+++ b/src/runtime/internal/sys/zgoarch_riscv64.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build riscv64
 // +build riscv64
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_s390.go b/src/runtime/internal/sys/zgoarch_s390.go
index 20a1b23..4c4569e 100644
--- a/src/runtime/internal/sys/zgoarch_s390.go
+++ b/src/runtime/internal/sys/zgoarch_s390.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build s390
 // +build s390
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_s390x.go b/src/runtime/internal/sys/zgoarch_s390x.go
index ffdda0c..e50d2ed 100644
--- a/src/runtime/internal/sys/zgoarch_s390x.go
+++ b/src/runtime/internal/sys/zgoarch_s390x.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build s390x
 // +build s390x
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_sparc.go b/src/runtime/internal/sys/zgoarch_sparc.go
index b494951..0d08752 100644
--- a/src/runtime/internal/sys/zgoarch_sparc.go
+++ b/src/runtime/internal/sys/zgoarch_sparc.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build sparc
 // +build sparc
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_sparc64.go b/src/runtime/internal/sys/zgoarch_sparc64.go
index 0f6df41..ba405bb 100644
--- a/src/runtime/internal/sys/zgoarch_sparc64.go
+++ b/src/runtime/internal/sys/zgoarch_sparc64.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build sparc64
 // +build sparc64
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoarch_wasm.go b/src/runtime/internal/sys/zgoarch_wasm.go
index e69afb0..7c3e5af 100644
--- a/src/runtime/internal/sys/zgoarch_wasm.go
+++ b/src/runtime/internal/sys/zgoarch_wasm.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build wasm
 // +build wasm
 
 package sys
@@ -15,6 +16,7 @@
 const GoarchArm64be = 0
 const GoarchPpc64 = 0
 const GoarchPpc64le = 0
+const GoarchLoong64 = 0
 const GoarchMips = 0
 const GoarchMipsle = 0
 const GoarchMips64 = 0
diff --git a/src/runtime/internal/sys/zgoos_aix.go b/src/runtime/internal/sys/zgoos_aix.go
index 0631d02..f3b9074 100644
--- a/src/runtime/internal/sys/zgoos_aix.go
+++ b/src/runtime/internal/sys/zgoos_aix.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build aix
 // +build aix
 
 package sys
diff --git a/src/runtime/internal/sys/zgoos_android.go b/src/runtime/internal/sys/zgoos_android.go
index d356a40..e28baf7 100644
--- a/src/runtime/internal/sys/zgoos_android.go
+++ b/src/runtime/internal/sys/zgoos_android.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build android
 // +build android
 
 package sys
diff --git a/src/runtime/internal/sys/zgoos_darwin.go b/src/runtime/internal/sys/zgoos_darwin.go
index 6aa2db7..3c7f7b5 100644
--- a/src/runtime/internal/sys/zgoos_darwin.go
+++ b/src/runtime/internal/sys/zgoos_darwin.go
@@ -1,7 +1,7 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
-// +build !ios
-// +build darwin
+//go:build !ios && darwin
+// +build !ios,darwin
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoos_dragonfly.go b/src/runtime/internal/sys/zgoos_dragonfly.go
index 88ee117..f844d29 100644
--- a/src/runtime/internal/sys/zgoos_dragonfly.go
+++ b/src/runtime/internal/sys/zgoos_dragonfly.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build dragonfly
 // +build dragonfly
 
 package sys
diff --git a/src/runtime/internal/sys/zgoos_freebsd.go b/src/runtime/internal/sys/zgoos_freebsd.go
index 8de2ec0..8999a27 100644
--- a/src/runtime/internal/sys/zgoos_freebsd.go
+++ b/src/runtime/internal/sys/zgoos_freebsd.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build freebsd
 // +build freebsd
 
 package sys
diff --git a/src/runtime/internal/sys/zgoos_hurd.go b/src/runtime/internal/sys/zgoos_hurd.go
index 183ccb0..a546488 100644
--- a/src/runtime/internal/sys/zgoos_hurd.go
+++ b/src/runtime/internal/sys/zgoos_hurd.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build hurd
 // +build hurd
 
 package sys
diff --git a/src/runtime/internal/sys/zgoos_illumos.go b/src/runtime/internal/sys/zgoos_illumos.go
index d04134e..02a4ca0 100644
--- a/src/runtime/internal/sys/zgoos_illumos.go
+++ b/src/runtime/internal/sys/zgoos_illumos.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build illumos
 // +build illumos
 
 package sys
diff --git a/src/runtime/internal/sys/zgoos_ios.go b/src/runtime/internal/sys/zgoos_ios.go
index cf6e9d6..033eec6 100644
--- a/src/runtime/internal/sys/zgoos_ios.go
+++ b/src/runtime/internal/sys/zgoos_ios.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build ios
 // +build ios
 
 package sys
diff --git a/src/runtime/internal/sys/zgoos_js.go b/src/runtime/internal/sys/zgoos_js.go
index 1d9279a..28226ad 100644
--- a/src/runtime/internal/sys/zgoos_js.go
+++ b/src/runtime/internal/sys/zgoos_js.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build js
 // +build js
 
 package sys
diff --git a/src/runtime/internal/sys/zgoos_linux.go b/src/runtime/internal/sys/zgoos_linux.go
index 0f718d7..01546e4 100644
--- a/src/runtime/internal/sys/zgoos_linux.go
+++ b/src/runtime/internal/sys/zgoos_linux.go
@@ -1,7 +1,7 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
-// +build !android
-// +build linux
+//go:build !android && linux
+// +build !android,linux
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoos_netbsd.go b/src/runtime/internal/sys/zgoos_netbsd.go
index 2ae149f..9d658b2 100644
--- a/src/runtime/internal/sys/zgoos_netbsd.go
+++ b/src/runtime/internal/sys/zgoos_netbsd.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build netbsd
 // +build netbsd
 
 package sys
diff --git a/src/runtime/internal/sys/zgoos_openbsd.go b/src/runtime/internal/sys/zgoos_openbsd.go
index 7d4d61e..0f55454 100644
--- a/src/runtime/internal/sys/zgoos_openbsd.go
+++ b/src/runtime/internal/sys/zgoos_openbsd.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build openbsd
 // +build openbsd
 
 package sys
diff --git a/src/runtime/internal/sys/zgoos_plan9.go b/src/runtime/internal/sys/zgoos_plan9.go
index 30aec46..d034746 100644
--- a/src/runtime/internal/sys/zgoos_plan9.go
+++ b/src/runtime/internal/sys/zgoos_plan9.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build plan9
 // +build plan9
 
 package sys
diff --git a/src/runtime/internal/sys/zgoos_solaris.go b/src/runtime/internal/sys/zgoos_solaris.go
index 4bb8c99..05c3007 100644
--- a/src/runtime/internal/sys/zgoos_solaris.go
+++ b/src/runtime/internal/sys/zgoos_solaris.go
@@ -1,7 +1,7 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
-// +build !illumos
-// +build solaris
+//go:build !illumos && solaris
+// +build !illumos,solaris
 
 package sys
 
diff --git a/src/runtime/internal/sys/zgoos_windows.go b/src/runtime/internal/sys/zgoos_windows.go
index d1f4290..7d07fa3 100644
--- a/src/runtime/internal/sys/zgoos_windows.go
+++ b/src/runtime/internal/sys/zgoos_windows.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build windows
 // +build windows
 
 package sys
diff --git a/src/runtime/internal/sys/zgoos_zos.go b/src/runtime/internal/sys/zgoos_zos.go
index d22be46..d6e5b9b 100644
--- a/src/runtime/internal/sys/zgoos_zos.go
+++ b/src/runtime/internal/sys/zgoos_zos.go
@@ -1,5 +1,6 @@
 // Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
 
+//go:build zos
 // +build zos
 
 package sys
diff --git a/src/runtime/internal/sys/zversion.go b/src/runtime/internal/sys/zversion.go
index bd495c6..b058a3d 100644
--- a/src/runtime/internal/sys/zversion.go
+++ b/src/runtime/internal/sys/zversion.go
@@ -2,6 +2,4 @@
 
 package sys
 
-const TheVersion = `go1.16.3`
-const Goexperiment = ``
 const StackGuardMultiplierDefault = 1
diff --git a/src/runtime/lfstack_32bit.go b/src/runtime/lfstack_32bit.go
index f07ff1c..c00f096 100644
--- a/src/runtime/lfstack_32bit.go
+++ b/src/runtime/lfstack_32bit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 || arm || mips || mipsle
 // +build 386 arm mips mipsle
 
 package runtime
diff --git a/src/runtime/lfstack_64bit.go b/src/runtime/lfstack_64bit.go
index 9d821b9..4812dd1 100644
--- a/src/runtime/lfstack_64bit.go
+++ b/src/runtime/lfstack_64bit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm
 // +build amd64 arm64 mips64 mips64le ppc64 ppc64le riscv64 s390x wasm
 
 package runtime
diff --git a/src/runtime/libfuzzer.go b/src/runtime/libfuzzer.go
index 0161955..578bce0 100644
--- a/src/runtime/libfuzzer.go
+++ b/src/runtime/libfuzzer.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build libfuzzer
 // +build libfuzzer
 
 package runtime
diff --git a/src/runtime/libfuzzer_amd64.s b/src/runtime/libfuzzer_amd64.s
index 890fde3..13645fc 100644
--- a/src/runtime/libfuzzer_amd64.s
+++ b/src/runtime/libfuzzer_amd64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build libfuzzer
 // +build libfuzzer
 
 #include "go_asm.h"
diff --git a/src/runtime/libfuzzer_arm64.s b/src/runtime/libfuzzer_arm64.s
index 121673e..4ad8242 100644
--- a/src/runtime/libfuzzer_arm64.s
+++ b/src/runtime/libfuzzer_arm64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build libfuzzer
 // +build libfuzzer
 
 #include "go_asm.h"
diff --git a/src/runtime/lock_futex.go b/src/runtime/lock_futex.go
index 91467fd..e4c8d01 100644
--- a/src/runtime/lock_futex.go
+++ b/src/runtime/lock_futex.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || linux
 // +build dragonfly freebsd linux
 
 package runtime
@@ -238,7 +239,7 @@
 	return ok
 }
 
-func beforeIdle(int64) (*g, bool) {
+func beforeIdle(int64, int64) (*g, bool) {
 	return nil, false
 }
 
diff --git a/src/runtime/lock_js.go b/src/runtime/lock_js.go
index 14bdc76..0ca3512 100644
--- a/src/runtime/lock_js.go
+++ b/src/runtime/lock_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package runtime
@@ -175,7 +176,12 @@
 // If an event handler returned, we resume it and it will pause the execution.
 // beforeIdle either returns the specific goroutine to schedule next or
 // indicates with otherReady that some goroutine became ready.
-func beforeIdle(delay int64) (gp *g, otherReady bool) {
+func beforeIdle(now, pollUntil int64) (gp *g, otherReady bool) {
+	delay := int64(-1)
+	if pollUntil != 0 {
+		delay = pollUntil - now
+	}
+
 	if delay > 0 {
 		clearIdleID()
 		if delay < 1e6 {
diff --git a/src/runtime/lock_sema.go b/src/runtime/lock_sema.go
index 671e524..7a6af28 100644
--- a/src/runtime/lock_sema.go
+++ b/src/runtime/lock_sema.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || netbsd || openbsd || plan9 || solaris || windows
 // +build aix darwin netbsd openbsd plan9 solaris windows
 
 package runtime
@@ -297,7 +298,7 @@
 	return ok
 }
 
-func beforeIdle(int64) (*g, bool) {
+func beforeIdle(int64, int64) (*g, bool) {
 	return nil, false
 }
 
diff --git a/src/runtime/lockrank.go b/src/runtime/lockrank.go
index b3c01ba..dde9f7c 100644
--- a/src/runtime/lockrank.go
+++ b/src/runtime/lockrank.go
@@ -44,7 +44,6 @@
 	lockRankPollDesc
 	lockRankSched
 	lockRankDeadlock
-	lockRankPanic
 	lockRankAllg
 	lockRankAllp
 
@@ -92,6 +91,7 @@
 	// rank, we don't allow any further locks to be acquired other than more
 	// hchan locks.
 	lockRankHchanLeaf
+	lockRankPanic
 
 	// Leaf locks with no dependencies, so these constants are not actually used anywhere.
 	// There are other architecture-dependent leaf locks as well.
@@ -123,7 +123,6 @@
 	lockRankPollDesc: "pollDesc",
 	lockRankSched:    "sched",
 	lockRankDeadlock: "deadlock",
-	lockRankPanic:    "panic",
 	lockRankAllg:     "allg",
 	lockRankAllp:     "allp",
 
@@ -162,6 +161,7 @@
 
 	lockRankGFree:     "gFree",
 	lockRankHchanLeaf: "hchanLeaf",
+	lockRankPanic:     "panic",
 
 	lockRankNewmHandoff:   "newmHandoff.lock",
 	lockRankDebugPtrmask:  "debugPtrmask.lock",
@@ -202,10 +202,9 @@
 	lockRankPollDesc:      {},
 	lockRankSched:         {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc},
 	lockRankDeadlock:      {lockRankDeadlock},
-	lockRankPanic:         {lockRankDeadlock},
-	lockRankAllg:          {lockRankSysmon, lockRankSched, lockRankPanic},
+	lockRankAllg:          {lockRankSysmon, lockRankSched},
 	lockRankAllp:          {lockRankSysmon, lockRankSched},
-	lockRankTimers:        {lockRankSysmon, lockRankScavenge, lockRankSched, lockRankAllp, lockRankPollDesc, lockRankTimers},
+	lockRankTimers:        {lockRankSysmon, lockRankScavenge, lockRankPollDesc, lockRankSched, lockRankAllp, lockRankTimers},
 	lockRankItab:          {},
 	lockRankReflectOffs:   {lockRankItab},
 	lockRankHchan:         {lockRankScavenge, lockRankSweep, lockRankHchan},
@@ -214,29 +213,30 @@
 	lockRankTraceBuf:      {lockRankSysmon, lockRankScavenge},
 	lockRankTraceStrings:  {lockRankTraceBuf},
 	lockRankMspanSpecial:  {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings},
-	lockRankProf:          {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan},
-	lockRankGcBitsArenas:  {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan},
+	lockRankProf:          {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings},
+	lockRankGcBitsArenas:  {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings},
 	lockRankRoot:          {},
-	lockRankTrace:         {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankSched, lockRankHchan, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot, lockRankSweep},
-	lockRankTraceStackTab: {lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankAllg, lockRankTimers, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot, lockRankTrace},
+	lockRankTrace:         {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankHchan, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot},
+	lockRankTraceStackTab: {lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankAllg, lockRankTimers, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot, lockRankTrace},
 	lockRankNetpollInit:   {lockRankTimers},
 
 	lockRankRwmutexW: {},
 	lockRankRwmutexR: {lockRankSysmon, lockRankRwmutexW},
 
-	lockRankSpanSetSpine: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan},
-	lockRankGscan:        {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot, lockRankNotifyList, lockRankProf, lockRankGcBitsArenas, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankSpanSetSpine},
-	lockRankStackpool:    {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankPollDesc, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankRwmutexR, lockRankSpanSetSpine, lockRankGscan},
+	lockRankSpanSetSpine: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings},
+	lockRankGscan:        {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankSpanSetSpine},
+	lockRankStackpool:    {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankRwmutexR, lockRankSpanSetSpine, lockRankGscan},
 	lockRankStackLarge:   {lockRankSysmon, lockRankAssistQueue, lockRankSched, lockRankItab, lockRankHchan, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankSpanSetSpine, lockRankGscan},
 	lockRankDefer:        {},
-	lockRankSudog:        {lockRankNotifyList, lockRankHchan},
-	lockRankWbufSpans:    {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankAllg, lockRankPollDesc, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankMspanSpecial, lockRankProf, lockRankRoot, lockRankGscan, lockRankDefer, lockRankSudog},
-	lockRankMheap:        {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankFin, lockRankPollDesc, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan, lockRankMspanSpecial, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankDefer, lockRankSudog, lockRankWbufSpans, lockRankSpanSetSpine},
-	lockRankMheapSpecial: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan},
+	lockRankSudog:        {lockRankHchan, lockRankNotifyList},
+	lockRankWbufSpans:    {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankMspanSpecial, lockRankProf, lockRankRoot, lockRankGscan, lockRankDefer, lockRankSudog},
+	lockRankMheap:        {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankMspanSpecial, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankSpanSetSpine, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankDefer, lockRankSudog, lockRankWbufSpans},
+	lockRankMheapSpecial: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings},
 	lockRankGlobalAlloc:  {lockRankProf, lockRankSpanSetSpine, lockRankMheap, lockRankMheapSpecial},
 
 	lockRankGFree:     {lockRankSched},
 	lockRankHchanLeaf: {lockRankGscan, lockRankHchanLeaf},
+	lockRankPanic:     {lockRankDeadlock}, // plus any other lock held on throw.
 
 	lockRankNewmHandoff:   {},
 	lockRankDebugPtrmask:  {},
diff --git a/src/runtime/lockrank_off.go b/src/runtime/lockrank_off.go
index 7dcd8f5..f3d2c00 100644
--- a/src/runtime/lockrank_off.go
+++ b/src/runtime/lockrank_off.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !goexperiment.staticlockranking
 // +build !goexperiment.staticlockranking
 
 package runtime
diff --git a/src/runtime/lockrank_on.go b/src/runtime/lockrank_on.go
index 88ac95a..fc8d2dc 100644
--- a/src/runtime/lockrank_on.go
+++ b/src/runtime/lockrank_on.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build goexperiment.staticlockranking
 // +build goexperiment.staticlockranking
 
 package runtime
@@ -24,19 +25,6 @@
 	pad int
 }
 
-// init checks that the partial order in lockPartialOrder fits within the total
-// order determined by the order of the lockRank constants.
-func init() {
-	for rank, list := range lockPartialOrder {
-		for _, entry := range list {
-			if entry > lockRank(rank) {
-				println("lockPartial order row", lockRank(rank).String(), "entry", entry.String())
-				throw("lockPartialOrder table is inconsistent with total lock ranking order")
-			}
-		}
-	}
-}
-
 func lockInit(l *mutex, rank lockRank) {
 	l.rank = rank
 }
@@ -64,12 +52,11 @@
 		// rank recording for it, since print/println are used when
 		// printing out a lock ordering problem below.
 		//
-		// paniclk has an ordering problem, since it can be acquired
-		// during a panic with any other locks held (especially if the
-		// panic is because of a directed segv), and yet also allg is
-		// acquired after paniclk in tracebackothers()). This is a genuine
-		// problem, so for now we don't do lock rank recording for paniclk
-		// either.
+		// paniclk is only used for fatal throw/panic. Don't do lock
+		// ranking recording for it, since we throw after reporting a
+		// lock ordering problem. Additionally, paniclk may be taken
+		// after effectively any lock (anywhere we might panic), which
+		// the partial order doesn't cover.
 		lock2(l)
 		return
 	}
@@ -219,7 +206,7 @@
 func lockWithRankMayAcquire(l *mutex, rank lockRank) {
 	gp := getg()
 	if gp.m.locksHeldLen == 0 {
-		// No possibilty of lock ordering problem if no other locks held
+		// No possibility of lock ordering problem if no other locks held
 		return
 	}
 
diff --git a/src/runtime/lockrank_test.go b/src/runtime/lockrank_test.go
new file mode 100644
index 0000000..4b2fc0e
--- /dev/null
+++ b/src/runtime/lockrank_test.go
@@ -0,0 +1,41 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	. "runtime"
+	"testing"
+)
+
+// Check that the partial order in lockPartialOrder fits within the total order
+// determined by the order of the lockRank constants.
+func TestLockRankPartialOrder(t *testing.T) {
+	for r, list := range LockPartialOrder {
+		rank := LockRank(r)
+		for _, e := range list {
+			entry := LockRank(e)
+			if entry > rank {
+				t.Errorf("lockPartialOrder row %v entry %v is inconsistent with total lock ranking order", rank, entry)
+			}
+		}
+	}
+}
+
+// Verify that partial order lists are kept sorted. This is a purely cosemetic
+// check to make manual reviews simpler. It does not affect correctness, unlike
+// the above test.
+func TestLockRankPartialOrderSortedEntries(t *testing.T) {
+	for r, list := range LockPartialOrder {
+		rank := LockRank(r)
+		var prev LockRank
+		for _, e := range list {
+			entry := LockRank(e)
+			if entry <= prev {
+				t.Errorf("Partial order for rank %v out of order: %v <= %v in %v", rank, entry, prev, list)
+			}
+			prev = entry
+		}
+	}
+}
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index f20ded5..cc22b0f 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -227,6 +227,7 @@
 	// --------------  ---------  ----------  ----------  -----------
 	//       */64-bit         48        64MB           1    4M (32MB)
 	// windows/64-bit         48         4MB          64    1M  (8MB)
+	//      ios/arm64         33         4MB           1  2048  (8KB)
 	//       */32-bit         32         4MB           1  1024  (4KB)
 	//     */mips(le)         31         4MB           1   512  (2KB)
 
@@ -247,7 +248,7 @@
 	// logHeapArenaBytes is log_2 of heapArenaBytes. For clarity,
 	// prefer using heapArenaBytes where possible (we need the
 	// constant to compute some other constants).
-	logHeapArenaBytes = (6+20)*(_64bit*(1-sys.GoosWindows)*(1-sys.GoarchWasm)) + (2+20)*(_64bit*sys.GoosWindows) + (2+20)*(1-_64bit) + (2+20)*sys.GoarchWasm
+	logHeapArenaBytes = (6+20)*(_64bit*(1-sys.GoosWindows)*(1-sys.GoarchWasm)*(1-sys.GoosIos*sys.GoarchArm64)) + (2+20)*(_64bit*sys.GoosWindows) + (2+20)*(1-_64bit) + (2+20)*sys.GoarchWasm + (2+20)*sys.GoosIos*sys.GoarchArm64
 
 	// heapArenaBitmapBytes is the size of each heap arena's bitmap.
 	heapArenaBitmapBytes = heapArenaBytes / (sys.PtrSize * 8 / 2)
@@ -295,7 +296,7 @@
 	// high addresses if viewed as unsigned).
 	//
 	// On aix/ppc64, this offset allows to keep the heapAddrBits to
-	// 48. Otherwize, it would be 60 in order to handle mmap addresses
+	// 48. Otherwise, it would be 60 in order to handle mmap addresses
 	// (in range 0x0a00000000000000 - 0x0afffffffffffff). But in this
 	// case, the memory reserved in (s *pageAlloc).init for chunks
 	// is causing important slowdowns.
@@ -568,7 +569,7 @@
 		const arenaMetaSize = (1 << arenaBits) * unsafe.Sizeof(heapArena{})
 		meta := uintptr(sysReserve(nil, arenaMetaSize))
 		if meta != 0 {
-			mheap_.heapArenaAlloc.init(meta, arenaMetaSize)
+			mheap_.heapArenaAlloc.init(meta, arenaMetaSize, true)
 		}
 
 		// We want to start the arena low, but if we're linked
@@ -605,7 +606,7 @@
 		for _, arenaSize := range arenaSizes {
 			a, size := sysReserveAligned(unsafe.Pointer(p), arenaSize, heapArenaBytes)
 			if a != nil {
-				mheap_.arena.init(uintptr(a), size)
+				mheap_.arena.init(uintptr(a), size, false)
 				p = mheap_.arena.end // For hint below
 				break
 			}
@@ -622,8 +623,8 @@
 // heapArenaBytes. sysAlloc returns nil on failure.
 // There is no corresponding free function.
 //
-// sysAlloc returns a memory region in the Prepared state. This region must
-// be transitioned to Ready before use.
+// sysAlloc returns a memory region in the Reserved state. This region must
+// be transitioned to Prepared and then Ready before use.
 //
 // h must be locked.
 func (h *mheap) sysAlloc(n uintptr) (v unsafe.Pointer, size uintptr) {
@@ -725,9 +726,6 @@
 		throw("misrounded allocation in sysAlloc")
 	}
 
-	// Transition from Reserved to Prepared.
-	sysMap(v, size, &memstats.heap_sys)
-
 mapped:
 	// Create arena metadata.
 	for ri := arenaIndex(uintptr(v)); ri <= arenaIndex(uintptr(v)+size-1); ri++ {
@@ -936,7 +934,7 @@
 		}
 
 		if inittrace.active && inittrace.id == getg().goid {
-			// Init functions are executed sequentially in a single Go routine.
+			// Init functions are executed sequentially in a single goroutine.
 			inittrace.allocs += 1
 		}
 	}
@@ -981,6 +979,9 @@
 	var span *mspan
 	var x unsafe.Pointer
 	noscan := typ == nil || typ.ptrdata == 0
+	// In some cases block zeroing can profitably (for latency reduction purposes)
+	// be delayed till preemption is possible; isZeroed tracks that state.
+	isZeroed := true
 	if size <= maxSmallSize {
 		if noscan && size < maxTinySize {
 			// Tiny allocator.
@@ -1049,7 +1050,8 @@
 			(*[2]uint64)(x)[1] = 0
 			// See if we need to replace the existing tiny block with the new one
 			// based on amount of remaining free space.
-			if size < c.tinyoffset || c.tiny == 0 {
+			if !raceenabled && (size < c.tinyoffset || c.tiny == 0) {
+				// Note: disabled when race detector is on, see comment near end of this function.
 				c.tiny = uintptr(x)
 				c.tinyoffset = size
 			}
@@ -1075,7 +1077,9 @@
 		}
 	} else {
 		shouldhelpgc = true
-		span = c.allocLarge(size, needzero, noscan)
+		// For large allocations, keep track of zeroed state so that
+		// bulk zeroing can be happen later in a preemptible context.
+		span, isZeroed = c.allocLarge(size, needzero && !noscan, noscan)
 		span.freeindex = 1
 		span.allocCount = 1
 		x = unsafe.Pointer(span.base())
@@ -1131,30 +1135,34 @@
 		msanmalloc(x, size)
 	}
 
+	if rate := MemProfileRate; rate > 0 {
+		// Note cache c only valid while m acquired; see #47302
+		if rate != 1 && size < c.nextSample {
+			c.nextSample -= size
+		} else {
+			profilealloc(mp, x, size)
+		}
+	}
 	mp.mallocing = 0
 	releasem(mp)
 
+	// Pointerfree data can be zeroed late in a context where preemption can occur.
+	// x will keep the memory alive.
+	if !isZeroed && needzero {
+		memclrNoHeapPointersChunked(size, x) // This is a possible preemption point: see #47302
+	}
+
 	if debug.malloc {
 		if debug.allocfreetrace != 0 {
 			tracealloc(x, size, typ)
 		}
 
 		if inittrace.active && inittrace.id == getg().goid {
-			// Init functions are executed sequentially in a single Go routine.
+			// Init functions are executed sequentially in a single goroutine.
 			inittrace.bytes += uint64(size)
 		}
 	}
 
-	if rate := MemProfileRate; rate > 0 {
-		if rate != 1 && size < c.nextSample {
-			c.nextSample -= size
-		} else {
-			mp := acquirem()
-			profilealloc(mp, x, size)
-			releasem(mp)
-		}
-	}
-
 	if assistG != nil {
 		// Account for internal fragmentation in the assist
 		// debt now that we know it.
@@ -1167,9 +1175,52 @@
 		}
 	}
 
+	if raceenabled && noscan && dataSize < maxTinySize {
+		// Pad tinysize allocations so they are aligned with the end
+		// of the tinyalloc region. This ensures that any arithmetic
+		// that goes off the top end of the object will be detectable
+		// by checkptr (issue 38872).
+		// Note that we disable tinyalloc when raceenabled for this to work.
+		// TODO: This padding is only performed when the race detector
+		// is enabled. It would be nice to enable it if any package
+		// was compiled with checkptr, but there's no easy way to
+		// detect that (especially at compile time).
+		// TODO: enable this padding for all allocations, not just
+		// tinyalloc ones. It's tricky because of pointer maps.
+		// Maybe just all noscan objects?
+		x = add(x, size-dataSize)
+	}
+
 	return x
 }
 
+// memclrNoHeapPointersChunked repeatedly calls memclrNoHeapPointers
+// on chunks of the buffer to be zeroed, with opportunities for preemption
+// along the way.  memclrNoHeapPointers contains no safepoints and also
+// cannot be preemptively scheduled, so this provides a still-efficient
+// block copy that can also be preempted on a reasonable granularity.
+//
+// Use this with care; if the data being cleared is tagged to contain
+// pointers, this allows the GC to run before it is all cleared.
+func memclrNoHeapPointersChunked(size uintptr, x unsafe.Pointer) {
+	v := uintptr(x)
+	// got this from benchmarking. 128k is too small, 512k is too large.
+	const chunkBytes = 256 * 1024
+	vsize := v + size
+	for voff := v; voff < vsize; voff = voff + chunkBytes {
+		if getg().preempt {
+			// may hold locks, e.g., profiling
+			goschedguarded()
+		}
+		// clear min(avail, lump) bytes
+		n := vsize - voff
+		if n > chunkBytes {
+			n = chunkBytes
+		}
+		memclrNoHeapPointers(unsafe.Pointer(voff), n)
+	}
+}
+
 // implementation of new builtin
 // compiler (both frontend and SSA backend) knows the signature
 // of this function
@@ -1400,15 +1451,19 @@
 }
 
 // linearAlloc is a simple linear allocator that pre-reserves a region
-// of memory and then maps that region into the Ready state as needed. The
-// caller is responsible for locking.
+// of memory and then optionally maps that region into the Ready state
+// as needed.
+//
+// The caller is responsible for locking.
 type linearAlloc struct {
 	next   uintptr // next free byte
 	mapped uintptr // one byte past end of mapped space
 	end    uintptr // end of reserved space
+
+	mapMemory bool // transition memory from Reserved to Ready if true
 }
 
-func (l *linearAlloc) init(base, size uintptr) {
+func (l *linearAlloc) init(base, size uintptr, mapMemory bool) {
 	if base+size < base {
 		// Chop off the last byte. The runtime isn't prepared
 		// to deal with situations where the bounds could overflow.
@@ -1418,6 +1473,7 @@
 	}
 	l.next, l.mapped = base, base
 	l.end = base + size
+	l.mapMemory = mapMemory
 }
 
 func (l *linearAlloc) alloc(size, align uintptr, sysStat *sysMemStat) unsafe.Pointer {
@@ -1427,9 +1483,11 @@
 	}
 	l.next = p + size
 	if pEnd := alignUp(l.next-1, physPageSize); pEnd > l.mapped {
-		// Transition from Reserved to Prepared to Ready.
-		sysMap(unsafe.Pointer(l.mapped), pEnd-l.mapped, sysStat)
-		sysUsed(unsafe.Pointer(l.mapped), pEnd-l.mapped)
+		if l.mapMemory {
+			// Transition from Reserved to Prepared to Ready.
+			sysMap(unsafe.Pointer(l.mapped), pEnd-l.mapped, sysStat)
+			sysUsed(unsafe.Pointer(l.mapped), pEnd-l.mapped)
+		}
 		l.mapped = pEnd
 	}
 	return unsafe.Pointer(p)
diff --git a/src/runtime/malloc_test.go b/src/runtime/malloc_test.go
index 4ba94d0..e028554 100644
--- a/src/runtime/malloc_test.go
+++ b/src/runtime/malloc_test.go
@@ -154,6 +154,9 @@
 }
 
 func TestTinyAlloc(t *testing.T) {
+	if runtime.Raceenabled {
+		t.Skip("tinyalloc suppressed when running in race mode")
+	}
 	const N = 16
 	var v [N]unsafe.Pointer
 	for i := range v {
@@ -182,6 +185,9 @@
 }
 
 func TestTinyAllocIssue37262(t *testing.T) {
+	if runtime.Raceenabled {
+		t.Skip("tinyalloc suppressed when running in race mode")
+	}
 	// Try to cause an alignment access fault
 	// by atomically accessing the first 64-bit
 	// value of a tiny-allocated object.
diff --git a/src/runtime/map.go b/src/runtime/map.go
index 0beff57..111db56 100644
--- a/src/runtime/map.go
+++ b/src/runtime/map.go
@@ -113,7 +113,7 @@
 
 // A header for a Go map.
 type hmap struct {
-	// Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go.
+	// Note: the format of the hmap is also encoded in cmd/compile/internal/reflectdata/reflect.go.
 	// Make sure this stays in sync with the compiler's definition.
 	count     int // # live cells == size of map.  Must be first (used by len() builtin)
 	flags     uint8
@@ -159,11 +159,11 @@
 }
 
 // A hash iteration structure.
-// If you modify hiter, also change cmd/compile/internal/gc/reflect.go to indicate
+// If you modify hiter, also change cmd/compile/internal/reflectdata/reflect.go to indicate
 // the layout of this structure.
 type hiter struct {
-	key         unsafe.Pointer // Must be in first position.  Write nil to indicate iteration end (see cmd/compile/internal/gc/range.go).
-	elem        unsafe.Pointer // Must be in second position (see cmd/compile/internal/gc/range.go).
+	key         unsafe.Pointer // Must be in first position.  Write nil to indicate iteration end (see cmd/compile/internal/walk/range.go).
+	elem        unsafe.Pointer // Must be in second position (see cmd/compile/internal/walk/range.go).
 	t           *maptype
 	h           *hmap
 	buckets     unsafe.Pointer // bucket ptr at hash_iter initialization time
@@ -470,13 +470,13 @@
 	}
 	hash := t.hasher(key, uintptr(h.hash0))
 	m := bucketMask(h.B)
-	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + (hash&m)*uintptr(t.bucketsize)))
+	b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
 	if c := h.oldbuckets; c != nil {
 		if !h.sameSizeGrow() {
 			// There used to be half as many buckets; mask down one more power of two.
 			m >>= 1
 		}
-		oldb := (*bmap)(unsafe.Pointer(uintptr(c) + (hash&m)*uintptr(t.bucketsize)))
+		oldb := (*bmap)(add(c, (hash&m)*uintptr(t.bucketsize)))
 		if !evacuated(oldb) {
 			b = oldb
 		}
@@ -514,13 +514,13 @@
 	}
 	hash := t.hasher(key, uintptr(h.hash0))
 	m := bucketMask(h.B)
-	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + (hash&m)*uintptr(t.bucketsize)))
+	b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
 	if c := h.oldbuckets; c != nil {
 		if !h.sameSizeGrow() {
 			// There used to be half as many buckets; mask down one more power of two.
 			m >>= 1
 		}
-		oldb := (*bmap)(unsafe.Pointer(uintptr(c) + (hash&m)*uintptr(t.bucketsize)))
+		oldb := (*bmap)(add(c, (hash&m)*uintptr(t.bucketsize)))
 		if !evacuated(oldb) {
 			b = oldb
 		}
@@ -810,7 +810,7 @@
 	}
 
 	if unsafe.Sizeof(hiter{})/sys.PtrSize != 12 {
-		throw("hash_iter size incorrect") // see cmd/compile/internal/gc/reflect.go
+		throw("hash_iter size incorrect") // see cmd/compile/internal/reflectdata/reflect.go
 	}
 	it.t = t
 	it.h = h
diff --git a/src/runtime/map_faststr.go b/src/runtime/map_faststr.go
index 2d1ac76..0673dd3 100644
--- a/src/runtime/map_faststr.go
+++ b/src/runtime/map_faststr.go
@@ -255,6 +255,9 @@
 			// already have a mapping for key. Update it.
 			inserti = i
 			insertb = b
+			// Overwrite existing key, so it can be garbage collected.
+			// The size is already guaranteed to be set correctly.
+			k.str = key.str
 			goto done
 		}
 		ovf := b.overflow(t)
diff --git a/src/runtime/mbarrier.go b/src/runtime/mbarrier.go
index 2b5affc..4994347 100644
--- a/src/runtime/mbarrier.go
+++ b/src/runtime/mbarrier.go
@@ -14,6 +14,7 @@
 package runtime
 
 import (
+	"internal/abi"
 	"runtime/internal/sys"
 	"unsafe"
 )
@@ -223,11 +224,18 @@
 // stack map of reflectcall is wrong.
 //
 //go:nosplit
-func reflectcallmove(typ *_type, dst, src unsafe.Pointer, size uintptr) {
+func reflectcallmove(typ *_type, dst, src unsafe.Pointer, size uintptr, regs *abi.RegArgs) {
 	if writeBarrier.needed && typ != nil && typ.ptrdata != 0 && size >= sys.PtrSize {
 		bulkBarrierPreWrite(uintptr(dst), uintptr(src), size)
 	}
 	memmove(dst, src, size)
+
+	// Move pointers returned in registers to a place where the GC can see them.
+	for i := range regs.Ints {
+		if regs.ReturnIsPtr.Get(i) {
+			regs.Ptrs[i] = unsafe.Pointer(regs.Ints[i])
+		}
+	}
 }
 
 //go:nosplit
diff --git a/src/runtime/mbitmap.go b/src/runtime/mbitmap.go
index fbfaae0..32b8db7 100644
--- a/src/runtime/mbitmap.go
+++ b/src/runtime/mbitmap.go
@@ -226,16 +226,25 @@
 	return *bytep&mask == 0
 }
 
+// divideByElemSize returns n/s.elemsize.
+// n must be within [0, s.npages*_PageSize),
+// or may be exactly s.npages*_PageSize
+// if s.elemsize is from sizeclasses.go.
+func (s *mspan) divideByElemSize(n uintptr) uintptr {
+	const doubleCheck = false
+
+	// See explanation in mksizeclasses.go's computeDivMagic.
+	q := uintptr((uint64(n) * uint64(s.divMul)) >> 32)
+
+	if doubleCheck && q != n/s.elemsize {
+		println(n, "/", s.elemsize, "should be", n/s.elemsize, "but got", q)
+		throw("bad magic division")
+	}
+	return q
+}
+
 func (s *mspan) objIndex(p uintptr) uintptr {
-	byteOffset := p - s.base()
-	if byteOffset == 0 {
-		return 0
-	}
-	if s.baseMask != 0 {
-		// s.baseMask is non-0, elemsize is a power of two, so shift by s.divShift
-		return byteOffset >> s.divShift
-	}
-	return uintptr(((uint64(byteOffset) >> s.divShift) * uint64(s.divMul)) >> s.divShift2)
+	return s.divideByElemSize(p - s.base())
 }
 
 func markBitsForAddr(p uintptr) markBits {
@@ -324,6 +333,10 @@
 	return
 }
 
+// clobberdeadPtr is a special value that is used by the compiler to
+// clobber dead stack slots, when -clobberdead flag is set.
+const clobberdeadPtr = uintptr(0xdeaddead | 0xdeaddead<<((^uintptr(0)>>63)*32))
+
 // badPointer throws bad pointer in heap panic.
 func badPointer(s *mspan, p, refBase, refOff uintptr) {
 	// Typically this indicates an incorrect use
@@ -336,13 +349,16 @@
 	// in allocated spans.
 	printlock()
 	print("runtime: pointer ", hex(p))
-	state := s.state.get()
-	if state != mSpanInUse {
-		print(" to unallocated span")
-	} else {
-		print(" to unused region of span")
+	if s != nil {
+		state := s.state.get()
+		if state != mSpanInUse {
+			print(" to unallocated span")
+		} else {
+			print(" to unused region of span")
+		}
+		print(" span.base()=", hex(s.base()), " span.limit=", hex(s.limit), " span.state=", state)
 	}
-	print(" span.base()=", hex(s.base()), " span.limit=", hex(s.limit), " span.state=", state, "\n")
+	print("\n")
 	if refBase != 0 {
 		print("runtime: found in object at *(", hex(refBase), "+", hex(refOff), ")\n")
 		gcDumpObject("object", refBase, refOff)
@@ -370,6 +386,12 @@
 	// If s is nil, the virtual address has never been part of the heap.
 	// This pointer may be to some mmap'd region, so we allow it.
 	if s == nil {
+		if GOARCH == "amd64" && p == clobberdeadPtr && debug.invalidptr != 0 {
+			// Crash if clobberdeadPtr is seen. Only on AMD64 for now, as
+			// it is the only platform where compiler's clobberdead mode is
+			// implemented. On AMD64 clobberdeadPtr cannot be a valid address.
+			badPointer(s, p, refBase, refOff)
+		}
 		return
 	}
 	// If p is a bad pointer, it may not be in s's bounds.
@@ -388,24 +410,9 @@
 		}
 		return
 	}
-	// If this span holds object of a power of 2 size, just mask off the bits to
-	// the interior of the object. Otherwise use the size to get the base.
-	if s.baseMask != 0 {
-		// optimize for power of 2 sized objects.
-		base = s.base()
-		base = base + (p-base)&uintptr(s.baseMask)
-		objIndex = (base - s.base()) >> s.divShift
-		// base = p & s.baseMask is faster for small spans,
-		// but doesn't work for large spans.
-		// Overall, it's faster to use the more general computation above.
-	} else {
-		base = s.base()
-		if p-base >= s.elemsize {
-			// n := (p - base) / s.elemsize, using division by multiplication
-			objIndex = uintptr(p-base) >> s.divShift * uintptr(s.divMul) >> s.divShift2
-			base += objIndex * s.elemsize
-		}
-	}
+
+	objIndex = s.objIndex(p)
+	base = s.base() + objIndex*s.elemsize
 	return
 }
 
diff --git a/src/runtime/mcache.go b/src/runtime/mcache.go
index bb7475b..a9e9591 100644
--- a/src/runtime/mcache.go
+++ b/src/runtime/mcache.go
@@ -176,29 +176,29 @@
 	// mcache. If it gets uncached, we'll adjust this.
 	stats := memstats.heapStats.acquire()
 	atomic.Xadduintptr(&stats.smallAllocCount[spc.sizeclass()], uintptr(s.nelems)-uintptr(s.allocCount))
-	memstats.heapStats.release()
-
-	// Update heap_live with the same assumption.
-	usedBytes := uintptr(s.allocCount) * s.elemsize
-	atomic.Xadd64(&memstats.heap_live, int64(s.npages*pageSize)-int64(usedBytes))
 
 	// Flush tinyAllocs.
 	if spc == tinySpanClass {
-		atomic.Xadd64(&memstats.tinyallocs, int64(c.tinyAllocs))
+		atomic.Xadduintptr(&stats.tinyAllocCount, c.tinyAllocs)
 		c.tinyAllocs = 0
 	}
+	memstats.heapStats.release()
+
+	// Update gcController.heapLive with the same assumption.
+	usedBytes := uintptr(s.allocCount) * s.elemsize
+	atomic.Xadd64(&gcController.heapLive, int64(s.npages*pageSize)-int64(usedBytes))
 
 	// While we're here, flush scanAlloc, since we have to call
 	// revise anyway.
-	atomic.Xadd64(&memstats.heap_scan, int64(c.scanAlloc))
+	atomic.Xadd64(&gcController.heapScan, int64(c.scanAlloc))
 	c.scanAlloc = 0
 
 	if trace.enabled {
-		// heap_live changed.
+		// gcController.heapLive changed.
 		traceHeapAlloc()
 	}
 	if gcBlackenEnabled != 0 {
-		// heap_live and heap_scan changed.
+		// gcController.heapLive and heapScan changed.
 		gcController.revise()
 	}
 
@@ -206,7 +206,10 @@
 }
 
 // allocLarge allocates a span for a large object.
-func (c *mcache) allocLarge(size uintptr, needzero bool, noscan bool) *mspan {
+// The boolean result indicates whether the span is known-zeroed.
+// If it did not need to be zeroed, it may not have been zeroed;
+// but if it came directly from the OS, it is already zeroed.
+func (c *mcache) allocLarge(size uintptr, needzero bool, noscan bool) (*mspan, bool) {
 	if size+_PageSize < size {
 		throw("out of memory")
 	}
@@ -221,7 +224,7 @@
 	deductSweepCredit(npages*_PageSize, npages)
 
 	spc := makeSpanClass(0, noscan)
-	s := mheap_.alloc(npages, spc, needzero)
+	s, isZeroed := mheap_.alloc(npages, spc, needzero)
 	if s == nil {
 		throw("out of memory")
 	}
@@ -230,10 +233,10 @@
 	atomic.Xadduintptr(&stats.largeAllocCount, 1)
 	memstats.heapStats.release()
 
-	// Update heap_live and revise pacing if needed.
-	atomic.Xadd64(&memstats.heap_live, int64(npages*pageSize))
+	// Update gcController.heapLive and revise pacing if needed.
+	atomic.Xadd64(&gcController.heapLive, int64(npages*pageSize))
 	if trace.enabled {
-		// Trace that a heap alloc occurred because heap_live changed.
+		// Trace that a heap alloc occurred because gcController.heapLive changed.
 		traceHeapAlloc()
 	}
 	if gcBlackenEnabled != 0 {
@@ -245,12 +248,12 @@
 	mheap_.central[spc].mcentral.fullSwept(mheap_.sweepgen).push(s)
 	s.limit = s.base() + size
 	heapBitsForAddr(s.base()).initSpan(s)
-	return s
+	return s, isZeroed
 }
 
 func (c *mcache) releaseAll() {
 	// Take this opportunity to flush scanAlloc.
-	atomic.Xadd64(&memstats.heap_scan, int64(c.scanAlloc))
+	atomic.Xadd64(&gcController.heapScan, int64(c.scanAlloc))
 	c.scanAlloc = 0
 
 	sg := mheap_.sweepgen
@@ -263,14 +266,14 @@
 			atomic.Xadduintptr(&stats.smallAllocCount[spanClass(i).sizeclass()], -n)
 			memstats.heapStats.release()
 			if s.sweepgen != sg+1 {
-				// refill conservatively counted unallocated slots in heap_live.
+				// refill conservatively counted unallocated slots in gcController.heapLive.
 				// Undo this.
 				//
 				// If this span was cached before sweep, then
-				// heap_live was totally recomputed since
+				// gcController.heapLive was totally recomputed since
 				// caching this span, so we don't do this for
 				// stale spans.
-				atomic.Xadd64(&memstats.heap_live, -int64(n)*int64(s.elemsize))
+				atomic.Xadd64(&gcController.heapLive, -int64(n)*int64(s.elemsize))
 			}
 			// Release the span to the mcentral.
 			mheap_.central[i].mcentral.uncacheSpan(s)
@@ -280,10 +283,14 @@
 	// Clear tinyalloc pool.
 	c.tiny = 0
 	c.tinyoffset = 0
-	atomic.Xadd64(&memstats.tinyallocs, int64(c.tinyAllocs))
-	c.tinyAllocs = 0
 
-	// Updated heap_scan and possible heap_live.
+	// Flush tinyAllocs.
+	stats := memstats.heapStats.acquire()
+	atomic.Xadduintptr(&stats.tinyAllocCount, c.tinyAllocs)
+	c.tinyAllocs = 0
+	memstats.heapStats.release()
+
+	// Updated heapScan and possible gcController.heapLive.
 	if gcBlackenEnabled != 0 {
 		gcController.revise()
 	}
diff --git a/src/runtime/mcentral.go b/src/runtime/mcentral.go
index cd20dec..6013c94 100644
--- a/src/runtime/mcentral.go
+++ b/src/runtime/mcentral.go
@@ -81,8 +81,6 @@
 	spanBytes := uintptr(class_to_allocnpages[c.spanclass.sizeclass()]) * _PageSize
 	deductSweepCredit(spanBytes, 0)
 
-	sg := mheap_.sweepgen
-
 	traceDone := false
 	if trace.enabled {
 		traceGCSweepStart()
@@ -104,6 +102,8 @@
 	spanBudget := 100
 
 	var s *mspan
+	sl := newSweepLocker()
+	sg := sl.sweepGen
 
 	// Try partial swept spans first.
 	if s = c.partialSwept(sg).pop(); s != nil {
@@ -116,9 +116,10 @@
 		if s == nil {
 			break
 		}
-		if atomic.Load(&s.sweepgen) == sg-2 && atomic.Cas(&s.sweepgen, sg-2, sg-1) {
+		if s, ok := sl.tryAcquire(s); ok {
 			// We got ownership of the span, so let's sweep it and use it.
 			s.sweep(true)
+			sl.dispose()
 			goto havespan
 		}
 		// We failed to get ownership of the span, which means it's being or
@@ -135,20 +136,22 @@
 		if s == nil {
 			break
 		}
-		if atomic.Load(&s.sweepgen) == sg-2 && atomic.Cas(&s.sweepgen, sg-2, sg-1) {
+		if s, ok := sl.tryAcquire(s); ok {
 			// We got ownership of the span, so let's sweep it.
 			s.sweep(true)
 			// Check if there's any free space.
 			freeIndex := s.nextFreeIndex()
 			if freeIndex != s.nelems {
 				s.freeindex = freeIndex
+				sl.dispose()
 				goto havespan
 			}
 			// Add it to the swept list, because sweeping didn't give us any free space.
-			c.fullSwept(sg).push(s)
+			c.fullSwept(sg).push(s.mspan)
 		}
 		// See comment for partial unswept spans.
 	}
+	sl.dispose()
 	if trace.enabled {
 		traceGCSweepDone()
 		traceDone = true
@@ -211,7 +214,13 @@
 	if stale {
 		// It's stale, so just sweep it. Sweeping will put it on
 		// the right list.
-		s.sweep(false)
+		//
+		// We don't use a sweepLocker here. Stale cached spans
+		// aren't in the global sweep lists, so mark termination
+		// itself holds up sweep completion until all mcaches
+		// have been swept.
+		ss := sweepLocked{s}
+		ss.sweep(false)
 	} else {
 		if int(s.nelems)-int(s.allocCount) > 0 {
 			// Put it back on the partial swept list.
@@ -229,14 +238,14 @@
 	npages := uintptr(class_to_allocnpages[c.spanclass.sizeclass()])
 	size := uintptr(class_to_size[c.spanclass.sizeclass()])
 
-	s := mheap_.alloc(npages, c.spanclass, true)
+	s, _ := mheap_.alloc(npages, c.spanclass, true)
 	if s == nil {
 		return nil
 	}
 
 	// Use division by multiplication and shifts to quickly compute:
 	// n := (npages << _PageShift) / size
-	n := (npages << _PageShift) >> s.divShift * uintptr(s.divMul) >> s.divShift2
+	n := s.divideByElemSize(npages << _PageShift)
 	s.limit = s.base() + size*n
 	heapBitsForAddr(s.base()).initSpan(s)
 	return s
diff --git a/src/runtime/mem_bsd.go b/src/runtime/mem_bsd.go
index bc67201..dcbb9a1 100644
--- a/src/runtime/mem_bsd.go
+++ b/src/runtime/mem_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || netbsd || openbsd || solaris
 // +build dragonfly freebsd netbsd openbsd solaris
 
 package runtime
diff --git a/src/runtime/mem_js.go b/src/runtime/mem_js.go
index 957ed36..fe94036 100644
--- a/src/runtime/mem_js.go
+++ b/src/runtime/mem_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package runtime
diff --git a/src/runtime/memclr_386.s b/src/runtime/memclr_386.s
index 5e090ef..046c344 100644
--- a/src/runtime/memclr_386.s
+++ b/src/runtime/memclr_386.s
@@ -2,13 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !plan9
 // +build !plan9
 
 #include "go_asm.h"
 #include "textflag.h"
 
-// NOTE: Windows externalthreadhandler expects memclr to preserve DX.
-
 // See memclrNoHeapPointers Go doc for important implementation constraints.
 
 // func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
diff --git a/src/runtime/memclr_amd64.s b/src/runtime/memclr_amd64.s
index 37fe974..a10f57b 100644
--- a/src/runtime/memclr_amd64.s
+++ b/src/runtime/memclr_amd64.s
@@ -2,19 +2,25 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !plan9
 // +build !plan9
 
 #include "go_asm.h"
 #include "textflag.h"
 
-// NOTE: Windows externalthreadhandler expects memclr to preserve DX.
-
 // See memclrNoHeapPointers Go doc for important implementation constraints.
 
 // func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
-TEXT runtime·memclrNoHeapPointers(SB), NOSPLIT, $0-16
+// ABIInternal for performance.
+TEXT runtime·memclrNoHeapPointers<ABIInternal>(SB), NOSPLIT, $0-16
+#ifdef GOEXPERIMENT_regabiargs
+	// AX = ptr
+	// BX = n
+	MOVQ	AX, DI	// DI = ptr
+#else
 	MOVQ	ptr+0(FP), DI
 	MOVQ	n+8(FP), BX
+#endif
 	XORQ	AX, AX
 
 	// MOVOU seems always faster than REP STOSQ.
@@ -31,7 +37,9 @@
 	JE	_8
 	CMPQ	BX, $16
 	JBE	_9through16
-	PXOR	X0, X0
+#ifndef GOEXPERIMENT_regabig
+	PXOR	X15, X15
+#endif
 	CMPQ	BX, $32
 	JBE	_17through32
 	CMPQ	BX, $64
@@ -45,22 +53,22 @@
 	// TODO: for really big clears, use MOVNTDQ, even without AVX2.
 
 loop:
-	MOVOU	X0, 0(DI)
-	MOVOU	X0, 16(DI)
-	MOVOU	X0, 32(DI)
-	MOVOU	X0, 48(DI)
-	MOVOU	X0, 64(DI)
-	MOVOU	X0, 80(DI)
-	MOVOU	X0, 96(DI)
-	MOVOU	X0, 112(DI)
-	MOVOU	X0, 128(DI)
-	MOVOU	X0, 144(DI)
-	MOVOU	X0, 160(DI)
-	MOVOU	X0, 176(DI)
-	MOVOU	X0, 192(DI)
-	MOVOU	X0, 208(DI)
-	MOVOU	X0, 224(DI)
-	MOVOU	X0, 240(DI)
+	MOVOU	X15, 0(DI)
+	MOVOU	X15, 16(DI)
+	MOVOU	X15, 32(DI)
+	MOVOU	X15, 48(DI)
+	MOVOU	X15, 64(DI)
+	MOVOU	X15, 80(DI)
+	MOVOU	X15, 96(DI)
+	MOVOU	X15, 112(DI)
+	MOVOU	X15, 128(DI)
+	MOVOU	X15, 144(DI)
+	MOVOU	X15, 160(DI)
+	MOVOU	X15, 176(DI)
+	MOVOU	X15, 192(DI)
+	MOVOU	X15, 208(DI)
+	MOVOU	X15, 224(DI)
+	MOVOU	X15, 240(DI)
 	SUBQ	$256, BX
 	ADDQ	$256, DI
 	CMPQ	BX, $256
@@ -141,40 +149,40 @@
 	MOVQ	AX, -8(DI)(BX*1)
 	RET
 _17through32:
-	MOVOU	X0, (DI)
-	MOVOU	X0, -16(DI)(BX*1)
+	MOVOU	X15, (DI)
+	MOVOU	X15, -16(DI)(BX*1)
 	RET
 _33through64:
-	MOVOU	X0, (DI)
-	MOVOU	X0, 16(DI)
-	MOVOU	X0, -32(DI)(BX*1)
-	MOVOU	X0, -16(DI)(BX*1)
+	MOVOU	X15, (DI)
+	MOVOU	X15, 16(DI)
+	MOVOU	X15, -32(DI)(BX*1)
+	MOVOU	X15, -16(DI)(BX*1)
 	RET
 _65through128:
-	MOVOU	X0, (DI)
-	MOVOU	X0, 16(DI)
-	MOVOU	X0, 32(DI)
-	MOVOU	X0, 48(DI)
-	MOVOU	X0, -64(DI)(BX*1)
-	MOVOU	X0, -48(DI)(BX*1)
-	MOVOU	X0, -32(DI)(BX*1)
-	MOVOU	X0, -16(DI)(BX*1)
+	MOVOU	X15, (DI)
+	MOVOU	X15, 16(DI)
+	MOVOU	X15, 32(DI)
+	MOVOU	X15, 48(DI)
+	MOVOU	X15, -64(DI)(BX*1)
+	MOVOU	X15, -48(DI)(BX*1)
+	MOVOU	X15, -32(DI)(BX*1)
+	MOVOU	X15, -16(DI)(BX*1)
 	RET
 _129through256:
-	MOVOU	X0, (DI)
-	MOVOU	X0, 16(DI)
-	MOVOU	X0, 32(DI)
-	MOVOU	X0, 48(DI)
-	MOVOU	X0, 64(DI)
-	MOVOU	X0, 80(DI)
-	MOVOU	X0, 96(DI)
-	MOVOU	X0, 112(DI)
-	MOVOU	X0, -128(DI)(BX*1)
-	MOVOU	X0, -112(DI)(BX*1)
-	MOVOU	X0, -96(DI)(BX*1)
-	MOVOU	X0, -80(DI)(BX*1)
-	MOVOU	X0, -64(DI)(BX*1)
-	MOVOU	X0, -48(DI)(BX*1)
-	MOVOU	X0, -32(DI)(BX*1)
-	MOVOU	X0, -16(DI)(BX*1)
+	MOVOU	X15, (DI)
+	MOVOU	X15, 16(DI)
+	MOVOU	X15, 32(DI)
+	MOVOU	X15, 48(DI)
+	MOVOU	X15, 64(DI)
+	MOVOU	X15, 80(DI)
+	MOVOU	X15, 96(DI)
+	MOVOU	X15, 112(DI)
+	MOVOU	X15, -128(DI)(BX*1)
+	MOVOU	X15, -112(DI)(BX*1)
+	MOVOU	X15, -96(DI)(BX*1)
+	MOVOU	X15, -80(DI)(BX*1)
+	MOVOU	X15, -64(DI)(BX*1)
+	MOVOU	X15, -48(DI)(BX*1)
+	MOVOU	X15, -32(DI)(BX*1)
+	MOVOU	X15, -16(DI)(BX*1)
 	RET
diff --git a/src/runtime/memclr_arm.s b/src/runtime/memclr_arm.s
index f113a1a..f02d058 100644
--- a/src/runtime/memclr_arm.s
+++ b/src/runtime/memclr_arm.s
@@ -33,6 +33,7 @@
 // See memclrNoHeapPointers Go doc for important implementation constraints.
 
 // func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
+// Also called from assembly in sys_windows_arm.s without g (but using Go stack convention).
 TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-8
 	MOVW	ptr+0(FP), TO
 	MOVW	n+4(FP), N
diff --git a/src/runtime/memclr_arm64.s b/src/runtime/memclr_arm64.s
index bef7765..c1a0dce 100644
--- a/src/runtime/memclr_arm64.s
+++ b/src/runtime/memclr_arm64.s
@@ -7,6 +7,7 @@
 // See memclrNoHeapPointers Go doc for important implementation constraints.
 
 // func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
+// Also called from assembly in sys_windows_arm64.s without g (but using Go stack convention).
 TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16
 	MOVD	ptr+0(FP), R0
 	MOVD	n+8(FP), R1
diff --git a/src/runtime/memclr_mips64x.s b/src/runtime/memclr_mips64x.s
index d7a3251..bc03701 100644
--- a/src/runtime/memclr_mips64x.s
+++ b/src/runtime/memclr_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "go_asm.h"
diff --git a/src/runtime/memclr_mipsx.s b/src/runtime/memclr_mipsx.s
index eb2a8a7..3d21c3c 100644
--- a/src/runtime/memclr_mipsx.s
+++ b/src/runtime/memclr_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "textflag.h"
diff --git a/src/runtime/memclr_ppc64x.s b/src/runtime/memclr_ppc64x.s
index 7512620..6563932 100644
--- a/src/runtime/memclr_ppc64x.s
+++ b/src/runtime/memclr_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "textflag.h"
diff --git a/src/runtime/memmove_386.s b/src/runtime/memmove_386.s
index d99546c..1a43a1f 100644
--- a/src/runtime/memmove_386.s
+++ b/src/runtime/memmove_386.s
@@ -23,6 +23,7 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
+//go:build !plan9
 // +build !plan9
 
 #include "go_asm.h"
diff --git a/src/runtime/memmove_amd64.s b/src/runtime/memmove_amd64.s
index d91641a..24c6529 100644
--- a/src/runtime/memmove_amd64.s
+++ b/src/runtime/memmove_amd64.s
@@ -23,6 +23,7 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
+//go:build !plan9
 // +build !plan9
 
 #include "go_asm.h"
@@ -31,11 +32,20 @@
 // See memmove Go doc for important implementation constraints.
 
 // func memmove(to, from unsafe.Pointer, n uintptr)
-TEXT runtime·memmove(SB), NOSPLIT, $0-24
-
+// ABIInternal for performance.
+TEXT runtime·memmove<ABIInternal>(SB), NOSPLIT, $0-24
+#ifdef GOEXPERIMENT_regabiargs
+	// AX = to
+	// BX = from
+	// CX = n
+	MOVQ	AX, DI
+	MOVQ	BX, SI
+	MOVQ	CX, BX
+#else
 	MOVQ	to+0(FP), DI
 	MOVQ	from+8(FP), SI
 	MOVQ	n+16(FP), BX
+#endif
 
 	// REP instructions have a high startup cost, so we handle small sizes
 	// with some straightline code. The REP MOVSQ instruction is really fast
@@ -244,6 +254,10 @@
 	MOVOU	X13, -48(DI)(BX*1)
 	MOVOU	X14, -32(DI)(BX*1)
 	MOVOU	X15, -16(DI)(BX*1)
+#ifdef GOEXPERIMENT_regabig
+	// X15 must be zero on return
+	PXOR	X15, X15
+#endif
 	RET
 move_256through2048:
 	SUBQ	$256, BX
@@ -283,6 +297,10 @@
 	LEAQ	256(SI), SI
 	LEAQ	256(DI), DI
 	JGE	move_256through2048
+#ifdef GOEXPERIMENT_regabig
+	// X15 must be zero on return
+	PXOR	X15, X15
+#endif
 	JMP	tail
 
 avxUnaligned:
diff --git a/src/runtime/memmove_mips64x.s b/src/runtime/memmove_mips64x.s
index 8a1b88a..fef3c6b 100644
--- a/src/runtime/memmove_mips64x.s
+++ b/src/runtime/memmove_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "textflag.h"
diff --git a/src/runtime/memmove_mipsx.s b/src/runtime/memmove_mipsx.s
index 6c86558..cd02fc2 100644
--- a/src/runtime/memmove_mipsx.s
+++ b/src/runtime/memmove_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "textflag.h"
diff --git a/src/runtime/memmove_ppc64x.s b/src/runtime/memmove_ppc64x.s
index edc6452..fd16ad8 100644
--- a/src/runtime/memmove_ppc64x.s
+++ b/src/runtime/memmove_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "textflag.h"
@@ -157,7 +158,7 @@
 
 backward32setup:
 	MOVD	QWORDS, CTR			// set up loop ctr
-	MOVD	$16, IDX16			// 32 bytes at at time
+	MOVD	$16, IDX16			// 32 bytes at a time
 
 backward32loop:
 	SUB	$32, TGT
diff --git a/src/runtime/metrics.go b/src/runtime/metrics.go
index 3e8dbda..ba0a920 100644
--- a/src/runtime/metrics.go
+++ b/src/runtime/metrics.go
@@ -98,6 +98,20 @@
 				}
 			},
 		},
+		"/gc/heap/allocs:bytes": {
+			deps: makeStatDepSet(heapStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindUint64
+				out.scalar = in.heapStats.totalAllocated
+			},
+		},
+		"/gc/heap/allocs:objects": {
+			deps: makeStatDepSet(heapStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindUint64
+				out.scalar = in.heapStats.totalAllocs
+			},
+		},
 		"/gc/heap/frees-by-size:bytes": {
 			deps: makeStatDepSet(heapStatsDep),
 			compute: func(in *statAggregate, out *metricValue) {
@@ -110,6 +124,20 @@
 				}
 			},
 		},
+		"/gc/heap/frees:bytes": {
+			deps: makeStatDepSet(heapStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindUint64
+				out.scalar = in.heapStats.totalFreed
+			},
+		},
+		"/gc/heap/frees:objects": {
+			deps: makeStatDepSet(heapStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindUint64
+				out.scalar = in.heapStats.totalFrees
+			},
+		},
 		"/gc/heap/goal:bytes": {
 			deps: makeStatDepSet(sysStatsDep),
 			compute: func(in *statAggregate, out *metricValue) {
@@ -124,6 +152,13 @@
 				out.scalar = in.heapStats.numObjects
 			},
 		},
+		"/gc/heap/tiny/allocs:objects": {
+			deps: makeStatDepSet(heapStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindUint64
+				out.scalar = uint64(in.heapStats.tinyAllocCount)
+			},
+		},
 		"/gc/pauses:seconds": {
 			compute: func(_ *statAggregate, out *metricValue) {
 				hist := out.float64HistOrInit(timeHistBuckets)
@@ -245,6 +280,15 @@
 				out.scalar = uint64(gcount())
 			},
 		},
+		"/sched/latencies:seconds": {
+			compute: func(_ *statAggregate, out *metricValue) {
+				hist := out.float64HistOrInit(timeHistBuckets)
+				hist.counts[0] = atomic.Load64(&sched.timeToRun.underflow)
+				for i := range sched.timeToRun.counts {
+					hist.counts[i+1] = atomic.Load64(&sched.timeToRun.counts[i])
+				}
+			},
+		},
 	}
 	metricsInit = true
 }
@@ -321,6 +365,22 @@
 
 	// numObjects is the number of live objects in the heap.
 	numObjects uint64
+
+	// totalAllocated is the total bytes of heap objects allocated
+	// over the lifetime of the program.
+	totalAllocated uint64
+
+	// totalFreed is the total bytes of heap objects freed
+	// over the lifetime of the program.
+	totalFreed uint64
+
+	// totalAllocs is the number of heap objects allocated over
+	// the lifetime of the program.
+	totalAllocs uint64
+
+	// totalFrees is the number of heap objects freed over
+	// the lifetime of the program.
+	totalFrees uint64
 }
 
 // compute populates the heapStatsAggregate with values from the runtime.
@@ -328,13 +388,20 @@
 	memstats.heapStats.read(&a.heapStatsDelta)
 
 	// Calculate derived stats.
-	a.inObjects = uint64(a.largeAlloc - a.largeFree)
-	a.numObjects = uint64(a.largeAllocCount - a.largeFreeCount)
+	a.totalAllocs = uint64(a.largeAllocCount)
+	a.totalFrees = uint64(a.largeFreeCount)
+	a.totalAllocated = uint64(a.largeAlloc)
+	a.totalFreed = uint64(a.largeFree)
 	for i := range a.smallAllocCount {
-		n := uint64(a.smallAllocCount[i] - a.smallFreeCount[i])
-		a.inObjects += n * uint64(class_to_size[i])
-		a.numObjects += n
+		na := uint64(a.smallAllocCount[i])
+		nf := uint64(a.smallFreeCount[i])
+		a.totalAllocs += na
+		a.totalFrees += nf
+		a.totalAllocated += na * uint64(class_to_size[i])
+		a.totalFreed += nf * uint64(class_to_size[i])
 	}
+	a.inObjects = a.totalAllocated - a.totalFreed
+	a.numObjects = a.totalAllocs - a.totalFrees
 }
 
 // sysStatsAggregate represents system memory stats obtained
@@ -364,7 +431,7 @@
 	a.buckHashSys = memstats.buckhash_sys.load()
 	a.gcMiscSys = memstats.gcMiscSys.load()
 	a.otherSys = memstats.other_sys.load()
-	a.heapGoal = atomic.Load64(&memstats.next_gc)
+	a.heapGoal = atomic.Load64(&gcController.heapGoal)
 	a.gcCyclesDone = uint64(memstats.numgc)
 	a.gcCyclesForced = uint64(memstats.numforcedgc)
 
@@ -481,7 +548,7 @@
 
 	// Acquire the metricsSema but with handoff. This operation
 	// is expensive enough that queueing up goroutines and handing
-	// off between them will be noticably better-behaved.
+	// off between them will be noticeably better-behaved.
 	semacquire1(&metricsSema, true, 0, 0)
 
 	// Ensure the map is initialized.
diff --git a/src/runtime/metrics/description.go b/src/runtime/metrics/description.go
index 1175156..c147cad 100644
--- a/src/runtime/metrics/description.go
+++ b/src/runtime/metrics/description.go
@@ -70,18 +70,51 @@
 		Cumulative:  true,
 	},
 	{
-		Name:        "/gc/heap/allocs-by-size:bytes",
-		Description: "Distribution of all objects allocated by approximate size.",
-		Kind:        KindFloat64Histogram,
+		Name: "/gc/heap/allocs-by-size:bytes",
+		Description: "Distribution of heap allocations by approximate size. " +
+			"Note that this does not include tiny objects as defined by " +
+			"/gc/heap/tiny/allocs:objects, only tiny blocks.",
+		Kind:       KindFloat64Histogram,
+		Cumulative: true,
+	},
+	{
+		Name:        "/gc/heap/allocs:bytes",
+		Description: "Cumulative sum of memory allocated to the heap by the application.",
+		Kind:        KindUint64,
 		Cumulative:  true,
 	},
 	{
-		Name:        "/gc/heap/frees-by-size:bytes",
-		Description: "Distribution of all objects freed by approximate size.",
-		Kind:        KindFloat64Histogram,
+		Name: "/gc/heap/allocs:objects",
+		Description: "Cumulative count of heap allocations triggered by the application. " +
+			"Note that this does not include tiny objects as defined by " +
+			"/gc/heap/tiny/allocs:objects, only tiny blocks.",
+		Kind:       KindUint64,
+		Cumulative: true,
+	},
+	{
+		Name: "/gc/heap/frees-by-size:bytes",
+		Description: "Distribution of freed heap allocations by approximate size. " +
+			"Note that this does not include tiny objects as defined by " +
+			"/gc/heap/tiny/allocs:objects, only tiny blocks.",
+		Kind:       KindFloat64Histogram,
+		Cumulative: true,
+	},
+	{
+		Name:        "/gc/heap/frees:bytes",
+		Description: "Cumulative sum of heap memory freed by the garbage collector.",
+		Kind:        KindUint64,
 		Cumulative:  true,
 	},
 	{
+		Name: "/gc/heap/frees:objects",
+		Description: "Cumulative count of heap allocations whose storage was freed " +
+			"by the garbage collector. " +
+			"Note that this does not include tiny objects as defined by " +
+			"/gc/heap/tiny/allocs:objects, only tiny blocks.",
+		Kind:       KindUint64,
+		Cumulative: true,
+	},
+	{
 		Name:        "/gc/heap/goal:bytes",
 		Description: "Heap size target for the end of the GC cycle.",
 		Kind:        KindUint64,
@@ -92,6 +125,16 @@
 		Kind:        KindUint64,
 	},
 	{
+		Name: "/gc/heap/tiny/allocs:objects",
+		Description: "Count of small allocations that are packed together into blocks. " +
+			"These allocations are counted separately from other allocations " +
+			"because each individual allocation is not tracked by the runtime, " +
+			"only their block. Each block is already accounted for in " +
+			"allocs-by-size and frees-by-size.",
+		Kind:       KindUint64,
+		Cumulative: true,
+	},
+	{
 		Name:        "/gc/pauses:seconds",
 		Description: "Distribution individual GC-related stop-the-world pause latencies.",
 		Kind:        KindFloat64Histogram,
@@ -176,6 +219,11 @@
 		Description: "Count of live goroutines.",
 		Kind:        KindUint64,
 	},
+	{
+		Name:        "/sched/latencies:seconds",
+		Description: "Distribution of the time goroutines have spent in the scheduler in a runnable state before actually running.",
+		Kind:        KindFloat64Histogram,
+	},
 }
 
 // All returns a slice of containing metric descriptions for all supported metrics.
diff --git a/src/runtime/metrics/doc.go b/src/runtime/metrics/doc.go
index 7f790af..91ef030 100644
--- a/src/runtime/metrics/doc.go
+++ b/src/runtime/metrics/doc.go
@@ -61,10 +61,30 @@
 		Count of all completed GC cycles.
 
 	/gc/heap/allocs-by-size:bytes
-		Distribution of all objects allocated by approximate size.
+		Distribution of heap allocations by approximate size.
+		Note that this does not include tiny objects as defined by /gc/heap/tiny/allocs:objects,
+		only tiny blocks.
+
+	/gc/heap/allocs:bytes
+		Cumulative sum of memory allocated to the heap by the application.
+
+	/gc/heap/allocs:objects
+		Cumulative count of heap allocations triggered by the application.
+		Note that this does not include tiny objects as defined by /gc/heap/tiny/allocs:objects,
+		only tiny blocks.
 
 	/gc/heap/frees-by-size:bytes
-		Distribution of all objects freed by approximate size.
+		Distribution of freed heap allocations by approximate size.
+		Note that this does not include tiny objects as defined by /gc/heap/tiny/allocs:objects,
+		only tiny blocks.
+
+	/gc/heap/frees:bytes
+		Cumulative sum of heap memory freed by the garbage collector.
+
+	/gc/heap/frees:objects
+		Cumulative count of heap allocations whose storage was freed by the garbage collector.
+		Note that this does not include tiny objects as defined by /gc/heap/tiny/allocs:objects,
+		only tiny blocks.
 
 	/gc/heap/goal:bytes
 		Heap size target for the end of the GC cycle.
@@ -72,6 +92,13 @@
 	/gc/heap/objects:objects
 		Number of objects, live or unswept, occupying heap memory.
 
+	/gc/heap/tiny/allocs:objects
+		Count of small allocations that are packed together into blocks.
+		These allocations are counted separately from other allocations
+		because each individual allocation is not tracked by the runtime,
+		only their block. Each block is already accounted for in
+		allocs-by-size and frees-by-size.
+
 	/gc/pauses:seconds
 		Distribution individual GC-related stop-the-world pause latencies.
 
@@ -139,5 +166,9 @@
 
 	/sched/goroutines:goroutines
 		Count of live goroutines.
+
+	/sched/latencies:seconds
+		Distribution of the time goroutines have spent in the scheduler
+		in a runnable state before actually running.
 */
 package metrics
diff --git a/src/runtime/metrics_test.go b/src/runtime/metrics_test.go
index 8a3cf01..5d32ef4 100644
--- a/src/runtime/metrics_test.go
+++ b/src/runtime/metrics_test.go
@@ -40,6 +40,9 @@
 	}
 
 	// Check to make sure the values we read line up with other values we read.
+	var allocsBySize *metrics.Float64Histogram
+	var tinyAllocs uint64
+	var mallocs, frees uint64
 	for i := range samples {
 		switch name := samples[i].Name; name {
 		case "/memory/classes/heap/free:bytes":
@@ -84,6 +87,9 @@
 					t.Errorf("histogram counts do not much BySize for class %d: got %d, want %d", i, c, m)
 				}
 			}
+			allocsBySize = hist
+		case "/gc/heap/allocs:bytes":
+			checkUint64(t, name, samples[i].Value.Uint64(), mstats.TotalAlloc)
 		case "/gc/heap/frees-by-size:bytes":
 			hist := samples[i].Value.Float64Histogram()
 			// Skip size class 0 in BySize, because it's always empty and not represented
@@ -95,9 +101,29 @@
 					continue
 				}
 				if c, f := hist.Counts[i], sc.Frees; c != f {
-					t.Errorf("histogram counts do not much BySize for class %d: got %d, want %d", i, c, f)
+					t.Errorf("histogram counts do not match BySize for class %d: got %d, want %d", i, c, f)
 				}
 			}
+		case "/gc/heap/frees:bytes":
+			checkUint64(t, name, samples[i].Value.Uint64(), mstats.TotalAlloc-mstats.HeapAlloc)
+		case "/gc/heap/tiny/allocs:objects":
+			// Currently, MemStats adds tiny alloc count to both Mallocs AND Frees.
+			// The reason for this is because MemStats couldn't be extended at the time
+			// but there was a desire to have Mallocs at least be a little more representative,
+			// while having Mallocs - Frees still represent a live object count.
+			// Unfortunately, MemStats doesn't actually export a large allocation count,
+			// so it's impossible to pull this number out directly.
+			//
+			// Check tiny allocation count outside of this loop, by using the allocs-by-size
+			// histogram in order to figure out how many large objects there are.
+			tinyAllocs = samples[i].Value.Uint64()
+			// Because the next two metrics tests are checking against Mallocs and Frees,
+			// we can't check them directly for the same reason: we need to account for tiny
+			// allocations included in Mallocs and Frees.
+		case "/gc/heap/allocs:objects":
+			mallocs = samples[i].Value.Uint64()
+		case "/gc/heap/frees:objects":
+			frees = samples[i].Value.Uint64()
 		case "/gc/heap/objects:objects":
 			checkUint64(t, name, samples[i].Value.Uint64(), mstats.HeapObjects)
 		case "/gc/heap/goal:bytes":
@@ -110,6 +136,17 @@
 			checkUint64(t, name, samples[i].Value.Uint64(), uint64(mstats.NumGC))
 		}
 	}
+
+	// Check tinyAllocs.
+	nonTinyAllocs := uint64(0)
+	for _, c := range allocsBySize.Counts {
+		nonTinyAllocs += c
+	}
+	checkUint64(t, "/gc/heap/tiny/allocs:objects", tinyAllocs, mstats.Mallocs-nonTinyAllocs)
+
+	// Check allocation and free counts.
+	checkUint64(t, "/gc/heap/allocs:objects", mallocs, mstats.Mallocs-tinyAllocs)
+	checkUint64(t, "/gc/heap/frees:objects", frees, mstats.Frees-tinyAllocs)
 }
 
 func TestReadMetricsConsistency(t *testing.T) {
@@ -132,8 +169,10 @@
 		got, want uint64
 	}
 	var objects struct {
-		alloc, free *metrics.Float64Histogram
-		total       uint64
+		alloc, free             *metrics.Float64Histogram
+		allocs, frees           uint64
+		allocdBytes, freedBytes uint64
+		total, totalBytes       uint64
 	}
 	var gc struct {
 		numGC  uint64
@@ -159,10 +198,20 @@
 		switch samples[i].Name {
 		case "/memory/classes/total:bytes":
 			totalVirtual.got = samples[i].Value.Uint64()
+		case "/memory/classes/heap/objects:bytes":
+			objects.totalBytes = samples[i].Value.Uint64()
 		case "/gc/heap/objects:objects":
 			objects.total = samples[i].Value.Uint64()
+		case "/gc/heap/allocs:bytes":
+			objects.allocdBytes = samples[i].Value.Uint64()
+		case "/gc/heap/allocs:objects":
+			objects.allocs = samples[i].Value.Uint64()
 		case "/gc/heap/allocs-by-size:bytes":
 			objects.alloc = samples[i].Value.Float64Histogram()
+		case "/gc/heap/frees:bytes":
+			objects.freedBytes = samples[i].Value.Uint64()
+		case "/gc/heap/frees:objects":
+			objects.frees = samples[i].Value.Uint64()
 		case "/gc/heap/frees-by-size:bytes":
 			objects.free = samples[i].Value.Float64Histogram()
 		case "/gc/cycles:gc-cycles":
@@ -182,6 +231,12 @@
 	if totalVirtual.got != totalVirtual.want {
 		t.Errorf(`"/memory/classes/total:bytes" does not match sum of /memory/classes/**: got %d, want %d`, totalVirtual.got, totalVirtual.want)
 	}
+	if got, want := objects.allocs-objects.frees, objects.total; got != want {
+		t.Errorf("mismatch between object alloc/free tallies and total: got %d, want %d", got, want)
+	}
+	if got, want := objects.allocdBytes-objects.freedBytes, objects.totalBytes; got != want {
+		t.Errorf("mismatch between object alloc/free tallies and total: got %d, want %d", got, want)
+	}
 	if b, c := len(objects.alloc.Buckets), len(objects.alloc.Counts); b != c+1 {
 		t.Errorf("allocs-by-size has wrong bucket or counts length: %d buckets, %d counts", b, c)
 	}
@@ -201,17 +256,25 @@
 			}
 		}
 		if !t.Failed() {
-			got, want := uint64(0), objects.total
+			var gotAlloc, gotFree uint64
+			want := objects.total
 			for i := range objects.alloc.Counts {
 				if objects.alloc.Counts[i] < objects.free.Counts[i] {
 					t.Errorf("found more allocs than frees in object dist bucket %d", i)
 					continue
 				}
-				got += objects.alloc.Counts[i] - objects.free.Counts[i]
+				gotAlloc += objects.alloc.Counts[i]
+				gotFree += objects.free.Counts[i]
 			}
-			if got != want {
+			if got := gotAlloc - gotFree; got != want {
 				t.Errorf("object distribution counts don't match count of live objects: got %d, want %d", got, want)
 			}
+			if gotAlloc != objects.allocs {
+				t.Errorf("object distribution counts don't match total allocs: got %d, want %d", gotAlloc, objects.allocs)
+			}
+			if gotFree != objects.frees {
+				t.Errorf("object distribution counts don't match total allocs: got %d, want %d", gotFree, objects.frees)
+			}
 		}
 	}
 	// The current GC has at least 2 pauses per GC.
diff --git a/src/runtime/mfinal.go b/src/runtime/mfinal.go
index f4dbd77..c134a0f 100644
--- a/src/runtime/mfinal.go
+++ b/src/runtime/mfinal.go
@@ -7,6 +7,7 @@
 package runtime
 
 import (
+	"internal/abi"
 	"runtime/internal/atomic"
 	"runtime/internal/sys"
 	"unsafe"
@@ -162,6 +163,7 @@
 	var (
 		frame    unsafe.Pointer
 		framecap uintptr
+		argRegs  int
 	)
 
 	for {
@@ -175,6 +177,7 @@
 			goparkunlock(&finlock, waitReasonFinalizerWait, traceEvGoBlock, 1)
 			continue
 		}
+		argRegs = intArgRegs
 		unlock(&finlock)
 		if raceenabled {
 			racefingo()
@@ -183,7 +186,22 @@
 			for i := fb.cnt; i > 0; i-- {
 				f := &fb.fin[i-1]
 
-				framesz := unsafe.Sizeof((interface{})(nil)) + f.nret
+				var regs abi.RegArgs
+				var framesz uintptr
+				if argRegs > 0 {
+					// The args can always be passed in registers if they're
+					// available, because platforms we support always have no
+					// argument registers available, or more than 2.
+					//
+					// But unfortunately because we can have an arbitrary
+					// amount of returns and it would be complex to try and
+					// figure out how many of those can get passed in registers,
+					// just conservatively assume none of them do.
+					framesz = f.nret
+				} else {
+					// Need to pass arguments on the stack too.
+					framesz = unsafe.Sizeof((interface{})(nil)) + f.nret
+				}
 				if framecap < framesz {
 					// The frame does not contain pointers interesting for GC,
 					// all not yet finalized objects are stored in finq.
@@ -196,30 +214,35 @@
 				if f.fint == nil {
 					throw("missing type in runfinq")
 				}
-				// frame is effectively uninitialized
-				// memory. That means we have to clear
-				// it before writing to it to avoid
-				// confusing the write barrier.
-				*(*[2]uintptr)(frame) = [2]uintptr{}
+				r := frame
+				if argRegs > 0 {
+					r = unsafe.Pointer(&regs.Ints)
+				} else {
+					// frame is effectively uninitialized
+					// memory. That means we have to clear
+					// it before writing to it to avoid
+					// confusing the write barrier.
+					*(*[2]uintptr)(frame) = [2]uintptr{}
+				}
 				switch f.fint.kind & kindMask {
 				case kindPtr:
 					// direct use of pointer
-					*(*unsafe.Pointer)(frame) = f.arg
+					*(*unsafe.Pointer)(r) = f.arg
 				case kindInterface:
 					ityp := (*interfacetype)(unsafe.Pointer(f.fint))
 					// set up with empty interface
-					(*eface)(frame)._type = &f.ot.typ
-					(*eface)(frame).data = f.arg
+					(*eface)(r)._type = &f.ot.typ
+					(*eface)(r).data = f.arg
 					if len(ityp.mhdr) != 0 {
 						// convert to interface with methods
 						// this conversion is guaranteed to succeed - we checked in SetFinalizer
-						*(*iface)(frame) = assertE2I(ityp, *(*eface)(frame))
+						(*iface)(r).tab = assertE2I(ityp, (*eface)(r)._type)
 					}
 				default:
 					throw("bad kind in runfinq")
 				}
 				fingRunning = true
-				reflectcall(nil, unsafe.Pointer(f.fn), frame, uint32(framesz), uint32(framesz))
+				reflectcall(nil, unsafe.Pointer(f.fn), frame, uint32(framesz), uint32(framesz), uint32(framesz), &regs)
 				fingRunning = false
 
 				// Drop finalizer queue heap references
@@ -398,7 +421,7 @@
 			// ok - satisfies empty interface
 			goto okarg
 		}
-		if _, ok := assertE2I2(ityp, *efaceOf(&obj)); ok {
+		if iface := assertE2I2(ityp, *efaceOf(&obj)); iface.tab != nil {
 			goto okarg
 		}
 	}
@@ -443,6 +466,10 @@
 // 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.
+//
+// Note: KeepAlive should only be used to prevent finalizers from
+// running prematurely. In particular, when used with unsafe.Pointer,
+// the rules for valid uses of unsafe.Pointer still apply.
 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
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 185d320..4585663 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -113,8 +113,8 @@
 // Next GC is after we've allocated an extra amount of memory proportional to
 // the amount already in use. The proportion is controlled by GOGC environment variable
 // (100 by default). If GOGC=100 and we're using 4M, we'll GC again when we get to 8M
-// (this mark is tracked in next_gc variable). This keeps the GC cost in linear
-// proportion to the allocation cost. Adjusting GOGC just changes the linear constant
+// (this mark is tracked in gcController.heapGoal variable). This keeps the GC cost in
+// linear proportion to the allocation cost. Adjusting GOGC just changes the linear constant
 // (and also the amount of extra memory used).
 
 // Oblets
@@ -149,45 +149,16 @@
 	sweepMinHeapDistance = 1024 * 1024
 )
 
-// heapminimum is the minimum heap size at which to trigger GC.
-// For small heaps, this overrides the usual GOGC*live set rule.
-//
-// When there is a very small live set but a lot of allocation, simply
-// collecting when the heap reaches GOGC*live results in many GC
-// cycles and high total per-GC overhead. This minimum amortizes this
-// per-GC overhead while keeping the heap reasonably small.
-//
-// During initialization this is set to 4MB*GOGC/100. In the case of
-// GOGC==0, this will set heapminimum to 0, resulting in constant
-// collection even when the heap size is small, which is useful for
-// debugging.
-var heapminimum uint64 = defaultHeapMinimum
-
-// defaultHeapMinimum is the value of heapminimum for GOGC==100.
-const defaultHeapMinimum = 4 << 20
-
-// Initialized from $GOGC.  GOGC=off means no GC.
-var gcpercent int32
-
 func gcinit() {
 	if unsafe.Sizeof(workbuf{}) != _WorkbufSize {
 		throw("size of Workbuf is suboptimal")
 	}
-
 	// No sweep on the first cycle.
-	mheap_.sweepdone = 1
+	mheap_.sweepDrained = 1
 
-	// Set a reasonable initial GC trigger.
-	memstats.triggerRatio = 7 / 8.0
-
-	// Fake a heap_marked value so it looks like a trigger at
-	// heapminimum is the appropriate growth from heap_marked.
-	// This will go into computing the initial GC goal.
-	memstats.heap_marked = uint64(float64(heapminimum) / (1 + memstats.triggerRatio))
-
-	// Set gcpercent from the environment. This will also compute
-	// and set the GC trigger and goal.
-	_ = setGCPercent(readgogc())
+	// Initialize GC pacer state.
+	// Use the environment variable GOGC for the initial gcPercent value.
+	gcController.init(readGOGC())
 
 	work.startSema = 1
 	work.markDoneSema = 1
@@ -196,16 +167,9 @@
 	lockInit(&work.wbufSpans.lock, lockRankWbufSpans)
 }
 
-func readgogc() int32 {
-	p := gogetenv("GOGC")
-	if p == "off" {
-		return -1
-	}
-	if n, ok := atoi32(p); ok {
-		return n
-	}
-	return 100
-}
+// Temporary in order to enable register ABI work.
+// TODO(register args): convert back to local chan in gcenabled, passed to "go" stmts.
+var gcenable_setup chan int
 
 // gcenable is called after the bulk of the runtime initialization,
 // just before we're about to start letting user code run.
@@ -213,39 +177,15 @@
 // scavenger goroutine, and enables GC.
 func gcenable() {
 	// Kick off sweeping and scavenging.
-	c := make(chan int, 2)
-	go bgsweep(c)
-	go bgscavenge(c)
-	<-c
-	<-c
+	gcenable_setup = make(chan int, 2)
+	go bgsweep()
+	go bgscavenge()
+	<-gcenable_setup
+	<-gcenable_setup
+	gcenable_setup = nil
 	memstats.enablegc = true // now that runtime is initialized, GC is okay
 }
 
-//go:linkname setGCPercent runtime/debug.setGCPercent
-func setGCPercent(in int32) (out int32) {
-	// Run on the system stack since we grab the heap lock.
-	systemstack(func() {
-		lock(&mheap_.lock)
-		out = gcpercent
-		if in < 0 {
-			in = -1
-		}
-		gcpercent = in
-		heapminimum = defaultHeapMinimum * uint64(gcpercent) / 100
-		// Update pacing in response to gcpercent change.
-		gcSetTriggerRatio(memstats.triggerRatio)
-		unlock(&mheap_.lock)
-	})
-
-	// If we just disabled GC, wait for any concurrent GC mark to
-	// finish so we always return with no GC running.
-	if in < 0 {
-		gcWaitOnMark(atomic.Load(&work.cycles))
-	}
-
-	return out
-}
-
 // Garbage collector phase.
 // Indicates to write barrier and synchronization task to perform.
 var gcphase uint32
@@ -302,9 +242,11 @@
 	// gcMarkWorkerFractionalMode indicates that a P is currently
 	// running the "fractional" mark worker. The fractional worker
 	// 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*gcBackgroundUtilization.
+	// an integer and using only dedicated workers would result in
+	// utilization too far from the target of gcBackgroundUtilization.
+	// The fractional worker should run until it is preempted and
+	// will be scheduled to pick up the fractional part of
+	// GOMAXPROCS*gcBackgroundUtilization.
 	gcMarkWorkerFractionalMode
 
 	// gcMarkWorkerIdleMode indicates that a P is running the mark
@@ -323,474 +265,6 @@
 	"GC (idle)",
 }
 
-// gcController implements the GC pacing controller that determines
-// when to trigger concurrent garbage collection and how much marking
-// work to do in mutator assists and background marking.
-//
-// It uses a feedback control algorithm to adjust the memstats.gc_trigger
-// trigger based on the heap growth and GC CPU utilization each cycle.
-// This algorithm optimizes for heap growth to match GOGC and for CPU
-// utilization between assist and background marking to be 25% of
-// GOMAXPROCS. The high-level design of this algorithm is documented
-// at https://golang.org/s/go15gcpacing.
-//
-// All fields of gcController are used only during a single mark
-// cycle.
-var gcController gcControllerState
-
-type gcControllerState struct {
-	// scanWork is the total scan work performed this cycle. This
-	// is updated atomically during the cycle. Updates occur in
-	// bounded batches, since it is both written and read
-	// throughout the cycle. At the end of the cycle, this is how
-	// much of the retained heap is scannable.
-	//
-	// Currently this is the bytes of heap scanned. For most uses,
-	// this is an opaque unit of work, but for estimation the
-	// definition is important.
-	scanWork int64
-
-	// bgScanCredit is the scan work credit accumulated by the
-	// concurrent background scan. This credit is accumulated by
-	// the background scan and stolen by mutator assists. This is
-	// updated atomically. Updates occur in bounded batches, since
-	// it is both written and read throughout the cycle.
-	bgScanCredit int64
-
-	// assistTime is the nanoseconds spent in mutator assists
-	// during this cycle. This is updated atomically. Updates
-	// occur in bounded batches, since it is both written and read
-	// throughout the cycle.
-	assistTime int64
-
-	// dedicatedMarkTime is the nanoseconds spent in dedicated
-	// mark workers during this cycle. This is updated atomically
-	// at the end of the concurrent mark phase.
-	dedicatedMarkTime int64
-
-	// fractionalMarkTime is the nanoseconds spent in the
-	// fractional mark worker during this cycle. This is updated
-	// atomically throughout the cycle and will be up-to-date if
-	// the fractional mark worker is not currently running.
-	fractionalMarkTime int64
-
-	// idleMarkTime is the nanoseconds spent in idle marking
-	// during this cycle. This is updated atomically throughout
-	// the cycle.
-	idleMarkTime int64
-
-	// markStartTime is the absolute start time in nanoseconds
-	// that assists and background mark workers started.
-	markStartTime int64
-
-	// dedicatedMarkWorkersNeeded is the number of dedicated mark
-	// workers that need to be started. This is computed at the
-	// beginning of each cycle and decremented atomically as
-	// dedicated mark workers get started.
-	dedicatedMarkWorkersNeeded int64
-
-	// assistWorkPerByte is the ratio of scan work to allocated
-	// bytes that should be performed by mutator assists. This is
-	// computed at the beginning of each cycle and updated every
-	// time heap_scan is updated.
-	//
-	// Stored as a uint64, but it's actually a float64. Use
-	// float64frombits to get the value.
-	//
-	// Read and written atomically.
-	assistWorkPerByte uint64
-
-	// assistBytesPerWork is 1/assistWorkPerByte.
-	//
-	// Stored as a uint64, but it's actually a float64. Use
-	// float64frombits to get the value.
-	//
-	// Read and written atomically.
-	//
-	// Note that because this is read and written independently
-	// from assistWorkPerByte users may notice a skew between
-	// the two values, and such a state should be safe.
-	assistBytesPerWork uint64
-
-	// fractionalUtilizationGoal is the fraction of wall clock
-	// 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 the 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
-
-	_ cpu.CacheLinePad
-}
-
-// startCycle resets the GC controller's state and computes estimates
-// for a new GC cycle. The caller must hold worldsema and the world
-// must be stopped.
-func (c *gcControllerState) startCycle() {
-	c.scanWork = 0
-	c.bgScanCredit = 0
-	c.assistTime = 0
-	c.dedicatedMarkTime = 0
-	c.fractionalMarkTime = 0
-	c.idleMarkTime = 0
-
-	// Ensure that the heap goal is at least a little larger than
-	// the current live heap size. This may not be the case if GC
-	// start is delayed or if the allocation that pushed heap_live
-	// over gc_trigger is large or if the trigger is really close to
-	// GOGC. Assist is proportional to this distance, so enforce a
-	// minimum distance, even if it means going over the GOGC goal
-	// by a tiny bit.
-	if memstats.next_gc < memstats.heap_live+1024*1024 {
-		memstats.next_gc = memstats.heap_live + 1024*1024
-	}
-
-	// 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.fractionalUtilizationGoal = 0
-	}
-
-	// In STW mode, we just want dedicated workers.
-	if debug.gcstoptheworld > 0 {
-		c.dedicatedMarkWorkersNeeded = int64(gomaxprocs)
-		c.fractionalUtilizationGoal = 0
-	}
-
-	// Clear per-P state
-	for _, p := range allp {
-		p.gcAssistTime = 0
-		p.gcFractionalMarkTime = 0
-	}
-
-	// Compute initial values for controls that are updated
-	// throughout the cycle.
-	c.revise()
-
-	if debug.gcpacertrace > 0 {
-		assistRatio := float64frombits(atomic.Load64(&c.assistWorkPerByte))
-		print("pacer: assist ratio=", assistRatio,
-			" (scan ", memstats.heap_scan>>20, " MB in ",
-			work.initialHeapLive>>20, "->",
-			memstats.next_gc>>20, " MB)",
-			" workers=", c.dedicatedMarkWorkersNeeded,
-			"+", c.fractionalUtilizationGoal, "\n")
-	}
-}
-
-// revise updates the assist ratio during the GC cycle to account for
-// improved estimates. This should be called whenever memstats.heap_scan,
-// memstats.heap_live, or memstats.next_gc is updated. It is safe to
-// call concurrently, but it may race with other calls to revise.
-//
-// The result of this race is that the two assist ratio values may not line
-// up or may be stale. In practice this is OK because the assist ratio
-// moves slowly throughout a GC cycle, and the assist ratio is a best-effort
-// heuristic anyway. Furthermore, no part of the heuristic depends on
-// the two assist ratio values being exact reciprocals of one another, since
-// the two values are used to convert values from different sources.
-//
-// The worst case result of this raciness is that we may miss a larger shift
-// in the ratio (say, if we decide to pace more aggressively against the
-// hard heap goal) but even this "hard goal" is best-effort (see #40460).
-// The dedicated GC should ensure we don't exceed the hard goal by too much
-// in the rare case we do exceed it.
-//
-// It should only be called when gcBlackenEnabled != 0 (because this
-// is when assists are enabled and the necessary statistics are
-// available).
-func (c *gcControllerState) revise() {
-	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)
-	scan := atomic.Load64(&memstats.heap_scan)
-	work := atomic.Loadint64(&c.scanWork)
-
-	// Assume we're under the soft goal. Pace GC to complete at
-	// next_gc assuming the heap is in steady-state.
-	heapGoal := int64(atomic.Load64(&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(scan) * 100 / float64(100+gcpercent))
-
-	if int64(live) > heapGoal || work > scanWorkExpected {
-		// We're past the soft goal, or we've already done more scan
-		// work than we expected. Pace GC so that in the worst case it
-		// will complete by the hard goal.
-		const maxOvershoot = 1.1
-		heapGoal = int64(float64(heapGoal) * maxOvershoot)
-
-		// Compute the upper bound on the scan work remaining.
-		scanWorkExpected = int64(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 allocation will change this difference
-	// slowly in the soft regime and not at all in the hard
-	// regime.
-	scanWorkRemaining := scanWorkExpected - work
-	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 remaining scan work
-		// negative, even in the hard goal regime.
-		scanWorkRemaining = 1000
-	}
-
-	// Compute the heap distance remaining.
-	heapRemaining := heapGoal - int64(live)
-	if heapRemaining <= 0 {
-		// This shouldn't happen, but if it does, avoid
-		// dividing by zero or setting the assist negative.
-		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.
-	// Note that the assist ratio values are updated atomically
-	// but not together. This means there may be some degree of
-	// skew between the two values. This is generally OK as the
-	// values shift relatively slowly over the course of a GC
-	// cycle.
-	assistWorkPerByte := float64(scanWorkRemaining) / float64(heapRemaining)
-	assistBytesPerWork := float64(heapRemaining) / float64(scanWorkRemaining)
-	atomic.Store64(&c.assistWorkPerByte, float64bits(assistWorkPerByte))
-	atomic.Store64(&c.assistBytesPerWork, float64bits(assistBytesPerWork))
-}
-
-// endCycle computes the trigger ratio for the next cycle.
-func (c *gcControllerState) endCycle() float64 {
-	if work.userForced {
-		// Forced GC means this cycle didn't start at the
-		// trigger, so where it finished isn't good
-		// information about how to adjust the trigger.
-		// Just leave it where it is.
-		return memstats.triggerRatio
-	}
-
-	// Proportional response gain for the trigger controller. Must
-	// be in [0, 1]. Lower values smooth out transient effects but
-	// take longer to respond to phase changes. Higher values
-	// react to phase changes quickly, but are more affected by
-	// transient changes. Values near 1 may be unstable.
-	const triggerGain = 0.5
-
-	// Compute next cycle trigger ratio. First, this computes the
-	// "error" for this cycle; that is, how far off the trigger
-	// was from what it should have been, accounting for both heap
-	// growth and GC CPU utilization. We compute the actual heap
-	// growth during this cycle and scale that by how far off from
-	// the goal CPU utilization we were (to estimate the heap
-	// growth if we had the desired CPU utilization). The
-	// difference between this estimate and the GOGC-based goal
-	// heap growth is the error.
-	goalGrowthRatio := gcEffectiveGrowthRatio()
-	actualGrowthRatio := float64(memstats.heap_live)/float64(memstats.heap_marked) - 1
-	assistDuration := nanotime() - c.markStartTime
-
-	// Assume background mark hit its utilization goal.
-	utilization := gcBackgroundUtilization
-	// Add assist utilization; avoid divide by zero.
-	if assistDuration > 0 {
-		utilization += float64(c.assistTime) / float64(assistDuration*int64(gomaxprocs))
-	}
-
-	triggerError := goalGrowthRatio - memstats.triggerRatio - utilization/gcGoalUtilization*(actualGrowthRatio-memstats.triggerRatio)
-
-	// Finally, we adjust the trigger for next time by this error,
-	// damped by the proportional gain.
-	triggerRatio := memstats.triggerRatio + triggerGain*triggerError
-
-	if debug.gcpacertrace > 0 {
-		// Print controller state in terms of the design
-		// document.
-		H_m_prev := memstats.heap_marked
-		h_t := memstats.triggerRatio
-		H_T := memstats.gc_trigger
-		h_a := actualGrowthRatio
-		H_a := memstats.heap_live
-		h_g := goalGrowthRatio
-		H_g := int64(float64(H_m_prev) * (1 + h_g))
-		u_a := utilization
-		u_g := gcGoalUtilization
-		W_a := c.scanWork
-		print("pacer: H_m_prev=", H_m_prev,
-			" h_t=", h_t, " H_T=", H_T,
-			" h_a=", h_a, " H_a=", H_a,
-			" h_g=", h_g, " H_g=", H_g,
-			" u_a=", u_a, " u_g=", u_g,
-			" W_a=", W_a,
-			" goalΔ=", goalGrowthRatio-h_t,
-			" actualΔ=", h_a-h_t,
-			" u_a/u_g=", u_a/u_g,
-			"\n")
-	}
-
-	return triggerRatio
-}
-
-// enlistWorker encourages another dedicated mark worker to start on
-// another P if there are spare worker slots. It is used by putfull
-// when more work is made available.
-//
-//go:nowritebarrier
-func (c *gcControllerState) enlistWorker() {
-	// If there are idle Ps, wake one so it will run an idle worker.
-	// NOTE: This is suspected of causing deadlocks. See golang.org/issue/19112.
-	//
-	//	if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 {
-	//		wakep()
-	//		return
-	//	}
-
-	// There are no idle Ps. If we need more dedicated workers,
-	// try to preempt a running P so it will switch to a worker.
-	if c.dedicatedMarkWorkersNeeded <= 0 {
-		return
-	}
-	// Pick a random other P to preempt.
-	if gomaxprocs <= 1 {
-		return
-	}
-	gp := getg()
-	if gp == nil || gp.m == nil || gp.m.p == 0 {
-		return
-	}
-	myID := gp.m.p.ptr().id
-	for tries := 0; tries < 5; tries++ {
-		id := int32(fastrandn(uint32(gomaxprocs - 1)))
-		if id >= myID {
-			id++
-		}
-		p := allp[id]
-		if p.status != _Prunning {
-			continue
-		}
-		if preemptone(p) {
-			return
-		}
-	}
-}
-
-// findRunnableGCWorker returns a background mark worker for _p_ if it
-// should be run. This must only be called when gcBlackenEnabled != 0.
-func (c *gcControllerState) findRunnableGCWorker(_p_ *p) *g {
-	if gcBlackenEnabled == 0 {
-		throw("gcControllerState.findRunnable: blackening not enabled")
-	}
-
-	if !gcMarkWorkAvailable(_p_) {
-		// No work to be done right now. This can happen at
-		// the end of the mark phase when there are still
-		// assists tapering off. Don't bother running a worker
-		// now because it'll just return immediately.
-		return nil
-	}
-
-	// Grab a worker before we commit to running below.
-	node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
-	if node == nil {
-		// There is at least one worker per P, so normally there are
-		// enough workers to run on all Ps, if necessary. However, once
-		// a worker enters gcMarkDone it may park without rejoining the
-		// pool, thus freeing a P with no corresponding worker.
-		// gcMarkDone never depends on another worker doing work, so it
-		// is safe to simply do nothing here.
-		//
-		// If gcMarkDone bails out without completing the mark phase,
-		// it will always do so with queued global work. Thus, that P
-		// will be immediately eligible to re-run the worker G it was
-		// just using, ensuring work can complete.
-		return nil
-	}
-
-	decIfPositive := func(ptr *int64) bool {
-		for {
-			v := atomic.Loadint64(ptr)
-			if v <= 0 {
-				return false
-			}
-
-			// TODO: having atomic.Casint64 would be more pleasant.
-			if atomic.Cas64((*uint64)(unsafe.Pointer(ptr)), uint64(v), uint64(v-1)) {
-				return true
-			}
-		}
-	}
-
-	if decIfPositive(&c.dedicatedMarkWorkersNeeded) {
-		// 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.
-		gcBgMarkWorkerPool.push(&node.node)
-		return nil
-	} else {
-		// 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.
-			gcBgMarkWorkerPool.push(&node.node)
-			return nil
-		}
-		// Run a fractional worker.
-		_p_.gcMarkWorkerMode = gcMarkWorkerFractionalMode
-	}
-
-	// Run the background mark worker.
-	gp := node.gp.ptr()
-	casgstatus(gp, _Gwaiting, _Grunnable)
-	if trace.enabled {
-		traceGoUnpark(gp, 0)
-	}
-	return gp
-}
-
 // pollFractionalWorkerExit reports whether a fractional mark worker
 // should self-preempt. It assumes it is called from the fractional
 // worker.
@@ -809,203 +283,6 @@
 	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.
-//
-// This can be called any time. If GC is the in the middle of a
-// concurrent phase, it will adjust the pacing of that phase.
-//
-// This depends on gcpercent, memstats.heap_marked, and
-// memstats.heap_live. These must be up to date.
-//
-// mheap_.lock must be held or the world must be stopped.
-func gcSetTriggerRatio(triggerRatio float64) {
-	assertWorldStoppedOrLockHeld(&mheap_.lock)
-
-	// Compute the next GC goal, which is when the allocated heap
-	// has grown by GOGC/100 over the heap marked by the last
-	// cycle.
-	goal := ^uint64(0)
-	if gcpercent >= 0 {
-		goal = memstats.heap_marked + memstats.heap_marked*uint64(gcpercent)/100
-	}
-
-	// Set the trigger ratio, capped to reasonable bounds.
-	if gcpercent >= 0 {
-		scalingFactor := float64(gcpercent) / 100
-		// Ensure there's always a little margin so that the
-		// mutator assist ratio isn't infinity.
-		maxTriggerRatio := 0.95 * scalingFactor
-		if triggerRatio > maxTriggerRatio {
-			triggerRatio = maxTriggerRatio
-		}
-
-		// If we let triggerRatio go too low, then if the application
-		// is allocating very rapidly we might end up in a situation
-		// where we're allocating black during a nearly always-on GC.
-		// The result of this is a growing heap and ultimately an
-		// increase in RSS. By capping us at a point >0, we're essentially
-		// saying that we're OK using more CPU during the GC to prevent
-		// this growth in RSS.
-		//
-		// The current constant was chosen empirically: given a sufficiently
-		// fast/scalable allocator with 48 Ps that could drive the trigger ratio
-		// to <0.05, this constant causes applications to retain the same peak
-		// RSS compared to not having this allocator.
-		minTriggerRatio := 0.6 * scalingFactor
-		if triggerRatio < minTriggerRatio {
-			triggerRatio = minTriggerRatio
-		}
-	} else if triggerRatio < 0 {
-		// gcpercent < 0, so just make sure we're not getting a negative
-		// triggerRatio. This case isn't expected to happen in practice,
-		// and doesn't really matter because if gcpercent < 0 then we won't
-		// ever consume triggerRatio further on in this function, but let's
-		// just be defensive here; the triggerRatio being negative is almost
-		// certainly undesirable.
-		triggerRatio = 0
-	}
-	memstats.triggerRatio = triggerRatio
-
-	// Compute the absolute GC trigger from the trigger ratio.
-	//
-	// We trigger the next GC cycle when the allocated heap has
-	// grown by the trigger ratio over the marked heap size.
-	trigger := ^uint64(0)
-	if gcpercent >= 0 {
-		trigger = uint64(float64(memstats.heap_marked) * (1 + triggerRatio))
-		// Don't trigger below the minimum heap size.
-		minTrigger := heapminimum
-		if !isSweepDone() {
-			// Concurrent sweep happens in the heap growth
-			// from heap_live to gc_trigger, so ensure
-			// that concurrent sweep has some heap growth
-			// in which to perform sweeping before we
-			// start the next GC cycle.
-			sweepMin := atomic.Load64(&memstats.heap_live) + sweepMinHeapDistance
-			if sweepMin > minTrigger {
-				minTrigger = sweepMin
-			}
-		}
-		if trigger < minTrigger {
-			trigger = minTrigger
-		}
-		if int64(trigger) < 0 {
-			print("runtime: next_gc=", memstats.next_gc, " heap_marked=", memstats.heap_marked, " heap_live=", memstats.heap_live, " initialHeapLive=", work.initialHeapLive, "triggerRatio=", triggerRatio, " minTrigger=", minTrigger, "\n")
-			throw("gc_trigger underflow")
-		}
-		if trigger > goal {
-			// The trigger ratio is always less than GOGC/100, but
-			// other bounds on the trigger may have raised it.
-			// Push up the goal, too.
-			goal = trigger
-		}
-	}
-
-	// Commit to the trigger and goal.
-	memstats.gc_trigger = trigger
-	atomic.Store64(&memstats.next_gc, goal)
-	if trace.enabled {
-		traceNextGC()
-	}
-
-	// Update mark pacing.
-	if gcphase != _GCoff {
-		gcController.revise()
-	}
-
-	// Update sweep pacing.
-	if isSweepDone() {
-		mheap_.sweepPagesPerByte = 0
-	} else {
-		// Concurrent sweep needs to sweep all of the in-use
-		// pages by the time the allocated heap reaches the GC
-		// trigger. Compute the ratio of in-use pages to sweep
-		// per byte allocated, accounting for the fact that
-		// some might already be swept.
-		heapLiveBasis := atomic.Load64(&memstats.heap_live)
-		heapDistance := int64(trigger) - int64(heapLiveBasis)
-		// Add a little margin so rounding errors and
-		// concurrent sweep are less likely to leave pages
-		// unswept when GC starts.
-		heapDistance -= 1024 * 1024
-		if heapDistance < _PageSize {
-			// Avoid setting the sweep ratio extremely high
-			heapDistance = _PageSize
-		}
-		pagesSwept := atomic.Load64(&mheap_.pagesSwept)
-		pagesInUse := atomic.Load64(&mheap_.pagesInUse)
-		sweepDistancePages := int64(pagesInUse) - int64(pagesSwept)
-		if sweepDistancePages <= 0 {
-			mheap_.sweepPagesPerByte = 0
-		} else {
-			mheap_.sweepPagesPerByte = float64(sweepDistancePages) / float64(heapDistance)
-			mheap_.sweepHeapLiveBasis = heapLiveBasis
-			// Write pagesSweptBasis last, since this
-			// signals concurrent sweeps to recompute
-			// their debt.
-			atomic.Store64(&mheap_.pagesSweptBasis, pagesSwept)
-		}
-	}
-
-	gcPaceScavenger()
-}
-
-// gcEffectiveGrowthRatio returns the current effective heap growth
-// ratio (GOGC/100) based on heap_marked from the previous GC and
-// next_gc for the current GC.
-//
-// This may differ from gcpercent/100 because of various upper and
-// lower bounds on gcpercent. For example, if the heap is smaller than
-// heapminimum, this can be higher than gcpercent/100.
-//
-// mheap_.lock must be held or the world must be stopped.
-func gcEffectiveGrowthRatio() float64 {
-	assertWorldStoppedOrLockHeld(&mheap_.lock)
-
-	egogc := float64(atomic.Load64(&memstats.next_gc)-memstats.heap_marked) / float64(memstats.heap_marked)
-	if egogc < 0 {
-		// Shouldn't happen, but just in case.
-		egogc = 0
-	}
-	return egogc
-}
-
-// gcGoalUtilization is the goal CPU utilization for
-// marking as a fraction of GOMAXPROCS.
-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
-// accumulate locally before updating gcController.scanWork and,
-// optionally, gcController.bgScanCredit. Lower values give a more
-// accurate assist ratio and make it more likely that assists will
-// successfully steal background credit. Higher values reduce memory
-// contention.
-const gcCreditSlack = 2000
-
-// gcAssistTimeSlack is the nanoseconds of mutator assist time that
-// can accumulate on a P before updating gcController.assistTime.
-const gcAssistTimeSlack = 5000
-
-// gcOverAssistWork determines how many extra units of scan work a GC
-// assist does when an assist happens. This amortizes the cost of an
-// assist by pre-paying for this many bytes of future allocations.
-const gcOverAssistWork = 64 << 10
-
 var work struct {
 	full  lfstack          // lock-free list of full blocks workbuf
 	empty lfstack          // lock-free list of empty blocks workbuf
@@ -1048,9 +325,11 @@
 	nwait  uint32
 
 	// Number of roots of various root types. Set by gcMarkRootPrepare.
-	nFlushCacheRoots                               int
 	nDataRoots, nBSSRoots, nSpanRoots, nStackRoots int
 
+	// Base indexes of each root type. Set by gcMarkRootPrepare.
+	baseData, baseBSS, baseSpans, baseStacks, baseEnd uint32
+
 	// Each type of GC state transition is protected by a lock.
 	// Since multiple threads can simultaneously detect the state
 	// transition condition, any thread that detects a transition
@@ -1084,7 +363,7 @@
 	// program started if debug.gctrace > 0.
 	totaltime int64
 
-	// initialHeapLive is the value of memstats.heap_live at the
+	// initialHeapLive is the value of gcController.heapLive at the
 	// beginning of this GC cycle.
 	initialHeapLive uint64
 
@@ -1181,7 +460,7 @@
 	// First, wait for sweeping to finish. (We know there are no
 	// more spans on the sweep queue, but we may be concurrently
 	// sweeping spans, so we have to wait.)
-	for atomic.Load(&work.cycles) == n+1 && atomic.Load(&mheap_.sweepers) != 0 {
+	for atomic.Load(&work.cycles) == n+1 && !isSweepDone() {
 		Gosched()
 	}
 
@@ -1265,13 +544,13 @@
 	}
 	switch t.kind {
 	case gcTriggerHeap:
-		// Non-atomic access to heap_live for performance. If
+		// Non-atomic access to gcController.heapLive for performance. If
 		// we are going to trigger on this, this thread just
-		// atomically wrote heap_live anyway and we'll see our
+		// atomically wrote gcController.heapLive anyway and we'll see our
 		// own write.
-		return memstats.heap_live >= memstats.gc_trigger
+		return gcController.heapLive >= gcController.trigger
 	case gcTriggerTime:
-		if gcpercent < 0 {
+		if gcController.gcPercent < 0 {
 			return false
 		}
 		lastgc := int64(atomic.Load64(&memstats.last_gc_nanotime))
@@ -1365,7 +644,7 @@
 		// so it can't be more than ncpu, even if GOMAXPROCS is.
 		work.stwprocs = ncpu
 	}
-	work.heap0 = atomic.Load64(&memstats.heap_live)
+	work.heap0 = atomic.Load64(&gcController.heapLive)
 	work.pauseNS = 0
 	work.mode = mode
 
@@ -1388,7 +667,7 @@
 	work.cycles++
 
 	gcController.startCycle()
-	work.heapGoal = memstats.next_gc
+	work.heapGoal = gcController.heapGoal
 
 	// In STW mode, disable scheduling of user Gs. This may also
 	// disable scheduling of this goroutine, so it may block as
@@ -1617,7 +896,7 @@
 	// endCycle depends on all gcWork cache stats being flushed.
 	// The termination algorithm above ensured that up to
 	// allocations since the ragged barrier.
-	nextTriggerRatio := gcController.endCycle()
+	nextTriggerRatio := gcController.endCycle(work.userForced)
 
 	// Perform mark termination. This will restart the world.
 	gcMarkTermination(nextTriggerRatio)
@@ -1629,7 +908,7 @@
 	// Start marktermination (write barrier remains enabled for now).
 	setGCPhase(_GCmarktermination)
 
-	work.heap1 = memstats.heap_live
+	work.heap1 = gcController.heapLive
 	startTime := nanotime()
 
 	mp := acquirem()
@@ -1691,12 +970,12 @@
 		throw("gc done but gcphase != _GCoff")
 	}
 
-	// Record next_gc and heap_inuse for scavenger.
-	memstats.last_next_gc = memstats.next_gc
+	// Record heapGoal and heap_inuse for scavenger.
+	gcController.lastHeapGoal = gcController.heapGoal
 	memstats.last_heap_inuse = memstats.heap_inuse
 
 	// Update GC trigger and pacing for the next cycle.
-	gcSetTriggerRatio(nextTriggerRatio)
+	gcController.commit(nextTriggerRatio)
 
 	// Update timing memstats
 	now := nanotime()
@@ -1743,6 +1022,13 @@
 	// so events don't leak into the wrong cycle.
 	mProf_NextCycle()
 
+	// There may be stale spans in mcaches that need to be swept.
+	// Those aren't tracked in any sweep lists, so we need to
+	// count them against sweep completion until we ensure all
+	// those spans have been forced out.
+	sl := newSweepLocker()
+	sl.blockCompletion()
+
 	systemstack(func() { startTheWorldWithSema(true) })
 
 	// Flush the heap profile so we can start a new cycle next GC.
@@ -1766,6 +1052,9 @@
 			_p_.mcache.prepareForSweep()
 		})
 	})
+	// Now that we've swept stale spans in mcaches, they don't
+	// count against unswept spans.
+	sl.dispose()
 
 	// Print gctrace before dropping worldsema. As soon as we drop
 	// worldsema another cycle could start and smash the stats
@@ -1984,15 +1273,11 @@
 					// everything out of the run
 					// queue so it can run
 					// somewhere else.
-					lock(&sched.lock)
-					for {
-						gp, _ := runqget(pp)
-						if gp == nil {
-							break
-						}
-						globrunqput(gp)
+					if drainQ, n := runqdrain(pp); n > 0 {
+						lock(&sched.lock)
+						globrunqputbatch(&drainQ, int32(n))
+						unlock(&sched.lock)
 					}
-					unlock(&sched.lock)
 				}
 				// Go back to draining, this time
 				// without preemption.
@@ -2066,7 +1351,7 @@
 // gcMark runs the mark (or, for concurrent GC, mark termination)
 // All gcWork caches must be empty.
 // STW is in effect at this point.
-func gcMark(start_time int64) {
+func gcMark(startTime int64) {
 	if debug.allocfreetrace > 0 {
 		tracegc()
 	}
@@ -2074,7 +1359,7 @@
 	if gcphase != _GCmarktermination {
 		throw("in gcMark expecting to see gcphase as _GCmarktermination")
 	}
-	work.tstart = start_time
+	work.tstart = startTime
 
 	// Check that there's no marking work remaining.
 	if work.full != 0 || work.markrootNext < work.markrootJobs {
@@ -2136,25 +1421,25 @@
 	}
 
 	// Update the marked heap stat.
-	memstats.heap_marked = work.bytesMarked
+	gcController.heapMarked = work.bytesMarked
 
 	// Flush scanAlloc from each mcache since we're about to modify
-	// heap_scan directly. If we were to flush this later, then scanAlloc
+	// heapScan directly. If we were to flush this later, then scanAlloc
 	// might have incorrect information.
 	for _, p := range allp {
 		c := p.mcache
 		if c == nil {
 			continue
 		}
-		memstats.heap_scan += uint64(c.scanAlloc)
+		gcController.heapScan += uint64(c.scanAlloc)
 		c.scanAlloc = 0
 	}
 
 	// Update other GC heap size stats. This must happen after
 	// cachestats (which flushes local statistics to these) and
-	// flushallmcaches (which modifies heap_live).
-	memstats.heap_live = work.bytesMarked
-	memstats.heap_scan = uint64(gcController.scanWork)
+	// flushallmcaches (which modifies gcController.heapLive).
+	gcController.heapLive = work.bytesMarked
+	gcController.heapScan = uint64(gcController.scanWork)
 
 	if trace.enabled {
 		traceHeapAlloc()
@@ -2176,7 +1461,7 @@
 
 	lock(&mheap_.lock)
 	mheap_.sweepgen += 2
-	mheap_.sweepdone = 0
+	mheap_.sweepDrained = 0
 	mheap_.pagesSwept = 0
 	mheap_.sweepArenas = mheap_.allArenas
 	mheap_.reclaimIndex = 0
@@ -2227,14 +1512,12 @@
 //
 //go:systemstack
 func gcResetMarkState() {
-	// This may be called during a concurrent phase, so make sure
+	// This may be called during a concurrent phase, so lock to make sure
 	// allgs doesn't change.
-	lock(&allglock)
-	for _, gp := range allgs {
+	forEachG(func(gp *g) {
 		gp.gcscandone = false // set to true in gcphasework
 		gp.gcAssistBytes = 0
-	}
-	unlock(&allglock)
+	})
 
 	// Clear page marks. This is just 1MB per 64GB of heap, so the
 	// time here is pretty trivial.
@@ -2249,7 +1532,7 @@
 	}
 
 	work.bytesMarked = 0
-	work.initialHeapLive = atomic.Load64(&memstats.heap_live)
+	work.initialHeapLive = atomic.Load64(&gcController.heapLive)
 }
 
 // Hooks for other packages
@@ -2334,3 +1617,102 @@
 	}
 	return itoaDiv(buf, x, dec)
 }
+
+// Helpers for testing GC.
+
+// gcTestMoveStackOnNextCall causes the stack to be moved on a call
+// immediately following the call to this. It may not work correctly
+// if any other work appears after this call (such as returning).
+// Typically the following call should be marked go:noinline so it
+// performs a stack check.
+//
+// In rare cases this may not cause the stack to move, specifically if
+// there's a preemption between this call and the next.
+func gcTestMoveStackOnNextCall() {
+	gp := getg()
+	gp.stackguard0 = stackForceMove
+}
+
+// gcTestIsReachable performs a GC and returns a bit set where bit i
+// is set if ptrs[i] is reachable.
+func gcTestIsReachable(ptrs ...unsafe.Pointer) (mask uint64) {
+	// This takes the pointers as unsafe.Pointers in order to keep
+	// them live long enough for us to attach specials. After
+	// that, we drop our references to them.
+
+	if len(ptrs) > 64 {
+		panic("too many pointers for uint64 mask")
+	}
+
+	// Block GC while we attach specials and drop our references
+	// to ptrs. Otherwise, if a GC is in progress, it could mark
+	// them reachable via this function before we have a chance to
+	// drop them.
+	semacquire(&gcsema)
+
+	// Create reachability specials for ptrs.
+	specials := make([]*specialReachable, len(ptrs))
+	for i, p := range ptrs {
+		lock(&mheap_.speciallock)
+		s := (*specialReachable)(mheap_.specialReachableAlloc.alloc())
+		unlock(&mheap_.speciallock)
+		s.special.kind = _KindSpecialReachable
+		if !addspecial(p, &s.special) {
+			throw("already have a reachable special (duplicate pointer?)")
+		}
+		specials[i] = s
+		// Make sure we don't retain ptrs.
+		ptrs[i] = nil
+	}
+
+	semrelease(&gcsema)
+
+	// Force a full GC and sweep.
+	GC()
+
+	// Process specials.
+	for i, s := range specials {
+		if !s.done {
+			printlock()
+			println("runtime: object", i, "was not swept")
+			throw("IsReachable failed")
+		}
+		if s.reachable {
+			mask |= 1 << i
+		}
+		lock(&mheap_.speciallock)
+		mheap_.specialReachableAlloc.free(unsafe.Pointer(s))
+		unlock(&mheap_.speciallock)
+	}
+
+	return mask
+}
+
+// gcTestPointerClass returns the category of what p points to, one of:
+// "heap", "stack", "data", "bss", "other". This is useful for checking
+// that a test is doing what it's intended to do.
+//
+// This is nosplit simply to avoid extra pointer shuffling that may
+// complicate a test.
+//
+//go:nosplit
+func gcTestPointerClass(p unsafe.Pointer) string {
+	p2 := uintptr(noescape(p))
+	gp := getg()
+	if gp.stack.lo <= p2 && p2 < gp.stack.hi {
+		return "stack"
+	}
+	if base, _, _ := findObject(p2, 0, 0); base != 0 {
+		return "heap"
+	}
+	for _, datap := range activeModules() {
+		if datap.data <= p2 && p2 < datap.edata || datap.noptrdata <= p2 && p2 < datap.enoptrdata {
+			return "data"
+		}
+		if datap.bss <= p2 && p2 < datap.ebss || datap.noptrbss <= p2 && p2 <= datap.enoptrbss {
+			return "bss"
+		}
+	}
+	KeepAlive(p)
+	return "other"
+}
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index 46fae5d..1fd0732 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -56,8 +56,6 @@
 func gcMarkRootPrepare() {
 	assertWorldStopped()
 
-	work.nFlushCacheRoots = 0
-
 	// Compute how many data and BSS root blocks there are.
 	nBlocks := func(bytes uintptr) int {
 		return int(divRoundUp(bytes, rootBlockBytes))
@@ -105,7 +103,14 @@
 	work.nStackRoots = int(atomic.Loaduintptr(&allglen))
 
 	work.markrootNext = 0
-	work.markrootJobs = uint32(fixedRootCount + work.nFlushCacheRoots + work.nDataRoots + work.nBSSRoots + work.nSpanRoots + work.nStackRoots)
+	work.markrootJobs = uint32(fixedRootCount + work.nDataRoots + work.nBSSRoots + work.nSpanRoots + work.nStackRoots)
+
+	// Calculate base indexes of each root type
+	work.baseData = uint32(fixedRootCount)
+	work.baseBSS = work.baseData + uint32(work.nDataRoots)
+	work.baseSpans = work.baseBSS + uint32(work.nBSSRoots)
+	work.baseStacks = work.baseSpans + uint32(work.nSpanRoots)
+	work.baseEnd = work.baseStacks + uint32(work.nStackRoots)
 }
 
 // gcMarkRootCheck checks that all roots have been scanned. It is
@@ -116,23 +121,26 @@
 		throw("left over markroot jobs")
 	}
 
-	lock(&allglock)
 	// Check that stacks have been scanned.
-	var gp *g
-	for i := 0; i < work.nStackRoots; i++ {
-		gp = allgs[i]
-		if !gp.gcscandone {
-			goto fail
+	//
+	// We only check the first nStackRoots Gs that we should have scanned.
+	// Since we don't care about newer Gs (see comment in
+	// gcMarkRootPrepare), no locking is required.
+	i := 0
+	forEachGRace(func(gp *g) {
+		if i >= work.nStackRoots {
+			return
 		}
-	}
-	unlock(&allglock)
-	return
 
-fail:
-	println("gp", gp, "goid", gp.goid,
-		"status", readgstatus(gp),
-		"gcscandone", gp.gcscandone)
-	throw("scan missed a g")
+		if !gp.gcscandone {
+			println("gp", gp, "goid", gp.goid,
+				"status", readgstatus(gp),
+				"gcscandone", gp.gcscandone)
+			throw("scan missed a g")
+		}
+
+		i++
+	})
 }
 
 // ptrmask for an allocation containing a single pointer.
@@ -146,28 +154,16 @@
 //
 //go:nowritebarrier
 func markroot(gcw *gcWork, i uint32) {
-	// TODO(austin): This is a bit ridiculous. Compute and store
-	// the bases in gcMarkRootPrepare instead of the counts.
-	baseFlushCache := uint32(fixedRootCount)
-	baseData := baseFlushCache + uint32(work.nFlushCacheRoots)
-	baseBSS := baseData + uint32(work.nDataRoots)
-	baseSpans := baseBSS + uint32(work.nBSSRoots)
-	baseStacks := baseSpans + uint32(work.nSpanRoots)
-	end := baseStacks + uint32(work.nStackRoots)
-
 	// Note: if you add a case here, please also update heapdump.go:dumproots.
 	switch {
-	case baseFlushCache <= i && i < baseData:
-		flushmcache(int(i - baseFlushCache))
-
-	case baseData <= i && i < baseBSS:
+	case work.baseData <= i && i < work.baseBSS:
 		for _, datap := range activeModules() {
-			markrootBlock(datap.data, datap.edata-datap.data, datap.gcdatamask.bytedata, gcw, int(i-baseData))
+			markrootBlock(datap.data, datap.edata-datap.data, datap.gcdatamask.bytedata, gcw, int(i-work.baseData))
 		}
 
-	case baseBSS <= i && i < baseSpans:
+	case work.baseBSS <= i && i < work.baseSpans:
 		for _, datap := range activeModules() {
-			markrootBlock(datap.bss, datap.ebss-datap.bss, datap.gcbssmask.bytedata, gcw, int(i-baseBSS))
+			markrootBlock(datap.bss, datap.ebss-datap.bss, datap.gcbssmask.bytedata, gcw, int(i-work.baseBSS))
 		}
 
 	case i == fixedRootFinalizers:
@@ -181,15 +177,18 @@
 		// stackfree.
 		systemstack(markrootFreeGStacks)
 
-	case baseSpans <= i && i < baseStacks:
+	case work.baseSpans <= i && i < work.baseStacks:
 		// mark mspan.specials
-		markrootSpans(gcw, int(i-baseSpans))
+		markrootSpans(gcw, int(i-work.baseSpans))
 
 	default:
 		// the rest is scanning goroutine stacks
 		var gp *g
-		if baseStacks <= i && i < end {
-			gp = allgs[i-baseStacks]
+		if work.baseStacks <= i && i < work.baseEnd {
+			// N.B. Atomic read of allglen in gcMarkRootPrepare
+			// acts as a barrier to ensure that allgs must be large
+			// enough to contain all relevant Gs.
+			gp = allgs[i-work.baseStacks]
 		} else {
 			throw("markroot: bad index")
 		}
@@ -793,24 +792,24 @@
 		if obj == nil {
 			continue
 		}
-		t := obj.typ
-		if t == nil {
+		r := obj.r
+		if r == nil {
 			// We've already scanned this object.
 			continue
 		}
-		obj.setType(nil) // Don't scan it again.
+		obj.setRecord(nil) // Don't scan it again.
 		if stackTraceDebug {
 			printlock()
-			print("  live stkobj at", hex(state.stack.lo+uintptr(obj.off)), "of type", t.string())
+			print("  live stkobj at", hex(state.stack.lo+uintptr(obj.off)), "of size", obj.size)
 			if conservative {
 				print(" (conservative)")
 			}
 			println()
 			printunlock()
 		}
-		gcdata := t.gcdata
+		gcdata := r.gcdata
 		var s *mspan
-		if t.kind&kindGCProg != 0 {
+		if r.useGCProg() {
 			// This path is pretty unlikely, an object large enough
 			// to have a GC program allocated on the stack.
 			// We need some space to unpack the program into a straight
@@ -820,15 +819,15 @@
 			// to change from a Lempel-Ziv style program to something else.
 			// Or we can forbid putting objects on stacks if they require
 			// a gc program (see issue 27447).
-			s = materializeGCProg(t.ptrdata, gcdata)
+			s = materializeGCProg(r.ptrdata(), gcdata)
 			gcdata = (*byte)(unsafe.Pointer(s.startAddr))
 		}
 
 		b := state.stack.lo + uintptr(obj.off)
 		if conservative {
-			scanConservative(b, t.ptrdata, gcdata, gcw, &state)
+			scanConservative(b, r.ptrdata(), gcdata, gcw, &state)
 		} else {
-			scanblock(b, t.ptrdata, gcdata, gcw, &state)
+			scanblock(b, r.ptrdata(), gcdata, gcw, &state)
 		}
 
 		if s != nil {
@@ -844,10 +843,10 @@
 		if stackTraceDebug {
 			for i := 0; i < x.nobj; i++ {
 				obj := &x.obj[i]
-				if obj.typ == nil { // reachable
+				if obj.r == nil { // reachable
 					continue
 				}
-				println("  dead stkobj at", hex(gp.stack.lo+uintptr(obj.off)), "of type", obj.typ.string())
+				println("  dead stkobj at", hex(gp.stack.lo+uintptr(obj.off)), "of size", obj.r.size)
 				// Note: not necessarily really dead - only reachable-from-ptr dead.
 			}
 		}
@@ -867,7 +866,7 @@
 	}
 
 	isAsyncPreempt := frame.fn.valid() && frame.fn.funcID == funcID_asyncPreempt
-	isDebugCall := frame.fn.valid() && frame.fn.funcID == funcID_debugCallV1
+	isDebugCall := frame.fn.valid() && frame.fn.funcID == funcID_debugCallV2
 	if state.conservative || isAsyncPreempt || isDebugCall {
 		if debugScanConservative {
 			println("conservatively scanning function", funcname(frame.fn), "at PC", hex(frame.continpc))
@@ -928,7 +927,7 @@
 		// varp is 0 for defers, where there are no locals.
 		// In that case, there can't be a pointer to its args, either.
 		// (And all args would be scanned above anyway.)
-		for _, obj := range objs {
+		for i, obj := range objs {
 			off := obj.off
 			base := frame.varp // locals base pointer
 			if off >= 0 {
@@ -940,9 +939,9 @@
 				continue
 			}
 			if stackTraceDebug {
-				println("stkobj at", hex(ptr), "of type", obj.typ.string())
+				println("stkobj at", hex(ptr), "of size", obj.size)
 			}
-			state.addObject(ptr, obj.typ)
+			state.addObject(ptr, &objs[i])
 		}
 	}
 }
@@ -1252,12 +1251,7 @@
 	}
 
 	var i uintptr
-	for i = 0; i < n; i += sys.PtrSize {
-		// Find bits for this word.
-		if i != 0 {
-			// Avoid needless hbits.next() on last iteration.
-			hbits = hbits.next()
-		}
+	for i = 0; i < n; i, hbits = i+sys.PtrSize, hbits.next() {
 		// Load bits once. See CL 22712 and issue 16973 for discussion.
 		bits := hbits.bits()
 		if bits&bitScan == 0 {
diff --git a/src/runtime/mgcpacer.go b/src/runtime/mgcpacer.go
new file mode 100644
index 0000000..9338359
--- /dev/null
+++ b/src/runtime/mgcpacer.go
@@ -0,0 +1,848 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import (
+	"internal/cpu"
+	"runtime/internal/atomic"
+	"unsafe"
+)
+
+const (
+	// gcGoalUtilization is the goal CPU utilization for
+	// marking as a fraction of GOMAXPROCS.
+	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.
+	gcBackgroundUtilization = 0.25
+
+	// gcCreditSlack is the amount of scan work credit that can
+	// accumulate locally before updating gcController.scanWork and,
+	// optionally, gcController.bgScanCredit. Lower values give a more
+	// accurate assist ratio and make it more likely that assists will
+	// successfully steal background credit. Higher values reduce memory
+	// contention.
+	gcCreditSlack = 2000
+
+	// gcAssistTimeSlack is the nanoseconds of mutator assist time that
+	// can accumulate on a P before updating gcController.assistTime.
+	gcAssistTimeSlack = 5000
+
+	// gcOverAssistWork determines how many extra units of scan work a GC
+	// assist does when an assist happens. This amortizes the cost of an
+	// assist by pre-paying for this many bytes of future allocations.
+	gcOverAssistWork = 64 << 10
+
+	// defaultHeapMinimum is the value of heapMinimum for GOGC==100.
+	defaultHeapMinimum = 4 << 20
+)
+
+func init() {
+	if offset := unsafe.Offsetof(gcController.heapLive); offset%8 != 0 {
+		println(offset)
+		throw("gcController.heapLive not aligned to 8 bytes")
+	}
+}
+
+// gcController implements the GC pacing controller that determines
+// when to trigger concurrent garbage collection and how much marking
+// work to do in mutator assists and background marking.
+//
+// It uses a feedback control algorithm to adjust the gcController.trigger
+// trigger based on the heap growth and GC CPU utilization each cycle.
+// This algorithm optimizes for heap growth to match GOGC and for CPU
+// utilization between assist and background marking to be 25% of
+// GOMAXPROCS. The high-level design of this algorithm is documented
+// at https://golang.org/s/go15gcpacing.
+//
+// All fields of gcController are used only during a single mark
+// cycle.
+var gcController gcControllerState
+
+type gcControllerState struct {
+	// Initialized from $GOGC. GOGC=off means no GC.
+	gcPercent int32
+
+	_ uint32 // padding so following 64-bit values are 8-byte aligned
+
+	// heapMinimum is the minimum heap size at which to trigger GC.
+	// For small heaps, this overrides the usual GOGC*live set rule.
+	//
+	// When there is a very small live set but a lot of allocation, simply
+	// collecting when the heap reaches GOGC*live results in many GC
+	// cycles and high total per-GC overhead. This minimum amortizes this
+	// per-GC overhead while keeping the heap reasonably small.
+	//
+	// During initialization this is set to 4MB*GOGC/100. In the case of
+	// GOGC==0, this will set heapMinimum to 0, resulting in constant
+	// collection even when the heap size is small, which is useful for
+	// debugging.
+	heapMinimum uint64
+
+	// triggerRatio is the heap growth ratio that triggers marking.
+	//
+	// E.g., if this is 0.6, then GC should start when the live
+	// heap has reached 1.6 times the heap size marked by the
+	// previous cycle. This should be ≤ GOGC/100 so the trigger
+	// heap size is less than the goal heap size. This is set
+	// during mark termination for the next cycle's trigger.
+	//
+	// Protected by mheap_.lock or a STW.
+	triggerRatio float64
+
+	// trigger is the heap size that triggers marking.
+	//
+	// When heapLive ≥ trigger, the mark phase will start.
+	// This is also the heap size by which proportional sweeping
+	// must be complete.
+	//
+	// This is computed from triggerRatio during mark termination
+	// for the next cycle's trigger.
+	//
+	// Protected by mheap_.lock or a STW.
+	trigger uint64
+
+	// heapGoal is the goal heapLive for when next GC ends.
+	// Set to ^uint64(0) if disabled.
+	//
+	// Read and written atomically, unless the world is stopped.
+	heapGoal uint64
+
+	// lastHeapGoal is the value of heapGoal for the previous GC.
+	// Note that this is distinct from the last value heapGoal had,
+	// because it could change if e.g. gcPercent changes.
+	//
+	// Read and written with the world stopped or with mheap_.lock held.
+	lastHeapGoal uint64
+
+	// heapLive is the number of bytes considered live by the GC.
+	// That is: retained by the most recent GC plus allocated
+	// since then. heapLive ≤ memstats.heapAlloc, since heapAlloc includes
+	// unmarked objects that have not yet been swept (and hence goes up as we
+	// allocate and down as we sweep) while heapLive excludes these
+	// objects (and hence only goes up between GCs).
+	//
+	// This is updated atomically without locking. To reduce
+	// contention, this is updated only when obtaining a span from
+	// an mcentral and at this point it counts all of the
+	// unallocated slots in that span (which will be allocated
+	// before that mcache obtains another span from that
+	// mcentral). Hence, it slightly overestimates the "true" live
+	// heap size. It's better to overestimate than to
+	// underestimate because 1) this triggers the GC earlier than
+	// necessary rather than potentially too late and 2) this
+	// leads to a conservative GC rate rather than a GC rate that
+	// is potentially too low.
+	//
+	// Reads should likewise be atomic (or during STW).
+	//
+	// Whenever this is updated, call traceHeapAlloc() and
+	// this gcControllerState's revise() method.
+	heapLive uint64
+
+	// heapScan is the number of bytes of "scannable" heap. This
+	// is the live heap (as counted by heapLive), but omitting
+	// no-scan objects and no-scan tails of objects.
+	//
+	// Whenever this is updated, call this gcControllerState's
+	// revise() method.
+	//
+	// Read and written atomically or with the world stopped.
+	heapScan uint64
+
+	// heapMarked is the number of bytes marked by the previous
+	// GC. After mark termination, heapLive == heapMarked, but
+	// unlike heapLive, heapMarked does not change until the
+	// next mark termination.
+	heapMarked uint64
+
+	// scanWork is the total scan work performed this cycle. This
+	// is updated atomically during the cycle. Updates occur in
+	// bounded batches, since it is both written and read
+	// throughout the cycle. At the end of the cycle, this is how
+	// much of the retained heap is scannable.
+	//
+	// Currently this is the bytes of heap scanned. For most uses,
+	// this is an opaque unit of work, but for estimation the
+	// definition is important.
+	scanWork int64
+
+	// bgScanCredit is the scan work credit accumulated by the
+	// concurrent background scan. This credit is accumulated by
+	// the background scan and stolen by mutator assists. This is
+	// updated atomically. Updates occur in bounded batches, since
+	// it is both written and read throughout the cycle.
+	bgScanCredit int64
+
+	// assistTime is the nanoseconds spent in mutator assists
+	// during this cycle. This is updated atomically. Updates
+	// occur in bounded batches, since it is both written and read
+	// throughout the cycle.
+	assistTime int64
+
+	// dedicatedMarkTime is the nanoseconds spent in dedicated
+	// mark workers during this cycle. This is updated atomically
+	// at the end of the concurrent mark phase.
+	dedicatedMarkTime int64
+
+	// fractionalMarkTime is the nanoseconds spent in the
+	// fractional mark worker during this cycle. This is updated
+	// atomically throughout the cycle and will be up-to-date if
+	// the fractional mark worker is not currently running.
+	fractionalMarkTime int64
+
+	// idleMarkTime is the nanoseconds spent in idle marking
+	// during this cycle. This is updated atomically throughout
+	// the cycle.
+	idleMarkTime int64
+
+	// markStartTime is the absolute start time in nanoseconds
+	// that assists and background mark workers started.
+	markStartTime int64
+
+	// dedicatedMarkWorkersNeeded is the number of dedicated mark
+	// workers that need to be started. This is computed at the
+	// beginning of each cycle and decremented atomically as
+	// dedicated mark workers get started.
+	dedicatedMarkWorkersNeeded int64
+
+	// assistWorkPerByte is the ratio of scan work to allocated
+	// bytes that should be performed by mutator assists. This is
+	// computed at the beginning of each cycle and updated every
+	// time heapScan is updated.
+	//
+	// Stored as a uint64, but it's actually a float64. Use
+	// float64frombits to get the value.
+	//
+	// Read and written atomically.
+	assistWorkPerByte uint64
+
+	// assistBytesPerWork is 1/assistWorkPerByte.
+	//
+	// Stored as a uint64, but it's actually a float64. Use
+	// float64frombits to get the value.
+	//
+	// Read and written atomically.
+	//
+	// Note that because this is read and written independently
+	// from assistWorkPerByte users may notice a skew between
+	// the two values, and such a state should be safe.
+	assistBytesPerWork uint64
+
+	// fractionalUtilizationGoal is the fraction of wall clock
+	// 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 the 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
+
+	_ cpu.CacheLinePad
+}
+
+func (c *gcControllerState) init(gcPercent int32) {
+	c.heapMinimum = defaultHeapMinimum
+
+	// Set a reasonable initial GC trigger.
+	c.triggerRatio = 7 / 8.0
+
+	// Fake a heapMarked value so it looks like a trigger at
+	// heapMinimum is the appropriate growth from heapMarked.
+	// This will go into computing the initial GC goal.
+	c.heapMarked = uint64(float64(c.heapMinimum) / (1 + c.triggerRatio))
+
+	// This will also compute and set the GC trigger and goal.
+	c.setGCPercent(gcPercent)
+}
+
+// startCycle resets the GC controller's state and computes estimates
+// for a new GC cycle. The caller must hold worldsema and the world
+// must be stopped.
+func (c *gcControllerState) startCycle() {
+	c.scanWork = 0
+	c.bgScanCredit = 0
+	c.assistTime = 0
+	c.dedicatedMarkTime = 0
+	c.fractionalMarkTime = 0
+	c.idleMarkTime = 0
+
+	// Ensure that the heap goal is at least a little larger than
+	// the current live heap size. This may not be the case if GC
+	// start is delayed or if the allocation that pushed gcController.heapLive
+	// over trigger is large or if the trigger is really close to
+	// GOGC. Assist is proportional to this distance, so enforce a
+	// minimum distance, even if it means going over the GOGC goal
+	// by a tiny bit.
+	if c.heapGoal < c.heapLive+1024*1024 {
+		c.heapGoal = c.heapLive + 1024*1024
+	}
+
+	// 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.fractionalUtilizationGoal = 0
+	}
+
+	// In STW mode, we just want dedicated workers.
+	if debug.gcstoptheworld > 0 {
+		c.dedicatedMarkWorkersNeeded = int64(gomaxprocs)
+		c.fractionalUtilizationGoal = 0
+	}
+
+	// Clear per-P state
+	for _, p := range allp {
+		p.gcAssistTime = 0
+		p.gcFractionalMarkTime = 0
+	}
+
+	// Compute initial values for controls that are updated
+	// throughout the cycle.
+	c.revise()
+
+	if debug.gcpacertrace > 0 {
+		assistRatio := float64frombits(atomic.Load64(&c.assistWorkPerByte))
+		print("pacer: assist ratio=", assistRatio,
+			" (scan ", gcController.heapScan>>20, " MB in ",
+			work.initialHeapLive>>20, "->",
+			c.heapGoal>>20, " MB)",
+			" workers=", c.dedicatedMarkWorkersNeeded,
+			"+", c.fractionalUtilizationGoal, "\n")
+	}
+}
+
+// revise updates the assist ratio during the GC cycle to account for
+// improved estimates. This should be called whenever gcController.heapScan,
+// gcController.heapLive, or gcController.heapGoal is updated. It is safe to
+// call concurrently, but it may race with other calls to revise.
+//
+// The result of this race is that the two assist ratio values may not line
+// up or may be stale. In practice this is OK because the assist ratio
+// moves slowly throughout a GC cycle, and the assist ratio is a best-effort
+// heuristic anyway. Furthermore, no part of the heuristic depends on
+// the two assist ratio values being exact reciprocals of one another, since
+// the two values are used to convert values from different sources.
+//
+// The worst case result of this raciness is that we may miss a larger shift
+// in the ratio (say, if we decide to pace more aggressively against the
+// hard heap goal) but even this "hard goal" is best-effort (see #40460).
+// The dedicated GC should ensure we don't exceed the hard goal by too much
+// in the rare case we do exceed it.
+//
+// It should only be called when gcBlackenEnabled != 0 (because this
+// is when assists are enabled and the necessary statistics are
+// available).
+func (c *gcControllerState) revise() {
+	gcPercent := c.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(&c.heapLive)
+	scan := atomic.Load64(&c.heapScan)
+	work := atomic.Loadint64(&c.scanWork)
+
+	// Assume we're under the soft goal. Pace GC to complete at
+	// heapGoal assuming the heap is in steady-state.
+	heapGoal := int64(atomic.Load64(&c.heapGoal))
+
+	// 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*heapScan.)
+	scanWorkExpected := int64(float64(scan) * 100 / float64(100+gcPercent))
+
+	if int64(live) > heapGoal || work > scanWorkExpected {
+		// We're past the soft goal, or we've already done more scan
+		// work than we expected. Pace GC so that in the worst case it
+		// will complete by the hard goal.
+		const maxOvershoot = 1.1
+		heapGoal = int64(float64(heapGoal) * maxOvershoot)
+
+		// Compute the upper bound on the scan work remaining.
+		scanWorkExpected = int64(scan)
+	}
+
+	// Compute the remaining scan work estimate.
+	//
+	// Note that we currently count allocations during GC as both
+	// scannable heap (heapScan) and scan work completed
+	// (scanWork), so allocation will change this difference
+	// slowly in the soft regime and not at all in the hard
+	// regime.
+	scanWorkRemaining := scanWorkExpected - work
+	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 remaining scan work
+		// negative, even in the hard goal regime.
+		scanWorkRemaining = 1000
+	}
+
+	// Compute the heap distance remaining.
+	heapRemaining := heapGoal - int64(live)
+	if heapRemaining <= 0 {
+		// This shouldn't happen, but if it does, avoid
+		// dividing by zero or setting the assist negative.
+		heapRemaining = 1
+	}
+
+	// Compute the mutator assist ratio so by the time the mutator
+	// allocates the remaining heap bytes up to heapGoal, it will
+	// have done (or stolen) the remaining amount of scan work.
+	// Note that the assist ratio values are updated atomically
+	// but not together. This means there may be some degree of
+	// skew between the two values. This is generally OK as the
+	// values shift relatively slowly over the course of a GC
+	// cycle.
+	assistWorkPerByte := float64(scanWorkRemaining) / float64(heapRemaining)
+	assistBytesPerWork := float64(heapRemaining) / float64(scanWorkRemaining)
+	atomic.Store64(&c.assistWorkPerByte, float64bits(assistWorkPerByte))
+	atomic.Store64(&c.assistBytesPerWork, float64bits(assistBytesPerWork))
+}
+
+// endCycle computes the trigger ratio for the next cycle.
+// userForced indicates whether the current GC cycle was forced
+// by the application.
+func (c *gcControllerState) endCycle(userForced bool) float64 {
+	if userForced {
+		// Forced GC means this cycle didn't start at the
+		// trigger, so where it finished isn't good
+		// information about how to adjust the trigger.
+		// Just leave it where it is.
+		return c.triggerRatio
+	}
+
+	// Proportional response gain for the trigger controller. Must
+	// be in [0, 1]. Lower values smooth out transient effects but
+	// take longer to respond to phase changes. Higher values
+	// react to phase changes quickly, but are more affected by
+	// transient changes. Values near 1 may be unstable.
+	const triggerGain = 0.5
+
+	// Compute next cycle trigger ratio. First, this computes the
+	// "error" for this cycle; that is, how far off the trigger
+	// was from what it should have been, accounting for both heap
+	// growth and GC CPU utilization. We compute the actual heap
+	// growth during this cycle and scale that by how far off from
+	// the goal CPU utilization we were (to estimate the heap
+	// growth if we had the desired CPU utilization). The
+	// difference between this estimate and the GOGC-based goal
+	// heap growth is the error.
+	goalGrowthRatio := c.effectiveGrowthRatio()
+	actualGrowthRatio := float64(c.heapLive)/float64(c.heapMarked) - 1
+	assistDuration := nanotime() - c.markStartTime
+
+	// Assume background mark hit its utilization goal.
+	utilization := gcBackgroundUtilization
+	// Add assist utilization; avoid divide by zero.
+	if assistDuration > 0 {
+		utilization += float64(c.assistTime) / float64(assistDuration*int64(gomaxprocs))
+	}
+
+	triggerError := goalGrowthRatio - c.triggerRatio - utilization/gcGoalUtilization*(actualGrowthRatio-c.triggerRatio)
+
+	// Finally, we adjust the trigger for next time by this error,
+	// damped by the proportional gain.
+	triggerRatio := c.triggerRatio + triggerGain*triggerError
+
+	if debug.gcpacertrace > 0 {
+		// Print controller state in terms of the design
+		// document.
+		H_m_prev := c.heapMarked
+		h_t := c.triggerRatio
+		H_T := c.trigger
+		h_a := actualGrowthRatio
+		H_a := c.heapLive
+		h_g := goalGrowthRatio
+		H_g := int64(float64(H_m_prev) * (1 + h_g))
+		u_a := utilization
+		u_g := gcGoalUtilization
+		W_a := c.scanWork
+		print("pacer: H_m_prev=", H_m_prev,
+			" h_t=", h_t, " H_T=", H_T,
+			" h_a=", h_a, " H_a=", H_a,
+			" h_g=", h_g, " H_g=", H_g,
+			" u_a=", u_a, " u_g=", u_g,
+			" W_a=", W_a,
+			" goalΔ=", goalGrowthRatio-h_t,
+			" actualΔ=", h_a-h_t,
+			" u_a/u_g=", u_a/u_g,
+			"\n")
+	}
+
+	return triggerRatio
+}
+
+// enlistWorker encourages another dedicated mark worker to start on
+// another P if there are spare worker slots. It is used by putfull
+// when more work is made available.
+//
+//go:nowritebarrier
+func (c *gcControllerState) enlistWorker() {
+	// If there are idle Ps, wake one so it will run an idle worker.
+	// NOTE: This is suspected of causing deadlocks. See golang.org/issue/19112.
+	//
+	//	if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 {
+	//		wakep()
+	//		return
+	//	}
+
+	// There are no idle Ps. If we need more dedicated workers,
+	// try to preempt a running P so it will switch to a worker.
+	if c.dedicatedMarkWorkersNeeded <= 0 {
+		return
+	}
+	// Pick a random other P to preempt.
+	if gomaxprocs <= 1 {
+		return
+	}
+	gp := getg()
+	if gp == nil || gp.m == nil || gp.m.p == 0 {
+		return
+	}
+	myID := gp.m.p.ptr().id
+	for tries := 0; tries < 5; tries++ {
+		id := int32(fastrandn(uint32(gomaxprocs - 1)))
+		if id >= myID {
+			id++
+		}
+		p := allp[id]
+		if p.status != _Prunning {
+			continue
+		}
+		if preemptone(p) {
+			return
+		}
+	}
+}
+
+// findRunnableGCWorker returns a background mark worker for _p_ if it
+// should be run. This must only be called when gcBlackenEnabled != 0.
+func (c *gcControllerState) findRunnableGCWorker(_p_ *p) *g {
+	if gcBlackenEnabled == 0 {
+		throw("gcControllerState.findRunnable: blackening not enabled")
+	}
+
+	if !gcMarkWorkAvailable(_p_) {
+		// No work to be done right now. This can happen at
+		// the end of the mark phase when there are still
+		// assists tapering off. Don't bother running a worker
+		// now because it'll just return immediately.
+		return nil
+	}
+
+	// Grab a worker before we commit to running below.
+	node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
+	if node == nil {
+		// There is at least one worker per P, so normally there are
+		// enough workers to run on all Ps, if necessary. However, once
+		// a worker enters gcMarkDone it may park without rejoining the
+		// pool, thus freeing a P with no corresponding worker.
+		// gcMarkDone never depends on another worker doing work, so it
+		// is safe to simply do nothing here.
+		//
+		// If gcMarkDone bails out without completing the mark phase,
+		// it will always do so with queued global work. Thus, that P
+		// will be immediately eligible to re-run the worker G it was
+		// just using, ensuring work can complete.
+		return nil
+	}
+
+	decIfPositive := func(ptr *int64) bool {
+		for {
+			v := atomic.Loadint64(ptr)
+			if v <= 0 {
+				return false
+			}
+
+			if atomic.Casint64(ptr, v, v-1) {
+				return true
+			}
+		}
+	}
+
+	if decIfPositive(&c.dedicatedMarkWorkersNeeded) {
+		// 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.
+		gcBgMarkWorkerPool.push(&node.node)
+		return nil
+	} else {
+		// Is this P behind on the fractional utilization
+		// goal?
+		//
+		// This should be kept in sync with pollFractionalWorkerExit.
+		delta := nanotime() - c.markStartTime
+		if delta > 0 && float64(_p_.gcFractionalMarkTime)/float64(delta) > c.fractionalUtilizationGoal {
+			// Nope. No need to run a fractional worker.
+			gcBgMarkWorkerPool.push(&node.node)
+			return nil
+		}
+		// Run a fractional worker.
+		_p_.gcMarkWorkerMode = gcMarkWorkerFractionalMode
+	}
+
+	// Run the background mark worker.
+	gp := node.gp.ptr()
+	casgstatus(gp, _Gwaiting, _Grunnable)
+	if trace.enabled {
+		traceGoUnpark(gp, 0)
+	}
+	return gp
+}
+
+// commit sets the trigger ratio and updates everything
+// derived from it: the absolute trigger, the heap goal, mark pacing,
+// and sweep pacing.
+//
+// This can be called any time. If GC is the in the middle of a
+// concurrent phase, it will adjust the pacing of that phase.
+//
+// This depends on gcPercent, gcController.heapMarked, and
+// gcController.heapLive. These must be up to date.
+//
+// mheap_.lock must be held or the world must be stopped.
+func (c *gcControllerState) commit(triggerRatio float64) {
+	assertWorldStoppedOrLockHeld(&mheap_.lock)
+
+	// Compute the next GC goal, which is when the allocated heap
+	// has grown by GOGC/100 over the heap marked by the last
+	// cycle.
+	goal := ^uint64(0)
+	if c.gcPercent >= 0 {
+		goal = c.heapMarked + c.heapMarked*uint64(c.gcPercent)/100
+	}
+
+	// Set the trigger ratio, capped to reasonable bounds.
+	if c.gcPercent >= 0 {
+		scalingFactor := float64(c.gcPercent) / 100
+		// Ensure there's always a little margin so that the
+		// mutator assist ratio isn't infinity.
+		maxTriggerRatio := 0.95 * scalingFactor
+		if triggerRatio > maxTriggerRatio {
+			triggerRatio = maxTriggerRatio
+		}
+
+		// If we let triggerRatio go too low, then if the application
+		// is allocating very rapidly we might end up in a situation
+		// where we're allocating black during a nearly always-on GC.
+		// The result of this is a growing heap and ultimately an
+		// increase in RSS. By capping us at a point >0, we're essentially
+		// saying that we're OK using more CPU during the GC to prevent
+		// this growth in RSS.
+		//
+		// The current constant was chosen empirically: given a sufficiently
+		// fast/scalable allocator with 48 Ps that could drive the trigger ratio
+		// to <0.05, this constant causes applications to retain the same peak
+		// RSS compared to not having this allocator.
+		minTriggerRatio := 0.6 * scalingFactor
+		if triggerRatio < minTriggerRatio {
+			triggerRatio = minTriggerRatio
+		}
+	} else if triggerRatio < 0 {
+		// gcPercent < 0, so just make sure we're not getting a negative
+		// triggerRatio. This case isn't expected to happen in practice,
+		// and doesn't really matter because if gcPercent < 0 then we won't
+		// ever consume triggerRatio further on in this function, but let's
+		// just be defensive here; the triggerRatio being negative is almost
+		// certainly undesirable.
+		triggerRatio = 0
+	}
+	c.triggerRatio = triggerRatio
+
+	// Compute the absolute GC trigger from the trigger ratio.
+	//
+	// We trigger the next GC cycle when the allocated heap has
+	// grown by the trigger ratio over the marked heap size.
+	trigger := ^uint64(0)
+	if c.gcPercent >= 0 {
+		trigger = uint64(float64(c.heapMarked) * (1 + triggerRatio))
+		// Don't trigger below the minimum heap size.
+		minTrigger := c.heapMinimum
+		if !isSweepDone() {
+			// Concurrent sweep happens in the heap growth
+			// from gcController.heapLive to trigger, so ensure
+			// that concurrent sweep has some heap growth
+			// in which to perform sweeping before we
+			// start the next GC cycle.
+			sweepMin := atomic.Load64(&c.heapLive) + sweepMinHeapDistance
+			if sweepMin > minTrigger {
+				minTrigger = sweepMin
+			}
+		}
+		if trigger < minTrigger {
+			trigger = minTrigger
+		}
+		if int64(trigger) < 0 {
+			print("runtime: heapGoal=", c.heapGoal, " heapMarked=", c.heapMarked, " gcController.heapLive=", c.heapLive, " initialHeapLive=", work.initialHeapLive, "triggerRatio=", triggerRatio, " minTrigger=", minTrigger, "\n")
+			throw("trigger underflow")
+		}
+		if trigger > goal {
+			// The trigger ratio is always less than GOGC/100, but
+			// other bounds on the trigger may have raised it.
+			// Push up the goal, too.
+			goal = trigger
+		}
+	}
+
+	// Commit to the trigger and goal.
+	c.trigger = trigger
+	atomic.Store64(&c.heapGoal, goal)
+	if trace.enabled {
+		traceHeapGoal()
+	}
+
+	// Update mark pacing.
+	if gcphase != _GCoff {
+		c.revise()
+	}
+
+	// Update sweep pacing.
+	if isSweepDone() {
+		mheap_.sweepPagesPerByte = 0
+	} else {
+		// Concurrent sweep needs to sweep all of the in-use
+		// pages by the time the allocated heap reaches the GC
+		// trigger. Compute the ratio of in-use pages to sweep
+		// per byte allocated, accounting for the fact that
+		// some might already be swept.
+		heapLiveBasis := atomic.Load64(&c.heapLive)
+		heapDistance := int64(trigger) - int64(heapLiveBasis)
+		// Add a little margin so rounding errors and
+		// concurrent sweep are less likely to leave pages
+		// unswept when GC starts.
+		heapDistance -= 1024 * 1024
+		if heapDistance < _PageSize {
+			// Avoid setting the sweep ratio extremely high
+			heapDistance = _PageSize
+		}
+		pagesSwept := atomic.Load64(&mheap_.pagesSwept)
+		pagesInUse := atomic.Load64(&mheap_.pagesInUse)
+		sweepDistancePages := int64(pagesInUse) - int64(pagesSwept)
+		if sweepDistancePages <= 0 {
+			mheap_.sweepPagesPerByte = 0
+		} else {
+			mheap_.sweepPagesPerByte = float64(sweepDistancePages) / float64(heapDistance)
+			mheap_.sweepHeapLiveBasis = heapLiveBasis
+			// Write pagesSweptBasis last, since this
+			// signals concurrent sweeps to recompute
+			// their debt.
+			atomic.Store64(&mheap_.pagesSweptBasis, pagesSwept)
+		}
+	}
+
+	gcPaceScavenger()
+}
+
+// effectiveGrowthRatio returns the current effective heap growth
+// ratio (GOGC/100) based on heapMarked from the previous GC and
+// heapGoal for the current GC.
+//
+// This may differ from gcPercent/100 because of various upper and
+// lower bounds on gcPercent. For example, if the heap is smaller than
+// heapMinimum, this can be higher than gcPercent/100.
+//
+// mheap_.lock must be held or the world must be stopped.
+func (c *gcControllerState) effectiveGrowthRatio() float64 {
+	assertWorldStoppedOrLockHeld(&mheap_.lock)
+
+	egogc := float64(atomic.Load64(&c.heapGoal)-c.heapMarked) / float64(c.heapMarked)
+	if egogc < 0 {
+		// Shouldn't happen, but just in case.
+		egogc = 0
+	}
+	return egogc
+}
+
+// setGCPercent updates gcPercent and all related pacer state.
+// Returns the old value of gcPercent.
+//
+// The world must be stopped, or mheap_.lock must be held.
+func (c *gcControllerState) setGCPercent(in int32) int32 {
+	assertWorldStoppedOrLockHeld(&mheap_.lock)
+
+	out := c.gcPercent
+	if in < 0 {
+		in = -1
+	}
+	c.gcPercent = in
+	c.heapMinimum = defaultHeapMinimum * uint64(c.gcPercent) / 100
+	// Update pacing in response to gcPercent change.
+	c.commit(c.triggerRatio)
+
+	return out
+}
+
+//go:linkname setGCPercent runtime/debug.setGCPercent
+func setGCPercent(in int32) (out int32) {
+	// Run on the system stack since we grab the heap lock.
+	systemstack(func() {
+		lock(&mheap_.lock)
+		out = gcController.setGCPercent(in)
+		unlock(&mheap_.lock)
+	})
+
+	// If we just disabled GC, wait for any concurrent GC mark to
+	// finish so we always return with no GC running.
+	if in < 0 {
+		gcWaitOnMark(atomic.Load(&work.cycles))
+	}
+
+	return out
+}
+
+func readGOGC() int32 {
+	p := gogetenv("GOGC")
+	if p == "off" {
+		return -1
+	}
+	if n, ok := atoi32(p); ok {
+		return n
+	}
+	return 100
+}
diff --git a/src/runtime/mgcscavenge.go b/src/runtime/mgcscavenge.go
index a7c5bc4..7578129 100644
--- a/src/runtime/mgcscavenge.go
+++ b/src/runtime/mgcscavenge.go
@@ -18,12 +18,12 @@
 // application down to a goal.
 //
 // That goal is defined as:
-//   (retainExtraPercent+100) / 100 * (next_gc / last_next_gc) * last_heap_inuse
+//   (retainExtraPercent+100) / 100 * (heapGoal / lastHeapGoal) * last_heap_inuse
 //
 // Essentially, we wish to have the application's RSS track the heap goal, but
 // the heap goal is defined in terms of bytes of objects, rather than pages like
 // RSS. As a result, we need to take into account for fragmentation internal to
-// spans. next_gc / last_next_gc defines the ratio between the current heap goal
+// spans. heapGoal / lastHeapGoal defines the ratio between the current heap goal
 // and the last heap goal, which tells us by how much the heap is growing and
 // shrinking. We estimate what the heap will grow to in terms of pages by taking
 // this ratio and multiplying it by heap_inuse at the end of the last GC, which
@@ -118,12 +118,12 @@
 	// We never scavenge before the 2nd GC cycle anyway (we don't have enough
 	// information about the heap yet) so this is fine, and avoids a fault
 	// or garbage data later.
-	if memstats.last_next_gc == 0 {
+	if gcController.lastHeapGoal == 0 {
 		mheap_.scavengeGoal = ^uint64(0)
 		return
 	}
 	// Compute our scavenging goal.
-	goalRatio := float64(atomic.Load64(&memstats.next_gc)) / float64(memstats.last_next_gc)
+	goalRatio := float64(atomic.Load64(&gcController.heapGoal)) / float64(gcController.lastHeapGoal)
 	retainedGoal := uint64(float64(memstats.last_heap_inuse) * goalRatio)
 	// Add retainExtraPercent overhead to retainedGoal. This calculation
 	// looks strange but the purpose is to arrive at an integer division
@@ -207,7 +207,7 @@
 		// Ready the goroutine by injecting it. We use injectglist instead
 		// of ready or goready in order to allow us to run this function
 		// without a P. injectglist also avoids placing the goroutine in
-		// the current P's runnext slot, which is desireable to prevent
+		// the current P's runnext slot, which is desirable to prevent
 		// the scavenger from interfering with user goroutine scheduling
 		// too much.
 		var list gList
@@ -249,7 +249,7 @@
 // The background scavenger maintains the RSS of the application below
 // the line described by the proportional scavenging statistics in
 // the mheap struct.
-func bgscavenge(c chan int) {
+func bgscavenge() {
 	scavenge.g = getg()
 
 	lockInit(&scavenge.lock, lockRankScavenge)
@@ -261,7 +261,7 @@
 		wakeScavenger()
 	}
 
-	c <- 1
+	gcenable_setup <- 1
 	goparkunlock(&scavenge.lock, waitReasonGCScavengeWait, traceEvGoBlock, 1)
 
 	// Exponentially-weighted moving average of the fraction of time this
@@ -372,7 +372,7 @@
 		// Due to OS-related anomalies we may "sleep" for an inordinate amount
 		// of time. Let's avoid letting the ratio get out of hand by bounding
 		// the sleep time we use in our EWMA.
-		const minFraction = 1 / 1000
+		const minFraction = 1.0 / 1000.0
 		if fraction < minFraction {
 			fraction = minFraction
 		}
diff --git a/src/runtime/mgcscavenge_test.go b/src/runtime/mgcscavenge_test.go
index 2503430..3b12a2e 100644
--- a/src/runtime/mgcscavenge_test.go
+++ b/src/runtime/mgcscavenge_test.go
@@ -152,12 +152,6 @@
 			max:   PallocChunkPages,
 			want:  BitRange{0, uint(m)},
 		}
-		tests["StartFree"+suffix] = test{
-			alloc: []BitRange{{uint(m), PallocChunkPages - uint(m)}},
-			min:   m,
-			max:   PallocChunkPages,
-			want:  BitRange{0, uint(m)},
-		}
 		tests["EndFree"+suffix] = test{
 			alloc: []BitRange{{0, PallocChunkPages - uint(m)}},
 			min:   m,
diff --git a/src/runtime/mgcstack.go b/src/runtime/mgcstack.go
index 8eb941a..92d5848 100644
--- a/src/runtime/mgcstack.go
+++ b/src/runtime/mgcstack.go
@@ -150,19 +150,19 @@
 //
 //go:notinheap
 type stackObject struct {
-	off   uint32       // offset above stack.lo
-	size  uint32       // size of object
-	typ   *_type       // type info (for ptr/nonptr bits). nil if object has been scanned.
-	left  *stackObject // objects with lower addresses
-	right *stackObject // objects with higher addresses
+	off   uint32             // offset above stack.lo
+	size  uint32             // size of object
+	r     *stackObjectRecord // info of the object (for ptr/nonptr bits). nil if object has been scanned.
+	left  *stackObject       // objects with lower addresses
+	right *stackObject       // objects with higher addresses
 }
 
-// obj.typ = typ, but with no write barrier.
+// obj.r = r, but with no write barrier.
 //go:nowritebarrier
-func (obj *stackObject) setType(typ *_type) {
+func (obj *stackObject) setRecord(r *stackObjectRecord) {
 	// Types of stack objects are always in read-only memory, not the heap.
 	// So not using a write barrier is ok.
-	*(*uintptr)(unsafe.Pointer(&obj.typ)) = uintptr(unsafe.Pointer(typ))
+	*(*uintptr)(unsafe.Pointer(&obj.r)) = uintptr(unsafe.Pointer(r))
 }
 
 // A stackScanState keeps track of the state used during the GC walk
@@ -271,7 +271,7 @@
 }
 
 // addObject adds a stack object at addr of type typ to the set of stack objects.
-func (s *stackScanState) addObject(addr uintptr, typ *_type) {
+func (s *stackScanState) addObject(addr uintptr, r *stackObjectRecord) {
 	x := s.tail
 	if x == nil {
 		// initial setup
@@ -294,8 +294,8 @@
 	obj := &x.obj[x.nobj]
 	x.nobj++
 	obj.off = uint32(addr - s.stack.lo)
-	obj.size = uint32(typ.size)
-	obj.setType(typ)
+	obj.size = uint32(r.size)
+	obj.setRecord(r)
 	// obj.left and obj.right will be initialized by buildIndex before use.
 	s.nobjs++
 }
diff --git a/src/runtime/mgcsweep.go b/src/runtime/mgcsweep.go
index 76bc424..8fe3a65 100644
--- a/src/runtime/mgcsweep.go
+++ b/src/runtime/mgcsweep.go
@@ -153,13 +153,13 @@
 	nextMarkBitArenaEpoch()
 }
 
-func bgsweep(c chan int) {
+func bgsweep() {
 	sweep.g = getg()
 
 	lockInit(&sweep.lock, lockRankSweep)
 	lock(&sweep.lock)
 	sweep.parked = true
-	c <- 1
+	gcenable_setup <- 1
 	goparkunlock(&sweep.lock, waitReasonGCSweepWait, traceEvGoBlock, 1)
 
 	for {
@@ -183,66 +183,133 @@
 	}
 }
 
+// sweepLocker acquires sweep ownership of spans and blocks sweep
+// completion.
+type sweepLocker struct {
+	// sweepGen is the sweep generation of the heap.
+	sweepGen uint32
+	// blocking indicates that this tracker is blocking sweep
+	// completion, usually as a result of acquiring sweep
+	// ownership of at least one span.
+	blocking bool
+}
+
+// sweepLocked represents sweep ownership of a span.
+type sweepLocked struct {
+	*mspan
+}
+
+func newSweepLocker() sweepLocker {
+	return sweepLocker{
+		sweepGen: mheap_.sweepgen,
+	}
+}
+
+// tryAcquire attempts to acquire sweep ownership of span s. If it
+// successfully acquires ownership, it blocks sweep completion.
+func (l *sweepLocker) tryAcquire(s *mspan) (sweepLocked, bool) {
+	// Check before attempting to CAS.
+	if atomic.Load(&s.sweepgen) != l.sweepGen-2 {
+		return sweepLocked{}, false
+	}
+	// Add ourselves to sweepers before potentially taking
+	// ownership.
+	l.blockCompletion()
+	// Attempt to acquire sweep ownership of s.
+	if !atomic.Cas(&s.sweepgen, l.sweepGen-2, l.sweepGen-1) {
+		return sweepLocked{}, false
+	}
+	return sweepLocked{s}, true
+}
+
+// blockCompletion blocks sweep completion without acquiring any
+// specific spans.
+func (l *sweepLocker) blockCompletion() {
+	if !l.blocking {
+		atomic.Xadd(&mheap_.sweepers, +1)
+		l.blocking = true
+	}
+}
+
+func (l *sweepLocker) dispose() {
+	if !l.blocking {
+		return
+	}
+	// Decrement the number of active sweepers and if this is the
+	// last one, mark sweep as complete.
+	l.blocking = false
+	if atomic.Xadd(&mheap_.sweepers, -1) == 0 && atomic.Load(&mheap_.sweepDrained) != 0 {
+		l.sweepIsDone()
+	}
+}
+
+func (l *sweepLocker) sweepIsDone() {
+	if debug.gcpacertrace > 0 {
+		print("pacer: sweep done at heap size ", gcController.heapLive>>20, "MB; allocated ", (gcController.heapLive-mheap_.sweepHeapLiveBasis)>>20, "MB during sweep; swept ", mheap_.pagesSwept, " pages at ", mheap_.sweepPagesPerByte, " pages/byte\n")
+	}
+}
+
 // sweepone sweeps some unswept heap span and returns the number of pages returned
 // to the heap, or ^uintptr(0) if there was nothing to sweep.
 func sweepone() uintptr {
 	_g_ := getg()
-	sweepRatio := mheap_.sweepPagesPerByte // For debugging
 
 	// increment locks to ensure that the goroutine is not preempted
 	// in the middle of sweep thus leaving the span in an inconsistent state for next GC
 	_g_.m.locks++
-	if atomic.Load(&mheap_.sweepdone) != 0 {
+	if atomic.Load(&mheap_.sweepDrained) != 0 {
 		_g_.m.locks--
 		return ^uintptr(0)
 	}
-	atomic.Xadd(&mheap_.sweepers, +1)
+	// TODO(austin): sweepone is almost always called in a loop;
+	// lift the sweepLocker into its callers.
+	sl := newSweepLocker()
 
 	// Find a span to sweep.
-	var s *mspan
-	sg := mheap_.sweepgen
+	npages := ^uintptr(0)
+	var noMoreWork bool
 	for {
-		s = mheap_.nextSpanForSweep()
+		s := mheap_.nextSpanForSweep()
 		if s == nil {
-			atomic.Store(&mheap_.sweepdone, 1)
+			noMoreWork = atomic.Cas(&mheap_.sweepDrained, 0, 1)
 			break
 		}
 		if state := s.state.get(); state != mSpanInUse {
 			// This can happen if direct sweeping already
 			// swept this span, but in that case the sweep
 			// generation should always be up-to-date.
-			if !(s.sweepgen == sg || s.sweepgen == sg+3) {
-				print("runtime: bad span s.state=", state, " s.sweepgen=", s.sweepgen, " sweepgen=", sg, "\n")
+			if !(s.sweepgen == sl.sweepGen || s.sweepgen == sl.sweepGen+3) {
+				print("runtime: bad span s.state=", state, " s.sweepgen=", s.sweepgen, " sweepgen=", sl.sweepGen, "\n")
 				throw("non in-use span in unswept list")
 			}
 			continue
 		}
-		if s.sweepgen == sg-2 && atomic.Cas(&s.sweepgen, sg-2, sg-1) {
+		if s, ok := sl.tryAcquire(s); ok {
+			// Sweep the span we found.
+			npages = s.npages
+			if s.sweep(false) {
+				// Whole span was freed. Count it toward the
+				// page reclaimer credit since these pages can
+				// now be used for span allocation.
+				atomic.Xadduintptr(&mheap_.reclaimCredit, npages)
+			} else {
+				// Span is still in-use, so this returned no
+				// pages to the heap and the span needs to
+				// move to the swept in-use list.
+				npages = 0
+			}
 			break
 		}
 	}
 
-	// Sweep the span we found.
-	npages := ^uintptr(0)
-	if s != nil {
-		npages = s.npages
-		if s.sweep(false) {
-			// Whole span was freed. Count it toward the
-			// page reclaimer credit since these pages can
-			// now be used for span allocation.
-			atomic.Xadduintptr(&mheap_.reclaimCredit, npages)
-		} else {
-			// Span is still in-use, so this returned no
-			// pages to the heap and the span needs to
-			// move to the swept in-use list.
-			npages = 0
-		}
-	}
+	sl.dispose()
 
-	// Decrement the number of active sweepers and if this is the
-	// last one print trace information.
-	if atomic.Xadd(&mheap_.sweepers, -1) == 0 && atomic.Load(&mheap_.sweepdone) != 0 {
-		// Since the sweeper is done, move the scavenge gen forward (signalling
+	if noMoreWork {
+		// The sweep list is empty. There may still be
+		// concurrent sweeps running, but we're at least very
+		// close to done sweeping.
+
+		// Move the scavenge gen forward (signalling
 		// that there's new work to do) and wake the scavenger.
 		//
 		// The scavenger is signaled by the last sweeper because once
@@ -262,23 +329,23 @@
 		// for us to wake the scavenger directly via wakeScavenger, since
 		// it could allocate. Ask sysmon to do it for us instead.
 		readyForScavenger()
-
-		if debug.gcpacertrace > 0 {
-			print("pacer: sweep done at heap size ", memstats.heap_live>>20, "MB; allocated ", (memstats.heap_live-mheap_.sweepHeapLiveBasis)>>20, "MB during sweep; swept ", mheap_.pagesSwept, " pages at ", sweepRatio, " pages/byte\n")
-		}
 	}
+
 	_g_.m.locks--
 	return npages
 }
 
-// isSweepDone reports whether all spans are swept or currently being swept.
+// isSweepDone reports whether all spans are swept.
 //
 // Note that this condition may transition from false to true at any
 // time as the sweeper runs. It may transition from true to false if a
 // GC runs; to prevent that the caller must be non-preemptible or must
 // somehow block GC progress.
 func isSweepDone() bool {
-	return mheap_.sweepdone != 0
+	// Check that all spans have at least begun sweeping and there
+	// are no active sweepers. If both are true, then all spans
+	// have finished sweeping.
+	return atomic.Load(&mheap_.sweepDrained) != 0 && atomic.Load(&mheap_.sweepers) == 0
 }
 
 // Returns only when span s has been swept.
@@ -292,20 +359,19 @@
 		throw("mspan.ensureSwept: m is not locked")
 	}
 
-	sg := mheap_.sweepgen
-	spangen := atomic.Load(&s.sweepgen)
-	if spangen == sg || spangen == sg+3 {
-		return
-	}
+	sl := newSweepLocker()
 	// The caller must be sure that the span is a mSpanInUse span.
-	if atomic.Cas(&s.sweepgen, sg-2, sg-1) {
+	if s, ok := sl.tryAcquire(s); ok {
 		s.sweep(false)
+		sl.dispose()
 		return
 	}
+	sl.dispose()
+
 	// unfortunate condition, and we don't have efficient means to wait
 	for {
 		spangen := atomic.Load(&s.sweepgen)
-		if spangen == sg || spangen == sg+3 {
+		if spangen == sl.sweepGen || spangen == sl.sweepGen+3 {
 			break
 		}
 		osyield()
@@ -317,13 +383,21 @@
 // Returns true if the span was returned to heap.
 // If preserve=true, don't return it to heap nor relink in mcentral lists;
 // caller takes care of it.
-func (s *mspan) sweep(preserve bool) bool {
+func (sl *sweepLocked) sweep(preserve bool) bool {
 	// It's critical that we enter this function with preemption disabled,
 	// GC must not start while we are in the middle of this function.
 	_g_ := getg()
 	if _g_.m.locks == 0 && _g_.m.mallocing == 0 && _g_ != _g_.m.g0 {
 		throw("mspan.sweep: m is not locked")
 	}
+
+	s := sl.mspan
+	if !preserve {
+		// We'll release ownership of this span. Nil it out to
+		// prevent the caller from accidentally using it.
+		sl.mspan = nil
+	}
+
 	sweepgen := mheap_.sweepgen
 	if state := s.state.get(); state != mSpanInUse || s.sweepgen != sweepgen-1 {
 		print("mspan.sweep: state=", state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n")
@@ -356,11 +430,10 @@
 	//    If such object is not marked, we need to queue all finalizers at once.
 	// Both 1 and 2 are possible at the same time.
 	hadSpecials := s.specials != nil
-	specialp := &s.specials
-	special := *specialp
-	for special != nil {
+	siter := newSpecialsIter(s)
+	for siter.valid() {
 		// A finalizer can be set for an inner byte of an object, find object beginning.
-		objIndex := uintptr(special.offset) / size
+		objIndex := uintptr(siter.s.offset) / size
 		p := s.base() + objIndex*size
 		mbits := s.markBitsForIndex(objIndex)
 		if !mbits.isMarked() {
@@ -368,7 +441,7 @@
 			// Pass 1: see if it has at least one finalizer.
 			hasFin := false
 			endOffset := p - s.base() + size
-			for tmp := special; tmp != nil && uintptr(tmp.offset) < endOffset; tmp = tmp.next {
+			for tmp := siter.s; tmp != nil && uintptr(tmp.offset) < endOffset; tmp = tmp.next {
 				if tmp.kind == _KindSpecialFinalizer {
 					// Stop freeing of object if it has a finalizer.
 					mbits.setMarkedNonAtomic()
@@ -377,27 +450,31 @@
 				}
 			}
 			// Pass 2: queue all finalizers _or_ handle profile record.
-			for special != nil && uintptr(special.offset) < endOffset {
+			for siter.valid() && uintptr(siter.s.offset) < endOffset {
 				// Find the exact byte for which the special was setup
 				// (as opposed to object beginning).
+				special := siter.s
 				p := s.base() + uintptr(special.offset)
 				if special.kind == _KindSpecialFinalizer || !hasFin {
-					// Splice out special record.
-					y := special
-					special = special.next
-					*specialp = special
-					freespecial(y, unsafe.Pointer(p), size)
+					siter.unlinkAndNext()
+					freeSpecial(special, unsafe.Pointer(p), size)
 				} else {
-					// This is profile record, but the object has finalizers (so kept alive).
-					// Keep special record.
-					specialp = &special.next
-					special = *specialp
+					// The object has finalizers, so we're keeping it alive.
+					// All other specials only apply when an object is freed,
+					// so just keep the special record.
+					siter.next()
 				}
 			}
 		} else {
-			// object is still live: keep special record
-			specialp = &special.next
-			special = *specialp
+			// object is still live
+			if siter.s.kind == _KindSpecialReachable {
+				special := siter.unlinkAndNext()
+				(*specialReachable)(unsafe.Pointer(special)).reachable = true
+				freeSpecial(special, unsafe.Pointer(p), size)
+			} else {
+				// keep special record
+				siter.next()
+			}
 		}
 	}
 	if hadSpecials && s.specials == nil {
@@ -645,7 +722,7 @@
 	sweptBasis := atomic.Load64(&mheap_.pagesSweptBasis)
 
 	// Fix debt if necessary.
-	newHeapLive := uintptr(atomic.Load64(&memstats.heap_live)-mheap_.sweepHeapLiveBasis) + spanBytes
+	newHeapLive := uintptr(atomic.Load64(&gcController.heapLive)-mheap_.sweepHeapLiveBasis) + spanBytes
 	pagesTarget := int64(mheap_.sweepPagesPerByte*float64(newHeapLive)) - int64(callerSweepPages)
 	for pagesTarget > int64(atomic.Load64(&mheap_.pagesSwept)-sweptBasis) {
 		if sweepone() == ^uintptr(0) {
diff --git a/src/runtime/mgcwork.go b/src/runtime/mgcwork.go
index b3a0686..667c7af 100644
--- a/src/runtime/mgcwork.go
+++ b/src/runtime/mgcwork.go
@@ -398,7 +398,7 @@
 }
 
 // putempty puts a workbuf onto the work.empty list.
-// Upon entry this go routine owns b. The lfstack.push relinquishes ownership.
+// Upon entry this goroutine owns b. The lfstack.push relinquishes ownership.
 //go:nowritebarrier
 func putempty(b *workbuf) {
 	b.checkempty()
diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go
index 1855330..84c00ce 100644
--- a/src/runtime/mheap.go
+++ b/src/runtime/mheap.go
@@ -62,11 +62,12 @@
 type mheap struct {
 	// lock must only be acquired on the system stack, otherwise a g
 	// could self-deadlock if its stack grows with the lock held.
-	lock      mutex
-	pages     pageAlloc // page allocation data structure
-	sweepgen  uint32    // sweep generation, see comment in mspan; written during STW
-	sweepdone uint32    // all spans are swept
-	sweepers  uint32    // number of active sweepone calls
+	lock  mutex
+	pages pageAlloc // page allocation data structure
+
+	sweepgen     uint32 // sweep generation, see comment in mspan; written during STW
+	sweepDrained uint32 // all spans are swept or are being swept
+	sweepers     uint32 // number of active sweepone calls
 
 	// allspans is a slice of all mspans ever created. Each mspan
 	// appears exactly once.
@@ -85,14 +86,14 @@
 
 	// Proportional sweep
 	//
-	// These parameters represent a linear function from heap_live
+	// These parameters represent a linear function from gcController.heapLive
 	// to page sweep count. The proportional sweep system works to
 	// stay in the black by keeping the current page sweep count
-	// above this line at the current heap_live.
+	// above this line at the current gcController.heapLive.
 	//
 	// The line has slope sweepPagesPerByte and passes through a
 	// basis point at (sweepHeapLiveBasis, pagesSweptBasis). At
-	// any given time, the system is at (memstats.heap_live,
+	// any given time, the system is at (gcController.heapLive,
 	// pagesSwept) in this space.
 	//
 	// It's important that the line pass through a point we
@@ -104,7 +105,7 @@
 	pagesInUse         uint64  // pages of spans in stats mSpanInUse; updated atomically
 	pagesSwept         uint64  // pages swept this cycle; updated atomically
 	pagesSweptBasis    uint64  // pagesSwept to use as the origin of the sweep ratio; updated atomically
-	sweepHeapLiveBasis uint64  // value of heap_live to use as the origin of sweep ratio; written with lock, read without
+	sweepHeapLiveBasis uint64  // value of gcController.heapLive to use as the origin of sweep ratio; written with lock, read without
 	sweepPagesPerByte  float64 // proportional sweep ratio; written with lock, read without
 	// TODO(austin): pagesInUse should be a uintptr, but the 386
 	// compiler can't 8-byte align fields.
@@ -212,6 +213,7 @@
 	cachealloc            fixalloc // allocator for mcache*
 	specialfinalizeralloc fixalloc // allocator for specialfinalizer*
 	specialprofilealloc   fixalloc // allocator for specialprofile*
+	specialReachableAlloc fixalloc // allocator for specialReachable
 	speciallock           mutex    // lock for special record allocators.
 	arenaHintAlloc        fixalloc // allocator for arenaHints
 
@@ -451,14 +453,11 @@
 	// h->sweepgen is incremented by 2 after every GC
 
 	sweepgen    uint32
-	divMul      uint16        // for divide by elemsize - divMagic.mul
-	baseMask    uint16        // if non-0, elemsize is a power of 2, & this will get object allocation base
+	divMul      uint32        // for divide by elemsize
 	allocCount  uint16        // number of allocated objects
 	spanclass   spanClass     // size class and noscan (uint8)
 	state       mSpanStateBox // mSpanInUse etc; accessed atomically (get/set methods)
 	needzero    uint8         // needs to be zeroed before allocation
-	divShift    uint8         // for divide by elemsize - divMagic.shift
-	divShift2   uint8         // for divide by elemsize - divMagic.shift2
 	elemsize    uintptr       // computed from sizeclass or from npages
 	limit       uintptr       // end of data in span
 	speciallock mutex         // guards specials list
@@ -706,6 +705,7 @@
 	h.cachealloc.init(unsafe.Sizeof(mcache{}), nil, nil, &memstats.mcache_sys)
 	h.specialfinalizeralloc.init(unsafe.Sizeof(specialfinalizer{}), nil, nil, &memstats.other_sys)
 	h.specialprofilealloc.init(unsafe.Sizeof(specialprofile{}), nil, nil, &memstats.other_sys)
+	h.specialReachableAlloc.init(unsafe.Sizeof(specialReachable{}), nil, nil, &memstats.other_sys)
 	h.arenaHintAlloc.init(unsafe.Sizeof(arenaHint{}), nil, nil, &memstats.other_sys)
 
 	// Don't zero mspan allocations. Background sweeping can
@@ -818,7 +818,7 @@
 
 	n0 := n
 	var nFreed uintptr
-	sg := h.sweepgen
+	sl := newSweepLocker()
 	for n > 0 {
 		ai := arenas[pageIdx/pagesPerArena]
 		ha := h.arenas[ai.l1()][ai.l2()]
@@ -843,7 +843,7 @@
 			for j := uint(0); j < 8; j++ {
 				if inUseUnmarked&(1<<j) != 0 {
 					s := ha.spans[arenaPage+uint(i)*8+j]
-					if atomic.Load(&s.sweepgen) == sg-2 && atomic.Cas(&s.sweepgen, sg-2, sg-1) {
+					if s, ok := sl.tryAcquire(s); ok {
 						npages := s.npages
 						unlock(&h.lock)
 						if s.sweep(false) {
@@ -864,6 +864,7 @@
 		pageIdx += uintptr(len(inUse) * 8)
 		n -= uintptr(len(inUse) * 8)
 	}
+	sl.dispose()
 	if trace.enabled {
 		unlock(&h.lock)
 		// Account for pages scanned but not reclaimed.
@@ -896,7 +897,9 @@
 // spanclass indicates the span's size class and scannability.
 //
 // If needzero is true, the memory for the returned span will be zeroed.
-func (h *mheap) alloc(npages uintptr, spanclass spanClass, needzero bool) *mspan {
+// The boolean returned indicates whether the returned span contains zeroes,
+// either because this was requested, or because it was already zeroed.
+func (h *mheap) alloc(npages uintptr, spanclass spanClass, needzero bool) (*mspan, bool) {
 	// Don't do any operations that lock the heap on the G stack.
 	// It might trigger stack growth, and the stack growth code needs
 	// to be able to allocate heap.
@@ -904,19 +907,22 @@
 	systemstack(func() {
 		// To prevent excessive heap growth, before allocating n pages
 		// we need to sweep and reclaim at least n pages.
-		if h.sweepdone == 0 {
+		if !isSweepDone() {
 			h.reclaim(npages)
 		}
 		s = h.allocSpan(npages, spanAllocHeap, spanclass)
 	})
 
-	if s != nil {
-		if needzero && s.needzero != 0 {
-			memclrNoHeapPointers(unsafe.Pointer(s.base()), s.npages<<_PageShift)
-		}
-		s.needzero = 0
+	if s == nil {
+		return nil, false
 	}
-	return s
+	isZeroed := s.needzero == 0
+	if needzero && !isZeroed {
+		memclrNoHeapPointers(unsafe.Pointer(s.base()), s.npages<<_PageShift)
+		isZeroed = true
+	}
+	s.needzero = 0
+	return s, isZeroed
 }
 
 // allocManual allocates a manually-managed span of npage pages.
@@ -1224,20 +1230,11 @@
 		if sizeclass := spanclass.sizeclass(); sizeclass == 0 {
 			s.elemsize = nbytes
 			s.nelems = 1
-
-			s.divShift = 0
 			s.divMul = 0
-			s.divShift2 = 0
-			s.baseMask = 0
 		} else {
 			s.elemsize = uintptr(class_to_size[sizeclass])
 			s.nelems = nbytes / s.elemsize
-
-			m := &class_to_divmagic[sizeclass]
-			s.divShift = m.shift
-			s.divMul = m.mul
-			s.divShift2 = m.shift2
-			s.baseMask = m.baseMask
+			s.divMul = class_to_divmagic[sizeclass]
 		}
 
 		// Initialize mark and allocation structures.
@@ -1332,6 +1329,10 @@
 	assertLockHeld(&h.lock)
 
 	// We must grow the heap in whole palloc chunks.
+	// We call sysMap below but note that because we
+	// round up to pallocChunkPages which is on the order
+	// of MiB (generally >= to the huge page size) we
+	// won't be calling it too much.
 	ask := alignUp(npage, pallocChunkPages) * pageSize
 
 	totalGrowth := uintptr(0)
@@ -1358,6 +1359,17 @@
 			// remains of the current space and switch to
 			// the new space. This should be rare.
 			if size := h.curArena.end - h.curArena.base; size != 0 {
+				// Transition this space from Reserved to Prepared and mark it
+				// as released since we'll be able to start using it after updating
+				// the page allocator and releasing the lock at any time.
+				sysMap(unsafe.Pointer(h.curArena.base), size, &memstats.heap_sys)
+				// Update stats.
+				atomic.Xadd64(&memstats.heap_released, int64(size))
+				stats := memstats.heapStats.acquire()
+				atomic.Xaddint64(&stats.released, int64(size))
+				memstats.heapStats.release()
+				// Update the page allocator's structures to make this
+				// space ready for allocation.
 				h.pages.grow(h.curArena.base, size)
 				totalGrowth += size
 			}
@@ -1366,17 +1378,6 @@
 			h.curArena.end = uintptr(av) + asize
 		}
 
-		// The memory just allocated counts as both released
-		// and idle, even though it's not yet backed by spans.
-		//
-		// The allocation is always aligned to the heap arena
-		// size which is always > physPageSize, so its safe to
-		// just add directly to heap_released.
-		atomic.Xadd64(&memstats.heap_released, int64(asize))
-		stats := memstats.heapStats.acquire()
-		atomic.Xaddint64(&stats.released, int64(asize))
-		memstats.heapStats.release()
-
 		// Recalculate nBase.
 		// We know this won't overflow, because sysAlloc returned
 		// a valid region starting at h.curArena.base which is at
@@ -1387,6 +1388,23 @@
 	// Grow into the current arena.
 	v := h.curArena.base
 	h.curArena.base = nBase
+
+	// Transition the space we're going to use from Reserved to Prepared.
+	sysMap(unsafe.Pointer(v), nBase-v, &memstats.heap_sys)
+
+	// The memory just allocated counts as both released
+	// and idle, even though it's not yet backed by spans.
+	//
+	// The allocation is always aligned to the heap arena
+	// size which is always > physPageSize, so its safe to
+	// just add directly to heap_released.
+	atomic.Xadd64(&memstats.heap_released, int64(nBase-v))
+	stats := memstats.heapStats.acquire()
+	atomic.Xaddint64(&stats.released, int64(nBase-v))
+	memstats.heapStats.release()
+
+	// Update the page allocator's structures to make this
+	// space ready for allocation.
 	h.pages.grow(v, nBase-v)
 	totalGrowth += nBase - v
 
@@ -1640,6 +1658,9 @@
 const (
 	_KindSpecialFinalizer = 1
 	_KindSpecialProfile   = 2
+	// _KindSpecialReachable is a special used for tracking
+	// reachability during testing.
+	_KindSpecialReachable = 3
 	// Note: The finalizer special must be first because if we're freeing
 	// an object, a finalizer special will cause the freeing operation
 	// to abort, and we want to keep the other special records around
@@ -1845,9 +1866,45 @@
 	}
 }
 
-// Do whatever cleanup needs to be done to deallocate s. It has
-// already been unlinked from the mspan specials list.
-func freespecial(s *special, p unsafe.Pointer, size uintptr) {
+// specialReachable tracks whether an object is reachable on the next
+// GC cycle. This is used by testing.
+type specialReachable struct {
+	special   special
+	done      bool
+	reachable bool
+}
+
+// specialsIter helps iterate over specials lists.
+type specialsIter struct {
+	pprev **special
+	s     *special
+}
+
+func newSpecialsIter(span *mspan) specialsIter {
+	return specialsIter{&span.specials, span.specials}
+}
+
+func (i *specialsIter) valid() bool {
+	return i.s != nil
+}
+
+func (i *specialsIter) next() {
+	i.pprev = &i.s.next
+	i.s = *i.pprev
+}
+
+// unlinkAndNext removes the current special from the list and moves
+// the iterator to the next special. It returns the unlinked special.
+func (i *specialsIter) unlinkAndNext() *special {
+	cur := i.s
+	i.s = cur.next
+	*i.pprev = i.s
+	return cur
+}
+
+// freeSpecial performs any cleanup on special s and deallocates it.
+// s must already be unlinked from the specials list.
+func freeSpecial(s *special, p unsafe.Pointer, size uintptr) {
 	switch s.kind {
 	case _KindSpecialFinalizer:
 		sf := (*specialfinalizer)(unsafe.Pointer(s))
@@ -1861,6 +1918,10 @@
 		lock(&mheap_.speciallock)
 		mheap_.specialprofilealloc.free(unsafe.Pointer(sp))
 		unlock(&mheap_.speciallock)
+	case _KindSpecialReachable:
+		sp := (*specialReachable)(unsafe.Pointer(s))
+		sp.done = true
+		// The creator frees these.
 	default:
 		throw("bad special kind")
 		panic("not reached")
diff --git a/src/runtime/mkduff.go b/src/runtime/mkduff.go
index 94ae75f..da191cc 100644
--- a/src/runtime/mkduff.go
+++ b/src/runtime/mkduff.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // runtime·duffzero is a Duff's device for zeroing memory.
@@ -62,15 +63,15 @@
 func notags(w io.Writer) { fmt.Fprintln(w) }
 
 func zeroAMD64(w io.Writer) {
-	// X0: zero
+	// X15: zero
 	// DI: ptr to memory to be zeroed
 	// DI is updated as a side effect.
-	fmt.Fprintln(w, "TEXT runtime·duffzero(SB), NOSPLIT, $0-0")
+	fmt.Fprintln(w, "TEXT runtime·duffzero<ABIInternal>(SB), NOSPLIT, $0-0")
 	for i := 0; i < 16; i++ {
-		fmt.Fprintln(w, "\tMOVUPS\tX0,(DI)")
-		fmt.Fprintln(w, "\tMOVUPS\tX0,16(DI)")
-		fmt.Fprintln(w, "\tMOVUPS\tX0,32(DI)")
-		fmt.Fprintln(w, "\tMOVUPS\tX0,48(DI)")
+		fmt.Fprintln(w, "\tMOVUPS\tX15,(DI)")
+		fmt.Fprintln(w, "\tMOVUPS\tX15,16(DI)")
+		fmt.Fprintln(w, "\tMOVUPS\tX15,32(DI)")
+		fmt.Fprintln(w, "\tMOVUPS\tX15,48(DI)")
 		fmt.Fprintln(w, "\tLEAQ\t64(DI),DI") // We use lea instead of add, to avoid clobbering flags
 		fmt.Fprintln(w)
 	}
@@ -84,7 +85,7 @@
 	//
 	// This is equivalent to a sequence of MOVSQ but
 	// for some reason that is 3.5x slower than this code.
-	fmt.Fprintln(w, "TEXT runtime·duffcopy(SB), NOSPLIT, $0-0")
+	fmt.Fprintln(w, "TEXT runtime·duffcopy<ABIInternal>(SB), NOSPLIT, $0-0")
 	for i := 0; i < 64; i++ {
 		fmt.Fprintln(w, "\tMOVUPS\t(SI), X0")
 		fmt.Fprintln(w, "\tADDQ\t$16, SI")
@@ -178,6 +179,7 @@
 
 func tagsPPC64x(w io.Writer) {
 	fmt.Fprintln(w)
+	fmt.Fprintln(w, "//go:build ppc64 || ppc64le")
 	fmt.Fprintln(w, "// +build ppc64 ppc64le")
 	fmt.Fprintln(w)
 }
@@ -201,6 +203,7 @@
 
 func tagsMIPS64x(w io.Writer) {
 	fmt.Fprintln(w)
+	fmt.Fprintln(w, "//go:build mips64 || mips64le")
 	fmt.Fprintln(w, "// +build mips64 mips64le")
 	fmt.Fprintln(w)
 }
diff --git a/src/runtime/mkfastlog2table.go b/src/runtime/mkfastlog2table.go
index d650292..8d78a39 100644
--- a/src/runtime/mkfastlog2table.go
+++ b/src/runtime/mkfastlog2table.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // fastlog2Table contains log2 approximations for 5 binary digits.
diff --git a/src/runtime/mkpreempt.go b/src/runtime/mkpreempt.go
index 1d614dd..6c98054 100644
--- a/src/runtime/mkpreempt.go
+++ b/src/runtime/mkpreempt.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // mkpreempt generates the asyncPreempt functions for each
@@ -122,6 +123,7 @@
 	fmt.Fprintf(out, "// Code generated by mkpreempt.go; DO NOT EDIT.\n\n")
 	if beLe[arch] {
 		base := arch[:len(arch)-1]
+		fmt.Fprintf(out, "//go:build %s || %sle\n", base, base)
 		fmt.Fprintf(out, "// +build %s %sle\n\n", base, base)
 	}
 	fmt.Fprintf(out, "#include \"go_asm.h\"\n")
@@ -229,12 +231,16 @@
 		if reg == "SP" || reg == "BP" {
 			continue
 		}
-		if strings.HasPrefix(reg, "X") {
-			l.add("MOVUPS", reg, 16)
-		} else {
+		if !strings.HasPrefix(reg, "X") {
 			l.add("MOVQ", reg, 8)
 		}
 	}
+	lSSE := layout{stack: l.stack, sp: "SP"}
+	for _, reg := range regNamesAMD64 {
+		if strings.HasPrefix(reg, "X") {
+			lSSE.add("MOVUPS", reg, 16)
+		}
+	}
 
 	// TODO: MXCSR register?
 
@@ -243,10 +249,12 @@
 	p("// Save flags before clobbering them")
 	p("PUSHFQ")
 	p("// obj doesn't understand ADD/SUB on SP, but does understand ADJSP")
-	p("ADJSP $%d", l.stack)
+	p("ADJSP $%d", lSSE.stack)
 	p("// But vet doesn't know ADJSP, so suppress vet stack checking")
 	p("NOP SP")
 
+	l.save()
+
 	// Apparently, the signal handling code path in darwin kernel leaves
 	// the upper bits of Y registers in a dirty state, which causes
 	// many SSE operations (128-bit and narrower) become much slower.
@@ -258,10 +266,11 @@
 	p("VZEROUPPER")
 	p("#endif")
 
-	l.save()
+	lSSE.save()
 	p("CALL ·asyncPreempt2(SB)")
+	lSSE.restore()
 	l.restore()
-	p("ADJSP $%d", -l.stack)
+	p("ADJSP $%d", -lSSE.stack)
 	p("POPFQ")
 	p("POPQ BP")
 	p("RET")
diff --git a/src/runtime/mksizeclasses.go b/src/runtime/mksizeclasses.go
index b92d1fe..b1b10e9 100644
--- a/src/runtime/mksizeclasses.go
+++ b/src/runtime/mksizeclasses.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // Generate tables for small malloc size classes.
@@ -36,6 +37,8 @@
 	"go/format"
 	"io"
 	"log"
+	"math"
+	"math/bits"
 	"os"
 )
 
@@ -86,11 +89,6 @@
 type class struct {
 	size   int // max size
 	npages int // number of pages
-
-	mul    int
-	shift  uint
-	shift2 uint
-	mask   int
 }
 
 func powerOfTwo(x int) bool {
@@ -167,9 +165,9 @@
 	return classes
 }
 
-// computeDivMagic computes some magic constants to implement
-// the division required to compute object number from span offset.
-// n / c.size is implemented as n >> c.shift * c.mul >> c.shift2
+// computeDivMagic checks that the division required to compute object
+// index from span offset can be computed using 32-bit multiplication.
+// n / c.size is implemented as (n * (^uint32(0)/uint32(c.size) + 1)) >> 32
 // for all 0 <= n <= c.npages * pageSize
 func computeDivMagic(c *class) {
 	// divisor
@@ -181,68 +179,67 @@
 	// maximum input value for which the formula needs to work.
 	max := c.npages * pageSize
 
+	// As reported in [1], if n and d are unsigned N-bit integers, we
+	// can compute n / d as ⌊n * c / 2^F⌋, where c is ⌈2^F / d⌉ and F is
+	// computed with:
+	//
+	// 	Algorithm 2: Algorithm to select the number of fractional bits
+	// 	and the scaled approximate reciprocal in the case of unsigned
+	// 	integers.
+	//
+	// 	if d is a power of two then
+	// 		Let F ← log₂(d) and c = 1.
+	// 	else
+	// 		Let F ← N + L where L is the smallest integer
+	// 		such that d ≤ (2^(N+L) mod d) + 2^L.
+	// 	end if
+	//
+	// [1] "Faster Remainder by Direct Computation: Applications to
+	// Compilers and Software Libraries" Daniel Lemire, Owen Kaser,
+	// Nathan Kurz arXiv:1902.01961
+	//
+	// To minimize the risk of introducing errors, we implement the
+	// algorithm exactly as stated, rather than trying to adapt it to
+	// fit typical Go idioms.
+	N := bits.Len(uint(max))
+	var F int
 	if powerOfTwo(d) {
-		// If the size is a power of two, heapBitsForObject can divide even faster by masking.
-		// Compute this mask.
-		if max >= 1<<16 {
-			panic("max too big for power of two size")
+		F = int(math.Log2(float64(d)))
+		if d != 1<<F {
+			panic("imprecise log2")
 		}
-		c.mask = 1<<16 - d
-	}
-
-	// Compute pre-shift by factoring power of 2 out of d.
-	for d%2 == 0 {
-		c.shift++
-		d >>= 1
-		max >>= 1
-	}
-
-	// Find the smallest k that works.
-	// A small k allows us to fit the math required into 32 bits
-	// so we can use 32-bit multiplies and shifts on 32-bit platforms.
-nextk:
-	for k := uint(0); ; k++ {
-		mul := (int(1)<<k + d - 1) / d //  ⌈2^k / d⌉
-
-		// Test to see if mul works.
-		for n := 0; n <= max; n++ {
-			if n*mul>>k != n/d {
-				continue nextk
+	} else {
+		for L := 0; ; L++ {
+			if d <= ((1<<(N+L))%d)+(1<<L) {
+				F = N + L
+				break
 			}
 		}
-		if mul >= 1<<16 {
-			panic("mul too big")
-		}
-		if uint64(mul)*uint64(max) >= 1<<32 {
-			panic("mul*max too big")
-		}
-		c.mul = mul
-		c.shift2 = k
-		break
 	}
 
-	// double-check.
+	// Also, noted in the paper, F is the smallest number of fractional
+	// bits required. We use 32 bits, because it works for all size
+	// classes and is fast on all CPU architectures that we support.
+	if F > 32 {
+		fmt.Printf("d=%d max=%d N=%d F=%d\n", c.size, max, N, F)
+		panic("size class requires more than 32 bits of precision")
+	}
+
+	// Brute force double-check with the exact computation that will be
+	// done by the runtime.
+	m := ^uint32(0)/uint32(c.size) + 1
 	for n := 0; n <= max; n++ {
-		if n*c.mul>>c.shift2 != n/d {
-			fmt.Printf("d=%d max=%d mul=%d shift2=%d n=%d\n", d, max, c.mul, c.shift2, n)
-			panic("bad multiply magic")
-		}
-		// Also check the exact computations that will be done by the runtime,
-		// for both 32 and 64 bit operations.
-		if uint32(n)*uint32(c.mul)>>uint8(c.shift2) != uint32(n/d) {
-			fmt.Printf("d=%d max=%d mul=%d shift2=%d n=%d\n", d, max, c.mul, c.shift2, n)
+		if uint32((uint64(n)*uint64(m))>>32) != uint32(n/c.size) {
+			fmt.Printf("d=%d max=%d m=%d n=%d\n", d, max, m, n)
 			panic("bad 32-bit multiply magic")
 		}
-		if uint64(n)*uint64(c.mul)>>uint8(c.shift2) != uint64(n/d) {
-			fmt.Printf("d=%d max=%d mul=%d shift2=%d n=%d\n", d, max, c.mul, c.shift2, n)
-			panic("bad 64-bit multiply magic")
-		}
 	}
 }
 
 func printComment(w io.Writer, classes []class) {
-	fmt.Fprintf(w, "// %-5s  %-9s  %-10s  %-7s  %-10s  %-9s\n", "class", "bytes/obj", "bytes/span", "objects", "tail waste", "max waste")
+	fmt.Fprintf(w, "// %-5s  %-9s  %-10s  %-7s  %-10s  %-9s  %-9s\n", "class", "bytes/obj", "bytes/span", "objects", "tail waste", "max waste", "min align")
 	prevSize := 0
+	var minAligns [pageShift + 1]int
 	for i, c := range classes {
 		if i == 0 {
 			continue
@@ -251,8 +248,32 @@
 		objects := spanSize / c.size
 		tailWaste := spanSize - c.size*(spanSize/c.size)
 		maxWaste := float64((c.size-prevSize-1)*objects+tailWaste) / float64(spanSize)
+		alignBits := bits.TrailingZeros(uint(c.size))
+		if alignBits > pageShift {
+			// object alignment is capped at page alignment
+			alignBits = pageShift
+		}
+		for i := range minAligns {
+			if i > alignBits {
+				minAligns[i] = 0
+			} else if minAligns[i] == 0 {
+				minAligns[i] = c.size
+			}
+		}
 		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, "// %5d  %9d  %10d  %7d  %10d  %8.2f%%  %9d\n", i, c.size, spanSize, objects, tailWaste, 100*maxWaste, 1<<alignBits)
+	}
+	fmt.Fprintf(w, "\n")
+
+	fmt.Fprintf(w, "// %-9s  %-4s  %-12s\n", "alignment", "bits", "min obj size")
+	for bits, size := range minAligns {
+		if size == 0 {
+			break
+		}
+		if bits+1 < len(minAligns) && size == minAligns[bits+1] {
+			continue
+		}
+		fmt.Fprintf(w, "// %9d  %4d  %12d\n", 1<<bits, bits, size)
 	}
 	fmt.Fprintf(w, "\n")
 }
@@ -279,15 +300,13 @@
 	}
 	fmt.Fprintln(w, "}")
 
-	fmt.Fprintln(w, "type divMagic struct {")
-	fmt.Fprintln(w, "  shift uint8")
-	fmt.Fprintln(w, "  shift2 uint8")
-	fmt.Fprintln(w, "  mul uint16")
-	fmt.Fprintln(w, "  baseMask uint16")
-	fmt.Fprintln(w, "}")
-	fmt.Fprint(w, "var class_to_divmagic = [_NumSizeClasses]divMagic {")
+	fmt.Fprint(w, "var class_to_divmagic = [_NumSizeClasses]uint32 {")
 	for _, c := range classes {
-		fmt.Fprintf(w, "{%d,%d,%d,%d},", c.shift, c.shift2, c.mul, c.mask)
+		if c.size == 0 {
+			fmt.Fprintf(w, "0,")
+			continue
+		}
+		fmt.Fprintf(w, "^uint32(0)/%d+1,", c.size)
 	}
 	fmt.Fprintln(w, "}")
 
diff --git a/src/runtime/mmap.go b/src/runtime/mmap.go
index 1b1848b..7460eb3 100644
--- a/src/runtime/mmap.go
+++ b/src/runtime/mmap.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !aix && !darwin && !js && (!linux || !amd64) && (!linux || !arm64) && !openbsd && !plan9 && !solaris && !windows
 // +build !aix
 // +build !darwin
 // +build !js
diff --git a/src/runtime/mpagealloc.go b/src/runtime/mpagealloc.go
index dac1f39..071f1fc 100644
--- a/src/runtime/mpagealloc.go
+++ b/src/runtime/mpagealloc.go
@@ -395,6 +395,9 @@
 			// Store it atomically to avoid races with readers which
 			// don't acquire the heap lock.
 			r := sysAlloc(unsafe.Sizeof(*p.chunks[0]), p.sysStat)
+			if r == nil {
+				throw("pageAlloc: out of memory")
+			}
 			atomic.StorepNoWB(unsafe.Pointer(&p.chunks[c.l1()]), r)
 		}
 		p.chunkOf(c).scavenged.setRange(0, pallocChunkPages)
diff --git a/src/runtime/mpagealloc_32bit.go b/src/runtime/mpagealloc_32bit.go
index 331dada..fceb4e7 100644
--- a/src/runtime/mpagealloc_32bit.go
+++ b/src/runtime/mpagealloc_32bit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 || arm || mips || mipsle || wasm || (ios && arm64)
 // +build 386 arm mips mipsle wasm ios,arm64
 
 // wasm is a treated as a 32-bit architecture for the purposes of the page
diff --git a/src/runtime/mpagealloc_64bit.go b/src/runtime/mpagealloc_64bit.go
index ffacb46..1657734 100644
--- a/src/runtime/mpagealloc_64bit.go
+++ b/src/runtime/mpagealloc_64bit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 || (!ios && arm64) || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x
 // +build amd64 !ios,arm64 mips64 mips64le ppc64 ppc64le riscv64 s390x
 
 // See mpagealloc_32bit.go for why ios/arm64 is excluded here.
diff --git a/src/runtime/mprof.go b/src/runtime/mprof.go
index 128498d..5235b89 100644
--- a/src/runtime/mprof.go
+++ b/src/runtime/mprof.go
@@ -133,7 +133,7 @@
 // A blockRecord is the bucket data for a bucket of type blockProfile,
 // which is used in blocking and mutex profiles.
 type blockRecord struct {
-	count  int64
+	count  float64
 	cycles int64
 }
 
@@ -398,20 +398,23 @@
 	if cycles <= 0 {
 		cycles = 1
 	}
-	if blocksampled(cycles) {
-		saveblockevent(cycles, skip+1, blockProfile)
+
+	rate := int64(atomic.Load64(&blockprofilerate))
+	if blocksampled(cycles, rate) {
+		saveblockevent(cycles, rate, skip+1, blockProfile)
 	}
 }
 
-func blocksampled(cycles int64) bool {
-	rate := int64(atomic.Load64(&blockprofilerate))
+// blocksampled returns true for all events where cycles >= rate. Shorter
+// events have a cycles/rate random chance of returning true.
+func blocksampled(cycles, rate int64) bool {
 	if rate <= 0 || (rate > cycles && int64(fastrand())%rate > cycles) {
 		return false
 	}
 	return true
 }
 
-func saveblockevent(cycles int64, skip int, which bucketType) {
+func saveblockevent(cycles, rate int64, skip int, which bucketType) {
 	gp := getg()
 	var nstk int
 	var stk [maxStack]uintptr
@@ -422,8 +425,15 @@
 	}
 	lock(&proflock)
 	b := stkbucket(which, 0, stk[:nstk], true)
-	b.bp().count++
-	b.bp().cycles += cycles
+
+	if which == blockProfile && cycles < rate {
+		// Remove sampling bias, see discussion on http://golang.org/cl/299991.
+		b.bp().count += float64(rate) / float64(cycles)
+		b.bp().cycles += rate
+	} else {
+		b.bp().count++
+		b.bp().cycles += cycles
+	}
 	unlock(&proflock)
 }
 
@@ -454,7 +464,7 @@
 	// TODO(pjw): measure impact of always calling fastrand vs using something
 	// like malloc.go:nextSample()
 	if rate > 0 && int64(fastrand())%rate == 0 {
-		saveblockevent(cycles, skip+1, mutexProfile)
+		saveblockevent(cycles, rate, skip+1, mutexProfile)
 	}
 }
 
@@ -490,7 +500,22 @@
 // memory profiling rate should do so just once, as early as
 // possible in the execution of the program (for example,
 // at the beginning of main).
-var MemProfileRate int = 512 * 1024
+var MemProfileRate int = defaultMemProfileRate(512 * 1024)
+
+// defaultMemProfileRate returns 0 if disableMemoryProfiling is set.
+// It exists primarily for the godoc rendering of MemProfileRate
+// above.
+func defaultMemProfileRate(v int) int {
+	if disableMemoryProfiling {
+		return 0
+	}
+	return v
+}
+
+// disableMemoryProfiling is set by the linker if runtime.MemProfile
+// is not used and the link type guarantees nobody else could use it
+// elsewhere.
+var disableMemoryProfiling bool
 
 // A MemProfileRecord describes the live objects allocated
 // by a particular call sequence (stack trace).
@@ -641,7 +666,12 @@
 		for b := bbuckets; b != nil; b = b.allnext {
 			bp := b.bp()
 			r := &p[0]
-			r.Count = bp.count
+			r.Count = int64(bp.count)
+			// Prevent callers from having to worry about division by zero errors.
+			// See discussion on http://golang.org/cl/299991.
+			if r.Count == 0 {
+				r.Count = 1
+			}
 			r.Cycles = bp.cycles
 			if raceenabled {
 				racewriterangepc(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0), getcallerpc(), funcPC(BlockProfile))
@@ -731,12 +761,13 @@
 
 	stopTheWorld("profile")
 
+	// World is stopped, no locking required.
 	n = 1
-	for _, gp1 := range allgs {
+	forEachGRace(func(gp1 *g) {
 		if isOK(gp1) {
 			n++
 		}
-	}
+	})
 
 	if n <= len(p) {
 		ok = true
@@ -757,21 +788,23 @@
 		}
 
 		// Save other goroutines.
-		for _, gp1 := range allgs {
-			if isOK(gp1) {
-				if len(r) == 0 {
-					// Should be impossible, but better to return a
-					// truncated profile than to crash the entire process.
-					break
-				}
-				saveg(^uintptr(0), ^uintptr(0), gp1, &r[0])
-				if labels != nil {
-					lbl[0] = gp1.labels
-					lbl = lbl[1:]
-				}
-				r = r[1:]
+		forEachGRace(func(gp1 *g) {
+			if !isOK(gp1) {
+				return
 			}
-		}
+
+			if len(r) == 0 {
+				// Should be impossible, but better to return a
+				// truncated profile than to crash the entire process.
+				return
+			}
+			saveg(^uintptr(0), ^uintptr(0), gp1, &r[0])
+			if labels != nil {
+				lbl[0] = gp1.labels
+				lbl = lbl[1:]
+			}
+			r = r[1:]
+		})
 	}
 
 	startTheWorld()
diff --git a/src/runtime/msan.go b/src/runtime/msan.go
index 6a5960b..25aaf94 100644
--- a/src/runtime/msan.go
+++ b/src/runtime/msan.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build msan
 // +build msan
 
 package runtime
diff --git a/src/runtime/msan0.go b/src/runtime/msan0.go
index 374d13f..b1096a6 100644
--- a/src/runtime/msan0.go
+++ b/src/runtime/msan0.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !msan
 // +build !msan
 
 // Dummy MSan support API, used when not built with -msan.
diff --git a/src/runtime/msan_amd64.s b/src/runtime/msan_amd64.s
index 669e9ca..1bb57a3 100644
--- a/src/runtime/msan_amd64.s
+++ b/src/runtime/msan_amd64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build msan
 // +build msan
 
 #include "go_asm.h"
diff --git a/src/runtime/msan_arm64.s b/src/runtime/msan_arm64.s
index f19906c..93ade8d 100644
--- a/src/runtime/msan_arm64.s
+++ b/src/runtime/msan_arm64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build msan
 // +build msan
 
 #include "go_asm.h"
diff --git a/src/runtime/mstats.go b/src/runtime/mstats.go
index 6defaed..eeb2a7b 100644
--- a/src/runtime/mstats.go
+++ b/src/runtime/mstats.go
@@ -8,6 +8,7 @@
 
 import (
 	"runtime/internal/atomic"
+	"runtime/internal/sys"
 	"unsafe"
 )
 
@@ -62,12 +63,6 @@
 
 	// Statistics about the garbage collector.
 
-	// next_gc is the goal heap_live for when next GC ends.
-	// Set to ^uint64(0) if disabled.
-	//
-	// Read and written atomically, unless the world is stopped.
-	next_gc uint64
-
 	// Protected by mheap or stopping the world during GC.
 	last_gc_unix    uint64 // last gc (in unix time)
 	pause_total_ns  uint64
@@ -92,69 +87,8 @@
 	_ [1 - _NumSizeClasses%2]uint32
 
 	last_gc_nanotime uint64 // last gc (monotonic time)
-	tinyallocs       uint64 // number of tiny allocations that didn't cause actual allocation; not exported to go directly
-	last_next_gc     uint64 // next_gc for the previous GC
 	last_heap_inuse  uint64 // heap_inuse at mark termination of the previous GC
 
-	// triggerRatio is the heap growth ratio that triggers marking.
-	//
-	// E.g., if this is 0.6, then GC should start when the live
-	// heap has reached 1.6 times the heap size marked by the
-	// previous cycle. This should be ≤ GOGC/100 so the trigger
-	// heap size is less than the goal heap size. This is set
-	// during mark termination for the next cycle's trigger.
-	triggerRatio float64
-
-	// gc_trigger is the heap size that triggers marking.
-	//
-	// When heap_live ≥ gc_trigger, the mark phase will start.
-	// This is also the heap size by which proportional sweeping
-	// must be complete.
-	//
-	// This is computed from triggerRatio during mark termination
-	// for the next cycle's trigger.
-	gc_trigger uint64
-
-	// heap_live is the number of bytes considered live by the GC.
-	// That is: retained by the most recent GC plus allocated
-	// since then. heap_live <= alloc, since alloc includes unmarked
-	// objects that have not yet been swept (and hence goes up as we
-	// allocate and down as we sweep) while heap_live excludes these
-	// objects (and hence only goes up between GCs).
-	//
-	// This is updated atomically without locking. To reduce
-	// contention, this is updated only when obtaining a span from
-	// an mcentral and at this point it counts all of the
-	// unallocated slots in that span (which will be allocated
-	// before that mcache obtains another span from that
-	// mcentral). Hence, it slightly overestimates the "true" live
-	// heap size. It's better to overestimate than to
-	// underestimate because 1) this triggers the GC earlier than
-	// necessary rather than potentially too late and 2) this
-	// leads to a conservative GC rate rather than a GC rate that
-	// is potentially too low.
-	//
-	// Reads should likewise be atomic (or during STW).
-	//
-	// Whenever this is updated, call traceHeapAlloc() and
-	// gcController.revise().
-	heap_live uint64
-
-	// heap_scan is the number of bytes of "scannable" heap. This
-	// is the live heap (as counted by heap_live), but omitting
-	// no-scan objects and no-scan tails of objects.
-	//
-	// Whenever this is updated, call gcController.revise().
-	//
-	// Read and written atomically or with the world stopped.
-	heap_scan uint64
-
-	// heap_marked is the number of bytes marked by the previous
-	// GC. After mark termination, heap_live == heap_marked, but
-	// unlike heap_live, heap_marked does not change until the
-	// next mark termination.
-	heap_marked uint64
-
 	// heapStats is a set of statistics
 	heapStats consistentHeapStats
 
@@ -443,10 +377,6 @@
 }
 
 func init() {
-	if offset := unsafe.Offsetof(memstats.heap_live); offset%8 != 0 {
-		println(offset)
-		throw("memstats.heap_live not aligned to 8 bytes")
-	}
 	if offset := unsafe.Offsetof(memstats.heapStats); offset%8 != 0 {
 		println(offset)
 		throw("memstats.heapStats not aligned to 8 bytes")
@@ -523,7 +453,7 @@
 	// at a more granular level in the runtime.
 	stats.GCSys = memstats.gcMiscSys.load() + memstats.gcWorkBufInUse + memstats.gcProgPtrScalarBitsInUse
 	stats.OtherSys = memstats.other_sys.load()
-	stats.NextGC = memstats.next_gc
+	stats.NextGC = gcController.heapGoal
 	stats.LastGC = memstats.last_gc_unix
 	stats.PauseTotalNs = memstats.pause_total_ns
 	stats.PauseNs = memstats.pause_ns
@@ -656,8 +586,8 @@
 	}
 
 	// Account for tiny allocations.
-	memstats.nfree += memstats.tinyallocs
-	memstats.nmalloc += memstats.tinyallocs
+	memstats.nfree += uint64(consStats.tinyAllocCount)
+	memstats.nmalloc += uint64(consStats.tinyAllocCount)
 
 	// Calculate derived stats.
 	memstats.total_alloc = totalAlloc
@@ -773,6 +703,7 @@
 	inPtrScalarBits int64 // byte delta of memory reserved for unrolled GC prog bits
 
 	// Allocator stats.
+	tinyAllocCount  uintptr                  // number of tiny allocations
 	largeAlloc      uintptr                  // bytes allocated for large objects
 	largeAllocCount uintptr                  // number of large object allocations
 	smallAllocCount [_NumSizeClasses]uintptr // number of allocs for small objects
@@ -782,7 +713,7 @@
 
 	// Add a uint32 to ensure this struct is a multiple of 8 bytes in size.
 	// Only necessary on 32-bit platforms.
-	// _ [(sys.PtrSize / 4) % 2]uint32
+	_ [(sys.PtrSize / 4) % 2]uint32
 }
 
 // merge adds in the deltas from b into a.
@@ -794,6 +725,7 @@
 	a.inWorkBufs += b.inWorkBufs
 	a.inPtrScalarBits += b.inPtrScalarBits
 
+	a.tinyAllocCount += b.tinyAllocCount
 	a.largeAlloc += b.largeAlloc
 	a.largeAllocCount += b.largeAllocCount
 	for i := range b.smallAllocCount {
diff --git a/src/runtime/nbpipe_fcntl_libc_test.go b/src/runtime/nbpipe_fcntl_libc_test.go
index b38c583..076a722 100644
--- a/src/runtime/nbpipe_fcntl_libc_test.go
+++ b/src/runtime/nbpipe_fcntl_libc_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || solaris
 // +build aix darwin solaris
 
 package runtime_test
diff --git a/src/runtime/nbpipe_fcntl_unix_test.go b/src/runtime/nbpipe_fcntl_unix_test.go
index 75acdb6..6d5e4ff 100644
--- a/src/runtime/nbpipe_fcntl_unix_test.go
+++ b/src/runtime/nbpipe_fcntl_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || linux || netbsd || openbsd
 // +build dragonfly freebsd linux netbsd openbsd
 
 package runtime_test
diff --git a/src/runtime/nbpipe_pipe.go b/src/runtime/nbpipe_pipe.go
index 822b294..b17257e 100644
--- a/src/runtime/nbpipe_pipe.go
+++ b/src/runtime/nbpipe_pipe.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin dragonfly
+//go:build aix || darwin
+// +build aix darwin
 
 package runtime
 
diff --git a/src/runtime/nbpipe_pipe2.go b/src/runtime/nbpipe_pipe2.go
index e3639d9..f22b2b5 100644
--- a/src/runtime/nbpipe_pipe2.go
+++ b/src/runtime/nbpipe_pipe2.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build freebsd linux netbsd openbsd solaris
+//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris
+// +build dragonfly freebsd linux netbsd openbsd solaris
 
 package runtime
 
diff --git a/src/runtime/nbpipe_test.go b/src/runtime/nbpipe_test.go
index d739f57..1d6a9b5 100644
--- a/src/runtime/nbpipe_test.go
+++ b/src/runtime/nbpipe_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package runtime_test
diff --git a/src/runtime/netpoll.go b/src/runtime/netpoll.go
index 77eb3aa..6c26fdb 100644
--- a/src/runtime/netpoll.go
+++ b/src/runtime/netpoll.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
 
 package runtime
@@ -22,6 +23,9 @@
 //     Arm edge-triggered notifications for fd. The pd argument is to pass
 //     back to netpollready when fd is ready. Return an errno value.
 //
+// func netpollclose(fd uintptr) int32
+//     Disable notifications for fd. Return an errno value.
+//
 // func netpoll(delta int64) gList
 //     Poll the network. If delta < 0, block indefinitely. If delta == 0,
 //     poll without blocking. If delta > 0, block for up to delta nanoseconds.
@@ -161,9 +165,12 @@
 	pd.self = pd
 	unlock(&pd.lock)
 
-	var errno int32
-	errno = netpollopen(fd, pd)
-	return pd, int(errno)
+	errno := netpollopen(fd, pd)
+	if errno != 0 {
+		pollcache.free(pd)
+		return nil, int(errno)
+	}
+	return pd, 0
 }
 
 //go:linkname poll_runtime_pollClose internal/poll.runtime_pollClose
diff --git a/src/runtime/netpoll_epoll.go b/src/runtime/netpoll_epoll.go
index 58f4fa8..371ac59 100644
--- a/src/runtime/netpoll_epoll.go
+++ b/src/runtime/netpoll_epoll.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux
 // +build linux
 
 package runtime
diff --git a/src/runtime/netpoll_fake.go b/src/runtime/netpoll_fake.go
index b2af3b8..8366f28 100644
--- a/src/runtime/netpoll_fake.go
+++ b/src/runtime/netpoll_fake.go
@@ -5,6 +5,7 @@
 // Fake network poller for wasm/js.
 // Should never be used, because wasm/js network connections do not honor "SetNonblock".
 
+//go:build js && wasm
 // +build js,wasm
 
 package runtime
diff --git a/src/runtime/netpoll_kqueue.go b/src/runtime/netpoll_kqueue.go
index 3bd93c1..80d1b0c 100644
--- a/src/runtime/netpoll_kqueue.go
+++ b/src/runtime/netpoll_kqueue.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 package runtime
diff --git a/src/runtime/netpoll_stub.go b/src/runtime/netpoll_stub.go
index 3599f2d..33ab8eb 100644
--- a/src/runtime/netpoll_stub.go
+++ b/src/runtime/netpoll_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build plan9
 // +build plan9
 
 package runtime
diff --git a/src/runtime/norace_linux_test.go b/src/runtime/norace_linux_test.go
index 3517a5d..94b7c7a 100644
--- a/src/runtime/norace_linux_test.go
+++ b/src/runtime/norace_linux_test.go
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // The file contains tests that cannot run under race detector for some reason.
+//go:build !race
 // +build !race
 
 package runtime_test
diff --git a/src/runtime/norace_test.go b/src/runtime/norace_test.go
index e90128b..9ad5dde 100644
--- a/src/runtime/norace_test.go
+++ b/src/runtime/norace_test.go
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // The file contains tests that cannot run under race detector for some reason.
+//go:build !race
 // +build !race
 
 package runtime_test
diff --git a/src/runtime/os2_aix.go b/src/runtime/os2_aix.go
index 428ff7f..4d77f0d 100644
--- a/src/runtime/os2_aix.go
+++ b/src/runtime/os2_aix.go
@@ -18,11 +18,11 @@
 
 //go:cgo_import_dynamic libc___n_pthreads __n_pthreads "libpthread.a/shr_xpg5_64.o"
 //go:cgo_import_dynamic libc___mod_init __mod_init "libc.a/shr_64.o"
-//go:linkname libc___n_pthreads libc___n_pthread
+//go:linkname libc___n_pthreads libc___n_pthreads
 //go:linkname libc___mod_init libc___mod_init
 
 var (
-	libc___n_pthread,
+	libc___n_pthreads,
 	libc___mod_init libFunc
 )
 
@@ -527,23 +527,20 @@
 func usleep1(us uint32)
 
 //go:nosplit
-func usleep(us uint32) {
-	_g_ := getg()
-
-	// Check the validity of m because we might be called in cgo callback
-	// path early enough where there isn't a g or a m available yet.
-	if _g_ != nil && _g_.m != nil {
-		r, err := syscall1(&libc_usleep, uintptr(us))
-		if int32(r) == -1 {
-			println("syscall usleep failed: ", hex(err))
-			throw("syscall usleep")
-		}
-		return
-	}
+func usleep_no_g(us uint32) {
 	usleep1(us)
 }
 
 //go:nosplit
+func usleep(us uint32) {
+	r, err := syscall1(&libc_usleep, uintptr(us))
+	if int32(r) == -1 {
+		println("syscall usleep failed: ", hex(err))
+		throw("syscall usleep")
+	}
+}
+
+//go:nosplit
 func clock_gettime(clockid int32, tp *timespec) int32 {
 	r, _ := syscall2(&libc_clock_gettime, uintptr(clockid), uintptr(unsafe.Pointer(tp)))
 	return int32(r)
@@ -611,23 +608,20 @@
 func osyield1()
 
 //go:nosplit
-func osyield() {
-	_g_ := getg()
-
-	// Check the validity of m because it might be called during a cgo
-	// callback early enough where m isn't available yet.
-	if _g_ != nil && _g_.m != nil {
-		r, err := syscall0(&libc_sched_yield)
-		if int32(r) == -1 {
-			println("syscall osyield failed: ", hex(err))
-			throw("syscall osyield")
-		}
-		return
-	}
+func osyield_no_g() {
 	osyield1()
 }
 
 //go:nosplit
+func osyield() {
+	r, err := syscall0(&libc_sched_yield)
+	if int32(r) == -1 {
+		println("syscall osyield failed: ", hex(err))
+		throw("syscall osyield")
+	}
+}
+
+//go:nosplit
 func sysconf(name int32) uintptr {
 	r, _ := syscall1(&libc_sysconf, uintptr(name))
 	if int32(r) == -1 {
diff --git a/src/runtime/os3_plan9.go b/src/runtime/os3_plan9.go
index 15ca335..c5dc23d 100644
--- a/src/runtime/os3_plan9.go
+++ b/src/runtime/os3_plan9.go
@@ -92,10 +92,6 @@
 			if usesLR {
 				c.setlr(pc)
 			} else {
-				if sys.RegSize > sys.PtrSize {
-					sp -= sys.PtrSize
-					*(*uintptr)(unsafe.Pointer(sp)) = 0
-				}
 				sp -= sys.PtrSize
 				*(*uintptr)(unsafe.Pointer(sp)) = pc
 				c.setsp(sp)
@@ -104,7 +100,7 @@
 		if usesLR {
 			c.setpc(funcPC(sigpanictramp))
 		} else {
-			c.setpc(funcPC(sigpanic))
+			c.setpc(funcPC(sigpanic0))
 		}
 		return _NCONT
 	}
diff --git a/src/runtime/os3_solaris.go b/src/runtime/os3_solaris.go
index 6ba11af..39ef831 100644
--- a/src/runtime/os3_solaris.go
+++ b/src/runtime/os3_solaris.go
@@ -522,11 +522,16 @@
 func usleep1(usec uint32)
 
 //go:nosplit
+func usleep_no_g(µs uint32) {
+	usleep1(µs)
+}
+
+//go:nosplit
 func usleep(µs uint32) {
 	usleep1(µs)
 }
 
-func walltime1() (sec int64, nsec int32) {
+func walltime() (sec int64, nsec int32) {
 	var ts mts
 	sysvicall2(&libc_clock_gettime, _CLOCK_REALTIME, uintptr(unsafe.Pointer(&ts)))
 	return ts.tv_sec, int32(ts.tv_nsec)
@@ -569,18 +574,15 @@
 func osyield1()
 
 //go:nosplit
-func osyield() {
-	_g_ := getg()
-
-	// Check the validity of m because we might be called in cgo callback
-	// path early enough where there isn't a m available yet.
-	if _g_ != nil && _g_.m != nil {
-		sysvicall0(&libc_sched_yield)
-		return
-	}
+func osyield_no_g() {
 	osyield1()
 }
 
+//go:nosplit
+func osyield() {
+	sysvicall0(&libc_sched_yield)
+}
+
 //go:linkname executablePath os.executablePath
 var executablePath string
 
diff --git a/src/runtime/os_aix.go b/src/runtime/os_aix.go
index 303f087..4fb1c8e 100644
--- a/src/runtime/os_aix.go
+++ b/src/runtime/os_aix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix
 // +build aix
 
 package runtime
@@ -335,7 +336,7 @@
 	return tp.tv_sec*1000000000 + tp.tv_nsec
 }
 
-func walltime1() (sec int64, nsec int32) {
+func walltime() (sec int64, nsec int32) {
 	ts := &timespec{}
 	if clock_gettime(_CLOCK_REALTIME, ts) != 0 {
 		throw("syscall clock_gettime failed")
diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go
index 9ca17c2..079be10 100644
--- a/src/runtime/os_darwin.go
+++ b/src/runtime/os_darwin.go
@@ -4,7 +4,10 @@
 
 package runtime
 
-import "unsafe"
+import (
+	"internal/abi"
+	"unsafe"
+)
 
 type mOS struct {
 	initialized bool
@@ -115,10 +118,15 @@
 
 // sigNoteSleep waits for a note created by sigNoteSetup to be woken.
 func sigNoteSleep(*note) {
-	entersyscallblock()
-	var b byte
-	read(sigNoteRead, unsafe.Pointer(&b), 1)
-	exitsyscall()
+	for {
+		var b byte
+		entersyscallblock()
+		n := read(sigNoteRead, unsafe.Pointer(&b), 1)
+		exitsyscall()
+		if n != -_EINTR {
+			return
+		}
+	}
 }
 
 // BSD interface for threading.
@@ -221,7 +229,7 @@
 	// setup and then calls mstart.
 	var oset sigset
 	sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
-	err = pthread_create(&attr, funcPC(mstart_stub), unsafe.Pointer(mp))
+	err = pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 	if err != 0 {
 		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
@@ -331,6 +339,11 @@
 }
 
 //go:nosplit
+func osyield_no_g() {
+	usleep_no_g(1)
+}
+
+//go:nosplit
 func osyield() {
 	usleep(1)
 }
@@ -356,11 +369,11 @@
 	var sa usigactiont
 	sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
 	sa.sa_mask = ^uint32(0)
-	if fn == funcPC(sighandler) {
+	if fn == funcPC(sighandler) { // funcPC(sighandler) matches the callers in signal_unix.go
 		if iscgo {
-			fn = funcPC(cgoSigtramp)
+			fn = abi.FuncPCABI0(cgoSigtramp)
 		} else {
-			fn = funcPC(sigtramp)
+			fn = abi.FuncPCABI0(sigtramp)
 		}
 	}
 	*(*uintptr)(unsafe.Pointer(&sa.__sigaction_u)) = fn
diff --git a/src/runtime/os_dragonfly.go b/src/runtime/os_dragonfly.go
index 383df54..5c688a3 100644
--- a/src/runtime/os_dragonfly.go
+++ b/src/runtime/os_dragonfly.go
@@ -51,16 +51,20 @@
 
 func osyield()
 
+//go:nosplit
+func osyield_no_g() {
+	osyield()
+}
+
 func kqueue() int32
 
 //go:noescape
 func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
-func closeonexec(fd int32)
-func setNonblock(fd int32)
 
 func pipe() (r, w int32, errno int32)
-
-const stackSystem = 0
+func pipe2(flags int32) (r, w int32, errno int32)
+func closeonexec(fd int32)
+func setNonblock(fd int32)
 
 // From DragonFly's <sys/sysctl.h>
 const (
diff --git a/src/runtime/os_freebsd.go b/src/runtime/os_freebsd.go
index 09065cc..09dd50c 100644
--- a/src/runtime/os_freebsd.go
+++ b/src/runtime/os_freebsd.go
@@ -36,6 +36,11 @@
 
 func osyield()
 
+//go:nosplit
+func osyield_no_g() {
+	osyield()
+}
+
 func kqueue() int32
 
 //go:noescape
diff --git a/src/runtime/os_freebsd2.go b/src/runtime/os_freebsd2.go
index 6947a05..fde6fbf 100644
--- a/src/runtime/os_freebsd2.go
+++ b/src/runtime/os_freebsd2.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build freebsd && !amd64
 // +build freebsd,!amd64
 
 package runtime
diff --git a/src/runtime/os_freebsd_noauxv.go b/src/runtime/os_freebsd_noauxv.go
index 01efb9b..8fe0cb6 100644
--- a/src/runtime/os_freebsd_noauxv.go
+++ b/src/runtime/os_freebsd_noauxv.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build freebsd
-// +build !arm
+//go:build freebsd && !arm
+// +build freebsd,!arm
 
 package runtime
 
diff --git a/src/runtime/os_js.go b/src/runtime/os_js.go
index 24261e8..52b64e7 100644
--- a/src/runtime/os_js.go
+++ b/src/runtime/os_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package runtime
@@ -30,12 +31,22 @@
 
 func usleep(usec uint32)
 
+//go:nosplit
+func usleep_no_g(usec uint32) {
+	usleep(usec)
+}
+
 func exitThread(wait *uint32)
 
 type mOS struct{}
 
 func osyield()
 
+//go:nosplit
+func osyield_no_g() {
+	osyield()
+}
+
 const _SIGSEGV = 0xb
 
 func sigpanic() {
diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go
index 058c7da..c8b29e3 100644
--- a/src/runtime/os_linux.go
+++ b/src/runtime/os_linux.go
@@ -385,7 +385,7 @@
 //#endif
 
 func sigreturn()
-func sigtramp(sig uint32, info *siginfo, ctx unsafe.Pointer)
+func sigtramp() // Called via C ABI
 func cgoSigtramp()
 
 //go:noescape
@@ -410,6 +410,11 @@
 func sched_getaffinity(pid, len uintptr, buf *byte) int32
 func osyield()
 
+//go:nosplit
+func osyield_no_g() {
+	osyield()
+}
+
 func pipe() (r, w int32, errno int32)
 func pipe2(flags int32) (r, w int32, errno int32)
 func setNonblock(fd int32)
diff --git a/src/runtime/os_linux_arm64.go b/src/runtime/os_linux_arm64.go
index c5fd742..5260f22 100644
--- a/src/runtime/os_linux_arm64.go
+++ b/src/runtime/os_linux_arm64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build arm64
 // +build arm64
 
 package runtime
diff --git a/src/runtime/os_linux_be64.go b/src/runtime/os_linux_be64.go
index 9860002..498d7ce 100644
--- a/src/runtime/os_linux_be64.go
+++ b/src/runtime/os_linux_be64.go
@@ -2,8 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// The standard GNU/Linux sigset type on big-endian 64-bit machines.
+// The standard Linux sigset type on big-endian 64-bit machines.
 
+//go:build linux && (ppc64 || s390x)
 // +build linux
 // +build ppc64 s390x
 
diff --git a/src/runtime/os_linux_generic.go b/src/runtime/os_linux_generic.go
index e1d0952..fe1973d 100644
--- a/src/runtime/os_linux_generic.go
+++ b/src/runtime/os_linux_generic.go
@@ -2,13 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !mips
-// +build !mipsle
-// +build !mips64
-// +build !mips64le
-// +build !s390x
-// +build !ppc64
-// +build linux
+//go:build !mips && !mipsle && !mips64 && !mips64le && !s390x && !ppc64 && linux
+// +build !mips,!mipsle,!mips64,!mips64le,!s390x,!ppc64,linux
 
 package runtime
 
diff --git a/src/runtime/os_linux_mips64x.go b/src/runtime/os_linux_mips64x.go
index 815a83a..bd76442 100644
--- a/src/runtime/os_linux_mips64x.go
+++ b/src/runtime/os_linux_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips64 || mips64le)
 // +build linux
 // +build mips64 mips64le
 
diff --git a/src/runtime/os_linux_mipsx.go b/src/runtime/os_linux_mipsx.go
index 00fb02e..ef8b3f7 100644
--- a/src/runtime/os_linux_mipsx.go
+++ b/src/runtime/os_linux_mipsx.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips || mipsle)
 // +build linux
 // +build mips mipsle
 
diff --git a/src/runtime/os_linux_noauxv.go b/src/runtime/os_linux_noauxv.go
index 895b4cd..59b5aac 100644
--- a/src/runtime/os_linux_noauxv.go
+++ b/src/runtime/os_linux_noauxv.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux
-// +build !arm,!arm64,!mips,!mipsle,!mips64,!mips64le,!s390x,!ppc64,!ppc64le
+//go:build linux && !arm && !arm64 && !mips && !mipsle && !mips64 && !mips64le && !s390x && !ppc64 && !ppc64le
+// +build linux,!arm,!arm64,!mips,!mipsle,!mips64,!mips64le,!s390x,!ppc64,!ppc64le
 
 package runtime
 
diff --git a/src/runtime/os_linux_novdso.go b/src/runtime/os_linux_novdso.go
index 155f415..8104f63 100644
--- a/src/runtime/os_linux_novdso.go
+++ b/src/runtime/os_linux_novdso.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux
-// +build !386,!amd64,!arm,!arm64,!mips64,!mips64le,!ppc64,!ppc64le
+//go:build linux && !386 && !amd64 && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le
+// +build linux,!386,!amd64,!arm,!arm64,!mips64,!mips64le,!ppc64,!ppc64le
 
 package runtime
 
diff --git a/src/runtime/os_linux_ppc64x.go b/src/runtime/os_linux_ppc64x.go
index 3aedc23..c093d2e 100644
--- a/src/runtime/os_linux_ppc64x.go
+++ b/src/runtime/os_linux_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (ppc64 || ppc64le)
 // +build linux
 // +build ppc64 ppc64le
 
diff --git a/src/runtime/os_linux_x86.go b/src/runtime/os_linux_x86.go
index d91fa1a..5667774 100644
--- a/src/runtime/os_linux_x86.go
+++ b/src/runtime/os_linux_x86.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (386 || amd64)
 // +build linux
 // +build 386 amd64
 
diff --git a/src/runtime/os_netbsd.go b/src/runtime/os_netbsd.go
index 2b742a3..6fbb3aa 100644
--- a/src/runtime/os_netbsd.go
+++ b/src/runtime/os_netbsd.go
@@ -67,6 +67,11 @@
 
 func osyield()
 
+//go:nosplit
+func osyield_no_g() {
+	osyield()
+}
+
 func kqueue() int32
 
 //go:noescape
@@ -223,7 +228,11 @@
 	}
 }
 
-// netbsdMStart is the function call that starts executing a newly
+// mstart is the entry-point for new Ms.
+// It is written in assembly, uses ABI0, is marked TOPFRAME, and calls netbsdMstart0.
+func netbsdMstart()
+
+// netbsdMStart0 is the function call that starts executing a newly
 // created thread. On NetBSD, a new thread inherits the signal stack
 // of the creating thread. That confuses minit, so we remove that
 // signal stack here before calling the regular mstart. It's a bit
@@ -231,10 +240,10 @@
 // it's a simple change that keeps NetBSD working like other OS's.
 // At this point all signals are blocked, so there is no race.
 //go:nosplit
-func netbsdMstart() {
+func netbsdMstart0() {
 	st := stackt{ss_flags: _SS_DISABLE}
 	sigaltstack(&st, nil)
-	mstart()
+	mstart0()
 }
 
 func osinit() {
diff --git a/src/runtime/os_nonopenbsd.go b/src/runtime/os_nonopenbsd.go
index e65697b..6134b6c 100644
--- a/src/runtime/os_nonopenbsd.go
+++ b/src/runtime/os_nonopenbsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !openbsd
 // +build !openbsd
 
 package runtime
diff --git a/src/runtime/os_only_solaris.go b/src/runtime/os_only_solaris.go
index e2f5409..3829683 100644
--- a/src/runtime/os_only_solaris.go
+++ b/src/runtime/os_only_solaris.go
@@ -4,6 +4,7 @@
 
 // Solaris code that doesn't also apply to illumos.
 
+//go:build !illumos
 // +build !illumos
 
 package runtime
diff --git a/src/runtime/os_openbsd_libc.go b/src/runtime/os_openbsd_libc.go
index 2edb035..0a342e5 100644
--- a/src/runtime/os_openbsd_libc.go
+++ b/src/runtime/os_openbsd_libc.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build openbsd,amd64 openbsd,arm64
+//go:build openbsd && !mips64
+// +build openbsd,!mips64
 
 package runtime
 
diff --git a/src/runtime/os_openbsd_syscall.go b/src/runtime/os_openbsd_syscall.go
index 16ff2b8..3cdcb6c 100644
--- a/src/runtime/os_openbsd_syscall.go
+++ b/src/runtime/os_openbsd_syscall.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build openbsd,!amd64
-// +build openbsd,!arm64
+//go:build openbsd && mips64
+// +build openbsd,mips64
 
 package runtime
 
diff --git a/src/runtime/os_openbsd_syscall1.go b/src/runtime/os_openbsd_syscall1.go
index b0bef4c..c20ee83 100644
--- a/src/runtime/os_openbsd_syscall1.go
+++ b/src/runtime/os_openbsd_syscall1.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build openbsd,!amd64,!arm64
+//go:build openbsd && mips64
+// +build openbsd,mips64
 
 package runtime
 
@@ -13,3 +14,8 @@
 func thrwakeup(ident uintptr, n int32) int32
 
 func osyield()
+
+//go:nosplit
+func osyield_no_g() {
+	osyield()
+}
diff --git a/src/runtime/os_openbsd_syscall2.go b/src/runtime/os_openbsd_syscall2.go
index ab94051..af19971 100644
--- a/src/runtime/os_openbsd_syscall2.go
+++ b/src/runtime/os_openbsd_syscall2.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build openbsd,!amd64,!arm64
+//go:build openbsd && mips64
+// +build openbsd,mips64
 
 package runtime
 
@@ -32,6 +33,11 @@
 func exit(code int32)
 func usleep(usec uint32)
 
+//go:nosplit
+func usleep_no_g(usec uint32) {
+	usleep(usec)
+}
+
 // write calls the write system call.
 // It returns a non-negative number of bytes written or a negative errno value.
 //go:noescape
@@ -92,4 +98,4 @@
 func closeonexec(fd int32)
 func setNonblock(fd int32)
 
-func walltime1() (sec int64, nsec int32)
+func walltime() (sec int64, nsec int32)
diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go
index 2a84a73..4d42834 100644
--- a/src/runtime/os_plan9.go
+++ b/src/runtime/os_plan9.go
@@ -325,7 +325,23 @@
 
 //go:nosplit
 func getRandomData(r []byte) {
-	extendRandom(r, 0)
+	// inspired by wyrand see hash32.go for detail
+	t := nanotime()
+	v := getg().m.procid ^ uint64(t)
+
+	for len(r) > 0 {
+		v ^= 0xa0761d6478bd642f
+		v *= 0xe7037ed1a0b428db
+		size := 8
+		if len(r) < 8 {
+			size = len(r)
+		}
+		for i := 0; i < size; i++ {
+			r[i] = byte(v >> (8 * i))
+		}
+		r = r[size:]
+		v = v>>32 | v<<32
+	}
 }
 
 func initsig(preinit bool) {
@@ -340,6 +356,11 @@
 }
 
 //go:nosplit
+func osyield_no_g() {
+	osyield()
+}
+
+//go:nosplit
 func usleep(µs uint32) {
 	ms := int32(µs / 1000)
 	if ms == 0 {
@@ -349,6 +370,11 @@
 }
 
 //go:nosplit
+func usleep_no_g(usec uint32) {
+	usleep(usec)
+}
+
+//go:nosplit
 func nanotime1() int64 {
 	var scratch int64
 	ns := nsec(&scratch)
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
index e6b22e3..f093526 100644
--- a/src/runtime/os_windows.go
+++ b/src/runtime/os_windows.go
@@ -18,6 +18,7 @@
 //go:cgo_import_dynamic runtime._AddVectoredExceptionHandler AddVectoredExceptionHandler%2 "kernel32.dll"
 //go:cgo_import_dynamic runtime._CloseHandle CloseHandle%1 "kernel32.dll"
 //go:cgo_import_dynamic runtime._CreateEventA CreateEventA%4 "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateFileA CreateFileA%7 "kernel32.dll"
 //go:cgo_import_dynamic runtime._CreateIoCompletionPort CreateIoCompletionPort%4 "kernel32.dll"
 //go:cgo_import_dynamic runtime._CreateThread CreateThread%6 "kernel32.dll"
 //go:cgo_import_dynamic runtime._CreateWaitableTimerA CreateWaitableTimerA%3 "kernel32.dll"
@@ -67,6 +68,7 @@
 	_AddVectoredExceptionHandler,
 	_CloseHandle,
 	_CreateEventA,
+	_CreateFileA,
 	_CreateIoCompletionPort,
 	_CreateThread,
 	_CreateWaitableTimerA,
@@ -132,7 +134,9 @@
 	// Load ntdll.dll manually during startup, otherwise Mingw
 	// links wrong printf function to cgo executable (see issue
 	// 12030 for details).
-	_NtWaitForSingleObject stdFunction
+	_NtWaitForSingleObject  stdFunction
+	_RtlGetCurrentPeb       stdFunction
+	_RtlGetNtVersionNumbers stdFunction
 
 	// These are from non-kernel32.dll, so we prefer to LoadLibraryEx them.
 	_timeBeginPeriod,
@@ -145,8 +149,8 @@
 // to start new os thread.
 func tstart_stdcall(newm *m)
 
-// Called by OS using stdcall ABI.
-func ctrlhandler()
+// Init-time helper
+func wintls()
 
 type mOS struct {
 	threadLock mutex   // protects "thread" and prevents closing
@@ -216,26 +220,29 @@
 	return stdFunction(unsafe.Pointer(f))
 }
 
-var sysDirectory [521]byte
+const _MAX_PATH = 260 // https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
+var sysDirectory [_MAX_PATH + 1]byte
 var sysDirectoryLen uintptr
 
 func windowsLoadSystemLib(name []byte) uintptr {
+	if sysDirectoryLen == 0 {
+		l := stdcall2(_GetSystemDirectoryA, uintptr(unsafe.Pointer(&sysDirectory[0])), uintptr(len(sysDirectory)-1))
+		if l == 0 || l > uintptr(len(sysDirectory)-1) {
+			throw("Unable to determine system directory")
+		}
+		sysDirectory[l] = '\\'
+		sysDirectoryLen = l + 1
+	}
 	if useLoadLibraryEx {
 		return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32)
 	} else {
-		if sysDirectoryLen == 0 {
-			l := stdcall2(_GetSystemDirectoryA, uintptr(unsafe.Pointer(&sysDirectory[0])), uintptr(len(sysDirectory)-1))
-			if l == 0 || l > uintptr(len(sysDirectory)-1) {
-				throw("Unable to determine system directory")
-			}
-			sysDirectory[l] = '\\'
-			sysDirectoryLen = l + 1
-		}
 		absName := append(sysDirectory[:sysDirectoryLen], name...)
 		return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0])))
 	}
 }
 
+const haveCputicksAsm = GOARCH == "386" || GOARCH == "amd64"
+
 func loadOptionalSyscalls() {
 	var kernel32dll = []byte("kernel32.dll\000")
 	k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0])))
@@ -261,8 +268,10 @@
 		throw("ntdll.dll not found")
 	}
 	_NtWaitForSingleObject = windowsFindfunc(n32, []byte("NtWaitForSingleObject\000"))
+	_RtlGetCurrentPeb = windowsFindfunc(n32, []byte("RtlGetCurrentPeb\000"))
+	_RtlGetNtVersionNumbers = windowsFindfunc(n32, []byte("RtlGetNtVersionNumbers\000"))
 
-	if GOARCH == "arm" {
+	if !haveCputicksAsm {
 		_QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
 		if _QueryPerformanceCounter == nil {
 			throw("could not find QPC syscalls")
@@ -377,9 +386,7 @@
 )
 
 // in sys_windows_386.s and sys_windows_amd64.s:
-func externalthreadhandler()
 func getlasterror() uint32
-func setlasterror(err uint32)
 
 // When loading DLLs, we prefer to use LoadLibraryEx with
 // LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not
@@ -453,23 +460,90 @@
 		_SYNCHRONIZE|_TIMER_QUERY_STATE|_TIMER_MODIFY_STATE)
 }
 
+const highResTimerSupported = GOARCH == "386" || GOARCH == "amd64"
+
 func initHighResTimer() {
-	if GOARCH == "arm" {
+	if !highResTimerSupported {
 		// TODO: Not yet implemented.
 		return
 	}
 	h := createHighResTimer()
 	if h != 0 {
 		haveHighResTimer = true
-		usleep2Addr = unsafe.Pointer(funcPC(usleep2HighRes))
 		stdcall1(_CloseHandle, h)
 	}
 }
 
+//go:linkname canUseLongPaths os.canUseLongPaths
+var canUseLongPaths bool
+
+// We want this to be large enough to hold the contents of sysDirectory, *plus*
+// a slash and another component that itself is greater than MAX_PATH.
+var longFileName [(_MAX_PATH+1)*2 + 1]byte
+
+// initLongPathSupport initializes the canUseLongPaths variable, which is
+// linked into os.canUseLongPaths for determining whether or not long paths
+// need to be fixed up. In the best case, this function is running on newer
+// Windows 10 builds, which have a bit field member of the PEB called
+// "IsLongPathAwareProcess." When this is set, we don't need to go through the
+// error-prone fixup function in order to access long paths. So this init
+// function first checks the Windows build number, sets the flag, and then
+// tests to see if it's actually working. If everything checks out, then
+// canUseLongPaths is set to true, and later when called, os.fixLongPath
+// returns early without doing work.
+func initLongPathSupport() {
+	const (
+		IsLongPathAwareProcess = 0x80
+		PebBitFieldOffset      = 3
+		OPEN_EXISTING          = 3
+		ERROR_PATH_NOT_FOUND   = 3
+	)
+
+	// Check that we're ≥ 10.0.15063.
+	var maj, min, build uint32
+	stdcall3(_RtlGetNtVersionNumbers, uintptr(unsafe.Pointer(&maj)), uintptr(unsafe.Pointer(&min)), uintptr(unsafe.Pointer(&build)))
+	if maj < 10 || (maj == 10 && min == 0 && build&0xffff < 15063) {
+		return
+	}
+
+	// Set the IsLongPathAwareProcess flag of the PEB's bit field.
+	bitField := (*byte)(unsafe.Pointer(stdcall0(_RtlGetCurrentPeb) + PebBitFieldOffset))
+	originalBitField := *bitField
+	*bitField |= IsLongPathAwareProcess
+
+	// Check that this actually has an effect, by constructing a large file
+	// path and seeing whether we get ERROR_PATH_NOT_FOUND, rather than
+	// some other error, which would indicate the path is too long, and
+	// hence long path support is not successful. This whole section is NOT
+	// strictly necessary, but is a nice validity check for the near to
+	// medium term, when this functionality is still relatively new in
+	// Windows.
+	getRandomData(longFileName[len(longFileName)-33 : len(longFileName)-1])
+	start := copy(longFileName[:], sysDirectory[:sysDirectoryLen])
+	const dig = "0123456789abcdef"
+	for i := 0; i < 32; i++ {
+		longFileName[start+i*2] = dig[longFileName[len(longFileName)-33+i]>>4]
+		longFileName[start+i*2+1] = dig[longFileName[len(longFileName)-33+i]&0xf]
+	}
+	start += 64
+	for i := start; i < len(longFileName)-1; i++ {
+		longFileName[i] = 'A'
+	}
+	stdcall7(_CreateFileA, uintptr(unsafe.Pointer(&longFileName[0])), 0, 0, 0, OPEN_EXISTING, 0, 0)
+	// The ERROR_PATH_NOT_FOUND error value is distinct from
+	// ERROR_FILE_NOT_FOUND or ERROR_INVALID_NAME, the latter of which we
+	// expect here due to the final component being too long.
+	if getlasterror() == ERROR_PATH_NOT_FOUND {
+		*bitField = originalBitField
+		println("runtime: warning: IsLongPathAwareProcess failed to enable long paths; proceeding in fixup mode")
+		return
+	}
+
+	canUseLongPaths = true
+}
+
 func osinit() {
 	asmstdcallAddr = unsafe.Pointer(funcPC(asmstdcall))
-	usleep2Addr = unsafe.Pointer(funcPC(usleep2))
-	switchtothreadAddr = unsafe.Pointer(funcPC(switchtothread))
 
 	setBadSignalMsg()
 
@@ -479,11 +553,11 @@
 
 	initExceptionHandler()
 
-	stdcall2(_SetConsoleCtrlHandler, funcPC(ctrlhandler), 1)
-
 	initHighResTimer()
 	timeBeginPeriodRetValue = osRelax(false)
 
+	initLongPathSupport()
+
 	ncpu = getproccount()
 
 	physPageSize = getPageSize()
@@ -605,8 +679,12 @@
 
 	stdcall1(_FreeEnvironmentStringsW, uintptr(strings))
 
-	// We call this all the way here, late in init, so that malloc works
-	// for the callback function this generates.
+	// We call these all the way here, late in init, so that malloc works
+	// for the callback functions these generate.
+	var fn interface{} = ctrlHandler
+	ctrlHandlerPC := compileCallback(*efaceOf(&fn), true)
+	stdcall2(_SetConsoleCtrlHandler, ctrlHandlerPC, 1)
+
 	monitorSuspendResume()
 }
 
@@ -726,9 +804,6 @@
 	return
 }
 
-// walltime1 isn't implemented on Windows, but will never be called.
-func walltime1() (sec int64, nsec int32)
-
 //go:nosplit
 func semasleep(ns int64) int32 {
 	const (
@@ -1006,6 +1081,7 @@
 }
 
 //go:nosplit
+//go:cgo_unsafe_args
 func stdcall1(fn stdFunction, a0 uintptr) uintptr {
 	mp := getg().m
 	mp.libcall.n = 1
@@ -1014,6 +1090,7 @@
 }
 
 //go:nosplit
+//go:cgo_unsafe_args
 func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr {
 	mp := getg().m
 	mp.libcall.n = 2
@@ -1022,6 +1099,7 @@
 }
 
 //go:nosplit
+//go:cgo_unsafe_args
 func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr {
 	mp := getg().m
 	mp.libcall.n = 3
@@ -1030,6 +1108,7 @@
 }
 
 //go:nosplit
+//go:cgo_unsafe_args
 func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr {
 	mp := getg().m
 	mp.libcall.n = 4
@@ -1038,6 +1117,7 @@
 }
 
 //go:nosplit
+//go:cgo_unsafe_args
 func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr {
 	mp := getg().m
 	mp.libcall.n = 5
@@ -1046,6 +1126,7 @@
 }
 
 //go:nosplit
+//go:cgo_unsafe_args
 func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr {
 	mp := getg().m
 	mp.libcall.n = 6
@@ -1054,6 +1135,7 @@
 }
 
 //go:nosplit
+//go:cgo_unsafe_args
 func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
 	mp := getg().m
 	mp.libcall.n = 7
@@ -1061,29 +1143,42 @@
 	return stdcall(fn)
 }
 
-// In sys_windows_386.s and sys_windows_amd64.s.
-func onosstack(fn unsafe.Pointer, arg uint32)
-
-// These are not callable functions. They should only be called via onosstack.
-func usleep2(usec uint32)
-func usleep2HighRes(usec uint32)
+// These must run on the system stack only.
+func usleep2(dt int32)
+func usleep2HighRes(dt int32)
 func switchtothread()
 
-var usleep2Addr unsafe.Pointer
-var switchtothreadAddr unsafe.Pointer
+//go:nosplit
+func osyield_no_g() {
+	switchtothread()
+}
 
 //go:nosplit
 func osyield() {
-	onosstack(switchtothreadAddr, 0)
+	systemstack(switchtothread)
+}
+
+//go:nosplit
+func usleep_no_g(us uint32) {
+	dt := -10 * int32(us) // relative sleep (negative), 100ns units
+	usleep2(dt)
 }
 
 //go:nosplit
 func usleep(us uint32) {
-	// Have 1us units; want 100ns units.
-	onosstack(usleep2Addr, 10*us)
+	systemstack(func() {
+		dt := -10 * int32(us) // relative sleep (negative), 100ns units
+		// If the high-res timer is available and its handle has been allocated for this m, use it.
+		// Otherwise fall back to the low-res one, which doesn't need a handle.
+		if haveHighResTimer && getg().m.highResTimer != 0 {
+			usleep2HighRes(dt)
+		} else {
+			usleep2(dt)
+		}
+	})
 }
 
-func ctrlhandler1(_type uint32) uint32 {
+func ctrlHandler(_type uint32) uintptr {
 	var s uint32
 
 	switch _type {
@@ -1106,9 +1201,6 @@
 	return 0
 }
 
-// in sys_windows_386.s and sys_windows_amd64.s
-func profileloop()
-
 // called from zcallback_windows_*.s to sys_windows_*.s
 func callbackasm1()
 
@@ -1123,31 +1215,36 @@
 	c.contextflags = _CONTEXT_CONTROL
 	stdcall2(_GetThreadContext, thread, uintptr(unsafe.Pointer(c)))
 
-	gp := gFromTLS(mp)
+	gp := gFromSP(mp, c.sp())
 
 	sigprof(c.ip(), c.sp(), c.lr(), gp, mp)
 }
 
-func gFromTLS(mp *m) *g {
-	switch GOARCH {
-	case "arm":
-		tls := &mp.tls[0]
-		return **((***g)(unsafe.Pointer(tls)))
-	case "386", "amd64":
-		tls := &mp.tls[0]
-		return *((**g)(unsafe.Pointer(tls)))
+func gFromSP(mp *m, sp uintptr) *g {
+	if gp := mp.g0; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
+		return gp
 	}
-	throw("unsupported architecture")
+	if gp := mp.gsignal; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
+		return gp
+	}
+	if gp := mp.curg; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
+		return gp
+	}
 	return nil
 }
 
-func profileloop1(param uintptr) uint32 {
+func profileLoop() {
 	stdcall2(_SetThreadPriority, currentThread, _THREAD_PRIORITY_HIGHEST)
 
 	for {
 		stdcall2(_WaitForSingleObject, profiletimer, _INFINITE)
 		first := (*m)(atomic.Loadp(unsafe.Pointer(&allm)))
 		for mp := first; mp != nil; mp = mp.alllink {
+			if mp == getg().m {
+				// Don't profile ourselves.
+				continue
+			}
+
 			lock(&mp.threadLock)
 			// Do not profile threads blocked on Notes,
 			// this includes idle worker threads,
@@ -1159,8 +1256,8 @@
 			// Acquire our own handle to the thread.
 			var thread uintptr
 			if stdcall7(_DuplicateHandle, currentProcess, mp.thread, currentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
-				print("runtime.profileloop1: duplicatehandle failed; errno=", getlasterror(), "\n")
-				throw("runtime.profileloop1: duplicatehandle failed")
+				print("runtime: duplicatehandle failed; errno=", getlasterror(), "\n")
+				throw("duplicatehandle failed")
 			}
 			unlock(&mp.threadLock)
 
@@ -1188,9 +1285,7 @@
 	if profiletimer == 0 {
 		timer := stdcall3(_CreateWaitableTimerA, 0, 0, 0)
 		atomic.Storeuintptr(&profiletimer, timer)
-		thread := stdcall6(_CreateThread, 0, 0, funcPC(profileloop), 0, 0, 0)
-		stdcall2(_SetThreadPriority, thread, _THREAD_PRIORITY_HIGHEST)
-		stdcall1(_CloseHandle, thread)
+		newm(profileLoop, nil, -1)
 	}
 }
 
@@ -1208,14 +1303,14 @@
 	atomic.Store((*uint32)(unsafe.Pointer(&getg().m.profilehz)), uint32(hz))
 }
 
-const preemptMSupported = GOARCH != "arm"
+const preemptMSupported = GOARCH == "386" || GOARCH == "amd64"
 
 // suspendLock protects simultaneous SuspendThread operations from
 // suspending each other.
 var suspendLock mutex
 
 func preemptM(mp *m) {
-	if GOARCH == "arm" {
+	if !preemptMSupported {
 		// TODO: Implement call injection
 		return
 	}
@@ -1286,8 +1381,8 @@
 	unlock(&suspendLock)
 
 	// Does it want a preemption and is it safe to preempt?
-	gp := gFromTLS(mp)
-	if wantAsyncPreempt(gp) {
+	gp := gFromSP(mp, c.sp())
+	if gp != nil && wantAsyncPreempt(gp) {
 		if ok, newpc := isAsyncSafePoint(gp, c.ip(), c.sp(), c.lr()); ok {
 			// Inject call to asyncPreempt
 			targetPC := funcPC(asyncPreempt)
diff --git a/src/runtime/os_windows_arm64.go b/src/runtime/os_windows_arm64.go
new file mode 100644
index 0000000..7e41344
--- /dev/null
+++ b/src/runtime/os_windows_arm64.go
@@ -0,0 +1,14 @@
+// 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 runtime
+
+import "unsafe"
+
+//go:nosplit
+func cputicks() int64 {
+	var counter int64
+	stdcall1(_QueryPerformanceCounter, uintptr(unsafe.Pointer(&counter)))
+	return counter
+}
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index 5b2ccdd..f6c38aa 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -5,6 +5,8 @@
 package runtime
 
 import (
+	"internal/abi"
+	"internal/goexperiment"
 	"runtime/internal/atomic"
 	"runtime/internal/sys"
 	"unsafe"
@@ -158,6 +160,12 @@
 	panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3C})
 }
 
+// failures in the conversion (*[x]T)s, 0 <= x <= y, x == cap(s)
+func goPanicSliceConvert(x int, y int) {
+	panicCheck1(getcallerpc(), "slice length too short to convert to pointer to array")
+	panic(boundsError{x: int64(x), signed: true, y: y, code: boundsConvert})
+}
+
 // Implemented in assembly, as they take arguments in registers.
 // Declared here to mark them as ABIInternal.
 func panicIndex(x int, y int)
@@ -176,6 +184,7 @@
 func panicSlice3BU(x uint, y int)
 func panicSlice3C(x int, y int)
 func panicSlice3CU(x uint, y int)
+func panicSliceConvert(x int, y int)
 
 var shiftError = error(errorString("negative shift amount"))
 
@@ -227,6 +236,11 @@
 		throw("defer on system stack")
 	}
 
+	if goexperiment.RegabiDefer && siz != 0 {
+		// TODO: Make deferproc just take a func().
+		throw("defer with non-empty frame")
+	}
+
 	// the arguments of fn are in a perilous state. The stack map
 	// for deferproc does not describe them. So we can't let garbage
 	// collection or stack copying trigger until we've copied them out
@@ -279,6 +293,9 @@
 		// go code on the system stack can't defer
 		throw("defer on system stack")
 	}
+	if goexperiment.RegabiDefer && d.siz != 0 {
+		throw("defer with non-empty frame")
+	}
 	// siz and fn are already set.
 	// The other fields are junk on entry to deferprocStack and
 	// are initialized here.
@@ -373,6 +390,19 @@
 	return add(unsafe.Pointer(d), unsafe.Sizeof(*d))
 }
 
+// deferFunc returns d's deferred function. This is temporary while we
+// support both modes of GOEXPERIMENT=regabidefer. Once we commit to
+// that experiment, we should change the type of d.fn.
+//go:nosplit
+func deferFunc(d *_defer) func() {
+	if !goexperiment.RegabiDefer {
+		throw("requires GOEXPERIMENT=regabidefer")
+	}
+	var fn func()
+	*(**funcval)(unsafe.Pointer(&fn)) = d.fn
+	return fn
+}
+
 var deferType *_type // type of _defer struct
 
 func init() {
@@ -518,10 +548,8 @@
 // modifying the caller's frame in order to reuse the frame to call the deferred
 // function.
 //
-// The single argument isn't actually used - it just has its address
-// taken so it can be matched against pending defers.
 //go:nosplit
-func deferreturn(arg0 uintptr) {
+func deferreturn() {
 	gp := getg()
 	d := gp._defer
 	if d == nil {
@@ -547,13 +575,14 @@
 	// nosplit because the garbage collector won't know the form
 	// of the arguments until the jmpdefer can flip the PC over to
 	// fn.
+	argp := getcallersp() + sys.MinFrameSize
 	switch d.siz {
 	case 0:
 		// Do nothing.
 	case sys.PtrSize:
-		*(*uintptr)(unsafe.Pointer(&arg0)) = *(*uintptr)(deferArgs(d))
+		*(*uintptr)(unsafe.Pointer(argp)) = *(*uintptr)(deferArgs(d))
 	default:
-		memmove(unsafe.Pointer(&arg0), deferArgs(d), uintptr(d.siz))
+		memmove(unsafe.Pointer(argp), deferArgs(d), uintptr(d.siz))
 	}
 	fn := d.fn
 	d.fn = nil
@@ -565,7 +594,7 @@
 	// stack, because the stack trace can be incorrect in that case - see
 	// issue #8153).
 	_ = fn.fn
-	jmpdefer(fn, uintptr(unsafe.Pointer(&arg0)))
+	jmpdefer(fn, argp)
 }
 
 // Goexit terminates the goroutine that calls it. No other goroutine is affected.
@@ -626,10 +655,15 @@
 				addOneOpenDeferFrame(gp, 0, nil)
 			}
 		} else {
-
-			// Save the pc/sp in reflectcallSave(), so we can "recover" back to this
-			// loop if necessary.
-			reflectcallSave(&p, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz))
+			if goexperiment.RegabiDefer {
+				// Save the pc/sp in deferCallSave(), so we can "recover" back to this
+				// loop if necessary.
+				deferCallSave(&p, deferFunc(d))
+			} else {
+				// Save the pc/sp in reflectcallSave(), so we can "recover" back to this
+				// loop if necessary.
+				reflectcallSave(&p, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz))
+			}
 		}
 		if p.aborted {
 			// We had a recursive panic in the defer d we started, and
@@ -698,7 +732,7 @@
 // specified by sp. If sp is nil, it uses the sp from the current defer record
 // (which has just been finished). Hence, it continues the stack scan from the
 // frame of the defer that just finished. It skips any frame that already has an
-// open-coded _defer record, which would have been been created from a previous
+// open-coded _defer record, which would have been created from a previous
 // (unrecovered) panic.
 //
 // Note: All entries of the defer chain (including this new open-coded entry) have
@@ -823,6 +857,9 @@
 		argWidth, fd = readvarintUnsafe(fd)
 		closureOffset, fd = readvarintUnsafe(fd)
 		nArgs, fd = readvarintUnsafe(fd)
+		if goexperiment.RegabiDefer && argWidth != 0 {
+			throw("defer with non-empty frame")
+		}
 		if deferBits&(1<<i) == 0 {
 			for j := uint32(0); j < nArgs; j++ {
 				_, fd = readvarintUnsafe(fd)
@@ -848,7 +885,11 @@
 		deferBits = deferBits &^ (1 << i)
 		*(*uint8)(unsafe.Pointer(d.varp - uintptr(deferBitsOffset))) = deferBits
 		p := d._panic
-		reflectcallSave(p, unsafe.Pointer(closure), deferArgs, argWidth)
+		if goexperiment.RegabiDefer {
+			deferCallSave(p, deferFunc(d))
+		} else {
+			reflectcallSave(p, unsafe.Pointer(closure), deferArgs, argWidth)
+		}
 		if p != nil && p.aborted {
 			break
 		}
@@ -868,13 +909,45 @@
 // panic record. This allows the runtime to return to the Goexit defer processing
 // loop, in the unusual case where the Goexit may be bypassed by a successful
 // recover.
+//
+// This is marked as a wrapper by the compiler so it doesn't appear in
+// tracebacks.
 func reflectcallSave(p *_panic, fn, arg unsafe.Pointer, argsize uint32) {
+	if goexperiment.RegabiDefer {
+		throw("not allowed with GOEXPERIMENT=regabidefer")
+	}
 	if p != nil {
-		p.argp = unsafe.Pointer(getargp(0))
+		p.argp = unsafe.Pointer(getargp())
 		p.pc = getcallerpc()
 		p.sp = unsafe.Pointer(getcallersp())
 	}
-	reflectcall(nil, fn, arg, argsize, argsize)
+	// Pass a dummy RegArgs since we'll only take this path if
+	// we're not using the register ABI.
+	var regs abi.RegArgs
+	reflectcall(nil, fn, arg, argsize, argsize, argsize, &regs)
+	if p != nil {
+		p.pc = 0
+		p.sp = unsafe.Pointer(nil)
+	}
+}
+
+// deferCallSave calls fn() after saving the caller's pc and sp in the
+// panic record. This allows the runtime to return to the Goexit defer
+// processing loop, in the unusual case where the Goexit may be
+// bypassed by a successful recover.
+//
+// This is marked as a wrapper by the compiler so it doesn't appear in
+// tracebacks.
+func deferCallSave(p *_panic, fn func()) {
+	if !goexperiment.RegabiDefer {
+		throw("only allowed with GOEXPERIMENT=regabidefer")
+	}
+	if p != nil {
+		p.argp = unsafe.Pointer(getargp())
+		p.pc = getcallerpc()
+		p.sp = unsafe.Pointer(getcallersp())
+	}
+	fn()
 	if p != nil {
 		p.pc = 0
 		p.sp = unsafe.Pointer(nil)
@@ -952,7 +1025,7 @@
 
 		// Mark defer as started, but keep on list, so that traceback
 		// can find and update the defer's argument frame if stack growth
-		// or a garbage collection happens before reflectcall starts executing d.fn.
+		// or a garbage collection happens before executing d.fn.
 		d.started = true
 
 		// Record the panic that is running the defer.
@@ -967,12 +1040,21 @@
 				addOneOpenDeferFrame(gp, 0, nil)
 			}
 		} else {
-			p.argp = unsafe.Pointer(getargp(0))
-			reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
+			p.argp = unsafe.Pointer(getargp())
+
+			if goexperiment.RegabiDefer {
+				fn := deferFunc(d)
+				fn()
+			} else {
+				// Pass a dummy RegArgs since we'll only take this path if
+				// we're not using the register ABI.
+				var regs abi.RegArgs
+				reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz), uint32(d.siz), &regs)
+			}
 		}
 		p.argp = nil
 
-		// reflectcall did not panic. Remove d.
+		// Deferred function did not panic. Remove d.
 		if gp._defer != d {
 			throw("bad defer entry in panic")
 		}
@@ -1070,9 +1152,8 @@
 // writes outgoing function call arguments.
 //go:nosplit
 //go:noinline
-func getargp(x int) uintptr {
-	// x is an argument mainly so that we can return its address.
-	return uintptr(noescape(unsafe.Pointer(&x)))
+func getargp() uintptr {
+	return getcallersp() + sys.MinFrameSize
 }
 
 // The implementation of the predeclared function recover.
@@ -1409,5 +1490,9 @@
 //
 //go:nosplit
 func isAbortPC(pc uintptr) bool {
-	return pc == funcPC(abort) || ((GOARCH == "arm" || GOARCH == "arm64") && pc == funcPC(abort)+sys.PCQuantum)
+	f := findfunc(pc)
+	if !f.valid() {
+		return false
+	}
+	return f.funcID == funcID_abort
 }
diff --git a/src/runtime/panic32.go b/src/runtime/panic32.go
index aea8401..acbdd1f 100644
--- a/src/runtime/panic32.go
+++ b/src/runtime/panic32.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 || arm || mips || mipsle
 // +build 386 arm mips mipsle
 
 package runtime
diff --git a/src/runtime/plugin.go b/src/runtime/plugin.go
index 5e05be7..cd7fc5f 100644
--- a/src/runtime/plugin.go
+++ b/src/runtime/plugin.go
@@ -115,7 +115,8 @@
 			entry2 = f2.entry
 		}
 		badtable = true
-		println("ftab entry outside pc range: ", hex(entry), "/", hex(entry2), ": ", name, "/", name2)
+		println("ftab entry", hex(entry), "/", hex(entry2), ": ",
+			name, "/", name2, "outside pc range:[", hex(md.minpc), ",", hex(md.maxpc), "], modulename=", md.modulename, ", pluginpath=", md.pluginpath)
 	}
 	if badtable {
 		throw("runtime: plugin has bad symbol table")
diff --git a/src/runtime/pprof/mprof_test.go b/src/runtime/pprof/mprof_test.go
index c11a45f..b4680fb 100644
--- a/src/runtime/pprof/mprof_test.go
+++ b/src/runtime/pprof/mprof_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package pprof
@@ -85,6 +86,17 @@
 
 	runtime.GC() // materialize stats
 
+	// TODO(mknyszek): Fix #45315 and remove this extra call.
+	//
+	// Unfortunately, it's possible for the sweep termination condition
+	// to flap, so with just one runtime.GC call, a freed object could be
+	// missed, leading this test to fail. A second call reduces the chance
+	// of this happening to zero, because sweeping actually has to finish
+	// to move on to the next GC, during which nothing will happen.
+	//
+	// See #46500 for more details.
+	runtime.GC()
+
 	memoryProfilerRun++
 
 	tests := []struct {
@@ -93,31 +105,31 @@
 	}{{
 		stk: []string{"runtime/pprof.allocatePersistent1K", "runtime/pprof.TestMemoryProfiler"},
 		legacy: fmt.Sprintf(`%v: %v \[%v: %v\] @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
-#	0x[0-9,a-f]+	runtime/pprof\.allocatePersistent1K\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test\.go:47
-#	0x[0-9,a-f]+	runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test\.go:82
+#	0x[0-9,a-f]+	runtime/pprof\.allocatePersistent1K\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test\.go:48
+#	0x[0-9,a-f]+	runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test\.go:83
 `, 32*memoryProfilerRun, 1024*memoryProfilerRun, 32*memoryProfilerRun, 1024*memoryProfilerRun),
 	}, {
 		stk: []string{"runtime/pprof.allocateTransient1M", "runtime/pprof.TestMemoryProfiler"},
 		legacy: fmt.Sprintf(`0: 0 \[%v: %v\] @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
-#	0x[0-9,a-f]+	runtime/pprof\.allocateTransient1M\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:24
-#	0x[0-9,a-f]+	runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:79
+#	0x[0-9,a-f]+	runtime/pprof\.allocateTransient1M\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:25
+#	0x[0-9,a-f]+	runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:80
 `, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun),
 	}, {
 		stk: []string{"runtime/pprof.allocateTransient2M", "runtime/pprof.TestMemoryProfiler"},
 		legacy: fmt.Sprintf(`0: 0 \[%v: %v\] @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
-#	0x[0-9,a-f]+	runtime/pprof\.allocateTransient2M\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:30
-#	0x[0-9,a-f]+	runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:80
+#	0x[0-9,a-f]+	runtime/pprof\.allocateTransient2M\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:31
+#	0x[0-9,a-f]+	runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:81
 `, memoryProfilerRun, (2<<20)*memoryProfilerRun),
 	}, {
 		stk: []string{"runtime/pprof.allocateTransient2MInline", "runtime/pprof.TestMemoryProfiler"},
 		legacy: fmt.Sprintf(`0: 0 \[%v: %v\] @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
-#	0x[0-9,a-f]+	runtime/pprof\.allocateTransient2MInline\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:34
-#	0x[0-9,a-f]+	runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:81
+#	0x[0-9,a-f]+	runtime/pprof\.allocateTransient2MInline\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:35
+#	0x[0-9,a-f]+	runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:82
 `, memoryProfilerRun, (2<<20)*memoryProfilerRun),
 	}, {
 		stk: []string{"runtime/pprof.allocateReflectTransient"},
 		legacy: fmt.Sprintf(`0: 0 \[%v: %v\] @( 0x[0-9,a-f]+)+
-#	0x[0-9,a-f]+	runtime/pprof\.allocateReflectTransient\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:55
+#	0x[0-9,a-f]+	runtime/pprof\.allocateReflectTransient\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:56
 `, memoryProfilerRun, (2<<20)*memoryProfilerRun),
 	}}
 
diff --git a/src/runtime/pprof/pprof.go b/src/runtime/pprof/pprof.go
index d3b7df3..99eda10 100644
--- a/src/runtime/pprof/pprof.go
+++ b/src/runtime/pprof/pprof.go
@@ -843,45 +843,7 @@
 
 // writeBlock writes the current blocking profile to w.
 func writeBlock(w io.Writer, debug int) error {
-	var p []runtime.BlockProfileRecord
-	n, ok := runtime.BlockProfile(nil)
-	for {
-		p = make([]runtime.BlockProfileRecord, n+50)
-		n, ok = runtime.BlockProfile(p)
-		if ok {
-			p = p[:n]
-			break
-		}
-	}
-
-	sort.Slice(p, func(i, j int) bool { return p[i].Cycles > p[j].Cycles })
-
-	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 {
-		r := &p[i]
-		fmt.Fprintf(w, "%v %v @", r.Cycles, r.Count)
-		for _, pc := range r.Stack() {
-			fmt.Fprintf(w, " %#x", pc)
-		}
-		fmt.Fprint(w, "\n")
-		if debug > 0 {
-			printStackRecord(w, r.Stack(), true)
-		}
-	}
-
-	if tw != nil {
-		tw.Flush()
-	}
-	return b.Flush()
+	return writeProfileInternal(w, debug, "contention", runtime.BlockProfile, scaleBlockProfile)
 }
 
 func scaleBlockProfile(cnt int64, ns float64) (int64, float64) {
@@ -894,12 +856,16 @@
 
 // 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!
+	return writeProfileInternal(w, debug, "mutex", runtime.MutexProfile, scaleMutexProfile)
+}
+
+// writeProfileInternal writes the current blocking or mutex profile depending on the passed parameters
+func writeProfileInternal(w io.Writer, debug int, name string, runtimeProfile func([]runtime.BlockProfileRecord) (int, bool), scaleProfile func(int64, float64) (int64, float64)) error {
 	var p []runtime.BlockProfileRecord
-	n, ok := runtime.MutexProfile(nil)
+	n, ok := runtimeProfile(nil)
 	for {
 		p = make([]runtime.BlockProfileRecord, n+50)
-		n, ok = runtime.MutexProfile(p)
+		n, ok = runtimeProfile(p)
 		if ok {
 			p = p[:n]
 			break
@@ -909,16 +875,18 @@
 	sort.Slice(p, func(i, j int) bool { return p[i].Cycles > p[j].Cycles })
 
 	if debug <= 0 {
-		return printCountCycleProfile(w, "contentions", "delay", scaleMutexProfile, p)
+		return printCountCycleProfile(w, "contentions", "delay", scaleProfile, p)
 	}
 
 	b := bufio.NewWriter(w)
 	tw := tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
 	w = tw
 
-	fmt.Fprintf(w, "--- mutex:\n")
+	fmt.Fprintf(w, "--- %v:\n", name)
 	fmt.Fprintf(w, "cycles/second=%v\n", runtime_cyclesPerSecond())
-	fmt.Fprintf(w, "sampling period=%d\n", runtime.SetMutexProfileFraction(-1))
+	if name == "mutex" {
+		fmt.Fprintf(w, "sampling period=%d\n", runtime.SetMutexProfileFraction(-1))
+	}
 	for i := range p {
 		r := &p[i]
 		fmt.Fprintf(w, "%v %v @", r.Cycles, r.Count)
diff --git a/src/runtime/pprof/pprof_norusage.go b/src/runtime/pprof/pprof_norusage.go
index 6fdcc6c..e175dd3 100644
--- a/src/runtime/pprof/pprof_norusage.go
+++ b/src/runtime/pprof/pprof_norusage.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !darwin && !linux
 // +build !darwin,!linux
 
 package pprof
diff --git a/src/runtime/pprof/pprof_rusage.go b/src/runtime/pprof/pprof_rusage.go
index 7954673..269f21b 100644
--- a/src/runtime/pprof/pprof_rusage.go
+++ b/src/runtime/pprof/pprof_rusage.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || linux
 // +build darwin linux
 
 package pprof
diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go
index b6ee160..7c71d82 100644
--- a/src/runtime/pprof/pprof_test.go
+++ b/src/runtime/pprof/pprof_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 package pprof
@@ -13,6 +14,7 @@
 	"internal/profile"
 	"internal/testenv"
 	"io"
+	"math"
 	"math/big"
 	"os"
 	"os/exec"
@@ -23,6 +25,7 @@
 	"sync/atomic"
 	"testing"
 	"time"
+	_ "unsafe"
 )
 
 func cpuHogger(f func(x int) int, y *int, dur time.Duration) {
@@ -257,39 +260,43 @@
 	return p
 }
 
+func cpuProfilingBroken() bool {
+	switch runtime.GOOS {
+	case "plan9":
+		// Profiling unimplemented.
+		return true
+	case "aix":
+		// See https://golang.org/issue/45170.
+		return true
+	case "ios", "dragonfly", "netbsd", "illumos", "solaris":
+		// See https://golang.org/issue/13841.
+		return true
+	case "openbsd":
+		if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
+			// See https://golang.org/issue/13841.
+			return true
+		}
+	}
+
+	return false
+}
+
 // testCPUProfile runs f under the CPU profiler, checking for some conditions specified by need,
 // as interpreted by matches, and returns the parsed profile.
 func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []string, f func(dur time.Duration)) *profile.Profile {
 	switch runtime.GOOS {
-	case "darwin", "ios":
-		switch runtime.GOARCH {
-		case "arm64":
-			// nothing
-		default:
-			out, err := exec.Command("uname", "-a").CombinedOutput()
-			if err != nil {
-				t.Fatal(err)
-			}
-			vers := string(out)
-			t.Logf("uname -a: %v", vers)
+	case "darwin":
+		out, err := exec.Command("uname", "-a").CombinedOutput()
+		if err != nil {
+			t.Fatal(err)
 		}
+		vers := string(out)
+		t.Logf("uname -a: %v", vers)
 	case "plan9":
 		t.Skip("skipping on plan9")
 	}
 
-	broken := false
-	switch runtime.GOOS {
-	case "darwin", "ios", "dragonfly", "netbsd", "illumos", "solaris":
-		broken = true
-	case "openbsd":
-		if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
-			broken = true
-		}
-	case "windows":
-		if runtime.GOARCH == "arm" {
-			broken = true // See https://golang.org/issues/42862
-		}
-	}
+	broken := cpuProfilingBroken()
 
 	maxDuration := 5 * time.Second
 	if testing.Short() && broken {
@@ -514,8 +521,10 @@
 		}
 		StopCPUProfile()
 
-		// Read profile to look for entries for runtime.gogo with an attempt at a traceback.
-		// The special entry
+		// Read profile to look for entries for gogo with an attempt at a traceback.
+		// "runtime.gogo" is OK, because that's the part of the context switch
+		// before the actual switch begins. But we should not see "gogo",
+		// aka "gogo<>(SB)", which does the actual switch and is marked SPWRITE.
 		parseProfile(t, prof.Bytes(), func(count uintptr, stk []*profile.Location, _ map[string][]string) {
 			// An entry with two frames with 'System' in its top frame
 			// exists to record a PC without a traceback. Those are okay.
@@ -526,13 +535,19 @@
 				}
 			}
 
-			// Otherwise, should not see runtime.gogo.
+			// An entry with just one frame is OK too:
+			// it knew to stop at gogo.
+			if len(stk) == 1 {
+				return
+			}
+
+			// Otherwise, should not see gogo.
 			// The place we'd see it would be the inner most frame.
 			name := stk[0].Line[0].Function.Name
-			if name == "runtime.gogo" {
+			if name == "gogo" {
 				var buf bytes.Buffer
 				fprintStack(&buf, stk)
-				t.Fatalf("found profile entry for runtime.gogo:\n%s", buf.String())
+				t.Fatalf("found profile entry for gogo:\n%s", buf.String())
 			}
 		})
 	}
@@ -603,17 +618,20 @@
 
 //go:noinline
 func growstack1() {
-	growstack()
+	growstack(10)
 }
 
 //go:noinline
-func growstack() {
-	var buf [8 << 10]byte
+func growstack(n int) {
+	var buf [8 << 18]byte
 	use(buf)
+	if n > 0 {
+		growstack(n - 1)
+	}
 }
 
 //go:noinline
-func use(x [8 << 10]byte) {}
+func use(x [8 << 18]byte) {}
 
 func TestBlockProfile(t *testing.T) {
 	type TestCase struct {
@@ -891,6 +909,74 @@
 	mu.Unlock()
 }
 
+// See http://golang.org/cl/299991.
+func TestBlockProfileBias(t *testing.T) {
+	rate := int(1000) // arbitrary value
+	runtime.SetBlockProfileRate(rate)
+	defer runtime.SetBlockProfileRate(0)
+
+	// simulate blocking events
+	blockFrequentShort(rate)
+	blockInfrequentLong(rate)
+
+	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)
+
+	il := float64(-1) // blockInfrequentLong duration
+	fs := float64(-1) // blockFrequentShort duration
+	for _, s := range p.Sample {
+		for _, l := range s.Location {
+			for _, line := range l.Line {
+				if len(s.Value) < 2 {
+					t.Fatal("block profile has less than 2 sample types")
+				}
+
+				if line.Function.Name == "runtime/pprof.blockInfrequentLong" {
+					il = float64(s.Value[1])
+				} else if line.Function.Name == "runtime/pprof.blockFrequentShort" {
+					fs = float64(s.Value[1])
+				}
+			}
+		}
+	}
+	if il == -1 || fs == -1 {
+		t.Fatal("block profile is missing expected functions")
+	}
+
+	// stddev of bias from 100 runs on local machine multiplied by 10x
+	const threshold = 0.2
+	if bias := (il - fs) / il; math.Abs(bias) > threshold {
+		t.Fatalf("bias: abs(%f) > %f", bias, threshold)
+	} else {
+		t.Logf("bias: abs(%f) < %f", bias, threshold)
+	}
+}
+
+// blockFrequentShort produces 100000 block events with an average duration of
+// rate / 10.
+func blockFrequentShort(rate int) {
+	for i := 0; i < 100000; i++ {
+		blockevent(int64(rate/10), 1)
+	}
+}
+
+// blockFrequentShort produces 10000 block events with an average duration of
+// rate.
+func blockInfrequentLong(rate int) {
+	for i := 0; i < 10000; i++ {
+		blockevent(int64(rate), 1)
+	}
+}
+
+// Used by TestBlockProfileBias.
+//go:linkname blockevent runtime.blockevent
+func blockevent(cycles int64, skip int)
+
 func TestMutexProfile(t *testing.T) {
 	// Generate mutex profile
 
diff --git a/src/runtime/preempt.go b/src/runtime/preempt.go
index 3721852..1d5aae1 100644
--- a/src/runtime/preempt.go
+++ b/src/runtime/preempt.go
@@ -413,6 +413,8 @@
 		//
 		// TODO: Are there cases that are safe but don't have a
 		// locals pointer map, like empty frame functions?
+		// It might be possible to preempt any assembly functions
+		// except the ones that have funcFlag_SPWRITE set in f.flag.
 		return false, 0
 	}
 	name := funcname(f)
diff --git a/src/runtime/preempt_amd64.s b/src/runtime/preempt_amd64.s
index 92c664d..dc7af80 100644
--- a/src/runtime/preempt_amd64.s
+++ b/src/runtime/preempt_amd64.s
@@ -13,11 +13,6 @@
 	ADJSP $368
 	// But vet doesn't know ADJSP, so suppress vet stack checking
 	NOP SP
-	#ifdef GOOS_darwin
-	CMPB internal∕cpu·X86+const_offsetX86HasAVX(SB), $0
-	JE 2(PC)
-	VZEROUPPER
-	#endif
 	MOVQ AX, 0(SP)
 	MOVQ CX, 8(SP)
 	MOVQ DX, 16(SP)
@@ -32,6 +27,11 @@
 	MOVQ R13, 88(SP)
 	MOVQ R14, 96(SP)
 	MOVQ R15, 104(SP)
+	#ifdef GOOS_darwin
+	CMPB internal∕cpu·X86+const_offsetX86HasAVX(SB), $0
+	JE 2(PC)
+	VZEROUPPER
+	#endif
 	MOVUPS X0, 112(SP)
 	MOVUPS X1, 128(SP)
 	MOVUPS X2, 144(SP)
diff --git a/src/runtime/preempt_mips64x.s b/src/runtime/preempt_mips64x.s
index 0d0c157..b755425 100644
--- a/src/runtime/preempt_mips64x.s
+++ b/src/runtime/preempt_mips64x.s
@@ -1,5 +1,6 @@
 // Code generated by mkpreempt.go; DO NOT EDIT.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "go_asm.h"
diff --git a/src/runtime/preempt_mipsx.s b/src/runtime/preempt_mipsx.s
index 86d3a91..c1bff60 100644
--- a/src/runtime/preempt_mipsx.s
+++ b/src/runtime/preempt_mipsx.s
@@ -1,5 +1,6 @@
 // Code generated by mkpreempt.go; DO NOT EDIT.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "go_asm.h"
diff --git a/src/runtime/preempt_nonwindows.go b/src/runtime/preempt_nonwindows.go
index 3066a15..365e86a 100644
--- a/src/runtime/preempt_nonwindows.go
+++ b/src/runtime/preempt_nonwindows.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows
 // +build !windows
 
 package runtime
diff --git a/src/runtime/preempt_ppc64x.s b/src/runtime/preempt_ppc64x.s
index 9063438..70bd919 100644
--- a/src/runtime/preempt_ppc64x.s
+++ b/src/runtime/preempt_ppc64x.s
@@ -1,5 +1,6 @@
 // Code generated by mkpreempt.go; DO NOT EDIT.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "go_asm.h"
diff --git a/src/runtime/print.go b/src/runtime/print.go
index 64055a3..f15296c 100644
--- a/src/runtime/print.go
+++ b/src/runtime/print.go
@@ -216,13 +216,15 @@
 	printuint(uint64(v))
 }
 
+var minhexdigits = 0 // protected by printlock
+
 func printhex(v uint64) {
 	const dig = "0123456789abcdef"
 	var buf [100]byte
 	i := len(buf)
 	for i--; i > 0; i-- {
 		buf[i] = dig[v%16]
-		if v < 16 {
+		if v < 16 && len(buf)-i >= minhexdigits {
 			break
 		}
 		v /= 16
@@ -265,29 +267,16 @@
 // 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] = ' '
+	minhexdigits = int(unsafe.Sizeof(uintptr(0)) * 2)
 	for i := uintptr(0); p+i < end; i += sys.PtrSize {
 		if i%16 == 0 {
 			if i != 0 {
 				println()
 			}
-			p1(p + i)
-			print(": ")
+			print(hex(p+i), ": ")
 		}
 
 		if mark != nil {
@@ -298,15 +287,16 @@
 		}
 		gwrite(markbuf[:])
 		val := *(*uintptr)(unsafe.Pointer(p + i))
-		p1(val)
+		print(hex(val))
 		print(" ")
 
 		// Can we symbolize val?
 		fn := findfunc(val)
 		if fn.valid() {
-			print("<", funcname(fn), "+", val-fn.entry, "> ")
+			print("<", funcname(fn), "+", hex(val-fn.entry), "> ")
 		}
 	}
+	minhexdigits = 0
 	println()
 	printunlock()
 }
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 73a789c..a144b36 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -5,15 +5,14 @@
 package runtime
 
 import (
-	"internal/bytealg"
+	"internal/abi"
 	"internal/cpu"
+	"internal/goexperiment"
 	"runtime/internal/atomic"
 	"runtime/internal/sys"
 	"unsafe"
 )
 
-var buildVersion = sys.TheVersion
-
 // set using cmd/go/internal/modload.ModInfoProg
 var modinfo string
 
@@ -52,33 +51,64 @@
 //    any work to do.
 //
 // The current approach:
-// We unpark an additional thread when we ready a goroutine if (1) there is an
-// idle P and there are no "spinning" worker threads. A worker thread is considered
-// spinning if it is out of local work and did not find work in global run queue/
-// netpoller; the spinning state is denoted in m.spinning and in sched.nmspinning.
-// Threads unparked this way are also considered spinning; we don't do goroutine
-// handoff so such threads are out of work initially. Spinning threads do some
-// spinning looking for work in per-P run queues before parking. If a spinning
-// thread finds work it takes itself out of the spinning state and proceeds to
-// execution. If it does not find work it takes itself out of the spinning state
-// and then parks.
-// If there is at least one spinning thread (sched.nmspinning>1), we don't unpark
-// new threads when readying goroutines. To compensate for that, if the last spinning
-// thread finds work and stops spinning, it must unpark a new spinning thread.
-// This approach smooths out unjustified spikes of thread unparking,
-// but at the same time guarantees eventual maximal CPU parallelism utilization.
 //
-// The main implementation complication is that we need to be very careful during
-// spinning->non-spinning thread transition. This transition can race with submission
-// of a new goroutine, and either one part or another needs to unpark another worker
-// thread. If they both fail to do that, we can end up with semi-persistent CPU
-// underutilization. The general pattern for goroutine readying is: submit a goroutine
-// to local work queue, #StoreLoad-style memory barrier, check sched.nmspinning.
-// The general pattern for spinning->non-spinning transition is: decrement nmspinning,
-// #StoreLoad-style memory barrier, check all per-P work queues for new work.
-// Note that all this complexity does not apply to global run queue as we are not
-// sloppy about thread unparking when submitting to global queue. Also see comments
-// for nmspinning manipulation.
+// This approach applies to three primary sources of potential work: readying a
+// goroutine, new/modified-earlier timers, and idle-priority GC. See below for
+// additional details.
+//
+// We unpark an additional thread when we submit work if (this is wakep()):
+// 1. There is an idle P, and
+// 2. There are no "spinning" worker threads.
+//
+// A worker thread is considered spinning if it is out of local work and did
+// not find work in the global run queue or netpoller; the spinning state is
+// denoted in m.spinning and in sched.nmspinning. Threads unparked this way are
+// also considered spinning; we don't do goroutine handoff so such threads are
+// out of work initially. Spinning threads spin on looking for work in per-P
+// run queues and timer heaps or from the GC before parking. If a spinning
+// thread finds work it takes itself out of the spinning state and proceeds to
+// execution. If it does not find work it takes itself out of the spinning
+// state and then parks.
+//
+// If there is at least one spinning thread (sched.nmspinning>1), we don't
+// unpark new threads when submitting work. To compensate for that, if the last
+// spinning thread finds work and stops spinning, it must unpark a new spinning
+// thread.  This approach smooths out unjustified spikes of thread unparking,
+// but at the same time guarantees eventual maximal CPU parallelism
+// utilization.
+//
+// The main implementation complication is that we need to be very careful
+// during spinning->non-spinning thread transition. This transition can race
+// with submission of new work, and either one part or another needs to unpark
+// another worker thread. If they both fail to do that, we can end up with
+// semi-persistent CPU underutilization.
+//
+// The general pattern for submission is:
+// 1. Submit work to the local run queue, timer heap, or GC state.
+// 2. #StoreLoad-style memory barrier.
+// 3. Check sched.nmspinning.
+//
+// The general pattern for spinning->non-spinning transition is:
+// 1. Decrement nmspinning.
+// 2. #StoreLoad-style memory barrier.
+// 3. Check all per-P work queues and GC for new work.
+//
+// Note that all this complexity does not apply to global run queue as we are
+// not sloppy about thread unparking when submitting to global queue. Also see
+// comments for nmspinning manipulation.
+//
+// How these different sources of work behave varies, though it doesn't affect
+// the synchronization approach:
+// * Ready goroutine: this is an obvious source of work; the goroutine is
+//   immediately ready and must run on some thread eventually.
+// * New/modified-earlier timer: The current timer implementation (see time.go)
+//   uses netpoll in a thread with no work available to wait for the soonest
+//   timer. If there is no thread waiting, we want a new spinning thread to go
+//   wait.
+// * Idle-priority GC: The GC wakes a stopped idle thread to contribute to
+//   background GC work (note: currently disabled per golang.org/issue/19112).
+//   Also see golang.org/issue/44313, as this should be extended to all GC
+//   workers.
 
 var (
 	m0           m
@@ -499,8 +529,8 @@
 	allglock mutex
 	allgs    []*g
 
-	// allglen and allgptr are atomic variables that contain len(allg) and
-	// &allg[0] respectively. Proper ordering depends on totally-ordered
+	// allglen and allgptr are atomic variables that contain len(allgs) and
+	// &allgs[0] respectively. Proper ordering depends on totally-ordered
 	// loads and stores. Writes are protected by allglock.
 	//
 	// allgptr is updated before allglen. Readers should read allglen
@@ -541,6 +571,30 @@
 	return *(**g)(add(unsafe.Pointer(ptr), i*sys.PtrSize))
 }
 
+// forEachG calls fn on every G from allgs.
+//
+// forEachG takes a lock to exclude concurrent addition of new Gs.
+func forEachG(fn func(gp *g)) {
+	lock(&allglock)
+	for _, gp := range allgs {
+		fn(gp)
+	}
+	unlock(&allglock)
+}
+
+// forEachGRace calls fn on every G from allgs.
+//
+// forEachGRace avoids locking, but does not exclude addition of new Gs during
+// execution, which may be missed.
+func forEachGRace(fn func(gp *g)) {
+	ptr, length := atomicAllG()
+	for i := uintptr(0); i < length; i++ {
+		gp := atomicAllGIndex(ptr, i)
+		fn(gp)
+	}
+	return
+}
+
 const (
 	// Number of goroutine ids to grab from sched.goidgen to local per-P cache at once.
 	// 16 seems to provide enough amortization, but other than that it's mostly arbitrary number.
@@ -644,6 +698,11 @@
 	sigsave(&_g_.m.sigmask)
 	initSigmask = _g_.m.sigmask
 
+	if offset := unsafe.Offsetof(sched.timeToRun); offset%8 != 0 {
+		println(offset)
+		throw("sched.timeToRun not aligned to 8 bytes")
+	}
+
 	goargs()
 	goenvs()
 	parsedebugvars()
@@ -920,6 +979,37 @@
 			nextYield = nanotime() + yieldDelay/2
 		}
 	}
+
+	// Handle tracking for scheduling latencies.
+	if oldval == _Grunning {
+		// Track every 8th time a goroutine transitions out of running.
+		if gp.trackingSeq%gTrackingPeriod == 0 {
+			gp.tracking = true
+		}
+		gp.trackingSeq++
+	}
+	if gp.tracking {
+		now := nanotime()
+		if oldval == _Grunnable {
+			// We transitioned out of runnable, so measure how much
+			// time we spent in this state and add it to
+			// runnableTime.
+			gp.runnableTime += now - gp.runnableStamp
+			gp.runnableStamp = 0
+		}
+		if newval == _Grunnable {
+			// We just transitioned into runnable, so record what
+			// time that happened.
+			gp.runnableStamp = now
+		} else if newval == _Grunning {
+			// We're transitioning into running, so turn off
+			// tracking and record how much time we spent in
+			// runnable.
+			gp.tracking = false
+			sched.timeToRun.record(gp.runnableTime)
+			gp.runnableTime = 0
+		}
+	}
 }
 
 // casgstatus(gp, oldstatus, Gcopystack), assuming oldstatus is Gwaiting or Grunnable.
@@ -1213,7 +1303,7 @@
 	case "aix", "darwin", "illumos", "ios", "solaris", "windows":
 		return true
 	case "openbsd":
-		return GOARCH == "amd64" || GOARCH == "arm64"
+		return GOARCH == "386" || GOARCH == "amd64" || GOARCH == "arm" || GOARCH == "arm64"
 	}
 	return false
 }
@@ -1226,7 +1316,7 @@
 		return true
 	case "openbsd":
 		switch GOARCH {
-		case "amd64", "arm64":
+		case "386", "amd64", "arm", "arm64":
 			return true
 		}
 	}
@@ -1234,7 +1324,10 @@
 }
 
 // mstart is the entry-point for new Ms.
-//
+// It is written in assembly, uses ABI0, is marked TOPFRAME, and calls mstart0.
+func mstart()
+
+// mstart0 is the Go entry-point for new Ms.
 // This must not split the stack because we may not even have stack
 // bounds set up yet.
 //
@@ -1243,7 +1336,7 @@
 //
 //go:nosplit
 //go:nowritebarrierrec
-func mstart() {
+func mstart0() {
 	_g_ := getg()
 
 	osStack := _g_.stack.lo == 0
@@ -1281,6 +1374,9 @@
 	mexit(osStack)
 }
 
+// The go:noinline is to guarantee the getcallerpc/getcallersp below are safe,
+// so that we can set up g0.sched to return to the call of mstart1 above.
+//go:noinline
 func mstart1() {
 	_g_ := getg()
 
@@ -1288,11 +1384,16 @@
 		throw("bad runtime·mstart")
 	}
 
-	// Record the caller for use as the top of stack in mcall and
-	// for terminating the thread.
+	// Set up m.g0.sched as a label returning to just
+	// after the mstart1 call in mstart0 above, for use by goexit0 and mcall.
 	// We're never coming back to mstart1 after we call schedule,
 	// so other calls can reuse the current frame.
-	save(getcallerpc(), getcallersp())
+	// And goexit0 does a gogo that needs to return from mstart1
+	// and let mstart0 exit the thread.
+	_g_.sched.g = guintptr(unsafe.Pointer(_g_))
+	_g_.sched.pc = getcallerpc()
+	_g_.sched.sp = getcallersp()
+
 	asminit()
 	minit()
 
@@ -1338,6 +1439,9 @@
 	g := getg()
 	for {
 		notesleep(&g.m.park)
+		// Note, because of signal handling by this parked m,
+		// a preemptive mDoFixup() may actually occur via
+		// mDoFixupAndOSYield(). (See golang.org/issue/44193)
 		noteclear(&g.m.park)
 		if !mDoFixup() {
 			return
@@ -1418,6 +1522,8 @@
 	}
 	unlock(&sched.lock)
 
+	atomic.Xadd64(&ncgocall, int64(m.ncgocall))
+
 	// Release the P.
 	handoffp(releasep())
 	// After this point we must not have write barriers.
@@ -1571,6 +1677,22 @@
 	for atomic.Load(&sched.sysmonStarting) != 0 {
 		osyield()
 	}
+
+	// We don't want this thread to handle signals for the
+	// duration of this critical section. The underlying issue
+	// being that this locked coordinating m is the one monitoring
+	// for fn() execution by all the other m's of the runtime,
+	// while no regular go code execution is permitted (the world
+	// is stopped). If this present m were to get distracted to
+	// run signal handling code, and find itself waiting for a
+	// second thread to execute go code before being able to
+	// return from that signal handling, a deadlock will result.
+	// (See golang.org/issue/44193.)
+	lockOSThread()
+	var sigmask sigset
+	sigsave(&sigmask)
+	sigblock(false)
+
 	stopTheWorldGC("doAllThreadsSyscall")
 	if atomic.Load(&newmHandoff.haveTemplateThread) != 0 {
 		// Ensure that there are no in-flight thread
@@ -1622,6 +1744,7 @@
 			// the possibility of racing with mp.
 			lock(&mp.mFixup.lock)
 			mp.mFixup.fn = fn
+			atomic.Store(&mp.mFixup.used, 1)
 			if mp.doesPark {
 				// For non-service threads this will
 				// cause the wakeup to be short lived
@@ -1638,9 +1761,7 @@
 				if mp.procid == tid {
 					continue
 				}
-				lock(&mp.mFixup.lock)
-				done = done && (mp.mFixup.fn == nil)
-				unlock(&mp.mFixup.lock)
+				done = atomic.Load(&mp.mFixup.used) == 0
 			}
 			if done {
 				break
@@ -1667,6 +1788,8 @@
 		unlock(&mFixupRace.lock)
 	}
 	startTheWorldGC()
+	msigrestore(sigmask)
+	unlockOSThread()
 }
 
 // runSafePointFn runs the safe point function, if any, for this P.
@@ -1848,6 +1971,10 @@
 	// Store the original signal mask for use by minit.
 	mp.sigmask = sigmask
 
+	// Install TLS on some platforms (previously setg
+	// would do this if necessary).
+	osSetupTLS(mp)
+
 	// Install g (= m->g0) and set the stack bounds
 	// to match the current stack. We don't actually know
 	// how big the stack is, like we don't know how big any
@@ -1898,9 +2025,9 @@
 	// the goroutine stack ends.
 	mp := allocm(nil, nil, -1)
 	gp := malg(4096)
-	gp.sched.pc = funcPC(goexit) + sys.PCQuantum
+	gp.sched.pc = abi.FuncPCABI0(goexit) + sys.PCQuantum
 	gp.sched.sp = gp.stack.hi
-	gp.sched.sp -= 4 * sys.RegSize // extra space in case of reads slightly beyond frame
+	gp.sched.sp -= 4 * sys.PtrSize // extra space in case of reads slightly beyond frame
 	gp.sched.lr = 0
 	gp.sched.g = guintptr(unsafe.Pointer(gp))
 	gp.syscallpc = gp.sched.pc
@@ -2012,7 +2139,7 @@
 	for {
 		old := atomic.Loaduintptr(&extram)
 		if old == locked {
-			osyield()
+			osyield_no_g()
 			continue
 		}
 		if old == 0 && !nilokay {
@@ -2023,13 +2150,13 @@
 				atomic.Xadd(&extraMWaiters, 1)
 				incr = true
 			}
-			usleep(1)
+			usleep_no_g(1)
 			continue
 		}
 		if atomic.Casuintptr(&extram, old, locked) {
 			return (*m)(unsafe.Pointer(old))
 		}
-		osyield()
+		osyield_no_g()
 		continue
 	}
 }
@@ -2157,9 +2284,21 @@
 // mDoFixup runs any outstanding fixup function for the running m.
 // Returns true if a fixup was outstanding and actually executed.
 //
+// Note: to avoid deadlocks, and the need for the fixup function
+// itself to be async safe, signals are blocked for the working m
+// while it holds the mFixup lock. (See golang.org/issue/44193)
+//
 //go:nosplit
 func mDoFixup() bool {
 	_g_ := getg()
+	if used := atomic.Load(&_g_.m.mFixup.used); used == 0 {
+		return false
+	}
+
+	// slow path - if fixup fn is used, block signals and lock.
+	var sigmask sigset
+	sigsave(&sigmask)
+	sigblock(false)
 	lock(&_g_.m.mFixup.lock)
 	fn := _g_.m.mFixup.fn
 	if fn != nil {
@@ -2176,7 +2315,6 @@
 			// is more obviously safe.
 			throw("GC must be disabled to protect validity of fn value")
 		}
-		*(*uintptr)(unsafe.Pointer(&_g_.m.mFixup.fn)) = 0
 		if _g_.racectx != 0 || !raceenabled {
 			fn(false)
 		} else {
@@ -2191,11 +2329,24 @@
 			_g_.racectx = 0
 			unlock(&mFixupRace.lock)
 		}
+		*(*uintptr)(unsafe.Pointer(&_g_.m.mFixup.fn)) = 0
+		atomic.Store(&_g_.m.mFixup.used, 0)
 	}
 	unlock(&_g_.m.mFixup.lock)
+	msigrestore(sigmask)
 	return fn != nil
 }
 
+// mDoFixupAndOSYield is called when an m is unable to send a signal
+// because the allThreadsSyscall mechanism is in progress. That is, an
+// mPark() has been interrupted with this signal handler so we need to
+// ensure the fixup is executed from this context.
+//go:nosplit
+func mDoFixupAndOSYield() {
+	mDoFixup()
+	osyield()
+}
+
 // templateThread 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 in a good state.
@@ -2613,85 +2764,40 @@
 		}
 	}
 
-	// Steal work from other P's.
+	// Spinning Ms: steal work from other Ps.
+	//
+	// Limit the number of spinning Ms to half the number of busy Ps.
+	// This is necessary to prevent excessive CPU consumption when
+	// GOMAXPROCS>>1 but the program parallelism is low.
 	procs := uint32(gomaxprocs)
-	ranTimer := false
-	// If number of spinning M's >= number of busy P's, block.
-	// This is necessary to prevent excessive CPU consumption
-	// when GOMAXPROCS>>1 but the program parallelism is low.
-	if !_g_.m.spinning && 2*atomic.Load(&sched.nmspinning) >= procs-atomic.Load(&sched.npidle) {
-		goto stop
-	}
-	if !_g_.m.spinning {
-		_g_.m.spinning = true
-		atomic.Xadd(&sched.nmspinning, 1)
-	}
-	const stealTries = 4
-	for i := 0; i < stealTries; i++ {
-		stealTimersOrRunNextG := i == stealTries-1
+	if _g_.m.spinning || 2*atomic.Load(&sched.nmspinning) < procs-atomic.Load(&sched.npidle) {
+		if !_g_.m.spinning {
+			_g_.m.spinning = true
+			atomic.Xadd(&sched.nmspinning, 1)
+		}
 
-		for enum := stealOrder.start(fastrand()); !enum.done(); enum.next() {
-			if sched.gcwaiting != 0 {
-				goto top
-			}
-			p2 := allp[enum.position()]
-			if _p_ == p2 {
-				continue
-			}
-
-			// Steal timers from p2. This call to checkTimers is the only place
-			// where we might hold a lock on a different P's timers. We do this
-			// once on the last pass before checking runnext because stealing
-			// from the other P's runnext should be the last resort, so if there
-			// are timers to steal do that first.
-			//
-			// We only check timers on one of the stealing iterations because
-			// the time stored in now doesn't change in this loop and checking
-			// the timers for each P more than once with the same value of now
-			// is probably a waste of time.
-			//
-			// timerpMask tells us whether the P may have timers at all. If it
-			// can't, no need to check at all.
-			if stealTimersOrRunNextG && timerpMask.read(enum.position()) {
-				tnow, w, ran := checkTimers(p2, now)
-				now = tnow
-				if w != 0 && (pollUntil == 0 || w < pollUntil) {
-					pollUntil = w
-				}
-				if ran {
-					// Running the timers may have
-					// made an arbitrary number of G's
-					// ready and added them to this P's
-					// local run queue. That invalidates
-					// the assumption of runqsteal
-					// that is always has room to add
-					// stolen G's. So check now if there
-					// is a local G to run.
-					if gp, inheritTime := runqget(_p_); gp != nil {
-						return gp, inheritTime
-					}
-					ranTimer = true
-				}
-			}
-
-			// Don't bother to attempt to steal if p2 is idle.
-			if !idlepMask.read(enum.position()) {
-				if gp := runqsteal(_p_, p2, stealTimersOrRunNextG); gp != nil {
-					return gp, false
-				}
-			}
+		gp, inheritTime, tnow, w, newWork := stealWork(now)
+		now = tnow
+		if gp != nil {
+			// Successfully stole.
+			return gp, inheritTime
+		}
+		if newWork {
+			// There may be new timer or GC work; restart to
+			// discover.
+			goto top
+		}
+		if w != 0 && (pollUntil == 0 || w < pollUntil) {
+			// Earlier timer to wait for.
+			pollUntil = w
 		}
 	}
-	if ranTimer {
-		// Running a timer may have made some goroutine ready.
-		goto top
-	}
 
-stop:
-
-	// We have nothing to do. If we're in the GC mark phase, can
-	// safely scan and blacken objects, and have work to do, run
-	// idle-time marking rather than give up the P.
+	// We have nothing to do.
+	//
+	// If we're in the GC mark phase, can safely scan and blacken objects,
+	// and have work to do, run idle-time marking rather than give up the
+	// P.
 	if gcBlackenEnabled != 0 && gcMarkWorkAvailable(_p_) {
 		node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
 		if node != nil {
@@ -2705,17 +2811,11 @@
 		}
 	}
 
-	delta := int64(-1)
-	if pollUntil != 0 {
-		// checkTimers ensures that polluntil > now.
-		delta = pollUntil - now
-	}
-
 	// wasm only:
 	// If a callback returned and no other goroutine is awake,
 	// then wake event handler goroutine which pauses execution
 	// until a callback was triggered.
-	gp, otherReady := beforeIdle(delta)
+	gp, otherReady := beforeIdle(now, pollUntil)
 	if gp != nil {
 		casgstatus(gp, _Gwaiting, _Grunnable)
 		if trace.enabled {
@@ -2754,18 +2854,25 @@
 	pidleput(_p_)
 	unlock(&sched.lock)
 
-	// Delicate dance: thread transitions from spinning to non-spinning state,
-	// potentially concurrently with submission of new goroutines. We must
-	// drop nmspinning first and then check all per-P queues again (with
-	// #StoreLoad memory barrier in between). If we do it the other way around,
-	// another thread can submit a goroutine after we've checked all run queues
-	// but before we drop nmspinning; as a result nobody will unpark a thread
-	// to run the goroutine.
+	// Delicate dance: thread transitions from spinning to non-spinning
+	// state, potentially concurrently with submission of new work. We must
+	// drop nmspinning first and then check all sources again (with
+	// #StoreLoad memory barrier in between). If we do it the other way
+	// around, another thread can submit work after we've checked all
+	// sources but before we drop nmspinning; as a result nobody will
+	// unpark a thread to run the work.
+	//
+	// This applies to the following sources of work:
+	//
+	// * Goroutines added to a per-P run queue.
+	// * New/modified-earlier timers on a per-P timer heap.
+	// * Idle-priority GC work (barring golang.org/issue/19112).
+	//
 	// If we discover new work below, we need to restore m.spinning as a signal
 	// for resetspinning to unpark a new worker thread (because there can be more
 	// than one starving goroutine). However, if after discovering new work
-	// we also observe no idle Ps, it is OK to just park the current thread:
-	// the system is fully loaded so no spinning threads are required.
+	// we also observe no idle Ps it is OK to skip unparking a new worker
+	// thread: the system is fully loaded so no spinning threads are required.
 	// Also see "Worker thread parking/unparking" comment at the top of the file.
 	wasSpinning := _g_.m.spinning
 	if _g_.m.spinning {
@@ -2773,97 +2880,48 @@
 		if int32(atomic.Xadd(&sched.nmspinning, -1)) < 0 {
 			throw("findrunnable: negative nmspinning")
 		}
-	}
 
-	// check all runqueues once again
-	for id, _p_ := range allpSnapshot {
-		if !idlepMaskSnapshot.read(uint32(id)) && !runqempty(_p_) {
-			lock(&sched.lock)
-			_p_ = pidleget()
-			unlock(&sched.lock)
-			if _p_ != nil {
-				acquirep(_p_)
-				if wasSpinning {
-					_g_.m.spinning = true
-					atomic.Xadd(&sched.nmspinning, 1)
-				}
-				goto top
-			}
-			break
-		}
-	}
+		// Note the for correctness, only the last M transitioning from
+		// spinning to non-spinning must perform these rechecks to
+		// ensure no missed work. We are performing it on every M that
+		// transitions as a conservative change to monitor effects on
+		// latency. See golang.org/issue/43997.
 
-	// Similar to above, check for timer creation or expiry concurrently with
-	// transitioning from spinning to non-spinning. Note that we cannot use
-	// checkTimers here because it calls adjusttimers which may need to allocate
-	// memory, and that isn't allowed when we don't have an active P.
-	for id, _p_ := range allpSnapshot {
-		if timerpMaskSnapshot.read(uint32(id)) {
-			w := nobarrierWakeTime(_p_)
-			if w != 0 && (pollUntil == 0 || w < pollUntil) {
-				pollUntil = w
-			}
-		}
-	}
-	if pollUntil != 0 {
-		if now == 0 {
-			now = nanotime()
-		}
-		delta = pollUntil - now
-		if delta < 0 {
-			delta = 0
-		}
-	}
-
-	// Check for idle-priority GC work again.
-	//
-	// N.B. Since we have no P, gcBlackenEnabled may change at any time; we
-	// must check again after acquiring a P.
-	if atomic.Load(&gcBlackenEnabled) != 0 && gcMarkWorkAvailable(nil) {
-		// Work is available; we can start an idle GC worker only if
-		// there is an available P and available worker G.
-		//
-		// We can attempt to acquire these in either order. Workers are
-		// almost always available (see comment in findRunnableGCWorker
-		// for the one case there may be none). Since we're slightly
-		// less likely to find a P, check for that first.
-		lock(&sched.lock)
-		var node *gcBgMarkWorkerNode
-		_p_ = pidleget()
-		if _p_ != nil {
-			// Now that we own a P, gcBlackenEnabled can't change
-			// (as it requires STW).
-			if gcBlackenEnabled != 0 {
-				node = (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
-				if node == nil {
-					pidleput(_p_)
-					_p_ = nil
-				}
-			} else {
-				pidleput(_p_)
-				_p_ = nil
-			}
-		}
-		unlock(&sched.lock)
+		// Check all runqueues once again.
+		_p_ = checkRunqsNoP(allpSnapshot, idlepMaskSnapshot)
 		if _p_ != nil {
 			acquirep(_p_)
-			if wasSpinning {
-				_g_.m.spinning = true
-				atomic.Xadd(&sched.nmspinning, 1)
-			}
+			_g_.m.spinning = true
+			atomic.Xadd(&sched.nmspinning, 1)
+			goto top
+		}
+
+		// Check for idle-priority GC work again.
+		_p_, gp = checkIdleGCNoP()
+		if _p_ != nil {
+			acquirep(_p_)
+			_g_.m.spinning = true
+			atomic.Xadd(&sched.nmspinning, 1)
 
 			// Run the idle worker.
 			_p_.gcMarkWorkerMode = gcMarkWorkerIdleMode
-			gp := node.gp.ptr()
 			casgstatus(gp, _Gwaiting, _Grunnable)
 			if trace.enabled {
 				traceGoUnpark(gp, 0)
 			}
 			return gp, false
 		}
+
+		// Finally, check for timer creation or expiry concurrently with
+		// transitioning from spinning to non-spinning.
+		//
+		// Note that we cannot use checkTimers here because it calls
+		// adjusttimers which may need to allocate memory, and that isn't
+		// allowed when we don't have an active P.
+		pollUntil = checkTimersNoP(allpSnapshot, timerpMaskSnapshot, pollUntil)
 	}
 
-	// poll network
+	// Poll network until next timer.
 	if netpollinited() && (atomic.Load(&netpollWaiters) > 0 || pollUntil != 0) && atomic.Xchg64(&sched.lastpoll, 0) != 0 {
 		atomic.Store64(&sched.pollUntil, uint64(pollUntil))
 		if _g_.m.p != 0 {
@@ -2872,11 +2930,21 @@
 		if _g_.m.spinning {
 			throw("findrunnable: netpoll with spinning")
 		}
+		delay := int64(-1)
+		if pollUntil != 0 {
+			if now == 0 {
+				now = nanotime()
+			}
+			delay = pollUntil - now
+			if delay < 0 {
+				delay = 0
+			}
+		}
 		if faketime != 0 {
 			// When using fake time, just poll.
-			delta = 0
+			delay = 0
 		}
-		list := netpoll(delta) // block until new work is available
+		list := netpoll(delay) // block until new work is available
 		atomic.Store64(&sched.pollUntil, 0)
 		atomic.Store64(&sched.lastpoll, uint64(nanotime()))
 		if faketime != 0 && list.empty() {
@@ -2938,6 +3006,178 @@
 	return false
 }
 
+// stealWork attempts to steal a runnable goroutine or timer from any P.
+//
+// If newWork is true, new work may have been readied.
+//
+// If now is not 0 it is the current time. stealWork returns the passed time or
+// the current time if now was passed as 0.
+func stealWork(now int64) (gp *g, inheritTime bool, rnow, pollUntil int64, newWork bool) {
+	pp := getg().m.p.ptr()
+
+	ranTimer := false
+
+	const stealTries = 4
+	for i := 0; i < stealTries; i++ {
+		stealTimersOrRunNextG := i == stealTries-1
+
+		for enum := stealOrder.start(fastrand()); !enum.done(); enum.next() {
+			if sched.gcwaiting != 0 {
+				// GC work may be available.
+				return nil, false, now, pollUntil, true
+			}
+			p2 := allp[enum.position()]
+			if pp == p2 {
+				continue
+			}
+
+			// Steal timers from p2. This call to checkTimers is the only place
+			// where we might hold a lock on a different P's timers. We do this
+			// once on the last pass before checking runnext because stealing
+			// from the other P's runnext should be the last resort, so if there
+			// are timers to steal do that first.
+			//
+			// We only check timers on one of the stealing iterations because
+			// the time stored in now doesn't change in this loop and checking
+			// the timers for each P more than once with the same value of now
+			// is probably a waste of time.
+			//
+			// timerpMask tells us whether the P may have timers at all. If it
+			// can't, no need to check at all.
+			if stealTimersOrRunNextG && timerpMask.read(enum.position()) {
+				tnow, w, ran := checkTimers(p2, now)
+				now = tnow
+				if w != 0 && (pollUntil == 0 || w < pollUntil) {
+					pollUntil = w
+				}
+				if ran {
+					// Running the timers may have
+					// made an arbitrary number of G's
+					// ready and added them to this P's
+					// local run queue. That invalidates
+					// the assumption of runqsteal
+					// that it always has room to add
+					// stolen G's. So check now if there
+					// is a local G to run.
+					if gp, inheritTime := runqget(pp); gp != nil {
+						return gp, inheritTime, now, pollUntil, ranTimer
+					}
+					ranTimer = true
+				}
+			}
+
+			// Don't bother to attempt to steal if p2 is idle.
+			if !idlepMask.read(enum.position()) {
+				if gp := runqsteal(pp, p2, stealTimersOrRunNextG); gp != nil {
+					return gp, false, now, pollUntil, ranTimer
+				}
+			}
+		}
+	}
+
+	// No goroutines found to steal. Regardless, running a timer may have
+	// made some goroutine ready that we missed. Indicate the next timer to
+	// wait for.
+	return nil, false, now, pollUntil, ranTimer
+}
+
+// Check all Ps for a runnable G to steal.
+//
+// On entry we have no P. If a G is available to steal and a P is available,
+// the P is returned which the caller should acquire and attempt to steal the
+// work to.
+func checkRunqsNoP(allpSnapshot []*p, idlepMaskSnapshot pMask) *p {
+	for id, p2 := range allpSnapshot {
+		if !idlepMaskSnapshot.read(uint32(id)) && !runqempty(p2) {
+			lock(&sched.lock)
+			pp := pidleget()
+			unlock(&sched.lock)
+			if pp != nil {
+				return pp
+			}
+
+			// Can't get a P, don't bother checking remaining Ps.
+			break
+		}
+	}
+
+	return nil
+}
+
+// Check all Ps for a timer expiring sooner than pollUntil.
+//
+// Returns updated pollUntil value.
+func checkTimersNoP(allpSnapshot []*p, timerpMaskSnapshot pMask, pollUntil int64) int64 {
+	for id, p2 := range allpSnapshot {
+		if timerpMaskSnapshot.read(uint32(id)) {
+			w := nobarrierWakeTime(p2)
+			if w != 0 && (pollUntil == 0 || w < pollUntil) {
+				pollUntil = w
+			}
+		}
+	}
+
+	return pollUntil
+}
+
+// Check for idle-priority GC, without a P on entry.
+//
+// If some GC work, a P, and a worker G are all available, the P and G will be
+// returned. The returned P has not been wired yet.
+func checkIdleGCNoP() (*p, *g) {
+	// N.B. Since we have no P, gcBlackenEnabled may change at any time; we
+	// must check again after acquiring a P.
+	if atomic.Load(&gcBlackenEnabled) == 0 {
+		return nil, nil
+	}
+	if !gcMarkWorkAvailable(nil) {
+		return nil, nil
+	}
+
+	// Work is available; we can start an idle GC worker only if there is
+	// an available P and available worker G.
+	//
+	// We can attempt to acquire these in either order, though both have
+	// synchronization concerns (see below). Workers are almost always
+	// available (see comment in findRunnableGCWorker for the one case
+	// there may be none). Since we're slightly less likely to find a P,
+	// check for that first.
+	//
+	// Synchronization: note that we must hold sched.lock until we are
+	// committed to keeping it. Otherwise we cannot put the unnecessary P
+	// back in sched.pidle without performing the full set of idle
+	// transition checks.
+	//
+	// If we were to check gcBgMarkWorkerPool first, we must somehow handle
+	// the assumption in gcControllerState.findRunnableGCWorker that an
+	// empty gcBgMarkWorkerPool is only possible if gcMarkDone is running.
+	lock(&sched.lock)
+	pp := pidleget()
+	if pp == nil {
+		unlock(&sched.lock)
+		return nil, nil
+	}
+
+	// Now that we own a P, gcBlackenEnabled can't change (as it requires
+	// STW).
+	if gcBlackenEnabled == 0 {
+		pidleput(pp)
+		unlock(&sched.lock)
+		return nil, nil
+	}
+
+	node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
+	if node == nil {
+		pidleput(pp)
+		unlock(&sched.lock)
+		return nil, nil
+	}
+
+	unlock(&sched.lock)
+
+	return pp, node.gp.ptr()
+}
+
 // wakeNetPoller wakes up the thread sleeping in the network poller if it isn't
 // going to wake up before the when argument; or it wakes an idle P to service
 // timers and the network poller if there isn't one already.
@@ -3104,7 +3344,9 @@
 	}
 	if gp == nil && gcBlackenEnabled != 0 {
 		gp = gcController.findRunnableGCWorker(_g_.m.p.ptr())
-		tryWakeP = tryWakeP || gp != nil
+		if gp != nil {
+			tryWakeP = true
+		}
 	}
 	if gp == nil {
 		// Check the global runnable queue once in a while to ensure fairness.
@@ -3180,7 +3422,7 @@
 
 // checkTimers runs any timers for the P that are ready.
 // If now is not 0 it is the current time.
-// It returns the current time or 0 if it is not known,
+// It returns the passed time or the current time if now was passed as 0.
 // and the time when the next timer should run or 0 if there is no next timer,
 // and reports whether it ran any timers.
 // If the time when the next timer should run is not 0,
@@ -3330,6 +3572,21 @@
 		throw("bad g status")
 	}
 	gp.waitreason = waitReasonPreempted
+
+	if gp.asyncSafePoint {
+		// Double-check that async preemption does not
+		// happen in SPWRITE assembly functions.
+		// isAsyncSafePoint must exclude this case.
+		f := findfunc(gp.sched.pc)
+		if !f.valid() {
+			throw("preempt at unknown pc")
+		}
+		if f.flag&funcFlag_SPWRITE != 0 {
+			println("runtime: unexpected SPWRITE function", funcname(f), "in async preempt")
+			throw("preempt SPWRITE")
+		}
+	}
+
 	// Transition from _Grunning to _Gscan|_Gpreempted. We can't
 	// be in _Grunning when we dropg because then we'd be running
 	// without an M, but the moment we're in _Gpreempted,
@@ -3445,11 +3702,19 @@
 func save(pc, sp uintptr) {
 	_g_ := getg()
 
+	if _g_ == _g_.m.g0 || _g_ == _g_.m.gsignal {
+		// m.g0.sched is special and must describe the context
+		// for exiting the thread. mstart1 writes to it directly.
+		// m.gsignal.sched should not be used at all.
+		// This check makes sure save calls do not accidentally
+		// run in contexts where they'd write to system g's.
+		throw("save on system g not allowed")
+	}
+
 	_g_.sched.pc = pc
 	_g_.sched.sp = sp
 	_g_.sched.lr = 0
 	_g_.sched.ret = 0
-	_g_.sched.g = guintptr(unsafe.Pointer(_g_))
 	// We need to ensure ctxt is zero, but can't have a write
 	// barrier here. However, it should always already be zero.
 	// Assert that.
@@ -3463,7 +3728,7 @@
 // This is called only from the go syscall library and cgocall,
 // not from the low-level system calls used by the runtime.
 //
-// Entersyscall cannot split the stack: the gosave must
+// Entersyscall cannot split the stack: the save must
 // make g->sched refer to the caller's stack segment, because
 // entersyscall is going to return immediately after.
 //
@@ -3809,19 +4074,27 @@
 // exitsyscall slow path on g0.
 // Failed to acquire P, enqueue gp as runnable.
 //
+// Called via mcall, so gp is the calling g from this M.
+//
 //go:nowritebarrierrec
 func exitsyscall0(gp *g) {
-	_g_ := getg()
-
 	casgstatus(gp, _Gsyscall, _Grunnable)
 	dropg()
 	lock(&sched.lock)
 	var _p_ *p
-	if schedEnabled(_g_) {
+	if schedEnabled(gp) {
 		_p_ = pidleget()
 	}
+	var locked bool
 	if _p_ == nil {
 		globrunqput(gp)
+
+		// Below, we stoplockedm if gp is locked. globrunqput releases
+		// ownership of gp, so we must check if gp is locked prior to
+		// committing the release by unlocking sched.lock, otherwise we
+		// could race with another M transitioning gp from unlocked to
+		// locked.
+		locked = gp.lockedm != 0
 	} else if atomic.Load(&sched.sysmonwait) != 0 {
 		atomic.Store(&sched.sysmonwait, 0)
 		notewakeup(&sched.sysmonnote)
@@ -3831,8 +4104,11 @@
 		acquirep(_p_)
 		execute(gp, false) // Never returns.
 	}
-	if _g_.m.lockedg != 0 {
+	if locked {
 		// Wait until another thread schedules gp and so m again.
+		//
+		// N.B. lockedm must be this M, as this g was running on this M
+		// before entersyscall.
 		stoplockedm()
 		execute(gp, false) // Never returns.
 	}
@@ -3997,6 +4273,14 @@
 //
 //go:systemstack
 func newproc1(fn *funcval, argp unsafe.Pointer, narg int32, callergp *g, callerpc uintptr) *g {
+	if goexperiment.RegabiDefer && narg != 0 {
+		// TODO: When we commit to GOEXPERIMENT=regabidefer,
+		// rewrite the comments for newproc and newproc1.
+		// newproc will no longer have a funny stack layout or
+		// need to be nosplit.
+		throw("go with non-empty frame")
+	}
+
 	_g_ := getg()
 
 	if fn == nil {
@@ -4009,9 +4293,9 @@
 
 	// We could allocate a larger initial stack if necessary.
 	// Not worth it: this is almost always an error.
-	// 4*sizeof(uintreg): extra space added below
-	// sizeof(uintreg): caller's LR (arm) or return address (x86, in gostartcall).
-	if siz >= _StackMin-4*sys.RegSize-sys.RegSize {
+	// 4*PtrSize: extra space added below
+	// PtrSize: caller's LR (arm) or return address (x86, in gostartcall).
+	if siz >= _StackMin-4*sys.PtrSize-sys.PtrSize {
 		throw("newproc: function arguments too large for new goroutine")
 	}
 
@@ -4030,8 +4314,8 @@
 		throw("newproc1: new g is not Gdead")
 	}
 
-	totalSize := 4*sys.RegSize + uintptr(siz) + sys.MinFrameSize // extra space in case of reads slightly beyond frame
-	totalSize += -totalSize & (sys.SpAlign - 1)                  // align to spAlign
+	totalSize := 4*sys.PtrSize + uintptr(siz) + sys.MinFrameSize // extra space in case of reads slightly beyond frame
+	totalSize += -totalSize & (sys.StackAlign - 1)               // align to StackAlign
 	sp := newg.stack.hi - totalSize
 	spArg := sp
 	if usesLR {
@@ -4062,7 +4346,7 @@
 	memclrNoHeapPointers(unsafe.Pointer(&newg.sched), unsafe.Sizeof(newg.sched))
 	newg.sched.sp = sp
 	newg.stktopsp = sp
-	newg.sched.pc = funcPC(goexit) + sys.PCQuantum // +PCQuantum so that previous instruction is in same function
+	newg.sched.pc = abi.FuncPCABI0(goexit) + sys.PCQuantum // +PCQuantum so that previous instruction is in same function
 	newg.sched.g = guintptr(unsafe.Pointer(newg))
 	gostartcallfn(&newg.sched, fn)
 	newg.gopc = callerpc
@@ -4074,6 +4358,11 @@
 	if isSystemGoroutine(newg, false) {
 		atomic.Xadd(&sched.ngsys, +1)
 	}
+	// Track initial transition?
+	newg.trackingSeq = uint8(fastrand())
+	if newg.trackingSeq%gTrackingPeriod == 0 {
+		newg.tracking = true
+	}
 	casgstatus(newg, _Gdead, _Grunnable)
 
 	if _p_.goidcache == _p_.goidcacheend {
@@ -4151,17 +4440,25 @@
 	_p_.gFree.push(gp)
 	_p_.gFree.n++
 	if _p_.gFree.n >= 64 {
-		lock(&sched.gFree.lock)
+		var (
+			inc      int32
+			stackQ   gQueue
+			noStackQ gQueue
+		)
 		for _p_.gFree.n >= 32 {
-			_p_.gFree.n--
 			gp = _p_.gFree.pop()
+			_p_.gFree.n--
 			if gp.stack.lo == 0 {
-				sched.gFree.noStack.push(gp)
+				noStackQ.push(gp)
 			} else {
-				sched.gFree.stack.push(gp)
+				stackQ.push(gp)
 			}
-			sched.gFree.n++
+			inc++
 		}
+		lock(&sched.gFree.lock)
+		sched.gFree.noStack.pushAll(noStackQ)
+		sched.gFree.stack.pushAll(stackQ)
+		sched.gFree.n += inc
 		unlock(&sched.gFree.lock)
 	}
 }
@@ -4213,17 +4510,25 @@
 
 // Purge all cached G's from gfree list to the global list.
 func gfpurge(_p_ *p) {
-	lock(&sched.gFree.lock)
+	var (
+		inc      int32
+		stackQ   gQueue
+		noStackQ gQueue
+	)
 	for !_p_.gFree.empty() {
 		gp := _p_.gFree.pop()
 		_p_.gFree.n--
 		if gp.stack.lo == 0 {
-			sched.gFree.noStack.push(gp)
+			noStackQ.push(gp)
 		} else {
-			sched.gFree.stack.push(gp)
+			stackQ.push(gp)
 		}
-		sched.gFree.n++
+		inc++
 	}
+	lock(&sched.gFree.lock)
+	sched.gFree.noStack.pushAll(noStackQ)
+	sched.gFree.stack.pushAll(stackQ)
+	sched.gFree.n += inc
 	unlock(&sched.gFree.lock)
 }
 
@@ -4381,7 +4686,7 @@
 		return
 	}
 
-	// On mips{,le}, 64bit atomics are emulated with spinlocks, in
+	// On mips{,le}/arm, 64bit atomics are emulated with spinlocks, in
 	// runtime/internal/atomic. If SIGPROF arrives while the program is inside
 	// the critical section, it creates a deadlock (when writing the sample).
 	// As a workaround, create a counter of SIGPROFs while in critical section
@@ -4394,6 +4699,13 @@
 				return
 			}
 		}
+		if GOARCH == "arm" && goarm < 7 && GOOS == "linux" && pc&0xffff0000 == 0xffff0000 {
+			// runtime/internal/atomic functions call into kernel
+			// helpers on arm < 7. See
+			// runtime/internal/atomic/sys_linux_arm.s.
+			cpuprof.lostAtomic++
+			return
+		}
 	}
 
 	// Profiling runs concurrently with GC, so it must not allocate.
@@ -4404,75 +4716,6 @@
 	// See golang.org/issue/17165.
 	getg().m.mallocing++
 
-	// Define that a "user g" is a user-created goroutine, and a "system g"
-	// is one that is m->g0 or m->gsignal.
-	//
-	// We might be interrupted for profiling halfway through a
-	// goroutine switch. The switch involves updating three (or four) values:
-	// g, PC, SP, and (on arm) LR. The PC must be the last to be updated,
-	// because once it gets updated the new g is running.
-	//
-	// When switching from a user g to a system g, LR is not considered live,
-	// so the update only affects g, SP, and PC. Since PC must be last, there
-	// the possible partial transitions in ordinary execution are (1) g alone is updated,
-	// (2) both g and SP are updated, and (3) SP alone is updated.
-	// If SP or g alone is updated, we can detect the partial transition by checking
-	// whether the SP is within g's stack bounds. (We could also require that SP
-	// be changed only after g, but the stack bounds check is needed by other
-	// cases, so there is no need to impose an additional requirement.)
-	//
-	// There is one exceptional transition to a system g, not in ordinary execution.
-	// When a signal arrives, the operating system starts the signal handler running
-	// with an updated PC and SP. The g is updated last, at the beginning of the
-	// handler. There are two reasons this is okay. First, until g is updated the
-	// g and SP do not match, so the stack bounds check detects the partial transition.
-	// Second, signal handlers currently run with signals disabled, so a profiling
-	// signal cannot arrive during the handler.
-	//
-	// When switching from a system g to a user g, there are three possibilities.
-	//
-	// First, it may be that the g switch has no PC update, because the SP
-	// either corresponds to a user g throughout (as in asmcgocall)
-	// or because it has been arranged to look like a user g frame
-	// (as in cgocallback). In this case, since the entire
-	// transition is a g+SP update, a partial transition updating just one of
-	// those will be detected by the stack bounds check.
-	//
-	// Second, when returning from a signal handler, the PC and SP updates
-	// are performed by the operating system in an atomic update, so the g
-	// update must be done before them. The stack bounds check detects
-	// the partial transition here, and (again) signal handlers run with signals
-	// disabled, so a profiling signal cannot arrive then anyway.
-	//
-	// Third, the common case: it may be that the switch updates g, SP, and PC
-	// separately. If the PC is within any of the functions that does this,
-	// we don't ask for a traceback. C.F. the function setsSP for more about this.
-	//
-	// There is another apparently viable approach, recorded here in case
-	// the "PC within setsSP function" check turns out not to be usable.
-	// It would be possible to delay the update of either g or SP until immediately
-	// before the PC update instruction. Then, because of the stack bounds check,
-	// the only problematic interrupt point is just before that PC update instruction,
-	// and the sigprof handler can detect that instruction and simulate stepping past
-	// it in order to reach a consistent state. On ARM, the update of g must be made
-	// in two places (in R10 and also in a TLS slot), so the delayed update would
-	// need to be the SP update. The sigprof handler must read the instruction at
-	// the current PC and if it was the known instruction (for example, JMP BX or
-	// MOV R2, PC), use that other register in place of the PC value.
-	// The biggest drawback to this solution is that it requires that we can tell
-	// whether it's safe to read from the memory pointed at by PC.
-	// In a correct program, we can test PC == nil and otherwise read,
-	// but if a profiling signal happens at the instant that a program executes
-	// a bad jump (before the program manages to handle the resulting fault)
-	// the profiling handler could fault trying to read nonexistent memory.
-	//
-	// To recap, there are no constraints on the assembly being used for the
-	// transition. We simply require that g and SP match and that the PC is not
-	// in gogo.
-	traceback := true
-	if gp == nil || sp < gp.stack.lo || gp.stack.hi < sp || setsSP(pc) || (mp != nil && mp.vdsoSP != 0) {
-		traceback = false
-	}
 	var stk [maxCPUProfStack]uintptr
 	n := 0
 	if mp.ncgo > 0 && mp.curg != nil && mp.curg.syscallpc != 0 && mp.curg.syscallsp != 0 {
@@ -4495,7 +4738,7 @@
 		if n > 0 {
 			n += cgoOff
 		}
-	} else if traceback {
+	} else {
 		n = gentraceback(pc, sp, lr, gp, 0, &stk[0], len(stk), nil, nil, _TraceTrap|_TraceJumpStack)
 	}
 
@@ -4574,30 +4817,6 @@
 	}
 }
 
-// Reports whether a function will set the SP
-// to an absolute value. Important that
-// we don't traceback when these are at the bottom
-// of the stack since we can't be sure that we will
-// find the caller.
-//
-// If the function is not on the bottom of the stack
-// we assume that it will have set it up so that traceback will be consistent,
-// either by being a traceback terminating function
-// or putting one on the stack at the right offset.
-func setsSP(pc uintptr) bool {
-	f := findfunc(pc)
-	if !f.valid() {
-		// couldn't find the function for this PC,
-		// so assume the worst and stop traceback
-		return true
-	}
-	switch f.funcID {
-	case funcID_gogo, funcID_systemstack, funcID_mcall, funcID_morestack:
-		return true
-	}
-	return false
-}
-
 // setcpuprofilerate sets the CPU profiling rate to hz times per second.
 // If hz <= 0, setcpuprofilerate turns off CPU profiling.
 func setcpuprofilerate(hz int32) {
@@ -4707,7 +4926,6 @@
 		moveTimers(plocal, pp.timers)
 		pp.timers = nil
 		pp.numTimers = 0
-		pp.adjustTimers = 0
 		pp.deletedTimers = 0
 		atomic.Store64(&pp.timer0When, 0)
 		unlock(&pp.timersLock)
@@ -5027,11 +5245,9 @@
 	}
 
 	grunning := 0
-	lock(&allglock)
-	for i := 0; i < len(allgs); i++ {
-		gp := allgs[i]
+	forEachG(func(gp *g) {
 		if isSystemGoroutine(gp, false) {
-			continue
+			return
 		}
 		s := readgstatus(gp)
 		switch s &^ _Gscan {
@@ -5044,8 +5260,7 @@
 			print("runtime: checkdead: find g ", gp.goid, " in status ", s, "\n")
 			throw("checkdead: runnable g")
 		}
-	}
-	unlock(&allglock)
+	})
 	if grunning == 0 { // possible if main goroutine calls runtime·Goexit()
 		unlock(&sched.lock) // unlock so that GODEBUG=scheddetail=1 doesn't hang
 		throw("no goroutines (main called runtime.Goexit) - deadlock!")
@@ -5349,7 +5564,7 @@
 
 // Tell the goroutine running on processor P to stop.
 // This function is purely best-effort. It can incorrectly fail to inform the
-// goroutine. It can send inform the wrong goroutine. Even if it informs the
+// goroutine. It can inform the wrong goroutine. Even if it informs the
 // correct goroutine, that goroutine might ignore the request if it is
 // simultaneously executing newstack.
 // No lock needs to be held.
@@ -5369,7 +5584,7 @@
 
 	gp.preempt = true
 
-	// Every call in a go routine checks for stack overflow by
+	// Every call in a goroutine checks for stack overflow by
 	// comparing the current stack pointer to gp->stackguard0.
 	// Setting gp->stackguard0 to StackPreempt folds
 	// preemption into the normal stack overflow check.
@@ -5448,9 +5663,7 @@
 		print("  M", mp.id, ": p=", id1, " curg=", id2, " mallocing=", mp.mallocing, " throwing=", mp.throwing, " preemptoff=", mp.preemptoff, ""+" locks=", mp.locks, " dying=", mp.dying, " spinning=", mp.spinning, " blocked=", mp.blocked, " lockedg=", id3, "\n")
 	}
 
-	lock(&allglock)
-	for gi := 0; gi < len(allgs); gi++ {
-		gp := allgs[gi]
+	forEachG(func(gp *g) {
 		mp := gp.m
 		lockedm := gp.lockedm.ptr()
 		id1 := int64(-1)
@@ -5462,8 +5675,7 @@
 			id2 = lockedm.id
 		}
 		print("  G", gp.goid, ": status=", readgstatus(gp), "(", gp.waitreason.String(), ") m=", id1, " lockedm=", id2, "\n")
-	}
-	unlock(&allglock)
+	})
 	unlock(&sched.lock)
 }
 
@@ -5558,6 +5770,8 @@
 // Put a batch of runnable goroutines on the global runnable queue.
 // This clears *batch.
 // sched.lock must be held.
+// May run during STW, so write barriers are not allowed.
+//go:nowritebarrierrec
 func globrunqputbatch(batch *gQueue, n int32) {
 	assertLockHeld(&sched.lock)
 
@@ -5873,6 +6087,45 @@
 	}
 }
 
+// runqdrain drains the local runnable queue of _p_ and returns all goroutines in it.
+// Executed only by the owner P.
+func runqdrain(_p_ *p) (drainQ gQueue, n uint32) {
+	oldNext := _p_.runnext
+	if oldNext != 0 && _p_.runnext.cas(oldNext, 0) {
+		drainQ.pushBack(oldNext.ptr())
+		n++
+	}
+
+retry:
+	h := atomic.LoadAcq(&_p_.runqhead) // load-acquire, synchronize with other consumers
+	t := _p_.runqtail
+	qn := t - h
+	if qn == 0 {
+		return
+	}
+	if qn > uint32(len(_p_.runq)) { // read inconsistent h and t
+		goto retry
+	}
+
+	if !atomic.CasRel(&_p_.runqhead, h, h+qn) { // cas-release, commits consume
+		goto retry
+	}
+
+	// We've inverted the order in which it gets G's from the local P's runnable queue
+	// and then advances the head pointer because we don't want to mess up the statuses of G's
+	// while runqdrain() and runqsteal() are running in parallel.
+	// Thus we should advance the head pointer before draining the local P into a gQueue,
+	// so that we can update any gp.schedlink only after we take the full ownership of G,
+	// meanwhile, other P's can't access to all G's in local P's runnable queue and steal them.
+	// See https://groups.google.com/g/golang-dev/c/0pTKxEKhHSc/m/6Q85QjdVBQAJ for more details.
+	for i := uint32(0); i < qn; i++ {
+		gp := _p_.runq[(h+i)%uint32(len(_p_.runq))].ptr()
+		drainQ.pushBack(gp)
+		n++
+	}
+	return
+}
+
 // Grabs a batch of goroutines from _p_'s runnable queue into batch.
 // Batch is a ring buffer starting at batchHead.
 // Returns number of grabbed goroutines.
@@ -6066,26 +6319,6 @@
 	return
 }
 
-func haveexperiment(name string) bool {
-	x := sys.Goexperiment
-	for x != "" {
-		xname := ""
-		i := bytealg.IndexByteString(x, ',')
-		if i < 0 {
-			xname, x = x, ""
-		} else {
-			xname, x = x[:i], x[i+1:]
-		}
-		if xname == name {
-			return true
-		}
-		if len(xname) > 2 && xname[:2] == "no" && xname[2:] == name {
-			return false
-		}
-	}
-	return false
-}
-
 //go:nosplit
 func procPin() int {
 	_g_ := getg()
@@ -6222,7 +6455,7 @@
 
 type tracestat struct {
 	active bool   // init tracing activation status
-	id     int64  // init go routine id
+	id     int64  // init goroutine id
 	allocs uint64 // heap allocations
 	bytes  uint64 // heap allocated bytes
 }
@@ -6254,7 +6487,7 @@
 
 		if inittrace.active {
 			start = nanotime()
-			// Load stats non-atomically since tracinit is updated only by this init go routine.
+			// Load stats non-atomically since tracinit is updated only by this init goroutine.
 			before = inittrace
 		}
 
@@ -6267,7 +6500,7 @@
 
 		if inittrace.active {
 			end := nanotime()
-			// Load stats non-atomically since tracinit is updated only by this init go routine.
+			// Load stats non-atomically since tracinit is updated only by this init goroutine.
 			after := inittrace
 
 			pkg := funcpkgpath(findfunc(funcPC(firstFunc)))
diff --git a/src/runtime/proc_test.go b/src/runtime/proc_test.go
index 767bde1..53cafe8 100644
--- a/src/runtime/proc_test.go
+++ b/src/runtime/proc_test.go
@@ -692,6 +692,55 @@
 	}
 }
 
+// warmupScheduler ensures the scheduler has at least targetThreadCount threads
+// in its thread pool.
+func warmupScheduler(targetThreadCount int) {
+	var wg sync.WaitGroup
+	var count int32
+	for i := 0; i < targetThreadCount; i++ {
+		wg.Add(1)
+		go func() {
+			atomic.AddInt32(&count, 1)
+			for atomic.LoadInt32(&count) < int32(targetThreadCount) {
+				// spin until all threads started
+			}
+
+			// spin a bit more to ensure they are all running on separate CPUs.
+			doWork(time.Millisecond)
+			wg.Done()
+		}()
+	}
+	wg.Wait()
+}
+
+func doWork(dur time.Duration) {
+	start := time.Now()
+	for time.Since(start) < dur {
+	}
+}
+
+// BenchmarkCreateGoroutinesSingle creates many goroutines, all from a single
+// producer (the main benchmark goroutine).
+//
+// Compared to BenchmarkCreateGoroutines, this causes different behavior in the
+// scheduler because Ms are much more likely to need to steal work from the
+// main P rather than having work in the local run queue.
+func BenchmarkCreateGoroutinesSingle(b *testing.B) {
+	// Since we are interested in stealing behavior, warm the scheduler to
+	// get all the Ps running first.
+	warmupScheduler(runtime.GOMAXPROCS(0))
+	b.ResetTimer()
+
+	var wg sync.WaitGroup
+	wg.Add(b.N)
+	for i := 0; i < b.N; i++ {
+		go func() {
+			wg.Done()
+		}()
+	}
+	wg.Wait()
+}
+
 func BenchmarkClosureCall(b *testing.B) {
 	sum := 0
 	off1 := 1
diff --git a/src/runtime/race.go b/src/runtime/race.go
index 79fd217..ce6b5b5 100644
--- a/src/runtime/race.go
+++ b/src/runtime/race.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build race
 // +build race
 
 package runtime
@@ -342,7 +343,7 @@
 func racewriterangepc1(addr, size, pc uintptr)
 func racecallbackthunk(uintptr)
 
-// racecall allows calling an arbitrary function f from C race runtime
+// racecall allows calling an arbitrary function fn from C race runtime
 // with up to 4 uintptr arguments.
 func racecall(fn *byte, arg0, arg1, arg2, arg3 uintptr)
 
diff --git a/src/runtime/race/README b/src/runtime/race/README
index 178ab94..3b188a0 100644
--- a/src/runtime/race/README
+++ b/src/runtime/race/README
@@ -1,6 +1,6 @@
 runtime/race package contains the data race detector runtime library.
 It is based on ThreadSanitizer race detector, that is currently a part of
-the LLVM project (https://github.com/llvm/llvm-project/tree/master/compiler-rt).
+the LLVM project (https://github.com/llvm/llvm-project/tree/main/compiler-rt).
 
 To update the .syso files use golang.org/x/build/cmd/racebuild.
 
@@ -12,3 +12,4 @@
 race_windows_amd64.syso built with LLVM 89f7ccea6f6488c443655880229c54db1f180153 and Go f62d3202bf9dbb3a00ad2a2c63ff4fa4188c5d3b.
 race_linux_arm64.syso built with LLVM 89f7ccea6f6488c443655880229c54db1f180153 and Go f62d3202bf9dbb3a00ad2a2c63ff4fa4188c5d3b.
 race_darwin_arm64.syso built with LLVM 00da38ce2d36c07f12c287dc515d37bb7bc410e9 and Go fe70a3a0fd31441bcbb9932ecab11a6083cf2119.
+race_openbsd_amd64.syso built with LLVM fcf6ae2f070eba73074b6ec8d8281e54d29dbeeb and Go 8f2db14cd35bbd674cb2988a508306de6655e425.
diff --git a/src/runtime/race/output_test.go b/src/runtime/race/output_test.go
index 6949687..9905207 100644
--- a/src/runtime/race/output_test.go
+++ b/src/runtime/race/output_test.go
@@ -2,11 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build race
 // +build race
 
 package race_test
 
 import (
+	"fmt"
 	"internal/testenv"
 	"os"
 	"os/exec"
@@ -18,11 +20,7 @@
 )
 
 func TestOutput(t *testing.T) {
-	pkgdir, err := os.MkdirTemp("", "go-build-race-output")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(pkgdir)
+	pkgdir := t.TempDir()
 	out, err := exec.Command(testenv.GoToolPath(t), "install", "-race", "-pkgdir="+pkgdir, "testing").CombinedOutput()
 	if err != nil {
 		t.Fatalf("go install -race: %v\n%s", err, out)
@@ -33,11 +31,7 @@
 			t.Logf("test %v runs only on %v, skipping: ", test.name, test.goos)
 			continue
 		}
-		dir, err := os.MkdirTemp("", "go-build")
-		if err != nil {
-			t.Fatalf("failed to create temp directory: %v", err)
-		}
-		defer os.RemoveAll(dir)
+		dir := t.TempDir()
 		source := "main.go"
 		if test.run == "test" {
 			source = "main_test.go"
@@ -71,9 +65,24 @@
 			"GORACE="+test.gorace,
 		)
 		got, _ := cmd.CombinedOutput()
-		if !regexp.MustCompile(test.re).MatchString(string(got)) {
-			t.Fatalf("failed test case %v, expect:\n%v\ngot:\n%s",
-				test.name, test.re, got)
+		matched := false
+		for _, re := range test.re {
+			if regexp.MustCompile(re).MatchString(string(got)) {
+				matched = true
+				break
+			}
+		}
+		if !matched {
+			exp := fmt.Sprintf("expect:\n%v\n", test.re[0])
+			if len(test.re) > 1 {
+				exp = fmt.Sprintf("expected one of %d patterns:\n",
+					len(test.re))
+				for k, re := range test.re {
+					exp += fmt.Sprintf("pattern %d:\n%v\n", k, re)
+				}
+			}
+			t.Fatalf("failed test case %v, %sgot:\n%s",
+				test.name, exp, got)
 		}
 	}
 }
@@ -84,11 +93,13 @@
 	goos   string
 	gorace string
 	source string
-	re     string
+	re     []string
 }{
 	{"simple", "run", "", "atexit_sleep_ms=0", `
 package main
 import "time"
+var xptr *int
+var donechan chan bool
 func main() {
 	done := make(chan bool)
 	x := 0
@@ -100,36 +111,38 @@
 	*x = v
 }
 func startRacer(x *int, done chan bool) {
-	go racer(x, done)
+	xptr = x
+	donechan = done
+	go racer()
 }
-func racer(x *int, done chan bool) {
+func racer() {
 	time.Sleep(10*time.Millisecond)
-	store(x, 42)
-	done <- true
+	store(xptr, 42)
+	donechan <- true
 }
-`, `==================
+`, []string{`==================
 WARNING: DATA RACE
 Write at 0x[0-9,a-f]+ by goroutine [0-9]:
   main\.store\(\)
-      .+/main\.go:12 \+0x[0-9,a-f]+
+      .+/main\.go:14 \+0x[0-9,a-f]+
   main\.racer\(\)
-      .+/main\.go:19 \+0x[0-9,a-f]+
+      .+/main\.go:23 \+0x[0-9,a-f]+
 
 Previous write at 0x[0-9,a-f]+ by main goroutine:
   main\.store\(\)
-      .+/main\.go:12 \+0x[0-9,a-f]+
+      .+/main\.go:14 \+0x[0-9,a-f]+
   main\.main\(\)
-      .+/main\.go:8 \+0x[0-9,a-f]+
+      .+/main\.go:10 \+0x[0-9,a-f]+
 
 Goroutine [0-9] \(running\) created at:
   main\.startRacer\(\)
-      .+/main\.go:15 \+0x[0-9,a-f]+
+      .+/main\.go:19 \+0x[0-9,a-f]+
   main\.main\(\)
-      .+/main\.go:7 \+0x[0-9,a-f]+
+      .+/main\.go:9 \+0x[0-9,a-f]+
 ==================
 Found 1 data race\(s\)
 exit status 66
-`},
+`}},
 
 	{"exitcode", "run", "", "atexit_sleep_ms=0 exitcode=13", `
 package main
@@ -143,7 +156,7 @@
 	x = 43
 	<-done
 }
-`, `exit status 13`},
+`, []string{`exit status 13`}},
 
 	{"strip_path_prefix", "run", "", "atexit_sleep_ms=0 strip_path_prefix=/main.", `
 package main
@@ -157,9 +170,9 @@
 	x = 43
 	<-done
 }
-`, `
+`, []string{`
       go:7 \+0x[0-9,a-f]+
-`},
+`}},
 
 	{"halt_on_error", "run", "", "atexit_sleep_ms=0 halt_on_error=1", `
 package main
@@ -173,10 +186,10 @@
 	x = 43
 	<-done
 }
-`, `
+`, []string{`
 ==================
 exit status 66
-`},
+`}},
 
 	{"test_fails_on_race", "test", "", "atexit_sleep_ms=0", `
 package main_test
@@ -193,12 +206,12 @@
 	<-done
 	t.Log(t.Failed())
 }
-`, `
+`, []string{`
 ==================
 --- FAIL: TestFail \(0...s\)
 .*main_test.go:14: true
 .*testing.go:.*: race detected during execution of test
-FAIL`},
+FAIL`}},
 
 	{"slicebytetostring_pc", "run", "", "atexit_sleep_ms=0", `
 package main
@@ -211,26 +224,26 @@
 	data[0] = 1
 	<-done
 }
-`, `
+`, []string{`
   runtime\.slicebytetostring\(\)
       .*/runtime/string\.go:.*
   main\.main\.func1\(\)
-      .*/main.go:7`},
+      .*/main.go:7`}},
 
 	// Test for https://golang.org/issue/33309
 	{"midstack_inlining_traceback", "run", "linux", "atexit_sleep_ms=0", `
 package main
 
 var x int
-
+var c chan int
 func main() {
-	c := make(chan int)
-	go f(c)
+	c = make(chan int)
+	go f()
 	x = 1
 	<-c
 }
 
-func f(c chan int) {
+func f() {
 	g(c)
 }
 
@@ -241,7 +254,7 @@
 func h(c chan int) {
 	c <- x
 }
-`, `==================
+`, []string{`==================
 WARNING: DATA RACE
 Read at 0x[0-9,a-f]+ by goroutine [0-9]:
   main\.h\(\)
@@ -261,7 +274,7 @@
 ==================
 Found 1 data race\(s\)
 exit status 66
-`},
+`}},
 
 	// Test for https://golang.org/issue/17190
 	{"external_cgo_thread", "run", "linux", "atexit_sleep_ms=0", `
@@ -300,7 +313,25 @@
 	racy++
 	<- done
 }
-`, `==================
+`, []string{`==================
+WARNING: DATA RACE
+Read at 0x[0-9,a-f]+ by main goroutine:
+  main\.main\(\)
+      .*/main\.go:34 \+0x[0-9,a-f]+
+
+Previous write at 0x[0-9,a-f]+ by goroutine [0-9]:
+  main\.goCallback\(\)
+      .*/main\.go:27 \+0x[0-9,a-f]+
+  _cgoexp_[0-9a-z]+_goCallback\(\)
+      .*_cgo_gotypes\.go:[0-9]+ \+0x[0-9,a-f]+
+  _cgoexp_[0-9a-z]+_goCallback\(\)
+      <autogenerated>:1 \+0x[0-9,a-f]+
+
+Goroutine [0-9] \(running\) created at:
+  runtime\.newextram\(\)
+      .*/runtime/proc.go:[0-9]+ \+0x[0-9,a-f]+
+==================`,
+		`==================
 WARNING: DATA RACE
 Read at 0x[0-9,a-f]+ by .*:
   main\..*
@@ -313,7 +344,7 @@
 Goroutine [0-9] \(running\) created at:
   runtime\.newextram\(\)
       .*/runtime/proc.go:[0-9]+ \+0x[0-9,a-f]+
-==================`},
+==================`}},
 	{"second_test_passes", "test", "", "atexit_sleep_ms=0", `
 package main_test
 import "testing"
@@ -331,11 +362,11 @@
 
 func TestPass(t *testing.T) {
 }
-`, `
+`, []string{`
 ==================
 --- FAIL: TestFail \(0...s\)
 .*testing.go:.*: race detected during execution of test
-FAIL`},
+FAIL`}},
 	{"mutex", "run", "", "atexit_sleep_ms=0", `
 package main
 import (
@@ -366,7 +397,7 @@
 	}
 	wg.Wait()
 	if (data == iterations*(threads+1)) { fmt.Println("pass") }
-}`, `pass`},
+}`, []string{`pass`}},
 	// Test for https://github.com/golang/go/issues/37355
 	{"chanmm", "run", "", "atexit_sleep_ms=0", `
 package main
@@ -395,7 +426,7 @@
 	wg.Wait()
 	_ = data
 }
-`, `==================
+`, []string{`==================
 WARNING: DATA RACE
 Write at 0x[0-9,a-f]+ by goroutine [0-9]:
   main\.main\.func2\(\)
@@ -408,5 +439,5 @@
 Goroutine [0-9] \(running\) created at:
   main\.main\(\)
       .*/main.go:[0-9]+ \+0x[0-9,a-f]+
-==================`},
+==================`}},
 }
diff --git a/src/runtime/race/race.go b/src/runtime/race/race.go
index d6a14b7..84050e8 100644
--- a/src/runtime/race/race.go
+++ b/src/runtime/race/race.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build race,linux,amd64 race,freebsd,amd64 race,netbsd,amd64 race,darwin,amd64 race,windows,amd64 race,linux,ppc64le race,linux,arm64 race,darwin,arm64
+//go:build (race && linux && amd64) || (race && freebsd && amd64) || (race && netbsd && amd64) || (race && darwin && amd64) || (race && windows && amd64) || (race && linux && ppc64le) || (race && linux && arm64) || (race && darwin && arm64) || (race && openbsd && amd64)
+// +build race,linux,amd64 race,freebsd,amd64 race,netbsd,amd64 race,darwin,amd64 race,windows,amd64 race,linux,ppc64le race,linux,arm64 race,darwin,arm64 race,openbsd,amd64
 
 package race
 
diff --git a/src/runtime/race/race_linux_test.go b/src/runtime/race/race_linux_test.go
index c00ce4d..9c0d48d 100644
--- a/src/runtime/race/race_linux_test.go
+++ b/src/runtime/race/race_linux_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && race
 // +build linux,race
 
 package race_test
diff --git a/src/runtime/race/race_openbsd_amd64.syso b/src/runtime/race/race_openbsd_amd64.syso
new file mode 100644
index 0000000..9fefd87
--- /dev/null
+++ b/src/runtime/race/race_openbsd_amd64.syso
Binary files differ
diff --git a/src/runtime/race/race_test.go b/src/runtime/race/race_test.go
index d433af6..8c880b8 100644
--- a/src/runtime/race/race_test.go
+++ b/src/runtime/race/race_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build race
 // +build race
 
 // This program is used to verify the race detector
diff --git a/src/runtime/race/race_unix_test.go b/src/runtime/race/race_unix_test.go
index 84f0ace..acd6e47 100644
--- a/src/runtime/race/race_unix_test.go
+++ b/src/runtime/race/race_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build race && (darwin || freebsd || linux)
 // +build race
 // +build darwin freebsd linux
 
diff --git a/src/runtime/race/race_windows_test.go b/src/runtime/race/race_windows_test.go
index 307a1ea..e490d76 100644
--- a/src/runtime/race/race_windows_test.go
+++ b/src/runtime/race/race_windows_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build windows && race
 // +build windows,race
 
 package race_test
diff --git a/src/runtime/race/sched_test.go b/src/runtime/race/sched_test.go
index d6bb323..e904ebd 100644
--- a/src/runtime/race/sched_test.go
+++ b/src/runtime/race/sched_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build race
 // +build race
 
 package race_test
diff --git a/src/runtime/race/syso_test.go b/src/runtime/race/syso_test.go
index db846c5..f509573 100644
--- a/src/runtime/race/syso_test.go
+++ b/src/runtime/race/syso_test.go
@@ -2,13 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !android,!js,!ppc64le
-
-// Note: we don't run on Android or ppc64 because if there is any non-race test
-// file in this package, the OS tries to link the .syso file into the
-// test (even when we're not in race mode), which fails. I'm not sure
-// why, but easiest to just punt - as long as a single builder runs
-// this test, we're good.
+//go:build race
+// +build race
 
 package race
 
diff --git a/src/runtime/race/testdata/io_test.go b/src/runtime/race/testdata/io_test.go
index c5055f7..3303cb0 100644
--- a/src/runtime/race/testdata/io_test.go
+++ b/src/runtime/race/testdata/io_test.go
@@ -17,7 +17,7 @@
 
 func TestNoRaceIOFile(t *testing.T) {
 	x := 0
-	path, _ := os.MkdirTemp("", "race_test")
+	path := t.TempDir()
 	fname := filepath.Join(path, "data")
 	go func() {
 		x = 42
diff --git a/src/runtime/race/testdata/mutex_test.go b/src/runtime/race/testdata/mutex_test.go
index cbed2d3..9dbed9a 100644
--- a/src/runtime/race/testdata/mutex_test.go
+++ b/src/runtime/race/testdata/mutex_test.go
@@ -78,16 +78,23 @@
 	var mu sync.Mutex
 	var x int16 = 0
 	_ = x
+	written := false
 	ch := make(chan bool, 2)
 	go func() {
 		x = 1
 		mu.Lock()
+		written = true
 		mu.Unlock()
 		ch <- true
 	}()
 	go func() {
-		<-time.After(1e5)
+		time.Sleep(100 * time.Microsecond)
 		mu.Lock()
+		for !written {
+			mu.Unlock()
+			time.Sleep(100 * time.Microsecond)
+			mu.Lock()
+		}
 		mu.Unlock()
 		x = 1
 		ch <- true
diff --git a/src/runtime/race/timer_test.go b/src/runtime/race/timer_test.go
index a6c34a8..f11f845 100644
--- a/src/runtime/race/timer_test.go
+++ b/src/runtime/race/timer_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build race
 // +build race
 
 package race_test
diff --git a/src/runtime/race0.go b/src/runtime/race0.go
index 180f707..0e431b8 100644
--- a/src/runtime/race0.go
+++ b/src/runtime/race0.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !race
 // +build !race
 
 // Dummy race detection API, used when not built with -race.
diff --git a/src/runtime/race_amd64.s b/src/runtime/race_amd64.s
index 9818bc6..8d4813e 100644
--- a/src/runtime/race_amd64.s
+++ b/src/runtime/race_amd64.s
@@ -2,12 +2,14 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build race
 // +build race
 
 #include "go_asm.h"
 #include "go_tls.h"
 #include "funcdata.h"
 #include "textflag.h"
+#include "cgo/abi_amd64.h"
 
 // The following thunks allow calling the gcc-compiled race runtime directly
 // from Go code without going all the way through cgo.
@@ -44,7 +46,11 @@
 // Defined as ABIInternal so as to avoid introducing a wrapper,
 // which would render runtime.getcallerpc ineffective.
 TEXT	runtime·raceread<ABIInternal>(SB), NOSPLIT, $0-8
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	AX, RARG1
+#else
 	MOVQ	addr+0(FP), RARG1
+#endif
 	MOVQ	(SP), RARG2
 	// void __tsan_read(ThreadState *thr, void *addr, void *pc);
 	MOVQ	$__tsan_read(SB), AX
@@ -70,7 +76,11 @@
 // Defined as ABIInternal so as to avoid introducing a wrapper,
 // which would render runtime.getcallerpc ineffective.
 TEXT	runtime·racewrite<ABIInternal>(SB), NOSPLIT, $0-8
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	AX, RARG1
+#else
 	MOVQ	addr+0(FP), RARG1
+#endif
 	MOVQ	(SP), RARG2
 	// void __tsan_write(ThreadState *thr, void *addr, void *pc);
 	MOVQ	$__tsan_write(SB), AX
@@ -121,8 +131,13 @@
 // Defined as ABIInternal so as to avoid introducing a wrapper,
 // which would render runtime.getcallerpc ineffective.
 TEXT	runtime·racewriterange<ABIInternal>(SB), NOSPLIT, $0-16
+#ifdef GOEXPERIMENT_regabiargs
+	MOVQ	AX, RARG1
+	MOVQ	BX, RARG2
+#else
 	MOVQ	addr+0(FP), RARG1
 	MOVQ	size+8(FP), RARG2
+#endif
 	MOVQ	(SP), RARG3
 	// void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc);
 	MOVQ	$__tsan_write_range(SB), AX
@@ -146,8 +161,10 @@
 // If addr (RARG1) is out of range, do nothing.
 // Otherwise, setup goroutine context and invoke racecall. Other arguments already set.
 TEXT	racecalladdr<>(SB), NOSPLIT, $0-0
+#ifndef GOEXPERIMENT_regabig
 	get_tls(R12)
 	MOVQ	g(R12), R14
+#endif
 	MOVQ	g_racectx(R14), RARG0	// goroutine context
 	// Check that addr is within [arenastart, arenaend) or within [racedatastart, racedataend).
 	CMPQ	RARG1, runtime·racearenastart(SB)
@@ -165,40 +182,36 @@
 ret:
 	RET
 
-// func runtime·racefuncenterfp(fp uintptr)
-// Called from instrumented code.
-// Like racefuncenter but passes FP, not PC
-TEXT	runtime·racefuncenterfp(SB), NOSPLIT, $0-8
-	MOVQ	fp+0(FP), R11
-	MOVQ	-8(R11), R11
-	JMP	racefuncenter<>(SB)
-
 // func runtime·racefuncenter(pc uintptr)
 // Called from instrumented code.
 TEXT	runtime·racefuncenter(SB), NOSPLIT, $0-8
 	MOVQ	callpc+0(FP), R11
 	JMP	racefuncenter<>(SB)
 
-// Common code for racefuncenter/racefuncenterfp
+// Common code for racefuncenter
 // R11 = caller's return address
 TEXT	racefuncenter<>(SB), NOSPLIT, $0-0
-	MOVQ	DX, R15		// save function entry context (for closures)
+	MOVQ	DX, BX		// save function entry context (for closures)
+#ifndef GOEXPERIMENT_regabig
 	get_tls(R12)
 	MOVQ	g(R12), R14
+#endif
 	MOVQ	g_racectx(R14), RARG0	// goroutine context
 	MOVQ	R11, RARG1
 	// void __tsan_func_enter(ThreadState *thr, void *pc);
 	MOVQ	$__tsan_func_enter(SB), AX
-	// racecall<> preserves R15
+	// racecall<> preserves BX
 	CALL	racecall<>(SB)
-	MOVQ	R15, DX	// restore function entry context
+	MOVQ	BX, DX	// restore function entry context
 	RET
 
 // func runtime·racefuncexit()
 // Called from instrumented code.
 TEXT	runtime·racefuncexit(SB), NOSPLIT, $0-0
+#ifndef GOEXPERIMENT_regabig
 	get_tls(R12)
 	MOVQ	g(R12), R14
+#endif
 	MOVQ	g_racectx(R14), RARG0	// goroutine context
 	// void __tsan_func_exit(ThreadState *thr);
 	MOVQ	$__tsan_func_exit(SB), AX
@@ -357,8 +370,10 @@
 	JAE	racecallatomic_ignore
 racecallatomic_ok:
 	// Addr is within the good range, call the atomic function.
+#ifndef GOEXPERIMENT_regabig
 	get_tls(R12)
 	MOVQ	g(R12), R14
+#endif
 	MOVQ	g_racectx(R14), RARG0	// goroutine context
 	MOVQ	8(SP), RARG1	// caller pc
 	MOVQ	(SP), RARG2	// pc
@@ -368,13 +383,15 @@
 	// Addr is outside the good range.
 	// Call __tsan_go_ignore_sync_begin to ignore synchronization during the atomic op.
 	// An attempt to synchronize on the address would cause crash.
-	MOVQ	AX, R15	// remember the original function
+	MOVQ	AX, BX	// remember the original function
 	MOVQ	$__tsan_go_ignore_sync_begin(SB), AX
+#ifndef GOEXPERIMENT_regabig
 	get_tls(R12)
 	MOVQ	g(R12), R14
+#endif
 	MOVQ	g_racectx(R14), RARG0	// goroutine context
 	CALL	racecall<>(SB)
-	MOVQ	R15, AX	// restore the original function
+	MOVQ	BX, AX	// restore the original function
 	// Call the atomic function.
 	MOVQ	g_racectx(R14), RARG0	// goroutine context
 	MOVQ	8(SP), RARG1	// caller pc
@@ -399,8 +416,10 @@
 
 // Switches SP to g0 stack and calls (AX). Arguments already set.
 TEXT	racecall<>(SB), NOSPLIT, $0-0
+#ifndef GOEXPERIMENT_regabig
 	get_tls(R12)
 	MOVQ	g(R12), R14
+#endif
 	MOVQ	g_m(R14), R13
 	// Switch to g0 stack.
 	MOVQ	SP, R12		// callee-saved, preserved across the CALL
@@ -412,6 +431,9 @@
 	ANDQ	$~15, SP	// alignment for gcc ABI
 	CALL	AX
 	MOVQ	R12, SP
+	// Back to Go world, set special registers.
+	// The g register (R14) is preserved in C.
+	XORPS	X15, X15
 	RET
 
 // C->Go callback thunk that allows to call runtime·racesymbolize from C code.
@@ -419,7 +441,9 @@
 // The overall effect of Go->C->Go call chain is similar to that of mcall.
 // RARG0 contains command code. RARG1 contains command-specific context.
 // See racecallback for command codes.
-TEXT	runtime·racecallbackthunk(SB), NOSPLIT, $56-8
+// Defined as ABIInternal so as to avoid introducing a wrapper,
+// because its address is passed to C via funcPC.
+TEXT	runtime·racecallbackthunk<ABIInternal>(SB), NOSPLIT, $0-0
 	// Handle command raceGetProcCmd (0) here.
 	// First, code below assumes that we are on curg, while raceGetProcCmd
 	// can be executed on g0. Second, it is called frequently, so will
@@ -435,24 +459,17 @@
 	RET
 
 rest:
-	// Save callee-saved registers (Go code won't respect that).
-	// This is superset of darwin/linux/windows registers.
-	PUSHQ	BX
-	PUSHQ	BP
-	PUSHQ	DI
-	PUSHQ	SI
-	PUSHQ	R12
-	PUSHQ	R13
-	PUSHQ	R14
-	PUSHQ	R15
+	// Transition from C ABI to Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
 	// Set g = g0.
 	get_tls(R12)
-	MOVQ	g(R12), R13
-	MOVQ	g_m(R13), R14
-	MOVQ	m_g0(R14), R15
+	MOVQ	g(R12), R14
+	MOVQ	g_m(R14), R13
+	MOVQ	m_g0(R13), R15
 	CMPQ	R13, R15
 	JEQ	noswitch	// branch if already on g0
 	MOVQ	R15, g(R12)	// g = m->g0
+	MOVQ	R15, R14	// set g register
 	PUSHQ	RARG1	// func arg
 	PUSHQ	RARG0	// func arg
 	CALL	runtime·racecallback(SB)
@@ -465,15 +482,7 @@
 	MOVQ	m_curg(R13), R14
 	MOVQ	R14, g(R12)	// g = m->curg
 ret:
-	// Restore callee-saved registers.
-	POPQ	R15
-	POPQ	R14
-	POPQ	R13
-	POPQ	R12
-	POPQ	SI
-	POPQ	DI
-	POPQ	BP
-	POPQ	BX
+	POP_REGS_HOST_TO_ABI0()
 	RET
 
 noswitch:
diff --git a/src/runtime/race_arm64.s b/src/runtime/race_arm64.s
index 8aa1774..c6d5b91 100644
--- a/src/runtime/race_arm64.s
+++ b/src/runtime/race_arm64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build race
 // +build race
 
 #include "go_asm.h"
@@ -160,21 +161,13 @@
 ret:
 	RET
 
-// func runtime·racefuncenterfp(fp uintptr)
-// Called from instrumented code.
-// Like racefuncenter but doesn't passes an arg, uses the caller pc
-// from the first slot on the stack
-TEXT	runtime·racefuncenterfp(SB), NOSPLIT, $0-0
-	MOVD	0(RSP), R9
-	JMP	racefuncenter<>(SB)
-
 // func runtime·racefuncenter(pc uintptr)
 // Called from instrumented code.
 TEXT	runtime·racefuncenter(SB), NOSPLIT, $0-8
 	MOVD	callpc+0(FP), R9
 	JMP	racefuncenter<>(SB)
 
-// Common code for racefuncenter/racefuncenterfp
+// Common code for racefuncenter
 // R9 = caller's return address
 TEXT	racefuncenter<>(SB), NOSPLIT, $0-0
 	load_g
diff --git a/src/runtime/race_ppc64le.s b/src/runtime/race_ppc64le.s
index 8961254..963e570 100644
--- a/src/runtime/race_ppc64le.s
+++ b/src/runtime/race_ppc64le.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build race
 // +build race
 
 #include "go_asm.h"
@@ -36,9 +37,9 @@
 // racecalladdr.
 //
 // The sequence used to get the race ctx:
-//    MOVD    runtime·tls_g(SB), R10	// offset to TLS
-//    MOVD    0(R13)(R10*1), g		// R13=TLS for this thread, g = R30
-//    MOVD    g_racectx(g), R3		// racectx == ThreadState
+//    MOVD    runtime·tls_g(SB), R10 // Address of TLS variable
+//    MOVD    0(R10), g              // g = R30
+//    MOVD    g_racectx(g), R3       // racectx == ThreadState
 
 // func runtime·RaceRead(addr uintptr)
 // Called from instrumented Go code
@@ -137,7 +138,7 @@
 // Otherwise, setup goroutine context and invoke racecall. Other arguments already set.
 TEXT	racecalladdr<>(SB), NOSPLIT, $0-0
 	MOVD    runtime·tls_g(SB), R10
-	MOVD	0(R13)(R10*1), g
+	MOVD	0(R10), g
 	MOVD	g_racectx(g), R3	// goroutine context
 	// Check that addr is within [arenastart, arenaend) or within [racedatastart, racedataend).
 	MOVD	runtime·racearenastart(SB), R9
@@ -163,27 +164,17 @@
 ret:
 	RET
 
-// func runtime·racefuncenterfp()
-// Called from instrumented Go code.
-// Like racefuncenter but doesn't pass an arg, uses the caller pc
-// from the first slot on the stack.
-TEXT	runtime·racefuncenterfp(SB), NOSPLIT, $0-0
-	MOVD	0(R1), R8
-	BR	racefuncenter<>(SB)
-
 // func runtime·racefuncenter(pc uintptr)
 // Called from instrumented Go code.
-// Not used now since gc/racewalk.go doesn't pass the
-// correct caller pc and racefuncenterfp can do it.
 TEXT	runtime·racefuncenter(SB), NOSPLIT, $0-8
 	MOVD	callpc+0(FP), R8
 	BR	racefuncenter<>(SB)
 
-// Common code for racefuncenter/racefuncenterfp
+// Common code for racefuncenter
 // R11 = caller's return address
 TEXT	racefuncenter<>(SB), NOSPLIT, $0-0
 	MOVD    runtime·tls_g(SB), R10
-	MOVD    0(R13)(R10*1), g
+	MOVD    0(R10), g
 	MOVD    g_racectx(g), R3        // goroutine racectx aka *ThreadState
 	MOVD	R8, R4			// caller pc set by caller in R8
 	// void __tsan_func_enter(ThreadState *thr, void *pc);
@@ -195,7 +186,7 @@
 // Called from Go instrumented code.
 TEXT	runtime·racefuncexit(SB), NOSPLIT, $0-0
 	MOVD    runtime·tls_g(SB), R10
-	MOVD    0(R13)(R10*1), g
+	MOVD    0(R10), g
 	MOVD    g_racectx(g), R3        // goroutine racectx aka *ThreadState
 	// void __tsan_func_exit(ThreadState *thr);
 	MOVD	$__tsan_func_exit(SB), R8
@@ -390,7 +381,7 @@
 racecallatomic_ok:
 	// Addr is within the good range, call the atomic function.
 	MOVD    runtime·tls_g(SB), R10
-	MOVD    0(R13)(R10*1), g
+	MOVD    0(R10), g
 	MOVD    g_racectx(g), R3        // goroutine racectx aka *ThreadState
 	MOVD	R8, R5			// pc is the function called
 	MOVD	(R1), R4		// caller pc from stack
@@ -404,7 +395,7 @@
 	MOVD	R6, R17 // save the original arg list addr
 	MOVD	$__tsan_go_ignore_sync_begin(SB), R8 // func addr to call
 	MOVD    runtime·tls_g(SB), R10
-	MOVD    0(R13)(R10*1), g
+	MOVD    0(R10), g
 	MOVD    g_racectx(g), R3        // goroutine context
 	BL	racecall<>(SB)
 	MOVD	R15, R8	// restore the original function
@@ -412,7 +403,7 @@
 	// Call the atomic function.
 	// racecall will call LLVM race code which might clobber r30 (g)
 	MOVD	runtime·tls_g(SB), R10
-	MOVD	0(R13)(R10*1), g
+	MOVD	0(R10), g
 
 	MOVD	g_racectx(g), R3
 	MOVD	R8, R4		// pc being called same TODO as above
@@ -444,7 +435,7 @@
 	MOVD	R10, 16(R1)	// C ABI
 	// Get info from the current goroutine
 	MOVD    runtime·tls_g(SB), R10	// g offset in TLS
-	MOVD    0(R13)(R10*1), g	// R13 = current TLS
+	MOVD    0(R10), g
 	MOVD	g_m(g), R7		// m for g
 	MOVD	R1, R16			// callee-saved, preserved across C call
 	MOVD	m_g0(R7), R10		// g0 for m
@@ -458,7 +449,7 @@
 	XOR     R0, R0			// clear R0 on return from Clang
 	MOVD	R16, R1			// restore R1; R16 nonvol in Clang
 	MOVD    runtime·tls_g(SB), R10	// find correct g
-	MOVD    0(R13)(R10*1), g
+	MOVD    0(R10), g
 	MOVD	16(R1), R10		// LR was saved away, restore for return
 	MOVD	R10, LR
 	RET
@@ -479,7 +470,7 @@
 	// g0 TODO: Don't modify g here since R30 is nonvolatile
 	MOVD	g, R9
 	MOVD    runtime·tls_g(SB), R10
-	MOVD    0(R13)(R10*1), g
+	MOVD    0(R10), g
 	MOVD	g_m(g), R3
 	MOVD	m_p(R3), R3
 	MOVD	p_raceprocctx(R3), R3
@@ -537,7 +528,7 @@
 	MOVD	R4, FIXED_FRAME+8(R1)
 
 	MOVD    runtime·tls_g(SB), R10
-	MOVD    0(R13)(R10*1), g
+	MOVD    0(R10), g
 
 	MOVD	g_m(g), R7
 	MOVD	m_g0(R7), R8
@@ -550,7 +541,7 @@
 
 	// All registers are clobbered after Go code, reload.
 	MOVD    runtime·tls_g(SB), R10
-	MOVD    0(R13)(R10*1), g
+	MOVD    0(R10), g
 
 	MOVD	g_m(g), R7
 	MOVD	m_curg(R7), g // restore g = m->curg
diff --git a/src/runtime/relax_stub.go b/src/runtime/relax_stub.go
index 81ed129..5b92879 100644
--- a/src/runtime/relax_stub.go
+++ b/src/runtime/relax_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows
 // +build !windows
 
 package runtime
diff --git a/src/runtime/rt0_linux_mips64x.s b/src/runtime/rt0_linux_mips64x.s
index 5550675..fabd857 100644
--- a/src/runtime/rt0_linux_mips64x.s
+++ b/src/runtime/rt0_linux_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips64 || mips64le)
 // +build linux
 // +build mips64 mips64le
 
diff --git a/src/runtime/rt0_linux_mipsx.s b/src/runtime/rt0_linux_mipsx.s
index 74b8f50..9f5842b 100644
--- a/src/runtime/rt0_linux_mipsx.s
+++ b/src/runtime/rt0_linux_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips || mipsle)
 // +build linux
 // +build mips mipsle
 
diff --git a/src/runtime/rt0_windows_amd64.s b/src/runtime/rt0_windows_amd64.s
index 345e141..e60bf4c 100644
--- a/src/runtime/rt0_windows_amd64.s
+++ b/src/runtime/rt0_windows_amd64.s
@@ -16,24 +16,12 @@
 // phase.
 // Leave space for four pointers on the stack as required
 // by the Windows amd64 calling convention.
-TEXT _rt0_amd64_windows_lib(SB),NOSPLIT,$0x48
-	MOVQ	BP, 0x20(SP)
-	MOVQ	BX, 0x28(SP)
-	MOVQ	AX, 0x30(SP)
-	MOVQ  CX, 0x38(SP)
-	MOVQ  DX, 0x40(SP)
-
+TEXT _rt0_amd64_windows_lib(SB),NOSPLIT,$0x20
 	// Create a new thread to do the runtime initialization and return.
 	MOVQ	_cgo_sys_thread_create(SB), AX
 	MOVQ	$_rt0_amd64_windows_lib_go(SB), CX
 	MOVQ	$0, DX
 	CALL	AX
-
-	MOVQ	0x20(SP), BP
-	MOVQ	0x28(SP), BX
-	MOVQ	0x30(SP), AX
-	MOVQ	0x38(SP), CX
-	MOVQ	0x40(SP), DX
 	RET
 
 TEXT _rt0_amd64_windows_lib_go(SB),NOSPLIT,$0
diff --git a/src/runtime/rt0_windows_arm64.s b/src/runtime/rt0_windows_arm64.s
new file mode 100644
index 0000000..bad85c2
--- /dev/null
+++ b/src/runtime/rt0_windows_arm64.s
@@ -0,0 +1,29 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "textflag.h"
+
+// This is the entry point for the program from the
+// kernel for an ordinary -buildmode=exe program.
+TEXT _rt0_arm64_windows(SB),NOSPLIT|NOFRAME,$0
+	B	·rt0_go(SB)
+
+TEXT _rt0_arm64_windows_lib(SB),NOSPLIT|NOFRAME,$0
+	MOVD	$_rt0_arm64_windows_lib_go(SB), R0
+	MOVD	$0, R1
+	MOVD	_cgo_sys_thread_create(SB), R2
+	B	(R2)
+
+TEXT _rt0_arm64_windows_lib_go(SB),NOSPLIT|NOFRAME,$0
+	MOVD	$0, R0
+	MOVD	$0, R1
+	MOVD	$runtime·rt0_go(SB), R2
+	B	(R2)
+
+TEXT main(SB),NOSPLIT,$0
+	MOVD	$runtime·rt0_go(SB), R2
+	B	(R2)
+
diff --git a/src/runtime/runtime-gdb_test.go b/src/runtime/runtime-gdb_test.go
index 5df8c3c..8c76a91 100644
--- a/src/runtime/runtime-gdb_test.go
+++ b/src/runtime/runtime-gdb_test.go
@@ -169,11 +169,7 @@
 	checkGdbVersion(t)
 	checkGdbPython(t)
 
-	dir, err := os.MkdirTemp("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	var buf bytes.Buffer
 	buf.WriteString("package main\n")
@@ -194,7 +190,7 @@
 		}
 	}
 
-	err = os.WriteFile(filepath.Join(dir, "main.go"), src, 0644)
+	err := os.WriteFile(filepath.Join(dir, "main.go"), src, 0644)
 	if err != nil {
 		t.Fatalf("failed to create file: %v", err)
 	}
@@ -403,15 +399,11 @@
 	t.Parallel()
 	checkGdbVersion(t)
 
-	dir, err := os.MkdirTemp("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	// Build the source code.
 	src := filepath.Join(dir, "main.go")
-	err = os.WriteFile(src, []byte(backtraceSource), 0644)
+	err := os.WriteFile(src, []byte(backtraceSource), 0644)
 	if err != nil {
 		t.Fatalf("failed to create file: %v", err)
 	}
@@ -481,15 +473,11 @@
 		t.Skip("TestGdbAutotmpTypes is too slow on aix/ppc64")
 	}
 
-	dir, err := os.MkdirTemp("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	// Build the source code.
 	src := filepath.Join(dir, "main.go")
-	err = os.WriteFile(src, []byte(autotmpTypeSource), 0644)
+	err := os.WriteFile(src, []byte(autotmpTypeSource), 0644)
 	if err != nil {
 		t.Fatalf("failed to create file: %v", err)
 	}
@@ -550,15 +538,11 @@
 	t.Parallel()
 	checkGdbVersion(t)
 
-	dir, err := os.MkdirTemp("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	// Build the source code.
 	src := filepath.Join(dir, "main.go")
-	err = os.WriteFile(src, []byte(constsSource), 0644)
+	err := os.WriteFile(src, []byte(constsSource), 0644)
 	if err != nil {
 		t.Fatalf("failed to create file: %v", err)
 	}
@@ -617,15 +601,11 @@
 	t.Parallel()
 	checkGdbVersion(t)
 
-	dir, err := os.MkdirTemp("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	// Build the source code.
 	src := filepath.Join(dir, "main.go")
-	err = os.WriteFile(src, []byte(panicSource), 0644)
+	err := os.WriteFile(src, []byte(panicSource), 0644)
 	if err != nil {
 		t.Fatalf("failed to create file: %v", err)
 	}
@@ -695,15 +675,11 @@
 	t.Parallel()
 	checkGdbVersion(t)
 
-	dir, err := os.MkdirTemp("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	// Build the source code.
 	src := filepath.Join(dir, "main.go")
-	err = os.WriteFile(src, []byte(InfCallstackSource), 0644)
+	err := os.WriteFile(src, []byte(InfCallstackSource), 0644)
 	if err != nil {
 		t.Fatalf("failed to create file: %v", err)
 	}
diff --git a/src/runtime/runtime-lldb_test.go b/src/runtime/runtime-lldb_test.go
index c923b87..19a6cc6 100644
--- a/src/runtime/runtime-lldb_test.go
+++ b/src/runtime/runtime-lldb_test.go
@@ -142,14 +142,10 @@
 
 	checkLldbPython(t)
 
-	dir, err := os.MkdirTemp("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	src := filepath.Join(dir, "main.go")
-	err = os.WriteFile(src, []byte(lldbHelloSource), 0644)
+	err := os.WriteFile(src, []byte(lldbHelloSource), 0644)
 	if err != nil {
 		t.Fatalf("failed to create src file: %v", err)
 	}
diff --git a/src/runtime/runtime1.go b/src/runtime/runtime1.go
index 30b7044..b238da8 100644
--- a/src/runtime/runtime1.go
+++ b/src/runtime/runtime1.go
@@ -310,7 +310,6 @@
 	gctrace            int32
 	invalidptr         int32
 	madvdontneed       int32 // for Linux; issue 28466
-	scavenge           int32
 	scavtrace          int32
 	scheddetail        int32
 	schedtrace         int32
@@ -339,7 +338,6 @@
 	{"invalidptr", &debug.invalidptr},
 	{"madvdontneed", &debug.madvdontneed},
 	{"sbrk", &debug.sbrk},
-	{"scavenge", &debug.scavenge},
 	{"scavtrace", &debug.scavtrace},
 	{"scheddetail", &debug.scheddetail},
 	{"schedtrace", &debug.schedtrace},
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 109f0da..5051ec4 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -5,7 +5,6 @@
 package runtime
 
 import (
-	"internal/cpu"
 	"runtime/internal/atomic"
 	"runtime/internal/sys"
 	"unsafe"
@@ -327,7 +326,7 @@
 	pc   uintptr
 	g    guintptr
 	ctxt unsafe.Pointer
-	ret  sys.Uintreg
+	ret  uintptr
 	lr   uintptr
 	bp   uintptr // for framepointer-enabled architectures
 }
@@ -413,14 +412,25 @@
 	stackguard0 uintptr // offset known to liblink
 	stackguard1 uintptr // offset known to liblink
 
-	_panic       *_panic // innermost panic - offset known to liblink
-	_defer       *_defer // innermost defer
-	m            *m      // current m; offset known to arm liblink
-	sched        gobuf
-	syscallsp    uintptr        // if status==Gsyscall, syscallsp = sched.sp to use during gc
-	syscallpc    uintptr        // if status==Gsyscall, syscallpc = sched.pc to use during gc
-	stktopsp     uintptr        // expected sp at top of stack, to check in traceback
-	param        unsafe.Pointer // passed parameter on wakeup
+	_panic    *_panic // innermost panic - offset known to liblink
+	_defer    *_defer // innermost defer
+	m         *m      // current m; offset known to arm liblink
+	sched     gobuf
+	syscallsp uintptr // if status==Gsyscall, syscallsp = sched.sp to use during gc
+	syscallpc uintptr // if status==Gsyscall, syscallpc = sched.pc to use during gc
+	stktopsp  uintptr // expected sp at top of stack, to check in traceback
+	// param is a generic pointer parameter field used to pass
+	// values in particular contexts where other storage for the
+	// parameter would be difficult to find. It is currently used
+	// in three ways:
+	// 1. When a channel operation wakes up a blocked goroutine, it sets param to
+	//    point to the sudog of the completed blocking operation.
+	// 2. By gcAssistAlloc1 to signal back to its caller that the goroutine completed
+	//    the GC cycle. It is unsafe to do so in any other way, because the goroutine's
+	//    stack may have moved in the meantime.
+	// 3. By debugCallWrap to pass parameters to a new goroutine because allocating a
+	//    closure in the runtime is forbidden.
+	param        unsafe.Pointer
 	atomicstatus uint32
 	stackLock    uint32 // sigprof/scang lock; TODO: fold in to atomicstatus
 	goid         int64
@@ -452,6 +462,10 @@
 
 	raceignore     int8     // ignore race detection events
 	sysblocktraced bool     // StartTrace has emitted EvGoInSyscall about this goroutine
+	tracking       bool     // whether we're tracking this G for sched latency statistics
+	trackingSeq    uint8    // used to decide whether to track this G
+	runnableStamp  int64    // timestamp of when the G last became runnable, only used when tracking
+	runnableTime   int64    // the amount of time spent runnable, cleared when running, only used when tracking
 	sysexitticks   int64    // cputicks when syscall has returned (for tracing)
 	traceseq       uint64   // trace event sequencer
 	tracelastp     puintptr // last P emitted an event for this goroutine
@@ -483,17 +497,28 @@
 	gcAssistBytes int64
 }
 
+// gTrackingPeriod is the number of transitions out of _Grunning between
+// latency tracking runs.
+const gTrackingPeriod = 8
+
+const (
+	// tlsSlots is the number of pointer-sized slots reserved for TLS on some platforms,
+	// like Windows.
+	tlsSlots = 6
+	tlsSize  = tlsSlots * sys.PtrSize
+)
+
 type m struct {
 	g0      *g     // goroutine with scheduling stack
 	morebuf gobuf  // gobuf arg to morestack
 	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
-	goSigStack    gsignalStack // Go-allocated signal handling stack
-	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           [tlsSlots]uintptr // thread-local storage (for x86 extern register)
 	mstartfn      func()
 	curg          *g       // current running goroutine
 	caughtsig     guintptr // goroutine running during fatal signal
@@ -537,10 +562,13 @@
 	syscalltick   uint32
 	freelink      *m // on sched.freem
 
-	// mFixup is used to synchronize OS related m state (credentials etc)
-	// use mutex to access.
+	// mFixup is used to synchronize OS related m state
+	// (credentials etc) use mutex to access. To avoid deadlocks
+	// an atomic.Load() of used being zero in mDoFixupFn()
+	// guarantees fn is nil.
 	mFixup struct {
 		lock mutex
+		used uint32
 		fn   func(bool) bool
 	}
 
@@ -605,6 +633,9 @@
 	// unit and eliminates the (potentially large) scheduling
 	// latency that otherwise arises from adding the ready'd
 	// goroutines to the end of the run queue.
+	//
+	// Note that while other P's may atomically CAS this to zero,
+	// only the owner P can CAS it to a valid G.
 	runnext guintptr
 
 	// Available G's (status == Gdead)
@@ -650,7 +681,7 @@
 	// timerModifiedEarlier status. Because the timer may have been
 	// modified again, there need not be any timer with this value.
 	// This is updated using atomic functions.
-	// This is 0 if the value is unknown.
+	// This is 0 if there are no timerModifiedEarlier timers.
 	timerModifiedEarliest uint64
 
 	// Per-P GC state
@@ -696,12 +727,6 @@
 	// Modified using atomic instructions.
 	numTimers uint32
 
-	// Number of timerModifiedEarlier timers on P's heap.
-	// This should only be modified while holding timersLock,
-	// or while the timer status is in a transient state
-	// such as timerModifying.
-	adjustTimers uint32
-
 	// Number of timerDeleted timers in P's heap.
 	// Modified using atomic instructions.
 	deletedTimers uint32
@@ -713,7 +738,8 @@
 	// scheduler ASAP (regardless of what G is running on it).
 	preempt bool
 
-	pad cpu.CacheLinePad
+	// Padding is no longer needed. False sharing is now not a worry because p is large enough
+	// that its size class is an integer multiple of the cache line size (for any of our architectures).
 }
 
 type schedt struct {
@@ -803,6 +829,15 @@
 	// Acquire and hold this mutex to block sysmon from interacting
 	// with the rest of the runtime.
 	sysmonlock mutex
+
+	_ uint32 // ensure timeToRun has 8-byte alignment
+
+	// timeToRun is a distribution of scheduling latencies, defined
+	// as the sum of time a G spends in the _Grunnable state before
+	// it transitions to _Grunning.
+	//
+	// timeToRun is protected by sched.lock.
+	timeToRun timeHistogram
 }
 
 // Values for the flags field of a sigTabT.
@@ -833,10 +868,11 @@
 	pcfile    uint32
 	pcln      uint32
 	npcdata   uint32
-	cuOffset  uint32  // runtime.cutab offset of this function's CU
-	funcID    funcID  // set for certain special runtime functions
-	_         [2]byte // pad
-	nfuncdata uint8   // must be last
+	cuOffset  uint32 // runtime.cutab offset of this function's CU
+	funcID    funcID // set for certain special runtime functions
+	flag      funcFlag
+	_         [1]byte // pad
+	nfuncdata uint8   // must be last, must end on a uint32-aligned boundary
 }
 
 // Pseudo-Func that is returned for PCs that occur in inlined code.
@@ -853,7 +889,7 @@
 // layout of Itab known to compilers
 // allocated in non-garbage-collected memory
 // Needs to be in sync with
-// ../cmd/compile/internal/gc/reflect.go:/^func.dumptabs.
+// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs.
 type itab struct {
 	inter *interfacetype
 	_type *_type
@@ -898,7 +934,7 @@
 
 // A _defer holds an entry on the list of deferred calls.
 // If you add a field here, add code to clear it in freedefer and deferProcStack
-// This struct must match the code in cmd/compile/internal/gc/reflect.go:deferstruct
+// This struct must match the code in cmd/compile/internal/reflectdata/reflect.go:deferstruct
 // and cmd/compile/internal/gc/ssa.go:(*state).call.
 // Some defers will be allocated on the stack and some on the heap.
 // All defers are logically part of the stack, so write barriers to
@@ -1104,5 +1140,5 @@
 	isarchive bool // -buildmode=c-archive
 )
 
-// Must agree with cmd/internal/objabi.Framepointer_enabled.
-const framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64" && (GOOS == "linux" || GOOS == "darwin" || GOOS == "ios")
+// Must agree with internal/buildcfg.Experiment.FramePointer.
+const framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64"
diff --git a/src/runtime/runtime_mmap_test.go b/src/runtime/runtime_mmap_test.go
index bb0b747..f71f8af 100644
--- a/src/runtime/runtime_mmap_test.go
+++ b/src/runtime/runtime_mmap_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package runtime_test
diff --git a/src/runtime/runtime_test.go b/src/runtime/runtime_test.go
index e5d2d97..4572a25 100644
--- a/src/runtime/runtime_test.go
+++ b/src/runtime/runtime_test.go
@@ -266,8 +266,8 @@
 		n int64
 		z struct{}
 	}
-	if unsafe.Sizeof(T2{}) != 8+unsafe.Sizeof(Uintreg(0)) {
-		t.Errorf("sizeof(%#v)==%d, want %d", T2{}, unsafe.Sizeof(T2{}), 8+unsafe.Sizeof(Uintreg(0)))
+	if unsafe.Sizeof(T2{}) != 8+unsafe.Sizeof(uintptr(0)) {
+		t.Errorf("sizeof(%#v)==%d, want %d", T2{}, unsafe.Sizeof(T2{}), 8+unsafe.Sizeof(uintptr(0)))
 	}
 	type T3 struct {
 		n byte
diff --git a/src/runtime/runtime_unix_test.go b/src/runtime/runtime_unix_test.go
index b0cbbbe..0251c67 100644
--- a/src/runtime/runtime_unix_test.go
+++ b/src/runtime/runtime_unix_test.go
@@ -6,6 +6,7 @@
 // We need a fast system call to provoke the race,
 // and Close(-1) is nearly universally fast.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || plan9
 // +build aix darwin dragonfly freebsd linux netbsd openbsd plan9
 
 package runtime_test
diff --git a/src/runtime/select.go b/src/runtime/select.go
index e72761b..06edb69 100644
--- a/src/runtime/select.go
+++ b/src/runtime/select.go
@@ -15,7 +15,7 @@
 
 // Select case descriptor.
 // Known to compiler.
-// Changes here must also be made in src/cmd/internal/gc/select.go's scasetype.
+// Changes here must also be made in src/cmd/compile/internal/walk/select.go's scasetype.
 type scase struct {
 	c    *hchan         // chan
 	elem unsafe.Pointer // data element
diff --git a/src/runtime/semasleep_test.go b/src/runtime/semasleep_test.go
index 9b371b0..905e932 100644
--- a/src/runtime/semasleep_test.go
+++ b/src/runtime/semasleep_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !plan9 && !windows && !js
 // +build !plan9,!windows,!js
 
 package runtime_test
diff --git a/src/runtime/sigaction.go b/src/runtime/sigaction.go
index 3c88857..30050ef 100644
--- a/src/runtime/sigaction.go
+++ b/src/runtime/sigaction.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux,!amd64,!arm64 freebsd,!amd64
+//go:build (linux && !amd64 && !arm64 && !ppc64le) || (freebsd && !amd64)
+// +build linux,!amd64,!arm64,!ppc64le freebsd,!amd64
 
 package runtime
 
diff --git a/src/runtime/signal_386.go b/src/runtime/signal_386.go
index 065aff4..5824ead 100644
--- a/src/runtime/signal_386.go
+++ b/src/runtime/signal_386.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || linux || netbsd || openbsd
 // +build dragonfly freebsd linux netbsd openbsd
 
 package runtime
diff --git a/src/runtime/signal_aix_ppc64.go b/src/runtime/signal_aix_ppc64.go
index c17563e..a0becd4 100644
--- a/src/runtime/signal_aix_ppc64.go
+++ b/src/runtime/signal_aix_ppc64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix
 // +build aix
 
 package runtime
diff --git a/src/runtime/signal_amd64.go b/src/runtime/signal_amd64.go
index 6ab1f75..e45fbb4 100644
--- a/src/runtime/signal_amd64.go
+++ b/src/runtime/signal_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 && (darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris)
 // +build amd64
 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
@@ -65,11 +66,14 @@
 	pc := uintptr(c.rip())
 	sp := uintptr(c.rsp())
 
+	// In case we are panicking from external code, we need to initialize
+	// Go special registers. We inject sigpanic0 (instead of sigpanic),
+	// which takes care of that.
 	if shouldPushSigpanic(gp, pc, *(*uintptr)(unsafe.Pointer(sp))) {
-		c.pushCall(funcPC(sigpanic), pc)
+		c.pushCall(funcPC(sigpanic0), pc)
 	} else {
 		// Not safe to push the call. Just clobber the frame.
-		c.set_rip(uint64(funcPC(sigpanic)))
+		c.set_rip(uint64(funcPC(sigpanic0)))
 	}
 }
 
diff --git a/src/runtime/signal_arm.go b/src/runtime/signal_arm.go
index 156d9d3..4d9c622 100644
--- a/src/runtime/signal_arm.go
+++ b/src/runtime/signal_arm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || linux || netbsd || openbsd
 // +build dragonfly freebsd linux netbsd openbsd
 
 package runtime
diff --git a/src/runtime/signal_arm64.go b/src/runtime/signal_arm64.go
index 3c20139..f047500 100644
--- a/src/runtime/signal_arm64.go
+++ b/src/runtime/signal_arm64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || freebsd || linux || netbsd || openbsd
 // +build darwin freebsd linux netbsd openbsd
 
 package runtime
@@ -63,7 +64,7 @@
 	// functions are correctly handled. This smashes
 	// the stack frame but we're not going back there
 	// anyway.
-	sp := c.sp() - sys.SpAlign // needs only sizeof uint64, but must align the stack
+	sp := c.sp() - sys.StackAlign // needs only sizeof uint64, but must align the stack
 	c.set_sp(sp)
 	*(*uint64)(unsafe.Pointer(uintptr(sp))) = c.lr()
 
diff --git a/src/runtime/signal_linux_mips64x.go b/src/runtime/signal_linux_mips64x.go
index b608197..f0a75ac 100644
--- a/src/runtime/signal_linux_mips64x.go
+++ b/src/runtime/signal_linux_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips64 || mips64le)
 // +build linux
 // +build mips64 mips64le
 
diff --git a/src/runtime/signal_linux_mipsx.go b/src/runtime/signal_linux_mipsx.go
index c88ac4d..f3969c5 100644
--- a/src/runtime/signal_linux_mipsx.go
+++ b/src/runtime/signal_linux_mipsx.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips || mipsle)
 // +build linux
 // +build mips mipsle
 
diff --git a/src/runtime/signal_linux_ppc64x.go b/src/runtime/signal_linux_ppc64x.go
index 97cb26d..d9d3e55 100644
--- a/src/runtime/signal_linux_ppc64x.go
+++ b/src/runtime/signal_linux_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (ppc64 || ppc64le)
 // +build linux
 // +build ppc64 ppc64le
 
diff --git a/src/runtime/signal_mips64x.go b/src/runtime/signal_mips64x.go
index 2a347ff..1616b57 100644
--- a/src/runtime/signal_mips64x.go
+++ b/src/runtime/signal_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (linux || openbsd) && (mips64 || mips64le)
 // +build linux openbsd
 // +build mips64 mips64le
 
diff --git a/src/runtime/signal_mipsx.go b/src/runtime/signal_mipsx.go
index 8c29f59..dcc7f1e 100644
--- a/src/runtime/signal_mipsx.go
+++ b/src/runtime/signal_mipsx.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips || mipsle)
 // +build linux
 // +build mips mipsle
 
diff --git a/src/runtime/signal_ppc64x.go b/src/runtime/signal_ppc64x.go
index 5de93a3..f2225da 100644
--- a/src/runtime/signal_ppc64x.go
+++ b/src/runtime/signal_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (aix || linux) && (ppc64 || ppc64le)
 // +build aix linux
 // +build ppc64 ppc64le
 
diff --git a/src/runtime/signal_riscv64.go b/src/runtime/signal_riscv64.go
index 93363a4..e6b1b14 100644
--- a/src/runtime/signal_riscv64.go
+++ b/src/runtime/signal_riscv64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && riscv64
 // +build linux,riscv64
 
 package runtime
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index 3f70707..6096760 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package runtime
@@ -279,6 +280,8 @@
 		it.it_value = it.it_interval
 		setitimer(_ITIMER_PROF, &it, nil)
 	} else {
+		setitimer(_ITIMER_PROF, &itimerval{}, nil)
+
 		// If the Go signal handler should be disabled by default,
 		// switch back to the signal handler that was installed
 		// when we enabled profiling. We don't try to handle the case
@@ -302,8 +305,6 @@
 				setsig(_SIGPROF, h)
 			}
 		}
-
-		setitimer(_ITIMER_PROF, &itimerval{}, nil)
 	}
 }
 
@@ -381,7 +382,7 @@
 //go:nosplit
 func sigFetchG(c *sigctxt) *g {
 	switch GOARCH {
-	case "arm", "arm64":
+	case "arm", "arm64", "ppc64", "ppc64le":
 		if !iscgo && inVDSOPage(c.sigpc()) {
 			// When using cgo, we save the g on TLS and load it from there
 			// in sigtramp. Just use that.
diff --git a/src/runtime/signal_windows.go b/src/runtime/signal_windows.go
index 3af2e39..b720ddc 100644
--- a/src/runtime/signal_windows.go
+++ b/src/runtime/signal_windows.go
@@ -5,6 +5,7 @@
 package runtime
 
 import (
+	"runtime/internal/sys"
 	"unsafe"
 )
 
@@ -43,13 +44,18 @@
 //
 //go:nosplit
 func isAbort(r *context) bool {
-	// In the case of an abort, the exception IP is one byte after
-	// the INT3 (this differs from UNIX OSes).
-	return isAbortPC(r.ip() - 1)
+	pc := r.ip()
+	if GOARCH == "386" || GOARCH == "amd64" || GOARCH == "arm" {
+		// In the case of an abort, the exception IP is one byte after
+		// the INT3 (this differs from UNIX OSes). Note that on ARM,
+		// this means that the exception IP is no longer aligned.
+		pc--
+	}
+	return isAbortPC(pc)
 }
 
 // isgoexception reports whether this exception should be translated
-// into a Go panic.
+// into a Go panic or throw.
 //
 // It is nosplit to avoid growing the stack in case we're aborting
 // because of a stack overflow.
@@ -63,11 +69,6 @@
 		return false
 	}
 
-	if isAbort(r) {
-		// Never turn abort into a panic.
-		return false
-	}
-
 	// Go will only handle some exceptions.
 	switch info.exceptioncode {
 	default:
@@ -81,6 +82,7 @@
 	case _EXCEPTION_FLT_OVERFLOW:
 	case _EXCEPTION_FLT_UNDERFLOW:
 	case _EXCEPTION_BREAKPOINT:
+	case _EXCEPTION_ILLEGAL_INSTRUCTION: // breakpoint arrives this way on arm64
 	}
 	return true
 }
@@ -99,21 +101,23 @@
 		return _EXCEPTION_CONTINUE_SEARCH
 	}
 
-	// After this point, it is safe to grow the stack.
-
-	if gp.throwsplit {
-		// We can't safely sigpanic because it may grow the
-		// stack. Let it fall through.
-		return _EXCEPTION_CONTINUE_SEARCH
+	if gp.throwsplit || isAbort(r) {
+		// We can't safely sigpanic because it may grow the stack.
+		// Or this is a call to abort.
+		// Don't go through any more of the Windows handler chain.
+		// Crash now.
+		winthrow(info, r, gp)
 	}
 
+	// After this point, it is safe to grow the stack.
+
 	// Make it look like a call to the signal func.
 	// Have to pass arguments out of band since
 	// augmenting the stack frame would break
 	// the unwinding code.
 	gp.sig = info.exceptioncode
-	gp.sigcode0 = uintptr(info.exceptioninformation[0])
-	gp.sigcode1 = uintptr(info.exceptioninformation[1])
+	gp.sigcode0 = info.exceptioninformation[0]
+	gp.sigcode1 = info.exceptioninformation[1]
 	gp.sigpc = r.ip()
 
 	// Only push runtime·sigpanic if r.ip() != 0.
@@ -131,19 +135,17 @@
 	// overwrite the PC. (See issue #35773)
 	if r.ip() != 0 && r.ip() != funcPC(asyncPreempt) {
 		sp := unsafe.Pointer(r.sp())
-		sp = add(sp, ^(unsafe.Sizeof(uintptr(0)) - 1)) // sp--
+		delta := uintptr(sys.StackAlign)
+		sp = add(sp, -delta)
 		r.set_sp(uintptr(sp))
-		switch GOARCH {
-		default:
-			panic("unsupported architecture")
-		case "386", "amd64":
-			*((*uintptr)(sp)) = r.ip()
-		case "arm":
+		if usesLR {
 			*((*uintptr)(sp)) = r.lr()
 			r.set_lr(r.ip())
+		} else {
+			*((*uintptr)(sp)) = r.ip()
 		}
 	}
-	r.set_ip(funcPC(sigpanic))
+	r.set_ip(funcPC(sigpanic0))
 	return _EXCEPTION_CONTINUE_EXECUTION
 }
 
@@ -181,6 +183,23 @@
 		return _EXCEPTION_CONTINUE_SEARCH
 	}
 
+	// VEH is called before SEH, but arm64 MSVC DLLs use SEH to trap
+	// illegal instructions during runtime initialization to determine
+	// CPU features, so if we make it to the last handler and we're
+	// arm64 and it's an illegal instruction and this is coming from
+	// non-Go code, then assume it's this runtime probing happen, and
+	// pass that onward to SEH.
+	if GOARCH == "arm64" && info.exceptioncode == _EXCEPTION_ILLEGAL_INSTRUCTION &&
+		(r.ip() < firstmoduledata.text || firstmoduledata.etext < r.ip()) {
+		return _EXCEPTION_CONTINUE_SEARCH
+	}
+
+	winthrow(info, r, gp)
+	return 0 // not reached
+}
+
+//go:nosplit
+func winthrow(info *exceptionrecord, r *context, gp *g) {
 	_g_ := getg()
 
 	if panicking != 0 { // traceback already printed
@@ -206,11 +225,8 @@
 	}
 	print("\n")
 
-	// TODO(jordanrh1): This may be needed for 386/AMD64 as well.
-	if GOARCH == "arm" {
-		_g_.m.throwing = 1
-		_g_.m.caughtsig.set(gp)
-	}
+	_g_.m.throwing = 1
+	_g_.m.caughtsig.set(gp)
 
 	level, _, docrash := gotraceback()
 	if level > 0 {
@@ -224,7 +240,6 @@
 	}
 
 	exit(2)
-	return 0 // not reached
 }
 
 func sigpanic() {
diff --git a/src/runtime/signal_windows_test.go b/src/runtime/signal_windows_test.go
index 33a9b92..1b7cb9d 100644
--- a/src/runtime/signal_windows_test.go
+++ b/src/runtime/signal_windows_test.go
@@ -1,3 +1,4 @@
+//go:build windows
 // +build windows
 
 package runtime_test
@@ -7,7 +8,6 @@
 	"bytes"
 	"fmt"
 	"internal/testenv"
-	"os"
 	"os/exec"
 	"path/filepath"
 	"runtime"
@@ -28,15 +28,11 @@
 	testenv.MustHaveExecPath(t, "gcc")
 	testprog.Lock()
 	defer testprog.Unlock()
-	dir, err := os.MkdirTemp("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	// build go dll
 	dll := filepath.Join(dir, "testwinlib.dll")
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dll, "--buildmode", "c-shared", "testdata/testwinlib/main.go")
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dll, "-buildmode", "c-shared", "testdata/testwinlib/main.go")
 	out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
 	if err != nil {
 		t.Fatalf("failed to build go library: %s\n%s", err, out)
@@ -156,15 +152,11 @@
 	testenv.MustHaveExecPath(t, "gcc")
 	testprog.Lock()
 	defer testprog.Unlock()
-	dir, err := os.MkdirTemp("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	// build go dll
 	dll := filepath.Join(dir, "dummy.dll")
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dll, "--buildmode", "c-shared", "testdata/testwinlibsignal/dummy.go")
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dll, "-buildmode", "c-shared", "testdata/testwinlibsignal/dummy.go")
 	out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
 	if err != nil {
 		t.Fatalf("failed to build go library: %s\n%s", err, out)
diff --git a/src/runtime/sigqueue.go b/src/runtime/sigqueue.go
index 28b9e26..6c91fb3 100644
--- a/src/runtime/sigqueue.go
+++ b/src/runtime/sigqueue.go
@@ -28,6 +28,7 @@
 // unnecessary rechecks of sig.mask, but it cannot lead to missed signals
 // nor deadlocks.
 
+//go:build !plan9
 // +build !plan9
 
 package runtime
@@ -71,7 +72,7 @@
 // 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)) {
+	if s >= uint32(32*len(sig.wanted)) {
 		return false
 	}
 
@@ -119,7 +120,7 @@
 			}
 		case sigFixup:
 			// nothing to do - we need to wait for sigIdle.
-			osyield()
+			mDoFixupAndOSYield()
 		}
 	}
 
diff --git a/src/runtime/sigqueue_note.go b/src/runtime/sigqueue_note.go
index 16aeeb2..e23446b 100644
--- a/src/runtime/sigqueue_note.go
+++ b/src/runtime/sigqueue_note.go
@@ -7,8 +7,8 @@
 // signal_recv thread. This file holds the non-Darwin implementations of
 // those functions. These functions will never be called.
 
-// +build !darwin
-// +build !plan9
+//go:build !darwin && !plan9
+// +build !darwin,!plan9
 
 package runtime
 
diff --git a/src/runtime/sigtab_linux_generic.go b/src/runtime/sigtab_linux_generic.go
index 38d6865..dc1debd 100644
--- a/src/runtime/sigtab_linux_generic.go
+++ b/src/runtime/sigtab_linux_generic.go
@@ -2,11 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !mips
-// +build !mipsle
-// +build !mips64
-// +build !mips64le
-// +build linux
+//go:build !mips && !mipsle && !mips64 && !mips64le && linux
+// +build !mips,!mipsle,!mips64,!mips64le,linux
 
 package runtime
 
diff --git a/src/runtime/sigtab_linux_mipsx.go b/src/runtime/sigtab_linux_mipsx.go
index 51ef470..af9c7e5 100644
--- a/src/runtime/sigtab_linux_mipsx.go
+++ b/src/runtime/sigtab_linux_mipsx.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (mips || mipsle || mips64 || mips64le) && linux
 // +build mips mipsle mips64 mips64le
 // +build linux
 
diff --git a/src/runtime/sizeclasses.go b/src/runtime/sizeclasses.go
index c5521ce..067871e 100644
--- a/src/runtime/sizeclasses.go
+++ b/src/runtime/sizeclasses.go
@@ -3,74 +3,83 @@
 
 package runtime
 
-// 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         24        8192      341           8     29.24%
-//     4         32        8192      256           0     21.88%
-//     5         48        8192      170          32     31.52%
-//     6         64        8192      128           0     23.44%
-//     7         80        8192      102          32     19.07%
-//     8         96        8192       85          32     15.95%
-//     9        112        8192       73          16     13.56%
-//    10        128        8192       64           0     11.72%
-//    11        144        8192       56         128     11.82%
-//    12        160        8192       51          32      9.73%
-//    13        176        8192       46          96      9.59%
-//    14        192        8192       42         128      9.25%
-//    15        208        8192       39          80      8.12%
-//    16        224        8192       36         128      8.15%
-//    17        240        8192       34          32      6.62%
-//    18        256        8192       32           0      5.86%
-//    19        288        8192       28         128     12.16%
-//    20        320        8192       25         192     11.80%
-//    21        352        8192       23          96      9.88%
-//    22        384        8192       21         128      9.51%
-//    23        416        8192       19         288     10.71%
-//    24        448        8192       18         128      8.37%
-//    25        480        8192       17          32      6.82%
-//    26        512        8192       16           0      6.05%
-//    27        576        8192       14         128     12.33%
-//    28        640        8192       12         512     15.48%
-//    29        704        8192       11         448     13.93%
-//    30        768        8192       10         512     13.94%
-//    31        896        8192        9         128     15.52%
-//    32       1024        8192        8           0     12.40%
-//    33       1152        8192        7         128     12.41%
-//    34       1280        8192        6         512     15.55%
-//    35       1408       16384       11         896     14.00%
-//    36       1536        8192        5         512     14.00%
-//    37       1792       16384        9         256     15.57%
-//    38       2048        8192        4           0     12.45%
-//    39       2304       16384        7         256     12.46%
-//    40       2688        8192        3         128     15.59%
-//    41       3072       24576        8           0     12.47%
-//    42       3200       16384        5         384      6.22%
-//    43       3456       24576        7         384      8.83%
-//    44       4096        8192        2           0     15.60%
-//    45       4864       24576        5         256     16.65%
-//    46       5376       16384        3         256     10.92%
-//    47       6144       24576        4           0     12.48%
-//    48       6528       32768        5         128      6.23%
-//    49       6784       40960        6         256      4.36%
-//    50       6912       49152        7         768      3.37%
-//    51       8192        8192        1           0     15.61%
-//    52       9472       57344        6         512     14.28%
-//    53       9728       49152        5         512      3.64%
-//    54      10240       40960        4           0      4.99%
-//    55      10880       32768        3         128      6.24%
-//    56      12288       24576        2           0     11.45%
-//    57      13568       40960        3         256      9.99%
-//    58      14336       57344        4           0      5.35%
-//    59      16384       16384        1           0     12.49%
-//    60      18432       73728        4           0     11.11%
-//    61      19072       57344        3         128      3.57%
-//    62      20480       40960        2           0      6.87%
-//    63      21760       65536        3         256      6.25%
-//    64      24576       24576        1           0     11.45%
-//    65      27264       81920        3         128     10.00%
-//    66      28672       57344        2           0      4.91%
-//    67      32768       32768        1           0     12.50%
+// class  bytes/obj  bytes/span  objects  tail waste  max waste  min align
+//     1          8        8192     1024           0     87.50%          8
+//     2         16        8192      512           0     43.75%         16
+//     3         24        8192      341           8     29.24%          8
+//     4         32        8192      256           0     21.88%         32
+//     5         48        8192      170          32     31.52%         16
+//     6         64        8192      128           0     23.44%         64
+//     7         80        8192      102          32     19.07%         16
+//     8         96        8192       85          32     15.95%         32
+//     9        112        8192       73          16     13.56%         16
+//    10        128        8192       64           0     11.72%        128
+//    11        144        8192       56         128     11.82%         16
+//    12        160        8192       51          32      9.73%         32
+//    13        176        8192       46          96      9.59%         16
+//    14        192        8192       42         128      9.25%         64
+//    15        208        8192       39          80      8.12%         16
+//    16        224        8192       36         128      8.15%         32
+//    17        240        8192       34          32      6.62%         16
+//    18        256        8192       32           0      5.86%        256
+//    19        288        8192       28         128     12.16%         32
+//    20        320        8192       25         192     11.80%         64
+//    21        352        8192       23          96      9.88%         32
+//    22        384        8192       21         128      9.51%        128
+//    23        416        8192       19         288     10.71%         32
+//    24        448        8192       18         128      8.37%         64
+//    25        480        8192       17          32      6.82%         32
+//    26        512        8192       16           0      6.05%        512
+//    27        576        8192       14         128     12.33%         64
+//    28        640        8192       12         512     15.48%        128
+//    29        704        8192       11         448     13.93%         64
+//    30        768        8192       10         512     13.94%        256
+//    31        896        8192        9         128     15.52%        128
+//    32       1024        8192        8           0     12.40%       1024
+//    33       1152        8192        7         128     12.41%        128
+//    34       1280        8192        6         512     15.55%        256
+//    35       1408       16384       11         896     14.00%        128
+//    36       1536        8192        5         512     14.00%        512
+//    37       1792       16384        9         256     15.57%        256
+//    38       2048        8192        4           0     12.45%       2048
+//    39       2304       16384        7         256     12.46%        256
+//    40       2688        8192        3         128     15.59%        128
+//    41       3072       24576        8           0     12.47%       1024
+//    42       3200       16384        5         384      6.22%        128
+//    43       3456       24576        7         384      8.83%        128
+//    44       4096        8192        2           0     15.60%       4096
+//    45       4864       24576        5         256     16.65%        256
+//    46       5376       16384        3         256     10.92%        256
+//    47       6144       24576        4           0     12.48%       2048
+//    48       6528       32768        5         128      6.23%        128
+//    49       6784       40960        6         256      4.36%        128
+//    50       6912       49152        7         768      3.37%        256
+//    51       8192        8192        1           0     15.61%       8192
+//    52       9472       57344        6         512     14.28%        256
+//    53       9728       49152        5         512      3.64%        512
+//    54      10240       40960        4           0      4.99%       2048
+//    55      10880       32768        3         128      6.24%        128
+//    56      12288       24576        2           0     11.45%       4096
+//    57      13568       40960        3         256      9.99%        256
+//    58      14336       57344        4           0      5.35%       2048
+//    59      16384       16384        1           0     12.49%       8192
+//    60      18432       73728        4           0     11.11%       2048
+//    61      19072       57344        3         128      3.57%        128
+//    62      20480       40960        2           0      6.87%       4096
+//    63      21760       65536        3         256      6.25%        256
+//    64      24576       24576        1           0     11.45%       8192
+//    65      27264       81920        3         128     10.00%        128
+//    66      28672       57344        2           0      4.91%       4096
+//    67      32768       32768        1           0     12.50%       8192
+
+// alignment  bits  min obj size
+//         8     3             8
+//        16     4            32
+//        32     5           256
+//        64     6           512
+//       128     7           768
+//      4096    12         28672
+//      8192    13         32768
 
 const (
 	_MaxSmallSize   = 32768
@@ -83,14 +92,6 @@
 
 var class_to_size = [_NumSizeClasses]uint16{0, 8, 16, 24, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896, 1024, 1152, 1280, 1408, 1536, 1792, 2048, 2304, 2688, 3072, 3200, 3456, 4096, 4864, 5376, 6144, 6528, 6784, 6912, 8192, 9472, 9728, 10240, 10880, 12288, 13568, 14336, 16384, 18432, 19072, 20480, 21760, 24576, 27264, 28672, 32768}
 var class_to_allocnpages = [_NumSizeClasses]uint8{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 2, 3, 1, 3, 2, 3, 4, 5, 6, 1, 7, 6, 5, 4, 3, 5, 7, 2, 9, 7, 5, 8, 3, 10, 7, 4}
-
-type divMagic struct {
-	shift    uint8
-	shift2   uint8
-	mul      uint16
-	baseMask uint16
-}
-
-var class_to_divmagic = [_NumSizeClasses]divMagic{{0, 0, 0, 0}, {3, 0, 1, 65528}, {4, 0, 1, 65520}, {3, 11, 683, 0}, {5, 0, 1, 65504}, {4, 11, 683, 0}, {6, 0, 1, 65472}, {4, 10, 205, 0}, {5, 9, 171, 0}, {4, 11, 293, 0}, {7, 0, 1, 65408}, {4, 13, 911, 0}, {5, 10, 205, 0}, {4, 12, 373, 0}, {6, 9, 171, 0}, {4, 13, 631, 0}, {5, 11, 293, 0}, {4, 13, 547, 0}, {8, 0, 1, 65280}, {5, 9, 57, 0}, {6, 9, 103, 0}, {5, 12, 373, 0}, {7, 7, 43, 0}, {5, 10, 79, 0}, {6, 10, 147, 0}, {5, 11, 137, 0}, {9, 0, 1, 65024}, {6, 9, 57, 0}, {7, 9, 103, 0}, {6, 11, 187, 0}, {8, 7, 43, 0}, {7, 8, 37, 0}, {10, 0, 1, 64512}, {7, 9, 57, 0}, {8, 6, 13, 0}, {7, 11, 187, 0}, {9, 5, 11, 0}, {8, 8, 37, 0}, {11, 0, 1, 63488}, {8, 9, 57, 0}, {7, 10, 49, 0}, {10, 5, 11, 0}, {7, 10, 41, 0}, {7, 9, 19, 0}, {12, 0, 1, 61440}, {8, 9, 27, 0}, {8, 10, 49, 0}, {11, 5, 11, 0}, {7, 13, 161, 0}, {7, 13, 155, 0}, {8, 9, 19, 0}, {13, 0, 1, 57344}, {8, 12, 111, 0}, {9, 9, 27, 0}, {11, 6, 13, 0}, {7, 14, 193, 0}, {12, 3, 3, 0}, {8, 13, 155, 0}, {11, 8, 37, 0}, {14, 0, 1, 49152}, {11, 8, 29, 0}, {7, 13, 55, 0}, {12, 5, 7, 0}, {8, 14, 193, 0}, {13, 3, 3, 0}, {7, 14, 77, 0}, {12, 7, 19, 0}, {15, 0, 1, 32768}}
+var class_to_divmagic = [_NumSizeClasses]uint32{0, ^uint32(0)/8 + 1, ^uint32(0)/16 + 1, ^uint32(0)/24 + 1, ^uint32(0)/32 + 1, ^uint32(0)/48 + 1, ^uint32(0)/64 + 1, ^uint32(0)/80 + 1, ^uint32(0)/96 + 1, ^uint32(0)/112 + 1, ^uint32(0)/128 + 1, ^uint32(0)/144 + 1, ^uint32(0)/160 + 1, ^uint32(0)/176 + 1, ^uint32(0)/192 + 1, ^uint32(0)/208 + 1, ^uint32(0)/224 + 1, ^uint32(0)/240 + 1, ^uint32(0)/256 + 1, ^uint32(0)/288 + 1, ^uint32(0)/320 + 1, ^uint32(0)/352 + 1, ^uint32(0)/384 + 1, ^uint32(0)/416 + 1, ^uint32(0)/448 + 1, ^uint32(0)/480 + 1, ^uint32(0)/512 + 1, ^uint32(0)/576 + 1, ^uint32(0)/640 + 1, ^uint32(0)/704 + 1, ^uint32(0)/768 + 1, ^uint32(0)/896 + 1, ^uint32(0)/1024 + 1, ^uint32(0)/1152 + 1, ^uint32(0)/1280 + 1, ^uint32(0)/1408 + 1, ^uint32(0)/1536 + 1, ^uint32(0)/1792 + 1, ^uint32(0)/2048 + 1, ^uint32(0)/2304 + 1, ^uint32(0)/2688 + 1, ^uint32(0)/3072 + 1, ^uint32(0)/3200 + 1, ^uint32(0)/3456 + 1, ^uint32(0)/4096 + 1, ^uint32(0)/4864 + 1, ^uint32(0)/5376 + 1, ^uint32(0)/6144 + 1, ^uint32(0)/6528 + 1, ^uint32(0)/6784 + 1, ^uint32(0)/6912 + 1, ^uint32(0)/8192 + 1, ^uint32(0)/9472 + 1, ^uint32(0)/9728 + 1, ^uint32(0)/10240 + 1, ^uint32(0)/10880 + 1, ^uint32(0)/12288 + 1, ^uint32(0)/13568 + 1, ^uint32(0)/14336 + 1, ^uint32(0)/16384 + 1, ^uint32(0)/18432 + 1, ^uint32(0)/19072 + 1, ^uint32(0)/20480 + 1, ^uint32(0)/21760 + 1, ^uint32(0)/24576 + 1, ^uint32(0)/27264 + 1, ^uint32(0)/28672 + 1, ^uint32(0)/32768 + 1}
 var size_to_class8 = [smallSizeMax/smallSizeDiv + 1]uint8{0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}
 var size_to_class128 = [(_MaxSmallSize-smallSizeMax)/largeSizeDiv + 1]uint8{32, 33, 34, 35, 36, 37, 37, 38, 38, 39, 39, 40, 40, 40, 41, 41, 41, 42, 43, 43, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 48, 48, 49, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67}
diff --git a/src/runtime/sizeof_test.go b/src/runtime/sizeof_test.go
index 736e848..bbbd1be 100644
--- a/src/runtime/sizeof_test.go
+++ b/src/runtime/sizeof_test.go
@@ -21,7 +21,7 @@
 		_32bit uintptr     // size on 32bit platforms
 		_64bit uintptr     // size on 64bit platforms
 	}{
-		{runtime.G{}, 216, 376},   // g, but exported for testing
+		{runtime.G{}, 236, 392},   // g, but exported for testing
 		{runtime.Sudog{}, 56, 88}, // sudog, but exported for testing
 	}
 
diff --git a/src/runtime/slice.go b/src/runtime/slice.go
index c0647d9..01cdcae 100644
--- a/src/runtime/slice.go
+++ b/src/runtime/slice.go
@@ -112,6 +112,43 @@
 	return makeslice(et, len, cap)
 }
 
+func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
+	if len == 0 {
+		return
+	}
+
+	if ptr == nil {
+		panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
+	}
+
+	mem, overflow := math.MulUintptr(et.size, uintptr(len))
+	if overflow || mem > maxAlloc || len < 0 {
+		panicunsafeslicelen()
+	}
+}
+
+func unsafeslice64(et *_type, ptr unsafe.Pointer, len64 int64) {
+	len := int(len64)
+	if int64(len) != len64 {
+		panicunsafeslicelen()
+	}
+	unsafeslice(et, ptr, len)
+}
+
+func unsafeslicecheckptr(et *_type, ptr unsafe.Pointer, len64 int64) {
+	unsafeslice64(et, ptr, len64)
+
+	// Check that underlying array doesn't straddle multiple heap objects.
+	// unsafeslice64 has already checked for overflow.
+	if checkptrStraddles(ptr, uintptr(len64)*et.size) {
+		throw("checkptr: unsafe.Slice result straddles multiple allocations")
+	}
+}
+
+func panicunsafeslicelen() {
+	panic(errorString("unsafe.Slice: len out of range"))
+}
+
 // growslice handles slice growth during append.
 // It is passed the slice element type, the old slice, and the desired new minimum capacity,
 // and it returns a new slice with at least that capacity, with the old data
diff --git a/src/runtime/stack.go b/src/runtime/stack.go
index 7b9dce5..6e0d157 100644
--- a/src/runtime/stack.go
+++ b/src/runtime/stack.go
@@ -5,6 +5,7 @@
 package runtime
 
 import (
+	"internal/abi"
 	"internal/cpu"
 	"runtime/internal/atomic"
 	"runtime/internal/sys"
@@ -91,6 +92,10 @@
 
 	// The stack guard is a pointer this many bytes above the
 	// bottom of the stack.
+	//
+	// The guard leaves enough room for one _StackSmall frame plus
+	// a _StackLimit chain of NOSPLIT calls plus _StackSystem
+	// bytes for the OS.
 	_StackGuard = 928*sys.StackGuardMultiplier + _StackSystem
 
 	// After a stack split check the SP is allowed to be this
@@ -122,16 +127,21 @@
 const (
 	uintptrMask = 1<<(8*sys.PtrSize) - 1
 
+	// The values below can be stored to g.stackguard0 to force
+	// the next stack check to fail.
+	// These are all larger than any real SP.
+
 	// Goroutine preemption request.
-	// Stored into g->stackguard0 to cause split stack check failure.
-	// Must be greater than any real sp.
 	// 0xfffffade in hex.
 	stackPreempt = uintptrMask & -1314
 
-	// Thread is forking.
-	// Stored into g->stackguard0 to cause split stack check failure.
-	// Must be greater than any real sp.
+	// Thread is forking. Causes a split stack check failure.
+	// 0xfffffb2e in hex.
 	stackFork = uintptrMask & -1234
+
+	// Force a stack movement. Used for debugging.
+	// 0xfffffeed in hex.
+	stackForceMove = uintptrMask & -275
 )
 
 // Global pool of spans that have free stacks.
@@ -651,7 +661,7 @@
 
 	// Adjust saved base pointer if there is one.
 	// TODO what about arm64 frame pointer adjustment?
-	if sys.ArchFamily == sys.AMD64 && frame.argp-frame.varp == 2*sys.RegSize {
+	if sys.ArchFamily == sys.AMD64 && frame.argp-frame.varp == 2*sys.PtrSize {
 		if stackDebug >= 3 {
 			print("      saved bp\n")
 		}
@@ -692,15 +702,15 @@
 				// we call into morestack.)
 				continue
 			}
-			t := obj.typ
-			gcdata := t.gcdata
+			ptrdata := obj.ptrdata()
+			gcdata := obj.gcdata
 			var s *mspan
-			if t.kind&kindGCProg != 0 {
+			if obj.useGCProg() {
 				// See comments in mgcmark.go:scanstack
-				s = materializeGCProg(t.ptrdata, gcdata)
+				s = materializeGCProg(ptrdata, gcdata)
 				gcdata = (*byte)(unsafe.Pointer(s.startAddr))
 			}
-			for i := uintptr(0); i < t.ptrdata; i += sys.PtrSize {
+			for i := uintptr(0); i < ptrdata; i += sys.PtrSize {
 				if *addb(gcdata, i/(8*sys.PtrSize))>>(i/sys.PtrSize&7)&1 != 0 {
 					adjustpointer(adjinfo, unsafe.Pointer(p+i))
 				}
@@ -1054,11 +1064,20 @@
 	// recheck the bounds on return.)
 	if f := findfunc(gp.sched.pc); f.valid() {
 		max := uintptr(funcMaxSPDelta(f))
-		for newsize-oldsize < max+_StackGuard {
+		needed := max + _StackGuard
+		used := gp.stack.hi - gp.sched.sp
+		for newsize-used < needed {
 			newsize *= 2
 		}
 	}
 
+	if gp.stackguard0 == stackForceMove {
+		// Forced stack movement used for debugging.
+		// Don't double the stack (or we may quickly run out
+		// if this is done repeatedly).
+		newsize = oldsize
+	}
+
 	if newsize > maxstacksize || newsize > maxstackceiling {
 		if maxstacksize < maxstackceiling {
 			print("runtime: goroutine stack exceeds ", maxstacksize, "-byte limit\n")
@@ -1089,7 +1108,7 @@
 }
 
 // adjust Gobuf as if it executed a call to fn
-// and then did an immediate gosave.
+// and then stopped before the first instruction in fn.
 func gostartcallfn(gobuf *gobuf, fv *funcval) {
 	var fn unsafe.Pointer
 	if fv != nil {
@@ -1245,7 +1264,7 @@
 	var minsize uintptr
 	switch sys.ArchFamily {
 	case sys.ARM64:
-		minsize = sys.SpAlign
+		minsize = sys.StackAlign
 	default:
 		minsize = sys.MinFrameSize
 	}
@@ -1301,29 +1320,70 @@
 	}
 
 	// stack objects.
-	p := funcdata(f, _FUNCDATA_StackObjects)
-	if p != nil {
-		n := *(*uintptr)(p)
-		p = add(p, sys.PtrSize)
-		*(*slice)(unsafe.Pointer(&objs)) = slice{array: noescape(p), len: int(n), cap: int(n)}
-		// Note: the noescape above is needed to keep
-		// getStackMap from "leaking param content:
-		// frame".  That leak propagates up to getgcmask, then
-		// GCMask, then verifyGCInfo, which converts the stack
-		// gcinfo tests into heap gcinfo tests :(
+	if GOARCH == "amd64" && unsafe.Sizeof(abi.RegArgs{}) > 0 && frame.argmap != nil {
+		// argmap is set when the function is reflect.makeFuncStub or reflect.methodValueCall.
+		// We don't actually use argmap in this case, but we need to fake the stack object
+		// record for these frames which contain an internal/abi.RegArgs at a hard-coded offset
+		// on amd64.
+		objs = methodValueCallFrameObjs
+	} else {
+		p := funcdata(f, _FUNCDATA_StackObjects)
+		if p != nil {
+			n := *(*uintptr)(p)
+			p = add(p, sys.PtrSize)
+			*(*slice)(unsafe.Pointer(&objs)) = slice{array: noescape(p), len: int(n), cap: int(n)}
+			// Note: the noescape above is needed to keep
+			// getStackMap from "leaking param content:
+			// frame".  That leak propagates up to getgcmask, then
+			// GCMask, then verifyGCInfo, which converts the stack
+			// gcinfo tests into heap gcinfo tests :(
+		}
 	}
 
 	return
 }
 
+var (
+	abiRegArgsEface          interface{} = abi.RegArgs{}
+	abiRegArgsType           *_type      = efaceOf(&abiRegArgsEface)._type
+	methodValueCallFrameObjs             = []stackObjectRecord{
+		{
+			off:      -int32(alignUp(abiRegArgsType.size, 8)), // It's always the highest address local.
+			size:     int32(abiRegArgsType.size),
+			_ptrdata: int32(abiRegArgsType.ptrdata),
+			gcdata:   abiRegArgsType.gcdata,
+		},
+	}
+)
+
+func init() {
+	if abiRegArgsType.kind&kindGCProg != 0 {
+		throw("abiRegArgsType needs GC Prog, update methodValueCallFrameObjs")
+	}
+}
+
 // A stackObjectRecord is generated by the compiler for each stack object in a stack frame.
-// This record must match the generator code in cmd/compile/internal/gc/ssa.go:emitStackObjects.
+// This record must match the generator code in cmd/compile/internal/liveness/plive.go:emitStackObjects.
 type stackObjectRecord struct {
 	// offset in frame
 	// if negative, offset from varp
 	// if non-negative, offset from argp
-	off int
-	typ *_type
+	off      int32
+	size     int32
+	_ptrdata int32 // ptrdata, or -ptrdata is GC prog is used
+	gcdata   *byte // pointer map or GC prog of the type
+}
+
+func (r *stackObjectRecord) useGCProg() bool {
+	return r._ptrdata < 0
+}
+
+func (r *stackObjectRecord) ptrdata() uintptr {
+	x := r._ptrdata
+	if x < 0 {
+		return uintptr(-x)
+	}
+	return uintptr(x)
 }
 
 // This is exported as ABI0 via linkname so obj can call it.
diff --git a/src/runtime/string.go b/src/runtime/string.go
index 9a601f0..d6030a1 100644
--- a/src/runtime/string.go
+++ b/src/runtime/string.go
@@ -55,20 +55,20 @@
 	return s
 }
 
-func concatstring2(buf *tmpBuf, a [2]string) string {
-	return concatstrings(buf, a[:])
+func concatstring2(buf *tmpBuf, a0, a1 string) string {
+	return concatstrings(buf, []string{a0, a1})
 }
 
-func concatstring3(buf *tmpBuf, a [3]string) string {
-	return concatstrings(buf, a[:])
+func concatstring3(buf *tmpBuf, a0, a1, a2 string) string {
+	return concatstrings(buf, []string{a0, a1, a2})
 }
 
-func concatstring4(buf *tmpBuf, a [4]string) string {
-	return concatstrings(buf, a[:])
+func concatstring4(buf *tmpBuf, a0, a1, a2, a3 string) string {
+	return concatstrings(buf, []string{a0, a1, a2, a3})
 }
 
-func concatstring5(buf *tmpBuf, a [5]string) string {
-	return concatstrings(buf, a[:])
+func concatstring5(buf *tmpBuf, a0, a1, a2, a3, a4 string) string {
+	return concatstrings(buf, []string{a0, a1, a2, a3, a4})
 }
 
 // slicebytetostring converts a byte slice to a string.
diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go
index 2ee2c74..16d7583 100644
--- a/src/runtime/stubs.go
+++ b/src/runtime/stubs.go
@@ -4,7 +4,11 @@
 
 package runtime
 
-import "unsafe"
+import (
+	"internal/abi"
+	"internal/goexperiment"
+	"unsafe"
+)
 
 // Should be a built-in for unsafe.Pointer?
 //go:nosplit
@@ -105,6 +109,9 @@
 //go:noescape
 func memmove(to, from unsafe.Pointer, n uintptr)
 
+// Outside assembly calls memmove. Make sure it has ABI wrappers.
+//go:linkname memmove
+
 //go:linkname reflect_memmove reflect.memmove
 func reflect_memmove(to, from unsafe.Pointer, n uintptr) {
 	memmove(to, from, n)
@@ -166,8 +173,8 @@
 // This in turn calls cgocallbackg, which is where we'll find
 // pointer-declared arguments.
 func cgocallback(fn, frame, ctxt uintptr)
+
 func gogo(buf *gobuf)
-func gosave(buf *gobuf)
 
 //go:noescape
 func jmpdefer(fv *funcval, argp uintptr)
@@ -175,19 +182,50 @@
 func setg(gg *g)
 func breakpoint()
 
-// reflectcall calls fn with a copy of the n argument bytes pointed at by arg.
-// After fn returns, reflectcall copies n-retoffset result bytes
-// back into arg+retoffset before returning. If copying result bytes back,
-// the caller should pass the argument frame type as argtype, so that
-// call can execute appropriate write barriers during the copy.
+// reflectcall calls fn with arguments described by stackArgs, stackArgsSize,
+// frameSize, and regArgs.
 //
-// Package reflect always passes a frame type. In package runtime,
-// Windows callbacks are the only use of this that copies results
-// back, and those cannot have pointers in their results, so runtime
-// passes nil for the frame type.
+// Arguments passed on the stack and space for return values passed on the stack
+// must be laid out at the space pointed to by stackArgs (with total length
+// stackArgsSize) according to the ABI.
+//
+// stackRetOffset must be some value <= stackArgsSize that indicates the
+// offset within stackArgs where the return value space begins.
+//
+// frameSize is the total size of the argument frame at stackArgs and must
+// therefore be >= stackArgsSize. It must include additional space for spilling
+// register arguments for stack growth and preemption.
+//
+// TODO(mknyszek): Once we don't need the additional spill space, remove frameSize,
+// since frameSize will be redundant with stackArgsSize.
+//
+// Arguments passed in registers must be laid out in regArgs according to the ABI.
+// regArgs will hold any return values passed in registers after the call.
+//
+// reflectcall copies stack arguments from stackArgs to the goroutine stack, and
+// then copies back stackArgsSize-stackRetOffset bytes back to the return space
+// in stackArgs once fn has completed. It also "unspills" argument registers from
+// regArgs before calling fn, and spills them back into regArgs immediately
+// following the call to fn. If there are results being returned on the stack,
+// the caller should pass the argument frame type as stackArgsType so that
+// reflectcall can execute appropriate write barriers during the copy.
+//
+// reflectcall expects regArgs.ReturnIsPtr to be populated indicating which
+// registers on the return path will contain Go pointers. It will then store
+// these pointers in regArgs.Ptrs such that they are visible to the GC.
+//
+// Package reflect passes a frame type. In package runtime, there is only
+// one call that copies results back, in callbackWrap in syscall_windows.go, and it
+// does NOT pass a frame type, meaning there are no write barriers invoked. See that
+// call site for justification.
 //
 // Package reflect accesses this symbol through a linkname.
-func reflectcall(argtype *_type, fn, arg unsafe.Pointer, argsize uint32, retoffset uint32)
+//
+// Arguments passed through to reflectcall do not escape. The type is used
+// only in a very limited callee of reflectcall, the stackArgs are copied, and
+// regArgs is only used in the reflectcall frame.
+//go:noescape
+func reflectcall(stackArgsType *_type, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
 
 func procyield(cycles uint32)
 
@@ -284,33 +322,34 @@
 
 // in asm_*.s
 // not called directly; definitions here supply type information for traceback.
-func call16(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call32(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call64(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call128(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call256(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call512(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call1024(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call2048(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call4096(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call8192(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call16384(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call32768(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call65536(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call131072(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call262144(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call524288(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call1048576(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call2097152(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call4194304(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call8388608(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call16777216(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call33554432(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call67108864(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call134217728(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call268435456(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call536870912(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
-func call1073741824(typ, fn, arg unsafe.Pointer, n, retoffset uint32)
+// These must have the same signature (arg pointer map) as reflectcall.
+func call16(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call32(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call64(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call128(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call256(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call512(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call1024(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call2048(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call4096(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call8192(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call16384(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call32768(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call65536(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call131072(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call262144(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call524288(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call1048576(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call2097152(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call4194304(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call8388608(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call16777216(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call33554432(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call67108864(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call134217728(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call268435456(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call536870912(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call1073741824(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
 
 func systemstack_switch()
 
@@ -357,3 +396,37 @@
 
 // Called from linker-generated .initarray; declared for go vet; do NOT call from Go.
 func addmoduledata()
+
+// Injected by the signal handler for panicking signals.
+// Initializes any registers that have fixed meaning at calls but
+// are scratch in bodies and calls sigpanic.
+// On many platforms it just jumps to sigpanic.
+func sigpanic0()
+
+// intArgRegs is used by the various register assignment
+// algorithm implementations in the runtime. These include:.
+// - Finalizers (mfinal.go)
+// - Windows callbacks (syscall_windows.go)
+//
+// Both are stripped-down versions of the algorithm since they
+// only have to deal with a subset of cases (finalizers only
+// take a pointer or interface argument, Go Windows callbacks
+// don't support floating point).
+//
+// It should be modified with care and are generally only
+// modified when testing this package.
+//
+// It should never be set higher than its internal/abi
+// constant counterparts, because the system relies on a
+// structure that is at least large enough to hold the
+// registers the system supports.
+//
+// Currently it's set to zero because using the actual
+// constant will break every part of the toolchain that
+// uses finalizers or Windows callbacks to call functions
+// The value that is currently commented out there should be
+// the actual value once we're ready to use the register ABI
+// everywhere.
+//
+// Protected by finlock.
+var intArgRegs = abi.IntArgRegs * goexperiment.RegabiArgsInt
diff --git a/src/runtime/stubs2.go b/src/runtime/stubs2.go
index 85088b3..525b324 100644
--- a/src/runtime/stubs2.go
+++ b/src/runtime/stubs2.go
@@ -2,13 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !aix
-// +build !darwin
-// +build !js
-// +build !openbsd
-// +build !plan9
-// +build !solaris
-// +build !windows
+//go:build !aix && !darwin && !js && !openbsd && !plan9 && !solaris && !windows
+// +build !aix,!darwin,!js,!openbsd,!plan9,!solaris,!windows
 
 package runtime
 
@@ -23,6 +18,11 @@
 func exit(code int32)
 func usleep(usec uint32)
 
+//go:nosplit
+func usleep_no_g(usec uint32) {
+	usleep(usec)
+}
+
 // write calls the write system call.
 // It returns a non-negative number of bytes written or a negative errno value.
 //go:noescape
diff --git a/src/runtime/stubs3.go b/src/runtime/stubs3.go
index 1885d32..b895be4 100644
--- a/src/runtime/stubs3.go
+++ b/src/runtime/stubs3.go
@@ -2,12 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !aix
-// +build !darwin
-// +build !freebsd
-// +build !openbsd
-// +build !plan9
-// +build !solaris
+//go:build !aix && !darwin && !freebsd && !openbsd && !plan9 && !solaris
+// +build !aix,!darwin,!freebsd,!openbsd,!plan9,!solaris
 
 package runtime
 
diff --git a/src/runtime/stubs_386.go b/src/runtime/stubs_386.go
index 5108294..300f167 100644
--- a/src/runtime/stubs_386.go
+++ b/src/runtime/stubs_386.go
@@ -15,3 +15,6 @@
 // Called from assembly only; declared for go vet.
 func setldt(slot uintptr, base unsafe.Pointer, size uintptr)
 func emptyfunc()
+
+//go:noescape
+func asmcgocall_no_g(fn, arg unsafe.Pointer)
diff --git a/src/runtime/stubs_amd64.go b/src/runtime/stubs_amd64.go
index 8c14bc2..687a506 100644
--- a/src/runtime/stubs_amd64.go
+++ b/src/runtime/stubs_amd64.go
@@ -4,6 +4,8 @@
 
 package runtime
 
+import "unsafe"
+
 // Called from compiled code; declared for vet; do NOT call from Go.
 func gcWriteBarrierCX()
 func gcWriteBarrierDX()
@@ -35,3 +37,13 @@
 func retpolineR13()
 func retpolineR14()
 func retpolineR15()
+
+//go:noescape
+func asmcgocall_no_g(fn, arg unsafe.Pointer)
+
+// Used by reflectcall and the reflect package.
+//
+// Spills/loads arguments in registers to/from an internal/abi.RegArgs
+// respectively. Does not follow the Go ABI.
+func spillArgs()
+func unspillArgs()
diff --git a/src/runtime/stubs_arm.go b/src/runtime/stubs_arm.go
index c13bf16..52c3293 100644
--- a/src/runtime/stubs_arm.go
+++ b/src/runtime/stubs_arm.go
@@ -4,6 +4,8 @@
 
 package runtime
 
+import "unsafe"
+
 // Called from compiler-generated code; declared for go vet.
 func udiv()
 func _div()
@@ -18,3 +20,6 @@
 func emptyfunc()
 func _initcgo()
 func read_tls_fallback()
+
+//go:noescape
+func asmcgocall_no_g(fn, arg unsafe.Pointer)
diff --git a/src/runtime/stubs_arm64.go b/src/runtime/stubs_arm64.go
index 44c566e..f5e3bb4 100644
--- a/src/runtime/stubs_arm64.go
+++ b/src/runtime/stubs_arm64.go
@@ -4,6 +4,13 @@
 
 package runtime
 
+import "unsafe"
+
 // Called from assembly only; declared for go vet.
 func load_g()
 func save_g()
+
+//go:noescape
+func asmcgocall_no_g(fn, arg unsafe.Pointer)
+
+func emptyfunc()
diff --git a/src/runtime/stubs_linux.go b/src/runtime/stubs_linux.go
index e75fcf6..ba26700 100644
--- a/src/runtime/stubs_linux.go
+++ b/src/runtime/stubs_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux
 // +build linux
 
 package runtime
diff --git a/src/runtime/stubs_mips64x.go b/src/runtime/stubs_mips64x.go
index 4e62c1c..05a4d0d 100644
--- a/src/runtime/stubs_mips64x.go
+++ b/src/runtime/stubs_mips64x.go
@@ -2,10 +2,16 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 package runtime
 
+import "unsafe"
+
 // Called from assembly only; declared for go vet.
 func load_g()
 func save_g()
+
+//go:noescape
+func asmcgocall_no_g(fn, arg unsafe.Pointer)
diff --git a/src/runtime/stubs_mipsx.go b/src/runtime/stubs_mipsx.go
index 707b295..9bffb35 100644
--- a/src/runtime/stubs_mipsx.go
+++ b/src/runtime/stubs_mipsx.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 package runtime
diff --git a/src/runtime/stubs_nonlinux.go b/src/runtime/stubs_nonlinux.go
index e1ea05c..f9b9859 100644
--- a/src/runtime/stubs_nonlinux.go
+++ b/src/runtime/stubs_nonlinux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !linux
 // +build !linux
 
 package runtime
diff --git a/src/runtime/stubs_ppc64.go b/src/runtime/stubs_ppc64.go
new file mode 100644
index 0000000..f692947
--- /dev/null
+++ b/src/runtime/stubs_ppc64.go
@@ -0,0 +1,16 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux
+// +build linux
+
+package runtime
+
+// Called from assembly only; declared for go vet.
+func load_g()
+func save_g()
+func reginit()
+
+//go:noescape
+func callCgoSigaction(sig uintptr, new, old *sigactiont) int32
diff --git a/src/runtime/stubs_ppc64le.go b/src/runtime/stubs_ppc64le.go
new file mode 100644
index 0000000..5b73313
--- /dev/null
+++ b/src/runtime/stubs_ppc64le.go
@@ -0,0 +1,10 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+// Called from assembly only; declared for go vet.
+func load_g()
+func save_g()
+func reginit()
diff --git a/src/runtime/stubs_ppc64x.go b/src/runtime/stubs_ppc64x.go
deleted file mode 100644
index 26f5bb2..0000000
--- a/src/runtime/stubs_ppc64x.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ppc64 ppc64le
-
-package runtime
-
-// Called from assembly only; declared for go vet.
-func load_g()
-func save_g()
-func reginit()
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index 09225fb..999300a 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -68,8 +68,15 @@
 	return f
 }
 
-// Next returns frame information for the next caller.
-// If more is false, there are no more callers (the Frame value is valid).
+// Next returns a Frame representing the next call frame in the slice
+// of PC values. If it has already returned all call frames, Next
+// returns a zero Frame.
+//
+// The more result indicates whether the next call to Next will return
+// a valid Frame. It does not necessarily indicate whether this call
+// returned one.
+//
+// See the Frames example for idiomatic usage.
 func (ci *Frames) Next() (frame Frame, more bool) {
 	for len(ci.frames) < 2 {
 		// Find the next frame.
@@ -185,7 +192,9 @@
 	var cache pcvalueCache
 	inltree := (*[1 << 20]inlinedCall)(inldata)
 	for {
-		ix := pcdatavalue(f, _PCDATA_InlTreeIndex, tracepc, &cache)
+		// Non-strict as cgoTraceback may have added bogus PCs
+		// with a valid funcInfo but invalid PCDATA.
+		ix := pcdatavalue1(f, _PCDATA_InlTreeIndex, tracepc, &cache, false)
 		if ix < 0 {
 			break
 		}
@@ -279,6 +288,7 @@
 	_FUNCDATA_StackObjects       = 2
 	_FUNCDATA_InlTree            = 3
 	_FUNCDATA_OpenCodedDeferInfo = 4
+	_FUNCDATA_ArgInfo            = 5
 
 	_ArgsSizeUnknown = -0x80000000
 )
@@ -310,30 +320,53 @@
 
 const (
 	funcID_normal funcID = iota // not a special function
-	funcID_runtime_main
+	funcID_abort
+	funcID_asmcgocall
+	funcID_asyncPreempt
+	funcID_cgocallback
+	funcID_debugCallV2
+	funcID_gcBgMarkWorker
 	funcID_goexit
+	funcID_gogo
+	funcID_gopanic
+	funcID_handleAsyncEvent
 	funcID_jmpdefer
 	funcID_mcall
 	funcID_morestack
 	funcID_mstart
-	funcID_rt0_go
-	funcID_asmcgocall
-	funcID_sigpanic
-	funcID_runfinq
-	funcID_gcBgMarkWorker
-	funcID_systemstack_switch
-	funcID_systemstack
-	funcID_cgocallback
-	funcID_gogo
-	funcID_externalthreadhandler
-	funcID_debugCallV1
-	funcID_gopanic
 	funcID_panicwrap
-	funcID_handleAsyncEvent
-	funcID_asyncPreempt
+	funcID_rt0_go
+	funcID_runfinq
+	funcID_runtime_main
+	funcID_sigpanic
+	funcID_systemstack
+	funcID_systemstack_switch
 	funcID_wrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.)
 )
 
+// A FuncFlag holds bits about a function.
+// This list must match the list in cmd/internal/objabi/funcid.go.
+type funcFlag uint8
+
+const (
+	// TOPFRAME indicates a function that appears at the top of its stack.
+	// The traceback routine stop at such a function and consider that a
+	// successful, complete traversal of the stack.
+	// Examples of TOPFRAME functions include goexit, which appears
+	// at the top of a user goroutine stack, and mstart, which appears
+	// at the top of a system goroutine stack.
+	funcFlag_TOPFRAME funcFlag = 1 << iota
+
+	// SPWRITE indicates a function that writes an arbitrary value to SP
+	// (any write other than adding or subtracting a constant amount).
+	// The traceback routines cannot encode such changes into the
+	// pcsp tables, so the function traceback cannot safely unwind past
+	// SPWRITE functions. Stopping at an SPWRITE function is considered
+	// to be an incomplete unwinding of the stack. In certain contexts
+	// (in particular garbage collector stack scans) that is a fatal error.
+	funcFlag_SPWRITE
+)
+
 // pcHeader holds data used by the pclntab lookups.
 type pcHeader struct {
 	magic          uint32  // 0xFFFFFFFA
@@ -536,7 +569,11 @@
 	// Check that the pclntab's format is valid.
 	hdr := datap.pcHeader
 	if hdr.magic != 0xfffffffa || hdr.pad1 != 0 || hdr.pad2 != 0 || hdr.minLC != sys.PCQuantum || hdr.ptrSize != sys.PtrSize {
-		println("runtime: function symbol table header:", hex(hdr.magic), hex(hdr.pad1), hex(hdr.pad2), hex(hdr.minLC), hex(hdr.ptrSize))
+		print("runtime: function symbol table header:", hex(hdr.magic), hex(hdr.pad1), hex(hdr.pad2), hex(hdr.minLC), hex(hdr.ptrSize))
+		if datap.pluginpath != "" {
+			print(", plugin:", datap.pluginpath)
+		}
+		println()
 		throw("invalid function symbol table\n")
 	}
 
@@ -551,7 +588,11 @@
 			if i+1 < nftab {
 				f2name = funcname(f2)
 			}
-			println("function symbol table not sorted by program counter:", hex(datap.ftab[i].entry), funcname(f1), ">", hex(datap.ftab[i+1].entry), f2name)
+			print("function symbol table not sorted by program counter:", hex(datap.ftab[i].entry), funcname(f1), ">", hex(datap.ftab[i+1].entry), f2name)
+			if datap.pluginpath != "" {
+				print(", plugin:", datap.pluginpath)
+			}
+			println()
 			for j := 0; j <= i; j++ {
 				print("\t", hex(datap.ftab[j].entry), " ", funcname(funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[j].funcoff])), datap}), "\n")
 			}
@@ -646,6 +687,12 @@
 	return file, int(line32)
 }
 
+// findmoduledatap looks up the moduledata for a PC.
+//
+// It is nosplit because it's part of the isgoexception
+// implementation.
+//
+//go:nosplit
 func findmoduledatap(pc uintptr) *moduledata {
 	for datap := &firstmoduledata; datap != nil; datap = datap.next {
 		if datap.minpc <= pc && pc < datap.maxpc {
@@ -668,6 +715,12 @@
 	return (*Func)(unsafe.Pointer(f._func))
 }
 
+// findfunc looks up function metadata for a PC.
+//
+// It is nosplit because it's part of the isgoexception
+// implementation.
+//
+//go:nosplit
 func findfunc(pc uintptr) funcInfo {
 	datap := findmoduledatap(pc)
 	if datap == nil {
diff --git a/src/runtime/sys_aix_ppc64.s b/src/runtime/sys_aix_ppc64.s
index a56d043..c171c19 100644
--- a/src/runtime/sys_aix_ppc64.s
+++ b/src/runtime/sys_aix_ppc64.s
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix
-// +build ppc64 ppc64le
-
 //
 // System calls and other sys.stuff for ppc64, Aix
 //
diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go
index 4a3f2fc..0f91685 100644
--- a/src/runtime/sys_darwin.go
+++ b/src/runtime/sys_darwin.go
@@ -4,7 +4,10 @@
 
 package runtime
 
-import "unsafe"
+import (
+	"internal/abi"
+	"unsafe"
+)
 
 // The X versions of syscall expect the libc call to return a 64-bit result.
 // Otherwise (the non-X version) expects a 32-bit result.
@@ -17,7 +20,7 @@
 //go:cgo_unsafe_args
 func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
 	entersyscall()
-	libcCall(unsafe.Pointer(funcPC(syscall)), unsafe.Pointer(&fn))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&fn))
 	exitsyscall()
 	return
 }
@@ -27,8 +30,8 @@
 //go:nosplit
 //go:cgo_unsafe_args
 func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
-	entersyscallblock()
-	libcCall(unsafe.Pointer(funcPC(syscallX)), unsafe.Pointer(&fn))
+	entersyscall()
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallX)), unsafe.Pointer(&fn))
 	exitsyscall()
 	return
 }
@@ -39,7 +42,7 @@
 //go:cgo_unsafe_args
 func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
 	entersyscall()
-	libcCall(unsafe.Pointer(funcPC(syscall6)), unsafe.Pointer(&fn))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&fn))
 	exitsyscall()
 	return
 }
@@ -50,7 +53,7 @@
 //go:cgo_unsafe_args
 func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
 	entersyscall()
-	libcCall(unsafe.Pointer(funcPC(syscall6X)), unsafe.Pointer(&fn))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6X)), unsafe.Pointer(&fn))
 	exitsyscall()
 	return
 }
@@ -61,7 +64,7 @@
 //go:cgo_unsafe_args
 func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
 	entersyscall()
-	libcCall(unsafe.Pointer(funcPC(syscallPtr)), unsafe.Pointer(&fn))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallPtr)), unsafe.Pointer(&fn))
 	exitsyscall()
 	return
 }
@@ -71,7 +74,7 @@
 //go:nosplit
 //go:cgo_unsafe_args
 func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
-	libcCall(unsafe.Pointer(funcPC(syscall)), unsafe.Pointer(&fn))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&fn))
 	return
 }
 
@@ -79,7 +82,7 @@
 //go:nosplit
 //go:cgo_unsafe_args
 func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
-	libcCall(unsafe.Pointer(funcPC(syscall6)), unsafe.Pointer(&fn))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&fn))
 	return
 }
 
@@ -90,7 +93,7 @@
 //go:cgo_unsafe_args
 func crypto_x509_syscall(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1 uintptr) {
 	entersyscall()
-	libcCall(unsafe.Pointer(funcPC(syscallNoErr)), unsafe.Pointer(&fn))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallNoErr)), unsafe.Pointer(&fn))
 	exitsyscall()
 	return
 }
@@ -102,42 +105,42 @@
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_attr_init(attr *pthreadattr) int32 {
-	return libcCall(unsafe.Pointer(funcPC(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
 }
 func pthread_attr_init_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_attr_getstacksize(attr *pthreadattr, size *uintptr) int32 {
-	return libcCall(unsafe.Pointer(funcPC(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
 }
 func pthread_attr_getstacksize_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_attr_setdetachstate(attr *pthreadattr, state int) int32 {
-	return libcCall(unsafe.Pointer(funcPC(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
 }
 func pthread_attr_setdetachstate_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_create(attr *pthreadattr, start uintptr, arg unsafe.Pointer) int32 {
-	return libcCall(unsafe.Pointer(funcPC(pthread_create_trampoline)), unsafe.Pointer(&attr))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_create_trampoline)), unsafe.Pointer(&attr))
 }
 func pthread_create_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func raise(sig uint32) {
-	libcCall(unsafe.Pointer(funcPC(raise_trampoline)), unsafe.Pointer(&sig))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(raise_trampoline)), unsafe.Pointer(&sig))
 }
 func raise_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_self() (t pthread) {
-	libcCall(unsafe.Pointer(funcPC(pthread_self_trampoline)), unsafe.Pointer(&t))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_self_trampoline)), unsafe.Pointer(&t))
 	return
 }
 func pthread_self_trampoline()
@@ -145,7 +148,7 @@
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_kill(t pthread, sig uint32) {
-	libcCall(unsafe.Pointer(funcPC(pthread_kill_trampoline)), unsafe.Pointer(&t))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_kill_trampoline)), unsafe.Pointer(&t))
 	return
 }
 func pthread_kill_trampoline()
@@ -163,7 +166,7 @@
 		ret1            unsafe.Pointer
 		ret2            int
 	}{addr, n, prot, flags, fd, off, nil, 0}
-	libcCall(unsafe.Pointer(funcPC(mmap_trampoline)), unsafe.Pointer(&args))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(mmap_trampoline)), unsafe.Pointer(&args))
 	return args.ret1, args.ret2
 }
 func mmap_trampoline()
@@ -171,34 +174,34 @@
 //go:nosplit
 //go:cgo_unsafe_args
 func munmap(addr unsafe.Pointer, n uintptr) {
-	libcCall(unsafe.Pointer(funcPC(munmap_trampoline)), unsafe.Pointer(&addr))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(munmap_trampoline)), unsafe.Pointer(&addr))
 }
 func munmap_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
-	libcCall(unsafe.Pointer(funcPC(madvise_trampoline)), unsafe.Pointer(&addr))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(madvise_trampoline)), unsafe.Pointer(&addr))
 }
 func madvise_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func mlock(addr unsafe.Pointer, n uintptr) {
-	libcCall(unsafe.Pointer(funcPC(mlock_trampoline)), unsafe.Pointer(&addr))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(mlock_trampoline)), unsafe.Pointer(&addr))
 }
 func mlock_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func read(fd int32, p unsafe.Pointer, n int32) int32 {
-	return libcCall(unsafe.Pointer(funcPC(read_trampoline)), unsafe.Pointer(&fd))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(read_trampoline)), unsafe.Pointer(&fd))
 }
 func read_trampoline()
 
 func pipe() (r, w int32, errno int32) {
 	var p [2]int32
-	errno = libcCall(unsafe.Pointer(funcPC(pipe_trampoline)), noescape(unsafe.Pointer(&p)))
+	errno = libcCall(unsafe.Pointer(abi.FuncPCABI0(pipe_trampoline)), noescape(unsafe.Pointer(&p)))
 	return p[0], p[1], errno
 }
 func pipe_trampoline()
@@ -206,7 +209,7 @@
 //go:nosplit
 //go:cgo_unsafe_args
 func closefd(fd int32) int32 {
-	return libcCall(unsafe.Pointer(funcPC(close_trampoline)), unsafe.Pointer(&fd))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(close_trampoline)), unsafe.Pointer(&fd))
 }
 func close_trampoline()
 
@@ -216,28 +219,34 @@
 // This is exported via linkname to assembly in runtime/cgo.
 //go:linkname exit
 func exit(code int32) {
-	libcCall(unsafe.Pointer(funcPC(exit_trampoline)), unsafe.Pointer(&code))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(exit_trampoline)), unsafe.Pointer(&code))
 }
 func exit_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func usleep(usec uint32) {
-	libcCall(unsafe.Pointer(funcPC(usleep_trampoline)), unsafe.Pointer(&usec))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec))
 }
 func usleep_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
+func usleep_no_g(usec uint32) {
+	asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec))
+}
+
+//go:nosplit
+//go:cgo_unsafe_args
 func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
-	return libcCall(unsafe.Pointer(funcPC(write_trampoline)), unsafe.Pointer(&fd))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(write_trampoline)), unsafe.Pointer(&fd))
 }
 func write_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func open(name *byte, mode, perm int32) (ret int32) {
-	return libcCall(unsafe.Pointer(funcPC(open_trampoline)), unsafe.Pointer(&name))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(open_trampoline)), unsafe.Pointer(&name))
 }
 func open_trampoline()
 
@@ -248,7 +257,7 @@
 		t            int64  // raw timer
 		numer, denom uint32 // conversion factors. nanoseconds = t * numer / denom.
 	}
-	libcCall(unsafe.Pointer(funcPC(nanotime_trampoline)), unsafe.Pointer(&r))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(nanotime_trampoline)), unsafe.Pointer(&r))
 	// Note: Apple seems unconcerned about overflow here. See
 	// https://developer.apple.com/library/content/qa/qa1398/_index.html
 	// Note also, numer == denom == 1 is common.
@@ -265,9 +274,9 @@
 
 //go:nosplit
 //go:cgo_unsafe_args
-func walltime1() (int64, int32) {
+func walltime() (int64, int32) {
 	var t timespec
-	libcCall(unsafe.Pointer(funcPC(walltime_trampoline)), unsafe.Pointer(&t))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(walltime_trampoline)), unsafe.Pointer(&t))
 	return t.tv_sec, int32(t.tv_nsec)
 }
 func walltime_trampoline()
@@ -275,14 +284,14 @@
 //go:nosplit
 //go:cgo_unsafe_args
 func sigaction(sig uint32, new *usigactiont, old *usigactiont) {
-	libcCall(unsafe.Pointer(funcPC(sigaction_trampoline)), unsafe.Pointer(&sig))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaction_trampoline)), unsafe.Pointer(&sig))
 }
 func sigaction_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func sigprocmask(how uint32, new *sigset, old *sigset) {
-	libcCall(unsafe.Pointer(funcPC(sigprocmask_trampoline)), unsafe.Pointer(&how))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(sigprocmask_trampoline)), unsafe.Pointer(&how))
 }
 func sigprocmask_trampoline()
 
@@ -296,49 +305,49 @@
 		// ref: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20140421/214296.html
 		new.ss_size = 32768
 	}
-	libcCall(unsafe.Pointer(funcPC(sigaltstack_trampoline)), unsafe.Pointer(&new))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaltstack_trampoline)), unsafe.Pointer(&new))
 }
 func sigaltstack_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func raiseproc(sig uint32) {
-	libcCall(unsafe.Pointer(funcPC(raiseproc_trampoline)), unsafe.Pointer(&sig))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(raiseproc_trampoline)), unsafe.Pointer(&sig))
 }
 func raiseproc_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func setitimer(mode int32, new, old *itimerval) {
-	libcCall(unsafe.Pointer(funcPC(setitimer_trampoline)), unsafe.Pointer(&mode))
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(setitimer_trampoline)), unsafe.Pointer(&mode))
 }
 func setitimer_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func sysctl(mib *uint32, miblen uint32, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32 {
-	return libcCall(unsafe.Pointer(funcPC(sysctl_trampoline)), unsafe.Pointer(&mib))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctl_trampoline)), unsafe.Pointer(&mib))
 }
 func sysctl_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func sysctlbyname(name *byte, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32 {
-	return libcCall(unsafe.Pointer(funcPC(sysctlbyname_trampoline)), unsafe.Pointer(&name))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctlbyname_trampoline)), unsafe.Pointer(&name))
 }
 func sysctlbyname_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func fcntl(fd, cmd, arg int32) int32 {
-	return libcCall(unsafe.Pointer(funcPC(fcntl_trampoline)), unsafe.Pointer(&fd))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(fcntl_trampoline)), unsafe.Pointer(&fd))
 }
 func fcntl_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func kqueue() int32 {
-	v := libcCall(unsafe.Pointer(funcPC(kqueue_trampoline)), nil)
+	v := libcCall(unsafe.Pointer(abi.FuncPCABI0(kqueue_trampoline)), nil)
 	return v
 }
 func kqueue_trampoline()
@@ -346,56 +355,56 @@
 //go:nosplit
 //go:cgo_unsafe_args
 func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 {
-	return libcCall(unsafe.Pointer(funcPC(kevent_trampoline)), unsafe.Pointer(&kq))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(kevent_trampoline)), unsafe.Pointer(&kq))
 }
 func kevent_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_mutex_init(m *pthreadmutex, attr *pthreadmutexattr) int32 {
-	return libcCall(unsafe.Pointer(funcPC(pthread_mutex_init_trampoline)), unsafe.Pointer(&m))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_init_trampoline)), unsafe.Pointer(&m))
 }
 func pthread_mutex_init_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_mutex_lock(m *pthreadmutex) int32 {
-	return libcCall(unsafe.Pointer(funcPC(pthread_mutex_lock_trampoline)), unsafe.Pointer(&m))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_lock_trampoline)), unsafe.Pointer(&m))
 }
 func pthread_mutex_lock_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_mutex_unlock(m *pthreadmutex) int32 {
-	return libcCall(unsafe.Pointer(funcPC(pthread_mutex_unlock_trampoline)), unsafe.Pointer(&m))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_unlock_trampoline)), unsafe.Pointer(&m))
 }
 func pthread_mutex_unlock_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_cond_init(c *pthreadcond, attr *pthreadcondattr) int32 {
-	return libcCall(unsafe.Pointer(funcPC(pthread_cond_init_trampoline)), unsafe.Pointer(&c))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_init_trampoline)), unsafe.Pointer(&c))
 }
 func pthread_cond_init_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_cond_wait(c *pthreadcond, m *pthreadmutex) int32 {
-	return libcCall(unsafe.Pointer(funcPC(pthread_cond_wait_trampoline)), unsafe.Pointer(&c))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_wait_trampoline)), unsafe.Pointer(&c))
 }
 func pthread_cond_wait_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_cond_timedwait_relative_np(c *pthreadcond, m *pthreadmutex, t *timespec) int32 {
-	return libcCall(unsafe.Pointer(funcPC(pthread_cond_timedwait_relative_np_trampoline)), unsafe.Pointer(&c))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_timedwait_relative_np_trampoline)), unsafe.Pointer(&c))
 }
 func pthread_cond_timedwait_relative_np_trampoline()
 
 //go:nosplit
 //go:cgo_unsafe_args
 func pthread_cond_signal(c *pthreadcond) int32 {
-	return libcCall(unsafe.Pointer(funcPC(pthread_cond_signal_trampoline)), unsafe.Pointer(&c))
+	return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_signal_trampoline)), unsafe.Pointer(&c))
 }
 func pthread_cond_signal_trampoline()
 
diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s
index 630fb5d..3bd027f 100644
--- a/src/runtime/sys_darwin_amd64.s
+++ b/src/runtime/sys_darwin_amd64.s
@@ -9,6 +9,7 @@
 #include "go_asm.h"
 #include "go_tls.h"
 #include "textflag.h"
+#include "cgo/abi_amd64.h"
 
 #define CLOCK_REALTIME		0
 
@@ -212,36 +213,21 @@
 
 // This is the function registered during sigaction and is invoked when
 // a signal is received. It just redirects to the Go function sigtrampgo.
+// Called using C ABI.
 TEXT runtime·sigtramp(SB),NOSPLIT,$0
-	// This runs on the signal stack, so we have lots of stack available.
-	// We allocate our own stack space, because if we tell the linker
-	// how much we're using, the NOSPLIT check fails.
-	PUSHQ	BP
-	MOVQ	SP, BP
-	SUBQ	$64, SP
-
-	// Save callee-save registers.
-	MOVQ	BX, 24(SP)
-	MOVQ	R12, 32(SP)
-	MOVQ	R13, 40(SP)
-	MOVQ	R14, 48(SP)
-	MOVQ	R15, 56(SP)
+	// Transition from C ABI to Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
 
 	// Call into the Go signal handler
-	MOVL	DI, 0(SP)  // sig
-	MOVQ	SI, 8(SP)  // info
-	MOVQ	DX, 16(SP) // ctx
-	CALL runtime·sigtrampgo(SB)
+	NOP	SP		// disable vet stack checking
+	ADJSP	$24
+	MOVL	DI, 0(SP)	// sig
+	MOVQ	SI, 8(SP)	// info
+	MOVQ	DX, 16(SP)	// ctx
+	CALL	·sigtrampgo(SB)
+	ADJSP	$-24
 
-	// Restore callee-save registers.
-	MOVQ	24(SP), BX
-	MOVQ	32(SP), R12
-	MOVQ	40(SP), R13
-	MOVQ	48(SP), R14
-	MOVQ	56(SP), R15
-
-	MOVQ	BP, SP
-	POPQ	BP
+	POP_REGS_HOST_TO_ABI0()
 	RET
 
 // Used instead of sigtramp in programs that use cgo.
@@ -436,13 +422,8 @@
 	// DI points to the m.
 	// We are already on m's g0 stack.
 
-	// Save callee-save registers.
-	SUBQ	$40, SP
-	MOVQ	BX, 0(SP)
-	MOVQ	R12, 8(SP)
-	MOVQ	R13, 16(SP)
-	MOVQ	R14, 24(SP)
-	MOVQ	R15, 32(SP)
+	// Transition from C ABI to Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
 
 	MOVQ	m_g0(DI), DX // g
 
@@ -450,24 +431,14 @@
 	// See cmd/link/internal/ld/sym.go:computeTLSOffset.
 	MOVQ	DX, 0x30(GS)
 
-	// Someday the convention will be D is always cleared.
-	CLD
-
 	CALL	runtime·mstart(SB)
 
-	// Restore callee-save registers.
-	MOVQ	0(SP), BX
-	MOVQ	8(SP), R12
-	MOVQ	16(SP), R13
-	MOVQ	24(SP), R14
-	MOVQ	32(SP), R15
+	POP_REGS_HOST_TO_ABI0()
 
 	// Go is all done with this OS thread.
 	// Tell pthread everything is ok (we never join with this thread, so
 	// the value here doesn't really matter).
 	XORL	AX, AX
-
-	ADDQ	$40, SP
 	RET
 
 // These trampolines help convert from Go calling convention to C calling convention.
diff --git a/src/runtime/sys_dragonfly_amd64.s b/src/runtime/sys_dragonfly_amd64.s
index 580633a..d57bc2a 100644
--- a/src/runtime/sys_dragonfly_amd64.s
+++ b/src/runtime/sys_dragonfly_amd64.s
@@ -9,6 +9,7 @@
 #include "go_asm.h"
 #include "go_tls.h"
 #include "textflag.h"
+#include "cgo/abi_amd64.h"
 
 TEXT runtime·sys_umtx_sleep(SB),NOSPLIT,$0
 	MOVQ addr+0(FP), DI		// arg 1 - ptr
@@ -123,6 +124,24 @@
 	MOVL	$0, errno+8(FP)
 	RET
 
+// func pipe2(flags int32) (r, w int32, errno int32)
+TEXT runtime·pipe2(SB),NOSPLIT,$0-20
+	MOVL	$0, DI
+	// dragonfly expects flags as the 2nd argument
+	MOVL	flags+0(FP), SI
+	MOVL	$538, AX
+	SYSCALL
+	JCC	pipe2ok
+	MOVL	$-1,r+8(FP)
+	MOVL	$-1,w+12(FP)
+	MOVL	AX, errno+16(FP)
+	RET
+pipe2ok:
+	MOVL	AX, r+8(FP)
+	MOVL	DX, w+12(FP)
+	MOVL	$0, errno+16(FP)
+	RET
+
 TEXT runtime·write1(SB),NOSPLIT,$-8
 	MOVQ	fd+0(FP), DI		// arg 1 fd
 	MOVQ	p+8(FP), SI		// arg 2 buf
@@ -165,8 +184,8 @@
 	SYSCALL
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB), NOSPLIT, $32
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB), NOSPLIT, $32
 	MOVL	$232, AX // clock_gettime
 	MOVQ	$0, DI  	// CLOCK_REALTIME
 	LEAQ	8(SP), SI
@@ -217,28 +236,21 @@
 	POPQ	BP
 	RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$72
-	// Save callee-saved C registers, since the caller may be a C signal handler.
-	MOVQ	BX,  bx-8(SP)
-	MOVQ	BP,  bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
-	MOVQ	R12, r12-24(SP)
-	MOVQ	R13, r13-32(SP)
-	MOVQ	R14, r14-40(SP)
-	MOVQ	R15, r15-48(SP)
-	// We don't save mxcsr or the x87 control word because sigtrampgo doesn't
-	// modify them.
+// Called using C ABI.
+TEXT runtime·sigtramp(SB),NOSPLIT,$0
+	// Transition from C ABI to Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
 
-	MOVQ	DX, ctx-56(SP)
-	MOVQ	SI, info-64(SP)
-	MOVQ	DI, signum-72(SP)
-	CALL	runtime·sigtrampgo(SB)
+	// Call into the Go signal handler
+	NOP	SP		// disable vet stack checking
+	ADJSP	$24
+	MOVQ	DI, 0(SP)	// sig
+	MOVQ	SI, 8(SP)	// info
+	MOVQ	DX, 16(SP)	// ctx
+	CALL	·sigtrampgo(SB)
+	ADJSP	$-24
 
-	MOVQ	r15-48(SP), R15
-	MOVQ	r14-40(SP), R14
-	MOVQ	r13-32(SP), R13
-	MOVQ	r12-24(SP), R12
-	MOVQ	bp-16(SP),  BP
-	MOVQ	bx-8(SP),   BX
+	POP_REGS_HOST_TO_ABI0()
 	RET
 
 TEXT runtime·mmap(SB),NOSPLIT,$0
diff --git a/src/runtime/sys_freebsd_amd64.s b/src/runtime/sys_freebsd_amd64.s
index 07734b0..71a60ca 100644
--- a/src/runtime/sys_freebsd_amd64.s
+++ b/src/runtime/sys_freebsd_amd64.s
@@ -9,6 +9,7 @@
 #include "go_asm.h"
 #include "go_tls.h"
 #include "textflag.h"
+#include "cgo/abi_amd64.h"
 
 TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
 	MOVQ addr+0(FP), DI
@@ -237,28 +238,21 @@
 	POPQ	BP
 	RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$72
-	// Save callee-saved C registers, since the caller may be a C signal handler.
-	MOVQ	BX, bx-8(SP)
-	MOVQ	BP, bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
-	MOVQ	R12, r12-24(SP)
-	MOVQ	R13, r13-32(SP)
-	MOVQ	R14, r14-40(SP)
-	MOVQ	R15, r15-48(SP)
-	// We don't save mxcsr or the x87 control word because sigtrampgo doesn't
-	// modify them.
+// Called using C ABI.
+TEXT runtime·sigtramp(SB),NOSPLIT,$0
+	// Transition from C ABI to Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
 
-	MOVQ	DX, ctx-56(SP)
-	MOVQ	SI, info-64(SP)
-	MOVQ	DI, signum-72(SP)
-	CALL	runtime·sigtrampgo(SB)
+	// Call into the Go signal handler
+	NOP	SP		// disable vet stack checking
+        ADJSP   $24
+	MOVQ	DI, 0(SP)	// sig
+	MOVQ	SI, 8(SP)	// info
+	MOVQ	DX, 16(SP)	// ctx
+	CALL	·sigtrampgo(SB)
+	ADJSP	$-24
 
-	MOVQ	r15-48(SP), R15
-	MOVQ	r14-40(SP), R14
-	MOVQ	r13-32(SP), R13
-	MOVQ	r12-24(SP), R12
-	MOVQ	bp-16(SP),  BP
-	MOVQ	bx-8(SP),   BX
+        POP_REGS_HOST_TO_ABI0()
 	RET
 
 // Used instead of sigtramp in programs that use cgo.
diff --git a/src/runtime/sys_libc.go b/src/runtime/sys_libc.go
index 996c032..b1a9f8b 100644
--- a/src/runtime/sys_libc.go
+++ b/src/runtime/sys_libc.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin openbsd,amd64 openbsd,arm64
+//go:build darwin || (openbsd && !mips64)
+// +build darwin openbsd,!mips64
 
 package runtime
 
diff --git a/src/runtime/sys_linux_386.s b/src/runtime/sys_linux_386.s
index 1e3a834..3ae5a90 100644
--- a/src/runtime/sys_linux_386.s
+++ b/src/runtime/sys_linux_386.s
@@ -219,8 +219,8 @@
 	MOVL	AX, ret+12(FP)
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB), NOSPLIT, $8-12
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB), NOSPLIT, $8-12
 	// We don't know how much stack space the VDSO code will need,
 	// so switch to g0.
 
@@ -412,6 +412,7 @@
 	MOVL	AX, SP
 	RET
 
+// Called using C ABI.
 TEXT runtime·sigtramp(SB),NOSPLIT,$28
 	// Save callee-saved C registers, since the caller may be a C signal handler.
 	MOVL	BX, bx-4(SP)
@@ -421,11 +422,11 @@
 	// We don't save mxcsr or the x87 control word because sigtrampgo doesn't
 	// modify them.
 
-	MOVL	sig+0(FP), BX
+	MOVL	(28+4)(SP), BX
 	MOVL	BX, 0(SP)
-	MOVL	info+4(FP), BX
+	MOVL	(28+8)(SP), BX
 	MOVL	BX, 4(SP)
-	MOVL	ctx+8(FP), BX
+	MOVL	(28+12)(SP), BX
 	MOVL	BX, 8(SP)
 	CALL	runtime·sigtrampgo(SB)
 
diff --git a/src/runtime/sys_linux_amd64.s b/src/runtime/sys_linux_amd64.s
index 37cb8da..33cc670 100644
--- a/src/runtime/sys_linux_amd64.s
+++ b/src/runtime/sys_linux_amd64.s
@@ -9,6 +9,7 @@
 #include "go_asm.h"
 #include "go_tls.h"
 #include "textflag.h"
+#include "cgo/abi_amd64.h"
 
 #define AT_FDCWD -100
 
@@ -203,9 +204,8 @@
 	MOVL	AX, ret+24(FP)
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-// non-zero frame-size means bp is saved and restored
-TEXT runtime·walltime1(SB),NOSPLIT,$16-12
+// func nanotime1() int64
+TEXT runtime·nanotime1(SB),NOSPLIT,$16-8
 	// 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
@@ -215,69 +215,13 @@
 
 	MOVQ	SP, R12	// Save old SP; R12 unchanged by C code.
 
+#ifdef GOEXPERIMENT_regabig
+	MOVQ	g_m(R14), BX // BX unchanged by C code.
+#else
 	get_tls(CX)
 	MOVQ	g(CX), AX
 	MOVQ	g_m(AX), BX // BX unchanged by C code.
-
-	// Set vdsoPC and vdsoSP for SIGPROF traceback.
-	// Save the old values on stack and restore them on exit,
-	// so this function is reentrant.
-	MOVQ	m_vdsoPC(BX), CX
-	MOVQ	m_vdsoSP(BX), DX
-	MOVQ	CX, 0(SP)
-	MOVQ	DX, 8(SP)
-
-	LEAQ	sec+0(FP), DX
-	MOVQ	-8(DX), CX
-	MOVQ	CX, m_vdsoPC(BX)
-	MOVQ	DX, m_vdsoSP(BX)
-
-	CMPQ	AX, m_curg(BX)	// Only switch if on curg.
-	JNE	noswitch
-
-	MOVQ	m_g0(BX), 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
-
-	MOVL	$0, DI // CLOCK_REALTIME
-	LEAQ	0(SP), SI
-	MOVQ	runtime·vdsoClockgettimeSym(SB), AX
-	CMPQ	AX, $0
-	JEQ	fallback
-	CALL	AX
-ret:
-	MOVQ	0(SP), AX	// sec
-	MOVQ	8(SP), DX	// nsec
-	MOVQ	R12, SP		// Restore real SP
-	// Restore vdsoPC, vdsoSP
-	// We don't worry about being signaled between the two stores.
-	// If we are not in a signal handler, we'll restore vdsoSP to 0,
-	// and no one will care about vdsoPC. If we are in a signal handler,
-	// we cannot receive another signal.
-	MOVQ	8(SP), CX
-	MOVQ	CX, m_vdsoSP(BX)
-	MOVQ	0(SP), CX
-	MOVQ	CX, m_vdsoPC(BX)
-	MOVQ	AX, sec+0(FP)
-	MOVL	DX, nsec+8(FP)
-	RET
-fallback:
-	MOVQ	$SYS_clock_gettime, AX
-	SYSCALL
-	JMP ret
-
-// func nanotime1() int64
-TEXT runtime·nanotime1(SB),NOSPLIT,$16-8
-	// Switch to g0 stack. See comment above in runtime·walltime.
-
-	MOVQ	SP, R12	// Save old SP; R12 unchanged by C code.
-
-	get_tls(CX)
-	MOVQ	g(CX), AX
-	MOVQ	g_m(AX), BX // BX unchanged by C code.
+#endif
 
 	// Set vdsoPC and vdsoSP for SIGPROF traceback.
 	// Save the old values on stack and restore them on exit,
@@ -292,7 +236,11 @@
 	MOVQ	CX, m_vdsoPC(BX)
 	MOVQ	DX, m_vdsoSP(BX)
 
+#ifdef GOEXPERIMENT_regabig
+	CMPQ	R14, m_curg(BX)	// Only switch if on curg.
+#else
 	CMPQ	AX, m_curg(BX)	// Only switch if on curg.
+#endif
 	JNE	noswitch
 
 	MOVQ	m_g0(BX), DX
@@ -381,29 +329,21 @@
 	RET
 
 // Defined as ABIInternal since it does not use the stack-based Go ABI.
-TEXT runtime·sigtramp<ABIInternal>(SB),NOSPLIT,$72
-	// Save callee-saved C registers, since the caller may be a C signal handler.
-	MOVQ	BX,  bx-8(SP)
-	MOVQ	BP,  bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
-	MOVQ	R12, r12-24(SP)
-	MOVQ	R13, r13-32(SP)
-	MOVQ	R14, r14-40(SP)
-	MOVQ	R15, r15-48(SP)
-	// We don't save mxcsr or the x87 control word because sigtrampgo doesn't
-	// modify them.
+// Called using C ABI.
+TEXT runtime·sigtramp<ABIInternal>(SB),NOSPLIT,$0
+	// Transition from C ABI to Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
 
-	MOVQ	DX, ctx-56(SP)
-	MOVQ	SI, info-64(SP)
-	MOVQ	DI, signum-72(SP)
-	MOVQ	$runtime·sigtrampgo(SB), AX
-	CALL AX
+	// Call into the Go signal handler
+	NOP	SP		// disable vet stack checking
+        ADJSP   $24
+	MOVQ	DI, 0(SP)	// sig
+	MOVQ	SI, 8(SP)	// info
+	MOVQ	DX, 16(SP)	// ctx
+	CALL	·sigtrampgo(SB)
+	ADJSP	$-24
 
-	MOVQ	r15-48(SP), R15
-	MOVQ	r14-40(SP), R14
-	MOVQ	r13-32(SP), R13
-	MOVQ	r12-24(SP), R12
-	MOVQ	bp-16(SP),  BP
-	MOVQ	bx-8(SP),   BX
+        POP_REGS_HOST_TO_ABI0()
 	RET
 
 // Used instead of sigtramp in programs that use cgo.
@@ -632,10 +572,11 @@
 	get_tls(CX)
 	MOVQ	R13, g_m(R9)
 	MOVQ	R9, g(CX)
+	MOVQ	R9, R14 // set g register
 	CALL	runtime·stackcheck(SB)
 
 nog2:
-	// Call fn
+	// Call fn. This is the PC of an ABI0 function.
 	CALL	R12
 
 	// It shouldn't return. If it does, exit that thread.
diff --git a/src/runtime/sys_linux_arm.s b/src/runtime/sys_linux_arm.s
index 475f523..02a5d4a 100644
--- a/src/runtime/sys_linux_arm.s
+++ b/src/runtime/sys_linux_arm.s
@@ -242,7 +242,7 @@
 	MOVW	R0, ret+12(FP)
 	RET
 
-TEXT runtime·walltime1(SB),NOSPLIT,$8-12
+TEXT runtime·walltime(SB),NOSPLIT,$8-12
 	// We don't know how much stack space the VDSO code will need,
 	// so switch to g0.
 
diff --git a/src/runtime/sys_linux_arm64.s b/src/runtime/sys_linux_arm64.s
index 198a5ba..69ac160 100644
--- a/src/runtime/sys_linux_arm64.s
+++ b/src/runtime/sys_linux_arm64.s
@@ -206,8 +206,8 @@
 	MOVW	R0, ret+24(FP)
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB),NOSPLIT,$24-12
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB),NOSPLIT,$24-12
 	MOVD	RSP, R20	// R20 is unchanged by C code
 	MOVD	RSP, R1
 
diff --git a/src/runtime/sys_linux_mips64x.s b/src/runtime/sys_linux_mips64x.s
index c3e9f37..e18d291 100644
--- a/src/runtime/sys_linux_mips64x.s
+++ b/src/runtime/sys_linux_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips64 || mips64le)
 // +build linux
 // +build mips64 mips64le
 
@@ -213,8 +214,8 @@
 	MOVW	R2, ret+24(FP)
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB),NOSPLIT,$16-12
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB),NOSPLIT,$16-12
 	MOVV	R29, R16	// R16 is unchanged by C code
 	MOVV	R29, R1
 
@@ -319,7 +320,7 @@
 	BEQ	R25, fallback
 
 	JAL	(R25)
-	// see walltime1 for detail
+	// see walltime for detail
 	BEQ	R2, R0, finish
 	MOVV	R0, runtime·vdsoClockgettimeSym(SB)
 	MOVW	$1, R4 // CLOCK_MONOTONIC
diff --git a/src/runtime/sys_linux_mipsx.s b/src/runtime/sys_linux_mipsx.s
index fab2ab3..b3970be 100644
--- a/src/runtime/sys_linux_mipsx.s
+++ b/src/runtime/sys_linux_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips || mipsle)
 // +build linux
 // +build mips mipsle
 
@@ -218,8 +219,8 @@
 	MOVW	R2, ret+12(FP)
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB),NOSPLIT,$8-12
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB),NOSPLIT,$8-12
 	MOVW	$0, R4	// CLOCK_REALTIME
 	MOVW	$4(R29), R5
 	MOVW	$SYS_clock_gettime, R2
diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s
index fd69ee7..005fa4d 100644
--- a/src/runtime/sys_linux_ppc64x.s
+++ b/src/runtime/sys_linux_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (ppc64 || ppc64le)
 // +build linux
 // +build ppc64 ppc64le
 
@@ -184,8 +185,8 @@
 	MOVW	R3, ret+24(FP)
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB),NOSPLIT,$16-12
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB),NOSPLIT,$16-12
 	MOVD	R1, R15		// R15 is unchanged by C code
 	MOVD	g_m(g), R21	// R21 = m
 
@@ -215,15 +216,45 @@
 	MOVD	(g_sched+gobuf_sp)(R7), R1	// Set SP to g0 stack
 
 noswitch:
-	SUB	$16, R1			// Space for results
-	RLDICR	$0, R1, $59, R1		// Align for C code
+	SUB	$16, R1                 // Space for results
+	RLDICR	$0, R1, $59, R1         // Align for C code
 	MOVD	R12, CTR
 	MOVD	R1, R4
-	BL	(CTR)			// Call from VDSO
-	MOVD	$0, R0			// Restore R0
-	MOVD	0(R1), R3		// sec
-	MOVD	8(R1), R5		// nsec
-	MOVD	R15, R1			// Restore SP
+
+	// Store g on gsignal's stack, so if we receive a signal
+	// during VDSO code we can find the g.
+	// If we don't have a signal stack, we won't receive signal,
+	// so don't bother saving g.
+	// When using cgo, we already saved g on TLS, also don't save
+	// g here.
+	// Also don't save g if we are already on the signal stack.
+	// We won't get a nested signal.
+	MOVBZ	runtime·iscgo(SB), R22
+	CMP	R22, $0
+	BNE	nosaveg
+	MOVD	m_gsignal(R21), R22	// g.m.gsignal
+	CMP	R22, $0
+	BEQ	nosaveg
+
+	CMP	g, R22
+	BEQ	nosaveg
+	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
+	MOVD	g, (R22)
+
+	BL	(CTR)	// Call from VDSO
+
+	MOVD	$0, (R22)	// clear g slot, R22 is unchanged by C code
+
+	JMP	finish
+
+nosaveg:
+	BL	(CTR)	// Call from VDSO
+
+finish:
+	MOVD	$0, R0		// Restore R0
+	MOVD	0(R1), R3	// sec
+	MOVD	8(R1), R5	// nsec
+	MOVD	R15, R1		// Restore SP
 
 	// Restore vdsoPC, vdsoSP
 	// We don't worry about being signaled between the two stores.
@@ -235,7 +266,7 @@
 	MOVD	32(R1), R6
 	MOVD	R6, m_vdsoPC(R21)
 
-finish:
+return:
 	MOVD	R3, sec+0(FP)
 	MOVW	R5, nsec+8(FP)
 	RET
@@ -246,7 +277,7 @@
 	SYSCALL $SYS_clock_gettime
 	MOVD	32(R1), R3
 	MOVD	40(R1), R5
-	JMP	finish
+	JMP	return
 
 TEXT runtime·nanotime1(SB),NOSPLIT,$16-8
 	MOVD	$1, R3		// CLOCK_MONOTONIC
@@ -282,7 +313,37 @@
 	RLDICR	$0, R1, $59, R1		// Align for C code
 	MOVD	R12, CTR
 	MOVD	R1, R4
-	BL	(CTR)			// Call from VDSO
+
+	// Store g on gsignal's stack, so if we receive a signal
+	// during VDSO code we can find the g.
+	// If we don't have a signal stack, we won't receive signal,
+	// so don't bother saving g.
+	// When using cgo, we already saved g on TLS, also don't save
+	// g here.
+	// Also don't save g if we are already on the signal stack.
+	// We won't get a nested signal.
+	MOVBZ	runtime·iscgo(SB), R22
+	CMP	R22, $0
+	BNE	nosaveg
+	MOVD	m_gsignal(R21), R22	// g.m.gsignal
+	CMP	R22, $0
+	BEQ	nosaveg
+
+	CMP	g, R22
+	BEQ	nosaveg
+	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
+	MOVD	g, (R22)
+
+	BL	(CTR)	// Call from VDSO
+
+	MOVD	$0, (R22)	// clear g slot, R22 is unchanged by C code
+
+	JMP	finish
+
+nosaveg:
+	BL	(CTR)	// Call from VDSO
+
+finish:
 	MOVD	$0, R0			// Restore R0
 	MOVD	0(R1), R3		// sec
 	MOVD	8(R1), R5		// nsec
@@ -298,7 +359,7 @@
 	MOVD	32(R1), R6
 	MOVD	R6, m_vdsoPC(R21)
 
-finish:
+return:
 	// sec is in R3, nsec in R5
 	// return nsec in R3
 	MOVD	$1000000000, R4
@@ -313,7 +374,7 @@
 	SYSCALL $SYS_clock_gettime
 	MOVD	32(R1), R3
 	MOVD	40(R1), R5
-	JMP	finish
+	JMP	return
 
 TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
 	MOVW	how+0(FP), R3
@@ -336,6 +397,26 @@
 	MOVW	R3, ret+32(FP)
 	RET
 
+#ifdef GOARCH_ppc64le
+// Call the function stored in _cgo_sigaction using the GCC calling convention.
+TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0
+	MOVD    sig+0(FP), R3
+	MOVD    new+8(FP), R4
+	MOVD    old+16(FP), R5
+	MOVD     _cgo_sigaction(SB), R12
+	MOVD    R12, CTR                // R12 should contain the function address
+	MOVD    R1, R15                 // Save R1
+	MOVD    R2, 24(R1)              // Save R2
+	SUB     $48, R1                 // reserve 32 (frame) + 16 bytes for sp-8 where fp may be saved.
+	RLDICR  $0, R1, $59, R1         // Align to 16 bytes for C code
+	BL      (CTR)
+	XOR     R0, R0, R0              // Clear R0 as Go expects
+	MOVD    R15, R1                 // Restore R1
+	MOVD    24(R1), R2              // Restore R2
+	MOVW    R3, ret+24(FP)          // Return result
+	RET
+#endif
+
 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
 	MOVW	sig+8(FP), R3
 	MOVD	info+16(FP), R4
@@ -351,22 +432,104 @@
 
 #ifdef GOARCH_ppc64le
 // ppc64le doesn't need function descriptors
-TEXT runtime·sigtramp(SB),NOSPLIT,$64
+// Save callee-save registers in the case of signal forwarding.
+// Same as on ARM64 https://golang.org/issue/31827 .
+TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0
 #else
 // function descriptor for the real sigtramp
 TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0
 	DWORD	$sigtramp<>(SB)
 	DWORD	$0
 	DWORD	$0
-TEXT sigtramp<>(SB),NOSPLIT,$64
+TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0
 #endif
+	// Start with standard C stack frame layout and linkage.
+	MOVD    LR, R0
+	MOVD    R0, 16(R1) // Save LR in caller's frame.
+	MOVW    CR, R0     // Save CR in caller's frame
+	MOVD    R0, 8(R1)
+	// The stack must be acquired here and not
+	// in the automatic way based on stack size
+	// since that sequence clobbers R31 before it
+	// gets saved.
+	// We are being ultra safe here in saving the
+	// Vregs. The case where they might need to
+	// be saved is very unlikely.
+	MOVDU   R1, -544(R1)
+	MOVD    R14, 64(R1)
+	MOVD    R15, 72(R1)
+	MOVD    R16, 80(R1)
+	MOVD    R17, 88(R1)
+	MOVD    R18, 96(R1)
+	MOVD    R19, 104(R1)
+	MOVD    R20, 112(R1)
+	MOVD    R21, 120(R1)
+	MOVD    R22, 128(R1)
+	MOVD    R23, 136(R1)
+	MOVD    R24, 144(R1)
+	MOVD    R25, 152(R1)
+	MOVD    R26, 160(R1)
+	MOVD    R27, 168(R1)
+	MOVD    R28, 176(R1)
+	MOVD    R29, 184(R1)
+	MOVD    g, 192(R1) // R30
+	MOVD    R31, 200(R1)
+	FMOVD   F14, 208(R1)
+	FMOVD   F15, 216(R1)
+	FMOVD   F16, 224(R1)
+	FMOVD   F17, 232(R1)
+	FMOVD   F18, 240(R1)
+	FMOVD   F19, 248(R1)
+	FMOVD   F20, 256(R1)
+	FMOVD   F21, 264(R1)
+	FMOVD   F22, 272(R1)
+	FMOVD   F23, 280(R1)
+	FMOVD   F24, 288(R1)
+	FMOVD   F25, 296(R1)
+	FMOVD   F26, 304(R1)
+	FMOVD   F27, 312(R1)
+	FMOVD   F28, 320(R1)
+	FMOVD   F29, 328(R1)
+	FMOVD   F30, 336(R1)
+	FMOVD   F31, 344(R1)
+	// Save V regs
+	// STXVD2X and LXVD2X used since
+	// we aren't sure of alignment.
+	// Endianness doesn't matter
+	// if we are just loading and
+	// storing values.
+	MOVD	$352, R7 // V20
+	STXVD2X VS52, (R7)(R1)
+	ADD	$16, R7 // V21 368
+	STXVD2X VS53, (R7)(R1)
+	ADD	$16, R7 // V22 384
+	STXVD2X VS54, (R7)(R1)
+	ADD	$16, R7 // V23 400
+	STXVD2X VS55, (R7)(R1)
+	ADD	$16, R7 // V24 416
+	STXVD2X	VS56, (R7)(R1)
+	ADD	$16, R7 // V25 432
+	STXVD2X	VS57, (R7)(R1)
+	ADD	$16, R7 // V26 448
+	STXVD2X VS58, (R7)(R1)
+	ADD	$16, R7 // V27 464
+	STXVD2X VS59, (R7)(R1)
+	ADD	$16, R7 // V28 480
+	STXVD2X VS60, (R7)(R1)
+	ADD	$16, R7 // V29 496
+	STXVD2X VS61, (R7)(R1)
+	ADD	$16, R7 // V30 512
+	STXVD2X VS62, (R7)(R1)
+	ADD	$16, R7 // V31 528
+	STXVD2X VS63, (R7)(R1)
+
 	// initialize essential registers (just in case)
 	BL	runtime·reginit(SB)
 
 	// this might be called in external code context,
 	// where g is not set.
 	MOVBZ	runtime·iscgo(SB), R6
-	CMP 	R6, $0
+	CMP	R6, $0
 	BEQ	2(PC)
 	BL	runtime·load_g(SB)
 
@@ -376,7 +539,74 @@
 	MOVD	$runtime·sigtrampgo(SB), R12
 	MOVD	R12, CTR
 	BL	(CTR)
-	MOVD	24(R1), R2
+	MOVD	24(R1), R2 // Should this be here? Where is it saved?
+	// Starts at 64; FIXED_FRAME is 32
+	MOVD    64(R1), R14
+	MOVD    72(R1), R15
+	MOVD    80(R1), R16
+	MOVD    88(R1), R17
+	MOVD    96(R1), R18
+	MOVD    104(R1), R19
+	MOVD    112(R1), R20
+	MOVD    120(R1), R21
+	MOVD    128(R1), R22
+	MOVD    136(R1), R23
+	MOVD    144(R1), R24
+	MOVD    152(R1), R25
+	MOVD    160(R1), R26
+	MOVD    168(R1), R27
+	MOVD    176(R1), R28
+	MOVD    184(R1), R29
+	MOVD    192(R1), g // R30
+	MOVD    200(R1), R31
+	FMOVD   208(R1), F14
+	FMOVD   216(R1), F15
+	FMOVD   224(R1), F16
+	FMOVD   232(R1), F17
+	FMOVD   240(R1), F18
+	FMOVD   248(R1), F19
+	FMOVD   256(R1), F20
+	FMOVD   264(R1), F21
+	FMOVD   272(R1), F22
+	FMOVD   280(R1), F23
+	FMOVD   288(R1), F24
+	FMOVD   292(R1), F25
+	FMOVD   300(R1), F26
+	FMOVD   308(R1), F27
+	FMOVD   316(R1), F28
+	FMOVD   328(R1), F29
+	FMOVD   336(R1), F30
+	FMOVD   344(R1), F31
+	MOVD	$352, R7
+	LXVD2X	(R7)(R1), VS52
+	ADD	$16, R7 // 368 V21
+	LXVD2X	(R7)(R1), VS53
+	ADD	$16, R7 // 384 V22
+	LXVD2X	(R7)(R1), VS54
+	ADD	$16, R7 // 400 V23
+	LXVD2X	(R7)(R1), VS55
+	ADD	$16, R7 // 416 V24
+	LXVD2X	(R7)(R1), VS56
+	ADD	$16, R7 // 432 V25
+	LXVD2X	(R7)(R1), VS57
+	ADD	$16, R7 // 448 V26
+	LXVD2X	(R7)(R1), VS58
+	ADD	$16, R8 // 464 V27
+	LXVD2X	(R7)(R1), VS59
+	ADD	$16, R7 // 480 V28
+	LXVD2X	(R7)(R1), VS60
+	ADD	$16, R7 // 496 V29
+	LXVD2X	(R7)(R1), VS61
+	ADD	$16, R7 // 512 V30
+	LXVD2X	(R7)(R1), VS62
+	ADD	$16, R7 // 528 V31
+	LXVD2X	(R7)(R1), VS63
+	ADD	$544, R1
+	MOVD	8(R1), R0
+	MOVFL	R0, $0xff
+	MOVD	16(R1), R0
+	MOVD	R0, LR
+
 	RET
 
 #ifdef GOARCH_ppc64le
@@ -406,6 +636,7 @@
 
 	// Figure out if we are currently in a cgo call.
 	// If not, just do usual sigtramp.
+	// compared to ARM64 and others.
 	CMP	$0, g
 	BEQ	sigtrampnog // g == nil
 	MOVD	g_m(g), R6
diff --git a/src/runtime/sys_linux_riscv64.s b/src/runtime/sys_linux_riscv64.s
index 626ab39..2389f1c 100644
--- a/src/runtime/sys_linux_riscv64.s
+++ b/src/runtime/sys_linux_riscv64.s
@@ -219,8 +219,8 @@
 	MOVW	A0, ret+24(FP)
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB),NOSPLIT,$24-12
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB),NOSPLIT,$24-12
 	MOV	$0, A0 // CLOCK_REALTIME
 	MOV	$8(X2), A1
 	MOV	$SYS_clock_gettime, A7
diff --git a/src/runtime/sys_linux_s390x.s b/src/runtime/sys_linux_s390x.s
index c15a1d5..916dfad 100644
--- a/src/runtime/sys_linux_s390x.s
+++ b/src/runtime/sys_linux_s390x.s
@@ -194,8 +194,8 @@
 	MOVW	R2, ret+24(FP)
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB),NOSPLIT,$16
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB),NOSPLIT,$16
 	MOVW	$0, R2 // CLOCK_REALTIME
 	MOVD	$tp-16(SP), R3
 	MOVW	$SYS_clock_gettime, R1
diff --git a/src/runtime/sys_mips64x.go b/src/runtime/sys_mips64x.go
index cb429c3..842a4a7 100644
--- a/src/runtime/sys_mips64x.go
+++ b/src/runtime/sys_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 package runtime
diff --git a/src/runtime/sys_mipsx.go b/src/runtime/sys_mipsx.go
index 2819218..2038eb7 100644
--- a/src/runtime/sys_mipsx.go
+++ b/src/runtime/sys_mipsx.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 package runtime
diff --git a/src/runtime/sys_netbsd_386.s b/src/runtime/sys_netbsd_386.s
index d0c470c..8a33894 100644
--- a/src/runtime/sys_netbsd_386.s
+++ b/src/runtime/sys_netbsd_386.s
@@ -206,8 +206,8 @@
 	INT	$0x80
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB), NOSPLIT, $32
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB), NOSPLIT, $32
 	LEAL	12(SP), BX
 	MOVL	$CLOCK_REALTIME, 4(SP)	// arg 1 - clock_id
 	MOVL	BX, 8(SP)		// arg 2 - tp
@@ -376,6 +376,10 @@
 	MOVL	$0x1234, 0x1005
 	RET
 
+TEXT ·netbsdMstart(SB),NOSPLIT|TOPFRAME,$0
+	CALL	·netbsdMstart0(SB)
+	RET // not reached
+
 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
 	MOVL	$SYS___sigaltstack14, AX
 	MOVL	new+0(FP), BX
diff --git a/src/runtime/sys_netbsd_amd64.s b/src/runtime/sys_netbsd_amd64.s
index dc9bd12..02f5b4b 100644
--- a/src/runtime/sys_netbsd_amd64.s
+++ b/src/runtime/sys_netbsd_amd64.s
@@ -9,6 +9,7 @@
 #include "go_asm.h"
 #include "go_tls.h"
 #include "textflag.h"
+#include "cgo/abi_amd64.h"
 
 #define CLOCK_REALTIME		0
 #define CLOCK_MONOTONIC		3
@@ -70,7 +71,7 @@
 	MOVQ	R9, g(CX)
 	CALL	runtime·stackcheck(SB)
 
-	// Call fn
+	// Call fn. This is an ABI0 PC.
 	CALL	R12
 
 	// It shouldn't return. If it does, exit.
@@ -78,6 +79,10 @@
 	SYSCALL
 	JMP	-3(PC)			// keep exiting
 
+TEXT ·netbsdMstart(SB),NOSPLIT|TOPFRAME,$0
+	CALL	·netbsdMstart0(SB)
+	RET // not reached
+
 TEXT runtime·osyield(SB),NOSPLIT,$0
 	MOVL	$SYS_sched_yield, AX
 	SYSCALL
@@ -233,8 +238,8 @@
 	SYSCALL
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB), NOSPLIT, $32
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB), NOSPLIT, $32
 	MOVQ	$CLOCK_REALTIME, DI	// arg 1 - clock_id
 	LEAQ	8(SP), SI		// arg 2 - tp
 	MOVL	$SYS___clock_gettime50, AX
@@ -314,28 +319,21 @@
 	POPQ	BP
 	RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$72
-	// Save callee-saved C registers, since the caller may be a C signal handler.
-	MOVQ	BX,  bx-8(SP)
-	MOVQ	BP,  bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
-	MOVQ	R12, r12-24(SP)
-	MOVQ	R13, r13-32(SP)
-	MOVQ	R14, r14-40(SP)
-	MOVQ	R15, r15-48(SP)
-	// We don't save mxcsr or the x87 control word because sigtrampgo doesn't
-	// modify them.
+// Called using C ABI.
+TEXT runtime·sigtramp(SB),NOSPLIT,$0
+	// Transition from C ABI to Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
 
-	MOVQ	DX, ctx-56(SP)
-	MOVQ	SI, info-64(SP)
-	MOVQ	DI, signum-72(SP)
-	CALL	runtime·sigtrampgo(SB)
+	// Call into the Go signal handler
+	NOP	SP		// disable vet stack checking
+        ADJSP   $24
+	MOVQ	DI, 0(SP)	// sig
+	MOVQ	SI, 8(SP)	// info
+	MOVQ	DX, 16(SP)	// ctx
+	CALL	·sigtrampgo(SB)
+	ADJSP	$-24
 
-	MOVQ	r15-48(SP), R15
-	MOVQ	r14-40(SP), R14
-	MOVQ	r13-32(SP), R13
-	MOVQ	r12-24(SP), R12
-	MOVQ	bp-16(SP),  BP
-	MOVQ	bx-8(SP),   BX
+        POP_REGS_HOST_TO_ABI0()
 	RET
 
 TEXT runtime·mmap(SB),NOSPLIT,$0
diff --git a/src/runtime/sys_netbsd_arm.s b/src/runtime/sys_netbsd_arm.s
index 678dea5..3a763b2 100644
--- a/src/runtime/sys_netbsd_arm.s
+++ b/src/runtime/sys_netbsd_arm.s
@@ -177,6 +177,10 @@
 	MOVW R8, (R8)
 	RET
 
+TEXT ·netbsdMstart(SB),NOSPLIT|TOPFRAME,$0
+	BL ·netbsdMstart0(SB)
+	RET // not reached
+
 TEXT runtime·usleep(SB),NOSPLIT,$16
 	MOVW usec+0(FP), R0
 	CALL runtime·usplitR0(SB)
@@ -212,8 +216,8 @@
 	SWI $SYS___setitimer50
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB), NOSPLIT, $32
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB), NOSPLIT, $32
 	MOVW $0, R0	// CLOCK_REALTIME
 	MOVW $8(R13), R1
 	SWI $SYS___clock_gettime50
diff --git a/src/runtime/sys_netbsd_arm64.s b/src/runtime/sys_netbsd_arm64.s
index 4d9b054..2d0b894 100644
--- a/src/runtime/sys_netbsd_arm64.s
+++ b/src/runtime/sys_netbsd_arm64.s
@@ -76,6 +76,10 @@
 	MOVD	$0, R0  // crash (not reached)
 	MOVD	R0, (R8)
 
+TEXT ·netbsdMstart(SB),NOSPLIT|TOPFRAME,$0
+	CALL	·netbsdMstart0(SB)
+	RET // not reached
+
 TEXT runtime·osyield(SB),NOSPLIT,$0
 	SVC	$SYS_sched_yield
 	RET
@@ -220,8 +224,8 @@
 	SVC	$SYS___setitimer50
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB), NOSPLIT, $32
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB), NOSPLIT, $32
 	MOVW	$CLOCK_REALTIME, R0	// arg 1 - clock_id
 	MOVD	$8(RSP), R1		// arg 2 - tp
 	SVC	$SYS___clock_gettime50
diff --git a/src/runtime/sys_nonppc64x.go b/src/runtime/sys_nonppc64x.go
index 4409374..66821b1 100644
--- a/src/runtime/sys_nonppc64x.go
+++ b/src/runtime/sys_nonppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !ppc64 && !ppc64le
 // +build !ppc64,!ppc64le
 
 package runtime
diff --git a/src/runtime/sys_openbsd.go b/src/runtime/sys_openbsd.go
index fcddf4d..ab31495 100644
--- a/src/runtime/sys_openbsd.go
+++ b/src/runtime/sys_openbsd.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build openbsd,amd64 openbsd,arm64
+//go:build openbsd && !mips64
+// +build openbsd,!mips64
 
 package runtime
 
diff --git a/src/runtime/sys_openbsd1.go b/src/runtime/sys_openbsd1.go
index e288621..cb5d358 100644
--- a/src/runtime/sys_openbsd1.go
+++ b/src/runtime/sys_openbsd1.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build openbsd,amd64 openbsd,arm64
+//go:build openbsd && !mips64
+// +build openbsd,!mips64
 
 package runtime
 
@@ -22,11 +23,17 @@
 }
 func thrwakeup_trampoline()
 
+//go:nosplit
 func osyield() {
 	libcCall(unsafe.Pointer(funcPC(sched_yield_trampoline)), unsafe.Pointer(nil))
 }
 func sched_yield_trampoline()
 
+//go:nosplit
+func osyield_no_g() {
+	asmcgocall_no_g(unsafe.Pointer(funcPC(sched_yield_trampoline)), unsafe.Pointer(nil))
+}
+
 //go:cgo_import_dynamic libc_thrsleep __thrsleep "libc.so"
 //go:cgo_import_dynamic libc_thrwakeup __thrwakeup "libc.so"
 //go:cgo_import_dynamic libc_sched_yield sched_yield "libc.so"
diff --git a/src/runtime/sys_openbsd2.go b/src/runtime/sys_openbsd2.go
index 474e714..cd1a4e8 100644
--- a/src/runtime/sys_openbsd2.go
+++ b/src/runtime/sys_openbsd2.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build openbsd,amd64 openbsd,arm64
+//go:build openbsd && !mips64
+// +build openbsd,!mips64
 
 package runtime
 
@@ -130,6 +131,12 @@
 
 //go:nosplit
 //go:cgo_unsafe_args
+func usleep_no_g(usec uint32) {
+	asmcgocall_no_g(unsafe.Pointer(funcPC(usleep_trampoline)), unsafe.Pointer(&usec))
+}
+
+//go:nosplit
+//go:cgo_unsafe_args
 func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 {
 	return libcCall(unsafe.Pointer(funcPC(sysctl_trampoline)), unsafe.Pointer(&mib))
 }
@@ -155,7 +162,7 @@
 func clock_gettime_trampoline()
 
 //go:nosplit
-func walltime1() (int64, int32) {
+func walltime() (int64, int32) {
 	var ts timespec
 	args := struct {
 		clock_id int32
diff --git a/src/runtime/sys_openbsd3.go b/src/runtime/sys_openbsd3.go
index 4d4c88e..8d77a4b 100644
--- a/src/runtime/sys_openbsd3.go
+++ b/src/runtime/sys_openbsd3.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build openbsd,amd64 openbsd,arm64
+//go:build openbsd && !mips64
+// +build openbsd,!mips64
 
 package runtime
 
diff --git a/src/runtime/sys_openbsd_386.s b/src/runtime/sys_openbsd_386.s
index 24fbfd6..7830b61 100644
--- a/src/runtime/sys_openbsd_386.s
+++ b/src/runtime/sys_openbsd_386.s
@@ -3,7 +3,9 @@
 // license that can be found in the LICENSE file.
 //
 // System calls and other sys.stuff for 386, OpenBSD
-// /usr/src/sys/kern/syscalls.master for syscall numbers.
+// System calls are implemented in libc/libpthread, this file
+// contains trampolines that convert from Go to C calling convention.
+// Some direct system call implementations currently remain.
 //
 
 #include "go_asm.h"
@@ -12,221 +14,44 @@
 
 #define	CLOCK_MONOTONIC	$3
 
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$-4
-	MOVL	$1, AX
-	INT	$0x80
-	MOVL	$0xf1, 0xf1		// crash
+TEXT runtime·setldt(SB),NOSPLIT,$0
+	// Nothing to do, pthread already set thread-local storage up.
 	RET
 
-// func exitThread(wait *uint32)
-TEXT runtime·exitThread(SB),NOSPLIT,$0-4
-	MOVL	$302, AX		// sys___threxit
-	INT	$0x80
-	MOVL	$0xf1, 0xf1		// crash
-	JMP	0(PC)
+// mstart_stub is the first function executed on a new thread started by pthread_create.
+// It just does some low-level setup and then calls mstart.
+// Note: called with the C calling convention.
+TEXT runtime·mstart_stub(SB),NOSPLIT,$28
+	NOP	SP	// tell vet SP changed - stop checking offsets
 
-TEXT runtime·open(SB),NOSPLIT,$-4
-	MOVL	$5, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$-1, AX
-	MOVL	AX, ret+12(FP)
-	RET
+	// We are already on m's g0 stack.
 
-TEXT runtime·closefd(SB),NOSPLIT,$-4
-	MOVL	$6, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$-1, AX
-	MOVL	AX, ret+4(FP)
-	RET
+	// Save callee-save registers.
+	MOVL	BX, bx-4(SP)
+	MOVL	BP, bp-8(SP)
+	MOVL	SI, si-12(SP)
+	MOVL	DI, di-16(SP)
 
-TEXT runtime·read(SB),NOSPLIT,$-4
-	MOVL	$3, AX
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX			// caller expects negative errno
-	MOVL	AX, ret+12(FP)
-	RET
+	MOVL	32(SP), AX	// m
+	MOVL	m_g0(AX), DX
+	get_tls(CX)
+	MOVL	DX, g(CX)
 
-// func pipe() (r, w int32, errno int32)
-TEXT runtime·pipe(SB),NOSPLIT,$8-12
-	MOVL	$263, AX
-	LEAL	r+0(FP), BX
-	MOVL	BX, 4(SP)
-	INT	$0x80
-	MOVL	AX, errno+8(FP)
-	RET
+	CALL	runtime·mstart(SB)
 
-// func pipe2(flags int32) (r, w int32, errno int32)
-TEXT runtime·pipe2(SB),NOSPLIT,$12-16
-	MOVL	$101, AX
-	LEAL	r+4(FP), BX
-	MOVL	BX, 4(SP)
-	MOVL	flags+0(FP), BX
-	MOVL	BX, 8(SP)
-	INT	$0x80
-	MOVL	AX, errno+12(FP)
-	RET
+	// Restore callee-save registers.
+	MOVL	di-16(SP), DI
+	MOVL	si-12(SP), SI
+	MOVL	bp-8(SP),  BP
+	MOVL	bx-4(SP),  BX
 
-TEXT runtime·write1(SB),NOSPLIT,$-4
-	MOVL	$4, AX			// sys_write
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX			// caller expects negative errno
-	MOVL	AX, ret+12(FP)
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$24
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVL	AX, 12(SP)		// tv_sec - l32
-	MOVL	$0, 16(SP)		// tv_sec - h32
-	MOVL	$1000, AX
-	MULL	DX
-	MOVL	AX, 20(SP)		// tv_nsec
-
-	MOVL	$0, 0(SP)
-	LEAL	12(SP), AX
-	MOVL	AX, 4(SP)		// arg 1 - rqtp
-	MOVL	$0, 8(SP)		// arg 2 - rmtp
-	MOVL	$91, AX			// sys_nanosleep
-	INT	$0x80
-	RET
-
-TEXT runtime·getthrid(SB),NOSPLIT,$0-4
-	MOVL	$299, AX		// sys_getthrid
-	INT	$0x80
-	MOVL	AX, ret+0(FP)
-	RET
-
-TEXT runtime·thrkill(SB),NOSPLIT,$16-8
-	MOVL	$0, 0(SP)
-	MOVL	tid+0(FP), AX
-	MOVL	AX, 4(SP)		// arg 1 - tid
-	MOVL	sig+4(FP), AX
-	MOVL	AX, 8(SP)		// arg 2 - signum
-	MOVL	$0, 12(SP)		// arg 3 - tcb
-	MOVL	$119, AX		// sys_thrkill
-	INT	$0x80
-	RET
-
-TEXT runtime·raiseproc(SB),NOSPLIT,$12
-	MOVL	$20, AX			// sys_getpid
-	INT	$0x80
-	MOVL	$0, 0(SP)
-	MOVL	AX, 4(SP)		// arg 1 - pid
-	MOVL	sig+0(FP), AX
-	MOVL	AX, 8(SP)		// arg 2 - signum
-	MOVL	$122, AX		// sys_kill
-	INT	$0x80
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$36
-	LEAL	addr+0(FP), SI
-	LEAL	4(SP), DI
-	CLD
-	MOVSL				// arg 1 - addr
-	MOVSL				// arg 2 - len
-	MOVSL				// arg 3 - prot
-	MOVSL				// arg 4 - flags
-	MOVSL				// arg 5 - fd
+	// Go is all done with this OS thread.
+	// Tell pthread everything is ok (we never join with this thread, so
+	// the value here doesn't really matter).
 	MOVL	$0, AX
-	STOSL				// arg 6 - pad
-	MOVSL				// arg 7 - offset
-	MOVL	$0, AX			// top 32 bits of file offset
-	STOSL
-	MOVL	$197, AX		// sys_mmap
-	INT	$0x80
-	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
-	MOVL	$73, AX			// sys_munmap
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$-4
-	MOVL	$75, AX			// sys_madvise
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$-1, AX
-	MOVL	AX, ret+12(FP)
-	RET
-
-TEXT runtime·setitimer(SB),NOSPLIT,$-4
-	MOVL	$69, AX
-	INT	$0x80
-	RET
-
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB), NOSPLIT, $32
-	LEAL	12(SP), BX
-	MOVL	$0, 4(SP)		// arg 1 - clock_id
-	MOVL	BX, 8(SP)		// arg 2 - tp
-	MOVL	$87, AX			// sys_clock_gettime
-	INT	$0x80
-
-	MOVL	12(SP), AX		// sec - l32
-	MOVL	AX, sec_lo+0(FP)
-	MOVL	16(SP), AX		// sec - h32
-	MOVL	AX, sec_hi+4(FP)
-
-	MOVL	20(SP), BX		// nsec
-	MOVL	BX, nsec+8(FP)
-	RET
-
-// int64 nanotime1(void) so really
-// void nanotime1(int64 *nsec)
-TEXT runtime·nanotime1(SB),NOSPLIT,$32
-	LEAL	12(SP), BX
-	MOVL	CLOCK_MONOTONIC, 4(SP)	// arg 1 - clock_id
-	MOVL	BX, 8(SP)		// arg 2 - tp
-	MOVL	$87, AX			// sys_clock_gettime
-	INT	$0x80
-
-	MOVL    16(SP), CX		// sec - h32
-	IMULL   $1000000000, CX
-
-	MOVL    12(SP), AX		// sec - l32
-	MOVL    $1000000000, BX
-	MULL    BX			// result in dx:ax
-
-	MOVL	20(SP), BX		// nsec
-	ADDL	BX, AX
-	ADCL	CX, DX			// add high bits with carry
-
-	MOVL	AX, ret_lo+0(FP)
-	MOVL	DX, ret_hi+4(FP)
-	RET
-
-TEXT runtime·sigaction(SB),NOSPLIT,$-4
-	MOVL	$46, AX			// sys_sigaction
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·obsdsigprocmask(SB),NOSPLIT,$-4
-	MOVL	$48, AX			// sys_sigprocmask
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	MOVL	AX, ret+8(FP)
-	RET
-
-TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
+TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
 	MOVL	fn+0(FP), AX
 	MOVL	sig+4(FP), BX
 	MOVL	info+8(FP), CX
@@ -268,194 +93,876 @@
 	MOVL	bx-4(SP),  BX
 	RET
 
-// int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
-TEXT runtime·tfork(SB),NOSPLIT,$12
-
-	// Copy mp, gp and fn from the parent stack onto the child stack.
-	MOVL	param+0(FP), AX
-	MOVL	8(AX), CX		// tf_stack
-	SUBL	$16, CX
-	MOVL	CX, 8(AX)
-	MOVL	mm+8(FP), SI
-	MOVL	SI, 0(CX)
-	MOVL	gg+12(FP), SI
-	MOVL	SI, 4(CX)
-	MOVL	fn+16(FP), SI
-	MOVL	SI, 8(CX)
-	MOVL	$1234, 12(CX)
-
-	MOVL	$0, 0(SP)		// syscall gap
-	MOVL	param+0(FP), AX
-	MOVL	AX, 4(SP)		// arg 1 - param
-	MOVL	psize+4(FP), AX
-	MOVL	AX, 8(SP)		// arg 2 - psize
-	MOVL	$8, AX			// sys___tfork
-	INT	$0x80
-
-	// Return if tfork syscall failed.
-	JCC	4(PC)
-	NEGL	AX
-	MOVL	AX, ret+20(FP)
-	RET
-
-	// In parent, return.
-	CMPL	AX, $0
-	JEQ	3(PC)
-	MOVL	AX, ret+20(FP)
-	RET
-
-	// Paranoia: check that SP is as we expect.
-	MOVL	12(SP), BP
-	CMPL	BP, $1234
-	JEQ	2(PC)
-	INT	$3
-
-	// Reload registers.
-	MOVL	0(SP), BX		// m
-	MOVL	4(SP), DX		// g
-	MOVL	8(SP), SI		// fn
-
-	// Set FS to point at m->tls.
-	LEAL	m_tls(BX), BP
-	PUSHAL				// save registers
+// These trampolines help convert from Go calling convention to C calling convention.
+// They should be called with asmcgocall - note that while asmcgocall does
+// stack alignment, creation of a frame undoes it again.
+// A pointer to the arguments is passed on the stack.
+// A single int32 result is returned in AX.
+// (For more results, make an args/results structure.)
+TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
 	PUSHL	BP
-	CALL	set_tcb<>(SB)
-	POPL	AX
-	POPAL
-
-	// Now segment is established. Initialize m, g.
-	get_tls(AX)
-	MOVL	DX, g(AX)
-	MOVL	BX, g_m(DX)
-
-	CALL	runtime·stackcheck(SB)	// smashes AX, CX
-	MOVL	0(DX), DX		// paranoia; check they are not nil
-	MOVL	0(BX), BX
-
-	// More paranoia; check that stack splitting code works.
-	PUSHAL
-	CALL	runtime·emptyfunc(SB)
-	POPAL
-
-	// Call fn.
-	CALL	SI
-
-	// fn should never return.
-	MOVL	$0x1234, 0x1005
+	MOVL	SP, BP
+	SUBL	$4, SP
+	MOVL	12(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	AX, 0(SP)		// arg 1 - attr
+	CALL	libc_pthread_attr_init(SB)
+	MOVL	BP, SP
+	POPL	BP
 	RET
 
-TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
-	MOVL	$288, AX		// sys_sigaltstack
-	MOVL	new+0(FP), BX
-	MOVL	old+4(FP), CX
-	INT	$0x80
-	CMPL	AX, $0xfffff001
-	JLS	2(PC)
-	INT	$3
+TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$4, SP
+	MOVL	12(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	AX, 0(SP)		// arg 1 - attr
+	CALL	libc_pthread_attr_destroy(SB)
+	MOVL	BP, SP
+	POPL	BP
 	RET
 
-TEXT runtime·setldt(SB),NOSPLIT,$4
-	// Under OpenBSD we set the GS base instead of messing with the LDT.
-	MOVL	base+4(FP), AX
-	MOVL	AX, 0(SP)
-	CALL	set_tcb<>(SB)
+TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$8, SP
+	MOVL	16(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	AX, 0(SP)		// arg 1 - attr
+	MOVL	BX, 4(SP)		// arg 2 - size
+	CALL	libc_pthread_attr_getstacksize(SB)
+	MOVL	BP, SP
+	POPL	BP
 	RET
 
-TEXT set_tcb<>(SB),NOSPLIT,$8
-	// adjust for ELF: wants to use -4(GS) for g
-	MOVL	tlsbase+0(FP), CX
-	ADDL	$4, CX
-	MOVL	$0, 0(SP)		// syscall gap
-	MOVL	CX, 4(SP)		// arg 1 - tcb
-	MOVL	$329, AX		// sys___set_tcb
-	INT	$0x80
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
+TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$8, SP
+	MOVL	16(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	AX, 0(SP)		// arg 1 - attr
+	MOVL	BX, 4(SP)		// arg 2 - state
+	CALL	libc_pthread_attr_setdetachstate(SB)
+	MOVL	BP, SP
+	POPL	BP
 	RET
 
-TEXT runtime·osyield(SB),NOSPLIT,$-4
-	MOVL	$298, AX		// sys_sched_yield
-	INT	$0x80
+TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$20, SP
+	MOVL	28(SP), DX		// pointer to args
+	LEAL	16(SP), AX
+	MOVL	AX, 0(SP)		// arg 1 - &threadid (discarded)
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 4(SP)		// arg 2 - attr
+	MOVL	BX, 8(SP)		// arg 3 - start
+	MOVL	CX, 12(SP)		// arg 4 - arg
+	CALL	libc_pthread_create(SB)
+	MOVL	BP, SP
+	POPL	BP
 	RET
 
-TEXT runtime·thrsleep(SB),NOSPLIT,$-4
-	MOVL	$94, AX			// sys___thrsleep
-	INT	$0x80
-	MOVL	AX, ret+20(FP)
+TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$12, SP
+	MOVL	20(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	AX, 0(SP)		// arg 1 - tid
+	MOVL	BX, 4(SP)		// arg 2 - signal
+	MOVL	$0, 8(SP)		// arg 3 - tcb
+	CALL	libc_thrkill(SB)
+	MOVL	BP, SP
+	POPL	BP
 	RET
 
-TEXT runtime·thrwakeup(SB),NOSPLIT,$-4
-	MOVL	$301, AX		// sys___thrwakeup
-	INT	$0x80
-	MOVL	AX, ret+8(FP)
+TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$20, SP
+	MOVL	28(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 0(SP)		// arg 1 - id
+	MOVL	BX, 4(SP)		// arg 2 - clock_id
+	MOVL	CX, 8(SP)		// arg 3 - abstime
+	MOVL	12(DX), AX
+	MOVL	16(DX), BX
+	MOVL	AX, 12(SP)		// arg 4 - lock
+	MOVL	BX, 16(SP)		// arg 5 - abort
+	CALL	libc_thrsleep(SB)
+	MOVL	BP, SP
+	POPL	BP
 	RET
 
-TEXT runtime·sysctl(SB),NOSPLIT,$28
-	LEAL	mib+0(FP), SI
-	LEAL	4(SP), DI
-	CLD
-	MOVSL				// arg 1 - name
-	MOVSL				// arg 2 - namelen
-	MOVSL				// arg 3 - oldp
-	MOVSL				// arg 4 - oldlenp
-	MOVSL				// arg 5 - newp
-	MOVSL				// arg 6 - newlen
-	MOVL	$202, AX		// sys___sysctl
-	INT	$0x80
-	JCC	4(PC)
-	NEGL	AX
-	MOVL	AX, ret+24(FP)
+TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$8, SP
+	MOVL	16(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	AX, 0(SP)		// arg 1 - id
+	MOVL	BX, 4(SP)		// arg 2 - count
+	CALL	libc_thrwakeup(SB)
+	MOVL	BP, SP
+	POPL	BP
 	RET
+
+TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$4, SP
+	MOVL	12(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	AX, 0(SP)		// arg 1 - status
+	CALL	libc_exit(SB)
+	MOVL	$0xf1, 0xf1		// crash on failure
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	CALL	libc_getthrid(SB)
+	NOP	SP			// tell vet SP changed - stop checking offsets
+	MOVL	8(SP), DX		// pointer to return value
+	MOVL	AX, 0(DX)
+	POPL	BP
+	RET
+
+TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$8, SP
+	MOVL	16(SP), DX
+	MOVL	0(DX), BX
+	CALL	libc_getpid(SB)
+	MOVL	AX, 0(SP)		// arg 1 - pid
+	MOVL	BX, 4(SP)		// arg 2 - signal
+	CALL	libc_kill(SB)
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	CALL	libc_sched_yield(SB)
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$32, SP
+	MOVL	40(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 0(SP)		// arg 1 - addr
+	MOVL	BX, 4(SP)		// arg 2 - len
+	MOVL	CX, 8(SP)		// arg 3 - prot
+	MOVL	12(DX), AX
+	MOVL	16(DX), BX
+	MOVL	20(DX), CX
+	MOVL	AX, 12(SP)		// arg 4 - flags
+	MOVL	BX, 16(SP)		// arg 5 - fid
+	MOVL	$0, 20(SP)		// pad
+	MOVL	CX, 24(SP)		// arg 6 - offset (low 32 bits)
+	MOVL	$0, 28(SP)		// offset (high 32 bits)
+	CALL	libc_mmap(SB)
+	MOVL	$0, BX
+	CMPL	AX, $-1
+	JNE	ok
+	CALL	libc_errno(SB)
+	MOVL	(AX), BX
 	MOVL	$0, AX
-	MOVL	AX, ret+24(FP)
+ok:
+	MOVL	40(SP), DX
+	MOVL	AX, 24(DX)
+	MOVL	BX, 28(DX)
+	MOVL	BP, SP
+	POPL	BP
 	RET
 
-// int32 runtime·kqueue(void);
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVL	$269, AX
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	MOVL	AX, ret+0(FP)
+TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$8, SP
+	MOVL	16(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	AX, 0(SP)		// arg 1 - addr
+	MOVL	BX, 4(SP)		// arg 2 - len
+	CALL	libc_munmap(SB)
+	CMPL	AX, $-1
+	JNE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash on failure
+	MOVL	BP, SP
+	POPL	BP
 	RET
 
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
-TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVL	$72, AX			// sys_kevent
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	MOVL	AX, ret+24(FP)
+TEXT runtime·madvise_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$12, SP
+	MOVL	20(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 0(SP)		// arg 1 - addr
+	MOVL	BX, 4(SP)		// arg 2 - len
+	MOVL	CX, 8(SP)		// arg 3 - advice
+	CALL	libc_madvise(SB)
+	// ignore failure - maybe pages are locked
+	MOVL	BP, SP
+	POPL	BP
 	RET
 
-// int32 runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$32
-	MOVL	$92, AX			// sys_fcntl
-	// 0(SP) is where the caller PC would be; kernel skips it
-	MOVL	fd+0(FP), BX
-	MOVL	BX, 4(SP)	// fd
-	MOVL	$2, 8(SP)	// F_SETFD
-	MOVL	$1, 12(SP)	// FD_CLOEXEC
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
+TEXT runtime·open_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$16, SP
+	MOVL	24(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 0(SP)		// arg 1 - path
+	MOVL	BX, 4(SP)		// arg 2 - flags
+	MOVL	CX, 8(SP)		// arg 3 - mode
+	MOVL	$0, 12(SP)		// vararg
+	CALL	libc_open(SB)
+	MOVL	BP, SP
+	POPL	BP
 	RET
 
-// func runtime·setNonblock(fd int32)
-TEXT runtime·setNonblock(SB),NOSPLIT,$16-4
-	MOVL	$92, AX // fcntl
-	MOVL	fd+0(FP), BX // fd
-	MOVL	BX, 4(SP)
-	MOVL	$3, 8(SP) // F_GETFL
-	MOVL	$0, 12(SP)
-	INT	$0x80
-	MOVL	fd+0(FP), BX // fd
-	MOVL	BX, 4(SP)
-	MOVL	$4, 8(SP) // F_SETFL
-	ORL	$4, AX // O_NONBLOCK
-	MOVL	AX, 12(SP)
-	MOVL	$92, AX // fcntl
-	INT	$0x80
+TEXT runtime·close_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$4, SP
+	MOVL	12(SP), DX
+	MOVL	0(DX), AX
+	MOVL	AX, 0(SP)		// arg 1 - fd
+	CALL	libc_close(SB)
+	MOVL	BP, SP
+	POPL	BP
 	RET
 
-GLOBL runtime·tlsoffset(SB),NOPTR,$4
+TEXT runtime·read_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$12, SP
+	MOVL	20(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 0(SP)		// arg 1 - fd
+	MOVL	BX, 4(SP)		// arg 2 - buf
+	MOVL	CX, 8(SP)		// arg 3 - count
+	CALL	libc_read(SB)
+	CMPL	AX, $-1
+	JNE	noerr
+	CALL	libc_errno(SB)
+	MOVL	(AX), AX
+	NEGL	AX			// caller expects negative errno
+noerr:
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·write_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$12, SP
+	MOVL	20(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 0(SP)		// arg 1 - fd
+	MOVL	BX, 4(SP)		// arg 2 - buf
+	MOVL	CX, 8(SP)		// arg 3 - count
+	CALL	libc_write(SB)
+	CMPL	AX, $-1
+	JNE	noerr
+	CALL	libc_errno(SB)
+	MOVL	(AX), AX
+	NEGL	AX			// caller expects negative errno
+noerr:
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$8, SP
+	MOVL	16(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	AX, 0(SP)		// arg 1 - fds
+	MOVL	BX, 4(SP)		// arg 2 - flags
+	CALL	libc_pipe2(SB)
+	CMPL	AX, $-1
+	JNE	noerr
+	CALL	libc_errno(SB)
+	MOVL	(AX), AX
+	NEGL	AX			// caller expects negative errno
+noerr:
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$12, SP
+	MOVL	20(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 0(SP)		// arg 1 - which
+	MOVL	BX, 4(SP)		// arg 2 - new
+	MOVL	CX, 8(SP)		// arg 3 - old
+	CALL	libc_setitimer(SB)
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$4, SP
+	MOVL	12(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	AX, 0(SP)
+	CALL	libc_usleep(SB)
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$24, SP
+	MOVL	32(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 0(SP)		// arg 1 - name
+	MOVL	BX, 4(SP)		// arg 2 - namelen
+	MOVL	CX, 8(SP)		// arg 3 - old
+	MOVL	12(DX), AX
+	MOVL	16(DX), BX
+	MOVL	20(DX), CX
+	MOVL	AX, 12(SP)		// arg 4 - oldlenp
+	MOVL	BX, 16(SP)		// arg 5 - newp
+	MOVL	CX, 20(SP)		// arg 6 - newlen
+	CALL	libc_sysctl(SB)
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	CALL	libc_kqueue(SB)
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$24, SP
+	MOVL	32(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 0(SP)		// arg 1 - kq
+	MOVL	BX, 4(SP)		// arg 2 - keventt
+	MOVL	CX, 8(SP)		// arg 3 - nch
+	MOVL	12(DX), AX
+	MOVL	16(DX), BX
+	MOVL	20(DX), CX
+	MOVL	AX, 12(SP)		// arg 4 - ev
+	MOVL	BX, 16(SP)		// arg 5 - nev
+	MOVL	CX, 20(SP)		// arg 6 - ts
+	CALL	libc_kevent(SB)
+	CMPL	AX, $-1
+	JNE	noerr
+	CALL	libc_errno(SB)
+	MOVL	(AX), AX
+	NEGL	AX			// caller expects negative errno
+noerr:
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$8, SP
+	MOVL	16(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	AX, 0(SP)		// arg 1 - tp
+	MOVL	BX, 4(SP)		// arg 2 - clock_id
+	CALL	libc_clock_gettime(SB)
+	CMPL	AX, $-1
+	JNE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash on failure
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$16, SP
+	MOVL	24(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 0(SP)		// arg 1 - fd
+	MOVL	BX, 4(SP)		// arg 2 - cmd
+	MOVL	CX, 8(SP)		// arg 3 - arg
+	MOVL	$0, 12(SP)		// vararg
+	CALL	libc_fcntl(SB)
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$12, SP
+	MOVL	20(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 0(SP)		// arg 1 - sig
+	MOVL	BX, 4(SP)		// arg 2 - new
+	MOVL	CX, 8(SP)		// arg 3 - old
+	CALL	libc_sigaction(SB)
+	CMPL	AX, $-1
+	JNE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash on failure
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$12, SP
+	MOVL	20(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	8(DX), CX
+	MOVL	AX, 0(SP)		// arg 1 - how
+	MOVL	BX, 4(SP)		// arg 2 - new
+	MOVL	CX, 8(SP)		// arg 3 - old
+	CALL	libc_pthread_sigmask(SB)
+	CMPL	AX, $-1
+	JNE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash on failure
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	SUBL	$8, SP
+	MOVL	16(SP), DX		// pointer to args
+	MOVL	0(DX), AX
+	MOVL	4(DX), BX
+	MOVL	AX, 0(SP)		// arg 1 - new
+	MOVL	BX, 4(SP)		// arg 2 - old
+	CALL	libc_sigaltstack(SB)
+	CMPL	AX, $-1
+	JNE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash on failure
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+// syscall calls a function in libc on behalf of the syscall package.
+// syscall takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscall must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall expects a 32-bit result and tests for 32-bit -1
+// to decide there was an error.
+TEXT runtime·syscall(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+
+	SUBL	$12, SP
+	MOVL	20(SP), BX		// pointer to args
+
+	MOVL	(1*4)(BX), AX
+	MOVL	(2*4)(BX), CX
+	MOVL	(3*4)(BX), DX
+	MOVL	AX, (0*4)(SP)		// a1
+	MOVL	CX, (1*4)(SP)		// a2
+	MOVL	DX, (2*4)(SP)		// a3
+
+	MOVL	(0*4)(BX), AX		// fn
+	CALL	AX
+
+	MOVL	AX, (4*4)(BX)		// r1
+	MOVL	DX, (5*4)(BX)		// r2
+
+	// Standard libc functions return -1 on error and set errno.
+	CMPL	AX, $-1
+	JNE	ok
+
+	// Get error code from libc.
+	CALL	libc_errno(SB)
+	MOVL	(AX), AX
+	MOVW	AX, (6*4)(BX)		// err
+
+ok:
+	MOVL	$0, AX			// no error (it's ignored anyway)
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+// syscallX calls a function in libc on behalf of the syscall package.
+// syscallX takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscallX must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscallX is like syscall but expects a 64-bit result
+// and tests for 64-bit -1 to decide there was an error.
+TEXT runtime·syscallX(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+
+	SUBL	$12, SP
+	MOVL	20(SP), BX		// pointer to args
+
+	MOVL	(1*4)(BX), AX
+	MOVL	(2*4)(BX), CX
+	MOVL	(3*4)(BX), DX
+	MOVL	AX, (0*4)(SP)		// a1
+	MOVL	CX, (1*4)(SP)		// a2
+	MOVL	DX, (2*4)(SP)		// a3
+
+	MOVL	(0*4)(BX), AX		// fn
+	CALL	AX
+
+	MOVL	AX, (4*4)(BX)		// r1
+	MOVL	DX, (5*4)(BX)		// r2
+
+	// Standard libc functions return -1 on error and set errno.
+	CMPL	AX, $-1
+	JNE	ok
+	CMPL	DX, $-1
+	JNE	ok
+
+	// Get error code from libc.
+	CALL	libc_errno(SB)
+	MOVL	(AX), AX
+	MOVW	AX, (6*4)(BX)		// err
+
+ok:
+	MOVL	$0, AX			// no error (it's ignored anyway)
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+// syscall6 calls a function in libc on behalf of the syscall package.
+// syscall6 takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	a4    uintptr
+//	a5    uintptr
+//	a6    uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscall6 must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall6 expects a 32-bit result and tests for 32-bit -1
+// to decide there was an error.
+TEXT runtime·syscall6(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+
+	SUBL	$24, SP
+	MOVL	32(SP), BX		// pointer to args
+
+	MOVL	(1*4)(BX), AX
+	MOVL	(2*4)(BX), CX
+	MOVL	(3*4)(BX), DX
+	MOVL	AX, (0*4)(SP)		// a1
+	MOVL	CX, (1*4)(SP)		// a2
+	MOVL	DX, (2*4)(SP)		// a3
+	MOVL	(4*4)(BX), AX
+	MOVL	(5*4)(BX), CX
+	MOVL	(6*4)(BX), DX
+	MOVL	AX, (3*4)(SP)		// a4
+	MOVL	CX, (4*4)(SP)		// a5
+	MOVL	DX, (5*4)(SP)		// a6
+
+	MOVL	(0*4)(BX), AX		// fn
+	CALL	AX
+
+	MOVL	AX, (7*4)(BX)		// r1
+	MOVL	DX, (8*4)(BX)		// r2
+
+	// Standard libc functions return -1 on error and set errno.
+	CMPL	AX, $-1
+	JNE	ok
+
+	// Get error code from libc.
+	CALL	libc_errno(SB)
+	MOVL	(AX), AX
+	MOVW	AX, (9*4)(BX)		// err
+
+ok:
+	MOVL	$0, AX			// no error (it's ignored anyway)
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+// syscall6X calls a function in libc on behalf of the syscall package.
+// syscall6X takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	a4    uintptr
+//	a5    uintptr
+//	a6    uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscall6X must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall6X is like syscall6 but expects a 64-bit result
+// and tests for 64-bit -1 to decide there was an error.
+TEXT runtime·syscall6X(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+
+	SUBL	$24, SP
+	MOVL	32(SP), BX		// pointer to args
+
+	MOVL	(1*4)(BX), AX
+	MOVL	(2*4)(BX), CX
+	MOVL	(3*4)(BX), DX
+	MOVL	AX, (0*4)(SP)		// a1
+	MOVL	CX, (1*4)(SP)		// a2
+	MOVL	DX, (2*4)(SP)		// a3
+	MOVL	(4*4)(BX), AX
+	MOVL	(5*4)(BX), CX
+	MOVL	(6*4)(BX), DX
+	MOVL	AX, (3*4)(SP)		// a4
+	MOVL	CX, (4*4)(SP)		// a5
+	MOVL	DX, (5*4)(SP)		// a6
+
+	MOVL	(0*4)(BX), AX		// fn
+	CALL	AX
+
+	MOVL	AX, (7*4)(BX)		// r1
+	MOVL	DX, (8*4)(BX)		// r2
+
+	// Standard libc functions return -1 on error and set errno.
+	CMPL	AX, $-1
+	JNE	ok
+	CMPL	DX, $-1
+	JNE	ok
+
+	// Get error code from libc.
+	CALL	libc_errno(SB)
+	MOVL	(AX), AX
+	MOVW	AX, (9*4)(BX)		// err
+
+ok:
+	MOVL	$0, AX			// no error (it's ignored anyway)
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+// syscall10 calls a function in libc on behalf of the syscall package.
+// syscall10 takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	a4    uintptr
+//	a5    uintptr
+//	a6    uintptr
+//	a7    uintptr
+//	a8    uintptr
+//	a9    uintptr
+//	a10   uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscall10 must be called on the g0 stack with the
+// C calling convention (use libcCall).
+TEXT runtime·syscall10(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+
+	SUBL	$40, SP
+	MOVL	48(SP), BX		// pointer to args
+
+	MOVL	(1*4)(BX), AX
+	MOVL	(2*4)(BX), CX
+	MOVL	(3*4)(BX), DX
+	MOVL	AX, (0*4)(SP)		// a1
+	MOVL	CX, (1*4)(SP)		// a2
+	MOVL	DX, (2*4)(SP)		// a3
+	MOVL	(4*4)(BX), AX
+	MOVL	(5*4)(BX), CX
+	MOVL	(6*4)(BX), DX
+	MOVL	AX, (3*4)(SP)		// a4
+	MOVL	CX, (4*4)(SP)		// a5
+	MOVL	DX, (5*4)(SP)		// a6
+	MOVL	(7*4)(BX), AX
+	MOVL	(8*4)(BX), CX
+	MOVL	(9*4)(BX), DX
+	MOVL	AX, (6*4)(SP)		// a7
+	MOVL	CX, (7*4)(SP)		// a8
+	MOVL	DX, (8*4)(SP)		// a9
+	MOVL	(10*4)(BX), AX
+	MOVL	AX, (9*4)(SP)		// a10
+
+	MOVL	(0*4)(BX), AX		// fn
+	CALL	AX
+
+	MOVL	AX, (11*4)(BX)		// r1
+	MOVL	DX, (12*4)(BX)		// r2
+
+	// Standard libc functions return -1 on error and set errno.
+	CMPL	AX, $-1
+	JNE	ok
+
+	// Get error code from libc.
+	CALL	libc_errno(SB)
+	MOVL	(AX), AX
+	MOVW	AX, (13*4)(BX)		// err
+
+ok:
+	MOVL	$0, AX			// no error (it's ignored anyway)
+	MOVL	BP, SP
+	POPL	BP
+	RET
+
+// syscall10X calls a function in libc on behalf of the syscall package.
+// syscall10X takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	a4    uintptr
+//	a5    uintptr
+//	a6    uintptr
+//	a7    uintptr
+//	a8    uintptr
+//	a9    uintptr
+//	a10   uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscall10X must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall10X is like syscall9 but expects a 64-bit result
+// and tests for 64-bit -1 to decide there was an error.
+TEXT runtime·syscall10X(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+
+	SUBL	$40, SP
+	MOVL	48(SP), BX		// pointer to args
+
+	MOVL	(1*4)(BX), AX
+	MOVL	(2*4)(BX), CX
+	MOVL	(3*4)(BX), DX
+	MOVL	AX, (0*4)(SP)		// a1
+	MOVL	CX, (1*4)(SP)		// a2
+	MOVL	DX, (2*4)(SP)		// a3
+	MOVL	(4*4)(BX), AX
+	MOVL	(5*4)(BX), CX
+	MOVL	(6*4)(BX), DX
+	MOVL	AX, (3*4)(SP)		// a4
+	MOVL	CX, (4*4)(SP)		// a5
+	MOVL	DX, (5*4)(SP)		// a6
+	MOVL	(7*4)(BX), AX
+	MOVL	(8*4)(BX), CX
+	MOVL	(9*4)(BX), DX
+	MOVL	AX, (6*4)(SP)		// a7
+	MOVL	CX, (7*4)(SP)		// a8
+	MOVL	DX, (8*4)(SP)		// a9
+	MOVL	(10*4)(BX), AX
+	MOVL	AX, (9*4)(SP)		// a10
+
+	MOVL	(0*4)(BX), AX		// fn
+	CALL	AX
+
+	MOVL	AX, (11*4)(BX)		// r1
+	MOVL	DX, (12*4)(BX)		// r2
+
+	// Standard libc functions return -1 on error and set errno.
+	CMPL	AX, $-1
+	JNE	ok
+	CMPL	DX, $-1
+	JNE	ok
+
+	// Get error code from libc.
+	CALL	libc_errno(SB)
+	MOVL	(AX), AX
+	MOVW	AX, (13*4)(BX)		// err
+
+ok:
+	MOVL	$0, AX			// no error (it's ignored anyway)
+	MOVL	BP, SP
+	POPL	BP
+	RET
diff --git a/src/runtime/sys_openbsd_amd64.s b/src/runtime/sys_openbsd_amd64.s
index b3a76b5..522e98c 100644
--- a/src/runtime/sys_openbsd_amd64.s
+++ b/src/runtime/sys_openbsd_amd64.s
@@ -11,6 +11,7 @@
 #include "go_asm.h"
 #include "go_tls.h"
 #include "textflag.h"
+#include "cgo/abi_amd64.h"
 
 #define CLOCK_MONOTONIC	$3
 
@@ -25,39 +26,22 @@
 	// DI points to the m.
 	// We are already on m's g0 stack.
 
-	// Save callee-save registers.
-	SUBQ	$48, SP
-	MOVQ	BX, 0(SP)
-	MOVQ	BP, 8(SP)
-	MOVQ	R12, 16(SP)
-	MOVQ	R13, 24(SP)
-	MOVQ	R14, 32(SP)
-	MOVQ	R15, 40(SP)
+	// Transition from C ABI to Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
 
 	// Load g and save to TLS entry.
 	// See cmd/link/internal/ld/sym.go:computeTLSOffset.
 	MOVQ	m_g0(DI), DX // g
 	MOVQ	DX, -8(FS)
 
-	// Someday the convention will be D is always cleared.
-	CLD
-
 	CALL	runtime·mstart(SB)
 
-	// Restore callee-save registers.
-	MOVQ	0(SP), BX
-	MOVQ	8(SP), BP
-	MOVQ	16(SP), R12
-	MOVQ	24(SP), R13
-	MOVQ	32(SP), R14
-	MOVQ	40(SP), R15
+	POP_REGS_HOST_TO_ABI0()
 
 	// Go is all done with this OS thread.
 	// Tell pthread everything is ok (we never join with this thread, so
 	// the value here doesn't really matter).
 	XORL	AX, AX
-
-	ADDQ	$48, SP
 	RET
 
 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
@@ -73,28 +57,21 @@
 	POPQ	BP
 	RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$72
-	// Save callee-saved C registers, since the caller may be a C signal handler.
-	MOVQ	BX,  bx-8(SP)
-	MOVQ	BP,  bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
-	MOVQ	R12, r12-24(SP)
-	MOVQ	R13, r13-32(SP)
-	MOVQ	R14, r14-40(SP)
-	MOVQ	R15, r15-48(SP)
-	// We don't save mxcsr or the x87 control word because sigtrampgo doesn't
-	// modify them.
+// Called using C ABI.
+TEXT runtime·sigtramp<ABIInternal>(SB),NOSPLIT,$0
+	// Transition from C ABI to Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
 
-	MOVQ	DX, ctx-56(SP)
-	MOVQ	SI, info-64(SP)
-	MOVQ	DI, signum-72(SP)
-	CALL	runtime·sigtrampgo(SB)
+	// Call into the Go signal handler
+	NOP	SP		// disable vet stack checking
+        ADJSP   $24
+	MOVQ	DI, 0(SP)	// sig
+	MOVQ	SI, 8(SP)	// info
+	MOVQ	DX, 16(SP)	// ctx
+	CALL	·sigtrampgo(SB)
+	ADJSP	$-24
 
-	MOVQ	r15-48(SP), R15
-	MOVQ	r14-40(SP), R14
-	MOVQ	r13-32(SP), R13
-	MOVQ	r12-24(SP), R12
-	MOVQ	bp-16(SP),  BP
-	MOVQ	bx-8(SP),   BX
+        POP_REGS_HOST_TO_ABI0()
 	RET
 
 //
diff --git a/src/runtime/sys_openbsd_arm.s b/src/runtime/sys_openbsd_arm.s
index 9e18ce0..143fcf0 100644
--- a/src/runtime/sys_openbsd_arm.s
+++ b/src/runtime/sys_openbsd_arm.s
@@ -10,7 +10,7 @@
 #include "go_tls.h"
 #include "textflag.h"
 
-#define CLOCK_REALTIME	$0
+#define	CLOCK_REALTIME	$0
 #define	CLOCK_MONOTONIC	$3
 
 // With OpenBSD 6.7 onwards, an armv7 syscall returns two instructions
@@ -25,238 +25,40 @@
 	NOOP;		\
 	NOOP
 
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0
-	MOVW	code+0(FP), R0	// arg 1 - status
-	MOVW	$1, R12			// sys_exit
-	INVOKE_SYSCALL
-	MOVW.CS	$0, R8			// crash on syscall failure
-	MOVW.CS	R8, (R8)
-	RET
+// mstart_stub is the first function executed on a new thread started by pthread_create.
+// It just does some low-level setup and then calls mstart.
+// Note: called with the C calling convention.
+TEXT runtime·mstart_stub(SB),NOSPLIT,$0
+	// R0 points to the m.
+	// We are already on m's g0 stack.
 
-// func exitThread(wait *uint32)
-TEXT runtime·exitThread(SB),NOSPLIT,$0-4
-	MOVW	wait+0(FP), R0		// arg 1 - notdead
-	MOVW	$302, R12		// sys___threxit
-	INVOKE_SYSCALL
-	MOVW.CS	$1, R8			// crash on syscall failure
-	MOVW.CS	R8, (R8)
-	JMP	0(PC)
+	// Save callee-save registers.
+	MOVM.DB.W [R4-R11], (R13)
 
-TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0
-	MOVW	name+0(FP), R0		// arg 1 - path
-	MOVW	mode+4(FP), R1		// arg 2 - mode
-	MOVW	perm+8(FP), R2		// arg 3 - perm
-	MOVW	$5, R12			// sys_open
-	INVOKE_SYSCALL
-	MOVW.CS	$-1, R0
-	MOVW	R0, ret+12(FP)
-	RET
+	MOVW	m_g0(R0), g
+	BL	runtime·save_g(SB)
 
-TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0
-	MOVW	fd+0(FP), R0		// arg 1 - fd
-	MOVW	$6, R12			// sys_close
-	INVOKE_SYSCALL
-	MOVW.CS	$-1, R0
-	MOVW	R0, ret+4(FP)
-	RET
+	BL	runtime·mstart(SB)
 
-TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0
-	MOVW	fd+0(FP), R0		// arg 1 - fd
-	MOVW	p+4(FP), R1		// arg 2 - buf
-	MOVW	n+8(FP), R2		// arg 3 - nbyte
-	MOVW	$3, R12			// sys_read
-	INVOKE_SYSCALL
-	RSB.CS	$0, R0		// caller expects negative errno
-	MOVW	R0, ret+12(FP)
-	RET
+	// Restore callee-save registers.
+	MOVM.IA.W (R13), [R4-R11]
 
-// func pipe() (r, w int32, errno int32)
-TEXT runtime·pipe(SB),NOSPLIT,$0-12
-	MOVW	$r+0(FP), R0
-	MOVW	$263, R12
-	INVOKE_SYSCALL
-	MOVW	R0, errno+8(FP)
-	RET
-
-// func pipe2(flags int32) (r, w int32, errno int32)
-TEXT runtime·pipe2(SB),NOSPLIT,$0-16
-	MOVW	$r+4(FP), R0
-	MOVW	flags+0(FP), R1
-	MOVW	$101, R12
-	INVOKE_SYSCALL
-	MOVW	R0, errno+12(FP)
-	RET
-
-TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0
-	MOVW	fd+0(FP), R0		// arg 1 - fd
-	MOVW	p+4(FP), R1		// arg 2 - buf
-	MOVW	n+8(FP), R2		// arg 3 - nbyte
-	MOVW	$4, R12			// sys_write
-	INVOKE_SYSCALL
-	RSB.CS	$0, R0		// caller expects negative errno
-	MOVW	R0, ret+12(FP)
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$16
-	MOVW	usec+0(FP), R0
-	CALL	runtime·usplitR0(SB)
-	MOVW	R0, 4(R13)		// tv_sec - l32
+	// Go is all done with this OS thread.
+	// Tell pthread everything is ok (we never join with this thread, so
+	// the value here doesn't really matter).
 	MOVW	$0, R0
-	MOVW	R0, 8(R13)		// tv_sec - h32
-	MOVW	$1000, R2
-	MUL	R1, R2
-	MOVW	R2, 12(R13)		// tv_nsec
-
-	MOVW	$4(R13), R0		// arg 1 - rqtp
-	MOVW	$0, R1			// arg 2 - rmtp
-	MOVW	$91, R12		// sys_nanosleep
-	INVOKE_SYSCALL
-	RET
-
-TEXT runtime·getthrid(SB),NOSPLIT,$0-4
-	MOVW	$299, R12		// sys_getthrid
-	INVOKE_SYSCALL
-	MOVW	R0, ret+0(FP)
-	RET
-
-TEXT runtime·thrkill(SB),NOSPLIT,$0-8
-	MOVW	tid+0(FP), R0		// arg 1 - tid
-	MOVW	sig+4(FP), R1		// arg 2 - signum
-	MOVW	$0, R2			// arg 3 - tcb
-	MOVW	$119, R12		// sys_thrkill
-	INVOKE_SYSCALL
-	RET
-
-TEXT runtime·raiseproc(SB),NOSPLIT,$12
-	MOVW	$20, R12		// sys_getpid
-	INVOKE_SYSCALL
-					// arg 1 - pid, already in R0
-	MOVW	sig+0(FP), R1		// arg 2 - signum
-	MOVW	$122, R12		// sys_kill
-	INVOKE_SYSCALL
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$16
-	MOVW	addr+0(FP), R0		// arg 1 - addr
-	MOVW	n+4(FP), R1		// arg 2 - len
-	MOVW	prot+8(FP), R2		// arg 3 - prot
-	MOVW	flags+12(FP), R3	// arg 4 - flags
-	MOVW	fd+16(FP), R4		// arg 5 - fd (on stack)
-	MOVW	R4, 4(R13)
-	MOVW	$0, R5			// arg 6 - pad (on stack)
-	MOVW	R5, 8(R13)
-	MOVW	off+20(FP), R6		// arg 7 - offset (on stack)
-	MOVW	R6, 12(R13)		// lower 32 bits (from Go runtime)
-	MOVW	$0, R7
-	MOVW	R7, 16(R13)		// high 32 bits
-	ADD	$4, R13
-	MOVW	$197, R12		// sys_mmap
-	INVOKE_SYSCALL
-	SUB	$4, R13
-	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
-	MOVW	addr+0(FP), R0		// arg 1 - addr
-	MOVW	n+4(FP), R1		// arg 2 - len
-	MOVW	$73, R12		// sys_munmap
-	INVOKE_SYSCALL
-	MOVW.CS	$0, R8			// crash on syscall failure
-	MOVW.CS	R8, (R8)
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$0
-	MOVW	addr+0(FP), R0		// arg 1 - addr
-	MOVW	n+4(FP), R1		// arg 2 - len
-	MOVW	flags+8(FP), R2		// arg 2 - flags
-	MOVW	$75, R12		// sys_madvise
-	INVOKE_SYSCALL
-	MOVW.CS	$-1, R0
-	MOVW	R0, ret+12(FP)
-	RET
-
-TEXT runtime·setitimer(SB),NOSPLIT,$0
-	MOVW	mode+0(FP), R0		// arg 1 - mode
-	MOVW	new+4(FP), R1		// arg 2 - new value
-	MOVW	old+8(FP), R2		// arg 3 - old value
-	MOVW	$69, R12		// sys_setitimer
-	INVOKE_SYSCALL
-	RET
-
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB), NOSPLIT, $32
-	MOVW	CLOCK_REALTIME, R0	// arg 1 - clock_id
-	MOVW	$8(R13), R1		// arg 2 - tp
-	MOVW	$87, R12		// sys_clock_gettime
-	INVOKE_SYSCALL
-
-	MOVW	8(R13), R0		// sec - l32
-	MOVW	12(R13), R1		// sec - h32
-	MOVW	16(R13), R2		// nsec
-
-	MOVW	R0, sec_lo+0(FP)
-	MOVW	R1, sec_hi+4(FP)
-	MOVW	R2, nsec+8(FP)
-
-	RET
-
-// int64 nanotime1(void) so really
-// void nanotime1(int64 *nsec)
-TEXT runtime·nanotime1(SB),NOSPLIT,$32
-	MOVW	CLOCK_MONOTONIC, R0	// arg 1 - clock_id
-	MOVW	$8(R13), R1		// arg 2 - tp
-	MOVW	$87, R12		// sys_clock_gettime
-	INVOKE_SYSCALL
-
-	MOVW	8(R13), R0		// sec - l32
-	MOVW	12(R13), R4		// sec - h32
-	MOVW	16(R13), R2		// nsec
-
-	MOVW	$1000000000, R3
-	MULLU	R0, R3, (R1, R0)
-	MUL	R3, R4
-	ADD.S	R2, R0
-	ADC	R4, R1
-
-	MOVW	R0, ret_lo+0(FP)
-	MOVW	R1, ret_hi+4(FP)
-	RET
-
-TEXT runtime·sigaction(SB),NOSPLIT,$0
-	MOVW	sig+0(FP), R0		// arg 1 - signum
-	MOVW	new+4(FP), R1		// arg 2 - new sigaction
-	MOVW	old+8(FP), R2		// arg 3 - old sigaction
-	MOVW	$46, R12		// sys_sigaction
-	INVOKE_SYSCALL
-	MOVW.CS	$3, R8			// crash on syscall failure
-	MOVW.CS	R8, (R8)
-	RET
-
-TEXT runtime·obsdsigprocmask(SB),NOSPLIT,$0
-	MOVW	how+0(FP), R0		// arg 1 - mode
-	MOVW	new+4(FP), R1		// arg 2 - new
-	MOVW	$48, R12		// sys_sigprocmask
-	INVOKE_SYSCALL
-	MOVW.CS	$3, R8			// crash on syscall failure
-	MOVW.CS	R8, (R8)
-	MOVW	R0, ret+8(FP)
 	RET
 
 TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
 	MOVW	sig+4(FP), R0
 	MOVW	info+8(FP), R1
 	MOVW	ctx+12(FP), R2
-	MOVW	fn+0(FP), R11
-	MOVW	R13, R4
+	MOVW	fn+0(FP), R3
+	MOVW	R13, R9
 	SUB	$24, R13
 	BIC	$0x7, R13 // alignment for ELF ABI
-	BL	(R11)
-	MOVW	R4, R13
+	BL	(R3)
+	MOVW	R9, R13
 	RET
 
 TEXT runtime·sigtramp(SB),NOSPLIT,$0
@@ -267,9 +69,7 @@
 	// If called from an external code context, g will not be set.
 	// Save R0, since runtime·load_g will clobber it.
 	MOVW	R0, 4(R13)		// signum
-	MOVB	runtime·iscgo(SB), R0
-	CMP	$0, R0
-	BL.NE	runtime·load_g(SB)
+	BL	runtime·load_g(SB)
 
 	MOVW	R1, 8(R13)
 	MOVW	R2, 12(R13)
@@ -281,155 +81,726 @@
 
 	RET
 
-// int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
-TEXT runtime·tfork(SB),NOSPLIT,$0
-
-	// Copy mp, gp and fn off parent stack for use by child.
-	MOVW	mm+8(FP), R4
-	MOVW	gg+12(FP), R5
-	MOVW	fn+16(FP), R6
-
-	MOVW	param+0(FP), R0		// arg 1 - param
-	MOVW	psize+4(FP), R1		// arg 2 - psize
-	MOVW	$8, R12			// sys___tfork
-	INVOKE_SYSCALL
-
-	// Return if syscall failed.
-	B.CC	4(PC)
-	RSB	$0, R0
-	MOVW	R0, ret+20(FP)
-	RET
-
-	// In parent, return.
-	CMP	$0, R0
-	BEQ	3(PC)
-	MOVW	R0, ret+20(FP)
-	RET
-
-	// Initialise m, g.
-	MOVW	R5, g
-	MOVW	R4, g_m(g)
-
-	// Paranoia; check that stack splitting code works.
-	BL	runtime·emptyfunc(SB)
-
-	// Call fn.
-	BL	(R6)
-
-	// fn should never return.
-	MOVW	$2, R8			// crash if reached
-	MOVW	R8, (R8)
-	RET
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$0
-	MOVW	new+0(FP), R0		// arg 1 - new sigaltstack
-	MOVW	old+4(FP), R1		// arg 2 - old sigaltstack
-	MOVW	$288, R12		// sys_sigaltstack
-	INVOKE_SYSCALL
-	MOVW.CS	$0, R8			// crash on syscall failure
-	MOVW.CS	R8, (R8)
-	RET
-
-TEXT runtime·osyield(SB),NOSPLIT,$0
-	MOVW	$298, R12		// sys_sched_yield
-	INVOKE_SYSCALL
-	RET
-
-TEXT runtime·thrsleep(SB),NOSPLIT,$4
-	MOVW	ident+0(FP), R0		// arg 1 - ident
-	MOVW	clock_id+4(FP), R1	// arg 2 - clock_id
-	MOVW	tsp+8(FP), R2		// arg 3 - tsp
-	MOVW	lock+12(FP), R3		// arg 4 - lock
-	MOVW	abort+16(FP), R4	// arg 5 - abort (on stack)
-	MOVW	R4, 4(R13)
-	ADD	$4, R13
-	MOVW	$94, R12		// sys___thrsleep
-	INVOKE_SYSCALL
-	SUB	$4, R13
-	MOVW	R0, ret+20(FP)
-	RET
-
-TEXT runtime·thrwakeup(SB),NOSPLIT,$0
-	MOVW	ident+0(FP), R0		// arg 1 - ident
-	MOVW	n+4(FP), R1		// arg 2 - n
-	MOVW	$301, R12		// sys___thrwakeup
-	INVOKE_SYSCALL
-	MOVW	R0, ret+8(FP)
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$8
-	MOVW	mib+0(FP), R0		// arg 1 - mib
-	MOVW	miblen+4(FP), R1	// arg 2 - miblen
-	MOVW	out+8(FP), R2		// arg 3 - out
-	MOVW	size+12(FP), R3		// arg 4 - size
-	MOVW	dst+16(FP), R4		// arg 5 - dest (on stack)
-	MOVW	R4, 4(R13)
-	MOVW	ndst+20(FP), R5		// arg 6 - newlen (on stack)
-	MOVW	R5, 8(R13)
-	ADD	$4, R13
-	MOVW	$202, R12		// sys___sysctl
-	INVOKE_SYSCALL
-	SUB	$4, R13
-	MOVW.CC	$0, R0
-	RSB.CS	$0, R0
-	MOVW	R0, ret+24(FP)
-	RET
-
-// int32 runtime·kqueue(void);
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVW	$269, R12		// sys_kqueue
-	INVOKE_SYSCALL
-	RSB.CS	$0, R0
-	MOVW	R0, ret+0(FP)
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
-TEXT runtime·kevent(SB),NOSPLIT,$8
-	MOVW	kq+0(FP), R0		// arg 1 - kq
-	MOVW	ch+4(FP), R1		// arg 2 - changelist
-	MOVW	nch+8(FP), R2		// arg 3 - nchanges
-	MOVW	ev+12(FP), R3		// arg 4 - eventlist
-	MOVW	nev+16(FP), R4		// arg 5 - nevents (on stack)
-	MOVW	R4, 4(R13)
-	MOVW	ts+20(FP), R5		// arg 6 - timeout (on stack)
-	MOVW	R5, 8(R13)
-	ADD	$4, R13
-	MOVW	$72, R12		// sys_kevent
-	INVOKE_SYSCALL
-	RSB.CS	$0, R0
-	SUB	$4, R13
-	MOVW	R0, ret+24(FP)
-	RET
-
-// func closeonexec(fd int32)
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVW	fd+0(FP), R0		// arg 1 - fd
-	MOVW	$2, R1			// arg 2 - cmd (F_SETFD)
-	MOVW	$1, R2			// arg 3 - arg (FD_CLOEXEC)
-	MOVW	$92, R12		// sys_fcntl
-	INVOKE_SYSCALL
-	RET
-
-// func runtime·setNonblock(fd int32)
-TEXT runtime·setNonblock(SB),NOSPLIT,$0-4
-	MOVW	fd+0(FP), R0	// fd
-	MOVW	$3, R1	// F_GETFL
-	MOVW	$0, R2
-	MOVW	$92, R12
-	INVOKE_SYSCALL
-	ORR	$0x4, R0, R2	// O_NONBLOCK
-	MOVW	fd+0(FP), R0	// fd
-	MOVW	$4, R1	// F_SETFL
-	MOVW	$92, R12
-	INVOKE_SYSCALL
-	RET
-
 TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
 	B	runtime·armPublicationBarrier(SB)
 
+// TODO(jsing): OpenBSD only supports GOARM=7 machines... this
+// should not be needed, however the linker still allows GOARM=5
+// on this platform.
 TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
 	MOVM.WP	[R1, R2, R3, R12], (R13)
 	MOVW	$330, R12		// sys___get_tcb
 	INVOKE_SYSCALL
 	MOVM.IAW (R13), [R1, R2, R3, R12]
 	RET
+
+// These trampolines help convert from Go calling convention to C calling convention.
+// They should be called with asmcgocall - note that while asmcgocall does
+// stack alignment, creation of a frame undoes it again.
+// A pointer to the arguments is passed in R0.
+// A single int32 result is returned in R0.
+// (For more results, make an args/results structure.)
+TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	0(R0), R0		// arg 1 attr
+	CALL	libc_pthread_attr_init(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	0(R0), R0		// arg 1 attr
+	CALL	libc_pthread_attr_destroy(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 size
+	MOVW	0(R0), R0		// arg 1 attr
+	CALL	libc_pthread_attr_getstacksize(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 state
+	MOVW	0(R0), R0		// arg 1 attr
+	CALL	libc_pthread_attr_setdetachstate(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	SUB	$16, R13
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	0(R0), R1		// arg 2 attr
+	MOVW	4(R0), R2		// arg 3 start
+	MOVW	8(R0), R3		// arg 4 arg
+	MOVW	R13, R0			// arg 1 &threadid (discarded)
+	CALL	libc_pthread_create(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 - signal
+	MOVW	$0, R2			// arg 3 - tcb
+	MOVW	0(R0), R0		// arg 1 - tid
+	CALL	libc_thrkill(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	SUB	$16, R13
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 - clock_id
+	MOVW	8(R0), R2		// arg 3 - abstime
+	MOVW	12(R0), R3		// arg 4 - lock
+	MOVW	16(R0), R4		// arg 5 - abort (on stack)
+	MOVW	R4, 0(R13)
+	MOVW	0(R0), R0		// arg 1 - id
+	CALL	libc_thrsleep(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 - count
+	MOVW	0(R0), R0		// arg 1 - id
+	CALL	libc_thrwakeup(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	0(R0), R0		// arg 1 exit status
+	BL	libc_exit(SB)
+	MOVW	$0, R8			// crash on failure
+	MOVW	R8, (R8)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	MOVW	R0, R8
+	BIC     $0x7, R13		// align for ELF ABI
+	BL	libc_getthrid(SB)
+	MOVW	R0, 0(R8)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	R0, R4
+	BL	libc_getpid(SB)		// arg 1 pid
+	MOVW	R4, R1			// arg 2 signal
+	BL	libc_kill(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	BL	libc_sched_yield(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	SUB	$16, R13
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	R0, R8
+	MOVW	4(R0), R1		// arg 2 len
+	MOVW	8(R0), R2		// arg 3 prot
+	MOVW	12(R0), R3		// arg 4 flags
+	MOVW	16(R0), R4		// arg 5 fid (on stack)
+	MOVW	R4, 0(R13)
+	MOVW	$0, R5			// pad (on stack)
+	MOVW	R5, 4(R13)
+	MOVW	20(R0), R6		// arg 6 offset (on stack)
+	MOVW	R6, 8(R13)		// low 32 bits
+	MOVW    $0, R7
+	MOVW	R7, 12(R13)		// high 32 bits
+	MOVW	0(R0), R0		// arg 1 addr
+	BL	libc_mmap(SB)
+	MOVW	$0, R1
+	CMP	$-1, R0
+	BNE	ok
+	BL	libc_errno(SB)
+	MOVW	(R0), R1		// errno
+	MOVW	$0, R0
+ok:
+	MOVW	R0, 24(R8)
+	MOVW	R1, 28(R8)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 len
+	MOVW	0(R0), R0		// arg 1 addr
+	BL	libc_munmap(SB)
+	CMP	$-1, R0
+	BNE	3(PC)
+	MOVW	$0, R8			// crash on failure
+	MOVW	R8, (R8)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 len
+	MOVW	8(R0), R2		// arg 3 advice
+	MOVW	0(R0), R0		// arg 1 addr
+	BL	libc_madvise(SB)
+	// ignore failure - maybe pages are locked
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·open_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	SUB	$8, R13
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 - flags
+	MOVW	8(R0), R2		// arg 3 - mode (vararg, on stack)
+	MOVW	R2, 0(R13)
+	MOVW	0(R0), R0		// arg 1 - path
+	MOVW	R13, R4
+	BIC     $0x7, R13		// align for ELF ABI
+	BL	libc_open(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·close_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	0(R0), R0		// arg 1 - fd
+	BL	libc_close(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·read_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 - buf
+	MOVW	8(R0), R2		// arg 3 - count
+	MOVW	0(R0), R0		// arg 1 - fd
+	BL	libc_read(SB)
+	CMP	$-1, R0
+	BNE	noerr
+	BL	libc_errno(SB)
+	MOVW	(R0), R0		// errno
+	RSB.CS	$0, R0			// caller expects negative errno
+noerr:
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·write_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 buf
+	MOVW	8(R0), R2		// arg 3 count
+	MOVW	0(R0), R0		// arg 1 fd
+	BL	libc_write(SB)
+	CMP	$-1, R0
+	BNE	noerr
+	BL	libc_errno(SB)
+	MOVW	(R0), R0		// errno
+	RSB.CS	$0, R0			// caller expects negative errno
+noerr:
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 flags
+	MOVW	0(R0), R0		// arg 1 filedes
+	BL	libc_pipe2(SB)
+	CMP	$-1, R0
+	BNE	3(PC)
+	BL	libc_errno(SB)
+	MOVW	(R0), R0		// errno
+	RSB.CS	$0, R0			// caller expects negative errno
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 new
+	MOVW	8(R0), R2		// arg 3 old
+	MOVW	0(R0), R0		// arg 1 which
+	BL	libc_setitimer(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	0(R0), R0		// arg 1 usec
+	BL	libc_usleep(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	SUB	$8, R13
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 miblen
+	MOVW	8(R0), R2		// arg 3 out
+	MOVW	12(R0), R3		// arg 4 size
+	MOVW	16(R0), R4		// arg 5 dst (on stack)
+	MOVW	R4, 0(R13)
+	MOVW	20(R0), R5		// arg 6 ndst (on stack)
+	MOVW	R5, 4(R13)
+	MOVW	0(R0), R0		// arg 1 mib
+	BL	libc_sysctl(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	BL	libc_kqueue(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	SUB	$8, R13
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 keventt
+	MOVW	8(R0), R2		// arg 3 nch
+	MOVW	12(R0), R3		// arg 4 ev
+	MOVW	16(R0), R4		// arg 5 nev (on stack)
+	MOVW	R4, 0(R13)
+	MOVW	20(R0), R5		// arg 6 ts (on stack)
+	MOVW	R5, 4(R13)
+	MOVW	0(R0), R0		// arg 1 kq
+	BL	libc_kevent(SB)
+	CMP	$-1, R0
+	BNE	ok
+	BL	libc_errno(SB)
+	MOVW	(R0), R0		// errno
+	RSB.CS	$0, R0			// caller expects negative errno
+ok:
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 tp
+	MOVW	0(R0), R0		// arg 1 clock_id
+	BL	libc_clock_gettime(SB)
+	CMP	$-1, R0
+	BNE	3(PC)
+	MOVW	$0, R8			// crash on failure
+	MOVW	R8, (R8)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	SUB	$8, R13
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 cmd
+	MOVW	8(R0), R2		// arg 3 arg (vararg, on stack)
+	MOVW	R2, 0(R13)
+	MOVW	0(R0), R0		// arg 1 fd
+	BL	libc_fcntl(SB)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 new
+	MOVW	8(R0), R2		// arg 3 old
+	MOVW	0(R0), R0		// arg 1 sig
+	BL	libc_sigaction(SB)
+	CMP	$-1, R0
+	BNE	3(PC)
+	MOVW	$0, R8			// crash on failure
+	MOVW	R8, (R8)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 new
+	MOVW	8(R0), R2		// arg 3 old
+	MOVW	0(R0), R0		// arg 1 how
+	BL	libc_pthread_sigmask(SB)
+	CMP	$-1, R0
+	BNE	3(PC)
+	MOVW	$0, R8			// crash on failure
+	MOVW	R8, (R8)
+	MOVW	R9, R13
+	RET
+
+TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+	MOVW	4(R0), R1		// arg 2 old
+	MOVW	0(R0), R0		// arg 1 new
+	BL	libc_sigaltstack(SB)
+	CMP	$-1, R0
+	BNE	3(PC)
+	MOVW	$0, R8			// crash on failure
+	MOVW	R8, (R8)
+	MOVW	R9, R13
+	RET
+
+// syscall calls a function in libc on behalf of the syscall package.
+// syscall takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscall must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall expects a 32-bit result and tests for 32-bit -1
+// to decide there was an error.
+TEXT runtime·syscall(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+
+	MOVW	R0, R8
+
+	MOVW	(0*4)(R8), R7 // fn
+	MOVW	(1*4)(R8), R0 // a1
+	MOVW	(2*4)(R8), R1 // a2
+	MOVW	(3*4)(R8), R2 // a3
+
+	BL	(R7)
+
+	MOVW	R0, (4*4)(R8) // r1
+	MOVW	R1, (5*4)(R8) // r2
+
+	// Standard libc functions return -1 on error and set errno.
+	CMP	$-1, R0
+	BNE	ok
+
+	// Get error code from libc.
+	BL	libc_errno(SB)
+	MOVW	(R0), R1
+	MOVW	R1, (6*4)(R8) // err
+
+ok:
+	MOVW	$0, R0		// no error (it's ignored anyway)
+	MOVW	R9, R13
+	RET
+
+// syscallX calls a function in libc on behalf of the syscall package.
+// syscallX takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscallX must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscallX is like syscall but expects a 64-bit result
+// and tests for 64-bit -1 to decide there was an error.
+TEXT runtime·syscallX(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	BIC     $0x7, R13		// align for ELF ABI
+
+	MOVW	R0, R8
+
+	MOVW	(0*4)(R8), R7 // fn
+	MOVW	(1*4)(R8), R0 // a1
+	MOVW	(2*4)(R8), R1 // a2
+	MOVW	(3*4)(R8), R2 // a3
+
+	BL	(R7)
+
+	MOVW	R0, (4*4)(R8) // r1
+	MOVW	R1, (5*4)(R8) // r2
+
+	// Standard libc functions return -1 on error and set errno.
+	CMP	$-1, R0
+	BNE	ok
+	CMP	$-1, R1
+	BNE	ok
+
+	// Get error code from libc.
+	BL	libc_errno(SB)
+	MOVW	(R0), R1
+	MOVW	R1, (6*4)(R8) // err
+
+ok:
+	MOVW	$0, R0		// no error (it's ignored anyway)
+	MOVW	R9, R13
+	RET
+
+// syscall6 calls a function in libc on behalf of the syscall package.
+// syscall6 takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	a4    uintptr
+//	a5    uintptr
+//	a6    uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscall6 must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall6 expects a 32-bit result and tests for 32-bit -1
+// to decide there was an error.
+TEXT runtime·syscall6(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	SUB	$8, R13
+	BIC     $0x7, R13		// align for ELF ABI
+
+	MOVW	R0, R8
+
+	MOVW	(0*4)(R8), R7 // fn
+	MOVW	(1*4)(R8), R0 // a1
+	MOVW	(2*4)(R8), R1 // a2
+	MOVW	(3*4)(R8), R2 // a3
+	MOVW	(4*4)(R8), R3 // a4
+	MOVW	(5*4)(R8), R4 // a5
+	MOVW	R4, 0(R13)
+	MOVW	(6*4)(R8), R5 // a6
+	MOVW	R5, 4(R13)
+
+	BL	(R7)
+
+	MOVW	R0, (7*4)(R8) // r1
+	MOVW	R1, (8*4)(R8) // r2
+
+	// Standard libc functions return -1 on error and set errno.
+	CMP	$-1, R0
+	BNE	ok
+
+	// Get error code from libc.
+	BL	libc_errno(SB)
+	MOVW	(R0), R1
+	MOVW	R1, (9*4)(R8) // err
+
+ok:
+	MOVW	$0, R0		// no error (it's ignored anyway)
+	MOVW	R9, R13
+	RET
+
+// syscall6X calls a function in libc on behalf of the syscall package.
+// syscall6X takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	a4    uintptr
+//	a5    uintptr
+//	a6    uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscall6X must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall6X is like syscall6 but expects a 64-bit result
+// and tests for 64-bit -1 to decide there was an error.
+TEXT runtime·syscall6X(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	SUB	$8, R13
+	BIC     $0x7, R13		// align for ELF ABI
+
+	MOVW	R0, R8
+
+	MOVW	(0*4)(R8), R7 // fn
+	MOVW	(1*4)(R8), R0 // a1
+	MOVW	(2*4)(R8), R1 // a2
+	MOVW	(3*4)(R8), R2 // a3
+	MOVW	(4*4)(R8), R3 // a4
+	MOVW	(5*4)(R8), R4 // a5
+	MOVW	R4, 0(R13)
+	MOVW	(6*4)(R8), R5 // a6
+	MOVW	R5, 4(R13)
+
+	BL	(R7)
+
+	MOVW	R0, (7*4)(R8) // r1
+	MOVW	R1, (8*4)(R8) // r2
+
+	// Standard libc functions return -1 on error and set errno.
+	CMP	$-1, R0
+	BNE	ok
+	CMP	$-1, R1
+	BNE	ok
+
+	// Get error code from libc.
+	BL	libc_errno(SB)
+	MOVW	(R0), R1
+	MOVW	R1, (9*4)(R8) // err
+
+ok:
+	MOVW	$0, R0		// no error (it's ignored anyway)
+	MOVW	R9, R13
+	RET
+
+// syscall10 calls a function in libc on behalf of the syscall package.
+// syscall10 takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	a4    uintptr
+//	a5    uintptr
+//	a6    uintptr
+//	a7    uintptr
+//	a8    uintptr
+//	a9    uintptr
+//	a10   uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscall10 must be called on the g0 stack with the
+// C calling convention (use libcCall).
+TEXT runtime·syscall10(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	SUB	$24, R13
+	BIC     $0x7, R13		// align for ELF ABI
+
+	MOVW	R0, R8
+
+	MOVW	(0*4)(R8), R7 // fn
+	MOVW	(1*4)(R8), R0 // a1
+	MOVW	(2*4)(R8), R1 // a2
+	MOVW	(3*4)(R8), R2 // a3
+	MOVW	(4*4)(R8), R3 // a4
+	MOVW	(5*4)(R8), R4 // a5
+	MOVW	R4, 0(R13)
+	MOVW	(6*4)(R8), R5 // a6
+	MOVW	R5, 4(R13)
+	MOVW	(7*4)(R8), R6 // a7
+	MOVW	R6, 8(R13)
+	MOVW	(8*4)(R8), R4 // a8
+	MOVW	R4, 12(R13)
+	MOVW	(9*4)(R8), R5 // a9
+	MOVW	R5, 16(R13)
+	MOVW	(10*4)(R8), R6 // a10
+	MOVW	R6, 20(R13)
+
+	BL	(R7)
+
+	MOVW	R0, (11*4)(R8) // r1
+	MOVW	R1, (12*4)(R8) // r2
+
+	// Standard libc functions return -1 on error and set errno.
+	CMP	$-1, R0
+	BNE	ok
+
+	// Get error code from libc.
+	BL	libc_errno(SB)
+	MOVW	(R0), R1
+	MOVW	R1, (13*4)(R8) // err
+
+ok:
+	MOVW	$0, R0		// no error (it's ignored anyway)
+	MOVW	R9, R13
+	RET
+
+// syscall10X calls a function in libc on behalf of the syscall package.
+// syscall10X takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	a4    uintptr
+//	a5    uintptr
+//	a6    uintptr
+//	a7    uintptr
+//	a8    uintptr
+//	a9    uintptr
+//	a10   uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscall10X must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall10X is like syscall10 but expects a 64-bit result
+// and tests for 64-bit -1 to decide there was an error.
+TEXT runtime·syscall10X(SB),NOSPLIT,$0
+	MOVW	R13, R9
+	SUB	$24, R13
+	BIC     $0x7, R13		// align for ELF ABI
+
+	MOVW	R0, R8
+
+	MOVW	(0*4)(R8), R7 // fn
+	MOVW	(1*4)(R8), R0 // a1
+	MOVW	(2*4)(R8), R1 // a2
+	MOVW	(3*4)(R8), R2 // a3
+	MOVW	(4*4)(R8), R3 // a4
+	MOVW	(5*4)(R8), R4 // a5
+	MOVW	R4, 0(R13)
+	MOVW	(6*4)(R8), R5 // a6
+	MOVW	R5, 4(R13)
+	MOVW	(7*4)(R8), R6 // a7
+	MOVW	R6, 8(R13)
+	MOVW	(8*4)(R8), R4 // a8
+	MOVW	R4, 12(R13)
+	MOVW	(9*4)(R8), R5 // a9
+	MOVW	R5, 16(R13)
+	MOVW	(10*4)(R8), R6 // a10
+	MOVW	R6, 20(R13)
+
+	BL	(R7)
+
+	MOVW	R0, (11*4)(R8) // r1
+	MOVW	R1, (12*4)(R8) // r2
+
+	// Standard libc functions return -1 on error and set errno.
+	CMP	$-1, R0
+	BNE	ok
+	CMP	$-1, R1
+	BNE	ok
+
+	// Get error code from libc.
+	BL	libc_errno(SB)
+	MOVW	(R0), R1
+	MOVW	R1, (13*4)(R8) // err
+
+ok:
+	MOVW	$0, R0		// no error (it's ignored anyway)
+	MOVW	R9, R13
+	RET
diff --git a/src/runtime/sys_openbsd_mips64.s b/src/runtime/sys_openbsd_mips64.s
index 3e4d209..f8ae8e7 100644
--- a/src/runtime/sys_openbsd_mips64.s
+++ b/src/runtime/sys_openbsd_mips64.s
@@ -186,8 +186,8 @@
 	SYSCALL
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB), NOSPLIT, $32
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB), NOSPLIT, $32
 	MOVW	CLOCK_REALTIME, R4	// arg 1 - clock_id
 	MOVV	$8(R29), R5		// arg 2 - tp
 	MOVV	$87, R2			// sys_clock_gettime
diff --git a/src/runtime/sys_plan9_386.s b/src/runtime/sys_plan9_386.s
index f9969f6..b3d2f13 100644
--- a/src/runtime/sys_plan9_386.s
+++ b/src/runtime/sys_plan9_386.s
@@ -102,8 +102,8 @@
 	MOVL	$-1, ret_hi+8(FP)
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB),NOSPLIT,$8-12
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB),NOSPLIT,$8-12
 	CALL	runtime·nanotime1(SB)
 	MOVL	0(SP), AX
 	MOVL	4(SP), DX
diff --git a/src/runtime/sys_plan9_amd64.s b/src/runtime/sys_plan9_amd64.s
index 383622b..731306a 100644
--- a/src/runtime/sys_plan9_amd64.s
+++ b/src/runtime/sys_plan9_amd64.s
@@ -88,8 +88,8 @@
 	MOVQ	AX, ret+8(FP)
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB),NOSPLIT,$8-12
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB),NOSPLIT,$8-12
 	CALL	runtime·nanotime1(SB)
 	MOVQ	0(SP), AX
 
diff --git a/src/runtime/sys_plan9_arm.s b/src/runtime/sys_plan9_arm.s
index 9fbe305..5343085 100644
--- a/src/runtime/sys_plan9_arm.s
+++ b/src/runtime/sys_plan9_arm.s
@@ -138,8 +138,8 @@
 	MOVW	R0, ret_hi+8(FP)
 	RET
 
-// func walltime1() (sec int64, nsec int32)
-TEXT runtime·walltime1(SB),NOSPLIT,$12-12
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB),NOSPLIT,$12-12
 	// use nsec system call to get current time in nanoseconds
 	MOVW	$sysnsec_lo-8(SP), R0	// destination addr
 	MOVW	R0,res-12(SP)
diff --git a/src/runtime/sys_ppc64x.go b/src/runtime/sys_ppc64x.go
index 796f27c..69bd99f 100644
--- a/src/runtime/sys_ppc64x.go
+++ b/src/runtime/sys_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 package runtime
diff --git a/src/runtime/sys_wasm.go b/src/runtime/sys_wasm.go
index 9bf710b..057ed4c 100644
--- a/src/runtime/sys_wasm.go
+++ b/src/runtime/sys_wasm.go
@@ -27,13 +27,9 @@
 func wasmExit(code int32)
 
 // adjust Gobuf as it if executed a call to fn with context ctxt
-// and then did an immediate gosave.
+// and then stopped before the first instruction in fn.
 func gostartcall(buf *gobuf, fn, ctxt unsafe.Pointer) {
 	sp := buf.sp
-	if sys.RegSize > sys.PtrSize {
-		sp -= sys.PtrSize
-		*(*uintptr)(unsafe.Pointer(sp)) = 0
-	}
 	sp -= sys.PtrSize
 	*(*uintptr)(unsafe.Pointer(sp)) = buf.pc
 	buf.sp = sp
diff --git a/src/runtime/sys_wasm.s b/src/runtime/sys_wasm.s
index e7a6570..164dd16 100644
--- a/src/runtime/sys_wasm.s
+++ b/src/runtime/sys_wasm.s
@@ -185,7 +185,7 @@
 	CallImport
 	RET
 
-TEXT ·walltime1(SB), NOSPLIT, $0
+TEXT ·walltime(SB), NOSPLIT, $0
 	CallImport
 	RET
 
diff --git a/src/runtime/sys_windows_386.s b/src/runtime/sys_windows_386.s
index ef8a3dd..0b39335 100644
--- a/src/runtime/sys_windows_386.s
+++ b/src/runtime/sys_windows_386.s
@@ -5,9 +5,10 @@
 #include "go_asm.h"
 #include "go_tls.h"
 #include "textflag.h"
+#include "time_windows.h"
 
 // void runtime·asmstdcall(void *c);
-TEXT runtime·asmstdcall(SB),NOSPLIT,$0
+TEXT runtime·asmstdcall<ABIInternal>(SB),NOSPLIT,$0
 	MOVL	fn+0(FP), BX
 
 	// SetLastError(0).
@@ -57,7 +58,9 @@
 	MOVL	DX, 12(SP)
 	MOVL	$0, 16(SP) // overlapped
 	CALL	*runtime·_WriteFile(SB)
-	MOVL	BP, SI
+
+	// Does not return.
+	CALL	runtime·abort(SB)
 	RET
 
 // faster get/set last error
@@ -66,11 +69,6 @@
 	MOVL	AX, ret+0(FP)
 	RET
 
-TEXT runtime·setlasterror(SB),NOSPLIT,$0
-	MOVL	err+0(FP), AX
-	MOVL	AX, 0x34(FS)
-	RET
-
 // Called by Windows as a Vectored Exception Handler (VEH).
 // First argument is pointer to struct containing
 // exception record and context pointers.
@@ -99,7 +97,7 @@
 	JNE	2(PC)
 	CALL	runtime·badsignal2(SB)
 
-	// save g and SP in case of stack switch
+	// save g in case of stack switch
 	MOVL	DX, 32(SP)	// g
 	MOVL	SP, 36(SP)
 
@@ -113,13 +111,9 @@
 	get_tls(BP)
 	MOVL	BX, g(BP)
 	MOVL	(g_sched+gobuf_sp)(BX), DI
-	// make it look like mstart called us on g0, to stop traceback
-	SUBL	$4, DI
-	MOVL	$runtime·mstart(SB), 0(DI)
-	// traceback will think that we've done SUBL
-	// on this stack, so subtract them here to match.
-	// (we need room for sighandler arguments anyway).
+	// make room for sighandler arguments
 	// and re-save old SP for restoring later.
+	// (note that the 36(DI) here must match the 36(SP) above.)
 	SUBL	$40, DI
 	MOVL	SP, 36(DI)
 	MOVL	DI, SP
@@ -137,7 +131,7 @@
 	// switch back to original stack and g
 	// no-op if we never left.
 	MOVL	36(SP), SP
-	MOVL	32(SP), DX
+	MOVL	32(SP), DX	// note: different SP
 	get_tls(BP)
 	MOVL	DX, g(BP)
 
@@ -153,90 +147,21 @@
 	BYTE $0xC2; WORD $4
 	RET // unreached; make assembler happy
 
-TEXT runtime·exceptiontramp(SB),NOSPLIT,$0
+TEXT runtime·exceptiontramp<ABIInternal>(SB),NOSPLIT,$0
 	MOVL	$runtime·exceptionhandler(SB), AX
 	JMP	sigtramp<>(SB)
 
-TEXT runtime·firstcontinuetramp(SB),NOSPLIT,$0-0
+TEXT runtime·firstcontinuetramp<ABIInternal>(SB),NOSPLIT,$0-0
 	// is never called
 	INT	$3
 
-TEXT runtime·lastcontinuetramp(SB),NOSPLIT,$0-0
+TEXT runtime·lastcontinuetramp<ABIInternal>(SB),NOSPLIT,$0-0
 	MOVL	$runtime·lastcontinuehandler(SB), AX
 	JMP	sigtramp<>(SB)
 
-// Called by OS using stdcall ABI: bool ctrlhandler(uint32).
-TEXT runtime·ctrlhandler(SB),NOSPLIT,$0
-	PUSHL	$runtime·ctrlhandler1(SB)
-	NOP	SP	// tell vet SP changed - stop checking offsets
-	CALL	runtime·externalthreadhandler(SB)
-	MOVL	4(SP), CX
-	ADDL	$12, SP
-	JMP	CX
-
-// Called by OS using stdcall ABI: uint32 profileloop(void*).
-TEXT runtime·profileloop(SB),NOSPLIT,$0
-	PUSHL	$runtime·profileloop1(SB)
-	NOP	SP	// tell vet SP changed - stop checking offsets
-	CALL	runtime·externalthreadhandler(SB)
-	MOVL	4(SP), CX
-	ADDL	$12, SP
-	JMP	CX
-
-TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0
-	PUSHL	BP
-	MOVL	SP, BP
-	PUSHL	BX
-	PUSHL	SI
-	PUSHL	DI
-	PUSHL	0x14(FS)
-	MOVL	SP, DX
-
-	// setup dummy m, g
-	SUBL	$m__size, SP		// space for M
-	MOVL	SP, 0(SP)
-	MOVL	$m__size, 4(SP)
-	CALL	runtime·memclrNoHeapPointers(SB)	// smashes AX,BX,CX
-
-	LEAL	m_tls(SP), CX
-	MOVL	CX, 0x14(FS)
-	MOVL	SP, BX
-	SUBL	$g__size, SP		// space for G
-	MOVL	SP, g(CX)
-	MOVL	SP, m_g0(BX)
-
-	MOVL	SP, 0(SP)
-	MOVL	$g__size, 4(SP)
-	CALL	runtime·memclrNoHeapPointers(SB)	// smashes AX,BX,CX
-	LEAL	g__size(SP), BX
-	MOVL	BX, g_m(SP)
-
-	LEAL	-32768(SP), CX		// must be less than SizeOfStackReserve set by linker
-	MOVL	CX, (g_stack+stack_lo)(SP)
-	ADDL	$const__StackGuard, CX
-	MOVL	CX, g_stackguard0(SP)
-	MOVL	CX, g_stackguard1(SP)
-	MOVL	DX, (g_stack+stack_hi)(SP)
-
-	PUSHL	AX			// room for return value
-	PUSHL	16(BP)			// arg for handler
-	CALL	8(BP)
-	POPL	CX
-	POPL	AX			// pass return value to Windows in AX
-
-	get_tls(CX)
-	MOVL	g(CX), CX
-	MOVL	(g_stack+stack_hi)(CX), SP
-	POPL	0x14(FS)
-	POPL	DI
-	POPL	SI
-	POPL	BX
-	POPL	BP
-	RET
-
 GLOBL runtime·cbctxts(SB), NOPTR, $4
 
-TEXT runtime·callbackasm1(SB),NOSPLIT,$0
+TEXT runtime·callbackasm1<ABIInternal>(SB),NOSPLIT,$0
   	MOVL	0(SP), AX	// will use to find our callback context
 
 	// remove return address from stack, we are not returning to callbackasm, but to its caller.
@@ -255,7 +180,7 @@
 	CLD
 
 	// determine index into runtime·cbs table
-	SUBL	$runtime·callbackasm(SB), AX
+	SUBL	$runtime·callbackasm<ABIInternal>(SB), AX
 	MOVL	$0, DX
 	MOVL	$5, BX	// divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
 	DIVL	BX
@@ -325,7 +250,7 @@
 	RET
 
 // uint32 tstart_stdcall(M *newm);
-TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
+TEXT runtime·tstart_stdcall<ABIInternal>(SB),NOSPLIT,$0
 	MOVL	newm+0(FP), BX
 
 	PUSHL	BX
@@ -347,60 +272,11 @@
 	MOVL	CX, 0x14(FS)
 	RET
 
-// onosstack calls fn on OS stack.
-// func onosstack(fn unsafe.Pointer, arg uint32)
-TEXT runtime·onosstack(SB),NOSPLIT,$0
-	MOVL	fn+0(FP), AX		// to hide from 8l
-	MOVL	arg+4(FP), BX
-
-	// Execute call on m->g0 stack, in case we are not actually
-	// calling a system call wrapper, like when running under WINE.
-	get_tls(CX)
-	CMPL	CX, $0
-	JNE	3(PC)
-	// Not a Go-managed thread. Do not switch stack.
-	CALL	AX
-	RET
-
-	MOVL	g(CX), BP
-	MOVL	g_m(BP), BP
-
-	// leave pc/sp for cpu profiler
-	MOVL	(SP), SI
-	MOVL	SI, m_libcallpc(BP)
-	MOVL	g(CX), SI
-	MOVL	SI, m_libcallg(BP)
-	// sp must be the last, because once async cpu profiler finds
-	// all three values to be non-zero, it will use them
-	LEAL	fn+0(FP), SI
-	MOVL	SI, m_libcallsp(BP)
-
-	MOVL	m_g0(BP), SI
-	CMPL	g(CX), SI
-	JNE	switch
-	// executing on m->g0 already
-	CALL	AX
-	JMP	ret
-
-switch:
-	// Switch to m->g0 stack and back.
-	MOVL	(g_sched+gobuf_sp)(SI), SI
-	MOVL	SP, -4(SI)
-	LEAL	-4(SI), SP
-	CALL	AX
-	MOVL	0(SP), SP
-
-ret:
-	get_tls(CX)
-	MOVL	g(CX), BP
-	MOVL	g_m(BP), BP
-	MOVL	$0, m_libcallsp(BP)
-	RET
-
-// Runs on OS stack. duration (in 100ns units) is in BX.
-TEXT runtime·usleep2(SB),NOSPLIT,$20
-	// Want negative 100ns units.
-	NEGL	BX
+// Runs on OS stack.
+// duration (in -100ns units) is in dt+0(FP).
+// g may be nil.
+TEXT runtime·usleep2(SB),NOSPLIT,$20-4
+	MOVL	dt+0(FP), BX
 	MOVL	$-1, hi-4(SP)
 	MOVL	BX, lo-8(SP)
 	LEAL	lo-8(SP), BX
@@ -413,17 +289,15 @@
 	MOVL	BP, SP
 	RET
 
-// Runs on OS stack. duration (in 100ns units) is in BX.
-TEXT runtime·usleep2HighRes(SB),NOSPLIT,$36
-	get_tls(CX)
-	CMPL	CX, $0
-	JE	gisnotset
-
-	// Want negative 100ns units.
-	NEGL	BX
+// Runs on OS stack.
+// duration (in -100ns units) is in dt+0(FP).
+// g is valid.
+TEXT runtime·usleep2HighRes(SB),NOSPLIT,$36-4
+	MOVL	dt+0(FP), BX
 	MOVL	$-1, hi-4(SP)
 	MOVL	BX, lo-8(SP)
 
+	get_tls(CX)
 	MOVL	g(CX), CX
 	MOVL	g_m(CX), CX
 	MOVL	(m_mOS+mOS_highResTimer)(CX), CX
@@ -452,12 +326,6 @@
 
 	RET
 
-gisnotset:
-	// TLS is not configured. Call usleep2 instead.
-	MOVL	$runtime·usleep2(SB), AX
-	CALL	AX
-	RET
-
 // Runs on OS stack.
 TEXT runtime·switchtothread(SB),NOSPLIT,$0
 	MOVL	SP, BP
@@ -466,14 +334,6 @@
 	MOVL	BP, SP
 	RET
 
-// See https://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/getting-os-information-the-kuser_shared_data-structure/
-// Must read hi1, then lo, then hi2. The snapshot is valid if hi1 == hi2.
-#define _INTERRUPT_TIME 0x7ffe0008
-#define _SYSTEM_TIME 0x7ffe0014
-#define time_lo 0
-#define time_hi1 4
-#define time_hi2 8
-
 TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
 	CMPB	runtime·useQPCTime(SB), $0
 	JNE	useQPC
@@ -496,78 +356,3 @@
 useQPC:
 	JMP	runtime·nanotimeQPC(SB)
 	RET
-
-TEXT time·now(SB),NOSPLIT,$0-20
-	CMPB	runtime·useQPCTime(SB), $0
-	JNE	useQPC
-loop:
-	MOVL	(_INTERRUPT_TIME+time_hi1), AX
-	MOVL	(_INTERRUPT_TIME+time_lo), CX
-	MOVL	(_INTERRUPT_TIME+time_hi2), DI
-	CMPL	AX, DI
-	JNE	loop
-
-	// w = DI:CX
-	// multiply by 100
-	MOVL	$100, AX
-	MULL	CX
-	IMULL	$100, DI
-	ADDL	DI, DX
-	// w*100 = DX:AX
-	MOVL	AX, mono+12(FP)
-	MOVL	DX, mono+16(FP)
-
-wall:
-	MOVL	(_SYSTEM_TIME+time_hi1), CX
-	MOVL	(_SYSTEM_TIME+time_lo), AX
-	MOVL	(_SYSTEM_TIME+time_hi2), DX
-	CMPL	CX, DX
-	JNE	wall
-
-	// w = DX:AX
-	// convert to Unix epoch (but still 100ns units)
-	#define delta 116444736000000000
-	SUBL	$(delta & 0xFFFFFFFF), AX
-	SBBL $(delta >> 32), DX
-
-	// nano/100 = DX:AX
-	// split into two decimal halves by div 1e9.
-	// (decimal point is two spots over from correct place,
-	// but we avoid overflow in the high word.)
-	MOVL	$1000000000, CX
-	DIVL	CX
-	MOVL	AX, DI
-	MOVL	DX, SI
-
-	// DI = nano/100/1e9 = nano/1e11 = sec/100, DX = SI = nano/100%1e9
-	// split DX into seconds and nanoseconds by div 1e7 magic multiply.
-	MOVL	DX, AX
-	MOVL	$1801439851, CX
-	MULL	CX
-	SHRL	$22, DX
-	MOVL	DX, BX
-	IMULL	$10000000, DX
-	MOVL	SI, CX
-	SUBL	DX, CX
-
-	// DI = sec/100 (still)
-	// BX = (nano/100%1e9)/1e7 = (nano/1e9)%100 = sec%100
-	// CX = (nano/100%1e9)%1e7 = (nano%1e9)/100 = nsec/100
-	// store nsec for return
-	IMULL	$100, CX
-	MOVL	CX, nsec+8(FP)
-
-	// DI = sec/100 (still)
-	// BX = sec%100
-	// construct DX:AX = 64-bit sec and store for return
-	MOVL	$0, DX
-	MOVL	$100, AX
-	MULL	DI
-	ADDL	BX, AX
-	ADCL	$0, DX
-	MOVL	AX, sec+0(FP)
-	MOVL	DX, sec+4(FP)
-	RET
-useQPC:
-	JMP	runtime·nowQPC(SB)
-	RET
diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s
index d1690ca..e778284 100644
--- a/src/runtime/sys_windows_amd64.s
+++ b/src/runtime/sys_windows_amd64.s
@@ -5,13 +5,15 @@
 #include "go_asm.h"
 #include "go_tls.h"
 #include "textflag.h"
+#include "time_windows.h"
+#include "cgo/abi_amd64.h"
 
 // maxargs should be divisible by 2, as Windows stack
 // must be kept 16-byte aligned on syscall entry.
-#define maxargs 16
+#define maxargs 18
 
 // void runtime·asmstdcall(void *c);
-TEXT runtime·asmstdcall(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·asmstdcall<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
 	// asmcgocall will put first argument into CX.
 	PUSHQ	CX			// save for later
 	MOVQ	libcall_fn(CX), AX
@@ -94,6 +96,8 @@
 	MOVQ	runtime·_WriteFile(SB), AX
 	CALL	AX
 
+	// Does not return.
+	CALL	runtime·abort(SB)
 	RET
 
 // faster get/set last error
@@ -103,12 +107,6 @@
 	MOVL	AX, ret+0(FP)
 	RET
 
-TEXT runtime·setlasterror(SB),NOSPLIT,$0
-	MOVL	err+0(FP), AX
-	MOVQ	0x30(GS),	CX
-	MOVL	AX, 0x68(CX)
-	RET
-
 // Called by Windows as a Vectored Exception Handler (VEH).
 // First argument is pointer to struct containing
 // exception record and context pointers.
@@ -117,18 +115,10 @@
 TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0-0
 	// CX: PEXCEPTION_POINTERS ExceptionInfo
 
-	// DI SI BP BX R12 R13 R14 R15 registers and DF flag are preserved
-	// as required by windows callback convention.
-	PUSHFQ
-	SUBQ	$112, SP
-	MOVQ	DI, 80(SP)
-	MOVQ	SI, 72(SP)
-	MOVQ	BP, 64(SP)
-	MOVQ	BX, 56(SP)
-	MOVQ	R12, 48(SP)
-	MOVQ	R13, 40(SP)
-	MOVQ	R14, 32(SP)
-	MOVQ	R15, 88(SP)
+	// Switch from the host ABI to the Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
+	// Make stack space for the rest of the function.
+	ADJSP	$48
 
 	MOVQ	AX, R15	// save handler address
 
@@ -144,8 +134,8 @@
 	CALL	runtime·badsignal2(SB)
 
 	// save g and SP in case of stack switch
-	MOVQ	DX, 96(SP) // g
-	MOVQ	SP, 104(SP)
+	MOVQ	DX, 32(SP) // g
+	MOVQ	SP, 40(SP)
 
 	// do we need to switch to the g0 stack?
 	MOVQ	g_m(DX), BX
@@ -157,17 +147,13 @@
 	get_tls(BP)
 	MOVQ	BX, g(BP)
 	MOVQ	(g_sched+gobuf_sp)(BX), DI
-	// make it look like mstart called us on g0, to stop traceback
-	SUBQ	$8, DI
-	MOVQ	$runtime·mstart(SB), SI
-	MOVQ	SI, 0(DI)
-	// traceback will think that we've done PUSHFQ and SUBQ
-	// on this stack, so subtract them here to match.
-	// (we need room for sighandler arguments anyway).
+	// make room for sighandler arguments
 	// and re-save old SP for restoring later.
-	SUBQ	$(112+8), DI
-	// save g, save old stack pointer.
-	MOVQ	SP, 104(DI)
+	// Adjust g0 stack by the space we're using and
+	// save SP at the same place on the g0 stack.
+	// The 40(DI) here must match the 40(SP) above.
+	SUBQ	$(REGS_HOST_TO_ABI0_STACK + 48), DI
+	MOVQ	SP, 40(DI)
 	MOVQ	DI, SP
 
 g0:
@@ -182,102 +168,29 @@
 
 	// switch back to original stack and g
 	// no-op if we never left.
-	MOVQ	104(SP), SP
-	MOVQ	96(SP), DX
+	MOVQ	40(SP), SP
+	MOVQ	32(SP), DX
 	get_tls(BP)
 	MOVQ	DX, g(BP)
 
 done:
-	// restore registers as required for windows callback
-	MOVQ	88(SP), R15
-	MOVQ	32(SP), R14
-	MOVQ	40(SP), R13
-	MOVQ	48(SP), R12
-	MOVQ	56(SP), BX
-	MOVQ	64(SP), BP
-	MOVQ	72(SP), SI
-	MOVQ	80(SP), DI
-	ADDQ	$112, SP
-	POPFQ
+	ADJSP	$-48
+	POP_REGS_HOST_TO_ABI0()
 
 	RET
 
-TEXT runtime·exceptiontramp(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·exceptiontramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
 	MOVQ	$runtime·exceptionhandler(SB), AX
 	JMP	sigtramp<>(SB)
 
-TEXT runtime·firstcontinuetramp(SB),NOSPLIT|NOFRAME,$0-0
+TEXT runtime·firstcontinuetramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-0
 	MOVQ	$runtime·firstcontinuehandler(SB), AX
 	JMP	sigtramp<>(SB)
 
-TEXT runtime·lastcontinuetramp(SB),NOSPLIT|NOFRAME,$0-0
+TEXT runtime·lastcontinuetramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-0
 	MOVQ	$runtime·lastcontinuehandler(SB), AX
 	JMP	sigtramp<>(SB)
 
-TEXT runtime·ctrlhandler(SB),NOSPLIT|NOFRAME,$8
-	MOVQ	CX, 16(SP)		// spill
-	MOVQ	$runtime·ctrlhandler1(SB), CX
-	MOVQ	CX, 0(SP)
-	CALL	runtime·externalthreadhandler(SB)
-	RET
-
-TEXT runtime·profileloop(SB),NOSPLIT|NOFRAME,$8
-	MOVQ	$runtime·profileloop1(SB), CX
-	MOVQ	CX, 0(SP)
-	CALL	runtime·externalthreadhandler(SB)
-	RET
-
-TEXT runtime·externalthreadhandler(SB),NOSPLIT|NOFRAME,$0
-	PUSHQ	BP
-	MOVQ	SP, BP
-	PUSHQ	BX
-	PUSHQ	SI
-	PUSHQ	DI
-	PUSHQ	0x28(GS)
-	MOVQ	SP, DX
-
-	// setup dummy m, g
-	SUBQ	$m__size, SP		// space for M
-	MOVQ	SP, 0(SP)
-	MOVQ	$m__size, 8(SP)
-	CALL	runtime·memclrNoHeapPointers(SB)	// smashes AX,BX,CX, maybe BP
-
-	LEAQ	m_tls(SP), CX
-	MOVQ	CX, 0x28(GS)
-	MOVQ	SP, BX
-	SUBQ	$g__size, SP		// space for G
-	MOVQ	SP, g(CX)
-	MOVQ	SP, m_g0(BX)
-
-	MOVQ	SP, 0(SP)
-	MOVQ	$g__size, 8(SP)
-	CALL	runtime·memclrNoHeapPointers(SB)	// smashes AX,BX,CX, maybe BP
-	LEAQ	g__size(SP), BX
-	MOVQ	BX, g_m(SP)
-
-	LEAQ	-32768(SP), CX		// must be less than SizeOfStackReserve set by linker
-	MOVQ	CX, (g_stack+stack_lo)(SP)
-	ADDQ	$const__StackGuard, CX
-	MOVQ	CX, g_stackguard0(SP)
-	MOVQ	CX, g_stackguard1(SP)
-	MOVQ	DX, (g_stack+stack_hi)(SP)
-
-	PUSHQ	AX			// room for return value
-	PUSHQ	32(BP)			// arg for handler
-	CALL	16(BP)
-	POPQ	CX
-	POPQ	AX			// pass return value to Windows in AX
-
-	get_tls(CX)
-	MOVQ	g(CX), CX
-	MOVQ	(g_stack+stack_hi)(CX), SP
-	POPQ	0x28(GS)
-	POPQ	DI
-	POPQ	SI
-	POPQ	BX
-	POPQ	BP
-	RET
-
 GLOBL runtime·cbctxts(SB), NOPTR, $8
 
 TEXT runtime·callbackasm1(SB),NOSPLIT,$0
@@ -299,28 +212,15 @@
 	ADDQ	$8, SP
 
 	// determine index into runtime·cbs table
-	MOVQ	$runtime·callbackasm(SB), DX
+	MOVQ	$runtime·callbackasm<ABIInternal>(SB), DX
 	SUBQ	DX, AX
 	MOVQ	$0, DX
 	MOVQ	$5, CX	// divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
 	DIVL	CX
 	SUBQ	$1, AX	// subtract 1 because return PC is to the next slot
 
-	// DI SI BP BX R12 R13 R14 R15 registers and DF flag are preserved
-	// as required by windows callback convention.
-	PUSHFQ
-	SUBQ	$64, SP
-	MOVQ	DI, 56(SP)
-	MOVQ	SI, 48(SP)
-	MOVQ	BP, 40(SP)
-	MOVQ	BX, 32(SP)
-	MOVQ	R12, 24(SP)
-	MOVQ	R13, 16(SP)
-	MOVQ	R14, 8(SP)
-	MOVQ	R15, 0(SP)
-
-	// Go ABI requires DF flag to be cleared.
-	CLD
+	// Switch from the host ABI to the Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
 
 	// Create a struct callbackArgs on our stack to be passed as
 	// the "frame" to cgocallback and on to callbackWrap.
@@ -332,30 +232,23 @@
 	// Call cgocallback, which will call callbackWrap(frame).
 	MOVQ	$0, 16(SP)	// context
 	MOVQ	AX, 8(SP)	// frame (address of callbackArgs)
-	LEAQ	·callbackWrap(SB), BX
+	LEAQ	·callbackWrap<ABIInternal>(SB), BX	// cgocallback takes an ABIInternal entry-point
 	MOVQ	BX, 0(SP)	// PC of function value to call (callbackWrap)
 	CALL	·cgocallback(SB)
 	// Get callback result.
 	MOVQ	(24+callbackArgs_result)(SP), AX
 	ADDQ	$(24+callbackArgs__size), SP
 
-	// restore registers as required for windows callback
-	MOVQ	0(SP), R15
-	MOVQ	8(SP), R14
-	MOVQ	16(SP), R13
-	MOVQ	24(SP), R12
-	MOVQ	32(SP), BX
-	MOVQ	40(SP), BP
-	MOVQ	48(SP), SI
-	MOVQ	56(SP), DI
-	ADDQ	$64, SP
-	POPFQ
+	POP_REGS_HOST_TO_ABI0()
 
 	// The return value was placed in AX above.
 	RET
 
 // uint32 tstart_stdcall(M *newm);
-TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
+TEXT runtime·tstart_stdcall<ABIInternal>(SB),NOSPLIT,$0
+	// Switch from the host ABI to the Go ABI.
+	PUSH_REGS_HOST_TO_ABI0()
+
 	// CX contains first arg newm
 	MOVQ	m_g0(CX), DX		// g
 
@@ -374,12 +267,11 @@
 	MOVQ	CX, g_m(DX)
 	MOVQ	DX, g(SI)
 
-	// Someday the convention will be D is always cleared.
-	CLD
-
 	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
 	CALL	runtime·mstart(SB)
 
+	POP_REGS_HOST_TO_ABI0()
+
 	XORL	AX, AX			// return 0 == success
 	RET
 
@@ -388,61 +280,16 @@
 	MOVQ	DI, 0x28(GS)
 	RET
 
-// func onosstack(fn unsafe.Pointer, arg uint32)
-TEXT runtime·onosstack(SB),NOSPLIT,$0
-	MOVQ	fn+0(FP), AX		// to hide from 6l
-	MOVL	arg+8(FP), BX
-
-	// Execute call on m->g0 stack, in case we are not actually
-	// calling a system call wrapper, like when running under WINE.
-	get_tls(R15)
-	CMPQ	R15, $0
-	JNE	3(PC)
-	// Not a Go-managed thread. Do not switch stack.
-	CALL	AX
-	RET
-
-	MOVQ	g(R15), R13
-	MOVQ	g_m(R13), R13
-
-	// leave pc/sp for cpu profiler
-	MOVQ	(SP), R12
-	MOVQ	R12, m_libcallpc(R13)
-	MOVQ	g(R15), R12
-	MOVQ	R12, m_libcallg(R13)
-	// sp must be the last, because once async cpu profiler finds
-	// all three values to be non-zero, it will use them
-	LEAQ	fn+0(FP), R12
-	MOVQ	R12, m_libcallsp(R13)
-
-	MOVQ	m_g0(R13), R14
-	CMPQ	g(R15), R14
-	JNE	switch
-	// executing on m->g0 already
-	CALL	AX
-	JMP	ret
-
-switch:
-	// Switch to m->g0 stack and back.
-	MOVQ	(g_sched+gobuf_sp)(R14), R14
-	MOVQ	SP, -8(R14)
-	LEAQ	-8(R14), SP
-	CALL	AX
-	MOVQ	0(SP), SP
-
-ret:
-	MOVQ	$0, m_libcallsp(R13)
-	RET
-
-// Runs on OS stack. duration (in 100ns units) is in BX.
+// Runs on OS stack.
+// duration (in -100ns units) is in dt+0(FP).
+// g may be nil.
 // The function leaves room for 4 syscall parameters
 // (as per windows amd64 calling convention).
-TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$48
+TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$48-4
+	MOVLQSX	dt+0(FP), BX
 	MOVQ	SP, AX
 	ANDQ	$~15, SP	// alignment as per Windows requirement
 	MOVQ	AX, 40(SP)
-	// Want negative 100ns units.
-	NEGQ	BX
 	LEAQ	32(SP), R8  // ptime
 	MOVQ	BX, (R8)
 	MOVQ	$-1, CX // handle
@@ -452,11 +299,11 @@
 	MOVQ	40(SP), SP
 	RET
 
-// Runs on OS stack. duration (in 100ns units) is in BX.
-TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$72
+// Runs on OS stack. duration (in -100ns units) is in dt+0(FP).
+// g is valid.
+TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$72-4
+	MOVLQSX	dt+0(FP), BX
 	get_tls(CX)
-	CMPQ	CX, $0
-	JE	gisnotset
 
 	MOVQ	SP, AX
 	ANDQ	$~15, SP	// alignment as per Windows requirement
@@ -466,8 +313,6 @@
 	MOVQ	g_m(CX), CX
 	MOVQ	(m_mOS+mOS_highResTimer)(CX), CX	// hTimer
 	MOVQ	CX, 48(SP)				// save hTimer for later
-	// Want negative 100ns units.
-	NEGQ	BX
 	LEAQ	56(SP), DX				// lpDueTime
 	MOVQ	BX, (DX)
 	MOVQ	$0, R8					// lPeriod
@@ -487,12 +332,6 @@
 	MOVQ	64(SP), SP
 	RET
 
-gisnotset:
-	// TLS is not configured. Call usleep2 instead.
-	MOVQ	$runtime·usleep2(SB), AX
-	CALL	AX
-	RET
-
 // Runs on OS stack.
 TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
 	MOVQ	SP, AX
@@ -505,14 +344,6 @@
 	MOVQ	32(SP), SP
 	RET
 
-// See https://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/getting-os-information-the-kuser_shared_data-structure/
-// Must read hi1, then lo, then hi2. The snapshot is valid if hi1 == hi2.
-#define _INTERRUPT_TIME 0x7ffe0008
-#define _SYSTEM_TIME 0x7ffe0014
-#define time_lo 0
-#define time_hi1 4
-#define time_hi2 8
-
 TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
 	CMPB	runtime·useQPCTime(SB), $0
 	JNE	useQPC
@@ -532,48 +363,10 @@
 	JMP	runtime·nanotimeQPC(SB)
 	RET
 
-TEXT time·now(SB),NOSPLIT,$0-24
-	CMPB	runtime·useQPCTime(SB), $0
-	JNE	useQPC
-	MOVQ	$_INTERRUPT_TIME, DI
-loop:
-	MOVL	time_hi1(DI), AX
-	MOVL	time_lo(DI), BX
-	MOVL	time_hi2(DI), CX
-	CMPL	AX, CX
-	JNE	loop
-	SHLQ	$32, AX
-	ORQ	BX, AX
-	IMULQ	$100, AX
-	MOVQ	AX, mono+16(FP)
-
-	MOVQ	$_SYSTEM_TIME, DI
-wall:
-	MOVL	time_hi1(DI), AX
-	MOVL	time_lo(DI), BX
-	MOVL	time_hi2(DI), CX
-	CMPL	AX, CX
-	JNE	wall
-	SHLQ	$32, AX
-	ORQ	BX, AX
-	MOVQ	$116444736000000000, DI
-	SUBQ	DI, AX
-	IMULQ	$100, AX
-
-	// generated code for
-	//	func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
-	// adapted to reduce duplication
-	MOVQ	AX, CX
-	MOVQ	$1360296554856532783, AX
-	MULQ	CX
-	ADDQ	CX, DX
-	RCRQ	$1, DX
-	SHRQ	$29, DX
-	MOVQ	DX, sec+0(FP)
-	IMULQ	$1000000000, DX
-	SUBQ	DX, CX
-	MOVL	CX, nsec+8(FP)
-	RET
-useQPC:
-	JMP	runtime·nowQPC(SB)
+// func osSetupTLS(mp *m)
+// Setup TLS. for use by needm on Windows.
+TEXT runtime·osSetupTLS(SB),NOSPLIT,$0-8
+	MOVQ	mp+0(FP), AX
+	LEAQ	m_tls(AX), DI
+	CALL	runtime·settls(SB)
 	RET
diff --git a/src/runtime/sys_windows_arm.s b/src/runtime/sys_windows_arm.s
index fe26708..48f8c7d 100644
--- a/src/runtime/sys_windows_arm.s
+++ b/src/runtime/sys_windows_arm.s
@@ -5,9 +5,12 @@
 #include "go_asm.h"
 #include "go_tls.h"
 #include "textflag.h"
+#include "time_windows.h"
+
+// Note: For system ABI, R0-R3 are args, R4-R11 are callee-save.
 
 // void runtime·asmstdcall(void *c);
-TEXT runtime·asmstdcall(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·asmstdcall<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
 	MOVM.DB.W [R4, R5, R14], (R13)	// push {r4, r5, lr}
 	MOVW	R0, R4			// put libcall * in r4
 	MOVW	R13, R5			// save stack pointer in r5
@@ -94,8 +97,8 @@
 	MOVW	runtime·_WriteFile(SB), R12
 	BL	(R12)
 
-	MOVW	R4, R13			// restore SP
-	MOVM.IA.W (R13), [R4, R15]	// pop {r4, pc}
+	// Does not return.
+	B	runtime·abort(SB)
 
 TEXT runtime·getlasterror(SB),NOSPLIT,$0
 	MRC	15, 0, R0, C13, C0, 2
@@ -103,11 +106,6 @@
 	MOVW	R0, ret+0(FP)
 	RET
 
-TEXT runtime·setlasterror(SB),NOSPLIT|NOFRAME,$0
-	MRC	15, 0, R1, C13, C0, 2
-	MOVW	R0, 0x34(R1)
-	RET
-
 // Called by Windows as a Vectored Exception Handler (VEH).
 // First argument is pointer to struct containing
 // exception record and context pointers.
@@ -144,11 +142,10 @@
 	MOVW	(g_sched+gobuf_sp)(g), R3	// R3 = g->gobuf.sp
 	BL      runtime·save_g(SB)
 
-	// traceback will think that we've done PUSH and SUB
-	// on this stack, so subtract them here to match.
-	// (we need room for sighandler arguments anyway).
+	// make room for sighandler arguments
 	// and re-save old SP for restoring later.
-	SUB	$(40+8+20), R3
+	// (note that the 24(R3) here must match the 24(R13) above.)
+	SUB	$40, R3
 	MOVW	R13, 24(R3)		// save old stack pointer
 	MOVW	R3, R13			// switch stack
 
@@ -156,21 +153,18 @@
 	MOVW	0(R6), R2	// R2 = ExceptionPointers->ExceptionRecord
 	MOVW	4(R6), R3	// R3 = ExceptionPointers->ContextRecord
 
-	// make it look like mstart called us on g0, to stop traceback
-	MOVW    $runtime·mstart(SB), R4
-
-	MOVW	R4, 0(R13)	// Save link register for traceback
+	MOVW	$0, R4
+	MOVW	R4, 0(R13)	// No saved link register.
 	MOVW	R2, 4(R13)	// Move arg0 (ExceptionRecord) into position
 	MOVW	R3, 8(R13)	// Move arg1 (ContextRecord) into position
 	MOVW	R5, 12(R13)	// Move arg2 (original g) into position
-	BL	(R7)		// Call the go routine
+	BL	(R7)		// Call the goroutine
 	MOVW	16(R13), R4	// Fetch return value from stack
 
-	// Compute the value of the g0 stack pointer after deallocating
-	// this frame, then allocating 8 bytes. We may need to store
-	// the resume SP and PC on the g0 stack to work around
-	// control flow guard when we resume from the exception.
-	ADD	$(40+20), R13, R12
+	// Save system stack pointer for sigresume setup below.
+	// The exact value does not matter - nothing is read or written
+	// from this address. It just needs to be on the system stack.
+	MOVW	R13, R12
 
 	// switch back to original stack and g
 	MOVW	24(R13), R13
@@ -188,132 +182,61 @@
 	BEQ	return
 
 	// Check if we need to set up the control flow guard workaround.
-	// On Windows/ARM, the stack pointer must lie within system
-	// stack limits when we resume from exception.
+	// On Windows, the stack pointer in the context must lie within
+	// system stack limits when we resume from exception.
 	// Store the resume SP and PC on the g0 stack,
-	// and return to returntramp on the g0 stack. returntramp
+	// and return to sigresume on the g0 stack. sigresume
 	// pops the saved PC and SP from the g0 stack, resuming execution
 	// at the desired location.
-	// If returntramp has already been set up by a previous exception
+	// If sigresume has already been set up by a previous exception
 	// handler, don't clobber the stored SP and PC on the stack.
 	MOVW	4(R3), R3			// PEXCEPTION_POINTERS->Context
-	MOVW	0x40(R3), R2			// load PC from context record
-	MOVW	$returntramp<>(SB), R1
+	MOVW	context_pc(R3), R2		// load PC from context record
+	MOVW	$sigresume<>(SB), R1
 	CMP	R1, R2
 	B.EQ	return				// do not clobber saved SP/PC
 
-	// Save resume SP and PC on g0 stack
-	MOVW	0x38(R3), R2			// load SP from context record
-	MOVW	R2, 0(R12)			// Store resume SP on g0 stack
-	MOVW	0x40(R3), R2			// load PC from context record
-	MOVW	R2, 4(R12)			// Store resume PC on g0 stack
+	// Save resume SP and PC into R0, R1.
+	MOVW	context_spr(R3), R2
+	MOVW	R2, context_r0(R3)
+	MOVW	context_pc(R3), R2
+	MOVW	R2, context_r1(R3)
 
-	// Set up context record to return to returntramp on g0 stack
-	MOVW	R12, 0x38(R3)			// save g0 stack pointer
-						// in context record
-	MOVW	$returntramp<>(SB), R2	// save resume address
-	MOVW	R2, 0x40(R3)			// in context record
+	// Set up context record to return to sigresume on g0 stack
+	MOVW	R12, context_spr(R3)
+	MOVW	$sigresume<>(SB), R2
+	MOVW	R2, context_pc(R3)
 
 return:
 	B	(R14)				// return
 
-//
 // Trampoline to resume execution from exception handler.
 // This is part of the control flow guard workaround.
 // It switches stacks and jumps to the continuation address.
-//
-TEXT returntramp<>(SB),NOSPLIT|NOFRAME,$0
-	MOVM.IA	(R13), [R13, R15]		// ldm sp, [sp, pc]
+// R0 and R1 are set above at the end of sigtramp<>
+// in the context that starts executing at sigresume<>.
+TEXT sigresume<>(SB),NOSPLIT|NOFRAME,$0
+	// Important: do not smash LR,
+	// which is set to a live value when handling
+	// a signal by pushing a call to sigpanic onto the stack.
+	MOVW	R0, R13
+	B	(R1)
 
-TEXT runtime·exceptiontramp(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·exceptiontramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
 	MOVW	$runtime·exceptionhandler(SB), R1
 	B	sigtramp<>(SB)
 
-TEXT runtime·firstcontinuetramp(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·firstcontinuetramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
 	MOVW	$runtime·firstcontinuehandler(SB), R1
 	B	sigtramp<>(SB)
 
-TEXT runtime·lastcontinuetramp(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·lastcontinuetramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
 	MOVW	$runtime·lastcontinuehandler(SB), R1
 	B	sigtramp<>(SB)
 
-TEXT runtime·ctrlhandler(SB),NOSPLIT|NOFRAME,$0
-	MOVW	$runtime·ctrlhandler1(SB), R1
-	B	runtime·externalthreadhandler(SB)
-
-TEXT runtime·profileloop(SB),NOSPLIT|NOFRAME,$0
-	MOVW	$runtime·profileloop1(SB), R1
-	B	runtime·externalthreadhandler(SB)
-
-// int32 externalthreadhandler(uint32 arg, int (*func)(uint32))
-// stack layout:
-//   +----------------+
-//   | callee-save    |
-//   | registers      |
-//   +----------------+
-//   | m              |
-//   +----------------+
-// 20| g              |
-//   +----------------+
-// 16| func ptr (r1)  |
-//   +----------------+
-// 12| argument (r0)  |
-//---+----------------+
-// 8 | param1         |
-//   +----------------+
-// 4 | param0         |
-//   +----------------+
-// 0 | retval         |
-//   +----------------+
-//
-TEXT runtime·externalthreadhandler(SB),NOSPLIT|NOFRAME,$0
-	MOVM.DB.W [R4-R11, R14], (R13)		// push {r4-r11, lr}
-	SUB	$(m__size + g__size + 20), R13	// space for locals
-	MOVW	R0, 12(R13)
-	MOVW	R1, 16(R13)
-
-	// zero out m and g structures
-	ADD	$20, R13, R0			// compute pointer to g
-	MOVW	R0, 4(R13)
-	MOVW	$(m__size + g__size), R0
-	MOVW	R0, 8(R13)
-	BL	runtime·memclrNoHeapPointers(SB)
-
-	// initialize m and g structures
-	ADD	$20, R13, R2			// R2 = g
-	ADD	$(20 + g__size), R13, R3	// R3 = m
-	MOVW	R2, m_g0(R3)			// m->g0 = g
-	MOVW	R3, g_m(R2)			// g->m = m
-	MOVW	R2, m_curg(R3)			// m->curg = g
-
-	MOVW	R2, g
-	BL	runtime·save_g(SB)
-
-	// set up stackguard stuff
-	MOVW	R13, R0
-	MOVW	R0, g_stack+stack_hi(g)
-	SUB	$(32*1024), R0
-	MOVW	R0, (g_stack+stack_lo)(g)
-	MOVW	R0, g_stackguard0(g)
-	MOVW	R0, g_stackguard1(g)
-
-	// move argument into position and call function
-	MOVW	12(R13), R0
-	MOVW	R0, 4(R13)
-	MOVW	16(R13), R1
-	BL	(R1)
-
-	// clear g
-	MOVW	$0, g
-	BL	runtime·save_g(SB)
-
-	MOVW	0(R13), R0			// load return value
-	ADD	$(m__size + g__size + 20), R13	// free locals
-	MOVM.IA.W (R13), [R4-R11, R15]		// pop {r4-r11, pc}
-
 GLOBL runtime·cbctxts(SB), NOPTR, $4
 
-TEXT runtime·callbackasm1(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·callbackasm1<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
 	// On entry, the trampoline in zcallback_windows_arm.s left
 	// the callback index in R12 (which is volatile in the C ABI).
 
@@ -352,16 +275,13 @@
 	B	(R12)	// return
 
 // uint32 tstart_stdcall(M *newm);
-TEXT runtime·tstart_stdcall(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·tstart_stdcall<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
 	MOVM.DB.W [R4-R11, R14], (R13)		// push {r4-r11, lr}
 
 	MOVW	m_g0(R0), g
 	MOVW	R0, g_m(g)
 	BL	runtime·save_g(SB)
 
-	// do per-thread TLS initialization
-	BL	init_thread_tls<>(SB)
-
 	// Layout new m scheduler stack on os stack.
 	MOVW	R13, R0
 	MOVW	R0, g_stack+stack_hi(g)
@@ -377,84 +297,15 @@
 	MOVW	$0, R0
 	MOVM.IA.W (R13), [R4-R11, R15]		// pop {r4-r11, pc}
 
-// onosstack calls fn on OS stack.
-// adapted from asm_arm.s : systemstack
-// func onosstack(fn unsafe.Pointer, arg uint32)
-TEXT runtime·onosstack(SB),NOSPLIT,$0
-	MOVW	fn+0(FP), R5		// R5 = fn
-	MOVW	arg+4(FP), R6		// R6 = arg
-
-	// This function can be called when there is no g,
-	// for example, when we are handling a callback on a non-go thread.
-	// In this case we're already on the system stack.
-	CMP	$0, g
-	BEQ	noswitch
-
-	MOVW	g_m(g), R1		// R1 = m
-
-	MOVW	m_gsignal(R1), R2	// R2 = gsignal
-	CMP	g, R2
-	B.EQ	noswitch
-
-	MOVW	m_g0(R1), R2		// R2 = g0
-	CMP	g, R2
-	B.EQ	noswitch
-
-	MOVW	m_curg(R1), R3
-	CMP	g, R3
-	B.EQ	switch
-
-	// Bad: g is not gsignal, not g0, not curg. What is it?
-	// Hide call from linker nosplit analysis.
-	MOVW	$runtime·badsystemstack(SB), R0
-	BL	(R0)
-	B	runtime·abort(SB)
-
-switch:
-	// save our state in g->sched. Pretend to
-	// be systemstack_switch if the G stack is scanned.
-	MOVW	$runtime·systemstack_switch(SB), R3
-	ADD	$4, R3, R3 // get past push {lr}
-	MOVW	R3, (g_sched+gobuf_pc)(g)
-	MOVW	R13, (g_sched+gobuf_sp)(g)
-	MOVW	LR, (g_sched+gobuf_lr)(g)
-	MOVW	g, (g_sched+gobuf_g)(g)
-
-	// switch to g0
-	MOVW	R2, g
-	MOVW	(g_sched+gobuf_sp)(R2), R3
-	// make it look like mstart called systemstack on g0, to stop traceback
-	SUB	$4, R3, R3
-	MOVW	$runtime·mstart(SB), R4
-	MOVW	R4, 0(R3)
-	MOVW	R3, R13
-
-	// call target function
-	MOVW	R6, R0		// arg
-	BL	(R5)
-
-	// switch back to g
-	MOVW	g_m(g), R1
-	MOVW	m_curg(R1), g
-	MOVW	(g_sched+gobuf_sp)(g), R13
-	MOVW	$0, R3
-	MOVW	R3, (g_sched+gobuf_sp)(g)
-	RET
-
-noswitch:
-	// Using a tail call here cleans up tracebacks since we won't stop
-	// at an intermediate systemstack.
-	MOVW.P	4(R13), R14	// restore LR
-	MOVW	R6, R0		// arg
-	B	(R5)
-
-// Runs on OS stack. Duration (in 100ns units) is in R0.
-TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$0
+// Runs on OS stack.
+// duration (in -100ns units) is in dt+0(FP).
+// g may be nil.
+TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$0-4
+	MOVW	dt+0(FP), R3
 	MOVM.DB.W [R4, R14], (R13)	// push {r4, lr}
 	MOVW	R13, R4			// Save SP
 	SUB	$8, R13			// R13 = R13 - 8
 	BIC	$0x7, R13		// Align SP for ABI
-	RSB	$0, R0, R3		// R3 = -R0
 	MOVW	$0, R1			// R1 = FALSE (alertable)
 	MOVW	$-1, R0			// R0 = handle
 	MOVW	R13, R2			// R2 = pTime
@@ -465,9 +316,11 @@
 	MOVW	R4, R13			// Restore SP
 	MOVM.IA.W (R13), [R4, R15]	// pop {R4, pc}
 
-// Runs on OS stack. Duration (in 100ns units) is in R0.
+// Runs on OS stack.
+// duration (in -100ns units) is in dt+0(FP).
+// g is valid.
 // TODO: neeeds to be implemented properly.
-TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$0-4
 	B	runtime·abort(SB)
 
 // Runs on OS stack.
@@ -483,21 +336,13 @@
 TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
 	B	runtime·armPublicationBarrier(SB)
 
-// never called (cgo not supported)
+// never called (this is a GOARM=7 platform)
 TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
 	MOVW	$0xabcd, R0
 	MOVW	R0, (R0)
 	RET
 
-// See http://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/getting-os-information-the-kuser_shared_data-structure/
-// Must read hi1, then lo, then hi2. The snapshot is valid if hi1 == hi2.
-#define _INTERRUPT_TIME 0x7ffe0008
-#define _SYSTEM_TIME 0x7ffe0014
-#define time_lo 0
-#define time_hi1 4
-#define time_hi2 8
-
-TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
+TEXT runtime·nanotime1(SB),NOSPLIT|NOFRAME,$0-8
 	MOVW	$0, R0
 	MOVB	runtime·useQPCTime(SB), R0
 	CMP	$0, R0
@@ -521,84 +366,6 @@
 	RET
 useQPC:
 	B	runtime·nanotimeQPC(SB)		// tail call
-	RET
-
-TEXT time·now(SB),NOSPLIT,$0-20
-	MOVW    $0, R0
-	MOVB    runtime·useQPCTime(SB), R0
-	CMP	$0, R0
-	BNE	useQPC
-	MOVW	$_INTERRUPT_TIME, R3
-loop:
-	MOVW	time_hi1(R3), R1
-	MOVW	time_lo(R3), R0
-	MOVW	time_hi2(R3), R2
-	CMP	R1, R2
-	BNE	loop
-
-	// wintime = R1:R0, multiply by 100
-	MOVW	$100, R2
-	MULLU	R0, R2, (R4, R3)    // R4:R3 = R1:R0 * R2
-	MULA	R1, R2, R4, R4
-
-	// wintime*100 = R4:R3
-	MOVW	R3, mono+12(FP)
-	MOVW	R4, mono+16(FP)
-
-	MOVW	$_SYSTEM_TIME, R3
-wall:
-	MOVW	time_hi1(R3), R1
-	MOVW	time_lo(R3), R0
-	MOVW	time_hi2(R3), R2
-	CMP	R1, R2
-	BNE	wall
-
-	// w = R1:R0 in 100ns untis
-	// convert to Unix epoch (but still 100ns units)
-	#define delta 116444736000000000
-	SUB.S   $(delta & 0xFFFFFFFF), R0
-	SBC     $(delta >> 32), R1
-
-	// Convert to nSec
-	MOVW    $100, R2
-	MULLU   R0, R2, (R4, R3)    // R4:R3 = R1:R0 * R2
-	MULA    R1, R2, R4, R4
-	// w = R2:R1 in nSec
-	MOVW    R3, R1	      // R4:R3 -> R2:R1
-	MOVW    R4, R2
-
-	// multiply nanoseconds by reciprocal of 10**9 (scaled by 2**61)
-	// to get seconds (96 bit scaled result)
-	MOVW	$0x89705f41, R3		// 2**61 * 10**-9
-	MULLU	R1,R3,(R6,R5)		// R7:R6:R5 = R2:R1 * R3
-	MOVW	$0,R7
-	MULALU	R2,R3,(R7,R6)
-
-	// unscale by discarding low 32 bits, shifting the rest by 29
-	MOVW	R6>>29,R6		// R7:R6 = (R7:R6:R5 >> 61)
-	ORR	R7<<3,R6
-	MOVW	R7>>29,R7
-
-	// subtract (10**9 * sec) from nsec to get nanosecond remainder
-	MOVW	$1000000000, R5	// 10**9
-	MULLU	R6,R5,(R9,R8)   // R9:R8 = R7:R6 * R5
-	MULA	R7,R5,R9,R9
-	SUB.S	R8,R1		// R2:R1 -= R9:R8
-	SBC	R9,R2
-
-	// because reciprocal was a truncated repeating fraction, quotient
-	// may be slightly too small -- adjust to make remainder < 10**9
-	CMP	R5,R1	// if remainder > 10**9
-	SUB.HS	R5,R1   //    remainder -= 10**9
-	ADD.HS	$1,R6	//    sec += 1
-
-	MOVW	R6,sec_lo+0(FP)
-	MOVW	R7,sec_hi+4(FP)
-	MOVW	R1,nsec+8(FP)
-	RET
-useQPC:
-	B	runtime·nanotimeQPC(SB)		// tail call
-	RET
 
 // save_g saves the g register (R10) into thread local memory
 // so that we can call externally compiled
@@ -656,39 +423,8 @@
 	MOVW 	$runtime·tls_g(SB), R1
 	MOVW	R0, (R1)
 
-	BL	init_thread_tls<>(SB)
-
 	MOVW	R4, R13
 	MOVM.IA.W (R13), [R4, R15]	// pop {r4, pc}
 
-// void init_thread_tls()
-//
-// Does per-thread TLS initialization. Saves a pointer to the TLS slot
-// holding G, in the current m.
-//
-//     g->m->tls[0] = &_TEB->TlsSlots[tls_g]
-//
-// The purpose of this is to enable the profiling handler to get the
-// current g associated with the thread. We cannot use m->curg because curg
-// only holds the current user g. If the thread is executing system code or
-// external code, m->curg will be NULL. The thread's TLS slot always holds
-// the current g, so save a reference to this location so the profiling
-// handler can get the real g from the thread's m.
-//
-// Clobbers R0-R3
-TEXT init_thread_tls<>(SB),NOSPLIT|NOFRAME,$0
-	// compute &_TEB->TlsSlots[tls_g]
-	MRC	15, 0, R0, C13, C0, 2
-	ADD	$0xe10, R0
-	MOVW 	$runtime·tls_g(SB), R1
-	MOVW	(R1), R1
-	MOVW	R1<<2, R1
-	ADD	R1, R0
-
-	// save in g->m->tls[0]
-	MOVW	g_m(g), R1
-	MOVW	R0, m_tls(R1)
-	RET
-
 // Holds the TLS Slot, which was allocated by TlsAlloc()
 GLOBL runtime·tls_g+0(SB), NOPTR, $4
diff --git a/src/runtime/sys_windows_arm64.s b/src/runtime/sys_windows_arm64.s
new file mode 100644
index 0000000..7a2e11f
--- /dev/null
+++ b/src/runtime/sys_windows_arm64.s
@@ -0,0 +1,455 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "textflag.h"
+#include "funcdata.h"
+#include "time_windows.h"
+
+// Offsets into Thread Environment Block (pointer in R18)
+#define TEB_error 0x68
+#define TEB_TlsSlots 0x1480
+
+// Note: R0-R7 are args, R8 is indirect return value address,
+// R9-R15 are caller-save, R19-R29 are callee-save.
+//
+// load_g and save_g (in tls_arm64.s) clobber R27 (REGTMP) and R0.
+
+// void runtime·asmstdcall(void *c);
+TEXT runtime·asmstdcall<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+	STP.W	(R29, R30), -32(RSP)	// allocate C ABI stack frame
+	STP	(R19, R20), 16(RSP) // save old R19, R20
+	MOVD	R0, R19	// save libcall pointer
+	MOVD	RSP, R20	// save stack pointer
+
+	// SetLastError(0)
+	MOVD	$0,	TEB_error(R18_PLATFORM)
+	MOVD	libcall_args(R19), R12	// libcall->args
+
+	// Do we have more than 8 arguments?
+	MOVD	libcall_n(R19), R0
+	CMP	$0,	R0; BEQ	_0args
+	CMP	$1,	R0; BEQ	_1args
+	CMP	$2,	R0; BEQ	_2args
+	CMP	$3,	R0; BEQ	_3args
+	CMP	$4,	R0; BEQ	_4args
+	CMP	$5,	R0; BEQ	_5args
+	CMP	$6,	R0; BEQ	_6args
+	CMP	$7,	R0; BEQ	_7args
+	CMP	$8,	R0; BEQ	_8args
+
+	// Reserve stack space for remaining args
+	SUB	$8, R0, R2
+	ADD	$1, R2, R3 // make even number of words for stack alignment
+	AND	$~1, R3
+	LSL	$3, R3
+	SUB	R3, RSP
+
+	// R4: size of stack arguments (n-8)*8
+	// R5: &args[8]
+	// R6: loop counter, from 0 to (n-8)*8
+	// R7: scratch
+	// R8: copy of RSP - (R2)(RSP) assembles as (R2)(ZR)
+	SUB	$8, R0, R4
+	LSL	$3, R4
+	ADD	$(8*8), R12, R5
+	MOVD	$0, R6
+	MOVD	RSP, R8
+stackargs:
+	MOVD	(R6)(R5), R7
+	MOVD	R7, (R6)(R8)
+	ADD	$8, R6
+	CMP	R6, R4
+	BNE	stackargs
+
+_8args:
+	MOVD	(7*8)(R12), R7
+_7args:
+	MOVD	(6*8)(R12), R6
+_6args:
+	MOVD	(5*8)(R12), R5
+_5args:
+	MOVD	(4*8)(R12), R4
+_4args:
+	MOVD	(3*8)(R12), R3
+_3args:
+	MOVD	(2*8)(R12), R2
+_2args:
+	MOVD	(1*8)(R12), R1
+_1args:
+	MOVD	(0*8)(R12), R0
+_0args:
+
+	MOVD	libcall_fn(R19), R12	// branch to libcall->fn
+	BL	(R12)
+
+	MOVD	R20, RSP			// free stack space
+	MOVD	R0, libcall_r1(R19)		// save return value to libcall->r1
+	// TODO(rsc) floating point like amd64 in libcall->r2?
+
+	// GetLastError
+	MOVD	TEB_error(R18_PLATFORM), R0
+	MOVD	R0, libcall_err(R19)
+
+	// Restore callee-saved registers.
+	LDP	16(RSP), (R19, R20)
+	LDP.P	32(RSP), (R29, R30)
+	RET
+
+TEXT runtime·badsignal2(SB),NOSPLIT,$16-0
+	NO_LOCAL_POINTERS
+
+	// stderr
+	MOVD	runtime·_GetStdHandle(SB), R1
+	MOVD	$-12, R0
+	SUB	$16, RSP	// skip over saved frame pointer below RSP
+	BL	(R1)
+	ADD	$16, RSP
+
+	// handle in R0 already
+	MOVD	$runtime·badsignalmsg(SB), R1	// lpBuffer
+	MOVD	$runtime·badsignallen(SB), R2	// lpNumberOfBytesToWrite
+	MOVD	(R2), R2
+	MOVD	R13, R3		// lpNumberOfBytesWritten
+	MOVD	$0, R4			// lpOverlapped
+	MOVD	runtime·_WriteFile(SB), R12
+	SUB	$16, RSP	// skip over saved frame pointer below RSP
+	BL	(R12)
+
+	// Does not return.
+	B	runtime·abort(SB)
+
+	RET
+
+TEXT runtime·getlasterror(SB),NOSPLIT|NOFRAME,$0
+	MOVD	TEB_error(R18_PLATFORM), R0
+	MOVD	R0, ret+0(FP)
+	RET
+
+#define SAVE_R19_TO_R28(offset) \
+	MOVD	R19, savedR19+((offset)+0*8)(SP); \
+	MOVD	R20, savedR20+((offset)+1*8)(SP); \
+	MOVD	R21, savedR21+((offset)+2*8)(SP); \
+	MOVD	R22, savedR22+((offset)+3*8)(SP); \
+	MOVD	R23, savedR23+((offset)+4*8)(SP); \
+	MOVD	R24, savedR24+((offset)+5*8)(SP); \
+	MOVD	R25, savedR25+((offset)+6*8)(SP); \
+	MOVD	R26, savedR26+((offset)+7*8)(SP); \
+	MOVD	R27, savedR27+((offset)+8*8)(SP); \
+	MOVD	g, savedR28+((offset)+9*8)(SP);
+
+#define RESTORE_R19_TO_R28(offset) \
+	MOVD	savedR19+((offset)+0*8)(SP), R19; \
+	MOVD	savedR20+((offset)+1*8)(SP), R20; \
+	MOVD	savedR21+((offset)+2*8)(SP), R21; \
+	MOVD	savedR22+((offset)+3*8)(SP), R22; \
+	MOVD	savedR23+((offset)+4*8)(SP), R23; \
+	MOVD	savedR24+((offset)+5*8)(SP), R24; \
+	MOVD	savedR25+((offset)+6*8)(SP), R25; \
+	MOVD	savedR26+((offset)+7*8)(SP), R26; \
+	MOVD	savedR27+((offset)+8*8)(SP), R27; \
+	MOVD	savedR28+((offset)+9*8)(SP), g; /* R28 */
+
+// Called by Windows as a Vectored Exception Handler (VEH).
+// First argument is pointer to struct containing
+// exception record and context pointers.
+// Handler function is stored in R1
+// Return 0 for 'not handled', -1 for handled.
+// int32_t sigtramp(
+//     PEXCEPTION_POINTERS ExceptionInfo,
+//     func *GoExceptionHandler);
+TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0
+	// Save R0, R1 (args) as well as LR, R27, R28 (callee-save).
+	MOVD	R0, R5
+	MOVD	R1, R6
+	MOVD	LR, R7
+	MOVD	R27, R16		// saved R27 (callee-save)
+	MOVD	g, R17 			// saved R28 (callee-save from Windows, not really g)
+
+	BL      runtime·load_g(SB)	// smashes R0, R27, R28 (g)
+	CMP	$0, g			// is there a current g?
+	BNE	2(PC)
+	BL	runtime·badsignal2(SB)
+
+	// Do we need to switch to the g0 stack?
+	MOVD	g, R3			// R3 = oldg (for sigtramp_g0)
+	MOVD	g_m(g), R2		// R2 = m
+	MOVD	m_g0(R2), R2		// R2 = g0
+	CMP	g, R2			// if curg == g0
+	BNE	switch
+
+	// No: on g0 stack already, tail call to sigtramp_g0.
+	// Restore all the callee-saves so sigtramp_g0 can return to our caller.
+	// We also pass R2 = g0, R3 = oldg, both set above.
+	MOVD	R5, R0
+	MOVD	R6, R1
+	MOVD	R7, LR
+	MOVD	R16, R27		// restore R27
+	MOVD	R17, g 			// restore R28
+	B	sigtramp_g0<>(SB)
+
+switch:
+	// switch to g0 stack (but do not update g - that's sigtramp_g0's job)
+	MOVD	RSP, R8
+	MOVD	(g_sched+gobuf_sp)(R2), R4	// R4 = g->gobuf.sp
+	SUB	$(6*8), R4			// alloc space for saves - 2 words below SP for frame pointer, 3 for us to use, 1 for alignment
+	MOVD	R4, RSP				// switch to g0 stack
+
+	MOVD	$0, (0*8)(RSP)	// fake saved LR
+	MOVD	R7, (1*8)(RSP)	// saved LR
+	MOVD	R8, (2*8)(RSP)	// saved SP
+
+	MOVD	R5, R0		// original args
+	MOVD	R6, R1		// original args
+	MOVD	R16, R27
+	MOVD	R17, g 		// R28
+	BL	sigtramp_g0<>(SB)
+
+	// switch back to original stack; g already updated
+	MOVD	(1*8)(RSP), R7	// saved LR
+	MOVD	(2*8)(RSP), R8	// saved SP
+	MOVD	R7, LR
+	MOVD	R8, RSP
+	RET
+
+// sigtramp_g0 is running on the g0 stack, with R2 = g0, R3 = oldg.
+// But g itself is not set - that's R28, a callee-save register,
+// and it still holds the value from the Windows DLL caller.
+TEXT sigtramp_g0<>(SB),NOSPLIT,$128
+	NO_LOCAL_POINTERS
+
+	// Push C callee-save registers R19-R28. LR, FP already saved.
+	SAVE_R19_TO_R28(-10*8)
+
+	MOVD	0(R0), R5	// R5 = ExceptionPointers->ExceptionRecord
+	MOVD	8(R0), R6	// R6 = ExceptionPointers->ContextRecord
+	MOVD	R6, context-(11*8)(SP)
+
+	MOVD	R2, g 			// g0
+	BL      runtime·save_g(SB)	// smashes R0
+
+	MOVD	R5, (1*8)(RSP)	// arg0 (ExceptionRecord)
+	MOVD	R6, (2*8)(RSP)	// arg1 (ContextRecord)
+	MOVD	R3, (3*8)(RSP)	// arg2 (original g)
+	MOVD	R3, oldg-(12*8)(SP)
+	BL	(R1)
+	MOVD	oldg-(12*8)(SP), g
+	BL      runtime·save_g(SB)	// smashes R0
+	MOVW	(4*8)(RSP), R0	// return value (0 or -1)
+
+	// if return value is CONTINUE_SEARCH, do not set up control
+	// flow guard workaround
+	CMP	$0, R0
+	BEQ	return
+
+	// Check if we need to set up the control flow guard workaround.
+	// On Windows, the stack pointer in the context must lie within
+	// system stack limits when we resume from exception.
+	// Store the resume SP and PC in alternate registers
+	// and return to sigresume on the g0 stack.
+	// sigresume makes no use of the stack at all,
+	// loading SP from R0 and jumping to R1.
+	// Note that smashing R0 and R1 is only safe because we know sigpanic
+	// will not actually return to the original frame, so the registers
+	// are effectively dead. But this does mean we can't use the
+	// same mechanism for async preemption.
+	MOVD	context-(11*8)(SP), R6
+	MOVD	context_pc(R6), R2		// load PC from context record
+	MOVD	$sigresume<>(SB), R1
+
+	CMP	R1, R2
+	BEQ	return				// do not clobber saved SP/PC
+
+	// Save resume SP and PC into R0, R1.
+	MOVD	context_xsp(R6), R2
+	MOVD	R2, (context_x+0*8)(R6)
+	MOVD	context_pc(R6), R2
+	MOVD	R2, (context_x+1*8)(R6)
+
+	// Set up context record to return to sigresume on g0 stack
+	MOVD	RSP, R2
+	MOVD	R2, context_xsp(R6)
+	MOVD	$sigresume<>(SB), R2
+	MOVD	R2, context_pc(R6)
+
+return:
+	RESTORE_R19_TO_R28(-10*8)		// smashes g
+	RET
+
+// Trampoline to resume execution from exception handler.
+// This is part of the control flow guard workaround.
+// It switches stacks and jumps to the continuation address.
+// R0 and R1 are set above at the end of sigtramp<>
+// in the context that starts executing at sigresume<>.
+TEXT sigresume<>(SB),NOSPLIT|NOFRAME,$0
+	// Important: do not smash LR,
+	// which is set to a live value when handling
+	// a signal by pushing a call to sigpanic onto the stack.
+	MOVD	R0, RSP
+	B	(R1)
+
+TEXT runtime·exceptiontramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+	MOVD	$runtime·exceptionhandler<ABIInternal>(SB), R1
+	B	sigtramp<>(SB)
+
+TEXT runtime·firstcontinuetramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+	MOVD	$runtime·firstcontinuehandler<ABIInternal>(SB), R1
+	B	sigtramp<>(SB)
+
+TEXT runtime·lastcontinuetramp(SB),NOSPLIT|NOFRAME,$0
+	MOVD	$runtime·lastcontinuehandler<ABIInternal>(SB), R1
+	B	sigtramp<>(SB)
+
+GLOBL runtime·cbctxts(SB), NOPTR, $4
+
+TEXT runtime·callbackasm1<ABIInternal>(SB),NOSPLIT,$208-0
+	NO_LOCAL_POINTERS
+
+	// On entry, the trampoline in zcallback_windows_arm64.s left
+	// the callback index in R12 (which is volatile in the C ABI).
+
+	// Save callback register arguments R0-R7.
+	// We do this at the top of the frame so they're contiguous with stack arguments.
+	// The 7*8 setting up R14 looks like a bug but is not: the eighth word
+	// is the space the assembler reserved for our caller's frame pointer,
+	// but we are not called from Go so that space is ours to use,
+	// and we must to be contiguous with the stack arguments.
+	MOVD	$arg0-(7*8)(SP), R14
+	MOVD	R0, (0*8)(R14)
+	MOVD	R1, (1*8)(R14)
+	MOVD	R2, (2*8)(R14)
+	MOVD	R3, (3*8)(R14)
+	MOVD	R4, (4*8)(R14)
+	MOVD	R5, (5*8)(R14)
+	MOVD	R6, (6*8)(R14)
+	MOVD	R7, (7*8)(R14)
+
+	// Push C callee-save registers R19-R28.
+	// LR, FP already saved.
+	SAVE_R19_TO_R28(-18*8)
+
+	// Create a struct callbackArgs on our stack.
+	MOVD	$cbargs-(18*8+callbackArgs__size)(SP), R13
+	MOVD	R12, callbackArgs_index(R13)	// callback index
+	MOVD	R14, R0
+	MOVD	R0, callbackArgs_args(R13)		// address of args vector
+	MOVD	$0, R0
+	MOVD	R0, callbackArgs_result(R13)	// result
+
+	// Call cgocallback, which will call callbackWrap(frame).
+	MOVD	$·callbackWrap(SB), R0	// PC of function to call
+	MOVD	R13, R1	// frame (&callbackArgs{...})
+	MOVD	$0, R2	// context
+	MOVD	R0, (1*8)(RSP)
+	MOVD	R1, (2*8)(RSP)
+	MOVD	R2, (3*8)(RSP)
+	BL	runtime·cgocallback(SB)
+
+	// Get callback result.
+	MOVD	$cbargs-(18*8+callbackArgs__size)(SP), R13
+	MOVD	callbackArgs_result(R13), R0
+
+	RESTORE_R19_TO_R28(-18*8)
+
+	RET
+
+// uint32 tstart_stdcall(M *newm);
+TEXT runtime·tstart_stdcall<ABIInternal>(SB),NOSPLIT,$96-0
+	SAVE_R19_TO_R28(-10*8)
+
+	MOVD	m_g0(R0), g
+	MOVD	R0, g_m(g)
+	BL	runtime·save_g(SB)
+
+	// Set up stack guards for OS stack.
+	MOVD	RSP, R0
+	MOVD	R0, g_stack+stack_hi(g)
+	SUB	$(64*1024), R0
+	MOVD	R0, (g_stack+stack_lo)(g)
+	MOVD	R0, g_stackguard0(g)
+	MOVD	R0, g_stackguard1(g)
+
+	BL	runtime·emptyfunc(SB)	// fault if stack check is wrong
+	BL	runtime·mstart(SB)
+
+	RESTORE_R19_TO_R28(-10*8)
+
+	// Exit the thread.
+	MOVD	$0, R0
+	RET
+
+// Runs on OS stack.
+// duration (in -100ns units) is in dt+0(FP).
+// g may be nil.
+TEXT runtime·usleep2(SB),NOSPLIT,$32-4
+	MOVW	dt+0(FP), R0
+	MOVD	$16(RSP), R2		// R2 = pTime
+	MOVD	R0, 0(R2)		// *pTime = -dt
+	MOVD	$-1, R0			// R0 = handle
+	MOVD	$0, R1			// R1 = FALSE (alertable)
+	MOVD	runtime·_NtWaitForSingleObject(SB), R3
+	SUB	$16, RSP	// skip over saved frame pointer below RSP
+	BL	(R3)
+	ADD	$16, RSP
+	RET
+
+// Runs on OS stack.
+// duration (in -100ns units) is in dt+0(FP).
+// g is valid.
+// TODO: neeeds to be implemented properly.
+TEXT runtime·usleep2HighRes(SB),NOSPLIT,$0-4
+	B	runtime·abort(SB)
+
+// Runs on OS stack.
+TEXT runtime·switchtothread(SB),NOSPLIT,$16-0
+	MOVD	runtime·_SwitchToThread(SB), R0
+	SUB	$16, RSP	// skip over saved frame pointer below RSP
+	BL	(R0)
+	ADD	$16, RSP
+	RET
+
+TEXT runtime·nanotime1(SB),NOSPLIT|NOFRAME,$0-8
+	MOVB	runtime·useQPCTime(SB), R0
+	CMP	$0, R0
+	BNE	useQPC
+	MOVD	$_INTERRUPT_TIME, R3
+loop:
+	MOVWU	time_hi1(R3), R1
+	MOVWU	time_lo(R3), R0
+	MOVWU	time_hi2(R3), R2
+	CMP	R1, R2
+	BNE	loop
+
+	// wintime = R1:R0, multiply by 100
+	ORR	R1<<32, R0
+	MOVD	$100, R1
+	MUL	R1, R0
+	MOVD	R0, ret+0(FP)
+	RET
+useQPC:
+	B	runtime·nanotimeQPC(SB)		// tail call
+
+// This is called from rt0_go, which runs on the system stack
+// using the initial stack allocated by the OS.
+// It calls back into standard C using the BL below.
+TEXT runtime·wintls(SB),NOSPLIT,$0
+	// Allocate a TLS slot to hold g across calls to external code
+	MOVD	runtime·_TlsAlloc(SB), R0
+	SUB	$16, RSP	// skip over saved frame pointer below RSP
+	BL	(R0)
+	ADD	$16, RSP
+
+	// Assert that slot is less than 64 so we can use _TEB->TlsSlots
+	CMP	$64, R0
+	BLT	ok
+	MOVD	$runtime·abort(SB), R1
+	BL	(R1)
+ok:
+
+	// Save offset from R18 into tls_g.
+	LSL	$3, R0
+	ADD	$TEB_TlsSlots, R0
+	MOVD	R0, runtime·tls_g(SB)
+	RET
diff --git a/src/runtime/sys_x86.go b/src/runtime/sys_x86.go
index f917cb8..0866e31 100644
--- a/src/runtime/sys_x86.go
+++ b/src/runtime/sys_x86.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 || 386
 // +build amd64 386
 
 package runtime
@@ -12,13 +13,9 @@
 )
 
 // adjust Gobuf as if it executed a call to fn with context ctxt
-// and then did an immediate gosave.
+// and then stopped before the first instruction in fn.
 func gostartcall(buf *gobuf, fn, ctxt unsafe.Pointer) {
 	sp := buf.sp
-	if sys.RegSize > sys.PtrSize {
-		sp -= sys.PtrSize
-		*(*uintptr)(unsafe.Pointer(sp)) = 0
-	}
 	sp -= sys.PtrSize
 	*(*uintptr)(unsafe.Pointer(sp)) = buf.pc
 	buf.sp = sp
diff --git a/src/runtime/syscall2_solaris.go b/src/runtime/syscall2_solaris.go
index e098e80..3310489 100644
--- a/src/runtime/syscall2_solaris.go
+++ b/src/runtime/syscall2_solaris.go
@@ -15,7 +15,6 @@
 //go:cgo_import_dynamic libc_gethostname gethostname "libc.so"
 //go:cgo_import_dynamic libc_getpid getpid "libc.so"
 //go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
-//go:cgo_import_dynamic libc_pipe pipe "libc.so"
 //go:cgo_import_dynamic libc_setgid setgid "libc.so"
 //go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
 //go:cgo_import_dynamic libc_setsid setsid "libc.so"
@@ -33,7 +32,6 @@
 //go:linkname libc_gethostname libc_gethostname
 //go:linkname libc_getpid libc_getpid
 //go:linkname libc_ioctl libc_ioctl
-//go:linkname libc_pipe libc_pipe
 //go:linkname libc_setgid libc_setgid
 //go:linkname libc_setgroups libc_setgroups
 //go:linkname libc_setsid libc_setsid
diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go
index 7835b49..4763a44 100644
--- a/src/runtime/syscall_windows.go
+++ b/src/runtime/syscall_windows.go
@@ -5,6 +5,7 @@
 package runtime
 
 import (
+	"internal/abi"
 	"runtime/internal/sys"
 	"unsafe"
 )
@@ -21,30 +22,186 @@
 type winCallback struct {
 	fn     *funcval // Go function
 	retPop uintptr  // For 386 cdecl, how many bytes to pop on return
+	abiMap abiDesc
+}
 
-	// abiMap specifies how to translate from a C frame to a Go
-	// frame. This does not specify how to translate back because
-	// the result is always a uintptr. If the C ABI is fastcall,
-	// this assumes the four fastcall registers were first spilled
-	// to the shadow space.
-	abiMap []abiPart
+// abiPartKind is the action an abiPart should take.
+type abiPartKind int
+
+const (
+	abiPartBad   abiPartKind = iota
+	abiPartStack             // Move a value from memory to the stack.
+	abiPartReg               // Move a value from memory to a register.
+)
+
+// abiPart encodes a step in translating between calling ABIs.
+type abiPart struct {
+	kind           abiPartKind
+	srcStackOffset uintptr
+	dstStackOffset uintptr // used if kind == abiPartStack
+	dstRegister    int     // used if kind == abiPartReg
+	len            uintptr
+}
+
+func (a *abiPart) tryMerge(b abiPart) bool {
+	if a.kind != abiPartStack || b.kind != abiPartStack {
+		return false
+	}
+	if a.srcStackOffset+a.len == b.srcStackOffset && a.dstStackOffset+a.len == b.dstStackOffset {
+		a.len += b.len
+		return true
+	}
+	return false
+}
+
+// abiDesc specifies how to translate from a C frame to a Go
+// frame. This does not specify how to translate back because
+// the result is always a uintptr. If the C ABI is fastcall,
+// this assumes the four fastcall registers were first spilled
+// to the shadow space.
+type abiDesc struct {
+	parts []abiPart
+
+	srcStackSize uintptr // stdcall/fastcall stack space tracking
+	dstStackSize uintptr // Go stack space used
+	dstSpill     uintptr // Extra stack space for argument spill slots
+	dstRegisters int     // Go ABI int argument registers used
+
 	// retOffset is the offset of the uintptr-sized result in the Go
 	// frame.
 	retOffset uintptr
 }
 
-// abiPart encodes a step in translating between calling ABIs.
-type abiPart struct {
-	src, dst uintptr
-	len      uintptr
+func (p *abiDesc) assignArg(t *_type) {
+	if t.size > sys.PtrSize {
+		// We don't support this right now. In
+		// stdcall/cdecl, 64-bit ints and doubles are
+		// passed as two words (little endian); and
+		// structs are pushed on the stack. In
+		// fastcall, arguments larger than the word
+		// size are passed by reference. On arm,
+		// 8-byte aligned arguments round up to the
+		// next even register and can be split across
+		// registers and the stack.
+		panic("compileCallback: argument size is larger than uintptr")
+	}
+	if k := t.kind & kindMask; GOARCH != "386" && (k == kindFloat32 || k == kindFloat64) {
+		// In fastcall, floating-point arguments in
+		// the first four positions are passed in
+		// floating-point registers, which we don't
+		// currently spill. arm passes floating-point
+		// arguments in VFP registers, which we also
+		// don't support.
+		// So basically we only support 386.
+		panic("compileCallback: float arguments not supported")
+	}
+
+	if t.size == 0 {
+		// The Go ABI aligns for zero-sized types.
+		p.dstStackSize = alignUp(p.dstStackSize, uintptr(t.align))
+		return
+	}
+
+	// In the C ABI, we're already on a word boundary.
+	// Also, sub-word-sized fastcall register arguments
+	// are stored to the least-significant bytes of the
+	// argument word and all supported Windows
+	// architectures are little endian, so srcStackOffset
+	// is already pointing to the right place for smaller
+	// arguments. The same is true on arm.
+
+	oldParts := p.parts
+	if p.tryRegAssignArg(t, 0) {
+		// Account for spill space.
+		//
+		// TODO(mknyszek): Remove this when we no longer have
+		// caller reserved spill space.
+		p.dstSpill = alignUp(p.dstSpill, uintptr(t.align))
+		p.dstSpill += t.size
+	} else {
+		// Register assignment failed.
+		// Undo the work and stack assign.
+		p.parts = oldParts
+
+		// The Go ABI aligns arguments.
+		p.dstStackSize = alignUp(p.dstStackSize, uintptr(t.align))
+
+		// Copy just the size of the argument. Note that this
+		// could be a small by-value struct, but C and Go
+		// struct layouts are compatible, so we can copy these
+		// directly, too.
+		part := abiPart{
+			kind:           abiPartStack,
+			srcStackOffset: p.srcStackSize,
+			dstStackOffset: p.dstStackSize,
+			len:            t.size,
+		}
+		// Add this step to the adapter.
+		if len(p.parts) == 0 || !p.parts[len(p.parts)-1].tryMerge(part) {
+			p.parts = append(p.parts, part)
+		}
+		// The Go ABI packs arguments.
+		p.dstStackSize += t.size
+	}
+
+	// cdecl, stdcall, fastcall, and arm pad arguments to word size.
+	// TODO(rsc): On arm and arm64 do we need to skip the caller's saved LR?
+	p.srcStackSize += sys.PtrSize
 }
 
-func (a *abiPart) tryMerge(b abiPart) bool {
-	if a.src+a.len == b.src && a.dst+a.len == b.dst {
-		a.len += b.len
+// tryRegAssignArg tries to register-assign a value of type t.
+// If this type is nested in an aggregate type, then offset is the
+// offset of this type within its parent type.
+// Assumes t.size <= sys.PtrSize and t.size != 0.
+//
+// Returns whether the assignment succeeded.
+func (p *abiDesc) tryRegAssignArg(t *_type, offset uintptr) bool {
+	switch k := t.kind & kindMask; k {
+	case kindBool, kindInt, kindInt8, kindInt16, kindInt32, kindUint, kindUint8, kindUint16, kindUint32, kindUintptr, kindPtr, kindUnsafePointer:
+		// Assign a register for all these types.
+		return p.assignReg(t.size, offset)
+	case kindInt64, kindUint64:
+		// Only register-assign if the registers are big enough.
+		if sys.PtrSize == 8 {
+			return p.assignReg(t.size, offset)
+		}
+	case kindArray:
+		at := (*arraytype)(unsafe.Pointer(t))
+		if at.len == 1 {
+			return p.tryRegAssignArg(at.elem, offset)
+		}
+	case kindStruct:
+		st := (*structtype)(unsafe.Pointer(t))
+		for i := range st.fields {
+			f := &st.fields[i]
+			if !p.tryRegAssignArg(f.typ, offset+f.offset()) {
+				return false
+			}
+		}
 		return true
 	}
-	return false
+	// Pointer-sized types such as maps and channels are currently
+	// not supported.
+	panic("compileCallabck: type " + t.string() + " is currently not supported for use in system callbacks")
+}
+
+// assignReg attempts to assign a single register for an
+// argument with the given size, at the given offset into the
+// value in the C ABI space.
+//
+// Returns whether the assignment was successful.
+func (p *abiDesc) assignReg(size, offset uintptr) bool {
+	if p.dstRegisters >= intArgRegs {
+		return false
+	}
+	p.parts = append(p.parts, abiPart{
+		kind:           abiPartReg,
+		srcStackOffset: p.srcStackSize + offset,
+		dstRegister:    p.dstRegisters,
+		len:            size,
+	})
+	p.dstRegisters++
+	return true
 }
 
 type winCallbackKey struct {
@@ -70,8 +227,8 @@
 		panic("unsupported architecture")
 	case "386", "amd64":
 		entrySize = 5
-	case "arm":
-		// On ARM, each entry is a MOV instruction
+	case "arm", "arm64":
+		// On ARM and ARM64, each entry is a MOV instruction
 		// followed by a branch instruction
 		entrySize = 8
 	}
@@ -100,60 +257,14 @@
 	ft := (*functype)(unsafe.Pointer(fn._type))
 
 	// Check arguments and construct ABI translation.
-	var abiMap []abiPart
-	var src, dst uintptr
+	var abiMap abiDesc
 	for _, t := range ft.in() {
-		if t.size > sys.PtrSize {
-			// We don't support this right now. In
-			// stdcall/cdecl, 64-bit ints and doubles are
-			// passed as two words (little endian); and
-			// structs are pushed on the stack. In
-			// fastcall, arguments larger than the word
-			// size are passed by reference. On arm,
-			// 8-byte aligned arguments round up to the
-			// next even register and can be split across
-			// registers and the stack.
-			panic("compileCallback: argument size is larger than uintptr")
-		}
-		if k := t.kind & kindMask; (GOARCH == "amd64" || GOARCH == "arm") && (k == kindFloat32 || k == kindFloat64) {
-			// In fastcall, floating-point arguments in
-			// the first four positions are passed in
-			// floating-point registers, which we don't
-			// currently spill. arm passes floating-point
-			// arguments in VFP registers, which we also
-			// don't support.
-			panic("compileCallback: float arguments not supported")
-		}
-
-		// The Go ABI aligns arguments.
-		dst = alignUp(dst, uintptr(t.align))
-		// In the C ABI, we're already on a word boundary.
-		// Also, sub-word-sized fastcall register arguments
-		// are stored to the least-significant bytes of the
-		// argument word and all supported Windows
-		// architectures are little endian, so src is already
-		// pointing to the right place for smaller arguments.
-		// The same is true on arm.
-
-		// Copy just the size of the argument. Note that this
-		// could be a small by-value struct, but C and Go
-		// struct layouts are compatible, so we can copy these
-		// directly, too.
-		part := abiPart{src, dst, t.size}
-		// Add this step to the adapter.
-		if len(abiMap) == 0 || !abiMap[len(abiMap)-1].tryMerge(part) {
-			abiMap = append(abiMap, part)
-		}
-
-		// cdecl, stdcall, fastcall, and arm pad arguments to word size.
-		src += sys.PtrSize
-		// The Go ABI packs arguments.
-		dst += t.size
+		abiMap.assignArg(t)
 	}
 	// The Go ABI aligns the result to the word size. src is
 	// already aligned.
-	dst = alignUp(dst, sys.PtrSize)
-	retOffset := dst
+	abiMap.dstStackSize = alignUp(abiMap.dstStackSize, sys.PtrSize)
+	abiMap.retOffset = abiMap.dstStackSize
 
 	if len(ft.out()) != 1 {
 		panic("compileCallback: expected function with one uintptr-sized result")
@@ -167,10 +278,18 @@
 		// Either way, it's not AX.
 		panic("compileCallback: float results not supported")
 	}
-	// Make room for the uintptr-sized result.
-	dst += sys.PtrSize
+	if intArgRegs == 0 {
+		// Make room for the uintptr-sized result.
+		// If there are argument registers, the return value will
+		// be passed in the first register.
+		abiMap.dstStackSize += sys.PtrSize
+	}
 
-	if dst > callbackMaxFrame {
+	// TODO(mknyszek): Remove dstSpill from this calculation when we no longer have
+	// caller reserved spill space.
+	frameSize := alignUp(abiMap.dstStackSize, sys.PtrSize)
+	frameSize += abiMap.dstSpill
+	if frameSize > callbackMaxFrame {
 		panic("compileCallback: function argument frame too large")
 	}
 
@@ -178,7 +297,7 @@
 	// arguments from the C stack.
 	var retPop uintptr
 	if cdecl {
-		retPop = src
+		retPop = abiMap.srcStackSize
 	}
 
 	key := winCallbackKey{(*funcval)(fn.data), cdecl}
@@ -200,7 +319,7 @@
 		unlock(&cbs.lock)
 		throw("too many callback functions")
 	}
-	c := winCallback{key.fn, retPop, abiMap, retOffset}
+	c := winCallback{key.fn, retPop, abiMap}
 	cbs.ctxt[n] = c
 	cbs.index[key] = n
 	cbs.n++
@@ -234,18 +353,44 @@
 	a.retPop = c.retPop
 
 	// Convert from C to Go ABI.
+	var regs abi.RegArgs
 	var frame [callbackMaxFrame]byte
 	goArgs := unsafe.Pointer(&frame)
-	for _, part := range c.abiMap {
-		memmove(add(goArgs, part.dst), add(a.args, part.src), part.len)
+	for _, part := range c.abiMap.parts {
+		switch part.kind {
+		case abiPartStack:
+			memmove(add(goArgs, part.dstStackOffset), add(a.args, part.srcStackOffset), part.len)
+		case abiPartReg:
+			goReg := unsafe.Pointer(&regs.Ints[part.dstRegister])
+			memmove(goReg, add(a.args, part.srcStackOffset), part.len)
+		default:
+			panic("bad ABI description")
+		}
 	}
 
+	// TODO(mknyszek): Remove this when we no longer have
+	// caller reserved spill space.
+	frameSize := alignUp(c.abiMap.dstStackSize, sys.PtrSize)
+	frameSize += c.abiMap.dstSpill
+
 	// Even though this is copying back results, we can pass a nil
 	// type because those results must not require write barriers.
-	reflectcall(nil, unsafe.Pointer(c.fn), noescape(goArgs), uint32(c.retOffset)+sys.PtrSize, uint32(c.retOffset))
+	reflectcall(nil, unsafe.Pointer(c.fn), noescape(goArgs), uint32(c.abiMap.dstStackSize), uint32(c.abiMap.retOffset), uint32(frameSize), &regs)
 
 	// Extract the result.
-	a.result = *(*uintptr)(unsafe.Pointer(&frame[c.retOffset]))
+	//
+	// There's always exactly one return value, one pointer in size.
+	// If it's on the stack, then we will have reserved space for it
+	// at the end of the frame, otherwise it was passed in a register.
+	if c.abiMap.dstStackSize != c.abiMap.retOffset {
+		a.result = *(*uintptr)(unsafe.Pointer(&frame[c.abiMap.retOffset]))
+	} else {
+		var zero int
+		// On architectures with no registers, Ints[0] would be a compile error,
+		// so we use a dynamic index. These architectures will never take this
+		// branch, so this won't cause a runtime panic.
+		a.result = regs.Ints[zero]
+	}
 }
 
 const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
@@ -256,6 +401,7 @@
 // to the full path inside of system32 for use with vanilla LoadLibrary.
 //go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary
 //go:nosplit
+//go:cgo_unsafe_args
 func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) {
 	lockOSThread()
 	c := &getg().m.syscall
@@ -286,6 +432,7 @@
 
 //go:linkname syscall_loadlibrary syscall.loadlibrary
 //go:nosplit
+//go:cgo_unsafe_args
 func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
 	lockOSThread()
 	defer unlockOSThread()
@@ -303,6 +450,7 @@
 
 //go:linkname syscall_getprocaddress syscall.getprocaddress
 //go:nosplit
+//go:cgo_unsafe_args
 func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
 	lockOSThread()
 	defer unlockOSThread()
@@ -320,6 +468,7 @@
 
 //go:linkname syscall_Syscall syscall.Syscall
 //go:nosplit
+//go:cgo_unsafe_args
 func syscall_Syscall(fn, nargs, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
 	lockOSThread()
 	defer unlockOSThread()
@@ -333,6 +482,7 @@
 
 //go:linkname syscall_Syscall6 syscall.Syscall6
 //go:nosplit
+//go:cgo_unsafe_args
 func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
 	lockOSThread()
 	defer unlockOSThread()
@@ -346,52 +496,56 @@
 
 //go:linkname syscall_Syscall9 syscall.Syscall9
 //go:nosplit
+//go:cgo_unsafe_args
 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
 	c.args = uintptr(noescape(unsafe.Pointer(&a1)))
 	cgocall(asmstdcallAddr, unsafe.Pointer(c))
+	unlockOSThread()
 	return c.r1, c.r2, c.err
 }
 
 //go:linkname syscall_Syscall12 syscall.Syscall12
 //go:nosplit
+//go:cgo_unsafe_args
 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
 	c.args = uintptr(noescape(unsafe.Pointer(&a1)))
 	cgocall(asmstdcallAddr, unsafe.Pointer(c))
+	unlockOSThread()
 	return c.r1, c.r2, c.err
 }
 
 //go:linkname syscall_Syscall15 syscall.Syscall15
 //go:nosplit
+//go:cgo_unsafe_args
 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
 	c.args = uintptr(noescape(unsafe.Pointer(&a1)))
 	cgocall(asmstdcallAddr, unsafe.Pointer(c))
+	unlockOSThread()
 	return c.r1, c.r2, c.err
 }
 
 //go:linkname syscall_Syscall18 syscall.Syscall18
 //go:nosplit
+//go:cgo_unsafe_args
 func syscall_Syscall18(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 uintptr) (r1, r2, err uintptr) {
 	lockOSThread()
-	defer unlockOSThread()
 	c := &getg().m.syscall
 	c.fn = fn
 	c.n = nargs
 	c.args = uintptr(noescape(unsafe.Pointer(&a1)))
 	cgocall(asmstdcallAddr, unsafe.Pointer(c))
+	unlockOSThread()
 	return c.r1, c.r2, c.err
 }
diff --git a/src/runtime/syscall_windows_test.go b/src/runtime/syscall_windows_test.go
index fb215b3..e3f772a 100644
--- a/src/runtime/syscall_windows_test.go
+++ b/src/runtime/syscall_windows_test.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"fmt"
+	"internal/abi"
 	"internal/syscall/windows/sysdll"
 	"internal/testenv"
 	"io"
@@ -388,6 +389,118 @@
 	{func(i1, i2, i3, i4, i5 uint8Pair) uintptr {
 		return uintptr(i1.x + i1.y + i2.x + i2.y + i3.x + i3.y + i4.x + i4.y + i5.x + i5.y)
 	}},
+	{func(i1, i2, i3, i4, i5, i6, i7, i8, i9 uint32) uintptr {
+		runtime.GC()
+		return uintptr(i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9)
+	}},
+}
+
+//go:registerparams
+func sum2(i1, i2 uintptr) uintptr {
+	return i1 + i2
+}
+
+//go:registerparams
+func sum3(i1, i2, i3 uintptr) uintptr {
+	return i1 + i2 + i3
+}
+
+//go:registerparams
+func sum4(i1, i2, i3, i4 uintptr) uintptr {
+	return i1 + i2 + i3 + i4
+}
+
+//go:registerparams
+func sum5(i1, i2, i3, i4, i5 uintptr) uintptr {
+	return i1 + i2 + i3 + i4 + i5
+}
+
+//go:registerparams
+func sum6(i1, i2, i3, i4, i5, i6 uintptr) uintptr {
+	return i1 + i2 + i3 + i4 + i5 + i6
+}
+
+//go:registerparams
+func sum7(i1, i2, i3, i4, i5, i6, i7 uintptr) uintptr {
+	return i1 + i2 + i3 + i4 + i5 + i6 + i7
+}
+
+//go:registerparams
+func sum8(i1, i2, i3, i4, i5, i6, i7, i8 uintptr) uintptr {
+	return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8
+}
+
+//go:registerparams
+func sum9(i1, i2, i3, i4, i5, i6, i7, i8, i9 uintptr) uintptr {
+	return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9
+}
+
+//go:registerparams
+func sum10(i1, i2, i3, i4, i5, i6, i7, i8, i9, i10 uintptr) uintptr {
+	return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10
+}
+
+//go:registerparams
+func sum9uint8(i1, i2, i3, i4, i5, i6, i7, i8, i9 uint8) uintptr {
+	return uintptr(i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9)
+}
+
+//go:registerparams
+func sum9uint16(i1, i2, i3, i4, i5, i6, i7, i8, i9 uint16) uintptr {
+	return uintptr(i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9)
+}
+
+//go:registerparams
+func sum9int8(i1, i2, i3, i4, i5, i6, i7, i8, i9 int8) uintptr {
+	return uintptr(i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9)
+}
+
+//go:registerparams
+func sum5mix(i1 int8, i2 int16, i3 int32, i4, i5 uintptr) uintptr {
+	return uintptr(i1) + uintptr(i2) + uintptr(i3) + i4 + i5
+}
+
+//go:registerparams
+func sum5andPair(i1, i2, i3, i4, i5 uint8Pair) uintptr {
+	return uintptr(i1.x + i1.y + i2.x + i2.y + i3.x + i3.y + i4.x + i4.y + i5.x + i5.y)
+}
+
+// This test forces a GC. The idea is to have enough arguments
+// that insufficient spill slots allocated (according to the ABI)
+// may cause compiler-generated spills to clobber the return PC.
+// Then, the GC stack scanning will catch that.
+//go:registerparams
+func sum9andGC(i1, i2, i3, i4, i5, i6, i7, i8, i9 uint32) uintptr {
+	runtime.GC()
+	return uintptr(i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9)
+}
+
+// TODO(register args): Remove this once we switch to using the register
+// calling convention by default, since this is redundant with the existing
+// tests.
+var cbFuncsRegABI = []cbFunc{
+	{sum2},
+	{sum3},
+	{sum4},
+	{sum5},
+	{sum6},
+	{sum7},
+	{sum8},
+	{sum9},
+	{sum10},
+	{sum9uint8},
+	{sum9uint16},
+	{sum9int8},
+	{sum5mix},
+	{sum5andPair},
+	{sum9andGC},
+}
+
+func getCallbackTestFuncs() []cbFunc {
+	if regs := runtime.SetIntArgRegs(-1); regs > 0 {
+		return cbFuncsRegABI
+	}
+	return cbFuncs
 }
 
 type cbDLL struct {
@@ -406,7 +519,7 @@
 #include <stdint.h>
 typedef struct { uint8_t x, y; } uint8Pair_t;
 `)
-	for _, cbf := range cbFuncs {
+	for _, cbf := range getCallbackTestFuncs() {
 		cbf.cSrc(f, false)
 		cbf.cSrc(f, true)
 	}
@@ -445,18 +558,17 @@
 	if _, err := exec.LookPath("gcc"); err != nil {
 		t.Skip("skipping test: gcc is missing")
 	}
-	tmp, err := os.MkdirTemp("", "TestCDeclCallback")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer os.RemoveAll(tmp)
+	tmp := t.TempDir()
+
+	oldRegs := runtime.SetIntArgRegs(abi.IntArgRegs)
+	defer runtime.SetIntArgRegs(oldRegs)
 
 	for _, dll := range cbDLLs {
 		t.Run(dll.name, func(t *testing.T) {
 			dllPath := dll.build(t, tmp)
 			dll := syscall.MustLoadDLL(dllPath)
 			defer dll.Release()
-			for _, cbf := range cbFuncs {
+			for _, cbf := range getCallbackTestFuncs() {
 				t.Run(cbf.cName(false), func(t *testing.T) {
 					stdcall := syscall.NewCallback(cbf.goFunc)
 					cbf.testOne(t, dll, false, stdcall)
@@ -601,14 +713,10 @@
    return r;
 }
 `
-	tmpdir, err := os.MkdirTemp("", "TestReturnAfterStackGrowInCallback")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	srcname := "mydll.c"
-	err = os.WriteFile(filepath.Join(tmpdir, srcname), []byte(src), 0)
+	err := os.WriteFile(filepath.Join(tmpdir, srcname), []byte(src), 0)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -651,6 +759,51 @@
 	}
 }
 
+func TestSyscall18(t *testing.T) {
+	if _, err := exec.LookPath("gcc"); err != nil {
+		t.Skip("skipping test: gcc is missing")
+	}
+	if runtime.GOARCH != "amd64" {
+		t.Skipf("skipping test: GOARCH=%s", runtime.GOARCH)
+	}
+
+	const src = `
+#include <stdint.h>
+#include <windows.h>
+
+int cfunc(	int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9,
+			int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18) {
+	return 1;
+}
+`
+	tmpdir := t.TempDir()
+
+	srcname := "mydll.c"
+	err := os.WriteFile(filepath.Join(tmpdir, srcname), []byte(src), 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	outname := "mydll.dll"
+	cmd := exec.Command("gcc", "-shared", "-s", "-Werror", "-o", outname, srcname)
+	cmd.Dir = tmpdir
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("failed to build dll: %v - %v", err, string(out))
+	}
+	dllpath := filepath.Join(tmpdir, outname)
+
+	dll := syscall.MustLoadDLL(dllpath)
+	defer dll.Release()
+
+	proc := dll.MustFindProc("cfunc")
+
+	// proc.Call() will call Syscall18() internally.
+	r, _, err := proc.Call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)
+	if r != 1 {
+		t.Errorf("got %d want 1 (err=%v)", r, err)
+	}
+}
+
 func TestFloatArgs(t *testing.T) {
 	if _, err := exec.LookPath("gcc"); err != nil {
 		t.Skip("skipping test: gcc is missing")
@@ -670,14 +823,10 @@
 	return 0;
 }
 `
-	tmpdir, err := os.MkdirTemp("", "TestFloatArgs")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	srcname := "mydll.c"
-	err = os.WriteFile(filepath.Join(tmpdir, srcname), []byte(src), 0)
+	err := os.WriteFile(filepath.Join(tmpdir, srcname), []byte(src), 0)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -732,14 +881,10 @@
 	return 0;
 }
 `
-	tmpdir, err := os.MkdirTemp("", "TestFloatReturn")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	srcname := "mydll.c"
-	err = os.WriteFile(filepath.Join(tmpdir, srcname), []byte(src), 0)
+	err := os.WriteFile(filepath.Join(tmpdir, srcname), []byte(src), 0)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -947,16 +1092,7 @@
 		t.Skip("skipping test: gcc is missing")
 	}
 
-	tmpdir, err := os.MkdirTemp("", "TestDLLPreloadMitigation")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer func() {
-		err := os.RemoveAll(tmpdir)
-		if err != nil {
-			t.Error(err)
-		}
-	}()
+	tmpdir := t.TempDir()
 
 	dir0, err := os.Getwd()
 	if err != nil {
@@ -1034,11 +1170,7 @@
 		t.Fatal("Abs failed: ", err)
 	}
 
-	tmpdir, err := os.MkdirTemp("", "TestBigStackCallback")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := t.TempDir()
 
 	outname := "mydll.dll"
 	cmd := exec.Command("gcc", "-shared", "-s", "-Werror", "-o", outname, srcname)
@@ -1183,14 +1315,10 @@
 }
 
 func BenchmarkRunningGoProgram(b *testing.B) {
-	tmpdir, err := os.MkdirTemp("", "BenchmarkRunningGoProgram")
-	if err != nil {
-		b.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmpdir := b.TempDir()
 
 	src := filepath.Join(tmpdir, "main.go")
-	err = os.WriteFile(src, []byte(benchmarkRunningGoProgram), 0666)
+	err := os.WriteFile(src, []byte(benchmarkRunningGoProgram), 0666)
 	if err != nil {
 		b.Fatal(err)
 	}
diff --git a/src/runtime/testdata/testprog/checkptr.go b/src/runtime/testdata/testprog/checkptr.go
index e0a2794..9c55613 100644
--- a/src/runtime/testdata/testprog/checkptr.go
+++ b/src/runtime/testdata/testprog/checkptr.go
@@ -4,15 +4,22 @@
 
 package main
 
-import "unsafe"
+import (
+	"runtime"
+	"time"
+	"unsafe"
+)
 
 func init() {
 	register("CheckPtrAlignmentNoPtr", CheckPtrAlignmentNoPtr)
 	register("CheckPtrAlignmentPtr", CheckPtrAlignmentPtr)
+	register("CheckPtrAlignmentNilPtr", CheckPtrAlignmentNilPtr)
 	register("CheckPtrArithmetic", CheckPtrArithmetic)
 	register("CheckPtrArithmetic2", CheckPtrArithmetic2)
 	register("CheckPtrSize", CheckPtrSize)
 	register("CheckPtrSmall", CheckPtrSmall)
+	register("CheckPtrSliceOK", CheckPtrSliceOK)
+	register("CheckPtrSliceFail", CheckPtrSliceFail)
 }
 
 func CheckPtrAlignmentNoPtr() {
@@ -27,6 +34,35 @@
 	sink2 = (**int64)(unsafe.Pointer(uintptr(p) + 1))
 }
 
+// CheckPtrAlignmentNilPtr tests that checkptrAlignment doesn't crash
+// on nil pointers (#47430).
+func CheckPtrAlignmentNilPtr() {
+	var do func(int)
+	do = func(n int) {
+		// Inflate the stack so runtime.shrinkstack gets called during GC
+		if n > 0 {
+			do(n - 1)
+		}
+
+		var p unsafe.Pointer
+		_ = (*int)(p)
+	}
+
+	go func() {
+		for {
+			runtime.GC()
+		}
+	}()
+
+	go func() {
+		for i := 0; ; i++ {
+			do(i % 1024)
+		}
+	}()
+
+	time.Sleep(time.Second)
+}
+
 func CheckPtrArithmetic() {
 	var x int
 	i := uintptr(unsafe.Pointer(&x))
@@ -49,3 +85,14 @@
 func CheckPtrSmall() {
 	sink2 = unsafe.Pointer(uintptr(1))
 }
+
+func CheckPtrSliceOK() {
+	p := new([4]int64)
+	sink2 = unsafe.Slice(&p[1], 3)
+}
+
+func CheckPtrSliceFail() {
+	p := new(int64)
+	sink2 = p
+	sink2 = unsafe.Slice(p, 100)
+}
diff --git a/src/runtime/testdata/testprog/crashdump.go b/src/runtime/testdata/testprog/crashdump.go
new file mode 100644
index 0000000..bced397
--- /dev/null
+++ b/src/runtime/testdata/testprog/crashdump.go
@@ -0,0 +1,47 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"os"
+	"runtime"
+)
+
+func init() {
+	register("CrashDumpsAllThreads", CrashDumpsAllThreads)
+}
+
+func CrashDumpsAllThreads() {
+	const count = 4
+	runtime.GOMAXPROCS(count + 1)
+
+	chans := make([]chan bool, count)
+	for i := range chans {
+		chans[i] = make(chan bool)
+		go crashDumpsAllThreadsLoop(i, chans[i])
+	}
+
+	// Wait for all the goroutines to start executing.
+	for _, c := range chans {
+		<-c
+	}
+
+	// Tell our parent that all the goroutines are executing.
+	if _, err := os.NewFile(3, "pipe").WriteString("x"); err != nil {
+		fmt.Fprintf(os.Stderr, "write to pipe failed: %v\n", err)
+		os.Exit(2)
+	}
+
+	select {}
+}
+
+func crashDumpsAllThreadsLoop(i int, c chan bool) {
+	close(c)
+	for {
+		for j := 0; j < 0x7fffffff; j++ {
+		}
+	}
+}
diff --git a/src/runtime/testdata/testprogcgo/aprof.go b/src/runtime/testdata/testprogcgo/aprof.go
index aabca9e..44a15b0 100644
--- a/src/runtime/testdata/testprogcgo/aprof.go
+++ b/src/runtime/testdata/testprogcgo/aprof.go
@@ -10,7 +10,7 @@
 // The test fails when the function is the first C function.
 // The exported functions are the first C functions, so we use that.
 
-// extern void GoNop();
+// extern void CallGoNop();
 import "C"
 
 import (
@@ -38,7 +38,7 @@
 					break
 				}
 			}
-			C.GoNop()
+			C.CallGoNop()
 		}
 		c <- true
 	}()
diff --git a/src/runtime/testdata/testprogcgo/aprof_c.c b/src/runtime/testdata/testprogcgo/aprof_c.c
new file mode 100644
index 0000000..d588e13
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/aprof_c.c
@@ -0,0 +1,9 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "_cgo_export.h"
+
+void CallGoNop() {
+	GoNop();
+}
diff --git a/src/runtime/testdata/testprogcgo/bigstack1_windows.c b/src/runtime/testdata/testprogcgo/bigstack1_windows.c
new file mode 100644
index 0000000..551fb68
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/bigstack1_windows.c
@@ -0,0 +1,12 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This is not in bigstack_windows.c because it needs to be part of
+// testprogcgo but is not part of the DLL built from bigstack_windows.c.
+
+#include "_cgo_export.h"
+
+void CallGoBigStack1(char* p) {
+	goBigStack1(p);
+}
diff --git a/src/runtime/testdata/testprogcgo/bigstack_windows.go b/src/runtime/testdata/testprogcgo/bigstack_windows.go
index f58fcf9..135b5fc 100644
--- a/src/runtime/testdata/testprogcgo/bigstack_windows.go
+++ b/src/runtime/testdata/testprogcgo/bigstack_windows.go
@@ -6,7 +6,7 @@
 
 /*
 typedef void callback(char*);
-extern void goBigStack1(char*);
+extern void CallGoBigStack1(char*);
 extern void bigStack(callback*);
 */
 import "C"
@@ -18,7 +18,7 @@
 func BigStack() {
 	// Create a large thread stack and call back into Go to test
 	// if Go correctly determines the stack bounds.
-	C.bigStack((*C.callback)(C.goBigStack1))
+	C.bigStack((*C.callback)(C.CallGoBigStack1))
 }
 
 //export goBigStack1
diff --git a/src/runtime/testdata/testprogcgo/tracebackctxt.go b/src/runtime/testdata/testprogcgo/tracebackctxt.go
index 51fa4ad..62ff8ec 100644
--- a/src/runtime/testdata/testprogcgo/tracebackctxt.go
+++ b/src/runtime/testdata/testprogcgo/tracebackctxt.go
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// The __attribute__((weak)) used below doesn't seem to work on Windows.
-
 package main
 
 // Test the context argument to SetCgoTraceback.
@@ -14,20 +12,24 @@
 extern void C1(void);
 extern void C2(void);
 extern void tcContext(void*);
+extern void tcContextSimple(void*);
 extern void tcTraceback(void*);
 extern void tcSymbolizer(void*);
 extern int getContextCount(void);
+extern void TracebackContextPreemptionCallGo(int);
 */
 import "C"
 
 import (
 	"fmt"
 	"runtime"
+	"sync"
 	"unsafe"
 )
 
 func init() {
 	register("TracebackContext", TracebackContext)
+	register("TracebackContextPreemption", TracebackContextPreemption)
 }
 
 var tracebackOK bool
@@ -105,3 +107,30 @@
 		tracebackOK = false
 	}
 }
+
+// Issue 47441.
+func TracebackContextPreemption() {
+	runtime.SetCgoTraceback(0, unsafe.Pointer(C.tcTraceback), unsafe.Pointer(C.tcContextSimple), unsafe.Pointer(C.tcSymbolizer))
+
+	const funcs = 10
+	const calls = 1e5
+	var wg sync.WaitGroup
+	for i := 0; i < funcs; i++ {
+		wg.Add(1)
+		go func(i int) {
+			defer wg.Done()
+			for j := 0; j < calls; j++ {
+				C.TracebackContextPreemptionCallGo(C.int(i*calls + j))
+			}
+		}(i)
+	}
+	wg.Wait()
+
+	fmt.Println("OK")
+}
+
+//export TracebackContextPreemptionGoFunction
+func TracebackContextPreemptionGoFunction(i C.int) {
+	// Do some busy work.
+	fmt.Sprintf("%d\n", i)
+}
diff --git a/src/runtime/testdata/testprogcgo/tracebackctxt_c.c b/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
index 900cada..910cb7b 100644
--- a/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
+++ b/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
@@ -11,6 +11,7 @@
 // Functions exported from Go.
 extern void G1(void);
 extern void G2(void);
+extern void TracebackContextPreemptionGoFunction(int);
 
 void C1() {
 	G1();
@@ -62,10 +63,17 @@
 	}
 }
 
+void tcContextSimple(void* parg) {
+	struct cgoContextArg* arg = (struct cgoContextArg*)(parg);
+	if (arg->context == 0) {
+		arg->context = 1;
+	}
+}
+
 void tcTraceback(void* parg) {
 	int base, i;
 	struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
-	if (arg->context == 0) {
+	if (arg->context == 0 && arg->sigContext == 0) {
 		// This shouldn't happen in this program.
 		abort();
 	}
@@ -89,3 +97,7 @@
 	arg->func = "cFunction";
 	arg->lineno = arg->pc + (arg->more << 16);
 }
+
+void TracebackContextPreemptionCallGo(int i) {
+	TracebackContextPreemptionGoFunction(i);
+}
diff --git a/src/runtime/testdata/testprogcgo/windows/win.go b/src/runtime/testdata/testprogcgo/windows/win.go
index f2eabb9..12488aa 100644
--- a/src/runtime/testdata/testprogcgo/windows/win.go
+++ b/src/runtime/testdata/testprogcgo/windows/win.go
@@ -1,7 +1,7 @@
 package windows
 
 /*
-#cgo CFLAGS: -mnop-fun-dllimport
+#cgo amd64 386 CFLAGS: -mnop-fun-dllimport
 
 #include <windows.h>
 
diff --git a/src/runtime/testdata/testwinlibsignal/dummy.go b/src/runtime/testdata/testwinlibsignal/dummy.go
index 82dfd91..e610f15 100644
--- a/src/runtime/testdata/testwinlibsignal/dummy.go
+++ b/src/runtime/testdata/testwinlibsignal/dummy.go
@@ -1,7 +1,10 @@
+//go:build windows
 // +build windows
 
 package main
 
+import "C"
+
 //export Dummy
 func Dummy() int {
 	return 42
diff --git a/src/runtime/testdata/testwinlibsignal/main.c b/src/runtime/testdata/testwinlibsignal/main.c
index 1787fef..37f2482 100644
--- a/src/runtime/testdata/testwinlibsignal/main.c
+++ b/src/runtime/testdata/testwinlibsignal/main.c
@@ -19,13 +19,13 @@
 {
     waitForCtrlBreakEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
     if (!waitForCtrlBreakEvent) {
-        fprintf(stderr, "ERROR: Could not create event");
+        fprintf(stderr, "ERROR: Could not create event\n");
         return 1;
     }
 
     if (!SetConsoleCtrlHandler(CtrlHandler, TRUE))
     {
-        fprintf(stderr, "ERROR: Could not set control handler");
+        fprintf(stderr, "ERROR: Could not set control handler\n");
         return 1;
     }
 
@@ -34,7 +34,14 @@
     // This way the library handler gets called first.
     HMODULE dummyDll = LoadLibrary("dummy.dll");
     if (!dummyDll) {
-        fprintf(stderr, "ERROR: Could not load dummy.dll");
+        fprintf(stderr, "ERROR: Could not load dummy.dll\n");
+        return 1;
+    }
+
+    // Call the Dummy function so that Go initialization completes, since
+    // all cgo entry points call out to _cgo_wait_runtime_init_done.
+    if (((int(*)(void))GetProcAddress(dummyDll, "Dummy"))() != 42) {
+        fprintf(stderr, "ERROR: Dummy function did not return 42\n");
         return 1;
     }
 
@@ -42,7 +49,7 @@
     fflush(stdout);
 
     if (WaitForSingleObject(waitForCtrlBreakEvent, 5000) != WAIT_OBJECT_0) {
-        fprintf(stderr, "FAILURE: No signal received");
+        fprintf(stderr, "FAILURE: No signal received\n");
         return 1;
     }
 
diff --git a/src/runtime/testdata/testwinsignal/main.go b/src/runtime/testdata/testwinsignal/main.go
index d8cd884..1e7c947 100644
--- a/src/runtime/testdata/testwinsignal/main.go
+++ b/src/runtime/testdata/testwinsignal/main.go
@@ -1,19 +1,19 @@
-package main

-

-import (

-	"fmt"

-	"os"

-	"os/signal"

-	"time"

-)

-

-func main() {

-	c := make(chan os.Signal, 1)

-	signal.Notify(c)

-

-	fmt.Println("ready")

-	sig := <-c

-

-	time.Sleep(time.Second)

-	fmt.Println(sig)

-}

+package main
+
+import (
+	"fmt"
+	"os"
+	"os/signal"
+	"time"
+)
+
+func main() {
+	c := make(chan os.Signal, 1)
+	signal.Notify(c)
+
+	fmt.Println("ready")
+	sig := <-c
+
+	time.Sleep(time.Second)
+	fmt.Println(sig)
+}
diff --git a/src/runtime/textflag.h b/src/runtime/textflag.h
index daca36d..214075e 100644
--- a/src/runtime/textflag.h
+++ b/src/runtime/textflag.h
@@ -32,6 +32,8 @@
 #define NOFRAME 512
 // Function can call reflect.Type.Method or reflect.Type.MethodByName.
 #define REFLECTMETHOD 1024
-// Function is the top of the call stack. Call stack unwinders should stop
-// at this function.
+// Function is the outermost frame of the call stack. Call stack unwinders
+// should stop at this function.
 #define TOPFRAME 2048
+// Function is an ABI wrapper.
+#define ABIWRAPPER 4096
diff --git a/src/runtime/time.go b/src/runtime/time.go
index dee6a67..666b242 100644
--- a/src/runtime/time.go
+++ b/src/runtime/time.go
@@ -333,7 +333,6 @@
 				// Must fetch t.pp before setting status
 				// to timerDeleted.
 				tpp := t.pp.ptr()
-				atomic.Xadd(&tpp.adjustTimers, -1)
 				if !atomic.Cas(&t.status, timerModifying, timerDeleted) {
 					badTimer()
 				}
@@ -510,20 +509,9 @@
 
 		tpp := t.pp.ptr()
 
-		// Update the adjustTimers field.  Subtract one if we
-		// are removing a timerModifiedEarlier, add one if we
-		// are adding a timerModifiedEarlier.
-		adjust := int32(0)
-		if status == timerModifiedEarlier {
-			adjust--
-		}
 		if newStatus == timerModifiedEarlier {
-			adjust++
 			updateTimerModifiedEarliest(tpp, when)
 		}
-		if adjust != 0 {
-			atomic.Xadd(&tpp.adjustTimers, adjust)
-		}
 
 		// Set the new status of the timer.
 		if !atomic.Cas(&t.status, timerModifying, newStatus) {
@@ -591,9 +579,6 @@
 			// Move t to the right position.
 			dodeltimer0(pp)
 			doaddtimer(pp, t)
-			if s == timerModifiedEarlier {
-				atomic.Xadd(&pp.adjustTimers, -1)
-			}
 			if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
 				badTimer()
 			}
@@ -664,37 +649,23 @@
 // it also moves timers that have been modified to run later,
 // and removes deleted timers. The caller must have locked the timers for pp.
 func adjusttimers(pp *p, now int64) {
-	if atomic.Load(&pp.adjustTimers) == 0 {
-		if verifyTimers {
-			verifyTimerHeap(pp)
-		}
-		// There are no timers to adjust, so it is safe to clear
-		// timerModifiedEarliest. Do so in case it is stale.
-		// Everything will work if we don't do this,
-		// but clearing here may save future calls to adjusttimers.
-		atomic.Store64(&pp.timerModifiedEarliest, 0)
-		return
-	}
-
 	// If we haven't yet reached the time of the first timerModifiedEarlier
 	// timer, don't do anything. This speeds up programs that adjust
 	// a lot of timers back and forth if the timers rarely expire.
 	// We'll postpone looking through all the adjusted timers until
 	// one would actually expire.
-	if first := atomic.Load64(&pp.timerModifiedEarliest); first != 0 {
-		if int64(first) > now {
-			if verifyTimers {
-				verifyTimerHeap(pp)
-			}
-			return
+	first := atomic.Load64(&pp.timerModifiedEarliest)
+	if first == 0 || int64(first) > now {
+		if verifyTimers {
+			verifyTimerHeap(pp)
 		}
-
-		// We are going to clear all timerModifiedEarlier timers.
-		atomic.Store64(&pp.timerModifiedEarliest, 0)
+		return
 	}
 
+	// We are going to clear all timerModifiedEarlier timers.
+	atomic.Store64(&pp.timerModifiedEarliest, 0)
+
 	var moved []*timer
-loop:
 	for i := 0; i < len(pp.timers); i++ {
 		t := pp.timers[i]
 		if t.pp.ptr() != pp {
@@ -721,11 +692,6 @@
 				// loop to skip some other timer.
 				dodeltimer(pp, i)
 				moved = append(moved, t)
-				if s == timerModifiedEarlier {
-					if n := atomic.Xadd(&pp.adjustTimers, -1); int32(n) <= 0 {
-						break loop
-					}
-				}
 				// Look at this heap position again.
 				i--
 			}
@@ -824,9 +790,6 @@
 			t.when = t.nextwhen
 			dodeltimer0(pp)
 			doaddtimer(pp, t)
-			if s == timerModifiedEarlier {
-				atomic.Xadd(&pp.adjustTimers, -1)
-			}
 			if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
 				badTimer()
 			}
@@ -921,7 +884,6 @@
 	atomic.Store64(&pp.timerModifiedEarliest, 0)
 
 	cdel := int32(0)
-	cearlier := int32(0)
 	to := 0
 	changedHeap := false
 	timers := pp.timers
@@ -946,9 +908,6 @@
 					if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
 						badTimer()
 					}
-					if s == timerModifiedEarlier {
-						cearlier++
-					}
 					continue nextTimer
 				}
 			case timerDeleted:
@@ -985,7 +944,6 @@
 
 	atomic.Xadd(&pp.deletedTimers, -cdel)
 	atomic.Xadd(&pp.numTimers, -cdel)
-	atomic.Xadd(&pp.adjustTimers, -cearlier)
 
 	timers = timers[:to]
 	pp.timers = timers
diff --git a/src/runtime/time_fake.go b/src/runtime/time_fake.go
index c64d299..c790fab 100644
--- a/src/runtime/time_fake.go
+++ b/src/runtime/time_fake.go
@@ -2,20 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build faketime
-// +build !windows
+//go:build faketime && !windows
+// +build faketime,!windows
 
-// Faketime isn't currently supported on Windows. This would require:
-//
-// 1. Shadowing time_now, which is implemented in assembly on Windows.
-//    Since that's exported directly to the time package from runtime
-//    assembly, this would involve moving it from sys_windows_*.s into
-//    its own assembly files build-tagged with !faketime and using the
-//    implementation of time_now from timestub.go in faketime mode.
-//
-// 2. Modifying syscall.Write to call syscall.faketimeWrite,
-//    translating the Stdout and Stderr handles into FDs 1 and 2.
-//    (See CL 192739 PS 3.)
+// Faketime isn't currently supported on Windows. This would require
+// modifying syscall.Write to call syscall.faketimeWrite,
+// translating the Stdout and Stderr handles into FDs 1 and 2.
+// (See CL 192739 PS 3.)
 
 package runtime
 
@@ -44,8 +37,9 @@
 	return faketime
 }
 
-func walltime() (sec int64, nsec int32) {
-	return faketime / 1000000000, int32(faketime % 1000000000)
+//go:linkname time_now time.now
+func time_now() (sec int64, nsec int32, mono int64) {
+	return faketime / 1e9, int32(faketime % 1e9), faketime
 }
 
 func write(fd uintptr, p unsafe.Pointer, n int32) int32 {
diff --git a/src/runtime/time_linux_amd64.s b/src/runtime/time_linux_amd64.s
new file mode 100644
index 0000000..0dd7919
--- /dev/null
+++ b/src/runtime/time_linux_amd64.s
@@ -0,0 +1,97 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !faketime
+// +build !faketime
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "textflag.h"
+
+#define SYS_clock_gettime	228
+
+// func time.now() (sec int64, nsec int32, mono int64)
+TEXT time·now(SB),NOSPLIT,$16-24
+	MOVQ	SP, R12 // Save old SP; R12 unchanged by C code.
+
+#ifdef GOEXPERIMENT_regabig
+	MOVQ	g_m(R14), BX // BX unchanged by C code.
+#else
+	get_tls(CX)
+	MOVQ	g(CX), AX
+	MOVQ	g_m(AX), BX // BX unchanged by C code.
+#endif
+
+	// Store CLOCK_REALTIME results directly to return space.
+	LEAQ	sec+0(FP), SI
+
+	// Set vdsoPC and vdsoSP for SIGPROF traceback.
+	// Save the old values on stack and restore them on exit,
+	// so this function is reentrant.
+	MOVQ	m_vdsoPC(BX), CX
+	MOVQ	m_vdsoSP(BX), DX
+	MOVQ	CX, 0(SP)
+	MOVQ	DX, 8(SP)
+
+	MOVQ	-8(SI), CX	// Sets CX to function return address.
+	MOVQ	CX, m_vdsoPC(BX)
+	MOVQ	SI, m_vdsoSP(BX)
+
+#ifdef GOEXPERIMENT_regabig
+	CMPQ	R14, m_curg(BX)	// Only switch if on curg.
+#else
+	CMPQ	AX, m_curg(BX)	// Only switch if on curg.
+#endif
+	JNE	noswitch
+
+	MOVQ	m_g0(BX), DX
+	MOVQ	(g_sched+gobuf_sp)(DX), SP	// Set SP to g0 stack
+
+noswitch:
+	SUBQ	$16, SP		// Space for monotonic time results
+	ANDQ	$~15, SP	// Align for C code
+
+	MOVL	$0, DI // CLOCK_REALTIME
+	MOVQ	runtime·vdsoClockgettimeSym(SB), AX
+	CMPQ	AX, $0
+	JEQ	fallback
+	CALL	AX
+
+	MOVL	$1, DI // CLOCK_MONOTONIC
+	LEAQ	0(SP), SI
+	MOVQ	runtime·vdsoClockgettimeSym(SB), AX
+	CALL	AX
+
+ret:
+	MOVQ	0(SP), AX	// sec
+	MOVQ	8(SP), DX	// nsec
+
+	MOVQ	R12, SP		// Restore real SP
+	// Restore vdsoPC, vdsoSP
+	// We don't worry about being signaled between the two stores.
+	// If we are not in a signal handler, we'll restore vdsoSP to 0,
+	// and no one will care about vdsoPC. If we are in a signal handler,
+	// we cannot receive another signal.
+	MOVQ	8(SP), CX
+	MOVQ	CX, m_vdsoSP(BX)
+	MOVQ	0(SP), CX
+	MOVQ	CX, m_vdsoPC(BX)
+
+	// sec is in AX, nsec in DX
+	// return nsec in AX
+	IMULQ	$1000000000, AX
+	ADDQ	DX, AX
+	MOVQ	AX, mono+16(FP)
+	RET
+
+fallback:
+	MOVQ	$SYS_clock_gettime, AX
+	SYSCALL
+
+	MOVL	$1, DI // CLOCK_MONOTONIC
+	LEAQ	0(SP), SI
+	MOVQ	$SYS_clock_gettime, AX
+	SYSCALL
+
+	JMP	ret
diff --git a/src/runtime/time_nofake.go b/src/runtime/time_nofake.go
index 1912a94..5a4ceaf 100644
--- a/src/runtime/time_nofake.go
+++ b/src/runtime/time_nofake.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !faketime
 // +build !faketime
 
 package runtime
@@ -19,10 +20,6 @@
 	return nanotime1()
 }
 
-func walltime() (sec int64, nsec int32) {
-	return walltime1()
-}
-
 // write must be nosplit on Windows (see write1)
 //
 //go:nosplit
diff --git a/src/runtime/time_windows.h b/src/runtime/time_windows.h
new file mode 100644
index 0000000..cd16fd1
--- /dev/null
+++ b/src/runtime/time_windows.h
@@ -0,0 +1,16 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Constants for fetching time values on Windows for use in asm code.
+
+// See https://wrkhpi.wordpress.com/2007/08/09/getting-os-information-the-kuser_shared_data-structure/
+// Archived copy at:
+// http://web.archive.org/web/20210411000829/https://wrkhpi.wordpress.com/2007/08/09/getting-os-information-the-kuser_shared_data-structure/
+
+// Must read hi1, then lo, then hi2. The snapshot is valid if hi1 == hi2.
+#define _INTERRUPT_TIME 0x7ffe0008
+#define _SYSTEM_TIME 0x7ffe0014
+#define time_lo 0
+#define time_hi1 4
+#define time_hi2 8
diff --git a/src/runtime/time_windows_386.s b/src/runtime/time_windows_386.s
new file mode 100644
index 0000000..19ce691
--- /dev/null
+++ b/src/runtime/time_windows_386.s
@@ -0,0 +1,85 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !faketime
+// +build !faketime
+
+#include "go_asm.h"
+#include "textflag.h"
+#include "time_windows.h"
+
+TEXT time·now(SB),NOSPLIT,$0-20
+	CMPB	runtime·useQPCTime(SB), $0
+	JNE	useQPC
+loop:
+	MOVL	(_INTERRUPT_TIME+time_hi1), AX
+	MOVL	(_INTERRUPT_TIME+time_lo), CX
+	MOVL	(_INTERRUPT_TIME+time_hi2), DI
+	CMPL	AX, DI
+	JNE	loop
+
+	// w = DI:CX
+	// multiply by 100
+	MOVL	$100, AX
+	MULL	CX
+	IMULL	$100, DI
+	ADDL	DI, DX
+	// w*100 = DX:AX
+	MOVL	AX, mono+12(FP)
+	MOVL	DX, mono+16(FP)
+
+wall:
+	MOVL	(_SYSTEM_TIME+time_hi1), CX
+	MOVL	(_SYSTEM_TIME+time_lo), AX
+	MOVL	(_SYSTEM_TIME+time_hi2), DX
+	CMPL	CX, DX
+	JNE	wall
+
+	// w = DX:AX
+	// convert to Unix epoch (but still 100ns units)
+	#define delta 116444736000000000
+	SUBL	$(delta & 0xFFFFFFFF), AX
+	SBBL $(delta >> 32), DX
+
+	// nano/100 = DX:AX
+	// split into two decimal halves by div 1e9.
+	// (decimal point is two spots over from correct place,
+	// but we avoid overflow in the high word.)
+	MOVL	$1000000000, CX
+	DIVL	CX
+	MOVL	AX, DI
+	MOVL	DX, SI
+
+	// DI = nano/100/1e9 = nano/1e11 = sec/100, DX = SI = nano/100%1e9
+	// split DX into seconds and nanoseconds by div 1e7 magic multiply.
+	MOVL	DX, AX
+	MOVL	$1801439851, CX
+	MULL	CX
+	SHRL	$22, DX
+	MOVL	DX, BX
+	IMULL	$10000000, DX
+	MOVL	SI, CX
+	SUBL	DX, CX
+
+	// DI = sec/100 (still)
+	// BX = (nano/100%1e9)/1e7 = (nano/1e9)%100 = sec%100
+	// CX = (nano/100%1e9)%1e7 = (nano%1e9)/100 = nsec/100
+	// store nsec for return
+	IMULL	$100, CX
+	MOVL	CX, nsec+8(FP)
+
+	// DI = sec/100 (still)
+	// BX = sec%100
+	// construct DX:AX = 64-bit sec and store for return
+	MOVL	$0, DX
+	MOVL	$100, AX
+	MULL	DI
+	ADDL	BX, AX
+	ADCL	$0, DX
+	MOVL	AX, sec+0(FP)
+	MOVL	DX, sec+4(FP)
+	RET
+useQPC:
+	JMP	runtime·nowQPC(SB)
+	RET
diff --git a/src/runtime/time_windows_amd64.s b/src/runtime/time_windows_amd64.s
new file mode 100644
index 0000000..93ab960
--- /dev/null
+++ b/src/runtime/time_windows_amd64.s
@@ -0,0 +1,56 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !faketime
+// +build !faketime
+
+#include "go_asm.h"
+#include "textflag.h"
+#include "time_windows.h"
+
+TEXT time·now(SB),NOSPLIT,$0-24
+	CMPB	runtime·useQPCTime(SB), $0
+	JNE	useQPC
+	MOVQ	$_INTERRUPT_TIME, DI
+loop:
+	MOVL	time_hi1(DI), AX
+	MOVL	time_lo(DI), BX
+	MOVL	time_hi2(DI), CX
+	CMPL	AX, CX
+	JNE	loop
+	SHLQ	$32, AX
+	ORQ	BX, AX
+	IMULQ	$100, AX
+	MOVQ	AX, mono+16(FP)
+
+	MOVQ	$_SYSTEM_TIME, DI
+wall:
+	MOVL	time_hi1(DI), AX
+	MOVL	time_lo(DI), BX
+	MOVL	time_hi2(DI), CX
+	CMPL	AX, CX
+	JNE	wall
+	SHLQ	$32, AX
+	ORQ	BX, AX
+	MOVQ	$116444736000000000, DI
+	SUBQ	DI, AX
+	IMULQ	$100, AX
+
+	// generated code for
+	//	func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
+	// adapted to reduce duplication
+	MOVQ	AX, CX
+	MOVQ	$1360296554856532783, AX
+	MULQ	CX
+	ADDQ	CX, DX
+	RCRQ	$1, DX
+	SHRQ	$29, DX
+	MOVQ	DX, sec+0(FP)
+	IMULQ	$1000000000, DX
+	SUBQ	DX, CX
+	MOVL	CX, nsec+8(FP)
+	RET
+useQPC:
+	JMP	runtime·nowQPC(SB)
+	RET
diff --git a/src/runtime/time_windows_arm.s b/src/runtime/time_windows_arm.s
new file mode 100644
index 0000000..7c763b6
--- /dev/null
+++ b/src/runtime/time_windows_arm.s
@@ -0,0 +1,87 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !faketime
+// +build !faketime
+
+#include "go_asm.h"
+#include "textflag.h"
+#include "time_windows.h"
+
+TEXT time·now(SB),NOSPLIT|NOFRAME,$0-20
+	MOVW    $0, R0
+	MOVB    runtime·useQPCTime(SB), R0
+	CMP	$0, R0
+	BNE	useQPC
+	MOVW	$_INTERRUPT_TIME, R3
+loop:
+	MOVW	time_hi1(R3), R1
+	MOVW	time_lo(R3), R0
+	MOVW	time_hi2(R3), R2
+	CMP	R1, R2
+	BNE	loop
+
+	// wintime = R1:R0, multiply by 100
+	MOVW	$100, R2
+	MULLU	R0, R2, (R4, R3)    // R4:R3 = R1:R0 * R2
+	MULA	R1, R2, R4, R4
+
+	// wintime*100 = R4:R3
+	MOVW	R3, mono+12(FP)
+	MOVW	R4, mono+16(FP)
+
+	MOVW	$_SYSTEM_TIME, R3
+wall:
+	MOVW	time_hi1(R3), R1
+	MOVW	time_lo(R3), R0
+	MOVW	time_hi2(R3), R2
+	CMP	R1, R2
+	BNE	wall
+
+	// w = R1:R0 in 100ns untis
+	// convert to Unix epoch (but still 100ns units)
+	#define delta 116444736000000000
+	SUB.S   $(delta & 0xFFFFFFFF), R0
+	SBC     $(delta >> 32), R1
+
+	// Convert to nSec
+	MOVW    $100, R2
+	MULLU   R0, R2, (R4, R3)    // R4:R3 = R1:R0 * R2
+	MULA    R1, R2, R4, R4
+	// w = R2:R1 in nSec
+	MOVW    R3, R1	      // R4:R3 -> R2:R1
+	MOVW    R4, R2
+
+	// multiply nanoseconds by reciprocal of 10**9 (scaled by 2**61)
+	// to get seconds (96 bit scaled result)
+	MOVW	$0x89705f41, R3		// 2**61 * 10**-9
+	MULLU	R1,R3,(R6,R5)		// R7:R6:R5 = R2:R1 * R3
+	MOVW	$0,R7
+	MULALU	R2,R3,(R7,R6)
+
+	// unscale by discarding low 32 bits, shifting the rest by 29
+	MOVW	R6>>29,R6		// R7:R6 = (R7:R6:R5 >> 61)
+	ORR	R7<<3,R6
+	MOVW	R7>>29,R7
+
+	// subtract (10**9 * sec) from nsec to get nanosecond remainder
+	MOVW	$1000000000, R5	// 10**9
+	MULLU	R6,R5,(R9,R8)   // R9:R8 = R7:R6 * R5
+	MULA	R7,R5,R9,R9
+	SUB.S	R8,R1		// R2:R1 -= R9:R8
+	SBC	R9,R2
+
+	// because reciprocal was a truncated repeating fraction, quotient
+	// may be slightly too small -- adjust to make remainder < 10**9
+	CMP	R5,R1	// if remainder > 10**9
+	SUB.HS	R5,R1   //    remainder -= 10**9
+	ADD.HS	$1,R6	//    sec += 1
+
+	MOVW	R6,sec_lo+0(FP)
+	MOVW	R7,sec_hi+4(FP)
+	MOVW	R1,nsec+8(FP)
+	RET
+useQPC:
+	B	runtime·nowQPC(SB)		// tail call
+
diff --git a/src/runtime/time_windows_arm64.s b/src/runtime/time_windows_arm64.s
new file mode 100644
index 0000000..ef52ce4
--- /dev/null
+++ b/src/runtime/time_windows_arm64.s
@@ -0,0 +1,67 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !faketime
+// +build !faketime
+
+#include "go_asm.h"
+#include "textflag.h"
+#include "time_windows.h"
+
+TEXT time·now(SB),NOSPLIT|NOFRAME,$0-24
+	MOVB    runtime·useQPCTime(SB), R0
+	CMP	$0, R0
+	BNE	useQPC
+	MOVD	$_INTERRUPT_TIME, R3
+loop:
+	MOVWU	time_hi1(R3), R1
+	MOVWU	time_lo(R3), R0
+	MOVWU	time_hi2(R3), R2
+	CMP	R1, R2
+	BNE	loop
+
+	// wintime = R1:R0, multiply by 100
+	ORR	R1<<32, R0
+	MOVD	$100, R1
+	MUL	R1, R0
+	MOVD	R0, mono+16(FP)
+
+	MOVD	$_SYSTEM_TIME, R3
+wall:
+	MOVWU	time_hi1(R3), R1
+	MOVWU	time_lo(R3), R0
+	MOVWU	time_hi2(R3), R2
+	CMP	R1, R2
+	BNE	wall
+
+	// w = R1:R0 in 100ns units
+	// convert to Unix epoch (but still 100ns units)
+	#define delta 116444736000000000
+	ORR	R1<<32, R0
+	SUB	$delta, R0
+
+	// Convert to nSec
+	MOVD	$100, R1
+	MUL	R1, R0
+
+	// Code stolen from compiler output for:
+	//
+	//	var x uint64
+	//	func f() (sec uint64, nsec uint32) { return x / 1000000000, uint32(x % 100000000) }
+	//
+	LSR	$1, R0, R1
+	MOVD	$-8543223759426509416, R2
+	UMULH	R2, R1, R1
+	LSR	$28, R1, R1
+	MOVD	R1, sec+0(FP)
+	MOVD	$-6067343680855748867, R1
+	UMULH	R0, R1, R1
+	LSR	$26, R1, R1
+	MOVD	$100000000, R2
+	MSUB	R1, R0, R2, R0
+	MOVW	R0, nsec+8(FP)
+	RET
+useQPC:
+	B	runtime·nowQPC(SB)		// tail call
+
diff --git a/src/runtime/timeasm.go b/src/runtime/timeasm.go
index 82cf63e..468ff8a 100644
--- a/src/runtime/timeasm.go
+++ b/src/runtime/timeasm.go
@@ -4,7 +4,9 @@
 
 // Declarations for operating systems implementing time.now directly in assembly.
 
-// +build windows
+//go:build !faketime && (windows || (linux && amd64))
+// +build !faketime
+// +build windows linux,amd64
 
 package runtime
 
diff --git a/src/runtime/timestub.go b/src/runtime/timestub.go
index 459bf8e..6f16c70 100644
--- a/src/runtime/timestub.go
+++ b/src/runtime/timestub.go
@@ -5,7 +5,10 @@
 // Declarations for operating systems implementing time.now
 // indirectly, in terms of walltime and nanotime assembly.
 
+//go:build !faketime && !windows && !(linux && amd64)
+// +build !faketime
 // +build !windows
+// +build !linux !amd64
 
 package runtime
 
diff --git a/src/runtime/timestub2.go b/src/runtime/timestub2.go
index 68777ee..800a2a9 100644
--- a/src/runtime/timestub2.go
+++ b/src/runtime/timestub2.go
@@ -2,13 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !aix && !darwin && !freebsd && !openbsd && !solaris && !windows && !(linux && amd64)
 // +build !aix
 // +build !darwin
 // +build !freebsd
 // +build !openbsd
 // +build !solaris
 // +build !windows
+// +build !linux !amd64
 
 package runtime
 
-func walltime1() (sec int64, nsec int32)
+func walltime() (sec int64, nsec int32)
diff --git a/src/runtime/tls_arm.s b/src/runtime/tls_arm.s
index e42de8d..879caac 100644
--- a/src/runtime/tls_arm.s
+++ b/src/runtime/tls_arm.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows
 // +build !windows
 
 #include "go_asm.h"
diff --git a/src/runtime/tls_arm64.h b/src/runtime/tls_arm64.h
index 0804fa3..fe5e4ce 100644
--- a/src/runtime/tls_arm64.h
+++ b/src/runtime/tls_arm64.h
@@ -41,8 +41,16 @@
 #define MRS_TPIDR_R0 WORD $0xd53bd040 // MRS TPIDR_EL0, R0
 #endif
 
+#ifdef GOOS_windows
+#define TLS_windows
+#endif
+#ifdef TLS_windows
+#define TLSG_IS_VARIABLE
+#define MRS_TPIDR_R0 MOVD R18_PLATFORM, R0
+#endif
+
 // Define something that will break the build if
 // the GOOS is unknown.
-#ifndef TPIDR
-#define MRS_TPIDR_R0 TPIDR_UNKNOWN
+#ifndef MRS_TPIDR_R0
+#define MRS_TPIDR_R0 unknown_TLS_implementation_in_tls_arm64_h
 #endif
diff --git a/src/runtime/tls_arm64.s b/src/runtime/tls_arm64.s
index 085012f..52b3e8f 100644
--- a/src/runtime/tls_arm64.s
+++ b/src/runtime/tls_arm64.s
@@ -9,12 +9,14 @@
 #include "tls_arm64.h"
 
 TEXT runtime·load_g(SB),NOSPLIT,$0
-#ifndef TLS_darwin
+#ifndef GOOS_darwin
 #ifndef GOOS_openbsd
+#ifndef GOOS_windows
 	MOVB	runtime·iscgo(SB), R0
 	CBZ	R0, nocgo
 #endif
 #endif
+#endif
 
 	MRS_TPIDR_R0
 #ifdef TLS_darwin
@@ -28,12 +30,14 @@
 	RET
 
 TEXT runtime·save_g(SB),NOSPLIT,$0
-#ifndef TLS_darwin
+#ifndef GOOS_darwin
 #ifndef GOOS_openbsd
+#ifndef GOOS_windows
 	MOVB	runtime·iscgo(SB), R0
 	CBZ	R0, nocgo
 #endif
 #endif
+#endif
 
 	MRS_TPIDR_R0
 #ifdef TLS_darwin
diff --git a/src/runtime/tls_mips64x.s b/src/runtime/tls_mips64x.s
index 888c0ef..779d64b 100644
--- a/src/runtime/tls_mips64x.s
+++ b/src/runtime/tls_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 #include "go_asm.h"
diff --git a/src/runtime/tls_mipsx.s b/src/runtime/tls_mipsx.s
index d2ffcd9..ada8d06 100644
--- a/src/runtime/tls_mipsx.s
+++ b/src/runtime/tls_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 #include "go_asm.h"
diff --git a/src/runtime/tls_ppc64x.s b/src/runtime/tls_ppc64x.s
index c697449..7e935d0 100644
--- a/src/runtime/tls_ppc64x.s
+++ b/src/runtime/tls_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 #include "go_asm.h"
@@ -29,7 +30,7 @@
 	BEQ	nocgo
 #endif
 	MOVD	runtime·tls_g(SB), R31
-	MOVD	g, 0(R13)(R31*1)
+	MOVD	g, 0(R31)
 
 nocgo:
 	RET
@@ -45,7 +46,7 @@
 // NOTE: _cgo_topofstack assumes this only clobbers g (R30), and R31.
 TEXT runtime·load_g(SB),NOSPLIT|NOFRAME,$0-0
 	MOVD	runtime·tls_g(SB), R31
-	MOVD	0(R13)(R31*1), g
+	MOVD	0(R31), g
 	RET
 
 GLOBL runtime·tls_g+0(SB), TLSBSS+DUPOK, $8
diff --git a/src/runtime/tls_stub.go b/src/runtime/tls_stub.go
new file mode 100644
index 0000000..95dafd0
--- /dev/null
+++ b/src/runtime/tls_stub.go
@@ -0,0 +1,11 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (windows && !amd64) || !windows
+// +build windows,!amd64 !windows
+
+package runtime
+
+//go:nosplit
+func osSetupTLS(mp *m) {}
diff --git a/src/runtime/tls_windows_amd64.go b/src/runtime/tls_windows_amd64.go
new file mode 100644
index 0000000..cacaa84
--- /dev/null
+++ b/src/runtime/tls_windows_amd64.go
@@ -0,0 +1,10 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+// osSetupTLS is called by needm to set up TLS for non-Go threads.
+//
+// Defined in assembly.
+func osSetupTLS(mp *m)
diff --git a/src/runtime/trace.go b/src/runtime/trace.go
index bcd0b9d..1530178 100644
--- a/src/runtime/trace.go
+++ b/src/runtime/trace.go
@@ -53,8 +53,8 @@
 	traceEvGoSysBlock        = 30 // syscall blocks [timestamp]
 	traceEvGoWaiting         = 31 // denotes that goroutine is blocked when tracing starts [timestamp, goroutine id]
 	traceEvGoInSyscall       = 32 // denotes that goroutine is in syscall when tracing starts [timestamp, goroutine id]
-	traceEvHeapAlloc         = 33 // memstats.heap_live change [timestamp, heap_alloc]
-	traceEvNextGC            = 34 // memstats.next_gc change [timestamp, next_gc]
+	traceEvHeapAlloc         = 33 // gcController.heapLive change [timestamp, heap_alloc]
+	traceEvHeapGoal          = 34 // gcController.heapGoal (formerly next_gc) change [timestamp, heap goal in bytes]
 	traceEvTimerGoroutine    = 35 // not currently used; previously denoted timer goroutine [timer goroutine id]
 	traceEvFutileWakeup      = 36 // denotes that the previous wakeup of this goroutine was futile [timestamp]
 	traceEvString            = 37 // string dictionary entry [ID, length, string]
@@ -221,7 +221,8 @@
 	stackID := traceStackID(mp, stkBuf, 2)
 	releasem(mp)
 
-	for _, gp := range allgs {
+	// World is stopped, no need to lock.
+	forEachGRace(func(gp *g) {
 		status := readgstatus(gp)
 		if status != _Gdead {
 			gp.traceseq = 0
@@ -241,7 +242,7 @@
 		} else {
 			gp.sysblocktraced = false
 		}
-	}
+	})
 	traceProcStart()
 	traceGoStart()
 	// Note: ticksStart needs to be set after we emit traceEvGoInSyscall events.
@@ -1143,15 +1144,15 @@
 }
 
 func traceHeapAlloc() {
-	traceEvent(traceEvHeapAlloc, -1, memstats.heap_live)
+	traceEvent(traceEvHeapAlloc, -1, gcController.heapLive)
 }
 
-func traceNextGC() {
-	if nextGC := atomic.Load64(&memstats.next_gc); nextGC == ^uint64(0) {
+func traceHeapGoal() {
+	if heapGoal := atomic.Load64(&gcController.heapGoal); heapGoal == ^uint64(0) {
 		// Heap-based triggering is disabled.
-		traceEvent(traceEvNextGC, -1, 0)
+		traceEvent(traceEvHeapGoal, -1, 0)
 	} else {
-		traceEvent(traceEvNextGC, -1, nextGC)
+		traceEvent(traceEvHeapGoal, -1, heapGoal)
 	}
 }
 
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index 2601cd6..814c323 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -15,24 +15,9 @@
 // The most important fact about a given architecture is whether it uses a link register.
 // On systems with link registers, the prologue for a non-leaf function stores the
 // incoming value of LR at the bottom of the newly allocated stack frame.
-// On systems without link registers, the architecture pushes a return PC during
+// On systems without link registers (x86), the architecture pushes a return PC during
 // the call instruction, so the return PC ends up above the stack frame.
 // In this file, the return PC is always called LR, no matter how it was found.
-//
-// To date, the opposite of a link register architecture is an x86 architecture.
-// This code may need to change if some other kind of non-link-register
-// architecture comes along.
-//
-// The other important fact is the size of a pointer: on 32-bit systems the LR
-// takes up only 4 bytes on the stack, while on 64-bit systems it takes up 8 bytes.
-// Typically this is ptrSize.
-//
-// As an exception, amd64p32 had ptrSize == 4 but the CALL instruction still
-// stored an 8-byte return PC onto the stack. To accommodate this, we used regSize
-// as the size of the architecture-pushed return PC.
-//
-// usesLR is defined below in terms of minFrameSize, which is defined in
-// arch_$GOARCH.go. ptrSize and regSize are defined in stubs.go.
 
 const usesLR = sys.MinFrameSize > 0
 
@@ -71,8 +56,6 @@
 	}
 }
 
-const sizeofSkipFunction = 256
-
 // Generic traceback. Handles runtime stack prints (pcbuf == nil),
 // the runtime.Callers function (pcbuf != nil), as well as the garbage
 // collector (callback != nil).  A little clunky to merge these, but avoids
@@ -80,9 +63,7 @@
 //
 // The skip argument is only valid with pcbuf != nil and counts the number
 // of logical frames to skip rather than physical frames (with inlining, a
-// PC in pcbuf can represent multiple calls). If a PC is partially skipped
-// and max > 1, pcbuf[1] will be runtime.skipPleaseUseCallersFrames+N where
-// N indicates the number of logical frames to skip in pcbuf[0].
+// PC in pcbuf can represent multiple calls).
 func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max int, callback func(*stkframe, unsafe.Pointer) bool, v unsafe.Pointer, flags uint) int {
 	if skip > 0 && callback != nil {
 		throw("gentraceback callback cannot be used with non-zero skip")
@@ -144,8 +125,8 @@
 			frame.pc = *(*uintptr)(unsafe.Pointer(frame.sp))
 			frame.lr = 0
 		} else {
-			frame.pc = uintptr(*(*sys.Uintreg)(unsafe.Pointer(frame.sp)))
-			frame.sp += sys.RegSize
+			frame.pc = uintptr(*(*uintptr)(unsafe.Pointer(frame.sp)))
+			frame.sp += sys.PtrSize
 		}
 	}
 
@@ -180,6 +161,22 @@
 			break
 		}
 
+		// Compute function info flags.
+		flag := f.flag
+		if f.funcID == funcID_cgocallback {
+			// cgocallback does write SP to switch from the g0 to the curg stack,
+			// but it carefully arranges that during the transition BOTH stacks
+			// have cgocallback frame valid for unwinding through.
+			// So we don't need to exclude it with the other SP-writing functions.
+			flag &^= funcFlag_SPWRITE
+		}
+		if frame.pc == pc0 && frame.sp == sp0 && pc0 == gp.syscallpc && sp0 == gp.syscallsp {
+			// Some Syscall functions write to SP, but they do so only after
+			// saving the entry PC/SP using entersyscall.
+			// Since we are using the entry PC/SP, the later SP write doesn't matter.
+			flag &^= funcFlag_SPWRITE
+		}
+
 		// Found an actual function.
 		// Derive frame pointer and link register.
 		if frame.fp == 0 {
@@ -196,6 +193,7 @@
 					frame.pc = gp.m.curg.sched.pc
 					frame.fn = findfunc(frame.pc)
 					f = frame.fn
+					flag = f.flag
 					frame.sp = gp.m.curg.sched.sp
 					cgoCtxt = gp.m.curg.cgoCtxt
 				case funcID_systemstack:
@@ -203,29 +201,44 @@
 					// stack transition.
 					frame.sp = gp.m.curg.sched.sp
 					cgoCtxt = gp.m.curg.cgoCtxt
+					flag &^= funcFlag_SPWRITE
 				}
 			}
 			frame.fp = frame.sp + uintptr(funcspdelta(f, frame.pc, &cache))
 			if !usesLR {
 				// On x86, call instruction pushes return PC before entering new function.
-				frame.fp += sys.RegSize
+				frame.fp += sys.PtrSize
 			}
 		}
 		var flr funcInfo
-		if topofstack(f, gp.m != nil && gp == gp.m.g0) {
+		if flag&funcFlag_TOPFRAME != 0 {
+			// This function marks the top of the stack. Stop the traceback.
 			frame.lr = 0
 			flr = funcInfo{}
-		} else if usesLR && f.funcID == funcID_jmpdefer {
-			// jmpdefer modifies SP/LR/PC non-atomically.
-			// If a profiling interrupt arrives during jmpdefer,
-			// the stack unwind may see a mismatched register set
-			// and get confused. Stop if we see PC within jmpdefer
-			// to avoid that confusion.
-			// See golang.org/issue/8153.
+		} else if flag&funcFlag_SPWRITE != 0 && (callback == nil || n > 0) {
+			// The function we are in does a write to SP that we don't know
+			// how to encode in the spdelta table. Examples include context
+			// switch routines like runtime.gogo but also any code that switches
+			// to the g0 stack to run host C code. Since we can't reliably unwind
+			// the SP (we might not even be on the stack we think we are),
+			// we stop the traceback here.
+			// This only applies for profiling signals (callback == nil).
+			//
+			// For a GC stack traversal (callback != nil), we should only see
+			// a function when it has voluntarily preempted itself on entry
+			// during the stack growth check. In that case, the function has
+			// not yet had a chance to do any writes to SP and is safe to unwind.
+			// isAsyncSafePoint does not allow assembly functions to be async preempted,
+			// and preemptPark double-checks that SPWRITE functions are not async preempted.
+			// So for GC stack traversal we leave things alone (this if body does not execute for n == 0)
+			// at the bottom frame of the stack. But farther up the stack we'd better not
+			// find any.
 			if callback != nil {
-				throw("traceback_arm: found jmpdefer when tracing with callback")
+				println("traceback: unexpected SPWRITE function", funcname(f))
+				throw("traceback")
 			}
 			frame.lr = 0
+			flr = funcInfo{}
 		} else {
 			var lrPtr uintptr
 			if usesLR {
@@ -235,8 +248,8 @@
 				}
 			} else {
 				if frame.lr == 0 {
-					lrPtr = frame.fp - sys.RegSize
-					frame.lr = uintptr(*(*sys.Uintreg)(unsafe.Pointer(lrPtr)))
+					lrPtr = frame.fp - sys.PtrSize
+					frame.lr = uintptr(*(*uintptr)(unsafe.Pointer(lrPtr)))
 				}
 			}
 			flr = findfunc(frame.lr)
@@ -266,13 +279,28 @@
 		frame.varp = frame.fp
 		if !usesLR {
 			// On x86, call instruction pushes return PC before entering new function.
-			frame.varp -= sys.RegSize
+			frame.varp -= sys.PtrSize
 		}
 
 		// For architectures with frame pointers, if there's
 		// a frame, then there's a saved frame pointer here.
-		if frame.varp > frame.sp && (GOARCH == "amd64" || GOARCH == "arm64") {
-			frame.varp -= sys.RegSize
+		//
+		// NOTE: This code is not as general as it looks.
+		// On x86, the ABI is to save the frame pointer word at the
+		// top of the stack frame, so we have to back down over it.
+		// On arm64, the frame pointer should be at the bottom of
+		// the stack (with R29 (aka FP) = RSP), in which case we would
+		// not want to do the subtraction here. But we started out without
+		// any frame pointer, and when we wanted to add it, we didn't
+		// want to break all the assembly doing direct writes to 8(RSP)
+		// to set the first parameter to a called function.
+		// So we decided to write the FP link *below* the stack pointer
+		// (with R29 = RSP - 8 in Go functions).
+		// This is technically ABI-compatible but not standard.
+		// And it happens to end up mimicking the x86 layout.
+		// Other architectures may make different decisions.
+		if frame.varp > frame.sp && framepointer_enabled {
+			frame.varp -= sys.PtrSize
 		}
 
 		// Derive size of arguments.
@@ -432,17 +460,8 @@
 					name = "panic"
 				}
 				print(name, "(")
-				argp := (*[100]uintptr)(unsafe.Pointer(frame.argp))
-				for i := uintptr(0); i < frame.arglen/sys.PtrSize; i++ {
-					if i >= 10 {
-						print(", ...")
-						break
-					}
-					if i != 0 {
-						print(", ")
-					}
-					print(hex(argp[i]))
-				}
+				argp := unsafe.Pointer(frame.argp)
+				printArgs(f, argp)
 				print(")\n")
 				print("\t", file, ":", line)
 				if frame.pc > f.entry {
@@ -490,11 +509,7 @@
 		// before faking a call.
 		if usesLR && injectedCall {
 			x := *(*uintptr)(unsafe.Pointer(frame.sp))
-			frame.sp += sys.MinFrameSize
-			if GOARCH == "arm64" {
-				// arm64 needs 16-byte aligned SP, always
-				frame.sp += sys.PtrSize
-			}
+			frame.sp += alignUp(sys.MinFrameSize, sys.StackAlign)
 			f = findfunc(frame.pc)
 			frame.fn = f
 			if !f.valid() {
@@ -558,6 +573,82 @@
 	return n
 }
 
+// printArgs prints function arguments in traceback.
+func printArgs(f funcInfo, argp unsafe.Pointer) {
+	// The "instruction" of argument printing is encoded in _FUNCDATA_ArgInfo.
+	// See cmd/compile/internal/ssagen.emitArgInfo for the description of the
+	// encoding.
+	// These constants need to be in sync with the compiler.
+	const (
+		_endSeq         = 0xff
+		_startAgg       = 0xfe
+		_endAgg         = 0xfd
+		_dotdotdot      = 0xfc
+		_offsetTooLarge = 0xfb
+	)
+
+	const (
+		limit    = 10                       // print no more than 10 args/components
+		maxDepth = 5                        // no more than 5 layers of nesting
+		maxLen   = (maxDepth*3+2)*limit + 1 // max length of _FUNCDATA_ArgInfo (see the compiler side for reasoning)
+	)
+
+	p := (*[maxLen]uint8)(funcdata(f, _FUNCDATA_ArgInfo))
+	if p == nil {
+		return
+	}
+
+	print1 := func(off, sz uint8) {
+		x := readUnaligned64(add(argp, uintptr(off)))
+		// mask out irrelavant bits
+		if sz < 8 {
+			shift := 64 - sz*8
+			if sys.BigEndian {
+				x = x >> shift
+			} else {
+				x = x << shift >> shift
+			}
+		}
+		print(hex(x))
+	}
+
+	start := true
+	printcomma := func() {
+		if !start {
+			print(", ")
+		}
+	}
+	pi := 0
+printloop:
+	for {
+		o := p[pi]
+		pi++
+		switch o {
+		case _endSeq:
+			break printloop
+		case _startAgg:
+			printcomma()
+			print("{")
+			start = true
+			continue
+		case _endAgg:
+			print("}")
+		case _dotdotdot:
+			printcomma()
+			print("...")
+		case _offsetTooLarge:
+			printcomma()
+			print("_")
+		default:
+			printcomma()
+			sz := p[pi]
+			pi++
+			print1(o, sz)
+		}
+		start = false
+	}
+}
+
 // reflectMethodValue is a partial duplicate of reflect.makeFuncImpl
 // and reflect.methodValue.
 type reflectMethodValue struct {
@@ -609,7 +700,7 @@
 				// Figure out whether the return values are valid.
 				// Reflect will update this value after it copies
 				// in the return values.
-				retValid = *(*bool)(unsafe.Pointer(arg0 + 3*sys.PtrSize))
+				retValid = *(*bool)(unsafe.Pointer(arg0 + 4*sys.PtrSize))
 			}
 			if mv.fn != f.entry {
 				print("runtime: confused by ", funcname(f), "\n")
@@ -924,19 +1015,16 @@
 		traceback(^uintptr(0), ^uintptr(0), 0, curgp)
 	}
 
-	// We can't take allglock here because this may be during fatal
-	// throw/panic, where locking allglock could be out-of-order or a
-	// direct deadlock.
+	// We can't call locking forEachG here because this may be during fatal
+	// throw/panic, where locking could be out-of-order or a direct
+	// deadlock.
 	//
-	// Instead, use atomic access to allgs which requires no locking. We
-	// don't lock against concurrent creation of new Gs, but even with
-	// allglock we may miss Gs created after this loop.
-	ptr, length := atomicAllG()
-	for i := uintptr(0); i < length; i++ {
-		gp := atomicAllGIndex(ptr, i)
-
+	// Instead, use forEachGRace, which requires no locking. We don't lock
+	// against concurrent creation of new Gs, but even with allglock we may
+	// miss Gs created after this loop.
+	forEachGRace(func(gp *g) {
 		if gp == me || gp == curgp || readgstatus(gp) == _Gdead || isSystemGoroutine(gp, false) && level < 2 {
-			continue
+			return
 		}
 		print("\n")
 		goroutineheader(gp)
@@ -950,7 +1038,7 @@
 		} else {
 			traceback(^uintptr(0), ^uintptr(0), 0, gp)
 		}
-	}
+	})
 }
 
 // tracebackHexdump hexdumps part of stk around frame.sp and frame.fp
@@ -1000,22 +1088,6 @@
 	})
 }
 
-// Does f mark the top of a goroutine stack?
-func topofstack(f funcInfo, g0 bool) bool {
-	return f.funcID == funcID_goexit ||
-		f.funcID == funcID_mstart ||
-		f.funcID == funcID_mcall ||
-		f.funcID == funcID_morestack ||
-		f.funcID == funcID_rt0_go ||
-		f.funcID == funcID_externalthreadhandler ||
-		// 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 && f.funcID == funcID_asmcgocall)
-}
-
 // isSystemGoroutine reports whether the goroutine g must be omitted
 // in stack dumps and deadlock detector. This is any goroutine that
 // starts at a runtime.* entry point, except for runtime.main,
diff --git a/src/runtime/traceback_test.go b/src/runtime/traceback_test.go
new file mode 100644
index 0000000..83b86a7
--- /dev/null
+++ b/src/runtime/traceback_test.go
@@ -0,0 +1,292 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"bytes"
+	"runtime"
+	"testing"
+)
+
+var testTracebackArgsBuf [1000]byte
+
+func TestTracebackArgs(t *testing.T) {
+	tests := []struct {
+		fn     func() int
+		expect string
+	}{
+		// simple ints
+		{
+			func() int { return testTracebackArgs1(1, 2, 3, 4, 5) },
+			"testTracebackArgs1(0x1, 0x2, 0x3, 0x4, 0x5)",
+		},
+		// some aggregates
+		{
+			func() int {
+				return testTracebackArgs2(false, struct {
+					a, b, c int
+					x       [2]int
+				}{1, 2, 3, [2]int{4, 5}}, [0]int{}, [3]byte{6, 7, 8})
+			},
+			"testTracebackArgs2(0x0, {0x1, 0x2, 0x3, {0x4, 0x5}}, {}, {0x6, 0x7, 0x8})",
+		},
+		{
+			func() int { return testTracebackArgs3([3]byte{1, 2, 3}, 4, 5, 6, [3]byte{7, 8, 9}) },
+			"testTracebackArgs3({0x1, 0x2, 0x3}, 0x4, 0x5, 0x6, {0x7, 0x8, 0x9})",
+		},
+		// too deeply nested type
+		{
+			func() int { return testTracebackArgs4(false, [1][1][1][1][1][1][1][1][1][1]int{}) },
+			"testTracebackArgs4(0x0, {{{{{...}}}}})",
+		},
+		// a lot of zero-sized type
+		{
+			func() int {
+				z := [0]int{}
+				return testTracebackArgs5(false, struct {
+					x int
+					y [0]int
+					z [2][0]int
+				}{1, z, [2][0]int{}}, z, z, z, z, z, z, z, z, z, z, z, z)
+			},
+			"testTracebackArgs5(0x0, {0x1, {}, {{}, {}}}, {}, {}, {}, {}, {}, ...)",
+		},
+
+		// edge cases for ...
+		// no ... for 10 args
+		{
+			func() int { return testTracebackArgs6a(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) },
+			"testTracebackArgs6a(0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa)",
+		},
+		// has ... for 11 args
+		{
+			func() int { return testTracebackArgs6b(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) },
+			"testTracebackArgs6b(0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, ...)",
+		},
+		// no ... for aggregates with 10 words
+		{
+			func() int { return testTracebackArgs7a([10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) },
+			"testTracebackArgs7a({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa})",
+		},
+		// has ... for aggregates with 11 words
+		{
+			func() int { return testTracebackArgs7b([11]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}) },
+			"testTracebackArgs7b({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, ...})",
+		},
+		// no ... for aggregates, but with more args
+		{
+			func() int { return testTracebackArgs7c([10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 11) },
+			"testTracebackArgs7c({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa}, ...)",
+		},
+		// has ... for aggregates and also for more args
+		{
+			func() int { return testTracebackArgs7d([11]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 12) },
+			"testTracebackArgs7d({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, ...}, ...)",
+		},
+		// nested aggregates, no ...
+		{
+			func() int { return testTracebackArgs8a(testArgsType8a{1, 2, 3, 4, 5, 6, 7, 8, [2]int{9, 10}}) },
+			"testTracebackArgs8a({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, {0x9, 0xa}})",
+		},
+		// nested aggregates, ... in inner but not outer
+		{
+			func() int { return testTracebackArgs8b(testArgsType8b{1, 2, 3, 4, 5, 6, 7, 8, [3]int{9, 10, 11}}) },
+			"testTracebackArgs8b({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, {0x9, 0xa, ...}})",
+		},
+		// nested aggregates, ... in outer but not inner
+		{
+			func() int { return testTracebackArgs8c(testArgsType8c{1, 2, 3, 4, 5, 6, 7, 8, [2]int{9, 10}, 11}) },
+			"testTracebackArgs8c({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, {0x9, 0xa}, ...})",
+		},
+		// nested aggregates, ... in both inner and outer
+		{
+			func() int { return testTracebackArgs8d(testArgsType8d{1, 2, 3, 4, 5, 6, 7, 8, [3]int{9, 10, 11}, 12}) },
+			"testTracebackArgs8d({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, {0x9, 0xa, ...}, ...})",
+		},
+	}
+	for _, test := range tests {
+		n := test.fn()
+		got := testTracebackArgsBuf[:n]
+		if !bytes.Contains(got, []byte(test.expect)) {
+			t.Errorf("traceback does not contain expected string: want %q, got\n%s", test.expect, got)
+		}
+	}
+}
+
+//go:noinline
+func testTracebackArgs1(a, b, c, d, e int) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a < 0 {
+		// use in-reg args to keep them alive
+		return a + b + c + d + e
+	}
+	return n
+}
+
+//go:noinline
+func testTracebackArgs2(a bool, b struct {
+	a, b, c int
+	x       [2]int
+}, _ [0]int, d [3]byte) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a {
+		// use in-reg args to keep them alive
+		return b.a + b.b + b.c + b.x[0] + b.x[1] + int(d[0]) + int(d[1]) + int(d[2])
+	}
+	return n
+
+}
+
+//go:noinline
+//go:registerparams
+func testTracebackArgs3(x [3]byte, a, b, c int, y [3]byte) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a < 0 {
+		// use in-reg args to keep them alive
+		return int(x[0]) + int(x[1]) + int(x[2]) + a + b + c + int(y[0]) + int(y[1]) + int(y[2])
+	}
+	return n
+}
+
+//go:noinline
+func testTracebackArgs4(a bool, x [1][1][1][1][1][1][1][1][1][1]int) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a {
+		panic(x) // use args to keep them alive
+	}
+	return n
+}
+
+//go:noinline
+func testTracebackArgs5(a bool, x struct {
+	x int
+	y [0]int
+	z [2][0]int
+}, _, _, _, _, _, _, _, _, _, _, _, _ [0]int) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a {
+		panic(x) // use args to keep them alive
+	}
+	return n
+}
+
+//go:noinline
+func testTracebackArgs6a(a, b, c, d, e, f, g, h, i, j int) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a < 0 {
+		// use in-reg args to keep them alive
+		return a + b + c + d + e + f + g + h + i + j
+	}
+	return n
+}
+
+//go:noinline
+func testTracebackArgs6b(a, b, c, d, e, f, g, h, i, j, k int) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a < 0 {
+		// use in-reg args to keep them alive
+		return a + b + c + d + e + f + g + h + i + j + k
+	}
+	return n
+}
+
+//go:noinline
+func testTracebackArgs7a(a [10]int) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a[0] < 0 {
+		// use in-reg args to keep them alive
+		return a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9]
+	}
+	return n
+}
+
+//go:noinline
+func testTracebackArgs7b(a [11]int) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a[0] < 0 {
+		// use in-reg args to keep them alive
+		return a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9] + a[10]
+	}
+	return n
+}
+
+//go:noinline
+func testTracebackArgs7c(a [10]int, b int) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a[0] < 0 {
+		// use in-reg args to keep them alive
+		return a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9] + b
+	}
+	return n
+}
+
+//go:noinline
+func testTracebackArgs7d(a [11]int, b int) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a[0] < 0 {
+		// use in-reg args to keep them alive
+		return a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9] + a[10] + b
+	}
+	return n
+}
+
+type testArgsType8a struct {
+	a, b, c, d, e, f, g, h int
+	i                      [2]int
+}
+type testArgsType8b struct {
+	a, b, c, d, e, f, g, h int
+	i                      [3]int
+}
+type testArgsType8c struct {
+	a, b, c, d, e, f, g, h int
+	i                      [2]int
+	j                      int
+}
+type testArgsType8d struct {
+	a, b, c, d, e, f, g, h int
+	i                      [3]int
+	j                      int
+}
+
+//go:noinline
+func testTracebackArgs8a(a testArgsType8a) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a.a < 0 {
+		// use in-reg args to keep them alive
+		return a.b + a.c + a.d + a.e + a.f + a.g + a.h + a.i[0] + a.i[1]
+	}
+	return n
+}
+
+//go:noinline
+func testTracebackArgs8b(a testArgsType8b) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a.a < 0 {
+		// use in-reg args to keep them alive
+		return a.b + a.c + a.d + a.e + a.f + a.g + a.h + a.i[0] + a.i[1] + a.i[2]
+	}
+	return n
+}
+
+//go:noinline
+func testTracebackArgs8c(a testArgsType8c) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a.a < 0 {
+		// use in-reg args to keep them alive
+		return a.b + a.c + a.d + a.e + a.f + a.g + a.h + a.i[0] + a.i[1] + a.j
+	}
+	return n
+}
+
+//go:noinline
+func testTracebackArgs8d(a testArgsType8d) int {
+	n := runtime.Stack(testTracebackArgsBuf[:], false)
+	if a.a < 0 {
+		// use in-reg args to keep them alive
+		return a.b + a.c + a.d + a.e + a.f + a.g + a.h + a.i[0] + a.i[1] + a.i[2] + a.j
+	}
+	return n
+}
diff --git a/src/runtime/type.go b/src/runtime/type.go
index 81455f3..4039273 100644
--- a/src/runtime/type.go
+++ b/src/runtime/type.go
@@ -11,7 +11,7 @@
 // tflag is documented in reflect/type.go.
 //
 // tflag values must be kept in sync with copies in:
-//	cmd/compile/internal/gc/reflect.go
+//	cmd/compile/internal/reflectdata/reflect.go
 //	cmd/link/internal/ld/decodesym.go
 //	reflect/type.go
 //      internal/reflectlite/type.go
@@ -25,7 +25,7 @@
 )
 
 // Needs to be in sync with ../cmd/link/internal/ld/decodesym.go:/^func.commonsize,
-// ../cmd/compile/internal/gc/reflect.go:/^func.dcommontype and
+// ../cmd/compile/internal/reflectdata/reflect.go:/^func.dcommontype and
 // ../reflect/type.go:/^type.rtype.
 // ../internal/reflectlite/type.go:/^type.rtype.
 type _type struct {
@@ -262,7 +262,7 @@
 	if off == -1 {
 		// -1 is the sentinel value for unreachable code.
 		// See cmd/link/internal/ld/data.go:relocsym.
-		return unsafe.Pointer(^uintptr(0))
+		return unsafe.Pointer(funcPC(unreachableMethod))
 	}
 	base := uintptr(unsafe.Pointer(t))
 	var md *moduledata
@@ -383,7 +383,7 @@
 }
 
 // Note: flag values must match those used in the TMAP case
-// in ../cmd/compile/internal/gc/reflect.go:dtypesym.
+// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
 func (mt *maptype) indirectkey() bool { // store ptr to key instead of key itself
 	return mt.flags&1 != 0
 }
@@ -459,51 +459,52 @@
 	return (*n.bytes)&(1<<0) != 0
 }
 
-func (n name) nameLen() int {
-	return int(uint16(*n.data(1))<<8 | uint16(*n.data(2)))
-}
-
-func (n name) tagLen() int {
-	if *n.data(0)&(1<<1) == 0 {
-		return 0
+func (n name) readvarint(off int) (int, int) {
+	v := 0
+	for i := 0; ; i++ {
+		x := *n.data(off + i)
+		v += int(x&0x7f) << (7 * i)
+		if x&0x80 == 0 {
+			return i + 1, v
+		}
 	}
-	off := 3 + n.nameLen()
-	return int(uint16(*n.data(off))<<8 | uint16(*n.data(off + 1)))
 }
 
 func (n name) name() (s string) {
 	if n.bytes == nil {
 		return ""
 	}
-	nl := n.nameLen()
-	if nl == 0 {
+	i, l := n.readvarint(1)
+	if l == 0 {
 		return ""
 	}
 	hdr := (*stringStruct)(unsafe.Pointer(&s))
-	hdr.str = unsafe.Pointer(n.data(3))
-	hdr.len = nl
-	return s
+	hdr.str = unsafe.Pointer(n.data(1 + i))
+	hdr.len = l
+	return
 }
 
 func (n name) tag() (s string) {
-	tl := n.tagLen()
-	if tl == 0 {
+	if *n.data(0)&(1<<1) == 0 {
 		return ""
 	}
-	nl := n.nameLen()
+	i, l := n.readvarint(1)
+	i2, l2 := n.readvarint(1 + i + l)
 	hdr := (*stringStruct)(unsafe.Pointer(&s))
-	hdr.str = unsafe.Pointer(n.data(3 + nl + 2))
-	hdr.len = tl
-	return s
+	hdr.str = unsafe.Pointer(n.data(1 + i + l + i2))
+	hdr.len = l2
+	return
 }
 
 func (n name) pkgPath() string {
 	if n.bytes == nil || *n.data(0)&(1<<2) == 0 {
 		return ""
 	}
-	off := 3 + n.nameLen()
-	if tl := n.tagLen(); tl > 0 {
-		off += 2 + tl
+	i, l := n.readvarint(1)
+	off := 1 + i + l
+	if *n.data(0)&(1<<1) != 0 {
+		i2, l2 := n.readvarint(off)
+		off += i2 + l2
 	}
 	var nameOff nameOff
 	copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off)))[:])
@@ -515,10 +516,8 @@
 	if n.bytes == nil {
 		return false
 	}
-	if n.nameLen() != 1 {
-		return false
-	}
-	return *n.data(3) == '_'
+	_, l := n.readvarint(1)
+	return l == 1 && *n.data(2) == '_'
 }
 
 // typelinksinit scans the types from extra modules and builds the
diff --git a/src/runtime/vdso_elf32.go b/src/runtime/vdso_elf32.go
index 2720f33..456173b 100644
--- a/src/runtime/vdso_elf32.go
+++ b/src/runtime/vdso_elf32.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (386 || arm)
 // +build linux
 // +build 386 arm
 
diff --git a/src/runtime/vdso_elf64.go b/src/runtime/vdso_elf64.go
index 6ded9d6..9923bd4 100644
--- a/src/runtime/vdso_elf64.go
+++ b/src/runtime/vdso_elf64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le)
 // +build linux
 // +build amd64 arm64 mips64 mips64le ppc64 ppc64le
 
diff --git a/src/runtime/vdso_freebsd.go b/src/runtime/vdso_freebsd.go
index 122cc8b..7ca7b28 100644
--- a/src/runtime/vdso_freebsd.go
+++ b/src/runtime/vdso_freebsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build freebsd
 // +build freebsd
 
 package runtime
@@ -105,7 +106,7 @@
 	return int64((1e9 * uint64(bt.sec)) + ((1e9 * uint64(bt.frac>>32)) >> 32))
 }
 
-func walltime1() (sec int64, nsec int32) {
+func walltime() (sec int64, nsec int32) {
 	bt := vdsoClockGettime(_CLOCK_REALTIME)
 	if bt == zeroBintime {
 		return fallback_walltime()
diff --git a/src/runtime/vdso_freebsd_x86.go b/src/runtime/vdso_freebsd_x86.go
index 1fa5d80..23a5a8c 100644
--- a/src/runtime/vdso_freebsd_x86.go
+++ b/src/runtime/vdso_freebsd_x86.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build freebsd && (386 || amd64)
 // +build freebsd
 // +build 386 amd64
 
diff --git a/src/runtime/vdso_in_none.go b/src/runtime/vdso_in_none.go
index 7f4019c..c66fbf8 100644
--- a/src/runtime/vdso_in_none.go
+++ b/src/runtime/vdso_in_none.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (linux && !386 && !amd64 && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le) || !linux
 // +build linux,!386,!amd64,!arm,!arm64,!mips64,!mips64le,!ppc64,!ppc64le !linux
 
 package runtime
diff --git a/src/runtime/vdso_linux.go b/src/runtime/vdso_linux.go
index 6e29424..ae211f9 100644
--- a/src/runtime/vdso_linux.go
+++ b/src/runtime/vdso_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (386 || amd64 || arm || arm64 || mips64 || mips64le || ppc64 || ppc64le)
 // +build linux
 // +build 386 amd64 arm arm64 mips64 mips64le ppc64 ppc64le
 
diff --git a/src/runtime/vdso_linux_mips64x.go b/src/runtime/vdso_linux_mips64x.go
index 3a0f947..395ddbb 100644
--- a/src/runtime/vdso_linux_mips64x.go
+++ b/src/runtime/vdso_linux_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips64 || mips64le)
 // +build linux
 // +build mips64 mips64le
 
diff --git a/src/runtime/vdso_linux_ppc64x.go b/src/runtime/vdso_linux_ppc64x.go
index f30946e..b741dbf 100644
--- a/src/runtime/vdso_linux_ppc64x.go
+++ b/src/runtime/vdso_linux_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (ppc64 || ppc64le)
 // +build linux
 // +build ppc64 ppc64le
 
diff --git a/src/runtime/vlrt.go b/src/runtime/vlrt.go
index 996c061..cf631bd 100644
--- a/src/runtime/vlrt.go
+++ b/src/runtime/vlrt.go
@@ -23,6 +23,7 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
+//go:build arm || 386 || mips || mipsle
 // +build arm 386 mips mipsle
 
 package runtime
diff --git a/src/runtime/wincallback.go b/src/runtime/wincallback.go
index fb45222..a7a787d 100644
--- a/src/runtime/wincallback.go
+++ b/src/runtime/wincallback.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // Generate Windows callback assembly file.
@@ -21,7 +22,9 @@
 
 	buf.WriteString(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
 
+//go:build 386 || amd64
 // +build 386 amd64
+
 // runtime·callbackasm is called by external code to
 // execute Go implemented callback function. It is not
 // called from the start, instead runtime·compilecallback
@@ -30,7 +33,7 @@
 // CALL instruction in runtime·callbackasm. This determines
 // which Go callback function is executed later on.
 
-TEXT runtime·callbackasm(SB),7,$0
+TEXT runtime·callbackasm<ABIInternal>(SB),7,$0
 `)
 	for i := 0; i < maxCallback; i++ {
 		buf.WriteString("\tCALL\truntime·callbackasm1(SB)\n")
@@ -58,7 +61,7 @@
 // It then calls the Go implementation for that callback.
 #include "textflag.h"
 
-TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·callbackasm<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
 `)
 	for i := 0; i < maxCallback; i++ {
 		buf.WriteString(fmt.Sprintf("\tMOVW\t$%d, R12\n", i))
@@ -72,6 +75,34 @@
 	}
 }
 
+func genasmArm64() {
+	var buf bytes.Buffer
+
+	buf.WriteString(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
+
+// External code calls into callbackasm at an offset corresponding
+// to the callback index. Callbackasm is a table of MOV and B instructions.
+// The MOV instruction loads R12 with the callback index, and the
+// B instruction branches to callbackasm1.
+// callbackasm1 takes the callback index from R12 and
+// indexes into an array that stores information about each callback.
+// It then calls the Go implementation for that callback.
+#include "textflag.h"
+
+TEXT runtime·callbackasm<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+`)
+	for i := 0; i < maxCallback; i++ {
+		buf.WriteString(fmt.Sprintf("\tMOVD\t$%d, R12\n", i))
+		buf.WriteString("\tB\truntime·callbackasm1(SB)\n")
+	}
+
+	err := os.WriteFile("zcallback_windows_arm64.s", buf.Bytes(), 0666)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "wincallback: %s\n", err)
+		os.Exit(2)
+	}
+}
+
 func gengo() {
 	var buf bytes.Buffer
 
@@ -91,5 +122,6 @@
 func main() {
 	genasm386Amd64()
 	genasmArm()
+	genasmArm64()
 	gengo()
 }
diff --git a/src/runtime/write_err.go b/src/runtime/write_err.go
index 6b1467b..a4656fd 100644
--- a/src/runtime/write_err.go
+++ b/src/runtime/write_err.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !android
 // +build !android
 
 package runtime
diff --git a/src/runtime/write_err_android.go b/src/runtime/write_err_android.go
index 2419fc8..a876900 100644
--- a/src/runtime/write_err_android.go
+++ b/src/runtime/write_err_android.go
@@ -144,7 +144,7 @@
 	//      hdr[3:7] sec unsigned uint32, little endian.
 	//      hdr[7:11] nsec unsigned uint32, little endian.
 	hdr[0] = 0 // LOG_ID_MAIN
-	sec, nsec := walltime()
+	sec, nsec, _ := time_now()
 	packUint32(hdr[3:7], uint32(sec))
 	packUint32(hdr[7:11], uint32(nsec))
 
diff --git a/src/runtime/zcallback_windows.s b/src/runtime/zcallback_windows.s
index 7772eef..e451c2b 100644
--- a/src/runtime/zcallback_windows.s
+++ b/src/runtime/zcallback_windows.s
@@ -1,6 +1,8 @@
 // Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
 
+//go:build 386 || amd64
 // +build 386 amd64
+
 // runtime·callbackasm is called by external code to
 // execute Go implemented callback function. It is not
 // called from the start, instead runtime·compilecallback
@@ -9,7 +11,7 @@
 // CALL instruction in runtime·callbackasm. This determines
 // which Go callback function is executed later on.
 
-TEXT runtime·callbackasm(SB),7,$0
+TEXT runtime·callbackasm<ABIInternal>(SB),7,$0
 	CALL	runtime·callbackasm1(SB)
 	CALL	runtime·callbackasm1(SB)
 	CALL	runtime·callbackasm1(SB)
diff --git a/src/runtime/zcallback_windows_arm.s b/src/runtime/zcallback_windows_arm.s
index f943d84..a73a813 100644
--- a/src/runtime/zcallback_windows_arm.s
+++ b/src/runtime/zcallback_windows_arm.s
@@ -9,7 +9,7 @@
 // It then calls the Go implementation for that callback.
 #include "textflag.h"
 
-TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·callbackasm<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
 	MOVW	$0, R12
 	B	runtime·callbackasm1(SB)
 	MOVW	$1, R12
diff --git a/src/runtime/zcallback_windows_arm64.s b/src/runtime/zcallback_windows_arm64.s
new file mode 100644
index 0000000..2a6bda0
--- /dev/null
+++ b/src/runtime/zcallback_windows_arm64.s
@@ -0,0 +1,4012 @@
+// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
+
+// External code calls into callbackasm at an offset corresponding
+// to the callback index. Callbackasm is a table of MOV and B instructions.
+// The MOV instruction loads R12 with the callback index, and the
+// B instruction branches to callbackasm1.
+// callbackasm1 takes the callback index from R12 and
+// indexes into an array that stores information about each callback.
+// It then calls the Go implementation for that callback.
+#include "textflag.h"
+
+TEXT runtime·callbackasm<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+	MOVD	$0, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$2, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$3, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$4, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$5, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$6, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$7, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$8, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$9, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$10, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$11, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$12, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$13, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$14, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$15, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$16, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$17, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$18, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$19, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$20, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$21, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$22, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$23, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$24, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$25, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$26, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$27, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$28, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$29, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$30, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$31, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$32, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$33, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$34, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$35, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$36, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$37, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$38, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$39, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$40, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$41, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$42, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$43, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$44, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$45, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$46, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$47, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$48, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$49, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$50, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$51, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$52, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$53, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$54, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$55, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$56, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$57, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$58, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$59, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$60, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$61, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$62, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$63, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$64, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$65, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$66, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$67, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$68, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$69, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$70, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$71, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$72, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$73, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$74, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$75, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$76, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$77, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$78, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$79, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$80, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$81, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$82, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$83, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$84, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$85, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$86, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$87, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$88, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$89, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$90, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$91, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$92, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$93, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$94, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$95, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$96, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$97, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$98, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$99, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$100, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$101, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$102, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$103, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$104, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$105, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$106, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$107, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$108, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$109, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$110, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$111, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$112, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$113, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$114, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$115, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$116, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$117, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$118, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$119, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$120, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$121, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$122, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$123, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$124, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$125, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$126, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$127, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$128, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$129, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$130, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$131, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$132, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$133, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$134, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$135, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$136, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$137, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$138, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$139, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$140, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$141, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$142, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$143, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$144, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$145, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$146, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$147, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$148, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$149, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$150, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$151, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$152, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$153, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$154, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$155, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$156, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$157, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$158, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$159, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$160, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$161, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$162, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$163, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$164, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$165, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$166, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$167, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$168, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$169, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$170, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$171, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$172, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$173, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$174, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$175, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$176, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$177, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$178, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$179, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$180, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$181, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$182, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$183, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$184, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$185, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$186, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$187, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$188, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$189, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$190, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$191, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$192, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$193, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$194, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$195, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$196, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$197, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$198, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$199, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$200, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$201, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$202, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$203, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$204, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$205, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$206, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$207, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$208, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$209, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$210, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$211, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$212, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$213, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$214, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$215, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$216, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$217, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$218, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$219, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$220, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$221, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$222, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$223, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$224, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$225, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$226, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$227, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$228, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$229, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$230, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$231, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$232, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$233, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$234, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$235, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$236, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$237, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$238, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$239, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$240, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$241, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$242, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$243, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$244, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$245, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$246, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$247, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$248, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$249, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$250, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$251, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$252, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$253, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$254, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$255, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$256, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$257, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$258, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$259, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$260, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$261, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$262, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$263, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$264, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$265, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$266, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$267, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$268, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$269, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$270, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$271, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$272, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$273, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$274, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$275, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$276, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$277, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$278, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$279, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$280, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$281, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$282, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$283, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$284, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$285, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$286, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$287, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$288, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$289, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$290, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$291, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$292, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$293, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$294, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$295, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$296, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$297, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$298, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$299, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$300, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$301, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$302, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$303, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$304, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$305, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$306, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$307, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$308, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$309, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$310, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$311, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$312, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$313, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$314, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$315, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$316, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$317, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$318, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$319, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$320, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$321, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$322, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$323, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$324, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$325, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$326, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$327, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$328, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$329, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$330, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$331, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$332, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$333, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$334, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$335, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$336, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$337, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$338, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$339, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$340, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$341, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$342, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$343, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$344, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$345, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$346, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$347, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$348, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$349, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$350, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$351, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$352, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$353, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$354, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$355, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$356, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$357, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$358, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$359, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$360, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$361, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$362, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$363, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$364, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$365, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$366, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$367, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$368, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$369, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$370, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$371, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$372, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$373, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$374, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$375, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$376, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$377, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$378, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$379, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$380, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$381, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$382, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$383, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$384, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$385, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$386, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$387, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$388, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$389, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$390, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$391, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$392, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$393, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$394, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$395, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$396, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$397, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$398, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$399, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$400, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$401, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$402, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$403, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$404, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$405, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$406, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$407, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$408, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$409, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$410, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$411, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$412, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$413, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$414, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$415, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$416, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$417, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$418, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$419, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$420, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$421, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$422, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$423, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$424, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$425, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$426, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$427, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$428, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$429, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$430, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$431, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$432, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$433, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$434, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$435, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$436, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$437, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$438, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$439, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$440, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$441, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$442, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$443, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$444, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$445, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$446, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$447, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$448, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$449, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$450, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$451, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$452, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$453, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$454, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$455, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$456, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$457, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$458, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$459, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$460, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$461, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$462, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$463, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$464, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$465, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$466, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$467, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$468, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$469, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$470, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$471, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$472, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$473, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$474, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$475, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$476, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$477, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$478, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$479, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$480, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$481, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$482, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$483, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$484, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$485, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$486, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$487, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$488, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$489, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$490, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$491, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$492, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$493, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$494, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$495, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$496, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$497, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$498, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$499, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$500, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$501, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$502, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$503, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$504, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$505, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$506, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$507, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$508, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$509, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$510, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$511, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$512, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$513, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$514, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$515, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$516, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$517, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$518, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$519, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$520, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$521, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$522, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$523, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$524, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$525, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$526, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$527, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$528, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$529, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$530, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$531, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$532, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$533, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$534, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$535, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$536, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$537, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$538, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$539, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$540, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$541, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$542, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$543, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$544, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$545, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$546, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$547, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$548, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$549, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$550, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$551, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$552, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$553, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$554, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$555, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$556, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$557, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$558, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$559, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$560, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$561, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$562, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$563, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$564, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$565, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$566, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$567, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$568, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$569, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$570, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$571, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$572, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$573, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$574, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$575, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$576, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$577, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$578, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$579, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$580, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$581, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$582, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$583, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$584, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$585, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$586, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$587, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$588, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$589, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$590, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$591, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$592, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$593, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$594, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$595, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$596, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$597, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$598, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$599, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$600, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$601, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$602, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$603, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$604, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$605, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$606, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$607, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$608, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$609, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$610, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$611, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$612, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$613, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$614, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$615, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$616, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$617, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$618, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$619, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$620, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$621, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$622, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$623, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$624, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$625, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$626, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$627, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$628, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$629, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$630, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$631, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$632, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$633, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$634, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$635, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$636, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$637, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$638, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$639, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$640, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$641, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$642, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$643, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$644, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$645, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$646, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$647, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$648, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$649, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$650, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$651, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$652, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$653, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$654, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$655, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$656, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$657, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$658, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$659, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$660, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$661, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$662, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$663, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$664, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$665, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$666, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$667, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$668, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$669, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$670, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$671, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$672, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$673, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$674, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$675, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$676, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$677, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$678, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$679, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$680, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$681, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$682, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$683, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$684, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$685, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$686, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$687, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$688, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$689, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$690, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$691, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$692, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$693, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$694, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$695, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$696, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$697, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$698, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$699, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$700, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$701, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$702, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$703, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$704, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$705, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$706, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$707, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$708, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$709, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$710, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$711, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$712, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$713, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$714, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$715, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$716, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$717, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$718, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$719, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$720, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$721, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$722, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$723, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$724, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$725, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$726, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$727, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$728, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$729, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$730, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$731, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$732, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$733, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$734, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$735, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$736, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$737, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$738, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$739, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$740, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$741, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$742, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$743, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$744, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$745, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$746, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$747, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$748, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$749, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$750, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$751, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$752, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$753, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$754, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$755, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$756, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$757, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$758, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$759, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$760, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$761, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$762, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$763, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$764, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$765, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$766, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$767, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$768, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$769, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$770, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$771, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$772, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$773, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$774, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$775, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$776, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$777, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$778, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$779, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$780, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$781, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$782, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$783, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$784, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$785, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$786, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$787, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$788, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$789, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$790, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$791, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$792, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$793, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$794, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$795, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$796, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$797, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$798, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$799, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$800, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$801, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$802, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$803, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$804, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$805, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$806, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$807, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$808, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$809, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$810, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$811, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$812, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$813, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$814, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$815, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$816, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$817, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$818, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$819, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$820, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$821, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$822, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$823, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$824, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$825, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$826, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$827, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$828, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$829, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$830, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$831, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$832, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$833, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$834, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$835, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$836, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$837, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$838, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$839, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$840, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$841, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$842, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$843, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$844, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$845, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$846, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$847, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$848, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$849, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$850, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$851, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$852, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$853, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$854, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$855, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$856, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$857, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$858, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$859, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$860, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$861, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$862, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$863, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$864, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$865, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$866, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$867, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$868, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$869, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$870, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$871, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$872, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$873, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$874, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$875, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$876, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$877, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$878, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$879, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$880, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$881, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$882, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$883, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$884, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$885, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$886, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$887, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$888, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$889, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$890, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$891, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$892, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$893, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$894, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$895, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$896, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$897, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$898, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$899, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$900, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$901, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$902, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$903, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$904, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$905, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$906, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$907, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$908, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$909, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$910, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$911, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$912, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$913, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$914, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$915, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$916, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$917, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$918, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$919, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$920, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$921, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$922, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$923, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$924, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$925, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$926, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$927, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$928, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$929, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$930, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$931, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$932, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$933, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$934, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$935, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$936, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$937, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$938, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$939, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$940, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$941, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$942, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$943, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$944, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$945, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$946, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$947, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$948, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$949, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$950, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$951, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$952, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$953, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$954, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$955, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$956, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$957, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$958, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$959, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$960, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$961, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$962, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$963, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$964, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$965, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$966, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$967, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$968, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$969, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$970, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$971, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$972, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$973, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$974, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$975, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$976, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$977, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$978, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$979, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$980, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$981, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$982, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$983, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$984, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$985, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$986, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$987, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$988, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$989, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$990, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$991, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$992, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$993, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$994, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$995, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$996, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$997, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$998, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$999, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1000, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1001, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1002, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1003, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1004, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1005, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1006, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1007, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1008, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1009, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1010, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1011, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1012, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1013, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1014, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1015, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1016, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1017, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1018, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1019, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1020, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1021, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1022, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1023, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1024, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1025, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1026, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1027, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1028, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1029, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1030, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1031, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1032, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1033, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1034, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1035, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1036, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1037, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1038, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1039, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1040, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1041, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1042, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1043, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1044, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1045, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1046, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1047, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1048, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1049, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1050, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1051, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1052, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1053, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1054, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1055, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1056, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1057, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1058, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1059, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1060, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1061, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1062, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1063, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1064, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1065, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1066, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1067, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1068, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1069, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1070, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1071, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1072, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1073, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1074, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1075, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1076, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1077, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1078, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1079, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1080, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1081, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1082, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1083, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1084, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1085, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1086, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1087, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1088, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1089, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1090, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1091, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1092, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1093, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1094, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1095, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1096, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1097, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1098, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1099, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1100, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1101, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1102, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1103, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1104, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1105, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1106, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1107, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1108, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1109, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1110, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1111, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1112, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1113, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1114, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1115, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1116, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1117, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1118, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1119, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1120, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1121, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1122, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1123, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1124, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1125, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1126, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1127, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1128, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1129, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1130, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1131, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1132, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1133, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1134, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1135, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1136, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1137, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1138, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1139, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1140, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1141, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1142, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1143, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1144, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1145, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1146, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1147, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1148, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1149, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1150, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1151, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1152, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1153, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1154, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1155, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1156, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1157, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1158, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1159, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1160, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1161, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1162, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1163, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1164, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1165, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1166, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1167, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1168, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1169, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1170, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1171, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1172, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1173, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1174, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1175, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1176, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1177, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1178, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1179, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1180, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1181, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1182, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1183, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1184, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1185, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1186, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1187, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1188, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1189, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1190, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1191, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1192, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1193, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1194, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1195, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1196, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1197, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1198, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1199, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1200, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1201, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1202, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1203, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1204, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1205, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1206, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1207, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1208, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1209, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1210, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1211, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1212, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1213, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1214, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1215, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1216, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1217, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1218, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1219, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1220, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1221, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1222, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1223, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1224, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1225, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1226, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1227, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1228, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1229, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1230, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1231, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1232, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1233, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1234, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1235, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1236, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1237, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1238, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1239, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1240, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1241, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1242, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1243, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1244, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1245, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1246, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1247, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1248, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1249, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1250, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1251, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1252, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1253, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1254, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1255, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1256, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1257, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1258, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1259, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1260, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1261, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1262, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1263, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1264, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1265, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1266, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1267, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1268, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1269, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1270, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1271, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1272, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1273, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1274, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1275, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1276, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1277, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1278, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1279, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1280, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1281, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1282, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1283, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1284, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1285, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1286, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1287, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1288, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1289, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1290, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1291, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1292, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1293, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1294, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1295, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1296, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1297, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1298, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1299, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1300, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1301, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1302, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1303, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1304, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1305, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1306, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1307, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1308, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1309, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1310, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1311, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1312, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1313, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1314, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1315, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1316, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1317, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1318, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1319, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1320, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1321, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1322, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1323, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1324, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1325, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1326, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1327, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1328, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1329, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1330, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1331, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1332, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1333, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1334, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1335, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1336, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1337, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1338, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1339, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1340, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1341, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1342, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1343, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1344, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1345, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1346, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1347, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1348, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1349, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1350, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1351, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1352, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1353, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1354, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1355, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1356, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1357, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1358, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1359, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1360, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1361, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1362, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1363, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1364, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1365, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1366, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1367, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1368, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1369, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1370, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1371, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1372, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1373, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1374, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1375, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1376, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1377, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1378, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1379, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1380, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1381, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1382, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1383, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1384, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1385, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1386, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1387, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1388, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1389, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1390, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1391, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1392, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1393, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1394, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1395, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1396, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1397, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1398, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1399, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1400, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1401, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1402, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1403, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1404, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1405, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1406, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1407, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1408, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1409, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1410, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1411, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1412, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1413, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1414, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1415, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1416, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1417, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1418, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1419, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1420, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1421, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1422, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1423, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1424, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1425, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1426, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1427, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1428, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1429, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1430, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1431, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1432, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1433, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1434, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1435, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1436, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1437, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1438, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1439, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1440, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1441, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1442, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1443, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1444, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1445, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1446, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1447, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1448, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1449, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1450, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1451, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1452, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1453, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1454, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1455, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1456, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1457, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1458, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1459, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1460, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1461, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1462, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1463, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1464, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1465, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1466, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1467, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1468, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1469, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1470, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1471, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1472, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1473, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1474, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1475, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1476, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1477, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1478, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1479, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1480, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1481, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1482, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1483, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1484, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1485, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1486, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1487, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1488, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1489, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1490, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1491, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1492, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1493, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1494, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1495, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1496, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1497, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1498, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1499, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1500, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1501, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1502, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1503, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1504, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1505, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1506, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1507, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1508, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1509, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1510, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1511, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1512, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1513, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1514, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1515, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1516, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1517, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1518, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1519, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1520, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1521, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1522, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1523, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1524, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1525, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1526, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1527, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1528, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1529, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1530, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1531, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1532, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1533, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1534, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1535, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1536, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1537, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1538, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1539, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1540, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1541, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1542, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1543, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1544, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1545, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1546, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1547, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1548, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1549, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1550, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1551, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1552, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1553, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1554, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1555, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1556, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1557, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1558, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1559, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1560, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1561, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1562, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1563, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1564, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1565, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1566, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1567, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1568, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1569, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1570, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1571, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1572, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1573, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1574, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1575, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1576, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1577, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1578, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1579, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1580, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1581, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1582, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1583, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1584, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1585, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1586, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1587, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1588, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1589, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1590, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1591, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1592, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1593, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1594, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1595, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1596, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1597, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1598, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1599, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1600, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1601, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1602, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1603, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1604, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1605, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1606, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1607, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1608, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1609, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1610, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1611, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1612, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1613, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1614, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1615, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1616, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1617, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1618, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1619, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1620, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1621, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1622, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1623, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1624, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1625, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1626, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1627, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1628, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1629, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1630, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1631, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1632, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1633, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1634, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1635, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1636, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1637, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1638, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1639, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1640, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1641, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1642, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1643, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1644, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1645, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1646, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1647, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1648, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1649, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1650, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1651, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1652, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1653, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1654, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1655, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1656, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1657, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1658, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1659, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1660, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1661, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1662, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1663, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1664, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1665, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1666, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1667, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1668, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1669, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1670, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1671, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1672, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1673, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1674, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1675, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1676, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1677, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1678, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1679, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1680, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1681, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1682, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1683, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1684, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1685, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1686, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1687, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1688, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1689, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1690, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1691, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1692, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1693, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1694, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1695, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1696, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1697, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1698, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1699, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1700, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1701, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1702, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1703, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1704, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1705, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1706, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1707, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1708, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1709, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1710, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1711, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1712, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1713, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1714, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1715, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1716, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1717, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1718, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1719, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1720, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1721, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1722, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1723, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1724, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1725, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1726, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1727, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1728, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1729, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1730, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1731, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1732, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1733, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1734, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1735, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1736, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1737, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1738, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1739, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1740, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1741, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1742, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1743, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1744, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1745, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1746, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1747, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1748, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1749, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1750, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1751, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1752, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1753, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1754, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1755, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1756, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1757, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1758, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1759, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1760, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1761, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1762, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1763, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1764, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1765, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1766, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1767, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1768, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1769, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1770, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1771, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1772, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1773, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1774, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1775, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1776, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1777, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1778, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1779, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1780, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1781, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1782, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1783, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1784, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1785, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1786, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1787, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1788, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1789, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1790, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1791, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1792, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1793, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1794, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1795, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1796, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1797, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1798, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1799, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1800, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1801, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1802, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1803, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1804, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1805, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1806, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1807, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1808, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1809, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1810, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1811, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1812, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1813, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1814, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1815, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1816, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1817, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1818, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1819, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1820, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1821, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1822, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1823, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1824, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1825, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1826, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1827, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1828, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1829, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1830, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1831, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1832, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1833, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1834, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1835, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1836, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1837, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1838, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1839, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1840, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1841, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1842, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1843, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1844, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1845, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1846, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1847, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1848, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1849, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1850, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1851, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1852, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1853, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1854, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1855, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1856, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1857, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1858, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1859, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1860, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1861, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1862, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1863, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1864, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1865, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1866, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1867, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1868, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1869, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1870, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1871, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1872, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1873, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1874, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1875, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1876, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1877, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1878, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1879, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1880, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1881, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1882, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1883, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1884, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1885, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1886, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1887, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1888, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1889, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1890, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1891, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1892, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1893, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1894, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1895, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1896, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1897, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1898, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1899, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1900, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1901, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1902, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1903, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1904, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1905, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1906, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1907, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1908, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1909, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1910, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1911, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1912, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1913, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1914, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1915, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1916, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1917, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1918, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1919, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1920, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1921, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1922, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1923, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1924, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1925, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1926, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1927, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1928, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1929, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1930, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1931, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1932, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1933, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1934, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1935, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1936, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1937, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1938, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1939, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1940, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1941, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1942, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1943, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1944, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1945, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1946, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1947, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1948, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1949, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1950, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1951, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1952, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1953, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1954, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1955, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1956, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1957, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1958, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1959, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1960, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1961, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1962, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1963, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1964, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1965, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1966, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1967, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1968, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1969, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1970, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1971, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1972, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1973, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1974, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1975, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1976, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1977, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1978, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1979, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1980, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1981, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1982, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1983, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1984, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1985, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1986, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1987, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1988, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1989, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1990, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1991, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1992, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1993, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1994, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1995, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1996, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1997, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1998, R12
+	B	runtime·callbackasm1(SB)
+	MOVD	$1999, R12
+	B	runtime·callbackasm1(SB)
diff --git a/src/sort/example_search_test.go b/src/sort/example_search_test.go
index 6928f0f..856422a 100644
--- a/src/sort/example_search_test.go
+++ b/src/sort/example_search_test.go
@@ -40,3 +40,35 @@
 	// Output:
 	// found 6 at index 7 in [55 45 36 28 21 15 10 6 3 1]
 }
+
+// This example demonstrates searching for float64 in a list sorted in ascending order.
+func ExampleSearchFloat64s() {
+	a := []float64{1.0, 2.0, 3.3, 4.6, 6.1, 7.2, 8.0}
+
+	x := 2.0
+	i := sort.SearchFloat64s(a, x)
+	fmt.Printf("found %g at index %d in %v\n", x, i, a)
+
+	x = 0.5
+	i = sort.SearchFloat64s(a, x)
+	fmt.Printf("%g not found, can be inserted at index %d in %v\n", x, i, a)
+	// Output:
+	// found 2 at index 1 in [1 2 3.3 4.6 6.1 7.2 8]
+	// 0.5 not found, can be inserted at index 0 in [1 2 3.3 4.6 6.1 7.2 8]
+}
+
+// This example demonstrates searching for int in a list sorted in ascending order.
+func ExampleSearchInts() {
+	a := []int{1, 2, 3, 4, 6, 7, 8}
+
+	x := 2
+	i := sort.SearchInts(a, x)
+	fmt.Printf("found %d at index %d in %v\n", x, i, a)
+
+	x = 5
+	i = sort.SearchInts(a, x)
+	fmt.Printf("%d not found, can be inserted at index %d in %v\n", x, i, a)
+	// Output:
+	// found 2 at index 1 in [1 2 3 4 6 7 8]
+	// 5 not found, can be inserted at index 4 in [1 2 3 4 6 7 8]
+}
diff --git a/src/sort/genzfunc.go b/src/sort/genzfunc.go
index e7eb573..ed04e33 100644
--- a/src/sort/genzfunc.go
+++ b/src/sort/genzfunc.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // This program is run via "go generate" (via a directive in sort.go)
diff --git a/src/sort/slice_go113.go b/src/sort/slice_go113.go
index bf24db7..53542db 100644
--- a/src/sort/slice_go113.go
+++ b/src/sort/slice_go113.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.13
 // +build go1.13
 
 package sort
diff --git a/src/sort/slice_go14.go b/src/sort/slice_go14.go
index 3bf5cbc..5d5949f 100644
--- a/src/sort/slice_go14.go
+++ b/src/sort/slice_go14.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !go1.8
 // +build !go1.8
 
 package sort
diff --git a/src/sort/slice_go18.go b/src/sort/slice_go18.go
index e176604..1538477 100644
--- a/src/sort/slice_go18.go
+++ b/src/sort/slice_go18.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.8 && !go1.13
 // +build go1.8,!go1.13
 
 package sort
diff --git a/src/strconv/atof.go b/src/strconv/atof.go
index 9010a66..57556c7 100644
--- a/src/strconv/atof.go
+++ b/src/strconv/atof.go
@@ -689,7 +689,7 @@
 // as their respective special floating point values. It ignores case when matching.
 func ParseFloat(s string, bitSize int) (float64, error) {
 	f, n, err := parseFloatPrefix(s, bitSize)
-	if err == nil && n != len(s) {
+	if n != len(s) && (err == nil || err.(*NumError).Err != ErrSyntax) {
 		return 0, syntaxError(fnParseFloat, s)
 	}
 	return f, err
diff --git a/src/strconv/atof_test.go b/src/strconv/atof_test.go
index 3c058b9..aa587a4 100644
--- a/src/strconv/atof_test.go
+++ b/src/strconv/atof_test.go
@@ -342,6 +342,9 @@
 	{"0x12.345p-_12", "0", ErrSyntax},
 	{"0x12.345p+1__2", "0", ErrSyntax},
 	{"0x12.345p+12_", "0", ErrSyntax},
+
+	{"1e100x", "0", ErrSyntax},
+	{"1e1000x", "0", ErrSyntax},
 }
 
 var atof32tests = []atofTest{
diff --git a/src/strconv/atoi.go b/src/strconv/atoi.go
index f6c4efa..631b487 100644
--- a/src/strconv/atoi.go
+++ b/src/strconv/atoi.go
@@ -57,6 +57,8 @@
 const maxUint64 = 1<<64 - 1
 
 // ParseUint is like ParseInt but for unsigned numbers.
+//
+// A sign prefix is not permitted.
 func ParseUint(s string, base int, bitSize int) (uint64, error) {
 	const fnParseUint = "ParseUint"
 
@@ -143,7 +145,7 @@
 
 		n1 := n + uint64(d)
 		if n1 < n || n1 > maxVal {
-			// n+v overflows
+			// n+d overflows
 			return maxVal, rangeError(fnParseUint, s0)
 		}
 		n = n1
@@ -159,10 +161,13 @@
 // 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.
 //
+// The string may begin with a leading sign: "+" or "-".
+//
 // If the base argument is 0, the true base is implied by the string's
-// prefix: 2 for "0b", 8 for "0" or "0o", 16 for "0x", and 10 otherwise.
-// Also, for argument base 0 only, underscore characters are permitted
-// as defined by the Go syntax for integer literals.
+// prefix following the sign (if present): 2 for "0b", 8 for "0" or "0o",
+// 16 for "0x", and 10 otherwise. Also, for argument base 0 only,
+// underscore characters are permitted as defined by the Go syntax for
+// integer literals.
 //
 // The bitSize argument specifies the integer type
 // that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
diff --git a/src/strconv/atoi_test.go b/src/strconv/atoi_test.go
index 178fb01..867fa66 100644
--- a/src/strconv/atoi_test.go
+++ b/src/strconv/atoi_test.go
@@ -33,6 +33,9 @@
 	{"_12345", 0, ErrSyntax},
 	{"1__2345", 0, ErrSyntax},
 	{"12345_", 0, ErrSyntax},
+	{"-0", 0, ErrSyntax},
+	{"-1", 0, ErrSyntax},
+	{"+1", 0, ErrSyntax},
 }
 
 type parseUint64BaseTest struct {
@@ -140,8 +143,10 @@
 	{"", 0, ErrSyntax},
 	{"0", 0, nil},
 	{"-0", 0, nil},
+	{"+0", 0, nil},
 	{"1", 1, nil},
 	{"-1", -1, nil},
+	{"+1", 1, nil},
 	{"12345", 12345, nil},
 	{"-12345", -12345, nil},
 	{"012345", 12345, nil},
@@ -236,6 +241,11 @@
 	{"0__12345", 0, 0, ErrSyntax},
 	{"01234__5", 0, 0, ErrSyntax},
 	{"012345_", 0, 0, ErrSyntax},
+
+	{"+0xf", 0, 0xf, nil},
+	{"-0xf", 0, -0xf, nil},
+	{"0x+f", 0, 0, ErrSyntax},
+	{"0x-f", 0, 0, ErrSyntax},
 }
 
 type parseUint32Test struct {
diff --git a/src/strconv/bytealg.go b/src/strconv/bytealg.go
new file mode 100644
index 0000000..a2bb12c
--- /dev/null
+++ b/src/strconv/bytealg.go
@@ -0,0 +1,15 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !compiler_bootstrap
+// +build !compiler_bootstrap
+
+package strconv
+
+import "internal/bytealg"
+
+// index returns the index of the first instance of c in s, or -1 if missing.
+func index(s string, c byte) int {
+	return bytealg.IndexByteString(s, c)
+}
diff --git a/src/strconv/bytealg_bootstrap.go b/src/strconv/bytealg_bootstrap.go
new file mode 100644
index 0000000..0ed79f4
--- /dev/null
+++ b/src/strconv/bytealg_bootstrap.go
@@ -0,0 +1,18 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build compiler_bootstrap
+// +build compiler_bootstrap
+
+package strconv
+
+// index returns the index of the first instance of c in s, or -1 if missing.
+func index(s string, c byte) int {
+	for i := 0; i < len(s); i++ {
+		if s[i] == c {
+			return i
+		}
+	}
+	return -1
+}
diff --git a/src/strconv/eisel_lemire.go b/src/strconv/eisel_lemire.go
index 6c7f852..fecd1b9 100644
--- a/src/strconv/eisel_lemire.go
+++ b/src/strconv/eisel_lemire.go
@@ -29,7 +29,7 @@
 	// Exp10 Range.
 	if man == 0 {
 		if neg {
-			f = math.Float64frombits(0x80000000_00000000) // Negative zero.
+			f = math.Float64frombits(0x8000000000000000) // Negative zero.
 		}
 		return f, true
 	}
@@ -39,7 +39,7 @@
 
 	// Normalization.
 	clz := bits.LeadingZeros64(man)
-	man <<= clz
+	man <<= uint(clz)
 	const float64ExponentBias = 1023
 	retExp2 := uint64(217706*exp10>>16+64+float64ExponentBias) - uint64(clz)
 
@@ -84,9 +84,9 @@
 	if retExp2-1 >= 0x7FF-1 {
 		return 0, false
 	}
-	retBits := retExp2<<52 | retMantissa&0x000FFFFF_FFFFFFFF
+	retBits := retExp2<<52 | retMantissa&0x000FFFFFFFFFFFFF
 	if neg {
-		retBits |= 0x80000000_00000000
+		retBits |= 0x8000000000000000
 	}
 	return math.Float64frombits(retBits), true
 }
@@ -114,7 +114,7 @@
 
 	// Normalization.
 	clz := bits.LeadingZeros64(man)
-	man <<= clz
+	man <<= uint(clz)
 	const float32ExponentBias = 127
 	retExp2 := uint64(217706*exp10>>16+64+float32ExponentBias) - uint64(clz)
 
@@ -122,13 +122,13 @@
 	xHi, xLo := bits.Mul64(man, detailedPowersOfTen[exp10-detailedPowersOfTenMinExp10][1])
 
 	// Wider Approximation.
-	if xHi&0x3F_FFFFFFFF == 0x3F_FFFFFFFF && xLo+man < man {
+	if xHi&0x3FFFFFFFFF == 0x3FFFFFFFFF && xLo+man < man {
 		yHi, yLo := bits.Mul64(man, detailedPowersOfTen[exp10-detailedPowersOfTenMinExp10][0])
 		mergedHi, mergedLo := xHi, xLo+yHi
 		if mergedLo < xLo {
 			mergedHi++
 		}
-		if mergedHi&0x3F_FFFFFFFF == 0x3F_FFFFFFFF && mergedLo+1 == 0 && yLo+man < man {
+		if mergedHi&0x3FFFFFFFFF == 0x3FFFFFFFFF && mergedLo+1 == 0 && yLo+man < man {
 			return 0, false
 		}
 		xHi, xLo = mergedHi, mergedLo
@@ -140,7 +140,7 @@
 	retExp2 -= 1 ^ msb
 
 	// Half-way Ambiguity.
-	if xLo == 0 && xHi&0x3F_FFFFFFFF == 0 && retMantissa&3 == 1 {
+	if xLo == 0 && xHi&0x3FFFFFFFFF == 0 && retMantissa&3 == 1 {
 		return 0, false
 	}
 
diff --git a/src/strconv/extfloat.go b/src/strconv/extfloat.go
deleted file mode 100644
index e7bfe51..0000000
--- a/src/strconv/extfloat.go
+++ /dev/null
@@ -1,517 +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 strconv
-
-import (
-	"math/bits"
-)
-
-// An extFloat represents an extended floating-point number, with more
-// precision than a float64. It does not try to save bits: the
-// number represented by the structure is mant*(2^exp), with a negative
-// sign if neg is true.
-type extFloat struct {
-	mant uint64
-	exp  int
-	neg  bool
-}
-
-// Powers of ten taken from double-conversion library.
-// https://code.google.com/p/double-conversion/
-const (
-	firstPowerOfTen = -348
-	stepPowerOfTen  = 8
-)
-
-var smallPowersOfTen = [...]extFloat{
-	{1 << 63, -63, false},        // 1
-	{0xa << 60, -60, false},      // 1e1
-	{0x64 << 57, -57, false},     // 1e2
-	{0x3e8 << 54, -54, false},    // 1e3
-	{0x2710 << 50, -50, false},   // 1e4
-	{0x186a0 << 47, -47, false},  // 1e5
-	{0xf4240 << 44, -44, false},  // 1e6
-	{0x989680 << 40, -40, false}, // 1e7
-}
-
-var powersOfTen = [...]extFloat{
-	{0xfa8fd5a0081c0288, -1220, false}, // 10^-348
-	{0xbaaee17fa23ebf76, -1193, false}, // 10^-340
-	{0x8b16fb203055ac76, -1166, false}, // 10^-332
-	{0xcf42894a5dce35ea, -1140, false}, // 10^-324
-	{0x9a6bb0aa55653b2d, -1113, false}, // 10^-316
-	{0xe61acf033d1a45df, -1087, false}, // 10^-308
-	{0xab70fe17c79ac6ca, -1060, false}, // 10^-300
-	{0xff77b1fcbebcdc4f, -1034, false}, // 10^-292
-	{0xbe5691ef416bd60c, -1007, false}, // 10^-284
-	{0x8dd01fad907ffc3c, -980, false},  // 10^-276
-	{0xd3515c2831559a83, -954, false},  // 10^-268
-	{0x9d71ac8fada6c9b5, -927, false},  // 10^-260
-	{0xea9c227723ee8bcb, -901, false},  // 10^-252
-	{0xaecc49914078536d, -874, false},  // 10^-244
-	{0x823c12795db6ce57, -847, false},  // 10^-236
-	{0xc21094364dfb5637, -821, false},  // 10^-228
-	{0x9096ea6f3848984f, -794, false},  // 10^-220
-	{0xd77485cb25823ac7, -768, false},  // 10^-212
-	{0xa086cfcd97bf97f4, -741, false},  // 10^-204
-	{0xef340a98172aace5, -715, false},  // 10^-196
-	{0xb23867fb2a35b28e, -688, false},  // 10^-188
-	{0x84c8d4dfd2c63f3b, -661, false},  // 10^-180
-	{0xc5dd44271ad3cdba, -635, false},  // 10^-172
-	{0x936b9fcebb25c996, -608, false},  // 10^-164
-	{0xdbac6c247d62a584, -582, false},  // 10^-156
-	{0xa3ab66580d5fdaf6, -555, false},  // 10^-148
-	{0xf3e2f893dec3f126, -529, false},  // 10^-140
-	{0xb5b5ada8aaff80b8, -502, false},  // 10^-132
-	{0x87625f056c7c4a8b, -475, false},  // 10^-124
-	{0xc9bcff6034c13053, -449, false},  // 10^-116
-	{0x964e858c91ba2655, -422, false},  // 10^-108
-	{0xdff9772470297ebd, -396, false},  // 10^-100
-	{0xa6dfbd9fb8e5b88f, -369, false},  // 10^-92
-	{0xf8a95fcf88747d94, -343, false},  // 10^-84
-	{0xb94470938fa89bcf, -316, false},  // 10^-76
-	{0x8a08f0f8bf0f156b, -289, false},  // 10^-68
-	{0xcdb02555653131b6, -263, false},  // 10^-60
-	{0x993fe2c6d07b7fac, -236, false},  // 10^-52
-	{0xe45c10c42a2b3b06, -210, false},  // 10^-44
-	{0xaa242499697392d3, -183, false},  // 10^-36
-	{0xfd87b5f28300ca0e, -157, false},  // 10^-28
-	{0xbce5086492111aeb, -130, false},  // 10^-20
-	{0x8cbccc096f5088cc, -103, false},  // 10^-12
-	{0xd1b71758e219652c, -77, false},   // 10^-4
-	{0x9c40000000000000, -50, false},   // 10^4
-	{0xe8d4a51000000000, -24, false},   // 10^12
-	{0xad78ebc5ac620000, 3, false},     // 10^20
-	{0x813f3978f8940984, 30, false},    // 10^28
-	{0xc097ce7bc90715b3, 56, false},    // 10^36
-	{0x8f7e32ce7bea5c70, 83, false},    // 10^44
-	{0xd5d238a4abe98068, 109, false},   // 10^52
-	{0x9f4f2726179a2245, 136, false},   // 10^60
-	{0xed63a231d4c4fb27, 162, false},   // 10^68
-	{0xb0de65388cc8ada8, 189, false},   // 10^76
-	{0x83c7088e1aab65db, 216, false},   // 10^84
-	{0xc45d1df942711d9a, 242, false},   // 10^92
-	{0x924d692ca61be758, 269, false},   // 10^100
-	{0xda01ee641a708dea, 295, false},   // 10^108
-	{0xa26da3999aef774a, 322, false},   // 10^116
-	{0xf209787bb47d6b85, 348, false},   // 10^124
-	{0xb454e4a179dd1877, 375, false},   // 10^132
-	{0x865b86925b9bc5c2, 402, false},   // 10^140
-	{0xc83553c5c8965d3d, 428, false},   // 10^148
-	{0x952ab45cfa97a0b3, 455, false},   // 10^156
-	{0xde469fbd99a05fe3, 481, false},   // 10^164
-	{0xa59bc234db398c25, 508, false},   // 10^172
-	{0xf6c69a72a3989f5c, 534, false},   // 10^180
-	{0xb7dcbf5354e9bece, 561, false},   // 10^188
-	{0x88fcf317f22241e2, 588, false},   // 10^196
-	{0xcc20ce9bd35c78a5, 614, false},   // 10^204
-	{0x98165af37b2153df, 641, false},   // 10^212
-	{0xe2a0b5dc971f303a, 667, false},   // 10^220
-	{0xa8d9d1535ce3b396, 694, false},   // 10^228
-	{0xfb9b7cd9a4a7443c, 720, false},   // 10^236
-	{0xbb764c4ca7a44410, 747, false},   // 10^244
-	{0x8bab8eefb6409c1a, 774, false},   // 10^252
-	{0xd01fef10a657842c, 800, false},   // 10^260
-	{0x9b10a4e5e9913129, 827, false},   // 10^268
-	{0xe7109bfba19c0c9d, 853, false},   // 10^276
-	{0xac2820d9623bf429, 880, false},   // 10^284
-	{0x80444b5e7aa7cf85, 907, false},   // 10^292
-	{0xbf21e44003acdd2d, 933, false},   // 10^300
-	{0x8e679c2f5e44ff8f, 960, false},   // 10^308
-	{0xd433179d9c8cb841, 986, false},   // 10^316
-	{0x9e19db92b4e31ba9, 1013, false},  // 10^324
-	{0xeb96bf6ebadf77d9, 1039, false},  // 10^332
-	{0xaf87023b9bf0ee6b, 1066, false},  // 10^340
-}
-
-// AssignComputeBounds sets f to the floating point value
-// defined by mant, exp and precision given by flt. It returns
-// lower, upper such that any number in the closed interval
-// [lower, upper] is converted back to the same floating point number.
-func (f *extFloat) AssignComputeBounds(mant uint64, exp int, neg bool, flt *floatInfo) (lower, upper extFloat) {
-	f.mant = mant
-	f.exp = exp - int(flt.mantbits)
-	f.neg = neg
-	if f.exp <= 0 && mant == (mant>>uint(-f.exp))<<uint(-f.exp) {
-		// An exact integer
-		f.mant >>= uint(-f.exp)
-		f.exp = 0
-		return *f, *f
-	}
-	expBiased := exp - flt.bias
-
-	upper = extFloat{mant: 2*f.mant + 1, exp: f.exp - 1, neg: f.neg}
-	if mant != 1<<flt.mantbits || expBiased == 1 {
-		lower = extFloat{mant: 2*f.mant - 1, exp: f.exp - 1, neg: f.neg}
-	} else {
-		lower = extFloat{mant: 4*f.mant - 1, exp: f.exp - 2, neg: f.neg}
-	}
-	return
-}
-
-// Normalize normalizes f so that the highest bit of the mantissa is
-// set, and returns the number by which the mantissa was left-shifted.
-func (f *extFloat) Normalize() uint {
-	// bits.LeadingZeros64 would return 64
-	if f.mant == 0 {
-		return 0
-	}
-	shift := bits.LeadingZeros64(f.mant)
-	f.mant <<= uint(shift)
-	f.exp -= shift
-	return uint(shift)
-}
-
-// Multiply sets f to the product f*g: the result is correctly rounded,
-// but not normalized.
-func (f *extFloat) Multiply(g extFloat) {
-	hi, lo := bits.Mul64(f.mant, g.mant)
-	// Round up.
-	f.mant = hi + (lo >> 63)
-	f.exp = f.exp + g.exp + 64
-}
-
-var uint64pow10 = [...]uint64{
-	1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
-	1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
-}
-
-// Frexp10 is an analogue of math.Frexp for decimal powers. It scales
-// f by an approximate power of ten 10^-exp, and returns exp10, so
-// that f*10^exp10 has the same value as the old f, up to an ulp,
-// as well as the index of 10^-exp in the powersOfTen table.
-func (f *extFloat) frexp10() (exp10, index int) {
-	// The constants expMin and expMax constrain the final value of the
-	// binary exponent of f. We want a small integral part in the result
-	// because finding digits of an integer requires divisions, whereas
-	// digits of the fractional part can be found by repeatedly multiplying
-	// by 10.
-	const expMin = -60
-	const expMax = -32
-	// Find power of ten such that x * 10^n has a binary exponent
-	// between expMin and expMax.
-	approxExp10 := ((expMin+expMax)/2 - f.exp) * 28 / 93 // log(10)/log(2) is close to 93/28.
-	i := (approxExp10 - firstPowerOfTen) / stepPowerOfTen
-Loop:
-	for {
-		exp := f.exp + powersOfTen[i].exp + 64
-		switch {
-		case exp < expMin:
-			i++
-		case exp > expMax:
-			i--
-		default:
-			break Loop
-		}
-	}
-	// Apply the desired decimal shift on f. It will have exponent
-	// in the desired range. This is multiplication by 10^-exp10.
-	f.Multiply(powersOfTen[i])
-
-	return -(firstPowerOfTen + i*stepPowerOfTen), i
-}
-
-// frexp10Many applies a common shift by a power of ten to a, b, c.
-func frexp10Many(a, b, c *extFloat) (exp10 int) {
-	exp10, i := c.frexp10()
-	a.Multiply(powersOfTen[i])
-	b.Multiply(powersOfTen[i])
-	return
-}
-
-// FixedDecimal stores in d the first n significant digits
-// of the decimal representation of f. It returns false
-// if it cannot be sure of the answer.
-func (f *extFloat) FixedDecimal(d *decimalSlice, n int) bool {
-	if f.mant == 0 {
-		d.nd = 0
-		d.dp = 0
-		d.neg = f.neg
-		return true
-	}
-	if n == 0 {
-		panic("strconv: internal error: extFloat.FixedDecimal called with n == 0")
-	}
-	// Multiply by an appropriate power of ten to have a reasonable
-	// number to process.
-	f.Normalize()
-	exp10, _ := f.frexp10()
-
-	shift := uint(-f.exp)
-	integer := uint32(f.mant >> shift)
-	fraction := f.mant - (uint64(integer) << shift)
-	ε := uint64(1) // ε is the uncertainty we have on the mantissa of f.
-
-	// Write exactly n digits to d.
-	needed := n        // how many digits are left to write.
-	integerDigits := 0 // the number of decimal digits of integer.
-	pow10 := uint64(1) // the power of ten by which f was scaled.
-	for i, pow := 0, uint64(1); i < 20; i++ {
-		if pow > uint64(integer) {
-			integerDigits = i
-			break
-		}
-		pow *= 10
-	}
-	rest := integer
-	if integerDigits > needed {
-		// the integral part is already large, trim the last digits.
-		pow10 = uint64pow10[integerDigits-needed]
-		integer /= uint32(pow10)
-		rest -= integer * uint32(pow10)
-	} else {
-		rest = 0
-	}
-
-	// Write the digits of integer: the digits of rest are omitted.
-	var buf [32]byte
-	pos := len(buf)
-	for v := integer; v > 0; {
-		v1 := v / 10
-		v -= 10 * v1
-		pos--
-		buf[pos] = byte(v + '0')
-		v = v1
-	}
-	for i := pos; i < len(buf); i++ {
-		d.d[i-pos] = buf[i]
-	}
-	nd := len(buf) - pos
-	d.nd = nd
-	d.dp = integerDigits + exp10
-	needed -= nd
-
-	if needed > 0 {
-		if rest != 0 || pow10 != 1 {
-			panic("strconv: internal error, rest != 0 but needed > 0")
-		}
-		// Emit digits for the fractional part. Each time, 10*fraction
-		// fits in a uint64 without overflow.
-		for needed > 0 {
-			fraction *= 10
-			ε *= 10 // the uncertainty scales as we multiply by ten.
-			if 2*ε > 1<<shift {
-				// the error is so large it could modify which digit to write, abort.
-				return false
-			}
-			digit := fraction >> shift
-			d.d[nd] = byte(digit + '0')
-			fraction -= digit << shift
-			nd++
-			needed--
-		}
-		d.nd = nd
-	}
-
-	// We have written a truncation of f (a numerator / 10^d.dp). The remaining part
-	// can be interpreted as a small number (< 1) to be added to the last digit of the
-	// numerator.
-	//
-	// If rest > 0, the amount is:
-	//    (rest<<shift | fraction) / (pow10 << shift)
-	//    fraction being known with a ±ε uncertainty.
-	//    The fact that n > 0 guarantees that pow10 << shift does not overflow a uint64.
-	//
-	// If rest = 0, pow10 == 1 and the amount is
-	//    fraction / (1 << shift)
-	//    fraction being known with a ±ε uncertainty.
-	//
-	// We pass this information to the rounding routine for adjustment.
-
-	ok := adjustLastDigitFixed(d, uint64(rest)<<shift|fraction, pow10, shift, ε)
-	if !ok {
-		return false
-	}
-	// Trim trailing zeros.
-	for i := d.nd - 1; i >= 0; i-- {
-		if d.d[i] != '0' {
-			d.nd = i + 1
-			break
-		}
-	}
-	return true
-}
-
-// adjustLastDigitFixed assumes d contains the representation of the integral part
-// of some number, whose fractional part is num / (den << shift). The numerator
-// num is only known up to an uncertainty of size ε, assumed to be less than
-// (den << shift)/2.
-//
-// It will increase the last digit by one to account for correct rounding, typically
-// when the fractional part is greater than 1/2, and will return false if ε is such
-// that no correct answer can be given.
-func adjustLastDigitFixed(d *decimalSlice, num, den uint64, shift uint, ε uint64) bool {
-	if num > den<<shift {
-		panic("strconv: num > den<<shift in adjustLastDigitFixed")
-	}
-	if 2*ε > den<<shift {
-		panic("strconv: ε > (den<<shift)/2")
-	}
-	if 2*(num+ε) < den<<shift {
-		return true
-	}
-	if 2*(num-ε) > den<<shift {
-		// increment d by 1.
-		i := d.nd - 1
-		for ; i >= 0; i-- {
-			if d.d[i] == '9' {
-				d.nd--
-			} else {
-				break
-			}
-		}
-		if i < 0 {
-			d.d[0] = '1'
-			d.nd = 1
-			d.dp++
-		} else {
-			d.d[i]++
-		}
-		return true
-	}
-	return false
-}
-
-// ShortestDecimal stores in d the shortest decimal representation of f
-// which belongs to the open interval (lower, upper), where f is supposed
-// to lie. It returns false whenever the result is unsure. The implementation
-// uses the Grisu3 algorithm.
-func (f *extFloat) ShortestDecimal(d *decimalSlice, lower, upper *extFloat) bool {
-	if f.mant == 0 {
-		d.nd = 0
-		d.dp = 0
-		d.neg = f.neg
-		return true
-	}
-	if f.exp == 0 && *lower == *f && *lower == *upper {
-		// an exact integer.
-		var buf [24]byte
-		n := len(buf) - 1
-		for v := f.mant; v > 0; {
-			v1 := v / 10
-			v -= 10 * v1
-			buf[n] = byte(v + '0')
-			n--
-			v = v1
-		}
-		nd := len(buf) - n - 1
-		for i := 0; i < nd; i++ {
-			d.d[i] = buf[n+1+i]
-		}
-		d.nd, d.dp = nd, nd
-		for d.nd > 0 && d.d[d.nd-1] == '0' {
-			d.nd--
-		}
-		if d.nd == 0 {
-			d.dp = 0
-		}
-		d.neg = f.neg
-		return true
-	}
-	upper.Normalize()
-	// Uniformize exponents.
-	if f.exp > upper.exp {
-		f.mant <<= uint(f.exp - upper.exp)
-		f.exp = upper.exp
-	}
-	if lower.exp > upper.exp {
-		lower.mant <<= uint(lower.exp - upper.exp)
-		lower.exp = upper.exp
-	}
-
-	exp10 := frexp10Many(lower, f, upper)
-	// Take a safety margin due to rounding in frexp10Many, but we lose precision.
-	upper.mant++
-	lower.mant--
-
-	// The shortest representation of f is either rounded up or down, but
-	// in any case, it is a truncation of upper.
-	shift := uint(-upper.exp)
-	integer := uint32(upper.mant >> shift)
-	fraction := upper.mant - (uint64(integer) << shift)
-
-	// How far we can go down from upper until the result is wrong.
-	allowance := upper.mant - lower.mant
-	// How far we should go to get a very precise result.
-	targetDiff := upper.mant - f.mant
-
-	// Count integral digits: there are at most 10.
-	var integerDigits int
-	for i, pow := 0, uint64(1); i < 20; i++ {
-		if pow > uint64(integer) {
-			integerDigits = i
-			break
-		}
-		pow *= 10
-	}
-	for i := 0; i < integerDigits; i++ {
-		pow := uint64pow10[integerDigits-i-1]
-		digit := integer / uint32(pow)
-		d.d[i] = byte(digit + '0')
-		integer -= digit * uint32(pow)
-		// evaluate whether we should stop.
-		if currentDiff := uint64(integer)<<shift + fraction; currentDiff < allowance {
-			d.nd = i + 1
-			d.dp = integerDigits + exp10
-			d.neg = f.neg
-			// Sometimes allowance is so large the last digit might need to be
-			// decremented to get closer to f.
-			return adjustLastDigit(d, currentDiff, targetDiff, allowance, pow<<shift, 2)
-		}
-	}
-	d.nd = integerDigits
-	d.dp = d.nd + exp10
-	d.neg = f.neg
-
-	// Compute digits of the fractional part. At each step fraction does not
-	// overflow. The choice of minExp implies that fraction is less than 2^60.
-	var digit int
-	multiplier := uint64(1)
-	for {
-		fraction *= 10
-		multiplier *= 10
-		digit = int(fraction >> shift)
-		d.d[d.nd] = byte(digit + '0')
-		d.nd++
-		fraction -= uint64(digit) << shift
-		if fraction < allowance*multiplier {
-			// We are in the admissible range. Note that if allowance is about to
-			// overflow, that is, allowance > 2^64/10, the condition is automatically
-			// true due to the limited range of fraction.
-			return adjustLastDigit(d,
-				fraction, targetDiff*multiplier, allowance*multiplier,
-				1<<shift, multiplier*2)
-		}
-	}
-}
-
-// 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 an error estimate of ulpBinary*ε.
-func adjustLastDigit(d *decimalSlice, currentDiff, targetDiff, maxDiff, ulpDecimal, ulpBinary uint64) bool {
-	if ulpDecimal < 2*ulpBinary {
-		// Approximation is too wide.
-		return false
-	}
-	for currentDiff+ulpDecimal/2+ulpBinary < targetDiff {
-		d.d[d.nd-1]--
-		currentDiff += ulpDecimal
-	}
-	if currentDiff+ulpDecimal <= targetDiff+ulpDecimal/2+ulpBinary {
-		// we have two choices, and don't know what to do.
-		return false
-	}
-	if currentDiff < ulpBinary || currentDiff > maxDiff-ulpBinary {
-		// we went too far
-		return false
-	}
-	if d.nd == 1 && d.d[0] == '0' {
-		// the number has actually reached zero.
-		d.nd = 0
-		d.dp = 0
-	}
-	return true
-}
diff --git a/src/strconv/ftoa.go b/src/strconv/ftoa.go
index 8ce6ef3..eca04b8 100644
--- a/src/strconv/ftoa.go
+++ b/src/strconv/ftoa.go
@@ -113,15 +113,11 @@
 	// Negative precision means "only as much as needed to be exact."
 	shortest := prec < 0
 	if shortest {
-		// Try Grisu3 algorithm.
-		f := new(extFloat)
-		lower, upper := f.AssignComputeBounds(mant, exp, neg, flt)
+		// Use Ryu algorithm.
 		var buf [32]byte
 		digs.d = buf[:]
-		ok = f.ShortestDecimal(&digs, &lower, &upper)
-		if !ok {
-			return bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
-		}
+		ryuFtoaShortest(&digs, mant, exp-int(flt.mantbits), flt)
+		ok = true
 		// Precision for shortest representation mode.
 		switch fmt {
 		case 'e', 'E':
@@ -143,12 +139,15 @@
 			}
 			digits = prec
 		}
-		if digits <= 15 {
-			// try fast algorithm when the number of digits is reasonable.
-			var buf [24]byte
+		var buf [24]byte
+		if bitSize == 32 && digits <= 9 {
 			digs.d = buf[:]
-			f := extFloat{mant, exp - int(flt.mantbits), neg}
-			ok = f.FixedDecimal(&digs, digits)
+			ryuFtoaFixed32(&digs, uint32(mant), exp-int(flt.mantbits), digits)
+			ok = true
+		} else if digits <= 18 {
+			digs.d = buf[:]
+			ryuFtoaFixed64(&digs, mant, exp-int(flt.mantbits), digits)
+			ok = true
 		}
 	}
 	if !ok {
diff --git a/src/strconv/ftoa_test.go b/src/strconv/ftoa_test.go
index 99cca17..73008b1 100644
--- a/src/strconv/ftoa_test.go
+++ b/src/strconv/ftoa_test.go
@@ -40,6 +40,7 @@
 	{200000, 'x', -1, "0x1.86ap+17"},
 	{200000, 'X', -1, "0X1.86AP+17"},
 	{2000000, 'g', -1, "2e+06"},
+	{1e10, 'g', -1, "1e+10"},
 
 	// g conversion and zero suppression
 	{400, 'g', 2, "4e+02"},
@@ -77,6 +78,15 @@
 	{1.2345e6, 'f', 5, "1234500.00000"},
 	{1.2345e6, 'g', 5, "1.2345e+06"},
 
+	// Round to even
+	{1.2345e6, 'e', 3, "1.234e+06"},
+	{1.2355e6, 'e', 3, "1.236e+06"},
+	{1.2345, 'f', 3, "1.234"},
+	{1.2355, 'f', 3, "1.236"},
+	{1234567890123456.5, 'e', 15, "1.234567890123456e+15"},
+	{1234567890123457.5, 'e', 15, "1.234567890123458e+15"},
+	{108678236358137.625, 'g', -1, "1.0867823635813762e+14"},
+
 	{1e23, 'e', 17, "9.99999999999999916e+22"},
 	{1e23, 'f', 17, "99999999999999991611392.00000000000000000"},
 	{1e23, 'g', 17, "9.9999999999999992e+22"},
@@ -183,6 +193,25 @@
 	}
 }
 
+func TestFtoaPowersOfTwo(t *testing.T) {
+	for exp := -2048; exp <= 2048; exp++ {
+		f := math.Ldexp(1, exp)
+		if !math.IsInf(f, 0) {
+			s := FormatFloat(f, 'e', -1, 64)
+			if x, _ := ParseFloat(s, 64); x != f {
+				t.Errorf("failed roundtrip %v => %s => %v", f, s, x)
+			}
+		}
+		f32 := float32(f)
+		if !math.IsInf(float64(f32), 0) {
+			s := FormatFloat(float64(f32), 'e', -1, 32)
+			if x, _ := ParseFloat(s, 32); float32(x) != f32 {
+				t.Errorf("failed roundtrip %v => %s => %v", f32, s, float32(x))
+			}
+		}
+	}
+}
+
 func TestFtoaRandom(t *testing.T) {
 	N := int(1e4)
 	if testing.Short() {
@@ -232,6 +261,7 @@
 	{"Float", 339.7784, 'g', -1, 64},
 	{"Exp", -5.09e75, 'g', -1, 64},
 	{"NegExp", -5.11e-95, 'g', -1, 64},
+	{"LongExp", 1.234567890123456e-78, 'g', -1, 64},
 
 	{"Big", 123456789123456789123456789, 'g', -1, 64},
 	{"BinaryExp", -1, 'b', -1, 64},
@@ -241,14 +271,30 @@
 	{"32Point", 339.7784, 'g', -1, 32},
 	{"32Exp", -5.09e25, 'g', -1, 32},
 	{"32NegExp", -5.11e-25, 'g', -1, 32},
+	{"32Shortest", 1.234567e-8, 'g', -1, 32},
+	{"32Fixed8Hard", math.Ldexp(15961084, -125), 'e', 8, 32},
+	{"32Fixed9Hard", math.Ldexp(14855922, -83), 'e', 9, 32},
 
 	{"64Fixed1", 123456, 'e', 3, 64},
 	{"64Fixed2", 123.456, 'e', 3, 64},
 	{"64Fixed3", 1.23456e+78, 'e', 3, 64},
 	{"64Fixed4", 1.23456e-78, 'e', 3, 64},
+	{"64Fixed12", 1.23456e-78, 'e', 12, 64},
+	{"64Fixed16", 1.23456e-78, 'e', 16, 64},
+	// From testdata/testfp.txt
+	{"64Fixed12Hard", math.Ldexp(6965949469487146, -249), 'e', 12, 64},
+	{"64Fixed17Hard", math.Ldexp(8887055249355788, 665), 'e', 17, 64},
+	{"64Fixed18Hard", math.Ldexp(6994187472632449, 690), 'e', 18, 64},
 
 	// Trigger slow path (see issue #15672).
-	{"Slowpath64", 622666234635.3213e-320, 'e', -1, 64},
+	// The shortest is: 8.034137530808823e+43
+	{"Slowpath64", 8.03413753080882349e+43, 'e', -1, 64},
+	// This denormal is pathological because the lower/upper
+	// halfways to neighboring floats are:
+	// 622666234635.321003e-320 ~= 622666234635.321e-320
+	// 622666234635.321497e-320 ~= 622666234635.3215e-320
+	// making it hard to find the 3rd digit
+	{"SlowpathDenormal64", 622666234635.3213e-320, 'e', -1, 64},
 }
 
 func BenchmarkFormatFloat(b *testing.B) {
diff --git a/src/strconv/ftoaryu.go b/src/strconv/ftoaryu.go
new file mode 100644
index 0000000..1c61288
--- /dev/null
+++ b/src/strconv/ftoaryu.go
@@ -0,0 +1,567 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strconv
+
+import (
+	"math/bits"
+)
+
+// binary to decimal conversion using the Ryū algorithm.
+//
+// See Ulf Adams, "Ryū: Fast Float-to-String Conversion" (doi:10.1145/3192366.3192369)
+//
+// Fixed precision formatting is a variant of the original paper's
+// algorithm, where a single multiplication by 10^k is required,
+// sharing the same rounding guarantees.
+
+// ryuFtoaFixed32 formats mant*(2^exp) with prec decimal digits.
+func ryuFtoaFixed32(d *decimalSlice, mant uint32, exp int, prec int) {
+	if prec < 0 {
+		panic("ryuFtoaFixed32 called with negative prec")
+	}
+	if prec > 9 {
+		panic("ryuFtoaFixed32 called with prec > 9")
+	}
+	// Zero input.
+	if mant == 0 {
+		d.nd, d.dp = 0, 0
+		return
+	}
+	// Renormalize to a 25-bit mantissa.
+	e2 := exp
+	if b := bits.Len32(mant); b < 25 {
+		mant <<= uint(25 - b)
+		e2 += int(b) - 25
+	}
+	// Choose an exponent such that rounded mant*(2^e2)*(10^q) has
+	// at least prec decimal digits, i.e
+	//     mant*(2^e2)*(10^q) >= 10^(prec-1)
+	// Because mant >= 2^24, it is enough to choose:
+	//     2^(e2+24) >= 10^(-q+prec-1)
+	// or q = -mulByLog2Log10(e2+24) + prec - 1
+	q := -mulByLog2Log10(e2+24) + prec - 1
+
+	// Now compute mant*(2^e2)*(10^q).
+	// Is it an exact computation?
+	// Only small positive powers of 10 are exact (5^28 has 66 bits).
+	exact := q <= 27 && q >= 0
+
+	di, dexp2, d0 := mult64bitPow10(mant, e2, q)
+	if dexp2 >= 0 {
+		panic("not enough significant bits after mult64bitPow10")
+	}
+	// As a special case, computation might still be exact, if exponent
+	// was negative and if it amounts to computing an exact division.
+	// In that case, we ignore all lower bits.
+	// Note that division by 10^11 cannot be exact as 5^11 has 26 bits.
+	if q < 0 && q >= -10 && divisibleByPower5(uint64(mant), -q) {
+		exact = true
+		d0 = true
+	}
+	// Remove extra lower bits and keep rounding info.
+	extra := uint(-dexp2)
+	extraMask := uint32(1<<extra - 1)
+
+	di, dfrac := di>>extra, di&extraMask
+	roundUp := false
+	if exact {
+		// If we computed an exact product, d + 1/2
+		// should round to d+1 if 'd' is odd.
+		roundUp = dfrac > 1<<(extra-1) ||
+			(dfrac == 1<<(extra-1) && !d0) ||
+			(dfrac == 1<<(extra-1) && d0 && di&1 == 1)
+	} else {
+		// otherwise, d+1/2 always rounds up because
+		// we truncated below.
+		roundUp = dfrac>>(extra-1) == 1
+	}
+	if dfrac != 0 {
+		d0 = false
+	}
+	// Proceed to the requested number of digits
+	formatDecimal(d, uint64(di), !d0, roundUp, prec)
+	// Adjust exponent
+	d.dp -= q
+}
+
+// ryuFtoaFixed64 formats mant*(2^exp) with prec decimal digits.
+func ryuFtoaFixed64(d *decimalSlice, mant uint64, exp int, prec int) {
+	if prec > 18 {
+		panic("ryuFtoaFixed64 called with prec > 18")
+	}
+	// Zero input.
+	if mant == 0 {
+		d.nd, d.dp = 0, 0
+		return
+	}
+	// Renormalize to a 55-bit mantissa.
+	e2 := exp
+	if b := bits.Len64(mant); b < 55 {
+		mant = mant << uint(55-b)
+		e2 += int(b) - 55
+	}
+	// Choose an exponent such that rounded mant*(2^e2)*(10^q) has
+	// at least prec decimal digits, i.e
+	//     mant*(2^e2)*(10^q) >= 10^(prec-1)
+	// Because mant >= 2^54, it is enough to choose:
+	//     2^(e2+54) >= 10^(-q+prec-1)
+	// or q = -mulByLog2Log10(e2+54) + prec - 1
+	//
+	// The minimal required exponent is -mulByLog2Log10(1025)+18 = -291
+	// The maximal required exponent is mulByLog2Log10(1074)+18 = 342
+	q := -mulByLog2Log10(e2+54) + prec - 1
+
+	// Now compute mant*(2^e2)*(10^q).
+	// Is it an exact computation?
+	// Only small positive powers of 10 are exact (5^55 has 128 bits).
+	exact := q <= 55 && q >= 0
+
+	di, dexp2, d0 := mult128bitPow10(mant, e2, q)
+	if dexp2 >= 0 {
+		panic("not enough significant bits after mult128bitPow10")
+	}
+	// As a special case, computation might still be exact, if exponent
+	// was negative and if it amounts to computing an exact division.
+	// In that case, we ignore all lower bits.
+	// Note that division by 10^23 cannot be exact as 5^23 has 54 bits.
+	if q < 0 && q >= -22 && divisibleByPower5(mant, -q) {
+		exact = true
+		d0 = true
+	}
+	// Remove extra lower bits and keep rounding info.
+	extra := uint(-dexp2)
+	extraMask := uint64(1<<extra - 1)
+
+	di, dfrac := di>>extra, di&extraMask
+	roundUp := false
+	if exact {
+		// If we computed an exact product, d + 1/2
+		// should round to d+1 if 'd' is odd.
+		roundUp = dfrac > 1<<(extra-1) ||
+			(dfrac == 1<<(extra-1) && !d0) ||
+			(dfrac == 1<<(extra-1) && d0 && di&1 == 1)
+	} else {
+		// otherwise, d+1/2 always rounds up because
+		// we truncated below.
+		roundUp = dfrac>>(extra-1) == 1
+	}
+	if dfrac != 0 {
+		d0 = false
+	}
+	// Proceed to the requested number of digits
+	formatDecimal(d, di, !d0, roundUp, prec)
+	// Adjust exponent
+	d.dp -= q
+}
+
+var uint64pow10 = [...]uint64{
+	1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+	1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+}
+
+// formatDecimal fills d with at most prec decimal digits
+// of mantissa m. The boolean trunc indicates whether m
+// is truncated compared to the original number being formatted.
+func formatDecimal(d *decimalSlice, m uint64, trunc bool, roundUp bool, prec int) {
+	max := uint64pow10[prec]
+	trimmed := 0
+	for m >= max {
+		a, b := m/10, m%10
+		m = a
+		trimmed++
+		if b > 5 {
+			roundUp = true
+		} else if b < 5 {
+			roundUp = false
+		} else { // b == 5
+			// round up if there are trailing digits,
+			// or if the new value of m is odd (round-to-even convention)
+			roundUp = trunc || m&1 == 1
+		}
+		if b != 0 {
+			trunc = true
+		}
+	}
+	if roundUp {
+		m++
+	}
+	if m >= max {
+		// Happens if di was originally 99999....xx
+		m /= 10
+		trimmed++
+	}
+	// render digits (similar to formatBits)
+	n := uint(prec)
+	d.nd = int(prec)
+	v := m
+	for v >= 100 {
+		var v1, v2 uint64
+		if v>>32 == 0 {
+			v1, v2 = uint64(uint32(v)/100), uint64(uint32(v)%100)
+		} else {
+			v1, v2 = v/100, v%100
+		}
+		n -= 2
+		d.d[n+1] = smallsString[2*v2+1]
+		d.d[n+0] = smallsString[2*v2+0]
+		v = v1
+	}
+	if v > 0 {
+		n--
+		d.d[n] = smallsString[2*v+1]
+	}
+	if v >= 10 {
+		n--
+		d.d[n] = smallsString[2*v]
+	}
+	for d.d[d.nd-1] == '0' {
+		d.nd--
+		trimmed++
+	}
+	d.dp = d.nd + trimmed
+}
+
+// ryuFtoaShortest formats mant*2^exp with prec decimal digits.
+func ryuFtoaShortest(d *decimalSlice, mant uint64, exp int, flt *floatInfo) {
+	if mant == 0 {
+		d.nd, d.dp = 0, 0
+		return
+	}
+	// If input is an exact integer with fewer bits than the mantissa,
+	// the previous and next integer are not admissible representations.
+	if exp <= 0 && bits.TrailingZeros64(mant) >= -exp {
+		mant >>= uint(-exp)
+		ryuDigits(d, mant, mant, mant, true, false)
+		return
+	}
+	ml, mc, mu, e2 := computeBounds(mant, exp, flt)
+	if e2 == 0 {
+		ryuDigits(d, ml, mc, mu, true, false)
+		return
+	}
+	// Find 10^q *larger* than 2^-e2
+	q := mulByLog2Log10(-e2) + 1
+
+	// We are going to multiply by 10^q using 128-bit arithmetic.
+	// The exponent is the same for all 3 numbers.
+	var dl, dc, du uint64
+	var dl0, dc0, du0 bool
+	if flt == &float32info {
+		var dl32, dc32, du32 uint32
+		dl32, _, dl0 = mult64bitPow10(uint32(ml), e2, q)
+		dc32, _, dc0 = mult64bitPow10(uint32(mc), e2, q)
+		du32, e2, du0 = mult64bitPow10(uint32(mu), e2, q)
+		dl, dc, du = uint64(dl32), uint64(dc32), uint64(du32)
+	} else {
+		dl, _, dl0 = mult128bitPow10(ml, e2, q)
+		dc, _, dc0 = mult128bitPow10(mc, e2, q)
+		du, e2, du0 = mult128bitPow10(mu, e2, q)
+	}
+	if e2 >= 0 {
+		panic("not enough significant bits after mult128bitPow10")
+	}
+	// Is it an exact computation?
+	if q > 55 {
+		// Large positive powers of ten are not exact
+		dl0, dc0, du0 = false, false, false
+	}
+	if q < 0 && q >= -24 {
+		// Division by a power of ten may be exact.
+		// (note that 5^25 is a 59-bit number so division by 5^25 is never exact).
+		if divisibleByPower5(ml, -q) {
+			dl0 = true
+		}
+		if divisibleByPower5(mc, -q) {
+			dc0 = true
+		}
+		if divisibleByPower5(mu, -q) {
+			du0 = true
+		}
+	}
+	// Express the results (dl, dc, du)*2^e2 as integers.
+	// Extra bits must be removed and rounding hints computed.
+	extra := uint(-e2)
+	extraMask := uint64(1<<extra - 1)
+	// Now compute the floored, integral base 10 mantissas.
+	dl, fracl := dl>>extra, dl&extraMask
+	dc, fracc := dc>>extra, dc&extraMask
+	du, fracu := du>>extra, du&extraMask
+	// Is it allowed to use 'du' as a result?
+	// It is always allowed when it is truncated, but also
+	// if it is exact and the original binary mantissa is even
+	// When disallowed, we can substract 1.
+	uok := !du0 || fracu > 0
+	if du0 && fracu == 0 {
+		uok = mant&1 == 0
+	}
+	if !uok {
+		du--
+	}
+	// Is 'dc' the correctly rounded base 10 mantissa?
+	// The correct rounding might be dc+1
+	cup := false // don't round up.
+	if dc0 {
+		// If we computed an exact product, the half integer
+		// should round to next (even) integer if 'dc' is odd.
+		cup = fracc > 1<<(extra-1) ||
+			(fracc == 1<<(extra-1) && dc&1 == 1)
+	} else {
+		// otherwise, the result is a lower truncation of the ideal
+		// result.
+		cup = fracc>>(extra-1) == 1
+	}
+	// Is 'dl' an allowed representation?
+	// Only if it is an exact value, and if the original binary mantissa
+	// was even.
+	lok := dl0 && fracl == 0 && (mant&1 == 0)
+	if !lok {
+		dl++
+	}
+	// We need to remember whether the trimmed digits of 'dc' are zero.
+	c0 := dc0 && fracc == 0
+	// render digits
+	ryuDigits(d, dl, dc, du, c0, cup)
+	d.dp -= q
+}
+
+// mulByLog2Log10 returns math.Floor(x * log(2)/log(10)) for an integer x in
+// the range -1600 <= x && x <= +1600.
+//
+// The range restriction lets us work in faster integer arithmetic instead of
+// slower floating point arithmetic. Correctness is verified by unit tests.
+func mulByLog2Log10(x int) int {
+	// log(2)/log(10) ≈ 0.30102999566 ≈ 78913 / 2^18
+	return (x * 78913) >> 18
+}
+
+// mulByLog10Log2 returns math.Floor(x * log(10)/log(2)) for an integer x in
+// the range -500 <= x && x <= +500.
+//
+// The range restriction lets us work in faster integer arithmetic instead of
+// slower floating point arithmetic. Correctness is verified by unit tests.
+func mulByLog10Log2(x int) int {
+	// log(10)/log(2) ≈ 3.32192809489 ≈ 108853 / 2^15
+	return (x * 108853) >> 15
+}
+
+// computeBounds returns a floating-point vector (l, c, u)×2^e2
+// where the mantissas are 55-bit (or 26-bit) integers, describing the interval
+// represented by the input float64 or float32.
+func computeBounds(mant uint64, exp int, flt *floatInfo) (lower, central, upper uint64, e2 int) {
+	if mant != 1<<flt.mantbits || exp == flt.bias+1-int(flt.mantbits) {
+		// regular case (or denormals)
+		lower, central, upper = 2*mant-1, 2*mant, 2*mant+1
+		e2 = exp - 1
+		return
+	} else {
+		// border of an exponent
+		lower, central, upper = 4*mant-1, 4*mant, 4*mant+2
+		e2 = exp - 2
+		return
+	}
+}
+
+func ryuDigits(d *decimalSlice, lower, central, upper uint64,
+	c0, cup bool) {
+	lhi, llo := divmod1e9(lower)
+	chi, clo := divmod1e9(central)
+	uhi, ulo := divmod1e9(upper)
+	if uhi == 0 {
+		// only low digits (for denormals)
+		ryuDigits32(d, llo, clo, ulo, c0, cup, 8)
+	} else if lhi < uhi {
+		// truncate 9 digits at once.
+		if llo != 0 {
+			lhi++
+		}
+		c0 = c0 && clo == 0
+		cup = (clo > 5e8) || (clo == 5e8 && cup)
+		ryuDigits32(d, lhi, chi, uhi, c0, cup, 8)
+		d.dp += 9
+	} else {
+		d.nd = 0
+		// emit high part
+		n := uint(9)
+		for v := chi; v > 0; {
+			v1, v2 := v/10, v%10
+			v = v1
+			n--
+			d.d[n] = byte(v2 + '0')
+		}
+		d.d = d.d[n:]
+		d.nd = int(9 - n)
+		// emit low part
+		ryuDigits32(d, llo, clo, ulo,
+			c0, cup, d.nd+8)
+	}
+	// trim trailing zeros
+	for d.nd > 0 && d.d[d.nd-1] == '0' {
+		d.nd--
+	}
+	// trim initial zeros
+	for d.nd > 0 && d.d[0] == '0' {
+		d.nd--
+		d.dp--
+		d.d = d.d[1:]
+	}
+}
+
+// ryuDigits32 emits decimal digits for a number less than 1e9.
+func ryuDigits32(d *decimalSlice, lower, central, upper uint32,
+	c0, cup bool, endindex int) {
+	if upper == 0 {
+		d.dp = endindex + 1
+		return
+	}
+	trimmed := 0
+	// Remember last trimmed digit to check for round-up.
+	// c0 will be used to remember zeroness of following digits.
+	cNextDigit := 0
+	for upper > 0 {
+		// Repeatedly compute:
+		// l = Ceil(lower / 10^k)
+		// c = Round(central / 10^k)
+		// u = Floor(upper / 10^k)
+		// and stop when c goes out of the (l, u) interval.
+		l := (lower + 9) / 10
+		c, cdigit := central/10, central%10
+		u := upper / 10
+		if l > u {
+			// don't trim the last digit as it is forbidden to go below l
+			// other, trim and exit now.
+			break
+		}
+		// Check that we didn't cross the lower boundary.
+		// The case where l < u but c == l-1 is essentially impossible,
+		// but may happen if:
+		//    lower   = ..11
+		//    central = ..19
+		//    upper   = ..31
+		// and means that 'central' is very close but less than
+		// an integer ending with many zeros, and usually
+		// the "round-up" logic hides the problem.
+		if l == c+1 && c < u {
+			c++
+			cdigit = 0
+			cup = false
+		}
+		trimmed++
+		// Remember trimmed digits of c
+		c0 = c0 && cNextDigit == 0
+		cNextDigit = int(cdigit)
+		lower, central, upper = l, c, u
+	}
+	// should we round up?
+	if trimmed > 0 {
+		cup = cNextDigit > 5 ||
+			(cNextDigit == 5 && !c0) ||
+			(cNextDigit == 5 && c0 && central&1 == 1)
+	}
+	if central < upper && cup {
+		central++
+	}
+	// We know where the number ends, fill directly
+	endindex -= trimmed
+	v := central
+	n := endindex
+	for n > d.nd {
+		v1, v2 := v/100, v%100
+		d.d[n] = smallsString[2*v2+1]
+		d.d[n-1] = smallsString[2*v2+0]
+		n -= 2
+		v = v1
+	}
+	if n == d.nd {
+		d.d[n] = byte(v + '0')
+	}
+	d.nd = endindex + 1
+	d.dp = d.nd + trimmed
+}
+
+// mult64bitPow10 takes a floating-point input with a 25-bit
+// mantissa and multiplies it with 10^q. The resulting mantissa
+// is m*P >> 57 where P is a 64-bit element of the detailedPowersOfTen tables.
+// It is typically 31 or 32-bit wide.
+// The returned boolean is true if all trimmed bits were zero.
+//
+// That is:
+//     m*2^e2 * round(10^q) = resM * 2^resE + ε
+//     exact = ε == 0
+func mult64bitPow10(m uint32, e2, q int) (resM uint32, resE int, exact bool) {
+	if q == 0 {
+		// P == 1<<63
+		return m << 6, e2 - 6, true
+	}
+	if q < detailedPowersOfTenMinExp10 || detailedPowersOfTenMaxExp10 < q {
+		// This never happens due to the range of float32/float64 exponent
+		panic("mult64bitPow10: power of 10 is out of range")
+	}
+	pow := detailedPowersOfTen[q-detailedPowersOfTenMinExp10][1]
+	if q < 0 {
+		// Inverse powers of ten must be rounded up.
+		pow += 1
+	}
+	hi, lo := bits.Mul64(uint64(m), pow)
+	e2 += mulByLog10Log2(q) - 63 + 57
+	return uint32(hi<<7 | lo>>57), e2, lo<<7 == 0
+}
+
+// mult128bitPow10 takes a floating-point input with a 55-bit
+// mantissa and multiplies it with 10^q. The resulting mantissa
+// is m*P >> 119 where P is a 128-bit element of the detailedPowersOfTen tables.
+// It is typically 63 or 64-bit wide.
+// The returned boolean is true is all trimmed bits were zero.
+//
+// That is:
+//     m*2^e2 * round(10^q) = resM * 2^resE + ε
+//     exact = ε == 0
+func mult128bitPow10(m uint64, e2, q int) (resM uint64, resE int, exact bool) {
+	if q == 0 {
+		// P == 1<<127
+		return m << 8, e2 - 8, true
+	}
+	if q < detailedPowersOfTenMinExp10 || detailedPowersOfTenMaxExp10 < q {
+		// This never happens due to the range of float32/float64 exponent
+		panic("mult128bitPow10: power of 10 is out of range")
+	}
+	pow := detailedPowersOfTen[q-detailedPowersOfTenMinExp10]
+	if q < 0 {
+		// Inverse powers of ten must be rounded up.
+		pow[0] += 1
+	}
+	e2 += mulByLog10Log2(q) - 127 + 119
+
+	// long multiplication
+	l1, l0 := bits.Mul64(m, pow[0])
+	h1, h0 := bits.Mul64(m, pow[1])
+	mid, carry := bits.Add64(l1, h0, 0)
+	h1 += carry
+	return h1<<9 | mid>>55, e2, mid<<9 == 0 && l0 == 0
+}
+
+func divisibleByPower5(m uint64, k int) bool {
+	if m == 0 {
+		return true
+	}
+	for i := 0; i < k; i++ {
+		if m%5 != 0 {
+			return false
+		}
+		m /= 5
+	}
+	return true
+}
+
+// divmod1e9 computes quotient and remainder of division by 1e9,
+// avoiding runtime uint64 division on 32-bit platforms.
+func divmod1e9(x uint64) (uint32, uint32) {
+	if !host32bit {
+		return uint32(x / 1e9), uint32(x % 1e9)
+	}
+	// Use the same sequence of operations as the amd64 compiler.
+	hi, _ := bits.Mul64(x>>1, 0x89705f4136b4a598) // binary digits of 1e-9
+	q := hi >> 28
+	return uint32(q), uint32(x - q*1e9)
+}
diff --git a/src/strconv/ftoaryu_test.go b/src/strconv/ftoaryu_test.go
new file mode 100644
index 0000000..9758619
--- /dev/null
+++ b/src/strconv/ftoaryu_test.go
@@ -0,0 +1,31 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strconv_test
+
+import (
+	"math"
+	. "strconv"
+	"testing"
+)
+
+func TestMulByLog2Log10(t *testing.T) {
+	for x := -1600; x <= +1600; x++ {
+		iMath := MulByLog2Log10(x)
+		fMath := int(math.Floor(float64(x) * math.Ln2 / math.Ln10))
+		if iMath != fMath {
+			t.Errorf("mulByLog2Log10(%d) failed: %d vs %d\n", x, iMath, fMath)
+		}
+	}
+}
+
+func TestMulByLog10Log2(t *testing.T) {
+	for x := -500; x <= +500; x++ {
+		iMath := MulByLog10Log2(x)
+		fMath := int(math.Floor(float64(x) * math.Ln10 / math.Ln2))
+		if iMath != fMath {
+			t.Errorf("mulByLog10Log2(%d) failed: %d vs %d\n", x, iMath, fMath)
+		}
+	}
+}
diff --git a/src/strconv/internal_test.go b/src/strconv/internal_test.go
index bb4a418..f2cceff 100644
--- a/src/strconv/internal_test.go
+++ b/src/strconv/internal_test.go
@@ -21,3 +21,11 @@
 func ParseFloatPrefix(s string, bitSize int) (float64, int, error) {
 	return parseFloatPrefix(s, bitSize)
 }
+
+func MulByLog2Log10(x int) int {
+	return mulByLog2Log10(x)
+}
+
+func MulByLog10Log2(x int) int {
+	return mulByLog10Log2(x)
+}
diff --git a/src/strconv/makeisprint.go b/src/strconv/makeisprint.go
index 0e6e90a..909f9e4 100644
--- a/src/strconv/makeisprint.go
+++ b/src/strconv/makeisprint.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 //
@@ -36,7 +37,7 @@
 func bsearch16(a []uint16, x uint16) int {
 	i, j := 0, len(a)
 	for i < j {
-		h := i + (j-i)/2
+		h := i + (j-i)>>1
 		if a[h] < x {
 			i = h + 1
 		} else {
@@ -51,7 +52,7 @@
 func bsearch32(a []uint32, x uint32) int {
 	i, j := 0, len(a)
 	for i < j {
-		h := i + (j-i)/2
+		h := i + (j-i)>>1
 		if a[h] < x {
 			i = h + 1
 		} else {
diff --git a/src/strconv/quote.go b/src/strconv/quote.go
index bcbdbc5..b3bbb16 100644
--- a/src/strconv/quote.go
+++ b/src/strconv/quote.go
@@ -7,7 +7,6 @@
 package strconv
 
 import (
-	"internal/bytealg"
 	"unicode/utf8"
 )
 
@@ -16,6 +15,11 @@
 	upperhex = "0123456789ABCDEF"
 )
 
+// contains reports whether the string contains the byte c.
+func contains(s string, c byte) bool {
+	return index(s, c) != -1
+}
+
 func quoteWith(s string, quote byte, ASCIIonly, graphicOnly bool) string {
 	return string(appendQuotedWith(make([]byte, 0, 3*len(s)/2), s, quote, ASCIIonly, graphicOnly))
 }
@@ -360,85 +364,132 @@
 	return
 }
 
+// QuotedPrefix returns the quoted string (as understood by Unquote) at the prefix of s.
+// If s does not start with a valid quoted string, QuotedPrefix returns an error.
+func QuotedPrefix(s string) (string, error) {
+	out, _, err := unquote(s, false)
+	return out, err
+}
+
 // Unquote interprets s as a single-quoted, double-quoted,
 // or backquoted Go string literal, returning the string value
 // that s quotes.  (If s is single-quoted, it would be a Go
 // character literal; Unquote returns the corresponding
 // one-character string.)
 func Unquote(s string) (string, error) {
-	n := len(s)
-	if n < 2 {
+	out, rem, err := unquote(s, true)
+	if len(rem) > 0 {
 		return "", ErrSyntax
 	}
-	quote := s[0]
-	if quote != s[n-1] {
-		return "", ErrSyntax
-	}
-	s = s[1 : n-1]
-
-	if quote == '`' {
-		if contains(s, '`') {
-			return "", ErrSyntax
-		}
-		if contains(s, '\r') {
-			// -1 because we know there is at least one \r to remove.
-			buf := make([]byte, 0, len(s)-1)
-			for i := 0; i < len(s); i++ {
-				if s[i] != '\r' {
-					buf = append(buf, s[i])
-				}
-			}
-			return string(buf), nil
-		}
-		return s, nil
-	}
-	if quote != '"' && quote != '\'' {
-		return "", ErrSyntax
-	}
-	if contains(s, '\n') {
-		return "", ErrSyntax
-	}
-
-	// Is it trivial? Avoid allocation.
-	if !contains(s, '\\') && !contains(s, quote) {
-		switch quote {
-		case '"':
-			if utf8.ValidString(s) {
-				return s, nil
-			}
-		case '\'':
-			r, size := utf8.DecodeRuneInString(s)
-			if size == len(s) && (r != utf8.RuneError || size != 1) {
-				return s, nil
-			}
-		}
-	}
-
-	var runeTmp [utf8.UTFMax]byte
-	buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
-	for len(s) > 0 {
-		c, multibyte, ss, err := UnquoteChar(s, quote)
-		if err != nil {
-			return "", err
-		}
-		s = ss
-		if c < utf8.RuneSelf || !multibyte {
-			buf = append(buf, byte(c))
-		} else {
-			n := utf8.EncodeRune(runeTmp[:], c)
-			buf = append(buf, runeTmp[:n]...)
-		}
-		if quote == '\'' && len(s) != 0 {
-			// single-quoted must be single character
-			return "", ErrSyntax
-		}
-	}
-	return string(buf), nil
+	return out, err
 }
 
-// contains reports whether the string contains the byte c.
-func contains(s string, c byte) bool {
-	return bytealg.IndexByteString(s, c) != -1
+// unquote parses a quoted string at the start of the input,
+// returning the parsed prefix, the remaining suffix, and any parse errors.
+// If unescape is true, the parsed prefix is unescaped,
+// otherwise the input prefix is provided verbatim.
+func unquote(in string, unescape bool) (out, rem string, err error) {
+	// Determine the quote form and optimistically find the terminating quote.
+	if len(in) < 2 {
+		return "", in, ErrSyntax
+	}
+	quote := in[0]
+	end := index(in[1:], quote)
+	if end < 0 {
+		return "", in, ErrSyntax
+	}
+	end += 2 // position after terminating quote; may be wrong if escape sequences are present
+
+	switch quote {
+	case '`':
+		switch {
+		case !unescape:
+			out = in[:end] // include quotes
+		case !contains(in[:end], '\r'):
+			out = in[len("`") : end-len("`")] // exclude quotes
+		default:
+			// Carriage return characters ('\r') inside raw string literals
+			// are discarded from the raw string value.
+			buf := make([]byte, 0, end-len("`")-len("\r")-len("`"))
+			for i := len("`"); i < end-len("`"); i++ {
+				if in[i] != '\r' {
+					buf = append(buf, in[i])
+				}
+			}
+			out = string(buf)
+		}
+		// NOTE: Prior implementations did not verify that raw strings consist
+		// of valid UTF-8 characters and we continue to not verify it as such.
+		// The Go specification does not explicitly require valid UTF-8,
+		// but only mention that it is implicitly valid for Go source code
+		// (which must be valid UTF-8).
+		return out, in[end:], nil
+	case '"', '\'':
+		// Handle quoted strings without any escape sequences.
+		if !contains(in[:end], '\\') && !contains(in[:end], '\n') {
+			var valid bool
+			switch quote {
+			case '"':
+				valid = utf8.ValidString(in[len(`"`) : end-len(`"`)])
+			case '\'':
+				r, n := utf8.DecodeRuneInString(in[len("'") : end-len("'")])
+				valid = len("'")+n+len("'") == end && (r != utf8.RuneError || n != 1)
+			}
+			if valid {
+				out = in[:end]
+				if unescape {
+					out = out[1 : end-1] // exclude quotes
+				}
+				return out, in[end:], nil
+			}
+		}
+
+		// Handle quoted strings with escape sequences.
+		var buf []byte
+		in0 := in
+		in = in[1:] // skip starting quote
+		if unescape {
+			buf = make([]byte, 0, 3*end/2) // try to avoid more allocations
+		}
+		for len(in) > 0 && in[0] != quote {
+			// Process the next character,
+			// rejecting any unescaped newline characters which are invalid.
+			r, multibyte, rem, err := UnquoteChar(in, quote)
+			if in[0] == '\n' || err != nil {
+				return "", in0, ErrSyntax
+			}
+			in = rem
+
+			// Append the character if unescaping the input.
+			if unescape {
+				if r < utf8.RuneSelf || !multibyte {
+					buf = append(buf, byte(r))
+				} else {
+					var arr [utf8.UTFMax]byte
+					n := utf8.EncodeRune(arr[:], r)
+					buf = append(buf, arr[:n]...)
+				}
+			}
+
+			// Single quoted strings must be a single character.
+			if quote == '\'' {
+				break
+			}
+		}
+
+		// Verify that the string ends with a terminating quote.
+		if !(len(in) > 0 && in[0] == quote) {
+			return "", in0, ErrSyntax
+		}
+		in = in[1:] // skip terminating quote
+
+		if unescape {
+			return string(buf), in, nil
+		}
+		return in0[:len(in0)-len(in)], in, nil
+	default:
+		return "", in, ErrSyntax
+	}
 }
 
 // bsearch16 returns the smallest i such that a[i] >= x.
@@ -446,7 +497,7 @@
 func bsearch16(a []uint16, x uint16) int {
 	i, j := 0, len(a)
 	for i < j {
-		h := i + (j-i)/2
+		h := i + (j-i)>>1
 		if a[h] < x {
 			i = h + 1
 		} else {
@@ -461,7 +512,7 @@
 func bsearch32(a []uint32, x uint32) int {
 	i, j := 0, len(a)
 	for i < j {
-		h := i + (j-i)/2
+		h := i + (j-i)>>1
 		if a[h] < x {
 			i = h + 1
 		} else {
diff --git a/src/strconv/quote_test.go b/src/strconv/quote_test.go
index f1faf13..4750be2 100644
--- a/src/strconv/quote_test.go
+++ b/src/strconv/quote_test.go
@@ -6,6 +6,7 @@
 
 import (
 	. "strconv"
+	"strings"
 	"testing"
 	"unicode"
 )
@@ -297,6 +298,7 @@
 	`"\z"`,
 	"`",
 	"`xxx",
+	"``x\r",
 	"`\"",
 	`"\'"`,
 	`'\"'`,
@@ -307,22 +309,13 @@
 
 func TestUnquote(t *testing.T) {
 	for _, tt := range unquotetests {
-		if out, err := Unquote(tt.in); err != nil || out != tt.out {
-			t.Errorf("Unquote(%#q) = %q, %v want %q, nil", tt.in, out, err, tt.out)
-		}
+		testUnquote(t, tt.in, tt.out, nil)
 	}
-
-	// run the quote tests too, backward
 	for _, tt := range quotetests {
-		if in, err := Unquote(tt.out); in != tt.in {
-			t.Errorf("Unquote(%#q) = %q, %v, want %q, nil", tt.out, in, err, tt.in)
-		}
+		testUnquote(t, tt.out, tt.in, nil)
 	}
-
 	for _, s := range misquoted {
-		if out, err := Unquote(s); out != "" || err != ErrSyntax {
-			t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", ErrSyntax)
-		}
+		testUnquote(t, s, "", ErrSyntax)
 	}
 }
 
@@ -333,26 +326,44 @@
 
 		// one of:
 		want    string
-		wantErr string
+		wantErr error
 	}{
 		{in: `"foo"`, want: "foo"},
-		{in: `"foo`, wantErr: "invalid syntax"},
+		{in: `"foo`, wantErr: ErrSyntax},
 		{in: `"` + "\xc0" + `"`, want: "\xef\xbf\xbd"},
 		{in: `"a` + "\xc0" + `"`, want: "a\xef\xbf\xbd"},
 		{in: `"\t` + "\xc0" + `"`, want: "\t\xef\xbf\xbd"},
 	}
-	for i, tt := range tests {
-		got, err := Unquote(tt.in)
-		var gotErr string
-		if err != nil {
-			gotErr = err.Error()
-		}
-		if gotErr != tt.wantErr {
-			t.Errorf("%d. Unquote(%q) = err %v; want %q", i, tt.in, err, tt.wantErr)
-		}
-		if tt.wantErr == "" && err == nil && got != tt.want {
-			t.Errorf("%d. Unquote(%q) = %02x; want %02x", i, tt.in, []byte(got), []byte(tt.want))
-		}
+	for _, tt := range tests {
+		testUnquote(t, tt.in, tt.want, tt.wantErr)
+	}
+}
+
+func testUnquote(t *testing.T, in, want string, wantErr error) {
+	// Test Unquote.
+	got, gotErr := Unquote(in)
+	if got != want || gotErr != wantErr {
+		t.Errorf("Unquote(%q) = (%q, %v), want (%q, %v)", in, got, gotErr, want, wantErr)
+	}
+
+	// Test QuotedPrefix.
+	// Adding an arbitrary suffix should not change the result of QuotedPrefix
+	// assume that the suffix doesn't accidentally terminate a truncated input.
+	if gotErr == nil {
+		want = in
+	}
+	suffix := "\n\r\\\"`'" // special characters for quoted strings
+	if len(in) > 0 {
+		suffix = strings.ReplaceAll(suffix, in[:1], "")
+	}
+	in += suffix
+	got, gotErr = QuotedPrefix(in)
+	if gotErr == nil && wantErr != nil {
+		_, wantErr = Unquote(got) // original input had trailing junk, reparse with only valid prefix
+		want = got
+	}
+	if got != want || gotErr != wantErr {
+		t.Errorf("QuotedPrefix(%q) = (%q, %v), want (%q, %v)", in, got, gotErr, want, wantErr)
 	}
 }
 
diff --git a/src/strings/builder.go b/src/strings/builder.go
index 6ff151d..547e52e 100644
--- a/src/strings/builder.go
+++ b/src/strings/builder.go
@@ -103,7 +103,8 @@
 // It returns the length of r and a nil error.
 func (b *Builder) WriteRune(r rune) (int, error) {
 	b.copyCheck()
-	if r < utf8.RuneSelf {
+	// Compare as uint32 to correctly handle negative runes.
+	if uint32(r) < utf8.RuneSelf {
 		b.buf = append(b.buf, byte(r))
 		return 1, nil
 	}
diff --git a/src/strings/builder_test.go b/src/strings/builder_test.go
index b662efe..e3d2392 100644
--- a/src/strings/builder_test.go
+++ b/src/strings/builder_test.go
@@ -8,6 +8,7 @@
 	"bytes"
 	. "strings"
 	"testing"
+	"unicode/utf8"
 )
 
 func check(t *testing.T, b *Builder, want string) {
@@ -301,6 +302,16 @@
 	}
 }
 
+func TestBuilderWriteInvalidRune(t *testing.T) {
+	// Invalid runes, including negative ones, should be written as
+	// utf8.RuneError.
+	for _, r := range []rune{-1, utf8.MaxRune + 1} {
+		var b Builder
+		b.WriteRune(r)
+		check(t, &b, "\uFFFD")
+	}
+}
+
 var someBytes = []byte("some bytes sdljlk jsklj3lkjlk djlkjw")
 
 var sinkS string
diff --git a/src/sync/atomic/asm.s b/src/sync/atomic/asm.s
index f86726f..7b8c9b9 100644
--- a/src/sync/atomic/asm.s
+++ b/src/sync/atomic/asm.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !race
 // +build !race
 
 #include "textflag.h"
diff --git a/src/sync/atomic/race.s b/src/sync/atomic/race.s
index fd6ca22..0866487 100644
--- a/src/sync/atomic/race.s
+++ b/src/sync/atomic/race.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build race
 // +build race
 
 // This file is here only to allow external functions.
diff --git a/src/sync/atomic/value.go b/src/sync/atomic/value.go
index eab7e70..3500cd2 100644
--- a/src/sync/atomic/value.go
+++ b/src/sync/atomic/value.go
@@ -25,7 +25,7 @@
 
 // Load returns the value set by the most recent Store.
 // It returns nil if there has been no call to Store for this Value.
-func (v *Value) Load() (x interface{}) {
+func (v *Value) Load() (val interface{}) {
 	vp := (*ifaceWords)(unsafe.Pointer(v))
 	typ := LoadPointer(&vp.typ)
 	if typ == nil || uintptr(typ) == ^uintptr(0) {
@@ -33,21 +33,21 @@
 		return nil
 	}
 	data := LoadPointer(&vp.data)
-	xp := (*ifaceWords)(unsafe.Pointer(&x))
-	xp.typ = typ
-	xp.data = data
+	vlp := (*ifaceWords)(unsafe.Pointer(&val))
+	vlp.typ = typ
+	vlp.data = data
 	return
 }
 
 // Store sets the value of the Value to x.
 // All calls to Store for a given Value must use values of the same concrete type.
 // Store of an inconsistent type panics, as does Store(nil).
-func (v *Value) Store(x interface{}) {
-	if x == nil {
+func (v *Value) Store(val interface{}) {
+	if val == nil {
 		panic("sync/atomic: store of nil value into Value")
 	}
 	vp := (*ifaceWords)(unsafe.Pointer(v))
-	xp := (*ifaceWords)(unsafe.Pointer(&x))
+	vlp := (*ifaceWords)(unsafe.Pointer(&val))
 	for {
 		typ := LoadPointer(&vp.typ)
 		if typ == nil {
@@ -61,8 +61,8 @@
 				continue
 			}
 			// Complete first store.
-			StorePointer(&vp.data, xp.data)
-			StorePointer(&vp.typ, xp.typ)
+			StorePointer(&vp.data, vlp.data)
+			StorePointer(&vp.typ, vlp.typ)
 			runtime_procUnpin()
 			return
 		}
@@ -73,14 +73,121 @@
 			continue
 		}
 		// First store completed. Check type and overwrite data.
-		if typ != xp.typ {
+		if typ != vlp.typ {
 			panic("sync/atomic: store of inconsistently typed value into Value")
 		}
-		StorePointer(&vp.data, xp.data)
+		StorePointer(&vp.data, vlp.data)
 		return
 	}
 }
 
+// Swap stores new into Value and returns the previous value. It returns nil if
+// the Value is empty.
+//
+// All calls to Swap for a given Value must use values of the same concrete
+// type. Swap of an inconsistent type panics, as does Swap(nil).
+func (v *Value) Swap(new interface{}) (old interface{}) {
+	if new == nil {
+		panic("sync/atomic: swap of nil value into Value")
+	}
+	vp := (*ifaceWords)(unsafe.Pointer(v))
+	np := (*ifaceWords)(unsafe.Pointer(&new))
+	for {
+		typ := LoadPointer(&vp.typ)
+		if typ == nil {
+			// Attempt to start first store.
+			// Disable preemption so that other goroutines can use
+			// active spin wait to wait for completion; and so that
+			// GC does not see the fake type accidentally.
+			runtime_procPin()
+			if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(^uintptr(0))) {
+				runtime_procUnpin()
+				continue
+			}
+			// Complete first store.
+			StorePointer(&vp.data, np.data)
+			StorePointer(&vp.typ, np.typ)
+			runtime_procUnpin()
+			return nil
+		}
+		if uintptr(typ) == ^uintptr(0) {
+			// First store in progress. Wait.
+			// Since we disable preemption around the first store,
+			// we can wait with active spinning.
+			continue
+		}
+		// First store completed. Check type and overwrite data.
+		if typ != np.typ {
+			panic("sync/atomic: swap of inconsistently typed value into Value")
+		}
+		op := (*ifaceWords)(unsafe.Pointer(&old))
+		op.typ, op.data = np.typ, SwapPointer(&vp.data, np.data)
+		return old
+	}
+}
+
+// CompareAndSwap executes the compare-and-swap operation for the Value.
+//
+// All calls to CompareAndSwap for a given Value must use values of the same
+// concrete type. CompareAndSwap of an inconsistent type panics, as does
+// CompareAndSwap(old, nil).
+func (v *Value) CompareAndSwap(old, new interface{}) (swapped bool) {
+	if new == nil {
+		panic("sync/atomic: compare and swap of nil value into Value")
+	}
+	vp := (*ifaceWords)(unsafe.Pointer(v))
+	np := (*ifaceWords)(unsafe.Pointer(&new))
+	op := (*ifaceWords)(unsafe.Pointer(&old))
+	if op.typ != nil && np.typ != op.typ {
+		panic("sync/atomic: compare and swap of inconsistently typed values")
+	}
+	for {
+		typ := LoadPointer(&vp.typ)
+		if typ == nil {
+			if old != nil {
+				return false
+			}
+			// Attempt to start first store.
+			// Disable preemption so that other goroutines can use
+			// active spin wait to wait for completion; and so that
+			// GC does not see the fake type accidentally.
+			runtime_procPin()
+			if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(^uintptr(0))) {
+				runtime_procUnpin()
+				continue
+			}
+			// Complete first store.
+			StorePointer(&vp.data, np.data)
+			StorePointer(&vp.typ, np.typ)
+			runtime_procUnpin()
+			return true
+		}
+		if uintptr(typ) == ^uintptr(0) {
+			// First store in progress. Wait.
+			// Since we disable preemption around the first store,
+			// we can wait with active spinning.
+			continue
+		}
+		// First store completed. Check type and overwrite data.
+		if typ != np.typ {
+			panic("sync/atomic: compare and swap of inconsistently typed value into Value")
+		}
+		// Compare old and current via runtime equality check.
+		// This allows value types to be compared, something
+		// not offered by the package functions.
+		// CompareAndSwapPointer below only ensures vp.data
+		// has not changed since LoadPointer.
+		data := LoadPointer(&vp.data)
+		var i interface{}
+		(*ifaceWords)(unsafe.Pointer(&i)).typ = typ
+		(*ifaceWords)(unsafe.Pointer(&i)).data = data
+		if i != old {
+			return false
+		}
+		return CompareAndSwapPointer(&vp.data, data, np.data)
+	}
+}
+
 // Disable/enable preemption, implemented in runtime.
 func runtime_procPin()
 func runtime_procUnpin()
diff --git a/src/sync/atomic/value_test.go b/src/sync/atomic/value_test.go
index f289766..a5e717d 100644
--- a/src/sync/atomic/value_test.go
+++ b/src/sync/atomic/value_test.go
@@ -7,6 +7,9 @@
 import (
 	"math/rand"
 	"runtime"
+	"strconv"
+	"sync"
+	"sync/atomic"
 	. "sync/atomic"
 	"testing"
 )
@@ -133,3 +136,139 @@
 		}
 	})
 }
+
+var Value_SwapTests = []struct {
+	init interface{}
+	new  interface{}
+	want interface{}
+	err  interface{}
+}{
+	{init: nil, new: nil, err: "sync/atomic: swap of nil value into Value"},
+	{init: nil, new: true, want: nil, err: nil},
+	{init: true, new: "", err: "sync/atomic: swap of inconsistently typed value into Value"},
+	{init: true, new: false, want: true, err: nil},
+}
+
+func TestValue_Swap(t *testing.T) {
+	for i, tt := range Value_SwapTests {
+		t.Run(strconv.Itoa(i), func(t *testing.T) {
+			var v Value
+			if tt.init != nil {
+				v.Store(tt.init)
+			}
+			defer func() {
+				err := recover()
+				switch {
+				case tt.err == nil && err != nil:
+					t.Errorf("should not panic, got %v", err)
+				case tt.err != nil && err == nil:
+					t.Errorf("should panic %v, got <nil>", tt.err)
+				}
+			}()
+			if got := v.Swap(tt.new); got != tt.want {
+				t.Errorf("got %v, want %v", got, tt.want)
+			}
+			if got := v.Load(); got != tt.new {
+				t.Errorf("got %v, want %v", got, tt.new)
+			}
+		})
+	}
+}
+
+func TestValueSwapConcurrent(t *testing.T) {
+	var v Value
+	var count uint64
+	var g sync.WaitGroup
+	var m, n uint64 = 10000, 10000
+	if testing.Short() {
+		m = 1000
+		n = 1000
+	}
+	for i := uint64(0); i < m*n; i += n {
+		i := i
+		g.Add(1)
+		go func() {
+			var c uint64
+			for new := i; new < i+n; new++ {
+				if old := v.Swap(new); old != nil {
+					c += old.(uint64)
+				}
+			}
+			atomic.AddUint64(&count, c)
+			g.Done()
+		}()
+	}
+	g.Wait()
+	if want, got := (m*n-1)*(m*n)/2, count+v.Load().(uint64); got != want {
+		t.Errorf("sum from 0 to %d was %d, want %v", m*n-1, got, want)
+	}
+}
+
+var heapA, heapB = struct{ uint }{0}, struct{ uint }{0}
+
+var Value_CompareAndSwapTests = []struct {
+	init interface{}
+	new  interface{}
+	old  interface{}
+	want bool
+	err  interface{}
+}{
+	{init: nil, new: nil, old: nil, err: "sync/atomic: compare and swap of nil value into Value"},
+	{init: nil, new: true, old: "", err: "sync/atomic: compare and swap of inconsistently typed values into Value"},
+	{init: nil, new: true, old: true, want: false, err: nil},
+	{init: nil, new: true, old: nil, want: true, err: nil},
+	{init: true, new: "", err: "sync/atomic: compare and swap of inconsistently typed value into Value"},
+	{init: true, new: true, old: false, want: false, err: nil},
+	{init: true, new: true, old: true, want: true, err: nil},
+	{init: heapA, new: struct{ uint }{1}, old: heapB, want: true, err: nil},
+}
+
+func TestValue_CompareAndSwap(t *testing.T) {
+	for i, tt := range Value_CompareAndSwapTests {
+		t.Run(strconv.Itoa(i), func(t *testing.T) {
+			var v Value
+			if tt.init != nil {
+				v.Store(tt.init)
+			}
+			defer func() {
+				err := recover()
+				switch {
+				case tt.err == nil && err != nil:
+					t.Errorf("got %v, wanted no panic", err)
+				case tt.err != nil && err == nil:
+					t.Errorf("did not panic, want %v", tt.err)
+				}
+			}()
+			if got := v.CompareAndSwap(tt.old, tt.new); got != tt.want {
+				t.Errorf("got %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestValueCompareAndSwapConcurrent(t *testing.T) {
+	var v Value
+	var w sync.WaitGroup
+	v.Store(0)
+	m, n := 1000, 100
+	if testing.Short() {
+		m = 100
+		n = 100
+	}
+	for i := 0; i < m; i++ {
+		i := i
+		w.Add(1)
+		go func() {
+			for j := i; j < m*n; runtime.Gosched() {
+				if v.CompareAndSwap(j, j+1) {
+					j += m
+				}
+			}
+			w.Done()
+		}()
+	}
+	w.Wait()
+	if stop := v.Load().(int); stop != m*n {
+		t.Errorf("did not get to %v, stopped at %v", m*n, stop)
+	}
+}
diff --git a/src/sync/map.go b/src/sync/map.go
index 9ad2535..dfb62dd 100644
--- a/src/sync/map.go
+++ b/src/sync/map.go
@@ -73,7 +73,8 @@
 type entry struct {
 	// p points to the interface{} value stored for the entry.
 	//
-	// If p == nil, the entry has been deleted and m.dirty == nil.
+	// If p == nil, the entry has been deleted, and either m.dirty == nil or
+	// m.dirty[key] is e.
 	//
 	// If p == expunged, the entry has been deleted, m.dirty != nil, and the entry
 	// is missing from m.dirty.
diff --git a/src/sync/pool_test.go b/src/sync/pool_test.go
index ad98350..65666da 100644
--- a/src/sync/pool_test.go
+++ b/src/sync/pool_test.go
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // Pool is no-op under race detector, so all these tests do not work.
+//go:build !race
 // +build !race
 
 package sync_test
diff --git a/src/sync/runtime2.go b/src/sync/runtime2.go
index f10c4e8..c4b4489 100644
--- a/src/sync/runtime2.go
+++ b/src/sync/runtime2.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !goexperiment.staticlockranking
 // +build !goexperiment.staticlockranking
 
 package sync
diff --git a/src/sync/runtime2_lockrank.go b/src/sync/runtime2_lockrank.go
index aaa1c27..e91fdb6 100644
--- a/src/sync/runtime2_lockrank.go
+++ b/src/sync/runtime2_lockrank.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build goexperiment.staticlockranking
 // +build goexperiment.staticlockranking
 
 package sync
diff --git a/src/syscall/asm9_unix1_amd64.s b/src/syscall/asm9_unix1_amd64.s
index f2ae87d..e4609d0 100644
--- a/src/syscall/asm9_unix1_amd64.s
+++ b/src/syscall/asm9_unix1_amd64.s
@@ -1,9 +1,10 @@
-// +build netbsd
-
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build netbsd
+// +build netbsd
+
 #include "textflag.h"
 #include "funcdata.h"
 
diff --git a/src/syscall/asm9_unix2_amd64.s b/src/syscall/asm9_unix2_amd64.s
index 6633c12..7e5e3c5 100644
--- a/src/syscall/asm9_unix2_amd64.s
+++ b/src/syscall/asm9_unix2_amd64.s
@@ -1,9 +1,10 @@
-// +build dragonfly freebsd
-
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd
+// +build dragonfly freebsd
+
 #include "textflag.h"
 #include "funcdata.h"
 
diff --git a/src/syscall/asm_linux_386.s b/src/syscall/asm_linux_386.s
index 4201f36..1c69083 100644
--- a/src/syscall/asm_linux_386.s
+++ b/src/syscall/asm_linux_386.s
@@ -110,6 +110,26 @@
 	MOVL	$0, err+36(FP)
 	RET
 
+// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
+	MOVL	trap+0(FP), AX	// syscall entry
+	MOVL	a1+4(FP), BX
+	MOVL	$0, CX
+	MOVL	$0, DX
+	POPL	SI // preserve return address
+	INVOKE_SYSCALL
+	PUSHL	SI
+	CMPL	AX, $0xfffff001
+	JLS	ok
+	MOVL	$-1, r1+8(FP)
+	NEGL	AX
+	MOVL	AX, err+12(FP)
+	RET
+ok:
+	MOVL	AX, r1+8(FP)
+	MOVL	$0, err+12(FP)
+	RET
+
 // func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-24
 	MOVL	trap+0(FP), AX	// syscall entry
diff --git a/src/syscall/asm_linux_amd64.s b/src/syscall/asm_linux_amd64.s
index ba22179..a9af68d 100644
--- a/src/syscall/asm_linux_amd64.s
+++ b/src/syscall/asm_linux_amd64.s
@@ -108,7 +108,7 @@
 	RET
 
 // func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
-TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-32
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
 	MOVQ	a1+8(FP), DI
 	MOVQ	$0, SI
 	MOVQ	$0, DX
diff --git a/src/syscall/asm_linux_arm.s b/src/syscall/asm_linux_arm.s
index 458e9cc..6bb4df8 100644
--- a/src/syscall/asm_linux_arm.s
+++ b/src/syscall/asm_linux_arm.s
@@ -154,6 +154,27 @@
 	MOVW	R0, err+24(FP)
 	RET
 
+// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
+	MOVW	trap+0(FP), R7	// syscall entry
+	MOVW	a1+4(FP), R0
+	MOVW	$0, R1
+	MOVW	$0, R2
+	SWI	$0
+	MOVW	$0xfffff001, R1
+	CMP	R1, R0
+	BLS	ok
+	MOVW	$-1, R1
+	MOVW	R1, r1+8(FP)
+	RSB	$0, R0, R0
+	MOVW	R0, err+12(FP)
+	RET
+ok:
+	MOVW	R0, r1+8(FP)
+	MOVW	$0, R0
+	MOVW	R0, err+12(FP)
+	RET
+
 // func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-24
 	MOVW	trap+0(FP), R7	// syscall entry
diff --git a/src/syscall/asm_linux_arm64.s b/src/syscall/asm_linux_arm64.s
index fb22f8d..a30e4d8 100644
--- a/src/syscall/asm_linux_arm64.s
+++ b/src/syscall/asm_linux_arm64.s
@@ -125,7 +125,6 @@
 	MOVD	ZR, err+24(FP)	// errno
 	RET
 
-
 // func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
 	MOVD	a1+8(FP), R0
diff --git a/src/syscall/asm_linux_mips64x.s b/src/syscall/asm_linux_mips64x.s
index d0b0e5a..d18a7b8 100644
--- a/src/syscall/asm_linux_mips64x.s
+++ b/src/syscall/asm_linux_mips64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips64 || mips64le)
 // +build linux
 // +build mips64 mips64le
 
@@ -102,6 +103,26 @@
 	MOVV	R0, err+72(FP)	// errno
 	RET
 
+// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
+	MOVV	a1+8(FP), R4
+	MOVV	R0, R5
+	MOVV	R0, R6
+	MOVV	R0, R7
+	MOVV	R0, R8
+	MOVV	R0, R9
+	MOVV	trap+0(FP), R2	// syscall entry
+	SYSCALL
+	BEQ	R7, ok
+	MOVV	$-1, R1
+	MOVV	R1, r1+16(FP)	// r1
+	MOVV	R2, err+24(FP)	// errno
+	RET
+ok:
+	MOVV	R2, r1+16(FP)	// r1
+	MOVV	R0, err+24(FP)	// errno
+	RET
+
 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
 	MOVV	a1+8(FP), R4
 	MOVV	a2+16(FP), R5
diff --git a/src/syscall/asm_linux_mipsx.s b/src/syscall/asm_linux_mipsx.s
index 5727e4d..cafa6a3 100644
--- a/src/syscall/asm_linux_mipsx.s
+++ b/src/syscall/asm_linux_mipsx.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips || mipsle)
 // +build linux
 // +build mips mipsle
 
@@ -139,6 +140,23 @@
 	MOVW	R0, err+36(FP)	// errno
 	RET
 
+// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
+	MOVW	a1+4(FP), R4
+	MOVW	R0, R5
+	MOVW	R0, R6
+	MOVW	trap+0(FP), R2	// syscall entry
+	SYSCALL
+	BEQ	R7, ok
+	MOVW	$-1, R1
+	MOVW	R1, r1+8(FP)	// r1
+	MOVW	R2, err+12(FP)	// errno
+	RET
+ok:
+	MOVW	R2, r1+8(FP)	// r1
+	MOVW	R0, err+12(FP)	// errno
+	RET
+
 TEXT ·rawSyscallNoError(SB),NOSPLIT,$20-24
 	MOVW	a1+4(FP), R4
 	MOVW	a2+8(FP), R5
diff --git a/src/syscall/asm_linux_ppc64x.s b/src/syscall/asm_linux_ppc64x.s
index 8be0d68..eac7272 100644
--- a/src/syscall/asm_linux_ppc64x.s
+++ b/src/syscall/asm_linux_ppc64x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (ppc64 || ppc64le)
 // +build linux
 // +build ppc64 ppc64le
 
diff --git a/src/syscall/asm_openbsd_386.s b/src/syscall/asm_openbsd_386.s
new file mode 100644
index 0000000..6f7b275
--- /dev/null
+++ b/src/syscall/asm_openbsd_386.s
@@ -0,0 +1,32 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+//
+// System call support for 386, OpenBSD
+//
+
+// Provide these function names via assembly so they are provided as ABI0,
+// rather than ABIInternal.
+
+// func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+TEXT	·Syscall(SB),NOSPLIT,$0-28
+	JMP	·syscallInternal(SB)
+
+// func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+TEXT	·Syscall6(SB),NOSPLIT,$0-40
+	JMP	·syscall6Internal(SB)
+
+// func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+TEXT	·RawSyscall(SB),NOSPLIT,$0-28
+	JMP	·rawSyscallInternal(SB)
+
+// func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	JMP	·rawSyscall6Internal(SB)
+
+// func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
+TEXT	·Syscall9(SB),NOSPLIT,$0-52
+	JMP	·syscall9Internal(SB)
diff --git a/src/syscall/asm_openbsd_arm.s b/src/syscall/asm_openbsd_arm.s
index 26fd791..520da91 100644
--- a/src/syscall/asm_openbsd_arm.s
+++ b/src/syscall/asm_openbsd_arm.s
@@ -3,137 +3,30 @@
 // license that can be found in the LICENSE file.
 
 #include "textflag.h"
-#include "funcdata.h"
 
 //
 // System call support for ARM, OpenBSD
 //
 
-// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
-// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
-// func Syscall9(trap int32, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int32)
-// func RawSyscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
-// func RawSyscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
+// Provide these function names via assembly so they are provided as ABI0,
+// rather than ABIInternal.
 
-// See comment in runtime/sys_openbsd_arm.s re this construction.
-#define NOOP	MOVW    R0, R0
-#define	INVOKE_SYSCALL	\
-	SWI	$0;	\
-	NOOP;		\
-	NOOP
-
+// func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
 TEXT	·Syscall(SB),NOSPLIT,$0-28
-	BL runtime·entersyscall(SB)
-	MOVW trap+0(FP), R12		// syscall number
-	MOVW a1+4(FP), R0		// arg 1
-	MOVW a2+8(FP), R1		// arg 2
-	MOVW a3+12(FP), R2		// arg 3
-	INVOKE_SYSCALL
-	MOVW $0, R2
-	BCS error
-	MOVW R0, r1+16(FP)		// ret 1
-	MOVW R1, r2+20(FP)		// ret 2
-	MOVW R2, err+24(FP)		// err
-	BL runtime·exitsyscall(SB)
-	RET
-error:
-	MOVW $-1, R3
-	MOVW R3, r1+16(FP)		// ret 1
-	MOVW R2, r2+20(FP)		// ret 2
-	MOVW R0, err+24(FP)		// err
-	BL runtime·exitsyscall(SB)
-	RET
+	JMP	·syscallInternal(SB)
 
+// func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	BL runtime·entersyscall(SB)
-	MOVW trap+0(FP), R12		// syscall number
-	MOVW a1+4(FP), R0		// arg 1
-	MOVW a2+8(FP), R1		// arg 2
-	MOVW a3+12(FP), R2		// arg 3
-	MOVW a4+16(FP), R3		// arg 4
-	MOVW R13, R4
-	MOVW $a5+20(FP), R13		// arg 5 to arg 6 are passed on stack
-	INVOKE_SYSCALL
-	MOVW R4, R13
-	MOVW $0, R2
-	BCS error6
-	MOVW R0, r1+28(FP)		// ret 1
-	MOVW R1, r2+32(FP)		// ret 2
-	MOVW R2, err+36(FP)		// err
-	BL runtime·exitsyscall(SB)
-	RET
-error6:
-	MOVW $-1, R3
-	MOVW R3, r1+28(FP)		// ret 1
-	MOVW R2, r2+32(FP)		// ret 2
-	MOVW R0, err+36(FP)		// err
-	BL runtime·exitsyscall(SB)
-	RET
+	JMP	·syscall6Internal(SB)
 
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	BL runtime·entersyscall(SB)
-	MOVW num+0(FP), R12		// syscall number
-	MOVW a1+4(FP), R0		// arg 1
-	MOVW a2+8(FP), R1		// arg 2
-	MOVW a3+12(FP), R2		// arg 3
-	MOVW a4+16(FP), R3		// arg 4
-	MOVW R13, R4
-	MOVW $a5+20(FP), R13		// arg 5 to arg 9 are passed on stack
-	INVOKE_SYSCALL
-	MOVW R4, R13
-	MOVW $0, R2
-	BCS error9
-	MOVW R0, r1+40(FP)		// ret 1
-	MOVW R1, r2+44(FP)		// ret 2
-	MOVW R2, err+48(FP)		// err
-	BL runtime·exitsyscall(SB)
-	RET
-error9:
-	MOVW $-1, R3
-	MOVW R3, r1+40(FP)		// ret 1
-	MOVW R2, r2+44(FP)		// ret 2
-	MOVW R0, err+48(FP)		// err
-	BL runtime·exitsyscall(SB)
-	RET
-
+// func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
 TEXT	·RawSyscall(SB),NOSPLIT,$0-28
-	MOVW trap+0(FP), R12		// syscall number
-	MOVW a1+4(FP), R0		// arg 1
-	MOVW a2+8(FP), R1		// arg 2
-	MOVW a3+12(FP), R2		// arg 3
-	INVOKE_SYSCALL
-	MOVW $0, R2
-	BCS errorr
-	MOVW R0, r1+16(FP)		// ret 1
-	MOVW R1, r2+20(FP)		// ret 2
-	MOVW R2, err+24(FP)		// err
-	RET
-errorr:
-	MOVW $-1, R3
-	MOVW R3, r1+16(FP)		// ret 1
-	MOVW R2, r2+20(FP)		// ret 2
-	MOVW R0, err+24(FP)		// err
-	RET
+	JMP	·rawSyscallInternal(SB)
 
+// func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	MOVW trap+0(FP), R12		// syscall number
-	MOVW a1+4(FP), R0		// arg 1
-	MOVW a2+8(FP), R1		// arg 2
-	MOVW a3+12(FP), R2		// arg 3
-	MOVW a4+16(FP), R3		// arg 4
-	MOVW R13, R4
-	MOVW $a5+20(FP), R13		// arg 5 to arg 6 are passed on stack
-	INVOKE_SYSCALL
-	MOVW R4, R13
-	MOVW $0, R2
-	BCS errorr6
-	MOVW R0, r1+28(FP)		// ret 1
-	MOVW R1, r2+32(FP)		// ret 2
-	MOVW R2, err+36(FP)		// err
-	RET
-errorr6:
-	MOVW $-1, R3
-	MOVW R3, r1+28(FP)		// ret 1
-	MOVW R2, r2+32(FP)		// ret 2
-	MOVW R0, err+36(FP)		// err
-	RET
+	JMP	·rawSyscall6Internal(SB)
+
+// func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
+TEXT	·Syscall9(SB),NOSPLIT,$0-52
+	JMP	·syscall9Internal(SB)
diff --git a/src/syscall/asm_unix_386.s b/src/syscall/asm_unix_386.s
index 1e82b88..9f9b7f3 100644
--- a/src/syscall/asm_unix_386.s
+++ b/src/syscall/asm_unix_386.s
@@ -1,9 +1,10 @@
-// +build netbsd freebsd openbsd
-
 // Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build freebsd || netbsd
+// +build freebsd netbsd
+
 #include "textflag.h"
 #include "funcdata.h"
 
diff --git a/src/syscall/asm_unix_amd64.s b/src/syscall/asm_unix_amd64.s
index aa03eb9..c53e1a4 100644
--- a/src/syscall/asm_unix_amd64.s
+++ b/src/syscall/asm_unix_amd64.s
@@ -1,9 +1,10 @@
-// +build netbsd freebsd dragonfly
-
 // Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || netbsd
+// +build dragonfly freebsd netbsd
+
 #include "textflag.h"
 #include "funcdata.h"
 
diff --git a/src/syscall/asm_windows.s b/src/syscall/asm_windows.s
deleted file mode 100644
index e965914..0000000
--- a/src/syscall/asm_windows.s
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// abi0Syms is a dummy symbol that creates ABI0 wrappers for Go
-// functions called from assembly in other packages.
-TEXT abi0Syms<>(SB),NOSPLIT,$0-0
-	CALL ·getprocaddress(SB)
-	CALL ·loadlibrary(SB)
diff --git a/src/syscall/bpf_bsd.go b/src/syscall/bpf_bsd.go
index f67ee60..452d4cf 100644
--- a/src/syscall/bpf_bsd.go
+++ b/src/syscall/bpf_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || netbsd || openbsd
 // +build dragonfly freebsd netbsd openbsd
 
 // Berkeley packet filter for BSD variants
diff --git a/src/syscall/creds_test.go b/src/syscall/creds_test.go
index 524689a..c1a8b51 100644
--- a/src/syscall/creds_test.go
+++ b/src/syscall/creds_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux
 // +build linux
 
 package syscall_test
@@ -37,16 +38,19 @@
 		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 {
+			syscall.Close(fds[0])
+			syscall.Close(fds[1])
 			t.Fatalf("SetsockoptInt: %v", err)
 		}
 
 		srvFile := os.NewFile(uintptr(fds[0]), "server")
+		cliFile := os.NewFile(uintptr(fds[1]), "client")
 		defer srvFile.Close()
+		defer cliFile.Close()
+
 		srv, err := net.FileConn(srvFile)
 		if err != nil {
 			t.Errorf("FileConn: %v", err)
@@ -54,8 +58,6 @@
 		}
 		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)
@@ -103,8 +105,8 @@
 		if err != nil {
 			t.Fatalf("ReadMsgUnix: %v", err)
 		}
-		if flags != 0 {
-			t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
+		if flags != syscall.MSG_CMSG_CLOEXEC {
+			t.Fatalf("ReadMsgUnix flags = %#x, want %#x (MSG_CMSG_CLOEXEC)", flags, syscall.MSG_CMSG_CLOEXEC)
 		}
 		if n != tt.dataLen {
 			t.Fatalf("ReadMsgUnix n = %d, want %d", n, tt.dataLen)
diff --git a/src/syscall/dirent.go b/src/syscall/dirent.go
index fab123d..9e1222e 100644
--- a/src/syscall/dirent.go
+++ b/src/syscall/dirent.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package syscall
diff --git a/src/syscall/dirent_test.go b/src/syscall/dirent_test.go
index 7dac98f..71b445b 100644
--- a/src/syscall/dirent_test.go
+++ b/src/syscall/dirent_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package syscall_test
@@ -26,16 +27,12 @@
 		filenameMinSize = 11
 	)
 
-	d, err := os.MkdirTemp("", "dirent-test")
-	if err != nil {
-		t.Fatalf("tempdir: %v", err)
-	}
-	defer os.RemoveAll(d)
+	d := t.TempDir()
 	t.Logf("tmpdir: %s", d)
 
 	for i, c := range []byte("0123456789") {
 		name := string(bytes.Repeat([]byte{c}, filenameMinSize+i))
-		err = os.WriteFile(filepath.Join(d, name), nil, 0644)
+		err := os.WriteFile(filepath.Join(d, name), nil, 0644)
 		if err != nil {
 			t.Fatalf("writefile: %v", err)
 		}
@@ -92,18 +89,14 @@
 	}
 
 	// Make a directory containing N files
-	d, err := os.MkdirTemp("", "direntRepeat-test")
-	if err != nil {
-		t.Fatalf("tempdir: %v", err)
-	}
-	defer os.RemoveAll(d)
+	d := t.TempDir()
 
 	var files []string
 	for i := 0; i < N; i++ {
 		files = append(files, fmt.Sprintf("file%d", i))
 	}
 	for _, file := range files {
-		err = os.WriteFile(filepath.Join(d, file), []byte("contents"), 0644)
+		err := os.WriteFile(filepath.Join(d, file), []byte("contents"), 0644)
 		if err != nil {
 			t.Fatalf("writefile: %v", err)
 		}
diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go
index d99da00..16210ca 100644
--- a/src/syscall/dll_windows.go
+++ b/src/syscall/dll_windows.go
@@ -5,6 +5,7 @@
 package syscall
 
 import (
+	"internal/itoa"
 	"internal/syscall/windows/sysdll"
 	"sync"
 	"sync/atomic"
@@ -215,7 +216,7 @@
 	case 18:
 		return Syscall18(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17])
 	default:
-		panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".")
+		panic("Call " + p.Name + " with too many arguments " + itoa.Itoa(len(a)) + ".")
 	}
 }
 
diff --git a/src/syscall/endian_big.go b/src/syscall/endian_big.go
index 3c26005..dc0947f 100644
--- a/src/syscall/endian_big.go
+++ b/src/syscall/endian_big.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 //
+//go:build ppc64 || s390x || mips || mips64
 // +build ppc64 s390x mips mips64
 
 package syscall
diff --git a/src/syscall/endian_little.go b/src/syscall/endian_little.go
index 43b081d..a894445 100644
--- a/src/syscall/endian_little.go
+++ b/src/syscall/endian_little.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 //
+//go:build 386 || amd64 || arm || arm64 || ppc64le || mips64le || mipsle || riscv64 || wasm
 // +build 386 amd64 arm arm64 ppc64le mips64le mipsle riscv64 wasm
 
 package syscall
diff --git a/src/syscall/env_unix.go b/src/syscall/env_unix.go
index a4bb28c..022ef6e 100644
--- a/src/syscall/env_unix.go
+++ b/src/syscall/env_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || plan9
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris plan9
 
 // Unix environment variables.
diff --git a/src/syscall/exec_aix_test.go b/src/syscall/exec_aix_test.go
index 22b752c..17c7ac0 100644
--- a/src/syscall/exec_aix_test.go
+++ b/src/syscall/exec_aix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix
 // +build aix
 
 package syscall
diff --git a/src/syscall/exec_bsd.go b/src/syscall/exec_bsd.go
index 940a81b..709066e 100644
--- a/src/syscall/exec_bsd.go
+++ b/src/syscall/exec_bsd.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build dragonfly freebsd netbsd openbsd,!amd64,!arm64
+//go:build dragonfly || freebsd || netbsd || (openbsd && mips64)
+// +build dragonfly freebsd netbsd openbsd,mips64
 
 package syscall
 
@@ -89,8 +90,6 @@
 
 	// Fork succeeded, now in child.
 
-	runtime_AfterForkInChild()
-
 	// Enable tracing if requested.
 	if sys.Ptrace {
 		_, _, err1 = RawSyscall(SYS_PTRACE, uintptr(PTRACE_TRACEME), 0, 0)
@@ -136,6 +135,10 @@
 		}
 	}
 
+	// Restore the signal mask. We do this after TIOCSPGRP to avoid
+	// having the kernel send a SIGTTOU signal to the process group.
+	runtime_AfterForkInChild()
+
 	// Chroot
 	if chroot != nil {
 		_, _, err1 = RawSyscall(SYS_CHROOT, uintptr(unsafe.Pointer(chroot)), 0, 0)
diff --git a/src/syscall/exec_libc.go b/src/syscall/exec_libc.go
index 3722858..8a84954 100644
--- a/src/syscall/exec_libc.go
+++ b/src/syscall/exec_libc.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || solaris
 // +build aix solaris
 
 // This file handles forkAndExecInChild function for OS using libc syscall like AIX or Solaris.
@@ -115,8 +116,6 @@
 
 	// Fork succeeded, now in child.
 
-	runtime_AfterForkInChild()
-
 	// Session ID
 	if sys.Setsid {
 		_, err1 = setsid()
@@ -152,6 +151,10 @@
 		}
 	}
 
+	// Restore the signal mask. We do this after TIOCSPGRP to avoid
+	// having the kernel send a SIGTTOU signal to the process group.
+	runtime_AfterForkInChild()
+
 	// Chroot
 	if chroot != nil {
 		err1 = chroot1(uintptr(unsafe.Pointer(chroot)))
diff --git a/src/syscall/exec_libc2.go b/src/syscall/exec_libc2.go
index 45d3f85..b999754 100644
--- a/src/syscall/exec_libc2.go
+++ b/src/syscall/exec_libc2.go
@@ -2,11 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin openbsd,amd64 openbsd,arm64
+//go:build darwin || (openbsd && !mips64)
+// +build darwin openbsd,!mips64
 
 package syscall
 
 import (
+	"internal/abi"
 	"unsafe"
 )
 
@@ -75,7 +77,7 @@
 	// About to call fork.
 	// No more allocation or calls of non-assembly functions.
 	runtime_BeforeFork()
-	r1, _, err1 = rawSyscall(funcPC(libc_fork_trampoline), 0, 0, 0)
+	r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
 	if err1 != 0 {
 		runtime_AfterFork()
 		return 0, err1
@@ -89,8 +91,6 @@
 
 	// Fork succeeded, now in child.
 
-	runtime_AfterForkInChild()
-
 	// Enable tracing if requested.
 	if sys.Ptrace {
 		if err := ptrace(PTRACE_TRACEME, 0, 0, 0); err != nil {
@@ -101,7 +101,7 @@
 
 	// Session ID
 	if sys.Setsid {
-		_, _, err1 = rawSyscall(funcPC(libc_setsid_trampoline), 0, 0, 0)
+		_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
 		if err1 != 0 {
 			goto childerror
 		}
@@ -110,7 +110,7 @@
 	// Set process group
 	if sys.Setpgid || sys.Foreground {
 		// Place child in process group.
-		_, _, err1 = rawSyscall(funcPC(libc_setpgid_trampoline), 0, uintptr(sys.Pgid), 0)
+		_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), 0, uintptr(sys.Pgid), 0)
 		if err1 != 0 {
 			goto childerror
 		}
@@ -119,7 +119,7 @@
 	if sys.Foreground {
 		pgrp := sys.Pgid
 		if pgrp == 0 {
-			r1, _, err1 = rawSyscall(funcPC(libc_getpid_trampoline), 0, 0, 0)
+			r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
 			if err1 != 0 {
 				goto childerror
 			}
@@ -128,15 +128,19 @@
 		}
 
 		// Place process group in foreground.
-		_, _, err1 = rawSyscall(funcPC(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSPGRP), uintptr(unsafe.Pointer(&pgrp)))
+		_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSPGRP), uintptr(unsafe.Pointer(&pgrp)))
 		if err1 != 0 {
 			goto childerror
 		}
 	}
 
+	// Restore the signal mask. We do this after TIOCSPGRP to avoid
+	// having the kernel send a SIGTTOU signal to the process group.
+	runtime_AfterForkInChild()
+
 	// Chroot
 	if chroot != nil {
-		_, _, err1 = rawSyscall(funcPC(libc_chroot_trampoline), uintptr(unsafe.Pointer(chroot)), 0, 0)
+		_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(chroot)), 0, 0)
 		if err1 != 0 {
 			goto childerror
 		}
@@ -150,16 +154,16 @@
 			groups = uintptr(unsafe.Pointer(&cred.Groups[0]))
 		}
 		if !cred.NoSetGroups {
-			_, _, err1 = rawSyscall(funcPC(libc_setgroups_trampoline), ngroups, groups, 0)
+			_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), ngroups, groups, 0)
 			if err1 != 0 {
 				goto childerror
 			}
 		}
-		_, _, err1 = rawSyscall(funcPC(libc_setgid_trampoline), uintptr(cred.Gid), 0, 0)
+		_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(cred.Gid), 0, 0)
 		if err1 != 0 {
 			goto childerror
 		}
-		_, _, err1 = rawSyscall(funcPC(libc_setuid_trampoline), uintptr(cred.Uid), 0, 0)
+		_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(cred.Uid), 0, 0)
 		if err1 != 0 {
 			goto childerror
 		}
@@ -167,7 +171,7 @@
 
 	// Chdir
 	if dir != nil {
-		_, _, err1 = rawSyscall(funcPC(libc_chdir_trampoline), uintptr(unsafe.Pointer(dir)), 0, 0)
+		_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(dir)), 0, 0)
 		if err1 != 0 {
 			goto childerror
 		}
@@ -176,11 +180,11 @@
 	// Pass 1: look for fd[i] < i and move those up above len(fd)
 	// so that pass 2 won't stomp on an fd it needs later.
 	if pipe < nextfd {
-		_, _, err1 = rawSyscall(funcPC(libc_dup2_trampoline), uintptr(pipe), uintptr(nextfd), 0)
+		_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(pipe), uintptr(nextfd), 0)
 		if err1 != 0 {
 			goto childerror
 		}
-		rawSyscall(funcPC(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+		rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
 		pipe = nextfd
 		nextfd++
 	}
@@ -189,11 +193,11 @@
 			if nextfd == pipe { // don't stomp on pipe
 				nextfd++
 			}
-			_, _, err1 = rawSyscall(funcPC(libc_dup2_trampoline), uintptr(fd[i]), uintptr(nextfd), 0)
+			_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(fd[i]), uintptr(nextfd), 0)
 			if err1 != 0 {
 				goto childerror
 			}
-			rawSyscall(funcPC(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+			rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
 			fd[i] = nextfd
 			nextfd++
 		}
@@ -202,13 +206,13 @@
 	// Pass 2: dup fd[i] down onto i.
 	for i = 0; i < len(fd); i++ {
 		if fd[i] == -1 {
-			rawSyscall(funcPC(libc_close_trampoline), uintptr(i), 0, 0)
+			rawSyscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(i), 0, 0)
 			continue
 		}
 		if fd[i] == int(i) {
 			// dup2(i, i) won't clear close-on-exec flag on Linux,
 			// probably not elsewhere either.
-			_, _, err1 = rawSyscall(funcPC(libc_fcntl_trampoline), uintptr(fd[i]), F_SETFD, 0)
+			_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd[i]), F_SETFD, 0)
 			if err1 != 0 {
 				goto childerror
 			}
@@ -216,7 +220,7 @@
 		}
 		// The new fd is created NOT close-on-exec,
 		// which is exactly what we want.
-		_, _, err1 = rawSyscall(funcPC(libc_dup2_trampoline), uintptr(fd[i]), uintptr(i), 0)
+		_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(fd[i]), uintptr(i), 0)
 		if err1 != 0 {
 			goto childerror
 		}
@@ -227,12 +231,12 @@
 	// Programs that know they inherit fds >= 3 will need
 	// to set them close-on-exec.
 	for i = len(fd); i < 3; i++ {
-		rawSyscall(funcPC(libc_close_trampoline), uintptr(i), 0, 0)
+		rawSyscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(i), 0, 0)
 	}
 
 	// Detach fd 0 from tty
 	if sys.Noctty {
-		_, _, err1 = rawSyscall(funcPC(libc_ioctl_trampoline), 0, uintptr(TIOCNOTTY), 0)
+		_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), 0, uintptr(TIOCNOTTY), 0)
 		if err1 != 0 {
 			goto childerror
 		}
@@ -240,22 +244,22 @@
 
 	// Set the controlling TTY to Ctty
 	if sys.Setctty {
-		_, _, err1 = rawSyscall(funcPC(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
+		_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
 		if err1 != 0 {
 			goto childerror
 		}
 	}
 
 	// Time to exec.
-	_, _, err1 = rawSyscall(funcPC(libc_execve_trampoline),
+	_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_execve_trampoline),
 		uintptr(unsafe.Pointer(argv0)),
 		uintptr(unsafe.Pointer(&argv[0])),
 		uintptr(unsafe.Pointer(&envv[0])))
 
 childerror:
 	// send error code on pipe
-	rawSyscall(funcPC(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
+	rawSyscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
 	for {
-		rawSyscall(funcPC(libc_exit_trampoline), 253, 0, 0)
+		rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), 253, 0, 0)
 	}
 }
diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
index b6acad9..ccc0e39 100644
--- a/src/syscall/exec_linux.go
+++ b/src/syscall/exec_linux.go
@@ -2,11 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux
 // +build linux
 
 package syscall
 
 import (
+	"internal/itoa"
 	"runtime"
 	"unsafe"
 )
@@ -207,18 +209,12 @@
 		}
 	}
 
-	var hasRawVforkSyscall bool
-	switch runtime.GOARCH {
-	case "amd64", "arm64", "ppc64", "riscv64", "s390x":
-		hasRawVforkSyscall = true
-	}
-
 	// About to call fork.
 	// No more allocation or calls of non-assembly functions.
 	runtime_BeforeFork()
 	locked = true
 	switch {
-	case hasRawVforkSyscall && (sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0):
+	case sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0:
 		r1, err1 = rawVforkSyscall(SYS_CLONE, uintptr(SIGCHLD|CLONE_VFORK|CLONE_VM)|sys.Cloneflags)
 	case runtime.GOARCH == "s390x":
 		r1, _, err1 = RawSyscall6(SYS_CLONE, 0, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0)
@@ -237,8 +233,6 @@
 
 	// Fork succeeded, now in child.
 
-	runtime_AfterForkInChild()
-
 	// Enable the "keep capabilities" flag to set ambient capabilities later.
 	if len(sys.AmbientCaps) > 0 {
 		_, _, err1 = RawSyscall6(SYS_PRCTL, PR_SET_KEEPCAPS, 1, 0, 0, 0, 0)
@@ -298,6 +292,10 @@
 		}
 	}
 
+	// Restore the signal mask. We do this after TIOCSPGRP to avoid
+	// having the kernel send a SIGTTOU signal to the process group.
+	runtime_AfterForkInChild()
+
 	// Unshare
 	if sys.Unshareflags != 0 {
 		_, _, err1 = RawSyscall(SYS_UNSHARE, sys.Unshareflags, 0, 0)
@@ -573,7 +571,7 @@
 func formatIDMappings(idMap []SysProcIDMap) []byte {
 	var data []byte
 	for _, im := range idMap {
-		data = append(data, []byte(itoa(im.ContainerID)+" "+itoa(im.HostID)+" "+itoa(im.Size)+"\n")...)
+		data = append(data, []byte(itoa.Itoa(im.ContainerID)+" "+itoa.Itoa(im.HostID)+" "+itoa.Itoa(im.Size)+"\n")...)
 	}
 	return data
 }
@@ -602,7 +600,7 @@
 // This is needed since kernel 3.19, because you can't write gid_map without
 // disabling setgroups() system call.
 func writeSetgroups(pid int, enable bool) error {
-	sgf := "/proc/" + itoa(pid) + "/setgroups"
+	sgf := "/proc/" + itoa.Itoa(pid) + "/setgroups"
 	fd, err := Open(sgf, O_RDWR, 0)
 	if err != nil {
 		return err
@@ -627,7 +625,7 @@
 // for a process and it is called from the parent process.
 func writeUidGidMappings(pid int, sys *SysProcAttr) error {
 	if sys.UidMappings != nil {
-		uidf := "/proc/" + itoa(pid) + "/uid_map"
+		uidf := "/proc/" + itoa.Itoa(pid) + "/uid_map"
 		if err := writeIDMappings(uidf, sys.UidMappings); err != nil {
 			return err
 		}
@@ -638,7 +636,7 @@
 		if err := writeSetgroups(pid, sys.GidMappingsEnableSetgroups); err != nil && err != ENOENT {
 			return err
 		}
-		gidf := "/proc/" + itoa(pid) + "/gid_map"
+		gidf := "/proc/" + itoa.Itoa(pid) + "/gid_map"
 		if err := writeIDMappings(gidf, sys.GidMappings); err != nil {
 			return err
 		}
diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
index ac3a575..85b59ad 100644
--- a/src/syscall/exec_linux_test.go
+++ b/src/syscall/exec_linux_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux
 // +build linux
 
 package syscall_test
@@ -317,6 +318,7 @@
 		"uid=0(root) gid=0(root) groups=0(root),65534",
 		"uid=0(root) gid=0(root) groups=0(root),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody)", // Alpine; see https://golang.org/issue/19938
 		"uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023",                                                                               // CentOS with SELinux context, see https://golang.org/issue/34547
+		"uid=0(root) gid=0(root) groups=0(root),65534(nobody) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023",                                                                 // Fedora with SElinux context, see https://golang.org/issue/46752
 	}
 	for _, e := range expected {
 		if strOut == e {
diff --git a/src/syscall/exec_plan9.go b/src/syscall/exec_plan9.go
index 12c4237..c469fe1 100644
--- a/src/syscall/exec_plan9.go
+++ b/src/syscall/exec_plan9.go
@@ -7,6 +7,7 @@
 package syscall
 
 import (
+	"internal/itoa"
 	"runtime"
 	"sync"
 	"unsafe"
@@ -320,7 +321,7 @@
 		return e
 	}
 
-	fd, e := Open("#d/"+itoa(p[1]), O_RDWR|O_CLOEXEC)
+	fd, e := Open("#d/"+itoa.Itoa(p[1]), O_RDWR|O_CLOEXEC)
 	if e != nil {
 		Close(p[0])
 		Close(p[1])
diff --git a/src/syscall/exec_solaris_test.go b/src/syscall/exec_solaris_test.go
index 6b8f1ad..f54fc83 100644
--- a/src/syscall/exec_solaris_test.go
+++ b/src/syscall/exec_solaris_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build solaris
 // +build solaris
 
 package syscall
diff --git a/src/syscall/exec_unix.go b/src/syscall/exec_unix.go
index 1f49c78..54b18dc 100644
--- a/src/syscall/exec_unix.go
+++ b/src/syscall/exec_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 // Fork, exec, wait, etc.
@@ -300,7 +301,7 @@
 	} else if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
 		// Similarly on Darwin.
 		err1 = execveDarwin(argv0p, &argvp[0], &envvp[0])
-	} else if runtime.GOOS == "openbsd" && runtime.GOARCH == "amd64" {
+	} else if runtime.GOOS == "openbsd" && (runtime.GOARCH == "386" || runtime.GOARCH == "amd64" || runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
 		// Similarly on OpenBSD.
 		err1 = execveOpenBSD(argv0p, &argvp[0], &envvp[0])
 	} else {
diff --git a/src/syscall/exec_unix_test.go b/src/syscall/exec_unix_test.go
index d6b6f51..866671b 100644
--- a/src/syscall/exec_unix_test.go
+++ b/src/syscall/exec_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package syscall_test
@@ -166,11 +167,13 @@
 
 func TestForeground(t *testing.T) {
 	signal.Ignore(syscall.SIGTTIN, syscall.SIGTTOU)
+	defer signal.Reset()
 
 	tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
 	if err != nil {
 		t.Skipf("Can't test Foreground. Couldn't open /dev/tty: %s", err)
 	}
+	defer tty.Close()
 
 	// This should really be pid_t, however _C_int (aka int32) is generally
 	// equivalent.
@@ -211,12 +214,68 @@
 
 	cmd.Stop()
 
-	errno = syscall.Ioctl(tty.Fd(), syscall.TIOCSPGRP, uintptr(unsafe.Pointer(&fpgrp)))
+	// This call fails on darwin/arm64. The failure doesn't matter, though.
+	// This is just best effort.
+	syscall.Ioctl(tty.Fd(), syscall.TIOCSPGRP, uintptr(unsafe.Pointer(&fpgrp)))
+}
+
+func TestForegroundSignal(t *testing.T) {
+	tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
+	if err != nil {
+		t.Skipf("couldn't open /dev/tty: %s", err)
+	}
+	defer tty.Close()
+
+	// This should really be pid_t, however _C_int (aka int32) is generally
+	// equivalent.
+	fpgrp := int32(0)
+
+	errno := syscall.Ioctl(tty.Fd(), syscall.TIOCGPGRP, uintptr(unsafe.Pointer(&fpgrp)))
 	if errno != 0 {
-		t.Fatalf("TIOCSPGRP failed with error code: %s", errno)
+		t.Fatalf("TIOCGPGRP failed with error code: %s", errno)
 	}
 
-	signal.Reset()
+	if fpgrp == 0 {
+		t.Fatalf("Foreground process group is zero")
+	}
+
+	defer func() {
+		signal.Ignore(syscall.SIGTTIN, syscall.SIGTTOU)
+		syscall.Ioctl(tty.Fd(), syscall.TIOCSPGRP, uintptr(unsafe.Pointer(&fpgrp)))
+		signal.Reset()
+	}()
+
+	ch1 := make(chan os.Signal, 1)
+	ch2 := make(chan bool)
+
+	signal.Notify(ch1, syscall.SIGTTIN, syscall.SIGTTOU)
+	defer signal.Stop(ch1)
+
+	cmd := create(t)
+
+	go func() {
+		cmd.proc.SysProcAttr = &syscall.SysProcAttr{
+			Ctty:       int(tty.Fd()),
+			Foreground: true,
+		}
+		cmd.Start()
+		cmd.Stop()
+		close(ch2)
+	}()
+
+	timer := time.NewTimer(30 * time.Second)
+	defer timer.Stop()
+	for {
+		select {
+		case sig := <-ch1:
+			t.Errorf("unexpected signal %v", sig)
+		case <-ch2:
+			// Success.
+			return
+		case <-timer.C:
+			t.Fatal("timed out waiting for child process")
+		}
+	}
 }
 
 // Test a couple of cases that SysProcAttr can't handle. Issue 29458.
diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go
index 46cbd75..18d1502 100644
--- a/src/syscall/exec_windows.go
+++ b/src/syscall/exec_windows.go
@@ -7,6 +7,7 @@
 package syscall
 
 import (
+	"runtime"
 	"sync"
 	"unicode/utf16"
 	"unsafe"
@@ -235,13 +236,15 @@
 }
 
 type SysProcAttr struct {
-	HideWindow        bool
-	CmdLine           string // used if non-empty, else the windows command line is built by escaping the arguments passed to StartProcess
-	CreationFlags     uint32
-	Token             Token               // if set, runs new process in the security context represented by the token
-	ProcessAttributes *SecurityAttributes // if set, applies these security attributes as the descriptor for the new process
-	ThreadAttributes  *SecurityAttributes // if set, applies these security attributes as the descriptor for the main thread of the new process
-	NoInheritHandles  bool                // if set, each inheritable handle in the calling process is not inherited by the new process
+	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
+	ProcessAttributes          *SecurityAttributes // if set, applies these security attributes as the descriptor for the new process
+	ThreadAttributes           *SecurityAttributes // if set, applies these security attributes as the descriptor for the main thread of the new process
+	NoInheritHandles           bool                // if set, each inheritable handle in the calling process is not inherited by the new process
+	AdditionalInheritedHandles []Handle            // a list of additional handles, already marked as inheritable, that will be inherited by the new process
+	ParentProcess              Handle              // if non-zero, the new process regards the process given by this handle as its parent process, and AdditionalInheritedHandles, if set, should exist in this parent process
 }
 
 var zeroProcAttr ProcAttr
@@ -310,46 +313,104 @@
 		}
 	}
 
-	// Acquire the fork lock so that no other threads
-	// create new fds that are not yet close-on-exec
-	// before we fork.
-	ForkLock.Lock()
-	defer ForkLock.Unlock()
+	var maj, min, build uint32
+	rtlGetNtVersionNumbers(&maj, &min, &build)
+	isWin7 := maj < 6 || (maj == 6 && min <= 1)
+	// NT kernel handles are divisible by 4, with the bottom 3 bits left as
+	// a tag. The fully set tag correlates with the types of handles we're
+	// concerned about here.  Except, the kernel will interpret some
+	// special handle values, like -1, -2, and so forth, so kernelbase.dll
+	// checks to see that those bottom three bits are checked, but that top
+	// bit is not checked.
+	isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 }
 
 	p, _ := GetCurrentProcess()
+	parentProcess := p
+	if sys.ParentProcess != 0 {
+		parentProcess = sys.ParentProcess
+	}
 	fd := make([]Handle, len(attr.Files))
 	for i := range attr.Files {
 		if attr.Files[i] > 0 {
-			err := DuplicateHandle(p, Handle(attr.Files[i]), p, &fd[i], 0, true, DUPLICATE_SAME_ACCESS)
+			destinationProcessHandle := parentProcess
+
+			// On Windows 7, console handles aren't real handles, and can only be duplicated
+			// into the current process, not a parent one, which amounts to the same thing.
+			if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) {
+				destinationProcessHandle = p
+			}
+
+			err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS)
 			if err != nil {
 				return 0, 0, err
 			}
-			defer CloseHandle(Handle(fd[i]))
+			defer DuplicateHandle(parentProcess, fd[i], 0, nil, 0, false, DUPLICATE_CLOSE_SOURCE)
 		}
 	}
-	si := new(StartupInfo)
+	si := new(_STARTUPINFOEXW)
+	si.ProcThreadAttributeList, err = newProcThreadAttributeList(2)
+	if err != nil {
+		return 0, 0, err
+	}
+	defer deleteProcThreadAttributeList(si.ProcThreadAttributeList)
 	si.Cb = uint32(unsafe.Sizeof(*si))
 	si.Flags = STARTF_USESTDHANDLES
 	if sys.HideWindow {
 		si.Flags |= STARTF_USESHOWWINDOW
 		si.ShowWindow = SW_HIDE
 	}
+	if sys.ParentProcess != 0 {
+		err = updateProcThreadAttribute(si.ProcThreadAttributeList, 0, _PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, unsafe.Pointer(&sys.ParentProcess), unsafe.Sizeof(sys.ParentProcess), nil, nil)
+		if err != nil {
+			return 0, 0, err
+		}
+	}
 	si.StdInput = fd[0]
 	si.StdOutput = fd[1]
 	si.StdErr = fd[2]
 
-	pi := new(ProcessInformation)
+	fd = append(fd, sys.AdditionalInheritedHandles...)
 
-	flags := sys.CreationFlags | CREATE_UNICODE_ENVIRONMENT
+	// On Windows 7, console handles aren't real handles, so don't pass them
+	// through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST.
+	for i := range fd {
+		if isLegacyWin7ConsoleHandle(fd[i]) {
+			fd[i] = 0
+		}
+	}
+
+	// The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST
+	// to treat the entire list as empty, so remove NULL handles.
+	j := 0
+	for i := range fd {
+		if fd[i] != 0 {
+			fd[j] = fd[i]
+			j++
+		}
+	}
+	fd = fd[:j]
+
+	// Do not accidentally inherit more than these handles.
+	if len(fd) > 0 {
+		err = updateProcThreadAttribute(si.ProcThreadAttributeList, 0, _PROC_THREAD_ATTRIBUTE_HANDLE_LIST, unsafe.Pointer(&fd[0]), uintptr(len(fd))*unsafe.Sizeof(fd[0]), nil, nil)
+		if err != nil {
+			return 0, 0, err
+		}
+	}
+
+	pi := new(ProcessInformation)
+	flags := sys.CreationFlags | CREATE_UNICODE_ENVIRONMENT | _EXTENDED_STARTUPINFO_PRESENT
 	if sys.Token != 0 {
-		err = CreateProcessAsUser(sys.Token, argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, !sys.NoInheritHandles, flags, createEnvBlock(attr.Env), dirp, si, pi)
+		err = CreateProcessAsUser(sys.Token, argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, len(fd) > 0 && !sys.NoInheritHandles, flags, createEnvBlock(attr.Env), dirp, &si.StartupInfo, pi)
 	} else {
-		err = CreateProcess(argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, !sys.NoInheritHandles, flags, createEnvBlock(attr.Env), dirp, si, pi)
+		err = CreateProcess(argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, len(fd) > 0 && !sys.NoInheritHandles, flags, createEnvBlock(attr.Env), dirp, &si.StartupInfo, pi)
 	}
 	if err != nil {
 		return 0, 0, err
 	}
 	defer CloseHandle(Handle(pi.Thread))
+	runtime.KeepAlive(fd)
+	runtime.KeepAlive(sys)
 
 	return int(pi.ProcessId), uintptr(pi.Process), nil
 }
diff --git a/src/syscall/exec_windows_test.go b/src/syscall/exec_windows_test.go
index eda1d36..8b8f330 100644
--- a/src/syscall/exec_windows_test.go
+++ b/src/syscall/exec_windows_test.go
@@ -5,8 +5,13 @@
 package syscall_test
 
 import (
+	"fmt"
+	"os"
+	"os/exec"
+	"path/filepath"
 	"syscall"
 	"testing"
+	"time"
 )
 
 func TestEscapeArg(t *testing.T) {
@@ -41,3 +46,70 @@
 		}
 	}
 }
+
+func TestChangingProcessParent(t *testing.T) {
+	if os.Getenv("GO_WANT_HELPER_PROCESS") == "parent" {
+		// in parent process
+
+		// Parent does nothing. It is just used as a parent of a child process.
+		time.Sleep(time.Minute)
+		os.Exit(0)
+	}
+
+	if os.Getenv("GO_WANT_HELPER_PROCESS") == "child" {
+		// in child process
+		dumpPath := os.Getenv("GO_WANT_HELPER_PROCESS_FILE")
+		if dumpPath == "" {
+			fmt.Fprintf(os.Stderr, "Dump file path cannot be blank.")
+			os.Exit(1)
+		}
+		err := os.WriteFile(dumpPath, []byte(fmt.Sprintf("%d", os.Getppid())), 0644)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "Error writing dump file: %v", err)
+			os.Exit(2)
+		}
+		os.Exit(0)
+	}
+
+	// run parent process
+
+	parent := exec.Command(os.Args[0], "-test.run=TestChangingProcessParent")
+	parent.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=parent")
+	err := parent.Start()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer func() {
+		parent.Process.Kill()
+		parent.Wait()
+	}()
+
+	// run child process
+
+	const _PROCESS_CREATE_PROCESS = 0x0080
+	const _PROCESS_DUP_HANDLE = 0x0040
+	childDumpPath := filepath.Join(t.TempDir(), "ppid.txt")
+	ph, err := syscall.OpenProcess(_PROCESS_CREATE_PROCESS|_PROCESS_DUP_HANDLE|syscall.PROCESS_QUERY_INFORMATION,
+		false, uint32(parent.Process.Pid))
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer syscall.CloseHandle(ph)
+
+	child := exec.Command(os.Args[0], "-test.run=TestChangingProcessParent")
+	child.Env = append(os.Environ(),
+		"GO_WANT_HELPER_PROCESS=child",
+		"GO_WANT_HELPER_PROCESS_FILE="+childDumpPath)
+	child.SysProcAttr = &syscall.SysProcAttr{ParentProcess: ph}
+	childOutput, err := child.CombinedOutput()
+	if err != nil {
+		t.Errorf("child failed: %v: %v", err, string(childOutput))
+	}
+	childOutput, err = os.ReadFile(childDumpPath)
+	if err != nil {
+		t.Fatalf("reading child output failed: %v", err)
+	}
+	if got, want := string(childOutput), fmt.Sprintf("%d", parent.Process.Pid); got != want {
+		t.Fatalf("child output: want %q, got %q", want, got)
+	}
+}
diff --git a/src/syscall/export_test.go b/src/syscall/export_test.go
deleted file mode 100644
index 55c09e6..0000000
--- a/src/syscall/export_test.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-
-var Itoa = itoa
diff --git a/src/syscall/export_unix_test.go b/src/syscall/export_unix_test.go
index 4c3d0f6..2d2c676 100644
--- a/src/syscall/export_unix_test.go
+++ b/src/syscall/export_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || linux || netbsd || openbsd
 // +build dragonfly freebsd linux netbsd openbsd
 
 package syscall
diff --git a/src/syscall/export_windows_test.go b/src/syscall/export_windows_test.go
new file mode 100644
index 0000000..a72a1ee
--- /dev/null
+++ b/src/syscall/export_windows_test.go
@@ -0,0 +1,11 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+var NewProcThreadAttributeList = newProcThreadAttributeList
+var UpdateProcThreadAttribute = updateProcThreadAttribute
+var DeleteProcThreadAttributeList = deleteProcThreadAttributeList
+
+const PROC_THREAD_ATTRIBUTE_HANDLE_LIST = _PROC_THREAD_ATTRIBUTE_HANDLE_LIST
diff --git a/src/syscall/flock.go b/src/syscall/flock.go
index 568efca..3b43b6a 100644
--- a/src/syscall/flock.go
+++ b/src/syscall/flock.go
@@ -1,3 +1,4 @@
+//go:build linux || freebsd || openbsd || netbsd || dragonfly
 // +build linux freebsd openbsd netbsd dragonfly
 
 // Copyright 2014 The Go Authors. All rights reserved.
diff --git a/src/syscall/flock_linux_32bit.go b/src/syscall/flock_linux_32bit.go
index e11aed6..2f32774 100644
--- a/src/syscall/flock_linux_32bit.go
+++ b/src/syscall/flock_linux_32bit.go
@@ -5,6 +5,7 @@
 // If you change the build tags here, see
 // internal/syscall/unix/fcntl_linux_32bit.go.
 
+//go:build (linux && 386) || (linux && arm) || (linux && mips) || (linux && mipsle)
 // +build linux,386 linux,arm linux,mips linux,mipsle
 
 package syscall
diff --git a/src/syscall/forkpipe.go b/src/syscall/forkpipe.go
index d9999cb..79cbdf4 100644
--- a/src/syscall/forkpipe.go
+++ b/src/syscall/forkpipe.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build aix darwin dragonfly solaris
+//go:build aix || darwin || solaris
+// +build aix darwin solaris
 
 package syscall
 
diff --git a/src/syscall/forkpipe2.go b/src/syscall/forkpipe2.go
index c9a0c49..e57240c 100644
--- a/src/syscall/forkpipe2.go
+++ b/src/syscall/forkpipe2.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build freebsd netbsd openbsd
+//go:build dragonfly || freebsd || netbsd || openbsd
+// +build dragonfly freebsd netbsd openbsd
 
 package syscall
 
diff --git a/src/syscall/fs_js.go b/src/syscall/fs_js.go
index 673feea..0170516 100644
--- a/src/syscall/fs_js.go
+++ b/src/syscall/fs_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package syscall
diff --git a/src/syscall/getdirentries_test.go b/src/syscall/getdirentries_test.go
index 66bb8ac..814e656 100644
--- a/src/syscall/getdirentries_test.go
+++ b/src/syscall/getdirentries_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || freebsd || netbsd || openbsd
 // +build darwin freebsd netbsd openbsd
 
 package syscall_test
@@ -28,11 +29,7 @@
 	if count > 100 && testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" {
 		t.Skip("skipping in -short mode")
 	}
-	d, err := os.MkdirTemp("", "getdirentries-test")
-	if err != nil {
-		t.Fatalf("Tempdir: %v", err)
-	}
-	defer os.RemoveAll(d)
+	d := t.TempDir()
 	var names []string
 	for i := 0; i < count; i++ {
 		names = append(names, fmt.Sprintf("file%03d", i))
diff --git a/src/syscall/mkall.sh b/src/syscall/mkall.sh
index d1e28ef..dffb528 100755
--- a/src/syscall/mkall.sh
+++ b/src/syscall/mkall.sh
@@ -285,11 +285,12 @@
 openbsd_386)
 	GOOSARCH_in="syscall_openbsd1.go syscall_openbsd_$GOARCH.go"
 	mkerrors="$mkerrors -m32"
-	mksyscall="./mksyscall.pl -l32 -openbsd"
+	mksyscall="./mksyscall.pl -l32 -openbsd -libc"
 	mksysctl="./mksysctl_openbsd.pl"
 	zsysctl="zsysctl_openbsd.go"
 	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	mkasm="go run mkasm.go"
 	;;
 openbsd_amd64)
 	GOOSARCH_in="syscall_openbsd_libc.go syscall_openbsd_$GOARCH.go"
@@ -302,15 +303,16 @@
 	mkasm="go run mkasm.go"
 	;;
 openbsd_arm)
-	GOOSARCH_in="syscall_openbsd1.go syscall_openbsd_$GOARCH.go"
+	GOOSARCH_in="syscall_openbsd_libc.go syscall_openbsd_$GOARCH.go"
 	mkerrors="$mkerrors"
-	mksyscall="./mksyscall.pl -l32 -openbsd -arm"
+	mksyscall="./mksyscall.pl -l32 -openbsd -arm -libc"
 	mksysctl="./mksysctl_openbsd.pl"
 	zsysctl="zsysctl_openbsd.go"
 	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
 	# Let the type of C char be signed to make the bare syscall
 	# API consistent between platforms.
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+	mkasm="go run mkasm.go"
 	;;
 openbsd_arm64)
 	GOOSARCH_in="syscall_openbsd_libc.go syscall_openbsd_$GOARCH.go"
diff --git a/src/syscall/mkasm.go b/src/syscall/mkasm.go
index 2ebaf8d..e0ec466 100644
--- a/src/syscall/mkasm.go
+++ b/src/syscall/mkasm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // mkasm.go generates assembly trampolines to call library routines from Go.
diff --git a/src/syscall/mkpost.go b/src/syscall/mkpost.go
index ef89128..94e8d92 100644
--- a/src/syscall/mkpost.go
+++ b/src/syscall/mkpost.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // mkpost processes the output of cgo -godefs to
diff --git a/src/syscall/mksyscall.pl b/src/syscall/mksyscall.pl
index 67e8d1d..758948b 100755
--- a/src/syscall/mksyscall.pl
+++ b/src/syscall/mksyscall.pl
@@ -32,6 +32,8 @@
 my $arm = 0; # 64-bit value should use (even, odd)-pair
 my $libc = 0;
 my $tags = "";  # build tags
+my $newtags = ""; # new style build tags
+my $extraimports = "";
 
 if($ARGV[0] eq "-b32") {
 	$_32bit = "big-endian";
@@ -80,6 +82,10 @@
 	exit 1;
 }
 
+if($libc) {
+	$extraimports = 'import "internal/abi"';
+}
+
 sub parseparamlist($) {
 	my ($list) = @_;
 	$list =~ s/^\s*//;
@@ -131,7 +137,7 @@
 	# without reading the header.
 	$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
 
-	if (($darwin || ($openbsd && $libc)) && $func eq "ptrace") {
+	if (($darwin && $func eq "ptrace1") || (($openbsd && $libc) && $func eq "ptrace")) {
 		# The ptrace function is called from forkAndExecInChild where stack
 		# growth is forbidden.
 		$text .= "//go:nosplit\n"
@@ -185,6 +191,10 @@
 			if (!$libc) {
 				push @args, "0";
 			}
+			if($libc && $arm && @args % 2) {
+				# arm abi specifies 64 bit argument must be 64 bit aligned.
+				push @args, "0"
+			}
 			if($_32bit eq "big-endian") {
 				push @args, "uintptr($name>>32)", "uintptr($name)";
 			} elsif($_32bit eq "little-endian") {
@@ -276,7 +286,7 @@
 			$sysname = substr $sysname, 4;
 			$funcname = "libc_$sysname";
 		}
-		$sysname = "funcPC(${funcname}_trampoline)";
+		$sysname = "abi.FuncPCABI0(${funcname}_trampoline)";
 	}
 
 	# Actual call.
@@ -350,10 +360,7 @@
 		if (not exists $trampolines{$funcname}) {
 			$trampolines{$funcname} = 1;
 			# The assembly trampoline that jumps to the libc routine.
-			$text .= "func ${funcname}_trampoline()\n";
-			# Map syscall.funcname to just plain funcname.
-			# (The jump to this function is in the assembly trampoline, generated by mkasm.go.)
-			$text .= "//go:linkname $funcname $funcname\n";
+			$text .= "func ${funcname}_trampoline()\n\n";
 			# Tell the linker that funcname can be found in libSystem using varname without the libc_ prefix.
 			my $basename = substr $funcname, 5;
 			my $libc = "libc.so";
@@ -372,15 +379,20 @@
 	exit 1;
 }
 
+# TODO: this assumes tags are just simply comma separated. For now this is all the uses.
+$newtags = $tags =~ s/,/ && /r;
+
 print <<EOF;
 // $cmdline
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build $newtags
 // +build $tags
 
 package syscall
 
 import "unsafe"
+$extraimports
 
 $text
 EOF
diff --git a/src/syscall/mksyscall_libc.pl b/src/syscall/mksyscall_libc.pl
index 5ceedc8..631a07c 100755
--- a/src/syscall/mksyscall_libc.pl
+++ b/src/syscall/mksyscall_libc.pl
@@ -23,6 +23,7 @@
 my $errors = 0;
 my $_32bit = "";
 my $tags = "";  # build tags
+my $newtags = ""; # new style build tags
 my $aix = 0;
 my $solaris = 0;
 
@@ -300,10 +301,14 @@
 	exit 1;
 }
 
+# TODO: this assumes tags are just simply comma separated. For now this is all the uses.
+$newtags = $tags =~ s/,/ && /r;
+
 print <<EOF;
 // $cmdline
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build $newtags
 // +build $tags
 
 package $package
diff --git a/src/syscall/mksyscall_windows.go b/src/syscall/mksyscall_windows.go
index 240254b..d8e8a71 100644
--- a/src/syscall/mksyscall_windows.go
+++ b/src/syscall/mksyscall_windows.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // mksyscall_windows wraps golang.org/x/sys/windows/mkwinsyscall.
diff --git a/src/syscall/mmap_unix_test.go b/src/syscall/mmap_unix_test.go
index d0b3644..e3909f1 100644
--- a/src/syscall/mmap_unix_test.go
+++ b/src/syscall/mmap_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd
 // +build aix darwin dragonfly freebsd linux netbsd openbsd
 
 package syscall_test
diff --git a/src/syscall/msan.go b/src/syscall/msan.go
index baaad6d..89fb75f 100644
--- a/src/syscall/msan.go
+++ b/src/syscall/msan.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build msan
 // +build msan
 
 package syscall
diff --git a/src/syscall/msan0.go b/src/syscall/msan0.go
index ff10be9..8509702 100644
--- a/src/syscall/msan0.go
+++ b/src/syscall/msan0.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !msan
 // +build !msan
 
 package syscall
diff --git a/src/syscall/net_js.go b/src/syscall/net_js.go
index 25f171b..ed46202 100644
--- a/src/syscall/net_js.go
+++ b/src/syscall/net_js.go
@@ -5,6 +5,7 @@
 // js/wasm uses fake networking directly implemented in the net package.
 // This file only exists to make the compiler happy.
 
+//go:build js && wasm
 // +build js,wasm
 
 package syscall
diff --git a/src/syscall/ptrace_darwin.go b/src/syscall/ptrace_darwin.go
index a873d82..b968c7c 100644
--- a/src/syscall/ptrace_darwin.go
+++ b/src/syscall/ptrace_darwin.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !ios
 // +build !ios
 
 package syscall
diff --git a/src/syscall/route_bsd.go b/src/syscall/route_bsd.go
index b364eea..e9321a4 100644
--- a/src/syscall/route_bsd.go
+++ b/src/syscall/route_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 package syscall
diff --git a/src/syscall/route_freebsd_32bit.go b/src/syscall/route_freebsd_32bit.go
index aed8682..412833a 100644
--- a/src/syscall/route_freebsd_32bit.go
+++ b/src/syscall/route_freebsd_32bit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (freebsd && 386) || (freebsd && arm)
 // +build freebsd,386 freebsd,arm
 
 package syscall
diff --git a/src/syscall/route_freebsd_64bit.go b/src/syscall/route_freebsd_64bit.go
index e70ba3d..5300bed 100644
--- a/src/syscall/route_freebsd_64bit.go
+++ b/src/syscall/route_freebsd_64bit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (freebsd && amd64) || (freebsd && arm64)
 // +build freebsd,amd64 freebsd,arm64
 
 package syscall
diff --git a/src/syscall/setuidgid_32_linux.go b/src/syscall/setuidgid_32_linux.go
index b0b7f61..64897fe 100644
--- a/src/syscall/setuidgid_32_linux.go
+++ b/src/syscall/setuidgid_32_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (386 || arm)
 // +build linux
 // +build 386 arm
 
diff --git a/src/syscall/setuidgid_linux.go b/src/syscall/setuidgid_linux.go
index 38c83c9..3b36f66 100644
--- a/src/syscall/setuidgid_linux.go
+++ b/src/syscall/setuidgid_linux.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux
-// +build !386,!arm
+//go:build linux && !386 && !arm
+// +build linux,!386,!arm
 
 package syscall
 
diff --git a/src/syscall/sockcmsg_unix.go b/src/syscall/sockcmsg_unix.go
index 1ff97a5..99913b9 100644
--- a/src/syscall/sockcmsg_unix.go
+++ b/src/syscall/sockcmsg_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 // Socket control messages
diff --git a/src/syscall/sockcmsg_unix_other.go b/src/syscall/sockcmsg_unix_other.go
index 40f0314..bd8dcfa 100644
--- a/src/syscall/sockcmsg_unix_other.go
+++ b/src/syscall/sockcmsg_unix_other.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin freebsd linux netbsd openbsd solaris
 
 package syscall
diff --git a/src/syscall/str.go b/src/syscall/str.go
deleted file mode 100644
index 2ddf04b..0000000
--- a/src/syscall/str.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-
-func itoa(val int) string { // do it here rather than with fmt to avoid dependency
-	if val < 0 {
-		return "-" + uitoa(uint(-val))
-	}
-	return uitoa(uint(val))
-}
-
-func uitoa(val uint) string {
-	var buf [32]byte // big enough for int64
-	i := len(buf) - 1
-	for val >= 10 {
-		buf[i] = byte(val%10 + '0')
-		i--
-		val /= 10
-	}
-	buf[i] = byte(val + '0')
-	return string(buf[i:])
-}
diff --git a/src/syscall/syscall_bsd.go b/src/syscall/syscall_bsd.go
index 1c7ec58..595e705 100644
--- a/src/syscall/syscall_bsd.go
+++ b/src/syscall/syscall_bsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 // BSD system call wrappers shared by *BSD based systems
diff --git a/src/syscall/syscall_bsd_test.go b/src/syscall/syscall_bsd_test.go
index f2bc3f5..2d8a8cb 100644
--- a/src/syscall/syscall_bsd_test.go
+++ b/src/syscall/syscall_bsd_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || openbsd
 // +build darwin dragonfly freebsd openbsd
 
 package syscall_test
diff --git a/src/syscall/syscall_darwin.go b/src/syscall/syscall_darwin.go
index afdadbf..a4fe4f1 100644
--- a/src/syscall/syscall_darwin.go
+++ b/src/syscall/syscall_darwin.go
@@ -12,7 +12,10 @@
 
 package syscall
 
-import "unsafe"
+import (
+	"internal/abi"
+	"unsafe"
+)
 
 type SockaddrDatalink struct {
 	Len    uint8
@@ -105,7 +108,7 @@
 		_p0 = unsafe.Pointer(&buf[0])
 		bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
 	}
-	r0, _, e1 := syscall(funcPC(libc_getfsstat_trampoline), uintptr(_p0), bufsize, uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getfsstat_trampoline), uintptr(_p0), bufsize, uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = e1
@@ -115,7 +118,6 @@
 
 func libc_getfsstat_trampoline()
 
-//go:linkname libc_getfsstat libc_getfsstat
 //go:cgo_import_dynamic libc_getfsstat getfsstat "/usr/lib/libSystem.B.dylib"
 
 func setattrlistTimes(path string, times []Timespec) error {
@@ -132,7 +134,7 @@
 	attributes := [2]Timespec{times[1], times[0]}
 	const options = 0
 	_, _, e1 := syscall6(
-		funcPC(libc_setattrlist_trampoline),
+		abi.FuncPCABI0(libc_setattrlist_trampoline),
 		uintptr(unsafe.Pointer(_p0)),
 		uintptr(unsafe.Pointer(&attrList)),
 		uintptr(unsafe.Pointer(&attributes)),
@@ -148,7 +150,6 @@
 
 func libc_setattrlist_trampoline()
 
-//go:linkname libc_setattrlist libc_setattrlist
 //go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib"
 
 func utimensat(dirfd int, path string, times *[2]Timespec, flag int) error {
@@ -266,7 +267,7 @@
 }
 
 func fdopendir(fd int) (dir uintptr, err error) {
-	r0, _, e1 := syscallPtr(funcPC(libc_fdopendir_trampoline), uintptr(fd), 0, 0)
+	r0, _, e1 := syscallPtr(abi.FuncPCABI0(libc_fdopendir_trampoline), uintptr(fd), 0, 0)
 	dir = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -276,11 +277,10 @@
 
 func libc_fdopendir_trampoline()
 
-//go:linkname libc_fdopendir libc_fdopendir
 //go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
 
 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -289,7 +289,7 @@
 }
 
 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -379,10 +379,3 @@
 func rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
 func rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 func syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
-
-// Find the entry point for f. See comments in runtime/proc.go for the
-// function of the same name.
-//go:nosplit
-func funcPC(f func()) uintptr {
-	return **(**uintptr)(unsafe.Pointer(&f))
-}
diff --git a/src/syscall/syscall_darwin_amd64.go b/src/syscall/syscall_darwin_amd64.go
index 22ddb78..ef3c199 100644
--- a/src/syscall/syscall_darwin_amd64.go
+++ b/src/syscall/syscall_darwin_amd64.go
@@ -4,7 +4,10 @@
 
 package syscall
 
-import "unsafe"
+import (
+	"internal/abi"
+	"unsafe"
+)
 
 func setTimespec(sec, nsec int64) Timespec {
 	return Timespec{Sec: sec, Nsec: nsec}
@@ -44,7 +47,7 @@
 func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
 	var length = uint64(count)
 
-	_, _, e1 := syscall6(funcPC(libc_sendfile_trampoline), uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sendfile_trampoline), uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0)
 
 	written = int(length)
 
@@ -56,7 +59,6 @@
 
 func libc_sendfile_trampoline()
 
-//go:linkname libc_sendfile libc_sendfile
 //go:cgo_import_dynamic libc_sendfile sendfile "/usr/lib/libSystem.B.dylib"
 
 // Implemented in the runtime package (runtime/sys_darwin_64.go)
diff --git a/src/syscall/syscall_darwin_arm64.go b/src/syscall/syscall_darwin_arm64.go
index ecb9fff..cea4277 100644
--- a/src/syscall/syscall_darwin_arm64.go
+++ b/src/syscall/syscall_darwin_arm64.go
@@ -4,7 +4,10 @@
 
 package syscall
 
-import "unsafe"
+import (
+	"internal/abi"
+	"unsafe"
+)
 
 func setTimespec(sec, nsec int64) Timespec {
 	return Timespec{Sec: sec, Nsec: nsec}
@@ -44,7 +47,7 @@
 func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
 	var length = uint64(count)
 
-	_, _, e1 := syscall6(funcPC(libc_sendfile_trampoline), uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sendfile_trampoline), uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0)
 
 	written = int(length)
 
@@ -56,7 +59,6 @@
 
 func libc_sendfile_trampoline()
 
-//go:linkname libc_sendfile libc_sendfile
 //go:cgo_import_dynamic libc_sendfile sendfile "/usr/lib/libSystem.B.dylib"
 
 // Implemented in the runtime package (runtime/sys_darwin_64.go)
diff --git a/src/syscall/syscall_dragonfly.go b/src/syscall/syscall_dragonfly.go
index 0988fe4..b01a4ad 100644
--- a/src/syscall/syscall_dragonfly.go
+++ b/src/syscall/syscall_dragonfly.go
@@ -100,6 +100,19 @@
 	return
 }
 
+//sysnb	pipe2(p *[2]_C_int, flags int) (r int, w int, err error)
+
+func Pipe2(p []int, flags int) (err error) {
+	if len(p) != 2 {
+		return EINVAL
+	}
+	var pp [2]_C_int
+	// pipe2 on dragonfly takes an fds array as an argument, but still
+	// returns the file descriptors.
+	p[0], p[1], err = pipe2(&pp, flags)
+	return err
+}
+
 //sys	extpread(fd int, p []byte, flags int, offset int64) (n int, err error)
 func Pread(fd int, p []byte, offset int64) (n int, err error) {
 	return extpread(fd, p, 0, offset)
diff --git a/src/syscall/syscall_dup2_linux.go b/src/syscall/syscall_dup2_linux.go
index f03a923..351a96e 100644
--- a/src/syscall/syscall_dup2_linux.go
+++ b/src/syscall/syscall_dup2_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !android && (386 || amd64 || arm || mips || mipsle || mips64 || mips64le || ppc64 || ppc64le || s390x)
 // +build !android
 // +build 386 amd64 arm mips mipsle mips64 mips64le ppc64 ppc64le s390x
 
diff --git a/src/syscall/syscall_dup3_linux.go b/src/syscall/syscall_dup3_linux.go
index 1ebdcb2..66ec67b 100644
--- a/src/syscall/syscall_dup3_linux.go
+++ b/src/syscall/syscall_dup3_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build android || arm64 || riscv64
 // +build android arm64 riscv64
 
 package syscall
diff --git a/src/syscall/syscall_freebsd_test.go b/src/syscall/syscall_freebsd_test.go
index 3ccfe5d..89c7959 100644
--- a/src/syscall/syscall_freebsd_test.go
+++ b/src/syscall/syscall_freebsd_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build freebsd
 // +build freebsd
 
 package syscall_test
diff --git a/src/syscall/syscall_illumos.go b/src/syscall/syscall_illumos.go
index d70a436..ef95fe5 100644
--- a/src/syscall/syscall_illumos.go
+++ b/src/syscall/syscall_illumos.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build illumos
 // +build illumos
 
 // Illumos system calls not present on Solaris.
diff --git a/src/syscall/syscall_js.go b/src/syscall/syscall_js.go
index 0ab8c3f..ed70d62 100644
--- a/src/syscall/syscall_js.go
+++ b/src/syscall/syscall_js.go
@@ -2,11 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package syscall
 
 import (
+	"internal/itoa"
 	"internal/oserror"
 	"sync"
 	"unsafe"
@@ -59,7 +61,7 @@
 			return s
 		}
 	}
-	return "errno " + itoa(int(e))
+	return "errno " + itoa.Itoa(int(e))
 }
 
 func (e Errno) Is(target error) bool {
@@ -105,7 +107,7 @@
 			return str
 		}
 	}
-	return "signal " + itoa(int(s))
+	return "signal " + itoa.Itoa(int(s))
 }
 
 var signals = [...]string{}
diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go
index 3041f6f..dfce3d0 100644
--- a/src/syscall/syscall_linux.go
+++ b/src/syscall/syscall_linux.go
@@ -11,7 +11,10 @@
 
 package syscall
 
-import "unsafe"
+import (
+	"internal/itoa"
+	"unsafe"
+)
 
 func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
 
@@ -225,7 +228,7 @@
 func Futimes(fd int, tv []Timeval) (err error) {
 	// Believe it or not, this is the best we can do on Linux
 	// (and is what glibc does).
-	return Utimes("/proc/self/fd/"+itoa(fd), tv)
+	return Utimes("/proc/self/fd/"+itoa.Itoa(fd), tv)
 }
 
 const ImplementsGetwd = true
@@ -550,7 +553,11 @@
 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
 	var rsa RawSockaddrAny
 	var len _Socklen = SizeofSockaddrAny
-	nfd, err = accept(fd, &rsa, &len)
+	// Try accept4 first for Android, then try accept for kernel older than 2.6.28
+	nfd, err = accept4(fd, &rsa, &len, 0)
+	if err == ENOSYS {
+		nfd, err = accept(fd, &rsa, &len)
+	}
 	if err != nil {
 		return
 	}
diff --git a/src/syscall/syscall_linux_386.go b/src/syscall/syscall_linux_386.go
index ed52647..0db0374 100644
--- a/src/syscall/syscall_linux_386.go
+++ b/src/syscall/syscall_linux_386.go
@@ -387,6 +387,4 @@
 	cmsg.Len = uint32(length)
 }
 
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
-	panic("not implemented")
-}
+func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_arm.go b/src/syscall/syscall_linux_arm.go
index 4a3729f..e887cf7 100644
--- a/src/syscall/syscall_linux_arm.go
+++ b/src/syscall/syscall_linux_arm.go
@@ -236,6 +236,4 @@
 	cmsg.Len = uint32(length)
 }
 
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
-	panic("not implemented")
-}
+func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_mips64x.go b/src/syscall/syscall_linux_mips64x.go
index ab25b7b..5feb03e 100644
--- a/src/syscall/syscall_linux_mips64x.go
+++ b/src/syscall/syscall_linux_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips64 || mips64le)
 // +build linux
 // +build mips64 mips64le
 
@@ -213,6 +214,4 @@
 	cmsg.Len = uint64(length)
 }
 
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
-	panic("not implemented")
-}
+func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_mipsx.go b/src/syscall/syscall_linux_mipsx.go
index 377946f..39104d7 100644
--- a/src/syscall/syscall_linux_mipsx.go
+++ b/src/syscall/syscall_linux_mipsx.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips || mipsle)
 // +build linux
 // +build mips mipsle
 
@@ -223,6 +224,4 @@
 	cmsg.Len = uint32(length)
 }
 
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
-	panic("not implemented")
-}
+func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_ppc64x.go b/src/syscall/syscall_linux_ppc64x.go
index 45bf667..495ae29 100644
--- a/src/syscall/syscall_linux_ppc64x.go
+++ b/src/syscall/syscall_linux_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (ppc64 || ppc64le)
 // +build linux
 // +build ppc64 ppc64le
 
diff --git a/src/syscall/syscall_linux_test.go b/src/syscall/syscall_linux_test.go
index adeb7c9..442dc9f 100644
--- a/src/syscall/syscall_linux_test.go
+++ b/src/syscall/syscall_linux_test.go
@@ -14,6 +14,7 @@
 	"os/signal"
 	"path/filepath"
 	"runtime"
+	"sort"
 	"strconv"
 	"strings"
 	"syscall"
@@ -583,11 +584,23 @@
 				// "Pid:\t".
 			}
 			if strings.HasPrefix(line, filter) {
-				if line != expected {
-					return fmt.Errorf("%q got:%q want:%q (bad) [pid=%d file:'%s' %v]\n", tf, line, expected, pid, string(d), expectedProc)
+				if line == expected {
+					foundAThread = true
+					break
 				}
-				foundAThread = true
-				break
+				if filter == "Groups:" && strings.HasPrefix(line, "Groups:\t") {
+					// https://github.com/golang/go/issues/46145
+					// Containers don't reliably output this line in sorted order so manually sort and compare that.
+					a := strings.Split(line[8:], " ")
+					sort.Strings(a)
+					got := strings.Join(a, " ")
+					if got == expected[8:] {
+						foundAThread = true
+						break
+					}
+
+				}
+				return fmt.Errorf("%q got:%q want:%q (bad) [pid=%d file:'%s' %v]\n", tf, line, expected, pid, string(d), expectedProc)
 			}
 		}
 	}
diff --git a/src/syscall/syscall_openbsd1.go b/src/syscall/syscall_openbsd1.go
index 2c7d0f8..15870ce 100644
--- a/src/syscall/syscall_openbsd1.go
+++ b/src/syscall/syscall_openbsd1.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build openbsd,!amd64,!arm64
+//go:build openbsd && mips64
+// +build openbsd,mips64
 
 package syscall
 
diff --git a/src/syscall/syscall_openbsd_libc.go b/src/syscall/syscall_openbsd_libc.go
index 042615b..e67ee4e 100644
--- a/src/syscall/syscall_openbsd_libc.go
+++ b/src/syscall/syscall_openbsd_libc.go
@@ -2,11 +2,14 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build openbsd,amd64 openbsd,arm64
+//go:build openbsd && !mips64
+// +build openbsd,!mips64
 
 package syscall
 
-import "unsafe"
+import (
+	"internal/abi"
+)
 
 func init() {
 	execveOpenBSD = execve
@@ -15,23 +18,23 @@
 //sys directSyscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr) (ret uintptr, err error) = SYS_syscall
 
 func syscallInternal(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
-	return syscall6X(funcPC(libc_syscall_trampoline), trap, a1, a2, a3, 0, 0)
+	return syscall6X(abi.FuncPCABI0(libc_syscall_trampoline), trap, a1, a2, a3, 0, 0)
 }
 
 func syscall6Internal(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
-	return syscall10X(funcPC(libc_syscall_trampoline), trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
+	return syscall10X(abi.FuncPCABI0(libc_syscall_trampoline), trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
 }
 
 func rawSyscallInternal(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
-	return rawSyscall6X(funcPC(libc_syscall_trampoline), trap, a1, a2, a3, 0, 0)
+	return rawSyscall6X(abi.FuncPCABI0(libc_syscall_trampoline), trap, a1, a2, a3, 0, 0)
 }
 
 func rawSyscall6Internal(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
-	return rawSyscall10X(funcPC(libc_syscall_trampoline), trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
+	return rawSyscall10X(abi.FuncPCABI0(libc_syscall_trampoline), trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
 }
 
 func syscall9Internal(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) {
-	return rawSyscall10X(funcPC(libc_syscall_trampoline), trap, a1, a2, a3, a4, a5, a6, a7, a8, a9)
+	return rawSyscall10X(abi.FuncPCABI0(libc_syscall_trampoline), trap, a1, a2, a3, a4, a5, a6, a7, a8, a9)
 }
 
 // Implemented in the runtime package (runtime/sys_openbsd3.go)
@@ -53,13 +56,6 @@
 	return syscall10X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, 0)
 }
 
-// Find the entry point for f. See comments in runtime/proc.go for the
-// function of the same name.
-//go:nosplit
-func funcPC(f func()) uintptr {
-	return **(**uintptr)(unsafe.Pointer(&f))
-}
-
 //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	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_lseek
diff --git a/src/syscall/syscall_ptrace_test.go b/src/syscall/syscall_ptrace_test.go
index 6b7f54d..45729d9 100644
--- a/src/syscall/syscall_ptrace_test.go
+++ b/src/syscall/syscall_ptrace_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
 // +build darwin dragonfly freebsd linux netbsd openbsd
 
 package syscall_test
diff --git a/src/syscall/syscall_test.go b/src/syscall/syscall_test.go
index 5390f8a..b2b9463 100644
--- a/src/syscall/syscall_test.go
+++ b/src/syscall/syscall_test.go
@@ -5,7 +5,6 @@
 package syscall_test
 
 import (
-	"fmt"
 	"internal/testenv"
 	"os"
 	"runtime"
@@ -33,22 +32,6 @@
 	testSetGetenv(t, "TESTENV", "")
 }
 
-func TestItoa(t *testing.T) {
-	// Make most negative integer: 0x8000...
-	i := 1
-	for i<<1 != 0 {
-		i <<= 1
-	}
-	if i >= 0 {
-		t.Fatal("bad math")
-	}
-	s := syscall.Itoa(i)
-	f := fmt.Sprint(i)
-	if s != f {
-		t.Fatalf("itoa(%d) = %s, want %s", i, s, f)
-	}
-}
-
 // Check that permuting child process fds doesn't interfere with
 // reporting of fork/exec status. See Issue 14979.
 func TestExecErrPermutedFds(t *testing.T) {
diff --git a/src/syscall/syscall_unix.go b/src/syscall/syscall_unix.go
index 786ad34..5b405b9 100644
--- a/src/syscall/syscall_unix.go
+++ b/src/syscall/syscall_unix.go
@@ -2,11 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package syscall
 
 import (
+	"internal/itoa"
 	"internal/oserror"
 	"internal/race"
 	"internal/unsafeheader"
@@ -120,7 +122,7 @@
 			return s
 		}
 	}
-	return "errno " + itoa(int(e))
+	return "errno " + itoa.Itoa(int(e))
 }
 
 func (e Errno) Is(target error) bool {
@@ -180,7 +182,7 @@
 			return str
 		}
 	}
-	return "signal " + itoa(int(s))
+	return "signal " + itoa.Itoa(int(s))
 }
 
 func Read(fd int, p []byte) (n int, err error) {
diff --git a/src/syscall/syscall_unix_test.go b/src/syscall/syscall_unix_test.go
index 7e6a8c9..af0bc85 100644
--- a/src/syscall/syscall_unix_test.go
+++ b/src/syscall/syscall_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package syscall_test
@@ -78,16 +79,12 @@
 	}
 	if os.Getenv("GO_WANT_HELPER_PROCESS") == "" {
 		// parent
-		tempDir, err := os.MkdirTemp("", "TestFcntlFlock")
-		if err != nil {
-			t.Fatalf("Failed to create temp dir: %v", err)
-		}
+		tempDir := t.TempDir()
 		name := filepath.Join(tempDir, "TestFcntlFlock")
 		fd, err := syscall.Open(name, syscall.O_CREAT|syscall.O_RDWR|syscall.O_CLOEXEC, 0)
 		if err != nil {
 			t.Fatalf("Open failed: %v", err)
 		}
-		defer os.RemoveAll(tempDir)
 		defer syscall.Close(fd)
 		if err := syscall.Ftruncate(fd, 1<<20); err != nil {
 			t.Fatalf("Ftruncate(1<<20) failed: %v", err)
@@ -156,18 +153,12 @@
 
 	}
 
-	tempDir, err := os.MkdirTemp("", "TestPassFD")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tempDir)
+	tempDir := t.TempDir()
 
 	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])
 	writeFile := os.NewFile(uintptr(fds[0]), "child-writes")
 	readFile := os.NewFile(uintptr(fds[1]), "parent-reads")
 	defer writeFile.Close()
diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go
index 69cef52..660179a 100644
--- a/src/syscall/syscall_windows.go
+++ b/src/syscall/syscall_windows.go
@@ -8,6 +8,7 @@
 
 import (
 	errorspkg "errors"
+	"internal/itoa"
 	"internal/oserror"
 	"internal/race"
 	"internal/unsafeheader"
@@ -132,7 +133,7 @@
 	if err != nil {
 		n, err = formatMessage(flags, 0, uint32(e), 0, b, nil)
 		if err != nil {
-			return "winapi error #" + itoa(int(e))
+			return "winapi error #" + itoa.Itoa(int(e))
 		}
 	}
 	// trim terminating \r and \n
@@ -173,6 +174,9 @@
 // NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention.
 // This is useful when interoperating with Windows code requiring callbacks.
 // The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
+// Only a limited number of callbacks may be created in a single Go process, and any memory allocated
+// for these callbacks is never released.
+// Between NewCallback and NewCallbackCDecl, at least 1024 callbacks can always be created.
 func NewCallback(fn interface{}) uintptr {
 	return compileCallback(fn, true)
 }
@@ -180,6 +184,9 @@
 // NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention.
 // This is useful when interoperating with Windows code requiring callbacks.
 // The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
+// Only a limited number of callbacks may be created in a single Go process, and any memory allocated
+// for these callbacks is never released.
+// Between NewCallback and NewCallbackCDecl, at least 1024 callbacks can always be created.
 func NewCallbackCDecl(fn interface{}) uintptr {
 	return compileCallback(fn, false)
 }
@@ -191,6 +198,7 @@
 //sys	FreeLibrary(handle Handle) (err error)
 //sys	GetProcAddress(module Handle, procname string) (proc uintptr, err error)
 //sys	GetVersion() (ver uint32, err error)
+//sys	rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) = ntdll.RtlGetNtVersionNumbers
 //sys	formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
 //sys	ExitProcess(exitcode uint32)
 //sys	CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
@@ -284,6 +292,9 @@
 // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
 //sys	CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW
 //sys	CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW
+//sys	initializeProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, attrcount uint32, flags uint32, size *uintptr) (err error) = InitializeProcThreadAttributeList
+//sys	deleteProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST) = DeleteProcThreadAttributeList
+//sys	updateProcThreadAttribute(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) = UpdateProcThreadAttribute
 
 // syscall interface implementation for other packages
 
@@ -414,19 +425,22 @@
 // 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
-	switch runtime.GOARCH {
-	default:
-		panic("unsupported architecture")
-	case "amd64":
+	if unsafe.Sizeof(uintptr(0)) == 8 {
 		_, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 4, uintptr(handle), uintptr(distToMove), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0, 0)
-	case "386":
-		// 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)
-	case "arm":
-		// distToMove must be 8-byte aligned per ARM calling convention
-		// https://msdn.microsoft.com/en-us/library/dn736986.aspx#Anchor_7
-		_, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 6, uintptr(handle), 0, uintptr(distToMove), uintptr(distToMove>>32), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence))
+	} else {
+		// Different 32-bit systems disgaree about whether distToMove starts 8-byte aligned.
+		switch runtime.GOARCH {
+		default:
+			panic("unsupported 32-bit architecture")
+		case "386":
+			// 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)
+		case "arm":
+			// distToMove must be 8-byte aligned per ARM calling convention
+			// https://msdn.microsoft.com/en-us/library/dn736986.aspx#Anchor_7
+			_, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 6, uintptr(handle), 0, uintptr(distToMove), uintptr(distToMove>>32), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence))
+		}
 	}
 	if e1 != 0 {
 		return errnoErr(e1)
@@ -465,7 +479,6 @@
 
 func getStdHandle(h int) (fd Handle) {
 	r, _ := GetStdHandle(h)
-	CloseOnExec(r)
 	return r
 }
 
@@ -1146,7 +1159,7 @@
 			return str
 		}
 	}
-	return "signal " + itoa(int(s))
+	return "signal " + itoa.Itoa(int(s))
 }
 
 func LoadCreateSymbolicLink() error {
@@ -1237,3 +1250,24 @@
 func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) error {
 	return postQueuedCompletionStatus(cphandle, qty, uintptr(key), overlapped)
 }
+
+// newProcThreadAttributeList allocates new PROC_THREAD_ATTRIBUTE_LIST, with
+// the requested maximum number of attributes, which must be cleaned up by
+// deleteProcThreadAttributeList.
+func newProcThreadAttributeList(maxAttrCount uint32) (*_PROC_THREAD_ATTRIBUTE_LIST, error) {
+	var size uintptr
+	err := initializeProcThreadAttributeList(nil, maxAttrCount, 0, &size)
+	if err != ERROR_INSUFFICIENT_BUFFER {
+		if err == nil {
+			return nil, errorspkg.New("unable to query buffer size from InitializeProcThreadAttributeList")
+		}
+		return nil, err
+	}
+	// size is guaranteed to be ≥1 by initializeProcThreadAttributeList.
+	al := (*_PROC_THREAD_ATTRIBUTE_LIST)(unsafe.Pointer(&make([]byte, size)[0]))
+	err = initializeProcThreadAttributeList(al, maxAttrCount, 0, &size)
+	if err != nil {
+		return nil, err
+	}
+	return al, nil
+}
diff --git a/src/syscall/syscall_windows_386.go b/src/syscall/syscall_windows_386.go
deleted file mode 100644
index e82b540..0000000
--- a/src/syscall/syscall_windows_386.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
diff --git a/src/syscall/syscall_windows_amd64.go b/src/syscall/syscall_windows_amd64.go
deleted file mode 100644
index e82b540..0000000
--- a/src/syscall/syscall_windows_amd64.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
diff --git a/src/syscall/syscall_windows_test.go b/src/syscall/syscall_windows_test.go
index a9ae547..194c878 100644
--- a/src/syscall/syscall_windows_test.go
+++ b/src/syscall/syscall_windows_test.go
@@ -5,18 +5,18 @@
 package syscall_test
 
 import (
+	"fmt"
+	"internal/testenv"
 	"os"
+	"os/exec"
 	"path/filepath"
+	"strings"
 	"syscall"
 	"testing"
 )
 
 func TestWin32finddata(t *testing.T) {
-	dir, err := os.MkdirTemp("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
+	dir := t.TempDir()
 
 	path := filepath.Join(dir, "long_name.and_extension")
 	f, err := os.Create(path)
@@ -75,3 +75,75 @@
 		t.Errorf("TOKEN_ALL_ACCESS = %x, want 0xF01FF", syscall.TOKEN_ALL_ACCESS)
 	}
 }
+
+func TestStdioAreInheritable(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+	testenv.MustHaveCGO(t)
+	testenv.MustHaveExecPath(t, "gcc")
+
+	tmpdir := t.TempDir()
+
+	// build go dll
+	const dlltext = `
+package main
+
+import "C"
+import (
+	"fmt"
+)
+
+//export HelloWorld
+func HelloWorld() {
+	fmt.Println("Hello World")
+}
+
+func main() {}
+`
+	dllsrc := filepath.Join(tmpdir, "helloworld.go")
+	err := os.WriteFile(dllsrc, []byte(dlltext), 0644)
+	if err != nil {
+		t.Fatal(err)
+	}
+	dll := filepath.Join(tmpdir, "helloworld.dll")
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dll, "-buildmode", "c-shared", dllsrc)
+	out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
+	if err != nil {
+		t.Fatalf("failed to build go library: %s\n%s", err, out)
+	}
+
+	// build c exe
+	const exetext = `
+#include <stdlib.h>
+#include <windows.h>
+int main(int argc, char *argv[])
+{
+	system("hostname");
+	((void(*)(void))GetProcAddress(LoadLibraryA(%q), "HelloWorld"))();
+	system("hostname");
+	return 0;
+}
+`
+	exe := filepath.Join(tmpdir, "helloworld.exe")
+	cmd = exec.Command("gcc", "-o", exe, "-xc", "-")
+	cmd.Stdin = strings.NewReader(fmt.Sprintf(exetext, dll))
+	out, err = testenv.CleanCmdEnv(cmd).CombinedOutput()
+	if err != nil {
+		t.Fatalf("failed to build c executable: %s\n%s", err, out)
+	}
+	out, err = exec.Command(exe).CombinedOutput()
+	if err != nil {
+		t.Fatalf("c program execution failed: %v: %v", err, string(out))
+	}
+
+	hostname, err := os.Hostname()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	have := strings.ReplaceAll(string(out), "\n", "")
+	have = strings.ReplaceAll(have, "\r", "")
+	want := fmt.Sprintf("%sHello World%s", hostname, hostname)
+	if have != want {
+		t.Fatalf("c program output is wrong: got %q, want %q", have, want)
+	}
+}
diff --git a/src/syscall/tables_js.go b/src/syscall/tables_js.go
index a7c4f8c..64d9584 100644
--- a/src/syscall/tables_js.go
+++ b/src/syscall/tables_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package syscall
diff --git a/src/syscall/time_fake.go b/src/syscall/time_fake.go
index 5dec57a..cf88aeb 100644
--- a/src/syscall/time_fake.go
+++ b/src/syscall/time_fake.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build faketime
 // +build faketime
 
 package syscall
diff --git a/src/syscall/time_nofake.go b/src/syscall/time_nofake.go
index c94cef8..5eaa2da 100644
--- a/src/syscall/time_nofake.go
+++ b/src/syscall/time_nofake.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !faketime
 // +build !faketime
 
 package syscall
diff --git a/src/syscall/timestruct.go b/src/syscall/timestruct.go
index bca51df..e4f3d50 100644
--- a/src/syscall/timestruct.go
+++ b/src/syscall/timestruct.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package syscall
diff --git a/src/syscall/types_aix.go b/src/syscall/types_aix.go
index cbc47cc..6588d69 100644
--- a/src/syscall/types_aix.go
+++ b/src/syscall/types_aix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/syscall/types_darwin.go b/src/syscall/types_darwin.go
index 7b3a9d2..c2a32c0 100644
--- a/src/syscall/types_darwin.go
+++ b/src/syscall/types_darwin.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/syscall/types_dragonfly.go b/src/syscall/types_dragonfly.go
index 53bc124..9f8d5bc 100644
--- a/src/syscall/types_dragonfly.go
+++ b/src/syscall/types_dragonfly.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/syscall/types_freebsd.go b/src/syscall/types_freebsd.go
index f686021..d741411 100644
--- a/src/syscall/types_freebsd.go
+++ b/src/syscall/types_freebsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/syscall/types_illumos_amd64.go b/src/syscall/types_illumos_amd64.go
index abb282f..254e3e7 100644
--- a/src/syscall/types_illumos_amd64.go
+++ b/src/syscall/types_illumos_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build illumos
 // +build illumos
 
 // Illumos consts not present on Solaris. These are added manually rather than
diff --git a/src/syscall/types_linux.go b/src/syscall/types_linux.go
index 9de32d9..bf76be9 100644
--- a/src/syscall/types_linux.go
+++ b/src/syscall/types_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/syscall/types_netbsd.go b/src/syscall/types_netbsd.go
index 30ab2dc..0bd25ea 100644
--- a/src/syscall/types_netbsd.go
+++ b/src/syscall/types_netbsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/syscall/types_openbsd.go b/src/syscall/types_openbsd.go
index 9228648..8b41cdc 100644
--- a/src/syscall/types_openbsd.go
+++ b/src/syscall/types_openbsd.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/syscall/types_solaris.go b/src/syscall/types_solaris.go
index 76a7450..179f791 100644
--- a/src/syscall/types_solaris.go
+++ b/src/syscall/types_solaris.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 /*
diff --git a/src/syscall/types_windows.go b/src/syscall/types_windows.go
index 0349f3b..384b5b4 100644
--- a/src/syscall/types_windows.go
+++ b/src/syscall/types_windows.go
@@ -398,6 +398,14 @@
 	Reserved1         uint32
 	FileName          [MAX_PATH]uint16
 	AlternateFileName [14]uint16
+
+	// The Microsoft documentation for this struct¹ describes three additional
+	// fields: dwFileType, dwCreatorType, and wFinderFlags. However, those fields
+	// are empirically only present in the macOS port of the Win32 API,² and thus
+	// not needed for binaries built for Windows.
+	//
+	// ¹ https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-win32_find_dataw
+	// ² https://golang.org/issue/42637#issuecomment-760715755
 }
 
 func copyFindData(dst *Win32finddata, src *win32finddata1) {
@@ -482,6 +490,22 @@
 	StdErr        Handle
 }
 
+type _PROC_THREAD_ATTRIBUTE_LIST struct {
+	_ [1]byte
+}
+
+const (
+	_PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000
+	_PROC_THREAD_ATTRIBUTE_HANDLE_LIST    = 0x00020002
+)
+
+type _STARTUPINFOEXW struct {
+	StartupInfo
+	ProcThreadAttributeList *_PROC_THREAD_ATTRIBUTE_LIST
+}
+
+const _EXTENDED_STARTUPINFO_PRESENT = 0x00080000
+
 type ProcessInformation struct {
 	Process   Handle
 	Thread    Handle
diff --git a/src/syscall/types_windows_arm64.go b/src/syscall/types_windows_arm64.go
new file mode 100644
index 0000000..7d45ddb
--- /dev/null
+++ b/src/syscall/types_windows_arm64.go
@@ -0,0 +1,22 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+type WSAData struct {
+	Version      uint16
+	HighVersion  uint16
+	MaxSockets   uint16
+	MaxUdpDg     uint16
+	VendorInfo   *byte
+	Description  [WSADESCRIPTION_LEN + 1]byte
+	SystemStatus [WSASYS_STATUS_LEN + 1]byte
+}
+
+type Servent struct {
+	Name    *byte
+	Aliases **byte
+	Proto   *byte
+	Port    uint16
+}
diff --git a/src/syscall/zerrors_darwin_amd64.go b/src/syscall/zerrors_darwin_amd64.go
index 58799fb..0b98972 100644
--- a/src/syscall/zerrors_darwin_amd64.go
+++ b/src/syscall/zerrors_darwin_amd64.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m64 _const.go
 
+//go:build amd64 && darwin
 // +build amd64,darwin
 
 package syscall
diff --git a/src/syscall/zerrors_darwin_arm64.go b/src/syscall/zerrors_darwin_arm64.go
index 8b43361..5f210fd 100644
--- a/src/syscall/zerrors_darwin_arm64.go
+++ b/src/syscall/zerrors_darwin_arm64.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m64 _const.go
 
+//go:build arm64 && darwin
 // +build arm64,darwin
 
 package syscall
diff --git a/src/syscall/zerrors_dragonfly_amd64.go b/src/syscall/zerrors_dragonfly_amd64.go
index 3434a85..35e2a52 100644
--- a/src/syscall/zerrors_dragonfly_amd64.go
+++ b/src/syscall/zerrors_dragonfly_amd64.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m64 _const.go
 
+//go:build amd64 && dragonfly
 // +build amd64,dragonfly
 
 package syscall
@@ -849,6 +850,7 @@
 	MAP_VPAGETABLE                    = 0x2000
 	MCL_CURRENT                       = 0x1
 	MCL_FUTURE                        = 0x2
+	MSG_CMSG_CLOEXEC                  = 0x1000
 	MSG_CTRUNC                        = 0x20
 	MSG_DONTROUTE                     = 0x4
 	MSG_DONTWAIT                      = 0x80
@@ -1237,8 +1239,10 @@
 	VWERASE                           = 0x4
 	WCONTINUED                        = 0x4
 	WCOREFLAG                         = 0x80
+	WEXITED                           = 0x10
 	WLINUXCLONE                       = 0x80000000
 	WNOHANG                           = 0x1
+	WNOWAIT                           = 0x8
 	WSTOPPED                          = 0x7f
 	WUNTRACED                         = 0x2
 )
diff --git a/src/syscall/zerrors_freebsd_386.go b/src/syscall/zerrors_freebsd_386.go
index 85786a5..aec26ad 100644
--- a/src/syscall/zerrors_freebsd_386.go
+++ b/src/syscall/zerrors_freebsd_386.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m32 _const.go
 
+//go:build 386 && freebsd
 // +build 386,freebsd
 
 package syscall
diff --git a/src/syscall/zerrors_freebsd_amd64.go b/src/syscall/zerrors_freebsd_amd64.go
index b3ebf3d..d6d13e4 100644
--- a/src/syscall/zerrors_freebsd_amd64.go
+++ b/src/syscall/zerrors_freebsd_amd64.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m64 _const.go
 
+//go:build amd64 && freebsd
 // +build amd64,freebsd
 
 package syscall
diff --git a/src/syscall/zerrors_freebsd_arm.go b/src/syscall/zerrors_freebsd_arm.go
index 29eabb1..15c714f 100644
--- a/src/syscall/zerrors_freebsd_arm.go
+++ b/src/syscall/zerrors_freebsd_arm.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- _const.go
 
+//go:build arm && freebsd
 // +build arm,freebsd
 
 package syscall
diff --git a/src/syscall/zerrors_freebsd_arm64.go b/src/syscall/zerrors_freebsd_arm64.go
index 82ee158..b20ce7d 100644
--- a/src/syscall/zerrors_freebsd_arm64.go
+++ b/src/syscall/zerrors_freebsd_arm64.go
@@ -1,6 +1,7 @@
 // mkerrors.sh -m64
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build freebsd && arm64
 // +build freebsd,arm64
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
diff --git a/src/syscall/zerrors_linux_386.go b/src/syscall/zerrors_linux_386.go
index 53a442d..fb64932 100644
--- a/src/syscall/zerrors_linux_386.go
+++ b/src/syscall/zerrors_linux_386.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m32 _const.go
 
+//go:build 386 && linux
 // +build 386,linux
 
 package syscall
diff --git a/src/syscall/zerrors_linux_amd64.go b/src/syscall/zerrors_linux_amd64.go
index 0b4c60d..3a92bcd 100644
--- a/src/syscall/zerrors_linux_amd64.go
+++ b/src/syscall/zerrors_linux_amd64.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m64 _const.go
 
+//go:build amd64 && linux
 // +build amd64,linux
 
 package syscall
diff --git a/src/syscall/zerrors_linux_arm.go b/src/syscall/zerrors_linux_arm.go
index 9a8d9e8..e013d8e 100644
--- a/src/syscall/zerrors_linux_arm.go
+++ b/src/syscall/zerrors_linux_arm.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- _const.go
 
+//go:build arm && linux
 // +build arm,linux
 
 package syscall
diff --git a/src/syscall/zerrors_linux_arm64.go b/src/syscall/zerrors_linux_arm64.go
index f0caf55..1a4d33e 100644
--- a/src/syscall/zerrors_linux_arm64.go
+++ b/src/syscall/zerrors_linux_arm64.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- _const.go
 
+//go:build arm64 && linux
 // +build arm64,linux
 
 package syscall
diff --git a/src/syscall/zerrors_linux_ppc64.go b/src/syscall/zerrors_linux_ppc64.go
index f064731..1dda43b 100644
--- a/src/syscall/zerrors_linux_ppc64.go
+++ b/src/syscall/zerrors_linux_ppc64.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m64 _const.go
 
+//go:build ppc64 && linux
 // +build ppc64,linux
 
 package syscall
diff --git a/src/syscall/zerrors_linux_ppc64le.go b/src/syscall/zerrors_linux_ppc64le.go
index 41e21a5..6d56f1c 100644
--- a/src/syscall/zerrors_linux_ppc64le.go
+++ b/src/syscall/zerrors_linux_ppc64le.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m64 _const.go
 
+//go:build ppc64le && linux
 // +build ppc64le,linux
 
 package syscall
diff --git a/src/syscall/zerrors_netbsd_386.go b/src/syscall/zerrors_netbsd_386.go
index bf1e4a7..934e9ef 100644
--- a/src/syscall/zerrors_netbsd_386.go
+++ b/src/syscall/zerrors_netbsd_386.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m32 _const.go
 
+//go:build 386 && netbsd
 // +build 386,netbsd
 
 package syscall
@@ -1426,6 +1427,7 @@
 	WALTSIG                           = 0x4
 	WCLONE                            = 0x4
 	WCOREFLAG                         = 0x80
+	WEXITED                           = 0x20
 	WNOHANG                           = 0x1
 	WNOWAIT                           = 0x10000
 	WNOZOMBIE                         = 0x20000
diff --git a/src/syscall/zerrors_netbsd_amd64.go b/src/syscall/zerrors_netbsd_amd64.go
index 247e78e..0f5ad61 100644
--- a/src/syscall/zerrors_netbsd_amd64.go
+++ b/src/syscall/zerrors_netbsd_amd64.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m64 _const.go
 
+//go:build amd64 && netbsd
 // +build amd64,netbsd
 
 package syscall
@@ -1416,6 +1417,7 @@
 	WALTSIG                           = 0x4
 	WCLONE                            = 0x4
 	WCOREFLAG                         = 0x80
+	WEXITED                           = 0x20
 	WNOHANG                           = 0x1
 	WNOWAIT                           = 0x10000
 	WNOZOMBIE                         = 0x20000
diff --git a/src/syscall/zerrors_netbsd_arm.go b/src/syscall/zerrors_netbsd_arm.go
index f23cd86..9d86787 100644
--- a/src/syscall/zerrors_netbsd_arm.go
+++ b/src/syscall/zerrors_netbsd_arm.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -marm _const.go
 
+//go:build arm && netbsd
 // +build arm,netbsd
 
 package syscall
@@ -1402,6 +1403,7 @@
 	WALTSIG                           = 0x4
 	WCLONE                            = 0x4
 	WCOREFLAG                         = 0x80
+	WEXITED                           = 0x20
 	WNOHANG                           = 0x1
 	WNOWAIT                           = 0x10000
 	WNOZOMBIE                         = 0x20000
diff --git a/src/syscall/zerrors_netbsd_arm64.go b/src/syscall/zerrors_netbsd_arm64.go
index 6f6453f..7adb72f 100644
--- a/src/syscall/zerrors_netbsd_arm64.go
+++ b/src/syscall/zerrors_netbsd_arm64.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m64 _const.go
 
+//go:build arm64 && netbsd
 // +build arm64,netbsd
 
 package syscall
@@ -1416,6 +1417,7 @@
 	WALTSIG                           = 0x4
 	WCLONE                            = 0x4
 	WCOREFLAG                         = 0x80
+	WEXITED                           = 0x20
 	WNOHANG                           = 0x1
 	WNOWAIT                           = 0x10000
 	WNOZOMBIE                         = 0x20000
diff --git a/src/syscall/zerrors_openbsd_386.go b/src/syscall/zerrors_openbsd_386.go
index 7985abe..a8457c6 100644
--- a/src/syscall/zerrors_openbsd_386.go
+++ b/src/syscall/zerrors_openbsd_386.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m32 _const.go
 
+//go:build 386 && openbsd
 // +build 386,openbsd
 
 package syscall
@@ -890,6 +891,7 @@
 	MCL_CURRENT                       = 0x1
 	MCL_FUTURE                        = 0x2
 	MSG_BCAST                         = 0x100
+	MSG_CMSG_CLOEXEC                  = 0x800
 	MSG_CTRUNC                        = 0x20
 	MSG_DONTROUTE                     = 0x4
 	MSG_DONTWAIT                      = 0x80
diff --git a/src/syscall/zerrors_openbsd_amd64.go b/src/syscall/zerrors_openbsd_amd64.go
index 9c4ff29..eb19537 100644
--- a/src/syscall/zerrors_openbsd_amd64.go
+++ b/src/syscall/zerrors_openbsd_amd64.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m64 _const.go
 
+//go:build amd64 && openbsd
 // +build amd64,openbsd
 
 package syscall
@@ -890,6 +891,7 @@
 	MCL_CURRENT                       = 0x1
 	MCL_FUTURE                        = 0x2
 	MSG_BCAST                         = 0x100
+	MSG_CMSG_CLOEXEC                  = 0x800
 	MSG_CTRUNC                        = 0x20
 	MSG_DONTROUTE                     = 0x4
 	MSG_DONTWAIT                      = 0x80
diff --git a/src/syscall/zerrors_openbsd_arm.go b/src/syscall/zerrors_openbsd_arm.go
index 493a838..89a4e6d 100644
--- a/src/syscall/zerrors_openbsd_arm.go
+++ b/src/syscall/zerrors_openbsd_arm.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- _const.go
 
+//go:build arm && openbsd
 // +build arm,openbsd
 
 package syscall
diff --git a/src/syscall/zerrors_solaris_amd64.go b/src/syscall/zerrors_solaris_amd64.go
index eba4015..b7dee69 100644
--- a/src/syscall/zerrors_solaris_amd64.go
+++ b/src/syscall/zerrors_solaris_amd64.go
@@ -4,6 +4,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -m64 _const.go
 
+//go:build amd64 && solaris
 // +build amd64,solaris
 
 package syscall
diff --git a/src/syscall/zerrors_windows_386.go b/src/syscall/zerrors_windows_386.go
deleted file mode 100644
index 8bc5b6b..0000000
--- a/src/syscall/zerrors_windows_386.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
diff --git a/src/syscall/zerrors_windows_amd64.go b/src/syscall/zerrors_windows_amd64.go
deleted file mode 100644
index 8bc5b6b..0000000
--- a/src/syscall/zerrors_windows_amd64.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
diff --git a/src/syscall/zsyscall_aix_ppc64.go b/src/syscall/zsyscall_aix_ppc64.go
index 20625c1..134ae41 100644
--- a/src/syscall/zsyscall_aix_ppc64.go
+++ b/src/syscall/zsyscall_aix_ppc64.go
@@ -1,6 +1,7 @@
 // mksyscall_libc.pl -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build aix && ppc64
 // +build aix,ppc64
 
 package syscall
diff --git a/src/syscall/zsyscall_darwin_amd64.go b/src/syscall/zsyscall_darwin_amd64.go
index c246c3a..07a519d 100644
--- a/src/syscall/zsyscall_darwin_amd64.go
+++ b/src/syscall/zsyscall_darwin_amd64.go
@@ -1,16 +1,18 @@
 // mksyscall.pl -darwin -tags darwin,amd64 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build darwin && amd64
 // +build darwin,amd64
 
 package syscall
 
 import "unsafe"
+import "internal/abi"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -20,13 +22,12 @@
 
 func libc_getgroups_trampoline()
 
-//go:linkname libc_getgroups libc_getgroups
 //go:cgo_import_dynamic libc_getgroups getgroups "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -35,13 +36,12 @@
 
 func libc_setgroups_trampoline()
 
-//go:linkname libc_setgroups libc_setgroups
 //go:cgo_import_dynamic libc_setgroups setgroups "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := syscall6(funcPC(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -51,13 +51,12 @@
 
 func libc_wait4_trampoline()
 
-//go:linkname libc_wait4 libc_wait4
 //go:cgo_import_dynamic libc_wait4 wait4 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -67,13 +66,12 @@
 
 func libc_accept_trampoline()
 
-//go:linkname libc_accept libc_accept
 //go:cgo_import_dynamic libc_accept accept "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall(funcPC(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -82,13 +80,12 @@
 
 func libc_bind_trampoline()
 
-//go:linkname libc_bind libc_bind
 //go:cgo_import_dynamic libc_bind bind "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall(funcPC(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -97,13 +94,12 @@
 
 func libc_connect_trampoline()
 
-//go:linkname libc_connect libc_connect
 //go:cgo_import_dynamic libc_connect connect "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -113,13 +109,12 @@
 
 func libc_socket_trampoline()
 
-//go:linkname libc_socket libc_socket
 //go:cgo_import_dynamic libc_socket socket "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -128,13 +123,12 @@
 
 func libc_getsockopt_trampoline()
 
-//go:linkname libc_getsockopt libc_getsockopt
 //go:cgo_import_dynamic libc_getsockopt getsockopt "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -143,13 +137,12 @@
 
 func libc_setsockopt_trampoline()
 
-//go:linkname libc_setsockopt libc_setsockopt
 //go:cgo_import_dynamic libc_setsockopt setsockopt "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -158,13 +151,12 @@
 
 func libc_getpeername_trampoline()
 
-//go:linkname libc_getpeername libc_getpeername
 //go:cgo_import_dynamic libc_getpeername getpeername "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -173,13 +165,12 @@
 
 func libc_getsockname_trampoline()
 
-//go:linkname libc_getsockname libc_getsockname
 //go:cgo_import_dynamic libc_getsockname getsockname "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -188,13 +179,12 @@
 
 func libc_shutdown_trampoline()
 
-//go:linkname libc_shutdown libc_shutdown
 //go:cgo_import_dynamic libc_shutdown shutdown "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := rawSyscall6(funcPC(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := rawSyscall6(abi.FuncPCABI0(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -203,7 +193,6 @@
 
 func libc_socketpair_trampoline()
 
-//go:linkname libc_socketpair libc_socketpair
 //go:cgo_import_dynamic libc_socketpair socketpair "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -215,7 +204,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall6(funcPC(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -225,7 +214,6 @@
 
 func libc_recvfrom_trampoline()
 
-//go:linkname libc_recvfrom libc_recvfrom
 //go:cgo_import_dynamic libc_recvfrom recvfrom "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -237,7 +225,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall6(funcPC(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -246,13 +234,12 @@
 
 func libc_sendto_trampoline()
 
-//go:linkname libc_sendto libc_sendto
 //go:cgo_import_dynamic libc_sendto sendto "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -262,13 +249,12 @@
 
 func libc_recvmsg_trampoline()
 
-//go:linkname libc_recvmsg libc_recvmsg
 //go:cgo_import_dynamic libc_recvmsg recvmsg "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -278,13 +264,12 @@
 
 func libc_sendmsg_trampoline()
 
-//go:linkname libc_sendmsg libc_sendmsg
 //go:cgo_import_dynamic libc_sendmsg sendmsg "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := syscall6(funcPC(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -294,7 +279,6 @@
 
 func libc_kevent_trampoline()
 
-//go:linkname libc_kevent libc_kevent
 //go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -305,7 +289,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -314,13 +298,12 @@
 
 func libc_utimes_trampoline()
 
-//go:linkname libc_utimes libc_utimes
 //go:cgo_import_dynamic libc_utimes utimes "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := syscall(funcPC(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -329,13 +312,12 @@
 
 func libc_futimes_trampoline()
 
-//go:linkname libc_futimes libc_futimes
 //go:cgo_import_dynamic libc_futimes futimes "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -345,13 +327,12 @@
 
 func libc_fcntl_trampoline()
 
-//go:linkname libc_fcntl libc_fcntl
 //go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pipe(p *[2]int32) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_pipe_trampoline), uintptr(unsafe.Pointer(p)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_pipe_trampoline), uintptr(unsafe.Pointer(p)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -360,13 +341,12 @@
 
 func libc_pipe_trampoline()
 
-//go:linkname libc_pipe libc_pipe
 //go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kill(pid int, signum int, posix int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_kill_trampoline), uintptr(pid), uintptr(signum), uintptr(posix))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_kill_trampoline), uintptr(pid), uintptr(signum), uintptr(posix))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -375,7 +355,6 @@
 
 func libc_kill_trampoline()
 
-//go:linkname libc_kill libc_kill
 //go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -386,7 +365,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -395,13 +374,12 @@
 
 func libc_access_trampoline()
 
-//go:linkname libc_access libc_access
 //go:cgo_import_dynamic libc_access access "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := syscall(funcPC(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -410,7 +388,6 @@
 
 func libc_adjtime_trampoline()
 
-//go:linkname libc_adjtime libc_adjtime
 //go:cgo_import_dynamic libc_adjtime adjtime "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -421,7 +398,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -430,7 +407,6 @@
 
 func libc_chdir_trampoline()
 
-//go:linkname libc_chdir libc_chdir
 //go:cgo_import_dynamic libc_chdir chdir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -441,7 +417,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -450,7 +426,6 @@
 
 func libc_chflags_trampoline()
 
-//go:linkname libc_chflags libc_chflags
 //go:cgo_import_dynamic libc_chflags chflags "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -461,7 +436,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -470,7 +445,6 @@
 
 func libc_chmod_trampoline()
 
-//go:linkname libc_chmod libc_chmod
 //go:cgo_import_dynamic libc_chmod chmod "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -481,7 +455,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -490,7 +464,6 @@
 
 func libc_chown_trampoline()
 
-//go:linkname libc_chown libc_chown
 //go:cgo_import_dynamic libc_chown chown "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -501,7 +474,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -510,13 +483,12 @@
 
 func libc_chroot_trampoline()
 
-//go:linkname libc_chroot libc_chroot
 //go:cgo_import_dynamic libc_chroot chroot "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_close_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -525,13 +497,12 @@
 
 func libc_close_trampoline()
 
-//go:linkname libc_close libc_close
 //go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func closedir(dir uintptr) (err error) {
-	_, _, e1 := syscall(funcPC(libc_closedir_trampoline), uintptr(dir), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_closedir_trampoline), uintptr(dir), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -540,13 +511,12 @@
 
 func libc_closedir_trampoline()
 
-//go:linkname libc_closedir libc_closedir
 //go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_dup_trampoline), uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -556,13 +526,12 @@
 
 func libc_dup_trampoline()
 
-//go:linkname libc_dup libc_dup
 //go:cgo_import_dynamic libc_dup dup "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -571,7 +540,6 @@
 
 func libc_dup2_trampoline()
 
-//go:linkname libc_dup2 libc_dup2
 //go:cgo_import_dynamic libc_dup2 dup2 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -587,7 +555,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_exchangedata_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_exchangedata_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -596,13 +564,12 @@
 
 func libc_exchangedata_trampoline()
 
-//go:linkname libc_exchangedata libc_exchangedata
 //go:cgo_import_dynamic libc_exchangedata exchangedata "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchdir_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchdir_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -611,13 +578,12 @@
 
 func libc_fchdir_trampoline()
 
-//go:linkname libc_fchdir libc_fchdir
 //go:cgo_import_dynamic libc_fchdir fchdir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -626,13 +592,12 @@
 
 func libc_fchflags_trampoline()
 
-//go:linkname libc_fchflags libc_fchflags
 //go:cgo_import_dynamic libc_fchflags fchflags "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -641,13 +606,12 @@
 
 func libc_fchmod_trampoline()
 
-//go:linkname libc_fchmod libc_fchmod
 //go:cgo_import_dynamic libc_fchmod fchmod "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -656,13 +620,12 @@
 
 func libc_fchown_trampoline()
 
-//go:linkname libc_fchown libc_fchown
 //go:cgo_import_dynamic libc_fchown fchown "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -671,13 +634,12 @@
 
 func libc_flock_trampoline()
 
-//go:linkname libc_flock libc_flock
 //go:cgo_import_dynamic libc_flock flock "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -687,13 +649,12 @@
 
 func libc_fpathconf_trampoline()
 
-//go:linkname libc_fpathconf libc_fpathconf
 //go:cgo_import_dynamic libc_fpathconf fpathconf "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fsync_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fsync_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -702,13 +663,12 @@
 
 func libc_fsync_trampoline()
 
-//go:linkname libc_fsync libc_fsync
 //go:cgo_import_dynamic libc_fsync fsync "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := syscall(funcPC(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -717,65 +677,60 @@
 
 func libc_ftruncate_trampoline()
 
-//go:linkname libc_ftruncate libc_ftruncate
 //go:cgo_import_dynamic libc_ftruncate ftruncate "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getdtablesize() (size int) {
-	r0, _, _ := syscall(funcPC(libc_getdtablesize_trampoline), 0, 0, 0)
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_getdtablesize_trampoline), 0, 0, 0)
 	size = int(r0)
 	return
 }
 
 func libc_getdtablesize_trampoline()
 
-//go:linkname libc_getdtablesize libc_getdtablesize
 //go:cgo_import_dynamic libc_getdtablesize getdtablesize "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getegid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getegid_trampoline), 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
 func libc_getegid_trampoline()
 
-//go:linkname libc_getegid libc_getegid
 //go:cgo_import_dynamic libc_getegid getegid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_geteuid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_geteuid_trampoline), 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
 func libc_geteuid_trampoline()
 
-//go:linkname libc_geteuid libc_geteuid
 //go:cgo_import_dynamic libc_geteuid geteuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getgid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getgid_trampoline), 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
 func libc_getgid_trampoline()
 
-//go:linkname libc_getgid libc_getgid
 //go:cgo_import_dynamic libc_getgid getgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_getpgid_trampoline), uintptr(pid), 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpgid_trampoline), uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -785,52 +740,48 @@
 
 func libc_getpgid_trampoline()
 
-//go:linkname libc_getpgid libc_getpgid
 //go:cgo_import_dynamic libc_getpgid getpgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getpgrp_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpgrp_trampoline), 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
 func libc_getpgrp_trampoline()
 
-//go:linkname libc_getpgrp libc_getpgrp
 //go:cgo_import_dynamic libc_getpgrp getpgrp "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getpid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
 func libc_getpid_trampoline()
 
-//go:linkname libc_getpid libc_getpid
 //go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getppid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getppid_trampoline), 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
 func libc_getppid_trampoline()
 
-//go:linkname libc_getppid libc_getppid
 //go:cgo_import_dynamic libc_getppid getppid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -840,13 +791,12 @@
 
 func libc_getpriority_trampoline()
 
-//go:linkname libc_getpriority libc_getpriority
 //go:cgo_import_dynamic libc_getpriority getpriority "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -855,13 +805,12 @@
 
 func libc_getrlimit_trampoline()
 
-//go:linkname libc_getrlimit libc_getrlimit
 //go:cgo_import_dynamic libc_getrlimit getrlimit "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -870,13 +819,12 @@
 
 func libc_getrusage_trampoline()
 
-//go:linkname libc_getrusage libc_getrusage
 //go:cgo_import_dynamic libc_getrusage getrusage "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_getsid_trampoline), uintptr(pid), 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsid_trampoline), uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -886,39 +834,36 @@
 
 func libc_getsid_trampoline()
 
-//go:linkname libc_getsid libc_getsid
 //go:cgo_import_dynamic libc_getsid getsid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getuid_trampoline), 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
 func libc_getuid_trampoline()
 
-//go:linkname libc_getuid libc_getuid
 //go:cgo_import_dynamic libc_getuid getuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := rawSyscall(funcPC(libc_issetugid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_issetugid_trampoline), 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
 func libc_issetugid_trampoline()
 
-//go:linkname libc_issetugid libc_issetugid
 //go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_kqueue_trampoline), 0, 0, 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_kqueue_trampoline), 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -928,7 +873,6 @@
 
 func libc_kqueue_trampoline()
 
-//go:linkname libc_kqueue libc_kqueue
 //go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -939,7 +883,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -948,7 +892,6 @@
 
 func libc_lchown_trampoline()
 
-//go:linkname libc_lchown libc_lchown
 //go:cgo_import_dynamic libc_lchown lchown "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -964,7 +907,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -973,13 +916,12 @@
 
 func libc_link_trampoline()
 
-//go:linkname libc_link libc_link
 //go:cgo_import_dynamic libc_link link "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -988,7 +930,6 @@
 
 func libc_listen_trampoline()
 
-//go:linkname libc_listen libc_listen
 //go:cgo_import_dynamic libc_listen listen "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -999,7 +940,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1008,7 +949,6 @@
 
 func libc_mkdir_trampoline()
 
-//go:linkname libc_mkdir libc_mkdir
 //go:cgo_import_dynamic libc_mkdir mkdir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1019,7 +959,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1028,7 +968,6 @@
 
 func libc_mkfifo_trampoline()
 
-//go:linkname libc_mkfifo libc_mkfifo
 //go:cgo_import_dynamic libc_mkfifo mkfifo "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1039,7 +978,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1048,7 +987,6 @@
 
 func libc_mknod_trampoline()
 
-//go:linkname libc_mknod libc_mknod
 //go:cgo_import_dynamic libc_mknod mknod "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1060,7 +998,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall(funcPC(libc_mlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1069,13 +1007,12 @@
 
 func libc_mlock_trampoline()
 
-//go:linkname libc_mlock libc_mlock
 //go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlockall(flags int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_mlockall_trampoline), uintptr(flags), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mlockall_trampoline), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1084,7 +1021,6 @@
 
 func libc_mlockall_trampoline()
 
-//go:linkname libc_mlockall libc_mlockall
 //go:cgo_import_dynamic libc_mlockall mlockall "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1096,7 +1032,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall(funcPC(libc_mprotect_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mprotect_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(prot))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1105,7 +1041,6 @@
 
 func libc_mprotect_trampoline()
 
-//go:linkname libc_mprotect libc_mprotect
 //go:cgo_import_dynamic libc_mprotect mprotect "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1117,7 +1052,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall(funcPC(libc_munlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_munlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1126,13 +1061,12 @@
 
 func libc_munlock_trampoline()
 
-//go:linkname libc_munlock libc_munlock
 //go:cgo_import_dynamic libc_munlock munlock "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlockall() (err error) {
-	_, _, e1 := syscall(funcPC(libc_munlockall_trampoline), 0, 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_munlockall_trampoline), 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1141,7 +1075,6 @@
 
 func libc_munlockall_trampoline()
 
-//go:linkname libc_munlockall libc_munlockall
 //go:cgo_import_dynamic libc_munlockall munlockall "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1152,7 +1085,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall(funcPC(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1162,7 +1095,6 @@
 
 func libc_open_trampoline()
 
-//go:linkname libc_open libc_open
 //go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1173,7 +1105,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall(funcPC(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1183,7 +1115,6 @@
 
 func libc_pathconf_trampoline()
 
-//go:linkname libc_pathconf libc_pathconf
 //go:cgo_import_dynamic libc_pathconf pathconf "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1195,7 +1126,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall6(funcPC(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1205,7 +1136,6 @@
 
 func libc_pread_trampoline()
 
-//go:linkname libc_pread libc_pread
 //go:cgo_import_dynamic libc_pread pread "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1217,7 +1147,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall6(funcPC(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1227,7 +1157,6 @@
 
 func libc_pwrite_trampoline()
 
-//go:linkname libc_pwrite libc_pwrite
 //go:cgo_import_dynamic libc_pwrite pwrite "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1239,7 +1168,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1249,20 +1178,18 @@
 
 func libc_read_trampoline()
 
-//go:linkname libc_read libc_read
 //go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
-	r0, _, _ := syscall(funcPC(libc_readdir_r_trampoline), uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_readdir_r_trampoline), uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
 	res = Errno(r0)
 	return
 }
 
 func libc_readdir_r_trampoline()
 
-//go:linkname libc_readdir_r libc_readdir_r
 //go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1279,7 +1206,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1289,7 +1216,6 @@
 
 func libc_readlink_trampoline()
 
-//go:linkname libc_readlink libc_readlink
 //go:cgo_import_dynamic libc_readlink readlink "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1305,7 +1231,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1314,7 +1240,6 @@
 
 func libc_rename_trampoline()
 
-//go:linkname libc_rename libc_rename
 //go:cgo_import_dynamic libc_rename rename "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1325,7 +1250,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1334,7 +1259,6 @@
 
 func libc_revoke_trampoline()
 
-//go:linkname libc_revoke libc_revoke
 //go:cgo_import_dynamic libc_revoke revoke "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1345,7 +1269,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1354,13 +1278,12 @@
 
 func libc_rmdir_trampoline()
 
-//go:linkname libc_rmdir libc_rmdir
 //go:cgo_import_dynamic libc_rmdir rmdir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := syscallX(funcPC(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(whence))
+	r0, _, e1 := syscallX(abi.FuncPCABI0(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(whence))
 	newoffset = int64(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1370,13 +1293,12 @@
 
 func libc_lseek_trampoline()
 
-//go:linkname libc_lseek libc_lseek
 //go:cgo_import_dynamic libc_lseek lseek "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_select_trampoline), uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_select_trampoline), uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1385,13 +1307,12 @@
 
 func libc_select_trampoline()
 
-//go:linkname libc_select libc_select
 //go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_setegid_trampoline), uintptr(egid), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setegid_trampoline), uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1400,13 +1321,12 @@
 
 func libc_setegid_trampoline()
 
-//go:linkname libc_setegid libc_setegid
 //go:cgo_import_dynamic libc_setegid setegid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_seteuid_trampoline), uintptr(euid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_seteuid_trampoline), uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1415,13 +1335,12 @@
 
 func libc_seteuid_trampoline()
 
-//go:linkname libc_seteuid libc_seteuid
 //go:cgo_import_dynamic libc_seteuid seteuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setgid_trampoline), uintptr(gid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1430,7 +1349,6 @@
 
 func libc_setgid_trampoline()
 
-//go:linkname libc_setgid libc_setgid
 //go:cgo_import_dynamic libc_setgid setgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1441,7 +1359,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1450,13 +1368,12 @@
 
 func libc_setlogin_trampoline()
 
-//go:linkname libc_setlogin libc_setlogin
 //go:cgo_import_dynamic libc_setlogin setlogin "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1465,13 +1382,12 @@
 
 func libc_setpgid_trampoline()
 
-//go:linkname libc_setpgid libc_setpgid
 //go:cgo_import_dynamic libc_setpgid setpgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1480,13 +1396,12 @@
 
 func libc_setpriority_trampoline()
 
-//go:linkname libc_setpriority libc_setpriority
 //go:cgo_import_dynamic libc_setpriority setpriority "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setprivexec(flag int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_setprivexec_trampoline), uintptr(flag), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setprivexec_trampoline), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1495,13 +1410,12 @@
 
 func libc_setprivexec_trampoline()
 
-//go:linkname libc_setprivexec libc_setprivexec
 //go:cgo_import_dynamic libc_setprivexec setprivexec "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1510,13 +1424,12 @@
 
 func libc_setregid_trampoline()
 
-//go:linkname libc_setregid libc_setregid
 //go:cgo_import_dynamic libc_setregid setregid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1525,13 +1438,12 @@
 
 func libc_setreuid_trampoline()
 
-//go:linkname libc_setreuid libc_setreuid
 //go:cgo_import_dynamic libc_setreuid setreuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1540,13 +1452,12 @@
 
 func libc_setrlimit_trampoline()
 
-//go:linkname libc_setrlimit libc_setrlimit
 //go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_setsid_trampoline), 0, 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1556,13 +1467,12 @@
 
 func libc_setsid_trampoline()
 
-//go:linkname libc_setsid libc_setsid
 //go:cgo_import_dynamic libc_setsid setsid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1571,13 +1481,12 @@
 
 func libc_settimeofday_trampoline()
 
-//go:linkname libc_settimeofday libc_settimeofday
 //go:cgo_import_dynamic libc_settimeofday settimeofday "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setuid_trampoline), uintptr(uid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1586,7 +1495,6 @@
 
 func libc_setuid_trampoline()
 
-//go:linkname libc_setuid libc_setuid
 //go:cgo_import_dynamic libc_setuid setuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1602,7 +1510,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1611,13 +1519,12 @@
 
 func libc_symlink_trampoline()
 
-//go:linkname libc_symlink libc_symlink
 //go:cgo_import_dynamic libc_symlink symlink "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := syscall(funcPC(libc_sync_trampoline), 0, 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_sync_trampoline), 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1626,7 +1533,6 @@
 
 func libc_sync_trampoline()
 
-//go:linkname libc_sync libc_sync
 //go:cgo_import_dynamic libc_sync sync "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1637,7 +1543,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1646,20 +1552,18 @@
 
 func libc_truncate_trampoline()
 
-//go:linkname libc_truncate libc_truncate
 //go:cgo_import_dynamic libc_truncate truncate "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := syscall(funcPC(libc_umask_trampoline), uintptr(newmask), 0, 0)
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_umask_trampoline), uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
 func libc_umask_trampoline()
 
-//go:linkname libc_umask libc_umask
 //go:cgo_import_dynamic libc_umask umask "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1670,7 +1574,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_undelete_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_undelete_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1679,7 +1583,6 @@
 
 func libc_undelete_trampoline()
 
-//go:linkname libc_undelete libc_undelete
 //go:cgo_import_dynamic libc_undelete undelete "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1690,7 +1593,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1699,7 +1602,6 @@
 
 func libc_unlink_trampoline()
 
-//go:linkname libc_unlink libc_unlink
 //go:cgo_import_dynamic libc_unlink unlink "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1710,7 +1612,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1719,7 +1621,6 @@
 
 func libc_unmount_trampoline()
 
-//go:linkname libc_unmount libc_unmount
 //go:cgo_import_dynamic libc_unmount unmount "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1731,7 +1632,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1741,7 +1642,6 @@
 
 func libc_write_trampoline()
 
-//go:linkname libc_write libc_write
 //go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1753,7 +1653,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscallX(funcPC(libc_writev_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
+	r0, _, e1 := syscallX(abi.FuncPCABI0(libc_writev_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
 	cnt = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1763,13 +1663,12 @@
 
 func libc_writev_trampoline()
 
-//go:linkname libc_writev libc_writev
 //go:cgo_import_dynamic libc_writev writev "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := syscall6X(funcPC(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	r0, _, e1 := syscall6X(abi.FuncPCABI0(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1779,13 +1678,12 @@
 
 func libc_mmap_trampoline()
 
-//go:linkname libc_mmap libc_mmap
 //go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := syscall(funcPC(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1794,13 +1692,12 @@
 
 func libc_munmap_trampoline()
 
-//go:linkname libc_munmap libc_munmap
 //go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fork() (pid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_fork_trampoline), 0, 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1810,13 +1707,12 @@
 
 func libc_fork_trampoline()
 
-//go:linkname libc_fork libc_fork
 //go:cgo_import_dynamic libc_fork fork "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctl(fd int, req int, arg int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1825,13 +1721,12 @@
 
 func libc_ioctl_trampoline()
 
-//go:linkname libc_ioctl libc_ioctl
 //go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1841,7 +1736,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func execve(path *byte, argv **byte, envp **byte) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_execve_trampoline), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(argv)), uintptr(unsafe.Pointer(envp)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_execve_trampoline), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(argv)), uintptr(unsafe.Pointer(envp)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1850,13 +1745,12 @@
 
 func libc_execve_trampoline()
 
-//go:linkname libc_execve libc_execve
 //go:cgo_import_dynamic libc_execve execve "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func exit(res int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_exit_trampoline), uintptr(res), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), uintptr(res), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1865,7 +1759,6 @@
 
 func libc_exit_trampoline()
 
-//go:linkname libc_exit libc_exit
 //go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1877,7 +1770,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall6(funcPC(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1886,13 +1779,12 @@
 
 func libc_sysctl_trampoline()
 
-//go:linkname libc_sysctl libc_sysctl
 //go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1908,7 +1800,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_unlinkat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unlinkat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1917,7 +1809,6 @@
 
 func libc_unlinkat_trampoline()
 
-//go:linkname libc_unlinkat libc_unlinkat
 //go:cgo_import_dynamic libc_unlinkat unlinkat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1928,7 +1819,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall6(funcPC(libc_openat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(perm), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_openat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(perm), 0, 0)
 	fdret = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1938,7 +1829,6 @@
 
 func libc_openat_trampoline()
 
-//go:linkname libc_openat libc_openat
 //go:cgo_import_dynamic libc_openat openat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1950,7 +1840,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1960,13 +1850,12 @@
 
 func libc_getcwd_trampoline()
 
-//go:linkname libc_getcwd libc_getcwd
 //go:cgo_import_dynamic libc_getcwd getcwd "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fstat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fstat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1975,13 +1864,12 @@
 
 func libc_fstat64_trampoline()
 
-//go:linkname libc_fstat64 libc_fstat64
 //go:cgo_import_dynamic libc_fstat64 fstat64 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fstatfs64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fstatfs64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1990,13 +1878,12 @@
 
 func libc_fstatfs64_trampoline()
 
-//go:linkname libc_fstatfs64 libc_fstatfs64
 //go:cgo_import_dynamic libc_fstatfs64 fstatfs64 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tp *Timeval) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -2005,7 +1892,6 @@
 
 func libc_gettimeofday_trampoline()
 
-//go:linkname libc_gettimeofday libc_gettimeofday
 //go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -2016,7 +1902,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_lstat64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_lstat64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -2025,7 +1911,6 @@
 
 func libc_lstat64_trampoline()
 
-//go:linkname libc_lstat64 libc_lstat64
 //go:cgo_import_dynamic libc_lstat64 lstat64 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -2036,7 +1921,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_stat64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_stat64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -2045,7 +1930,6 @@
 
 func libc_stat64_trampoline()
 
-//go:linkname libc_stat64 libc_stat64
 //go:cgo_import_dynamic libc_stat64 stat64 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -2056,7 +1940,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_statfs64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_statfs64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -2065,7 +1949,6 @@
 
 func libc_statfs64_trampoline()
 
-//go:linkname libc_statfs64 libc_statfs64
 //go:cgo_import_dynamic libc_statfs64 statfs64 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -2076,7 +1959,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall6(funcPC(libc_fstatat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_fstatat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -2085,14 +1968,13 @@
 
 func libc_fstatat64_trampoline()
 
-//go:linkname libc_fstatat64 libc_fstatat64
 //go:cgo_import_dynamic libc_fstatat64 fstatat64 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 //go:nosplit
 func ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -2101,5 +1983,4 @@
 
 func libc_ptrace_trampoline()
 
-//go:linkname libc_ptrace libc_ptrace
 //go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
diff --git a/src/syscall/zsyscall_darwin_arm64.go b/src/syscall/zsyscall_darwin_arm64.go
index ede0091..5ae0967 100644
--- a/src/syscall/zsyscall_darwin_arm64.go
+++ b/src/syscall/zsyscall_darwin_arm64.go
@@ -1,16 +1,18 @@
 // mksyscall.pl -darwin -tags darwin,arm64 syscall_bsd.go syscall_darwin.go syscall_darwin_arm64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build darwin && arm64
 // +build darwin,arm64
 
 package syscall
 
 import "unsafe"
+import "internal/abi"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -20,13 +22,12 @@
 
 func libc_getgroups_trampoline()
 
-//go:linkname libc_getgroups libc_getgroups
 //go:cgo_import_dynamic libc_getgroups getgroups "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -35,13 +36,12 @@
 
 func libc_setgroups_trampoline()
 
-//go:linkname libc_setgroups libc_setgroups
 //go:cgo_import_dynamic libc_setgroups setgroups "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := syscall6(funcPC(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -51,13 +51,12 @@
 
 func libc_wait4_trampoline()
 
-//go:linkname libc_wait4 libc_wait4
 //go:cgo_import_dynamic libc_wait4 wait4 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -67,13 +66,12 @@
 
 func libc_accept_trampoline()
 
-//go:linkname libc_accept libc_accept
 //go:cgo_import_dynamic libc_accept accept "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall(funcPC(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -82,13 +80,12 @@
 
 func libc_bind_trampoline()
 
-//go:linkname libc_bind libc_bind
 //go:cgo_import_dynamic libc_bind bind "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall(funcPC(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -97,13 +94,12 @@
 
 func libc_connect_trampoline()
 
-//go:linkname libc_connect libc_connect
 //go:cgo_import_dynamic libc_connect connect "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -113,13 +109,12 @@
 
 func libc_socket_trampoline()
 
-//go:linkname libc_socket libc_socket
 //go:cgo_import_dynamic libc_socket socket "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -128,13 +123,12 @@
 
 func libc_getsockopt_trampoline()
 
-//go:linkname libc_getsockopt libc_getsockopt
 //go:cgo_import_dynamic libc_getsockopt getsockopt "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -143,13 +137,12 @@
 
 func libc_setsockopt_trampoline()
 
-//go:linkname libc_setsockopt libc_setsockopt
 //go:cgo_import_dynamic libc_setsockopt setsockopt "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -158,13 +151,12 @@
 
 func libc_getpeername_trampoline()
 
-//go:linkname libc_getpeername libc_getpeername
 //go:cgo_import_dynamic libc_getpeername getpeername "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -173,13 +165,12 @@
 
 func libc_getsockname_trampoline()
 
-//go:linkname libc_getsockname libc_getsockname
 //go:cgo_import_dynamic libc_getsockname getsockname "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -188,13 +179,12 @@
 
 func libc_shutdown_trampoline()
 
-//go:linkname libc_shutdown libc_shutdown
 //go:cgo_import_dynamic libc_shutdown shutdown "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := rawSyscall6(funcPC(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := rawSyscall6(abi.FuncPCABI0(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -203,7 +193,6 @@
 
 func libc_socketpair_trampoline()
 
-//go:linkname libc_socketpair libc_socketpair
 //go:cgo_import_dynamic libc_socketpair socketpair "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -215,7 +204,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall6(funcPC(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -225,7 +214,6 @@
 
 func libc_recvfrom_trampoline()
 
-//go:linkname libc_recvfrom libc_recvfrom
 //go:cgo_import_dynamic libc_recvfrom recvfrom "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -237,7 +225,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall6(funcPC(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -246,13 +234,12 @@
 
 func libc_sendto_trampoline()
 
-//go:linkname libc_sendto libc_sendto
 //go:cgo_import_dynamic libc_sendto sendto "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -262,13 +249,12 @@
 
 func libc_recvmsg_trampoline()
 
-//go:linkname libc_recvmsg libc_recvmsg
 //go:cgo_import_dynamic libc_recvmsg recvmsg "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -278,13 +264,12 @@
 
 func libc_sendmsg_trampoline()
 
-//go:linkname libc_sendmsg libc_sendmsg
 //go:cgo_import_dynamic libc_sendmsg sendmsg "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := syscall6(funcPC(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -294,7 +279,6 @@
 
 func libc_kevent_trampoline()
 
-//go:linkname libc_kevent libc_kevent
 //go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -305,7 +289,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -314,13 +298,12 @@
 
 func libc_utimes_trampoline()
 
-//go:linkname libc_utimes libc_utimes
 //go:cgo_import_dynamic libc_utimes utimes "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := syscall(funcPC(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -329,13 +312,12 @@
 
 func libc_futimes_trampoline()
 
-//go:linkname libc_futimes libc_futimes
 //go:cgo_import_dynamic libc_futimes futimes "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -345,13 +327,12 @@
 
 func libc_fcntl_trampoline()
 
-//go:linkname libc_fcntl libc_fcntl
 //go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pipe(p *[2]int32) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_pipe_trampoline), uintptr(unsafe.Pointer(p)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_pipe_trampoline), uintptr(unsafe.Pointer(p)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -360,13 +341,12 @@
 
 func libc_pipe_trampoline()
 
-//go:linkname libc_pipe libc_pipe
 //go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kill(pid int, signum int, posix int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_kill_trampoline), uintptr(pid), uintptr(signum), uintptr(posix))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_kill_trampoline), uintptr(pid), uintptr(signum), uintptr(posix))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -375,7 +355,6 @@
 
 func libc_kill_trampoline()
 
-//go:linkname libc_kill libc_kill
 //go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -386,7 +365,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -395,13 +374,12 @@
 
 func libc_access_trampoline()
 
-//go:linkname libc_access libc_access
 //go:cgo_import_dynamic libc_access access "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := syscall(funcPC(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -410,7 +388,6 @@
 
 func libc_adjtime_trampoline()
 
-//go:linkname libc_adjtime libc_adjtime
 //go:cgo_import_dynamic libc_adjtime adjtime "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -421,7 +398,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -430,7 +407,6 @@
 
 func libc_chdir_trampoline()
 
-//go:linkname libc_chdir libc_chdir
 //go:cgo_import_dynamic libc_chdir chdir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -441,7 +417,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -450,7 +426,6 @@
 
 func libc_chflags_trampoline()
 
-//go:linkname libc_chflags libc_chflags
 //go:cgo_import_dynamic libc_chflags chflags "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -461,7 +436,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -470,7 +445,6 @@
 
 func libc_chmod_trampoline()
 
-//go:linkname libc_chmod libc_chmod
 //go:cgo_import_dynamic libc_chmod chmod "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -481,7 +455,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -490,7 +464,6 @@
 
 func libc_chown_trampoline()
 
-//go:linkname libc_chown libc_chown
 //go:cgo_import_dynamic libc_chown chown "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -501,7 +474,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -510,13 +483,12 @@
 
 func libc_chroot_trampoline()
 
-//go:linkname libc_chroot libc_chroot
 //go:cgo_import_dynamic libc_chroot chroot "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_close_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -525,13 +497,12 @@
 
 func libc_close_trampoline()
 
-//go:linkname libc_close libc_close
 //go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func closedir(dir uintptr) (err error) {
-	_, _, e1 := syscall(funcPC(libc_closedir_trampoline), uintptr(dir), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_closedir_trampoline), uintptr(dir), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -540,13 +511,12 @@
 
 func libc_closedir_trampoline()
 
-//go:linkname libc_closedir libc_closedir
 //go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_dup_trampoline), uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -556,13 +526,12 @@
 
 func libc_dup_trampoline()
 
-//go:linkname libc_dup libc_dup
 //go:cgo_import_dynamic libc_dup dup "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -571,7 +540,6 @@
 
 func libc_dup2_trampoline()
 
-//go:linkname libc_dup2 libc_dup2
 //go:cgo_import_dynamic libc_dup2 dup2 "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -587,7 +555,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_exchangedata_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_exchangedata_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -596,13 +564,12 @@
 
 func libc_exchangedata_trampoline()
 
-//go:linkname libc_exchangedata libc_exchangedata
 //go:cgo_import_dynamic libc_exchangedata exchangedata "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchdir_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchdir_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -611,13 +578,12 @@
 
 func libc_fchdir_trampoline()
 
-//go:linkname libc_fchdir libc_fchdir
 //go:cgo_import_dynamic libc_fchdir fchdir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -626,13 +592,12 @@
 
 func libc_fchflags_trampoline()
 
-//go:linkname libc_fchflags libc_fchflags
 //go:cgo_import_dynamic libc_fchflags fchflags "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -641,13 +606,12 @@
 
 func libc_fchmod_trampoline()
 
-//go:linkname libc_fchmod libc_fchmod
 //go:cgo_import_dynamic libc_fchmod fchmod "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -656,13 +620,12 @@
 
 func libc_fchown_trampoline()
 
-//go:linkname libc_fchown libc_fchown
 //go:cgo_import_dynamic libc_fchown fchown "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -671,13 +634,12 @@
 
 func libc_flock_trampoline()
 
-//go:linkname libc_flock libc_flock
 //go:cgo_import_dynamic libc_flock flock "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -687,13 +649,12 @@
 
 func libc_fpathconf_trampoline()
 
-//go:linkname libc_fpathconf libc_fpathconf
 //go:cgo_import_dynamic libc_fpathconf fpathconf "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fsync_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fsync_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -702,13 +663,12 @@
 
 func libc_fsync_trampoline()
 
-//go:linkname libc_fsync libc_fsync
 //go:cgo_import_dynamic libc_fsync fsync "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := syscall(funcPC(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -717,65 +677,60 @@
 
 func libc_ftruncate_trampoline()
 
-//go:linkname libc_ftruncate libc_ftruncate
 //go:cgo_import_dynamic libc_ftruncate ftruncate "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getdtablesize() (size int) {
-	r0, _, _ := syscall(funcPC(libc_getdtablesize_trampoline), 0, 0, 0)
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_getdtablesize_trampoline), 0, 0, 0)
 	size = int(r0)
 	return
 }
 
 func libc_getdtablesize_trampoline()
 
-//go:linkname libc_getdtablesize libc_getdtablesize
 //go:cgo_import_dynamic libc_getdtablesize getdtablesize "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getegid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getegid_trampoline), 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
 func libc_getegid_trampoline()
 
-//go:linkname libc_getegid libc_getegid
 //go:cgo_import_dynamic libc_getegid getegid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_geteuid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_geteuid_trampoline), 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
 func libc_geteuid_trampoline()
 
-//go:linkname libc_geteuid libc_geteuid
 //go:cgo_import_dynamic libc_geteuid geteuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getgid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getgid_trampoline), 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
 func libc_getgid_trampoline()
 
-//go:linkname libc_getgid libc_getgid
 //go:cgo_import_dynamic libc_getgid getgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_getpgid_trampoline), uintptr(pid), 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpgid_trampoline), uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -785,52 +740,48 @@
 
 func libc_getpgid_trampoline()
 
-//go:linkname libc_getpgid libc_getpgid
 //go:cgo_import_dynamic libc_getpgid getpgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getpgrp_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpgrp_trampoline), 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
 func libc_getpgrp_trampoline()
 
-//go:linkname libc_getpgrp libc_getpgrp
 //go:cgo_import_dynamic libc_getpgrp getpgrp "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getpid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
 func libc_getpid_trampoline()
 
-//go:linkname libc_getpid libc_getpid
 //go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getppid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getppid_trampoline), 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
 func libc_getppid_trampoline()
 
-//go:linkname libc_getppid libc_getppid
 //go:cgo_import_dynamic libc_getppid getppid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -840,13 +791,12 @@
 
 func libc_getpriority_trampoline()
 
-//go:linkname libc_getpriority libc_getpriority
 //go:cgo_import_dynamic libc_getpriority getpriority "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -855,13 +805,12 @@
 
 func libc_getrlimit_trampoline()
 
-//go:linkname libc_getrlimit libc_getrlimit
 //go:cgo_import_dynamic libc_getrlimit getrlimit "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -870,13 +819,12 @@
 
 func libc_getrusage_trampoline()
 
-//go:linkname libc_getrusage libc_getrusage
 //go:cgo_import_dynamic libc_getrusage getrusage "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_getsid_trampoline), uintptr(pid), 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsid_trampoline), uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -886,39 +834,36 @@
 
 func libc_getsid_trampoline()
 
-//go:linkname libc_getsid libc_getsid
 //go:cgo_import_dynamic libc_getsid getsid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getuid_trampoline), 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
 func libc_getuid_trampoline()
 
-//go:linkname libc_getuid libc_getuid
 //go:cgo_import_dynamic libc_getuid getuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := rawSyscall(funcPC(libc_issetugid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_issetugid_trampoline), 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
 func libc_issetugid_trampoline()
 
-//go:linkname libc_issetugid libc_issetugid
 //go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_kqueue_trampoline), 0, 0, 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_kqueue_trampoline), 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -928,7 +873,6 @@
 
 func libc_kqueue_trampoline()
 
-//go:linkname libc_kqueue libc_kqueue
 //go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -939,7 +883,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -948,7 +892,6 @@
 
 func libc_lchown_trampoline()
 
-//go:linkname libc_lchown libc_lchown
 //go:cgo_import_dynamic libc_lchown lchown "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -964,7 +907,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -973,13 +916,12 @@
 
 func libc_link_trampoline()
 
-//go:linkname libc_link libc_link
 //go:cgo_import_dynamic libc_link link "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -988,7 +930,6 @@
 
 func libc_listen_trampoline()
 
-//go:linkname libc_listen libc_listen
 //go:cgo_import_dynamic libc_listen listen "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -999,7 +940,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1008,7 +949,6 @@
 
 func libc_mkdir_trampoline()
 
-//go:linkname libc_mkdir libc_mkdir
 //go:cgo_import_dynamic libc_mkdir mkdir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1019,7 +959,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1028,7 +968,6 @@
 
 func libc_mkfifo_trampoline()
 
-//go:linkname libc_mkfifo libc_mkfifo
 //go:cgo_import_dynamic libc_mkfifo mkfifo "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1039,7 +978,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1048,7 +987,6 @@
 
 func libc_mknod_trampoline()
 
-//go:linkname libc_mknod libc_mknod
 //go:cgo_import_dynamic libc_mknod mknod "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1060,7 +998,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall(funcPC(libc_mlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1069,13 +1007,12 @@
 
 func libc_mlock_trampoline()
 
-//go:linkname libc_mlock libc_mlock
 //go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlockall(flags int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_mlockall_trampoline), uintptr(flags), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mlockall_trampoline), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1084,7 +1021,6 @@
 
 func libc_mlockall_trampoline()
 
-//go:linkname libc_mlockall libc_mlockall
 //go:cgo_import_dynamic libc_mlockall mlockall "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1096,7 +1032,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall(funcPC(libc_mprotect_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mprotect_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(prot))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1105,7 +1041,6 @@
 
 func libc_mprotect_trampoline()
 
-//go:linkname libc_mprotect libc_mprotect
 //go:cgo_import_dynamic libc_mprotect mprotect "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1117,7 +1052,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall(funcPC(libc_munlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_munlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1126,13 +1061,12 @@
 
 func libc_munlock_trampoline()
 
-//go:linkname libc_munlock libc_munlock
 //go:cgo_import_dynamic libc_munlock munlock "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlockall() (err error) {
-	_, _, e1 := syscall(funcPC(libc_munlockall_trampoline), 0, 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_munlockall_trampoline), 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1141,7 +1075,6 @@
 
 func libc_munlockall_trampoline()
 
-//go:linkname libc_munlockall libc_munlockall
 //go:cgo_import_dynamic libc_munlockall munlockall "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1152,7 +1085,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall(funcPC(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1162,7 +1095,6 @@
 
 func libc_open_trampoline()
 
-//go:linkname libc_open libc_open
 //go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1173,7 +1105,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall(funcPC(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1183,7 +1115,6 @@
 
 func libc_pathconf_trampoline()
 
-//go:linkname libc_pathconf libc_pathconf
 //go:cgo_import_dynamic libc_pathconf pathconf "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1195,7 +1126,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall6(funcPC(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1205,7 +1136,6 @@
 
 func libc_pread_trampoline()
 
-//go:linkname libc_pread libc_pread
 //go:cgo_import_dynamic libc_pread pread "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1217,7 +1147,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall6(funcPC(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1227,7 +1157,6 @@
 
 func libc_pwrite_trampoline()
 
-//go:linkname libc_pwrite libc_pwrite
 //go:cgo_import_dynamic libc_pwrite pwrite "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1239,7 +1168,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1249,20 +1178,18 @@
 
 func libc_read_trampoline()
 
-//go:linkname libc_read libc_read
 //go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
-	r0, _, _ := syscall(funcPC(libc_readdir_r_trampoline), uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_readdir_r_trampoline), uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
 	res = Errno(r0)
 	return
 }
 
 func libc_readdir_r_trampoline()
 
-//go:linkname libc_readdir_r libc_readdir_r
 //go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1279,7 +1206,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1289,7 +1216,6 @@
 
 func libc_readlink_trampoline()
 
-//go:linkname libc_readlink libc_readlink
 //go:cgo_import_dynamic libc_readlink readlink "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1305,7 +1231,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1314,7 +1240,6 @@
 
 func libc_rename_trampoline()
 
-//go:linkname libc_rename libc_rename
 //go:cgo_import_dynamic libc_rename rename "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1325,7 +1250,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1334,7 +1259,6 @@
 
 func libc_revoke_trampoline()
 
-//go:linkname libc_revoke libc_revoke
 //go:cgo_import_dynamic libc_revoke revoke "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1345,7 +1269,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1354,13 +1278,12 @@
 
 func libc_rmdir_trampoline()
 
-//go:linkname libc_rmdir libc_rmdir
 //go:cgo_import_dynamic libc_rmdir rmdir "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := syscallX(funcPC(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(whence))
+	r0, _, e1 := syscallX(abi.FuncPCABI0(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(whence))
 	newoffset = int64(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1370,13 +1293,12 @@
 
 func libc_lseek_trampoline()
 
-//go:linkname libc_lseek libc_lseek
 //go:cgo_import_dynamic libc_lseek lseek "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_select_trampoline), uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_select_trampoline), uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1385,13 +1307,12 @@
 
 func libc_select_trampoline()
 
-//go:linkname libc_select libc_select
 //go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_setegid_trampoline), uintptr(egid), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setegid_trampoline), uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1400,13 +1321,12 @@
 
 func libc_setegid_trampoline()
 
-//go:linkname libc_setegid libc_setegid
 //go:cgo_import_dynamic libc_setegid setegid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_seteuid_trampoline), uintptr(euid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_seteuid_trampoline), uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1415,13 +1335,12 @@
 
 func libc_seteuid_trampoline()
 
-//go:linkname libc_seteuid libc_seteuid
 //go:cgo_import_dynamic libc_seteuid seteuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setgid_trampoline), uintptr(gid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1430,7 +1349,6 @@
 
 func libc_setgid_trampoline()
 
-//go:linkname libc_setgid libc_setgid
 //go:cgo_import_dynamic libc_setgid setgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1441,7 +1359,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1450,13 +1368,12 @@
 
 func libc_setlogin_trampoline()
 
-//go:linkname libc_setlogin libc_setlogin
 //go:cgo_import_dynamic libc_setlogin setlogin "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1465,13 +1382,12 @@
 
 func libc_setpgid_trampoline()
 
-//go:linkname libc_setpgid libc_setpgid
 //go:cgo_import_dynamic libc_setpgid setpgid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1480,13 +1396,12 @@
 
 func libc_setpriority_trampoline()
 
-//go:linkname libc_setpriority libc_setpriority
 //go:cgo_import_dynamic libc_setpriority setpriority "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setprivexec(flag int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_setprivexec_trampoline), uintptr(flag), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setprivexec_trampoline), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1495,13 +1410,12 @@
 
 func libc_setprivexec_trampoline()
 
-//go:linkname libc_setprivexec libc_setprivexec
 //go:cgo_import_dynamic libc_setprivexec setprivexec "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1510,13 +1424,12 @@
 
 func libc_setregid_trampoline()
 
-//go:linkname libc_setregid libc_setregid
 //go:cgo_import_dynamic libc_setregid setregid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1525,13 +1438,12 @@
 
 func libc_setreuid_trampoline()
 
-//go:linkname libc_setreuid libc_setreuid
 //go:cgo_import_dynamic libc_setreuid setreuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1540,13 +1452,12 @@
 
 func libc_setrlimit_trampoline()
 
-//go:linkname libc_setrlimit libc_setrlimit
 //go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_setsid_trampoline), 0, 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1556,13 +1467,12 @@
 
 func libc_setsid_trampoline()
 
-//go:linkname libc_setsid libc_setsid
 //go:cgo_import_dynamic libc_setsid setsid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1571,13 +1481,12 @@
 
 func libc_settimeofday_trampoline()
 
-//go:linkname libc_settimeofday libc_settimeofday
 //go:cgo_import_dynamic libc_settimeofday settimeofday "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setuid_trampoline), uintptr(uid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1586,7 +1495,6 @@
 
 func libc_setuid_trampoline()
 
-//go:linkname libc_setuid libc_setuid
 //go:cgo_import_dynamic libc_setuid setuid "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1602,7 +1510,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1611,13 +1519,12 @@
 
 func libc_symlink_trampoline()
 
-//go:linkname libc_symlink libc_symlink
 //go:cgo_import_dynamic libc_symlink symlink "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := syscall(funcPC(libc_sync_trampoline), 0, 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_sync_trampoline), 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1626,7 +1533,6 @@
 
 func libc_sync_trampoline()
 
-//go:linkname libc_sync libc_sync
 //go:cgo_import_dynamic libc_sync sync "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1637,7 +1543,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1646,20 +1552,18 @@
 
 func libc_truncate_trampoline()
 
-//go:linkname libc_truncate libc_truncate
 //go:cgo_import_dynamic libc_truncate truncate "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := syscall(funcPC(libc_umask_trampoline), uintptr(newmask), 0, 0)
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_umask_trampoline), uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
 func libc_umask_trampoline()
 
-//go:linkname libc_umask libc_umask
 //go:cgo_import_dynamic libc_umask umask "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1670,7 +1574,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_undelete_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_undelete_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1679,7 +1583,6 @@
 
 func libc_undelete_trampoline()
 
-//go:linkname libc_undelete libc_undelete
 //go:cgo_import_dynamic libc_undelete undelete "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1690,7 +1593,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1699,7 +1602,6 @@
 
 func libc_unlink_trampoline()
 
-//go:linkname libc_unlink libc_unlink
 //go:cgo_import_dynamic libc_unlink unlink "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1710,7 +1612,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1719,7 +1621,6 @@
 
 func libc_unmount_trampoline()
 
-//go:linkname libc_unmount libc_unmount
 //go:cgo_import_dynamic libc_unmount unmount "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1731,7 +1632,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1741,7 +1642,6 @@
 
 func libc_write_trampoline()
 
-//go:linkname libc_write libc_write
 //go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1753,7 +1653,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscallX(funcPC(libc_writev_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
+	r0, _, e1 := syscallX(abi.FuncPCABI0(libc_writev_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
 	cnt = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1763,13 +1663,12 @@
 
 func libc_writev_trampoline()
 
-//go:linkname libc_writev libc_writev
 //go:cgo_import_dynamic libc_writev writev "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := syscall6X(funcPC(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	r0, _, e1 := syscall6X(abi.FuncPCABI0(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1779,13 +1678,12 @@
 
 func libc_mmap_trampoline()
 
-//go:linkname libc_mmap libc_mmap
 //go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := syscall(funcPC(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1794,13 +1692,12 @@
 
 func libc_munmap_trampoline()
 
-//go:linkname libc_munmap libc_munmap
 //go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fork() (pid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_fork_trampoline), 0, 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1810,13 +1707,12 @@
 
 func libc_fork_trampoline()
 
-//go:linkname libc_fork libc_fork
 //go:cgo_import_dynamic libc_fork fork "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctl(fd int, req int, arg int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1825,13 +1721,12 @@
 
 func libc_ioctl_trampoline()
 
-//go:linkname libc_ioctl libc_ioctl
 //go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1841,7 +1736,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func execve(path *byte, argv **byte, envp **byte) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_execve_trampoline), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(argv)), uintptr(unsafe.Pointer(envp)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_execve_trampoline), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(argv)), uintptr(unsafe.Pointer(envp)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1850,13 +1745,12 @@
 
 func libc_execve_trampoline()
 
-//go:linkname libc_execve libc_execve
 //go:cgo_import_dynamic libc_execve execve "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func exit(res int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_exit_trampoline), uintptr(res), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), uintptr(res), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1865,7 +1759,6 @@
 
 func libc_exit_trampoline()
 
-//go:linkname libc_exit libc_exit
 //go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1877,7 +1770,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall6(funcPC(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1886,13 +1779,12 @@
 
 func libc_sysctl_trampoline()
 
-//go:linkname libc_sysctl libc_sysctl
 //go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1908,7 +1800,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_unlinkat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unlinkat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1917,7 +1809,6 @@
 
 func libc_unlinkat_trampoline()
 
-//go:linkname libc_unlinkat libc_unlinkat
 //go:cgo_import_dynamic libc_unlinkat unlinkat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1928,7 +1819,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall6(funcPC(libc_openat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(perm), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_openat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(perm), 0, 0)
 	fdret = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1938,7 +1829,6 @@
 
 func libc_openat_trampoline()
 
-//go:linkname libc_openat libc_openat
 //go:cgo_import_dynamic libc_openat openat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1950,7 +1840,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1960,13 +1850,12 @@
 
 func libc_getcwd_trampoline()
 
-//go:linkname libc_getcwd libc_getcwd
 //go:cgo_import_dynamic libc_getcwd getcwd "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1975,13 +1864,12 @@
 
 func libc_fstat_trampoline()
 
-//go:linkname libc_fstat libc_fstat
 //go:cgo_import_dynamic libc_fstat fstat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fstatfs_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fstatfs_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1990,13 +1878,12 @@
 
 func libc_fstatfs_trampoline()
 
-//go:linkname libc_fstatfs libc_fstatfs
 //go:cgo_import_dynamic libc_fstatfs fstatfs "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tp *Timeval) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -2005,7 +1892,6 @@
 
 func libc_gettimeofday_trampoline()
 
-//go:linkname libc_gettimeofday libc_gettimeofday
 //go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -2016,7 +1902,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_lstat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_lstat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -2025,7 +1911,6 @@
 
 func libc_lstat_trampoline()
 
-//go:linkname libc_lstat libc_lstat
 //go:cgo_import_dynamic libc_lstat lstat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -2036,7 +1921,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_stat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_stat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -2045,7 +1930,6 @@
 
 func libc_stat_trampoline()
 
-//go:linkname libc_stat libc_stat
 //go:cgo_import_dynamic libc_stat stat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -2056,7 +1940,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_statfs_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_statfs_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -2065,7 +1949,6 @@
 
 func libc_statfs_trampoline()
 
-//go:linkname libc_statfs libc_statfs
 //go:cgo_import_dynamic libc_statfs statfs "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -2076,7 +1959,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall6(funcPC(libc_fstatat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_fstatat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -2085,14 +1968,13 @@
 
 func libc_fstatat_trampoline()
 
-//go:linkname libc_fstatat libc_fstatat
 //go:cgo_import_dynamic libc_fstatat fstatat "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 //go:nosplit
 func ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -2101,5 +1983,4 @@
 
 func libc_ptrace_trampoline()
 
-//go:linkname libc_ptrace libc_ptrace
 //go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
diff --git a/src/syscall/zsyscall_dragonfly_amd64.go b/src/syscall/zsyscall_dragonfly_amd64.go
index 578b5a3..aa327c0 100644
--- a/src/syscall/zsyscall_dragonfly_amd64.go
+++ b/src/syscall/zsyscall_dragonfly_amd64.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -dragonfly -tags dragonfly,amd64 syscall_bsd.go syscall_dragonfly.go syscall_dragonfly_amd64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build dragonfly && amd64
 // +build dragonfly,amd64
 
 package syscall
@@ -273,6 +274,18 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func pipe2(p *[2]_C_int, flags int) (r int, w int, err error) {
+	r0, r1, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 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 extpread(fd int, p []byte, flags int, offset int64) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(p) > 0 {
diff --git a/src/syscall/zsyscall_freebsd_386.go b/src/syscall/zsyscall_freebsd_386.go
index ddc265f..7137d66 100644
--- a/src/syscall/zsyscall_freebsd_386.go
+++ b/src/syscall/zsyscall_freebsd_386.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -l32 -tags freebsd,386 syscall_bsd.go syscall_freebsd.go syscall_freebsd_386.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build freebsd && 386
 // +build freebsd,386
 
 package syscall
diff --git a/src/syscall/zsyscall_freebsd_amd64.go b/src/syscall/zsyscall_freebsd_amd64.go
index a0f7952..d721daf 100644
--- a/src/syscall/zsyscall_freebsd_amd64.go
+++ b/src/syscall/zsyscall_freebsd_amd64.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -tags freebsd,amd64 syscall_bsd.go syscall_freebsd.go syscall_freebsd_amd64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build freebsd && amd64
 // +build freebsd,amd64
 
 package syscall
diff --git a/src/syscall/zsyscall_freebsd_arm.go b/src/syscall/zsyscall_freebsd_arm.go
index 2cd23d3..d9dbea9 100644
--- a/src/syscall/zsyscall_freebsd_arm.go
+++ b/src/syscall/zsyscall_freebsd_arm.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -l32 -arm -tags freebsd,arm syscall_bsd.go syscall_freebsd.go syscall_freebsd_arm.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build freebsd && arm
 // +build freebsd,arm
 
 package syscall
diff --git a/src/syscall/zsyscall_freebsd_arm64.go b/src/syscall/zsyscall_freebsd_arm64.go
index 1b17738..a24f011 100644
--- a/src/syscall/zsyscall_freebsd_arm64.go
+++ b/src/syscall/zsyscall_freebsd_arm64.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -tags freebsd,arm64 syscall_bsd.go syscall_freebsd.go syscall_freebsd_arm64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build freebsd && arm64
 // +build freebsd,arm64
 
 package syscall
diff --git a/src/syscall/zsyscall_linux_386.go b/src/syscall/zsyscall_linux_386.go
index 5a749ff..ac822d6 100644
--- a/src/syscall/zsyscall_linux_386.go
+++ b/src/syscall/zsyscall_linux_386.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -l32 -tags linux,386 syscall_linux.go syscall_linux_386.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build linux && 386
 // +build linux,386
 
 package syscall
diff --git a/src/syscall/zsyscall_linux_amd64.go b/src/syscall/zsyscall_linux_amd64.go
index 34b624c..ed37fa8 100644
--- a/src/syscall/zsyscall_linux_amd64.go
+++ b/src/syscall/zsyscall_linux_amd64.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -tags linux,amd64 syscall_linux.go syscall_linux_amd64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build linux && amd64
 // +build linux,amd64
 
 package syscall
diff --git a/src/syscall/zsyscall_linux_arm.go b/src/syscall/zsyscall_linux_arm.go
index 4d13376..213aaf3 100644
--- a/src/syscall/zsyscall_linux_arm.go
+++ b/src/syscall/zsyscall_linux_arm.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -l32 -arm -tags linux,arm syscall_linux.go syscall_linux_arm.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build linux && arm
 // +build linux,arm
 
 package syscall
diff --git a/src/syscall/zsyscall_linux_arm64.go b/src/syscall/zsyscall_linux_arm64.go
index e7f7b7e..e2f9c0f 100644
--- a/src/syscall/zsyscall_linux_arm64.go
+++ b/src/syscall/zsyscall_linux_arm64.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -tags linux,arm64 syscall_linux.go syscall_linux_arm64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build linux && arm64
 // +build linux,arm64
 
 package syscall
diff --git a/src/syscall/zsyscall_linux_mips.go b/src/syscall/zsyscall_linux_mips.go
index a8522dc..617c2f5 100644
--- a/src/syscall/zsyscall_linux_mips.go
+++ b/src/syscall/zsyscall_linux_mips.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -b32 -arm -tags linux,mips syscall_linux.go syscall_linux_mipsx.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build linux && mips
 // +build linux,mips
 
 package syscall
diff --git a/src/syscall/zsyscall_linux_mips64.go b/src/syscall/zsyscall_linux_mips64.go
index 1219fcc..793d4b9 100644
--- a/src/syscall/zsyscall_linux_mips64.go
+++ b/src/syscall/zsyscall_linux_mips64.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -tags linux,mips64 syscall_linux.go syscall_linux_mips64x.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build linux && mips64
 // +build linux,mips64
 
 package syscall
diff --git a/src/syscall/zsyscall_linux_mips64le.go b/src/syscall/zsyscall_linux_mips64le.go
index c3737bf..54e1760 100644
--- a/src/syscall/zsyscall_linux_mips64le.go
+++ b/src/syscall/zsyscall_linux_mips64le.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -tags linux,mips64le syscall_linux.go syscall_linux_mips64x.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build linux && mips64le
 // +build linux,mips64le
 
 package syscall
diff --git a/src/syscall/zsyscall_linux_mipsle.go b/src/syscall/zsyscall_linux_mipsle.go
index 5006f4a..ba7e211 100644
--- a/src/syscall/zsyscall_linux_mipsle.go
+++ b/src/syscall/zsyscall_linux_mipsle.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -l32 -arm -tags linux,mipsle syscall_linux.go syscall_linux_mipsx.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build linux && mipsle
 // +build linux,mipsle
 
 package syscall
diff --git a/src/syscall/zsyscall_linux_ppc64.go b/src/syscall/zsyscall_linux_ppc64.go
index 323be98..c343772 100644
--- a/src/syscall/zsyscall_linux_ppc64.go
+++ b/src/syscall/zsyscall_linux_ppc64.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -tags linux,ppc64 syscall_linux.go syscall_linux_ppc64x.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build linux && ppc64
 // +build linux,ppc64
 
 package syscall
diff --git a/src/syscall/zsyscall_linux_ppc64le.go b/src/syscall/zsyscall_linux_ppc64le.go
index 99aea6b..acc34a7 100644
--- a/src/syscall/zsyscall_linux_ppc64le.go
+++ b/src/syscall/zsyscall_linux_ppc64le.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -tags linux,ppc64le syscall_linux.go syscall_linux_ppc64x.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build linux && ppc64le
 // +build linux,ppc64le
 
 package syscall
diff --git a/src/syscall/zsyscall_linux_riscv64.go b/src/syscall/zsyscall_linux_riscv64.go
index afa8945..d662d78 100644
--- a/src/syscall/zsyscall_linux_riscv64.go
+++ b/src/syscall/zsyscall_linux_riscv64.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -tags linux,riscv64 syscall_linux.go syscall_linux_riscv64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build linux && riscv64
 // +build linux,riscv64
 
 package syscall
diff --git a/src/syscall/zsyscall_linux_s390x.go b/src/syscall/zsyscall_linux_s390x.go
index 5717206..20f8c61 100644
--- a/src/syscall/zsyscall_linux_s390x.go
+++ b/src/syscall/zsyscall_linux_s390x.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -tags linux,s390x syscall_linux.go syscall_linux_s390x.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build linux && s390x
 // +build linux,s390x
 
 package syscall
diff --git a/src/syscall/zsyscall_netbsd_386.go b/src/syscall/zsyscall_netbsd_386.go
index 7e02100..07ff5fb 100644
--- a/src/syscall/zsyscall_netbsd_386.go
+++ b/src/syscall/zsyscall_netbsd_386.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -l32 -netbsd -tags netbsd,386 syscall_bsd.go syscall_netbsd.go syscall_netbsd_386.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build netbsd && 386
 // +build netbsd,386
 
 package syscall
diff --git a/src/syscall/zsyscall_netbsd_amd64.go b/src/syscall/zsyscall_netbsd_amd64.go
index e9ee790..ffb4e05 100644
--- a/src/syscall/zsyscall_netbsd_amd64.go
+++ b/src/syscall/zsyscall_netbsd_amd64.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -netbsd -tags netbsd,amd64 syscall_bsd.go syscall_netbsd.go syscall_netbsd_amd64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build netbsd && amd64
 // +build netbsd,amd64
 
 package syscall
diff --git a/src/syscall/zsyscall_netbsd_arm.go b/src/syscall/zsyscall_netbsd_arm.go
index 37438b0..37df77e 100644
--- a/src/syscall/zsyscall_netbsd_arm.go
+++ b/src/syscall/zsyscall_netbsd_arm.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -l32 -netbsd -arm -tags netbsd,arm syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build netbsd && arm
 // +build netbsd,arm
 
 package syscall
diff --git a/src/syscall/zsyscall_netbsd_arm64.go b/src/syscall/zsyscall_netbsd_arm64.go
index 758f398..c5eb57a 100644
--- a/src/syscall/zsyscall_netbsd_arm64.go
+++ b/src/syscall/zsyscall_netbsd_arm64.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -netbsd -tags netbsd,arm64 syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build netbsd && arm64
 // +build netbsd,arm64
 
 package syscall
diff --git a/src/syscall/zsyscall_openbsd_386.go b/src/syscall/zsyscall_openbsd_386.go
index decd169..1ff5c95 100644
--- a/src/syscall/zsyscall_openbsd_386.go
+++ b/src/syscall/zsyscall_openbsd_386.go
@@ -1,16 +1,18 @@
-// mksyscall.pl -l32 -openbsd -tags openbsd,386 syscall_bsd.go syscall_openbsd.go syscall_openbsd_386.go
+// mksyscall.pl -l32 -openbsd -libc -tags openbsd,386 syscall_bsd.go syscall_openbsd.go syscall_openbsd_libc.go syscall_openbsd_386.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build openbsd && 386
 // +build openbsd,386
 
 package syscall
 
 import "unsafe"
+import "internal/abi"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -18,20 +20,28 @@
 	return
 }
 
+func libc_getgroups_trampoline()
+
+//go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setgroups_trampoline()
+
+//go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -39,10 +49,14 @@
 	return
 }
 
+func libc_wait4_trampoline()
+
+//go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -50,30 +64,42 @@
 	return
 }
 
+func libc_accept_trampoline()
+
+//go:cgo_import_dynamic libc_accept accept "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_bind_trampoline()
+
+//go:cgo_import_dynamic libc_bind bind "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_connect_trampoline()
+
+//go:cgo_import_dynamic libc_connect connect "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -81,66 +107,94 @@
 	return
 }
 
+func libc_socket_trampoline()
+
+//go:cgo_import_dynamic libc_socket socket "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_getsockopt_trampoline()
+
+//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setsockopt_trampoline()
+
+//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_getpeername_trampoline()
+
+//go:cgo_import_dynamic libc_getpeername getpeername "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_getsockname_trampoline()
+
+//go:cgo_import_dynamic libc_getsockname getsockname "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_shutdown_trampoline()
+
+//go:cgo_import_dynamic libc_shutdown shutdown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := rawSyscall6(abi.FuncPCABI0(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_socketpair_trampoline()
+
+//go:cgo_import_dynamic libc_socketpair socketpair "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
@@ -150,7 +204,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -158,6 +212,10 @@
 	return
 }
 
+func libc_recvfrom_trampoline()
+
+//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
@@ -167,17 +225,21 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_sendto_trampoline()
+
+//go:cgo_import_dynamic libc_sendto sendto "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -185,10 +247,14 @@
 	return
 }
 
+func libc_recvmsg_trampoline()
+
+//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -196,10 +262,14 @@
 	return
 }
 
+func libc_sendmsg_trampoline()
+
+//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -207,21 +277,9 @@
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func libc_kevent_trampoline()
 
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
+//go:cgo_import_dynamic libc_kevent kevent "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
@@ -231,27 +289,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_utimes_trampoline()
+
+//go:cgo_import_dynamic libc_utimes utimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_futimes_trampoline()
+
+//go:cgo_import_dynamic libc_futimes futimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -259,20 +325,28 @@
 	return
 }
 
+func libc_fcntl_trampoline()
+
+//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_pipe2_trampoline), uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_pipe2_trampoline()
+
+//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) {
-	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_accept4_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -280,6 +354,10 @@
 	return
 }
 
+func libc_accept4_trampoline()
+
+//go:cgo_import_dynamic libc_accept4 accept4 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getdents(fd int, buf []byte) (n int, err error) {
@@ -289,7 +367,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getdents_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -297,6 +375,10 @@
 	return
 }
 
+func libc_getdents_trampoline()
+
+//go:cgo_import_dynamic libc_getdents getdents "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Access(path string, mode uint32) (err error) {
@@ -305,23 +387,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_access_trampoline()
+
+//go:cgo_import_dynamic libc_access access "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_adjtime_trampoline()
+
+//go:cgo_import_dynamic libc_adjtime adjtime "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chdir(path string) (err error) {
@@ -330,13 +420,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_chdir_trampoline()
+
+//go:cgo_import_dynamic libc_chdir chdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chflags(path string, flags int) (err error) {
@@ -345,13 +439,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_chflags_trampoline()
+
+//go:cgo_import_dynamic libc_chflags chflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chmod(path string, mode uint32) (err error) {
@@ -360,13 +458,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_chmod_trampoline()
+
+//go:cgo_import_dynamic libc_chmod chmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chown(path string, uid int, gid int) (err error) {
@@ -375,13 +477,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_chown_trampoline()
+
+//go:cgo_import_dynamic libc_chown chown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chroot(path string) (err error) {
@@ -390,27 +496,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_chroot_trampoline()
+
+//go:cgo_import_dynamic libc_chroot chroot "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_close_trampoline()
+
+//go:cgo_import_dynamic libc_close close "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_dup_trampoline), uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -418,70 +532,98 @@
 	return
 }
 
+func libc_dup_trampoline()
+
+//go:cgo_import_dynamic libc_dup dup "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_dup2_trampoline()
+
+//go:cgo_import_dynamic libc_dup2 dup2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchdir_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fchdir_trampoline()
+
+//go:cgo_import_dynamic libc_fchdir fchdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fchflags_trampoline()
+
+//go:cgo_import_dynamic libc_fchflags fchflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fchmod_trampoline()
+
+//go:cgo_import_dynamic libc_fchmod fchmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fchown_trampoline()
+
+//go:cgo_import_dynamic libc_fchown fchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_flock_trampoline()
+
+//go:cgo_import_dynamic libc_flock flock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -489,74 +631,106 @@
 	return
 }
 
+func libc_fpathconf_trampoline()
+
+//go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fstat_trampoline()
+
+//go:cgo_import_dynamic libc_fstat fstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fstatfs_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fstatfs_trampoline()
+
+//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fsync_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fsync_trampoline()
+
+//go:cgo_import_dynamic libc_fsync fsync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), uintptr(length>>32))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_ftruncate_trampoline()
+
+//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getegid_trampoline), 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
+func libc_getegid_trampoline()
+
+//go:cgo_import_dynamic libc_getegid getegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_geteuid_trampoline), 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+func libc_geteuid_trampoline()
+
+//go:cgo_import_dynamic libc_geteuid geteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getgid_trampoline), 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
+func libc_getgid_trampoline()
+
+//go:cgo_import_dynamic libc_getgid getgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpgid_trampoline), uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -564,34 +738,50 @@
 	return
 }
 
+func libc_getpgid_trampoline()
+
+//go:cgo_import_dynamic libc_getpgid getpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpgrp_trampoline), 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
+func libc_getpgrp_trampoline()
+
+//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
+func libc_getpid_trampoline()
+
+//go:cgo_import_dynamic libc_getpid getpid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getppid_trampoline), 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
+func libc_getppid_trampoline()
+
+//go:cgo_import_dynamic libc_getppid getppid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -599,30 +789,42 @@
 	return
 }
 
+func libc_getpriority_trampoline()
+
+//go:cgo_import_dynamic libc_getpriority getpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_getrlimit_trampoline()
+
+//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_getrusage_trampoline()
+
+//go:cgo_import_dynamic libc_getrusage getrusage "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsid_trampoline), uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -630,46 +832,66 @@
 	return
 }
 
+func libc_getsid_trampoline()
+
+//go:cgo_import_dynamic libc_getsid getsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tv)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_gettimeofday_trampoline()
+
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getuid_trampoline), 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+func libc_getuid_trampoline()
+
+//go:cgo_import_dynamic libc_getuid getuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_issetugid_trampoline), 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
+func libc_issetugid_trampoline()
+
+//go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_kill_trampoline), uintptr(pid), uintptr(signum), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_kill_trampoline()
+
+//go:cgo_import_dynamic libc_kill kill "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_kqueue_trampoline), 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -677,6 +899,10 @@
 	return
 }
 
+func libc_kqueue_trampoline()
+
+//go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lchown(path string, uid int, gid int) (err error) {
@@ -685,13 +911,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_lchown_trampoline()
+
+//go:cgo_import_dynamic libc_lchown lchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Link(path string, link string) (err error) {
@@ -705,23 +935,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_link_trampoline()
+
+//go:cgo_import_dynamic libc_link link "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_listen_trampoline()
+
+//go:cgo_import_dynamic libc_listen listen "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lstat(path string, stat *Stat_t) (err error) {
@@ -730,13 +968,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_lstat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_lstat_trampoline()
+
+//go:cgo_import_dynamic libc_lstat lstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkdir(path string, mode uint32) (err error) {
@@ -745,13 +987,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_mkdir_trampoline()
+
+//go:cgo_import_dynamic libc_mkdir mkdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkfifo(path string, mode uint32) (err error) {
@@ -760,13 +1006,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_mkfifo_trampoline()
+
+//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mknod(path string, mode uint32, dev int) (err error) {
@@ -775,23 +1025,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_mknod_trampoline()
+
+//go:cgo_import_dynamic libc_mknod mknod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_nanosleep_trampoline), uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_nanosleep_trampoline()
+
+//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Open(path string, mode int, perm uint32) (fd int, err error) {
@@ -800,7 +1058,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -808,6 +1066,10 @@
 	return
 }
 
+func libc_open_trampoline()
+
+//go:cgo_import_dynamic libc_open open "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Pathconf(path string, name int) (val int, err error) {
@@ -816,7 +1078,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -824,6 +1086,10 @@
 	return
 }
 
+func libc_pathconf_trampoline()
+
+//go:cgo_import_dynamic libc_pathconf pathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Pread(fd int, p []byte, offset int64) (n int, err error) {
@@ -833,7 +1099,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -841,6 +1107,10 @@
 	return
 }
 
+func libc_pread_trampoline()
+
+//go:cgo_import_dynamic libc_pread pread "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
@@ -850,7 +1120,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -858,6 +1128,10 @@
 	return
 }
 
+func libc_pwrite_trampoline()
+
+//go:cgo_import_dynamic libc_pwrite pwrite "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func read(fd int, p []byte) (n int, err error) {
@@ -867,7 +1141,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -875,6 +1149,10 @@
 	return
 }
 
+func libc_read_trampoline()
+
+//go:cgo_import_dynamic libc_read read "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Readlink(path string, buf []byte) (n int, err error) {
@@ -889,7 +1167,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -897,6 +1175,10 @@
 	return
 }
 
+func libc_readlink_trampoline()
+
+//go:cgo_import_dynamic libc_readlink readlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rename(from string, to string) (err error) {
@@ -910,13 +1192,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_rename_trampoline()
+
+//go:cgo_import_dynamic libc_rename rename "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Revoke(path string) (err error) {
@@ -925,13 +1211,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_revoke_trampoline()
+
+//go:cgo_import_dynamic libc_revoke revoke "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rmdir(path string) (err error) {
@@ -940,64 +1230,73 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func libc_rmdir_trampoline()
 
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
-	newoffset = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
+//go:cgo_import_dynamic libc_rmdir rmdir "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_select_trampoline), uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_select_trampoline()
+
+//go:cgo_import_dynamic libc_select select "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setegid_trampoline), uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setegid_trampoline()
+
+//go:cgo_import_dynamic libc_setegid setegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_seteuid_trampoline), uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_seteuid_trampoline()
+
+//go:cgo_import_dynamic libc_seteuid seteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setgid_trampoline()
+
+//go:cgo_import_dynamic libc_setgid setgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setlogin(name string) (err error) {
@@ -1006,67 +1305,91 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setlogin_trampoline()
+
+//go:cgo_import_dynamic libc_setlogin setlogin "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setpgid_trampoline()
+
+//go:cgo_import_dynamic libc_setpgid setpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setpriority_trampoline()
+
+//go:cgo_import_dynamic libc_setpriority setpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setregid_trampoline()
+
+//go:cgo_import_dynamic libc_setregid setregid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setreuid_trampoline()
+
+//go:cgo_import_dynamic libc_setreuid setreuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setrlimit_trampoline()
+
+//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1074,26 +1397,38 @@
 	return
 }
 
+func libc_setsid_trampoline()
+
+//go:cgo_import_dynamic libc_setsid setsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_settimeofday_trampoline()
+
+//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setuid_trampoline()
+
+//go:cgo_import_dynamic libc_setuid setuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Stat(path string, stat *Stat_t) (err error) {
@@ -1102,13 +1437,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_stat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_stat_trampoline()
+
+//go:cgo_import_dynamic libc_stat stat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Statfs(path string, stat *Statfs_t) (err error) {
@@ -1117,13 +1456,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_statfs_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_statfs_trampoline()
+
+//go:cgo_import_dynamic libc_statfs statfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Symlink(path string, link string) (err error) {
@@ -1137,23 +1480,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_symlink_trampoline()
+
+//go:cgo_import_dynamic libc_symlink symlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_sync_trampoline), 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_sync_trampoline()
+
+//go:cgo_import_dynamic libc_sync sync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Truncate(path string, length int64) (err error) {
@@ -1162,21 +1513,29 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), uintptr(length>>32))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_truncate_trampoline()
+
+//go:cgo_import_dynamic libc_truncate truncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_umask_trampoline), uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
+func libc_umask_trampoline()
+
+//go:cgo_import_dynamic libc_umask umask "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unlink(path string) (err error) {
@@ -1185,13 +1544,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_unlink_trampoline()
+
+//go:cgo_import_dynamic libc_unlink unlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unmount(path string, flags int) (err error) {
@@ -1200,13 +1563,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_unmount_trampoline()
+
+//go:cgo_import_dynamic libc_unmount unmount "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func write(fd int, p []byte) (n int, err error) {
@@ -1216,7 +1583,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1224,10 +1591,14 @@
 	return
 }
 
+func libc_write_trampoline()
+
+//go:cgo_import_dynamic libc_write write "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
+	r0, _, e1 := syscall9(abi.FuncPCABI0(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos), uintptr(pos>>32), 0, 0)
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1235,20 +1606,62 @@
 	return
 }
 
+func libc_mmap_trampoline()
+
+//go:cgo_import_dynamic libc_mmap mmap "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_munmap_trampoline()
+
+//go:cgo_import_dynamic libc_munmap munmap "libc.so"
+
+// 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(abi.FuncPCABI0(libc_utimensat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_utimensat_trampoline()
+
+//go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func directSyscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr) (ret uintptr, err error) {
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_syscall_trampoline), uintptr(trap), uintptr(a1), uintptr(a2), uintptr(a3), uintptr(a4), uintptr(a5))
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_syscall_trampoline()
+
+//go:cgo_import_dynamic libc_syscall syscall "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1259,7 +1672,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1269,19 +1682,19 @@
 
 // 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)
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, r1, e1 := syscall6X(abi.FuncPCABI0(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(whence), 0, 0)
+	newoffset = int64(int64(r1)<<32 | int64(r0))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_lseek_trampoline()
+
+//go:cgo_import_dynamic libc_lseek lseek "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getcwd(buf []byte) (n int, err error) {
@@ -1291,10 +1704,195 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
+
+func libc_getcwd_trampoline()
+
+//go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_sysctl_trampoline()
+
+//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fork() (pid int, err error) {
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_fork_trampoline()
+
+//go:cgo_import_dynamic libc_fork fork "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ioctl(fd int, req int, arg int) (err error) {
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_ioctl_trampoline()
+
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func execve(path *byte, argv **byte, envp **byte) (err error) {
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_execve_trampoline), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(argv)), uintptr(unsafe.Pointer(envp)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_execve_trampoline()
+
+//go:cgo_import_dynamic libc_execve execve "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func exit(res int) (err error) {
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), uintptr(res), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_exit_trampoline()
+
+//go:cgo_import_dynamic libc_exit exit "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+//go:nosplit
+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_ptrace_trampoline()
+
+//go:cgo_import_dynamic libc_ptrace ptrace "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getentropy(p []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getentropy_trampoline), uintptr(_p0), uintptr(len(p)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_getentropy_trampoline()
+
+//go:cgo_import_dynamic libc_getentropy getentropy "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_fstatat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_fstatat_trampoline()
+
+//go:cgo_import_dynamic libc_fstatat fstatat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) {
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func unlinkat(fd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unlinkat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_unlinkat_trampoline()
+
+//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func openat(fd int, path string, flags int, perm uint32) (fdret int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_openat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(perm), 0, 0)
+	fdret = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_openat_trampoline()
+
+//go:cgo_import_dynamic libc_openat openat "libc.so"
diff --git a/src/syscall/zsyscall_openbsd_386.s b/src/syscall/zsyscall_openbsd_386.s
new file mode 100644
index 0000000..d47a4f4
--- /dev/null
+++ b/src/syscall/zsyscall_openbsd_386.s
@@ -0,0 +1,233 @@
+// go run mkasm.go openbsd 386
+// Code generated by the command above; DO NOT EDIT.
+#include "textflag.h"
+TEXT ·libc_getgroups_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getgroups(SB)
+TEXT ·libc_setgroups_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setgroups(SB)
+TEXT ·libc_wait4_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_wait4(SB)
+TEXT ·libc_accept_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_accept(SB)
+TEXT ·libc_bind_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_bind(SB)
+TEXT ·libc_connect_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_connect(SB)
+TEXT ·libc_socket_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_socket(SB)
+TEXT ·libc_getsockopt_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getsockopt(SB)
+TEXT ·libc_setsockopt_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setsockopt(SB)
+TEXT ·libc_getpeername_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getpeername(SB)
+TEXT ·libc_getsockname_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getsockname(SB)
+TEXT ·libc_shutdown_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_shutdown(SB)
+TEXT ·libc_socketpair_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_socketpair(SB)
+TEXT ·libc_recvfrom_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_recvfrom(SB)
+TEXT ·libc_sendto_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_sendto(SB)
+TEXT ·libc_recvmsg_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_recvmsg(SB)
+TEXT ·libc_sendmsg_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_sendmsg(SB)
+TEXT ·libc_kevent_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_kevent(SB)
+TEXT ·libc_utimes_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_utimes(SB)
+TEXT ·libc_futimes_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_futimes(SB)
+TEXT ·libc_fcntl_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fcntl(SB)
+TEXT ·libc_pipe2_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_pipe2(SB)
+TEXT ·libc_accept4_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_accept4(SB)
+TEXT ·libc_getdents_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getdents(SB)
+TEXT ·libc_access_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_access(SB)
+TEXT ·libc_adjtime_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_adjtime(SB)
+TEXT ·libc_chdir_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_chdir(SB)
+TEXT ·libc_chflags_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_chflags(SB)
+TEXT ·libc_chmod_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_chmod(SB)
+TEXT ·libc_chown_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_chown(SB)
+TEXT ·libc_chroot_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_chroot(SB)
+TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_close(SB)
+TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_dup(SB)
+TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_dup2(SB)
+TEXT ·libc_fchdir_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fchdir(SB)
+TEXT ·libc_fchflags_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fchflags(SB)
+TEXT ·libc_fchmod_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fchmod(SB)
+TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fchown(SB)
+TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_flock(SB)
+TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fpathconf(SB)
+TEXT ·libc_fstat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fstat(SB)
+TEXT ·libc_fstatfs_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fstatfs(SB)
+TEXT ·libc_fsync_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fsync(SB)
+TEXT ·libc_ftruncate_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_ftruncate(SB)
+TEXT ·libc_getegid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getegid(SB)
+TEXT ·libc_geteuid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_geteuid(SB)
+TEXT ·libc_getgid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getgid(SB)
+TEXT ·libc_getpgid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getpgid(SB)
+TEXT ·libc_getpgrp_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getpgrp(SB)
+TEXT ·libc_getpid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getpid(SB)
+TEXT ·libc_getppid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getppid(SB)
+TEXT ·libc_getpriority_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getpriority(SB)
+TEXT ·libc_getrlimit_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getrlimit(SB)
+TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getrusage(SB)
+TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getsid(SB)
+TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_gettimeofday(SB)
+TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getuid(SB)
+TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_issetugid(SB)
+TEXT ·libc_kill_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_kill(SB)
+TEXT ·libc_kqueue_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_kqueue(SB)
+TEXT ·libc_lchown_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_lchown(SB)
+TEXT ·libc_link_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_link(SB)
+TEXT ·libc_listen_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_listen(SB)
+TEXT ·libc_lstat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_lstat(SB)
+TEXT ·libc_mkdir_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_mkdir(SB)
+TEXT ·libc_mkfifo_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifo(SB)
+TEXT ·libc_mknod_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_mknod(SB)
+TEXT ·libc_nanosleep_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_nanosleep(SB)
+TEXT ·libc_open_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_open(SB)
+TEXT ·libc_pathconf_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_pathconf(SB)
+TEXT ·libc_pread_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_pread(SB)
+TEXT ·libc_pwrite_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_pwrite(SB)
+TEXT ·libc_read_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_read(SB)
+TEXT ·libc_readlink_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_readlink(SB)
+TEXT ·libc_rename_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_rename(SB)
+TEXT ·libc_revoke_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_revoke(SB)
+TEXT ·libc_rmdir_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_rmdir(SB)
+TEXT ·libc_select_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_select(SB)
+TEXT ·libc_setegid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setegid(SB)
+TEXT ·libc_seteuid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_seteuid(SB)
+TEXT ·libc_setgid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setgid(SB)
+TEXT ·libc_setlogin_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setlogin(SB)
+TEXT ·libc_setpgid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setpgid(SB)
+TEXT ·libc_setpriority_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setpriority(SB)
+TEXT ·libc_setregid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setregid(SB)
+TEXT ·libc_setreuid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setreuid(SB)
+TEXT ·libc_setrlimit_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setrlimit(SB)
+TEXT ·libc_setsid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setsid(SB)
+TEXT ·libc_settimeofday_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_settimeofday(SB)
+TEXT ·libc_setuid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setuid(SB)
+TEXT ·libc_stat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_stat(SB)
+TEXT ·libc_statfs_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_statfs(SB)
+TEXT ·libc_symlink_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_symlink(SB)
+TEXT ·libc_sync_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_sync(SB)
+TEXT ·libc_truncate_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_truncate(SB)
+TEXT ·libc_umask_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_umask(SB)
+TEXT ·libc_unlink_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_unlink(SB)
+TEXT ·libc_unmount_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_unmount(SB)
+TEXT ·libc_write_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_write(SB)
+TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_mmap(SB)
+TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_munmap(SB)
+TEXT ·libc_utimensat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_utimensat(SB)
+TEXT ·libc_syscall_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_syscall(SB)
+TEXT ·libc_lseek_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_lseek(SB)
+TEXT ·libc_getcwd_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getcwd(SB)
+TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_sysctl(SB)
+TEXT ·libc_fork_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fork(SB)
+TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_ioctl(SB)
+TEXT ·libc_execve_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_execve(SB)
+TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_exit(SB)
+TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_ptrace(SB)
+TEXT ·libc_getentropy_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getentropy(SB)
+TEXT ·libc_fstatat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fstatat(SB)
+TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_unlinkat(SB)
+TEXT ·libc_openat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_openat(SB)
diff --git a/src/syscall/zsyscall_openbsd_amd64.go b/src/syscall/zsyscall_openbsd_amd64.go
index 733050a..85cb195 100644
--- a/src/syscall/zsyscall_openbsd_amd64.go
+++ b/src/syscall/zsyscall_openbsd_amd64.go
@@ -1,16 +1,18 @@
 // mksyscall.pl -openbsd -libc -tags openbsd,amd64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_libc.go syscall_openbsd_amd64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build openbsd && amd64
 // +build openbsd,amd64
 
 package syscall
 
 import "unsafe"
+import "internal/abi"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -20,13 +22,12 @@
 
 func libc_getgroups_trampoline()
 
-//go:linkname libc_getgroups libc_getgroups
 //go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -35,13 +36,12 @@
 
 func libc_setgroups_trampoline()
 
-//go:linkname libc_setgroups libc_setgroups
 //go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := syscall6(funcPC(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -51,13 +51,12 @@
 
 func libc_wait4_trampoline()
 
-//go:linkname libc_wait4 libc_wait4
 //go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -67,13 +66,12 @@
 
 func libc_accept_trampoline()
 
-//go:linkname libc_accept libc_accept
 //go:cgo_import_dynamic libc_accept accept "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall(funcPC(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -82,13 +80,12 @@
 
 func libc_bind_trampoline()
 
-//go:linkname libc_bind libc_bind
 //go:cgo_import_dynamic libc_bind bind "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall(funcPC(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -97,13 +94,12 @@
 
 func libc_connect_trampoline()
 
-//go:linkname libc_connect libc_connect
 //go:cgo_import_dynamic libc_connect connect "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -113,13 +109,12 @@
 
 func libc_socket_trampoline()
 
-//go:linkname libc_socket libc_socket
 //go:cgo_import_dynamic libc_socket socket "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -128,13 +123,12 @@
 
 func libc_getsockopt_trampoline()
 
-//go:linkname libc_getsockopt libc_getsockopt
 //go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -143,13 +137,12 @@
 
 func libc_setsockopt_trampoline()
 
-//go:linkname libc_setsockopt libc_setsockopt
 //go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -158,13 +151,12 @@
 
 func libc_getpeername_trampoline()
 
-//go:linkname libc_getpeername libc_getpeername
 //go:cgo_import_dynamic libc_getpeername getpeername "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -173,13 +165,12 @@
 
 func libc_getsockname_trampoline()
 
-//go:linkname libc_getsockname libc_getsockname
 //go:cgo_import_dynamic libc_getsockname getsockname "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -188,13 +179,12 @@
 
 func libc_shutdown_trampoline()
 
-//go:linkname libc_shutdown libc_shutdown
 //go:cgo_import_dynamic libc_shutdown shutdown "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := rawSyscall6(funcPC(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := rawSyscall6(abi.FuncPCABI0(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -203,7 +193,6 @@
 
 func libc_socketpair_trampoline()
 
-//go:linkname libc_socketpair libc_socketpair
 //go:cgo_import_dynamic libc_socketpair socketpair "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -215,7 +204,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall6(funcPC(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -225,7 +214,6 @@
 
 func libc_recvfrom_trampoline()
 
-//go:linkname libc_recvfrom libc_recvfrom
 //go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -237,7 +225,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall6(funcPC(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -246,13 +234,12 @@
 
 func libc_sendto_trampoline()
 
-//go:linkname libc_sendto libc_sendto
 //go:cgo_import_dynamic libc_sendto sendto "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -262,13 +249,12 @@
 
 func libc_recvmsg_trampoline()
 
-//go:linkname libc_recvmsg libc_recvmsg
 //go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -278,13 +264,12 @@
 
 func libc_sendmsg_trampoline()
 
-//go:linkname libc_sendmsg libc_sendmsg
 //go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := syscall6(funcPC(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -294,7 +279,6 @@
 
 func libc_kevent_trampoline()
 
-//go:linkname libc_kevent libc_kevent
 //go:cgo_import_dynamic libc_kevent kevent "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -305,7 +289,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -314,13 +298,12 @@
 
 func libc_utimes_trampoline()
 
-//go:linkname libc_utimes libc_utimes
 //go:cgo_import_dynamic libc_utimes utimes "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := syscall(funcPC(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -329,13 +312,12 @@
 
 func libc_futimes_trampoline()
 
-//go:linkname libc_futimes libc_futimes
 //go:cgo_import_dynamic libc_futimes futimes "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -345,13 +327,12 @@
 
 func libc_fcntl_trampoline()
 
-//go:linkname libc_fcntl libc_fcntl
 //go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_pipe2_trampoline), uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_pipe2_trampoline), uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -360,13 +341,12 @@
 
 func libc_pipe2_trampoline()
 
-//go:linkname libc_pipe2 libc_pipe2
 //go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) {
-	r0, _, e1 := syscall6(funcPC(libc_accept4_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_accept4_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -376,7 +356,6 @@
 
 func libc_accept4_trampoline()
 
-//go:linkname libc_accept4 libc_accept4
 //go:cgo_import_dynamic libc_accept4 accept4 "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -388,7 +367,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_getdents_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getdents_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -398,7 +377,6 @@
 
 func libc_getdents_trampoline()
 
-//go:linkname libc_getdents libc_getdents
 //go:cgo_import_dynamic libc_getdents getdents "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -409,7 +387,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -418,13 +396,12 @@
 
 func libc_access_trampoline()
 
-//go:linkname libc_access libc_access
 //go:cgo_import_dynamic libc_access access "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := syscall(funcPC(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -433,7 +410,6 @@
 
 func libc_adjtime_trampoline()
 
-//go:linkname libc_adjtime libc_adjtime
 //go:cgo_import_dynamic libc_adjtime adjtime "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -444,7 +420,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -453,7 +429,6 @@
 
 func libc_chdir_trampoline()
 
-//go:linkname libc_chdir libc_chdir
 //go:cgo_import_dynamic libc_chdir chdir "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -464,7 +439,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -473,7 +448,6 @@
 
 func libc_chflags_trampoline()
 
-//go:linkname libc_chflags libc_chflags
 //go:cgo_import_dynamic libc_chflags chflags "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -484,7 +458,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -493,7 +467,6 @@
 
 func libc_chmod_trampoline()
 
-//go:linkname libc_chmod libc_chmod
 //go:cgo_import_dynamic libc_chmod chmod "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -504,7 +477,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -513,7 +486,6 @@
 
 func libc_chown_trampoline()
 
-//go:linkname libc_chown libc_chown
 //go:cgo_import_dynamic libc_chown chown "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -524,7 +496,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -533,13 +505,12 @@
 
 func libc_chroot_trampoline()
 
-//go:linkname libc_chroot libc_chroot
 //go:cgo_import_dynamic libc_chroot chroot "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_close_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -548,13 +519,12 @@
 
 func libc_close_trampoline()
 
-//go:linkname libc_close libc_close
 //go:cgo_import_dynamic libc_close close "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_dup_trampoline), uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -564,13 +534,12 @@
 
 func libc_dup_trampoline()
 
-//go:linkname libc_dup libc_dup
 //go:cgo_import_dynamic libc_dup dup "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -579,13 +548,12 @@
 
 func libc_dup2_trampoline()
 
-//go:linkname libc_dup2 libc_dup2
 //go:cgo_import_dynamic libc_dup2 dup2 "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchdir_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchdir_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -594,13 +562,12 @@
 
 func libc_fchdir_trampoline()
 
-//go:linkname libc_fchdir libc_fchdir
 //go:cgo_import_dynamic libc_fchdir fchdir "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -609,13 +576,12 @@
 
 func libc_fchflags_trampoline()
 
-//go:linkname libc_fchflags libc_fchflags
 //go:cgo_import_dynamic libc_fchflags fchflags "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -624,13 +590,12 @@
 
 func libc_fchmod_trampoline()
 
-//go:linkname libc_fchmod libc_fchmod
 //go:cgo_import_dynamic libc_fchmod fchmod "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -639,13 +604,12 @@
 
 func libc_fchown_trampoline()
 
-//go:linkname libc_fchown libc_fchown
 //go:cgo_import_dynamic libc_fchown fchown "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -654,13 +618,12 @@
 
 func libc_flock_trampoline()
 
-//go:linkname libc_flock libc_flock
 //go:cgo_import_dynamic libc_flock flock "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -670,13 +633,12 @@
 
 func libc_fpathconf_trampoline()
 
-//go:linkname libc_fpathconf libc_fpathconf
 //go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -685,13 +647,12 @@
 
 func libc_fstat_trampoline()
 
-//go:linkname libc_fstat libc_fstat
 //go:cgo_import_dynamic libc_fstat fstat "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fstatfs_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fstatfs_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -700,13 +661,12 @@
 
 func libc_fstatfs_trampoline()
 
-//go:linkname libc_fstatfs libc_fstatfs
 //go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fsync_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fsync_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -715,13 +675,12 @@
 
 func libc_fsync_trampoline()
 
-//go:linkname libc_fsync libc_fsync
 //go:cgo_import_dynamic libc_fsync fsync "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := syscall(funcPC(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -730,52 +689,48 @@
 
 func libc_ftruncate_trampoline()
 
-//go:linkname libc_ftruncate libc_ftruncate
 //go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getegid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getegid_trampoline), 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
 func libc_getegid_trampoline()
 
-//go:linkname libc_getegid libc_getegid
 //go:cgo_import_dynamic libc_getegid getegid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_geteuid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_geteuid_trampoline), 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
 func libc_geteuid_trampoline()
 
-//go:linkname libc_geteuid libc_geteuid
 //go:cgo_import_dynamic libc_geteuid geteuid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getgid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getgid_trampoline), 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
 func libc_getgid_trampoline()
 
-//go:linkname libc_getgid libc_getgid
 //go:cgo_import_dynamic libc_getgid getgid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_getpgid_trampoline), uintptr(pid), 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpgid_trampoline), uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -785,52 +740,48 @@
 
 func libc_getpgid_trampoline()
 
-//go:linkname libc_getpgid libc_getpgid
 //go:cgo_import_dynamic libc_getpgid getpgid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getpgrp_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpgrp_trampoline), 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
 func libc_getpgrp_trampoline()
 
-//go:linkname libc_getpgrp libc_getpgrp
 //go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getpid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
 func libc_getpid_trampoline()
 
-//go:linkname libc_getpid libc_getpid
 //go:cgo_import_dynamic libc_getpid getpid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getppid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getppid_trampoline), 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
 func libc_getppid_trampoline()
 
-//go:linkname libc_getppid libc_getppid
 //go:cgo_import_dynamic libc_getppid getppid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -840,13 +791,12 @@
 
 func libc_getpriority_trampoline()
 
-//go:linkname libc_getpriority libc_getpriority
 //go:cgo_import_dynamic libc_getpriority getpriority "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -855,13 +805,12 @@
 
 func libc_getrlimit_trampoline()
 
-//go:linkname libc_getrlimit libc_getrlimit
 //go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -870,13 +819,12 @@
 
 func libc_getrusage_trampoline()
 
-//go:linkname libc_getrusage libc_getrusage
 //go:cgo_import_dynamic libc_getrusage getrusage "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_getsid_trampoline), uintptr(pid), 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsid_trampoline), uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -886,13 +834,12 @@
 
 func libc_getsid_trampoline()
 
-//go:linkname libc_getsid libc_getsid
 //go:cgo_import_dynamic libc_getsid getsid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tv)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tv)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -901,39 +848,36 @@
 
 func libc_gettimeofday_trampoline()
 
-//go:linkname libc_gettimeofday libc_gettimeofday
 //go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getuid_trampoline), 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
 func libc_getuid_trampoline()
 
-//go:linkname libc_getuid libc_getuid
 //go:cgo_import_dynamic libc_getuid getuid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := syscall(funcPC(libc_issetugid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_issetugid_trampoline), 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
 func libc_issetugid_trampoline()
 
-//go:linkname libc_issetugid libc_issetugid
 //go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := syscall(funcPC(libc_kill_trampoline), uintptr(pid), uintptr(signum), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_kill_trampoline), uintptr(pid), uintptr(signum), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -942,13 +886,12 @@
 
 func libc_kill_trampoline()
 
-//go:linkname libc_kill libc_kill
 //go:cgo_import_dynamic libc_kill kill "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_kqueue_trampoline), 0, 0, 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_kqueue_trampoline), 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -958,7 +901,6 @@
 
 func libc_kqueue_trampoline()
 
-//go:linkname libc_kqueue libc_kqueue
 //go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -969,7 +911,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -978,7 +920,6 @@
 
 func libc_lchown_trampoline()
 
-//go:linkname libc_lchown libc_lchown
 //go:cgo_import_dynamic libc_lchown lchown "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -994,7 +935,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1003,13 +944,12 @@
 
 func libc_link_trampoline()
 
-//go:linkname libc_link libc_link
 //go:cgo_import_dynamic libc_link link "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1018,7 +958,6 @@
 
 func libc_listen_trampoline()
 
-//go:linkname libc_listen libc_listen
 //go:cgo_import_dynamic libc_listen listen "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1029,7 +968,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_lstat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_lstat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1038,7 +977,6 @@
 
 func libc_lstat_trampoline()
 
-//go:linkname libc_lstat libc_lstat
 //go:cgo_import_dynamic libc_lstat lstat "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1049,7 +987,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1058,7 +996,6 @@
 
 func libc_mkdir_trampoline()
 
-//go:linkname libc_mkdir libc_mkdir
 //go:cgo_import_dynamic libc_mkdir mkdir "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1069,7 +1006,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1078,7 +1015,6 @@
 
 func libc_mkfifo_trampoline()
 
-//go:linkname libc_mkfifo libc_mkfifo
 //go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1089,7 +1025,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1098,13 +1034,12 @@
 
 func libc_mknod_trampoline()
 
-//go:linkname libc_mknod libc_mknod
 //go:cgo_import_dynamic libc_mknod mknod "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := syscall(funcPC(libc_nanosleep_trampoline), uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_nanosleep_trampoline), uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1113,7 +1048,6 @@
 
 func libc_nanosleep_trampoline()
 
-//go:linkname libc_nanosleep libc_nanosleep
 //go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1124,7 +1058,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall(funcPC(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1134,7 +1068,6 @@
 
 func libc_open_trampoline()
 
-//go:linkname libc_open libc_open
 //go:cgo_import_dynamic libc_open open "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1145,7 +1078,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall(funcPC(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1155,7 +1088,6 @@
 
 func libc_pathconf_trampoline()
 
-//go:linkname libc_pathconf libc_pathconf
 //go:cgo_import_dynamic libc_pathconf pathconf "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1167,7 +1099,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall6(funcPC(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1177,7 +1109,6 @@
 
 func libc_pread_trampoline()
 
-//go:linkname libc_pread libc_pread
 //go:cgo_import_dynamic libc_pread pread "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1189,7 +1120,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall6(funcPC(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1199,7 +1130,6 @@
 
 func libc_pwrite_trampoline()
 
-//go:linkname libc_pwrite libc_pwrite
 //go:cgo_import_dynamic libc_pwrite pwrite "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1211,7 +1141,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1221,7 +1151,6 @@
 
 func libc_read_trampoline()
 
-//go:linkname libc_read libc_read
 //go:cgo_import_dynamic libc_read read "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1238,7 +1167,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1248,7 +1177,6 @@
 
 func libc_readlink_trampoline()
 
-//go:linkname libc_readlink libc_readlink
 //go:cgo_import_dynamic libc_readlink readlink "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1264,7 +1192,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1273,7 +1201,6 @@
 
 func libc_rename_trampoline()
 
-//go:linkname libc_rename libc_rename
 //go:cgo_import_dynamic libc_rename rename "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1284,7 +1211,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1293,7 +1220,6 @@
 
 func libc_revoke_trampoline()
 
-//go:linkname libc_revoke libc_revoke
 //go:cgo_import_dynamic libc_revoke revoke "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1304,7 +1230,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1313,13 +1239,12 @@
 
 func libc_rmdir_trampoline()
 
-//go:linkname libc_rmdir libc_rmdir
 //go:cgo_import_dynamic libc_rmdir rmdir "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_select_trampoline), uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_select_trampoline), uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1328,13 +1253,12 @@
 
 func libc_select_trampoline()
 
-//go:linkname libc_select libc_select
 //go:cgo_import_dynamic libc_select select "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setegid_trampoline), uintptr(egid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setegid_trampoline), uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1343,13 +1267,12 @@
 
 func libc_setegid_trampoline()
 
-//go:linkname libc_setegid libc_setegid
 //go:cgo_import_dynamic libc_setegid setegid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_seteuid_trampoline), uintptr(euid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_seteuid_trampoline), uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1358,13 +1281,12 @@
 
 func libc_seteuid_trampoline()
 
-//go:linkname libc_seteuid libc_seteuid
 //go:cgo_import_dynamic libc_seteuid seteuid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setgid_trampoline), uintptr(gid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1373,7 +1295,6 @@
 
 func libc_setgid_trampoline()
 
-//go:linkname libc_setgid libc_setgid
 //go:cgo_import_dynamic libc_setgid setgid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1384,7 +1305,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1393,13 +1314,12 @@
 
 func libc_setlogin_trampoline()
 
-//go:linkname libc_setlogin libc_setlogin
 //go:cgo_import_dynamic libc_setlogin setlogin "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1408,13 +1328,12 @@
 
 func libc_setpgid_trampoline()
 
-//go:linkname libc_setpgid libc_setpgid
 //go:cgo_import_dynamic libc_setpgid setpgid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1423,13 +1342,12 @@
 
 func libc_setpriority_trampoline()
 
-//go:linkname libc_setpriority libc_setpriority
 //go:cgo_import_dynamic libc_setpriority setpriority "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1438,13 +1356,12 @@
 
 func libc_setregid_trampoline()
 
-//go:linkname libc_setregid libc_setregid
 //go:cgo_import_dynamic libc_setregid setregid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1453,13 +1370,12 @@
 
 func libc_setreuid_trampoline()
 
-//go:linkname libc_setreuid libc_setreuid
 //go:cgo_import_dynamic libc_setreuid setreuid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1468,13 +1384,12 @@
 
 func libc_setrlimit_trampoline()
 
-//go:linkname libc_setrlimit libc_setrlimit
 //go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_setsid_trampoline), 0, 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1484,13 +1399,12 @@
 
 func libc_setsid_trampoline()
 
-//go:linkname libc_setsid libc_setsid
 //go:cgo_import_dynamic libc_setsid setsid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1499,13 +1413,12 @@
 
 func libc_settimeofday_trampoline()
 
-//go:linkname libc_settimeofday libc_settimeofday
 //go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setuid_trampoline), uintptr(uid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1514,7 +1427,6 @@
 
 func libc_setuid_trampoline()
 
-//go:linkname libc_setuid libc_setuid
 //go:cgo_import_dynamic libc_setuid setuid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1525,7 +1437,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_stat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_stat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1534,7 +1446,6 @@
 
 func libc_stat_trampoline()
 
-//go:linkname libc_stat libc_stat
 //go:cgo_import_dynamic libc_stat stat "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1545,7 +1456,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_statfs_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_statfs_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1554,7 +1465,6 @@
 
 func libc_statfs_trampoline()
 
-//go:linkname libc_statfs libc_statfs
 //go:cgo_import_dynamic libc_statfs statfs "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1570,7 +1480,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1579,13 +1489,12 @@
 
 func libc_symlink_trampoline()
 
-//go:linkname libc_symlink libc_symlink
 //go:cgo_import_dynamic libc_symlink symlink "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := syscall(funcPC(libc_sync_trampoline), 0, 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_sync_trampoline), 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1594,7 +1503,6 @@
 
 func libc_sync_trampoline()
 
-//go:linkname libc_sync libc_sync
 //go:cgo_import_dynamic libc_sync sync "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1605,7 +1513,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1614,20 +1522,18 @@
 
 func libc_truncate_trampoline()
 
-//go:linkname libc_truncate libc_truncate
 //go:cgo_import_dynamic libc_truncate truncate "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := syscall(funcPC(libc_umask_trampoline), uintptr(newmask), 0, 0)
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_umask_trampoline), uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
 func libc_umask_trampoline()
 
-//go:linkname libc_umask libc_umask
 //go:cgo_import_dynamic libc_umask umask "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1638,7 +1544,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1647,7 +1553,6 @@
 
 func libc_unlink_trampoline()
 
-//go:linkname libc_unlink libc_unlink
 //go:cgo_import_dynamic libc_unlink unlink "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1658,7 +1563,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1667,7 +1572,6 @@
 
 func libc_unmount_trampoline()
 
-//go:linkname libc_unmount libc_unmount
 //go:cgo_import_dynamic libc_unmount unmount "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1679,7 +1583,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1689,13 +1593,12 @@
 
 func libc_write_trampoline()
 
-//go:linkname libc_write libc_write
 //go:cgo_import_dynamic libc_write write "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := syscall6X(funcPC(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	r0, _, e1 := syscall6X(abi.FuncPCABI0(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1705,13 +1608,12 @@
 
 func libc_mmap_trampoline()
 
-//go:linkname libc_mmap libc_mmap
 //go:cgo_import_dynamic libc_mmap mmap "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := syscall(funcPC(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1720,7 +1622,6 @@
 
 func libc_munmap_trampoline()
 
-//go:linkname libc_munmap libc_munmap
 //go:cgo_import_dynamic libc_munmap munmap "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1731,7 +1632,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall6(funcPC(libc_utimensat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_utimensat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1740,13 +1641,12 @@
 
 func libc_utimensat_trampoline()
 
-//go:linkname libc_utimensat libc_utimensat
 //go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func directSyscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr) (ret uintptr, err error) {
-	r0, _, e1 := syscall6X(funcPC(libc_syscall_trampoline), uintptr(trap), uintptr(a1), uintptr(a2), uintptr(a3), uintptr(a4), uintptr(a5))
+	r0, _, e1 := syscall6X(abi.FuncPCABI0(libc_syscall_trampoline), uintptr(trap), uintptr(a1), uintptr(a2), uintptr(a3), uintptr(a4), uintptr(a5))
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1756,13 +1656,12 @@
 
 func libc_syscall_trampoline()
 
-//go:linkname libc_syscall libc_syscall
 //go:cgo_import_dynamic libc_syscall syscall "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1773,7 +1672,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1784,7 +1683,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := syscallX(funcPC(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(whence))
+	r0, _, e1 := syscallX(abi.FuncPCABI0(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(whence))
 	newoffset = int64(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1794,7 +1693,6 @@
 
 func libc_lseek_trampoline()
 
-//go:linkname libc_lseek libc_lseek
 //go:cgo_import_dynamic libc_lseek lseek "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1806,7 +1704,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1816,7 +1714,6 @@
 
 func libc_getcwd_trampoline()
 
-//go:linkname libc_getcwd libc_getcwd
 //go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1828,7 +1725,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall6(funcPC(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1837,13 +1734,12 @@
 
 func libc_sysctl_trampoline()
 
-//go:linkname libc_sysctl libc_sysctl
 //go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fork() (pid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_fork_trampoline), 0, 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1853,13 +1749,12 @@
 
 func libc_fork_trampoline()
 
-//go:linkname libc_fork libc_fork
 //go:cgo_import_dynamic libc_fork fork "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctl(fd int, req int, arg int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1868,13 +1763,12 @@
 
 func libc_ioctl_trampoline()
 
-//go:linkname libc_ioctl libc_ioctl
 //go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func execve(path *byte, argv **byte, envp **byte) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_execve_trampoline), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(argv)), uintptr(unsafe.Pointer(envp)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_execve_trampoline), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(argv)), uintptr(unsafe.Pointer(envp)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1883,13 +1777,12 @@
 
 func libc_execve_trampoline()
 
-//go:linkname libc_execve libc_execve
 //go:cgo_import_dynamic libc_execve execve "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func exit(res int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_exit_trampoline), uintptr(res), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), uintptr(res), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1898,14 +1791,13 @@
 
 func libc_exit_trampoline()
 
-//go:linkname libc_exit libc_exit
 //go:cgo_import_dynamic libc_exit exit "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 //go:nosplit
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1914,7 +1806,6 @@
 
 func libc_ptrace_trampoline()
 
-//go:linkname libc_ptrace libc_ptrace
 //go:cgo_import_dynamic libc_ptrace ptrace "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1926,7 +1817,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := rawSyscall(funcPC(libc_getentropy_trampoline), uintptr(_p0), uintptr(len(p)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getentropy_trampoline), uintptr(_p0), uintptr(len(p)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1935,7 +1826,6 @@
 
 func libc_getentropy_trampoline()
 
-//go:linkname libc_getentropy libc_getentropy
 //go:cgo_import_dynamic libc_getentropy getentropy "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1946,7 +1836,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall6(funcPC(libc_fstatat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_fstatat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1955,13 +1845,12 @@
 
 func libc_fstatat_trampoline()
 
-//go:linkname libc_fstatat libc_fstatat
 //go:cgo_import_dynamic libc_fstatat fstatat "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1977,7 +1866,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_unlinkat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unlinkat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1986,7 +1875,6 @@
 
 func libc_unlinkat_trampoline()
 
-//go:linkname libc_unlinkat libc_unlinkat
 //go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1997,7 +1885,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall6(funcPC(libc_openat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(perm), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_openat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(perm), 0, 0)
 	fdret = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2007,5 +1895,4 @@
 
 func libc_openat_trampoline()
 
-//go:linkname libc_openat libc_openat
 //go:cgo_import_dynamic libc_openat openat "libc.so"
diff --git a/src/syscall/zsyscall_openbsd_arm.go b/src/syscall/zsyscall_openbsd_arm.go
index dce0a54..04a2fad 100644
--- a/src/syscall/zsyscall_openbsd_arm.go
+++ b/src/syscall/zsyscall_openbsd_arm.go
@@ -1,16 +1,18 @@
-// mksyscall.pl -l32 -openbsd -arm -tags openbsd,arm syscall_bsd.go syscall_openbsd.go syscall_openbsd_arm.go
+// mksyscall.pl -l32 -openbsd -arm -libc -tags openbsd,arm syscall_bsd.go syscall_openbsd.go syscall_openbsd_libc.go syscall_openbsd_arm.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build openbsd && arm
 // +build openbsd,arm
 
 package syscall
 
 import "unsafe"
+import "internal/abi"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -18,20 +20,28 @@
 	return
 }
 
+func libc_getgroups_trampoline()
+
+//go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setgroups_trampoline()
+
+//go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -39,10 +49,14 @@
 	return
 }
 
+func libc_wait4_trampoline()
+
+//go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -50,30 +64,42 @@
 	return
 }
 
+func libc_accept_trampoline()
+
+//go:cgo_import_dynamic libc_accept accept "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_bind_trampoline()
+
+//go:cgo_import_dynamic libc_bind bind "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_connect_trampoline()
+
+//go:cgo_import_dynamic libc_connect connect "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -81,66 +107,94 @@
 	return
 }
 
+func libc_socket_trampoline()
+
+//go:cgo_import_dynamic libc_socket socket "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_getsockopt_trampoline()
+
+//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setsockopt_trampoline()
+
+//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_getpeername_trampoline()
+
+//go:cgo_import_dynamic libc_getpeername getpeername "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_getsockname_trampoline()
+
+//go:cgo_import_dynamic libc_getsockname getsockname "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_shutdown_trampoline()
+
+//go:cgo_import_dynamic libc_shutdown shutdown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := rawSyscall6(abi.FuncPCABI0(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_socketpair_trampoline()
+
+//go:cgo_import_dynamic libc_socketpair socketpair "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
@@ -150,7 +204,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -158,6 +212,10 @@
 	return
 }
 
+func libc_recvfrom_trampoline()
+
+//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
@@ -167,17 +225,21 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_sendto_trampoline()
+
+//go:cgo_import_dynamic libc_sendto sendto "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -185,10 +247,14 @@
 	return
 }
 
+func libc_recvmsg_trampoline()
+
+//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -196,10 +262,14 @@
 	return
 }
 
+func libc_sendmsg_trampoline()
+
+//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -207,21 +277,9 @@
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func libc_kevent_trampoline()
 
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
+//go:cgo_import_dynamic libc_kevent kevent "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
@@ -231,27 +289,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_utimes_trampoline()
+
+//go:cgo_import_dynamic libc_utimes utimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_futimes_trampoline()
+
+//go:cgo_import_dynamic libc_futimes futimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -259,20 +325,28 @@
 	return
 }
 
+func libc_fcntl_trampoline()
+
+//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_pipe2_trampoline), uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_pipe2_trampoline()
+
+//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) {
-	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_accept4_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -280,6 +354,10 @@
 	return
 }
 
+func libc_accept4_trampoline()
+
+//go:cgo_import_dynamic libc_accept4 accept4 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getdents(fd int, buf []byte) (n int, err error) {
@@ -289,7 +367,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getdents_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -297,6 +375,10 @@
 	return
 }
 
+func libc_getdents_trampoline()
+
+//go:cgo_import_dynamic libc_getdents getdents "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Access(path string, mode uint32) (err error) {
@@ -305,23 +387,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_access_trampoline()
+
+//go:cgo_import_dynamic libc_access access "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_adjtime_trampoline()
+
+//go:cgo_import_dynamic libc_adjtime adjtime "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chdir(path string) (err error) {
@@ -330,13 +420,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_chdir_trampoline()
+
+//go:cgo_import_dynamic libc_chdir chdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chflags(path string, flags int) (err error) {
@@ -345,13 +439,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_chflags_trampoline()
+
+//go:cgo_import_dynamic libc_chflags chflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chmod(path string, mode uint32) (err error) {
@@ -360,13 +458,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_chmod_trampoline()
+
+//go:cgo_import_dynamic libc_chmod chmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chown(path string, uid int, gid int) (err error) {
@@ -375,13 +477,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_chown_trampoline()
+
+//go:cgo_import_dynamic libc_chown chown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chroot(path string) (err error) {
@@ -390,27 +496,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_chroot_trampoline()
+
+//go:cgo_import_dynamic libc_chroot chroot "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_close_trampoline()
+
+//go:cgo_import_dynamic libc_close close "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_dup_trampoline), uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -418,70 +532,98 @@
 	return
 }
 
+func libc_dup_trampoline()
+
+//go:cgo_import_dynamic libc_dup dup "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_dup2_trampoline()
+
+//go:cgo_import_dynamic libc_dup2 dup2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchdir_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fchdir_trampoline()
+
+//go:cgo_import_dynamic libc_fchdir fchdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fchflags_trampoline()
+
+//go:cgo_import_dynamic libc_fchflags fchflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fchmod_trampoline()
+
+//go:cgo_import_dynamic libc_fchmod fchmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fchown_trampoline()
+
+//go:cgo_import_dynamic libc_fchown fchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_flock_trampoline()
+
+//go:cgo_import_dynamic libc_flock flock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -489,74 +631,106 @@
 	return
 }
 
+func libc_fpathconf_trampoline()
+
+//go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fstat_trampoline()
+
+//go:cgo_import_dynamic libc_fstat fstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fstatfs_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fstatfs_trampoline()
+
+//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fsync_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_fsync_trampoline()
+
+//go:cgo_import_dynamic libc_fsync fsync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_ftruncate_trampoline), uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_ftruncate_trampoline()
+
+//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getegid_trampoline), 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
+func libc_getegid_trampoline()
+
+//go:cgo_import_dynamic libc_getegid getegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_geteuid_trampoline), 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+func libc_geteuid_trampoline()
+
+//go:cgo_import_dynamic libc_geteuid geteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getgid_trampoline), 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
+func libc_getgid_trampoline()
+
+//go:cgo_import_dynamic libc_getgid getgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpgid_trampoline), uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -564,34 +738,50 @@
 	return
 }
 
+func libc_getpgid_trampoline()
+
+//go:cgo_import_dynamic libc_getpgid getpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpgrp_trampoline), 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
+func libc_getpgrp_trampoline()
+
+//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
+func libc_getpid_trampoline()
+
+//go:cgo_import_dynamic libc_getpid getpid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getppid_trampoline), 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
+func libc_getppid_trampoline()
+
+//go:cgo_import_dynamic libc_getppid getppid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -599,30 +789,42 @@
 	return
 }
 
+func libc_getpriority_trampoline()
+
+//go:cgo_import_dynamic libc_getpriority getpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_getrlimit_trampoline()
+
+//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_getrusage_trampoline()
+
+//go:cgo_import_dynamic libc_getrusage getrusage "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsid_trampoline), uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -630,46 +832,66 @@
 	return
 }
 
+func libc_getsid_trampoline()
+
+//go:cgo_import_dynamic libc_getsid getsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tv)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_gettimeofday_trampoline()
+
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getuid_trampoline), 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+func libc_getuid_trampoline()
+
+//go:cgo_import_dynamic libc_getuid getuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_issetugid_trampoline), 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
+func libc_issetugid_trampoline()
+
+//go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_kill_trampoline), uintptr(pid), uintptr(signum), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_kill_trampoline()
+
+//go:cgo_import_dynamic libc_kill kill "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_kqueue_trampoline), 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -677,6 +899,10 @@
 	return
 }
 
+func libc_kqueue_trampoline()
+
+//go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lchown(path string, uid int, gid int) (err error) {
@@ -685,13 +911,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_lchown_trampoline()
+
+//go:cgo_import_dynamic libc_lchown lchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Link(path string, link string) (err error) {
@@ -705,23 +935,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_link_trampoline()
+
+//go:cgo_import_dynamic libc_link link "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_listen_trampoline()
+
+//go:cgo_import_dynamic libc_listen listen "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lstat(path string, stat *Stat_t) (err error) {
@@ -730,13 +968,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_lstat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_lstat_trampoline()
+
+//go:cgo_import_dynamic libc_lstat lstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkdir(path string, mode uint32) (err error) {
@@ -745,13 +987,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_mkdir_trampoline()
+
+//go:cgo_import_dynamic libc_mkdir mkdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkfifo(path string, mode uint32) (err error) {
@@ -760,13 +1006,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_mkfifo_trampoline()
+
+//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mknod(path string, mode uint32, dev int) (err error) {
@@ -775,23 +1025,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_mknod_trampoline()
+
+//go:cgo_import_dynamic libc_mknod mknod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_nanosleep_trampoline), uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_nanosleep_trampoline()
+
+//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Open(path string, mode int, perm uint32) (fd int, err error) {
@@ -800,7 +1058,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -808,6 +1066,10 @@
 	return
 }
 
+func libc_open_trampoline()
+
+//go:cgo_import_dynamic libc_open open "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Pathconf(path string, name int) (val int, err error) {
@@ -816,7 +1078,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -824,6 +1086,10 @@
 	return
 }
 
+func libc_pathconf_trampoline()
+
+//go:cgo_import_dynamic libc_pathconf pathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Pread(fd int, p []byte, offset int64) (n int, err error) {
@@ -833,7 +1099,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -841,6 +1107,10 @@
 	return
 }
 
+func libc_pread_trampoline()
+
+//go:cgo_import_dynamic libc_pread pread "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
@@ -850,7 +1120,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -858,6 +1128,10 @@
 	return
 }
 
+func libc_pwrite_trampoline()
+
+//go:cgo_import_dynamic libc_pwrite pwrite "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func read(fd int, p []byte) (n int, err error) {
@@ -867,7 +1141,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -875,6 +1149,10 @@
 	return
 }
 
+func libc_read_trampoline()
+
+//go:cgo_import_dynamic libc_read read "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Readlink(path string, buf []byte) (n int, err error) {
@@ -889,7 +1167,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -897,6 +1175,10 @@
 	return
 }
 
+func libc_readlink_trampoline()
+
+//go:cgo_import_dynamic libc_readlink readlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rename(from string, to string) (err error) {
@@ -910,13 +1192,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_rename_trampoline()
+
+//go:cgo_import_dynamic libc_rename rename "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Revoke(path string) (err error) {
@@ -925,13 +1211,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_revoke_trampoline()
+
+//go:cgo_import_dynamic libc_revoke revoke "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rmdir(path string) (err error) {
@@ -940,64 +1230,73 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func libc_rmdir_trampoline()
 
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
-	newoffset = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
+//go:cgo_import_dynamic libc_rmdir rmdir "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_select_trampoline), uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_select_trampoline()
+
+//go:cgo_import_dynamic libc_select select "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setegid_trampoline), uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setegid_trampoline()
+
+//go:cgo_import_dynamic libc_setegid setegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_seteuid_trampoline), uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_seteuid_trampoline()
+
+//go:cgo_import_dynamic libc_seteuid seteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setgid_trampoline()
+
+//go:cgo_import_dynamic libc_setgid setgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setlogin(name string) (err error) {
@@ -1006,67 +1305,91 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setlogin_trampoline()
+
+//go:cgo_import_dynamic libc_setlogin setlogin "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setpgid_trampoline()
+
+//go:cgo_import_dynamic libc_setpgid setpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setpriority_trampoline()
+
+//go:cgo_import_dynamic libc_setpriority setpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setregid_trampoline()
+
+//go:cgo_import_dynamic libc_setregid setregid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setreuid_trampoline()
+
+//go:cgo_import_dynamic libc_setreuid setreuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setrlimit_trampoline()
+
+//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1074,26 +1397,38 @@
 	return
 }
 
+func libc_setsid_trampoline()
+
+//go:cgo_import_dynamic libc_setsid setsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_settimeofday_trampoline()
+
+//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_setuid_trampoline()
+
+//go:cgo_import_dynamic libc_setuid setuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Stat(path string, stat *Stat_t) (err error) {
@@ -1102,13 +1437,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_stat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_stat_trampoline()
+
+//go:cgo_import_dynamic libc_stat stat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Statfs(path string, stat *Statfs_t) (err error) {
@@ -1117,13 +1456,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_statfs_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_statfs_trampoline()
+
+//go:cgo_import_dynamic libc_statfs statfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Symlink(path string, link string) (err error) {
@@ -1137,23 +1480,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_symlink_trampoline()
+
+//go:cgo_import_dynamic libc_symlink symlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_sync_trampoline), 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_sync_trampoline()
+
+//go:cgo_import_dynamic libc_sync sync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Truncate(path string, length int64) (err error) {
@@ -1162,21 +1513,29 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_truncate_trampoline()
+
+//go:cgo_import_dynamic libc_truncate truncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_umask_trampoline), uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
+func libc_umask_trampoline()
+
+//go:cgo_import_dynamic libc_umask umask "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unlink(path string) (err error) {
@@ -1185,13 +1544,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_unlink_trampoline()
+
+//go:cgo_import_dynamic libc_unlink unlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unmount(path string, flags int) (err error) {
@@ -1200,13 +1563,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_unmount_trampoline()
+
+//go:cgo_import_dynamic libc_unmount unmount "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func write(fd int, p []byte) (n int, err error) {
@@ -1216,7 +1583,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1224,10 +1591,14 @@
 	return
 }
 
+func libc_write_trampoline()
+
+//go:cgo_import_dynamic libc_write write "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
+	r0, _, e1 := syscall9(abi.FuncPCABI0(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1235,20 +1606,62 @@
 	return
 }
 
+func libc_mmap_trampoline()
+
+//go:cgo_import_dynamic libc_mmap mmap "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_munmap_trampoline()
+
+//go:cgo_import_dynamic libc_munmap munmap "libc.so"
+
+// 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(abi.FuncPCABI0(libc_utimensat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_utimensat_trampoline()
+
+//go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func directSyscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr) (ret uintptr, err error) {
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_syscall_trampoline), uintptr(trap), uintptr(a1), uintptr(a2), uintptr(a3), uintptr(a4), uintptr(a5))
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_syscall_trampoline()
+
+//go:cgo_import_dynamic libc_syscall syscall "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1259,7 +1672,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1269,19 +1682,19 @@
 
 // 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)
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, r1, e1 := syscall6X(abi.FuncPCABI0(libc_lseek_trampoline), uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
+	newoffset = int64(int64(r1)<<32 | int64(r0))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+func libc_lseek_trampoline()
+
+//go:cgo_import_dynamic libc_lseek lseek "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getcwd(buf []byte) (n int, err error) {
@@ -1291,10 +1704,195 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
+
+func libc_getcwd_trampoline()
+
+//go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_sysctl_trampoline()
+
+//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fork() (pid int, err error) {
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_fork_trampoline()
+
+//go:cgo_import_dynamic libc_fork fork "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ioctl(fd int, req int, arg int) (err error) {
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_ioctl_trampoline()
+
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func execve(path *byte, argv **byte, envp **byte) (err error) {
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_execve_trampoline), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(argv)), uintptr(unsafe.Pointer(envp)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_execve_trampoline()
+
+//go:cgo_import_dynamic libc_execve execve "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func exit(res int) (err error) {
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), uintptr(res), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_exit_trampoline()
+
+//go:cgo_import_dynamic libc_exit exit "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+//go:nosplit
+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_ptrace_trampoline()
+
+//go:cgo_import_dynamic libc_ptrace ptrace "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getentropy(p []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getentropy_trampoline), uintptr(_p0), uintptr(len(p)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_getentropy_trampoline()
+
+//go:cgo_import_dynamic libc_getentropy getentropy "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_fstatat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_fstatat_trampoline()
+
+//go:cgo_import_dynamic libc_fstatat fstatat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) {
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func unlinkat(fd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unlinkat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_unlinkat_trampoline()
+
+//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func openat(fd int, path string, flags int, perm uint32) (fdret int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_openat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(perm), 0, 0)
+	fdret = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_openat_trampoline()
+
+//go:cgo_import_dynamic libc_openat openat "libc.so"
diff --git a/src/syscall/zsyscall_openbsd_arm.s b/src/syscall/zsyscall_openbsd_arm.s
new file mode 100644
index 0000000..d33f3aa
--- /dev/null
+++ b/src/syscall/zsyscall_openbsd_arm.s
@@ -0,0 +1,233 @@
+// go run mkasm.go openbsd arm
+// Code generated by the command above; DO NOT EDIT.
+#include "textflag.h"
+TEXT ·libc_getgroups_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getgroups(SB)
+TEXT ·libc_setgroups_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setgroups(SB)
+TEXT ·libc_wait4_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_wait4(SB)
+TEXT ·libc_accept_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_accept(SB)
+TEXT ·libc_bind_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_bind(SB)
+TEXT ·libc_connect_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_connect(SB)
+TEXT ·libc_socket_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_socket(SB)
+TEXT ·libc_getsockopt_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getsockopt(SB)
+TEXT ·libc_setsockopt_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setsockopt(SB)
+TEXT ·libc_getpeername_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getpeername(SB)
+TEXT ·libc_getsockname_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getsockname(SB)
+TEXT ·libc_shutdown_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_shutdown(SB)
+TEXT ·libc_socketpair_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_socketpair(SB)
+TEXT ·libc_recvfrom_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_recvfrom(SB)
+TEXT ·libc_sendto_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_sendto(SB)
+TEXT ·libc_recvmsg_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_recvmsg(SB)
+TEXT ·libc_sendmsg_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_sendmsg(SB)
+TEXT ·libc_kevent_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_kevent(SB)
+TEXT ·libc_utimes_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_utimes(SB)
+TEXT ·libc_futimes_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_futimes(SB)
+TEXT ·libc_fcntl_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fcntl(SB)
+TEXT ·libc_pipe2_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_pipe2(SB)
+TEXT ·libc_accept4_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_accept4(SB)
+TEXT ·libc_getdents_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getdents(SB)
+TEXT ·libc_access_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_access(SB)
+TEXT ·libc_adjtime_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_adjtime(SB)
+TEXT ·libc_chdir_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_chdir(SB)
+TEXT ·libc_chflags_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_chflags(SB)
+TEXT ·libc_chmod_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_chmod(SB)
+TEXT ·libc_chown_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_chown(SB)
+TEXT ·libc_chroot_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_chroot(SB)
+TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_close(SB)
+TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_dup(SB)
+TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_dup2(SB)
+TEXT ·libc_fchdir_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fchdir(SB)
+TEXT ·libc_fchflags_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fchflags(SB)
+TEXT ·libc_fchmod_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fchmod(SB)
+TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fchown(SB)
+TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_flock(SB)
+TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fpathconf(SB)
+TEXT ·libc_fstat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fstat(SB)
+TEXT ·libc_fstatfs_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fstatfs(SB)
+TEXT ·libc_fsync_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fsync(SB)
+TEXT ·libc_ftruncate_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_ftruncate(SB)
+TEXT ·libc_getegid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getegid(SB)
+TEXT ·libc_geteuid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_geteuid(SB)
+TEXT ·libc_getgid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getgid(SB)
+TEXT ·libc_getpgid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getpgid(SB)
+TEXT ·libc_getpgrp_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getpgrp(SB)
+TEXT ·libc_getpid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getpid(SB)
+TEXT ·libc_getppid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getppid(SB)
+TEXT ·libc_getpriority_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getpriority(SB)
+TEXT ·libc_getrlimit_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getrlimit(SB)
+TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getrusage(SB)
+TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getsid(SB)
+TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_gettimeofday(SB)
+TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getuid(SB)
+TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_issetugid(SB)
+TEXT ·libc_kill_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_kill(SB)
+TEXT ·libc_kqueue_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_kqueue(SB)
+TEXT ·libc_lchown_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_lchown(SB)
+TEXT ·libc_link_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_link(SB)
+TEXT ·libc_listen_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_listen(SB)
+TEXT ·libc_lstat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_lstat(SB)
+TEXT ·libc_mkdir_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_mkdir(SB)
+TEXT ·libc_mkfifo_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifo(SB)
+TEXT ·libc_mknod_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_mknod(SB)
+TEXT ·libc_nanosleep_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_nanosleep(SB)
+TEXT ·libc_open_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_open(SB)
+TEXT ·libc_pathconf_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_pathconf(SB)
+TEXT ·libc_pread_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_pread(SB)
+TEXT ·libc_pwrite_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_pwrite(SB)
+TEXT ·libc_read_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_read(SB)
+TEXT ·libc_readlink_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_readlink(SB)
+TEXT ·libc_rename_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_rename(SB)
+TEXT ·libc_revoke_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_revoke(SB)
+TEXT ·libc_rmdir_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_rmdir(SB)
+TEXT ·libc_select_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_select(SB)
+TEXT ·libc_setegid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setegid(SB)
+TEXT ·libc_seteuid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_seteuid(SB)
+TEXT ·libc_setgid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setgid(SB)
+TEXT ·libc_setlogin_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setlogin(SB)
+TEXT ·libc_setpgid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setpgid(SB)
+TEXT ·libc_setpriority_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setpriority(SB)
+TEXT ·libc_setregid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setregid(SB)
+TEXT ·libc_setreuid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setreuid(SB)
+TEXT ·libc_setrlimit_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setrlimit(SB)
+TEXT ·libc_setsid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setsid(SB)
+TEXT ·libc_settimeofday_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_settimeofday(SB)
+TEXT ·libc_setuid_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_setuid(SB)
+TEXT ·libc_stat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_stat(SB)
+TEXT ·libc_statfs_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_statfs(SB)
+TEXT ·libc_symlink_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_symlink(SB)
+TEXT ·libc_sync_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_sync(SB)
+TEXT ·libc_truncate_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_truncate(SB)
+TEXT ·libc_umask_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_umask(SB)
+TEXT ·libc_unlink_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_unlink(SB)
+TEXT ·libc_unmount_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_unmount(SB)
+TEXT ·libc_write_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_write(SB)
+TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_mmap(SB)
+TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_munmap(SB)
+TEXT ·libc_utimensat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_utimensat(SB)
+TEXT ·libc_syscall_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_syscall(SB)
+TEXT ·libc_lseek_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_lseek(SB)
+TEXT ·libc_getcwd_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getcwd(SB)
+TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_sysctl(SB)
+TEXT ·libc_fork_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fork(SB)
+TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_ioctl(SB)
+TEXT ·libc_execve_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_execve(SB)
+TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_exit(SB)
+TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_ptrace(SB)
+TEXT ·libc_getentropy_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_getentropy(SB)
+TEXT ·libc_fstatat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_fstatat(SB)
+TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_unlinkat(SB)
+TEXT ·libc_openat_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_openat(SB)
diff --git a/src/syscall/zsyscall_openbsd_arm64.go b/src/syscall/zsyscall_openbsd_arm64.go
index 2093eb7..fa35905 100644
--- a/src/syscall/zsyscall_openbsd_arm64.go
+++ b/src/syscall/zsyscall_openbsd_arm64.go
@@ -1,16 +1,18 @@
 // mksyscall.pl -openbsd -libc -tags openbsd,arm64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_libc.go syscall_openbsd_arm64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build openbsd && arm64
 // +build openbsd,arm64
 
 package syscall
 
 import "unsafe"
+import "internal/abi"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -20,13 +22,12 @@
 
 func libc_getgroups_trampoline()
 
-//go:linkname libc_getgroups libc_getgroups
 //go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -35,13 +36,12 @@
 
 func libc_setgroups_trampoline()
 
-//go:linkname libc_setgroups libc_setgroups
 //go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := syscall6(funcPC(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -51,13 +51,12 @@
 
 func libc_wait4_trampoline()
 
-//go:linkname libc_wait4 libc_wait4
 //go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -67,13 +66,12 @@
 
 func libc_accept_trampoline()
 
-//go:linkname libc_accept libc_accept
 //go:cgo_import_dynamic libc_accept accept "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall(funcPC(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -82,13 +80,12 @@
 
 func libc_bind_trampoline()
 
-//go:linkname libc_bind libc_bind
 //go:cgo_import_dynamic libc_bind bind "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall(funcPC(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -97,13 +94,12 @@
 
 func libc_connect_trampoline()
 
-//go:linkname libc_connect libc_connect
 //go:cgo_import_dynamic libc_connect connect "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -113,13 +109,12 @@
 
 func libc_socket_trampoline()
 
-//go:linkname libc_socket libc_socket
 //go:cgo_import_dynamic libc_socket socket "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -128,13 +123,12 @@
 
 func libc_getsockopt_trampoline()
 
-//go:linkname libc_getsockopt libc_getsockopt
 //go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -143,13 +137,12 @@
 
 func libc_setsockopt_trampoline()
 
-//go:linkname libc_setsockopt libc_setsockopt
 //go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -158,13 +151,12 @@
 
 func libc_getpeername_trampoline()
 
-//go:linkname libc_getpeername libc_getpeername
 //go:cgo_import_dynamic libc_getpeername getpeername "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -173,13 +165,12 @@
 
 func libc_getsockname_trampoline()
 
-//go:linkname libc_getsockname libc_getsockname
 //go:cgo_import_dynamic libc_getsockname getsockname "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -188,13 +179,12 @@
 
 func libc_shutdown_trampoline()
 
-//go:linkname libc_shutdown libc_shutdown
 //go:cgo_import_dynamic libc_shutdown shutdown "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := rawSyscall6(funcPC(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := rawSyscall6(abi.FuncPCABI0(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -203,7 +193,6 @@
 
 func libc_socketpair_trampoline()
 
-//go:linkname libc_socketpair libc_socketpair
 //go:cgo_import_dynamic libc_socketpair socketpair "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -215,7 +204,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall6(funcPC(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -225,7 +214,6 @@
 
 func libc_recvfrom_trampoline()
 
-//go:linkname libc_recvfrom libc_recvfrom
 //go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -237,7 +225,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall6(funcPC(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -246,13 +234,12 @@
 
 func libc_sendto_trampoline()
 
-//go:linkname libc_sendto libc_sendto
 //go:cgo_import_dynamic libc_sendto sendto "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -262,13 +249,12 @@
 
 func libc_recvmsg_trampoline()
 
-//go:linkname libc_recvmsg libc_recvmsg
 //go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -278,13 +264,12 @@
 
 func libc_sendmsg_trampoline()
 
-//go:linkname libc_sendmsg libc_sendmsg
 //go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := syscall6(funcPC(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -294,7 +279,6 @@
 
 func libc_kevent_trampoline()
 
-//go:linkname libc_kevent libc_kevent
 //go:cgo_import_dynamic libc_kevent kevent "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -305,7 +289,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -314,13 +298,12 @@
 
 func libc_utimes_trampoline()
 
-//go:linkname libc_utimes libc_utimes
 //go:cgo_import_dynamic libc_utimes utimes "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := syscall(funcPC(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -329,13 +312,12 @@
 
 func libc_futimes_trampoline()
 
-//go:linkname libc_futimes libc_futimes
 //go:cgo_import_dynamic libc_futimes futimes "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -345,13 +327,12 @@
 
 func libc_fcntl_trampoline()
 
-//go:linkname libc_fcntl libc_fcntl
 //go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_pipe2_trampoline), uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_pipe2_trampoline), uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -360,13 +341,12 @@
 
 func libc_pipe2_trampoline()
 
-//go:linkname libc_pipe2 libc_pipe2
 //go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) {
-	r0, _, e1 := syscall6(funcPC(libc_accept4_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_accept4_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -376,7 +356,6 @@
 
 func libc_accept4_trampoline()
 
-//go:linkname libc_accept4 libc_accept4
 //go:cgo_import_dynamic libc_accept4 accept4 "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -388,7 +367,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_getdents_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getdents_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -398,7 +377,6 @@
 
 func libc_getdents_trampoline()
 
-//go:linkname libc_getdents libc_getdents
 //go:cgo_import_dynamic libc_getdents getdents "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -409,7 +387,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -418,13 +396,12 @@
 
 func libc_access_trampoline()
 
-//go:linkname libc_access libc_access
 //go:cgo_import_dynamic libc_access access "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := syscall(funcPC(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -433,7 +410,6 @@
 
 func libc_adjtime_trampoline()
 
-//go:linkname libc_adjtime libc_adjtime
 //go:cgo_import_dynamic libc_adjtime adjtime "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -444,7 +420,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -453,7 +429,6 @@
 
 func libc_chdir_trampoline()
 
-//go:linkname libc_chdir libc_chdir
 //go:cgo_import_dynamic libc_chdir chdir "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -464,7 +439,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -473,7 +448,6 @@
 
 func libc_chflags_trampoline()
 
-//go:linkname libc_chflags libc_chflags
 //go:cgo_import_dynamic libc_chflags chflags "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -484,7 +458,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -493,7 +467,6 @@
 
 func libc_chmod_trampoline()
 
-//go:linkname libc_chmod libc_chmod
 //go:cgo_import_dynamic libc_chmod chmod "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -504,7 +477,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -513,7 +486,6 @@
 
 func libc_chown_trampoline()
 
-//go:linkname libc_chown libc_chown
 //go:cgo_import_dynamic libc_chown chown "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -524,7 +496,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -533,13 +505,12 @@
 
 func libc_chroot_trampoline()
 
-//go:linkname libc_chroot libc_chroot
 //go:cgo_import_dynamic libc_chroot chroot "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_close_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -548,13 +519,12 @@
 
 func libc_close_trampoline()
 
-//go:linkname libc_close libc_close
 //go:cgo_import_dynamic libc_close close "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_dup_trampoline), uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -564,13 +534,12 @@
 
 func libc_dup_trampoline()
 
-//go:linkname libc_dup libc_dup
 //go:cgo_import_dynamic libc_dup dup "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -579,13 +548,12 @@
 
 func libc_dup2_trampoline()
 
-//go:linkname libc_dup2 libc_dup2
 //go:cgo_import_dynamic libc_dup2 dup2 "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchdir_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchdir_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -594,13 +562,12 @@
 
 func libc_fchdir_trampoline()
 
-//go:linkname libc_fchdir libc_fchdir
 //go:cgo_import_dynamic libc_fchdir fchdir "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -609,13 +576,12 @@
 
 func libc_fchflags_trampoline()
 
-//go:linkname libc_fchflags libc_fchflags
 //go:cgo_import_dynamic libc_fchflags fchflags "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -624,13 +590,12 @@
 
 func libc_fchmod_trampoline()
 
-//go:linkname libc_fchmod libc_fchmod
 //go:cgo_import_dynamic libc_fchmod fchmod "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -639,13 +604,12 @@
 
 func libc_fchown_trampoline()
 
-//go:linkname libc_fchown libc_fchown
 //go:cgo_import_dynamic libc_fchown fchown "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -654,13 +618,12 @@
 
 func libc_flock_trampoline()
 
-//go:linkname libc_flock libc_flock
 //go:cgo_import_dynamic libc_flock flock "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -670,13 +633,12 @@
 
 func libc_fpathconf_trampoline()
 
-//go:linkname libc_fpathconf libc_fpathconf
 //go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -685,13 +647,12 @@
 
 func libc_fstat_trampoline()
 
-//go:linkname libc_fstat libc_fstat
 //go:cgo_import_dynamic libc_fstat fstat "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fstatfs_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fstatfs_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -700,13 +661,12 @@
 
 func libc_fstatfs_trampoline()
 
-//go:linkname libc_fstatfs libc_fstatfs
 //go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_fsync_trampoline), uintptr(fd), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_fsync_trampoline), uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -715,13 +675,12 @@
 
 func libc_fsync_trampoline()
 
-//go:linkname libc_fsync libc_fsync
 //go:cgo_import_dynamic libc_fsync fsync "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := syscall(funcPC(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -730,52 +689,48 @@
 
 func libc_ftruncate_trampoline()
 
-//go:linkname libc_ftruncate libc_ftruncate
 //go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getegid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getegid_trampoline), 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
 func libc_getegid_trampoline()
 
-//go:linkname libc_getegid libc_getegid
 //go:cgo_import_dynamic libc_getegid getegid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_geteuid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_geteuid_trampoline), 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
 func libc_geteuid_trampoline()
 
-//go:linkname libc_geteuid libc_geteuid
 //go:cgo_import_dynamic libc_geteuid geteuid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getgid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getgid_trampoline), 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
 func libc_getgid_trampoline()
 
-//go:linkname libc_getgid libc_getgid
 //go:cgo_import_dynamic libc_getgid getgid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_getpgid_trampoline), uintptr(pid), 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpgid_trampoline), uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -785,52 +740,48 @@
 
 func libc_getpgid_trampoline()
 
-//go:linkname libc_getpgid libc_getpgid
 //go:cgo_import_dynamic libc_getpgid getpgid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getpgrp_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpgrp_trampoline), 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
 func libc_getpgrp_trampoline()
 
-//go:linkname libc_getpgrp libc_getpgrp
 //go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getpid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
 func libc_getpid_trampoline()
 
-//go:linkname libc_getpid libc_getpid
 //go:cgo_import_dynamic libc_getpid getpid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getppid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getppid_trampoline), 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
 func libc_getppid_trampoline()
 
-//go:linkname libc_getppid libc_getppid
 //go:cgo_import_dynamic libc_getppid getppid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -840,13 +791,12 @@
 
 func libc_getpriority_trampoline()
 
-//go:linkname libc_getpriority libc_getpriority
 //go:cgo_import_dynamic libc_getpriority getpriority "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -855,13 +805,12 @@
 
 func libc_getrlimit_trampoline()
 
-//go:linkname libc_getrlimit libc_getrlimit
 //go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -870,13 +819,12 @@
 
 func libc_getrusage_trampoline()
 
-//go:linkname libc_getrusage libc_getrusage
 //go:cgo_import_dynamic libc_getrusage getrusage "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_getsid_trampoline), uintptr(pid), 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsid_trampoline), uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -886,13 +834,12 @@
 
 func libc_getsid_trampoline()
 
-//go:linkname libc_getsid libc_getsid
 //go:cgo_import_dynamic libc_getsid getsid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tv)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tv)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -901,39 +848,36 @@
 
 func libc_gettimeofday_trampoline()
 
-//go:linkname libc_gettimeofday libc_gettimeofday
 //go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0)
+	r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getuid_trampoline), 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
 func libc_getuid_trampoline()
 
-//go:linkname libc_getuid libc_getuid
 //go:cgo_import_dynamic libc_getuid getuid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := syscall(funcPC(libc_issetugid_trampoline), 0, 0, 0)
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_issetugid_trampoline), 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
 func libc_issetugid_trampoline()
 
-//go:linkname libc_issetugid libc_issetugid
 //go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := syscall(funcPC(libc_kill_trampoline), uintptr(pid), uintptr(signum), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_kill_trampoline), uintptr(pid), uintptr(signum), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -942,13 +886,12 @@
 
 func libc_kill_trampoline()
 
-//go:linkname libc_kill libc_kill
 //go:cgo_import_dynamic libc_kill kill "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_kqueue_trampoline), 0, 0, 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_kqueue_trampoline), 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -958,7 +901,6 @@
 
 func libc_kqueue_trampoline()
 
-//go:linkname libc_kqueue libc_kqueue
 //go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -969,7 +911,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -978,7 +920,6 @@
 
 func libc_lchown_trampoline()
 
-//go:linkname libc_lchown libc_lchown
 //go:cgo_import_dynamic libc_lchown lchown "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -994,7 +935,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1003,13 +944,12 @@
 
 func libc_link_trampoline()
 
-//go:linkname libc_link libc_link
 //go:cgo_import_dynamic libc_link link "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1018,7 +958,6 @@
 
 func libc_listen_trampoline()
 
-//go:linkname libc_listen libc_listen
 //go:cgo_import_dynamic libc_listen listen "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1029,7 +968,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_lstat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_lstat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1038,7 +977,6 @@
 
 func libc_lstat_trampoline()
 
-//go:linkname libc_lstat libc_lstat
 //go:cgo_import_dynamic libc_lstat lstat "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1049,7 +987,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1058,7 +996,6 @@
 
 func libc_mkdir_trampoline()
 
-//go:linkname libc_mkdir libc_mkdir
 //go:cgo_import_dynamic libc_mkdir mkdir "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1069,7 +1006,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1078,7 +1015,6 @@
 
 func libc_mkfifo_trampoline()
 
-//go:linkname libc_mkfifo libc_mkfifo
 //go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1089,7 +1025,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1098,13 +1034,12 @@
 
 func libc_mknod_trampoline()
 
-//go:linkname libc_mknod libc_mknod
 //go:cgo_import_dynamic libc_mknod mknod "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := syscall(funcPC(libc_nanosleep_trampoline), uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_nanosleep_trampoline), uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1113,7 +1048,6 @@
 
 func libc_nanosleep_trampoline()
 
-//go:linkname libc_nanosleep libc_nanosleep
 //go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1124,7 +1058,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall(funcPC(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1134,7 +1068,6 @@
 
 func libc_open_trampoline()
 
-//go:linkname libc_open libc_open
 //go:cgo_import_dynamic libc_open open "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1145,7 +1078,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall(funcPC(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1155,7 +1088,6 @@
 
 func libc_pathconf_trampoline()
 
-//go:linkname libc_pathconf libc_pathconf
 //go:cgo_import_dynamic libc_pathconf pathconf "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1167,7 +1099,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall6(funcPC(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1177,7 +1109,6 @@
 
 func libc_pread_trampoline()
 
-//go:linkname libc_pread libc_pread
 //go:cgo_import_dynamic libc_pread pread "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1189,7 +1120,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall6(funcPC(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1199,7 +1130,6 @@
 
 func libc_pwrite_trampoline()
 
-//go:linkname libc_pwrite libc_pwrite
 //go:cgo_import_dynamic libc_pwrite pwrite "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1211,7 +1141,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1221,7 +1151,6 @@
 
 func libc_read_trampoline()
 
-//go:linkname libc_read libc_read
 //go:cgo_import_dynamic libc_read read "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1238,7 +1167,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1248,7 +1177,6 @@
 
 func libc_readlink_trampoline()
 
-//go:linkname libc_readlink libc_readlink
 //go:cgo_import_dynamic libc_readlink readlink "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1264,7 +1192,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1273,7 +1201,6 @@
 
 func libc_rename_trampoline()
 
-//go:linkname libc_rename libc_rename
 //go:cgo_import_dynamic libc_rename rename "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1284,7 +1211,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1293,7 +1220,6 @@
 
 func libc_revoke_trampoline()
 
-//go:linkname libc_revoke libc_revoke
 //go:cgo_import_dynamic libc_revoke revoke "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1304,7 +1230,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1313,13 +1239,12 @@
 
 func libc_rmdir_trampoline()
 
-//go:linkname libc_rmdir libc_rmdir
 //go:cgo_import_dynamic libc_rmdir rmdir "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_select_trampoline), uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_select_trampoline), uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1328,13 +1253,12 @@
 
 func libc_select_trampoline()
 
-//go:linkname libc_select libc_select
 //go:cgo_import_dynamic libc_select select "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setegid_trampoline), uintptr(egid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setegid_trampoline), uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1343,13 +1267,12 @@
 
 func libc_setegid_trampoline()
 
-//go:linkname libc_setegid libc_setegid
 //go:cgo_import_dynamic libc_setegid setegid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_seteuid_trampoline), uintptr(euid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_seteuid_trampoline), uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1358,13 +1281,12 @@
 
 func libc_seteuid_trampoline()
 
-//go:linkname libc_seteuid libc_seteuid
 //go:cgo_import_dynamic libc_seteuid seteuid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setgid_trampoline), uintptr(gid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1373,7 +1295,6 @@
 
 func libc_setgid_trampoline()
 
-//go:linkname libc_setgid libc_setgid
 //go:cgo_import_dynamic libc_setgid setgid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1384,7 +1305,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1393,13 +1314,12 @@
 
 func libc_setlogin_trampoline()
 
-//go:linkname libc_setlogin libc_setlogin
 //go:cgo_import_dynamic libc_setlogin setlogin "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1408,13 +1328,12 @@
 
 func libc_setpgid_trampoline()
 
-//go:linkname libc_setpgid libc_setpgid
 //go:cgo_import_dynamic libc_setpgid setpgid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := syscall(funcPC(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1423,13 +1342,12 @@
 
 func libc_setpriority_trampoline()
 
-//go:linkname libc_setpriority libc_setpriority
 //go:cgo_import_dynamic libc_setpriority setpriority "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1438,13 +1356,12 @@
 
 func libc_setregid_trampoline()
 
-//go:linkname libc_setregid libc_setregid
 //go:cgo_import_dynamic libc_setregid setregid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1453,13 +1370,12 @@
 
 func libc_setreuid_trampoline()
 
-//go:linkname libc_setreuid libc_setreuid
 //go:cgo_import_dynamic libc_setreuid setreuid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1468,13 +1384,12 @@
 
 func libc_setrlimit_trampoline()
 
-//go:linkname libc_setrlimit libc_setrlimit
 //go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_setsid_trampoline), 0, 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1484,13 +1399,12 @@
 
 func libc_setsid_trampoline()
 
-//go:linkname libc_setsid libc_setsid
 //go:cgo_import_dynamic libc_setsid setsid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1499,13 +1413,12 @@
 
 func libc_settimeofday_trampoline()
 
-//go:linkname libc_settimeofday libc_settimeofday
 //go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_setuid_trampoline), uintptr(uid), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1514,7 +1427,6 @@
 
 func libc_setuid_trampoline()
 
-//go:linkname libc_setuid libc_setuid
 //go:cgo_import_dynamic libc_setuid setuid "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1525,7 +1437,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_stat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_stat_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1534,7 +1446,6 @@
 
 func libc_stat_trampoline()
 
-//go:linkname libc_stat libc_stat
 //go:cgo_import_dynamic libc_stat stat "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1545,7 +1456,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_statfs_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_statfs_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1554,7 +1465,6 @@
 
 func libc_statfs_trampoline()
 
-//go:linkname libc_statfs libc_statfs
 //go:cgo_import_dynamic libc_statfs statfs "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1570,7 +1480,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1579,13 +1489,12 @@
 
 func libc_symlink_trampoline()
 
-//go:linkname libc_symlink libc_symlink
 //go:cgo_import_dynamic libc_symlink symlink "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := syscall(funcPC(libc_sync_trampoline), 0, 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_sync_trampoline), 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1594,7 +1503,6 @@
 
 func libc_sync_trampoline()
 
-//go:linkname libc_sync libc_sync
 //go:cgo_import_dynamic libc_sync sync "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1605,7 +1513,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1614,20 +1522,18 @@
 
 func libc_truncate_trampoline()
 
-//go:linkname libc_truncate libc_truncate
 //go:cgo_import_dynamic libc_truncate truncate "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := syscall(funcPC(libc_umask_trampoline), uintptr(newmask), 0, 0)
+	r0, _, _ := syscall(abi.FuncPCABI0(libc_umask_trampoline), uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
 func libc_umask_trampoline()
 
-//go:linkname libc_umask libc_umask
 //go:cgo_import_dynamic libc_umask umask "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1638,7 +1544,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1647,7 +1553,6 @@
 
 func libc_unlink_trampoline()
 
-//go:linkname libc_unlink libc_unlink
 //go:cgo_import_dynamic libc_unlink unlink "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1658,7 +1563,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1667,7 +1572,6 @@
 
 func libc_unmount_trampoline()
 
-//go:linkname libc_unmount libc_unmount
 //go:cgo_import_dynamic libc_unmount unmount "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1679,7 +1583,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1689,13 +1593,12 @@
 
 func libc_write_trampoline()
 
-//go:linkname libc_write libc_write
 //go:cgo_import_dynamic libc_write write "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := syscall6X(funcPC(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	r0, _, e1 := syscall6X(abi.FuncPCABI0(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1705,13 +1608,12 @@
 
 func libc_mmap_trampoline()
 
-//go:linkname libc_mmap libc_mmap
 //go:cgo_import_dynamic libc_mmap mmap "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := syscall(funcPC(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1720,7 +1622,6 @@
 
 func libc_munmap_trampoline()
 
-//go:linkname libc_munmap libc_munmap
 //go:cgo_import_dynamic libc_munmap munmap "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1731,7 +1632,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall6(funcPC(libc_utimensat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_utimensat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1740,13 +1641,12 @@
 
 func libc_utimensat_trampoline()
 
-//go:linkname libc_utimensat libc_utimensat
 //go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func directSyscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr) (ret uintptr, err error) {
-	r0, _, e1 := syscall6X(funcPC(libc_syscall_trampoline), uintptr(trap), uintptr(a1), uintptr(a2), uintptr(a3), uintptr(a4), uintptr(a5))
+	r0, _, e1 := syscall6X(abi.FuncPCABI0(libc_syscall_trampoline), uintptr(trap), uintptr(a1), uintptr(a2), uintptr(a3), uintptr(a4), uintptr(a5))
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1756,13 +1656,12 @@
 
 func libc_syscall_trampoline()
 
-//go:linkname libc_syscall libc_syscall
 //go:cgo_import_dynamic libc_syscall syscall "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1773,7 +1672,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1784,7 +1683,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := syscallX(funcPC(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(whence))
+	r0, _, e1 := syscallX(abi.FuncPCABI0(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(whence))
 	newoffset = int64(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1794,7 +1693,6 @@
 
 func libc_lseek_trampoline()
 
-//go:linkname libc_lseek libc_lseek
 //go:cgo_import_dynamic libc_lseek lseek "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1806,7 +1704,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall(funcPC(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1816,7 +1714,6 @@
 
 func libc_getcwd_trampoline()
 
-//go:linkname libc_getcwd libc_getcwd
 //go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1828,7 +1725,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall6(funcPC(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1837,13 +1734,12 @@
 
 func libc_sysctl_trampoline()
 
-//go:linkname libc_sysctl libc_sysctl
 //go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fork() (pid int, err error) {
-	r0, _, e1 := rawSyscall(funcPC(libc_fork_trampoline), 0, 0, 0)
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1853,13 +1749,12 @@
 
 func libc_fork_trampoline()
 
-//go:linkname libc_fork libc_fork
 //go:cgo_import_dynamic libc_fork fork "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctl(fd int, req int, arg int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1868,13 +1763,12 @@
 
 func libc_ioctl_trampoline()
 
-//go:linkname libc_ioctl libc_ioctl
 //go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func execve(path *byte, argv **byte, envp **byte) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_execve_trampoline), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(argv)), uintptr(unsafe.Pointer(envp)))
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_execve_trampoline), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(argv)), uintptr(unsafe.Pointer(envp)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1883,13 +1777,12 @@
 
 func libc_execve_trampoline()
 
-//go:linkname libc_execve libc_execve
 //go:cgo_import_dynamic libc_execve execve "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func exit(res int) (err error) {
-	_, _, e1 := rawSyscall(funcPC(libc_exit_trampoline), uintptr(res), 0, 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), uintptr(res), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1898,14 +1791,13 @@
 
 func libc_exit_trampoline()
 
-//go:linkname libc_exit libc_exit
 //go:cgo_import_dynamic libc_exit exit "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 //go:nosplit
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
-	_, _, e1 := syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1914,7 +1806,6 @@
 
 func libc_ptrace_trampoline()
 
-//go:linkname libc_ptrace libc_ptrace
 //go:cgo_import_dynamic libc_ptrace ptrace "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1926,7 +1817,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := rawSyscall(funcPC(libc_getentropy_trampoline), uintptr(_p0), uintptr(len(p)), 0)
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getentropy_trampoline), uintptr(_p0), uintptr(len(p)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1935,7 +1826,6 @@
 
 func libc_getentropy_trampoline()
 
-//go:linkname libc_getentropy libc_getentropy
 //go:cgo_import_dynamic libc_getentropy getentropy "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1946,7 +1836,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall6(funcPC(libc_fstatat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall6(abi.FuncPCABI0(libc_fstatat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1955,13 +1845,12 @@
 
 func libc_fstatat_trampoline()
 
-//go:linkname libc_fstatat libc_fstatat
 //go:cgo_import_dynamic libc_fstatat fstatat "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) {
-	r0, _, e1 := syscall(funcPC(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1977,7 +1866,7 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall(funcPC(libc_unlinkat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_unlinkat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1986,7 +1875,6 @@
 
 func libc_unlinkat_trampoline()
 
-//go:linkname libc_unlinkat libc_unlinkat
 //go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1997,7 +1885,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall6(funcPC(libc_openat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(perm), 0, 0)
+	r0, _, e1 := syscall6(abi.FuncPCABI0(libc_openat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(perm), 0, 0)
 	fdret = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -2007,5 +1895,4 @@
 
 func libc_openat_trampoline()
 
-//go:linkname libc_openat libc_openat
 //go:cgo_import_dynamic libc_openat openat "libc.so"
diff --git a/src/syscall/zsyscall_openbsd_mips64.go b/src/syscall/zsyscall_openbsd_mips64.go
index ded0568..70fd147 100644
--- a/src/syscall/zsyscall_openbsd_mips64.go
+++ b/src/syscall/zsyscall_openbsd_mips64.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -openbsd -tags openbsd,mips64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_mips64x.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build openbsd && mips64
 // +build openbsd,mips64
 
 package syscall
diff --git a/src/syscall/zsyscall_plan9_386.go b/src/syscall/zsyscall_plan9_386.go
index 998c6c5..8b7727b 100644
--- a/src/syscall/zsyscall_plan9_386.go
+++ b/src/syscall/zsyscall_plan9_386.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -l32 -plan9 -tags plan9,386 syscall_plan9.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build plan9 && 386
 // +build plan9,386
 
 package syscall
diff --git a/src/syscall/zsyscall_plan9_amd64.go b/src/syscall/zsyscall_plan9_amd64.go
index 02a2829..bed9108 100644
--- a/src/syscall/zsyscall_plan9_amd64.go
+++ b/src/syscall/zsyscall_plan9_amd64.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -l32 -plan9 -tags plan9,amd64 syscall_plan9.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build plan9 && amd64
 // +build plan9,amd64
 
 package syscall
diff --git a/src/syscall/zsyscall_plan9_arm.go b/src/syscall/zsyscall_plan9_arm.go
index 4498239..7bbcf9b 100644
--- a/src/syscall/zsyscall_plan9_arm.go
+++ b/src/syscall/zsyscall_plan9_arm.go
@@ -1,6 +1,7 @@
 // mksyscall.pl -l32 -plan9 -tags plan9,arm syscall_plan9.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build plan9 && arm
 // +build plan9,arm
 
 package syscall
diff --git a/src/syscall/zsyscall_solaris_amd64.go b/src/syscall/zsyscall_solaris_amd64.go
index 446ebfc..9b37dc0 100644
--- a/src/syscall/zsyscall_solaris_amd64.go
+++ b/src/syscall/zsyscall_solaris_amd64.go
@@ -1,6 +1,7 @@
 // mksyscall_libc.pl -solaris -tags solaris,amd64 syscall_solaris.go syscall_solaris_amd64.go
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build solaris && amd64
 // +build solaris,amd64
 
 package syscall
diff --git a/src/syscall/zsyscall_windows.go b/src/syscall/zsyscall_windows.go
index b1480ba..7bfff16 100644
--- a/src/syscall/zsyscall_windows.go
+++ b/src/syscall/zsyscall_windows.go
@@ -43,6 +43,7 @@
 	modkernel32 = NewLazyDLL(sysdll.Add("kernel32.dll"))
 	modmswsock  = NewLazyDLL(sysdll.Add("mswsock.dll"))
 	modnetapi32 = NewLazyDLL(sysdll.Add("netapi32.dll"))
+	modntdll    = NewLazyDLL(sysdll.Add("ntdll.dll"))
 	modsecur32  = NewLazyDLL(sysdll.Add("secur32.dll"))
 	modshell32  = NewLazyDLL(sysdll.Add("shell32.dll"))
 	moduserenv  = NewLazyDLL(sysdll.Add("userenv.dll"))
@@ -93,6 +94,7 @@
 	procCreateSymbolicLinkW                = modkernel32.NewProc("CreateSymbolicLinkW")
 	procCreateToolhelp32Snapshot           = modkernel32.NewProc("CreateToolhelp32Snapshot")
 	procDeleteFileW                        = modkernel32.NewProc("DeleteFileW")
+	procDeleteProcThreadAttributeList      = modkernel32.NewProc("DeleteProcThreadAttributeList")
 	procDeviceIoControl                    = modkernel32.NewProc("DeviceIoControl")
 	procDuplicateHandle                    = modkernel32.NewProc("DuplicateHandle")
 	procExitProcess                        = modkernel32.NewProc("ExitProcess")
@@ -131,6 +133,7 @@
 	procGetTempPathW                       = modkernel32.NewProc("GetTempPathW")
 	procGetTimeZoneInformation             = modkernel32.NewProc("GetTimeZoneInformation")
 	procGetVersion                         = modkernel32.NewProc("GetVersion")
+	procInitializeProcThreadAttributeList  = modkernel32.NewProc("InitializeProcThreadAttributeList")
 	procLoadLibraryW                       = modkernel32.NewProc("LoadLibraryW")
 	procLocalFree                          = modkernel32.NewProc("LocalFree")
 	procMapViewOfFile                      = modkernel32.NewProc("MapViewOfFile")
@@ -153,6 +156,7 @@
 	procSetHandleInformation               = modkernel32.NewProc("SetHandleInformation")
 	procTerminateProcess                   = modkernel32.NewProc("TerminateProcess")
 	procUnmapViewOfFile                    = modkernel32.NewProc("UnmapViewOfFile")
+	procUpdateProcThreadAttribute          = modkernel32.NewProc("UpdateProcThreadAttribute")
 	procVirtualLock                        = modkernel32.NewProc("VirtualLock")
 	procVirtualUnlock                      = modkernel32.NewProc("VirtualUnlock")
 	procWaitForSingleObject                = modkernel32.NewProc("WaitForSingleObject")
@@ -164,6 +168,7 @@
 	procNetApiBufferFree                   = modnetapi32.NewProc("NetApiBufferFree")
 	procNetGetJoinInformation              = modnetapi32.NewProc("NetGetJoinInformation")
 	procNetUserGetInfo                     = modnetapi32.NewProc("NetUserGetInfo")
+	procRtlGetNtVersionNumbers             = modntdll.NewProc("RtlGetNtVersionNumbers")
 	procGetUserNameExW                     = modsecur32.NewProc("GetUserNameExW")
 	procTranslateNameW                     = modsecur32.NewProc("TranslateNameW")
 	procCommandLineToArgvW                 = modshell32.NewProc("CommandLineToArgvW")
@@ -569,6 +574,11 @@
 	return
 }
 
+func deleteProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST) {
+	Syscall(procDeleteProcThreadAttributeList.Addr(), 1, uintptr(unsafe.Pointer(attrlist)), 0, 0)
+	return
+}
+
 func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) {
 	r1, _, e1 := Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0)
 	if r1 == 0 {
@@ -897,6 +907,14 @@
 	return
 }
 
+func initializeProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, attrcount uint32, flags uint32, size *uintptr) (err error) {
+	r1, _, e1 := Syscall6(procInitializeProcThreadAttributeList.Addr(), 4, uintptr(unsafe.Pointer(attrlist)), uintptr(attrcount), uintptr(flags), uintptr(unsafe.Pointer(size)), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func LoadLibrary(libname string) (handle Handle, err error) {
 	var _p0 *uint16
 	_p0, err = UTF16PtrFromString(libname)
@@ -1099,6 +1117,14 @@
 	return
 }
 
+func updateProcThreadAttribute(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) {
+	r1, _, e1 := Syscall9(procUpdateProcThreadAttribute.Addr(), 7, uintptr(unsafe.Pointer(attrlist)), uintptr(flags), uintptr(attr), uintptr(value), uintptr(size), uintptr(prevvalue), uintptr(unsafe.Pointer(returnedsize)), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func VirtualLock(addr uintptr, length uintptr) (err error) {
 	r1, _, e1 := Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0)
 	if r1 == 0 {
@@ -1189,6 +1215,11 @@
 	return
 }
 
+func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) {
+	Syscall(procRtlGetNtVersionNumbers.Addr(), 3, uintptr(unsafe.Pointer(majorVersion)), uintptr(unsafe.Pointer(minorVersion)), uintptr(unsafe.Pointer(buildNumber)))
+	return
+}
+
 func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) {
 	r1, _, e1 := Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize)))
 	if r1&0xff == 0 {
diff --git a/src/syscall/zsysnum_darwin_amd64.go b/src/syscall/zsysnum_darwin_amd64.go
index a2331be..f66f7d2 100644
--- a/src/syscall/zsysnum_darwin_amd64.go
+++ b/src/syscall/zsysnum_darwin_amd64.go
@@ -1,6 +1,7 @@
 // mksysnum_darwin.pl /usr/include/sys/syscall.h
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build amd64 && darwin
 // +build amd64,darwin
 
 package syscall
diff --git a/src/syscall/zsysnum_darwin_arm64.go b/src/syscall/zsysnum_darwin_arm64.go
index 9548717..6fa1463 100644
--- a/src/syscall/zsysnum_darwin_arm64.go
+++ b/src/syscall/zsysnum_darwin_arm64.go
@@ -1,6 +1,7 @@
 // mksysnum_darwin.pl /usr/include/sys/syscall.h
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build arm64 && darwin
 // +build arm64,darwin
 
 package syscall
diff --git a/src/syscall/zsysnum_dragonfly_amd64.go b/src/syscall/zsysnum_dragonfly_amd64.go
index 9ce11f5..e8996db 100644
--- a/src/syscall/zsysnum_dragonfly_amd64.go
+++ b/src/syscall/zsysnum_dragonfly_amd64.go
@@ -1,6 +1,7 @@
 // mksysnum_dragonfly.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build amd64 && dragonfly
 // +build amd64,dragonfly
 
 package syscall
@@ -301,6 +302,8 @@
 	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_PIPE2                  = 538 // { int pipe2(int *fildes, int flags); }
 	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); }
+	SYS_WAIT6                  = 548 // { int wait6(idtype_t idtype, id_t id, int *status, int options, struct __wrusage *wrusage, siginfo_t *info); }
 )
diff --git a/src/syscall/zsysnum_freebsd_386.go b/src/syscall/zsysnum_freebsd_386.go
index bb6e9d7..1ed7e3e 100644
--- a/src/syscall/zsysnum_freebsd_386.go
+++ b/src/syscall/zsysnum_freebsd_386.go
@@ -1,6 +1,7 @@
 // mksysnum_freebsd.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build 386 && freebsd
 // +build 386,freebsd
 
 package syscall
diff --git a/src/syscall/zsysnum_freebsd_amd64.go b/src/syscall/zsysnum_freebsd_amd64.go
index f5d81ab..d72dbc9 100644
--- a/src/syscall/zsysnum_freebsd_amd64.go
+++ b/src/syscall/zsysnum_freebsd_amd64.go
@@ -1,6 +1,7 @@
 // mksysnum_freebsd.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build amd64 && freebsd
 // +build amd64,freebsd
 
 package syscall
diff --git a/src/syscall/zsysnum_freebsd_arm.go b/src/syscall/zsysnum_freebsd_arm.go
index 006b49c..4f4dc4d 100644
--- a/src/syscall/zsysnum_freebsd_arm.go
+++ b/src/syscall/zsysnum_freebsd_arm.go
@@ -1,6 +1,7 @@
 // mksysnum_freebsd.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build arm && freebsd
 // +build arm,freebsd
 
 package syscall
diff --git a/src/syscall/zsysnum_freebsd_arm64.go b/src/syscall/zsysnum_freebsd_arm64.go
index 0ce3d05..ab1a052 100644
--- a/src/syscall/zsysnum_freebsd_arm64.go
+++ b/src/syscall/zsysnum_freebsd_arm64.go
@@ -1,6 +1,7 @@
 // mksysnum_freebsd.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build arm64 && freebsd
 // +build arm64,freebsd
 
 package syscall
diff --git a/src/syscall/zsysnum_linux_386.go b/src/syscall/zsysnum_linux_386.go
index 6bcd221..792f435 100644
--- a/src/syscall/zsysnum_linux_386.go
+++ b/src/syscall/zsysnum_linux_386.go
@@ -1,6 +1,7 @@
 // mksysnum_linux.pl /usr/include/asm/unistd_32.h
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build 386 && linux
 // +build 386,linux
 
 package syscall
diff --git a/src/syscall/zsysnum_linux_amd64.go b/src/syscall/zsysnum_linux_amd64.go
index 70ca686..9ea18d6 100644
--- a/src/syscall/zsysnum_linux_amd64.go
+++ b/src/syscall/zsysnum_linux_amd64.go
@@ -1,6 +1,7 @@
 // mksysnum_linux.pl /usr/include/asm/unistd_64.h
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build amd64 && linux
 // +build amd64,linux
 
 package syscall
diff --git a/src/syscall/zsysnum_linux_arm.go b/src/syscall/zsysnum_linux_arm.go
index 39ddc65..ccae9c1 100644
--- a/src/syscall/zsysnum_linux_arm.go
+++ b/src/syscall/zsysnum_linux_arm.go
@@ -1,6 +1,7 @@
 // mksysnum_linux.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build arm && linux
 // +build arm,linux
 
 package syscall
diff --git a/src/syscall/zsysnum_linux_arm64.go b/src/syscall/zsysnum_linux_arm64.go
index 22a88b4..17c54a2 100644
--- a/src/syscall/zsysnum_linux_arm64.go
+++ b/src/syscall/zsysnum_linux_arm64.go
@@ -1,6 +1,7 @@
 // mksysnum_linux.pl /usr/include/asm-generic/unistd.h
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build arm64 && linux
 // +build arm64,linux
 
 package syscall
diff --git a/src/syscall/zsysnum_linux_ppc64.go b/src/syscall/zsysnum_linux_ppc64.go
index 5882a7c..a0d37ff 100644
--- a/src/syscall/zsysnum_linux_ppc64.go
+++ b/src/syscall/zsysnum_linux_ppc64.go
@@ -1,6 +1,7 @@
 // mksysnum_linux.pl /usr/include/asm/unistd.h
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build ppc64 && linux
 // +build ppc64,linux
 
 package syscall
diff --git a/src/syscall/zsysnum_linux_ppc64le.go b/src/syscall/zsysnum_linux_ppc64le.go
index 4fb3f6c..f8f82d2 100644
--- a/src/syscall/zsysnum_linux_ppc64le.go
+++ b/src/syscall/zsysnum_linux_ppc64le.go
@@ -1,6 +1,7 @@
 // mksysnum_linux.pl /usr/include/powerpc64le-linux-gnu/asm/unistd.h
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build ppc64le && linux
 // +build ppc64le,linux
 
 package syscall
diff --git a/src/syscall/zsysnum_netbsd_386.go b/src/syscall/zsysnum_netbsd_386.go
index 514d1f8..fd0c329 100644
--- a/src/syscall/zsysnum_netbsd_386.go
+++ b/src/syscall/zsysnum_netbsd_386.go
@@ -1,6 +1,7 @@
 // mksysnum_netbsd.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build 386 && netbsd
 // +build 386,netbsd
 
 package syscall
@@ -270,4 +271,5 @@
 	SYS_POSIX_SPAWN          = 474 // { int|sys||posix_spawn(pid_t *pid, const char *path, const struct posix_spawn_file_actions *file_actions, const struct posix_spawnattr *attrp, char *const *argv, char *const *envp); }
 	SYS_RECVMMSG             = 475 // { int|sys||recvmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout); }
 	SYS_SENDMMSG             = 476 // { int|sys||sendmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, unsigned int flags); }
+	SYS_WAIT6                = 481 // { int|sys||wait6(idtype_t idtype, id_t id, int *status, int options, struct wrusage *wru, siginfo_t *info); }
 )
diff --git a/src/syscall/zsysnum_netbsd_amd64.go b/src/syscall/zsysnum_netbsd_amd64.go
index db05c03..03f2cd3 100644
--- a/src/syscall/zsysnum_netbsd_amd64.go
+++ b/src/syscall/zsysnum_netbsd_amd64.go
@@ -1,6 +1,7 @@
 // mksysnum_netbsd.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build amd64 && netbsd
 // +build amd64,netbsd
 
 package syscall
@@ -270,4 +271,5 @@
 	SYS_POSIX_SPAWN          = 474 // { int|sys||posix_spawn(pid_t *pid, const char *path, const struct posix_spawn_file_actions *file_actions, const struct posix_spawnattr *attrp, char *const *argv, char *const *envp); }
 	SYS_RECVMMSG             = 475 // { int|sys||recvmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout); }
 	SYS_SENDMMSG             = 476 // { int|sys||sendmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, unsigned int flags); }
+	SYS_WAIT6                = 481 // { int|sys||wait6(idtype_t idtype, id_t id, int *status, int options, struct wrusage *wru, siginfo_t *info); }
 )
diff --git a/src/syscall/zsysnum_netbsd_arm.go b/src/syscall/zsysnum_netbsd_arm.go
index 9a10a43..7b356e7 100644
--- a/src/syscall/zsysnum_netbsd_arm.go
+++ b/src/syscall/zsysnum_netbsd_arm.go
@@ -1,6 +1,7 @@
 // mksysnum_netbsd.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build arm && netbsd
 // +build arm,netbsd
 
 package syscall
@@ -270,4 +271,5 @@
 	SYS_POSIX_SPAWN          = 474 // { int|sys||posix_spawn(pid_t *pid, const char *path, const struct posix_spawn_file_actions *file_actions, const struct posix_spawnattr *attrp, char *const *argv, char *const *envp); }
 	SYS_RECVMMSG             = 475 // { int|sys||recvmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout); }
 	SYS_SENDMMSG             = 476 // { int|sys||sendmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, unsigned int flags); }
+	SYS_WAIT6                = 481 // { int|sys||wait6(idtype_t idtype, id_t id, int *status, int options, struct wrusage *wru, siginfo_t *info); }
 )
diff --git a/src/syscall/zsysnum_netbsd_arm64.go b/src/syscall/zsysnum_netbsd_arm64.go
index 31e13bf..3f57ec4 100644
--- a/src/syscall/zsysnum_netbsd_arm64.go
+++ b/src/syscall/zsysnum_netbsd_arm64.go
@@ -1,6 +1,7 @@
 // mksysnum_netbsd.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build arm64 && netbsd
 // +build arm64,netbsd
 
 package syscall
@@ -270,4 +271,5 @@
 	SYS_POSIX_SPAWN          = 474 // { int|sys||posix_spawn(pid_t *pid, const char *path, const struct posix_spawn_file_actions *file_actions, const struct posix_spawnattr *attrp, char *const *argv, char *const *envp); }
 	SYS_RECVMMSG             = 475 // { int|sys||recvmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout); }
 	SYS_SENDMMSG             = 476 // { int|sys||sendmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, unsigned int flags); }
+	SYS_WAIT6                = 481 // { int|sys||wait6(idtype_t idtype, id_t id, int *status, int options, struct wrusage *wru, siginfo_t *info); }
 )
diff --git a/src/syscall/zsysnum_openbsd_386.go b/src/syscall/zsysnum_openbsd_386.go
index 39b9c78..b289886 100644
--- a/src/syscall/zsysnum_openbsd_386.go
+++ b/src/syscall/zsysnum_openbsd_386.go
@@ -1,6 +1,7 @@
 // mksysnum_openbsd.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build 386 && openbsd
 // +build 386,openbsd
 
 package syscall
diff --git a/src/syscall/zsysnum_openbsd_amd64.go b/src/syscall/zsysnum_openbsd_amd64.go
index e176c4e..8cf2b68 100644
--- a/src/syscall/zsysnum_openbsd_amd64.go
+++ b/src/syscall/zsysnum_openbsd_amd64.go
@@ -1,6 +1,7 @@
 // mksysnum_openbsd.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build amd64 && openbsd
 // +build amd64,openbsd
 
 package syscall
diff --git a/src/syscall/zsysnum_openbsd_arm.go b/src/syscall/zsysnum_openbsd_arm.go
index 96bbdb0..cc33773 100644
--- a/src/syscall/zsysnum_openbsd_arm.go
+++ b/src/syscall/zsysnum_openbsd_arm.go
@@ -1,6 +1,7 @@
 // mksysnum_openbsd.pl
 // Code generated by the command above; DO NOT EDIT.
 
+//go:build arm && openbsd
 // +build arm,openbsd
 
 package syscall
diff --git a/src/syscall/zsysnum_solaris_amd64.go b/src/syscall/zsysnum_solaris_amd64.go
index be198f8..23c9c71 100644
--- a/src/syscall/zsysnum_solaris_amd64.go
+++ b/src/syscall/zsysnum_solaris_amd64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 && solaris
 // +build amd64,solaris
 
 package syscall
diff --git a/src/syscall/zsysnum_windows_386.go b/src/syscall/zsysnum_windows_386.go
deleted file mode 100644
index 36bf065..0000000
--- a/src/syscall/zsysnum_windows_386.go
+++ /dev/null
@@ -1,3 +0,0 @@
-// nothing to see here
-
-package syscall
diff --git a/src/syscall/zsysnum_windows_amd64.go b/src/syscall/zsysnum_windows_amd64.go
deleted file mode 100644
index 36bf065..0000000
--- a/src/syscall/zsysnum_windows_amd64.go
+++ /dev/null
@@ -1,3 +0,0 @@
-// nothing to see here
-
-package syscall
diff --git a/src/syscall/ztypes_darwin_amd64.go b/src/syscall/ztypes_darwin_amd64.go
index da56f0d..8feacc4 100644
--- a/src/syscall/ztypes_darwin_amd64.go
+++ b/src/syscall/ztypes_darwin_amd64.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_darwin.go
 
+//go:build amd64 && darwin
 // +build amd64,darwin
 
 package syscall
diff --git a/src/syscall/ztypes_darwin_arm64.go b/src/syscall/ztypes_darwin_arm64.go
index 82685ff..8079d22 100644
--- a/src/syscall/ztypes_darwin_arm64.go
+++ b/src/syscall/ztypes_darwin_arm64.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_darwin.go
 
+//go:build arm64 && darwin
 // +build arm64,darwin
 
 package syscall
diff --git a/src/syscall/ztypes_dragonfly_amd64.go b/src/syscall/ztypes_dragonfly_amd64.go
index e9e811f..a51e003 100644
--- a/src/syscall/ztypes_dragonfly_amd64.go
+++ b/src/syscall/ztypes_dragonfly_amd64.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_dragonfly.go
 
+//go:build amd64 && dragonfly
 // +build amd64,dragonfly
 
 package syscall
diff --git a/src/syscall/ztypes_freebsd_386.go b/src/syscall/ztypes_freebsd_386.go
index 27d82de..1739726 100644
--- a/src/syscall/ztypes_freebsd_386.go
+++ b/src/syscall/ztypes_freebsd_386.go
@@ -1,6 +1,7 @@
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
 // cgo -godefs types_freebsd.go | go run mkpost.go
 
+//go:build 386 && freebsd
 // +build 386,freebsd
 
 package syscall
diff --git a/src/syscall/ztypes_freebsd_amd64.go b/src/syscall/ztypes_freebsd_amd64.go
index 8abfbb4..0457d8e 100644
--- a/src/syscall/ztypes_freebsd_amd64.go
+++ b/src/syscall/ztypes_freebsd_amd64.go
@@ -1,6 +1,7 @@
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
 // cgo -godefs types_freebsd.go | go run mkpost.go
 
+//go:build amd64 && freebsd
 // +build amd64,freebsd
 
 package syscall
diff --git a/src/syscall/ztypes_freebsd_arm.go b/src/syscall/ztypes_freebsd_arm.go
index ff552a6..29c8380 100644
--- a/src/syscall/ztypes_freebsd_arm.go
+++ b/src/syscall/ztypes_freebsd_arm.go
@@ -1,6 +1,7 @@
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
 // cgo -godefs -- -fsigned-char types_freebsd.go
 
+//go:build arm && freebsd
 // +build arm,freebsd
 
 package syscall
diff --git a/src/syscall/ztypes_freebsd_arm64.go b/src/syscall/ztypes_freebsd_arm64.go
index 6d56fc8..6472db0 100644
--- a/src/syscall/ztypes_freebsd_arm64.go
+++ b/src/syscall/ztypes_freebsd_arm64.go
@@ -1,6 +1,7 @@
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
 // cgo -godefs types_freebsd.go | go run mkpost.go
 
+//go:build arm64 && freebsd
 // +build arm64,freebsd
 
 package syscall
diff --git a/src/syscall/ztypes_linux_386.go b/src/syscall/ztypes_linux_386.go
index 0252620..251a0c0 100644
--- a/src/syscall/ztypes_linux_386.go
+++ b/src/syscall/ztypes_linux_386.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_linux.go
 
+//go:build 386 && linux
 // +build 386,linux
 
 package syscall
diff --git a/src/syscall/ztypes_linux_amd64.go b/src/syscall/ztypes_linux_amd64.go
index 1fb0ee5..34c953f 100644
--- a/src/syscall/ztypes_linux_amd64.go
+++ b/src/syscall/ztypes_linux_amd64.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_linux.go
 
+//go:build amd64 && linux
 // +build amd64,linux
 
 package syscall
diff --git a/src/syscall/ztypes_linux_arm.go b/src/syscall/ztypes_linux_arm.go
index a88b577..4de656b 100644
--- a/src/syscall/ztypes_linux_arm.go
+++ b/src/syscall/ztypes_linux_arm.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_linux.go
 
+//go:build arm && linux
 // +build arm,linux
 
 package syscall
diff --git a/src/syscall/ztypes_linux_arm64.go b/src/syscall/ztypes_linux_arm64.go
index f63391c..bed9cb0 100644
--- a/src/syscall/ztypes_linux_arm64.go
+++ b/src/syscall/ztypes_linux_arm64.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -fsigned-char types_linux.go
 
+//go:build arm64 && linux
 // +build arm64,linux
 
 package syscall
diff --git a/src/syscall/ztypes_linux_ppc64.go b/src/syscall/ztypes_linux_ppc64.go
index 8b6be21..355533f 100644
--- a/src/syscall/ztypes_linux_ppc64.go
+++ b/src/syscall/ztypes_linux_ppc64.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_linux.go
 
+//go:build ppc64 && linux
 // +build ppc64,linux
 
 package syscall
diff --git a/src/syscall/ztypes_linux_ppc64le.go b/src/syscall/ztypes_linux_ppc64le.go
index a9c3ee2..94e12c7 100644
--- a/src/syscall/ztypes_linux_ppc64le.go
+++ b/src/syscall/ztypes_linux_ppc64le.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_linux.go
 
+//go:build ppc64le && linux
 // +build ppc64le,linux
 
 package syscall
diff --git a/src/syscall/ztypes_netbsd_386.go b/src/syscall/ztypes_netbsd_386.go
index 737abb8..321460f 100644
--- a/src/syscall/ztypes_netbsd_386.go
+++ b/src/syscall/ztypes_netbsd_386.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_netbsd.go
 
+//go:build 386 && netbsd
 // +build 386,netbsd
 
 package syscall
diff --git a/src/syscall/ztypes_netbsd_amd64.go b/src/syscall/ztypes_netbsd_amd64.go
index cf059f7..370d717 100644
--- a/src/syscall/ztypes_netbsd_amd64.go
+++ b/src/syscall/ztypes_netbsd_amd64.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_netbsd.go
 
+//go:build amd64 && netbsd
 // +build amd64,netbsd
 
 package syscall
diff --git a/src/syscall/ztypes_netbsd_arm.go b/src/syscall/ztypes_netbsd_arm.go
index c532b3a..557c634 100644
--- a/src/syscall/ztypes_netbsd_arm.go
+++ b/src/syscall/ztypes_netbsd_arm.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_netbsd.go
 
+//go:build arm && netbsd
 // +build arm,netbsd
 
 package syscall
diff --git a/src/syscall/ztypes_netbsd_arm64.go b/src/syscall/ztypes_netbsd_arm64.go
index 6d7f9ed..19f3690 100644
--- a/src/syscall/ztypes_netbsd_arm64.go
+++ b/src/syscall/ztypes_netbsd_arm64.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_netbsd.go
 
+//go:build arm64 && netbsd
 // +build arm64,netbsd
 
 package syscall
diff --git a/src/syscall/ztypes_openbsd_386.go b/src/syscall/ztypes_openbsd_386.go
index c2a03eb..222c6c7 100644
--- a/src/syscall/ztypes_openbsd_386.go
+++ b/src/syscall/ztypes_openbsd_386.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_openbsd.go
 
+//go:build 386 && openbsd
 // +build 386,openbsd
 
 package syscall
diff --git a/src/syscall/ztypes_openbsd_amd64.go b/src/syscall/ztypes_openbsd_amd64.go
index 1a659ba..644ee9b 100644
--- a/src/syscall/ztypes_openbsd_amd64.go
+++ b/src/syscall/ztypes_openbsd_amd64.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_openbsd.go
 
+//go:build amd64 && openbsd
 // +build amd64,openbsd
 
 package syscall
diff --git a/src/syscall/ztypes_solaris_amd64.go b/src/syscall/ztypes_solaris_amd64.go
index f846666..64e16b4 100644
--- a/src/syscall/ztypes_solaris_amd64.go
+++ b/src/syscall/ztypes_solaris_amd64.go
@@ -1,6 +1,7 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_solaris.go
 
+//go:build amd64 && solaris
 // +build amd64,solaris
 
 package syscall
diff --git a/src/testing/benchmark.go b/src/testing/benchmark.go
index a8f75e9..15b4426 100644
--- a/src/testing/benchmark.go
+++ b/src/testing/benchmark.go
@@ -238,12 +238,15 @@
 	}
 	// Only print the output if we know we are not going to proceed.
 	// Otherwise it is printed in processBench.
-	if atomic.LoadInt32(&b.hasSub) != 0 || b.finished {
+	b.mu.RLock()
+	finished := b.finished
+	b.mu.RUnlock()
+	if atomic.LoadInt32(&b.hasSub) != 0 || finished {
 		tag := "BENCH"
 		if b.skipped {
 			tag = "SKIP"
 		}
-		if b.chatty != nil && (len(b.output) > 0 || b.finished) {
+		if b.chatty != nil && (len(b.output) > 0 || finished) {
 			b.trimOutput()
 			fmt.Fprintf(b.w, "--- %s: %s\n%s", tag, b.name, b.output)
 		}
diff --git a/src/testing/benchmark_test.go b/src/testing/benchmark_test.go
index 4c1cbd1..3b1dc82 100644
--- a/src/testing/benchmark_test.go
+++ b/src/testing/benchmark_test.go
@@ -102,6 +102,30 @@
 	})
 }
 
+func TestRunParallelFatal(t *testing.T) {
+	testing.Benchmark(func(b *testing.B) {
+		b.RunParallel(func(pb *testing.PB) {
+			for pb.Next() {
+				if b.N > 1 {
+					b.Fatal("error")
+				}
+			}
+		})
+	})
+}
+
+func TestRunParallelSkipNow(t *testing.T) {
+	testing.Benchmark(func(b *testing.B) {
+		b.RunParallel(func(pb *testing.PB) {
+			for pb.Next() {
+				if b.N > 1 {
+					b.SkipNow()
+				}
+			}
+		})
+	})
+}
+
 func ExampleB_RunParallel() {
 	// Parallel benchmark for text/template.Template.Execute on a single object.
 	testing.Benchmark(func(b *testing.B) {
diff --git a/src/testing/fstest/mapfs.go b/src/testing/fstest/mapfs.go
index a5d4a23..9fef2f4 100644
--- a/src/testing/fstest/mapfs.go
+++ b/src/testing/fstest/mapfs.go
@@ -223,12 +223,12 @@
 
 func (d *mapDir) ReadDir(count int) ([]fs.DirEntry, error) {
 	n := len(d.entry) - d.offset
-	if count > 0 && n > count {
-		n = count
-	}
 	if n == 0 && count > 0 {
 		return nil, io.EOF
 	}
+	if count > 0 && n > count {
+		n = count
+	}
 	list := make([]fs.DirEntry, n)
 	for i := range list {
 		list[i] = &d.entry[d.offset+i]
diff --git a/src/testing/fstest/testfs.go b/src/testing/fstest/testfs.go
index 8fc8aca..5c4f30a 100644
--- a/src/testing/fstest/testfs.go
+++ b/src/testing/fstest/testfs.go
@@ -10,7 +10,6 @@
 	"fmt"
 	"io"
 	"io/fs"
-	"io/ioutil"
 	"path"
 	"reflect"
 	"sort"
@@ -23,7 +22,7 @@
 // opening and checking that each file behaves correctly.
 // It also checks that the file system contains at least the expected files.
 // As a special case, if no expected files are listed, fsys must be empty.
-// Otherwise, fsys must only contain at least the listed files: it can also contain others.
+// Otherwise, fsys must contain at least the listed files; it can also contain others.
 // The contents of fsys must not change concurrently with TestFS.
 //
 // If TestFS finds any misbehaviors, it returns an error reporting all of them.
@@ -303,7 +302,7 @@
 		for i, e := range elem {
 			var pattern []rune
 			for j, r := range e {
-				if r == '*' || r == '?' || r == '\\' || r == '[' {
+				if r == '*' || r == '?' || r == '\\' || r == '[' || r == '-' {
 					pattern = append(pattern, '\\', r)
 					continue
 				}
@@ -514,7 +513,7 @@
 		return
 	}
 
-	data, err := ioutil.ReadAll(f)
+	data, err := io.ReadAll(f)
 	if err != nil {
 		f.Close()
 		t.errorf("%s: Open+ReadAll: %v", file, err)
@@ -538,6 +537,18 @@
 		}
 		t.checkFileRead(file, "ReadAll vs fsys.ReadFile", data, data2)
 
+		// Modify the data and check it again. Modifying the
+		// returned byte slice should not affect the next call.
+		for i := range data2 {
+			data2[i]++
+		}
+		data2, err = fsys.ReadFile(file)
+		if err != nil {
+			t.errorf("%s: second call to fsys.ReadFile: %v", file, err)
+			return
+		}
+		t.checkFileRead(file, "Readall vs second fsys.ReadFile", data, data2)
+
 		t.checkBadPath(file, "ReadFile",
 			func(name string) error { _, err := fsys.ReadFile(name); return err })
 	}
diff --git a/src/testing/fstest/testfs_test.go b/src/testing/fstest/testfs_test.go
index 5b8813c..aefb4b3 100644
--- a/src/testing/fstest/testfs_test.go
+++ b/src/testing/fstest/testfs_test.go
@@ -29,3 +29,12 @@
 		t.Fatal(err)
 	}
 }
+
+func TestDash(t *testing.T) {
+	m := MapFS{
+		"a-b/a": {Data: []byte("a-b/a")},
+	}
+	if err := TestFS(m, "a-b/a"); err != nil {
+		t.Error(err)
+	}
+}
diff --git a/src/testing/run_example.go b/src/testing/run_example.go
index 4dc83f7..d9e342d 100644
--- a/src/testing/run_example.go
+++ b/src/testing/run_example.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !js
 // +build !js
 
 // TODO(@musiol, @odeke-em): re-unify this entire file back into
diff --git a/src/testing/run_example_js.go b/src/testing/run_example_js.go
index 1d4164b..d914633 100644
--- a/src/testing/run_example_js.go
+++ b/src/testing/run_example_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js
 // +build js
 
 package testing
diff --git a/src/testing/sub_test.go b/src/testing/sub_test.go
index 5b226f8..6c7d83a 100644
--- a/src/testing/sub_test.go
+++ b/src/testing/sub_test.go
@@ -822,7 +822,7 @@
 						c2 <- fmt.Sprintf("subtest panic with unexpected value %v", p)
 						return
 					}
-					const want = "Log in goroutine after TestLateLog has completed"
+					const want = "Log in goroutine after TestLateLog has completed: log after test"
 					if !strings.Contains(s, want) {
 						c2 <- fmt.Sprintf("subtest panic %q does not contain %q", s, want)
 					}
diff --git a/src/testing/testing.go b/src/testing/testing.go
index dec39d2..a19238d 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -190,7 +190,7 @@
 //         }
 //     }
 //
-// The race detector kills the program if it exceeds 8192 concurrent goroutines,
+// The race detector kills the program if it exceeds 8128 concurrent goroutines,
 // so use care when running parallel tests with the -race flag set.
 //
 // Run does not return until parallel subtests have completed, providing a way
@@ -208,14 +208,14 @@
 //
 // Main
 //
-// It is sometimes necessary for a test program to do extra setup or teardown
-// before or after testing. It is also sometimes necessary for a test to control
+// It is sometimes necessary for a test or benchmark program to do extra setup or teardown
+// before or after it executes. It is also sometimes necessary to control
 // which code runs on the main thread. To support these and other cases,
 // if a test file contains a function:
 //
 //	func TestMain(m *testing.M)
 //
-// then the generated test will call TestMain(m) instead of running the tests
+// then the generated test will call TestMain(m) instead of running the tests or benchmarks
 // directly. TestMain runs in the main goroutine and can do whatever setup
 // and teardown is necessary around a call to m.Run. m.Run will return an exit
 // code that may be passed to os.Exit. If TestMain returns, the test wrapper
@@ -233,6 +233,8 @@
 //		os.Exit(m.Run())
 //	}
 //
+// TestMain is a low-level primitive and should not be necessary for casual
+// testing needs, where ordinary test functions suffice.
 package testing
 
 import (
@@ -242,6 +244,7 @@
 	"fmt"
 	"internal/race"
 	"io"
+	"math/rand"
 	"os"
 	"runtime"
 	"runtime/debug"
@@ -251,6 +254,8 @@
 	"sync"
 	"sync/atomic"
 	"time"
+	"unicode"
+	"unicode/utf8"
 )
 
 var initRan bool
@@ -299,6 +304,7 @@
 	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)")
+	shuffle = flag.String("test.shuffle", "off", "randomize the execution order of tests and benchmarks")
 
 	initBenchmarkFlags()
 }
@@ -325,6 +331,7 @@
 	timeout              *time.Duration
 	cpuListStr           *string
 	parallel             *int
+	shuffle              *string
 	testlog              *string
 
 	haveExamples bool // are there examples?
@@ -388,17 +395,17 @@
 	w           io.Writer            // For flushToParent.
 	ran         bool                 // Test or benchmark (or one of its subtests) was executed.
 	failed      bool                 // Test or benchmark has failed.
-	skipped     bool                 // Test of benchmark has been skipped.
+	skipped     bool                 // Test or benchmark has been skipped.
 	done        bool                 // Test is finished and all subtests have completed.
 	helperPCs   map[uintptr]struct{} // functions to be skipped when writing file/line info
 	helperNames map[string]struct{}  // helperPCs converted to function names
 	cleanups    []func()             // optional functions to be called at the end of the test
 	cleanupName string               // Name of the cleanup function.
 	cleanupPc   []uintptr            // The stack trace at the point where Cleanup was called.
+	finished    bool                 // Test function has completed.
 
 	chatty     *chattyPrinter // A copy of chattyPrinter, if the chatty flag is set.
 	bench      bool           // Whether the current test is a benchmark.
-	finished   bool           // Test function has completed.
 	hasSub     int32          // Written atomically.
 	raceErrors int            // Number of races detected during test.
 	runner     string         // Function name of tRunner running the test.
@@ -639,6 +646,7 @@
 	Log(args ...interface{})
 	Logf(format string, args ...interface{})
 	Name() string
+	Setenv(key, value string)
 	Skip(args ...interface{})
 	SkipNow()
 	Skipf(format string, args ...interface{})
@@ -666,12 +674,17 @@
 type T struct {
 	common
 	isParallel bool
+	isEnvSet   bool
 	context    *testContext // For running tests and subtests.
 }
 
 func (c *common) private() {}
 
-// Name returns the name of the running test or benchmark.
+// Name returns the name of the running (sub-) test or benchmark.
+//
+// The name will include the name of the test along with the names of
+// any nested sub-tests. If two sibling sub-tests have the same name,
+// Name will append a suffix to guarantee the returned name is unique.
 func (c *common) Name() string {
 	return c.name
 }
@@ -737,7 +750,9 @@
 	// it would run on a test failure. Because we send on c.signal during
 	// a top-of-stack deferred function now, we know that the send
 	// only happens after any other stacked defers have completed.
+	c.mu.Lock()
 	c.finished = true
+	c.mu.Unlock()
 	runtime.Goexit()
 }
 
@@ -761,7 +776,7 @@
 				return
 			}
 		}
-		panic("Log in goroutine after " + c.name + " has completed")
+		panic("Log in goroutine after " + c.name + " has completed: " + s)
 	} else {
 		if c.chatty != nil {
 			if c.bench {
@@ -836,15 +851,11 @@
 // other goroutines created during the test. Calling SkipNow does not stop
 // those other goroutines.
 func (c *common) SkipNow() {
-	c.skip()
-	c.finished = true
-	runtime.Goexit()
-}
-
-func (c *common) skip() {
 	c.mu.Lock()
-	defer c.mu.Unlock()
 	c.skipped = true
+	c.finished = true
+	c.mu.Unlock()
+	runtime.Goexit()
 }
 
 // Skipped reports whether the test was skipped.
@@ -875,7 +886,7 @@
 	}
 }
 
-// Cleanup registers a function to be called when the test and all its
+// Cleanup registers a function to be called when the test (or subtest) and all its
 // subtests complete. Cleanup functions will be called in last added,
 // first called order.
 func (c *common) Cleanup(f func()) {
@@ -906,11 +917,6 @@
 	c.cleanups = append(c.cleanups, fn)
 }
 
-var tempDirReplacer struct {
-	sync.Once
-	r *strings.Replacer
-}
-
 // TempDir returns a temporary directory for the test to use.
 // The directory is automatically removed by Cleanup when the test and
 // all its subtests complete.
@@ -934,13 +940,26 @@
 	if nonExistent {
 		c.Helper()
 
-		// os.MkdirTemp doesn't like path separators in its pattern,
-		// so mangle the name to accommodate subtests.
-		tempDirReplacer.Do(func() {
-			tempDirReplacer.r = strings.NewReplacer("/", "_", "\\", "_", ":", "_")
-		})
-		pattern := tempDirReplacer.r.Replace(c.Name())
-
+		// Drop unusual characters (such as path separators or
+		// characters interacting with globs) from the directory name to
+		// avoid surprising os.MkdirTemp behavior.
+		mapper := func(r rune) rune {
+			if r < utf8.RuneSelf {
+				const allowed = "!#$%&()+,-.=@^_{}~ "
+				if '0' <= r && r <= '9' ||
+					'a' <= r && r <= 'z' ||
+					'A' <= r && r <= 'Z' {
+					return r
+				}
+				if strings.ContainsRune(allowed, r) {
+					return r
+				}
+			} else if unicode.IsLetter(r) || unicode.IsNumber(r) {
+				return r
+			}
+			return -1
+		}
+		pattern := strings.Map(mapper, c.Name())
 		c.tempDir, c.tempDirErr = os.MkdirTemp("", pattern)
 		if c.tempDirErr == nil {
 			c.Cleanup(func() {
@@ -963,6 +982,29 @@
 	return dir
 }
 
+// Setenv calls os.Setenv(key, value) and uses Cleanup to
+// restore the environment variable to its original value
+// after the test.
+//
+// This cannot be used in parallel tests.
+func (c *common) Setenv(key, value string) {
+	prevValue, ok := os.LookupEnv(key)
+
+	if err := os.Setenv(key, value); err != nil {
+		c.Fatalf("cannot set environment variable: %v", err)
+	}
+
+	if ok {
+		c.Cleanup(func() {
+			os.Setenv(key, prevValue)
+		})
+	} else {
+		c.Cleanup(func() {
+			os.Unsetenv(key)
+		})
+	}
+}
+
 // panicHanding is an argument to runCleanup.
 type panicHandling int
 
@@ -1034,6 +1076,9 @@
 	if t.isParallel {
 		panic("testing: t.Parallel called multiple times")
 	}
+	if t.isEnvSet {
+		panic("testing: t.Parallel called after t.Setenv; cannot set environment variables in parallel tests")
+	}
 	t.isParallel = true
 
 	// We don't want to include the time we spend waiting for serial tests
@@ -1067,6 +1112,21 @@
 	t.raceErrors += -race.Errors()
 }
 
+// Setenv calls os.Setenv(key, value) and uses Cleanup to
+// restore the environment variable to its original value
+// after the test.
+//
+// This cannot be used in parallel tests.
+func (t *T) Setenv(key, value string) {
+	if t.isParallel {
+		panic("testing: t.Setenv called after t.Parallel; cannot set environment variables in parallel tests")
+	}
+
+	t.isEnvSet = true
+
+	t.common.Setenv(key, value)
+}
+
 // InternalTest is an internal type but exported because it is cross-package;
 // it is part of the implementation of the "go test" command.
 type InternalTest struct {
@@ -1096,10 +1156,16 @@
 		err := recover()
 		signal := true
 
-		if !t.finished && err == nil {
+		t.mu.RLock()
+		finished := t.finished
+		t.mu.RUnlock()
+		if !finished && err == nil {
 			err = errNilPanicOrGoexit
 			for p := t.parent; p != nil; p = p.parent {
-				if p.finished {
+				p.mu.RLock()
+				finished = p.finished
+				p.mu.RUnlock()
+				if finished {
 					t.Errorf("%v: subtest may have called FailNow on a parent test", err)
 					err = nil
 					signal = false
@@ -1193,7 +1259,9 @@
 	fn(t)
 
 	// code beyond here will not be executed when FailNow is invoked
+	t.mu.Lock()
 	t.finished = true
+	t.mu.Unlock()
 }
 
 // Run runs f as a subtest of t called name. It runs f in a separate goroutine
@@ -1216,7 +1284,7 @@
 	t = &T{
 		common: common{
 			barrier: make(chan bool),
-			signal:  make(chan bool),
+			signal:  make(chan bool, 1),
 			name:    testName,
 			parent:  &t.common,
 			level:   t.level + 1,
@@ -1408,6 +1476,25 @@
 		return
 	}
 
+	if *shuffle != "off" {
+		var n int64
+		var err error
+		if *shuffle == "on" {
+			n = time.Now().UnixNano()
+		} else {
+			n, err = strconv.ParseInt(*shuffle, 10, 64)
+			if err != nil {
+				fmt.Fprintln(os.Stderr, `testing: -shuffle should be "off", "on", or a valid integer:`, err)
+				m.exitCode = 2
+				return
+			}
+		}
+		fmt.Println("-test.shuffle", n)
+		rng := rand.New(rand.NewSource(n))
+		rng.Shuffle(len(m.tests), func(i, j int) { m.tests[i], m.tests[j] = m.tests[j], m.tests[i] })
+		rng.Shuffle(len(m.benchmarks), func(i, j int) { m.benchmarks[i], m.benchmarks[j] = m.benchmarks[j], m.benchmarks[i] })
+	}
+
 	parseCpuList()
 
 	m.before()
@@ -1497,7 +1584,7 @@
 			ctx.deadline = deadline
 			t := &T{
 				common: common{
-					signal:  make(chan bool),
+					signal:  make(chan bool, 1),
 					barrier: make(chan bool),
 					w:       os.Stdout,
 				},
@@ -1510,11 +1597,12 @@
 				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 }()
 			})
+			select {
+			case <-t.signal:
+			default:
+				panic("internal error: tRunner exited without sending on t.signal")
+			}
 			ok = ok && !t.Failed()
 			ran = ran || t.ran
 		}
diff --git a/src/testing/testing_test.go b/src/testing/testing_test.go
index 0f09698..08ae239 100644
--- a/src/testing/testing_test.go
+++ b/src/testing/testing_test.go
@@ -58,6 +58,9 @@
 	t.Run("test:subtest", testTempDir)
 	t.Run("test/..", testTempDir)
 	t.Run("../test", testTempDir)
+	t.Run("test[]", testTempDir)
+	t.Run("test*", testTempDir)
+	t.Run("äöüéè", testTempDir)
 }
 
 func testTempDir(t *testing.T) {
@@ -74,7 +77,7 @@
 			if err != nil {
 				t.Fatal(err)
 			}
-			t.Errorf("directory %q stil exists: %v, isDir=%v", dir, fi, fi.IsDir())
+			t.Errorf("directory %q still exists: %v, isDir=%v", dir, fi, fi.IsDir())
 		default:
 			if !t.Failed() {
 				t.Fatal("never received dir channel")
@@ -108,4 +111,92 @@
 	if len(files) > 0 {
 		t.Errorf("unexpected %d files in TempDir: %v", len(files), files)
 	}
+
+	glob := filepath.Join(dir, "*.txt")
+	if _, err := filepath.Glob(glob); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestSetenv(t *testing.T) {
+	tests := []struct {
+		name               string
+		key                string
+		initialValueExists bool
+		initialValue       string
+		newValue           string
+	}{
+		{
+			name:               "initial value exists",
+			key:                "GO_TEST_KEY_1",
+			initialValueExists: true,
+			initialValue:       "111",
+			newValue:           "222",
+		},
+		{
+			name:               "initial value exists but empty",
+			key:                "GO_TEST_KEY_2",
+			initialValueExists: true,
+			initialValue:       "",
+			newValue:           "222",
+		},
+		{
+			name:               "initial value is not exists",
+			key:                "GO_TEST_KEY_3",
+			initialValueExists: false,
+			initialValue:       "",
+			newValue:           "222",
+		},
+	}
+
+	for _, test := range tests {
+		if test.initialValueExists {
+			if err := os.Setenv(test.key, test.initialValue); err != nil {
+				t.Fatalf("unable to set env: got %v", err)
+			}
+		} else {
+			os.Unsetenv(test.key)
+		}
+
+		t.Run(test.name, func(t *testing.T) {
+			t.Setenv(test.key, test.newValue)
+			if os.Getenv(test.key) != test.newValue {
+				t.Fatalf("unexpected value after t.Setenv: got %s, want %s", os.Getenv(test.key), test.newValue)
+			}
+		})
+
+		got, exists := os.LookupEnv(test.key)
+		if got != test.initialValue {
+			t.Fatalf("unexpected value after t.Setenv cleanup: got %s, want %s", got, test.initialValue)
+		}
+		if exists != test.initialValueExists {
+			t.Fatalf("unexpected value after t.Setenv cleanup: got %t, want %t", exists, test.initialValueExists)
+		}
+	}
+}
+
+func TestSetenvWithParallelAfterSetenv(t *testing.T) {
+	defer func() {
+		want := "testing: t.Parallel called after t.Setenv; cannot set environment variables in parallel tests"
+		if got := recover(); got != want {
+			t.Fatalf("expected panic; got %#v want %q", got, want)
+		}
+	}()
+
+	t.Setenv("GO_TEST_KEY_1", "value")
+
+	t.Parallel()
+}
+
+func TestSetenvWithParallelBeforeSetenv(t *testing.T) {
+	defer func() {
+		want := "testing: t.Setenv called after t.Parallel; cannot set environment variables in parallel tests"
+		if got := recover(); got != want {
+			t.Fatalf("expected panic; got %#v want %q", got, want)
+		}
+	}()
+
+	t.Parallel()
+
+	t.Setenv("GO_TEST_KEY_1", "value")
 }
diff --git a/src/text/scanner/scanner.go b/src/text/scanner/scanner.go
index e0847a7..c5fc4ff 100644
--- a/src/text/scanner/scanner.go
+++ b/src/text/scanner/scanner.go
@@ -23,7 +23,7 @@
 	"unicode/utf8"
 )
 
-// A source position is represented by a Position value.
+// Position is a value that represents a source position.
 // A position is valid if Line > 0.
 type Position struct {
 	Filename string // filename, if any
diff --git a/src/text/template/exec.go b/src/text/template/exec.go
index 19154fc..5ad3b4e 100644
--- a/src/text/template/exec.go
+++ b/src/text/template/exec.go
@@ -179,10 +179,7 @@
 // A template may be executed safely in parallel, although if parallel
 // executions share a Writer the output may be interleaved.
 func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
-	var tmpl *Template
-	if t.common != nil {
-		tmpl = t.tmpl[name]
-	}
+	tmpl := t.Lookup(name)
 	if tmpl == nil {
 		return fmt.Errorf("template: no template %q associated with template %q", name, t.name)
 	}
@@ -230,6 +227,8 @@
 		return ""
 	}
 	var b strings.Builder
+	t.muTmpl.RLock()
+	defer t.muTmpl.RUnlock()
 	for name, tmpl := range t.tmpl {
 		if tmpl.Tree == nil || tmpl.Root == nil {
 			continue
@@ -401,7 +400,7 @@
 
 func (s *state) walkTemplate(dot reflect.Value, t *parse.TemplateNode) {
 	s.at(t)
-	tmpl := s.tmpl.tmpl[t.Name]
+	tmpl := s.tmpl.Lookup(t.Name)
 	if tmpl == nil {
 		s.errorf("template %q not defined", t.Name)
 	}
@@ -615,7 +614,7 @@
 		tField, ok := receiver.Type().FieldByName(fieldName)
 		if ok {
 			field := receiver.FieldByIndex(tField.Index)
-			if tField.PkgPath != "" { // field is unexported
+			if !tField.IsExported() {
 				s.errorf("%s is an unexported field of struct type %s", fieldName, typ)
 			}
 			// If it's a function, we must call it.
@@ -727,7 +726,7 @@
 	// error to the caller.
 	if err != nil {
 		s.at(node)
-		s.errorf("error calling %s: %v", name, err)
+		s.errorf("error calling %s: %w", name, err)
 	}
 	if v.Type() == reflectValueType {
 		v = v.Interface().(reflect.Value)
diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go
index 1a129ed..ef52164 100644
--- a/src/text/template/exec_test.go
+++ b/src/text/template/exec_test.go
@@ -12,6 +12,7 @@
 	"io"
 	"reflect"
 	"strings"
+	"sync"
 	"testing"
 )
 
@@ -902,6 +903,28 @@
 	}
 }
 
+type CustomError struct{}
+
+func (*CustomError) Error() string { return "heyo !" }
+
+// Check that a custom error can be returned.
+func TestExecError_CustomError(t *testing.T) {
+	failingFunc := func() (string, error) {
+		return "", &CustomError{}
+	}
+	tmpl := Must(New("top").Funcs(FuncMap{
+		"err": failingFunc,
+	}).Parse("{{ err }}"))
+
+	var b bytes.Buffer
+	err := tmpl.Execute(&b, nil)
+
+	var e *CustomError
+	if !errors.As(err, &e) {
+		t.Fatalf("expected custom error; got %s", err)
+	}
+}
+
 func TestJSEscaping(t *testing.T) {
 	testCases := []struct {
 		in, exp string
@@ -1178,8 +1201,11 @@
 	{"eq .Ptr .NilPtr", "false", true},
 	{"eq .NilPtr .NilPtr", "true", true},
 	{"eq .Iface1 .Iface1", "true", true},
-	{"eq .Iface1 .Iface2", "false", true},
-	{"eq .Iface2 .Iface2", "true", true},
+	{"eq .Iface1 .NilIface", "false", true},
+	{"eq .NilIface .NilIface", "true", true},
+	{"eq .NilIface .Iface1", "false", true},
+	{"eq .NilIface 0", "false", true},
+	{"eq 0 .NilIface", "false", true},
 	// Errors
 	{"eq `xy` 1", "", false},       // Different types.
 	{"eq 2 2.0", "", false},        // Different types.
@@ -1194,12 +1220,12 @@
 func TestComparison(t *testing.T) {
 	b := new(bytes.Buffer)
 	var cmpStruct = struct {
-		Uthree, Ufour  uint
-		NegOne, Three  int
-		Ptr, NilPtr    *int
-		Map            map[int]int
-		V1, V2         V
-		Iface1, Iface2 fmt.Stringer
+		Uthree, Ufour    uint
+		NegOne, Three    int
+		Ptr, NilPtr      *int
+		Map              map[int]int
+		V1, V2           V
+		Iface1, NilIface fmt.Stringer
 	}{
 		Uthree: 3,
 		Ufour:  4,
@@ -1710,3 +1736,40 @@
 		t.Errorf("%s", err)
 	}
 }
+
+// Issue 39807: data race in html/template & text/template
+func TestIssue39807(t *testing.T) {
+	var wg sync.WaitGroup
+
+	tplFoo, err := New("foo").Parse(`{{ template "bar" . }}`)
+	if err != nil {
+		t.Error(err)
+	}
+
+	tplBar, err := New("bar").Parse("bar")
+	if err != nil {
+		t.Error(err)
+	}
+
+	gofuncs := 10
+	numTemplates := 10
+
+	for i := 1; i <= gofuncs; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			for j := 0; j < numTemplates; j++ {
+				_, err := tplFoo.AddParseTree(tplBar.Name(), tplBar.Tree)
+				if err != nil {
+					t.Error(err)
+				}
+				err = tplFoo.Execute(io.Discard, nil)
+				if err != nil {
+					t.Error(err)
+				}
+			}
+		}()
+	}
+
+	wg.Wait()
+}
diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go
index 1b6940a..fff833e 100644
--- a/src/text/template/funcs.go
+++ b/src/text/template/funcs.go
@@ -23,6 +23,9 @@
 // return value evaluates to non-nil during execution, execution terminates and
 // Execute returns that error.
 //
+// Errors returned by Execute wrap the underlying error; call errors.As to
+// uncover them.
+//
 // When template execution invokes a function with an argument list, that list
 // must be assignable to the function's parameter types. Functions meant to
 // apply to arguments of arbitrary type can use parameters of type interface{} or
@@ -344,7 +347,7 @@
 
 		var err error
 		if argv[i], err = prepareArg(arg, argType); err != nil {
-			return reflect.Value{}, fmt.Errorf("arg %d: %s", i, err)
+			return reflect.Value{}, fmt.Errorf("arg %d: %w", i, err)
 		}
 	}
 	return safeCall(fn, argv)
@@ -475,7 +478,9 @@
 			case k1 == uintKind && k2 == intKind:
 				truth = arg.Int() >= 0 && arg1.Uint() == uint64(arg.Int())
 			default:
-				return false, errBadComparison
+				if arg1 != zero && arg != zero {
+					return false, errBadComparison
+				}
 			}
 		} else {
 			switch k1 {
@@ -492,7 +497,7 @@
 			case uintKind:
 				truth = arg1.Uint() == arg.Uint()
 			default:
-				if arg == zero {
+				if arg == zero || arg1 == zero {
 					truth = arg1 == arg
 				} else {
 					if t2 := arg.Type(); !t2.Comparable() {
diff --git a/src/text/template/link_test.go b/src/text/template/link_test.go
index 9dc70df..e1d3136 100644
--- a/src/text/template/link_test.go
+++ b/src/text/template/link_test.go
@@ -39,11 +39,7 @@
 	t.Used()
 }
 `
-	td, err := os.MkdirTemp("", "text_template_TestDeadCodeElimination")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(td)
+	td := t.TempDir()
 
 	if err := os.WriteFile(filepath.Join(td, "x.go"), []byte(prog), 0644); err != nil {
 		t.Fatal(err)
diff --git a/src/text/template/parse/parse.go b/src/text/template/parse/parse.go
index 5e6e512..1a63961 100644
--- a/src/text/template/parse/parse.go
+++ b/src/text/template/parse/parse.go
@@ -39,6 +39,7 @@
 
 const (
 	ParseComments Mode = 1 << iota // parse comments and add them to AST
+	SkipFuncCheck                  // do not check that functions are defined
 )
 
 // Copy returns a copy of the Tree. Any parsing state is discarded.
@@ -689,7 +690,8 @@
 func (t *Tree) term() Node {
 	switch token := t.nextNonSpace(); token.typ {
 	case itemIdentifier:
-		if !t.hasFunction(token.val) {
+		checkFunc := t.Mode&SkipFuncCheck == 0
+		if checkFunc && !t.hasFunction(token.val) {
 			t.errorf("function %q not defined", token.val)
 		}
 		return NewIdentifier(token.val).SetTree(t).SetPos(token.pos)
diff --git a/src/text/template/parse/parse_test.go b/src/text/template/parse/parse_test.go
index 220f984..9b1be27 100644
--- a/src/text/template/parse/parse_test.go
+++ b/src/text/template/parse/parse_test.go
@@ -379,6 +379,22 @@
 	}
 }
 
+func TestSkipFuncCheck(t *testing.T) {
+	oldTextFormat := textFormat
+	textFormat = "%q"
+	defer func() { textFormat = oldTextFormat }()
+	tr := New("skip func check")
+	tr.Mode = SkipFuncCheck
+	tmpl, err := tr.Parse("{{fn 1 2}}", "", "", make(map[string]*Tree))
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	expected := "{{fn 1 2}}"
+	if result := tmpl.Root.String(); result != expected {
+		t.Errorf("got\n\t%v\nexpected\n\t%v", result, expected)
+	}
+}
+
 type isEmptyTest struct {
 	name  string
 	input string
diff --git a/src/text/template/template.go b/src/text/template/template.go
index ec26eb4..fd74d45 100644
--- a/src/text/template/template.go
+++ b/src/text/template/template.go
@@ -13,6 +13,7 @@
 // common holds the information shared by related templates.
 type common struct {
 	tmpl   map[string]*Template // Map from name to defined templates.
+	muTmpl sync.RWMutex         // protects tmpl
 	option option
 	// We use two maps, one for parsing and one for execution.
 	// This separation makes the API cleaner since it doesn't
@@ -88,6 +89,8 @@
 	if t.common == nil {
 		return nt, nil
 	}
+	t.muTmpl.RLock()
+	defer t.muTmpl.RUnlock()
 	for k, v := range t.tmpl {
 		if k == t.name {
 			nt.tmpl[t.name] = nt
@@ -124,6 +127,8 @@
 // its definition. If it has been defined and already has that name, the existing
 // definition is replaced; otherwise a new template is created, defined, and returned.
 func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error) {
+	t.muTmpl.Lock()
+	defer t.muTmpl.Unlock()
 	t.init()
 	nt := t
 	if name != t.name {
@@ -142,6 +147,8 @@
 		return nil
 	}
 	// Return a slice so we don't expose the map.
+	t.muTmpl.RLock()
+	defer t.muTmpl.RUnlock()
 	m := make([]*Template, 0, len(t.tmpl))
 	for _, v := range t.tmpl {
 		m = append(m, v)
@@ -182,6 +189,8 @@
 	if t.common == nil {
 		return nil
 	}
+	t.muTmpl.RLock()
+	defer t.muTmpl.RUnlock()
 	return t.tmpl[name]
 }
 
diff --git a/src/time/embed.go b/src/time/embed.go
index cb4fdac..34490c8 100644
--- a/src/time/embed.go
+++ b/src/time/embed.go
@@ -5,6 +5,7 @@
 // This file is used with build tag timetzdata to embed tzdata into
 // the binary.
 
+//go:build timetzdata
 // +build timetzdata
 
 package time
diff --git a/src/time/export_test.go b/src/time/export_test.go
index f4a8cd9..9baad60 100644
--- a/src/time/export_test.go
+++ b/src/time/export_test.go
@@ -51,6 +51,7 @@
 	RuleJulian       = RuleKind(ruleJulian)
 	RuleDOY          = RuleKind(ruleDOY)
 	RuleMonthWeekDay = RuleKind(ruleMonthWeekDay)
+	UnixToInternal   = unixToInternal
 )
 
 type Rule struct {
@@ -128,3 +129,5 @@
 	stdFracSecond9 | 8<<stdArgShift: ".99999999",
 	stdFracSecond9 | 9<<stdArgShift: ".999999999",
 }
+
+var Quote = quote
diff --git a/src/time/format.go b/src/time/format.go
index f11fb7e..f4b4f48 100644
--- a/src/time/format.go
+++ b/src/time/format.go
@@ -7,57 +7,18 @@
 import "errors"
 
 // These are predefined layouts for use in Time.Format and time.Parse.
-// The reference time used in the layouts is the specific time:
-//	Mon Jan 2 15:04:05 MST 2006
-// which is Unix time 1136239445. Since MST is GMT-0700,
-// the reference time can be thought of as
+// The reference time used in these layouts is the specific time stamp:
 //	01/02 03:04:05PM '06 -0700
-// To define your own format, write down what the reference time would look
-// like formatted your way; see the values of constants like ANSIC,
-// StampMicro or Kitchen for examples. The model is to demonstrate what the
-// reference time looks like so that the Format and Parse methods can apply
-// the same transformation to a general time value.
+// (January 2, 15:04:05, 2006, in time zone seven hours west of GMT).
+// That value is recorded as the constant named Layout, listed below. As a Unix
+// time, this is 1136239445. Since MST is GMT-0700, the reference would be
+// printed by the Unix date command as:
+//	Mon Jan 2 15:04:05 MST 2006
+// It is a regrettable historic error that the date uses the American convention
+// of putting the numerical month before the day.
 //
-// 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.
-//
-// A decimal point followed by one or more zeros represents a fractional
-// second, printed to the given number of decimal places. A decimal point
-// followed by one or more nines represents a fractional second, printed to
-// the given number of decimal places, with trailing zeros removed.
-// When parsing (only), the input may contain a fractional second
-// field immediately after the seconds field, even if the layout does not
-// signify its presence. In that case a decimal point followed by a maximal
-// series of digits is parsed as a fractional second.
-//
-// Numeric time zone offsets format as follows:
-//	-0700  ±hhmm
-//	-07:00 ±hh:mm
-//	-07    ±hh
-// Replacing the sign in the format with a Z triggers
-// the ISO 8601 behavior of printing Z instead of an
-// offset for the UTC zone. Thus:
-//	Z0700  Z or ±hhmm
-//	Z07:00 Z or ±hh:mm
-//	Z07    Z or ±hh
-//
-// The recognized day of week formats are "Mon" and "Monday".
-// The recognized month formats are "Jan" and "January".
-//
-// The formats 2, _2, and 02 are unpadded, space-padded, and zero-padded
-// day of month. The formats __2 and 002 are space-padded and zero-padded
-// three-character day of year; there is no unpadded day of year format.
-//
-// Text in the format string that is not recognized as part of the reference
-// 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
-// of the layout string in detail and is a good reference.
+// The 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
 // only to local times. Applying them to UTC times will use "UTC" as the
@@ -70,7 +31,65 @@
 // permitted by the RFCs and they do accept time formats not formally defined.
 // The RFC3339Nano format removes trailing zeros from the seconds field
 // and thus may not sort correctly once formatted.
+//
+// Most programs can use one of the defined constants as the layout passed to
+// Format or Parse. The rest of this comment can be ignored unless you are
+// creating a custom layout string.
+//
+// To define your own format, write down what the reference time would look like
+// formatted your way; see the values of constants like ANSIC, StampMicro or
+// Kitchen for examples. The model is to demonstrate what the reference time
+// looks like so that the Format and Parse methods can apply the same
+// transformation to a general time value.
+//
+// Here is a summary of the components of a layout string. Each element shows by
+// example the formatting of an element of the reference time. Only these values
+// are recognized. Text in the layout string that is not recognized as part of
+// the reference time is echoed verbatim during Format and expected to appear
+// verbatim in the input to Parse.
+//
+//	Year: "2006" "06"
+//	Month: "Jan" "January"
+//	Textual day of the week: "Mon" "Monday"
+//	Numeric day of the month: "2" "_2" "02"
+//	Numeric day of the year: "__2" "002"
+//	Hour: "15" "3" "03" (PM or AM)
+//	Minute: "4" "04"
+//	Second: "5" "05"
+//	AM/PM mark: "PM"
+//
+// Numeric time zone offsets format as follows:
+//	"-0700"  ±hhmm
+//	"-07:00" ±hh:mm
+//	"-07"    ±hh
+// Replacing the sign in the format with a Z triggers
+// the ISO 8601 behavior of printing Z instead of an
+// offset for the UTC zone. Thus:
+//	"Z0700"  Z or ±hhmm
+//	"Z07:00" Z or ±hh:mm
+//	"Z07"    Z or ±hh
+//
+// Within the format string, the underscores in "_2" and "__2" represent spaces
+// that may be replaced by digits if the following number has multiple digits,
+// for compatibility with fixed-width Unix time formats. A leading zero represents
+// a zero-padded value.
+//
+// The formats  and 002 are space-padded and zero-padded
+// three-character day of year; there is no unpadded day of year format.
+//
+// A comma or decimal point followed by one or more zeros represents
+// a fractional second, printed to the given number of decimal places.
+// A comma or decimal point followed by one or more nines represents
+// a fractional second, printed to the given number of decimal places, with
+// trailing zeros removed.
+// For example "15:04:05,000" or "15:04:05.000" formats or parses with
+// millisecond precision.
+//
+// Some valid layouts are invalid time values for time.Parse, due to formats
+// such as _ for space padding and Z for zone information.
+//
 const (
+	Layout      = "01/02 03:04:05PM '06 -0700" // The reference time, in numerical order.
 	ANSIC       = "Mon Jan _2 15:04:05 2006"
 	UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
 	RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
@@ -261,7 +280,7 @@
 				return layout[0:i], stdISO8601ShortTZ, layout[i+3:]
 			}
 
-		case '.': // .000 or .999 - repeated digits for fractional seconds.
+		case '.', ',': // ,000, or .000, or ,999, or .999 - repeated digits for fractional seconds.
 			if i+1 < len(layout) && (layout[i+1] == '0' || layout[i+1] == '9') {
 				ch := layout[i+1]
 				j := i + 1
@@ -476,22 +495,66 @@
 	return s
 }
 
-// Format returns a textual representation of the time value formatted
-// according to layout, which defines the format by showing how the reference
-// time, defined to be
-//	Mon Jan 2 15:04:05 -0700 MST 2006
-// would be displayed if it were the value; it serves as an example of the
-// desired output. The same display rules will then be applied to the time
-// value.
+// GoString implements fmt.GoStringer and formats t to be printed in Go source
+// code.
+func (t Time) GoString() string {
+	buf := []byte("time.Date(")
+	buf = appendInt(buf, t.Year(), 0)
+	month := t.Month()
+	if January <= month && month <= December {
+		buf = append(buf, ", time."...)
+		buf = append(buf, t.Month().String()...)
+	} else {
+		// It's difficult to construct a time.Time with a date outside the
+		// standard range but we might as well try to handle the case.
+		buf = appendInt(buf, int(month), 0)
+	}
+	buf = append(buf, ", "...)
+	buf = appendInt(buf, t.Day(), 0)
+	buf = append(buf, ", "...)
+	buf = appendInt(buf, t.Hour(), 0)
+	buf = append(buf, ", "...)
+	buf = appendInt(buf, t.Minute(), 0)
+	buf = append(buf, ", "...)
+	buf = appendInt(buf, t.Second(), 0)
+	buf = append(buf, ", "...)
+	buf = appendInt(buf, t.Nanosecond(), 0)
+	buf = append(buf, ", "...)
+	switch loc := t.Location(); loc {
+	case UTC, nil:
+		buf = append(buf, "time.UTC"...)
+	case Local:
+		buf = append(buf, "time.Local"...)
+	default:
+		// there are several options for how we could display this, none of
+		// which are great:
+		//
+		// - use Location(loc.name), which is not technically valid syntax
+		// - use LoadLocation(loc.name), which will cause a syntax error when
+		// embedded and also would require us to escape the string without
+		// importing fmt or strconv
+		// - try to use FixedZone, which would also require escaping the name
+		// and would represent e.g. "America/Los_Angeles" daylight saving time
+		// shifts inaccurately
+		// - use the pointer format, which is no worse than you'd get with the
+		// old fmt.Sprintf("%#v", t) format.
+		//
+		// Of these, Location(loc.name) is the least disruptive. This is an edge
+		// case we hope not to hit too often.
+		buf = append(buf, `time.Location(`...)
+		buf = append(buf, []byte(quote(loc.name))...)
+		buf = append(buf, `)`...)
+	}
+	buf = append(buf, ')')
+	return string(buf)
+}
+
+// Format returns a textual representation of the time value formatted according
+// to the layout defined by the argument. See the documentation for the
+// constant called Layout to see how to represent the layout format.
 //
-// A fractional second is represented by adding a period and zeros
-// to the end of the seconds section of layout string, as in "15:04:05.000"
-// to format a time stamp with millisecond precision.
-//
-// Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard
-// and convenient representations of the reference time. For more information
-// about the formats and the definition of the reference time, see the
-// documentation for ANSIC and the other constants defined by this package.
+// The executable example for Time.Format demonstrates the working
+// of the layout string in detail and is a good reference.
 func (t Time) Format(layout string) string {
 	const bufSize = 64
 	var b []byte
@@ -686,8 +749,48 @@
 	Message    string
 }
 
+// These are borrowed from unicode/utf8 and strconv and replicate behavior in
+// that package, since we can't take a dependency on either.
+const (
+	lowerhex  = "0123456789abcdef"
+	runeSelf  = 0x80
+	runeError = '\uFFFD'
+)
+
 func quote(s string) string {
-	return "\"" + s + "\""
+	buf := make([]byte, 1, len(s)+2) // slice will be at least len(s) + quotes
+	buf[0] = '"'
+	for i, c := range s {
+		if c >= runeSelf || c < ' ' {
+			// This means you are asking us to parse a time.Duration or
+			// time.Location with unprintable or non-ASCII characters in it.
+			// We don't expect to hit this case very often. We could try to
+			// reproduce strconv.Quote's behavior with full fidelity but
+			// given how rarely we expect to hit these edge cases, speed and
+			// conciseness are better.
+			var width int
+			if c == runeError {
+				width = 1
+				if i+2 < len(s) && s[i:i+3] == string(runeError) {
+					width = 3
+				}
+			} else {
+				width = len(string(c))
+			}
+			for j := 0; j < width; j++ {
+				buf = append(buf, `\x`...)
+				buf = append(buf, lowerhex[s[i+j]>>4])
+				buf = append(buf, lowerhex[s[i+j]&0xF])
+			}
+		} else {
+			if c == '"' || c == '\\' {
+				buf = append(buf, '\\')
+			}
+			buf = append(buf, string(c)...)
+		}
+	}
+	buf = append(buf, '"')
+	return string(buf)
 }
 
 // Error returns the string representation of a ParseError.
@@ -771,21 +874,19 @@
 }
 
 // Parse parses a formatted string and returns the time value it represents.
-// The layout defines the format by showing how the reference time,
-// defined to be
-//	Mon Jan 2 15:04:05 -0700 MST 2006
-// would be interpreted if it were the value; it serves as an example of
-// the input format. The same interpretation will then be made to the
-// input string.
+// See the documentation for the constant called Layout to see how to
+// represent the format. The second argument must be parseable using
+// the format string (layout) provided as the first argument.
 //
-// Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard
-// and convenient representations of the reference time. For more information
-// about the formats and the definition of the reference time, see the
-// documentation for ANSIC and the other constants defined by this package.
-// Also, the executable example for Time.Format demonstrates the working
-// of the layout string in detail and is a good reference.
+// The 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
+// When parsing (only), the input may contain a fractional second
+// field immediately after the seconds field, even if the layout does not
+// signify its presence. In that case either a comma or a decimal point
+// followed by a maximal series of digits is parsed as a fractional second.
+//
+// Elements omitted from the layout are assumed to be zero or, when
 // zero is impossible, one, so parsing "3:04pm" returns the time
 // corresponding to Jan 1, year 0, 15:04:00 UTC (note that because the year is
 // 0, this time is before the zero Time).
@@ -795,6 +896,8 @@
 // For layouts specifying the two-digit year 06, a value NN >= 69 will be treated
 // as 19NN and a value NN < 69 will be treated as 20NN.
 //
+// The remainder of this comment describes the handling of time zones.
+//
 // In the absence of a time zone indicator, Parse returns a time in UTC.
 //
 // When parsing a time with a zone offset like -0700, if the offset corresponds
@@ -940,7 +1043,7 @@
 			}
 			// Special case: do we have a fractional second but no
 			// fractional second in the format?
-			if len(value) >= 2 && value[0] == '.' && isDigit(value, 1) {
+			if len(value) >= 2 && commaOrPeriod(value[0]) && isDigit(value, 1) {
 				_, std, _ = nextStdChunk(layout)
 				std &= stdMask
 				if std == stdFracSecond0 || std == stdFracSecond9 {
@@ -1070,7 +1173,7 @@
 			value = value[ndigit:]
 
 		case stdFracSecond9:
-			if len(value) < 2 || value[0] != '.' || value[1] < '0' || '9' < value[1] {
+			if len(value) < 2 || !commaOrPeriod(value[0]) || value[1] < '0' || '9' < value[1] {
 				// Fractional second omitted.
 				break
 			}
@@ -1152,7 +1255,7 @@
 
 		// Look for local zone with the given offset.
 		// If that zone was in effect at the given time, use it.
-		name, offset, _, _ := local.lookup(t.unixSec())
+		name, offset, _, _, _ := local.lookup(t.unixSec())
 		if offset == zoneOffset && (zoneName == "" || name == zoneName) {
 			t.setLoc(local)
 			return t, nil
@@ -1279,8 +1382,12 @@
 	return len(value) - len(rem)
 }
 
+func commaOrPeriod(b byte) bool {
+	return b == '.' || b == ','
+}
+
 func parseNanoseconds(value string, nbytes int) (ns int, rangeErrString string, err error) {
-	if value[0] != '.' {
+	if !commaOrPeriod(value[0]) {
 		err = errBad
 		return
 	}
diff --git a/src/time/format_test.go b/src/time/format_test.go
index 4574d20..1af41e2 100644
--- a/src/time/format_test.go
+++ b/src/time/format_test.go
@@ -129,6 +129,31 @@
 	}
 }
 
+var goStringTests = []struct {
+	in   Time
+	want string
+}{
+	{Date(2009, February, 5, 5, 0, 57, 12345600, UTC),
+		"time.Date(2009, time.February, 5, 5, 0, 57, 12345600, time.UTC)"},
+	{Date(2009, February, 5, 5, 0, 57, 12345600, Local),
+		"time.Date(2009, time.February, 5, 5, 0, 57, 12345600, time.Local)"},
+	{Date(2009, February, 5, 5, 0, 57, 12345600, FixedZone("Europe/Berlin", 3*60*60)),
+		`time.Date(2009, time.February, 5, 5, 0, 57, 12345600, time.Location("Europe/Berlin"))`,
+	},
+	{Date(2009, February, 5, 5, 0, 57, 12345600, FixedZone("Non-ASCII character ⏰", 3*60*60)),
+		`time.Date(2009, time.February, 5, 5, 0, 57, 12345600, time.Location("Non-ASCII character \xe2\x8f\xb0"))`,
+	},
+}
+
+func TestGoString(t *testing.T) {
+	// The numeric time represents Thu Feb  4 21:00:57.012345600 PST 2009
+	for _, tt := range goStringTests {
+		if tt.in.GoString() != tt.want {
+			t.Errorf("GoString (%q): got %q want %q", tt.in, tt.in.GoString(), tt.want)
+		}
+	}
+}
+
 // issue 12440.
 func TestFormatSingleDigits(t *testing.T) {
 	time := Date(2001, 2, 3, 4, 5, 6, 700000000, UTC)
@@ -207,9 +232,13 @@
 	{"ANSIC", ANSIC, "THU FEB 4 21:00:57 2010", false, true, 1, 0},
 	{"ANSIC", ANSIC, "thu feb 4 21:00:57 2010", false, true, 1, 0},
 	// Fractional seconds.
-	{"millisecond", "Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 21:00:57.012 2010", false, true, 1, 3},
-	{"microsecond", "Mon Jan _2 15:04:05.000000 2006", "Thu Feb  4 21:00:57.012345 2010", false, true, 1, 6},
-	{"nanosecond", "Mon Jan _2 15:04:05.000000000 2006", "Thu Feb  4 21:00:57.012345678 2010", false, true, 1, 9},
+	{"millisecond:: dot separator", "Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 21:00:57.012 2010", false, true, 1, 3},
+	{"microsecond:: dot separator", "Mon Jan _2 15:04:05.000000 2006", "Thu Feb  4 21:00:57.012345 2010", false, true, 1, 6},
+	{"nanosecond:: dot separator", "Mon Jan _2 15:04:05.000000000 2006", "Thu Feb  4 21:00:57.012345678 2010", false, true, 1, 9},
+	{"millisecond:: comma separator", "Mon Jan _2 15:04:05,000 2006", "Thu Feb  4 21:00:57.012 2010", false, true, 1, 3},
+	{"microsecond:: comma separator", "Mon Jan _2 15:04:05,000000 2006", "Thu Feb  4 21:00:57.012345 2010", false, true, 1, 6},
+	{"nanosecond:: comma separator", "Mon Jan _2 15:04:05,000000000 2006", "Thu Feb  4 21:00:57.012345678 2010", false, true, 1, 9},
+
 	// Leading zeros in other places should not be taken as fractional seconds.
 	{"zero1", "2006.01.02.15.04.05.0", "2010.02.04.21.00.57.0", false, false, 1, 1},
 	{"zero2", "2006.01.02.15.04.05.00", "2010.02.04.21.00.57.01", false, false, 1, 2},
@@ -222,12 +251,20 @@
 	// Accept any number of fractional second digits (including none) for .999...
 	// In Go 1, .999... was completely ignored in the format, meaning the first two
 	// cases would succeed, but the next four would not. Go 1.1 accepts all six.
+	// decimal "." separator.
 	{"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57 -0800 PST", true, false, 1, 0},
 	{"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57 -0800 PST", true, false, 1, 0},
 	{"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57.0123 -0800 PST", true, false, 1, 4},
 	{"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57.0123 -0800 PST", true, false, 1, 4},
 	{"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57.012345678 -0800 PST", true, false, 1, 9},
 	{"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57.012345678 -0800 PST", true, false, 1, 9},
+	// comma "," separator.
+	{"", "2006-01-02 15:04:05,9999 -0700 MST", "2010-02-04 21:00:57 -0800 PST", true, false, 1, 0},
+	{"", "2006-01-02 15:04:05,999999999 -0700 MST", "2010-02-04 21:00:57 -0800 PST", true, false, 1, 0},
+	{"", "2006-01-02 15:04:05,9999 -0700 MST", "2010-02-04 21:00:57.0123 -0800 PST", true, false, 1, 4},
+	{"", "2006-01-02 15:04:05,999999999 -0700 MST", "2010-02-04 21:00:57.0123 -0800 PST", true, false, 1, 4},
+	{"", "2006-01-02 15:04:05,9999 -0700 MST", "2010-02-04 21:00:57.012345678 -0800 PST", true, false, 1, 9},
+	{"", "2006-01-02 15:04:05,999999999 -0700 MST", "2010-02-04 21:00:57.012345678 -0800 PST", true, false, 1, 9},
 
 	// issue 4502.
 	{"", StampNano, "Feb  4 21:00:57.012345678", false, false, -1, 9},
@@ -551,6 +588,10 @@
 	// invalid or mismatched day-of-year
 	{"Jan _2 002 2006", "Feb  4 034 2006", "day-of-year does not match day"},
 	{"Jan _2 002 2006", "Feb  4 004 2006", "day-of-year does not match month"},
+
+	// issue 45391.
+	{`"2006-01-02T15:04:05Z07:00"`, "0", `parsing time "0" as "\"2006-01-02T15:04:05Z07:00\"": cannot parse "0" as "\""`},
+	{RFC3339, "\"", `parsing time "\"" as "2006-01-02T15:04:05Z07:00": cannot parse "\"" as "2006"`},
 }
 
 func TestParseErrors(t *testing.T) {
@@ -770,3 +811,24 @@
 		}
 	}
 }
+
+// Issue 45391.
+func TestQuote(t *testing.T) {
+	tests := []struct {
+		s, want string
+	}{
+		{`"`, `"\""`},
+		{`abc"xyz"`, `"abc\"xyz\""`},
+		{"", `""`},
+		{"abc", `"abc"`},
+		{`☺`, `"\xe2\x98\xba"`},
+		{`☺ hello ☺ hello`, `"\xe2\x98\xba hello \xe2\x98\xba hello"`},
+		{"\x04", `"\x04"`},
+	}
+	for _, tt := range tests {
+		if q := Quote(tt.s); q != tt.want {
+			t.Errorf("Quote(%q) = got %q, want %q", tt.s, q, tt.want)
+		}
+	}
+
+}
diff --git a/src/time/genzabbrs.go b/src/time/genzabbrs.go
index 9825e70..9fd2f2b 100644
--- a/src/time/genzabbrs.go
+++ b/src/time/genzabbrs.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 //
diff --git a/src/time/internal_test.go b/src/time/internal_test.go
index ffe54e4..87a4208 100644
--- a/src/time/internal_test.go
+++ b/src/time/internal_test.go
@@ -62,4 +62,6 @@
 var (
 	MinMonoTime = Time{wall: 1 << 63, ext: -1 << 63, loc: UTC}
 	MaxMonoTime = Time{wall: 1 << 63, ext: 1<<63 - 1, loc: UTC}
+
+	NotMonoNegativeTime = Time{wall: 0, ext: -1<<63 + 50}
 )
diff --git a/src/time/sleep_test.go b/src/time/sleep_test.go
index 6ee0631..e0172bf 100644
--- a/src/time/sleep_test.go
+++ b/src/time/sleep_test.go
@@ -527,6 +527,40 @@
 	}
 }
 
+// Test that rapidly moving a timer earlier doesn't cause it to get dropped.
+// Issue 47329.
+func TestTimerModifiedEarlier(t *testing.T) {
+	past := Until(Unix(0, 0))
+	count := 1000
+	fail := 0
+	for i := 0; i < count; i++ {
+		timer := NewTimer(Hour)
+		for j := 0; j < 10; j++ {
+			if !timer.Stop() {
+				<-timer.C
+			}
+			timer.Reset(past)
+		}
+
+		deadline := NewTimer(10 * Second)
+		defer deadline.Stop()
+		now := Now()
+		select {
+		case <-timer.C:
+			if since := Since(now); since > 8*Second {
+				t.Errorf("timer took too long (%v)", since)
+				fail++
+			}
+		case <-deadline.C:
+			t.Error("deadline expired")
+		}
+	}
+
+	if fail > 0 {
+		t.Errorf("%d failures", fail)
+	}
+}
+
 // Benchmark timer latency when the thread that creates the timer is busy with
 // other work and the timers must be serviced by other threads.
 // https://golang.org/issue/38860
diff --git a/src/time/sys_plan9.go b/src/time/sys_plan9.go
index b7fba08..4dc55e4 100644
--- a/src/time/sys_plan9.go
+++ b/src/time/sys_plan9.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build plan9
 // +build plan9
 
 package time
diff --git a/src/time/sys_unix.go b/src/time/sys_unix.go
index 97b1140..60fc090 100644
--- a/src/time/sys_unix.go
+++ b/src/time/sys_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
 
 package time
diff --git a/src/time/testdata/2020b_Europe_Berlin b/src/time/testdata/2020b_Europe_Berlin
new file mode 100644
index 0000000..465546b
--- /dev/null
+++ b/src/time/testdata/2020b_Europe_Berlin
Binary files differ
diff --git a/src/time/testdata/2021a_America_Nuuk b/src/time/testdata/2021a_America_Nuuk
new file mode 100644
index 0000000..4ddc99d
--- /dev/null
+++ b/src/time/testdata/2021a_America_Nuuk
Binary files differ
diff --git a/src/time/testdata/2021a_Asia_Gaza b/src/time/testdata/2021a_Asia_Gaza
new file mode 100644
index 0000000..58e9fdf
--- /dev/null
+++ b/src/time/testdata/2021a_Asia_Gaza
Binary files differ
diff --git a/src/time/testdata/2021a_Europe_Dublin b/src/time/testdata/2021a_Europe_Dublin
new file mode 100644
index 0000000..4a45ea8
--- /dev/null
+++ b/src/time/testdata/2021a_Europe_Dublin
Binary files differ
diff --git a/src/time/tick_test.go b/src/time/tick_test.go
index 9a1cdf9..b5d0a18 100644
--- a/src/time/tick_test.go
+++ b/src/time/tick_test.go
@@ -52,9 +52,14 @@
 		t1 := Now()
 		dt := t1.Sub(t0)
 		target := 3 * delta * Duration(count/2)
-		slop := target * 2 / 10
+		slop := target * 3 / 10
 		if dt < target-slop || dt > target+slop {
-			errs = append(errs, fmt.Sprintf("%d %s ticks took %s, expected [%s,%s]", count, delta, dt, target-slop, target+slop))
+			errs = append(errs, fmt.Sprintf("%d %s ticks then %d %s ticks took %s, expected [%s,%s]", count/2, delta, count/2, delta*2, dt, target-slop, target+slop))
+			if dt > target+slop {
+				// System may be overloaded; sleep a bit
+				// in the hopes it will recover.
+				Sleep(Second / 2)
+			}
 			continue
 		}
 		// Now test that the ticker stopped.
diff --git a/src/time/time.go b/src/time/time.go
index 8ae6230..4ecc3d8 100644
--- a/src/time/time.go
+++ b/src/time/time.go
@@ -189,8 +189,15 @@
 		t.stripMono()
 	}
 
-	// TODO: Check for overflow.
-	t.ext += d
+	// Check if the sum of t.ext and d overflows and handle it properly.
+	sum := t.ext + d
+	if (sum > t.ext) == (d > 0) {
+		t.ext = sum
+	} else if d > 0 {
+		t.ext = 1<<63 - 1
+	} else {
+		t.ext = -(1<<63 - 1)
+	}
 }
 
 // setLoc sets the location associated with the time.
@@ -440,7 +447,7 @@
 		if l.cacheZone != nil && l.cacheStart <= sec && sec < l.cacheEnd {
 			sec += int64(l.cacheZone.offset)
 		} else {
-			_, offset, _, _ := l.lookup(sec)
+			_, offset, _, _, _ := l.lookup(sec)
 			sec += int64(offset)
 		}
 	}
@@ -461,7 +468,7 @@
 			name = l.cacheZone.name
 			offset = l.cacheZone.offset
 		} else {
-			name, offset, _, _ = l.lookup(sec)
+			name, offset, _, _, _ = l.lookup(sec)
 		}
 		sec += int64(offset)
 	} else {
@@ -1114,7 +1121,7 @@
 // Zone computes the time zone in effect at time t, returning the abbreviated
 // name of the zone (such as "CET") and its offset in seconds east of UTC.
 func (t Time) Zone() (name string, offset int) {
-	name, offset, _, _ = t.loc.lookup(t.unixSec())
+	name, offset, _, _, _ = t.loc.lookup(t.unixSec())
 	return
 }
 
@@ -1128,6 +1135,24 @@
 	return t.unixSec()
 }
 
+// UnixMilli returns t as a Unix time, the number of milliseconds elapsed since
+// January 1, 1970 UTC. The result is undefined if the Unix time in
+// milliseconds cannot be represented by an int64 (a date more than 292 million
+// years before or after 1970). The result does not depend on the
+// location associated with t.
+func (t Time) UnixMilli() int64 {
+	return t.unixSec()*1e3 + int64(t.nsec())/1e6
+}
+
+// UnixMicro returns t as a Unix time, the number of microseconds elapsed since
+// January 1, 1970 UTC. The result is undefined if the Unix time in
+// microseconds cannot be represented by an int64 (a date before year -290307 or
+// after year 294246). The result does not depend on the location associated
+// with t.
+func (t Time) UnixMicro() int64 {
+	return t.unixSec()*1e6 + int64(t.nsec())/1e3
+}
+
 // UnixNano returns t as a Unix time, the number of nanoseconds elapsed
 // since January 1, 1970 UTC. The result is undefined if the Unix time
 // in nanoseconds cannot be represented by an int64 (a date before the year
@@ -1212,7 +1237,7 @@
 
 	if offset == -1*60 {
 		t.setLoc(&utcLoc)
-	} else if _, localoff, _, _ := Local.lookup(t.unixSec()); offset == localoff {
+	} else if _, localoff, _, _, _ := Local.lookup(t.unixSec()); offset == localoff {
 		t.setLoc(Local)
 	} else {
 		t.setLoc(FixedZone("", offset))
@@ -1302,6 +1327,24 @@
 	return unixTime(sec, int32(nsec))
 }
 
+// UnixMilli returns the local Time corresponding to the given Unix time,
+// msec milliseconds since January 1, 1970 UTC.
+func UnixMilli(msec int64) Time {
+	return Unix(msec/1e3, (msec%1e3)*1e6)
+}
+
+// UnixMicro returns the local Time corresponding to the given Unix time,
+// usec microseconds since January 1, 1970 UTC.
+func UnixMicro(usec int64) Time {
+	return Unix(usec/1e6, (usec%1e6)*1e3)
+}
+
+// IsDST reports whether the time in the configured location is in Daylight Savings Time.
+func (t Time) IsDST() bool {
+	_, _, _, _, isDST := t.loc.lookup(t.Unix())
+	return isDST
+}
+
 func isLeap(year int) bool {
 	return year%4 == 0 && (year%100 != 0 || year%400 == 0)
 }
@@ -1377,13 +1420,13 @@
 	// The lookup function expects UTC, so we pass t in the
 	// hope that it will not be too close to a zone transition,
 	// and then adjust if it is.
-	_, offset, start, end := loc.lookup(unix)
+	_, offset, start, end, _ := loc.lookup(unix)
 	if offset != 0 {
 		switch utc := unix - int64(offset); {
 		case utc < start:
-			_, offset, _, _ = loc.lookup(start - 1)
+			_, offset, _, _, _ = loc.lookup(start - 1)
 		case utc >= end:
-			_, offset, _, _ = loc.lookup(end)
+			_, offset, _, _, _ = loc.lookup(end)
 		}
 		unix -= int64(offset)
 	}
diff --git a/src/time/time_test.go b/src/time/time_test.go
index 154198a..cea5f2d 100644
--- a/src/time/time_test.go
+++ b/src/time/time_test.go
@@ -202,6 +202,28 @@
 	}
 }
 
+func TestUnixMilli(t *testing.T) {
+	f := func(msec int64) bool {
+		t := UnixMilli(msec)
+		return t.UnixMilli() == msec
+	}
+	cfg := &quick.Config{MaxCount: 10000}
+	if err := quick.Check(f, cfg); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestUnixMicro(t *testing.T) {
+	f := func(usec int64) bool {
+		t := UnixMicro(usec)
+		return t.UnixMicro() == usec
+	}
+	cfg := &quick.Config{MaxCount: 10000}
+	if err := quick.Check(f, cfg); err != nil {
+		t.Fatal(err)
+	}
+}
+
 // The time routines provide no way to get absolute time
 // (seconds since zero), but we need it to compute the right
 // answer for bizarre roundings like "to the nearest 3 ns".
@@ -895,6 +917,11 @@
 	{".s", `".s"`},
 	{"+.s", `"+.s"`},
 	{"1d", `"1d"`},
+	{"\x85\x85", `"\x85\x85"`},
+	{"\xffff", `"\xffff"`},
+	{"hello \xffff world", `"hello \xffff world"`},
+	{"\uFFFD", `"\xef\xbf\xbd"`},                                             // utf8.RuneError
+	{"\uFFFD hello \uFFFD world", `"\xef\xbf\xbd hello \xef\xbf\xbd world"`}, // utf8.RuneError
 	// overflow
 	{"9223372036854775810ns", `"9223372036854775810ns"`},
 	{"9223372036854775808ns", `"9223372036854775808ns"`},
@@ -959,6 +986,8 @@
 }{
 	{0, `time.Now()`, func() { t = Now() }},
 	{0, `time.Now().UnixNano()`, func() { u = Now().UnixNano() }},
+	{0, `time.Now().UnixMilli()`, func() { u = Now().UnixMilli() }},
+	{0, `time.Now().UnixMicro()`, func() { u = Now().UnixMicro() }},
 }
 
 func TestCountMallocs(t *testing.T) {
@@ -1249,6 +1278,8 @@
 
 	{"Unix", func(t1, t2 Time) bool { return t1.Unix() == t2.Unix() }},
 	{"UnixNano", func(t1, t2 Time) bool { return t1.UnixNano() == t2.UnixNano() }},
+	{"UnixMilli", func(t1, t2 Time) bool { return t1.UnixMilli() == t2.UnixMilli() }},
+	{"UnixMicro", func(t1, t2 Time) bool { return t1.UnixMicro() == t2.UnixMicro() }},
 
 	{"MarshalBinary", func(t1, t2 Time) bool {
 		a1, b1 := t1.MarshalBinary()
@@ -1301,6 +1332,18 @@
 	}
 }
 
+func BenchmarkNowUnixMilli(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		u = Now().UnixMilli()
+	}
+}
+
+func BenchmarkNowUnixMicro(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		u = Now().UnixMicro()
+	}
+}
+
 func BenchmarkFormat(b *testing.B) {
 	t := Unix(1265346057, 0)
 	for i := 0; i < b.N; i++ {
@@ -1465,3 +1508,64 @@
 	}
 	wg.Wait()
 }
+
+func TestTimeIsDST(t *testing.T) {
+	ForceZipFileForTesting(true)
+	defer ForceZipFileForTesting(false)
+
+	tzWithDST, err := LoadLocation("Australia/Sydney")
+	if err != nil {
+		t.Fatalf("could not load tz 'Australia/Sydney': %v", err)
+	}
+	tzWithoutDST, err := LoadLocation("Australia/Brisbane")
+	if err != nil {
+		t.Fatalf("could not load tz 'Australia/Brisbane': %v", err)
+	}
+	tzFixed := FixedZone("FIXED_TIME", 12345)
+
+	tests := [...]struct {
+		time Time
+		want bool
+	}{
+		0: {Date(2009, 1, 1, 12, 0, 0, 0, UTC), false},
+		1: {Date(2009, 6, 1, 12, 0, 0, 0, UTC), false},
+		2: {Date(2009, 1, 1, 12, 0, 0, 0, tzWithDST), true},
+		3: {Date(2009, 6, 1, 12, 0, 0, 0, tzWithDST), false},
+		4: {Date(2009, 1, 1, 12, 0, 0, 0, tzWithoutDST), false},
+		5: {Date(2009, 6, 1, 12, 0, 0, 0, tzWithoutDST), false},
+		6: {Date(2009, 1, 1, 12, 0, 0, 0, tzFixed), false},
+		7: {Date(2009, 6, 1, 12, 0, 0, 0, tzFixed), false},
+	}
+
+	for i, tt := range tests {
+		got := tt.time.IsDST()
+		if got != tt.want {
+			t.Errorf("#%d:: (%#v).IsDST()=%t, want %t", i, tt.time.Format(RFC3339), got, tt.want)
+		}
+	}
+}
+
+func TestTimeAddSecOverflow(t *testing.T) {
+	// Test it with positive delta.
+	var maxInt64 int64 = 1<<63 - 1
+	timeExt := maxInt64 - UnixToInternal - 50
+	notMonoTime := Unix(timeExt, 0)
+	for i := int64(0); i < 100; i++ {
+		sec := notMonoTime.Unix()
+		notMonoTime = notMonoTime.Add(Duration(i * 1e9))
+		if newSec := notMonoTime.Unix(); newSec != sec+i && newSec+UnixToInternal != maxInt64 {
+			t.Fatalf("time ext: %d overflows with positive delta, overflow threshold: %d", newSec, maxInt64)
+		}
+	}
+
+	// Test it with negative delta.
+	maxInt64 = -maxInt64
+	notMonoTime = NotMonoNegativeTime
+	for i := int64(0); i > -100; i-- {
+		sec := notMonoTime.Unix()
+		notMonoTime = notMonoTime.Add(Duration(i * 1e9))
+		if newSec := notMonoTime.Unix(); newSec != sec+i && newSec+UnixToInternal != maxInt64 {
+			t.Fatalf("time ext: %d overflows with positive delta, overflow threshold: %d", newSec, maxInt64)
+		}
+	}
+}
diff --git a/src/time/tzdata/generate_zipdata.go b/src/time/tzdata/generate_zipdata.go
index 21357fb..64b5b1b 100644
--- a/src/time/tzdata/generate_zipdata.go
+++ b/src/time/tzdata/generate_zipdata.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 // This program generates zipdata.go from $GOROOT/lib/time/zoneinfo.zip.
diff --git a/src/time/zoneinfo.go b/src/time/zoneinfo.go
index 6db9443..57aed03 100644
--- a/src/time/zoneinfo.go
+++ b/src/time/zoneinfo.go
@@ -121,7 +121,7 @@
 // the start and end times bracketing sec when that zone is in effect,
 // the offset in seconds east of UTC (such as -5*60*60), and whether
 // the daylight savings is being observed at that time.
-func (l *Location) lookup(sec int64) (name string, offset int, start, end int64) {
+func (l *Location) lookup(sec int64) (name string, offset int, start, end int64, isDST bool) {
 	l = l.get()
 
 	if len(l.zone) == 0 {
@@ -129,6 +129,7 @@
 		offset = 0
 		start = alpha
 		end = omega
+		isDST = false
 		return
 	}
 
@@ -137,6 +138,7 @@
 		offset = zone.offset
 		start = l.cacheStart
 		end = l.cacheEnd
+		isDST = zone.isDST
 		return
 	}
 
@@ -150,6 +152,7 @@
 		} else {
 			end = omega
 		}
+		isDST = zone.isDST
 		return
 	}
 
@@ -174,12 +177,13 @@
 	offset = zone.offset
 	start = tx[lo].when
 	// end = maintained during the search
+	isDST = zone.isDST
 
 	// If we're at the end of the known zone transitions,
 	// try the extend string.
 	if lo == len(tx)-1 && l.extend != "" {
-		if ename, eoffset, estart, eend, ok := tzset(l.extend, end, sec); ok {
-			return ename, eoffset, estart, eend
+		if ename, eoffset, estart, eend, eisDST, ok := tzset(l.extend, end, sec); ok {
+			return ename, eoffset, estart, eend, eisDST
 		}
 	}
 
@@ -244,7 +248,7 @@
 // We call this a tzset string since in C the function tzset reads TZ.
 // The return values are as for lookup, plus ok which reports whether the
 // parse succeeded.
-func tzset(s string, initEnd, sec int64) (name string, offset int, start, end int64, ok bool) {
+func tzset(s string, initEnd, sec int64) (name string, offset int, start, end int64, isDST, ok bool) {
 	var (
 		stdName, dstName     string
 		stdOffset, dstOffset int
@@ -255,7 +259,7 @@
 		stdOffset, s, ok = tzsetOffset(s)
 	}
 	if !ok {
-		return "", 0, 0, 0, false
+		return "", 0, 0, 0, false, false
 	}
 
 	// The numbers in the tzset string are added to local time to get UTC,
@@ -265,7 +269,7 @@
 
 	if len(s) == 0 || s[0] == ',' {
 		// No daylight savings time.
-		return stdName, stdOffset, initEnd, omega, true
+		return stdName, stdOffset, initEnd, omega, false, true
 	}
 
 	dstName, s, ok = tzsetName(s)
@@ -278,7 +282,7 @@
 		}
 	}
 	if !ok {
-		return "", 0, 0, 0, false
+		return "", 0, 0, 0, false, false
 	}
 
 	if len(s) == 0 {
@@ -287,19 +291,19 @@
 	}
 	// The TZ definition does not mention ';' here but tzcode accepts it.
 	if s[0] != ',' && s[0] != ';' {
-		return "", 0, 0, 0, false
+		return "", 0, 0, 0, false, false
 	}
 	s = s[1:]
 
 	var startRule, endRule rule
 	startRule, s, ok = tzsetRule(s)
 	if !ok || len(s) == 0 || s[0] != ',' {
-		return "", 0, 0, 0, false
+		return "", 0, 0, 0, false, false
 	}
 	s = s[1:]
 	endRule, s, ok = tzsetRule(s)
 	if !ok || len(s) > 0 {
-		return "", 0, 0, 0, false
+		return "", 0, 0, 0, false, false
 	}
 
 	year, _, _, yday := absDate(uint64(sec+unixToInternal+internalToAbsolute), false)
@@ -313,10 +317,15 @@
 
 	startSec := int64(tzruleTime(year, startRule, stdOffset))
 	endSec := int64(tzruleTime(year, endRule, dstOffset))
+	dstIsDST, stdIsDST := true, false
+	// Note: this is a flipping of "DST" and "STD" while retaining the labels
+	// This happens in southern hemispheres. The labelling here thus is a little
+	// inconsistent with the goal.
 	if endSec < startSec {
 		startSec, endSec = endSec, startSec
 		stdName, dstName = dstName, stdName
 		stdOffset, dstOffset = dstOffset, stdOffset
+		stdIsDST, dstIsDST = dstIsDST, stdIsDST
 	}
 
 	// The start and end values that we return are accurate
@@ -324,11 +333,11 @@
 	// just the start and end of the year. That suffices for
 	// the only caller that cares, which is Date.
 	if ysec < startSec {
-		return stdName, stdOffset, abs, startSec + abs, true
+		return stdName, stdOffset, abs, startSec + abs, stdIsDST, true
 	} else if ysec >= endSec {
-		return stdName, stdOffset, endSec + abs, abs + 365*secondsPerDay, true
+		return stdName, stdOffset, endSec + abs, abs + 365*secondsPerDay, stdIsDST, true
 	} else {
-		return dstName, dstOffset, startSec + abs, endSec + abs, true
+		return dstName, dstOffset, startSec + abs, endSec + abs, dstIsDST, true
 	}
 }
 
@@ -587,7 +596,7 @@
 	for i := range l.zone {
 		zone := &l.zone[i]
 		if zone.name == name {
-			nam, offset, _, _ := l.lookup(unix - int64(zone.offset))
+			nam, offset, _, _, _ := l.lookup(unix - int64(zone.offset))
 			if nam == zone.name {
 				return offset, true
 			}
diff --git a/src/time/zoneinfo_ios.go b/src/time/zoneinfo_ios.go
index 0f1e933..044691e 100644
--- a/src/time/zoneinfo_ios.go
+++ b/src/time/zoneinfo_ios.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ios
 // +build ios
 
 package time
diff --git a/src/time/zoneinfo_js.go b/src/time/zoneinfo_js.go
index 2d76a57..8245614 100644
--- a/src/time/zoneinfo_js.go
+++ b/src/time/zoneinfo_js.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
 // +build js,wasm
 
 package time
diff --git a/src/time/zoneinfo_read.go b/src/time/zoneinfo_read.go
index c739864..b983026 100644
--- a/src/time/zoneinfo_read.go
+++ b/src/time/zoneinfo_read.go
@@ -247,8 +247,8 @@
 		// This also avoids a panic later when we add and then use a fake transition (golang.org/issue/29437).
 		return nil, badData
 	}
-	zone := make([]zone, nzone)
-	for i := range zone {
+	zones := make([]zone, nzone)
+	for i := range zones {
 		var ok bool
 		var n uint32
 		if n, ok = zonedata.big4(); !ok {
@@ -257,22 +257,22 @@
 		if uint32(int(n)) != n {
 			return nil, badData
 		}
-		zone[i].offset = int(int32(n))
+		zones[i].offset = int(int32(n))
 		var b byte
 		if b, ok = zonedata.byte(); !ok {
 			return nil, badData
 		}
-		zone[i].isDST = b != 0
+		zones[i].isDST = b != 0
 		if b, ok = zonedata.byte(); !ok || int(b) >= len(abbrev) {
 			return nil, badData
 		}
-		zone[i].name = byteString(abbrev[b:])
+		zones[i].name = byteString(abbrev[b:])
 		if runtime.GOOS == "aix" && len(name) > 8 && (name[:8] == "Etc/GMT+" || name[:8] == "Etc/GMT-") {
 			// There is a bug with AIX 7.2 TL 0 with files in Etc,
 			// GMT+1 will return GMT-1 instead of GMT+1 or -01.
 			if name != "Etc/GMT+0" {
 				// GMT+0 is OK
-				zone[i].name = name[4:]
+				zones[i].name = name[4:]
 			}
 		}
 	}
@@ -295,7 +295,7 @@
 			}
 		}
 		tx[i].when = n
-		if int(txzones[i]) >= len(zone) {
+		if int(txzones[i]) >= len(zones) {
 			return nil, badData
 		}
 		tx[i].index = txzones[i]
@@ -314,7 +314,7 @@
 	}
 
 	// Committed to succeed.
-	l := &Location{zone: zone, tx: tx, name: name, extend: extend}
+	l := &Location{zone: zones, tx: tx, name: name, extend: extend}
 
 	// Fill in the cache with information about right now,
 	// since that will be the most common lookup.
@@ -323,26 +323,27 @@
 		if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) {
 			l.cacheStart = tx[i].when
 			l.cacheEnd = omega
-			zoneIdx := tx[i].index
+			l.cacheZone = &l.zone[tx[i].index]
 			if i+1 < len(tx) {
 				l.cacheEnd = tx[i+1].when
 			} else if l.extend != "" {
 				// If we're at the end of the known zone transitions,
 				// try the extend string.
-				if name, _, estart, eend, ok := tzset(l.extend, l.cacheEnd, sec); ok {
+				if name, offset, estart, eend, isDST, ok := tzset(l.extend, l.cacheEnd, sec); ok {
 					l.cacheStart = estart
 					l.cacheEnd = eend
-					// Find the zone that is returned by tzset,
-					// the last transition is not always the correct zone.
-					for i, z := range l.zone {
-						if z.name == name {
-							zoneIdx = uint8(i)
-							break
+					// Find the zone that is returned by tzset to avoid allocation if possible.
+					if zoneIdx := findZone(l.zone, name, offset, isDST); zoneIdx != -1 {
+						l.cacheZone = &l.zone[zoneIdx]
+					} else {
+						l.cacheZone = &zone{
+							name:   name,
+							offset: offset,
+							isDST:  isDST,
 						}
 					}
 				}
 			}
-			l.cacheZone = &l.zone[zoneIdx]
 			break
 		}
 	}
@@ -350,6 +351,15 @@
 	return l, nil
 }
 
+func findZone(zones []zone, name string, offset int, isDST bool) int {
+	for i, z := range zones {
+		if z.name == name && z.offset == offset && z.isDST == isDST {
+			return i
+		}
+	}
+	return -1
+}
+
 // 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) {
diff --git a/src/time/zoneinfo_test.go b/src/time/zoneinfo_test.go
index d043e1e..f032aa7 100644
--- a/src/time/zoneinfo_test.go
+++ b/src/time/zoneinfo_test.go
@@ -25,8 +25,7 @@
 	const testZoneinfo = "foo.zip"
 	const env = "ZONEINFO"
 
-	defer os.Setenv(env, os.Getenv(env))
-	os.Setenv(env, testZoneinfo)
+	t.Setenv(env, testZoneinfo)
 
 	// Result isn't important, we're testing the side effect of this command
 	time.LoadLocation("Asia/Jerusalem")
@@ -50,8 +49,7 @@
 func TestLoadLocationValidatesNames(t *testing.T) {
 	time.ResetZoneinfoForTesting()
 	const env = "ZONEINFO"
-	defer os.Setenv(env, os.Getenv(env))
-	os.Setenv(env, "")
+	t.Setenv(env, "")
 
 	bad := []string{
 		"/usr/foo/Foo",
@@ -185,41 +183,59 @@
 
 var slimTests = []struct {
 	zoneName   string
-	tzData     string
+	fileName   string
+	date       func(*time.Location) time.Time
 	wantName   string
 	wantOffset int
 }{
 	{
 		// 2020b slim tzdata for Europe/Berlin.
 		zoneName:   "Europe/Berlin",
-		tzData:     "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\n",
+		fileName:   "2020b_Europe_Berlin",
+		date:       func(loc *time.Location) time.Time { return time.Date(2020, time.October, 29, 15, 30, 0, 0, loc) },
 		wantName:   "CET",
 		wantOffset: 3600,
 	},
 	{
 		// 2021a slim tzdata for America/Nuuk.
 		zoneName:   "America/Nuuk",
-		tzData:     "TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\bLMT\x00-03\x00-02\x00\n<-03>3<-02>,M3.5.0/-2,M10.5.0/-1\n",
+		fileName:   "2021a_America_Nuuk",
+		date:       func(loc *time.Location) time.Time { return time.Date(2020, time.October, 29, 15, 30, 0, 0, loc) },
 		wantName:   "-03",
 		wantOffset: -10800,
 	},
 	{
 		// 2021a slim tzdata for Asia/Gaza.
 		zoneName:   "Asia/Gaza",
-		tzData:     "TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff}\xbdJ\xb0\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\u007f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb'BP\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x000\xe7\a\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00\x006\x01\x86`\x00\x00\x00\x007\x16a`\x00\x00\x00\x008\x06DP\x00\x00\x00\x008\xff}\xe0\x00\x00\x00\x009\xef`\xd0\x00\x00\x00\x00:\xdf_\xe0\x00\x00\x00\x00;\xcfB\xd0\x00\x00\x00\x00<\xbfA\xe0\x00\x00\x00\x00=\xaf$\xd0\x00\x00\x00\x00>\x9f#\xe0\x00\x00\x00\x00?\x8f\x06\xd0\x00\x00\x00\x00@\u007f\x05\xe0\x00\x00\x00\x00A\\\x81\xe0\x00\x00\x00\x00B^\xe7\xe0\x00\x00\x00\x00CA\xb7\xf0\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\x0e\xd9\xe0\x00\x00\x00\x00F\xe8op\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00\x00K\xad.\x9c\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P[\x91\xe0\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00RD\xa0P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TIlP\x00\x00\x00\x00U\x15\xd2\xe0\x00\x00\x00\x00V)\\`\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00Xդ\xf0\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00\x00\x00\x00[ӎ`\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00\x00^~w`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00 P\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x11LMT\x00EEST\x00EET\x00IDT\x00IST\x00\nEET-2EEST,M3.4.4/48,M10.4.4/49\n",
+		fileName:   "2021a_Asia_Gaza",
+		date:       func(loc *time.Location) time.Time { return time.Date(2020, time.October, 29, 15, 30, 0, 0, loc) },
 		wantName:   "EET",
 		wantOffset: 7200,
 	},
+	{
+		// 2021a slim tzdata for Europe/Dublin.
+		zoneName:   "Europe/Dublin",
+		fileName:   "2021a_Europe_Dublin",
+		date:       func(loc *time.Location) time.Time { return time.Date(2021, time.April, 2, 11, 12, 13, 0, loc) },
+		wantName:   "IST",
+		wantOffset: 3600,
+	},
 }
 
 func TestLoadLocationFromTZDataSlim(t *testing.T) {
 	for _, test := range slimTests {
-		reference, err := time.LoadLocationFromTZData(test.zoneName, []byte(test.tzData))
+		tzData, err := os.ReadFile("testdata/" + test.fileName)
 		if err != nil {
-			t.Fatal(err)
+			t.Error(err)
+			continue
+		}
+		reference, err := time.LoadLocationFromTZData(test.zoneName, tzData)
+		if err != nil {
+			t.Error(err)
+			continue
 		}
 
-		d := time.Date(2020, time.October, 29, 15, 30, 0, 0, reference)
+		d := test.date(reference)
 		tzName, tzOffset := d.Zone()
 		if tzName != test.wantName {
 			t.Errorf("Zone name == %s, want %s", tzName, test.wantName)
@@ -239,20 +255,21 @@
 		off   int
 		start int64
 		end   int64
+		isDST bool
 		ok    bool
 	}{
-		{"", 0, 0, "", 0, 0, 0, false},
-		{"PST8PDT,M3.2.0,M11.1.0", 0, 2159200800, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true},
-		{"PST8PDT,M3.2.0,M11.1.0", 0, 2152173599, "PST", -8 * 60 * 60, 2145916800, 2152173600, true},
-		{"PST8PDT,M3.2.0,M11.1.0", 0, 2152173600, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true},
-		{"PST8PDT,M3.2.0,M11.1.0", 0, 2152173601, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true},
-		{"PST8PDT,M3.2.0,M11.1.0", 0, 2172733199, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true},
-		{"PST8PDT,M3.2.0,M11.1.0", 0, 2172733200, "PST", -8 * 60 * 60, 2172733200, 2177452800, true},
-		{"PST8PDT,M3.2.0,M11.1.0", 0, 2172733201, "PST", -8 * 60 * 60, 2172733200, 2177452800, true},
+		{"", 0, 0, "", 0, 0, 0, false, false},
+		{"PST8PDT,M3.2.0,M11.1.0", 0, 2159200800, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
+		{"PST8PDT,M3.2.0,M11.1.0", 0, 2152173599, "PST", -8 * 60 * 60, 2145916800, 2152173600, false, true},
+		{"PST8PDT,M3.2.0,M11.1.0", 0, 2152173600, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
+		{"PST8PDT,M3.2.0,M11.1.0", 0, 2152173601, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
+		{"PST8PDT,M3.2.0,M11.1.0", 0, 2172733199, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
+		{"PST8PDT,M3.2.0,M11.1.0", 0, 2172733200, "PST", -8 * 60 * 60, 2172733200, 2177452800, false, true},
+		{"PST8PDT,M3.2.0,M11.1.0", 0, 2172733201, "PST", -8 * 60 * 60, 2172733200, 2177452800, false, true},
 	} {
-		name, off, start, end, ok := time.Tzset(test.inStr, test.inEnd, test.inSec)
-		if name != test.name || off != test.off || start != test.start || end != test.end || ok != test.ok {
-			t.Errorf("tzset(%q, %d, %d) = %q, %d, %d, %d, %t, want %q, %d, %d, %d, %t", test.inStr, test.inEnd, test.inSec, name, off, start, end, ok, test.name, test.off, test.start, test.end, test.ok)
+		name, off, start, end, isDST, ok := time.Tzset(test.inStr, test.inEnd, test.inSec)
+		if name != test.name || off != test.off || start != test.start || end != test.end || isDST != test.isDST || ok != test.ok {
+			t.Errorf("tzset(%q, %d, %d) = %q, %d, %d, %d, %t, %t, want %q, %d, %d, %d, %t, %t", test.inStr, test.inEnd, test.inSec, name, off, start, end, isDST, ok, test.name, test.off, test.start, test.end, test.isDST, test.ok)
 		}
 	}
 }
diff --git a/src/time/zoneinfo_unix.go b/src/time/zoneinfo_unix.go
index d2465ee..4ea029d 100644
--- a/src/time/zoneinfo_unix.go
+++ b/src/time/zoneinfo_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || (darwin && !ios) || dragonfly || freebsd || (linux && !android) || netbsd || openbsd || solaris
 // +build aix darwin,!ios dragonfly freebsd linux,!android netbsd openbsd solaris
 
 // Parse "zoneinfo" time zone file.
diff --git a/src/time/zoneinfo_unix_test.go b/src/time/zoneinfo_unix_test.go
index f290ae7..b75b374 100644
--- a/src/time/zoneinfo_unix_test.go
+++ b/src/time/zoneinfo_unix_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || (darwin && !ios) || dragonfly || freebsd || (linux && !android) || netbsd || openbsd || solaris
 // +build aix darwin,!ios dragonfly freebsd linux,!android netbsd openbsd solaris
 
 package time_test
diff --git a/src/unicode/letter.go b/src/unicode/letter.go
index a57566f..268e457 100644
--- a/src/unicode/letter.go
+++ b/src/unicode/letter.go
@@ -154,7 +154,8 @@
 // Is reports whether the rune is in the specified table of ranges.
 func Is(rangeTab *RangeTable, r rune) bool {
 	r16 := rangeTab.R16
-	if len(r16) > 0 && r <= rune(r16[len(r16)-1].Hi) {
+	// Compare as uint32 to correctly handle negative runes.
+	if len(r16) > 0 && uint32(r) <= uint32(r16[len(r16)-1].Hi) {
 		return is16(r16, uint16(r))
 	}
 	r32 := rangeTab.R32
@@ -166,7 +167,8 @@
 
 func isExcludingLatin(rangeTab *RangeTable, r rune) bool {
 	r16 := rangeTab.R16
-	if off := rangeTab.LatinOffset; len(r16) > off && r <= rune(r16[len(r16)-1].Hi) {
+	// Compare as uint32 to correctly handle negative runes.
+	if off := rangeTab.LatinOffset; len(r16) > off && uint32(r) <= uint32(r16[len(r16)-1].Hi) {
 		return is16(r16[off:], uint16(r))
 	}
 	r32 := rangeTab.R32
diff --git a/src/unicode/letter_test.go b/src/unicode/letter_test.go
index 19ee535..a91e3a3 100644
--- a/src/unicode/letter_test.go
+++ b/src/unicode/letter_test.go
@@ -563,3 +563,82 @@
 		t.Errorf("got %q; want %q", got, want)
 	}
 }
+
+func TestNegativeRune(t *testing.T) {
+	// Issue 43254
+	// These tests cover negative rune handling by testing values which,
+	// when cast to uint8 or uint16, look like a particular valid rune.
+	// This package has Latin-1-specific optimizations, so we test all of
+	// Latin-1 and representative non-Latin-1 values in the character
+	// categories covered by IsGraphic, etc.
+	nonLatin1 := []uint32{
+		// Lu: LATIN CAPITAL LETTER A WITH MACRON
+		0x0100,
+		// Ll: LATIN SMALL LETTER A WITH MACRON
+		0x0101,
+		// Lt: LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
+		0x01C5,
+		// M: COMBINING GRAVE ACCENT
+		0x0300,
+		// Nd: ARABIC-INDIC DIGIT ZERO
+		0x0660,
+		// P: GREEK QUESTION MARK
+		0x037E,
+		// S: MODIFIER LETTER LEFT ARROWHEAD
+		0x02C2,
+		// Z: OGHAM SPACE MARK
+		0x1680,
+	}
+	for i := 0; i < MaxLatin1+len(nonLatin1); i++ {
+		base := uint32(i)
+		if i >= MaxLatin1 {
+			base = nonLatin1[i-MaxLatin1]
+		}
+
+		// Note r is negative, but uint8(r) == uint8(base) and
+		// uint16(r) == uint16(base).
+		r := rune(base - 1<<31)
+		if Is(Letter, r) {
+			t.Errorf("Is(Letter, 0x%x - 1<<31) = true, want false", base)
+		}
+		if IsControl(r) {
+			t.Errorf("IsControl(0x%x - 1<<31) = true, want false", base)
+		}
+		if IsDigit(r) {
+			t.Errorf("IsDigit(0x%x - 1<<31) = true, want false", base)
+		}
+		if IsGraphic(r) {
+			t.Errorf("IsGraphic(0x%x - 1<<31) = true, want false", base)
+		}
+		if IsLetter(r) {
+			t.Errorf("IsLetter(0x%x - 1<<31) = true, want false", base)
+		}
+		if IsLower(r) {
+			t.Errorf("IsLower(0x%x - 1<<31) = true, want false", base)
+		}
+		if IsMark(r) {
+			t.Errorf("IsMark(0x%x - 1<<31) = true, want false", base)
+		}
+		if IsNumber(r) {
+			t.Errorf("IsNumber(0x%x - 1<<31) = true, want false", base)
+		}
+		if IsPrint(r) {
+			t.Errorf("IsPrint(0x%x - 1<<31) = true, want false", base)
+		}
+		if IsPunct(r) {
+			t.Errorf("IsPunct(0x%x - 1<<31) = true, want false", base)
+		}
+		if IsSpace(r) {
+			t.Errorf("IsSpace(0x%x - 1<<31) = true, want false", base)
+		}
+		if IsSymbol(r) {
+			t.Errorf("IsSymbol(0x%x - 1<<31) = true, want false", base)
+		}
+		if IsTitle(r) {
+			t.Errorf("IsTitle(0x%x - 1<<31) = true, want false", base)
+		}
+		if IsUpper(r) {
+			t.Errorf("IsUpper(0x%x - 1<<31) = true, want false", base)
+		}
+	}
+}
diff --git a/src/unsafe/unsafe.go b/src/unsafe/unsafe.go
index 272761d..16e3890 100644
--- a/src/unsafe/unsafe.go
+++ b/src/unsafe/unsafe.go
@@ -14,6 +14,10 @@
 // part of the unsafe package. It represents the type of an arbitrary Go expression.
 type ArbitraryType int
 
+// IntegerType is here for the purposes of documentation only and is not actually
+// part of the unsafe package. It represents any arbitrary integer type.
+type IntegerType int
+
 // Pointer represents a pointer to an arbitrary type. There are four special operations
 // available for type Pointer that are not available for other types:
 //	- A pointer value of any type can be converted to a Pointer.
@@ -203,3 +207,27 @@
 // value returned by reflect.TypeOf(s.f).FieldAlign().
 // The return value of Alignof is a Go constant.
 func Alignof(x ArbitraryType) uintptr
+
+// The function Add adds len to ptr and returns the updated pointer
+// Pointer(uintptr(ptr) + uintptr(len)).
+// The len argument must be of integer type or an untyped constant.
+// A constant len argument must be representable by a value of type int;
+// if it is an untyped constant it is given type int.
+// The rules for valid uses of Pointer still apply.
+func Add(ptr Pointer, len IntegerType) Pointer
+
+// The function Slice returns a slice whose underlying array starts at ptr
+// and whose length and capacity are len.
+// Slice(ptr, len) is equivalent to
+//
+//	(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:]
+//
+// except that, as a special case, if ptr is nil and len is zero,
+// Slice returns nil.
+//
+// The len argument must be of integer type or an untyped constant.
+// A constant len argument must be non-negative and representable by a value of type int;
+// if it is an untyped constant it is given type int.
+// At run time, if len is negative, or if ptr is nil and len is not zero,
+// a run-time panic occurs.
+func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
diff --git a/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go b/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
index b799e44..94c71ac 100644
--- a/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
+++ b/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build go1.11,!gccgo,!purego
+//go:build go1.11 && gc && !purego
+// +build go1.11,gc,!purego
 
 package chacha20
 
diff --git a/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s b/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
index 8914815..8fb49a1 100644
--- a/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
+++ b/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
@@ -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 go1.11,!gccgo,!purego
+// +build go1.11,gc,!purego
 
 #include "textflag.h"
 
diff --git a/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go b/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
index 4635307..025b498 100644
--- a/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
+++ b/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !arm64,!s390x,!ppc64le arm64,!go1.11 gccgo purego
+//go:build (!arm64 && !s390x && !ppc64le) || (arm64 && !go1.11) || !gc || purego
+// +build !arm64,!s390x,!ppc64le arm64,!go1.11 !gc purego
 
 package chacha20
 
diff --git a/src/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go b/src/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
index b799330..da420b2 100644
--- a/src/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
+++ b/src/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 package chacha20
 
diff --git a/src/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s b/src/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
index 23c6021..3dad4b2 100644
--- a/src/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
+++ b/src/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
@@ -19,7 +19,7 @@
 // The differences in this and the original implementation are
 // due to the calling conventions and initialization of constants.
 
-// +build !gccgo,!purego
+// +build gc,!purego
 
 #include "textflag.h"
 
diff --git a/src/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go b/src/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
index a9244bd..c5898db 100644
--- a/src/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
+++ b/src/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 package chacha20
 
diff --git a/src/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s b/src/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
index 89c658c..8181611 100644
--- a/src/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
+++ b/src/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
@@ -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 !gccgo,!purego
+// +build gc,!purego
 
 #include "go_asm.h"
 #include "textflag.h"
diff --git a/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go b/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
index cda7781..25959b9 100644
--- a/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
+++ b/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 package chacha20poly1305
 
diff --git a/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s b/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
index 3469c87..55226b0 100644
--- a/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
+++ b/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
@@ -4,7 +4,7 @@
 
 // This file was originally from https://golang.org/cl/24717 by Vlad Krasnov of CloudFlare.
 
-// +build !gccgo,!purego
+// +build gc,!purego
 
 #include "textflag.h"
 // General register allocation
diff --git a/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go b/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go
index 9ce4aa9..f832b33 100644
--- a/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go
+++ b/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64 gccgo purego
+//go:build !amd64 || !gc || purego
+// +build !amd64 !gc purego
 
 package chacha20poly1305
 
diff --git a/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go b/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go
index d3596ee..83c776d 100644
--- a/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go
+++ b/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go
@@ -117,6 +117,19 @@
 	})
 }
 
+// AddASN1UTCTime appends a DER-encoded ASN.1 UTCTime.
+func (b *Builder) AddASN1UTCTime(t time.Time) {
+	b.AddASN1(asn1.UTCTime, func(c *Builder) {
+		// As utilized by the X.509 profile, UTCTime can only
+		// represent the years 1950 through 2049.
+		if t.Year() < 1950 || t.Year() >= 2050 {
+			b.err = fmt.Errorf("cryptobyte: cannot represent %v as a UTCTime", t)
+			return
+		}
+		c.AddBytes([]byte(t.Format(defaultUTCTimeFormatStr)))
+	})
+}
+
 // 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) {
@@ -466,6 +479,45 @@
 	return true
 }
 
+const defaultUTCTimeFormatStr = "060102150405Z0700"
+
+// ReadASN1UTCTime decodes an ASN.1 UTCTime into out and advances.
+// It reports whether the read was successful.
+func (s *String) ReadASN1UTCTime(out *time.Time) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.UTCTime) {
+		return false
+	}
+	t := string(bytes)
+
+	formatStr := defaultUTCTimeFormatStr
+	var err error
+	res, err := time.Parse(formatStr, t)
+	if err != nil {
+		// Fallback to minute precision if we can't parse second
+		// precision. If we are following X.509 or X.690 we shouldn't
+		// support this, but we do.
+		formatStr = "0601021504Z0700"
+		res, err = time.Parse(formatStr, t)
+	}
+	if err != nil {
+		return false
+	}
+
+	if serialized := res.Format(formatStr); serialized != t {
+		return false
+	}
+
+	if res.Year() >= 2050 {
+		// UTCTime interprets the low order digits 50-99 as 1950-99.
+		// This only applies to its use in the X.509 profile.
+		// See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+		res = res.AddDate(-100, 0, 0)
+	}
+	*out = res
+	return true
+}
+
 // ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances.
 // It reports whether the read was successful.
 func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
diff --git a/src/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go b/src/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
index 5120b77..8485848 100644
--- a/src/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
+++ b/src/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build amd64,!gccgo,!appengine,!purego
+//go:build amd64 && gc && !purego
+// +build amd64,gc,!purego
 
 package curve25519
 
diff --git a/src/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s b/src/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s
index 0250c88..6c53380 100644
--- a/src/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s
+++ b/src/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s
@@ -5,7 +5,7 @@
 // This code was translated into a form compatible with 6a from the public
 // domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
 
-// +build amd64,!gccgo,!appengine,!purego
+// +build amd64,gc,!purego
 
 #define REDMASK51     0x0007FFFFFFFFFFFF
 
diff --git a/src/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go b/src/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
index 047d49a..259728a 100644
--- a/src/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
+++ b/src/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64 gccgo appengine purego
+//go:build !amd64 || !gc || purego
+// +build !amd64 !gc purego
 
 package curve25519
 
diff --git a/src/vendor/golang.org/x/crypto/internal/subtle/aliasing.go b/src/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
index f38797b..4fad24f 100644
--- a/src/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
+++ b/src/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !appengine
+//go:build !purego
+// +build !purego
 
 // Package subtle implements functions that are often useful in cryptographic
 // code but require careful thought to use correctly.
diff --git a/src/vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go b/src/vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go
deleted file mode 100644
index 0cc4a8a..0000000
--- a/src/vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build appengine
-
-// Package subtle implements functions that are often useful in cryptographic
-// code but require careful thought to use correctly.
-package subtle // import "golang.org/x/crypto/internal/subtle"
-
-// This is the Google App Engine standard variant based on reflect
-// because the unsafe package and cgo are disallowed.
-
-import "reflect"
-
-// AnyOverlap reports whether x and y share memory at any (not necessarily
-// corresponding) index. The memory beyond the slice length is ignored.
-func AnyOverlap(x, y []byte) bool {
-	return len(x) > 0 && len(y) > 0 &&
-		reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&
-		reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()
-}
-
-// InexactOverlap reports whether x and y share memory at any non-corresponding
-// index. The memory beyond the slice length is ignored. Note that x and y can
-// have different lengths and still not have any inexact overlap.
-//
-// InexactOverlap can be used to implement the requirements of the crypto/cipher
-// AEAD, Block, BlockMode and Stream interfaces.
-func InexactOverlap(x, y []byte) bool {
-	if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
-		return false
-	}
-	return AnyOverlap(x, y)
-}
diff --git a/src/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go b/src/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go
new file mode 100644
index 0000000..80ccbed
--- /dev/null
+++ b/src/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go
@@ -0,0 +1,36 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build purego
+// +build purego
+
+// Package subtle implements functions that are often useful in cryptographic
+// code but require careful thought to use correctly.
+package subtle // import "golang.org/x/crypto/internal/subtle"
+
+// This is the Google App Engine standard variant based on reflect
+// because the unsafe package and cgo are disallowed.
+
+import "reflect"
+
+// AnyOverlap reports whether x and y share memory at any (not necessarily
+// corresponding) index. The memory beyond the slice length is ignored.
+func AnyOverlap(x, y []byte) bool {
+	return len(x) > 0 && len(y) > 0 &&
+		reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&
+		reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()
+}
+
+// InexactOverlap reports whether x and y share memory at any non-corresponding
+// index. The memory beyond the slice length is ignored. Note that x and y can
+// have different lengths and still not have any inexact overlap.
+//
+// InexactOverlap can be used to implement the requirements of the crypto/cipher
+// AEAD, Block, BlockMode and Stream interfaces.
+func InexactOverlap(x, y []byte) bool {
+	if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+		return false
+	}
+	return AnyOverlap(x, y)
+}
diff --git a/src/vendor/golang.org/x/crypto/poly1305/bits_compat.go b/src/vendor/golang.org/x/crypto/poly1305/bits_compat.go
index 157a69f..45b5c96 100644
--- a/src/vendor/golang.org/x/crypto/poly1305/bits_compat.go
+++ b/src/vendor/golang.org/x/crypto/poly1305/bits_compat.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !go1.13
 // +build !go1.13
 
 package poly1305
diff --git a/src/vendor/golang.org/x/crypto/poly1305/bits_go1.13.go b/src/vendor/golang.org/x/crypto/poly1305/bits_go1.13.go
index a0a185f..ed52b34 100644
--- a/src/vendor/golang.org/x/crypto/poly1305/bits_go1.13.go
+++ b/src/vendor/golang.org/x/crypto/poly1305/bits_go1.13.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.13
 // +build go1.13
 
 package poly1305
diff --git a/src/vendor/golang.org/x/crypto/poly1305/mac_noasm.go b/src/vendor/golang.org/x/crypto/poly1305/mac_noasm.go
index d118f30..f184b67 100644
--- a/src/vendor/golang.org/x/crypto/poly1305/mac_noasm.go
+++ b/src/vendor/golang.org/x/crypto/poly1305/mac_noasm.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64,!ppc64le,!s390x gccgo purego
+//go:build (!amd64 && !ppc64le && !s390x) || !gc || purego
+// +build !amd64,!ppc64le,!s390x !gc purego
 
 package poly1305
 
diff --git a/src/vendor/golang.org/x/crypto/poly1305/sum_amd64.go b/src/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
index 99e5a1d..6d52233 100644
--- a/src/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
+++ b/src/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 package poly1305
 
diff --git a/src/vendor/golang.org/x/crypto/poly1305/sum_amd64.s b/src/vendor/golang.org/x/crypto/poly1305/sum_amd64.s
index 8d394a2..2cb0373 100644
--- a/src/vendor/golang.org/x/crypto/poly1305/sum_amd64.s
+++ b/src/vendor/golang.org/x/crypto/poly1305/sum_amd64.s
@@ -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 !gccgo,!purego
+// +build gc,!purego
 
 #include "textflag.h"
 
diff --git a/src/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go b/src/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
index 2e7a120..4a06994 100644
--- a/src/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
+++ b/src/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 package poly1305
 
diff --git a/src/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s b/src/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s
index 4e02813..3cede53 100644
--- a/src/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s
+++ b/src/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s
@@ -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 !gccgo,!purego
+// +build gc,!purego
 
 #include "textflag.h"
 
@@ -82,7 +82,7 @@
 	BGE loop
 
 bytes_between_0_and_15:
-	CMP  $0, R5
+	CMP  R5, $0
 	BEQ  done
 	MOVD $0, R16 // h0
 	MOVD $0, R17 // h1
@@ -122,7 +122,7 @@
 	// Exactly 8
 	MOVD (R4), R16
 
-	CMP $0, R17
+	CMP R17, $0
 
 	// Check if we've already set R17; if not
 	// set 1 to indicate end of msg.
@@ -151,7 +151,7 @@
 	ADD   $2, R4
 
 less2:
-	CMP   $0, R5
+	CMP   R5, $0
 	BEQ   insert1
 	MOVBZ (R4), R21
 	SLD   R22, R21, R21
@@ -166,12 +166,12 @@
 
 carry:
 	// Add new values to h0, h1, h2
-	ADDC R16, R8
-	ADDE R17, R9
-	ADDE $0, R10
-	MOVD $16, R5
-	ADD  R5, R4
-	BR   multiply
+	ADDC  R16, R8
+	ADDE  R17, R9
+	ADDZE R10, R10
+	MOVD  $16, R5
+	ADD   R5, R4
+	BR    multiply
 
 done:
 	// Save h0, h1, h2 in state
diff --git a/src/vendor/golang.org/x/crypto/poly1305/sum_s390x.go b/src/vendor/golang.org/x/crypto/poly1305/sum_s390x.go
index 958fedc..62cc9f8 100644
--- a/src/vendor/golang.org/x/crypto/poly1305/sum_s390x.go
+++ b/src/vendor/golang.org/x/crypto/poly1305/sum_s390x.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !gccgo,!purego
+//go:build gc && !purego
+// +build gc,!purego
 
 package poly1305
 
diff --git a/src/vendor/golang.org/x/crypto/poly1305/sum_s390x.s b/src/vendor/golang.org/x/crypto/poly1305/sum_s390x.s
index 0fa9ee6..bdd882c 100644
--- a/src/vendor/golang.org/x/crypto/poly1305/sum_s390x.s
+++ b/src/vendor/golang.org/x/crypto/poly1305/sum_s390x.s
@@ -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 !gccgo,!purego
+// +build gc,!purego
 
 #include "textflag.h"
 
diff --git a/src/vendor/golang.org/x/net/dns/dnsmessage/message.go b/src/vendor/golang.org/x/net/dns/dnsmessage/message.go
index 654f191..1736fc5 100644
--- a/src/vendor/golang.org/x/net/dns/dnsmessage/message.go
+++ b/src/vendor/golang.org/x/net/dns/dnsmessage/message.go
@@ -1023,6 +1023,24 @@
 	return r, nil
 }
 
+// UnknownResource parses a single UnknownResource.
+//
+// One of the XXXHeader methods must have been called before calling this
+// method.
+func (p *Parser) UnknownResource() (UnknownResource, error) {
+	if !p.resHeaderValid {
+		return UnknownResource{}, ErrNotStarted
+	}
+	r, err := unpackUnknownResource(p.resHeader.Type, p.msg, p.off, p.resHeader.Length)
+	if err != nil {
+		return UnknownResource{}, err
+	}
+	p.off += int(p.resHeader.Length)
+	p.resHeaderValid = false
+	p.index++
+	return r, nil
+}
+
 // Unpack parses a full Message.
 func (m *Message) Unpack(msg []byte) error {
 	var p Parser
@@ -1557,6 +1575,30 @@
 	return nil
 }
 
+// UnknownResource adds a single UnknownResource.
+func (b *Builder) UnknownResource(h ResourceHeader, r UnknownResource) error {
+	if err := b.checkResourceSection(); err != nil {
+		return err
+	}
+	h.Type = r.realType()
+	msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
+	if err != nil {
+		return &nestedError{"ResourceHeader", err}
+	}
+	preLen := len(msg)
+	if msg, err = r.pack(msg, b.compression, b.start); err != nil {
+		return &nestedError{"UnknownResource body", err}
+	}
+	if err := h.fixLen(msg, lenOff, preLen); err != nil {
+		return err
+	}
+	if err := b.incrementSectionCount(); err != nil {
+		return err
+	}
+	b.msg = msg
+	return nil
+}
+
 // Finish ends message building and generates a binary message.
 func (b *Builder) Finish() ([]byte, error) {
 	if b.section < sectionHeader {
@@ -2135,13 +2177,15 @@
 		rb, err = unpackOPTResource(msg, off, hdr.Length)
 		r = &rb
 		name = "OPT"
+	default:
+		var rb UnknownResource
+		rb, err = unpackUnknownResource(hdr.Type, msg, off, hdr.Length)
+		r = &rb
+		name = "Unknown"
 	}
 	if err != nil {
 		return nil, off, &nestedError{name + " record", err}
 	}
-	if r == nil {
-		return nil, off, errors.New("invalid resource type: " + hdr.Type.String())
-	}
 	return r, off + int(hdr.Length), nil
 }
 
@@ -2585,3 +2629,36 @@
 	}
 	return OPTResource{opts}, nil
 }
+
+// An UnknownResource is a catch-all container for unknown record types.
+type UnknownResource struct {
+	Type Type
+	Data []byte
+}
+
+func (r *UnknownResource) realType() Type {
+	return r.Type
+}
+
+// pack appends the wire format of the UnknownResource to msg.
+func (r *UnknownResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+	return packBytes(msg, r.Data[:]), nil
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r *UnknownResource) GoString() string {
+	return "dnsmessage.UnknownResource{" +
+		"Type: " + r.Type.GoString() + ", " +
+		"Data: []byte{" + printByteSlice(r.Data) + "}}"
+}
+
+func unpackUnknownResource(recordType Type, msg []byte, off int, length uint16) (UnknownResource, error) {
+	parsed := UnknownResource{
+		Type: recordType,
+		Data: make([]byte, length),
+	}
+	if _, err := unpackBytes(msg, off, parsed.Data); err != nil {
+		return UnknownResource{}, err
+	}
+	return parsed, nil
+}
diff --git a/src/vendor/golang.org/x/net/http/httpguts/httplex.go b/src/vendor/golang.org/x/net/http/httpguts/httplex.go
index e7de24e..c79aa73 100644
--- a/src/vendor/golang.org/x/net/http/httpguts/httplex.go
+++ b/src/vendor/golang.org/x/net/http/httpguts/httplex.go
@@ -137,11 +137,13 @@
 // contains token amongst its comma-separated tokens, ASCII
 // case-insensitively.
 func headerValueContainsToken(v string, token string) bool {
-	v = trimOWS(v)
-	if comma := strings.IndexByte(v, ','); comma != -1 {
-		return tokenEqual(trimOWS(v[:comma]), token) || headerValueContainsToken(v[comma+1:], token)
+	for comma := strings.IndexByte(v, ','); comma != -1; comma = strings.IndexByte(v, ',') {
+		if tokenEqual(trimOWS(v[:comma]), token) {
+			return true
+		}
+		v = v[comma+1:]
 	}
-	return tokenEqual(v, token)
+	return tokenEqual(trimOWS(v), token)
 }
 
 // lowerASCII returns the ASCII lowercase version of b.
diff --git a/src/vendor/golang.org/x/net/idna/idna10.0.0.go b/src/vendor/golang.org/x/net/idna/idna10.0.0.go
index a98a31f..5208ba6 100644
--- a/src/vendor/golang.org/x/net/idna/idna10.0.0.go
+++ b/src/vendor/golang.org/x/net/idna/idna10.0.0.go
@@ -4,6 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.10
 // +build go1.10
 
 // Package idna implements IDNA2008 using the compatibility processing
@@ -66,15 +67,14 @@
 
 // VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
 // are longer than allowed by the RFC.
+//
+// This option corresponds to the VerifyDnsLength flag in UTS #46.
 func VerifyDNSLength(verify bool) Option {
 	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 }
 }
@@ -82,6 +82,8 @@
 // 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.
+// In particular, ValidateLabels also sets the CheckHyphens and CheckJoiners flags
+// in UTS #46.
 func ValidateLabels(enable bool) Option {
 	return func(o *options) {
 		// Don't override existing mappings, but set one that at least checks
@@ -90,25 +92,48 @@
 			o.mapping = normalize
 		}
 		o.trie = trie
-		o.validateLabels = enable
-		o.fromPuny = validateFromPunycode
+		o.checkJoiners = enable
+		o.checkHyphens = enable
+		if enable {
+			o.fromPuny = validateFromPunycode
+		} else {
+			o.fromPuny = nil
+		}
+	}
+}
+
+// CheckHyphens sets whether to check for correct use of hyphens ('-') in
+// labels. Most web browsers do not have this option set, since labels such as
+// "r3---sn-apo3qvuoxuxbt-j5pe" are in common use.
+//
+// This option corresponds to the CheckHyphens flag in UTS #46.
+func CheckHyphens(enable bool) Option {
+	return func(o *options) { o.checkHyphens = enable }
+}
+
+// CheckJoiners sets whether to check the ContextJ rules as defined in Appendix
+// A of RFC 5892, concerning the use of joiner runes.
+//
+// This option corresponds to the CheckJoiners flag in UTS #46.
+func CheckJoiners(enable bool) Option {
+	return func(o *options) {
+		o.trie = trie
+		o.checkJoiners = enable
 	}
 }
 
 // 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.
+// hyphen). This is set by default for MapForLookup and ValidateForRegistration,
+// but is only useful if ValidateLabels is set.
 //
 // This option is useful, for instance, for browsers that allow characters
 // outside this range, for example a '_' (U+005F LOW LINE). See
-// http://www.rfc-editor.org/std/std3.txt for more details This option
-// corresponds to the UseSTD3ASCIIRules option in UTS #46.
+// http://www.rfc-editor.org/std/std3.txt for more details.
+//
+// This option corresponds to the UseSTD3ASCIIRules flag in UTS #46.
 func StrictDomainName(use bool) Option {
-	return func(o *options) {
-		o.trie = trie
-		o.useSTD3Rules = use
-		o.fromPuny = validateFromPunycode
-	}
+	return func(o *options) { o.useSTD3Rules = use }
 }
 
 // NOTE: the following options pull in tables. The tables should not be linked
@@ -116,6 +141,8 @@
 
 // BidiRule enables the Bidi rule as defined in RFC 5893. Any application
 // that relies on proper validation of labels should include this rule.
+//
+// This option corresponds to the CheckBidi flag in UTS #46.
 func BidiRule() Option {
 	return func(o *options) { o.bidirule = bidirule.ValidString }
 }
@@ -151,7 +178,8 @@
 type options struct {
 	transitional      bool
 	useSTD3Rules      bool
-	validateLabels    bool
+	checkHyphens      bool
+	checkJoiners      bool
 	verifyDNSLength   bool
 	removeLeadingDots bool
 
@@ -224,8 +252,11 @@
 	if p.useSTD3Rules {
 		s += ":UseSTD3Rules"
 	}
-	if p.validateLabels {
-		s += ":ValidateLabels"
+	if p.checkHyphens {
+		s += ":CheckHyphens"
+	}
+	if p.checkJoiners {
+		s += ":CheckJoiners"
 	}
 	if p.verifyDNSLength {
 		s += ":VerifyDNSLength"
@@ -253,26 +284,29 @@
 
 	punycode = &Profile{}
 	lookup   = &Profile{options{
-		transitional:   true,
-		useSTD3Rules:   true,
-		validateLabels: true,
-		trie:           trie,
-		fromPuny:       validateFromPunycode,
-		mapping:        validateAndMap,
-		bidirule:       bidirule.ValidString,
+		transitional: true,
+		useSTD3Rules: true,
+		checkHyphens: true,
+		checkJoiners: true,
+		trie:         trie,
+		fromPuny:     validateFromPunycode,
+		mapping:      validateAndMap,
+		bidirule:     bidirule.ValidString,
 	}}
 	display = &Profile{options{
-		useSTD3Rules:   true,
-		validateLabels: true,
-		trie:           trie,
-		fromPuny:       validateFromPunycode,
-		mapping:        validateAndMap,
-		bidirule:       bidirule.ValidString,
+		useSTD3Rules: true,
+		checkHyphens: true,
+		checkJoiners: true,
+		trie:         trie,
+		fromPuny:     validateFromPunycode,
+		mapping:      validateAndMap,
+		bidirule:     bidirule.ValidString,
 	}}
 	registration = &Profile{options{
 		useSTD3Rules:    true,
-		validateLabels:  true,
 		verifyDNSLength: true,
+		checkHyphens:    true,
+		checkJoiners:    true,
 		trie:            trie,
 		fromPuny:        validateFromPunycode,
 		mapping:         validateRegistration,
@@ -339,7 +373,7 @@
 			}
 			isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight
 			labels.set(u)
-			if err == nil && p.validateLabels {
+			if err == nil && p.fromPuny != nil {
 				err = p.fromPuny(p, u)
 			}
 			if err == nil {
@@ -680,16 +714,18 @@
 		}
 		return nil
 	}
-	if !p.validateLabels {
+	if p.checkHyphens {
+		if len(s) > 4 && s[2] == '-' && s[3] == '-' {
+			return &labelError{s, "V2"}
+		}
+		if s[0] == '-' || s[len(s)-1] == '-' {
+			return &labelError{s, "V3"}
+		}
+	}
+	if !p.checkJoiners {
 		return nil
 	}
-	trie := p.trie // p.validateLabels is only set if trie is set.
-	if len(s) > 4 && s[2] == '-' && s[3] == '-' {
-		return &labelError{s, "V2"}
-	}
-	if s[0] == '-' || s[len(s)-1] == '-' {
-		return &labelError{s, "V3"}
-	}
+	trie := p.trie // p.checkJoiners is only set if trie is set.
 	// TODO: merge the use of this in the trie.
 	v, sz := trie.lookupString(s)
 	x := info(v)
diff --git a/src/vendor/golang.org/x/net/idna/idna9.0.0.go b/src/vendor/golang.org/x/net/idna/idna9.0.0.go
index 8842146..55f718f 100644
--- a/src/vendor/golang.org/x/net/idna/idna9.0.0.go
+++ b/src/vendor/golang.org/x/net/idna/idna9.0.0.go
@@ -4,6 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !go1.10
 // +build !go1.10
 
 // Package idna implements IDNA2008 using the compatibility processing
@@ -65,15 +66,14 @@
 
 // VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
 // are longer than allowed by the RFC.
+//
+// This option corresponds to the VerifyDnsLength flag in UTS #46.
 func VerifyDNSLength(verify bool) Option {
 	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 }
 }
@@ -81,6 +81,8 @@
 // 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.
+// In particular, ValidateLabels also sets the CheckHyphens and CheckJoiners flags
+// in UTS #46.
 func ValidateLabels(enable bool) Option {
 	return func(o *options) {
 		// Don't override existing mappings, but set one that at least checks
@@ -89,25 +91,48 @@
 			o.mapping = normalize
 		}
 		o.trie = trie
-		o.validateLabels = enable
-		o.fromPuny = validateFromPunycode
+		o.checkJoiners = enable
+		o.checkHyphens = enable
+		if enable {
+			o.fromPuny = validateFromPunycode
+		} else {
+			o.fromPuny = nil
+		}
+	}
+}
+
+// CheckHyphens sets whether to check for correct use of hyphens ('-') in
+// labels. Most web browsers do not have this option set, since labels such as
+// "r3---sn-apo3qvuoxuxbt-j5pe" are in common use.
+//
+// This option corresponds to the CheckHyphens flag in UTS #46.
+func CheckHyphens(enable bool) Option {
+	return func(o *options) { o.checkHyphens = enable }
+}
+
+// CheckJoiners sets whether to check the ContextJ rules as defined in Appendix
+// A of RFC 5892, concerning the use of joiner runes.
+//
+// This option corresponds to the CheckJoiners flag in UTS #46.
+func CheckJoiners(enable bool) Option {
+	return func(o *options) {
+		o.trie = trie
+		o.checkJoiners = enable
 	}
 }
 
 // StrictDomainName limits the set of permissable 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.
+// hyphen). This is set by default for MapForLookup and ValidateForRegistration,
+// but is only useful if ValidateLabels is set.
 //
 // This option is useful, for instance, for browsers that allow characters
 // outside this range, for example a '_' (U+005F LOW LINE). See
-// http://www.rfc-editor.org/std/std3.txt for more details This option
-// corresponds to the UseSTD3ASCIIRules option in UTS #46.
+// http://www.rfc-editor.org/std/std3.txt for more details.
+//
+// This option corresponds to the UseSTD3ASCIIRules flag in UTS #46.
 func StrictDomainName(use bool) Option {
-	return func(o *options) {
-		o.trie = trie
-		o.useSTD3Rules = use
-		o.fromPuny = validateFromPunycode
-	}
+	return func(o *options) { o.useSTD3Rules = use }
 }
 
 // NOTE: the following options pull in tables. The tables should not be linked
@@ -115,6 +140,8 @@
 
 // BidiRule enables the Bidi rule as defined in RFC 5893. Any application
 // that relies on proper validation of labels should include this rule.
+//
+// This option corresponds to the CheckBidi flag in UTS #46.
 func BidiRule() Option {
 	return func(o *options) { o.bidirule = bidirule.ValidString }
 }
@@ -151,7 +178,8 @@
 type options struct {
 	transitional      bool
 	useSTD3Rules      bool
-	validateLabels    bool
+	checkHyphens      bool
+	checkJoiners      bool
 	verifyDNSLength   bool
 	removeLeadingDots bool
 
@@ -224,8 +252,11 @@
 	if p.useSTD3Rules {
 		s += ":UseSTD3Rules"
 	}
-	if p.validateLabels {
-		s += ":ValidateLabels"
+	if p.checkHyphens {
+		s += ":CheckHyphens"
+	}
+	if p.checkJoiners {
+		s += ":CheckJoiners"
 	}
 	if p.verifyDNSLength {
 		s += ":VerifyDNSLength"
@@ -254,9 +285,10 @@
 	punycode = &Profile{}
 	lookup   = &Profile{options{
 		transitional:      true,
-		useSTD3Rules:      true,
-		validateLabels:    true,
 		removeLeadingDots: true,
+		useSTD3Rules:      true,
+		checkHyphens:      true,
+		checkJoiners:      true,
 		trie:              trie,
 		fromPuny:          validateFromPunycode,
 		mapping:           validateAndMap,
@@ -264,8 +296,9 @@
 	}}
 	display = &Profile{options{
 		useSTD3Rules:      true,
-		validateLabels:    true,
 		removeLeadingDots: true,
+		checkHyphens:      true,
+		checkJoiners:      true,
 		trie:              trie,
 		fromPuny:          validateFromPunycode,
 		mapping:           validateAndMap,
@@ -273,8 +306,9 @@
 	}}
 	registration = &Profile{options{
 		useSTD3Rules:    true,
-		validateLabels:  true,
 		verifyDNSLength: true,
+		checkHyphens:    true,
+		checkJoiners:    true,
 		trie:            trie,
 		fromPuny:        validateFromPunycode,
 		mapping:         validateRegistration,
@@ -338,7 +372,7 @@
 				continue
 			}
 			labels.set(u)
-			if err == nil && p.validateLabels {
+			if err == nil && p.fromPuny != nil {
 				err = p.fromPuny(p, u)
 			}
 			if err == nil {
@@ -628,16 +662,18 @@
 	if p.bidirule != nil && !p.bidirule(s) {
 		return &labelError{s, "B"}
 	}
-	if !p.validateLabels {
+	if p.checkHyphens {
+		if len(s) > 4 && s[2] == '-' && s[3] == '-' {
+			return &labelError{s, "V2"}
+		}
+		if s[0] == '-' || s[len(s)-1] == '-' {
+			return &labelError{s, "V3"}
+		}
+	}
+	if !p.checkJoiners {
 		return nil
 	}
-	trie := p.trie // p.validateLabels is only set if trie is set.
-	if len(s) > 4 && s[2] == '-' && s[3] == '-' {
-		return &labelError{s, "V2"}
-	}
-	if s[0] == '-' || s[len(s)-1] == '-' {
-		return &labelError{s, "V3"}
-	}
+	trie := p.trie // p.checkJoiners is only set if trie is set.
 	// TODO: merge the use of this in the trie.
 	v, sz := trie.lookupString(s)
 	x := info(v)
diff --git a/src/vendor/golang.org/x/net/idna/tables10.0.0.go b/src/vendor/golang.org/x/net/idna/tables10.0.0.go
index 54fddb4..d1d62ef 100644
--- a/src/vendor/golang.org/x/net/idna/tables10.0.0.go
+++ b/src/vendor/golang.org/x/net/idna/tables10.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build go1.10 && !go1.13
 // +build go1.10,!go1.13
 
 package idna
diff --git a/src/vendor/golang.org/x/net/idna/tables11.0.0.go b/src/vendor/golang.org/x/net/idna/tables11.0.0.go
index 8ce0811..167efba 100644
--- a/src/vendor/golang.org/x/net/idna/tables11.0.0.go
+++ b/src/vendor/golang.org/x/net/idna/tables11.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build go1.13 && !go1.14
 // +build go1.13,!go1.14
 
 package idna
diff --git a/src/vendor/golang.org/x/net/idna/tables12.0.0.go b/src/vendor/golang.org/x/net/idna/tables12.0.0.go
index f39f0cb..ab40f7b 100644
--- a/src/vendor/golang.org/x/net/idna/tables12.0.0.go
+++ b/src/vendor/golang.org/x/net/idna/tables12.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build go1.14 && !go1.16
 // +build go1.14,!go1.16
 
 package idna
diff --git a/src/vendor/golang.org/x/net/idna/tables13.0.0.go b/src/vendor/golang.org/x/net/idna/tables13.0.0.go
index e8c7a36..390c5e5 100644
--- a/src/vendor/golang.org/x/net/idna/tables13.0.0.go
+++ b/src/vendor/golang.org/x/net/idna/tables13.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build go1.16
 // +build go1.16
 
 package idna
diff --git a/src/vendor/golang.org/x/net/idna/tables9.0.0.go b/src/vendor/golang.org/x/net/idna/tables9.0.0.go
index 8b65fa1..4074b53 100644
--- a/src/vendor/golang.org/x/net/idna/tables9.0.0.go
+++ b/src/vendor/golang.org/x/net/idna/tables9.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build !go1.10
 // +build !go1.10
 
 package idna
diff --git a/src/vendor/golang.org/x/net/nettest/nettest_stub.go b/src/vendor/golang.org/x/net/nettest/nettest_stub.go
index 22c2461..6e3a931 100644
--- a/src/vendor/golang.org/x/net/nettest/nettest_stub.go
+++ b/src/vendor/golang.org/x/net/nettest/nettest_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
 // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
 
 package nettest
diff --git a/src/vendor/golang.org/x/net/nettest/nettest_unix.go b/src/vendor/golang.org/x/net/nettest/nettest_unix.go
index c1b1359..b1cb8b2 100644
--- a/src/vendor/golang.org/x/net/nettest/nettest_unix.go
+++ b/src/vendor/golang.org/x/net/nettest/nettest_unix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
 
 package nettest
diff --git a/src/vendor/golang.org/x/net/route/address.go b/src/vendor/golang.org/x/net/route/address.go
index 3c2fe15..4f6ad96 100644
--- a/src/vendor/golang.org/x/net/route/address.go
+++ b/src/vendor/golang.org/x/net/route/address.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 package route
diff --git a/src/vendor/golang.org/x/net/route/binary.go b/src/vendor/golang.org/x/net/route/binary.go
index 6910520..a5e28f1 100644
--- a/src/vendor/golang.org/x/net/route/binary.go
+++ b/src/vendor/golang.org/x/net/route/binary.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 package route
diff --git a/src/vendor/golang.org/x/net/route/empty.s b/src/vendor/golang.org/x/net/route/empty.s
index bff0231..90ab4ca 100644
--- a/src/vendor/golang.org/x/net/route/empty.s
+++ b/src/vendor/golang.org/x/net/route/empty.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin && go1.12
 // +build darwin,go1.12
 
 // This exists solely so we can linkname in symbols from syscall.
diff --git a/src/vendor/golang.org/x/net/route/interface.go b/src/vendor/golang.org/x/net/route/interface.go
index 05ef2a9..9e94078 100644
--- a/src/vendor/golang.org/x/net/route/interface.go
+++ b/src/vendor/golang.org/x/net/route/interface.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 package route
diff --git a/src/vendor/golang.org/x/net/route/interface_announce.go b/src/vendor/golang.org/x/net/route/interface_announce.go
index 520d657..8282bfe 100644
--- a/src/vendor/golang.org/x/net/route/interface_announce.go
+++ b/src/vendor/golang.org/x/net/route/interface_announce.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || netbsd
 // +build dragonfly freebsd netbsd
 
 package route
diff --git a/src/vendor/golang.org/x/net/route/interface_classic.go b/src/vendor/golang.org/x/net/route/interface_classic.go
index ac4e7a6..85b7e99 100644
--- a/src/vendor/golang.org/x/net/route/interface_classic.go
+++ b/src/vendor/golang.org/x/net/route/interface_classic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || netbsd
 // +build darwin dragonfly netbsd
 
 package route
diff --git a/src/vendor/golang.org/x/net/route/interface_multicast.go b/src/vendor/golang.org/x/net/route/interface_multicast.go
index 1e99a9c..dd0b214 100644
--- a/src/vendor/golang.org/x/net/route/interface_multicast.go
+++ b/src/vendor/golang.org/x/net/route/interface_multicast.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd
 // +build darwin dragonfly freebsd
 
 package route
diff --git a/src/vendor/golang.org/x/net/route/message.go b/src/vendor/golang.org/x/net/route/message.go
index 80c482a..d53bb7f 100644
--- a/src/vendor/golang.org/x/net/route/message.go
+++ b/src/vendor/golang.org/x/net/route/message.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 package route
diff --git a/src/vendor/golang.org/x/net/route/route.go b/src/vendor/golang.org/x/net/route/route.go
index 4462cf1..fd0019e 100644
--- a/src/vendor/golang.org/x/net/route/route.go
+++ b/src/vendor/golang.org/x/net/route/route.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 // Package route provides basic functions for the manipulation of
@@ -107,17 +108,28 @@
 // an interface index or a set of interface flags. In most cases, zero
 // means a wildcard.
 func FetchRIB(af int, typ RIBType, arg int) ([]byte, error) {
-	mib := [6]int32{sysCTL_NET, sysAF_ROUTE, 0, int32(af), int32(typ), int32(arg)}
-	n := uintptr(0)
-	if err := sysctl(mib[:], nil, &n, nil, 0); err != nil {
-		return nil, os.NewSyscallError("sysctl", err)
+	try := 0
+	for {
+		try++
+		mib := [6]int32{sysCTL_NET, sysAF_ROUTE, 0, int32(af), int32(typ), int32(arg)}
+		n := uintptr(0)
+		if err := sysctl(mib[:], nil, &n, nil, 0); err != nil {
+			return nil, os.NewSyscallError("sysctl", err)
+		}
+		if n == 0 {
+			return nil, nil
+		}
+		b := make([]byte, n)
+		if err := sysctl(mib[:], &b[0], &n, nil, 0); err != nil {
+			// If the sysctl failed because the data got larger
+			// between the two sysctl calls, try a few times
+			// before failing. (golang.org/issue/45736).
+			const maxTries = 3
+			if err == syscall.ENOMEM && try < maxTries {
+				continue
+			}
+			return nil, os.NewSyscallError("sysctl", err)
+		}
+		return b[:n], nil
 	}
-	if n == 0 {
-		return nil, nil
-	}
-	b := make([]byte, n)
-	if err := sysctl(mib[:], &b[0], &n, nil, 0); err != nil {
-		return nil, os.NewSyscallError("sysctl", err)
-	}
-	return b[:n], nil
 }
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 b83add6..d6ee42f 100644
--- a/src/vendor/golang.org/x/net/route/route_classic.go
+++ b/src/vendor/golang.org/x/net/route/route_classic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd
 // +build darwin dragonfly freebsd netbsd
 
 package route
diff --git a/src/vendor/golang.org/x/net/route/sys.go b/src/vendor/golang.org/x/net/route/sys.go
index a0ab3e9..537484a 100644
--- a/src/vendor/golang.org/x/net/route/sys.go
+++ b/src/vendor/golang.org/x/net/route/sys.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
 // +build darwin dragonfly freebsd netbsd openbsd
 
 package route
diff --git a/src/vendor/golang.org/x/net/route/syscall.go b/src/vendor/golang.org/x/net/route/syscall.go
index 72431b0..97166dd 100644
--- a/src/vendor/golang.org/x/net/route/syscall.go
+++ b/src/vendor/golang.org/x/net/route/syscall.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build dragonfly || freebsd || netbsd || openbsd
 // +build dragonfly freebsd netbsd openbsd
 
 package route
diff --git a/src/vendor/golang.org/x/net/route/syscall_go1_12_darwin.go b/src/vendor/golang.org/x/net/route/syscall_go1_12_darwin.go
index 7922a68..7a13e4f 100644
--- a/src/vendor/golang.org/x/net/route/syscall_go1_12_darwin.go
+++ b/src/vendor/golang.org/x/net/route/syscall_go1_12_darwin.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.12
 // +build go1.12
 
 package route
diff --git a/src/vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s b/src/vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s
index 6b4027b..db9171c 100644
--- a/src/vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s
+++ b/src/vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 #include "textflag.h"
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu.go b/src/vendor/golang.org/x/sys/cpu/cpu.go
index f77701f..abbec2d 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu.go
@@ -154,14 +154,13 @@
 // For ppc64/ppc64le, 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 feature bits for
-// those as well. The minimum processor requirement is POWER8 (ISA 2.07).
-// The struct is padded to avoid false sharing.
+// those as well. The struct is padded to avoid false sharing.
 var PPC64 struct {
 	_        CacheLinePad
 	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)
+	IsPOWER9 bool // ISA v3.00 (POWER9), implies IsPOWER8
 	_        CacheLinePad
 }
 
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_aix.go b/src/vendor/golang.org/x/sys/cpu/cpu_aix.go
index 464a209..8aaeef5 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_aix.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_aix.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build aix
 // +build aix
 
 package cpu
@@ -19,6 +20,7 @@
 		PPC64.IsPOWER8 = true
 	}
 	if impl&_IMPL_POWER9 != 0 {
+		PPC64.IsPOWER8 = true
 		PPC64.IsPOWER9 = true
 	}
 
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_arm64.s b/src/vendor/golang.org/x/sys/cpu/cpu_arm64.s
index cfc08c9..c61f95a 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_arm64.s
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_arm64.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 #include "textflag.h"
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go b/src/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
index 7f7f272..ccf542a 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 package cpu
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go b/src/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go
index 75a9556..0af2f24 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 package cpu
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go b/src/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
index 4adb89c..3298a87 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (386 || amd64 || amd64p32) && gc
 // +build 386 amd64 amd64p32
 // +build gc
 
@@ -14,3 +15,7 @@
 // xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
 // and in cpu_gccgo.c for gccgo.
 func xgetbv() (eax, edx uint32)
+
+// darwinSupportsAVX512 is implemented in cpu_x86.s for gc compiler
+// and in cpu_gccgo_x86.go for gccgo.
+func darwinSupportsAVX512() bool
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go b/src/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go
index 53ca8d6..2aff318 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gccgo
 // +build gccgo
 
 package cpu
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go b/src/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go
index aa986f7..4bfbda6 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gccgo
 // +build gccgo
 
 package cpu
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go b/src/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go
index ba49b91..863d415 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (386 || amd64 || amd64p32) && gccgo
 // +build 386 amd64 amd64p32
 // +build gccgo
 
@@ -24,3 +25,9 @@
 	gccgoXgetbv(&a, &d)
 	return a, d
 }
+
+// gccgo doesn't build on Darwin, per:
+// https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/gcc.rb#L76
+func darwinSupportsAVX512() bool {
+	return false
+}
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_linux.go b/src/vendor/golang.org/x/sys/cpu/cpu_linux.go
index 6fc874f..159a686 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_linux.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_linux.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !386 && !amd64 && !amd64p32 && !arm64
 // +build !386,!amd64,!amd64p32,!arm64
 
 package cpu
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go b/src/vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go
index 5a41890..6000db4 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (mips64 || mips64le)
 // +build linux
 // +build mips64 mips64le
 
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go b/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go
index 42b5d33..f4992b1 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x
 // +build linux,!arm,!arm64,!mips64,!mips64le,!ppc64,!ppc64le,!s390x
 
 package cpu
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go b/src/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go
index 99f8a63..021356d 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux && (ppc64 || ppc64le)
 // +build linux
 // +build ppc64 ppc64le
 
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_mips64x.go b/src/vendor/golang.org/x/sys/cpu/cpu_mips64x.go
index 57b5b67..f4063c6 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_mips64x.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips64 || mips64le
 // +build mips64 mips64le
 
 package cpu
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_mipsx.go b/src/vendor/golang.org/x/sys/cpu/cpu_mipsx.go
index cfc1946..07c4e36 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_mipsx.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_mipsx.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build mips || mipsle
 // +build mips mipsle
 
 package cpu
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_other_arm.go b/src/vendor/golang.org/x/sys/cpu/cpu_other_arm.go
index b412efc..d7b4fb4 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_other_arm.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_other_arm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !linux && arm
 // +build !linux,arm
 
 package cpu
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go b/src/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
index 16c1c40..f8c484f 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !linux,!netbsd
-// +build arm64
+//go:build !linux && !netbsd && arm64
+// +build !linux,!netbsd,arm64
 
 package cpu
 
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go b/src/vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go
index f49fad6..0dafe96 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !linux && (mips64 || mips64le)
 // +build !linux
 // +build mips64 mips64le
 
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_ppc64x.go b/src/vendor/golang.org/x/sys/cpu/cpu_ppc64x.go
index d28d675..4e8acd1 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_ppc64x.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_ppc64x.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build ppc64 || ppc64le
 // +build ppc64 ppc64le
 
 package cpu
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_riscv64.go b/src/vendor/golang.org/x/sys/cpu/cpu_riscv64.go
index 8b08de3..bd6c128 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_riscv64.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_riscv64.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build riscv64
 // +build riscv64
 
 package cpu
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_s390x.s b/src/vendor/golang.org/x/sys/cpu/cpu_s390x.s
index 964946d..96f81e2 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_s390x.s
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_s390x.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build gc
 // +build gc
 
 #include "textflag.h"
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_wasm.go b/src/vendor/golang.org/x/sys/cpu/cpu_wasm.go
index 5382f2a..7747d88 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_wasm.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_wasm.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build wasm
 // +build wasm
 
 package cpu
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_x86.go b/src/vendor/golang.org/x/sys/cpu/cpu_x86.go
index 48d4293..54ca466 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_x86.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_x86.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build 386 || amd64 || amd64p32
 // +build 386 amd64 amd64p32
 
 package cpu
@@ -86,8 +87,14 @@
 		// Check if XMM and YMM registers have OS support.
 		osSupportsAVX = isSet(1, eax) && isSet(2, eax)
 
-		// Check if OPMASK and ZMM registers have OS support.
-		osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax)
+		if runtime.GOOS == "darwin" {
+			// Check darwin commpage for AVX512 support. Necessary because:
+			// https://github.com/apple/darwin-xnu/blob/0a798f6738bc1db01281fc08ae024145e84df927/osfmk/i386/fpu.c#L175-L201
+			osSupportsAVX512 = osSupportsAVX && darwinSupportsAVX512()
+		} else {
+			// Check if OPMASK and ZMM registers have OS support.
+			osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax)
+		}
 	}
 
 	X86.HasAVX = isSet(28, ecx1) && osSupportsAVX
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_x86.s b/src/vendor/golang.org/x/sys/cpu/cpu_x86.s
index 2f557a5..b748ba5 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_x86.s
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_x86.s
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (386 || amd64 || amd64p32) && gc
 // +build 386 amd64 amd64p32
 // +build gc
 
@@ -25,3 +26,27 @@
 	MOVL AX, eax+0(FP)
 	MOVL DX, edx+4(FP)
 	RET
+
+// func darwinSupportsAVX512() bool
+TEXT ·darwinSupportsAVX512(SB), NOSPLIT, $0-1
+    MOVB    $0, ret+0(FP) // default to false
+#ifdef GOOS_darwin   // return if not darwin
+#ifdef GOARCH_amd64  // return if not amd64
+// These values from:
+// https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/osfmk/i386/cpu_capabilities.h
+#define commpage64_base_address         0x00007fffffe00000
+#define commpage64_cpu_capabilities64   (commpage64_base_address+0x010)
+#define commpage64_version              (commpage64_base_address+0x01E)
+#define hasAVX512F                      0x0000004000000000
+    MOVQ    $commpage64_version, BX
+    CMPW    (BX), $13  // cpu_capabilities64 undefined in versions < 13
+    JL      no_avx512
+    MOVQ    $commpage64_cpu_capabilities64, BX
+    MOVQ    $hasAVX512F, CX
+    TESTQ   (BX), CX
+    JZ      no_avx512
+    MOVB    $1, ret+0(FP)
+no_avx512:
+#endif
+#endif
+    RET
diff --git a/src/vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go b/src/vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go
index 76fbe40..a864f24 100644
--- a/src/vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go
+++ b/src/vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go
@@ -8,8 +8,8 @@
 // Morever, this file will be used during the building of
 // gccgo's libgo and thus must not used a CGo method.
 
-// +build aix
-// +build gccgo
+//go:build aix && gccgo
+// +build aix,gccgo
 
 package cpu
 
diff --git a/src/vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go b/src/vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go
index 5b427d6..904be42 100644
--- a/src/vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go
+++ b/src/vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go
@@ -6,8 +6,8 @@
 // system call on AIX without depending on x/sys/unix.
 // (See golang.org/issue/32102)
 
-// +build aix,ppc64
-// +build gc
+//go:build aix && ppc64 && gc
+// +build aix,ppc64,gc
 
 package cpu
 
diff --git a/src/vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go b/src/vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go
index e4c6228..8a7392c 100644
--- a/src/vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go
+++ b/src/vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.10
 // +build go1.10
 
 package bidirule
diff --git a/src/vendor/golang.org/x/text/secure/bidirule/bidirule9.0.0.go b/src/vendor/golang.org/x/text/secure/bidirule/bidirule9.0.0.go
index 02b9e1e..bb0a920 100644
--- a/src/vendor/golang.org/x/text/secure/bidirule/bidirule9.0.0.go
+++ b/src/vendor/golang.org/x/text/secure/bidirule/bidirule9.0.0.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !go1.10
 // +build !go1.10
 
 package bidirule
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 e8edc54..fd05760 100644
--- a/src/vendor/golang.org/x/text/unicode/bidi/bidi.go
+++ b/src/vendor/golang.org/x/text/unicode/bidi/bidi.go
@@ -12,15 +12,14 @@
 // and without notice.
 package bidi // import "golang.org/x/text/unicode/bidi"
 
-// TODO:
-// The following functionality would not be hard to implement, but hinges on
-// the definition of a Segmenter interface. For now this is up to the user.
-// - Iterate over paragraphs
-// - Segmenter to iterate over runs directly from a given text.
-// Also:
+// TODO
 // - Transformer for reordering?
 // - Transformer (validator, really) for Bidi Rule.
 
+import (
+	"bytes"
+)
+
 // This API tries to avoid dealing with embedding levels for now. Under the hood
 // these will be computed, but the question is to which extent the user should
 // know they exist. We should at some point allow the user to specify an
@@ -49,7 +48,9 @@
 	Neutral
 )
 
-type options struct{}
+type options struct {
+	defaultDirection Direction
+}
 
 // An Option is an option for Bidi processing.
 type Option func(*options)
@@ -66,12 +67,62 @@
 // DefaultDirection sets the default direction for a Paragraph. The direction is
 // overridden if the text contains directional characters.
 func DefaultDirection(d Direction) Option {
-	panic("unimplemented")
+	return func(opts *options) {
+		opts.defaultDirection = d
+	}
 }
 
 // A Paragraph holds a single Paragraph for Bidi processing.
 type Paragraph struct {
-	// buffers
+	p          []byte
+	o          Ordering
+	opts       []Option
+	types      []Class
+	pairTypes  []bracketType
+	pairValues []rune
+	runes      []rune
+	options    options
+}
+
+// Initialize the p.pairTypes, p.pairValues and p.types from the input previously
+// set by p.SetBytes() or p.SetString(). Also limit the input up to (and including) a paragraph
+// separator (bidi class B).
+//
+// The function p.Order() needs these values to be set, so this preparation could be postponed.
+// But since the SetBytes and SetStrings functions return the length of the input up to the paragraph
+// separator, the whole input needs to be processed anyway and should not be done twice.
+//
+// The function has the same return values as SetBytes() / SetString()
+func (p *Paragraph) prepareInput() (n int, err error) {
+	p.runes = bytes.Runes(p.p)
+	bytecount := 0
+	// clear slices from previous SetString or SetBytes
+	p.pairTypes = nil
+	p.pairValues = nil
+	p.types = nil
+
+	for _, r := range p.runes {
+		props, i := LookupRune(r)
+		bytecount += i
+		cls := props.Class()
+		if cls == B {
+			return bytecount, nil
+		}
+		p.types = append(p.types, cls)
+		if props.IsOpeningBracket() {
+			p.pairTypes = append(p.pairTypes, bpOpen)
+			p.pairValues = append(p.pairValues, r)
+		} else if props.IsBracket() {
+			// this must be a closing bracket,
+			// since IsOpeningBracket is not true
+			p.pairTypes = append(p.pairTypes, bpClose)
+			p.pairValues = append(p.pairValues, r)
+		} else {
+			p.pairTypes = append(p.pairTypes, bpNone)
+			p.pairValues = append(p.pairValues, 0)
+		}
+	}
+	return bytecount, nil
 }
 
 // SetBytes configures p for the given paragraph text. It replaces text
@@ -80,70 +131,150 @@
 // consumed from b including this separator. Error may be non-nil if options are
 // given.
 func (p *Paragraph) SetBytes(b []byte, opts ...Option) (n int, err error) {
-	panic("unimplemented")
+	p.p = b
+	p.opts = opts
+	return p.prepareInput()
 }
 
-// SetString configures p for the given paragraph text. It replaces text
-// previously set by SetBytes or SetString. If b contains a paragraph separator
+// SetString configures s for the given paragraph text. It replaces text
+// previously set by SetBytes or SetString. If s contains a paragraph separator
 // it will only process the first paragraph and report the number of bytes
-// consumed from b including this separator. Error may be non-nil if options are
+// consumed from s including this separator. Error may be non-nil if options are
 // given.
 func (p *Paragraph) SetString(s string, opts ...Option) (n int, err error) {
-	panic("unimplemented")
+	p.p = []byte(s)
+	p.opts = opts
+	return p.prepareInput()
 }
 
 // IsLeftToRight reports whether the principle direction of rendering for this
 // paragraphs is left-to-right. If this returns false, the principle direction
 // of rendering is right-to-left.
 func (p *Paragraph) IsLeftToRight() bool {
-	panic("unimplemented")
+	return p.Direction() == LeftToRight
 }
 
 // Direction returns the direction of the text of this paragraph.
 //
 // The direction may be LeftToRight, RightToLeft, Mixed, or Neutral.
 func (p *Paragraph) Direction() Direction {
-	panic("unimplemented")
+	return p.o.Direction()
 }
 
+// TODO: what happens if the position is > len(input)? This should return an error.
+
 // RunAt reports the Run at the given position of the input text.
 //
 // This method can be used for computing line breaks on paragraphs.
 func (p *Paragraph) RunAt(pos int) Run {
-	panic("unimplemented")
+	c := 0
+	runNumber := 0
+	for i, r := range p.o.runes {
+		c += len(r)
+		if pos < c {
+			runNumber = i
+		}
+	}
+	return p.o.Run(runNumber)
+}
+
+func calculateOrdering(levels []level, runes []rune) Ordering {
+	var curDir Direction
+
+	prevDir := Neutral
+	prevI := 0
+
+	o := Ordering{}
+	// lvl = 0,2,4,...: left to right
+	// lvl = 1,3,5,...: right to left
+	for i, lvl := range levels {
+		if lvl%2 == 0 {
+			curDir = LeftToRight
+		} else {
+			curDir = RightToLeft
+		}
+		if curDir != prevDir {
+			if i > 0 {
+				o.runes = append(o.runes, runes[prevI:i])
+				o.directions = append(o.directions, prevDir)
+				o.startpos = append(o.startpos, prevI)
+			}
+			prevI = i
+			prevDir = curDir
+		}
+	}
+	o.runes = append(o.runes, runes[prevI:])
+	o.directions = append(o.directions, prevDir)
+	o.startpos = append(o.startpos, prevI)
+	return o
 }
 
 // Order computes the visual ordering of all the runs in a Paragraph.
 func (p *Paragraph) Order() (Ordering, error) {
-	panic("unimplemented")
+	if len(p.types) == 0 {
+		return Ordering{}, nil
+	}
+
+	for _, fn := range p.opts {
+		fn(&p.options)
+	}
+	lvl := level(-1)
+	if p.options.defaultDirection == RightToLeft {
+		lvl = 1
+	}
+	para, err := newParagraph(p.types, p.pairTypes, p.pairValues, lvl)
+	if err != nil {
+		return Ordering{}, err
+	}
+
+	levels := para.getLevels([]int{len(p.types)})
+
+	p.o = calculateOrdering(levels, p.runes)
+	return p.o, nil
 }
 
 // Line computes the visual ordering of runs for a single line starting and
 // ending at the given positions in the original text.
 func (p *Paragraph) Line(start, end int) (Ordering, error) {
-	panic("unimplemented")
+	lineTypes := p.types[start:end]
+	para, err := newParagraph(lineTypes, p.pairTypes[start:end], p.pairValues[start:end], -1)
+	if err != nil {
+		return Ordering{}, err
+	}
+	levels := para.getLevels([]int{len(lineTypes)})
+	o := calculateOrdering(levels, p.runes[start:end])
+	return o, nil
 }
 
 // An Ordering holds the computed visual order of runs of a Paragraph. Calling
 // SetBytes or SetString on the originating Paragraph invalidates an Ordering.
 // The methods of an Ordering should only be called by one goroutine at a time.
-type Ordering struct{}
+type Ordering struct {
+	runes      [][]rune
+	directions []Direction
+	startpos   []int
+}
 
 // Direction reports the directionality of the runs.
 //
 // The direction may be LeftToRight, RightToLeft, Mixed, or Neutral.
 func (o *Ordering) Direction() Direction {
-	panic("unimplemented")
+	return o.directions[0]
 }
 
 // NumRuns returns the number of runs.
 func (o *Ordering) NumRuns() int {
-	panic("unimplemented")
+	return len(o.runes)
 }
 
 // Run returns the ith run within the ordering.
 func (o *Ordering) Run(i int) Run {
-	panic("unimplemented")
+	r := Run{
+		runes:     o.runes[i],
+		direction: o.directions[i],
+		startpos:  o.startpos[i],
+	}
+	return r
 }
 
 // TODO: perhaps with options.
@@ -155,16 +286,19 @@
 
 // A Run is a continuous sequence of characters of a single direction.
 type Run struct {
+	runes     []rune
+	direction Direction
+	startpos  int
 }
 
 // String returns the text of the run in its original order.
 func (r *Run) String() string {
-	panic("unimplemented")
+	return string(r.runes)
 }
 
 // Bytes returns the text of the run in its original order.
 func (r *Run) Bytes() []byte {
-	panic("unimplemented")
+	return []byte(r.String())
 }
 
 // TODO: methods for
@@ -174,25 +308,52 @@
 
 // Direction reports the direction of the run.
 func (r *Run) Direction() Direction {
-	panic("unimplemented")
+	return r.direction
 }
 
-// Position of the Run within the text passed to SetBytes or SetString of the
+// Pos returns the position of the Run within the text passed to SetBytes or SetString of the
 // originating Paragraph value.
 func (r *Run) Pos() (start, end int) {
-	panic("unimplemented")
+	return r.startpos, r.startpos + len(r.runes) - 1
 }
 
 // AppendReverse reverses the order of characters of in, appends them to out,
 // and returns the result. Modifiers will still follow the runes they modify.
 // Brackets are replaced with their counterparts.
 func AppendReverse(out, in []byte) []byte {
-	panic("unimplemented")
+	ret := make([]byte, len(in)+len(out))
+	copy(ret, out)
+	inRunes := bytes.Runes(in)
+
+	for i, r := range inRunes {
+		prop, _ := LookupRune(r)
+		if prop.IsBracket() {
+			inRunes[i] = prop.reverseBracket(r)
+		}
+	}
+
+	for i, j := 0, len(inRunes)-1; i < j; i, j = i+1, j-1 {
+		inRunes[i], inRunes[j] = inRunes[j], inRunes[i]
+	}
+	copy(ret[len(out):], string(inRunes))
+
+	return ret
 }
 
 // ReverseString reverses the order of characters in s and returns a new string.
 // Modifiers will still follow the runes they modify. Brackets are replaced with
 // their counterparts.
 func ReverseString(s string) string {
-	panic("unimplemented")
+	input := []rune(s)
+	li := len(input)
+	ret := make([]rune, li)
+	for i, r := range input {
+		prop, _ := LookupRune(r)
+		if prop.IsBracket() {
+			ret[li-i-1] = prop.reverseBracket(r)
+		} else {
+			ret[li-i-1] = r
+		}
+	}
+	return string(ret)
 }
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 50deb66..e4c0811 100644
--- a/src/vendor/golang.org/x/text/unicode/bidi/core.go
+++ b/src/vendor/golang.org/x/text/unicode/bidi/core.go
@@ -4,7 +4,10 @@
 
 package bidi
 
-import "log"
+import (
+	"fmt"
+	"log"
+)
 
 // This implementation is a port based on the reference implementation found at:
 // https://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/
@@ -97,13 +100,20 @@
 // rune (suggested is the rune of the open bracket for opening and matching
 // close brackets, after normalization). The embedding levels are optional, but
 // may be supplied to encode embedding levels of styled text.
-//
-// TODO: return an error.
-func newParagraph(types []Class, pairTypes []bracketType, pairValues []rune, levels level) *paragraph {
-	validateTypes(types)
-	validatePbTypes(pairTypes)
-	validatePbValues(pairValues, pairTypes)
-	validateParagraphEmbeddingLevel(levels)
+func newParagraph(types []Class, pairTypes []bracketType, pairValues []rune, levels level) (*paragraph, error) {
+	var err error
+	if err = validateTypes(types); err != nil {
+		return nil, err
+	}
+	if err = validatePbTypes(pairTypes); err != nil {
+		return nil, err
+	}
+	if err = validatePbValues(pairValues, pairTypes); err != nil {
+		return nil, err
+	}
+	if err = validateParagraphEmbeddingLevel(levels); err != nil {
+		return nil, err
+	}
 
 	p := &paragraph{
 		initialTypes:   append([]Class(nil), types...),
@@ -115,7 +125,7 @@
 		resultTypes: append([]Class(nil), types...),
 	}
 	p.run()
-	return p
+	return p, nil
 }
 
 func (p *paragraph) Len() int { return len(p.initialTypes) }
@@ -1001,58 +1011,61 @@
 	return R
 }
 
-// TODO: change validation to not panic
-
-func validateTypes(types []Class) {
+func validateTypes(types []Class) error {
 	if len(types) == 0 {
-		log.Panic("types is null")
+		return fmt.Errorf("types is null")
 	}
 	for i, t := range types[:len(types)-1] {
 		if t == B {
-			log.Panicf("B type before end of paragraph at index: %d", i)
+			return fmt.Errorf("B type before end of paragraph at index: %d", i)
 		}
 	}
+	return nil
 }
 
-func validateParagraphEmbeddingLevel(embeddingLevel level) {
+func validateParagraphEmbeddingLevel(embeddingLevel level) error {
 	if embeddingLevel != implicitLevel &&
 		embeddingLevel != 0 &&
 		embeddingLevel != 1 {
-		log.Panicf("illegal paragraph embedding level: %d", embeddingLevel)
+		return fmt.Errorf("illegal paragraph embedding level: %d", embeddingLevel)
 	}
+	return nil
 }
 
-func validateLineBreaks(linebreaks []int, textLength int) {
+func validateLineBreaks(linebreaks []int, textLength int) error {
 	prev := 0
 	for i, next := range linebreaks {
 		if next <= prev {
-			log.Panicf("bad linebreak: %d at index: %d", next, i)
+			return fmt.Errorf("bad linebreak: %d at index: %d", next, i)
 		}
 		prev = next
 	}
 	if prev != textLength {
-		log.Panicf("last linebreak was %d, want %d", prev, textLength)
+		return fmt.Errorf("last linebreak was %d, want %d", prev, textLength)
 	}
+	return nil
 }
 
-func validatePbTypes(pairTypes []bracketType) {
+func validatePbTypes(pairTypes []bracketType) error {
 	if len(pairTypes) == 0 {
-		log.Panic("pairTypes is null")
+		return fmt.Errorf("pairTypes is null")
 	}
 	for i, pt := range pairTypes {
 		switch pt {
 		case bpNone, bpOpen, bpClose:
 		default:
-			log.Panicf("illegal pairType value at %d: %v", i, pairTypes[i])
+			return fmt.Errorf("illegal pairType value at %d: %v", i, pairTypes[i])
 		}
 	}
+	return nil
 }
 
-func validatePbValues(pairValues []rune, pairTypes []bracketType) {
+func validatePbValues(pairValues []rune, pairTypes []bracketType) error {
 	if pairValues == nil {
-		log.Panic("pairValues is null")
+		return fmt.Errorf("pairValues is null")
 	}
 	if len(pairTypes) != len(pairValues) {
-		log.Panic("pairTypes is different length from pairValues")
+		return fmt.Errorf("pairTypes is different length from pairValues")
 	}
+	return nil
 }
diff --git a/src/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go b/src/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go
index d8c94e1..42fa8d7 100644
--- a/src/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go
+++ b/src/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build go1.10 && !go1.13
 // +build go1.10,!go1.13
 
 package bidi
diff --git a/src/vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go b/src/vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go
index 16b11db..56a0e1e 100644
--- a/src/vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go
+++ b/src/vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build go1.13 && !go1.14
 // +build go1.13,!go1.14
 
 package bidi
diff --git a/src/vendor/golang.org/x/text/unicode/bidi/tables12.0.0.go b/src/vendor/golang.org/x/text/unicode/bidi/tables12.0.0.go
index 647f2d4..baacf32 100644
--- a/src/vendor/golang.org/x/text/unicode/bidi/tables12.0.0.go
+++ b/src/vendor/golang.org/x/text/unicode/bidi/tables12.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build go1.14 && !go1.16
 // +build go1.14,!go1.16
 
 package bidi
diff --git a/src/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go b/src/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go
index c937d09..f248eff 100644
--- a/src/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go
+++ b/src/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build go1.16
 // +build go1.16
 
 package bidi
diff --git a/src/vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go b/src/vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go
index 0ca0193..f517fdb 100644
--- a/src/vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go
+++ b/src/vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build !go1.10
 // +build !go1.10
 
 package bidi
diff --git a/src/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go b/src/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go
index 26fbd55..f5a0788 100644
--- a/src/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go
+++ b/src/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build go1.10 && !go1.13
 // +build go1.10,!go1.13
 
 package norm
diff --git a/src/vendor/golang.org/x/text/unicode/norm/tables11.0.0.go b/src/vendor/golang.org/x/text/unicode/norm/tables11.0.0.go
index 2c58f09..cb7239c 100644
--- a/src/vendor/golang.org/x/text/unicode/norm/tables11.0.0.go
+++ b/src/vendor/golang.org/x/text/unicode/norm/tables11.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build go1.13 && !go1.14
 // +build go1.13,!go1.14
 
 package norm
diff --git a/src/vendor/golang.org/x/text/unicode/norm/tables12.0.0.go b/src/vendor/golang.org/x/text/unicode/norm/tables12.0.0.go
index 7e1ae09..11b2733 100644
--- a/src/vendor/golang.org/x/text/unicode/norm/tables12.0.0.go
+++ b/src/vendor/golang.org/x/text/unicode/norm/tables12.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build go1.14 && !go1.16
 // +build go1.14,!go1.16
 
 package norm
diff --git a/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go b/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
index 9ea1b42..96a130d 100644
--- a/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
+++ b/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build go1.16
 // +build go1.16
 
 package norm
diff --git a/src/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go b/src/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go
index 9429069..0175eae 100644
--- a/src/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go
+++ b/src/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go
@@ -1,5 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
+//go:build !go1.10
 // +build !go1.10
 
 package norm
diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt
index 04bb67e..ff01db5 100644
--- a/src/vendor/modules.txt
+++ b/src/vendor/modules.txt
@@ -1,5 +1,5 @@
-# golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
-## explicit
+# golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e
+## explicit; go 1.17
 golang.org/x/crypto/chacha20
 golang.org/x/crypto/chacha20poly1305
 golang.org/x/crypto/cryptobyte
@@ -8,8 +8,8 @@
 golang.org/x/crypto/hkdf
 golang.org/x/crypto/internal/subtle
 golang.org/x/crypto/poly1305
-# golang.org/x/net v0.0.0-20201209123823-ac852fbbde11
-## explicit
+# golang.org/x/net v0.0.0-20210510120150-4163338589ed
+## explicit; go 1.17
 golang.org/x/net/dns/dnsmessage
 golang.org/x/net/http/httpguts
 golang.org/x/net/http/httpproxy
@@ -18,11 +18,11 @@
 golang.org/x/net/lif
 golang.org/x/net/nettest
 golang.org/x/net/route
-# golang.org/x/sys v0.0.0-20201204225414-ed752295db88
-## explicit
+# golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744
+## explicit; go 1.17
 golang.org/x/sys/cpu
-# golang.org/x/text v0.3.4
-## explicit
+# golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f
+## explicit; go 1.17
 golang.org/x/text/secure/bidirule
 golang.org/x/text/transform
 golang.org/x/text/unicode/bidi
diff --git a/test/abi/bad_internal_offsets.go b/test/abi/bad_internal_offsets.go
new file mode 100644
index 0000000..d396c1a
--- /dev/null
+++ b/test/abi/bad_internal_offsets.go
@@ -0,0 +1,74 @@
+// compile
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package genChecker0
+
+var FailCount int
+
+//go:noinline
+func NoteFailure(fidx int, pkg string, pref string, parmNo int, _ uint64) {
+	FailCount += 1
+	if FailCount > 10 {
+		panic("bad")
+	}
+}
+
+//go:noinline
+func NoteFailureElem(fidx int, pkg string, pref string, parmNo int, elem int, _ uint64) {
+	FailCount += 1
+	if FailCount > 10 {
+		panic("bad")
+	}
+}
+
+type StructF0S0 struct {
+	F0 int16
+	F1 string
+	F2 StructF0S1
+}
+
+type StructF0S1 struct {
+	_ uint16
+}
+
+// 0 returns 3 params
+//go:registerparams
+//go:noinline
+func Test0(p0 uint32, p1 StructF0S0, p2 int32) {
+	// consume some stack space, so as to trigger morestack
+	var pad [256]uint64
+	pad[FailCount]++
+	if p0 == 0 {
+		return
+	}
+	p1f0c := int16(-3096)
+	if p1.F0 != p1f0c {
+		NoteFailureElem(0, "genChecker0", "parm", 1, 0, pad[0])
+		return
+	}
+	p1f1c := "f6ꂅ8ˋ<"
+	if p1.F1 != p1f1c {
+		NoteFailureElem(0, "genChecker0", "parm", 1, 1, pad[0])
+		return
+	}
+	p1f2c := StructF0S1{}
+	if p1.F2 != p1f2c {
+		NoteFailureElem(0, "genChecker0", "parm", 1, 2, pad[0])
+		return
+	}
+	p2f0c := int32(496713155)
+	if p2 != p2f0c {
+		NoteFailureElem(0, "genChecker0", "parm", 2, 0, pad[0])
+		return
+	}
+	// recursive call
+	Test0(p0-1, p1, p2)
+	return
+	// 0 addr-taken params, 0 addr-taken returns
+}
diff --git a/test/abi/bad_select_crash.go b/test/abi/bad_select_crash.go
new file mode 100644
index 0000000..58ca463
--- /dev/null
+++ b/test/abi/bad_select_crash.go
@@ -0,0 +1,272 @@
+// build -goexperiment regabi,regabiargs
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"os"
+	"reflect"
+)
+
+func main() {
+	// Only print if there is a problem
+	Caller2()
+	if FailCount != 0 {
+		fmt.Fprintf(os.Stderr, "FAILURES: %d\n", FailCount)
+		os.Exit(2)
+	}
+}
+
+var ParamFailCount int
+
+var ReturnFailCount int
+
+var FailCount int
+
+var Mode string
+
+type UtilsType int
+
+//go:noinline
+func NoteFailure(cm int, pidx int, fidx int, pkg string, pref string, parmNo int, isret bool, _ uint64) {
+	if isret {
+		if ParamFailCount != 0 {
+			return
+		}
+		ReturnFailCount++
+	} else {
+		ParamFailCount++
+	}
+	fmt.Fprintf(os.Stderr, "Error: fail %s |%d|%d|%d| =%s.Test%d= %s %d\n", Mode, cm, pidx, fidx, pkg, fidx, pref, parmNo)
+
+	if ParamFailCount+FailCount+ReturnFailCount > 9999 {
+		os.Exit(1)
+	}
+}
+
+//go:noinline
+func NoteFailureElem(cm int, pidx int, fidx int, pkg string, pref string, parmNo int, elem int, isret bool, _ uint64) {
+
+	if isret {
+		if ParamFailCount != 0 {
+			return
+		}
+		ReturnFailCount++
+	} else {
+		ParamFailCount++
+	}
+	fmt.Fprintf(os.Stderr, "Error: fail %s |%d|%d|%d| =%s.Test%d= %s %d elem %d\n", Mode, cm, pidx, fidx, pkg, fidx, pref, parmNo, elem)
+
+	if ParamFailCount+FailCount+ReturnFailCount > 9999 {
+		os.Exit(1)
+	}
+}
+
+func BeginFcn() {
+	ParamFailCount = 0
+	ReturnFailCount = 0
+}
+
+func EndFcn() {
+	FailCount += ParamFailCount
+	FailCount += ReturnFailCount
+}
+
+func Caller2() {
+	BeginFcn()
+	c0 := StructF2S0{F0: ArrayF2S1E1{New_3(float64(-0.4418990509835844))}}
+	c1 := ArrayF2S2E1{StructF2S1{ /* _: "񊶿(z̽|" */ F1: "􂊇񊶿"}}
+	c2 := int16(4162)
+	c3 := float32(-7.667096e+37)
+	c4 := int64(3202175648847048679)
+	var p0 ArrayF2S0E0
+	p0 = ArrayF2S0E0{}
+	var p1 uint8
+	p1 = uint8(57)
+	var p2 uint16
+	p2 = uint16(10920)
+	var p3 float64
+	p3 = float64(-1.597256501942112)
+	Mode = ""
+	// 5 returns 4 params
+	r0, r1, r2, r3, r4 := Test2(p0, p1, p2, p3)
+	if !EqualStructF2S0(r0, c0) {
+		NoteFailure(9, 42, 2, "genChecker42", "return", 0, true, uint64(0))
+	}
+	if r1 != c1 {
+		NoteFailure(9, 42, 2, "genChecker42", "return", 1, true, uint64(0))
+	}
+	if r2 != c2 {
+		NoteFailure(9, 42, 2, "genChecker42", "return", 2, true, uint64(0))
+	}
+	if r3 != c3 {
+		NoteFailure(9, 42, 2, "genChecker42", "return", 3, true, uint64(0))
+	}
+	if r4 != c4 {
+		NoteFailure(9, 42, 2, "genChecker42", "return", 4, true, uint64(0))
+	}
+	// same call via reflection
+	Mode = "reflect"
+	rc := reflect.ValueOf(Test2)
+	rvslice := rc.Call([]reflect.Value{reflect.ValueOf(p0), reflect.ValueOf(p1), reflect.ValueOf(p2), reflect.ValueOf(p3)})
+	rr0i := rvslice[0].Interface()
+	rr0v := rr0i.(StructF2S0)
+	if !EqualStructF2S0(rr0v, c0) {
+		NoteFailure(9, 42, 2, "genChecker42", "return", 0, true, uint64(0))
+	}
+	rr1i := rvslice[1].Interface()
+	rr1v := rr1i.(ArrayF2S2E1)
+	if rr1v != c1 {
+		NoteFailure(9, 42, 2, "genChecker42", "return", 1, true, uint64(0))
+	}
+	rr2i := rvslice[2].Interface()
+	rr2v := rr2i.(int16)
+	if rr2v != c2 {
+		NoteFailure(9, 42, 2, "genChecker42", "return", 2, true, uint64(0))
+	}
+	rr3i := rvslice[3].Interface()
+	rr3v := rr3i.(float32)
+	if rr3v != c3 {
+		NoteFailure(9, 42, 2, "genChecker42", "return", 3, true, uint64(0))
+	}
+	rr4i := rvslice[4].Interface()
+	rr4v := rr4i.(int64)
+	if rr4v != c4 {
+		NoteFailure(9, 42, 2, "genChecker42", "return", 4, true, uint64(0))
+	}
+	EndFcn()
+}
+
+type StructF0S0 struct {
+}
+
+type ArrayF0S0E2 [2]int16
+
+type ArrayF0S1E1 [1]StructF0S0
+
+type StructF1S0 struct {
+	F0 StructF1S1
+	_  ArrayF1S0E4
+}
+
+type StructF1S1 struct {
+}
+
+type StructF1S2 struct {
+	F0 uint32
+	F1 uint8
+	F2 string
+	F3 string
+	F4 ArrayF1S1E1
+}
+
+type StructF1S3 struct {
+	F0 float64
+}
+
+type StructF1S4 struct {
+	_  int32
+	F1 float32
+}
+
+type StructF1S5 struct {
+	F0 uint16
+}
+
+type StructF1S6 struct {
+	F0 uint8
+	F1 uint32
+}
+
+type ArrayF1S0E4 [4]float64
+
+type ArrayF1S1E1 [1]StructF1S3
+
+type ArrayF1S2E2 [2]StructF1S4
+
+type ArrayF1S3E2 [2]StructF1S5
+
+type ArrayF1S4E4 [4]ArrayF1S5E3
+
+type ArrayF1S5E3 [3]string
+
+type ArrayF1S6E1 [1]float64
+
+type StructF2S0 struct {
+	F0 ArrayF2S1E1
+}
+
+// equal func for StructF2S0
+//go:noinline
+func EqualStructF2S0(left StructF2S0, right StructF2S0) bool {
+	return EqualArrayF2S1E1(left.F0, right.F0)
+}
+
+type StructF2S1 struct {
+	_  string
+	F1 string
+}
+
+type ArrayF2S0E0 [0]int8
+
+type ArrayF2S1E1 [1]*float64
+
+// equal func for ArrayF2S1E1
+//go:noinline
+func EqualArrayF2S1E1(left ArrayF2S1E1, right ArrayF2S1E1) bool {
+	return *left[0] == *right[0]
+}
+
+type ArrayF2S2E1 [1]StructF2S1
+
+// 5 returns 4 params
+//go:registerparams
+//go:noinline
+func Test2(p0 ArrayF2S0E0, p1 uint8, _ uint16, p3 float64) (r0 StructF2S0, r1 ArrayF2S2E1, r2 int16, r3 float32, r4 int64) {
+	// consume some stack space, so as to trigger morestack
+	var pad [16]uint64
+	pad[FailCount&0x1]++
+	rc0 := StructF2S0{F0: ArrayF2S1E1{New_3(float64(-0.4418990509835844))}}
+	rc1 := ArrayF2S2E1{StructF2S1{ /* _: "񊶿(z̽|" */ F1: "􂊇񊶿"}}
+	rc2 := int16(4162)
+	rc3 := float32(-7.667096e+37)
+	rc4 := int64(3202175648847048679)
+	p1f0c := uint8(57)
+	if p1 != p1f0c {
+		NoteFailureElem(9, 42, 2, "genChecker42", "parm", 1, 0, false, pad[0])
+		return
+	}
+	_ = uint16(10920)
+	p3f0c := float64(-1.597256501942112)
+	if p3 != p3f0c {
+		NoteFailureElem(9, 42, 2, "genChecker42", "parm", 3, 0, false, pad[0])
+		return
+	}
+	defer func(p0 ArrayF2S0E0, p1 uint8) {
+		// check parm passed
+		// check parm passed
+		if p1 != p1f0c {
+			NoteFailureElem(9, 42, 2, "genChecker42", "parm", 1, 0, false, pad[0])
+			return
+		}
+		// check parm captured
+		if p3 != p3f0c {
+			NoteFailureElem(9, 42, 2, "genChecker42", "parm", 3, 0, false, pad[0])
+			return
+		}
+	}(p0, p1)
+
+	return rc0, rc1, rc2, rc3, rc4
+	// 0 addr-taken params, 0 addr-taken returns
+}
+
+//go:noinline
+func New_3(i float64) *float64 {
+	x := new(float64)
+	*x = i
+	return x
+}
diff --git a/test/abi/convF_criteria.go b/test/abi/convF_criteria.go
new file mode 100644
index 0000000..77ed56d
--- /dev/null
+++ b/test/abi/convF_criteria.go
@@ -0,0 +1,27 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+type myStruct struct {
+	F0 [0]struct{}
+	F1 float32
+}
+
+type myStruct2 struct {
+	F0 [0]struct{}
+	F1 float32
+	F2 [0]struct{}
+}
+
+func main() {
+	x := myStruct{F1: -1.25}
+	fmt.Println(x)
+	x2 := myStruct2{F1: -7.97}
+	fmt.Println(x2)
+}
diff --git a/test/abi/convF_criteria.out b/test/abi/convF_criteria.out
new file mode 100644
index 0000000..457f0de
--- /dev/null
+++ b/test/abi/convF_criteria.out
@@ -0,0 +1,2 @@
+{[] -1.25}
+{[] -7.97 []}
diff --git a/test/abi/convT64_criteria.go b/test/abi/convT64_criteria.go
new file mode 100644
index 0000000..165bdfa
--- /dev/null
+++ b/test/abi/convT64_criteria.go
@@ -0,0 +1,25 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+type MyStruct struct {
+	F0 [0]float64
+	F1 byte
+	F2 int16
+	_  struct {
+		F0 uint32
+	}
+}
+
+func main() {
+	p0 := MyStruct{F0: [0]float64{}, F1: byte(27), F2: int16(9887)}
+	fmt.Println(p0)
+}
diff --git a/test/abi/convT64_criteria.out b/test/abi/convT64_criteria.out
new file mode 100644
index 0000000..8ac8571
--- /dev/null
+++ b/test/abi/convT64_criteria.out
@@ -0,0 +1 @@
+{[] 27 9887 {0}}
diff --git a/test/abi/defer_aggregate.go b/test/abi/defer_aggregate.go
new file mode 100644
index 0000000..6dd8282
--- /dev/null
+++ b/test/abi/defer_aggregate.go
@@ -0,0 +1,48 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+const p0exp = "foo"
+const p1exp = 10101
+const p2exp = 3030303
+const p3exp = 505050505
+const p4exp = 70707070707
+
+//go:noinline
+//go:registerparams
+func callee(p0 string, p1 uint64, p2 uint64, p3 uint64, p4 uint64) {
+	if p0 != p0exp {
+		panic("bad p0")
+	}
+	if p1 != p1exp {
+		panic("bad p1")
+	}
+	if p2 != p2exp {
+		panic("bad p2")
+	}
+	if p3 != p3exp {
+		panic("bad p3")
+	}
+	if p4 != p4exp {
+		panic("bad p4")
+	}
+	defer func(p0 string, p2 uint64) {
+		if p0 != p0exp {
+			panic("defer bad p0")
+		}
+		if p1 != p1exp {
+			panic("defer bad p1")
+		}
+		if p2 != p2exp {
+			panic("defer bad p2")
+		}
+	}(p0, p2)
+}
+
+func main() {
+	callee(p0exp, p1exp, p2exp, p3exp, p4exp)
+}
diff --git a/test/abi/defer_recover_results.go b/test/abi/defer_recover_results.go
new file mode 100644
index 0000000..7787f26
--- /dev/null
+++ b/test/abi/defer_recover_results.go
@@ -0,0 +1,36 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that when a function recovers from a panic, it
+// returns the correct results to the caller (in particular,
+// setting the result registers correctly).
+
+package main
+
+type S struct {
+	x uint8
+	y uint16
+	z uint32
+	w float64
+}
+
+var a0, b0, c0, d0 = 10, "hello", S{1, 2, 3, 4}, [2]int{111, 222}
+
+//go:noinline
+//go:registerparams
+func F() (a int, b string, _ int, c S, d [2]int) {
+	a, b, c, d = a0, b0, c0, d0
+	defer func() { recover() }()
+	panic("XXX")
+	return
+}
+
+func main() {
+	a1, b1, zero, c1, d1 := F()
+	if a1 != a0 || b1 != b0 || c1 != c0 || d1 != d0 || zero != 0 { // unnamed result gets zero value
+		panic("FAIL")
+	}
+}
diff --git a/test/abi/double_nested_addressed_struct.go b/test/abi/double_nested_addressed_struct.go
new file mode 100644
index 0000000..be7c88a
--- /dev/null
+++ b/test/abi/double_nested_addressed_struct.go
@@ -0,0 +1,62 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import (
+	"fmt"
+)
+
+var sink *string
+
+type stringPair struct {
+	a, b string
+}
+
+type stringPairPair struct {
+	x, y stringPair
+}
+
+// The goal of this test is to be sure that the call arg/result expander works correctly
+// for a corner case of passing a 2-nested struct that fits in registers to/from calls.
+// AND, the struct has its address taken.
+
+//go:registerparams
+//go:noinline
+func H(spp stringPairPair) string {
+	F(&spp)
+	return spp.x.a + " " + spp.x.b + " " + spp.y.a + " " + spp.y.b
+}
+
+//go:registerparams
+//go:noinline
+func G(d, c, b, a string) stringPairPair {
+	return stringPairPair{stringPair{a, b}, stringPair{c, d}}
+}
+
+//go:registerparams
+//go:noinline
+func F(spp *stringPairPair) {
+	spp.x.a, spp.x.b, spp.y.a, spp.y.b = spp.y.b, spp.y.a, spp.x.b, spp.x.a
+}
+
+func main() {
+	spp := G("this", "is", "a", "test")
+	s := H(spp)
+	gotVsWant(s, "this is a test")
+}
+
+func gotVsWant(got, want string) {
+	if got != want {
+		fmt.Printf("FAIL, got %s, wanted %s\n", got, want)
+	}
+}
diff --git a/test/abi/double_nested_struct.go b/test/abi/double_nested_struct.go
new file mode 100644
index 0000000..814341e
--- /dev/null
+++ b/test/abi/double_nested_struct.go
@@ -0,0 +1,54 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import (
+	"fmt"
+)
+
+var sink *string
+
+type stringPair struct {
+	a, b string
+}
+
+type stringPairPair struct {
+	x, y stringPair
+}
+
+// The goal of this test is to be sure that the call arg/result expander works correctly
+// for a corner case of passing a 2-nested struct that fits in registers to/from calls.
+
+//go:registerparams
+//go:noinline
+func H(spp stringPairPair) string {
+	return spp.x.a + " " + spp.x.b + " " + spp.y.a + " " + spp.y.b
+}
+
+//go:registerparams
+//go:noinline
+func G(a, b, c, d string) stringPairPair {
+	return stringPairPair{stringPair{a, b}, stringPair{c, d}}
+}
+
+func main() {
+	spp := G("this", "is", "a", "test")
+	s := H(spp)
+	gotVsWant(s, "this is a test")
+}
+
+func gotVsWant(got, want string) {
+	if got != want {
+		fmt.Printf("FAIL, got %s, wanted %s\n", got, want)
+	}
+}
diff --git a/test/abi/f_ret_z_not.go b/test/abi/f_ret_z_not.go
new file mode 100644
index 0000000..63d6c79
--- /dev/null
+++ b/test/abi/f_ret_z_not.go
@@ -0,0 +1,39 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import "fmt"
+
+type Z struct {
+}
+
+type NZ struct {
+	x, y int
+}
+
+//go:noinline
+func f(x, y int) (Z, NZ, Z) {
+	var z Z
+	return z, NZ{x, y}, z
+}
+
+//go:noinline
+func g() (Z, NZ, Z) {
+	a, b, c := f(3, 4)
+	return c, b, a
+}
+
+func main() {
+	_, b, _ := g()
+	fmt.Println(b.x + b.y)
+}
diff --git a/test/abi/f_ret_z_not.out b/test/abi/f_ret_z_not.out
new file mode 100644
index 0000000..7f8f011
--- /dev/null
+++ b/test/abi/f_ret_z_not.out
@@ -0,0 +1 @@
+7
diff --git a/test/abi/fibish.go b/test/abi/fibish.go
new file mode 100644
index 0000000..b72f132
--- /dev/null
+++ b/test/abi/fibish.go
@@ -0,0 +1,33 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+// Test that register results are correctly returned (and passed)
+
+//go:registerparams
+//go:noinline
+func f(x int) (int, int) {
+
+	if x < 3 {
+		return 0, x
+	}
+
+	a, b := f(x - 2)
+	c, d := f(x - 1)
+	return a + d, b + c
+}
+
+func main() {
+	x := 40
+	a, b := f(x)
+	fmt.Printf("f(%d)=%d,%d\n", x, a, b)
+}
diff --git a/test/abi/fibish.out b/test/abi/fibish.out
new file mode 100644
index 0000000..9bd80c3
--- /dev/null
+++ b/test/abi/fibish.out
@@ -0,0 +1 @@
+f(40)=39088169,126491972
diff --git a/test/abi/fibish_closure.go b/test/abi/fibish_closure.go
new file mode 100644
index 0000000..988001e
--- /dev/null
+++ b/test/abi/fibish_closure.go
@@ -0,0 +1,34 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+// Test that register results are correctly returned (and passed)
+
+type MagicLastTypeNameForTestingRegisterABI func(int, MagicLastTypeNameForTestingRegisterABI) (int, int)
+
+//go:noinline
+func f(x int, unused MagicLastTypeNameForTestingRegisterABI) (int, int) {
+
+	if x < 3 {
+		return 0, x
+	}
+
+	a, b := f(x-2, unused)
+	c, d := f(x-1, unused)
+	return a + d, b + c
+}
+
+func main() {
+	x := 40
+	a, b := f(x, f)
+	fmt.Printf("f(%d)=%d,%d\n", x, a, b)
+}
diff --git a/test/abi/fibish_closure.out b/test/abi/fibish_closure.out
new file mode 100644
index 0000000..9bd80c3
--- /dev/null
+++ b/test/abi/fibish_closure.out
@@ -0,0 +1 @@
+f(40)=39088169,126491972
diff --git a/test/abi/fuzz_trailing_zero_field.go b/test/abi/fuzz_trailing_zero_field.go
new file mode 100644
index 0000000..ae7ad32
--- /dev/null
+++ b/test/abi/fuzz_trailing_zero_field.go
@@ -0,0 +1,39 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var p0exp = S1{
+	F1: complex(float64(2.3640607624715027), float64(-0.2717825524109192)),
+	F2: S2{F1: 9},
+	F3: 103050709,
+}
+
+type S1 struct {
+	F1 complex128
+	F2 S2
+	F3 uint64
+}
+
+type S2 struct {
+	F1 uint64
+	F2 empty
+}
+
+type empty struct {
+}
+
+//go:noinline
+//go:registerparams
+func callee(p0 S1) {
+	if p0 != p0exp {
+		panic("bad p0")
+	}
+}
+
+func main() {
+	callee(p0exp)
+}
diff --git a/test/abi/idata.go b/test/abi/idata.go
new file mode 100644
index 0000000..af2b87b
--- /dev/null
+++ b/test/abi/idata.go
@@ -0,0 +1,97 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Excerpted from go/constant/value.go to capture a bug from there.
+
+package main
+
+import (
+	"fmt"
+	"math"
+	"math/big"
+)
+
+type (
+	unknownVal struct{}
+	intVal     struct{ val *big.Int }   // Int values not representable as an int64
+	ratVal     struct{ val *big.Rat }   // Float values representable as a fraction
+	floatVal   struct{ val *big.Float } // Float values not representable as a fraction
+	complexVal struct{ re, im Value }
+)
+
+const prec = 512
+
+func (unknownVal) String() string { return "unknown" }
+
+func (x intVal) String() string   { return x.val.String() }
+func (x ratVal) String() string   { return rtof(x).String() }
+
+func (x floatVal) String() string {
+	f := x.val
+
+	// Use exact fmt formatting if in float64 range (common case):
+	// proceed if f doesn't underflow to 0 or overflow to inf.
+	if x, _ := f.Float64(); f.Sign() == 0 == (x == 0) && !math.IsInf(x, 0) {
+		return fmt.Sprintf("%.6g", x)
+	}
+
+	return "OOPS"
+}
+
+func (x complexVal) String() string { return fmt.Sprintf("(%s + %si)", x.re, x.im) }
+
+func newFloat() *big.Float { return new(big.Float).SetPrec(prec) }
+
+//go:noinline
+//go:registerparams
+func itor(x intVal) ratVal       { return ratVal{nil} }
+
+//go:noinline
+//go:registerparams
+func itof(x intVal) floatVal     { return floatVal{nil} }
+func rtof(x ratVal) floatVal     { return floatVal{newFloat().SetRat(x.val)} }
+
+type Value interface {
+	String() string
+}
+
+//go:noinline
+//go:registerparams
+func ToFloat(x Value) Value {
+	switch x := x.(type) {
+	case intVal:
+		if smallInt(x.val) {
+			return itor(x)
+		}
+		return itof(x)
+	case ratVal, floatVal:
+		return x
+	case complexVal:
+		if Sign(x.im) == 0 {
+			return ToFloat(x.re)
+		}
+	}
+	return unknownVal{}
+}
+
+//go:noinline
+//go:registerparams
+func smallInt(x *big.Int) bool {
+	return false
+}
+
+//go:noinline
+//go:registerparams
+func Sign(x Value) int {
+	return 0
+}
+
+
+func main() {
+	v := ratVal{big.NewRat(22,7)}
+	s := ToFloat(v).String()
+	fmt.Printf("s=%s\n", s)
+}
diff --git a/test/abi/idata.out b/test/abi/idata.out
new file mode 100644
index 0000000..98190c2
--- /dev/null
+++ b/test/abi/idata.out
@@ -0,0 +1 @@
+s=3.14286
diff --git a/test/abi/leaf.go b/test/abi/leaf.go
new file mode 100644
index 0000000..f893f5d
--- /dev/null
+++ b/test/abi/leaf.go
@@ -0,0 +1,36 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import "fmt"
+
+type i5f5 struct {
+	a, b          int16
+	c, d, e       int32
+	r, s, t, u, v float32
+}
+
+//go:registerparams
+//go:noinline
+func F(x i5f5) i5f5 {
+	return x
+}
+
+func main() {
+	x := i5f5{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
+	y := x
+	z := F(x)
+	if y != z {
+		fmt.Printf("y=%v, z=%v\n", y, z)
+	}
+}
diff --git a/test/abi/leaf2.go b/test/abi/leaf2.go
new file mode 100644
index 0000000..d2018d5
--- /dev/null
+++ b/test/abi/leaf2.go
@@ -0,0 +1,43 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import "fmt"
+
+type i4 struct {
+	a, b, c, d int
+}
+
+//go:registerparams
+//go:noinline
+func F(x i4) i4 {
+	ab := x.a + x.b
+	bc := x.b + x.c
+	cd := x.c + x.d
+	ad := x.a + x.d
+	ba := x.a - x.b
+	cb := x.b - x.c
+	dc := x.c - x.d
+	da := x.a - x.d
+
+	return i4{ab*bc + da, cd*ad + cb, ba*cb + ad, dc*da + bc}
+}
+
+func main() {
+	x := i4{1, 2, 3, 4}
+	y := x
+	z := F(x)
+	if (i4{12, 34, 6, 8}) != z {
+		fmt.Printf("y=%v, z=%v\n", y, z)
+	}
+}
diff --git a/test/abi/many_int_input.go b/test/abi/many_int_input.go
new file mode 100644
index 0000000..8fda937
--- /dev/null
+++ b/test/abi/many_int_input.go
@@ -0,0 +1,33 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import (
+	"fmt"
+)
+
+//go:registerparams
+//go:noinline
+func F(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z int64) {
+	G(z, y, x, w, v, u, t, s, r, q, p, o, n, m, l, k, j, i, h, g, f, e, d, c, b, a)
+}
+
+//go:registerparams
+//go:noinline
+func G(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z int64) {
+	fmt.Println(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)
+}
+
+func main() {
+	F(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)
+}
diff --git a/test/abi/many_int_input.out b/test/abi/many_int_input.out
new file mode 100644
index 0000000..fecfa82
--- /dev/null
+++ b/test/abi/many_int_input.out
@@ -0,0 +1 @@
+26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
diff --git a/test/abi/many_intstar_input.go b/test/abi/many_intstar_input.go
new file mode 100644
index 0000000..b209c80
--- /dev/null
+++ b/test/abi/many_intstar_input.go
@@ -0,0 +1,45 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import (
+	"fmt"
+)
+
+var sink int = 3
+
+//go:registerparams
+//go:noinline
+func F(a, b, c, d, e, f *int) {
+	G(f, e, d, c, b, a)
+	sink += *a // *a == 6 after swapping in G
+}
+
+//go:registerparams
+//go:noinline
+func G(a, b, c, d, e, f *int) {
+	var scratch [1000 * 100]int
+	scratch[*a] = *f                    // scratch[6] = 1
+	fmt.Println(*a, *b, *c, *d, *e, *f) // Forces it to spill b
+	sink = scratch[*b+1]                // scratch[5+1] == 1
+	*f, *a = *a, *f
+	*e, *b = *b, *e
+	*d, *c = *c, *d
+}
+
+func main() {
+	a, b, c, d, e, f := 1, 2, 3, 4, 5, 6
+	F(&a, &b, &c, &d, &e, &f)
+	fmt.Println(a, b, c, d, e, f)
+	fmt.Println(sink)
+}
diff --git a/test/abi/many_intstar_input.out b/test/abi/many_intstar_input.out
new file mode 100644
index 0000000..0a37ccb
--- /dev/null
+++ b/test/abi/many_intstar_input.out
@@ -0,0 +1,3 @@
+6 5 4 3 2 1
+6 5 4 3 2 1
+7
diff --git a/test/abi/map.go b/test/abi/map.go
new file mode 100644
index 0000000..236655a
--- /dev/null
+++ b/test/abi/map.go
@@ -0,0 +1,34 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "runtime"
+
+type T [10]int
+
+var m map[*T]int
+
+//go:noinline
+func F() {
+	m = map[*T]int{
+		K(): V(), // the key temp should be live across call to V
+	}
+}
+
+//go:noinline
+func V() int { runtime.GC(); runtime.GC(); runtime.GC(); return 123 }
+
+//go:noinline
+func K() *T {
+	p := new(T)
+	runtime.SetFinalizer(p, func(*T) { println("FAIL") })
+	return p
+}
+
+func main() {
+	F()
+}
diff --git a/test/abi/more_intstar_input.go b/test/abi/more_intstar_input.go
new file mode 100644
index 0000000..f0a48fb
--- /dev/null
+++ b/test/abi/more_intstar_input.go
@@ -0,0 +1,44 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import (
+	"fmt"
+)
+
+var sink int
+
+//go:registerparams
+//go:noinline
+func F(a, b, c, d, e, f, g, h, i, j, k, l, m *int) {
+	G(m, l, k, j, i, h, g, f, e, d, c, b, a)
+	// did the pointers get properly updated?
+	sink = *a + *m
+}
+
+//go:registerparams
+//go:noinline
+func G(a, b, c, d, e, f, g, h, i, j, k, l, m *int) {
+	// Do not reference the parameters
+	var scratch [1000 * 100]int
+	I := *c - *e - *l // zero.
+	scratch[I] = *d
+	fmt.Println("Got this far!")
+	sink += scratch[0]
+}
+
+func main() {
+	a, b, c, d, e, f, g, h, i, j, k, l, m := 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
+	F(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m)
+	fmt.Printf("Sink = %d\n", sink-7)
+}
diff --git a/test/abi/more_intstar_input.out b/test/abi/more_intstar_input.out
new file mode 100644
index 0000000..2ab84bf
--- /dev/null
+++ b/test/abi/more_intstar_input.out
@@ -0,0 +1,2 @@
+Got this far!
+Sink = 7
diff --git a/test/abi/named_results.go b/test/abi/named_results.go
new file mode 100644
index 0000000..eaaadb1
--- /dev/null
+++ b/test/abi/named_results.go
@@ -0,0 +1,91 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+var sink *string
+
+var y int
+
+//go:registerparams
+//go:noinline
+func F(a, b, c *int) (x int) {
+	x = *a
+	G(&x)
+	x += *b
+	G(&x)
+	x += *c
+	G(&x)
+	return
+}
+
+//go:registerparams
+//go:noinline
+func G(x *int) {
+	y += *x
+	fmt.Println("y = ", y)
+}
+
+//go:registerparams
+//go:noinline
+func X() {
+	*sink += " !!!!!!!!!!!!!!!"
+}
+
+//go:registerparams
+//go:noinline
+func H(s, t string) (result string) { // result leaks to heap
+	result = "Aloha! " + s + " " + t
+	sink = &result
+	r := ""
+	if len(s) <= len(t) {
+		r = "OKAY! "
+		X()
+	}
+	return r + result
+}
+
+//go:registerparams
+//go:noinline
+func K(s, t string) (result string) { // result spills
+	result = "Aloha! " + s + " " + t
+	r := ""
+	if len(s) <= len(t) {
+		r = "OKAY! "
+		X()
+	}
+	return r + result
+}
+
+func main() {
+	a, b, c := 1, 4, 16
+	x := F(&a, &b, &c)
+	fmt.Printf("x = %d\n", x)
+
+	y := H("Hello", "World!")
+	fmt.Println("len(y) =", len(y))
+	fmt.Println("y =", y)
+	z := H("Hello", "Pal!")
+	fmt.Println("len(z) =", len(z))
+	fmt.Println("z =", z)
+
+	fmt.Println()
+
+	y = K("Hello", "World!")
+	fmt.Println("len(y) =", len(y))
+	fmt.Println("y =", y)
+	z = K("Hello", "Pal!")
+	fmt.Println("len(z) =", len(z))
+	fmt.Println("z =", z)
+
+}
diff --git a/test/abi/named_results.out b/test/abi/named_results.out
new file mode 100644
index 0000000..02f12e8
--- /dev/null
+++ b/test/abi/named_results.out
@@ -0,0 +1,13 @@
+y =  1
+y =  6
+y =  27
+x = 21
+len(y) = 41
+y = OKAY! Aloha! Hello World! !!!!!!!!!!!!!!!
+len(z) = 17
+z = Aloha! Hello Pal!
+
+len(y) = 25
+y = OKAY! Aloha! Hello World!
+len(z) = 17
+z = Aloha! Hello Pal!
diff --git a/test/abi/named_return_stuff.go b/test/abi/named_return_stuff.go
new file mode 100644
index 0000000..faa0221
--- /dev/null
+++ b/test/abi/named_return_stuff.go
@@ -0,0 +1,94 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import (
+	"fmt"
+)
+
+var sink *string
+
+var y int
+
+//go:registerparams
+//go:noinline
+func F(a, b, c *int) (x int) {
+	x = *a
+	G(&x)
+	x += *b
+	G(&x)
+	x += *c
+	G(&x)
+	return
+}
+
+//go:registerparams
+//go:noinline
+func G(x *int) {
+	y += *x
+	fmt.Println("y = ", y)
+}
+
+//go:registerparams
+//go:noinline
+func X() {
+	*sink += " !!!!!!!!!!!!!!!"
+}
+
+//go:registerparams
+//go:noinline
+func H(s, t string) (result string) { // result leaks to heap
+	result = "Aloha! " + s + " " + t
+	sink = &result
+	r := ""
+	if len(s) <= len(t) {
+		r = "OKAY! "
+		X()
+	}
+	return r + result
+}
+
+//go:registerparams
+//go:noinline
+func K(s, t string) (result string) { // result spills
+	result = "Aloha! " + s + " " + t
+	r := ""
+	if len(s) <= len(t) {
+		r = "OKAY! "
+		X()
+	}
+	return r + result
+}
+
+func main() {
+	a, b, c := 1, 4, 16
+	x := F(&a, &b, &c)
+	fmt.Printf("x = %d\n", x)
+
+	y := H("Hello", "World!")
+	fmt.Println("len(y) =", len(y))
+	fmt.Println("y =", y)
+	z := H("Hello", "Pal!")
+	fmt.Println("len(z) =", len(z))
+	fmt.Println("z =", z)
+
+	fmt.Println()
+
+	y = K("Hello", "World!")
+	fmt.Println("len(y) =", len(y))
+	fmt.Println("y =", y)
+	z = K("Hello", "Pal!")
+	fmt.Println("len(z) =", len(z))
+	fmt.Println("z =", z)
+
+}
diff --git a/test/abi/named_return_stuff.out b/test/abi/named_return_stuff.out
new file mode 100644
index 0000000..02f12e8
--- /dev/null
+++ b/test/abi/named_return_stuff.out
@@ -0,0 +1,13 @@
+y =  1
+y =  6
+y =  27
+x = 21
+len(y) = 41
+y = OKAY! Aloha! Hello World! !!!!!!!!!!!!!!!
+len(z) = 17
+z = Aloha! Hello Pal!
+
+len(y) = 25
+y = OKAY! Aloha! Hello World!
+len(z) = 17
+z = Aloha! Hello Pal!
diff --git a/test/abi/open_defer_1.go b/test/abi/open_defer_1.go
new file mode 100644
index 0000000..0a0ace3
--- /dev/null
+++ b/test/abi/open_defer_1.go
@@ -0,0 +1,36 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// For #45062, miscompilation of open defer of method invocation
+
+package main
+
+func main() {
+	var x, y, z int = -1, -2, -3
+	F(x, y, z)
+}
+
+//go:noinline
+func F(x, y, z int) {
+	defer i.M(x, y, z)
+	defer func() { recover() }()
+	panic("XXX")
+}
+
+type T int
+
+func (t *T) M(x, y, z int) {
+	if x == -1 && y == -2 && z == -3 {
+		return
+	}
+	println("FAIL: Expected -1, -2, -3, but x, y, z =", x, y, z)
+}
+
+var t T = 42
+
+type I interface{ M(x, y, z int) }
+
+var i I = &t
diff --git a/test/abi/part_live.go b/test/abi/part_live.go
new file mode 100644
index 0000000..592b6b3
--- /dev/null
+++ b/test/abi/part_live.go
@@ -0,0 +1,48 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// A test for partial liveness / partial spilling / compiler-induced GC failure
+
+package main
+
+import "runtime"
+import "unsafe"
+
+//go:registerparams
+func F(s []int) {
+	for i, x := range s {
+		G(i, x)
+	}
+	GC()
+	G(len(s), cap(s))
+	GC()
+}
+
+//go:noinline
+//go:registerparams
+func G(int, int) {}
+
+//go:registerparams
+func GC() { runtime.GC(); runtime.GC() }
+
+func main() {
+	s := make([]int, 3)
+	escape(s)
+	p := int(uintptr(unsafe.Pointer(&s[2])) + 42) // likely point to unallocated memory
+	poison([3]int{p, p, p})
+	F(s)
+}
+
+//go:noinline
+//go:registerparams
+func poison([3]int) {}
+
+//go:noinline
+//go:registerparams
+func escape(s []int) {
+	g = s
+}
+var g []int
diff --git a/test/abi/part_live_2.go b/test/abi/part_live_2.go
new file mode 100644
index 0000000..f9d7b01
--- /dev/null
+++ b/test/abi/part_live_2.go
@@ -0,0 +1,53 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// A test for partial liveness / partial spilling / compiler-induced GC failure
+
+package main
+
+import "runtime"
+import "unsafe"
+
+//go:registerparams
+func F(s []int) {
+	for i, x := range s {
+		G(i, x)
+	}
+	GC()
+	H(&s[0]) // It's possible that this will make the spill redundant, but there's a bug in spill slot allocation.
+	G(len(s), cap(s))
+	GC()
+}
+
+//go:noinline
+//go:registerparams
+func G(int, int) {}
+
+//go:noinline
+//go:registerparams
+func H(*int) {}
+
+//go:registerparams
+func GC() { runtime.GC(); runtime.GC() }
+
+func main() {
+	s := make([]int, 3)
+	escape(s)
+	p := int(uintptr(unsafe.Pointer(&s[2])) + 42) // likely point to unallocated memory
+	poison([3]int{p, p, p})
+	F(s)
+}
+
+//go:noinline
+//go:registerparams
+func poison([3]int) {}
+
+//go:noinline
+//go:registerparams
+func escape(s []int) {
+	g = s
+}
+var g []int
diff --git a/test/abi/result_live.go b/test/abi/result_live.go
new file mode 100644
index 0000000..2be54e3
--- /dev/null
+++ b/test/abi/result_live.go
@@ -0,0 +1,20 @@
+// errorcheck -0 -live
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T struct { a, b, c, d string } // pass in registers, not SSA-able
+
+//go:registerparams
+func F() (r T) {
+	r.a = g(1) // ERROR "live at call to g: r"
+	r.b = g(2) // ERROR "live at call to g: r"
+	r.c = g(3) // ERROR "live at call to g: r"
+	r.d = g(4) // ERROR "live at call to g: r"
+	return
+}
+
+func g(int) string
diff --git a/test/abi/result_regalloc.go b/test/abi/result_regalloc.go
new file mode 100644
index 0000000..58aecad
--- /dev/null
+++ b/test/abi/result_regalloc.go
@@ -0,0 +1,46 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Bug: in (*bb).d, the value to be returned was not allocated to
+// a register that satisfies its register mask.
+
+package main
+
+type bb struct {
+	r float64
+	x []float64
+}
+
+//go:noinline
+func B(r float64, x []float64) I {
+	return bb{r, x}
+}
+
+func (b bb) d() (int, int) {
+	if b.r == 0 {
+		return 0, len(b.x)
+	}
+	return len(b.x), len(b.x)
+}
+
+type I interface { d() (int, int) }
+
+func D(r I) (int, int) { return r.d() }
+
+//go:noinline
+func F() (int, int) {
+	r := float64(1)
+	x := []float64{0, 1, 2}
+	b := B(r, x)
+	return D(b)
+}
+
+func main() {
+	x, y := F()
+	if x != 3 || y != 3 {
+		panic("FAIL")
+	}
+}
diff --git a/test/abi/return_stuff.go b/test/abi/return_stuff.go
new file mode 100644
index 0000000..130d8be
--- /dev/null
+++ b/test/abi/return_stuff.go
@@ -0,0 +1,38 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import (
+	"fmt"
+)
+
+//go:registerparams
+//go:noinline
+func F(a, b, c *int) int {
+	return *a + *b + *c
+}
+
+//go:registerparams
+//go:noinline
+func H(s, t string) string {
+	return s + " " + t
+}
+
+func main() {
+	a, b, c := 1, 4, 16
+	x := F(&a, &b, &c)
+	fmt.Printf("x = %d\n", x)
+	y := H("Hello", "World!")
+	fmt.Println("len(y) =", len(y))
+	fmt.Println("y =", y)
+}
diff --git a/test/abi/return_stuff.out b/test/abi/return_stuff.out
new file mode 100644
index 0000000..5f519d7
--- /dev/null
+++ b/test/abi/return_stuff.out
@@ -0,0 +1,3 @@
+x = 21
+len(y) = 12
+y = Hello World!
diff --git a/test/abi/s_sif_sif.go b/test/abi/s_sif_sif.go
new file mode 100644
index 0000000..f05f26f
--- /dev/null
+++ b/test/abi/s_sif_sif.go
@@ -0,0 +1,37 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// Test ensures that abi information producer and consumer agree about the
+// order of registers for inputs.  T's registers should be I0, F0, I1, F1.
+
+import "fmt"
+
+type P struct {
+	a int8
+	x float64
+}
+
+type T struct {
+	d, e P
+}
+
+//go:registerparams
+//go:noinline
+func G(t T) float64 {
+	return float64(t.d.a+t.e.a) + t.d.x + t.e.x
+}
+
+func main() {
+	x := G(T{P{10, 20}, P{30, 40}})
+	if x != 100.0 {
+		fmt.Printf("FAIL, Expected 100, got %f\n", x)
+	}
+}
diff --git a/test/abi/spills3.go b/test/abi/spills3.go
new file mode 100644
index 0000000..2478284
--- /dev/null
+++ b/test/abi/spills3.go
@@ -0,0 +1,48 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import "fmt"
+
+type i4 struct {
+	a, b, c, d int
+}
+
+//go:noinline
+func spills(px *i4) {
+}
+
+//go:registerparams
+//go:noinline
+func F(x i4) i4 {
+	ab := x.a + x.b
+	bc := x.b + x.c
+	cd := x.c + x.d
+	ad := x.a + x.d
+	ba := x.a - x.b
+	cb := x.b - x.c
+	dc := x.c - x.d
+	da := x.a - x.d
+	i := i4{ab*bc + da, cd*ad + cb, ba*cb + ad, dc*da + bc}
+	spills(&i)
+	return i
+}
+
+func main() {
+	x := i4{1, 2, 3, 4}
+	y := x
+	z := F(x)
+	if z != (i4{12, 34, 6, 8}) {
+		fmt.Printf("y=%v, z=%v\n", y, z)
+	}
+}
diff --git a/test/abi/spills4.go b/test/abi/spills4.go
new file mode 100644
index 0000000..205f5a6
--- /dev/null
+++ b/test/abi/spills4.go
@@ -0,0 +1,44 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import "fmt"
+
+type i5f5 struct {
+	a, b          int16
+	c, d, e       int32
+	r, s, t, u, v float32
+}
+
+//go:noinline
+func spills(_ *float32) {
+
+}
+
+//go:registerparams
+//go:noinline
+func F(x i5f5) i5f5 {
+	y := x.v
+	spills(&y)
+	x.r = y
+	return x
+}
+
+func main() {
+	x := i5f5{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
+	y := x
+	z := F(x)
+	if (i5f5{1, 2, 3, 4, 5, 10, 7, 8, 9, 10}) != z {
+		fmt.Printf("y=%v, z=%v\n", y, z)
+	}
+}
diff --git a/test/abi/store_reg_args.go b/test/abi/store_reg_args.go
new file mode 100644
index 0000000..df5e4e1
--- /dev/null
+++ b/test/abi/store_reg_args.go
@@ -0,0 +1,29 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// When the function Store an Arg and also use it in another place,
+// be sure not to generate duplicated OpArgXXXReg values, which confuses
+// the register allocator.
+
+package main
+
+//go:noinline
+//go:registerparams
+func F(x, y float32) {
+	if x < 0 {
+		panic("FAIL")
+	}
+	g = [4]float32{x, y, x, y}
+}
+
+var g [4]float32
+
+func main() {
+	F(1, 2)
+	if g[0] != 1 || g[1] != 2 || g[2] != 1 || g[3] != 2 {
+		panic("FAIL")
+	}
+}
diff --git a/test/abi/struct_3_string_input.go b/test/abi/struct_3_string_input.go
new file mode 100644
index 0000000..54a8b38
--- /dev/null
+++ b/test/abi/struct_3_string_input.go
@@ -0,0 +1,40 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import (
+	"fmt"
+)
+
+var sink *string
+
+type toobig struct {
+	a, b, c string
+}
+
+//go:registerparams
+//go:noinline
+func H(x toobig) string {
+	return x.a + " " + x.b + " " + x.c
+}
+
+func main() {
+	s := H(toobig{"Hello", "there,", "World"})
+	gotVsWant(s, "Hello there, World")
+}
+
+func gotVsWant(got, want string) {
+	if got != want {
+		fmt.Printf("FAIL, got %s, wanted %s\n", got, want)
+	}
+}
diff --git a/test/abi/struct_3_string_input.out b/test/abi/struct_3_string_input.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/abi/struct_3_string_input.out
diff --git a/test/abi/struct_lower_1.go b/test/abi/struct_lower_1.go
new file mode 100644
index 0000000..b20de9b
--- /dev/null
+++ b/test/abi/struct_lower_1.go
@@ -0,0 +1,30 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+//go:registerparams
+//go:noinline
+func passStruct6(a Struct6) Struct6 {
+	return a
+}
+
+type Struct6 struct {
+	Struct1
+}
+
+type Struct1 struct {
+	A, B, C uint
+}
+
+func main() {
+	fmt.Println(passStruct6(Struct6{Struct1{1, 2, 3}}))
+}
diff --git a/test/abi/struct_lower_1.out b/test/abi/struct_lower_1.out
new file mode 100644
index 0000000..d326cb6
--- /dev/null
+++ b/test/abi/struct_lower_1.out
@@ -0,0 +1 @@
+{{1 2 3}}
diff --git a/test/abi/too_big_to_ssa.go b/test/abi/too_big_to_ssa.go
new file mode 100644
index 0000000..6c55d31
--- /dev/null
+++ b/test/abi/too_big_to_ssa.go
@@ -0,0 +1,48 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+var sink *string
+
+type toobig struct {
+	// 6 words will not SSA but will fit in registers
+	a, b, c string
+}
+
+//go:registerparams
+//go:noinline
+func H(x toobig) string {
+	return x.a + " " + x.b + " " + x.c
+}
+
+//go:registerparams
+//go:noinline
+func I(a, b, c string) toobig {
+	return toobig{a, b, c}
+}
+
+func main() {
+	s := H(toobig{"Hello", "there,", "World"})
+	gotVsWant(s, "Hello there, World")
+	fmt.Println(s)
+	t := H(I("Ahoy", "there,", "Matey"))
+	gotVsWant(t, "Ahoy there, Matey")
+	fmt.Println(t)
+}
+
+func gotVsWant(got, want string) {
+	if got != want {
+		fmt.Printf("FAIL, got %s, wanted %s\n", got, want)
+	}
+}
diff --git a/test/abi/too_big_to_ssa.out b/test/abi/too_big_to_ssa.out
new file mode 100644
index 0000000..eeece34
--- /dev/null
+++ b/test/abi/too_big_to_ssa.out
@@ -0,0 +1,2 @@
+Hello there, World
+Ahoy there, Matey
diff --git a/test/abi/uglyfib.go b/test/abi/uglyfib.go
new file mode 100644
index 0000000..b8e8739
--- /dev/null
+++ b/test/abi/uglyfib.go
@@ -0,0 +1,82 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// wasm is excluded because the compiler chatter about register abi pragma ends up
+// on stdout, and causes the expected output to not match.
+
+package main
+
+import "fmt"
+
+// This test is designed to provoke a stack growth
+// in a way that very likely leaves junk in the
+// parameter save area if they aren't saved or spilled
+// there, as appropriate.
+
+//go:registerparams
+//go:noinline
+func f(x int, xm1, xm2, p *int) {
+	var y = [2]int{x - 4, 0}
+	if x < 2 {
+		*p += x
+		return
+	}
+	x -= 3
+	g(*xm1, xm2, &x, p)   // xm1 is no longer live.
+	h(*xm2, &x, &y[0], p) // xm2 is no longer live, but was spilled.
+}
+
+//go:registerparams
+//go:noinline
+func g(x int, xm1, xm2, p *int) {
+	var y = [3]int{x - 4, 0, 0}
+	if x < 2 {
+		*p += x
+		return
+	}
+	x -= 3
+	k(*xm2, &x, &y[0], p)
+	h(*xm1, xm2, &x, p)
+}
+
+//go:registerparams
+//go:noinline
+func h(x int, xm1, xm2, p *int) {
+	var y = [4]int{x - 4, 0, 0, 0}
+	if x < 2 {
+		*p += x
+		return
+	}
+	x -= 3
+	k(*xm1, xm2, &x, p)
+	f(*xm2, &x, &y[0], p)
+}
+
+//go:registerparams
+//go:noinline
+func k(x int, xm1, xm2, p *int) {
+	var y = [5]int{x - 4, 0, 0, 0, 0}
+	if x < 2 {
+		*p += x
+		return
+	}
+	x -= 3
+	f(*xm2, &x, &y[0], p)
+	g(*xm1, xm2, &x, p)
+}
+
+func main() {
+	x := 40
+	var y int
+	xm1 := x - 1
+	xm2 := x - 2
+	f(x, &xm1, &xm2, &y)
+
+	fmt.Printf("Fib(%d)=%d\n", x, y)
+}
diff --git a/test/abi/uglyfib.out b/test/abi/uglyfib.out
new file mode 100644
index 0000000..d892270
--- /dev/null
+++ b/test/abi/uglyfib.out
@@ -0,0 +1 @@
+Fib(40)=102334155
diff --git a/test/abi/wrapdefer_largetmp.go b/test/abi/wrapdefer_largetmp.go
new file mode 100644
index 0000000..fb6eeba
--- /dev/null
+++ b/test/abi/wrapdefer_largetmp.go
@@ -0,0 +1,37 @@
+// run
+
+//go:build !wasm
+// +build !wasm
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+//go:noinline
+func F() {
+	b := g()
+	defer g2(b)
+	n := g()[20]
+	println(n)
+}
+
+type T [45]int
+
+var x = 0
+
+//go:noinline
+func g() T {
+	x++
+	return T{20: x}
+}
+
+//go:noinline
+func g2(t T) {
+	if t[20] != 1 {
+		println("FAIL", t[20])
+	}
+}
+
+func main() { F() }
diff --git a/test/abi/wrapdefer_largetmp.out b/test/abi/wrapdefer_largetmp.out
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/test/abi/wrapdefer_largetmp.out
@@ -0,0 +1 @@
+2
diff --git a/test/abi/zombie_struct_select.go b/test/abi/zombie_struct_select.go
new file mode 100644
index 0000000..d0cab98
--- /dev/null
+++ b/test/abi/zombie_struct_select.go
@@ -0,0 +1,36 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type patchlist struct {
+	head, tail uint32
+}
+
+type frag struct {
+	i   uint32
+	out patchlist
+}
+
+//go:noinline
+//go:registerparams
+func patch(l patchlist, i uint32) {
+}
+
+//go:noinline
+//go:registerparams
+func badbad(f1, f2 frag) frag {
+	// concat of failure is failure
+	if f1.i == 0 || f2.i == 0 { // internal compiler error: 'badbad': incompatible OpArgIntReg [4]: v42 and v26
+		return frag{}
+	}
+	patch(f1.out, f2.i)
+	return frag{f1.i, f2.out}
+}
+
+func main() {
+	badbad(frag{i: 2}, frag{i: 3})
+}
diff --git a/test/alias2.go b/test/alias2.go
index 1c141ac..d7b5dcc 100644
--- a/test/alias2.go
+++ b/test/alias2.go
@@ -36,7 +36,7 @@
 
 // Methods can be declared on the original named type and the alias.
 func (T0) m1()  {} // GCCGO_ERROR "previous"
-func (*T0) m1() {} // ERROR "method redeclared: T0\.m1|redefinition of .m1."
+func (*T0) m1() {} // ERROR "method redeclared: T0\.m1|T0\.m1 redeclared in this block|redefinition of .m1."
 func (A0) m1()  {} // ERROR "T0\.m1 redeclared in this block|redefinition of .m1."
 func (A0) m1()  {} // ERROR "T0\.m1 redeclared in this block|redefinition of .m1."
 func (A0) m2()  {}
@@ -90,7 +90,7 @@
 
 // Invalid type alias declarations.
 
-type _ = reflect.ValueOf // ERROR "reflect.ValueOf is not a type|expected type"
+type _ = reflect.ValueOf // ERROR "reflect.ValueOf .*is not a type|expected type"
 
 func (A1) m() {} // ERROR "cannot define new methods on non-local type int|may not define methods on non-local type"
 func (A2) m() {} // ERROR "invalid receiver type"
diff --git a/test/append1.go b/test/append1.go
index 0fe24c0..9dab120 100644
--- a/test/append1.go
+++ b/test/append1.go
@@ -13,10 +13,10 @@
 
 	s := make([]int, 8)
 
-	_ = append()           // ERROR "missing arguments to append"
-	_ = append(s...)       // ERROR "cannot use ... on first argument"
-	_ = append(s, 2, s...) // ERROR "too many arguments to append"
+	_ = append()           // ERROR "missing arguments to append|not enough arguments for append"
+	_ = append(s...)       // ERROR "cannot use ... on first argument|not enough arguments in call to append"
+	_ = append(s, 2, s...) // ERROR "too many arguments to append|too many arguments in call to append"
 
-	_ = append(s, make([]int, 0))     // ERROR "cannot use make.* as type int in append"
-	_ = append(s, make([]int, -1)...) // ERROR "negative len argument in make"
+	_ = append(s, make([]int, 0))     // ERROR "cannot use make.* as type int in append|cannot use make.* as int value"
+	_ = append(s, make([]int, -1)...) // ERROR "negative len argument in make|index -1.* must not be negative"
 }
diff --git a/test/assign.go b/test/assign.go
index 62fd3b5..bdec58b 100644
--- a/test/assign.go
+++ b/test/assign.go
@@ -56,13 +56,13 @@
 	{
 		var x = 1
 		{
-			x, x := 2, 3 // ERROR ".*x.* repeated on left side of :="
+			x, x := 2, 3 // ERROR ".*x.* repeated on left side of :=|x redeclared in this block"
 			_ = x
 		}
 		_ = x
 	}
 	{
-		a, a := 1, 2 // ERROR ".*a.* repeated on left side of :="
+		a, a := 1, 2 // ERROR ".*a.* repeated on left side of :=|a redeclared in this block"
 		_ = a
 	}
 }
diff --git a/test/bench/go1/gob_test.go b/test/bench/go1/gob_test.go
index 224beff..f289fcc 100644
--- a/test/bench/go1/gob_test.go
+++ b/test/bench/go1/gob_test.go
@@ -10,7 +10,7 @@
 	"bytes"
 	"encoding/gob"
 	"encoding/json"
-	"io/ioutil"
+	"io"
 	"log"
 	"reflect"
 	"testing"
@@ -73,7 +73,7 @@
 }
 
 func gobenc() {
-	if err := gob.NewEncoder(ioutil.Discard).Encode(&gobdata); err != nil {
+	if err := gob.NewEncoder(io.Discard).Encode(&gobdata); err != nil {
 		panic(err)
 	}
 }
diff --git a/test/bench/go1/gzip_test.go b/test/bench/go1/gzip_test.go
index 648eec5..d3f98da 100644
--- a/test/bench/go1/gzip_test.go
+++ b/test/bench/go1/gzip_test.go
@@ -10,7 +10,6 @@
 	"bytes"
 	gz "compress/gzip"
 	"io"
-	"io/ioutil"
 	"testing"
 )
 
@@ -28,7 +27,7 @@
 }
 
 func gzip() {
-	c := gz.NewWriter(ioutil.Discard)
+	c := gz.NewWriter(io.Discard)
 	if _, err := c.Write(jsongunz); err != nil {
 		panic(err)
 	}
@@ -42,7 +41,7 @@
 	if err != nil {
 		panic(err)
 	}
-	if _, err := io.Copy(ioutil.Discard, r); err != nil {
+	if _, err := io.Copy(io.Discard, r); err != nil {
 		panic(err)
 	}
 	r.Close()
diff --git a/test/bench/go1/http_test.go b/test/bench/go1/http_test.go
index 7ece9b2..08583d6 100644
--- a/test/bench/go1/http_test.go
+++ b/test/bench/go1/http_test.go
@@ -6,7 +6,7 @@
 
 import (
 	"bytes"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"net/http/httptest"
 	"testing"
@@ -34,7 +34,7 @@
 		if err != nil {
 			b.Fatal("Get:", err)
 		}
-		all, err := ioutil.ReadAll(res.Body)
+		all, err := io.ReadAll(res.Body)
 		if err != nil {
 			b.Fatal("ReadAll:", err)
 		}
diff --git a/test/bench/go1/json_test.go b/test/bench/go1/json_test.go
index 5ff1f8b..782ef76 100644
--- a/test/bench/go1/json_test.go
+++ b/test/bench/go1/json_test.go
@@ -12,7 +12,6 @@
 	"encoding/base64"
 	"encoding/json"
 	"io"
-	"io/ioutil"
 	"testing"
 )
 
@@ -26,7 +25,7 @@
 	r = bytes.NewReader(bytes.Replace(jsonbz2_base64, []byte{'\n'}, nil, -1))
 	r = base64.NewDecoder(base64.StdEncoding, r)
 	r = bzip2.NewReader(r)
-	b, err := ioutil.ReadAll(r)
+	b, err := io.ReadAll(r)
 	if err != nil {
 		panic(err)
 	}
diff --git a/test/bench/go1/parser_test.go b/test/bench/go1/parser_test.go
index 7848cad..8b7baa3 100644
--- a/test/bench/go1/parser_test.go
+++ b/test/bench/go1/parser_test.go
@@ -12,7 +12,6 @@
 	"go/parser"
 	"go/token"
 	"io"
-	"io/ioutil"
 	"strings"
 	"testing"
 )
@@ -26,7 +25,7 @@
 	r = strings.NewReader(parserbz2_base64)
 	r = base64.NewDecoder(base64.StdEncoding, r)
 	r = bzip2.NewReader(r)
-	b, err := ioutil.ReadAll(r)
+	b, err := io.ReadAll(r)
 	if err != nil {
 		panic(err)
 	}
diff --git a/test/bench/go1/regexp_test.go b/test/bench/go1/regexp_test.go
index 3ce9f3a..dd1034f 100644
--- a/test/bench/go1/regexp_test.go
+++ b/test/bench/go1/regexp_test.go
@@ -53,7 +53,7 @@
 func BenchmarkRegexpMatchEasy0_1K(b *testing.B)  { benchmark(b, easy0, 1<<10) }
 func BenchmarkRegexpMatchEasy1_32(b *testing.B)  { benchmark(b, easy1, 32<<0) }
 func BenchmarkRegexpMatchEasy1_1K(b *testing.B)  { benchmark(b, easy1, 1<<10) }
-func BenchmarkRegexpMatchMedium_32(b *testing.B) { benchmark(b, medium, 1<<0) }
+func BenchmarkRegexpMatchMedium_32(b *testing.B) { benchmark(b, medium, 32<<0) }
 func BenchmarkRegexpMatchMedium_1K(b *testing.B) { benchmark(b, medium, 1<<10) }
 func BenchmarkRegexpMatchHard_32(b *testing.B)   { benchmark(b, hard, 32<<0) }
 func BenchmarkRegexpMatchHard_1K(b *testing.B)   { benchmark(b, hard, 1<<10) }
diff --git a/test/bench/go1/revcomp_test.go b/test/bench/go1/revcomp_test.go
index 7d57bd6..c2e2c39 100644
--- a/test/bench/go1/revcomp_test.go
+++ b/test/bench/go1/revcomp_test.go
@@ -10,7 +10,7 @@
 import (
 	"bufio"
 	"bytes"
-	"io/ioutil"
+	"io"
 	"testing"
 )
 
@@ -35,7 +35,7 @@
 
 func revcomp(data []byte) {
 	in := bufio.NewReader(bytes.NewBuffer(data))
-	out := ioutil.Discard
+	out := io.Discard
 	buf := make([]byte, 1024*1024)
 	line, err := in.ReadSlice('\n')
 	for err == nil {
diff --git a/test/bench/go1/template_test.go b/test/bench/go1/template_test.go
index 10dacaa..b7e98d5 100644
--- a/test/bench/go1/template_test.go
+++ b/test/bench/go1/template_test.go
@@ -9,7 +9,7 @@
 
 import (
 	"bytes"
-	"io/ioutil"
+	"io"
 	"strings"
 	"testing"
 	"text/template"
@@ -63,7 +63,7 @@
 }
 
 func tmplexec() {
-	if err := tmpl.Execute(ioutil.Discard, &jsondata); err != nil {
+	if err := tmpl.Execute(io.Discard, &jsondata); err != nil {
 		panic(err)
 	}
 }
diff --git a/test/blank1.go b/test/blank1.go
index 70e01b1..815a7e9 100644
--- a/test/blank1.go
+++ b/test/blank1.go
@@ -25,8 +25,8 @@
 	_()	// ERROR "cannot use .* as value"
 	x := _+1	// ERROR "cannot use .* as value"
 	_ = x
-	_ = t._ // ERROR "cannot refer to blank field|invalid use of"
+	_ = t._ // ERROR "cannot refer to blank field|invalid use of|t._ undefined"
 
       var v1, v2 T
-      _ = v1 == v2 // ERROR "cannot be compared|non-comparable"
+      _ = v1 == v2 // ERROR "cannot be compared|non-comparable|cannot compare v1 == v2"
 }
diff --git a/test/cannotassign.go b/test/cannotassign.go
index 0de04ec..27e6289 100644
--- a/test/cannotassign.go
+++ b/test/cannotassign.go
@@ -10,24 +10,24 @@
 
 func main() {
 	var s string = "hello"
-	s[1:2] = "a" // ERROR "cannot assign to .* \(strings are immutable\)"
-	s[3] = "b"   // ERROR "cannot assign to .* \(strings are immutable\)"
+	s[1:2] = "a" // ERROR "cannot assign to .* (\(strings are immutable\))?"
+	s[3] = "b"   // ERROR "cannot assign to .* (\(strings are immutable\))?"
 
 	const n int = 1
 	const cs string = "hello"
-	n = 2        // ERROR "cannot assign to .* \(declared const\)"
-	cs = "hi"    // ERROR "cannot assign to .* \(declared const\)"
-	true = false // ERROR "cannot assign to .* \(declared const\)"
+	n = 2        // ERROR "cannot assign to .* (\(declared const\))?"
+	cs = "hi"    // ERROR "cannot assign to .* (\(declared const\))?"
+	true = false // ERROR "cannot assign to .* (\(declared const\))?"
 
 	var m map[int]struct{ n int }
 	m[0].n = 7 // ERROR "cannot assign to struct field .* in map$"
 
-	1 = 7         // ERROR "cannot assign to 1$"
-	"hi" = 7      // ERROR `cannot assign to "hi"$`
-	nil = 7       // ERROR "cannot assign to nil$"
-	len("") = 7   // ERROR `cannot assign to len\(""\)$`
-	[]int{} = nil // ERROR "cannot assign to \[\]int\{\}$"
+	1 = 7         // ERROR "cannot assign to 1"
+	"hi" = 7      // ERROR `cannot assign to "hi"`
+	nil = 7       // ERROR "cannot assign to nil"
+	len("") = 7   // ERROR `cannot assign to len\(""\)`
+	[]int{} = nil // ERROR "cannot assign to \[\]int\{\}"
 
 	var x int = 7
-	x + 1 = 7 // ERROR "cannot assign to x \+ 1$"
+	x + 1 = 7 // ERROR "cannot assign to x \+ 1"
 }
diff --git a/test/chan/perm.go b/test/chan/perm.go
index 0c96d92..4c94ab7 100644
--- a/test/chan/perm.go
+++ b/test/chan/perm.go
@@ -66,5 +66,5 @@
 	close(c)
 	close(cs)
 	close(cr) // ERROR "receive"
-	close(n)  // ERROR "invalid operation.*non-chan type|must be channel"
+	close(n)  // ERROR "invalid operation.*non-chan type|must be channel|not a channel"
 }
diff --git a/test/char_lit1.go b/test/char_lit1.go
index 489744b..8899aff 100644
--- a/test/char_lit1.go
+++ b/test/char_lit1.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/closure2.go b/test/closure2.go
index e4db05d..812d41f 100644
--- a/test/closure2.go
+++ b/test/closure2.go
@@ -9,6 +9,8 @@
 
 package main
 
+var never bool
+
 func main() {
 	{
 		type X struct {
@@ -115,4 +117,16 @@
 			panic("g() != 2")
 		}
 	}
+
+	{
+		var g func() int
+		q := 0
+		q, g = 1, func() int { return q }
+		if never {
+			g = func() int { return 2 }
+		}
+		if g() != 1 {
+			panic("g() != 1")
+		}
+	}
 }
diff --git a/test/closure3.dir/main.go b/test/closure3.dir/main.go
index 5694673..662a2e9 100644
--- a/test/closure3.dir/main.go
+++ b/test/closure3.dir/main.go
@@ -93,11 +93,11 @@
 		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"
+		y, sink = func() (func(int) int, int) { // ERROR "can inline main.func12"
+			return func(x int) int { // ERROR "func literal does not escape" "can inline main.func12"
 				return x + 1
 			}, 42
-		}()
+		}() // ERROR "inlining call to main.func12"
 		if y(40) != 41 {
 			ppanic("y(40) != 41")
 		}
@@ -105,14 +105,14 @@
 
 	{
 		func() { // ERROR "func literal does not escape"
-			y := func(x int) int { // ERROR "can inline main.func13.1" "func literal does not escape"
+			y := func(x int) int { // ERROR "func literal does not escape" "can inline main.func13.1"
 				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"
+			y, sink = func() (func(int) int, int) { // ERROR "can inline main.func13.2"
+				return func(x int) int { // ERROR  "func literal does not escape" "can inline main.func13.2"
 					return x + 1
 				}, 42
-			}()
+			}() // ERROR "inlining call to main.func13.2"
 			if y(40) != 41 {
 				ppanic("y(40) != 41")
 			}
@@ -187,29 +187,29 @@
 
 	{
 		x := 42
-		if z := func(y int) int { // ERROR "func literal does not escape"
-			return func() int { // ERROR "can inline main.func22.1"
+		if z := func(y int) int { // ERROR "can inline main.func22"
+			return func() int { // ERROR "can inline main.func22.1" "can inline main.func30"
 				return x + y
 			}() // ERROR "inlining call to main.func22.1"
-		}(1); z != 43 {
+		}(1); z != 43 { // ERROR "inlining call to main.func22" "inlining call to main.func30"
 			ppanic("z != 43")
 		}
-		if z := func(y int) int { // ERROR "func literal does not escape"
-			return func() int { // ERROR "can inline main.func23.1"
+		if z := func(y int) int { // ERROR "func literal does not escape" "can inline main.func23"
+			return func() int { // ERROR "can inline main.func23.1" "can inline main.func31"
 				return x + y
 			}() // ERROR "inlining call to main.func23.1"
-		}; z(1) != 43 {
+		}; z(1) != 43 { // ERROR "inlining call to main.func23" "inlining call to main.func31"
 			ppanic("z(1) != 43")
 		}
 	}
 
 	{
 		a := 1
-		func() { // ERROR "func literal does not escape"
-			func() { // ERROR "can inline main.func24"
+		func() { // ERROR "can inline main.func24"
+			func() { // ERROR "can inline main.func24" "can inline main.func32"
 				a = 2
 			}() // ERROR "inlining call to main.func24"
-		}()
+		}() // ERROR "inlining call to main.func24" "inlining call to main.func32"
 		if a != 2 {
 			ppanic("a != 2")
 		}
@@ -250,12 +250,12 @@
 		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"
+			return func(y int) int { // ERROR "can inline main.func27.1"
 				c := 5
-				return func(z int) int { // ERROR "can inline main.func27.1.1"
+				return func(z int) int { // ERROR "can inline main.func27.1.1" "can inline main.func27.2"
 					return a*x + b*y + c*z
 				}(10) // ERROR "inlining call to main.func27.1.1"
-			}(100)
+			}(100) // ERROR "inlining call to main.func27.1" "inlining call to main.func27.2"
 		}(1000); r != 2350 {
 			ppanic("r != 2350")
 		}
@@ -265,15 +265,15 @@
 		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"
+			return func(y int) int { // ERROR "can inline main.func28.1"
 				c := 5
-				func(z int) { // ERROR "can inline main.func28.1.1"
+				func(z int) { // ERROR "can inline main.func28.1.1" "can inline main.func28.2"
 					a = a * x
 					b = b * y
 					c = c * z
 				}(10) // ERROR "inlining call to main.func28.1.1"
 				return a + c
-			}(100) + b
+			}(100) + b // ERROR "inlining call to main.func28.1" "inlining call to main.func28.2"
 		}(1000); r != 2350 {
 			ppanic("r != 2350")
 		}
@@ -285,5 +285,5 @@
 
 //go:noinline
 func ppanic(s string) { // ERROR "leaking param: s"
-	panic(s)
+	panic(s) // ERROR "s escapes to heap"
 }
diff --git a/test/closure3.go b/test/closure3.go
index 37b548d..452a527 100644
--- a/test/closure3.go
+++ b/test/closure3.go
@@ -1,4 +1,4 @@
-// errorcheckandrundir -0 -m
+// errorcheckandrundir -0 -m -d=inlfuncswithclosures=1
 
 // Copyright 2017 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/closure5.dir/a.go b/test/closure5.dir/a.go
new file mode 100644
index 0000000..de8082b
--- /dev/null
+++ b/test/closure5.dir/a.go
@@ -0,0 +1,11 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check correctness of various closure corner cases
+// that are expected to be inlined
+
+package a
+
+func f() bool               { return true }
+func G() func() func() bool { return func() func() bool { return f } }
diff --git a/test/closure5.dir/main.go b/test/closure5.dir/main.go
new file mode 100644
index 0000000..ee5dba6
--- /dev/null
+++ b/test/closure5.dir/main.go
@@ -0,0 +1,15 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check correctness of various closure corner cases
+// that are expected to be inlined
+package main
+
+import "a"
+
+func main() {
+	if !a.G()()() {
+		panic("FAIL")
+	}
+}
diff --git a/test/closure5.go b/test/closure5.go
new file mode 100644
index 0000000..a7022b2
--- /dev/null
+++ b/test/closure5.go
@@ -0,0 +1,10 @@
+// compiledir
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check correctness of various closure corner cases
+// that are expected to be inlined
+
+package ignored
diff --git a/test/closure6.go b/test/closure6.go
new file mode 100644
index 0000000..b5592ad
--- /dev/null
+++ b/test/closure6.go
@@ -0,0 +1,18 @@
+// compile
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type Float64Slice []float64
+
+func (a Float64Slice) Search1(x float64) int {
+	f := func(q int) bool { return a[q] >= x }
+	i := 0
+	if !f(3) {
+		i = 5
+	}
+	return i
+}
diff --git a/test/closure7.go b/test/closure7.go
new file mode 100644
index 0000000..823333f
--- /dev/null
+++ b/test/closure7.go
@@ -0,0 +1,28 @@
+// run
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func g(f func()) {
+}
+
+// Must have exportable name
+func F() {
+	g(func() {
+		ch := make(chan int)
+		for {
+			select {
+			case <-ch:
+				return
+			default:
+			}
+		}
+	})
+}
+
+func main() {
+	F()
+}
diff --git a/test/cmp6.go b/test/cmp6.go
index 7cf7604..704ead2 100644
--- a/test/cmp6.go
+++ b/test/cmp6.go
@@ -63,16 +63,16 @@
 	use(a3 == a3) // ERROR "invalid operation|invalid comparison"
 
 	// Comparison of structs should have a good message
-	use(t3 == t3) // ERROR "struct|expected"
-	use(t4 == t4) // ERROR "cannot be compared|non-comparable"
+	use(t3 == t3) // ERROR "struct|expected|cannot compare"
+	use(t4 == t4) // ERROR "cannot be compared|non-comparable|cannot compare"
 
 	// Slices, functions, and maps too.
 	var x []int
 	var f func()
 	var m map[int]int
-	use(x == x) // ERROR "slice can only be compared to nil"
-	use(f == f) // ERROR "func can only be compared to nil"
-	use(m == m) // ERROR "map can only be compared to nil"
+	use(x == x) // ERROR "slice can only be compared to nil|cannot compare"
+	use(f == f) // ERROR "func can only be compared to nil|cannot compare"
+	use(m == m) // ERROR "map can only be compared to nil|cannot compare"
 
 	// Comparison with interface that cannot return true
 	// (would panic).
diff --git a/test/codegen/arithmetic.go b/test/codegen/arithmetic.go
index 0bdb66a..a27a17f 100644
--- a/test/codegen/arithmetic.go
+++ b/test/codegen/arithmetic.go
@@ -139,7 +139,7 @@
 }
 
 func MergeMuls2(n int) int {
-	// amd64:"IMUL3Q\t[$]23","ADDQ\t[$]29"
+	// amd64:"IMUL3Q\t[$]23","(ADDQ\t[$]29)|(LEAQ\t29)"
 	// 386:"IMUL3L\t[$]23","ADDL\t[$]29"
 	return 5*n + 7*(n+1) + 11*(n+2) // 23n + 29
 }
@@ -322,6 +322,9 @@
 	if divr > 5 {
 		d /= divr // amd64:-"JMP"
 		e %= divr // amd64:-"JMP"
+		// The following statement is to avoid conflict between the above check
+		// and the normal JMP generated at the end of the block.
+		d += e
 	}
 	return d, e
 }
@@ -333,6 +336,7 @@
 	if divd > -9223372036854775808 {
 		d = divd / divr // amd64:-"JMP"
 		e = divd % divr // amd64:-"JMP"
+		d += e
 	}
 	return d, e
 }
@@ -347,6 +351,7 @@
 		// amd64:-"JMP"
 		// 386:-"JMP"
 		e %= divr
+		d += e
 	}
 	return d, e
 }
@@ -362,6 +367,7 @@
 		// amd64:-"JMP"
 		// 386:-"JMP"
 		e = divd % divr
+		d += e
 	}
 	return d, e
 }
@@ -376,6 +382,7 @@
 		// amd64:-"JMP"
 		// 386:-"JMP"
 		e %= divr
+		d += e
 	}
 	return d, e
 }
@@ -391,6 +398,7 @@
 		// amd64:-"JMP"
 		// 386:-"JMP"
 		e = divd % divr
+		d += e
 	}
 	return d, e
 }
diff --git a/test/codegen/bitfield.go b/test/codegen/bitfield.go
index 7abc1c2..0fe6799 100644
--- a/test/codegen/bitfield.go
+++ b/test/codegen/bitfield.go
@@ -244,3 +244,34 @@
 	// mips64:`SLLV\t[$]17`,-`SGT`
 	return x << 17
 }
+
+func rev16(c uint64) (uint64, uint64, uint64) {
+	// arm64:`REV16`,-`AND`,-`LSR`,-`AND`,-`ORR\tR[0-9]+<<8`
+	b1 := ((c & 0xff00ff00ff00ff00) >> 8) | ((c & 0x00ff00ff00ff00ff) << 8)
+	// arm64:-`ADD\tR[0-9]+<<8`
+	b2 := ((c & 0xff00ff00ff00ff00) >> 8) + ((c & 0x00ff00ff00ff00ff) << 8)
+	// arm64:-`EOR\tR[0-9]+<<8`
+	b3 := ((c & 0xff00ff00ff00ff00) >> 8) ^ ((c & 0x00ff00ff00ff00ff) << 8)
+	return b1, b2, b3
+}
+
+func rev16w(c uint32) (uint32, uint32, uint32) {
+	// arm64:`REV16W`,-`AND`,-`UBFX`,-`AND`,-`ORR\tR[0-9]+<<8`
+	b1 := ((c & 0xff00ff00) >> 8) | ((c & 0x00ff00ff) << 8)
+	// arm64:-`ADD\tR[0-9]+<<8`
+	b2 := ((c & 0xff00ff00) >> 8) + ((c & 0x00ff00ff) << 8)
+	// arm64:-`EOR\tR[0-9]+<<8`
+	b3 := ((c & 0xff00ff00) >> 8) ^ ((c & 0x00ff00ff) << 8)
+	return b1, b2, b3
+}
+
+func shift(x uint32, y uint16, z uint8) uint64 {
+	// arm64:-`MOVWU`,-`LSR\t[$]32`
+	a := uint64(x) >> 32
+	// arm64:-`MOVHU
+	b := uint64(y) >> 16
+	// arm64:-`MOVBU`
+	c := uint64(z) >> 8
+	// arm64:`MOVD\tZR`,-`ADD\tR[0-9]+>>16`,-`ADD\tR[0-9]+>>8`,
+	return a + b + c
+}
diff --git a/test/codegen/bits.go b/test/codegen/bits.go
index 6f75022..8117a62 100644
--- a/test/codegen/bits.go
+++ b/test/codegen/bits.go
@@ -264,24 +264,12 @@
 
 // check direct operation on memory with constant and shifted constant sources
 func bitOpOnMem(a []uint32, b, c, d uint32) {
-	// amd64:`ANDL\s[$]200,\s\([A-Z]+\)`
+	// amd64:`ANDL\s[$]200,\s\([A-Z][A-Z0-9]+\)`
 	a[0] &= 200
-	// amd64:`ORL\s[$]220,\s4\([A-Z]+\)`
+	// amd64:`ORL\s[$]220,\s4\([A-Z][A-Z0-9]+\)`
 	a[1] |= 220
-	// amd64:`XORL\s[$]240,\s8\([A-Z]+\)`
+	// amd64:`XORL\s[$]240,\s8\([A-Z][A-Z0-9]+\)`
 	a[2] ^= 240
-	// amd64:`BTRL\s[$]15,\s12\([A-Z]+\)`,-`ANDL`
-	a[3] &= 0xffff7fff
-	// amd64:`BTSL\s[$]14,\s16\([A-Z]+\)`,-`ORL`
-	a[4] |= 0x4000
-	// amd64:`BTCL\s[$]13,\s20\([A-Z]+\)`,-`XORL`
-	a[5] ^= 0x2000
-	// amd64:`BTRL\s[A-Z]+,\s24\([A-Z]+\)`
-	a[6] &^= 1 << (b & 31)
-	// amd64:`BTSL\s[A-Z]+,\s28\([A-Z]+\)`
-	a[7] |= 1 << (c & 31)
-	// amd64:`BTCL\s[A-Z]+,\s32\([A-Z]+\)`
-	a[8] ^= 1 << (d & 31)
 }
 
 func bitcheckMostNegative(b uint8) bool {
@@ -358,3 +346,12 @@
 	// s390x:"RISBGZ\t[$]48, [$]15, [$]0,"
 	return x & 0xffff00000000ffff
 }
+
+func issue44228a(a []int64, i int) bool {
+	// amd64: "BTQ", -"SHL"
+	return a[i>>6]&(1<<(i&63)) != 0
+}
+func issue44228b(a []int32, i int) bool {
+	// amd64: "BTL", -"SHL"
+	return a[i>>5]&(1<<(i&31)) != 0
+}
diff --git a/test/codegen/clobberdead.go b/test/codegen/clobberdead.go
new file mode 100644
index 0000000..f8d964c
--- /dev/null
+++ b/test/codegen/clobberdead.go
@@ -0,0 +1,32 @@
+// asmcheck -gcflags=-clobberdead
+
+// +build amd64
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package codegen
+
+type T [2]*int // contain pointer, not SSA-able (so locals are not registerized)
+
+var p1, p2, p3 T
+
+func F() {
+	// 3735936685 is 0xdeaddead
+	// clobber x, y at entry. not clobber z (stack object).
+	// amd64:`MOVL\t\$3735936685, ""\.x`, `MOVL\t\$3735936685, ""\.y`, -`MOVL\t\$3735936685, ""\.z`
+	x, y, z := p1, p2, p3
+	addrTaken(&z)
+	// x is dead at the call (the value of x is loaded before the CALL), y is not
+	// amd64:`MOVL\t\$3735936685, ""\.x`, -`MOVL\t\$3735936685, ""\.y`
+	use(x)
+	// amd64:`MOVL\t\$3735936685, ""\.x`, `MOVL\t\$3735936685, ""\.y`
+	use(y)
+}
+
+//go:noinline
+func use(T) {}
+
+//go:noinline
+func addrTaken(*T) {}
diff --git a/test/codegen/clobberdeadreg.go b/test/codegen/clobberdeadreg.go
new file mode 100644
index 0000000..2a93c41
--- /dev/null
+++ b/test/codegen/clobberdeadreg.go
@@ -0,0 +1,33 @@
+// asmcheck -gcflags=-clobberdeadreg
+
+// +build amd64
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package codegen
+
+type S struct {
+	a, b, c, d, e, f int
+}
+
+func F(a, b, c int, d S) {
+	// -2401018187971961171 is 0xdeaddeaddeaddead
+	// amd64:`MOVQ\t\$-2401018187971961171, AX`, `MOVQ\t\$-2401018187971961171, BX`, `MOVQ\t\$-2401018187971961171, CX`
+	// amd64:`MOVQ\t\$-2401018187971961171, DX`, `MOVQ\t\$-2401018187971961171, SI`, `MOVQ\t\$-2401018187971961171, DI`
+	// amd64:`MOVQ\t\$-2401018187971961171, R8`, `MOVQ\t\$-2401018187971961171, R9`, `MOVQ\t\$-2401018187971961171, R10`
+	// amd64:`MOVQ\t\$-2401018187971961171, R11`, `MOVQ\t\$-2401018187971961171, R12`, `MOVQ\t\$-2401018187971961171, R13`
+	// amd64:-`MOVQ\t\$-2401018187971961171, BP` // frame pointer is not clobbered
+	StackArgsCall([10]int{a, b, c})
+	// amd64:`MOVQ\t\$-2401018187971961171, R12`, `MOVQ\t\$-2401018187971961171, R13`, `MOVQ\t\$-2401018187971961171, DX`
+	// amd64:-`MOVQ\t\$-2401018187971961171, AX`, -`MOVQ\t\$-2401018187971961171, R11` // register args are not clobbered
+	RegArgsCall(a, b, c, d)
+}
+
+//go:noinline
+func StackArgsCall([10]int) {}
+
+//go:noinline
+//go:registerparams
+func RegArgsCall(int, int, int, S) {}
diff --git a/test/codegen/comparisons.go b/test/codegen/comparisons.go
index 02bed38..17dcd94 100644
--- a/test/codegen/comparisons.go
+++ b/test/codegen/comparisons.go
@@ -90,9 +90,11 @@
 
 // Test that LEAQ/ADDQconst are folded into SETx ops
 
-func CmpFold(x uint32) bool {
-	// amd64:`SETHI\t.*\(SP\)`
-	return x > 4
+var r bool
+
+func CmpFold(x uint32) {
+	// amd64:`SETHI\t.*\(SB\)`
+	r = x > 4
 }
 
 // Test that direct comparisons with memory are generated when
@@ -426,7 +428,7 @@
 }
 
 func UintGtZero(a uint8, b uint16, c uint32, d uint64) int {
-	// arm64: `CBZW`, `CBNZW`, `CBNZ`, -`(CMPW|CMP|BLS|BHI)`
+	// arm64: `(CBN?ZW)`, `(CBN?Z[^W])`, -`(CMPW|CMP|BLS|BHI)`
 	if a > 0 || b > 0 || c > 0 || d > 0 {
 		return 1
 	}
@@ -434,7 +436,7 @@
 }
 
 func UintLeqZero(a uint8, b uint16, c uint32, d uint64) int {
-	// arm64: `CBNZW`, `CBZW`, `CBZ`, -`(CMPW|CMP|BHI|BLS)`
+	// arm64: `(CBN?ZW)`, `(CBN?Z[^W])`, -`(CMPW|CMP|BHI|BLS)`
 	if a <= 0 || b <= 0 || c <= 0 || d <= 0 {
 		return 1
 	}
@@ -442,7 +444,7 @@
 }
 
 func UintLtOne(a uint8, b uint16, c uint32, d uint64) int {
-	// arm64: `CBNZW`, `CBZW`, `CBZW`, `CBZ`, -`(CMPW|CMP|BHS|BLO)`
+	// arm64: `(CBN?ZW)`, `(CBN?Z[^W])`, -`(CMPW|CMP|BHS|BLO)`
 	if a < 1 || b < 1 || c < 1 || d < 1 {
 		return 1
 	}
@@ -450,7 +452,7 @@
 }
 
 func UintGeqOne(a uint8, b uint16, c uint32, d uint64) int {
-	// arm64: `CBZW`, `CBNZW`, `CBNZ`, -`(CMPW|CMP|BLO|BHS)`
+	// arm64: `(CBN?ZW)`, `(CBN?Z[^W])`, -`(CMPW|CMP|BLO|BHS)`
 	if a >= 1 || b >= 1 || c >= 1 || d >= 1 {
 		return 1
 	}
diff --git a/test/codegen/condmove.go b/test/codegen/condmove.go
index f86da34..707f223 100644
--- a/test/codegen/condmove.go
+++ b/test/codegen/condmove.go
@@ -31,8 +31,8 @@
 	if x < y {
 		x = -y
 	}
-	// amd64:"CMOVQCS"
-	// arm64:"CSEL\t(LO|HI)"
+	// amd64:"CMOVQ(HI|CS)"
+	// arm64:"CSNEG\tLS"
 	// wasm:"Select"
 	return x
 }
@@ -41,8 +41,8 @@
 	if x < y {
 		x = -y
 	}
-	// amd64:"CMOVLCS"
-	// arm64:"CSEL\t(LO|HI)"
+	// amd64:"CMOVL(HI|CS)"
+	// arm64:"CSNEG\t(LS|HS)"
 	// wasm:"Select"
 	return x
 }
@@ -51,8 +51,8 @@
 	if x < y {
 		x = -y
 	}
-	// amd64:"CMOVWCS"
-	// arm64:"CSEL\t(LO|HI)"
+	// amd64:"CMOVW(HI|CS)"
+	// arm64:"CSNEG\t(LS|HS)"
 	// wasm:"Select"
 	return x
 }
@@ -208,3 +208,195 @@
 	// amd64:"CMOVQNE"
 	a[i] = 7
 }
+
+var r0, r1, r2, r3, r4, r5 int
+
+func cmovinc(cond bool, a, b, c int) {
+	var x0, x1 int
+
+	if cond {
+		x0 = a
+	} else {
+		x0 = b + 1
+	}
+	// arm64:"CSINC\tNE", -"CSEL"
+	r0 = x0
+
+	if cond {
+		x1 = b + 1
+	} else {
+		x1 = a
+	}
+	// arm64:"CSINC\tEQ", -"CSEL"
+	r1 = x1
+
+	if cond {
+		c++
+	}
+	// arm64:"CSINC\tEQ", -"CSEL"
+	r2 = c
+}
+
+func cmovinv(cond bool, a, b int) {
+	var x0, x1 int
+
+	if cond {
+		x0 = a
+	} else {
+		x0 = ^b
+	}
+	// arm64:"CSINV\tNE", -"CSEL"
+	r0 = x0
+
+	if cond {
+		x1 = ^b
+	} else {
+		x1 = a
+	}
+	// arm64:"CSINV\tEQ", -"CSEL"
+	r1 = x1
+}
+
+func cmovneg(cond bool, a, b, c int) {
+	var x0, x1 int
+
+	if cond {
+		x0 = a
+	} else {
+		x0 = -b
+	}
+	// arm64:"CSNEG\tNE", -"CSEL"
+	r0 = x0
+
+	if cond {
+		x1 = -b
+	} else {
+		x1 = a
+	}
+	// arm64:"CSNEG\tEQ", -"CSEL"
+	r1 = x1
+}
+
+func cmovsetm(cond bool, x int) {
+	var x0, x1 int
+
+	if cond {
+		x0 = -1
+	} else {
+		x0 = 0
+	}
+	// arm64:"CSETM\tNE", -"CSEL"
+	r0 = x0
+
+	if cond {
+		x1 = 0
+	} else {
+		x1 = -1
+	}
+	// arm64:"CSETM\tEQ", -"CSEL"
+	r1 = x1
+}
+
+func cmovFcmp0(s, t float64, a, b int) {
+	var x0, x1, x2, x3, x4, x5 int
+
+	if s < t {
+		x0 = a
+	} else {
+		x0 = b + 1
+	}
+	// arm64:"CSINC\tMI", -"CSEL"
+	r0 = x0
+
+	if s <= t {
+		x1 = a
+	} else {
+		x1 = ^b
+	}
+	// arm64:"CSINV\tLS", -"CSEL"
+	r1 = x1
+
+	if s > t {
+		x2 = a
+	} else {
+		x2 = -b
+	}
+	// arm64:"CSNEG\tMI", -"CSEL"
+	r2 = x2
+
+	if s >= t {
+		x3 = -1
+	} else {
+		x3 = 0
+	}
+	// arm64:"CSETM\tLS", -"CSEL"
+	r3 = x3
+
+	if s == t {
+		x4 = a
+	} else {
+		x4 = b + 1
+	}
+	// arm64:"CSINC\tEQ", -"CSEL"
+	r4 = x4
+
+	if s != t {
+		x5 = a
+	} else {
+		x5 = b + 1
+	}
+	// arm64:"CSINC\tNE", -"CSEL"
+	r5 = x5
+}
+
+func cmovFcmp1(s, t float64, a, b int) {
+	var x0, x1, x2, x3, x4, x5 int
+
+	if s < t {
+		x0 = b + 1
+	} else {
+		x0 = a
+	}
+	// arm64:"CSINC\tPL", -"CSEL"
+	r0 = x0
+
+	if s <= t {
+		x1 = ^b
+	} else {
+		x1 = a
+	}
+	// arm64:"CSINV\tHI", -"CSEL"
+	r1 = x1
+
+	if s > t {
+		x2 = -b
+	} else {
+		x2 = a
+	}
+	// arm64:"CSNEG\tPL", -"CSEL"
+	r2 = x2
+
+	if s >= t {
+		x3 = 0
+	} else {
+		x3 = -1
+	}
+	// arm64:"CSETM\tHI", -"CSEL"
+	r3 = x3
+
+	if s == t {
+		x4 = b + 1
+	} else {
+		x4 = a
+	}
+	// arm64:"CSINC\tNE", -"CSEL"
+	r4 = x4
+
+	if s != t {
+		x5 = b + 1
+	} else {
+		x5 = a
+	}
+	// arm64:"CSINC\tEQ", -"CSEL"
+	r5 = x5
+}
diff --git a/test/codegen/copy.go b/test/codegen/copy.go
index 0cd86d1..ea8a01f 100644
--- a/test/codegen/copy.go
+++ b/test/codegen/copy.go
@@ -97,6 +97,42 @@
 	copy(a[:], a[128:])
 }
 
+// Check arch-specific memmove lowering. See issue 41662 fot details
+
+func moveArchLowering1(b []byte, x *[1]byte) {
+	_ = b[1]
+	// amd64:-".*memmove"
+	// arm64:-".*memmove"
+	copy(b, x[:])
+}
+
+func moveArchLowering2(b []byte, x *[2]byte) {
+	_ = b[2]
+	// amd64:-".*memmove"
+	// arm64:-".*memmove"
+	copy(b, x[:])
+}
+
+func moveArchLowering4(b []byte, x *[4]byte) {
+	_ = b[4]
+	// amd64:-".*memmove"
+	// arm64:-".*memmove"
+	copy(b, x[:])
+}
+
+func moveArchLowering8(b []byte, x *[8]byte) {
+	_ = b[8]
+	// amd64:-".*memmove"
+	// arm64:-".*memmove"
+	copy(b, x[:])
+}
+
+func moveArchLowering16(b []byte, x *[16]byte) {
+	_ = b[16]
+	// amd64:-".*memmove"
+	copy(b, x[:])
+}
+
 // Check that no branches are generated when the pointers are [not] equal.
 
 func ptrEqual() {
diff --git a/test/codegen/floats.go b/test/codegen/floats.go
index 83b4a35..397cbb8 100644
--- a/test/codegen/floats.go
+++ b/test/codegen/floats.go
@@ -53,12 +53,12 @@
 }
 
 func indexLoad(b0 []float32, b1 float32, idx int) float32 {
-	// arm64:`FMOVS\s\(R[0-9]+\)\(R[0-9]+\),\sF[0-9]+`
+	// arm64:`FMOVS\s\(R[0-9]+\)\(R[0-9]+<<2\),\sF[0-9]+`
 	return b0[idx] * b1
 }
 
 func indexStore(b0 []float64, b1 float64, idx int) {
-	// arm64:`FMOVD\sF[0-9]+,\s\(R[0-9]+\)\(R[0-9]+\)`
+	// arm64:`FMOVD\sF[0-9]+,\s\(R[0-9]+\)\(R[0-9]+<<3\)`
 	b0[idx] = b1
 }
 
diff --git a/test/codegen/issue25378.go b/test/codegen/issue25378.go
index 14aa2c3..810a022 100644
--- a/test/codegen/issue25378.go
+++ b/test/codegen/issue25378.go
@@ -13,10 +13,10 @@
 	'\r': true,
 }
 
-func zeroExtArgByte(ch byte) bool {
-	return wsp[ch] // amd64:-"MOVBLZX\t..,.."
+func zeroExtArgByte(ch [2]byte) bool {
+	return wsp[ch[0]] // amd64:-"MOVBLZX\t..,.."
 }
 
-func zeroExtArgUint16(ch uint16) bool {
-	return wsp[ch] // amd64:-"MOVWLZX\t..,.."
+func zeroExtArgUint16(ch [2]uint16) bool {
+	return wsp[ch[0]] // amd64:-"MOVWLZX\t..,.."
 }
diff --git a/test/codegen/maps.go b/test/codegen/maps.go
index 8dd22ed..dcb4a93 100644
--- a/test/codegen/maps.go
+++ b/test/codegen/maps.go
@@ -16,12 +16,12 @@
 // Direct use of constants in fast map access calls (Issue #19015).
 
 func AccessInt1(m map[int]int) int {
-	// amd64:"MOVQ\t[$]5"
+	// amd64:"MOV[LQ]\t[$]5"
 	return m[5]
 }
 
 func AccessInt2(m map[int]int) bool {
-	// amd64:"MOVQ\t[$]5"
+	// amd64:"MOV[LQ]\t[$]5"
 	_, ok := m[5]
 	return ok
 }
diff --git a/test/codegen/math.go b/test/codegen/math.go
index ac80714..04cb4e5 100644
--- a/test/codegen/math.go
+++ b/test/codegen/math.go
@@ -55,6 +55,17 @@
 	return math.Sqrt(x)
 }
 
+func sqrt32(x float32) float32 {
+	// amd64:"SQRTSS"
+	// 386/sse2:"SQRTSS" 386/softfloat:-"SQRTS"
+	// arm64:"FSQRTS"
+	// arm/7:"SQRTF"
+	// mips/hardfloat:"SQRTF" mips/softfloat:-"SQRTF"
+	// mips64/hardfloat:"SQRTF" mips64/softfloat:-"SQRTF"
+	// wasm:"F32Sqrt"
+	return float32(math.Sqrt(float64(x)))
+}
+
 // Check that it's using integer registers
 func abs(x, y float64) {
 	// amd64:"BTRQ\t[$]63"
@@ -149,13 +160,13 @@
 // are evaluated at compile-time
 
 func constantCheck64() bool {
-	// amd64:"MOVB\t[$]0",-"FCMP",-"MOVB\t[$]1"
+	// amd64:"(MOVB\t[$]0)|(XORL\t[A-Z][A-Z0-9]+, [A-Z][A-Z0-9]+)",-"FCMP",-"MOVB\t[$]1"
 	// s390x:"MOV(B|BZ|D)\t[$]0,",-"FCMPU",-"MOV(B|BZ|D)\t[$]1,"
 	return 0.5 == float64(uint32(1)) || 1.5 > float64(uint64(1<<63))
 }
 
 func constantCheck32() bool {
-	// amd64:"MOVB\t[$]1",-"FCMP",-"MOVB\t[$]0"
+	// amd64:"MOV(B|L)\t[$]1",-"FCMP",-"MOV(B|L)\t[$]0"
 	// s390x:"MOV(B|BZ|D)\t[$]1,",-"FCMPU",-"MOV(B|BZ|D)\t[$]0,"
 	return float32(0.5) <= float32(int64(1)) && float32(1.5) >= float32(int32(-1<<31))
 }
diff --git a/test/codegen/mathbits.go b/test/codegen/mathbits.go
index fff6639..03012ef 100644
--- a/test/codegen/mathbits.go
+++ b/test/codegen/mathbits.go
@@ -118,7 +118,7 @@
 //    bits.OnesCount    //
 // -------------------- //
 
-// amd64:".*x86HasPOPCNT"
+// TODO(register args) Restore a m d 6 4 :.*x86HasPOPCNT when only one ABI is tested.
 func OnesCount(n uint) int {
 	// amd64:"POPCNTQ"
 	// arm64:"VCNT","VUADDLV"
@@ -129,7 +129,6 @@
 	return bits.OnesCount(n)
 }
 
-// amd64:".*x86HasPOPCNT"
 func OnesCount64(n uint64) int {
 	// amd64:"POPCNTQ"
 	// arm64:"VCNT","VUADDLV"
@@ -140,7 +139,6 @@
 	return bits.OnesCount64(n)
 }
 
-// amd64:".*x86HasPOPCNT"
 func OnesCount32(n uint32) int {
 	// amd64:"POPCNTL"
 	// arm64:"VCNT","VUADDLV"
@@ -151,7 +149,6 @@
 	return bits.OnesCount32(n)
 }
 
-// amd64:".*x86HasPOPCNT"
 func OnesCount16(n uint16) int {
 	// amd64:"POPCNTL"
 	// arm64:"VCNT","VUADDLV"
diff --git a/test/codegen/memcombine.go b/test/codegen/memcombine.go
index 6ad9514..d74dae0 100644
--- a/test/codegen/memcombine.go
+++ b/test/codegen/memcombine.go
@@ -306,16 +306,16 @@
 
 // Check load combining across function calls.
 
-func fcall_byte(a, b byte) (byte, byte) {
-	return fcall_byte(fcall_byte(a, b)) // amd64:`MOVW`
+func fcall_byte(a [2]byte) [2]byte {
+	return fcall_byte(fcall_byte(a)) // amd64:`MOVW`
 }
 
-func fcall_uint16(a, b uint16) (uint16, uint16) {
-	return fcall_uint16(fcall_uint16(a, b)) // amd64:`MOVL`
+func fcall_uint16(a [2]uint16) [2]uint16 {
+	return fcall_uint16(fcall_uint16(a)) // amd64:`MOVL`
 }
 
-func fcall_uint32(a, b uint32) (uint32, uint32) {
-	return fcall_uint32(fcall_uint32(a, b)) // amd64:`MOVQ`
+func fcall_uint32(a [2]uint32) [2]uint32 {
+	return fcall_uint32(fcall_uint32(a)) // amd64:`MOVQ`
 }
 
 // We want to merge load+op in the first function, but not in the
@@ -367,6 +367,15 @@
 	binary.LittleEndian.PutUint64(b[idx:], sink64)
 }
 
+func store_le64_load(b []byte, x *[8]byte) {
+	_ = b[8]
+	// amd64:-`MOV[BWL]`
+	// arm64:-`MOV[BWH]`
+	// ppc64le:-`MOV[BWH]`
+	// s390x:-`MOVB`,-`MOV[WH]BR`
+	binary.LittleEndian.PutUint64(b, binary.LittleEndian.Uint64(x[:]))
+}
+
 func store_le32(b []byte) {
 	// amd64:`MOVL\s`
 	// arm64:`MOVW`,-`MOV[BH]`
diff --git a/test/codegen/memops.go b/test/codegen/memops.go
index a234283..fb8208f 100644
--- a/test/codegen/memops.go
+++ b/test/codegen/memops.go
@@ -36,50 +36,34 @@
 	return 0
 }
 
-//go:noinline
-func f(x int) bool {
-	return false
+type T struct {
+	x   bool
+	x8  uint8
+	x16 uint16
+	x32 uint32
+	x64 uint64
+	a   [2]int // force it passed in memory
 }
 
-//go:noinline
-func f8(x int) int8 {
-	return 0
-}
-
-//go:noinline
-func f16(x int) int16 {
-	return 0
-}
-
-//go:noinline
-func f32(x int) int32 {
-	return 0
-}
-
-//go:noinline
-func f64(x int) int64 {
-	return 0
-}
-
-func compMem2() int {
-	// amd64:`CMPB\t8\(SP\), [$]0`
-	if f(3) {
+func compMem2(t T) int {
+	// amd64:`CMPB\t.*\(SP\), [$]0`
+	if t.x {
 		return 1
 	}
-	// amd64:`CMPB\t8\(SP\), [$]7`
-	if f8(3) == 7 {
+	// amd64:`CMPB\t.*\(SP\), [$]7`
+	if t.x8 == 7 {
 		return 1
 	}
-	// amd64:`CMPW\t8\(SP\), [$]7`
-	if f16(3) == 7 {
+	// amd64:`CMPW\t.*\(SP\), [$]7`
+	if t.x16 == 7 {
 		return 1
 	}
-	// amd64:`CMPL\t8\(SP\), [$]7`
-	if f32(3) == 7 {
+	// amd64:`CMPL\t.*\(SP\), [$]7`
+	if t.x32 == 7 {
 		return 1
 	}
-	// amd64:`CMPQ\t8\(SP\), [$]7`
-	if f64(3) == 7 {
+	// amd64:`CMPQ\t.*\(SP\), [$]7`
+	if t.x64 == 7 {
 		return 1
 	}
 	return 0
@@ -177,9 +161,11 @@
 	var t float32
 	//    amd64: `MOVSS\t4\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*4\), X[0-9]+`
 	// 386/sse2: `MOVSS\t4\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*4\), X[0-9]+`
+	//    arm64: `FMOVS\t\(R[0-9]*\)\(R[0-9]*<<2\), F[0-9]+`
 	t = x[i+1]
 	//    amd64: `MOVSS\tX[0-9]+, 4\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*4\)`
 	// 386/sse2: `MOVSS\tX[0-9]+, 4\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*4\)`
+	//    arm64: `FMOVS\tF[0-9]+, \(R[0-9]*\)\(R[0-9]*<<2\)`
 	y[i+1] = t
 	//    amd64: `MOVSS\t4\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*[14]\), X[0-9]+`
 	// 386/sse2: `MOVSS\t4\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*[14]\), X[0-9]+`
@@ -193,9 +179,11 @@
 	var t float64
 	//    amd64: `MOVSD\t8\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*8\), X[0-9]+`
 	// 386/sse2: `MOVSD\t8\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*8\), X[0-9]+`
+	//    arm64: `FMOVD\t\(R[0-9]*\)\(R[0-9]*<<3\), F[0-9]+`
 	t = x[i+1]
 	//    amd64: `MOVSD\tX[0-9]+, 8\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*8\)`
 	// 386/sse2: `MOVSD\tX[0-9]+, 8\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*8\)`
+	//    arm64: `FMOVD\tF[0-9]+, \(R[0-9]*\)\(R[0-9]*<<3\)`
 	y[i+1] = t
 	//    amd64: `MOVSD\t8\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*[18]\), X[0-9]+`
 	// 386/sse2: `MOVSD\t8\([A-Z]+[0-9]*\)\([A-Z]+[0-9]*\*[18]\), X[0-9]+`
diff --git a/test/codegen/regabi_regalloc.go b/test/codegen/regabi_regalloc.go
new file mode 100644
index 0000000..a7b7bd5
--- /dev/null
+++ b/test/codegen/regabi_regalloc.go
@@ -0,0 +1,23 @@
+// asmcheck
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package codegen
+
+//go:registerparams
+func f1(a, b int) {
+	// amd64:"MOVQ\tBX, CX", "MOVQ\tAX, BX", "MOVL\t\\$1, AX", -"MOVQ\t.*DX"
+	g(1, a, b)
+}
+
+//go:registerparams
+func f2(a, b int) {
+	// amd64:"MOVQ\tBX, AX", "MOVQ\t[AB]X, CX", -"MOVQ\t.*, BX"
+	g(b, b, b)
+}
+
+//go:noinline
+//go:registerparams
+func g(int, int, int) {}
diff --git a/test/codegen/rotate.go b/test/codegen/rotate.go
index e0bcd0a..519cc83 100644
--- a/test/codegen/rotate.go
+++ b/test/codegen/rotate.go
@@ -16,8 +16,6 @@
 	var a uint64
 
 	// amd64:"ROLQ\t[$]7"
-	// arm64:"ROR\t[$]57"
-	// s390x:"RISBGZ\t[$]0, [$]63, [$]7, "
 	// ppc64:"ROTL\t[$]7"
 	// ppc64le:"ROTL\t[$]7"
 	a += x<<7 | x>>57
@@ -36,6 +34,8 @@
 	// ppc64le:"ROTL\t[$]9"
 	a += x<<9 ^ x>>55
 
+	// s390x:"RISBGZ\t[$]0, [$]63, [$]7, "
+	// arm64:"ROR\t[$]57" // TODO this is not great line numbering, but then again, the instruction did appear
 	return a
 }
 
@@ -44,8 +44,6 @@
 
 	// amd64:"ROLL\t[$]7"
 	// arm:"MOVW\tR\\d+@>25"
-	// arm64:"RORW\t[$]25"
-	// s390x:"RLL\t[$]7"
 	// ppc64:"ROTLW\t[$]7"
 	// ppc64le:"ROTLW\t[$]7"
 	a += x<<7 | x>>25
@@ -66,6 +64,8 @@
 	// ppc64le:"ROTLW\t[$]9"
 	a += x<<9 ^ x>>23
 
+	// s390x:"RLL\t[$]7"
+	// arm64:"RORW\t[$]25" // TODO this is not great line numbering, but then again, the instruction did appear
 	return a
 }
 
@@ -176,38 +176,38 @@
 func checkMaskedRotate32(a []uint32, r int) {
 	i := 0
 
-	// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]16711680, R[0-9]+"
-	// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]16711680, R[0-9]+"
+	// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
+	// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
 	a[i] = bits.RotateLeft32(a[i], 16) & 0xFF0000
 	i++
-	// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]16711680, R[0-9]+"
-	// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]16711680, R[0-9]+"
+	// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
+	// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
 	a[i] = bits.RotateLeft32(a[i]&0xFF, 16)
 	i++
-	// ppc64le: "RLWNM\t[$]4, R[0-9]+, [$]4080, R[0-9]+"
-	// ppc64: "RLWNM\t[$]4, R[0-9]+, [$]4080, R[0-9]+"
+	// ppc64le: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]27, R[0-9]+"
+	// ppc64: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]27, R[0-9]+"
 	a[i] = bits.RotateLeft32(a[i], 4) & 0xFF0
 	i++
-	// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]255, R[0-9]+"
-	// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]255, R[0-9]+"
+	// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]24, [$]31, R[0-9]+"
+	// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]24, [$]31, R[0-9]+"
 	a[i] = bits.RotateLeft32(a[i]&0xFF0000, 16)
 	i++
 
-	// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]16711680, R[0-9]+"
-	// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]16711680, R[0-9]+"
+	// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]8, [$]15, R[0-9]+"
+	// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]8, [$]15, R[0-9]+"
 	a[i] = bits.RotateLeft32(a[i], r) & 0xFF0000
 	i++
-	// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]65280, R[0-9]+"
-	// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]65280, R[0-9]+"
+	// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]16, [$]23, R[0-9]+"
+	// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]16, [$]23, R[0-9]+"
 	a[i] = bits.RotateLeft32(a[3], r) & 0xFF00
 	i++
 
-	// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]4293922815, R[0-9]+"
-	// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]4293922815, R[0-9]+"
+	// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]20, [$]11, R[0-9]+"
+	// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]20, [$]11, R[0-9]+"
 	a[i] = bits.RotateLeft32(a[3], r) & 0xFFF00FFF
 	i++
-	// ppc64le: "RLWNM\t[$]4, R[0-9]+, [$]4293922815, R[0-9]+"
-	// ppc64: "RLWNM\t[$]4, R[0-9]+, [$]4293922815, R[0-9]+"
+	// ppc64le: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]11, R[0-9]+"
+	// ppc64: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]11, R[0-9]+"
 	a[i] = bits.RotateLeft32(a[3], 4) & 0xFFF00FFF
 	i++
 }
diff --git a/test/codegen/shift.go b/test/codegen/shift.go
index d19a198..06f6f12 100644
--- a/test/codegen/shift.go
+++ b/test/codegen/shift.go
@@ -240,12 +240,12 @@
 func checkShiftAndMask32(v []uint32) {
 	i := 0
 
-	// ppc64le: "RLWNM\t[$]24, R[0-9]+, [$]1044480, R[0-9]+"
-	// ppc64: "RLWNM\t[$]24, R[0-9]+, [$]1044480, R[0-9]+"
+	// ppc64le: "RLWNM\t[$]24, R[0-9]+, [$]12, [$]19, R[0-9]+"
+	// ppc64: "RLWNM\t[$]24, R[0-9]+, [$]12, [$]19, R[0-9]+"
 	v[i] = (v[i] & 0xFF00000) >> 8
 	i++
-	// ppc64le: "RLWNM\t[$]26, R[0-9]+, [$]1020, R[0-9]+"
-	// ppc64: "RLWNM\t[$]26, R[0-9]+, [$]1020, R[0-9]+"
+	// ppc64le: "RLWNM\t[$]26, R[0-9]+, [$]22, [$]29, R[0-9]+"
+	// ppc64: "RLWNM\t[$]26, R[0-9]+, [$]22, [$]29, R[0-9]+"
 	v[i] = (v[i] & 0xFF00) >> 6
 	i++
 	// ppc64le: "MOVW\tR0"
@@ -256,12 +256,12 @@
 	// ppc64: "MOVW\tR0"
 	v[i] = (v[i] & 0xF000000) >> 28
 	i++
-	// ppc64le: "RLWNM\t[$]26, R[0-9]+, [$]255, R[0-9]+"
-	// ppc64: "RLWNM\t[$]26, R[0-9]+, [$]255, R[0-9]+"
+	// ppc64le: "RLWNM\t[$]26, R[0-9]+, [$]24, [$]31, R[0-9]+"
+	// ppc64: "RLWNM\t[$]26, R[0-9]+, [$]24, [$]31, R[0-9]+"
 	v[i] = (v[i] >> 6) & 0xFF
 	i++
-	// ppc64le: "RLWNM\t[$]26, R[0-9]+, [$]1044480, R[0-9]+"
-	// ppc64: "RLWNM\t[$]26, R[0-9]+, [$]1044480, R[0-9]+"
+	// ppc64le: "RLWNM\t[$]26, R[0-9]+, [$]12, [$]19, R[0-9]+"
+	// ppc64: "RLWNM\t[$]26, R[0-9]+, [$]12, [$]19, R[0-9]+"
 	v[i] = (v[i] >> 6) & 0xFF000
 	i++
 	// ppc64le: "MOVW\tR0"
@@ -275,16 +275,29 @@
 }
 
 func checkMergedShifts32(a [256]uint32, b [256]uint64, u uint32, v uint32) {
-	//ppc64le: -"CLRLSLDI", "RLWNM\t[$]10, R[0-9]+, [$]1020, R[0-9]+"
-	//ppc64: -"CLRLSLDI", "RLWNM\t[$]10, R[0-9]+, [$]1020, R[0-9]+"
+	//ppc64le: -"CLRLSLDI", "RLWNM\t[$]10, R[0-9]+, [$]22, [$]29, R[0-9]+"
+	//ppc64: -"CLRLSLDI", "RLWNM\t[$]10, R[0-9]+, [$]22, [$]29, R[0-9]+"
 	a[0] = a[uint8(v>>24)]
-	//ppc64le: -"CLRLSLDI", "RLWNM\t[$]11, R[0-9]+, [$]2040, R[0-9]+"
-	//ppc64: -"CLRLSLDI", "RLWNM\t[$]11, R[0-9]+, [$]2040, R[0-9]+"
+	//ppc64le: -"CLRLSLDI", "RLWNM\t[$]11, R[0-9]+, [$]21, [$]28, R[0-9]+"
+	//ppc64: -"CLRLSLDI", "RLWNM\t[$]11, R[0-9]+, [$]21, [$]28, R[0-9]+"
 	b[0] = b[uint8(v>>24)]
-	//ppc64le: -"CLRLSLDI", "RLWNM\t[$]15, R[0-9]+, [$]2040, R[0-9]+"
-	//ppc64: -"CLRLSLDI", "RLWNM\t[$]15, R[0-9]+, [$]2040, R[0-9]+"
+	//ppc64le: -"CLRLSLDI", "RLWNM\t[$]15, R[0-9]+, [$]21, [$]28, R[0-9]+"
+	//ppc64: -"CLRLSLDI", "RLWNM\t[$]15, R[0-9]+, [$]21, [$]28, R[0-9]+"
 	b[1] = b[(v>>20)&0xFF]
-	//ppc64le: -"SLD", "RLWNM\t[$]10, R[0-9]+, [$]1016, R[0-9]+"
-	//ppc64: -"SLD", "RLWNM\t[$]10, R[0-9]+, [$]1016, R[0-9]+"
+	//ppc64le: -"SLD", "RLWNM\t[$]10, R[0-9]+, [$]22, [$]28, R[0-9]+"
+	//ppc64: -"SLD", "RLWNM\t[$]10, R[0-9]+, [$]22, [$]28, R[0-9]+"
 	b[2] = b[v>>25]
 }
+
+// 128 bit shifts
+
+func check128bitShifts(x, y uint64, bits uint) (uint64, uint64) {
+	s := bits & 63
+	ŝ := (64 - bits) & 63
+	// check that the shift operation has two commas (three operands)
+	// amd64:"SHRQ.*,.*,"
+	shr := x>>s | y<<ŝ
+	// amd64:"SHLQ.*,.*,"
+	shl := x<<s | y>>ŝ
+	return shr, shl
+}
diff --git a/test/codegen/slices.go b/test/codegen/slices.go
index 38e8a62..d20aa9e 100644
--- a/test/codegen/slices.go
+++ b/test/codegen/slices.go
@@ -307,7 +307,7 @@
 }
 
 func InitNotSmallSliceLiteral() []int {
-	// amd64:`MOVQ\t.*autotmp_`
+	// amd64:`LEAQ\t.*stmp_`
 	return []int{
 		42,
 		42,
diff --git a/test/codegen/spectre.go b/test/codegen/spectre.go
index 3753498..d845da3 100644
--- a/test/codegen/spectre.go
+++ b/test/codegen/spectre.go
@@ -13,12 +13,12 @@
 }
 
 func IndexString(x string, i int) byte {
-	// amd64:`CMOVQCC`
+	// amd64:`CMOVQLS`
 	return x[i]
 }
 
 func IndexSlice(x []float64, i int) float64 {
-	// amd64:`CMOVQCC`
+	// amd64:`CMOVQLS`
 	return x[i]
 }
 
diff --git a/test/codegen/stack.go b/test/codegen/stack.go
index 7d70024..f28b4a3 100644
--- a/test/codegen/stack.go
+++ b/test/codegen/stack.go
@@ -92,11 +92,11 @@
 // Check that assembly output has matching offset and base register
 // (issue #21064).
 
-func check_asmout(a, b int) int {
+func check_asmout(b [2]int) int {
 	runtime.GC() // use some frame
 	// amd64:`.*b\+24\(SP\)`
 	// arm:`.*b\+4\(FP\)`
-	return b
+	return b[1]
 }
 
 // Check that simple functions get promoted to nosplit, even when
diff --git a/test/codegen/strings.go b/test/codegen/strings.go
index 0859e24..19e1dbd 100644
--- a/test/codegen/strings.go
+++ b/test/codegen/strings.go
@@ -30,6 +30,7 @@
 	//   arm:`MOVW\t\$48`,`MOVW\t\$49`,`MOVW\t\$50`
 	// arm64:`MOVD\t\$12592`,`MOVD\t\$50`
 	//  wasm:`I64Const\t\$12592`,`I64Store16\t\$0`,`I64Const\t\$50`,`I64Store8\t\$2`
+	// mips64:`MOVV\t\$48`,`MOVV\t\$49`,`MOVV\t\$50`
 	bsink = []byte("012")
 
 	// 858927408 = 0x33323130
diff --git a/test/codegen/structs.go b/test/codegen/structs.go
index 9eddc5b..c4bcb55 100644
--- a/test/codegen/structs.go
+++ b/test/codegen/structs.go
@@ -18,7 +18,7 @@
 }
 
 func Zero1(t *Z1) { // Issue #18370
-	// amd64:`XORPS\tX., X`,`MOVUPS\tX., \(.*\)`,`MOVQ\t\$0, 16\(.*\)`
+	// amd64:`MOVUPS\tX[0-9]+, \(.*\)`,`MOVQ\t\$0, 16\(.*\)`
 	*t = Z1{}
 }
 
@@ -27,7 +27,7 @@
 }
 
 func Zero2(t *Z2) {
-	// amd64:`XORPS\tX., X`,`MOVUPS\tX., \(.*\)`,`MOVQ\t\$0, 16\(.*\)`
+	// amd64:`MOVUPS\tX[0-9]+, \(.*\)`,`MOVQ\t\$0, 16\(.*\)`
 	// amd64:`.*runtime[.]gcWriteBarrier.*\(SB\)`
 	*t = Z2{}
 }
diff --git a/test/codegen/zerosize.go b/test/codegen/zerosize.go
index cd0c83b..292c5a0 100644
--- a/test/codegen/zerosize.go
+++ b/test/codegen/zerosize.go
@@ -12,14 +12,14 @@
 
 func zeroSize() {
 	c := make(chan struct{})
-	// amd64:`MOVQ\t\$0, ""\.s\+32\(SP\)`
+	// amd64:`MOVQ\t\$0, ""\.s\+56\(SP\)`
 	var s *int
-	g(&s) // force s to be a stack object
+	// force s to be a stack object, also use some (fixed) stack space
+	g(&s, 1, 2, 3, 4, 5)
 
-	// amd64:`LEAQ\t""\..*\+31\(SP\)`
+	// amd64:`LEAQ\t""\..*\+55\(SP\)`
 	c <- struct{}{}
 }
 
 //go:noinline
-func g(p **int) {
-}
+func g(**int, int, int, int, int, int) {}
diff --git a/test/const1.go b/test/const1.go
index 3fd5b55..1efe688 100644
--- a/test/const1.go
+++ b/test/const1.go
@@ -30,43 +30,43 @@
 )
 
 var (
-	a1 = Int8 * 100              // ERROR "overflow"
+	a1 = Int8 * 100              // ERROR "overflow|cannot convert"
 	a2 = Int8 * -1               // OK
-	a3 = Int8 * 1000             // ERROR "overflow"
-	a4 = Int8 * int8(1000)       // ERROR "overflow"
-	a5 = int8(Int8 * 1000)       // ERROR "overflow"
-	a6 = int8(Int8 * int8(1000)) // ERROR "overflow"
-	a7 = Int8 - 2*Int8 - 2*Int8  // ERROR "overflow"
-	a8 = Int8 * Const / 100      // ERROR "overflow"
+	a3 = Int8 * 1000             // ERROR "overflow|cannot convert"
+	a4 = Int8 * int8(1000)       // ERROR "overflow|cannot convert"
+	a5 = int8(Int8 * 1000)       // ERROR "overflow|cannot convert"
+	a6 = int8(Int8 * int8(1000)) // ERROR "overflow|cannot convert"
+	a7 = Int8 - 2*Int8 - 2*Int8  // ERROR "overflow|cannot convert"
+	a8 = Int8 * Const / 100      // ERROR "overflow|cannot convert"
 	a9 = Int8 * (Const / 100)    // OK
 
-	b1        = Uint8 * Uint8         // ERROR "overflow"
-	b2        = Uint8 * -1            // ERROR "overflow"
+	b1        = Uint8 * Uint8         // ERROR "overflow|cannot convert"
+	b2        = Uint8 * -1            // ERROR "overflow|cannot convert"
 	b3        = Uint8 - Uint8         // OK
-	b4        = Uint8 - Uint8 - Uint8 // ERROR "overflow"
-	b5        = uint8(^0)             // ERROR "overflow"
+	b4        = Uint8 - Uint8 - Uint8 // ERROR "overflow|cannot convert"
+	b5        = uint8(^0)             // ERROR "overflow|cannot convert"
 	b5a       = int64(^0)             // OK
 	b6        = ^uint8(0)             // OK
 	b6a       = ^int64(0)             // OK
-	b7        = uint8(Minus1)         // ERROR "overflow"
-	b8        = uint8(int8(-1))       // ERROR "overflow"
-	b8a       = uint8(-1)             // ERROR "overflow"
+	b7        = uint8(Minus1)         // ERROR "overflow|cannot convert"
+	b8        = uint8(int8(-1))       // ERROR "overflow|cannot convert"
+	b8a       = uint8(-1)             // ERROR "overflow|cannot convert"
 	b9   byte = (1 << 10) >> 8        // OK
-	b10  byte = (1 << 10)             // ERROR "overflow"
-	b11  byte = (byte(1) << 10) >> 8  // ERROR "overflow"
-	b12  byte = 1000                  // ERROR "overflow"
-	b13  byte = byte(1000)            // ERROR "overflow"
-	b14  byte = byte(100) * byte(100) // ERROR "overflow"
-	b15  byte = byte(100) * 100       // ERROR "overflow"
-	b16  byte = byte(0) * 1000        // ERROR "overflow"
+	b10  byte = (1 << 10)             // ERROR "overflow|cannot convert"
+	b11  byte = (byte(1) << 10) >> 8  // ERROR "overflow|cannot convert"
+	b12  byte = 1000                  // ERROR "overflow|cannot convert"
+	b13  byte = byte(1000)            // ERROR "overflow|cannot convert"
+	b14  byte = byte(100) * byte(100) // ERROR "overflow|cannot convert"
+	b15  byte = byte(100) * 100       // ERROR "overflow|cannot convert"
+	b16  byte = byte(0) * 1000        // ERROR "overflow|cannot convert"
 	b16a byte = 0 * 1000              // OK
-	b17  byte = byte(0) * byte(1000)  // ERROR "overflow"
+	b17  byte = byte(0) * byte(1000)  // ERROR "overflow|cannot convert"
 	b18  byte = Uint8 / 0             // ERROR "division by zero"
 
 	c1 float64 = Big
-	c2 float64 = Big * Big          // ERROR "overflow"
-	c3 float64 = float64(Big) * Big // ERROR "overflow"
-	c4         = Big * Big          // ERROR "overflow"
+	c2 float64 = Big * Big          // ERROR "overflow|cannot convert"
+	c3 float64 = float64(Big) * Big // ERROR "overflow|cannot convert"
+	c4         = Big * Big          // ERROR "overflow|cannot convert"
 	c5         = Big / 0            // ERROR "division by zero"
 	c6         = 1000 % 1e3         // ERROR "invalid operation|expected integer type"
 )
@@ -87,8 +87,8 @@
 	f(Bool)             // ERROR "convert|wrong type|cannot|incompatible"
 }
 
-const ptr = nil // ERROR "const.*nil"
+const ptr = nil // ERROR "const.*nil|not constant"
 const _ = string([]byte(nil)) // ERROR "is not a? ?constant"
 const _ = uintptr(unsafe.Pointer((*int)(nil))) // ERROR "is not a? ?constant"
-const _ = unsafe.Pointer((*int)(nil)) // ERROR "cannot be nil|invalid constant type|is not a constant"
-const _ = (*int)(nil) // ERROR "cannot be nil|invalid constant type|is not a constant"
+const _ = unsafe.Pointer((*int)(nil)) // ERROR "cannot be nil|invalid constant type|is not a constant|not constant"
+const _ = (*int)(nil) // ERROR "cannot be nil|invalid constant type|is not a constant|not constant"
diff --git a/test/const2.go b/test/const2.go
index 048d0cb..f0de37b 100644
--- a/test/const2.go
+++ b/test/const2.go
@@ -11,7 +11,7 @@
 
 const (
 	A int = 1
-	B byte;	// ERROR "type without expr|expected .=."
+	B byte;	// ERROR "type without expr|expected .=.|missing init expr"
 )
 
 const LargeA = 1000000000000000000
@@ -19,3 +19,14 @@
 const LargeC = LargeB * LargeB * LargeB // GC_ERROR "constant multiplication overflow"
 
 const AlsoLargeA = LargeA << 400 << 400 >> 400 >> 400 // GC_ERROR "constant shift overflow"
+
+// Issue #42732.
+
+const a = 1e+500000000
+const b = a * a // ERROR "constant multiplication overflow|not representable"
+const c = b * b
+
+const MaxInt512 = (1<<256 - 1) * (1<<256 + 1)
+const _ = MaxInt512 + 1  // ERROR "constant addition overflow"
+const _ = MaxInt512 ^ -1 // ERROR "constant bitwise XOR overflow"
+const _ = ^MaxInt512     // ERROR "constant bitwise complement overflow"
diff --git a/test/const7.go b/test/const7.go
new file mode 100644
index 0000000..9ffd678
--- /dev/null
+++ b/test/const7.go
@@ -0,0 +1,77 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check that the compiler refuses excessively long constants.
+
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+)
+
+// testProg creates a package called name, with path dir/name.go,
+// which declares an untyped constant of the given length.
+// testProg compiles this package and checks for the absence or
+// presence of a constant literal error.
+func testProg(dir, name string, G_option, length int, ok bool) {
+	var buf bytes.Buffer
+
+	fmt.Fprintf(&buf,
+		"package %s; const _ = %s // %d digits",
+		name, strings.Repeat("9", length), length,
+	)
+
+	filename := filepath.Join(dir, fmt.Sprintf("%s.go", name))
+	if err := os.WriteFile(filename, buf.Bytes(), 0666); err != nil {
+		log.Fatal(err)
+	}
+
+	cmd := exec.Command("go", "tool", "compile", fmt.Sprintf("-G=%d", G_option), filename)
+	cmd.Dir = dir
+	output, err := cmd.CombinedOutput()
+
+	if ok {
+		// no error expected
+		if err != nil {
+			log.Fatalf("%s: compile failed unexpectedly: %v", name, err)
+		}
+		return
+	}
+
+	// error expected
+	if err == nil {
+		log.Fatalf("%s: compile succeeded unexpectedly", name)
+	}
+	if !bytes.Contains(output, []byte("excessively long constant")) {
+		log.Fatalf("%s: wrong compiler error message:\n%s\n", name, output)
+	}
+}
+
+func main() {
+	if runtime.GOOS == "js" || runtime.Compiler != "gc" {
+		return
+	}
+
+	dir, err := ioutil.TempDir("", "const7_")
+	if err != nil {
+		log.Fatalf("creating temp dir: %v\n", err)
+	}
+	defer os.RemoveAll(dir)
+
+	const limit = 10000 // compiler-internal constant length limit
+	testProg(dir, "x1", 0, limit, true)    // -G=0
+	testProg(dir, "x2", 0, limit+1, false) // -G=0
+	testProg(dir, "x1", 1, limit, true)    // -G=1 (new type checker)
+	testProg(dir, "x2", 1, limit+1, false) // -G=1 (new type checker)
+}
diff --git a/test/convert2.go b/test/convert2.go
index c500638..8e43967 100644
--- a/test/convert2.go
+++ b/test/convert2.go
@@ -22,7 +22,7 @@
 	var t T
 	var u struct{}
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
 	s = u
 	s = S(s)
 	s = S(t)
@@ -42,12 +42,12 @@
 		x int "bar"
 	}
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
+	s = u // ERROR "cannot use .* in assignment|incompatible type"
 	s = S(s)
 	s = S(t)
 	s = S(u)
-	t = u // ERROR "cannot use .* in assignment"
+	t = u // ERROR "cannot use .* in assignment|incompatible type"
 	t = T(u)
 }
 
@@ -63,12 +63,12 @@
 		x E "bar"
 	}
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
+	s = u // ERROR "cannot use .* in assignment|incompatible type"
 	s = S(s)
 	s = S(t)
 	s = S(u)
-	t = u // ERROR "cannot use .* in assignment"
+	t = u // ERROR "cannot use .* in assignment|incompatible type"
 	t = T(u)
 }
 
@@ -91,12 +91,12 @@
 		} "bar"
 	}
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
+	s = u // ERROR "cannot use .* in assignment|incompatible type"
 	s = S(s)
 	s = S(t)
 	s = S(u)
-	t = u // ERROR "cannot use .* in assignment"
+	t = u // ERROR "cannot use .* in assignment|incompatible type"
 	t = T(u)
 }
 
@@ -117,12 +117,12 @@
 		x E2 "bar"
 	}
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
+	s = u // ERROR "cannot use .* in assignment|incompatible type"
 	s = S(s)
 	s = S(t) // ERROR "cannot convert"
 	s = S(u) // ERROR "cannot convert"
-	t = u    // ERROR "cannot use .* in assignment"
+	t = u    // ERROR "cannot use .* in assignment|incompatible type"
 	t = T(u)
 }
 
@@ -142,12 +142,12 @@
 	var t T
 	var u struct{ f func(E) }
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
+	s = u // ERROR "cannot use .* in assignment|incompatible type"
 	s = S(s)
 	s = S(t)
 	s = S(u) // ERROR "cannot convert"
-	t = u    // ERROR "cannot use .* in assignment"
+	t = u    // ERROR "cannot use .* in assignment|incompatible type"
 	t = T(u) // ERROR "cannot convert"
 }
 
@@ -160,12 +160,12 @@
 	var t *T
 	var u *struct{}
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
+	s = u // ERROR "cannot use .* in assignment|incompatible type"
 	s = (*S)(s)
 	s = (*S)(t)
 	s = (*S)(u)
-	t = u // ERROR "cannot use .* in assignment"
+	t = u // ERROR "cannot use .* in assignment|incompatible type"
 	t = (*T)(u)
 }
 
@@ -180,12 +180,12 @@
 		x int "bar"
 	}
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
+	s = u // ERROR "cannot use .* in assignment|incompatible type"
 	s = (*S)(s)
 	s = (*S)(t)
 	s = (*S)(u)
-	t = u // ERROR "cannot use .* in assignment"
+	t = u // ERROR "cannot use .* in assignment|incompatible type"
 	t = (*T)(u)
 }
 
@@ -201,12 +201,12 @@
 		x E "bar"
 	}
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
+	s = u // ERROR "cannot use .* in assignment|incompatible type"
 	s = (*S)(s)
 	s = (*S)(t)
 	s = (*S)(u)
-	t = u // ERROR "cannot use .* in assignment"
+	t = u // ERROR "cannot use .* in assignment|incompatible type"
 	t = (*T)(u)
 }
 
@@ -229,12 +229,12 @@
 		} "bar"
 	}
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
+	s = u // ERROR "cannot use .* in assignment|incompatible type"
 	s = (*S)(s)
 	s = (*S)(t)
 	s = (*S)(u)
-	t = u // ERROR "cannot use .* in assignment"
+	t = u // ERROR "cannot use .* in assignment|incompatible type"
 	t = (*T)(u)
 }
 
@@ -255,12 +255,12 @@
 		x E2 "bar"
 	}
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
+	s = u // ERROR "cannot use .* in assignment|incompatible type"
 	s = (*S)(s)
 	s = (*S)(t) // ERROR "cannot convert"
 	s = (*S)(u) // ERROR "cannot convert"
-	t = u       // ERROR "cannot use .* in assignment"
+	t = u       // ERROR "cannot use .* in assignment|incompatible type"
 	t = (*T)(u)
 }
 
@@ -280,12 +280,12 @@
 	var t *T
 	var u *struct{ f func(E) }
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
+	s = u // ERROR "cannot use .* in assignment|incompatible type"
 	s = (*S)(s)
 	s = (*S)(t)
 	s = (*S)(u) // ERROR "cannot convert"
-	t = u       // ERROR "cannot use .* in assignment"
+	t = u       // ERROR "cannot use .* in assignment|incompatible type"
 	t = (*T)(u) // ERROR "cannot convert"
 }
 
@@ -305,11 +305,25 @@
 	var t *T
 	var u *struct{ f func(E) }
 	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
+	s = t // ERROR "cannot use .* in assignment|incompatible type"
+	s = u // ERROR "cannot use .* in assignment|incompatible type"
 	s = (*S)(s)
 	s = (*S)(t)
 	s = (*S)(u) // ERROR "cannot convert"
-	t = u       // ERROR "cannot use .* in assignment"
+	t = u       // ERROR "cannot use .* in assignment|incompatible type"
 	t = (*T)(u) // ERROR "cannot convert"
 }
+
+func _() {
+	var s []byte
+	_ = ([4]byte)(s) // ERROR "cannot convert"
+	_ = (*[4]byte)(s)
+
+	type A [4]byte
+	_ = (A)(s) // ERROR "cannot convert"
+	_ = (*A)(s)
+
+	type P *[4]byte
+	_ = (P)(s)
+	_ = (*P)(s) // ERROR "cannot convert"
+}
diff --git a/test/convert4.go b/test/convert4.go
new file mode 100644
index 0000000..2bc9c96
--- /dev/null
+++ b/test/convert4.go
@@ -0,0 +1,86 @@
+// run
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test conversion from slice to array pointer.
+
+package main
+
+func wantPanic(fn func(), s string) {
+	defer func() {
+		err := recover()
+		if err == nil {
+			panic("expected panic")
+		}
+		if got := err.(error).Error(); got != s {
+			panic("expected panic " + s + " got " + got)
+		}
+	}()
+	fn()
+}
+
+func main() {
+	s := make([]byte, 8, 10)
+	if p := (*[8]byte)(s); &p[0] != &s[0] {
+		panic("*[8]byte conversion failed")
+	}
+	wantPanic(
+		func() {
+			_ = (*[9]byte)(s)
+		},
+		"runtime error: cannot convert slice with length 8 to pointer to array with length 9",
+	)
+
+	var n []byte
+	if p := (*[0]byte)(n); p != nil {
+		panic("nil slice converted to *[0]byte should be nil")
+	}
+
+	z := make([]byte, 0)
+	if p := (*[0]byte)(z); p == nil {
+		panic("empty slice converted to *[0]byte should be non-nil")
+	}
+
+	// Test with named types
+	type Slice []int
+	type Int4 [4]int
+	type PInt4 *[4]int
+	ii := make(Slice, 4)
+	if p := (*Int4)(ii); &p[0] != &ii[0] {
+		panic("*Int4 conversion failed")
+	}
+	if p := PInt4(ii); &p[0] != &ii[0] {
+		panic("PInt4 conversion failed")
+	}
+}
+
+// test static variable conversion
+
+var (
+	ss  = make([]string, 10)
+	s5  = (*[5]string)(ss)
+	s10 = (*[10]string)(ss)
+
+	ns  []string
+	ns0 = (*[0]string)(ns)
+
+	zs  = make([]string, 0)
+	zs0 = (*[0]string)(zs)
+)
+
+func init() {
+	if &ss[0] != &s5[0] {
+		panic("s5 conversion failed")
+	}
+	if &ss[0] != &s10[0] {
+		panic("s5 conversion failed")
+	}
+	if ns0 != nil {
+		panic("ns0 should be nil")
+	}
+	if zs0 == nil {
+		panic("zs0 should not be nil")
+	}
+}
diff --git a/test/convlit.go b/test/convlit.go
index 1c66c89..8bf9928 100644
--- a/test/convlit.go
+++ b/test/convlit.go
@@ -17,8 +17,8 @@
 var x3 = int(1.5)     // ERROR "convert|truncate"
 var x4 int = int(1.5) // ERROR "convert|truncate"
 var x5 = "a" + string(1)
-var x6 = int(1e100)      // ERROR "overflow"
-var x7 = float32(1e1000) // ERROR "overflow"
+var x6 = int(1e100)      // ERROR "overflow|cannot convert"
+var x7 = float32(1e1000) // ERROR "overflow|cannot convert"
 
 // unsafe.Pointer can only convert to/from uintptr
 var _ = string(unsafe.Pointer(uintptr(65)))  // ERROR "convert|conversion"
@@ -34,7 +34,7 @@
 var bad5 = "a" + 'a' // ERROR "literals|incompatible|convert|invalid"
 
 var bad6 int = 1.5       // ERROR "convert|truncate"
-var bad7 int = 1e100     // ERROR "overflow"
+var bad7 int = 1e100     // ERROR "overflow|truncated to int|truncated"
 var bad8 float32 = 1e200 // ERROR "overflow"
 
 // but these implicit conversions are okay
@@ -48,8 +48,8 @@
 var _ = []byte("abc")
 
 // implicit is not
-var _ []int = "abc"  // ERROR "cannot use|incompatible|invalid"
-var _ []byte = "abc" // ERROR "cannot use|incompatible|invalid"
+var _ []int = "abc"  // ERROR "cannot use|incompatible|invalid|cannot convert"
+var _ []byte = "abc" // ERROR "cannot use|incompatible|invalid|cannot convert"
 
 // named string is okay
 type Tstring string
@@ -70,5 +70,5 @@
 var _ = Tbyte("abc") // ok
 
 // implicit is still not
-var _ Trune = "abc" // ERROR "cannot use|incompatible|invalid"
-var _ Tbyte = "abc" // ERROR "cannot use|incompatible|invalid"
+var _ Trune = "abc" // ERROR "cannot use|incompatible|invalid|cannot convert"
+var _ Tbyte = "abc" // ERROR "cannot use|incompatible|invalid|cannot convert"
diff --git a/test/copy1.go b/test/copy1.go
index e1fa105..c0760f7 100644
--- a/test/copy1.go
+++ b/test/copy1.go
@@ -17,11 +17,11 @@
 	_ = copy()        // ERROR "not enough arguments"
 	_ = copy(1, 2, 3) // ERROR "too many arguments"
 
-	_ = copy(si, "hi") // ERROR "have different element types.*int.*string"
+	_ = copy(si, "hi") // ERROR "have different element types(.*int.*string| int and byte)"
 	_ = copy(si, sf)   // ERROR "have different element types.*int.*float64"
 
-	_ = copy(1, 2)  // ERROR "must be slices; have int, int"
-	_ = copy(1, si) // ERROR "first argument to copy should be"
-	_ = copy(si, 2) // ERROR "second argument to copy should be"
+	_ = copy(1, 2)  // ERROR "must be slices; have int, int|expects slice arguments"
+	_ = copy(1, si) // ERROR "first argument to copy should be|expects slice arguments"
+	_ = copy(si, 2) // ERROR "second argument to copy should be|expects slice arguments"
 
 }
diff --git a/test/ddd1.go b/test/ddd1.go
index 01b9c0e..ad49b34 100644
--- a/test/ddd1.go
+++ b/test/ddd1.go
@@ -29,7 +29,7 @@
 	_ = sum(tuple())
 	_ = sum(tuple()...) // ERROR "multiple-value"
 	_ = sum3(tuple())
-	_ = sum3(tuple()...) // ERROR "multiple-value"
+	_ = sum3(tuple()...) // ERROR "multiple-value" ERROR "invalid use of .*[.][.][.]"
 )
 
 type T []T
diff --git a/test/declbad.go b/test/declbad.go
index 728eceb..b978652 100644
--- a/test/declbad.go
+++ b/test/declbad.go
@@ -23,13 +23,13 @@
 	{
 		// change of type for f
 		i, f, s := f3()
-		f, g, t := f3() // ERROR "redeclared|cannot assign|incompatible"
+		f, g, t := f3() // ERROR "redeclared|cannot assign|incompatible|cannot use"
 		_, _, _, _, _ = i, f, s, g, t
 	}
 	{
 		// change of type for i
 		i, f, s := f3()
-		j, i, t := f3() // ERROR "redeclared|cannot assign|incompatible"
+		j, i, t := f3() // ERROR "redeclared|cannot assign|incompatible|cannot use"
 		_, _, _, _, _ = i, f, s, j, t
 	}
 	{
diff --git a/test/deferfin.go b/test/deferfin.go
index 8037291..1312bbb 100644
--- a/test/deferfin.go
+++ b/test/deferfin.go
@@ -18,12 +18,8 @@
 var sink func()
 
 func main() {
-	// Does not work on 32-bits due to partially conservative GC.
+	// Does not work with gccgo, due to partially conservative GC.
 	// Try to enable when we have fully precise GC.
-	if runtime.GOARCH != "amd64" {
-		return
-	}
-	// Likewise for gccgo.
 	if runtime.Compiler == "gccgo" {
 		return
 	}
@@ -60,4 +56,3 @@
 		panic("not all finalizers are called")
 	}
 }
-
diff --git a/test/escape2.go b/test/escape2.go
index 5c6eb55..b9b723d 100644
--- a/test/escape2.go
+++ b/test/escape2.go
@@ -1547,7 +1547,7 @@
 	case int: // ERROR "moved to heap: x$"
 		return &x
 	}
-	panic(0)
+	panic(0) // ERROR "0 escapes to heap"
 }
 
 // issue 8185 - &result escaping into result
diff --git a/test/escape2n.go b/test/escape2n.go
index 46e58f8..7c8208a 100644
--- a/test/escape2n.go
+++ b/test/escape2n.go
@@ -1547,7 +1547,7 @@
 	case int: // ERROR "moved to heap: x$"
 		return &x
 	}
-	panic(0)
+	panic(0) // ERROR "0 escapes to heap"
 }
 
 // issue 8185 - &result escaping into result
diff --git a/test/escape4.go b/test/escape4.go
index a4a9c14..4e50231 100644
--- a/test/escape4.go
+++ b/test/escape4.go
@@ -35,14 +35,14 @@
 func f2() {} // ERROR "can inline f2"
 
 // No inline for recover; panic now allowed to inline.
-func f3() { panic(1) } // ERROR "can inline f3"
+func f3() { panic(1) } // ERROR "can inline f3" "1 escapes to heap"
 func f4() { recover() }
 
 func f5() *byte {
 	type T struct {
 		x [1]byte
 	}
-	t := new(T)    // ERROR "new.T. escapes to heap"
+	t := new(T) // ERROR "new.T. escapes to heap"
 	return &t.x[0]
 }
 
@@ -52,6 +52,6 @@
 			y byte
 		}
 	}
-	t := new(T)   // ERROR "new.T. escapes to heap"
+	t := new(T) // ERROR "new.T. escapes to heap"
 	return &t.x.y
 }
diff --git a/test/escape_param.go b/test/escape_param.go
index 993e914..dc93f68 100644
--- a/test/escape_param.go
+++ b/test/escape_param.go
@@ -212,7 +212,7 @@
 
 // **in -> heap
 func param8(i **int) { // ERROR "i does not escape$"
-	sink = **i // ERROR "\* \(\*i\) escapes to heap"
+	sink = **i // ERROR "\*\(\*i\) escapes to heap"
 }
 
 func caller8() {
@@ -402,7 +402,7 @@
 	var p *int
 	v := &Val{&p} // ERROR "&Val{...} does not escape$"
 	v.param13(&i)
-	sink = **v.p // ERROR "\* \(\*v\.p\) escapes to heap"
+	sink = **v.p // ERROR "\*\(\*v\.p\) escapes to heap"
 }
 
 type Node struct {
diff --git a/test/escape_slice.go b/test/escape_slice.go
index 6ce852e..d604147 100644
--- a/test/escape_slice.go
+++ b/test/escape_slice.go
@@ -101,6 +101,10 @@
 	_ = s
 }
 
+func slice12(x []int) *[1]int { // ERROR "leaking param: x to result ~r1 level=0$"
+	return (*[1]int)(x)
+}
+
 func envForDir(dir string) []string { // ERROR "dir does not escape"
 	env := os.Environ()
 	return mergeEnvLists([]string{"PWD=" + dir}, env) // ERROR ".PWD=. \+ dir escapes to heap" "\[\]string{...} does not escape"
diff --git a/test/fixedbugs/bug040.go b/test/fixedbugs/bug040.go
index d2cf88a..5c3a1d7 100644
--- a/test/fixedbugs/bug040.go
+++ b/test/fixedbugs/bug040.go
@@ -7,5 +7,5 @@
 package main
 
 func f (x,		// GCCGO_ERROR "previous"
-	x int) {	// ERROR "duplicate argument|redefinition"
+	x int) {	// ERROR "duplicate argument|redefinition|redeclared"
 }
diff --git a/test/fixedbugs/bug050.go b/test/fixedbugs/bug050.go
index aba68b1..1e299ed 100644
--- a/test/fixedbugs/bug050.go
+++ b/test/fixedbugs/bug050.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/bug062.go b/test/fixedbugs/bug062.go
index 1cc5003..24c2dff 100644
--- a/test/fixedbugs/bug062.go
+++ b/test/fixedbugs/bug062.go
@@ -8,4 +8,5 @@
 
 func main() {
 	var s string = nil;	// ERROR "illegal|invalid|incompatible|cannot"
+	_ = s
 }
diff --git a/test/fixedbugs/bug081.go b/test/fixedbugs/bug081.go
index c25d288..40e6dd1 100644
--- a/test/fixedbugs/bug081.go
+++ b/test/fixedbugs/bug081.go
@@ -6,7 +6,7 @@
 
 package main
 
-const x x = 2 // ERROR "loop|type"
+const x x = 2 // ERROR "loop|type|cycle"
 
 /*
 bug081.go:3: first constant must evaluate an expression
diff --git a/test/fixedbugs/bug090.go b/test/fixedbugs/bug090.go
index 320bd57..6d30cca 100644
--- a/test/fixedbugs/bug090.go
+++ b/test/fixedbugs/bug090.go
@@ -42,5 +42,5 @@
 
 	const h float64 = 3.14;
 	i = h;  // ERROR "convert|incompatible|cannot"
-	i = int(h);	// ERROR "truncate"
+	i = int(h);	// ERROR "truncate|cannot convert"
 }
diff --git a/test/fixedbugs/bug122.go b/test/fixedbugs/bug122.go
index fb4eb9f..5640cf2 100644
--- a/test/fixedbugs/bug122.go
+++ b/test/fixedbugs/bug122.go
@@ -8,5 +8,5 @@
 
 func main() {
 	// should allow at most 2 sizes
-	a := make([]int, 10, 20, 30, 40); // ERROR "too many"
+	a := make([]int, 10, 20, 30, 40); // ERROR "too many|expects 2 or 3 arguments; found 5"
 }
diff --git a/test/fixedbugs/bug131.go b/test/fixedbugs/bug131.go
index 0ebbd26..2c9d120 100644
--- a/test/fixedbugs/bug131.go
+++ b/test/fixedbugs/bug131.go
@@ -9,4 +9,5 @@
 func main() {
 	const a uint64 = 10;
 	var b int64 = a;	// ERROR "convert|cannot|incompatible"
+	_ = b
 }
diff --git a/test/fixedbugs/bug132.go b/test/fixedbugs/bug132.go
index e334566..b75e833 100644
--- a/test/fixedbugs/bug132.go
+++ b/test/fixedbugs/bug132.go
@@ -7,5 +7,5 @@
 package main
 
 type T struct {
-	x, x int  // ERROR "duplicate"
+	x, x int  // ERROR "duplicate|redeclared"
 }
diff --git a/test/fixedbugs/bug163.go b/test/fixedbugs/bug163.go
index d69f6be..f3e0543 100644
--- a/test/fixedbugs/bug163.go
+++ b/test/fixedbugs/bug163.go
@@ -6,6 +6,4 @@
 
 package main
 
-func main() {
-	x⊛y := 1;	// ERROR "identifier"
-}
+var x⊛y int	// ERROR "invalid character .* in identifier"
diff --git a/test/fixedbugs/bug175.go b/test/fixedbugs/bug175.go
index 5fca4b2..88210a5 100644
--- a/test/fixedbugs/bug175.go
+++ b/test/fixedbugs/bug175.go
@@ -9,6 +9,6 @@
 func f() (int, bool) { return 0, true }
 
 func main() {
-	x, y := f(), 2;	// ERROR "multi"
+	x, y := f(), 2;	// ERROR "multi|2-valued"
 	_, _ = x, y
 }
diff --git a/test/fixedbugs/bug188.go b/test/fixedbugs/bug188.go
index 5506147..8195e36 100644
--- a/test/fixedbugs/bug188.go
+++ b/test/fixedbugs/bug188.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -9,7 +9,7 @@
 import "sort"
 
 func main() {
-	sort.Sort(nil);
-	var x int;
-	sort(x);	// ERROR "package"
+	sort.Sort(nil)
+	var x int
+	sort(x) // ERROR "package"
 }
diff --git a/test/fixedbugs/bug192.go b/test/fixedbugs/bug192.go
index 679aaed..a22e6a2 100644
--- a/test/fixedbugs/bug192.go
+++ b/test/fixedbugs/bug192.go
@@ -8,4 +8,6 @@
 
 import "fmt"	// GCCGO_ERROR "previous"
 
-var fmt int	// ERROR "redecl|redefinition"
+var _ = fmt.Println // avoid imported and not used error
+
+var fmt int	// ERROR "redecl|redefinition|fmt already declared"
diff --git a/test/fixedbugs/bug193.go b/test/fixedbugs/bug193.go
index 64e06da..3607322 100644
--- a/test/fixedbugs/bug193.go
+++ b/test/fixedbugs/bug193.go
@@ -11,6 +11,8 @@
 	ss := 1 << s
 	y1 := float64(ss)
 	y2 := float64(1 << s) // ERROR "shift"
-	y3 := string(1 << s)  // ERROR "shift"
+	// see issues #45114, #45117
+	// y3 := string(1 << s)  // DISABLED "shift"
+	y3 := 0
 	_, _, _, _, _ = s, ss, y1, y2, y3
 }
diff --git a/test/fixedbugs/bug205.go b/test/fixedbugs/bug205.go
index 1e0d9d1..165020e 100644
--- a/test/fixedbugs/bug205.go
+++ b/test/fixedbugs/bug205.go
@@ -11,8 +11,8 @@
 var m map[string]int;
 
 func main() {
-	println(t["hi"]); // ERROR "non-integer slice index|must be integer"
-	println(s["hi"]); // ERROR "non-integer string index|must be integer"
-	println(m[0]);    // ERROR "cannot use.*as type string"
+	println(t["hi"]); // ERROR "non-integer slice index|must be integer|cannot convert"
+	println(s["hi"]); // ERROR "non-integer string index|must be integer|cannot convert"
+	println(m[0]);    // ERROR "cannot use.*as type string|cannot convert|cannot use"
 }
 
diff --git a/test/fixedbugs/bug215.go b/test/fixedbugs/bug215.go
index b27cc7d..5546d0c 100644
--- a/test/fixedbugs/bug215.go
+++ b/test/fixedbugs/bug215.go
@@ -9,6 +9,6 @@
 
 package main
 
-type A struct {	a A }	// ERROR "recursive"
+type A struct {	a A }	// ERROR "recursive|cycle"
 func foo()		{ new(A).bar() }
 func (a A) bar()	{}
diff --git a/test/fixedbugs/bug223.go b/test/fixedbugs/bug223.go
index 29ae53c..50082cb 100644
--- a/test/fixedbugs/bug223.go
+++ b/test/fixedbugs/bug223.go
@@ -18,4 +18,4 @@
 	}
 }
 
-var m = map[string]F{"f": f} // ERROR "initialization loop|depends upon itself"
+var m = map[string]F{"f": f} // ERROR "initialization loop|depends upon itself|initialization cycle"
diff --git a/test/fixedbugs/bug224.go b/test/fixedbugs/bug224.go
index d2fd67c..4ff8301 100644
--- a/test/fixedbugs/bug224.go
+++ b/test/fixedbugs/bug224.go
@@ -6,5 +6,5 @@
 
 package main
 
-type T T		// ERROR "recursive"
+type T T		// ERROR "recursive|cycle"
 
diff --git a/test/fixedbugs/bug228.go b/test/fixedbugs/bug228.go
index f7ac670..50e8959 100644
--- a/test/fixedbugs/bug228.go
+++ b/test/fixedbugs/bug228.go
@@ -8,7 +8,7 @@
 
 func f(x int, y ...int)	// ok
 
-func g(x int, y float32) (...)	// ERROR "[.][.][.]" "final argument"
+func g(x int, y float32) (...)	// ERROR "[.][.][.]"
 
 func h(x, y ...int)		// ERROR "[.][.][.]"
 
diff --git a/test/fixedbugs/bug229.go b/test/fixedbugs/bug229.go
index a30202f..3cf1142 100644
--- a/test/fixedbugs/bug229.go
+++ b/test/fixedbugs/bug229.go
@@ -14,7 +14,7 @@
 	// make sure error mentions that
 	// name is unexported, not just "name not found".
 
-	t.common.name = nil // ERROR "unexported"
+	t.common.name = nil // ERROR "unexported|undefined"
 
-	println(testing.anyLowercaseName("asdf")) // ERROR "unexported"
+	println(testing.anyLowercaseName("asdf")) // ERROR "unexported|undefined"
 }
diff --git a/test/fixedbugs/bug280.go b/test/fixedbugs/bug280.go
index afec57f..9a9d4c9 100644
--- a/test/fixedbugs/bug280.go
+++ b/test/fixedbugs/bug280.go
@@ -8,6 +8,6 @@
 
 package main
 
-type A [...]int	// ERROR "outside of array literal"
+type A [...]int	// ERROR "outside of array literal|invalid use of \[\.\.\.\]"
 
 
diff --git a/test/fixedbugs/bug289.go b/test/fixedbugs/bug289.go
index 3fc7fb2..fea6829 100644
--- a/test/fixedbugs/bug289.go
+++ b/test/fixedbugs/bug289.go
@@ -9,14 +9,14 @@
 package main
 
 func f1() {
-	a, b := f()	// ERROR "assignment mismatch|does not match"
+	a, b := f()	// ERROR "assignment mismatch|does not match|cannot initialize"
 	_ = a
 	_ = b
 }
 
 func f2() {
 	var a, b int
-	a, b = f()	// ERROR "assignment mismatch|does not match"
+	a, b = f()	// ERROR "assignment mismatch|does not match|cannot assign"
 	_ = a
 	_ = b
 }
diff --git a/test/fixedbugs/bug297.go b/test/fixedbugs/bug297.go
index c2bd253..70eb4ca 100644
--- a/test/fixedbugs/bug297.go
+++ b/test/fixedbugs/bug297.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2010 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -9,7 +9,8 @@
 package main
 
 type ByteSize float64
+
 const (
-	_ = iota;   // ignore first value by assigning to blank identifier
-	KB ByteSize = 1<<(10*X) // ERROR "undefined"
+	_           = iota          // ignore first value by assigning to blank identifier
+	KB ByteSize = 1 << (10 * X) // ERROR "undefined"
 )
diff --git a/test/fixedbugs/bug325.go b/test/fixedbugs/bug325.go
index e6528ae..74d7bbb 100644
--- a/test/fixedbugs/bug325.go
+++ b/test/fixedbugs/bug325.go
@@ -10,6 +10,6 @@
 
 func main() {
 	var x unsafe.Pointer
-	println(*x) // ERROR "invalid indirect.*unsafe.Pointer"
+	println(*x) // ERROR "invalid indirect.*unsafe.Pointer|cannot indirect"
 	var _ = (unsafe.Pointer)(nil).foo  // ERROR "foo"
 }
diff --git a/test/fixedbugs/bug326.go b/test/fixedbugs/bug326.go
index 75d620c..dfd8be8 100644
--- a/test/fixedbugs/bug326.go
+++ b/test/fixedbugs/bug326.go
@@ -19,7 +19,7 @@
 }
 
 func i() (int, error) {
-	return // ERROR "not enough arguments to return"
+	return // ERROR "not enough arguments to return|wrong number of return values"
 }
 
 func f1() (_ int, err error) {
diff --git a/test/fixedbugs/bug340.go b/test/fixedbugs/bug340.go
index 8c543c9..117b286 100644
--- a/test/fixedbugs/bug340.go
+++ b/test/fixedbugs/bug340.go
@@ -12,6 +12,7 @@
 	var x interface{}
 	switch t := x.(type) {
 	case 0:		// ERROR "type"
-		t.x = 1 // ERROR "type interface \{\}|reference to undefined field or method|interface with no methods"
+		t.x = 1
+		x.x = 1 // ERROR "type interface \{\}|reference to undefined field or method|interface with no methods|undefined"
 	}
 }
diff --git a/test/fixedbugs/bug342.go b/test/fixedbugs/bug342.go
index f90f6f3..ccf93a6 100644
--- a/test/fixedbugs/bug342.go
+++ b/test/fixedbugs/bug342.go
@@ -9,7 +9,7 @@
 package p
 
 type a interface {
-	foo(x int) (x int) // ERROR "duplicate argument|redefinition"
+	foo(x int) (x int) // ERROR "duplicate argument|redefinition|redeclared"
 }
 
 /*
diff --git a/test/fixedbugs/bug350.go b/test/fixedbugs/bug350.go
index cdce1cf..39f91d4 100644
--- a/test/fixedbugs/bug350.go
+++ b/test/fixedbugs/bug350.go
@@ -12,4 +12,4 @@
 func (T) m() {} // ERROR "T[.]m redeclared|redefinition"
 
 func (*T) p() {} // GCCGO_ERROR "previous"
-func (*T) p() {} // ERROR "[(][*]T[)][.]p redeclared|redefinition"
+func (*T) p() {} // ERROR "[(][*]T[)][.]p redeclared|redefinition|redeclared"
diff --git a/test/fixedbugs/bug357.go b/test/fixedbugs/bug357.go
index e9db50e..0a4cbed 100644
--- a/test/fixedbugs/bug357.go
+++ b/test/fixedbugs/bug357.go
@@ -15,7 +15,7 @@
 
 func bla5() bool {
 	_ = 1
-	false  // ERROR "false evaluated but not used|value computed is not used"
+	false  // ERROR "false evaluated but not used|value computed is not used|is not used"
 	_ = 2
 	return false
 }
diff --git a/test/fixedbugs/bug358.go b/test/fixedbugs/bug358.go
index 5ca0be1..541051c 100644
--- a/test/fixedbugs/bug358.go
+++ b/test/fixedbugs/bug358.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/bug362.go b/test/fixedbugs/bug362.go
index 771d13d..98d6b0c 100644
--- a/test/fixedbugs/bug362.go
+++ b/test/fixedbugs/bug362.go
@@ -10,7 +10,7 @@
 package main
 
 var (
-	a = iota  // ERROR "undefined: iota|iota is only defined in const"
-	b = iota  // ERROR "undefined: iota|iota is only defined in const"
-	c = iota  // ERROR "undefined: iota|iota is only defined in const"
+	a = iota  // ERROR "undefined: iota|iota is only defined in const|cannot use iota outside constant declaration"
+	b = iota  // ERROR "undefined: iota|iota is only defined in const|cannot use iota outside constant declaration"
+	c = iota  // ERROR "undefined: iota|iota is only defined in const|cannot use iota outside constant declaration"
 )
diff --git a/test/fixedbugs/bug371.go b/test/fixedbugs/bug371.go
index 3a626e5..eb51b9e 100644
--- a/test/fixedbugs/bug371.go
+++ b/test/fixedbugs/bug371.go
@@ -19,6 +19,6 @@
 	p.m()
 
 	q := &p
-	q.m()  // ERROR "requires explicit dereference"
-	q.pm() // ERROR "requires explicit dereference"
+	q.m()  // ERROR "requires explicit dereference|undefined"
+	q.pm() // ERROR "requires explicit dereference|undefined"
 }
diff --git a/test/fixedbugs/bug379.go b/test/fixedbugs/bug379.go
index 5638123..aa078b6 100644
--- a/test/fixedbugs/bug379.go
+++ b/test/fixedbugs/bug379.go
@@ -14,5 +14,5 @@
 package main
 
 func main() {
-	1 + 2 // ERROR "1 \+ 2 evaluated but not used|value computed is not used"
+	1 + 2 // ERROR "1 \+ 2 evaluated but not used|value computed is not used|is not used"
 }
diff --git a/test/fixedbugs/bug383.go b/test/fixedbugs/bug383.go
index dc2ecd6..543ee10 100644
--- a/test/fixedbugs/bug383.go
+++ b/test/fixedbugs/bug383.go
@@ -8,6 +8,6 @@
 
 package main
 func main() {
-	if 2e9 { }      // ERROR "2e.09|expected bool"
-	if 3.14+1i { }  // ERROR "3.14 . 1i|expected bool"
+	if 2e9 { }      // ERROR "2e.09|expected bool|non-boolean condition in if statement"
+	if 3.14+1i { }  // ERROR "3.14 . 1i|expected bool|non-boolean condition in if statement"
 }
diff --git a/test/fixedbugs/bug386.go b/test/fixedbugs/bug386.go
index 889c8b0..0899d1f 100644
--- a/test/fixedbugs/bug386.go
+++ b/test/fixedbugs/bug386.go
@@ -7,6 +7,6 @@
 // Issue 2451, 2452 
 package foo
 
-func f() error { return 0 } // ERROR "cannot use 0 .type int.|has no methods"
+func f() error { return 0 } // ERROR "cannot use 0 (.type int.)?|has no methods"
 
-func g() error { return -1 }  // ERROR "cannot use -1 .type int.|has no methods"
+func g() error { return -1 }  // ERROR "cannot use -1 (.type int.)?|has no methods"
diff --git a/test/fixedbugs/bug389.go b/test/fixedbugs/bug389.go
index 14804c8..167e64e 100644
--- a/test/fixedbugs/bug389.go
+++ b/test/fixedbugs/bug389.go
@@ -9,4 +9,4 @@
 
 func fn(a float32) {}
 
-var f func(arg int) = fn  // ERROR "cannot use fn .type func.float32.. as type func.int. in assignment|different parameter types"
+var f func(arg int) = fn  // ERROR "cannot use fn .type func.float32.. as type func.int. in assignment|different parameter types|incompatible type"
diff --git a/test/fixedbugs/bug390.go b/test/fixedbugs/bug390.go
index 7ce9e13..4ab24fb 100644
--- a/test/fixedbugs/bug390.go
+++ b/test/fixedbugs/bug390.go
@@ -12,5 +12,5 @@
 
 func main() {
 	var x *int
-	_ = unsafe.Pointer(x) - unsafe.Pointer(x) // ERROR "operator - not defined on unsafe.Pointer|expected integer, floating, or complex type"
+	_ = unsafe.Pointer(x) - unsafe.Pointer(x) // ERROR "(operator|operation) - not defined on unsafe.Pointer|expected integer, floating, or complex type"
 }
diff --git a/test/fixedbugs/bug397.go b/test/fixedbugs/bug397.go
index 6188e3e..5f1476a 100644
--- a/test/fixedbugs/bug397.go
+++ b/test/fixedbugs/bug397.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -7,7 +7,7 @@
 package main
 
 // Issue 2623
-var m = map[string]int {
-	"abc":1,
-	1:2, // ERROR "cannot use 1.*as type string in map key|incompatible type"
+var m = map[string]int{
+	"abc": 1,
+	1:     2, // ERROR "cannot use 1.*as type string in map key|incompatible type|cannot convert|cannot use"
 }
diff --git a/test/fixedbugs/bug416.go b/test/fixedbugs/bug416.go
index 9fc3532..74b55cc 100644
--- a/test/fixedbugs/bug416.go
+++ b/test/fixedbugs/bug416.go
@@ -10,4 +10,4 @@
 	X int
 }
 
-func (t *T) X() {} // ERROR "type T has both field and method named X|redeclares struct field name"
+func (t *T) X() {} // ERROR "type T has both field and method named X|redeclares struct field name|field and method with the same name"
diff --git a/test/fixedbugs/bug418.go b/test/fixedbugs/bug418.go
index 64d86b3..4e63e86 100644
--- a/test/fixedbugs/bug418.go
+++ b/test/fixedbugs/bug418.go
@@ -13,10 +13,10 @@
 
 // F used to compile.
 func F() (x interface{}, y int) {
-	return Two(), 0 // ERROR "single-value context"
+	return Two(), 0 // ERROR "single-value context|2\-valued"
 }
 
 // Recursive used to trigger an internal compiler error.
 func Recursive() (x interface{}, y int) {
-	return Recursive(), 0 // ERROR "single-value context"
+	return Recursive(), 0 // ERROR "single-value context|2\-valued"
 }
diff --git a/test/fixedbugs/bug462.go b/test/fixedbugs/bug462.go
index 3df63b0..c6962e4 100644
--- a/test/fixedbugs/bug462.go
+++ b/test/fixedbugs/bug462.go
@@ -8,12 +8,14 @@
 
 import "os"
 
+var _ = os.Open // avoid imported and not used error
+
 type T struct {
 	File int
 }
 
 func main() {
-	_ = T {
-		os.File: 1, // ERROR "unknown T? ?field"
+	_ = T{
+		os.File: 1, // ERROR "invalid field name os.File|unknown field"
 	}
 }
diff --git a/test/fixedbugs/bug463.go b/test/fixedbugs/bug463.go
index c7f9237..ed546bf 100644
--- a/test/fixedbugs/bug463.go
+++ b/test/fixedbugs/bug463.go
@@ -9,11 +9,11 @@
 
 package main
 
-const a = a // ERROR "refers to itself|definition loop"
+const a = a // ERROR "refers to itself|definition loop|initialization loop"
 
 const (
 	X    = A
-	A    = B // ERROR "refers to itself|definition loop"
+	A    = B // ERROR "refers to itself|definition loop|initialization loop"
 	B    = D
 	C, D = 1, A
 )
diff --git a/test/fixedbugs/bug487.go b/test/fixedbugs/bug487.go
index e60af6c..150d660 100644
--- a/test/fixedbugs/bug487.go
+++ b/test/fixedbugs/bug487.go
@@ -14,11 +14,11 @@
 }
 
 func F() {
-	a, b := G()	// ERROR "mismatch"
-	a, b = G()	// ERROR "mismatch"
+	a, b := G()	// ERROR "mismatch|cannot initialize"
+	a, b = G()	// ERROR "mismatch|cannot assign"
 	_, _ = a, b
 }
 
 func H() (int, int) {
-	return G()	// ERROR "too many|mismatch"
+	return G()	// ERROR "too many|mismatch|wrong number"
 }
diff --git a/test/fixedbugs/bug511.dir/a.go b/test/fixedbugs/bug511.dir/a.go
new file mode 100644
index 0000000..33931a0
--- /dev/null
+++ b/test/fixedbugs/bug511.dir/a.go
@@ -0,0 +1,11 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+type S struct{}
+
+type A = S
+
+func (A) M() {}
diff --git a/test/fixedbugs/bug511.dir/b.go b/test/fixedbugs/bug511.dir/b.go
new file mode 100644
index 0000000..f8877d6
--- /dev/null
+++ b/test/fixedbugs/bug511.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "./a"
+
+func F() {
+	a.S{}.M()
+}
diff --git a/test/fixedbugs/bug511.go b/test/fixedbugs/bug511.go
new file mode 100644
index 0000000..edd3a23
--- /dev/null
+++ b/test/fixedbugs/bug511.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Gccgo mishandled type aliases as receiver types.
+
+package ignored
diff --git a/test/fixedbugs/bug512.go b/test/fixedbugs/bug512.go
new file mode 100644
index 0000000..6be6eb9
--- /dev/null
+++ b/test/fixedbugs/bug512.go
@@ -0,0 +1,52 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Gccgo did not make a copy of a value receiver when using a
+// goroutine to call a method.
+
+package main
+
+import (
+	"sync"
+	"sync/atomic"
+)
+
+var wg sync.WaitGroup
+
+type S struct {
+	i1, i2 int32
+}
+
+var done int32
+
+func (s S) Check(v1, v2 int32) {
+	for {
+		if g1 := atomic.LoadInt32(&s.i1); v1 != g1 {
+			panic(g1)
+		}
+		if g2 := atomic.LoadInt32(&s.i2); v2 != g2 {
+			panic(g2)
+		}
+		if atomic.LoadInt32(&done) != 0 {
+			break
+		}
+	}
+	wg.Done()
+}
+
+func F() {
+	s := S{1, 2}
+	go s.Check(1, 2)
+	atomic.StoreInt32(&s.i1, 3)
+	atomic.StoreInt32(&s.i2, 4)
+	atomic.StoreInt32(&done, 1)
+}
+
+func main() {
+	wg.Add(1)
+	F()
+	wg.Wait()
+}
diff --git a/test/fixedbugs/bug513.go b/test/fixedbugs/bug513.go
new file mode 100644
index 0000000..459a9c3
--- /dev/null
+++ b/test/fixedbugs/bug513.go
@@ -0,0 +1,21 @@
+// run -race -gcflags=all=-d=checkptr=0
+// +build linux,amd64 linux,ppc64le darwin,amd64 freebsd,amd64 netbsd,amd64 windows,amd64
+// +build cgo
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Although -race turns on -d=checkptr, the explicit -d=checkptr=0
+// should override it.
+
+package main
+
+import "unsafe"
+
+var v1 = new([2]int16)
+var v2 *[3]int64
+
+func main() {
+	v2 = (*[3]int64)(unsafe.Pointer(uintptr(unsafe.Pointer(&(*v1)[0]))))
+}
diff --git a/test/fixedbugs/issue10607.go b/test/fixedbugs/issue10607.go
index 448a37d..8a04bc9 100644
--- a/test/fixedbugs/issue10607.go
+++ b/test/fixedbugs/issue10607.go
@@ -1,4 +1,4 @@
-// +build linux,!ppc64,!riscv64,gc
+// +build linux,!ppc64,gc
 // run
 
 // Copyright 2015 The Go Authors. All rights reserved.
@@ -8,9 +8,6 @@
 // Test that a -B option is passed through when using both internal
 // and external linking mode.
 
-// TODO(jsing): Re-enable on riscv64 when it has support for external
-// linking - see golang.org/issue/36739
-
 package main
 
 import (
diff --git a/test/fixedbugs/issue10975.go b/test/fixedbugs/issue10975.go
index 933badf..89ef23c 100644
--- a/test/fixedbugs/issue10975.go
+++ b/test/fixedbugs/issue10975.go
@@ -10,7 +10,7 @@
 package main
 
 type I interface {
-	int // ERROR "interface contains embedded non-interface"
+	int // ERROR "interface contains embedded non-interface|not an interface"
 }
 
 func New() I {
diff --git a/test/fixedbugs/issue11326.go b/test/fixedbugs/issue11326.go
index e0c6a9f..4ce25c5 100644
--- a/test/fixedbugs/issue11326.go
+++ b/test/fixedbugs/issue11326.go
@@ -18,14 +18,14 @@
 
 	// Any implementation must be able to handle these constants at
 	// compile time (even though they cannot be assigned to a float64).
-	var _ = 1e646456992  // ERROR "1e\+646456992 overflows float64|floating-point constant overflow|exponent too large"
-	var _ = 1e64645699   // ERROR "1e\+64645699 overflows float64|floating-point constant overflow|exponent too large"
-	var _ = 1e6464569    // ERROR "1e\+6464569 overflows float64|floating-point constant overflow|exponent too large"
-	var _ = 1e646456     // ERROR "1e\+646456 overflows float64|floating-point constant overflow|exponent too large"
-	var _ = 1e64645      // ERROR "1e\+64645 overflows float64|floating-point constant overflow|exponent too large"
-	var _ = 1e6464       // ERROR "1e\+6464 overflows float64|floating-point constant overflow"
-	var _ = 1e646        // ERROR "1e\+646 overflows float64|floating-point constant overflow"
-	var _ = 1e309        // ERROR "1e\+309 overflows float64|floating-point constant overflow"
+	var _ = 1e646456992  // ERROR "1e\+646456992 overflows float64|floating-point constant overflow|exponent too large|overflows float64|overflows"
+	var _ = 1e64645699   // ERROR "1e\+64645699 overflows float64|floating-point constant overflow|exponent too large|overflows float64|overflows"
+	var _ = 1e6464569    // ERROR "1e\+6464569 overflows float64|floating-point constant overflow|exponent too large|overflows float64|overflows"
+	var _ = 1e646456     // ERROR "1e\+646456 overflows float64|floating-point constant overflow|exponent too large|overflows float64|overflows"
+	var _ = 1e64645      // ERROR "1e\+64645 overflows float64|floating-point constant overflow|exponent too large|overflows float64|overflows"
+	var _ = 1e6464       // ERROR "1e\+6464 overflows float64|floating-point constant overflow|overflows float64|overflows"
+	var _ = 1e646        // ERROR "1e\+646 overflows float64|floating-point constant overflow|overflows float64|overflows"
+	var _ = 1e309        // ERROR "1e\+309 overflows float64|floating-point constant overflow|overflows float64|overflows"
 
 	var _ = 1e308
 }
diff --git a/test/fixedbugs/issue11361.go b/test/fixedbugs/issue11361.go
index 63dbf05..1ef8735 100644
--- a/test/fixedbugs/issue11361.go
+++ b/test/fixedbugs/issue11361.go
@@ -8,4 +8,4 @@
 
 import "fmt"  // GC_ERROR "imported and not used"
 
-const n = fmt // ERROR "fmt without selector|unexpected reference to package"
+const n = fmt // ERROR "fmt without selector|unexpected reference to package|use of package fmt not in selector"
diff --git a/test/fixedbugs/issue11362.go b/test/fixedbugs/issue11362.go
index 964e5fd..f4b65b0 100644
--- a/test/fixedbugs/issue11362.go
+++ b/test/fixedbugs/issue11362.go
@@ -8,8 +8,7 @@
 
 package main
 
-import _ "unicode//utf8" // GC_ERROR "non-canonical import path .unicode//utf8. \(should be .unicode/utf8.\)" "can't find import: .unicode//utf8."
+import _ "unicode//utf8" // GC_ERROR "non-canonical import path .unicode//utf8. \(should be .unicode/utf8.\)"
 
 func main() {
 }
-
diff --git a/test/fixedbugs/issue11371.go b/test/fixedbugs/issue11371.go
index 8acd18f..bc10ca6 100644
--- a/test/fixedbugs/issue11371.go
+++ b/test/fixedbugs/issue11371.go
@@ -9,9 +9,9 @@
 
 package issue11371
 
-const a int = 1.1        // ERROR "constant 1.1 truncated to integer|floating-point constant truncated to integer"
-const b int = 1e20       // ERROR "overflows int|integer constant overflow"
-const c int = 1 + 1e-70  // ERROR "constant truncated to integer"
-const d int = 1 - 1e-70  // ERROR "constant truncated to integer"
-const e int = 1.00000001 // ERROR "constant truncated to integer"
-const f int = 0.00000001 // ERROR "constant 1e-08 truncated to integer|floating-point constant truncated to integer"
+const a int = 1.1        // ERROR "constant 1.1 truncated to integer|floating-point constant truncated to integer|truncated to int|truncated"
+const b int = 1e20       // ERROR "overflows int|integer constant overflow|truncated to int|truncated"
+const c int = 1 + 1e-70  // ERROR "constant truncated to integer|truncated to int|truncated"
+const d int = 1 - 1e-70  // ERROR "constant truncated to integer|truncated to int|truncated"
+const e int = 1.00000001 // ERROR "constant truncated to integer|truncated to int|truncated"
+const f int = 0.00000001 // ERROR "constant 1e-08 truncated to integer|floating-point constant truncated to integer|truncated to int|truncated"
diff --git a/test/fixedbugs/issue11674.go b/test/fixedbugs/issue11674.go
index b43032d..183ed13 100644
--- a/test/fixedbugs/issue11674.go
+++ b/test/fixedbugs/issue11674.go
@@ -13,28 +13,28 @@
 const y complex128 = 0
 
 var _ = x / 1e-20
-var _ = x / 1e-50   // GC_ERROR "complex division by zero"
-var _ = x / 1e-1000 // GC_ERROR "complex division by zero"
+var _ = x / 1e-50   // GC_ERROR "division by zero"
+var _ = x / 1e-1000 // GC_ERROR "division by zero"
 var _ = x / 1e-20i
-var _ = x / 1e-50i   // GC_ERROR "complex division by zero"
-var _ = x / 1e-1000i // GC_ERROR "complex division by zero"
+var _ = x / 1e-50i   // GC_ERROR "division by zero"
+var _ = x / 1e-1000i // GC_ERROR "division by zero"
 
 var _ = x / 1e-45 // smallest positive float32
 
 var _ = x / (1e-20 + 1e-20i)
 var _ = x / (1e-50 + 1e-20i)
 var _ = x / (1e-20 + 1e-50i)
-var _ = x / (1e-50 + 1e-50i)     // GC_ERROR "complex division by zero"
-var _ = x / (1e-1000 + 1e-1000i) // GC_ERROR "complex division by zero"
+var _ = x / (1e-50 + 1e-50i)     // GC_ERROR "division by zero"
+var _ = x / (1e-1000 + 1e-1000i) // GC_ERROR "division by zero"
 
 var _ = y / 1e-50
-var _ = y / 1e-1000 // GC_ERROR "complex division by zero"
+var _ = y / 1e-1000 // GC_ERROR "division by zero"
 var _ = y / 1e-50i
-var _ = y / 1e-1000i // GC_ERROR "complex division by zero"
+var _ = y / 1e-1000i // GC_ERROR "division by zero"
 
 var _ = y / 5e-324 // smallest positive float64
 
 var _ = y / (1e-50 + 1e-50)
 var _ = y / (1e-1000 + 1e-50i)
 var _ = y / (1e-50 + 1e-1000i)
-var _ = y / (1e-1000 + 1e-1000i) // GC_ERROR "complex division by zero"
+var _ = y / (1e-1000 + 1e-1000i) // GC_ERROR "division by zero"
diff --git a/test/fixedbugs/issue11737.go b/test/fixedbugs/issue11737.go
index 86ecf9a..eb4bfe8 100644
--- a/test/fixedbugs/issue11737.go
+++ b/test/fixedbugs/issue11737.go
@@ -12,6 +12,6 @@
 
 func s(x interface{}) {
 	switch x {
-	case f: // ERROR "invalid case f \(type func\(\)\) in switch \(incomparable type\)"
+	case f: // ERROR "invalid case f \(type func\(\)\) in switch \(incomparable type\)|cannot compare"
 	}
 }
diff --git a/test/fixedbugs/issue11945.go b/test/fixedbugs/issue11945.go
index 510b655..218d07a 100644
--- a/test/fixedbugs/issue11945.go
+++ b/test/fixedbugs/issue11945.go
@@ -13,6 +13,10 @@
 	_ = real(0) // from bug report
 	_ = imag(0) // from bug report
 
+	// same as above, but exported for #43891
+	Real0 = real(0)
+	Imag0 = imag(0)
+
 	// if the arguments are untyped, the results must be untyped
 	// (and compatible with types that can represent the values)
 	_ int = real(1)
diff --git a/test/fixedbugs/issue13365.go b/test/fixedbugs/issue13365.go
index 31a663e..b22fa0f 100644
--- a/test/fixedbugs/issue13365.go
+++ b/test/fixedbugs/issue13365.go
@@ -11,15 +11,15 @@
 var t struct{}
 
 func main() {
-	_ = []int{-1: 0}    // ERROR "index must be non\-negative integer constant|index expression is negative"
-	_ = [10]int{-1: 0}  // ERROR "index must be non\-negative integer constant|index expression is negative"
-	_ = [...]int{-1: 0} // ERROR "index must be non\-negative integer constant|index expression is negative"
+	_ = []int{-1: 0}    // ERROR "index must be non\-negative integer constant|index expression is negative|must not be negative"
+	_ = [10]int{-1: 0}  // ERROR "index must be non\-negative integer constant|index expression is negative|must not be negative"
+	_ = [...]int{-1: 0} // ERROR "index must be non\-negative integer constant|index expression is negative|must not be negative"
 
 	_ = []int{100: 0}
 	_ = [10]int{100: 0} // ERROR "array index 100 out of bounds|out of range"
 	_ = [...]int{100: 0}
 
-	_ = []int{t}    // ERROR "cannot use .* as type int in slice literal|incompatible type"
-	_ = [10]int{t}  // ERROR "cannot use .* as type int in array literal|incompatible type"
-	_ = [...]int{t} // ERROR "cannot use .* as type int in array literal|incompatible type"
+	_ = []int{t}    // ERROR "cannot use .* as (type )?int( in slice literal)?|incompatible type"
+	_ = [10]int{t}  // ERROR "cannot use .* as (type )?int( in array literal)?|incompatible type"
+	_ = [...]int{t} // ERROR "cannot use .* as (type )?int( in array literal)?|incompatible type"
 }
diff --git a/test/fixedbugs/issue13471.go b/test/fixedbugs/issue13471.go
index 9069412..cab6bed 100644
--- a/test/fixedbugs/issue13471.go
+++ b/test/fixedbugs/issue13471.go
@@ -9,17 +9,17 @@
 package main
 
 func main() {
-	const _ int64 = 1e646456992 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
-	const _ int32 = 1e64645699  // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
-	const _ int16 = 1e6464569   // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
-	const _ int8 = 1e646456     // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
-	const _ int = 1e64645       // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
+	const _ int64 = 1e646456992 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large|truncated"
+	const _ int32 = 1e64645699  // ERROR "integer too large|floating-point constant truncated to integer|exponent too large|truncated"
+	const _ int16 = 1e6464569   // ERROR "integer too large|floating-point constant truncated to integer|exponent too large|truncated"
+	const _ int8 = 1e646456     // ERROR "integer too large|floating-point constant truncated to integer|exponent too large|truncated"
+	const _ int = 1e64645       // ERROR "integer too large|floating-point constant truncated to integer|exponent too large|truncated"
 
-	const _ uint64 = 1e646456992 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
-	const _ uint32 = 1e64645699  // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
-	const _ uint16 = 1e6464569   // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
-	const _ uint8 = 1e646456     // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
-	const _ uint = 1e64645       // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
+	const _ uint64 = 1e646456992 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large|truncated"
+	const _ uint32 = 1e64645699  // ERROR "integer too large|floating-point constant truncated to integer|exponent too large|truncated"
+	const _ uint16 = 1e6464569   // ERROR "integer too large|floating-point constant truncated to integer|exponent too large|truncated"
+	const _ uint8 = 1e646456     // ERROR "integer too large|floating-point constant truncated to integer|exponent too large|truncated"
+	const _ uint = 1e64645       // ERROR "integer too large|floating-point constant truncated to integer|exponent too large|truncated"
 
-	const _ rune = 1e64645 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
+	const _ rune = 1e64645 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large|truncated"
 }
diff --git a/test/fixedbugs/issue13480.go b/test/fixedbugs/issue13480.go
index cd2f05d..7e859c5 100644
--- a/test/fixedbugs/issue13480.go
+++ b/test/fixedbugs/issue13480.go
@@ -18,21 +18,21 @@
 	var m M
 	var f F
 
-	_ = s == S(nil) // ERROR "compare.*to nil"
-	_ = S(nil) == s // ERROR "compare.*to nil"
+	_ = s == S(nil) // ERROR "compare.*to nil|operator \=\= not defined for .|cannot compare"
+	_ = S(nil) == s // ERROR "compare.*to nil|operator \=\= not defined for .|cannot compare"
 	switch s {
-	case S(nil): // ERROR "compare.*to nil"
+	case S(nil): // ERROR "compare.*to nil|operator \=\= not defined for .|cannot compare"
 	}
 
-	_ = m == M(nil) // ERROR "compare.*to nil"
-	_ = M(nil) == m // ERROR "compare.*to nil"
+	_ = m == M(nil) // ERROR "compare.*to nil|operator \=\= not defined for .|cannot compare"
+	_ = M(nil) == m // ERROR "compare.*to nil|operator \=\= not defined for .|cannot compare"
 	switch m {
-	case M(nil): // ERROR "compare.*to nil"
+	case M(nil): // ERROR "compare.*to nil|operator \=\= not defined for .|cannot compare"
 	}
 
-	_ = f == F(nil) // ERROR "compare.*to nil"
-	_ = F(nil) == f // ERROR "compare.*to nil"
+	_ = f == F(nil) // ERROR "compare.*to nil|operator \=\= not defined for .|cannot compare"
+	_ = F(nil) == f // ERROR "compare.*to nil|operator \=\= not defined for .|cannot compare"
 	switch f {
-	case F(nil): // ERROR "compare.*to nil"
+	case F(nil): // ERROR "compare.*to nil|operator \=\= not defined for .|cannot compare"
 	}
 }
diff --git a/test/fixedbugs/issue13485.go b/test/fixedbugs/issue13485.go
index a9beea1..d928c1e 100644
--- a/test/fixedbugs/issue13485.go
+++ b/test/fixedbugs/issue13485.go
@@ -9,10 +9,10 @@
 var (
 	_ [10]int
 	_ [10.0]int
-	_ [float64(10)]int                // ERROR "invalid array bound"
+	_ [float64(10)]int                // ERROR "invalid array bound|must be integer"
 	_ [10 + 0i]int
 	_ [complex(10, 0)]int
-	_ [complex128(complex(10, 0))]int // ERROR "invalid array bound"
+	_ [complex128(complex(10, 0))]int // ERROR "invalid array bound|must be integer"
 	_ ['a']int
 	_ [rune(65)]int
 )
diff --git a/test/fixedbugs/issue13539.go b/test/fixedbugs/issue13539.go
index 72c3ab0..181fbef 100644
--- a/test/fixedbugs/issue13539.go
+++ b/test/fixedbugs/issue13539.go
@@ -10,7 +10,7 @@
 
 package main
 
-import "math" // ERROR "imported and not used"
+import "math" // ERROR "imported and not used|imported but not used"
 
 func main() {
 math:
diff --git a/test/fixedbugs/issue13559.go b/test/fixedbugs/issue13559.go
index 16de2a2..cc139d5 100644
--- a/test/fixedbugs/issue13559.go
+++ b/test/fixedbugs/issue13559.go
@@ -10,80 +10,80 @@
 package p
 
 // failure case in issue
-const _ int64 = 1e-10000 // ERROR "1e\-10000 truncated"
+const _ int64 = 1e-10000 // ERROR "1e\-10000 truncated|.* truncated to int64|truncated"
 
 const (
-	_ int64 = 1e10000000 // ERROR "integer too large"
-	_ int64 = 1e1000000  // ERROR "integer too large"
-	_ int64 = 1e100000   // ERROR "integer too large"
-	_ int64 = 1e10000    // ERROR "integer too large"
-	_ int64 = 1e1000     // ERROR "integer too large"
-	_ int64 = 1e100      // ERROR "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows"
+	_ int64 = 1e10000000 // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = 1e1000000  // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = 1e100000   // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = 1e10000    // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = 1e1000     // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = 1e100      // ERROR "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows|truncated to int64|truncated"
 	_ int64 = 1e10
 	_ int64 = 1e1
 	_ int64 = 1e0
-	_ int64 = 1e-1       // ERROR "0\.1 truncated"
-	_ int64 = 1e-10      // ERROR "1e\-10 truncated"
-	_ int64 = 1e-100     // ERROR "1e\-100 truncated"
-	_ int64 = 1e-1000    // ERROR "1e\-1000 truncated"
-	_ int64 = 1e-10000   // ERROR "1e\-10000 truncated"
-	_ int64 = 1e-100000  // ERROR "1e\-100000 truncated"
-	_ int64 = 1e-1000000 // ERROR "1e\-1000000 truncated"
+	_ int64 = 1e-1       // ERROR "0\.1 truncated|.* truncated to int64|truncated"
+	_ int64 = 1e-10      // ERROR "1e\-10 truncated|.* truncated to int64|truncated"
+	_ int64 = 1e-100     // ERROR "1e\-100 truncated|.* truncated to int64|truncated"
+	_ int64 = 1e-1000    // ERROR "1e\-1000 truncated|.* truncated to int64|truncated"
+	_ int64 = 1e-10000   // ERROR "1e\-10000 truncated|.* truncated to int64|truncated"
+	_ int64 = 1e-100000  // ERROR "1e\-100000 truncated|.* truncated to int64|truncated"
+	_ int64 = 1e-1000000 // ERROR "1e\-1000000 truncated|.* truncated to int64|truncated"
 )
 
 const (
-	_ int64 = -1e10000000 // ERROR "integer too large"
-	_ int64 = -1e1000000  // ERROR "integer too large"
-	_ int64 = -1e100000   // ERROR "integer too large"
-	_ int64 = -1e10000    // ERROR "integer too large"
-	_ int64 = -1e1000     // ERROR "integer too large"
-	_ int64 = -1e100      // ERROR "\-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows"
+	_ int64 = -1e10000000 // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = -1e1000000  // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = -1e100000   // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = -1e10000    // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = -1e1000     // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = -1e100      // ERROR "\-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows|truncated to int64|truncated"
 	_ int64 = -1e10
 	_ int64 = -1e1
 	_ int64 = -1e0
-	_ int64 = -1e-1       // ERROR "\-0\.1 truncated"
-	_ int64 = -1e-10      // ERROR "\-1e\-10 truncated"
-	_ int64 = -1e-100     // ERROR "\-1e\-100 truncated"
-	_ int64 = -1e-1000    // ERROR "\-1e\-1000 truncated"
-	_ int64 = -1e-10000   // ERROR "\-1e\-10000 truncated"
-	_ int64 = -1e-100000  // ERROR "\-1e\-100000 truncated"
-	_ int64 = -1e-1000000 // ERROR "\-1e\-1000000 truncated"
+	_ int64 = -1e-1       // ERROR "\-0\.1 truncated|.* truncated to int64|truncated"
+	_ int64 = -1e-10      // ERROR "\-1e\-10 truncated|.* truncated to int64|truncated"
+	_ int64 = -1e-100     // ERROR "\-1e\-100 truncated|.* truncated to int64|truncated"
+	_ int64 = -1e-1000    // ERROR "\-1e\-1000 truncated|.* truncated to int64|truncated"
+	_ int64 = -1e-10000   // ERROR "\-1e\-10000 truncated|.* truncated to int64|truncated"
+	_ int64 = -1e-100000  // ERROR "\-1e\-100000 truncated|.* truncated to int64|truncated"
+	_ int64 = -1e-1000000 // ERROR "\-1e\-1000000 truncated|.* truncated to int64|truncated"
 )
 
 const (
-	_ int64 = 1.23456789e10000000 // ERROR "integer too large"
-	_ int64 = 1.23456789e1000000  // ERROR "integer too large"
-	_ int64 = 1.23456789e100000   // ERROR "integer too large"
-	_ int64 = 1.23456789e10000    // ERROR "integer too large"
-	_ int64 = 1.23456789e1000     // ERROR "integer too large"
-	_ int64 = 1.23456789e100      // ERROR "12345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows"
+	_ int64 = 1.23456789e10000000 // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = 1.23456789e1000000  // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = 1.23456789e100000   // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = 1.23456789e10000    // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = 1.23456789e1000     // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = 1.23456789e100      // ERROR "12345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows|truncated to int64|truncated"
 	_ int64 = 1.23456789e10
-	_ int64 = 1.23456789e1        // ERROR "12\.3457 truncated"
-	_ int64 = 1.23456789e0        // ERROR "1\.23457 truncated"
-	_ int64 = 1.23456789e-1       // ERROR "0\.123457 truncated"
-	_ int64 = 1.23456789e-10      // ERROR "1\.23457e\-10 truncated"
-	_ int64 = 1.23456789e-100     // ERROR "1\.23457e\-100 truncated"
-	_ int64 = 1.23456789e-1000    // ERROR "1\.23457e\-1000 truncated"
-	_ int64 = 1.23456789e-10000   // ERROR "1\.23457e\-10000 truncated"
-	_ int64 = 1.23456789e-100000  // ERROR "1\.23457e\-100000 truncated"
-	_ int64 = 1.23456789e-1000000 // ERROR "1\.23457e\-1000000 truncated"
+	_ int64 = 1.23456789e1        // ERROR "12\.3457 truncated|.* truncated to int64|truncated"
+	_ int64 = 1.23456789e0        // ERROR "1\.23457 truncated|.* truncated to int64|truncated"
+	_ int64 = 1.23456789e-1       // ERROR "0\.123457 truncated|.* truncated to int64|truncated"
+	_ int64 = 1.23456789e-10      // ERROR "1\.23457e\-10 truncated|.* truncated to int64|truncated"
+	_ int64 = 1.23456789e-100     // ERROR "1\.23457e\-100 truncated|.* truncated to int64|truncated"
+	_ int64 = 1.23456789e-1000    // ERROR "1\.23457e\-1000 truncated|.* truncated to int64|truncated"
+	_ int64 = 1.23456789e-10000   // ERROR "1\.23457e\-10000 truncated|.* truncated to int64|truncated"
+	_ int64 = 1.23456789e-100000  // ERROR "1\.23457e\-100000 truncated|.* truncated to int64|truncated"
+	_ int64 = 1.23456789e-1000000 // ERROR "1\.23457e\-1000000 truncated|.* truncated to int64|truncated"
 )
 
 const (
-	_ int64 = -1.23456789e10000000 // ERROR "integer too large"
-	_ int64 = -1.23456789e1000000  // ERROR "integer too large"
-	_ int64 = -1.23456789e100000   // ERROR "integer too large"
-	_ int64 = -1.23456789e10000    // ERROR "integer too large"
-	_ int64 = -1.23456789e1000     // ERROR "integer too large"
-	_ int64 = -1.23456789e100      // ERROR "\-12345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows"
+	_ int64 = -1.23456789e10000000 // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = -1.23456789e1000000  // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = -1.23456789e100000   // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = -1.23456789e10000    // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = -1.23456789e1000     // ERROR "integer too large|truncated to int64|truncated"
+	_ int64 = -1.23456789e100      // ERROR "\-12345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows|truncated to int64|truncated"
 	_ int64 = -1.23456789e10
-	_ int64 = -1.23456789e1        // ERROR "\-12\.3457 truncated"
-	_ int64 = -1.23456789e0        // ERROR "\-1\.23457 truncated"
-	_ int64 = -1.23456789e-1       // ERROR "\-0\.123457 truncated"
-	_ int64 = -1.23456789e-10      // ERROR "\-1\.23457e\-10 truncated"
-	_ int64 = -1.23456789e-100     // ERROR "\-1\.23457e\-100 truncated"
-	_ int64 = -1.23456789e-1000    // ERROR "\-1\.23457e\-1000 truncated"
-	_ int64 = -1.23456789e-10000   // ERROR "\-1\.23457e\-10000 truncated"
-	_ int64 = -1.23456789e-100000  // ERROR "\-1\.23457e\-100000 truncated"
-	_ int64 = -1.23456789e-1000000 // ERROR "\-1\.23457e\-1000000 truncated"
+	_ int64 = -1.23456789e1        // ERROR "\-12\.3457 truncated|.* truncated to int64|truncated"
+	_ int64 = -1.23456789e0        // ERROR "\-1\.23457 truncated|.* truncated to int64|truncated"
+	_ int64 = -1.23456789e-1       // ERROR "\-0\.123457 truncated|.* truncated to int64|truncated"
+	_ int64 = -1.23456789e-10      // ERROR "\-1\.23457e\-10 truncated|.* truncated to int64|truncated"
+	_ int64 = -1.23456789e-100     // ERROR "\-1\.23457e\-100 truncated|.* truncated to int64|truncated"
+	_ int64 = -1.23456789e-1000    // ERROR "\-1\.23457e\-1000 truncated|.* truncated to int64|truncated"
+	_ int64 = -1.23456789e-10000   // ERROR "\-1\.23457e\-10000 truncated|.* truncated to int64|truncated"
+	_ int64 = -1.23456789e-100000  // ERROR "\-1\.23457e\-100000 truncated|.* truncated to int64|truncated"
+	_ int64 = -1.23456789e-1000000 // ERROR "\-1\.23457e\-1000000 truncated|.* truncated to int64|truncated"
 )
diff --git a/test/fixedbugs/issue13799.go b/test/fixedbugs/issue13799.go
index fbdd4c3..c8ecfc5 100644
--- a/test/fixedbugs/issue13799.go
+++ b/test/fixedbugs/issue13799.go
@@ -60,7 +60,7 @@
 	}
 
 	if len(m) != maxI {
-		panic(fmt.Sprintf("iter %d: maxI = %d, len(m) = %d", iter, maxI, len(m))) // ERROR "iter escapes to heap$" "len\(m\) escapes to heap$" "maxI escapes to heap$" "... argument does not escape$"
+		panic(fmt.Sprintf("iter %d: maxI = %d, len(m) = %d", iter, maxI, len(m))) // ERROR "iter escapes to heap$" "len\(m\) escapes to heap$" "maxI escapes to heap$" "... argument does not escape$" "fmt.Sprintf\(.*\) escapes to heap"
 	}
 }
 
@@ -84,7 +84,7 @@
 	}
 
 	if len(m) != maxI {
-		panic(fmt.Sprintf("iter %d: maxI = %d, len(m) = %d", iter, maxI, len(m))) // ERROR "iter escapes to heap$" "len\(m\) escapes to heap$" "maxI escapes to heap$" "... argument does not escape$"
+		panic(fmt.Sprintf("iter %d: maxI = %d, len(m) = %d", iter, maxI, len(m))) // ERROR "iter escapes to heap$" "len\(m\) escapes to heap$" "maxI escapes to heap$" "... argument does not escape$" "fmt.Sprintf\(.*\) escapes to heap"
 	}
 }
 
@@ -110,7 +110,7 @@
 	}
 
 	if *m != maxI {
-		panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "... argument does not escape$"
+		panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "... argument does not escape$" "fmt.Sprintf\(.*\) escapes to heap"
 	}
 }
 
@@ -136,7 +136,7 @@
 	}
 
 	if *m != maxI {
-		panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "... argument does not escape$"
+		panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "... argument does not escape$" "fmt.Sprintf\(.*\) escapes to heap"
 	}
 }
 
@@ -167,7 +167,7 @@
 	}
 
 	if *m != maxI {
-		panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "... argument does not escape$"
+		panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "... argument does not escape$" "fmt.Sprintf\(.*\) escapes to heap"
 	}
 }
 
@@ -185,6 +185,6 @@
 	}
 
 	if *m != maxI {
-		panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "... argument does not escape$"
+		panic(fmt.Sprintf("iter %d: maxI = %d, *m = %d", iter, maxI, *m)) // ERROR "\*m escapes to heap$" "iter escapes to heap$" "maxI escapes to heap$" "... argument does not escape$" "fmt.Sprintf\(.*\) escapes to heap"
 	}
 }
diff --git a/test/fixedbugs/issue14136.go b/test/fixedbugs/issue14136.go
index 38308cd..a066d26 100644
--- a/test/fixedbugs/issue14136.go
+++ b/test/fixedbugs/issue14136.go
@@ -15,5 +15,7 @@
 
 func main() {
 	t := T{X: 1, X: 1, X: 1, X: 1, X: 1, X: 1, X: 1, X: 1, X: 1, X: 1} // ERROR "unknown field 'X' in struct literal of type T|unknown field .*X.* in .*T.*"
-	var s string = 1 // ERROR "cannot use 1|incompatible type"
+	_ = t
+	var s string = 1 // ERROR "cannot use 1|incompatible type|cannot convert"
+	_ = s
 }
diff --git a/test/fixedbugs/issue14321.go b/test/fixedbugs/issue14321.go
index e1149c3..0791819 100644
--- a/test/fixedbugs/issue14321.go
+++ b/test/fixedbugs/issue14321.go
@@ -30,4 +30,4 @@
 var _ = C.F // ERROR "ambiguous"
 var _ = C.G // ERROR "ambiguous"
 var _ = C.H // ERROR "ambiguous"
-var _ = C.I // ERROR "no method .*I.*"
+var _ = C.I // ERROR "no method .*I.*|C.I undefined"
diff --git a/test/fixedbugs/issue14729.go b/test/fixedbugs/issue14729.go
index 9b30fd2..e5c8235 100644
--- a/test/fixedbugs/issue14729.go
+++ b/test/fixedbugs/issue14729.go
@@ -10,5 +10,5 @@
 
 import "unsafe"
 
-type s struct { unsafe.Pointer } // ERROR "embedded type cannot be a pointer|embedded type may not be a pointer"
+type s struct { unsafe.Pointer } // ERROR "embedded type cannot be a pointer|embedded type may not be a pointer||embedded field type cannot be unsafe.Pointer"
 type s1 struct { p unsafe.Pointer }
diff --git a/test/fixedbugs/issue15055.go b/test/fixedbugs/issue15055.go
index e58047e..81758d1 100644
--- a/test/fixedbugs/issue15055.go
+++ b/test/fixedbugs/issue15055.go
@@ -8,10 +8,12 @@
 
 func main() {
 	type name string
-	_ = []byte("abc", "def", 12)    // ERROR "too many arguments to conversion to \[\]byte: \(\[\]byte\)\(.abc., .def., 12\)"
-	_ = string("a", "b", nil)       // ERROR "too many arguments to conversion to string: string\(.a., .b., nil\)"
-	_ = []byte()                    // ERROR "missing argument to conversion to \[\]byte: \(\[\]byte\)\(\)"
-	_ = string()                    // ERROR "missing argument to conversion to string: string\(\)"
-	_ = name("a", 1, 3.3)           // ERROR "too many arguments to conversion to name: name\(.a., 1, 3.3\)"
-	_ = map[string]string(nil, nil) // ERROR "too many arguments to conversion to map\[string\]string: \(map\[string\]string\)\(nil, nil\)"
+	_ = []byte("abc", "def", 12)    // ERROR "too many arguments (to conversion to \[\]byte: \(\[\]byte\)\(.abc., .def., 12\))?"
+	_ = string("a", "b", nil)       // ERROR "too many arguments (to conversion to string: string\(.a., .b., nil\))?"
+	_ = []byte()                    // ERROR "missing argument (to conversion to \[\]byte: \(\[\]byte\)\(\))?"
+	_ = string()                    // ERROR "missing argument (to conversion to string: string\(\))?"
+	_ = *int()                      // ERROR "missing argument (to conversion to int: int\(\))?"
+	_ = (*int)()                    // ERROR "missing argument (to conversion to \*int: \(\*int\)\(\))?"
+	_ = name("a", 1, 3.3)           // ERROR "too many arguments (to conversion to name: name\(.a., 1, 3.3\))?"
+	_ = map[string]string(nil, nil) // ERROR "too many arguments (to conversion to map\[string\]string: \(map\[string\]string\)\(nil, nil\))?"
 }
diff --git a/test/fixedbugs/issue15898.go b/test/fixedbugs/issue15898.go
index 94369f9..09f906a 100644
--- a/test/fixedbugs/issue15898.go
+++ b/test/fixedbugs/issue15898.go
@@ -8,11 +8,11 @@
 
 func f(e interface{}) {
 	switch e.(type) {
-	case nil, nil: // ERROR "multiple nil cases in type switch|duplicate type in switch"
+	case nil, nil: // ERROR "multiple nil cases in type switch|duplicate type in switch|duplicate case nil in type switch"
 	}
 
 	switch e.(type) {
 	case nil:
-	case nil: // ERROR "multiple nil cases in type switch|duplicate type in switch"
+	case nil: // ERROR "multiple nil cases in type switch|duplicate type in switch|duplicate case nil in type switch"
 	}
 }
diff --git a/test/fixedbugs/issue16439.go b/test/fixedbugs/issue16439.go
index 704b6b1..77baa1f 100644
--- a/test/fixedbugs/issue16439.go
+++ b/test/fixedbugs/issue16439.go
@@ -7,12 +7,12 @@
 package p
 
 var a []int = []int{1: 1}
-var b []int = []int{-1: 1} // ERROR "must be non-negative integer constant|index expression is negative"
+var b []int = []int{-1: 1} // ERROR "must be non-negative integer constant|index expression is negative|must not be negative"
 
 var c []int = []int{2.0: 2}
-var d []int = []int{-2.0: 2} // ERROR "must be non-negative integer constant|index expression is negative"
+var d []int = []int{-2.0: 2} // ERROR "must be non-negative integer constant|index expression is negative|must not be negative"
 
 var e []int = []int{3 + 0i: 3}
-var f []int = []int{3i: 3} // ERROR "truncated to integer|index expression is not integer constant"
+var f []int = []int{3i: 3} // ERROR "truncated to integer|index expression is not integer constant|truncated to int"
 
-var g []int = []int{"a": 4} // ERROR "must be non-negative integer constant|index expression is not integer constant"
+var g []int = []int{"a": 4} // ERROR "must be non-negative integer constant|index expression is not integer constant|cannot convert"
diff --git a/test/fixedbugs/issue16760.go b/test/fixedbugs/issue16760.go
index d0e08b5..a7eede4 100644
--- a/test/fixedbugs/issue16760.go
+++ b/test/fixedbugs/issue16760.go
@@ -6,7 +6,7 @@
 
 // Make sure we don't start marshaling (writing to the stack)
 // arguments until those arguments are evaluated and known
-// not to unconditinally panic. If they unconditionally panic,
+// not to unconditionally panic. If they unconditionally panic,
 // we write some args but never do the call. That messes up
 // the logic which decides how big the argout section needs to be.
 
diff --git a/test/fixedbugs/issue16949.go b/test/fixedbugs/issue16949.go
index 9ee3387..1007d70 100644
--- a/test/fixedbugs/issue16949.go
+++ b/test/fixedbugs/issue16949.go
@@ -12,19 +12,19 @@
 
 func main() {
 	sink = make([]byte, 1.0)
-	sink = make([]byte, float32(1.0)) // ERROR "non-integer.*len"
-	sink = make([]byte, float64(1.0)) // ERROR "non-integer.*len"
+	sink = make([]byte, float32(1.0)) // ERROR "non-integer.*len|must be integer"
+	sink = make([]byte, float64(1.0)) // ERROR "non-integer.*len|must be integer"
 
 	sink = make([]byte, 0, 1.0)
-	sink = make([]byte, 0, float32(1.0)) // ERROR "non-integer.*cap"
-	sink = make([]byte, 0, float64(1.0)) // ERROR "non-integer.*cap"
+	sink = make([]byte, 0, float32(1.0)) // ERROR "non-integer.*cap|must be integer"
+	sink = make([]byte, 0, float64(1.0)) // ERROR "non-integer.*cap|must be integer"
 
 	sink = make([]byte, 1+0i)
-	sink = make([]byte, complex64(1+0i))  // ERROR "non-integer.*len"
-	sink = make([]byte, complex128(1+0i)) // ERROR "non-integer.*len"
+	sink = make([]byte, complex64(1+0i))  // ERROR "non-integer.*len|must be integer"
+	sink = make([]byte, complex128(1+0i)) // ERROR "non-integer.*len|must be integer"
 
 	sink = make([]byte, 0, 1+0i)
-	sink = make([]byte, 0, complex64(1+0i))  // ERROR "non-integer.*cap"
-	sink = make([]byte, 0, complex128(1+0i)) // ERROR "non-integer.*cap"
+	sink = make([]byte, 0, complex64(1+0i))  // ERROR "non-integer.*cap|must be integer"
+	sink = make([]byte, 0, complex128(1+0i)) // ERROR "non-integer.*cap|must be integer"
 
 }
diff --git a/test/fixedbugs/issue17588.go b/test/fixedbugs/issue17588.go
index 0e3a14e..5c0787b 100644
--- a/test/fixedbugs/issue17588.go
+++ b/test/fixedbugs/issue17588.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -11,10 +11,10 @@
 
 package p
 
-type F func(b T)  // ERROR "T is not a type|expected type"
+type F func(b T) // ERROR "T .*is not a type|expected type"
 
 func T(fn F) {
-    func() {
-        fn(nil)  // If Decldepth is not initialized properly, typecheckclosure() Fatals here.
-    }()
+	func() {
+		fn(nil) // If Decldepth is not initialized properly, typecheckclosure() Fatals here.
+	}()
 }
diff --git a/test/fixedbugs/issue18392.go b/test/fixedbugs/issue18392.go
index 053a337..e0640ed 100644
--- a/test/fixedbugs/issue18392.go
+++ b/test/fixedbugs/issue18392.go
@@ -10,5 +10,5 @@
 	// TODO(mdempsky): This should be an error, but this error is
 	// nonsense. The error should actually mention that there's a
 	// type loop.
-	Fn(A.Fn) // ERROR "type A has no method Fn"
+	Fn(A.Fn) // ERROR "type A has no method Fn|A.Fn undefined"
 }
diff --git a/test/fixedbugs/issue19323.go b/test/fixedbugs/issue19323.go
index 71365e1..77cac3e 100644
--- a/test/fixedbugs/issue19323.go
+++ b/test/fixedbugs/issue19323.go
@@ -9,11 +9,11 @@
 func g() {}
 
 func f() {
-	g()[:] // ERROR "g.. used as value|attempt to slice object that is not"
+	g()[:] // ERROR "g.* used as value|attempt to slice object that is not"
 }
 
 func g2() ([]byte, []byte) { return nil, nil }
 
 func f2() {
-	g2()[:] // ERROR "multiple-value g2.. in single-value context|attempt to slice object that is not"
+	g2()[:] // ERROR "multiple-value g2.. in single-value context|attempt to slice object that is not|2\-valued g"
 }
diff --git a/test/fixedbugs/issue19482.go b/test/fixedbugs/issue19482.go
index 4c2c19e..ee0d340 100644
--- a/test/fixedbugs/issue19482.go
+++ b/test/fixedbugs/issue19482.go
@@ -22,13 +22,13 @@
 
 var (
 	y = T{"stare"}
-	w = T{_: "look"} // ERROR "invalid field name _ in struct initializer|expected struct field name"
+	w = T{_: "look"} // ERROR "invalid field name _ in struct initializer|expected struct field name|unknown field '_' in struct literal of type T"
 	_ = T{"page"}
-	_ = T{_: "out"} // ERROR "invalid field name _ in struct initializer|expected struct field name"
+	_ = T{_: "out"} // ERROR "invalid field name _ in struct initializer|expected struct field name|unknown field '_' in struct literal of type T"
 )
 
 func bad() {
-	var z = T{_: "verse"} // ERROR "invalid field name _ in struct initializer|expected struct field name"
+	var z = T{_: "verse"} // ERROR "invalid field name _ in struct initializer|expected struct field name|unknown field '_' in struct literal of type T"
 	_ = z
-	_ = T{_: "itinerary"} // ERROR "invalid field name _ in struct initializer|expected struct field name"
+	_ = T{_: "itinerary"} // ERROR "invalid field name _ in struct initializer|expected struct field name|unknown field '_' in struct literal of type T"
 }
diff --git a/test/fixedbugs/issue19699b.go b/test/fixedbugs/issue19699b.go
index 4afc0ca..32ed30f 100644
--- a/test/fixedbugs/issue19699b.go
+++ b/test/fixedbugs/issue19699b.go
@@ -11,4 +11,4 @@
 	} else {
 		return true
 	}
-} // ERROR "missing return at end of function"
+} // ERROR "missing return( at end of function)?"
diff --git a/test/fixedbugs/issue19880.go b/test/fixedbugs/issue19880.go
index 3d83cf3..57cdc93 100644
--- a/test/fixedbugs/issue19880.go
+++ b/test/fixedbugs/issue19880.go
@@ -11,7 +11,7 @@
 }
 
 func a() {
-	_ = T // ERROR "type T is not an expression|invalid use of type"
+	_ = T // ERROR "type T is not an expression|invalid use of type|not an expression"
 }
 
 func b() {
diff --git a/test/fixedbugs/issue19947.go b/test/fixedbugs/issue19947.go
index 3233469..752cfc6 100644
--- a/test/fixedbugs/issue19947.go
+++ b/test/fixedbugs/issue19947.go
@@ -8,8 +8,8 @@
 
 package issue19947
 
-var _ = float32(1) * 1e200 // ERROR "constant 1e\+200 overflows float32"
-var _ = float64(1) * 1e500 // ERROR "constant 1e\+500 overflows float64"
+var _ = float32(1) * 1e200 // ERROR "constant 1e\+200 overflows float32|1e200 .* overflows float32"
+var _ = float64(1) * 1e500 // ERROR "constant 1e\+500 overflows float64|1e500 .* overflows float64"
 
-var _ = complex64(1) * 1e200  // ERROR "constant 1e\+200 overflows complex64"
-var _ = complex128(1) * 1e500 // ERROR "constant 1e\+500 overflows complex128"
+var _ = complex64(1) * 1e200  // ERROR "constant 1e\+200 overflows complex64|1e200 .* overflows complex64"
+var _ = complex128(1) * 1e500 // ERROR "constant 1e\+500 overflows complex128|1e500 .* overflows complex128"
diff --git a/test/fixedbugs/issue20014.dir/a/a.go b/test/fixedbugs/issue20014.dir/a/a.go
new file mode 100644
index 0000000..1e66326
--- /dev/null
+++ b/test/fixedbugs/issue20014.dir/a/a.go
@@ -0,0 +1,21 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+type T struct {
+	X int `go:"track"`
+	Y int `go:"track"`
+	Z int // untracked
+}
+
+func (t *T) GetX() int {
+	return t.X
+}
+func (t *T) GetY() int {
+	return t.Y
+}
+func (t *T) GetZ() int {
+	return t.Z
+}
diff --git a/test/fixedbugs/issue20014.dir/main.go b/test/fixedbugs/issue20014.dir/main.go
new file mode 100644
index 0000000..ac9957d
--- /dev/null
+++ b/test/fixedbugs/issue20014.dir/main.go
@@ -0,0 +1,54 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"strings"
+
+	"issue20014.dir/a"
+)
+
+func main() {
+	samePackage()
+	crossPackage()
+	// Print fields registered with field tracking.
+	for _, line := range strings.Split(fieldTrackInfo, "\n") {
+		if line == "" {
+			continue
+		}
+		println(strings.Split(line, "\t")[0])
+	}
+}
+
+type T struct {
+	X int `go:"track"`
+	Y int `go:"track"`
+	Z int // untracked
+}
+
+func (t *T) GetX() int {
+	return t.X
+}
+func (t *T) GetY() int {
+	return t.Y
+}
+func (t *T) GetZ() int {
+	return t.Z
+}
+
+func samePackage() {
+	var t T
+	println(t.GetX())
+	println(t.GetZ())
+}
+
+func crossPackage() {
+	var t a.T
+	println(t.GetX())
+	println(t.GetZ())
+}
+
+// This global variable is set by the linker using the -k option.
+var fieldTrackInfo string
diff --git a/test/fixedbugs/issue20014.go b/test/fixedbugs/issue20014.go
new file mode 100644
index 0000000..e186aa1
--- /dev/null
+++ b/test/fixedbugs/issue20014.go
@@ -0,0 +1,7 @@
+// runindir -goexperiment fieldtrack -ldflags -k=main.fieldTrackInfo
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue20014.out b/test/fixedbugs/issue20014.out
new file mode 100644
index 0000000..252e78d
--- /dev/null
+++ b/test/fixedbugs/issue20014.out
@@ -0,0 +1,6 @@
+0
+0
+0
+0
+main.T.X
+issue20014.dir/a.T.X
diff --git a/test/fixedbugs/issue20185.go b/test/fixedbugs/issue20185.go
index 9065868..ee60cab 100644
--- a/test/fixedbugs/issue20185.go
+++ b/test/fixedbugs/issue20185.go
@@ -10,7 +10,7 @@
 package p
 
 func F() {
-	switch t := nil.(type) { // ERROR "cannot type switch on non-interface value"
+	switch t := nil.(type) { // ERROR "cannot type switch on non-interface value|not an interface"
 	default:
 		_ = t
 	}
@@ -19,7 +19,7 @@
 const x = 1
 
 func G() {
-	switch t := x.(type) { // ERROR "cannot type switch on non-interface value|declared but not used"
+	switch t := x.(type) { // ERROR "cannot type switch on non-interface value|declared but not used|not an interface"
 	default:
 	}
 }
diff --git a/test/fixedbugs/issue20232.go b/test/fixedbugs/issue20232.go
index f91c749..846843d 100644
--- a/test/fixedbugs/issue20232.go
+++ b/test/fixedbugs/issue20232.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2017 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -6,6 +6,7 @@
 
 package main
 
-const _ = 6e5518446744 // ERROR "malformed constant: 6e5518446744 \(exponent overflow\)"
+const x = 6e5518446744 // ERROR "malformed constant: 6e5518446744"
+const _ = x * x
 const _ = 1e-1000000000
-const _ = 1e+1000000000 // ERROR "constant too large"
+const _ = 1e+1000000000 // ERROR "malformed constant: 1e\+1000000000"
diff --git a/test/fixedbugs/issue20245.go b/test/fixedbugs/issue20245.go
index b07dbe2..2025823 100644
--- a/test/fixedbugs/issue20245.go
+++ b/test/fixedbugs/issue20245.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2017 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/issue20250.go b/test/fixedbugs/issue20250.go
index c190515..1a513be 100644
--- a/test/fixedbugs/issue20250.go
+++ b/test/fixedbugs/issue20250.go
@@ -1,4 +1,4 @@
-// errorcheck -0 -live -l -d=compilelater
+// errorcheck -0 -live -l
 
 // Copyright 2017 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/issue20415.go b/test/fixedbugs/issue20415.go
index 9e7649f..71f34bb 100644
--- a/test/fixedbugs/issue20415.go
+++ b/test/fixedbugs/issue20415.go
@@ -11,7 +11,7 @@
 // 1
 var f byte
 
-var f interface{} // ERROR "previous declaration at issue20415.go:12|redefinition"
+var f interface{} // ERROR "issue20415.go:12: previous declaration|redefinition|f redeclared"
 
 func _(f int) {
 }
@@ -22,7 +22,7 @@
 func _(g int) {
 }
 
-var g interface{} // ERROR "previous declaration at issue20415.go:20|redefinition"
+var g interface{} // ERROR "issue20415.go:20: previous declaration|redefinition|g redeclared"
 
 // 3
 func _(h int) {
@@ -30,4 +30,4 @@
 
 var h byte
 
-var h interface{} // ERROR "previous declaration at issue20415.go:31|redefinition"
+var h interface{} // ERROR "issue20415.go:31: previous declaration|redefinition|h redeclared"
diff --git a/test/fixedbugs/issue20749.go b/test/fixedbugs/issue20749.go
index de2d3ad..2ca1f43 100644
--- a/test/fixedbugs/issue20749.go
+++ b/test/fixedbugs/issue20749.go
@@ -9,7 +9,7 @@
 // Verify that the compiler complains even if the array
 // has length 0.
 var a [0]int
-var _ = a[2:] // ERROR "invalid slice index 2|array index out of bounds"
+var _ = a[2:] // ERROR "invalid slice index 2|array index out of bounds|index 2 out of bounds"
 
 var b [1]int
-var _ = b[2:] // ERROR "invalid slice index 2|array index out of bounds"
+var _ = b[2:] // ERROR "invalid slice index 2|array index out of bounds|index 2 out of bounds"
diff --git a/test/fixedbugs/issue20780.go b/test/fixedbugs/issue20780.go
index 53c4f61..f73e6d1 100644
--- a/test/fixedbugs/issue20780.go
+++ b/test/fixedbugs/issue20780.go
@@ -9,11 +9,17 @@
 
 package main
 
+type Big = [400e6]byte
+
 func f() { // GC_ERROR "stack frame too large"
-	var x [800e6]byte
-	g(x)
-	return
+	// Note: This test relies on the fact that we currently always
+	// spill function-results to the stack, even if they're so
+	// large that we would normally heap allocate them. If we ever
+	// improve the backend to spill temporaries to the heap, this
+	// test will probably need updating to find some new way to
+	// construct an overly large stack frame.
+	g(h(), h())
 }
 
-//go:noinline
-func g([800e6]byte) {}
+func g(Big, Big)
+func h() Big
diff --git a/test/fixedbugs/issue20780b.go b/test/fixedbugs/issue20780b.go
new file mode 100644
index 0000000..c8bf1f8
--- /dev/null
+++ b/test/fixedbugs/issue20780b.go
@@ -0,0 +1,62 @@
+// +build cgo,linux,amd64
+// run -race
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that CL 281293 doesn't interfere with race detector
+// instrumentation.
+
+package main
+
+import "fmt"
+
+const N = 2e6
+
+type Big = [N]int
+
+var sink interface{}
+
+func main() {
+	g(0, f(0))
+
+	x1 := f(1)
+	sink = &x1
+	g(1, x1)
+	g(7, f(7))
+	g(1, x1)
+
+	x3 := f(3)
+	sink = &x3
+	g(1, x1)
+	g(3, x3)
+
+	h(f(0), x1, f(2), x3, f(4))
+}
+
+//go:noinline
+func f(k int) (x Big) {
+	for i := range x {
+		x[i] = k*N + i
+	}
+	return
+}
+
+//go:noinline
+func g(k int, x Big) {
+	for i := range x {
+		if x[i] != k*N+i {
+			panic(fmt.Sprintf("x%d[%d] = %d", k, i, x[i]))
+		}
+	}
+}
+
+//go:noinline
+func h(x0, x1, x2, x3, x4 Big) {
+	g(0, x0)
+	g(1, x1)
+	g(2, x2)
+	g(3, x3)
+	g(4, x4)
+}
diff --git a/test/fixedbugs/issue22389.go b/test/fixedbugs/issue22389.go
index 706b449..81e6d94 100644
--- a/test/fixedbugs/issue22389.go
+++ b/test/fixedbugs/issue22389.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2017 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -14,5 +14,5 @@
 
 func main() {
 	f := &Foo{}
-	f.Call(func(f) {}) // ERROR "f is not a type"
+	f.Call(func(f) {}) // ERROR "f .*is not a type"
 }
diff --git a/test/fixedbugs/issue22794.go b/test/fixedbugs/issue22794.go
index 2ac31ef..e13e470 100644
--- a/test/fixedbugs/issue22794.go
+++ b/test/fixedbugs/issue22794.go
@@ -17,4 +17,5 @@
 	}
 	i2 := &it{floats: false} // ERROR "(but does have Floats)|unknown field|declared but not used"
 	_ = &it{InneR: "foo"}    // ERROR "(but does have inner)|unknown field"
+	_ = i2
 }
diff --git a/test/fixedbugs/issue22822.go b/test/fixedbugs/issue22822.go
index ea53452..9483c9c 100644
--- a/test/fixedbugs/issue22822.go
+++ b/test/fixedbugs/issue22822.go
@@ -11,6 +11,9 @@
 
 func F() {
 	slice := []int{1, 2, 3}
+	_ = slice
 	len := int(2)
-	println(len(slice)) // ERROR "cannot call non-function len .type int., declared at|expected function"
+	println(len(slice)) // ERROR "cannot call non-function len .type int., declared at LINE-1|expected function|cannot call non-function len"
+	const iota = 1
+	println(iota(slice)) // ERROR "cannot call non-function iota .type int., declared at LINE-1|expected function|cannot call non-function iota"
 }
diff --git a/test/fixedbugs/issue22921.go b/test/fixedbugs/issue22921.go
index 5336ba3..cdd77fb 100644
--- a/test/fixedbugs/issue22921.go
+++ b/test/fixedbugs/issue22921.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2020 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/issue23017.go b/test/fixedbugs/issue23017.go
new file mode 100644
index 0000000..770c48e
--- /dev/null
+++ b/test/fixedbugs/issue23017.go
@@ -0,0 +1,113 @@
+// run
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// assignment order in multiple assignments.
+// See issue #23017
+
+package main
+
+import "fmt"
+
+func main() {}
+
+func init() {
+	var m = map[int]int{}
+	var p *int
+
+	defer func() {
+		recover()
+		check(1, len(m))
+		check(42, m[2])
+	}()
+	m[2], *p = 42, 2
+}
+
+func init() {
+	var m = map[int]int{}
+	p := []int{}
+
+	defer func() {
+		recover()
+		check(1, len(m))
+		check(2, m[2])
+	}()
+	m[2], p[1] = 2, 2
+}
+
+func init() {
+	type P struct{ i int }
+	var m = map[int]int{}
+	var p *P
+
+	defer func() {
+		recover()
+		check(1, len(m))
+		check(3, m[2])
+	}()
+	m[2], p.i = 3, 2
+}
+
+func init() {
+	type T struct{ i int }
+	var x T
+	p := &x
+	p, p.i = new(T), 4
+	check(4, x.i)
+}
+
+func init() {
+	var m map[int]int
+	var a int
+	var p = &a
+
+	defer func() {
+		recover()
+		check(5, *p)
+	}()
+	*p, m[2] = 5, 2
+}
+
+var g int
+
+func init() {
+	var m map[int]int
+	defer func() {
+		recover()
+		check(0, g)
+	}()
+	m[0], g = 1, 2
+}
+
+func init() {
+	type T struct{ x struct{ y int } }
+	var x T
+	p := &x
+	p, p.x.y = new(T), 7
+	check(7, x.x.y)
+	check(0, p.x.y)
+}
+
+func init() {
+	type T *struct{ x struct{ y int } }
+	x := struct{ y int }{0}
+	var q T = &struct{ x struct{ y int } }{x}
+	p := q
+	p, p.x.y = nil, 7
+	check(7, q.x.y)
+}
+
+func init() {
+	x, y := 1, 2
+	x, y = y, x
+	check(2, x)
+	check(1, y)
+}
+
+func check(want, got int) {
+	if want != got {
+		panic(fmt.Sprintf("wanted %d, but got %d", want, got))
+	}
+}
diff --git a/test/fixedbugs/issue23094.go b/test/fixedbugs/issue23094.go
index 415556f..853b19b 100644
--- a/test/fixedbugs/issue23094.go
+++ b/test/fixedbugs/issue23094.go
@@ -8,4 +8,4 @@
 
 package p
 
-var a [len(a)]int // ERROR "\[len\(a\)\]int"
+var a [len(a)]int // ERROR "\[len\(a\)\]int|initialization loop"
diff --git a/test/fixedbugs/issue23587.go b/test/fixedbugs/issue23587.go
index bd5df27..2308992 100644
--- a/test/fixedbugs/issue23587.go
+++ b/test/fixedbugs/issue23587.go
@@ -6,7 +6,10 @@
 
 package p
 
-func f(x int) {
-	_ = ~x    // ERROR "invalid character"
-	_ = x ~ x // ERROR "invalid character" "unexpected x at end of statement"
+func _(x int) {
+	_ = ~x    // ERROR "unexpected ~"
+}
+
+func _(x int) {
+	_ = x ~ x // ERROR "unexpected ~ at end of statement"
 }
diff --git a/test/fixedbugs/issue23609.go b/test/fixedbugs/issue23609.go
index 7c17a98..9130e8d 100644
--- a/test/fixedbugs/issue23609.go
+++ b/test/fixedbugs/issue23609.go
@@ -21,7 +21,7 @@
 }
 
 var (
-	_ = t2{t1f1: 600} // ERROR "cannot use promoted field t1.t1f1 in struct literal of type t2"
-	_ = t3{t1f2: 800} // ERROR "cannot use promoted field t2.t1.t1f2 in struct literal of type t3"
-	_ = t3{t2f1: 900} // ERROR "cannot use promoted field t2.t2f1 in struct literal of type t3"
+	_ = t2{t1f1: 600} // ERROR "cannot use promoted field t1.t1f1 in struct literal of type t2|unknown field"
+	_ = t3{t1f2: 800} // ERROR "cannot use promoted field t2.t1.t1f2 in struct literal of type t3|unknown field"
+	_ = t3{t2f1: 900} // ERROR "cannot use promoted field t2.t2f1 in struct literal of type t3|unknown field"
 )
diff --git a/test/fixedbugs/issue23823.go b/test/fixedbugs/issue23823.go
index 067a8f1..c53415f 100644
--- a/test/fixedbugs/issue23823.go
+++ b/test/fixedbugs/issue23823.go
@@ -11,6 +11,6 @@
 }
 
 // BAD: type loop should mention I1; see also #41669
-type I2 interface { // GC_ERROR "invalid recursive type I2\n\tLINE: I2 refers to\n\tLINE: I2$"
+type I2 interface { // GC_ERROR "invalid recursive type I2\n\tLINE: I2 refers to\n\tLINE: I2$|invalid recursive type I2"
 	I1 // GCCGO_ERROR "invalid recursive interface"
 }
diff --git a/test/fixedbugs/issue24470.go b/test/fixedbugs/issue24470.go
index d0e5e23..5b7b2b5 100644
--- a/test/fixedbugs/issue24470.go
+++ b/test/fixedbugs/issue24470.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2018 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -10,6 +10,7 @@
 package p
 
 func f(i interface{}) {
-	if x, ok := i.(type); ok { // ERROR "outside type switch"
+	if x, ok := i.(type); ok { // ERROR "assignment mismatch|outside type switch"
+		_ = x
 	}
 }
diff --git a/test/fixedbugs/issue25727.go b/test/fixedbugs/issue25727.go
index 936b9f8..5599a83 100644
--- a/test/fixedbugs/issue25727.go
+++ b/test/fixedbugs/issue25727.go
@@ -9,13 +9,13 @@
 import "net/http"
 
 var s = http.Server{}
-var _ = s.doneChan                  // ERROR "s.doneChan undefined .cannot refer to unexported field or method doneChan.$|unexported field or method"
+var _ = s.doneChan                  // ERROR "s.doneChan undefined .cannot refer to unexported field or method doneChan.$|unexported field or method|s.doneChan undefined"
 var _ = s.DoneChan                  // ERROR "s.DoneChan undefined .type http.Server has no field or method DoneChan.$|undefined field or method"
-var _ = http.Server{tlsConfig: nil} // ERROR "unknown field 'tlsConfig' in struct literal.+ .but does have TLSConfig.$|unknown field .?tlsConfig.? in .?http.Server"
+var _ = http.Server{tlsConfig: nil} // ERROR "unknown field 'tlsConfig' in struct literal.+ .but does have TLSConfig.$|unknown field .?tlsConfig.? in .?http.Server|unknown field"
 var _ = http.Server{DoneChan: nil}  // ERROR "unknown field 'DoneChan' in struct literal of type http.Server$|unknown field .?DoneChan.? in .?http.Server"
 
 type foo struct {
 	bar int
 }
 
-var _ = &foo{bAr: 10} // ERROR "unknown field 'bAr' in struct literal.+ .but does have bar.$|unknown field .?bAr.? in .?foo"
+var _ = &foo{bAr: 10} // ERROR "unknown field 'bAr' in struct literal.+ .but does have bar.$|unknown field .?bAr.? in .?foo|unknown field"
diff --git a/test/fixedbugs/issue26163.go b/test/fixedbugs/issue26163.go
index 3f3d778..d141a27 100644
--- a/test/fixedbugs/issue26163.go
+++ b/test/fixedbugs/issue26163.go
@@ -1,4 +1,4 @@
-// compile -N -d=softfloat
+// compile -N -d=softfloat -goexperiment noregabiargs
 
 // Copyright 2018 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/issue26616.go b/test/fixedbugs/issue26616.go
index 87c0293..d5210e8 100644
--- a/test/fixedbugs/issue26616.go
+++ b/test/fixedbugs/issue26616.go
@@ -6,14 +6,13 @@
 
 package p
 
-var x int = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values|multiple-value function call in single-value context"
+var x int = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values|multiple-value function call in single-value context|3\-valued"
 
 func f() {
-	var _ int = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values|multiple-value function call in single-value context"
-	var a int = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values|multiple-value function call in single-value context"
-	a = three()         // ERROR "assignment mismatch: 1 variable but three returns 3 values|multiple-value function call in single-value context"
-	b := three()        // ERROR "assignment mismatch: 1 variable but three returns 3 values|single variable set to multiple-value|multiple-value function call in single-value context"
-
+	var _ int = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values|multiple-value function call in single-value context|3\-valued"
+	var a int = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values|multiple-value function call in single-value context|3\-valued"
+	a = three()         // ERROR "assignment mismatch: 1 variable but three returns 3 values|multiple-value function call in single-value context|cannot assign"
+	b := three()        // ERROR "assignment mismatch: 1 variable but three returns 3 values|single variable set to multiple-value|multiple-value function call in single-value context|cannot initialize"
 	_, _ = a, b
 }
 
diff --git a/test/fixedbugs/issue27595.go b/test/fixedbugs/issue27595.go
index af5c7a1..2fc0eb2 100644
--- a/test/fixedbugs/issue27595.go
+++ b/test/fixedbugs/issue27595.go
@@ -6,9 +6,9 @@
 
 package main
 
-var a = twoResults()       // ERROR "assignment mismatch: 1 variable but twoResults returns 2 values"
-var b, c, d = twoResults() // ERROR "assignment mismatch: 3 variables but twoResults returns 2 values"
-var e, f = oneResult()     // ERROR "assignment mismatch: 2 variables but oneResult returns 1 values"
+var a = twoResults()       // ERROR "assignment mismatch: 1 variable but twoResults returns 2 values|2\-valued"
+var b, c, d = twoResults() // ERROR "assignment mismatch: 3 variables but twoResults returns 2 values|cannot initialize"
+var e, f = oneResult()     // ERROR "assignment mismatch: 2 variables but oneResult returns 1 value|cannot initialize"
 
 func twoResults() (int, int) {
 	return 1, 2
diff --git a/test/fixedbugs/issue27938.go b/test/fixedbugs/issue27938.go
index ed974e6..2589e1e 100644
--- a/test/fixedbugs/issue27938.go
+++ b/test/fixedbugs/issue27938.go
@@ -1,4 +1,4 @@
-// errorcheck
+// errorcheck -d=panic
 
 // Copyright 2018 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/issue28079b.go b/test/fixedbugs/issue28079b.go
index d1992e1..54c9db9 100644
--- a/test/fixedbugs/issue28079b.go
+++ b/test/fixedbugs/issue28079b.go
@@ -13,5 +13,5 @@
 type T [uintptr(unsafe.Pointer(nil))]int // ERROR "non-constant array bound|array bound is not constant"
 
 func f() {
-	_ = complex(1<<uintptr(unsafe.Pointer(nil)), 0) // GCCGO_ERROR "non-integer type for left operand of shift"
+	_ = complex(1<<uintptr(unsafe.Pointer(nil)), 0) // ERROR "shift of type float64|non-integer type for left operand of shift"
 }
diff --git a/test/fixedbugs/issue28079c.go b/test/fixedbugs/issue28079c.go
index dfac8d0..f6954ed 100644
--- a/test/fixedbugs/issue28079c.go
+++ b/test/fixedbugs/issue28079c.go
@@ -11,5 +11,5 @@
 import "unsafe"
 
 func f() {
-	_ = complex(1<<uintptr(unsafe.Pointer(nil)), 0) // ERROR "invalid operation: .*shift of type float64.*|non-integer type for left operand of shift"
+	_ = complex(1<<uintptr(unsafe.Pointer(nil)), 0) // ERROR "invalid operation: .*shift of type float64.*|non-integer type for left operand of shift|shifted operand .* must be integer"
 }
diff --git a/test/fixedbugs/issue28450.go b/test/fixedbugs/issue28450.go
index 2acfe39..ca7ba14 100644
--- a/test/fixedbugs/issue28450.go
+++ b/test/fixedbugs/issue28450.go
@@ -6,13 +6,13 @@
 
 package p
 
-func f(a, b, c, d ...int)       {} // ERROR "non-final parameter a|only permits one name"
-func g(a ...int, b ...int)      {} // ERROR "non-final parameter a|must be last parameter"
-func h(...int, ...int, float32) {} // ERROR "non-final parameter|must be last parameter"
+func f(a, b, c, d ...int)       {} // ERROR "non-final parameter a|only permits one name|can only use ... with final parameter"
+func g(a ...int, b ...int)      {} // ERROR "non-final parameter a|must be last parameter|can only use ... with final parameter"
+func h(...int, ...int, float32) {} // ERROR "non-final parameter|must be last parameter|can only use ... with final parameter"
 
-type a func(...float32, ...interface{}) // ERROR "non-final parameter|must be last parameter"
+type a func(...float32, ...interface{}) // ERROR "non-final parameter|must be last parameter|can only use ... with final parameter"
 type b interface {
-	f(...int, ...int)                // ERROR "non-final parameter|must be last parameter"
-	g(a ...int, b ...int, c float32) // ERROR "non-final parameter a|must be last parameter"
+	f(...int, ...int)                // ERROR "non-final parameter|must be last parameter|can only use ... with final parameter"
+	g(a ...int, b ...int, c float32) // ERROR "non-final parameter a|must be last parameter|can only use ... with final parameter"
 	valid(...int)
 }
diff --git a/test/fixedbugs/issue28688.go b/test/fixedbugs/issue28688.go
index 0d2000e..8ef0802 100644
--- a/test/fixedbugs/issue28688.go
+++ b/test/fixedbugs/issue28688.go
@@ -1,4 +1,4 @@
-// run -gcflags=-d=softfloat
+// run -gcflags=-d=softfloat -goexperiment noregabiargs
 
 // Copyright 2018 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/issue30085.go b/test/fixedbugs/issue30085.go
index d2ac4cf..512355a 100644
--- a/test/fixedbugs/issue30085.go
+++ b/test/fixedbugs/issue30085.go
@@ -7,6 +7,7 @@
 package main
 
 func main() {
-	var c, d = 1, 2, 3 // ERROR "assignment mismatch: 2 variables but 3 values|wrong number of initializations"
-	var e, f, g = 1, 2 // ERROR "assignment mismatch: 3 variables but 2 values|wrong number of initializations"
+	var c, d = 1, 2, 3 // ERROR "assignment mismatch: 2 variables but 3 values|wrong number of initializations|extra init expr"
+	var e, f, g = 1, 2 // ERROR "assignment mismatch: 3 variables but 2 values|wrong number of initializations|missing init expr"
+	_, _, _, _ = c, d, e, f
 }
diff --git a/test/fixedbugs/issue30087.go b/test/fixedbugs/issue30087.go
index 3ad9c8c..3e4b032 100644
--- a/test/fixedbugs/issue30087.go
+++ b/test/fixedbugs/issue30087.go
@@ -7,8 +7,9 @@
 package main
 
 func main() {
-	var a, b = 1    // ERROR "assignment mismatch: 2 variables but 1 values|wrong number of initializations"
-	_ = 1, 2        // ERROR "assignment mismatch: 1 variables but 2 values|number of variables does not match"
-	c, d := 1       // ERROR "assignment mismatch: 2 variables but 1 values|wrong number of initializations"
-	e, f := 1, 2, 3 // ERROR "assignment mismatch: 2 variables but 3 values|wrong number of initializations"
+	var a, b = 1    // ERROR "assignment mismatch: 2 variables but 1 value|wrong number of initializations|cannot initialize"
+	_ = 1, 2        // ERROR "assignment mismatch: 1 variable but 2 values|number of variables does not match|cannot assign"
+	c, d := 1       // ERROR "assignment mismatch: 2 variables but 1 value|wrong number of initializations|cannot initialize"
+	e, f := 1, 2, 3 // ERROR "assignment mismatch: 2 variables but 3 values|wrong number of initializations|cannot initialize"
+	_, _, _, _ = c, d, e, f
 }
diff --git a/test/fixedbugs/issue31053.dir/main.go b/test/fixedbugs/issue31053.dir/main.go
index 895c262..3bc75d1 100644
--- a/test/fixedbugs/issue31053.dir/main.go
+++ b/test/fixedbugs/issue31053.dir/main.go
@@ -35,8 +35,8 @@
 	_ = f.Exported
 	_ = f.exported    // ERROR "f.exported undefined .type f1.Foo has no field or method exported, but does have Exported."
 	_ = f.Unexported  // ERROR "f.Unexported undefined .type f1.Foo has no field or method Unexported."
-	_ = f.unexported  // ERROR "f.unexported undefined .cannot refer to unexported field or method f1..\*Foo..unexported."
-	f.unexported = 10 // ERROR "f.unexported undefined .cannot refer to unexported field or method f1..\*Foo..unexported."
-	f.unexported()    // ERROR "f.unexported undefined .cannot refer to unexported field or method f1..\*Foo..unexported."
+	_ = f.unexported  // ERROR "f.unexported undefined .cannot refer to unexported field or method unexported."
+	f.unexported = 10 // ERROR "f.unexported undefined .cannot refer to unexported field or method unexported."
+	f.unexported()    // ERROR "f.unexported undefined .cannot refer to unexported field or method unexported."
 	_ = f.hook        // ERROR "f.hook undefined .cannot refer to unexported field or method hook."
 }
diff --git a/test/fixedbugs/issue31747.go b/test/fixedbugs/issue31747.go
index 420fe30..319a721 100644
--- a/test/fixedbugs/issue31747.go
+++ b/test/fixedbugs/issue31747.go
@@ -8,7 +8,7 @@
 
 // numeric literals
 const (
-	_ = 1_000 // ERROR "underscores in numeric literals requires go1.13 or later \(-lang was set to go1.12; check go.mod\)"
+	_ = 1_000 // ERROR "underscores in numeric literals requires go1.13 or later \(-lang was set to go1.12; check go.mod\)|requires go1.13"
 	_ = 0b111 // ERROR "binary literals requires go1.13 or later"
 	_ = 0o567 // ERROR "0o/0O-style octal literals requires go1.13 or later"
 	_ = 0xabc // ok
@@ -29,6 +29,6 @@
 // signed shift counts
 var (
 	s int
-	_ = 1 << s // ERROR "invalid operation: 1 << s \(signed shift count type int\) requires go1.13 or later"
+	_ = 1 << s // ERROR "invalid operation: 1 << s \(signed shift count type int\) requires go1.13 or later|signed shift count"
 	_ = 1 >> s // ERROR "signed shift count"
 )
diff --git a/test/fixedbugs/issue35291.go b/test/fixedbugs/issue35291.go
index 5d8381c..f6cd455 100644
--- a/test/fixedbugs/issue35291.go
+++ b/test/fixedbugs/issue35291.go
@@ -10,5 +10,5 @@
 
 var s = []string{
 	1: "dup",
-	1: "dup", // ERROR "duplicate index in slice literal: 1|duplicate value for index 1"
+	1: "dup", // ERROR "duplicate index in slice literal: 1|duplicate value for index 1|duplicate index 1"
 }
diff --git a/test/fixedbugs/issue36705.go b/test/fixedbugs/issue36705.go
index 83e4136..b0485c6 100644
--- a/test/fixedbugs/issue36705.go
+++ b/test/fixedbugs/issue36705.go
@@ -1,5 +1,5 @@
-// +build cgo
-// run
+// +build cgo,!windows
+// run fake-arg-to-force-use-of-go-run
 
 // Copyright 2020 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/issue38117.go b/test/fixedbugs/issue38117.go
index 11edef7..c0707ef 100644
--- a/test/fixedbugs/issue38117.go
+++ b/test/fixedbugs/issue38117.go
@@ -13,5 +13,5 @@
 	_ = int(complex64(int(0)))
 	_ = float64(complex128(float64(0)))
 
-	_ = int8(complex128(1000)) // ERROR "overflow"
+	_ = int8(complex128(1000)) // ERROR "overflow|cannot convert"
 )
diff --git a/test/fixedbugs/issue38698.go b/test/fixedbugs/issue38698.go
new file mode 100644
index 0000000..819e223
--- /dev/null
+++ b/test/fixedbugs/issue38698.go
@@ -0,0 +1,23 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This test case caused a panic in the compiler's DWARF gen code.
+
+package p
+
+func ff( /*line :10*/ x string) bool {
+	{
+		var _ /*line :10*/, x int
+		_ = x
+	}
+	return x == ""
+}
+
+
+func h(a string) bool {
+	return ff(a)
+}
+
diff --git a/test/fixedbugs/issue38745.go b/test/fixedbugs/issue38745.go
index 7d4283b..3a84a56 100644
--- a/test/fixedbugs/issue38745.go
+++ b/test/fixedbugs/issue38745.go
@@ -10,7 +10,7 @@
 
 func f1() {
 	t{}.M()     // ERROR "t{}.M undefined \(type t has no field or method M\)|undefined field or method .*M"
-	t{x: 1}.M() // ERROR "t{...}.M undefined \(type t has no field or method M\)|undefined field or method .*M"
+	t{x: 1}.M() // ERROR "t{...}.M undefined \(type t has no field or method M\)|undefined field or method .*M|no field or method M"
 }
 
 func f2() (*t, error) {
diff --git a/test/fixedbugs/issue3925.go b/test/fixedbugs/issue3925.go
index 628c222..f085187 100644
--- a/test/fixedbugs/issue3925.go
+++ b/test/fixedbugs/issue3925.go
@@ -18,6 +18,6 @@
 var _ = []string{
 	"foo",
 	"bar",
-	20, // ERROR "cannot use|incompatible type"
+	20, // ERROR "cannot use|incompatible type|cannot convert"
 }
 
diff --git a/test/fixedbugs/issue4085a.go b/test/fixedbugs/issue4085a.go
index 200290a..bf97c9e 100644
--- a/test/fixedbugs/issue4085a.go
+++ b/test/fixedbugs/issue4085a.go
@@ -10,9 +10,9 @@
 
 func main() {
 	_ = make(T, -1)    // ERROR "negative"
-	_ = make(T, 0.5)   // ERROR "constant 0.5 truncated to integer|non-integer len argument"
+	_ = make(T, 0.5)   // ERROR "constant 0.5 truncated to integer|non-integer len argument|truncated to int"
 	_ = make(T, 1.0)   // ok
-	_ = make(T, 1<<63) // ERROR "len argument too large"
-	_ = make(T, 0, -1) // ERROR "negative cap"
-	_ = make(T, 10, 0) // ERROR "len larger than cap"
+	_ = make(T, 1<<63) // ERROR "len argument too large|overflows int"
+	_ = make(T, 0, -1) // ERROR "negative cap|must not be negative"
+	_ = make(T, 10, 0) // ERROR "len larger than cap|length and capacity swapped"
 }
diff --git a/test/fixedbugs/issue41500.go b/test/fixedbugs/issue41500.go
index 82dca34..3ec23a0 100644
--- a/test/fixedbugs/issue41500.go
+++ b/test/fixedbugs/issue41500.go
@@ -13,8 +13,8 @@
 func f() {
 	var x *s
 
-	_ = x == nil || len(x.slice) // ERROR "invalid operation: .+ \(operator \|\| not defined on int\)|incompatible types"
-	_ = len(x.slice) || x == nil // ERROR "invalid operation: .+ \(operator \|\| not defined on int\)|incompatible types"
-	_ = x == nil && len(x.slice) // ERROR "invalid operation: .+ \(operator && not defined on int\)|incompatible types"
-	_ = len(x.slice) && x == nil // ERROR "invalid operation: .+ \(operator && not defined on int\)|incompatible types"
+	_ = x == nil || len(x.slice) // ERROR "invalid operation: .+ \(operator \|\| not defined on int\)|incompatible types|cannot convert"
+	_ = len(x.slice) || x == nil // ERROR "invalid operation: .+ \(operator \|\| not defined on int\)|incompatible types|cannot convert"
+	_ = x == nil && len(x.slice) // ERROR "invalid operation: .+ \(operator && not defined on int\)|incompatible types|cannot convert"
+	_ = len(x.slice) && x == nil // ERROR "invalid operation: .+ \(operator && not defined on int\)|incompatible types|cannot convert"
 }
diff --git a/test/fixedbugs/issue4215.go b/test/fixedbugs/issue4215.go
index be9fc74..7201591 100644
--- a/test/fixedbugs/issue4215.go
+++ b/test/fixedbugs/issue4215.go
@@ -7,28 +7,28 @@
 package main
 
 func foo() (int, int) {
-	return 2.3 // ERROR "not enough arguments to return\n\thave \(number\)\n\twant \(int, int\)|not enough arguments to return"
+	return 2.3 // ERROR "not enough arguments to return\n\thave \(number\)\n\twant \(int, int\)|not enough arguments to return|wrong number of return values"
 }
 
 func foo2() {
-	return int(2), 2 // ERROR "too many arguments to return\n\thave \(int, number\)\n\twant \(\)|return with value in function with no return type"
+	return int(2), 2 // ERROR "too many arguments to return\n\thave \(int, number\)\n\twant \(\)|return with value in function with no return type|no result values expected"
 }
 
 func foo3(v int) (a, b, c, d int) {
 	if v >= 0 {
-		return 1 // ERROR "not enough arguments to return\n\thave \(number\)\n\twant \(int, int, int, int\)|not enough arguments to return"
+		return 1 // ERROR "not enough arguments to return\n\thave \(number\)\n\twant \(int, int, int, int\)|not enough arguments to return|wrong number of return values"
 	}
-	return 2, 3 // ERROR "not enough arguments to return\n\thave \(number, number\)\n\twant \(int, int, int, int\)|not enough arguments to return"
+	return 2, 3 // ERROR "not enough arguments to return\n\thave \(number, number\)\n\twant \(int, int, int, int\)|not enough arguments to return|wrong number of return values"
 }
 
 func foo4(name string) (string, int) {
 	switch name {
 	case "cow":
-		return "moo" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(string, int\)|not enough arguments to return"
+		return "moo" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(string, int\)|not enough arguments to return|wrong number of return values"
 	case "dog":
-		return "dog", 10, true // ERROR "too many arguments to return\n\thave \(string, number, bool\)\n\twant \(string, int\)|too many values in return statement"
+		return "dog", 10, true // ERROR "too many arguments to return\n\thave \(string, number, bool\)\n\twant \(string, int\)|too many values in return statement|wrong number of return values"
 	case "fish":
-		return "" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(string, int\)|not enough arguments to return"
+		return "" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(string, int\)|not enough arguments to return|wrong number of return values"
 	default:
 		return "lizard", 10
 	}
@@ -40,14 +40,14 @@
 
 func foo5() (S, T, U) {
 	if false {
-		return "" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(S, T, U\)|not enough arguments to return"
+		return "" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(S, T, U\)|not enough arguments to return|wrong number of return values"
 	} else {
 		ptr := new(T)
-		return ptr // ERROR "not enough arguments to return\n\thave \(\*T\)\n\twant \(S, T, U\)|not enough arguments to return"
+		return ptr // ERROR "not enough arguments to return\n\thave \(\*T\)\n\twant \(S, T, U\)|not enough arguments to return|wrong number of return values"
 	}
-	return new(S), 12.34, 1 + 0i, 'r', true // ERROR "too many arguments to return\n\thave \(\*S, number, number, number, bool\)\n\twant \(S, T, U\)|too many values in return statement"
+	return new(S), 12.34, 1 + 0i, 'r', true // ERROR "too many arguments to return\n\thave \(\*S, number, number, number, bool\)\n\twant \(S, T, U\)|too many values in return statement|wrong number of return values"
 }
 
 func foo6() (T, string) {
-	return "T", true, true // ERROR "too many arguments to return\n\thave \(string, bool, bool\)\n\twant \(T, string\)|too many values in return statement"
+	return "T", true, true // ERROR "too many arguments to return\n\thave \(string, bool, bool\)\n\twant \(T, string\)|too many values in return statement|wrong number of return values"
 }
diff --git a/test/fixedbugs/issue4251.go b/test/fixedbugs/issue4251.go
index d11ce51..81e3edf 100644
--- a/test/fixedbugs/issue4251.go
+++ b/test/fixedbugs/issue4251.go
@@ -9,13 +9,13 @@
 package p
 
 func F1(s []byte) []byte {
-	return s[2:1]		// ERROR "invalid slice index|inverted slice range"
+	return s[2:1]		// ERROR "invalid slice index|inverted slice range|invalid slice indices"
 }
 
 func F2(a [10]byte) []byte {
-	return a[2:1]		// ERROR "invalid slice index|inverted slice range"
+	return a[2:1]		// ERROR "invalid slice index|inverted slice range|invalid slice indices"
 }
 
 func F3(s string) string {
-	return s[2:1]		// ERROR "invalid slice index|inverted slice range"
+	return s[2:1]		// ERROR "invalid slice index|inverted slice range|invalid slice indices"
 }
diff --git a/test/fixedbugs/issue42686.go b/test/fixedbugs/issue42686.go
index 962bdd3..9f9075c 100644
--- a/test/fixedbugs/issue42686.go
+++ b/test/fixedbugs/issue42686.go
@@ -1,4 +1,4 @@
-// compile -d=fieldtrack
+// compile -goexperiment fieldtrack
 
 // Copyright 2020 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/issue43164.dir/a.go b/test/fixedbugs/issue43164.dir/a.go
new file mode 100644
index 0000000..fa10e85
--- /dev/null
+++ b/test/fixedbugs/issue43164.dir/a.go
@@ -0,0 +1,13 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import . "strings"
+
+var _ = Index // use strings
+
+type t struct{ Index int }
+
+var _ = t{Index: 0}
diff --git a/test/fixedbugs/issue43164.dir/b.go b/test/fixedbugs/issue43164.dir/b.go
new file mode 100644
index 0000000..b025927
--- /dev/null
+++ b/test/fixedbugs/issue43164.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import . "bytes"
+
+var _ = Index // use bytes
+
+var _ = t{Index: 0}
diff --git a/test/fixedbugs/issue43164.go b/test/fixedbugs/issue43164.go
new file mode 100644
index 0000000..f21d1d5
--- /dev/null
+++ b/test/fixedbugs/issue43164.go
@@ -0,0 +1,7 @@
+// compiledir
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue43167.go b/test/fixedbugs/issue43167.go
new file mode 100644
index 0000000..1d1b69a
--- /dev/null
+++ b/test/fixedbugs/issue43167.go
@@ -0,0 +1,13 @@
+// errorcheck
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import . "bytes"
+
+var _ Buffer // use package bytes
+
+var Index byte // ERROR "Index redeclared.*\n\tLINE-4: previous declaration during import .bytes.|already declared|redefinition"
diff --git a/test/fixedbugs/issue43384.go b/test/fixedbugs/issue43384.go
new file mode 100644
index 0000000..1bd793b
--- /dev/null
+++ b/test/fixedbugs/issue43384.go
@@ -0,0 +1,124 @@
+// errorcheck
+
+// Copyright 2020 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package p
+
+type T int
+
+func (T) Mv()  {}
+func (*T) Mp() {}
+
+type P1 struct{ T }
+type P2 struct{ *T }
+type P3 *struct{ T }
+type P4 *struct{ *T }
+
+func _() {
+	{
+		var p P1
+		p.Mv()
+		(&p).Mv()
+		(*&p).Mv()
+		p.Mp()
+		(&p).Mp()
+		(*&p).Mp()
+	}
+	{
+		var p P2
+		p.Mv()
+		(&p).Mv()
+		(*&p).Mv()
+		p.Mp()
+		(&p).Mp()
+		(*&p).Mp()
+	}
+	{
+		var p P3
+		p.Mv()     // ERROR "undefined"
+		(&p).Mv()  // ERROR "undefined"
+		(*&p).Mv() // ERROR "undefined"
+		(**&p).Mv()
+		(*p).Mv()
+		(&*p).Mv()
+		p.Mp()     // ERROR "undefined"
+		(&p).Mp()  // ERROR "undefined"
+		(*&p).Mp() // ERROR "undefined"
+		(**&p).Mp()
+		(*p).Mp()
+		(&*p).Mp()
+	}
+	{
+		var p P4
+		p.Mv()     // ERROR "undefined"
+		(&p).Mv()  // ERROR "undefined"
+		(*&p).Mv() // ERROR "undefined"
+		(**&p).Mv()
+		(*p).Mv()
+		(&*p).Mv()
+		p.Mp()     // ERROR "undefined"
+		(&p).Mp()  // ERROR "undefined"
+		(*&p).Mp() // ERROR "undefined"
+		(**&p).Mp()
+		(*p).Mp()
+		(&*p).Mp()
+	}
+}
+
+func _() {
+	type P5 struct{ T }
+	type P6 struct{ *T }
+	type P7 *struct{ T }
+	type P8 *struct{ *T }
+
+	{
+		var p P5
+		p.Mv()
+		(&p).Mv()
+		(*&p).Mv()
+		p.Mp()
+		(&p).Mp()
+		(*&p).Mp()
+	}
+	{
+		var p P6
+		p.Mv()
+		(&p).Mv()
+		(*&p).Mv()
+		p.Mp()
+		(&p).Mp()
+		(*&p).Mp()
+	}
+	{
+		var p P7
+		p.Mv()     // ERROR "undefined"
+		(&p).Mv()  // ERROR "undefined"
+		(*&p).Mv() // ERROR "undefined"
+		(**&p).Mv()
+		(*p).Mv()
+		(&*p).Mv()
+		p.Mp()     // ERROR "undefined"
+		(&p).Mp()  // ERROR "undefined"
+		(*&p).Mp() // ERROR "undefined"
+		(**&p).Mp()
+		(*p).Mp()
+		(&*p).Mp()
+	}
+	{
+		var p P8
+		p.Mv()     // ERROR "undefined"
+		(&p).Mv()  // ERROR "undefined"
+		(*&p).Mv() // ERROR "undefined"
+		(**&p).Mv()
+		(*p).Mv()
+		(&*p).Mv()
+		p.Mp()     // ERROR "undefined"
+		(&p).Mp()  // ERROR "undefined"
+		(*&p).Mp() // ERROR "undefined"
+		(**&p).Mp()
+		(*p).Mp()
+		(&*p).Mp()
+	}
+}
diff --git a/test/fixedbugs/issue43428.go b/test/fixedbugs/issue43428.go
new file mode 100644
index 0000000..773a3f3
--- /dev/null
+++ b/test/fixedbugs/issue43428.go
@@ -0,0 +1,25 @@
+// errorcheck
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "time"
+
+type T int
+
+func (T) Mv()  {}
+func (*T) Mp() {}
+
+var _ = []int{
+	T.Mv,    // ERROR "cannot use T\.Mv|incompatible type"
+	(*T).Mv, // ERROR "cannot use \(\*T\)\.Mv|incompatible type"
+	(*T).Mp, // ERROR "cannot use \(\*T\)\.Mp|incompatible type"
+
+	time.Time.GobEncode,    // ERROR "cannot use time\.Time\.GobEncode|incompatible type"
+	(*time.Time).GobEncode, // ERROR "cannot use \(\*time\.Time\)\.GobEncode|incompatible type"
+	(*time.Time).GobDecode, // ERROR "cannot use \(\*time\.Time\)\.GobDecode|incompatible type"
+
+}
diff --git a/test/fixedbugs/issue43444.go b/test/fixedbugs/issue43444.go
new file mode 100644
index 0000000..c430e1b
--- /dev/null
+++ b/test/fixedbugs/issue43444.go
@@ -0,0 +1,28 @@
+// run
+
+package main
+
+var sp = ""
+
+func f(name string, _ ...interface{}) int {
+	print(sp, name)
+	sp = " "
+	return 0
+}
+
+var a = f("a", x)
+var b = f("b", y)
+var c = f("c", z)
+var d = func() int {
+	if false {
+		_ = z
+	}
+	return f("d")
+}()
+var e = f("e")
+
+var x int
+var y int = 42
+var z int = func() int { return 42 }()
+
+func main() { println() }
diff --git a/test/fixedbugs/issue43444.out b/test/fixedbugs/issue43444.out
new file mode 100644
index 0000000..22d6a0d
--- /dev/null
+++ b/test/fixedbugs/issue43444.out
@@ -0,0 +1 @@
+e a b c d
diff --git a/test/fixedbugs/issue43479.dir/a.go b/test/fixedbugs/issue43479.dir/a.go
new file mode 100644
index 0000000..ed3e6a5
--- /dev/null
+++ b/test/fixedbugs/issue43479.dir/a.go
@@ -0,0 +1,27 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+type Here struct{ stuff int }
+type Info struct{ Dir string }
+
+func New() Here { return Here{} }
+func (h Here) Dir(p string) (Info, error)
+
+type I interface{ M(x string) }
+
+type T = struct {
+	Here
+	I
+}
+
+var X T
+
+var A = (*T).Dir
+var B = T.Dir
+var C = X.Dir
+var D = (*T).M
+var E = T.M
+var F = X.M
diff --git a/test/fixedbugs/issue43479.dir/b.go b/test/fixedbugs/issue43479.dir/b.go
new file mode 100644
index 0000000..02d1690
--- /dev/null
+++ b/test/fixedbugs/issue43479.dir/b.go
@@ -0,0 +1,38 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "./a"
+
+var Here = a.New()
+var Dir = Here.Dir
+
+type T = struct {
+	a.Here
+	a.I
+}
+
+var X T
+
+// Test exporting the type of method values for anonymous structs with
+// promoted methods.
+var A = a.A
+var B = a.B
+var C = a.C
+var D = a.D
+var E = a.E
+var F = a.F
+var G = (*a.T).Dir
+var H = a.T.Dir
+var I = a.X.Dir
+var J = (*a.T).M
+var K = a.T.M
+var L = a.X.M
+var M = (*T).Dir
+var N = T.Dir
+var O = X.Dir
+var P = (*T).M
+var Q = T.M
+var R = X.M
diff --git a/test/fixedbugs/issue43479.go b/test/fixedbugs/issue43479.go
new file mode 100644
index 0000000..f21d1d5
--- /dev/null
+++ b/test/fixedbugs/issue43479.go
@@ -0,0 +1,7 @@
+// compiledir
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue43480.go b/test/fixedbugs/issue43480.go
new file mode 100644
index 0000000..d98ad3a
--- /dev/null
+++ b/test/fixedbugs/issue43480.go
@@ -0,0 +1,33 @@
+// run
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue #43480: ICE on large uint64 constants in switch cases.
+
+package main
+
+func isPow10(x uint64) bool {
+	switch x {
+	case 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19:
+		return true
+	}
+	return false
+}
+
+func main() {
+	var x uint64 = 1
+
+	for {
+		if !isPow10(x) || isPow10(x-1) || isPow10(x+1) {
+			panic(x)
+		}
+		next := x * 10
+		if next/10 != x {
+			break // overflow
+		}
+		x = next
+	}
+}
diff --git a/test/fixedbugs/issue43633.dir/a.go b/test/fixedbugs/issue43633.dir/a.go
new file mode 100644
index 0000000..946a37e
--- /dev/null
+++ b/test/fixedbugs/issue43633.dir/a.go
@@ -0,0 +1,28 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+func F() bool {
+	{
+		x := false
+		_ = x
+	}
+	if false {
+		_ = func(x bool) {}
+	}
+	x := true
+	return x
+}
+
+func G() func() bool {
+	x := true
+	return func() bool {
+		{
+			x := false
+			_ = x
+		}
+		return x
+	}
+}
diff --git a/test/fixedbugs/issue43633.dir/main.go b/test/fixedbugs/issue43633.dir/main.go
new file mode 100644
index 0000000..320e000
--- /dev/null
+++ b/test/fixedbugs/issue43633.dir/main.go
@@ -0,0 +1,18 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "./a"
+
+var g = a.G()
+
+func main() {
+	if !a.F() {
+		panic("FAIL")
+	}
+	if !g() {
+		panic("FAIL")
+	}
+}
diff --git a/test/fixedbugs/issue43633.go b/test/fixedbugs/issue43633.go
new file mode 100644
index 0000000..40df49f
--- /dev/null
+++ b/test/fixedbugs/issue43633.go
@@ -0,0 +1,7 @@
+// rundir
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue43677.go b/test/fixedbugs/issue43677.go
new file mode 100644
index 0000000..1a68c8b
--- /dev/null
+++ b/test/fixedbugs/issue43677.go
@@ -0,0 +1,18 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue #43677: ICE during compilation of dynamic initializers for
+// composite blank variables.
+
+package p
+
+func f() *int
+
+var _ = [2]*int{nil, f()}
+
+var _ = struct{ x, y *int }{nil, f()}
+
+var _ interface{} = f()
diff --git a/test/fixedbugs/issue43701.go b/test/fixedbugs/issue43701.go
new file mode 100644
index 0000000..6e16180
--- /dev/null
+++ b/test/fixedbugs/issue43701.go
@@ -0,0 +1,18 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f() {
+	var st struct {
+		s string
+		i int16
+	}
+	_ = func() {
+		var m map[int16]int
+		m[st.i] = 0
+	}
+}
diff --git a/test/fixedbugs/issue43762.go b/test/fixedbugs/issue43762.go
new file mode 100644
index 0000000..9f7682a
--- /dev/null
+++ b/test/fixedbugs/issue43762.go
@@ -0,0 +1,11 @@
+// errorcheck
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+var _ = true == '\\' // ERROR "invalid operation: true == '\\\\'|cannot convert true"
+var _ = true == '\'' // ERROR "invalid operation: true == '\\''|cannot convert true"
+var _ = true == '\n' // ERROR "invalid operation: true == '\\n'|cannot convert true"
diff --git a/test/fixedbugs/issue43835.go b/test/fixedbugs/issue43835.go
index 449eb72..29a5194 100644
--- a/test/fixedbugs/issue43835.go
+++ b/test/fixedbugs/issue43835.go
@@ -13,6 +13,9 @@
 	if bad, _ := g(); bad {
 		panic("FAIL")
 	}
+	if bad, _ := h(); bad {
+		panic("FAIL")
+	}
 }
 
 func f() (bad bool) {
@@ -31,3 +34,12 @@
 	var p *int
 	return true, *p
 }
+
+
+func h() (_ bool, _ int) {
+	defer func() {
+		recover()
+	}()
+	var p *int
+	return true, *p
+}
diff --git a/test/fixedbugs/issue43908.go b/test/fixedbugs/issue43908.go
new file mode 100644
index 0000000..47709eb
--- /dev/null
+++ b/test/fixedbugs/issue43908.go
@@ -0,0 +1,21 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Verify exact constant evaluation independent of
+// (mathematically equivalent) expression form.
+
+package main
+
+import "fmt"
+
+const ulp1 = imag(1i + 2i / 3 - 5i / 3)
+const ulp2 = imag(1i + complex(0, 2) / 3 - 5i / 3)
+
+func main() {
+	if ulp1 != ulp2 {
+		panic(fmt.Sprintf("%g != %g\n", ulp1, ulp2))
+	}
+}
diff --git a/test/fixedbugs/issue43962.dir/a.go b/test/fixedbugs/issue43962.dir/a.go
new file mode 100644
index 0000000..168b206
--- /dev/null
+++ b/test/fixedbugs/issue43962.dir/a.go
@@ -0,0 +1,5 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package init
diff --git a/test/fixedbugs/issue43962.dir/b.go b/test/fixedbugs/issue43962.dir/b.go
new file mode 100644
index 0000000..f55fea1
--- /dev/null
+++ b/test/fixedbugs/issue43962.dir/b.go
@@ -0,0 +1,7 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "./a" // ERROR "cannot import package as init"
diff --git a/test/fixedbugs/issue43962.go b/test/fixedbugs/issue43962.go
new file mode 100644
index 0000000..dca4d07
--- /dev/null
+++ b/test/fixedbugs/issue43962.go
@@ -0,0 +1,9 @@
+// errorcheckdir
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 43962: Importing a package called "init" is an error.
+
+package ignored
diff --git a/test/fixedbugs/issue44266.go b/test/fixedbugs/issue44266.go
new file mode 100644
index 0000000..c683e56
--- /dev/null
+++ b/test/fixedbugs/issue44266.go
@@ -0,0 +1,23 @@
+// errorcheck
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "io"
+
+type T1 interface {
+	io.Reader
+}
+
+type T2 struct {
+	io.SectionReader
+}
+
+type T3 struct { // ERROR "invalid recursive type T3"
+	T1
+	T2
+	parent T3
+}
diff --git a/test/fixedbugs/issue4429.go b/test/fixedbugs/issue4429.go
index 9eb2e0f..3af6f97 100644
--- a/test/fixedbugs/issue4429.go
+++ b/test/fixedbugs/issue4429.go
@@ -12,5 +12,5 @@
 
 func main() {
   av := a{};
-  _ = *a(av); // ERROR "invalid indirect|expected pointer"
+  _ = *a(av); // ERROR "invalid indirect|expected pointer|cannot indirect"
 }
diff --git a/test/fixedbugs/issue44325.dir/a.go b/test/fixedbugs/issue44325.dir/a.go
new file mode 100644
index 0000000..5a22b45
--- /dev/null
+++ b/test/fixedbugs/issue44325.dir/a.go
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package a
+
+func FM() func() {
+	return func() {
+		_ = func() int {
+			return 0
+		}
+	}
+}
diff --git a/test/fixedbugs/issue44325.dir/b.go b/test/fixedbugs/issue44325.dir/b.go
new file mode 100644
index 0000000..c4d77e3
--- /dev/null
+++ b/test/fixedbugs/issue44325.dir/b.go
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package b
+
+import (
+	"./a"
+)
+
+func F() {
+	a.FM()
+}
diff --git a/test/fixedbugs/issue44325.go b/test/fixedbugs/issue44325.go
new file mode 100644
index 0000000..d406838
--- /dev/null
+++ b/test/fixedbugs/issue44325.go
@@ -0,0 +1,7 @@
+// compiledir
+
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue44330.dir/a.go b/test/fixedbugs/issue44330.dir/a.go
new file mode 100644
index 0000000..9d3ab9f
--- /dev/null
+++ b/test/fixedbugs/issue44330.dir/a.go
@@ -0,0 +1,21 @@
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package a
+
+type Table struct {
+	ColumnSeparator bool
+	RowSeparator    bool
+
+	// ColumnResizer is called on each Draw. Can be used for custom column sizing.
+	ColumnResizer func()
+}
+
+func NewTable() *Table {
+	return &Table{
+		ColumnSeparator: true,
+		RowSeparator:    true,
+		ColumnResizer:   func() {},
+	}
+}
diff --git a/test/fixedbugs/issue44330.dir/b.go b/test/fixedbugs/issue44330.dir/b.go
new file mode 100644
index 0000000..1d57424
--- /dev/null
+++ b/test/fixedbugs/issue44330.dir/b.go
@@ -0,0 +1,23 @@
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package main
+
+import (
+	"./a"
+)
+
+type Term struct {
+	top *a.Table
+}
+
+//go:noinline
+func NewFred() *Term {
+	table := a.NewTable()
+	return &Term{top: table}
+}
+
+func main() {
+	NewFred()
+}
diff --git a/test/fixedbugs/issue44330.go b/test/fixedbugs/issue44330.go
new file mode 100644
index 0000000..682d9c5
--- /dev/null
+++ b/test/fixedbugs/issue44330.go
@@ -0,0 +1,7 @@
+// rundir
+
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue44335.dir/a.go b/test/fixedbugs/issue44335.dir/a.go
new file mode 100644
index 0000000..2c9c217
--- /dev/null
+++ b/test/fixedbugs/issue44335.dir/a.go
@@ -0,0 +1,17 @@
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file
+
+package a
+
+type W struct {
+	M func(string) string
+}
+
+func FM(m string) func(W) {
+	return func(pw W) {
+		pw.M = func(string) string {
+			return m
+		}
+	}
+}
diff --git a/test/fixedbugs/issue44335.dir/b.go b/test/fixedbugs/issue44335.dir/b.go
new file mode 100644
index 0000000..e72c2ab
--- /dev/null
+++ b/test/fixedbugs/issue44335.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package b
+
+import "./a"
+
+func F() {
+	a.FM("")
+}
diff --git a/test/fixedbugs/issue44335.go b/test/fixedbugs/issue44335.go
new file mode 100644
index 0000000..d406838
--- /dev/null
+++ b/test/fixedbugs/issue44335.go
@@ -0,0 +1,7 @@
+// compiledir
+
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue44344.go b/test/fixedbugs/issue44344.go
new file mode 100644
index 0000000..06c4cb6
--- /dev/null
+++ b/test/fixedbugs/issue44344.go
@@ -0,0 +1,30 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue #44344: a crash in DWARF scope generation (trying to
+// scope the PCs of a function that was inlined away).
+
+package main
+
+func main() {
+	pv := []int{3, 4, 5}
+	if pv[1] != 9 {
+		pv = append(pv, 9)
+	}
+	tryit := func() bool {
+		lpv := len(pv)
+		if lpv == 101 {
+			return false
+		}
+		if worst := pv[pv[1]&1]; worst != 101 {
+			return true
+		}
+		return false
+	}()
+	if tryit {
+		println(pv[0])
+	}
+}
diff --git a/test/fixedbugs/issue44370.dir/a.go b/test/fixedbugs/issue44370.dir/a.go
new file mode 100644
index 0000000..c5bf1bc
--- /dev/null
+++ b/test/fixedbugs/issue44370.dir/a.go
@@ -0,0 +1,20 @@
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package a
+
+// A StoppableWaitGroup waits for a collection of goroutines to finish.
+type StoppableWaitGroup struct {
+	// i is the internal counter which can store tolerate negative values
+	// as opposed the golang's library WaitGroup.
+	i *int64
+}
+
+// NewStoppableWaitGroup returns a new StoppableWaitGroup. When the 'Stop' is
+// executed, following 'Add()' calls won't have any effect.
+func NewStoppableWaitGroup() *StoppableWaitGroup {
+	return &StoppableWaitGroup{
+		i: func() *int64 { i := int64(0); return &i }(),
+	}
+}
diff --git a/test/fixedbugs/issue44370.dir/b.go b/test/fixedbugs/issue44370.dir/b.go
new file mode 100644
index 0000000..f0e0b4e
--- /dev/null
+++ b/test/fixedbugs/issue44370.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package b
+
+import "./a"
+
+func JoinClusterServices() {
+	_ = a.NewStoppableWaitGroup()
+}
diff --git a/test/fixedbugs/issue44370.go b/test/fixedbugs/issue44370.go
new file mode 100644
index 0000000..d406838
--- /dev/null
+++ b/test/fixedbugs/issue44370.go
@@ -0,0 +1,7 @@
+// compiledir
+
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue44383.go b/test/fixedbugs/issue44383.go
new file mode 100644
index 0000000..d2d5752
--- /dev/null
+++ b/test/fixedbugs/issue44383.go
@@ -0,0 +1,18 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 44383: gofrontend internal compiler error
+
+package main
+
+func main() {
+	var b1, b2 byte
+	f := func() int {
+		var m map[byte]int
+		return m[b1/b2]
+	}
+	f()
+}
diff --git a/test/fixedbugs/issue44432.go b/test/fixedbugs/issue44432.go
new file mode 100644
index 0000000..c5fb67e
--- /dev/null
+++ b/test/fixedbugs/issue44432.go
@@ -0,0 +1,13 @@
+// errorcheck -G=0 -d=panic
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+var m = map[string]int{
+	"a": 1,
+	1:   1, // ERROR "cannot use 1.*as type string in map key"
+	2:   2, // ERROR "cannot use 2.*as type string in map key"
+}
diff --git a/test/fixedbugs/issue44465.go b/test/fixedbugs/issue44465.go
new file mode 100644
index 0000000..8cb62ad
--- /dev/null
+++ b/test/fixedbugs/issue44465.go
@@ -0,0 +1,21 @@
+// compile -d=ssa/check/seed
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code caused an internal consistency error due to a bad shortcircuit optimization.
+
+package p
+
+func f() {
+	var b bool
+	if b {
+		b = true
+	}
+l:
+	for !b {
+		b = true
+		goto l
+	}
+}
diff --git a/test/fixedbugs/issue4458.go b/test/fixedbugs/issue4458.go
index 59cfa9f..6ac6d86 100644
--- a/test/fixedbugs/issue4458.go
+++ b/test/fixedbugs/issue4458.go
@@ -16,5 +16,5 @@
 func main() {
 	av := T{}
 	pav := &av
-	(**T).foo(&pav) // ERROR "no method .*foo|requires named type or pointer to named"
+	(**T).foo(&pav) // ERROR "no method .*foo|requires named type or pointer to named|undefined"
 }
diff --git a/test/fixedbugs/issue4470.go b/test/fixedbugs/issue4470.go
index d922478..1dc5563 100644
--- a/test/fixedbugs/issue4470.go
+++ b/test/fixedbugs/issue4470.go
@@ -13,4 +13,5 @@
 	switch (i.(type)) { // ERROR "outside type switch"
 	default:
 	}
+	_ = i
 }
diff --git a/test/fixedbugs/issue44732.dir/bar/bar.go b/test/fixedbugs/issue44732.dir/bar/bar.go
new file mode 100644
index 0000000..fc14161
--- /dev/null
+++ b/test/fixedbugs/issue44732.dir/bar/bar.go
@@ -0,0 +1,11 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bar
+
+import "issue44732.dir/foo"
+
+type Bar struct {
+	Foo *foo.Foo
+}
diff --git a/test/fixedbugs/issue44732.dir/foo/foo.go b/test/fixedbugs/issue44732.dir/foo/foo.go
new file mode 100644
index 0000000..c8afb0e
--- /dev/null
+++ b/test/fixedbugs/issue44732.dir/foo/foo.go
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package foo
+
+type Foo struct {
+	updatecb func()
+}
+
+func NewFoo() *Foo {
+	return &Foo{updatecb: nil}
+}
diff --git a/test/fixedbugs/issue44732.dir/main.go b/test/fixedbugs/issue44732.dir/main.go
new file mode 100644
index 0000000..21208ec
--- /dev/null
+++ b/test/fixedbugs/issue44732.dir/main.go
@@ -0,0 +1,15 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"issue44732.dir/bar"
+	"issue44732.dir/foo"
+)
+
+func main() {
+	_ = bar.Bar{}
+	_ = foo.NewFoo()
+}
diff --git a/test/fixedbugs/issue44732.go b/test/fixedbugs/issue44732.go
new file mode 100644
index 0000000..4210671
--- /dev/null
+++ b/test/fixedbugs/issue44732.go
@@ -0,0 +1,7 @@
+// runindir
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue44739.go b/test/fixedbugs/issue44739.go
new file mode 100644
index 0000000..3441a90
--- /dev/null
+++ b/test/fixedbugs/issue44739.go
@@ -0,0 +1,61 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// issue 44739: cmd/compile: incorrect offset in MOVD
+// load/store on ppc64/ppc64le causes assembler error.
+
+// Test other 8 byte loads and stores where the
+// compile time offset is not aligned to 8, as
+// well as cases where the offset is not known
+// until link time (e.g. gostrings).
+
+package main
+
+import (
+	"fmt"
+)
+
+type T struct {
+	x [4]byte
+	y [8]byte
+}
+
+var st T
+
+const (
+	gostring1 = "abc"
+	gostring2 = "defghijk"
+	gostring3 = "lmnopqrs"
+)
+
+func f(a T, _ byte, b T) bool {
+	// initialization of a,b
+	// tests unaligned store
+	return a.y == b.y
+}
+
+func g(a T) {
+	// test load of unaligned
+	// 8 byte gostring, store
+	// to unaligned static
+	copy(a.y[:], gostring2)
+}
+
+func main() {
+	var t1, t2 T
+
+	// test copy to automatic storage,
+	// load of unaligned gostring.
+	copy(st.y[:], gostring2)
+	copy(t1.y[:], st.y[:])
+	copy(t2.y[:], gostring3)
+	// test initialization of params
+	if !f(t1, 'a', t2) {
+		// gostring1 added so it has a use
+		fmt.Printf("FAIL: %s\n", gostring1)
+	}
+}
+
diff --git a/test/fixedbugs/issue44823.go b/test/fixedbugs/issue44823.go
new file mode 100644
index 0000000..85811df
--- /dev/null
+++ b/test/fixedbugs/issue44823.go
@@ -0,0 +1,26 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 44823: miscompilation with store combining.
+
+package main
+
+import "encoding/binary"
+
+//go:noinline
+func Id(a [8]byte) (x [8]byte) {
+	binary.LittleEndian.PutUint64(x[:], binary.LittleEndian.Uint64(a[:]))
+	return
+}
+
+var a = [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
+
+func main() {
+	x := Id(a)
+	if x != a {
+		panic("FAIL")
+	}
+}
diff --git a/test/fixedbugs/issue44830.go b/test/fixedbugs/issue44830.go
new file mode 100644
index 0000000..7df5aeb
--- /dev/null
+++ b/test/fixedbugs/issue44830.go
@@ -0,0 +1,19 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+func main() {
+	t := reflect.TypeOf(unsafe.Pointer(nil))
+	if pkgPath := t.PkgPath(); pkgPath != "unsafe" {
+		panic("unexpected t.PkgPath(): " + pkgPath)
+	}
+}
diff --git a/test/fixedbugs/issue45045.go b/test/fixedbugs/issue45045.go
new file mode 100644
index 0000000..6e6db64
--- /dev/null
+++ b/test/fixedbugs/issue45045.go
@@ -0,0 +1,51 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"reflect"
+	"runtime"
+	"unsafe"
+)
+
+func k(c chan string, val string) string {
+	b := make([]byte, 1000)
+	runtime.SetFinalizer(&b[0], func(*byte) {
+		c <- val
+	})
+	var s string
+	h := (*reflect.StringHeader)(unsafe.Pointer(&s))
+	h.Data = uintptr(unsafe.Pointer(&b[0]))
+	h.Len = len(b)
+	return s
+}
+
+func main() {
+	{
+		c := make(chan string, 2)
+		m := make(map[string]int)
+		m[k(c, "first")] = 0
+		m[k(c, "second")] = 0
+		runtime.GC()
+		if s := <-c; s != "first" {
+			panic("map[string], second key did not retain.")
+		}
+		runtime.KeepAlive(m)
+	}
+
+	{
+		c := make(chan string, 2)
+		m := make(map[[2]string]int)
+		m[[2]string{k(c, "first")}] = 0
+		m[[2]string{k(c, "second")}] = 0
+		runtime.GC()
+		if s := <-c; s != "first" {
+			panic("map[[2]string], second key did not retain.")
+		}
+		runtime.KeepAlive(m)
+	}
+}
diff --git a/test/fixedbugs/issue4517d.go b/test/fixedbugs/issue4517d.go
index 197c225..d732e1f 100644
--- a/test/fixedbugs/issue4517d.go
+++ b/test/fixedbugs/issue4517d.go
@@ -6,4 +6,4 @@
 
 package p
 
-import init "fmt" // ERROR "cannot import package as init"
+import init "fmt" // ERROR "cannot import package as init|cannot declare init"
diff --git a/test/fixedbugs/issue45242.go b/test/fixedbugs/issue45242.go
new file mode 100644
index 0000000..b997221
--- /dev/null
+++ b/test/fixedbugs/issue45242.go
@@ -0,0 +1,28 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+//go:noinline
+func repro(b []byte, bit int32) {
+	_ = b[3]
+	v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 | 1<<(bit&31)
+	b[0] = byte(v)
+	b[1] = byte(v >> 8)
+	b[2] = byte(v >> 16)
+	b[3] = byte(v >> 24)
+}
+
+func main() {
+	var b [8]byte
+	repro(b[:], 32)
+	want := [8]byte{1, 0, 0, 0, 0, 0, 0, 0}
+	if b != want {
+		panic(fmt.Sprintf("got %v, want %v\n", b, want))
+	}
+}
diff --git a/test/fixedbugs/issue45258.go b/test/fixedbugs/issue45258.go
new file mode 100644
index 0000000..f4d6fcc
--- /dev/null
+++ b/test/fixedbugs/issue45258.go
@@ -0,0 +1,28 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type Fooer interface {
+	Foo() Barer
+}
+
+type Barer interface {
+	Bar()
+}
+
+type impl struct{}
+
+func (r *impl) Foo() Barer {
+	return r
+}
+
+func (r *impl) Bar() {}
+
+func _() {
+	var r Fooer = &impl{}
+	r.Foo().Bar()
+}
diff --git a/test/fixedbugs/issue45323.go b/test/fixedbugs/issue45323.go
new file mode 100644
index 0000000..870d1a2
--- /dev/null
+++ b/test/fixedbugs/issue45323.go
@@ -0,0 +1,24 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func g() bool
+
+func f(y int) bool {
+	b, ok := true, false
+	if y > 1 {
+		ok = g()
+	}
+	if !ok {
+		ok = g()
+		b = false
+	}
+	if !ok {
+		return false
+	}
+	return b
+}
diff --git a/test/fixedbugs/issue45344.go b/test/fixedbugs/issue45344.go
new file mode 100644
index 0000000..70c3d89
--- /dev/null
+++ b/test/fixedbugs/issue45344.go
@@ -0,0 +1,20 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 45344: expand_calls does not handle direct interface
+// typed argument well.
+
+package p
+
+type T struct {
+	a map[int]int
+}
+
+func F(t T) {
+	G(t)
+}
+
+func G(...interface{})
diff --git a/test/fixedbugs/issue45359.go b/test/fixedbugs/issue45359.go
new file mode 100644
index 0000000..5448556
--- /dev/null
+++ b/test/fixedbugs/issue45359.go
@@ -0,0 +1,20 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func f() {
+	var i, j int
+	var b bool
+	i = -(i &^ i)
+	for 1>>uint(i) == 0 {
+		_ = func() {
+			i, b = 0, true
+		}
+		_ = b
+		i %= j
+	}
+}
diff --git a/test/fixedbugs/issue45503.dir/a.go b/test/fixedbugs/issue45503.dir/a.go
new file mode 100644
index 0000000..b45835b
--- /dev/null
+++ b/test/fixedbugs/issue45503.dir/a.go
@@ -0,0 +1,15 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+type S struct{}
+
+func (s *S) M() {
+	s.m((*S).N)
+}
+
+func (s *S) N() {}
+
+func (s *S) m(func(*S)) {}
diff --git a/test/fixedbugs/issue45503.dir/b.go b/test/fixedbugs/issue45503.dir/b.go
new file mode 100644
index 0000000..df4877a
--- /dev/null
+++ b/test/fixedbugs/issue45503.dir/b.go
@@ -0,0 +1,12 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "a"
+
+func F() {
+	s := a.S{}
+	s.M()
+}
diff --git a/test/fixedbugs/issue45503.go b/test/fixedbugs/issue45503.go
new file mode 100644
index 0000000..ab3b901
--- /dev/null
+++ b/test/fixedbugs/issue45503.go
@@ -0,0 +1,10 @@
+// compiledir
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This test exercises exporting + importing method
+// expressions for use when inlining.
+
+package ignored
diff --git a/test/fixedbugs/issue45606.go b/test/fixedbugs/issue45606.go
new file mode 100644
index 0000000..1b52b4e
--- /dev/null
+++ b/test/fixedbugs/issue45606.go
@@ -0,0 +1,17 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func x() {
+	func() func() {
+		return func() {
+			f := func() {}
+			g, _ := f, 0
+			g()
+		}
+	}()()
+}
diff --git a/test/fixedbugs/issue45665.go b/test/fixedbugs/issue45665.go
new file mode 100644
index 0000000..2981a49
--- /dev/null
+++ b/test/fixedbugs/issue45665.go
@@ -0,0 +1,15 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main() {
+	Get([]string{"a", "b"})
+}
+
+func Get(ss []string) *[2]string {
+	return (*[2]string)(ss)
+}
diff --git a/test/fixedbugs/issue45693.go b/test/fixedbugs/issue45693.go
new file mode 100644
index 0000000..20a0cec
--- /dev/null
+++ b/test/fixedbugs/issue45693.go
@@ -0,0 +1,16 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 45693: ICE with register args.
+
+package p
+
+func f() {
+	var s string
+	s = s + "" + s + "" + s + ""
+	for {
+	}
+}
diff --git a/test/fixedbugs/issue45706.go b/test/fixedbugs/issue45706.go
new file mode 100644
index 0000000..6518dbf
--- /dev/null
+++ b/test/fixedbugs/issue45706.go
@@ -0,0 +1,25 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+var i int
+var arr []*int
+var f func() int
+
+func g() {
+	for i, *(arr[f()]) = range []int{} {
+	}
+}
+
+func h() {
+	var x int
+	var f func() int
+	var arr []int
+	var arr2 [][0]rune
+	for arr[x], arr2[arr[f()]][x] = range "" {
+	}
+}
diff --git a/test/fixedbugs/issue45743.go b/test/fixedbugs/issue45743.go
new file mode 100644
index 0000000..0b30e0f
--- /dev/null
+++ b/test/fixedbugs/issue45743.go
@@ -0,0 +1,20 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func fn() func(interface{}) {
+	return func(o interface{}) {
+		switch v := o.(type) {
+		case *int:
+			*v = 1
+		}
+	}
+}
+
+func main() {
+	fn()
+}
diff --git a/test/fixedbugs/issue45804.go b/test/fixedbugs/issue45804.go
new file mode 100644
index 0000000..28d42c8
--- /dev/null
+++ b/test/fixedbugs/issue45804.go
@@ -0,0 +1,19 @@
+// errorcheck
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func g() int
+func h(int)
+
+var b bool
+
+func f() {
+	did := g()
+	if !did && b { // ERROR "invalid operation"
+		h(x) // ERROR "undefined"
+	}
+}
diff --git a/test/fixedbugs/issue45851.go b/test/fixedbugs/issue45851.go
new file mode 100644
index 0000000..b137071
--- /dev/null
+++ b/test/fixedbugs/issue45851.go
@@ -0,0 +1,68 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This tickles a stack-allocation bug when the register ABI is enabled.
+// The original report was from cue, internal/core/adt/equality.go,
+// function equalVertex.
+
+// In the failing case, something bad gets passed to equalTerminal.
+
+package main
+
+import "fmt"
+
+type Kind uint16
+type Flag uint16
+
+const (
+	allKinds Kind = 1
+	TopKind  Kind = (allKinds - 1)
+)
+type Value interface {
+	Kind() Kind
+}
+type Vertex struct {
+	BaseValue Value
+	name string
+}
+func (v *Vertex) Kind() Kind {
+	return TopKind
+}
+
+func main() {
+	vA := &Vertex{name:"vA",}
+	vB := &Vertex{name:"vB",}
+	vX := &Vertex{name:"vX",}
+	vA.BaseValue = vX
+	vB.BaseValue = vX
+	_ = equalVertex(vA, vB, Flag(1))
+}
+
+var foo string
+
+//go:noinline
+func (v *Vertex) IsClosedStruct() bool {
+	return true
+}
+
+func equalVertex(x *Vertex, v Value, flags Flag) bool {
+	y, ok := v.(*Vertex)
+	if !ok {
+		return false
+	}
+	v, ok1 := x.BaseValue.(Value)
+	w, ok2 := y.BaseValue.(Value)
+	if !ok1 && !ok2 {
+		return true // both are struct or list.
+	}
+	return equalTerminal(v, w, flags)
+}
+
+//go:noinline
+func equalTerminal(x Value, y Value, flags Flag) bool {
+	foo = fmt.Sprintf("EQclosed %s %s %d\n", x.(*Vertex).name, y.(*Vertex).name, flags)
+	return true
+}
diff --git a/test/fixedbugs/issue45913.go b/test/fixedbugs/issue45913.go
new file mode 100644
index 0000000..aa86028
--- /dev/null
+++ b/test/fixedbugs/issue45913.go
@@ -0,0 +1,17 @@
+// errorcheck
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+func f(s1, s2 string) { fmt.Printf("%s %s", s1, s2) }
+
+func main() {
+	f([2]string{"a", "b"}...) // ERROR "invalid use of .*[.][.][.]|cannot use [.][.][.] in call to non-variadic"
+}
diff --git a/test/fixedbugs/issue45947.go b/test/fixedbugs/issue45947.go
new file mode 100644
index 0000000..4086449
--- /dev/null
+++ b/test/fixedbugs/issue45947.go
@@ -0,0 +1,16 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f() {
+	_ = func() func() {
+		return func() {
+		l:
+			goto l
+		}
+	}()
+}
diff --git a/test/fixedbugs/issue45948.go b/test/fixedbugs/issue45948.go
new file mode 100644
index 0000000..37f8e70
--- /dev/null
+++ b/test/fixedbugs/issue45948.go
@@ -0,0 +1,16 @@
+// compile -N
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 45948: assert in debug generation for degenerate
+// function with infinite loop.
+
+package p
+
+func f(p int) {
+L:
+	goto L
+
+}
diff --git a/test/fixedbugs/issue46234.go b/test/fixedbugs/issue46234.go
new file mode 100644
index 0000000..8e7eb8b
--- /dev/null
+++ b/test/fixedbugs/issue46234.go
@@ -0,0 +1,103 @@
+// buildrun -t 30
+
+// +build !js
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Ensure that runtime traceback does not infinite loop for
+// the testcase below.
+
+package main
+
+import (
+	"bytes"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+)
+
+const prog = `
+
+package main
+
+import "context"
+
+var gpi *int
+
+type nAO struct {
+	eE bool
+}
+
+type NAO func(*nAO)
+
+func WEA() NAO {
+	return func(o *nAO) { o.eE = true }
+}
+
+type R struct {
+	cM *CM
+}
+
+type CM int
+
+type A string
+
+func (m *CM) NewA(ctx context.Context, cN string, nn *nAO, opts ...NAO) (*A, error) {
+	for _, o := range opts {
+		o(nn)
+	}
+	s := A("foo")
+	return &s, nil
+}
+
+func (r *R) CA(ctx context.Context, cN string, nn *nAO) (*int, error) {
+	cA, err := r.cM.NewA(ctx, cN, nn, WEA(), WEA())
+	if err == nil {
+		return nil, err
+	}
+	println(cA)
+	x := int(42)
+	return &x, nil
+}
+
+func main() {
+	c := CM(1)
+	r := R{cM: &c}
+	var ctx context.Context
+	nnr := nAO{}
+	pi, err := r.CA(ctx, "foo", nil)
+	if err != nil {
+		panic("bad")
+	}
+	println(nnr.eE)
+	gpi = pi
+}
+`
+
+func main() {
+	dir, err := ioutil.TempDir("", "46234")
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
+
+	file := filepath.Join(dir, "main.go")
+	if err := ioutil.WriteFile(file, []byte(prog), 0655); err != nil {
+		log.Fatalf("Write error %v", err)
+	}
+
+	cmd := exec.Command("go", "run", file)
+	output, err := cmd.CombinedOutput()
+	if err == nil {
+		log.Fatalf("Passed, expected an error")
+	}
+
+	want := []byte("nil pointer dereference")
+	if !bytes.Contains(output, want) {
+		log.Fatalf("Unmatched error message %q:\nin\n%s\nError: %v", want, output, err)
+	}
+}
diff --git a/test/fixedbugs/issue46304.go b/test/fixedbugs/issue46304.go
new file mode 100644
index 0000000..b8ecfc9
--- /dev/null
+++ b/test/fixedbugs/issue46304.go
@@ -0,0 +1,76 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This testcase caused a crash when the register ABI was in effect,
+// on amd64 (problem with register allocation).
+
+package main
+
+type Op struct {
+	tag   string
+	_x    []string
+	_q    [20]uint64
+	plist []P
+}
+
+type P struct {
+	tag string
+	_x  [10]uint64
+	b   bool
+}
+
+type M int
+
+//go:noinline
+func (w *M) walkP(p *P) *P {
+	np := &P{}
+	*np = *p
+	np.tag += "new"
+	return np
+}
+
+func (w *M) walkOp(op *Op) *Op {
+	if op == nil {
+		return nil
+	}
+
+	orig := op
+	cloned := false
+	clone := func() {
+		if !cloned {
+			cloned = true
+			op = &Op{}
+			*op = *orig
+		}
+	}
+
+	pCloned := false
+	for i := range op.plist {
+		if s := w.walkP(&op.plist[i]); s != &op.plist[i] {
+			if !pCloned {
+				pCloned = true
+				clone()
+				op.plist = make([]P, len(orig.plist))
+				copy(op.plist, orig.plist)
+			}
+			op.plist[i] = *s
+		}
+	}
+
+	return op
+}
+
+func main() {
+	var ww M
+	w := &ww
+	p1 := P{tag: "a"}
+	p1._x[1] = 9
+	o := Op{tag: "old", plist: []P{p1}}
+	no := w.walkOp(&o)
+	if no.plist[0].tag != "anew" {
+		panic("bad")
+	}
+}
diff --git a/test/fixedbugs/issue46386.go b/test/fixedbugs/issue46386.go
new file mode 100644
index 0000000..89dea8a
--- /dev/null
+++ b/test/fixedbugs/issue46386.go
@@ -0,0 +1,32 @@
+// compile -p=main
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type I interface {
+	M() interface{}
+}
+
+type S1 struct{}
+
+func (S1) M() interface{} {
+	return nil
+}
+
+type EI interface{}
+
+type S struct{}
+
+func (S) M(as interface{ I }) {}
+
+func f() interface{ EI } {
+	return &S1{}
+}
+
+func main() {
+	var i interface{ I }
+	(&S{}).M(i)
+}
diff --git a/test/fixedbugs/issue46525.go b/test/fixedbugs/issue46525.go
new file mode 100644
index 0000000..164e147
--- /dev/null
+++ b/test/fixedbugs/issue46525.go
@@ -0,0 +1,14 @@
+// errorcheck -lang=go1.16
+
+// Copyright 2021 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package p
+
+import "unsafe"
+
+func main() {
+	_ = unsafe.Add(unsafe.Pointer(nil), 0) // ERROR "unsafe.Add requires go1.17 or later"
+	_ = unsafe.Slice(new(byte), 1)         // ERROR "unsafe.Slice requires go1.17 or later"
+}
diff --git a/test/fixedbugs/issue46653.dir/bad/bad.go b/test/fixedbugs/issue46653.dir/bad/bad.go
new file mode 100644
index 0000000..c1611b8
--- /dev/null
+++ b/test/fixedbugs/issue46653.dir/bad/bad.go
@@ -0,0 +1,64 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+func Bad() {
+	m := make(map[int64]A)
+	a := m[0]
+	if len(a.B.C1.D2.E2.F1) != 0 ||
+		len(a.B.C1.D2.E2.F2) != 0 ||
+		len(a.B.C1.D2.E2.F3) != 0 ||
+		len(a.B.C1.D2.E2.F4) != 0 ||
+		len(a.B.C1.D2.E2.F5) != 0 ||
+		len(a.B.C1.D2.E2.F6) != 0 ||
+		len(a.B.C1.D2.E2.F7) != 0 ||
+		len(a.B.C1.D2.E2.F8) != 0 ||
+		len(a.B.C1.D2.E2.F9) != 0 ||
+		len(a.B.C1.D2.E2.F10) != 0 ||
+		len(a.B.C1.D2.E2.F11) != 0 ||
+		len(a.B.C1.D2.E2.F16) != 0 {
+		panic("bad")
+	}
+}
+
+type A struct {
+	B
+}
+
+type B struct {
+	C1 C
+	C2 C
+}
+
+type C struct {
+	D1 D
+	D2 D
+}
+
+type D struct {
+	E1 E
+	E2 E
+	E3 E
+	E4 E
+}
+
+type E struct {
+	F1  string
+	F2  string
+	F3  string
+	F4  string
+	F5  string
+	F6  string
+	F7  string
+	F8  string
+	F9  string
+	F10 string
+	F11 string
+	F12 string
+	F13 string
+	F14 string
+	F15 string
+	F16 string
+}
diff --git a/test/fixedbugs/issue46653.dir/main.go b/test/fixedbugs/issue46653.dir/main.go
new file mode 100644
index 0000000..e2a96e5
--- /dev/null
+++ b/test/fixedbugs/issue46653.dir/main.go
@@ -0,0 +1,27 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	bad "issue46653.dir/bad"
+)
+
+func main() {
+	bad.Bad()
+}
+
+func neverCalled() L {
+	m := make(map[string]L)
+	return m[""]
+}
+
+type L struct {
+	A Data
+	B Data
+}
+
+type Data struct {
+	F1 [22][]string
+}
diff --git a/test/fixedbugs/issue46653.go b/test/fixedbugs/issue46653.go
new file mode 100644
index 0000000..e6283b1
--- /dev/null
+++ b/test/fixedbugs/issue46653.go
@@ -0,0 +1,10 @@
+// runindir
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test to verify compiler and linker handling of multiple
+// competing map.zero symbol definitions.
+
+package ignored
diff --git a/test/fixedbugs/issue46720.go b/test/fixedbugs/issue46720.go
new file mode 100644
index 0000000..3b0151a
--- /dev/null
+++ b/test/fixedbugs/issue46720.go
@@ -0,0 +1,15 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f() {
+	nonce := make([]byte, 24)
+	g((*[24]byte)(nonce))
+}
+
+//go:noinline
+func g(*[24]byte) {}
diff --git a/test/fixedbugs/issue46725.go b/test/fixedbugs/issue46725.go
new file mode 100644
index 0000000..29799c7
--- /dev/null
+++ b/test/fixedbugs/issue46725.go
@@ -0,0 +1,48 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "runtime"
+
+type T [4]int
+
+//go:noinline
+func g(x []*T) ([]*T, []*T) { return x, x }
+
+func main() {
+	const Jenny = 8675309
+	s := [10]*T{{Jenny}}
+
+	done := make(chan struct{})
+	runtime.SetFinalizer(s[0], func(p *T) { close(done) })
+
+	var h, _ interface{} = g(s[:])
+
+	if wait(done) {
+		panic("GC'd early")
+	}
+
+	if h.([]*T)[0][0] != Jenny {
+		panic("lost Jenny's number")
+	}
+
+	if !wait(done) {
+		panic("never GC'd")
+	}
+}
+
+func wait(done <-chan struct{}) bool {
+	for i := 0; i < 10; i++ {
+		runtime.GC()
+		select {
+		case <-done:
+			return true
+		default:
+		}
+	}
+	return false
+}
diff --git a/test/fixedbugs/issue46749.go b/test/fixedbugs/issue46749.go
new file mode 100644
index 0000000..63ed197
--- /dev/null
+++ b/test/fixedbugs/issue46749.go
@@ -0,0 +1,37 @@
+// errorcheck
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+var s string
+var b bool
+var i int
+var iface interface{}
+
+var (
+	_ = "" + b   // ERROR "invalid operation.*mismatched types.*untyped string and bool"
+	_ = "" + i   // ERROR "invalid operation.*mismatched types.*untyped string and int"
+	_ = "" + nil // ERROR "invalid operation.*mismatched types.*untyped string and nil"
+)
+
+var (
+	_ = s + false // ERROR "invalid operation.*mismatched types.*string and untyped bool"
+	_ = s + 1     // ERROR "invalid operation.*mismatched types.*string and untyped int"
+	_ = s + nil   // ERROR "invalid operation.*mismatched types.*string and nil"
+)
+
+var (
+	_ = "" + false // ERROR "invalid operation.*mismatched types.*untyped string and untyped bool"
+	_ = "" + 1     // ERROR "invalid operation.*mismatched types.*untyped string and untyped int"
+)
+
+var (
+	_ = b + 1         // ERROR "invalid operation.*mismatched types.*bool and untyped int"
+	_ = i + false     // ERROR "invalid operation.*mismatched types.*int and untyped bool"
+	_ = iface + 1     // ERROR "invalid operation.*mismatched types.*interface {} and int"
+	_ = iface + 1.0   // ERROR "invalid operation.*mismatched types.*interface {} and float64"
+	_ = iface + false // ERROR "invalid operation.*mismatched types.*interface {} and bool"
+)
diff --git a/test/fixedbugs/issue46907.go b/test/fixedbugs/issue46907.go
new file mode 100644
index 0000000..bd82f4f
--- /dev/null
+++ b/test/fixedbugs/issue46907.go
@@ -0,0 +1,11 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f(b []byte) []byte {
+	return (*[32]byte)(b[:32])[:]
+}
diff --git a/test/fixedbugs/issue46957.go b/test/fixedbugs/issue46957.go
new file mode 100644
index 0000000..f3ed3c3
--- /dev/null
+++ b/test/fixedbugs/issue46957.go
@@ -0,0 +1,13 @@
+// errorcheck
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func f(a int, b ...int) {}
+
+func main() {
+	f(nil...) // ERROR "not enough arguments in call to f$"
+}
diff --git a/test/fixedbugs/issue47087.dir/a.go b/test/fixedbugs/issue47087.dir/a.go
new file mode 100644
index 0000000..6093092
--- /dev/null
+++ b/test/fixedbugs/issue47087.dir/a.go
@@ -0,0 +1,9 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+func F() interface{} { return struct{ _ []int }{} }
+
+var X = F()
diff --git a/test/fixedbugs/issue47087.dir/b.go b/test/fixedbugs/issue47087.dir/b.go
new file mode 100644
index 0000000..8f96d25
--- /dev/null
+++ b/test/fixedbugs/issue47087.dir/b.go
@@ -0,0 +1,9 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+func F() interface{} { return struct{ _ []int }{} }
+
+var X = F()
diff --git a/test/fixedbugs/issue47087.dir/main.go b/test/fixedbugs/issue47087.dir/main.go
new file mode 100644
index 0000000..ccd0891
--- /dev/null
+++ b/test/fixedbugs/issue47087.dir/main.go
@@ -0,0 +1,19 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"a"
+	"b"
+)
+
+func main() {
+	if a.F() == b.F() {
+		panic("FAIL")
+	}
+	if a.X == b.X {
+		panic("FAIL")
+	}
+}
diff --git a/test/fixedbugs/issue47087.go b/test/fixedbugs/issue47087.go
new file mode 100644
index 0000000..40df49f
--- /dev/null
+++ b/test/fixedbugs/issue47087.go
@@ -0,0 +1,7 @@
+// rundir
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue47185.dir/bad/bad.go b/test/fixedbugs/issue47185.dir/bad/bad.go
new file mode 100644
index 0000000..1aa4fbb
--- /dev/null
+++ b/test/fixedbugs/issue47185.dir/bad/bad.go
@@ -0,0 +1,72 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+// Note that the use of CGO here is solely to trigger external
+// linking, since that is required to trigger that bad behavior
+// in this bug.
+
+// #include <stdlib.h>
+import "C"
+
+func Bad() {
+	m := make(map[int64]A)
+	a := m[0]
+	if len(a.B.C1.D2.E2.F1) != 0 ||
+		len(a.B.C1.D2.E2.F2) != 0 ||
+		len(a.B.C1.D2.E2.F3) != 0 ||
+		len(a.B.C1.D2.E2.F4) != 0 ||
+		len(a.B.C1.D2.E2.F5) != 0 ||
+		len(a.B.C1.D2.E2.F6) != 0 ||
+		len(a.B.C1.D2.E2.F7) != 0 ||
+		len(a.B.C1.D2.E2.F8) != 0 ||
+		len(a.B.C1.D2.E2.F9) != 0 ||
+		len(a.B.C1.D2.E2.F10) != 0 ||
+		len(a.B.C1.D2.E2.F11) != 0 ||
+		len(a.B.C1.D2.E2.F16) != 0 {
+		panic("bad")
+	}
+	C.malloc(100)
+}
+
+type A struct {
+	B
+}
+
+type B struct {
+	C1 C
+	C2 C
+}
+
+type C struct {
+	D1 D
+	D2 D
+}
+
+type D struct {
+	E1 E
+	E2 E
+	E3 E
+	E4 E
+}
+
+type E struct {
+	F1  string
+	F2  string
+	F3  string
+	F4  string
+	F5  string
+	F6  string
+	F7  string
+	F8  string
+	F9  string
+	F10 string
+	F11 string
+	F12 string
+	F13 string
+	F14 string
+	F15 string
+	F16 string
+}
diff --git a/test/fixedbugs/issue47185.dir/main.go b/test/fixedbugs/issue47185.dir/main.go
new file mode 100644
index 0000000..7b46e55
--- /dev/null
+++ b/test/fixedbugs/issue47185.dir/main.go
@@ -0,0 +1,28 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	bad "issue47185.dir/bad"
+)
+
+func main() {
+	another()
+	bad.Bad()
+}
+
+func another() L {
+	m := make(map[string]L)
+	return m[""]
+}
+
+type L struct {
+	A Data
+	B Data
+}
+
+type Data struct {
+	F1 [22][]string
+}
diff --git a/test/fixedbugs/issue47185.go b/test/fixedbugs/issue47185.go
new file mode 100644
index 0000000..9c921b8
--- /dev/null
+++ b/test/fixedbugs/issue47185.go
@@ -0,0 +1,11 @@
+// +build cgo
+// runindir
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Another test to verify compiler and linker handling of multiple
+// competing map.zero symbol definitions.
+
+package ignored
diff --git a/test/fixedbugs/issue47201.dir/a.go b/test/fixedbugs/issue47201.dir/a.go
new file mode 100644
index 0000000..54b7079
--- /dev/null
+++ b/test/fixedbugs/issue47201.dir/a.go
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	. "fmt"
+)
+
+func test() {
+	Println("foo")
+}
diff --git a/test/fixedbugs/issue47201.dir/b.go b/test/fixedbugs/issue47201.dir/b.go
new file mode 100644
index 0000000..5fd0635
--- /dev/null
+++ b/test/fixedbugs/issue47201.dir/b.go
@@ -0,0 +1,9 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func Println() {} // ERROR "Println redeclared in this block"
+
+func main() {}
diff --git a/test/fixedbugs/issue47201.go b/test/fixedbugs/issue47201.go
new file mode 100644
index 0000000..e3a470b
--- /dev/null
+++ b/test/fixedbugs/issue47201.go
@@ -0,0 +1,7 @@
+// errorcheckdir
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue47317.dir/a.s b/test/fixedbugs/issue47317.dir/a.s
new file mode 100644
index 0000000..b969ddb
--- /dev/null
+++ b/test/fixedbugs/issue47317.dir/a.s
@@ -0,0 +1,6 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+TEXT	·G(SB),4,$0
+	RET
diff --git a/test/fixedbugs/issue47317.dir/x.go b/test/fixedbugs/issue47317.dir/x.go
new file mode 100644
index 0000000..83b5542
--- /dev/null
+++ b/test/fixedbugs/issue47317.dir/x.go
@@ -0,0 +1,17 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 47317: ICE when calling ABI0 function via func value.
+
+package main
+
+func main() { F() }
+
+func F() interface{} {
+	g := G
+	g(1)
+	return G
+}
+
+func G(x int) [2]int
diff --git a/test/fixedbugs/issue47317.go b/test/fixedbugs/issue47317.go
new file mode 100644
index 0000000..3548e90
--- /dev/null
+++ b/test/fixedbugs/issue47317.go
@@ -0,0 +1,7 @@
+// builddir
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue4909a.go b/test/fixedbugs/issue4909a.go
index 09e1b85..27ae294 100644
--- a/test/fixedbugs/issue4909a.go
+++ b/test/fixedbugs/issue4909a.go
@@ -27,8 +27,8 @@
 var t T
 var p *T
 
-const N1 = unsafe.Offsetof(t.X)      // ERROR "indirection"
-const N2 = unsafe.Offsetof(p.X)      // ERROR "indirection"
+const N1 = unsafe.Offsetof(t.X)      // ERROR "indirection|field X is embedded via a pointer in T"
+const N2 = unsafe.Offsetof(p.X)      // ERROR "indirection|field X is embedded via a pointer in T"
 const N3 = unsafe.Offsetof(t.B.X)    // valid
 const N4 = unsafe.Offsetof(p.B.X)    // valid
 const N5 = unsafe.Offsetof(t.Method) // ERROR "method value"
diff --git a/test/fixedbugs/issue5493.go b/test/fixedbugs/issue5493.go
index 2ee0398..8f771bc 100644
--- a/test/fixedbugs/issue5493.go
+++ b/test/fixedbugs/issue5493.go
@@ -14,6 +14,7 @@
 )
 
 const N = 10
+
 var count int64
 
 func run() error {
@@ -31,10 +32,9 @@
 }
 
 func main() {
-	// Does not work on 32-bits, or with gccgo, due to partially
-	// conservative GC.
+	// Does not work with gccgo, due to partially conservative GC.
 	// Try to enable when we have fully precise GC.
-	if runtime.GOARCH != "amd64" || runtime.Compiler == "gccgo" {
+	if runtime.Compiler == "gccgo" {
 		return
 	}
 	count = N
@@ -56,4 +56,3 @@
 		panic("not all finalizers are called")
 	}
 }
-
diff --git a/test/fixedbugs/issue6402.go b/test/fixedbugs/issue6402.go
index ecde9ae..39cb9ac 100644
--- a/test/fixedbugs/issue6402.go
+++ b/test/fixedbugs/issue6402.go
@@ -9,5 +9,5 @@
 package p
 
 func f() uintptr {
-	return nil // ERROR "cannot use nil as type uintptr in return argument|incompatible type"
+	return nil // ERROR "cannot use nil as type uintptr in return argument|incompatible type|cannot use untyped nil"
 }
diff --git a/test/fixedbugs/issue6428.go b/test/fixedbugs/issue6428.go
new file mode 100644
index 0000000..c3f7b20
--- /dev/null
+++ b/test/fixedbugs/issue6428.go
@@ -0,0 +1,15 @@
+// errorcheck
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import . "testing" // ERROR "imported and not used"
+
+type S struct {
+	T int
+}
+
+var _ = S{T: 0}
diff --git a/test/fixedbugs/issue6572.go b/test/fixedbugs/issue6572.go
index e4465e9..9f4d2de 100644
--- a/test/fixedbugs/issue6572.go
+++ b/test/fixedbugs/issue6572.go
@@ -17,5 +17,6 @@
 func main() {
 	var x, y, z int
 	x, y = foo()
-	x, y, z = bar() // ERROR "cannot (use type|assign) string"
+	x, y, z = bar() // ERROR "cannot (use type|assign) string|incompatible type"
+	_, _, _ = x, y, z
 }
diff --git a/test/fixedbugs/issue6750.go b/test/fixedbugs/issue6750.go
index f62a850..fca4e66 100644
--- a/test/fixedbugs/issue6750.go
+++ b/test/fixedbugs/issue6750.go
@@ -18,5 +18,5 @@
 func main() {
 	printmany(1, 2, 3)
 	printmany([]int{1, 2, 3}...)
-	printmany(1, "abc", []int{2, 3}...) // ERROR "too many arguments in call to printmany\n\thave \(number, string, \.\.\.int\)\n\twant \(...int\)"
+	printmany(1, "abc", []int{2, 3}...) // ERROR "too many arguments in call( to printmany\n\thave \(number, string, \.\.\.int\)\n\twant \(...int\))?"
 }
diff --git a/test/fixedbugs/issue6772.go b/test/fixedbugs/issue6772.go
index 5bd15ba..5cc89b4 100644
--- a/test/fixedbugs/issue6772.go
+++ b/test/fixedbugs/issue6772.go
@@ -7,14 +7,14 @@
 package p
 
 func f1() {
-	for a, a := range []int{1, 2, 3} { // ERROR "a.* repeated on left side of :="
+	for a, a := range []int{1, 2, 3} { // ERROR "a.* repeated on left side of :=|a redeclared"
 		println(a)
 	}
 }
 
 func f2() {
 	var a int
-	for a, a := range []int{1, 2, 3} { // ERROR "a.* repeated on left side of :="
+	for a, a := range []int{1, 2, 3} { // ERROR "a.* repeated on left side of :=|a redeclared"
 		println(a)
 	}
 	println(a)
diff --git a/test/fixedbugs/issue7129.go b/test/fixedbugs/issue7129.go
index 2765200..70dc263 100644
--- a/test/fixedbugs/issue7129.go
+++ b/test/fixedbugs/issue7129.go
@@ -15,7 +15,7 @@
 func h(int, int) {}
 
 func main() {
-	f(g())        // ERROR "in argument to f|incompatible type"
-	f(true)       // ERROR "in argument to f|incompatible type"
-	h(true, true) // ERROR "in argument to h|incompatible type"
+	f(g())        // ERROR "in argument to f|incompatible type|cannot convert"
+	f(true)       // ERROR "in argument to f|incompatible type|cannot convert"
+	h(true, true) // ERROR "in argument to h|incompatible type|cannot convert"
 }
diff --git a/test/fixedbugs/issue7150.go b/test/fixedbugs/issue7150.go
index 7cddf48..52eed93 100644
--- a/test/fixedbugs/issue7150.go
+++ b/test/fixedbugs/issue7150.go
@@ -9,7 +9,7 @@
 package main
 
 func main() {
-	_ = [0]int{-1: 50}              // ERROR "index must be non-negative integer constant|index expression is negative"
+	_ = [0]int{-1: 50}              // ERROR "index must be non-negative integer constant|index expression is negative|must not be negative"
 	_ = [0]int{0: 0}                // ERROR "index 0 out of bounds \[0:0\]|out of range"
 	_ = [0]int{5: 25}               // ERROR "index 5 out of bounds \[0:0\]|out of range"
 	_ = [10]int{2: 10, 15: 30}      // ERROR "index 15 out of bounds \[0:10\]|out of range"
diff --git a/test/fixedbugs/issue7153.go b/test/fixedbugs/issue7153.go
index e8b95d5..0b29ec7 100644
--- a/test/fixedbugs/issue7153.go
+++ b/test/fixedbugs/issue7153.go
@@ -8,4 +8,4 @@
 
 package p
 
-var _ = []int{a: true, true} // ERROR "undefined: a" "cannot use true \(type untyped bool\) as type int in slice literal|undefined name .*a|incompatible type"
+var _ = []int{a: true, true} // ERROR "undefined: a" "cannot use true \(type untyped bool\) as type int in slice literal|undefined name .*a|incompatible type|cannot use"
diff --git a/test/fixedbugs/issue7223.go b/test/fixedbugs/issue7223.go
index 0ec3476..c78de28 100644
--- a/test/fixedbugs/issue7223.go
+++ b/test/fixedbugs/issue7223.go
@@ -12,9 +12,9 @@
 func main() {
 	_ = make([]byte, 1<<bits1)
 	_ = make([]byte, 1<<bits2)
-	_ = make([]byte, nil) // ERROR "non-integer.*len"
-	_ = make([]byte, nil, 2) // ERROR "non-integer.*len"
-	_ = make([]byte, 1, nil) // ERROR "non-integer.*cap"
-	_ = make([]byte, true) // ERROR "non-integer.*len"
-	_ = make([]byte, "abc") // ERROR "non-integer.*len"
+	_ = make([]byte, nil) // ERROR "non-integer.*len|untyped nil"
+	_ = make([]byte, nil, 2) // ERROR "non-integer.*len|untyped nil"
+	_ = make([]byte, 1, nil) // ERROR "non-integer.*cap|untyped nil"
+	_ = make([]byte, true) // ERROR "non-integer.*len|untyped bool"
+	_ = make([]byte, "abc") // ERROR "non-integer.*len|untyped string"
 }
diff --git a/test/fixedbugs/issue7310.go b/test/fixedbugs/issue7310.go
index ba50e42..4d10e47 100644
--- a/test/fixedbugs/issue7310.go
+++ b/test/fixedbugs/issue7310.go
@@ -9,7 +9,7 @@
 package main
 
 func main() {
-	_ = copy(nil, []int{}) // ERROR "use of untyped nil|left argument must be a slice"
-	_ = copy([]int{}, nil) // ERROR "use of untyped nil|second argument must be slice or string"
-	_ = 1 + true           // ERROR "mismatched types untyped int and untyped bool|incompatible types"
+	_ = copy(nil, []int{}) // ERROR "use of untyped nil|left argument must be a slice|expects slice arguments"
+	_ = copy([]int{}, nil) // ERROR "use of untyped nil|second argument must be slice or string|expects slice arguments"
+	_ = 1 + true           // ERROR "mismatched types untyped int and untyped bool|incompatible types|cannot convert"
 }
diff --git a/test/fixedbugs/issue7740.go b/test/fixedbugs/issue7740.go
index 8f1afe8..6bc6249 100644
--- a/test/fixedbugs/issue7740.go
+++ b/test/fixedbugs/issue7740.go
@@ -21,7 +21,7 @@
 	var prec float64
 	switch runtime.Compiler {
 	case "gc":
-		prec = 512
+		prec = math.Inf(1) // exact precision using rational arithmetic
 	case "gccgo":
 		prec = 256
 	default:
diff --git a/test/fixedbugs/issue7921.go b/test/fixedbugs/issue7921.go
index 5dce557..65be4b5 100644
--- a/test/fixedbugs/issue7921.go
+++ b/test/fixedbugs/issue7921.go
@@ -41,7 +41,7 @@
 
 func bufferNoEscape4() []byte {
 	var b bytes.Buffer
-	b.Grow(64) // ERROR "bufferNoEscape4 ignoring self-assignment in bytes.b.buf = bytes.b.buf\[:bytes.m·3\]$" "inlining call to bytes.\(\*Buffer\).Grow$"
+	b.Grow(64) // ERROR "bufferNoEscape4 ignoring self-assignment in bytes.b.buf = bytes.b.buf\[:bytes.m\]$" "inlining call to bytes.\(\*Buffer\).Grow$" "string\(.*\) escapes to heap"
 	useBuffer(&b)
 	return b.Bytes() // ERROR "inlining call to bytes.\(\*Buffer\).Bytes$"
 }
diff --git a/test/fixedbugs/issue8183.go b/test/fixedbugs/issue8183.go
index caac667..fe2dff7 100644
--- a/test/fixedbugs/issue8183.go
+++ b/test/fixedbugs/issue8183.go
@@ -12,12 +12,12 @@
 	ok = byte(iota + 253)
 	bad
 	barn
-	bard // ERROR "constant 256 overflows byte|integer constant overflow"
+	bard // ERROR "constant 256 overflows byte|integer constant overflow|cannot convert"
 )
 
 const (
 	c = len([1 - iota]int{})
 	d
-	e // ERROR "array bound must be non-negative|negative array bound"
-	f // ERROR "array bound must be non-negative|negative array bound"
+	e // ERROR "array bound must be non-negative|negative array bound|invalid array length"
+	f // ERROR "array bound must be non-negative|negative array bound|invalid array length"
 )
diff --git a/test/fixedbugs/issue8438.go b/test/fixedbugs/issue8438.go
index f433e36..fcbb4f8 100644
--- a/test/fixedbugs/issue8438.go
+++ b/test/fixedbugs/issue8438.go
@@ -10,8 +10,8 @@
 package main
 
 func main() {
-	_ = []byte{"foo"}   // ERROR "cannot use|incompatible type"
-	_ = []int{"foo"}    // ERROR "cannot use|incompatible type"
-	_ = []rune{"foo"}   // ERROR "cannot use|incompatible type"
+	_ = []byte{"foo"}   // ERROR "cannot use|incompatible type|cannot convert"
+	_ = []int{"foo"}    // ERROR "cannot use|incompatible type|cannot convert"
+	_ = []rune{"foo"}   // ERROR "cannot use|incompatible type|cannot convert"
 	_ = []string{"foo"} // OK
 }
diff --git a/test/fixedbugs/issue8440.go b/test/fixedbugs/issue8440.go
index e9c5b54..1d9fa93 100644
--- a/test/fixedbugs/issue8440.go
+++ b/test/fixedbugs/issue8440.go
@@ -7,5 +7,5 @@
 package main
 
 func main() {
-	n.foo = 6 // ERROR "undefined: n in n.foo|undefined name .*n"
+	n.foo = 6 // ERROR "undefined: n in n.foo|undefined name .*n|undefined: n"
 }
diff --git a/test/fixedbugs/issue8745.go b/test/fixedbugs/issue8745.go
index fee2ca7..c2d00a7 100644
--- a/test/fixedbugs/issue8745.go
+++ b/test/fixedbugs/issue8745.go
@@ -9,5 +9,5 @@
 package p
 
 func f(s string) {
-	var _ float64 = s[2] // ERROR "cannot use.*type byte.*as type float64"
+	var _ float64 = s[2] // ERROR "cannot use.*type byte.*as type float64|cannot use .* as float64 value"
 }
diff --git a/test/fixedbugs/issue9083.go b/test/fixedbugs/issue9083.go
index d4762f8..f5c5296 100644
--- a/test/fixedbugs/issue9083.go
+++ b/test/fixedbugs/issue9083.go
@@ -13,6 +13,7 @@
 
 func main() {
 	var x int
+	_ = x
 	x = make(map[int]int) // ERROR "cannot use make\(map\[int\]int\)|incompatible"
 	x = make(map[int]int, 0) // ERROR "cannot use make\(map\[int\]int, 0\)|incompatible"
 	x = make(map[int]int, zero) // ERROR "cannot use make\(map\[int\]int, zero\)|incompatible"
diff --git a/test/fixedbugs/issue9370.go b/test/fixedbugs/issue9370.go
index 6cc8d5b..1a45103 100644
--- a/test/fixedbugs/issue9370.go
+++ b/test/fixedbugs/issue9370.go
@@ -33,24 +33,24 @@
 var (
 	_ = e == c
 	_ = e != c
-	_ = e >= c // ERROR "invalid operation.*not defined|invalid comparison"
+	_ = e >= c // ERROR "invalid operation.*not defined|invalid comparison|cannot compare"
 	_ = c == e
 	_ = c != e
-	_ = c >= e // ERROR "invalid operation.*not defined|invalid comparison"
+	_ = c >= e // ERROR "invalid operation.*not defined|invalid comparison|cannot compare"
 
 	_ = i == c
 	_ = i != c
-	_ = i >= c // ERROR "invalid operation.*not defined|invalid comparison"
+	_ = i >= c // ERROR "invalid operation.*not defined|invalid comparison|cannot compare"
 	_ = c == i
 	_ = c != i
-	_ = c >= i // ERROR "invalid operation.*not defined|invalid comparison"
+	_ = c >= i // ERROR "invalid operation.*not defined|invalid comparison|cannot compare"
 
 	_ = e == n
 	_ = e != n
-	_ = e >= n // ERROR "invalid operation.*not defined|invalid comparison"
+	_ = e >= n // ERROR "invalid operation.*not defined|invalid comparison|cannot compare"
 	_ = n == e
 	_ = n != e
-	_ = n >= e // ERROR "invalid operation.*not defined|invalid comparison"
+	_ = n >= e // ERROR "invalid operation.*not defined|invalid comparison|cannot compare"
 
 	// i and n are not assignable to each other
 	_ = i == n // ERROR "invalid operation.*mismatched types|incompatible types"
@@ -67,12 +67,12 @@
 	_ = 1 != e
 	_ = 1 >= e // ERROR "invalid operation.*not defined|invalid comparison"
 
-	_ = i == 1 // ERROR "invalid operation.*mismatched types|incompatible types"
-	_ = i != 1 // ERROR "invalid operation.*mismatched types|incompatible types"
-	_ = i >= 1 // ERROR "invalid operation.*mismatched types|incompatible types"
-	_ = 1 == i // ERROR "invalid operation.*mismatched types|incompatible types"
-	_ = 1 != i // ERROR "invalid operation.*mismatched types|incompatible types"
-	_ = 1 >= i // ERROR "invalid operation.*mismatched types|incompatible types"
+	_ = i == 1 // ERROR "invalid operation.*mismatched types|incompatible types|cannot convert"
+	_ = i != 1 // ERROR "invalid operation.*mismatched types|incompatible types|cannot convert"
+	_ = i >= 1 // ERROR "invalid operation.*mismatched types|incompatible types|cannot convert"
+	_ = 1 == i // ERROR "invalid operation.*mismatched types|incompatible types|cannot convert"
+	_ = 1 != i // ERROR "invalid operation.*mismatched types|incompatible types|cannot convert"
+	_ = 1 >= i // ERROR "invalid operation.*mismatched types|incompatible types|cannot convert"
 
 	_ = e == f // ERROR "invalid operation.*not defined|invalid operation"
 	_ = e != f // ERROR "invalid operation.*not defined|invalid operation"
diff --git a/test/fixedbugs/issue9432.go b/test/fixedbugs/issue9432.go
index e8946a5..3df3b90 100644
--- a/test/fixedbugs/issue9432.go
+++ b/test/fixedbugs/issue9432.go
@@ -9,7 +9,7 @@
 // See golang.org/issue/9432.
 package p
 
-type foo struct { // ERROR "invalid recursive type"
+type foo struct { // ERROR "invalid recursive type|cycle"
 	bar  foo
 	blah foo
 }
diff --git a/test/fixedbugs/issue9634.go b/test/fixedbugs/issue9634.go
index 2d5aae4..86e3e9a 100644
--- a/test/fixedbugs/issue9634.go
+++ b/test/fixedbugs/issue9634.go
@@ -14,5 +14,5 @@
 		t []int
 		u int
 	}{}
-	_ = append(s, 0) // ERROR "must be a slice|must be slice"
+	_ = append(s, 0) // ERROR "must be a slice|must be slice|not a slice"
 }
diff --git a/test/float_lit3.go b/test/float_lit3.go
index c4d1aa5..850d02c 100644
--- a/test/float_lit3.go
+++ b/test/float_lit3.go
@@ -37,12 +37,11 @@
 
 	// If the compiler's internal floating point representation
 	// is shorter than 1024 bits, it cannot distinguish max64+ulp64/2-1 and max64+ulp64/2.
-	// gc uses fewer than 1024 bits, so allow it to print the overflow error for the -1 case.
 	float64(max64 + ulp64/2 - two1024/two256), // ok
-	float64(max64 + ulp64/2 - 1),              // GC_ERROR "constant 1\.79769e\+308 overflows float64"
+	float64(max64 + ulp64/2 - 1),              // ok
 	float64(max64 + ulp64/2),                  // ERROR "constant 1\.79769e\+308 overflows float64"
 
 	float64(-max64 - ulp64/2 + two1024/two256), // ok
-	float64(-max64 - ulp64/2 + 1),              // GC_ERROR "constant -1\.79769e\+308 overflows float64"
+	float64(-max64 - ulp64/2 + 1),              // ok
 	float64(-max64 - ulp64/2),                  // ERROR "constant -1\.79769e\+308 overflows float64"
 }
diff --git a/test/func1.go b/test/func1.go
index fb6f561..ec25161 100644
--- a/test/func1.go
+++ b/test/func1.go
@@ -14,6 +14,6 @@
 }
 
 
-func f2(a int) (a int, b float32) { // ERROR "duplicate argument a|definition"
+func f2(a int) (a int, b float32) { // ERROR "duplicate argument a|definition|redeclared"
 	return 8, 8.0
 }
diff --git a/test/funcdup.go b/test/funcdup.go
index 7b05d12..3dbb15b 100644
--- a/test/funcdup.go
+++ b/test/funcdup.go
@@ -7,21 +7,21 @@
 package p
 
 type T interface {
-	F1(i int) (i int) // ERROR "duplicate argument i|redefinition|previous"
-	F2(i, i int) // ERROR "duplicate argument i|redefinition|previous"
-	F3() (i, i int) // ERROR "duplicate argument i|redefinition|previous"
+	F1(i int) (i int) // ERROR "duplicate argument i|redefinition|previous|redeclared"
+	F2(i, i int) // ERROR "duplicate argument i|redefinition|previous|redeclared"
+	F3() (i, i int) // ERROR "duplicate argument i|redefinition|previous|redeclared"
 }
 
-type T1 func(i, i int) // ERROR "duplicate argument i|redefinition|previous"
-type T2 func(i int) (i int) // ERROR "duplicate argument i|redefinition|previous"
-type T3 func() (i, i int) // ERROR "duplicate argument i|redefinition|previous"
+type T1 func(i, i int) // ERROR "duplicate argument i|redefinition|previous|redeclared"
+type T2 func(i int) (i int) // ERROR "duplicate argument i|redefinition|previous|redeclared"
+type T3 func() (i, i int) // ERROR "duplicate argument i|redefinition|previous|redeclared"
 
 type R struct{}
 
-func (i *R) F1(i int)         {} // ERROR "duplicate argument i|redefinition|previous"
-func (i *R) F2() (i int)      {return 0} // ERROR "duplicate argument i|redefinition|previous"
-func (i *R) F3(j int) (j int) {return 0} // ERROR "duplicate argument j|redefinition|previous"
+func (i *R) F1(i int)         {} // ERROR "duplicate argument i|redefinition|previous|redeclared"
+func (i *R) F2() (i int)      {return 0} // ERROR "duplicate argument i|redefinition|previous|redeclared"
+func (i *R) F3(j int) (j int) {return 0} // ERROR "duplicate argument j|redefinition|previous|redeclared"
 
-func F1(i, i int)      {} // ERROR "duplicate argument i|redefinition|previous"
-func F2(i int) (i int) {return 0} // ERROR "duplicate argument i|redefinition|previous"
-func F3() (i, i int)   {return 0, 0} // ERROR "duplicate argument i|redefinition|previous"
+func F1(i, i int)      {} // ERROR "duplicate argument i|redefinition|previous|redeclared"
+func F2(i int) (i int) {return 0} // ERROR "duplicate argument i|redefinition|previous|redeclared"
+func F3() (i, i int)   {return 0, 0} // ERROR "duplicate argument i|redefinition|previous|redeclared"
diff --git a/test/funcdup2.go b/test/funcdup2.go
index 9513ef4..2ee3024 100644
--- a/test/funcdup2.go
+++ b/test/funcdup2.go
@@ -7,11 +7,11 @@
 package p
 
 var T interface {
-	F1(i int) (i int) // ERROR "duplicate argument i|redefinition|previous"
-	F2(i, i int) // ERROR "duplicate argument i|redefinition|previous"
-	F3() (i, i int) // ERROR "duplicate argument i|redefinition|previous"
+	F1(i int) (i int) // ERROR "duplicate argument i|redefinition|previous|redeclared"
+	F2(i, i int) // ERROR "duplicate argument i|redefinition|previous|redeclared"
+	F3() (i, i int) // ERROR "duplicate argument i|redefinition|previous|redeclared"
 }
 
-var T1 func(i, i int) // ERROR "duplicate argument i|redefinition|previous"
-var T2 func(i int) (i int) // ERROR "duplicate argument i|redefinition|previous"
-var T3 func() (i, i int) // ERROR "duplicate argument i|redefinition|previous"
+var T1 func(i, i int) // ERROR "duplicate argument i|redefinition|previous|redeclared"
+var T2 func(i int) (i int) // ERROR "duplicate argument i|redefinition|previous|redeclared"
+var T3 func() (i, i int) // ERROR "duplicate argument i|redefinition|previous|redeclared"
diff --git a/test/fuse.go b/test/fuse.go
new file mode 100644
index 0000000..ea908bf
--- /dev/null
+++ b/test/fuse.go
@@ -0,0 +1,190 @@
+// +build amd64,!gcflags_noopt arm64,!gcflags_noopt
+// errorcheck -0 -d=ssa/late_fuse/debug=1
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "strings"
+
+const Cf2 = 2.0
+
+func fEqEq(a int, f float64) bool {
+	return a == 0 && f > Cf2 || a == 0 && f < -Cf2 // ERROR "Redirect Eq64 based on Eq64$"
+}
+
+func fEqNeq(a int32, f float64) bool {
+	return a == 0 && f > Cf2 || a != 0 && f < -Cf2 // ERROR "Redirect Neq32 based on Eq32$"
+}
+
+func fEqLess(a int8, f float64) bool {
+	return a == 0 && f > Cf2 || a < 0 && f < -Cf2
+}
+
+func fEqLeq(a float64, f float64) bool {
+	return a == 0 && f > Cf2 || a <= 0 && f < -Cf2
+}
+
+func fEqLessU(a uint, f float64) bool {
+	return a == 0 && f > Cf2 || a < 0 && f < -Cf2
+}
+
+func fEqLeqU(a uint64, f float64) bool {
+	return a == 0 && f > Cf2 || a <= 0 && f < -Cf2 // ERROR "Redirect Leq64U based on Eq64$"
+}
+
+func fNeqEq(a int, f float64) bool {
+	return a != 0 && f > Cf2 || a == 0 && f < -Cf2 // ERROR "Redirect Eq64 based on Neq64$"
+}
+
+func fNeqNeq(a int32, f float64) bool {
+	return a != 0 && f > Cf2 || a != 0 && f < -Cf2 // ERROR "Redirect Neq32 based on Neq32$"
+}
+
+func fNeqLess(a float32, f float64) bool {
+	// TODO: Add support for floating point numbers in prove
+	return a != 0 && f > Cf2 || a < 0 && f < -Cf2
+}
+
+func fNeqLeq(a int16, f float64) bool {
+	return a != 0 && f > Cf2 || a <= 0 && f < -Cf2 // ERROR "Redirect Leq16 based on Neq16$"
+}
+
+func fNeqLessU(a uint, f float64) bool {
+	return a != 0 && f > Cf2 || a < 0 && f < -Cf2
+}
+
+func fNeqLeqU(a uint32, f float64) bool {
+	return a != 0 && f > Cf2 || a <= 0 && f < -Cf2 // ERROR "Redirect Leq32U based on Neq32$"
+}
+
+func fLessEq(a int, f float64) bool {
+	return a < 0 && f > Cf2 || a == 0 && f < -Cf2
+}
+
+func fLessNeq(a int32, f float64) bool {
+	return a < 0 && f > Cf2 || a != 0 && f < -Cf2
+}
+
+func fLessLess(a float32, f float64) bool {
+	return a < 0 && f > Cf2 || a < 0 && f < -Cf2 // ERROR "Redirect Less32F based on Less32F$"
+}
+
+func fLessLeq(a float64, f float64) bool {
+	return a < 0 && f > Cf2 || a <= 0 && f < -Cf2
+}
+
+func fLeqEq(a float64, f float64) bool {
+	return a <= 0 && f > Cf2 || a == 0 && f < -Cf2
+}
+
+func fLeqNeq(a int16, f float64) bool {
+	return a <= 0 && f > Cf2 || a != 0 && f < -Cf2 // ERROR "Redirect Neq16 based on Leq16$"
+}
+
+func fLeqLess(a float32, f float64) bool {
+	return a <= 0 && f > Cf2 || a < 0 && f < -Cf2
+}
+
+func fLeqLeq(a int8, f float64) bool {
+	return a <= 0 && f > Cf2 || a <= 0 && f < -Cf2 // ERROR "Redirect Leq8 based on Leq8$"
+}
+
+func fLessUEq(a uint8, f float64) bool {
+	return a < 0 && f > Cf2 || a == 0 && f < -Cf2
+}
+
+func fLessUNeq(a uint16, f float64) bool {
+	return a < 0 && f > Cf2 || a != 0 && f < -Cf2
+}
+
+func fLessULessU(a uint32, f float64) bool {
+	return a < 0 && f > Cf2 || a < 0 && f < -Cf2
+}
+
+func fLessULeqU(a uint64, f float64) bool {
+	return a < 0 && f > Cf2 || a <= 0 && f < -Cf2
+}
+
+func fLeqUEq(a uint8, f float64) bool {
+	return a <= 0 && f > Cf2 || a == 0 && f < -Cf2 // ERROR "Redirect Eq8 based on Leq8U$"
+}
+
+func fLeqUNeq(a uint16, f float64) bool {
+	return a <= 0 && f > Cf2 || a != 0 && f < -Cf2 // ERROR "Redirect Neq16 based on Leq16U$"
+}
+
+func fLeqLessU(a uint32, f float64) bool {
+	return a <= 0 && f > Cf2 || a < 0 && f < -Cf2
+}
+
+func fLeqLeqU(a uint64, f float64) bool {
+	return a <= 0 && f > Cf2 || a <= 0 && f < -Cf2 // ERROR "Redirect Leq64U based on Leq64U$"
+}
+
+// Arg tests are disabled because the op name is different on amd64 and arm64.
+
+func fEqPtrEqPtr(a, b *int, f float64) bool {
+	return a == b && f > Cf2 || a == b && f < -Cf2 // ERROR "Redirect EqPtr based on EqPtr$"
+}
+
+func fEqPtrNeqPtr(a, b *int, f float64) bool {
+	return a == b && f > Cf2 || a != b && f < -Cf2 // ERROR "Redirect NeqPtr based on EqPtr$"
+}
+
+func fNeqPtrEqPtr(a, b *int, f float64) bool {
+	return a != b && f > Cf2 || a == b && f < -Cf2 // ERROR "Redirect EqPtr based on NeqPtr$"
+}
+
+func fNeqPtrNeqPtr(a, b *int, f float64) bool {
+	return a != b && f > Cf2 || a != b && f < -Cf2 // ERROR "Redirect NeqPtr based on NeqPtr$"
+}
+
+func fEqInterEqInter(a interface{}, f float64) bool {
+	return a == nil && f > Cf2 || a == nil && f < -Cf2 // ERROR "Redirect IsNonNil based on IsNonNil$"
+}
+
+func fEqInterNeqInter(a interface{}, f float64) bool {
+	return a == nil && f > Cf2 || a != nil && f < -Cf2
+}
+
+func fNeqInterEqInter(a interface{}, f float64) bool {
+	return a != nil && f > Cf2 || a == nil && f < -Cf2
+}
+
+func fNeqInterNeqInter(a interface{}, f float64) bool {
+	return a != nil && f > Cf2 || a != nil && f < -Cf2 // ERROR "Redirect IsNonNil based on IsNonNil$"
+}
+
+func fEqSliceEqSlice(a []int, f float64) bool {
+	return a == nil && f > Cf2 || a == nil && f < -Cf2 // ERROR "Redirect IsNonNil based on IsNonNil$"
+}
+
+func fEqSliceNeqSlice(a []int, f float64) bool {
+	return a == nil && f > Cf2 || a != nil && f < -Cf2
+}
+
+func fNeqSliceEqSlice(a []int, f float64) bool {
+	return a != nil && f > Cf2 || a == nil && f < -Cf2
+}
+
+func fNeqSliceNeqSlice(a []int, f float64) bool {
+	return a != nil && f > Cf2 || a != nil && f < -Cf2 // ERROR "Redirect IsNonNil based on IsNonNil$"
+}
+
+func fPhi(a, b string) string {
+	aslash := strings.HasSuffix(a, "/") // ERROR "Redirect Phi based on Phi$"
+	bslash := strings.HasPrefix(b, "/")
+	switch {
+	case aslash && bslash:
+		return a + b[1:]
+	case !aslash && !bslash:
+		return a + "/" + b
+	}
+	return a + b
+}
+
+func main() {
+}
diff --git a/test/init.go b/test/init.go
index 5e18228..43bb3c6 100644
--- a/test/init.go
+++ b/test/init.go
@@ -14,6 +14,6 @@
 
 func main() {
 	init()         // ERROR "undefined.*init"
-	runtime.init() // ERROR "undefined.*runtime\.init|reference to undefined name"
+	runtime.init() // ERROR "undefined.*runtime\.init|reference to undefined name|undefined: runtime"
 	var _ = init   // ERROR "undefined.*init"
 }
diff --git a/test/initloop.go b/test/initloop.go
index d90395d..b1a8470 100644
--- a/test/initloop.go
+++ b/test/initloop.go
@@ -11,7 +11,7 @@
 
 var (
 	x int = a
-	a int = b // ERROR "a refers to\n.*b refers to\n.*c refers to\n.*a"
+	a int = b // ERROR "a refers to\n.*b refers to\n.*c refers to\n.*a|initialization loop"
 	b int = c
 	c int = a
 )
diff --git a/test/inline.go b/test/inline.go
index d754f06..472a941 100644
--- a/test/inline.go
+++ b/test/inline.go
@@ -1,4 +1,4 @@
-// errorcheck -0 -m
+// errorcheck -0 -m -d=inlfuncswithclosures=1
 
 // Copyright 2015 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -58,7 +58,7 @@
 var somethingWrong error
 
 // local closures can be inlined
-func l(x, y int) (int, int, error) {
+func l(x, y int) (int, int, error) { // ERROR "can inline l"
 	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
 	}
@@ -90,19 +90,19 @@
 // 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"
+	func(x int) {                  // ERROR "can inline o.func2"
 		if x > 10 {
-			foo = func() int { return 2 } // ERROR "can inline o.func2" "func literal escapes"
+			foo = func() int { return 2 } // ERROR "func literal does not escape" "can inline o.func2"
 		}
-	}(11)
+	}(11) // ERROR "inlining call to o.func2"
 	return foo()
 }
 
-func p() int {
+func p() int { // ERROR "can inline p"
 	return func() int { return 42 }() // ERROR "can inline p.func1" "inlining call to p.func1"
 }
 
-func q(x int) int {
+func q(x int) int { // ERROR "can inline q"
 	foo := func() int { return x * 2 } // ERROR "can inline q.func1" "func literal does not escape"
 	return foo()                       // ERROR "inlining call to q.func1"
 }
@@ -111,15 +111,15 @@
 	foo := func(x int) int { // ERROR "can inline r.func1" "func literal does not escape"
 		return x + z
 	}
-	bar := func(x int) int { // ERROR "func literal does not escape"
-		return x + func(y int) int { // ERROR "can inline r.func2.1"
+	bar := func(x int) int { // ERROR "func literal does not escape" "can inline r.func2"
+		return x + func(y int) int { // ERROR "can inline r.func2.1" "can inline r.func3"
 			return 2*y + x*z
 		}(x) // ERROR "inlining call to r.func2.1"
 	}
-	return foo(42) + bar(42) // ERROR "inlining call to r.func1"
+	return foo(42) + bar(42) // ERROR "inlining call to r.func1" "inlining call to r.func2" "inlining call to r.func3"
 }
 
-func s0(x int) int {
+func s0(x int) int { // ERROR "can inline s0"
 	foo := func() { // ERROR "can inline s0.func1" "func literal does not escape"
 		x = x + 1
 	}
@@ -127,7 +127,7 @@
 	return x
 }
 
-func s1(x int) int {
+func s1(x int) int { // ERROR "can inline s1"
 	foo := func() int { // ERROR "can inline s1.func1" "func literal does not escape"
 		return x
 	}
@@ -262,3 +262,31 @@
 func gd3() func() { // ERROR "can inline gd3"
 	return ii
 }
+
+// Issue #42788 - ensure ODEREF OCONVNOP* OADDR is low cost.
+func EncodeQuad(d []uint32, x [6]float32) { // ERROR "can inline EncodeQuad" "d does not escape"
+	_ = d[:6]
+	d[0] = float32bits(x[0]) // ERROR "inlining call to float32bits"
+	d[1] = float32bits(x[1]) // ERROR "inlining call to float32bits"
+	d[2] = float32bits(x[2]) // ERROR "inlining call to float32bits"
+	d[3] = float32bits(x[3]) // ERROR "inlining call to float32bits"
+	d[4] = float32bits(x[4]) // ERROR "inlining call to float32bits"
+	d[5] = float32bits(x[5]) // ERROR "inlining call to float32bits"
+}
+
+// float32bits is a copy of math.Float32bits to ensure that
+// these tests pass with `-gcflags=-l`.
+func float32bits(f float32) uint32 { // ERROR "can inline float32bits"
+	return *(*uint32)(unsafe.Pointer(&f))
+}
+
+// Ensure OCONVNOP is zero cost.
+func Conv(v uint64) uint64 { // ERROR "can inline Conv"
+	return conv2(conv2(conv2(v))) // ERROR "inlining call to (conv1|conv2)"
+}
+func conv2(v uint64) uint64 { // ERROR "can inline conv2"
+	return conv1(conv1(conv1(conv1(v)))) // ERROR "inlining call to conv1"
+}
+func conv1(v uint64) uint64 { // ERROR "can inline conv1"
+	return uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(v)))))))))))
+}
diff --git a/test/interface/embed2.go b/test/interface/embed2.go
index df3e2e4..97a2d96 100644
--- a/test/interface/embed2.go
+++ b/test/interface/embed2.go
@@ -48,25 +48,25 @@
 	check("t.M()", t.M())
 	check("pt.M()", pt.M())
 	check("ti.M()", ti.M())
-	check("pti.M()", pti.M()) // ERROR "pointer to interface, not interface"
+	check("pti.M()", pti.M()) // ERROR "pointer to interface, not interface|no field or method M"
 	check("s.M()", s.M())
 	check("ps.M()", ps.M())
 
 	i = t
 	check("i = t; i.M()", i.M())
-	check("i = t; pi.M()", pi.M()) // ERROR "pointer to interface, not interface"
+	check("i = t; pi.M()", pi.M()) // ERROR "pointer to interface, not interface|no field or method M"
 
 	i = pt
 	check("i = pt; i.M()", i.M())
-	check("i = pt; pi.M()", pi.M()) // ERROR "pointer to interface, not interface"
+	check("i = pt; pi.M()", pi.M()) // ERROR "pointer to interface, not interface|no field or method M"
 
 	i = s
 	check("i = s; i.M()", i.M())
-	check("i = s; pi.M()", pi.M()) // ERROR "pointer to interface, not interface"
+	check("i = s; pi.M()", pi.M()) // ERROR "pointer to interface, not interface|no field or method M"
 
 	i = ps
 	check("i = ps; i.M()", i.M())
-	check("i = ps; pi.M()", pi.M()) // ERROR "pointer to interface, not interface"
+	check("i = ps; pi.M()", pi.M()) // ERROR "pointer to interface, not interface|no field or method M"
 
 	if !ok {
 		println("BUG: interface10")
diff --git a/test/interface/explicit.go b/test/interface/explicit.go
index 3f9451e..1b7af67 100644
--- a/test/interface/explicit.go
+++ b/test/interface/explicit.go
@@ -38,7 +38,7 @@
 
 func main() {
 	e = t // ok
-	t = e // ERROR "need explicit|need type assertion"
+	t = e // ERROR "need explicit|need type assertion|incompatible type"
 
 	// neither of these can work,
 	// because i has an extra method
@@ -50,14 +50,14 @@
 	i2 = i // ERROR "incompatible|missing N method"
 
 	i = I(i2)  // ok
-	i2 = I2(i) // ERROR "invalid|missing N method"
+	i2 = I2(i) // ERROR "invalid|missing N method|cannot convert"
 
 	e = E(t) // ok
-	t = T(e) // ERROR "need explicit|need type assertion|incompatible"
+	t = T(e) // ERROR "need explicit|need type assertion|incompatible|cannot convert"
 
 	// cannot type-assert non-interfaces
 	f := 2.0
-	_ = f.(int) // ERROR "non-interface type|only valid for interface types"
+	_ = f.(int) // ERROR "non-interface type|only valid for interface types|not an interface type"
 
 }
 
@@ -83,8 +83,8 @@
 var m1 M = ii // ERROR "incompatible|missing"
 var m2 M = jj // ERROR "incompatible|wrong type for M method"
 
-var m3 = M(ii) // ERROR "invalid|missing"
-var m4 = M(jj) // ERROR "invalid|wrong type for M method"
+var m3 = M(ii) // ERROR "invalid|missing|cannot convert"
+var m4 = M(jj) // ERROR "invalid|wrong type for M method|cannot convert"
 
 type B1 interface {
 	_() // ERROR "methods must have a unique non-blank name"
@@ -100,6 +100,7 @@
 func (t *T2) M() {}
 func (t *T2) _() {}
 
-// Check that nothing satisfies an interface with blank methods.
-var b1 B1 = &T2{} // ERROR "incompatible|missing _ method"
-var b2 B2 = &T2{} // ERROR "incompatible|missing _ method"
+// Already reported about the invalid blank interface method above;
+// no need to report about not implementing it.
+var b1 B1 = &T2{}
+var b2 B2 = &T2{}
diff --git a/test/interface/pointer.go b/test/interface/pointer.go
index 2927050..c21e4da 100644
--- a/test/interface/pointer.go
+++ b/test/interface/pointer.go
@@ -32,7 +32,9 @@
 
 func main() {
 	print("call addinst\n")
-	var x Inst = AddInst(new(Start)) // ERROR "pointer to interface"
+	var x Inst = AddInst(new(Start)) // ERROR "pointer to interface|incompatible type"
+	_ = x
 	print("return from  addinst\n")
 	var y *Inst = new(Start)  // ERROR "pointer to interface|incompatible type"
+	_ = y
 }
diff --git a/test/interface/receiver1.go b/test/interface/receiver1.go
index 2b7ccdc..a0a8753 100644
--- a/test/interface/receiver1.go
+++ b/test/interface/receiver1.go
@@ -37,14 +37,14 @@
 	var sp SP
 
 	v = t
-	p = t // ERROR "does not implement|requires a pointer"
+	p = t // ERROR "does not implement|requires a pointer|cannot use"
 	_, _ = v, p
 	v = &t
 	p = &t
 	_, _ = v, p
 
 	v = s
-	p = s // ERROR "does not implement|requires a pointer"
+	p = s // ERROR "does not implement|requires a pointer|cannot use"
 	_, _ = v, p
 	v = &s
 	p = &s
diff --git a/test/linkname2.go b/test/linkname2.go
new file mode 100644
index 0000000..43e66a5
--- /dev/null
+++ b/test/linkname2.go
@@ -0,0 +1,30 @@
+// errorcheck
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Tests that errors are reported for misuse of linkname.
+package p
+
+import _ "unsafe"
+
+type t int
+
+var x, y int
+
+//go:linkname x ok
+
+// ERROR "//go:linkname requires linkname argument or -p compiler flag"
+// BAD: want error "//go:linkname must refer to declared function or variable"
+// BAD: want error "//go:linkname must refer to declared function or variable"
+// ERROR "duplicate //go:linkname for x"
+
+// The two BAD lines are just waiting for #42938 before we can
+// re-enable the errors.
+
+//line linkname2.go:18
+//go:linkname y
+//go:linkname nonexist nonexist
+//go:linkname t notvarfunc
+//go:linkname x duplicate
diff --git a/test/live.go b/test/live.go
index 3df7ab0..bc7b384 100644
--- a/test/live.go
+++ b/test/live.go
@@ -1,8 +1,10 @@
 // errorcheckwithauto -0 -l -live -wb=0 -d=ssa/insert_resched_checks/off
-// +build !ppc64,!ppc64le
+// +build !ppc64,!ppc64le,!goexperiment.regabi,!goexperiment.regabidefer
 
 // ppc64 needs a better tighten pass to make f18 pass
 // rescheduling checks need to be turned off because there are some live variables across the inserted check call
+//
+// For register ABI, liveness info changes slightly. See live_regabi.go.
 
 // Copyright 2014 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -718,5 +720,5 @@
 	}
 	ret := T{}
 	ret.s[0] = f()
-	return ret // ERROR "stack object .autotmp_5 T"
+	return ret // ERROR "stack object .autotmp_[0-9]+ T"
 }
diff --git a/test/live_regabi.go b/test/live_regabi.go
new file mode 100644
index 0000000..2b0278e
--- /dev/null
+++ b/test/live_regabi.go
@@ -0,0 +1,719 @@
+// errorcheckwithauto -0 -l -live -wb=0 -d=ssa/insert_resched_checks/off
+// +build amd64,goexperiment.regabidefer,goexperiment.regabiargs
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// liveness tests with inlining disabled.
+// see also live2.go.
+
+package main
+
+func printnl()
+
+//go:noescape
+func printpointer(**int)
+
+//go:noescape
+func printintpointer(*int)
+
+//go:noescape
+func printstringpointer(*string)
+
+//go:noescape
+func printstring(string)
+
+//go:noescape
+func printbytepointer(*byte)
+
+func printint(int)
+
+func f1() {
+	var x *int       // ERROR "stack object x \*int$"
+	printpointer(&x) // ERROR "live at call to printpointer: x$"
+	printpointer(&x)
+}
+
+func f2(b bool) {
+	if b {
+		printint(0) // nothing live here
+		return
+	}
+	var x *int       // ERROR "stack object x \*int$"
+	printpointer(&x) // ERROR "live at call to printpointer: x$"
+	printpointer(&x)
+}
+
+func f3(b1, b2 bool) {
+	// Here x and y are ambiguously live. In previous go versions they
+	// were marked as live throughout the function to avoid being
+	// poisoned in GODEBUG=gcdead=1 mode; this is now no longer the
+	// case.
+
+	printint(0)
+	if b1 == false {
+		printint(0)
+		return
+	}
+
+	if b2 {
+		var x *int       // ERROR "stack object x \*int$"
+		printpointer(&x) // ERROR "live at call to printpointer: x$"
+		printpointer(&x)
+	} else {
+		var y *int       // ERROR "stack object y \*int$"
+		printpointer(&y) // ERROR "live at call to printpointer: y$"
+		printpointer(&y)
+	}
+	printint(0) // nothing is live here
+}
+
+// The old algorithm treated x as live on all code that
+// could flow to a return statement, so it included the
+// function entry and code above the declaration of x
+// but would not include an indirect use of x in an infinite loop.
+// Check that these cases are handled correctly.
+
+func f4(b1, b2 bool) { // x not live here
+	if b2 {
+		printint(0) // x not live here
+		return
+	}
+	var z **int
+	x := new(int) // ERROR "stack object x \*int$"
+	*x = 42
+	z = &x
+	printint(**z) // ERROR "live at call to printint: x$"
+	if b2 {
+		printint(1) // x not live here
+		return
+	}
+	for {
+		printint(**z) // ERROR "live at call to printint: x$"
+	}
+}
+
+func f5(b1 bool) {
+	var z **int
+	if b1 {
+		x := new(int) // ERROR "stack object x \*int$"
+		*x = 42
+		z = &x
+	} else {
+		y := new(int) // ERROR "stack object y \*int$"
+		*y = 54
+		z = &y
+	}
+	printint(**z) // nothing live here
+}
+
+// confusion about the _ result used to cause spurious "live at entry to f6: _".
+
+func f6() (_, y string) {
+	y = "hello"
+	return
+}
+
+// confusion about addressed results used to cause "live at entry to f7: x".
+
+func f7() (x string) { // ERROR "stack object x string"
+	_ = &x
+	x = "hello"
+	return
+}
+
+// ignoring block returns used to cause "live at entry to f8: x, y".
+
+func f8() (x, y string) {
+	return g8()
+}
+
+func g8() (string, string)
+
+// ignoring block assignments used to cause "live at entry to f9: x"
+// issue 7205
+
+var i9 interface{}
+
+func f9() bool {
+	g8()
+	x := i9
+	y := interface{}(g18()) // ERROR "live at call to convT2E: x.data$" "live at call to g18: x.data$" "stack object .autotmp_[0-9]+ \[2\]string$"
+	i9 = y                  // make y escape so the line above has to call convT2E
+	return x != y
+}
+
+// liveness formerly confused by UNDEF followed by RET,
+// leading to "live at entry to f10: ~r1" (unnamed result).
+
+func f10() string {
+	panic(1)
+}
+
+// liveness formerly confused by select, thinking runtime.selectgo
+// can return to next instruction; it always jumps elsewhere.
+// note that you have to use at least two cases in the select
+// to get a true select; smaller selects compile to optimized helper functions.
+
+var c chan *int
+var b bool
+
+// this used to have a spurious "live at entry to f11a: ~r0"
+func f11a() *int {
+	select { // ERROR "stack object .autotmp_[0-9]+ \[2\]struct"
+	case <-c:
+		return nil
+	case <-c:
+		return nil
+	}
+}
+
+func f11b() *int {
+	p := new(int)
+	if b {
+		// At this point p is dead: the code here cannot
+		// get to the bottom of the function.
+		// This used to have a spurious "live at call to printint: p".
+		printint(1) // nothing live here!
+		select {    // ERROR "stack object .autotmp_[0-9]+ \[2\]struct"
+		case <-c:
+			return nil
+		case <-c:
+			return nil
+		}
+	}
+	println(*p)
+	return nil
+}
+
+var sink *int
+
+func f11c() *int {
+	p := new(int)
+	sink = p // prevent stack allocation, otherwise p is rematerializeable
+	if b {
+		// Unlike previous, the cases in this select fall through,
+		// so we can get to the println, so p is not dead.
+		printint(1) // ERROR "live at call to printint: p$"
+		select {    // ERROR "live at call to selectgo: p$" "stack object .autotmp_[0-9]+ \[2\]struct"
+		case <-c:
+		case <-c:
+		}
+	}
+	println(*p)
+	return nil
+}
+
+// similarly, select{} does not fall through.
+// this used to have a spurious "live at entry to f12: ~r0".
+
+func f12() *int {
+	if b {
+		select {}
+	} else {
+		return nil
+	}
+}
+
+// incorrectly placed VARDEF annotations can cause missing liveness annotations.
+// this used to be missing the fact that s is live during the call to g13 (because it is
+// needed for the call to h13).
+
+func f13() {
+	s := g14()
+	s = h13(s, g13(s)) // ERROR "live at call to g13: s.ptr$"
+}
+
+func g13(string) string
+func h13(string, string) string
+
+// more incorrectly placed VARDEF.
+
+func f14() {
+	x := g14() // ERROR "stack object x string$"
+	printstringpointer(&x)
+}
+
+func g14() 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
+// trying to check that there is only one at any given site,
+// and also that none show up in "ambiguously live" messages.
+
+var m map[string]int
+var mi map[interface{}]int
+
+// str and iface are used to ensure that a temp is required for runtime calls below.
+func str() string
+func iface() interface{}
+
+func f16() {
+	if b {
+		delete(mi, iface()) // ERROR "stack object .autotmp_[0-9]+ interface \{\}$"
+	}
+	delete(mi, iface())
+	delete(mi, iface())
+}
+
+var m2s map[string]*byte
+var m2 map[[2]string]*byte
+var x2 [2]string
+var bp *byte
+
+func f17a(p *byte) { // ERROR "live at entry to f17a: p$"
+	if b {
+		m2[x2] = p // ERROR "live at call to mapassign: p$"
+	}
+	m2[x2] = p // ERROR "live at call to mapassign: p$"
+	m2[x2] = p // ERROR "live at call to mapassign: p$"
+}
+
+func f17b(p *byte) { // ERROR "live at entry to f17b: p$"
+	// key temporary
+	if b {
+		m2s[str()] = p // ERROR "live at call to mapassign_faststr: p$" "live at call to str: p$"
+	}
+	m2s[str()] = p // ERROR "live at call to mapassign_faststr: p$" "live at call to str: p$"
+	m2s[str()] = p // ERROR "live at call to mapassign_faststr: p$" "live at call to str: p$"
+}
+
+func f17c() {
+	// key and value temporaries
+	if b {
+		m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign_faststr: .autotmp_[0-9]+$"
+	}
+	m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign_faststr: .autotmp_[0-9]+$"
+	m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign_faststr: .autotmp_[0-9]+$"
+}
+
+func f17d() *byte
+
+func g18() [2]string
+
+func f18() {
+	// key temporary for mapaccess.
+	// temporary introduced by orderexpr.
+	var z *byte
+	if b {
+		z = m2[g18()] // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
+	}
+	z = m2[g18()]
+	z = m2[g18()]
+	printbytepointer(z)
+}
+
+var ch chan *byte
+
+// byteptr is used to ensure that a temp is required for runtime calls below.
+func byteptr() *byte
+
+func f19() {
+	// dest temporary for channel receive.
+	var z *byte
+
+	if b {
+		z = <-ch // ERROR "stack object .autotmp_[0-9]+ \*byte$"
+	}
+	z = <-ch
+	z = <-ch // ERROR "live at call to chanrecv1: .autotmp_[0-9]+$"
+	printbytepointer(z)
+}
+
+func f20() {
+	// src temporary for channel send
+	if b {
+		ch <- byteptr() // ERROR "stack object .autotmp_[0-9]+ \*byte$"
+	}
+	ch <- byteptr()
+	ch <- byteptr()
+}
+
+func f21() {
+	// key temporary for mapaccess using array literal key.
+	var z *byte
+	if b {
+		z = m2[[2]string{"x", "y"}] // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
+	}
+	z = m2[[2]string{"x", "y"}]
+	z = m2[[2]string{"x", "y"}]
+	printbytepointer(z)
+}
+
+func f23() {
+	// key temporary for two-result map access using array literal key.
+	var z *byte
+	var ok bool
+	if b {
+		z, ok = m2[[2]string{"x", "y"}] // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
+	}
+	z, ok = m2[[2]string{"x", "y"}]
+	z, ok = m2[[2]string{"x", "y"}]
+	printbytepointer(z)
+	print(ok)
+}
+
+func f24() {
+	// key temporary for map access using array literal key.
+	// value temporary too.
+	if b {
+		m2[[2]string{"x", "y"}] = nil // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
+	}
+	m2[[2]string{"x", "y"}] = nil
+	m2[[2]string{"x", "y"}] = nil
+}
+
+// Non-open-coded defers should not cause autotmps.  (Open-coded defers do create extra autotmps).
+func f25(b bool) {
+	for i := 0; i < 2; i++ {
+		// Put in loop to make sure defer is not open-coded
+		defer g25()
+	}
+	if b {
+		return
+	}
+	var x string
+	x = g14()
+	printstring(x)
+	return
+}
+
+func g25()
+
+// non-escaping ... slices passed to function call should die on return,
+// so that the temporaries do not stack and do not cause ambiguously
+// live variables.
+
+func f26(b bool) {
+	if b {
+		print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "stack object .autotmp_[0-9]+ \[3\]interface \{\}$"
+	}
+	print26((*int)(nil), (*int)(nil), (*int)(nil))
+	print26((*int)(nil), (*int)(nil), (*int)(nil))
+	printnl()
+}
+
+//go:noescape
+func print26(...interface{})
+
+// non-escaping closures passed to function call should die on return
+
+func f27(b bool) {
+	x := 0
+	if b {
+		call27(func() { x++ }) // ERROR "stack object .autotmp_[0-9]+ struct \{"
+	}
+	call27(func() { x++ })
+	call27(func() { x++ })
+	printnl()
+}
+
+// but defer does escape to later execution in the function
+
+func f27defer(b bool) {
+	x := 0
+	if b {
+		defer call27(func() { x++ }) // ERROR "stack object .autotmp_[0-9]+ struct \{"
+	}
+	defer call27(func() { x++ }) // ERROR "stack object .autotmp_[0-9]+ struct \{"
+	printnl()                    // ERROR "live at call to printnl: .autotmp_[0-9]+ .autotmp_[0-9]+"
+	return                       // ERROR "live at indirect call: .autotmp_[0-9]+"
+}
+
+// and newproc (go) escapes to the heap
+
+func f27go(b bool) {
+	x := 0
+	if b {
+		go call27(func() { x++ }) // ERROR "live at call to newobject: &x$" "live at call to newobject: &x .autotmp_[0-9]+$" "live at call to newproc: &x$" // allocate two closures, the func literal, and the wrapper for go
+	}
+	go call27(func() { x++ }) // ERROR "live at call to newobject: &x$" "live at call to newobject: .autotmp_[0-9]+$" // allocate two closures, the func literal, and the wrapper for go
+	printnl()
+}
+
+//go:noescape
+func call27(func())
+
+// concatstring slice should die on return
+
+var s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 string
+
+func f28(b bool) {
+	if b {
+		printstring(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10) // ERROR "stack object .autotmp_[0-9]+ \[10\]string$"
+	}
+	printstring(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10)
+	printstring(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10)
+}
+
+// map iterator should die on end of range loop
+
+func f29(b bool) {
+	if b {
+		for k := range m { // ERROR "live at call to mapiterinit: .autotmp_[0-9]+$" "live at call to mapiternext: .autotmp_[0-9]+$" "stack object .autotmp_[0-9]+ map.iter\[string\]int$"
+			printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
+		}
+	}
+	for k := range m { // ERROR "live at call to mapiterinit: .autotmp_[0-9]+$" "live at call to mapiternext: .autotmp_[0-9]+$"
+		printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
+	}
+	for k := range m { // ERROR "live at call to mapiterinit: .autotmp_[0-9]+$" "live at call to mapiternext: .autotmp_[0-9]+$"
+		printstring(k) // ERROR "live at call to printstring: .autotmp_[0-9]+$"
+	}
+}
+
+// copy of array of pointers should die at end of range loop
+var pstructarr [10]pstruct
+
+// Struct size chosen to make pointer to element in pstructarr
+// not computable by strength reduction.
+type pstruct struct {
+	intp *int
+	_    [8]byte
+}
+
+func f30(b bool) {
+	// live temp during printintpointer(p):
+	// the internal iterator pointer if a pointer to pstruct in pstructarr
+	// can not be easily computed by strength reduction.
+	if b {
+		for _, p := range pstructarr { // ERROR "stack object .autotmp_[0-9]+ \[10\]pstruct$"
+			printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+$"
+		}
+	}
+	for _, p := range pstructarr {
+		printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+$"
+	}
+	for _, p := range pstructarr {
+		printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+$"
+	}
+}
+
+// conversion to interface should not leave temporary behind
+
+func f31(b1, b2, b3 bool) {
+	if b1 {
+		g31(g18()) // ERROR "stack object .autotmp_[0-9]+ \[2\]string$"
+	}
+	if b2 {
+		h31(g18()) // ERROR "live at call to convT2E: .autotmp_[0-9]+$" "live at call to newobject: .autotmp_[0-9]+$"
+	}
+	if b3 {
+		panic(g18())
+	}
+	print(b3)
+}
+
+func g31(interface{})
+func h31(...interface{})
+
+// non-escaping partial functions passed to function call should die on return
+
+type T32 int
+
+func (t *T32) Inc() { // ERROR "live at entry to \(\*T32\).Inc: t$"
+	*t++
+}
+
+var t32 T32
+
+func f32(b bool) {
+	if b {
+		call32(t32.Inc) // ERROR "stack object .autotmp_[0-9]+ struct \{"
+	}
+	call32(t32.Inc)
+	call32(t32.Inc)
+}
+
+//go:noescape
+func call32(func())
+
+// temporaries introduced during if conditions and && || expressions
+// should die once the condition has been acted upon.
+
+var m33 map[interface{}]int
+
+func f33() {
+	if m33[byteptr()] == 0 { // ERROR "stack object .autotmp_[0-9]+ interface \{\}$"
+		printnl()
+		return
+	} else {
+		printnl()
+	}
+	printnl()
+}
+
+func f34() {
+	if m33[byteptr()] == 0 { // ERROR "stack object .autotmp_[0-9]+ interface \{\}$"
+		printnl()
+		return
+	}
+	printnl()
+}
+
+func f35() {
+	if m33[byteptr()] == 0 && // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
+		m33[byteptr()] == 0 { // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
+		printnl()
+		return
+	}
+	printnl()
+}
+
+func f36() {
+	if m33[byteptr()] == 0 || // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
+		m33[byteptr()] == 0 { // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
+		printnl()
+		return
+	}
+	printnl()
+}
+
+func f37() {
+	if (m33[byteptr()] == 0 || // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
+		m33[byteptr()] == 0) && // ERROR "stack object .autotmp_[0-9]+ interface \{\}"
+		m33[byteptr()] == 0 {
+		printnl()
+		return
+	}
+	printnl()
+}
+
+// select temps should disappear in the case bodies
+
+var c38 chan string
+
+func fc38() chan string
+func fi38(int) *string
+func fb38() *bool
+
+func f38(b bool) {
+	// we don't care what temps are printed on the lines with output.
+	// we care that the println lines have no live variables
+	// and therefore no output.
+	if b {
+		select { // ERROR "live at call to selectgo:( .autotmp_[0-9]+)+$" "stack object .autotmp_[0-9]+ \[4\]struct \{"
+		case <-fc38():
+			printnl()
+		case fc38() <- *fi38(1): // ERROR "live at call to fc38:( .autotmp_[0-9]+)+$" "live at call to fi38:( .autotmp_[0-9]+)+$" "stack object .autotmp_[0-9]+ string$"
+			printnl()
+		case *fi38(2) = <-fc38(): // ERROR "live at call to fc38:( .autotmp_[0-9]+)+$" "live at call to fi38:( .autotmp_[0-9]+)+$" "stack object .autotmp_[0-9]+ string$"
+			printnl()
+		case *fi38(3), *fb38() = <-fc38(): // ERROR "stack object .autotmp_[0-9]+ string$" "live at call to fc38:( .autotmp_[0-9]+)+$" "live at call to fi38:( .autotmp_[0-9]+)+$"
+			printnl()
+		}
+		printnl()
+	}
+	printnl()
+}
+
+// issue 8097: mishandling of x = x during return.
+
+func f39() (x []int) {
+	x = []int{1}
+	printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+$"
+	return x
+}
+
+func f39a() (x []int) {
+	x = []int{1}
+	printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+$"
+	return
+}
+
+func f39b() (x [10]*int) {
+	x = [10]*int{}
+	x[0] = new(int) // ERROR "live at call to newobject: x$"
+	printnl()       // ERROR "live at call to printnl: x$"
+	return x
+}
+
+func f39c() (x [10]*int) {
+	x = [10]*int{}
+	x[0] = new(int) // ERROR "live at call to newobject: x$"
+	printnl()       // ERROR "live at call to printnl: x$"
+	return
+}
+
+// issue 8142: lost 'addrtaken' bit on inlined variables.
+// no inlining in this test, so just checking that non-inlined works.
+
+type T40 struct {
+	m map[int]int
+}
+
+//go:noescape
+func useT40(*T40)
+
+func newT40() *T40 {
+	ret := T40{}
+	ret.m = make(map[int]int, 42) // ERROR "live at call to makemap: &ret$"
+	return &ret
+}
+
+func bad40() {
+	t := newT40()
+	_ = t
+	printnl()
+}
+
+func good40() {
+	ret := T40{}              // ERROR "stack object ret T40$"
+	ret.m = make(map[int]int) // ERROR "live at call to fastrand: .autotmp_[0-9]+$" "stack object .autotmp_[0-9]+ map.hdr\[int\]int$"
+	t := &ret
+	printnl() // ERROR "live at call to printnl: ret$"
+	// Note: ret is live at the printnl because the compiler moves &ret
+	// from before the printnl to after.
+	useT40(t)
+}
+
+func ddd1(x, y *int) { // ERROR "live at entry to ddd1: x y$"
+	ddd2(x, y) // ERROR "stack object .autotmp_[0-9]+ \[2\]\*int$"
+	printnl()
+	// Note: no .?autotmp live at printnl.  See issue 16996.
+}
+func ddd2(a ...*int) { // ERROR "live at entry to ddd2: a$"
+	sink = a[0]
+}
+
+// issue 16016: autogenerated wrapper should have arguments live
+type T struct{}
+
+func (*T) Foo(ptr *int) {}
+
+type R struct{ *T } // ERRORAUTO "live at entry to \(\*R\)\.Foo: \.this ptr" "live at entry to R\.Foo: \.this ptr"
+
+// issue 18860: output arguments must be live all the time if there is a defer.
+// In particular, at printint r must be live.
+func f41(p, q *int) (r *int) { // ERROR "live at entry to f41: p q$"
+	r = p
+	defer func() {
+		recover()
+	}()
+	printint(0) // ERROR "live at call to printint: q .autotmp_[0-9]+ r$"
+	r = q
+	return // ERROR "live at call to f41.func1: .autotmp_[0-9]+ r$"
+}
+
+func f42() {
+	var p, q, r int
+	f43([]*int{&p, &q, &r}) // ERROR "stack object .autotmp_[0-9]+ \[3\]\*int$"
+	f43([]*int{&p, &r, &q})
+	f43([]*int{&q, &p, &r})
+}
+
+//go:noescape
+func f43(a []*int)
+
+// Assigning to a sub-element that makes up an entire local variable
+// should clobber that variable.
+func f44(f func() [2]*int) interface{} { // ERROR "live at entry to f44: f"
+	type T struct {
+		s [1][2]*int
+	}
+	ret := T{}
+	ret.s[0] = f()
+	return ret // ERROR "stack object .autotmp_[0-9]+ T"
+}
diff --git a/test/mainsig.go b/test/mainsig.go
new file mode 100644
index 0000000..d006d9c
--- /dev/null
+++ b/test/mainsig.go
@@ -0,0 +1,13 @@
+// errorcheck
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main(int)  {}           // ERROR "func main must have no arguments and no return values"
+func main() int { return 1 } // ERROR "func main must have no arguments and no return values" "main redeclared in this block"
+
+func init(int)  {}           // ERROR "func init must have no arguments and no return values"
+func init() int { return 1 } // ERROR "func init must have no arguments and no return values"
diff --git a/test/makechan.go b/test/makechan.go
index 6608620..9fabd17 100644
--- a/test/makechan.go
+++ b/test/makechan.go
@@ -15,14 +15,14 @@
 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, -1)            // ERROR "negative buffer argument in make.*|must not be negative"
+	sink = make(T, uint64(1<<63)) // ERROR "buffer argument too large in make.*|overflows int"
 
-	sink = make(T, 0.5) // ERROR "constant 0.5 truncated to integer"
+	sink = make(T, 0.5) // ERROR "constant 0.5 truncated to integer|truncated to int"
 	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, float32(1.0)) // ERROR "non-integer buffer argument in make.*|must be integer"
+	sink = make(T, float64(1.0)) // ERROR "non-integer buffer argument in make.*|must be integer"
 	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, complex64(1+0i))  // ERROR "non-integer buffer argument in make.*|must be integer"
+	sink = make(T, complex128(1+0i)) // ERROR "non-integer buffer argument in make.*|must be integer"
 }
diff --git a/test/makemap.go b/test/makemap.go
index 63998d7..f63e5b4 100644
--- a/test/makemap.go
+++ b/test/makemap.go
@@ -15,20 +15,20 @@
 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, -1)            // ERROR "negative size argument in make.*|must not be negative"
+	sink = make(T, uint64(1<<63)) // ERROR "size argument too large in make.*|overflows int"
 
 	// Test that errors are emitted at call sites, not const declarations
 	const x = -1
-	sink = make(T, x) // ERROR "negative size argument in make.*"
+	sink = make(T, x) // ERROR "negative size argument in make.*|must not be negative"
 	const y = uint64(1 << 63)
-	sink = make(T, y) // ERROR "size argument too large in make.*"
+	sink = make(T, y) // ERROR "size argument too large in make.*|overflows int"
 
-	sink = make(T, 0.5) // ERROR "constant 0.5 truncated to integer"
+	sink = make(T, 0.5) // ERROR "constant 0.5 truncated to integer|truncated to int"
 	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, float32(1.0)) // ERROR "non-integer size argument in make.*|must be integer"
+	sink = make(T, float64(1.0)) // ERROR "non-integer size argument in make.*|must be integer"
 	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, complex64(1+0i))  // ERROR "non-integer size argument in make.*|must be integer"
+	sink = make(T, complex128(1+0i)) // ERROR "non-integer size argument in make.*|must be integer"
 }
diff --git a/test/makenew.go b/test/makenew.go
index 058d975..14854dc 100644
--- a/test/makenew.go
+++ b/test/makenew.go
@@ -10,10 +10,10 @@
 package main
 
 func main() {
-	_ = make()      // ERROR "missing argument"
-	_ = make(int)   // ERROR "cannot make type"
-	_ = make([]int) // ERROR "missing len argument"
+	_ = make()      // ERROR "missing argument|not enough arguments"
+	_ = make(int)   // ERROR "cannot make type|cannot make int"
+	_ = make([]int) // ERROR "missing len argument|expects 2 or 3 arguments"
 
-	_ = new()       // ERROR "missing argument"
+	_ = new()       // ERROR "missing argument|not enough arguments"
 	_ = new(int, 2) // ERROR "too many arguments"
 }
diff --git a/test/map1.go b/test/map1.go
index b4aa707..a6b27e6 100644
--- a/test/map1.go
+++ b/test/map1.go
@@ -64,5 +64,5 @@
 	delete()        // ERROR "missing arguments|not enough arguments"
 	delete(m)       // ERROR "missing second \(key\) argument|not enough arguments"
 	delete(m, 2, 3) // ERROR "too many arguments"
-	delete(1, m)    // ERROR "first argument to delete must be map|argument 1 must be a map"
+	delete(1, m)    // ERROR "first argument to delete must be map|argument 1 must be a map|is not a map"
 }
diff --git a/test/method2.go b/test/method2.go
index ac1d771..2a92136 100644
--- a/test/method2.go
+++ b/test/method2.go
@@ -15,8 +15,8 @@
 type P *T
 type P1 *T
 
-func (p P) val() int   { return 1 } // ERROR "receiver.* pointer|invalid pointer or interface receiver"
-func (p *P1) val() int { return 1 } // ERROR "receiver.* pointer|invalid pointer or interface receiver"
+func (p P) val() int   { return 1 } // ERROR "receiver.* pointer|invalid pointer or interface receiver|invalid receiver"
+func (p *P1) val() int { return 1 } // ERROR "receiver.* pointer|invalid pointer or interface receiver|invalid receiver"
 
 type I interface{}
 type I1 interface{}
@@ -38,4 +38,4 @@
 
 func (t *T) g() int { return t.a }
 
-var _ = (T).g() // ERROR "needs pointer receiver|undefined|method requires pointer"
+var _ = (T).g() // ERROR "needs pointer receiver|undefined|method requires pointer|cannot call pointer method"
diff --git a/test/method6.go b/test/method6.go
index 20eccce..ede3467 100644
--- a/test/method6.go
+++ b/test/method6.go
@@ -18,5 +18,5 @@
 
 var _ = func() {
 	var a A
-	A(a).g() // ERROR "cannot call pointer method on|cannot take the address of"
+	A(a).g() // ERROR "cannot call pointer method .*on|cannot take the address of"
 }
diff --git a/test/method7.go b/test/method7.go
index 15e123e..05accb3 100644
--- a/test/method7.go
+++ b/test/method7.go
@@ -25,6 +25,11 @@
 
 func (T) m2() { got += " m2()" }
 
+type Outer struct{ *Inner }
+type Inner struct{ s string }
+
+func (i Inner) M() string { return i.s }
+
 func main() {
 	// method expressions with named receiver types
 	I.m(S{})
@@ -52,4 +57,11 @@
 	if got != want {
 		panic("got" + got + ", want" + want)
 	}
+
+	h := (*Outer).M
+	got := h(&Outer{&Inner{"hello"}})
+	want := "hello"
+	if got != want {
+		panic("got " + got + ", want " + want)
+	}
 }
diff --git a/test/named1.go b/test/named1.go
index 7feae13..452c6da 100644
--- a/test/named1.go
+++ b/test/named1.go
@@ -54,7 +54,7 @@
 	_ = b
 
 	_, bb := <-c
-	asBool(bb) // ERROR "cannot use.*type bool.*as type Bool"
+	asBool(bb) // ERROR "cannot use.*type bool.*as type Bool|cannot use bb"
 	_, b = <-c // ok now
 	_ = b
 
diff --git a/test/nilptr.go b/test/nilptr.go
index c9a044d..b296c88 100644
--- a/test/nilptr.go
+++ b/test/nilptr.go
@@ -9,7 +9,8 @@
 
 // +build !aix
 // +build !darwin !arm64
-// Address space starts at 1<<32 on AIX and on darwin/arm64, so dummy is too far.
+// +build !windows !arm64
+// Address space starts at 1<<32 on AIX and on darwin/arm64 and on windows/arm64, so dummy is too far.
 
 package main
 
diff --git a/test/nilptr3.go b/test/nilptr3.go
index e0f2ed9..3345cfa 100644
--- a/test/nilptr3.go
+++ b/test/nilptr3.go
@@ -214,14 +214,6 @@
 	return p[5] // ERROR "removed nil check"
 }
 
-// make sure not to do nil check for access of PAUTOHEAP
-//go:noinline
-func (p *Struct) m() {}
-func c1() {
-	var x Struct
-	func() { x.m() }() // ERROR "removed nil check"
-}
-
 type SS struct {
 	x byte
 }
diff --git a/test/nosplit.go b/test/nosplit.go
index faa7b8c..7c7e1bf 100644
--- a/test/nosplit.go
+++ b/test/nosplit.go
@@ -21,6 +21,8 @@
 	"strings"
 )
 
+const debug = false
+
 var tests = `
 # These are test cases for the linker analysis that detects chains of
 # nosplit functions that would cause a stack overflow.
@@ -33,8 +35,8 @@
 # The body is assembly code, with some shorthands.
 # The shorthand 'call x' stands for CALL x(SB).
 # The shorthand 'callind' stands for 'CALL R0', where R0 is a register.
-# Each test case must define a function named main, and it must be first.
-# That is, a line beginning "main " indicates the start of a new test case.
+# Each test case must define a function named start, and it must be first.
+# That is, a line beginning "start " indicates the start of a new test case.
 # Within a stanza, ; can be used instead of \n to separate lines.
 #
 # After the function definition, the test case ends with an optional
@@ -46,41 +48,41 @@
 # that are only 32-bit aligned.
 
 # Ordinary function should work
-main 0
+start 0
 
 # Large frame marked nosplit is always wrong.
-main 10000 nosplit
+start 10000 nosplit
 REJECT
 
 # Calling a large frame is okay.
-main 0 call big
+start 0 call big
 big 10000
 
 # But not if the frame is nosplit.
-main 0 call big
+start 0 call big
 big 10000 nosplit
 REJECT
 
 # Recursion is okay.
-main 0 call main
+start 0 call start
 
 # Recursive nosplit runs out of space.
-main 0 nosplit call main
+start 0 nosplit call start
 REJECT
 
 # Chains of ordinary functions okay.
-main 0 call f1
+start 0 call f1
 f1 80 call f2
 f2 80
 
 # Chains of nosplit must fit in the stack limit, 128 bytes.
-main 0 call f1
+start 0 call f1
 f1 80 nosplit call f2
 f2 80 nosplit
 REJECT
 
 # Larger chains.
-main 0 call f1
+start 0 call f1
 f1 16 call f2
 f2 16 call f3
 f3 16 call f4
@@ -91,7 +93,7 @@
 f8 16 call end
 end 1000
 
-main 0 call f1
+start 0 call f1
 f1 16 nosplit call f2
 f2 16 nosplit call f3
 f3 16 nosplit call f4
@@ -106,27 +108,27 @@
 # Test cases near the 128-byte limit.
 
 # Ordinary stack split frame is always okay.
-main 112
-main 116
-main 120
-main 124
-main 128
-main 132
-main 136
+start 112
+start 116
+start 120
+start 124
+start 128
+start 132
+start 136
 
 # A nosplit leaf can use the whole 128-CallSize bytes available on entry.
 # (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 arm64
-main 108 nosplit; REJECT ppc64 ppc64le
-main 112 nosplit; REJECT ppc64 ppc64le arm64
-main 116 nosplit; REJECT ppc64 ppc64le
-main 120 nosplit; REJECT ppc64 ppc64le amd64 arm64
-main 124 nosplit; REJECT ppc64 ppc64le amd64
-main 128 nosplit; REJECT
-main 132 nosplit; REJECT
-main 136 nosplit; REJECT
+start 96 nosplit
+start 100 nosplit; REJECT ppc64 ppc64le
+start 104 nosplit; REJECT ppc64 ppc64le arm64
+start 108 nosplit; REJECT ppc64 ppc64le
+start 112 nosplit; REJECT ppc64 ppc64le arm64
+start 116 nosplit; REJECT ppc64 ppc64le
+start 120 nosplit; REJECT ppc64 ppc64le amd64 arm64
+start 124 nosplit; REJECT ppc64 ppc64le amd64
+start 128 nosplit; REJECT
+start 132 nosplit; REJECT
+start 136 nosplit; REJECT
 
 # Calling a nosplit function from a nosplit function requires
 # having room for the saved caller PC and the called frame.
@@ -134,55 +136,55 @@
 # 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 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 arm64
-main 108 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
-main 112 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 arm64
-main 116 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64
-main 120 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 arm64
-main 124 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 386
-main 128 nosplit call f; f 0 nosplit; REJECT
-main 132 nosplit call f; f 0 nosplit; REJECT
-main 136 nosplit call f; f 0 nosplit; REJECT
+start 96 nosplit call f; f 0 nosplit
+start 100 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
+start 104 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le arm64
+start 108 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
+start 112 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 arm64
+start 116 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64
+start 120 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 arm64
+start 124 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 386
+start 128 nosplit call f; f 0 nosplit; REJECT
+start 132 nosplit call f; f 0 nosplit; REJECT
+start 136 nosplit call f; f 0 nosplit; REJECT
 
 # 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.
 # 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 amd64 arm64
-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 arm64
-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 arm64
-main 124 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 386
-main 128 nosplit call f; f 0 call f; REJECT
-main 132 nosplit call f; f 0 call f; REJECT
-main 136 nosplit call f; f 0 call f; REJECT
+start 96 nosplit call f; f 0 call f
+start 100 nosplit call f; f 0 call f; REJECT ppc64 ppc64le
+start 104 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 arm64
+start 108 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64
+start 112 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 arm64
+start 116 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64
+start 120 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 386 arm64
+start 124 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 386
+start 128 nosplit call f; f 0 call f; REJECT
+start 132 nosplit call f; f 0 call f; REJECT
+start 136 nosplit call f; f 0 call f; REJECT
 
 # 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 amd64 arm64
-main 108 nosplit callind; REJECT ppc64 ppc64le amd64
-main 112 nosplit callind; REJECT ppc64 ppc64le amd64 arm64
-main 116 nosplit callind; REJECT ppc64 ppc64le amd64
-main 120 nosplit callind; REJECT ppc64 ppc64le amd64 386 arm64
-main 124 nosplit callind; REJECT ppc64 ppc64le amd64 386
-main 128 nosplit callind; REJECT
-main 132 nosplit callind; REJECT
-main 136 nosplit callind; REJECT
+start 96 nosplit callind
+start 100 nosplit callind; REJECT ppc64 ppc64le
+start 104 nosplit callind; REJECT ppc64 ppc64le amd64 arm64
+start 108 nosplit callind; REJECT ppc64 ppc64le amd64
+start 112 nosplit callind; REJECT ppc64 ppc64le amd64 arm64
+start 116 nosplit callind; REJECT ppc64 ppc64le amd64
+start 120 nosplit callind; REJECT ppc64 ppc64le amd64 386 arm64
+start 124 nosplit callind; REJECT ppc64 ppc64le amd64 386
+start 128 nosplit callind; REJECT
+start 132 nosplit callind; REJECT
+start 136 nosplit callind; REJECT
 
 # Issue 7623
-main 0 call f; f 112
-main 0 call f; f 116
-main 0 call f; f 120
-main 0 call f; f 124
-main 0 call f; f 128
-main 0 call f; f 132
-main 0 call f; f 136
+start 0 call f; f 112
+start 0 call f; f 116
+start 0 call f; f 120
+start 0 call f; f 124
+start 0 call f; f 128
+start 0 call f; f 132
+start 0 call f; f 136
 `
 
 var (
@@ -199,17 +201,6 @@
 		goarch = runtime.GOARCH
 	}
 
-	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 s := string(version); goarch == "amd64" && strings.Contains(s, "X:") && !strings.Contains(s, "framepointer") {
-		// Skip this test if framepointer is NOT enabled on AMD64
-		return
-	}
-
 	dir, err := ioutil.TempDir("", "go-test-nosplit")
 	if err != nil {
 		bug()
@@ -231,7 +222,7 @@
 TestCases:
 	for len(tests) > 0 {
 		var stanza string
-		i := strings.Index(tests, "\nmain ")
+		i := strings.Index(tests, "\nstart ")
 		if i < 0 {
 			stanza, tests = tests, ""
 		} else {
@@ -293,6 +284,14 @@
 			fmt.Fprintf(&buf, "#define REGISTER AX\n")
 		}
 
+		// Since all of the functions we're generating are
+		// ABI0, first enter ABI0 via a splittable function
+		// and then go to the chain we're testing. This way we
+		// don't have to account for ABI wrappers in the chain.
+		fmt.Fprintf(&gobuf, "func main0()\n")
+		fmt.Fprintf(&gobuf, "func main() { main0() }\n")
+		fmt.Fprintf(&buf, "TEXT ·main0(SB),0,$0-0\n\tCALL ·start(SB)\n")
+
 		for _, line := range strings.Split(lines, "\n") {
 			line = strings.TrimSpace(line)
 			if line == "" {
@@ -346,6 +345,12 @@
 			}
 		}
 
+		if debug {
+			fmt.Printf("===\n%s\n", strings.TrimSpace(stanza))
+			fmt.Printf("-- main.go --\n%s", gobuf.String())
+			fmt.Printf("-- asm.s --\n%s", buf.String())
+		}
+
 		if err := ioutil.WriteFile(filepath.Join(dir, "asm.s"), buf.Bytes(), 0666); err != nil {
 			log.Fatal(err)
 		}
diff --git a/test/phiopt.go b/test/phiopt.go
index 98a7b75..e04373e 100644
--- a/test/phiopt.go
+++ b/test/phiopt.go
@@ -1,4 +1,4 @@
-// +build amd64 s390x
+// +build amd64 s390x arm64
 // errorcheck -0 -d=ssa/phiopt/debug=3
 
 // Copyright 2016 The Go Authors. All rights reserved.
@@ -104,5 +104,29 @@
 	return a && b // ERROR "converted OpPhi to AndB$"
 }
 
+//go:noinline
+func f8(s string) (string, bool) {
+	neg := false
+	if s[0] == '-' {    // ERROR "converted OpPhi to Copy$"
+		neg = true
+		s = s[1:]
+	}
+	return s, neg
+}
+
+var d int
+
+//go:noinline
+func f9(a, b int) bool {
+	c := false
+	if a < 0 {          // ERROR "converted OpPhi to Copy$"
+		if b < 0 {
+			d = d + 1
+		}
+		c = true
+	}
+	return c
+}
+
 func main() {
 }
diff --git a/test/prove.go b/test/prove.go
index d37021d..83b0380 100644
--- a/test/prove.go
+++ b/test/prove.go
@@ -629,6 +629,22 @@
 	_ = b[i] // ERROR "Proved IsInBounds$"
 }
 
+func trans4(b []byte, x int) {
+	// Issue #42603: slice len/cap transitive relations.
+	switch x {
+	case 0:
+		if len(b) < 20 {
+			return
+		}
+		_ = b[:2] // ERROR "Proved IsSliceInBounds$"
+	case 1:
+		if len(b) < 40 {
+			return
+		}
+		_ = b[:2] // ERROR "Proved IsSliceInBounds$"
+	}
+}
+
 // Derived from nat.cmp
 func natcmp(x, y []uint) (r int) {
 	m := len(x)
@@ -997,7 +1013,7 @@
 // opt, an earlier pass, has already replaced it.
 // The fix for this issue allows prove to zero a right shift that was added as
 // part of the less-than-optimal reqwrite. That change by prove then allows
-// lateopt to clean up all the unneccesary parts of the original division
+// lateopt to clean up all the unnecessary parts of the original division
 // replacement. See issue #36159.
 func divShiftClean(n int) int {
 	if n < 0 {
diff --git a/test/rename1.go b/test/rename1.go
index c49a70a..058db44 100644
--- a/test/rename1.go
+++ b/test/rename1.go
@@ -13,7 +13,7 @@
 	var n byte         // ERROR "not a type|expected type"
 	var y = float32(0) // ERROR "cannot call|expected function"
 	const (
-		a = 1 + iota // ERROR "invalid operation|incompatible types"
+		a = 1 + iota // ERROR "invalid operation|incompatible types|cannot convert"
 	)
 
 }
diff --git a/test/reorder.go b/test/reorder.go
index 3a87d02..57892f8 100644
--- a/test/reorder.go
+++ b/test/reorder.go
@@ -20,6 +20,8 @@
 	p7()
 	p8()
 	p9()
+	p10()
+	p11()
 }
 
 var gx []int
@@ -149,3 +151,17 @@
 		panic("failed")
 	}
 }
+
+//go:noinline
+func fp() (*int, int) { return nil, 42 }
+
+func p10() {
+	p := new(int)
+	p, *p = fp()
+}
+
+func p11() {
+	var i interface{}
+	p := new(bool)
+	p, *p = i.(*bool)
+}
diff --git a/test/run.go b/test/run.go
index 624f223..d7f5d02 100644
--- a/test/run.go
+++ b/test/run.go
@@ -12,6 +12,7 @@
 	"errors"
 	"flag"
 	"fmt"
+	"go/build"
 	"hash/fnv"
 	"io"
 	"io/fs"
@@ -56,10 +57,11 @@
 
 var (
 	goos, goarch string
+	cgoEnabled   bool
 
 	// dirs are the directories to look for *.go files in.
 	// TODO(bradfitz): just use all directories?
-	dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen", "runtime"}
+	dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen", "runtime", "abi", "typeparam"}
 
 	// ratec controls the max number of tests running at a time.
 	ratec chan bool
@@ -82,6 +84,10 @@
 
 	goos = getenv("GOOS", runtime.GOOS)
 	goarch = getenv("GOARCH", runtime.GOARCH)
+	cgoEnv, err := exec.Command(goTool(), "env", "CGO_ENABLED").Output()
+	if err == nil {
+		cgoEnabled, _ = strconv.ParseBool(strings.TrimSpace(string(cgoEnv)))
+	}
 
 	findExecCmd()
 
@@ -367,9 +373,10 @@
 }
 
 type context struct {
-	GOOS     string
-	GOARCH   string
-	noOptEnv bool
+	GOOS       string
+	GOARCH     string
+	cgoEnabled bool
+	noOptEnv   bool
 }
 
 // shouldTest looks for build tags in a source file and returns
@@ -391,9 +398,10 @@
 		}
 		gcFlags := os.Getenv("GO_GCFLAGS")
 		ctxt := &context{
-			GOOS:     goos,
-			GOARCH:   goarch,
-			noOptEnv: strings.Contains(gcFlags, "-N") || strings.Contains(gcFlags, "-l"),
+			GOOS:       goos,
+			GOARCH:     goarch,
+			cgoEnabled: cgoEnabled,
+			noOptEnv:   strings.Contains(gcFlags, "-N") || strings.Contains(gcFlags, "-l"),
 		}
 
 		words := strings.Fields(line)
@@ -438,6 +446,19 @@
 		}
 	}
 
+	if strings.HasPrefix(name, "goexperiment.") {
+		for _, tag := range build.Default.ToolTags {
+			if tag == name {
+				return true
+			}
+		}
+		return false
+	}
+
+	if name == "cgo" && ctxt.cgoEnabled {
+		return true
+	}
+
 	if name == ctxt.GOOS || name == ctxt.GOARCH || name == "gc" {
 		return true
 	}
@@ -491,7 +512,7 @@
 	// Execution recipe stops at first blank line.
 	pos := strings.Index(t.src, "\n\n")
 	if pos == -1 {
-		t.err = errors.New("double newline not found")
+		t.err = fmt.Errorf("double newline ending execution recipe not found in %s", t.goFileName())
 		return
 	}
 	action := t.src[:pos]
@@ -513,7 +534,7 @@
 		return
 	}
 
-	var args, flags []string
+	var args, flags, runenv []string
 	var tim int
 	wantError := false
 	wantAuto := false
@@ -572,6 +593,9 @@
 			if err != nil {
 				t.err = fmt.Errorf("need number of seconds for -t timeout, got %s instead", args[0])
 			}
+		case "-goexperiment": // set GOEXPERIMENT environment
+			args = args[1:]
+			runenv = append(runenv, "GOEXPERIMENT="+args[0])
 
 		default:
 			flags = append(flags, args[0])
@@ -628,6 +652,7 @@
 		if tempDirIsGOPATH {
 			cmd.Env = append(cmd.Env, "GOPATH="+t.tempDir)
 		}
+		cmd.Env = append(cmd.Env, runenv...)
 
 		var err error
 
@@ -725,7 +750,7 @@
 		// Fail if wantError is true and compilation was successful and vice versa.
 		// Match errors produced by gc against errors in comments.
 		// TODO(gri) remove need for -C (disable printing of columns in error messages)
-		cmdline := []string{goTool(), "tool", "compile", "-C", "-e", "-o", "a.o"}
+		cmdline := []string{goTool(), "tool", "compile", "-d=panic", "-C", "-e", "-o", "a.o"}
 		// No need to add -dynlink even if linkshared if we're just checking for errors...
 		cmdline = append(cmdline, flags...)
 		cmdline = append(cmdline, long)
@@ -749,7 +774,66 @@
 			t.updateErrors(string(out), long)
 		}
 		t.err = t.errorCheck(string(out), wantAuto, long, t.gofile)
-		return
+		if t.err != nil {
+			return // don't hide error if run below succeeds
+		}
+
+		// The following is temporary scaffolding to get types2 typechecker
+		// up and running against the existing test cases. The explicitly
+		// listed files don't pass yet, usually because the error messages
+		// are slightly different (this list is not complete). Any errorcheck
+		// tests that require output from analysis phases past initial type-
+		// checking are also excluded since these phases are not running yet.
+		// We can get rid of this code once types2 is fully plugged in.
+
+		// For now we're done when we can't handle the file or some of the flags.
+		// The first goal is to eliminate the excluded list; the second goal is to
+		// eliminate the flag list.
+
+		// Excluded files.
+		filename := strings.Replace(t.goFileName(), "\\", "/", -1) // goFileName() uses \ on Windows
+		if excluded[filename] {
+			if *verbose {
+				fmt.Printf("excl\t%s\n", filename)
+			}
+			return // cannot handle file yet
+		}
+
+		// Excluded flags.
+		for _, flag := range flags {
+			for _, pattern := range []string{
+				"-m",
+			} {
+				if strings.Contains(flag, pattern) {
+					if *verbose {
+						fmt.Printf("excl\t%s\t%s\n", filename, flags)
+					}
+					return // cannot handle flag
+				}
+			}
+		}
+
+		// Run errorcheck again with -G option (new typechecker).
+		cmdline = []string{goTool(), "tool", "compile", "-G=3", "-C", "-e", "-o", "a.o"}
+		// No need to add -dynlink even if linkshared if we're just checking for errors...
+		cmdline = append(cmdline, flags...)
+		cmdline = append(cmdline, long)
+		out, err = runcmd(cmdline...)
+		if wantError {
+			if err == nil {
+				t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out)
+				return
+			}
+		} else {
+			if err != nil {
+				t.err = err
+				return
+			}
+		}
+		if *updateErrors {
+			t.updateErrors(string(out), long)
+		}
+		t.err = t.errorCheck(string(out), wantAuto, long, t.gofile)
 
 	case "compile":
 		// Compile Go file.
@@ -771,6 +855,7 @@
 		}
 
 	case "errorcheckdir", "errorcheckandrundir":
+		flags = append(flags, "-d=panic")
 		// Compile and errorCheck all files in the directory as packages in lexicographic order.
 		// If errorcheckdir and wantError, compilation of the last package must fail.
 		// If errorcheckandrundir and wantError, compilation of the package prior the last must fail.
@@ -868,9 +953,7 @@
 					t.err = err
 					return
 				}
-				if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
-					t.err = fmt.Errorf("incorrect output\n%s", out)
-				}
+				t.checkExpectedOutput(out)
 			}
 		}
 
@@ -904,15 +987,14 @@
 		if *linkshared {
 			cmd = append(cmd, "-linkshared")
 		}
+		cmd = append(cmd, flags...)
 		cmd = append(cmd, ".")
 		out, err := runcmd(cmd...)
 		if err != nil {
 			t.err = err
 			return
 		}
-		if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
-			t.err = fmt.Errorf("incorrect output\n%s", out)
-		}
+		t.checkExpectedOutput(out)
 
 	case "build":
 		// Build Go file.
@@ -997,9 +1079,7 @@
 				t.err = err
 				break
 			}
-			if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
-				t.err = fmt.Errorf("incorrect output\n%s", out)
-			}
+			t.checkExpectedOutput(out)
 		}
 
 	case "buildrun":
@@ -1025,9 +1105,7 @@
 			return
 		}
 
-		if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
-			t.err = fmt.Errorf("incorrect output\n%s", out)
-		}
+		t.checkExpectedOutput(out)
 
 	case "run":
 		// Run Go file if no special go command flags are provided;
@@ -1070,9 +1148,7 @@
 			t.err = err
 			return
 		}
-		if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
-			t.err = fmt.Errorf("incorrect output\n%s", out)
-		}
+		t.checkExpectedOutput(out)
 
 	case "runoutput":
 		// Run Go file and write its output into temporary Go file.
@@ -1107,9 +1183,7 @@
 			t.err = err
 			return
 		}
-		if string(out) != t.expectedOutput() {
-			t.err = fmt.Errorf("incorrect output\n%s", out)
-		}
+		t.checkExpectedOutput(out)
 
 	case "errorcheckoutput":
 		// Run Go file and write its output into temporary Go file.
@@ -1131,7 +1205,7 @@
 			t.err = fmt.Errorf("write tempfile:%s", err)
 			return
 		}
-		cmdline := []string{goTool(), "tool", "compile", "-e", "-o", "a.o"}
+		cmdline := []string{goTool(), "tool", "compile", "-d=panic", "-e", "-o", "a.o"}
 		cmdline = append(cmdline, flags...)
 		cmdline = append(cmdline, tfile)
 		out, err = runcmd(cmdline...)
@@ -1183,12 +1257,24 @@
 	}
 }
 
-func (t *test) expectedOutput() string {
+// checkExpectedOutput compares the output from compiling and/or running with the contents
+// of the corresponding reference output file, if any (replace ".go" with ".out").
+// If they don't match, fail with an informative message.
+func (t *test) checkExpectedOutput(gotBytes []byte) {
+	got := string(gotBytes)
 	filename := filepath.Join(t.dir, t.gofile)
 	filename = filename[:len(filename)-len(".go")]
 	filename += ".out"
-	b, _ := ioutil.ReadFile(filename)
-	return string(b)
+	b, err := ioutil.ReadFile(filename)
+	// File is allowed to be missing (err != nil) in which case output should be empty.
+	got = strings.Replace(got, "\r\n", "\n", -1)
+	if got != string(b) {
+		if err == nil {
+			t.err = fmt.Errorf("output does not match expected in %s. Instead saw\n%s", filename, got)
+		} else {
+			t.err = fmt.Errorf("output should be empty when (optional) expected-output file %s is not present. Instead saw\n%s", filename, got)
+		}
+	}
 }
 
 func splitOutput(out string, wantAuto bool) []string {
@@ -1854,3 +1940,67 @@
 		return err
 	})
 }
+
+// List of files that the compiler cannot errorcheck with the new typechecker (compiler -G option).
+// Temporary scaffolding until we pass all the tests at which point this map can be removed.
+var excluded = map[string]bool{
+	"complit1.go":     true, // types2 reports extra errors
+	"const2.go":       true, // types2 not run after syntax errors
+	"ddd1.go":         true, // issue #42987
+	"directive.go":    true, // misplaced compiler directive checks
+	"float_lit3.go":   true, // types2 reports extra errors
+	"import1.go":      true, // types2 reports extra errors
+	"import5.go":      true, // issue #42988
+	"import6.go":      true, // issue #43109
+	"initializerr.go": true, // types2 reports extra errors
+	"linkname2.go":    true, // error reported by noder (not running for types2 errorcheck test)
+	"notinheap.go":    true, // types2 doesn't report errors about conversions that are invalid due to //go:notinheap
+	"shift1.go":       true, // issue #42989
+	"typecheck.go":    true, // invalid function is not causing errors when called
+	"writebarrier.go": true, // correct diagnostics, but different lines (probably irgen's fault)
+
+	"fixedbugs/bug176.go":    true, // types2 reports all errors (pref: types2)
+	"fixedbugs/bug195.go":    true, // types2 reports slightly different (but correct) bugs
+	"fixedbugs/bug228.go":    true, // types2 not run after syntax errors
+	"fixedbugs/bug231.go":    true, // types2 bug? (same error reported twice)
+	"fixedbugs/bug255.go":    true, // types2 reports extra errors
+	"fixedbugs/bug351.go":    true, // types2 reports extra errors
+	"fixedbugs/bug374.go":    true, // types2 reports extra errors
+	"fixedbugs/bug385_32.go": true, // types2 doesn't produce missing error "type .* too large" (32-bit specific)
+	"fixedbugs/bug388.go":    true, // types2 not run due to syntax errors
+	"fixedbugs/bug412.go":    true, // types2 produces a follow-on error
+
+	"fixedbugs/issue11590.go":  true, // types2 doesn't report a follow-on error (pref: types2)
+	"fixedbugs/issue11610.go":  true, // types2 not run after syntax errors
+	"fixedbugs/issue11614.go":  true, // types2 reports an extra error
+	"fixedbugs/issue13415.go":  true, // declared but not used conflict
+	"fixedbugs/issue14520.go":  true, // missing import path error by types2
+	"fixedbugs/issue16428.go":  true, // types2 reports two instead of one error
+	"fixedbugs/issue17038.go":  true, // types2 doesn't report a follow-on error (pref: types2)
+	"fixedbugs/issue17645.go":  true, // multiple errors on same line
+	"fixedbugs/issue18331.go":  true, // missing error about misuse of //go:noescape (irgen needs code from noder)
+	"fixedbugs/issue18393.go":  true, // types2 not run after syntax errors
+	"fixedbugs/issue19012.go":  true, // multiple errors on same line
+	"fixedbugs/issue20233.go":  true, // types2 reports two instead of one error (pref: compiler)
+	"fixedbugs/issue20245.go":  true, // types2 reports two instead of one error (pref: compiler)
+	"fixedbugs/issue20250.go":  true, // correct diagnostics, but different lines (probably irgen's fault)
+	"fixedbugs/issue21979.go":  true, // types2 doesn't report a follow-on error (pref: types2)
+	"fixedbugs/issue23732.go":  true, // types2 reports different (but ok) line numbers
+	"fixedbugs/issue25958.go":  true, // types2 doesn't report a follow-on error (pref: types2)
+	"fixedbugs/issue28079b.go": true, // types2 reports follow-on errors
+	"fixedbugs/issue28268.go":  true, // types2 reports follow-on errors
+	"fixedbugs/issue33460.go":  true, // types2 reports alternative positions in separate error
+	"fixedbugs/issue41575.go":  true, // types2 reports alternative positions in separate error
+	"fixedbugs/issue42058a.go": true, // types2 doesn't report "channel element type too large"
+	"fixedbugs/issue42058b.go": true, // types2 doesn't report "channel element type too large"
+	"fixedbugs/issue4232.go":   true, // types2 reports (correct) extra errors
+	"fixedbugs/issue4452.go":   true, // types2 reports (correct) extra errors
+	"fixedbugs/issue5609.go":   true, // types2 needs a better error message
+	"fixedbugs/issue6889.go":   true, // types2 can handle this without constant overflow
+	"fixedbugs/issue7525.go":   true, // types2 reports init cycle error on different line - ok otherwise
+	"fixedbugs/issue7525b.go":  true, // types2 reports init cycle error on different line - ok otherwise
+	"fixedbugs/issue7525c.go":  true, // types2 reports init cycle error on different line - ok otherwise
+	"fixedbugs/issue7525d.go":  true, // types2 reports init cycle error on different line - ok otherwise
+	"fixedbugs/issue7525e.go":  true, // types2 reports init cycle error on different line - ok otherwise
+	"fixedbugs/issue46749.go":  true, // types2 reports can not convert error instead of type mismatched
+}
diff --git a/test/runtime.go b/test/runtime.go
index bccc9b5..58a5eee 100644
--- a/test/runtime.go
+++ b/test/runtime.go
@@ -17,5 +17,5 @@
 import "runtime"
 
 func main() {
-	runtime.printbool(true)	// ERROR "unexported"
+	runtime.printbool(true)	// ERROR "unexported|undefined"
 }
diff --git a/test/slice3err.go b/test/slice3err.go
index 1309fdd..120ecbe 100644
--- a/test/slice3err.go
+++ b/test/slice3err.go
@@ -17,12 +17,12 @@
 	_ = array[i:]
 	_ = array[:j]
 	_ = array[i:j]
-	_ = array[::] // ERROR "middle index required in 3-index slice" "final index required in 3-index slice"
-	_ = array[i::] // ERROR "middle index required in 3-index slice" "final index required in 3-index slice"
-	_ = array[:j:] // ERROR "final index required in 3-index slice"
-	_ = array[i:j:] // ERROR "final index required in 3-index slice"
-	_ = array[::k] // ERROR "middle index required in 3-index slice"
-	_ = array[i::k] // ERROR "middle index required in 3-index slice"
+	_ = array[::] // ERROR "middle index required in 3-index slice|invalid slice indices" "final index required in 3-index slice"
+	_ = array[i::] // ERROR "middle index required in 3-index slice|invalid slice indices" "final index required in 3-index slice"
+	_ = array[:j:] // ERROR "final index required in 3-index slice|invalid slice indices"
+	_ = array[i:j:] // ERROR "final index required in 3-index slice|invalid slice indices"
+	_ = array[::k] // ERROR "middle index required in 3-index slice|invalid slice indices"
+	_ = array[i::k] // ERROR "middle index required in 3-index slice|invalid slice indices"
 	_ = array[:j:k]
 	_ = array[i:j:k]
 	
@@ -30,12 +30,12 @@
 	_ = slice[i:]
 	_ = slice[:j]
 	_ = slice[i:j]
-	_ = slice[::] // ERROR "middle index required in 3-index slice" "final index required in 3-index slice"
-	_ = slice[i::] // ERROR "middle index required in 3-index slice" "final index required in 3-index slice"
-	_ = slice[:j:] // ERROR "final index required in 3-index slice"
-	_ = slice[i:j:] // ERROR "final index required in 3-index slice"
-	_ = slice[::k] // ERROR "middle index required in 3-index slice"
-	_ = slice[i::k] // ERROR "middle index required in 3-index slice"
+	_ = slice[::] // ERROR "middle index required in 3-index slice|invalid slice indices" "final index required in 3-index slice"
+	_ = slice[i::] // ERROR "middle index required in 3-index slice|invalid slice indices" "final index required in 3-index slice"
+	_ = slice[:j:] // ERROR "final index required in 3-index slice|invalid slice indices"
+	_ = slice[i:j:] // ERROR "final index required in 3-index slice|invalid slice indices"
+	_ = slice[::k] // ERROR "middle index required in 3-index slice|invalid slice indices"
+	_ = slice[i::k] // ERROR "middle index required in 3-index slice|invalid slice indices"
 	_ = slice[:j:k]
 	_ = slice[i:j:k]
 	
@@ -54,43 +54,43 @@
 
 	// check invalid indices
 	_ = array[1:2]
-	_ = array[2:1] // ERROR "invalid slice index|inverted slice"
+	_ = array[2:1] // ERROR "invalid slice index|invalid slice indices|inverted slice"
 	_ = array[2:2]
 	_ = array[i:1]
 	_ = array[1:j]
 	_ = array[1:2:3]
-	_ = array[1:3:2] // ERROR "invalid slice index|inverted slice"
-	_ = array[2:1:3] // ERROR "invalid slice index|inverted slice"
-	_ = array[2:3:1] // ERROR "invalid slice index|inverted slice"
-	_ = array[3:1:2] // ERROR "invalid slice index|inverted slice"
-	_ = array[3:2:1] // ERROR "invalid slice index|inverted slice"
+	_ = array[1:3:2] // ERROR "invalid slice index|invalid slice indices|inverted slice"
+	_ = array[2:1:3] // ERROR "invalid slice index|invalid slice indices|inverted slice"
+	_ = array[2:3:1] // ERROR "invalid slice index|invalid slice indices|inverted slice"
+	_ = array[3:1:2] // ERROR "invalid slice index|invalid slice indices|inverted slice"
+	_ = array[3:2:1] // ERROR "invalid slice index|invalid slice indices|inverted slice"
 	_ = array[i:1:2]
-	_ = array[i:2:1] // ERROR "invalid slice index|inverted slice"
+	_ = array[i:2:1] // ERROR "invalid slice index|invalid slice indices|inverted slice"
 	_ = array[1:j:2]
-	_ = array[2:j:1] // ERROR "invalid slice index"
+	_ = array[2:j:1] // ERROR "invalid slice index|invalid slice indices"
 	_ = array[1:2:k]
-	_ = array[2:1:k] // ERROR "invalid slice index|inverted slice"
+	_ = array[2:1:k] // ERROR "invalid slice index|invalid slice indices|inverted slice"
 	
 	_ = slice[1:2]
-	_ = slice[2:1] // ERROR "invalid slice index|inverted slice"
+	_ = slice[2:1] // ERROR "invalid slice index|invalid slice indices|inverted slice"
 	_ = slice[2:2]
 	_ = slice[i:1]
 	_ = slice[1:j]
 	_ = slice[1:2:3]
-	_ = slice[1:3:2] // ERROR "invalid slice index|inverted slice"
-	_ = slice[2:1:3] // ERROR "invalid slice index|inverted slice"
-	_ = slice[2:3:1] // ERROR "invalid slice index|inverted slice"
-	_ = slice[3:1:2] // ERROR "invalid slice index|inverted slice"
-	_ = slice[3:2:1] // ERROR "invalid slice index|inverted slice"
+	_ = slice[1:3:2] // ERROR "invalid slice index|invalid slice indices|inverted slice"
+	_ = slice[2:1:3] // ERROR "invalid slice index|invalid slice indices|inverted slice"
+	_ = slice[2:3:1] // ERROR "invalid slice index|invalid slice indices|inverted slice"
+	_ = slice[3:1:2] // ERROR "invalid slice index|invalid slice indices|inverted slice"
+	_ = slice[3:2:1] // ERROR "invalid slice index|invalid slice indices|inverted slice"
 	_ = slice[i:1:2]
-	_ = slice[i:2:1] // ERROR "invalid slice index|inverted slice"
+	_ = slice[i:2:1] // ERROR "invalid slice index|invalid slice indices|inverted slice"
 	_ = slice[1:j:2]
-	_ = slice[2:j:1] // ERROR "invalid slice index"
+	_ = slice[2:j:1] // ERROR "invalid slice index|invalid slice indices"
 	_ = slice[1:2:k]
-	_ = slice[2:1:k] // ERROR "invalid slice index|inverted slice"
+	_ = slice[2:1:k] // ERROR "invalid slice index|invalid slice indices|inverted slice"
 	
 	_ = str[1:2]
-	_ = str[2:1] // ERROR "invalid slice index|inverted slice"
+	_ = str[2:1] // ERROR "invalid slice index|invalid slice indices|inverted slice"
 	_ = str[2:2]
 	_ = str[i:1]
 	_ = str[1:j]
@@ -115,7 +115,7 @@
 	_ = slice[1:11]
 	_ = slice[1:11:12]
 	_ = slice[1:2:11]
-	_ = slice[1:11:3] // ERROR "invalid slice index"
-	_ = slice[11:2:3] // ERROR "invalid slice index|inverted slice"
+	_ = slice[1:11:3] // ERROR "invalid slice index|invalid slice indices"
+	_ = slice[11:2:3] // ERROR "invalid slice index|invalid slice indices|inverted slice"
 	_ = slice[11:12:13]
 }
diff --git a/test/stress/runstress.go b/test/stress/runstress.go
index 3f16fc9..b752fa8 100644
--- a/test/stress/runstress.go
+++ b/test/stress/runstress.go
@@ -12,7 +12,6 @@
 	"flag"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"log"
 	"math/rand"
 	"net"
@@ -70,7 +69,7 @@
 		if res.StatusCode != 200 {
 			log.Fatalf("stressNet: Status code = %d", res.StatusCode)
 		}
-		n, err := io.Copy(ioutil.Discard, res.Body)
+		n, err := io.Copy(io.Discard, res.Body)
 		if err != nil {
 			log.Fatalf("stressNet: io.Copy: %v", err)
 		}
diff --git a/test/switch3.go b/test/switch3.go
index 28705e4..4035632 100644
--- a/test/switch3.go
+++ b/test/switch3.go
@@ -28,21 +28,21 @@
 	var m, m1 map[int]int
 	switch m {
 	case nil:
-	case m1: // ERROR "can only compare map m to nil|map can only be compared to nil"
+	case m1: // ERROR "can only compare map m to nil|map can only be compared to nil|cannot compare"
 	default:
 	}
 
 	var a, a1 []int
 	switch a {
 	case nil:
-	case a1: // ERROR "can only compare slice a to nil|slice can only be compared to nil"
+	case a1: // ERROR "can only compare slice a to nil|slice can only be compared to nil|cannot compare"
 	default:
 	}
 
 	var f, f1 func()
 	switch f {
 	case nil:
-	case f1: // ERROR "can only compare func f to nil|func can only be compared to nil"
+	case f1: // ERROR "can only compare func f to nil|func can only be compared to nil|cannot compare"
 	default:
 	}
 
diff --git a/test/switch5.go b/test/switch5.go
index ce95bf8..dcf7ba0 100644
--- a/test/switch5.go
+++ b/test/switch5.go
@@ -12,41 +12,41 @@
 func f0(x int) {
 	switch x {
 	case 0:
-	case 0: // ERROR "duplicate case 0 in switch"
+	case 0: // ERROR "duplicate case (0 in switch)?"
 	}
 
 	switch x {
 	case 0:
-	case int(0): // ERROR "duplicate case int.0. .value 0. in switch"
+	case int(0): // ERROR "duplicate case (int.0. .value 0. in switch)?"
 	}
 }
 
 func f1(x float32) {
 	switch x {
 	case 5:
-	case 5: // ERROR "duplicate case 5 in switch"
-	case 5.0: // ERROR "duplicate case 5 in switch"
+	case 5: // ERROR "duplicate case (5 in switch)?"
+	case 5.0: // ERROR "duplicate case (5 in switch)?"
 	}
 }
 
 func f2(s string) {
 	switch s {
 	case "":
-	case "": // ERROR "duplicate case .. in switch"
+	case "": // ERROR "duplicate case (.. in switch)?"
 	case "abc":
-	case "abc": // ERROR "duplicate case .abc. in switch"
+	case "abc": // ERROR "duplicate case (.abc. in switch)?"
 	}
 }
 
 func f3(e interface{}) {
 	switch e {
 	case 0:
-	case 0: // ERROR "duplicate case 0 in switch"
+	case 0: // ERROR "duplicate case (0 in switch)?"
 	case int64(0):
 	case float32(10):
-	case float32(10): // ERROR "duplicate case float32\(10\) .value 10. in switch"
+	case float32(10): // ERROR "duplicate case (float32\(10\) .value 10. in switch)?"
 	case float64(10):
-	case float64(10): // ERROR "duplicate case float64\(10\) .value 10. in switch"
+	case float64(10): // ERROR "duplicate case (float64\(10\) .value 10. in switch)?"
 	}
 }
 
@@ -82,13 +82,13 @@
 func f8(r rune) {
 	const x = 10
 	switch r {
-	case 33, 33: // ERROR "duplicate case 33 in switch"
+	case 33, 33: // ERROR "duplicate case (33 in switch)?"
 	case 34, '"': // ERROR "duplicate case '"' .value 34. in switch"
-	case 35, rune('#'): // ERROR "duplicate case rune.'#'. .value 35. in switch"
-	case 36, rune(36): // ERROR "duplicate case rune.36. .value 36. in switch"
-	case 37, '$'+1: // ERROR "duplicate case '\$' \+ 1 .value 37. in switch"
+	case 35, rune('#'): // ERROR "duplicate case (rune.'#'. .value 35. in switch)?"
+	case 36, rune(36): // ERROR "duplicate case (rune.36. .value 36. in switch)?"
+	case 37, '$'+1: // ERROR "duplicate case ('\$' \+ 1 .value 37. in switch)?"
 	case 'b':
-	case 'a', 'b', 'c', 'd': // ERROR "duplicate case 'b' .value 98."
-	case x, x: // ERROR "duplicate case x .value 10."
+	case 'a', 'b', 'c', 'd': // ERROR "duplicate case ('b' .value 98.)?"
+	case x, x: // ERROR "duplicate case (x .value 10.)?"
 	}
 }
diff --git a/test/switch6.go b/test/switch6.go
index 9d102fe..4f95d02 100644
--- a/test/switch6.go
+++ b/test/switch6.go
@@ -15,7 +15,7 @@
 // Verify that type switch statements with impossible cases are detected by the compiler.
 func f0(e error) {
 	switch e.(type) {
-	case int: // ERROR "impossible type switch case: e \(type error\) cannot have dynamic type int \(missing Error method\)"
+	case int: // ERROR "impossible type switch case: e \(type error\) cannot have dynamic type int \(missing Error method\)|impossible type assertion"
 	}
 }
 
@@ -23,11 +23,11 @@
 func f1(e interface{}) {
 	switch e {
 	default:
-	default: // ERROR "multiple defaults in switch"
+	default: // ERROR "multiple defaults( in switch)?"
 	}
 	switch e.(type) {
 	default:
-	default: // ERROR "multiple defaults in switch"
+	default: // ERROR "multiple defaults( in switch)?"
 	}
 }
 
@@ -41,6 +41,6 @@
 func f2() {
 	var i I
 	switch i.(type) {
-	case X: // ERROR "impossible type switch case: i \(type I\) cannot have dynamic type X \(Foo method has pointer receiver\)"
+	case X: // ERROR "impossible type switch case: i \(type I\) cannot have dynamic type X \(Foo method has pointer receiver\)|impossible type assertion"
 	}
 }
diff --git a/test/switch7.go b/test/switch7.go
index 7506066..3fb0129 100644
--- a/test/switch7.go
+++ b/test/switch7.go
@@ -27,7 +27,7 @@
 	case struct {
 		i int "tag2"
 	}:
-	case struct { // ERROR "duplicate case struct { i int .tag1. } in type switch"
+	case struct { // ERROR "duplicate case struct { i int .tag1. } in type switch|duplicate case"
 		i int "tag1"
 	}:
 	}
diff --git a/test/syntax/interface.go b/test/syntax/interface.go
deleted file mode 100644
index 010d3ce..0000000
--- a/test/syntax/interface.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// errorcheck
-
-// 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 main
-
-type T interface {
-	f, g ()	// ERROR "name list not allowed in interface type"
-}
-
-
-
diff --git a/test/typecheckloop.go b/test/typecheckloop.go
index 3b3e788..13f413c 100644
--- a/test/typecheckloop.go
+++ b/test/typecheckloop.go
@@ -9,6 +9,6 @@
 
 package main
 
-const A = 1 + B // ERROR "constant definition loop\n.*A uses B\n.*B uses C\n.*C uses A"
-const B = C - 1 // ERROR "constant definition loop\n.*B uses C\n.*C uses B"
+const A = 1 + B // ERROR "constant definition loop\n.*A uses B\n.*B uses C\n.*C uses A|initialization loop"
+const B = C - 1 // ERROR "constant definition loop\n.*B uses C\n.*C uses B|initialization loop"
 const C = A + B + 1
diff --git a/test/typeparam/absdiff.go b/test/typeparam/absdiff.go
new file mode 100644
index 0000000..1381d7c
--- /dev/null
+++ b/test/typeparam/absdiff.go
@@ -0,0 +1,98 @@
+// run -gcflags=-G=3
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"math"
+)
+
+type Numeric interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64,
+		complex64, complex128
+}
+
+// numericAbs matches numeric types with an Abs method.
+type numericAbs[T any] interface {
+	Numeric
+	Abs() T
+}
+
+// AbsDifference computes the absolute value of the difference of
+// a and b, where the absolute value is determined by the Abs method.
+func absDifference[T numericAbs[T]](a, b T) T {
+	d := a - b
+	return d.Abs()
+}
+
+// orderedNumeric matches numeric types that support the < operator.
+type orderedNumeric interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64
+}
+
+// Complex matches the two complex types, which do not have a < operator.
+type Complex interface {
+	type complex64, complex128
+}
+
+// orderedAbs is a helper type that defines an Abs method for
+// ordered numeric types.
+type orderedAbs[T orderedNumeric] T
+
+func (a orderedAbs[T]) Abs() orderedAbs[T] {
+	// TODO(danscales): orderedAbs[T] conversion shouldn't be needed
+	if a < orderedAbs[T](0) {
+		return -a
+	}
+	return a
+}
+
+// complexAbs is a helper type that defines an Abs method for
+// complex types.
+type complexAbs[T Complex] T
+
+func (a complexAbs[T]) Abs() complexAbs[T] {
+	r := float64(real(a))
+	i := float64(imag(a))
+	d := math.Sqrt(r * r + i * i)
+	return complexAbs[T](complex(d, 0))
+}
+
+// OrderedAbsDifference returns the absolute value of the difference
+// between a and b, where a and b are of an ordered type.
+func orderedAbsDifference[T orderedNumeric](a, b T) T {
+	return T(absDifference(orderedAbs[T](a), orderedAbs[T](b)))
+}
+
+// ComplexAbsDifference returns the absolute value of the difference
+// between a and b, where a and b are of a complex type.
+func complexAbsDifference[T Complex](a, b T) T {
+	return T(absDifference(complexAbs[T](a), complexAbs[T](b)))
+}
+
+func main() {
+	if got, want := orderedAbsDifference(1.0, -2.0), 3.0; got != want {
+		panic(fmt.Sprintf("got = %v, want = %v", got, want))
+	}
+	if got, want := orderedAbsDifference(-1.0, 2.0), 3.0; got != want {
+		panic(fmt.Sprintf("got = %v, want = %v", got, want))
+	}
+	if got, want := orderedAbsDifference(-20, 15), 35; got != want {
+		panic(fmt.Sprintf("got = %v, want = %v", got, want))
+	}
+
+	if got, want := complexAbsDifference(5.0 + 2.0i, 2.0 - 2.0i), 5+0i; got != want {
+		panic(fmt.Sprintf("got = %v, want = %v", got, want))
+	}
+	if got, want := complexAbsDifference(2.0 - 2.0i, 5.0 + 2.0i), 5+0i; got != want {
+		panic(fmt.Sprintf("got = %v, want = %v", got, want))
+	}
+}
diff --git a/test/typeparam/adder.go b/test/typeparam/adder.go
new file mode 100644
index 0000000..0c25ad4
--- /dev/null
+++ b/test/typeparam/adder.go
@@ -0,0 +1,29 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+type AddType interface {
+	type int, int64, string
+}
+
+// _Add can add numbers or strings
+func _Add[T AddType](a, b T) T {
+	return a + b
+}
+
+func main() {
+	if got, want := _Add(5, 3), 8; got != want {
+		panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+	if got, want := _Add("ab", "cd"), "abcd"; got != want {
+		panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+}
diff --git a/test/typeparam/append.go b/test/typeparam/append.go
new file mode 100644
index 0000000..8b9bc20
--- /dev/null
+++ b/test/typeparam/append.go
@@ -0,0 +1,31 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type Recv <-chan int
+
+type sliceOf[E any] interface {
+	type []E
+}
+
+func _Append[S sliceOf[T], T any](s S, t ...T) S {
+	return append(s, t...)
+}
+
+func main() {
+	recv := make(Recv)
+	a := _Append([]Recv{recv}, recv)
+	if len(a) != 2 || a[0] != recv || a[1] != recv {
+		panic(a)
+	}
+
+	recv2 := make(chan<- int)
+	a2 := _Append([]chan<- int{recv2}, recv2)
+	if len(a2) != 2 || a2[0] != recv2 || a2[1] != recv2 {
+		panic(a)
+	}
+}
diff --git a/test/typeparam/chans.go b/test/typeparam/chans.go
new file mode 100644
index 0000000..2fcd4af
--- /dev/null
+++ b/test/typeparam/chans.go
@@ -0,0 +1,413 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package chans provides utility functions for working with channels.
+package main
+
+import (
+	"context"
+	"fmt"
+	"runtime"
+	"sort"
+	"sync"
+	"time"
+)
+
+// _Equal reports whether two slices are equal: the same length and all
+// elements equal. All floating point NaNs are considered equal.
+func _SliceEqual[Elem comparable](s1, s2 []Elem) bool {
+	if len(s1) != len(s2) {
+		return false
+	}
+	for i, v1 := range s1 {
+		v2 := s2[i]
+		if v1 != v2 {
+			isNaN := func(f Elem) bool { return f != f }
+			if !isNaN(v1) || !isNaN(v2) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// _ReadAll reads from c until the channel is closed or the context is
+// canceled, returning all the values read.
+func _ReadAll[Elem any](ctx context.Context, c <-chan Elem) []Elem {
+	var r []Elem
+	for {
+		select {
+		case <-ctx.Done():
+			return r
+		case v, ok := <-c:
+			if !ok {
+				return r
+			}
+			r = append(r, v)
+		}
+	}
+}
+
+// _Merge merges two channels into a single channel.
+// This will leave a goroutine running until either both channels are closed
+// or the context is canceled, at which point the returned channel is closed.
+func _Merge[Elem any](ctx context.Context, c1, c2 <-chan Elem) <-chan Elem {
+	r := make(chan Elem)
+	go func(ctx context.Context, c1, c2 <-chan Elem, r chan<- Elem) {
+		defer close(r)
+		for c1 != nil || c2 != nil {
+			select {
+			case <-ctx.Done():
+				return
+			case v1, ok := <-c1:
+				if ok {
+					r <- v1
+				} else {
+					c1 = nil
+				}
+			case v2, ok := <-c2:
+				if ok {
+					r <- v2
+				} else {
+					c2 = nil
+				}
+			}
+		}
+	}(ctx, c1, c2, r)
+	return r
+}
+
+// _Filter calls f on each value read from c. If f returns true the value
+// is sent on the returned channel. This will leave a goroutine running
+// until c is closed or the context is canceled, at which point the
+// returned channel is closed.
+func _Filter[Elem any](ctx context.Context, c <-chan Elem, f func(Elem) bool) <-chan Elem {
+	r := make(chan Elem)
+	go func(ctx context.Context, c <-chan Elem, f func(Elem) bool, r chan<- Elem) {
+		defer close(r)
+		for {
+			select {
+			case <-ctx.Done():
+				return
+			case v, ok := <-c:
+				if !ok {
+					return
+				}
+				if f(v) {
+					r <- v
+				}
+			}
+		}
+	}(ctx, c, f, r)
+	return r
+}
+
+// _Sink returns a channel that discards all values sent to it.
+// This will leave a goroutine running until the context is canceled
+// or the returned channel is closed.
+func _Sink[Elem any](ctx context.Context) chan<- Elem {
+	r := make(chan Elem)
+	go func(ctx context.Context, r <-chan Elem) {
+		for {
+			select {
+			case <-ctx.Done():
+				return
+			case _, ok := <-r:
+				if !ok {
+					return
+				}
+			}
+		}
+	}(ctx, r)
+	return r
+}
+
+// An Exclusive is a value that may only be used by a single goroutine
+// at a time. This is implemented using channels rather than a mutex.
+type _Exclusive[Val any] struct {
+	c chan Val
+}
+
+// _MakeExclusive makes an initialized exclusive value.
+func _MakeExclusive[Val any](initial Val) *_Exclusive[Val] {
+	r := &_Exclusive[Val]{
+		c: make(chan Val, 1),
+	}
+	r.c <- initial
+	return r
+}
+
+// _Acquire acquires the exclusive value for private use.
+// It must be released using the Release method.
+func (e *_Exclusive[Val]) Acquire() Val {
+	return <-e.c
+}
+
+// TryAcquire attempts to acquire the value. The ok result reports whether
+// the value was acquired. If the value is acquired, it must be released
+// using the Release method.
+func (e *_Exclusive[Val]) TryAcquire() (v Val, ok bool) {
+	select {
+	case r := <-e.c:
+		return r, true
+	default:
+		return v, false
+	}
+}
+
+// Release updates and releases the value.
+// This method panics if the value has not been acquired.
+func (e *_Exclusive[Val]) Release(v Val) {
+	select {
+	case e.c <- v:
+	default:
+		panic("_Exclusive Release without Acquire")
+	}
+}
+
+// Ranger returns a Sender and a Receiver. The Receiver provides a
+// Next method to retrieve values. The Sender provides a Send method
+// to send values and a Close method to stop sending values. The Next
+// method indicates when the Sender has been closed, and the Send
+// method indicates when the Receiver has been freed.
+//
+// This is a convenient way to exit a goroutine sending values when
+// the receiver stops reading them.
+func _Ranger[Elem any]() (*_Sender[Elem], *_Receiver[Elem]) {
+	c := make(chan Elem)
+	d := make(chan struct{})
+	s := &_Sender[Elem]{
+		values: c,
+		done:   d,
+	}
+	r := &_Receiver[Elem] {
+		values: c,
+		done:   d,
+	}
+	runtime.SetFinalizer(r, (*_Receiver[Elem]).finalize)
+	return s, r
+}
+
+// A _Sender is used to send values to a Receiver.
+type _Sender[Elem any] struct {
+	values chan<- Elem
+	done   <-chan struct{}
+}
+
+// Send sends a value to the receiver. It reports whether the value was sent.
+// The value will not be sent if the context is closed or the receiver
+// is freed.
+func (s *_Sender[Elem]) Send(ctx context.Context, v Elem) bool {
+	select {
+	case <-ctx.Done():
+		return false
+	case s.values <- v:
+		return true
+	case <-s.done:
+		return false
+	}
+}
+
+// Close tells the receiver that no more values will arrive.
+// After Close is called, the _Sender may no longer be used.
+func (s *_Sender[Elem]) Close() {
+	close(s.values)
+}
+
+// A _Receiver receives values from a _Sender.
+type _Receiver[Elem any] struct {
+	values <-chan Elem
+	done   chan<- struct{}
+}
+
+// Next returns the next value from the channel. The bool result indicates
+// whether the value is valid.
+func (r *_Receiver[Elem]) Next(ctx context.Context) (v Elem, ok bool) {
+	select {
+	case <-ctx.Done():
+	case v, ok = <-r.values:
+	}
+	return v, ok
+}
+
+// finalize is a finalizer for the receiver.
+func (r *_Receiver[Elem]) finalize() {
+	close(r.done)
+}
+
+func TestReadAll() {
+	c := make(chan int)
+	go func() {
+		c <- 4
+		c <- 2
+		c <- 5
+		close(c)
+	}()
+	got := _ReadAll(context.Background(), c)
+	want := []int{4, 2, 5}
+	if !_SliceEqual(got, want) {
+		panic(fmt.Sprintf("_ReadAll returned %v, want %v", got, want))
+	}
+}
+
+func TestMerge() {
+	c1 := make(chan int)
+	c2 := make(chan int)
+	go func() {
+		c1 <- 1
+		c1 <- 3
+		c1 <- 5
+		close(c1)
+	}()
+	go func() {
+		c2 <- 2
+		c2 <- 4
+		c2 <- 6
+		close(c2)
+	}()
+	ctx := context.Background()
+	got := _ReadAll(ctx, _Merge(ctx, c1, c2))
+	sort.Ints(got)
+	want := []int{1, 2, 3, 4, 5, 6}
+	if !_SliceEqual(got, want) {
+		panic(fmt.Sprintf("_Merge returned %v, want %v", got, want))
+	}
+}
+
+func TestFilter() {
+	c := make(chan int)
+	go func() {
+		c <- 1
+		c <- 2
+		c <- 3
+		close(c)
+	}()
+	even := func(i int) bool { return i%2 == 0 }
+	ctx := context.Background()
+	got := _ReadAll(ctx, _Filter(ctx, c, even))
+	want := []int{2}
+	if !_SliceEqual(got, want) {
+		panic(fmt.Sprintf("_Filter returned %v, want %v", got, want))
+	}
+}
+
+func TestSink() {
+	c := _Sink[int](context.Background())
+	after := time.NewTimer(time.Minute)
+	defer after.Stop()
+	send := func(v int) {
+		select {
+		case c <- v:
+		case <-after.C:
+			panic("timed out sending to _Sink")
+		}
+	}
+	send(1)
+	send(2)
+	send(3)
+	close(c)
+}
+
+func TestExclusive() {
+	val := 0
+	ex := _MakeExclusive(&val)
+
+	var wg sync.WaitGroup
+	f := func() {
+		defer wg.Done()
+		for i := 0; i < 10; i++ {
+			p := ex.Acquire()
+			(*p)++
+			ex.Release(p)
+		}
+	}
+
+	wg.Add(2)
+	go f()
+	go f()
+
+	wg.Wait()
+	if val != 20 {
+		panic(fmt.Sprintf("after Acquire/Release loop got %d, want 20", val))
+	}
+}
+
+func TestExclusiveTry() {
+	s := ""
+	ex := _MakeExclusive(&s)
+	p, ok := ex.TryAcquire()
+	if !ok {
+		panic("TryAcquire failed")
+	}
+	*p = "a"
+
+	var wg sync.WaitGroup
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		_, ok := ex.TryAcquire()
+		if ok {
+			panic(fmt.Sprintf("TryAcquire succeeded unexpectedly"))
+		}
+	}()
+	wg.Wait()
+
+	ex.Release(p)
+
+	p, ok = ex.TryAcquire()
+	if !ok {
+		panic(fmt.Sprintf("TryAcquire failed"))
+	}
+}
+
+func TestRanger() {
+	s, r := _Ranger[int]()
+
+	ctx := context.Background()
+	go func() {
+		// Receive one value then exit.
+		v, ok := r.Next(ctx)
+		if !ok {
+			panic(fmt.Sprintf("did not receive any values"))
+		} else if v != 1 {
+			panic(fmt.Sprintf("received %d, want 1", v))
+		}
+	}()
+
+	c1 := make(chan bool)
+	c2 := make(chan bool)
+	go func() {
+		defer close(c2)
+		if !s.Send(ctx, 1) {
+			panic(fmt.Sprintf("Send failed unexpectedly"))
+		}
+		close(c1)
+		if s.Send(ctx, 2) {
+			panic(fmt.Sprintf("Send succeeded unexpectedly"))
+		}
+	}()
+
+	<-c1
+
+	// Force a garbage collection to try to get the finalizers to run.
+	runtime.GC()
+
+	select {
+	case <-c2:
+	case <-time.After(time.Minute):
+		panic("_Ranger Send should have failed, but timed out")
+	}
+}
+
+func main() {
+	TestReadAll()
+	TestMerge()
+	TestFilter()
+	TestSink()
+	TestExclusive()
+	TestExclusiveTry()
+	TestRanger()
+}
diff --git a/test/typeparam/combine.go b/test/typeparam/combine.go
new file mode 100644
index 0000000..d4a2988
--- /dev/null
+++ b/test/typeparam/combine.go
@@ -0,0 +1,65 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+type _Gen[A any] func() (A, bool)
+
+func combine[T1, T2, T any](g1 _Gen[T1], g2 _Gen[T2], join func(T1, T2) T) _Gen[T] {
+    return func() (T, bool) {
+        var t T
+        t1, ok := g1()
+        if !ok {
+            return t, false
+        }
+        t2, ok := g2()
+        if !ok {
+            return t, false
+        }
+        return join(t1, t2), true
+    }
+}
+
+type _Pair[A, B any] struct {
+	A A
+	B B
+}
+
+func _NewPair[A, B any](a A, b B) _Pair[A, B] {
+	return _Pair[A, B]{a, b}
+}
+
+func _Combine2[A, B any](ga _Gen[A], gb _Gen[B]) _Gen[_Pair[A, B]] {
+    return combine(ga, gb, _NewPair[A, B])
+}
+
+func main() {
+	var g1 _Gen[int] = func() (int, bool) { return 3, true }
+	var g2 _Gen[string] = func() (string, bool) { return "x", false }
+	var g3 _Gen[string] = func() (string, bool) { return "y", true }
+
+	gc := combine(g1, g2, _NewPair[int, string])
+	if got, ok := gc(); ok {
+		panic(fmt.Sprintf("got %v, %v, wanted -/false", got, ok))
+	}
+	gc2 := _Combine2(g1, g2)
+	if got, ok := gc2(); ok {
+		panic(fmt.Sprintf("got %v, %v, wanted -/false", got, ok))
+	}
+
+	gc3 := combine(g1, g3, _NewPair[int, string])
+	if got, ok := gc3(); !ok || got.A != 3 || got.B != "y" {
+		panic(fmt.Sprintf("got %v, %v, wanted {3, y}, true", got, ok))
+	}
+	gc4 := _Combine2(g1, g3)
+	if got, ok := gc4(); !ok || got.A != 3 || got.B != "y" {
+		panic (fmt.Sprintf("got %v, %v, wanted {3, y}, true", got, ok))
+	}
+}
diff --git a/test/typeparam/cons.go b/test/typeparam/cons.go
new file mode 100644
index 0000000..8d255eb
--- /dev/null
+++ b/test/typeparam/cons.go
@@ -0,0 +1,100 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// lice
+
+package main
+
+import "fmt"
+
+// Overriding the predeclare "any", so it can be used as a type constraint or a type
+// argument
+type any interface{}
+
+type _Function[a, b any] interface {
+	Apply(x a) b
+}
+
+type incr struct{ n int }
+
+func (this incr) Apply(x int) int {
+	return x + this.n
+}
+
+type pos struct{}
+
+func (this pos) Apply(x int) bool {
+	return x > 0
+}
+
+type compose[a, b, c any] struct {
+	f _Function[a, b]
+	g _Function[b, c]
+}
+
+func (this compose[a, b, c]) Apply(x a) c {
+	return this.g.Apply(this.f.Apply(x))
+}
+
+type _Eq[a any] interface {
+	Equal(a) bool
+}
+
+type Int int
+
+func (this Int) Equal(that int) bool {
+	return int(this) == that
+}
+
+type _List[a any] interface {
+	Match(casenil _Function[_Nil[a], any], casecons _Function[_Cons[a], any]) any
+}
+
+type _Nil[a any] struct{
+}
+
+func (xs _Nil[a]) Match(casenil _Function[_Nil[a], any], casecons _Function[_Cons[a], any]) any {
+	return casenil.Apply(xs)
+}
+
+type _Cons[a any] struct {
+	Head a
+	Tail _List[a]
+}
+
+func (xs _Cons[a]) Match(casenil _Function[_Nil[a], any], casecons _Function[_Cons[a], any]) any {
+	return casecons.Apply(xs)
+}
+
+type mapNil[a, b any] struct{
+}
+
+func (m mapNil[a, b]) Apply(_ _Nil[a]) any {
+	return _Nil[b]{}
+}
+
+type mapCons[a, b any] struct {
+	f _Function[a, b]
+}
+
+func (m mapCons[a, b]) Apply(xs _Cons[a]) any {
+	return _Cons[b]{m.f.Apply(xs.Head), _Map[a, b](m.f, xs.Tail)}
+}
+
+func _Map[a, b any](f _Function[a, b], xs _List[a]) _List[b] {
+	return xs.Match(mapNil[a, b]{}, mapCons[a, b]{f}).(_List[b])
+}
+
+func main() {
+	var xs _List[int] = _Cons[int]{3, _Cons[int]{6, _Nil[int]{}}}
+	var ys _List[int] = _Map[int, int](incr{-5}, xs)
+	var xz _List[bool] = _Map[int, bool](pos{}, ys)
+	cs1 := xz.(_Cons[bool])
+	cs2 := cs1.Tail.(_Cons[bool])
+	_, ok := cs2.Tail.(_Nil[bool])
+	if cs1.Head != false || cs2.Head != true || !ok {
+		panic(fmt.Sprintf("got %v, %v, %v, expected false, true, true",
+			cs1.Head, cs2.Head, ok))
+	}
+}
diff --git a/test/typeparam/double.go b/test/typeparam/double.go
new file mode 100644
index 0000000..ce78ec9
--- /dev/null
+++ b/test/typeparam/double.go
@@ -0,0 +1,72 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"reflect"
+)
+
+type Number interface {
+	type int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, float32, float64
+}
+
+type MySlice []int
+type MyFloatSlice []float64
+
+type _SliceOf[E any] interface {
+	type []E
+}
+
+func _DoubleElems[S _SliceOf[E], E Number](s S) S {
+	r := make(S, len(s))
+	for i, v := range s {
+		r[i] = v + v
+	}
+	return r
+}
+
+// Test use of untyped constant in an expression with a generically-typed parameter
+func _DoubleElems2[S _SliceOf[E], E Number](s S) S {
+	r := make(S, len(s))
+	for i, v := range s {
+		r[i] = v * 2
+	}
+	return r
+}
+
+func main() {
+	arg := MySlice{1, 2, 3}
+	want := MySlice{2, 4, 6}
+	got := _DoubleElems[MySlice, int](arg)
+	if !reflect.DeepEqual(got, want) {
+                panic(fmt.Sprintf("got %s, want %s", got, want))
+	}
+
+	// constraint type inference
+	got = _DoubleElems[MySlice](arg)
+	if !reflect.DeepEqual(got, want) {
+                panic(fmt.Sprintf("got %s, want %s", got, want))
+	}
+
+	got = _DoubleElems(arg)
+	if !reflect.DeepEqual(got, want) {
+                panic(fmt.Sprintf("got %s, want %s", got, want))
+	}
+
+	farg := MyFloatSlice{1.2, 2.0, 3.5}
+	fwant := MyFloatSlice{2.4, 4.0, 7.0}
+	fgot := _DoubleElems(farg)
+	if !reflect.DeepEqual(fgot, fwant) {
+                panic(fmt.Sprintf("got %s, want %s", fgot, fwant))
+	}
+
+	fgot = _DoubleElems2(farg)
+	if !reflect.DeepEqual(fgot, fwant) {
+                panic(fmt.Sprintf("got %s, want %s", fgot, fwant))
+	}
+}
diff --git a/test/typeparam/fact.go b/test/typeparam/fact.go
new file mode 100644
index 0000000..16b2adf
--- /dev/null
+++ b/test/typeparam/fact.go
@@ -0,0 +1,32 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+func fact[T interface { type int, int64, float64 }](n T) T {
+	if n == T(1) {
+		return T(1)
+	}
+	return n * fact(n - T(1))
+}
+
+func main() {
+	const want = 120
+
+	if got := fact(5); got != want {
+		panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+
+	if got := fact[int64](5); got != want {
+		panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+
+	if got := fact(5.0); got != want {
+		panic(fmt.Sprintf("got %f, want %f", got, want))
+	}
+}
diff --git a/test/typeparam/graph.go b/test/typeparam/graph.go
new file mode 100644
index 0000000..f2a2630
--- /dev/null
+++ b/test/typeparam/graph.go
@@ -0,0 +1,231 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"errors"
+	"fmt"
+)
+
+// _Equal reports whether two slices are equal: the same length and all
+// elements equal. All floating point NaNs are considered equal.
+func _SliceEqual[Elem comparable](s1, s2 []Elem) bool {
+	if len(s1) != len(s2) {
+		return false
+	}
+	for i, v1 := range s1 {
+		v2 := s2[i]
+		if v1 != v2 {
+			isNaN := func(f Elem) bool { return f != f }
+			if !isNaN(v1) || !isNaN(v2) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// A Graph is a collection of nodes. A node may have an arbitrary number
+// of edges. An edge connects two nodes. Both nodes and edges must be
+// comparable. This is an undirected simple graph.
+type _Graph[_Node _NodeC[_Edge], _Edge _EdgeC[_Node]] struct {
+	nodes []_Node
+}
+
+// _NodeC is the contraints on a node in a graph, given the _Edge type.
+type _NodeC[_Edge any] interface {
+	comparable
+	Edges() []_Edge
+}
+
+// Edgec is the constraints on an edge in a graph, given the _Node type.
+type _EdgeC[_Node any] interface {
+	comparable
+	Nodes() (a, b _Node)
+}
+
+// _New creates a new _Graph from a collection of Nodes.
+func _New[_Node _NodeC[_Edge], _Edge _EdgeC[_Node]](nodes []_Node) *_Graph[_Node, _Edge] {
+	return &_Graph[_Node, _Edge]{nodes: nodes}
+}
+
+// nodePath holds the path to a node during ShortestPath.
+// This should ideally be a type defined inside ShortestPath,
+// but the translator tool doesn't support that.
+type nodePath[_Node _NodeC[_Edge], _Edge _EdgeC[_Node]] struct {
+	node _Node
+	path []_Edge
+}
+
+// ShortestPath returns the shortest path between two nodes,
+// as an ordered list of edges. If there are multiple shortest paths,
+// which one is returned is unpredictable.
+func (g *_Graph[_Node, _Edge]) ShortestPath(from, to _Node) ([]_Edge, error) {
+	visited := make(map[_Node]bool)
+	visited[from] = true
+	workqueue := []nodePath[_Node, _Edge]{nodePath[_Node, _Edge]{from, nil}}
+	for len(workqueue) > 0 {
+		current := workqueue
+		workqueue = nil
+		for _, np := range current {
+			edges := np.node.Edges()
+			for _, edge := range edges {
+				a, b := edge.Nodes()
+				if a == np.node {
+					a = b
+				}
+				if !visited[a] {
+					ve := append([]_Edge(nil), np.path...)
+					ve = append(ve, edge)
+					if a == to {
+						return ve, nil
+					}
+					workqueue = append(workqueue, nodePath[_Node, _Edge]{a, ve})
+					visited[a] = true
+				}
+			}
+		}
+	}
+	return nil, errors.New("no path")
+}
+
+type direction int
+
+const (
+	north direction = iota
+	ne
+	east
+	se
+	south
+	sw
+	west
+	nw
+	up
+	down
+)
+
+func (dir direction) String() string {
+	strs := map[direction]string{
+		north: "north",
+		ne:    "ne",
+		east:  "east",
+		se:    "se",
+		south: "south",
+		sw:    "sw",
+		west:  "west",
+		nw:    "nw",
+		up:    "up",
+		down:  "down",
+	}
+	if str, ok := strs[dir]; ok {
+		return str
+	}
+	return fmt.Sprintf("direction %d", dir)
+}
+
+type mazeRoom struct {
+	index int
+	exits [10]int
+}
+
+type mazeEdge struct {
+	from, to int
+	dir      direction
+}
+
+// Edges returns the exits from the room.
+func (m mazeRoom) Edges() []mazeEdge {
+	var r []mazeEdge
+	for i, exit := range m.exits {
+		if exit != 0 {
+			r = append(r, mazeEdge{
+				from: m.index,
+				to:   exit,
+				dir:  direction(i),
+			})
+		}
+	}
+	return r
+}
+
+// Nodes returns the rooms connected by an edge.
+//go:noinline
+func (e mazeEdge) Nodes() (mazeRoom, mazeRoom) {
+	m1, ok := zork[e.from]
+	if !ok {
+		panic("bad edge")
+	}
+	m2, ok := zork[e.to]
+	if !ok {
+		panic("bad edge")
+	}
+	return m1, m2
+}
+
+// The first maze in Zork. Room indexes based on original Fortran data file.
+// You are in a maze of twisty little passages, all alike.
+var zork = map[int]mazeRoom{
+	11: {exits: [10]int{north: 11, south: 12, east: 14}}, // west to Troll Room
+	12: {exits: [10]int{south: 11, north: 14, east: 13}},
+	13: {exits: [10]int{west: 12, north: 14, up: 16}},
+	14: {exits: [10]int{west: 13, north: 11, east: 15}},
+	15: {exits: [10]int{south: 14}},                   // Dead End
+	16: {exits: [10]int{east: 17, north: 13, sw: 18}}, // skeleton, etc.
+	17: {exits: [10]int{west: 16}},                    // Dead End
+	18: {exits: [10]int{down: 16, east: 19, west: 18, up: 22}},
+	19: {exits: [10]int{up: 29, west: 18, ne: 15, east: 20, south: 30}},
+	20: {exits: [10]int{ne: 19, west: 20, se: 21}},
+	21: {exits: [10]int{north: 20}}, // Dead End
+	22: {exits: [10]int{north: 18, east: 24, down: 23, south: 28, west: 26, nw: 22}},
+	23: {exits: [10]int{east: 22, west: 28, up: 24}},
+	24: {exits: [10]int{ne: 25, down: 23, nw: 28, sw: 26}},
+	25: {exits: [10]int{sw: 24}}, // Grating room (up to Clearing)
+	26: {exits: [10]int{west: 16, sw: 24, east: 28, up: 22, north: 27}},
+	27: {exits: [10]int{south: 26}}, // Dead End
+	28: {exits: [10]int{east: 22, down: 26, south: 23, west: 24}},
+	29: {exits: [10]int{west: 30, nw: 29, ne: 19, south: 19}},
+	30: {exits: [10]int{west: 29, south: 19}}, // ne to Cyclops Room
+}
+
+func TestShortestPath() {
+	// The Zork maze is not a proper undirected simple graph,
+	// as there are some one way paths (e.g., 19 -> 15),
+	// but for this test that doesn't matter.
+
+	// Set the index field in the map. Simpler than doing it in the
+	// composite literal.
+	for k := range zork {
+		r := zork[k]
+		r.index = k
+		zork[k] = r
+	}
+
+	var nodes []mazeRoom
+	for idx, room := range zork {
+		mridx := room
+		mridx.index = idx
+		nodes = append(nodes, mridx)
+	}
+	g := _New[mazeRoom, mazeEdge](nodes)
+	path, err := g.ShortestPath(zork[11], zork[30])
+	if err != nil {
+		panic(fmt.Sprintf("%v", err))
+	}
+	var steps []direction
+	for _, edge := range path {
+		steps = append(steps, edge.dir)
+	}
+	want := []direction{east, west, up, sw, east, south}
+	if !_SliceEqual(steps, want) {
+		panic(fmt.Sprintf("ShortestPath returned %v, want %v", steps, want))
+	}
+}
+
+
+func main() {
+	TestShortestPath()
+}
diff --git a/test/typeparam/importtest.go b/test/typeparam/importtest.go
new file mode 100644
index 0000000..9cb30e8
--- /dev/null
+++ b/test/typeparam/importtest.go
@@ -0,0 +1,16 @@
+// compile -G
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file checks that basic importing works in -G mode.
+
+package p
+
+import "fmt"
+import "math"
+
+func f(x float64) {
+	fmt.Println(math.Sin(x))
+}
diff --git a/test/typeparam/index.go b/test/typeparam/index.go
new file mode 100644
index 0000000..83e65ac
--- /dev/null
+++ b/test/typeparam/index.go
@@ -0,0 +1,46 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+// Index returns the index of x in s, or -1 if not found.
+func index[T comparable](s []T, x T) int {
+	for i, v := range s {
+		// v and x are type T, which has the comparable
+		// constraint, so we can use == here.
+		if v == x {
+			return i
+		}
+	}
+	return -1
+}
+
+type obj struct {
+	x int
+}
+
+func main() {
+	want := 2
+
+	vec1 := []string{"ab", "cd", "ef"}
+	if got := index(vec1, "ef"); got != want {
+		panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+
+	vec2 := []byte{'c', '6', '@'}
+	if got := index(vec2, '@'); got != want {
+		panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+
+	vec3 := []*obj{&obj{2}, &obj{42}, &obj{1}}
+	if got := index(vec3, vec3[2]); got != want {
+		panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+}
diff --git a/test/typeparam/interfacearg.go b/test/typeparam/interfacearg.go
new file mode 100644
index 0000000..e2d85e3
--- /dev/null
+++ b/test/typeparam/interfacearg.go
@@ -0,0 +1,44 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type I interface{}
+
+type _S[T any] struct {
+	*T
+}
+
+// F is a non-generic function, but has a type _S[I] which is instantiated from a
+// generic type. Test that _S[I] is successfully exported.
+func F() {
+	v := _S[I]{}
+	if v.T != nil {
+		panic(v)
+	}
+}
+
+// Testing the various combinations of method expressions.
+type S1 struct{}
+func (*S1) M() {}
+
+type S2 struct{}
+func (S2) M() {}
+
+func _F1[T interface{ M() }](t T) {
+	_ = T.M
+}
+
+func F2() {
+        _F1(&S1{})
+        _F1(S2{})
+        _F1(&S2{})
+}
+
+func main() {
+	F()
+	F2()
+}
diff --git a/test/typeparam/issue45547.go b/test/typeparam/issue45547.go
new file mode 100644
index 0000000..0a08d66
--- /dev/null
+++ b/test/typeparam/issue45547.go
@@ -0,0 +1,20 @@
+// compile -G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f[T any]() (f, g T) { return f, g }
+
+// Tests for generic function instantiation on the right hande side of multi-value
+// assignments.
+
+func _() {
+	// Multi-value assignment within a function
+	var _, _ = f[int]()
+}
+
+// Multi-value assignment outside a function.
+var _, _ = f[int]()
diff --git a/test/typeparam/issue45722.go b/test/typeparam/issue45722.go
new file mode 100644
index 0000000..0d7c20c
--- /dev/null
+++ b/test/typeparam/issue45722.go
@@ -0,0 +1,34 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"log"
+)
+
+func try[T any](v T, err error) T {
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+func handle(handle func(error)) {
+	if issue := recover(); issue != nil {
+		if e, ok := issue.(error); ok && e != nil {
+			handle(e)
+		} else {
+			handle(fmt.Errorf("%v", e))
+		}
+	}
+}
+
+func main() {
+	defer handle(func(e error) { log.Fatalln(e) })
+	_ = try(fmt.Print(""))
+}
diff --git a/test/typeparam/issue45738.go b/test/typeparam/issue45738.go
new file mode 100644
index 0000000..9f03e79
--- /dev/null
+++ b/test/typeparam/issue45738.go
@@ -0,0 +1,18 @@
+// compile -G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+//go:noinline
+func f[T any]() {
+	x := 5
+	g := func() int { return x }
+	g()
+}
+
+func main() {
+	f[int]()
+}
diff --git a/test/typeparam/list.go b/test/typeparam/list.go
new file mode 100644
index 0000000..579078f
--- /dev/null
+++ b/test/typeparam/list.go
@@ -0,0 +1,103 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+type Ordered interface {
+        type int, int8, int16, int32, int64,
+                uint, uint8, uint16, uint32, uint64, uintptr,
+                float32, float64,
+                string
+}
+
+// _List is a linked list of ordered values of type T.
+type _List[T Ordered] struct {
+	next *_List[T]
+	val  T
+}
+
+func (l *_List[T]) Largest() T {
+	var max T
+	for p := l; p != nil; p = p.next {
+		if p.val > max {
+			max = p.val
+		}
+	}
+	return max
+}
+
+type OrderedNum interface {
+        type int, int8, int16, int32, int64,
+                uint, uint8, uint16, uint32, uint64, uintptr,
+                float32, float64
+}
+
+// _ListNum is a linked _List of ordered numeric values of type T.
+type _ListNum[T OrderedNum] struct {
+	next *_ListNum[T]
+	val  T
+}
+
+const Clip = 5
+
+// clippedLargest returns the largest in the list of OrderNums, but a max of 5.
+// Test use of untyped constant in an expression with a generically-typed parameter
+func (l *_ListNum[T]) ClippedLargest() T {
+	var max T
+	for p := l; p != nil; p = p.next {
+		if p.val > max && p.val < Clip {
+			max = p.val
+		}
+	}
+	return max
+}
+
+func main() {
+	i3 := &_List[int]{nil, 1}
+	i2 := &_List[int]{i3, 3}
+	i1 := &_List[int]{i2, 2}
+	if got, want := i1.Largest(), 3; got != want {
+                panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+
+	b3 := &_List[byte]{nil, byte(1)}
+	b2 := &_List[byte]{b3, byte(3)}
+	b1 := &_List[byte]{b2, byte(2)}
+	if got, want := b1.Largest(), byte(3); got != want {
+                panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+
+	f3 := &_List[float64]{nil, 13.5}
+	f2 := &_List[float64]{f3, 1.2}
+	f1 := &_List[float64]{f2, 4.5}
+	if got, want := f1.Largest(), 13.5; got != want {
+                panic(fmt.Sprintf("got %f, want %f", got, want))
+	}
+
+	s3 := &_List[string]{nil, "dd"}
+	s2 := &_List[string]{s3, "aa"}
+	s1 := &_List[string]{s2, "bb"}
+	if got, want := s1.Largest(), "dd"; got != want {
+                panic(fmt.Sprintf("got %s, want %s", got, want))
+	}
+
+	j3 := &_ListNum[int]{nil, 1}
+	j2 := &_ListNum[int]{j3, 32}
+	j1 := &_ListNum[int]{j2, 2}
+	if got, want := j1.ClippedLargest(), 2; got != want {
+                panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+	g3 := &_ListNum[float64]{nil, 13.5}
+	g2 := &_ListNum[float64]{g3, 1.2}
+	g1 := &_ListNum[float64]{g2, 4.5}
+	if got, want := g1.ClippedLargest(), 4.5; got != want {
+                panic(fmt.Sprintf("got %f, want %f", got, want))
+	}
+}
diff --git a/test/typeparam/list2.go b/test/typeparam/list2.go
new file mode 100644
index 0000000..385193d
--- /dev/null
+++ b/test/typeparam/list2.go
@@ -0,0 +1,601 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package list provides a doubly linked list of some element type
+// (generic form of the "container/list" package).
+
+package main
+
+import (
+	"fmt"
+	"strconv"
+)
+
+// Element is an element of a linked list.
+type _Element[T any] struct {
+	// Next and previous pointers in the doubly-linked list of elements.
+	// To simplify the implementation, internally a list l is implemented
+	// as a ring, such that &l.root is both the next element of the last
+	// list element (l.Back()) and the previous element of the first list
+	// element (l.Front()).
+	next, prev *_Element[T]
+
+	// The list to which this element belongs.
+	list *_List[T]
+
+	// The value stored with this element.
+	Value T
+}
+
+// Next returns the next list element or nil.
+func (e *_Element[T]) Next() *_Element[T] {
+	if p := e.next; e.list != nil && p != &e.list.root {
+		return p
+	}
+	return nil
+}
+
+// Prev returns the previous list element or nil.
+func (e *_Element[T]) Prev() *_Element[T] {
+	if p := e.prev; e.list != nil && p != &e.list.root {
+		return p
+	}
+	return nil
+}
+
+// _List represents a doubly linked list.
+// The zero value for _List is an empty list ready to use.
+type _List[T any] struct {
+	root _Element[T] // sentinel list element, only &root, root.prev, and root.next are used
+	len  int     // current list length excluding (this) sentinel element
+}
+
+// Init initializes or clears list l.
+func (l *_List[T]) Init() *_List[T] {
+	l.root.next = &l.root
+	l.root.prev = &l.root
+	l.len = 0
+	return l
+}
+
+// New returns an initialized list.
+func _New[T any]() *_List[T] { return new(_List[T]).Init() }
+
+// Len returns the number of elements of list l.
+// The complexity is O(1).
+func (l *_List[_]) Len() int { return l.len }
+
+// Front returns the first element of list l or nil if the list is empty.
+func (l *_List[T]) Front() *_Element[T] {
+	if l.len == 0 {
+		return nil
+	}
+	return l.root.next
+}
+
+// Back returns the last element of list l or nil if the list is empty.
+func (l *_List[T]) Back() *_Element[T] {
+	if l.len == 0 {
+		return nil
+	}
+	return l.root.prev
+}
+
+// lazyInit lazily initializes a zero _List value.
+func (l *_List[_]) lazyInit() {
+	if l.root.next == nil {
+		l.Init()
+	}
+}
+
+// insert inserts e after at, increments l.len, and returns e.
+func (l *_List[T]) insert(e, at *_Element[T]) *_Element[T] {
+	e.prev = at
+	e.next = at.next
+	e.prev.next = e
+	e.next.prev = e
+	e.list = l
+	l.len++
+	return e
+}
+
+// insertValue is a convenience wrapper for insert(&_Element[T]{Value: v}, at).
+func (l *_List[T]) insertValue(v T, at *_Element[T]) *_Element[T] {
+	return l.insert(&_Element[T]{Value: v}, at)
+}
+
+// remove removes e from its list, decrements l.len, and returns e.
+func (l *_List[T]) remove(e *_Element[T]) *_Element[T] {
+	e.prev.next = e.next
+	e.next.prev = e.prev
+	e.next = nil // avoid memory leaks
+	e.prev = nil // avoid memory leaks
+	e.list = nil
+	l.len--
+	return e
+}
+
+// move moves e to next to at and returns e.
+func (l *_List[T]) move(e, at *_Element[T]) *_Element[T] {
+	if e == at {
+		return e
+	}
+	e.prev.next = e.next
+	e.next.prev = e.prev
+
+	e.prev = at
+	e.next = at.next
+	e.prev.next = e
+	e.next.prev = e
+
+	return e
+}
+
+// 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[T]) Remove(e *_Element[T]) T {
+	if e.list == l {
+		// if e.list == l, l must have been initialized when e was inserted
+		// in l or l == nil (e is a zero _Element) and l.remove will crash
+		l.remove(e)
+	}
+	return e.Value
+}
+
+// PushFront inserts a new element e with value v at the front of list l and returns e.
+func (l *_List[T]) PushFront(v T) *_Element[T] {
+	l.lazyInit()
+	return l.insertValue(v, &l.root)
+}
+
+// PushBack inserts a new element e with value v at the back of list l and returns e.
+func (l *_List[T]) PushBack(v T) *_Element[T] {
+	l.lazyInit()
+	return l.insertValue(v, l.root.prev)
+}
+
+// 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[T]) InsertBefore(v T, mark *_Element[T]) *_Element[T] {
+	if mark.list != l {
+		return nil
+	}
+	// see comment in _List.Remove about initialization of l
+	return l.insertValue(v, mark.prev)
+}
+
+// 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[T]) InsertAfter(v T, mark *_Element[T]) *_Element[T] {
+	if mark.list != l {
+		return nil
+	}
+	// see comment in _List.Remove about initialization of l
+	return l.insertValue(v, mark)
+}
+
+// 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[T]) MoveToFront(e *_Element[T]) {
+	if e.list != l || l.root.next == e {
+		return
+	}
+	// see comment in _List.Remove about initialization of l
+	l.move(e, &l.root)
+}
+
+// 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[T]) MoveToBack(e *_Element[T]) {
+	if e.list != l || l.root.prev == e {
+		return
+	}
+	// see comment in _List.Remove about initialization of l
+	l.move(e, l.root.prev)
+}
+
+// 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[T]) MoveBefore(e, mark *_Element[T]) {
+	if e.list != l || e == mark || mark.list != l {
+		return
+	}
+	l.move(e, mark.prev)
+}
+
+// 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[T]) MoveAfter(e, mark *_Element[T]) {
+	if e.list != l || e == mark || mark.list != l {
+		return
+	}
+	l.move(e, mark)
+}
+
+// PushBackList inserts a copy of an other list at the back of list l.
+// The lists l and other may be the same. They must not be nil.
+func (l *_List[T]) PushBackList(other *_List[T]) {
+	l.lazyInit()
+	for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() {
+		l.insertValue(e.Value, l.root.prev)
+	}
+}
+
+// PushFrontList inserts a copy of an other list at the front of list l.
+// The lists l and other may be the same. They must not be nil.
+func (l *_List[T]) PushFrontList(other *_List[T]) {
+	l.lazyInit()
+	for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() {
+		l.insertValue(e.Value, &l.root)
+	}
+}
+
+// Transform runs a transform function on a list returning a new list.
+func _Transform[TElem1, TElem2 any](lst *_List[TElem1], f func(TElem1) TElem2) *_List[TElem2] {
+	ret := _New[TElem2]()
+	for p := lst.Front(); p != nil; p = p.Next() {
+		ret.PushBack(f(p.Value))
+	}
+	return ret
+}
+
+func checkListLen[T any](l *_List[T], len int) bool {
+	if n := l.Len(); n != len {
+		panic(fmt.Sprintf("l.Len() = %d, want %d", n, len))
+		return false
+	}
+	return true
+}
+
+func checkListPointers[T any](l *_List[T], es []*_Element[T]) {
+	root := &l.root
+
+	if !checkListLen(l, len(es)) {
+		return
+	}
+
+	// zero length lists must be the zero value or properly initialized (sentinel circle)
+	if len(es) == 0 {
+		if l.root.next != nil && l.root.next != root || l.root.prev != nil && l.root.prev != root {
+			panic(fmt.Sprintf("l.root.next = %p, l.root.prev = %p; both should both be nil or %p", l.root.next, l.root.prev, root))
+		}
+		return
+	}
+	// len(es) > 0
+
+	// check internal and external prev/next connections
+	for i, e := range es {
+		prev := root
+		Prev := (*_Element[T])(nil)
+		if i > 0 {
+			prev = es[i-1]
+			Prev = prev
+		}
+		if p := e.prev; p != prev {
+			panic(fmt.Sprintf("elt[%d](%p).prev = %p, want %p", i, e, p, prev))
+		}
+		if p := e.Prev(); p != Prev {
+			panic(fmt.Sprintf("elt[%d](%p).Prev() = %p, want %p", i, e, p, Prev))
+		}
+
+		next := root
+		Next := (*_Element[T])(nil)
+		if i < len(es)-1 {
+			next = es[i+1]
+			Next = next
+		}
+		if n := e.next; n != next {
+			panic(fmt.Sprintf("elt[%d](%p).next = %p, want %p", i, e, n, next))
+		}
+		if n := e.Next(); n != Next {
+			panic(fmt.Sprintf("elt[%d](%p).Next() = %p, want %p", i, e, n, Next))
+		}
+	}
+}
+
+func TestList() {
+	l := _New[string]()
+	checkListPointers(l, []*(_Element[string]){})
+
+	// Single element list
+	e := l.PushFront("a")
+	checkListPointers(l, []*(_Element[string]){e})
+	l.MoveToFront(e)
+	checkListPointers(l, []*(_Element[string]){e})
+	l.MoveToBack(e)
+	checkListPointers(l, []*(_Element[string]){e})
+	l.Remove(e)
+	checkListPointers(l, []*(_Element[string]){})
+
+	// Bigger list
+	l2 := _New[int]()
+	e2 := l2.PushFront(2)
+	e1 := l2.PushFront(1)
+	e3 := l2.PushBack(3)
+	e4 := l2.PushBack(600)
+	checkListPointers(l2, []*(_Element[int]){e1, e2, e3, e4})
+
+	l2.Remove(e2)
+	checkListPointers(l2, []*(_Element[int]){e1, e3, e4})
+
+	l2.MoveToFront(e3) // move from middle
+	checkListPointers(l2, []*(_Element[int]){e3, e1, e4})
+
+	l2.MoveToFront(e1)
+	l2.MoveToBack(e3) // move from middle
+	checkListPointers(l2, []*(_Element[int]){e1, e4, e3})
+
+	l2.MoveToFront(e3) // move from back
+	checkListPointers(l2, []*(_Element[int]){e3, e1, e4})
+	l2.MoveToFront(e3) // should be no-op
+	checkListPointers(l2, []*(_Element[int]){e3, e1, e4})
+
+	l2.MoveToBack(e3) // move from front
+	checkListPointers(l2, []*(_Element[int]){e1, e4, e3})
+	l2.MoveToBack(e3) // should be no-op
+	checkListPointers(l2, []*(_Element[int]){e1, e4, e3})
+
+	e2 = l2.InsertBefore(2, e1) // insert before front
+	checkListPointers(l2, []*(_Element[int]){e2, e1, e4, e3})
+	l2.Remove(e2)
+	e2 = l2.InsertBefore(2, e4) // insert before middle
+	checkListPointers(l2, []*(_Element[int]){e1, e2, e4, e3})
+	l2.Remove(e2)
+	e2 = l2.InsertBefore(2, e3) // insert before back
+	checkListPointers(l2, []*(_Element[int]){e1, e4, e2, e3})
+	l2.Remove(e2)
+
+	e2 = l2.InsertAfter(2, e1) // insert after front
+	checkListPointers(l2, []*(_Element[int]){e1, e2, e4, e3})
+	l2.Remove(e2)
+	e2 = l2.InsertAfter(2, e4) // insert after middle
+	checkListPointers(l2, []*(_Element[int]){e1, e4, e2, e3})
+	l2.Remove(e2)
+	e2 = l2.InsertAfter(2, e3) // insert after back
+	checkListPointers(l2, []*(_Element[int]){e1, e4, e3, e2})
+	l2.Remove(e2)
+
+	// Check standard iteration.
+	sum := 0
+	for e := l2.Front(); e != nil; e = e.Next() {
+		sum += e.Value
+	}
+	if sum != 604 {
+		panic(fmt.Sprintf("sum over l = %d, want 604", sum))
+	}
+
+	// Clear all elements by iterating
+	var next *_Element[int]
+	for e := l2.Front(); e != nil; e = next {
+		next = e.Next()
+		l2.Remove(e)
+	}
+	checkListPointers(l2, []*(_Element[int]){})
+}
+
+func checkList[T comparable](l *_List[T], es []interface{}) {
+	if !checkListLen(l, len(es)) {
+		return
+	}
+
+	i := 0
+	for e := l.Front(); e != nil; e = e.Next() {
+		le := e.Value
+		// Comparison between a generically-typed variable le and an interface.
+		if le != es[i] {
+			panic(fmt.Sprintf("elt[%d].Value = %v, want %v", i, le, es[i]))
+		}
+		i++
+	}
+}
+
+func TestExtending() {
+	l1 := _New[int]()
+	l2 := _New[int]()
+
+	l1.PushBack(1)
+	l1.PushBack(2)
+	l1.PushBack(3)
+
+	l2.PushBack(4)
+	l2.PushBack(5)
+
+	l3 := _New[int]()
+	l3.PushBackList(l1)
+	checkList(l3, []interface{}{1, 2, 3})
+	l3.PushBackList(l2)
+	checkList(l3, []interface{}{1, 2, 3, 4, 5})
+
+	l3 = _New[int]()
+	l3.PushFrontList(l2)
+	checkList(l3, []interface{}{4, 5})
+	l3.PushFrontList(l1)
+	checkList(l3, []interface{}{1, 2, 3, 4, 5})
+
+	checkList(l1, []interface{}{1, 2, 3})
+	checkList(l2, []interface{}{4, 5})
+
+	l3 = _New[int]()
+	l3.PushBackList(l1)
+	checkList(l3, []interface{}{1, 2, 3})
+	l3.PushBackList(l3)
+	checkList(l3, []interface{}{1, 2, 3, 1, 2, 3})
+
+	l3 = _New[int]()
+	l3.PushFrontList(l1)
+	checkList(l3, []interface{}{1, 2, 3})
+	l3.PushFrontList(l3)
+	checkList(l3, []interface{}{1, 2, 3, 1, 2, 3})
+
+	l3 = _New[int]()
+	l1.PushBackList(l3)
+	checkList(l1, []interface{}{1, 2, 3})
+	l1.PushFrontList(l3)
+	checkList(l1, []interface{}{1, 2, 3})
+}
+
+func TestRemove() {
+	l := _New[int]()
+	e1 := l.PushBack(1)
+	e2 := l.PushBack(2)
+	checkListPointers(l, []*(_Element[int]){e1, e2})
+	e := l.Front()
+	l.Remove(e)
+	checkListPointers(l, []*(_Element[int]){e2})
+	l.Remove(e)
+	checkListPointers(l, []*(_Element[int]){e2})
+}
+
+func TestIssue4103() {
+	l1 := _New[int]()
+	l1.PushBack(1)
+	l1.PushBack(2)
+
+	l2 := _New[int]()
+	l2.PushBack(3)
+	l2.PushBack(4)
+
+	e := l1.Front()
+	l2.Remove(e) // l2 should not change because e is not an element of l2
+	if n := l2.Len(); n != 2 {
+		panic(fmt.Sprintf("l2.Len() = %d, want 2", n))
+	}
+
+	l1.InsertBefore(8, e)
+	if n := l1.Len(); n != 3 {
+		panic(fmt.Sprintf("l1.Len() = %d, want 3", n))
+	}
+}
+
+func TestIssue6349() {
+	l := _New[int]()
+	l.PushBack(1)
+	l.PushBack(2)
+
+	e := l.Front()
+	l.Remove(e)
+	if e.Value != 1 {
+		panic(fmt.Sprintf("e.value = %d, want 1", e.Value))
+	}
+	if e.Next() != nil {
+		panic(fmt.Sprintf("e.Next() != nil"))
+	}
+	if e.Prev() != nil {
+		panic(fmt.Sprintf("e.Prev() != nil"))
+	}
+}
+
+func TestMove() {
+	l := _New[int]()
+	e1 := l.PushBack(1)
+	e2 := l.PushBack(2)
+	e3 := l.PushBack(3)
+	e4 := l.PushBack(4)
+
+	l.MoveAfter(e3, e3)
+	checkListPointers(l, []*(_Element[int]){e1, e2, e3, e4})
+	l.MoveBefore(e2, e2)
+	checkListPointers(l, []*(_Element[int]){e1, e2, e3, e4})
+
+	l.MoveAfter(e3, e2)
+	checkListPointers(l, []*(_Element[int]){e1, e2, e3, e4})
+	l.MoveBefore(e2, e3)
+	checkListPointers(l, []*(_Element[int]){e1, e2, e3, e4})
+
+	l.MoveBefore(e2, e4)
+	checkListPointers(l, []*(_Element[int]){e1, e3, e2, e4})
+	e2, e3 = e3, e2
+
+	l.MoveBefore(e4, e1)
+	checkListPointers(l, []*(_Element[int]){e4, e1, e2, e3})
+	e1, e2, e3, e4 = e4, e1, e2, e3
+
+	l.MoveAfter(e4, e1)
+	checkListPointers(l, []*(_Element[int]){e1, e4, e2, e3})
+	e2, e3, e4 = e4, e2, e3
+
+	l.MoveAfter(e2, e3)
+	checkListPointers(l, []*(_Element[int]){e1, e3, e2, e4})
+	e2, e3 = e3, e2
+}
+
+// Test PushFront, PushBack, PushFrontList, PushBackList with uninitialized _List
+func TestZeroList() {
+	var l1 = new(_List[int])
+	l1.PushFront(1)
+	checkList(l1, []interface{}{1})
+
+	var l2 = new(_List[int])
+	l2.PushBack(1)
+	checkList(l2, []interface{}{1})
+
+	var l3 = new(_List[int])
+	l3.PushFrontList(l1)
+	checkList(l3, []interface{}{1})
+
+	var l4 = new(_List[int])
+	l4.PushBackList(l2)
+	checkList(l4, []interface{}{1})
+}
+
+// Test that a list l is not modified when calling InsertBefore with a mark that is not an element of l.
+func TestInsertBeforeUnknownMark() {
+	var l _List[int]
+	l.PushBack(1)
+	l.PushBack(2)
+	l.PushBack(3)
+	l.InsertBefore(1, new(_Element[int]))
+	checkList(&l, []interface{}{1, 2, 3})
+}
+
+// Test that a list l is not modified when calling InsertAfter with a mark that is not an element of l.
+func TestInsertAfterUnknownMark() {
+	var l _List[int]
+	l.PushBack(1)
+	l.PushBack(2)
+	l.PushBack(3)
+	l.InsertAfter(1, new(_Element[int]))
+	checkList(&l, []interface{}{1, 2, 3})
+}
+
+// Test that a list l is not modified when calling MoveAfter or MoveBefore with a mark that is not an element of l.
+func TestMoveUnknownMark() {
+	var l1 _List[int]
+	e1 := l1.PushBack(1)
+
+	var l2 _List[int]
+	e2 := l2.PushBack(2)
+
+	l1.MoveAfter(e1, e2)
+	checkList(&l1, []interface{}{1})
+	checkList(&l2, []interface{}{2})
+
+	l1.MoveBefore(e1, e2)
+	checkList(&l1, []interface{}{1})
+	checkList(&l2, []interface{}{2})
+}
+
+// Test the Transform function.
+func TestTransform() {
+	l1 := _New[int]()
+	l1.PushBack(1)
+	l1.PushBack(2)
+	l2 := _Transform(l1, strconv.Itoa)
+	checkList(l2, []interface{}{"1", "2"})
+}
+
+
+func main() {
+	TestList()
+}
+
diff --git a/test/typeparam/lockable.go b/test/typeparam/lockable.go
new file mode 100644
index 0000000..d538175
--- /dev/null
+++ b/test/typeparam/lockable.go
@@ -0,0 +1,50 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "sync"
+
+// A _Lockable is a value that may be safely simultaneously accessed
+// from multiple goroutines via the Get and Set methods.
+type _Lockable[T any] struct {
+	T
+	mu sync.Mutex
+}
+
+// Get returns the value stored in a _Lockable.
+func (l *_Lockable[T]) get() T {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	return l.T
+}
+
+// set sets the value in a _Lockable.
+func (l *_Lockable[T]) set(v T) {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	l.T = v
+}
+
+func main() {
+	sl := _Lockable[string]{T: "a"}
+	if got := sl.get(); got != "a" {
+		panic(got)
+	}
+	sl.set("b")
+	if got := sl.get(); got != "b" {
+		panic(got)
+	}
+
+	il := _Lockable[int]{T: 1}
+	if got := il.get(); got != 1 {
+		panic(got)
+	}
+	il.set(2)
+	if got := il.get(); got != 2 {
+		panic(got)
+	}
+}
diff --git a/test/typeparam/map.go b/test/typeparam/map.go
new file mode 100644
index 0000000..72d05f0
--- /dev/null
+++ b/test/typeparam/map.go
@@ -0,0 +1,39 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"reflect"
+	"strconv"
+)
+
+// Map calls the function f on every element of the slice s,
+// returning a new slice of the results.
+func mapper[F, T any](s []F, f func(F) T) []T {
+	r := make([]T, len(s))
+	for i, v := range s {
+		r[i] = f(v)
+	}
+	return r
+}
+
+func main() {
+	got := mapper([]int{1, 2, 3}, strconv.Itoa)
+	want := []string{"1", "2", "3"}
+	if !reflect.DeepEqual(got, want) {
+		panic(fmt.Sprintf("got %s, want %s", got, want))
+	}
+
+	fgot := mapper([]float64{2.5, 2.3, 3.5}, func(f float64) string {
+		return strconv.FormatFloat(f, 'f', -1, 64)
+	})
+	fwant := []string{"2.5", "2.3", "3.5"}
+	if !reflect.DeepEqual(fgot, fwant) {
+		panic(fmt.Sprintf("got %s, want %s", fgot, fwant))
+	}
+}
diff --git a/test/typeparam/maps.go b/test/typeparam/maps.go
new file mode 100644
index 0000000..d18dd59
--- /dev/null
+++ b/test/typeparam/maps.go
@@ -0,0 +1,260 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"math"
+	"sort"
+)
+
+// _Equal reports whether two slices are equal: the same length and all
+// elements equal. All floating point NaNs are considered equal.
+func _SliceEqual[Elem comparable](s1, s2 []Elem) bool {
+	if len(s1) != len(s2) {
+		return false
+	}
+	for i, v1 := range s1 {
+		v2 := s2[i]
+		if v1 != v2 {
+			isNaN := func(f Elem) bool { return f != f }
+			if !isNaN(v1) || !isNaN(v2) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// _Keys returns the keys of the map m.
+// The keys will be an indeterminate order.
+func _Keys[K comparable, V any](m map[K]V) []K {
+	r := make([]K, 0, len(m))
+	for k := range m {
+		r = append(r, k)
+	}
+	return r
+}
+
+// _Values returns the values of the map m.
+// The values will be in an indeterminate order.
+func _Values[K comparable, V any](m map[K]V) []V {
+	r := make([]V, 0, len(m))
+	for _, v := range m {
+		r = append(r, v)
+	}
+	return r
+}
+
+// _Equal reports whether two maps contain the same key/value pairs.
+// _Values are compared using ==.
+func _Equal[K, V comparable](m1, m2 map[K]V) bool {
+	if len(m1) != len(m2) {
+		return false
+	}
+	for k, v1 := range m1 {
+		if v2, ok := m2[k]; !ok || v1 != v2 {
+			return false
+		}
+	}
+	return true
+}
+
+// _Copy returns a copy of m.
+func _Copy[K comparable, V any](m map[K]V) map[K]V {
+	r := make(map[K]V, len(m))
+	for k, v := range m {
+		r[k] = v
+	}
+	return r
+}
+
+// _Add adds all key/value pairs in m2 to m1. _Keys in m2 that are already
+// present in m1 will be overwritten with the value in m2.
+func _Add[K comparable, V any](m1, m2 map[K]V) {
+	for k, v := range m2 {
+		m1[k] = v
+	}
+}
+
+// _Sub removes all keys in m2 from m1. _Keys in m2 that are not present
+// in m1 are ignored. The values in m2 are ignored.
+func _Sub[K comparable, V any](m1, m2 map[K]V) {
+	for k := range m2 {
+		delete(m1, k)
+	}
+}
+
+// _Intersect removes all keys from m1 that are not present in m2.
+// _Keys in m2 that are not in m1 are ignored. The values in m2 are ignored.
+func _Intersect[K comparable, V any](m1, m2 map[K]V) {
+	for k := range m1 {
+		if _, ok := m2[k]; !ok {
+			delete(m1, k)
+		}
+	}
+}
+
+// _Filter deletes any key/value pairs from m for which f returns false.
+func _Filter[K comparable, V any](m map[K]V, f func(K, V) bool) {
+	for k, v := range m {
+		if !f(k, v) {
+			delete(m, k)
+		}
+	}
+}
+
+// _TransformValues applies f to each value in m. The keys remain unchanged.
+func _TransformValues[K comparable, V any](m map[K]V, f func(V) V) {
+	for k, v := range m {
+		m[k] = f(v)
+	}
+}
+
+var m1 = map[int]int{1: 2, 2: 4, 4: 8, 8: 16}
+var m2 = map[int]string{1: "2", 2: "4", 4: "8", 8: "16"}
+
+func TestKeys() {
+	want := []int{1, 2, 4, 8}
+
+	got1 := _Keys(m1)
+	sort.Ints(got1)
+	if !_SliceEqual(got1, want) {
+		panic(fmt.Sprintf("_Keys(%v) = %v, want %v", m1, got1, want))
+	}
+
+	got2 := _Keys(m2)
+	sort.Ints(got2)
+	if !_SliceEqual(got2, want) {
+		panic(fmt.Sprintf("_Keys(%v) = %v, want %v", m2, got2, want))
+	}
+}
+
+func TestValues() {
+	got1 := _Values(m1)
+	want1 := []int{2, 4, 8, 16}
+	sort.Ints(got1)
+	if !_SliceEqual(got1, want1) {
+		panic(fmt.Sprintf("_Values(%v) = %v, want %v", m1, got1, want1))
+	}
+
+	got2 := _Values(m2)
+	want2 := []string{"16", "2", "4", "8"}
+	sort.Strings(got2)
+	if !_SliceEqual(got2, want2) {
+		panic(fmt.Sprintf("_Values(%v) = %v, want %v", m2, got2, want2))
+	}
+}
+
+func TestEqual() {
+	if !_Equal(m1, m1) {
+		panic(fmt.Sprintf("_Equal(%v, %v) = false, want true", m1, m1))
+	}
+	if _Equal(m1, nil) {
+		panic(fmt.Sprintf("_Equal(%v, nil) = true, want false", m1))
+	}
+	if _Equal(nil, m1) {
+		panic(fmt.Sprintf("_Equal(nil, %v) = true, want false", m1))
+	}
+	if !_Equal[int, int](nil, nil) {
+		panic("_Equal(nil, nil) = false, want true")
+	}
+	if ms := map[int]int{1: 2}; _Equal(m1, ms) {
+		panic(fmt.Sprintf("_Equal(%v, %v) = true, want false", m1, ms))
+	}
+
+	// Comparing NaN for equality is expected to fail.
+	mf := map[int]float64{1: 0, 2: math.NaN()}
+	if _Equal(mf, mf) {
+		panic(fmt.Sprintf("_Equal(%v, %v) = true, want false", mf, mf))
+	}
+}
+
+func TestCopy() {
+	m2 := _Copy(m1)
+	if !_Equal(m1, m2) {
+		panic(fmt.Sprintf("_Copy(%v) = %v, want %v", m1, m2, m1))
+	}
+	m2[16] = 32
+	if _Equal(m1, m2) {
+		panic(fmt.Sprintf("_Equal(%v, %v) = true, want false", m1, m2))
+	}
+}
+
+func TestAdd() {
+	mc := _Copy(m1)
+	_Add(mc, mc)
+	if !_Equal(mc, m1) {
+		panic(fmt.Sprintf("_Add(%v, %v) = %v, want %v", m1, m1, mc, m1))
+	}
+	_Add(mc, map[int]int{16: 32})
+	want := map[int]int{1: 2, 2: 4, 4: 8, 8: 16, 16: 32}
+	if !_Equal(mc, want) {
+		panic(fmt.Sprintf("_Add result = %v, want %v", mc, want))
+	}
+}
+
+func TestSub() {
+	mc := _Copy(m1)
+	_Sub(mc, mc)
+	if len(mc) > 0 {
+		panic(fmt.Sprintf("_Sub(%v, %v) = %v, want empty map", m1, m1, mc))
+	}
+	mc = _Copy(m1)
+	_Sub(mc, map[int]int{1: 0})
+	want := map[int]int{2: 4, 4: 8, 8: 16}
+	if !_Equal(mc, want) {
+		panic(fmt.Sprintf("_Sub result = %v, want %v", mc, want))
+	}
+}
+
+func TestIntersect() {
+	mc := _Copy(m1)
+	_Intersect(mc, mc)
+	if !_Equal(mc, m1) {
+		panic(fmt.Sprintf("_Intersect(%v, %v) = %v, want %v", m1, m1, mc, m1))
+	}
+	_Intersect(mc, map[int]int{1: 0, 2: 0})
+	want := map[int]int{1: 2, 2: 4}
+	if !_Equal(mc, want) {
+		panic(fmt.Sprintf("_Intersect result = %v, want %v", mc, want))
+	}
+}
+
+func TestFilter() {
+	mc := _Copy(m1)
+	_Filter(mc, func(int, int) bool { return true })
+	if !_Equal(mc, m1) {
+		panic(fmt.Sprintf("_Filter(%v, true) = %v, want %v", m1, mc, m1))
+	}
+	_Filter(mc, func(k, v int) bool { return k < 3 })
+	want := map[int]int{1: 2, 2: 4}
+	if !_Equal(mc, want) {
+		panic(fmt.Sprintf("_Filter result = %v, want %v", mc, want))
+	}
+}
+
+func TestTransformValues() {
+	mc := _Copy(m1)
+	_TransformValues(mc, func(i int) int { return i / 2 })
+	want := map[int]int{1: 1, 2: 2, 4: 4, 8: 8}
+	if !_Equal(mc, want) {
+		panic(fmt.Sprintf("_TransformValues result = %v, want %v", mc, want))
+	}
+}
+
+func main() {
+	TestKeys()
+	TestValues()
+	TestEqual()
+	TestCopy()
+	TestAdd()
+	TestSub()
+	TestIntersect()
+	TestFilter()
+	TestTransformValues()
+}
diff --git a/test/typeparam/metrics.go b/test/typeparam/metrics.go
new file mode 100644
index 0000000..8a39d99
--- /dev/null
+++ b/test/typeparam/metrics.go
@@ -0,0 +1,196 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package metrics provides tracking arbitrary metrics composed of
+// values of comparable types.
+package main
+
+import (
+	"fmt"
+	"sort"
+	"sync"
+)
+
+// _Metric1 tracks metrics of values of some type.
+type _Metric1[T comparable] struct {
+	mu sync.Mutex
+	m  map[T]int
+}
+
+// Add adds another instance of some value.
+func (m *_Metric1[T]) Add(v T) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	if m.m == nil {
+		m.m = make(map[T]int)
+	}
+	m.m[v]++
+}
+
+// Count returns the number of instances we've seen of v.
+func (m *_Metric1[T]) Count(v T) int {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	return m.m[v]
+}
+
+// Metrics returns all the values we've seen, in an indeterminate order.
+func (m *_Metric1[T]) Metrics() []T {
+	return _Keys(m.m)
+}
+
+type key2[T1, T2 comparable] struct {
+	f1 T1
+	f2 T2
+}
+
+// _Metric2 tracks metrics of pairs of values.
+type _Metric2[T1, T2 comparable] struct {
+	mu sync.Mutex
+	m  map[key2[T1, T2]]int
+}
+
+// Add adds another instance of some pair of values.
+func (m *_Metric2[T1, T2]) Add(v1 T1, v2 T2) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	if m.m == nil {
+		m.m = make(map[key2[T1, T2]]int)
+	}
+	m.m[key2[T1, T2]{v1, v2}]++
+}
+
+// Count returns the number of instances we've seen of v1/v2.
+func (m *_Metric2[T1, T2]) Count(v1 T1, v2 T2) int {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	return m.m[key2[T1, T2]{v1, v2}]
+}
+
+// Metrics returns all the values we've seen, in an indeterminate order.
+func (m *_Metric2[T1, T2]) Metrics() (r1 []T1, r2 []T2) {
+	for _, k := range _Keys(m.m) {
+		r1 = append(r1, k.f1)
+		r2 = append(r2, k.f2)
+	}
+	return r1, r2
+}
+
+type key3[T1, T2, T3 comparable] struct {
+	f1 T1
+	f2 T2
+	f3 T3
+}
+
+// _Metric3 tracks metrics of triplets of values.
+type _Metric3[T1, T2, T3 comparable] struct {
+	mu sync.Mutex
+	m  map[key3[T1, T2, T3]]int
+}
+
+// Add adds another instance of some triplet of values.
+func (m *_Metric3[T1, T2, T3]) Add(v1 T1, v2 T2, v3 T3) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	if m.m == nil {
+		m.m = make(map[key3[T1, T2, T3]]int)
+	}
+	m.m[key3[T1, T2, T3]{v1, v2, v3}]++
+}
+
+// Count returns the number of instances we've seen of v1/v2/v3.
+func (m *_Metric3[T1, T2, T3]) Count(v1 T1, v2 T2, v3 T3) int {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	return m.m[key3[T1, T2, T3]{v1, v2, v3}]
+}
+
+// Metrics returns all the values we've seen, in an indeterminate order.
+func (m *_Metric3[T1, T2, T3]) Metrics() (r1 []T1, r2 []T2, r3 []T3) {
+	for k := range m.m {
+		r1 = append(r1, k.f1)
+		r2 = append(r2, k.f2)
+		r3 = append(r3, k.f3)
+	}
+	return r1, r2, r3
+}
+
+type S struct{ a, b, c string }
+
+func TestMetrics() {
+	m1 := _Metric1[string]{}
+	if got := m1.Count("a"); got != 0 {
+		panic(fmt.Sprintf("Count(%q) = %d, want 0", "a", got))
+	}
+	m1.Add("a")
+	m1.Add("a")
+	if got := m1.Count("a"); got != 2 {
+		panic(fmt.Sprintf("Count(%q) = %d, want 2", "a", got))
+	}
+	if got, want := m1.Metrics(), []string{"a"}; !_SlicesEqual(got, want) {
+		panic(fmt.Sprintf("Metrics = %v, want %v", got, want))
+	}
+
+	m2 := _Metric2[int, float64]{}
+	m2.Add(1, 1)
+	m2.Add(2, 2)
+	m2.Add(3, 3)
+	m2.Add(3, 3)
+	k1, k2 := m2.Metrics()
+
+	sort.Ints(k1)
+	w1 := []int{1, 2, 3}
+	if !_SlicesEqual(k1, w1) {
+		panic(fmt.Sprintf("_Metric2.Metrics first slice = %v, want %v", k1, w1))
+	}
+
+	sort.Float64s(k2)
+	w2 := []float64{1, 2, 3}
+	if !_SlicesEqual(k2, w2) {
+		panic(fmt.Sprintf("_Metric2.Metrics first slice = %v, want %v", k2, w2))
+	}
+
+	m3 := _Metric3[string, S, S]{}
+	m3.Add("a", S{"d", "e", "f"}, S{"g", "h", "i"})
+	m3.Add("a", S{"d", "e", "f"}, S{"g", "h", "i"})
+	m3.Add("a", S{"d", "e", "f"}, S{"g", "h", "i"})
+	m3.Add("b", S{"d", "e", "f"}, S{"g", "h", "i"})
+	if got := m3.Count("a", S{"d", "e", "f"}, S{"g", "h", "i"}); got != 3 {
+		panic(fmt.Sprintf("Count(%v, %v, %v) = %d, want 3", "a", S{"d", "e", "f"}, S{"g", "h", "i"}, got))
+	}
+}
+
+func main() {
+	TestMetrics()
+}
+
+// _Equal reports whether two slices are equal: the same length and all
+// elements equal. All floating point NaNs are considered equal.
+func _SlicesEqual[Elem comparable](s1, s2 []Elem) bool {
+	if len(s1) != len(s2) {
+		return false
+	}
+	for i, v1 := range s1 {
+		v2 := s2[i]
+		if v1 != v2 {
+			isNaN := func(f Elem) bool { return f != f }
+			if !isNaN(v1) || !isNaN(v2) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// _Keys returns the keys of the map m.
+// The keys will be an indeterminate order.
+func _Keys[K comparable, V any](m map[K]V) []K {
+	r := make([]K, 0, len(m))
+	for k := range m {
+		r = append(r, k)
+	}
+	return r
+}
diff --git a/test/typeparam/min.go b/test/typeparam/min.go
new file mode 100644
index 0000000..a3e4464
--- /dev/null
+++ b/test/typeparam/min.go
@@ -0,0 +1,41 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+type Ordered interface {
+	type int, int64, float64
+}
+
+func min[T Ordered](x, y T) T {
+	if x < y {
+		return x
+	}
+	return y
+}
+
+func main() {
+	const want = 2
+	if got := min[int](2, 3); got != want {
+		panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+
+	if got := min(2, 3); got != want {
+		panic(fmt.Sprintf("want %d, got %d", want, got))
+	}
+
+	if got := min[float64](3.5, 2.0); got != want {
+		panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+
+	if got := min(3.5, 2.0); got != want {
+		panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+}
diff --git a/test/typeparam/ordered.go b/test/typeparam/ordered.go
new file mode 100644
index 0000000..448db68
--- /dev/null
+++ b/test/typeparam/ordered.go
@@ -0,0 +1,95 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"math"
+	"sort"
+)
+
+type Ordered interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64,
+		string
+}
+
+type orderedSlice[Elem Ordered] []Elem
+
+func (s orderedSlice[Elem]) Len() int           { return len(s) }
+func (s orderedSlice[Elem]) Less(i, j int) bool {
+	if s[i] < s[j] {
+		return true
+	}
+	isNaN := func(f Elem) bool { return f != f }
+	if isNaN(s[i]) && !isNaN(s[j]) {
+		return true
+	}
+	return false
+}
+func (s orderedSlice[Elem]) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+
+func _OrderedSlice[Elem Ordered](s []Elem) {
+	sort.Sort(orderedSlice[Elem](s))
+}
+
+var ints = []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
+var float64s = []float64{74.3, 59.0, math.Inf(1), 238.2, -784.0, 2.3, math.NaN(), math.NaN(), math.Inf(-1), 9845.768, -959.7485, 905, 7.8, 7.8}
+var strings = []string{"", "Hello", "foo", "bar", "foo", "f00", "%*&^*&^&", "***"}
+
+func TestSortOrderedInts() bool {
+	return testOrdered("ints", ints, sort.Ints)
+}
+
+func TestSortOrderedFloat64s() bool {
+	return testOrdered("float64s", float64s, sort.Float64s)
+}
+
+func TestSortOrderedStrings() bool {
+	return testOrdered("strings", strings, sort.Strings)
+}
+
+func testOrdered[Elem Ordered](name string, s []Elem, sorter func([]Elem)) bool {
+	s1 := make([]Elem, len(s))
+	copy(s1, s)
+	s2 := make([]Elem, len(s))
+	copy(s2, s)
+	_OrderedSlice(s1)
+	sorter(s2)
+	ok := true
+	if !sliceEq(s1, s2) {
+		fmt.Printf("%s: got %v, want %v", name, s1, s2)
+		ok = false
+	}
+	for i := len(s1) - 1; i > 0; i-- {
+		if s1[i] < s1[i-1] {
+			fmt.Printf("%s: element %d (%v) < element %d (%v)", name, i, s1[i], i - 1, s1[i - 1])
+			ok = false
+		}
+	}
+	return ok
+}
+
+func sliceEq[Elem Ordered](s1, s2 []Elem) bool {
+	for i, v1 := range s1 {
+		v2 := s2[i]
+		if v1 != v2 {
+			isNaN := func(f Elem) bool { return f != f }
+			if !isNaN(v1) || !isNaN(v2) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+func main() {
+	if !TestSortOrderedInts() || !TestSortOrderedFloat64s() || !TestSortOrderedStrings() {
+		panic("failure")
+	}
+}
diff --git a/test/typeparam/orderedmap.go b/test/typeparam/orderedmap.go
new file mode 100644
index 0000000..db1b374
--- /dev/null
+++ b/test/typeparam/orderedmap.go
@@ -0,0 +1,286 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package orderedmap provides an ordered map, implemented as a binary tree.
+package main
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"runtime"
+)
+
+type Ordered interface {
+        type int, int8, int16, int32, int64,
+                uint, uint8, uint16, uint32, uint64, uintptr,
+                float32, float64,
+                string
+}
+
+// _Map is an ordered map.
+type _Map[K, V any] struct {
+	root    *node[K, V]
+	compare func(K, K) int
+}
+
+// node is the type of a node in the binary tree.
+type node[K, V any] struct {
+	key         K
+	val         V
+	left, right *node[K, V]
+}
+
+// _New returns a new map. It takes a comparison function that compares two
+// keys and returns < 0 if the first is less, == 0 if they are equal,
+// > 0 if the first is greater.
+func _New[K, V any](compare func(K, K) int) *_Map[K, V] {
+	return &_Map[K, V]{compare: compare}
+}
+
+// _NewOrdered returns a new map whose key is an ordered type.
+// This is like _New, but does not require providing a compare function.
+// The map compare function uses the obvious key ordering.
+func _NewOrdered[K Ordered, V any]() *_Map[K, V] {
+	return _New[K, V](func(k1, k2 K) int {
+		switch {
+		case k1 < k2:
+			return -1
+		case k1 == k2:
+			return 0
+		default:
+			return 1
+		}
+	})
+}
+
+// find looks up key in the map, returning either a pointer to the slot of the
+// node holding key, or a pointer to the slot where should a node would go.
+func (m *_Map[K, V]) find(key K) **node[K, V] {
+	pn := &m.root
+	for *pn != nil {
+		switch cmp := m.compare(key, (*pn).key); {
+		case cmp < 0:
+			pn = &(*pn).left
+		case cmp > 0:
+			pn = &(*pn).right
+		default:
+			return pn
+		}
+	}
+	return pn
+}
+
+// Insert inserts a new key/value into the map.
+// If the key is already present, the value is replaced.
+// Reports whether this is a new key.
+func (m *_Map[K, V]) Insert(key K, val V) bool {
+	pn := m.find(key)
+	if *pn != nil {
+		(*pn).val = val
+		return false
+	}
+	*pn = &node[K, V]{key: key, val: val}
+	return true
+}
+
+// Find returns the value associated with a key, or the zero value
+// if not present. The found result reports whether the key was found.
+func (m *_Map[K, V]) Find(key K) (V, bool) {
+	pn := m.find(key)
+	if *pn == nil {
+		var zero V
+		return zero, false
+	}
+	return (*pn).val, true
+}
+
+// keyValue is a pair of key and value used while iterating.
+type keyValue[K, V any] struct {
+	key K
+	val V
+}
+
+// iterate returns an iterator that traverses the map.
+func (m *_Map[K, V]) Iterate() *_Iterator[K, V] {
+	sender, receiver := _Ranger[keyValue[K, V]]()
+	var f func(*node[K, V]) bool
+	f = func(n *node[K, V]) bool {
+		if n == nil {
+			return true
+		}
+		// Stop the traversal if Send fails, which means that
+		// nothing is listening to the receiver.
+		return f(n.left) &&
+			sender.Send(context.Background(), keyValue[K, V]{n.key, n.val}) &&
+			f(n.right)
+	}
+	go func() {
+		f(m.root)
+		sender.Close()
+	}()
+	return &_Iterator[K, V]{receiver}
+}
+
+// _Iterator is used to iterate over the map.
+type _Iterator[K, V any] struct {
+	r *_Receiver[keyValue[K, V]]
+}
+
+// Next returns the next key and value pair, and a boolean that reports
+// whether they are valid. If not valid, we have reached the end of the map.
+func (it *_Iterator[K, V]) Next() (K, V, bool) {
+	keyval, ok := it.r.Next(context.Background())
+	if !ok {
+		var zerok K
+		var zerov V
+		return zerok, zerov, false
+	}
+	return keyval.key, keyval.val, true
+}
+
+func TestMap() {
+	m := _New[[]byte, int](bytes.Compare)
+
+	if _, found := m.Find([]byte("a")); found {
+		panic(fmt.Sprintf("unexpectedly found %q in empty map", []byte("a")))
+	}
+	if !m.Insert([]byte("a"), 'a') {
+		panic(fmt.Sprintf("key %q unexpectedly already present", []byte("a")))
+	}
+	if !m.Insert([]byte("c"), 'c') {
+		panic(fmt.Sprintf("key %q unexpectedly already present", []byte("c")))
+	}
+	if !m.Insert([]byte("b"), 'b') {
+		panic(fmt.Sprintf("key %q unexpectedly already present", []byte("b")))
+	}
+	if m.Insert([]byte("c"), 'x') {
+		panic(fmt.Sprintf("key %q unexpectedly not present", []byte("c")))
+	}
+
+	if v, found := m.Find([]byte("a")); !found {
+		panic(fmt.Sprintf("did not find %q", []byte("a")))
+	} else if v != 'a' {
+		panic(fmt.Sprintf("key %q returned wrong value %c, expected %c", []byte("a"), v, 'a'))
+	}
+	if v, found := m.Find([]byte("c")); !found {
+		panic(fmt.Sprintf("did not find %q", []byte("c")))
+	} else if v != 'x' {
+		panic(fmt.Sprintf("key %q returned wrong value %c, expected %c", []byte("c"), v, 'x'))
+	}
+
+	if _, found := m.Find([]byte("d")); found {
+		panic(fmt.Sprintf("unexpectedly found %q", []byte("d")))
+	}
+
+	gather := func(it *_Iterator[[]byte, int]) []int {
+		var r []int
+		for {
+			_, v, ok := it.Next()
+			if !ok {
+				return r
+			}
+			r = append(r, v)
+		}
+	}
+	got := gather(m.Iterate())
+	want := []int{'a', 'b', 'x'}
+	if !_SliceEqual(got, want) {
+		panic(fmt.Sprintf("Iterate returned %v, want %v", got, want))
+	}
+}
+
+func main() {
+	TestMap()
+}
+
+// _Equal reports whether two slices are equal: the same length and all
+// elements equal. All floating point NaNs are considered equal.
+func _SliceEqual[Elem comparable](s1, s2 []Elem) bool {
+	if len(s1) != len(s2) {
+		return false
+	}
+	for i, v1 := range s1 {
+		v2 := s2[i]
+		if v1 != v2 {
+			isNaN := func(f Elem) bool { return f != f }
+			if !isNaN(v1) || !isNaN(v2) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// Ranger returns a Sender and a Receiver. The Receiver provides a
+// Next method to retrieve values. The Sender provides a Send method
+// to send values and a Close method to stop sending values. The Next
+// method indicates when the Sender has been closed, and the Send
+// method indicates when the Receiver has been freed.
+//
+// This is a convenient way to exit a goroutine sending values when
+// the receiver stops reading them.
+func _Ranger[Elem any]() (*_Sender[Elem], *_Receiver[Elem]) {
+	c := make(chan Elem)
+	d := make(chan struct{})
+	s := &_Sender[Elem]{
+		values: c,
+		done:   d,
+	}
+	r := &_Receiver[Elem] {
+		values: c,
+		done:   d,
+	}
+	runtime.SetFinalizer(r, (*_Receiver[Elem]).finalize)
+	return s, r
+}
+
+// A _Sender is used to send values to a Receiver.
+type _Sender[Elem any] struct {
+	values chan<- Elem
+	done   <-chan struct{}
+}
+
+// Send sends a value to the receiver. It reports whether the value was sent.
+// The value will not be sent if the context is closed or the receiver
+// is freed.
+func (s *_Sender[Elem]) Send(ctx context.Context, v Elem) bool {
+	select {
+	case <-ctx.Done():
+		return false
+	case s.values <- v:
+		return true
+	case <-s.done:
+		return false
+	}
+}
+
+// Close tells the receiver that no more values will arrive.
+// After Close is called, the _Sender may no longer be used.
+func (s *_Sender[Elem]) Close() {
+	close(s.values)
+}
+
+// A _Receiver receives values from a _Sender.
+type _Receiver[Elem any] struct {
+	values <-chan Elem
+	done   chan<- struct{}
+}
+
+// Next returns the next value from the channel. The bool result indicates
+// whether the value is valid.
+func (r *_Receiver[Elem]) Next(ctx context.Context) (v Elem, ok bool) {
+	select {
+	case <-ctx.Done():
+	case v, ok = <-r.values:
+	}
+	return v, ok
+}
+
+// finalize is a finalizer for the receiver.
+func (r *_Receiver[Elem]) finalize() {
+	close(r.done)
+}
diff --git a/test/typeparam/pair.go b/test/typeparam/pair.go
new file mode 100644
index 0000000..7faf083
--- /dev/null
+++ b/test/typeparam/pair.go
@@ -0,0 +1,32 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"unsafe"
+)
+
+type pair[F1, F2 any] struct {
+	f1 F1
+	f2 F2
+}
+
+func main() {
+	p := pair[int32, int64]{1, 2}
+	if got, want := unsafe.Sizeof(p.f1), uintptr(4); got != want {
+		panic(fmt.Sprintf("unexpected f1 size == %d, want %d", got, want))
+	}
+	if got, want := unsafe.Sizeof(p.f2), uintptr(8); got != want {
+		panic(fmt.Sprintf("unexpected f2 size == %d, want %d", got, want))
+	}
+	type mypair struct { f1 int32; f2 int64 }
+	mp := mypair(p)
+	if mp.f1 != 1 || mp.f2 != 2 {
+		panic(fmt.Sprintf("mp == %#v, want %#v", mp, mypair{1, 2}))
+	}
+}
diff --git a/test/typeparam/pragma.go b/test/typeparam/pragma.go
new file mode 100644
index 0000000..6743e24
--- /dev/null
+++ b/test/typeparam/pragma.go
@@ -0,0 +1,19 @@
+// errorcheck -0 -m -G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure the go:noinline pragma makes it from a
+// generic function to any of its stenciled instances.
+
+package main
+
+//go:noinline
+func f[T any](x T) T {
+	return x
+}
+
+func main() { // ERROR "can inline main"
+	println(f(5))
+}
diff --git a/test/typeparam/sets.go b/test/typeparam/sets.go
new file mode 100644
index 0000000..2585144
--- /dev/null
+++ b/test/typeparam/sets.go
@@ -0,0 +1,280 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"sort"
+)
+
+// _Equal reports whether two slices are equal: the same length and all
+// elements equal. All floating point NaNs are considered equal.
+func _SliceEqual[Elem comparable](s1, s2 []Elem) bool {
+	if len(s1) != len(s2) {
+		return false
+	}
+	for i, v1 := range s1 {
+		v2 := s2[i]
+		if v1 != v2 {
+			isNaN := func(f Elem) bool { return f != f }
+			if !isNaN(v1) || !isNaN(v2) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// A _Set is a set of elements of some type.
+type _Set[Elem comparable] struct {
+	m map[Elem]struct{}
+}
+
+// _Make makes a new set.
+func _Make[Elem comparable]() _Set[Elem] {
+	return _Set[Elem]{m: make(map[Elem]struct{})}
+}
+
+// Add adds an element to a set.
+func (s _Set[Elem]) Add(v Elem) {
+	s.m[v] = struct{}{}
+}
+
+// Delete removes an element from a set. If the element is not present
+// in the set, this does nothing.
+func (s _Set[Elem]) Delete(v Elem) {
+	delete(s.m, v)
+}
+
+// Contains reports whether v is in the set.
+func (s _Set[Elem]) Contains(v Elem) bool {
+	_, ok := s.m[v]
+	return ok
+}
+
+// Len returns the number of elements in the set.
+func (s _Set[Elem]) Len() int {
+	return len(s.m)
+}
+
+// Values returns the values in the set.
+// The values will be in an indeterminate order.
+func (s _Set[Elem]) Values() []Elem {
+	r := make([]Elem, 0, len(s.m))
+	for v := range s.m {
+		r = append(r, v)
+	}
+	return r
+}
+
+// _Equal reports whether two sets contain the same elements.
+func _Equal[Elem comparable](s1, s2 _Set[Elem]) bool {
+	if len(s1.m) != len(s2.m) {
+		return false
+	}
+	for v1 := range s1.m {
+		if !s2.Contains(v1) {
+			return false
+		}
+	}
+	return true
+}
+
+// Copy returns a copy of s.
+func (s _Set[Elem]) Copy() _Set[Elem] {
+	r := _Set[Elem]{m: make(map[Elem]struct{}, len(s.m))}
+	for v := range s.m {
+		r.m[v] = struct{}{}
+	}
+	return r
+}
+
+// AddSet adds all the elements of s2 to s.
+func (s _Set[Elem]) AddSet(s2 _Set[Elem]) {
+	for v := range s2.m {
+		s.m[v] = struct{}{}
+	}
+}
+
+// SubSet removes all elements in s2 from s.
+// Values in s2 that are not in s are ignored.
+func (s _Set[Elem]) SubSet(s2 _Set[Elem]) {
+	for v := range s2.m {
+		delete(s.m, v)
+	}
+}
+
+// Intersect removes all elements from s that are not present in s2.
+// Values in s2 that are not in s are ignored.
+func (s _Set[Elem]) Intersect(s2 _Set[Elem]) {
+	for v := range s.m {
+		if !s2.Contains(v) {
+			delete(s.m, v)
+		}
+	}
+}
+
+// Iterate calls f on every element in the set.
+func (s _Set[Elem]) Iterate(f func(Elem)) {
+	for v := range s.m {
+		f(v)
+	}
+}
+
+// Filter deletes any elements from s for which f returns false.
+func (s _Set[Elem]) Filter(f func(Elem) bool) {
+	for v := range s.m {
+		if !f(v) {
+			delete(s.m, v)
+		}
+	}
+}
+
+func TestSet() {
+	s1 := _Make[int]()
+	if got := s1.Len(); got != 0 {
+		panic(fmt.Sprintf("Len of empty set = %d, want 0", got))
+	}
+	s1.Add(1)
+	s1.Add(1)
+	s1.Add(1)
+	if got := s1.Len(); got != 1 {
+		panic(fmt.Sprintf("(%v).Len() == %d, want 1", s1, got))
+	}
+	s1.Add(2)
+	s1.Add(3)
+	s1.Add(4)
+	if got := s1.Len(); got != 4 {
+		panic(fmt.Sprintf("(%v).Len() == %d, want 4", s1, got))
+	}
+	if !s1.Contains(1) {
+		panic(fmt.Sprintf("(%v).Contains(1) == false, want true", s1))
+	}
+	if s1.Contains(5) {
+		panic(fmt.Sprintf("(%v).Contains(5) == true, want false", s1))
+	}
+	vals := s1.Values()
+	sort.Ints(vals)
+	w1 := []int{1, 2, 3, 4}
+	if !_SliceEqual(vals,  w1) {
+		panic(fmt.Sprintf("(%v).Values() == %v, want %v", s1, vals, w1))
+	}
+}
+
+func TestEqual() {
+	s1 := _Make[string]()
+	s2 := _Make[string]()
+	if !_Equal(s1, s2) {
+		panic(fmt.Sprintf("_Equal(%v, %v) = false, want true", s1, s2))
+	}
+	s1.Add("hello")
+	s1.Add("world")
+	if got := s1.Len(); got != 2 {
+		panic(fmt.Sprintf("(%v).Len() == %d, want 2", s1, got))
+	}
+	if _Equal(s1, s2) {
+		panic(fmt.Sprintf("_Equal(%v, %v) = true, want false", s1, s2))
+	}
+}
+
+func TestCopy() {
+	s1 := _Make[float64]()
+	s1.Add(0)
+	s2 := s1.Copy()
+	if !_Equal(s1, s2) {
+		panic(fmt.Sprintf("_Equal(%v, %v) = false, want true", s1, s2))
+	}
+	s1.Add(1)
+	if _Equal(s1, s2) {
+		panic(fmt.Sprintf("_Equal(%v, %v) = true, want false", s1, s2))
+	}
+}
+
+func TestAddSet() {
+	s1 := _Make[int]()
+	s1.Add(1)
+	s1.Add(2)
+	s2 := _Make[int]()
+	s2.Add(2)
+	s2.Add(3)
+	s1.AddSet(s2)
+	if got := s1.Len(); got != 3 {
+		panic(fmt.Sprintf("(%v).Len() == %d, want 3", s1, got))
+	}
+	s2.Add(1)
+	if !_Equal(s1, s2) {
+		panic(fmt.Sprintf("_Equal(%v, %v) = false, want true", s1, s2))
+	}
+}
+
+func TestSubSet() {
+	s1 := _Make[int]()
+	s1.Add(1)
+	s1.Add(2)
+	s2 := _Make[int]()
+	s2.Add(2)
+	s2.Add(3)
+	s1.SubSet(s2)
+	if got := s1.Len(); got != 1 {
+		panic(fmt.Sprintf("(%v).Len() == %d, want 1", s1, got))
+	}
+	if vals, want := s1.Values(), []int{1}; !_SliceEqual(vals, want) {
+		panic(fmt.Sprintf("after SubSet got %v, want %v", vals, want))
+	}
+}
+
+func TestIntersect() {
+	s1 := _Make[int]()
+	s1.Add(1)
+	s1.Add(2)
+	s2 := _Make[int]()
+	s2.Add(2)
+	s2.Add(3)
+	s1.Intersect(s2)
+	if got := s1.Len(); got != 1 {
+		panic(fmt.Sprintf("(%v).Len() == %d, want 1", s1, got))
+	}
+	if vals, want := s1.Values(), []int{2}; !_SliceEqual(vals, want) {
+		panic(fmt.Sprintf("after Intersect got %v, want %v", vals, want))
+	}
+}
+
+func TestIterate() {
+	s1 := _Make[int]()
+	s1.Add(1)
+	s1.Add(2)
+	s1.Add(3)
+	s1.Add(4)
+	tot := 0
+	s1.Iterate(func(i int) { tot += i })
+	if tot != 10 {
+		panic(fmt.Sprintf("total of %v == %d, want 10", s1, tot))
+	}
+}
+
+func TestFilter() {
+	s1 := _Make[int]()
+	s1.Add(1)
+	s1.Add(2)
+	s1.Add(3)
+	s1.Filter(func(v int) bool { return v%2 == 0 })
+	if vals, want := s1.Values(), []int{2}; !_SliceEqual(vals, want) {
+		panic(fmt.Sprintf("after Filter got %v, want %v", vals, want))
+	}
+
+}
+
+func main() {
+	TestSet()
+	TestEqual()
+	TestCopy()
+	TestAddSet()
+	TestSubSet()
+	TestIntersect()
+	TestIterate()
+	TestFilter()
+}
diff --git a/test/typeparam/settable.go b/test/typeparam/settable.go
new file mode 100644
index 0000000..588166d
--- /dev/null
+++ b/test/typeparam/settable.go
@@ -0,0 +1,124 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"strconv"
+)
+
+// Various implementations of fromStrings().
+
+type _Setter[B any] interface {
+	Set(string)
+	type *B
+}
+
+// Takes two type parameters where PT = *T
+func fromStrings1[T any, PT _Setter[T]](s []string) []T {
+	result := make([]T, len(s))
+	for i, v := range s {
+		// The type of &result[i] is *T which is in the type list
+		// of Setter, so we can convert it to PT.
+		p := PT(&result[i])
+		// PT has a Set method.
+		p.Set(v)
+	}
+	return result
+}
+
+func fromStrings1a[T any, PT _Setter[T]](s []string) []PT {
+	result := make([]PT, len(s))
+	for i, v := range s {
+		// The type new(T) is *T which is in the type list
+		// of Setter, so we can convert it to PT.
+		result[i] = PT(new(T))
+		p := result[i]
+		// PT has a Set method.
+		p.Set(v)
+	}
+	return result
+}
+
+
+// Takes one type parameter and a set function
+func fromStrings2[T any](s []string, set func(*T, string)) []T {
+	results := make([]T, len(s))
+	for i, v := range s {
+		set(&results[i], v)
+	}
+	return results
+}
+
+type _Setter2 interface {
+	Set(string)
+}
+
+// Takes only one type parameter, but causes a panic (see below)
+func fromStrings3[T _Setter2](s []string) []T {
+	results := make([]T, len(s))
+	for i, v := range s {
+		// Panics if T is a pointer type because receiver is T(nil).
+		results[i].Set(v)
+	}
+	return results
+}
+
+// Two concrete types with the appropriate Set method.
+
+type SettableInt int
+
+func (p *SettableInt) Set(s string) {
+	i, err := strconv.Atoi(s)
+	if err != nil {
+		panic(err)
+	}
+	*p = SettableInt(i)
+}
+
+type SettableString struct {
+	s string
+}
+
+func (x *SettableString) Set(s string) {
+	x.s = s
+}
+
+func main() {
+	s := fromStrings1[SettableInt, *SettableInt]([]string{"1"})
+	if len(s) != 1 || s[0] != 1 {
+		panic(fmt.Sprintf("got %v, want %v", s, []int{1}))
+	}
+
+	s2 := fromStrings1a[SettableInt, *SettableInt]([]string{"1"})
+	if len(s2) != 1 || *s2[0] != 1 {
+		x := 1
+		panic(fmt.Sprintf("got %v, want %v", s2, []*int{&x}))
+	}
+
+	// Test out constraint type inference, which should determine that the second
+	// type param is *SettableString.
+	ps := fromStrings1[SettableString]([]string{"x", "y"})
+	if len(ps) != 2 || ps[0] != (SettableString{"x"}) || ps[1] != (SettableString{"y"}) {
+		panic(s)
+	}
+
+	s = fromStrings2([]string{"1"}, func(p *SettableInt, s string) { p.Set(s) })
+	if len(s) != 1 || s[0] != 1 {
+		panic(fmt.Sprintf("got %v, want %v", s, []int{1}))
+	}
+
+	defer func() {
+		if recover() == nil {
+			panic("did not panic as expected")
+		}
+	}()
+	// This should type check but should panic at run time,
+	// because it will make a slice of *SettableInt and then call
+	// Set on a nil value.
+	fromStrings3[*SettableInt]([]string{"1"})
+}
diff --git a/test/typeparam/slices.go b/test/typeparam/slices.go
new file mode 100644
index 0000000..149199e
--- /dev/null
+++ b/test/typeparam/slices.go
@@ -0,0 +1,318 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package slices provides functions for basic operations on
+// slices of any element type.
+package main
+
+import (
+	"fmt"
+	"math"
+	"strings"
+)
+
+type Ordered interface {
+        type int, int8, int16, int32, int64,
+                uint, uint8, uint16, uint32, uint64, uintptr,
+                float32, float64,
+                string
+}
+
+type Integer interface {
+        type int, int8, int16, int32, int64,
+                uint, uint8, uint16, uint32, uint64, uintptr
+}
+
+// Max returns the maximum of two values of some ordered type.
+func _Max[T Ordered](a, b T) T {
+        if a > b {
+                return a
+        }
+        return b
+}
+
+// Min returns the minimum of two values of some ordered type.
+func _Min[T Ordered](a, b T) T {
+        if a < b {
+                return a
+        }
+        return b
+}
+
+// _Equal reports whether two slices are equal: the same length and all
+// elements equal. All floating point NaNs are considered equal.
+func _Equal[Elem comparable](s1, s2 []Elem) bool {
+	if len(s1) != len(s2) {
+		return false
+	}
+	for i, v1 := range s1 {
+		v2 := s2[i]
+		if v1 != v2 {
+			isNaN := func(f Elem) bool { return f != f }
+			if !isNaN(v1) || !isNaN(v2) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// _EqualFn reports whether two slices are equal using a comparision
+// function on each element.
+func _EqualFn[Elem any](s1, s2 []Elem, eq func(Elem, Elem) bool) bool {
+	if len(s1) != len(s2) {
+		return false
+	}
+	for i, v1 := range s1 {
+		v2 := s2[i]
+		if !eq(v1, v2) {
+			return false
+		}
+	}
+	return true
+}
+
+// _Map turns a []Elem1 to a []Elem2 using a mapping function.
+func _Map[Elem1, Elem2 any](s []Elem1, f func(Elem1) Elem2) []Elem2 {
+	r := make([]Elem2, len(s))
+	for i, v := range s {
+		r[i] = f(v)
+	}
+	return r
+}
+
+// _Reduce reduces a []Elem1 to a single value of type Elem2 using
+// a reduction function.
+func _Reduce[Elem1, Elem2 any](s []Elem1, initializer Elem2, f func(Elem2, Elem1) Elem2) Elem2 {
+	r := initializer
+	for _, v := range s {
+		r = f(r, v)
+	}
+	return r
+}
+
+// _Filter filters values from a slice using a filter function.
+func _Filter[Elem any](s []Elem, f func(Elem) bool) []Elem {
+	var r []Elem
+	for _, v := range s {
+		if f(v) {
+			r = append(r, v)
+		}
+	}
+	return r
+}
+
+// _Max returns the maximum element in a slice of some ordered type.
+// If the slice is empty it returns the zero value of the element type.
+func _SliceMax[Elem Ordered](s []Elem) Elem {
+	if len(s) == 0 {
+		var zero Elem
+		return zero
+	}
+	return _Reduce(s[1:], s[0], _Max[Elem])
+}
+
+// _Min returns the minimum element in a slice of some ordered type.
+// If the slice is empty it returns the zero value of the element type.
+func _SliceMin[Elem Ordered](s []Elem) Elem {
+	if len(s) == 0 {
+		var zero Elem
+		return zero
+	}
+	return _Reduce(s[1:], s[0], _Min[Elem])
+}
+
+// _Append adds values to the end of a slice, returning a new slice.
+// This is like the predeclared append function; it's an example
+// of how to write it using generics. We used to write code like
+// this before append was added to the language, but we had to write
+// a separate copy for each type.
+func _Append[T any](s []T, t ...T) []T {
+	lens := len(s)
+	tot := lens + len(t)
+	if tot <= cap(s) {
+		s = s[:tot]
+	} else {
+		news := make([]T, tot, tot + tot/2)
+		_Copy(news, s)
+		s = news
+	}
+	_Copy(s[lens:tot], t)
+	return s
+}
+
+// _Copy copies values from t to s, stopping when either slice is full,
+// returning the number of values copied. This is like the predeclared
+// copy function; it's an example of how to write it using generics.
+func _Copy[T any](s, t []T) int {
+	i := 0
+	for ; i < len(s) && i < len(t); i++ {
+		s[i] = t[i]
+	}
+	return i
+}
+
+func TestEqual() {
+        s1 := []int{1, 2, 3}
+        if !_Equal(s1, s1) {
+                panic(fmt.Sprintf("_Equal(%v, %v) = false, want true", s1, s1))
+        }
+        s2 := []int{1, 2, 3}
+        if !_Equal(s1, s2) {
+                panic(fmt.Sprintf("_Equal(%v, %v) = false, want true", s1, s2))
+        }
+        s2 = append(s2, 4)
+        if _Equal(s1, s2) {
+                panic(fmt.Sprintf("_Equal(%v, %v) = true, want false", s1, s2))
+        }
+
+        s3 := []float64{1, 2, math.NaN()}
+        if !_Equal(s3, s3) {
+                panic(fmt.Sprintf("_Equal(%v, %v) = false, want true", s3, s3))
+        }
+
+        if _Equal(s1, nil) {
+                panic(fmt.Sprintf("_Equal(%v, nil) = true, want false", s1))
+        }
+        if _Equal(nil, s1) {
+                panic(fmt.Sprintf("_Equal(nil, %v) = true, want false", s1))
+        }
+        if !_Equal(s1[:0], nil) {
+                panic(fmt.Sprintf("_Equal(%v, nil = false, want true", s1[:0]))
+        }
+}
+
+func offByOne[Elem Integer](a, b Elem) bool {
+	return a == b + 1 || a == b - 1
+}
+
+func TestEqualFn() {
+	s1 := []int{1, 2, 3}
+	s2 := []int{2, 3, 4}
+	if _EqualFn(s1, s1, offByOne[int]) {
+		panic(fmt.Sprintf("_EqualFn(%v, %v, offByOne) = true, want false", s1, s1))
+	}
+	if !_EqualFn(s1, s2, offByOne[int]) {
+		panic(fmt.Sprintf("_EqualFn(%v, %v, offByOne) = false, want true", s1, s2))
+	}
+
+	if !_EqualFn(s1[:0], nil, offByOne[int]) {
+		panic(fmt.Sprintf("_EqualFn(%v, nil, offByOne) = false, want true", s1[:0]))
+	}
+
+	s3 := []string{"a", "b", "c"}
+	s4 := []string{"A", "B", "C"}
+	if !_EqualFn(s3, s4, strings.EqualFold) {
+		panic(fmt.Sprintf("_EqualFn(%v, %v, strings.EqualFold) = false, want true", s3, s4))
+	}
+}
+
+func TestMap() {
+	s1 := []int{1, 2, 3}
+	s2 := _Map(s1, func(i int) float64 { return float64(i) * 2.5 })
+	if want := []float64{2.5, 5, 7.5}; !_Equal(s2, want) {
+		panic(fmt.Sprintf("_Map(%v, ...) = %v, want %v", s1, s2, want))
+	}
+
+	s3 := []string{"Hello", "World"}
+	s4 := _Map(s3, strings.ToLower)
+	if want := []string{"hello", "world"}; !_Equal(s4, want) {
+		panic(fmt.Sprintf("_Map(%v, strings.ToLower) = %v, want %v", s3, s4, want))
+	}
+
+	s5 := _Map(nil, func(i int) int { return i })
+	if len(s5) != 0 {
+		panic(fmt.Sprintf("_Map(nil, identity) = %v, want empty slice", s5))
+	}
+}
+
+func TestReduce() {
+	s1 := []int{1, 2, 3}
+	r := _Reduce(s1, 0, func(f float64, i int) float64 { return float64(i) * 2.5 + f })
+	if want := 15.0; r != want {
+		panic(fmt.Sprintf("_Reduce(%v, 0, ...) = %v, want %v", s1, r, want))
+	}
+
+	if got := _Reduce(nil, 0, func(i, j int) int { return i + j}); got != 0 {
+		panic(fmt.Sprintf("_Reduce(nil, 0, add) = %v, want 0", got))
+	}
+}
+
+func TestFilter() {
+	s1 := []int{1, 2, 3}
+	s2 := _Filter(s1, func(i int) bool { return i%2 == 0 })
+	if want := []int{2}; !_Equal(s2, want) {
+		panic(fmt.Sprintf("_Filter(%v, even) = %v, want %v", s1, s2, want))
+	}
+
+	if s3 := _Filter(s1[:0], func(i int) bool { return true }); len(s3) > 0 {
+		panic(fmt.Sprintf("_Filter(%v, identity) = %v, want empty slice", s1[:0], s3))
+	}
+}
+
+func TestMax() {
+	s1 := []int{1, 2, 3, -5}
+	if got, want := _SliceMax(s1), 3; got != want {
+		panic(fmt.Sprintf("_Max(%v) = %d, want %d", s1, got, want))
+	}
+
+	s2 := []string{"aaa", "a", "aa", "aaaa"}
+	if got, want := _SliceMax(s2), "aaaa"; got != want {
+		panic(fmt.Sprintf("_Max(%v) = %q, want %q", s2, got, want))
+	}
+
+	if got, want := _SliceMax(s2[:0]), ""; got != want {
+		panic(fmt.Sprintf("_Max(%v) = %q, want %q", s2[:0], got, want))
+	}
+}
+
+func TestMin() {
+	s1 := []int{1, 2, 3, -5}
+	if got, want := _SliceMin(s1), -5; got != want {
+		panic(fmt.Sprintf("_Min(%v) = %d, want %d", s1, got, want))
+	}
+
+	s2 := []string{"aaa", "a", "aa", "aaaa"}
+	if got, want := _SliceMin(s2), "a"; got != want {
+		panic(fmt.Sprintf("_Min(%v) = %q, want %q", s2, got, want))
+	}
+
+	if got, want := _SliceMin(s2[:0]), ""; got != want {
+		panic(fmt.Sprintf("_Min(%v) = %q, want %q", s2[:0], got, want))
+	}
+}
+
+func TestAppend() {
+	s := []int{1, 2, 3}
+	s = _Append(s, 4, 5, 6)
+	want := []int{1, 2, 3, 4, 5, 6}
+	if !_Equal(s, want) {
+		panic(fmt.Sprintf("after _Append got %v, want %v", s, want))
+	}
+}
+
+func TestCopy() {
+	s1 := []int{1, 2, 3}
+	s2 := []int{4, 5}
+	if got := _Copy(s1, s2); got != 2 {
+		panic(fmt.Sprintf("_Copy returned %d, want 2", got))
+	}
+	want := []int{4, 5, 3}
+	if !_Equal(s1, want) {
+		panic(fmt.Sprintf("after _Copy got %v, want %v", s1, want))
+	}
+}
+func main() {
+	TestEqual()
+	TestEqualFn()
+	TestMap()
+	TestReduce()
+	TestFilter()
+	TestMax()
+	TestMin()
+	TestAppend()
+	TestCopy()
+}
diff --git a/test/typeparam/smallest.go b/test/typeparam/smallest.go
new file mode 100644
index 0000000..63dd9dd
--- /dev/null
+++ b/test/typeparam/smallest.go
@@ -0,0 +1,42 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+type Ordered interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64,
+		string
+}
+
+func smallest[T Ordered](s []T) T {
+	r := s[0] // panics if slice is empty
+	for _, v := range s[1:] {
+		if v < r {
+			r = v
+		}
+	}
+	return r
+}
+
+func main() {
+	vec1 := []float64{5.3, 1.2, 32.8}
+	vec2 := []string{"abc", "def", "aaa"}
+
+	want1 := 1.2
+	if got := smallest(vec1); got != want1 {
+		panic(fmt.Sprintf("got %d, want %d", got, want1))
+	}
+	want2 := "aaa"
+	if got := smallest(vec2); got != want2 {
+		panic(fmt.Sprintf("got %d, want %d", got, want2))
+	}
+}
diff --git a/test/typeparam/smoketest.go b/test/typeparam/smoketest.go
new file mode 100644
index 0000000..b7d6201
--- /dev/null
+++ b/test/typeparam/smoketest.go
@@ -0,0 +1,56 @@
+// compile -G
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file checks simple code using type parameters.
+
+package smoketest
+
+// type parameters for functions
+func f1[P any]()
+func f2[P1, P2 any, P3 any]()
+func f3[P interface{}](x P, y T1[int])
+
+// function instantiations
+var _ = f1[int]
+var _ = f2[int, string, struct{}]
+var _ = f3[bool]
+
+// type parameters for types
+type T1[P any] struct{}
+type T2[P1, P2 any, P3 any] struct{}
+type T3[P interface{}] interface{}
+
+// type instantiations
+type _ T1[int]
+type _ T2[int, string, struct{}]
+type _ T3[bool]
+
+// methods
+func (T1[P]) m1() {}
+func (T1[_]) m2() {}
+func (x T2[P1, P2, P3]) m() {}
+
+// type lists
+type _ interface {
+	m1()
+	m2()
+	type int, float32, string
+	m3()
+}
+
+// embedded instantiated types
+type _ struct {
+	f1, f2 int
+	T1[int]
+	T2[int, string, struct{}]
+	T3[bool]
+}
+
+type _ interface {
+	m1()
+	m2()
+	T3[bool]
+}
diff --git a/test/typeparam/stringable.go b/test/typeparam/stringable.go
new file mode 100644
index 0000000..9340a3b
--- /dev/null
+++ b/test/typeparam/stringable.go
@@ -0,0 +1,46 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+type Stringer interface {
+	String() string
+}
+
+// stringableList is a slice of some type, where the type
+// must have a String method.
+type stringableList[T Stringer] []T
+
+func (s stringableList[T]) String() string {
+	var sb strings.Builder
+	for i, v := range s {
+		if i > 0 {
+			sb.WriteString(", ")
+		}
+		sb.WriteString(v.String())
+	}
+	return sb.String()
+}
+
+type myint int
+
+func (a myint) String() string {
+	return strconv.Itoa(int(a))
+}
+
+func main() {
+	v := stringableList[myint]{ myint(1), myint(2) }
+
+	if got, want := v.String(), "1, 2"; got != want {
+                panic(fmt.Sprintf("got %s, want %s", got, want))
+	}
+}
diff --git a/test/typeparam/stringer.go b/test/typeparam/stringer.go
new file mode 100644
index 0000000..81290d5
--- /dev/null
+++ b/test/typeparam/stringer.go
@@ -0,0 +1,88 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test method calls on type parameters
+
+package main
+
+import (
+	"fmt"
+	"reflect"
+	"strconv"
+)
+
+// Simple constraint
+type Stringer interface {
+	String() string
+}
+
+func stringify[T Stringer](s []T) (ret []string) {
+	for _, v := range s {
+		ret = append(ret, v.String())
+	}
+	return ret
+}
+
+type myint int
+
+func (i myint) String() string {
+	return strconv.Itoa(int(i))
+}
+
+// Constraint with an embedded interface, but still only requires String()
+type Stringer2 interface {
+	CanBeStringer2() int
+	SubStringer2
+}
+
+type SubStringer2 interface {
+	CanBeSubStringer2() int
+	String() string
+}
+
+func stringify2[T Stringer2](s []T) (ret []string) {
+	for _, v := range s {
+		ret = append(ret, v.String())
+	}
+	return ret
+}
+
+func (myint) CanBeStringer2() int {
+	return 0
+}
+
+func (myint) CanBeSubStringer2() int {
+	return 0
+}
+
+// Test use of method values that are not called
+func stringify3[T Stringer](s []T) (ret []string) {
+	for _, v := range s {
+		f := v.String
+		ret = append(ret, f())
+	}
+	return ret
+}
+
+func main() {
+	x := []myint{myint(1), myint(2), myint(3)}
+
+	got := stringify(x)
+	want := []string{"1", "2", "3"}
+	if !reflect.DeepEqual(got, want) {
+		panic(fmt.Sprintf("got %s, want %s", got, want))
+	}
+
+	got = stringify2(x)
+	if !reflect.DeepEqual(got, want) {
+		panic(fmt.Sprintf("got %s, want %s", got, want))
+	}
+
+	got = stringify3(x)
+	if !reflect.DeepEqual(got, want) {
+		panic(fmt.Sprintf("got %s, want %s", got, want))
+	}
+}
diff --git a/test/typeparam/struct.go b/test/typeparam/struct.go
new file mode 100644
index 0000000..98f0fcd
--- /dev/null
+++ b/test/typeparam/struct.go
@@ -0,0 +1,49 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+type _E[T any] struct {
+	v T
+}
+
+type _S1 struct {
+	_E[int]
+	v string
+}
+
+type _Eint = _E[int]
+type _Ebool = _E[bool]
+
+type _S2 struct {
+	_Eint
+	_Ebool
+	v string
+}
+
+type _S3 struct {
+	*_E[int]
+}
+
+func main() {
+	s1 := _S1{_Eint{2}, "foo"}
+	if got, want := s1._E.v, 2; got != want {
+                panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+	s2 := _S2{_Eint{3}, _Ebool{true}, "foo"}
+	if got, want := s2._Eint.v, 3; got != want {
+                panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+	var s3 _S3
+	s3._E = &_Eint{4}
+	if got, want := s3._E.v, 4; got != want {
+                panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+}
diff --git a/test/typeparam/sum.go b/test/typeparam/sum.go
new file mode 100644
index 0000000..f0f5e6a
--- /dev/null
+++ b/test/typeparam/sum.go
@@ -0,0 +1,50 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+func sum[T interface{ type int, float64 }](vec []T) T {
+	var sum T
+	for _, elt := range vec {
+		sum = sum + elt
+	}
+	return sum
+}
+
+func abs(f float64) float64 {
+	if f < 0.0 {
+		return -f
+	}
+	return f
+}
+
+func main() {
+	vec1 := []int{3, 4}
+	vec2 := []float64{5.8, 9.6}
+	got := sum[int](vec1)
+	want := vec1[0] + vec1[1]
+	if got != want {
+		panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+	got = sum(vec1)
+	if want != got {
+		panic(fmt.Sprintf("got %d, want %d", got, want))
+	}
+
+	fwant := vec2[0] + vec2[1]
+	fgot := sum[float64](vec2)
+	if abs(fgot - fwant) > 1e-10 {
+		panic(fmt.Sprintf("got %f, want %f", fgot, fwant))
+	}
+	fgot = sum(vec2)
+	if abs(fgot - fwant) > 1e-10 {
+		panic(fmt.Sprintf("got %f, want %f", fgot, fwant))
+	}
+}
diff --git a/test/typeparam/tparam1.go b/test/typeparam/tparam1.go
new file mode 100644
index 0000000..7043933
--- /dev/null
+++ b/test/typeparam/tparam1.go
@@ -0,0 +1,42 @@
+// errorcheck -G
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Basic type parameter list type-checking (not syntax) errors.
+
+package tparam1
+
+// The predeclared identifier "any" is only visible as a constraint
+// in a type parameter list.
+var _ any // ERROR "undefined"
+func _(_ any) // ERROR "undefined"
+type _[_ any /* ok here */ ] struct{}
+
+const N = 10
+
+type (
+        _[] struct{} // slice
+        _[N] struct{} // array
+        _[T any] struct{}
+        _[T, T any] struct{} // ERROR "T redeclared"
+        _[T1, T2 any, T3 any] struct{}
+)
+
+func _[T any]()
+func _[T, T any]() // ERROR "T redeclared"
+func _[T1, T2 any](x T1) T2
+
+// Type parameters are visible from opening [ to end of function.
+type C interface{}
+
+func _[T interface{}]()
+func _[T C]()
+func _[T struct{}]() // ERROR "not an interface"
+func _[T interface{ m() T }]()
+func _[T1 interface{ m() T2 }, T2 interface{ m() T1 }]() {
+        var _ T1
+}
+
+// TODO(gri) expand this
diff --git a/test/typeparam/typelist.go b/test/typeparam/typelist.go
new file mode 100644
index 0000000..bd90d86
--- /dev/null
+++ b/test/typeparam/typelist.go
@@ -0,0 +1,122 @@
+// compile -G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file tests type lists & structural constraints.
+
+package p
+
+// Assignability of an unnamed pointer type to a type parameter that
+// has a matching underlying type.
+func _[T interface{}, PT interface{type *T}] (x T) PT {
+    return &x
+}
+
+// Indexing of generic types containing type parameters in their type list:
+func at[T interface{ type []E }, E any](x T, i int) E {
+        return x[i]
+}
+
+// A generic type inside a function acts like a named type. Its underlying
+// type is itself, its "operational type" is defined by the type list in
+// the tybe bound, if any.
+func _[T interface{type int}](x T) {
+	type myint int
+	var _ int = int(x)
+	var _ T = 42
+	var _ T = T(myint(42))
+}
+
+// Indexing a generic type which has a structural contraints to be an array.
+func _[T interface { type [10]int }](x T) {
+	_ = x[9] // ok
+}
+
+// Dereference of a generic type which has a structural contraint to be a pointer.
+func _[T interface{ type *int }](p T) int {
+	return *p
+}
+
+// Channel send and receive on a generic type which has a structural constraint to
+// be a channel.
+func _[T interface{ type chan int }](ch T) int {
+	// This would deadlock if executed (but ok for a compile test)
+	ch <- 0
+	return <- ch
+}
+
+// Calling of a generic type which has a structural constraint to be a function.
+func _[T interface{ type func() }](f T) {
+	f()
+	go f()
+}
+
+// Same, but function has a parameter and return value.
+func _[T interface{ type func(string) int }](f T) int {
+	return f("hello")
+}
+
+// Map access of a generic type which has a structural constraint to be a map.
+func _[V any, T interface { type map[string]V }](p T) V {
+	return p["test"]
+}
+
+
+// Testing partial and full type inference, including the case where the types can
+// be inferred without needing the types of the function arguments.
+
+func f0[A any, B interface{type C}, C interface{type D}, D interface{type A}](A, B, C, D)
+func _() {
+        f := f0[string]
+        f("a", "b", "c", "d")
+        f0("a", "b", "c", "d")
+}
+
+func f1[A any, B interface{type A}](A, B)
+func _() {
+        f := f1[int]
+        f(int(0), int(0))
+        f1(int(0), int(0))
+        f(0, 0)
+        f1(0, 0)
+}
+
+func f2[A any, B interface{type []A}](_ A, _ B)
+func _() {
+	f := f2[byte]
+	f(byte(0), []byte{})
+	f2(byte(0), []byte{})
+	f(0, []byte{})
+	// f2(0, []byte{}) - this one doesn't work
+}
+
+func f3[A any, B interface{type C}, C interface{type *A}](a A, _ B, c C)
+func _() {
+	f := f3[int]
+	var x int
+	f(x, &x, &x)
+	f3(x, &x, &x)
+}
+
+func f4[A any, B interface{type []C}, C interface{type *A}](_ A, _ B, c C)
+func _() {
+	f := f4[int]
+	var x int
+	f(x, []*int{}, &x)
+	f4(x, []*int{}, &x)
+}
+
+func f5[A interface{type struct{b B; c C}}, B any, C interface{type *B}](x B) A
+func _() {
+	x := f5(1.2)
+	var _ float64 = x.b
+	var _ float64 = *x.c
+}
+
+func f6[A any, B interface{type struct{f []A}}](B) A
+func _() {
+	x := f6(struct{f []string}{})
+	var _ string = x
+}
diff --git a/test/typeparam/value.go b/test/typeparam/value.go
new file mode 100644
index 0000000..5dd7449
--- /dev/null
+++ b/test/typeparam/value.go
@@ -0,0 +1,75 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+type value[T any] struct {
+	val T
+}
+
+func get[T2 any](v *value[T2]) T2 {
+	return v.val
+}
+
+func set[T any](v *value[T], val T) {
+	v.val = val
+}
+
+func (v *value[T2]) set(val T2) {
+	v.val = val
+}
+
+func (v *value[T2]) get() T2 {
+	return v.val
+}
+
+func main() {
+	var v1 value[int]
+	set(&v1, 1)
+	if got, want := get(&v1), 1; got != want {
+		panic(fmt.Sprintf("get() == %d, want %d", got, want))
+	}
+
+	v1.set(2)
+	if got, want := v1.get(), 2; got != want {
+		panic(fmt.Sprintf("get() == %d, want %d", got, want))
+	}
+
+	v1p := new(value[int])
+	set(v1p, 3)
+	if got, want := get(v1p), 3; got != want {
+		panic(fmt.Sprintf("get() == %d, want %d", got, want))
+	}
+
+	v1p.set(4)
+	if got, want := v1p.get(), 4; got != want {
+		panic(fmt.Sprintf("get() == %d, want %d", got, want))
+	}
+
+	var v2 value[string]
+	set(&v2, "a")
+	if got, want := get(&v2), "a"; got != want {
+		panic(fmt.Sprintf("get() == %q, want %q", got, want))
+	}
+
+	v2.set("b")
+	if got, want := get(&v2), "b"; got != want {
+		panic(fmt.Sprintf("get() == %q, want %q", got, want))
+	}
+
+	v2p := new(value[string])
+	set(v2p, "c")
+	if got, want := get(v2p), "c"; got != want {
+		panic(fmt.Sprintf("get() == %d, want %d", got, want))
+	}
+
+	v2p.set("d")
+	if got, want := v2p.get(), "d"; got != want {
+		panic(fmt.Sprintf("get() == %d, want %d", got, want))
+	}
+}
diff --git a/test/typeswitch3.go b/test/typeswitch3.go
index 1388187..a57889b 100644
--- a/test/typeswitch3.go
+++ b/test/typeswitch3.go
@@ -36,13 +36,13 @@
 	}
 
 	// Issue 2827.
-	switch _ := r.(type) { // ERROR "invalid variable name _|no new variables"
+	switch _ := r.(type) { // ERROR "invalid variable name _|no new variables?"
 	}
 }
 
 func noninterface() {
 	var i int
-	switch i.(type) { // ERROR "cannot type switch on non-interface value"
+	switch i.(type) { // ERROR "cannot type switch on non-interface value|not an interface type"
 	case string:
 	case int:
 	}
@@ -51,6 +51,6 @@
 		name string
 	}
 	var s S
-	switch s.(type) { // ERROR "cannot type switch on non-interface value"
+	switch s.(type) { // ERROR "cannot type switch on non-interface value|not an interface type"
 	}
 }
diff --git a/test/unsafebuiltins.go b/test/unsafebuiltins.go
new file mode 100644
index 0000000..4c940aa
--- /dev/null
+++ b/test/unsafebuiltins.go
@@ -0,0 +1,64 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"math"
+	"unsafe"
+)
+
+const maxUintptr = 1 << (8 * unsafe.Sizeof(uintptr(0)))
+
+func main() {
+	var p [10]byte
+
+	// unsafe.Add
+	{
+		p1 := unsafe.Pointer(&p[1])
+		assert(unsafe.Add(p1, 1) == unsafe.Pointer(&p[2]))
+		assert(unsafe.Add(p1, -1) == unsafe.Pointer(&p[0]))
+	}
+
+	// unsafe.Slice
+	{
+		s := unsafe.Slice(&p[0], len(p))
+		assert(&s[0] == &p[0])
+		assert(len(s) == len(p))
+		assert(cap(s) == len(p))
+
+		// nil pointer with zero length returns nil
+		assert(unsafe.Slice((*int)(nil), 0) == nil)
+
+		// nil pointer with positive length panics
+		mustPanic(func() { _ = unsafe.Slice((*int)(nil), 1) })
+
+		// negative length
+		var neg int = -1
+		mustPanic(func() { _ = unsafe.Slice(new(byte), neg) })
+
+		// length too large
+		var tooBig uint64 = math.MaxUint64
+		mustPanic(func() { _ = unsafe.Slice(new(byte), tooBig) })
+
+		// size overflows address space
+		mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8) })
+		mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8+1) })
+	}
+}
+
+func assert(ok bool) {
+	if !ok {
+		panic("FAIL")
+	}
+}
+
+func mustPanic(f func()) {
+	defer func() {
+		assert(recover() != nil)
+	}()
+	f()
+}
diff --git a/test/used.go b/test/used.go
new file mode 100644
index 0000000..5bdc5a7
--- /dev/null
+++ b/test/used.go
@@ -0,0 +1,145 @@
+// errorcheck
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "unsafe"
+
+const C = 1
+
+var x, x1, x2 int
+var b bool
+var s string
+var c chan int
+var cp complex128
+var slice []int
+var array [2]int
+var bytes []byte
+var runes []rune
+var r rune
+
+func f0()            {}
+func f1() int        { return 1 }
+func f2() (int, int) { return 1, 1 }
+
+type T struct{ X int }
+
+func (T) M1() int { return 1 }
+func (T) M0()     {}
+func (T) M()      {}
+
+var t T
+var tp *T
+
+type I interface{ M() }
+
+var i I
+
+var m map[int]int
+
+func _() {
+	// Note: if the next line changes to x, the error silences the x+x etc below!
+	x1 // ERROR "x1 .* not used"
+
+	nil                    // ERROR "nil .* not used"
+	C                      // ERROR  "C .* not used"
+	1                      // ERROR "1 .* not used"
+	x + x                  // ERROR "x \+ x .* not used"
+	x - x                  // ERROR "x - x .* not used"
+	x | x                  // ERROR "x \| x .* not used"
+	"a" + s                // ERROR ".a. \+ s .* not used"
+	&x                     // ERROR "&x .* not used"
+	b && b                 // ERROR "b && b .* not used"
+	append(slice, 1)       // ERROR "append\(slice, 1\) .* not used"
+	string(bytes)          // ERROR "string\(bytes\) .* not used"
+	string(runes)          // ERROR "string\(runes\) .* not used"
+	f0()                   // ok
+	f1()                   // ok
+	f2()                   // ok
+	_ = f0()               // ERROR "f0\(\) .*used as value"
+	_ = f1()               // ok
+	_, _ = f2()            // ok
+	_ = f2()               // ERROR "assignment mismatch: 1 variable but f2 returns 2 values|cannot assign"
+	_ = f1(), 0            // ERROR "assignment mismatch: 1 variable but 2 values|cannot assign"
+	T.M0                   // ERROR "T.M0 .* not used"
+	t.M0                   // ERROR "t.M0 .* not used"
+	cap                    // ERROR "use of builtin cap not in function call|must be called"
+	cap(slice)             // ERROR "cap\(slice\) .* not used"
+	close(c)               // ok
+	_ = close(c)           // ERROR "close\(c\) .*used as value"
+	func() {}              // ERROR "func literal .* not used|is not used"
+	X{}                    // ERROR "undefined: X"
+	map[string]int{}       // ERROR "map\[string\]int{} .* not used"
+	struct{}{}             // ERROR "struct ?{}{} .* not used"
+	[1]int{}               // ERROR "\[1\]int{} .* not used"
+	[]int{}                // ERROR "\[\]int{} .* not used"
+	&struct{}{}            // ERROR "&struct ?{}{} .* not used"
+	float32(x)             // ERROR "float32\(x\) .* not used"
+	I(t)                   // ERROR "I\(t\) .* not used"
+	int(x)                 // ERROR "int\(x\) .* not used"
+	copy(slice, slice)     // ok
+	_ = copy(slice, slice) // ok
+	delete(m, 1)           // ok
+	_ = delete(m, 1)       // ERROR "delete\(m, 1\) .*used as value"
+	t.X                    // ERROR "t.X .* not used"
+	tp.X                   // ERROR "tp.X .* not used"
+	t.M                    // ERROR "t.M .* not used"
+	I.M                    // ERROR "I.M .* not used"
+	i.(T)                  // ERROR "i.\(T\) .* not used"
+	x == x                 // ERROR "x == x .* not used"
+	x != x                 // ERROR "x != x .* not used"
+	x != x                 // ERROR "x != x .* not used"
+	x < x                  // ERROR "x < x .* not used"
+	x >= x                 // ERROR "x >= x .* not used"
+	x > x                  // ERROR "x > x .* not used"
+	*tp                    // ERROR "\*tp .* not used"
+	slice[0]               // ERROR "slice\[0\] .* not used"
+	m[1]                   // ERROR "m\[1\] .* not used"
+	len(slice)             // ERROR "len\(slice\) .* not used"
+	make(chan int)         // ERROR "make\(chan int\) .* not used"
+	make(map[int]int)      // ERROR "make\(map\[int\]int\) .* not used"
+	make([]int, 1)         // ERROR "make\(\[\]int, 1\) .* not used"
+	x * x                  // ERROR "x \* x .* not used"
+	x / x                  // ERROR "x / x .* not used"
+	x % x                  // ERROR "x % x .* not used"
+	x << x                 // ERROR "x << x .* not used"
+	x >> x                 // ERROR "x >> x .* not used"
+	x & x                  // ERROR "x & x .* not used"
+	x &^ x                 // ERROR "x &\^ x .* not used"
+	new(int)               // ERROR "new\(int\) .* not used"
+	!b                     // ERROR "!b .* not used"
+	^x                     // ERROR "\^x .* not used"
+	+x                     // ERROR "\+x .* not used"
+	-x                     // ERROR "-x .* not used"
+	b || b                 // ERROR "b \|\| b .* not used"
+	panic(1)               // ok
+	_ = panic(1)           // ERROR "panic\(1\) .*used as value"
+	print(1)               // ok
+	_ = print(1)           // ERROR "print\(1\) .*used as value"
+	println(1)             // ok
+	_ = println(1)         // ERROR "println\(1\) .*used as value"
+	c <- 1                 // ok
+	slice[1:1]             // ERROR "slice\[1:1\] .* not used"
+	array[1:1]             // ERROR "array\[1:1\] .* not used"
+	s[1:1]                 // ERROR "s\[1:1\] .* not used"
+	slice[1:1:1]           // ERROR "slice\[1:1:1\] .* not used"
+	array[1:1:1]           // ERROR "array\[1:1:1\] .* not used"
+	recover()              // ok
+	<-c                    // ok
+	string(r)              // ERROR "string\(r\) .* not used"
+	iota                   // ERROR "undefined: iota|cannot use iota"
+	real(cp)               // ERROR "real\(cp\) .* not used"
+	imag(cp)               // ERROR "imag\(cp\) .* not used"
+	complex(1, 2)          // ERROR "complex\(1, 2\) .* not used"
+	unsafe.Alignof(t.X)    // ERROR "unsafe.Alignof\(t.X\) .* not used"
+	unsafe.Offsetof(t.X)   // ERROR "unsafe.Offsetof\(t.X\) .* not used"
+	unsafe.Sizeof(t)       // ERROR "unsafe.Sizeof\(t\) .* not used"
+	_ = int                // ERROR "type int is not an expression|not an expression"
+	(x)                    // ERROR "x .* not used|not used"
+	_ = new(x2)            // ERROR "x2 is not a type|not a type"
+	// Disabled due to issue #43125.
+	// _ = new(1 + 1)         // DISABLED "1 \+ 1 is not a type"
+}
diff --git a/test/varerr.go b/test/varerr.go
index 82ab814..349cc8b 100644
--- a/test/varerr.go
+++ b/test/varerr.go
@@ -12,6 +12,6 @@
 func main() {
 	_ = asdf	// ERROR "undefined.*asdf"
 
-	new = 1	// ERROR "use of builtin new not in function call|invalid left hand side"
+	new = 1	// ERROR "use of builtin new not in function call|invalid left hand side|must be called"
 }
 
diff --git a/update-prebuilts.sh b/update-prebuilts.sh
new file mode 100755
index 0000000..6d990af
--- /dev/null
+++ b/update-prebuilts.sh
@@ -0,0 +1,89 @@
+#!/bin/bash -e
+
+# Copyright 2020 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.
+
+# A script to update the Go prebuilts from a build completed on Android CI.
+
+set -eo pipefail
+
+if [ -z $1 ]; then
+  echo "usage: $0 <build number>"
+  exit 1
+fi
+
+readonly BUILD_NUMBER=$1
+readonly GERRIT_TOPIC="update-go-${BUILD_NUMBER}"
+
+cd "$(dirname $0)"
+
+readonly tmpdir=$(mktemp -d)
+
+function finish {
+  if [ ! -z "${tmpdir}" ]; then
+    rm -rf "${tmpdir}"
+  fi
+}
+trap finish EXIT
+
+function fetch_artifact() {
+  local target=$1; shift
+  local artifact=$1; shift
+  local output=$1; shift
+  /google/data/ro/projects/android/fetch_artifact \
+    --branch aosp-build-tools-release \
+    --bid ${BUILD_NUMBER} \
+    --target ${target}\
+    "${artifact}" "${output}"
+}
+
+# Downloads the relevant go.zip and creates a CL with its contents.
+function upload_cl() {
+  # aosp-build-tools-release target
+  local target=$1; shift
+
+  # os directory name of the go prebuilts
+  local arch=$1; shift
+
+  zipfile="${tmpdir}/${arch}.zip"
+
+  echo "Downloading ${arch} go.zip from ab/${BUILD_NUMBER}.."
+  fetch_artifact "${target}" go.zip "${zipfile}"
+
+  pushd "../../prebuilts/go/${arch}" > /dev/null
+
+  echo "Uploading new ${arch} go.zip to Gerrit.."
+  repo start "${GERRIT_TOPIC}"
+
+  git rm -rf .
+  unzip -q -d "$(pwd)" "${zipfile}"
+  git add -A .
+  git commit -m "Update ${arch} Go prebuilts from ab/${BUILD_NUMBER}
+
+https://ci.android.com/builds/branches/aosp-build-tools-release/grid?head=${BUILD_NUMBER}&tail=${BUILD_NUMBER}
+
+Update script: toolchain/go/update-prebuilts.sh
+
+Test: Treehugger presubmit"
+  repo upload --cbr -t -y .
+
+  popd
+}
+
+# upload_cl <aosp-build-tools-release target> <prebuilts dir>
+upload_cl linux linux-x86
+upload_cl darwin_mac darwin-x86
+
+echo "Uploaded CLs: https://android-review.googlesource.com/q/topic:%22${GERRIT_TOPIC}%22+status:open"
+echo "Done."